[
  {
    "path": ".boring",
    "content": "#\n# Boring file regular expresions\n#\n\n~$\n\\#\n(^|/)\\.DS_Store$\n(^|/)Thumbs\\.db$\n(^|/)core(\\.[0-9]+)?$\n\\.(pyc|pyo|o|so|orig|rej|prof|bak|BAK|tmp|wpr|wpu|swp|swo|komodoproject)$\n\n(^|/)\\.idea($|/)\n(^|/)\\.komodotools($|/)\n(^|/)_darcs($|/)\n(^|/)autom4te.cache($|/)\n(^|/)tags($|/)\n\n^MANIFEST$\n^build($|/)\n^dist($|/)\n^test($|/)\n^sipsimple/core/_core.c$\n^sipsimple/util/_sha1.c$\n"
  },
  {
    "path": "AUTHORS",
    "content": "Adrian Georgescu\nDan Pascu\nRuud Klaver\nDenis Bilenko\nLucian Stanescu\nSaúl Ibarra\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright: 2008-2020 AG Projects\n\nLicense: GPL-3+\n\n    This package is free software; you can redistribute it and/or modify it\n    under the terms of the GNU General Public License as published by the\n    Free Software Foundation; either version 3 of the License, or (at your\n    option) any later version.\n\n    This package is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n    GNU General Public License for more details.\n\n    For a copy of the license see https://www.gnu.org/licenses/gpl.html\n\n"
  },
  {
    "path": "MANIFEST.in",
    "content": "include AUTHORS\ninclude LICENSE\ninclude README\ninclude MANIFEST.in\n\ninclude build_inplace\ninclude setup_pjsip.py\n\ninclude sipsimple/payloads/xml-schemas/*.xsd\ninclude sipsimple/util/_sha1.h\n\ninclude debian/changelog\ninclude debian/compat\ninclude debian/control\ninclude debian/copyright\ninclude debian/dirs\ninclude debian/docs\ninclude debian/pycompat\ninclude debian/pyversions\ninclude debian/python-sipsimple.lintian-overrides\ninclude debian/python-sipsimple-dbg.lintian-overrides\ninclude debian/rules\ninclude debian/source/format\n\nrecursive-include docs *\nrecursive-include deps *\n"
  },
  {
    "path": "README",
    "content": "\nSIP SIMPLE Client SDK\n---------------------\n\nCopyright (c) 2008-2020 AG Projects\nhttp://ag-projects.com\n\n\nDescription\n-----------\n\nSIP SIMPLE client SDK is a Software Development Kit for easy development of\nSIP end-points that support rich media like Audio, Video, Instant Messaging,\nFile Transfers, Desktop Sharing and Presence.  Other media types can be\neasily added by using an extensible high-level API.\n\nThe software has undergone in the past years several interoperability tests\nat SIPIT (http://www.sipit.net) and today is of industry strength quality.\n\n\nBackground\n----------\n\nSIP stands for 'Sessions Initiation Protocol', an IETF standard described by\nRFC 3261. SIP is an application-layer control protocol that can establish,\nmodify and terminate multimedia sessions such as Internet telephony calls\n(VoIP). Media can be added to (and removed from) an existing session.\n\nSIP allows the endpoints to negotiate and combine any type of session they\nmutually understand like video, instant messaging (IM), file transfer,\ndesktop sharing and provides a generic event notification system with\nreal-time publications and subscriptions about state changes that can be\nused for asynchronous services like presence, message waiting indicator and\nbusy line appearance.\n\n\nFeatures\n--------\n\nThe library has cross platform capabilities on Linux OS, Mac OSX and\nMicrosoft Windows.  The library should work with minimal changes on any\nplatform that supports C and Python development environments.\n\nThe SDK is suitable for building end-points like SIP clients or SIP\nApplication Servers.  To see what the SDK is capable of, you can try Blink\nfrom http://icanblink.com\n\n\nGeneral\n\n * Written in Python\n * Non-blocking asynchronous engine\n * Built-in configuration framework\n * TLS Security for signaling (SIP) and media (MSRP, XCAP)\n * Support for multiple SIP accounts\n * Multiple Media Types per Session (e.g. Video, Audio and IM)\n * Failover support for DNS lookups, SIP and MSRP routing\n * Implements re-INVITEs for adding and removing media streams\n * Automatically handling if IP Address changes\n * Audio conference bridge\n * Wav player and recorder\n * Acoustic Echo Cancelation\n * Answering machine\n * Wide-band Internet audio codecs: Opus and Speex\n * PSTN compatible codecs: G722, G711, iLBC, GSM\n * Video codecs: H.264, VP8\n\nSupported media\n\n * Audio and Video (RTP/SRTP/ZRTP)\n * Instant Messaging (MSRP and its relay extension)\n * File Transfer (MSRP and its relay extension)\n * Screen Sharing (VNC over MSRP)\n\nAll media types can be combined together in the same SIP session.\n\n\nNormative References\n--------------------\n\nSIP Signaling\n\n * SIP, Session Initiation Protocol (RFC 3261)\n * SDP, Session Description Protocol (RFC 4566)\n * An Offer/Answer Model with Session Description Protocol (SDP) (RFC 3264)\n * Reliability of Provisional Responses in Session Initiation Protocol (RFC 3262)\n * HTTP Authentication: Basic and Digest Access Authentication (RFC 2617)\n * The Reason Header Field for the Session Initiation Protocol (RFC 3326)\n * The Session Initiation Protocol (SIP) Refer Method (RFC 3515)\n * The Session Initiation Protocol (SIP) \"Replaces\" Header (RFC 3891)\n * Session Initiation Protocol (SIP) Call Control - Transfer  (RFC 5589)\n\nAddress Resolution\n\n * DNS resolution (RFC 3263)\n * Bonjour multicast DNS (draft-lee-sip-dns-sd-uri-03)\n\nNAT Traversal\n\n * SIP Signaling: Symmetric Response Routing Symmetric media (RFC 3581)\n * RTP media (Audio and Video): ICE, Interactive Connectivity Establishment\n   (RFC 5245)\n * MSRP media (Instant Messaging and File Transfer): MSRP protocol relay\n   extension (RFC 4976)\n\nAudio and Video\n\n * RTP, A Transport Protocol for Real-Time Applications (RFC 3550)\n * Real Time Control Protocol (RTCP) attribute in Session Description\n   Protocol (SDP) (RFC 3605)\n * SRTP, The Secure Real-time Transport Protocol (RFC 3711)\n * Generation and parsing of telephone-events payload in both RTP and SDP\n   (RFC 2833)\n * ZRTP: Media Path Key Agreement for Unicast Secure RTP (RFC 6189)\n\nInstant Messaging\n\n * CPIM, Common Presence and Instant Messaging: (RFC 3862)\n * Session Initiation Protocol (SIP) Extension for Instant Messaging\n   (RFC 3428)\n * MSRP Protocol (RFC 4975)\n * Indication of Message Composition for Instant Messaging (RFC 3994)\n * Message Summary Event Package (RFC 3842)\n * File Transfer (RFC 5547)\n\nScreen Sharing\n\n * Variation of draft-garcia-mmusic-sdp-collaboration-00 using RFB over MSRP\n\nConferencing\n\n * Conference Event Package (RFC 4575)\n * A Framework for Conferencing with the Session Initiation Protocol (RFC 4353)\n * SIP Call Control - Conferencing for User Agents (RFC 4579)\n * MSRP ad-hoc multi-party chat sessions (RFC 7701)\n\nPresence\n\n * SIP Specific Event Notification (RFC 3265)\n * SIP Extension for Event State Publication (RFC 3903) \n * PIDF: Presence Data Model (RFC 3863, RFC 3379, RFC 4479)\n * Watcher-info Event Package (RFC 3857, RFC 3858)\n * Rich Presence Extensions to PIDF (RFC 4480)\n * Contact Information Extension to PIDF (RFC 4482)\n * User Agent Capability Extension to PIDF (RFC 5196) \n * XCAP Protocol (RFC 4825)\n * Common Policy (RFC 4745)\n * Presence Rules (RFC 5025)\n * Resource Lists (RFC 4826)\n * RLS Services (RFC 4826)\n * PIDF manipulation (RFC 4827)\n * XCAP Diff (RFC 5874)\n * OMA Reference Release Definition for XDM v1.1 and Presence SIMPLE v1.1\n   Implementation Guidelines\n * OMA XML  Document Management V1.1\n\n\nSupport\n-------\n\nThe project is developed and supported by AG Projects. The support is\nprovided on a best-effort basis. \"best-effort\" means that we try to solve\nthe bugs you report or help fix your problems as soon as we can, subject to\navailable resources.\n\nTo request support you must use the mailing list available at\n\nhttp://lists.ag-projects.com/mailman/listinfo/sipbeyondvoip\n\nPatches and bug reports must be submitted by opening a ticket at\n\nhttp://sipsimpleclient.org/projects/sipsimpleclient/issues\n\nTo open ticket please Register first.\n\n\nAcknowledgments\n---------------\n\nSIP SIMPLE client SDK has been partly funded by the European Commission\nunder grant number FP7-IST-216217.\n\n"
  },
  {
    "path": "TODO",
    "content": "- If the SIP account password is changed on the server, then the client\n  modifies some contact, xcap PUT will keep failing with 401 even after\n  the password is reverted on the server. This will only be fixed by\n  deactivating/reactivating the account or restarting the application.\n\n- Warning header takes a code (300-399) a hostname (not user agent) and a\n  message. Class allows any code (100-999) and we use engine.user_agent\n  for the hostname where we use this header in session.py\n\n- 202 is deprecated (see https://tools.ietf.org/html/rfc6665#page-43)\n\n- After ICE negotiation completed we do not save state and later re-INVITEs\n  can fail, we must send re-INVITE or UPDATE with chosen candidate\n\n+ Allow resume of failed file transfers (a=file-range SDP attribute)\n\n+ combine account.uri and account.contact into account.uri.aor and\n  account.uri.contact. This will also remove the confusion between\n  account.contact and account.contact_manager\n\n+ change settings so they store changes in a thread local container\n  which is made public (accessible for all threads) when save is called.\n  This will make changes be atomic inside a thread (everything from \n  attribute changes up to the save operation is contained in the thread\n  and will not mix with changes done in parallel from other threads).\n\n+ there is a race condition that can prevent an account to start if it is\n  created while the start method of SIPApplication runs and it passed the\n  point where it called AccountManager.start. A quick workaround is to\n  never create an account before SIPApplicationDidStart is posted\n\n+ SIPApplication.start attempts to be restartable in case of errors, but\n  there are cases where it may enter into a state where it will raise\n  exceptions perpetually, even if the condition that led to the exception\n  was fixed.\n\n- allow deleting transport on SIPURI\n\n- modify Invitation/Request/Subscription to reset transport on request_uri\n\n- in application.py it subscribes to notifications but doesn't remove them\n  when it stops\n\n- End a session while in accepting state (requires session serialization)\n\n- Model file transfer after desktop sharing (use handlers on termination)\n  have internal/external handlers (notifications based or file bridges)\n\n- Use an ordered dict for keeping accounts in the AccountManager ?!?\n  see http://code.activestate.com/recipes/576693/\n\n- send notifications when local/remote party becomes focus\n  SIPSessionLocalPartyIsFocus, SIPSessionRemotePartyIsFocus\n\n- have higher level notifications on conference events\n\n\nTo fix this exception:\n\nsip:nwpsefvl@10.0.0.1:52067 52067\nsip:nwpsefvl@10.0.0.1:52067 52067\nsip:nwpsefvl@10.0.0.1;transport=tcp None\nTraceback (most recent call last):\n  File \"/usr/lib/python2.5/site-packages/twisted/internet/base.py\", line 778, in runUntilCurrent\n    call.func(*call.args, **call.kw)\n  File \"/usr/lib/pymodules/python2.5/eventlet/hubs/twistedr.py\", line 158, in call_if_greenlet_alive\n    return func(*args1, **kwargs1)\n  File \"/usr/lib/pymodules/python2.5/eventlet/proc.py\", line 571, in _run\n    result = function(*args, **kwargs)\n  File \"/home/dan/work/voip/python-sipsimple/sipsimple/account.py\", line 683, in _handle_commands\n    handler(command)\n  File \"/home/dan/work/voip/python-sipsimple/sipsimple/account.py\", line 720, in _CH_register\n    txtRecord=bonjour.TXTRecord(items=txtdata))\n  File \"/home/dan/work/voip/blink-qt/sipsimple/bonjour.py\", line 1125, in DNSServiceRegister\nTypeError: an integer is required\n\n- Notification from SIPApplication when a transport is added/removed to the\n  engine.\n- SIPApplication should provide a list of supported transports that need to\n  be used instead of the ones from settings because not everything enabled\n  in settings may actually be available at runtime on the engine\n- Build contacts on above notification instead of building them on the fly\n\n- Use OpenH264 implementation\n    - We need the binaries?!\n\n- Ability to start stream deactivated / on-hold\n    - VideoStream(direction='sendrecv') like MSRP?\n    - Review stream API, s/deactivate/shutdown/ ?\n\n- Open the camera at its native framerate\n\n"
  },
  {
    "path": "build_inplace",
    "content": "#!/bin/sh\n\npython setup.py build_ext --inplace \"$@\"\ntest -d build && python setup.py clean\n\n"
  },
  {
    "path": "debian/changelog",
    "content": "python-sipsimple (3.6.0) unstable; urgency=medium\n\n  * Added support for creating and parsing IMDN (RFC5438) documents\n  * Fixed CPIM decode if envelope has content type message/imdn+xml\n\n -- Tijmen de Mes <tijmen@ag-projects.com>  Wed, 16 Jun 2021 15:04:04 +0200\n\npython-sipsimple (3.5.1) unstable; urgency=medium\n\n  * Do not run account delete inside green thread\n\n -- Adrian Georgescu <ag@ag-projects.com>  Sun, 10 Jan 2021 20:26:12 +0100\n\npython-sipsimple (3.5.0) unstable; urgency=medium\n\n  * Fixed issue with clients locking when using PulseAudio as input device\n  * Fixed correctness and consistency issue with getting the display name\n  * Use identity tests instead of equality tests for None\n  * Fixed timer callback function signatures\n  * Added support for digest passwords in credentials objects\n  * Simplified setting attribute in init\n  * Use an internal attribute for digest for symmetry with FrozenCredentials\n  * Fix build with LibreSSL 2.7\n  * Adapted the MSRP logger to the API changes in msrplib\n  * Replaced parse_uri with the new URI.parse in msrplib\n  * Added note about illegal character used by filetransfer MSRP extension\n  * Use r-strings for regular expressions\n  * Removed redundant parentheses\n  * Added OffsetHeader type to encode/decode MSRP file offset headers\n  * Changed how headers are added to MSRPData to be consistent\n  * Use named attributes instead of tuple indexes when accessing byte_range\n  * Preserve quoted arguments with build_inplace\n  * Cleanup after build_inplace\n  * Updated shebang line in setup.py\n  * Updated debian build flags\n  * Removed DH_VERBOSE definition in debian rules\n  * Explicitly use python2 in shebang lines\n  * Updated license and copyright years\n  * Updated minimum version of debian dependencies\n  * Increased debian compatibility level to 11\n  * Increased debian standards version to 4.5.0\n\n -- Dan Pascu <dan@ag-projects.com>  Fri, 14 Feb 2020 12:46:51 +0200\n\npython-sipsimple (3.4.2) unstable; urgency=medium\n\n  * Fixed crash when using sha1 hmac with zrtp\n  * Added __dir__ method to Engine to correctly reflect UA attributes\n  * Updated windows installation instructions\n\n -- Dan Pascu <dan@ag-projects.com>  Tue, 26 Mar 2019 11:30:05 +0200\n\npython-sipsimple (3.4.1) unstable; urgency=medium\n\n  * Fixed cleanup of media stream when ending to avoid memory leak\n  * Fixed inconsistency in session state at the time of posting notification\n  * Fixed memory leak caused by out of order execution from race condition\n\n -- Dan Pascu <dan@ag-projects.com>  Wed, 27 Feb 2019 10:14:48 +0200\n\npython-sipsimple (3.4.0) unstable; urgency=medium\n\n  * Fixed attribute name in comparison\n  * Added dialog_id property on the Session class\n  * Added logic to handle early-only and RFC2543 style tags for Replaces\n  * Avoid unnecessary list copy\n  * Removed unnecessary boolean variable\n  * Do not reset the proposed_streams attribute when the session is rejected\n  * Reordered some operations for consistency\n  * Make sure the greenlet attribute is always removed when greenlet exits\n  * Removed code that duplicated cancel handling inside reject handler\n  * Simplified RTPStreamEncryption properties\n  * Ordered RTPStreamEncryption properties alphabetically\n  * Fixed potential access to uninitialized variable\n  * Removed unnecessary attribute from RTPStream\n  * Fixed memory leak for unused streams that bleeded out audio resources\n  * Fixed memory leak that did not release streams when canceling proposals\n  * Use setter syntax for defining properties\n  * PEP-8 compliance changes\n  * Use set literals instead of set instances\n  * Do not use mutable value for function default argument\n  * Improved error message\n  * Use local variable instead of instance attribute\n  * Fixed right hand value in assignment\n  * Use super when instantiating data types\n  * Always clean up proposed streams when cancelling proposal\n  * Added language_level for cython sources\n\n -- Dan Pascu <dan@ag-projects.com>  Mon, 25 Feb 2019 13:51:22 +0200\n\npython-sipsimple (3.3.0) unstable; urgency=medium\n\n  * Updated to support openssl-1.1 in pjsip and zrtp\n  * Updated to support openh264-1.6+ in pjmedia\n  * Removed duplicate declaration of pjmedia_dir enum in _core.pxd\n\n -- Dan Pascu <dan@ag-projects.com>  Wed, 12 Dec 2018 07:02:37 +0200\n\npython-sipsimple (3.2.1) unstable; urgency=medium\n\n  * Fixed building sipsimple when python-application is not installed\n\n -- Dan Pascu <dan@ag-projects.com>  Fri, 05 Oct 2018 18:57:56 +0300\n\npython-sipsimple (3.2.0) unstable; urgency=medium\n\n  * Shutdown already started subsystems if application is stopped early\n  * Fixed a bug that would hang the application if the engine fails to start\n  * Stop the engine thread on engine failure\n  * Reset encryption type when the RTP stream ends\n  * Use a named logger for sipsimple logging\n  * Use modern syntax for catching exception\n  * Removed underscore prefix from argument name\n  * Fixed typo in notification name\n  * Order imports alphabetically\n  * Import statement cleanup\n  * Removed obsolete build option\n  * [core] Removed unnecessary local variables\n  * [core] Removed test for failures that cannot happen\n  * [core] Fixed the transport being used within an incoming SUBSCRIBE dialog\n  * [core] Removed unnecessary semicolon at the end of statement\n  * [core] Added missing cdef statement\n  * [core] Minimize releasing/acquiring the GIL\n  * [core] Propagate exceptions\n  * [core] Undo setting incoming subscription transport as it conflicts\n  * [core] Removed unused code from setting transport\n  * Use the new logging API in python-application 2.5.0\n  * Fixed compiling with newer ffmpeg\n  * Removed duplicate dependency\n  * Update macOS installation instructions\n  * Added deb building instructions for Rasberry Pi\n  * Removed copyright notices from install files\n  * Updated copyright years\n  * Replaced deprecated debian package priority\n  * Switched from dbg package to dbgsym package\n\n -- Dan Pascu <dan@ag-projects.com>  Fri, 05 Oct 2018 17:01:31 +0300\n\npython-sipsimple (3.1.1) unstable; urgency=medium\n\n  * Fix processing audio / video SDPs with non numeric formats\n  * Document how to compile ffmpeg without SecureTransport\n  * Removed obsolete pycompat/pyversions files\n  * Updated debian uploaders\n  * Updated debian standards version\n  * Simplified condition\n  * PEP-8 compliance changes\n  * Improved object representation\n  * Simplified building the Route's URI\n  * Made output from Route.__str__ be consitent with SIPURI.__str__\n  * Fixed debian build dependency for libssl\n  * Updated copyright years\n  * Increased debian compatibility level to 9\n  * Removed unnecessary phony targets\n  * Updated debian copyright\n  * Updated debian package description\n  * Fixed python-sipsimple-dbg dependencies\n  * Simplified debian build and fixed missing module in the debug package\n\n -- Dan Pascu <dan@ag-projects.com>  Fri, 05 May 2017 17:29:13 +0300\n\npython-sipsimple (3.1.0) unstable; urgency=medium\n\n  * Update Opus to version 1.1.2\n  * pjsip: fix handling empty re-INVITE requests\n  * Updated dependency versions\n  * Improved MANIFEST.in\n  * Removed build time dependency on python-application\n  * Updated building documentation\n  * Added interface for scheduling functions to run in a thread\n  * Added fake xcap settings to the BonjourAccount\n  * Fix race conditions when processing ICE callbacks\n  * Ignore NAPTR and SRV timeouts when doing DNS lookups\n  * Fixed setting Referred-By header\n\n -- Saul Ibarra <saul@ag-projects.com>  Tue, 18 Oct 2016 01:28:40 +0200\n\npython-sipsimple (3.0.0) unstable; urgency=medium\n\n  * Added OTR encryption support in the chat stream\n  * Use openfile where we need control over the file creation\n  * Use defaultweakobjectmap defined in python-application\n  * Simplified verifying the transferred file's hash\n  * Added FileSelectorHash class to simplify code and improve readability\n  * Fixed recovering session state in certain failure conditions\n  * Do not wait for notifications if we couldn't notify transfer progress\n  * Capture unhandled exceptions and log errors from new_from_sdp\n  * Capture errors while parsing the file selector\n  * Handle the MedisStreamDidNotInitialize notification when adding streams\n  * Read code and reason from the notification when posting SIPSessionDidFail\n  * Don't rely on the failure reason being set for failed transfers\n  * Modified the SimplePayload and CPIMPayload to only work with bytes\n  * Handle parsing errors for is-composing documents\n  * Added package info module\n  * Fixed MediaStreamBase not posting MediaStreamDidNotInitialize sometimes\n  * Remove transfer_source from notifications\n  * Set transfer origin to the remote identity if Referred-By is missing\n  * Don't add a Referred-By header if it wasn't specified\n  * Handle exception when closing a file that is being read in another thread\n  * Prevent Session.transfer from being called while a transfer is in progress\n  * Changed default transfer reject code from 486 (Busy) to 603 (Decline)\n  * Protect SIPPublicationWillExpire from being called by an older publication\n  * Handle race condition where state is SameState for initial PUBLISH\n  * Remove bundled RFC/draft files\n  * zrtp: prefer standard AES to Twofish cipher\n  * Log Engine failures using application.log\n  * Set locks to NULL after destroying them\n  * pjsip: fix compilation warnings with recent versions of FFmpeg\n  * pjsip: removed unused files\n  * pjsip: update to revision 5249\n  * Always build pjsip in non-debug mode\n  * Avoid running timers if subscription dialog was destroyed\n  * Suppress some compilation warnings\n  * Avoid lockups on Engine shutdown\n  * Post notification when SIPApplication gets a fatal error\n\n -- Saul Ibarra <saul@ag-projects.com>  Tue, 08 Mar 2016 12:46:06 +0100\n\npython-sipsimple (2.6.0) unstable; urgency=medium\n\n  * pjsip: fix crash when TLS transport is reset while data is being sent\n  * Switched is-composing failure_report to no\n  * Refactor CPIM envelope usage\n  * Enable lrint functions on Opus\n  * Refactored sipsimple.streams package structure\n  * Changed MediaStreamRegistry from being a class to being an instance\n  * Added prefer_cpim boolean class attribute to ChatStream\n  * Fixed stripping data in the MSRP trace\n  * Only post chat delivery notifications when notify_progress is True\n  * Do not post MediaStreamDidNotInitialize twice in some cases\n  * Fixed file transfer failure reasons\n  * Prefer CPIM for chat messages for the time being\n  * Fixed Registrar/Publisher getting stuck under certain conditions\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 04 Dec 2015 12:15:35 +0100\n\npython-sipsimple (2.5.1) unstable; urgency=medium\n\n  * Fixed opening files in binary mode when using os.open\n  * pjsip: enumerate supported resolutions in AVF video backend\n  * pjsip: fix opening camera with the right resolution on AVF backend\n  * Made stream fetch the local uri from the MSRP transport or connector\n  * Updated dependency to latest python-msrplib\n  * Return the ZRTP peer id as is and let the application format it as it\n    needs\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 28 Aug 2015 12:59:49 +0200\n\npython-sipsimple (2.5.0) unstable; urgency=medium\n\n  * Added VP8 video codec support\n  * Added basic RTCP PLI support, used for requesting keyframes\n  * Fixed crash when handling bogus Opus packets\n  * Simplified registering audio codecs in the core\n  * Handle socket errors when fetching XCAP documents\n  * Fixed several compilation warnings\n  * Added python-application as a build dependency\n  * Fixed getting file offset on Windows\n\n -- Saul Ibarra <saul@ag-projects.com>  Wed, 10 Jun 2015 13:57:35 +0200\n\npython-sipsimple (2.4.0) unstable; urgency=medium\n\n  * Refactor file transfers and add resume support\n  * Interrupt stream.initialize if session is cancelled\n  * Add ISIPSimpleApplicationDataStorage interface\n  * Adapt to API changes in MSRPlib\n  * Simplified RTP streams initialization code\n\n -- Saul Ibarra <saul@ag-projects.com>  Wed, 29 Apr 2015 12:05:30 +0200\n\npython-sipsimple (2.3.1) unstable; urgency=medium\n\n  * Report sent but unconfirmed chat messages as not delivered\n  * Don't stop and start video ports when accessing the tee\n  * Compile PJSIP with -fno-omit-frame-pointer\n  * Updated Windows compilation instructions\n  * pjsip: fix compilation of ZRTP library on Windows\n  * pjsip: don't run AVFoundation functions in the main thread\n  * pjsip: make the video tee thread-safe\n  * pjsip: remove tons of unneeded code\n\n -- Saul Ibarra <saul@ag-projects.com>  Wed, 25 Mar 2015 12:40:20 +0100\n\npython-sipsimple (2.3.0) unstable; urgency=medium\n\n  * Added ZRTP support\n  * Add setting for opportunistic SRTP encryption\n  * Fix Opus SDP encoding\n  * Reject video streams without a profile-level-id attribute\n  * Renamed RTP stream related notifications\n  * Renamed audio stream recording related notifications\n  * Fix setting FFmpeg libraries path in some cases on OSX\n  * Fix posting ICE state change notifications\n  * Fix sending initial keyframes when ICE is used\n  * Run _send_keyframes on the Twisted thread\n  * Add ability to override the sender for chat messages\n  * pjsip: fix rendering on OSX\n  * pjsip: avoid crashes on OSX if video size changes\n  * Work around issue with the RTP transport lock being hold for too long\n  * Stop the VideoTransport in the device-io thread\n  * Removed caching of statistics on the RTP transports when stopping\n  * Fix draining the message queue in ChatStream\n  * Post SIPApplicationWillStart before starting the core\n  * Make SIPApplication start / stop consistent\n  * Fix race conditions when handling SIPApplication.state\n  * Avoid exceptions when un-pickling XCAP journal\n  * Add chatroom_capabilities property to ChatStream\n\n -- Saul Ibarra <saul@ag-projects.com>  Tue, 17 Mar 2015 09:27:02 +0100\n\npython-sipsimple (2.2.0) unstable; urgency=medium\n\n  * Make sure ICE status change notification is only sent while waiting for it\n  * Listen for notifications on the RTPTransport until the stream ends\n  * pjsip: skip all surround device configurations in ALSA backend\n  * Hold the stream lock just for checking / changing states\n  * Adapt to API change in MSRPLib\n  * Refactor message handling in ChatStream\n  * Check remote supported content types in ChatStream\n  * Update supported types in ChatStream\n  * Raised python-msrplib version dependency\n\n -- Saul Ibarra <saul@ag-projects.com>  Mon, 26 Jan 2015 12:59:03 +0100\n\npython-sipsimple (2.1.1) unstable; urgency=medium\n\n  * Add a base class for Audio and Video streams\n  * Add / support file-transfer-id SDP attribute to FileTransferStream\n  * Refactor video pausing capability\n  * Relax handling some errors in the core\n  * Compile PJSIP with -O2 optimization\n\n -- Saul Ibarra <saul@ag-projects.com>  Mon, 05 Jan 2015 12:36:56 +0100\n\npython-sipsimple (2.1.0) unstable; urgency=medium\n\n  * Use the Engine IP address also for media\n  * Extend Session.connect and Session.accept with an extra_headers parameter\n  * Do not reset the Echo Canceller unless the audio stream changes direction\n  * Also call stream.update on the remaining streams when removing streams\n  * Fix unnecessarily waiting for a timeout on Session.reject_proposal\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 05 Dec 2014 13:26:06 +0100\n\npython-sipsimple (2.0.0) unstable; urgency=medium\n\n  * Add video support (H264 codec)\n  * Add support for handling initial INVITE requests without SDP\n  * Restart TCP and TLS transports when network conditions change\n  * Reuse disabled SDP streams\n  * Fix parsing makefile options\n  * Fix linking with OSX frameworks\n  * Unregister and unpublish when network conditions change, before restarting\n  * Leave symbols in even on release builds\n  * Fix not ending streams in some cases when Session.remove_streams fails\n  * Make stream initialization and ending consistent\n  * Report stream failure in MediaStreamDidEnd\n  * Add ExponentialTimer helper class to util\n  * Improved handling failures when processing remote proposals\n  * Reply with 488 if a remote SDP offer has deleted streams\n  * Fix race conditions when handling remote proposals\n  * Refresh SRTP crypto lines when updating local SDP\n  * Simplify code for obtaining the path to the OSX SDK\n  * Use 488 code when a proposal with streams fails\n  * Use timezone aware timestamps for Session start_time and stop_time\n  * Parse and generate bandwidth info attributes (b=) on the SDP\n  * Include address information with the MSRPTransportTrace notification\n  * Use SSLv23 method for TLSi (SSLv2 and SSLv3 are disabled)\n  * Updated bundled PJSIP to revision 4961\n  * Make sure a removed stream always has a connection line\n  * Remove bandwidth attributes when disabling a stream\n  * Reject incoming re-INVITE if we couldn't reply to it\n  * Fix setting SDP connection line when accepting a proposal\n\n -- Saul Ibarra <saul@ag-projects.com>  Thu, 20 Nov 2014 18:30:35 +0100\n\npython-sipsimple (1.4.2) unstable; urgency=medium\n\n  * Avoid recompiling the whole PJSIP every time the core is recompiled\n  * Fix encoding when expanding user home path\n  * Made the XMLDocument schema path configurable\n\n -- Saul Ibarra <saul@ag-projects.com>  Mon, 28 Jul 2014 13:51:42 +0200\n\npython-sipsimple (1.4.1) unstable; urgency=medium\n\n  * Close external VNC viewer socket when the stream has ended\n  * Don't try to set TLS options if there is no default account\n  * Increased the connect timeout for external screen sharing handlers\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 27 Jun 2014 09:43:19 +0200\n\npython-sipsimple (1.4.0) unstable; urgency=medium\n\n  * Add support for adding/removing multiple streams at once\n  * Refactored SDP handling\n  * Send re-INVITE after ICE negotiation is done\n  * Refactored API for creating screen sharing streams and handlers\n  * Enable RTP keep-alive using empty RTP packets\n  * Disabled speex codec by default\n  * Fixed race condition when saving ICE state\n  * Made the VNC handler connection timeout a class attribute\n  * Allow the default VNC server and viewer handlers to be configurable\n  * Fix closing media transport to avoid leaking STUN sockets\n  * Store our Python object in the user_data field of pjmedia_transport\n  * Simplified srtp_active property\n  * Make ice_active property dynamic\n  * Make sure session state and proposed_streams are set to correct values\n    when processing proposals\n  * Use a shorter timeout for re-INVITEs that need to be answered without user\n    interaction\n  * Silence unused-function warning caused by cython\n\n -- Saul Ibarra <saul@ag-projects.com>  Wed, 28 May 2014 11:51:06 +0200\n\npython-sipsimple (1.3.0) unstable; urgency=medium\n\n  * Initialize core from main thread\n  * Add AudioStream.recorder property and remove obsolete ones\n  * Allow AudioStream.start_recording to be called early\n  * Ensure MediaStreamDidEnd is always posted for MSRP streams\n  * Fixed cancel_proposal when no streams were proposed\n  * Fixed setting proposed streams on hold when holding during a re-INVITE\n  * Fixed originator for SIPSessionProposalRejected\n  * Fixed pickling for some core objects\n  * Fixed compilation with latest Cython version\n  * Fixed processing AudioPortDidChangeSlots if bridge was stopped\n  * Avoid sending failure reports for MSRP keep-alive chunks\n  * Avoid resetting greenlet when session is about to end or cancel a proposal\n  * Removed unused tls_timeout configuration parameter\n  * pjsip: don't compile libmilenage\n\n -- Saul Ibarra <saul@ag-projects.com>  Thu, 10 Apr 2014 14:55:40 +0200\n\npython-sipsimple (1.2.1) unstable; urgency=medium\n\n  * Handle errors when sending hold/unhold requests\n  * Fix crash if sdp_done callback is processed too late\n  * Make sure code and reason are always set when state is disconnected\n  * Stop AudioStream bridge when deactivating stream\n  * pjsip: fixed compilation warning\n  * pjsip: fix build on Windows\n\n -- Saul Ibarra <saul@ag-projects.com>  Wed, 05 Mar 2014 15:03:20 +0100\n\npython-sipsimple (1.2.0) unstable; urgency=medium\n\n  * pjsip: updated bundled version to revision 4738\n  * pjsip: return base address as ICE transport address\n  * Use 101 as the telephone-event payload type\n  * Always open file in binary mode for file transfers\n  * Accept unicode in SIPURI objects\n  * Avoid exceptions in IncomingSubscription.end\n  * End session if an unrecoverable error happens in remove_stream\n  * Initialize transport to None in MSRPStreamBase.__init__\n  * Fixed compile warnings with Cython 0.20\n  * Post NetowrkConditionsDidChange if system IP address changes or the DNS\n    Manager changes the resolvers\n  * Fake ICE gathering states since we might get them too early\n  * Use 127.0.0.1 for bonjour when the default IP address is not available\n\n -- Saul Ibarra <saul@ag-projects.com>  Wed, 19 Feb 2014 13:22:57 +0100\n\npython-sipsimple (1.1.0) unstable; urgency=medium\n\n  * Updated opus codec to version 1.1\n  * Cleanup opus.c and fix compilation warnings\n  * Always put useinbandfec in SDP for opus codec\n  * Relax codec matching when doing SDP negotiation\n  * Use single global c line when creating SDP\n  * Added function to manually refresh sound devices\n  * Added trace_msrp setting\n  * Fixed SIP and PJSIP logging\n  * Fixed not posting state change notifications for different provisional\n    responses\n  * Changed notification API for renegotiating streams\n  * Renamed streams to proposed_streams on SIPSessionNewProposal\n  * Renamed streams to proposed_streams on SIPSessionHadProposalFailure\n  * Added audio.muted runtime setting to SIPSimpleSettings\n  * Post SIPApplicationWillEnd even if Engine failed\n  * Renamed MediaStreamRegistrar to MediaStreamType\n  * Properly handle mutex creation failures\n  * Added missing context attribute to MediaStreamDidFail notification\n  * Fixed memory leak by initializing the handler after the stream initialized\n  * Moved AudioConference to audio module\n  * Added helper functions to allocate and release memory pools\n  * Create null sound port only once and reuse it\n  * Simplified audio device fallback code\n  * Fixed crash when in-dialog request fails to be sent within a subscription\n  * Properly patch dnspython to make it nonblocking\n  * Added initial_delay to WavePlayer, replacing initial_play\n  * Always use timezone aware timestamps in MSRP streams\n  * Make sure MSRPlib always gets bytes, not unicode\n  * Always return unicode as the received chat message body\n  * Post SIPEngineGotException also if Engine fails to start\n  * Make send_composing_indication refresh argument optional\n  * Return default refresh value in ChatStreamGotComposingIndication if not\n    specified\n  * Don't set last active timestamp automatically\n  * Always pass copies of stream lists in Session notifications\n  * Don't compile WebRTC AEC if machine is not x86 or x86_64\n  * Raised Cython version dependency to 0.19.0\n  * Cleanup Cython imports and remove no longer needed workarounds\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 13 Dec 2013 13:45:31 +0100\n\npython-sipsimple (1.0.0) unstable; urgency=low\n\n  * Updated core to PJSIP 2\n  * Added gain control and high pass filter to audio processing\n  * Added Opus codec support\n  * Added support for RFC5768 (ICE option tag)\n  * Added enabled setting for echo canceller and echo_canceller settings group\n  * Fixed echo cancelling when using 32kHz sample rate\n  * Always disable sound device when idle\n  * Removed unused ignore_missing_ack feature\n  * Removed engine shutdown workaround\n  * Removed TLS protocol setting\n  * Removed NAT detector from SIPApplication\n  * Don't cap codecs based on sample rate, let PJSIP resample\n  * Disabled narrowband speex\n  * Fixed starting media stream if ICE fails early\n  * Don't reset stream statistics, always report absolute values\n  * Don't add BonjourAccount to AccountManager if there is no bonjour support\n  * Set session state to terminated when ended before starting\n  * Prevent PJSIP from switching transports automagically\n  * Dropped support for Python 2.6\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 09 Aug 2013 11:17:47 +0200\n\npython-sipsimple (0.35.0) unstable; urgency=low\n\n  * Added default URI implementation for contacts\n  * Added extension to PIDF to include the status type\n  * Added ItemCollection settings type\n  * Added RuntimeSetting to the configuration framework\n  * Publish instance id over Bonjour\n  * Refactored bonjour discovery notifications\n  * Return SIP Request headers in SIPMessageDidFail and SIPMessageDidSucceed\n    notification data\n  * Removed unnecessary end method on Message\n  * Fixed building XML schemas on all platforms\n  * Fixed parsing sip.instance from a REGISTER reply\n  * Fixed compilation with Cython 0.19\n  * Fixed posting PublicationDidSucceed after a failure\n  * Catch ValueError when parsing XML documents\n\n -- Saul Ibarra <saul@ag-projects.com>  Wed, 26 Jun 2013 16:08:30 +0200\n\npython-sipsimple (0.34.0) unstable; urgency=low\n\n  * Added Bonjour presence\n  * Added presence subscriber for itself to Account\n  * Added SDPNegotiator class\n  * Added ability to properly stringify SDPSession objects\n  * Added ability to parse a SDPSession object from a string\n  * Disable PJSIP assertions on recoverable errors\n  * Removed extra checks on SDP origin field\n  * Fixed deadlock when cross instantiating conditional singletons\n  * Avoid sending adding participant progress if the answer is final\n  * Avoid doing mDNS lookups with dnspython\n  * Define __nonzero__ for XCAP Document objects\n  * Made AddressbookManager.transaction a class method\n\n -- Saul Ibarra <saul@ag-projects.com>  Tue, 19 Mar 2013 11:31:27 +0100\n\npython-sipsimple (0.33.0) unstable; urgency=low\n\n  * Added notification when incoming subscription times out\n  * Added call_id attribute to Subscription and IncomingSubscription\n  * Allow incoming subscriptions to have expires 0\n  * Fixed session transfer after API changes\n  * Fixed setting initial timeout for incoming subscriptions\n  * Renamed desktop-sharing media type to screen-sharing\n  * Provide direct access to stream types on MediaStreamRegistry\n  * Post notifications about removed neighbours when stopping bonjour services\n  * Only set reason for NOTIFY if state is terminated\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 25 Jan 2013 16:22:05 +0100\n\npython-sipsimple (0.32.0) unstable; urgency=low\n\n  * Fixed updating local SDP direction if answer is inactive\n  * Fixed test for supported audio codecs\n  * Adjusted pres-rules auid to org.openmobilealliance.pres-rules\n  * Removed icon alternative location since it was custom and is now unused\n  * Use digits only for contact usernames to improve interoperability\n  * Disable NAT detection\n  * Allow more types to be directly used as configuration data types\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 11 Jan 2013 12:03:11 +0100\n\npython-sipsimple (0.31.1) unstable; urgency=low\n\n  * Terminate session if a stream fails and can't be removed from the session\n  * Removed extended-away state from PIDF extension\n  * Fixed setting local hold state after direction was inactive\n  * Prevent account's activate/deactivate methods to run at the same time\n  * Fixed race conditions when deleting an account\n  * Fixed some lintian warnings\n\n -- Saul Ibarra <saul@ag-projects.com>  Wed, 28 Nov 2012 12:37:01 +0100\n\npython-sipsimple (0.31.0) unstable; urgency=low\n\n  * Refactored streams and account relationship\n  * Added Supported header indication for GRUU on REGISTERs\n  * Allow extra headers to be passed to Registration\n  * Don't use GRUU for conference subscriptions and referrals\n  * Fixed XML datatypes for CIPID extensions\n  * Fixed sending extra headers when unsubscribing\n  * Fixed parsing RLS NOTIFY fayload if advertised CID is not present\n  * Fixed thread safety issues with ChatStream functions\n  * Moved identity attributes from MSRPStreamBase to ChatStream\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 26 Oct 2012 12:33:23 +0200\n\npython-sipsimple (0.30.1) unstable; urgency=low\n\n  * Allow unicode filenames on WaveFile and RecordingWaveFile\n  * Fixed handling stream hold edge cases\n  * Fixed unitialized variable error when using Cython >= 0.15\n\n -- Saul Ibarra <saul@ag-projects.com>  Mon, 17 Sep 2012 11:46:56 +0200\n\npython-sipsimple (0.30.0) unstable; urgency=low\n\n  * Added PUBLISH for presence and dialog events\n  * Added SUBSCRIBE using RLS for presence and dialog events\n  * Added SUBSCRIBE for presence.winfo and dialog.winfo events\n  * Added handing for RLS NOTIFYs for presence and dialog events\n  * Added Offline Presence capability using XCAP pidf-manipulation\n  * Added Icon Storage using XCAP oma-pres-content\n  * Added Presence policy management using XCAP oma-common-policy\n  * Added Addressbook with Presence enabled Contacts\n  * Added MSRP Switch NICKNAME support\n  * Added GRUU support (RFC 5627)\n  * Added ability to configure SIP loop detection\n  * Refactored XML payloads framework and datatypes\n  * Refactored the XCAP manager and its API\n  * Refactored contact management into addressbook management\n  * Refactored interaction between the account and its handlers\n  * Fixed building sipfrag payloads\n  * Fixed crash when bogus G722 payload is received\n  * Fixed crash on SDP version overflow\n  * Fixed removing a stream if a negative response was received\n  * Fixed engine failure on bogus incoming REFER requests\n  * Fixed crash on RTCP decryption when using SRTP\n  * Fixed handling re-INVITEs with empty body\n  * Fixed subscribing to conference event from Bonjour account\n  * Reply with 200 OK to in-dialog OPTIONS requests\n  * Support hostnames in STUN servers list\n  * Skip processing bogus NOTIFY requests\n  * Honor Min-Expires header for REGISTER requests\n  * Adapted to eventlet package rename\n  * Raised dependency on msrplib and xcaplib due to API changes\n\n -- Saul Ibarra <saul@ag-projects.com>  Thu, 06 Sep 2012 18:13:17 +0200\n\npython-sipsimple (0.20.0) unstable; urgency=low\n\n  * Refactored XML document manipulation framework and payloads\n  * Added screen image extension to User from conference\n  * Accumulate chunks in ChatStream if they were segmented\n  * Do not assume content type is text in CPIM messages\n  * Validate participant URI when inviting to a conference\n  * Fixed race condition when stopping uninitialized MSRP stream\n  * Add reason attribute to notification data for SIPSessionTransferDidFail\n    when rejecting\n  * Fixed handling incoming call transfer failures\n  * Dropped support for Python 2.5\n  * Fixed issue with notifications being posted in the wrong order\n  * Updated build instructions\n\n -- Saul Ibarra <saul@ag-projects.com>  Mon, 19 Dec 2011 14:34:44 +0100\n\npython-sipsimple (0.19.0) unstable; urgency=low\n\n  * Added Contact Management API\n  * Integrated XCAP manager into Account\n  * Added WebRTC AEC\n  * Added Call Transfer support\n  * Refactored PJSIP build process to avoid using svn\n  * Allow TLS MSRP transport also for Bonjour accounts\n  * Allow account to be restartable\n  * Added ability to query the system default device name\n  * Added the ability to get the old value of a setting\n  * Added the ability for an XMLApplication to unregister a namespace\n  * Added XCAPTransaction context manager for XCAPManager transactions\n  * Workaround lxml exception when unicode strings contain encoding\n    declaration\n  * Automatically singleton-ize SettingsObject subclasses with static IDs\n  * Avoid processing notification if audio bridges are not created yet\n  * Fixed passing headers dictionary to subscription callback\n  * Fixed getting Subscription-State header parameters\n  * Fixed handling bogus responses to SUBSCRIBE requests\n  * Call the notification handlers in the appropriate threads in\n    application.py\n  * Execute function immediately if already in the requested thread\n  * Fixed parsing Refer-To header\n  * Fixed __eq__ methods to properly compare with unknown type objects\n  * Added the missing __ne__ methods to all the classes defining __eq__\n  * Avoid setting sound devices if none was removed\n  * Handle error if remote ends session while we try to end it as well\n  * Fixed race condition when reading/using the invitation state in\n    Session.end\n  * Added the ability to specify fallback policies when adding an XCAP contact\n  * Fixed bug that changed empty strings into None when loading configuration\n  * Terminate conference subscription at the same stage if session failed or\n    ended\n  * Consider XCAP applications unsupported until proven otherwise\n  * Set default register interval to 3600\n  * Apply changes to audio tail_length in realtime\n  * Don't fail to start audio device if starting the EC fails\n  * Reset stream statistics after retrieving them\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 16 Sep 2011 10:52:41 +0200\n\npython-sipsimple (0.18.2) unstable; urgency=low\n\n  * Added compatibility with Python 2.7\n  * Adapted code for Cython >= 0.13\n  * Don't depend on the debug interpreter, recommend it\n  * Removed unused SSL methods\n  * Removed use of pysupport, use dh_python2 instead\n  * Updated import paths for Null and Singleton for latest python-application\n  * Fixed race condition that resulted in multiple bonjour accounts\n\n -- Saul Ibarra <saul@ag-projects.com>  Wed, 08 Jun 2011 09:11:50 +0200\n\npython-sipsimple (0.18.1) unstable; urgency=low\n\n  * Added push file transfers (RFC5547)\n  * Implemented support for MSRP ACM (RFC6135)\n  * Added file transfers information to conference event package\n  * Fixed string representation of SIP URIs with special characters\n  * Implemented multi-level key based access to configuration objects\n  * Log exceptions that occur while saving the configuration when deleting\n  * Fixed SDP negotiation on bogus answer\n  * Remove SDP attributes when a stream is disabled\n  * Added format list validation for MSRP streams\n  * Added DuplicateIDError to replace ValueError for duplicate ID's\n  * Post notifications when settings objects are created/deleted\n  * Protect AccountManager.load_accounts against being called multiple times\n  * Removed internal AccountManager methods for adding/removing accounts\n  * Refactored API to provide storage backends to SIPApplication\n  * Start accounts in parallel\n  * Protect Session.end against being called multiple times\n  * Don't instantiate DNS resolver if no DNS query will be done\n  * Break circular reference between streams and Session\n\n -- Saul Ibarra <saul@ag-projects.com>  Mon, 23 May 2011 16:34:20 +0200\n\npython-sipsimple (0.18.0) unstable; urgency=low\n\n  * Added support for out-of-dialog REFER\n  * Added add/remove participants functionality to Session\n  * Added support for Subject header\n  * Fixed accepting incoming subscription without any initial content\n  * Fixed exception when NAT type detection is attempted without connectivity\n  * Fixed conference event subscription for Bonjour account\n  * Fixed exceptions when contact URI can't be built for the desired route\n  * Fixed subscription locking issues\n  * Set remote focus on incoming session, if applicable\n  * Fixed building header body with parameters without value\n  * Fixed building UAC and UAS dialogs when headers contain parameters\n  * Fixed setting contact header parameters for subscription\n  * Hide route header for outbound SUBSCRIBE requests\n  * Fixed crashes and increased resilience when connectivity is lost\n  * Fixed exception classes not to update their internal dict\n  * Relax check on SDP origin to increase interoperability\n  * Save XCAP journal after each committed operation to avoid loosing it\n  * Reset XCAP journal when account id changes\n  * Don't use contact URI when building conference Referral and Subscription\n  * Fixed bug where settings with dynamc IDs were not saved in some cases\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 18 Mar 2011 17:00:29 +0100\n\npython-sipsimple (0.17.1) unstable; urgency=low\n\n  * Simplified FileSelector interface and interaction with the application\n  * Fixed Timestamp formatting with offset-aware datetime objects\n  * Return unicode for username and fullname from sipsimple.util.user_info\n  * Made display_name on accounts support unicode\n  * Fixed CPIMIdentity parsing to be unicode aware\n  * Changed SIP headers to handle unicode display names\n  * Made Path datatype inherit from unicode\n  * Simplified disconnect reason on failures\n  * Fixed exception when the session is ended on error conditions\n  * Fixed support for audio devices containing unicode symbols in their name\n  * Fixed detecting backslash in regex\n  * Added request_uri attribute to Invitation\n\n -- Saul Ibarra <saul@ag-projects.com>  Wed, 16 Feb 2011 14:25:28 +0100\n\npython-sipsimple (0.17.0) unstable; urgency=low\n\n  * Added blocking API to WavePlayer\n  * Added peer_address attribute to all request objects\n  * Do not enforce transport on request URI from route\n  * Fixed crash on IncomingRequest deallocation\n  * Simplified and made account contact management consistent\n  * Fixed conference payload to accept multiple Media elements\n  * Build PJSIP with debugging symbols, if specified\n  * Fixed parsing conference-info payload\n  * Removed handling of impossible invitation state transition\n  * Wait for things to stabilize for bonjour after returning from sleep\n  * Don't send SIPSessionDidFail in end if state is None\n  * Only handle records in the local. domain for bonjour\n  * Added ability to compute a FileSelector's file hash later\n  * Added AudioStreamDidTimeout notification\n  * Make request_uri the first argument for Request object\n  * Added remote_contact_header attribute to Invitation\n  * Added generation of -dbg debian package\n  * Fixed exception when an empty SEND is received in the MSRP stream\n  * Added request_uri attribute to Invitation and Subscription\n  * Added conference event support to Session\n  * Added recipients to ChatStreamGotComposingIndication notification\n  * Added remote_media attribute to MSRP streams\n  * Fixed private chat message detection\n  * Send 500 response if we fail to create incoming invitation\n  * Added lock to IncomingSubscription and released GIL where appropriate\n  * Terminate incoming subscription if NOTIFY got 408, 481 or 7xx\n  * Handle local timeout for outgoing NOTIFY requests in IncomingSubscription\n  * Interrupt commands instead of killing and restarting greenlets\n  * Only refresh subscription on events if we already have one\n  * Properly schedule events after system is stable when waking up from sleep\n  * Added missing notification handlers in XCAPManager for system events\n  * Properly perform NAT detection considering all system event triggers\n  * Allow Command to send specific results and also propagate exceptions\n  * Fixed UTC offset in Timestamp class\n  * If the received chat doesn't have a timestamp, build it offset-aware\n  * Added python-dateutil dependency\n  * Added build time dependency on cython-dbg\n  * Reverted wrong changes and made xcap manager test script work again\n  * Fixed race conditions in subscription handlers\n  * Don't have XCAPManager as a singleton to avoid retaining the account\n    forever\n  * Terminate session conference subscription on SIPSessionWillEnd\n  * Reduced subscription retry interval on fatal failures\n  * Fixed receiving empty SEND in file transfer stream\n\n -- Saul Ibarra <saul@ag-projects.com>  Thu, 27 Jan 2011 13:56:55 +0100\n\npython-sipsimple (0.16.5) unstable; urgency=low\n\n  * Fixed matching of media codecs on incoming calls\n  * Allow ip_address to be specified on engine start\n  * Fixed accepted types checking when using CPIM\n  * Fixed CPIM support detection\n  * Generate InvalidStreamError if no compatible payload types are found\n    in ChatStream\n  * Added nameservers used for lookup to the DNSLookupTrace notification\n  * Added InterruptCommand exception\n  * Added DNS resolver autodetection capabilities\n  * Made accessing to the transport parameter of a SIP URI easier\n  * Fixed TLS transport initialization\n  * Fixed XCAPManager shutdown\n  * Adapt XCAPManager test script to changes in the middleware\n  * Handle ConnectionLost error in XCAPManager\n  * Only use fallback candidate list as the last resort\n  * Avoid creating a external reference on the subscriptions lists\n  * Avoid moving external references to resource-lists toplevel\n  * Don't initialize XCAPManager if the server doesn't support certain auids\n  * Reset cached documents if XCAP root changes\n  * Added ThreadManager and moved thread related stuff from util to threading\n  * Reformatted some module docstrings\n  * Made configuration thread safe\n  * Automated finding python packages in setup.py\n  * Updated documentation\n\n -- Saul Ibarra <saul@ag-projects.com>  Tue, 14 Dec 2010 16:57:07 +0100\n\npython-sipsimple (0.16.4) unstable; urgency=low\n\n  * Fixed accessing Message-Account in MWI payload as it could be None\n  * Fixed building codec list when rtpmap line is missing\n  * Match codec names case insensitive\n\n -- Saul Ibarra <saul@ag-projects.com>  Tue, 30 Nov 2010 10:32:03 +0100\n\npython-sipsimple (0.16.3) unstable; urgency=low\n\n  * Changed some option defaults to False\n  * Do not impose limits on the subscription interval\n  * Added all parsed SIP headers to SIPEngineGotMessage notification\n  * Refactored bonjour code to be more efficient and handle all use cases\n  * Fixed crash when parsing Retry-After header\n  * Fixed MSRP chunk transaction status callback\n  * Set the response code and reason when outgoing session times out\n  * Don't answer SUBSCRIBE while deallocating\n  * Fixed crash when Content-Type header is missing for MESSAGE\n  * Do not create an audio stream if not compatible codecs are found\n  * Created ContentType object for representing content type in notifications\n  * Added extra attributes to SIPSubscriptionGotNotify notification\n  * Fixed race condition in Session that caused exceptions in some situations\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 26 Nov 2010 15:18:48 +0100\n\npython-sipsimple (0.16.2) unstable; urgency=low\n\n  * Fixed memory and file descriptor leaks in BonjourServices\n  * Added notifications for Bonjour discovery failures\n  * Refactored Bonjour re-discovery after settings change\n  * Ignore TLS contacts if the Boujour account doesn't have a certificate\n  * Refresh MWI subscription if always_use_my_proxy setting changes\n  * Use always_use_my_proxy setting for MWI subscriptions\n  * Set minimum time for refreshing a subscription to 30 seconds\n  * Wait for 3 hours if MWI subscription fails instead of stopping it\n  * Fixed bonjour discovery when SIP transport list is changed\n  * Made accounts also listen for config changes from SIPSimpleSettings\n  * Do not return routes with unsupported transport from the DNS lookup\n  * Set MSRPRelayAddress setting default port to 2855\n  * Moved server_advertised_uri attribute to the mwi handler\n  * Added reregister method on Account\n  * Added reactivate methods for registrar and mwi\n  * Prefer the server advertised voicemail URI over the user setting\n  * Added account.sip.always_use_my_proxy setting\n  * Use None when the server advertised voicemail URI is an empty string\n  * Reset the server advertised voicemail URI when MWI is disabled\n  * Fixed handling of multiple settings changed at the same time\n  * Remove sip: from the server advertised voicemail uri when saving it\n  * Use capital case letters for acronyms\n  * Remove transport_list setting from BonjourAccount\n  * Reset bonjour neighbours on account deactivation\n  * Turn off ICE by default\n  * Limit PJSIP log level setting value between 0 and 5 to avoid crashes\n  * Fixed handling of Account id change in AccountManager\n  * Fixed handling of the id change of an Account and other SettingsObjects\n  * Made XCAPManager not transition to insync if journal is not empty\n  * Made audio device settings strings and removed unnecessary empty subclases\n  * Made SampleRate only accept valid rates\n  * Added SIPAccountWillActivate and SIPAccountWillDeactivate notifications\n  * Set XCAP User-Agent on application start\n  * Use xml.xsd from local folder instead of importing it remotely\n  * Trigger a XCAP document fetch on some subscription errors\n  * Make port test consistent with the rest of the code\n  * Simplified port range handling and fixed case for odd ports number\n  * Fixed port boundary checks\n  * Fixed incorrect __hash__ method\n  * Use UA string as User-Agent header for XCAP requests\n  * Avoind unnecessary conversion to unicode in PortRange conversion\n  * Added missing __ne__ method to some data types\n  * Fixed saving configuration after assigning DefaultValue to a setting\n  * Added PositiveInteger datatype\n  * Enhanced xcapdiff subscription process\n  * Removed use_xcap_diff setting\n  * Rollback: Changed visibility of command and data channels\n  * Rollback: Avoid using SubHandlingValue object inside XCAPManager\n  * Fixed account elements reload on settings change\n  * Synced Engine default options with settings\n  * Improved default values for various global settings\n  * Use the specific version of cython 0.12.1 for building the package\n  * Enhanced xcapdiff subscription termination\n  * Don't try to unregister if we weren't registered at all\n  * Changed visibility of command and data channels to private\n  * Fixed handling bogus TXT records for XCAP server lookups\n  * Fixed contact edit in XCAPManager when it needs to be removed and readded\n  * Avoid using SubHandlingValue object inside XCAPManager\n  * Fixed building contact name on XCAP manager\n  * Fixed use of identity conditions\n  * Fixed handling of SIPRegistrationDidFail and SIPSubscriptionDidFail exceptions\n  * Fixed handling of SDP c line inside the media stream\n  * Don't wait for pending operations to finish on shutdown\n  * Added cached_cocuments property to XCAPManager\n  * Handle BadStatusLine exception when fetching/updating documents\n  * Added equal and hash methods to Contact, Policy and condition classes\n  * Raise RuntimeError if no cache directory is provided for XCAP documents\n  * Don't keep old transformations if updated rule's action is not 'allow'\n  * Removed some unnecessary NotificationCenter instantiations\n  * Added properties for handling the server advertised voicemail URI\n  * Disable dialog event by default\n  * Increase default subscribe and publish intervals\n  * Added back thread attribute in SIPApplication\n  * Properly fix race condition when first NOTIFY for MWI arrives\n  * Avoid adding more than one MWI subscribe operation to the command channel\n  * Fixed waiting timeout for engine shutdown\n  * Changed name for reactor thread attribute and join thread on stop\n  * Moved Changelog back to toplevel\n  * Fixed boolean parameters in xcap_manager test script\n  * End MWI subscription before ending registration\n\n -- Adrian Georgescu <ag@ag-projects.com>  Thu, 11 Nov 2010 13:31:38 +0100\n\npython-sipsimple (0.16.1) unstable; urgency=low\n\n  * Fixed XML document parsing for unicode objects\n  * Changed default audio sample rate to 44100\n  * Stop using audio device when idle on Snow Leopard\n  * Added short description for a legal sip address format\n  * Send MWI subscription to voicemail_uri if specified\n  * Fixed broken dependency to python-aplication for non-Debian systems\n\n -- Saul Ibarra <saul@ag-projects.com>  Mon, 06 Sep 2010 15:55:28 +0200\n\npython-sipsimple (0.16.0) unstable; urgency=low\n\n  * Added XCAP contacts management based on OMA specifications\n  * Added parser/generator for OMA pres-rules extensions\n  * Added custom extension for extra attributes to entries in resource-lists\n  * Added xcap-caps payload support\n  * Added support for Message Waiting Indicator (MWI)\n  * Added SIPAccountMWIDidFail and SIPAccountMWIDidGetSummary notifications\n  * Added min_expires attribute to SipSubscriptionDidFail notification\n  * Added audio device change detection capability in Windows\n  * Improved logic for determining source IP address used in signalling\n  * Added lookup_xcap_server method to DNSLookup\n  * Added timestamp to sipsimple.util.Command objects\n  * Added generic All and Any objects to sipsimple.util\n  * Added support for deleting children by id in RuleSet and RLSServices\n  * Added extension to add a display-name to common policy rules\n  * Renamed Icon payload definition to PresenceContent\n  * Added support for finding the parent of an element to sipsimple.payloads\n  * Added support for XPath to sipsimple.payloads\n  * Fixed parsing of IdentityMany policy elements\n  * Added support for parsing file-like objects with XML payloads\n  * Improved XMLElement hashes to allow list elements to be hashable\n  * Delegated encoding/decoding of URI values to sipsimple.payloads\n  * Improved unicode support of XML payloads\n  * Removed IP address from rtcp SDP attribute\n  * Avoid refreshing subscription if no NOTIFY was received after\n    an un-SUBSCRIBE\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 03 Sep 2010 10:08:12 +0200\n\npython-sipsimple (0.15.3) unstable; urgency=low\n\n  * Changed default codec list to have G722 as first choice\n  * Fixed handling of case when session is ended before INVITE is sent\n  * Fixed subversion command execution for Windows\n  * Set all devices to None before shutdown\n  * Made the reactor thread a daemon thread\n  * Bumped Standards-Version to 3.9.1\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 13 Aug 2010 11:06:45 +0200\n\npython-sipsimple (0.15.2) unstable; urgency=low\n\n  * Added check to ensure uniqueness of account IDs\n  * Revert G722 adaptive bitshifting that broke re-INVITES\n  * Added python-lxml dependency and sorted dependencies order\n  * Fixed handling unicode characters in the bonjour neighbour display names\n  * Made use of the normalized property of Path configuration datatype\n  * Fixed handling the case when an internal pjsip invitation error occurs\n  * Fixed falling back to the None device when opening an AudioMixer\n  * Null is already an instance, no need to instantiate it anymore\n  * Added exponential timeout to DNS lookups for register\n  * Lower PortAudio revision to 1412 and removed pulse patches\n  * Bumped Standards-Version to 3.9.0\n\n -- Saul Ibarra <saul@ag-projects.com>  Wed, 28 Jul 2010 10:39:05 +0200\n\npython-sipsimple (0.15.1) unstable; urgency=low\n\n  * Added support for Microsoft Windows\n  * Added PJSIP patch for adaptive G722 bitshifting \n  * Improved the initialization of the TLS options when starting the Engine\n  * Added support for terminating sessions in SessionManager\n  * Don't enable bonjour account if bonjour support is not detected\n  * Modified account matching rule for incoming sessions to ignore IP address\n  * Added thread attribute to SIPApplication as the Thread the reactor runs in\n  * Improved synchronization of the audio devices with corresponding entries\n\n -- Saul Ibarra <saul@ag-projects.com>  Wed, 07 Jul 2010 17:17:42 +0200\n\npython-sipsimple (0.15.0) unstable; urgency=low\n\n  * Updated documentation\n  * Added Acknowledgments section\n  * Added support for MSRP Alternative Connection Model\n  * Added NAT detector to SIPApplication object\n  * Don't fail a DNS lookup if an IP address is provided\n  * Made filename argument of start_recording mandatory\n  * Added proposed_streams attribute to SIPSessionGotAcceptProposal\n  * Hide Route header when sending requests out\n  * Fixed adding/removing ports on a bridge after stop was called\n  * Improved SIPURI with pickling and matching capabilities\n  * Improved hold/unhold cascading in Session\n  * Modified WavePlayer and WaveRecorder to allow unicode objects as filename\n  * Fixed crash when system has no soundcard at all\n  * Added ability to select PortAudio revision\n  * Fixed use of the Reason header for determining call disconnect reason\n  * Fixed handling of stream added to conference\n  * Only accept IP addresses for the STUN server list\n  * Moved MSRP transport setting to the account\n  * Fixed ICE support detection\n  * Added configuration instructions for audio device sharing in Linux\n  * Fixed starting of recording on AudioStream while on hold\n  * Fixed MSRP transport used for contacting the relay\n  * Fixed error message in SIPProxyAddress configuration data type\n  * Modified DNSLookup to not timeout completely if NS queries fail\n  * Modified AudioMixer so that it keeps the sound device open on MacOSX 10.6\n  * Added permanent references to AudioStream to keep pjsip from crashing\n  * Fixed Bonjour neighbour discovery handling\n  * Improved sRTP negotiation capabilities\n  * Fixed the build process on MacOSX 10.6\n  * Split the installation instructions for Debian and Ubuntu\n  * Split the installation instructions for MacOSX 10.5 and 10.6\n  * Allow use of cython 0.11.2\n  * Fixed handling of missing ACK in Session\n  * Fixed dialog rules payload namespace\n  * Added pjmedia patch not to close a media stream too fast\n  * Allocate thread descriptor from pool in portaudio callback\n  * Fixed receiving a BYE without receiving a final response to INVITE\n\n -- Saul Ibarra <saul@ag-projects.com>  Mon, 21 Jun 2010 12:59:04 +0200\n\npython-sipsimple (0.14.2) unstable; urgency=low\n\n  * Improved organization of attributes/properties in accounts\n  * Added patch to not consider SDP in all requests/responses\n  * Added host name to the BonjourAccountDidAddNeighbour notification\n  * Improved default value of BonjourAccount's display_name setting\n  * Added support for authentication username\n  * Raised required cython version\n  * Added RootAudioBridge to skip not needed audio processing\n\n -- Saul Ibarra <saul@ag-projects.com>  Tue, 20 Apr 2010 10:02:32 +0200\n\npython-sipsimple (0.14.1) unstable; urgency=low\n\n  * Added missing dependency for AVAHI's Bonjour compatibility\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 09 Apr 2010 18:29:03 +0200\n\npython-sipsimple (0.14.0) unstable; urgency=low\n\n  * Added handling for PJMEDIA_SDPNEG errors in Session\n  * Use transport in general settings when not using a MSRP Relay\n  * Added missing presence and dialog settings\n  * Do not post MSRPLibraryLog for debug level\n  * Added reason argument to reject and reject_proposal methods of Session\n  * Add ability to CANCEL re-INVITEs\n  * Changed the way NotificationProxyLogger sends MSRP trace notifications\n  * Modified the AudioStream to initialize the audio device once it starts\n  * Added Intel architecture to Prerequisites\n  * Calculate ICE candidate priority according to draft\n  * Use regular nomination in ICE instead of aggressive\n  * Changed DNSLookup to fallback to using local nameservers if NS queries\n    fail\n  * Added instructions for installing the cli scripts\n  * Added new setting account.sip.enable_outbound_proxy\n  * Fixed CPIM implementation and improved ChatStream interface\n  * Added notifications for ICE negotiation status\n  * Refactored audio support\n  * Don't initialize ICE transport if remote SDP doesn't offer ICE\n  * Proper forward declaration of Cython objects\n  * Save session start time when media stream did timeout\n  * Added audio conference support\n  * Set disconnect_reason and failure_reason to the Reason header value if\n    present (RFC 3326)\n  * Added sip.transport_list setting to BonjourAccount\n  * Added MSRP settings to Bonjour account\n  * Added publishing and discovery support to BonjourAccount\n  * Modified AudioTransport to not pause/resume the stream on hold/unhold\n  * Add support for ICE keepalive\n  * Changed defauls for use sRTP and codec list for better interoperability\n  * Added a timeout when sending (re-)INVITEs\n  * Updated documentation\n  * Numerous bugfixes\n\n -- Saul Ibarra <saul@ag-projects.com>  Fri, 09 Apr 2010 13:36:50 +0200\n\npython-sipsimple (0.12.0) unstable; urgency=low\n\n  * Removed obsolete desktopsharing.py file\n  * Use OMA standard auids for icon and directory applications\n  * Added slot property to AudioStream\n  * Refactored DNS lookup implementation\n  * Don't bit-shift g722 audio samples\n  * Updated installation procedures\n  * Added IVirtualAudioDevice interface and support for it in AudioStream\n  * Modified DNSLookup to offer both a synchronous and an asynchronous API\n  * Improved logging in DNSLookup.lookup_service\n  * Added the request URI to the SIPEngineGotMessage notification data\n  * Added CIPID (RFC4482) application\n  * Added check in MSRPStreamBase for transport mismatch in settings\n  * Added checks for SDP media stream transport for incoming sessions\n  * Made Registration always communicate via notifications\n  * Added capabilities application (RFC5196)\n  * Added conference XML application (RFC4575)\n  * Added message summary application (RFC3842)\n  * Modified AudioStream to support changing the rtp port in reINVITEs\n  * Pass code and reason of SIP MESSAGE response to its notification\n  * Added dialog-info application (RFC4235)\n  * Added call_in_(twisted|green)_thread utility functions\n  * Added limit utility function\n  * Refactored sipsimple.account using a green model\n  * Restrucutred SIPApplication to simplify the code\n  * Added support for detecting default IP address changes\n  * Added redirect_identities attribute to SIPSessionDidFail notifications\n  * Modified Account to re-register when some settings change\n  * Removed sip.ip_address and rtp.ip_address global settings\n  * Removed msrp.port global setting\n  * Reorganized account registration notifications\n  * Reorganized settings\n  * Patched dns.entropy module which is not thread-safe\n  * Modified SilenceableWaveFile to use a green model\n  * Made Account.credentials a property\n  * Reorganized the contents of the sipsimple.util module\n  * Modified MSRPStreamBase to stop other operations when an end is requested\n  * Added support for SystemDidWakeUpFromSleep notification in registration\n  * Moved Timestamp from sipsimple.applications.util to sipsimple.util\n  * Removed sipclients related modules, scripts and data from the project\n  * Reorganized packages and modules\n  * Numerous bug fixes\n\n -- Lucian Stanescu <luci@ag-projects.com>  Wed, 20 Jan 2010 12:21:35 +0000\n\npython-sipsimple (0.9.1) unstable; urgency=low\n\n  * Prepare next version\n\n -- Adrian Georgescu <ag@ag-projects.com>  Wed, 26 Aug 2009 15:13:16 +0200\n\npython-sipsimple (0.9.0) unstable; urgency=low\n\n  * Added upgrade guide:\n    Read this wiki page when upgrading from a previous version\n  * Added developer guide:\n    http://sipsimpleclient.org/projects/sipsimpleclient/wiki/SipDeveloperGuide\n  * Implemented notifications system from python-application\n  * Added event-driven middleware API based on notifications:\n    http://sipsimpleclient.org/projects/sipsimpleclient/wiki/SipMiddlewareApi\n  * Added high-level configuration API:\n    http://sipsimpleclient.org/projects/sipsimpleclient/wiki/SipConfigurationAPI\n    Added sip_settings to manage the configuration framework\n  * Configuration file config.ini is now deprecated. Use\n    sip_migrate_settings to migrate settings from previous config.ini \n    to the new configuration API\n  * Added synchronous API for non-blocking operations\n  * Adapted all command line tools to the new APIs\n  * Added re-INVITE (hold/un-hold, adding and removing other media types)\n  * Added sip_session script that combines MSRP chat and RTP audio in one\n    session, media can be added/subtracted to/from active session. The\n    script can be used for both incoming and outgoing sessions\n  * Unify command line arguments for command line tools\n  * Added dummy audio device support for systems without sound card\n  * Added --auto-answer and --auto-hangup to sip_audio_session script. \n    sip_audio_session script can now be used for scripting alarms that check\n    both siganling and media paths, it can detect missing ACK, negative SIP\n    response codes and missing RTP media after call setup\n  * sip_send_file and sip_desktop_sharing temporarily disabled until\n    migrated to the new APIs\n  * Added asynchronous DNS lookup module and removed DNS lookups from core\n  * Added Session manager to manage multiple SIP sessions\n  * Added Account manager to manage multiple SIP accounts\n  * Integrated SIP registration into the SIP account\n  * Added next hop failover for INVITE and REGISTER methods\n  * Made Route argument mandatory in SIP core object creation\n  * Allow settable Contact URI for objects in SIP core\n  * Better support for server-less scenarios (P2P and bonjour)\n  * Added support for TLS in P2P/bonjour mode for both SIP and MSRP\n  * Integrated various patches into PJSIP, Eventlet and Greenlet projects\n  * Ported eventlet to ARM CPUs, msrp works now on Nokia 810\n  * Improved ICE/STUN support and related DNS lookups\n  * Improved logging to file and console for SIP, MSRP, PJSIP an core\n    notifications, added runtime control for traces in scripts\n  * Added support for draft-ietf-mmusic-file-transfer-mech-11 in msrplib\n  * Added support for chunking in msrplib\n  * Splited sipclient Debian package into python-sipsimple and sipsimple-cli\n  * Numerous bug fixes\n\n -- Dan Pascu <dan@ag-projects.com>  Mon, 13 Apr 2009 16:56:50 +0300\n\nsipclient (0.4.0) unstable; urgency=low\n\n  * Added desktop sharing using VNC over MSRP\n  * Added PJSIP patch to write and parse i= line to SDP and updated SDP\n    wrapper classes to use it\n  * Added --pjsip-clean-compile option to setup.py\n  * Continue with present PJSIP tree if SVN update fails in setup.py\n  * Revised Invitation state machine, method names, events and internals\n  * Only ring on 180 in sip_audio_session.py\n  * Allow Credentials object to not have a password set\n  * Improved scripts to print any remaining logging message after the Engine\n    has been shut down\n  * Catch uncaught exceptions in PJSIP callbacks and generate an event to\n    inform the application\n  * Disconnect if no audio is received for 10 seconds in sip_audio_session.py\n  * Use default_host_ip from python-application if local_ip is set to None in\n    Engine\n  * Integrated notification system from python-application\n  * Renamed all event names to new notification naming scheme\n  * Changed interface of Engine class in order to use Singleton metaclass from\n    python-application\n  * Fixed some threading bugs in the core\n  * Renamed anything related to PyPJUA to SIP core\n  * Renamed pypjua module to sipsimple\n  * Fixed various bugs in XML payload handling\n  * Made small, cosmetic changes in presence-related scripts\n  * Set return code of scripts based on SIP status codes\n  * Added --auto-hangup option to sip_audio_session to terminate a call after\n    a specified amount of time\n  * Enhanced XML applications in order to be more robust in usage and allow for\n    future implementation of features such as xcap-diff\n  * Updated eventlet-based interface to engine and moved it to green package\n  * Moved logging from green classes into logstate.py module\n  * Fixed bug: in CPIM headers 'sips' was parsed as 'sip'\n  * Fixed bug: CPIM content was not generated / parsed properly (must add\n    space before Content-Type line)\n  * sip_im_session: throttle played sounds and play them at specified volume\n  * sip_im_session: calling from command line is equivalent to issuing :call\n  * sip_im_session: do things in the background when possible (like\n    registrations and closing sessions)\n  * sip_im_session: print a calming message if it takes longer than 1 sec to\n    finish SIP transactions before exit\n  * sip_im_session: added --no-register option\n  * sip_im_session and sip_send_file: added --msrp-tcp option\n  * sip_im_session: save chat history under .sipclient/history\n  * sip_im_session: hide \"Early session\" messages\n  * sip_im_session and sip_send file: relay can no longer be used for outgoing\n    session. -r auto option is deprecated.\n  * sip_send_file: fixed -m option to work\n  * sip_im_session and sip_send_file: added --trace-engine option\n  * sip_im_session: fixed to ignore path in incoming file transfers\n  * sip_send_file: fixed not to put path in file transfer description\n  * Added iso8601.py by Michael Twomey for parsing CPIM's DateTime header\n  * CPIM now puts DateTime header in every message. DateTime is also used now\n    when displaying incoming messages\n  * Fixed green package to end session with 500 in case of exception (not 488)\n  * sip_im_session: don't exit if failed to parse an incoming message\n  * Fixed shutdown functions not to silent pypjua errors\n  * Avoid hiding tracebacks by not using potentially blocking code in finally\n  * Fixed a number of bugs in chat scripts\n  * Removed debug_util.py\n  * Removed chatroom.py\n  * Removed trafficlog.py\n\n -- Adrian Georgescu <ag@ag-projects.com>  Mon, 19 Jan 2009 17:26:02 +0100\n\nsipclient (0.3.0) unstable; urgency=low\n\n  * This version requires eventlet for twisted, which is not yet available as\n    debian package. See doc/INSTALL.x for how to manually install eventlet\n  * Purge the old debian package and/or remove any command line tools starting\n    with sip_ and  xcap_ from the path where they have been installed\n  * Renamed sip_rtp_audio_session to sip_audio_session\n  * Removed sip_msrp_im_session and sip_msrp_file_transfer scripts\n  * Added sip_im_session script, supporting chats with multiple other parties\n    and incoming file transfers\n  * Added sip_send_file for sending files over SIP/MSRP in a batch mode\n  * Added auto_accept_file_transfers General option\n  * Added rtp_port_range General option\n  * Added listen_udp General option\n  * Added file_transfer_directory General option\n  * Added history_directory General option\n  * Added log_directory General option\n  * Added msrp_relay SIP account option\n  * Play sounds when send and receive IM\n  * Added xcap_rls_services script\n  * Added rtp_port_range init and runtime option to Engine/PJSIPUA\n  * Added realtime echo cancellation adjustment to audio session script\n  * Remodeled Invitation class to mirror PJSIP states and communicate with\n    application by means of SDPSession objects\n  * Adjusted audio and IM session scripts to use this new Invitation class\n  * Implemented RTPTransport and AudioTransport classes, which wrap PJSIP\n    media transport and audio stream functionality respectively\n  * Refactored SIPURI, Credentials and Route classes to be dynamic\n  * Added foreign thread and deallocation checking to PyPJUA\n  * Prevented PJLIB calles in import to improve Windows compatibility\n  * Removed dependency on python-application for PyPJUA\n  * Added msrplib: MSRP protocol implementation powered by twisted/eventlet\n  * Added twisted/eventlet wrapper for Engine\n  * Added creation of history, log and file transfer directories in enrollment\n  * Made sip traces get logged in <log_directory>/<sip_address>/sip_trace.txt\n  * Added script sip_auto_publish_presence\n  * Made sip_subscribe_rls script subscribe by default to username-buddies@domain\n\n -- Adrian Georgescu <ag@ag-projects.com>  Sat, 29 Nov 2008 10:44:33 +0100\n\nsipclient (0.2.3) unstable; urgency=low\n\n  * Updated MacOSX installation procedure from sources\n  * Added fink installation from binary packages\n  * Update the server software the client is tested against\n  * Put version in default User-Agent header\n  * Renamed obsolete setting name presence to use_presence_agent\n  * Improved documentation\n  * Define log directory in config file\n  * More comments about settings from sample config file\n  * Update linux install procedure with debian package installation instructions\n  * Use the etag returned after an XCAP PUT so as not to need a GET afterwards\n  * Change the name of the config option presence to use_presence_agent and document it\n  * Fix buggy interconnections between conference bridge slots\n  * Make the sip_subscribe_winfo script also use the listen_udp option\n  * Do a GET after a HTTP error in PUT for pres-rules  \n  * Ported new-style SRV lookup to sip_msrp_file_transfer script\n  * Ported new-style SRV lookup to sip_msrp_im_session script\n  * Change order of display (available accounts, current account)\n  * Record audio files to the history directory\n  * Fix sip_subscribe_winfo when polite-blocking and change output\n  * Add xcap_pres_rules script\n  * Toggle logging at runtime in sip_register\n  * Better description of what the scripts do\n  * Make sip_register script exit after a number of REGISTERs\n  * Print current pres rules when sip_subscribe_winfo starts\n  * Add polite-block option to sip_subscribe_winfo script\n  * Added PJSIP version string to default User-Agent header\n  * Fix for bug in accepting SDP streams\n  * Added LICENSE file to MANIFEST.in\n\n -- Adrian Georgescu <ag@ag-projects.com>  Wed, 29 Oct 2008 19:46:25 +0100\n\nsipclient (0.2.2) unstable; urgency=low\n\n  * Small bug fixes\n  * Recording capability added\n  * Make sip_subscribe_rls script accept multipart/related content-type\n  * Allow setting basic presence in sip_publish_presence script\n\n -- Lucian Stanescu <luci@ag-projects.com>  Wed, 15 Oct 2008 17:39:34 +0200\n\nsipclient (0.2.1) unstable; urgency=low\n\n  * Include the xml schemas\n  * Include Debian packages instructions in docs/INSTALL.linux\n  * A minimal configuration file is generated if not found\n  * Add 'Supported' header when subscribing to RLS services URIs\n  * Added local IP address and port to listen on for UDP packets to\n    configuration file\n  * Added registerless \"bonjour\" account to relevant scripts\n  * Improved SRV lookup procedure and do full lookup for outbound proxy\n  * Do not consider 404 an error when getting the pres-rules document in sip_subscribe_winfo\n  * Make the UDP limit 64K\n\n -- Lucian Stanescu <luci@ag-projects.com>  Mon, 13 Oct 2008 17:29:48 +0200\n\nsipclient (0.2) unstable; urgency=low\n\n  * Initial release\n\n -- Lucian Stanescu <luci@ag-projects.com>  Mon, 13 Oct 2008 10:29:08 +0200\n\n"
  },
  {
    "path": "debian/compat",
    "content": "11\n"
  },
  {
    "path": "debian/control",
    "content": "Source: python-sipsimple\nSection: python\nPriority: optional\nMaintainer: Dan Pascu <dan@ag-projects.com>\nUploaders: Adrian Georgescu <ag@ag-projects.com>, Tijmen de Mes <tijmen@ag-projects.com>\nBuild-Depends: debhelper (>= 11),\n               dh-python,\n               python-all-dev (>= 2.7),\n               python-all-dbg (>= 2.7),\n               cython-dbg (>= 0.19),\n               libasound2-dev,\n               libssl-dev,\n               libv4l-dev,\n               libavcodec-dev (>= 7:2.7),\n               libavformat-dev (>= 7:2.7),\n               libavutil-dev (>= 7:2.7),\n               libswscale-dev (>= 7:2.7),\n               libx264-dev,\n               libvpx-dev,\n               libsqlite3-dev,\n               pkg-config,\n               uuid-dev\nStandards-Version: 4.5.0\nHomepage: http://sipsimpleclient.org\n\nPackage: python-sipsimple\nArchitecture: any\nDepends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends},\n         python-application (>= 2.8.0),\n         python-dateutil,\n         python-dnspython (>= 1.9),\n         python-eventlib,\n         python-gnutls,\n         python-lxml,\n         python-msrplib (>= 0.20.0),\n         python-otr (>= 1.2.0),\n         python-twisted-core (>= 8.1.0),\n         python-xcaplib (>= 1.0.17)\nSuggests: libavahi-compat-libdnssd1\nProvides: ${python:Provides}\nDescription: Python SDK for development of SIP end-points\n SIP SIMPLE client SDK is a Software Development Kit for easy development of\n SIP end-points that support rich media like Audio, Video, Instant Messaging,\n File Transfers, Desktop Sharing and Presence. Other media types can be added\n by using an extensible high-level API.\n\n"
  },
  {
    "path": "debian/copyright",
    "content": "Copyright: 2008-2020 AG Projects\n\nLicense: GPL-3+\n\n    This package is free software; you can redistribute it and/or modify it\n    under the terms of the GNU General Public License as published by the\n    Free Software Foundation; either version 3 of the License, or (at your\n    option) any later version.\n\n    This package is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n    GNU General Public License for more details.\n\n    For a copy of the license see /usr/share/common-licenses/GPL-3\n\n"
  },
  {
    "path": "debian/docs",
    "content": "docs/DeveloperGuide.txt\n"
  },
  {
    "path": "debian/python-sipsimple.lintian-overrides",
    "content": "binary: possible-gpl-code-linked-with-openssl\n"
  },
  {
    "path": "debian/rules",
    "content": "#!/usr/bin/make -f\n\nexport DEB_BUILD_HARDENING = 1\nexport PYBUILD_NAME = sipsimple\n\n%:\n\tdh $@ --with python2 --buildsystem=pybuild\n\noverride_dh_clean:\n\tdh_clean\n\trm -rf build dist MANIFEST\n\n"
  },
  {
    "path": "debian/source/format",
    "content": "3.0 (native)\n"
  },
  {
    "path": "deps/pjsip/COPYING",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.\n"
  },
  {
    "path": "deps/pjsip/Makefile",
    "content": "include build.mak\ninclude build/host-$(HOST_NAME).mak\n-include user.mak\ninclude version.mak\n\nLIB_DIRS = pjlib/build pjlib-util/build pjnath/build third_party/build pjmedia/build pjsip/build\nDIRS = $(LIB_DIRS) $(EXTRA_DIRS)\n\nifdef MINSIZE\nMAKE_FLAGS := MINSIZE=1\nendif\n\nall clean dep depend print:\n\tfor dir in $(DIRS); do \\\n\t\tif $(MAKE) $(MAKE_FLAGS) -C $$dir $@; then \\\n\t\t    true; \\\n\t\telse \\\n\t\t    exit 1; \\\n\t\tfi; \\\n\tdone\n\ndistclean realclean:\n\tfor dir in $(DIRS); do \\\n\t\tif $(MAKE) $(MAKE_FLAGS) -C $$dir $@; then \\\n\t\t    true; \\\n\t\telse \\\n\t\t    exit 1; \\\n\t\tfi; \\\n\tdone\n\t$(HOST_RM) config.log\n\t$(HOST_RM) config.status\n\nlib:\n\tfor dir in $(LIB_DIRS); do \\\n\t\tif $(MAKE) $(MAKE_FLAGS) -C $$dir all; then \\\n\t\t    true; \\\n\t\telse \\\n\t\t    exit 1; \\\n\t\tfi; \\\n\tdone; \\\n\n\n.PHONY: lib doc\n\ndoc:\n\t@if test \\( ! \"$(WWWDIR)\" == \"\" \\) -a \\( ! -d $(WWWDIR)/pjlib/docs/html \\) ; then \\\n\t\techo 'Directory \"$(WWWDIR)\" does not look like a valid pjsip web directory'; \\\n\t\texit 1; \\\n\tfi\n\tfor dir in $(DIRS); do \\\n\t\tif $(MAKE) $(MAKE_FLAGS) -C $$dir $@; then \\\n\t\t    true; \\\n\t\telse \\\n\t\t    exit 1; \\\n\t\tfi; \\\n\tdone\n\t\nLIBS = \tpjlib/lib/libpj-$(TARGET_NAME).a \\\n\tpjlib-util/lib/libpjlib-util-$(TARGET_NAME).a \\\n\tpjnath/lib/libpjnath-$(TARGET_NAME).a \\\n\tpjmedia/lib/libpjmedia-$(TARGET_NAME).a \\\n\tpjmedia/lib/libpjmedia-audiodev-$(TARGET_NAME).a \\\n\tpjmedia/lib/libpjmedia-codec-$(TARGET_NAME).a \\\n    \tpjsip/lib/libpjsip-$(TARGET_NAME).a \\\n\tpjsip/lib/libpjsip-ua-$(TARGET_NAME).a \\\n\tpjsip/lib/libpjsip-simple-$(TARGET_NAME).a \\\n\tpjsip/lib/libpjsua-$(TARGET_NAME).a\nBINS = \tpjsip-apps/bin/pjsua-$(TARGET_NAME)$(HOST_EXE) \n\nsize:\n\t@echo -n 'Date: '\n\t@date\n\t@echo\n\t@for lib in $(LIBS); do \\\n\t\techo \"$$lib:\"; \\\n\t\tsize -t $$lib | awk '{print $$1 \"\\t\" $$2 \"\\t\" $$3 \"\\t\" $$6}'; \\\n\t\techo; \\\n\tdone\n\t@echo\n\t@for bin in $(BINS); do \\\n\t\techo \"size $$bin:\"; \\\n\t\tsize $$bin; \\\n\tdone\n\n#dos2unix:\n#\tfor f in `find . | egrep '(mak|h|c|S|s|Makefile)$$'`; do \\\n#\t\tdos2unix \"$$f\" > dos2unix.tmp; \\\n#\t\tcp dos2unix.tmp \"$$f\"; \\\n#\tdone\n#\trm -f dos2unix.tmp\n\nxhdrid:\n\tfor f in `find . | egrep '\\.(h|c|S|s|cpp|hpp)$$'`; do \\\n\t\techo Processing $$f...; \\\n\t\tcat $$f | sed 's/.*\\$$Author\\$$/ */' > /tmp/id; \\\n\t\tcp /tmp/id $$f; \\\n\tdone\n\nselftest: pjlib-test pjlib-util-test pjnath-test pjmedia-test pjsip-test pjsua-test\n\npjlib-test: pjlib/bin/pjlib-test-$(TARGET_NAME)\n\tcd pjlib/build && ../bin/pjlib-test-$(TARGET_NAME)\n\npjlib-util-test: pjlib-util/bin/pjlib-util-test-$(TARGET_NAME)\n\tcd pjlib-util/build && ../bin/pjlib-util-test-$(TARGET_NAME)\n\npjnath-test: pjnath/bin/pjnath-test-$(TARGET_NAME)\n\tcd pjnath/build && ../bin/pjnath-test-$(TARGET_NAME)\n\npjmedia-test: pjmedia/bin/pjmedia-test-$(TARGET_NAME)\n\tcd pjmedia/build && ../bin/pjmedia-test-$(TARGET_NAME)\n\npjsip-test: pjsip/bin/pjsip-test-$(TARGET_NAME)\n\tcd pjsip/build && ../bin/pjsip-test-$(TARGET_NAME)\n\npjsua-test:\n\tcd tests/pjsua && python runall.py\n\nprefix = $(ac_prefix)\n\ninstall:\n\tmkdir -p $(DESTDIR)$(prefix)/lib\n\tcp -f $(APP_LIB_FILES) $(DESTDIR)$(prefix)/lib/\n\tmkdir -p $(DESTDIR)$(prefix)/include\n\tfor d in pjlib pjlib-util pjnath pjmedia pjsip; do \\\n\t\tcp -RLf $$d/include/* $(DESTDIR)$(prefix)/include/; \\\n\tdone\n\tmkdir -p $(DESTDIR)$(prefix)/lib/pkgconfig\n\tsed -e \"s!@PREFIX@!$(DESTDIR)$(prefix)!\" libpjproject.pc.in | \\\n\t\tsed -e \"s/@PJ_VERSION@/$(PJ_VERSION)/\" | \\\n\t\tsed -e \"s!@PJ_LDLIBS@!$(PJ_LDLIBS)!\" | \\\n\t\tsed -e \"s!@PJ_INSTALL_CFLAGS@!$(PJ_INSTALL_CFLAGS)!\" > $(DESTDIR)/$(prefix)/lib/pkgconfig/libpjproject.pc\n"
  },
  {
    "path": "deps/pjsip/README.txt",
    "content": " Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n\n This program is free software: you can redistribute it and/or modify it\n under the terms of the GNU General Public License as published by the Free\n Software Foundation, either version 2 of the License, or (at your option)\n any later version.\n\n This program is distributed in the hope that it will be useful, but\n WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n for more details.\n\n You should have received a copy of the GNU General Public License along\n with this program. If not, see http://www.gnu.org/licenses/.\n\n\nGetting Started: Building and Using PJSIP and PJMEDIA\n\n   [Last Update: $Date: 2007-02-02 20:42:44 +0000 (Fri, 02 Feb 2007) $]\n\n                                                   Print Friendly Page\n     _________________________________________________________________\n\n   This article describes how to download, customize, build, and use the open\n   source PJSIP and PJMEDIA SIP and media stack. The online (and HTML) version\n   of this file can be downloaded from http://www.pjsip.org/using.htm\n\n\nQuick Info\n     _________________________________________________________________\n\n   Building with GNU tools (Linux, *BSD, MacOS X, mingw, etc.)\n          Generally these should be all that are needed to build the libraries,\n          applications, and samples:\n\n   $ ./configure\n   $ make dep && make clean && make\n\n   Building Win32 Target with Microsoft Visual Studio\n          Generally we can just do these steps:\n\n         1. Visual Studio 6: open pjproject.dsw workspace,\n         2. Visual Studio 2005: open pjproject-vs8.sln solution,\n         3. Create an empty pjlib/include/pj/config_site.h, and\n         4. build the pjsua application.\n\n   Building for Windows Mobile\n          Generally these are all that are needed:\n\n         1. Open pjsip-apps/build/wince-evc4/wince_demos.vcw EVC4 workspace,\n         2. Create an empty pjlib/include/pj/config_site.h, and\n         3. build the pjsua_wince application.\n\n   Invoking Older Build System (e.g. for RTEMS)\n          Generally these should be all that are needed to build the libraries,\n          applications, and samples:\n\n   $ ./configure-legacy\n   $ make dep && make clean && make\n\n   Locating Output Binaries/Libraries\n          Libraries will be put in lib directory, and binaries will be put in\n          bin directory, under each projects.\n\n   Running the Applications\n          After successful build, you can try running pjsua application on\n          pjsip-apps/bin   directory.   PJSUA  manual  can  be  found  in\n          http://www.pjsip.org/pjsua.htm page.\n\n\nTable of Contents:\n     _________________________________________________________________\n\n   1. Getting the Source Distribution\n\n     1.1 Getting the Release tarball\n\n     1.2 Getting from Subversion trunk\n\n     1.3 Source Directories Layout\n\n   2. Build Preparation\n\n     2.1 config_site.h file\n\n     2.2 Disk Space Requirements\n\n   3.  Building Linux, *nix, *BSD, and MacOS X Targets with GNU Build\n   Systems\n\n     3.1 Supported Targets\n\n     3.2 Requirements\n\n     3.3 Running configure\n\n     3.4 Running make\n\n     3.5 Cross Compilation\n\n     3.6 Build Customizations\n\n   4. Building for Windows Targets with Microsoft Visual Studio\n\n     4.1 Requirements\n\n     4.2 Building the Projects\n\n     4.3 Debugging the Sample Application\n\n   5. Building for Windows Mobile Targets (Windows CE/WinCE/PDA/SmartPhone)\n\n     5.1 Requirements\n\n     5.2 Building the Projects\n\n   6. Older PJLIB Build System for Non-Autoconf Targets (e.g. RTEMS)\n\n     6.1 Supported Targets\n\n     6.2 Invoking the Build System\n\n   7. Running the Applications\n\n     7.1 pjsua\n\n     7.2 Sample Applications\n\n     7.3 pjlib-test\n\n     7.4 pjsip-test\n\n   8. Using PJPROJECT with Applications\n\n\n   Appendix I: Common Problems/Frequently Asked Question (FAQ)\n\n     I.1 fatal error C1083: Cannot open include file: 'pj/config_site.h':\n   No such file or directory\n\n\n1. Getting the Source Code Distribution\n     _________________________________________________________________\n\n   All libraries (PJLIB, PJLIB-UTIL, PJSIP, PJMEDIA, and PJMEDIA-CODEC) are\n   currently distributed under a single source tree, collectively named as\n   PJPROJECT or just PJ libraries. These libraries can be obtained by either\n   downloading the release tarball or getting them from the Subversion trunk.\n\n\n1.1 Getting the Release tarball\n     _________________________________________________________________\n\n   Getting the released tarball is a convenient way to obtain stable version of\n   PJPROJECT. The tarball may not contain the latest features or bug-fixes, but\n   normally it is considered more stable as each will be tested more rigorously\n   before released.\n\n   The   latest   released   tarball   can   be   downloaded   from   the\n   http://www.pjsip.org/download.htm.\n\n\n1.2 Getting from Subversion trunk\n     _________________________________________________________________\n\n   PJPROJECT  Subversion  repository  will always contain the latest/most\n   up-to-date version of the sources. Normally the Subversion repository is\n   always kept in a \"good\" state. However, there's always a chance that things\n   break  and  the  tree  doesn't  build  correctly (particularly for the\n   \"not-so-popular\" targets), so please consult the mailing list should there\n   be any problems.\n\n   Using Subversion also has benefits of keeping the local copy of the source\n   up to date with the main PJ source tree and to easily track the changes made\n   to the local copy, if any.\n\n\nWhat is Subversion\n\n   Subversion (SVN) is Open Source version control system similar to CVS.\n   Subversion homepage is in http://subversion.tigris.org/\n\n\nGetting Subversion Client\n\n   A Subversion (SVN) client is needed to download the PJ source files from\n   pjsip.org  SVN  tree.  SVN  client  binaries  can  be  downloaded from\n   http://subversion.tigris.org/, and the program should be available for\n   Windows, Linux, MacOS X, and many more platforms.\n\n\nGetting the Source for The First Time\n\n   Once Subversion client is installed, we can use these commands to initially\n   retrieve the latest sources from the Subversion trunk:\n\n\n\n   $ svn co http://svn.pjproject.net/repos/pjproject/trunk pjproject\n   $ cd pjproject\n\n\nKeeping The Local Copy Up-to-Date\n\n   Once sources have been downloaded, we can keep the local copy up to date by\n   periodically synchronizing the local source with the latest revision from\n   the  PJ's  Subversion  trunk. The mailing list provides best source of\n   information about the availability of new updates in the trunk.\n\n   To  update  the  local  copy  with the latest changes in the main PJ's\n   repository:\n\n\n\n   $ cd pjproject\n   $ svn update\n\n\nTracking Local and Remote Changes\n\n   To see what files have been changed locally:\n\n\n\n   $ cd pjproject\n   $ svn status\n\n   The above command only compares local file against the original local copy,\n   so it doesn't require Internet connection while performing the check.\n\n   To see both what files have been changed locally and what files have been\n   updated in the PJ's Subversion repository:\n\n\n\n   $ cd pjproject\n   $ svn status -u\n\n   Note that this command requires active Internet connection to query the\n   status of PJPROJECT's source repository.\n\n\n1.3 Source Directories Layout\n     _________________________________________________________________\n\nTop-Level Directory Layout\n\n   The top-level directories (denoted as $TOP here) in the source distribution\n   contains the following sub-directories:\n\n   $TOP/build\n          Contains makefiles that are common for all projects.\n\n   $TOP/pjlib\n          Contains  header  and  source files of PJLIB. PJLIB is the base\n          portability  and  framework  library which is used by all other\n          libraries\n\n   $TOP/pjlib-util\n          Contains  PJLIB-UTIL  header and source files. PJLIB-UTIL is an\n          auxiliary library that contains utility functions such as scanner,\n          XML, STUN, MD5 algorithm, getopt() implementation, etc.\n\n   $TOP/pjmedia\n          Contains PJMEDIA and PJMEDIA-CODEC header and source files. The\n          sources of various codecs (such as GSM, Speex, and iLBC) can be found\n          under this directory.\n\n   $TOP/pjsip\n          Contains PJSIP header and source files.\n\n   $TOP/pjsip-apps\n          Contains source code for PJSUA and various sample applications.\n\n\nIndividual Directory Inside Each Project\n\n   Each library directory further contains these sub-directories:\n\n   bin\n          Contains binaries produced by the build process.\n\n   build\n          Contains build scripts/makefiles, project files, project workspace,\n          etc. to build the project. In particular, it contains one Makefile\n          file  to  build the project with GNU build systems, and a *.dsw\n          workspace file to build the library with Microsoft Visual Studio 6 or\n          later.\n\n   build/output\n          The build/output directory contains the object files and other files\n          generated by the build process. To support building multiple targets\n          with a single source tree, each build target will occupy a different\n          subdirectory under this directory.\n\n   build/wince-evc4\n          This directory contains the project/workspace files to build Windows\n          CE/WinCE version of the project using Microsoft Embedded Visual C++\n          4.\n\n   build/wince-evc4/output\n          This directory contains the library, executable, and object files\n          generated by Windows Mobile build process.\n\n   docs\n          Contains Doxygen configuration file (doxygen.cfg) to generate online\n          documentation from the source files. The output documentation will be\n          put in this directory as well (for example, docs/html directory for\n          the HTML files).\n\n          (to generate Doxygen documentation from the source tree, just run\n          \"doxygen docs/doxygen.cfg\" in the individual project directory. The\n          generated files will reside in docs directory).\n\n   include\n          Contains the header files for the project.\n\n   lib\n          Contains libraries produced by the build process.\n\n   src\n          Contains the source files of the project.\n\n\n2. Build Preparation\n     _________________________________________________________________\n\n2.1 Create config_site.h file\n     _________________________________________________________________\n\n   Before source files can be built, the pjlib/include/pj/config_site.h file\n   must be created (it can just be an empty file).\n\n   Note:\n          When the Makefile based build system is used, this process is taken\n          care by the Makefiles. But when non-Makefile based build system (such\n          as Visual Studio) is used, the config_site.h file must be created\n          manually.\n\n\nWhat is config_site.h File\n\n   The pjlib/include/pj/config_site.h contains local customizations to the\n   libraries.\n\n   All customizations should be put in this file instead of modifying PJ's\n   files, because if PJ's files get modified, then those modified files will\n   not be updated the next time the source is synchronized. Or in other case,\n   the local modification may be overwritten with the fresh copy from the SVN.\n\n   Putting the local customization to the config_site.h solves this problem,\n   because this file is not included in the version control, so it will never\n   be overwritten by \"svn update\" command.\n\n   Please find list of configuration macros that can be overriden from these\n   files:\n     * PJLIB Configuration (the pjlib/config.h file)\n     * PJLIB-UTIL Configuration (the pjlib-util/config.h file)\n     * PJMEDIA Configuration (the pjmedia/config.h file)\n     * PJSIP Configuration (the pjsip/sip_config.h file)\n\n   A     sample    config_site.h    file    is    also    available    in\n   pjlib/include/config_site_sample.h.\n\n\nCreating config_site.h file\n\n   The simplest way is just to create an empty file, to use whetever default\n   values set by the libraries.\n\n   Another way to create the config_site.h file is to write something like the\n   following:\n\n\n   // Uncomment to get minimum footprint (suitable for 1-2 concurrent calls\n   only)\n   //#define PJ_CONFIG_MINIMAL_SIZE\n   // Uncomment to get maximum performance\n   //#define PJ_CONFIG_MAXIMUM_SPEED\n   #include <pj/config_site_sample.h>\n\n\n2.2 Disk Space Requirements\n     _________________________________________________________________\n\n   The building process needs:\n   about 50-60 MB of disk space to store the uncompressed source files, and\n     * about 30-50 MB of additional space for building each target\n\n   (Visual Studio Debug and Release are considered as separate targets)\n\n\n3. Building Linux, *nix, *BSD, and MacOS X Targets with GNU Build Systems\n     _________________________________________________________________\n\n3.1 Supported Targets\n     _________________________________________________________________\n\n   The  new,  autoconf  based  GNU  build system can be used to build the\n   libraries/applications for the following targets:\n     * Linux/uC-Linux (i386, Opteron, Itanium, MIPS, PowerPC, etc.),\n     * MacOS X (PowerPC),\n     * mingw (i386),\n     * FreeBSD and maybe other BSD's (i386, Opteron, etc.),\n     * RTEMS with cross compilation (ARM, powerpc),\n     * etc.\n\n\n3.2 Requirements\n     _________________________________________________________________\n\n   In order to use PJ's GNU build system, these typical GNU tools are needed:\n     * GNU make (other make will not work),\n     * GNU binutils for the target, and\n     * GNU gcc for the target.\n     * OpenSSL header files/libraries (optional) if TLS support is wanted.\n\n   In addition, the appropriate \"SDK\" must be installed for the particular\n   target (this could just be a libc and the appropriate system abstraction\n   library such as Posix).\n\n   The build system is known to work on the following hosts:\n     * Linux, many types of distributions.\n     * MacOS X 10.2\n     * mingw (Win2K, XP)\n     * FreeBSD (must use gmake instead of make)\n\n   Building Win32 applications with Cygwin is currently not supported by the\n   autoconf script (there is some Windows header conflicts), but one can still\n   use the old configure script by calling ./configure-legacy. More over,\n   cross-compilations might also work with Cygwin.\n\n\n3.3 Running configure\n     _________________________________________________________________\n\nUsing Default Settings\n\n   Run  \"./configure\"  without  any  options to let the script detect the\n   appropriate settings for the host:\n\n\n\n   $ cd pjproject\n   $ ./configure\n   ...\n\n   Notes:\n          The default settings build the libraries in \"release\" mode, with\n          default CFLAGS set to \"-O2 -DNDEBUG\". To change the default CFLAGS,\n          we can use the usual \"./configure CFLAGS='-g'\" construct.\n\n    Features Customization\n\n   With the new autoconf based build system, most configuration/customization\n   can be specified as configure arguments. The list of customizable features\n   can be viewed by running \"./configure --help\" command:\n\n\n\n   $ cd pjproject\n   $ ./configure --help\n   ...\n   Optional Features:\n   --enable-epoll           Use epoll on Linux instead of select\n   --disable-floating-point\tDisable floating point where possible\n   --disable-sound \t\tExclude sound (i.e. use null sound)\n   --disable-small-filter \tExclude small filter in resampling\n   --disable-large-filter \tExclude large filter in resampling\n   --disable-g711-plc \t\tExclude G.711 Annex A PLC\n   --disable-speex-aec \t\tExclude Speex Acoustic Echo Canceller/AEC\n   --disable-g711-codec \tExclude G.711 codecs from the build\n   --disable-l16-codec \t\tExclude Linear/L16 codec family from the build\n   --disable-gsm-codec \t\tExclude GSM codec in the build\n   --disable-speex-codec \tExclude Speex codecs in the build\n   --disable-ilbc-codec \tExclude iLBC codec in the build\n   --disable-tls Force excluding TLS support (default is autodetected based on\n   OpenSSL availability)\n   ...\n\n    Configuring Debug Version and Other Customizations\n\n   The configure script accepts standard customization, which details can be\n   obtained by executing ./configure --help.\n\n   Below is an example of specifying CFLAGS in configure:\n\n\n\n   $ ./configure CFLAGS=\"-O3 -DNDEBUG -msoft-float -fno-builtin\"\n   ...\n\n    Configuring TLS Support\n\n   By default, TLS support is configured based on the availability of OpenSSL\n   header files and libraries. If OpenSSL is available at the default include\n   and library path locations, TLS will be enabled by the configure script.\n\n   You  can explicitly disable TLS support by giving the configure script\n   --disable-tls option.\n\n\n  3.4 Cross Compilation\n     _________________________________________________________________\n\n   Cross compilation should be supported, using the usual autoconf syntax:\n\n\n\n   $ ./configure --host=arm-elf-linux\n   ...\n\n   Since cross-compilation is not tested as often as the \"normal\" build, please\n   watch for the ./configure output for incorrect settings (well ideally this\n   should be done for normal build too).\n\n   Please refer to Porting Guide for further information about porting PJ\n   software.\n\n\n  3.5 Running make\n     _________________________________________________________________\n\n   Once the configure script completes successfully, start the build process by\n   invoking these commands:\n\n\n\n   $ cd pjproject\n   $ make dep\n   $ make\n\n   Note:\n          gmake may need to be specified instead of make for some hosts, to\n          invoke GNU make instead of the native make.\n\n\n   Description of all make targets supported by the Makefile's:\n\n   all\n          The default (or first) target to build the libraries/binaries.\n\n   dep, depend\n          Build dependencies rule from the source files.\n\n   clean\n          Clean  the object files for current target, but keep the output\n          library/binary files intact.\n\n   distclean, realclean\n          Remove  all  generated  files (object, libraries, binaries, and\n          dependency files) for current target.\n\n\n   Note:\n          make can be invoked either in the top-level PJ directory or in build\n          directory under each project to build only the particular project.\n\n\n  3.6 Build Customizations\n     _________________________________________________________________\n\n   Build features can be customized by specifying the options when running\n   ./configure as described in Running Configure above.\n\n   In addition, additional CFLAGS and LDFLAGS options can be put in user.mak\n   file in PJ root directory (this file may need to be created if it doesn't\n   exist). Below is a sample of user.mak file contents:\n\n\n\n   export CFLAGS += -msoft-float -fno-builtin\n   export LDFLAGS +=\n\n\n4. Building for Windows Targets with Microsoft Visual Studio\n     _________________________________________________________________\n\n  4.1 Requirements\n     _________________________________________________________________\n\n   The Microsoft Visual Studio based project files can be used with one of the\n   following:\n\n     * Microsoft Visual Studio 6,\n     * Microsoft Visual Studio .NET 2002,\n     * Microsoft Visual Studio .NET 2003,\n     * Microsoft Visual C++ 2005 (including Express edition),\n\n   In addition, the following SDK's are needed:\n     * Platform SDK, if you're using Visual Studio 2005 Express (tested with\n       Platform SDK for Windows Server 2003 SP1),\n     * DirectX SDK (tested with DirectX version 8 and 9),\n     * OpenSSL development kit would be needed if TLS support is wanted, or\n       otherwise this is optional.\n\n   For the host, the following are required:\n     * Windows NT, 2000, XP, 2003, or later ,\n     * Windows 95/98 should work too, but this has not been tested,\n     * Sufficient amount of RAM for the build process (at least 256MB).\n\n\n    Enabling TLS Support with OpenSSL\n\n   If  TLS  support  is wanted, then OpenSSL SDK must be installed in the\n   development host.\n\n   To install OpenSSL SDK from the Win32 binary distribution:\n    1. Install OpenSSL SDK to any folder (e.g. C:\\OpenSSL)\n    2. Add OpenSSL DLL location to the system PATH.\n    3. Add OpenSSL include path to Visual Studio includes search directory.\n       Make sure that OpenSSL header files can be accessed from the program\n       with #include <openssl/ssl.h> construct.\n    4. Add OpenSSL library path to Visual Studio library search directory. Make\n       sure the following libraries are accessible:\n          + For Debug build: libeay32MTd and ssleay32MTd.\n          + For Release build: libeay32MT and ssleay32MT.\n\n   Then to enable TLS transport support in PJSIP, just add\n\n     #define PJSIP_HAS_TLS_TRANSPORT 1\n\n   in your pj/config_site.h. When this macro is defined, OpenSSL libraries will\n   be automatically linked to the application via the #pragma construct in\n   sip_transport_tls_ossl.c file.\n\n\n  4.2 Building the Projects\n     _________________________________________________________________\n\n   Follow the steps below to build the libraries/application using Visual\n   Studio:\n    1. For Visual Studio 6: open pjproject.dsw workspace file.\n    2. For Visual Studio 8 (VS 2005): open pjproject-vs8.sln solution file.\n    3. Set pjsua as Active Project.\n    4. Select Debug or Release build as appropriate.\n    5. Build the project. This will build pjsua application and all libraries\n       needed by pjsua.\n    6. After  successful  build,  the pjsua application will be placed in\n       pjsip-apps/bin directory, and the libraries in lib directory under each\n       projects.\n\n   To build the samples:\n    1. (Still using the same workspace)\n    2. Set samples project as Active Project\n    3. Select Debug or Release build as appropriate.\n    4. Build the project. This will build all sample applications and all\n       libraries needed.\n    5. After  successful build, the sample applications will be placed in\n       pjsip-apps/bin/samples directory, and the libraries in lib directory\n       under each projects.\n\n  4.3 Debugging the Sample Application\n     _________________________________________________________________\n\n   The sample applications are build using Samples.mak makefile, therefore it\n   is  difficult  to  setup  debugging session in Visual Studio for these\n   applications. To solve this issue, the pjsip_apps workspace contain one\n   project  called  sample_debug  which  can  be used to debug the sample\n   application.\n\n   To setup debugging using sample_debug project:\n    1. (Still using pjsip_apps workspace)\n    2. Set sample_debug project as Active Project\n    3. Edit debug.c file inside this project.\n    4. Modify the #include line to include the particular sample application to\n       debug\n    5. Select Debug build.\n    6. Build and debug the project.\n\n\n5. Building for Windows Mobile Targets (Windows CE/WinCE/PDA/SmartPhone)\n     _________________________________________________________________\n\n   PJ supports building SIP and media stacks and applications for Windows\n   Mobile targets. A very simple WinCE SIP user agent (with media) application\n   is provided just as proof of concept that the port works.\n\n  5.1 Requirements\n     _________________________________________________________________\n\n   One of the following development tools is needed to build SIP and media\n   components for Windows Mobile:\n     * Microsoft Embedded Visual C++ 4 with appropriate SDKs, or\n     * Microsoft Visual Studio 2005 for Windows Mobile with appropriate SDKs.\n\n   Note that VS2005 is not directly supported (as I don't have the tools), but\n   it is reported to work (I assumed that VS2005 for Windows Mobile can import\n   EVC4 workspace file).\n\n  5.2 Building the Projects\n     _________________________________________________________________\n\n   The Windows Mobile port is included in the main source distribution. Please\n   follow  the  following  steps  to build the WinCE libraries and sample\n   application:\n    1. Open pjsip-apps/build/wince-evc4/wince_demos.vcw workspace file. If\n       later version of EVC4 is being used, this may cause the workspace file\n       to be converted to the appropriate format.\n    2. Select pjsua_wince project as the Active Project.\n    3. Select the appropriate SDK (for example Pocket PC 2003 SDK or SmartPhone\n       2003 SDK)\n    4. Select the appropriate configuration (for example, Win32 (WCE Emulator\n       Debug) to debug the program in emulator, or other configurations such as\n       ARMV4, MIPS, SH3, SH4, or whatever suitable for the device)\n    5. Select the appropriate device (Emulator or the actual Device).\n    6. Build the project. This will build the sample WinCE application and all\n       libraries (SIP, Media, etc.) needed by this application.\n\n   Notes\n\n          + If the config_site.h includes config_site_sample.h file, then\n            there are certain configuration in config_site_sample.h that get\n            activated for Windows CE targets. Please make sure that these\n            configurations are suitable for the application.\n          + The libraries, binaries and object files produced by the build\n            process are located under build/wince-evc4/output directory of each\n            projects.\n\n\n6. Older PJLIB Build System for Non-Autoconf Targets (e.g. RTEMS)\n     _________________________________________________________________\n\n   The old PJLIB build system can still be used for building PJ libraries, for\n   example for RTEMS target. Please see the Porting PJLIB page in PJLIB\n   Reference documentation for information on how to support new target using\n   this build system.\n\n  6.1 Supported Targets\n     _________________________________________________________________\n\n   The older build system supports building PJ libraries for the following\n   operating systems:\n     * RTEMS\n     * Linux\n     * MacOS X\n     * Cygwin and Mingw\n\n   And it supports the following target architectures:\n     * i386, x86_64, itanium\n     * ARM\n     * mips\n     * powerpc\n     * mpc860\n     * etc.\n\n   For other targets, specific files need to be added to the build system,\n   please see the Porting PJLIB page in PJLIB Reference documentation for\n   details.\n\n  6.2 Invoking the Build System\n     _________________________________________________________________\n\n   To invoke the older build system, run the following:\n\n\n\n   $ cd pjproject\n   $ ./configure-legacy\n   $ make dep && make clean && make\n\n\n\n7. Running the Applications\n     _________________________________________________________________\n\n   Upon successful build, the output libraries (PJLIB, PJLIB-UTIL, PJMEDIA,\n   PJSIP, etc.) are put under ./lib sub-directory under each project directory.\n   In addition, some applications may also be built, and such applications will\n   be put in ./bin sub-directory under each project directory.\n\n\n  7.1 pjsua\n     _________________________________________________________________\n\n   pjsua is the reference implementation for both PJSIP and PJMEDIA stack, and\n   is  the  main target of the build system. Upon successful build, pjsua\n   application will be put in pjsip-apps/bin directory.\n\n   pjsua manual can be found in pjsua Manual Page.\n\n\n  7.2 Sample Applications\n     _________________________________________________________________\n\n   Sample applications will be built with the Makefile build system. For Visual\n   Studio, you have to build the samples manually by selecting and building the\n   Samples project inside pjsip-apps/build/pjsip_apps.dsw project workspace.\n\n   Upon   successful   build,   the   sample   applications  are  put  in\n   pjsip-apps/bin/samples directory.\n\n   The  sample applications are described in PJMEDIA Samples Page and\n   PJSIP Samples Page in the website.\n\n\n  7.3 pjlib-test\n     _________________________________________________________________\n\n   pjlib-test contains comprehensive tests for testing PJLIB functionality.\n   This application will only be built when the Makefile build system is used;\n   with  Visual  Studio, one has to open pjlib.dsw project in pjlib/build\n   directory to build this application.\n\n   If  you're  porting PJLIB to new target, it is recommended to run this\n   application to make sure that all functionalities works as expected.\n\n\n  7.4 pjsip-test\n     _________________________________________________________________\n\n   pjsip-test contains codes for testing various SIP functionalities in PJSIP\n   and also to benchmark static performance metrics such as message parsing per\n   second.\n\n\n\n8. Using PJPROJECT with Applications\n     _________________________________________________________________\n\n   Regardless of the build system being used, the following tasks are normally\n   needed to be done in order to build application to use PJSIP and PJMEDIA:\n    1. Put these include directories in the include search path:\n          + pjlib/include\n          + pjlib-util/include\n          + pjmedia/include\n          + pjsip/include\n    2. Put these library directories in the library search path:\n          + pjlib/lib\n          + pjlib-util/lib\n          + pjmedia/lib\n          + pjsip/lib\n    3. Include the relevant PJ header files in the application source file. For\n       example, using these would include ALL APIs exported by PJ:\n\n      #include <pjlib.h>\n      #include <pjlib-util.h>\n      #include <pjsip.h>\n      #include <pjsip_ua.h>\n      #include <pjsip_simple.h>\n      #include <pjsua.h>\n      #include <pjmedia.h>\n      #include <pjmedia-codec.h>\n       (Note: the documentation of the relevant libraries should say which\n       header files should be included to get the declaration of the APIs).\n    4. Declare the OS macros.\n          + For Windows applications built with Visual Studio, we need to\n            declare PJ_WIN32=1 macro in the project settings (declaring the\n            macro in the source file may not be sufficient).\n          + For Windows Mobile applications build with Visual C++, we need to\n            declare PJ_WIN32_WINCE=1 macro in the project settings.\n          + For  GNU build system/autoconf based build system, we need to\n            declare PJ_AUTOCONF=1 macro when compiling the applications.\n       (Note: the old PJ build system requires declaring the target processor\n       with PJ_M_XXX=1 macro, but this has been made obsolete. The target\n       processor  will  be  detected  from compiler's predefined macro by\n       pjlib/config.h file).\n    5. Link with the appropriate PJ libraries. The following libraries will\n       need to be included in the library link specifications:\n\n        pjlib\n                Base library used by all libraries.\n\n        pjlib-util\n                Auxiliary library containing scanner, XML, STUN, MD5, getopt,\n                etc, used by the SIP and media stack.\n\n        pjsip\n                SIP core stack library.\n\n        pjsip-ua\n                SIP user agent library containing INVITE session, call\n                transfer, client registration, etc.\n\n        pjsip-simple\n                SIP SIMPLE library for base event framework, presence, instant\n                messaging, etc.\n\n        pjsua\n                High level SIP UA library, combining SIP and media stack into\n                high-level easy to use API.\n\n        pjmedia\n                The media framework.\n\n        pjmedia-codec\n                Container library for various codecs such as GSM, Speex, and\n                iLBC.\n\n\n   Note: the actual library names will be appended with the target name and the\n   build configuration. For example:\n\n        For Visual Studio builds\n                The actual library names will look like\n                pjlib-i386-win32-vc6-debug.lib,\n                pjlib-i386-win32-vc6-release.lib, etc., depending on whether we\n                are building the Debug or Release version of the library.\n\n                An easier way to link with the libraries is to include PJ\n                project files in the workspace, and to configure project\n                dependencies so that the application depends on the PJ\n                libraries. This way, we don't need to manually add each PJ\n                libraries to the input library file specification, since VS\n                will automatically link the dependency libraries with the\n                application.\n\n        For Windows Mobile builds\n                Unfortunately the PJ libraries built for Windows Mobile will\n                not be placed in the usual lib directory, but rather under the\n                output directory under build/wince-evc4 project directory.\n\n                An easier way to link with the libraries is to include PJ\n                project files in the workspace, and to configure project\n                dependencies so that the application depends on the PJ\n                libraries. This way, we don't need to manually add each PJ\n                libraries to the input library file specification, since VS\n                will automatically link the dependency libraries with the\n                application.\n\n        For GNU builds\n                Application's Makefile can get the PJ library suffix by\n                including PJ's build.mak file from the root PJ directory (the\n                suffix is contained in TARGET_NAME variable). For example, to\n                link with PJLIB and PJMEDIA, we can use this syntax in the\n                LDFLAGS: \"-lpj-$(TARGET_NAME) -lpjmedia-$(TARGET_NAME)\"\n\n\n    6. Link with system spesific libraries:\n\n        Windows\n                Add (among other things): wsock32.lib, ws2_32.lib, ole32.lib,\n                dsound.lib\n\n        Linux, *nix, *BSD\n                Add (among other things): '-lpthread -lm' (at least).\n\n        MacOS X\n                Add (among other things): '-framework CoreAudio -lpthread -lm'.\n\n\nAppendix I: Common Problems/Frequently Asked Question (FAQ)\n     _________________________________________________________________\n\n  I.1 fatal error C1083: Cannot open include file: 'pj/config_site.h': No such\n  file or directory\n\n   This error normally occurs when the config_site.h file has not been created.\n   This file needs to be created manually (an empty file is sufficient). Please\n   follow the Build Preparation instructions above to create this file.\n\n\n\n\n\n\n\n\n     _________________________________________________________________\n\n   Feedback:\n          Thanks for using PJ libraries and for reading this document. Please\n          send feedbacks or general comments to <bennylp at pjsip dot org>.\n\n"
  },
  {
    "path": "deps/pjsip/aconfigure",
    "content": "#!/bin/sh\n# Guess values for system-dependent variables and create Makefiles.\n# Generated by GNU Autoconf 2.69 for pjproject 2.x.\n#\n#\n# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.\n#\n#\n# This configure script is free software; the Free Software Foundation\n# gives unlimited permission to copy, distribute and modify it.\n## -------------------- ##\n## M4sh Initialization. ##\n## -------------------- ##\n\n# Be more Bourne compatible\nDUALCASE=1; export DUALCASE # for MKS sh\nif test -n \"${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :\n  emulate sh\n  NULLCMD=:\n  # Pre-4.2 versions of Zsh do word splitting on ${1+\"$@\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '${1+\"$@\"}'='\"$@\"'\n  setopt NO_GLOB_SUBST\nelse\n  case `(set -o) 2>/dev/null` in #(\n  *posix*) :\n    set -o posix ;; #(\n  *) :\n     ;;\nesac\nfi\n\n\nas_nl='\n'\nexport as_nl\n# Printing a long string crashes Solaris 7 /usr/bin/printf.\nas_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo\n# Prefer a ksh shell builtin over an external printf program on Solaris,\n# but without wasting forks for bash or zsh.\nif test -z \"$BASH_VERSION$ZSH_VERSION\" \\\n    && (test \"X`print -r -- $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='print -r --'\n  as_echo_n='print -rn --'\nelif (test \"X`printf %s $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='printf %s\\n'\n  as_echo_n='printf %s'\nelse\n  if test \"X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`\" = \"X-n $as_echo\"; then\n    as_echo_body='eval /usr/ucb/echo -n \"$1$as_nl\"'\n    as_echo_n='/usr/ucb/echo -n'\n  else\n    as_echo_body='eval expr \"X$1\" : \"X\\\\(.*\\\\)\"'\n    as_echo_n_body='eval\n      arg=$1;\n      case $arg in #(\n      *\"$as_nl\"*)\n\texpr \"X$arg\" : \"X\\\\(.*\\\\)$as_nl\";\n\targ=`expr \"X$arg\" : \".*$as_nl\\\\(.*\\\\)\"`;;\n      esac;\n      expr \"X$arg\" : \"X\\\\(.*\\\\)\" | tr -d \"$as_nl\"\n    '\n    export as_echo_n_body\n    as_echo_n='sh -c $as_echo_n_body as_echo'\n  fi\n  export as_echo_body\n  as_echo='sh -c $as_echo_body as_echo'\nfi\n\n# The user is always right.\nif test \"${PATH_SEPARATOR+set}\" != set; then\n  PATH_SEPARATOR=:\n  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {\n    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||\n      PATH_SEPARATOR=';'\n  }\nfi\n\n\n# IFS\n# We need space, tab and new line, in precisely that order.  Quoting is\n# there to prevent editors from complaining about space-tab.\n# (If _AS_PATH_WALK were called with IFS unset, it would disable word\n# splitting by setting IFS to empty value.)\nIFS=\" \"\"\t$as_nl\"\n\n# Find who we are.  Look in the path if we contain no directory separator.\nas_myself=\ncase $0 in #((\n  *[\\\\/]* ) as_myself=$0 ;;\n  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    test -r \"$as_dir/$0\" && as_myself=$as_dir/$0 && break\n  done\nIFS=$as_save_IFS\n\n     ;;\nesac\n# We did not find ourselves, most probably we were run as `sh COMMAND'\n# in which case we are not to be found in the path.\nif test \"x$as_myself\" = x; then\n  as_myself=$0\nfi\nif test ! -f \"$as_myself\"; then\n  $as_echo \"$as_myself: error: cannot find myself; rerun with an absolute file name\" >&2\n  exit 1\nfi\n\n# Unset variables that we do not need and which cause bugs (e.g. in\n# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the \"|| exit 1\"\n# suppresses any \"Segmentation fault\" message there.  '((' could\n# trigger a bug in pdksh 5.2.14.\nfor as_var in BASH_ENV ENV MAIL MAILPATH\ndo eval test x\\${$as_var+set} = xset \\\n  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :\ndone\nPS1='$ '\nPS2='> '\nPS4='+ '\n\n# NLS nuisances.\nLC_ALL=C\nexport LC_ALL\nLANGUAGE=C\nexport LANGUAGE\n\n# CDPATH.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\n# Use a proper internal environment variable to ensure we don't fall\n  # into an infinite loop, continuously re-executing ourselves.\n  if test x\"${_as_can_reexec}\" != xno && test \"x$CONFIG_SHELL\" != x; then\n    _as_can_reexec=no; export _as_can_reexec;\n    # We cannot yet assume a decent shell, so we have to provide a\n# neutralization value for shells without unset; and this also\n# works around shells that cannot unset nonexistent variables.\n# Preserve -v and -x to the replacement shell.\nBASH_ENV=/dev/null\nENV=/dev/null\n(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV\ncase $- in # ((((\n  *v*x* | *x*v* ) as_opts=-vx ;;\n  *v* ) as_opts=-v ;;\n  *x* ) as_opts=-x ;;\n  * ) as_opts= ;;\nesac\nexec $CONFIG_SHELL $as_opts \"$as_myself\" ${1+\"$@\"}\n# Admittedly, this is quite paranoid, since all the known shells bail\n# out after a failed `exec'.\n$as_echo \"$0: could not re-execute with $CONFIG_SHELL\" >&2\nas_fn_exit 255\n  fi\n  # We don't want this to propagate to other subprocesses.\n          { _as_can_reexec=; unset _as_can_reexec;}\nif test \"x$CONFIG_SHELL\" = x; then\n  as_bourne_compatible=\"if test -n \\\"\\${ZSH_VERSION+set}\\\" && (emulate sh) >/dev/null 2>&1; then :\n  emulate sh\n  NULLCMD=:\n  # Pre-4.2 versions of Zsh do word splitting on \\${1+\\\"\\$@\\\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '\\${1+\\\"\\$@\\\"}'='\\\"\\$@\\\"'\n  setopt NO_GLOB_SUBST\nelse\n  case \\`(set -o) 2>/dev/null\\` in #(\n  *posix*) :\n    set -o posix ;; #(\n  *) :\n     ;;\nesac\nfi\n\"\n  as_required=\"as_fn_return () { (exit \\$1); }\nas_fn_success () { as_fn_return 0; }\nas_fn_failure () { as_fn_return 1; }\nas_fn_ret_success () { return 0; }\nas_fn_ret_failure () { return 1; }\n\nexitcode=0\nas_fn_success || { exitcode=1; echo as_fn_success failed.; }\nas_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }\nas_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }\nas_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }\nif ( set x; as_fn_ret_success y && test x = \\\"\\$1\\\" ); then :\n\nelse\n  exitcode=1; echo positional parameters were not saved.\nfi\ntest x\\$exitcode = x0 || exit 1\ntest -x / || exit 1\"\n  as_suggested=\"  as_lineno_1=\";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested\" as_lineno_1a=\\$LINENO\n  as_lineno_2=\";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested\" as_lineno_2a=\\$LINENO\n  eval 'test \\\"x\\$as_lineno_1'\\$as_run'\\\" != \\\"x\\$as_lineno_2'\\$as_run'\\\" &&\n  test \\\"x\\`expr \\$as_lineno_1'\\$as_run' + 1\\`\\\" = \\\"x\\$as_lineno_2'\\$as_run'\\\"' || exit 1\ntest \\$(( 1 + 1 )) = 2 || exit 1\"\n  if (eval \"$as_required\") 2>/dev/null; then :\n  as_have_required=yes\nelse\n  as_have_required=no\nfi\n  if test x$as_have_required = xyes && (eval \"$as_suggested\") 2>/dev/null; then :\n\nelse\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nas_found=false\nfor as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  as_found=:\n  case $as_dir in #(\n\t /*)\n\t   for as_base in sh bash ksh sh5; do\n\t     # Try only shells that exist, to save several forks.\n\t     as_shell=$as_dir/$as_base\n\t     if { test -f \"$as_shell\" || test -f \"$as_shell.exe\"; } &&\n\t\t    { $as_echo \"$as_bourne_compatible\"\"$as_required\" | as_run=a \"$as_shell\"; } 2>/dev/null; then :\n  CONFIG_SHELL=$as_shell as_have_required=yes\n\t\t   if { $as_echo \"$as_bourne_compatible\"\"$as_suggested\" | as_run=a \"$as_shell\"; } 2>/dev/null; then :\n  break 2\nfi\nfi\n\t   done;;\n       esac\n  as_found=false\ndone\n$as_found || { if { test -f \"$SHELL\" || test -f \"$SHELL.exe\"; } &&\n\t      { $as_echo \"$as_bourne_compatible\"\"$as_required\" | as_run=a \"$SHELL\"; } 2>/dev/null; then :\n  CONFIG_SHELL=$SHELL as_have_required=yes\nfi; }\nIFS=$as_save_IFS\n\n\n      if test \"x$CONFIG_SHELL\" != x; then :\n  export CONFIG_SHELL\n             # We cannot yet assume a decent shell, so we have to provide a\n# neutralization value for shells without unset; and this also\n# works around shells that cannot unset nonexistent variables.\n# Preserve -v and -x to the replacement shell.\nBASH_ENV=/dev/null\nENV=/dev/null\n(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV\ncase $- in # ((((\n  *v*x* | *x*v* ) as_opts=-vx ;;\n  *v* ) as_opts=-v ;;\n  *x* ) as_opts=-x ;;\n  * ) as_opts= ;;\nesac\nexec $CONFIG_SHELL $as_opts \"$as_myself\" ${1+\"$@\"}\n# Admittedly, this is quite paranoid, since all the known shells bail\n# out after a failed `exec'.\n$as_echo \"$0: could not re-execute with $CONFIG_SHELL\" >&2\nexit 255\nfi\n\n    if test x$as_have_required = xno; then :\n  $as_echo \"$0: This script requires a shell more modern than all\"\n  $as_echo \"$0: the shells that I found on your system.\"\n  if test x${ZSH_VERSION+set} = xset ; then\n    $as_echo \"$0: In particular, zsh $ZSH_VERSION has bugs and should\"\n    $as_echo \"$0: be upgraded to zsh 4.3.4 or later.\"\n  else\n    $as_echo \"$0: Please tell bug-autoconf@gnu.org about your system,\n$0: including any error possibly output before this\n$0: message. Then install a modern shell, or manually run\n$0: the script under such a shell if you do have one.\"\n  fi\n  exit 1\nfi\nfi\nfi\nSHELL=${CONFIG_SHELL-/bin/sh}\nexport SHELL\n# Unset more variables known to interfere with behavior of common tools.\nCLICOLOR_FORCE= GREP_OPTIONS=\nunset CLICOLOR_FORCE GREP_OPTIONS\n\n## --------------------- ##\n## M4sh Shell Functions. ##\n## --------------------- ##\n# as_fn_unset VAR\n# ---------------\n# Portably unset VAR.\nas_fn_unset ()\n{\n  { eval $1=; unset $1;}\n}\nas_unset=as_fn_unset\n\n# as_fn_set_status STATUS\n# -----------------------\n# Set $? to STATUS, without forking.\nas_fn_set_status ()\n{\n  return $1\n} # as_fn_set_status\n\n# as_fn_exit STATUS\n# -----------------\n# Exit the shell with STATUS, even in a \"trap 0\" or \"set -e\" context.\nas_fn_exit ()\n{\n  set +e\n  as_fn_set_status $1\n  exit $1\n} # as_fn_exit\n\n# as_fn_mkdir_p\n# -------------\n# Create \"$as_dir\" as a directory, including parents if necessary.\nas_fn_mkdir_p ()\n{\n\n  case $as_dir in #(\n  -*) as_dir=./$as_dir;;\n  esac\n  test -d \"$as_dir\" || eval $as_mkdir_p || {\n    as_dirs=\n    while :; do\n      case $as_dir in #(\n      *\\'*) as_qdir=`$as_echo \"$as_dir\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;; #'(\n      *) as_qdir=$as_dir;;\n      esac\n      as_dirs=\"'$as_qdir' $as_dirs\"\n      as_dir=`$as_dirname -- \"$as_dir\" ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n      test -d \"$as_dir\" && break\n    done\n    test -z \"$as_dirs\" || eval \"mkdir $as_dirs\"\n  } || test -d \"$as_dir\" || as_fn_error $? \"cannot create directory $as_dir\"\n\n\n} # as_fn_mkdir_p\n\n# as_fn_executable_p FILE\n# -----------------------\n# Test if FILE is an executable regular file.\nas_fn_executable_p ()\n{\n  test -f \"$1\" && test -x \"$1\"\n} # as_fn_executable_p\n# as_fn_append VAR VALUE\n# ----------------------\n# Append the text in VALUE to the end of the definition contained in VAR. Take\n# advantage of any shell optimizations that allow amortized linear growth over\n# repeated appends, instead of the typical quadratic growth present in naive\n# implementations.\nif (eval \"as_var=1; as_var+=2; test x\\$as_var = x12\") 2>/dev/null; then :\n  eval 'as_fn_append ()\n  {\n    eval $1+=\\$2\n  }'\nelse\n  as_fn_append ()\n  {\n    eval $1=\\$$1\\$2\n  }\nfi # as_fn_append\n\n# as_fn_arith ARG...\n# ------------------\n# Perform arithmetic evaluation on the ARGs, and store the result in the\n# global $as_val. Take advantage of shells that can avoid forks. The arguments\n# must be portable across $(()) and expr.\nif (eval \"test \\$(( 1 + 1 )) = 2\") 2>/dev/null; then :\n  eval 'as_fn_arith ()\n  {\n    as_val=$(( $* ))\n  }'\nelse\n  as_fn_arith ()\n  {\n    as_val=`expr \"$@\" || test $? -eq 1`\n  }\nfi # as_fn_arith\n\n\n# as_fn_error STATUS ERROR [LINENO LOG_FD]\n# ----------------------------------------\n# Output \"`basename $0`: error: ERROR\" to stderr. If LINENO and LOG_FD are\n# provided, also output the error to LOG_FD, referencing LINENO. Then exit the\n# script with STATUS, using 1 if that was 0.\nas_fn_error ()\n{\n  as_status=$1; test $as_status -eq 0 && as_status=1\n  if test \"$4\"; then\n    as_lineno=${as_lineno-\"$3\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n    $as_echo \"$as_me:${as_lineno-$LINENO}: error: $2\" >&$4\n  fi\n  $as_echo \"$as_me: error: $2\" >&2\n  as_fn_exit $as_status\n} # as_fn_error\n\nif expr a : '\\(a\\)' >/dev/null 2>&1 &&\n   test \"X`expr 00001 : '.*\\(...\\)'`\" = X001; then\n  as_expr=expr\nelse\n  as_expr=false\nfi\n\nif (basename -- /) >/dev/null 2>&1 && test \"X`basename -- / 2>&1`\" = \"X/\"; then\n  as_basename=basename\nelse\n  as_basename=false\nfi\n\nif (as_dir=`dirname -- /` && test \"X$as_dir\" = X/) >/dev/null 2>&1; then\n  as_dirname=dirname\nelse\n  as_dirname=false\nfi\n\nas_me=`$as_basename -- \"$0\" ||\n$as_expr X/\"$0\" : '.*/\\([^/][^/]*\\)/*$' \\| \\\n\t X\"$0\" : 'X\\(//\\)$' \\| \\\n\t X\"$0\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X/\"$0\" |\n    sed '/^.*\\/\\([^/][^/]*\\)\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n\n# Avoid depending upon Character Ranges.\nas_cr_letters='abcdefghijklmnopqrstuvwxyz'\nas_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nas_cr_Letters=$as_cr_letters$as_cr_LETTERS\nas_cr_digits='0123456789'\nas_cr_alnum=$as_cr_Letters$as_cr_digits\n\n\n  as_lineno_1=$LINENO as_lineno_1a=$LINENO\n  as_lineno_2=$LINENO as_lineno_2a=$LINENO\n  eval 'test \"x$as_lineno_1'$as_run'\" != \"x$as_lineno_2'$as_run'\" &&\n  test \"x`expr $as_lineno_1'$as_run' + 1`\" = \"x$as_lineno_2'$as_run'\"' || {\n  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)\n  sed -n '\n    p\n    /[$]LINENO/=\n  ' <$as_myself |\n    sed '\n      s/[$]LINENO.*/&-/\n      t lineno\n      b\n      :lineno\n      N\n      :loop\n      s/[$]LINENO\\([^'$as_cr_alnum'_].*\\n\\)\\(.*\\)/\\2\\1\\2/\n      t loop\n      s/-\\n.*//\n    ' >$as_me.lineno &&\n  chmod +x \"$as_me.lineno\" ||\n    { $as_echo \"$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell\" >&2; as_fn_exit 1; }\n\n  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have\n  # already done that, so ensure we don't try to do so again and fall\n  # in an infinite loop.  This has already happened in practice.\n  _as_can_reexec=no; export _as_can_reexec\n  # Don't try to exec as it changes $[0], causing all sort of problems\n  # (the dirname of $[0] is not the place where we might find the\n  # original and so on.  Autoconf is especially sensitive to this).\n  . \"./$as_me.lineno\"\n  # Exit status is that of the last command.\n  exit\n}\n\nECHO_C= ECHO_N= ECHO_T=\ncase `echo -n x` in #(((((\n-n*)\n  case `echo 'xy\\c'` in\n  *c*) ECHO_T='\t';;\t# ECHO_T is single tab character.\n  xy)  ECHO_C='\\c';;\n  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null\n       ECHO_T='\t';;\n  esac;;\n*)\n  ECHO_N='-n';;\nesac\n\nrm -f conf$$ conf$$.exe conf$$.file\nif test -d conf$$.dir; then\n  rm -f conf$$.dir/conf$$.file\nelse\n  rm -f conf$$.dir\n  mkdir conf$$.dir 2>/dev/null\nfi\nif (echo >conf$$.file) 2>/dev/null; then\n  if ln -s conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s='ln -s'\n    # ... but there are two gotchas:\n    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.\n    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.\n    # In both cases, we have to default to `cp -pR'.\n    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||\n      as_ln_s='cp -pR'\n  elif ln conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s=ln\n  else\n    as_ln_s='cp -pR'\n  fi\nelse\n  as_ln_s='cp -pR'\nfi\nrm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file\nrmdir conf$$.dir 2>/dev/null\n\nif mkdir -p . 2>/dev/null; then\n  as_mkdir_p='mkdir -p \"$as_dir\"'\nelse\n  test -d ./-p && rmdir ./-p\n  as_mkdir_p=false\nfi\n\nas_test_x='test -x'\nas_executable_p=as_fn_executable_p\n\n# Sed expression to map a string onto a valid CPP name.\nas_tr_cpp=\"eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'\"\n\n# Sed expression to map a string onto a valid variable name.\nas_tr_sh=\"eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'\"\n\n\ntest -n \"$DJDIR\" || exec 7<&0 </dev/null\nexec 6>&1\n\n# Name of the host.\n# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,\n# so uname gets run too.\nac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`\n\n#\n# Initializations.\n#\nac_default_prefix=/usr/local\nac_clean_files=\nac_config_libobj_dir=.\nLIBOBJS=\ncross_compiling=no\nsubdirs=\nMFLAGS=\nMAKEFLAGS=\n\n# Identity of this package.\nPACKAGE_NAME='pjproject'\nPACKAGE_TARNAME='pjproject'\nPACKAGE_VERSION='2.x'\nPACKAGE_STRING='pjproject 2.x'\nPACKAGE_BUGREPORT=''\nPACKAGE_URL=''\n\n# Factoring default headers for most tests.\nac_includes_default=\"\\\n#include <stdio.h>\n#ifdef HAVE_SYS_TYPES_H\n# include <sys/types.h>\n#endif\n#ifdef HAVE_SYS_STAT_H\n# include <sys/stat.h>\n#endif\n#ifdef STDC_HEADERS\n# include <stdlib.h>\n# include <stddef.h>\n#else\n# ifdef HAVE_STDLIB_H\n#  include <stdlib.h>\n# endif\n#endif\n#ifdef HAVE_STRING_H\n# if !defined STDC_HEADERS && defined HAVE_MEMORY_H\n#  include <memory.h>\n# endif\n# include <string.h>\n#endif\n#ifdef HAVE_STRINGS_H\n# include <strings.h>\n#endif\n#ifdef HAVE_INTTYPES_H\n# include <inttypes.h>\n#endif\n#ifdef HAVE_STDINT_H\n# include <stdint.h>\n#endif\n#ifdef HAVE_UNISTD_H\n# include <unistd.h>\n#endif\"\n\nac_subst_vars='LTLIBOBJS\nLIBOBJS\nac_main_obj\nac_host\nlibcrypto_present\nlibssl_present\nopenssl_h_present\nac_no_ssl\nac_webrtc_platform\nac_libyuv_ldflags\nac_libyuv_cflags\nac_openh264_ldflags\nac_openh264_cflags\nac_v4l2_ldflags\nac_v4l2_cflags\nac_vpx_ldflags\nac_vpx_cflags\nSAVED_PKG_CONFIG_PATH\nac_ffmpeg_ldflags\nac_ffmpeg_cflags\nPKG_CONFIG\nac_resample_dll\nac_no_g7221_codec\nac_no_speex_aec\nac_no_large_filter\nac_no_small_filter\nac_dshow_ldflags\nac_dshow_cflags\nac_pjmedia_video_has_dshow\nac_avf_cflags\nac_pjmedia_video_has_avf\nac_ios_cflags\nac_pjmedia_video_has_ios\nac_pjmedia_video\nac_pjmedia_audiodev_objs\nac_linux_poll\nac_os_objs\nEGREP\nGREP\nCPP\nac_cross_compile\nac_shlib_suffix\nac_build_mak_vars\nac_pjdir\nCC_CFLAGS\nCC_OPTIMIZE\nCC_DEF\nCC_INC\nCC_OUT\nLIBEXT2\nLIBEXT\nLDOUT\nLD\nAR_FLAGS\nac_ct_AR\nAR\nRANLIB\nac_ct_CXX\nCXXFLAGS\nCXX\nOBJEXT\nEXEEXT\nac_ct_CC\nCPPFLAGS\nLDFLAGS\nCFLAGS\nCC\ntarget_os\ntarget_vendor\ntarget_cpu\ntarget\nhost_os\nhost_vendor\nhost_cpu\nhost\nbuild_os\nbuild_vendor\nbuild_cpu\nbuild\ntarget_alias\nhost_alias\nbuild_alias\nLIBS\nECHO_T\nECHO_N\nECHO_C\nDEFS\nmandir\nlocaledir\nlibdir\npsdir\npdfdir\ndvidir\nhtmldir\ninfodir\ndocdir\noldincludedir\nincludedir\nlocalstatedir\nsharedstatedir\nsysconfdir\ndatadir\ndatarootdir\nlibexecdir\nsbindir\nbindir\nprogram_transform_name\nprefix\nexec_prefix\nPACKAGE_URL\nPACKAGE_BUGREPORT\nPACKAGE_STRING\nPACKAGE_VERSION\nPACKAGE_TARNAME\nPACKAGE_NAME\nPATH_SEPARATOR\nSHELL'\nac_subst_files=''\nac_user_opts='\nenable_option_checking\nenable_epoll\nenable_small_filter\nenable_large_filter\nenable_speex_aec\nenable_g7221_codec\nenable_libsamplerate\nenable_resample_dll\nwith_ffmpeg\nwith_vpx\nenable_v4l2\nwith_openh264\nenable_openh264\nwith_libyuv\nenable_libyuv\nwith_ssl\nenable_ssl\n'\n      ac_precious_vars='build_alias\nhost_alias\ntarget_alias\nCC\nCFLAGS\nLDFLAGS\nLIBS\nCPPFLAGS\nCXX\nCXXFLAGS\nCCC\nCPP'\n\n\n# Initialize some variables set by options.\nac_init_help=\nac_init_version=false\nac_unrecognized_opts=\nac_unrecognized_sep=\n# The variables have the same names as the options, with\n# dashes changed to underlines.\ncache_file=/dev/null\nexec_prefix=NONE\nno_create=\nno_recursion=\nprefix=NONE\nprogram_prefix=NONE\nprogram_suffix=NONE\nprogram_transform_name=s,x,x,\nsilent=\nsite=\nsrcdir=\nverbose=\nx_includes=NONE\nx_libraries=NONE\n\n# Installation directory options.\n# These are left unexpanded so users can \"make install exec_prefix=/foo\"\n# and all the variables that are supposed to be based on exec_prefix\n# by default will actually change.\n# Use braces instead of parens because sh, perl, etc. also accept them.\n# (The list follows the same order as the GNU Coding Standards.)\nbindir='${exec_prefix}/bin'\nsbindir='${exec_prefix}/sbin'\nlibexecdir='${exec_prefix}/libexec'\ndatarootdir='${prefix}/share'\ndatadir='${datarootdir}'\nsysconfdir='${prefix}/etc'\nsharedstatedir='${prefix}/com'\nlocalstatedir='${prefix}/var'\nincludedir='${prefix}/include'\noldincludedir='/usr/include'\ndocdir='${datarootdir}/doc/${PACKAGE_TARNAME}'\ninfodir='${datarootdir}/info'\nhtmldir='${docdir}'\ndvidir='${docdir}'\npdfdir='${docdir}'\npsdir='${docdir}'\nlibdir='${exec_prefix}/lib'\nlocaledir='${datarootdir}/locale'\nmandir='${datarootdir}/man'\n\nac_prev=\nac_dashdash=\nfor ac_option\ndo\n  # If the previous option needs an argument, assign it.\n  if test -n \"$ac_prev\"; then\n    eval $ac_prev=\\$ac_option\n    ac_prev=\n    continue\n  fi\n\n  case $ac_option in\n  *=?*) ac_optarg=`expr \"X$ac_option\" : '[^=]*=\\(.*\\)'` ;;\n  *=)   ac_optarg= ;;\n  *)    ac_optarg=yes ;;\n  esac\n\n  # Accept the important Cygnus configure options, so we can diagnose typos.\n\n  case $ac_dashdash$ac_option in\n  --)\n    ac_dashdash=yes ;;\n\n  -bindir | --bindir | --bindi | --bind | --bin | --bi)\n    ac_prev=bindir ;;\n  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)\n    bindir=$ac_optarg ;;\n\n  -build | --build | --buil | --bui | --bu)\n    ac_prev=build_alias ;;\n  -build=* | --build=* | --buil=* | --bui=* | --bu=*)\n    build_alias=$ac_optarg ;;\n\n  -cache-file | --cache-file | --cache-fil | --cache-fi \\\n  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)\n    ac_prev=cache_file ;;\n  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \\\n  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)\n    cache_file=$ac_optarg ;;\n\n  --config-cache | -C)\n    cache_file=config.cache ;;\n\n  -datadir | --datadir | --datadi | --datad)\n    ac_prev=datadir ;;\n  -datadir=* | --datadir=* | --datadi=* | --datad=*)\n    datadir=$ac_optarg ;;\n\n  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \\\n  | --dataroo | --dataro | --datar)\n    ac_prev=datarootdir ;;\n  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \\\n  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)\n    datarootdir=$ac_optarg ;;\n\n  -disable-* | --disable-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*disable-\\(.*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error $? \"invalid feature name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"enable_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval enable_$ac_useropt=no ;;\n\n  -docdir | --docdir | --docdi | --doc | --do)\n    ac_prev=docdir ;;\n  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)\n    docdir=$ac_optarg ;;\n\n  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)\n    ac_prev=dvidir ;;\n  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)\n    dvidir=$ac_optarg ;;\n\n  -enable-* | --enable-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*enable-\\([^=]*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error $? \"invalid feature name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"enable_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval enable_$ac_useropt=\\$ac_optarg ;;\n\n  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \\\n  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \\\n  | --exec | --exe | --ex)\n    ac_prev=exec_prefix ;;\n  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \\\n  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \\\n  | --exec=* | --exe=* | --ex=*)\n    exec_prefix=$ac_optarg ;;\n\n  -gas | --gas | --ga | --g)\n    # Obsolete; use --with-gas.\n    with_gas=yes ;;\n\n  -help | --help | --hel | --he | -h)\n    ac_init_help=long ;;\n  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)\n    ac_init_help=recursive ;;\n  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)\n    ac_init_help=short ;;\n\n  -host | --host | --hos | --ho)\n    ac_prev=host_alias ;;\n  -host=* | --host=* | --hos=* | --ho=*)\n    host_alias=$ac_optarg ;;\n\n  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)\n    ac_prev=htmldir ;;\n  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \\\n  | --ht=*)\n    htmldir=$ac_optarg ;;\n\n  -includedir | --includedir | --includedi | --included | --include \\\n  | --includ | --inclu | --incl | --inc)\n    ac_prev=includedir ;;\n  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \\\n  | --includ=* | --inclu=* | --incl=* | --inc=*)\n    includedir=$ac_optarg ;;\n\n  -infodir | --infodir | --infodi | --infod | --info | --inf)\n    ac_prev=infodir ;;\n  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)\n    infodir=$ac_optarg ;;\n\n  -libdir | --libdir | --libdi | --libd)\n    ac_prev=libdir ;;\n  -libdir=* | --libdir=* | --libdi=* | --libd=*)\n    libdir=$ac_optarg ;;\n\n  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \\\n  | --libexe | --libex | --libe)\n    ac_prev=libexecdir ;;\n  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \\\n  | --libexe=* | --libex=* | --libe=*)\n    libexecdir=$ac_optarg ;;\n\n  -localedir | --localedir | --localedi | --localed | --locale)\n    ac_prev=localedir ;;\n  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)\n    localedir=$ac_optarg ;;\n\n  -localstatedir | --localstatedir | --localstatedi | --localstated \\\n  | --localstate | --localstat | --localsta | --localst | --locals)\n    ac_prev=localstatedir ;;\n  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \\\n  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)\n    localstatedir=$ac_optarg ;;\n\n  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)\n    ac_prev=mandir ;;\n  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)\n    mandir=$ac_optarg ;;\n\n  -nfp | --nfp | --nf)\n    # Obsolete; use --without-fp.\n    with_fp=no ;;\n\n  -no-create | --no-create | --no-creat | --no-crea | --no-cre \\\n  | --no-cr | --no-c | -n)\n    no_create=yes ;;\n\n  -no-recursion | --no-recursion | --no-recursio | --no-recursi \\\n  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)\n    no_recursion=yes ;;\n\n  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \\\n  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \\\n  | --oldin | --oldi | --old | --ol | --o)\n    ac_prev=oldincludedir ;;\n  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \\\n  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \\\n  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)\n    oldincludedir=$ac_optarg ;;\n\n  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)\n    ac_prev=prefix ;;\n  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)\n    prefix=$ac_optarg ;;\n\n  -program-prefix | --program-prefix | --program-prefi | --program-pref \\\n  | --program-pre | --program-pr | --program-p)\n    ac_prev=program_prefix ;;\n  -program-prefix=* | --program-prefix=* | --program-prefi=* \\\n  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)\n    program_prefix=$ac_optarg ;;\n\n  -program-suffix | --program-suffix | --program-suffi | --program-suff \\\n  | --program-suf | --program-su | --program-s)\n    ac_prev=program_suffix ;;\n  -program-suffix=* | --program-suffix=* | --program-suffi=* \\\n  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)\n    program_suffix=$ac_optarg ;;\n\n  -program-transform-name | --program-transform-name \\\n  | --program-transform-nam | --program-transform-na \\\n  | --program-transform-n | --program-transform- \\\n  | --program-transform | --program-transfor \\\n  | --program-transfo | --program-transf \\\n  | --program-trans | --program-tran \\\n  | --progr-tra | --program-tr | --program-t)\n    ac_prev=program_transform_name ;;\n  -program-transform-name=* | --program-transform-name=* \\\n  | --program-transform-nam=* | --program-transform-na=* \\\n  | --program-transform-n=* | --program-transform-=* \\\n  | --program-transform=* | --program-transfor=* \\\n  | --program-transfo=* | --program-transf=* \\\n  | --program-trans=* | --program-tran=* \\\n  | --progr-tra=* | --program-tr=* | --program-t=*)\n    program_transform_name=$ac_optarg ;;\n\n  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)\n    ac_prev=pdfdir ;;\n  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)\n    pdfdir=$ac_optarg ;;\n\n  -psdir | --psdir | --psdi | --psd | --ps)\n    ac_prev=psdir ;;\n  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)\n    psdir=$ac_optarg ;;\n\n  -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n  | -silent | --silent | --silen | --sile | --sil)\n    silent=yes ;;\n\n  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)\n    ac_prev=sbindir ;;\n  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \\\n  | --sbi=* | --sb=*)\n    sbindir=$ac_optarg ;;\n\n  -sharedstatedir | --sharedstatedir | --sharedstatedi \\\n  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \\\n  | --sharedst | --shareds | --shared | --share | --shar \\\n  | --sha | --sh)\n    ac_prev=sharedstatedir ;;\n  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \\\n  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \\\n  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \\\n  | --sha=* | --sh=*)\n    sharedstatedir=$ac_optarg ;;\n\n  -site | --site | --sit)\n    ac_prev=site ;;\n  -site=* | --site=* | --sit=*)\n    site=$ac_optarg ;;\n\n  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)\n    ac_prev=srcdir ;;\n  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)\n    srcdir=$ac_optarg ;;\n\n  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \\\n  | --syscon | --sysco | --sysc | --sys | --sy)\n    ac_prev=sysconfdir ;;\n  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \\\n  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)\n    sysconfdir=$ac_optarg ;;\n\n  -target | --target | --targe | --targ | --tar | --ta | --t)\n    ac_prev=target_alias ;;\n  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)\n    target_alias=$ac_optarg ;;\n\n  -v | -verbose | --verbose | --verbos | --verbo | --verb)\n    verbose=yes ;;\n\n  -version | --version | --versio | --versi | --vers | -V)\n    ac_init_version=: ;;\n\n  -with-* | --with-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*with-\\([^=]*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error $? \"invalid package name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"with_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval with_$ac_useropt=\\$ac_optarg ;;\n\n  -without-* | --without-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*without-\\(.*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error $? \"invalid package name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"with_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval with_$ac_useropt=no ;;\n\n  --x)\n    # Obsolete; use --with-x.\n    with_x=yes ;;\n\n  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \\\n  | --x-incl | --x-inc | --x-in | --x-i)\n    ac_prev=x_includes ;;\n  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \\\n  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)\n    x_includes=$ac_optarg ;;\n\n  -x-libraries | --x-libraries | --x-librarie | --x-librari \\\n  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)\n    ac_prev=x_libraries ;;\n  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \\\n  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)\n    x_libraries=$ac_optarg ;;\n\n  -*) as_fn_error $? \"unrecognized option: \\`$ac_option'\nTry \\`$0 --help' for more information\"\n    ;;\n\n  *=*)\n    ac_envvar=`expr \"x$ac_option\" : 'x\\([^=]*\\)='`\n    # Reject names that are not valid shell variable names.\n    case $ac_envvar in #(\n      '' | [0-9]* | *[!_$as_cr_alnum]* )\n      as_fn_error $? \"invalid variable name: \\`$ac_envvar'\" ;;\n    esac\n    eval $ac_envvar=\\$ac_optarg\n    export $ac_envvar ;;\n\n  *)\n    # FIXME: should be removed in autoconf 3.0.\n    $as_echo \"$as_me: WARNING: you should use --build, --host, --target\" >&2\n    expr \"x$ac_option\" : \".*[^-._$as_cr_alnum]\" >/dev/null &&\n      $as_echo \"$as_me: WARNING: invalid host type: $ac_option\" >&2\n    : \"${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}\"\n    ;;\n\n  esac\ndone\n\nif test -n \"$ac_prev\"; then\n  ac_option=--`echo $ac_prev | sed 's/_/-/g'`\n  as_fn_error $? \"missing argument to $ac_option\"\nfi\n\nif test -n \"$ac_unrecognized_opts\"; then\n  case $enable_option_checking in\n    no) ;;\n    fatal) as_fn_error $? \"unrecognized options: $ac_unrecognized_opts\" ;;\n    *)     $as_echo \"$as_me: WARNING: unrecognized options: $ac_unrecognized_opts\" >&2 ;;\n  esac\nfi\n\n# Check all directory arguments for consistency.\nfor ac_var in\texec_prefix prefix bindir sbindir libexecdir datarootdir \\\n\t\tdatadir sysconfdir sharedstatedir localstatedir includedir \\\n\t\toldincludedir docdir infodir htmldir dvidir pdfdir psdir \\\n\t\tlibdir localedir mandir\ndo\n  eval ac_val=\\$$ac_var\n  # Remove trailing slashes.\n  case $ac_val in\n    */ )\n      ac_val=`expr \"X$ac_val\" : 'X\\(.*[^/]\\)' \\| \"X$ac_val\" : 'X\\(.*\\)'`\n      eval $ac_var=\\$ac_val;;\n  esac\n  # Be sure to have absolute directory names.\n  case $ac_val in\n    [\\\\/$]* | ?:[\\\\/]* )  continue;;\n    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;\n  esac\n  as_fn_error $? \"expected an absolute directory name for --$ac_var: $ac_val\"\ndone\n\n# There might be people who depend on the old broken behavior: `$host'\n# used to hold the argument of --host etc.\n# FIXME: To remove some day.\nbuild=$build_alias\nhost=$host_alias\ntarget=$target_alias\n\n# FIXME: To remove some day.\nif test \"x$host_alias\" != x; then\n  if test \"x$build_alias\" = x; then\n    cross_compiling=maybe\n  elif test \"x$build_alias\" != \"x$host_alias\"; then\n    cross_compiling=yes\n  fi\nfi\n\nac_tool_prefix=\ntest -n \"$host_alias\" && ac_tool_prefix=$host_alias-\n\ntest \"$silent\" = yes && exec 6>/dev/null\n\n\nac_pwd=`pwd` && test -n \"$ac_pwd\" &&\nac_ls_di=`ls -di .` &&\nac_pwd_ls_di=`cd \"$ac_pwd\" && ls -di .` ||\n  as_fn_error $? \"working directory cannot be determined\"\ntest \"X$ac_ls_di\" = \"X$ac_pwd_ls_di\" ||\n  as_fn_error $? \"pwd does not report name of working directory\"\n\n\n# Find the source files, if location was not specified.\nif test -z \"$srcdir\"; then\n  ac_srcdir_defaulted=yes\n  # Try the directory containing this script, then the parent directory.\n  ac_confdir=`$as_dirname -- \"$as_myself\" ||\n$as_expr X\"$as_myself\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_myself\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_myself\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_myself\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$as_myself\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n  srcdir=$ac_confdir\n  if test ! -r \"$srcdir/$ac_unique_file\"; then\n    srcdir=..\n  fi\nelse\n  ac_srcdir_defaulted=no\nfi\nif test ! -r \"$srcdir/$ac_unique_file\"; then\n  test \"$ac_srcdir_defaulted\" = yes && srcdir=\"$ac_confdir or ..\"\n  as_fn_error $? \"cannot find sources ($ac_unique_file) in $srcdir\"\nfi\nac_msg=\"sources are in $srcdir, but \\`cd $srcdir' does not work\"\nac_abs_confdir=`(\n\tcd \"$srcdir\" && test -r \"./$ac_unique_file\" || as_fn_error $? \"$ac_msg\"\n\tpwd)`\n# When building in place, set srcdir=.\nif test \"$ac_abs_confdir\" = \"$ac_pwd\"; then\n  srcdir=.\nfi\n# Remove unnecessary trailing slashes from srcdir.\n# Double slashes in file names in object file debugging info\n# mess up M-x gdb in Emacs.\ncase $srcdir in\n*/) srcdir=`expr \"X$srcdir\" : 'X\\(.*[^/]\\)' \\| \"X$srcdir\" : 'X\\(.*\\)'`;;\nesac\nfor ac_var in $ac_precious_vars; do\n  eval ac_env_${ac_var}_set=\\${${ac_var}+set}\n  eval ac_env_${ac_var}_value=\\$${ac_var}\n  eval ac_cv_env_${ac_var}_set=\\${${ac_var}+set}\n  eval ac_cv_env_${ac_var}_value=\\$${ac_var}\ndone\n\n#\n# Report the --help message.\n#\nif test \"$ac_init_help\" = \"long\"; then\n  # Omit some internal or obsolete options to make the list less imposing.\n  # This message is too long to be a string in the A/UX 3.1 sh.\n  cat <<_ACEOF\n\\`configure' configures pjproject 2.x to adapt to many kinds of systems.\n\nUsage: $0 [OPTION]... [VAR=VALUE]...\n\nTo assign environment variables (e.g., CC, CFLAGS...), specify them as\nVAR=VALUE.  See below for descriptions of some of the useful variables.\n\nDefaults for the options are specified in brackets.\n\nConfiguration:\n  -h, --help              display this help and exit\n      --help=short        display options specific to this package\n      --help=recursive    display the short help of all the included packages\n  -V, --version           display version information and exit\n  -q, --quiet, --silent   do not print \\`checking ...' messages\n      --cache-file=FILE   cache test results in FILE [disabled]\n  -C, --config-cache      alias for \\`--cache-file=config.cache'\n  -n, --no-create         do not create output files\n      --srcdir=DIR        find the sources in DIR [configure dir or \\`..']\n\nInstallation directories:\n  --prefix=PREFIX         install architecture-independent files in PREFIX\n                          [$ac_default_prefix]\n  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX\n                          [PREFIX]\n\nBy default, \\`make install' will install all the files in\n\\`$ac_default_prefix/bin', \\`$ac_default_prefix/lib' etc.  You can specify\nan installation prefix other than \\`$ac_default_prefix' using \\`--prefix',\nfor instance \\`--prefix=\\$HOME'.\n\nFor better control, use the options below.\n\nFine tuning of the installation directories:\n  --bindir=DIR            user executables [EPREFIX/bin]\n  --sbindir=DIR           system admin executables [EPREFIX/sbin]\n  --libexecdir=DIR        program executables [EPREFIX/libexec]\n  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]\n  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]\n  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]\n  --libdir=DIR            object code libraries [EPREFIX/lib]\n  --includedir=DIR        C header files [PREFIX/include]\n  --oldincludedir=DIR     C header files for non-gcc [/usr/include]\n  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]\n  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]\n  --infodir=DIR           info documentation [DATAROOTDIR/info]\n  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]\n  --mandir=DIR            man documentation [DATAROOTDIR/man]\n  --docdir=DIR            documentation root [DATAROOTDIR/doc/pjproject]\n  --htmldir=DIR           html documentation [DOCDIR]\n  --dvidir=DIR            dvi documentation [DOCDIR]\n  --pdfdir=DIR            pdf documentation [DOCDIR]\n  --psdir=DIR             ps documentation [DOCDIR]\n_ACEOF\n\n  cat <<\\_ACEOF\n\nSystem types:\n  --build=BUILD     configure for building on BUILD [guessed]\n  --host=HOST       cross-compile to build programs to run on HOST [BUILD]\n  --target=TARGET   configure for building compilers for TARGET [HOST]\n_ACEOF\nfi\n\nif test -n \"$ac_init_help\"; then\n  case $ac_init_help in\n     short | recursive ) echo \"Configuration of pjproject 2.x:\";;\n   esac\n  cat <<\\_ACEOF\n\nOptional Features:\n  --disable-option-checking  ignore unrecognized --enable/--with options\n  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)\n  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]\n  --enable-epoll          Use /dev/epoll ioqueue on Linux (experimental)\n  --disable-small-filter  Exclude small filter in resampling\n  --disable-large-filter  Exclude large filter in resampling\n  --disable-speex-aec     Exclude Speex Acoustic Echo Canceller/AEC\n  --disable-g7221-codec   Exclude G.7221 codec in the build\n  --enable-libsamplerate  Link with libsamplerate when available. Note that\n                          PJMEDIA_RESAMPLE_IMP must also be configured\n  --enable-resample-dll   Build libresample as shared library\n  --disable-v4l2          Disable Video4Linux2 (default: not disabled)\n  --disable-openh264      Disable OpenH264 (default: not disabled)\n  --disable-libyuv        Exclude libyuv in the build\n  --disable-ssl           Exclude SSL support the build (default: autodetect)\n\n\nOptional Packages:\n  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]\n  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)\n  --with-ffmpeg=DIR       Specify alternate FFMPEG prefix\n  --with-vpx=DIR          Specify alternate libVPX prefix\n  --with-openh264=DIR     Specify alternate OpenH264 prefix\n  --with-libyuv=DIR       Specify alternate libyuv prefix\n  --with-ssl=DIR          Specify alternate libssl prefix\n\nSome influential environment variables:\n  CC          C compiler command\n  CFLAGS      C compiler flags\n  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a\n              nonstandard directory <lib dir>\n  LIBS        libraries to pass to the linker, e.g. -l<library>\n  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if\n              you have headers in a nonstandard directory <include dir>\n  CXX         C++ compiler command\n  CXXFLAGS    C++ compiler flags\n  CPP         C preprocessor\n\nUse these variables to override the choices made by `configure' or to help\nit to find libraries and programs with nonstandard names/locations.\n\nReport bugs to the package provider.\n_ACEOF\nac_status=$?\nfi\n\nif test \"$ac_init_help\" = \"recursive\"; then\n  # If there are subdirs, report their specific --help.\n  for ac_dir in : $ac_subdirs_all; do test \"x$ac_dir\" = x: && continue\n    test -d \"$ac_dir\" ||\n      { cd \"$srcdir\" && ac_pwd=`pwd` && srcdir=. && test -d \"$ac_dir\"; } ||\n      continue\n    ac_builddir=.\n\ncase \"$ac_dir\" in\n.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;\n*)\n  ac_dir_suffix=/`$as_echo \"$ac_dir\" | sed 's|^\\.[\\\\/]||'`\n  # A \"..\" for each directory in $ac_dir_suffix.\n  ac_top_builddir_sub=`$as_echo \"$ac_dir_suffix\" | sed 's|/[^\\\\/]*|/..|g;s|/||'`\n  case $ac_top_builddir_sub in\n  \"\") ac_top_builddir_sub=. ac_top_build_prefix= ;;\n  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;\n  esac ;;\nesac\nac_abs_top_builddir=$ac_pwd\nac_abs_builddir=$ac_pwd$ac_dir_suffix\n# for backward compatibility:\nac_top_builddir=$ac_top_build_prefix\n\ncase $srcdir in\n  .)  # We are building in place.\n    ac_srcdir=.\n    ac_top_srcdir=$ac_top_builddir_sub\n    ac_abs_top_srcdir=$ac_pwd ;;\n  [\\\\/]* | ?:[\\\\/]* )  # Absolute name.\n    ac_srcdir=$srcdir$ac_dir_suffix;\n    ac_top_srcdir=$srcdir\n    ac_abs_top_srcdir=$srcdir ;;\n  *) # Relative name.\n    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix\n    ac_top_srcdir=$ac_top_build_prefix$srcdir\n    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;\nesac\nac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix\n\n    cd \"$ac_dir\" || { ac_status=$?; continue; }\n    # Check for guested configure.\n    if test -f \"$ac_srcdir/configure.gnu\"; then\n      echo &&\n      $SHELL \"$ac_srcdir/configure.gnu\" --help=recursive\n    elif test -f \"$ac_srcdir/configure\"; then\n      echo &&\n      $SHELL \"$ac_srcdir/configure\" --help=recursive\n    else\n      $as_echo \"$as_me: WARNING: no configuration information is in $ac_dir\" >&2\n    fi || ac_status=$?\n    cd \"$ac_pwd\" || { ac_status=$?; break; }\n  done\nfi\n\ntest -n \"$ac_init_help\" && exit $ac_status\nif $ac_init_version; then\n  cat <<\\_ACEOF\npjproject configure 2.x\ngenerated by GNU Autoconf 2.69\n\nCopyright (C) 2012 Free Software Foundation, Inc.\nThis configure script is free software; the Free Software Foundation\ngives unlimited permission to copy, distribute and modify it.\n_ACEOF\n  exit\nfi\n\n## ------------------------ ##\n## Autoconf initialization. ##\n## ------------------------ ##\n\n# ac_fn_c_try_compile LINENO\n# --------------------------\n# Try to compile conftest.$ac_ext, and return whether this succeeded.\nac_fn_c_try_compile ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext\n  if { { ac_try=\"$ac_compile\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compile\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_c_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest.$ac_objext; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_try_compile\n\n# ac_fn_cxx_try_compile LINENO\n# ----------------------------\n# Try to compile conftest.$ac_ext, and return whether this succeeded.\nac_fn_cxx_try_compile ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext\n  if { { ac_try=\"$ac_compile\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compile\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_cxx_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest.$ac_objext; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_cxx_try_compile\n\n# ac_fn_c_try_link LINENO\n# -----------------------\n# Try to link conftest.$ac_ext, and return whether this succeeded.\nac_fn_c_try_link ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext conftest$ac_exeext\n  if { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_c_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest$ac_exeext && {\n\t test \"$cross_compiling\" = yes ||\n\t test -x conftest$ac_exeext\n       }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information\n  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would\n  # interfere with the next link command; also delete a directory that is\n  # left behind by Apple's compiler.  We do this before executing the actions.\n  rm -rf conftest.dSYM conftest_ipa8_conftest.oo\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_try_link\n\n# ac_fn_c_try_run LINENO\n# ----------------------\n# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes\n# that executables *can* be run.\nac_fn_c_try_run ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'\n  { { case \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_try\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: program exited with status $ac_status\" >&5\n       $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n       ac_retval=$ac_status\nfi\n  rm -rf conftest.dSYM conftest_ipa8_conftest.oo\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_try_run\n\n# ac_fn_c_try_cpp LINENO\n# ----------------------\n# Try to preprocess conftest.$ac_ext, and return whether this succeeded.\nac_fn_c_try_cpp ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if { { ac_try=\"$ac_cpp conftest.$ac_ext\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_cpp conftest.$ac_ext\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } > conftest.i && {\n\t test -z \"$ac_c_preproc_warn_flag$ac_c_werror_flag\" ||\n\t test ! -s conftest.err\n       }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n    ac_retval=1\nfi\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_try_cpp\n\n# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES\n# -------------------------------------------------------\n# Tests whether HEADER exists and can be compiled using the include files in\n# INCLUDES, setting the cache variable VAR accordingly.\nac_fn_c_check_header_compile ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif eval \\${$3+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$4\n#include <$2>\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  eval \"$3=yes\"\nelse\n  eval \"$3=no\"\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n\n} # ac_fn_c_check_header_compile\n\n# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES\n# -------------------------------------------------------\n# Tests whether HEADER exists, giving a warning if it cannot be compiled using\n# the include files in INCLUDES and setting the cache variable VAR\n# accordingly.\nac_fn_c_check_header_mongrel ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if eval \\${$3+:} false; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif eval \\${$3+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\nelse\n  # Is the header compilable?\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking $2 usability\" >&5\n$as_echo_n \"checking $2 usability... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$4\n#include <$2>\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_header_compiler=yes\nelse\n  ac_header_compiler=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler\" >&5\n$as_echo \"$ac_header_compiler\" >&6; }\n\n# Is the header present?\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking $2 presence\" >&5\n$as_echo_n \"checking $2 presence... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <$2>\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n  ac_header_preproc=yes\nelse\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.i conftest.$ac_ext\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc\" >&5\n$as_echo \"$ac_header_preproc\" >&6; }\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((\n  yes:no: )\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!\" >&5\n$as_echo \"$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result\" >&5\n$as_echo \"$as_me: WARNING: $2: proceeding with the compiler's result\" >&2;}\n    ;;\n  no:yes:* )\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled\" >&5\n$as_echo \"$as_me: WARNING: $2: present but cannot be compiled\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?\" >&5\n$as_echo \"$as_me: WARNING: $2:     check for missing prerequisite headers?\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation\" >&5\n$as_echo \"$as_me: WARNING: $2: see the Autoconf documentation\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\n$as_echo \"$as_me: WARNING: $2:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result\" >&5\n$as_echo \"$as_me: WARNING: $2: proceeding with the compiler's result\" >&2;}\n    ;;\nesac\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif eval \\${$3+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  eval \"$3=\\$ac_header_compiler\"\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\nfi\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n\n} # ac_fn_c_check_header_mongrel\n\n# ac_fn_c_check_func LINENO FUNC VAR\n# ----------------------------------\n# Tests whether FUNC exists, setting the cache variable VAR accordingly\nac_fn_c_check_func ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif eval \\${$3+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n/* Define $2 to an innocuous variant, in case <limits.h> declares $2.\n   For example, HP-UX 11i <limits.h> declares gettimeofday.  */\n#define $2 innocuous_$2\n\n/* System header to define __stub macros and hopefully few prototypes,\n    which can conflict with char $2 (); below.\n    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n    <limits.h> exists even on freestanding compilers.  */\n\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\n#undef $2\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar $2 ();\n/* The GNU C library defines this for functions which it implements\n    to always fail with ENOSYS.  Some functions are actually named\n    something starting with __ and the normal name is an alias.  */\n#if defined __stub_$2 || defined __stub___$2\nchoke me\n#endif\n\nint\nmain ()\n{\nreturn $2 ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  eval \"$3=yes\"\nelse\n  eval \"$3=no\"\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n\n} # ac_fn_c_check_func\ncat >config.log <<_ACEOF\nThis file contains any messages produced by compilers while\nrunning configure, to aid debugging if configure makes a mistake.\n\nIt was created by pjproject $as_me 2.x, which was\ngenerated by GNU Autoconf 2.69.  Invocation command line was\n\n  $ $0 $@\n\n_ACEOF\nexec 5>>config.log\n{\ncat <<_ASUNAME\n## --------- ##\n## Platform. ##\n## --------- ##\n\nhostname = `(hostname || uname -n) 2>/dev/null | sed 1q`\nuname -m = `(uname -m) 2>/dev/null || echo unknown`\nuname -r = `(uname -r) 2>/dev/null || echo unknown`\nuname -s = `(uname -s) 2>/dev/null || echo unknown`\nuname -v = `(uname -v) 2>/dev/null || echo unknown`\n\n/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`\n/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`\n\n/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`\n/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`\n/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`\n/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`\n/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`\n/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`\n/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`\n\n_ASUNAME\n\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    $as_echo \"PATH: $as_dir\"\n  done\nIFS=$as_save_IFS\n\n} >&5\n\ncat >&5 <<_ACEOF\n\n\n## ----------- ##\n## Core tests. ##\n## ----------- ##\n\n_ACEOF\n\n\n# Keep a trace of the command line.\n# Strip out --no-create and --no-recursion so they do not pile up.\n# Strip out --silent because we don't want to record it for future runs.\n# Also quote any args containing shell meta-characters.\n# Make two passes to allow for proper duplicate-argument suppression.\nac_configure_args=\nac_configure_args0=\nac_configure_args1=\nac_must_keep_next=false\nfor ac_pass in 1 2\ndo\n  for ac_arg\n  do\n    case $ac_arg in\n    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;\n    -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n    | -silent | --silent | --silen | --sile | --sil)\n      continue ;;\n    *\\'*)\n      ac_arg=`$as_echo \"$ac_arg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    esac\n    case $ac_pass in\n    1) as_fn_append ac_configure_args0 \" '$ac_arg'\" ;;\n    2)\n      as_fn_append ac_configure_args1 \" '$ac_arg'\"\n      if test $ac_must_keep_next = true; then\n\tac_must_keep_next=false # Got value, back to normal.\n      else\n\tcase $ac_arg in\n\t  *=* | --config-cache | -C | -disable-* | --disable-* \\\n\t  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \\\n\t  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \\\n\t  | -with-* | --with-* | -without-* | --without-* | --x)\n\t    case \"$ac_configure_args0 \" in\n\t      \"$ac_configure_args1\"*\" '$ac_arg' \"* ) continue ;;\n\t    esac\n\t    ;;\n\t  -* ) ac_must_keep_next=true ;;\n\tesac\n      fi\n      as_fn_append ac_configure_args \" '$ac_arg'\"\n      ;;\n    esac\n  done\ndone\n{ ac_configure_args0=; unset ac_configure_args0;}\n{ ac_configure_args1=; unset ac_configure_args1;}\n\n# When interrupted or exit'd, cleanup temporary files, and complete\n# config.log.  We remove comments because anyway the quotes in there\n# would cause problems or look ugly.\n# WARNING: Use '\\'' to represent an apostrophe within the trap.\n# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.\ntrap 'exit_status=$?\n  # Save into config.log some information that might help in debugging.\n  {\n    echo\n\n    $as_echo \"## ---------------- ##\n## Cache variables. ##\n## ---------------- ##\"\n    echo\n    # The following way of writing the cache mishandles newlines in values,\n(\n  for ac_var in `(set) 2>&1 | sed -n '\\''s/^\\([a-zA-Z_][a-zA-Z0-9_]*\\)=.*/\\1/p'\\''`; do\n    eval ac_val=\\$$ac_var\n    case $ac_val in #(\n    *${as_nl}*)\n      case $ac_var in #(\n      *_cv_*) { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline\" >&5\n$as_echo \"$as_me: WARNING: cache variable $ac_var contains a newline\" >&2;} ;;\n      esac\n      case $ac_var in #(\n      _ | IFS | as_nl) ;; #(\n      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(\n      *) { eval $ac_var=; unset $ac_var;} ;;\n      esac ;;\n    esac\n  done\n  (set) 2>&1 |\n    case $as_nl`(ac_space='\\'' '\\''; set) 2>&1` in #(\n    *${as_nl}ac_space=\\ *)\n      sed -n \\\n\t\"s/'\\''/'\\''\\\\\\\\'\\'''\\''/g;\n\t  s/^\\\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\\\)=\\\\(.*\\\\)/\\\\1='\\''\\\\2'\\''/p\"\n      ;; #(\n    *)\n      sed -n \"/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p\"\n      ;;\n    esac |\n    sort\n)\n    echo\n\n    $as_echo \"## ----------------- ##\n## Output variables. ##\n## ----------------- ##\"\n    echo\n    for ac_var in $ac_subst_vars\n    do\n      eval ac_val=\\$$ac_var\n      case $ac_val in\n      *\\'\\''*) ac_val=`$as_echo \"$ac_val\" | sed \"s/'\\''/'\\''\\\\\\\\\\\\\\\\'\\'''\\''/g\"`;;\n      esac\n      $as_echo \"$ac_var='\\''$ac_val'\\''\"\n    done | sort\n    echo\n\n    if test -n \"$ac_subst_files\"; then\n      $as_echo \"## ------------------- ##\n## File substitutions. ##\n## ------------------- ##\"\n      echo\n      for ac_var in $ac_subst_files\n      do\n\teval ac_val=\\$$ac_var\n\tcase $ac_val in\n\t*\\'\\''*) ac_val=`$as_echo \"$ac_val\" | sed \"s/'\\''/'\\''\\\\\\\\\\\\\\\\'\\'''\\''/g\"`;;\n\tesac\n\t$as_echo \"$ac_var='\\''$ac_val'\\''\"\n      done | sort\n      echo\n    fi\n\n    if test -s confdefs.h; then\n      $as_echo \"## ----------- ##\n## confdefs.h. ##\n## ----------- ##\"\n      echo\n      cat confdefs.h\n      echo\n    fi\n    test \"$ac_signal\" != 0 &&\n      $as_echo \"$as_me: caught signal $ac_signal\"\n    $as_echo \"$as_me: exit $exit_status\"\n  } >&5\n  rm -f core *.core core.conftest.* &&\n    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&\n    exit $exit_status\n' 0\nfor ac_signal in 1 2 13 15; do\n  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal\ndone\nac_signal=0\n\n# confdefs.h avoids OS command line length limits that DEFS can exceed.\nrm -f -r conftest* confdefs.h\n\n$as_echo \"/* confdefs.h */\" > confdefs.h\n\n# Predefined preprocessor variables.\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_NAME \"$PACKAGE_NAME\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_VERSION \"$PACKAGE_VERSION\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_STRING \"$PACKAGE_STRING\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_URL \"$PACKAGE_URL\"\n_ACEOF\n\n\n# Let the site file select an alternate cache file if it wants to.\n# Prefer an explicitly selected file to automatically selected ones.\nac_site_file1=NONE\nac_site_file2=NONE\nif test -n \"$CONFIG_SITE\"; then\n  # We do not want a PATH search for config.site.\n  case $CONFIG_SITE in #((\n    -*)  ac_site_file1=./$CONFIG_SITE;;\n    */*) ac_site_file1=$CONFIG_SITE;;\n    *)   ac_site_file1=./$CONFIG_SITE;;\n  esac\nelif test \"x$prefix\" != xNONE; then\n  ac_site_file1=$prefix/share/config.site\n  ac_site_file2=$prefix/etc/config.site\nelse\n  ac_site_file1=$ac_default_prefix/share/config.site\n  ac_site_file2=$ac_default_prefix/etc/config.site\nfi\nfor ac_site_file in \"$ac_site_file1\" \"$ac_site_file2\"\ndo\n  test \"x$ac_site_file\" = xNONE && continue\n  if test /dev/null != \"$ac_site_file\" && test -r \"$ac_site_file\"; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file\" >&5\n$as_echo \"$as_me: loading site script $ac_site_file\" >&6;}\n    sed 's/^/| /' \"$ac_site_file\" >&5\n    . \"$ac_site_file\" \\\n      || { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error $? \"failed to load site script $ac_site_file\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\n  fi\ndone\n\nif test -r \"$cache_file\"; then\n  # Some versions of bash will fail to source /dev/null (special files\n  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.\n  if test /dev/null != \"$cache_file\" && test -f \"$cache_file\"; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: loading cache $cache_file\" >&5\n$as_echo \"$as_me: loading cache $cache_file\" >&6;}\n    case $cache_file in\n      [\\\\/]* | ?:[\\\\/]* ) . \"$cache_file\";;\n      *)                      . \"./$cache_file\";;\n    esac\n  fi\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: creating cache $cache_file\" >&5\n$as_echo \"$as_me: creating cache $cache_file\" >&6;}\n  >$cache_file\nfi\n\n# Check that the precious variables saved in the cache have kept the same\n# value.\nac_cache_corrupted=false\nfor ac_var in $ac_precious_vars; do\n  eval ac_old_set=\\$ac_cv_env_${ac_var}_set\n  eval ac_new_set=\\$ac_env_${ac_var}_set\n  eval ac_old_val=\\$ac_cv_env_${ac_var}_value\n  eval ac_new_val=\\$ac_env_${ac_var}_value\n  case $ac_old_set,$ac_new_set in\n    set,)\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: error: \\`$ac_var' was set to \\`$ac_old_val' in the previous run\" >&5\n$as_echo \"$as_me: error: \\`$ac_var' was set to \\`$ac_old_val' in the previous run\" >&2;}\n      ac_cache_corrupted=: ;;\n    ,set)\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: error: \\`$ac_var' was not set in the previous run\" >&5\n$as_echo \"$as_me: error: \\`$ac_var' was not set in the previous run\" >&2;}\n      ac_cache_corrupted=: ;;\n    ,);;\n    *)\n      if test \"x$ac_old_val\" != \"x$ac_new_val\"; then\n\t# differences in whitespace do not lead to failure.\n\tac_old_val_w=`echo x $ac_old_val`\n\tac_new_val_w=`echo x $ac_new_val`\n\tif test \"$ac_old_val_w\" != \"$ac_new_val_w\"; then\n\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: error: \\`$ac_var' has changed since the previous run:\" >&5\n$as_echo \"$as_me: error: \\`$ac_var' has changed since the previous run:\" >&2;}\n\t  ac_cache_corrupted=:\n\telse\n\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \\`$ac_var' since the previous run:\" >&5\n$as_echo \"$as_me: warning: ignoring whitespace changes in \\`$ac_var' since the previous run:\" >&2;}\n\t  eval $ac_var=\\$ac_old_val\n\tfi\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}:   former value:  \\`$ac_old_val'\" >&5\n$as_echo \"$as_me:   former value:  \\`$ac_old_val'\" >&2;}\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}:   current value: \\`$ac_new_val'\" >&5\n$as_echo \"$as_me:   current value: \\`$ac_new_val'\" >&2;}\n      fi;;\n  esac\n  # Pass precious variables to config.status.\n  if test \"$ac_new_set\" = set; then\n    case $ac_new_val in\n    *\\'*) ac_arg=$ac_var=`$as_echo \"$ac_new_val\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    *) ac_arg=$ac_var=$ac_new_val ;;\n    esac\n    case \" $ac_configure_args \" in\n      *\" '$ac_arg' \"*) ;; # Avoid dups.  Use of quotes ensures accuracy.\n      *) as_fn_append ac_configure_args \" '$ac_arg'\" ;;\n    esac\n  fi\ndone\nif $ac_cache_corrupted; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build\" >&5\n$as_echo \"$as_me: error: changes in the environment can compromise the build\" >&2;}\n  as_fn_error $? \"run \\`make distclean' and/or \\`rm $cache_file' and start over\" \"$LINENO\" 5\nfi\n## -------------------- ##\n## Main body of script. ##\n## -------------------- ##\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n\nhost_orig=\"$host\"\n\nac_aux_dir=\nfor ac_dir in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"; do\n  if test -f \"$ac_dir/install-sh\"; then\n    ac_aux_dir=$ac_dir\n    ac_install_sh=\"$ac_aux_dir/install-sh -c\"\n    break\n  elif test -f \"$ac_dir/install.sh\"; then\n    ac_aux_dir=$ac_dir\n    ac_install_sh=\"$ac_aux_dir/install.sh -c\"\n    break\n  elif test -f \"$ac_dir/shtool\"; then\n    ac_aux_dir=$ac_dir\n    ac_install_sh=\"$ac_aux_dir/shtool install -c\"\n    break\n  fi\ndone\nif test -z \"$ac_aux_dir\"; then\n  as_fn_error $? \"cannot find install-sh, install.sh, or shtool in \\\"$srcdir\\\" \\\"$srcdir/..\\\" \\\"$srcdir/../..\\\"\" \"$LINENO\" 5\nfi\n\n# These three variables are undocumented and unsupported,\n# and are intended to be withdrawn in a future Autoconf release.\n# They can cause serious problems if a builder's source tree is in a directory\n# whose full name contains unusual characters.\nac_config_guess=\"$SHELL $ac_aux_dir/config.guess\"  # Please don't use this var.\nac_config_sub=\"$SHELL $ac_aux_dir/config.sub\"  # Please don't use this var.\nac_configure=\"$SHELL $ac_aux_dir/configure\"  # Please don't use this var.\n\n\n# Make sure we can run config.sub.\n$SHELL \"$ac_aux_dir/config.sub\" sun4 >/dev/null 2>&1 ||\n  as_fn_error $? \"cannot run $SHELL $ac_aux_dir/config.sub\" \"$LINENO\" 5\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking build system type\" >&5\n$as_echo_n \"checking build system type... \" >&6; }\nif ${ac_cv_build+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_build_alias=$build_alias\ntest \"x$ac_build_alias\" = x &&\n  ac_build_alias=`$SHELL \"$ac_aux_dir/config.guess\"`\ntest \"x$ac_build_alias\" = x &&\n  as_fn_error $? \"cannot guess build type; you must specify one\" \"$LINENO\" 5\nac_cv_build=`$SHELL \"$ac_aux_dir/config.sub\" $ac_build_alias` ||\n  as_fn_error $? \"$SHELL $ac_aux_dir/config.sub $ac_build_alias failed\" \"$LINENO\" 5\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_build\" >&5\n$as_echo \"$ac_cv_build\" >&6; }\ncase $ac_cv_build in\n*-*-*) ;;\n*) as_fn_error $? \"invalid value of canonical build\" \"$LINENO\" 5;;\nesac\nbuild=$ac_cv_build\nac_save_IFS=$IFS; IFS='-'\nset x $ac_cv_build\nshift\nbuild_cpu=$1\nbuild_vendor=$2\nshift; shift\n# Remember, the first character of IFS is used to create $*,\n# except with old shells:\nbuild_os=$*\nIFS=$ac_save_IFS\ncase $build_os in *\\ *) build_os=`echo \"$build_os\" | sed 's/ /-/g'`;; esac\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking host system type\" >&5\n$as_echo_n \"checking host system type... \" >&6; }\nif ${ac_cv_host+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test \"x$host_alias\" = x; then\n  ac_cv_host=$ac_cv_build\nelse\n  ac_cv_host=`$SHELL \"$ac_aux_dir/config.sub\" $host_alias` ||\n    as_fn_error $? \"$SHELL $ac_aux_dir/config.sub $host_alias failed\" \"$LINENO\" 5\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_host\" >&5\n$as_echo \"$ac_cv_host\" >&6; }\ncase $ac_cv_host in\n*-*-*) ;;\n*) as_fn_error $? \"invalid value of canonical host\" \"$LINENO\" 5;;\nesac\nhost=$ac_cv_host\nac_save_IFS=$IFS; IFS='-'\nset x $ac_cv_host\nshift\nhost_cpu=$1\nhost_vendor=$2\nshift; shift\n# Remember, the first character of IFS is used to create $*,\n# except with old shells:\nhost_os=$*\nIFS=$ac_save_IFS\ncase $host_os in *\\ *) host_os=`echo \"$host_os\" | sed 's/ /-/g'`;; esac\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking target system type\" >&5\n$as_echo_n \"checking target system type... \" >&6; }\nif ${ac_cv_target+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test \"x$target_alias\" = x; then\n  ac_cv_target=$ac_cv_host\nelse\n  ac_cv_target=`$SHELL \"$ac_aux_dir/config.sub\" $target_alias` ||\n    as_fn_error $? \"$SHELL $ac_aux_dir/config.sub $target_alias failed\" \"$LINENO\" 5\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_target\" >&5\n$as_echo \"$ac_cv_target\" >&6; }\ncase $ac_cv_target in\n*-*-*) ;;\n*) as_fn_error $? \"invalid value of canonical target\" \"$LINENO\" 5;;\nesac\ntarget=$ac_cv_target\nac_save_IFS=$IFS; IFS='-'\nset x $ac_cv_target\nshift\ntarget_cpu=$1\ntarget_vendor=$2\nshift; shift\n# Remember, the first character of IFS is used to create $*,\n# except with old shells:\ntarget_os=$*\nIFS=$ac_save_IFS\ncase $target_os in *\\ *) target_os=`echo \"$target_os\" | sed 's/ /-/g'`;; esac\n\n\n# The aliases save the names the user supplied, while $host etc.\n# will get canonicalized.\ntest -n \"$target_alias\" &&\n  test \"$program_prefix$program_suffix$program_transform_name\" = \\\n    NONENONEs,x,x, &&\n  program_prefix=${target_alias}-\nac_config_headers=\"$ac_config_headers pjlib/include/pj/compat/os_auto.h pjlib/include/pj/compat/m_auto.h pjmedia/include/pjmedia/config_auto.h pjmedia/include/pjmedia-codec/config_auto.h pjsip/include/pjsip/sip_autoconf.h\"\n\nac_config_files=\"$ac_config_files build.mak build/os-auto.mak build/cc-auto.mak pjlib/build/os-auto.mak pjmedia/build/os-auto.mak pjsip/build/os-auto.mak third_party/build/webrtc/os-auto.mak third_party/build/os-auto.mak\"\n\n\n\nif test \"$CFLAGS\" = \"\"; then\n  CFLAGS=\"-O2\"\nelse\n  CFLAGS=\"$CFLAGS\"\nfi\n\nCXXFLAGS=\"$CFLAGS $CXXFLAGS\"\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}gcc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}gcc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_CC+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_CC=\"${ac_tool_prefix}gcc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_CC\"; then\n  ac_ct_CC=$CC\n  # Extract the first word of \"gcc\", so it can be a program name with args.\nset dummy gcc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_ac_ct_CC+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CC\"; then\n  ac_cv_prog_ac_ct_CC=\"$ac_ct_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_ac_ct_CC=\"gcc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CC=$ac_cv_prog_ac_ct_CC\nif test -n \"$ac_ct_CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC\" >&5\n$as_echo \"$ac_ct_CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_CC\" = x; then\n    CC=\"\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CC=$ac_ct_CC\n  fi\nelse\n  CC=\"$ac_cv_prog_CC\"\nfi\n\nif test -z \"$CC\"; then\n          if test -n \"$ac_tool_prefix\"; then\n    # Extract the first word of \"${ac_tool_prefix}cc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}cc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_CC+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_CC=\"${ac_tool_prefix}cc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  fi\nfi\nif test -z \"$CC\"; then\n  # Extract the first word of \"cc\", so it can be a program name with args.\nset dummy cc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_CC+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\n  ac_prog_rejected=no\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    if test \"$as_dir/$ac_word$ac_exec_ext\" = \"/usr/ucb/cc\"; then\n       ac_prog_rejected=yes\n       continue\n     fi\n    ac_cv_prog_CC=\"cc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nif test $ac_prog_rejected = yes; then\n  # We found a bogon in the path, so make sure we never use it.\n  set dummy $ac_cv_prog_CC\n  shift\n  if test $# != 0; then\n    # We chose a different compiler from the bogus one.\n    # However, it has the same basename, so the bogon will be chosen\n    # first if we set CC to just the basename; use the full file name.\n    shift\n    ac_cv_prog_CC=\"$as_dir/$ac_word${1+' '}$@\"\n  fi\nfi\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$CC\"; then\n  if test -n \"$ac_tool_prefix\"; then\n  for ac_prog in cl.exe\n  do\n    # Extract the first word of \"$ac_tool_prefix$ac_prog\", so it can be a program name with args.\nset dummy $ac_tool_prefix$ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_CC+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_CC=\"$ac_tool_prefix$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n    test -n \"$CC\" && break\n  done\nfi\nif test -z \"$CC\"; then\n  ac_ct_CC=$CC\n  for ac_prog in cl.exe\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_ac_ct_CC+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CC\"; then\n  ac_cv_prog_ac_ct_CC=\"$ac_ct_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_ac_ct_CC=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CC=$ac_cv_prog_ac_ct_CC\nif test -n \"$ac_ct_CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC\" >&5\n$as_echo \"$ac_ct_CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$ac_ct_CC\" && break\ndone\n\n  if test \"x$ac_ct_CC\" = x; then\n    CC=\"\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CC=$ac_ct_CC\n  fi\nfi\n\nfi\n\n\ntest -z \"$CC\" && { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error $? \"no acceptable C compiler found in \\$PATH\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\n\n# Provide some information about the compiler.\n$as_echo \"$as_me:${as_lineno-$LINENO}: checking for C compiler version\" >&5\nset X $ac_compile\nac_compiler=$2\nfor ac_option in --version -v -V -qversion; do\n  { { ac_try=\"$ac_compiler $ac_option >&5\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compiler $ac_option >&5\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    sed '10a\\\n... rest of stderr output deleted ...\n         10q' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n  fi\n  rm -f conftest.er1 conftest.err\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\ndone\n\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nac_clean_files_save=$ac_clean_files\nac_clean_files=\"$ac_clean_files a.out a.out.dSYM a.exe b.out\"\n# Try to create an executable without -o first, disregard a.out.\n# It will help us diagnose broken compilers, and finding out an intuition\n# of exeext.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the C compiler works\" >&5\n$as_echo_n \"checking whether the C compiler works... \" >&6; }\nac_link_default=`$as_echo \"$ac_link\" | sed 's/ -o *conftest[^ ]*//'`\n\n# The possible output files:\nac_files=\"a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*\"\n\nac_rmfiles=\nfor ac_file in $ac_files\ndo\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;\n    * ) ac_rmfiles=\"$ac_rmfiles $ac_file\";;\n  esac\ndone\nrm -f $ac_rmfiles\n\nif { { ac_try=\"$ac_link_default\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link_default\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then :\n  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.\n# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'\n# in a Makefile.  We should not override ac_cv_exeext if it was cached,\n# so that the user can short-circuit this test for compilers unknown to\n# Autoconf.\nfor ac_file in $ac_files ''\ndo\n  test -f \"$ac_file\" || continue\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )\n\t;;\n    [ab].out )\n\t# We found the default executable, but exeext='' is most\n\t# certainly right.\n\tbreak;;\n    *.* )\n\tif test \"${ac_cv_exeext+set}\" = set && test \"$ac_cv_exeext\" != no;\n\tthen :; else\n\t   ac_cv_exeext=`expr \"$ac_file\" : '[^.]*\\(\\..*\\)'`\n\tfi\n\t# We set ac_cv_exeext here because the later test for it is not\n\t# safe: cross compilers may not add the suffix if given an `-o'\n\t# argument, so we may need to know it at that point already.\n\t# Even if this section looks crufty: it has the advantage of\n\t# actually working.\n\tbreak;;\n    * )\n\tbreak;;\n  esac\ndone\ntest \"$ac_cv_exeext\" = no && ac_cv_exeext=\n\nelse\n  ac_file=''\nfi\nif test -z \"$ac_file\"; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n$as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n{ { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error 77 \"C compiler cannot create executables\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name\" >&5\n$as_echo_n \"checking for C compiler default output file name... \" >&6; }\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_file\" >&5\n$as_echo \"$ac_file\" >&6; }\nac_exeext=$ac_cv_exeext\n\nrm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out\nac_clean_files=$ac_clean_files_save\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for suffix of executables\" >&5\n$as_echo_n \"checking for suffix of executables... \" >&6; }\nif { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then :\n  # If both `conftest.exe' and `conftest' are `present' (well, observable)\n# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will\n# work properly (i.e., refer to `conftest.exe'), while it won't with\n# `rm'.\nfor ac_file in conftest.exe conftest conftest.*; do\n  test -f \"$ac_file\" || continue\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;\n    *.* ) ac_cv_exeext=`expr \"$ac_file\" : '[^.]*\\(\\..*\\)'`\n\t  break;;\n    * ) break;;\n  esac\ndone\nelse\n  { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error $? \"cannot compute suffix of executables: cannot compile and link\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\nfi\nrm -f conftest conftest$ac_cv_exeext\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext\" >&5\n$as_echo \"$ac_cv_exeext\" >&6; }\n\nrm -f conftest.$ac_ext\nEXEEXT=$ac_cv_exeext\nac_exeext=$EXEEXT\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdio.h>\nint\nmain ()\n{\nFILE *f = fopen (\"conftest.out\", \"w\");\n return ferror (f) || fclose (f) != 0;\n\n  ;\n  return 0;\n}\n_ACEOF\nac_clean_files=\"$ac_clean_files conftest.out\"\n# Check that the compiler produces executables we can run.  If not, either\n# the compiler is broken, or we cross compile.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling\" >&5\n$as_echo_n \"checking whether we are cross compiling... \" >&6; }\nif test \"$cross_compiling\" != yes; then\n  { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\n  if { ac_try='./conftest$ac_cv_exeext'\n  { { case \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_try\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; }; then\n    cross_compiling=no\n  else\n    if test \"$cross_compiling\" = maybe; then\n\tcross_compiling=yes\n    else\n\t{ { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error $? \"cannot run C compiled programs.\nIf you meant to cross compile, use \\`--host'.\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\n    fi\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $cross_compiling\" >&5\n$as_echo \"$cross_compiling\" >&6; }\n\nrm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out\nac_clean_files=$ac_clean_files_save\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for suffix of object files\" >&5\n$as_echo_n \"checking for suffix of object files... \" >&6; }\nif ${ac_cv_objext+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.o conftest.obj\nif { { ac_try=\"$ac_compile\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compile\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then :\n  for ac_file in conftest.o conftest.obj conftest.*; do\n  test -f \"$ac_file\" || continue;\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;\n    *) ac_cv_objext=`expr \"$ac_file\" : '.*\\.\\(.*\\)'`\n       break;;\n  esac\ndone\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n{ { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error $? \"cannot compute suffix of object files: cannot compile\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\nfi\nrm -f conftest.$ac_cv_objext conftest.$ac_ext\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext\" >&5\n$as_echo \"$ac_cv_objext\" >&6; }\nOBJEXT=$ac_cv_objext\nac_objext=$OBJEXT\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler\" >&5\n$as_echo_n \"checking whether we are using the GNU C compiler... \" >&6; }\nif ${ac_cv_c_compiler_gnu+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n#ifndef __GNUC__\n       choke me\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_compiler_gnu=yes\nelse\n  ac_compiler_gnu=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nac_cv_c_compiler_gnu=$ac_compiler_gnu\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu\" >&5\n$as_echo \"$ac_cv_c_compiler_gnu\" >&6; }\nif test $ac_compiler_gnu = yes; then\n  GCC=yes\nelse\n  GCC=\nfi\nac_test_CFLAGS=${CFLAGS+set}\nac_save_CFLAGS=$CFLAGS\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g\" >&5\n$as_echo_n \"checking whether $CC accepts -g... \" >&6; }\nif ${ac_cv_prog_cc_g+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_save_c_werror_flag=$ac_c_werror_flag\n   ac_c_werror_flag=yes\n   ac_cv_prog_cc_g=no\n   CFLAGS=\"-g\"\n   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_g=yes\nelse\n  CFLAGS=\"\"\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n\nelse\n  ac_c_werror_flag=$ac_save_c_werror_flag\n\t CFLAGS=\"-g\"\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_g=yes\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n   ac_c_werror_flag=$ac_save_c_werror_flag\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g\" >&5\n$as_echo \"$ac_cv_prog_cc_g\" >&6; }\nif test \"$ac_test_CFLAGS\" = set; then\n  CFLAGS=$ac_save_CFLAGS\nelif test $ac_cv_prog_cc_g = yes; then\n  if test \"$GCC\" = yes; then\n    CFLAGS=\"-g -O2\"\n  else\n    CFLAGS=\"-g\"\n  fi\nelse\n  if test \"$GCC\" = yes; then\n    CFLAGS=\"-O2\"\n  else\n    CFLAGS=\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89\" >&5\n$as_echo_n \"checking for $CC option to accept ISO C89... \" >&6; }\nif ${ac_cv_prog_cc_c89+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_cv_prog_cc_c89=no\nac_save_CC=$CC\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdarg.h>\n#include <stdio.h>\nstruct stat;\n/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */\nstruct buf { int x; };\nFILE * (*rcsopen) (struct buf *, struct stat *, int);\nstatic char *e (p, i)\n     char **p;\n     int i;\n{\n  return p[i];\n}\nstatic char *f (char * (*g) (char **, int), char **p, ...)\n{\n  char *s;\n  va_list v;\n  va_start (v,p);\n  s = g (p, va_arg (v,int));\n  va_end (v);\n  return s;\n}\n\n/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has\n   function prototypes and stuff, but not '\\xHH' hex character constants.\n   These don't provoke an error unfortunately, instead are silently treated\n   as 'x'.  The following induces an error, until -std is added to get\n   proper ANSI mode.  Curiously '\\x00'!='x' always comes out true, for an\n   array size at least.  It's necessary to write '\\x00'==0 to get something\n   that's true only with -std.  */\nint osf4_cc_array ['\\x00' == 0 ? 1 : -1];\n\n/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters\n   inside strings and character constants.  */\n#define FOO(x) 'x'\nint xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];\n\nint test (int i, double x);\nstruct s1 {int (*f) (int a);};\nstruct s2 {int (*f) (double a);};\nint pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);\nint argc;\nchar **argv;\nint\nmain ()\n{\nreturn f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];\n  ;\n  return 0;\n}\n_ACEOF\nfor ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \\\n\t-Ae \"-Aa -D_HPUX_SOURCE\" \"-Xc -D__EXTENSIONS__\"\ndo\n  CC=\"$ac_save_CC $ac_arg\"\n  if ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_c89=$ac_arg\nfi\nrm -f core conftest.err conftest.$ac_objext\n  test \"x$ac_cv_prog_cc_c89\" != \"xno\" && break\ndone\nrm -f conftest.$ac_ext\nCC=$ac_save_CC\n\nfi\n# AC_CACHE_VAL\ncase \"x$ac_cv_prog_cc_c89\" in\n  x)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: none needed\" >&5\n$as_echo \"none needed\" >&6; } ;;\n  xno)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: unsupported\" >&5\n$as_echo \"unsupported\" >&6; } ;;\n  *)\n    CC=\"$CC $ac_cv_prog_cc_c89\"\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89\" >&5\n$as_echo \"$ac_cv_prog_cc_c89\" >&6; } ;;\nesac\nif test \"x$ac_cv_prog_cc_c89\" != xno; then :\n\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nac_ext=cpp\nac_cpp='$CXXCPP $CPPFLAGS'\nac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_cxx_compiler_gnu\nif test -z \"$CXX\"; then\n  if test -n \"$CCC\"; then\n    CXX=$CCC\n  else\n    if test -n \"$ac_tool_prefix\"; then\n  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC\n  do\n    # Extract the first word of \"$ac_tool_prefix$ac_prog\", so it can be a program name with args.\nset dummy $ac_tool_prefix$ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_CXX+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CXX\"; then\n  ac_cv_prog_CXX=\"$CXX\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_CXX=\"$ac_tool_prefix$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCXX=$ac_cv_prog_CXX\nif test -n \"$CXX\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CXX\" >&5\n$as_echo \"$CXX\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n    test -n \"$CXX\" && break\n  done\nfi\nif test -z \"$CXX\"; then\n  ac_ct_CXX=$CXX\n  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_ac_ct_CXX+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CXX\"; then\n  ac_cv_prog_ac_ct_CXX=\"$ac_ct_CXX\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_ac_ct_CXX=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CXX=$ac_cv_prog_ac_ct_CXX\nif test -n \"$ac_ct_CXX\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX\" >&5\n$as_echo \"$ac_ct_CXX\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$ac_ct_CXX\" && break\ndone\n\n  if test \"x$ac_ct_CXX\" = x; then\n    CXX=\"g++\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CXX=$ac_ct_CXX\n  fi\nfi\n\n  fi\nfi\n# Provide some information about the compiler.\n$as_echo \"$as_me:${as_lineno-$LINENO}: checking for C++ compiler version\" >&5\nset X $ac_compile\nac_compiler=$2\nfor ac_option in --version -v -V -qversion; do\n  { { ac_try=\"$ac_compiler $ac_option >&5\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compiler $ac_option >&5\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    sed '10a\\\n... rest of stderr output deleted ...\n         10q' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n  fi\n  rm -f conftest.er1 conftest.err\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\ndone\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler\" >&5\n$as_echo_n \"checking whether we are using the GNU C++ compiler... \" >&6; }\nif ${ac_cv_cxx_compiler_gnu+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n#ifndef __GNUC__\n       choke me\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_compiler_gnu=yes\nelse\n  ac_compiler_gnu=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nac_cv_cxx_compiler_gnu=$ac_compiler_gnu\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu\" >&5\n$as_echo \"$ac_cv_cxx_compiler_gnu\" >&6; }\nif test $ac_compiler_gnu = yes; then\n  GXX=yes\nelse\n  GXX=\nfi\nac_test_CXXFLAGS=${CXXFLAGS+set}\nac_save_CXXFLAGS=$CXXFLAGS\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g\" >&5\n$as_echo_n \"checking whether $CXX accepts -g... \" >&6; }\nif ${ac_cv_prog_cxx_g+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_save_cxx_werror_flag=$ac_cxx_werror_flag\n   ac_cxx_werror_flag=yes\n   ac_cv_prog_cxx_g=no\n   CXXFLAGS=\"-g\"\n   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cxx_g=yes\nelse\n  CXXFLAGS=\"\"\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n\nelse\n  ac_cxx_werror_flag=$ac_save_cxx_werror_flag\n\t CXXFLAGS=\"-g\"\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cxx_g=yes\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n   ac_cxx_werror_flag=$ac_save_cxx_werror_flag\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g\" >&5\n$as_echo \"$ac_cv_prog_cxx_g\" >&6; }\nif test \"$ac_test_CXXFLAGS\" = set; then\n  CXXFLAGS=$ac_save_CXXFLAGS\nelif test $ac_cv_prog_cxx_g = yes; then\n  if test \"$GXX\" = yes; then\n    CXXFLAGS=\"-g -O2\"\n  else\n    CXXFLAGS=\"-g\"\n  fi\nelse\n  if test \"$GXX\" = yes; then\n    CXXFLAGS=\"-O2\"\n  else\n    CXXFLAGS=\n  fi\nfi\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}ranlib\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}ranlib; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_RANLIB+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$RANLIB\"; then\n  ac_cv_prog_RANLIB=\"$RANLIB\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_RANLIB=\"${ac_tool_prefix}ranlib\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nRANLIB=$ac_cv_prog_RANLIB\nif test -n \"$RANLIB\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $RANLIB\" >&5\n$as_echo \"$RANLIB\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_RANLIB\"; then\n  ac_ct_RANLIB=$RANLIB\n  # Extract the first word of \"ranlib\", so it can be a program name with args.\nset dummy ranlib; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_ac_ct_RANLIB+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_RANLIB\"; then\n  ac_cv_prog_ac_ct_RANLIB=\"$ac_ct_RANLIB\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_ac_ct_RANLIB=\"ranlib\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB\nif test -n \"$ac_ct_RANLIB\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB\" >&5\n$as_echo \"$ac_ct_RANLIB\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_RANLIB\" = x; then\n    RANLIB=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    RANLIB=$ac_ct_RANLIB\n  fi\nelse\n  RANLIB=\"$ac_cv_prog_RANLIB\"\nfi\n\nif test -n \"$ac_tool_prefix\"; then\n  for ac_prog in ar gar\n  do\n    # Extract the first word of \"$ac_tool_prefix$ac_prog\", so it can be a program name with args.\nset dummy $ac_tool_prefix$ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_AR+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$AR\"; then\n  ac_cv_prog_AR=\"$AR\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_AR=\"$ac_tool_prefix$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nAR=$ac_cv_prog_AR\nif test -n \"$AR\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $AR\" >&5\n$as_echo \"$AR\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n    test -n \"$AR\" && break\n  done\nfi\nif test -z \"$AR\"; then\n  ac_ct_AR=$AR\n  for ac_prog in ar gar\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_ac_ct_AR+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_AR\"; then\n  ac_cv_prog_ac_ct_AR=\"$ac_ct_AR\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_ac_ct_AR=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_AR=$ac_cv_prog_ac_ct_AR\nif test -n \"$ac_ct_AR\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR\" >&5\n$as_echo \"$ac_ct_AR\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$ac_ct_AR\" && break\ndone\n\n  if test \"x$ac_ct_AR\" = x; then\n    AR=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    AR=$ac_ct_AR\n  fi\nfi\n\n\nif test \"$AR_FLAGS\" = \"\"; then AR_FLAGS=\"rv\"; fi\n\nif test \"$LD\" = \"\"; then LD=\"$CC\"; fi\n\nif test \"$LDOUT\" = \"\"; then LDOUT=\"-o \"; fi\n\nif test \"$OBJEXT\" = \"\"; then OBJEXT='o'; fi\n\nif test \"$LIBEXT\" = \"\"; then LIBEXT='a'; fi\n\nif test \"$LIBEXT2\" = \"\"; then LIBEXT2=\"\"; fi\n\nif test \"$CC_OUT\" = \"\"; then CC_OUT=\"-o \"; fi\n\nif test \"$CC_INC\" = \"\"; then CC_INC=\"-I\"; fi\n\nif test \"$CC_DEF\" = \"\"; then CC_DEF=\"-D\"; fi\n\nif test \"$CC_OPTIMIZE\" = \"\"; then CC_OPTIMIZE=\"-O2\"; fi\n\nif test \"$CC_CFLAGS\" = \"\"; then CC_CFLAGS=\"-Wall\"; fi\n\n\n\n\n\n\n\ncase $host in\n    *mingw* | *cygw* | *win32* | *w32* )\n\tif pwd -W 2&> /dev/null; then\n\t   ac_pjdir=`pwd -W`\n\telse\n\t   # We're probably cross-compiling mingw on Linux\n\t   ac_pjdir=`pwd`\n\tfi\n\t;;\n    *)\n\tac_pjdir=`pwd`\n\t;;\nesac\n\n\ncase $target in\n    *mingw* | *cygw* | *win32* | *w32* )\n\tac_shlib_suffix=dll\n\t;;\n    *darwin*)\n\tac_shlib_suffix=dylib\n\t;;\n    *)\n\tac_shlib_suffix=so\n\t;;\nesac\n\n\nif test \"$build\" = \"$host\"; then\n    ac_cross_compile=\nelse\n    ac_cross_compile=${host_orig}-\nfi\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread\" >&5\n$as_echo_n \"checking for pthread_create in -lpthread... \" >&6; }\nif ${ac_cv_lib_pthread_pthread_create+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lpthread  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar pthread_create ();\nint\nmain ()\n{\nreturn pthread_create ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_pthread_pthread_create=yes\nelse\n  ac_cv_lib_pthread_pthread_create=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create\" >&5\n$as_echo \"$ac_cv_lib_pthread_pthread_create\" >&6; }\nif test \"x$ac_cv_lib_pthread_pthread_create\" = xyes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBPTHREAD 1\n_ACEOF\n\n  LIBS=\"-lpthread $LIBS\"\n\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for puts in -lwsock32\" >&5\n$as_echo_n \"checking for puts in -lwsock32... \" >&6; }\nif ${ac_cv_lib_wsock32_puts+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lwsock32  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar puts ();\nint\nmain ()\n{\nreturn puts ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_wsock32_puts=yes\nelse\n  ac_cv_lib_wsock32_puts=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wsock32_puts\" >&5\n$as_echo \"$ac_cv_lib_wsock32_puts\" >&6; }\nif test \"x$ac_cv_lib_wsock32_puts\" = xyes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBWSOCK32 1\n_ACEOF\n\n  LIBS=\"-lwsock32 $LIBS\"\n\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for puts in -lws2_32\" >&5\n$as_echo_n \"checking for puts in -lws2_32... \" >&6; }\nif ${ac_cv_lib_ws2_32_puts+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lws2_32  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar puts ();\nint\nmain ()\n{\nreturn puts ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_ws2_32_puts=yes\nelse\n  ac_cv_lib_ws2_32_puts=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_puts\" >&5\n$as_echo \"$ac_cv_lib_ws2_32_puts\" >&6; }\nif test \"x$ac_cv_lib_ws2_32_puts\" = xyes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBWS2_32 1\n_ACEOF\n\n  LIBS=\"-lws2_32 $LIBS\"\n\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for puts in -lole32\" >&5\n$as_echo_n \"checking for puts in -lole32... \" >&6; }\nif ${ac_cv_lib_ole32_puts+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lole32  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar puts ();\nint\nmain ()\n{\nreturn puts ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_ole32_puts=yes\nelse\n  ac_cv_lib_ole32_puts=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ole32_puts\" >&5\n$as_echo \"$ac_cv_lib_ole32_puts\" >&6; }\nif test \"x$ac_cv_lib_ole32_puts\" = xyes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBOLE32 1\n_ACEOF\n\n  LIBS=\"-lole32 $LIBS\"\n\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for puts in -lwinmm\" >&5\n$as_echo_n \"checking for puts in -lwinmm... \" >&6; }\nif ${ac_cv_lib_winmm_puts+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lwinmm  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar puts ();\nint\nmain ()\n{\nreturn puts ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_winmm_puts=yes\nelse\n  ac_cv_lib_winmm_puts=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_winmm_puts\" >&5\n$as_echo \"$ac_cv_lib_winmm_puts\" >&6; }\nif test \"x$ac_cv_lib_winmm_puts\" = xyes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBWINMM 1\n_ACEOF\n\n  LIBS=\"-lwinmm $LIBS\"\n\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for puts in -lsocket\" >&5\n$as_echo_n \"checking for puts in -lsocket... \" >&6; }\nif ${ac_cv_lib_socket_puts+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lsocket  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar puts ();\nint\nmain ()\n{\nreturn puts ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_socket_puts=yes\nelse\n  ac_cv_lib_socket_puts=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_puts\" >&5\n$as_echo \"$ac_cv_lib_socket_puts\" >&6; }\nif test \"x$ac_cv_lib_socket_puts\" = xyes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBSOCKET 1\n_ACEOF\n\n  LIBS=\"-lsocket $LIBS\"\n\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for puts in -lrt\" >&5\n$as_echo_n \"checking for puts in -lrt... \" >&6; }\nif ${ac_cv_lib_rt_puts+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lrt  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar puts ();\nint\nmain ()\n{\nreturn puts ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_rt_puts=yes\nelse\n  ac_cv_lib_rt_puts=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_puts\" >&5\n$as_echo \"$ac_cv_lib_rt_puts\" >&6; }\nif test \"x$ac_cv_lib_rt_puts\" = xyes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBRT 1\n_ACEOF\n\n  LIBS=\"-lrt $LIBS\"\n\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for sin in -lm\" >&5\n$as_echo_n \"checking for sin in -lm... \" >&6; }\nif ${ac_cv_lib_m_sin+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lm  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar sin ();\nint\nmain ()\n{\nreturn sin ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_m_sin=yes\nelse\n  ac_cv_lib_m_sin=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sin\" >&5\n$as_echo \"$ac_cv_lib_m_sin\" >&6; }\nif test \"x$ac_cv_lib_m_sin\" = xyes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBM 1\n_ACEOF\n\n  LIBS=\"-lm $LIBS\"\n\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for uuid_generate in -luuid\" >&5\n$as_echo_n \"checking for uuid_generate in -luuid... \" >&6; }\nif ${ac_cv_lib_uuid_uuid_generate+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-luuid  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar uuid_generate ();\nint\nmain ()\n{\nreturn uuid_generate ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_uuid_uuid_generate=yes\nelse\n  ac_cv_lib_uuid_uuid_generate=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate\" >&5\n$as_echo \"$ac_cv_lib_uuid_uuid_generate\" >&6; }\nif test \"x$ac_cv_lib_uuid_uuid_generate\" = xyes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBUUID 1\n_ACEOF\n\n  LIBS=\"-luuid $LIBS\"\n\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for uuid_generate in -luuid\" >&5\n$as_echo_n \"checking for uuid_generate in -luuid... \" >&6; }\nif ${ac_cv_lib_uuid_uuid_generate+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-luuid  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar uuid_generate ();\nint\nmain ()\n{\nreturn uuid_generate ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_uuid_uuid_generate=yes\nelse\n  ac_cv_lib_uuid_uuid_generate=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate\" >&5\n$as_echo \"$ac_cv_lib_uuid_uuid_generate\" >&6; }\nif test \"x$ac_cv_lib_uuid_uuid_generate\" = xyes; then :\n  ac_has_uuid_lib=1\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname\" >&5\n$as_echo_n \"checking for library containing gethostbyname... \" >&6; }\nif ${ac_cv_search_gethostbyname+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_func_search_save_LIBS=$LIBS\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar gethostbyname ();\nint\nmain ()\n{\nreturn gethostbyname ();\n  ;\n  return 0;\n}\n_ACEOF\nfor ac_lib in '' nsl; do\n  if test -z \"$ac_lib\"; then\n    ac_res=\"none required\"\n  else\n    ac_res=-l$ac_lib\n    LIBS=\"-l$ac_lib  $ac_func_search_save_LIBS\"\n  fi\n  if ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_search_gethostbyname=$ac_res\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext\n  if ${ac_cv_search_gethostbyname+:} false; then :\n  break\nfi\ndone\nif ${ac_cv_search_gethostbyname+:} false; then :\n\nelse\n  ac_cv_search_gethostbyname=no\nfi\nrm conftest.$ac_ext\nLIBS=$ac_func_search_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname\" >&5\n$as_echo \"$ac_cv_search_gethostbyname\" >&6; }\nac_res=$ac_cv_search_gethostbyname\nif test \"$ac_res\" != no; then :\n  test \"$ac_res\" = \"none required\" || LIBS=\"$ac_res $LIBS\"\n\nfi\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Setting PJ_M_NAME to $target_cpu\" >&5\n$as_echo \"Setting PJ_M_NAME to $target_cpu\" >&6; }\ncat >>confdefs.h <<_ACEOF\n#define PJ_M_NAME \"$target_cpu\"\n_ACEOF\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking memory alignment\" >&5\n$as_echo_n \"checking memory alignment... \" >&6; }\ncase $target in\n    sparc64-* | ia64-* | x86_64-* )\n\t$as_echo \"#define PJ_POOL_ALIGNMENT 8\" >>confdefs.h\n\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: 8 bytes\" >&5\n$as_echo \"8 bytes\" >&6; }\n\t;;\n    * )\n\t$as_echo \"#define PJ_POOL_ALIGNMENT 4\" >>confdefs.h\n\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: 4 bytes (default)\" >&5\n$as_echo \"4 bytes (default)\" >&6; }\n\t;;\nesac\n\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor\" >&5\n$as_echo_n \"checking how to run the C preprocessor... \" >&6; }\n# On Suns, sometimes $CPP names a directory.\nif test -n \"$CPP\" && test -d \"$CPP\"; then\n  CPP=\nfi\nif test -z \"$CPP\"; then\n  if ${ac_cv_prog_CPP+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n      # Double quotes because CPP needs to be expanded\n    for CPP in \"$CC -E\" \"$CC -E -traditional-cpp\" \"/lib/cpp\"\n    do\n      ac_preproc_ok=false\nfor ac_c_preproc_warn_flag in '' yes\ndo\n  # Use a header file that comes with gcc, so configuring glibc\n  # with a fresh cross-compiler works.\n  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n  # <limits.h> exists even on freestanding compilers.\n  # On the NeXT, cc -E runs the code through the compiler's parser,\n  # not just through cpp. \"Syntax error\" is here to catch this case.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\t\t     Syntax error\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n\nelse\n  # Broken: fails on valid input.\ncontinue\nfi\nrm -f conftest.err conftest.i conftest.$ac_ext\n\n  # OK, works on sane cases.  Now check whether nonexistent headers\n  # can be detected and how.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ac_nonexistent.h>\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n  # Broken: success on invalid input.\ncontinue\nelse\n  # Passes both tests.\nac_preproc_ok=:\nbreak\nfi\nrm -f conftest.err conftest.i conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.i conftest.err conftest.$ac_ext\nif $ac_preproc_ok; then :\n  break\nfi\n\n    done\n    ac_cv_prog_CPP=$CPP\n\nfi\n  CPP=$ac_cv_prog_CPP\nelse\n  ac_cv_prog_CPP=$CPP\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CPP\" >&5\n$as_echo \"$CPP\" >&6; }\nac_preproc_ok=false\nfor ac_c_preproc_warn_flag in '' yes\ndo\n  # Use a header file that comes with gcc, so configuring glibc\n  # with a fresh cross-compiler works.\n  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n  # <limits.h> exists even on freestanding compilers.\n  # On the NeXT, cc -E runs the code through the compiler's parser,\n  # not just through cpp. \"Syntax error\" is here to catch this case.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\t\t     Syntax error\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n\nelse\n  # Broken: fails on valid input.\ncontinue\nfi\nrm -f conftest.err conftest.i conftest.$ac_ext\n\n  # OK, works on sane cases.  Now check whether nonexistent headers\n  # can be detected and how.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ac_nonexistent.h>\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n  # Broken: success on invalid input.\ncontinue\nelse\n  # Passes both tests.\nac_preproc_ok=:\nbreak\nfi\nrm -f conftest.err conftest.i conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.i conftest.err conftest.$ac_ext\nif $ac_preproc_ok; then :\n\nelse\n  { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error $? \"C preprocessor \\\"$CPP\\\" fails sanity check\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e\" >&5\n$as_echo_n \"checking for grep that handles long lines and -e... \" >&6; }\nif ${ac_cv_path_GREP+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -z \"$GREP\"; then\n  ac_path_GREP_found=false\n  # Loop through the user's path and test for each of PROGNAME-LIST\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in grep ggrep; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      ac_path_GREP=\"$as_dir/$ac_prog$ac_exec_ext\"\n      as_fn_executable_p \"$ac_path_GREP\" || continue\n# Check for GNU ac_path_GREP and select it if it is found.\n  # Check for GNU $ac_path_GREP\ncase `\"$ac_path_GREP\" --version 2>&1` in\n*GNU*)\n  ac_cv_path_GREP=\"$ac_path_GREP\" ac_path_GREP_found=:;;\n*)\n  ac_count=0\n  $as_echo_n 0123456789 >\"conftest.in\"\n  while :\n  do\n    cat \"conftest.in\" \"conftest.in\" >\"conftest.tmp\"\n    mv \"conftest.tmp\" \"conftest.in\"\n    cp \"conftest.in\" \"conftest.nl\"\n    $as_echo 'GREP' >> \"conftest.nl\"\n    \"$ac_path_GREP\" -e 'GREP$' -e '-(cannot match)-' < \"conftest.nl\" >\"conftest.out\" 2>/dev/null || break\n    diff \"conftest.out\" \"conftest.nl\" >/dev/null 2>&1 || break\n    as_fn_arith $ac_count + 1 && ac_count=$as_val\n    if test $ac_count -gt ${ac_path_GREP_max-0}; then\n      # Best one so far, save it but keep looking for a better one\n      ac_cv_path_GREP=\"$ac_path_GREP\"\n      ac_path_GREP_max=$ac_count\n    fi\n    # 10*(2^10) chars as input seems more than enough\n    test $ac_count -gt 10 && break\n  done\n  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;\nesac\n\n      $ac_path_GREP_found && break 3\n    done\n  done\n  done\nIFS=$as_save_IFS\n  if test -z \"$ac_cv_path_GREP\"; then\n    as_fn_error $? \"no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin\" \"$LINENO\" 5\n  fi\nelse\n  ac_cv_path_GREP=$GREP\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP\" >&5\n$as_echo \"$ac_cv_path_GREP\" >&6; }\n GREP=\"$ac_cv_path_GREP\"\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for egrep\" >&5\n$as_echo_n \"checking for egrep... \" >&6; }\nif ${ac_cv_path_EGREP+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1\n   then ac_cv_path_EGREP=\"$GREP -E\"\n   else\n     if test -z \"$EGREP\"; then\n  ac_path_EGREP_found=false\n  # Loop through the user's path and test for each of PROGNAME-LIST\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in egrep; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      ac_path_EGREP=\"$as_dir/$ac_prog$ac_exec_ext\"\n      as_fn_executable_p \"$ac_path_EGREP\" || continue\n# Check for GNU ac_path_EGREP and select it if it is found.\n  # Check for GNU $ac_path_EGREP\ncase `\"$ac_path_EGREP\" --version 2>&1` in\n*GNU*)\n  ac_cv_path_EGREP=\"$ac_path_EGREP\" ac_path_EGREP_found=:;;\n*)\n  ac_count=0\n  $as_echo_n 0123456789 >\"conftest.in\"\n  while :\n  do\n    cat \"conftest.in\" \"conftest.in\" >\"conftest.tmp\"\n    mv \"conftest.tmp\" \"conftest.in\"\n    cp \"conftest.in\" \"conftest.nl\"\n    $as_echo 'EGREP' >> \"conftest.nl\"\n    \"$ac_path_EGREP\" 'EGREP$' < \"conftest.nl\" >\"conftest.out\" 2>/dev/null || break\n    diff \"conftest.out\" \"conftest.nl\" >/dev/null 2>&1 || break\n    as_fn_arith $ac_count + 1 && ac_count=$as_val\n    if test $ac_count -gt ${ac_path_EGREP_max-0}; then\n      # Best one so far, save it but keep looking for a better one\n      ac_cv_path_EGREP=\"$ac_path_EGREP\"\n      ac_path_EGREP_max=$ac_count\n    fi\n    # 10*(2^10) chars as input seems more than enough\n    test $ac_count -gt 10 && break\n  done\n  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;\nesac\n\n      $ac_path_EGREP_found && break 3\n    done\n  done\n  done\nIFS=$as_save_IFS\n  if test -z \"$ac_cv_path_EGREP\"; then\n    as_fn_error $? \"no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin\" \"$LINENO\" 5\n  fi\nelse\n  ac_cv_path_EGREP=$EGREP\nfi\n\n   fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP\" >&5\n$as_echo \"$ac_cv_path_EGREP\" >&6; }\n EGREP=\"$ac_cv_path_EGREP\"\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for ANSI C header files\" >&5\n$as_echo_n \"checking for ANSI C header files... \" >&6; }\nif ${ac_cv_header_stdc+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdlib.h>\n#include <stdarg.h>\n#include <string.h>\n#include <float.h>\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_header_stdc=yes\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\nif test $ac_cv_header_stdc = yes; then\n  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <string.h>\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"memchr\" >/dev/null 2>&1; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f conftest*\n\nfi\n\nif test $ac_cv_header_stdc = yes; then\n  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdlib.h>\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"free\" >/dev/null 2>&1; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f conftest*\n\nfi\n\nif test $ac_cv_header_stdc = yes; then\n  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.\n  if test \"$cross_compiling\" = yes; then :\n  :\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ctype.h>\n#include <stdlib.h>\n#if ((' ' & 0x0FF) == 0x020)\n# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')\n# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))\n#else\n# define ISLOWER(c) \\\n\t\t   (('a' <= (c) && (c) <= 'i') \\\n\t\t     || ('j' <= (c) && (c) <= 'r') \\\n\t\t     || ('s' <= (c) && (c) <= 'z'))\n# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))\n#endif\n\n#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))\nint\nmain ()\n{\n  int i;\n  for (i = 0; i < 256; i++)\n    if (XOR (islower (i), ISLOWER (i))\n\t|| toupper (i) != TOUPPER (i))\n      return 2;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_run \"$LINENO\"; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \\\n  conftest.$ac_objext conftest.beam conftest.$ac_ext\nfi\n\nfi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc\" >&5\n$as_echo \"$ac_cv_header_stdc\" >&6; }\nif test $ac_cv_header_stdc = yes; then\n\n$as_echo \"#define STDC_HEADERS 1\" >>confdefs.h\n\nfi\n\n# On IRIX 5.3, sys/types and inttypes.h are conflicting.\nfor ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \\\n\t\t  inttypes.h stdint.h unistd.h\ndo :\n  as_ac_Header=`$as_echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nac_fn_c_check_header_compile \"$LINENO\" \"$ac_header\" \"$as_ac_Header\" \"$ac_includes_default\n\"\nif eval test \\\"x\\$\"$as_ac_Header\"\\\" = x\"yes\"; then :\n  cat >>confdefs.h <<_ACEOF\n#define `$as_echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\n { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian\" >&5\n$as_echo_n \"checking whether byte ordering is bigendian... \" >&6; }\nif ${ac_cv_c_bigendian+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_cv_c_bigendian=unknown\n    # See if we're dealing with a universal compiler.\n    cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#ifndef __APPLE_CC__\n\t       not a universal capable compiler\n\t     #endif\n\t     typedef int dummy;\n\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n\n\t# Check for potential -arch flags.  It is not universal unless\n\t# there are at least two -arch flags with different values.\n\tac_arch=\n\tac_prev=\n\tfor ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do\n\t if test -n \"$ac_prev\"; then\n\t   case $ac_word in\n\t     i?86 | x86_64 | ppc | ppc64)\n\t       if test -z \"$ac_arch\" || test \"$ac_arch\" = \"$ac_word\"; then\n\t\t ac_arch=$ac_word\n\t       else\n\t\t ac_cv_c_bigendian=universal\n\t\t break\n\t       fi\n\t       ;;\n\t   esac\n\t   ac_prev=\n\t elif test \"x$ac_word\" = \"x-arch\"; then\n\t   ac_prev=arch\n\t fi\n       done\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n    if test $ac_cv_c_bigendian = unknown; then\n      # See if sys/param.h defines the BYTE_ORDER macro.\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <sys/types.h>\n\t     #include <sys/param.h>\n\nint\nmain ()\n{\n#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \\\n\t\t     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \\\n\t\t     && LITTLE_ENDIAN)\n\t      bogus endian macros\n\t     #endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  # It does; now see whether it defined to BIG_ENDIAN or not.\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <sys/types.h>\n\t\t#include <sys/param.h>\n\nint\nmain ()\n{\n#if BYTE_ORDER != BIG_ENDIAN\n\t\t not big endian\n\t\t#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_c_bigendian=yes\nelse\n  ac_cv_c_bigendian=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n    fi\n    if test $ac_cv_c_bigendian = unknown; then\n      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <limits.h>\n\nint\nmain ()\n{\n#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)\n\t      bogus endian macros\n\t     #endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  # It does; now see whether it defined to _BIG_ENDIAN or not.\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <limits.h>\n\nint\nmain ()\n{\n#ifndef _BIG_ENDIAN\n\t\t not big endian\n\t\t#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_c_bigendian=yes\nelse\n  ac_cv_c_bigendian=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n    fi\n    if test $ac_cv_c_bigendian = unknown; then\n      # Compile a test program.\n      if test \"$cross_compiling\" = yes; then :\n  # Try to guess by grepping values from an object file.\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\nshort int ascii_mm[] =\n\t\t  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };\n\t\tshort int ascii_ii[] =\n\t\t  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };\n\t\tint use_ascii (int i) {\n\t\t  return ascii_mm[i] + ascii_ii[i];\n\t\t}\n\t\tshort int ebcdic_ii[] =\n\t\t  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };\n\t\tshort int ebcdic_mm[] =\n\t\t  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };\n\t\tint use_ebcdic (int i) {\n\t\t  return ebcdic_mm[i] + ebcdic_ii[i];\n\t\t}\n\t\textern int foo;\n\nint\nmain ()\n{\nreturn use_ascii (foo) == use_ebcdic (foo);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then\n\t      ac_cv_c_bigendian=yes\n\t    fi\n\t    if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then\n\t      if test \"$ac_cv_c_bigendian\" = unknown; then\n\t\tac_cv_c_bigendian=no\n\t      else\n\t\t# finding both strings is unlikely to happen, but who knows?\n\t\tac_cv_c_bigendian=unknown\n\t      fi\n\t    fi\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\n\n\t     /* Are we little or big endian?  From Harbison&Steele.  */\n\t     union\n\t     {\n\t       long int l;\n\t       char c[sizeof (long int)];\n\t     } u;\n\t     u.l = 1;\n\t     return u.c[sizeof (long int) - 1] == 1;\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_run \"$LINENO\"; then :\n  ac_cv_c_bigendian=no\nelse\n  ac_cv_c_bigendian=yes\nfi\nrm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \\\n  conftest.$ac_objext conftest.beam conftest.$ac_ext\nfi\n\n    fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian\" >&5\n$as_echo \"$ac_cv_c_bigendian\" >&6; }\n case $ac_cv_c_bigendian in #(\n   yes)\n     $as_echo \"#define WORDS_BIGENDIAN 1\" >>confdefs.h\n;; #(\n   no)\n      ;; #(\n   universal)\n\n$as_echo \"#define AC_APPLE_UNIVERSAL_BUILD 1\" >>confdefs.h\n\n     ;; #(\n   *)\n     as_fn_error $? \"unknown endianness\n presetting ac_cv_c_bigendian=no (or yes) will help\" \"$LINENO\" 5 ;;\n esac\n\n\nif test \"x$ac_cv_c_bigendian\" = \"xyes\"; then\n  CFLAGS=\"$CFLAGS -DPJ_IS_BIG_ENDIAN=1 -DPJ_IS_LITTLE_ENDIAN=0\"\nelse\n  CFLAGS=\"$CFLAGS -DPJ_IS_BIG_ENDIAN=0 -DPJ_IS_LITTLE_ENDIAN=1\"\nfi\n\ncase $target in\n    *android*)\n\t$as_echo \"#define PJ_ANDROID 1\" >>confdefs.h\n\n\t;;\n    *mingw* | *cygw* | *win32* | *w32* )\n\t$as_echo \"#define PJ_WIN32 1\" >>confdefs.h\n\n\t$as_echo \"#define PJ_WIN32_WINNT 0x0400\" >>confdefs.h\n\n\t$as_echo \"#define WIN32_LEAN_AND_MEAN 1\" >>confdefs.h\n\n\t;;\n    *darwin*)\n\t$as_echo \"#define PJ_DARWINOS 1\" >>confdefs.h\n\n\t;;\n    *linux*)\n\t$as_echo \"#define PJ_LINUX 1\" >>confdefs.h\n\n\t;;\n    *rtems*)\n\t$as_echo \"#define PJ_RTEMS 1\" >>confdefs.h\n\n\t;;\n    *sunos* | *solaris* )\n\t$as_echo \"#define PJ_SUNOS 1\" >>confdefs.h\n\n\t;;\n    *)\n\t;;\nesac\n\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"arpa/inet.h\" \"ac_cv_header_arpa_inet_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_arpa_inet_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_ARPA_INET_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"assert.h\" \"ac_cv_header_assert_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_assert_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_ASSERT_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"ctype.h\" \"ac_cv_header_ctype_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_ctype_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_CTYPE_H 1\" >>confdefs.h\n\nfi\n\n\n\ncase $target in\n    *mingw* | *cygw* | *win32* | *w32* )\n\t$as_echo \"#define PJ_HAS_ERRNO_H 0\" >>confdefs.h\n\n\t;;\n    *)\n\tac_fn_c_check_header_mongrel \"$LINENO\" \"errno.h\" \"ac_cv_header_errno_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_errno_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_ERRNO_H 1\" >>confdefs.h\n\nfi\n\n\n\t;;\nesac\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"fcntl.h\" \"ac_cv_header_fcntl_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_fcntl_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_FCNTL_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"linux/socket.h\" \"ac_cv_header_linux_socket_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_linux_socket_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_LINUX_SOCKET_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"limits.h\" \"ac_cv_header_limits_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_limits_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_LIMITS_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"malloc.h\" \"ac_cv_header_malloc_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_malloc_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_MALLOC_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"netdb.h\" \"ac_cv_header_netdb_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_netdb_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_NETDB_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"netinet/in_systm.h\" \"ac_cv_header_netinet_in_systm_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_netinet_in_systm_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_NETINET_IN_SYSTM_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"netinet/in.h\" \"ac_cv_header_netinet_in_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_netinet_in_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_NETINET_IN_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_compile \"$LINENO\" \"netinet/ip.h\" \"ac_cv_header_netinet_ip_h\" \"#if PJ_HAS_SYS_TYPES_H\n          \t  #\tinclude <sys/types.h>\n          \t  #endif\n\t\t  #if PJ_HAS_NETINET_IN_SYSTM_H\n          \t  #\tinclude <netinet/in_systm.h>\n          \t  #endif\n\t\t  #if PJ_HAS_NETINET_IN_H\n          \t  #\tinclude <netinet/in.h>\n          \t  #endif\n\n\"\nif test \"x$ac_cv_header_netinet_ip_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_NETINET_IP_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"netinet/tcp.h\" \"ac_cv_header_netinet_tcp_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_netinet_tcp_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_NETINET_TCP_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"ifaddrs.h\" \"ac_cv_header_ifaddrs_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_ifaddrs_h\" = xyes; then :\n  ac_fn_c_check_func \"$LINENO\" \"getifaddrs\" \"ac_cv_func_getifaddrs\"\nif test \"x$ac_cv_func_getifaddrs\" = xyes; then :\n  $as_echo \"#define PJ_HAS_IFADDRS_H 1\" >>confdefs.h\n\nfi\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"semaphore.h\" \"ac_cv_header_semaphore_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_semaphore_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_SEMAPHORE_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"setjmp.h\" \"ac_cv_header_setjmp_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_setjmp_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_SETJMP_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"stdarg.h\" \"ac_cv_header_stdarg_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_stdarg_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_STDARG_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"stddef.h\" \"ac_cv_header_stddef_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_stddef_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_STDDEF_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"stdio.h\" \"ac_cv_header_stdio_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_stdio_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_STDIO_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"stdint.h\" \"ac_cv_header_stdint_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_stdint_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_STDINT_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"stdlib.h\" \"ac_cv_header_stdlib_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_stdlib_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_STDLIB_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"string.h\" \"ac_cv_header_string_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_string_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_STRING_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"sys/ioctl.h\" \"ac_cv_header_sys_ioctl_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_ioctl_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_SYS_IOCTL_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"sys/select.h\" \"ac_cv_header_sys_select_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_select_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_SYS_SELECT_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"sys/socket.h\" \"ac_cv_header_sys_socket_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_socket_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_SYS_SOCKET_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"sys/time.h\" \"ac_cv_header_sys_time_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_time_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_SYS_TIME_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"sys/timeb.h\" \"ac_cv_header_sys_timeb_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_timeb_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_SYS_TIMEB_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"sys/types.h\" \"ac_cv_header_sys_types_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_types_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_SYS_TYPES_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"sys/filio.h\" \"ac_cv_header_sys_filio_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_filio_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_SYS_FILIO_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"sys/sockio.h\" \"ac_cv_header_sys_sockio_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_sockio_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_SYS_SOCKIO_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"sys/utsname.h\" \"ac_cv_header_sys_utsname_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_utsname_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_SYS_UTSNAME_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"time.h\" \"ac_cv_header_time_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_time_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_TIME_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"unistd.h\" \"ac_cv_header_unistd_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_unistd_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_UNISTD_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"winsock.h\" \"ac_cv_header_winsock_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_winsock_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_WINSOCK_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"winsock2.h\" \"ac_cv_header_winsock2_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_winsock2_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_WINSOCK2_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_compile \"$LINENO\" \"mswsock.h\" \"ac_cv_header_mswsock_h\" \"#if PJ_HAS_WINSOCK2_H\n          \t  #\tinclude <winsock2.h>\n\t\t  #elif PJ_HAS_WINSOCK_H\n          \t  #\tinclude <winsock.h>\n          \t  #endif\n\n\"\nif test \"x$ac_cv_header_mswsock_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_MSWSOCK_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"ws2tcpip.h\" \"ac_cv_header_ws2tcpip_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_ws2tcpip_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_WS2TCPIP_H 1\" >>confdefs.h\n\nfi\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"uuid/uuid.h\" \"ac_cv_header_uuid_uuid_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_uuid_uuid_h\" = xyes; then :\n  ac_has_uuid_h=1\nfi\n\n\nac_fn_c_check_header_compile \"$LINENO\" \"net/if.h\" \"ac_cv_header_net_if_h\" \"#if PJ_HAS_SYS_TYPES_H\n          \t  #\tinclude <sys/types.h>\n          \t  #endif\n\t\t  #if PJ_HAS_SYS_SOCKET_H\n\n          \t  #\tinclude <sys/socket.h>\n          \t  #endif\n\n\"\nif test \"x$ac_cv_header_net_if_h\" = xyes; then :\n  $as_echo \"#define PJ_HAS_NET_IF_H 1\" >>confdefs.h\n\nfi\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Setting PJ_OS_NAME to $target\" >&5\n$as_echo \"Setting PJ_OS_NAME to $target\" >&6; }\ncat >>confdefs.h <<_ACEOF\n#define PJ_OS_NAME \"$target\"\n_ACEOF\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Setting PJ_HAS_ERRNO_VAR to 1\" >&5\n$as_echo \"Setting PJ_HAS_ERRNO_VAR to 1\" >&6; }\n$as_echo \"#define PJ_HAS_ERRNO_VAR 1\" >>confdefs.h\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Setting PJ_HAS_HIGH_RES_TIMER to 1\" >&5\n$as_echo \"Setting PJ_HAS_HIGH_RES_TIMER to 1\" >&6; }\n$as_echo \"#define PJ_HAS_HIGH_RES_TIMER 1\" >>confdefs.h\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Setting PJ_HAS_MALLOC to 1\" >&5\n$as_echo \"Setting PJ_HAS_MALLOC to 1\" >&6; }\n$as_echo \"#define PJ_HAS_MALLOC 1\" >>confdefs.h\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Setting PJ_NATIVE_STRING_IS_UNICODE to 0\" >&5\n$as_echo \"Setting PJ_NATIVE_STRING_IS_UNICODE to 0\" >&6; }\n$as_echo \"#define PJ_NATIVE_STRING_IS_UNICODE 0\" >>confdefs.h\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Setting PJ_ATOMIC_VALUE_TYPE to long\" >&5\n$as_echo \"Setting PJ_ATOMIC_VALUE_TYPE to long\" >&6; }\n$as_echo \"#define PJ_ATOMIC_VALUE_TYPE long\" >>confdefs.h\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if inet_aton() is available\" >&5\n$as_echo_n \"checking if inet_aton() is available... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <sys/types.h>\n\t\t\t\t     #include <sys/socket.h>\n\t\t\t\t     #include <arpa/inet.h>\nint\nmain ()\n{\ninet_aton(0, 0);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  $as_echo \"#define PJ_SOCK_HAS_INET_ATON 1\" >>confdefs.h\n\n\t\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if inet_pton() is available\" >&5\n$as_echo_n \"checking if inet_pton() is available... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <sys/types.h>\n\t\t\t\t     #include <sys/socket.h>\n\t\t\t\t     #include <arpa/inet.h>\nint\nmain ()\n{\ninet_pton(0, 0, 0);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  $as_echo \"#define PJ_SOCK_HAS_INET_PTON 1\" >>confdefs.h\n\n\t\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if inet_ntop() is available\" >&5\n$as_echo_n \"checking if inet_ntop() is available... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <sys/types.h>\n\t\t\t\t     #include <sys/socket.h>\n\t\t\t\t     #include <arpa/inet.h>\nint\nmain ()\n{\ninet_ntop(0, 0, 0, 0);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  $as_echo \"#define PJ_SOCK_HAS_INET_NTOP 1\" >>confdefs.h\n\n\t\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if getaddrinfo() is available\" >&5\n$as_echo_n \"checking if getaddrinfo() is available... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <sys/types.h>\n\t\t\t\t     #include <sys/socket.h>\n\t\t\t\t     #include <netdb.h>\nint\nmain ()\n{\ngetaddrinfo(0, 0, 0, 0);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  $as_echo \"#define PJ_SOCK_HAS_GETADDRINFO 1\" >>confdefs.h\n\n\t\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if sockaddr_in has sin_len member\" >&5\n$as_echo_n \"checking if sockaddr_in has sin_len member... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <sys/types.h>\n\t\t\t\t     #include <sys/socket.h>\n\t\t    \t\t     #include <netinet/in.h>\n\t\t    \t\t     #include <arpa/inet.h>\nint\nmain ()\n{\nstruct sockaddr_in a; a.sin_len=0;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  $as_echo \"#define PJ_SOCKADDR_HAS_LEN 1\" >>confdefs.h\n\n\t\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if socklen_t is available\" >&5\n$as_echo_n \"checking if socklen_t is available... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <sys/types.h>\n                                     #include <sys/socket.h>\nint\nmain ()\n{\nsocklen_t xxx = 0;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  $as_echo \"#define PJ_HAS_SOCKLEN_T 1\" >>confdefs.h\n\n\t\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if SO_ERROR is available\" >&5\n$as_echo_n \"checking if SO_ERROR is available... \" >&6; }\ncase $target in\n    *mingw* | *cygw* | *win32* | *w32* )\n\t$as_echo \"#define PJ_HAS_SO_ERROR 1\" >>confdefs.h\n\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\t;;\n    *)\n\tcat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <sys/types.h>\n\t\t\t\t\t     #include <sys/socket.h>\n\t\t\t\t\t     #include <netinet/in.h>\n\t\t\t\t\t     #include <arpa/inet.h>\nint\nmain ()\n{\nint i=SO_ERROR;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  $as_echo \"#define PJ_HAS_SO_ERROR 1\" >>confdefs.h\n\n\t\t\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\t;;\nesac\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if pthread_rwlock_t is available\" >&5\n$as_echo_n \"checking if pthread_rwlock_t is available... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <pthread.h>\nint\nmain ()\n{\npthread_rwlock_t *x;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  $as_echo \"#define PJ_EMULATE_RWMUTEX 0\" >>confdefs.h\n\n\t\t   ac_rwmutex=\"yes\"\n  \t\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  $as_echo \"#define PJ_EMULATE_RWMUTEX 1\" >>confdefs.h\n\n\t\t   ac_rwmutex=\"no\"\n\t\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\nif test \"$ac_rwmutex\" = \"no\"; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if pthread_rwlock_t is available with _POSIX_READER_WRITER_LOCKS\" >&5\n$as_echo_n \"checking if pthread_rwlock_t is available with _POSIX_READER_WRITER_LOCKS... \" >&6; }\n    cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#define _POSIX_READER_WRITER_LOCKS\n\t\t\t\t\t #include <pthread.h>\nint\nmain ()\n{\npthread_rwlock_t *x;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  $as_echo \"#define PJ_EMULATE_RWMUTEX 0\" >>confdefs.h\n\n\t\t       CFLAGS=\"$CFLAGS -D_POSIX_THREADS -D_POSIX_READER_WRITER_LOCKS\"\n\t\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  $as_echo \"#define PJ_EMULATE_RWMUTEX 1\" >>confdefs.h\n\n\t\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if pthread_mutexattr_settype() is available\" >&5\n$as_echo_n \"checking if pthread_mutexattr_settype() is available... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <pthread.h>\nint\nmain ()\n{\npthread_mutexattr_settype(0,PTHREAD_MUTEX_FAST_NP);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  $as_echo \"#define PJ_HAS_PTHREAD_MUTEXATTR_SETTYPE 1\" >>confdefs.h\n\n  \t\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if pthread_mutexattr_t has recursive member\" >&5\n$as_echo_n \"checking if pthread_mutexattr_t has recursive member... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <pthread.h>\nint\nmain ()\n{\npthread_mutexattr_t attr;\n\t\t\t\t     attr.recursive=1;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  $as_echo \"#define PJ_PTHREAD_MUTEXATTR_T_HAS_RECURSIVE 1\" >>confdefs.h\n\n  \t\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking ioqueue backend\" >&5\n$as_echo_n \"checking ioqueue backend... \" >&6; }\n# Check whether --enable-epoll was given.\nif test \"${enable_epoll+set}\" = set; then :\n  enableval=$enable_epoll;\n\t\tac_os_objs=ioqueue_epoll.o\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: /dev/epoll\" >&5\n$as_echo \"/dev/epoll\" >&6; }\n\t\t$as_echo \"#define PJ_HAS_LINUX_EPOLL 1\" >>confdefs.h\n\n\t\tac_linux_poll=epoll\n\nelse\n\n\t\tac_os_objs=ioqueue_select.o\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: select()\" >&5\n$as_echo \"select()\" >&6; }\n\t\tac_linux_poll=select\n\nfi\n\n\n\ncase $target in\n  *mingw* | *cygw* | *win32* | *w32* )\n\tac_os_objs=\"$ac_os_objs file_access_win32.o file_io_win32.o os_core_win32.o os_error_win32.o os_time_win32.o os_timestamp_win32.o guid_win32.o\"\n\t;;\n  *)\n\tac_os_objs=\"$ac_os_objs file_access_unistd.o file_io_ansi.o os_core_unix.o os_error_unix.o os_time_unix.o os_timestamp_posix.o\"\n\tcase $target in\n\t  arm-apple-darwin*)\n\t\tac_os_objs=\"$ac_os_objs os_info_iphone.o\"\n\t\t;;\n\tesac\n\t# UUID\n\tif test \"$ac_has_uuid_lib\" = \"1\" -a \"$ac_has_uuid_h\" = \"1\"; then\n\t\tac_os_objs=\"$ac_os_objs guid_uuid.o\"\n\telse\n\t\tac_os_objs=\"$ac_os_objs guid_simple.o\"\n\tfi\n\t;;\nesac\n\ncase $target in\n  *darwin*)\n\tac_os_objs=\"$ac_os_objs os_core_darwin.o\"\n\t;;\nesac\n\n\n\n\ncase $target in\n *android*)\n       LIBS=\"$LIBS -lOpenSLES\"\n       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking sound device backend... OpenSL ES\" >&5\n$as_echo \"Checking sound device backend... OpenSL ES\" >&6; }\n       ;;\n arm-apple-darwin*)\n       LIBS=\"$LIBS -framework CoreAudio -framework CoreFoundation -framework AudioToolbox -framework CFNetwork -framework UIKit\"\n\tac_pjmedia_audiodev_objs=\"coreaudio_dev.o\"\n       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking sound device backend... AudioUnit\" >&5\n$as_echo \"Checking sound device backend... AudioUnit\" >&6; }\n       ;;\n *darwin*)\n       LIBS=\"$LIBS -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox\"\n\tac_pjmedia_audiodev_objs=\"coreaudio_dev.o\"\n       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking sound device backend... CoreAudio\" >&5\n$as_echo \"Checking sound device backend... CoreAudio\" >&6; }\n       ;;\n *cygwin* | *mingw*)\n       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking sound device backend... win32 sound\" >&5\n$as_echo \"Checking sound device backend... win32 sound\" >&6; }\n       ;;\n *rtems*)\n       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking sound device backend... null sound\" >&5\n$as_echo \"Checking sound device backend... null sound\" >&6; }\n       ;;\n *)\n              ac_fn_c_check_header_mongrel \"$LINENO\" \"alsa/version.h\" \"ac_cv_header_alsa_version_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_alsa_version_h\" = xyes; then :\n  LIBS=\"$LIBS -lasound\"\nfi\n\n\n       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking sound device backend... unix\" >&5\n$as_echo \"Checking sound device backend... unix\" >&6; }\n       ;;\nesac\n\n\n\ncase $target in\n *android*)\n\tLIBS=\"$LIBS -llog -lgcc\"\n\t;;\n arm-apple-darwin*)\n \tLIBS=\"$LIBS -framework UIKit\"\n\t;;\n *darwin*)\n \tLIBS=\"$LIBS -framework Foundation -framework AppKit\"\n\t;;\nesac\n\ncase $target in\n arm-apple-darwin*)\n       ac_pjmedia_video=iphone_os\n\n\n       SAVED_LIBS=\"$LIBS\"\n       LIBS=\"-framework AVFoundation -framework CoreGraphics -framework QuartzCore -framework CoreVideo -framework CoreMedia\"\n       cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_pjmedia_video_has_ios=yes\nelse\n  ac_pjmedia_video_has_ios=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n       LIBS=\"$SAVED_LIBS\"\n       if test \"$ac_pjmedia_video_has_ios\" = \"yes\"; then\n         ac_ios_cflags=\"-DPJMEDIA_VIDEO_DEV_HAS_IOS=1 -DPJMEDIA_VIDEO_DEV_HAS_IOS_OPENGL=1\"\n         LIBS=\"$LIBS -framework OpenGLES -framework AVFoundation -framework CoreGraphics -framework QuartzCore -framework CoreVideo -framework CoreMedia\"\n         { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if AVFoundation framework is available... yes\" >&5\n$as_echo \"Checking if AVFoundation framework is available... yes\" >&6; }\n       else\n         { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if AVFoundation framework is available... no\" >&5\n$as_echo \"Checking if AVFoundation framework is available... no\" >&6; }\n       fi\n       ;;\n *darwin*)\n       ac_pjmedia_video=mac_os\n\n\n       SAVED_LIBS=\"$LIBS\"\n       LIBS=\"-framework AVFoundation\"\n       cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_pjmedia_video_has_avf=yes\nelse\n  ac_pjmedia_video_has_avf=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n       LIBS=\"$SAVED_LIBS\"\n       if test \"$ac_pjmedia_video_has_avf\" = \"yes\"; then\n         ac_qt_cflags=\"-DPJMEDIA_VIDEO_DEV_HAS_AVF=1\"\n         LIBS=\"$LIBS -framework AVFoundation -framework QuartzCore\"\n         { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if AVFoundation framework is available... yes\" >&5\n$as_echo \"Checking if AVFoundation framework is available... yes\" >&6; }\n       else\n         { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if AVFoundation framework is available... no\" >&5\n$as_echo \"Checking if AVFoundation framework is available... no\" >&6; }\n       fi\n       ;;\n *cygwin* | *mingw*)\n\n\n\n       cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_pjmedia_video_has_dshow=yes\nelse\n  ac_pjmedia_video_has_dshow=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n       if test \"$ac_pjmedia_video_has_dshow\" = \"yes\"; then\n         ac_dshow_cflags=\"-DPJMEDIA_VIDEO_DEV_HAS_DSHOW=1\"\n         ac_dshow_ldflags=\"-lstrmiids -lrpcrt4 -lquartz -lstrmbase -loleaut32 -lstdc++ -luuid\"\n         LIBS=\"$ac_dshow_ldflags $LIBS\"\n         { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if DirectShow is available... yes\" >&5\n$as_echo \"Checking if DirectShow is available... yes\" >&6; }\n       else\n         { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if DirectShow is available... no\" >&5\n$as_echo \"Checking if DirectShow is available... no\" >&6; }\n       fi\n       ac_android_cflags=\"$ac_android_cflags -DPJMEDIA_VIDEO_DEV_HAS_ANDROID=1\"\n       ;;\nesac\n\n\n\n# Check whether --enable-small-filter was given.\nif test \"${enable_small_filter+set}\" = set; then :\n  enableval=$enable_small_filter; if test \"$enable_small_filter\" = \"no\"; then\n\t\tac_no_small_filter='-DPJMEDIA_HAS_SMALL_FILTER=0'\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if small filter is disabled... yes\" >&5\n$as_echo \"Checking if small filter is disabled... yes\" >&6; }\n\t       fi\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if small filter is disabled... no\" >&5\n$as_echo \"Checking if small filter is disabled... no\" >&6; }\nfi\n\n\n\n# Check whether --enable-large-filter was given.\nif test \"${enable_large_filter+set}\" = set; then :\n  enableval=$enable_large_filter; if test \"$enable_large_filter\" = \"no\"; then\n\t\tac_no_large_filter='-DPJMEDIA_HAS_LARGE_FILTER=0'\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if large filter is disabled... yes\" >&5\n$as_echo \"Checking if large filter is disabled... yes\" >&6; }\n\t       fi\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if large filter is disabled... no\" >&5\n$as_echo \"Checking if large filter is disabled... no\" >&6; }\nfi\n\n\n\n# Check whether --enable-speex-aec was given.\nif test \"${enable_speex_aec+set}\" = set; then :\n  enableval=$enable_speex_aec; if test \"$enable_speex_aec\" = \"no\"; then\n\t\tac_no_speex_aec='-DPJMEDIA_HAS_SPEEX_AEC=0'\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if Speex AEC is disabled...yes\" >&5\n$as_echo \"Checking if Speex AEC is disabled...yes\" >&6; }\n\t       fi\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if Speex AEC is disabled...no\" >&5\n$as_echo \"Checking if Speex AEC is disabled...no\" >&6; }\nfi\n\n\n\n# Check whether --enable-g7221-codec was given.\nif test \"${enable_g7221_codec+set}\" = set; then :\n  enableval=$enable_g7221_codec; if test \"$enable_g7221_codec\" = \"no\"; then\n\t\tac_no_g7221_codec=1\n\t\t$as_echo \"#define PJMEDIA_HAS_G7221_CODEC 0\" >>confdefs.h\n\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if G.722.1 codec is disabled...yes\" >&5\n$as_echo \"Checking if G.722.1 codec is disabled...yes\" >&6; }\n\t       fi\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if G.722.1 codec is disabled...no\" >&5\n$as_echo \"Checking if G.722.1 codec is disabled...no\" >&6; }\nfi\n\n\n# Check whether --enable-libsamplerate was given.\nif test \"${enable_libsamplerate+set}\" = set; then :\n  enableval=$enable_libsamplerate;  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for src_new in -lsamplerate\" >&5\n$as_echo_n \"checking for src_new in -lsamplerate... \" >&6; }\nif ${ac_cv_lib_samplerate_src_new+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lsamplerate  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar src_new ();\nint\nmain ()\n{\nreturn src_new ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_samplerate_src_new=yes\nelse\n  ac_cv_lib_samplerate_src_new=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_samplerate_src_new\" >&5\n$as_echo \"$ac_cv_lib_samplerate_src_new\" >&6; }\nif test \"x$ac_cv_lib_samplerate_src_new\" = xyes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBSAMPLERATE 1\n_ACEOF\n\n  LIBS=\"-lsamplerate $LIBS\"\n\nfi\n\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Skipping libsamplerate detection\" >&5\n$as_echo \"Skipping libsamplerate detection\" >&6; }\n\nfi\n\n\n\n# Check whether --enable-resample_dll was given.\nif test \"${enable_resample_dll+set}\" = set; then :\n  enableval=$enable_resample_dll; if test \"$enable_resample_dll\" = \"yes\"; then\n\t\tac_resample_dll=1\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Building libresample as shared library... yes\" >&5\n$as_echo \"Building libresample as shared library... yes\" >&6; }\n\t       fi\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Building libresample as shared library... no\" >&5\n$as_echo \"Building libresample as shared library... no\" >&6; }\n\nfi\n\n\n\nfor ac_prog in pkg-config\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_PKG_CONFIG+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$PKG_CONFIG\"; then\n  ac_cv_prog_PKG_CONFIG=\"$PKG_CONFIG\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_PKG_CONFIG=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nPKG_CONFIG=$ac_cv_prog_PKG_CONFIG\nif test -n \"$PKG_CONFIG\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG\" >&5\n$as_echo \"$PKG_CONFIG\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$PKG_CONFIG\" && break\ndone\ntest -n \"$PKG_CONFIG\" || PKG_CONFIG=\"none\"\n\n\nif test \"$PKG_CONFIG\" == \"none\"; then\n\tas_fn_error $? \"*** Error: pkg-config not found  ***\" \"$LINENO\" 5\nfi\n\n\n\n# Check whether --with-ffmpeg was given.\nif test \"${with_ffmpeg+set}\" = set; then :\n  withval=$with_ffmpeg;\nelse\n  with_ffmpeg=check\n\nfi\n\n\n\n\n\nFFMPEG_PREFIX=\"\"\n\nSAVED_PKG_CONFIG_PATH=$PKG_CONFIG_PATH\nif test \"x$with_ffmpeg\" != \"xcheck\" -a \"x$with_ffmpeg\" != \"x\"; then\n\tFFMPEG_PREFIX=$with_ffmpeg\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Using ffmpeg prefix... $FFMPEG_PREFIX\" >&5\n$as_echo \"Using ffmpeg prefix... $FFMPEG_PREFIX\" >&6; }\n\texport PKG_CONFIG_PATH=$FFMPEG_PREFIX/lib/pkgconfig\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking ffmpeg packages\" >&5\n$as_echo_n \"checking ffmpeg packages... \" >&6; }\nav_pkg=\"\"\nif $PKG_CONFIG --exists libavformat; then\n        ac_ffmpeg_cflags=\"$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVFORMAT=1\"\n        av_pkg=\"$av_pkg libavformat\"\nelse\n    as_fn_error $? \"*** Error: libavformat not detected  ***\" \"$LINENO\" 5\nfi\nif $PKG_CONFIG --exists libavcodec; then\n        ac_ffmpeg_cflags=\"$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVCODEC=1\"\n        av_pkg=\"$av_pkg libavcodec\"\nelse\n    as_fn_error $? \"*** Error: libavcodec not detected  ***\" \"$LINENO\" 5\nfi\nif $PKG_CONFIG --exists libswscale; then\n        ac_ffmpeg_cflags=\"$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBSWSCALE=1\"\n        av_pkg=\"$av_pkg libswscale\"\nelse\n    as_fn_error $? \"*** Error: libswscale not detected  ***\" \"$LINENO\" 5\nfi\nif $PKG_CONFIG --exists libavutil; then\n        ac_ffmpeg_cflags=\"$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVUTIL=1\"\n        av_pkg=\"$av_pkg libavutil\"\nelse\n    as_fn_error $? \"*** Error: libavutil not detected  ***\" \"$LINENO\" 5\nfi\nif $PKG_CONFIG --exists libavcore; then\n        ac_ffmpeg_cflags=\"$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVCORE=1\"\n        av_pkg=\"$av_pkg libavcore\"\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $av_pkg\" >&5\n$as_echo \"$av_pkg\" >&6; }\n\nac_ffmpeg_cflags=\"$ac_ffmpeg_cflags `$PKG_CONFIG --cflags $av_pkg`\"\nac_ffmpeg_ldflags=\"$ac_ffmpeg_ldflags `$PKG_CONFIG --libs $av_pkg`\"\n\nLIBS=\"$LIBS $ac_ffmpeg_ldflags\"\nexport PKG_CONFIG_PATH=$SAVED_PKG_CONFIG_PATH\n\n\n\n\n# Check whether --with-vpx was given.\nif test \"${with_vpx+set}\" = set; then :\n  withval=$with_vpx;\nelse\n  with_vpx=check\n\nfi\n\n\n\n\n\nVPX_PREFIX=\"\"\n\nSAVED_PKG_CONFIG_PATH=$PKG_CONFIG_PATH\nif test \"x$with_vpx\" != \"xcheck\" -a \"x$with_vpx\" != \"x\"; then\n\tVPX_PREFIX=$with_vpx\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Using libVPX prefix... $VPX_PREFIX\" >&5\n$as_echo \"Using libVPX prefix... $VPX_PREFIX\" >&6; }\n\texport PKG_CONFIG_PATH=$VPX_PREFIX\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking libvpx packages\" >&5\n$as_echo_n \"checking libvpx packages... \" >&6; }\nif $PKG_CONFIG --exists vpx; then\n        ac_vpx_cflags=\"`$PKG_CONFIG --cflags vpx` -DPJMEDIA_HAS_LIBVPX=1\"\n        ac_vpx_ldflags=\"`$PKG_CONFIG --libs vpx`\"\n        { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n    as_fn_error $? \"*** Error: VPX library not detected  ***\" \"$LINENO\" 5\nfi\n\nLIBS=\"$LIBS $ac_vpx_ldflags\"\nexport PKG_CONFIG_PATH=$SAVED_PKG_CONFIG_PATH\n\n\n# Check whether --enable-v4l2 was given.\nif test \"${enable_v4l2+set}\" = set; then :\n  enableval=$enable_v4l2;\n\t\tif test \"$enable_v4l2\" = \"no\"; then\n\t\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if V4L2 is disabled... yes\" >&5\n$as_echo \"Checking if V4L2 is disabled... yes\" >&6; }\n\t\tfi\n\nelse\n\n\n\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for v4l2_open in -lv4l2\" >&5\n$as_echo_n \"checking for v4l2_open in -lv4l2... \" >&6; }\nif ${ac_cv_lib_v4l2_v4l2_open+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lv4l2  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar v4l2_open ();\nint\nmain ()\n{\nreturn v4l2_open ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_v4l2_v4l2_open=yes\nelse\n  ac_cv_lib_v4l2_v4l2_open=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_v4l2_v4l2_open\" >&5\n$as_echo \"$ac_cv_lib_v4l2_v4l2_open\" >&6; }\nif test \"x$ac_cv_lib_v4l2_v4l2_open\" = xyes; then :\n  ac_v4l2_cflags=\"-DPJMEDIA_VIDEO_DEV_HAS_V4L2=1\"\n\t\t\t      ac_v4l2_ldflags=\"-lv4l2\"\n\t\t\t      LIBS=\"$LIBS -lv4l2\"\n\n\nfi\n\n\nfi\n\n\n\n# Check whether --with-openh264 was given.\nif test \"${with_openh264+set}\" = set; then :\n  withval=$with_openh264;\nelse\n  with_openh264=no\n\nfi\n\n\nif test \"x$ac_cross_compile\" != \"x\" -a \"x$with_openh264\" = \"xno\"; then\n    enable_openh264=no\nfi\n\n\n\n# Check whether --enable-openh264 was given.\nif test \"${enable_openh264+set}\" = set; then :\n  enableval=$enable_openh264;\n\t\tif test \"$enable_openh264\" = \"no\"; then\n\t\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if OpenH264 is disabled... yes\" >&5\n$as_echo \"Checking if OpenH264 is disabled... yes\" >&6; }\n\t\tfi\n\nelse\n\n\t\t  if test \"x$with_openh264\" != \"xno\" -a \"x$with_openh264\" != \"x\"; then\n\t\t        OPENH264_PREFIX=$with_openh264\n\t\t  \tOPENH264_CFLAGS=\"-I$OPENH264_PREFIX/include\"\n\t\t\tOPENH264_LDFLAGS=\"-L$OPENH264_PREFIX/lib\"\n\t\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Using OpenH264 prefix... $with_openh264\" >&5\n$as_echo \"Using OpenH264 prefix... $with_openh264\" >&6; }\n\t\t  else\n\t\t  \tOPENH264_CFLAGS=\"\"\n\t\t\tOPENH264_LDFLAGS=\"\"\n\t\t  fi\n\n\t\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking OpenH264 usability\" >&5\n$as_echo_n \"checking OpenH264 usability... \" >&6; }\n\n\t\t  OPENH264_LIBS=\"-lopenh264\"\n\n\t\t  SAVED_LIBS=\"$LIBS\"\n\t\t  SAVED_LDFLAGS=\"$LDFLAGS\"\n\t\t  SAVED_CFLAGS=\"$CFLAGS\"\n\n\t\t  LIBS=\"$OPENH264_LIBS $LIBS\"\n\t\t  LDFLAGS=\"$OPENH264_LDFLAGS $LDFLAGS -lstdc++\"\n\t\t  CFLAGS=\"$OPENH264_CFLAGS $CFLAGS\"\n\n\t\t  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <wels/codec_api.h>\n\t\t                                    #include <wels/codec_app_def.h>\n\nint\nmain ()\n{\nWelsCreateSVCEncoder(0);\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n   ac_openh264_cflags=\"-DPJMEDIA_HAS_OPENH264_CODEC=1 $OPENH264_CFLAGS\"\n\t\t  \t\t   ac_openh264_ldflags=\"$OPENH264_LDFLAGS $OPENH264_LIBS\"\n\t\t  \t\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: ok\" >&5\n$as_echo \"ok\" >&6; }\n\nelse\n\n\t\t\t\t   LIBS=\"$SAVED_LIBS\"\n\t\t\t\t   LDFLAGS=\"$SAVED_LDFLAGS\"\n\t\t\t\t   CFLAGS=\"$SAVED_CFLAGS\"\n\t\t  \t\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\n\nfi\n\n\n\n# Check whether --with-libyuv was given.\nif test \"${with_libyuv+set}\" = set; then :\n  withval=$with_libyuv;\nelse\n  with_libyuv=no\n\nfi\n\n\nif test \"x$ac_cross_compile\" != \"x\" -a \"x$with_libyuv\" = \"xno\"; then\n    enable_libyuv=no\nfi\n\n\n\n# Check whether --enable-libyuv was given.\nif test \"${enable_libyuv+set}\" = set; then :\n  enableval=$enable_libyuv; if test \"$enable_libyuv\" = \"no\"; then\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if libyuv is disabled...yes\" >&5\n$as_echo \"Checking if libyuv is disabled...yes\" >&6; }\n\t       fi\nelse\n\n\t\t  if test \"x$with_libyuv\" != \"xno\" -a \"x$with_libyuv\" != \"x\"; then\n\t\t        LIBYUV_PREFIX=$with_libyuv\n\t\t  \tLIBYUV_CFLAGS=\"-I$LIBYUV_PREFIX/include\"\n\n\t\t\tcase $target in\n\t\t\t    arm-apple-darwin*)\n\t\t\t\tLIBYUV_LDFLAGS=\"-L$LIBYUV_PREFIX/out_ios/Release-iphoneos\"\n\t\t\t\tcase $ARCH in\n\t\t\t\t    *armv7*)\n\t\t\t\t    LIBYUV_LIBS=\"-lyuv_neon\"\n\t\t\t\t    ;;\n\t\t\t\t*)\n\t\t\t\t    ;;\n\t\t\t\tesac\n\t\t\t\t;;\n\t\t\t    *mingw* | *cygw* | *win32* | *w32* | *darwin* | *linux* | *android*)\n\t\t\t\tLIBYUV_LDFLAGS=\"-L$LIBYUV_PREFIX/out/Release\"\n\t\t\t\t;;\n\t\t\t    *)\n\t\t\t\tLIBYUV_CFLAGS=\"\"\n\t\t\t\tLIBYUV_LDFLAGS=\"\"\n\t\t\t\t;;\n\t\t\tesac\n\n\t\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: Using libyuv prefix... $with_libyuv\" >&5\n$as_echo \"Using libyuv prefix... $with_libyuv\" >&6; }\n\t\t  else\n\t\t  \tLIBYUV_CFLAGS=\"\"\n\t\t\tLIBYUV_LDFLAGS=\"\"\n\t\t  fi\n\n\t\t  LIBYUV_LIBS=\"$LIBYUV_LIBS -lyuv\"\n\n\t\t  SAVED_LIBS=\"$LIBS\"\n\t\t  SAVED_LDFLAGS=\"$LDFLAGS\"\n\t\t  SAVED_CFLAGS=\"$CFLAGS\"\n\n\t\t  LIBS=\"$LIBYUV_LIBS $LIBS\"\n\t\t  LDFLAGS=\"$LIBYUV_LDFLAGS $LDFLAGS\"\n\t\t  CFLAGS=\"$LIBYUV_CFLAGS $CFLAGS\"\n\n\t\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for I420Scale in -lyuv\" >&5\n$as_echo_n \"checking for I420Scale in -lyuv... \" >&6; }\nif ${ac_cv_lib_yuv_I420Scale+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lyuv\n\t\t\t        $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar I420Scale ();\nint\nmain ()\n{\nreturn I420Scale ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_yuv_I420Scale=yes\nelse\n  ac_cv_lib_yuv_I420Scale=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_yuv_I420Scale\" >&5\n$as_echo \"$ac_cv_lib_yuv_I420Scale\" >&6; }\nif test \"x$ac_cv_lib_yuv_I420Scale\" = xyes; then :\n   ac_libyuv_cflags=\"-DPJMEDIA_HAS_LIBYUV=1 $LIBYUV_CFLAGS\"\n\t\t  \t\t ac_libyuv_ldflags=\"$LIBYUV_LDFLAGS $LIBYUV_LIBS\"\n\nelse\n   LIBS=\"$SAVED_LIBS\"\n\t\t\t\t LDFLAGS=\"$SAVED_LDFLAGS\"\n\t\t\t\t CFLAGS=\"$SAVED_CFLAGS\"\n\nfi\n\n\nfi\n\n\n\n\n\ncase $target in\n *darwin*)\n       ac_webrtc_platform=webrtc_darwinos\n       ;;\n *mingw*)\n       ac_webrtc_platform=webrtc_win32\n       ;;\n *linux*)\n       ac_webrtc_platform=webrtc_linux\n       ;;\n *)\n       ac_webrtc_platform=null\n       ;;\nesac\n\n\n\n\n# Check whether --with-ssl was given.\nif test \"${with_ssl+set}\" = set; then :\n  withval=$with_ssl;\nelse\n  with_ssl=no\n\nfi\n\n\nif test \"x$ac_cross_compile\" != \"x\" -a \"x$with_ssl\" = \"xno\"; then\n    enable_ssl=no\nfi\n\n\n# Check whether --enable-ssl was given.\nif test \"${enable_ssl+set}\" = set; then :\n  enableval=$enable_ssl;\n\t\tif test \"$enable_ssl\" = \"no\"; then\n\t\t ac_no_ssl=1\n\t\t { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Checking if SSL support is disabled... yes\" >&5\n$as_echo \"Checking if SSL support is disabled... yes\" >&6; }\n\t        fi\n\nelse\n\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: checking for OpenSSL installations..\" >&5\n$as_echo \"checking for OpenSSL installations..\" >&6; }\n                if test \"x$with_ssl\" != \"xno\" -a \"x$with_ssl\" != \"x\"; then\n                    CFLAGS=\"$CFLAGS -I$with_ssl/include\"\n                    LDFLAGS=\"$LDFLAGS -L$with_ssl/lib\"\n                    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: Using SSL prefix... $with_ssl\" >&5\n$as_echo \"Using SSL prefix... $with_ssl\" >&6; }\n                fi\n\n\n\n\t\tac_fn_c_check_header_mongrel \"$LINENO\" \"openssl/ssl.h\" \"ac_cv_header_openssl_ssl_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_openssl_ssl_h\" = xyes; then :\n  openssl_h_present=1\nfi\n\n\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for ERR_load_BIO_strings in -lcrypto\" >&5\n$as_echo_n \"checking for ERR_load_BIO_strings in -lcrypto... \" >&6; }\nif ${ac_cv_lib_crypto_ERR_load_BIO_strings+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lcrypto  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar ERR_load_BIO_strings ();\nint\nmain ()\n{\nreturn ERR_load_BIO_strings ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_crypto_ERR_load_BIO_strings=yes\nelse\n  ac_cv_lib_crypto_ERR_load_BIO_strings=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_ERR_load_BIO_strings\" >&5\n$as_echo \"$ac_cv_lib_crypto_ERR_load_BIO_strings\" >&6; }\nif test \"x$ac_cv_lib_crypto_ERR_load_BIO_strings\" = xyes; then :\n  libcrypto_present=1 && LIBS=\"-lcrypto $LIBS\"\nfi\n\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for SSL_CTX_new in -lssl\" >&5\n$as_echo_n \"checking for SSL_CTX_new in -lssl... \" >&6; }\nif ${ac_cv_lib_ssl_SSL_CTX_new+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lssl  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar SSL_CTX_new ();\nint\nmain ()\n{\nreturn SSL_CTX_new ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_ssl_SSL_CTX_new=yes\nelse\n  ac_cv_lib_ssl_SSL_CTX_new=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_CTX_new\" >&5\n$as_echo \"$ac_cv_lib_ssl_SSL_CTX_new\" >&6; }\nif test \"x$ac_cv_lib_ssl_SSL_CTX_new\" = xyes; then :\n  libssl_present=1 && LIBS=\"-lssl $LIBS\"\nfi\n\n\t\tif test \"x$openssl_h_present\" = \"x1\" -a \"x$libssl_present\" = \"x1\" -a \"x$libcrypto_present\" = \"x1\"; then\n\t        \t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: OpenSSL library found, SSL support enabled\" >&5\n$as_echo \"OpenSSL library found, SSL support enabled\" >&6; }\n\t\t\t# PJSIP_HAS_TLS_TRANSPORT setting follows PJ_HAS_SSL_SOCK\n\t\t\t#AC_DEFINE(PJSIP_HAS_TLS_TRANSPORT, 1)\n\t\t\t$as_echo \"#define PJ_HAS_SSL_SOCK 1\" >>confdefs.h\n\n\t\telse\n\t\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: ** OpenSSL libraries not found, disabling SSL support **\" >&5\n$as_echo \"** OpenSSL libraries not found, disabling SSL support **\" >&6; }\n\t\tfi\n\nfi\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if select() needs correct nfds\" >&5\n$as_echo_n \"checking if select() needs correct nfds... \" >&6; }\ncase $target in\n  *rtems*) $as_echo \"#define PJ_SELECT_NEEDS_NFDS 1\" >>confdefs.h\n\n\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\t;;\n  *) $as_echo \"#define PJ_SELECT_NEEDS_NFDS 0\" >>confdefs.h\n\n     { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no (default)\" >&5\n$as_echo \"no (default)\" >&6; }\n     { $as_echo \"$as_me:${as_lineno-$LINENO}: result: ** Decided that select() doesn't need correct nfds (please check)\" >&5\n$as_echo \"** Decided that select() doesn't need correct nfds (please check)\" >&6; }\n\t;;\nesac\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if pj_thread_create() should enforce stack size\" >&5\n$as_echo_n \"checking if pj_thread_create() should enforce stack size... \" >&6; }\ncase $target in\n  *rtems*) $as_echo \"#define PJ_THREAD_SET_STACK_SIZE 1\" >>confdefs.h\n\n\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\t;;\n  *) $as_echo \"#define PJ_THREAD_SET_STACK_SIZE 0\" >>confdefs.h\n\n     { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no (default)\" >&5\n$as_echo \"no (default)\" >&6; }\n\t;;\nesac\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if pj_thread_create() should allocate stack\" >&5\n$as_echo_n \"checking if pj_thread_create() should allocate stack... \" >&6; }\ncase $target in\n  *rtems*) $as_echo \"#define PJ_THREAD_ALLOCATE_STACK 1\" >>confdefs.h\n\n\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\t;;\n  *) $as_echo \"#define PJ_THREAD_ALLOCATE_STACK 0\" >>confdefs.h\n\n     { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no (default)\" >&5\n$as_echo \"no (default)\" >&6; }\n\t;;\nesac\n\ncase $target in\n  *mingw* | *cygw* | *win32* | *w32* )\n\t$as_echo \"#define PJ_BLOCKING_ERROR_VAL WSAEWOULDBLOCK\" >>confdefs.h\n\n\t;;\n  *) $as_echo \"#define PJ_BLOCKING_ERROR_VAL EAGAIN\" >>confdefs.h\n\n     { $as_echo \"$as_me:${as_lineno-$LINENO}: result: ** Setting non-blocking recv() retval to EAGAIN (please check)\" >&5\n$as_echo \"** Setting non-blocking recv() retval to EAGAIN (please check)\" >&6; }\n\t;;\nesac\n\ncase $target in\n  *mingw* | *cygw* | *win32* | *w32* )\n\t$as_echo \"#define PJ_BLOCKING_CONNECT_ERROR_VAL WSAEWOULDBLOCK\" >>confdefs.h\n\n\t;;\n  *) $as_echo \"#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS\" >>confdefs.h\n\n     { $as_echo \"$as_me:${as_lineno-$LINENO}: result: ** Setting non-blocking connect() retval to EINPROGRESS (please check)\" >&5\n$as_echo \"** Setting non-blocking connect() retval to EINPROGRESS (please check)\" >&6; }\n\t;;\nesac\n\n\n\nac_linux_poll=select\n\nac_host=unix\n\n\ncase $target in\n  *rtems*)\n\tac_main_obj=main_rtems.o\n\t;;\n  *)\n\tac_main_obj=main.o\n\t;;\nesac\n\n\nac_build_mak_vars=`echo $ac_build_mak_vars | sed 's/\\\\\\\\n/\\n/g'`\ncat >confcache <<\\_ACEOF\n# This file is a shell script that caches the results of configure\n# tests run on this system so they can be shared between configure\n# scripts and configure runs, see configure's option --config-cache.\n# It is not useful on other systems.  If it contains results you don't\n# want to keep, you may remove or edit it.\n#\n# config.status only pays attention to the cache file if you give it\n# the --recheck option to rerun configure.\n#\n# `ac_cv_env_foo' variables (set or unset) will be overridden when\n# loading this file, other *unset* `ac_cv_foo' will be assigned the\n# following values.\n\n_ACEOF\n\n# The following way of writing the cache mishandles newlines in values,\n# but we know of no workaround that is simple, portable, and efficient.\n# So, we kill variables containing newlines.\n# Ultrix sh set writes to stderr and can't be redirected directly,\n# and sets the high bit in the cache file unless we assign to the vars.\n(\n  for ac_var in `(set) 2>&1 | sed -n 's/^\\([a-zA-Z_][a-zA-Z0-9_]*\\)=.*/\\1/p'`; do\n    eval ac_val=\\$$ac_var\n    case $ac_val in #(\n    *${as_nl}*)\n      case $ac_var in #(\n      *_cv_*) { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline\" >&5\n$as_echo \"$as_me: WARNING: cache variable $ac_var contains a newline\" >&2;} ;;\n      esac\n      case $ac_var in #(\n      _ | IFS | as_nl) ;; #(\n      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(\n      *) { eval $ac_var=; unset $ac_var;} ;;\n      esac ;;\n    esac\n  done\n\n  (set) 2>&1 |\n    case $as_nl`(ac_space=' '; set) 2>&1` in #(\n    *${as_nl}ac_space=\\ *)\n      # `set' does not quote correctly, so add quotes: double-quote\n      # substitution turns \\\\\\\\ into \\\\, and sed turns \\\\ into \\.\n      sed -n \\\n\t\"s/'/'\\\\\\\\''/g;\n\t  s/^\\\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\\\)=\\\\(.*\\\\)/\\\\1='\\\\2'/p\"\n      ;; #(\n    *)\n      # `set' quotes correctly as required by POSIX, so do not add quotes.\n      sed -n \"/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p\"\n      ;;\n    esac |\n    sort\n) |\n  sed '\n     /^ac_cv_env_/b end\n     t clear\n     :clear\n     s/^\\([^=]*\\)=\\(.*[{}].*\\)$/test \"${\\1+set}\" = set || &/\n     t end\n     s/^\\([^=]*\\)=\\(.*\\)$/\\1=${\\1=\\2}/\n     :end' >>confcache\nif diff \"$cache_file\" confcache >/dev/null 2>&1; then :; else\n  if test -w \"$cache_file\"; then\n    if test \"x$cache_file\" != \"x/dev/null\"; then\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: updating cache $cache_file\" >&5\n$as_echo \"$as_me: updating cache $cache_file\" >&6;}\n      if test ! -f \"$cache_file\" || test -h \"$cache_file\"; then\n\tcat confcache >\"$cache_file\"\n      else\n        case $cache_file in #(\n        */* | ?:*)\n\t  mv -f confcache \"$cache_file\"$$ &&\n\t  mv -f \"$cache_file\"$$ \"$cache_file\" ;; #(\n        *)\n\t  mv -f confcache \"$cache_file\" ;;\n\tesac\n      fi\n    fi\n  else\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file\" >&5\n$as_echo \"$as_me: not updating unwritable cache $cache_file\" >&6;}\n  fi\nfi\nrm -f confcache\n\ntest \"x$prefix\" = xNONE && prefix=$ac_default_prefix\n# Let make expand exec_prefix.\ntest \"x$exec_prefix\" = xNONE && exec_prefix='${prefix}'\n\nDEFS=-DHAVE_CONFIG_H\n\nac_libobjs=\nac_ltlibobjs=\nU=\nfor ac_i in : $LIBOBJS; do test \"x$ac_i\" = x: && continue\n  # 1. Remove the extension, and $U if already installed.\n  ac_script='s/\\$U\\././;s/\\.o$//;s/\\.obj$//'\n  ac_i=`$as_echo \"$ac_i\" | sed \"$ac_script\"`\n  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR\n  #    will be set to the directory where LIBOBJS objects are built.\n  as_fn_append ac_libobjs \" \\${LIBOBJDIR}$ac_i\\$U.$ac_objext\"\n  as_fn_append ac_ltlibobjs \" \\${LIBOBJDIR}$ac_i\"'$U.lo'\ndone\nLIBOBJS=$ac_libobjs\n\nLTLIBOBJS=$ac_ltlibobjs\n\n\n\n\n: \"${CONFIG_STATUS=./config.status}\"\nac_write_fail=0\nac_clean_files_save=$ac_clean_files\nac_clean_files=\"$ac_clean_files $CONFIG_STATUS\"\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS\" >&5\n$as_echo \"$as_me: creating $CONFIG_STATUS\" >&6;}\nas_write_fail=0\ncat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1\n#! $SHELL\n# Generated by $as_me.\n# Run this file to recreate the current configuration.\n# Compiler output produced by configure, useful for debugging\n# configure, is in config.log if it exists.\n\ndebug=false\nac_cs_recheck=false\nac_cs_silent=false\n\nSHELL=\\${CONFIG_SHELL-$SHELL}\nexport SHELL\n_ASEOF\ncat >>$CONFIG_STATUS <<\\_ASEOF || as_write_fail=1\n## -------------------- ##\n## M4sh Initialization. ##\n## -------------------- ##\n\n# Be more Bourne compatible\nDUALCASE=1; export DUALCASE # for MKS sh\nif test -n \"${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :\n  emulate sh\n  NULLCMD=:\n  # Pre-4.2 versions of Zsh do word splitting on ${1+\"$@\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '${1+\"$@\"}'='\"$@\"'\n  setopt NO_GLOB_SUBST\nelse\n  case `(set -o) 2>/dev/null` in #(\n  *posix*) :\n    set -o posix ;; #(\n  *) :\n     ;;\nesac\nfi\n\n\nas_nl='\n'\nexport as_nl\n# Printing a long string crashes Solaris 7 /usr/bin/printf.\nas_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo\n# Prefer a ksh shell builtin over an external printf program on Solaris,\n# but without wasting forks for bash or zsh.\nif test -z \"$BASH_VERSION$ZSH_VERSION\" \\\n    && (test \"X`print -r -- $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='print -r --'\n  as_echo_n='print -rn --'\nelif (test \"X`printf %s $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='printf %s\\n'\n  as_echo_n='printf %s'\nelse\n  if test \"X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`\" = \"X-n $as_echo\"; then\n    as_echo_body='eval /usr/ucb/echo -n \"$1$as_nl\"'\n    as_echo_n='/usr/ucb/echo -n'\n  else\n    as_echo_body='eval expr \"X$1\" : \"X\\\\(.*\\\\)\"'\n    as_echo_n_body='eval\n      arg=$1;\n      case $arg in #(\n      *\"$as_nl\"*)\n\texpr \"X$arg\" : \"X\\\\(.*\\\\)$as_nl\";\n\targ=`expr \"X$arg\" : \".*$as_nl\\\\(.*\\\\)\"`;;\n      esac;\n      expr \"X$arg\" : \"X\\\\(.*\\\\)\" | tr -d \"$as_nl\"\n    '\n    export as_echo_n_body\n    as_echo_n='sh -c $as_echo_n_body as_echo'\n  fi\n  export as_echo_body\n  as_echo='sh -c $as_echo_body as_echo'\nfi\n\n# The user is always right.\nif test \"${PATH_SEPARATOR+set}\" != set; then\n  PATH_SEPARATOR=:\n  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {\n    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||\n      PATH_SEPARATOR=';'\n  }\nfi\n\n\n# IFS\n# We need space, tab and new line, in precisely that order.  Quoting is\n# there to prevent editors from complaining about space-tab.\n# (If _AS_PATH_WALK were called with IFS unset, it would disable word\n# splitting by setting IFS to empty value.)\nIFS=\" \"\"\t$as_nl\"\n\n# Find who we are.  Look in the path if we contain no directory separator.\nas_myself=\ncase $0 in #((\n  *[\\\\/]* ) as_myself=$0 ;;\n  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    test -r \"$as_dir/$0\" && as_myself=$as_dir/$0 && break\n  done\nIFS=$as_save_IFS\n\n     ;;\nesac\n# We did not find ourselves, most probably we were run as `sh COMMAND'\n# in which case we are not to be found in the path.\nif test \"x$as_myself\" = x; then\n  as_myself=$0\nfi\nif test ! -f \"$as_myself\"; then\n  $as_echo \"$as_myself: error: cannot find myself; rerun with an absolute file name\" >&2\n  exit 1\nfi\n\n# Unset variables that we do not need and which cause bugs (e.g. in\n# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the \"|| exit 1\"\n# suppresses any \"Segmentation fault\" message there.  '((' could\n# trigger a bug in pdksh 5.2.14.\nfor as_var in BASH_ENV ENV MAIL MAILPATH\ndo eval test x\\${$as_var+set} = xset \\\n  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :\ndone\nPS1='$ '\nPS2='> '\nPS4='+ '\n\n# NLS nuisances.\nLC_ALL=C\nexport LC_ALL\nLANGUAGE=C\nexport LANGUAGE\n\n# CDPATH.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\n\n# as_fn_error STATUS ERROR [LINENO LOG_FD]\n# ----------------------------------------\n# Output \"`basename $0`: error: ERROR\" to stderr. If LINENO and LOG_FD are\n# provided, also output the error to LOG_FD, referencing LINENO. Then exit the\n# script with STATUS, using 1 if that was 0.\nas_fn_error ()\n{\n  as_status=$1; test $as_status -eq 0 && as_status=1\n  if test \"$4\"; then\n    as_lineno=${as_lineno-\"$3\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n    $as_echo \"$as_me:${as_lineno-$LINENO}: error: $2\" >&$4\n  fi\n  $as_echo \"$as_me: error: $2\" >&2\n  as_fn_exit $as_status\n} # as_fn_error\n\n\n# as_fn_set_status STATUS\n# -----------------------\n# Set $? to STATUS, without forking.\nas_fn_set_status ()\n{\n  return $1\n} # as_fn_set_status\n\n# as_fn_exit STATUS\n# -----------------\n# Exit the shell with STATUS, even in a \"trap 0\" or \"set -e\" context.\nas_fn_exit ()\n{\n  set +e\n  as_fn_set_status $1\n  exit $1\n} # as_fn_exit\n\n# as_fn_unset VAR\n# ---------------\n# Portably unset VAR.\nas_fn_unset ()\n{\n  { eval $1=; unset $1;}\n}\nas_unset=as_fn_unset\n# as_fn_append VAR VALUE\n# ----------------------\n# Append the text in VALUE to the end of the definition contained in VAR. Take\n# advantage of any shell optimizations that allow amortized linear growth over\n# repeated appends, instead of the typical quadratic growth present in naive\n# implementations.\nif (eval \"as_var=1; as_var+=2; test x\\$as_var = x12\") 2>/dev/null; then :\n  eval 'as_fn_append ()\n  {\n    eval $1+=\\$2\n  }'\nelse\n  as_fn_append ()\n  {\n    eval $1=\\$$1\\$2\n  }\nfi # as_fn_append\n\n# as_fn_arith ARG...\n# ------------------\n# Perform arithmetic evaluation on the ARGs, and store the result in the\n# global $as_val. Take advantage of shells that can avoid forks. The arguments\n# must be portable across $(()) and expr.\nif (eval \"test \\$(( 1 + 1 )) = 2\") 2>/dev/null; then :\n  eval 'as_fn_arith ()\n  {\n    as_val=$(( $* ))\n  }'\nelse\n  as_fn_arith ()\n  {\n    as_val=`expr \"$@\" || test $? -eq 1`\n  }\nfi # as_fn_arith\n\n\nif expr a : '\\(a\\)' >/dev/null 2>&1 &&\n   test \"X`expr 00001 : '.*\\(...\\)'`\" = X001; then\n  as_expr=expr\nelse\n  as_expr=false\nfi\n\nif (basename -- /) >/dev/null 2>&1 && test \"X`basename -- / 2>&1`\" = \"X/\"; then\n  as_basename=basename\nelse\n  as_basename=false\nfi\n\nif (as_dir=`dirname -- /` && test \"X$as_dir\" = X/) >/dev/null 2>&1; then\n  as_dirname=dirname\nelse\n  as_dirname=false\nfi\n\nas_me=`$as_basename -- \"$0\" ||\n$as_expr X/\"$0\" : '.*/\\([^/][^/]*\\)/*$' \\| \\\n\t X\"$0\" : 'X\\(//\\)$' \\| \\\n\t X\"$0\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X/\"$0\" |\n    sed '/^.*\\/\\([^/][^/]*\\)\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n\n# Avoid depending upon Character Ranges.\nas_cr_letters='abcdefghijklmnopqrstuvwxyz'\nas_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nas_cr_Letters=$as_cr_letters$as_cr_LETTERS\nas_cr_digits='0123456789'\nas_cr_alnum=$as_cr_Letters$as_cr_digits\n\nECHO_C= ECHO_N= ECHO_T=\ncase `echo -n x` in #(((((\n-n*)\n  case `echo 'xy\\c'` in\n  *c*) ECHO_T='\t';;\t# ECHO_T is single tab character.\n  xy)  ECHO_C='\\c';;\n  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null\n       ECHO_T='\t';;\n  esac;;\n*)\n  ECHO_N='-n';;\nesac\n\nrm -f conf$$ conf$$.exe conf$$.file\nif test -d conf$$.dir; then\n  rm -f conf$$.dir/conf$$.file\nelse\n  rm -f conf$$.dir\n  mkdir conf$$.dir 2>/dev/null\nfi\nif (echo >conf$$.file) 2>/dev/null; then\n  if ln -s conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s='ln -s'\n    # ... but there are two gotchas:\n    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.\n    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.\n    # In both cases, we have to default to `cp -pR'.\n    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||\n      as_ln_s='cp -pR'\n  elif ln conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s=ln\n  else\n    as_ln_s='cp -pR'\n  fi\nelse\n  as_ln_s='cp -pR'\nfi\nrm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file\nrmdir conf$$.dir 2>/dev/null\n\n\n# as_fn_mkdir_p\n# -------------\n# Create \"$as_dir\" as a directory, including parents if necessary.\nas_fn_mkdir_p ()\n{\n\n  case $as_dir in #(\n  -*) as_dir=./$as_dir;;\n  esac\n  test -d \"$as_dir\" || eval $as_mkdir_p || {\n    as_dirs=\n    while :; do\n      case $as_dir in #(\n      *\\'*) as_qdir=`$as_echo \"$as_dir\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;; #'(\n      *) as_qdir=$as_dir;;\n      esac\n      as_dirs=\"'$as_qdir' $as_dirs\"\n      as_dir=`$as_dirname -- \"$as_dir\" ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n      test -d \"$as_dir\" && break\n    done\n    test -z \"$as_dirs\" || eval \"mkdir $as_dirs\"\n  } || test -d \"$as_dir\" || as_fn_error $? \"cannot create directory $as_dir\"\n\n\n} # as_fn_mkdir_p\nif mkdir -p . 2>/dev/null; then\n  as_mkdir_p='mkdir -p \"$as_dir\"'\nelse\n  test -d ./-p && rmdir ./-p\n  as_mkdir_p=false\nfi\n\n\n# as_fn_executable_p FILE\n# -----------------------\n# Test if FILE is an executable regular file.\nas_fn_executable_p ()\n{\n  test -f \"$1\" && test -x \"$1\"\n} # as_fn_executable_p\nas_test_x='test -x'\nas_executable_p=as_fn_executable_p\n\n# Sed expression to map a string onto a valid CPP name.\nas_tr_cpp=\"eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'\"\n\n# Sed expression to map a string onto a valid variable name.\nas_tr_sh=\"eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'\"\n\n\nexec 6>&1\n## ----------------------------------- ##\n## Main body of $CONFIG_STATUS script. ##\n## ----------------------------------- ##\n_ASEOF\ntest $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n# Save the log message, to keep $0 and so on meaningful, and to\n# report actual input values of CONFIG_FILES etc. instead of their\n# values after options handling.\nac_log=\"\nThis file was extended by pjproject $as_me 2.x, which was\ngenerated by GNU Autoconf 2.69.  Invocation command line was\n\n  CONFIG_FILES    = $CONFIG_FILES\n  CONFIG_HEADERS  = $CONFIG_HEADERS\n  CONFIG_LINKS    = $CONFIG_LINKS\n  CONFIG_COMMANDS = $CONFIG_COMMANDS\n  $ $0 $@\n\non `(hostname || uname -n) 2>/dev/null | sed 1q`\n\"\n\n_ACEOF\n\ncase $ac_config_files in *\"\n\"*) set x $ac_config_files; shift; ac_config_files=$*;;\nesac\n\ncase $ac_config_headers in *\"\n\"*) set x $ac_config_headers; shift; ac_config_headers=$*;;\nesac\n\n\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n# Files that config.status was made for.\nconfig_files=\"$ac_config_files\"\nconfig_headers=\"$ac_config_headers\"\n\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nac_cs_usage=\"\\\n\\`$as_me' instantiates files and other configuration actions\nfrom templates according to the current configuration.  Unless the files\nand actions are specified as TAGs, all are instantiated by default.\n\nUsage: $0 [OPTION]... [TAG]...\n\n  -h, --help       print this help, then exit\n  -V, --version    print version number and configuration settings, then exit\n      --config     print configuration, then exit\n  -q, --quiet, --silent\n                   do not print progress messages\n  -d, --debug      don't remove temporary files\n      --recheck    update $as_me by reconfiguring in the same conditions\n      --file=FILE[:TEMPLATE]\n                   instantiate the configuration file FILE\n      --header=FILE[:TEMPLATE]\n                   instantiate the configuration header FILE\n\nConfiguration files:\n$config_files\n\nConfiguration headers:\n$config_headers\n\nReport bugs to the package provider.\"\n\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\nac_cs_config=\"`$as_echo \"$ac_configure_args\" | sed 's/^ //; s/[\\\\\"\"\\`\\$]/\\\\\\\\&/g'`\"\nac_cs_version=\"\\\\\npjproject config.status 2.x\nconfigured by $0, generated by GNU Autoconf 2.69,\n  with options \\\\\"\\$ac_cs_config\\\\\"\n\nCopyright (C) 2012 Free Software Foundation, Inc.\nThis config.status script is free software; the Free Software Foundation\ngives unlimited permission to copy, distribute and modify it.\"\n\nac_pwd='$ac_pwd'\nsrcdir='$srcdir'\ntest -n \"\\$AWK\" || AWK=awk\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n# The default lists apply if the user does not specify any file.\nac_need_defaults=:\nwhile test $# != 0\ndo\n  case $1 in\n  --*=?*)\n    ac_option=`expr \"X$1\" : 'X\\([^=]*\\)='`\n    ac_optarg=`expr \"X$1\" : 'X[^=]*=\\(.*\\)'`\n    ac_shift=:\n    ;;\n  --*=)\n    ac_option=`expr \"X$1\" : 'X\\([^=]*\\)='`\n    ac_optarg=\n    ac_shift=:\n    ;;\n  *)\n    ac_option=$1\n    ac_optarg=$2\n    ac_shift=shift\n    ;;\n  esac\n\n  case $ac_option in\n  # Handling of the options.\n  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)\n    ac_cs_recheck=: ;;\n  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )\n    $as_echo \"$ac_cs_version\"; exit ;;\n  --config | --confi | --conf | --con | --co | --c )\n    $as_echo \"$ac_cs_config\"; exit ;;\n  --debug | --debu | --deb | --de | --d | -d )\n    debug=: ;;\n  --file | --fil | --fi | --f )\n    $ac_shift\n    case $ac_optarg in\n    *\\'*) ac_optarg=`$as_echo \"$ac_optarg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    '') as_fn_error $? \"missing file argument\" ;;\n    esac\n    as_fn_append CONFIG_FILES \" '$ac_optarg'\"\n    ac_need_defaults=false;;\n  --header | --heade | --head | --hea )\n    $ac_shift\n    case $ac_optarg in\n    *\\'*) ac_optarg=`$as_echo \"$ac_optarg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    esac\n    as_fn_append CONFIG_HEADERS \" '$ac_optarg'\"\n    ac_need_defaults=false;;\n  --he | --h)\n    # Conflict between --help and --header\n    as_fn_error $? \"ambiguous option: \\`$1'\nTry \\`$0 --help' for more information.\";;\n  --help | --hel | -h )\n    $as_echo \"$ac_cs_usage\"; exit ;;\n  -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n  | -silent | --silent | --silen | --sile | --sil | --si | --s)\n    ac_cs_silent=: ;;\n\n  # This is an error.\n  -*) as_fn_error $? \"unrecognized option: \\`$1'\nTry \\`$0 --help' for more information.\" ;;\n\n  *) as_fn_append ac_config_targets \" $1\"\n     ac_need_defaults=false ;;\n\n  esac\n  shift\ndone\n\nac_configure_extra_args=\n\nif $ac_cs_silent; then\n  exec 6>/dev/null\n  ac_configure_extra_args=\"$ac_configure_extra_args --silent\"\nfi\n\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\nif \\$ac_cs_recheck; then\n  set X $SHELL '$0' $ac_configure_args \\$ac_configure_extra_args --no-create --no-recursion\n  shift\n  \\$as_echo \"running CONFIG_SHELL=$SHELL \\$*\" >&6\n  CONFIG_SHELL='$SHELL'\n  export CONFIG_SHELL\n  exec \"\\$@\"\nfi\n\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nexec 5>>config.log\n{\n  echo\n  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX\n## Running $as_me. ##\n_ASBOX\n  $as_echo \"$ac_log\"\n} >&5\n\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n\n# Handling of arguments.\nfor ac_config_target in $ac_config_targets\ndo\n  case $ac_config_target in\n    \"pjlib/include/pj/compat/os_auto.h\") CONFIG_HEADERS=\"$CONFIG_HEADERS pjlib/include/pj/compat/os_auto.h\" ;;\n    \"pjlib/include/pj/compat/m_auto.h\") CONFIG_HEADERS=\"$CONFIG_HEADERS pjlib/include/pj/compat/m_auto.h\" ;;\n    \"pjmedia/include/pjmedia/config_auto.h\") CONFIG_HEADERS=\"$CONFIG_HEADERS pjmedia/include/pjmedia/config_auto.h\" ;;\n    \"pjmedia/include/pjmedia-codec/config_auto.h\") CONFIG_HEADERS=\"$CONFIG_HEADERS pjmedia/include/pjmedia-codec/config_auto.h\" ;;\n    \"pjsip/include/pjsip/sip_autoconf.h\") CONFIG_HEADERS=\"$CONFIG_HEADERS pjsip/include/pjsip/sip_autoconf.h\" ;;\n    \"build.mak\") CONFIG_FILES=\"$CONFIG_FILES build.mak\" ;;\n    \"build/os-auto.mak\") CONFIG_FILES=\"$CONFIG_FILES build/os-auto.mak\" ;;\n    \"build/cc-auto.mak\") CONFIG_FILES=\"$CONFIG_FILES build/cc-auto.mak\" ;;\n    \"pjlib/build/os-auto.mak\") CONFIG_FILES=\"$CONFIG_FILES pjlib/build/os-auto.mak\" ;;\n    \"pjmedia/build/os-auto.mak\") CONFIG_FILES=\"$CONFIG_FILES pjmedia/build/os-auto.mak\" ;;\n    \"pjsip/build/os-auto.mak\") CONFIG_FILES=\"$CONFIG_FILES pjsip/build/os-auto.mak\" ;;\n    \"third_party/build/webrtc/os-auto.mak\") CONFIG_FILES=\"$CONFIG_FILES third_party/build/webrtc/os-auto.mak\" ;;\n    \"third_party/build/os-auto.mak\") CONFIG_FILES=\"$CONFIG_FILES third_party/build/os-auto.mak\" ;;\n\n  *) as_fn_error $? \"invalid argument: \\`$ac_config_target'\" \"$LINENO\" 5;;\n  esac\ndone\n\n\n# If the user did not use the arguments to specify the items to instantiate,\n# then the envvar interface is used.  Set only those that are not.\n# We use the long form for the default assignment because of an extremely\n# bizarre bug on SunOS 4.1.3.\nif $ac_need_defaults; then\n  test \"${CONFIG_FILES+set}\" = set || CONFIG_FILES=$config_files\n  test \"${CONFIG_HEADERS+set}\" = set || CONFIG_HEADERS=$config_headers\nfi\n\n# Have a temporary directory for convenience.  Make it in the build tree\n# simply because there is no reason against having it here, and in addition,\n# creating and moving files from /tmp can sometimes cause problems.\n# Hook for its removal unless debugging.\n# Note that there is a small window in which the directory will not be cleaned:\n# after its creation but before its name has been assigned to `$tmp'.\n$debug ||\n{\n  tmp= ac_tmp=\n  trap 'exit_status=$?\n  : \"${ac_tmp:=$tmp}\"\n  { test ! -d \"$ac_tmp\" || rm -fr \"$ac_tmp\"; } && exit $exit_status\n' 0\n  trap 'as_fn_exit 1' 1 2 13 15\n}\n# Create a (secure) tmp directory for tmp files.\n\n{\n  tmp=`(umask 077 && mktemp -d \"./confXXXXXX\") 2>/dev/null` &&\n  test -d \"$tmp\"\n}  ||\n{\n  tmp=./conf$$-$RANDOM\n  (umask 077 && mkdir \"$tmp\")\n} || as_fn_error $? \"cannot create a temporary directory in .\" \"$LINENO\" 5\nac_tmp=$tmp\n\n# Set up the scripts for CONFIG_FILES section.\n# No need to generate them if there are no CONFIG_FILES.\n# This happens for instance with `./config.status config.h'.\nif test -n \"$CONFIG_FILES\"; then\n\n\nac_cr=`echo X | tr X '\\015'`\n# On cygwin, bash can eat \\r inside `` if the user requested igncr.\n# But we know of no other shell where ac_cr would be empty at this\n# point, so we can use a bashism as a fallback.\nif test \"x$ac_cr\" = x; then\n  eval ac_cr=\\$\\'\\\\r\\'\nfi\nac_cs_awk_cr=`$AWK 'BEGIN { print \"a\\rb\" }' </dev/null 2>/dev/null`\nif test \"$ac_cs_awk_cr\" = \"a${ac_cr}b\"; then\n  ac_cs_awk_cr='\\\\r'\nelse\n  ac_cs_awk_cr=$ac_cr\nfi\n\necho 'BEGIN {' >\"$ac_tmp/subs1.awk\" &&\n_ACEOF\n\n\n{\n  echo \"cat >conf$$subs.awk <<_ACEOF\" &&\n  echo \"$ac_subst_vars\" | sed 's/.*/&!$&$ac_delim/' &&\n  echo \"_ACEOF\"\n} >conf$$subs.sh ||\n  as_fn_error $? \"could not make $CONFIG_STATUS\" \"$LINENO\" 5\nac_delim_num=`echo \"$ac_subst_vars\" | grep -c '^'`\nac_delim='%!_!# '\nfor ac_last_try in false false false false false :; do\n  . ./conf$$subs.sh ||\n    as_fn_error $? \"could not make $CONFIG_STATUS\" \"$LINENO\" 5\n\n  ac_delim_n=`sed -n \"s/.*$ac_delim\\$/X/p\" conf$$subs.awk | grep -c X`\n  if test $ac_delim_n = $ac_delim_num; then\n    break\n  elif $ac_last_try; then\n    as_fn_error $? \"could not make $CONFIG_STATUS\" \"$LINENO\" 5\n  else\n    ac_delim=\"$ac_delim!$ac_delim _$ac_delim!! \"\n  fi\ndone\nrm -f conf$$subs.sh\n\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\ncat >>\"\\$ac_tmp/subs1.awk\" <<\\\\_ACAWK &&\n_ACEOF\nsed -n '\nh\ns/^/S[\"/; s/!.*/\"]=/\np\ng\ns/^[^!]*!//\n:repl\nt repl\ns/'\"$ac_delim\"'$//\nt delim\n:nl\nh\ns/\\(.\\{148\\}\\)..*/\\1/\nt more1\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\\\\n\"\\\\/\np\nn\nb repl\n:more1\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"\\\\/\np\ng\ns/.\\{148\\}//\nt nl\n:delim\nh\ns/\\(.\\{148\\}\\)..*/\\1/\nt more2\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"/\np\nb\n:more2\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"\\\\/\np\ng\ns/.\\{148\\}//\nt delim\n' <conf$$subs.awk | sed '\n/^[^\"\"]/{\n  N\n  s/\\n//\n}\n' >>$CONFIG_STATUS || ac_write_fail=1\nrm -f conf$$subs.awk\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n_ACAWK\ncat >>\"\\$ac_tmp/subs1.awk\" <<_ACAWK &&\n  for (key in S) S_is_set[key] = 1\n  FS = \"\u0007\"\n\n}\n{\n  line = $ 0\n  nfields = split(line, field, \"@\")\n  substed = 0\n  len = length(field[1])\n  for (i = 2; i < nfields; i++) {\n    key = field[i]\n    keylen = length(key)\n    if (S_is_set[key]) {\n      value = S[key]\n      line = substr(line, 1, len) \"\" value \"\" substr(line, len + keylen + 3)\n      len += length(value) + length(field[++i])\n      substed = 1\n    } else\n      len += 1 + keylen\n  }\n\n  print line\n}\n\n_ACAWK\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nif sed \"s/$ac_cr//\" < /dev/null > /dev/null 2>&1; then\n  sed \"s/$ac_cr\\$//; s/$ac_cr/$ac_cs_awk_cr/g\"\nelse\n  cat\nfi < \"$ac_tmp/subs1.awk\" > \"$ac_tmp/subs.awk\" \\\n  || as_fn_error $? \"could not setup config files machinery\" \"$LINENO\" 5\n_ACEOF\n\n# VPATH may cause trouble with some makes, so we remove sole $(srcdir),\n# ${srcdir} and @srcdir@ entries from VPATH if srcdir is \".\", strip leading and\n# trailing colons and then remove the whole line if VPATH becomes empty\n# (actually we leave an empty line to preserve line numbers).\nif test \"x$srcdir\" = x.; then\n  ac_vpsub='/^[\t ]*VPATH[\t ]*=[\t ]*/{\nh\ns///\ns/^/:/\ns/[\t ]*$/:/\ns/:\\$(srcdir):/:/g\ns/:\\${srcdir}:/:/g\ns/:@srcdir@:/:/g\ns/^:*//\ns/:*$//\nx\ns/\\(=[\t ]*\\).*/\\1/\nG\ns/\\n//\ns/^[^=]*=[\t ]*$//\n}'\nfi\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nfi # test -n \"$CONFIG_FILES\"\n\n# Set up the scripts for CONFIG_HEADERS section.\n# No need to generate them if there are no CONFIG_HEADERS.\n# This happens for instance with `./config.status Makefile'.\nif test -n \"$CONFIG_HEADERS\"; then\ncat >\"$ac_tmp/defines.awk\" <<\\_ACAWK ||\nBEGIN {\n_ACEOF\n\n# Transform confdefs.h into an awk script `defines.awk', embedded as\n# here-document in config.status, that substitutes the proper values into\n# config.h.in to produce config.h.\n\n# Create a delimiter string that does not exist in confdefs.h, to ease\n# handling of long lines.\nac_delim='%!_!# '\nfor ac_last_try in false false :; do\n  ac_tt=`sed -n \"/$ac_delim/p\" confdefs.h`\n  if test -z \"$ac_tt\"; then\n    break\n  elif $ac_last_try; then\n    as_fn_error $? \"could not make $CONFIG_HEADERS\" \"$LINENO\" 5\n  else\n    ac_delim=\"$ac_delim!$ac_delim _$ac_delim!! \"\n  fi\ndone\n\n# For the awk script, D is an array of macro values keyed by name,\n# likewise P contains macro parameters if any.  Preserve backslash\n# newline sequences.\n\nac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*\nsed -n '\ns/.\\{148\\}/&'\"$ac_delim\"'/g\nt rset\n:rset\ns/^[\t ]*#[\t ]*define[\t ][\t ]*/ /\nt def\nd\n:def\ns/\\\\$//\nt bsnl\ns/[\"\\\\]/\\\\&/g\ns/^ \\('\"$ac_word_re\"'\\)\\(([^()]*)\\)[\t ]*\\(.*\\)/P[\"\\1\"]=\"\\2\"\\\nD[\"\\1\"]=\" \\3\"/p\ns/^ \\('\"$ac_word_re\"'\\)[\t ]*\\(.*\\)/D[\"\\1\"]=\" \\2\"/p\nd\n:bsnl\ns/[\"\\\\]/\\\\&/g\ns/^ \\('\"$ac_word_re\"'\\)\\(([^()]*)\\)[\t ]*\\(.*\\)/P[\"\\1\"]=\"\\2\"\\\nD[\"\\1\"]=\" \\3\\\\\\\\\\\\n\"\\\\/p\nt cont\ns/^ \\('\"$ac_word_re\"'\\)[\t ]*\\(.*\\)/D[\"\\1\"]=\" \\2\\\\\\\\\\\\n\"\\\\/p\nt cont\nd\n:cont\nn\ns/.\\{148\\}/&'\"$ac_delim\"'/g\nt clear\n:clear\ns/\\\\$//\nt bsnlc\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"/p\nd\n:bsnlc\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\\\\\\\\\\\\n\"\\\\/p\nb cont\n' <confdefs.h | sed '\ns/'\"$ac_delim\"'/\"\\\\\\\n\"/g' >>$CONFIG_STATUS || ac_write_fail=1\n\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n  for (key in D) D_is_set[key] = 1\n  FS = \"\u0007\"\n}\n/^[\\t ]*#[\\t ]*(define|undef)[\\t ]+$ac_word_re([\\t (]|\\$)/ {\n  line = \\$ 0\n  split(line, arg, \" \")\n  if (arg[1] == \"#\") {\n    defundef = arg[2]\n    mac1 = arg[3]\n  } else {\n    defundef = substr(arg[1], 2)\n    mac1 = arg[2]\n  }\n  split(mac1, mac2, \"(\") #)\n  macro = mac2[1]\n  prefix = substr(line, 1, index(line, defundef) - 1)\n  if (D_is_set[macro]) {\n    # Preserve the white space surrounding the \"#\".\n    print prefix \"define\", macro P[macro] D[macro]\n    next\n  } else {\n    # Replace #undef with comments.  This is necessary, for example,\n    # in the case of _POSIX_SOURCE, which is predefined and required\n    # on some systems where configure will not decide to define it.\n    if (defundef == \"undef\") {\n      print \"/*\", prefix defundef, macro, \"*/\"\n      next\n    }\n  }\n}\n{ print }\n_ACAWK\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n  as_fn_error $? \"could not setup config headers machinery\" \"$LINENO\" 5\nfi # test -n \"$CONFIG_HEADERS\"\n\n\neval set X \"  :F $CONFIG_FILES  :H $CONFIG_HEADERS    \"\nshift\nfor ac_tag\ndo\n  case $ac_tag in\n  :[FHLC]) ac_mode=$ac_tag; continue;;\n  esac\n  case $ac_mode$ac_tag in\n  :[FHL]*:*);;\n  :L* | :C*:*) as_fn_error $? \"invalid tag \\`$ac_tag'\" \"$LINENO\" 5;;\n  :[FH]-) ac_tag=-:-;;\n  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;\n  esac\n  ac_save_IFS=$IFS\n  IFS=:\n  set x $ac_tag\n  IFS=$ac_save_IFS\n  shift\n  ac_file=$1\n  shift\n\n  case $ac_mode in\n  :L) ac_source=$1;;\n  :[FH])\n    ac_file_inputs=\n    for ac_f\n    do\n      case $ac_f in\n      -) ac_f=\"$ac_tmp/stdin\";;\n      *) # Look for the file first in the build tree, then in the source tree\n\t # (if the path is not absolute).  The absolute path cannot be DOS-style,\n\t # because $ac_f cannot contain `:'.\n\t test -f \"$ac_f\" ||\n\t   case $ac_f in\n\t   [\\\\/$]*) false;;\n\t   *) test -f \"$srcdir/$ac_f\" && ac_f=\"$srcdir/$ac_f\";;\n\t   esac ||\n\t   as_fn_error 1 \"cannot find input file: \\`$ac_f'\" \"$LINENO\" 5;;\n      esac\n      case $ac_f in *\\'*) ac_f=`$as_echo \"$ac_f\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;; esac\n      as_fn_append ac_file_inputs \" '$ac_f'\"\n    done\n\n    # Let's still pretend it is `configure' which instantiates (i.e., don't\n    # use $as_me), people would be surprised to read:\n    #    /* config.h.  Generated by config.status.  */\n    configure_input='Generated from '`\n\t  $as_echo \"$*\" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'\n\t`' by configure.'\n    if test x\"$ac_file\" != x-; then\n      configure_input=\"$ac_file.  $configure_input\"\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: creating $ac_file\" >&5\n$as_echo \"$as_me: creating $ac_file\" >&6;}\n    fi\n    # Neutralize special characters interpreted by sed in replacement strings.\n    case $configure_input in #(\n    *\\&* | *\\|* | *\\\\* )\n       ac_sed_conf_input=`$as_echo \"$configure_input\" |\n       sed 's/[\\\\\\\\&|]/\\\\\\\\&/g'`;; #(\n    *) ac_sed_conf_input=$configure_input;;\n    esac\n\n    case $ac_tag in\n    *:-:* | *:-) cat >\"$ac_tmp/stdin\" \\\n      || as_fn_error $? \"could not create $ac_file\" \"$LINENO\" 5 ;;\n    esac\n    ;;\n  esac\n\n  ac_dir=`$as_dirname -- \"$ac_file\" ||\n$as_expr X\"$ac_file\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)$' \\| \\\n\t X\"$ac_file\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$ac_file\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n  as_dir=\"$ac_dir\"; as_fn_mkdir_p\n  ac_builddir=.\n\ncase \"$ac_dir\" in\n.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;\n*)\n  ac_dir_suffix=/`$as_echo \"$ac_dir\" | sed 's|^\\.[\\\\/]||'`\n  # A \"..\" for each directory in $ac_dir_suffix.\n  ac_top_builddir_sub=`$as_echo \"$ac_dir_suffix\" | sed 's|/[^\\\\/]*|/..|g;s|/||'`\n  case $ac_top_builddir_sub in\n  \"\") ac_top_builddir_sub=. ac_top_build_prefix= ;;\n  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;\n  esac ;;\nesac\nac_abs_top_builddir=$ac_pwd\nac_abs_builddir=$ac_pwd$ac_dir_suffix\n# for backward compatibility:\nac_top_builddir=$ac_top_build_prefix\n\ncase $srcdir in\n  .)  # We are building in place.\n    ac_srcdir=.\n    ac_top_srcdir=$ac_top_builddir_sub\n    ac_abs_top_srcdir=$ac_pwd ;;\n  [\\\\/]* | ?:[\\\\/]* )  # Absolute name.\n    ac_srcdir=$srcdir$ac_dir_suffix;\n    ac_top_srcdir=$srcdir\n    ac_abs_top_srcdir=$srcdir ;;\n  *) # Relative name.\n    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix\n    ac_top_srcdir=$ac_top_build_prefix$srcdir\n    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;\nesac\nac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix\n\n\n  case $ac_mode in\n  :F)\n  #\n  # CONFIG_FILE\n  #\n\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n# If the template does not know about datarootdir, expand it.\n# FIXME: This hack should be removed a few years after 2.60.\nac_datarootdir_hack=; ac_datarootdir_seen=\nac_sed_dataroot='\n/datarootdir/ {\n  p\n  q\n}\n/@datadir@/p\n/@docdir@/p\n/@infodir@/p\n/@localedir@/p\n/@mandir@/p'\ncase `eval \"sed -n \\\"\\$ac_sed_dataroot\\\" $ac_file_inputs\"` in\n*datarootdir*) ac_datarootdir_seen=yes;;\n*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting\" >&5\n$as_echo \"$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting\" >&2;}\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n  ac_datarootdir_hack='\n  s&@datadir@&$datadir&g\n  s&@docdir@&$docdir&g\n  s&@infodir@&$infodir&g\n  s&@localedir@&$localedir&g\n  s&@mandir@&$mandir&g\n  s&\\\\\\${datarootdir}&$datarootdir&g' ;;\nesac\n_ACEOF\n\n# Neutralize VPATH when `$srcdir' = `.'.\n# Shell code in configure.ac might set extrasub.\n# FIXME: do we really want to maintain this feature?\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\nac_sed_extra=\"$ac_vpsub\n$extrasub\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n:t\n/@[a-zA-Z_][a-zA-Z_0-9]*@/!b\ns|@configure_input@|$ac_sed_conf_input|;t t\ns&@top_builddir@&$ac_top_builddir_sub&;t t\ns&@top_build_prefix@&$ac_top_build_prefix&;t t\ns&@srcdir@&$ac_srcdir&;t t\ns&@abs_srcdir@&$ac_abs_srcdir&;t t\ns&@top_srcdir@&$ac_top_srcdir&;t t\ns&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t\ns&@builddir@&$ac_builddir&;t t\ns&@abs_builddir@&$ac_abs_builddir&;t t\ns&@abs_top_builddir@&$ac_abs_top_builddir&;t t\n$ac_datarootdir_hack\n\"\neval sed \\\"\\$ac_sed_extra\\\" \"$ac_file_inputs\" | $AWK -f \"$ac_tmp/subs.awk\" \\\n  >$ac_tmp/out || as_fn_error $? \"could not create $ac_file\" \"$LINENO\" 5\n\ntest -z \"$ac_datarootdir_hack$ac_datarootdir_seen\" &&\n  { ac_out=`sed -n '/\\${datarootdir}/p' \"$ac_tmp/out\"`; test -n \"$ac_out\"; } &&\n  { ac_out=`sed -n '/^[\t ]*datarootdir[\t ]*:*=/p' \\\n      \"$ac_tmp/out\"`; test -z \"$ac_out\"; } &&\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \\`datarootdir'\nwhich seems to be undefined.  Please make sure it is defined\" >&5\n$as_echo \"$as_me: WARNING: $ac_file contains a reference to the variable \\`datarootdir'\nwhich seems to be undefined.  Please make sure it is defined\" >&2;}\n\n  rm -f \"$ac_tmp/stdin\"\n  case $ac_file in\n  -) cat \"$ac_tmp/out\" && rm -f \"$ac_tmp/out\";;\n  *) rm -f \"$ac_file\" && mv \"$ac_tmp/out\" \"$ac_file\";;\n  esac \\\n  || as_fn_error $? \"could not create $ac_file\" \"$LINENO\" 5\n ;;\n  :H)\n  #\n  # CONFIG_HEADER\n  #\n  if test x\"$ac_file\" != x-; then\n    {\n      $as_echo \"/* $configure_input  */\" \\\n      && eval '$AWK -f \"$ac_tmp/defines.awk\"' \"$ac_file_inputs\"\n    } >\"$ac_tmp/config.h\" \\\n      || as_fn_error $? \"could not create $ac_file\" \"$LINENO\" 5\n    if diff \"$ac_file\" \"$ac_tmp/config.h\" >/dev/null 2>&1; then\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: $ac_file is unchanged\" >&5\n$as_echo \"$as_me: $ac_file is unchanged\" >&6;}\n    else\n      rm -f \"$ac_file\"\n      mv \"$ac_tmp/config.h\" \"$ac_file\" \\\n\t|| as_fn_error $? \"could not create $ac_file\" \"$LINENO\" 5\n    fi\n  else\n    $as_echo \"/* $configure_input  */\" \\\n      && eval '$AWK -f \"$ac_tmp/defines.awk\"' \"$ac_file_inputs\" \\\n      || as_fn_error $? \"could not create -\" \"$LINENO\" 5\n  fi\n ;;\n\n\n  esac\n\ndone # for ac_tag\n\n\nas_fn_exit 0\n_ACEOF\nac_clean_files=$ac_clean_files_save\n\ntest $ac_write_fail = 0 ||\n  as_fn_error $? \"write failure creating $CONFIG_STATUS\" \"$LINENO\" 5\n\n\n# configure is writing to config.log, and then calls config.status.\n# config.status does its own redirection, appending to config.log.\n# Unfortunately, on DOS this fails, as config.log is still kept open\n# by configure, so config.status won't be able to write to it; its\n# output is simply discarded.  So we exec the FD to /dev/null,\n# effectively closing config.log, so it can be properly (re)opened and\n# appended to by config.status.  When coming back to configure, we\n# need to make the FD available again.\nif test \"$no_create\" != yes; then\n  ac_cs_success=:\n  ac_config_status_args=\n  test \"$silent\" = yes &&\n    ac_config_status_args=\"$ac_config_status_args --quiet\"\n  exec 5>/dev/null\n  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false\n  exec 5>>config.log\n  # Use ||, not &&, to avoid exiting from the if with $? = 1, which\n  # would make configure fail if this is the last instruction.\n  $ac_cs_success || as_fn_exit 1\nfi\nif test -n \"$ac_unrecognized_opts\" && test \"$enable_option_checking\" != no; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts\" >&5\n$as_echo \"$as_me: WARNING: unrecognized options: $ac_unrecognized_opts\" >&2;}\nfi\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result:\n\nConfigurations for current target have been written to 'build.mak', and 'os-auto.mak' in various build directories, and pjlib/include/pj/compat/os_auto.h.\n\nFurther customizations can be put in:\n  - 'user.mak'\n  - 'pjlib/include/pj/config_site.h'\n\nThe next step now is to run 'make dep' and 'make'.\n\" >&5\n$as_echo \"\n\nConfigurations for current target have been written to 'build.mak', and 'os-auto.mak' in various build directories, and pjlib/include/pj/compat/os_auto.h.\n\nFurther customizations can be put in:\n  - 'user.mak'\n  - 'pjlib/include/pj/config_site.h'\n\nThe next step now is to run 'make dep' and 'make'.\n\" >&6; }\n\n"
  },
  {
    "path": "deps/pjsip/aconfigure.ac",
    "content": "AC_INIT(pjproject,2.x)\n\nhost_orig=\"$host\"\n\nAC_CANONICAL_BUILD\nAC_CANONICAL_HOST\nAC_CANONICAL_TARGET\nAC_CONFIG_HEADER([pjlib/include/pj/compat/os_auto.h\n\t\t  pjlib/include/pj/compat/m_auto.h\n\t\t  pjmedia/include/pjmedia/config_auto.h\n\t\t  pjmedia/include/pjmedia-codec/config_auto.h\n\t\t  pjsip/include/pjsip/sip_autoconf.h\n\t\t ])\nAC_CONFIG_FILES([build.mak \n\t\t build/os-auto.mak \n\t\t build/cc-auto.mak\n\t\t pjlib/build/os-auto.mak \n\t\t pjmedia/build/os-auto.mak\n\t\t pjsip/build/os-auto.mak\n \t\t third_party/build/webrtc/os-auto.mak\n\t\t third_party/build/os-auto.mak\n\t\t ])\n\n\ndnl\ndnl Setup default CFLAGS\ndnl\nif test \"$CFLAGS\" = \"\"; then\n  CFLAGS=\"-O2\"\nelse\n  CFLAGS=\"$CFLAGS\"\nfi\n\nCXXFLAGS=\"$CFLAGS $CXXFLAGS\"\n\ndnl #\ndnl # Configure tools\ndnl #\nAC_PROG_CC\nAC_PROG_CXX\nAC_LANG_C\n\nAC_PROG_RANLIB\nAC_CHECK_TOOLS([AR], [ar gar], :)\n\nif test \"$AR_FLAGS\" = \"\"; then AR_FLAGS=\"rv\"; fi\nAC_SUBST(AR_FLAGS)\nif test \"$LD\" = \"\"; then LD=\"$CC\"; fi\nAC_SUBST(LD)\nif test \"$LDOUT\" = \"\"; then LDOUT=\"-o \"; fi\nAC_SUBST(LDOUT)\nif test \"$OBJEXT\" = \"\"; then OBJEXT='o'; fi\nAC_SUBST(OBJEXT)\nif test \"$LIBEXT\" = \"\"; then LIBEXT='a'; fi\nAC_SUBST(LIBEXT)\nif test \"$LIBEXT2\" = \"\"; then LIBEXT2=\"\"; fi\nAC_SUBST(LIBEXT2)\nif test \"$CC_OUT\" = \"\"; then CC_OUT=\"-o \"; fi\nAC_SUBST(CC_OUT)\nif test \"$CC_INC\" = \"\"; then CC_INC=\"-I\"; fi\nAC_SUBST(CC_INC)\nif test \"$CC_DEF\" = \"\"; then CC_DEF=\"-D\"; fi\nAC_SUBST(CC_DEF)\nif test \"$CC_OPTIMIZE\" = \"\"; then CC_OPTIMIZE=\"-O2\"; fi\nAC_SUBST(CC_OPTIMIZE)\nif test \"$CC_CFLAGS\" = \"\"; then CC_CFLAGS=\"-Wall\"; fi\nAC_SUBST(CC_CFLAGS)\n\n\n\nAC_SUBST(ac_pjdir)\nAC_SUBST(ac_build_mak_vars)\n\ncase $host in \n    *mingw* | *cygw* | *win32* | *w32* )\n\tif pwd -W 2&> /dev/null; then\n\t   ac_pjdir=`pwd -W`\n\telse\n\t   # We're probably cross-compiling mingw on Linux\n\t   ac_pjdir=`pwd`\n\tfi\n\t;;\n    *)\n\tac_pjdir=`pwd`\n\t;;\nesac\n\nAC_SUBST(ac_shlib_suffix)\ncase $target in\n    *mingw* | *cygw* | *win32* | *w32* )\n\tac_shlib_suffix=dll\n\t;;\n    *darwin*)\n\tac_shlib_suffix=dylib\n\t;;\n    *)\n\tac_shlib_suffix=so\n\t;;\nesac\n\nAC_SUBST(ac_cross_compile)\nif test \"$build\" = \"$host\"; then\n    ac_cross_compile=\nelse\n    ac_cross_compile=${host_orig}-\nfi\n\nAC_CHECK_LIB(pthread,pthread_create)\nAC_CHECK_LIB(wsock32,puts)\nAC_CHECK_LIB(ws2_32,puts)\nAC_CHECK_LIB(ole32,puts)\nAC_CHECK_LIB(winmm,puts)\nAC_CHECK_LIB(socket,puts)\nAC_CHECK_LIB(rt,puts)\nAC_CHECK_LIB(m,sin)\nAC_CHECK_LIB(uuid,uuid_generate)\nAC_CHECK_LIB(uuid,uuid_generate,[ac_has_uuid_lib=1])\nAC_SEARCH_LIBS(gethostbyname,nsl)\n\nAC_MSG_RESULT([Setting PJ_M_NAME to $target_cpu])\nAC_DEFINE_UNQUOTED(PJ_M_NAME,[\"$target_cpu\"])\n\ndnl\ndnl Memory alignment detection\ndnl\nAC_MSG_CHECKING([memory alignment])\ncase $target in\n    sparc64-* | ia64-* | x86_64-* )\n\tAC_DEFINE(PJ_POOL_ALIGNMENT, 8)\n\tAC_MSG_RESULT([8 bytes])\n\t;;\n    * )\n\tAC_DEFINE(PJ_POOL_ALIGNMENT, 4)\n\tAC_MSG_RESULT([4 bytes (default)])\n\t;;\nesac\n\n\ndnl\ndnl Endianness detection\ndnl\nAC_C_BIGENDIAN\n\nif test \"x$ac_cv_c_bigendian\" = \"xyes\"; then\n  CFLAGS=\"$CFLAGS -DPJ_IS_BIG_ENDIAN=1 -DPJ_IS_LITTLE_ENDIAN=0\"\nelse\n  CFLAGS=\"$CFLAGS -DPJ_IS_BIG_ENDIAN=0 -DPJ_IS_LITTLE_ENDIAN=1\"\nfi\n\ndnl\ndnl Legacy macros\ndnl\ncase $target in\n    *android*)\n\tAC_DEFINE(PJ_ANDROID,1)\n\t;;\n    *mingw* | *cygw* | *win32* | *w32* )\n\tAC_DEFINE(PJ_WIN32,1)\n\tAC_DEFINE(PJ_WIN32_WINNT,0x0400)\n\tAC_DEFINE(WIN32_LEAN_AND_MEAN)\n\t;;\n    *darwin*)\n\tAC_DEFINE(PJ_DARWINOS,1)\n\t;;\n    *linux*)\n\tAC_DEFINE(PJ_LINUX,1)\n\t;;\n    *rtems*)\n\tAC_DEFINE(PJ_RTEMS,1)\n\t;;\n    *sunos* | *solaris* )\n\tAC_DEFINE(PJ_SUNOS,1)\n\t;;\n    *)\n\t;;\nesac\n\n\n\nAC_CHECK_HEADER(arpa/inet.h,[AC_DEFINE(PJ_HAS_ARPA_INET_H,1)])\nAC_CHECK_HEADER(assert.h,[AC_DEFINE(PJ_HAS_ASSERT_H,1)])\nAC_CHECK_HEADER(ctype.h,[AC_DEFINE(PJ_HAS_CTYPE_H,1)])\n\ncase $target in\n    *mingw* | *cygw* | *win32* | *w32* )\n\tAC_DEFINE(PJ_HAS_ERRNO_H,0)\n\t;;\n    *)\n\tAC_CHECK_HEADER(errno.h,[AC_DEFINE(PJ_HAS_ERRNO_H,1)])\n\t;;\nesac\n\nAC_CHECK_HEADER(fcntl.h,[AC_DEFINE(PJ_HAS_FCNTL_H,1)])\nAC_CHECK_HEADER(linux/socket.h,[AC_DEFINE(PJ_HAS_LINUX_SOCKET_H,1)])\nAC_CHECK_HEADER(limits.h,[AC_DEFINE(PJ_HAS_LIMITS_H,1)])\nAC_CHECK_HEADER(malloc.h,[AC_DEFINE(PJ_HAS_MALLOC_H,1)])\nAC_CHECK_HEADER(netdb.h,[AC_DEFINE(PJ_HAS_NETDB_H,1)])\nAC_CHECK_HEADER(netinet/in_systm.h,[AC_DEFINE(PJ_HAS_NETINET_IN_SYSTM_H,1)])\nAC_CHECK_HEADER(netinet/in.h,[AC_DEFINE(PJ_HAS_NETINET_IN_H,1)])\nAC_CHECK_HEADER(netinet/ip.h,[AC_DEFINE(PJ_HAS_NETINET_IP_H,1)],[],\n\t\t [#if PJ_HAS_SYS_TYPES_H\n          \t  #\tinclude <sys/types.h>\n          \t  #endif\n\t\t  #if PJ_HAS_NETINET_IN_SYSTM_H\n          \t  #\tinclude <netinet/in_systm.h>\n          \t  #endif\n\t\t  #if PJ_HAS_NETINET_IN_H\n          \t  #\tinclude <netinet/in.h>\n          \t  #endif\n          \t ])\nAC_CHECK_HEADER(netinet/tcp.h,[AC_DEFINE(PJ_HAS_NETINET_TCP_H,1)])\nAC_CHECK_HEADER(ifaddrs.h,\n\t\t[AC_CHECK_FUNC(getifaddrs,[AC_DEFINE(PJ_HAS_IFADDRS_H,1)])])\nAC_CHECK_HEADER(semaphore.h,[AC_DEFINE(PJ_HAS_SEMAPHORE_H,1)])\nAC_CHECK_HEADER(setjmp.h,[AC_DEFINE(PJ_HAS_SETJMP_H,1)])\nAC_CHECK_HEADER(stdarg.h,[AC_DEFINE(PJ_HAS_STDARG_H,1)])\nAC_CHECK_HEADER(stddef.h,[AC_DEFINE(PJ_HAS_STDDEF_H,1)])\nAC_CHECK_HEADER(stdio.h,[AC_DEFINE(PJ_HAS_STDIO_H,1)])\nAC_CHECK_HEADER(stdint.h,[AC_DEFINE(PJ_HAS_STDINT_H,1)])\nAC_CHECK_HEADER(stdlib.h,[AC_DEFINE(PJ_HAS_STDLIB_H,1)])\nAC_CHECK_HEADER(string.h,[AC_DEFINE(PJ_HAS_STRING_H,1)])\nAC_CHECK_HEADER(sys/ioctl.h,[AC_DEFINE(PJ_HAS_SYS_IOCTL_H,1)])\nAC_CHECK_HEADER(sys/select.h,[AC_DEFINE(PJ_HAS_SYS_SELECT_H,1)])\nAC_CHECK_HEADER(sys/socket.h,[AC_DEFINE(PJ_HAS_SYS_SOCKET_H,1)])\nAC_CHECK_HEADER(sys/time.h,[AC_DEFINE(PJ_HAS_SYS_TIME_H,1)])\nAC_CHECK_HEADER(sys/timeb.h,[AC_DEFINE(PJ_HAS_SYS_TIMEB_H,1)])\nAC_CHECK_HEADER(sys/types.h,[AC_DEFINE(PJ_HAS_SYS_TYPES_H,1)])\nAC_CHECK_HEADER(sys/filio.h,[AC_DEFINE(PJ_HAS_SYS_FILIO_H,1)])\nAC_CHECK_HEADER(sys/sockio.h,[AC_DEFINE(PJ_HAS_SYS_SOCKIO_H,1)])\nAC_CHECK_HEADER(sys/utsname.h,[AC_DEFINE(PJ_HAS_SYS_UTSNAME_H,1)])\nAC_CHECK_HEADER(time.h,[AC_DEFINE(PJ_HAS_TIME_H,1)])\nAC_CHECK_HEADER(unistd.h,[AC_DEFINE(PJ_HAS_UNISTD_H,1)])\nAC_CHECK_HEADER(winsock.h,[AC_DEFINE(PJ_HAS_WINSOCK_H,1)])\nAC_CHECK_HEADER(winsock2.h,[AC_DEFINE(PJ_HAS_WINSOCK2_H,1)])\nAC_CHECK_HEADER(mswsock.h,[AC_DEFINE(PJ_HAS_MSWSOCK_H,1)],[],\n\t\t [#if PJ_HAS_WINSOCK2_H\n          \t  #\tinclude <winsock2.h>\n\t\t  #elif PJ_HAS_WINSOCK_H\n          \t  #\tinclude <winsock.h>\n          \t  #endif\n          \t ])\nAC_CHECK_HEADER(ws2tcpip.h,[AC_DEFINE(PJ_HAS_WS2TCPIP_H,1)])\nAC_CHECK_HEADER(uuid/uuid.h,[ac_has_uuid_h=1])\nAC_CHECK_HEADER(net/if.h,[AC_DEFINE(PJ_HAS_NET_IF_H,1)],[],\n\t\t [#if PJ_HAS_SYS_TYPES_H\n          \t  #\tinclude <sys/types.h>\n          \t  #endif\n\t\t  #if PJ_HAS_SYS_SOCKET_H\n\n          \t  #\tinclude <sys/socket.h>\n          \t  #endif\n          \t ])\nAC_MSG_RESULT([Setting PJ_OS_NAME to $target])\nAC_DEFINE_UNQUOTED(PJ_OS_NAME,[\"$target\"])\n\nAC_MSG_RESULT([Setting PJ_HAS_ERRNO_VAR to 1])\nAC_DEFINE(PJ_HAS_ERRNO_VAR,1)\n\nAC_MSG_RESULT([Setting PJ_HAS_HIGH_RES_TIMER to 1])\nAC_DEFINE(PJ_HAS_HIGH_RES_TIMER,1)\n\nAC_MSG_RESULT([Setting PJ_HAS_MALLOC to 1])\nAC_DEFINE(PJ_HAS_MALLOC,1)\n\nAC_MSG_RESULT([Setting PJ_NATIVE_STRING_IS_UNICODE to 0])\nAC_DEFINE(PJ_NATIVE_STRING_IS_UNICODE,0)\n\nAC_MSG_RESULT([Setting PJ_ATOMIC_VALUE_TYPE to long])\nAC_DEFINE(PJ_ATOMIC_VALUE_TYPE,long)\n\ndnl # Determine if inet_aton() is available\nAC_MSG_CHECKING([if inet_aton() is available])\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>\n\t\t\t\t     #include <sys/socket.h>\n\t\t\t\t     #include <arpa/inet.h>]],\n\t\t    \t\t  [inet_aton(0, 0);])],\n\t\t  [AC_DEFINE(PJ_SOCK_HAS_INET_ATON,1)\n\t\t   AC_MSG_RESULT(yes)],\n\t\t  [AC_MSG_RESULT(no)])\n\ndnl # Determine if inet_pton() is available\nAC_MSG_CHECKING([if inet_pton() is available])\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>\n\t\t\t\t     #include <sys/socket.h>\n\t\t\t\t     #include <arpa/inet.h>]],\n\t\t    \t\t  [inet_pton(0, 0, 0);])],\n\t\t  [AC_DEFINE(PJ_SOCK_HAS_INET_PTON,1)\n\t\t   AC_MSG_RESULT(yes)],\n\t\t  [AC_MSG_RESULT(no)])\n\ndnl # Determine if inet_ntop() is available\nAC_MSG_CHECKING([if inet_ntop() is available])\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>\n\t\t\t\t     #include <sys/socket.h>\n\t\t\t\t     #include <arpa/inet.h>]],\n\t\t    \t\t  [inet_ntop(0, 0, 0, 0);])],\n\t\t  [AC_DEFINE(PJ_SOCK_HAS_INET_NTOP,1)\n\t\t   AC_MSG_RESULT(yes)],\n\t\t  [AC_MSG_RESULT(no)])\n\ndnl # Determine if getaddrinfo() is available\nAC_MSG_CHECKING([if getaddrinfo() is available])\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>\n\t\t\t\t     #include <sys/socket.h>\n\t\t\t\t     #include <netdb.h>]],\n\t\t    \t\t  [getaddrinfo(0, 0, 0, 0);])],\n\t\t  [AC_DEFINE(PJ_SOCK_HAS_GETADDRINFO,1)\n\t\t   AC_MSG_RESULT(yes)],\n\t\t  [AC_MSG_RESULT(no)])\n\ndnl # Determine if sockaddr_in has sin_len member\nAC_MSG_CHECKING([if sockaddr_in has sin_len member])\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>\n\t\t\t\t     #include <sys/socket.h>\n\t\t    \t\t     #include <netinet/in.h>\n\t\t    \t\t     #include <arpa/inet.h>]],\n\t\t    \t\t  [struct sockaddr_in a; a.sin_len=0;])],\n\t\t  [AC_DEFINE(PJ_SOCKADDR_HAS_LEN,1)\n\t\t   AC_MSG_RESULT(yes)],\n\t\t  AC_MSG_RESULT(no))\n\ndnl # Determine if socklen_t is available\nAC_MSG_CHECKING([if socklen_t is available])\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>\n                                     #include <sys/socket.h>]],\n\t\t    \t\t   [socklen_t xxx = 0;])],\n\t\t  [AC_DEFINE(PJ_HAS_SOCKLEN_T,1)\n\t\t   AC_MSG_RESULT(yes)],\n\t\t  AC_MSG_RESULT(no))\n\ndnl # Determine if SO_ERROR is available\nAC_MSG_CHECKING([if SO_ERROR is available])\ncase $target in\n    *mingw* | *cygw* | *win32* | *w32* )\n\tAC_DEFINE(PJ_HAS_SO_ERROR,1)\n\tAC_MSG_RESULT(yes)\n\t;;\n    *)\n\tAC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>\n\t\t\t\t\t     #include <sys/socket.h>\n\t\t\t\t\t     #include <netinet/in.h>\n\t\t\t\t\t     #include <arpa/inet.h>]],\n\t\t\t\t\t  [int i=SO_ERROR;])],\n\t\t\t  [AC_DEFINE(PJ_HAS_SO_ERROR,1)\n\t\t\t   AC_MSG_RESULT(yes)],\n\t\t\t  AC_MSG_RESULT(no))\n\t;;\nesac\n\n\ndnl # Determine if RW-mutex is available\nAC_MSG_CHECKING([if pthread_rwlock_t is available])\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],\n\t\t    \t\t   [pthread_rwlock_t *x;])],\n\t\t  [AC_DEFINE(PJ_EMULATE_RWMUTEX,0)\n\t\t   ac_rwmutex=\"yes\"\n  \t\t   AC_MSG_RESULT(yes)],\n\t\t  [AC_DEFINE(PJ_EMULATE_RWMUTEX,1)\n\t\t   ac_rwmutex=\"no\"\n\t\t   AC_MSG_RESULT(no)])\n\ndnl # If rwmutex is not detected, check again but this time\ndnl # with _POSIX_READER_WRITER_LOCKS defined (newlib needs this)\nif test \"$ac_rwmutex\" = \"no\"; then\n    AC_MSG_CHECKING([if pthread_rwlock_t is available with _POSIX_READER_WRITER_LOCKS])\n    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#define _POSIX_READER_WRITER_LOCKS\n\t\t\t\t\t #include <pthread.h>]],\n\t\t\t\t       [pthread_rwlock_t *x;])],\n\t\t      [AC_DEFINE(PJ_EMULATE_RWMUTEX,0)\n\t\t       CFLAGS=\"$CFLAGS -D_POSIX_THREADS -D_POSIX_READER_WRITER_LOCKS\"\n\t\t       AC_MSG_RESULT(yes)],\n\t\t      [AC_DEFINE(PJ_EMULATE_RWMUTEX,1)\n\t\t       AC_MSG_RESULT(no)])\nfi\n\ndnl # Do we have pthread_mutexattr_settype()?\nAC_MSG_CHECKING([if pthread_mutexattr_settype() is available])\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],\n\t\t    \t\t   [pthread_mutexattr_settype(0,PTHREAD_MUTEX_FAST_NP);])],\n\t\t  [AC_DEFINE(PJ_HAS_PTHREAD_MUTEXATTR_SETTYPE,1)\n  \t\t   AC_MSG_RESULT(yes)],\n\t\t  [AC_MSG_RESULT(no)])\n\ndnl # Does pthread_mutexattr_t has \"recursive\" member?\nAC_MSG_CHECKING([if pthread_mutexattr_t has recursive member])\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],\n\t\t    \t\t   [[pthread_mutexattr_t attr;\n\t\t\t\t     attr.recursive=1;]])],\n\t\t  [AC_DEFINE(PJ_PTHREAD_MUTEXATTR_T_HAS_RECURSIVE,1)\n  \t\t   AC_MSG_RESULT(yes)],\n\t\t  [AC_MSG_RESULT(no)])\n\ndnl ######################\ndnl # ioqueue selection\ndnl # \nAC_SUBST(ac_os_objs)\nAC_SUBST(ac_linux_poll)\nAC_MSG_CHECKING([ioqueue backend])\nAC_ARG_ENABLE(epoll,\n\t      AC_HELP_STRING([--enable-epoll],\n\t\t\t     [Use /dev/epoll ioqueue on Linux (experimental)]),\n\t      [\n\t\tac_os_objs=ioqueue_epoll.o\n\t\tAC_MSG_RESULT([/dev/epoll])\n\t\tAC_DEFINE(PJ_HAS_LINUX_EPOLL,1)\n\t\tac_linux_poll=epoll\n\t      ],\n\t      [\n\t\tac_os_objs=ioqueue_select.o\n\t\tAC_MSG_RESULT([select()])\n\t\tac_linux_poll=select\n\t      ])\n\n\ndnl ######################\ndnl # OS specific files\ndnl #\ncase $target in\n  *mingw* | *cygw* | *win32* | *w32* )\n\tac_os_objs=\"$ac_os_objs file_access_win32.o file_io_win32.o os_core_win32.o os_error_win32.o os_time_win32.o os_timestamp_win32.o guid_win32.o\"\n\t;;\n  *)\n\tac_os_objs=\"$ac_os_objs file_access_unistd.o file_io_ansi.o os_core_unix.o os_error_unix.o os_time_unix.o os_timestamp_posix.o\"\n\tcase $target in\n\t  arm-apple-darwin*)\n\t\tac_os_objs=\"$ac_os_objs os_info_iphone.o\"\n\t\t;;\n\tesac\n\t# UUID\n\tif test \"$ac_has_uuid_lib\" = \"1\" -a \"$ac_has_uuid_h\" = \"1\"; then\n\t\tac_os_objs=\"$ac_os_objs guid_uuid.o\"\n\telse\n\t\tac_os_objs=\"$ac_os_objs guid_simple.o\"\n\tfi\n\t;;\nesac\n\ncase $target in\n  *darwin*)\n\tac_os_objs=\"$ac_os_objs os_core_darwin.o\"\n\t;;\nesac\n\ndnl ##########################################\ndnl #\ndnl # PJMEDIA\ndnl #\n\n\nAC_SUBST(ac_pjmedia_audiodev_objs)\ncase $target in\n *android*)\n       LIBS=\"$LIBS -lOpenSLES\"\n       AC_MSG_RESULT([Checking sound device backend... OpenSL ES])\n       ;;\n arm-apple-darwin*)\n       LIBS=\"$LIBS -framework CoreAudio -framework CoreFoundation -framework AudioToolbox -framework CFNetwork -framework UIKit\"\n\tac_pjmedia_audiodev_objs=\"coreaudio_dev.o\"\n       AC_MSG_RESULT([Checking sound device backend... AudioUnit])\n       ;;\n *darwin*)\n       LIBS=\"$LIBS -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox\"\n\tac_pjmedia_audiodev_objs=\"coreaudio_dev.o\"\n       AC_MSG_RESULT([Checking sound device backend... CoreAudio])\n       ;;\n *cygwin* | *mingw*)\n       AC_MSG_RESULT([Checking sound device backend... win32 sound])\n       ;;\n *rtems*)\n       AC_MSG_RESULT([Checking sound device backend... null sound])\n       ;;\n *)\n       dnl # Check if ALSA is available\n       AC_CHECK_HEADER(alsa/version.h,[LIBS=\"$LIBS -lasound\"])\n       AC_MSG_RESULT([Checking sound device backend... unix])\n       ;;\nesac\n\nAC_SUBST(ac_pjmedia_video)\n\ncase $target in\n *android*)\n\tLIBS=\"$LIBS -llog -lgcc\"\n\t;;\n arm-apple-darwin*)\n \tLIBS=\"$LIBS -framework UIKit\"\n\t;;\n *darwin*)\n \tLIBS=\"$LIBS -framework Foundation -framework AppKit\"\n\t;;\nesac\n\ncase $target in\n arm-apple-darwin*)\n       ac_pjmedia_video=iphone_os\n       AC_SUBST(ac_pjmedia_video_has_ios)\n       AC_SUBST(ac_ios_cflags)\n       SAVED_LIBS=\"$LIBS\"\n       LIBS=\"-framework AVFoundation -framework CoreGraphics -framework QuartzCore -framework CoreVideo -framework CoreMedia\"\n       AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [])],[ac_pjmedia_video_has_ios=yes],[ac_pjmedia_video_has_ios=no])\n       LIBS=\"$SAVED_LIBS\"\n       if test \"$ac_pjmedia_video_has_ios\" = \"yes\"; then\n         ac_ios_cflags=\"-DPJMEDIA_VIDEO_DEV_HAS_IOS=1 -DPJMEDIA_VIDEO_DEV_HAS_IOS_OPENGL=1\"\n         LIBS=\"$LIBS -framework OpenGLES -framework AVFoundation -framework CoreGraphics -framework QuartzCore -framework CoreVideo -framework CoreMedia\"\n         AC_MSG_RESULT([Checking if AVFoundation framework is available... yes])\n       else\n         AC_MSG_RESULT([Checking if AVFoundation framework is available... no])\n       fi\n       ;;\n *darwin*)\n       ac_pjmedia_video=mac_os\n       AC_SUBST(ac_pjmedia_video_has_avf)\n       AC_SUBST(ac_avf_cflags)\n       SAVED_LIBS=\"$LIBS\"\n       LIBS=\"-framework AVFoundation\"\n       AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [])],[ac_pjmedia_video_has_avf=yes],[ac_pjmedia_video_has_avf=no])\n       LIBS=\"$SAVED_LIBS\"\n       if test \"$ac_pjmedia_video_has_avf\" = \"yes\"; then\n         ac_qt_cflags=\"-DPJMEDIA_VIDEO_DEV_HAS_AVF=1\"\n         LIBS=\"$LIBS -framework AVFoundation -framework QuartzCore\"\n         AC_MSG_RESULT([Checking if AVFoundation framework is available... yes])\n       else\n         AC_MSG_RESULT([Checking if AVFoundation framework is available... no])\n       fi\n       ;;\n *cygwin* | *mingw*)\n       AC_SUBST(ac_pjmedia_video_has_dshow)\n       AC_SUBST(ac_dshow_cflags)\n       AC_SUBST(ac_dshow_ldflags)\n       AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [])],[ac_pjmedia_video_has_dshow=yes],[ac_pjmedia_video_has_dshow=no])\n       if test \"$ac_pjmedia_video_has_dshow\" = \"yes\"; then\n         ac_dshow_cflags=\"-DPJMEDIA_VIDEO_DEV_HAS_DSHOW=1\"\n         ac_dshow_ldflags=\"-lstrmiids -lrpcrt4 -lquartz -lstrmbase -loleaut32 -lstdc++ -luuid\"\n         LIBS=\"$ac_dshow_ldflags $LIBS\"\n         AC_MSG_RESULT([Checking if DirectShow is available... yes])\n       else\n         AC_MSG_RESULT([Checking if DirectShow is available... no])\n       fi\n       ac_android_cflags=\"$ac_android_cflags -DPJMEDIA_VIDEO_DEV_HAS_ANDROID=1\"\n       ;;\nesac\n\n\ndnl # Include resampling small filter\nAC_SUBST(ac_no_small_filter)\nAC_ARG_ENABLE(small-filter,\n\t      AC_HELP_STRING([--disable-small-filter],\n\t\t\t     [Exclude small filter in resampling]),\n\t      [if test \"$enable_small_filter\" = \"no\"; then\n\t\t[ac_no_small_filter='-DPJMEDIA_HAS_SMALL_FILTER=0']\n\t\tAC_MSG_RESULT([Checking if small filter is disabled... yes])\n\t       fi],\n\t      AC_MSG_RESULT([Checking if small filter is disabled... no]))\n\ndnl # Include resampling large filter\nAC_SUBST(ac_no_large_filter)\nAC_ARG_ENABLE(large-filter,\n\t      AC_HELP_STRING([--disable-large-filter],\n\t\t\t     [Exclude large filter in resampling]),\n\t      [if test \"$enable_large_filter\" = \"no\"; then\n\t\t[ac_no_large_filter='-DPJMEDIA_HAS_LARGE_FILTER=0']\n\t\tAC_MSG_RESULT([Checking if large filter is disabled... yes])\n\t       fi],\n\t      AC_MSG_RESULT([Checking if large filter is disabled... no]))\n\ndnl # Include Speex AEC\nAC_SUBST(ac_no_speex_aec)\nAC_ARG_ENABLE(speex-aec,\n\t      AC_HELP_STRING([--disable-speex-aec],\n\t\t\t     [Exclude Speex Acoustic Echo Canceller/AEC]),\n\t      [if test \"$enable_speex_aec\" = \"no\"; then\n\t\t[ac_no_speex_aec='-DPJMEDIA_HAS_SPEEX_AEC=0']\n\t\tAC_MSG_RESULT([Checking if Speex AEC is disabled...yes])\n\t       fi],\n\t      AC_MSG_RESULT([Checking if Speex AEC is disabled...no]))\n\ndnl # Include G722.1 codec\nAC_SUBST(ac_no_g7221_codec)\nAC_ARG_ENABLE(g7221-codec,\n\t      AC_HELP_STRING([--disable-g7221-codec],\n\t\t\t     [Exclude G.7221 codec in the build]),\n\t      [if test \"$enable_g7221_codec\" = \"no\"; then\n\t\t[ac_no_g7221_codec=1]\n\t\tAC_DEFINE(PJMEDIA_HAS_G7221_CODEC,0)\n\t\tAC_MSG_RESULT([Checking if G.722.1 codec is disabled...yes])\n\t       fi],\n\t      AC_MSG_RESULT([Checking if G.722.1 codec is disabled...no]))\n\ndnl # Include libsamplerate\nAC_ARG_ENABLE(libsamplerate,\n\t      AC_HELP_STRING([--enable-libsamplerate],\n\t\t\t     [Link with libsamplerate when available. Note that PJMEDIA_RESAMPLE_IMP must also be configured]),\n\t      [ AC_CHECK_LIB(samplerate,src_new) ],\n\t      AC_MSG_RESULT([Skipping libsamplerate detection])\n\t     )\n\ndnl # Include libsamplerate\nAC_SUBST(ac_resample_dll)\nAC_ARG_ENABLE(resample_dll,\n\t      AC_HELP_STRING([--enable-resample-dll],\n\t\t\t     [Build libresample as shared library]),\n\t      [if test \"$enable_resample_dll\" = \"yes\"; then\n\t\t[ac_resample_dll=1]\n\t\tAC_MSG_RESULT([Building libresample as shared library... yes])\n\t       fi],\n\t      AC_MSG_RESULT([Building libresample as shared library... no])\n\t      )\n\n\ndnl # pkg-config\nAC_CHECK_PROGS(PKG_CONFIG,pkg-config,none)\n\nif test \"$PKG_CONFIG\" == \"none\"; then\n\tAC_MSG_ERROR([*** Error: pkg-config not found  ***])\nfi\n\ndnl # FFmpeg\n\nAC_ARG_WITH(ffmpeg,\n    AC_HELP_STRING([--with-ffmpeg=DIR],\n\t\t   [Specify alternate FFMPEG prefix]),\n    [],\n    [with_ffmpeg=check]\n)\n\nAC_SUBST(ac_ffmpeg_cflags)\nAC_SUBST(ac_ffmpeg_ldflags)\n\nFFMPEG_PREFIX=\"\"\nAC_SUBST(SAVED_PKG_CONFIG_PATH)\nSAVED_PKG_CONFIG_PATH=$PKG_CONFIG_PATH\nif test \"x$with_ffmpeg\" != \"xcheck\" -a \"x$with_ffmpeg\" != \"x\"; then\n\tFFMPEG_PREFIX=$with_ffmpeg\n\tAC_MSG_RESULT([Using ffmpeg prefix... $FFMPEG_PREFIX])\n\texport PKG_CONFIG_PATH=$FFMPEG_PREFIX/lib/pkgconfig\nfi\n\nAC_MSG_CHECKING([ffmpeg packages])\nav_pkg=\"\"\nif $PKG_CONFIG --exists libavformat; then\n        ac_ffmpeg_cflags=\"$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVFORMAT=1\"\n        av_pkg=\"$av_pkg libavformat\"\nelse\n    AC_MSG_ERROR([*** Error: libavformat not detected  ***])\nfi\nif $PKG_CONFIG --exists libavcodec; then\n        ac_ffmpeg_cflags=\"$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVCODEC=1\"\n        av_pkg=\"$av_pkg libavcodec\"\nelse\n    AC_MSG_ERROR([*** Error: libavcodec not detected  ***])\nfi\nif $PKG_CONFIG --exists libswscale; then\n        ac_ffmpeg_cflags=\"$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBSWSCALE=1\"\n        av_pkg=\"$av_pkg libswscale\"\nelse\n    AC_MSG_ERROR([*** Error: libswscale not detected  ***])\nfi\nif $PKG_CONFIG --exists libavutil; then\n        ac_ffmpeg_cflags=\"$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVUTIL=1\"\n        av_pkg=\"$av_pkg libavutil\"\nelse\n    AC_MSG_ERROR([*** Error: libavutil not detected  ***])\nfi\nif $PKG_CONFIG --exists libavcore; then\n        ac_ffmpeg_cflags=\"$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVCORE=1\"\n        av_pkg=\"$av_pkg libavcore\"\nfi\n\nAC_MSG_RESULT([$av_pkg])\n\nac_ffmpeg_cflags=\"$ac_ffmpeg_cflags `$PKG_CONFIG --cflags $av_pkg`\"\nac_ffmpeg_ldflags=\"$ac_ffmpeg_ldflags `$PKG_CONFIG --libs $av_pkg`\"\n\nLIBS=\"$LIBS $ac_ffmpeg_ldflags\"\nexport PKG_CONFIG_PATH=$SAVED_PKG_CONFIG_PATH\n\n\ndnl # libvpx\n\nAC_ARG_WITH(vpx,\n    AC_HELP_STRING([--with-vpx=DIR],\n\t\t   [Specify alternate libVPX prefix]),\n    [],\n    [with_vpx=check]\n)\n\nAC_SUBST(ac_vpx_cflags)\nAC_SUBST(ac_vpx_ldflags)\n\nVPX_PREFIX=\"\"\nAC_SUBST(SAVED_PKG_CONFIG_PATH)\nSAVED_PKG_CONFIG_PATH=$PKG_CONFIG_PATH\nif test \"x$with_vpx\" != \"xcheck\" -a \"x$with_vpx\" != \"x\"; then\n\tVPX_PREFIX=$with_vpx\n\tAC_MSG_RESULT([Using libVPX prefix... $VPX_PREFIX])\n\texport PKG_CONFIG_PATH=$VPX_PREFIX\nfi\n\nAC_MSG_CHECKING([libvpx packages])\nif $PKG_CONFIG --exists vpx; then\n        ac_vpx_cflags=\"`$PKG_CONFIG --cflags vpx` -DPJMEDIA_HAS_LIBVPX=1\"\n        ac_vpx_ldflags=\"`$PKG_CONFIG --libs vpx`\"\n        AC_MSG_RESULT(yes)\nelse\n    AC_MSG_ERROR([*** Error: VPX library not detected  ***])\nfi\n\nLIBS=\"$LIBS $ac_vpx_ldflags\"\nexport PKG_CONFIG_PATH=$SAVED_PKG_CONFIG_PATH\n\n\ndnl # Video for Linux 2\nAC_ARG_ENABLE(v4l2,\n\t      AC_HELP_STRING([--disable-v4l2],\n\t\t\t     [Disable Video4Linux2 (default: not disabled)]),\n\t      [\n\t\tif test \"$enable_v4l2\" = \"no\"; then\n\t\t  AC_MSG_RESULT([Checking if V4L2 is disabled... yes])\n\t\tfi\n\t      ],\n\t      [\n\t        AC_SUBST(ac_v4l2_cflags)\n\t        AC_SUBST(ac_v4l2_ldflags)\n\t\tAC_CHECK_LIB(v4l2,\n\t\t\t     v4l2_open,\n\t\t\t     [ac_v4l2_cflags=\"-DPJMEDIA_VIDEO_DEV_HAS_V4L2=1\"\n\t\t\t      ac_v4l2_ldflags=\"-lv4l2\"\n\t\t\t      LIBS=\"$LIBS -lv4l2\"\n\t\t\t     ]\n\t\t\t     )\n\t      ])\n\ndnl # OpenH264 alt prefix\nAC_ARG_WITH(openh264,\n            AC_HELP_STRING([--with-openh264=DIR],\n\t\t           [Specify alternate OpenH264 prefix]),\n            [],\n            [with_openh264=no]\n            )\n\ndnl # Do not use default OpenH264 installation if we are cross-compiling\nif test \"x$ac_cross_compile\" != \"x\" -a \"x$with_openh264\" = \"xno\"; then\n    enable_openh264=no\nfi\n\ndnl # OpenH264\nAC_SUBST(ac_openh264_cflags)\nAC_SUBST(ac_openh264_ldflags)\nAC_ARG_ENABLE(openh264,\n\t      AC_HELP_STRING([--disable-openh264],\n\t\t\t     [Disable OpenH264 (default: not disabled)]),\n\t      [\n\t\tif test \"$enable_openh264\" = \"no\"; then\n\t\t  AC_MSG_RESULT([Checking if OpenH264 is disabled... yes])\n\t\tfi\n\t      ],\n\t      [\n\t\t  if test \"x$with_openh264\" != \"xno\" -a \"x$with_openh264\" != \"x\"; then\n\t\t        OPENH264_PREFIX=$with_openh264\n\t\t  \tOPENH264_CFLAGS=\"-I$OPENH264_PREFIX/include\"\n\t\t\tOPENH264_LDFLAGS=\"-L$OPENH264_PREFIX/lib\" \n\t\t\tAC_MSG_RESULT([Using OpenH264 prefix... $with_openh264])\n\t\t  else\n\t\t  \tOPENH264_CFLAGS=\"\"\n\t\t\tOPENH264_LDFLAGS=\"\" \n\t\t  fi\n\n\t\t  AC_MSG_CHECKING([OpenH264 usability])\n\n\t\t  OPENH264_LIBS=\"-lopenh264\"\n\t\t  \n\t\t  SAVED_LIBS=\"$LIBS\"\n\t\t  SAVED_LDFLAGS=\"$LDFLAGS\"\n\t\t  SAVED_CFLAGS=\"$CFLAGS\"\n\t\t  \n\t\t  LIBS=\"$OPENH264_LIBS $LIBS\"\n\t\t  LDFLAGS=\"$OPENH264_LDFLAGS $LDFLAGS -lstdc++\"\n\t\t  CFLAGS=\"$OPENH264_CFLAGS $CFLAGS\"\n\t\t  \n\t\t  AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <wels/codec_api.h>\n\t\t                                    #include <wels/codec_app_def.h>\n\t\t\t\t\t          ]],\n\t\t\t\t\t          [WelsCreateSVCEncoder(0);]\n\t\t\t\t\t         )],\n\t\t  \t\t [ ac_openh264_cflags=\"-DPJMEDIA_HAS_OPENH264_CODEC=1 $OPENH264_CFLAGS\"\n\t\t  \t\t   ac_openh264_ldflags=\"$OPENH264_LDFLAGS $OPENH264_LIBS\"\n\t\t  \t\t   AC_MSG_RESULT(ok)\n\t\t  \t\t  ],\n\t\t  \t\t [\n\t\t\t\t   LIBS=\"$SAVED_LIBS\"\n\t\t\t\t   LDFLAGS=\"$SAVED_LDFLAGS\"\n\t\t\t\t   CFLAGS=\"$SAVED_CFLAGS\"\n\t\t  \t\t   AC_MSG_RESULT(no)\n\t\t  \t\t ])\n\n\t      ])\n\ndnl # libyuv alt prefix\nAC_ARG_WITH(libyuv,\n            AC_HELP_STRING([--with-libyuv=DIR],\n\t\t           [Specify alternate libyuv prefix]),\n            [],\n            [with_libyuv=no]\n            )\n\ndnl # Do not use default libyuv installation if we are cross-compiling\nif test \"x$ac_cross_compile\" != \"x\" -a \"x$with_libyuv\" = \"xno\"; then\n    enable_libyuv=no\nfi\t      \n\t      \ndnl # Include libyuv\nAC_SUBST(ac_libyuv_cflags)\nAC_SUBST(ac_libyuv_ldflags)\nAC_ARG_ENABLE(libyuv,\n\t      AC_HELP_STRING([--disable-libyuv],\n\t\t\t     [Exclude libyuv in the build]),\n\t      [if test \"$enable_libyuv\" = \"no\"; then\n\t\tAC_MSG_RESULT([Checking if libyuv is disabled...yes])\n\t       fi],\n\t      [\n\t\t  if test \"x$with_libyuv\" != \"xno\" -a \"x$with_libyuv\" != \"x\"; then\n\t\t        LIBYUV_PREFIX=$with_libyuv\n\t\t  \tLIBYUV_CFLAGS=\"-I$LIBYUV_PREFIX/include\"\n\t\t  \t\n\t\t\tcase $target in\n\t\t\t    arm-apple-darwin*)\n\t\t\t\tLIBYUV_LDFLAGS=\"-L$LIBYUV_PREFIX/out_ios/Release-iphoneos\"\n\t\t\t\tcase $ARCH in\n\t\t\t\t    *armv7*)\n\t\t\t\t    LIBYUV_LIBS=\"-lyuv_neon\"\n\t\t\t\t    ;;\n\t\t\t\t*)\n\t\t\t\t    ;;\n\t\t\t\tesac\n\t\t\t\t;;\t\t\t\n\t\t\t    *mingw* | *cygw* | *win32* | *w32* | *darwin* | *linux* | *android*)\n\t\t\t\tLIBYUV_LDFLAGS=\"-L$LIBYUV_PREFIX/out/Release\"\n\t\t\t\t;;\n\t\t\t    *)\n\t\t\t\tLIBYUV_CFLAGS=\"\"\n\t\t\t\tLIBYUV_LDFLAGS=\"\"\n\t\t\t\t;;\n\t\t\tesac\t\t  \t\n\t\t  \t\n\t\t\tAC_MSG_RESULT([Using libyuv prefix... $with_libyuv])\n\t\t  else\n\t\t  \tLIBYUV_CFLAGS=\"\"\n\t\t\tLIBYUV_LDFLAGS=\"\" \n\t\t  fi\n\t\t  \t\t  \n\t\t  LIBYUV_LIBS=\"$LIBYUV_LIBS -lyuv\"\n\t\t  \n\t\t  SAVED_LIBS=\"$LIBS\"\n\t\t  SAVED_LDFLAGS=\"$LDFLAGS\"\n\t\t  SAVED_CFLAGS=\"$CFLAGS\"\n\t\t  \n\t\t  LIBS=\"$LIBYUV_LIBS $LIBS\"\n\t\t  LDFLAGS=\"$LIBYUV_LDFLAGS $LDFLAGS\"\n\t\t  CFLAGS=\"$LIBYUV_CFLAGS $CFLAGS\"\n\t\t  \n\t\t  AC_CHECK_LIB(yuv,\n\t\t\t       I420Scale,\n\t\t\t       [ ac_libyuv_cflags=\"-DPJMEDIA_HAS_LIBYUV=1 $LIBYUV_CFLAGS\"\n\t\t  \t\t ac_libyuv_ldflags=\"$LIBYUV_LDFLAGS $LIBYUV_LIBS\"\n\t\t\t       ],\n\t\t\t       [ LIBS=\"$SAVED_LIBS\"\n\t\t\t\t LDFLAGS=\"$SAVED_LDFLAGS\"\n\t\t\t\t CFLAGS=\"$SAVED_CFLAGS\"\n\t\t\t       ],\n\t\t\t       []\n\t\t\t       )\n\t      ])\n\n\ndnl ##########################################\ndnl #\ndnl # WebRTC AEC Support\ndnl #\n\nAC_SUBST(ac_webrtc_platform)\ncase $target in\n *darwin*)\n       ac_webrtc_platform=webrtc_darwinos\n       ;;\n *mingw*)\n       ac_webrtc_platform=webrtc_win32\n       ;;\n *linux*)\n       ac_webrtc_platform=webrtc_linux\n       ;;\n *)\n       ac_webrtc_platform=null\n       ;;\nesac\n\n\ndnl ##########################################\ndnl #\ndnl # PJSIP CONFIG\ndnl #\n\ndnl # SSL alt prefix\nAC_ARG_WITH(ssl,\n    AC_HELP_STRING([--with-ssl=DIR],\n\t\t   [Specify alternate libssl prefix]),\n    [],\n    [with_ssl=no]\n    )\n\ndnl # Do not use default SSL installation if we are cross-compiling\nif test \"x$ac_cross_compile\" != \"x\" -a \"x$with_ssl\" = \"xno\"; then\n    enable_ssl=no\nfi\n\ndnl # Include SSL support\nAC_SUBST(ac_no_ssl)\nAC_ARG_ENABLE(ssl,\n\t      AC_HELP_STRING([--disable-ssl],\n\t\t\t     [Exclude SSL support the build (default: autodetect)])\n\t      ,\n\t      [\n\t\tif test \"$enable_ssl\" = \"no\"; then\n\t\t [ac_no_ssl=1]\n\t\t AC_MSG_RESULT([Checking if SSL support is disabled... yes])\n\t        fi\n\t      ],\n\t      [\n\t\tAC_MSG_RESULT([checking for OpenSSL installations..])\n                if test \"x$with_ssl\" != \"xno\" -a \"x$with_ssl\" != \"x\"; then\n                    CFLAGS=\"$CFLAGS -I$with_ssl/include\"\n                    LDFLAGS=\"$LDFLAGS -L$with_ssl/lib\"\n                    AC_MSG_RESULT([Using SSL prefix... $with_ssl])\n                fi\n\t\tAC_SUBST(openssl_h_present)\n\t\tAC_SUBST(libssl_present)\n\t\tAC_SUBST(libcrypto_present)\n\t\tAC_CHECK_HEADER(openssl/ssl.h,[openssl_h_present=1])\n\t\tAC_CHECK_LIB(crypto,ERR_load_BIO_strings,[libcrypto_present=1 && LIBS=\"-lcrypto $LIBS\"])\n\t\tAC_CHECK_LIB(ssl,SSL_CTX_new,[libssl_present=1 && LIBS=\"-lssl $LIBS\"])\n\t\tif test \"x$openssl_h_present\" = \"x1\" -a \"x$libssl_present\" = \"x1\" -a \"x$libcrypto_present\" = \"x1\"; then\n\t        \tAC_MSG_RESULT([OpenSSL library found, SSL support enabled])\n\t\t\t# PJSIP_HAS_TLS_TRANSPORT setting follows PJ_HAS_SSL_SOCK\n\t\t\t#AC_DEFINE(PJSIP_HAS_TLS_TRANSPORT, 1)\n\t\t\tAC_DEFINE(PJ_HAS_SSL_SOCK, 1)\n\t\telse\n\t\t\tAC_MSG_RESULT([** OpenSSL libraries not found, disabling SSL support **])\n\t\tfi\n\t      ])\n\n\ndnl ##########################################\ndnl #\ndnl # MANUAL CONFIG\ndnl #\n\n\ndnl # Determine if select() requires nfds to be filled up with\ndnl # correct value (max_fd+1). If zero, nfds will be filled up with\ndnl # PJ_FD_SETSIZE\nAC_MSG_CHECKING([if select() needs correct nfds])\ncase $target in\n  *rtems*) AC_DEFINE(PJ_SELECT_NEEDS_NFDS,1)\n\t   AC_MSG_RESULT(yes)\n\t;;\n  *) AC_DEFINE(PJ_SELECT_NEEDS_NFDS,0)\n     AC_MSG_RESULT([no (default)])\n     AC_MSG_RESULT([** Decided that select() doesn't need correct nfds (please check)])\n\t;;\nesac\n\ndnl # Determine if pj_thread_create() should enforce thread stack size when\ndnl # creating thread. Default is zero, to allow OS to allocate appropriate\ndnl # thread's stack size.\nAC_MSG_CHECKING([if pj_thread_create() should enforce stack size])\ncase $target in\n  *rtems*) AC_DEFINE(PJ_THREAD_SET_STACK_SIZE,1)\n\t   AC_MSG_RESULT(yes)\n\t;;\n  *) AC_DEFINE(PJ_THREAD_SET_STACK_SIZE,0)\n     AC_MSG_RESULT([no (default)])\n\t;;\nesac\n\ndnl # Determine if pj_thread_create() should allocate thread's stack from\ndnl # the pool. Default is zero, to let OS allocate thread's stack.\nAC_MSG_CHECKING([if pj_thread_create() should allocate stack])\ncase $target in\n  *rtems*) AC_DEFINE(PJ_THREAD_ALLOCATE_STACK,1)\n\t   AC_MSG_RESULT(yes)\n\t;;\n  *) AC_DEFINE(PJ_THREAD_ALLOCATE_STACK,0)\n     AC_MSG_RESULT([no (default)])\n\t;;\nesac\n\ndnl # This value specifies the value set in errno by the OS when a non-blocking\ndnl # socket recv() can not return immediate data.\ncase $target in\n  *mingw* | *cygw* | *win32* | *w32* )\n\tAC_DEFINE(PJ_BLOCKING_ERROR_VAL,WSAEWOULDBLOCK)\n\t;;\n  *) AC_DEFINE(PJ_BLOCKING_ERROR_VAL,EAGAIN)\n     AC_MSG_RESULT([** Setting non-blocking recv() retval to EAGAIN (please check)])\n\t;;\nesac\n\ndnl # This value specifies the value set in errno by the OS when a non-blocking\ndnl # socket connect() can not get connected immediately.\ncase $target in\n  *mingw* | *cygw* | *win32* | *w32* )\n\tAC_DEFINE(PJ_BLOCKING_CONNECT_ERROR_VAL,WSAEWOULDBLOCK)\n\t;;\n  *) AC_DEFINE(PJ_BLOCKING_CONNECT_ERROR_VAL,EINPROGRESS)\n     AC_MSG_RESULT([** Setting non-blocking connect() retval to EINPROGRESS (please check)])\n\t;;\nesac\n\n\nAC_SUBST(target)\nAC_SUBST(ac_linux_poll,select)\nAC_SUBST(ac_host,unix)\nAC_SUBST(ac_main_obj)\ncase $target in\n  *rtems*)\n\tac_main_obj=main_rtems.o\n\t;;\n  *)\n\tac_main_obj=main.o\n\t;;\nesac\nAC_SUBST(CC)\n\nac_build_mak_vars=`echo $ac_build_mak_vars | sed 's/\\\\\\\\n/\\n/g'`\nAC_OUTPUT()\n\n\nAC_MSG_RESULT([\n\nConfigurations for current target have been written to 'build.mak', and 'os-auto.mak' in various build directories, and pjlib/include/pj/compat/os_auto.h.\n\nFurther customizations can be put in:\n  - 'user.mak'\n  - 'pjlib/include/pj/config_site.h'\n\nThe next step now is to run 'make dep' and 'make'.\n])\n\n"
  },
  {
    "path": "deps/pjsip/base_rev",
    "content": "5249\n"
  },
  {
    "path": "deps/pjsip/build/cc-auto.mak.in",
    "content": "export CC = @CC@ -c\nexport CXX = @CXX@ -c\nexport AR = @AR@\nexport AR_FLAGS = @AR_FLAGS@\nexport LD = @LD@\nexport LDOUT = -o \nexport RANLIB = @RANLIB@\n\nexport OBJEXT := .@OBJEXT@\nexport LIBEXT := .@LIBEXT@\nexport LIBEXT2 := @LIBEXT2@\n\nexport CC_OUT := @CC_OUT@\nexport CC_INC := @CC_INC@\nexport CC_DEF := @CC_DEF@\nexport CC_OPTIMIZE := @CC_OPTIMIZE@\nexport CC_LIB := -l\n\nexport CC_SOURCES :=\nexport CC_CFLAGS := @CC_CFLAGS@\nexport CC_LDFLAGS :=\n\n"
  },
  {
    "path": "deps/pjsip/build/cc-gcc.mak",
    "content": "export CC = $(CROSS_COMPILE)gcc -c\nexport AR = $(CROSS_COMPILE)ar rv \nexport LD = $(CROSS_COMPILE)gcc\nexport LDOUT = -o \nexport RANLIB = $(CROSS_COMPILE)ranlib\n\nexport OBJEXT := .o\nexport LIBEXT := .a\nexport LIBEXT2 :=\n\nexport CC_OUT := -o \nexport CC_INC := -I\nexport CC_DEF := -D\nexport CC_OPTIMIZE := -O2\nexport CC_LIB := -l\n\nexport CC_SOURCES :=\nexport CC_CFLAGS := -Wall \n#export CC_CFLAGS += -Wdeclaration-after-statement\n#export CC_CXXFLAGS := -Wdeclaration-after-statement\nexport CC_LDFLAGS :=\n\n"
  },
  {
    "path": "deps/pjsip/build/common.mak",
    "content": "#\n# Include host/target/compiler selection.\n# This will export CC_NAME, MACHINE_NAME, OS_NAME, and HOST_NAME variables.\n#\ninclude $(PJDIR)/build.mak\n\n#\n# Include global compiler specific definitions\n#\ninclude $(PJDIR)/build/cc-$(CC_NAME).mak\n\n#\n# (Optionally) Include compiler specific configuration that is\n# specific to this project. This configuration file is\n# located in this directory.\n#\n-include cc-$(CC_NAME).mak\n\n#\n# Include auto configured compiler specification.\n# This will override the compiler settings above.\n# Currently this is made OPTIONAL, to prevent people\n# from getting errors because they don't re-run ./configure\n# after downloading new PJSIP.\n#\n-include $(PJDIR)/build/cc-auto.mak\n\n#\n# Include global machine specific definitions\n#\ninclude $(PJDIR)/build/m-$(MACHINE_NAME).mak\n-include m-$(MACHINE_NAME).mak\n\n#\n# Include target OS specific definitions\n#\ninclude $(PJDIR)/build/os-$(OS_NAME).mak\n\n#\n# (Optionally) Include target OS specific configuration that is\n# specific to this project. This configuration file is\n# located in this directory.\n#\n-include os-$(OS_NAME).mak\n\n#\n# Include host specific definitions\n#\ninclude $(PJDIR)/build/host-$(HOST_NAME).mak\n\n#\n# (Optionally) Include host specific configuration that is\n# specific to this project. This configuration file is\n# located in this directory.\n#\n-include host-$(HOST_NAME).mak\n\n#\n# Include global user configuration, if any\n#\n-include $(PJDIR)/user.mak\n\n\n"
  },
  {
    "path": "deps/pjsip/build/host-mingw.mak",
    "content": "export HOST_MV := mv\nexport HOST_RM := rm -f @@\nexport HOST_RMR := rm -rf @@\nexport HOST_RMDIR := rm -rf @@\nexport HOST_MKDIR := mkdir @@\nexport HOST_EXE := .exe\nexport HOST_PSEP := /\n\nexport HOST_SOURCES :=\nexport HOST_CFLAGS :=\nexport HOST_CXXFLAGS :=\nexport HOST_LDFLAGS := $(CC_LIB)stdc++$(LIBEXT2)\n\n"
  },
  {
    "path": "deps/pjsip/build/host-unix.mak",
    "content": "export HOST_MV := mv\nexport HOST_RM := rm -f @@\nexport HOST_RMR := rm -rf @@\nexport HOST_RMDIR := rm -rf @@\nexport HOST_MKDIR := mkdir -p @@\nexport HOST_EXE := $(HOST_EXE)\nexport HOST_PSEP := /\n\nexport HOST_SOURCES :=\nexport HOST_CFLAGS :=\nexport HOST_CXXFLAGS :=\nexport HOST_LDFLAGS := \n\n"
  },
  {
    "path": "deps/pjsip/build/host-win32.mak",
    "content": "export HOST_MV := ren\nexport HOST_RM := if exist @@; del /F /Q @@\nexport HOST_RMR := if exist @@; del /F /Q @@\nexport HOST_RMDIR := if exist @@; rmdir @@\nexport HOST_MKDIR := if not exist @@; mkdir @@\nexport HOST_EXE := .exe\nexport HOST_PSEP := \\\\\n\nexport HOST_SOURCES :=\nexport HOST_CFLAGS :=\nexport HOST_CXXFLAGS :=\nexport HOST_LDFLAGS :=\n"
  },
  {
    "path": "deps/pjsip/build/m-arm.mak",
    "content": "export M_CFLAGS := $(CC_DEF)PJ_M_ARMV4=1\nexport M_CXXFLAGS :=\nexport M_LDFLAGS :=\nexport M_SOURCES :=\n"
  },
  {
    "path": "deps/pjsip/build/m-auto.mak",
    "content": "# Nothing needs to be defined here\n"
  },
  {
    "path": "deps/pjsip/build/m-i386.mak",
    "content": "export M_CFLAGS := $(CC_DEF)PJ_M_I386=1\nexport M_CXXFLAGS :=\nexport M_LDFLAGS :=\nexport M_SOURCES :=\n"
  },
  {
    "path": "deps/pjsip/build/m-x86_64.mak",
    "content": "export M_CFLAGS := $(CC_DEF)PJ_M_X86_64=1\nexport M_CXXFLAGS :=\nexport M_LDFLAGS :=\nexport M_SOURCES :=\n"
  },
  {
    "path": "deps/pjsip/build/os-auto.mak.in",
    "content": "# @configure_input@\n\nexport OS_CFLAGS   := $(CC_DEF)PJ_AUTOCONF=1 @CFLAGS@\n\nexport OS_CXXFLAGS := $(CC_DEF)PJ_AUTOCONF=1 @CXXFLAGS@\n\nexport OS_LDFLAGS  := @LDFLAGS@ @LIBS@\n\nexport OS_SOURCES  := \n\n\n"
  },
  {
    "path": "deps/pjsip/build/rules.mak",
    "content": "ifeq ($(LIBDIR),)\nLIBDIR = ../lib\nendif\nifeq ($(BINDIR),)\nBINDIR = ../bin\nendif\n\n#\n# The full path of output lib file (e.g. ../lib/libapp.a).\n#\nLIB = $($(APP)_LIB)\n\n#\n# The full path of output lib file (e.g. ../lib/libapp.a).\n#\nSHLIB = $($(APP)_SHLIB)\n\n#\n# The full path of output executable file (e.g. ../bin/app.exe).\n#\nEXE = $($(APP)_EXE)\n\n#\n# Source directory\n#\nSRCDIR = $($(APP)_SRCDIR)\n\n#\n# Output directory for object files (i.e. output/target)\n#\nOBJDIR = output/$(app)-$(TARGET_NAME)\n\nifeq ($(OS_NAME),linux-kernel)\nexport $(APP)_CFLAGS += -DKBUILD_MODNAME=$(app) -DKBUILD_BASENAME=$(app)\nendif\n\n\n#\n# OBJS is ./output/target/file.o\n#\nOBJS = $(foreach file, $($(APP)_OBJS), $(OBJDIR)/$(file))\nOBJDIRS := $(sort $(dir $(OBJS)))\n\n#\n# FULL_SRCS is ../src/app/file1.c ../src/app/file1.S\n#\nFULL_SRCS = $(foreach file, $($(APP)_OBJS), $(SRCDIR)/$(basename $(file)).m $(SRCDIR)/$(basename $(file)).c $(SRCDIR)/$(basename $(file)).cpp $(SRCDIR)/$(basename $(file)).S)\n\n#\n# When generating dependency (gcc -MM), ideally we use only either\n# CFLAGS or CXXFLAGS (not both). But I just couldn't make if/ifeq to work.\n#\n#DEPFLAGS = $($(APP)_CXXFLAGS) $($(APP)_CFLAGS)\nDEPCFLAGS =  $($(APP)_CFLAGS)\nDEPCXXFLAGS = $($(APP)_CXXFLAGS)\n\n# Dependency file\nDEP_FILE := .$(app)-$(TARGET_NAME).depend\n\n\nprint_common:\n\t@echo \"###\"\n\t@echo \"### DUMPING MAKE VARIABLES (I WON'T DO ANYTHING ELSE):\"\n\t@echo \"###\"\n\t@echo APP=$(APP)\n\t@echo OBJDIR=$(OBJDIR)\n\t@echo OBJDIRS=$(OBJDIRS)\n\t@echo OBJS=$(OBJS)\n\t@echo SRCDIR=$(SRCDIR)\n\t@echo FULL_SRCS=$(FULL_SRCS)\n\t@echo $(APP)_CFLAGS=$($(APP)_CFLAGS)\n\t@echo $(APP)_CXXFLAGS=$($(APP)_CXXFLAGS)\n\t@echo $(APP)_LDFLAGS=$($(APP)_LDFLAGS)\n#\t@echo DEPFLAGS=$(DEPFLAGS)\n\t@echo CC=$(CC)\n\t@echo AR=$(AR)\n\t@echo AR_FLAGS=$(AR_FLAGS)\n\t@echo RANLIB=$(RANLIB)\n\nprint_bin: print_common\n\t@echo EXE=$(EXE)\n\t@echo BINDIR=$(BINDIR)\n\nprint_lib: print_common\n\t@echo LIB=$(LIB)\n\t@echo LIBDIR=$(LIBDIR)\n\n$(LIB): $(OBJDIRS) $(OBJS) $($(APP)_EXTRA_DEP)\n\tif test ! -d $(LIBDIR); then $(subst @@,$(subst /,$(HOST_PSEP),$(LIBDIR)),$(HOST_MKDIR)); fi\n\t$(AR) $(AR_FLAGS) $(LIB) $(OBJS)\n\t$(RANLIB) $(LIB)\n\n$(SHLIB): $(OBJDIRS) $(OBJS) $($(APP)_EXTRA_DEP)\n\tif test ! -d $(LIBDIR); then $(subst @@,$(subst /,$(HOST_PSEP),$(LIBDIR)),$(HOST_MKDIR)); fi\n\t$(LD) $(LDOUT)$(subst /,$(HOST_PSEP),$(SHLIB)) \\\n\t    $(subst /,$(HOST_PSEP),$(OBJS)) $($(APP)_LDFLAGS)\n\n$(EXE): $(OBJDIRS) $(OBJS) $($(APP)_EXTRA_DEP)\n\tif test ! -d $(BINDIR); then $(subst @@,$(subst /,$(HOST_PSEP),$(BINDIR)),$(HOST_MKDIR)); fi\n\t$(LD) $(LDOUT)$(subst /,$(HOST_PSEP),$(EXE)) \\\n\t    $(subst /,$(HOST_PSEP),$(OBJS)) $($(APP)_LDFLAGS)\n\n$(OBJDIR)/$(app).o: $(OBJDIRS) $(OBJS)\n\t$(CROSS_COMPILE)ld -r -o $@ $(OBJS)\n\n$(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o\n\t@echo Creating kbuild Makefile...\n\t@echo \"# Our module name:\" > $(OBJDIR)/Makefile\n\t@echo 'obj-m += $(app).o' >> $(OBJDIR)/Makefile\n\t@echo >> $(OBJDIR)/Makefile\n\t@echo \"# Object members:\" >> $(OBJDIR)/Makefile\n\t@echo -n '$(app)-objs += ' >> $(OBJDIR)/Makefile\n\t@for file in $($(APP)_OBJS); do \\\n\t\techo -n \"$$file \" >> $(OBJDIR)/Makefile; \\\n\tdone\n\t@echo >> $(OBJDIR)/Makefile\n\t@echo >> $(OBJDIR)/Makefile\n\t@echo \"# Prevent .o files to be built by kbuild:\" >> $(OBJDIR)/Makefile\n\t@for file in $($(APP)_OBJS); do \\\n\t\techo \".PHONY: `pwd`/$(OBJDIR)/$$file\" >> $(OBJDIR)/Makefile; \\\n\tdone\n\t@echo >> $(OBJDIR)/Makefile\n\t@echo all: >> $(OBJDIR)/Makefile\n\t@echo -e \"\\tmake -C $(KERNEL_DIR) M=`pwd`/$(OBJDIR) modules $(KERNEL_ARCH)\" >> $(OBJDIR)/Makefile\n\t@echo Invoking kbuild...\n\tmake -C $(OBJDIR)\n\n../lib/$(app).ko: $(LIB) $(OBJDIR)/$(app).ko\n\tcp $(OBJDIR)/$(app).ko ../lib\n\n$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.m\n\t$(CC) $($(APP)_CFLAGS) \\\n\t\t$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \\\n\t\t$(subst /,$(HOST_PSEP),$<) \n\n$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.c\n\t$(CC) $($(APP)_CFLAGS) \\\n\t\t$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \\\n\t\t$(subst /,$(HOST_PSEP),$<) \n\n$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.S\n\t$(CC) $($(APP)_CFLAGS) \\\n\t\t$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \\\n\t\t$(subst /,$(HOST_PSEP),$<) \n\n$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cpp\n\t$(CC) $($(APP)_CXXFLAGS) \\\n\t\t$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \\\n\t\t$(subst /,$(HOST_PSEP),$<)\n\n$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cc\n\t$(CC) $($(APP)_CXXFLAGS) \\\n\t\t$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \\\n\t\t$(subst /,$(HOST_PSEP),$<)\n\n$(OBJDIRS):\n\t$(subst @@,$(subst /,$(HOST_PSEP),$@),$(HOST_MKDIR)) \n\n$(LIBDIR):\n\t$(subst @@,$(subst /,$(HOST_PSEP),$(LIBDIR)),$(HOST_MKDIR))\n\n$(BINDIR):\n\t$(subst @@,$(subst /,$(HOST_PSEP),$(BINDIR)),$(HOST_MKDIR))\n\nclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),$(OBJDIR)/*),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),$(OBJDIR)),$(HOST_RMDIR))\nifeq ($(OS_NAME),linux-kernel)\n\trm -f ../lib/$(app).o\nendif\n\ngcov-report:\n\tfor file in $(FULL_SRCS); do \\\n\t\tgcov $$file -n -o $(OBJDIR); \\\n\tdone\n\nrealclean: clean\n\t$(subst @@,$(subst /,$(HOST_PSEP),$(LIB)) $(subst /,$(HOST_PSEP),$(EXE)),$(HOST_RM))\n\t$(subst @@,$(DEP_FILE),$(HOST_RM))\nifeq ($(OS_NAME),linux-kernel)\n\trm -f ../lib/$(app).ko\nendif\n\ndepend:\n\t$(subst @@,$(DEP_FILE),$(HOST_RM))\n\tfor F in $(FULL_SRCS); do \\\n\t   if test -f $$F; then \\\n\t     echo \"$(OBJDIR)/\" | tr -d '\\n' >> $(DEP_FILE); \\\n\t     if echo $$F | grep -q .cpp$$; then \\\n\t\tdep=\"$(CC) -M $(DEPCXXFLAGS) $$F\"; \\\n\t     else \\\n\t\tdep=\"$(CC) -M $(DEPCFLAGS) $$F\"; \\\n\t     fi; \\\n\t     if eval $$dep | sed '/^#/d' >> $(DEP_FILE); then \\\n\t\ttrue; \\\n\t     else \\\n\t\techo 'err:' >> $(DEP_FILE); \\\n\t\trm -f $(DEP_FILE); \\\n\t\texit 1; \\\n\t     fi; \\\n\t   fi; \\\n\tdone;\n\ndep: depend\n\n-include $(DEP_FILE)\n\n"
  },
  {
    "path": "deps/pjsip/build.mak.in",
    "content": "export PJDIR := @ac_pjdir@\ninclude $(PJDIR)/version.mak\nexport PJ_DIR := $(PJDIR)\n\n# @configure_input@\nexport MACHINE_NAME := auto\nexport OS_NAME := auto\nexport HOST_NAME := unix\nexport CC_NAME := gcc\nexport TARGET_NAME := @target@\nexport CROSS_COMPILE := @ac_cross_compile@\nexport LINUX_POLL := @ac_linux_poll@ \nexport SHLIB_SUFFIX := @ac_shlib_suffix@\n\nexport ac_prefix := @prefix@\n\nLIB_SUFFIX := $(TARGET_NAME).a\n\n# Determine which party libraries to use\nexport APP_THIRD_PARTY_LIBS := -lsrtp-$(TARGET_NAME)\nexport APP_THIRD_PARTY_EXT :=\nexport APP_THIRD_PARTY_LIB_FILES := $(PJ_DIR)/third_party/lib/libsrtp-$(LIB_SUFFIX)\n\nifeq (@ac_resample_dll@,1)\nexport PJ_RESAMPLE_DLL := 1\nexport APP_THIRD_PARTY_LIBS := -lresample $(APP_THIRD_PARTY_LIBS)\nexport APP_THIRD_PARTY_LIB_FILES := $(PJ_DIR)/third_party/lib/libresample.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libresample.$(SHLIB_SUFFIX) $(APP_THIRD_PARTY_LIB_FILES)\nelse\nexport APP_THIRD_PARTY_LIBS := -lresample-$(TARGET_NAME) $(APP_THIRD_PARTY_LIBS)\nexport APP_THIRD_PARTY_LIB_FILES := $(PJ_DIR)/third_party/lib/libresample-$(LIB_SUFFIX) $(APP_THIRD_PARTY_LIB_FILES)\nendif\n\n# WebRTC\nAPP_THIRD_PARTY_LIBS += -lwebrtcaec-$(TARGET_NAME)\nAPP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libwebrtcaec-$(LIB_SUFFIX)\n\n# Opus\nifneq (@ac_no_opus_codec@,1)\nAPP_THIRD_PARTY_LIBS += -lopuscodec-$(TARGET_NAME)\nAPP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libopuscodec-$(LIB_SUFFIX)\nendif\n\n# ZRTP\nAPP_THIRD_PARTY_LIBS += -lzsrtp-$(TARGET_NAME) -lsqlite3 -lstdc++\nAPP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libzsrtp-$(LIB_SUFFIX)\n\nifneq (@ac_no_gsm_codec@,1)\nifeq (@ac_external_gsm@,1)\n# External GSM library\nAPP_THIRD_PARTY_EXT += -lgsm\nelse\nAPP_THIRD_PARTY_LIBS += -lgsmcodec-$(TARGET_NAME)\nAPP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libgsmcodec-$(LIB_SUFFIX)\nendif\nendif\n\nifneq (@ac_no_speex_codec@,1)\nifeq (@ac_external_speex@,1)\nAPP_THIRD_PARTY_EXT += -lspeex -lspeexdsp\nelse\nAPP_THIRD_PARTY_LIBS += -lspeex-$(TARGET_NAME)\nAPP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libspeex-$(LIB_SUFFIX)\nendif\nendif\n\nifneq (@ac_no_ilbc_codec@,1)\nAPP_THIRD_PARTY_LIBS += -lilbccodec-$(TARGET_NAME)\nAPP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libilbccodec-$(LIB_SUFFIX)\nendif\n\nifneq (@ac_no_g7221_codec@,1)\nAPP_THIRD_PARTY_LIBS += -lg7221codec-$(TARGET_NAME)\nAPP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libg7221codec-$(LIB_SUFFIX)\nendif\n\n# Additional flags\n@ac_build_mak_vars@\n\n#\n# Video\n# Note: there are duplicated macros in pjmedia/os-auto.mak.in (and that's not\n#       good!\n\n# FFMPEG flags\nFFMPEG_CFLAGS = @ac_ffmpeg_cflags@ \nFFMPEG_LDFLAGS =  @ac_ffmpeg_ldflags@\n\n# VPX flags\nVPX_CFLAGS = @ac_vpx_cflags@\nVPX_LDFLAGS =  @ac_vpx_ldflags@\n\n# Video4Linux2\nV4L2_CFLAGS = @ac_v4l2_cflags@\nV4L2_LDFLAGS = @ac_v4l2_ldflags@\n\n# OPENH264 flags\nOPENH264_CFLAGS = @ac_openh264_cflags@ \nOPENH264_LDFLAGS =  @ac_openh264_ldflags@\n\n# AVF\nAC_PJMEDIA_VIDEO_HAS_AVF = @ac_pjmedia_video_has_avf@\nAVF_CFLAGS = @ac_avf_cflags@\n\n# iOS\nIOS_CFLAGS = @ac_ios_cflags@\n\n# Dshow\nAC_PJMEDIA_VIDEO_HAS_DSHOW = @ac_pjmedia_video_has_dshow@\nDSHOW_CFLAGS = @ac_dshow_cflags@\nDSHOW_LDFLAGS = @ac_dshow_ldflags@\n\n# Android\nANDROID_CFLAGS = @ac_android_cflags@\n\n# libyuv\nLIBYUV_CFLAGS = @ac_libyuv_cflags@ \nLIBYUV_LDFLAGS =  @ac_libyuv_ldflags@\n\n# PJMEDIA features exclusion\nPJ_VIDEO_CFLAGS += $(FFMPEG_CFLAGS) $(V4L2_CFLAGS) $(AVF_CFLAGS) \\\n\t\t   $(OPENH264_CFLAGS) $(IOS_CFLAGS) $(DSHOW_CFLAGS) $(LIBYUV_CFLAGS) \\\n\t\t   $(VPX_CFLAGS)\nPJ_VIDEO_LDFLAGS += $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS) \\\n                   $(OPENH264_LDFLAGS) $(DSHOW_LDFLAGS) $(LIBYUV_LDFLAGS) \\\n                   $(VPX_LDFLAGS)\n\n\n# CFLAGS, LDFLAGS, and LIBS to be used by applications\nexport APP_CC := @CC@\nexport APP_CXX := @CXX@\nexport APP_CFLAGS := -DPJ_AUTOCONF=1\\\n\t@CFLAGS@\\\n\t$(PJ_VIDEO_CFLAGS) \\\n\t-I$(PJDIR)/pjlib/include\\\n\t-I$(PJDIR)/pjlib-util/include\\\n\t-I$(PJDIR)/pjnath/include\\\n\t-I$(PJDIR)/pjmedia/include\\\n\t-I$(PJDIR)/pjsip/include\nexport APP_CXXFLAGS := $(APP_CFLAGS)\nexport APP_LDFLAGS := -L$(PJDIR)/pjlib/lib\\\n\t-L$(PJDIR)/pjlib-util/lib\\\n\t-L$(PJDIR)/pjnath/lib\\\n\t-L$(PJDIR)/pjmedia/lib\\\n\t-L$(PJDIR)/pjsip/lib\\\n\t-L$(PJDIR)/third_party/lib\\\n\t$(PJ_VIDEO_LDFLAGS) \\\n\t@LDFLAGS@\nexport APP_LDXXFLAGS := $(APP_LDFLAGS)\nexport APP_LDLIBS := \\\n\t-lpjsip-ua-$(TARGET_NAME)\\\n\t-lpjsip-simple-$(TARGET_NAME)\\\n\t-lpjsip-$(TARGET_NAME)\\\n\t-lpjmedia-codec-$(TARGET_NAME)\\\n\t-lpjmedia-videodev-$(TARGET_NAME)\\\n\t-lpjmedia-$(TARGET_NAME)\\\n\t-lpjmedia-audiodev-$(TARGET_NAME)\\\n\t-lpjnath-$(TARGET_NAME)\\\n\t-lpjlib-util-$(TARGET_NAME)\\\n\t$(APP_THIRD_PARTY_LIBS)\\\n\t$(APP_THIRD_PARTY_EXT)\\\n\t-lpj-$(TARGET_NAME)\\\n\t@LIBS@\nexport APP_LIB_FILES := \\\n\t$(PJ_DIR)/pjsip/lib/libpjsip-ua-$(LIB_SUFFIX) \\\n\t$(PJ_DIR)/pjsip/lib/libpjsip-simple-$(LIB_SUFFIX) \\\n\t$(PJ_DIR)/pjsip/lib/libpjsip-$(LIB_SUFFIX) \\\n\t$(PJ_DIR)/pjmedia/lib/libpjmedia-codec-$(LIB_SUFFIX) \\\n\t$(PJ_DIR)/pjmedia/lib/libpjmedia-videodev-$(LIB_SUFFIX) \\\n\t$(PJ_DIR)/pjmedia/lib/libpjmedia-$(LIB_SUFFIX) \\\n\t$(PJ_DIR)/pjmedia/lib/libpjmedia-audiodev-$(LIB_SUFFIX) \\\n\t$(PJ_DIR)/pjmedia/lib/libpjsdp-$(LIB_SUFFIX) \\\n\t$(PJ_DIR)/pjnath/lib/libpjnath-$(LIB_SUFFIX) \\\n\t$(PJ_DIR)/pjlib-util/lib/libpjlib-util-$(LIB_SUFFIX) \\\n\t$(APP_THIRD_PARTY_LIB_FILES) \\\n\t$(PJ_DIR)/pjlib/lib/libpj-$(LIB_SUFFIX)\n\n# Here are the variabels to use if application is using the library\n# from within the source distribution\nexport PJ_CC := $(APP_CC)\nexport PJ_CXX := $(APP_CXX)\nexport PJ_CFLAGS := $(APP_CFLAGS)\nexport PJ_CXXFLAGS := $(APP_CXXFLAGS)\nexport PJ_LDFLAGS := $(APP_LDFLAGS)\nexport PJ_LDLIBS := $(APP_LDLIBS)\nexport PJ_LIB_FILES := $(APP_LIB_FILES)\n\n# And here are the variables to use if application is using the\n# library from the install location (i.e. --prefix)\nexport PJ_INSTALL_DIR := @prefix@\nexport PJ_INSTALL_INC_DIR := $(PJ_INSTALL_DIR)/include\nexport PJ_INSTALL_LIB_DIR := $(PJ_INSTALL_DIR)/lib\nexport PJ_INSTALL_CFLAGS := -I$(PJ_INSTALL_INC_DIR) -DPJ_AUTOCONF=1\t@CFLAGS@\nexport PJ_INSTALL_CXXFLAGS := $(PJ_INSTALL_CFLAGS)\nexport PJ_INSTALL_LDFLAGS := -L$(PJ_INSTALL_LIB_DIR) $(APP_LDLIBS)\n"
  },
  {
    "path": "deps/pjsip/config.guess",
    "content": "#!/bin/sh\n# Attempt to guess a canonical system name.\n#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,\n#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,\n#   2011, 2012 Free Software Foundation, Inc.\n\ntimestamp='2012-06-17'\n\n# This file is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, see <http://www.gnu.org/licenses/>.\n#\n# As a special exception to the GNU General Public License, if you\n# distribute this file as part of a program that contains a\n# configuration script generated by Autoconf, you may include it under\n# the same distribution terms that you use for the rest of that program.\n\n\n# Originally written by Per Bothner.  Please send patches (context\n# diff format) to <config-patches@gnu.org> and include a ChangeLog\n# entry.\n#\n# This script attempts to guess a canonical system name similar to\n# config.sub.  If it succeeds, it prints the system name on stdout, and\n# exits with 0.  Otherwise, it exits with 1.\n#\n# You can get the latest version of this script from:\n# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD\n\nme=`echo \"$0\" | sed -e 's,.*/,,'`\n\nusage=\"\\\nUsage: $0 [OPTION]\n\nOutput the configuration name of the system \\`$me' is run on.\n\nOperation modes:\n  -h, --help         print this help, then exit\n  -t, --time-stamp   print date of last modification, then exit\n  -v, --version      print version number, then exit\n\nReport bugs and patches to <config-patches@gnu.org>.\"\n\nversion=\"\\\nGNU config.guess ($timestamp)\n\nOriginally written by Per Bothner.\nCopyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,\n2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012\nFree Software Foundation, Inc.\n\nThis is free software; see the source for copying conditions.  There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\"\n\nhelp=\"\nTry \\`$me --help' for more information.\"\n\n# Parse command line\nwhile test $# -gt 0 ; do\n  case $1 in\n    --time-stamp | --time* | -t )\n       echo \"$timestamp\" ; exit ;;\n    --version | -v )\n       echo \"$version\" ; exit ;;\n    --help | --h* | -h )\n       echo \"$usage\"; exit ;;\n    -- )     # Stop option processing\n       shift; break ;;\n    - )\t# Use stdin as input.\n       break ;;\n    -* )\n       echo \"$me: invalid option $1$help\" >&2\n       exit 1 ;;\n    * )\n       break ;;\n  esac\ndone\n\nif test $# != 0; then\n  echo \"$me: too many arguments$help\" >&2\n  exit 1\nfi\n\ntrap 'exit 1' 1 2 15\n\n# CC_FOR_BUILD -- compiler used by this script. Note that the use of a\n# compiler to aid in system detection is discouraged as it requires\n# temporary files to be created and, as you can see below, it is a\n# headache to deal with in a portable fashion.\n\n# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still\n# use `HOST_CC' if defined, but it is deprecated.\n\n# Portable tmp directory creation inspired by the Autoconf team.\n\nset_cc_for_build='\ntrap \"exitcode=\\$?; (rm -f \\$tmpfiles 2>/dev/null; rmdir \\$tmp 2>/dev/null) && exit \\$exitcode\" 0 ;\ntrap \"rm -f \\$tmpfiles 2>/dev/null; rmdir \\$tmp 2>/dev/null; exit 1\" 1 2 13 15 ;\n: ${TMPDIR=/tmp} ;\n { tmp=`(umask 077 && mktemp -d \"$TMPDIR/cgXXXXXX\") 2>/dev/null` && test -n \"$tmp\" && test -d \"$tmp\" ; } ||\n { test -n \"$RANDOM\" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||\n { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo \"Warning: creating insecure temp directory\" >&2 ; } ||\n { echo \"$me: cannot create a temporary directory in $TMPDIR\" >&2 ; exit 1 ; } ;\ndummy=$tmp/dummy ;\ntmpfiles=\"$dummy.c $dummy.o $dummy.rel $dummy\" ;\ncase $CC_FOR_BUILD,$HOST_CC,$CC in\n ,,)    echo \"int x;\" > $dummy.c ;\n\tfor c in cc gcc c89 c99 ; do\n\t  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then\n\t     CC_FOR_BUILD=\"$c\"; break ;\n\t  fi ;\n\tdone ;\n\tif test x\"$CC_FOR_BUILD\" = x ; then\n\t  CC_FOR_BUILD=no_compiler_found ;\n\tfi\n\t;;\n ,,*)   CC_FOR_BUILD=$CC ;;\n ,*,*)  CC_FOR_BUILD=$HOST_CC ;;\nesac ; set_cc_for_build= ;'\n\n# This is needed to find uname on a Pyramid OSx when run in the BSD universe.\n# (ghazi@noc.rutgers.edu 1994-08-24)\nif (test -f /.attbin/uname) >/dev/null 2>&1 ; then\n\tPATH=$PATH:/.attbin ; export PATH\nfi\n\nUNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown\nUNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown\nUNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown\nUNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown\n\n# Note: order is significant - the case branches are not exclusive.\n\ncase \"${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}\" in\n    *:NetBSD:*:*)\n\t# NetBSD (nbsd) targets should (where applicable) match one or\n\t# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,\n\t# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently\n\t# switched to ELF, *-*-netbsd* would select the old\n\t# object file format.  This provides both forward\n\t# compatibility and a consistent mechanism for selecting the\n\t# object file format.\n\t#\n\t# Note: NetBSD doesn't particularly care about the vendor\n\t# portion of the name.  We always set it to \"unknown\".\n\tsysctl=\"sysctl -n hw.machine_arch\"\n\tUNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \\\n\t    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`\n\tcase \"${UNAME_MACHINE_ARCH}\" in\n\t    armeb) machine=armeb-unknown ;;\n\t    arm*) machine=arm-unknown ;;\n\t    sh3el) machine=shl-unknown ;;\n\t    sh3eb) machine=sh-unknown ;;\n\t    sh5el) machine=sh5le-unknown ;;\n\t    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;\n\tesac\n\t# The Operating System including object format, if it has switched\n\t# to ELF recently, or will in the future.\n\tcase \"${UNAME_MACHINE_ARCH}\" in\n\t    arm*|i386|m68k|ns32k|sh3*|sparc|vax)\n\t\teval $set_cc_for_build\n\t\tif echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \\\n\t\t\t| grep -q __ELF__\n\t\tthen\n\t\t    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).\n\t\t    # Return netbsd for either.  FIX?\n\t\t    os=netbsd\n\t\telse\n\t\t    os=netbsdelf\n\t\tfi\n\t\t;;\n\t    *)\n\t\tos=netbsd\n\t\t;;\n\tesac\n\t# The OS release\n\t# Debian GNU/NetBSD machines have a different userland, and\n\t# thus, need a distinct triplet. However, they do not need\n\t# kernel version information, so it can be replaced with a\n\t# suitable tag, in the style of linux-gnu.\n\tcase \"${UNAME_VERSION}\" in\n\t    Debian*)\n\t\trelease='-gnu'\n\t\t;;\n\t    *)\n\t\trelease=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\\./'`\n\t\t;;\n\tesac\n\t# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:\n\t# contains redundant information, the shorter form:\n\t# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.\n\techo \"${machine}-${os}${release}\"\n\texit ;;\n    *:Bitrig:*:*)\n\tUNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`\n\techo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}\n\texit ;;\n    *:OpenBSD:*:*)\n\tUNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`\n\techo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}\n\texit ;;\n    *:ekkoBSD:*:*)\n\techo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}\n\texit ;;\n    *:SolidBSD:*:*)\n\techo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}\n\texit ;;\n    macppc:MirBSD:*:*)\n\techo powerpc-unknown-mirbsd${UNAME_RELEASE}\n\texit ;;\n    *:MirBSD:*:*)\n\techo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}\n\texit ;;\n    alpha:OSF1:*:*)\n\tcase $UNAME_RELEASE in\n\t*4.0)\n\t\tUNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`\n\t\t;;\n\t*5.*)\n\t\tUNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`\n\t\t;;\n\tesac\n\t# According to Compaq, /usr/sbin/psrinfo has been available on\n\t# OSF/1 and Tru64 systems produced since 1995.  I hope that\n\t# covers most systems running today.  This code pipes the CPU\n\t# types through head -n 1, so we only detect the type of CPU 0.\n\tALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \\(.*\\) processor.*$/\\1/p' | head -n 1`\n\tcase \"$ALPHA_CPU_TYPE\" in\n\t    \"EV4 (21064)\")\n\t\tUNAME_MACHINE=\"alpha\" ;;\n\t    \"EV4.5 (21064)\")\n\t\tUNAME_MACHINE=\"alpha\" ;;\n\t    \"LCA4 (21066/21068)\")\n\t\tUNAME_MACHINE=\"alpha\" ;;\n\t    \"EV5 (21164)\")\n\t\tUNAME_MACHINE=\"alphaev5\" ;;\n\t    \"EV5.6 (21164A)\")\n\t\tUNAME_MACHINE=\"alphaev56\" ;;\n\t    \"EV5.6 (21164PC)\")\n\t\tUNAME_MACHINE=\"alphapca56\" ;;\n\t    \"EV5.7 (21164PC)\")\n\t\tUNAME_MACHINE=\"alphapca57\" ;;\n\t    \"EV6 (21264)\")\n\t\tUNAME_MACHINE=\"alphaev6\" ;;\n\t    \"EV6.7 (21264A)\")\n\t\tUNAME_MACHINE=\"alphaev67\" ;;\n\t    \"EV6.8CB (21264C)\")\n\t\tUNAME_MACHINE=\"alphaev68\" ;;\n\t    \"EV6.8AL (21264B)\")\n\t\tUNAME_MACHINE=\"alphaev68\" ;;\n\t    \"EV6.8CX (21264D)\")\n\t\tUNAME_MACHINE=\"alphaev68\" ;;\n\t    \"EV6.9A (21264/EV69A)\")\n\t\tUNAME_MACHINE=\"alphaev69\" ;;\n\t    \"EV7 (21364)\")\n\t\tUNAME_MACHINE=\"alphaev7\" ;;\n\t    \"EV7.9 (21364A)\")\n\t\tUNAME_MACHINE=\"alphaev79\" ;;\n\tesac\n\t# A Pn.n version is a patched version.\n\t# A Vn.n version is a released version.\n\t# A Tn.n version is a released field test version.\n\t# A Xn.n version is an unreleased experimental baselevel.\n\t# 1.2 uses \"1.2\" for uname -r.\n\techo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`\n\t# Reset EXIT trap before exiting to avoid spurious non-zero exit code.\n\texitcode=$?\n\ttrap '' 0\n\texit $exitcode ;;\n    Alpha\\ *:Windows_NT*:*)\n\t# How do we know it's Interix rather than the generic POSIX subsystem?\n\t# Should we change UNAME_MACHINE based on the output of uname instead\n\t# of the specific Alpha model?\n\techo alpha-pc-interix\n\texit ;;\n    21064:Windows_NT:50:3)\n\techo alpha-dec-winnt3.5\n\texit ;;\n    Amiga*:UNIX_System_V:4.0:*)\n\techo m68k-unknown-sysv4\n\texit ;;\n    *:[Aa]miga[Oo][Ss]:*:*)\n\techo ${UNAME_MACHINE}-unknown-amigaos\n\texit ;;\n    *:[Mm]orph[Oo][Ss]:*:*)\n\techo ${UNAME_MACHINE}-unknown-morphos\n\texit ;;\n    *:OS/390:*:*)\n\techo i370-ibm-openedition\n\texit ;;\n    *:z/VM:*:*)\n\techo s390-ibm-zvmoe\n\texit ;;\n    *:OS400:*:*)\n\techo powerpc-ibm-os400\n\texit ;;\n    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)\n\techo arm-acorn-riscix${UNAME_RELEASE}\n\texit ;;\n    arm:riscos:*:*|arm:RISCOS:*:*)\n\techo arm-unknown-riscos\n\texit ;;\n    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)\n\techo hppa1.1-hitachi-hiuxmpp\n\texit ;;\n    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)\n\t# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.\n\tif test \"`(/bin/universe) 2>/dev/null`\" = att ; then\n\t\techo pyramid-pyramid-sysv3\n\telse\n\t\techo pyramid-pyramid-bsd\n\tfi\n\texit ;;\n    NILE*:*:*:dcosx)\n\techo pyramid-pyramid-svr4\n\texit ;;\n    DRS?6000:unix:4.0:6*)\n\techo sparc-icl-nx6\n\texit ;;\n    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)\n\tcase `/usr/bin/uname -p` in\n\t    sparc) echo sparc-icl-nx7; exit ;;\n\tesac ;;\n    s390x:SunOS:*:*)\n\techo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit ;;\n    sun4H:SunOS:5.*:*)\n\techo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit ;;\n    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)\n\techo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit ;;\n    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)\n\techo i386-pc-auroraux${UNAME_RELEASE}\n\texit ;;\n    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)\n\teval $set_cc_for_build\n\tSUN_ARCH=\"i386\"\n\t# If there is a compiler, see if it is configured for 64-bit objects.\n\t# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.\n\t# This test works for both compilers.\n\tif [ \"$CC_FOR_BUILD\" != 'no_compiler_found' ]; then\n\t    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \\\n\t\t(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \\\n\t\tgrep IS_64BIT_ARCH >/dev/null\n\t    then\n\t\tSUN_ARCH=\"x86_64\"\n\t    fi\n\tfi\n\techo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit ;;\n    sun4*:SunOS:6*:*)\n\t# According to config.sub, this is the proper way to canonicalize\n\t# SunOS6.  Hard to guess exactly what SunOS6 will be like, but\n\t# it's likely to be more like Solaris than SunOS4.\n\techo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit ;;\n    sun4*:SunOS:*:*)\n\tcase \"`/usr/bin/arch -k`\" in\n\t    Series*|S4*)\n\t\tUNAME_RELEASE=`uname -v`\n\t\t;;\n\tesac\n\t# Japanese Language versions have a version number like `4.1.3-JL'.\n\techo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`\n\texit ;;\n    sun3*:SunOS:*:*)\n\techo m68k-sun-sunos${UNAME_RELEASE}\n\texit ;;\n    sun*:*:4.2BSD:*)\n\tUNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`\n\ttest \"x${UNAME_RELEASE}\" = \"x\" && UNAME_RELEASE=3\n\tcase \"`/bin/arch`\" in\n\t    sun3)\n\t\techo m68k-sun-sunos${UNAME_RELEASE}\n\t\t;;\n\t    sun4)\n\t\techo sparc-sun-sunos${UNAME_RELEASE}\n\t\t;;\n\tesac\n\texit ;;\n    aushp:SunOS:*:*)\n\techo sparc-auspex-sunos${UNAME_RELEASE}\n\texit ;;\n    # The situation for MiNT is a little confusing.  The machine name\n    # can be virtually everything (everything which is not\n    # \"atarist\" or \"atariste\" at least should have a processor\n    # > m68000).  The system name ranges from \"MiNT\" over \"FreeMiNT\"\n    # to the lowercase version \"mint\" (or \"freemint\").  Finally\n    # the system name \"TOS\" denotes a system which is actually not\n    # MiNT.  But MiNT is downward compatible to TOS, so this should\n    # be no problem.\n    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)\n\techo m68k-atari-mint${UNAME_RELEASE}\n\texit ;;\n    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)\n\techo m68k-atari-mint${UNAME_RELEASE}\n\texit ;;\n    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)\n\techo m68k-atari-mint${UNAME_RELEASE}\n\texit ;;\n    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)\n\techo m68k-milan-mint${UNAME_RELEASE}\n\texit ;;\n    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)\n\techo m68k-hades-mint${UNAME_RELEASE}\n\texit ;;\n    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)\n\techo m68k-unknown-mint${UNAME_RELEASE}\n\texit ;;\n    m68k:machten:*:*)\n\techo m68k-apple-machten${UNAME_RELEASE}\n\texit ;;\n    powerpc:machten:*:*)\n\techo powerpc-apple-machten${UNAME_RELEASE}\n\texit ;;\n    RISC*:Mach:*:*)\n\techo mips-dec-mach_bsd4.3\n\texit ;;\n    RISC*:ULTRIX:*:*)\n\techo mips-dec-ultrix${UNAME_RELEASE}\n\texit ;;\n    VAX*:ULTRIX*:*:*)\n\techo vax-dec-ultrix${UNAME_RELEASE}\n\texit ;;\n    2020:CLIX:*:* | 2430:CLIX:*:*)\n\techo clipper-intergraph-clix${UNAME_RELEASE}\n\texit ;;\n    mips:*:*:UMIPS | mips:*:*:RISCos)\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n#ifdef __cplusplus\n#include <stdio.h>  /* for printf() prototype */\n\tint main (int argc, char *argv[]) {\n#else\n\tint main (argc, argv) int argc; char *argv[]; {\n#endif\n\t#if defined (host_mips) && defined (MIPSEB)\n\t#if defined (SYSTYPE_SYSV)\n\t  printf (\"mips-mips-riscos%ssysv\\n\", argv[1]); exit (0);\n\t#endif\n\t#if defined (SYSTYPE_SVR4)\n\t  printf (\"mips-mips-riscos%ssvr4\\n\", argv[1]); exit (0);\n\t#endif\n\t#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)\n\t  printf (\"mips-mips-riscos%sbsd\\n\", argv[1]); exit (0);\n\t#endif\n\t#endif\n\t  exit (-1);\n\t}\nEOF\n\t$CC_FOR_BUILD -o $dummy $dummy.c &&\n\t  dummyarg=`echo \"${UNAME_RELEASE}\" | sed -n 's/\\([0-9]*\\).*/\\1/p'` &&\n\t  SYSTEM_NAME=`$dummy $dummyarg` &&\n\t    { echo \"$SYSTEM_NAME\"; exit; }\n\techo mips-mips-riscos${UNAME_RELEASE}\n\texit ;;\n    Motorola:PowerMAX_OS:*:*)\n\techo powerpc-motorola-powermax\n\texit ;;\n    Motorola:*:4.3:PL8-*)\n\techo powerpc-harris-powermax\n\texit ;;\n    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)\n\techo powerpc-harris-powermax\n\texit ;;\n    Night_Hawk:Power_UNIX:*:*)\n\techo powerpc-harris-powerunix\n\texit ;;\n    m88k:CX/UX:7*:*)\n\techo m88k-harris-cxux7\n\texit ;;\n    m88k:*:4*:R4*)\n\techo m88k-motorola-sysv4\n\texit ;;\n    m88k:*:3*:R3*)\n\techo m88k-motorola-sysv3\n\texit ;;\n    AViiON:dgux:*:*)\n\t# DG/UX returns AViiON for all architectures\n\tUNAME_PROCESSOR=`/usr/bin/uname -p`\n\tif [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]\n\tthen\n\t    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \\\n\t       [ ${TARGET_BINARY_INTERFACE}x = x ]\n\t    then\n\t\techo m88k-dg-dgux${UNAME_RELEASE}\n\t    else\n\t\techo m88k-dg-dguxbcs${UNAME_RELEASE}\n\t    fi\n\telse\n\t    echo i586-dg-dgux${UNAME_RELEASE}\n\tfi\n\texit ;;\n    M88*:DolphinOS:*:*)\t# DolphinOS (SVR3)\n\techo m88k-dolphin-sysv3\n\texit ;;\n    M88*:*:R3*:*)\n\t# Delta 88k system running SVR3\n\techo m88k-motorola-sysv3\n\texit ;;\n    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)\n\techo m88k-tektronix-sysv3\n\texit ;;\n    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)\n\techo m68k-tektronix-bsd\n\texit ;;\n    *:IRIX*:*:*)\n\techo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`\n\texit ;;\n    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.\n\techo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id\n\texit ;;               # Note that: echo \"'`uname -s`'\" gives 'AIX '\n    i*86:AIX:*:*)\n\techo i386-ibm-aix\n\texit ;;\n    ia64:AIX:*:*)\n\tif [ -x /usr/bin/oslevel ] ; then\n\t\tIBM_REV=`/usr/bin/oslevel`\n\telse\n\t\tIBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}\n\tfi\n\techo ${UNAME_MACHINE}-ibm-aix${IBM_REV}\n\texit ;;\n    *:AIX:2:3)\n\tif grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then\n\t\teval $set_cc_for_build\n\t\tsed 's/^\t\t//' << EOF >$dummy.c\n\t\t#include <sys/systemcfg.h>\n\n\t\tmain()\n\t\t\t{\n\t\t\tif (!__power_pc())\n\t\t\t\texit(1);\n\t\t\tputs(\"powerpc-ibm-aix3.2.5\");\n\t\t\texit(0);\n\t\t\t}\nEOF\n\t\tif $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`\n\t\tthen\n\t\t\techo \"$SYSTEM_NAME\"\n\t\telse\n\t\t\techo rs6000-ibm-aix3.2.5\n\t\tfi\n\telif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then\n\t\techo rs6000-ibm-aix3.2.4\n\telse\n\t\techo rs6000-ibm-aix3.2\n\tfi\n\texit ;;\n    *:AIX:*:[4567])\n\tIBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`\n\tif /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then\n\t\tIBM_ARCH=rs6000\n\telse\n\t\tIBM_ARCH=powerpc\n\tfi\n\tif [ -x /usr/bin/oslevel ] ; then\n\t\tIBM_REV=`/usr/bin/oslevel`\n\telse\n\t\tIBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}\n\tfi\n\techo ${IBM_ARCH}-ibm-aix${IBM_REV}\n\texit ;;\n    *:AIX:*:*)\n\techo rs6000-ibm-aix\n\texit ;;\n    ibmrt:4.4BSD:*|romp-ibm:BSD:*)\n\techo romp-ibm-bsd4.4\n\texit ;;\n    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and\n\techo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to\n\texit ;;                             # report: romp-ibm BSD 4.3\n    *:BOSX:*:*)\n\techo rs6000-bull-bosx\n\texit ;;\n    DPX/2?00:B.O.S.:*:*)\n\techo m68k-bull-sysv3\n\texit ;;\n    9000/[34]??:4.3bsd:1.*:*)\n\techo m68k-hp-bsd\n\texit ;;\n    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)\n\techo m68k-hp-bsd4.4\n\texit ;;\n    9000/[34678]??:HP-UX:*:*)\n\tHPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`\n\tcase \"${UNAME_MACHINE}\" in\n\t    9000/31? )            HP_ARCH=m68000 ;;\n\t    9000/[34]?? )         HP_ARCH=m68k ;;\n\t    9000/[678][0-9][0-9])\n\t\tif [ -x /usr/bin/getconf ]; then\n\t\t    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`\n\t\t    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`\n\t\t    case \"${sc_cpu_version}\" in\n\t\t      523) HP_ARCH=\"hppa1.0\" ;; # CPU_PA_RISC1_0\n\t\t      528) HP_ARCH=\"hppa1.1\" ;; # CPU_PA_RISC1_1\n\t\t      532)                      # CPU_PA_RISC2_0\n\t\t\tcase \"${sc_kernel_bits}\" in\n\t\t\t  32) HP_ARCH=\"hppa2.0n\" ;;\n\t\t\t  64) HP_ARCH=\"hppa2.0w\" ;;\n\t\t\t  '') HP_ARCH=\"hppa2.0\" ;;   # HP-UX 10.20\n\t\t\tesac ;;\n\t\t    esac\n\t\tfi\n\t\tif [ \"${HP_ARCH}\" = \"\" ]; then\n\t\t    eval $set_cc_for_build\n\t\t    sed 's/^\t\t//' << EOF >$dummy.c\n\n\t\t#define _HPUX_SOURCE\n\t\t#include <stdlib.h>\n\t\t#include <unistd.h>\n\n\t\tint main ()\n\t\t{\n\t\t#if defined(_SC_KERNEL_BITS)\n\t\t    long bits = sysconf(_SC_KERNEL_BITS);\n\t\t#endif\n\t\t    long cpu  = sysconf (_SC_CPU_VERSION);\n\n\t\t    switch (cpu)\n\t\t\t{\n\t\t\tcase CPU_PA_RISC1_0: puts (\"hppa1.0\"); break;\n\t\t\tcase CPU_PA_RISC1_1: puts (\"hppa1.1\"); break;\n\t\t\tcase CPU_PA_RISC2_0:\n\t\t#if defined(_SC_KERNEL_BITS)\n\t\t\t    switch (bits)\n\t\t\t\t{\n\t\t\t\tcase 64: puts (\"hppa2.0w\"); break;\n\t\t\t\tcase 32: puts (\"hppa2.0n\"); break;\n\t\t\t\tdefault: puts (\"hppa2.0\"); break;\n\t\t\t\t} break;\n\t\t#else  /* !defined(_SC_KERNEL_BITS) */\n\t\t\t    puts (\"hppa2.0\"); break;\n\t\t#endif\n\t\t\tdefault: puts (\"hppa1.0\"); break;\n\t\t\t}\n\t\t    exit (0);\n\t\t}\nEOF\n\t\t    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`\n\t\t    test -z \"$HP_ARCH\" && HP_ARCH=hppa\n\t\tfi ;;\n\tesac\n\tif [ ${HP_ARCH} = \"hppa2.0w\" ]\n\tthen\n\t    eval $set_cc_for_build\n\n\t    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating\n\t    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler\n\t    # generating 64-bit code.  GNU and HP use different nomenclature:\n\t    #\n\t    # $ CC_FOR_BUILD=cc ./config.guess\n\t    # => hppa2.0w-hp-hpux11.23\n\t    # $ CC_FOR_BUILD=\"cc +DA2.0w\" ./config.guess\n\t    # => hppa64-hp-hpux11.23\n\n\t    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |\n\t\tgrep -q __LP64__\n\t    then\n\t\tHP_ARCH=\"hppa2.0w\"\n\t    else\n\t\tHP_ARCH=\"hppa64\"\n\t    fi\n\tfi\n\techo ${HP_ARCH}-hp-hpux${HPUX_REV}\n\texit ;;\n    ia64:HP-UX:*:*)\n\tHPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`\n\techo ia64-hp-hpux${HPUX_REV}\n\texit ;;\n    3050*:HI-UX:*:*)\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#include <unistd.h>\n\tint\n\tmain ()\n\t{\n\t  long cpu = sysconf (_SC_CPU_VERSION);\n\t  /* The order matters, because CPU_IS_HP_MC68K erroneously returns\n\t     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct\n\t     results, however.  */\n\t  if (CPU_IS_PA_RISC (cpu))\n\t    {\n\t      switch (cpu)\n\t\t{\n\t\t  case CPU_PA_RISC1_0: puts (\"hppa1.0-hitachi-hiuxwe2\"); break;\n\t\t  case CPU_PA_RISC1_1: puts (\"hppa1.1-hitachi-hiuxwe2\"); break;\n\t\t  case CPU_PA_RISC2_0: puts (\"hppa2.0-hitachi-hiuxwe2\"); break;\n\t\t  default: puts (\"hppa-hitachi-hiuxwe2\"); break;\n\t\t}\n\t    }\n\t  else if (CPU_IS_HP_MC68K (cpu))\n\t    puts (\"m68k-hitachi-hiuxwe2\");\n\t  else puts (\"unknown-hitachi-hiuxwe2\");\n\t  exit (0);\n\t}\nEOF\n\t$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&\n\t\t{ echo \"$SYSTEM_NAME\"; exit; }\n\techo unknown-hitachi-hiuxwe2\n\texit ;;\n    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )\n\techo hppa1.1-hp-bsd\n\texit ;;\n    9000/8??:4.3bsd:*:*)\n\techo hppa1.0-hp-bsd\n\texit ;;\n    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)\n\techo hppa1.0-hp-mpeix\n\texit ;;\n    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )\n\techo hppa1.1-hp-osf\n\texit ;;\n    hp8??:OSF1:*:*)\n\techo hppa1.0-hp-osf\n\texit ;;\n    i*86:OSF1:*:*)\n\tif [ -x /usr/sbin/sysversion ] ; then\n\t    echo ${UNAME_MACHINE}-unknown-osf1mk\n\telse\n\t    echo ${UNAME_MACHINE}-unknown-osf1\n\tfi\n\texit ;;\n    parisc*:Lites*:*:*)\n\techo hppa1.1-hp-lites\n\texit ;;\n    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)\n\techo c1-convex-bsd\n\texit ;;\n    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)\n\tif getsysinfo -f scalar_acc\n\tthen echo c32-convex-bsd\n\telse echo c2-convex-bsd\n\tfi\n\texit ;;\n    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)\n\techo c34-convex-bsd\n\texit ;;\n    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)\n\techo c38-convex-bsd\n\texit ;;\n    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)\n\techo c4-convex-bsd\n\texit ;;\n    CRAY*Y-MP:*:*:*)\n\techo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit ;;\n    CRAY*[A-Z]90:*:*:*)\n\techo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \\\n\t| sed -e 's/CRAY.*\\([A-Z]90\\)/\\1/' \\\n\t      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \\\n\t      -e 's/\\.[^.]*$/.X/'\n\texit ;;\n    CRAY*TS:*:*:*)\n\techo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit ;;\n    CRAY*T3E:*:*:*)\n\techo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit ;;\n    CRAY*SV1:*:*:*)\n\techo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit ;;\n    *:UNICOS/mp:*:*)\n\techo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit ;;\n    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)\n\tFUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`\n\tFUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\\///'`\n\tFUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`\n\techo \"${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}\"\n\texit ;;\n    5000:UNIX_System_V:4.*:*)\n\tFUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\\///'`\n\tFUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`\n\techo \"sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}\"\n\texit ;;\n    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\\ Embedded/OS:*:*)\n\techo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}\n\texit ;;\n    sparc*:BSD/OS:*:*)\n\techo sparc-unknown-bsdi${UNAME_RELEASE}\n\texit ;;\n    *:BSD/OS:*:*)\n\techo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}\n\texit ;;\n    *:FreeBSD:*:*)\n\tUNAME_PROCESSOR=`/usr/bin/uname -p`\n\tcase ${UNAME_PROCESSOR} in\n\t    amd64)\n\t\techo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;\n\t    *)\n\t\techo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;\n\tesac\n\texit ;;\n    i*:CYGWIN*:*)\n\techo ${UNAME_MACHINE}-pc-cygwin\n\texit ;;\n    *:MINGW*:*)\n\techo ${UNAME_MACHINE}-pc-mingw32\n\texit ;;\n    i*:MSYS*:*)\n\techo ${UNAME_MACHINE}-pc-msys\n\texit ;;\n    i*:windows32*:*)\n\t# uname -m includes \"-pc\" on this system.\n\techo ${UNAME_MACHINE}-mingw32\n\texit ;;\n    i*:PW*:*)\n\techo ${UNAME_MACHINE}-pc-pw32\n\texit ;;\n    *:Interix*:*)\n\tcase ${UNAME_MACHINE} in\n\t    x86)\n\t\techo i586-pc-interix${UNAME_RELEASE}\n\t\texit ;;\n\t    authenticamd | genuineintel | EM64T)\n\t\techo x86_64-unknown-interix${UNAME_RELEASE}\n\t\texit ;;\n\t    IA64)\n\t\techo ia64-unknown-interix${UNAME_RELEASE}\n\t\texit ;;\n\tesac ;;\n    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)\n\techo i${UNAME_MACHINE}-pc-mks\n\texit ;;\n    8664:Windows_NT:*)\n\techo x86_64-pc-mks\n\texit ;;\n    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)\n\t# How do we know it's Interix rather than the generic POSIX subsystem?\n\t# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we\n\t# UNAME_MACHINE based on the output of uname instead of i386?\n\techo i586-pc-interix\n\texit ;;\n    i*:UWIN*:*)\n\techo ${UNAME_MACHINE}-pc-uwin\n\texit ;;\n    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)\n\techo x86_64-unknown-cygwin\n\texit ;;\n    p*:CYGWIN*:*)\n\techo powerpcle-unknown-cygwin\n\texit ;;\n    prep*:SunOS:5.*:*)\n\techo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit ;;\n    *:GNU:*:*)\n\t# the GNU system\n\techo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`\n\texit ;;\n    *:GNU/*:*:*)\n\t# other systems with GNU libc and userland\n\techo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu\n\texit ;;\n    i*86:Minix:*:*)\n\techo ${UNAME_MACHINE}-pc-minix\n\texit ;;\n    aarch64:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    aarch64_be:Linux:*:*)\n\tUNAME_MACHINE=aarch64_be\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    alpha:Linux:*:*)\n\tcase `sed -n '/^cpu model/s/^.*: \\(.*\\)/\\1/p' < /proc/cpuinfo` in\n\t  EV5)   UNAME_MACHINE=alphaev5 ;;\n\t  EV56)  UNAME_MACHINE=alphaev56 ;;\n\t  PCA56) UNAME_MACHINE=alphapca56 ;;\n\t  PCA57) UNAME_MACHINE=alphapca56 ;;\n\t  EV6)   UNAME_MACHINE=alphaev6 ;;\n\t  EV67)  UNAME_MACHINE=alphaev67 ;;\n\t  EV68*) UNAME_MACHINE=alphaev68 ;;\n\tesac\n\tobjdump --private-headers /bin/sh | grep -q ld.so.1\n\tif test \"$?\" = 0 ; then LIBC=\"libc1\" ; else LIBC=\"\" ; fi\n\techo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}\n\texit ;;\n    arm*:Linux:*:*)\n\teval $set_cc_for_build\n\tif echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \\\n\t    | grep -q __ARM_EABI__\n\tthen\n\t    echo ${UNAME_MACHINE}-unknown-linux-gnu\n\telse\n\t    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \\\n\t\t| grep -q __ARM_PCS_VFP\n\t    then\n\t\techo ${UNAME_MACHINE}-unknown-linux-gnueabi\n\t    else\n\t\techo ${UNAME_MACHINE}-unknown-linux-gnueabihf\n\t    fi\n\tfi\n\texit ;;\n    avr32*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    cris:Linux:*:*)\n\techo ${UNAME_MACHINE}-axis-linux-gnu\n\texit ;;\n    crisv32:Linux:*:*)\n\techo ${UNAME_MACHINE}-axis-linux-gnu\n\texit ;;\n    frv:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    hexagon:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    i*86:Linux:*:*)\n\tLIBC=gnu\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#ifdef __dietlibc__\n\tLIBC=dietlibc\n\t#endif\nEOF\n\teval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`\n\techo \"${UNAME_MACHINE}-pc-linux-${LIBC}\"\n\texit ;;\n    ia64:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    m32r*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    m68*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    mips:Linux:*:* | mips64:Linux:*:*)\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#undef CPU\n\t#undef ${UNAME_MACHINE}\n\t#undef ${UNAME_MACHINE}el\n\t#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)\n\tCPU=${UNAME_MACHINE}el\n\t#else\n\t#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)\n\tCPU=${UNAME_MACHINE}\n\t#else\n\tCPU=\n\t#endif\n\t#endif\nEOF\n\teval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`\n\ttest x\"${CPU}\" != x && { echo \"${CPU}-unknown-linux-gnu\"; exit; }\n\t;;\n    or32:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    padre:Linux:*:*)\n\techo sparc-unknown-linux-gnu\n\texit ;;\n    parisc64:Linux:*:* | hppa64:Linux:*:*)\n\techo hppa64-unknown-linux-gnu\n\texit ;;\n    parisc:Linux:*:* | hppa:Linux:*:*)\n\t# Look for CPU level\n\tcase `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in\n\t  PA7*) echo hppa1.1-unknown-linux-gnu ;;\n\t  PA8*) echo hppa2.0-unknown-linux-gnu ;;\n\t  *)    echo hppa-unknown-linux-gnu ;;\n\tesac\n\texit ;;\n    ppc64:Linux:*:*)\n\techo powerpc64-unknown-linux-gnu\n\texit ;;\n    ppc:Linux:*:*)\n\techo powerpc-unknown-linux-gnu\n\texit ;;\n    s390:Linux:*:* | s390x:Linux:*:*)\n\techo ${UNAME_MACHINE}-ibm-linux\n\texit ;;\n    sh64*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    sh*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    sparc:Linux:*:* | sparc64:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    tile*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    vax:Linux:*:*)\n\techo ${UNAME_MACHINE}-dec-linux-gnu\n\texit ;;\n    x86_64:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    xtensa*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    i*86:DYNIX/ptx:4*:*)\n\t# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.\n\t# earlier versions are messed up and put the nodename in both\n\t# sysname and nodename.\n\techo i386-sequent-sysv4\n\texit ;;\n    i*86:UNIX_SV:4.2MP:2.*)\n\t# Unixware is an offshoot of SVR4, but it has its own version\n\t# number series starting with 2...\n\t# I am not positive that other SVR4 systems won't match this,\n\t# I just have to hope.  -- rms.\n\t# Use sysv4.2uw... so that sysv4* matches it.\n\techo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}\n\texit ;;\n    i*86:OS/2:*:*)\n\t# If we were able to find `uname', then EMX Unix compatibility\n\t# is probably installed.\n\techo ${UNAME_MACHINE}-pc-os2-emx\n\texit ;;\n    i*86:XTS-300:*:STOP)\n\techo ${UNAME_MACHINE}-unknown-stop\n\texit ;;\n    i*86:atheos:*:*)\n\techo ${UNAME_MACHINE}-unknown-atheos\n\texit ;;\n    i*86:syllable:*:*)\n\techo ${UNAME_MACHINE}-pc-syllable\n\texit ;;\n    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)\n\techo i386-unknown-lynxos${UNAME_RELEASE}\n\texit ;;\n    i*86:*DOS:*:*)\n\techo ${UNAME_MACHINE}-pc-msdosdjgpp\n\texit ;;\n    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)\n\tUNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\\/MP$//'`\n\tif grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then\n\t\techo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}\n\telse\n\t\techo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}\n\tfi\n\texit ;;\n    i*86:*:5:[678]*)\n\t# UnixWare 7.x, OpenUNIX and OpenServer 6.\n\tcase `/bin/uname -X | grep \"^Machine\"` in\n\t    *486*)\t     UNAME_MACHINE=i486 ;;\n\t    *Pentium)\t     UNAME_MACHINE=i586 ;;\n\t    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;\n\tesac\n\techo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}\n\texit ;;\n    i*86:*:3.2:*)\n\tif test -f /usr/options/cb.name; then\n\t\tUNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`\n\t\techo ${UNAME_MACHINE}-pc-isc$UNAME_REL\n\telif /bin/uname -X 2>/dev/null >/dev/null ; then\n\t\tUNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`\n\t\t(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486\n\t\t(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \\\n\t\t\t&& UNAME_MACHINE=i586\n\t\t(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \\\n\t\t\t&& UNAME_MACHINE=i686\n\t\t(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \\\n\t\t\t&& UNAME_MACHINE=i686\n\t\techo ${UNAME_MACHINE}-pc-sco$UNAME_REL\n\telse\n\t\techo ${UNAME_MACHINE}-pc-sysv32\n\tfi\n\texit ;;\n    pc:*:*:*)\n\t# Left here for compatibility:\n\t# uname -m prints for DJGPP always 'pc', but it prints nothing about\n\t# the processor, so we play safe by assuming i586.\n\t# Note: whatever this is, it MUST be the same as what config.sub\n\t# prints for the \"djgpp\" host, or else GDB configury will decide that\n\t# this is a cross-build.\n\techo i586-pc-msdosdjgpp\n\texit ;;\n    Intel:Mach:3*:*)\n\techo i386-pc-mach3\n\texit ;;\n    paragon:*:*:*)\n\techo i860-intel-osf1\n\texit ;;\n    i860:*:4.*:*) # i860-SVR4\n\tif grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then\n\t  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4\n\telse # Add other i860-SVR4 vendors below as they are discovered.\n\t  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4\n\tfi\n\texit ;;\n    mini*:CTIX:SYS*5:*)\n\t# \"miniframe\"\n\techo m68010-convergent-sysv\n\texit ;;\n    mc68k:UNIX:SYSTEM5:3.51m)\n\techo m68k-convergent-sysv\n\texit ;;\n    M680?0:D-NIX:5.3:*)\n\techo m68k-diab-dnix\n\texit ;;\n    M68*:*:R3V[5678]*:*)\n\ttest -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;\n    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)\n\tOS_REL=''\n\ttest -r /etc/.relid \\\n\t&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \\([0-9][0-9]\\).*/\\1/p' < /etc/.relid`\n\t/bin/uname -p 2>/dev/null | grep 86 >/dev/null \\\n\t  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }\n\t/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \\\n\t  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;\n    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)\n\t/bin/uname -p 2>/dev/null | grep 86 >/dev/null \\\n\t  && { echo i486-ncr-sysv4; exit; } ;;\n    NCR*:*:4.2:* | MPRAS*:*:4.2:*)\n\tOS_REL='.3'\n\ttest -r /etc/.relid \\\n\t    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \\([0-9][0-9]\\).*/\\1/p' < /etc/.relid`\n\t/bin/uname -p 2>/dev/null | grep 86 >/dev/null \\\n\t    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }\n\t/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \\\n\t    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }\n\t/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \\\n\t    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;\n    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)\n\techo m68k-unknown-lynxos${UNAME_RELEASE}\n\texit ;;\n    mc68030:UNIX_System_V:4.*:*)\n\techo m68k-atari-sysv4\n\texit ;;\n    TSUNAMI:LynxOS:2.*:*)\n\techo sparc-unknown-lynxos${UNAME_RELEASE}\n\texit ;;\n    rs6000:LynxOS:2.*:*)\n\techo rs6000-unknown-lynxos${UNAME_RELEASE}\n\texit ;;\n    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)\n\techo powerpc-unknown-lynxos${UNAME_RELEASE}\n\texit ;;\n    SM[BE]S:UNIX_SV:*:*)\n\techo mips-dde-sysv${UNAME_RELEASE}\n\texit ;;\n    RM*:ReliantUNIX-*:*:*)\n\techo mips-sni-sysv4\n\texit ;;\n    RM*:SINIX-*:*:*)\n\techo mips-sni-sysv4\n\texit ;;\n    *:SINIX-*:*:*)\n\tif uname -p 2>/dev/null >/dev/null ; then\n\t\tUNAME_MACHINE=`(uname -p) 2>/dev/null`\n\t\techo ${UNAME_MACHINE}-sni-sysv4\n\telse\n\t\techo ns32k-sni-sysv\n\tfi\n\texit ;;\n    PENTIUM:*:4.0*:*)\t# Unisys `ClearPath HMP IX 4000' SVR4/MP effort\n\t\t\t# says <Richard.M.Bartel@ccMail.Census.GOV>\n\techo i586-unisys-sysv4\n\texit ;;\n    *:UNIX_System_V:4*:FTX*)\n\t# From Gerald Hewes <hewes@openmarket.com>.\n\t# How about differentiating between stratus architectures? -djm\n\techo hppa1.1-stratus-sysv4\n\texit ;;\n    *:*:*:FTX*)\n\t# From seanf@swdc.stratus.com.\n\techo i860-stratus-sysv4\n\texit ;;\n    i*86:VOS:*:*)\n\t# From Paul.Green@stratus.com.\n\techo ${UNAME_MACHINE}-stratus-vos\n\texit ;;\n    *:VOS:*:*)\n\t# From Paul.Green@stratus.com.\n\techo hppa1.1-stratus-vos\n\texit ;;\n    mc68*:A/UX:*:*)\n\techo m68k-apple-aux${UNAME_RELEASE}\n\texit ;;\n    news*:NEWS-OS:6*:*)\n\techo mips-sony-newsos6\n\texit ;;\n    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)\n\tif [ -d /usr/nec ]; then\n\t\techo mips-nec-sysv${UNAME_RELEASE}\n\telse\n\t\techo mips-unknown-sysv${UNAME_RELEASE}\n\tfi\n\texit ;;\n    BeBox:BeOS:*:*)\t# BeOS running on hardware made by Be, PPC only.\n\techo powerpc-be-beos\n\texit ;;\n    BeMac:BeOS:*:*)\t# BeOS running on Mac or Mac clone, PPC only.\n\techo powerpc-apple-beos\n\texit ;;\n    BePC:BeOS:*:*)\t# BeOS running on Intel PC compatible.\n\techo i586-pc-beos\n\texit ;;\n    BePC:Haiku:*:*)\t# Haiku running on Intel PC compatible.\n\techo i586-pc-haiku\n\texit ;;\n    SX-4:SUPER-UX:*:*)\n\techo sx4-nec-superux${UNAME_RELEASE}\n\texit ;;\n    SX-5:SUPER-UX:*:*)\n\techo sx5-nec-superux${UNAME_RELEASE}\n\texit ;;\n    SX-6:SUPER-UX:*:*)\n\techo sx6-nec-superux${UNAME_RELEASE}\n\texit ;;\n    SX-7:SUPER-UX:*:*)\n\techo sx7-nec-superux${UNAME_RELEASE}\n\texit ;;\n    SX-8:SUPER-UX:*:*)\n\techo sx8-nec-superux${UNAME_RELEASE}\n\texit ;;\n    SX-8R:SUPER-UX:*:*)\n\techo sx8r-nec-superux${UNAME_RELEASE}\n\texit ;;\n    Power*:Rhapsody:*:*)\n\techo powerpc-apple-rhapsody${UNAME_RELEASE}\n\texit ;;\n    *:Rhapsody:*:*)\n\techo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}\n\texit ;;\n    *:Darwin:*:*)\n\tUNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown\n\tcase $UNAME_PROCESSOR in\n\t    i386)\n\t\teval $set_cc_for_build\n\t\tif [ \"$CC_FOR_BUILD\" != 'no_compiler_found' ]; then\n\t\t  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \\\n\t\t      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \\\n\t\t      grep IS_64BIT_ARCH >/dev/null\n\t\t  then\n\t\t      UNAME_PROCESSOR=\"x86_64\"\n\t\t  fi\n\t\tfi ;;\n\t    unknown) UNAME_PROCESSOR=powerpc ;;\n\tesac\n\techo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}\n\texit ;;\n    *:procnto*:*:* | *:QNX:[0123456789]*:*)\n\tUNAME_PROCESSOR=`uname -p`\n\tif test \"$UNAME_PROCESSOR\" = \"x86\"; then\n\t\tUNAME_PROCESSOR=i386\n\t\tUNAME_MACHINE=pc\n\tfi\n\techo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}\n\texit ;;\n    *:QNX:*:4*)\n\techo i386-pc-qnx\n\texit ;;\n    NEO-?:NONSTOP_KERNEL:*:*)\n\techo neo-tandem-nsk${UNAME_RELEASE}\n\texit ;;\n    NSE-*:NONSTOP_KERNEL:*:*)\n\techo nse-tandem-nsk${UNAME_RELEASE}\n\texit ;;\n    NSR-?:NONSTOP_KERNEL:*:*)\n\techo nsr-tandem-nsk${UNAME_RELEASE}\n\texit ;;\n    *:NonStop-UX:*:*)\n\techo mips-compaq-nonstopux\n\texit ;;\n    BS2000:POSIX*:*:*)\n\techo bs2000-siemens-sysv\n\texit ;;\n    DS/*:UNIX_System_V:*:*)\n\techo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}\n\texit ;;\n    *:Plan9:*:*)\n\t# \"uname -m\" is not consistent, so use $cputype instead. 386\n\t# is converted to i386 for consistency with other x86\n\t# operating systems.\n\tif test \"$cputype\" = \"386\"; then\n\t    UNAME_MACHINE=i386\n\telse\n\t    UNAME_MACHINE=\"$cputype\"\n\tfi\n\techo ${UNAME_MACHINE}-unknown-plan9\n\texit ;;\n    *:TOPS-10:*:*)\n\techo pdp10-unknown-tops10\n\texit ;;\n    *:TENEX:*:*)\n\techo pdp10-unknown-tenex\n\texit ;;\n    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)\n\techo pdp10-dec-tops20\n\texit ;;\n    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)\n\techo pdp10-xkl-tops20\n\texit ;;\n    *:TOPS-20:*:*)\n\techo pdp10-unknown-tops20\n\texit ;;\n    *:ITS:*:*)\n\techo pdp10-unknown-its\n\texit ;;\n    SEI:*:*:SEIUX)\n\techo mips-sei-seiux${UNAME_RELEASE}\n\texit ;;\n    *:DragonFly:*:*)\n\techo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`\n\texit ;;\n    *:*VMS:*:*)\n\tUNAME_MACHINE=`(uname -p) 2>/dev/null`\n\tcase \"${UNAME_MACHINE}\" in\n\t    A*) echo alpha-dec-vms ; exit ;;\n\t    I*) echo ia64-dec-vms ; exit ;;\n\t    V*) echo vax-dec-vms ; exit ;;\n\tesac ;;\n    *:XENIX:*:SysV)\n\techo i386-pc-xenix\n\texit ;;\n    i*86:skyos:*:*)\n\techo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'\n\texit ;;\n    i*86:rdos:*:*)\n\techo ${UNAME_MACHINE}-pc-rdos\n\texit ;;\n    i*86:AROS:*:*)\n\techo ${UNAME_MACHINE}-pc-aros\n\texit ;;\n    x86_64:VMkernel:*:*)\n\techo ${UNAME_MACHINE}-unknown-esx\n\texit ;;\nesac\n\n#echo '(No uname command or uname output not recognized.)' 1>&2\n#echo \"${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}\" 1>&2\n\neval $set_cc_for_build\ncat >$dummy.c <<EOF\n#ifdef _SEQUENT_\n# include <sys/types.h>\n# include <sys/utsname.h>\n#endif\nmain ()\n{\n#if defined (sony)\n#if defined (MIPSEB)\n  /* BFD wants \"bsd\" instead of \"newsos\".  Perhaps BFD should be changed,\n     I don't know....  */\n  printf (\"mips-sony-bsd\\n\"); exit (0);\n#else\n#include <sys/param.h>\n  printf (\"m68k-sony-newsos%s\\n\",\n#ifdef NEWSOS4\n\t\"4\"\n#else\n\t\"\"\n#endif\n\t); exit (0);\n#endif\n#endif\n\n#if defined (__arm) && defined (__acorn) && defined (__unix)\n  printf (\"arm-acorn-riscix\\n\"); exit (0);\n#endif\n\n#if defined (hp300) && !defined (hpux)\n  printf (\"m68k-hp-bsd\\n\"); exit (0);\n#endif\n\n#if defined (NeXT)\n#if !defined (__ARCHITECTURE__)\n#define __ARCHITECTURE__ \"m68k\"\n#endif\n  int version;\n  version=`(hostinfo | sed -n 's/.*NeXT Mach \\([0-9]*\\).*/\\1/p') 2>/dev/null`;\n  if (version < 4)\n    printf (\"%s-next-nextstep%d\\n\", __ARCHITECTURE__, version);\n  else\n    printf (\"%s-next-openstep%d\\n\", __ARCHITECTURE__, version);\n  exit (0);\n#endif\n\n#if defined (MULTIMAX) || defined (n16)\n#if defined (UMAXV)\n  printf (\"ns32k-encore-sysv\\n\"); exit (0);\n#else\n#if defined (CMU)\n  printf (\"ns32k-encore-mach\\n\"); exit (0);\n#else\n  printf (\"ns32k-encore-bsd\\n\"); exit (0);\n#endif\n#endif\n#endif\n\n#if defined (__386BSD__)\n  printf (\"i386-pc-bsd\\n\"); exit (0);\n#endif\n\n#if defined (sequent)\n#if defined (i386)\n  printf (\"i386-sequent-dynix\\n\"); exit (0);\n#endif\n#if defined (ns32000)\n  printf (\"ns32k-sequent-dynix\\n\"); exit (0);\n#endif\n#endif\n\n#if defined (_SEQUENT_)\n    struct utsname un;\n\n    uname(&un);\n\n    if (strncmp(un.version, \"V2\", 2) == 0) {\n\tprintf (\"i386-sequent-ptx2\\n\"); exit (0);\n    }\n    if (strncmp(un.version, \"V1\", 2) == 0) { /* XXX is V1 correct? */\n\tprintf (\"i386-sequent-ptx1\\n\"); exit (0);\n    }\n    printf (\"i386-sequent-ptx\\n\"); exit (0);\n\n#endif\n\n#if defined (vax)\n# if !defined (ultrix)\n#  include <sys/param.h>\n#  if defined (BSD)\n#   if BSD == 43\n      printf (\"vax-dec-bsd4.3\\n\"); exit (0);\n#   else\n#    if BSD == 199006\n      printf (\"vax-dec-bsd4.3reno\\n\"); exit (0);\n#    else\n      printf (\"vax-dec-bsd\\n\"); exit (0);\n#    endif\n#   endif\n#  else\n    printf (\"vax-dec-bsd\\n\"); exit (0);\n#  endif\n# else\n    printf (\"vax-dec-ultrix\\n\"); exit (0);\n# endif\n#endif\n\n#if defined (alliant) && defined (i860)\n  printf (\"i860-alliant-bsd\\n\"); exit (0);\n#endif\n\n  exit (1);\n}\nEOF\n\n$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&\n\t{ echo \"$SYSTEM_NAME\"; exit; }\n\n# Apollos put the system type in the environment.\n\ntest -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }\n\n# Convex versions that predate uname can use getsysinfo(1)\n\nif [ -x /usr/convex/getsysinfo ]\nthen\n    case `getsysinfo -f cpu_type` in\n    c1*)\n\techo c1-convex-bsd\n\texit ;;\n    c2*)\n\tif getsysinfo -f scalar_acc\n\tthen echo c32-convex-bsd\n\telse echo c2-convex-bsd\n\tfi\n\texit ;;\n    c34*)\n\techo c34-convex-bsd\n\texit ;;\n    c38*)\n\techo c38-convex-bsd\n\texit ;;\n    c4*)\n\techo c4-convex-bsd\n\texit ;;\n    esac\nfi\n\ncat >&2 <<EOF\n$0: unable to guess system type\n\nThis script, last modified $timestamp, has failed to recognize\nthe operating system you are using. It is advised that you\ndownload the most up to date version of the config scripts from\n\n  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD\nand\n  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD\n\nIf the version you run ($0) is already up to date, please\nsend the following data and any information you think might be\npertinent to <config-patches@gnu.org> in order to provide the needed\ninformation to handle your system.\n\nconfig.guess timestamp = $timestamp\n\nuname -m = `(uname -m) 2>/dev/null || echo unknown`\nuname -r = `(uname -r) 2>/dev/null || echo unknown`\nuname -s = `(uname -s) 2>/dev/null || echo unknown`\nuname -v = `(uname -v) 2>/dev/null || echo unknown`\n\n/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`\n/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`\n\nhostinfo               = `(hostinfo) 2>/dev/null`\n/bin/universe          = `(/bin/universe) 2>/dev/null`\n/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`\n/bin/arch              = `(/bin/arch) 2>/dev/null`\n/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`\n/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`\n\nUNAME_MACHINE = ${UNAME_MACHINE}\nUNAME_RELEASE = ${UNAME_RELEASE}\nUNAME_SYSTEM  = ${UNAME_SYSTEM}\nUNAME_VERSION = ${UNAME_VERSION}\nEOF\n\nexit 1\n\n# Local variables:\n# eval: (add-hook 'write-file-hooks 'time-stamp)\n# time-stamp-start: \"timestamp='\"\n# time-stamp-format: \"%:y-%02m-%02d\"\n# time-stamp-end: \"'\"\n# End:\n"
  },
  {
    "path": "deps/pjsip/config.sub",
    "content": "#!/bin/sh\n# Configuration validation subroutine script.\n#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,\n#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,\n#   2011, 2012 Free Software Foundation, Inc.\n\ntimestamp='2012-06-17'\n\n# This file is (in principle) common to ALL GNU software.\n# The presence of a machine in this file suggests that SOME GNU software\n# can handle that machine.  It does not imply ALL GNU software can.\n#\n# This file is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, see <http://www.gnu.org/licenses/>.\n#\n# As a special exception to the GNU General Public License, if you\n# distribute this file as part of a program that contains a\n# configuration script generated by Autoconf, you may include it under\n# the same distribution terms that you use for the rest of that program.\n\n\n# Please send patches to <config-patches@gnu.org>.  Submit a context\n# diff and a properly formatted GNU ChangeLog entry.\n#\n# Configuration subroutine to validate and canonicalize a configuration type.\n# Supply the specified configuration type as an argument.\n# If it is invalid, we print an error message on stderr and exit with code 1.\n# Otherwise, we print the canonical config type on stdout and succeed.\n\n# You can get the latest version of this script from:\n# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD\n\n# This file is supposed to be the same for all GNU packages\n# and recognize all the CPU types, system types and aliases\n# that are meaningful with *any* GNU software.\n# Each package is responsible for reporting which valid configurations\n# it does not support.  The user should be able to distinguish\n# a failure to support a valid configuration from a meaningless\n# configuration.\n\n# The goal of this file is to map all the various variations of a given\n# machine specification into a single specification in the form:\n#\tCPU_TYPE-MANUFACTURER-OPERATING_SYSTEM\n# or in some cases, the newer four-part form:\n#\tCPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM\n# It is wrong to echo any other type of specification.\n\nme=`echo \"$0\" | sed -e 's,.*/,,'`\n\nusage=\"\\\nUsage: $0 [OPTION] CPU-MFR-OPSYS\n       $0 [OPTION] ALIAS\n\nCanonicalize a configuration name.\n\nOperation modes:\n  -h, --help         print this help, then exit\n  -t, --time-stamp   print date of last modification, then exit\n  -v, --version      print version number, then exit\n\nReport bugs and patches to <config-patches@gnu.org>.\"\n\nversion=\"\\\nGNU config.sub ($timestamp)\n\nCopyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,\n2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012\nFree Software Foundation, Inc.\n\nThis is free software; see the source for copying conditions.  There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\"\n\nhelp=\"\nTry \\`$me --help' for more information.\"\n\n# Parse command line\nwhile test $# -gt 0 ; do\n  case $1 in\n    --time-stamp | --time* | -t )\n       echo \"$timestamp\" ; exit ;;\n    --version | -v )\n       echo \"$version\" ; exit ;;\n    --help | --h* | -h )\n       echo \"$usage\"; exit ;;\n    -- )     # Stop option processing\n       shift; break ;;\n    - )\t# Use stdin as input.\n       break ;;\n    -* )\n       echo \"$me: invalid option $1$help\"\n       exit 1 ;;\n\n    *local*)\n       # First pass through any local machine types.\n       echo $1\n       exit ;;\n\n    * )\n       break ;;\n  esac\ndone\n\ncase $# in\n 0) echo \"$me: missing argument$help\" >&2\n    exit 1;;\n 1) ;;\n *) echo \"$me: too many arguments$help\" >&2\n    exit 1;;\nesac\n\n# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).\n# Here we must recognize all the valid KERNEL-OS combinations.\nmaybe_os=`echo $1 | sed 's/^\\(.*\\)-\\([^-]*-[^-]*\\)$/\\2/'`\ncase $maybe_os in\n  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \\\n  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \\\n  knetbsd*-gnu* | netbsd*-gnu* | \\\n  kopensolaris*-gnu* | \\\n  storm-chaos* | os2-emx* | rtmk-nova*)\n    os=-$maybe_os\n    basic_machine=`echo $1 | sed 's/^\\(.*\\)-\\([^-]*-[^-]*\\)$/\\1/'`\n    ;;\n  android-linux)\n    os=-linux-android\n    basic_machine=`echo $1 | sed 's/^\\(.*\\)-\\([^-]*-[^-]*\\)$/\\1/'`-unknown\n    ;;\n  *)\n    basic_machine=`echo $1 | sed 's/-[^-]*$//'`\n    if [ $basic_machine != $1 ]\n    then os=`echo $1 | sed 's/.*-/-/'`\n    else os=; fi\n    ;;\nesac\n\n### Let's recognize common machines as not being operating systems so\n### that things like config.sub decstation-3100 work.  We also\n### recognize some manufacturers as not being operating systems, so we\n### can provide default operating systems below.\ncase $os in\n\t-sun*os*)\n\t\t# Prevent following clause from handling this invalid input.\n\t\t;;\n\t-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \\\n\t-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \\\n\t-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \\\n\t-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\\\n\t-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \\\n\t-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \\\n\t-apple | -axis | -knuth | -cray | -microblaze)\n\t\tos=\n\t\tbasic_machine=$1\n\t\t;;\n\t-bluegene*)\n\t\tos=-cnk\n\t\t;;\n\t-sim | -cisco | -oki | -wec | -winbond)\n\t\tos=\n\t\tbasic_machine=$1\n\t\t;;\n\t-scout)\n\t\t;;\n\t-wrs)\n\t\tos=-vxworks\n\t\tbasic_machine=$1\n\t\t;;\n\t-chorusos*)\n\t\tos=-chorusos\n\t\tbasic_machine=$1\n\t\t;;\n\t-chorusrdb)\n\t\tos=-chorusrdb\n\t\tbasic_machine=$1\n\t\t;;\n\t-hiux*)\n\t\tos=-hiuxwe2\n\t\t;;\n\t-sco6)\n\t\tos=-sco5v6\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco5)\n\t\tos=-sco3.2v5\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco4)\n\t\tos=-sco3.2v4\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco3.2.[4-9]*)\n\t\tos=`echo $os | sed -e 's/sco3.2./sco3.2v/'`\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco3.2v[4-9]*)\n\t\t# Don't forget version if it is 3.2v4 or newer.\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco5v6*)\n\t\t# Don't forget version if it is 3.2v4 or newer.\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco*)\n\t\tos=-sco3.2v2\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-udk*)\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-isc)\n\t\tos=-isc2.2\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-clix*)\n\t\tbasic_machine=clipper-intergraph\n\t\t;;\n\t-isc*)\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-lynx*178)\n\t\tos=-lynxos178\n\t\t;;\n\t-lynx*5)\n\t\tos=-lynxos5\n\t\t;;\n\t-lynx*)\n\t\tos=-lynxos\n\t\t;;\n\t-ptx*)\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`\n\t\t;;\n\t-windowsnt*)\n\t\tos=`echo $os | sed -e 's/windowsnt/winnt/'`\n\t\t;;\n\t-psos*)\n\t\tos=-psos\n\t\t;;\n\t-mint | -mint[0-9]*)\n\t\tbasic_machine=m68k-atari\n\t\tos=-mint\n\t\t;;\nesac\n\n# Decode aliases for certain CPU-COMPANY combinations.\ncase $basic_machine in\n\t# Recognize the basic CPU types without company name.\n\t# Some are omitted here because they have special meanings below.\n\t1750a | 580 \\\n\t| a29k \\\n\t| aarch64 | aarch64_be \\\n\t| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \\\n\t| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \\\n\t| am33_2.0 \\\n\t| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \\\n        | be32 | be64 \\\n\t| bfin \\\n\t| c4x | clipper \\\n\t| d10v | d30v | dlx | dsp16xx \\\n\t| epiphany \\\n\t| fido | fr30 | frv \\\n\t| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \\\n\t| hexagon \\\n\t| i370 | i860 | i960 | ia64 \\\n\t| ip2k | iq2000 \\\n\t| le32 | le64 \\\n\t| lm32 \\\n\t| m32c | m32r | m32rle | m68000 | m68k | m88k \\\n\t| maxq | mb | microblaze | mcore | mep | metag \\\n\t| mips | mipsbe | mipseb | mipsel | mipsle \\\n\t| mips16 \\\n\t| mips64 | mips64el \\\n\t| mips64octeon | mips64octeonel \\\n\t| mips64orion | mips64orionel \\\n\t| mips64r5900 | mips64r5900el \\\n\t| mips64vr | mips64vrel \\\n\t| mips64vr4100 | mips64vr4100el \\\n\t| mips64vr4300 | mips64vr4300el \\\n\t| mips64vr5000 | mips64vr5000el \\\n\t| mips64vr5900 | mips64vr5900el \\\n\t| mipsisa32 | mipsisa32el \\\n\t| mipsisa32r2 | mipsisa32r2el \\\n\t| mipsisa64 | mipsisa64el \\\n\t| mipsisa64r2 | mipsisa64r2el \\\n\t| mipsisa64sb1 | mipsisa64sb1el \\\n\t| mipsisa64sr71k | mipsisa64sr71kel \\\n\t| mipstx39 | mipstx39el \\\n\t| mn10200 | mn10300 \\\n\t| moxie \\\n\t| mt \\\n\t| msp430 \\\n\t| nds32 | nds32le | nds32be \\\n\t| nios | nios2 \\\n\t| ns16k | ns32k \\\n\t| open8 \\\n\t| or32 \\\n\t| pdp10 | pdp11 | pj | pjl \\\n\t| powerpc | powerpc64 | powerpc64le | powerpcle \\\n\t| pyramid \\\n\t| rl78 | rx \\\n\t| score \\\n\t| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \\\n\t| sh64 | sh64le \\\n\t| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \\\n\t| sparcv8 | sparcv9 | sparcv9b | sparcv9v \\\n\t| spu \\\n\t| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \\\n\t| ubicom32 \\\n\t| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \\\n\t| we32k \\\n\t| x86 | xc16x | xstormy16 | xtensa \\\n\t| z8k | z80)\n\t\tbasic_machine=$basic_machine-unknown\n\t\t;;\n\tc54x)\n\t\tbasic_machine=tic54x-unknown\n\t\t;;\n\tc55x)\n\t\tbasic_machine=tic55x-unknown\n\t\t;;\n\tc6x)\n\t\tbasic_machine=tic6x-unknown\n\t\t;;\n\tm6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)\n\t\tbasic_machine=$basic_machine-unknown\n\t\tos=-none\n\t\t;;\n\tm88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)\n\t\t;;\n\tms1)\n\t\tbasic_machine=mt-unknown\n\t\t;;\n\n\tstrongarm | thumb | xscale)\n\t\tbasic_machine=arm-unknown\n\t\t;;\n\txgate)\n\t\tbasic_machine=$basic_machine-unknown\n\t\tos=-none\n\t\t;;\n\txscaleeb)\n\t\tbasic_machine=armeb-unknown\n\t\t;;\n\n\txscaleel)\n\t\tbasic_machine=armel-unknown\n\t\t;;\n\n\t# We use `pc' rather than `unknown'\n\t# because (1) that's what they normally are, and\n\t# (2) the word \"unknown\" tends to confuse beginning users.\n\ti*86 | x86_64)\n\t  basic_machine=$basic_machine-pc\n\t  ;;\n\t# Object if more than one company name word.\n\t*-*-*)\n\t\techo Invalid configuration \\`$1\\': machine \\`$basic_machine\\' not recognized 1>&2\n\t\texit 1\n\t\t;;\n\t# Recognize the basic CPU types with company name.\n\t580-* \\\n\t| a29k-* \\\n\t| aarch64-* | aarch64_be-* \\\n\t| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \\\n\t| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \\\n\t| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \\\n\t| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \\\n\t| avr-* | avr32-* \\\n\t| be32-* | be64-* \\\n\t| bfin-* | bs2000-* \\\n\t| c[123]* | c30-* | [cjt]90-* | c4x-* \\\n\t| clipper-* | craynv-* | cydra-* \\\n\t| d10v-* | d30v-* | dlx-* \\\n\t| elxsi-* \\\n\t| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \\\n\t| h8300-* | h8500-* \\\n\t| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \\\n\t| hexagon-* \\\n\t| i*86-* | i860-* | i960-* | ia64-* \\\n\t| ip2k-* | iq2000-* \\\n\t| le32-* | le64-* \\\n\t| lm32-* \\\n\t| m32c-* | m32r-* | m32rle-* \\\n\t| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \\\n\t| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \\\n\t| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \\\n\t| mips16-* \\\n\t| mips64-* | mips64el-* \\\n\t| mips64octeon-* | mips64octeonel-* \\\n\t| mips64orion-* | mips64orionel-* \\\n\t| mips64r5900-* | mips64r5900el-* \\\n\t| mips64vr-* | mips64vrel-* \\\n\t| mips64vr4100-* | mips64vr4100el-* \\\n\t| mips64vr4300-* | mips64vr4300el-* \\\n\t| mips64vr5000-* | mips64vr5000el-* \\\n\t| mips64vr5900-* | mips64vr5900el-* \\\n\t| mipsisa32-* | mipsisa32el-* \\\n\t| mipsisa32r2-* | mipsisa32r2el-* \\\n\t| mipsisa64-* | mipsisa64el-* \\\n\t| mipsisa64r2-* | mipsisa64r2el-* \\\n\t| mipsisa64sb1-* | mipsisa64sb1el-* \\\n\t| mipsisa64sr71k-* | mipsisa64sr71kel-* \\\n\t| mipstx39-* | mipstx39el-* \\\n\t| mmix-* \\\n\t| mt-* \\\n\t| msp430-* \\\n\t| nds32-* | nds32le-* | nds32be-* \\\n\t| nios-* | nios2-* \\\n\t| none-* | np1-* | ns16k-* | ns32k-* \\\n\t| open8-* \\\n\t| orion-* \\\n\t| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \\\n\t| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \\\n\t| pyramid-* \\\n\t| rl78-* | romp-* | rs6000-* | rx-* \\\n\t| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \\\n\t| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \\\n\t| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \\\n\t| sparclite-* \\\n\t| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \\\n\t| tahoe-* \\\n\t| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \\\n\t| tile*-* \\\n\t| tron-* \\\n\t| ubicom32-* \\\n\t| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \\\n\t| vax-* \\\n\t| we32k-* \\\n\t| x86-* | x86_64-* | xc16x-* | xps100-* \\\n\t| xstormy16-* | xtensa*-* \\\n\t| ymp-* \\\n\t| z8k-* | z80-*)\n\t\t;;\n\t# Recognize the basic CPU types without company name, with glob match.\n\txtensa*)\n\t\tbasic_machine=$basic_machine-unknown\n\t\t;;\n\t# Recognize the various machine names and aliases which stand\n\t# for a CPU type and a company and sometimes even an OS.\n\t386bsd)\n\t\tbasic_machine=i386-unknown\n\t\tos=-bsd\n\t\t;;\n\t3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)\n\t\tbasic_machine=m68000-att\n\t\t;;\n\t3b*)\n\t\tbasic_machine=we32k-att\n\t\t;;\n\ta29khif)\n\t\tbasic_machine=a29k-amd\n\t\tos=-udi\n\t\t;;\n\tabacus)\n\t\tbasic_machine=abacus-unknown\n\t\t;;\n\tadobe68k)\n\t\tbasic_machine=m68010-adobe\n\t\tos=-scout\n\t\t;;\n\talliant | fx80)\n\t\tbasic_machine=fx80-alliant\n\t\t;;\n\taltos | altos3068)\n\t\tbasic_machine=m68k-altos\n\t\t;;\n\tam29k)\n\t\tbasic_machine=a29k-none\n\t\tos=-bsd\n\t\t;;\n\tamd64)\n\t\tbasic_machine=x86_64-pc\n\t\t;;\n\tamd64-*)\n\t\tbasic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tamdahl)\n\t\tbasic_machine=580-amdahl\n\t\tos=-sysv\n\t\t;;\n\tamiga | amiga-*)\n\t\tbasic_machine=m68k-unknown\n\t\t;;\n\tamigaos | amigados)\n\t\tbasic_machine=m68k-unknown\n\t\tos=-amigaos\n\t\t;;\n\tamigaunix | amix)\n\t\tbasic_machine=m68k-unknown\n\t\tos=-sysv4\n\t\t;;\n\tapollo68)\n\t\tbasic_machine=m68k-apollo\n\t\tos=-sysv\n\t\t;;\n\tapollo68bsd)\n\t\tbasic_machine=m68k-apollo\n\t\tos=-bsd\n\t\t;;\n\taros)\n\t\tbasic_machine=i386-pc\n\t\tos=-aros\n\t\t;;\n\taux)\n\t\tbasic_machine=m68k-apple\n\t\tos=-aux\n\t\t;;\n\tbalance)\n\t\tbasic_machine=ns32k-sequent\n\t\tos=-dynix\n\t\t;;\n\tblackfin)\n\t\tbasic_machine=bfin-unknown\n\t\tos=-linux\n\t\t;;\n\tblackfin-*)\n\t\tbasic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\tos=-linux\n\t\t;;\n\tbluegene*)\n\t\tbasic_machine=powerpc-ibm\n\t\tos=-cnk\n\t\t;;\n\tc54x-*)\n\t\tbasic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tc55x-*)\n\t\tbasic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tc6x-*)\n\t\tbasic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tc90)\n\t\tbasic_machine=c90-cray\n\t\tos=-unicos\n\t\t;;\n\tcegcc)\n\t\tbasic_machine=arm-unknown\n\t\tos=-cegcc\n\t\t;;\n\tconvex-c1)\n\t\tbasic_machine=c1-convex\n\t\tos=-bsd\n\t\t;;\n\tconvex-c2)\n\t\tbasic_machine=c2-convex\n\t\tos=-bsd\n\t\t;;\n\tconvex-c32)\n\t\tbasic_machine=c32-convex\n\t\tos=-bsd\n\t\t;;\n\tconvex-c34)\n\t\tbasic_machine=c34-convex\n\t\tos=-bsd\n\t\t;;\n\tconvex-c38)\n\t\tbasic_machine=c38-convex\n\t\tos=-bsd\n\t\t;;\n\tcray | j90)\n\t\tbasic_machine=j90-cray\n\t\tos=-unicos\n\t\t;;\n\tcraynv)\n\t\tbasic_machine=craynv-cray\n\t\tos=-unicosmp\n\t\t;;\n\tcr16 | cr16-*)\n\t\tbasic_machine=cr16-unknown\n\t\tos=-elf\n\t\t;;\n\tcrds | unos)\n\t\tbasic_machine=m68k-crds\n\t\t;;\n\tcrisv32 | crisv32-* | etraxfs*)\n\t\tbasic_machine=crisv32-axis\n\t\t;;\n\tcris | cris-* | etrax*)\n\t\tbasic_machine=cris-axis\n\t\t;;\n\tcrx)\n\t\tbasic_machine=crx-unknown\n\t\tos=-elf\n\t\t;;\n\tda30 | da30-*)\n\t\tbasic_machine=m68k-da30\n\t\t;;\n\tdecstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)\n\t\tbasic_machine=mips-dec\n\t\t;;\n\tdecsystem10* | dec10*)\n\t\tbasic_machine=pdp10-dec\n\t\tos=-tops10\n\t\t;;\n\tdecsystem20* | dec20*)\n\t\tbasic_machine=pdp10-dec\n\t\tos=-tops20\n\t\t;;\n\tdelta | 3300 | motorola-3300 | motorola-delta \\\n\t      | 3300-motorola | delta-motorola)\n\t\tbasic_machine=m68k-motorola\n\t\t;;\n\tdelta88)\n\t\tbasic_machine=m88k-motorola\n\t\tos=-sysv3\n\t\t;;\n\tdicos)\n\t\tbasic_machine=i686-pc\n\t\tos=-dicos\n\t\t;;\n\tdjgpp)\n\t\tbasic_machine=i586-pc\n\t\tos=-msdosdjgpp\n\t\t;;\n\tdpx20 | dpx20-*)\n\t\tbasic_machine=rs6000-bull\n\t\tos=-bosx\n\t\t;;\n\tdpx2* | dpx2*-bull)\n\t\tbasic_machine=m68k-bull\n\t\tos=-sysv3\n\t\t;;\n\tebmon29k)\n\t\tbasic_machine=a29k-amd\n\t\tos=-ebmon\n\t\t;;\n\telxsi)\n\t\tbasic_machine=elxsi-elxsi\n\t\tos=-bsd\n\t\t;;\n\tencore | umax | mmax)\n\t\tbasic_machine=ns32k-encore\n\t\t;;\n\tes1800 | OSE68k | ose68k | ose | OSE)\n\t\tbasic_machine=m68k-ericsson\n\t\tos=-ose\n\t\t;;\n\tfx2800)\n\t\tbasic_machine=i860-alliant\n\t\t;;\n\tgenix)\n\t\tbasic_machine=ns32k-ns\n\t\t;;\n\tgmicro)\n\t\tbasic_machine=tron-gmicro\n\t\tos=-sysv\n\t\t;;\n\tgo32)\n\t\tbasic_machine=i386-pc\n\t\tos=-go32\n\t\t;;\n\th3050r* | hiux*)\n\t\tbasic_machine=hppa1.1-hitachi\n\t\tos=-hiuxwe2\n\t\t;;\n\th8300hms)\n\t\tbasic_machine=h8300-hitachi\n\t\tos=-hms\n\t\t;;\n\th8300xray)\n\t\tbasic_machine=h8300-hitachi\n\t\tos=-xray\n\t\t;;\n\th8500hms)\n\t\tbasic_machine=h8500-hitachi\n\t\tos=-hms\n\t\t;;\n\tharris)\n\t\tbasic_machine=m88k-harris\n\t\tos=-sysv3\n\t\t;;\n\thp300-*)\n\t\tbasic_machine=m68k-hp\n\t\t;;\n\thp300bsd)\n\t\tbasic_machine=m68k-hp\n\t\tos=-bsd\n\t\t;;\n\thp300hpux)\n\t\tbasic_machine=m68k-hp\n\t\tos=-hpux\n\t\t;;\n\thp3k9[0-9][0-9] | hp9[0-9][0-9])\n\t\tbasic_machine=hppa1.0-hp\n\t\t;;\n\thp9k2[0-9][0-9] | hp9k31[0-9])\n\t\tbasic_machine=m68000-hp\n\t\t;;\n\thp9k3[2-9][0-9])\n\t\tbasic_machine=m68k-hp\n\t\t;;\n\thp9k6[0-9][0-9] | hp6[0-9][0-9])\n\t\tbasic_machine=hppa1.0-hp\n\t\t;;\n\thp9k7[0-79][0-9] | hp7[0-79][0-9])\n\t\tbasic_machine=hppa1.1-hp\n\t\t;;\n\thp9k78[0-9] | hp78[0-9])\n\t\t# FIXME: really hppa2.0-hp\n\t\tbasic_machine=hppa1.1-hp\n\t\t;;\n\thp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)\n\t\t# FIXME: really hppa2.0-hp\n\t\tbasic_machine=hppa1.1-hp\n\t\t;;\n\thp9k8[0-9][13679] | hp8[0-9][13679])\n\t\tbasic_machine=hppa1.1-hp\n\t\t;;\n\thp9k8[0-9][0-9] | hp8[0-9][0-9])\n\t\tbasic_machine=hppa1.0-hp\n\t\t;;\n\thppa-next)\n\t\tos=-nextstep3\n\t\t;;\n\thppaosf)\n\t\tbasic_machine=hppa1.1-hp\n\t\tos=-osf\n\t\t;;\n\thppro)\n\t\tbasic_machine=hppa1.1-hp\n\t\tos=-proelf\n\t\t;;\n\ti370-ibm* | ibm*)\n\t\tbasic_machine=i370-ibm\n\t\t;;\n\ti*86v32)\n\t\tbasic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`\n\t\tos=-sysv32\n\t\t;;\n\ti*86v4*)\n\t\tbasic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`\n\t\tos=-sysv4\n\t\t;;\n\ti*86v)\n\t\tbasic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`\n\t\tos=-sysv\n\t\t;;\n\ti*86sol2)\n\t\tbasic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`\n\t\tos=-solaris2\n\t\t;;\n\ti386mach)\n\t\tbasic_machine=i386-mach\n\t\tos=-mach\n\t\t;;\n\ti386-vsta | vsta)\n\t\tbasic_machine=i386-unknown\n\t\tos=-vsta\n\t\t;;\n\tiris | iris4d)\n\t\tbasic_machine=mips-sgi\n\t\tcase $os in\n\t\t    -irix*)\n\t\t\t;;\n\t\t    *)\n\t\t\tos=-irix4\n\t\t\t;;\n\t\tesac\n\t\t;;\n\tisi68 | isi)\n\t\tbasic_machine=m68k-isi\n\t\tos=-sysv\n\t\t;;\n\tm68knommu)\n\t\tbasic_machine=m68k-unknown\n\t\tos=-linux\n\t\t;;\n\tm68knommu-*)\n\t\tbasic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\tos=-linux\n\t\t;;\n\tm88k-omron*)\n\t\tbasic_machine=m88k-omron\n\t\t;;\n\tmagnum | m3230)\n\t\tbasic_machine=mips-mips\n\t\tos=-sysv\n\t\t;;\n\tmerlin)\n\t\tbasic_machine=ns32k-utek\n\t\tos=-sysv\n\t\t;;\n\tmicroblaze)\n\t\tbasic_machine=microblaze-xilinx\n\t\t;;\n\tmingw32)\n\t\tbasic_machine=i386-pc\n\t\tos=-mingw32\n\t\t;;\n\tmingw32ce)\n\t\tbasic_machine=arm-unknown\n\t\tos=-mingw32ce\n\t\t;;\n\tminiframe)\n\t\tbasic_machine=m68000-convergent\n\t\t;;\n\t*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)\n\t\tbasic_machine=m68k-atari\n\t\tos=-mint\n\t\t;;\n\tmips3*-*)\n\t\tbasic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`\n\t\t;;\n\tmips3*)\n\t\tbasic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown\n\t\t;;\n\tmonitor)\n\t\tbasic_machine=m68k-rom68k\n\t\tos=-coff\n\t\t;;\n\tmorphos)\n\t\tbasic_machine=powerpc-unknown\n\t\tos=-morphos\n\t\t;;\n\tmsdos)\n\t\tbasic_machine=i386-pc\n\t\tos=-msdos\n\t\t;;\n\tms1-*)\n\t\tbasic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`\n\t\t;;\n\tmsys)\n\t\tbasic_machine=i386-pc\n\t\tos=-msys\n\t\t;;\n\tmvs)\n\t\tbasic_machine=i370-ibm\n\t\tos=-mvs\n\t\t;;\n\tnacl)\n\t\tbasic_machine=le32-unknown\n\t\tos=-nacl\n\t\t;;\n\tncr3000)\n\t\tbasic_machine=i486-ncr\n\t\tos=-sysv4\n\t\t;;\n\tnetbsd386)\n\t\tbasic_machine=i386-unknown\n\t\tos=-netbsd\n\t\t;;\n\tnetwinder)\n\t\tbasic_machine=armv4l-rebel\n\t\tos=-linux\n\t\t;;\n\tnews | news700 | news800 | news900)\n\t\tbasic_machine=m68k-sony\n\t\tos=-newsos\n\t\t;;\n\tnews1000)\n\t\tbasic_machine=m68030-sony\n\t\tos=-newsos\n\t\t;;\n\tnews-3600 | risc-news)\n\t\tbasic_machine=mips-sony\n\t\tos=-newsos\n\t\t;;\n\tnecv70)\n\t\tbasic_machine=v70-nec\n\t\tos=-sysv\n\t\t;;\n\tnext | m*-next )\n\t\tbasic_machine=m68k-next\n\t\tcase $os in\n\t\t    -nextstep* )\n\t\t\t;;\n\t\t    -ns2*)\n\t\t      os=-nextstep2\n\t\t\t;;\n\t\t    *)\n\t\t      os=-nextstep3\n\t\t\t;;\n\t\tesac\n\t\t;;\n\tnh3000)\n\t\tbasic_machine=m68k-harris\n\t\tos=-cxux\n\t\t;;\n\tnh[45]000)\n\t\tbasic_machine=m88k-harris\n\t\tos=-cxux\n\t\t;;\n\tnindy960)\n\t\tbasic_machine=i960-intel\n\t\tos=-nindy\n\t\t;;\n\tmon960)\n\t\tbasic_machine=i960-intel\n\t\tos=-mon960\n\t\t;;\n\tnonstopux)\n\t\tbasic_machine=mips-compaq\n\t\tos=-nonstopux\n\t\t;;\n\tnp1)\n\t\tbasic_machine=np1-gould\n\t\t;;\n\tneo-tandem)\n\t\tbasic_machine=neo-tandem\n\t\t;;\n\tnse-tandem)\n\t\tbasic_machine=nse-tandem\n\t\t;;\n\tnsr-tandem)\n\t\tbasic_machine=nsr-tandem\n\t\t;;\n\top50n-* | op60c-*)\n\t\tbasic_machine=hppa1.1-oki\n\t\tos=-proelf\n\t\t;;\n\topenrisc | openrisc-*)\n\t\tbasic_machine=or32-unknown\n\t\t;;\n\tos400)\n\t\tbasic_machine=powerpc-ibm\n\t\tos=-os400\n\t\t;;\n\tOSE68000 | ose68000)\n\t\tbasic_machine=m68000-ericsson\n\t\tos=-ose\n\t\t;;\n\tos68k)\n\t\tbasic_machine=m68k-none\n\t\tos=-os68k\n\t\t;;\n\tpa-hitachi)\n\t\tbasic_machine=hppa1.1-hitachi\n\t\tos=-hiuxwe2\n\t\t;;\n\tparagon)\n\t\tbasic_machine=i860-intel\n\t\tos=-osf\n\t\t;;\n\tparisc)\n\t\tbasic_machine=hppa-unknown\n\t\tos=-linux\n\t\t;;\n\tparisc-*)\n\t\tbasic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\tos=-linux\n\t\t;;\n\tpbd)\n\t\tbasic_machine=sparc-tti\n\t\t;;\n\tpbb)\n\t\tbasic_machine=m68k-tti\n\t\t;;\n\tpc532 | pc532-*)\n\t\tbasic_machine=ns32k-pc532\n\t\t;;\n\tpc98)\n\t\tbasic_machine=i386-pc\n\t\t;;\n\tpc98-*)\n\t\tbasic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpentium | p5 | k5 | k6 | nexgen | viac3)\n\t\tbasic_machine=i586-pc\n\t\t;;\n\tpentiumpro | p6 | 6x86 | athlon | athlon_*)\n\t\tbasic_machine=i686-pc\n\t\t;;\n\tpentiumii | pentium2 | pentiumiii | pentium3)\n\t\tbasic_machine=i686-pc\n\t\t;;\n\tpentium4)\n\t\tbasic_machine=i786-pc\n\t\t;;\n\tpentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)\n\t\tbasic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpentiumpro-* | p6-* | 6x86-* | athlon-*)\n\t\tbasic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)\n\t\tbasic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpentium4-*)\n\t\tbasic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpn)\n\t\tbasic_machine=pn-gould\n\t\t;;\n\tpower)\tbasic_machine=power-ibm\n\t\t;;\n\tppc | ppcbe)\tbasic_machine=powerpc-unknown\n\t\t;;\n\tppc-* | ppcbe-*)\n\t\tbasic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tppcle | powerpclittle | ppc-le | powerpc-little)\n\t\tbasic_machine=powerpcle-unknown\n\t\t;;\n\tppcle-* | powerpclittle-*)\n\t\tbasic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tppc64)\tbasic_machine=powerpc64-unknown\n\t\t;;\n\tppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tppc64le | powerpc64little | ppc64-le | powerpc64-little)\n\t\tbasic_machine=powerpc64le-unknown\n\t\t;;\n\tppc64le-* | powerpc64little-*)\n\t\tbasic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tps2)\n\t\tbasic_machine=i386-ibm\n\t\t;;\n\tpw32)\n\t\tbasic_machine=i586-unknown\n\t\tos=-pw32\n\t\t;;\n\trdos)\n\t\tbasic_machine=i386-pc\n\t\tos=-rdos\n\t\t;;\n\trom68k)\n\t\tbasic_machine=m68k-rom68k\n\t\tos=-coff\n\t\t;;\n\trm[46]00)\n\t\tbasic_machine=mips-siemens\n\t\t;;\n\trtpc | rtpc-*)\n\t\tbasic_machine=romp-ibm\n\t\t;;\n\ts390 | s390-*)\n\t\tbasic_machine=s390-ibm\n\t\t;;\n\ts390x | s390x-*)\n\t\tbasic_machine=s390x-ibm\n\t\t;;\n\tsa29200)\n\t\tbasic_machine=a29k-amd\n\t\tos=-udi\n\t\t;;\n\tsb1)\n\t\tbasic_machine=mipsisa64sb1-unknown\n\t\t;;\n\tsb1el)\n\t\tbasic_machine=mipsisa64sb1el-unknown\n\t\t;;\n\tsde)\n\t\tbasic_machine=mipsisa32-sde\n\t\tos=-elf\n\t\t;;\n\tsei)\n\t\tbasic_machine=mips-sei\n\t\tos=-seiux\n\t\t;;\n\tsequent)\n\t\tbasic_machine=i386-sequent\n\t\t;;\n\tsh)\n\t\tbasic_machine=sh-hitachi\n\t\tos=-hms\n\t\t;;\n\tsh5el)\n\t\tbasic_machine=sh5le-unknown\n\t\t;;\n\tsh64)\n\t\tbasic_machine=sh64-unknown\n\t\t;;\n\tsparclite-wrs | simso-wrs)\n\t\tbasic_machine=sparclite-wrs\n\t\tos=-vxworks\n\t\t;;\n\tsps7)\n\t\tbasic_machine=m68k-bull\n\t\tos=-sysv2\n\t\t;;\n\tspur)\n\t\tbasic_machine=spur-unknown\n\t\t;;\n\tst2000)\n\t\tbasic_machine=m68k-tandem\n\t\t;;\n\tstratus)\n\t\tbasic_machine=i860-stratus\n\t\tos=-sysv4\n\t\t;;\n\tstrongarm-* | thumb-*)\n\t\tbasic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tsun2)\n\t\tbasic_machine=m68000-sun\n\t\t;;\n\tsun2os3)\n\t\tbasic_machine=m68000-sun\n\t\tos=-sunos3\n\t\t;;\n\tsun2os4)\n\t\tbasic_machine=m68000-sun\n\t\tos=-sunos4\n\t\t;;\n\tsun3os3)\n\t\tbasic_machine=m68k-sun\n\t\tos=-sunos3\n\t\t;;\n\tsun3os4)\n\t\tbasic_machine=m68k-sun\n\t\tos=-sunos4\n\t\t;;\n\tsun4os3)\n\t\tbasic_machine=sparc-sun\n\t\tos=-sunos3\n\t\t;;\n\tsun4os4)\n\t\tbasic_machine=sparc-sun\n\t\tos=-sunos4\n\t\t;;\n\tsun4sol2)\n\t\tbasic_machine=sparc-sun\n\t\tos=-solaris2\n\t\t;;\n\tsun3 | sun3-*)\n\t\tbasic_machine=m68k-sun\n\t\t;;\n\tsun4)\n\t\tbasic_machine=sparc-sun\n\t\t;;\n\tsun386 | sun386i | roadrunner)\n\t\tbasic_machine=i386-sun\n\t\t;;\n\tsv1)\n\t\tbasic_machine=sv1-cray\n\t\tos=-unicos\n\t\t;;\n\tsymmetry)\n\t\tbasic_machine=i386-sequent\n\t\tos=-dynix\n\t\t;;\n\tt3e)\n\t\tbasic_machine=alphaev5-cray\n\t\tos=-unicos\n\t\t;;\n\tt90)\n\t\tbasic_machine=t90-cray\n\t\tos=-unicos\n\t\t;;\n\ttile*)\n\t\tbasic_machine=$basic_machine-unknown\n\t\tos=-linux-gnu\n\t\t;;\n\ttx39)\n\t\tbasic_machine=mipstx39-unknown\n\t\t;;\n\ttx39el)\n\t\tbasic_machine=mipstx39el-unknown\n\t\t;;\n\ttoad1)\n\t\tbasic_machine=pdp10-xkl\n\t\tos=-tops20\n\t\t;;\n\ttower | tower-32)\n\t\tbasic_machine=m68k-ncr\n\t\t;;\n\ttpf)\n\t\tbasic_machine=s390x-ibm\n\t\tos=-tpf\n\t\t;;\n\tudi29k)\n\t\tbasic_machine=a29k-amd\n\t\tos=-udi\n\t\t;;\n\tultra3)\n\t\tbasic_machine=a29k-nyu\n\t\tos=-sym1\n\t\t;;\n\tv810 | necv810)\n\t\tbasic_machine=v810-nec\n\t\tos=-none\n\t\t;;\n\tvaxv)\n\t\tbasic_machine=vax-dec\n\t\tos=-sysv\n\t\t;;\n\tvms)\n\t\tbasic_machine=vax-dec\n\t\tos=-vms\n\t\t;;\n\tvpp*|vx|vx-*)\n\t\tbasic_machine=f301-fujitsu\n\t\t;;\n\tvxworks960)\n\t\tbasic_machine=i960-wrs\n\t\tos=-vxworks\n\t\t;;\n\tvxworks68)\n\t\tbasic_machine=m68k-wrs\n\t\tos=-vxworks\n\t\t;;\n\tvxworks29k)\n\t\tbasic_machine=a29k-wrs\n\t\tos=-vxworks\n\t\t;;\n\tw65*)\n\t\tbasic_machine=w65-wdc\n\t\tos=-none\n\t\t;;\n\tw89k-*)\n\t\tbasic_machine=hppa1.1-winbond\n\t\tos=-proelf\n\t\t;;\n\txbox)\n\t\tbasic_machine=i686-pc\n\t\tos=-mingw32\n\t\t;;\n\txps | xps100)\n\t\tbasic_machine=xps100-honeywell\n\t\t;;\n\txscale-* | xscalee[bl]-*)\n\t\tbasic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`\n\t\t;;\n\tymp)\n\t\tbasic_machine=ymp-cray\n\t\tos=-unicos\n\t\t;;\n\tz8k-*-coff)\n\t\tbasic_machine=z8k-unknown\n\t\tos=-sim\n\t\t;;\n\tz80-*-coff)\n\t\tbasic_machine=z80-unknown\n\t\tos=-sim\n\t\t;;\n\tnone)\n\t\tbasic_machine=none-none\n\t\tos=-none\n\t\t;;\n\n# Here we handle the default manufacturer of certain CPU types.  It is in\n# some cases the only manufacturer, in others, it is the most popular.\n\tw89k)\n\t\tbasic_machine=hppa1.1-winbond\n\t\t;;\n\top50n)\n\t\tbasic_machine=hppa1.1-oki\n\t\t;;\n\top60c)\n\t\tbasic_machine=hppa1.1-oki\n\t\t;;\n\tromp)\n\t\tbasic_machine=romp-ibm\n\t\t;;\n\tmmix)\n\t\tbasic_machine=mmix-knuth\n\t\t;;\n\trs6000)\n\t\tbasic_machine=rs6000-ibm\n\t\t;;\n\tvax)\n\t\tbasic_machine=vax-dec\n\t\t;;\n\tpdp10)\n\t\t# there are many clones, so DEC is not a safe bet\n\t\tbasic_machine=pdp10-unknown\n\t\t;;\n\tpdp11)\n\t\tbasic_machine=pdp11-dec\n\t\t;;\n\twe32k)\n\t\tbasic_machine=we32k-att\n\t\t;;\n\tsh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)\n\t\tbasic_machine=sh-unknown\n\t\t;;\n\tsparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)\n\t\tbasic_machine=sparc-sun\n\t\t;;\n\tcydra)\n\t\tbasic_machine=cydra-cydrome\n\t\t;;\n\torion)\n\t\tbasic_machine=orion-highlevel\n\t\t;;\n\torion105)\n\t\tbasic_machine=clipper-highlevel\n\t\t;;\n\tmac | mpw | mac-mpw)\n\t\tbasic_machine=m68k-apple\n\t\t;;\n\tpmac | pmac-mpw)\n\t\tbasic_machine=powerpc-apple\n\t\t;;\n\t*-unknown)\n\t\t# Make sure to match an already-canonicalized machine name.\n\t\t;;\n\t*)\n\t\techo Invalid configuration \\`$1\\': machine \\`$basic_machine\\' not recognized 1>&2\n\t\texit 1\n\t\t;;\nesac\n\n# Here we canonicalize certain aliases for manufacturers.\ncase $basic_machine in\n\t*-digital*)\n\t\tbasic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`\n\t\t;;\n\t*-commodore*)\n\t\tbasic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`\n\t\t;;\n\t*)\n\t\t;;\nesac\n\n# Decode manufacturer-specific aliases for certain operating systems.\n\nif [ x\"$os\" != x\"\" ]\nthen\ncase $os in\n\t# First match some system type aliases\n\t# that might get confused with valid system types.\n\t# -solaris* is a basic system type, with this one exception.\n\t-auroraux)\n\t\tos=-auroraux\n\t\t;;\n\t-solaris1 | -solaris1.*)\n\t\tos=`echo $os | sed -e 's|solaris1|sunos4|'`\n\t\t;;\n\t-solaris)\n\t\tos=-solaris2\n\t\t;;\n\t-svr4*)\n\t\tos=-sysv4\n\t\t;;\n\t-unixware*)\n\t\tos=-sysv4.2uw\n\t\t;;\n\t-gnu/linux*)\n\t\tos=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`\n\t\t;;\n\t# First accept the basic system types.\n\t# The portable systems comes first.\n\t# Each alternative MUST END IN A *, to match a version number.\n\t# -sysv* is not here because it comes later, after sysvr4.\n\t-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \\\n\t      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\\\n\t      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \\\n\t      | -sym* | -kopensolaris* \\\n\t      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \\\n\t      | -aos* | -aros* \\\n\t      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \\\n\t      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \\\n\t      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \\\n\t      | -bitrig* | -openbsd* | -solidbsd* \\\n\t      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \\\n\t      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \\\n\t      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \\\n\t      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \\\n\t      | -chorusos* | -chorusrdb* | -cegcc* \\\n\t      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \\\n\t      | -mingw32* | -linux-gnu* | -linux-android* \\\n\t      | -linux-newlib* | -linux-uclibc* \\\n\t      | -uxpv* | -beos* | -mpeix* | -udk* \\\n\t      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \\\n\t      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \\\n\t      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \\\n\t      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \\\n\t      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \\\n\t      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \\\n\t      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)\n\t# Remember, each alternative MUST END IN *, to match a version number.\n\t\t;;\n\t-qnx*)\n\t\tcase $basic_machine in\n\t\t    x86-* | i*86-*)\n\t\t\t;;\n\t\t    *)\n\t\t\tos=-nto$os\n\t\t\t;;\n\t\tesac\n\t\t;;\n\t-nto-qnx*)\n\t\t;;\n\t-nto*)\n\t\tos=`echo $os | sed -e 's|nto|nto-qnx|'`\n\t\t;;\n\t-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \\\n\t      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \\\n\t      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)\n\t\t;;\n\t-mac*)\n\t\tos=`echo $os | sed -e 's|mac|macos|'`\n\t\t;;\n\t-linux-dietlibc)\n\t\tos=-linux-dietlibc\n\t\t;;\n\t-linux*)\n\t\tos=`echo $os | sed -e 's|linux|linux-gnu|'`\n\t\t;;\n\t-sunos5*)\n\t\tos=`echo $os | sed -e 's|sunos5|solaris2|'`\n\t\t;;\n\t-sunos6*)\n\t\tos=`echo $os | sed -e 's|sunos6|solaris3|'`\n\t\t;;\n\t-opened*)\n\t\tos=-openedition\n\t\t;;\n\t-os400*)\n\t\tos=-os400\n\t\t;;\n\t-wince*)\n\t\tos=-wince\n\t\t;;\n\t-osfrose*)\n\t\tos=-osfrose\n\t\t;;\n\t-osf*)\n\t\tos=-osf\n\t\t;;\n\t-utek*)\n\t\tos=-bsd\n\t\t;;\n\t-dynix*)\n\t\tos=-bsd\n\t\t;;\n\t-acis*)\n\t\tos=-aos\n\t\t;;\n\t-atheos*)\n\t\tos=-atheos\n\t\t;;\n\t-syllable*)\n\t\tos=-syllable\n\t\t;;\n\t-386bsd)\n\t\tos=-bsd\n\t\t;;\n\t-ctix* | -uts*)\n\t\tos=-sysv\n\t\t;;\n\t-nova*)\n\t\tos=-rtmk-nova\n\t\t;;\n\t-ns2 )\n\t\tos=-nextstep2\n\t\t;;\n\t-nsk*)\n\t\tos=-nsk\n\t\t;;\n\t# Preserve the version number of sinix5.\n\t-sinix5.*)\n\t\tos=`echo $os | sed -e 's|sinix|sysv|'`\n\t\t;;\n\t-sinix*)\n\t\tos=-sysv4\n\t\t;;\n\t-tpf*)\n\t\tos=-tpf\n\t\t;;\n\t-triton*)\n\t\tos=-sysv3\n\t\t;;\n\t-oss*)\n\t\tos=-sysv3\n\t\t;;\n\t-svr4)\n\t\tos=-sysv4\n\t\t;;\n\t-svr3)\n\t\tos=-sysv3\n\t\t;;\n\t-sysvr4)\n\t\tos=-sysv4\n\t\t;;\n\t# This must come after -sysvr4.\n\t-sysv*)\n\t\t;;\n\t-ose*)\n\t\tos=-ose\n\t\t;;\n\t-es1800*)\n\t\tos=-ose\n\t\t;;\n\t-xenix)\n\t\tos=-xenix\n\t\t;;\n\t-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)\n\t\tos=-mint\n\t\t;;\n\t-aros*)\n\t\tos=-aros\n\t\t;;\n\t-kaos*)\n\t\tos=-kaos\n\t\t;;\n\t-zvmoe)\n\t\tos=-zvmoe\n\t\t;;\n\t-dicos*)\n\t\tos=-dicos\n\t\t;;\n\t-nacl*)\n\t\t;;\n\t-none)\n\t\t;;\n\t*)\n\t\t# Get rid of the `-' at the beginning of $os.\n\t\tos=`echo $os | sed 's/[^-]*-//'`\n\t\techo Invalid configuration \\`$1\\': system \\`$os\\' not recognized 1>&2\n\t\texit 1\n\t\t;;\nesac\nelse\n\n# Here we handle the default operating systems that come with various machines.\n# The value should be what the vendor currently ships out the door with their\n# machine or put another way, the most popular os provided with the machine.\n\n# Note that if you're going to try to match \"-MANUFACTURER\" here (say,\n# \"-sun\"), then you have to tell the case statement up towards the top\n# that MANUFACTURER isn't an operating system.  Otherwise, code above\n# will signal an error saying that MANUFACTURER isn't an operating\n# system, and we'll never get to this point.\n\ncase $basic_machine in\n\tscore-*)\n\t\tos=-elf\n\t\t;;\n\tspu-*)\n\t\tos=-elf\n\t\t;;\n\t*-acorn)\n\t\tos=-riscix1.2\n\t\t;;\n\tarm*-rebel)\n\t\tos=-linux\n\t\t;;\n\tarm*-semi)\n\t\tos=-aout\n\t\t;;\n\tc4x-* | tic4x-*)\n\t\tos=-coff\n\t\t;;\n\thexagon-*)\n\t\tos=-elf\n\t\t;;\n\ttic54x-*)\n\t\tos=-coff\n\t\t;;\n\ttic55x-*)\n\t\tos=-coff\n\t\t;;\n\ttic6x-*)\n\t\tos=-coff\n\t\t;;\n\t# This must come before the *-dec entry.\n\tpdp10-*)\n\t\tos=-tops20\n\t\t;;\n\tpdp11-*)\n\t\tos=-none\n\t\t;;\n\t*-dec | vax-*)\n\t\tos=-ultrix4.2\n\t\t;;\n\tm68*-apollo)\n\t\tos=-domain\n\t\t;;\n\ti386-sun)\n\t\tos=-sunos4.0.2\n\t\t;;\n\tm68000-sun)\n\t\tos=-sunos3\n\t\t;;\n\tm68*-cisco)\n\t\tos=-aout\n\t\t;;\n\tmep-*)\n\t\tos=-elf\n\t\t;;\n\tmips*-cisco)\n\t\tos=-elf\n\t\t;;\n\tmips*-*)\n\t\tos=-elf\n\t\t;;\n\tor32-*)\n\t\tos=-coff\n\t\t;;\n\t*-tti)\t# must be before sparc entry or we get the wrong os.\n\t\tos=-sysv3\n\t\t;;\n\tsparc-* | *-sun)\n\t\tos=-sunos4.1.1\n\t\t;;\n\t*-be)\n\t\tos=-beos\n\t\t;;\n\t*-haiku)\n\t\tos=-haiku\n\t\t;;\n\t*-ibm)\n\t\tos=-aix\n\t\t;;\n\t*-knuth)\n\t\tos=-mmixware\n\t\t;;\n\t*-wec)\n\t\tos=-proelf\n\t\t;;\n\t*-winbond)\n\t\tos=-proelf\n\t\t;;\n\t*-oki)\n\t\tos=-proelf\n\t\t;;\n\t*-hp)\n\t\tos=-hpux\n\t\t;;\n\t*-hitachi)\n\t\tos=-hiux\n\t\t;;\n\ti860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)\n\t\tos=-sysv\n\t\t;;\n\t*-cbm)\n\t\tos=-amigaos\n\t\t;;\n\t*-dg)\n\t\tos=-dgux\n\t\t;;\n\t*-dolphin)\n\t\tos=-sysv3\n\t\t;;\n\tm68k-ccur)\n\t\tos=-rtu\n\t\t;;\n\tm88k-omron*)\n\t\tos=-luna\n\t\t;;\n\t*-next )\n\t\tos=-nextstep\n\t\t;;\n\t*-sequent)\n\t\tos=-ptx\n\t\t;;\n\t*-crds)\n\t\tos=-unos\n\t\t;;\n\t*-ns)\n\t\tos=-genix\n\t\t;;\n\ti370-*)\n\t\tos=-mvs\n\t\t;;\n\t*-next)\n\t\tos=-nextstep3\n\t\t;;\n\t*-gould)\n\t\tos=-sysv\n\t\t;;\n\t*-highlevel)\n\t\tos=-bsd\n\t\t;;\n\t*-encore)\n\t\tos=-bsd\n\t\t;;\n\t*-sgi)\n\t\tos=-irix\n\t\t;;\n\t*-siemens)\n\t\tos=-sysv4\n\t\t;;\n\t*-masscomp)\n\t\tos=-rtu\n\t\t;;\n\tf30[01]-fujitsu | f700-fujitsu)\n\t\tos=-uxpv\n\t\t;;\n\t*-rom68k)\n\t\tos=-coff\n\t\t;;\n\t*-*bug)\n\t\tos=-coff\n\t\t;;\n\t*-apple)\n\t\tos=-macos\n\t\t;;\n\t*-atari*)\n\t\tos=-mint\n\t\t;;\n\t*)\n\t\tos=-none\n\t\t;;\nesac\nfi\n\n# Here we handle the case where we know the os, and the CPU type, but not the\n# manufacturer.  We pick the logical manufacturer.\nvendor=unknown\ncase $basic_machine in\n\t*-unknown)\n\t\tcase $os in\n\t\t\t-riscix*)\n\t\t\t\tvendor=acorn\n\t\t\t\t;;\n\t\t\t-sunos*)\n\t\t\t\tvendor=sun\n\t\t\t\t;;\n\t\t\t-cnk*|-aix*)\n\t\t\t\tvendor=ibm\n\t\t\t\t;;\n\t\t\t-beos*)\n\t\t\t\tvendor=be\n\t\t\t\t;;\n\t\t\t-hpux*)\n\t\t\t\tvendor=hp\n\t\t\t\t;;\n\t\t\t-mpeix*)\n\t\t\t\tvendor=hp\n\t\t\t\t;;\n\t\t\t-hiux*)\n\t\t\t\tvendor=hitachi\n\t\t\t\t;;\n\t\t\t-unos*)\n\t\t\t\tvendor=crds\n\t\t\t\t;;\n\t\t\t-dgux*)\n\t\t\t\tvendor=dg\n\t\t\t\t;;\n\t\t\t-luna*)\n\t\t\t\tvendor=omron\n\t\t\t\t;;\n\t\t\t-genix*)\n\t\t\t\tvendor=ns\n\t\t\t\t;;\n\t\t\t-mvs* | -opened*)\n\t\t\t\tvendor=ibm\n\t\t\t\t;;\n\t\t\t-os400*)\n\t\t\t\tvendor=ibm\n\t\t\t\t;;\n\t\t\t-ptx*)\n\t\t\t\tvendor=sequent\n\t\t\t\t;;\n\t\t\t-tpf*)\n\t\t\t\tvendor=ibm\n\t\t\t\t;;\n\t\t\t-vxsim* | -vxworks* | -windiss*)\n\t\t\t\tvendor=wrs\n\t\t\t\t;;\n\t\t\t-aux*)\n\t\t\t\tvendor=apple\n\t\t\t\t;;\n\t\t\t-hms*)\n\t\t\t\tvendor=hitachi\n\t\t\t\t;;\n\t\t\t-mpw* | -macos*)\n\t\t\t\tvendor=apple\n\t\t\t\t;;\n\t\t\t-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)\n\t\t\t\tvendor=atari\n\t\t\t\t;;\n\t\t\t-vos*)\n\t\t\t\tvendor=stratus\n\t\t\t\t;;\n\t\tesac\n\t\tbasic_machine=`echo $basic_machine | sed \"s/unknown/$vendor/\"`\n\t\t;;\nesac\n\necho $basic_machine$os\nexit\n\n# Local variables:\n# eval: (add-hook 'write-file-hooks 'time-stamp)\n# time-stamp-start: \"timestamp='\"\n# time-stamp-format: \"%:y-%02m-%02d\"\n# time-stamp-end: \"'\"\n# End:\n"
  },
  {
    "path": "deps/pjsip/configure",
    "content": "#!/bin/sh\n\n./aconfigure \"$@\"\n\n# Note:\n# if you're looking for the old configure script, it has been renamed\n# to configure-legacy\n\n"
  },
  {
    "path": "deps/pjsip/install-sh",
    "content": "#!/bin/sh\n\n# install - install a program, script, or datafile\n# This comes from X11R5 (mit/util/scripts/install.sh).\n#\n# Copyright 1991 by the Massachusetts Institute of Technology\n#\n# Permission to use, copy, modify, distribute, and sell this software and its\n# documentation for any purpose is hereby granted without fee, provided that\n# the above copyright notice appear in all copies and that both that\n# copyright notice and this permission notice appear in supporting\n# documentation, and that the name of M.I.T. not be used in advertising or\n# publicity pertaining to distribution of the software without specific,\n# written prior permission.  M.I.T. makes no representations about the\n# suitability of this software for any purpose.  It is provided \"as is\"\n# without express or implied warranty.\n#\n# Calling this script install-sh is preferred over install.sh, to prevent\n# `make' implicit rules from creating a file called install from it\n# when there is no Makefile.\n#\n# This script is compatible with the BSD install script, but was written\n# from scratch.  It can only install one file at a time, a restriction\n# shared with many OS's install programs.\n\n\n# set DOITPROG to echo to test this script\n\n# Don't use :- since 4.3BSD and earlier shells don't like it.\ndoit=\"${DOITPROG-}\"\n\n\n# put in absolute paths if you don't have them in your path; or use env. vars.\n\nmvprog=\"${MVPROG-mv}\"\ncpprog=\"${CPPROG-cp}\"\nchmodprog=\"${CHMODPROG-chmod}\"\nchownprog=\"${CHOWNPROG-chown}\"\nchgrpprog=\"${CHGRPPROG-chgrp}\"\nstripprog=\"${STRIPPROG-strip}\"\nrmprog=\"${RMPROG-rm}\"\nmkdirprog=\"${MKDIRPROG-mkdir}\"\n\ntransformbasename=\"\"\ntransform_arg=\"\"\ninstcmd=\"$mvprog\"\nchmodcmd=\"$chmodprog 0755\"\nchowncmd=\"\"\nchgrpcmd=\"\"\nstripcmd=\"\"\nrmcmd=\"$rmprog -f\"\nmvcmd=\"$mvprog\"\nsrc=\"\"\ndst=\"\"\ndir_arg=\"\"\n\nwhile [ x\"$1\" != x ]; do\n    case $1 in\n\t-c) instcmd=\"$cpprog\"\n\t    shift\n\t    continue;;\n\n\t-d) dir_arg=true\n\t    shift\n\t    continue;;\n\n\t-m) chmodcmd=\"$chmodprog $2\"\n\t    shift\n\t    shift\n\t    continue;;\n\n\t-o) chowncmd=\"$chownprog $2\"\n\t    shift\n\t    shift\n\t    continue;;\n\n\t-g) chgrpcmd=\"$chgrpprog $2\"\n\t    shift\n\t    shift\n\t    continue;;\n\n\t-s) stripcmd=\"$stripprog\"\n\t    shift\n\t    continue;;\n\n\t-t=*) transformarg=`echo $1 | sed 's/-t=//'`\n\t    shift\n\t    continue;;\n\n\t-b=*) transformbasename=`echo $1 | sed 's/-b=//'`\n\t    shift\n\t    continue;;\n\n\t*)  if [ x\"$src\" = x ]\n\t    then\n\t\tsrc=$1\n\t    else\n\t\t# this colon is to work around a 386BSD /bin/sh bug\n\t\t:\n\t\tdst=$1\n\t    fi\n\t    shift\n\t    continue;;\n    esac\ndone\n\nif [ x\"$src\" = x ]\nthen\n\techo \"install:\tno input file specified\"\n\texit 1\nelse\n\t:\nfi\n\nif [ x\"$dir_arg\" != x ]; then\n\tdst=$src\n\tsrc=\"\"\n\t\n\tif [ -d $dst ]; then\n\t\tinstcmd=:\n\t\tchmodcmd=\"\"\n\telse\n\t\tinstcmd=$mkdirprog\n\tfi\nelse\n\n# Waiting for this to be detected by the \"$instcmd $src $dsttmp\" command\n# might cause directories to be created, which would be especially bad \n# if $src (and thus $dsttmp) contains '*'.\n\n\tif [ -f \"$src\" ] || [ -d \"$src\" ]\n\tthen\n\t\t:\n\telse\n\t\techo \"install:  $src does not exist\"\n\t\texit 1\n\tfi\n\t\n\tif [ x\"$dst\" = x ]\n\tthen\n\t\techo \"install:\tno destination specified\"\n\t\texit 1\n\telse\n\t\t:\n\tfi\n\n# If destination is a directory, append the input filename; if your system\n# does not like double slashes in filenames, you may need to add some logic\n\n\tif [ -d $dst ]\n\tthen\n\t\tdst=\"$dst\"/`basename $src`\n\telse\n\t\t:\n\tfi\nfi\n\n## this sed command emulates the dirname command\ndstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`\n\n# Make sure that the destination directory exists.\n#  this part is taken from Noah Friedman's mkinstalldirs script\n\n# Skip lots of stat calls in the usual case.\nif [ ! -d \"$dstdir\" ]; then\ndefaultIFS='\n\t'\nIFS=\"${IFS-${defaultIFS}}\"\n\noIFS=\"${IFS}\"\n# Some sh's can't handle IFS=/ for some reason.\nIFS='%'\nset - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`\nIFS=\"${oIFS}\"\n\npathcomp=''\n\nwhile [ $# -ne 0 ] ; do\n\tpathcomp=\"${pathcomp}${1}\"\n\tshift\n\n\tif [ ! -d \"${pathcomp}\" ] ;\n        then\n\t\t$mkdirprog \"${pathcomp}\"\n\telse\n\t\t:\n\tfi\n\n\tpathcomp=\"${pathcomp}/\"\ndone\nfi\n\nif [ x\"$dir_arg\" != x ]\nthen\n\t$doit $instcmd $dst &&\n\n\tif [ x\"$chowncmd\" != x ]; then $doit $chowncmd $dst; else : ; fi &&\n\tif [ x\"$chgrpcmd\" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&\n\tif [ x\"$stripcmd\" != x ]; then $doit $stripcmd $dst; else : ; fi &&\n\tif [ x\"$chmodcmd\" != x ]; then $doit $chmodcmd $dst; else : ; fi\nelse\n\n# If we're going to rename the final executable, determine the name now.\n\n\tif [ x\"$transformarg\" = x ] \n\tthen\n\t\tdstfile=`basename $dst`\n\telse\n\t\tdstfile=`basename $dst $transformbasename | \n\t\t\tsed $transformarg`$transformbasename\n\tfi\n\n# don't allow the sed command to completely eliminate the filename\n\n\tif [ x\"$dstfile\" = x ] \n\tthen\n\t\tdstfile=`basename $dst`\n\telse\n\t\t:\n\tfi\n\n# Make a temp file name in the proper directory.\n\n\tdsttmp=$dstdir/#inst.$$#\n\n# Move or copy the file name to the temp name\n\n\t$doit $instcmd $src $dsttmp &&\n\n\ttrap \"rm -f ${dsttmp}\" 0 &&\n\n# and set any options; do chmod last to preserve setuid bits\n\n# If any of these fail, we abort the whole thing.  If we want to\n# ignore errors from any of these, just make sure not to ignore\n# errors from the above \"$doit $instcmd $src $dsttmp\" command.\n\n\tif [ x\"$chowncmd\" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&\n\tif [ x\"$chgrpcmd\" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&\n\tif [ x\"$stripcmd\" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&\n\tif [ x\"$chmodcmd\" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&\n\n# Now rename the file to the real destination.\n\n\t$doit $rmcmd -f $dstdir/$dstfile &&\n\t$doit $mvcmd $dsttmp $dstdir/$dstfile \n\nfi &&\n\n\nexit 0\n"
  },
  {
    "path": "deps/pjsip/pjlib/build/Makefile",
    "content": "include ../../build.mak\ninclude ../../version.mak\ninclude $(PJDIR)/build/common.mak\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\n\nexport PJLIB_LIB := ../lib/libpj-$(TARGET_NAME)$(LIBEXT)\n\n###############################################################################\n# Gather all flags.\n#\nexport _CFLAGS \t:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t\t   $(CFLAGS) $(CC_INC)../include\nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\nexport _LDFLAGS := $(subst /,$(HOST_PSEP),$(PJLIB_LIB)) \\\n\t\t   $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(LDFLAGS) \n\n###############################################################################\n# Defines for building PJLIB library\n#\nexport PJLIB_SRCDIR = ../src/pj\nexport PJLIB_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \\\n\tactivesock.o array.o config.o ctype.o errno.o except.o fifobuf.o \\\n\tguid.o hash.o ip_helper_generic.o list.o lock.o log.o os_time_common.o \\\n\tos_info.o pool.o pool_buf.o pool_caching.o pool_dbg.o rand.o \\\n\trbtree.o sock_common.o sock_qos_common.o sock_qos_bsd.o \\\n\tssl_sock_common.o ssl_sock_ossl.o ssl_sock_dump.o \\\n\tstring.o timer.o types.o\nexport PJLIB_CFLAGS += $(_CFLAGS)\n\n###############################################################################\n# Defines for building test application\n#\nexport TEST_SRCDIR = ../src/pjlib-test\nexport TEST_OBJS += activesock.o atomic.o echo_clt.o errno.o exception.o \\\n\t\t    fifobuf.o file.o hash_test.o ioq_perf.o ioq_udp.o \\\n\t\t    ioq_unreg.o ioq_tcp.o \\\n\t\t    list.o mutex.o os.o pool.o pool_perf.o rand.o rbtree.o \\\n\t\t    select.o sleep.o sock.o sock_perf.o ssl_sock.o \\\n\t\t    string.o test.o thread.o timer.o timestamp.o \\\n\t\t    udp_echo_srv_sync.o udp_echo_srv_ioqueue.o \\\n\t\t    util.o\nexport TEST_CFLAGS += $(_CFLAGS)\nexport TEST_LDFLAGS += $(_LDFLAGS)\nexport TEST_EXE := ../bin/pjlib-test-$(TARGET_NAME)$(HOST_EXE)\n\n\t\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT \n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && rm -rf docs/$(PJ_VERSION) && doxygen docs/doxygen.cfg\n\t@if [ -n \"$(WWWDIR)\" ] && ! [ -d \"$(WWWDIR)/docs/$(PJ_VERSION)/pjlib/docs/html\" ] ; then \\\n\t\techo \"Creating docs/$(PJ_VERSION)/pjlib/docs/html\" ; \\\n\t\tmkdir -p $(WWWDIR)/docs/$(PJ_VERSION)/pjlib/docs/html ; \\\n\tfi \n\t@if [ -n \"$(WWWDIR)\" ] && [ -d \"$(WWWDIR)/docs/$(PJ_VERSION)/pjlib/docs/html\" ] ; then \\\n\t\techo \"Copying docs/$(PJ_VERSION) to $(WWWDIR)/docs/$(PJ_VERSION)/pjlib/docs/html..\" ; \\\n\t\tcp -v -a ../docs/$(PJ_VERSION)/html/* $(WWWDIR)/docs/$(PJ_VERSION)/pjlib/docs/html/ ; \\\n\tfi\nprint:\n\t$(MAKE) -f $(RULES_MAK) APP=PJLIB app=pjlib print_lib\n\t$(MAKE) -f $(RULES_MAK) APP=TEST app=pjlib-test print_bin\n\t\ndepend: ../include/pj/config_site.h\n\t$(MAKE) -f $(RULES_MAK) APP=PJLIB app=pjlib depend\n\t$(MAKE) -f $(RULES_MAK) APP=TEST app=pjlib-test depend\n\techo '$(TEST_EXE): $(PJLIB_LIB)' >> .pjlib-test-$(TARGET_NAME).depend\n\n\n.PHONY: dep depend pjlib pjlib-test clean realclean distclean\n\ndep: depend\n\npjlib: ../include/pj/config_site.h\n\t$(MAKE) -f $(RULES_MAK) APP=PJLIB app=pjlib $(PJLIB_LIB)\n\n../include/pj/config_site.h:\n\ttouch ../include/pj/config_site.h\n\t\npjlib-test: pjlib\n\t$(MAKE) -f $(RULES_MAK) APP=TEST app=pjlib-test $(TEST_EXE)\n\n.PHONY: ../lib/pjlib.ko\n../lib/pjlib.ko:\n\techo Making $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJLIB app=pjlib $@\n\n.PHONY: ../lib/pjlib-test.ko\n../lib/pjlib-test.ko:\n\t$(MAKE) -f $(RULES_MAK) APP=TEST app=pjlib-test $@\n\nclean:\n\t$(MAKE) -f $(RULES_MAK) APP=PJLIB app=pjlib clean\n\t$(MAKE) -f $(RULES_MAK) APP=TEST app=pjlib-test clean\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjlib-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjlib-test-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(MAKE) -f $(RULES_MAK) APP=PJLIB app=pjlib realclean\n\t$(MAKE) -f $(RULES_MAK) APP=TEST app=pjlib-test realclean\n\ndistclean: realclean\n\ngcov-report:\n\t$(MAKE) -f $(RULES_MAK) APP=PJLIB app=pjlib gcov-report\n\t$(MAKE) -f $(RULES_MAK) APP=TEST app=pjlib-test gcov-report\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/build/os-auto.mak.in",
    "content": "# @configure_input@\n\n# Determine OS specific files\nAC_OS_OBJS=@ac_os_objs@\n\n#\n# PJLIB_OBJS specified here are object files to be included in PJLIB\n# (the library) for this specific operating system. Object files common \n# to all operating systems should go in Makefile instead.\n#\nexport PJLIB_OBJS +=\t$(AC_OS_OBJS) \\\n\t\t\taddr_resolv_sock.o \\\n\t\t\tlog_writer_stdout.o \\\n\t\t\tos_timestamp_common.o \\\n\t\t\tpool_policy_malloc.o sock_bsd.o sock_select.o\n\n#\n# TEST_OBJS are operating system specific object files to be included in\n# the test application.\n#\nexport TEST_OBJS +=\t@ac_main_obj@\n\n#\n# Additional LDFLAGS for pjlib-test\n#\nexport TEST_LDFLAGS += @LDFLAGS@ @LIBS@\n\n#\n# TARGETS are make targets in the Makefile, to be executed for this given\n# operating system.\n#\nexport TARGETS\t    =\tpjlib\n\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/docs/doxygen.cfg",
    "content": "# Doxyfile 1.3-rc3\r\n\r\n# This file describes the settings to be used by the documentation system\r\n# doxygen (www.doxygen.org) for a project\r\n#\r\n# All text after a hash (#) is considered a comment and will be ignored\r\n# The format is:\r\n#       TAG = value [value, ...]\r\n# For lists items can also be appended using:\r\n#       TAG += value [value, ...]\r\n# Values that contain spaces should be placed between quotes (\" \")\r\n\r\n#---------------------------------------------------------------------------\r\n# General configuration options\r\n#---------------------------------------------------------------------------\r\n\r\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded \r\n# by quotes) that should identify the project.\r\n\r\nPROJECT_NAME           =  \"PJLIB Reference\"\r\n\r\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. \r\n# This could be handy for archiving the generated documentation or \r\n# if some version control system is used.\r\n\r\nPROJECT_NUMBER         = $(PJ_VERSION)\r\n\r\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) \r\n# base path where the generated documentation will be put. \r\n# If a relative path is entered, it will be relative to the location \r\n# where doxygen was started. If left blank the current directory will be used.\r\n\r\nOUTPUT_DIRECTORY       = docs/$(PJ_VERSION)\r\n\r\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all \r\n# documentation generated by doxygen is written. Doxygen will use this \r\n# information to generate all constant output in the proper language. \r\n# The default language is English, other supported languages are: \r\n# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, \r\n# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en \r\n# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, \r\n# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian.\r\n\r\nOUTPUT_LANGUAGE        = English\r\n\r\n# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in \r\n# documentation are documented, even if no documentation was available. \r\n# Private class members and static file members will be hidden unless \r\n# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES\r\n\r\nEXTRACT_ALL            = NO\r\n\r\n# If the EXTRACT_PRIVATE tag is set to YES all private members of a class \r\n# will be included in the documentation.\r\n\r\nEXTRACT_PRIVATE        = NO\r\n\r\n# If the EXTRACT_STATIC tag is set to YES all static members of a file \r\n# will be included in the documentation.\r\n\r\nEXTRACT_STATIC         = NO\r\n\r\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) \r\n# defined locally in source files will be included in the documentation. \r\n# If set to NO only classes defined in header files are included.\r\n\r\nEXTRACT_LOCAL_CLASSES  = YES\r\n\r\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all \r\n# undocumented members of documented classes, files or namespaces. \r\n# If set to NO (the default) these members will be included in the \r\n# various overviews, but no documentation section is generated. \r\n# This option has no effect if EXTRACT_ALL is enabled.\r\n\r\nHIDE_UNDOC_MEMBERS     = NO\r\n\r\n# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all \r\n# undocumented classes that are normally visible in the class hierarchy. \r\n# If set to NO (the default) these class will be included in the various \r\n# overviews. This option has no effect if EXTRACT_ALL is enabled.\r\n\r\nHIDE_UNDOC_CLASSES     = NO\r\n\r\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all \r\n# friend (class|struct|union) declarations. \r\n# If set to NO (the default) these declarations will be included in the \r\n# documentation.\r\n\r\nHIDE_FRIEND_COMPOUNDS  = NO\r\n\r\n# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any \r\n# documentation blocks found inside the body of a function. \r\n# If set to NO (the default) these blocks will be appended to the \r\n# function's detailed documentation block.\r\n\r\nHIDE_IN_BODY_DOCS      = NO\r\n\r\n# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will \r\n# include brief member descriptions after the members that are listed in \r\n# the file and class documentation (similar to JavaDoc). \r\n# Set to NO to disable this.\r\n\r\nBRIEF_MEMBER_DESC      = YES\r\n\r\n# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend \r\n# the brief description of a member or function before the detailed description. \r\n# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the \r\n# brief descriptions will be completely suppressed.\r\n\r\nREPEAT_BRIEF           = YES\r\n\r\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then \r\n# Doxygen will generate a detailed section even if there is only a brief \r\n# description.\r\n\r\nALWAYS_DETAILED_SEC    = NO\r\n\r\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited \r\n# members of a class in the documentation of that class as if those members were \r\n# ordinary class members. Constructors, destructors and assignment operators of \r\n# the base classes will not be shown.\r\n\r\nINLINE_INHERITED_MEMB  = NO\r\n\r\n# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full \r\n# path before files name in the file list and in the header files. If set \r\n# to NO the shortest path that makes the file name unique will be used.\r\n\r\nFULL_PATH_NAMES        = NO\r\n\r\n# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag \r\n# can be used to strip a user defined part of the path. Stripping is \r\n# only done if one of the specified strings matches the left-hand part of \r\n# the path. It is allowed to use relative paths in the argument list.\r\n\r\nSTRIP_FROM_PATH        = \"c:\\project\\pjproject\"\r\n\r\n# The INTERNAL_DOCS tag determines if documentation \r\n# that is typed after a \\internal command is included. If the tag is set \r\n# to NO (the default) then the documentation will be excluded. \r\n# Set it to YES to include the internal documentation.\r\n\r\nINTERNAL_DOCS          = NO\r\n\r\n# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate \r\n# file names in lower case letters. If set to YES upper case letters are also \r\n# allowed. This is useful if you have classes or files whose names only differ \r\n# in case and if your file system supports case sensitive file names. Windows \r\n# users are adviced to set this option to NO.\r\n\r\nCASE_SENSE_NAMES       = YES\r\n\r\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter \r\n# (but less readable) file names. This can be useful is your file systems \r\n# doesn't support long names like on DOS, Mac, or CD-ROM.\r\n\r\nSHORT_NAMES            = NO\r\n\r\n# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen \r\n# will show members with their full class and namespace scopes in the \r\n# documentation. If set to YES the scope will be hidden.\r\n\r\nHIDE_SCOPE_NAMES       = NO\r\n\r\n# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen \r\n# will generate a verbatim copy of the header file for each class for \r\n# which an include is specified. Set to NO to disable this.\r\n\r\nVERBATIM_HEADERS       = YES\r\n\r\n# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen \r\n# will put list of the files that are included by a file in the documentation \r\n# of that file.\r\n\r\nSHOW_INCLUDE_FILES     = NO\r\n\r\n# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen \r\n# will interpret the first line (until the first dot) of a JavaDoc-style \r\n# comment as the brief description. If set to NO, the JavaDoc \r\n# comments  will behave just like the Qt-style comments (thus requiring an \r\n# explict @brief command for a brief description.\r\n\r\nJAVADOC_AUTOBRIEF      = NO\r\n\r\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen \r\n# treat a multi-line C++ special comment block (i.e. a block of //! or /// \r\n# comments) as a brief description. This used to be the default behaviour. \r\n# The new default is to treat a multi-line C++ comment block as a detailed \r\n# description. Set this tag to YES if you prefer the old behaviour instead.\r\n\r\nMULTILINE_CPP_IS_BRIEF = NO\r\n\r\n# If the DETAILS_AT_TOP tag is set to YES then Doxygen \r\n# will output the detailed description near the top, like JavaDoc.\r\n# If set to NO, the detailed description appears after the member \r\n# documentation.\r\n\r\nDETAILS_AT_TOP         = YES\r\n\r\n# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented \r\n# member inherits the documentation from any documented member that it \r\n# reimplements.\r\n\r\nINHERIT_DOCS           = YES\r\n\r\n# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] \r\n# is inserted in the documentation for inline members.\r\n\r\nINLINE_INFO            = YES\r\n\r\n# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen \r\n# will sort the (detailed) documentation of file and class members \r\n# alphabetically by member name. If set to NO the members will appear in \r\n# declaration order.\r\n\r\nSORT_MEMBER_DOCS       = YES\r\n\r\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC \r\n# tag is set to YES, then doxygen will reuse the documentation of the first \r\n# member in the group (if any) for the other members of the group. By default \r\n# all members of a group must be documented explicitly.\r\n\r\nDISTRIBUTE_GROUP_DOC   = NO\r\n\r\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. \r\n# Doxygen uses this value to replace tabs by spaces in code fragments.\r\n\r\nTAB_SIZE               = 8\r\n\r\n# The GENERATE_TODOLIST tag can be used to enable (YES) or \r\n# disable (NO) the todo list. This list is created by putting \\todo \r\n# commands in the documentation.\r\n\r\nGENERATE_TODOLIST      = YES\r\n\r\n# The GENERATE_TESTLIST tag can be used to enable (YES) or \r\n# disable (NO) the test list. This list is created by putting \\test \r\n# commands in the documentation.\r\n\r\nGENERATE_TESTLIST      = YES\r\n\r\n# The GENERATE_BUGLIST tag can be used to enable (YES) or \r\n# disable (NO) the bug list. This list is created by putting \\bug \r\n# commands in the documentation.\r\n\r\nGENERATE_BUGLIST       = YES\r\n\r\n# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or \r\n# disable (NO) the deprecated list. This list is created by putting \r\n# \\deprecated commands in the documentation.\r\n\r\nGENERATE_DEPRECATEDLIST= YES\r\n\r\n# This tag can be used to specify a number of aliases that acts \r\n# as commands in the documentation. An alias has the form \"name=value\". \r\n# For example adding \"sideeffect=\\par Side Effects:\\n\" will allow you to \r\n# put the command \\sideeffect (or @sideeffect) in the documentation, which \r\n# will result in a user defined paragraph with heading \"Side Effects:\". \r\n# You can put \\n's in the value part of an alias to insert newlines.\r\n\r\nALIASES                = \r\n\r\n# The ENABLED_SECTIONS tag can be used to enable conditional \r\n# documentation sections, marked by \\if sectionname ... \\endif.\r\n\r\nENABLED_SECTIONS       = \r\n\r\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines \r\n# the initial value of a variable or define consist of for it to appear in \r\n# the documentation. If the initializer consists of more lines than specified \r\n# here it will be hidden. Use a value of 0 to hide initializers completely. \r\n# The appearance of the initializer of individual variables and defines in the \r\n# documentation can be controlled using \\showinitializer or \\hideinitializer \r\n# command in the documentation regardless of this setting.\r\n\r\nMAX_INITIALIZER_LINES  = 30\r\n\r\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources \r\n# only. Doxygen will then generate output that is more tailored for C. \r\n# For instance some of the names that are used will be different. The list \r\n# of all members will be omitted, etc.\r\n\r\nOPTIMIZE_OUTPUT_FOR_C  = YES\r\n\r\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources \r\n# only. Doxygen will then generate output that is more tailored for Java. \r\n# For instance namespaces will be presented as packages, qualified scopes \r\n# will look different, etc.\r\n\r\nOPTIMIZE_OUTPUT_JAVA   = NO\r\n\r\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated \r\n# at the bottom of the documentation of classes and structs. If set to YES the \r\n# list will mention the files that were used to generate the documentation.\r\n\r\nSHOW_USED_FILES        = YES\r\nTYPEDEF_HIDES_STRUCT\t= YES\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to warning and progress messages\r\n#---------------------------------------------------------------------------\r\n\r\n# The QUIET tag can be used to turn on/off the messages that are generated \r\n# by doxygen. Possible values are YES and NO. If left blank NO is used.\r\n\r\nQUIET                  = NO\r\n\r\n# The WARNINGS tag can be used to turn on/off the warning messages that are \r\n# generated by doxygen. Possible values are YES and NO. If left blank \r\n# NO is used.\r\n\r\nWARNINGS               = YES\r\n\r\n# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings \r\n# for undocumented members. If EXTRACT_ALL is set to YES then this flag will \r\n# automatically be disabled.\r\n\r\nWARN_IF_UNDOCUMENTED   = YES\r\n\r\n# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for \r\n# potential errors in the documentation, such as not documenting some \r\n# parameters in a documented function, or documenting parameters that \r\n# don't exist or using markup commands wrongly.\r\n\r\nWARN_IF_DOC_ERROR      = YES\r\n\r\n# The WARN_FORMAT tag determines the format of the warning messages that \r\n# doxygen can produce. The string should contain the $file, $line, and $text \r\n# tags, which will be replaced by the file and line number from which the \r\n# warning originated and the warning text.\r\n\r\nWARN_FORMAT            = \"$file:$line: $text\"\r\n\r\n# The WARN_LOGFILE tag can be used to specify a file to which warning \r\n# and error messages should be written. If left blank the output is written \r\n# to stderr.\r\n\r\nWARN_LOGFILE           = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the input files\r\n#---------------------------------------------------------------------------\r\n\r\n# The INPUT tag can be used to specify the files and/or directories that contain \r\n# documented source files. You may enter file names like \"myfile.cpp\" or \r\n# directories like \"/usr/src/myproject\". Separate the files or directories \r\n# with spaces.\r\n\r\nINPUT                  =  include/pj src/pjlib-samples src/pjlib-test\r\n\r\n# If the value of the INPUT tag contains directories, you can use the \r\n# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \r\n# and *.h) to filter out the source-files in the directories. If left \r\n# blank the following patterns are tested: \r\n# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp \r\n# *.h++ *.idl *.odl\r\n\r\nFILE_PATTERNS          = *.h *.c\r\n\r\n# The RECURSIVE tag can be used to turn specify whether or not subdirectories \r\n# should be searched for input files as well. Possible values are YES and NO. \r\n# If left blank NO is used.\r\n\r\nRECURSIVE              = YES\r\n\r\n# The EXCLUDE tag can be used to specify files and/or directories that should \r\n# excluded from the INPUT source files. This way you can easily exclude a \r\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\r\n\r\nEXCLUDE                = \r\n\r\n# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories \r\n# that are symbolic links (a Unix filesystem feature) are excluded from the input.\r\n\r\nEXCLUDE_SYMLINKS       = NO\r\n\r\n# If the value of the INPUT tag contains directories, you can use the \r\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude \r\n# certain files from those directories.\r\n\r\nEXCLUDE_PATTERNS       = \"*_i.h\" \"*/compat/*\" \"*/config_site.h\"\r\n\r\n# The EXAMPLE_PATH tag can be used to specify one or more files or \r\n# directories that contain example code fragments that are included (see \r\n# the \\include command).\r\n\r\nEXAMPLE_PATH           = .\r\n\r\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the \r\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \r\n# and *.h) to filter out the source-files in the directories. If left \r\n# blank all files are included.\r\n\r\nEXAMPLE_PATTERNS       = \r\n\r\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be \r\n# searched for input files to be used with the \\include or \\dontinclude \r\n# commands irrespective of the value of the RECURSIVE tag. \r\n# Possible values are YES and NO. If left blank NO is used.\r\n\r\nEXAMPLE_RECURSIVE      = YES\r\n\r\n# The IMAGE_PATH tag can be used to specify one or more files or \r\n# directories that contain image that are included in the documentation (see \r\n# the \\image command).\r\n\r\nIMAGE_PATH             = \r\n\r\n# The INPUT_FILTER tag can be used to specify a program that doxygen should \r\n# invoke to filter for each input file. Doxygen will invoke the filter program \r\n# by executing (via popen()) the command <filter> <input-file>, where <filter> \r\n# is the value of the INPUT_FILTER tag, and <input-file> is the name of an \r\n# input file. Doxygen will then use the output that the filter program writes \r\n# to standard output.\r\n\r\nINPUT_FILTER           = \r\n\r\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using \r\n# INPUT_FILTER) will be used to filter the input files when producing source \r\n# files to browse (i.e. when SOURCE_BROWSER is set to YES).\r\n\r\nFILTER_SOURCE_FILES    = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to source browsing\r\n#---------------------------------------------------------------------------\r\n\r\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will \r\n# be generated. Documented entities will be cross-referenced with these sources.\r\n\r\nSOURCE_BROWSER         = NO\r\n\r\n# Setting the INLINE_SOURCES tag to YES will include the body \r\n# of functions and classes directly in the documentation.\r\n\r\nINLINE_SOURCES         = NO\r\n\r\n# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct \r\n# doxygen to hide any special comment blocks from generated source code \r\n# fragments. Normal C and C++ comments will always remain visible.\r\n\r\nSTRIP_CODE_COMMENTS    = YES\r\n\r\n# If the REFERENCED_BY_RELATION tag is set to YES (the default) \r\n# then for each documented function all documented \r\n# functions referencing it will be listed.\r\n\r\nREFERENCED_BY_RELATION = YES\r\n\r\n# If the REFERENCES_RELATION tag is set to YES (the default) \r\n# then for each documented function all documented entities \r\n# called/used by that function will be listed.\r\n\r\nREFERENCES_RELATION    = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the alphabetical class index\r\n#---------------------------------------------------------------------------\r\n\r\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index \r\n# of all compounds will be generated. Enable this if the project \r\n# contains a lot of classes, structs, unions or interfaces.\r\n\r\nALPHABETICAL_INDEX     = NO\r\n\r\n# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then \r\n# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns \r\n# in which this list will be split (can be a number in the range [1..20])\r\n\r\nCOLS_IN_ALPHA_INDEX    = 5\r\n\r\n# In case all classes in a project start with a common prefix, all \r\n# classes will be put under the same header in the alphabetical index. \r\n# The IGNORE_PREFIX tag can be used to specify one or more prefixes that \r\n# should be ignored while generating the index headers.\r\n\r\nIGNORE_PREFIX          = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the HTML output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_HTML tag is set to YES (the default) Doxygen will \r\n# generate HTML output.\r\n\r\nGENERATE_HTML          = YES\r\n\r\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `html' will be used as the default path.\r\n\r\nHTML_OUTPUT            = html\r\n\r\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for \r\n# each generated HTML page (for example: .htm,.php,.asp). If it is left blank \r\n# doxygen will generate files with .html extension.\r\n\r\nHTML_FILE_EXTENSION    = .htm\r\n\r\n# The HTML_HEADER tag can be used to specify a personal HTML header for \r\n# each generated HTML page. If it is left blank doxygen will generate a \r\n# standard header.\r\n\r\nHTML_HEADER            = docs/header.html\r\n\r\n# The HTML_FOOTER tag can be used to specify a personal HTML footer for \r\n# each generated HTML page. If it is left blank doxygen will generate a \r\n# standard footer.\r\n\r\nHTML_FOOTER            = docs/footer.html\r\n\r\n# The HTML_STYLESHEET tag can be used to specify a user defined cascading \r\n# style sheet that is used by each HTML page. It can be used to \r\n# fine-tune the look of the HTML output. If the tag is left blank doxygen \r\n# will generate a default style sheet\r\n\r\nHTML_STYLESHEET        = docs/doxygen.css\r\n\r\n# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, \r\n# files or namespaces will be aligned in HTML using tables. If set to \r\n# NO a bullet list will be used.\r\n\r\nHTML_ALIGN_MEMBERS     = YES\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, additional index files \r\n# will be generated that can be used as input for tools like the \r\n# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) \r\n# of the generated HTML documentation.\r\n\r\nGENERATE_HTMLHELP      = NO\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can \r\n# be used to specify the file name of the resulting .chm file. You \r\n# can add a path in front of the file if the result should not be \r\n# written to the html output dir.\r\n\r\nCHM_FILE               = \r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can \r\n# be used to specify the location (absolute path including file name) of \r\n# the HTML help compiler (hhc.exe). If non empty doxygen will try to run \r\n# the html help compiler on the generated index.hhp.\r\n\r\nHHC_LOCATION           = \r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag \r\n# controls if a separate .chi index file is generated (YES) or that \r\n# it should be included in the master .chm file (NO).\r\n\r\nGENERATE_CHI           = NO\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag \r\n# controls whether a binary table of contents is generated (YES) or a \r\n# normal table of contents (NO) in the .chm file.\r\n\r\nBINARY_TOC             = NO\r\n\r\n# The TOC_EXPAND flag can be set to YES to add extra items for group members \r\n# to the contents of the Html help documentation and to the tree view.\r\n\r\nTOC_EXPAND             = NO\r\n\r\n# The DISABLE_INDEX tag can be used to turn on/off the condensed index at \r\n# top of each HTML page. The value NO (the default) enables the index and \r\n# the value YES disables it.\r\n\r\nDISABLE_INDEX          = NO\r\n\r\n# This tag can be used to set the number of enum values (range [1..20]) \r\n# that doxygen will group on one line in the generated HTML documentation.\r\n\r\nENUM_VALUES_PER_LINE   = 4\r\n\r\n# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be\r\n# generated containing a tree-like index structure (just like the one that \r\n# is generated for HTML Help). For this to work a browser that supports \r\n# JavaScript, DHTML, CSS and frames is required (for instance Mozilla, \r\n# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are \r\n# probably better off using the HTML help feature.\r\n\r\nGENERATE_TREEVIEW      = NO\r\n\r\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be \r\n# used to set the initial width (in pixels) of the frame in which the tree \r\n# is shown.\r\n\r\nTREEVIEW_WIDTH         = 250\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the LaTeX output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will \r\n# generate Latex output.\r\n\r\nGENERATE_LATEX         = YES\r\n\r\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `latex' will be used as the default path.\r\n\r\nLATEX_OUTPUT           = latex\r\n\r\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be \r\n# invoked. If left blank `latex' will be used as the default command name.\r\n\r\nLATEX_CMD_NAME         = latex\r\n\r\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to \r\n# generate index for LaTeX. If left blank `makeindex' will be used as the \r\n# default command name.\r\n\r\nMAKEINDEX_CMD_NAME     = makeindex\r\n\r\n# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact \r\n# LaTeX documents. This may be useful for small projects and may help to \r\n# save some trees in general.\r\n\r\nCOMPACT_LATEX          = NO\r\n\r\n# The PAPER_TYPE tag can be used to set the paper type that is used \r\n# by the printer. Possible values are: a4, a4wide, letter, legal and \r\n# executive. If left blank a4wide will be used.\r\n\r\nPAPER_TYPE             = a4wide\r\n\r\n# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX \r\n# packages that should be included in the LaTeX output.\r\n\r\nEXTRA_PACKAGES         = \r\n\r\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for \r\n# the generated latex document. The header should contain everything until \r\n# the first chapter. If it is left blank doxygen will generate a \r\n# standard header. Notice: only use this tag if you know what you are doing!\r\n\r\nLATEX_HEADER           = \r\n\r\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated \r\n# is prepared for conversion to pdf (using ps2pdf). The pdf file will \r\n# contain links (just like the HTML output) instead of page references \r\n# This makes the output suitable for online browsing using a pdf viewer.\r\n\r\nPDF_HYPERLINKS         = YES\r\n\r\n# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of \r\n# plain latex in the generated Makefile. Set this option to YES to get a \r\n# higher quality PDF documentation.\r\n\r\nUSE_PDFLATEX           = YES\r\n\r\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\\\batchmode. \r\n# command to the generated LaTeX files. This will instruct LaTeX to keep \r\n# running if errors occur, instead of asking the user for help. \r\n# This option is also used when generating formulas in HTML.\r\n\r\nLATEX_BATCHMODE        = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the RTF output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output \r\n# The RTF output is optimised for Word 97 and may not look very pretty with \r\n# other RTF readers or editors.\r\n\r\nGENERATE_RTF           = NO\r\n\r\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `rtf' will be used as the default path.\r\n\r\nRTF_OUTPUT             = rtf\r\n\r\n# If the COMPACT_RTF tag is set to YES Doxygen generates more compact \r\n# RTF documents. This may be useful for small projects and may help to \r\n# save some trees in general.\r\n\r\nCOMPACT_RTF            = NO\r\n\r\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated \r\n# will contain hyperlink fields. The RTF file will \r\n# contain links (just like the HTML output) instead of page references. \r\n# This makes the output suitable for online browsing using WORD or other \r\n# programs which support those fields. \r\n# Note: wordpad (write) and others do not support links.\r\n\r\nRTF_HYPERLINKS         = NO\r\n\r\n# Load stylesheet definitions from file. Syntax is similar to doxygen's \r\n# config file, i.e. a series of assigments. You only have to provide \r\n# replacements, missing definitions are set to their default value.\r\n\r\nRTF_STYLESHEET_FILE    = \r\n\r\n# Set optional variables used in the generation of an rtf document. \r\n# Syntax is similar to doxygen's config file.\r\n\r\nRTF_EXTENSIONS_FILE    = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the man page output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_MAN tag is set to YES (the default) Doxygen will \r\n# generate man pages\r\n\r\nGENERATE_MAN           = NO\r\n\r\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `man' will be used as the default path.\r\n\r\nMAN_OUTPUT             = man\r\n\r\n# The MAN_EXTENSION tag determines the extension that is added to \r\n# the generated man pages (default is the subroutine's section .3)\r\n\r\nMAN_EXTENSION          = .3\r\n\r\n# If the MAN_LINKS tag is set to YES and Doxygen generates man output, \r\n# then it will generate one additional man file for each entity \r\n# documented in the real man page(s). These additional files \r\n# only source the real man page, but without them the man command \r\n# would be unable to find the correct page. The default is NO.\r\n\r\nMAN_LINKS              = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the XML output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_XML tag is set to YES Doxygen will \r\n# generate an XML file that captures the structure of \r\n# the code including all documentation. Note that this \r\n# feature is still experimental and incomplete at the \r\n# moment.\r\n\r\nGENERATE_XML           = NO\r\n\r\n# The XML_SCHEMA tag can be used to specify an XML schema, \r\n# which can be used by a validating XML parser to check the \r\n# syntax of the XML files.\r\n\r\nXML_SCHEMA             = \r\n\r\n# The XML_DTD tag can be used to specify an XML DTD, \r\n# which can be used by a validating XML parser to check the \r\n# syntax of the XML files.\r\n\r\nXML_DTD                = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options for the AutoGen Definitions output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will \r\n# generate an AutoGen Definitions (see autogen.sf.net) file \r\n# that captures the structure of the code including all \r\n# documentation. Note that this feature is still experimental \r\n# and incomplete at the moment.\r\n\r\nGENERATE_AUTOGEN_DEF   = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the Perl module output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_PERLMOD tag is set to YES Doxygen will \r\n# generate a Perl module file that captures the structure of \r\n# the code including all documentation. Note that this \r\n# feature is still experimental and incomplete at the \r\n# moment.\r\n\r\nGENERATE_PERLMOD       = NO\r\n\r\n# If the PERLMOD_LATEX tag is set to YES Doxygen will generate \r\n# the necessary Makefile rules, Perl scripts and LaTeX code to be able \r\n# to generate PDF and DVI output from the Perl module output.\r\n\r\nPERLMOD_LATEX          = NO\r\n\r\n# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be \r\n# nicely formatted so it can be parsed by a human reader.  This is useful \r\n# if you want to understand what is going on.  On the other hand, if this \r\n# tag is set to NO the size of the Perl module output will be much smaller \r\n# and Perl will parse it just the same.\r\n\r\nPERLMOD_PRETTY         = YES\r\n\r\n# The names of the make variables in the generated doxyrules.make file \r\n# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. \r\n# This is useful so different doxyrules.make files included by the same \r\n# Makefile don't overwrite each other's variables.\r\n\r\nPERLMOD_MAKEVAR_PREFIX = \r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration options related to the preprocessor   \r\n#---------------------------------------------------------------------------\r\n\r\n# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will \r\n# evaluate all C-preprocessor directives found in the sources and include \r\n# files.\r\n\r\nENABLE_PREPROCESSING   = YES\r\n\r\n# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro \r\n# names in the source code. If set to NO (the default) only conditional \r\n# compilation will be performed. Macro expansion can be done in a controlled \r\n# way by setting EXPAND_ONLY_PREDEF to YES.\r\n\r\nMACRO_EXPANSION        = YES\r\n\r\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES \r\n# then the macro expansion is limited to the macros specified with the \r\n# PREDEFINED and EXPAND_AS_PREDEFINED tags.\r\n\r\nEXPAND_ONLY_PREDEF     = NO\r\n\r\n# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files \r\n# in the INCLUDE_PATH (see below) will be search if a #include is found.\r\n\r\nSEARCH_INCLUDES        = YES\r\n\r\n# The INCLUDE_PATH tag can be used to specify one or more directories that \r\n# contain include files that are not input files but should be processed by \r\n# the preprocessor.\r\n\r\nINCLUDE_PATH           = \r\n\r\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard \r\n# patterns (like *.h and *.hpp) to filter out the header-files in the \r\n# directories. If left blank, the patterns specified with FILE_PATTERNS will \r\n# be used.\r\n\r\nINCLUDE_FILE_PATTERNS  = \r\n\r\n# The PREDEFINED tag can be used to specify one or more macro names that \r\n# are defined before the preprocessor is started (similar to the -D option of \r\n# gcc). The argument of the tag is a list of macros of the form: name \r\n# or name=definition (no spaces). If the definition and the = are \r\n# omitted =1 is assumed.\r\n\r\nPREDEFINED             = PJ_DECL(x)=x PJ_DEF(x)=x PJ_IDECL(x)=x \\\r\n\t\t\t PJ_IDEF(x)=x PJ_INLINE(x)=x \\\r\n\t\t\t PJ_DECL_DATA(x)=x \\\r\n\t\t\t PJ_DECL_NO_RETURN(x)=x \\\r\n\t\t\t PJ_NO_RETURN=x \\\r\n\t\t\t PJ_HAS_HIGH_RES_TIMER=1 \\\r\n\t\t\t PJ_LOG_MAX_LEVEL=4 \\\r\n\t\t\t PJ_HAS_SEMAPHORE=1 \\\r\n\t\t\t PJ_HAS_EVENT_OBJ=1 \\\r\n\t\t\t PJ_HAS_TCP=1\r\n\r\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then \r\n# this tag can be used to specify a list of macro names that should be expanded. \r\n# The macro definition that is found in the sources will be used. \r\n# Use the PREDEFINED tag if you want to use a different macro definition.\r\n\r\nEXPAND_AS_DEFINED      = \r\n\r\n# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then \r\n# doxygen's preprocessor will remove all function-like macros that are alone \r\n# on a line, have an all uppercase name, and do not end with a semicolon. Such \r\n# function macros are typically used for boiler-plate code, and will confuse the \r\n# parser if not removed.\r\n\r\nSKIP_FUNCTION_MACROS   = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration::addtions related to external references   \r\n#---------------------------------------------------------------------------\r\n\r\n# The TAGFILES tag can be used to specify one or more tagfiles.\r\n\r\nTAGFILES               = \r\n\r\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create \r\n# a tag file that is based on the input files it reads.\r\n\r\nGENERATE_TAGFILE       = docs/pjlib.tag\r\n\r\n# If the ALLEXTERNALS tag is set to YES all external classes will be listed \r\n# in the class index. If set to NO only the inherited external classes \r\n# will be listed.\r\n\r\nALLEXTERNALS           = NO\r\n\r\n# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed \r\n# in the modules index. If set to NO, only the current project's groups will \r\n# be listed.\r\n\r\nEXTERNAL_GROUPS        = YES\r\n\r\n# The PERL_PATH should be the absolute path and name of the perl script \r\n# interpreter (i.e. the result of `which perl').\r\n\r\n#PERL_PATH              = /usr/bin/perl\r\nPERL_PATH              = /c/Perl/bin/perl\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration options related to the dot tool   \r\n#---------------------------------------------------------------------------\r\n\r\n# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will \r\n# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or \r\n# super classes. Setting the tag to NO turns the diagrams off. Note that this \r\n# option is superceded by the HAVE_DOT option below. This is only a fallback. It is \r\n# recommended to install and use dot, since it yield more powerful graphs.\r\n\r\nCLASS_DIAGRAMS         = NO\r\n\r\n# If set to YES, the inheritance and collaboration graphs will hide \r\n# inheritance and usage relations if the target is undocumented \r\n# or is not a class.\r\n\r\nHIDE_UNDOC_RELATIONS   = YES\r\n\r\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is \r\n# available from the path. This tool is part of Graphviz, a graph visualization \r\n# toolkit from AT&T and Lucent Bell Labs. The other options in this section \r\n# have no effect if this option is set to NO (the default)\r\n\r\nHAVE_DOT               = NO\r\n\r\n# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen \r\n# will generate a graph for each documented class showing the direct and \r\n# indirect inheritance relations. Setting this tag to YES will force the \r\n# the CLASS_DIAGRAMS tag to NO.\r\n\r\nCLASS_GRAPH            = YES\r\n\r\n# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen \r\n# will generate a graph for each documented class showing the direct and \r\n# indirect implementation dependencies (inheritance, containment, and \r\n# class references variables) of the class with other documented classes.\r\n\r\nCOLLABORATION_GRAPH    = YES\r\n\r\n# If set to YES, the inheritance and collaboration graphs will show the \r\n# relations between templates and their instances.\r\n\r\nTEMPLATE_RELATIONS     = YES\r\n\r\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT \r\n# tags are set to YES then doxygen will generate a graph for each documented \r\n# file showing the direct and indirect include dependencies of the file with \r\n# other documented files.\r\n\r\nINCLUDE_GRAPH          = YES\r\n\r\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and \r\n# HAVE_DOT tags are set to YES then doxygen will generate a graph for each \r\n# documented header file showing the documented files that directly or \r\n# indirectly include this file.\r\n\r\nINCLUDED_BY_GRAPH      = YES\r\n\r\n# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen \r\n# will graphical hierarchy of all classes instead of a textual one.\r\n\r\nGRAPHICAL_HIERARCHY    = YES\r\n\r\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images \r\n# generated by dot. Possible values are png, jpg, or gif\r\n# If left blank png will be used.\r\n\r\nDOT_IMAGE_FORMAT       = png\r\n\r\n# The tag DOT_PATH can be used to specify the path where the dot tool can be \r\n# found. If left blank, it is assumed the dot tool can be found on the path.\r\n\r\nDOT_PATH               = \r\n\r\n# The DOTFILE_DIRS tag can be used to specify one or more directories that \r\n# contain dot files that are included in the documentation (see the \r\n# \\dotfile command).\r\n\r\nDOTFILE_DIRS           = \r\n\r\n# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width \r\n# (in pixels) of the graphs generated by dot. If a graph becomes larger than \r\n# this value, doxygen will try to truncate the graph, so that it fits within \r\n# the specified constraint. Beware that most browsers cannot cope with very \r\n# large images.\r\n\r\nMAX_DOT_GRAPH_WIDTH    = 1024\r\n\r\n# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height \r\n# (in pixels) of the graphs generated by dot. If a graph becomes larger than \r\n# this value, doxygen will try to truncate the graph, so that it fits within \r\n# the specified constraint. Beware that most browsers cannot cope with very \r\n# large images.\r\n\r\nMAX_DOT_GRAPH_HEIGHT   = 1024\r\n\r\n# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will \r\n# generate a legend page explaining the meaning of the various boxes and \r\n# arrows in the dot generated graphs.\r\n\r\nGENERATE_LEGEND        = YES\r\n\r\n# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will \r\n# remove the intermedate dot files that are used to generate \r\n# the various graphs.\r\n\r\nDOT_CLEANUP            = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration::addtions related to the search engine   \r\n#---------------------------------------------------------------------------\r\n\r\n# The SEARCHENGINE tag specifies whether or not a search engine should be \r\n# used. If set to NO the values of all tags below this one will be ignored.\r\n\r\nSEARCHENGINE           = NO\r\n\r\n# The CGI_NAME tag should be the name of the CGI script that \r\n# starts the search engine (doxysearch) with the correct parameters. \r\n# A script with this name will be generated by doxygen.\r\n\r\n#CGI_NAME               = search.cgi\r\n\r\n# The CGI_URL tag should be the absolute URL to the directory where the \r\n# cgi binaries are located. See the documentation of your http daemon for \r\n# details.\r\n\r\n#CGI_URL                = \r\n\r\n# The DOC_URL tag should be the absolute URL to the directory where the \r\n# documentation is located. If left blank the absolute path to the \r\n# documentation, with file:// prepended to it, will be used.\r\n\r\n#DOC_URL                = \r\n\r\n# The DOC_ABSPATH tag should be the absolute path to the directory where the \r\n# documentation is located. If left blank the directory on the local machine \r\n# will be used.\r\n\r\n#DOC_ABSPATH            = \r\n\r\n# The BIN_ABSPATH tag must point to the directory where the doxysearch binary \r\n# is installed.\r\n\r\n#BIN_ABSPATH            = /usr/local/bin/\r\n\r\n# The EXT_DOC_PATHS tag can be used to specify one or more paths to \r\n# documentation generated for other projects. This allows doxysearch to search \r\n# the documentation for these projects as well.\r\n\r\n#EXT_DOC_PATHS          = \r\n"
  },
  {
    "path": "deps/pjsip/pjlib/docs/doxygen.css",
    "content": "BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {\n\tfont-family: Geneva, Arial, Helvetica, sans-serif;\n}\nBODY,TD {\n       font-size: 80%;\n}\nCODE {\n\tfont-size: 120%;\n       font-family: monospace;\n}\n.fragment, pre {\n\tfont-size: 110%;\n       font-family: monospace;\n}\nH1 {\n\ttext-align: center;\n       font-size: 240%;\n}\nH2 {\n       \tfont-size: 200%;\n\tmargin-top     : 60px;\n}\nH3 {\n       font-size: 160%;\n}\nH4 {\n       font-size: 120%;\n}\nCAPTION { font-weight: bold }\nDIV.qindex {\n\twidth: 100%;\n\tbackground-color: #eeeeff;\n\tborder: 1px solid #b0b0b0;\n\ttext-align: center;\n\tmargin: 2px;\n\tpadding: 2px;\n\tline-height: 140%;\n}\nDIV.nav {\n\twidth: 100%;\n\tbackground-color: #eeeeff;\n\tborder: 1px solid #b0b0b0;\n\ttext-align: center;\n\tmargin: 2px;\n\tpadding: 2px;\n\tline-height: 140%;\n}\nA.qindex {\n       text-decoration: none;\n       font-size: 120%;\n       color: #1A419D;\n}\nA.qindex:visited {\n       text-decoration: none;\n       color: #1A419D\n}\nA.qindex:hover {\n\ttext-decoration: none;\n\tbackground-color: #ddddff;\n}\nA.qindexHL {\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tbackground-color: #6666cc;\n\tcolor: #ffffff;\n\tborder: 1px double #9295C2;\n}\nA.qindexHL:hover {\n\ttext-decoration: none;\n\tbackground-color: #6666cc;\n\tcolor: #ffffff;\n}\nA.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }\nA.el { text-decoration: none; font-weight: bold }\nA.elRef { font-weight: bold }\nA.code:link { text-decoration: none; font-weight: normal; color: #0000FF; }\nA.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}\nA.codeRef:link { font-weight: normal; color: #0000FF}\nA.codeRef:visited { font-weight: normal; color: #0000FF}\nA:hover { text-decoration: none; background-color: #f2f2ff }\nDL.el { margin-left: -1cm }\nPRE.fragment {\n\tborder: 1px solid #CCCCCC;\n\tbackground-color: #f5f5f5;\n\tmargin-top: 4px;\n\tmargin-bottom: 4px;\n\tmargin-left: 2px;\n\tmargin-right: 8px;\n\tpadding-left: 6px;\n\tpadding-right: 6px;\n\tpadding-top: 4px;\n\tpadding-bottom: 4px;\n}\nDIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }\nTD.md { background-color: #F4F4FB; font-weight: bold; }\nTD.mdPrefix {\n       background-color: #F4F4FB;\n       color: #606060;\n\tfont-size: 80%;\n}\nTD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; }\nTD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; }\nDIV.groupHeader {\n       margin-left: 16px;\n       margin-top: 12px;\n       margin-bottom: 6px;\n       font-weight: bold;\n}\nDIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }\nBODY {\n\tbackground: white;\n\tcolor: black;\n\tmargin-right: 20px;\n\tmargin-left: 20px;\n}\nTD.indexkey {\n\tbackground-color: #eeeeff;\n\tfont-weight: bold;\n\tpadding-right  : 10px;\n\tpadding-top    : 2px;\n\tpadding-left   : 10px;\n\tpadding-bottom : 2px;\n\tmargin-left    : 0px;\n\tmargin-right   : 0px;\n\tmargin-top     : 2px;\n\tmargin-bottom  : 2px;\n\tborder: 1px solid #CCCCCC;\n}\nTD.indexvalue {\n\tbackground-color: #eeeeff;\n\tfont-style: italic;\n\tpadding-right  : 10px;\n\tpadding-top    : 2px;\n\tpadding-left   : 10px;\n\tpadding-bottom : 2px;\n\tmargin-left    : 0px;\n\tmargin-right   : 0px;\n\tmargin-top     : 2px;\n\tmargin-bottom  : 2px;\n\tborder: 1px solid #CCCCCC;\n}\nTR.memlist {\n   background-color: #f0f0f0; \n}\nP.formulaDsp { text-align: center; }\nIMG.formulaDsp { }\nIMG.formulaInl { vertical-align: middle; }\nSPAN.keyword       { color: #008000 }\nSPAN.keywordtype   { color: #604020 }\nSPAN.keywordflow   { color: #e08000 }\nSPAN.comment       { color: #800000 }\nSPAN.preprocessor  { color: #806020 }\nSPAN.stringliteral { color: #002080 }\nSPAN.charliteral   { color: #008080 }\n.mdTable {\n\tborder: 1px solid #868686;\n\tbackground-color: #F4F4FB;\n}\n.mdRow {\n\tpadding: 8px 10px;\n}\n.mdescLeft {\n       padding: 0px 8px 4px 8px;\n\tfont-size: 80%;\n\tfont-style: italic;\n\tbackground-color: #FAFAFA;\n\tborder-top: 1px none #E0E0E0;\n\tborder-right: 1px none #E0E0E0;\n\tborder-bottom: 1px none #E0E0E0;\n\tborder-left: 1px none #E0E0E0;\n\tmargin: 0px;\n}\n.mdescRight {\n       padding: 0px 8px 4px 8px;\n\tfont-size: 80%;\n\tfont-style: italic;\n\tbackground-color: #FAFAFA;\n\tborder-top: 1px none #E0E0E0;\n\tborder-right: 1px none #E0E0E0;\n\tborder-bottom: 1px none #E0E0E0;\n\tborder-left: 1px none #E0E0E0;\n\tmargin: 0px;\n}\n.memItemLeft {\n\tpadding: 1px 0px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: solid;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.memItemRight {\n\tpadding: 1px 8px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: solid;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.memTemplItemLeft {\n\tpadding: 1px 0px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: none;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.memTemplItemRight {\n\tpadding: 1px 8px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: none;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.memTemplParams {\n\tpadding: 1px 0px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: solid;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n       color: #606060;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.search     { color: #003399;\n              font-weight: bold;\n}\nFORM.search {\n              margin-bottom: 0px;\n              margin-top: 0px;\n}\nINPUT.search { font-size: 75%;\n               color: #000080;\n               font-weight: normal;\n               background-color: #eeeeff;\n}\nTD.tiny      { font-size: 75%;\n}\na {\n\tcolor: #252E78;\n}\na:visited {\n\tcolor: #3D2185;\n}\n.dirtab { padding: 4px;\n          border-collapse: collapse;\n          border: 1px solid #b0b0b0;\n}\nTH.dirtab { background: #eeeeff;\n            font-weight: bold;\n}\nHR { height: 1px;\n     border: none;\n     border-top: 1px solid black;\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/docs/footer.html",
    "content": "<p>&nbsp;</p>\r\n<hr><center>\r\nPJLIB Open Source, high performance, small footprint, and very very portable framework<br>\r\nCopyright (C) 2006-2009 Teluu Inc.\r\n</center>\r\n\r\n\r\n<!--#include virtual=\"/footer.html\" -->\r\n\r\n</BODY>\r\n</HTML>\r\n"
  },
  {
    "path": "deps/pjsip/pjlib/docs/header.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=iso-8859-1\">\r\n<title>$title ($projectnumber)</title>\r\n<link href=\"/style/style.css\" rel=\"stylesheet\" type=\"text/css\">\r\n</head><body>\r\n\t<!--#include virtual=\"/header.html\" -->\r\n\t<p><A HREF=\"/\">Home</A> --&gt; <A HREF=\"/docs.htm\">Documentations</A> --&gt; PJLIB Reference</p>\r\n\r\n\r\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/activesock.h",
    "content": "/* $Id: activesock.h 4461 2013-04-05 03:02:19Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_ASYNCSOCK_H__\n#define __PJ_ASYNCSOCK_H__\n\n/**\n * @file activesock.h\n * @brief Active socket\n */\n\n#include <pj/ioqueue.h>\n#include <pj/sock.h>\n\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_ACTIVESOCK Active socket I/O\n * @brief Active socket performs active operations on socket.\n * @ingroup PJ_IO\n * @{\n *\n * Active socket is a higher level abstraction to the ioqueue. It provides\n * automation to socket operations which otherwise would have to be done\n * manually by the applications. For example with socket recv(), recvfrom(),\n * and accept() operations, application only needs to invoke these\n * operation once, and it will be notified whenever data or incoming TCP\n * connection (in the case of accept()) arrives.\n */\n\n/**\n * This opaque structure describes the active socket.\n */\ntypedef struct pj_activesock_t pj_activesock_t;\n\n/**\n * This structure contains the callbacks to be called by the active socket.\n */\ntypedef struct pj_activesock_cb\n{\n    /**\n     * This callback is called when a data arrives as the result of\n     * pj_activesock_start_read().\n     *\n     * @param asock\tThe active socket.\n     * @param data\tThe buffer containing the new data, if any. If \n     *\t\t\tthe status argument is non-PJ_SUCCESS, this \n     *\t\t\targument may be NULL.\n     * @param size\tThe length of data in the buffer.\n     * @param status\tThe status of the read operation. This may contain\n     *\t\t\tnon-PJ_SUCCESS for example when the TCP connection\n     *\t\t\thas been closed. In this case, the buffer may\n     *\t\t\tcontain left over data from previous callback which\n     *\t\t\tthe application may want to process.\n     * @param remainder\tIf application wishes to leave some data in the \n     *\t\t\tbuffer (common for TCP applications), it should \n     *\t\t\tmove the remainder data to the front part of the \n     *\t\t\tbuffer and set the remainder length here. The value\n     *\t\t\tof this parameter will be ignored for datagram\n     *\t\t\tsockets.\n     *\n     * @return\t\tPJ_TRUE if further read is desired, and PJ_FALSE \n     *\t\t\twhen application no longer wants to receive data.\n     *\t\t\tApplication may destroy the active socket in the\n     *\t\t\tcallback and return PJ_FALSE here.\n     */\n    pj_bool_t (*on_data_read)(pj_activesock_t *asock,\n\t\t\t      void *data,\n\t\t\t      pj_size_t size,\n\t\t\t      pj_status_t status,\n\t\t\t      pj_size_t *remainder);\n    /**\n     * This callback is called when a packet arrives as the result of\n     * pj_activesock_start_recvfrom().\n     *\n     * @param asock\tThe active socket.\n     * @param data\tThe buffer containing the packet, if any. If \n     *\t\t\tthe status argument is non-PJ_SUCCESS, this \n     *\t\t\targument will be set to NULL.\n     * @param size\tThe length of packet in the buffer. If \n     *\t\t\tthe status argument is non-PJ_SUCCESS, this \n     *\t\t\targument will be set to zero.\n     * @param src_addr\tSource address of the packet.\n     * @param addr_len\tLength of the source address.\n     * @param status\tThis contains\n     *\n     * @return\t\tPJ_TRUE if further read is desired, and PJ_FALSE \n     *\t\t\twhen application no longer wants to receive data.\n     *\t\t\tApplication may destroy the active socket in the\n     *\t\t\tcallback and return PJ_FALSE here.\n     */\n    pj_bool_t (*on_data_recvfrom)(pj_activesock_t *asock,\n\t\t\t\t  void *data,\n\t\t\t\t  pj_size_t size,\n\t\t\t\t  const pj_sockaddr_t *src_addr,\n\t\t\t\t  int addr_len,\n\t\t\t\t  pj_status_t status);\n\n    /**\n     * This callback is called when data has been sent.\n     *\n     * @param asock\tThe active socket.\n     * @param send_key\tKey associated with the send operation.\n     * @param sent\tIf value is positive non-zero it indicates the\n     *\t\t\tnumber of data sent. When the value is negative,\n     *\t\t\tit contains the error code which can be retrieved\n     *\t\t\tby negating the value (i.e. status=-sent).\n     *\n     * @return\t\tApplication may destroy the active socket in the\n     *\t\t\tcallback and return PJ_FALSE here.\n     */\n    pj_bool_t (*on_data_sent)(pj_activesock_t *asock,\n\t\t\t      pj_ioqueue_op_key_t *send_key,\n\t\t\t      pj_ssize_t sent);\n\n    /**\n     * This callback is called when new connection arrives as the result\n     * of pj_activesock_start_accept(). If the status of accept operation is\n     * needed use on_accept_complete2 instead of this callback.\n     *\n     * @param asock\tThe active socket.\n     * @param newsock\tThe new incoming socket.\n     * @param src_addr\tThe source address of the connection.\n     * @param addr_len\tLength of the source address.\n     *\n     * @return\t\tPJ_TRUE if further accept() is desired, and PJ_FALSE\n     *\t\t\twhen application no longer wants to accept incoming\n     *\t\t\tconnection. Application may destroy the active socket\n     *\t\t\tin the callback and return PJ_FALSE here.\n     */\n    pj_bool_t (*on_accept_complete)(pj_activesock_t *asock,\n\t\t\t\t    pj_sock_t newsock,\n\t\t\t\t    const pj_sockaddr_t *src_addr,\n\t\t\t\t    int src_addr_len);\n\n    /**\n     * This callback is called when new connection arrives as the result\n     * of pj_activesock_start_accept().\n     *\n     * @param asock\tThe active socket.\n     * @param newsock\tThe new incoming socket.\n     * @param src_addr\tThe source address of the connection.\n     * @param addr_len\tLength of the source address.\n     * @param status\tThe status of the accept operation. This may contain\n     *\t\t\tnon-PJ_SUCCESS for example when the TCP listener is in\n     *\t\t\tbad state for example on iOS platform after the\n     *\t\t\tapplication waking up from background.\n     *\n     * @return\t\tPJ_TRUE if further accept() is desired, and PJ_FALSE\n     *\t\t\twhen application no longer wants to accept incoming\n     *\t\t\tconnection. Application may destroy the active socket\n     *\t\t\tin the callback and return PJ_FALSE here.\n     */\n    pj_bool_t (*on_accept_complete2)(pj_activesock_t *asock,\n\t\t\t\t     pj_sock_t newsock,\n\t\t\t\t     const pj_sockaddr_t *src_addr,\n\t\t\t\t     int src_addr_len, \n\t\t\t\t     pj_status_t status);\n\n    /**\n     * This callback is called when pending connect operation has been\n     * completed.\n     *\n     * @param asock\tThe active  socket.\n     * @param status\tThe connection result. If connection has been\n     *\t\t\tsuccessfully established, the status will contain\n     *\t\t\tPJ_SUCCESS.\n     *\n     * @return\t\tApplication may destroy the active socket in the\n     *\t\t\tcallback and return PJ_FALSE here. \n     */\n    pj_bool_t (*on_connect_complete)(pj_activesock_t *asock,\n\t\t\t\t     pj_status_t status);\n\n} pj_activesock_cb;\n\n\n/**\n * Settings that can be given during active socket creation. Application\n * must initialize this structure with #pj_activesock_cfg_default().\n */\ntypedef struct pj_activesock_cfg\n{\n    /**\n     * Optional group lock to be assigned to the ioqueue key.\n     */\n    pj_grp_lock_t *grp_lock;\n\n    /**\n     * Number of concurrent asynchronous operations that is to be supported\n     * by the active socket. This value only affects socket receive and\n     * accept operations -- the active socket will issue one or more \n     * asynchronous read and accept operations based on the value of this\n     * field. Setting this field to more than one will allow more than one\n     * incoming data or incoming connections to be processed simultaneously\n     * on multiprocessor systems, when the ioqueue is polled by more than\n     * one threads.\n     *\n     * The default value is 1.\n     */\n    unsigned async_cnt;\n\n    /**\n     * The ioqueue concurrency to be forced on the socket when it is \n     * registered to the ioqueue. See #pj_ioqueue_set_concurrency() for more\n     * info about ioqueue concurrency.\n     *\n     * When this value is -1, the concurrency setting will not be forced for\n     * this socket, and the socket will inherit the concurrency setting of \n     * the ioqueue. When this value is zero, the active socket will disable\n     * concurrency for the socket. When this value is +1, the active socket\n     * will enable concurrency for the socket.\n     *\n     * The default value is -1.\n     */\n    int concurrency;\n\n    /**\n     * If this option is specified, the active socket will make sure that\n     * asynchronous send operation with stream oriented socket will only\n     * call the callback after all data has been sent. This means that the\n     * active socket will automatically resend the remaining data until\n     * all data has been sent.\n     *\n     * Please note that when this option is specified, it is possible that\n     * error is reported after partial data has been sent. Also setting\n     * this will disable the ioqueue concurrency for the socket.\n     *\n     * Default value is 1.\n     */\n    pj_bool_t whole_data;\n\n} pj_activesock_cfg;\n\n\n/**\n * Initialize the active socket configuration with the default values.\n *\n * @param cfg\t\tThe configuration to be initialized.\n */\nPJ_DECL(void) pj_activesock_cfg_default(pj_activesock_cfg *cfg);\n\n\n/**\n * Create the active socket for the specified socket. This will register\n * the socket to the specified ioqueue. \n *\n * @param pool\t\tPool to allocate memory from.\n * @param sock\t\tThe socket handle.\n * @param sock_type\tSpecify socket type, either pj_SOCK_DGRAM() or\n *\t\t\tpj_SOCK_STREAM(). The active socket needs this\n *\t\t\tinformation to handle connection closure for\n *\t\t\tconnection oriented sockets.\n * @param ioqueue\tThe ioqueue to use.\n * @param opt\t\tOptional settings. When this setting is not specifed,\n *\t\t\tthe default values will be used.\n * @param cb\t\tPointer to structure containing application\n *\t\t\tcallbacks.\n * @param user_data\tArbitrary user data to be associated with this\n *\t\t\tactive socket.\n * @param p_asock\tPointer to receive the active socket instance.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_activesock_create(pj_pool_t *pool,\n\t\t\t\t\t  pj_sock_t sock,\n\t\t\t\t\t  int sock_type,\n\t\t\t\t\t  const pj_activesock_cfg *opt,\n\t\t\t\t\t  pj_ioqueue_t *ioqueue,\n\t\t\t\t\t  const pj_activesock_cb *cb,\n\t\t\t\t\t  void *user_data,\n\t\t\t\t\t  pj_activesock_t **p_asock);\n\n/**\n * Create UDP socket descriptor, bind it to the specified address, and \n * create the active socket for the socket descriptor.\n *\n * @param pool\t\tPool to allocate memory from.\n * @param addr\t\tSpecifies the address family of the socket and the\n *\t\t\taddress where the socket should be bound to. If\n *\t\t\tthis argument is NULL, then AF_INET is assumed and\n *\t\t\tthe socket will be bound to any addresses and port.\n * @param opt\t\tOptional settings. When this setting is not specifed,\n *\t\t\tthe default values will be used.\n * @param cb\t\tPointer to structure containing application\n *\t\t\tcallbacks.\n * @param user_data\tArbitrary user data to be associated with this\n *\t\t\tactive socket.\n * @param p_asock\tPointer to receive the active socket instance.\n * @param bound_addr\tIf this argument is specified, it will be filled with\n *\t\t\tthe bound address on return.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_activesock_create_udp(pj_pool_t *pool,\n\t\t\t\t\t      const pj_sockaddr *addr,\n\t\t\t\t\t      const pj_activesock_cfg *opt,\n\t\t\t\t\t      pj_ioqueue_t *ioqueue,\n\t\t\t\t\t      const pj_activesock_cb *cb,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      pj_activesock_t **p_asock,\n\t\t\t\t\t      pj_sockaddr *bound_addr);\n\n/**\n * Close the active socket. This will unregister the socket from the\n * ioqueue and ultimately close the socket.\n *\n * @param asock\t    The active socket.\n *\n * @return\t    PJ_SUCCESS if the operation has been successful,\n *\t\t    or the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_activesock_close(pj_activesock_t *asock);\n\n#if (defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n     PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0) || \\\n     defined(DOXYGEN)\n/**\n * Set iPhone OS background mode setting. Setting to 1 will enable TCP\n * active socket to receive incoming data when application is in the\n * background. Setting to 0 will disable it. Default value of this\n * setting is PJ_ACTIVESOCK_TCP_IPHONE_OS_BG.\n *\n * This API is only available if PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT\n * is set to non-zero.\n *\n * @param asock\t    The active socket.\n * @param val\t    The value of background mode setting.\n *\n */\nPJ_DECL(void) pj_activesock_set_iphone_os_bg(pj_activesock_t *asock,\n\t\t\t\t\t     int val);\n\n/**\n * Enable/disable support for iPhone OS background mode. This setting\n * will apply globally and will affect any active sockets created\n * afterwards, if you want to change the setting for a particular\n * active socket, use #pj_activesock_set_iphone_os_bg() instead.\n * By default, this setting is enabled.\n *\n * This API is only available if PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT\n * is set to non-zero.\n *\n * @param val\t    The value of global background mode setting.\n *\n */\nPJ_DECL(void) pj_activesock_enable_iphone_os_bg(pj_bool_t val);\n#endif\n\n/**\n * Associate arbitrary data with the active socket. Application may\n * inspect this data in the callbacks and associate it with higher\n * level processing.\n *\n * @param asock\t    The active socket.\n * @param user_data The user data to be associated with the active\n *\t\t    socket.\n *\n * @return\t    PJ_SUCCESS if the operation has been successful,\n *\t\t    or the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_activesock_set_user_data(pj_activesock_t *asock,\n\t\t\t\t\t\t void *user_data);\n\n/**\n * Retrieve the user data previously associated with this active\n * socket.\n *\n * @param asock\t    The active socket.\n *\n * @return\t    The user data.\n */\nPJ_DECL(void*) pj_activesock_get_user_data(pj_activesock_t *asock);\n\n\n/**\n * Starts read operation on this active socket. This function will create\n * \\a async_cnt number of buffers (the \\a async_cnt parameter was given\n * in \\a pj_activesock_create() function) where each buffer is \\a buff_size\n * long. The buffers are allocated from the specified \\a pool. Once the \n * buffers are created, it then issues \\a async_cnt number of asynchronous\n * \\a recv() operations to the socket and returns back to caller. Incoming\n * data on the socket will be reported back to application via the \n * \\a on_data_read() callback.\n *\n * Application only needs to call this function once to initiate read\n * operations. Further read operations will be done automatically by the\n * active socket when \\a on_data_read() callback returns non-zero. \n *\n * @param asock\t    The active socket.\n * @param pool\t    Pool used to allocate buffers for incoming data.\n * @param buff_size The size of each buffer, in bytes.\n * @param flags\t    Flags to be given to pj_ioqueue_recv().\n *\n * @return\t    PJ_SUCCESS if the operation has been successful,\n *\t\t    or the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_activesock_start_read(pj_activesock_t *asock,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      unsigned buff_size,\n\t\t\t\t\t      pj_uint32_t flags);\n\n/**\n * Same as #pj_activesock_start_read(), except that the application\n * supplies the buffers for the read operation so that the acive socket\n * does not have to allocate the buffers.\n *\n * @param asock\t    The active socket.\n * @param pool\t    Pool used to allocate buffers for incoming data.\n * @param buff_size The size of each buffer, in bytes.\n * @param readbuf   Array of packet buffers, each has buff_size size.\n * @param flags\t    Flags to be given to pj_ioqueue_recv().\n *\n * @return\t    PJ_SUCCESS if the operation has been successful,\n *\t\t    or the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_activesock_start_read2(pj_activesock_t *asock,\n\t\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t\t       unsigned buff_size,\n\t\t\t\t\t       void *readbuf[],\n\t\t\t\t\t       pj_uint32_t flags);\n\n/**\n * Same as pj_activesock_start_read(), except that this function is used\n * only for datagram sockets, and it will trigger \\a on_data_recvfrom()\n * callback instead.\n *\n * @param asock\t    The active socket.\n * @param pool\t    Pool used to allocate buffers for incoming data.\n * @param buff_size The size of each buffer, in bytes.\n * @param flags\t    Flags to be given to pj_ioqueue_recvfrom().\n *\n * @return\t    PJ_SUCCESS if the operation has been successful,\n *\t\t    or the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_activesock_start_recvfrom(pj_activesock_t *asock,\n\t\t\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t\t\t  unsigned buff_size,\n\t\t\t\t\t\t  pj_uint32_t flags);\n\n/**\n * Same as #pj_activesock_start_recvfrom() except that the recvfrom() \n * operation takes the buffer from the argument rather than creating\n * new ones.\n *\n * @param asock\t    The active socket.\n * @param pool\t    Pool used to allocate buffers for incoming data.\n * @param buff_size The size of each buffer, in bytes.\n * @param readbuf   Array of packet buffers, each has buff_size size.\n * @param flags\t    Flags to be given to pj_ioqueue_recvfrom().\n *\n * @return\t    PJ_SUCCESS if the operation has been successful,\n *\t\t    or the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_activesock_start_recvfrom2(pj_activesock_t *asock,\n\t\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t\t   unsigned buff_size,\n\t\t\t\t\t\t   void *readbuf[],\n\t\t\t\t\t\t   pj_uint32_t flags);\n\n/**\n * Send data using the socket.\n *\n * @param asock\t    The active socket.\n * @param send_key  The operation key to send the data, which is useful\n *\t\t    if application wants to submit multiple pending\n *\t\t    send operations and want to track which exact data \n *\t\t    has been sent in the \\a on_data_sent() callback.\n * @param data\t    The data to be sent. This data must remain valid\n *\t\t    until the data has been sent.\n * @param size\t    The size of the data.\n * @param flags\t    Flags to be given to pj_ioqueue_send().\n *\n *\n * @return\t    PJ_SUCCESS if data has been sent immediately, or\n *\t\t    PJ_EPENDING if data cannot be sent immediately. In\n *\t\t    this case the \\a on_data_sent() callback will be\n *\t\t    called when data is actually sent. Any other return\n *\t\t    value indicates error condition.\n */\nPJ_DECL(pj_status_t) pj_activesock_send(pj_activesock_t *asock,\n\t\t\t\t\tpj_ioqueue_op_key_t *send_key,\n\t\t\t\t\tconst void *data,\n\t\t\t\t\tpj_ssize_t *size,\n\t\t\t\t\tunsigned flags);\n\n/**\n * Send datagram using the socket.\n *\n * @param asock\t    The active socket.\n * @param send_key  The operation key to send the data, which is useful\n *\t\t    if application wants to submit multiple pending\n *\t\t    send operations and want to track which exact data \n *\t\t    has been sent in the \\a on_data_sent() callback.\n * @param data\t    The data to be sent. This data must remain valid\n *\t\t    until the data has been sent.\n * @param size\t    The size of the data.\n * @param flags\t    Flags to be given to pj_ioqueue_send().\n * @param addr\t    The destination address.\n * @param addr_len  The length of the address.\n *\n * @return\t    PJ_SUCCESS if data has been sent immediately, or\n *\t\t    PJ_EPENDING if data cannot be sent immediately. In\n *\t\t    this case the \\a on_data_sent() callback will be\n *\t\t    called when data is actually sent. Any other return\n *\t\t    value indicates error condition.\n */\nPJ_DECL(pj_status_t) pj_activesock_sendto(pj_activesock_t *asock,\n\t\t\t\t\t  pj_ioqueue_op_key_t *send_key,\n\t\t\t\t\t  const void *data,\n\t\t\t\t\t  pj_ssize_t *size,\n\t\t\t\t\t  unsigned flags,\n\t\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t\t  int addr_len);\n\n#if PJ_HAS_TCP\n/**\n * Starts asynchronous socket accept() operations on this active socket. \n * Application must bind the socket before calling this function. This \n * function will issue \\a async_cnt number of asynchronous \\a accept() \n * operations to the socket and returns back to caller. Incoming\n * connection on the socket will be reported back to application via the\n * \\a on_accept_complete() callback.\n *\n * Application only needs to call this function once to initiate accept()\n * operations. Further accept() operations will be done automatically by \n * the active socket when \\a on_accept_complete() callback returns non-zero.\n *\n * @param asock\t    The active socket.\n * @param pool\t    Pool used to allocate some internal data for the\n *\t\t    operation.\n *\n * @return\t    PJ_SUCCESS if the operation has been successful,\n *\t\t    or the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_activesock_start_accept(pj_activesock_t *asock,\n\t\t\t\t\t\tpj_pool_t *pool);\n\n/**\n * Starts asynchronous socket connect() operation for this socket. Once\n * the connection is done (either successfully or not), the \n * \\a on_connect_complete() callback will be called.\n *\n * @param asock\t    The active socket.\n * @param pool\t    The pool to allocate some internal data for the\n *\t\t    operation.\n * @param remaddr   Remote address.\n * @param addr_len  Length of the remote address.\n *\n * @return\t    PJ_SUCCESS if connection can be established immediately,\n *\t\t    or PJ_EPENDING if connection cannot be established \n *\t\t    immediately. In this case the \\a on_connect_complete()\n *\t\t    callback will be called when connection is complete. \n *\t\t    Any other return value indicates error condition.\n */\nPJ_DECL(pj_status_t) pj_activesock_start_connect(pj_activesock_t *asock,\n\t\t\t\t\t\t pj_pool_t *pool,\n\t\t\t\t\t\t const pj_sockaddr_t *remaddr,\n\t\t\t\t\t\t int addr_len);\n\n\n#endif\t/* PJ_HAS_TCP */\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJ_ASYNCSOCK_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/addr_resolv.h",
    "content": "/* $Id: addr_resolv.h 4218 2012-08-07 02:18:15Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_ADDR_RESOLV_H__\n#define __PJ_ADDR_RESOLV_H__\n\n/**\n * @file addr_resolv.h\n * @brief IP address resolution.\n */\n\n#include <pj/sock.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup pj_addr_resolve Network Address Resolution\n * @ingroup PJ_IO\n * @{\n *\n * This module provides function to resolve Internet address of the\n * specified host name. To resolve a particular host name, application\n * can just call #pj_gethostbyname().\n *\n * Example:\n * <pre>\n *   ...\n *   pj_hostent he;\n *   pj_status_t rc;\n *   pj_str_t host = pj_str(\"host.example.com\");\n *   \n *   rc = pj_gethostbyname( &host, &he);\n *   if (rc != PJ_SUCCESS) {\n *      char errbuf[80];\n *      pj_strerror( rc, errbuf, sizeof(errbuf));\n *      PJ_LOG(2,(\"sample\", \"Unable to resolve host, error=%s\", errbuf));\n *      return rc;\n *   }\n *\n *   // process address...\n *   addr.sin_addr.s_addr = *(pj_uint32_t*)he.h_addr;\n *   ...\n * </pre>\n *\n * It's pretty simple really...\n */\n\n/** This structure describes an Internet host address. */\ntypedef struct pj_hostent\n{\n    char    *h_name;\t\t/**< The official name of the host. */\n    char   **h_aliases;\t\t/**< Aliases list. */\n    int\t     h_addrtype;\t/**< Host address type. */\n    int\t     h_length;\t\t/**< Length of address. */\n    char   **h_addr_list;\t/**< List of addresses. */\n} pj_hostent;\n\n/** Shortcut to h_addr_list[0] */\n#define h_addr h_addr_list[0]\n\n/** \n * This structure describes address information pj_getaddrinfo().\n */\ntypedef struct pj_addrinfo\n{\n    char\t ai_canonname[PJ_MAX_HOSTNAME]; /**< Canonical name for host*/\n    pj_sockaddr  ai_addr;\t\t\t/**< Binary address.\t    */\n} pj_addrinfo;\n\n\n/**\n * This function fills the structure of type pj_hostent for a given host name.\n * For host resolution function that also works with IPv6, please see\n * #pj_getaddrinfo().\n *\n * @param name\t    Host name to resolve. Specifying IPv4 address here\n *\t\t    may fail on some platforms (e.g. Windows)\n * @param he\t    The pj_hostent structure to be filled. Note that\n *\t\t    the pointers in this structure points to temporary\n *\t\t    variables which value will be reset upon subsequent\n *\t\t    invocation.\n *\n * @return\t    PJ_SUCCESS, or the appropriate error codes.\n */ \nPJ_DECL(pj_status_t) pj_gethostbyname(const pj_str_t *name, pj_hostent *he);\n\n\n/**\n * Resolve the primary IP address of local host. \n *\n * @param af\t    The desired address family to query. Valid values\n *\t\t    are pj_AF_INET() or pj_AF_INET6().\n * @param addr      On successful resolution, the address family and address\n *\t\t    part of this socket address will be filled up with the host\n *\t\t    IP address, in network byte order. Other parts of the socket\n *\t\t    address are untouched.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_gethostip(int af, pj_sockaddr *addr);\n\n\n/**\n * Get the interface IP address to send data to the specified destination.\n *\n * @param af\t    The desired address family to query. Valid values\n *\t\t    are pj_AF_INET() or pj_AF_INET6().\n * @param dst\t    The destination host.\n * @param itf_addr  On successful resolution, the address family and address\n *\t\t    part of this socket address will be filled up with the host\n *\t\t    IP address, in network byte order. Other parts of the socket\n *\t\t    address should be ignored.\n * @param allow_resolve   If \\a dst may contain hostname (instead of IP\n * \t\t    address), specify whether hostname resolution should\n * \t            be performed. If not, default interface address will\n *  \t\t    be returned.\n * @param p_dst_addr If not NULL, it will be filled with the IP address of\n * \t\t    the destination host.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_getipinterface(int af,\n                                       const pj_str_t *dst,\n                                       pj_sockaddr *itf_addr,\n                                       pj_bool_t allow_resolve,\n                                       pj_sockaddr *p_dst_addr);\n\n/**\n * Get the IP address of the default interface. Default interface is the\n * interface of the default route.\n *\n * @param af\t    The desired address family to query. Valid values\n *\t\t    are pj_AF_INET() or pj_AF_INET6().\n * @param addr      On successful resolution, the address family and address\n *\t\t    part of this socket address will be filled up with the host\n *\t\t    IP address, in network byte order. Other parts of the socket\n *\t\t    address are untouched.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_getdefaultipinterface(int af,\n\t\t\t\t\t      pj_sockaddr *addr);\n\n\n/**\n * This function translates the name of a service location (for example, \n * a host name) and returns a set of addresses and associated information\n * to be used in creating a socket with which to address the specified \n * service.\n *\n * @param af\t    The desired address family to query. Valid values\n *\t\t    are pj_AF_INET(), pj_AF_INET6(), or pj_AF_UNSPEC().\n * @param name\t    Descriptive name or an address string, such as host\n *\t\t    name.\n * @param count\t    On input, it specifies the number of elements in\n *\t\t    \\a ai array. On output, this will be set with the\n *\t\t    number of address informations found for the\n *\t\t    specified name.\n * @param ai\t    Array of address info to be filled with the information\n *\t\t    about the host.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *name,\n\t\t\t\t    unsigned *count, pj_addrinfo ai[]);\n\n\n\n/** @} */\n\nPJ_END_DECL\n\n#endif\t/* __PJ_ADDR_RESOLV_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/array.h",
    "content": "/* $Id: array.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_ARRAY_H__\n#define __PJ_ARRAY_H__\n\n/**\n * @file array.h\n * @brief PJLIB Array helper.\n */\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_ARRAY Array helper.\n * @ingroup PJ_DS\n * @{\n *\n * This module provides helper to manipulate array of elements of any size.\n * It provides most used array operations such as insert, erase, and search.\n */\n\n/**\n * Insert value to the array at the given position, and rearrange the\n * remaining nodes after the position.\n *\n * @param array\t    the array.\n * @param elem_size the size of the individual element.\n * @param count\t    the CURRENT number of elements in the array.\n * @param pos\t    the position where the new element is put.\n * @param value\t    the value to copy to the new element.\n */\nPJ_DECL(void) pj_array_insert( void *array,\n\t\t\t       unsigned elem_size,\n\t\t\t       unsigned count,\n\t\t\t       unsigned pos,\n\t\t\t       const void *value);\n\n/**\n * Erase a value from the array at given position, and rearrange the remaining\n * elements post the erased element.\n *\n * @param array\t    the array.\n * @param elem_size the size of the individual element.\n * @param count\t    the current number of elements in the array.\n * @param pos\t    the index/position to delete.\n */\nPJ_DECL(void) pj_array_erase( void *array,\n\t\t\t      unsigned elem_size,\n\t\t\t      unsigned count,\n\t\t\t      unsigned pos);\n\n/**\n * Search the first value in the array according to matching function.\n *\n * @param array\t    the array.\n * @param elem_size the individual size of the element.\n * @param count\t    the number of elements.\n * @param matching  the matching function, which MUST return PJ_SUCCESS if \n *\t\t    the specified element match.\n * @param result    the pointer to the value found.\n *\n * @return\t    PJ_SUCCESS if value is found, otherwise the error code.\n */\nPJ_DECL(pj_status_t) pj_array_find(   const void *array, \n\t\t\t\t      unsigned elem_size, \n\t\t\t\t      unsigned count, \n\t\t\t\t      pj_status_t (*matching)(const void *value),\n\t\t\t\t      void **result);\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJ_ARRAY_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/assert.h",
    "content": "/* $Id: assert.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_ASSERT_H__\n#define __PJ_ASSERT_H__\n\n/**\n * @file assert.h\n * @brief Assertion macro pj_assert().\n */\n\n#include <pj/config.h>\n#include <pj/compat/assert.h>\n\n/**\n * @defgroup pj_assert Assertion Macro\n * @ingroup PJ_MISC\n * @{\n *\n * Assertion and other helper macros for sanity checking.\n */\n\n/**\n * @hideinitializer\n * Check during debug build that an expression is true. If the expression\n * computes to false during run-time, then the program will stop at the\n * offending statements.\n * For release build, this macro will not do anything.\n *\n * @param expr\t    The expression to be evaluated.\n */\n#ifndef pj_assert\n#   define pj_assert(expr)   assert(expr)\n#endif\n\n\n/**\n * @hideinitializer\n * If #PJ_ENABLE_EXTRA_CHECK is declared and the value is non-zero, then \n * #PJ_ASSERT_RETURN macro will evaluate the expression in @a expr during\n * run-time. If the expression yields false, assertion will be triggered\n * and the current function will return with the specified return value.\n *\n * If #PJ_ENABLE_EXTRA_CHECK is not declared or is zero, then no run-time\n * checking will be performed. The macro simply evaluates to pj_assert(expr).\n */\n#if defined(PJ_ENABLE_EXTRA_CHECK) && PJ_ENABLE_EXTRA_CHECK != 0\n#   define PJ_ASSERT_RETURN(expr,retval)    \\\n\t    do { \\\n\t\tif (!(expr)) { return retval; } \\\n\t    } while (0)\n#else\n#   define PJ_ASSERT_RETURN(expr,retval)    pj_assert(expr)\n#endif\n\n/**\n * @hideinitializer\n * If #PJ_ENABLE_EXTRA_CHECK is declared and non-zero, then \n * #PJ_ASSERT_ON_FAIL macro will evaluate the expression in @a expr during\n * run-time. If the expression yields false, assertion will be triggered\n * and @a exec_on_fail will be executed.\n *\n * If #PJ_ENABLE_EXTRA_CHECK is not declared or is zero, then no run-time\n * checking will be performed. The macro simply evaluates to pj_assert(expr).\n */\n#if defined(PJ_ENABLE_EXTRA_CHECK) && PJ_ENABLE_EXTRA_CHECK != 0\n#   define PJ_ASSERT_ON_FAIL(expr,exec_on_fail)    \\\n\t    do { \\\n\t\tif (!(expr)) exec_on_fail; \\\n\t    } while (0)\n#else\n#   define PJ_ASSERT_ON_FAIL(expr,exec_on_fail)    pj_assert(expr)\n#endif\n\n/** @} */\n\n#endif\t/* __PJ_ASSERT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/assert.h",
    "content": "/* $Id: assert.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_ASSERT_H__\n#define __PJ_COMPAT_ASSERT_H__\n\n/**\n * @file assert.h\n * @brief Provides assert() macro.\n */\n\n#if defined(PJ_HAS_ASSERT_H) && PJ_HAS_ASSERT_H != 0\n#  include <assert.h>\n\n#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL != 0\n#  define assert(expr) do { \\\n\t\t\tif (!(expr)) \\\n\t\t\t  printk(\"!!ASSERTION FAILED: [%s:%d] \\\"\" #expr \"\\\"\\n\",\\\n\t\t\t\t __FILE__, __LINE__); \\\n\t\t       } while (0)\n\n#else\n#  warning \"assert() is not implemented\"\n#  define assert(expr)\n#endif\n\n#endif\t/* __PJ_COMPAT_ASSERT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/cc_armcc.h",
    "content": "/* $Id: cc_armcc.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_CC_ARMCC_H__\n#define __PJ_COMPAT_CC_ARMCC_H__\n\n/**\n * @file cc_armcc.h\n * @brief Describes ARMCC compiler specifics.\n */\n\n#ifndef __ARMCC__\n#  error \"This file is only for armcc!\"\n#endif\n\n#define PJ_CC_NAME\t\t\"armcc\"\n#define PJ_CC_VER_1             (__ARMCC_VERSION/100000)\n#define PJ_CC_VER_2             ((__ARMCC_VERSION%100000)/10000)\n#define PJ_CC_VER_3             (__ARMCC_VERSION%10000)\n\n#ifdef __cplusplus\n#  define PJ_INLINE_SPECIFIER\tinline\n#else\n#  define PJ_INLINE_SPECIFIER\tstatic __inline\n#endif\n\n#define PJ_THREAD_FUNC\t\n#define PJ_NORETURN\t\t\n#define PJ_ATTR_NORETURN\t__attribute__ ((noreturn))\n\n#define PJ_HAS_INT64\t\t1\n\ntypedef long long pj_int64_t;\ntypedef unsigned long long pj_uint64_t;\n\n#define PJ_INT64_FMT\t\t\"L\"\n\n#define PJ_UNREACHED(x)\t    \t\n\n#endif\t/* __PJ_COMPAT_CC_ARMCC_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/cc_codew.h",
    "content": "/* $Id: cc_codew.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_CC_CODEW_H__\n#define __PJ_COMPAT_CC_CODEW_H__\n\n/**\n * @file cc_codew.h\n * @brief Describes MetroWerks Code Warrior compiler specifics.\n */\n\n#ifndef __MWERKS__\n#  error \"This file is only for Code Warrior!\"\n#endif\n\n#define PJ_CC_NAME\t\t\"codewarrior\"\n#define PJ_CC_VER_1\t\t((__MWERKS__ & 0xF000) >> 12)\n#define PJ_CC_VER_2\t\t((__MWERKS__ & 0x0F00) >> 8)\n#define PJ_CC_VER_3\t\t((__MWERKS__ & 0xFF))\n\n\n#define PJ_INLINE_SPECIFIER\tstatic inline\n#define PJ_THREAD_FUNC\t\n#define PJ_NORETURN\t\t\n#define PJ_ATTR_NORETURN\t\n\n#define PJ_HAS_INT64\t\t1\n\ntypedef long long pj_int64_t;\ntypedef unsigned long long pj_uint64_t;\n\n#define PJ_INT64(val)\t\tval##LL\n#define PJ_UINT64(val)\t\tval##LLU\n#define PJ_INT64_FMT\t\t\"L\"\n\n#define PJ_UNREACHED(x)\t    \t\n\n#endif\t/* __PJ_COMPAT_CC_CODEW_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/cc_gcc.h",
    "content": "/* $Id: cc_gcc.h 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_CC_GCC_H__\n#define __PJ_COMPAT_CC_GCC_H__\n\n/**\n * @file cc_gcc.h\n * @brief Describes GCC compiler specifics.\n */\n\n#ifndef __GNUC__\n#  error \"This file is only for gcc!\"\n#endif\n\n#define PJ_CC_NAME\t\t\"gcc\"\n#define PJ_CC_VER_1\t\t__GNUC__\n#define PJ_CC_VER_2\t\t__GNUC_MINOR__\n\n/* __GNUC_PATCHLEVEL__ doesn't exist in gcc-2.9x.x */\n#ifdef __GNUC_PATCHLEVEL__\n#   define PJ_CC_VER_3\t\t__GNUC_PATCHLEVEL__\n#else\n#   define PJ_CC_VER_3\t\t0\n#endif\n\n\n\n#define PJ_THREAD_FUNC\t\n#define PJ_NORETURN\t\t\n\n#define PJ_HAS_INT64\t\t1\n\n#ifdef __STRICT_ANSI__\n  #include <inttypes.h> \n  typedef int64_t\t\tpj_int64_t;\n  typedef uint64_t\t\tpj_uint64_t;\n  #define PJ_INLINE_SPECIFIER\tstatic __inline\n  #define PJ_ATTR_NORETURN\t\n#else\n  typedef long long\t\tpj_int64_t;\n  typedef unsigned long long\tpj_uint64_t;\n  #define PJ_INLINE_SPECIFIER\tstatic inline\n  #define PJ_ATTR_NORETURN\t__attribute__ ((noreturn))\n#endif\n\n#define PJ_INT64(val)\t\tval##LL\n#define PJ_UINT64(val)\t\tval##LLU\n#define PJ_INT64_FMT\t\t\"L\"\n\n\n#ifdef __GLIBC__\n#   define PJ_HAS_BZERO\t\t1\n#endif\n\n#define PJ_UNREACHED(x)\t    \t\n\n#define PJ_ALIGN_DATA(declaration, alignment) declaration __attribute__((aligned (alignment)))\n\n\n#endif\t/* __PJ_COMPAT_CC_GCC_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/cc_gcce.h",
    "content": "/* $Id: cc_gcce.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_CC_GCCE_H__\n#define __PJ_COMPAT_CC_GCCE_H__\n\n/**\n * @file cc_gcce.h\n * @brief Describes GCCE compiler specifics.\n */\n\n#ifndef __GCCE__\n#  error \"This file is only for gcce!\"\n#endif\n\n#define PJ_CC_NAME\t\t\"gcce\"\n#define PJ_CC_VER_1\t\t__GCCE__\n#define PJ_CC_VER_2\t\t__GCCE_MINOR__\n#define PJ_CC_VER_3\t\t__GCCE_PATCHLEVEL__\n\n\n#define PJ_INLINE_SPECIFIER\tstatic inline\n#define PJ_THREAD_FUNC\t\n#define PJ_NORETURN\t\t\n#define PJ_ATTR_NORETURN\t__attribute__ ((noreturn))\n\n#define PJ_HAS_INT64\t\t1\n\ntypedef long long pj_int64_t;\ntypedef unsigned long long pj_uint64_t;\n\n#define PJ_INT64(val)\t\tval##LL\n#define PJ_UINT64(val)\t\tval##LLU\n#define PJ_INT64_FMT\t\t\"L\"\n\n\n#endif\t/* __PJ_COMPAT_CC_GCCE_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/cc_msvc.h",
    "content": "/* $Id: cc_msvc.h 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_CC_MSVC_H__\n#define __PJ_COMPAT_CC_MSVC_H__\n\n/**\n * @file cc_msvc.h\n * @brief Describes Microsoft Visual C compiler specifics.\n */\n\n#ifndef _MSC_VER\n#  error \"This header file is only for Visual C compiler!\"\n#endif\n\n#define PJ_CC_NAME\t    \"msvc\"\n#define PJ_CC_VER_1\t    (_MSC_VER/100)\n#define PJ_CC_VER_2\t    (_MSC_VER%100)\n#define PJ_CC_VER_3\t    0\n\n/* Disable CRT deprecation warnings. */\n#if PJ_CC_VER_1 >= 8 && !defined(_CRT_SECURE_NO_DEPRECATE)\n#   define _CRT_SECURE_NO_DEPRECATE\n#endif\n#if PJ_CC_VER_1 >= 8 && !defined(_CRT_SECURE_NO_WARNINGS)\n#   define _CRT_SECURE_NO_WARNINGS\n    /* The above doesn't seem to work, at least on VS2005, so lets use\n     * this construct as well.\n     */\n#   pragma warning(disable: 4996)\n#endif\n\n#pragma warning(disable: 4127) // conditional expression is constant\n#pragma warning(disable: 4611) // not wise to mix setjmp with C++\n#pragma warning(disable: 4514) // unref. inline function has been removed\n#ifdef NDEBUG\n#  pragma warning(disable: 4702) // unreachable code\n#  pragma warning(disable: 4710) // function is not inlined.\n#  pragma warning(disable: 4711) // function selected for auto inline expansion\n#endif\n\n#ifdef __cplusplus\n#  define PJ_INLINE_SPECIFIER\tinline\n#else\n#  define PJ_INLINE_SPECIFIER\tstatic __inline\n#endif\n\n#define PJ_EXPORT_DECL_SPECIFIER    __declspec(dllexport)\n#define PJ_EXPORT_DEF_SPECIFIER\t    __declspec(dllexport)\n#define PJ_IMPORT_DECL_SPECIFIER    __declspec(dllimport)\n\n#define PJ_THREAD_FUNC\t\n#define PJ_NORETURN\t\t__declspec(noreturn)\n#define PJ_ATTR_NORETURN\t\n\n#define PJ_HAS_INT64\t1\n\ntypedef __int64 pj_int64_t;\ntypedef unsigned __int64 pj_uint64_t;\n\n#define PJ_INT64(val)\t\tval##i64\n#define PJ_UINT64(val)\t\tval##ui64\n#define PJ_INT64_FMT\t\t\"I64\"\n\n#define PJ_UNREACHED(x)\t    \t\n\n#define PJ_ALIGN_DATA(declaration, alignment) __declspec(align(alignment)) declaration\n\n\n#endif\t/* __PJ_COMPAT_CC_MSVC_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/cc_mwcc.h",
    "content": "/* $Id: cc_mwcc.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_CC_MWCC_H__\n#define __PJ_COMPAT_CC_MWCC_H__\n\n/**\n * @file cc_mwcc.h\n * @brief Describes MWCC compiler specifics.\n */\n\n#ifndef __CW32__\n#  error \"This file is only for mwcc!\"\n#endif\n\n#define PJ_CC_NAME\t\t\"mwcc32sym\"\n#define PJ_CC_VER_1\t\t1\n#define PJ_CC_VER_2\t\t0\n#define PJ_CC_VER_3\t\t0\n\n\n#define PJ_INLINE_SPECIFIER\tstatic inline\n#define PJ_THREAD_FUNC\t\n#define PJ_NORETURN\t\t\n#define PJ_ATTR_NORETURN\t__attribute__ ((noreturn))\n\n#define PJ_HAS_INT64\t\t1\n\ntypedef long long pj_int64_t;\ntypedef unsigned long long pj_uint64_t;\n\n#define PJ_INT64(val)\t\tval##LL\n#define PJ_UINT64(val)\t\tval##LLU\n#define PJ_INT64_FMT\t\t\"L\"\n\n#define PJ_UNREACHED(x)\t    \t\n\n#endif\t/* __PJ_COMPAT_CC_MWCC_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/ctype.h",
    "content": "/* $Id: ctype.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_CTYPE_H__\n#define __PJ_COMPAT_CTYPE_H__\n\n/**\n * @file ctype.h\n * @brief Provides ctype function family.\n */\n\n#if defined(PJ_HAS_CTYPE_H) && PJ_HAS_CTYPE_H != 0\n#  include <ctype.h>\n#else\n#  define isalnum(c)\t    (isalpha(c) || isdigit(c))\n#  define isalpha(c)\t    (islower(c) || isupper(c))\n#  define isascii(c)\t    (((unsigned char)(c))<=0x7f)\n#  define isdigit(c)\t    ((c)>='0' && (c)<='9')\n#  define isspace(c)\t    ((c)==' '  || (c)=='\\t' ||\\\n\t\t\t     (c)=='\\n' || (c)=='\\r' || (c)=='\\v')\n#  define islower(c)\t    ((c)>='a' && (c)<='z')\n#  define isupper(c)\t    ((c)>='A' && (c)<='Z')\n#  define isxdigit(c)\t    (isdigit(c) || (tolower(c)>='a'&&tolower(c)<='f'))\n#  define tolower(c)\t    (((c) >= 'A' && (c) <= 'Z') ? (c)+('a'-'A') : (c))\n#  define toupper(c)\t    (((c) >= 'a' && (c) <= 'z') ? (c)-('a'-'A') : (c))\n#endif\n\n#ifndef isblank\n#   define isblank(c)\t    (c==' ' || c=='\\t')\n#endif\n\n\n#endif\t/* __PJ_COMPAT_CTYPE_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/errno.h",
    "content": "/* $Id: errno.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_ERRNO_H__\n#define __PJ_COMPAT_ERRNO_H__\n\n#if defined(PJ_WIN32) && PJ_WIN32 != 0 || \\\n    defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE != 0 || \\\n    defined(PJ_WIN64) && PJ_WIN64 != 0\n\n    typedef unsigned long pj_os_err_type;\n#   define pj_get_native_os_error()\t    GetLastError()\n#   define pj_get_native_netos_error()\t    WSAGetLastError()\n\n#elif defined(PJ_HAS_ERRNO_VAR) && PJ_HAS_ERRNO_VAR!= 0\n\n    typedef int pj_os_err_type;\n#   define pj_get_native_os_error()\t    (errno)\n#   define pj_get_native_netos_error()\t    (errno)\n\n#else\n\n#   error \"Please define how to get errno for this platform here!\"\n\n#endif\n\n\n#endif\t/* __PJ_COMPAT_ERRNO_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/high_precision.h",
    "content": "/* $Id: high_precision.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_HIGH_PRECISION_H__\n#define __PJ_COMPAT_HIGH_PRECISION_H__\n\n\n#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT != 0\n    /*\n     * The first choice for high precision math is to use double.\n     */\n#   include <math.h>\n    typedef double pj_highprec_t;\n\n#   define PJ_HIGHPREC_VALUE_IS_ZERO(a)     (a==0)\n#   define pj_highprec_mod(a,b)             (a=fmod(a,b))\n\n#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL != 0\n\n#   include <asm/div64.h>\n    \n    typedef pj_int64_t pj_highprec_t;\n\n#   define pj_highprec_div(a1,a2)   do_div(a1,a2)\n#   define pj_highprec_mod(a1,a2)   (a1=do_mod(a1, a2))\n\n    PJ_INLINE(pj_int64_t) do_mod( pj_int64_t a1, pj_int64_t a2)\n    {\n\treturn do_div(a1,a2);\n    }\n    \n    \n#elif defined(PJ_HAS_INT64) && PJ_HAS_INT64 != 0\n    /*\n     * Next choice is to use 64-bit arithmatics.\n     */\n    typedef pj_int64_t pj_highprec_t;\n\n#else\n#   warning \"High precision math is not available\"\n\n    /*\n     * Last, fallback to 32-bit arithmetics.\n     */\n    typedef pj_int32_t pj_highprec_t;\n\n#endif\n\n/**\n * @def pj_highprec_mul\n * pj_highprec_mul(a1, a2) - High Precision Multiplication\n * Multiply a1 and a2, and store the result in a1.\n */\n#ifndef pj_highprec_mul\n#   define pj_highprec_mul(a1,a2)   (a1 = a1 * a2)\n#endif\n\n/**\n * @def pj_highprec_div\n * pj_highprec_div(a1, a2) - High Precision Division\n * Divide a2 from a1, and store the result in a1.\n */\n#ifndef pj_highprec_div\n#   define pj_highprec_div(a1,a2)   (a1 = a1 / a2)\n#endif\n\n/**\n * @def pj_highprec_mod\n * pj_highprec_mod(a1, a2) - High Precision Modulus\n * Get the modulus a2 from a1, and store the result in a1.\n */\n#ifndef pj_highprec_mod\n#   define pj_highprec_mod(a1,a2)   (a1 = a1 % a2)\n#endif\n\n\n/**\n * @def PJ_HIGHPREC_VALUE_IS_ZERO(a)\n * Test if the specified high precision value is zero.\n */\n#ifndef PJ_HIGHPREC_VALUE_IS_ZERO\n#   define PJ_HIGHPREC_VALUE_IS_ZERO(a)     (a==0)\n#endif\n\n\n#endif\t/* __PJ_COMPAT_HIGH_PRECISION_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/m_alpha.h",
    "content": "/* $Id: m_alpha.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_M_ALPHA_H__\n#define __PJ_COMPAT_M_ALPHA_H__\n\n/**\n * @file m_alpha.h\n * @brief Describes Alpha processor family specifics.\n */\n\n#define PJ_M_NAME\t\t\"alpha\"\n\n#define PJ_HAS_PENTIUM\t\t0\n#define PJ_IS_LITTLE_ENDIAN\t1\n#define PJ_IS_BIG_ENDIAN\t0\n\n\n#endif\t/* __PJ_COMPAT_M_ALPHA_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/m_armv4.h",
    "content": "/* $Id: m_armv4.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_M_ARMV4_H__\n#define __PJ_COMPAT_M_ARMV4_H__\n\n/**\n * @file m_armv4.h\n * @brief Describes ARM family processor specifics.\n */\n\n/*\n * This file covers PJ_M_ARMV4 etc.\n */\n\n#define PJ_M_NAME\t\t\"armv4\"\n\n#define PJ_HAS_PENTIUM\t\t0\n#define PJ_IS_LITTLE_ENDIAN\t1\n#define PJ_IS_BIG_ENDIAN\t0\n\n\n#endif\t/* __PJ_COMPAT_M_ARMV4_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/m_auto.h.in",
    "content": "/* $Id: m_auto.h.in 3295 2010-08-25 12:51:29Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_M_AUTO_H__\n#define __PJ_COMPAT_M_AUTO_H__\n\n/**\n * @file m_auto.h\n * @brief Automatically generated process definition file.\n */\n\n/* Machine name, filled in by autoconf script */\n#undef PJ_M_NAME\n\n/* Endianness. It's reported on pjsip list on 09/02/13 that autoconf\n * endianness detection failed for universal build, so special case\n * for it here. Thanks Ruud Klaver for the fix.\n */\n#ifdef PJ_DARWINOS\n#  ifdef __BIG_ENDIAN__\n#    define WORDS_BIGENDIAN\t1\n#  endif\n#else\n    /* Endianness, as detected by autoconf */\n#  undef WORDS_BIGENDIAN\n#endif\n\n#ifdef WORDS_BIGENDIAN\n#  define PJ_IS_LITTLE_ENDIAN\t0\n#  define PJ_IS_BIG_ENDIAN\t1\n#else\n#  define PJ_IS_LITTLE_ENDIAN\t1\n#  define PJ_IS_BIG_ENDIAN\t0\n#endif\n\n\n/* Specify if floating point is present/desired */\n#undef PJ_HAS_FLOATING_POINT\n\n/* Deprecated */\n#define PJ_HAS_PENTIUM\t\t0\n\n#endif\t/* __PJ_COMPAT_M_AUTO_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/m_i386.h",
    "content": "/* $Id: m_i386.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_M_i386_H__\n#define __PJ_COMPAT_M_i386_H__\n\n/**\n * @file m_i386.h\n * @brief Describes Intel i386 family processor specifics.\n */\n\n#define PJ_M_NAME\t\t\"i386\"\n\n#define PJ_HAS_PENTIUM\t\t1\n#define PJ_IS_LITTLE_ENDIAN\t1\n#define PJ_IS_BIG_ENDIAN\t0\n\n\n#endif\t/* __PJ_COMPAT_M_i386_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/m_m68k.h",
    "content": "/* $Id: m_m68k.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_M_M68K_H__\n#define __PJ_COMPAT_M_M68K_H__\n\n/**\n * @file m_m68k.h\n * @brief Describes Motorola m68k family processor specifics.\n */\n\n#define PJ_M_NAME\t\t\"m68k\"\n\n#define PJ_HAS_PENTIUM\t\t0\n#define PJ_IS_LITTLE_ENDIAN\t1\n#define PJ_IS_BIG_ENDIAN\t0\n\n\n#endif\t/* __PJ_COMPAT_M_M68K_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/m_powerpc.h",
    "content": "/* $Id: m_powerpc.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_M_POWERPC_H__\n#define __PJ_COMPAT_M_POWERPC_H__\n\n/**\n * @file m_ppc.h\n * @brief Describes PowerPC family processor specifics.\n */\n\n#define PJ_M_NAME\t\t\"powerpc\"\n\n#define PJ_HAS_PENTIUM\t\t0\n#define PJ_IS_LITTLE_ENDIAN\t0\n#define PJ_IS_BIG_ENDIAN\t1\n\n\n#endif\t/* __PJ_COMPAT_M_POWERPC_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/m_sparc.h",
    "content": "/* $Id: m_sparc.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_M_SPARC_H__\n#define __PJ_COMPAT_M_SPARC_H__\n\n/**\n * @file m_sparc.h\n * @brief Describes SPARC family processor specifics.\n */\n\n#define PJ_M_NAME\t\t\"sparc\"\n\n#define PJ_HAS_PENTIUM\t\t0\n#define PJ_IS_LITTLE_ENDIAN\t0\n#define PJ_IS_BIG_ENDIAN\t1\n\n\n#endif\t/* __PJ_COMPAT_M_SPARC_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/m_x86_64.h",
    "content": "/* $Id: m_x86_64.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_M_x86_64_H__\n#define __PJ_COMPAT_M_x86_64_H__\n\n/**\n * @file m_i386.h\n * @brief Describes 64bit x86 Intel/AMD family processor specifics.\n */\n\n#define PJ_M_NAME\t\t\"x86_64\"\n\n#define PJ_HAS_PENTIUM\t\t1\n#define PJ_IS_LITTLE_ENDIAN\t1\n#define PJ_IS_BIG_ENDIAN\t0\n\n\n#endif\t/* __PJ_COMPAT_M_x86_64_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/malloc.h",
    "content": "/* $Id: malloc.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_MALLOC_H__\n#define __PJ_COMPAT_MALLOC_H__\n\n/**\n * @file malloc.h\n * @brief Provides malloc() and free() functions.\n */\n\n#if defined(PJ_HAS_MALLOC_H) && PJ_HAS_MALLOC_H != 0\n#  include <malloc.h>\n#elif defined(PJ_HAS_STDLIB_H) && PJ_HAS_STDLIB_H != 0\n#  include <stdlib.h>\n#endif\n\n#endif\t/* __PJ_COMPAT_MALLOC_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/os_auto.h.in",
    "content": "/* $Id: os_auto.h.in 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_OS_AUTO_H__\n#define __PJ_COMPAT_OS_AUTO_H__\n\n/**\n * @file os_auto.h\n * @brief Describes operating system specifics (automatically detected by\n *        autoconf)\n */\n\n/* Canonical OS name */\n#undef PJ_OS_NAME\n\n/* Legacy macros */\n#undef PJ_WIN32\n#undef PJ_WIN32_WINNT\n#undef WIN32_LEAN_AND_MEAN\n#undef PJ_DARWINOS\n#undef PJ_LINUX\n#undef PJ_RTEMS\n#undef PJ_SUNOS\n\n#if defined(PJ_WIN32_WINNT) && !defined(_WIN32_WINNT)\n#  define _WIN32_WINNT\tPJ_WIN32_WINNT\n#endif\n\n/* Headers availability */\n#undef PJ_HAS_ARPA_INET_H\n#undef PJ_HAS_ASSERT_H\n#undef PJ_HAS_CTYPE_H\n#undef PJ_HAS_ERRNO_H\n#undef PJ_HAS_FCNTL_H\n#undef PJ_HAS_LIMITS_H\n#undef PJ_HAS_LINUX_SOCKET_H\n#undef PJ_HAS_MALLOC_H\n#undef PJ_HAS_NETDB_H\n#undef PJ_HAS_NETINET_IN_SYSTM_H\n#undef PJ_HAS_NETINET_IN_H\n#undef PJ_HAS_NETINET_IP_H\n#undef PJ_HAS_NETINET_TCP_H\n#undef PJ_HAS_NET_IF_H\n#undef PJ_HAS_IFADDRS_H\n#undef PJ_HAS_SEMAPHORE_H\n#undef PJ_HAS_SETJMP_H\n#undef PJ_HAS_STDARG_H\n#undef PJ_HAS_STDDEF_H\n#undef PJ_HAS_STDIO_H\n#undef PJ_HAS_STDINT_H\n#undef PJ_HAS_STDLIB_H\n#undef PJ_HAS_STRING_H\n#undef PJ_HAS_SYS_IOCTL_H\n#undef PJ_HAS_SYS_SELECT_H\n#undef PJ_HAS_SYS_SOCKET_H\n#undef PJ_HAS_SYS_TIME_H\n#undef PJ_HAS_SYS_TIMEB_H\n#undef PJ_HAS_SYS_TYPES_H\n#undef PJ_HAS_SYS_FILIO_H\n#undef PJ_HAS_SYS_SOCKIO_H\n#undef PJ_HAS_SYS_UTSNAME_H\n#undef PJ_HAS_TIME_H\n#undef PJ_HAS_UNISTD_H\n\n#undef PJ_HAS_MSWSOCK_H\n#undef PJ_HAS_WINSOCK_H\n#undef PJ_HAS_WINSOCK2_H\n#undef PJ_HAS_WS2TCPIP_H\n\n#undef PJ_SOCK_HAS_INET_ATON\n#undef PJ_SOCK_HAS_INET_PTON\n#undef PJ_SOCK_HAS_INET_NTOP\n#undef PJ_SOCK_HAS_GETADDRINFO\n\n/* On these OSes, semaphore feature depends on semaphore.h */\n#if defined(PJ_HAS_SEMAPHORE_H) && PJ_HAS_SEMAPHORE_H!=0\n#   define PJ_HAS_SEMAPHORE\t1\n#elif defined(PJ_WIN32) && PJ_WIN32!=0\n#   define PJ_HAS_SEMAPHORE\t1\n#else\n#   define PJ_HAS_SEMAPHORE\t0\n#endif\n\n/* Do we have pthread_mutexattr_settype()? */\n#undef PJ_HAS_PTHREAD_MUTEXATTR_SETTYPE\n\n/* Does pthread_mutexattr_t has \"recursive\" member?  */\n#undef PJ_PTHREAD_MUTEXATTR_T_HAS_RECURSIVE\n\n/* Set 1 if native sockaddr_in has sin_len member. \n * Default: 0\n */\n#undef PJ_SOCKADDR_HAS_LEN\n\n/* Does the OS have socklen_t? */\n#undef PJ_HAS_SOCKLEN_T\n\n#if !defined(socklen_t) && (!defined(PJ_HAS_SOCKLEN_T) || PJ_HAS_SOCKLEN_T==0)\n# define PJ_HAS_SOCKLEN_T  1\n  typedef int socklen_t;\n#endif\n\n/**\n * If this macro is set, it tells select I/O Queue that select() needs to\n * be given correct value of nfds (i.e. largest fd + 1). This requires\n * select ioqueue to re-scan the descriptors on each registration and\n * unregistration.\n * If this macro is not set, then ioqueue will always give FD_SETSIZE for\n * nfds argument when calling select().\n *\n * Default: 0\n */\n#undef PJ_SELECT_NEEDS_NFDS\n\n/* Was Linux epoll support enabled */\n#undef PJ_HAS_LINUX_EPOLL\n\n/* Is errno a good way to retrieve OS errors?\n */\n#undef PJ_HAS_ERRNO_VAR\n\n/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return\n * the status of non-blocking connect() operation.\n */\n#undef PJ_HAS_SO_ERROR\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket recv() can not return immediate daata.\n */\n#undef PJ_BLOCKING_ERROR_VAL\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket connect() can not get connected immediately.\n */\n#undef PJ_BLOCKING_CONNECT_ERROR_VAL\n\n/* Default threading is enabled, unless it's overridden. */\n#ifndef PJ_HAS_THREADS\n#  define PJ_HAS_THREADS\t    (1)\n#endif\n\n/* Do we need high resolution timer? */\n#undef PJ_HAS_HIGH_RES_TIMER\n\n/* Is malloc() available? */\n#undef PJ_HAS_MALLOC\n\n#ifndef PJ_OS_HAS_CHECK_STACK\n#   define PJ_OS_HAS_CHECK_STACK    0\n#endif\n\n/* Unicode? */\n#undef PJ_NATIVE_STRING_IS_UNICODE\n\n/* Pool alignment in bytes */\n#undef PJ_POOL_ALIGNMENT\n\n/* The type of atomic variable value: */\n#undef PJ_ATOMIC_VALUE_TYPE\n\n#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0\n#    include \"TargetConditionals.h\"\n#    if TARGET_OS_IPHONE\n#\tinclude \"Availability.h\"\n\t/* Use CFHost API for pj_getaddrinfo() (see ticket #1246) */\n#\tdefine PJ_GETADDRINFO_USE_CFHOST 1\n\t/* Disable local host resolution in pj_gethostip() (see ticket #1342) */\n#\tdefine PJ_GETHOSTIP_DISABLE_LOCAL_RESOLUTION 1\n#    \tifdef __IPHONE_4_0\n \t    /* Is multitasking support available?  (see ticket #1107) */\n#\t    define PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT \t1\n\t    /* Enable activesock TCP background mode support */\n#\t    define PJ_ACTIVESOCK_TCP_IPHONE_OS_BG\t\t1\n#\tendif\n#    endif\n#endif\n\n/* If 1, use Read/Write mutex emulation for platforms that don't support it */\n#undef PJ_EMULATE_RWMUTEX\n\n/* If 1, pj_thread_create() should enforce the stack size when creating \n * threads.\n * Default: 0 (let OS decide the thread's stack size).\n */\n#undef PJ_THREAD_SET_STACK_SIZE\n\n/* If 1, pj_thread_create() should allocate stack from the pool supplied.\n * Default: 0 (let OS allocate memory for thread's stack).\n */\n#undef PJ_THREAD_ALLOCATE_STACK\n\n/* SSL socket availability. */\n#ifndef PJ_HAS_SSL_SOCK\n#undef PJ_HAS_SSL_SOCK\n#endif\n\n\n#endif\t/* __PJ_COMPAT_OS_AUTO_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/os_darwinos.h",
    "content": "/* $Id: os_darwinos.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_OS_DARWINOS_H__\n#define __PJ_COMPAT_OS_DARWINOS_H__\n\n/**\n * @file os_darwinos.h\n * @brief Describes Darwin/MacOSX operating system specifics.\n */\n\n#define PJ_OS_NAME\t\t    \"darwin\"\n\n#define PJ_HAS_ARPA_INET_H\t    1\n#define PJ_HAS_ASSERT_H\t\t    1\n#define PJ_HAS_CTYPE_H\t\t    1\n#define PJ_HAS_ERRNO_H\t\t    1\n#define PJ_HAS_LINUX_SOCKET_H\t    0\n#define PJ_HAS_MALLOC_H\t\t    0\n#define PJ_HAS_NETDB_H\t\t    1\n#define PJ_HAS_NETINET_IN_H\t    1\n#define PJ_HAS_NETINET_TCP_H\t    1\n#define PJ_HAS_SETJMP_H\t\t    1\n#define PJ_HAS_STDARG_H\t\t    1\n#define PJ_HAS_STDDEF_H\t\t    1\n#define PJ_HAS_STDIO_H\t\t    1\n#define PJ_HAS_STDLIB_H\t\t    1\n#define PJ_HAS_STRING_H\t\t    1\n#define PJ_HAS_SYS_IOCTL_H\t    1\n#define PJ_HAS_SYS_SELECT_H\t    1\n#define PJ_HAS_SYS_SOCKET_H\t    1\n#define PJ_HAS_SYS_TIME_H\t    1\n#define PJ_HAS_SYS_TIMEB_H\t    1\n#define PJ_HAS_SYS_TYPES_H\t    1\n#define PJ_HAS_TIME_H\t\t    1\n#define PJ_HAS_UNISTD_H\t\t    1\n\n#define PJ_HAS_MSWSOCK_H\t    0\n#define PJ_HAS_WINSOCK_H\t    0\n#define PJ_HAS_WINSOCK2_H\t    0\n\n/* Is errno a good way to retrieve OS errors?\n */\n#define PJ_HAS_ERRNO_VAR\t    1\n\n/* Has inet_aton() ?\n */   \n#define PJ_SOCK_HAS_INET_ATON\t    1\n\n/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return\n * the status of non-blocking connect() operation.\n */\n#define PJ_HAS_SO_ERROR             1\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket recv() can not return immediate daata.\n */\n#define PJ_BLOCKING_ERROR_VAL       EWOULDBLOCK\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket connect() can not get connected immediately.\n */\n#define PJ_BLOCKING_CONNECT_ERROR_VAL   EINPROGRESS\n\n/* Default threading is enabled, unless it's overridden. */\n#ifndef PJ_HAS_THREADS\n#  define PJ_HAS_THREADS\t\t(1)\n#endif\n\n#define PJ_HAS_HIGH_RES_TIMER\t\t1\n#define PJ_HAS_MALLOC\t\t\t1\n#ifndef PJ_OS_HAS_CHECK_STACK\n#   define PJ_OS_HAS_CHECK_STACK        0\n#endif\n#define PJ_NATIVE_STRING_IS_UNICODE\t0\n\n#define PJ_ATOMIC_VALUE_TYPE\t\tlong\n\n/*\n * Socket related\n */\ntypedef int socklen_t;\n\n/* Set 1 if native sockaddr_in has sin_len member. \n * Default: 0\n */\n#define PJ_SOCKADDR_HAS_LEN\t\t1\n\n/*\n * gcc complains that it can not use precompiled header because\n * the value of FD_SETSIZE that we declare in pj/config.h is\n * different than the value in /usr/include/sys/types.h.\n *\n * This changes the default value for Darwin.\n */\n#define PJ_IOQUEUE_MAX_HANDLES\t\t1024\n\n/**\n * If this macro is set, it tells select I/O Queue that select() needs to\n * be given correct value of nfds (i.e. largest fd + 1). This requires\n * select ioqueue to re-scan the descriptors on each registration and\n * unregistration.\n * If this macro is not set, then ioqueue will always give FD_SETSIZE for\n * nfds argument when calling select().\n *\n * Default: 0\n */\n#define PJ_SELECT_NEEDS_NFDS\t\t0\n\n/* If 1, use Read/Write mutex emulation for platforms that don't support it */\n#define PJ_EMULATE_RWMUTEX\t\t0\n\n/* If 1, pj_thread_create() should enforce the stack size when creating \n * threads.\n * Default: 0 (let OS decide the thread's stack size).\n */\n#define PJ_THREAD_SET_STACK_SIZE    \t0\n\n/* If 1, pj_thread_create() should allocate stack from the pool supplied.\n * Default: 0 (let OS allocate memory for thread's stack).\n */\n#define PJ_THREAD_ALLOCATE_STACK    \t0\n\n/* Oh well.. MacOS 10.2 doesn't have socklen_t, but 10.4 has! */\n#define PJ_HAS_SOCKLEN_T\t\t0\n\n\n#endif\t/* __PJ_COMPAT_OS_DARWINOS_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/os_linux.h",
    "content": "/* $Id: os_linux.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_OS_LINUX_H__\n#define __PJ_COMPAT_OS_LINUX_H__\n\n/**\n * @file os_linux.h\n * @brief Describes Linux operating system specifics.\n */\n\n#define PJ_OS_NAME\t\t    \"linux\"\n\n#define PJ_HAS_ARPA_INET_H\t    1\n#define PJ_HAS_ASSERT_H\t\t    1\n#define PJ_HAS_CTYPE_H\t\t    1\n#define PJ_HAS_ERRNO_H\t\t    1\n#define PJ_HAS_LINUX_SOCKET_H\t    0\n#define PJ_HAS_MALLOC_H\t\t    1\n#define PJ_HAS_NETDB_H\t\t    1\n#define PJ_HAS_NETINET_IN_H\t    1\n#define PJ_HAS_SETJMP_H\t\t    1\n#define PJ_HAS_STDARG_H\t\t    1\n#define PJ_HAS_STDDEF_H\t\t    1\n#define PJ_HAS_STDIO_H\t\t    1\n#define PJ_HAS_STDLIB_H\t\t    1\n#define PJ_HAS_STRING_H\t\t    1\n#define PJ_HAS_SYS_IOCTL_H\t    1\n#define PJ_HAS_SYS_SELECT_H\t    1\n#define PJ_HAS_SYS_SOCKET_H\t    1\n#define PJ_HAS_SYS_TIME_H\t    1\n#define PJ_HAS_SYS_TIMEB_H\t    1\n#define PJ_HAS_SYS_TYPES_H\t    1\n#define PJ_HAS_TIME_H\t\t    1\n#define PJ_HAS_UNISTD_H\t\t    1\n#define PJ_HAS_SEMAPHORE_H\t    1\n\n#define PJ_HAS_MSWSOCK_H\t    0\n#define PJ_HAS_WINSOCK_H\t    0\n#define PJ_HAS_WINSOCK2_H\t    0\n\n#define PJ_SOCK_HAS_INET_ATON\t    1\n\n/* Set 1 if native sockaddr_in has sin_len member. \n * Default: 0\n */\n#define PJ_SOCKADDR_HAS_LEN\t    0\n\n/**\n * If this macro is set, it tells select I/O Queue that select() needs to\n * be given correct value of nfds (i.e. largest fd + 1). This requires\n * select ioqueue to re-scan the descriptors on each registration and\n * unregistration.\n * If this macro is not set, then ioqueue will always give FD_SETSIZE for\n * nfds argument when calling select().\n *\n * Default: 0\n */\n#define PJ_SELECT_NEEDS_NFDS\t    0\n\n/* Is errno a good way to retrieve OS errors?\n */\n#define PJ_HAS_ERRNO_VAR\t    1\n\n/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return\n * the status of non-blocking connect() operation.\n */\n#define PJ_HAS_SO_ERROR             1\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket recv() can not return immediate daata.\n */\n#define PJ_BLOCKING_ERROR_VAL       EAGAIN\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket connect() can not get connected immediately.\n */\n#define PJ_BLOCKING_CONNECT_ERROR_VAL   EINPROGRESS\n\n/* Default threading is enabled, unless it's overridden. */\n#ifndef PJ_HAS_THREADS\n#  define PJ_HAS_THREADS\t    (1)\n#endif\n\n#define PJ_HAS_HIGH_RES_TIMER\t    1\n#define PJ_HAS_MALLOC               1\n#ifndef PJ_OS_HAS_CHECK_STACK\n#   define PJ_OS_HAS_CHECK_STACK    0\n#endif\n#define PJ_NATIVE_STRING_IS_UNICODE 0\n\n#define PJ_ATOMIC_VALUE_TYPE\t    long\n\n/* If 1, use Read/Write mutex emulation for platforms that don't support it */\n#define PJ_EMULATE_RWMUTEX\t    0\n\n/* If 1, pj_thread_create() should enforce the stack size when creating \n * threads.\n * Default: 0 (let OS decide the thread's stack size).\n */\n#define PJ_THREAD_SET_STACK_SIZE    \t0\n\n/* If 1, pj_thread_create() should allocate stack from the pool supplied.\n * Default: 0 (let OS allocate memory for thread's stack).\n */\n#define PJ_THREAD_ALLOCATE_STACK    \t0\n\n/* Linux has socklen_t */\n#define PJ_HAS_SOCKLEN_T\t\t1\n\n\n#endif\t/* __PJ_COMPAT_OS_LINUX_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/os_linux_kernel.h",
    "content": "/* $Id: os_linux_kernel.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_OS_LINUX_KERNEL_H__\n#define __PJ_COMPAT_OS_LINUX_KERNEL_H__\n\n/**\n * @file os_linux.h\n * @brief Describes Linux operating system specifics.\n */\n\n#define PJ_OS_NAME\t\t    \"linux-module\"\n\n#define PJ_HAS_ARPA_INET_H\t    0\n#define PJ_HAS_ASSERT_H\t\t    0\n#define PJ_HAS_CTYPE_H\t\t    0\n#define PJ_HAS_ERRNO_H\t\t    0\n#define PJ_HAS_LINUX_SOCKET_H\t    1\n#define PJ_HAS_MALLOC_H\t\t    0\n#define PJ_HAS_NETDB_H\t\t    0\n#define PJ_HAS_NETINET_IN_H\t    0\n#define PJ_HAS_SETJMP_H\t\t    0\n#define PJ_HAS_STDARG_H\t\t    1\n#define PJ_HAS_STDDEF_H\t\t    0\n#define PJ_HAS_STDIO_H\t\t    0\n#define PJ_HAS_STDLIB_H\t\t    0\n#define PJ_HAS_STRING_H\t\t    0\n#define PJ_HAS_SYS_IOCTL_H\t    0\n#define PJ_HAS_SYS_SELECT_H\t    0\n#define PJ_HAS_SYS_SOCKET_H\t    0\n#define PJ_HAS_SYS_TIME_H\t    0\n#define PJ_HAS_SYS_TIMEB_H\t    0\n#define PJ_HAS_SYS_TYPES_H\t    0\n#define PJ_HAS_TIME_H\t\t    0\n#define PJ_HAS_UNISTD_H\t\t    0\n\n#define PJ_HAS_MSWSOCK_H\t    0\n#define PJ_HAS_WINSOCK_H\t    0\n#define PJ_HAS_WINSOCK2_H\t    0\n\n#define PJ_SOCK_HAS_INET_ATON\t    0\n\n/* Set 1 if native sockaddr_in has sin_len member. \n * Default: 0\n */\n#define PJ_SOCKADDR_HAS_LEN\t    0\n\n/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return\n * the status of non-blocking connect() operation.\n */\n#define PJ_HAS_SO_ERROR             1\n\n/**\n * If this macro is set, it tells select I/O Queue that select() needs to\n * be given correct value of nfds (i.e. largest fd + 1). This requires\n * select ioqueue to re-scan the descriptors on each registration and\n * unregistration.\n * If this macro is not set, then ioqueue will always give FD_SETSIZE for\n * nfds argument when calling select().\n *\n * Default: 0\n */\n#define PJ_SELECT_NEEDS_NFDS\t    0\n\n/* Is errno a good way to retrieve OS errors?\n * (probably no for linux kernel) \n * If you answer no here, you'll need to tell pjlib how to get OS\n * error (a compile error will tell you exactly where)\n */\n#define PJ_HAS_ERRNO_VAR\t    0\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket recv() can not return immediate daata.\n */\n#define PJ_BLOCKING_ERROR_VAL       EAGAIN\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket connect() can not get connected immediately.\n */\n#define PJ_BLOCKING_CONNECT_ERROR_VAL   EINPROGRESS\n\n#ifndef PJ_HAS_THREADS\n#  define PJ_HAS_THREADS\t    (1)\n#endif\n\n\n/*\n * Declare __FD_SETSIZE now before including <linux*>.\n */\n#define __FD_SETSIZE\t\t    PJ_IOQUEUE_MAX_HANDLES\n\n#define NULL\t\t\t    ((void*)0)\n\n#include <linux/module.h>\t/* Needed by all modules */\n#include <linux/kernel.h>\t/* Needed for KERN_INFO */\n\n#define __PJ_EXPORT_SYMBOL(a)\t    EXPORT_SYMBOL(a);\n\n/*\n * Override features.\n */\n#define PJ_HAS_FLOATING_POINT\t    0\n#define PJ_HAS_MALLOC               0\n#define PJ_HAS_SEMAPHORE\t    0\n#define PJ_HAS_EVENT_OBJ\t    0\n#define PJ_HAS_HIGH_RES_TIMER\t    1\n#ifndef PJ_OS_HAS_CHECK_STACK\n#   define PJ_OS_HAS_CHECK_STACK    0\n#endif\n#define PJ_TERM_HAS_COLOR\t    0\n#define PJ_NATIVE_STRING_IS_UNICODE 0\n\n#define PJ_ATOMIC_VALUE_TYPE\t    int\n#define PJ_THREAD_DESC_SIZE\t    128\n\n/* If 1, use Read/Write mutex emulation for platforms that don't support it */\n#define PJ_EMULATE_RWMUTEX\t    0\n\n/* If 1, pj_thread_create() should enforce the stack size when creating \n * threads.\n * Default: 0 (let OS decide the thread's stack size).\n */\n#define PJ_THREAD_SET_STACK_SIZE    \t0\n\n/* If 1, pj_thread_create() should allocate stack from the pool supplied.\n * Default: 0 (let OS allocate memory for thread's stack).\n */\n#define PJ_THREAD_ALLOCATE_STACK    \t0\n\n\n\n#endif\t/* __PJ_COMPAT_OS_LINUX_KERNEL_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/os_palmos.h",
    "content": "/* $Id: os_palmos.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_OS_PALMOS_H__\n#define __PJ_COMPAT_OS_PALMOS_H__\n\n/**\n * @file os_palmos.h\n * @brief Describes PalmOS operating system specifics.\n */\n\n#define PJ_OS_NAME\t\t    \"palmos\"\n\n#define PJ_HAS_ARPA_INET_H\t    0\n#define PJ_HAS_ASSERT_H\t\t    1\n#define PJ_HAS_CTYPE_H\t\t    1\n#define PJ_HAS_ERRNO_H\t\t    0\n#define PJ_HAS_MALLOC_H\t\t    1\n#define PJ_HAS_NETDB_H\t\t    0\n#define PJ_HAS_NETINET_IN_H\t    0\n#define PJ_HAS_SETJMP_H\t\t    1\n#define PJ_HAS_STDARG_H\t\t    1\n#define PJ_HAS_STDDEF_H\t\t    1\n#define PJ_HAS_STDIO_H\t\t    1\n#define PJ_HAS_STDLIB_H\t\t    1\n#define PJ_HAS_STRING_H\t\t    1\n#define PJ_HAS_SYS_IOCTL_H\t    0\n#define PJ_HAS_SYS_SELECT_H\t    0\n#define PJ_HAS_SYS_SOCKET_H\t    0\n#define PJ_HAS_SYS_TIMEB_H\t    0\n#define PJ_HAS_SYS_TYPES_H\t    1\n#define PJ_HAS_TIME_H\t\t    1\n#define PJ_HAS_UNISTD_H\t\t    0\n\n#define PJ_HAS_MSWSOCK_H\t    0\n#define PJ_HAS_WINSOCK_H\t    0\n#define PJ_HAS_WINSOCK2_H\t    0\n\n#define PJ_SOCK_HAS_INET_ATON\t    0\n\n/* Set 1 if native sockaddr_in has sin_len member. \n * Default: 0\n */\n#define PJ_SOCKADDR_HAS_LEN\t    0\n\n/**\n * If this macro is set, it tells select I/O Queue that select() needs to\n * be given correct value of nfds (i.e. largest fd + 1). This requires\n * select ioqueue to re-scan the descriptors on each registration and\n * unregistration.\n * If this macro is not set, then ioqueue will always give FD_SETSIZE for\n * nfds argument when calling select().\n *\n * Default: 0\n */\n#define PJ_SELECT_NEEDS_NFDS\t    0\n\n/* Is errno a good way to retrieve OS errors?\n */\n#define PJ_HAS_ERRNO_VAR\t    0\n\n/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return\n * the status of non-blocking connect() operation.\n */\n#define PJ_HAS_SO_ERROR             0\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket recv() can not return immediate daata.\n */\n#define PJ_BLOCKING_ERROR_VAL       xxx\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket connect() can not get connected immediately.\n */\n#define PJ_BLOCKING_CONNECT_ERROR_VAL   xxx\n\n/* Default threading is enabled, unless it's overridden. */\n#ifndef PJ_HAS_THREADS\n#  define PJ_HAS_THREADS\t\t(1)\n#endif\n\n#define PJ_HAS_HIGH_RES_TIMER\t\t1\n#ifndef PJ_OS_HAS_CHECK_STACK\n#   define PJ_OS_HAS_CHECK_STACK\t0\n#define PJ_NATIVE_STRING_IS_UNICODE\t0\n\n/* If 1, use Read/Write mutex emulation for platforms that don't support it */\n#define PJ_EMULATE_RWMUTEX\t\t1\n\n/* If 1, pj_thread_create() should enforce the stack size when creating \n * threads.\n * Default: 0 (let OS decide the thread's stack size).\n */\n#define PJ_THREAD_SET_STACK_SIZE    \t0\n\n/* If 1, pj_thread_create() should allocate stack from the pool supplied.\n * Default: 0 (let OS allocate memory for thread's stack).\n */\n#define PJ_THREAD_ALLOCATE_STACK    \t0\n\n\n#endif\t/* __PJ_COMPAT_OS_PALMOS_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/os_rtems.h",
    "content": "/* $Id: os_rtems.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * Thanks Zetron, Inc and Phil Torre <ptorre@zetron.com> for donating PJLIB\n * port to RTEMS.\n */\n\n#ifndef __PJ_COMPAT_OS_RTEMS_H__\n#define __PJ_COMPAT_OS_RTEMS_H__\n\n/**\n * @file os_linux.h\n * @brief Describes Linux operating system specifics.\n */\n\n#define PJ_OS_NAME\t\t    \"rtems\"\n\n#define PJ_HAS_ARPA_INET_H\t    1\n#define PJ_HAS_ASSERT_H\t\t    1\n#define PJ_HAS_CTYPE_H\t\t    1\n#define PJ_HAS_ERRNO_H\t\t    1\n#define PJ_HAS_LINUX_SOCKET_H\t    0\n#define PJ_HAS_MALLOC_H\t\t    1\n#define PJ_HAS_NETDB_H\t\t    1\n#define PJ_HAS_NETINET_IN_H\t    1\n#define PJ_HAS_SETJMP_H\t\t    1\n#define PJ_HAS_STDARG_H\t\t    0\n#define PJ_HAS_STDDEF_H\t\t    1\n#define PJ_HAS_STDIO_H\t\t    1\n#define PJ_HAS_STDLIB_H\t\t    1\n#define PJ_HAS_STRING_H\t\t    1\n#define PJ_HAS_SYS_IOCTL_H\t    1\n#define PJ_HAS_SYS_SELECT_H\t    1\n#define PJ_HAS_SYS_SOCKET_H\t    1\n#define PJ_HAS_SYS_TIME_H\t    1\n#define PJ_HAS_SYS_TIMEB_H\t    1\n#define PJ_HAS_SYS_TYPES_H\t    1\n#define PJ_HAS_TIME_H\t\t    1\n#define PJ_HAS_UNISTD_H\t\t    1\n\n#define PJ_HAS_MSWSOCK_H\t    0\n#define PJ_HAS_WINSOCK_H\t    0\n#define PJ_HAS_WINSOCK2_H\t    0\n\n#define PJ_SOCK_HAS_INET_ATON\t    1\n\n/* Set 1 if native sockaddr_in has sin_len member. \n * Default: 0\n */\n#define PJ_SOCKADDR_HAS_LEN\t    1\n\n/* Is errno a good way to retrieve OS errors?\n */\n#define PJ_HAS_ERRNO_VAR\t    1\n\n/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return\n * the status of non-blocking connect() operation.\n */\n#define PJ_HAS_SO_ERROR             1\n\n/**\n * If this macro is set, it tells select I/O Queue that select() needs to\n * be given correct value of nfds (i.e. largest fd + 1). This requires\n * select ioqueue to re-scan the descriptors on each registration and\n * unregistration.\n * If this macro is not set, then ioqueue will always give FD_SETSIZE for\n * nfds argument when calling select().\n *\n * Default: 0\n */\n#define PJ_SELECT_NEEDS_NFDS\t    1\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket recv() can not return immediate daata.\n */\n#define PJ_BLOCKING_ERROR_VAL       EWOULDBLOCK\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket connect() can not get connected immediately.\n */\n#define PJ_BLOCKING_CONNECT_ERROR_VAL   EINPROGRESS\n\n/* Default threading is enabled, unless it's overridden. */\n#ifndef PJ_HAS_THREADS\n#  define PJ_HAS_THREADS\t    (1)\n#endif\n\n#define PJ_HAS_HIGH_RES_TIMER\t    1\n#define PJ_HAS_MALLOC               1\n#ifndef PJ_OS_HAS_CHECK_STACK\n#   define PJ_OS_HAS_CHECK_STACK    0\n#endif\n#define PJ_NATIVE_STRING_IS_UNICODE 0\n\n#define PJ_ATOMIC_VALUE_TYPE\t    int\n\n/* If 1, use Read/Write mutex emulation for platforms that don't support it */\n#define PJ_EMULATE_RWMUTEX\t    1\n\n/* Missing socklen_t */\ntypedef int socklen_t;\n\n/* If 1, pj_thread_create() should enforce the stack size when creating \n * threads.\n * Default: 0 (let OS decide the thread's stack size).\n */\n#define PJ_THREAD_SET_STACK_SIZE    1\n\n/* If 1, pj_thread_create() should allocate stack from the pool supplied.\n * Default: 0 (let OS allocate memory for thread's stack).\n */\n#define PJ_THREAD_ALLOCATE_STACK    1\n\n/* RTEMS has socklen_t (does it? )*/\n#define PJ_HAS_SOCKLEN_T\t    1\n\n\n\n\n#endif\t/* __PJ_COMPAT_OS_RTEMS_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/os_sunos.h",
    "content": "/* $Id: os_sunos.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_OS_SUNOS_H__\n#define __PJ_COMPAT_OS_SUNOS_H__\n\n/**\n * @file os_sunos.h\n * @brief Describes SunOS/Solaris operating system specifics.\n */\n\n#define PJ_OS_NAME\t\t    \"sunos\"\n\n#define PJ_HAS_ARPA_INET_H\t    1\n#define PJ_HAS_ASSERT_H\t\t    1\n#define PJ_HAS_CTYPE_H\t\t    1\n#define PJ_HAS_ERRNO_H\t\t    1\n#define PJ_HAS_LINUX_SOCKET_H\t    0\n#define PJ_HAS_MALLOC_H\t\t    1\n#define PJ_HAS_NETDB_H\t\t    1\n#define PJ_HAS_NETINET_IN_H\t    1\n#define PJ_HAS_SETJMP_H\t\t    1\n#define PJ_HAS_STDARG_H\t\t    1\n#define PJ_HAS_STDDEF_H\t\t    1\n#define PJ_HAS_STDIO_H\t\t    1\n#define PJ_HAS_STDLIB_H\t\t    1\n#define PJ_HAS_STRING_H\t\t    1\n#define PJ_HAS_SYS_IOCTL_H\t    1\n#define PJ_HAS_SYS_SELECT_H\t    1\n#define PJ_HAS_SYS_SOCKET_H\t    1\n#define PJ_HAS_SYS_TIME_H\t    0\n#define PJ_HAS_SYS_TIMEB_H\t    1\n#define PJ_HAS_SYS_TYPES_H\t    1\n#define PJ_HAS_TIME_H\t\t    1\n#define PJ_HAS_UNISTD_H\t\t    1\n\n#define PJ_HAS_MSWSOCK_H\t    0\n#define PJ_HAS_WINSOCK_H\t    0\n#define PJ_HAS_WINSOCK2_H\t    0\n\n#define PJ_SOCK_HAS_INET_ATON\t    0\n\n/* Set 1 if native sockaddr_in has sin_len member. \n * Default: 0\n */\n#define PJ_SOCKADDR_HAS_LEN\t    0\n\n/* Is errno a good way to retrieve OS errors?\n */\n#define PJ_HAS_ERRNO_VAR\t    1\n\n/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return\n * the status of non-blocking connect() operation.\n */\n#define PJ_HAS_SO_ERROR             0\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket recv() can not return immediate daata.\n */\n#define PJ_BLOCKING_ERROR_VAL       EWOULDBLOCK\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket connect() can not get connected immediately.\n */\n#define PJ_BLOCKING_CONNECT_ERROR_VAL   EINPROGRESS\n\n/**\n * If this macro is set, it tells select I/O Queue that select() needs to\n * be given correct value of nfds (i.e. largest fd + 1). This requires\n * select ioqueue to re-scan the descriptors on each registration and\n * unregistration.\n * If this macro is not set, then ioqueue will always give FD_SETSIZE for\n * nfds argument when calling select().\n *\n * Default: 0\n */\n#define PJ_SELECT_NEEDS_NFDS\t\t0\n\n/* Default threading is enabled, unless it's overridden. */\n#ifndef PJ_HAS_THREADS\n#  define PJ_HAS_THREADS\t\t(1)\n#endif\n\n#define PJ_HAS_HIGH_RES_TIMER\t\t1\n#define PJ_HAS_MALLOC\t\t\t1\n#ifndef PJ_OS_HAS_CHECK_STACK\n#   define PJ_OS_HAS_CHECK_STACK        0\n#endif\n#define PJ_NATIVE_STRING_IS_UNICODE\t0\n\n#define PJ_ATOMIC_VALUE_TYPE\t\tlong\n\n/* Get BSD related identifers in Sun's include files */\n#define BSD_COMP\n\n/* If 1, use Read/Write mutex emulation for platforms that don't support it */\n#define PJ_EMULATE_RWMUTEX\t\t0\n\n/* If 1, pj_thread_create() should enforce the stack size when creating \n * threads.\n * Default: 0 (let OS decide the thread's stack size).\n */\n#define PJ_THREAD_SET_STACK_SIZE    \t0\n\n/* If 1, pj_thread_create() should allocate stack from the pool supplied.\n * Default: 0 (let OS allocate memory for thread's stack).\n */\n#define PJ_THREAD_ALLOCATE_STACK    \t0\n\n/* SunOS has socklen_t (does it? )*/\n#define PJ_HAS_SOCKLEN_T\t    1\n\n\n\n#endif\t/* __PJ_COMPAT_OS_SUNOS_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/os_symbian.h",
    "content": "/* $Id: os_symbian.h 3841 2011-10-24 09:28:13Z ming $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef __PJ_COMPAT_OS_SYMBIAN_H__\n#define __PJ_COMPAT_OS_SYMBIAN_H__\n\n/**\n * @file os_symbian.h\n * @brief Describes Symbian operating system specifics.\n */\n\n#define PJ_OS_NAME\t\t    \"symbian\"\n\n#define PJ_HAS_ARPA_INET_H\t    1\n#define PJ_HAS_ASSERT_H\t\t    1\n#define PJ_HAS_CTYPE_H\t\t    1\n#define PJ_HAS_ERRNO_H\t\t    1\n#define PJ_HAS_LINUX_SOCKET_H\t    0\n#define PJ_HAS_MALLOC_H\t\t    0\n#define PJ_HAS_NETDB_H\t\t    1\n#define PJ_HAS_NETINET_IN_H\t    1\n#define PJ_HAS_NETINET_TCP_H\t    0\n#define PJ_HAS_SETJMP_H\t\t    1\n#define PJ_HAS_STDARG_H\t\t    1\n#define PJ_HAS_STDDEF_H\t\t    1\n#define PJ_HAS_STDIO_H\t\t    1\n#define PJ_HAS_STDLIB_H\t\t    1\n#define PJ_HAS_STRING_H\t\t    1\n#define PJ_HAS_NO_SNPRINTF\t    1\n#define PJ_HAS_SYS_IOCTL_H\t    1\n#define PJ_HAS_SYS_SELECT_H\t    0\n#define PJ_HAS_SYS_SOCKET_H\t    1\n#define PJ_HAS_SYS_TIME_H\t    1\n#define PJ_HAS_SYS_TIMEB_H\t    0\n#define PJ_HAS_SYS_TYPES_H\t    1\n#define PJ_HAS_TIME_H\t\t    1\n#define PJ_HAS_UNISTD_H\t\t    1\n\n#define PJ_HAS_MSWSOCK_H\t    0\n#define PJ_HAS_WINSOCK_H\t    0\n#define PJ_HAS_WINSOCK2_H\t    0\n\n#define PJ_SOCK_HAS_INET_ATON\t    0\n\n/* Set 1 if native sockaddr_in has sin_len member.\n * Default: 0\n */\n#define PJ_SOCKADDR_HAS_LEN\t    0\n/* Is errno a good way to retrieve OS errors?\n */\n#define PJ_HAS_ERRNO_VAR\t    1\n\n/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return\n * the status of non-blocking connect() operation.\n */\n#define PJ_HAS_SO_ERROR             1\n\n/**\n * If this macro is set, it tells select I/O Queue that select() needs to\n * be given correct value of nfds (i.e. largest fd + 1). This requires\n * select ioqueue to re-scan the descriptors on each registration and\n * unregistration.\n * If this macro is not set, then ioqueue will always give FD_SETSIZE for\n * nfds argument when calling select().\n *\n * Default: 0\n */\n#define PJ_SELECT_NEEDS_NFDS\t    0\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket recv() can not return immediate daata.\n */\n#define PJ_BLOCKING_ERROR_VAL       EAGAIN\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket connect() can not get connected immediately.\n */\n#define PJ_BLOCKING_CONNECT_ERROR_VAL   EINPROGRESS\n\n/*\n * We don't want to use threads in Symbian\n */\n#define PJ_HAS_THREADS\t\t    0\n\n\n/*\n * Declare __FD_SETSIZE now before including <linux*>.\n#define __FD_SETSIZE\t\t    PJ_IOQUEUE_MAX_HANDLES\n */\n\n#ifndef NULL\n#   define NULL 0\n#endif\n\n/* Endianness */\n#ifndef PJ_IS_LITTLE_ENDIAN\n#   define PJ_IS_LITTLE_ENDIAN\t1\n#   define PJ_IS_BIG_ENDIAN\t0\n#endif\n\n/* Doesn't seem to allow more than this */\n#define PJ_IOQUEUE_MAX_HANDLES\t    8\n\n/*\n * Override features.\n */\n#define PJ_HAS_FLOATING_POINT\t    0\n#define PJ_HAS_MALLOC               0\n#define PJ_HAS_SEMAPHORE\t    1\n#define PJ_HAS_EVENT_OBJ\t    0\n#define PJ_HAS_HIGH_RES_TIMER\t    1\n#define PJ_OS_HAS_CHECK_STACK       0\n#define PJ_TERM_HAS_COLOR\t    0\n#define PJ_NATIVE_STRING_IS_UNICODE 0\n#define PJ_NATIVE_ERR_POSITIVE\t    0\n\n#define PJ_ATOMIC_VALUE_TYPE\t    int\n#define PJ_THREAD_DESC_SIZE\t    128\n\n/* If 1, use Read/Write mutex emulation for platforms that don't support it */\n#define PJ_EMULATE_RWMUTEX\t    1\n\n/* If 1, pj_thread_create() should enforce the stack size when creating\n * threads.\n * Default: 0 (let OS decide the thread's stack size).\n */\n#define PJ_THREAD_SET_STACK_SIZE    \t0\n\n/* If 1, pj_thread_create() should allocate stack from the pool supplied.\n * Default: 0 (let OS allocate memory for thread's stack).\n */\n#define PJ_THREAD_ALLOCATE_STACK    \t0\n\n/* Missing socklen_t */\n#define PJ_HAS_SOCKLEN_T\t\t1\ntypedef unsigned int socklen_t;\n\n#ifndef __GCCE__\n#include <e32def.h>\n#endif\n\n#define PJ_EXPORT_DECL_SPECIFIER\tIMPORT_C\n//#define PJ_EXPORT_DECL_SPECIFIER\n#define PJ_EXPORT_DEF_SPECIFIER\t\tEXPORT_C\n#define PJ_IMPORT_DECL_SPECIFIER\tIMPORT_C\n\n\n#endif\t/* __PJ_COMPAT_OS_SYMBIAN_H__ */\n\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/os_win32.h",
    "content": "/* $Id: os_win32.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_OS_WIN32_H__\n#define __PJ_COMPAT_OS_WIN32_H__\n\n/**\n * @file os_win32.h\n * @brief Describes Win32 operating system family specifics.\n */\n\n#define PJ_OS_NAME\t\t    \"win32\"\n\n#define WIN32_LEAN_AND_MEAN\n#define PJ_WIN32_WINNT\t\t    0x0400\n#ifndef _WIN32_WINNT\n#  define _WIN32_WINNT\t\t    PJ_WIN32_WINNT\n#endif\n\n#define PJ_HAS_ARPA_INET_H\t    0\n#define PJ_HAS_ASSERT_H\t\t    1\n#define PJ_HAS_CTYPE_H\t\t    1\n#define PJ_HAS_ERRNO_H\t\t    0   /* Must be zero, otherwise errno_test() fails. */\n#define PJ_HAS_LINUX_SOCKET_H\t    0\n#define PJ_HAS_MALLOC_H\t\t    1\n#define PJ_HAS_NETDB_H\t\t    0\n#define PJ_HAS_NETINET_IN_H\t    0\n#define PJ_HAS_NETINET_TCP_H\t    0\n#define PJ_HAS_SETJMP_H\t\t    1\n#define PJ_HAS_STDARG_H\t\t    1\n#define PJ_HAS_STDDEF_H\t\t    1\n#undef  PJ_HAS_STDINT_H\n#define PJ_HAS_STDIO_H\t\t    1\n#define PJ_HAS_STDLIB_H\t\t    1\n#define PJ_HAS_STRING_H\t\t    1\n#define PJ_HAS_SYS_IOCTL_H\t    0\n#define PJ_HAS_SYS_SELECT_H\t    0\n#define PJ_HAS_SYS_SOCKET_H\t    0\n#define PJ_HAS_SYS_TIME_H\t    0\n#define PJ_HAS_SYS_TIMEB_H\t    1\n#define PJ_HAS_SYS_TYPES_H\t    1\n#define PJ_HAS_TIME_H\t\t    1\n#define PJ_HAS_UNISTD_H\t\t    0\n\n#define PJ_HAS_MSWSOCK_H\t    1\n#define PJ_HAS_WINSOCK_H\t    0\n#define PJ_HAS_WINSOCK2_H\t    1\n#define PJ_HAS_WS2TCPIP_H\t    1\n\n#define PJ_SOCK_HAS_INET_ATON\t    0\n\n/* Set 1 if native sockaddr_in has sin_len member. \n * Default: 0\n */\n#define PJ_SOCKADDR_HAS_LEN\t    0\n\n/* Is errno a good way to retrieve OS errors? (No)\n */\n#define PJ_HAS_ERRNO_VAR\t    0\n\n/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return\n * the status of non-blocking connect() operation.\n */\n#define PJ_HAS_SO_ERROR             1\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket recv() or send() can not return immediately.\n */\n#define PJ_BLOCKING_ERROR_VAL       WSAEWOULDBLOCK\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket connect() can not get connected immediately.\n */\n#define PJ_BLOCKING_CONNECT_ERROR_VAL   WSAEWOULDBLOCK\n\n/**\n * If this macro is set, it tells select I/O Queue that select() needs to\n * be given correct value of nfds (i.e. largest fd + 1). This requires\n * select ioqueue to re-scan the descriptors on each registration and\n * unregistration.\n * If this macro is not set, then ioqueue will always give FD_SETSIZE for\n * nfds argument when calling select().\n *\n * Default: 0\n */\n#define PJ_SELECT_NEEDS_NFDS\t\t0\n\n/* Default threading is enabled, unless it's overridden. */\n#ifndef PJ_HAS_THREADS\n#  define PJ_HAS_THREADS\t\t(1)\n#endif\n\n#define PJ_HAS_HIGH_RES_TIMER\t\t1\n#define PJ_HAS_MALLOC\t\t\t1\n#ifndef PJ_OS_HAS_CHECK_STACK\n#   define PJ_OS_HAS_CHECK_STACK\t1\n#endif\n\n#ifdef UNICODE\n#   define PJ_NATIVE_STRING_IS_UNICODE    1\n#else\n#   define PJ_NATIVE_STRING_IS_UNICODE    0\n#endif\n\n#define PJ_ATOMIC_VALUE_TYPE\t\tlong\n\n/* If 1, use Read/Write mutex emulation for platforms that don't support it */\n#define PJ_EMULATE_RWMUTEX\t\t1\n\n/* If 1, pj_thread_create() should enforce the stack size when creating \n * threads.\n * Default: 0 (let OS decide the thread's stack size).\n */\n#define PJ_THREAD_SET_STACK_SIZE    \t0\n\n/* If 1, pj_thread_create() should allocate stack from the pool supplied.\n * Default: 0 (let OS allocate memory for thread's stack).\n */\n#define PJ_THREAD_ALLOCATE_STACK    \t0\n\n\n#endif\t/* __PJ_COMPAT_OS_WIN32_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/os_win32_wince.h",
    "content": "/* $Id: os_win32_wince.h 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_OS_WIN32_WINCE_H__\n#define __PJ_COMPAT_OS_WIN32_WINCE_H__\n\n/**\n * @file os_win32.h\n * @brief Describes Win32 operating system family specifics.\n */\n\n#define PJ_OS_NAME\t\t    \"win32-wince\"\n\n#define WIN32_LEAN_AND_MEAN\n#define RPC_NO_WINDOWS_H\n//#define PJ_WIN32_WINNT\t\t    0x0400\n//#define _WIN32_WINNT\t\t    PJ_WIN32_WINNT\n\n#define PJ_HAS_ARPA_INET_H\t    0\n#define PJ_HAS_ASSERT_H\t\t    1\n#define PJ_HAS_CTYPE_H\t\t    1\n#define PJ_HAS_ERRNO_H\t\t    0   /* Must be zero, otherwise errno_test() fails. */\n#define PJ_HAS_LINUX_SOCKET_H\t    0\n#define PJ_HAS_MALLOC_H\t\t    1\n#define PJ_HAS_NETDB_H\t\t    0\n#define PJ_HAS_NETINET_IN_H\t    0\n#define PJ_HAS_NETINET_TCP_H\t    0\n#define PJ_HAS_SETJMP_H\t\t    1\n#define PJ_HAS_STDARG_H\t\t    1\n#define PJ_HAS_STDDEF_H\t\t    1\n#define PJ_HAS_STDIO_H\t\t    1\n#define PJ_HAS_STDLIB_H\t\t    1\n#define PJ_HAS_STRING_H\t\t    1\n#define PJ_HAS_SYS_IOCTL_H\t    0\n#define PJ_HAS_SYS_SELECT_H\t    0\n#define PJ_HAS_SYS_SOCKET_H\t    0\n#define PJ_HAS_SYS_TIME_H\t    0\n#define PJ_HAS_SYS_TIMEB_H\t    0\t/* Doesn't have sys/timeb.h */\n#define PJ_HAS_SYS_TYPES_H\t    0\t/* Doesn't have sys/types.h */\n#define PJ_HAS_TIME_H\t\t    1\n#define PJ_HAS_UNISTD_H\t\t    0\n\n#define PJ_HAS_MSWSOCK_H\t    1\n#define PJ_HAS_WINSOCK_H\t    0\n#define PJ_HAS_WINSOCK2_H\t    1\n\n#define PJ_SOCK_HAS_INET_ATON\t    0\n\n/* Set 1 if native sockaddr_in has sin_len member. \n * Default: 0\n */\n#define PJ_SOCKADDR_HAS_LEN\t    0\n\n/* Is errno a good way to retrieve OS errors? (no)\n */\n#define PJ_HAS_ERRNO_VAR\t    0\n\n/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return\n * the status of non-blocking connect() operation.\n */\n#define PJ_HAS_SO_ERROR             0\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket recv() or send() can not return immediately.\n */\n#define PJ_BLOCKING_ERROR_VAL       WSAEWOULDBLOCK\n\n/* This value specifies the value set in errno by the OS when a non-blocking\n * socket connect() can not get connected immediately.\n */\n#define PJ_BLOCKING_CONNECT_ERROR_VAL   WSAEWOULDBLOCK\n\n/**\n * If this macro is set, it tells select I/O Queue that select() needs to\n * be given correct value of nfds (i.e. largest fd + 1). This requires\n * select ioqueue to re-scan the descriptors on each registration and\n * unregistration.\n * If this macro is not set, then ioqueue will always give FD_SETSIZE for\n * nfds argument when calling select().\n *\n * Default: 0\n */\n#define PJ_SELECT_NEEDS_NFDS\t    0\n\n/* Endianness */\n#ifndef PJ_IS_LITTLE_ENDIAN\n#   define PJ_IS_LITTLE_ENDIAN\t1\n#   define PJ_IS_BIG_ENDIAN\t0\n#endif\n\n/* Default threading is enabled, unless it's overridden. */\n#ifndef PJ_HAS_THREADS\n#  define PJ_HAS_THREADS\t    (1)\n#endif\n\n#define PJ_HAS_HIGH_RES_TIMER\t    1\n#define PJ_HAS_MALLOC               1\n#define PJ_OS_HAS_CHECK_STACK\t    1\n\n#define PJ_ATOMIC_VALUE_TYPE\t    long\n\n/* TlsAlloc() error value. */\n#define TLS_OUT_OF_INDEXES\t    0xFFFFFFFF \n\n/* No console. */\n#define PJ_TERM_HAS_COLOR\t    0\n\n/* No rdtsc */\n#define PJ_TIMESTAMP_USE_RDTSC\t    0\n\n/* Native string is Unicode. */\n#define PJ_NATIVE_STRING_IS_UNICODE 1\n\n/* If 1, use Read/Write mutex emulation for platforms that don't support it */\n#define PJ_EMULATE_RWMUTEX\t    1\n\n/* If 1, pj_thread_create() should enforce the stack size when creating \n * threads.\n * Default: 0 (let OS decide the thread's stack size).\n */\n#define PJ_THREAD_SET_STACK_SIZE    \t0\n\n/* If 1, pj_thread_create() should allocate stack from the pool supplied.\n * Default: 0 (let OS allocate memory for thread's stack).\n */\n#define PJ_THREAD_ALLOCATE_STACK    \t0\n\n\n#endif\t/* __PJ_COMPAT_OS_WIN32_WINCE_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/rand.h",
    "content": "/* $Id: rand.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_RAND_H__\n#define __PJ_COMPAT_RAND_H__\n\n/**\n * @file rand.h\n * @brief Provides platform_rand() and platform_srand() functions.\n */\n\n#if defined(PJ_HAS_STDLIB_H) && PJ_HAS_STDLIB_H != 0\n   /*\n    * Use stdlib based rand() and srand().\n    */\n#  include <stdlib.h>\n#  define platform_srand    srand\n#  if defined(RAND_MAX) && RAND_MAX <= 0xFFFF\n       /*\n        * When rand() is only 16 bit strong, double the strength\n\t* by calling it twice!\n\t*/\n       PJ_INLINE(int) platform_rand(void)\n       {\n\t   return ((rand() & 0xFFFF) << 16) | (rand() & 0xFFFF);\n       }\n#  else\n#      define platform_rand rand\n#  endif\n\n#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL != 0\n   /*\n    * Linux kernel mode random number generator.\n    */\n#  include <linux/random.h>\n#  define platform_srand(seed)\n\n   PJ_INLINE(int) platform_rand(void)\n   {\n     int value;\n     get_random_bytes((void*)&value, sizeof(value));\n     return value;\n   }\n\n#else\n#  warning \"platform_rand() is not implemented\"\n#  define platform_rand()\t1\n#  define platform_srand(seed)\n\n#endif\n\n\n#endif\t/* __PJ_COMPAT_RAND_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/setjmp.h",
    "content": "/* $Id: setjmp.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_SETJMP_H__\n#define __PJ_COMPAT_SETJMP_H__\n\n/**\n * @file setjmp.h\n * @brief Provides setjmp.h functionality.\n */\n\n#if defined(PJ_HAS_SETJMP_H) && PJ_HAS_SETJMP_H != 0\n#  include <setjmp.h>\n   typedef jmp_buf pj_jmp_buf;\n#  ifndef pj_setjmp\n#    define pj_setjmp(buf)\tsetjmp(buf)\n#  endif\n#  ifndef pj_longjmp\n#    define pj_longjmp(buf,d)\tlongjmp(buf,d)\n#  endif\n\n#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL != 0 && \\\n      defined(PJ_M_I386) && PJ_M_I386 != 0\n\n    /*\n     * These are taken from uClibc.\n     * Copyright (C) 2000-2003 Erik Andersen <andersen@uclibc.org>\n     */\n#   if defined __USE_MISC || defined _ASM\n#\tdefine JB_BX\t0\n#\tdefine JB_SI\t1\n#\tdefine JB_DI\t2\n#\tdefine JB_BP\t3\n#\tdefine JB_SP\t4\n#\tdefine JB_PC\t5\n#\tdefine JB_SIZE 24\n#   endif\n\n# ifndef _ASM\n\ttypedef int __jmp_buf[6];\n\n    /* A `sigset_t' has a bit for each signal.  */\n#   define _SIGSET_NWORDS\t(1024 / (8 * sizeof (unsigned long int)))\n    typedef struct __sigset_t_tag\n    {\n\tunsigned long int __val[_SIGSET_NWORDS];\n    } __sigset_t;\n\n    /* Calling environment, plus possibly a saved signal mask.  */\n    typedef struct __jmp_buf_tag    /* C++ doesn't like tagless structs.  */\n    {\n\t/* NOTE: The machine-dependent definitions of `__sigsetjmp'\n\t   assume that a `jmp_buf' begins with a `__jmp_buf' and that\n\t   `__mask_was_saved' follows it.  Do not move these members\n\t   or add others before it.  */\n\t__jmp_buf __jmpbuf;\t\t/* Calling environment.  */\n\tint __mask_was_saved;\t\t/* Saved the signal mask?  */\n\t// we never saved the mask.\n\t__sigset_t __saved_mask;\t/* Saved signal mask.  */\n    } jmp_buf[1];\n\n    typedef jmp_buf sigjmp_buf;\n    typedef jmp_buf pj_jmp_buf;\n\n    PJ_DECL(int) pj_setjmp(pj_jmp_buf env);\n    PJ_DECL(void) pj_longjmp(pj_jmp_buf env, int val) __attribute__((noreturn));\n\n# endif   /* _ASM */\n\n#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0\n    /* Symbian framework don't use setjmp/longjmp */\n    \n#else\n#  warning \"setjmp()/longjmp() is not implemented\"\n   typedef int pj_jmp_buf[1];\n#  define pj_setjmp(buf)\t0\n#  define pj_longjmp(buf,d)\t0\n#endif\n\n\n#endif\t/* __PJ_COMPAT_SETJMP_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/size_t.h",
    "content": "/* $Id: size_t.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_SIZE_T_H__\n#define __PJ_COMPAT_SIZE_T_H__\n\n/**\n * @file size_t.h\n * @brief Provides size_t type.\n */\n#if PJ_HAS_STDDEF_H\n# include <stddef.h>\n#endif\n\n#endif\t/* __PJ_COMPAT_SIZE_T_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/socket.h",
    "content": "/* $Id: socket.h 4435 2013-03-11 06:32:58Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_SOCKET_H__\n#define __PJ_COMPAT_SOCKET_H__\n\n/**\n * @file socket.h\n * @brief Provides all socket related functions,data types, error codes, etc.\n */\n\n#if defined(PJ_HAS_WINSOCK2_H) && PJ_HAS_WINSOCK2_H != 0\n#  include <winsock2.h>\n#endif\n\n#if defined(PJ_HAS_WINSOCK_H) && PJ_HAS_WINSOCK_H != 0\n#  include <winsock.h>\n#endif\n\n#if defined(PJ_HAS_WS2TCPIP_H) && PJ_HAS_WS2TCPIP_H != 0\n#   include <ws2tcpip.h>\n#endif\n\n\n/*\n * IPv6 for Visual Studio's\n *\n * = Visual Studio 6 =\n *\n * Visual Studio 6 does not ship with IPv6 support, so you MUST\n * download and install IPv6 Tehnology Preview (IPv6Kit) from:\n *    http://msdn.microsoft.com/downloads/sdks/platform/tpipv6/ReadMe.asp\n * Then put IPv6Kit\\inc in your Visual Studio include path.\n * \n * In addition, by default IPv6Kit does not want to install on\n * Windows 2000 SP4. Please see:\n *    http://msdn.microsoft.com/downloads/sdks/platform/tpipv6/faq.asp\n * on  how to install IPv6Kit on Win2K SP4.\n *\n *\n * = Visual Studio 2003, 2005 (including Express) =\n *\n * These VS uses Microsoft Platform SDK for Windows Server 2003 SP1, and\n * it has built-in IPv6 support.\n */\n#if defined(_MSC_VER) && defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0\n#   ifndef s_addr\n#\tdefine s_addr  S_un.S_addr\n#   endif\n\n#   if !defined(IPPROTO_IPV6)\n\t/* Need to download and install IPv6Kit for this platform.\n\t * Please see the comments above about Visual Studio 6.\n\t */\n#\tinclude <tpipv6.h>\n#   endif\n\n#   define PJ_SOCK_HAS_GETADDRINFO  1\n#endif\t/* _MSC_VER */\n\n#if defined(PJ_HAS_SYS_TYPES_H) && PJ_HAS_SYS_TYPES_H != 0\n#  include <sys/types.h>\n#endif\n\n#if defined(PJ_HAS_SYS_SOCKET_H) && PJ_HAS_SYS_SOCKET_H != 0\n#  include <sys/socket.h>\n#endif\n\n#if defined(PJ_HAS_LINUX_SOCKET_H) && PJ_HAS_LINUX_SOCKET_H != 0\n#  include <linux/socket.h>\n#endif\n\n#if defined(PJ_HAS_SYS_SELECT_H) && PJ_HAS_SYS_SELECT_H != 0\n#  include <sys/select.h>\n#endif\n\n#if defined(PJ_HAS_NETINET_IN_H) && PJ_HAS_NETINET_IN_H != 0\n#  include <netinet/in.h>\n#endif\n\n#if defined(PJ_HAS_NETINET_IN_SYSTM_H) && PJ_HAS_NETINET_IN_SYSTM_H != 0\n/* Required to include netinet/ip.h in FreeBSD 7.0 */\n#  include <netinet/in_systm.h>\n#endif\n\n#if defined(PJ_HAS_NETINET_IP_H) && PJ_HAS_NETINET_IP_H != 0\n/* To pull in IPTOS_* constants */\n#  include <netinet/ip.h>\n#endif\n\n#if defined(PJ_HAS_NETINET_TCP_H) && PJ_HAS_NETINET_TCP_H != 0\n/* To pull in TCP_NODELAY constants */\n#  include <netinet/tcp.h>\n#endif\n\n#if defined(PJ_HAS_NET_IF_H) && PJ_HAS_NET_IF_H != 0\n/* For interface enumeration in ip_helper */\n#   include <net/if.h>\n#endif\n\n#if defined(PJ_HAS_IFADDRS_H) && PJ_HAS_IFADDRS_H != 0\n/* Interface enum with getifaddrs() which works with IPv6 */\n#   include <ifaddrs.h>\n#endif\n\n#if defined(PJ_HAS_ARPA_INET_H) && PJ_HAS_ARPA_INET_H != 0\n#  include <arpa/inet.h>\n#endif\n\n#if defined(PJ_HAS_SYS_IOCTL_H) && PJ_HAS_SYS_IOCTL_H != 0\n#  include <sys/ioctl.h>\t/* FBIONBIO */\n#endif\n\n#if defined(PJ_HAS_ERRNO_H) && PJ_HAS_ERRNO_H != 0\n#  include <errno.h>\n#endif\n\n#if defined(PJ_HAS_NETDB_H) && PJ_HAS_NETDB_H != 0\n#  include <netdb.h>\n#endif\n\n#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H != 0\n#  include <unistd.h>\n#endif\n\n#if defined(PJ_HAS_SYS_FILIO_H) && PJ_HAS_SYS_FILIO_H != 0\n#   include <sys/filio.h>\n#endif\n\n#if defined(PJ_HAS_SYS_SOCKIO_H) && PJ_HAS_SYS_SOCKIO_H != 0\n#   include <sys/sockio.h>\n#endif\n\n\n/*\n * Define common errors.\n */\n#if (defined(PJ_WIN32) && PJ_WIN32!=0) || \\\n    (defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0) || \\\n    (defined(PJ_WIN64) && PJ_WIN64!=0)\n#  define OSERR_EWOULDBLOCK    WSAEWOULDBLOCK\n#  define OSERR_EINPROGRESS    WSAEINPROGRESS\n#  define OSERR_ECONNRESET     WSAECONNRESET\n#  define OSERR_ENOTCONN       WSAENOTCONN\n#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0\n#  define OSERR_EWOULDBLOCK    -1\n#  define OSERR_EINPROGRESS    -1\n#  define OSERR_ECONNRESET     -1\n#  define OSERR_ENOTCONN       -1\n#else\n#  define OSERR_EWOULDBLOCK    EWOULDBLOCK\n#  define OSERR_EINPROGRESS    EINPROGRESS\n#  define OSERR_ECONNRESET     ECONNRESET\n#  define OSERR_ENOTCONN       ENOTCONN\n#endif\n\n\n/*\n * And undefine these..\n */\n#undef s_addr\n#undef s6_addr\n#undef sin_zero\n\n/*\n * Linux kernel specifics\n */\n#if defined(PJ_LINUX_KERNEL)\n#   include <linux/net.h>\n#   include <asm/ioctls.h>\t\t/* FIONBIO\t*/\n#   include <linux/syscalls.h>\t/* sys_select() */\n#   include <asm/uaccess.h>\t/* set/get_fs()\t*/\n\n    typedef int socklen_t;\n#   define getsockopt  sys_getsockopt\n\n    /*\n     * Wrapper for select() in Linux kernel.\n     */\n    PJ_INLINE(int) select(int n, fd_set *inp, fd_set *outp, fd_set *exp,\n\t\t          struct timeval *tvp)\n    {\n        int count;\n        mm_segment_t oldfs = get_fs();\n        set_fs(KERNEL_DS);\n        count = sys_select(n, inp, outp, exp, tvp);\n        set_fs(oldfs);\n        return count;\n    }\n#endif\t/* PJ_LINUX_KERNEL */\n\n\n/*\n * This will finally be obsoleted, since it should be declared in\n * os_auto.h\n */\n#if !defined(PJ_HAS_SOCKLEN_T) || PJ_HAS_SOCKLEN_T==0\n    typedef int socklen_t;\n#endif\n\n/* Regarding sin_len member of sockaddr_in:\n *  BSD systems (including MacOS X requires that the sin_len member of \n *  sockaddr_in be set to sizeof(sockaddr_in), while other systems (Windows\n *  and Linux included) do not.\n *\n *  To maintain compatibility between systems, PJLIB will automatically\n *  set this field before invoking native OS socket API, and it will\n *  always reset the field to zero before returning pj_sockaddr_in to\n *  application (such as in pj_getsockname() and pj_recvfrom()).\n *\n *  Application MUST always set this field to zero.\n *\n *  This way we can avoid hard to find problem such as when the socket \n *  address is used as hash table key.\n */\n#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0\n#   define PJ_SOCKADDR_SET_LEN(addr,len) (((pj_addr_hdr*)(addr))->sa_zero_len=(len))\n#   define PJ_SOCKADDR_RESET_LEN(addr)   (((pj_addr_hdr*)(addr))->sa_zero_len=0)\n#else\n#   define PJ_SOCKADDR_SET_LEN(addr,len) \n#   define PJ_SOCKADDR_RESET_LEN(addr)\n#endif\n\n#endif\t/* __PJ_COMPAT_SOCKET_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/stdarg.h",
    "content": "/* $Id: stdarg.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_STDARG_H__\n#define __PJ_COMPAT_STDARG_H__\n\n/**\n * @file stdarg.h\n * @brief Provides stdarg functionality.\n */\n\n#if defined(PJ_HAS_STDARG_H) && PJ_HAS_STDARG_H != 0\n#  include <stdarg.h>\n#endif\n\n#endif\t/* __PJ_COMPAT_STDARG_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/stdfileio.h",
    "content": "/* $Id: stdfileio.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_STDFILEIO_H__\n#define __PJ_COMPAT_STDFILEIO_H__\n\n/**\n * @file stdfileio.h\n * @brief Compatibility for ANSI file I/O like fputs, fflush, etc.\n */\n\n#if defined(PJ_HAS_STDIO_H) && PJ_HAS_STDIO_H != 0\n#  include <stdio.h>\n#endif\n\n#endif\t/* __PJ_COMPAT_STDFILEIO_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/string.h",
    "content": "/* $Id: string.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_STRING_H__\n#define __PJ_COMPAT_STRING_H__\n\n/**\n * @file string.h\n * @brief Provides string manipulation functions found in ANSI string.h.\n */\n\n\n#if defined(PJ_HAS_STRING_H) && PJ_HAS_STRING_H != 0\n#   include <string.h>\n#else\n\n    PJ_DECL(int) strcasecmp(const char *s1, const char *s2);\n    PJ_DECL(int) strncasecmp(const char *s1, const char *s2, int len);\n\n#endif\n\n/* For sprintf family */\n#include <stdio.h>\n\n/* On WinCE, string stuffs are declared in stdlib.h */\n#if defined(PJ_HAS_STDLIB_H) && PJ_HAS_STDLIB_H!=0\n#   include <stdlib.h>\n#endif\n\n#if defined(_MSC_VER)\n#   define strcasecmp\t_stricmp\n#   define strncasecmp\t_strnicmp\n#   define snprintf\t_snprintf\n#   define vsnprintf\t_vsnprintf\n#   define snwprintf\t_snwprintf\n#   define wcsicmp\t_wcsicmp\n#   define wcsnicmp\t_wcsnicmp\n#else\n#   define stricmp\tstrcasecmp\n#   define strnicmp\tstrncasecmp\n\n#   if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0\n#\terror \"Implement Unicode string functions\"\n#   endif\n#endif\n\n#define pj_ansi_strcmp\t\tstrcmp\n#define pj_ansi_strncmp\t\tstrncmp\n#define pj_ansi_strlen\t\tstrlen\n#define pj_ansi_strcpy\t\tstrcpy\n#define pj_ansi_strncpy\t\tstrncpy\n#define pj_ansi_strcat\t\tstrcat\n#define pj_ansi_strstr\t\tstrstr\n#define pj_ansi_strchr\t\tstrchr\n#define pj_ansi_strcasecmp\tstrcasecmp\n#define pj_ansi_stricmp\t\tstrcasecmp\n#define pj_ansi_strncasecmp\tstrncasecmp\n#define pj_ansi_strnicmp\tstrncasecmp\n#define pj_ansi_sprintf\t\tsprintf\n\n#if defined(PJ_HAS_NO_SNPRINTF) && PJ_HAS_NO_SNPRINTF != 0\n#   include <pj/types.h>\n#   include <pj/compat/stdarg.h>\n    PJ_BEGIN_DECL\n    PJ_DECL(int) snprintf(char*s1, pj_size_t len, const char*s2, ...);\n    PJ_DECL(int) vsnprintf(char*s1, pj_size_t len, const char*s2, va_list arg);\n    PJ_END_DECL\n#endif\n    \n#define pj_ansi_snprintf\tsnprintf\n#define pj_ansi_vsprintf\tvsprintf\n#define pj_ansi_vsnprintf\tvsnprintf\n\n#define pj_unicode_strcmp\twcscmp\n#define pj_unicode_strncmp\twcsncmp\n#define pj_unicode_strlen\twcslen\n#define pj_unicode_strcpy\twcscpy\n#define\tpj_unicode_strncpy\twcsncpy\n#define pj_unicode_strcat\twcscat\n#define pj_unicode_strstr\twcsstr\n#define pj_unicode_strchr\twcschr\n#define pj_unicode_strcasecmp\twcsicmp\n#define pj_unicode_stricmp\twcsicmp\n#define pj_unicode_strncasecmp\twcsnicmp\n#define pj_unicode_strnicmp\twcsnicmp\n#define pj_unicode_sprintf\tswprintf\n#define pj_unicode_snprintf\tsnwprintf\n#define pj_unicode_vsprintf\tvswprintf\n#define pj_unicode_vsnprintf\tvsnwprintf\n\n#if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0\n#   define pj_native_strcmp\t    pj_unicode_strcmp\n#   define pj_native_strncmp\t    pj_unicode_strncmp\n#   define pj_native_strlen\t    pj_unicode_strlen\n#   define pj_native_strcpy\t    pj_unicode_strcpy\n#   define pj_native_strncpy\t    pj_unicode_strncpy\n#   define pj_native_strcat\t    pj_unicode_strcat\n#   define pj_native_strstr\t    pj_unicode_strstr\n#   define pj_native_strchr\t    pj_unicode_strchr\n#   define pj_native_strcasecmp\t    pj_unicode_strcasecmp\n#   define pj_native_stricmp\t    pj_unicode_stricmp\n#   define pj_native_strncasecmp    pj_unicode_strncasecmp\n#   define pj_native_strnicmp\t    pj_unicode_strnicmp\n#   define pj_native_sprintf\t    pj_unicode_sprintf\n#   define pj_native_snprintf\t    pj_unicode_snprintf\n#   define pj_native_vsprintf\t    pj_unicode_vsprintf\n#   define pj_native_vsnprintf\t    pj_unicode_vsnprintf\n#else\n#   define pj_native_strcmp\t    pj_ansi_strcmp\n#   define pj_native_strncmp\t    pj_ansi_strncmp\n#   define pj_native_strlen\t    pj_ansi_strlen\n#   define pj_native_strcpy\t    pj_ansi_strcpy\n#   define pj_native_strncpy\t    pj_ansi_strncpy\n#   define pj_native_strcat\t    pj_ansi_strcat\n#   define pj_native_strstr\t    pj_ansi_strstr\n#   define pj_native_strchr\t    pj_ansi_strchr\n#   define pj_native_strcasecmp\t    pj_ansi_strcasecmp\n#   define pj_native_stricmp\t    pj_ansi_stricmp\n#   define pj_native_strncasecmp    pj_ansi_strncasecmp\n#   define pj_native_strnicmp\t    pj_ansi_strnicmp\n#   define pj_native_sprintf\t    pj_ansi_sprintf\n#   define pj_native_snprintf\t    pj_ansi_snprintf\n#   define pj_native_vsprintf\t    pj_ansi_vsprintf\n#   define pj_native_vsnprintf\t    pj_ansi_vsnprintf\n#endif\n\n\n#endif\t/* __PJ_COMPAT_STRING_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/compat/time.h",
    "content": "/* $Id: time.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_COMPAT_TIME_H__\n#define __PJ_COMPAT_TIME_H__\n\n/**\n * @file time.h\n * @brief Provides ftime() and localtime() etc functions.\n */\n\n#if defined(PJ_HAS_TIME_H) && PJ_HAS_TIME_H != 0\n#  include <time.h>\n#endif\n\n#if defined(PJ_HAS_SYS_TIME_H) && PJ_HAS_SYS_TIME_H != 0\n#  include <sys/time.h>\n#endif\n\n#if defined(PJ_HAS_SYS_TIMEB_H) && PJ_HAS_SYS_TIMEB_H != 0\n#  include <sys/timeb.h>\n#endif\n\n\n#endif\t/* __PJ_COMPAT_TIME_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/config.h",
    "content": "/* $Id: config.h 4419 2013-03-05 11:23:52Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_CONFIG_H__\n#define __PJ_CONFIG_H__\n\n\n/**\n * @file config.h\n * @brief PJLIB Main configuration settings.\n */\n\n/********************************************************************\n * Include compiler specific configuration.\n */\n#if defined(_MSC_VER)\n#  include <pj/compat/cc_msvc.h>\n#elif defined(__GNUC__)\n#  include <pj/compat/cc_gcc.h>\n#elif defined(__CW32__)\n#  include <pj/compat/cc_mwcc.h>\n#elif defined(__MWERKS__)\n#  include <pj/compat/cc_codew.h>\n#elif defined(__GCCE__)\n#  include <pj/compat/cc_gcce.h>\n#elif defined(__ARMCC__)\n#  include <pj/compat/cc_armcc.h>\n#else\n#  error \"Unknown compiler.\"\n#endif\n\n/* PJ_ALIGN_DATA is compiler specific directive to align data address */\n#ifndef PJ_ALIGN_DATA\n#  error \"PJ_ALIGN_DATA is not defined!\"\n#endif\n\n/********************************************************************\n * Include target OS specific configuration.\n */\n#if defined(PJ_AUTOCONF)\n    /*\n     * Autoconf\n     */\n#   include <pj/compat/os_auto.h>\n\n#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0\n    /*\n     * SymbianOS\n     */\n#  include <pj/compat/os_symbian.h>\n\n#elif defined(PJ_WIN32_WINCE) || defined(_WIN32_WCE) || defined(UNDER_CE)\n    /*\n     * Windows CE\n     */\n#   undef PJ_WIN32_WINCE\n#   define PJ_WIN32_WINCE   1\n#   include <pj/compat/os_win32_wince.h>\n\n    /* Also define Win32 */\n#   define PJ_WIN32 1\n\n#elif defined(PJ_WIN32) || defined(_WIN32) || defined(__WIN32__) || \\\n\tdefined(WIN32) || defined(PJ_WIN64) || defined(_WIN64) || \\\n\tdefined(WIN64) || defined(__TOS_WIN__) \n#   if defined(PJ_WIN64) || defined(_WIN64) || defined(WIN64)\n\t/*\n\t * Win64\n\t */\n#\tundef PJ_WIN64\n#\tdefine PJ_WIN64 1\n#   endif\n#   undef PJ_WIN32\n#   define PJ_WIN32 1\n#   include <pj/compat/os_win32.h>\n\n#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL!=0\n    /*\n     * Linux kernel\n     */\n#  include <pj/compat/os_linux_kernel.h>\n\n#elif defined(PJ_LINUX) || defined(linux) || defined(__linux)\n    /*\n     * Linux\n     */\n#   undef PJ_LINUX\n#   define PJ_LINUX\t    1\n#   include <pj/compat/os_linux.h>\n\n#elif defined(PJ_PALMOS) && PJ_PALMOS!=0\n    /*\n     * Palm\n     */\n#  include <pj/compat/os_palmos.h>\n\n#elif defined(PJ_SUNOS) || defined(sun) || defined(__sun)\n    /*\n     * SunOS\n     */\n#   undef PJ_SUNOS\n#   define PJ_SUNOS\t    1\n#   include <pj/compat/os_sunos.h>\n\n#elif defined(PJ_DARWINOS) || defined(__MACOSX__) || \\\n      defined (__APPLE__) || defined (__MACH__)\n    /*\n     * MacOS X\n     */\n#   undef PJ_DARWINOS\n#   define PJ_DARWINOS\t    1\n#   include <pj/compat/os_darwinos.h>\n\n#elif defined(PJ_RTEMS) && PJ_RTEMS!=0\n    /*\n     * RTEMS\n     */\n#  include <pj/compat/os_rtems.h>\n#else\n#   error \"Please specify target os.\"\n#endif\n\n\n/********************************************************************\n * Target machine specific configuration.\n */\n#if defined(PJ_AUTOCONF)\n    /*\n     * Autoconf configured\n     */\n#include <pj/compat/m_auto.h>\n\n#elif defined (PJ_M_I386) || defined(_i386_) || defined(i_386_) || \\\n\tdefined(_X86_) || defined(x86) || defined(__i386__) || \\\n\tdefined(__i386) || defined(_M_IX86) || defined(__I86__)\n    /*\n     * Generic i386 processor family, little-endian\n     */\n#   undef PJ_M_I386\n#   define PJ_M_I386\t\t1\n#   define PJ_M_NAME\t\t\"i386\"\n#   define PJ_HAS_PENTIUM\t1\n#   define PJ_IS_LITTLE_ENDIAN\t1\n#   define PJ_IS_BIG_ENDIAN\t0\n\n\n#elif defined (PJ_M_X86_64) || defined(__amd64__) || defined(__amd64) || \\\n\tdefined(__x86_64__) || defined(__x86_64) || \\\n\tdefined(_M_X64) || defined(_M_AMD64)\n    /*\n     * AMD 64bit processor, little endian\n     */\n#   undef PJ_M_X86_64\n#   define PJ_M_X86_64\t\t1\n#   define PJ_M_NAME\t\t\"x86_64\"\n#   define PJ_HAS_PENTIUM\t1\n#   define PJ_IS_LITTLE_ENDIAN\t1\n#   define PJ_IS_BIG_ENDIAN\t0\n\n#elif defined(PJ_M_IA64) || defined(__ia64__) || defined(_IA64) || \\\n\tdefined(__IA64__) || defined( \t_M_IA64)\n    /*\n     * Intel IA64 processor, default to little endian\n     */\n#   undef PJ_M_IA64\n#   define PJ_M_IA64\t\t1\n#   define PJ_M_NAME\t\t\"ia64\"\n#   define PJ_HAS_PENTIUM\t1\n#   define PJ_IS_LITTLE_ENDIAN\t1\n#   define PJ_IS_BIG_ENDIAN\t0\n\n#elif defined (PJ_M_M68K) && PJ_M_M68K != 0\n\n    /*\n     * Motorola m68k processor, big endian\n     */\n#   undef PJ_M_M68K\n#   define PJ_M_M68K\t\t1\n#   define PJ_M_NAME\t\t\"m68k\"\n#   define PJ_HAS_PENTIUM\t0\n#   define PJ_IS_LITTLE_ENDIAN\t0\n#   define PJ_IS_BIG_ENDIAN\t1\n\n\n#elif defined (PJ_M_ALPHA) || defined (__alpha__) || defined (__alpha) || \\\n\tdefined (_M_ALPHA)\n    /*\n     * DEC Alpha processor, little endian\n     */\n#   undef PJ_M_ALPHA\n#   define PJ_M_ALPHA\t\t1\n#   define PJ_M_NAME\t\t\"alpha\"\n#   define PJ_HAS_PENTIUM\t0\n#   define PJ_IS_LITTLE_ENDIAN\t1\n#   define PJ_IS_BIG_ENDIAN\t0\n\n\n#elif defined(PJ_M_MIPS) || defined(__mips__) || defined(__mips) || \\\n\tdefined(__MIPS__) || defined(MIPS) || defined(_MIPS_)\n    /*\n     * MIPS, bi-endian, so raise error if endianness is not configured\n     */\n#   undef PJ_M_MIPS\n#   define PJ_M_MIPS\t\t1\n#   define PJ_M_NAME\t\t\"mips\"\n#   define PJ_HAS_PENTIUM\t0\n#   if !PJ_IS_LITTLE_ENDIAN && !PJ_IS_BIG_ENDIAN\n#   \terror Endianness must be declared for this processor\n#   endif\n\n\n#elif defined (PJ_M_SPARC) || defined( \t__sparc__) || defined(__sparc)\n    /*\n     * Sun Sparc, big endian\n     */\n#   undef PJ_M_SPARC\n#   define PJ_M_SPARC\t\t1\n#   define PJ_M_NAME\t\t\"sparc\"\n#   define PJ_HAS_PENTIUM\t0\n#   define PJ_IS_LITTLE_ENDIAN\t0\n#   define PJ_IS_BIG_ENDIAN\t1\n\n#elif defined (PJ_M_ARMV4) || defined(ARM) || defined(_ARM_) ||  \\\n\tdefined(ARMV4) || defined(__arm__)\n    /*\n     * ARM, bi-endian, so raise error if endianness is not configured\n     */\n#   undef PJ_M_ARMV4\n#   define PJ_M_ARMV4\t\t1\n#   define PJ_M_NAME\t\t\"armv4\"\n#   define PJ_HAS_PENTIUM\t0\n#   if !PJ_IS_LITTLE_ENDIAN && !PJ_IS_BIG_ENDIAN\n#   \terror Endianness must be declared for this processor\n#   endif\n\n#elif defined (PJ_M_POWERPC) || defined(__powerpc) || defined(__powerpc__) || \\\n\tdefined(__POWERPC__) || defined(__ppc__) || defined(_M_PPC) || \\\n\tdefined(_ARCH_PPC)\n    /*\n     * PowerPC, bi-endian, so raise error if endianness is not configured\n     */\n#   undef PJ_M_POWERPC\n#   define PJ_M_POWERPC\t\t1\n#   define PJ_M_NAME\t\t\"powerpc\"\n#   define PJ_HAS_PENTIUM\t0\n#   if !PJ_IS_LITTLE_ENDIAN && !PJ_IS_BIG_ENDIAN\n#   \terror Endianness must be declared for this processor\n#   endif\n\n#elif defined (PJ_M_NIOS2) || defined(__nios2) || defined(__nios2__) || \\\n      defined(__NIOS2__) || defined(__M_NIOS2) || defined(_ARCH_NIOS2)\n    /*\n     * Nios2, little endian\n     */\n#   undef PJ_M_NIOS2\n#   define PJ_M_NIOS2\t\t1\n#   define PJ_M_NAME\t\t\"nios2\"\n#   define PJ_HAS_PENTIUM\t0\n#   define PJ_IS_LITTLE_ENDIAN\t1\n#   define PJ_IS_BIG_ENDIAN\t0\n\t\t\n#else\n#   error \"Please specify target machine.\"\n#endif\n\n/* Include size_t definition. */\n#include <pj/compat/size_t.h>\n\n/* Include site/user specific configuration to control PJLIB features.\n * YOU MUST CREATE THIS FILE YOURSELF!!\n */\n#include <pj/config_site.h>\n\n/********************************************************************\n * PJLIB Features.\n */\n\n/* Overrides for DOXYGEN */\n#ifdef DOXYGEN\n#   undef PJ_FUNCTIONS_ARE_INLINED\n#   undef PJ_HAS_FLOATING_POINT\n#   undef PJ_LOG_MAX_LEVEL\n#   undef PJ_LOG_MAX_SIZE\n#   undef PJ_LOG_USE_STACK_BUFFER\n#   undef PJ_TERM_HAS_COLOR\n#   undef PJ_POOL_DEBUG\n#   undef PJ_HAS_TCP\n#   undef PJ_MAX_HOSTNAME\n#   undef PJ_IOQUEUE_MAX_HANDLES\n#   undef FD_SETSIZE\n#   undef PJ_HAS_SEMAPHORE\n#   undef PJ_HAS_EVENT_OBJ\n#   undef PJ_ENABLE_EXTRA_CHECK\n#   undef PJ_EXCEPTION_USE_WIN32_SEH\n#   undef PJ_HAS_ERROR_STRING\n\n#   define PJ_HAS_IPV6\t1\n#endif\n\n/**\n * @defgroup pj_config Build Configuration\n * @{\n *\n * This section contains macros that can set during PJLIB build process\n * to controll various aspects of the library.\n *\n * <b>Note</b>: the values in this page does NOT necessarily reflect to the\n * macro values during the build process.\n */\n\n/**\n * If this macro is set to 1, it will enable some debugging checking\n * in the library.\n *\n * Default: equal to (NOT NDEBUG).\n */\n#ifndef PJ_DEBUG\n#  ifndef NDEBUG\n#    define PJ_DEBUG\t\t    1\n#  else\n#    define PJ_DEBUG\t\t    0\n#  endif\n#endif\n\n/**\n * Enable this macro to activate logging to mutex/semaphore related events.\n * This is useful to troubleshoot concurrency problems such as deadlocks.\n * In addition, you should also add PJ_LOG_HAS_THREAD_ID flag to the\n * log decoration to assist the troubleshooting.\n *\n * Default: 0\n */\n#ifndef PJ_DEBUG_MUTEX\n#   define PJ_DEBUG_MUTEX\t    0\n#endif\n\n/**\n * Expand functions in *_i.h header files as inline.\n *\n * Default: 0.\n */\n#ifndef PJ_FUNCTIONS_ARE_INLINED\n#  define PJ_FUNCTIONS_ARE_INLINED  0\n#endif\n\n/**\n * Use floating point computations in the library.\n *\n * Default: 1.\n */\n#ifndef PJ_HAS_FLOATING_POINT\n#  define PJ_HAS_FLOATING_POINT\t    1\n#endif\n\n/**\n * Declare maximum logging level/verbosity. Lower number indicates higher\n * importance, with the highest importance has level zero. The least\n * important level is five in this implementation, but this can be extended\n * by supplying the appropriate implementation.\n *\n * The level conventions:\n *  - 0: fatal error\n *  - 1: error\n *  - 2: warning\n *  - 3: info\n *  - 4: debug\n *  - 5: trace\n *  - 6: more detailed trace\n *\n * Default: 4\n */\n#ifndef PJ_LOG_MAX_LEVEL\n#  define PJ_LOG_MAX_LEVEL   5\n#endif\n\n/**\n * Maximum message size that can be sent to output device for each call\n * to PJ_LOG(). If the message size is longer than this value, it will be cut.\n * This may affect the stack usage, depending whether PJ_LOG_USE_STACK_BUFFER\n * flag is set.\n *\n * Default: 4000\n */\n#ifndef PJ_LOG_MAX_SIZE\n#  define PJ_LOG_MAX_SIZE\t    4000\n#endif\n\n/**\n * Log buffer.\n * Does the log get the buffer from the stack? (default is yes).\n * If the value is set to NO, then the buffer will be taken from static\n * buffer, which in this case will make the log function non-reentrant.\n *\n * Default: 1\n */\n#ifndef PJ_LOG_USE_STACK_BUFFER\n#  define PJ_LOG_USE_STACK_BUFFER   1\n#endif\n\n/**\n * Enable log indentation feature.\n *\n * Default: 1\n */\n#ifndef PJ_LOG_ENABLE_INDENT\n#   define PJ_LOG_ENABLE_INDENT        1\n#endif\n\n/**\n * Number of PJ_LOG_INDENT_CHAR to put every time pj_log_push_indent()\n * is called.\n *\n * Default: 1\n */\n#ifndef PJ_LOG_INDENT_SIZE\n#   define PJ_LOG_INDENT_SIZE        1\n#endif\n\n/**\n * Log indentation character.\n *\n * Default: space\n */\n#ifndef PJ_LOG_INDENT_CHAR\n#   define PJ_LOG_INDENT_CHAR\t    '.'\n#endif\n\n/**\n * Colorfull terminal (for logging etc).\n *\n * Default: 1\n */\n#ifndef PJ_TERM_HAS_COLOR\n#  define PJ_TERM_HAS_COLOR\t    1\n#endif\n\n\n/**\n * Set this flag to non-zero to enable various checking for pool\n * operations. When this flag is set, assertion must be enabled\n * in the application.\n *\n * This will slow down pool creation and destruction and will add\n * few bytes of overhead, so application would normally want to \n * disable this feature on release build.\n *\n * Default: 0\n */\n#ifndef PJ_SAFE_POOL\n#   define PJ_SAFE_POOL\t\t    0\n#endif\n\n\n/**\n * If pool debugging is used, then each memory allocation from the pool\n * will call malloc(), and pool will release all memory chunks when it\n * is destroyed. This works better when memory verification programs\n * such as Rational Purify is used.\n *\n * Default: 0\n */\n#ifndef PJ_POOL_DEBUG\n#  define PJ_POOL_DEBUG\t\t    0\n#endif\n\n\n/**\n * Enable timer heap debugging facility. When this is enabled, application\n * can call pj_timer_heap_dump() to show the contents of the timer heap\n * along with the source location where the timer entries were scheduled.\n * See https://trac.pjsip.org/repos/ticket/1527 for more info.\n *\n * Default: 0\n */\n#ifndef PJ_TIMER_DEBUG\n#  define PJ_TIMER_DEBUG\t    0\n#endif\n\n\n/**\n * Set this to 1 to enable debugging on the group lock. Default: 0\n */\n#ifndef PJ_GRP_LOCK_DEBUG\n#  define PJ_GRP_LOCK_DEBUG\t0\n#endif\n\n\n/**\n * Specify this as \\a stack_size argument in #pj_thread_create() to specify\n * that thread should use default stack size for the current platform.\n *\n * Default: 8192\n */\n#ifndef PJ_THREAD_DEFAULT_STACK_SIZE \n#  define PJ_THREAD_DEFAULT_STACK_SIZE    8192\n#endif\n\n\n/**\n * Specify if PJ_CHECK_STACK() macro is enabled to check the sanity of \n * the stack. The OS implementation may check that no stack overflow \n * occurs, and it also may collect statistic about stack usage. Note\n * that this will increase the footprint of the libraries since it\n * tracks the filename and line number of each functions.\n */\n#ifndef PJ_OS_HAS_CHECK_STACK\n#\tdefine PJ_OS_HAS_CHECK_STACK\t\t0\n#endif\n\n/**\n * Do we have alternate pool implementation?\n *\n * Default: 0\n */\n#ifndef PJ_HAS_POOL_ALT_API\n#   define PJ_HAS_POOL_ALT_API\t    PJ_POOL_DEBUG\n#endif\n\n\n/**\n * Support TCP in the library.\n * Disabling TCP will reduce the footprint slightly (about 6KB).\n *\n * Default: 1\n */\n#ifndef PJ_HAS_TCP\n#  define PJ_HAS_TCP\t\t    1\n#endif\n\n/**\n * Support IPv6 in the library. If this support is disabled, some IPv6 \n * related functions will return PJ_EIPV6NOTSUP.\n *\n * Default: 0 (disabled, for now)\n */\n#ifndef PJ_HAS_IPV6\n#  define PJ_HAS_IPV6\t\t    0\n#endif\n\n /**\n * Maximum hostname length.\n * Libraries sometimes needs to make copy of an address to stack buffer;\n * the value here affects the stack usage.\n *\n * Default: 128\n */\n#ifndef PJ_MAX_HOSTNAME\n#  define PJ_MAX_HOSTNAME\t    (128)\n#endif\n\n/**\n * Maximum consecutive identical error for accept() operation before\n * activesock stops calling the next ioqueue accept.\n *\n * Default: 50\n */\n#ifndef PJ_ACTIVESOCK_MAX_CONSECUTIVE_ACCEPT_ERROR\n#   define PJ_ACTIVESOCK_MAX_CONSECUTIVE_ACCEPT_ERROR 50\n#endif\n\n/**\n * Constants for declaring the maximum handles that can be supported by\n * a single IOQ framework. This constant might not be relevant to the \n * underlying I/O queue impelementation, but still, developers should be \n * aware of this constant, to make sure that the program will not break when\n * the underlying implementation changes.\n */\n#ifndef PJ_IOQUEUE_MAX_HANDLES\n#   define PJ_IOQUEUE_MAX_HANDLES\t(64)\n#endif\n\n\n/**\n * If PJ_IOQUEUE_HAS_SAFE_UNREG macro is defined, then ioqueue will do more\n * things to ensure thread safety of handle unregistration operation by\n * employing reference counter to each handle.\n *\n * In addition, the ioqueue will preallocate memory for the handles, \n * according to the maximum number of handles that is specified during \n * ioqueue creation.\n *\n * All applications would normally want this enabled, but you may disable\n * this if:\n *  - there is no dynamic unregistration to all ioqueues.\n *  - there is no threading, or there is no preemptive multitasking.\n *\n * Default: 1\n */\n#ifndef PJ_IOQUEUE_HAS_SAFE_UNREG\n#   define PJ_IOQUEUE_HAS_SAFE_UNREG\t1\n#endif\n\n\n/**\n * Default concurrency setting for sockets/handles registered to ioqueue.\n * This controls whether the ioqueue is allowed to call the key's callback\n * concurrently/in parallel. The default is yes, which means that if there\n * are more than one pending operations complete simultaneously, more\n * than one threads may call the key's callback at the same time. This\n * generally would promote good scalability for application, at the \n * expense of more complexity to manage the concurrent accesses.\n *\n * Please see the ioqueue documentation for more info.\n */\n#ifndef PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY\n#   define PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY   1\n#endif\n\n\n/* Sanity check:\n *  if ioqueue concurrency is disallowed, PJ_IOQUEUE_HAS_SAFE_UNREG\n *  must be enabled.\n */\n#if (PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY==0) && (PJ_IOQUEUE_HAS_SAFE_UNREG==0)\n#   error PJ_IOQUEUE_HAS_SAFE_UNREG must be enabled if ioqueue concurrency \\\n\t  is disabled\n#endif\n\n\n/**\n * When safe unregistration (PJ_IOQUEUE_HAS_SAFE_UNREG) is configured in\n * ioqueue, the PJ_IOQUEUE_KEY_FREE_DELAY macro specifies how long the\n * ioqueue key is kept in closing state before it can be reused.\n *\n * The value is in miliseconds.\n *\n * Default: 500 msec.\n */\n#ifndef PJ_IOQUEUE_KEY_FREE_DELAY\n#   define PJ_IOQUEUE_KEY_FREE_DELAY\t500\n#endif\n\n\n/**\n * Determine if FD_SETSIZE is changeable/set-able. If so, then we will\n * set it to PJ_IOQUEUE_MAX_HANDLES. Currently we detect this by checking\n * for Winsock.\n */\n#ifndef PJ_FD_SETSIZE_SETABLE\n#   if (defined(PJ_HAS_WINSOCK_H) && PJ_HAS_WINSOCK_H!=0) || \\\n       (defined(PJ_HAS_WINSOCK2_H) && PJ_HAS_WINSOCK2_H!=0)\n#\tdefine PJ_FD_SETSIZE_SETABLE\t1\n#   else\n#\tdefine PJ_FD_SETSIZE_SETABLE\t0\n#   endif\n#endif\n\n/**\n * Overrides FD_SETSIZE so it is consistent throughout the library.\n * We only do this if we detected that FD_SETSIZE is changeable. If\n * FD_SETSIZE is not set-able, then PJ_IOQUEUE_MAX_HANDLES must be\n * set to value lower than FD_SETSIZE.\n */\n#if PJ_FD_SETSIZE_SETABLE\n    /* Only override FD_SETSIZE if the value has not been set */\n#   ifndef FD_SETSIZE\n#\tdefine FD_SETSIZE\t\tPJ_IOQUEUE_MAX_HANDLES\n#   endif\n#else\n    /* When FD_SETSIZE is not changeable, check if PJ_IOQUEUE_MAX_HANDLES\n     * is lower than FD_SETSIZE value.\n     *\n     * Update: Not all ioqueue backends require this (such as epoll), so\n     * this check will be done on the ioqueue implementation itself, such as\n     * ioqueue select.\n     */\n/*\n#   ifdef FD_SETSIZE\n#\tif PJ_IOQUEUE_MAX_HANDLES > FD_SETSIZE\n#\t    error \"PJ_IOQUEUE_MAX_HANDLES is greater than FD_SETSIZE\"\n#\tendif\n#   endif\n*/\n#endif\n\n\n/**\n * Specify whether #pj_enum_ip_interface() function should exclude\n * loopback interfaces.\n *\n * Default: 1\n */\n#ifndef PJ_IP_HELPER_IGNORE_LOOPBACK_IF\n#   define PJ_IP_HELPER_IGNORE_LOOPBACK_IF\t1\n#endif\n\n\n/**\n * Has semaphore functionality?\n *\n * Default: 1\n */\n#ifndef PJ_HAS_SEMAPHORE\n#  define PJ_HAS_SEMAPHORE\t    1\n#endif\n\n\n/**\n * Event object (for synchronization, e.g. in Win32)\n *\n * Default: 1\n */\n#ifndef PJ_HAS_EVENT_OBJ\n#  define PJ_HAS_EVENT_OBJ\t    1\n#endif\n\n\n/**\n * Maximum file name length.\n */\n#ifndef PJ_MAXPATH\n#   define PJ_MAXPATH\t\t    260\n#endif\n\n\n/**\n * Enable library's extra check.\n * If this macro is enabled, #PJ_ASSERT_RETURN macro will expand to\n * run-time checking. If this macro is disabled, #PJ_ASSERT_RETURN\n * will simply evaluate to #pj_assert().\n *\n * You can disable this macro to reduce size, at the risk of crashes\n * if invalid value (e.g. NULL) is passed to the library.\n *\n * Default: 1\n */\n#ifndef PJ_ENABLE_EXTRA_CHECK\n#   define PJ_ENABLE_EXTRA_CHECK    1\n#endif\n\n\n/**\n * Enable name registration for exceptions with #pj_exception_id_alloc().\n * If this feature is enabled, then the library will keep track of\n * names associated with each exception ID requested by application via\n * #pj_exception_id_alloc().\n *\n * Disabling this macro will reduce the code and .bss size by a tad bit.\n * See also #PJ_MAX_EXCEPTION_ID.\n *\n * Default: 1\n */\n#ifndef PJ_HAS_EXCEPTION_NAMES\n#   define PJ_HAS_EXCEPTION_NAMES   1\n#endif\n\n/**\n * Maximum number of unique exception IDs that can be requested\n * with #pj_exception_id_alloc(). For each entry, a small record will\n * be allocated in the .bss segment.\n *\n * Default: 16\n */\n#ifndef PJ_MAX_EXCEPTION_ID\n#   define PJ_MAX_EXCEPTION_ID      16\n#endif\n\n/**\n * Should we use Windows Structured Exception Handling (SEH) for the\n * PJLIB exceptions.\n *\n * Default: 0\n */\n#ifndef PJ_EXCEPTION_USE_WIN32_SEH\n#  define PJ_EXCEPTION_USE_WIN32_SEH 0\n#endif\n\n/**\n * Should we attempt to use Pentium's rdtsc for high resolution\n * timestamp.\n *\n * Default: 0\n */\n#ifndef PJ_TIMESTAMP_USE_RDTSC\n#   define PJ_TIMESTAMP_USE_RDTSC   0\n#endif\n\n/**\n * Is native platform error positive number?\n * Default: 1 (yes)\n */\n#ifndef PJ_NATIVE_ERR_POSITIVE\n#   define PJ_NATIVE_ERR_POSITIVE   1\n#endif\n \n/**\n * Include error message string in the library (pj_strerror()).\n * This is very much desirable!\n *\n * Default: 1\n */\n#ifndef PJ_HAS_ERROR_STRING\n#   define PJ_HAS_ERROR_STRING\t    1\n#endif\n\n\n/**\n * Include pj_stricmp_alnum() and pj_strnicmp_alnum(), i.e. custom\n * functions to compare alnum strings. On some systems, they're faster\n * then stricmp/strcasecmp, but they can be slower on other systems.\n * When disabled, pjlib will fallback to stricmp/strnicmp.\n * \n * Default: 0\n */\n#ifndef PJ_HAS_STRICMP_ALNUM\n#   define PJ_HAS_STRICMP_ALNUM\t    0\n#endif\n\n\n/*\n * Types of QoS backend implementation.\n */\n\n/** \n * Dummy QoS backend implementation, will always return error on all\n * the APIs.\n */\n#define PJ_QOS_DUMMY\t    1\n\n/** QoS backend based on setsockopt(IP_TOS) */\n#define PJ_QOS_BSD\t    2\n\n/** QoS backend for Windows Mobile 6 */\n#define PJ_QOS_WM\t    3\n\n/** QoS backend for Symbian */\n#define PJ_QOS_SYMBIAN\t    4\n\n/**\n * Force the use of some QoS backend API for some platforms.\n */\n#ifndef PJ_QOS_IMPLEMENTATION\n#   if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE && _WIN32_WCE >= 0x502\n\t/* Windows Mobile 6 or later */\n#\tdefine PJ_QOS_IMPLEMENTATION    PJ_QOS_WM\n#   endif\n#endif\n\n\n/**\n * Enable secure socket. For most platforms, this is implemented using\n * OpenSSL, so this will require OpenSSL to be installed. For Symbian\n * platform, this is implemented natively using CSecureSocket.\n *\n * Default: 0 (for now)\n */\n#ifndef PJ_HAS_SSL_SOCK\n#  define PJ_HAS_SSL_SOCK\t    0\n#endif\n\n\n/**\n * Define the maximum number of ciphers supported by the secure socket.\n *\n * Default: 256\n */\n#ifndef PJ_SSL_SOCK_MAX_CIPHERS\n#  define PJ_SSL_SOCK_MAX_CIPHERS   256\n#endif\n\n\n/**\n * Specify what should be set as the available list of SSL_CIPHERs. For\n * example, set this as \"DEFAULT\" to use the default cipher list (Note:\n * PJSIP release 2.4 and before used this \"DEFAULT\" setting).\n *\n * Default: \"HIGH:-COMPLEMENTOFDEFAULT\"\n */\n#ifndef PJ_SSL_SOCK_OSSL_CIPHERS\n#  define PJ_SSL_SOCK_OSSL_CIPHERS   \"HIGH:-COMPLEMENTOFDEFAULT\"\n#endif\n\n\n/**\n * Disable WSAECONNRESET error for UDP sockets on Win32 platforms. See\n * https://trac.pjsip.org/repos/ticket/1197.\n *\n * Default: 1\n */\n#ifndef PJ_SOCK_DISABLE_WSAECONNRESET\n#   define PJ_SOCK_DISABLE_WSAECONNRESET    1\n#endif\n\n\n/** @} */\n\n/********************************************************************\n * General macros.\n */\n\n/**\n * @defgroup pj_dll_target Building Dynamic Link Libraries (DLL/DSO)\n * @ingroup pj_config\n * @{\n *\n * The libraries support generation of dynamic link libraries for\n * Symbian ABIv2 target (.dso/Dynamic Shared Object files, in Symbian\n * terms). Similar procedures may be applied for Win32 DLL with some \n * modification.\n *\n * Depending on the platforms, these steps may be necessary in order to\n * produce the dynamic libraries:\n *  - Create the (Visual Studio) projects to produce DLL output. PJLIB\n *    does not provide ready to use project files to produce DLL, so\n *    you need to create these projects yourself. For Symbian, the MMP\n *    files have been setup to produce DSO files for targets that \n *    require them.\n *  - In the (Visual Studio) projects, some macros need to be declared\n *    so that appropriate modifiers are added to symbol declarations\n *    and definitions. Please see the macro section below for information\n *    regarding these macros. For Symbian, these have been taken care by the\n *    MMP files.\n *  - Some build systems require .DEF file to be specified when creating\n *    the DLL. For Symbian, .DEF files are included in pjlib distribution,\n *    in <tt>pjlib/build.symbian</tt> directory. These DEF files are \n *    created by running <tt>./makedef.sh all</tt> from this directory,\n *    inside Mingw.\n *\n * Macros related for building DLL/DSO files:\n *  - For platforms that supports dynamic link libraries generation,\n *    it must declare <tt>PJ_EXPORT_SPECIFIER</tt> macro which value contains\n *    the prefix to be added to symbol definition, to export this \n *    symbol in the DLL/DSO. For example, on Win32/Visual Studio, the\n *    value of this macro is \\a __declspec(dllexport), and for ARM \n *    ABIv2/Symbian, the value is \\a EXPORT_C. \n *  - For platforms that supports linking with dynamic link libraries,\n *    it must declare <tt>PJ_IMPORT_SPECIFIER</tt> macro which value contains\n *    the prefix to be added to symbol declaration, to import this \n *    symbol from a DLL/DSO. For example, on Win32/Visual Studio, the\n *    value of this macro is \\a __declspec(dllimport), and for ARM \n *    ABIv2/Symbian, the value is \\a IMPORT_C. \n *  - Both <tt>PJ_EXPORT_SPECIFIER</tt> and <tt>PJ_IMPORT_SPECIFIER</tt> \n *    macros above can be declared in your \\a config_site.h if they are not\n *    declared by pjlib.\n *  - When PJLIB is built as DLL/DSO, both <tt>PJ_DLL</tt> and \n *    <tt>PJ_EXPORTING</tt> macros must be declared, so that \n *     <tt>PJ_EXPORT_SPECIFIER</tt> modifier will be added into function\n *    definition.\n *  - When application wants to link dynamically with PJLIB, then it\n *    must declare <tt>PJ_DLL</tt> macro when using/including PJLIB header,\n *    so that <tt>PJ_IMPORT_SPECIFIER</tt> modifier is properly added into \n *    symbol declarations.\n *\n * When <b>PJ_DLL</b> macro is not declared, static linking is assumed.\n *\n * For example, here are some settings to produce DLLs with Visual Studio\n * on Windows/Win32:\n *  - Create Visual Studio projects to produce DLL. Add the appropriate \n *    project dependencies to avoid link errors.\n *  - In the projects, declare <tt>PJ_DLL</tt> and <tt>PJ_EXPORTING</tt> \n *    macros.\n *  - Declare these macros in your <tt>config_site.h</tt>:\n \\verbatim\n\t#define PJ_EXPORT_SPECIFIER  __declspec(dllexport)\n\t#define PJ_IMPORT_SPECIFIER  __declspec(dllimport)\n \\endverbatim\n *  - And in the application (that links with the DLL) project, add \n *    <tt>PJ_DLL</tt> in the macro declarations.\n */\n\n/** @} */\n\n/**\n * @defgroup pj_config Build Configuration\n * @{\n */\n\n/**\n * @def PJ_INLINE(type)\n * @param type The return type of the function.\n * Expand the function as inline.\n */\n#define PJ_INLINE(type)\t  PJ_INLINE_SPECIFIER type\n\n/**\n * This macro declares platform/compiler specific specifier prefix\n * to be added to symbol declaration to export the symbol when PJLIB\n * is built as dynamic library.\n *\n * This macro should have been added by platform specific headers,\n * if the platform supports building dynamic library target. \n */\n#ifndef PJ_EXPORT_DECL_SPECIFIER\n#   define PJ_EXPORT_DECL_SPECIFIER\n#endif\n\n\n/**\n * This macro declares platform/compiler specific specifier prefix\n * to be added to symbol definition to export the symbol when PJLIB\n * is built as dynamic library.\n *\n * This macro should have been added by platform specific headers,\n * if the platform supports building dynamic library target. \n */\n#ifndef PJ_EXPORT_DEF_SPECIFIER\n#   define PJ_EXPORT_DEF_SPECIFIER\n#endif\n\n\n/**\n * This macro declares platform/compiler specific specifier prefix\n * to be added to symbol declaration to import the symbol.\n *\n * This macro should have been added by platform specific headers,\n * if the platform supports building dynamic library target.\n */\n#ifndef PJ_IMPORT_DECL_SPECIFIER\n#   define PJ_IMPORT_DECL_SPECIFIER\n#endif\n\n\n/**\n * This macro has been deprecated. It will evaluate to nothing.\n */\n#ifndef PJ_EXPORT_SYMBOL\n#   define PJ_EXPORT_SYMBOL(x)\n#endif\n\n\n/**\n * @def PJ_DECL(type)\n * @param type The return type of the function.\n * Declare a function.\n */\n#if defined(PJ_DLL)\n#   if defined(PJ_EXPORTING)\n#\tdefine PJ_DECL(type)\t    PJ_EXPORT_DECL_SPECIFIER type\n#   else\n#\tdefine PJ_DECL(type)\t    PJ_IMPORT_DECL_SPECIFIER type\n#   endif\n#elif !defined(PJ_DECL)\n#   if defined(__cplusplus)\n#\tdefine PJ_DECL(type)\t    type\n#   else\n#\tdefine PJ_DECL(type)\t    extern type\n#   endif\n#endif\n\n\n/**\n * @def PJ_DEF(type)\n * @param type The return type of the function.\n * Define a function.\n */\n#if defined(PJ_DLL) && defined(PJ_EXPORTING)\n#   define PJ_DEF(type)\t\t    PJ_EXPORT_DEF_SPECIFIER type\n#elif !defined(PJ_DEF)\n#   define PJ_DEF(type)\t\t    type\n#endif\n\n\n/**\n * @def PJ_DECL_NO_RETURN(type)\n * @param type The return type of the function.\n * Declare a function that will not return.\n */\n/**\n * @def PJ_IDECL_NO_RETURN(type)\n * @param type The return type of the function.\n * Declare an inline function that will not return.\n */\n/**\n * @def PJ_BEGIN_DECL\n * Mark beginning of declaration section in a header file.\n */\n/**\n * @def PJ_END_DECL\n * Mark end of declaration section in a header file.\n */\n#ifdef __cplusplus\n#  define PJ_DECL_NO_RETURN(type)   PJ_DECL(type) PJ_NORETURN\n#  define PJ_IDECL_NO_RETURN(type)  PJ_INLINE(type) PJ_NORETURN\n#  define PJ_BEGIN_DECL\t\t    extern \"C\" {\n#  define PJ_END_DECL\t\t    }\n#else\n#  define PJ_DECL_NO_RETURN(type)   PJ_NORETURN PJ_DECL(type)\n#  define PJ_IDECL_NO_RETURN(type)  PJ_NORETURN PJ_INLINE(type)\n#  define PJ_BEGIN_DECL\n#  define PJ_END_DECL\n#endif\n\n\n\n/**\n * @def PJ_DECL_DATA(type)\n * @param type The data type.\n * Declare a global data.\n */ \n#if defined(PJ_DLL)\n#   if defined(PJ_EXPORTING)\n#\tdefine PJ_DECL_DATA(type)   PJ_EXPORT_DECL_SPECIFIER extern type\n#   else\n#\tdefine PJ_DECL_DATA(type)   PJ_IMPORT_DECL_SPECIFIER extern type\n#   endif\n#elif !defined(PJ_DECL_DATA)\n#   define PJ_DECL_DATA(type)\t    extern type\n#endif\n\n\n/**\n * @def PJ_DEF_DATA(type)\n * @param type The data type.\n * Define a global data.\n */ \n#if defined(PJ_DLL) && defined(PJ_EXPORTING)\n#   define PJ_DEF_DATA(type)\t    PJ_EXPORT_DEF_SPECIFIER type\n#elif !defined(PJ_DEF_DATA)\n#   define PJ_DEF_DATA(type)\t    type\n#endif\n\n\n/**\n * @def PJ_IDECL(type)\n * @param type  The function's return type.\n * Declare a function that may be expanded as inline.\n */\n/**\n * @def PJ_IDEF(type)\n * @param type  The function's return type.\n * Define a function that may be expanded as inline.\n */\n\n#if PJ_FUNCTIONS_ARE_INLINED\n#  define PJ_IDECL(type)  PJ_INLINE(type)\n#  define PJ_IDEF(type)   PJ_INLINE(type)\n#else\n#  define PJ_IDECL(type)  PJ_DECL(type)\n#  define PJ_IDEF(type)   PJ_DEF(type)\n#endif\n\n\n/**\n * @def PJ_UNUSED_ARG(arg)\n * @param arg   The argument name.\n * PJ_UNUSED_ARG prevents warning about unused argument in a function.\n */\n#define PJ_UNUSED_ARG(arg)  (void)arg\n\n/**\n * @def PJ_TODO(id)\n * @param id    Any identifier that will be printed as TODO message.\n * PJ_TODO macro will display TODO message as warning during compilation.\n * Example: PJ_TODO(CLEAN_UP_ERROR);\n */\n#ifndef PJ_TODO\n#  define PJ_TODO(id)\t    TODO___##id:\n#endif\n\n/**\n * Simulate race condition by sleeping the thread in strategic locations.\n * Default: no!\n */\n#ifndef PJ_RACE_ME\n#  define PJ_RACE_ME(x)\n#endif\n\n/**\n * Function attributes to inform that the function may throw exception.\n *\n * @param x     The exception list, enclosed in parenthesis.\n */\n#define __pj_throw__(x)\n\n/** @} */\n\n/********************************************************************\n * Sanity Checks\n */\n#ifndef PJ_HAS_HIGH_RES_TIMER\n#  error \"PJ_HAS_HIGH_RES_TIMER is not defined!\"\n#endif\n\n#if !defined(PJ_HAS_PENTIUM)\n#  error \"PJ_HAS_PENTIUM is not defined!\"\n#endif\n\n#if !defined(PJ_IS_LITTLE_ENDIAN)\n#  error \"PJ_IS_LITTLE_ENDIAN is not defined!\"\n#endif\n\n#if !defined(PJ_IS_BIG_ENDIAN)\n#  error \"PJ_IS_BIG_ENDIAN is not defined!\"\n#endif\n\n#if !defined(PJ_EMULATE_RWMUTEX)\n#  error \"PJ_EMULATE_RWMUTEX should be defined in compat/os_xx.h\"\n#endif\n\n#if !defined(PJ_THREAD_SET_STACK_SIZE)\n#  error \"PJ_THREAD_SET_STACK_SIZE should be defined in compat/os_xx.h\"\n#endif\n\n#if !defined(PJ_THREAD_ALLOCATE_STACK)\n#  error \"PJ_THREAD_ALLOCATE_STACK should be defined in compat/os_xx.h\"\n#endif\n\nPJ_BEGIN_DECL\n\n/** PJLIB version major number. */\n#define PJ_VERSION_NUM_MAJOR\t2\n\n/** PJLIB version minor number. */\n#define PJ_VERSION_NUM_MINOR\t4\n\n/** PJLIB version revision number. */\n#define PJ_VERSION_NUM_REV\t5\n\n/**\n * Extra suffix for the version (e.g. \"-trunk\"), or empty for\n * web release version.\n */\n#define PJ_VERSION_NUM_EXTRA\t\"-svn\"\n\n/**\n * PJLIB version number consists of three bytes with the following format:\n * 0xMMIIRR00, where MM: major number, II: minor number, RR: revision\n * number, 00: always zero for now.\n */\n#define PJ_VERSION_NUM\t((PJ_VERSION_NUM_MAJOR << 24) |\t\\\n\t\t\t (PJ_VERSION_NUM_MINOR << 16) | \\\n\t\t\t (PJ_VERSION_NUM_REV << 8))\n\n/**\n * PJLIB version string constant. @see pj_get_version()\n */\nPJ_DECL_DATA(const char*) PJ_VERSION;\n\n/**\n * Get PJLIB version string.\n *\n * @return #PJ_VERSION constant.\n */\nPJ_DECL(const char*) pj_get_version(void);\n\n/**\n * Dump configuration to log with verbosity equal to info(3).\n */\nPJ_DECL(void) pj_dump_config(void);\n\nPJ_END_DECL\n\n\n#endif\t/* __PJ_CONFIG_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/config_site_sample.h",
    "content": "/*\n * This file contains several sample settings especially for Windows\n * Mobile and Symbian targets. You can include this file in your\n * <pj/config_site.h> file.\n *\n * The Windows Mobile and Symbian settings will be activated\n * automatically if you include this file.\n *\n * In addition, you may specify one of these macros (before including\n * this file) to activate additional settings:\n *\n * #define PJ_CONFIG_NOKIA_APS_DIRECT\n *   Use this macro to activate the APS-Direct feature. Please see\n *   http://trac.pjsip.org/repos/wiki/Nokia_APS_VAS_Direct for more \n *   info.\n *\n * #define PJ_CONFIG_WIN32_WMME_DIRECT\n *   Configuration to activate \"APS-Direct\" media mode on Windows or\n *   Windows Mobile, useful for testing purposes only.\n */\n\n\n/*\n * Typical configuration for WinCE target.\n */\n#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0\n\n    /*\n     * PJLIB settings.\n     */\n\n    /* Disable floating point support */\n    #define PJ_HAS_FLOATING_POINT\t\t0\n\n    /*\n     * PJMEDIA settings\n     */\n\n    /* Select codecs to disable */\n    #define PJMEDIA_HAS_L16_CODEC\t\t0\n    #define PJMEDIA_HAS_ILBC_CODEC\t\t0\n\n    /* We probably need more buffers on WM, so increase the limit */\n    #define PJMEDIA_SOUND_BUFFER_COUNT\t\t32\n\n    /* Fine tune Speex's default settings for best performance/quality */\n    #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY\t5\n\n    /* For CPU reason, disable speex AEC and use the echo suppressor. */\n    #define PJMEDIA_HAS_SPEEX_AEC\t\t0\n\n    /* Previously, resampling is disabled due to performance reason and\n     * this condition prevented some 'light' wideband codecs (e.g: G722.1)\n     * to work along with narrowband codecs. Lately, some tests showed\n     * that 16kHz <-> 8kHz resampling using libresample small filter was \n     * affordable on ARM9 260 MHz, so here we decided to enable resampling.\n     * Note that it is important to make sure that libresample is created\n     * using small filter. For example PJSUA_DEFAULT_CODEC_QUALITY must\n     * be set to 3 or 4 so pjsua-lib will apply small filter resampling.\n     */\n    //#define PJMEDIA_RESAMPLE_IMP\t\tPJMEDIA_RESAMPLE_NONE\n    #define PJMEDIA_RESAMPLE_IMP\t\tPJMEDIA_RESAMPLE_LIBRESAMPLE\n\n    /* Use the lighter WSOLA implementation */\n    #define PJMEDIA_WSOLA_IMP\t\t\tPJMEDIA_WSOLA_IMP_WSOLA_LITE\n\n    /*\n     * PJSIP settings.\n     */\n\n    /* Set maximum number of dialog/transaction/calls to minimum to reduce\n     * memory usage \n     */\n    #define PJSIP_MAX_TSX_COUNT \t\t31\n    #define PJSIP_MAX_DIALOG_COUNT \t\t31\n    #define PJSUA_MAX_CALLS\t\t\t4\n\n    /*\n     * PJSUA settings\n     */\n\n    /* Default codec quality, previously was set to 5, however it is now\n     * set to 4 to make sure pjsua instantiates resampler with small filter.\n     */\n    #define PJSUA_DEFAULT_CODEC_QUALITY\t\t4\n\n    /* Set maximum number of objects to minimum to reduce memory usage */\n    #define PJSUA_MAX_ACC\t\t\t4\n    #define PJSUA_MAX_PLAYERS\t\t\t4\n    #define PJSUA_MAX_RECORDERS\t\t\t4\n    #define PJSUA_MAX_CONF_PORTS\t\t(PJSUA_MAX_CALLS+2*PJSUA_MAX_PLAYERS)\n    #define PJSUA_MAX_BUDDIES\t\t\t32\n\n#endif\t/* PJ_WIN32_WINCE */\n\n\n/*\n * Typical configuration for Symbian OS target\n */\n#if defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0\n\n    /*\n     * PJLIB settings.\n     */\n\n    /* Disable floating point support */\n    #define PJ_HAS_FLOATING_POINT\t\t0\n\n    /* Misc PJLIB setting */\n    #define PJ_MAXPATH\t\t\t\t80\n\n    /* This is important for Symbian. Symbian lacks vsnprintf(), so\n     * if the log buffer is not long enough it's possible that\n     * large incoming packet will corrupt memory when the log tries\n     * to log the packet.\n     */\n    #define PJ_LOG_MAX_SIZE\t\t\t(PJSIP_MAX_PKT_LEN+500)\n\n    /* Since we don't have threads, log buffer can use static buffer\n     * rather than stack\n     */\n    #define PJ_LOG_USE_STACK_BUFFER\t\t0\n\n    /* Disable check stack since it increases footprint */\n    #define PJ_OS_HAS_CHECK_STACK\t\t0\n\n\n    /*\n     * PJMEDIA settings\n     */\n\n    /* Disable non-Symbian audio devices */\n    #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO\t0\n    #define PJMEDIA_AUDIO_DEV_HAS_WMME\t\t0\n\n    /* Select codecs to disable */\n    #define PJMEDIA_HAS_L16_CODEC\t\t0\n    #define PJMEDIA_HAS_ILBC_CODEC\t\t0\n    #define PJMEDIA_HAS_G722_CODEC\t\t0\n\n    /* Fine tune Speex's default settings for best performance/quality */\n    #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY\t5\n\n    /* For CPU reason, disable speex AEC and use the echo suppressor. */\n    #define PJMEDIA_HAS_SPEEX_AEC\t\t0\n\n    /* Previously, resampling is disabled due to performance reason and\n     * this condition prevented some 'light' wideband codecs (e.g: G722.1)\n     * to work along with narrowband codecs. Lately, some tests showed\n     * that 16kHz <-> 8kHz resampling using libresample small filter was \n     * affordable on ARM9 222 MHz, so here we decided to enable resampling.\n     * Note that it is important to make sure that libresample is created\n     * using small filter. For example PJSUA_DEFAULT_CODEC_QUALITY must\n     * be set to 3 or 4 so pjsua-lib will apply small filter resampling.\n     */\n    //#define PJMEDIA_RESAMPLE_IMP\t\tPJMEDIA_RESAMPLE_NONE\n    #define PJMEDIA_RESAMPLE_IMP\t\tPJMEDIA_RESAMPLE_LIBRESAMPLE\n\n    /* Use the lighter WSOLA implementation */\n    #define PJMEDIA_WSOLA_IMP\t\t\tPJMEDIA_WSOLA_IMP_WSOLA_LITE\n\n    /* We probably need more buffers especially if MDA audio backend \n     * is used, so increase the limit \n     */\n    #define PJMEDIA_SOUND_BUFFER_COUNT\t\t32\n\n    /*\n     * PJSIP settings.\n     */\n\n    /* Disable safe module access, since we don't use multithreading */\n    #define PJSIP_SAFE_MODULE\t\t\t0\n\n    /* Use large enough packet size  */\n    #define PJSIP_MAX_PKT_LEN\t\t\t2000\n\n    /* Symbian has problem with too many large blocks */\n    #define PJSIP_POOL_LEN_ENDPT\t\t1000\n    #define PJSIP_POOL_INC_ENDPT\t\t1000\n    #define PJSIP_POOL_RDATA_LEN\t\t2000\n    #define PJSIP_POOL_RDATA_INC\t\t2000\n    #define PJSIP_POOL_LEN_TDATA\t\t2000\n    #define PJSIP_POOL_INC_TDATA\t\t512\n    #define PJSIP_POOL_LEN_UA\t\t\t2000\n    #define PJSIP_POOL_INC_UA\t\t\t1000\n    #define PJSIP_POOL_TSX_LAYER_LEN\t\t256\n    #define PJSIP_POOL_TSX_LAYER_INC\t\t256\n    #define PJSIP_POOL_TSX_LEN\t\t\t512\n    #define PJSIP_POOL_TSX_INC\t\t\t128\n\n    /*\n     * PJSUA settings.\n     */\n\n    /* Default codec quality, previously was set to 5, however it is now\n     * set to 4 to make sure pjsua instantiates resampler with small filter.\n     */\n    #define PJSUA_DEFAULT_CODEC_QUALITY\t\t4\n\n    /* Set maximum number of dialog/transaction/calls to minimum */\n    #define PJSIP_MAX_TSX_COUNT \t\t31\n    #define PJSIP_MAX_DIALOG_COUNT \t\t31\n    #define PJSUA_MAX_CALLS\t\t\t4\n\n    /* Other pjsua settings */\n    #define PJSUA_MAX_ACC\t\t\t4\n    #define PJSUA_MAX_PLAYERS\t\t\t4\n    #define PJSUA_MAX_RECORDERS\t\t\t4\n    #define PJSUA_MAX_CONF_PORTS\t\t(PJSUA_MAX_CALLS+2*PJSUA_MAX_PLAYERS)\n    #define PJSUA_MAX_BUDDIES\t\t\t32\n#endif\n\n\n/*\n * Additional configuration to activate APS-Direct feature for\n * Nokia S60 target\n *\n * Please see http://trac.pjsip.org/repos/wiki/Nokia_APS_VAS_Direct\n */\n#ifdef PJ_CONFIG_NOKIA_APS_DIRECT\n\n    /* MUST use switchboard rather than the conference bridge */\n    #define PJMEDIA_CONF_USE_SWITCH_BOARD\t1\n\n    /* Enable APS sound device backend and disable MDA & VAS */\n    #define PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA\t0\n    #define PJMEDIA_AUDIO_DEV_HAS_SYMB_APS\t1\n    #define PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS\t0\n\n    /* Enable passthrough codec framework */\n    #define PJMEDIA_HAS_PASSTHROUGH_CODECS\t1\n\n    /* And selectively enable which codecs are supported by the handset */\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU\t1\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA\t1\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR\t1\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729\t1\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC\t1\n\n#endif\n\n\n/*\n * Additional configuration to activate VAS-Direct feature for\n * Nokia S60 target\n *\n * Please see http://trac.pjsip.org/repos/wiki/Nokia_APS_VAS_Direct\n */\n#ifdef PJ_CONFIG_NOKIA_VAS_DIRECT\n\n    /* MUST use switchboard rather than the conference bridge */\n    #define PJMEDIA_CONF_USE_SWITCH_BOARD\t1\n\n    /* Enable VAS sound device backend and disable MDA & APS */\n    #define PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA\t0\n    #define PJMEDIA_AUDIO_DEV_HAS_SYMB_APS\t0\n    #define PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS\t1\n\n    /* Enable passthrough codec framework */\n    #define PJMEDIA_HAS_PASSTHROUGH_CODECS\t1\n\n    /* And selectively enable which codecs are supported by the handset */\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU\t1\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA\t1\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR\t1\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729\t1\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC\t1\n\n#endif\n\n\n/*\n * Configuration to activate \"APS-Direct\" media mode on Windows,\n * useful for testing purposes only.\n */\n#ifdef PJ_CONFIG_WIN32_WMME_DIRECT\n\n    /* MUST use switchboard rather than the conference bridge */\n    #define PJMEDIA_CONF_USE_SWITCH_BOARD\t1\n\n    /* Only WMME supports the \"direct\" feature */\n    #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO\t0\n    #define PJMEDIA_AUDIO_DEV_HAS_WMME\t\t1\n\n    /* Enable passthrough codec framework */\n    #define PJMEDIA_HAS_PASSTHROUGH_CODECS\t1\n\n    /* Only PCMA and PCMU are supported by WMME-direct */\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU\t1\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA\t1\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR\t0\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729\t0\n    #define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC\t0\n\n#endif\n\n/*\n * iPhone sample settings.\n */\n#if PJ_CONFIG_IPHONE\n    /*\n     * PJLIB settings.\n     */\n\n    /* Both armv6 and armv7 has FP hardware support.\n     * See https://trac.pjsip.org/repos/ticket/1589 for more info\n     */\n    #define PJ_HAS_FLOATING_POINT\t\t1\n\n    /*\n     * PJMEDIA settings\n     */\n\n    /* We have our own native CoreAudio backend */\n    #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO\t0\n    #define PJMEDIA_AUDIO_DEV_HAS_WMME\t\t0\n    #define PJMEDIA_AUDIO_DEV_HAS_COREAUDIO\t1\n\n    /* The CoreAudio backend has built-in echo canceller! */\n    #define PJMEDIA_HAS_SPEEX_AEC    0\n\n    /* Disable some codecs */\n    #define PJMEDIA_HAS_L16_CODEC\t\t0\n    //#define PJMEDIA_HAS_G722_CODEC\t\t0\n\n    /* Use the built-in CoreAudio's iLBC codec (yay!) */\n    #define PJMEDIA_HAS_ILBC_CODEC\t\t1\n    #define PJMEDIA_ILBC_CODEC_USE_COREAUDIO\t1\n\n    /* Fine tune Speex's default settings for best performance/quality */\n    #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY\t5\n\n    /*\n     * PJSIP settings.\n     */\n\n    /* Increase allowable packet size, just in case */\n    //#define PJSIP_MAX_PKT_LEN\t\t\t2000\n\n    /*\n     * PJSUA settings.\n     */\n\n    /* Default codec quality, previously was set to 5, however it is now\n     * set to 4 to make sure pjsua instantiates resampler with small filter.\n     */\n    #define PJSUA_DEFAULT_CODEC_QUALITY\t\t4\n\n    /* Set maximum number of dialog/transaction/calls to minimum */\n    #define PJSIP_MAX_TSX_COUNT \t\t31\n    #define PJSIP_MAX_DIALOG_COUNT \t\t31\n    #define PJSUA_MAX_CALLS\t\t\t4\n\n    /* Other pjsua settings */\n    #define PJSUA_MAX_ACC\t\t\t4\n    #define PJSUA_MAX_PLAYERS\t\t\t4\n    #define PJSUA_MAX_RECORDERS\t\t\t4\n    #define PJSUA_MAX_CONF_PORTS\t\t(PJSUA_MAX_CALLS+2*PJSUA_MAX_PLAYERS)\n    #define PJSUA_MAX_BUDDIES\t\t\t32\n\n#endif\n\n/*\n * Android sample settings.\n */\n#if PJ_CONFIG_ANDROID\n\n    #define PJ_ANDROID                          1\n\n    /*\n     * PJLIB settings.\n     */\n\n    /* Disable floating point support */\n    #undef PJ_HAS_FLOATING_POINT\n    #define PJ_HAS_FLOATING_POINT\t\t0\n\n    /*\n     * PJMEDIA settings\n     */\n\n    /* We have our own OpenSL ES backend */\n    #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO\t0\n    #define PJMEDIA_AUDIO_DEV_HAS_WMME\t\t0\n    #define PJMEDIA_AUDIO_DEV_HAS_OPENSL        0\n    #define PJMEDIA_AUDIO_DEV_HAS_ANDROID_JNI\t1\n\n    /* Disable some codecs */\n    #define PJMEDIA_HAS_L16_CODEC\t\t0\n    //#define PJMEDIA_HAS_G722_CODEC\t\t0\n\n    /* Fine tune Speex's default settings for best performance/quality */\n    #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY\t5\n    \n    /* Increase number of video device's supported formats */\n    #define PJMEDIA_VID_DEV_INFO_FMT_CNT\t128\n\n    /*\n     * PJSIP settings.\n     */\n\n    /* Increase allowable packet size, just in case */\n    //#define PJSIP_MAX_PKT_LEN\t\t\t2000\n\n    /*\n     * PJSUA settings.\n     */\n\n    /* Default codec quality, previously was set to 5, however it is now\n     * set to 4 to make sure pjsua instantiates resampler with small filter.\n     */\n    #define PJSUA_DEFAULT_CODEC_QUALITY\t\t4\n\n    /* Set maximum number of dialog/transaction/calls to minimum */\n    #define PJSIP_MAX_TSX_COUNT \t\t31\n    #define PJSIP_MAX_DIALOG_COUNT \t\t31\n    #define PJSUA_MAX_CALLS\t\t\t4\n\n    /* Other pjsua settings */\n    #define PJSUA_MAX_ACC\t\t\t4\n    #define PJSUA_MAX_PLAYERS\t\t\t4\n    #define PJSUA_MAX_RECORDERS\t\t\t4\n    #define PJSUA_MAX_CONF_PORTS\t\t(PJSUA_MAX_CALLS+2*PJSUA_MAX_PLAYERS)\n    #define PJSUA_MAX_BUDDIES\t\t\t32\n#endif\n\n\n/*\n * BB10\n */\n#if defined(PJ_CONFIG_BB10) && PJ_CONFIG_BB10\n    /* Quality 3 - 4 to use resampling small filter */\n    #define PJSUA_DEFAULT_CODEC_QUALITY\t\t\t4\n    #define PJMEDIA_HAS_LEGACY_SOUND_API\t\t0\n    #undef PJMEDIA_HAS_SPEEX_AEC\n    #define PJMEDIA_HAS_SPEEX_AEC\t\t\t0\n    #undef PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO\n    #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO\t\t0\n#endif\n\n\n/*\n * Minimum size\n */\n#ifdef PJ_CONFIG_MINIMAL_SIZE\n\n#   undef PJ_OS_HAS_CHECK_STACK\n#   define PJ_OS_HAS_CHECK_STACK\t0\n#   define PJ_LOG_MAX_LEVEL\t\t0\n#   define PJ_ENABLE_EXTRA_CHECK\t0\n#   define PJ_HAS_ERROR_STRING\t\t0\n#   undef PJ_IOQUEUE_MAX_HANDLES\n/* Putting max handles to lower than 32 will make pj_fd_set_t size smaller\n * than native fdset_t and will trigger assertion on sock_select.c.\n */\n#   define PJ_IOQUEUE_MAX_HANDLES\t32\n#   define PJ_CRC32_HAS_TABLES\t\t0\n#   define PJSIP_MAX_TSX_COUNT\t\t15\n#   define PJSIP_MAX_DIALOG_COUNT\t15\n#   define PJSIP_UDP_SO_SNDBUF_SIZE\t4000\n#   define PJSIP_UDP_SO_RCVBUF_SIZE\t4000\n#   define PJMEDIA_HAS_ALAW_ULAW_TABLE\t0\n\n#elif defined(PJ_CONFIG_MAXIMUM_SPEED)\n#   define PJ_SCANNER_USE_BITWISE\t0\n#   undef PJ_OS_HAS_CHECK_STACK\n#   define PJ_OS_HAS_CHECK_STACK\t0\n#   define PJ_LOG_MAX_LEVEL\t\t3\n#   define PJ_ENABLE_EXTRA_CHECK\t0\n#   define PJ_IOQUEUE_MAX_HANDLES\t5000\n#   define PJSIP_MAX_TSX_COUNT\t\t((640*1024)-1)\n#   define PJSIP_MAX_DIALOG_COUNT\t((640*1024)-1)\n#   define PJSIP_UDP_SO_SNDBUF_SIZE\t(24*1024*1024)\n#   define PJSIP_UDP_SO_RCVBUF_SIZE\t(24*1024*1024)\n#   define PJ_DEBUG\t\t\t0\n#   define PJSIP_SAFE_MODULE\t\t0\n#   define PJ_HAS_STRICMP_ALNUM\t\t0\n#   define PJ_HASH_USE_OWN_TOLOWER\t1\n#   define PJSIP_UNESCAPE_IN_PLACE\t1\n\n#   if defined(PJ_WIN32) || defined(PJ_WIN64) \n#     define PJSIP_MAX_NET_EVENTS\t10\n#   endif\n\n#   define PJSUA_MAX_CALLS\t\t512\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/ctype.h",
    "content": "/* $Id: ctype.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_CTYPE_H__\n#define __PJ_CTYPE_H__\n\n/**\n * @file ctype.h\n * @brief C type helper macros.\n */\n\n#include <pj/types.h>\n#include <pj/compat/ctype.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup pj_ctype ctype - Character Type\n * @ingroup PJ_MISC\n * @{\n *\n * This module contains several inline functions/macros for testing or\n * manipulating character types. It is provided in PJLIB because PJLIB\n * must not depend to LIBC.\n */\n\n/** \n * Returns a non-zero value if either isalpha or isdigit is true for c.\n * @param c     The integer character to test.\n * @return      Non-zero value if either isalpha or isdigit is true for c.\n */\nPJ_INLINE(int) pj_isalnum(unsigned char c) { return isalnum(c); }\n\n/** \n * Returns a non-zero value if c is a particular representation of an \n * alphabetic character.\n * @param c     The integer character to test.\n * @return      Non-zero value if c is a particular representation of an \n *              alphabetic character.\n */\nPJ_INLINE(int) pj_isalpha(unsigned char c) { return isalpha(c); }\n\n/** \n * Returns a non-zero value if c is a particular representation of an \n * ASCII character.\n * @param c     The integer character to test.\n * @return      Non-zero value if c is a particular representation of \n *              an ASCII character.\n */\nPJ_INLINE(int) pj_isascii(unsigned char c) { return c<128; }\n\n/** \n * Returns a non-zero value if c is a particular representation of \n * a decimal-digit character.\n * @param c     The integer character to test.\n * @return      Non-zero value if c is a particular representation of \n *              a decimal-digit character.\n */\nPJ_INLINE(int) pj_isdigit(unsigned char c) { return isdigit(c); }\n\n/** \n * Returns a non-zero value if c is a particular representation of \n * a space character (0x09 - 0x0D or 0x20).\n * @param c     The integer character to test.\n * @return      Non-zero value if c is a particular representation of \n *              a space character (0x09 - 0x0D or 0x20).\n */\nPJ_INLINE(int) pj_isspace(unsigned char c) { return isspace(c); }\n\n/** \n * Returns a non-zero value if c is a particular representation of \n * a lowercase character.\n * @param c     The integer character to test.\n * @return      Non-zero value if c is a particular representation of \n *              a lowercase character.\n */\nPJ_INLINE(int) pj_islower(unsigned char c) { return islower(c); }\n\n\n/** \n * Returns a non-zero value if c is a particular representation of \n * a uppercase character.\n * @param c     The integer character to test.\n * @return      Non-zero value if c is a particular representation of \n *              a uppercase character.\n */\nPJ_INLINE(int) pj_isupper(unsigned char c) { return isupper(c); }\n\n/**\n * Returns a non-zero value if c is a either a space (' ') or horizontal\n * tab ('\\\\t') character.\n * @param c     The integer character to test.\n * @return      Non-zero value if c is a either a space (' ') or horizontal\n *              tab ('\\\\t') character.\n */\nPJ_INLINE(int) pj_isblank(unsigned char c) { return isblank(c); }\n\n/**\n * Converts character to lowercase.\n * @param c     The integer character to convert.\n * @return      Lowercase character of c.\n */\nPJ_INLINE(int) pj_tolower(unsigned char c) { return tolower(c); }\n\n/**\n * Converts character to uppercase.\n * @param c     The integer character to convert.\n * @return      Uppercase character of c.\n */\nPJ_INLINE(int) pj_toupper(unsigned char c) { return toupper(c); }\n\n/**\n * Returns a non-zero value if c is a particular representation of \n * an hexadecimal digit character.\n * @param c     The integer character to test.\n * @return      Non-zero value if c is a particular representation of \n *              an hexadecimal digit character.\n */\nPJ_INLINE(int) pj_isxdigit(unsigned char c){ return isxdigit(c); }\n\n/**\n * Array of hex digits, in lowerspace.\n */\n/*extern char pj_hex_digits[];*/\n#define pj_hex_digits\t\"0123456789abcdef\"\n\n/**\n * Convert a value to hex representation.\n * @param value\t    Integral value to convert.\n * @param p\t    Buffer to hold the hex representation, which must be\n *\t\t    at least two bytes length.\n */\nPJ_INLINE(void) pj_val_to_hex_digit(unsigned value, char *p)\n{\n    *p++ = pj_hex_digits[ (value & 0xF0) >> 4 ];\n    *p   = pj_hex_digits[ (value & 0x0F) ];\n}\n\n/**\n * Convert hex digit c to integral value.\n * @param c\tThe hex digit character.\n * @return\tThe integral value between 0 and 15.\n */\nPJ_INLINE(unsigned) pj_hex_digit_to_val(unsigned char c)\n{\n    if (c <= '9')\n\treturn (c-'0') & 0x0F;\n    else if (c <= 'F')\n\treturn  (c-'A'+10) & 0x0F;\n    else\n\treturn (c-'a'+10) & 0x0F;\n}\n\n/** @} */\n\nPJ_END_DECL\n\n#endif\t/* __PJ_CTYPE_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/doxygen.h",
    "content": "/* $Id: doxygen.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_DOXYGEN_H__\n#define __PJ_DOXYGEN_H__\n\n/**\n * @file doxygen.h\n * @brief Doxygen's mainpage.\n */\n\n/*////////////////////////////////////////////////////////////////////////// */\n/*\n\tINTRODUCTION PAGE\n */\n\n/**\n * @mainpage Welcome to PJLIB!\n *\n * @section intro_sec What is PJLIB\n *\n * PJLIB is an Open Source, small footprint framework library written in C for \n * making scalable applications. Because of its small footprint, it can be used\n * in embedded applications (we hope so!), but yet the library is also aimed for\n * facilitating the creation of high performance protocol stacks.\n *\n * PJLIB is released under GPL terms.\n *\n * @section download_sec Download\n *\n * PJLIB and all documentation can be downloaded from \n * http://www.pjsip.org.\n *\n *\n * @section how_to_use_sec About This Documentation\n *\n * This document is generated directly from PJLIB source file using\n * \\a doxygen (http://www.doxygen.org). Doxygen is a great (and free!) \n * tools for generating such documentation.\n *\n *\n * @subsection find_samples_subsec How to Read This Document\n *\n * This documentation is laid out more to be a reference guide instead\n * of tutorial, therefore first time users may find it difficult to\n * grasp PJLIB by reading this document alone.\n *\n * However, we've tried our best to make this document easy to follow.\n * For first time users, we would suggest that you follow these steps\n * when reading this documentation:\n *\n *  - continue reading this introduction chapter. At the end of this\n *    chapter, you'll find section called \\ref pjlib_fundamentals_sec\n *    which should guide you to understand basic things about PJLIB.\n *\n *  - find information about specific features that you want to use\n *    in PJLIB. Use the <b>Module Index</b> to find out about all \n *    features in PJLIB (if you're browsing the HTML documentation,\n *    click on the \\a Module link on top of the page, or if you're\n *    reading the PDF documentation, click on \\a Module \\a Documentation\n *    on the navigation pane on the left).\n *\n * @subsection doc_organize_sec How To's\n *\n * Please find below links to specific tasks that you probably\n * want to do:\n *\n *  - <b>How to Build PJLIB</b>\n *\\n\n * Please refer to \\ref pjlib_build_sys_pg page for more information.\n *\n *  - <b>How to Use PJLIB in My Application</b>\n *\\n\n * Please refer to \\ref configure_app_sec for more information.\n *\n *  - <b>How to Port PJLIB</b>\n *\\n\n * Please refer to \\ref porting_pjlib_pg page.\n *\n *  - <b>Where to Read Samples Documentation</b>\n *\\n\n * Most of the modules provide link to the corresponding sample file.\n * Alternatively, to get the list of all examples, you can click on \n * <b>Related Pages</b> on the top of HTML document or on \n * <b>PJLIB Page Documentation</b> on navigation pane of your PDF reader.\n *\n *  - <b>How to Submit Code to PJLIB Project</b>\n *\\n\n * Please read \\ref pjlib_coding_convention_page before submitting\n * your code. Send your code as patch against current Subversion tree\n * to the appropriate mailing list.\n *\n *\n * @section features_sec Features\n *\n * @subsection open_source_feat It's Open Source!\n *\n * PJLIB is currently released on GPL license, but other arrangements\n * can be made with the author.\n *\n * @subsection extreme_portable_feat Extreme Portability\n *\n * PJLIB is designed to be extremely portable. It can run on any kind\n * of processors (16-bit, 32-bit, or 64-bit, big or little endian, single\n * or multi-processors) and operating systems. Floating point or no\n * floating point. Multi-threading or not.\n * It can even run in environment where no ANSI LIBC is available. \n *\n * Currently PJLIB is known to run on these platforms:\n *  - Win32/x86 (Win95/98/ME, NT/2000/XP/2003, mingw).\n *  - arm, WinCE and Windows Mobile.\n *  - Linux/x86, (user mode and as <b>kernel module</b>(!)).\n *  - Linux/alpha\n *  - Solaris/ultra.\n *  - MacOS X/powerpc\n *  - RTEMS (x86 and powerpc).\n *\n * And efforts is under way to port PJLIB on:\n *  - Symbian OS\n *\n *\n * @subsection small_size_feat Small in Size\n *\n * One of the primary objectives is to have library that is small in size for\n * typical embedded applications. As a rough guidance, we aim to keep the \n * library size below 100KB for it to be considered as small.\n * As the result, most of the functionalities in the library can be tailored\n * to meet the requirements; user can enable/disable specific functionalities\n * to get the desired size/performance/functionality balance.\n *\n * For more info, please see @ref pj_config.\n *\n *\n * @subsection big_perform_feat Big in Performance\n *\n * Almost everything in PJLIB is designed to achieve the highest possible\n * performance out of the target platform. \n *\n *\n * @subsection no_dyn_mem No Dynamic Memory Allocations\n *\n * The central idea of PJLIB is that for applications to run as fast as it can,\n * it should not use \\a malloc() at all, but instead should get the memory \n * from a preallocated storage pool. There are few things that can be \n * optimized with this approach:\n *\n *  - \\a alloc() is a O(1) operation.\n *  - no mutex is used inside alloc(). It is assumed that synchronization \n *    will be used in higher abstraction by application anyway.\n *  - no \\a free() is required. All chunks will be deleted when the pool is \n *    destroyed.\n *\n * The performance gained on some systems can be as high as 30x speed up\n * against \\a malloc() and \\a free() on certain configurations, but of\n * course your mileage may vary. \n *\n * For more information, see \\ref PJ_POOL_GROUP\n *\n * \n * @subsection os_abstract_feat Operating System Abstraction\n *\n * PJLIB has abstractions for features that are normally not portable \n * across operating systems: \n *  - @ref PJ_THREAD\n *\\n\n *    Portable thread manipulation.\n *  - @ref PJ_TLS\n *\\n\n *    Storing data in thread's private data.\n *  - @ref PJ_MUTEX\n *\\n\n *    Mutual exclusion protection.\n *  - @ref PJ_SEM\n *\\n\n *    Semaphores.\n *  - @ref PJ_ATOMIC\n *\\n\n *    Atomic variables and their operations.\n *  - @ref PJ_CRIT_SEC\n *\\n\n *    Fast locking of critical sections.\n *  - @ref PJ_LOCK\n *\\n\n *    High level abstraction for lock objects.\n *  - @ref PJ_EVENT\n *\\n\n *    Event object.\n *  - @ref PJ_TIME\n *\\n\n *    Portable time manipulation.\n *  - @ref PJ_TIMESTAMP\n *\\n\n *    High resolution time value.\n *  - etc.\n *\n *\n * @subsection ll_network_io_sec Low-Level Network I/O\n *\n * PJLIB has very portable abstraction and fairly complete set of API for\n * doing network I/O communications. At the lowest level, PJLIB provides:\n *\n *  - @ref PJ_SOCK\n *\\n\n *    A highly portable socket abstraction, runs on all kind of\n *    network APIs such as standard BSD socket, Windows socket, Linux\n *    \\b kernel socket, PalmOS networking API, etc.\n *\n *  - @ref pj_addr_resolve\n *\\n\n *    Portable address resolution, which implements #pj_gethostbyname().\n *\n *  - @ref PJ_SOCK_SELECT\n *\\n\n *    A portable \\a select() like API (#pj_sock_select()) which can be\n *    implemented with various back-end.\n *\n *\n *\n * @subsection timer_mgmt_sec Timer Management\n *\n * A passive framework for managing timer, see @ref PJ_TIMER for more info.\n * There is also function to retrieve high resolution timestamp\n * from the system (see @ref PJ_TIMESTAMP).\n *\n *\n * @subsection data_struct_sec Various Data Structures\n *\n * Various data structures are provided in the library:\n *\n *  - @ref PJ_PSTR\n *  - @ref PJ_ARRAY\n *  - @ref PJ_HASH\n *  - @ref PJ_LIST\n *  - @ref PJ_RBTREE\n *\n *\n * @subsection exception_sec Exception Construct\n *\n * A convenient TRY/CATCH like construct to propagate errors, which by\n * default are used by the @ref PJ_POOL_GROUP \"memory pool\" and \n * the lexical scanner in pjlib-util. The exception\n * construct can be used to write programs like below:\n *\n * <pre>\n *    #define SYNTAX_ERROR  1\n *\n *    PJ_TRY {\n *       msg = NULL;\n *       msg = parse_msg(buf, len);\n *    }\n *    PJ_CATCH ( SYNTAX_ERROR ) {\n *       .. handle error ..\n *    }\n *    PJ_END;\n * </pre>\n *\n * Please see @ref PJ_EXCEPT for more information.\n *\n *\n * @subsection logging_sec Logging Facility\n *\n * PJLIB @ref PJ_LOG consists of macros to write logging information to\n * some output device. Some of the features of the logging facility:\n *\n *  - the verbosity can be fine-tuned both at compile time (to control\n *    the library size) or run-time (to control the verbosity of the\n *    information).\n *  - output device is configurable (e.g. stdout, printk, file, etc.)\n *  - log decoration is configurable.\n *\n * See @ref PJ_LOG for more information.\n *\n *\n * @subsection guid_gen_sec Random and GUID Generation\n *\n * PJLIB provides facility to create random string \n * (#pj_create_random_string()) or globally unique identifier\n * (see @ref PJ_GUID).\n *\n *\n *\n * @section configure_app_sec Configuring Application to use PJLIB\n *\n * @subsection pjlib_compil_sec Building PJLIB\n *\n * Follow the instructions in \\ref pjlib_build_sys_pg to build\n * PJLIB.\n *\n * @subsection pjlib_compil_app_sec Building Applications with PJLIB\n *\n * Use the following settings when building applications with PJLIB.\n *\n * @subsubsection compil_inc_dir_sec Include Search Path\n *\n * Add this to your include search path ($PJLIB is PJLIB root directory):\n * <pre>\n *   $PJLIB/include\n * </pre>\n *\n * @subsubsection compil_inc_file_sec Include PJLIB Header\n *\n * To include all PJLIB headers:\n * \\verbatim\n    #include <pjlib.h>\n   \\endverbatim\n *\n * Alternatively, you can include individual PJLIB headers like this:\n * \\verbatim\n     #include <pj/log.h>\n     #include <pj/os.h>\n  \\endverbatim\n *\n *\n * @subsubsection compil_lib_dir_sec Library Path\n *\n * Add this to your library search path:\n * <pre>\n *   $PJLIB/lib\n * </pre>\n *\n * Then add the appropriate PJLIB library to your link specification. For\n * example, you would add \\c libpj-i386-linux-gcc.a when you're building\n * applications in Linux.\n *\n *\n * @subsection pjlib_fundamentals_sec Principles in Using PJLIB\n *\n * Few things that you \\b MUST do when using PJLIB, to make sure that\n * you create trully portable applications.\n *\n * @subsubsection call_pjlib_init_sec Call pj_init()\n *\n * Before you do anything else, call \\c pj_init(). This would make sure that\n * PJLIB system is properly set up.\n *\n * @subsubsection no_ansi_subsec Do NOT Use ANSI C\n *\n * Contrary to popular teaching, ANSI C (and LIBC) is not the most portable\n * library in the world, nor it's the most ubiquitous. For example, LIBC\n * is not available in Linux kernel. Also normally LIBC will be excluded\n * from compilation of RTOSes to reduce size.\n *\n * So for maximum portability, do NOT use ANSI C. Do not even try to include\n * any other header files outside <include/pj>. Stick with the functionalities\n * provided by PJLIB. \n *\n *\n * @subsubsection string_rep_subsubsec Use pj_str_t instead of C Strings\n *\n * PJLIB uses pj_str_t instead of normal C strings. You SHOULD follow this\n * convention too. Remember, ANSI string-h is not always available. And\n * PJLIB string is faster!\n *\n * @subsubsection mem_alloc_subsubsec Use Pool for Memory Allocations\n *\n * You MUST NOT use \\a malloc() or any other memory allocation functions.\n * Use PJLIB @ref PJ_POOL_GROUP instead! It's faster and most portable.\n *\n * @subsection logging_subsubsec Use Logging for Text Display\n *\n * DO NOT use <stdio.h> for text output. Use PJLIB @ref PJ_LOG instead.\n *\n *\n * @section porting_pjlib_sec0 Porting PJLIB\n *\n * Please see \\ref porting_pjlib_pg page on more information to port\n * PJLIB to new target.\n *\n * @section enjoy_sec Enjoy Using PJLIB!\n *\n * We hope that you find PJLIB usefull for your application. If you\n * have any questions, suggestions, critics, bug fixes, or anything\n * else, we would be happy to hear it.\n *\n * Enjoy using PJLIB!\n *\n * Benny Prijono < bennylp at pjsip dot org >\n */\n\n\n\n/*////////////////////////////////////////////////////////////////////////// */\n/*\n         CODING CONVENTION\n */\n\n/**\n * @page pjlib_coding_convention_page Coding Convention\n *\n * Before you submit your code/patches to be included with PJLIB, you must\n * make sure that your code is compliant with PJLIB coding convention.\n * <b>This is very important!</b> Otherwise we would not accept your code.\n *\n * @section coding_conv_editor_sec Editor Settings\n *\n * The single most important thing in the whole coding convention is editor \n * settings. It's more important than the correctness of your code (bugs will\n * only crash the system, but incorrect tab size is mental!).\n *\n * Kindly set your editor as follows:\n *  - tab size to \\b 8.\n *  - indentation to \\b 4.\n *\n * With \\c vi, you can do it with:\n * <pre>\n *  :se ts=8\n *  :se sts=4\n * </pre>\n *\n * You should replace tab with eight spaces.\n *\n * @section coding_conv_detail_sec Coding Style\n *\n * Coding style MUST strictly follow K&R style. The rest of coding style\n * must follow current style. You SHOULD be able to observe the style\n * currently used by PJLIB from PJLIB sources, and apply the style to your \n * code. If you're not able to do simple thing like to observe PJLIB\n * coding style from the sources, then logic dictates that your ability to\n * observe more difficult area in PJLIB such as memory allocation strategy, \n * concurrency, etc is questionable.\n *\n * @section coding_conv_comment_sec Commenting Your Code\n *\n * Public API (e.g. in header files) MUST have doxygen compliant comments.\n *\n */\n\n\n/*////////////////////////////////////////////////////////////////////////// */\n/*\n\tBUILDING AND INSTALLING PJLIB\n */\n\n\n\n/**\n * @page pjlib_build_sys_pg Building, and Installing PJLIB\n *\n * @section build_sys_install_sec Build and Installation\n *\n * \\note\n * <b>The most up-to-date information on building and installing PJLIB\n *  should be found in the website, under \"Getting Started\" document.\n *  More over, the new PJLIB build system is now based on autoconf,\n *  so some of the information here might not be relevant anymore \n *  (although most still are, since the autoconf script still use\n *  the old Makefile system as the backend).</b>\n *\n * @subsection build_sys_install_win32_sec Visual Studio\n *\n * The PJLIB Visual Studio workspace supports the building of PJLIB\n * for Win32 target. Although currently only the Visual Studio 6 Workspace is\n * actively maintained, developers with later version of Visual Studio\n * can easily imports VS6 workspace into their IDE.\n *\n * To start building PJLIB projects with Visual Studio 6 or later, open\n * the \\a workspace file in the corresponding \\b \\c build directory. You have\n * several choices on which \\a dsw file to open:\n \\verbatim\n  $PJPROJECT/pjlib/build/pjlib.dsw\n  $PJPROJECT/pjsip/build/pjsip.dsw\n ..etc\n \\endverbatim\n *\n * The easiest way is to open <tt>pjsip_apps.dsw</tt> file in \\b \\c $PJPROJECT/pjsip-apps/build\n * directory, and build pjsua project or the samples project. \n * However this will not build the complete projects. \n * For example, the PJLIB test is not included in this workspace. \n * To build the complete projects, you must\n * open and build each \\a dsw file in \\c build directory in each\n * subprojects. For example, to open the complete PJLIB workspace, open\n * <tt>pjlib.dsw</tt> in <tt>$PJPROJECT/pjlib/build</tt> directory.\n *\n *\n * @subsubsection config_site_create_vc_sec Create config_site.h\n *\n * The file <tt><b>$PJPROJECT/pjlib/include/pj/config_site.h</b></tt>\n * is supposed to contain configuration that is specific to your site/target.\n * This file is not part of PJLIB, so you must create it yourself. Normally\n * you just need to create a blank file.\n *\n * The reason why it's not included in PJLIB is so that you would not accidently\n * overwrite your site configuration.\n *\n * If you fail to do this, Visual C will complain with error like: \n *\n * <b>\"fatal error C1083: Cannot open include file: 'pj/config_site.h': No such file \n * or directory\"</b>.\n *\n * @subsubsection build_vc_subsubsec Build the Projects\n *\n * Just hit the build button!\n *\n *\n * @subsection build_sys_install_unix_sec Make System\n *\n * For other targets, PJLIB provides a rather comprehensive build system\n * that uses GNU \\a make (and only GNU \\a make will work). \n * Currently, the build system supports building * PJLIB for these targets:\n *  - i386/Win32/mingw\n *  - i386/Linux\n *  - i386/Linux (kernel)\n *  - alpha/linux\n *  - sparc/SunOS\n *  - etc..\n *\n *\n * @subsubsection build_req_sec Requirements\n *\n * In order to use the \\c make based build system, you MUST have:\n *\n *  - <b>GNU make</b>\n *\\n\n *    The Makefiles heavily utilize GNU make commands which most likely\n *    are not available in other \\c make system.\n *  - <b>bash</b> shell is recommended.\n *\\n\n *    Specificly, there is a command <tt>\"echo -n\"</tt> which may not work\n *    in other shells. This command is used when generating dependencies\n *    (<tt>make dep</tt>) and it's located in \n *    <tt>$PJPROJECT/build/rules.mak</tt>.\n *  - <b>ar</b>, <b>ranlib</b> from GNU binutils\n *\\n\n *    In your system has different <tt>ar</tt> or <tt>ranlib</tt> (e.g. they\n *    may have been installed as <tt>gar</tt> and <tt>granlib</tt>), then\n *    either you create the relevant symbolic links, <b>or</b> modify\n *    <tt>$PJPROJECT/build/cc-gcc.mak</tt> and rename <tt>ar</tt> and\n *    <tt>ranlib</tt> to the appropriate names.\n *  - <b>gcc</b> to generate dependency.\n *\\n\n *    Currently the build system uses <tt>\"gcc -MM\"</tt> to generate build\n *    dependencies. If <tt>gcc</tt> is not desired to generate dependency,\n *    then either you don't run <tt>make dep</tt>, <b>or</b> edit\n *    <tt>$PJPROJECT/build/rules.mak</tt> to calculate dependency using\n *    your prefered method. (And let me know when you do so so that I can\n *    update the file. :) )\n *\n * @subsubsection build_overview_sec Building the Project\n *\n * Generally, steps required to build the PJLIB are:\n *\n \\verbatim\n   $ cd /home/user/pjproject\n   $ ./configure\n   $ touch pjlib/include/pj/config_site.h\n   $ make dep\n   $ make\n \\endverbatim\n *\n * The above process will build all static libraries and all applications.\n *\n * \\note the <tt>configure</tt> script is not a proper autoconf script,\n * but rather a simple shell script to detect current host. This script\n * currently does not support cross-compilation.\n *\n * \\note For Linux kernel target, there are additional steps required, which\n * will be explained in section \\ref linux_kern_target_subsec.\n *\n * @subsubsection build_mak_sec Cross Compilation\n * \n * For cross compilation, you will need to edit the \\c build.mak file in \n * \\c $PJPROJECT root directory manually. Please see <b>README-configure</b> file\n * in the root directory for more information.\n *\n * For Linux kernel target, you are also required to declare the following\n * variables in this file:\n *\t- \\c KERNEL_DIR: full path of kernel source tree.\n *\t- \\c KERNEL_ARCH: kernel ARCH options (e.g. \"ARCH=um\"), or leave blank\n * \t     for default.\n *\t- \\c PJPROJECT_DIR: full path of PJPROJECT source tree.\n *\n * Apart from these, there are also additional steps required to build\n * Linux kernel target, which will be explained in \\ref linux_kern_target_subsec.\n *\n * @subsubsection build_dir_sec Files in \"build\" Directory\n *\n * The <tt>*.mak</tt> files in \\c $PJPROJECT/build directory are used to specify\n * the configuration for the specified compiler, target machine target \n * operating system, and host options. These files will be executed\n * (included) by \\a make during building process, depending on the values\n * specified in <b>$PJPROJECT/build.mak</b> file.\n *\n * Normally you don't need to edit these files, except when you're porting\n * PJLIB to new target.\n *\n * Below are the description of some files in this directory:\n *\n *  - <tt>rules.mak</tt>: contains generic rules always included during make.\n *  - <tt>cc-gcc.mak</tt>: rules when gcc is used for compiler.\n *  - <tt>cc-vc.mak</tt>: rules when MSVC compiler is used.\n *  - <tt>host-mingw.mak</tt>: rules for building in mingw host.\n *  - <tt>host-unix.mak</tt>: rules for building in Unix/Posix host.\n *  - <tt>host-win32.mak</tt>: rules for building in Win32 command console\n *    (only valid when VC is used).\n *  - <tt>m-i386.mak</tt>: rules when target machine is an i386 processor.\n *  - <tt>m-m68k.mak</tt>: rules when target machine is an m68k processor.\n *  - <tt>os-linux.mak</tt>: rules when target OS is Linux.\n *  - <tt>os-linux-kernel.mak</tt>: rules when PJLIB is to be build as\n *    part of Linux kernel.\n *  - <tt>os-win32.mak</tt>: rules when target OS is Win32.\n *\n *\n * @subsubsection config_site_create_sec Create config_site.h\n *\n * The file <tt><b>$PJPROJECT/pjlib/include/pj/config_site.h</b></tt>\n * is supposed to contain configuration that is specific to your site/target.\n * This file is not part of PJLIB, so you must create it yourself.\n *\n * The reason why it's not included in PJLIB is so that you would not accidently\n * overwrite your site configuration.\n *\n *\n * @subsubsection invoking_make_sec Invoking make\n *\n * Normally, \\a make is invoked in \\c build directory under each project.\n * For example, to build PJLIB, you would invoke \\a make in\n * \\c $PJPROJECT/pjlib/build directory like below:\n *\n \\verbatim\n   $ cd pjlib/build\n   $ make\n \\endverbatim\n *\n * Alternatively you may invoke <tt>make</tt> in <tt>$PJPROJECT</tt> \n * directory, to build all projects under that directory (e.g. \n * PJLIB, PJSIP, etc.).\n *\n *\n * @subsubsection linux_kern_target_subsec Linux Kernel Target\n *\n * \\note\n * <b>BUILDING APPLICATIONS IN LINUX KERNEL MODE IS A VERY DANGEROUS BUSINESS.\n * YOU MAY CRASH THE WHOLE OF YOUR SYSTEM, CORRUPT YOUR HARDISK, ETC. PJLIB\n * KERNEL MODULES ARE STILL IN EXPERIMENTAL PHASE. DO NOT RUN IT IN PRODUCTION\n * SYSTEMS OR OTHER SYSTEMS WHERE RISK OF LOSS OF DATA IS NOT ACCEPTABLE.\n * YOU HAVE BEEN WARNED.</b>\n *\n * \\note\n * <b>User Mode Linux (UML)</b> provides excellent way to experiment with Linux\n * kernel without risking the stability of the host system. See\n * http://user-mode-linux.sourceforge.net for details.\n *\n * \\note\n * I only use <b>UML</b> to experiment with PJLIB kernel modules.\n * <b>I wouldn't be so foolish to use my host Linux machine to experiment\n * with this.</b> \n *\n * \\note\n * You have been warned.\n *\n * For building PJLIB for Linux kernel target, there are additional steps required.\n * In general, the additional tasks are:\n *\t- Declare some more variables in <b><tt>build.mak</tt></b> file (this\n *        has been explained in \\ref build_mak_sec above).\n *      - Perform these two small modifications in kernel source tree.\n *\n * There are two small modification need to be applied to the kernel tree.\n *\n * <b>1. Edit <tt>Makefile</tt> in kernel root source tree.</b>\n *\n * Add the following lines at the end of the <tt>Makefile</tt> in your \n * <tt>$KERNEL_SRC</tt> dir:\n \\verbatim\nscript:\n       $(SCRIPT)\n \\endverbatim\n *\n * \\note Remember to replace spaces with <b>tab</b> in the Makefile.\n *\n * The modification above is needed to capture kernel's \\c $CFLAGS and \n * \\c $CFLAGS_MODULE which will be used for PJLIB's compilation.\n *\n * <b>2. Add Additional Exports.</b>\n *\n * We need the kernel to export some more symbols for our use. So we declare\n * the additional symbols to be exported in <tt>extra-exports.c</tt> file, and add\n * a this file to be compiled into the kernel:\n *\n *\t- Copy the file <tt>extra-exports.c</tt> from <tt>pjlib/src/pj</tt> \n *\t  directory to <tt>$KERNEL_SRC/kernel/</tt> directory.\n *\t- Edit <tt>Makefile</tt> in that directory, and add this line\n *        somewhere after the declaration of that variable:\n \\verbatim\nobj-y   += extra-exports.o\n \\endverbatim\n *\n * To illustrate what have been done in your kernel source tree, below\n * is screenshot of my kernel source tree _after_ the modification.\n *\n \\verbatim\n[root@vpc-linux linux-2.6.7]# pwd\n/usr/src/linux-2.6.7\n[root@vpc-linux linux-2.6.7]# \n[root@vpc-linux linux-2.6.7]# \n[root@vpc-linux linux-2.6.7]# tail Makefile \n\nendif   # skip-makefile\n\nFORCE:\n\n.PHONY: script\n\nscript:\n        $(SCRIPT)\n\n[root@vpc-linux linux-2.6.7]# \n[root@vpc-linux linux-2.6.7]# \n[root@vpc-linux linux-2.6.7]# head kernel/extra-exports.c \n#include <linux/module.h>\n#include <linux/syscalls.h>\n\nEXPORT_SYMBOL(sys_select);\n\nEXPORT_SYMBOL(sys_epoll_create);\nEXPORT_SYMBOL(sys_epoll_ctl);\nEXPORT_SYMBOL(sys_epoll_wait);\n\nEXPORT_SYMBOL(sys_socket);\n[root@vpc-linux linux-2.6.7]# \n[root@vpc-linux linux-2.6.7]# \n[root@vpc-linux linux-2.6.7]# head -15 kernel/Makefile \n#\n# Makefile for the linux kernel.\n#\n\nobj-y     = sched.o fork.o exec_domain.o panic.o printk.o profile.o \\\n            exit.o itimer.o time.o softirq.o resource.o \\\n            sysctl.o capability.o ptrace.o timer.o user.o \\\n            signal.o sys.o kmod.o workqueue.o pid.o \\\n            rcupdate.o intermodule.o extable.o params.o posix-timers.o \\\n            kthread.o\n\nobj-y   +=  extra-exports.o\n\nobj-$(CONFIG_FUTEX) += futex.o\nobj-$(CONFIG_GENERIC_ISA_DMA) += dma.o\n[root@vpc-linux linux-2.6.7]# \n\n \\endverbatim\n *\n * Then you must rebuild the kernel.\n * If you fail to do this, you won't be able to <b>insmod</b> pjlib.\n *\n * \\note You will see a lots of warning messages during pjlib-test compilation.\n * The warning messages complain about unresolved symbols which are defined\n * in pjlib module. You can safely ignore these warnings. However, you can not\n * ignore warnings about non-pjlib unresolved symbols.\n *\n * \n * @subsection makefile_explained_sec Makefile Explained\n *\n * The \\a Makefile for each project (e.g. PJLIB, PJSIP, etc) should be\n * very similar in the contents. The Makefile is located under \\c build\n * directory in each project subdir.\n *\n * @subsubsection pjlib_makefile_subsec PJLIB Makefile.\n *\n * Below is PJLIB's Makefile:\n *\n * \\include build/Makefile\n *\n * @subsubsection pjlib_os_makefile_subsec PJLIB os-linux.mak.\n *\n * Below is file <tt><b>os-linux.mak</b></tt> file in \n * <tt>$PJPROJECT/pjlib/build</tt> directory,\n * which is OS specific configuration file for Linux target that is specific \n * for PJLIB project. For \\b global OS specific configuration, please see\n * <tt>$PJPROJECT/build/os-*.mak</tt>.\n *\n * \\include build/os-linux.mak\n *\n */\n\n\n/*////////////////////////////////////////////////////////////////////////// */\n/*\n         PORTING PJLIB\n */\n\n\n\n/**\n * @page porting_pjlib_pg Porting PJLIB\n *\n * \\note\n * <b>Since version 0.5.8, PJLIB build system is now based on autoconf, so\n * most of the time we shouldn't need to apply the tweakings below to get\n * PJLIB working on a new platform. However, since the autoconf build system\n * still uses the old Makefile build system, the information below may still\n * be useful for reference.\n * </b>\n *\n * @section new_arch_sec Porting to New CPU Architecture\n *\n * Below is step-by-step guide to add support for new CPU architecture.\n * This sample is based on porting to Alpha architecture; however steps for \n * porting to other CPU architectures should be pretty similar. \n *\n * Also note that in this example, the operating system used is <b>Linux</b>.\n * Should you wish to add support for new operating system, then follow\n * the next section \\ref porting_os_sec.\n *\n * Step-by-step guide to port to new CPU architecture:\n *  - decide the name for the new architecture. In this case, we choose\n *    <tt><b>alpha</b></tt>.\n *  - edit file <tt>$PJPROJECT/build.mak</tt>, and add new section for\n *    the new target:\n *    <pre>\n *      #\n *      # Linux alpha, gcc\n *      #\n *      export MACHINE_NAME := <b>alpha</b>\n *      export OS_NAME := linux\n *      export CC_NAME := gcc\n *      export HOST_NAME := unix\n *    </pre>\n *\n *  - create a new file <tt>$PJPROJECT/build/<b>m-alpha</b>.mak</tt>.\n *    Alternatively create a copy from other file in this directory.\n *    The contents of this file will look something like:\n *    <pre>\n *      export M_CFLAGS := $(CC_DEF)<b>PJ_M_ALPHA=1</b>\n *      export M_CXXFLAGS :=\n *      export M_LDFLAGS :=\n *      export M_SOURCES :=\n *    </pre>\n *  - create a new file <tt>$PJPROJECT/pjlib/include/pj/compat/<b>m_alpha.h</b></tt>.\n *    Alternatively create a copy from other header file in this directory.\n *    The contents of this file will look something like:\n *    <pre>\n *      #define PJ_HAS_PENTIUM          0\n *      #define PJ_IS_LITTLE_ENDIAN     1\n *      #define PJ_IS_BIG_ENDIAN        0\n *    </pre>\n *  - edit <tt>pjlib/include/pj/<b>config.h</b></tt>. Add new processor\n *    configuration in this header file, like follows:\n *    <pre>\n *      ...\n *      #elif defined (PJ_M_ALPHA) && PJ_M_ALPHA != 0\n *      #   include <pj/compat/m_alpha.h>\n *      ...\n *    </pre>\n *  - done. Build PJLIB with:\n *    <pre>\n *      $ cd $PJPROJECT/pjlib/build\n *      $ make dep\n *      $ make clean\n *      $ make\n *    </pre>\n *\n * @section porting_os_sec Porting to New Operating System Target\n *\n * This section will try to give you rough guideline on how to\n * port PJLIB to a new target. As a sample, we give the target a name tag, \n * for example <tt><b>xos</b></tt> (for X OS). \n *\n * @subsection new_compat_os_h_file_sec Create New Compat Header File\n *\n * You'll need to create a new header file \n * <b><tt>include/pj/compat/os_xos.h</tt></b>. You can copy as a \n * template other header file and edit it accordingly.\n *\n * @subsection modify_config_h_file_sec Modify config.h\n *\n * Then modify file <b><tt>include/pj/config.h</tt></b> to include\n * this file accordingly (e.g. when macro <tt><b>PJ_XOS</b></tt> is\n * defined):\n *\n \\verbatim\n ...\n #elif defined(PJ_XOS)\n #  include <pj/compat/os_xos.h>\n #else\n #...\n \\endverbatim\n * \n * @subsection new_target_mak_file_sec Create New Global Make Config File\n *\n * Then you'll need to create global configuration file that\n * is specific for this OS, i.e. <tt><b>os-xos.mak</b></tt> in \n * <tt><b>$PJPROJECT/build</b></tt> directory.\n *\n * At very minimum, the file will normally need to define\n * <tt><b>PJ_XOS=1</b></tt> in the \\c CFLAGS section:\n *\n \\verbatim\n#\n# $PJPROJECT/build/os-xos.mak:\n#\nexport OS_CFLAGS   := $(CC_DEF)PJ_XOS=1\nexport OS_CXXFLAGS := \nexport OS_LDFLAGS  :=\nexport OS_SOURCES  := \n \\endverbatim\n *\n *\n * @subsection new_target_prj_mak_file_sec Create New Project's Make Config File\n *\n * Then you'll need to create xos-specific configuration file\n * for PJLIB. This file is also named <tt><b>os-xos.mak</b></tt>,\n * but its located in <tt><b>pjlib/build</b></tt> directory.\n * This file will specify source files that are specific to\n * this OS to be included in the build process.\n *\n * Below is a sample:\n \\verbatim\n#\n# pjlib/build/os-xos.mak:\n#  XOS specific configuration for PJLIB.\n#\nexport PJLIB_OBJS += \tos_core_xos.o \\\n                        os_error_unix.o \\\n                        os_time_ansi.o\nexport TEST_OBJS +=\tmain.o\nexport TARGETS\t    =\tpjlib pjlib-test\n \\endverbatim\n *\n * @subsection new_target_src_sec Create and Edit Source Files\n *\n * You'll normally need to create at least these files:\n *  - <tt><b>os_core_xos.c</b></tt>: core OS specific\n *    functionality.\n *  - <tt><b>os_timestamp_xos.c</b></tt>: how to get timestamp\n *    in this OS.\n *\n * Depending on how things are done in your OS, you may need\n * to create these files:\n *  - <tt><b>os_error_*.c</b></tt>: how to manipulate\n *    OS error codes. Alternatively you may use existing\n *    <tt>os_error_unix.c</tt> if the OS has \\c errno and\n *    \\c strerror() function.\n *  - <tt><b>ioqueue_*.c</b></tt>: if the OS has specific method\n *    to perform asynchronous I/O. Alternatively you may\n *    use existing <tt>ioqueue_select.c</tt> if the OS supports\n *    \\c select() function call.\n *  - <tt><b>sock_*.c</b></tt>: if the OS has specific method\n *    to perform socket communication. Alternatively you may\n *    use existing <tt>sock_bsd.c</tt> if the OS supports\n *    BSD socket API, and edit <tt>include/pj/compat/socket.h</tt>\n *    file accordingly.\n *\n * You will also need to check various files in \n * <tt><b>include/pj/compat/*.h</b></tt>, to see if they're \n * compatible with your OS.\n *\n * @subsection new_target_build_file_sec Build The Project\n *\n * After basic building blocks have been created for the OS, then\n * the easiest way to see which parts need to be fixed is by building\n * the project and see the error messages.\n *\n * @subsection new_target_edit_vs_new_file_sec Editing Existing Files vs Creating New File\n *\n * When you encounter compatibility errors in PJLIB during porting,\n * you have three options on how to fix the error:\n *  - edit the existing <tt>*.c</tt> file, and give it <tt>#ifdef</tt>\n *    switch for the new OS, or\n *  - edit <tt>include/pj/compat/*.h</tt> instead, or\n *  - create a totally new file.\n *\n * Basicly there is no strict rule on which approach is the best\n * to use, however the following guidelines may be used:\n *  - if the file is expected to be completely different than\n *    any existing file, then perhaps you should create a completely\n *    new file. For example, file <tt>os_core_xxx.c</tt> will \n *    normally be different for each OS flavour.\n *  - if the difference can be localized in <tt>include/compat</tt>\n *    header file, and existing <tt>#ifdef</tt> switch is there,\n *    then preferably you should edit this <tt>include/compat</tt>\n *    header file.\n *  - if the existing <tt>*.c</tt> file has <tt>#ifdef</tt> switch,\n *    then you may add another <tt>#elif</tt> switch there. This\n *    normally is used for behaviors that are not totally\n *    different on each platform.\n *  - other than that above, use your own judgement on whether\n *    to edit the file or create new file etc.\n */\n\n#endif\t/* __PJ_DOXYGEN_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/errno.h",
    "content": "/* $Id: errno.h 4461 2013-04-05 03:02:19Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_ERRNO_H__\n#define __PJ_ERRNO_H__\n\n/**\n * @file errno.h\n * @brief PJLIB Error Subsystem\n */\n#include <pj/types.h>\n#include <pj/compat/errno.h>\n#include <stdarg.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup pj_errno Error Subsystem\n * @{\n *\n * The PJLIB Error Subsystem is a framework to unify all error codes\n * produced by all components into a single error space, and provide\n * uniform set of APIs to access them. With this framework, any error\n * codes are encoded as pj_status_t value. The framework is extensible,\n * application may register new error spaces to be recognized by\n * the framework.\n *\n * @section pj_errno_retval Return Values\n *\n * All functions that returns @a pj_status_t returns @a PJ_SUCCESS if the\n * operation was completed successfully, or non-zero value to indicate \n * error. If the error came from operating system, then the native error\n * code is translated/folded into PJLIB's error namespace by using\n * #PJ_STATUS_FROM_OS() macro. The function will do this automatically\n * before returning the error to caller.\n *\n * @section err_services Retrieving and Displaying Error Messages\n *\n * The framework provides the following APIs to retrieve and/or display\n * error messages:\n *\n *   - #pj_strerror(): this is the base API to retrieve error string\n *      description for the specified pj_status_t error code.\n *\n *   - #PJ_PERROR() macro: use this macro similar to PJ_LOG to format\n *      an error message and display them to the log\n *\n *   - #pj_perror(): this function is similar to PJ_PERROR() but unlike\n *      #PJ_PERROR(), this function will always be included in the\n *      link process. Due to this reason, prefer to use #PJ_PERROR()\n *      if the application is concerned about the executable size.\n *\n * Application MUST NOT pass native error codes (such as error code from\n * functions like GetLastError() or errno) to PJLIB functions expecting\n * @a pj_status_t.\n *\n * @section err_extending Extending the Error Space\n *\n * Application may register new error space to be recognized by the\n * framework by using #pj_register_strerror(). Use the range started\n * from PJ_ERRNO_START_USER to avoid conflict with existing error\n * spaces.\n *\n */\n\n/**\n * Guidelines on error message length.\n */\n#define PJ_ERR_MSG_SIZE  80\n\n/**\n * Buffer for title string of #PJ_PERROR().\n */\n#ifndef PJ_PERROR_TITLE_BUF_SIZE\n#   define PJ_PERROR_TITLE_BUF_SIZE\t120\n#endif\n\n\n/**\n * Get the last platform error/status, folded into pj_status_t.\n * @return\tOS dependent error code, folded into pj_status_t.\n * @remark\tThis function gets errno, or calls GetLastError() function and\n *\t\tconvert the code into pj_status_t with PJ_STATUS_FROM_OS. Do\n *\t\tnot call this for socket functions!\n * @see\tpj_get_netos_error()\n */\nPJ_DECL(pj_status_t) pj_get_os_error(void);\n\n/**\n * Set last error.\n * @param code\tpj_status_t\n */\nPJ_DECL(void) pj_set_os_error(pj_status_t code);\n\n/**\n * Get the last error from socket operations.\n * @return\tLast socket error, folded into pj_status_t.\n */\nPJ_DECL(pj_status_t) pj_get_netos_error(void);\n\n/**\n * Set error code.\n * @param code\tpj_status_t.\n */\nPJ_DECL(void) pj_set_netos_error(pj_status_t code);\n\n\n/**\n * Get the error message for the specified error code. The message\n * string will be NULL terminated.\n *\n * @param statcode  The error code.\n * @param buf\t    Buffer to hold the error message string.\n * @param bufsize   Size of the buffer.\n *\n * @return\t    The error message as NULL terminated string,\n *                  wrapped with pj_str_t.\n */\nPJ_DECL(pj_str_t) pj_strerror( pj_status_t statcode, \n\t\t\t       char *buf, pj_size_t bufsize);\n\n/**\n * A utility macro to print error message pertaining to the specified error \n * code to the log. This macro will construct the error message title \n * according to the 'title_fmt' argument, and add the error string pertaining\n * to the error code after the title string. A colon (':') will be added \n * automatically between the title and the error string.\n *\n * This function is similar to pj_perror() function, but has the advantage\n * that the function call can be omitted from the link process if the\n * log level argument is below PJ_LOG_MAX_LEVEL threshold.\n *\n * Note that the title string constructed from the title_fmt will be built on\n * a string buffer which size is PJ_PERROR_TITLE_BUF_SIZE, which normally is\n * allocated from the stack. By default this buffer size is small (around\n * 120 characters). Application MUST ensure that the constructed title string\n * will not exceed this limit, since not all platforms support truncating\n * the string.\n *\n * @see pj_perror()\n *\n * @param level\t    The logging verbosity level, valid values are 0-6. Lower\n *\t\t    number indicates higher importance, with level zero \n *\t\t    indicates fatal error. Only numeral argument is \n *\t\t    permitted (e.g. not variable).\n * @param arg\t    Enclosed 'printf' like arguments, with the following\n *\t\t    arguments:\n *\t\t     - the sender (NULL terminated string),\n *\t\t     - the error code (pj_status_t)\n *\t\t     - the format string (title_fmt), and \n *\t\t     - optional variable number of arguments suitable for the \n *\t\t       format string.\n *\n * Sample:\n * \\verbatim\n   PJ_PERROR(2, (__FILE__, PJ_EBUSY, \"Error making %s\", \"coffee\"));\n   \\endverbatim\n * @hideinitializer\n */\n#define PJ_PERROR(level,arg)\tdo { \\\n\t\t\t\t    pj_perror_wrapper_##level(arg); \\\n\t\t\t\t} while (0)\n\n/**\n * A utility function to print error message pertaining to the specified error \n * code to the log. This function will construct the error message title \n * according to the 'title_fmt' argument, and add the error string pertaining\n * to the error code after the title string. A colon (':') will be added \n * automatically between the title and the error string.\n *\n * Unlike the PJ_PERROR() macro, this function takes the \\a log_level argument\n * as a normal argument, unlike in PJ_PERROR() where a numeral value must be\n * given. However this function will always be linked to the executable,\n * unlike PJ_PERROR() which can be omitted when the level is below the \n * PJ_LOG_MAX_LEVEL.\n *\n * Note that the title string constructed from the title_fmt will be built on\n * a string buffer which size is PJ_PERROR_TITLE_BUF_SIZE, which normally is\n * allocated from the stack. By default this buffer size is small (around\n * 120 characters). Application MUST ensure that the constructed title string\n * will not exceed this limit, since not all platforms support truncating\n * the string.\n *\n * @see PJ_PERROR()\n */\nPJ_DECL(void) pj_perror(int log_level, const char *sender, pj_status_t status,\n\t\t        const char *title_fmt, ...);\n\n\n/**\n * Type of callback to be specified in #pj_register_strerror()\n *\n * @param e\t    The error code to lookup.\n * @param msg\t    Buffer to store the error message.\n * @param max\t    Length of the buffer.\n *\n * @return\t    The error string.\n */\ntypedef pj_str_t (*pj_error_callback)(pj_status_t e, char *msg, pj_size_t max);\n\n\n/**\n * Register strerror message handler for the specified error space.\n * Application can register its own handler to supply the error message\n * for the specified error code range. This handler will be called\n * by #pj_strerror().\n *\n * @param start_code\tThe starting error code where the handler should\n *\t\t\tbe called to retrieve the error message.\n * @param err_space\tThe size of error space. The error code range then\n *\t\t\twill fall in start_code to start_code+err_space-1\n *\t\t\trange.\n * @param f\t\tThe handler to be called when #pj_strerror() is\n *\t\t\tsupplied with error code that falls into this range.\n *\n * @return\t\tPJ_SUCCESS or the specified error code. The \n *\t\t\tregistration may fail when the error space has been\n *\t\t\toccupied by other handler, or when there are too many\n *\t\t\thandlers registered to PJLIB.\n */\nPJ_DECL(pj_status_t) pj_register_strerror(pj_status_t start_code,\n\t\t\t\t\t  pj_status_t err_space,\n\t\t\t\t\t  pj_error_callback f);\n\n/**\n * @hideinitializer\n * Return platform os error code folded into pj_status_t code. This is\n * the macro that is used throughout the library for all PJLIB's functions\n * that returns error from operating system. Application may override\n * this macro to reduce size (e.g. by defining it to always return \n * #PJ_EUNKNOWN).\n *\n * Note:\n *  This macro MUST return non-zero value regardless whether zero is\n *  passed as the argument. The reason is to protect logic error when\n *  the operating system doesn't report error codes properly.\n *\n * @param os_code   Platform OS error code. This value may be evaluated\n *\t\t    more than once.\n * @return\t    The platform os error code folded into pj_status_t.\n */\n#ifndef PJ_RETURN_OS_ERROR\n#   define PJ_RETURN_OS_ERROR(os_code)   (os_code ? \\\n\t\t\t\t\t    PJ_STATUS_FROM_OS(os_code) : -1)\n#endif\n\n\n/**\n * @hideinitializer\n * Fold a platform specific error into an pj_status_t code.\n *\n * @param e\tThe platform os error code.\n * @return\tpj_status_t\n * @warning\tMacro implementation; the syserr argument may be evaluated\n *\t\tmultiple times.\n */\n#if PJ_NATIVE_ERR_POSITIVE\n#   define PJ_STATUS_FROM_OS(e) (e == 0 ? PJ_SUCCESS : e + PJ_ERRNO_START_SYS)\n#else\n#   define PJ_STATUS_FROM_OS(e) (e == 0 ? PJ_SUCCESS : PJ_ERRNO_START_SYS - e)\n#endif\n\n/**\n * @hideinitializer\n * Fold an pj_status_t code back to the native platform defined error.\n *\n * @param e\tThe pj_status_t folded platform os error code.\n * @return\tpj_os_err_type\n * @warning\tmacro implementation; the statcode argument may be evaluated\n *\t\tmultiple times.  If the statcode was not created by \n *\t\tpj_get_os_error or PJ_STATUS_FROM_OS, the results are undefined.\n */\n#if PJ_NATIVE_ERR_POSITIVE\n#   define PJ_STATUS_TO_OS(e) (e == 0 ? PJ_SUCCESS : e - PJ_ERRNO_START_SYS)\n#else\n#   define PJ_STATUS_TO_OS(e) (e == 0 ? PJ_SUCCESS : PJ_ERRNO_START_SYS - e)\n#endif\n\n\n/**\n * @defgroup pj_errnum PJLIB's Own Error Codes\n * @ingroup pj_errno\n * @{\n */\n\n/**\n * Use this macro to generate error message text for your error code,\n * so that they look uniformly as the rest of the libraries.\n *\n * @param code\tThe error code\n * @param msg\tThe error test.\n */\n#ifndef PJ_BUILD_ERR\n#   define PJ_BUILD_ERR(code,msg) { code, msg \" (\" #code \")\" }\n#endif\n\n\n/**\n * @hideinitializer\n * Unknown error has been reported.\n */\n#define PJ_EUNKNOWN\t    (PJ_ERRNO_START_STATUS + 1)\t/* 70001 */\n/**\n * @hideinitializer\n * The operation is pending and will be completed later.\n */\n#define PJ_EPENDING\t    (PJ_ERRNO_START_STATUS + 2)\t/* 70002 */\n/**\n * @hideinitializer\n * Too many connecting sockets.\n */\n#define PJ_ETOOMANYCONN\t    (PJ_ERRNO_START_STATUS + 3)\t/* 70003 */\n/**\n * @hideinitializer\n * Invalid argument.\n */\n#define PJ_EINVAL\t    (PJ_ERRNO_START_STATUS + 4)\t/* 70004 */\n/**\n * @hideinitializer\n * Name too long (eg. hostname too long).\n */\n#define PJ_ENAMETOOLONG\t    (PJ_ERRNO_START_STATUS + 5)\t/* 70005 */\n/**\n * @hideinitializer\n * Not found.\n */\n#define PJ_ENOTFOUND\t    (PJ_ERRNO_START_STATUS + 6)\t/* 70006 */\n/**\n * @hideinitializer\n * Not enough memory.\n */\n#define PJ_ENOMEM\t    (PJ_ERRNO_START_STATUS + 7)\t/* 70007 */\n/**\n * @hideinitializer\n * Bug detected!\n */\n#define PJ_EBUG             (PJ_ERRNO_START_STATUS + 8)\t/* 70008 */\n/**\n * @hideinitializer\n * Operation timed out.\n */\n#define PJ_ETIMEDOUT        (PJ_ERRNO_START_STATUS + 9)\t/* 70009 */\n/**\n * @hideinitializer\n * Too many objects.\n */\n#define PJ_ETOOMANY         (PJ_ERRNO_START_STATUS + 10)/* 70010 */\n/**\n * @hideinitializer\n * Object is busy.\n */\n#define PJ_EBUSY            (PJ_ERRNO_START_STATUS + 11)/* 70011 */\n/**\n * @hideinitializer\n * The specified option is not supported.\n */\n#define PJ_ENOTSUP\t    (PJ_ERRNO_START_STATUS + 12)/* 70012 */\n/**\n * @hideinitializer\n * Invalid operation.\n */\n#define PJ_EINVALIDOP\t    (PJ_ERRNO_START_STATUS + 13)/* 70013 */\n/**\n * @hideinitializer\n * Operation is cancelled.\n */\n#define PJ_ECANCELLED\t    (PJ_ERRNO_START_STATUS + 14)/* 70014 */\n/**\n * @hideinitializer\n * Object already exists.\n */\n#define PJ_EEXISTS          (PJ_ERRNO_START_STATUS + 15)/* 70015 */\n/**\n * @hideinitializer\n * End of file.\n */\n#define PJ_EEOF\t\t    (PJ_ERRNO_START_STATUS + 16)/* 70016 */\n/**\n * @hideinitializer\n * Size is too big.\n */\n#define PJ_ETOOBIG\t    (PJ_ERRNO_START_STATUS + 17)/* 70017 */\n/**\n * @hideinitializer\n * Error in gethostbyname(). This is a generic error returned when\n * gethostbyname() has returned an error.\n */\n#define PJ_ERESOLVE\t    (PJ_ERRNO_START_STATUS + 18)/* 70018 */\n/**\n * @hideinitializer\n * Size is too small.\n */\n#define PJ_ETOOSMALL\t    (PJ_ERRNO_START_STATUS + 19)/* 70019 */\n/**\n * @hideinitializer\n * Ignored\n */\n#define PJ_EIGNORED\t    (PJ_ERRNO_START_STATUS + 20)/* 70020 */\n/**\n * @hideinitializer\n * IPv6 is not supported\n */\n#define PJ_EIPV6NOTSUP\t    (PJ_ERRNO_START_STATUS + 21)/* 70021 */\n/**\n * @hideinitializer\n * Unsupported address family\n */\n#define PJ_EAFNOTSUP\t    (PJ_ERRNO_START_STATUS + 22)/* 70022 */\n/**\n * @hideinitializer\n * Object no longer exists\n */\n#define PJ_EGONE\t    (PJ_ERRNO_START_STATUS + 23)/* 70023 */\n/**\n * @hideinitializer\n * Socket is stopped\n */\n#define PJ_ESOCKETSTOP\t    (PJ_ERRNO_START_STATUS + 24)/* 70024 */\n\n/** @} */   /* pj_errnum */\n\n/** @} */   /* pj_errno */\n\n\n/**\n * PJ_ERRNO_START is where PJLIB specific error values start.\n */\n#define PJ_ERRNO_START\t\t20000\n\n/**\n * PJ_ERRNO_SPACE_SIZE is the maximum number of errors in one of \n * the error/status range below.\n */\n#define PJ_ERRNO_SPACE_SIZE\t50000\n\n/**\n * PJ_ERRNO_START_STATUS is where PJLIB specific status codes start.\n * Effectively the error in this class would be 70000 - 119000.\n */\n#define PJ_ERRNO_START_STATUS\t(PJ_ERRNO_START + PJ_ERRNO_SPACE_SIZE)\n\n/**\n * PJ_ERRNO_START_SYS converts platform specific error codes into\n * pj_status_t values.\n * Effectively the error in this class would be 120000 - 169000.\n */\n#define PJ_ERRNO_START_SYS\t(PJ_ERRNO_START_STATUS + PJ_ERRNO_SPACE_SIZE)\n\n/**\n * PJ_ERRNO_START_USER are reserved for applications that use error\n * codes along with PJLIB codes.\n * Effectively the error in this class would be 170000 - 219000.\n */\n#define PJ_ERRNO_START_USER\t(PJ_ERRNO_START_SYS + PJ_ERRNO_SPACE_SIZE)\n\n\n/*\n * Below are list of error spaces that have been taken so far:\n *  - PJSIP_ERRNO_START\t\t(PJ_ERRNO_START_USER)\n *  - PJMEDIA_ERRNO_START\t(PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE)\n *  - PJSIP_SIMPLE_ERRNO_START\t(PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*2)\n *  - PJLIB_UTIL_ERRNO_START\t(PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*3)\n *  - PJNATH_ERRNO_START\t(PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*4)\n *  - PJMEDIA_AUDIODEV_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*5)\n *  - PJ_SSL_ERRNO_START\t   (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*6)\n *  - PJMEDIA_VIDEODEV_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*7)\n */\n\n/* Internal */\nvoid pj_errno_clear_handlers(void);\n\n\n/****** Internal for PJ_PERROR *******/\n\n/**\n * @def pj_perror_wrapper_1(arg)\n * Internal function to write log with verbosity 1. Will evaluate to\n * empty expression if PJ_LOG_MAX_LEVEL is below 1.\n * @param arg       Log expression.\n */\n#if PJ_LOG_MAX_LEVEL >= 1\n    #define pj_perror_wrapper_1(arg)\tpj_perror_1 arg\n    /** Internal function. */\n    PJ_DECL(void) pj_perror_1(const char *sender, pj_status_t status, \n\t\t\t      const char *title_fmt, ...);\n#else\n    #define pj_perror_wrapper_1(arg)\n#endif\n\n/**\n * @def pj_perror_wrapper_2(arg)\n * Internal function to write log with verbosity 2. Will evaluate to\n * empty expression if PJ_LOG_MAX_LEVEL is below 2.\n * @param arg       Log expression.\n */\n#if PJ_LOG_MAX_LEVEL >= 2\n    #define pj_perror_wrapper_2(arg)\tpj_perror_2 arg\n    /** Internal function. */\n    PJ_DECL(void) pj_perror_2(const char *sender, pj_status_t status, \n\t\t\t      const char *title_fmt, ...);\n#else\n    #define pj_perror_wrapper_2(arg)\n#endif\n\n/**\n * @def pj_perror_wrapper_3(arg)\n * Internal function to write log with verbosity 3. Will evaluate to\n * empty expression if PJ_LOG_MAX_LEVEL is below 3.\n * @param arg       Log expression.\n */\n#if PJ_LOG_MAX_LEVEL >= 3\n    #define pj_perror_wrapper_3(arg)\tpj_perror_3 arg\n    /** Internal function. */\n    PJ_DECL(void) pj_perror_3(const char *sender, pj_status_t status, \n\t\t\t      const char *title_fmt, ...);\n#else\n    #define pj_perror_wrapper_3(arg)\n#endif\n\n/**\n * @def pj_perror_wrapper_4(arg)\n * Internal function to write log with verbosity 4. Will evaluate to\n * empty expression if PJ_LOG_MAX_LEVEL is below 4.\n * @param arg       Log expression.\n */\n#if PJ_LOG_MAX_LEVEL >= 4\n    #define pj_perror_wrapper_4(arg)\tpj_perror_4 arg\n    /** Internal function. */\n    PJ_DECL(void) pj_perror_4(const char *sender, pj_status_t status, \n\t\t\t      const char *title_fmt, ...);\n#else\n    #define pj_perror_wrapper_4(arg)\n#endif\n\n/**\n * @def pj_perror_wrapper_5(arg)\n * Internal function to write log with verbosity 5. Will evaluate to\n * empty expression if PJ_LOG_MAX_LEVEL is below 5.\n * @param arg       Log expression.\n */\n#if PJ_LOG_MAX_LEVEL >= 5\n    #define pj_perror_wrapper_5(arg)\tpj_perror_5 arg\n    /** Internal function. */\n    PJ_DECL(void) pj_perror_5(const char *sender, pj_status_t status, \n\t\t\t      const char *title_fmt, ...);\n#else\n    #define pj_perror_wrapper_5(arg)\n#endif\n\n/**\n * @def pj_perror_wrapper_6(arg)\n * Internal function to write log with verbosity 6. Will evaluate to\n * empty expression if PJ_LOG_MAX_LEVEL is below 6.\n * @param arg       Log expression.\n */\n#if PJ_LOG_MAX_LEVEL >= 6\n    #define pj_perror_wrapper_6(arg)\tpj_perror_6 arg\n    /** Internal function. */\n    PJ_DECL(void) pj_perror_6(const char *sender, pj_status_t status, \n\t\t\t      const char *title_fmt, ...);\n#else\n    #define pj_perror_wrapper_6(arg)\n#endif\n\n\n\n\nPJ_END_DECL\n\n#endif\t/* __PJ_ERRNO_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/except.h",
    "content": "/* $Id: except.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_EXCEPTION_H__\n#define __PJ_EXCEPTION_H__\n\n/**\n * @file except.h\n * @brief Exception Handling in C.\n */\n\n#include <pj/types.h>\n#include <pj/compat/setjmp.h>\n#include <pj/log.h>\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJ_EXCEPT Exception Handling\n * @ingroup PJ_MISC\n * @{\n *\n * \\section pj_except_sample_sec Quick Example\n *\n * For the impatient, take a look at some examples:\n *  - @ref page_pjlib_samples_except_c\n *  - @ref page_pjlib_exception_test\n *\n * \\section pj_except_except Exception Handling\n *\n * This module provides exception handling syntactically similar to C++ in\n * C language. In Win32 systems, it uses Windows Structured Exception\n * Handling (SEH) if macro PJ_EXCEPTION_USE_WIN32_SEH is non-zero.\n * Otherwise it will use setjmp() and longjmp().\n *\n * On some platforms where setjmp/longjmp is not available, setjmp/longjmp \n * implementation is provided. See <pj/compat/setjmp.h> for compatibility.\n *\n * The exception handling mechanism is completely thread safe, so the exception\n * thrown by one thread will not interfere with other thread.\n *\n * The exception handling constructs are similar to C++. The blocks will be\n * constructed similar to the following sample:\n *\n * \\verbatim\n   #define NO_MEMORY     1\n   #define SYNTAX_ERROR  2\n  \n   int sample1()\n   {\n      PJ_USE_EXCEPTION;  // declare local exception stack.\n  \n      PJ_TRY {\n        ...// do something..\n      }\n      PJ_CATCH(NO_MEMORY) {\n        ... // handle exception 1\n      }\n      PJ_END;\n   }\n\n   int sample2()\n   {\n      PJ_USE_EXCEPTION;  // declare local exception stack.\n  \n      PJ_TRY {\n        ...// do something..\n      }\n      PJ_CATCH_ANY {\n         if (PJ_GET_EXCEPTION() == NO_MEMORY)\n\t    ...; // handle no memory situation\n\t else if (PJ_GET_EXCEPTION() == SYNTAX_ERROR)\n\t    ...; // handle syntax error\n      }\n      PJ_END;\n   }\n   \\endverbatim\n *\n * The above sample uses hard coded exception ID. It is @b strongly\n * recommended that applications request a unique exception ID instead\n * of hard coded value like above.\n *\n * \\section pj_except_reg Exception ID Allocation\n *\n * To ensure that exception ID (number) are used consistently and to\n * prevent ID collisions in an application, it is strongly suggested that \n * applications allocate an exception ID for each possible exception\n * type. As a bonus of this process, the application can identify\n * the name of the exception when the particular exception is thrown.\n *\n * Exception ID management are performed with the following APIs:\n *  - #pj_exception_id_alloc().\n *  - #pj_exception_id_free().\n *  - #pj_exception_id_name().\n *\n *\n * PJLIB itself automatically allocates one exception id, i.e.\n * #PJ_NO_MEMORY_EXCEPTION which is declared in <pj/pool.h>. This exception\n * ID is raised by default pool policy when it fails to allocate memory.\n *\n * CAVEATS:\n *  - unlike C++ exception, the scheme here won't call destructors of local\n *    objects if exception is thrown. Care must be taken when a function\n *    hold some resorce such as pool or mutex etc.\n *  - You CAN NOT make nested exception in one single function without using\n *    a nested PJ_USE_EXCEPTION. Samples:\n  \\verbatim\n\tvoid wrong_sample()\n\t{\n\t    PJ_USE_EXCEPTION;\n\n\t    PJ_TRY {\n\t\t// Do stuffs\n\t\t...\n\t    }\n\t    PJ_CATCH_ANY {\n\t\t// Do other stuffs\n\t\t....\n\t\t..\n\n\t\t// The following block is WRONG! You MUST declare \n\t\t// PJ_USE_EXCEPTION once again in this block.\n\t\tPJ_TRY {\n\t\t    ..\n\t\t}\n\t\tPJ_CATCH_ANY {\n\t\t    ..\n\t\t}\n\t\tPJ_END;\n\t    }\n\t    PJ_END;\n\t}\n\n  \\endverbatim\n\n *  - You MUST NOT exit the function inside the PJ_TRY block. The correct way\n *    is to return from the function after PJ_END block is executed. \n *    For example, the following code will yield crash not in this code,\n *    but rather in the subsequent execution of PJ_TRY block:\n  \\verbatim\n        void wrong_sample()\n\t{\n\t    PJ_USE_EXCEPTION;\n\n\t    PJ_TRY {\n\t\t// do some stuffs\n\t\t...\n\t\treturn;\t        <======= DO NOT DO THIS!\n\t    }\n\t    PJ_CATCH_ANY {\n\t    }\n\t    PJ_END;\n\t}\n  \\endverbatim\n  \n *  - You can not provide more than PJ_CATCH or PJ_CATCH_ANY nor use PJ_CATCH\n *    and PJ_CATCH_ANY for a single PJ_TRY.\n *  - Exceptions will always be caught by the first handler (unlike C++ where\n *    exception is only caught if the type matches.\n\n * \\section PJ_EX_KEYWORDS Keywords\n *\n * \\subsection PJ_THROW PJ_THROW(expression)\n * Throw an exception. The expression thrown is an integer as the result of\n * the \\a expression. This keyword can be specified anywhere within the \n * program.\n *\n * \\subsection PJ_USE_EXCEPTION PJ_USE_EXCEPTION\n * Specify this in the variable definition section of the function block \n * (or any blocks) to specify that the block has \\a PJ_TRY/PJ_CATCH exception \n * block. \n * Actually, this is just a macro to declare local variable which is used to\n * push the exception state to the exception stack.\n * Note: you must specify PJ_USE_EXCEPTION as the last statement in the\n * local variable declarations, since it may evaluate to nothing.\n *\n * \\subsection PJ_TRY PJ_TRY\n * The \\a PJ_TRY keyword is typically followed by a block. If an exception is\n * thrown in this block, then the execution will resume to the \\a PJ_CATCH \n * handler.\n *\n * \\subsection PJ_CATCH PJ_CATCH(expression)\n * The \\a PJ_CATCH is normally followed by a block. This block will be executed\n * if the exception being thrown is equal to the expression specified in the\n * \\a PJ_CATCH.\n *\n * \\subsection PJ_CATCH_ANY PJ_CATCH_ANY\n * The \\a PJ_CATCH is normally followed by a block. This block will be executed\n * if any exception was raised in the TRY block.\n *\n * \\subsection PJ_END PJ_END\n * Specify this keyword to mark the end of \\a PJ_TRY / \\a PJ_CATCH blocks.\n *\n * \\subsection PJ_GET_EXCEPTION PJ_GET_EXCEPTION(void)\n * Get the last exception thrown. This macro is normally called inside the\n * \\a PJ_CATCH or \\a PJ_CATCH_ANY block, altough it can be used anywhere where\n * the \\a PJ_USE_EXCEPTION definition is in scope.\n *\n * \n * \\section pj_except_examples_sec Examples\n *\n * For some examples on how to use the exception construct, please see:\n *  - @ref page_pjlib_samples_except_c\n *  - @ref page_pjlib_exception_test\n */\n\n/**\n * Allocate a unique exception id.\n * Applications don't have to allocate a unique exception ID before using\n * the exception construct. However, by doing so it ensures that there is\n * no collisions of exception ID.\n *\n * As a bonus, when exception number is acquired through this function,\n * the library can assign name to the exception (only if \n * PJ_HAS_EXCEPTION_NAMES is enabled (default is yes)) and find out the\n * exception name when it catches an exception.\n *\n * @param name      Name to be associated with the exception ID.\n * @param id        Pointer to receive the ID.\n *\n * @return          PJ_SUCCESS on success or PJ_ETOOMANY if the library \n *                  is running out out ids.\n */\nPJ_DECL(pj_status_t) pj_exception_id_alloc(const char *name,\n                                           pj_exception_id_t *id);\n\n/**\n * Free an exception id.\n *\n * @param id        The exception ID.\n *\n * @return          PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_exception_id_free(pj_exception_id_t id);\n\n/**\n * Retrieve name associated with the exception id.\n *\n * @param id        The exception ID.\n *\n * @return          The name associated with the specified ID.\n */\nPJ_DECL(const char*) pj_exception_id_name(pj_exception_id_t id);\n\n\n/** @} */\n\n#if defined(PJ_EXCEPTION_USE_WIN32_SEH) && PJ_EXCEPTION_USE_WIN32_SEH != 0\n/*****************************************************************************\n **\n ** IMPLEMENTATION OF EXCEPTION USING WINDOWS SEH\n **\n ****************************************************************************/\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n\nPJ_IDECL_NO_RETURN(void)\npj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN\n{\n    RaiseException(id,1,0,NULL);\n}\n\n#define PJ_USE_EXCEPTION    \n#define PJ_TRY\t\t    __try\n#define PJ_CATCH(id)\t    __except(GetExceptionCode()==id ? \\\n\t\t\t\t      EXCEPTION_EXECUTE_HANDLER : \\\n\t\t\t\t      EXCEPTION_CONTINUE_SEARCH)\n#define PJ_CATCH_ANY\t    __except(EXCEPTION_EXECUTE_HANDLER)\n#define PJ_END\t\t    \n#define PJ_THROW(id)\t    pj_throw_exception_(id)\n#define PJ_GET_EXCEPTION()  GetExceptionCode()\n\n\n#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0\n/*****************************************************************************\n **\n ** IMPLEMENTATION OF EXCEPTION USING SYMBIAN LEAVE/TRAP FRAMEWORK\n **\n ****************************************************************************/\n\n/* To include this file, the source file must be compiled as\n * C++ code!\n */\n#ifdef __cplusplus\n\nclass TPjException\n{\npublic:\n    int code_;\n};\n\n#define PJ_USE_EXCEPTION\n#define PJ_TRY\t\t\ttry\n//#define PJ_CATCH(id)\t\t\n#define PJ_CATCH_ANY\t\tcatch (const TPjException & pj_excp_)\n#define PJ_END\n#define PJ_THROW(x_id)\t\tdo { TPjException e; e.code_=x_id; throw e;} \\\n\t\t\t\twhile (0)\n#define PJ_GET_EXCEPTION()\tpj_excp_.code_\n\n#else\n\n#define PJ_USE_EXCEPTION\n#define PJ_TRY\t\t\t\t\n#define PJ_CATCH_ANY\t\tif (0)\n#define PJ_END\n#define PJ_THROW(x_id)\t\tdo { PJ_LOG(1,(\"PJ_THROW\",\" error code = %d\",x_id)); } while (0)\n#define PJ_GET_EXCEPTION()\t0\n\n#endif\t/* __cplusplus */\n\n#else\n/*****************************************************************************\n **\n ** IMPLEMENTATION OF EXCEPTION USING GENERIC SETJMP/LONGJMP\n **\n ****************************************************************************/\n\n/**\n * This structure (which should be invisible to user) manages the TRY handler\n * stack.\n */\nstruct pj_exception_state_t\n{    \n    pj_jmp_buf state;                   /**< jmp_buf.                    */\n    struct pj_exception_state_t *prev;  /**< Previous state in the list. */\n};\n\n/**\n * Throw exception.\n * @param id    Exception Id.\n */\nPJ_DECL_NO_RETURN(void) \npj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN;\n\n/**\n * Push exception handler.\n */\nPJ_DECL(void) pj_push_exception_handler_(struct pj_exception_state_t *rec);\n\n/**\n * Pop exception handler.\n */\nPJ_DECL(void) pj_pop_exception_handler_(struct pj_exception_state_t *rec);\n\n/**\n * Declare that the function will use exception.\n * @hideinitializer\n */\n#define PJ_USE_EXCEPTION    struct pj_exception_state_t pj_x_except__; int pj_x_code__\n\n/**\n * Start exception specification block.\n * @hideinitializer\n */\n#define PJ_TRY\t\t    if (1) { \\\n\t\t\t\tpj_push_exception_handler_(&pj_x_except__); \\\n\t\t\t\tpj_x_code__ = pj_setjmp(pj_x_except__.state); \\\n\t\t\t\tif (pj_x_code__ == 0)\n/**\n * Catch the specified exception Id.\n * @param id    The exception number to catch.\n * @hideinitializer\n */\n#define PJ_CATCH(id)\t    else if (pj_x_code__ == (id))\n\n/**\n * Catch any exception number.\n * @hideinitializer\n */\n#define PJ_CATCH_ANY\t    else\n\n/**\n * End of exception specification block.\n * @hideinitializer\n */\n#define PJ_END\t\t\tpj_pop_exception_handler_(&pj_x_except__); \\\n\t\t\t    } else {}\n\n/**\n * Throw exception.\n * @param exception_id  The exception number.\n * @hideinitializer\n */\n#define PJ_THROW(exception_id)\tpj_throw_exception_(exception_id)\n\n/**\n * Get current exception.\n * @return      Current exception code.\n * @hideinitializer\n */\n#define PJ_GET_EXCEPTION()\t(pj_x_code__)\n\n#endif\t/* PJ_EXCEPTION_USE_WIN32_SEH */\n\n\nPJ_END_DECL\n\n\n\n#endif\t/* __PJ_EXCEPTION_H__ */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/fifobuf.h",
    "content": "/* $Id: fifobuf.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_FIFOBUF_H__\n#define __PJ_FIFOBUF_H__\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\ntypedef struct pj_fifobuf_t pj_fifobuf_t;\nstruct pj_fifobuf_t\n{\n    char *first, *last;\n    char *ubegin, *uend;\n    int full;\n};\n\nPJ_DECL(void)\t     pj_fifobuf_init (pj_fifobuf_t *fb, void *buffer, unsigned size);\nPJ_DECL(unsigned)    pj_fifobuf_max_size (pj_fifobuf_t *fb);\nPJ_DECL(void*)\t     pj_fifobuf_alloc (pj_fifobuf_t *fb, unsigned size);\nPJ_DECL(pj_status_t) pj_fifobuf_unalloc (pj_fifobuf_t *fb, void *buf);\nPJ_DECL(pj_status_t) pj_fifobuf_free (pj_fifobuf_t *fb, void *buf);\n\nPJ_END_DECL\n\n#endif\t/* __PJ_FIFOBUF_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/file_access.h",
    "content": "/* $Id: file_access.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_FILE_ACCESS_H__\n#define __PJ_FILE_ACCESS_H__\n\n/**\n * @file file_access.h\n * @brief File manipulation and access.\n */\n#include <pj/types.h>\n\nPJ_BEGIN_DECL \n\n/**\n * @defgroup PJ_FILE_ACCESS File Access\n * @ingroup PJ_IO\n * @{\n *\n */\n\n/**\n * This structure describes file information, to be obtained by\n * calling #pj_file_getstat(). The time information in this structure\n * is in local time.\n */\ntypedef struct pj_file_stat\n{\n    pj_off_t        size;   /**< Total file size.               */\n    pj_time_val     atime;  /**< Time of last access.           */\n    pj_time_val     mtime;  /**< Time of last modification.     */\n    pj_time_val     ctime;  /**< Time of last creation.         */\n} pj_file_stat;\n\n\n/**\n * Returns non-zero if the specified file exists.\n *\n * @param filename      The file name.\n *\n * @return              Non-zero if the file exists.\n */\nPJ_DECL(pj_bool_t) pj_file_exists(const char *filename);\n\n/**\n * Returns the size of the file.\n *\n * @param filename      The file name.\n *\n * @return              The file size in bytes or -1 on error.\n */\nPJ_DECL(pj_off_t) pj_file_size(const char *filename);\n\n/**\n * Delete a file.\n *\n * @param filename      The filename.\n *\n * @return              PJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_file_delete(const char *filename);\n\n/**\n * Move a \\c oldname to \\c newname. If \\c newname already exists,\n * it will be overwritten.\n *\n * @param oldname       The file to rename.\n * @param newname       New filename to assign.\n *\n * @return              PJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_file_move( const char *oldname, \n                                   const char *newname);\n\n\n/**\n * Return information about the specified file. The time information in\n * the \\c stat structure will be in local time.\n *\n * @param filename      The filename.\n * @param stat          Pointer to variable to receive file information.\n *\n * @return              PJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_file_getstat(const char *filename, pj_file_stat *stat);\n\n\n/** @} */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJ_FILE_ACCESS_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/file_io.h",
    "content": "/* $Id: file_io.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_FILE_IO_H__\n#define __PJ_FILE_IO_H__\n\n/**\n * @file file_io.h\n * @brief Simple file I/O abstraction.\n */\n#include <pj/types.h>\n\nPJ_BEGIN_DECL \n\n/**\n * @defgroup PJ_FILE_IO File I/O\n * @ingroup PJ_IO\n * @{\n *\n * This file contains functionalities to perform file I/O. The file\n * I/O can be implemented with various back-end, either using native\n * file API or ANSI stream. \n *\n * @section pj_file_size_limit_sec Size Limits\n *\n * There may be limitation on the size that can be handled by the\n * #pj_file_setpos() or #pj_file_getpos() functions. The API itself\n * uses 64-bit integer for the file offset/position (where available); \n * however some backends (such as ANSI) may only support signed 32-bit \n * offset resolution.\n *\n * Reading and writing operation uses signed 32-bit integer to indicate\n * the size.\n *\n *\n */\n\n/**\n * These enumerations are used when opening file. Values PJ_O_RDONLY,\n * PJ_O_WRONLY, and PJ_O_RDWR are mutually exclusive. Value PJ_O_APPEND\n * can only be used when the file is opened for writing. \n */\nenum pj_file_access\n{\n    PJ_O_RDONLY     = 0x1101,   /**< Open file for reading.             */\n    PJ_O_WRONLY     = 0x1102,   /**< Open file for writing.             */\n    PJ_O_RDWR       = 0x1103,   /**< Open file for reading and writing. \n                                     File will be truncated.            */\n    PJ_O_APPEND     = 0x1108    /**< Append to existing file.           */\n};\n\n/**\n * The seek directive when setting the file position with #pj_file_setpos.\n */\nenum pj_file_seek_type\n{\n    PJ_SEEK_SET     = 0x1201,   /**< Offset from beginning of the file. */\n    PJ_SEEK_CUR     = 0x1202,   /**< Offset from current position.      */\n    PJ_SEEK_END     = 0x1203    /**< Size of the file plus offset.      */\n};\n\n/**\n * Open the file as specified in \\c pathname with the specified\n * mode, and return the handle in \\c fd. All files will be opened\n * as binary.\n *\n * @param pool          Pool to allocate memory for the new file descriptor.\n * @param pathname      The file name to open.\n * @param flags         Open flags, which is bitmask combination of\n *                      #pj_file_access enum. The flag must be either\n *                      PJ_O_RDONLY, PJ_O_WRONLY, or PJ_O_RDWR. When file\n *                      writing is specified, existing file will be \n *                      truncated unless PJ_O_APPEND is specified.\n * @param fd            The returned descriptor.\n *\n * @return              PJ_SUCCESS or the appropriate error code on error.\n */\nPJ_DECL(pj_status_t) pj_file_open(pj_pool_t *pool,\n                                  const char *pathname, \n                                  unsigned flags,\n                                  pj_oshandle_t *fd);\n\n/**\n * Close an opened file descriptor.\n *\n * @param fd            The file descriptor.\n *\n * @return              PJ_SUCCESS or the appropriate error code on error.\n */\nPJ_DECL(pj_status_t) pj_file_close(pj_oshandle_t fd);\n\n/**\n * Write data with the specified size to an opened file.\n *\n * @param fd            The file descriptor.\n * @param data          Data to be written to the file.\n * @param size          On input, specifies the size of data to be written.\n *                      On return, it contains the number of data actually\n *                      written to the file.\n *\n * @return              PJ_SUCCESS or the appropriate error code on error.\n */\nPJ_DECL(pj_status_t) pj_file_write(pj_oshandle_t fd,\n                                   const void *data,\n                                   pj_ssize_t *size);\n\n/**\n * Read data from the specified file. When end-of-file condition is set,\n * this function will return PJ_SUCCESS but the size will contain zero.\n *\n * @param fd            The file descriptor.\n * @param data          Pointer to buffer to receive the data.\n * @param size          On input, specifies the maximum number of data to\n *                      read from the file. On output, it contains the size\n *                      of data actually read from the file. It will contain\n *                      zero when EOF occurs.\n *\n * @return              PJ_SUCCESS or the appropriate error code on error.\n *                      When EOF occurs, the return is PJ_SUCCESS but size\n *                      will report zero.\n */\nPJ_DECL(pj_status_t) pj_file_read(pj_oshandle_t fd,\n                                  void *data,\n                                  pj_ssize_t *size);\n\n/**\n * Set file position to new offset according to directive \\c whence.\n *\n * @param fd            The file descriptor.\n * @param offset        The new file position to set.\n * @param whence        The directive.\n *\n * @return              PJ_SUCCESS or the appropriate error code on error.\n */\nPJ_DECL(pj_status_t) pj_file_setpos(pj_oshandle_t fd,\n                                    pj_off_t offset,\n                                    enum pj_file_seek_type whence);\n\n/**\n * Get current file position.\n *\n * @param fd            The file descriptor.\n * @param pos           On return contains the file position as measured\n *                      from the beginning of the file.\n *\n * @return              PJ_SUCCESS or the appropriate error code on error.\n */\nPJ_DECL(pj_status_t) pj_file_getpos(pj_oshandle_t fd,\n                                    pj_off_t *pos);\n\n/**\n * Flush file buffers.\n *\n * @param fd\t\tThe file descriptor.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code on error.\n */\nPJ_DECL(pj_status_t) pj_file_flush(pj_oshandle_t fd);\n\n\n/** @} */\n\n\nPJ_END_DECL\n\n#endif  /* __PJ_FILE_IO_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/guid.h",
    "content": "/* $Id: guid.h 4208 2012-07-18 07:52:33Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_GUID_H__\n#define __PJ_GUID_H__\n\n\n/**\n * @file guid.h\n * @brief GUID Globally Unique Identifier.\n */\n#include <pj/types.h>\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJ_DS Data Structure.\n */\n/**\n * @defgroup PJ_GUID Globally Unique Identifier\n * @ingroup PJ_DS\n * @{\n *\n * This module provides API to create string that is globally unique.\n * If application doesn't require that strong requirement, it can just\n * use #pj_create_random_string() instead.\n */\n\n\n/**\n * PJ_GUID_STRING_LENGTH specifies length of GUID string. The value is\n * dependent on the algorithm used internally to generate the GUID string.\n * If real GUID generator is used, then the length will be between 32 and\n * 36 bytes. Application should not assume which algorithm will\n * be used by GUID generator.\n *\n * Regardless of the actual length of the GUID, it will not exceed\n * PJ_GUID_MAX_LENGTH characters.\n *\n * @see pj_GUID_STRING_LENGTH()\n * @see PJ_GUID_MAX_LENGTH\n */\nPJ_DECL_DATA(const unsigned) PJ_GUID_STRING_LENGTH;\n\n/**\n * Get #PJ_GUID_STRING_LENGTH constant.\n */\nPJ_DECL(unsigned) pj_GUID_STRING_LENGTH(void);\n\n/**\n * PJ_GUID_MAX_LENGTH specifies the maximum length of GUID string,\n * regardless of which algorithm to use.\n */\n#define PJ_GUID_MAX_LENGTH  36\n\n/**\n * Create a globally unique string, which length is PJ_GUID_STRING_LENGTH\n * characters. Caller is responsible for preallocating the storage used\n * in the string.\n *\n * @param str       The string to store the result.\n *\n * @return          The string.\n */\nPJ_DECL(pj_str_t*) pj_generate_unique_string(pj_str_t *str);\n\n/**\n * Create a globally unique string in lowercase, which length is\n * PJ_GUID_STRING_LENGTH characters. Caller is responsible for preallocating\n * the storage used in the string.\n *\n * @param str       The string to store the result.\n *\n * @return          The string.\n */\nPJ_DECL(pj_str_t*) pj_generate_unique_string_lower(pj_str_t *str);\n\n/**\n * Generate a unique string.\n *\n * @param pool\t    Pool to allocate memory from.\n * @param str\t    The string.\n */\nPJ_DECL(void) pj_create_unique_string(pj_pool_t *pool, pj_str_t *str);\n\n/**\n * Generate a unique string in lowercase.\n *\n * @param pool\t    Pool to allocate memory from.\n * @param str\t    The string.\n */\nPJ_DECL(void) pj_create_unique_string_lower(pj_pool_t *pool, pj_str_t *str);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif/* __PJ_GUID_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/hash.h",
    "content": "/* $Id: hash.h 4208 2012-07-18 07:52:33Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_HASH_H__\n#define __PJ_HASH_H__\n\n/**\n * @file hash.h\n * @brief Hash Table.\n */\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_HASH Hash Table\n * @ingroup PJ_DS\n * @{\n * A hash table is a dictionary in which keys are mapped to array positions by\n * hash functions. Having the keys of more than one item map to the same \n * position is called a collision. In this library, we will chain the nodes\n * that have the same key in a list.\n */\n\n/**\n * If this constant is used as keylen, then the key is interpreted as\n * NULL terminated string.\n */\n#define PJ_HASH_KEY_STRING\t((unsigned)-1)\n\n/**\n * This indicates the size of of each hash entry.\n */\n#define PJ_HASH_ENTRY_BUF_SIZE\t(3*sizeof(void*) + 2*sizeof(pj_uint32_t))\n\n/**\n * Type declaration for entry buffer, used by #pj_hash_set_np()\n */\ntypedef void *pj_hash_entry_buf[(PJ_HASH_ENTRY_BUF_SIZE+sizeof(void*)-1)/(sizeof(void*))];\n\n/**\n * This is the function that is used by the hash table to calculate hash value\n * of the specified key.\n *\n * @param hval\t    the initial hash value, or zero.\n * @param key\t    the key to calculate.\n * @param keylen    the length of the key, or PJ_HASH_KEY_STRING to treat \n *\t\t    the key as null terminated string.\n *\n * @return          the hash value.\n */\nPJ_DECL(pj_uint32_t) pj_hash_calc(pj_uint32_t hval, \n\t\t\t\t  const void *key, unsigned keylen);\n\n\n/**\n * Convert the key to lowercase and calculate the hash value. The resulting\n * string is stored in \\c result.\n *\n * @param hval      The initial hash value, normally zero.\n * @param result    Optional. Buffer to store the result, which must be enough\n *                  to hold the string.\n * @param key       The input key to be converted and calculated.\n *\n * @return          The hash value.\n */\nPJ_DECL(pj_uint32_t) pj_hash_calc_tolower(pj_uint32_t hval,\n                                          char *result,\n                                          const pj_str_t *key);\n\n/**\n * Create a hash table with the specified 'bucket' size.\n *\n * @param pool\tthe pool from which the hash table will be allocated from.\n * @param size\tthe bucket size, which will be round-up to the nearest 2^n-1\n *\n * @return the hash table.\n */\nPJ_DECL(pj_hash_table_t*) pj_hash_create(pj_pool_t *pool, unsigned size);\n\n\n/**\n * Get the value associated with the specified key.\n *\n * @param ht\t    the hash table.\n * @param key\t    the key to look for.\n * @param keylen    the length of the key, or PJ_HASH_KEY_STRING to use the\n *\t\t    string length of the key.\n * @param hval\t    if this argument is not NULL and the value is not zero,\n *\t\t    the value will be used as the computed hash value. If\n *\t\t    the argument is not NULL and the value is zero, it will\n *\t\t    be filled with the computed hash upon return.\n *\n * @return the value associated with the key, or NULL if the key is not found.\n */\nPJ_DECL(void *) pj_hash_get( pj_hash_table_t *ht,\n\t\t\t     const void *key, unsigned keylen,\n\t\t\t     pj_uint32_t *hval );\n\n\n/**\n * Variant of #pj_hash_get() with the key being converted to lowercase when\n * calculating the hash value.\n *\n * @see pj_hash_get()\n */\nPJ_DECL(void *) pj_hash_get_lower( pj_hash_table_t *ht,\n\t\t\t           const void *key, unsigned keylen,\n\t\t\t           pj_uint32_t *hval );\n\n\n/**\n * Associate/disassociate a value with the specified key. If value is not\n * NULL and entry already exists, the entry's value will be overwritten.\n * If value is not NULL and entry does not exist, a new one will be created\n * with the specified pool. Otherwise if value is NULL, entry will be\n * deleted if it exists.\n *\n * @param pool\t    the pool to allocate the new entry if a new entry has to be\n *\t\t    created.\n * @param ht\t    the hash table.\n * @param key\t    the key. If pool is not specified, the key MUST point to\n * \t\t    buffer that remains valid for the duration of the entry.\n * @param keylen    the length of the key, or PJ_HASH_KEY_STRING to use the \n *\t\t    string length of the key.\n * @param hval\t    if the value is not zero, then the hash table will use\n *\t\t    this value to search the entry's index, otherwise it will\n *\t\t    compute the key. This value can be obtained when calling\n *\t\t    #pj_hash_get().\n * @param value\t    value to be associated, or NULL to delete the entry with\n *\t\t    the specified key.\n */\nPJ_DECL(void) pj_hash_set( pj_pool_t *pool, pj_hash_table_t *ht,\n\t\t\t   const void *key, unsigned keylen, pj_uint32_t hval,\n\t\t\t   void *value );\n\n\n/**\n * Variant of #pj_hash_set() with the key being converted to lowercase when\n * calculating the hash value.\n *\n * @see pj_hash_set()\n */\nPJ_DECL(void) pj_hash_set_lower( pj_pool_t *pool, pj_hash_table_t *ht,\n\t\t\t         const void *key, unsigned keylen,\n                                 pj_uint32_t hval, void *value );\n\n\n/**\n * Associate/disassociate a value with the specified key. This function works\n * like #pj_hash_set(), except that it doesn't use pool (hence the np -- no \n * pool suffix). If new entry needs to be allocated, it will use the entry_buf.\n *\n * @param ht\t    the hash table.\n * @param key\t    the key.\n * @param keylen    the length of the key, or PJ_HASH_KEY_STRING to use the \n *\t\t    string length of the key.\n * @param hval\t    if the value is not zero, then the hash table will use\n *\t\t    this value to search the entry's index, otherwise it will\n *\t\t    compute the key. This value can be obtained when calling\n *\t\t    #pj_hash_get().\n * @param entry_buf Buffer which will be used for the new entry, when one needs\n *\t\t    to be created.\n * @param value\t    value to be associated, or NULL to delete the entry with\n *\t\t    the specified key.\n */\nPJ_DECL(void) pj_hash_set_np(pj_hash_table_t *ht,\n\t\t\t     const void *key, unsigned keylen, \n\t\t\t     pj_uint32_t hval, pj_hash_entry_buf entry_buf, \n\t\t\t     void *value);\n\n/**\n * Variant of #pj_hash_set_np() with the key being converted to lowercase\n * when calculating the hash value.\n *\n * @see pj_hash_set_np()\n */\nPJ_DECL(void) pj_hash_set_np_lower(pj_hash_table_t *ht,\n\t\t\t           const void *key, unsigned keylen,\n\t\t\t           pj_uint32_t hval,\n                                   pj_hash_entry_buf entry_buf,\n\t\t\t           void *value);\n\n/**\n * Get the total number of entries in the hash table.\n *\n * @param ht\tthe hash table.\n *\n * @return the number of entries in the hash table.\n */\nPJ_DECL(unsigned) pj_hash_count( pj_hash_table_t *ht );\n\n\n/**\n * Get the iterator to the first element in the hash table. \n *\n * @param ht\tthe hash table.\n * @param it\tthe iterator for iterating hash elements.\n *\n * @return the iterator to the hash element, or NULL if no element presents.\n */\nPJ_DECL(pj_hash_iterator_t*) pj_hash_first( pj_hash_table_t *ht,\n\t\t\t\t\t    pj_hash_iterator_t *it );\n\n\n/**\n * Get the next element from the iterator.\n *\n * @param ht\tthe hash table.\n * @param it\tthe hash iterator.\n *\n * @return the next iterator, or NULL if there's no more element.\n */\nPJ_DECL(pj_hash_iterator_t*) pj_hash_next( pj_hash_table_t *ht, \n\t\t\t\t\t   pj_hash_iterator_t *it );\n\n/**\n * Get the value associated with a hash iterator.\n *\n * @param ht\tthe hash table.\n * @param it\tthe hash iterator.\n *\n * @return the value associated with the current element in iterator.\n */\nPJ_DECL(void*) pj_hash_this( pj_hash_table_t *ht,\n\t\t\t     pj_hash_iterator_t *it );\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/ioqueue.h",
    "content": "/* $Id: ioqueue.h 4359 2013-02-21 11:18:36Z bennylp $\n */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_IOQUEUE_H__\n#define __PJ_IOQUEUE_H__\n\n/**\n * @file ioqueue.h\n * @brief I/O Dispatching Mechanism\n */\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_IO Input/Output\n * @brief Input/Output\n * @ingroup PJ_OS\n *\n * This section contains API building blocks to perform network I/O and \n * communications. If provides:\n *  - @ref PJ_SOCK\n *\\n\n *    A highly portable socket abstraction, runs on all kind of\n *    network APIs such as standard BSD socket, Windows socket, Linux\n *    \\b kernel socket, PalmOS networking API, etc.\n *\n *  - @ref pj_addr_resolve\n *\\n\n *    Portable address resolution, which implements #pj_gethostbyname().\n *\n *  - @ref PJ_SOCK_SELECT\n *\\n\n *    A portable \\a select() like API (#pj_sock_select()) which can be\n *    implemented with various back-ends.\n *\n *  - @ref PJ_IOQUEUE\n *\\n\n *    Framework for dispatching network events.\n *\n * For more information see the modules below.\n */\n\n/**\n * @defgroup PJ_IOQUEUE IOQueue: I/O Event Dispatching with Proactor Pattern\n * @ingroup PJ_IO\n * @{\n *\n * I/O Queue provides API for performing asynchronous I/O operations. It\n * conforms to proactor pattern, which allows application to submit an\n * asynchronous operation and to be notified later when the operation has\n * completed.\n *\n * The I/O Queue can work on both socket and file descriptors. For \n * asynchronous file operations however, one must make sure that the correct\n * file I/O back-end is used, because not all file I/O back-end can be\n * used with the ioqueue. Please see \\ref PJ_FILE_IO for more details.\n *\n * The framework works natively in platforms where asynchronous operation API\n * exists, such as in Windows NT with IoCompletionPort/IOCP. In other \n * platforms, the I/O queue abstracts the operating system's event poll API\n * to provide semantics similar to IoCompletionPort with minimal penalties\n * (i.e. per ioqueue and per handle mutex protection).\n *\n * The I/O queue provides more than just unified abstraction. It also:\n *  - makes sure that the operation uses the most effective way to utilize\n *    the underlying mechanism, to achieve the maximum theoritical\n *    throughput possible on a given platform.\n *  - choose the most efficient mechanism for event polling on a given\n *    platform.\n *\n * Currently, the I/O Queue is implemented using:\n *  - <tt><b>select()</b></tt>, as the common denominator, but the least \n *    efficient. Also the number of descriptor is limited to \n *    \\c PJ_IOQUEUE_MAX_HANDLES (which by default is 64).\n *  - <tt><b>/dev/epoll</b></tt> on Linux (user mode and kernel mode), \n *    a much faster replacement for select() on Linux (and more importantly\n *    doesn't have limitation on number of descriptors).\n *  - <b>I/O Completion ports</b> on Windows NT/2000/XP, which is the most \n *    efficient way to dispatch events in Windows NT based OSes, and most \n *    importantly, it doesn't have the limit on how many handles to monitor.\n *    And it works with files (not only sockets) as well.\n *\n *\n * \\section pj_ioqueue_concurrency_sec Concurrency Rules\n *\n * The ioqueue has been fine tuned to allow multiple threads to poll the\n * handles simultaneously, to maximize scalability when the application is\n * running on multiprocessor systems. When more than one threads are polling\n * the ioqueue and there are more than one handles are signaled, more than\n * one threads will execute the callback simultaneously to serve the events.\n * These parallel executions are completely safe when the events happen for\n * two different handles.\n *\n * However, with multithreading, care must be taken when multiple events \n * happen on the same handle, or when event is happening on a handle (and \n * the callback is being executed) and application is performing \n * unregistration to the handle at the same time.\n *\n * The treatments of above scenario differ according to the concurrency\n * setting that are applied to the handle.\n *\n * \\subsection pj_ioq_concur_set Concurrency Settings for Handles\n *\n * Concurrency can be set on per handle (key) basis, by using\n * #pj_ioqueue_set_concurrency() function. The default key concurrency value \n * for the handle is inherited from the key concurrency setting of the ioqueue, \n * and the key concurrency setting for the ioqueue can be changed by using\n * #pj_ioqueue_set_default_concurrency(). The default key concurrency setting \n * for ioqueue itself is controlled by compile time setting\n * PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY.\n *\n * Note that this key concurrency setting only controls whether multiple\n * threads are allowed to operate <b>on the same key</b> at the same time. \n * The ioqueue itself always allows multiple threads to enter the ioqeuue at \n * the same time, and also simultaneous callback calls to <b>differrent \n * keys</b> is always allowed regardless to the key concurrency setting.\n *\n * \\subsection pj_ioq_parallel Parallel Callback Executions for the Same Handle\n *\n * Note that when key concurrency is enabled (i.e. parallel callback calls on\n * the same key is allowed; this is the default setting), the ioqueue will only\n * perform simultaneous callback executions on the same key when the key has\n * invoked multiple pending operations. This could be done for example by\n * calling #pj_ioqueue_recvfrom() more than once on the same key, each with\n * the same key but different operation key (pj_ioqueue_op_key_t). With this\n * scenario, when multiple packets arrive on the key at the same time, more\n * than one threads may execute the callback simultaneously, each with the\n * same key but different operation key.\n *\n * When there is only one pending operation on the key (e.g. there is only one\n * #pj_ioqueue_recvfrom() invoked on the key), then events occuring to the\n * same key will be queued by the ioqueue, thus no simultaneous callback calls\n * will be performed.\n *\n * \\subsection pj_ioq_allow_concur Concurrency is Enabled (Default Value)\n *\n * The default setting for the ioqueue is to allow multiple threads to\n * execute callbacks for the same handle/key. This setting is selected to\n * promote good performance and scalability for application.\n *\n * However this setting has a major drawback with regard to synchronization,\n * and application MUST carefully follow the following guidelines to ensure \n * that parallel access to the key does not cause problems:\n *\n *  - Always note that callback may be called simultaneously for the same\n *    key.\n *  - <b>Care must be taken when unregistering a key</b> from the\n *    ioqueue. Application must take care that when one thread is issuing\n *    an unregistration, other thread is not simultaneously invoking the\n *    callback <b>to the same key</b>.\n *\\n\n *    This happens because the ioqueue functions are working with a pointer\n *    to the key, and there is a possible race condition where the pointer\n *    has been rendered invalid by other threads before the ioqueue has a\n *    chance to acquire mutex on it.\n *\n * \\subsection pj_ioq_disallow_concur Concurrency is Disabled\n *\n * Alternatively, application may disable key concurrency to make \n * synchronization easier. As noted above, there are three ways to control\n * key concurrency setting:\n *  - by controlling on per handle/key basis, with #pj_ioqueue_set_concurrency().\n *  - by changing default key concurrency setting on the ioqueue, with\n *    #pj_ioqueue_set_default_concurrency().\n *  - by changing the default concurrency on compile time, by declaring\n *    PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY macro to zero in your config_site.h\n *\n * \\section pj_ioqeuue_examples_sec Examples\n *\n * For some examples on how to use the I/O Queue, please see:\n *\n *  - \\ref page_pjlib_ioqueue_tcp_test\n *  - \\ref page_pjlib_ioqueue_udp_test\n *  - \\ref page_pjlib_ioqueue_perf_test\n */\n\n\n/**\n * This structure describes operation specific key to be submitted to\n * I/O Queue when performing the asynchronous operation. This key will\n * be returned to the application when completion callback is called.\n *\n * Application normally wants to attach it's specific data in the\n * \\c user_data field so that it can keep track of which operation has\n * completed when the callback is called. Alternatively, application can\n * also extend this struct to include its data, because the pointer that\n * is returned in the completion callback will be exactly the same as\n * the pointer supplied when the asynchronous function is called.\n */\ntypedef struct pj_ioqueue_op_key_t\n{ \n    void *internal__[32];           /**< Internal I/O Queue data.   */\n    void *activesock_data;\t    /**< Active socket data.\t    */\n    void *user_data;                /**< Application data.          */\n} pj_ioqueue_op_key_t;\n\n/**\n * This structure describes the callbacks to be called when I/O operation\n * completes.\n */\ntypedef struct pj_ioqueue_callback\n{\n    /**\n     * This callback is called when #pj_ioqueue_recv or #pj_ioqueue_recvfrom\n     * completes.\n     *\n     * @param key\t    The key.\n     * @param op_key        Operation key.\n     * @param bytes_read    >= 0 to indicate the amount of data read, \n     *                      otherwise negative value containing the error\n     *                      code. To obtain the pj_status_t error code, use\n     *                      (pj_status_t code = -bytes_read).\n     */\n    void (*on_read_complete)(pj_ioqueue_key_t *key, \n                             pj_ioqueue_op_key_t *op_key, \n                             pj_ssize_t bytes_read);\n\n    /**\n     * This callback is called when #pj_ioqueue_send or #pj_ioqueue_sendto\n     * completes.\n     *\n     * @param key\t    The key.\n     * @param op_key        Operation key.\n     * @param bytes_sent    >= 0 to indicate the amount of data written, \n     *                      otherwise negative value containing the error\n     *                      code. To obtain the pj_status_t error code, use\n     *                      (pj_status_t code = -bytes_sent).\n     */\n    void (*on_write_complete)(pj_ioqueue_key_t *key, \n                              pj_ioqueue_op_key_t *op_key, \n                              pj_ssize_t bytes_sent);\n\n    /**\n     * This callback is called when #pj_ioqueue_accept completes.\n     *\n     * @param key\t    The key.\n     * @param op_key        Operation key.\n     * @param sock          Newly connected socket.\n     * @param status\t    Zero if the operation completes successfully.\n     */\n    void (*on_accept_complete)(pj_ioqueue_key_t *key, \n                               pj_ioqueue_op_key_t *op_key, \n                               pj_sock_t sock, \n                               pj_status_t status);\n\n    /**\n     * This callback is called when #pj_ioqueue_connect completes.\n     *\n     * @param key\t    The key.\n     * @param status\t    PJ_SUCCESS if the operation completes successfully.\n     */\n    void (*on_connect_complete)(pj_ioqueue_key_t *key, \n                                pj_status_t status);\n} pj_ioqueue_callback;\n\n\n/**\n * Types of pending I/O Queue operation. This enumeration is only used\n * internally within the ioqueue.\n */\ntypedef enum pj_ioqueue_operation_e\n{\n    PJ_IOQUEUE_OP_NONE\t\t= 0,\t/**< No operation.          */\n    PJ_IOQUEUE_OP_READ\t\t= 1,\t/**< read() operation.      */\n    PJ_IOQUEUE_OP_RECV          = 2,    /**< recv() operation.      */\n    PJ_IOQUEUE_OP_RECV_FROM\t= 4,\t/**< recvfrom() operation.  */\n    PJ_IOQUEUE_OP_WRITE\t\t= 8,\t/**< write() operation.     */\n    PJ_IOQUEUE_OP_SEND          = 16,   /**< send() operation.      */\n    PJ_IOQUEUE_OP_SEND_TO\t= 32,\t/**< sendto() operation.    */\n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0\n    PJ_IOQUEUE_OP_ACCEPT\t= 64,\t/**< accept() operation.    */\n    PJ_IOQUEUE_OP_CONNECT\t= 128\t/**< connect() operation.   */\n#endif\t/* PJ_HAS_TCP */\n} pj_ioqueue_operation_e;\n\n\n/**\n * This macro specifies the maximum number of events that can be\n * processed by the ioqueue on a single poll cycle, on implementation\n * that supports it. The value is only meaningfull when specified\n * during PJLIB build.\n */\n#ifndef PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL\n#   define PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL     (16)\n#endif\n\n\n/**\n * This macro specifies the maximum event candidates collected by each\n * polling thread to be able to reach maximum number of processed events\n * (i.e: PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL) in each poll cycle.\n * An event candidate will be dispatched to application as event unless\n * it is already being dispatched by other polling thread. So in order to\n * anticipate such race condition, each poll operation should collects its\n * event candidates more than PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL, the\n * recommended value is (PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL *\n * number of polling threads).\n *\n * The value is only meaningfull when specified during PJLIB build and\n * is only effective on multiple polling threads environment.\n */\n#if !defined(PJ_IOQUEUE_MAX_CAND_EVENTS) || \\\n    PJ_IOQUEUE_MAX_CAND_EVENTS < PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL\n#   undef  PJ_IOQUEUE_MAX_CAND_EVENTS\n#   define PJ_IOQUEUE_MAX_CAND_EVENTS\tPJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL\n#endif\n\n\n/**\n * When this flag is specified in ioqueue's recv() or send() operations,\n * the ioqueue will always mark the operation as asynchronous.\n */\n#define PJ_IOQUEUE_ALWAYS_ASYNC\t    ((pj_uint32_t)1 << (pj_uint32_t)31)\n\n/**\n * Return the name of the ioqueue implementation.\n *\n * @return\t\tImplementation name.\n */\nPJ_DECL(const char*) pj_ioqueue_name(void);\n\n\n/**\n * Create a new I/O Queue framework.\n *\n * @param pool\t\tThe pool to allocate the I/O queue structure. \n * @param max_fd\tThe maximum number of handles to be supported, which \n *\t\t\tshould not exceed PJ_IOQUEUE_MAX_HANDLES.\n * @param ioqueue\tPointer to hold the newly created I/O Queue.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_create( pj_pool_t *pool, \n\t\t\t\t\tpj_size_t max_fd,\n\t\t\t\t\tpj_ioqueue_t **ioqueue);\n\n/**\n * Destroy the I/O queue.\n *\n * @param ioque\t        The I/O Queue to be destroyed.\n *\n * @return              PJ_SUCCESS if success.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_destroy( pj_ioqueue_t *ioque );\n\n/**\n * Set the lock object to be used by the I/O Queue. This function can only\n * be called right after the I/O queue is created, before any handle is\n * registered to the I/O queue.\n *\n * Initially the I/O queue is created with non-recursive mutex protection. \n * Applications can supply alternative lock to be used by calling this \n * function.\n *\n * @param ioque         The ioqueue instance.\n * @param lock          The lock to be used by the ioqueue.\n * @param auto_delete   In non-zero, the lock will be deleted by the ioqueue.\n *\n * @return              PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_set_lock( pj_ioqueue_t *ioque, \n\t\t\t\t\t  pj_lock_t *lock,\n\t\t\t\t\t  pj_bool_t auto_delete );\n\n/**\n * Set default concurrency policy for this ioqueue. If this function is not\n * called, the default concurrency policy for the ioqueue is controlled by \n * compile time setting PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY.\n *\n * Note that changing the concurrency setting to the ioqueue will only affect\n * subsequent key registrations. To modify the concurrency setting for\n * individual key, use #pj_ioqueue_set_concurrency().\n *\n * @param ioqueue\tThe ioqueue instance.\n * @param allow\t\tNon-zero to allow concurrent callback calls, or\n *\t\t\tPJ_FALSE to disallow it.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_set_default_concurrency(pj_ioqueue_t *ioqueue,\n\t\t\t\t\t\t\tpj_bool_t allow);\n\n/**\n * Register a socket to the I/O queue framework. \n * When a socket is registered to the IOQueue, it may be modified to use\n * non-blocking IO. If it is modified, there is no guarantee that this \n * modification will be restored after the socket is unregistered.\n *\n * @param pool\t    To allocate the resource for the specified handle, \n *\t\t    which must be valid until the handle/key is unregistered \n *\t\t    from I/O Queue.\n * @param ioque\t    The I/O Queue.\n * @param sock\t    The socket.\n * @param user_data User data to be associated with the key, which can be\n *\t\t    retrieved later.\n * @param cb\t    Callback to be called when I/O operation completes. \n * @param key       Pointer to receive the key to be associated with this\n *                  socket. Subsequent I/O queue operation will need this\n *                  key.\n *\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,\n\t\t\t\t\t       pj_ioqueue_t *ioque,\n\t\t\t\t\t       pj_sock_t sock,\n\t\t\t\t\t       void *user_data,\n\t\t\t\t\t       const pj_ioqueue_callback *cb,\n                                               pj_ioqueue_key_t **key );\n\n/**\n * Variant of pj_ioqueue_register_sock() with additional group lock parameter.\n * If group lock is set for the key, the key will add the reference counter\n * when the socket is registered and decrease it when it is destroyed.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_register_sock2(pj_pool_t *pool,\n\t\t\t\t\t       pj_ioqueue_t *ioque,\n\t\t\t\t\t       pj_sock_t sock,\n\t\t\t\t\t       pj_grp_lock_t *grp_lock,\n\t\t\t\t\t       void *user_data,\n\t\t\t\t\t       const pj_ioqueue_callback *cb,\n                                               pj_ioqueue_key_t **key );\n\n/**\n * Unregister from the I/O Queue framework. Caller must make sure that\n * the key doesn't have any pending operations before calling this function,\n * by calling #pj_ioqueue_is_pending() for all previously submitted\n * operations except asynchronous connect, and if necessary call\n * #pj_ioqueue_post_completion() to cancel the pending operations.\n *\n * Note that asynchronous connect operation will automatically be \n * cancelled during the unregistration.\n *\n * Also note that when I/O Completion Port backend is used, application\n * MUST close the handle immediately after unregistering the key. This is\n * because there is no unregistering API for IOCP. The only way to\n * unregister the handle from IOCP is to close the handle.\n *\n * @param key\t    The key that was previously obtained from registration.\n *\n * @return          PJ_SUCCESS on success or the error code.\n *\n * @see pj_ioqueue_is_pending\n */\nPJ_DECL(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key );\n\n\n/**\n * Get user data associated with an ioqueue key.\n *\n * @param key\t    The key that was previously obtained from registration.\n *\n * @return          The user data associated with the descriptor, or NULL \n *                  on error or if no data is associated with the key during\n *                  registration.\n */\nPJ_DECL(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key );\n\n/**\n * Set or change the user data to be associated with the file descriptor or\n * handle or socket descriptor.\n *\n * @param key\t    The key that was previously obtained from registration.\n * @param user_data User data to be associated with the descriptor.\n * @param old_data  Optional parameter to retrieve the old user data.\n *\n * @return          PJ_SUCCESS on success or the error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key,\n                                               void *user_data,\n                                               void **old_data);\n\n/**\n * Configure whether the ioqueue is allowed to call the key's callback\n * concurrently/in parallel. The default concurrency setting for the key\n * is controlled by ioqueue's default concurrency value, which can be\n * changed by calling #pj_ioqueue_set_default_concurrency().\n *\n * If concurrency is allowed for the key, it means that if there are more\n * than one pending operations complete simultaneously, more than one\n * threads may call the key's  callback at the same time. This generally\n * would promote good scalability for application, at the expense of more\n * complexity to manage the concurrent accesses in application's code.\n *\n * Alternatively application may disable the concurrent access by\n * setting the \\a allow flag to false. With concurrency disabled, only\n * one thread can call the key's callback at one time.\n *\n * @param key\t    The key that was previously obtained from registration.\n * @param allow\t    Set this to non-zero to allow concurrent callback calls\n *\t\t    and zero (PJ_FALSE) to disallow it.\n *\n * @return\t    PJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_set_concurrency(pj_ioqueue_key_t *key,\n\t\t\t\t\t\tpj_bool_t allow);\n\n/**\n * Acquire the key's mutex. When the key's concurrency is disabled, \n * application may call this function to synchronize its operation\n * with the key's callback (i.e. this function will block until the\n * key's callback returns).\n *\n * @param key\t    The key that was previously obtained from registration.\n *\n * @return\t    PJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_lock_key(pj_ioqueue_key_t *key);\n\n/**\n * Try to acquire the key's mutex. When the key's concurrency is disabled, \n * application may call this function to synchronize its operation\n * with the key's callback.\n *\n * @param key\t    The key that was previously obtained from registration.\n *\n * @return\t    PJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_trylock_key(pj_ioqueue_key_t *key);\n\n/**\n * Release the lock previously acquired with pj_ioqueue_lock_key().\n *\n * @param key\t    The key that was previously obtained from registration.\n *\n * @return\t    PJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_unlock_key(pj_ioqueue_key_t *key);\n\n/**\n * Initialize operation key.\n *\n * @param op_key    The operation key to be initialied.\n * @param size\t    The size of the operation key.\n */\nPJ_DECL(void) pj_ioqueue_op_key_init( pj_ioqueue_op_key_t *op_key,\n\t\t\t\t      pj_size_t size );\n\n/**\n * Check if operation is pending on the specified operation key.\n * The \\c op_key must have been initialized with #pj_ioqueue_op_key_init() \n * or submitted as pending operation before, or otherwise the result \n * is undefined.\n *\n * @param key       The key.\n * @param op_key    The operation key, previously submitted to any of\n *                  the I/O functions and has returned PJ_EPENDING.\n *\n * @return          Non-zero if operation is still pending.\n */\nPJ_DECL(pj_bool_t) pj_ioqueue_is_pending( pj_ioqueue_key_t *key,\n                                          pj_ioqueue_op_key_t *op_key );\n\n\n/**\n * Post completion status to the specified operation key and call the\n * appropriate callback. When the callback is called, the number of bytes \n * received in read/write callback or the status in accept/connect callback\n * will be set from the \\c bytes_status parameter.\n *\n * @param key           The key.\n * @param op_key        Pending operation key.\n * @param bytes_status  Number of bytes or status to be set. A good value\n *                      to put here is -PJ_ECANCELLED.\n *\n * @return              PJ_SUCCESS if completion status has been successfully\n *                      sent.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_post_completion( pj_ioqueue_key_t *key,\n                                                 pj_ioqueue_op_key_t *op_key,\n                                                 pj_ssize_t bytes_status );\n\n\n\n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0\n/**\n * Instruct I/O Queue to accept incoming connection on the specified \n * listening socket. This function will return immediately (i.e. non-blocking)\n * regardless whether a connection is immediately available. If the function\n * can't complete immediately, the caller will be notified about the incoming\n * connection when it calls pj_ioqueue_poll(). If a new connection is\n * immediately available, the function returns PJ_SUCCESS with the new\n * connection; in this case, the callback WILL NOT be called.\n *\n * @param key\t    The key which registered to the server socket.\n * @param op_key    An operation specific key to be associated with the\n *                  pending operation, so that application can keep track of\n *                  which operation has been completed when the callback is\n *                  called.\n * @param new_sock  Argument which contain pointer to receive the new socket\n *                  for the incoming connection.\n * @param local\t    Optional argument which contain pointer to variable to \n *                  receive local address.\n * @param remote    Optional argument which contain pointer to variable to \n *                  receive the remote address.\n * @param addrlen   On input, contains the length of the buffer for the\n *\t\t    address, and on output, contains the actual length of the\n *\t\t    address. This argument is optional.\n * @return\n *  - PJ_SUCCESS    When connection is available immediately, and the \n *                  parameters will be updated to contain information about \n *                  the new connection. In this case, a completion callback\n *                  WILL NOT be called.\n *  - PJ_EPENDING   If no connection is available immediately. When a new\n *                  connection arrives, the callback will be called.\n *  - non-zero      which indicates the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key,\n                                        pj_ioqueue_op_key_t *op_key,\n\t\t\t\t\tpj_sock_t *new_sock,\n\t\t\t\t\tpj_sockaddr_t *local,\n\t\t\t\t\tpj_sockaddr_t *remote,\n\t\t\t\t\tint *addrlen );\n\n/**\n * Initiate non-blocking socket connect. If the socket can NOT be connected\n * immediately, asynchronous connect() will be scheduled and caller will be\n * notified via completion callback when it calls pj_ioqueue_poll(). If\n * socket is connected immediately, the function returns PJ_SUCCESS and\n * completion callback WILL NOT be called.\n *\n * @param key\t    The key associated with TCP socket\n * @param addr\t    The remote address.\n * @param addrlen   The remote address length.\n *\n * @return\n *  - PJ_SUCCESS    If socket is connected immediately. In this case, the\n *                  completion callback WILL NOT be called.\n *  - PJ_EPENDING   If operation is queued, or \n *  - non-zero      Indicates the error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key,\n\t\t\t\t\t const pj_sockaddr_t *addr,\n\t\t\t\t\t int addrlen );\n\n#endif\t/* PJ_HAS_TCP */\n\n/**\n * Poll the I/O Queue for completed events.\n *\n * Note: polling the ioqueue is not necessary in Symbian. Please see\n * @ref PJ_SYMBIAN_OS for more info.\n *\n * @param ioque\t\tthe I/O Queue.\n * @param timeout\tpolling timeout, or NULL if the thread wishes to wait\n *\t\t\tindefinetely for the event.\n *\n * @return \n *  - zero if timed out (no event).\n *  - (<0) if error occured during polling. Callback will NOT be called.\n *  - (>1) to indicate numbers of events. Callbacks have been called.\n */\nPJ_DECL(int) pj_ioqueue_poll( pj_ioqueue_t *ioque,\n\t\t\t      const pj_time_val *timeout);\n\n\n/**\n * Instruct the I/O Queue to read from the specified handle. This function\n * returns immediately (i.e. non-blocking) regardless whether some data has \n * been transferred. If the operation can't complete immediately, caller will \n * be notified about the completion when it calls pj_ioqueue_poll(). If data\n * is immediately available, the function will return PJ_SUCCESS and the\n * callback WILL NOT be called.\n *\n * @param key\t    The key that uniquely identifies the handle.\n * @param op_key    An operation specific key to be associated with the\n *                  pending operation, so that application can keep track of\n *                  which operation has been completed when the callback is\n *                  called. Caller must make sure that this key remains \n *                  valid until the function completes.\n * @param buffer    The buffer to hold the read data. The caller MUST make sure\n *\t\t    that this buffer remain valid until the framework completes\n *\t\t    reading the handle.\n * @param length    On input, it specifies the size of the buffer. If data is\n *                  available to be read immediately, the function returns\n *                  PJ_SUCCESS and this argument will be filled with the\n *                  amount of data read. If the function is pending, caller\n *                  will be notified about the amount of data read in the\n *                  callback. This parameter can point to local variable in\n *                  caller's stack and doesn't have to remain valid for the\n *                  duration of pending operation.\n * @param flags     Recv flag. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then\n *\t\t    the function will never return PJ_SUCCESS.\n *\n * @return\n *  - PJ_SUCCESS    If immediate data has been received in the buffer. In this\n *                  case, the callback WILL NOT be called.\n *  - PJ_EPENDING   If the operation has been queued, and the callback will be\n *                  called when data has been received.\n *  - non-zero      The return value indicates the error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_recv( pj_ioqueue_key_t *key,\n                                      pj_ioqueue_op_key_t *op_key,\n\t\t\t\t      void *buffer,\n\t\t\t\t      pj_ssize_t *length,\n\t\t\t\t      pj_uint32_t flags );\n\n/**\n * This function behaves similarly as #pj_ioqueue_recv(), except that it is\n * normally called for socket, and the remote address will also be returned\n * along with the data. Caller MUST make sure that both buffer and addr\n * remain valid until the framework completes reading the data.\n *\n * @param key\t    The key that uniquely identifies the handle.\n * @param op_key    An operation specific key to be associated with the\n *                  pending operation, so that application can keep track of\n *                  which operation has been completed when the callback is\n *                  called.\n * @param buffer    The buffer to hold the read data. The caller MUST make sure\n *\t\t    that this buffer remain valid until the framework completes\n *\t\t    reading the handle.\n * @param length    On input, it specifies the size of the buffer. If data is\n *                  available to be read immediately, the function returns\n *                  PJ_SUCCESS and this argument will be filled with the\n *                  amount of data read. If the function is pending, caller\n *                  will be notified about the amount of data read in the\n *                  callback. This parameter can point to local variable in\n *                  caller's stack and doesn't have to remain valid for the\n *                  duration of pending operation.\n * @param flags     Recv flag. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then\n *\t\t    the function will never return PJ_SUCCESS.\n * @param addr      Optional Pointer to buffer to receive the address.\n * @param addrlen   On input, specifies the length of the address buffer.\n *                  On output, it will be filled with the actual length of\n *                  the address. This argument can be NULL if \\c addr is not\n *                  specified.\n *\n * @return\n *  - PJ_SUCCESS    If immediate data has been received. In this case, the \n *\t\t    callback must have been called before this function \n *\t\t    returns, and no pending operation is scheduled.\n *  - PJ_EPENDING   If the operation has been queued.\n *  - non-zero      The return value indicates the error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_key_t *key,\n                                          pj_ioqueue_op_key_t *op_key,\n\t\t\t\t\t  void *buffer,\n\t\t\t\t\t  pj_ssize_t *length,\n                                          pj_uint32_t flags,\n\t\t\t\t\t  pj_sockaddr_t *addr,\n\t\t\t\t\t  int *addrlen);\n\n/**\n * Instruct the I/O Queue to write to the handle. This function will return\n * immediately (i.e. non-blocking) regardless whether some data has been \n * transferred. If the function can't complete immediately, the caller will\n * be notified about the completion when it calls pj_ioqueue_poll(). If \n * operation completes immediately and data has been transferred, the function\n * returns PJ_SUCCESS and the callback will NOT be called.\n *\n * @param key\t    The key that identifies the handle.\n * @param op_key    An operation specific key to be associated with the\n *                  pending operation, so that application can keep track of\n *                  which operation has been completed when the callback is\n *                  called.\n * @param data\t    The data to send. Caller MUST make sure that this buffer \n *\t\t    remains valid until the write operation completes.\n * @param length    On input, it specifies the length of data to send. When\n *                  data was sent immediately, this function returns PJ_SUCCESS\n *                  and this parameter contains the length of data sent. If\n *                  data can not be sent immediately, an asynchronous operation\n *                  is scheduled and caller will be notified via callback the\n *                  number of bytes sent. This parameter can point to local \n *                  variable on caller's stack and doesn't have to remain \n *                  valid until the operation has completed.\n * @param flags     Send flags. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then\n *\t\t    the function will never return PJ_SUCCESS.\n *\n * @return\n *  - PJ_SUCCESS    If data was immediately transferred. In this case, no\n *                  pending operation has been scheduled and the callback\n *                  WILL NOT be called.\n *  - PJ_EPENDING   If the operation has been queued. Once data base been\n *                  transferred, the callback will be called.\n *  - non-zero      The return value indicates the error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_send( pj_ioqueue_key_t *key,\n                                      pj_ioqueue_op_key_t *op_key,\n\t\t\t\t      const void *data,\n\t\t\t\t      pj_ssize_t *length,\n\t\t\t\t      pj_uint32_t flags );\n\n\n/**\n * Instruct the I/O Queue to write to the handle. This function will return\n * immediately (i.e. non-blocking) regardless whether some data has been \n * transferred. If the function can't complete immediately, the caller will\n * be notified about the completion when it calls pj_ioqueue_poll(). If \n * operation completes immediately and data has been transferred, the function\n * returns PJ_SUCCESS and the callback will NOT be called.\n *\n * @param key\t    the key that identifies the handle.\n * @param op_key    An operation specific key to be associated with the\n *                  pending operation, so that application can keep track of\n *                  which operation has been completed when the callback is\n *                  called.\n * @param data\t    the data to send. Caller MUST make sure that this buffer \n *\t\t    remains valid until the write operation completes.\n * @param length    On input, it specifies the length of data to send. When\n *                  data was sent immediately, this function returns PJ_SUCCESS\n *                  and this parameter contains the length of data sent. If\n *                  data can not be sent immediately, an asynchronous operation\n *                  is scheduled and caller will be notified via callback the\n *                  number of bytes sent. This parameter can point to local \n *                  variable on caller's stack and doesn't have to remain \n *                  valid until the operation has completed.\n * @param flags     send flags. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then\n *\t\t    the function will never return PJ_SUCCESS.\n * @param addr      Optional remote address.\n * @param addrlen   Remote address length, \\c addr is specified.\n *\n * @return\n *  - PJ_SUCCESS    If data was immediately written.\n *  - PJ_EPENDING   If the operation has been queued.\n *  - non-zero      The return value indicates the error code.\n */\nPJ_DECL(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key,\n                                        pj_ioqueue_op_key_t *op_key,\n\t\t\t\t\tconst void *data,\n\t\t\t\t\tpj_ssize_t *length,\n                                        pj_uint32_t flags,\n\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\tint addrlen);\n\n\n/**\n * !}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJ_IOQUEUE_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/ip_helper.h",
    "content": "/* $Id: ip_helper.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_IP_ROUTE_H__\n#define __PJ_IP_ROUTE_H__\n\n/**\n * @file ip_helper.h\n * @brief IP helper API\n */\n\n#include <pj/sock.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup pj_ip_helper IP Interface and Routing Helper\n * @ingroup PJ_IO\n * @{\n *\n * This module provides functions to query local host's IP interface and \n * routing table.\n */\n\n/**\n * This structure describes IP routing entry.\n */\ntypedef union pj_ip_route_entry\n{\n    /** IP routing entry for IP version 4 routing */\n    struct\n    {\n\tpj_in_addr\tif_addr;    /**< Local interface IP address.\t*/\n\tpj_in_addr\tdst_addr;   /**< Destination IP address.\t*/\n\tpj_in_addr\tmask;\t    /**< Destination mask.\t\t*/\n    } ipv4;\n} pj_ip_route_entry;\n\n\n/**\n * Enumerate the local IP interfaces currently active in the host.\n *\n * @param af\t    Family of the address to be retrieved. Application\n *\t\t    may specify pj_AF_UNSPEC() to retrieve all addresses,\n *\t\t    or pj_AF_INET() or pj_AF_INET6() to retrieve interfaces\n *\t\t    with specific address family.\n * @param count\t    On input, specify the number of entries. On output,\n *\t\t    it will be filled with the actual number of entries.\n * @param ifs\t    Array of socket addresses, which address part will\n *\t\t    be filled with the interface address. The address\n *\t\t    family part will be initialized with the address\n *\t\t    family of the IP address.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_enum_ip_interface(int af,\n\t\t\t\t\t  unsigned *count,\n\t\t\t\t\t  pj_sockaddr ifs[]);\n\n\n/**\n * Enumerate the IP routing table for this host.\n *\n * @param count\t    On input, specify the number of routes entries. On output,\n *\t\t    it will be filled with the actual number of route entries.\n * @param routes    Array of IP routing entries.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_enum_ip_route(unsigned *count,\n\t\t\t\t      pj_ip_route_entry routes[]);\n\n\n\n/** @} */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJ_IP_ROUTE_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/list.h",
    "content": "/* $Id: list.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_LIST_H__\n#define __PJ_LIST_H__\n\n/**\n * @file list.h\n * @brief Linked List data structure.\n */\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/*\n * @defgroup PJ_DS Data Structure.\n */\n\n/**\n * @defgroup PJ_LIST Linked List\n * @ingroup PJ_DS\n * @{\n *\n * List in PJLIB is implemented as doubly-linked list, and it won't require\n * dynamic memory allocation (just as all PJLIB data structures). The list here\n * should be viewed more like a low level C list instead of high level C++ list\n * (which normally are easier to use but require dynamic memory allocations),\n * therefore all caveats with C list apply here too (such as you can NOT put\n * a node in more than one lists).\n *\n * \\section pj_list_example_sec Examples\n *\n * See below for examples on how to manipulate linked list:\n *  - @ref page_pjlib_samples_list_c\n *  - @ref page_pjlib_list_test\n */\n\n\n/**\n * Use this macro in the start of the structure declaration to declare that\n * the structure can be used in the linked list operation. This macro simply\n * declares additional member @a prev and @a next to the structure.\n * @hideinitializer\n */\n#define PJ_DECL_LIST_MEMBER(type)                       \\\n                                   /** List @a prev. */ \\\n                                   type *prev;          \\\n                                   /** List @a next. */ \\\n                                   type *next \n\n\n/**\n * This structure describes generic list node and list. The owner of this list\n * must initialize the 'value' member to an appropriate value (typically the\n * owner itself).\n */\nstruct pj_list\n{\n    PJ_DECL_LIST_MEMBER(void);\n} PJ_ATTR_MAY_ALIAS; /* may_alias avoids warning with gcc-4.4 -Wall -O2 */\n\n\n/**\n * Initialize the list.\n * Initially, the list will have no member, and function pj_list_empty() will\n * always return nonzero (which indicates TRUE) for the newly initialized \n * list.\n *\n * @param node The list head.\n */\nPJ_INLINE(void) pj_list_init(pj_list_type * node)\n{\n    ((pj_list*)node)->next = ((pj_list*)node)->prev = node;\n}\n\n\n/**\n * Check that the list is empty.\n *\n * @param node\tThe list head.\n *\n * @return Non-zero if the list is empty, or zero if it is not empty.\n *\n */\nPJ_INLINE(int) pj_list_empty(const pj_list_type * node)\n{\n    return ((pj_list*)node)->next == node;\n}\n\n\n/**\n * Insert the node to the list before the specified element position.\n *\n * @param pos\tThe element to which the node will be inserted before. \n * @param node\tThe element to be inserted.\n *\n * @return void.\n */\nPJ_IDECL(void)\tpj_list_insert_before(pj_list_type *pos, pj_list_type *node);\n\n\n/**\n * Insert the node to the back of the list. This is just an alias for\n * #pj_list_insert_before().\n *\n * @param list\tThe list. \n * @param node\tThe element to be inserted.\n */\nPJ_INLINE(void) pj_list_push_back(pj_list_type *list, pj_list_type *node)\n{\n    pj_list_insert_before(list, node);\n}\n\n\n/**\n * Inserts all nodes in \\a nodes to the target list.\n *\n * @param lst\t    The target list.\n * @param nodes\t    Nodes list.\n */\nPJ_IDECL(void) pj_list_insert_nodes_before(pj_list_type *lst,\n\t\t\t\t\t   pj_list_type *nodes);\n\n/**\n * Insert a node to the list after the specified element position.\n *\n * @param pos\t    The element in the list which will precede the inserted \n *\t\t    element.\n * @param node\t    The element to be inserted after the position element.\n *\n * @return void.\n */\nPJ_IDECL(void) pj_list_insert_after(pj_list_type *pos, pj_list_type *node);\n\n\n/**\n * Insert the node to the front of the list. This is just an alias for\n * #pj_list_insert_after().\n *\n * @param list\tThe list. \n * @param node\tThe element to be inserted.\n */\nPJ_INLINE(void) pj_list_push_front(pj_list_type *list, pj_list_type *node)\n{\n    pj_list_insert_after(list, node);\n}\n\n\n/**\n * Insert all nodes in \\a nodes to the target list.\n *\n * @param lst\t    The target list.\n * @param nodes\t    Nodes list.\n */\nPJ_IDECL(void) pj_list_insert_nodes_after(pj_list_type *lst,\n\t\t\t\t\t  pj_list_type *nodes);\n\n\n/**\n * Remove elements from the source list, and insert them to the destination\n * list. The elements of the source list will occupy the\n * front elements of the target list. Note that the node pointed by \\a list2\n * itself is not considered as a node, but rather as the list descriptor, so\n * it will not be inserted to the \\a list1. The elements to be inserted starts\n * at \\a list2->next. If \\a list2 is to be included in the operation, use\n * \\a pj_list_insert_nodes_before.\n *\n * @param list1\tThe destination list.\n * @param list2\tThe source list.\n *\n * @return void.\n */\nPJ_IDECL(void) pj_list_merge_first(pj_list_type *list1, pj_list_type *list2);\n\n\n/**\n * Remove elements from the second list argument, and insert them to the list \n * in the first argument. The elements from the second list will be appended\n * to the first list. Note that the node pointed by \\a list2\n * itself is not considered as a node, but rather as the list descriptor, so\n * it will not be inserted to the \\a list1. The elements to be inserted starts\n * at \\a list2->next. If \\a list2 is to be included in the operation, use\n * \\a pj_list_insert_nodes_before.\n *\n * @param list1\t    The element in the list which will precede the inserted \n *\t\t    element.\n * @param list2\t    The element in the list to be inserted.\n *\n * @return void.\n */\nPJ_IDECL(void) pj_list_merge_last( pj_list_type *list1, pj_list_type *list2);\n\n\n/**\n * Erase the node from the list it currently belongs.\n *\n * @param node\t    The element to be erased.\n */\nPJ_IDECL(void) pj_list_erase(pj_list_type *node);\n\n\n/**\n * Find node in the list.\n *\n * @param list\t    The list head.\n * @param node\t    The node element to be searched.\n *\n * @return The node itself if it is found in the list, or NULL if it is not \n *         found in the list.\n */\nPJ_IDECL(pj_list_type*) pj_list_find_node(pj_list_type *list, \n\t\t\t\t\t  pj_list_type *node);\n\n\n/**\n * Search the list for the specified value, using the specified comparison\n * function. This function iterates on nodes in the list, started with the\n * first node, and call the user supplied comparison function until the\n * comparison function returns ZERO.\n *\n * @param list\t    The list head.\n * @param value\t    The user defined value to be passed in the comparison \n *\t\t    function\n * @param comp\t    The comparison function, which should return ZERO to \n *\t\t    indicate that the searched value is found.\n *\n * @return The first node that matched, or NULL if it is not found.\n */\nPJ_IDECL(pj_list_type*) pj_list_search(pj_list_type *list, void *value,\n\t\t\t\t       int (*comp)(void *value, \n\t\t\t\t\t\t   const pj_list_type *node)\n\t\t\t\t       );\n\n\n/**\n * Traverse the list to get the number of elements in the list.\n *\n * @param list\t    The list head.\n *\n * @return\t    Number of elements.\n */\nPJ_IDECL(pj_size_t) pj_list_size(const pj_list_type *list);\n\n\n/**\n * @}\n */\n\n#if PJ_FUNCTIONS_ARE_INLINED\n#  include \"list_i.h\"\n#endif\n\nPJ_END_DECL\n\n#endif\t/* __PJ_LIST_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/list_i.h",
    "content": "/* $Id: list_i.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n\n/* Internal */\nPJ_INLINE(void) pj_link_node(pj_list_type *prev, pj_list_type *next)\n{\n    ((pj_list*)prev)->next = next;\n    ((pj_list*)next)->prev = prev;\n}\n\nPJ_IDEF(void) pj_list_insert_after(pj_list_type *pos, pj_list_type *node)\n{\n    ((pj_list*)node)->prev = pos;\n    ((pj_list*)node)->next = ((pj_list*)pos)->next;\n    ((pj_list*) ((pj_list*)pos)->next) ->prev = node;\n    ((pj_list*)pos)->next = node;\n}\n\n\nPJ_IDEF(void) pj_list_insert_before(pj_list_type *pos, pj_list_type *node)\n{\n    pj_list_insert_after(((pj_list*)pos)->prev, node);\n}\n\n\nPJ_IDEF(void) pj_list_insert_nodes_after(pj_list_type *pos, pj_list_type *lst)\n{\n    pj_list *lst_last = (pj_list *) ((pj_list*)lst)->prev;\n    pj_list *pos_next = (pj_list *) ((pj_list*)pos)->next;\n\n    pj_link_node(pos, lst);\n    pj_link_node(lst_last, pos_next);\n}\n\nPJ_IDEF(void) pj_list_insert_nodes_before(pj_list_type *pos, pj_list_type *lst)\n{\n    pj_list_insert_nodes_after(((pj_list*)pos)->prev, lst);\n}\n\nPJ_IDEF(void) pj_list_merge_last(pj_list_type *lst1, pj_list_type *lst2)\n{\n    if (!pj_list_empty(lst2)) {\n\tpj_link_node(((pj_list*)lst1)->prev, ((pj_list*)lst2)->next);\n\tpj_link_node(((pj_list*)lst2)->prev, lst1);\n\tpj_list_init(lst2);\n    }\n}\n\nPJ_IDEF(void) pj_list_merge_first(pj_list_type *lst1, pj_list_type *lst2)\n{\n    if (!pj_list_empty(lst2)) {\n\tpj_link_node(((pj_list*)lst2)->prev, ((pj_list*)lst1)->next);\n\tpj_link_node(((pj_list*)lst1), ((pj_list*)lst2)->next);\n\tpj_list_init(lst2);\n    }\n}\n\nPJ_IDEF(void) pj_list_erase(pj_list_type *node)\n{\n    pj_link_node( ((pj_list*)node)->prev, ((pj_list*)node)->next);\n\n    /* It'll be safer to init the next/prev fields to itself, to\n     * prevent multiple erase() from corrupting the list. See\n     * ticket #520 for one sample bug.\n     */\n    pj_list_init(node);\n}\n\n\nPJ_IDEF(pj_list_type*) pj_list_find_node(pj_list_type *list, pj_list_type *node)\n{\n    pj_list *p = (pj_list *) ((pj_list*)list)->next;\n    while (p != list && p != node)\n\tp = (pj_list *) p->next;\n\n    return p==node ? p : NULL;\n}\n\n\nPJ_IDEF(pj_list_type*) pj_list_search(pj_list_type *list, void *value,\n\t       \t\tint (*comp)(void *value, const pj_list_type *node))\n{\n    pj_list *p = (pj_list *) ((pj_list*)list)->next;\n    while (p != list && (*comp)(value, p) != 0)\n\tp = (pj_list *) p->next;\n\n    return p==list ? NULL : p;\n}\n\n\nPJ_IDEF(pj_size_t) pj_list_size(const pj_list_type *list)\n{\n    const pj_list *node = (const pj_list*) ((const pj_list*)list)->next;\n    pj_size_t count = 0;\n\n    while (node != list) {\n\t++count;\n\tnode = (pj_list*)node->next;\n    }\n\n    return count;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/lock.h",
    "content": "/* $Id: lock.h 4359 2013-02-21 11:18:36Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_LOCK_H__\n#define __PJ_LOCK_H__\n\n/**\n * @file lock.h\n * @brief Higher abstraction for locking objects.\n */\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_LOCK Lock Objects\n * @ingroup PJ_OS\n * @{\n *\n * <b>Lock Objects</b> are higher abstraction for different lock mechanisms.\n * It offers the same API for manipulating different lock types (e.g.\n * @ref PJ_MUTEX \"mutex\", @ref PJ_SEM \"semaphores\", or null locks).\n * Because Lock Objects have the same API for different types of lock\n * implementation, it can be passed around in function arguments. As the\n * result, it can be used to control locking policy for  a particular\n * feature.\n */\n\n\n/**\n * Create simple, non recursive mutex lock object.\n *\n * @param pool\t    Memory pool.\n * @param name\t    Lock object's name.\n * @param lock\t    Pointer to store the returned handle.\n *\n * @return\t    PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_lock_create_simple_mutex( pj_pool_t *pool,\n\t\t\t\t\t\t  const char *name,\n\t\t\t\t\t\t  pj_lock_t **lock );\n\n/**\n * Create recursive mutex lock object.\n *\n * @param pool\t    Memory pool.\n * @param name\t    Lock object's name.\n * @param lock\t    Pointer to store the returned handle.\n *\n * @return\t    PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_lock_create_recursive_mutex( pj_pool_t *pool,\n\t\t\t\t\t\t     const char *name,\n\t\t\t\t\t\t     pj_lock_t **lock );\n\n\n/**\n * Create NULL mutex. A NULL mutex doesn't actually have any synchronization\n * object attached to it.\n *\n * @param pool\t    Memory pool.\n * @param name\t    Lock object's name.\n * @param lock\t    Pointer to store the returned handle.\n *\n * @return\t    PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_lock_create_null_mutex( pj_pool_t *pool,\n\t\t\t\t\t\tconst char *name,\n\t\t\t\t\t\tpj_lock_t **lock );\n\n\n#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0\n/**\n * Create semaphore lock object.\n *\n * @param pool\t    Memory pool.\n * @param name\t    Lock object's name.\n * @param initial   Initial value of the semaphore.\n * @param max\t    Maximum value of the semaphore.\n * @param lock\t    Pointer to store the returned handle.\n *\n * @return\t    PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_lock_create_semaphore( pj_pool_t *pool,\n\t\t\t\t\t       const char *name,\n\t\t\t\t\t       unsigned initial,\n\t\t\t\t\t       unsigned max,\n\t\t\t\t\t       pj_lock_t **lock );\n\n#endif\t/* PJ_HAS_SEMAPHORE */\n\n/**\n * Acquire lock on the specified lock object.\n *\n * @param lock\t    The lock object.\n *\n * @return\t    PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_lock_acquire( pj_lock_t *lock );\n\n\n/**\n * Try to acquire lock on the specified lock object.\n *\n * @param lock\t    The lock object.\n *\n * @return\t    PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_lock_tryacquire( pj_lock_t *lock );\n\n\n/**\n * Release lock on the specified lock object.\n *\n * @param lock\t    The lock object.\n *\n * @return\t    PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_lock_release( pj_lock_t *lock );\n\n\n/**\n * Destroy the lock object.\n *\n * @param lock\t    The lock object.\n *\n * @return\t    PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_lock_destroy( pj_lock_t *lock );\n\n\n/** @} */\n\n\n/**\n * @defgroup PJ_GRP_LOCK Group Lock\n * @ingroup PJ_LOCK\n * @{\n *\n * Group lock is a synchronization object to manage concurrency among members\n * within the same logical group. Example of such groups are:\n *\n *   - dialog, which has members such as the dialog itself, an invite session,\n *     and several transactions\n *   - ICE, which has members such as ICE stream transport, ICE session, STUN\n *     socket, TURN socket, and down to ioqueue key\n *\n * Group lock has three functions:\n *\n *   - mutual exclusion: to protect resources from being accessed by more than\n *     one threads at the same time\n *   - session management: to make sure that the resource is not destroyed\n *     while others are still using or about to use it.\n *   - lock coordinator: to provide uniform lock ordering among more than one\n *     lock objects, which is necessary to avoid deadlock.\n *\n * The requirements of the group lock are:\n *\n *    - must satisfy all the functions above\n *    - must allow members to join or leave the group (for example,\n *      transaction may be added or removed from a dialog)\n *    - must be able to synchronize with external lock (for example, a dialog\n *      lock must be able to sync itself with PJSUA lock)\n *\n * Please see https://trac.pjsip.org/repos/wiki/Group_Lock for more info.\n */\n\n/**\n * Settings for creating the group lock.\n */\ntypedef struct pj_grp_lock_config\n{\n    /**\n     * Creation flags, currently must be zero.\n     */\n    unsigned\tflags;\n\n} pj_grp_lock_config;\n\n\n/**\n * Initialize the config with the default values.\n *\n * @param cfg\t\tThe config to be initialized.\n */\nPJ_DECL(void) pj_grp_lock_config_default(pj_grp_lock_config *cfg);\n\n/**\n * Create a group lock object. Initially the group lock will have reference\n * counter of one.\n *\n * @param pool\t\tThe group lock only uses the pool parameter to get\n * \t\t\tthe pool factory, from which it will create its own\n * \t\t\tpool.\n * @param cfg\t\tOptional configuration.\n * @param p_grp_lock\tPointer to receive the newly created group lock.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_grp_lock_create(pj_pool_t *pool,\n                                        const pj_grp_lock_config *cfg,\n                                        pj_grp_lock_t **p_grp_lock);\n\n/**\n * Create a group lock object, with the specified destructor handler, to be\n * called by the group lock when it is about to be destroyed. Initially the\n * group lock will have reference counter of one.\n *\n * @param pool\t\tThe group lock only uses the pool parameter to get\n * \t\t\tthe pool factory, from which it will create its own\n * \t\t\tpool.\n * @param cfg\t\tOptional configuration.\n * @param member\tA pointer to be passed to the handler.\n * @param handler\tThe destroy handler.\n * @param p_grp_lock\tPointer to receive the newly created group lock.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_grp_lock_create_w_handler(pj_pool_t *pool,\n                                        \t  const pj_grp_lock_config *cfg,\n                                        \t  void *member,\n                                                  void (*handler)(void *member),\n                                        \t  pj_grp_lock_t **p_grp_lock);\n\n/**\n * Forcibly destroy the group lock, ignoring the reference counter value.\n *\n * @param grp_lock\tThe group lock.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_grp_lock_destroy( pj_grp_lock_t *grp_lock);\n\n/**\n * Move the contents of the old lock to the new lock and destroy the\n * old lock.\n *\n * @param old_lock\tThe old group lock to be destroyed.\n * @param new_lock\tThe new group lock.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_grp_lock_replace(pj_grp_lock_t *old_lock,\n                                         pj_grp_lock_t *new_lock);\n\n/**\n * Acquire lock on the specified group lock.\n *\n * @param grp_lock\tThe group lock.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_grp_lock_acquire( pj_grp_lock_t *grp_lock);\n\n/**\n * Acquire lock on the specified group lock if it is available, otherwise\n * return immediately wihout waiting.\n *\n * @param grp_lock\tThe group lock.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_grp_lock_tryacquire( pj_grp_lock_t *grp_lock);\n\n/**\n * Release the previously held lock. This may cause the group lock\n * to be destroyed if it is the last one to hold the reference counter.\n * In that case, the function will return PJ_EGONE.\n *\n * @param grp_lock\tThe group lock.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_grp_lock_release( pj_grp_lock_t *grp_lock);\n\n/**\n * Add a destructor handler, to be called by the group lock when it is\n * about to be destroyed.\n *\n * @param grp_lock\tThe group lock.\n * @param pool\t\tPool to allocate memory for the handler.\n * @param member\tA pointer to be passed to the handler.\n * @param handler\tThe destroy handler.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_grp_lock_add_handler(pj_grp_lock_t *grp_lock,\n                                             pj_pool_t *pool,\n                                             void *member,\n                                             void (*handler)(void *member));\n\n/**\n * Remove previously registered handler. All parameters must be the same\n * as when the handler was added.\n *\n * @param grp_lock\tThe group lock.\n * @param member\tA pointer to be passed to the handler.\n * @param handler\tThe destroy handler.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_grp_lock_del_handler(pj_grp_lock_t *grp_lock,\n                                             void *member,\n                                             void (*handler)(void *member));\n\n/**\n * Increment reference counter to prevent the group lock grom being destroyed.\n *\n * @param grp_lock\tThe group lock.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\n#if !PJ_GRP_LOCK_DEBUG\nPJ_DECL(pj_status_t) pj_grp_lock_add_ref(pj_grp_lock_t *grp_lock);\n\n#define pj_grp_lock_add_ref_dbg(grp_lock, x, y) pj_grp_lock_add_ref(grp_lock)\n\n#else\n\n#define pj_grp_lock_add_ref(g)\tpj_grp_lock_add_ref_dbg(g, __FILE__, __LINE__)\n\nPJ_DECL(pj_status_t) pj_grp_lock_add_ref_dbg(pj_grp_lock_t *grp_lock,\n                                             const char *file,\n                                             int line);\n#endif\n\n/**\n * Decrement the reference counter. When the counter value reaches zero, the\n * group lock will be destroyed and all destructor handlers will be called.\n *\n * @param grp_lock\tThe group lock.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\n#if !PJ_GRP_LOCK_DEBUG\nPJ_DECL(pj_status_t) pj_grp_lock_dec_ref(pj_grp_lock_t *grp_lock);\n\n#define pj_grp_lock_dec_ref_dbg(grp_lock, x, y) pj_grp_lock_dec_ref(grp_lock)\n#else\n\n#define pj_grp_lock_dec_ref(g)\tpj_grp_lock_dec_ref_dbg(g, __FILE__, __LINE__)\n\nPJ_DECL(pj_status_t) pj_grp_lock_dec_ref_dbg(pj_grp_lock_t *grp_lock,\n                                             const char *file,\n                                             int line);\n\n#endif\n\n/**\n * Get current reference count value. This normally is only used for\n * debugging purpose.\n *\n * @param grp_lock\tThe group lock.\n *\n * @return\t\tThe reference count value.\n */\nPJ_DECL(int) pj_grp_lock_get_ref(pj_grp_lock_t *grp_lock);\n\n\n/**\n * Dump group lock info for debugging purpose. If group lock debugging is\n * enabled (via PJ_GRP_LOCK_DEBUG) macro, this will print the group lock\n * reference counter value along with the source file and line. If\n * debugging is disabled, this will only print the reference counter.\n *\n * @param grp_lock\tThe group lock.\n */\nPJ_DECL(void) pj_grp_lock_dump(pj_grp_lock_t *grp_lock);\n\n\n/**\n * Synchronize an external lock with the group lock, by adding it to the\n * list of locks to be acquired by the group lock when the group lock is\n * acquired.\n *\n * The ''pos'' argument specifies the lock order and also the relative\n * position with regard to lock ordering against the group lock. Locks with\n * lower ''pos'' value will be locked first, and those with negative value\n * will be locked before the group lock (the group lock's ''pos'' value is\n * zero).\n *\n * @param grp_lock\tThe group lock.\n * @param ext_lock\tThe external lock\n * @param pos\t\tThe position.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_grp_lock_chain_lock(pj_grp_lock_t *grp_lock,\n                                            pj_lock_t *ext_lock,\n                                            int pos);\n\n/**\n * Remove an external lock from group lock's list of synchronized locks.\n *\n * @param grp_lock\tThe group lock.\n * @param ext_lock\tThe external lock\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_grp_lock_unchain_lock(pj_grp_lock_t *grp_lock,\n                                              pj_lock_t *ext_lock);\n\n\n/** @} */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJ_LOCK_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/log.h",
    "content": "/* $Id: log.h 3752 2011-09-18 14:38:46Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_LOG_H__\n#define __PJ_LOG_H__\n\n/**\n * @file log.h\n * @brief Logging Utility.\n */\n\n#include <pj/types.h>\n#include <stdarg.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_MISC Miscelaneous\n */\n\n/**\n * @defgroup PJ_LOG Logging Facility\n * @ingroup PJ_MISC\n * @{\n *\n * The PJLIB logging facility is a configurable, flexible, and convenient\n * way to write logging or trace information.\n *\n * To write to the log, one uses construct like below:\n *\n * <pre>\n *   ...\n *   PJ_LOG(3, (\"main.c\", \"Starting hello...\"));\n *   ...\n *   PJ_LOG(3, (\"main.c\", \"Hello world from process %d\", pj_getpid()));\n *   ...\n * </pre>\n *\n * In the above example, the number @b 3 controls the verbosity level of\n * the information (which means \"information\", by convention). The string\n * \"main.c\" specifies the source or sender of the message.\n *\n *\n * \\section pj_log_quick_sample_sec Examples\n *\n * For examples, see:\n *  - @ref page_pjlib_samples_log_c.\n *\n */\n\n/**\n * Log decoration flag, to be specified with #pj_log_set_decor().\n */\nenum pj_log_decoration\n{\n    PJ_LOG_HAS_DAY_NAME   =    1, /**< Include day name [default: no] \t      */\n    PJ_LOG_HAS_YEAR       =    2, /**< Include year digit [no]\t\t      */\n    PJ_LOG_HAS_MONTH\t  =    4, /**< Include month [no]\t\t      */\n    PJ_LOG_HAS_DAY_OF_MON =    8, /**< Include day of month [no]\t      */\n    PJ_LOG_HAS_TIME\t  =   16, /**< Include time [yes]\t\t      */\n    PJ_LOG_HAS_MICRO_SEC  =   32, /**< Include microseconds [yes]             */\n    PJ_LOG_HAS_SENDER\t  =   64, /**< Include sender in the log [yes] \t      */\n    PJ_LOG_HAS_NEWLINE\t  =  128, /**< Terminate each call with newline [yes] */\n    PJ_LOG_HAS_CR\t  =  256, /**< Include carriage return [no] \t      */\n    PJ_LOG_HAS_SPACE\t  =  512, /**< Include two spaces before log [yes]    */\n    PJ_LOG_HAS_COLOR\t  = 1024, /**< Colorize logs [yes on win32]\t      */\n    PJ_LOG_HAS_LEVEL_TEXT = 2048, /**< Include level text string [no]\t      */\n    PJ_LOG_HAS_THREAD_ID  = 4096, /**< Include thread identification [no]     */\n    PJ_LOG_HAS_THREAD_SWC = 8192, /**< Add mark when thread has switched [yes]*/\n    PJ_LOG_HAS_INDENT     =16384  /**< Indentation. Say yes! [yes]            */\n};\n\n/**\n * Write log message.\n * This is the main macro used to write text to the logging backend. \n *\n * @param level\t    The logging verbosity level. Lower number indicates higher\n *\t\t    importance, with level zero indicates fatal error. Only\n *\t\t    numeral argument is permitted (e.g. not variable).\n * @param arg\t    Enclosed 'printf' like arguments, with the first \n *\t\t    argument is the sender, the second argument is format \n *\t\t    string and the following arguments are variable number of \n *\t\t    arguments suitable for the format string.\n *\n * Sample:\n * \\verbatim\n   PJ_LOG(2, (__FILE__, \"current value is %d\", value));\n   \\endverbatim\n * @hideinitializer\n */\n#define PJ_LOG(level,arg)\tdo { \\\n\t\t\t\t    if (level <= pj_log_get_level()) \\\n\t\t\t\t\tpj_log_wrapper_##level(arg); \\\n\t\t\t\t} while (0)\n\n/**\n * Signature for function to be registered to the logging subsystem to\n * write the actual log message to some output device.\n *\n * @param level\t    Log level.\n * @param data\t    Log message, which will be NULL terminated.\n * @param len\t    Message length.\n */\ntypedef void pj_log_func(int level, const char *data, int len);\n\n/**\n * Default logging writer function used by front end logger function.\n * This function will print the log message to stdout only.\n * Application normally should NOT need to call this function, but\n * rather use the PJ_LOG macro.\n *\n * @param level\t    Log level.\n * @param buffer    Log message.\n * @param len\t    Message length.\n */\nPJ_DECL(void) pj_log_write(int level, const char *buffer, int len);\n\n\n#if PJ_LOG_MAX_LEVEL >= 1\n\n/**\n * Write to log.\n *\n * @param sender    Source of the message.\n * @param level\t    Verbosity level.\n * @param format    Format.\n * @param marker    Marker.\n */\nPJ_DECL(void) pj_log(const char *sender, int level, \n\t\t     const char *format, va_list marker);\n\n/**\n * Change log output function. The front-end logging functions will call\n * this function to write the actual message to the desired device. \n * By default, the front-end functions use pj_log_write() to write\n * the messages, unless it's changed by calling this function.\n *\n * @param func\t    The function that will be called to write the log\n *\t\t    messages to the desired device.\n */\nPJ_DECL(void) pj_log_set_log_func( pj_log_func *func );\n\n/**\n * Get the current log output function that is used to write log messages.\n *\n * @return\t    Current log output function.\n */\nPJ_DECL(pj_log_func*) pj_log_get_log_func(void);\n\n/**\n * Set maximum log level. Application can call this function to set \n * the desired level of verbosity of the logging messages. The bigger the\n * value, the more verbose the logging messages will be printed. However,\n * the maximum level of verbosity can not exceed compile time value of\n * PJ_LOG_MAX_LEVEL.\n *\n * @param level\t    The maximum level of verbosity of the logging\n *\t\t    messages (6=very detailed..1=error only, 0=disabled)\n */\nPJ_DECL(void) pj_log_set_level(int level);\n\n/**\n * Get current maximum log verbositylevel.\n *\n * @return\t    Current log maximum level.\n */\n#if 1\nPJ_DECL(int) pj_log_get_level(void);\n#else\nPJ_DECL_DATA(int) pj_log_max_level;\n#define pj_log_get_level()  pj_log_max_level\n#endif\n\n/**\n * Set log decoration. The log decoration flag controls what are printed\n * to output device alongside the actual message. For example, application\n * can specify that date/time information should be displayed with each\n * log message.\n *\n * @param decor\t    Bitmask combination of #pj_log_decoration to control\n *\t\t    the layout of the log message.\n */\nPJ_DECL(void) pj_log_set_decor(unsigned decor);\n\n/**\n * Get current log decoration flag.\n *\n * @return\t    Log decoration flag.\n */\nPJ_DECL(unsigned) pj_log_get_decor(void);\n\n/**\n * Add indentation to log message. Indentation will add PJ_LOG_INDENT_CHAR\n * before the message, and is useful to show the depth of function calls.\n *\n * @param indent    The indentation to add or substract. Positive value\n * \t\t    adds current indent, negative value subtracts current\n * \t\t    indent.\n */\nPJ_DECL(void) pj_log_add_indent(int indent);\n\n/**\n * Push indentation to the right by default value (PJ_LOG_INDENT).\n */\nPJ_DECL(void) pj_log_push_indent(void);\n\n/**\n * Pop indentation (to the left) by default value (PJ_LOG_INDENT).\n */\nPJ_DECL(void) pj_log_pop_indent(void);\n\n/**\n * Set color of log messages.\n *\n * @param level\t    Log level which color will be changed.\n * @param color\t    Desired color.\n */\nPJ_DECL(void) pj_log_set_color(int level, pj_color_t color);\n\n/**\n * Get color of log messages.\n *\n * @param level\t    Log level which color will be returned.\n * @return\t    Log color.\n */\nPJ_DECL(pj_color_t) pj_log_get_color(int level);\n\n/**\n * Internal function to be called by pj_init()\n */\npj_status_t pj_log_init(void);\n\n#else\t/* #if PJ_LOG_MAX_LEVEL >= 1 */\n\n/**\n * Change log output function. The front-end logging functions will call\n * this function to write the actual message to the desired device. \n * By default, the front-end functions use pj_log_write() to write\n * the messages, unless it's changed by calling this function.\n *\n * @param func\t    The function that will be called to write the log\n *\t\t    messages to the desired device.\n */\n#  define pj_log_set_log_func(func)\n\n/**\n * Write to log.\n *\n * @param sender    Source of the message.\n * @param level\t    Verbosity level.\n * @param format    Format.\n * @param marker    Marker.\n */\n#  define pj_log(sender, level, format, marker)\n\n/**\n * Set maximum log level. Application can call this function to set \n * the desired level of verbosity of the logging messages. The bigger the\n * value, the more verbose the logging messages will be printed. However,\n * the maximum level of verbosity can not exceed compile time value of\n * PJ_LOG_MAX_LEVEL.\n *\n * @param level\t    The maximum level of verbosity of the logging\n *\t\t    messages (6=very detailed..1=error only, 0=disabled)\n */\n#  define pj_log_set_level(level)\n\n/**\n * Set log decoration. The log decoration flag controls what are printed\n * to output device alongside the actual message. For example, application\n * can specify that date/time information should be displayed with each\n * log message.\n *\n * @param decor\t    Bitmask combination of #pj_log_decoration to control\n *\t\t    the layout of the log message.\n */\n#  define pj_log_set_decor(decor)\n\n/**\n * Add indentation to log message. Indentation will add PJ_LOG_INDENT_CHAR\n * before the message, and is useful to show the depth of function calls.\n *\n * @param indent    The indentation to add or substract. Positive value\n * \t\t    adds current indent, negative value subtracts current\n * \t\t    indent.\n */\n#  define pj_log_add_indent(indent)\n\n/**\n * Push indentation to the right by default value (PJ_LOG_INDENT).\n */\n#  define pj_log_push_indent()\n\n/**\n * Pop indentation (to the left) by default value (PJ_LOG_INDENT).\n */\n#  define pj_log_pop_indent()\n\n/**\n * Set color of log messages.\n *\n * @param level\t    Log level which color will be changed.\n * @param color\t    Desired color.\n */\n#  define pj_log_set_color(level, color)\n\n/**\n * Get current maximum log verbositylevel.\n *\n * @return\t    Current log maximum level.\n */\n#  define pj_log_get_level()\t0\n\n/**\n * Get current log decoration flag.\n *\n * @return\t    Log decoration flag.\n */\n#  define pj_log_get_decor()\t0\n\n/**\n * Get color of log messages.\n *\n * @param level\t    Log level which color will be returned.\n * @return\t    Log color.\n */\n#  define pj_log_get_color(level) 0\n\n\n/**\n * Internal.\n */\n#   define pj_log_init()\tPJ_SUCCESS\n\n#endif\t/* #if PJ_LOG_MAX_LEVEL >= 1 */\n\n/** \n * @}\n */\n\n/* **************************************************************************/\n/*\n * Log functions implementation prototypes.\n * These functions are called by PJ_LOG macros according to verbosity\n * level specified when calling the macro. Applications should not normally\n * need to call these functions directly.\n */\n\n/**\n * @def pj_log_wrapper_1(arg)\n * Internal function to write log with verbosity 1. Will evaluate to\n * empty expression if PJ_LOG_MAX_LEVEL is below 1.\n * @param arg       Log expression.\n */\n#if PJ_LOG_MAX_LEVEL >= 1\n    #define pj_log_wrapper_1(arg)\tpj_log_1 arg\n    /** Internal function. */\n    PJ_DECL(void) pj_log_1(const char *src, const char *format, ...);\n#else\n    #define pj_log_wrapper_1(arg)\n#endif\n\n/**\n * @def pj_log_wrapper_2(arg)\n * Internal function to write log with verbosity 2. Will evaluate to\n * empty expression if PJ_LOG_MAX_LEVEL is below 2.\n * @param arg       Log expression.\n */\n#if PJ_LOG_MAX_LEVEL >= 2\n    #define pj_log_wrapper_2(arg)\tpj_log_2 arg\n    /** Internal function. */\n    PJ_DECL(void) pj_log_2(const char *src, const char *format, ...);\n#else\n    #define pj_log_wrapper_2(arg)\n#endif\n\n/**\n * @def pj_log_wrapper_3(arg)\n * Internal function to write log with verbosity 3. Will evaluate to\n * empty expression if PJ_LOG_MAX_LEVEL is below 3.\n * @param arg       Log expression.\n */\n#if PJ_LOG_MAX_LEVEL >= 3\n    #define pj_log_wrapper_3(arg)\tpj_log_3 arg\n    /** Internal function. */\n    PJ_DECL(void) pj_log_3(const char *src, const char *format, ...);\n#else\n    #define pj_log_wrapper_3(arg)\n#endif\n\n/**\n * @def pj_log_wrapper_4(arg)\n * Internal function to write log with verbosity 4. Will evaluate to\n * empty expression if PJ_LOG_MAX_LEVEL is below 4.\n * @param arg       Log expression.\n */\n#if PJ_LOG_MAX_LEVEL >= 4\n    #define pj_log_wrapper_4(arg)\tpj_log_4 arg\n    /** Internal function. */\n    PJ_DECL(void) pj_log_4(const char *src, const char *format, ...);\n#else\n    #define pj_log_wrapper_4(arg)\n#endif\n\n/**\n * @def pj_log_wrapper_5(arg)\n * Internal function to write log with verbosity 5. Will evaluate to\n * empty expression if PJ_LOG_MAX_LEVEL is below 5.\n * @param arg       Log expression.\n */\n#if PJ_LOG_MAX_LEVEL >= 5\n    #define pj_log_wrapper_5(arg)\tpj_log_5 arg\n    /** Internal function. */\n    PJ_DECL(void) pj_log_5(const char *src, const char *format, ...);\n#else\n    #define pj_log_wrapper_5(arg)\n#endif\n\n/**\n * @def pj_log_wrapper_6(arg)\n * Internal function to write log with verbosity 6. Will evaluate to\n * empty expression if PJ_LOG_MAX_LEVEL is below 6.\n * @param arg       Log expression.\n */\n#if PJ_LOG_MAX_LEVEL >= 6\n    #define pj_log_wrapper_6(arg)\tpj_log_6 arg\n    /** Internal function. */\n    PJ_DECL(void) pj_log_6(const char *src, const char *format, ...);\n#else\n    #define pj_log_wrapper_6(arg)\n#endif\n\n\nPJ_END_DECL \n\n#endif  /* __PJ_LOG_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/math.h",
    "content": "/* $Id: math.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#ifndef __PJ_MATH_H__\n#define __PJ_MATH_H__\n\n/**\n * @file math.h\n * @brief Mathematics and Statistics.\n */\n\n#include <pj/string.h>\n#include <pj/compat/high_precision.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup pj_math Mathematics and Statistics\n * @ingroup PJ_MISC\n * @{\n *\n * Provides common mathematics constants and operations, and also standard\n * statistics calculation (min, max, mean, standard deviation). Statistics\n * calculation is done in realtime (statistics state is updated on time each\n * new sample comes).\n */\n\n/**\n * Mathematical constants\n */\n#define PJ_PI\t\t    3.14159265358979323846\t/* pi\t    */\n#define PJ_1_PI\t\t    0.318309886183790671538\t/* 1/pi\t    */\n\n/**\n * Mathematical macro\n */\n#define\tPJ_ABS(x)\t((x) >  0 ? (x) : -(x))\n#define\tPJ_MAX(x, y)\t((x) > (y)? (x) : (y))\n#define\tPJ_MIN(x, y)\t((x) < (y)? (x) : (y))\n\n/**\n * This structure describes statistics state.\n */\ntypedef struct pj_math_stat\n{\n    int\t\t     n;\t\t/* number of samples\t*/\n    int\t\t     max;\t/* maximum value\t*/\n    int\t\t     min;\t/* minimum value\t*/\n    int\t\t     last;\t/* last value\t\t*/\n    int\t\t     mean;\t/* mean\t\t\t*/\n\n    /* Private members */\n#if PJ_HAS_FLOATING_POINT\n    float\t     fmean_;\t/* mean(floating point) */\n#else\n    int\t\t     mean_res_;\t/* mean residu\t\t*/\n#endif\n    pj_highprec_t    m2_;\t/* variance * n\t\t*/\n} pj_math_stat;\n\n/**\n * Calculate integer square root of an integer.\n *\n * @param i         Integer to be calculated.\n *\n * @return          Square root result.\n */\nPJ_INLINE(unsigned) pj_isqrt(unsigned i)\n{\n    unsigned res = 1, prev;\n    \n    /* Rough guess, calculate half bit of input */\n    prev = i >> 2;\n    while (prev) {\n\tprev >>= 2;\n\tres <<= 1;\n    }\n\n    /* Babilonian method */\n    do {\n\tprev = res;\n\tres = (prev + i/prev) >> 1;\n    } while ((prev+res)>>1 != res);\n\n    return res;\n}\n\n/**\n * Initialize statistics state.\n *\n * @param stat\t    Statistic state.\n */\nPJ_INLINE(void) pj_math_stat_init(pj_math_stat *stat)\n{\n    pj_bzero(stat, sizeof(pj_math_stat));\n}\n\n/**\n * Update statistics state as a new sample comes.\n *\n * @param stat\t    Statistic state.\n * @param val\t    The new sample data.\n */\nPJ_INLINE(void) pj_math_stat_update(pj_math_stat *stat, int val)\n{\n#if PJ_HAS_FLOATING_POINT\n    float\t     delta;\n#else\n    int\t\t     delta;\n#endif\n\n    stat->last = val;\n    \n    if (stat->n++) {\n\tif (stat->min > val)\n\t    stat->min = val;\n\tif (stat->max < val)\n\t    stat->max = val;\n    } else {\n\tstat->min = stat->max = val;\n    }\n\n#if PJ_HAS_FLOATING_POINT\n    delta = val - stat->fmean_;\n    stat->fmean_ += delta/stat->n;\n    \n    /* Return mean value with 'rounding' */\n    stat->mean = (int) (stat->fmean_ + 0.5);\n\n    stat->m2_ += (int)(delta * (val-stat->fmean_));\n#else\n    delta = val - stat->mean;\n    stat->mean += delta/stat->n;\n    stat->mean_res_ += delta % stat->n;\n    if (stat->mean_res_ >= stat->n) {\n\t++stat->mean;\n\tstat->mean_res_ -= stat->n;\n    } else if (stat->mean_res_ <= -stat->n) {\n\t--stat->mean;\n\tstat->mean_res_ += stat->n;\n    }\n\n    stat->m2_ += delta * (val-stat->mean);\n#endif\n}\n\n/**\n * Get the standard deviation of specified statistics state.\n *\n * @param stat\t    Statistic state.\n *\n * @return\t    The standard deviation.\n */\nPJ_INLINE(unsigned) pj_math_stat_get_stddev(const pj_math_stat *stat)\n{\n    if (stat->n == 0) return 0;\n    return (pj_isqrt((unsigned)(stat->m2_/stat->n)));\n}\n\n/**\n * Set the standard deviation of statistics state. This is useful when\n * the statistic state is operated in 'read-only' mode as a storage of \n * statistical data.\n *\n * @param stat\t    Statistic state.\n *\n * @param dev\t    The standard deviation.\n */\nPJ_INLINE(void) pj_math_stat_set_stddev(pj_math_stat *stat, unsigned dev)\n{\n    if (stat->n == 0) \n\tstat->n = 1;\n    stat->m2_ = dev*dev*stat->n;\n}\n\n/** @} */\n\nPJ_END_DECL\n\n#endif /* __PJ_MATH_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/os.h",
    "content": "/* $Id: os.h 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_OS_H__\n#define __PJ_OS_H__\n\n/**\n * @file os.h\n * @brief OS dependent functions\n */\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_OS Operating System Dependent Functionality.\n */\n\n\n/* **************************************************************************/\n/**\n * @defgroup PJ_SYS_INFO System Information\n * @ingroup PJ_OS\n * @{\n */\n\n/**\n * These enumeration contains constants to indicate support of miscellaneous\n * system features. These will go in \"flags\" field of #pj_sys_info structure.\n */\ntypedef enum pj_sys_info_flag\n{\n    /**\n     * Support for Apple iOS background feature.\n     */\n    PJ_SYS_HAS_IOS_BG = 1\n\n} pj_sys_info_flag;\n\n\n/**\n * This structure contains information about the system. Use #pj_get_sys_info()\n * to obtain the system information.\n */\ntypedef struct pj_sys_info\n{\n    /**\n     * Null terminated string containing processor information (e.g. \"i386\",\n     * \"x86_64\"). It may contain empty string if the value cannot be obtained.\n     */\n    pj_str_t\tmachine;\n\n    /**\n     * Null terminated string identifying the system operation (e.g. \"Linux\",\n     * \"win32\", \"wince\"). It may contain empty string if the value cannot be\n     * obtained.\n     */\n    pj_str_t\tos_name;\n\n    /**\n     * A number containing the operating system version number. By convention,\n     * this field is divided into four bytes, where the highest order byte\n     * contains the most major version of the OS, the next less significant\n     * byte contains the less major version, and so on. How the OS version\n     * number is mapped into these four bytes would be specific for each OS.\n     * For example, Linux-2.6.32-28 would yield \"os_ver\" value of 0x0206201c,\n     * while for Windows 7 it will be 0x06010000 (because dwMajorVersion is\n     * 6 and dwMinorVersion is 1 for Windows 7).\n     *\n     * This field may contain zero if the OS version cannot be obtained.\n     */\n    pj_uint32_t\tos_ver;\n\n    /**\n     * Null terminated string identifying the SDK name that is used to build\n     * the library (e.g. \"glibc\", \"uclibc\", \"msvc\", \"wince\"). It may contain\n     * empty string if the value cannot eb obtained.\n     */\n    pj_str_t\tsdk_name;\n\n    /**\n     * A number containing the SDK version, using the numbering convention as\n     * the \"os_ver\" field. The value will be zero if the version cannot be\n     * obtained.\n     */\n    pj_uint32_t\tsdk_ver;\n\n    /**\n     * A longer null terminated string identifying the underlying system with\n     * as much information as possible.\n     */\n    pj_str_t\tinfo;\n\n    /**\n     * Other flags containing system specific information. The value is\n     * bitmask of #pj_sys_info_flag constants.\n     */\n    pj_uint32_t\tflags;\n\n} pj_sys_info;\n\n\n/**\n * Obtain the system information.\n *\n * @return\tSystem information structure.\n */\nPJ_DECL(const pj_sys_info*) pj_get_sys_info(void);\n\n/*\n * @}\n */\n\n/* **************************************************************************/\n/**\n * @defgroup PJ_THREAD Threads\n * @ingroup PJ_OS\n * @{\n * This module provides multithreading API.\n *\n * \\section pj_thread_examples_sec Examples\n *\n * For examples, please see:\n *  - \\ref page_pjlib_thread_test\n *  - \\ref page_pjlib_sleep_test\n *\n */\n\n/**\n * Thread creation flags:\n * - PJ_THREAD_SUSPENDED: specify that the thread should be created suspended.\n */\ntypedef enum pj_thread_create_flags\n{\n    PJ_THREAD_SUSPENDED = 1\n} pj_thread_create_flags;\n\n\n/**\n * Type of thread entry function.\n */\ntypedef int (PJ_THREAD_FUNC pj_thread_proc)(void*);\n\n/**\n * Size of thread struct.\n */\n#if !defined(PJ_THREAD_DESC_SIZE)\n#   define PJ_THREAD_DESC_SIZE\t    (64)\n#endif\n\n/**\n * Thread structure, to thread's state when the thread is created by external\n * or native API. \n */\ntypedef long pj_thread_desc[PJ_THREAD_DESC_SIZE];\n\n/**\n * Get process ID.\n * @return process ID.\n */\nPJ_DECL(pj_uint32_t) pj_getpid(void);\n\n/**\n * Create a new thread.\n *\n * @param pool          The memory pool from which the thread record \n *                      will be allocated from.\n * @param thread_name   The optional name to be assigned to the thread.\n * @param proc          Thread entry function.\n * @param arg           Argument to be passed to the thread entry function.\n * @param stack_size    The size of the stack for the new thread, or ZERO or\n *                      PJ_THREAD_DEFAULT_STACK_SIZE to let the \n *\t\t        library choose the reasonable size for the stack. \n *                      For some systems, the stack will be allocated from \n *                      the pool, so the pool must have suitable capacity.\n * @param flags         Flags for thread creation, which is bitmask combination \n *                      from enum pj_thread_create_flags.\n * @param thread        Pointer to hold the newly created thread.\n *\n * @return\t        PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_thread_create(  pj_pool_t *pool, \n                                        const char *thread_name,\n\t\t\t\t        pj_thread_proc *proc, \n                                        void *arg,\n\t\t\t\t        pj_size_t stack_size, \n                                        unsigned flags,\n\t\t\t\t\tpj_thread_t **thread );\n\n/**\n * Register a thread that was created by external or native API to PJLIB.\n * This function must be called in the context of the thread being registered.\n * When the thread is created by external function or API call,\n * it must be 'registered' to PJLIB using pj_thread_register(), so that it can\n * cooperate with PJLIB's framework. During registration, some data needs to\n * be maintained, and this data must remain available during the thread's \n * lifetime.\n *\n * @param thread_name   The optional name to be assigned to the thread.\n * @param desc          Thread descriptor, which must be available throughout \n *                      the lifetime of the thread.\n * @param thread        Pointer to hold the created thread handle.\n *\n * @return              PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_thread_register ( const char *thread_name,\n\t\t\t\t\t  pj_thread_desc desc,\n\t\t\t\t\t  pj_thread_t **thread);\n\n/**\n * Check if this thread has been registered to PJLIB.\n *\n * @return\t\tNon-zero if it is registered.\n */\nPJ_DECL(pj_bool_t) pj_thread_is_registered(void);\n\n\n/**\n * Get thread priority value for the thread.\n *\n * @param thread\tThread handle.\n *\n * @return\t\tThread priority value, or -1 on error.\n */\nPJ_DECL(int) pj_thread_get_prio(pj_thread_t *thread);\n\n\n/**\n * Set the thread priority. The priority value must be in the priority\n * value range, which can be retrieved with #pj_thread_get_prio_min() and\n * #pj_thread_get_prio_max() functions.\n *\n * @param thread\tThread handle.\n * @param prio\t\tNew priority to be set to the thread.\n *\n * @return\t\tPJ_SUCCESS on success or the error code.\n */\nPJ_DECL(pj_status_t) pj_thread_set_prio(pj_thread_t *thread,  int prio);\n\n/**\n * Get the lowest priority value available for this thread.\n *\n * @param thread\tThread handle.\n * @return\t\tMinimum thread priority value, or -1 on error.\n */\nPJ_DECL(int) pj_thread_get_prio_min(pj_thread_t *thread);\n\n\n/**\n * Get the highest priority value available for this thread.\n *\n * @param thread\tThread handle.\n * @return\t\tMinimum thread priority value, or -1 on error.\n */\nPJ_DECL(int) pj_thread_get_prio_max(pj_thread_t *thread);\n\n\n/**\n * Return native handle from pj_thread_t for manipulation using native\n * OS APIs.\n *\n * @param thread\tPJLIB thread descriptor.\n *\n * @return\t\tNative thread handle. For example, when the\n *\t\t\tbackend thread uses pthread, this function will\n *\t\t\treturn pointer to pthread_t, and on Windows,\n *\t\t\tthis function will return HANDLE.\n */\nPJ_DECL(void*) pj_thread_get_os_handle(pj_thread_t *thread);\n\n/**\n * Get thread name.\n *\n * @param thread    The thread handle.\n *\n * @return Thread name as null terminated string.\n */\nPJ_DECL(const char*) pj_thread_get_name(pj_thread_t *thread);\n\n/**\n * Resume a suspended thread.\n *\n * @param thread    The thread handle.\n *\n * @return zero on success.\n */\nPJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread);\n\n/**\n * Get the current thread.\n *\n * @return Thread handle of current thread.\n */\nPJ_DECL(pj_thread_t*) pj_thread_this(void);\n\n/**\n * Join thread, and block the caller thread until the specified thread exits.\n * If it is called from within the thread itself, it will return immediately\n * with failure status.\n * If the specified thread has already been dead, or it does not exist,\n * the function will return immediately with successful status.\n *\n * @param thread    The thread handle.\n *\n * @return PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread);\n\n\n/**\n * Destroy thread and release resources allocated for the thread.\n * However, the memory allocated for the pj_thread_t itself will only be released\n * when the pool used to create the thread is destroyed.\n *\n * @param thread    The thread handle.\n *\n * @return zero on success.\n */\nPJ_DECL(pj_status_t) pj_thread_destroy(pj_thread_t *thread);\n\n\n/**\n * Put the current thread to sleep for the specified miliseconds.\n *\n * @param msec Miliseconds delay.\n *\n * @return zero if successfull.\n */\nPJ_DECL(pj_status_t) pj_thread_sleep(unsigned msec);\n\n/**\n * @def PJ_CHECK_STACK()\n * PJ_CHECK_STACK() macro is used to check the sanity of the stack.\n * The OS implementation may check that no stack overflow occurs, and\n * it also may collect statistic about stack usage.\n */\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n\n#  define PJ_CHECK_STACK() pj_thread_check_stack(__FILE__, __LINE__)\n\n/** @internal\n * The implementation of stack checking. \n */\nPJ_DECL(void) pj_thread_check_stack(const char *file, int line);\n\n/** @internal\n * Get maximum stack usage statistic. \n */\nPJ_DECL(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread);\n\n/** @internal\n * Dump thread stack status. \n */\nPJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,\n\t\t\t\t\t      const char **file,\n\t\t\t\t\t      int *line);\n#else\n\n#  define PJ_CHECK_STACK()\n/** pj_thread_get_stack_max_usage() for the thread */\n#  define pj_thread_get_stack_max_usage(thread)\t    0\n/** pj_thread_get_stack_info() for the thread */\n#  define pj_thread_get_stack_info(thread,f,l)\t    (*(f)=\"\",*(l)=0)\n#endif\t/* PJ_OS_HAS_CHECK_STACK */\n\n/**\n * @}\n */\n\n/* **************************************************************************/\n/**\n * @defgroup PJ_SYMBIAN_OS Symbian OS Specific\n * @ingroup PJ_OS\n * @{\n * Functionalities specific to Symbian OS.\n *\n * Symbian OS strongly discourages the use of polling since this wastes\n * CPU power, and instead provides Active Object and Active Scheduler\n * pattern to allow application (in this case, PJLIB) to register asynchronous\n * tasks. PJLIB port for Symbian complies to this recommended behavior.\n * As the result, few things have been changed in PJLIB for Symbian:\n *\t- the timer heap (see @ref PJ_TIMER) is implemented with active\n *\t  object framework, and each timer entry registered to the timer \n *\t  heap will register an Active Object to the Active Scheduler.\n *\t  Because of this, polling the timer heap with pj_timer_heap_poll()\n *\t  is no longer necessary, and this function will just evaluate\n *\t  to nothing.\n *\t- the ioqueue (see @ref PJ_IOQUEUE) is also implemented with\n *\t  active object framework, with each asynchronous operation will\n *\t  register an Active Object to the Active Scheduler. Because of\n *\t  this, polling the ioqueue with pj_ioqueue_poll() is no longer\n *\t  necessary, and this function will just evaluate to nothing.\n *\n * Since timer heap and ioqueue polling are no longer necessary, Symbian\n * application can now poll for all events by calling \n * \\a User::WaitForAnyRequest() and \\a CActiveScheduler::RunIfReady().\n * PJLIB provides a thin wrapper which calls these two functions,\n * called pj_symbianos_poll().\n */\n \n/**\n * Wait the completion of any Symbian active objects. When the timeout\n * value is not specified (the \\a ms_timeout argument is -1), this \n * function is a thin wrapper which calls \\a User::WaitForAnyRequest() \n * and \\a CActiveScheduler::RunIfReady(). If the timeout value is\n * specified, this function will schedule a timer entry to the timer\n * heap (which is an Active Object), to limit the wait time for event\n * occurences. Scheduling a timer entry is an expensive operation,\n * therefore application should only specify a timeout value when it's\n * really necessary (for example, when it's not sure there are other\n * Active Objects currently running in the application).\n *\n * @param priority\tThe minimum priority of the Active Objects to\n *\t\t\tpoll, which values are from CActive::TPriority\n *\t\t\tconstants. If -1 is given, CActive::EPriorityStandard.\n *\t\t\tpriority will be used.\n * @param ms_timeout\tOptional timeout to wait. Application should\n *\t\t\tspecify -1 to let the function wait indefinitely\n *\t\t\tfor any events.\n *\n * @return\t\tPJ_TRUE if there have been any events executed\n *\t\t\tduring the polling. This function will only return\n *\t\t\tPJ_FALSE if \\a ms_timeout argument is specified\n *\t\t\t(i.e. the value is not -1) and there was no event\n *\t\t\texecuted when the timeout timer elapsed.\n */\nPJ_DECL(pj_bool_t) pj_symbianos_poll(int priority, int ms_timeout);\n\n\n/**\n * This structure declares Symbian OS specific parameters that can be\n * specified when calling #pj_symbianos_set_params().\n */\ntypedef struct pj_symbianos_params \n{\n    /**\n     * Optional RSocketServ instance to be used by PJLIB. If this\n     * value is NULL, PJLIB will create a new RSocketServ instance\n     * when pj_init() is called.\n     */\n    void\t*rsocketserv;\n    \n    /**\n     * Optional RConnection instance to be used by PJLIB when creating\n     * sockets. If this value is NULL, no RConnection will be\n     * specified when creating sockets.\n     */\n    void\t*rconnection;\n    \n    /**\n     * Optional RHostResolver instance to be used by PJLIB. If this value\n     * is NULL, a new RHostResolver instance will be created when\n     * pj_init() is called.\n     */\n    void \t*rhostresolver;\n     \n    /**\n     * Optional RHostResolver for IPv6 instance to be used by PJLIB. \n     * If this value is NULL, a new RHostResolver instance will be created\n     * when pj_init() is called.\n     */\n    void \t*rhostresolver6;\n     \n} pj_symbianos_params;\n\n/**\n * Specify Symbian OS parameters to be used by PJLIB. This function MUST\n * be called before #pj_init() is called.\n *\n * @param prm\t\tSymbian specific parameters.\n *\n * @return\t\tPJ_SUCCESS if the parameters can be applied\n *\t\t\tsuccessfully.\n */\nPJ_DECL(pj_status_t) pj_symbianos_set_params(pj_symbianos_params *prm);\n\n/**\n *  Notify PJLIB that the access point connection has been down or unusable\n *  and PJLIB should not try to access the Symbian socket API (especially ones\n *  that send packets). Sending packet when RConnection is reconnected to \n *  different access point may cause the WaitForRequest() for the function to \n *  block indefinitely.\n *  \n *  @param up\t\tIf set to PJ_FALSE it will cause PJLIB to not try\n *  \t\t\tto access socket API, and error will be returned\n *  \t\t\timmediately instead.\n */\nPJ_DECL(void) pj_symbianos_set_connection_status(pj_bool_t up);\n\n/**\n * @}\n */\n \n/* **************************************************************************/\n/**\n * @defgroup PJ_TLS Thread Local Storage.\n * @ingroup PJ_OS\n * @{\n */\n\n/** \n * Allocate thread local storage index. The initial value of the variable at\n * the index is zero.\n *\n * @param index\t    Pointer to hold the return value.\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_thread_local_alloc(long *index);\n\n/**\n * Deallocate thread local variable.\n *\n * @param index\t    The variable index.\n */\nPJ_DECL(void) pj_thread_local_free(long index);\n\n/**\n * Set the value of thread local variable.\n *\n * @param index\t    The index of the variable.\n * @param value\t    The value.\n */\nPJ_DECL(pj_status_t) pj_thread_local_set(long index, void *value);\n\n/**\n * Get the value of thread local variable.\n *\n * @param index\t    The index of the variable.\n * @return\t    The value.\n */\nPJ_DECL(void*) pj_thread_local_get(long index);\n\n\n/**\n * @}\n */\n\n\n/* **************************************************************************/\n/**\n * @defgroup PJ_ATOMIC Atomic Variables\n * @ingroup PJ_OS\n * @{\n *\n * This module provides API to manipulate atomic variables.\n *\n * \\section pj_atomic_examples_sec Examples\n *\n * For some example codes, please see:\n *  - @ref page_pjlib_atomic_test\n */\n\n\n/**\n * Create atomic variable.\n *\n * @param pool\t    The pool.\n * @param initial   The initial value of the atomic variable.\n * @param atomic    Pointer to hold the atomic variable upon return.\n *\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_atomic_create( pj_pool_t *pool, \n\t\t\t\t       pj_atomic_value_t initial,\n\t\t\t\t       pj_atomic_t **atomic );\n\n/**\n * Destroy atomic variable.\n *\n * @param atomic_var\tthe atomic variable.\n *\n * @return PJ_SUCCESS if success.\n */\nPJ_DECL(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var );\n\n/**\n * Set the value of an atomic type, and return the previous value.\n *\n * @param atomic_var\tthe atomic variable.\n * @param value\t\tvalue to be set to the variable.\n */\nPJ_DECL(void) pj_atomic_set( pj_atomic_t *atomic_var, \n\t\t\t     pj_atomic_value_t value);\n\n/**\n * Get the value of an atomic type.\n *\n * @param atomic_var\tthe atomic variable.\n *\n * @return the value of the atomic variable.\n */\nPJ_DECL(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var);\n\n/**\n * Increment the value of an atomic type.\n *\n * @param atomic_var\tthe atomic variable.\n */\nPJ_DECL(void) pj_atomic_inc(pj_atomic_t *atomic_var);\n\n/**\n * Increment the value of an atomic type and get the result.\n *\n * @param atomic_var\tthe atomic variable.\n *\n * @return              The incremented value.\n */\nPJ_DECL(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var);\n\n/**\n * Decrement the value of an atomic type.\n *\n * @param atomic_var\tthe atomic variable.\n */\nPJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var);\n\n/**\n * Decrement the value of an atomic type and get the result.\n *\n * @param atomic_var\tthe atomic variable.\n *\n * @return              The decremented value.\n */\nPJ_DECL(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var);\n\n/**\n * Add a value to an atomic type.\n *\n * @param atomic_var\tThe atomic variable.\n * @param value\t\tValue to be added.\n */\nPJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var,\n\t\t\t     pj_atomic_value_t value);\n\n/**\n * Add a value to an atomic type and get the result.\n *\n * @param atomic_var\tThe atomic variable.\n * @param value\t\tValue to be added.\n *\n * @return              The result after the addition.\n */\nPJ_DECL(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,\n\t\t\t                          pj_atomic_value_t value);\n\n/**\n * @}\n */\n\n/* **************************************************************************/\n/**\n * @defgroup PJ_MUTEX Mutexes.\n * @ingroup PJ_OS\n * @{\n *\n * Mutex manipulation. Alternatively, application can use higher abstraction\n * for lock objects, which provides uniform API for all kinds of lock \n * mechanisms, including mutex. See @ref PJ_LOCK for more information.\n */\n\n/**\n * Mutex types:\n *  - PJ_MUTEX_DEFAULT: default mutex type, which is system dependent.\n *  - PJ_MUTEX_SIMPLE: non-recursive mutex.\n *  - PJ_MUTEX_RECURSE: recursive mutex.\n */\ntypedef enum pj_mutex_type_e\n{\n    PJ_MUTEX_DEFAULT,\n    PJ_MUTEX_SIMPLE,\n    PJ_MUTEX_RECURSE\n} pj_mutex_type_e;\n\n\n/**\n * Create mutex of the specified type.\n *\n * @param pool\t    The pool.\n * @param name\t    Name to be associated with the mutex (for debugging).\n * @param type\t    The type of the mutex, of type #pj_mutex_type_e.\n * @param mutex\t    Pointer to hold the returned mutex instance.\n *\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_mutex_create(pj_pool_t *pool, \n                                     const char *name,\n\t\t\t\t     int type, \n                                     pj_mutex_t **mutex);\n\n/**\n * Create simple, non-recursive mutex.\n * This function is a simple wrapper for #pj_mutex_create to create \n * non-recursive mutex.\n *\n * @param pool\t    The pool.\n * @param name\t    Mutex name.\n * @param mutex\t    Pointer to hold the returned mutex instance.\n *\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,\n\t\t\t\t\t     pj_mutex_t **mutex );\n\n/**\n * Create recursive mutex.\n * This function is a simple wrapper for #pj_mutex_create to create \n * recursive mutex.\n *\n * @param pool\t    The pool.\n * @param name\t    Mutex name.\n * @param mutex\t    Pointer to hold the returned mutex instance.\n *\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,\n\t\t\t\t\t        const char *name,\n\t\t\t\t\t\tpj_mutex_t **mutex );\n\n/**\n * Acquire mutex lock.\n *\n * @param mutex\t    The mutex.\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex);\n\n/**\n * Release mutex lock.\n *\n * @param mutex\t    The mutex.\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex);\n\n/**\n * Try to acquire mutex lock.\n *\n * @param mutex\t    The mutex.\n * @return\t    PJ_SUCCESS on success, or the error code if the\n *\t\t    lock couldn't be acquired.\n */\nPJ_DECL(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex);\n\n/**\n * Destroy mutex.\n *\n * @param mutex\t    Te mutex.\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex);\n\n/**\n * Determine whether calling thread is owning the mutex (only available when\n * PJ_DEBUG is set).\n * @param mutex\t    The mutex.\n * @return\t    Non-zero if yes.\n */\nPJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex);\n\n/**\n * @}\n */\n\n/* **************************************************************************/\n/**\n * @defgroup PJ_RW_MUTEX Reader/Writer Mutex\n * @ingroup PJ_OS\n * @{\n * Reader/writer mutex is a classic synchronization object where multiple\n * readers can acquire the mutex, but only a single writer can acquire the \n * mutex.\n */\n\n/**\n * Opaque declaration for reader/writer mutex.\n * Reader/writer mutex is a classic synchronization object where multiple\n * readers can acquire the mutex, but only a single writer can acquire the \n * mutex.\n */\ntypedef struct pj_rwmutex_t pj_rwmutex_t;\n\n/**\n * Create reader/writer mutex.\n *\n * @param pool\t    Pool to allocate memory for the mutex.\n * @param name\t    Name to be assigned to the mutex.\n * @param mutex\t    Pointer to receive the newly created mutex.\n *\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,\n\t\t\t\t       pj_rwmutex_t **mutex);\n\n/**\n * Lock the mutex for reading.\n *\n * @param mutex\t    The mutex.\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex);\n\n/**\n * Lock the mutex for writing.\n *\n * @param mutex\t    The mutex.\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex);\n\n/**\n * Release read lock.\n *\n * @param mutex\t    The mutex.\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex);\n\n/**\n * Release write lock.\n *\n * @param mutex\t    The mutex.\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex);\n\n/**\n * Destroy reader/writer mutex.\n *\n * @param mutex\t    The mutex.\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex);\n\n\n/**\n * @}\n */\n\n\n/* **************************************************************************/\n/**\n * @defgroup PJ_CRIT_SEC Critical sections.\n * @ingroup PJ_OS\n * @{\n * Critical section protection can be used to protect regions where:\n *  - mutual exclusion protection is needed.\n *  - it's rather too expensive to create a mutex.\n *  - the time spent in the region is very very brief.\n *\n * Critical section is a global object, and it prevents any threads from\n * entering any regions that are protected by critical section once a thread\n * is already in the section.\n *\n * Critial section is \\a not recursive!\n *\n * Application <b>MUST NOT</b> call any functions that may cause current\n * thread to block (such as allocating memory, performing I/O, locking mutex,\n * etc.) while holding the critical section.\n */\n/**\n * Enter critical section.\n */\nPJ_DECL(void) pj_enter_critical_section(void);\n\n/**\n * Leave critical section.\n */\nPJ_DECL(void) pj_leave_critical_section(void);\n\n/**\n * @}\n */\n\n/* **************************************************************************/\n#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0\n/**\n * @defgroup PJ_SEM Semaphores.\n * @ingroup PJ_OS\n * @{\n *\n * This module provides abstraction for semaphores, where available.\n */\n\n/**\n * Create semaphore.\n *\n * @param pool\t    The pool.\n * @param name\t    Name to be assigned to the semaphore (for logging purpose)\n * @param initial   The initial count of the semaphore.\n * @param max\t    The maximum count of the semaphore.\n * @param sem\t    Pointer to hold the semaphore created.\n *\n * @return\t    PJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool, \n                                    const char *name,\n\t\t\t\t    unsigned initial, \n                                    unsigned max,\n\t\t\t\t    pj_sem_t **sem);\n\n/**\n * Wait for semaphore.\n *\n * @param sem\tThe semaphore.\n *\n * @return\tPJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem);\n\n/**\n * Try wait for semaphore.\n *\n * @param sem\tThe semaphore.\n *\n * @return\tPJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem);\n\n/**\n * Release semaphore.\n *\n * @param sem\tThe semaphore.\n *\n * @return\tPJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem);\n\n/**\n * Destroy semaphore.\n *\n * @param sem\tThe semaphore.\n *\n * @return\tPJ_SUCCESS on success, or the error code.\n */\nPJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem);\n\n/**\n * @}\n */\n#endif\t/* PJ_HAS_SEMAPHORE */\n\n\n/* **************************************************************************/\n#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0\n/**\n * @defgroup PJ_EVENT Event Object.\n * @ingroup PJ_OS\n * @{\n *\n * This module provides abstraction to event object (e.g. Win32 Event) where\n * available. Event objects can be used for synchronization among threads.\n */\n\n/**\n * Create event object.\n *\n * @param pool\t\tThe pool.\n * @param name\t\tThe name of the event object (for logging purpose).\n * @param manual_reset\tSpecify whether the event is manual-reset\n * @param initial\tSpecify the initial state of the event object.\n * @param event\t\tPointer to hold the returned event object.\n *\n * @return event handle, or NULL if failed.\n */\nPJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,\n\t\t\t\t     pj_bool_t manual_reset, pj_bool_t initial,\n\t\t\t\t     pj_event_t **event);\n\n/**\n * Wait for event to be signaled.\n *\n * @param event\t    The event object.\n *\n * @return zero if successfull.\n */\nPJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event);\n\n/**\n * Try wait for event object to be signalled.\n *\n * @param event The event object.\n *\n * @return zero if successfull.\n */\nPJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event);\n\n/**\n * Set the event object state to signaled. For auto-reset event, this \n * will only release the first thread that are waiting on the event. For\n * manual reset event, the state remains signaled until the event is reset.\n * If there is no thread waiting on the event, the event object state \n * remains signaled.\n *\n * @param event\t    The event object.\n *\n * @return zero if successfull.\n */\nPJ_DECL(pj_status_t) pj_event_set(pj_event_t *event);\n\n/**\n * Set the event object to signaled state to release appropriate number of\n * waiting threads and then reset the event object to non-signaled. For\n * manual-reset event, this function will release all waiting threads. For\n * auto-reset event, this function will only release one waiting thread.\n *\n * @param event\t    The event object.\n *\n * @return zero if successfull.\n */\nPJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event);\n\n/**\n * Set the event object state to non-signaled.\n *\n * @param event\t    The event object.\n *\n * @return zero if successfull.\n */\nPJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event);\n\n/**\n * Destroy the event object.\n *\n * @param event\t    The event object.\n *\n * @return zero if successfull.\n */\nPJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event);\n\n/**\n * @}\n */\n#endif\t/* PJ_HAS_EVENT_OBJ */\n\n/* **************************************************************************/\n/**\n * @addtogroup PJ_TIME Time Data Type and Manipulation.\n * @ingroup PJ_OS\n * @{\n * This module provides API for manipulating time.\n *\n * \\section pj_time_examples_sec Examples\n *\n * For examples, please see:\n *  - \\ref page_pjlib_sleep_test\n */\n\n/**\n * Get current time of day in local representation.\n *\n * @param tv\tVariable to store the result.\n *\n * @return zero if successfull.\n */\nPJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv);\n\n\n/**\n * Parse time value into date/time representation.\n *\n * @param tv\tThe time.\n * @param pt\tVariable to store the date time result.\n *\n * @return zero if successfull.\n */\nPJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt);\n\n/**\n * Encode date/time to time value.\n *\n * @param pt\tThe date/time.\n * @param tv\tVariable to store time value result.\n *\n * @return zero if successfull.\n */\nPJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);\n\n/**\n * Convert local time to GMT.\n *\n * @param tv\tTime to convert.\n *\n * @return zero if successfull.\n */\nPJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);\n\n/**\n * Convert GMT to local time.\n *\n * @param tv\tTime to convert.\n *\n * @return zero if successfull.\n */\nPJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);\n\n/**\n * @}\n */\n\n/* **************************************************************************/\n#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0\n\n/**\n * @defgroup PJ_TERM Terminal\n * @ingroup PJ_OS\n * @{\n */\n\n/**\n * Set current terminal color.\n *\n * @param color\t    The RGB color.\n *\n * @return zero on success.\n */\nPJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color);\n\n/**\n * Get current terminal foreground color.\n *\n * @return RGB color.\n */\nPJ_DECL(pj_color_t) pj_term_get_color(void);\n\n/**\n * @}\n */\n\n#endif\t/* PJ_TERM_HAS_COLOR */\n\n/* **************************************************************************/\n/**\n * @defgroup PJ_TIMESTAMP High Resolution Timestamp\n * @ingroup PJ_OS\n * @{\n *\n * PJLIB provides <b>High Resolution Timestamp</b> API to access highest \n * resolution timestamp value provided by the platform. The API is usefull\n * to measure precise elapsed time, and can be used in applications such\n * as profiling.\n *\n * The timestamp value is represented in cycles, and can be related to\n * normal time (in seconds or sub-seconds) using various functions provided.\n *\n * \\section pj_timestamp_examples_sec Examples\n *\n * For examples, please see:\n *  - \\ref page_pjlib_sleep_test\n *  - \\ref page_pjlib_timestamp_test\n */\n\n/*\n * High resolution timer.\n */\n#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0\n\n/**\n * Get monotonic time since some unspecified starting point.\n *\n * @param tv\tVariable to store the result.\n *\n * @return PJ_SUCCESS if successful.\n */\nPJ_DECL(pj_status_t) pj_gettickcount(pj_time_val *tv);\n\n/**\n * Acquire high resolution timer value. The time value are stored\n * in cycles.\n *\n * @param ts\t    High resolution timer value.\n * @return\t    PJ_SUCCESS or the appropriate error code.\n *\n * @see pj_get_timestamp_freq().\n */\nPJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts);\n\n/**\n * Get high resolution timer frequency, in cycles per second.\n *\n * @param freq\t    Timer frequency, in cycles per second.\n * @return\t    PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq);\n\n/**\n * Set timestamp from 32bit values.\n * @param t\t    The timestamp to be set.\n * @param hi\t    The high 32bit part.\n * @param lo\t    The low 32bit part.\n */\nPJ_INLINE(void) pj_set_timestamp32(pj_timestamp *t, pj_uint32_t hi,\n\t\t\t\t   pj_uint32_t lo)\n{\n    t->u32.hi = hi;\n    t->u32.lo = lo;\n}\n\n\n/**\n * Compare timestamp t1 and t2.\n * @param t1\t    t1.\n * @param t2\t    t2.\n * @return\t    -1 if (t1 < t2), 1 if (t1 > t2), or 0 if (t1 == t2)\n */\nPJ_INLINE(int) pj_cmp_timestamp(const pj_timestamp *t1, const pj_timestamp *t2)\n{\n#if PJ_HAS_INT64\n    if (t1->u64 < t2->u64)\n\treturn -1;\n    else if (t1->u64 > t2->u64)\n\treturn 1;\n    else\n\treturn 0;\n#else\n    if (t1->u32.hi < t2->u32.hi ||\n\t(t1->u32.hi == t2->u32.hi && t1->u32.lo < t2->u32.lo))\n\treturn -1;\n    else if (t1->u32.hi > t2->u32.hi ||\n\t     (t1->u32.hi == t2->u32.hi && t1->u32.lo > t2->u32.lo))\n\treturn 1;\n    else\n\treturn 0;\n#endif\n}\n\n\n/**\n * Add timestamp t2 to t1.\n * @param t1\t    t1.\n * @param t2\t    t2.\n */\nPJ_INLINE(void) pj_add_timestamp(pj_timestamp *t1, const pj_timestamp *t2)\n{\n#if PJ_HAS_INT64\n    t1->u64 += t2->u64;\n#else\n    pj_uint32_t old = t1->u32.lo;\n    t1->u32.hi += t2->u32.hi;\n    t1->u32.lo += t2->u32.lo;\n    if (t1->u32.lo < old)\n\t++t1->u32.hi;\n#endif\n}\n\n/**\n * Add timestamp t2 to t1.\n * @param t1\t    t1.\n * @param t2\t    t2.\n */\nPJ_INLINE(void) pj_add_timestamp32(pj_timestamp *t1, pj_uint32_t t2)\n{\n#if PJ_HAS_INT64\n    t1->u64 += t2;\n#else\n    pj_uint32_t old = t1->u32.lo;\n    t1->u32.lo += t2;\n    if (t1->u32.lo < old)\n\t++t1->u32.hi;\n#endif\n}\n\n/**\n * Substract timestamp t2 from t1.\n * @param t1\t    t1.\n * @param t2\t    t2.\n */\nPJ_INLINE(void) pj_sub_timestamp(pj_timestamp *t1, const pj_timestamp *t2)\n{\n#if PJ_HAS_INT64\n    t1->u64 -= t2->u64;\n#else\n    t1->u32.hi -= t2->u32.hi;\n    if (t1->u32.lo >= t2->u32.lo)\n\tt1->u32.lo -= t2->u32.lo;\n    else {\n\tt1->u32.lo -= t2->u32.lo;\n\t--t1->u32.hi;\n    }\n#endif\n}\n\n/**\n * Substract timestamp t2 from t1.\n * @param t1\t    t1.\n * @param t2\t    t2.\n */\nPJ_INLINE(void) pj_sub_timestamp32(pj_timestamp *t1, pj_uint32_t t2)\n{\n#if PJ_HAS_INT64\n    t1->u64 -= t2;\n#else\n    if (t1->u32.lo >= t2)\n\tt1->u32.lo -= t2;\n    else {\n\tt1->u32.lo -= t2;\n\t--t1->u32.hi;\n    }\n#endif\n}\n\n/**\n * Get the timestamp difference between t2 and t1 (that is t2 minus t1),\n * and return a 32bit signed integer difference.\n */\nPJ_INLINE(pj_int32_t) pj_timestamp_diff32(const pj_timestamp *t1,\n\t\t\t\t\t  const pj_timestamp *t2)\n{\n    /* Be careful with the signess (I think!) */\n#if PJ_HAS_INT64\n    pj_int64_t diff = t2->u64 - t1->u64;\n    return (pj_int32_t) diff;\n#else\n    pj_int32 diff = t2->u32.lo - t1->u32.lo;\n    return diff;\n#endif\n}\n\n\n/**\n * Calculate the elapsed time, and store it in pj_time_val.\n * This function calculates the elapsed time using highest precision\n * calculation that is available for current platform, considering\n * whether floating point or 64-bit precision arithmetic is available. \n * For maximum portability, application should prefer to use this function\n * rather than calculating the elapsed time by itself.\n *\n * @param start     The starting timestamp.\n * @param stop      The end timestamp.\n *\n * @return\t    Elapsed time as #pj_time_val.\n *\n * @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec()\n */\nPJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start,\n                                      const pj_timestamp *stop );\n\n/**\n * Calculate the elapsed time as 32-bit miliseconds.\n * This function calculates the elapsed time using highest precision\n * calculation that is available for current platform, considering\n * whether floating point or 64-bit precision arithmetic is available. \n * For maximum portability, application should prefer to use this function\n * rather than calculating the elapsed time by itself.\n *\n * @param start     The starting timestamp.\n * @param stop      The end timestamp.\n *\n * @return\t    Elapsed time in milisecond.\n *\n * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()\n */\nPJ_DECL(pj_uint32_t) pj_elapsed_msec( const pj_timestamp *start,\n                                      const pj_timestamp *stop );\n\n/**\n * Variant of #pj_elapsed_msec() which returns 64bit value.\n */\nPJ_DECL(pj_uint64_t) pj_elapsed_msec64(const pj_timestamp *start,\n                                       const pj_timestamp *stop );\n\n/**\n * Calculate the elapsed time in 32-bit microseconds.\n * This function calculates the elapsed time using highest precision\n * calculation that is available for current platform, considering\n * whether floating point or 64-bit precision arithmetic is available. \n * For maximum portability, application should prefer to use this function\n * rather than calculating the elapsed time by itself.\n *\n * @param start     The starting timestamp.\n * @param stop      The end timestamp.\n *\n * @return\t    Elapsed time in microsecond.\n *\n * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()\n */\nPJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,\n                                      const pj_timestamp *stop );\n\n/**\n * Calculate the elapsed time in 32-bit nanoseconds.\n * This function calculates the elapsed time using highest precision\n * calculation that is available for current platform, considering\n * whether floating point or 64-bit precision arithmetic is available. \n * For maximum portability, application should prefer to use this function\n * rather than calculating the elapsed time by itself.\n *\n * @param start     The starting timestamp.\n * @param stop      The end timestamp.\n *\n * @return\t    Elapsed time in nanoseconds.\n *\n * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec()\n */\nPJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,\n                                         const pj_timestamp *stop );\n\n/**\n * Calculate the elapsed time in 32-bit cycles.\n * This function calculates the elapsed time using highest precision\n * calculation that is available for current platform, considering\n * whether floating point or 64-bit precision arithmetic is available. \n * For maximum portability, application should prefer to use this function\n * rather than calculating the elapsed time by itself.\n *\n * @param start     The starting timestamp.\n * @param stop      The end timestamp.\n *\n * @return\t    Elapsed time in cycles.\n *\n * @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec()\n */\nPJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,\n                                       const pj_timestamp *stop );\n\n\n#endif\t/* PJ_HAS_HIGH_RES_TIMER */\n\n/** @} */\n\n\n/* **************************************************************************/\n/**\n * @defgroup PJ_APP_OS Application execution\n * @ingroup PJ_OS\n * @{\n */\n\n/**\n * Type for application main function.\n */\ntypedef int (*pj_main_func_ptr)(int argc, char *argv[]);\n\n/**\n * Run the application. This function has to be called in the main thread\n * and after doing the necessary initialization according to the flags\n * provided, it will call main_func() function.\n *\n * @param main_func Application's main function.\n * @param argc\t    Number of arguments from the main() function, which\n * \t\t    will be passed to main_func() function.\n * @param argv\t    The arguments from the main() function, which will\n * \t\t    be passed to main_func() function.\n * @param flags     Flags for application execution, currently must be 0.\n *\n * @return          main_func()'s return value.\n */\nPJ_DECL(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],\n\t\t\tunsigned flags);\n\n/** @} */\n\n\n/* **************************************************************************/\n/**\n * Internal PJLIB function to initialize the threading subsystem.\n * @return          PJ_SUCCESS or the appropriate error code.\n */\npj_status_t pj_thread_init(void);\n\n\nPJ_END_DECL\n\n#endif  /* __PJ_OS_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/pool.h",
    "content": "/* $Id: pool.h 4298 2012-11-22 05:00:01Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pj/list.h>\n\n/* See if we use pool's alternate API.\n * The alternate API is used e.g. to implement pool debugging.\n */\n#if PJ_HAS_POOL_ALT_API\n#  include <pj/pool_alt.h>\n#endif\n\n\n#ifndef __PJ_POOL_H__\n#define __PJ_POOL_H__\n\n/**\n * @file pool.h\n * @brief Memory Pool.\n */\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_POOL_GROUP Fast Memory Pool\n * @brief\n * Memory pools allow dynamic memory allocation comparable to malloc or the \n * new in operator C++. Those implementations are not desirable for very\n * high performance applications or real-time systems, because of the \n * performance bottlenecks and it suffers from fragmentation issue.\n *\n * \\section PJ_POOL_INTRO_SEC PJLIB's Memory Pool\n * \\subsection PJ_POOL_ADVANTAGE_SUBSEC Advantages\n * \n * PJLIB's pool has many advantages over traditional malloc/new operator and\n * over other memory pool implementations, because:\n *  - unlike other memory pool implementation, it allows allocation of\n *    memory chunks of different sizes,\n *  - it's very very fast. \n *    \\n\n *    Memory chunk allocation is not only an O(1) \n *    operation, but it's also very simple (just \n *    few pointer arithmetic operations) and it doesn't require locking \n *    any mutex,\n *  - it's memory efficient.\n *    \\n\n *    Pool doesn't keep track individual memory chunks allocated by\n *    applications, so there is no additional overhead needed for each\n *    memory allocation (other than possible additional of few bytes, up to\n *    PJ_POOL_ALIGNMENT-1, for aligning the memory). \n *    But see the @ref PJ_POOL_CAVEATS_SUBSEC below.\n *  - it prevents memory leaks. \n *    \\n\n *    Memory pool inherently has garbage collection functionality. In fact, \n *    there is no need to free the chunks allocated from the memory pool.\n *    All chunks previously allocated from the pool will be freed once the\n *    pool itself is destroyed. This would prevent memory leaks that haunt\n *    programmers for decades, and it provides additional performance \n *    advantage over traditional malloc/new operator.\n *\n * Even more, PJLIB's memory pool provides some additional usability and\n * flexibility for applications:\n *  - memory leaks are easily traceable, since memory pool is assigned name,\n *    and application can inspect what pools currently active in the system.\n *  - by design, memory allocation from a pool is not thread safe. We assumed\n *    that a pool will be owned by a higher level object, and thread safety \n *    should be handled by that object. This enables very fast pool operations\n *    and prevents unnecessary locking operations,\n *  - by default, the memory pool API behaves more like C++ new operator, \n *    in that it will throw PJ_NO_MEMORY_EXCEPTION exception (see \n *    @ref PJ_EXCEPT) when memory chunk allocation fails. This enables failure\n *    handling to be done on more high level function (instead of checking\n *    the result of pj_pool_alloc() everytime). If application doesn't like\n *    this, the default behavior can be changed on global basis by supplying \n *    different policy to the pool factory.\n *  - any memory allocation backend allocator/deallocator may be used. By\n *    default, the policy uses malloc() and free() to manage the pool's block,\n *    but application may use different strategy, for example to allocate\n *    memory blocks from a globally static memory location.\n *\n *\n * \\subsection PJ_POOL_PERFORMANCE_SUBSEC Performance\n * \n * The result of PJLIB's memory design and careful implementation is a\n * memory allocation strategy that can speed-up the memory allocations\n * and deallocations by up to <b>30 times</b> compared to standard\n * malloc()/free() (more than 150 million allocations per second on a\n * P4/3.0GHz Linux machine).\n *\n * (Note: your mileage may vary, of course. You can see how much PJLIB's\n *  pool improves the performance over malloc()/free() in your target\n *  system by running pjlib-test application).\n *\n *\n * \\subsection PJ_POOL_CAVEATS_SUBSEC Caveats\n *\n * There are some caveats though!\n *\n * When creating pool, PJLIB requires applications to specify the initial\n * pool size, and as soon as the pool is created, PJLIB allocates memory\n * from the system by that size. Application designers MUST choose the \n * initial pool size carefully, since choosing too big value will result in\n * wasting system's memory.\n *\n * But the pool can grow. Application designer can specify how the\n * pool will grow in size, by specifying the size increment when creating\n * the pool.\n *\n * The pool, however, <b>cannot</b> shrink! Since there is <b>no</b> \n * function to deallocate memory chunks, there is no way for the pool to \n * release back unused memory to the system. \n * Application designers must be aware that constant memory allocations \n * from pool that has infinite life-time may cause the memory usage of \n * the application to grow over time.\n *\n *\n * \\section PJ_POOL_USING_SEC Using Memory Pool\n *\n * This section describes how to use PJLIB's memory pool framework.\n * As we hope the readers will witness, PJLIB's memory pool API is quite\n * straightforward. \n *\n * \\subsection PJ_POOL_USING_F Create Pool Factory\n * First, application needs to initialize a pool factory (this normally\n * only needs to be done once in one application). PJLIB provides\n * a pool factory implementation called caching pool (see @ref \n * PJ_CACHING_POOL), and it is initialized by calling #pj_caching_pool_init().\n *\n * \\subsection PJ_POOL_USING_P Create The Pool\n * Then application creates the pool object itself with #pj_pool_create(),\n * specifying among other thing the pool factory where the pool should\n * be created from, the pool name, initial size, and increment/expansion\n * size.\n *\n * \\subsection PJ_POOL_USING_M Allocate Memory as Required\n * Then whenever application needs to allocate dynamic memory, it would\n * call #pj_pool_alloc(), #pj_pool_calloc(), or #pj_pool_zalloc() to\n * allocate memory chunks from the pool.\n *\n * \\subsection PJ_POOL_USING_DP Destroy the Pool\n * When application has finished with the pool, it should call \n * #pj_pool_release() to release the pool object back to the factory. \n * Depending on the types of the factory, this may release the memory back \n * to the operating system.\n *\n * \\subsection PJ_POOL_USING_Dc Destroy the Pool Factory\n * And finally, before application quites, it should deinitialize the\n * pool factory, to make sure that all memory blocks allocated by the\n * factory are released back to the operating system. After this, of \n * course no more memory pool allocation can be requested.\n *\n * \\subsection PJ_POOL_USING_EX Example\n * Below is a sample complete program that utilizes PJLIB's memory pool.\n *\n * \\code\n\n   #include <pjlib.h>\n\n   #define THIS_FILE    \"pool_sample.c\"\n\n   static void my_perror(const char *title, pj_status_t status)\n   {\n        char errmsg[PJ_ERR_MSG_SIZE];\n\n\tpj_strerror(status, errmsg, sizeof(errmsg));\n\tPJ_LOG(1,(THIS_FILE, \"%s: %s [status=%d]\", title, errmsg, status));\n   }\n\n   static void pool_demo_1(pj_pool_factory *pfactory)\n   {\n\tunsigned i;\n\tpj_pool_t *pool;\n\n\t// Must create pool before we can allocate anything\n\tpool = pj_pool_create(pfactory,\t // the factory\n\t\t\t      \"pool1\",\t // pool's name\n\t\t\t      4000,\t // initial size\n\t\t\t      4000,\t // increment size\n\t\t\t      NULL);\t // use default callback.\n\tif (pool == NULL) {\n\t    my_perror(\"Error creating pool\", PJ_ENOMEM);\n\t    return;\n\t}\n\n\t// Demo: allocate some memory chunks\n\tfor (i=0; i<1000; ++i) {\n\t    void *p;\n\n\t    p = pj_pool_alloc(pool, (pj_rand()+1) % 512);\n\n\t    // Do something with p\n\t    ...\n\n\t    // Look! No need to free p!!\n\t}\n\n\t// Done with silly demo, must free pool to release all memory.\n\tpj_pool_release(pool);\n   }\n\n   int main()\n   {\n\tpj_caching_pool cp;\n\tpj_status_t status;\n\n        // Must init PJLIB before anything else\n\tstatus = pj_init();\n\tif (status != PJ_SUCCESS) {\n\t    my_perror(\"Error initializing PJLIB\", status);\n\t    return 1;\n\t}\n\n\t// Create the pool factory, in this case, a caching pool,\n\t// using default pool policy.\n\tpj_caching_pool_init(&cp, NULL, 1024*1024 );\n\n\t// Do a demo\n\tpool_demo_1(&cp.factory);\n\n\t// Done with demos, destroy caching pool before exiting app.\n\tpj_caching_pool_destroy(&cp);\n\n\treturn 0;\n   }\n\n   \\endcode\n *\n * More information about pool factory, the pool object, and caching pool\n * can be found on the Module Links below.\n */\n\n\n/**\n * @defgroup PJ_POOL Memory Pool Object\n * @ingroup PJ_POOL_GROUP\n * @brief\n * The memory pool is an opaque object created by pool factory.\n * Application uses this object to request a memory chunk, by calling\n * #pj_pool_alloc(), #pj_pool_calloc(), or #pj_pool_zalloc(). \n * When the application has finished using\n * the pool, it must call #pj_pool_release() to free all the chunks previously\n * allocated and release the pool back to the factory.\n *\n * A memory pool is initialized with an initial amount of memory, which is\n * called a block. Pool can be configured to dynamically allocate more memory \n * blocks when it runs out of memory. \n *\n * The pool doesn't keep track of individual memory allocations\n * by user, and the user doesn't have to free these indidual allocations. This\n * makes memory allocation simple and very fast. All the memory allocated from\n * the pool will be destroyed when the pool itself is destroyed.\n *\n * \\section PJ_POOL_THREADING_SEC More on Threading Policies\n * - By design, memory allocation from a pool is not thread safe. We assumed \n *   that a pool will be owned by an object, and thread safety should be \n *   handled by that object. Thus these functions are not thread safe: \n *\t- #pj_pool_alloc, \n *\t- #pj_pool_calloc, \n *\t- and other pool statistic functions.\n * - Threading in the pool factory is decided by the policy set for the\n *   factory when it was created.\n *\n * \\section PJ_POOL_EXAMPLES_SEC Examples\n *\n * For some sample codes on how to use the pool, please see:\n *  - @ref page_pjlib_pool_test\n *\n * @{\n */\n\n/**\n * The type for function to receive callback from the pool when it is unable\n * to allocate memory. The elegant way to handle this condition is to throw\n * exception, and this is what is expected by most of this library \n * components.\n */\ntypedef void pj_pool_callback(pj_pool_t *pool, pj_size_t size);\n\n/**\n * This class, which is used internally by the pool, describes a single \n * block of memory from which user memory allocations will be allocated from.\n */\ntypedef struct pj_pool_block\n{\n    PJ_DECL_LIST_MEMBER(struct pj_pool_block);  /**< List's prev and next.  */\n    unsigned char    *buf;                      /**< Start of buffer.       */\n    unsigned char    *cur;                      /**< Current alloc ptr.     */\n    unsigned char    *end;                      /**< End of buffer.         */\n} pj_pool_block;\n\n\n/**\n * This structure describes the memory pool. Only implementors of pool factory\n * need to care about the contents of this structure.\n */\nstruct pj_pool_t\n{\n    PJ_DECL_LIST_MEMBER(struct pj_pool_t);  /**< Standard list elements.    */\n\n    /** Pool name */\n    char\t    obj_name[PJ_MAX_OBJ_NAME];\n\n    /** Pool factory. */\n    pj_pool_factory *factory;\n\n    /** Data put by factory */\n    void\t    *factory_data;\n\n    /** Current capacity allocated by the pool. */\n    pj_size_t\t    capacity;\n\n    /** Size of memory block to be allocated when the pool runs out of memory */\n    pj_size_t\t    increment_size;\n\n    /** List of memory blocks allcoated by the pool. */\n    pj_pool_block   block_list;\n\n    /** The callback to be called when the pool is unable to allocate memory. */\n    pj_pool_callback *callback;\n\n};\n\n\n/**\n * Guidance on how much memory required for initial pool administrative data.\n */\n#define PJ_POOL_SIZE\t        (sizeof(struct pj_pool_t))\n\n/** \n * Pool memory alignment (must be power of 2). \n */\n#ifndef PJ_POOL_ALIGNMENT\n#   define PJ_POOL_ALIGNMENT    4\n#endif\n\n/**\n * Create a new pool from the pool factory. This wrapper will call create_pool\n * member of the pool factory.\n *\n * @param factory\t    The pool factory.\n * @param name\t\t    The name to be assigned to the pool. The name should \n *\t\t\t    not be longer than PJ_MAX_OBJ_NAME (32 chars), or \n *\t\t\t    otherwise it will be truncated.\n * @param initial_size\t    The size of initial memory blocks taken by the pool.\n *\t\t\t    Note that the pool will take 68+20 bytes for \n *\t\t\t    administrative area from this block.\n * @param increment_size    the size of each additional blocks to be allocated\n *\t\t\t    when the pool is running out of memory. If user \n *\t\t\t    requests memory which is larger than this size, then \n *\t\t\t    an error occurs.\n *\t\t\t    Note that each time a pool allocates additional block, \n *\t\t\t    it needs PJ_POOL_SIZE more to store some \n *\t\t\t    administrative info.\n * @param callback\t    Callback to be called when error occurs in the pool.\n *\t\t\t    If this value is NULL, then the callback from pool\n *\t\t\t    factory policy will be used.\n *\t\t\t    Note that when an error occurs during pool creation, \n *\t\t\t    the callback itself is not called. Instead, NULL \n *\t\t\t    will be returned.\n *\n * @return                  The memory pool, or NULL.\n */\nPJ_IDECL(pj_pool_t*) pj_pool_create(pj_pool_factory *factory, \n\t\t\t\t    const char *name,\n\t\t\t\t    pj_size_t initial_size, \n\t\t\t\t    pj_size_t increment_size,\n\t\t\t\t    pj_pool_callback *callback);\n\n/**\n * Release the pool back to pool factory.\n *\n * @param pool\t    Memory pool.\n */\nPJ_IDECL(void) pj_pool_release( pj_pool_t *pool );\n\n/**\n * Get pool object name.\n *\n * @param pool the pool.\n *\n * @return pool name as NULL terminated string.\n */\nPJ_IDECL(const char *) pj_pool_getobjname( const pj_pool_t *pool );\n\n/**\n * Reset the pool to its state when it was initialized.\n * This means that if additional blocks have been allocated during runtime, \n * then they will be freed. Only the original block allocated during \n * initialization is retained. This function will also reset the internal \n * counters, such as pool capacity and used size.\n *\n * @param pool the pool.\n */\nPJ_DECL(void) pj_pool_reset( pj_pool_t *pool );\n\n\n/**\n * Get the pool capacity, that is, the system storage that have been allocated\n * by the pool, and have been used/will be used to allocate user requests.\n * There's no guarantee that the returned value represent a single\n * contiguous block, because the capacity may be spread in several blocks.\n *\n * @param pool\tthe pool.\n *\n * @return the capacity.\n */\nPJ_IDECL(pj_size_t) pj_pool_get_capacity( pj_pool_t *pool );\n\n/**\n * Get the total size of user allocation request.\n *\n * @param pool\tthe pool.\n *\n * @return the total size.\n */\nPJ_IDECL(pj_size_t) pj_pool_get_used_size( pj_pool_t *pool );\n\n/**\n * Allocate storage with the specified size from the pool.\n * If there's no storage available in the pool, then the pool can allocate more\n * blocks if the increment size is larger than the requested size.\n *\n * @param pool\t    the pool.\n * @param size\t    the requested size.\n *\n * @return pointer to the allocated memory.\n *\n * @see PJ_POOL_ALLOC_T\n */\nPJ_IDECL(void*) pj_pool_alloc( pj_pool_t *pool, pj_size_t size);\n\n/**\n * Allocate storage  from the pool, and initialize it to zero.\n * This function behaves like pj_pool_alloc(), except that the storage will\n * be initialized to zero.\n *\n * @param pool\t    the pool.\n * @param count\t    the number of elements in the array.\n * @param elem\t    the size of individual element.\n *\n * @return pointer to the allocated memory.\n */\nPJ_IDECL(void*) pj_pool_calloc( pj_pool_t *pool, pj_size_t count, \n\t\t\t\tpj_size_t elem);\n\n\n/**\n * Allocate storage from the pool and initialize it to zero.\n *\n * @param pool\t    The pool.\n * @param size\t    The size to be allocated.\n *\n * @return\t    Pointer to the allocated memory.\n *\n * @see PJ_POOL_ZALLOC_T\n */\nPJ_INLINE(void*) pj_pool_zalloc(pj_pool_t *pool, pj_size_t size)\n{\n    return pj_pool_calloc(pool, 1, size);\n}\n\n\n/**\n * This macro allocates memory from the pool and returns the instance of\n * the specified type. It provides a stricker type safety than pj_pool_alloc()\n * since the return value of this macro will be type-casted to the specified\n * type.\n *\n * @param pool\t    The pool\n * @param type\t    The type of object to be allocated\n *\n * @return\t    Memory buffer of the specified type.\n */\n#define PJ_POOL_ALLOC_T(pool,type) \\\n\t    ((type*)pj_pool_alloc(pool, sizeof(type)))\n\n/**\n * This macro allocates memory from the pool, zeroes the buffer, and \n * returns the instance of the specified type. It provides a stricker type \n * safety than pj_pool_zalloc() since the return value of this macro will be \n * type-casted to the specified type.\n *\n * @param pool\t    The pool\n * @param type\t    The type of object to be allocated\n *\n * @return\t    Memory buffer of the specified type.\n */\n#define PJ_POOL_ZALLOC_T(pool,type) \\\n\t    ((type*)pj_pool_zalloc(pool, sizeof(type)))\n\n/*\n * Internal functions\n */\nPJ_IDECL(void*) pj_pool_alloc_from_block(pj_pool_block *block, pj_size_t size);\nPJ_DECL(void*) pj_pool_allocate_find(pj_pool_t *pool, pj_size_t size);\n\n\n\t\n/**\n * @}\t// PJ_POOL\n */\n\n/* **************************************************************************/\n/**\n * @defgroup PJ_POOL_FACTORY Pool Factory and Policy\n * @ingroup PJ_POOL_GROUP\n * @brief\n * A pool object must be created through a factory. A factory not only provides\n * generic interface functions to create and release pool, but also provides \n * strategy to manage the life time of pools. One sample implementation, \n * \\a pj_caching_pool, can be set to keep the pools released by application for\n * future use as long as the total memory is below the limit.\n * \n * The pool factory interface declared in PJLIB is designed to be extensible.\n * Application can define its own strategy by creating it's own pool factory\n * implementation, and this strategy can be used even by existing library\n * without recompilation.\n *\n * \\section PJ_POOL_FACTORY_ITF Pool Factory Interface\n * The pool factory defines the following interface:\n *  - \\a policy: the memory pool factory policy.\n *  - \\a create_pool(): create a new memory pool.\n *  - \\a release_pool(): release memory pool back to factory.\n *\n * \\section PJ_POOL_FACTORY_POL Pool Factory Policy.\n *\n * A pool factory only defines functions to create and release pool and how\n * to manage pools, but the rest of the functionalities are controlled by\n * policy. A pool policy defines:\n *  - how memory block is allocated and deallocated (the default implementation\n *    allocates and deallocate memory by calling malloc() and free()).\n *  - callback to be called when memory allocation inside a pool fails (the\n *    default implementation will throw PJ_NO_MEMORY_EXCEPTION exception).\n *  - concurrency when creating and releasing pool from/to the factory.\n *\n * A pool factory can be given different policy during creation to make\n * it behave differently. For example, caching pool factory can be configured\n * to allocate and deallocate from a static/contiguous/preallocated memory \n * instead of using malloc()/free().\n * \n * What strategy/factory and what policy to use is not defined by PJLIB, but\n * instead is left to application to make use whichever is most efficient for\n * itself.\n *\n * The pool factory policy controls the behaviour of memory factories, and\n * defines the following interface:\n *  - \\a block_alloc(): allocate memory block from backend memory mgmt/system.\n *  - \\a block_free(): free memory block back to backend memory mgmt/system.\n * @{\n */\n\n/* We unfortunately don't have support for factory policy options as now,\n   so we keep this commented at the moment.\nenum PJ_POOL_FACTORY_OPTION\n{\n    PJ_POOL_FACTORY_SERIALIZE = 1\n};\n*/\n\n/**\n * This structure declares pool factory interface.\n */\ntypedef struct pj_pool_factory_policy\n{\n    /**\n     * Allocate memory block (for use by pool). This function is called\n     * by memory pool to allocate memory block.\n     * \n     * @param factory\tPool factory.\n     * @param size\tThe size of memory block to allocate.\n     *\n     * @return\t\tMemory block.\n     */\n    void* (*block_alloc)(pj_pool_factory *factory, pj_size_t size);\n\n    /**\n     * Free memory block.\n     *\n     * @param factory\tPool factory.\n     * @param mem\tMemory block previously allocated by block_alloc().\n     * @param size\tThe size of memory block.\n     */\n    void (*block_free)(pj_pool_factory *factory, void *mem, pj_size_t size);\n\n    /**\n     * Default callback to be called when memory allocation fails.\n     */\n    pj_pool_callback *callback;\n\n    /**\n     * Option flags.\n     */\n    unsigned flags;\n\n} pj_pool_factory_policy;\n\n/**\n * \\def PJ_NO_MEMORY_EXCEPTION\n * This constant denotes the exception number that will be thrown by default\n * memory factory policy when memory allocation fails.\n *\n * @see pj_NO_MEMORY_EXCEPTION()\n */\nPJ_DECL_DATA(int) PJ_NO_MEMORY_EXCEPTION;\n\n/**\n * Get #PJ_NO_MEMORY_EXCEPTION constant.\n */ \nPJ_DECL(int) pj_NO_MEMORY_EXCEPTION(void);\n\n/**\n * This global variable points to default memory pool factory policy.\n * The behaviour of the default policy is:\n *  - block allocation and deallocation use malloc() and free().\n *  - callback will raise PJ_NO_MEMORY_EXCEPTION exception.\n *  - access to pool factory is not serialized (i.e. not thread safe).\n *\n * @see pj_pool_factory_get_default_policy\n */\nPJ_DECL_DATA(pj_pool_factory_policy) pj_pool_factory_default_policy;\n\n\n/**\n * Get the default pool factory policy.\n *\n * @return the pool policy.\n */\nPJ_DECL(const pj_pool_factory_policy*) pj_pool_factory_get_default_policy(void);\n\n\n/**\n * This structure contains the declaration for pool factory interface.\n */\nstruct pj_pool_factory\n{\n    /**\n     * Memory pool policy.\n     */\n    pj_pool_factory_policy policy;\n\n    /**\n    * Create a new pool from the pool factory.\n    *\n    * @param factory\tThe pool factory.\n    * @param name\tthe name to be assigned to the pool. The name should \n    *\t\t\tnot be longer than PJ_MAX_OBJ_NAME (32 chars), or \n    *\t\t\totherwise it will be truncated.\n    * @param initial_size the size of initial memory blocks taken by the pool.\n    *\t\t\tNote that the pool will take 68+20 bytes for \n    *\t\t\tadministrative area from this block.\n    * @param increment_size the size of each additional blocks to be allocated\n    *\t\t\twhen the pool is running out of memory. If user \n    *\t\t\trequests memory which is larger than this size, then \n    *\t\t\tan error occurs.\n    *\t\t\tNote that each time a pool allocates additional block, \n    *\t\t\tit needs 20 bytes (equal to sizeof(pj_pool_block)) to \n    *\t\t\tstore some administrative info.\n    * @param callback\tCllback to be called when error occurs in the pool.\n    *\t\t\tNote that when an error occurs during pool creation, \n    *\t\t\tthe callback itself is not called. Instead, NULL \n    *\t\t\twill be returned.\n    *\n    * @return the memory pool, or NULL.\n    */\n    pj_pool_t*\t(*create_pool)( pj_pool_factory *factory,\n\t\t\t\tconst char *name,\n\t\t\t\tpj_size_t initial_size, \n\t\t\t\tpj_size_t increment_size,\n\t\t\t\tpj_pool_callback *callback);\n\n    /**\n     * Release the pool to the pool factory.\n     *\n     * @param factory\tThe pool factory.\n     * @param pool\tThe pool to be released.\n    */\n    void (*release_pool)( pj_pool_factory *factory, pj_pool_t *pool );\n\n    /**\n     * Dump pool status to log.\n     *\n     * @param factory\tThe pool factory.\n     */\n    void (*dump_status)( pj_pool_factory *factory, pj_bool_t detail );\n\n    /**\n     * This is optional callback to be called by allocation policy when\n     * it allocates a new memory block. The factory may use this callback\n     * for example to keep track of the total number of memory blocks\n     * currently allocated by applications.\n     *\n     * @param factory\t    The pool factory.\n     * @param size\t    Size requested by application.\n     *\n     * @return\t\t    MUST return PJ_TRUE, otherwise the block\n     *                      allocation is cancelled.\n     */\n    pj_bool_t (*on_block_alloc)(pj_pool_factory *factory, pj_size_t size);\n\n    /**\n     * This is optional callback to be called by allocation policy when\n     * it frees memory block. The factory may use this callback\n     * for example to keep track of the total number of memory blocks\n     * currently allocated by applications.\n     *\n     * @param factory\t    The pool factory.\n     * @param size\t    Size freed.\n     */\n    void (*on_block_free)(pj_pool_factory *factory, pj_size_t size);\n\n};\n\n/**\n * This function is intended to be used by pool factory implementors.\n * @param factory           Pool factory.\n * @param name              Pool name.\n * @param initial_size      Initial size.\n * @param increment_size    Increment size.\n * @param callback          Callback.\n * @return                  The pool object, or NULL.\n */\nPJ_DECL(pj_pool_t*) pj_pool_create_int(\tpj_pool_factory *factory, \n\t\t\t\t\tconst char *name,\n\t\t\t\t\tpj_size_t initial_size, \n\t\t\t\t\tpj_size_t increment_size,\n\t\t\t\t\tpj_pool_callback *callback);\n\n/**\n * This function is intended to be used by pool factory implementors.\n * @param pool              The pool.\n * @param name              Pool name.\n * @param increment_size    Increment size.\n * @param callback          Callback function.\n */\nPJ_DECL(void) pj_pool_init_int( pj_pool_t *pool, \n\t\t\t\tconst char *name,\n\t\t\t\tpj_size_t increment_size,\n\t\t\t\tpj_pool_callback *callback);\n\n/**\n * This function is intended to be used by pool factory implementors.\n * @param pool      The memory pool.\n */\nPJ_DECL(void) pj_pool_destroy_int( pj_pool_t *pool );\n\n\n/**\n * Dump pool factory state.\n * @param pf\t    The pool factory.\n * @param detail    Detail state required.\n */\nPJ_INLINE(void) pj_pool_factory_dump( pj_pool_factory *pf,\n\t\t\t\t      pj_bool_t detail )\n{\n    (*pf->dump_status)(pf, detail);\n}\n\n/**\n *  @}\t// PJ_POOL_FACTORY\n */\n\n/* **************************************************************************/\n\n/**\n * @defgroup PJ_CACHING_POOL Caching Pool Factory\n * @ingroup PJ_POOL_GROUP\n * @brief\n * Caching pool is one sample implementation of pool factory where the\n * factory can reuse memory to create a pool. Application defines what the \n * maximum memory the factory can hold, and when a pool is released the\n * factory decides whether to destroy the pool or to keep it for future use.\n * If the total amount of memory in the internal cache is still within the\n * limit, the factory will keep the pool in the internal cache, otherwise the\n * pool will be destroyed, thus releasing the memory back to the system.\n *\n * @{\n */\n\n/**\n * Number of unique sizes, to be used as index to the free list.\n * Each pool in the free list is organized by it's size.\n */\n#define PJ_CACHING_POOL_ARRAY_SIZE\t16\n\n/**\n * Declaration for caching pool. Application doesn't normally need to\n * care about the contents of this struct, it is only provided here because\n * application need to define an instance of this struct (we can not allocate\n * the struct from a pool since there is no pool factory yet!).\n */\nstruct pj_caching_pool \n{\n    /** Pool factory interface, must be declared first. */\n    pj_pool_factory factory;\n\n    /** Current factory's capacity, i.e. number of bytes that are allocated\n     *  and available for application in this factory. The factory's\n     *  capacity represents the size of all pools kept by this factory\n     *  in it's free list, which will be returned to application when it\n     *  requests to create a new pool.\n     */\n    pj_size_t\t    capacity;\n\n    /** Maximum size that can be held by this factory. Once the capacity\n     *  has exceeded @a max_capacity, further #pj_pool_release() will\n     *  flush the pool. If the capacity is still below the @a max_capacity,\n     *  #pj_pool_release() will save the pool to the factory's free list.\n     */\n    pj_size_t       max_capacity;\n\n    /**\n     * Number of pools currently held by applications. This number gets\n     * incremented everytime #pj_pool_create() is called, and gets\n     * decremented when #pj_pool_release() is called.\n     */\n    pj_size_t       used_count;\n\n    /**\n     * Total size of memory currently used by application.\n     */\n    pj_size_t\t    used_size;\n\n    /**\n     * The maximum size of memory used by application throughout the life\n     * of the caching pool.\n     */\n    pj_size_t\t    peak_used_size;\n\n    /**\n     * Lists of pools in the cache, indexed by pool size.\n     */\n    pj_list\t    free_list[PJ_CACHING_POOL_ARRAY_SIZE];\n\n    /**\n     * List of pools currently allocated by applications.\n     */\n    pj_list\t    used_list;\n\n    /**\n     * Internal pool.\n     */\n    char\t    pool_buf[256 * (sizeof(size_t) / 4)];\n\n    /**\n     * Mutex.\n     */\n    pj_lock_t\t   *lock;\n};\n\n\n\n/**\n * Initialize caching pool.\n *\n * @param ch_pool\tThe caching pool factory to be initialized.\n * @param policy\tPool factory policy.\n * @param max_capacity\tThe total capacity to be retained in the cache. When\n *\t\t\tthe pool is returned to the cache, it will be kept in\n *\t\t\trecycling list if the total capacity of pools in this\n *\t\t\tlist plus the capacity of the pool is still below this\n *\t\t\tvalue.\n */\nPJ_DECL(void) pj_caching_pool_init( pj_caching_pool *ch_pool, \n\t\t\t\t    const pj_pool_factory_policy *policy,\n\t\t\t\t    pj_size_t max_capacity);\n\n\n/**\n * Destroy caching pool, and release all the pools in the recycling list.\n *\n * @param ch_pool\tThe caching pool.\n */\nPJ_DECL(void) pj_caching_pool_destroy( pj_caching_pool *ch_pool );\n\n/**\n * @}\t// PJ_CACHING_POOL\n */\n\n#  if PJ_FUNCTIONS_ARE_INLINED\n#    include \"pool_i.h\"\n#  endif\n\nPJ_END_DECL\n    \n#endif\t/* __PJ_POOL_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/pool_alt.h",
    "content": "/* $Id: pool_alt.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_POOL_ALT_H__\n#define __PJ_POOL_ALT_H__\n\n#define __PJ_POOL_H__\n\nPJ_BEGIN_DECL\n\n/**\n * The type for function to receive callback from the pool when it is unable\n * to allocate memory. The elegant way to handle this condition is to throw\n * exception, and this is what is expected by most of this library \n * components.\n */\ntypedef void pj_pool_callback(pj_pool_t *pool, pj_size_t size);\n\nstruct pj_pool_mem\n{\n    struct pj_pool_mem *next;\n\n    /* data follows immediately */\n};\n\n\nstruct pj_pool_t\n{\n    struct pj_pool_mem *first_mem;\n    pj_pool_factory    *factory;\n    char\t        obj_name[32];\n    pj_size_t\t\tused_size;\n    pj_pool_callback   *cb;\n};\n\n\n#define PJ_POOL_SIZE\t        (sizeof(struct pj_pool_t))\n\n/**\n * This constant denotes the exception number that will be thrown by default\n * memory factory policy when memory allocation fails.\n */\nextern int PJ_NO_MEMORY_EXCEPTION;\n\n\n\n/*\n * Declare all pool API as macro that calls the implementation\n * function.\n */\n#define pj_pool_create(fc,nm,init,inc,cb)   \\\n\tpj_pool_create_imp(__FILE__, __LINE__, fc, nm, init, inc, cb)\n\n#define pj_pool_release(pool)\t\t    pj_pool_release_imp(pool)\n#define pj_pool_getobjname(pool)\t    pj_pool_getobjname_imp(pool)\n#define pj_pool_reset(pool)\t\t    pj_pool_reset_imp(pool)\n#define pj_pool_get_capacity(pool)\t    pj_pool_get_capacity_imp(pool)\n#define pj_pool_get_used_size(pool)\t    pj_pool_get_used_size_imp(pool)\n#define pj_pool_alloc(pool,sz)\t\t    \\\n\tpj_pool_alloc_imp(__FILE__, __LINE__, pool, sz)\n\n#define pj_pool_calloc(pool,cnt,elem)\t    \\\n\tpj_pool_calloc_imp(__FILE__, __LINE__, pool, cnt, elem)\n\n#define pj_pool_zalloc(pool,sz)\t\t    \\\n\tpj_pool_zalloc_imp(__FILE__, __LINE__, pool, sz)\n\n\n\n/*\n * Declare prototypes for pool implementation API.\n */\n\n/* Create pool */\nPJ_DECL(pj_pool_t*) pj_pool_create_imp(const char *file, int line,\n\t\t\t\t       void *factory,\n\t\t\t\t       const char *name,\n\t\t\t\t       pj_size_t initial_size,\n\t\t\t\t       pj_size_t increment_size,\n\t\t\t\t       pj_pool_callback *callback);\n\n/* Release pool */\nPJ_DECL(void) pj_pool_release_imp(pj_pool_t *pool);\n\n/* Get pool name */\nPJ_DECL(const char*) pj_pool_getobjname_imp(pj_pool_t *pool);\n\n/* Reset pool */\nPJ_DECL(void) pj_pool_reset_imp(pj_pool_t *pool);\n\n/* Get capacity */\nPJ_DECL(pj_size_t) pj_pool_get_capacity_imp(pj_pool_t *pool);\n\n/* Get total used size */\nPJ_DECL(pj_size_t) pj_pool_get_used_size_imp(pj_pool_t *pool);\n\n/* Allocate memory from the pool */\nPJ_DECL(void*) pj_pool_alloc_imp(const char *file, int line, \n\t\t\t\t pj_pool_t *pool, pj_size_t sz);\n\n/* Allocate memory from the pool and zero the memory */\nPJ_DECL(void*) pj_pool_calloc_imp(const char *file, int line, \n\t\t\t\t  pj_pool_t *pool, unsigned cnt, \n\t\t\t\t  unsigned elemsz);\n\n/* Allocate memory from the pool and zero the memory */\nPJ_DECL(void*) pj_pool_zalloc_imp(const char *file, int line, \n\t\t\t\t  pj_pool_t *pool, pj_size_t sz);\n\n\n#define PJ_POOL_ZALLOC_T(pool,type) \\\n\t    ((type*)pj_pool_zalloc(pool, sizeof(type)))\n#define PJ_POOL_ALLOC_T(pool,type) \\\n\t    ((type*)pj_pool_alloc(pool, sizeof(type)))\n#ifndef PJ_POOL_ALIGNMENT\n#   define PJ_POOL_ALIGNMENT    4\n#endif\n\n/**\n * This structure declares pool factory interface.\n */\ntypedef struct pj_pool_factory_policy\n{\n    /**\n     * Allocate memory block (for use by pool). This function is called\n     * by memory pool to allocate memory block.\n     * \n     * @param factory\tPool factory.\n     * @param size\tThe size of memory block to allocate.\n     *\n     * @return\t\tMemory block.\n     */\n    void* (*block_alloc)(pj_pool_factory *factory, pj_size_t size);\n\n    /**\n     * Free memory block.\n     *\n     * @param factory\tPool factory.\n     * @param mem\tMemory block previously allocated by block_alloc().\n     * @param size\tThe size of memory block.\n     */\n    void (*block_free)(pj_pool_factory *factory, void *mem, pj_size_t size);\n\n    /**\n     * Default callback to be called when memory allocation fails.\n     */\n    pj_pool_callback *callback;\n\n    /**\n     * Option flags.\n     */\n    unsigned flags;\n\n} pj_pool_factory_policy;\n\nstruct pj_pool_factory\n{\n    pj_pool_factory_policy policy;\n    int dummy;\n};\n\nstruct pj_caching_pool \n{\n    pj_pool_factory factory;\n\n    /* just to make it compilable */\n    unsigned used_count;\n    unsigned used_size;\n    unsigned peak_used_size;\n};\n\n/* just to make it compilable */\ntypedef struct pj_pool_block\n{\n    int dummy;\n} pj_pool_block;\n\n#define pj_caching_pool_init( cp, pol, mac)\n#define pj_caching_pool_destroy(cp)\n#define pj_pool_factory_dump(pf, detail)\n\nPJ_END_DECL\n\n#endif\t/* __PJ_POOL_ALT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/pool_buf.h",
    "content": "/* $Id: pool_buf.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __POOL_STACK_H__\n#define __POOL_STACK_H__\n\n#include <pj/pool.h>\n\n/**\n * @defgroup PJ_POOL_BUFFER Stack/Buffer Based Memory Pool Allocator\n * @ingroup PJ_POOL_GROUP\n * @brief Stack/buffer based pool.\n *\n * This section describes an implementation of memory pool which uses\n * memory allocated from the stack. Application creates this pool\n * by specifying a buffer (which can be allocated from static memory or\n * stack variable), and then use normal pool API to access/use the pool.\n *\n * If the buffer specified during pool creation is a buffer located in the\n * stack, the pool will be invalidated (or implicitly destroyed) when the\n * execution leaves the enclosing block containing the buffer. Note\n * that application must make sure that any objects allocated from this\n * pool (such as mutexes) have been destroyed before the pool gets\n * invalidated.\n *\n * Sample usage:\n *\n * \\code\n  #include <pjlib.h>\n\n  static void test()\n  {\n    char buffer[500];\n    pj_pool_t *pool;\n    void *p;\n\n    pool = pj_pool_create_on_buf(\"thepool\", buffer, sizeof(buffer));\n\n    // Use the pool as usual\n    p = pj_pool_alloc(pool, ...);\n    ...\n\n    // No need to release the pool\n  }\n\n  int main()\n  {\n    pj_init();\n    test();\n    return 0;\n  }\n\n   \\endcode\n *\n * @{\n */\n\nPJ_BEGIN_DECL\n\n/**\n * Create the pool using the specified buffer as the pool's memory.\n * Subsequent allocations made from the pool will use the memory from\n * this buffer.\n *\n * If the buffer specified in the parameter is a buffer located in the\n * stack, the pool will be invalid (or implicitly destroyed) when the\n * execution leaves the enclosing block containing the buffer. Note\n * that application must make sure that any objects allocated from this\n * pool (such as mutexes) have been destroyed before the pool gets\n * invalidated.\n *\n * @param name\t    Optional pool name.\n * @param buf\t    Buffer to be used by the pool.\n * @param size\t    The size of the buffer.\n *\n * @return\t    The memory pool instance.\n */\nPJ_DECL(pj_pool_t*) pj_pool_create_on_buf(const char *name,\n\t\t\t\t\t  void *buf,\n\t\t\t\t\t  pj_size_t size);\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __POOL_STACK_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/pool_i.h",
    "content": "/* $Id: pool_i.h 4298 2012-11-22 05:00:01Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n\n#include <pj/string.h>\n\n\nPJ_IDEF(pj_size_t) pj_pool_get_capacity( pj_pool_t *pool )\n{\n    return pool->capacity;\n}\n\nPJ_IDEF(pj_size_t) pj_pool_get_used_size( pj_pool_t *pool )\n{\n    pj_pool_block *b = pool->block_list.next;\n    pj_size_t used_size = sizeof(pj_pool_t);\n    while (b != &pool->block_list) {\n\tused_size += (b->cur - b->buf) + sizeof(pj_pool_block);\n\tb = b->next;\n    }\n    return used_size;\n}\n\nPJ_IDEF(void*) pj_pool_alloc_from_block( pj_pool_block *block, pj_size_t size )\n{\n    /* The operation below is valid for size==0. \n     * When size==0, the function will return the pointer to the pool\n     * memory address, but no memory will be allocated.\n     */\n    if (size & (PJ_POOL_ALIGNMENT-1)) {\n\tsize = (size + PJ_POOL_ALIGNMENT) & ~(PJ_POOL_ALIGNMENT-1);\n    }\n    if ((pj_size_t)(block->end - block->cur) >= size) {\n\tvoid *ptr = block->cur;\n\tblock->cur += size;\n\treturn ptr;\n    }\n    return NULL;\n}\n\nPJ_IDEF(void*) pj_pool_alloc( pj_pool_t *pool, pj_size_t size)\n{\n    void *ptr = pj_pool_alloc_from_block(pool->block_list.next, size);\n    if (!ptr)\n\tptr = pj_pool_allocate_find(pool, size);\n    return ptr;\n}\n\n\nPJ_IDEF(void*) pj_pool_calloc( pj_pool_t *pool, pj_size_t count, pj_size_t size)\n{\n    void *buf = pj_pool_alloc( pool, size*count);\n    if (buf)\n\tpj_bzero(buf, size * count);\n    return buf;\n}\n\nPJ_IDEF(const char *) pj_pool_getobjname( const pj_pool_t *pool )\n{\n    return pool->obj_name;\n}\n\nPJ_IDEF(pj_pool_t*) pj_pool_create( pj_pool_factory *f, \n\t\t\t\t    const char *name,\n\t\t\t\t    pj_size_t initial_size, \n\t\t\t\t    pj_size_t increment_size,\n\t\t\t\t    pj_pool_callback *callback)\n{\n    return (*f->create_pool)(f, name, initial_size, increment_size, callback);\n}\n\nPJ_IDEF(void) pj_pool_release( pj_pool_t *pool )\n{\n    if (pool->factory->release_pool)\n\t(*pool->factory->release_pool)(pool->factory, pool);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/rand.h",
    "content": "/* $Id: rand.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_RAND_H__\n#define __PJ_RAND_H__\n\n/**\n * @file rand.h\n * @brief Random Number Generator.\n */\n\n#include <pj/config.h>\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJ_RAND Random Number Generator\n * @ingroup PJ_MISC\n * @{\n * This module contains functions for generating random numbers.\n * This abstraction is needed not only because not all platforms have\n * \\a rand() and \\a srand(), but also on some platforms \\a rand()\n * only has 16-bit randomness, which is not good enough.\n */\n\n/**\n * Put in seed to random number generator.\n *\n * @param seed\t    Seed value.\n */\nPJ_DECL(void) pj_srand(unsigned int seed);\n\n\n/**\n * Generate random integer with 32bit randomness.\n *\n * @return a random integer.\n */\nPJ_DECL(int) pj_rand(void);\n\n\n/** @} */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJ_RAND_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/rbtree.h",
    "content": "/* $Id: rbtree.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_RBTREE_H__\n#define __PJ_RBTREE_H__\n\n/**\n * @file rbtree.h\n * @brief Red/Black Tree\n */\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_RBTREE Red/Black Balanced Tree\n * @ingroup PJ_DS\n * @brief\n * Red/Black tree is the variant of balanced tree, where the search, insert, \n * and delete operation is \\b guaranteed to take at most \\a O( lg(n) ).\n * @{\n */\n/**\n * Color type for Red-Black tree.\n */ \ntypedef enum pj_rbcolor_t\n{\n    PJ_RBCOLOR_BLACK,\n    PJ_RBCOLOR_RED\n} pj_rbcolor_t;\n\n/**\n * The type of the node of the R/B Tree.\n */\ntypedef struct pj_rbtree_node \n{\n    /** Pointers to the node's parent, and left and right siblings. */\n    struct pj_rbtree_node *parent, *left, *right;\n\n    /** Key associated with the node. */\n    const void *key;\n\n    /** User data associated with the node. */\n    void *user_data;\n\n    /** The R/B Tree node color. */\n    pj_rbcolor_t color;\n\n} pj_rbtree_node;\n\n\n/**\n * The type of function use to compare key value of tree node.\n * @return\n *  0 if the keys are equal\n * <0 if key1 is lower than key2\n * >0 if key1 is greater than key2.\n */\ntypedef int pj_rbtree_comp(const void *key1, const void *key2);\n\n\n/**\n * Declaration of a red-black tree. All elements in the tree must have UNIQUE\n * key.\n * A red black tree always maintains the balance of the tree, so that the\n * tree height will not be greater than lg(N). Insert, search, and delete\n * operation will take lg(N) on the worst case. But for insert and delete,\n * there is additional time needed to maintain the balance of the tree.\n */\ntypedef struct pj_rbtree\n{\n    pj_rbtree_node null_node;   /**< Constant to indicate NULL node.    */\n    pj_rbtree_node *null;       /**< Constant to indicate NULL node.    */\n    pj_rbtree_node *root;       /**< Root tree node.                    */\n    unsigned size;              /**< Number of elements in the tree.    */\n    pj_rbtree_comp *comp;       /**< Key comparison function.           */\n} pj_rbtree;\n\n\n/**\n * Guidance on how much memory required for each of the node.\n */\n#define PJ_RBTREE_NODE_SIZE\t    (sizeof(pj_rbtree_node))\n\n\n/**\n * Guidance on memory required for the tree.\n */\n#define PJ_RBTREE_SIZE\t\t    (sizeof(pj_rbtree))\n\n\n/**\n * Initialize the tree.\n * @param tree the tree to be initialized.\n * @param comp key comparison function to be used for this tree.\n */\nPJ_DECL(void) pj_rbtree_init( pj_rbtree *tree, pj_rbtree_comp *comp);\n\n/**\n * Get the first element in the tree.\n * The first element always has the least value for the key, according to\n * the comparison function.\n * @param tree the tree.\n * @return the tree node, or NULL if the tree has no element.\n */\nPJ_DECL(pj_rbtree_node*) pj_rbtree_first( pj_rbtree *tree );\n\n/**\n * Get the last element in the tree.\n * The last element always has the greatest key value, according to the\n * comparison function defined for the tree.\n * @param tree the tree.\n * @return the tree node, or NULL if the tree has no element.\n */\nPJ_DECL(pj_rbtree_node*) pj_rbtree_last( pj_rbtree *tree );\n\n/**\n * Get the successive element for the specified node.\n * The successive element is an element with greater key value.\n * @param tree the tree.\n * @param node the node.\n * @return the successive node, or NULL if the node has no successor.\n */\nPJ_DECL(pj_rbtree_node*) pj_rbtree_next( pj_rbtree *tree, \n\t\t\t\t\t pj_rbtree_node *node );\n\n/**\n * The the previous node for the specified node.\n * The previous node is an element with less key value.\n * @param tree the tree.\n * @param node the node.\n * @return the previous node, or NULL if the node has no previous node.\n */\nPJ_DECL(pj_rbtree_node*) pj_rbtree_prev( pj_rbtree *tree, \n\t\t\t\t\t pj_rbtree_node *node );\n\n/**\n * Insert a new node. \n * The node will be inserted at sorted location. The key of the node must \n * be UNIQUE, i.e. it hasn't existed in the tree.\n * @param tree the tree.\n * @param node the node to be inserted.\n * @return zero on success, or -1 if the key already exist.\n */\nPJ_DECL(int) pj_rbtree_insert( pj_rbtree *tree, \n\t\t\t       pj_rbtree_node *node );\n\n/**\n * Find a node which has the specified key.\n * @param tree the tree.\n * @param key the key to search.\n * @return the tree node with the specified key, or NULL if the key can not\n *         be found.\n */\nPJ_DECL(pj_rbtree_node*) pj_rbtree_find( pj_rbtree *tree,\n\t\t\t\t\t const void *key );\n\n/**\n * Erase a node from the tree.\n * @param tree the tree.\n * @param node the node to be erased.\n * @return the tree node itself.\n */\nPJ_DECL(pj_rbtree_node*) pj_rbtree_erase( pj_rbtree *tree,\n\t\t\t\t\t  pj_rbtree_node *node );\n\n/**\n * Get the maximum tree height from the specified node.\n * @param tree the tree.\n * @param node the node, or NULL to get the root of the tree.\n * @return the maximum height, which should be at most lg(N)\n */\nPJ_DECL(unsigned) pj_rbtree_max_height( pj_rbtree *tree,\n\t\t\t\t\tpj_rbtree_node *node );\n\n/**\n * Get the minumum tree height from the specified node.\n * @param tree the tree.\n * @param node the node, or NULL to get the root of the tree.\n * @return the height\n */\nPJ_DECL(unsigned) pj_rbtree_min_height( pj_rbtree *tree,\n\t\t\t\t\tpj_rbtree_node *node );\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJ_RBTREE_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/sock.h",
    "content": "/* $Id: sock.h 4343 2013-02-07 09:35:34Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_SOCK_H__\n#define __PJ_SOCK_H__\n\n/**\n * @file sock.h\n * @brief Socket Abstraction.\n */\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL \n\n\n/**\n * @defgroup PJ_SOCK Socket Abstraction\n * @ingroup PJ_IO\n * @{\n *\n * The PJLIB socket abstraction layer is a thin and very portable abstraction\n * for socket API. It provides API similar to BSD socket API. The abstraction\n * is needed because BSD socket API is not always available on all platforms,\n * therefore it wouldn't be possible to create a trully portable network\n * programs unless we provide such abstraction.\n *\n * Applications can use this API directly in their application, just\n * as they would when using traditional BSD socket API, provided they\n * call #pj_init() first.\n *\n * \\section pj_sock_examples_sec Examples\n *\n * For some examples on how to use the socket API, please see:\n *\n *  - \\ref page_pjlib_sock_test\n *  - \\ref page_pjlib_select_test\n *  - \\ref page_pjlib_sock_perf_test\n */\n\n\n/**\n * Supported address families. \n * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL AF_*, BECAUSE\n * THE LIBRARY WILL DO TRANSLATION TO THE NATIVE VALUE.\n */\n\n/** Address family is unspecified. @see pj_AF_UNSPEC() */\nextern const pj_uint16_t PJ_AF_UNSPEC;\n\n/** Unix domain socket.\t@see pj_AF_UNIX() */\nextern const pj_uint16_t PJ_AF_UNIX;\n\n/** POSIX name for AF_UNIX\t*/\n#define PJ_AF_LOCAL\t PJ_AF_UNIX;\n\n/** Internet IP protocol. @see pj_AF_INET() */\nextern const pj_uint16_t PJ_AF_INET;\n\n/** IP version 6. @see pj_AF_INET6() */\nextern const pj_uint16_t PJ_AF_INET6;\n\n/** Packet family. @see pj_AF_PACKET() */\nextern const pj_uint16_t PJ_AF_PACKET;\n\n/** IRDA sockets. @see pj_AF_IRDA() */\nextern const pj_uint16_t PJ_AF_IRDA;\n\n/*\n * Accessor functions for various address family constants. These\n * functions are provided because Symbian doesn't allow exporting\n * global variables from a DLL.\n */\n\n#if defined(PJ_DLL)\n    /** Get #PJ_AF_UNSPEC value */\n    PJ_DECL(pj_uint16_t) pj_AF_UNSPEC(void);\n    /** Get #PJ_AF_UNIX value. */\n    PJ_DECL(pj_uint16_t) pj_AF_UNIX(void);\n    /** Get #PJ_AF_INET value. */\n    PJ_DECL(pj_uint16_t) pj_AF_INET(void);\n    /** Get #PJ_AF_INET6 value. */\n    PJ_DECL(pj_uint16_t) pj_AF_INET6(void);\n    /** Get #PJ_AF_PACKET value. */\n    PJ_DECL(pj_uint16_t) pj_AF_PACKET(void);\n    /** Get #PJ_AF_IRDA value. */\n    PJ_DECL(pj_uint16_t) pj_AF_IRDA(void);\n#else\n    /* When pjlib is not built as DLL, these accessor functions are\n     * simply a macro to get their constants\n     */\n    /** Get #PJ_AF_UNSPEC value */\n#   define pj_AF_UNSPEC()   PJ_AF_UNSPEC\n    /** Get #PJ_AF_UNIX value. */\n#   define pj_AF_UNIX()\t    PJ_AF_UNIX\n    /** Get #PJ_AF_INET value. */\n#   define pj_AF_INET()\t    PJ_AF_INET\n    /** Get #PJ_AF_INET6 value. */\n#   define pj_AF_INET6()    PJ_AF_INET6\n    /** Get #PJ_AF_PACKET value. */\n#   define pj_AF_PACKET()   PJ_AF_PACKET\n    /** Get #PJ_AF_IRDA value. */\n#   define pj_AF_IRDA()\t    PJ_AF_IRDA\n#endif\n\n\n/**\n * Supported types of sockets.\n * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL SOCK_*, BECAUSE\n * THE LIBRARY WILL TRANSLATE THE VALUE TO THE NATIVE VALUE.\n */\n\n/** Sequenced, reliable, connection-based byte streams.\n *  @see pj_SOCK_STREAM() */\nextern const pj_uint16_t PJ_SOCK_STREAM;\n\n/** Connectionless, unreliable datagrams of fixed maximum lengths.\n *  @see pj_SOCK_DGRAM() */\nextern const pj_uint16_t PJ_SOCK_DGRAM;\n\n/** Raw protocol interface. @see pj_SOCK_RAW() */\nextern const pj_uint16_t PJ_SOCK_RAW;\n\n/** Reliably-delivered messages.  @see pj_SOCK_RDM() */\nextern const pj_uint16_t PJ_SOCK_RDM;\n\n\n/*\n * Accessor functions for various constants. These functions are provided\n * because Symbian doesn't allow exporting global variables from a DLL.\n */\n\n#if defined(PJ_DLL)\n    /** Get #PJ_SOCK_STREAM constant */\n    PJ_DECL(int) pj_SOCK_STREAM(void);\n    /** Get #PJ_SOCK_DGRAM constant */\n    PJ_DECL(int) pj_SOCK_DGRAM(void);\n    /** Get #PJ_SOCK_RAW constant */\n    PJ_DECL(int) pj_SOCK_RAW(void);\n    /** Get #PJ_SOCK_RDM constant */\n    PJ_DECL(int) pj_SOCK_RDM(void);\n#else\n    /** Get #PJ_SOCK_STREAM constant */\n#   define pj_SOCK_STREAM() PJ_SOCK_STREAM\n    /** Get #PJ_SOCK_DGRAM constant */\n#   define pj_SOCK_DGRAM()  PJ_SOCK_DGRAM\n    /** Get #PJ_SOCK_RAW constant */\n#   define pj_SOCK_RAW()    PJ_SOCK_RAW\n    /** Get #PJ_SOCK_RDM constant */\n#   define pj_SOCK_RDM()    PJ_SOCK_RDM\n#endif\n\n\n/**\n * Socket level specified in #pj_sock_setsockopt() or #pj_sock_getsockopt().\n * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL SOL_*, BECAUSE\n * THE LIBRARY WILL TRANSLATE THE VALUE TO THE NATIVE VALUE.\n */\n/** Socket level. @see pj_SOL_SOCKET() */\nextern const pj_uint16_t PJ_SOL_SOCKET;\n/** IP level. @see pj_SOL_IP() */\nextern const pj_uint16_t PJ_SOL_IP;\n/** TCP level. @see pj_SOL_TCP() */\nextern const pj_uint16_t PJ_SOL_TCP;\n/** UDP level. @see pj_SOL_UDP() */\nextern const pj_uint16_t PJ_SOL_UDP;\n/** IP version 6. @see pj_SOL_IPV6() */\nextern const pj_uint16_t PJ_SOL_IPV6;\n\n/*\n * Accessor functions for various constants. These functions are provided\n * because Symbian doesn't allow exporting global variables from a DLL.\n */\n\n#if defined(PJ_DLL)\n    /** Get #PJ_SOL_SOCKET constant */\n    PJ_DECL(pj_uint16_t) pj_SOL_SOCKET(void);\n    /** Get #PJ_SOL_IP constant */\n    PJ_DECL(pj_uint16_t) pj_SOL_IP(void);\n    /** Get #PJ_SOL_TCP constant */\n    PJ_DECL(pj_uint16_t) pj_SOL_TCP(void);\n    /** Get #PJ_SOL_UDP constant */\n    PJ_DECL(pj_uint16_t) pj_SOL_UDP(void);\n    /** Get #PJ_SOL_IPV6 constant */\n    PJ_DECL(pj_uint16_t) pj_SOL_IPV6(void);\n#else\n    /** Get #PJ_SOL_SOCKET constant */\n#   define pj_SOL_SOCKET()  PJ_SOL_SOCKET\n    /** Get #PJ_SOL_IP constant */\n#   define pj_SOL_IP()\t    PJ_SOL_IP\n    /** Get #PJ_SOL_TCP constant */\n#   define pj_SOL_TCP()\t    PJ_SOL_TCP\n    /** Get #PJ_SOL_UDP constant */\n#   define pj_SOL_UDP()\t    PJ_SOL_UDP\n    /** Get #PJ_SOL_IPV6 constant */\n#   define pj_SOL_IPV6()    PJ_SOL_IPV6\n#endif\n\n\n/* IP_TOS \n *\n * Note:\n *  TOS CURRENTLY DOES NOT WORK IN Windows 2000 and above!\n *  See http://support.microsoft.com/kb/248611\n */\n/** IP_TOS optname in setsockopt(). @see pj_IP_TOS() */\nextern const pj_uint16_t PJ_IP_TOS;\n\n/*\n * IP TOS related constats.\n *\n * Note:\n *  TOS CURRENTLY DOES NOT WORK IN Windows 2000 and above!\n *  See http://support.microsoft.com/kb/248611\n */\n/** Minimize delays. @see pj_IPTOS_LOWDELAY() */\nextern const pj_uint16_t PJ_IPTOS_LOWDELAY;\n\n/** Optimize throughput. @see pj_IPTOS_THROUGHPUT() */\nextern const pj_uint16_t PJ_IPTOS_THROUGHPUT;\n\n/** Optimize for reliability. @see pj_IPTOS_RELIABILITY() */\nextern const pj_uint16_t PJ_IPTOS_RELIABILITY;\n\n/** \"filler data\" where slow transmission does't matter.\n *  @see pj_IPTOS_MINCOST() */\nextern const pj_uint16_t PJ_IPTOS_MINCOST;\n\n\n#if defined(PJ_DLL)\n    /** Get #PJ_IP_TOS constant */\n    PJ_DECL(int) pj_IP_TOS(void);\n\n    /** Get #PJ_IPTOS_LOWDELAY constant */\n    PJ_DECL(int) pj_IPTOS_LOWDELAY(void);\n\n    /** Get #PJ_IPTOS_THROUGHPUT constant */\n    PJ_DECL(int) pj_IPTOS_THROUGHPUT(void);\n\n    /** Get #PJ_IPTOS_RELIABILITY constant */\n    PJ_DECL(int) pj_IPTOS_RELIABILITY(void);\n\n    /** Get #PJ_IPTOS_MINCOST constant */\n    PJ_DECL(int) pj_IPTOS_MINCOST(void);\n#else\n    /** Get #PJ_IP_TOS constant */\n#   define pj_IP_TOS()\t\tPJ_IP_TOS\n\n    /** Get #PJ_IPTOS_LOWDELAY constant */\n#   define pj_IPTOS_LOWDELAY()\tPJ_IP_TOS_LOWDELAY\n\n    /** Get #PJ_IPTOS_THROUGHPUT constant */\n#   define pj_IPTOS_THROUGHPUT() PJ_IP_TOS_THROUGHPUT\n\n    /** Get #PJ_IPTOS_RELIABILITY constant */\n#   define pj_IPTOS_RELIABILITY() PJ_IP_TOS_RELIABILITY\n\n    /** Get #PJ_IPTOS_MINCOST constant */\n#   define pj_IPTOS_MINCOST()\tPJ_IP_TOS_MINCOST\n#endif\n\n\n/**\n * Values to be specified as \\c optname when calling #pj_sock_setsockopt() \n * or #pj_sock_getsockopt().\n */\n\n/** Socket type. @see pj_SO_TYPE() */\nextern const pj_uint16_t PJ_SO_TYPE;\n\n/** Buffer size for receive. @see pj_SO_RCVBUF() */\nextern const pj_uint16_t PJ_SO_RCVBUF;\n\n/** Buffer size for send. @see pj_SO_SNDBUF() */\nextern const pj_uint16_t PJ_SO_SNDBUF;\n\n/** Disables the Nagle algorithm for send coalescing. @see pj_TCP_NODELAY */\nextern const pj_uint16_t PJ_TCP_NODELAY;\n\n/** Allows the socket to be bound to an address that is already in use.\n *  @see pj_SO_REUSEADDR */\nextern const pj_uint16_t PJ_SO_REUSEADDR;\n\n/** Do not generate SIGPIPE. @see pj_SO_NOSIGPIPE */\nextern const pj_uint16_t PJ_SO_NOSIGPIPE;\n\n/** Set the protocol-defined priority for all packets to be sent on socket.\n */\nextern const pj_uint16_t PJ_SO_PRIORITY;\n\n/** IP multicast interface. @see pj_IP_MULTICAST_IF() */\nextern const pj_uint16_t PJ_IP_MULTICAST_IF;\n \n/** IP multicast ttl. @see pj_IP_MULTICAST_TTL() */\nextern const pj_uint16_t PJ_IP_MULTICAST_TTL;\n\n/** IP multicast loopback. @see pj_IP_MULTICAST_LOOP() */\nextern const pj_uint16_t PJ_IP_MULTICAST_LOOP;\n\n/** Add an IP group membership. @see pj_IP_ADD_MEMBERSHIP() */\nextern const pj_uint16_t PJ_IP_ADD_MEMBERSHIP;\n\n/** Drop an IP group membership. @see pj_IP_DROP_MEMBERSHIP() */\nextern const pj_uint16_t PJ_IP_DROP_MEMBERSHIP;\n\n\n#if defined(PJ_DLL)\n    /** Get #PJ_SO_TYPE constant */\n    PJ_DECL(pj_uint16_t) pj_SO_TYPE(void);\n\n    /** Get #PJ_SO_RCVBUF constant */\n    PJ_DECL(pj_uint16_t) pj_SO_RCVBUF(void);\n\n    /** Get #PJ_SO_SNDBUF constant */\n    PJ_DECL(pj_uint16_t) pj_SO_SNDBUF(void);\n\n    /** Get #PJ_TCP_NODELAY constant */\n    PJ_DECL(pj_uint16_t) pj_TCP_NODELAY(void);\n\n    /** Get #PJ_SO_REUSEADDR constant */\n    PJ_DECL(pj_uint16_t) pj_SO_REUSEADDR(void);\n\n    /** Get #PJ_SO_NOSIGPIPE constant */\n    PJ_DECL(pj_uint16_t) pj_SO_NOSIGPIPE(void);\n\n    /** Get #PJ_SO_PRIORITY constant */\n    PJ_DECL(pj_uint16_t) pj_SO_PRIORITY(void);\n\n    /** Get #PJ_IP_MULTICAST_IF constant */\n    PJ_DECL(pj_uint16_t) pj_IP_MULTICAST_IF(void);\n\n    /** Get #PJ_IP_MULTICAST_TTL constant */\n    PJ_DECL(pj_uint16_t) pj_IP_MULTICAST_TTL(void);\n\n    /** Get #PJ_IP_MULTICAST_LOOP constant */\n    PJ_DECL(pj_uint16_t) pj_IP_MULTICAST_LOOP(void);\n\n    /** Get #PJ_IP_ADD_MEMBERSHIP constant */\n    PJ_DECL(pj_uint16_t) pj_IP_ADD_MEMBERSHIP(void);\n\n    /** Get #PJ_IP_DROP_MEMBERSHIP constant */\n    PJ_DECL(pj_uint16_t) pj_IP_DROP_MEMBERSHIP(void);\n#else\n    /** Get #PJ_SO_TYPE constant */\n#   define pj_SO_TYPE()\t    PJ_SO_TYPE\n\n    /** Get #PJ_SO_RCVBUF constant */\n#   define pj_SO_RCVBUF()   PJ_SO_RCVBUF\n\n    /** Get #PJ_SO_SNDBUF constant */\n#   define pj_SO_SNDBUF()   PJ_SO_SNDBUF\n\n    /** Get #PJ_TCP_NODELAY constant */\n#   define pj_TCP_NODELAY() PJ_TCP_NODELAY\n\n    /** Get #PJ_SO_REUSEADDR constant */\n#   define pj_SO_REUSEADDR() PJ_SO_REUSEADDR\n\n    /** Get #PJ_SO_NOSIGPIPE constant */\n#   define pj_SO_NOSIGPIPE() PJ_SO_NOSIGPIPE\n\n    /** Get #PJ_SO_PRIORITY constant */\n#   define pj_SO_PRIORITY() PJ_SO_PRIORITY\n\n    /** Get #PJ_IP_MULTICAST_IF constant */\n#   define pj_IP_MULTICAST_IF()    PJ_IP_MULTICAST_IF\n\n    /** Get #PJ_IP_MULTICAST_TTL constant */\n#   define pj_IP_MULTICAST_TTL()   PJ_IP_MULTICAST_TTL\n\n    /** Get #PJ_IP_MULTICAST_LOOP constant */\n#   define pj_IP_MULTICAST_LOOP()  PJ_IP_MULTICAST_LOOP\n\n    /** Get #PJ_IP_ADD_MEMBERSHIP constant */\n#   define pj_IP_ADD_MEMBERSHIP()  PJ_IP_ADD_MEMBERSHIP\n\n    /** Get #PJ_IP_DROP_MEMBERSHIP constant */\n#   define pj_IP_DROP_MEMBERSHIP() PJ_IP_DROP_MEMBERSHIP\n#endif\n\n\n/*\n * Flags to be specified in #pj_sock_recv, #pj_sock_send, etc.\n */\n\n/** Out-of-band messages. @see pj_MSG_OOB() */\nextern const int PJ_MSG_OOB;\n\n/** Peek, don't remove from buffer. @see pj_MSG_PEEK() */\nextern const int PJ_MSG_PEEK;\n\n/** Don't route. @see pj_MSG_DONTROUTE() */\nextern const int PJ_MSG_DONTROUTE;\n\n\n#if defined(PJ_DLL)\n    /** Get #PJ_MSG_OOB constant */\n    PJ_DECL(int) pj_MSG_OOB(void);\n\n    /** Get #PJ_MSG_PEEK constant */\n    PJ_DECL(int) pj_MSG_PEEK(void);\n\n    /** Get #PJ_MSG_DONTROUTE constant */\n    PJ_DECL(int) pj_MSG_DONTROUTE(void);\n#else\n    /** Get #PJ_MSG_OOB constant */\n#   define pj_MSG_OOB()\t\tPJ_MSG_OOB\n\n    /** Get #PJ_MSG_PEEK constant */\n#   define pj_MSG_PEEK()\tPJ_MSG_PEEK\n\n    /** Get #PJ_MSG_DONTROUTE constant */\n#   define pj_MSG_DONTROUTE()\tPJ_MSG_DONTROUTE\n#endif\n\n\n/**\n * Flag to be specified in #pj_sock_shutdown().\n */\ntypedef enum pj_socket_sd_type\n{\n    PJ_SD_RECEIVE   = 0,    /**< No more receive.\t    */\n    PJ_SHUT_RD\t    = 0,    /**< Alias for SD_RECEIVE.\t    */\n    PJ_SD_SEND\t    = 1,    /**< No more sending.\t    */\n    PJ_SHUT_WR\t    = 1,    /**< Alias for SD_SEND.\t    */\n    PJ_SD_BOTH\t    = 2,    /**< No more send and receive.  */\n    PJ_SHUT_RDWR    = 2     /**< Alias for SD_BOTH.\t    */\n} pj_socket_sd_type;\n\n\n\n/** Address to accept any incoming messages. */\n#define PJ_INADDR_ANY\t    ((pj_uint32_t)0)\n\n/** Address indicating an error return */\n#define PJ_INADDR_NONE\t    ((pj_uint32_t)0xffffffff)\n\n/** Address to send to all hosts. */\n#define PJ_INADDR_BROADCAST ((pj_uint32_t)0xffffffff)\n\n\n/** \n * Maximum length specifiable by #pj_sock_listen().\n * If the build system doesn't override this value, then the lowest \n * denominator (five, in Win32 systems) will be used.\n */\n#if !defined(PJ_SOMAXCONN)\n#  define PJ_SOMAXCONN\t5\n#endif\n\n\n/**\n * Constant for invalid socket returned by #pj_sock_socket() and\n * #pj_sock_accept().\n */\n#define PJ_INVALID_SOCKET   (-1)\n\n/* Must undefine s_addr because of pj_in_addr below */\n#undef s_addr\n\n/**\n * This structure describes Internet address.\n */\ntypedef struct pj_in_addr\n{\n    pj_uint32_t\ts_addr;\t\t/**< The 32bit IP address.\t    */\n} pj_in_addr;\n\n\n/**\n * Maximum length of text representation of an IPv4 address.\n */\n#define PJ_INET_ADDRSTRLEN\t16\n\n/**\n * Maximum length of text representation of an IPv6 address.\n */\n#define PJ_INET6_ADDRSTRLEN\t46\n\n/**\n * The size of sin_zero field in pj_sockaddr_in structure. Most OSes\n * use 8, but others such as the BSD TCP/IP stack in eCos uses 24.\n */\n#ifndef PJ_SOCKADDR_IN_SIN_ZERO_LEN\n#   define PJ_SOCKADDR_IN_SIN_ZERO_LEN\t8\n#endif\n\n/**\n * This structure describes Internet socket address.\n * If PJ_SOCKADDR_HAS_LEN is not zero, then sin_zero_len member is added\n * to this struct. As far the application is concerned, the value of\n * this member will always be zero. Internally, PJLIB may modify the value\n * before calling OS socket API, and reset the value back to zero before\n * returning the struct to application.\n */\nstruct pj_sockaddr_in\n{\n#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0\n    pj_uint8_t  sin_zero_len;\t/**< Just ignore this.\t\t    */\n    pj_uint8_t  sin_family;\t/**< Address family.\t\t    */\n#else\n    pj_uint16_t\tsin_family;\t/**< Address family.\t\t    */\n#endif\n    pj_uint16_t\tsin_port;\t/**< Transport layer port number.   */\n    pj_in_addr\tsin_addr;\t/**< IP address.\t\t    */\n    char\tsin_zero[PJ_SOCKADDR_IN_SIN_ZERO_LEN]; /**< Padding.*/\n};\n\n\n#undef s6_addr\n\n/**\n * This structure describes IPv6 address.\n */\ntypedef union pj_in6_addr\n{\n    /* This is the main entry */\n    pj_uint8_t  s6_addr[16];   /**< 8-bit array */\n\n    /* While these are used for proper alignment */\n    pj_uint32_t\tu6_addr32[4];\n\n    /* Do not use this with Winsock2, as this will align pj_sockaddr_in6\n     * to 64-bit boundary and Winsock2 doesn't like it!\n     * Update 26/04/2010:\n     *  This is now disabled, see http://trac.pjsip.org/repos/ticket/1058\n     */\n#if 0 && defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0 && \\\n    (!defined(PJ_WIN32) || PJ_WIN32==0)\n    pj_int64_t\tu6_addr64[2];\n#endif\n\n} pj_in6_addr;\n\n\n/** Initializer value for pj_in6_addr. */\n#define PJ_IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }\n\n/** Initializer value for pj_in6_addr. */\n#define PJ_IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }\n\n/**\n * This structure describes IPv6 socket address.\n * If PJ_SOCKADDR_HAS_LEN is not zero, then sin_zero_len member is added\n * to this struct. As far the application is concerned, the value of\n * this member will always be zero. Internally, PJLIB may modify the value\n * before calling OS socket API, and reset the value back to zero before\n * returning the struct to application.\n */\ntypedef struct pj_sockaddr_in6\n{\n#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0\n    pj_uint8_t  sin6_zero_len;\t    /**< Just ignore this.\t   */\n    pj_uint8_t  sin6_family;\t    /**< Address family.\t   */\n#else\n    pj_uint16_t\tsin6_family;\t    /**< Address family\t\t    */\n#endif\n    pj_uint16_t\tsin6_port;\t    /**< Transport layer port number. */\n    pj_uint32_t\tsin6_flowinfo;\t    /**< IPv6 flow information\t    */\n    pj_in6_addr sin6_addr;\t    /**< IPv6 address.\t\t    */\n    pj_uint32_t sin6_scope_id;\t    /**< Set of interfaces for a scope\t*/\n} pj_sockaddr_in6;\n\n\n/**\n * This structure describes common attributes found in transport addresses.\n * If PJ_SOCKADDR_HAS_LEN is not zero, then sa_zero_len member is added\n * to this struct. As far the application is concerned, the value of\n * this member will always be zero. Internally, PJLIB may modify the value\n * before calling OS socket API, and reset the value back to zero before\n * returning the struct to application.\n */\ntypedef struct pj_addr_hdr\n{\n#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0\n    pj_uint8_t  sa_zero_len;\n    pj_uint8_t  sa_family;\n#else\n    pj_uint16_t\tsa_family;\t/**< Common data: address family.   */\n#endif\n} pj_addr_hdr;\n\n\n/**\n * This union describes a generic socket address.\n */\ntypedef union pj_sockaddr\n{\n    pj_addr_hdr\t    addr;\t/**< Generic transport address.\t    */\n    pj_sockaddr_in  ipv4;\t/**< IPv4 transport address.\t    */\n    pj_sockaddr_in6 ipv6;\t/**< IPv6 transport address.\t    */\n} pj_sockaddr;\n\n\n/**\n * This structure provides multicast group information for IPv4 addresses.\n */\ntypedef struct pj_ip_mreq {\n    pj_in_addr imr_multiaddr;\t/**< IP multicast address of group. */\n    pj_in_addr imr_interface;\t/**< local IP address of interface. */\n} pj_ip_mreq;\n\n/* Maximum number of socket options. */\n#define PJ_MAX_SOCKOPT_PARAMS 4\n\n/**\n * Options to be set for the socket. \n */\ntypedef struct pj_sockopt_params\n{\n    /* The number of options to be applied. */\n    unsigned cnt;\n\n    /* Array of options to be applied. */\n    struct {\n\t/* The level at which the option is defined. */\n\tint level;\n\n\t/* Option name. */\n\tint optname;\n\n\t/* Pointer to the buffer in which the option is specified. */\n\tvoid *optval;\n\n\t/* Buffer size of the buffer pointed by optval. */\n\tint optlen;\n    } options[PJ_MAX_SOCKOPT_PARAMS];\n} pj_sockopt_params;\n\n/*****************************************************************************\n *\n * SOCKET ADDRESS MANIPULATION.\n *\n *****************************************************************************\n */\n\n/**\n * Convert 16-bit value from network byte order to host byte order.\n *\n * @param netshort  16-bit network value.\n * @return\t    16-bit host value.\n */\nPJ_DECL(pj_uint16_t) pj_ntohs(pj_uint16_t netshort);\n\n/**\n * Convert 16-bit value from host byte order to network byte order.\n *\n * @param hostshort 16-bit host value.\n * @return\t    16-bit network value.\n */\nPJ_DECL(pj_uint16_t) pj_htons(pj_uint16_t hostshort);\n\n/**\n * Convert 32-bit value from network byte order to host byte order.\n *\n * @param netlong   32-bit network value.\n * @return\t    32-bit host value.\n */\nPJ_DECL(pj_uint32_t) pj_ntohl(pj_uint32_t netlong);\n\n/**\n * Convert 32-bit value from host byte order to network byte order.\n *\n * @param hostlong  32-bit host value.\n * @return\t    32-bit network value.\n */\nPJ_DECL(pj_uint32_t) pj_htonl(pj_uint32_t hostlong);\n\n/**\n * Convert an Internet host address given in network byte order\n * to string in standard numbers and dots notation.\n *\n * @param inaddr    The host address.\n * @return\t    The string address.\n */\nPJ_DECL(char*) pj_inet_ntoa(pj_in_addr inaddr);\n\n/**\n * This function converts the Internet host address cp from the standard\n * numbers-and-dots notation into binary data and stores it in the structure\n * that inp points to. \n *\n * @param cp\tIP address in standard numbers-and-dots notation.\n * @param inp\tStructure that holds the output of the conversion.\n *\n * @return\tnonzero if the address is valid, zero if not.\n */\nPJ_DECL(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp);\n\n/**\n * This function converts an address in its standard text presentation form\n * into its numeric binary form. It supports both IPv4 and IPv6 address\n * conversion.\n *\n * @param af\tSpecify the family of the address.  The PJ_AF_INET and \n *\t\tPJ_AF_INET6 address families shall be supported.  \n * @param src\tPoints to the string being passed in. \n * @param dst\tPoints to a buffer into which the function stores the \n *\t\tnumeric address; this shall be large enough to hold the\n *\t\tnumeric address (32 bits for PJ_AF_INET, 128 bits for\n *\t\tPJ_AF_INET6).  \n *\n * @return\tPJ_SUCCESS if conversion was successful.\n */\nPJ_DECL(pj_status_t) pj_inet_pton(int af, const pj_str_t *src, void *dst);\n\n/**\n * This function converts a numeric address into a text string suitable\n * for presentation. It supports both IPv4 and IPv6 address\n * conversion. \n * @see pj_sockaddr_print()\n *\n * @param af\tSpecify the family of the address. This can be PJ_AF_INET\n *\t\tor PJ_AF_INET6.\n * @param src\tPoints to a buffer holding an IPv4 address if the af argument\n *\t\tis PJ_AF_INET, or an IPv6 address if the af argument is\n *\t\tPJ_AF_INET6; the address must be in network byte order.  \n * @param dst\tPoints to a buffer where the function stores the resulting\n *\t\ttext string; it shall not be NULL.  \n * @param size\tSpecifies the size of this buffer, which shall be large \n *\t\tenough to hold the text string (PJ_INET_ADDRSTRLEN characters\n *\t\tfor IPv4, PJ_INET6_ADDRSTRLEN characters for IPv6).\n *\n * @return\tPJ_SUCCESS if conversion was successful.\n */\nPJ_DECL(pj_status_t) pj_inet_ntop(int af, const void *src,\n\t\t\t\t  char *dst, int size);\n\n/**\n * Converts numeric address into its text string representation.\n * @see pj_sockaddr_print()\n *\n * @param af\tSpecify the family of the address. This can be PJ_AF_INET\n *\t\tor PJ_AF_INET6.\n * @param src\tPoints to a buffer holding an IPv4 address if the af argument\n *\t\tis PJ_AF_INET, or an IPv6 address if the af argument is\n *\t\tPJ_AF_INET6; the address must be in network byte order.  \n * @param dst\tPoints to a buffer where the function stores the resulting\n *\t\ttext string; it shall not be NULL.  \n * @param size\tSpecifies the size of this buffer, which shall be large \n *\t\tenough to hold the text string (PJ_INET_ADDRSTRLEN characters\n *\t\tfor IPv4, PJ_INET6_ADDRSTRLEN characters for IPv6).\n *\n * @return\tThe address string or NULL if failed.\n */\nPJ_DECL(char*) pj_inet_ntop2(int af, const void *src,\n\t\t\t     char *dst, int size);\n\n/**\n * Print socket address.\n *\n * @param addr\tThe socket address.\n * @param buf\tText buffer.\n * @param size\tSize of buffer.\n * @param flags\tBitmask combination of these value:\n *\t\t  - 1: port number is included.\n *\t\t  - 2: square bracket is included for IPv6 address.\n *\n * @return\tThe address string.\n */\nPJ_DECL(char*) pj_sockaddr_print(const pj_sockaddr_t *addr,\n\t\t\t\t char *buf, int size,\n\t\t\t\t unsigned flags);\n\n/**\n * Convert address string with numbers and dots to binary IP address.\n * \n * @param cp\t    The IP address in numbers and dots notation.\n * @return\t    If success, the IP address is returned in network\n *\t\t    byte order. If failed, PJ_INADDR_NONE will be\n *\t\t    returned.\n * @remark\n * This is an obsolete interface to #pj_inet_aton(); it is obsolete\n * because -1 is a valid address (255.255.255.255), and #pj_inet_aton()\n * provides a cleaner way to indicate error return.\n */\nPJ_DECL(pj_in_addr) pj_inet_addr(const pj_str_t *cp);\n\n/**\n * Convert address string with numbers and dots to binary IP address.\n * \n * @param cp\t    The IP address in numbers and dots notation.\n * @return\t    If success, the IP address is returned in network\n *\t\t    byte order. If failed, PJ_INADDR_NONE will be\n *\t\t    returned.\n * @remark\n * This is an obsolete interface to #pj_inet_aton(); it is obsolete\n * because -1 is a valid address (255.255.255.255), and #pj_inet_aton()\n * provides a cleaner way to indicate error return.\n */\nPJ_DECL(pj_in_addr) pj_inet_addr2(const char *cp);\n\n/**\n * Initialize IPv4 socket address based on the address and port info.\n * The string address may be in a standard numbers and dots notation or \n * may be a hostname. If hostname is specified, then the function will \n * resolve the host into the IP address.\n *\n * @see pj_sockaddr_init()\n *\n * @param addr\t    The IP socket address to be set.\n * @param cp\t    The address string, which can be in a standard \n *\t\t    dotted numbers or a hostname to be resolved.\n * @param port\t    The port number, in host byte order.\n *\n * @return\t    Zero on success.\n */\nPJ_DECL(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr,\n\t\t\t\t          const pj_str_t *cp,\n\t\t\t\t\t  pj_uint16_t port);\n\n/**\n * Initialize IP socket address based on the address and port info.\n * The string address may be in a standard numbers and dots notation or \n * may be a hostname. If hostname is specified, then the function will \n * resolve the host into the IP address.\n *\n * @see pj_sockaddr_in_init()\n *\n * @param af\t    Internet address family.\n * @param addr\t    The IP socket address to be set.\n * @param cp\t    The address string, which can be in a standard \n *\t\t    dotted numbers or a hostname to be resolved.\n * @param port\t    The port number, in host byte order.\n *\n * @return\t    Zero on success.\n */\nPJ_DECL(pj_status_t) pj_sockaddr_init(int af, \n\t\t\t\t      pj_sockaddr *addr,\n\t\t\t\t      const pj_str_t *cp,\n\t\t\t\t      pj_uint16_t port);\n\n/**\n * Compare two socket addresses.\n *\n * @param addr1\t    First address.\n * @param addr2\t    Second address.\n *\n * @return\t    Zero on equal, -1 if addr1 is less than addr2,\n *\t\t    and +1 if addr1 is more than addr2.\n */\nPJ_DECL(int) pj_sockaddr_cmp(const pj_sockaddr_t *addr1,\n\t\t\t     const pj_sockaddr_t *addr2);\n\n/**\n * Get pointer to the address part of a socket address.\n * \n * @param addr\t    Socket address.\n *\n * @return\t    Pointer to address part (sin_addr or sin6_addr,\n *\t\t    depending on address family)\n */\nPJ_DECL(void*) pj_sockaddr_get_addr(const pj_sockaddr_t *addr);\n\n/**\n * Check that a socket address contains a non-zero address part.\n *\n * @param addr\t    Socket address.\n *\n * @return\t    Non-zero if address is set to non-zero.\n */\nPJ_DECL(pj_bool_t) pj_sockaddr_has_addr(const pj_sockaddr_t *addr);\n\n/**\n * Get the address part length of a socket address, based on its address\n * family. For PJ_AF_INET, the length will be sizeof(pj_in_addr), and\n * for PJ_AF_INET6, the length will be sizeof(pj_in6_addr).\n * \n * @param addr\t    Socket address.\n *\n * @return\t    Length in bytes.\n */\nPJ_DECL(unsigned) pj_sockaddr_get_addr_len(const pj_sockaddr_t *addr);\n\n/**\n * Get the socket address length, based on its address\n * family. For PJ_AF_INET, the length will be sizeof(pj_sockaddr_in), and\n * for PJ_AF_INET6, the length will be sizeof(pj_sockaddr_in6).\n * \n * @param addr\t    Socket address.\n *\n * @return\t    Length in bytes.\n */\nPJ_DECL(unsigned) pj_sockaddr_get_len(const pj_sockaddr_t *addr);\n\n/** \n * Copy only the address part (sin_addr/sin6_addr) of a socket address.\n *\n * @param dst\t    Destination socket address.\n * @param src\t    Source socket address.\n *\n * @see @pj_sockaddr_cp()\n */\nPJ_DECL(void) pj_sockaddr_copy_addr(pj_sockaddr *dst,\n\t\t\t\t    const pj_sockaddr *src);\n/**\n * Copy socket address. This will copy the whole structure depending\n * on the address family of the source socket address.\n *\n * @param dst\t    Destination socket address.\n * @param src\t    Source socket address.\n *\n * @see @pj_sockaddr_copy_addr()\n */\nPJ_DECL(void) pj_sockaddr_cp(pj_sockaddr_t *dst, const pj_sockaddr_t *src);\n\n/**\n * Get the IP address of an IPv4 socket address.\n * The address is returned as 32bit value in host byte order.\n *\n * @param addr\t    The IP socket address.\n * @return\t    32bit address, in host byte order.\n */\nPJ_DECL(pj_in_addr) pj_sockaddr_in_get_addr(const pj_sockaddr_in *addr);\n\n/**\n * Set the IP address of an IPv4 socket address.\n *\n * @param addr\t    The IP socket address.\n * @param hostaddr  The host address, in host byte order.\n */\nPJ_DECL(void) pj_sockaddr_in_set_addr(pj_sockaddr_in *addr,\n\t\t\t\t      pj_uint32_t hostaddr);\n\n/**\n * Set the IP address of an IP socket address from string address, \n * with resolving the host if necessary. The string address may be in a\n * standard numbers and dots notation or may be a hostname. If hostname\n * is specified, then the function will resolve the host into the IP\n * address.\n *\n * @see pj_sockaddr_set_str_addr()\n *\n * @param addr\t    The IP socket address to be set.\n * @param cp\t    The address string, which can be in a standard \n *\t\t    dotted numbers or a hostname to be resolved.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr,\n\t\t\t\t\t          const pj_str_t *cp);\n\n/**\n * Set the IP address of an IPv4 or IPv6 socket address from string address,\n * with resolving the host if necessary. The string address may be in a\n * standard IPv6 or IPv6 address or may be a hostname. If hostname\n * is specified, then the function will resolve the host into the IP\n * address according to the address family.\n *\n * @param af\t    Address family.\n * @param addr\t    The IP socket address to be set.\n * @param cp\t    The address string, which can be in a standard \n *\t\t    IP numbers (IPv4 or IPv6) or a hostname to be resolved.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pj_sockaddr_set_str_addr(int af,\n\t\t\t\t\t      pj_sockaddr *addr,\n\t\t\t\t\t      const pj_str_t *cp);\n\n/**\n * Get the port number of a socket address, in host byte order. \n * This function can be used for both IPv4 and IPv6 socket address.\n * \n * @param addr\t    Socket address.\n *\n * @return\t    Port number, in host byte order.\n */\nPJ_DECL(pj_uint16_t) pj_sockaddr_get_port(const pj_sockaddr_t *addr);\n\n/**\n * Get the transport layer port number of an Internet socket address.\n * The port is returned in host byte order.\n *\n * @param addr\t    The IP socket address.\n * @return\t    Port number, in host byte order.\n */\nPJ_DECL(pj_uint16_t) pj_sockaddr_in_get_port(const pj_sockaddr_in *addr);\n\n/**\n * Set the port number of an Internet socket address.\n *\n * @param addr\t    The socket address.\n * @param hostport  The port number, in host byte order.\n */\nPJ_DECL(pj_status_t) pj_sockaddr_set_port(pj_sockaddr *addr, \n\t\t\t\t\t  pj_uint16_t hostport);\n\n/**\n * Set the port number of an IPv4 socket address.\n *\n * @see pj_sockaddr_set_port()\n *\n * @param addr\t    The IP socket address.\n * @param hostport  The port number, in host byte order.\n */\nPJ_DECL(void) pj_sockaddr_in_set_port(pj_sockaddr_in *addr, \n\t\t\t\t      pj_uint16_t hostport);\n\n/**\n * Parse string containing IP address and optional port into socket address,\n * possibly also with address family detection. This function supports both\n * IPv4 and IPv6 parsing, however IPv6 parsing may only be done if IPv6 is\n * enabled during compilation.\n *\n * This function supports parsing several formats. Sample IPv4 inputs and\n * their default results::\n *  - \"10.0.0.1:80\": address 10.0.0.1 and port 80.\n *  - \"10.0.0.1\": address 10.0.0.1 and port zero.\n *  - \"10.0.0.1:\": address 10.0.0.1 and port zero.\n *  - \"10.0.0.1:0\": address 10.0.0.1 and port zero.\n *  - \":80\": address 0.0.0.0 and port 80.\n *  - \":\": address 0.0.0.0 and port 0.\n *  - \"localhost\": address 127.0.0.1 and port 0.\n *  - \"localhost:\": address 127.0.0.1 and port 0.\n *  - \"localhost:80\": address 127.0.0.1 and port 80.\n *\n * Sample IPv6 inputs and their default results:\n *  - \"[fec0::01]:80\": address fec0::01 and port 80\n *  - \"[fec0::01]\": address fec0::01 and port 0\n *  - \"[fec0::01]:\": address fec0::01 and port 0\n *  - \"[fec0::01]:0\": address fec0::01 and port 0\n *  - \"fec0::01\": address fec0::01 and port 0\n *  - \"fec0::01:80\": address fec0::01:80 and port 0\n *  - \"::\": address zero (::) and port 0\n *  - \"[::]\": address zero (::) and port 0\n *  - \"[::]:\": address zero (::) and port 0\n *  - \":::\": address zero (::) and port 0\n *  - \"[::]:80\": address zero (::) and port 0\n *  - \":::80\": address zero (::) and port 80\n *\n * Note: when the IPv6 socket address contains port number, the IP \n * part of the socket address should be enclosed with square brackets, \n * otherwise the port number will be included as part of the IP address\n * (see \"fec0::01:80\" example above).\n *\n * @param af\t    Optionally specify the address family to be used. If the\n *\t\t    address family is to be deducted from the input, specify\n *\t\t    pj_AF_UNSPEC() here. Other supported values are\n *\t\t    #pj_AF_INET() and #pj_AF_INET6()\n * @param options   Additional options to assist the parsing, must be zero\n *\t\t    for now.\n * @param str\t    The input string to be parsed.\n * @param addr\t    Pointer to store the result.\n *\n * @return\t    PJ_SUCCESS if the parsing is successful.\n *\n * @see pj_sockaddr_parse2()\n */\nPJ_DECL(pj_status_t) pj_sockaddr_parse(int af, unsigned options,\n\t\t\t\t       const pj_str_t *str,\n\t\t\t\t       pj_sockaddr *addr);\n\n/**\n * This function is similar to #pj_sockaddr_parse(), except that it will not\n * convert the hostpart into IP address (thus possibly resolving the hostname\n * into a #pj_sockaddr. \n *\n * Unlike #pj_sockaddr_parse(), this function has a limitation that if port \n * number is specified in an IPv6 input string, the IP part of the IPv6 socket\n * address MUST be enclosed in square brackets, otherwise the port number will\n * be considered as part of the IPv6 IP address.\n *\n * @param af\t    Optionally specify the address family to be used. If the\n *\t\t    address family is to be deducted from the input, specify\n *\t\t    #pj_AF_UNSPEC() here. Other supported values are\n *\t\t    #pj_AF_INET() and #pj_AF_INET6()\n * @param options   Additional options to assist the parsing, must be zero\n *\t\t    for now.\n * @param str\t    The input string to be parsed.\n * @param hostpart  Optional pointer to store the host part of the socket \n *\t\t    address, with any brackets removed.\n * @param port\t    Optional pointer to store the port number. If port number\n *\t\t    is not found, this will be set to zero upon return.\n * @param raf\t    Optional pointer to store the detected address family of\n *\t\t    the input address.\n *\n * @return\t    PJ_SUCCESS if the parsing is successful.\n *\n * @see pj_sockaddr_parse()\n */\nPJ_DECL(pj_status_t) pj_sockaddr_parse2(int af, unsigned options,\n\t\t\t\t        const pj_str_t *str,\n\t\t\t\t        pj_str_t *hostpart,\n\t\t\t\t        pj_uint16_t *port,\n\t\t\t\t\tint *raf);\n\n/*****************************************************************************\n *\n * HOST NAME AND ADDRESS.\n *\n *****************************************************************************\n */\n\n/**\n * Get system's host name.\n *\n * @return\t    The hostname, or empty string if the hostname can not\n *\t\t    be identified.\n */\nPJ_DECL(const pj_str_t*) pj_gethostname(void);\n\n/**\n * Get host's IP address, which the the first IP address that is resolved\n * from the hostname.\n *\n * @return\t    The host's IP address, PJ_INADDR_NONE if the host\n *\t\t    IP address can not be identified.\n */\nPJ_DECL(pj_in_addr) pj_gethostaddr(void);\n\n\n/*****************************************************************************\n *\n * SOCKET API.\n *\n *****************************************************************************\n */\n\n/**\n * Create new socket/endpoint for communication.\n *\n * @param family    Specifies a communication domain; this selects the\n *\t\t    protocol family which will be used for communication.\n * @param type\t    The socket has the indicated type, which specifies the \n *\t\t    communication semantics.\n * @param protocol  Specifies  a  particular  protocol  to  be used with the\n *\t\t    socket.  Normally only a single protocol exists to support \n *\t\t    a particular socket  type  within  a given protocol family, \n *\t\t    in which a case protocol can be specified as 0.\n * @param sock\t    New socket descriptor, or PJ_INVALID_SOCKET on error.\n *\n * @return\t    Zero on success.\n */\nPJ_DECL(pj_status_t) pj_sock_socket(int family, \n\t\t\t\t    int type, \n\t\t\t\t    int protocol,\n\t\t\t\t    pj_sock_t *sock);\n\n/**\n * Close the socket descriptor.\n *\n * @param sockfd    The socket descriptor.\n *\n * @return\t    Zero on success.\n */\nPJ_DECL(pj_status_t) pj_sock_close(pj_sock_t sockfd);\n\n\n/**\n * This function gives the socket sockfd the local address my_addr. my_addr is\n * addrlen bytes long.  Traditionally, this is called assigning a name to\n * a socket. When a socket is created with #pj_sock_socket(), it exists in a\n * name space (address family) but has no name assigned.\n *\n * @param sockfd    The socket desriptor.\n * @param my_addr   The local address to bind the socket to.\n * @param addrlen   The length of the address.\n *\n * @return\t    Zero on success.\n */\nPJ_DECL(pj_status_t) pj_sock_bind( pj_sock_t sockfd, \n\t\t\t\t   const pj_sockaddr_t *my_addr,\n\t\t\t\t   int addrlen);\n\n/**\n * Bind the IP socket sockfd to the given address and port.\n *\n * @param sockfd    The socket descriptor.\n * @param addr\t    Local address to bind the socket to, in host byte order.\n * @param port\t    The local port to bind the socket to, in host byte order.\n *\n * @return\t    Zero on success.\n */\nPJ_DECL(pj_status_t) pj_sock_bind_in( pj_sock_t sockfd, \n\t\t\t\t      pj_uint32_t addr,\n\t\t\t\t      pj_uint16_t port);\n\n/**\n * Bind the IP socket sockfd to the given address and a random port in the\n * specified range.\n *\n * @param sockfd    \tThe socket desriptor.\n * @param addr      \tThe local address and port to bind the socket to.\n * @param port_range\tThe port range, relative the to start port number\n * \t\t\tspecified in port field in #addr. Note that if the\n * \t\t\tport is zero, this param will be ignored.\n * @param max_try   \tMaximum retries.\n *\n * @return\t    \tZero on success.\n */\nPJ_DECL(pj_status_t) pj_sock_bind_random( pj_sock_t sockfd,\n\t\t\t\t          const pj_sockaddr_t *addr,\n\t\t\t\t          pj_uint16_t port_range,\n\t\t\t\t          pj_uint16_t max_try);\n\n#if PJ_HAS_TCP\n/**\n * Listen for incoming connection. This function only applies to connection\n * oriented sockets (such as PJ_SOCK_STREAM or PJ_SOCK_SEQPACKET), and it\n * indicates the willingness to accept incoming connections.\n *\n * @param sockfd\tThe socket descriptor.\n * @param backlog\tDefines the maximum length the queue of pending\n *\t\t\tconnections may grow to.\n *\n * @return\t\tZero on success.\n */\nPJ_DECL(pj_status_t) pj_sock_listen( pj_sock_t sockfd, \n\t\t\t\t     int backlog );\n\n/**\n * Accept new connection on the specified connection oriented server socket.\n *\n * @param serverfd  The server socket.\n * @param newsock   New socket on success, of PJ_INVALID_SOCKET if failed.\n * @param addr\t    A pointer to sockaddr type. If the argument is not NULL,\n *\t\t    it will be filled by the address of connecting entity.\n * @param addrlen   Initially specifies the length of the address, and upon\n *\t\t    return will be filled with the exact address length.\n *\n * @return\t    Zero on success, or the error number.\n */\nPJ_DECL(pj_status_t) pj_sock_accept( pj_sock_t serverfd,\n\t\t\t\t     pj_sock_t *newsock,\n\t\t\t\t     pj_sockaddr_t *addr,\n\t\t\t\t     int *addrlen);\n#endif\n\n/**\n * The file descriptor sockfd must refer to a socket.  If the socket is of\n * type PJ_SOCK_DGRAM  then the serv_addr address is the address to which\n * datagrams are sent by default, and the only address from which datagrams\n * are received. If the socket is of type PJ_SOCK_STREAM or PJ_SOCK_SEQPACKET,\n * this call attempts to make a connection to another socket.  The\n * other socket is specified by serv_addr, which is an address (of length\n * addrlen) in the communications space of the  socket.  Each  communications\n * space interprets the serv_addr parameter in its own way.\n *\n * @param sockfd\tThe socket descriptor.\n * @param serv_addr\tServer address to connect to.\n * @param addrlen\tThe length of server address.\n *\n * @return\t\tZero on success.\n */\nPJ_DECL(pj_status_t) pj_sock_connect( pj_sock_t sockfd,\n\t\t\t\t      const pj_sockaddr_t *serv_addr,\n\t\t\t\t      int addrlen);\n\n/**\n * Return the address of peer which is connected to socket sockfd.\n *\n * @param sockfd\tThe socket descriptor.\n * @param addr\t\tPointer to sockaddr structure to which the address\n *\t\t\twill be returned.\n * @param namelen\tInitially the length of the addr. Upon return the value\n *\t\t\twill be set to the actual length of the address.\n *\n * @return\t\tZero on success.\n */\nPJ_DECL(pj_status_t) pj_sock_getpeername(pj_sock_t sockfd,\n\t\t\t\t\t  pj_sockaddr_t *addr,\n\t\t\t\t\t  int *namelen);\n\n/**\n * Return the current name of the specified socket.\n *\n * @param sockfd\tThe socket descriptor.\n * @param addr\t\tPointer to sockaddr structure to which the address\n *\t\t\twill be returned.\n * @param namelen\tInitially the length of the addr. Upon return the value\n *\t\t\twill be set to the actual length of the address.\n *\n * @return\t\tZero on success.\n */\nPJ_DECL(pj_status_t) pj_sock_getsockname( pj_sock_t sockfd,\n\t\t\t\t\t  pj_sockaddr_t *addr,\n\t\t\t\t\t  int *namelen);\n\n/**\n * Get socket option associated with a socket. Options may exist at multiple\n * protocol levels; they are always present at the uppermost socket level.\n *\n * @param sockfd\tThe socket descriptor.\n * @param level\t\tThe level which to get the option from.\n * @param optname\tThe option name.\n * @param optval\tIdentifies the buffer which the value will be\n *\t\t\treturned.\n * @param optlen\tInitially contains the length of the buffer, upon\n *\t\t\treturn will be set to the actual size of the value.\n *\n * @return\t\tZero on success.\n */\nPJ_DECL(pj_status_t) pj_sock_getsockopt( pj_sock_t sockfd,\n\t\t\t\t\t pj_uint16_t level,\n\t\t\t\t\t pj_uint16_t optname,\n\t\t\t\t\t void *optval,\n\t\t\t\t\t int *optlen);\n/**\n * Manipulate the options associated with a socket. Options may exist at \n * multiple protocol levels; they are always present at the uppermost socket \n * level.\n *\n * @param sockfd\tThe socket descriptor.\n * @param level\t\tThe level which to get the option from.\n * @param optname\tThe option name.\n * @param optval\tIdentifies the buffer which contain the value.\n * @param optlen\tThe length of the value.\n *\n * @return\t\tPJ_SUCCESS or the status code.\n */\nPJ_DECL(pj_status_t) pj_sock_setsockopt( pj_sock_t sockfd,\n\t\t\t\t\t pj_uint16_t level,\n\t\t\t\t\t pj_uint16_t optname,\n\t\t\t\t\t const void *optval,\n\t\t\t\t\t int optlen);\n\n/**\n * Set socket options associated with a socket. This method will apply all the \n * options specified, and ignore any errors that might be raised.\n *\n * @param sockfd\tThe socket descriptor.\n * @param params\tThe socket options.\n *\n * @return\t\tPJ_SUCCESS or the last error code. \n */\nPJ_DECL(pj_status_t) pj_sock_setsockopt_params( pj_sock_t sockfd,\n\t\t\t\t\t       const pj_sockopt_params *params);\t\t\t\t\t       \n\n/**\n * Helper function to set socket buffer size using #pj_sock_setsockopt()\n * with capability to auto retry with lower buffer setting value until\n * the highest possible value is successfully set.\n *\n * @param sockfd\tThe socket descriptor.\n * @param optname\tThe option name, valid values are pj_SO_RCVBUF()\n *\t\t\tand pj_SO_SNDBUF().\n * @param auto_retry\tOption whether auto retry with lower value is\n *\t\t\tenabled.\n * @param buf_size\tOn input, specify the prefered buffer size setting,\n *\t\t\ton output, the buffer size setting applied.\n *\n * @return\t\tPJ_SUCCESS or the status code.\n */\nPJ_DECL(pj_status_t) pj_sock_setsockopt_sobuf( pj_sock_t sockfd,\n\t\t\t\t\t       pj_uint16_t optname,\n\t\t\t\t\t       pj_bool_t auto_retry,\n\t\t\t\t\t       unsigned *buf_size);\n\n\n/**\n * Receives data stream or message coming to the specified socket.\n *\n * @param sockfd\tThe socket descriptor.\n * @param buf\t\tThe buffer to receive the data or message.\n * @param len\t\tOn input, the length of the buffer. On return,\n *\t\t\tcontains the length of data received.\n * @param flags\t\tFlags (such as pj_MSG_PEEK()).\n *\n * @return\t\tPJ_SUCCESS or the error code.\n */\nPJ_DECL(pj_status_t) pj_sock_recv(pj_sock_t sockfd,\n\t\t\t\t  void *buf,\n\t\t\t\t  pj_ssize_t *len,\n\t\t\t\t  unsigned flags);\n\n/**\n * Receives data stream or message coming to the specified socket.\n *\n * @param sockfd\tThe socket descriptor.\n * @param buf\t\tThe buffer to receive the data or message.\n * @param len\t\tOn input, the length of the buffer. On return,\n *\t\t\tcontains the length of data received.\n * @param flags\t\tFlags (such as pj_MSG_PEEK()).\n * @param from\t\tIf not NULL, it will be filled with the source\n *\t\t\taddress of the connection.\n * @param fromlen\tInitially contains the length of from address,\n *\t\t\tand upon return will be filled with the actual\n *\t\t\tlength of the address.\n *\n * @return\t\tPJ_SUCCESS or the error code.\n */\nPJ_DECL(pj_status_t) pj_sock_recvfrom( pj_sock_t sockfd,\n\t\t\t\t      void *buf,\n\t\t\t\t      pj_ssize_t *len,\n\t\t\t\t      unsigned flags,\n\t\t\t\t      pj_sockaddr_t *from,\n\t\t\t\t      int *fromlen);\n\n/**\n * Transmit data to the socket.\n *\n * @param sockfd\tSocket descriptor.\n * @param buf\t\tBuffer containing data to be sent.\n * @param len\t\tOn input, the length of the data in the buffer.\n *\t\t\tUpon return, it will be filled with the length\n *\t\t\tof data sent.\n * @param flags\t\tFlags (such as pj_MSG_DONTROUTE()).\n *\n * @return\t\tPJ_SUCCESS or the status code.\n */\nPJ_DECL(pj_status_t) pj_sock_send(pj_sock_t sockfd,\n\t\t\t\t  const void *buf,\n\t\t\t\t  pj_ssize_t *len,\n\t\t\t\t  unsigned flags);\n\n/**\n * Transmit data to the socket to the specified address.\n *\n * @param sockfd\tSocket descriptor.\n * @param buf\t\tBuffer containing data to be sent.\n * @param len\t\tOn input, the length of the data in the buffer.\n *\t\t\tUpon return, it will be filled with the length\n *\t\t\tof data sent.\n * @param flags\t\tFlags (such as pj_MSG_DONTROUTE()).\n * @param to\t\tThe address to send.\n * @param tolen\t\tThe length of the address in bytes.\n *\n * @return\t\tPJ_SUCCESS or the status code.\n */\nPJ_DECL(pj_status_t) pj_sock_sendto(pj_sock_t sockfd,\n\t\t\t\t    const void *buf,\n\t\t\t\t    pj_ssize_t *len,\n\t\t\t\t    unsigned flags,\n\t\t\t\t    const pj_sockaddr_t *to,\n\t\t\t\t    int tolen);\n\n#if PJ_HAS_TCP\n/**\n * The shutdown call causes all or part of a full-duplex connection on the\n * socket associated with sockfd to be shut down.\n *\n * @param sockfd\tThe socket descriptor.\n * @param how\t\tIf how is PJ_SHUT_RD, further receptions will be \n *\t\t\tdisallowed. If how is PJ_SHUT_WR, further transmissions\n *\t\t\twill be disallowed. If how is PJ_SHUT_RDWR, further \n *\t\t\treceptions andtransmissions will be disallowed.\n *\n * @return\t\tZero on success.\n */\nPJ_DECL(pj_status_t) pj_sock_shutdown( pj_sock_t sockfd,\n\t\t\t\t       int how);\n#endif\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n#endif\t/* __PJ_SOCK_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/sock_qos.h",
    "content": "/* $Id: sock_qos.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_SOCK_QOS_H__\n#define __PJ_SOCK_QOS_H__\n\n/**\n * @file sock_qos.h\n * @brief Socket QoS API\n */\n\n#include <pj/sock.h>\n\nPJ_BEGIN_DECL \n\n\n/**\n * @defgroup socket_qos Socket Quality of Service (QoS) API: TOS, DSCP, WMM, IEEE 802.1p\n * @ingroup PJ_SOCK\n * @{\n\n\n    \\section intro QoS Technologies\n\n    QoS settings are available for both Layer 2 and 3 of TCP/IP protocols:\n\n    \\subsection intro_ieee8021p Layer 2: IEEE 802.1p for Ethernet\n\n    IEEE 802.1p tagging will mark frames sent by a host for prioritized \n    delivery using a 3-bit Priority field in the virtual local area network \n    (VLAN) header of the Ethernet frame. The VLAN header is placed inside \n    the Ethernet header, between the Source Address field and either the \n    Length field (for an IEEE 802.3 frame) or the EtherType field (for an\n    Ethernet II frame).\n\n    \\subsection intro_wmm Layer 2: WMM\n\n    At the Network Interface layer for IEEE 802.11 wireless, the Wi-Fi \n    Alliance certification for Wi-Fi Multimedia (WMM) defines four access \n    categories for prioritizing network traffic. These access categories \n    are (in order of highest to lowest priority) voice, video, best-effort, \n    and background. Host support for WMM prioritization requires that both \n    wireless network adapters and their drivers support WMM. Wireless \n    access points (APs) must have WMM enabled.\n\n    \\subsection intro_dscp Layer 3: DSCP\n\n    At the Internet layer, you can use Differentiated Services/Diffserv and\n    set the value of the Differentiated Services Code Point (DSCP) in the \n    IP header. As defined in RFC 2474, the DSCP value is the high-order 6 bits\n    of the IP version 4 (IPv4) TOS field and the IP version 6 (IPv6) Traffic \n    Class field.\n\n    \\subsection intro_other Layer 3: Other\n\n    Other mechanisms exist (such as RSVP, IntServ) but this will not be \n    implemented.\n\n\n    \\section availability QoS Availability\n\n    \\subsection linux Linux\n\n    DSCP is available via IP TOS option.\n\n    Ethernet 802.1p tagging is done by setting setsockopt(SO_PRIORITY) option \n    of the socket, then with the set_egress_map option of the vconfig utility \n    to convert this to set vlan-qos field of the packet.\n\n    WMM is not known to be available.\n\n    \\subsection windows Windows and Windows Mobile\n\n    (It's a mess!)\n\n    DSCP is settable with setsockopt() on Windows 2000 or older, but Windows \n    would silently ignore this call on WinXP or later, unless administrator \n    modifies the registry. On Windows 2000, Windows XP, and Windows Server \n    2003, GQoS (Generic QoS) API is the standard API, but this API may not be\n    supported in the future. On Vista and Windows 7, the is a new QoS2 API, \n    also known as Quality Windows Audio-Video Experience (qWAVE).\n\n    IEEE 802.1p tagging is available via Traffic Control (TC) API, available\n    on Windows XP SP2, but this needs administrator access. For Vista and \n    later, it's in qWAVE.\n\n    WMM is available for mobile platforms on Windows Mobile 6 platform and \n    Windows Embedded CE 6, via setsockopt(IP_DSCP_TRAFFIC_TYPE). qWAVE \n    supports this as well.\n\n    \\subsection symbian Symbian S60 3rd Ed\n\n    Both DSCP and WMM is supported via RSocket::SetOpt() with will set both \n    Layer 2 and Layer 3 QoS settings accordingly. Internally, PJLIB sets the\n    DSCP field of the socket, and based on certain DSCP values mapping,\n    Symbian will set the WMM tag accordingly.\n\n    \\section api PJLIB's QoS API Abstraction\n\n    Based on the above, the following API is implemented.\n\n    Declare the following \"standard\" traffic types.\n\n    \\code\n     typedef enum pj_qos_type\n     {\n\tPJ_QOS_TYPE_BEST_EFFORT,\n\tPJ_QOS_TYPE_BACKGROUND,\n\tPJ_QOS_TYPE_VIDEO,\n\tPJ_QOS_TYPE_VOICE,\n\tPJ_QOS_TYPE_CONTROL\n     } pj_qos_type;\n    \\endcode\n\n    The traffic classes above will determine how the Layer 2 and 3 QoS \n    settings will be used. The standard mapping between the classes above \n    to the corresponding Layer 2 and 3 settings are as follows:\n\n    \\code\n    =================================================================\n    PJLIB Traffic Type \tIP DSCP \tWMM \t\t    802.1p\n    -----------------------------------------------------------------\n    BEST_EFFORT \t0x00 \t\tBE (Bulk Effort) \t0\n    BACKGROUND \t\t0x08 \t\tBK (Bulk) \t\t2\n    VIDEO \t\t0x28 \t\tVI (Video) \t\t5\n    VOICE \t\t0x30 \t\tVO (Voice) \t\t6\n    CONTROL \t\t0x38 \t\tVO (Voice) \t\t7\n    =================================================================\n    \\endcode\n\n    There are two sets of API provided to manipulate the QoS parameters.\n\n    \\subsection portable_api Portable API\n\n    The first set of API is:\n\n    \\code\n     // Set QoS parameters\n     PJ_DECL(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,\n\t\t\t\t\t       pj_qos_type val);\n\n     // Get QoS parameters\n     PJ_DECL(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,\n\t\t\t\t\t       pj_qos_type *p_val);\n    \\endcode\n\n    The API will set the traffic type according to the DSCP class, for both \n    Layer 2 and Layer 3 QoS settings, where it's available. If any of the \n    layer QoS setting is not settable, the API will silently ignore it. \n    If both layers are not setable, the API will return error.\n\n    The API above is the recommended use of QoS, since it is the most \n    portable across all platforms.\n\n    \\subsection detail_api Fine Grained Control API\n\n    The second set of API is intended for application that wants to fine \n    tune the QoS parameters.\n\n    The Layer 2 and 3 QoS parameters are stored in pj_qos_params structure:\n\n    \\code\n     typedef enum pj_qos_flag\n     {\n\tPJ_QOS_PARAM_HAS_DSCP = 1,\n\tPJ_QOS_PARAM_HAS_SO_PRIO = 2,\n\tPJ_QOS_PARAM_HAS_WMM = 4\n     } pj_qos_flag;\n\n     typedef enum pj_qos_wmm_prio\n     {\n\tPJ_QOS_WMM_PRIO_BULK_EFFORT,\n\tPJ_QOS_WMM_PRIO_BULK,\n\tPJ_QOS_WMM_PRIO_VIDEO,\n\tPJ_QOS_WMM_PRIO_VOICE\n     } pj_qos_wmm_prio;\n\n     typedef struct pj_qos_params\n     {\n\tpj_uint8_t      flags;    // Determines which values to \n\t\t\t\t  // set, bitmask of pj_qos_flag\n\tpj_uint8_t      dscp_val; // The 6 bits DSCP value to set\n\tpj_uint8_t      so_prio;  // SO_PRIORITY value\n\tpj_qos_wmm_prio wmm_prio; // WMM priority value\n     } pj_qos_params;\n    \\endcode\n\n    The second set of API with more fine-grained control over the parameters \n    are:\n\n    \\code\n     // Retrieve QoS params for the specified traffic type\n     PJ_DECL(pj_status_t) pj_qos_get_params(pj_qos_type type, \n\t\t\t\t\t    pj_qos_params *p);\n\n     // Set QoS parameters to the socket\n     PJ_DECL(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,\n\t\t\t\t\t\t const pj_qos_params *p);\n\n     // Get QoS parameters from the socket\n     PJ_DECL(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,\n\t\t\t\t\t\t pj_qos_params *p);\n    \\endcode\n\n\n    Important:\n\n    The pj_sock_set/get_qos_params() APIs are not portable, and it's probably \n    only going to be implemented on Linux. Application should always try to \n    use pj_sock_set_qos_type() instead.\n */\n\n\n/**\n * High level traffic classification.\n */\ntypedef enum pj_qos_type\n{\n    PJ_QOS_TYPE_BEST_EFFORT,\t/**< Best effort traffic (default value).\n\t\t\t\t     Any QoS function calls with specifying\n\t\t\t\t     this value are effectively no-op\t*/\n    PJ_QOS_TYPE_BACKGROUND,\t/**< Background traffic.\t\t*/\n    PJ_QOS_TYPE_VIDEO,\t\t/**< Video traffic.\t\t\t*/\n    PJ_QOS_TYPE_VOICE,\t\t/**< Voice traffic.\t\t\t*/\n    PJ_QOS_TYPE_CONTROL\t\t/**< Control traffic.\t\t\t*/\n} pj_qos_type;\n\n/**\n * Bitmask flag to indicate which QoS layer setting is set in the \n * \\a flags field of the #pj_qos_params structure. \n */\ntypedef enum pj_qos_flag\n{\n    PJ_QOS_PARAM_HAS_DSCP = 1,\t    /**< DSCP field is set.\t    */\n    PJ_QOS_PARAM_HAS_SO_PRIO = 2,   /**< Socket SO_PRIORITY\t    */\n    PJ_QOS_PARAM_HAS_WMM = 4\t    /**< WMM  field is set. \t    */\n} pj_qos_flag;\n\n\n/**\n * Standard WMM priorities.\n */\ntypedef enum pj_qos_wmm_prio\n{\n    PJ_QOS_WMM_PRIO_BULK_EFFORT,\t/**< Bulk effort priority   */\n    PJ_QOS_WMM_PRIO_BULK,\t\t/**< Bulk priority.\t    */\n    PJ_QOS_WMM_PRIO_VIDEO,\t\t/**< Video priority\t    */\n    PJ_QOS_WMM_PRIO_VOICE\t\t/**< Voice priority\t    */\n} pj_qos_wmm_prio;\n\n\n/**\n * QoS parameters to be set or retrieved to/from the socket.\n */\ntypedef struct pj_qos_params\n{\n    pj_uint8_t      flags;    /**< Determines which values to \n\t\t\t\t   set, bitmask of pj_qos_flag\t    */\n    pj_uint8_t      dscp_val; /**< The 6 bits DSCP value to set\t    */\n    pj_uint8_t      so_prio;  /**< SO_PRIORITY value\t\t    */\n    pj_qos_wmm_prio wmm_prio; /**< WMM priority value\t\t    */\n} pj_qos_params;\n\n\n\n/**\n * This is the high level and portable API to enable QoS on the specified \n * socket, by setting the traffic type to the specified parameter.\n *\n * @param sock\t    The socket.\n * @param type\t    Traffic type to be set.\n *\n * @return\t    PJ_SUCCESS if at least Layer 2 or Layer 3 setting is\n *\t\t    successfully set. If both Layer 2 and Layer 3 settings\n *\t\t    can't be set, this function will return error.\n */\nPJ_DECL(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,\n\t\t\t\t\t  pj_qos_type type);\n\n/**\n * This is the high level and portable API to get the traffic type that has\n * been set on the socket. On occasions where the Layer 2 or Layer 3 settings\n * were modified by using low level API, this function may return approximation\n * of the closest QoS type that matches the settings.\n *\n * @param sock\t    The socket.\n * @param p_type    Pointer to receive the traffic type of the socket.\n *\n * @return\t    PJ_SUCCESS if traffic type for the socket can be obtained\n *\t\t    or approximated..\n */\nPJ_DECL(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,\n\t\t\t\t\t  pj_qos_type *p_type);\n\n\n/**\n * This is a convenience function to apply QoS to the socket, and print error\n * logging if the operations failed. Both QoS traffic type and the low level\n * QoS parameters can be applied with this function.\n *\n * @param sock\t\tThe socket handle.\n * @param qos_type\tQoS traffic type. The QoS traffic type will be applied\n *\t\t\tonly if the value is not PJ_QOS_TYPE_BEST_EFFORT,\n * @param qos_params\tOptional low-level QoS parameters. This will be \n *\t\t\tapplied only if this argument is not NULL and the \n *\t\t\tflags inside the structure is non-zero. Upon return, \n *\t\t\tthe flags will indicate which parameters have been \n *\t\t\tapplied successfully.\n * @param log_level\tThis function will print to log at this level upon\n *\t\t\tencountering errors.\n * @param log_sender\tOptional sender name in the log.\n * @param sock_name\tOptional name to help identify the socket in the log.\n *\n * @return\t\tPJ_SUCCESS if at least Layer 2 or Layer 3 setting is\n *\t\t\tsuccessfully set. If both Layer 2 and Layer 3 settings\n *\t\t\tcan't be set, this function will return error.\n *\n * @see pj_sock_apply_qos2()\n */\nPJ_DECL(pj_status_t) pj_sock_apply_qos(pj_sock_t sock,\n\t\t\t\t       pj_qos_type qos_type,\n\t\t\t\t       pj_qos_params *qos_params,\n\t\t\t\t       unsigned log_level,\n\t\t\t\t       const char *log_sender,\n\t\t\t\t       const char *sock_name);\n\n/**\n * Variant of #pj_sock_apply_qos() where the \\a qos_params parameter is\n * const.\n *\n * @see pj_sock_apply_qos()\n */\nPJ_DECL(pj_status_t) pj_sock_apply_qos2(pj_sock_t sock,\n \t\t\t\t        pj_qos_type qos_type,\n\t\t\t\t        const pj_qos_params *qos_params,\n\t\t\t\t        unsigned log_level,\n\t\t\t\t        const char *log_sender,\n\t\t\t\t        const char *sock_name);\n\n/**\n * Retrieve the standard mapping of QoS params for the specified traffic\n * type.\n *\n * @param type\t    The traffic type from which the QoS parameters\n *\t\t    are to be retrieved.\n * @param p_param   Pointer to receive the QoS parameters.\n *\n * @return\t    PJ_SUCCESS on success or the appropriate error code.\n */ \nPJ_DECL(pj_status_t) pj_qos_get_params(pj_qos_type type, \n\t\t\t\t       pj_qos_params *p_param);\n\n\n/**\n * Retrieve the traffic type that matches the specified QoS parameters.\n * If no exact matching is found, this function will return an\n * approximation of the closest matching traffic type for the specified\n * QoS parameters.\n *\n * @param param\t    Structure containing QoS parameters to map into\n *\t\t    \"standard\" traffic types.\n * @param p_type    Pointer to receive the traffic type.\n *\n * @return\t    PJ_SUCCESS on success or the appropriate error code.\n */ \nPJ_DECL(pj_status_t) pj_qos_get_type(const pj_qos_params *param,\n\t\t\t\t     pj_qos_type *p_type);\n\n\n/**\n * This is a low level API to set QoS parameters to the socket.\n *\n * @param sock\t    The socket.\n * @param param\t    Structure containing QoS parameters to be applied\n *\t\t    to the socket. Upon return, the \\a flags field\n *\t\t    of this structure will be set with bitmask value\n *\t\t    indicating which QoS settings have successfully\n *\t\t    been applied to the socket.\n *\n * @return\t    PJ_SUCCESS if at least one field setting has been\n *\t\t    successfully set. If no setting can't be set, \n *\t\t    this function will return error.\n */ \nPJ_DECL(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,\n\t\t\t\t\t    pj_qos_params *param);\n\n/**\n * This is a low level API to get QoS parameters from the socket.\n *\n * @param sock\t    The socket.\n * @param p_param   Pointer to receive the parameters. Upon returning\n *\t\t    successfully, the \\a flags field of this structure\n *\t\t    will be initialized with the appropriate bitmask\n *\t\t    to indicate which fields have been successfully\n *\t\t    retrieved.\n *\n * @return\t    PJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,\n\t\t\t\t\t    pj_qos_params *p_param);\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n#endif\t/* __PJ_SOCK_QOS_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/sock_select.h",
    "content": "/* $Id: sock_select.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_SELECT_H__\n#define __PJ_SELECT_H__\n\n/**\n * @file sock_select.h\n * @brief Socket select().\n */\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL \n\n/**\n * @defgroup PJ_SOCK_SELECT Socket select() API.\n * @ingroup PJ_IO\n * @{\n * This module provides portable abstraction for \\a select() like API.\n * The abstraction is needed so that it can utilize various event\n * dispatching mechanisms that are available across platforms.\n *\n * The API is very similar to normal \\a select() usage. \n *\n * \\section pj_sock_select_examples_sec Examples\n *\n * For some examples on how to use the select API, please see:\n *\n *  - \\ref page_pjlib_select_test\n */\n\n/**\n * Portable structure declarations for pj_fd_set.\n * The implementation of pj_sock_select() does not use this structure \n * per-se, but instead it will use the native fd_set structure. However,\n * we must make sure that the size of pj_fd_set_t can accomodate the\n * native fd_set structure.\n */\ntypedef struct pj_fd_set_t\n{\n    pj_sock_t data[PJ_IOQUEUE_MAX_HANDLES+ 4]; /**< Opaque buffer for fd_set */\n} pj_fd_set_t;\n\n\n/**\n * Initialize the descriptor set pointed to by fdsetp to the null set.\n *\n * @param fdsetp    The descriptor set.\n */\nPJ_DECL(void) PJ_FD_ZERO(pj_fd_set_t *fdsetp);\n\n\n/**\n * This is an internal function, application shouldn't use this.\n * \n * Get the number of descriptors in the set. This is defined in sock_select.c\n * This function will only return the number of sockets set from PJ_FD_SET\n * operation. When the set is modified by other means (such as by select()),\n * the count will not be reflected here.\n *\n * @param fdsetp    The descriptor set.\n *\n * @return          Number of descriptors in the set.\n */\nPJ_DECL(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp);\n\n\n/**\n * Add the file descriptor fd to the set pointed to by fdsetp. \n * If the file descriptor fd is already in this set, there shall be no effect\n * on the set, nor will an error be returned.\n *\n * @param fd\t    The socket descriptor.\n * @param fdsetp    The descriptor set.\n */\nPJ_DECL(void) PJ_FD_SET(pj_sock_t fd, pj_fd_set_t *fdsetp);\n\n/**\n * Remove the file descriptor fd from the set pointed to by fdsetp. \n * If fd is not a member of this set, there shall be no effect on the set, \n * nor will an error be returned.\n *\n * @param fd\t    The socket descriptor.\n * @param fdsetp    The descriptor set.\n */\nPJ_DECL(void) PJ_FD_CLR(pj_sock_t fd, pj_fd_set_t *fdsetp);\n\n\n/**\n * Evaluate to non-zero if the file descriptor fd is a member of the set \n * pointed to by fdsetp, and shall evaluate to zero otherwise.\n *\n * @param fd\t    The socket descriptor.\n * @param fdsetp    The descriptor set.\n *\n * @return\t    Nonzero if fd is member of the descriptor set.\n */\nPJ_DECL(pj_bool_t) PJ_FD_ISSET(pj_sock_t fd, const pj_fd_set_t *fdsetp);\n\n\n/**\n * This function wait for a number of file  descriptors to change status.\n * The behaviour is the same as select() function call which appear in\n * standard BSD socket libraries.\n *\n * @param n\t    On Unices, this specifies the highest-numbered\n *\t\t    descriptor in any of the three set, plus 1. On Windows,\n *\t\t    the value is ignored.\n * @param readfds   Optional pointer to a set of sockets to be checked for \n *\t\t    readability.\n * @param writefds  Optional pointer to a set of sockets to be checked for \n *\t\t    writability.\n * @param exceptfds Optional pointer to a set of sockets to be checked for \n *\t\t    errors.\n * @param timeout   Maximum time for select to wait, or null for blocking \n *\t\t    operations.\n *\n * @return\t    The total number of socket handles that are ready, or\n *\t\t    zero if the time limit expired, or -1 if an error occurred.\n */\nPJ_DECL(int) pj_sock_select( int n, \n\t\t\t     pj_fd_set_t *readfds, \n\t\t\t     pj_fd_set_t *writefds,\n\t\t\t     pj_fd_set_t *exceptfds, \n\t\t\t     const pj_time_val *timeout);\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n#endif\t/* __PJ_SELECT_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/ssl_sock.h",
    "content": "/* $Id: ssl_sock.h 4506 2013-04-26 06:01:43Z bennylp $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_SSL_SOCK_H__\n#define __PJ_SSL_SOCK_H__\n\n/**\n * @file ssl_sock.h\n * @brief Secure socket\n */\n\n#include <pj/ioqueue.h>\n#include <pj/sock.h>\n#include <pj/sock_qos.h>\n\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_SSL_SOCK Secure socket I/O\n * @brief Secure socket provides security on socket operation using standard\n * security protocols such as SSL and TLS.\n * @ingroup PJ_IO\n * @{\n *\n * Secure socket wraps normal socket and applies security features, i.e: \n * privacy and data integrity, on the socket traffic, using standard security\n * protocols such as SSL and TLS.\n *\n * Secure socket employs active socket operations, which is similar to (and\n * described more detail) in \\ref PJ_ACTIVESOCK.\n */\n\n\n /**\n * This opaque structure describes the secure socket.\n */\ntypedef struct pj_ssl_sock_t pj_ssl_sock_t;\n\n\n/**\n * Opaque declaration of endpoint certificate or credentials. This may contains\n * certificate, private key, and trusted Certificate Authorities list.\n */\ntypedef struct pj_ssl_cert_t pj_ssl_cert_t;\n\n\ntypedef enum pj_ssl_cert_verify_flag_t\n{\n    /**\n     * No error in verification.\n     */\n    PJ_SSL_CERT_ESUCCESS\t\t\t\t= 0,\n\n    /**\n     * The issuer certificate cannot be found.\n     */\n    PJ_SSL_CERT_EISSUER_NOT_FOUND\t\t\t= (1 << 0),\n\n    /**\n     * The certificate is untrusted.\n     */\n    PJ_SSL_CERT_EUNTRUSTED\t\t\t\t= (1 << 1),\n\n    /**\n     * The certificate has expired or not yet valid.\n     */\n    PJ_SSL_CERT_EVALIDITY_PERIOD\t\t\t= (1 << 2),\n\n    /**\n     * One or more fields of the certificate cannot be decoded due to\n     * invalid format.\n     */\n    PJ_SSL_CERT_EINVALID_FORMAT\t\t\t\t= (1 << 3),\n\n    /**\n     * The certificate cannot be used for the specified purpose.\n     */\n    PJ_SSL_CERT_EINVALID_PURPOSE\t\t\t= (1 << 4),\n\n    /**\n     * The issuer info in the certificate does not match to the (candidate) \n     * issuer certificate, e.g: issuer name not match to subject name\n     * of (candidate) issuer certificate.\n     */\n    PJ_SSL_CERT_EISSUER_MISMATCH\t\t\t= (1 << 5),\n\n    /**\n     * The CRL certificate cannot be found or cannot be read properly.\n     */\n    PJ_SSL_CERT_ECRL_FAILURE\t\t\t\t= (1 << 6),\n\n    /**\n     * The certificate has been revoked.\n     */\n    PJ_SSL_CERT_EREVOKED\t\t\t\t= (1 << 7),\n\n    /**\n     * The certificate chain length is too long.\n     */\n    PJ_SSL_CERT_ECHAIN_TOO_LONG\t\t\t\t= (1 << 8),\n\n    /**\n     * The server identity does not match to any identities specified in \n     * the certificate, e.g: subjectAltName extension, subject common name.\n     * This flag will only be set by application as SSL socket does not \n     * perform server identity verification.\n     */\n    PJ_SSL_CERT_EIDENTITY_NOT_MATCH\t\t\t= (1 << 30),\n\n    /**\n     * Unknown verification error.\n     */\n    PJ_SSL_CERT_EUNKNOWN\t\t\t\t= (1 << 31)\n\n} pj_ssl_cert_verify_flag_t;\n\n\ntypedef enum pj_ssl_cert_name_type\n{\n    PJ_SSL_CERT_NAME_UNKNOWN = 0,\n    PJ_SSL_CERT_NAME_RFC822,\n    PJ_SSL_CERT_NAME_DNS,\n    PJ_SSL_CERT_NAME_URI,\n    PJ_SSL_CERT_NAME_IP\n} pj_ssl_cert_name_type;\n\n/**\n * Describe structure of certificate info.\n */\ntypedef struct pj_ssl_cert_info {\n\n    unsigned\tversion;\t    /**< Certificate version\t*/\n\n    pj_uint8_t\tserial_no[20];\t    /**< Serial number, array of\n\t\t\t\t         octets, first index is\n\t\t\t\t\t MSB\t\t\t*/\n\n    struct {\n        pj_str_t\tcn;\t    /**< Common name\t\t*/\n        pj_str_t\tinfo;\t    /**< One line subject, fields\n\t\t\t\t\t are separated by slash, e.g:\n\t\t\t\t\t \"CN=sample.org/OU=HRD\" */\n    } subject;\t\t\t    /**< Subject\t\t*/\n\n    struct {\n        pj_str_t\tcn;\t    /**< Common name\t\t*/\n        pj_str_t\tinfo;\t    /**< One line subject, fields\n\t\t\t\t\t are separated by slash.*/\n    } issuer;\t\t\t    /**< Issuer\t\t\t*/\n\n    struct {\n\tpj_time_val\tstart;\t    /**< Validity start\t\t*/\n\tpj_time_val\tend;\t    /**< Validity end\t\t*/\n\tpj_bool_t\tgmt;\t    /**< Flag if validity date/time \n\t\t\t\t\t use GMT\t\t*/\n    } validity;\t\t\t    /**< Validity\t\t*/\n\n    struct {\n\tunsigned\tcnt;\t    /**< # of entry\t\t*/\n\tstruct {\n\t    pj_ssl_cert_name_type type;\n\t\t\t\t    /**< Name type\t\t*/\n\t    pj_str_t\tname;\t    /**< The name\t\t*/\n\t} *entry;\t\t    /**< Subject alt name entry */\n    } subj_alt_name;\t\t    /**< Subject alternative\n\t\t\t\t\t name extension\t\t*/\n\n    pj_str_t raw;\t\t    /**< Raw certificate in PEM format, only\n\t\t\t\t\t available for remote certificate. */\n\n} pj_ssl_cert_info;\n\n\n/**\n * Create credential from files. TLS server application can provide multiple\n * certificates (RSA, ECC, and DSA) by supplying certificate name with \"_rsa\"\n * suffix, e.g: \"pjsip_rsa.pem\", the library will automatically check for\n * other certificates with \"_ecc\" and \"_dsa\" suffix.\n *\n * @param CA_file\tThe file of trusted CA list.\n * @param cert_file\tThe file of certificate.\n * @param privkey_file\tThe file of private key.\n * @param privkey_pass\tThe password of private key, if any.\n * @param p_cert\tPointer to credential instance to be created.\n *\n * @return\t\tPJ_SUCCESS when successful.\n */\nPJ_DECL(pj_status_t) pj_ssl_cert_load_from_files(pj_pool_t *pool,\n\t\t\t\t\t\t const pj_str_t *CA_file,\n\t\t\t\t\t\t const pj_str_t *cert_file,\n\t\t\t\t\t\t const pj_str_t *privkey_file,\n\t\t\t\t\t\t const pj_str_t *privkey_pass,\n\t\t\t\t\t\t pj_ssl_cert_t **p_cert);\n\n/**\n * Create credential from files. TLS server application can provide multiple\n * certificates (RSA, ECC, and DSA) by supplying certificate name with \"_rsa\"\n * suffix, e.g: \"pjsip_rsa.pem\", the library will automatically check for\n * other certificates with \"_ecc\" and \"_dsa\" suffix.\n *\n * This is the same as pj_ssl_cert_load_from_files() but also\n * accepts an additional param CA_path to load CA certificates from\n * a directory.\n *\n * @param CA_file\tThe file of trusted CA list.\n * @param CA_path\tThe path to a directory of trusted CA list.\n * @param cert_file\tThe file of certificate.\n * @param privkey_file\tThe file of private key.\n * @param privkey_pass\tThe password of private key, if any.\n * @param p_cert\tPointer to credential instance to be created.\n *\n * @return\t\tPJ_SUCCESS when successful.\n */\nPJ_DECL(pj_status_t) pj_ssl_cert_load_from_files2(\n\t\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\t\tconst pj_str_t *CA_file,\n\t\t\t\t\t\tconst pj_str_t *CA_path,\n\t\t\t\t\t\tconst pj_str_t *cert_file,\n\t\t\t\t\t\tconst pj_str_t *privkey_file,\n\t\t\t\t\t\tconst pj_str_t *privkey_pass,\n\t\t\t\t\t\tpj_ssl_cert_t **p_cert);\n\n\n/**\n * Dump SSL certificate info.\n *\n * @param ci\t\tThe certificate info.\n * @param indent\tString for left indentation.\n * @param buf\t\tThe buffer where certificate info will be printed on.\n * @param buf_size\tThe buffer size.\n *\n * @return\t\tThe length of the dump result, or -1 when buffer size\n *\t\t\tis not sufficient.\n */\nPJ_DECL(pj_ssize_t) pj_ssl_cert_info_dump(const pj_ssl_cert_info *ci,\n\t\t\t\t\t  const char *indent,\n\t\t\t\t\t  char *buf,\n\t\t\t\t\t  pj_size_t buf_size);\n\n\n/**\n * Get SSL certificate verification error messages from verification status.\n *\n * @param verify_status\tThe SSL certificate verification status.\n * @param error_strings\tArray of strings to receive the verification error \n *\t\t\tmessages.\n * @param count\t\tOn input it specifies maximum error messages should be\n *\t\t\tretrieved. On output it specifies the number of error\n *\t\t\tmessages retrieved.\n *\n * @return\t\tPJ_SUCCESS when successful.\n */\nPJ_DECL(pj_status_t) pj_ssl_cert_get_verify_status_strings(\n\t\t\t\t\t\t pj_uint32_t verify_status, \n\t\t\t\t\t\t const char *error_strings[],\n\t\t\t\t\t\t unsigned *count);\n\n\n/** \n * Cipher suites enumeration.\n */\ntypedef enum pj_ssl_cipher {\n\n    /* Unsupported cipher */\n    PJ_TLS_UNKNOWN_CIPHER                       = -1,\n\n    /* NULL */\n    PJ_TLS_NULL_WITH_NULL_NULL               \t= 0x00000000,\n\n    /* TLS/SSLv3 */\n    PJ_TLS_RSA_WITH_NULL_MD5                 \t= 0x00000001,\n    PJ_TLS_RSA_WITH_NULL_SHA                 \t= 0x00000002,\n    PJ_TLS_RSA_WITH_NULL_SHA256              \t= 0x0000003B,\n    PJ_TLS_RSA_WITH_RC4_128_MD5              \t= 0x00000004,\n    PJ_TLS_RSA_WITH_RC4_128_SHA              \t= 0x00000005,\n    PJ_TLS_RSA_WITH_3DES_EDE_CBC_SHA         \t= 0x0000000A,\n    PJ_TLS_RSA_WITH_AES_128_CBC_SHA          \t= 0x0000002F,\n    PJ_TLS_RSA_WITH_AES_256_CBC_SHA          \t= 0x00000035,\n    PJ_TLS_RSA_WITH_AES_128_CBC_SHA256       \t= 0x0000003C,\n    PJ_TLS_RSA_WITH_AES_256_CBC_SHA256       \t= 0x0000003D,\n    PJ_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA      \t= 0x0000000D,\n    PJ_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA      \t= 0x00000010,\n    PJ_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA     \t= 0x00000013,\n    PJ_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA     \t= 0x00000016,\n    PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA       \t= 0x00000030,\n    PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA       \t= 0x00000031,\n    PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA      \t= 0x00000032,\n    PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA      \t= 0x00000033,\n    PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA       \t= 0x00000036,\n    PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA       \t= 0x00000037,\n    PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA      \t= 0x00000038,\n    PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA      \t= 0x00000039,\n    PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA256    \t= 0x0000003E,\n    PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA256    \t= 0x0000003F,\n    PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256   \t= 0x00000040,\n    PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256   \t= 0x00000067,\n    PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA256    \t= 0x00000068,\n    PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA256    \t= 0x00000069,\n    PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256   \t= 0x0000006A,\n    PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256   \t= 0x0000006B,\n    PJ_TLS_DH_anon_WITH_RC4_128_MD5          \t= 0x00000018,\n    PJ_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA     \t= 0x0000001B,\n    PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA      \t= 0x00000034,\n    PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA      \t= 0x0000003A,\n    PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA256   \t= 0x0000006C,\n    PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA256   \t= 0x0000006D,\n\n    /* TLS (deprecated) */\n    PJ_TLS_RSA_EXPORT_WITH_RC4_40_MD5        \t= 0x00000003,\n    PJ_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5    \t= 0x00000006,\n    PJ_TLS_RSA_WITH_IDEA_CBC_SHA             \t= 0x00000007,\n    PJ_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA     \t= 0x00000008,\n    PJ_TLS_RSA_WITH_DES_CBC_SHA              \t= 0x00000009,\n    PJ_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA  \t= 0x0000000B,\n    PJ_TLS_DH_DSS_WITH_DES_CBC_SHA           \t= 0x0000000C,\n    PJ_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA  \t= 0x0000000E,\n    PJ_TLS_DH_RSA_WITH_DES_CBC_SHA           \t= 0x0000000F,\n    PJ_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA \t= 0x00000011,\n    PJ_TLS_DHE_DSS_WITH_DES_CBC_SHA          \t= 0x00000012,\n    PJ_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA \t= 0x00000014,\n    PJ_TLS_DHE_RSA_WITH_DES_CBC_SHA          \t= 0x00000015,\n    PJ_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5    \t= 0x00000017,\n    PJ_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA \t= 0x00000019,\n    PJ_TLS_DH_anon_WITH_DES_CBC_SHA          \t= 0x0000001A,\n\n    /* SSLv3 */\n    PJ_SSL_FORTEZZA_KEA_WITH_NULL_SHA        \t= 0x0000001C,\n    PJ_SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA\t= 0x0000001D,\n    PJ_SSL_FORTEZZA_KEA_WITH_RC4_128_SHA     \t= 0x0000001E,\n    \n    /* SSLv2 */\n    PJ_SSL_CK_RC4_128_WITH_MD5               \t= 0x00010080,\n    PJ_SSL_CK_RC4_128_EXPORT40_WITH_MD5      \t= 0x00020080,\n    PJ_SSL_CK_RC2_128_CBC_WITH_MD5           \t= 0x00030080,\n    PJ_SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5  \t= 0x00040080,\n    PJ_SSL_CK_IDEA_128_CBC_WITH_MD5          \t= 0x00050080,\n    PJ_SSL_CK_DES_64_CBC_WITH_MD5            \t= 0x00060040,\n    PJ_SSL_CK_DES_192_EDE3_CBC_WITH_MD5      \t= 0x000700C0\n\n} pj_ssl_cipher;\n\n\n/**\n * Get cipher list supported by SSL/TLS backend.\n *\n * @param ciphers\tThe ciphers buffer to receive cipher list.\n * @param cipher_num\tMaximum number of ciphers to be received.\n *\n * @return\t\tPJ_SUCCESS when successful.\n */\nPJ_DECL(pj_status_t) pj_ssl_cipher_get_availables(pj_ssl_cipher ciphers[],\n\t\t\t\t\t          unsigned *cipher_num);\n\n\n/**\n * Check if the specified cipher is supported by SSL/TLS backend.\n *\n * @param cipher\tThe cipher.\n *\n * @return\t\tPJ_TRUE when supported.\n */\nPJ_DECL(pj_bool_t) pj_ssl_cipher_is_supported(pj_ssl_cipher cipher);\n\n\n/**\n * Get cipher name string.\n *\n * @param cipher\tThe cipher.\n *\n * @return\t\tThe cipher name or NULL if cipher is not recognized/\n *\t\t\tsupported.\n */\nPJ_DECL(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher);\n\n\n/**\n * Get cipher ID from cipher name string. Note that on different backends\n * (e.g. OpenSSL or Symbian implementation), cipher names may not be\n * equivalent for the same cipher ID.\n *\n * @param cipher_name\tThe cipher name string.\n *\n * @return\t\tThe cipher ID or PJ_TLS_UNKNOWN_CIPHER if the cipher\n *\t\t\tname string is not recognized/supported.\n */\nPJ_DECL(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name);\n\n\n/**\n * This structure contains the callbacks to be called by the secure socket.\n */\ntypedef struct pj_ssl_sock_cb\n{\n    /**\n     * This callback is called when a data arrives as the result of\n     * pj_ssl_sock_start_read().\n     *\n     * @param ssock\tThe secure socket.\n     * @param data\tThe buffer containing the new data, if any. If \n     *\t\t\tthe status argument is non-PJ_SUCCESS, this \n     *\t\t\targument may be NULL.\n     * @param size\tThe length of data in the buffer.\n     * @param status\tThe status of the read operation. This may contain\n     *\t\t\tnon-PJ_SUCCESS for example when the TCP connection\n     *\t\t\thas been closed. In this case, the buffer may\n     *\t\t\tcontain left over data from previous callback which\n     *\t\t\tthe application may want to process.\n     * @param remainder\tIf application wishes to leave some data in the \n     *\t\t\tbuffer (common for TCP applications), it should \n     *\t\t\tmove the remainder data to the front part of the \n     *\t\t\tbuffer and set the remainder length here. The value\n     *\t\t\tof this parameter will be ignored for datagram\n     *\t\t\tsockets.\n     *\n     * @return\t\tPJ_TRUE if further read is desired, and PJ_FALSE \n     *\t\t\twhen application no longer wants to receive data.\n     *\t\t\tApplication may destroy the secure socket in the\n     *\t\t\tcallback and return PJ_FALSE here.\n     */\n    pj_bool_t (*on_data_read)(pj_ssl_sock_t *ssock,\n\t\t\t      void *data,\n\t\t\t      pj_size_t size,\n\t\t\t      pj_status_t status,\n\t\t\t      pj_size_t *remainder);\n    /**\n     * This callback is called when a packet arrives as the result of\n     * pj_ssl_sock_start_recvfrom().\n     *\n     * @param ssock\tThe secure socket.\n     * @param data\tThe buffer containing the packet, if any. If \n     *\t\t\tthe status argument is non-PJ_SUCCESS, this \n     *\t\t\targument will be set to NULL.\n     * @param size\tThe length of packet in the buffer. If \n     *\t\t\tthe status argument is non-PJ_SUCCESS, this \n     *\t\t\targument will be set to zero.\n     * @param src_addr\tSource address of the packet.\n     * @param addr_len\tLength of the source address.\n     * @param status\tThis contains\n     *\n     * @return\t\tPJ_TRUE if further read is desired, and PJ_FALSE \n     *\t\t\twhen application no longer wants to receive data.\n     *\t\t\tApplication may destroy the secure socket in the\n     *\t\t\tcallback and return PJ_FALSE here.\n     */\n    pj_bool_t (*on_data_recvfrom)(pj_ssl_sock_t *ssock,\n\t\t\t\t  void *data,\n\t\t\t\t  pj_size_t size,\n\t\t\t\t  const pj_sockaddr_t *src_addr,\n\t\t\t\t  int addr_len,\n\t\t\t\t  pj_status_t status);\n\n    /**\n     * This callback is called when data has been sent.\n     *\n     * @param ssock\tThe secure socket.\n     * @param send_key\tKey associated with the send operation.\n     * @param sent\tIf value is positive non-zero it indicates the\n     *\t\t\tnumber of data sent. When the value is negative,\n     *\t\t\tit contains the error code which can be retrieved\n     *\t\t\tby negating the value (i.e. status=-sent).\n     *\n     * @return\t\tApplication may destroy the secure socket in the\n     *\t\t\tcallback and return PJ_FALSE here.\n     */\n    pj_bool_t (*on_data_sent)(pj_ssl_sock_t *ssock,\n\t\t\t      pj_ioqueue_op_key_t *send_key,\n\t\t\t      pj_ssize_t sent);\n\n    /**\n     * This callback is called when new connection arrives as the result\n     * of pj_ssl_sock_start_accept().\n     *\n     * @param ssock\tThe secure socket.\n     * @param newsock\tThe new incoming secure socket.\n     * @param src_addr\tThe source address of the connection.\n     * @param addr_len\tLength of the source address.\n     *\n     * @return\t\tPJ_TRUE if further accept() is desired, and PJ_FALSE\n     *\t\t\twhen application no longer wants to accept incoming\n     *\t\t\tconnection. Application may destroy the secure socket\n     *\t\t\tin the callback and return PJ_FALSE here.\n     */\n    pj_bool_t (*on_accept_complete)(pj_ssl_sock_t *ssock,\n\t\t\t\t    pj_ssl_sock_t *newsock,\n\t\t\t\t    const pj_sockaddr_t *src_addr,\n\t\t\t\t    int src_addr_len);\n\n    /**\n     * This callback is called when pending connect operation has been\n     * completed.\n     *\n     * @param ssock\tThe secure socket.\n     * @param status\tThe connection result. If connection has been\n     *\t\t\tsuccessfully established, the status will contain\n     *\t\t\tPJ_SUCCESS.\n     *\n     * @return\t\tApplication may destroy the secure socket in the\n     *\t\t\tcallback and return PJ_FALSE here. \n     */\n    pj_bool_t (*on_connect_complete)(pj_ssl_sock_t *ssock,\n\t\t\t\t     pj_status_t status);\n\n} pj_ssl_sock_cb;\n\n\n/** \n * Enumeration of secure socket protocol types.\n * This can be combined using bitwise OR operation.\n */\ntypedef enum pj_ssl_sock_proto\n{\n    /**\n     * Default protocol of backend. \n     */   \n    PJ_SSL_SOCK_PROTO_DEFAULT = 0,\n\n    /** \n     * SSLv2.0 protocol.\t  \n     */\n    PJ_SSL_SOCK_PROTO_SSL2    = (1 << 0),\n\n    /** \n     * SSLv3.0 protocol.\t  \n     */\n    PJ_SSL_SOCK_PROTO_SSL3    = (1 << 1),\n\n    /**\n     * TLSv1.0 protocol.\t  \n     */\n    PJ_SSL_SOCK_PROTO_TLS1    = (1 << 2),\n\n    /** \n     * TLSv1.1 protocol.\n     */\n    PJ_SSL_SOCK_PROTO_TLS1_1  = (1 << 3),\n\n    /**\n     * TLSv1.2 protocol.\n     */\n    PJ_SSL_SOCK_PROTO_TLS1_2  = (1 << 4),\n\n    /** \n     * Certain backend implementation e.g:OpenSSL, has feature to enable all\n     * protocol. \n     */\n    PJ_SSL_SOCK_PROTO_SSL23   = (1 << 16) - 1,\n\n    /**\n     * DTLSv1.0 protocol.\t  \n     */\n    PJ_SSL_SOCK_PROTO_DTLS1   = (1 << 16),\n\n} pj_ssl_sock_proto;\n\n\n/**\n * Definition of secure socket info structure.\n */\ntypedef struct pj_ssl_sock_info \n{\n    /**\n     * Describes whether secure socket connection is established, i.e: TLS/SSL \n     * handshaking has been done successfully.\n     */\n    pj_bool_t established;\n\n    /**\n     * Describes secure socket protocol being used, see #pj_ssl_sock_proto. \n     * Use bitwise OR operation to combine the protocol type.\n     */\n    pj_uint32_t proto;\n\n    /**\n     * Describes cipher suite being used, this will only be set when connection\n     * is established.\n     */\n    pj_ssl_cipher cipher;\n\n    /**\n     * Describes local address.\n     */\n    pj_sockaddr local_addr;\n\n    /**\n     * Describes remote address.\n     */\n    pj_sockaddr remote_addr;\n   \n    /**\n     * Describes active local certificate info.\n     */\n    pj_ssl_cert_info *local_cert_info;\n   \n    /**\n     * Describes active remote certificate info.\n     */\n    pj_ssl_cert_info *remote_cert_info;\n\n    /**\n     * Status of peer certificate verification.\n     */\n    pj_uint32_t\t\tverify_status;\n\n    /**\n     * Last native error returned by the backend.\n     */\n    unsigned long\tlast_native_err;\n\n    /**\n     * Group lock assigned to the ioqueue key.\n     */\n    pj_grp_lock_t *grp_lock;\n\n} pj_ssl_sock_info;\n\n\n/**\n * Definition of secure socket creation parameters.\n */\ntypedef struct pj_ssl_sock_param\n{\n    /**\n     * Optional group lock to be assigned to the ioqueue key.\n     *\n     * Note that when a secure socket listener is configured with a group\n     * lock, any new secure socket of an accepted incoming connection\n     * will have its own group lock created automatically by the library,\n     * this group lock can be queried via pj_ssl_sock_get_info() in the info\n     * field pj_ssl_sock_info::grp_lock.\n     */\n    pj_grp_lock_t *grp_lock;\n\n    /**\n     * Specifies socket address family, either pj_AF_INET() and pj_AF_INET6().\n     *\n     * Default is pj_AF_INET().\n     */\n    int sock_af;\n\n    /**\n     * Specify socket type, either pj_SOCK_DGRAM() or pj_SOCK_STREAM().\n     *\n     * Default is pj_SOCK_STREAM().\n     */\n    int sock_type;\n\n    /**\n     * Specify the ioqueue to use. Secure socket uses the ioqueue to perform\n     * active socket operations, see \\ref PJ_ACTIVESOCK for more detail.\n     */\n    pj_ioqueue_t *ioqueue;\n\n    /**\n     * Specify the timer heap to use. Secure socket uses the timer to provide\n     * auto cancelation on asynchronous operation when it takes longer time \n     * than specified timeout period, e.g: security negotiation timeout.\n     */\n    pj_timer_heap_t *timer_heap;\n\n    /**\n     * Specify secure socket callbacks, see #pj_ssl_sock_cb.\n     */\n    pj_ssl_sock_cb cb;\n\n    /**\n     * Specify secure socket user data.\n     */\n    void *user_data;\n\n    /**\n     * Specify security protocol to use, see #pj_ssl_sock_proto. Use bitwise OR \n     * operation to combine the protocol type.\n     *\n     * Default is PJ_SSL_SOCK_PROTO_DEFAULT.\n     */\n    pj_uint32_t proto;\n\n    /**\n     * Number of concurrent asynchronous operations that is to be supported\n     * by the secure socket. This value only affects socket receive and\n     * accept operations -- the secure socket will issue one or more \n     * asynchronous read and accept operations based on the value of this\n     * field. Setting this field to more than one will allow more than one\n     * incoming data or incoming connections to be processed simultaneously\n     * on multiprocessor systems, when the ioqueue is polled by more than\n     * one threads.\n     *\n     * The default value is 1.\n     */\n    unsigned async_cnt;\n\n    /**\n     * The ioqueue concurrency to be forced on the socket when it is \n     * registered to the ioqueue. See #pj_ioqueue_set_concurrency() for more\n     * info about ioqueue concurrency.\n     *\n     * When this value is -1, the concurrency setting will not be forced for\n     * this socket, and the socket will inherit the concurrency setting of \n     * the ioqueue. When this value is zero, the secure socket will disable\n     * concurrency for the socket. When this value is +1, the secure socket\n     * will enable concurrency for the socket.\n     *\n     * The default value is -1.\n     */\n    int concurrency;\n\n    /**\n     * If this option is specified, the secure socket will make sure that\n     * asynchronous send operation with stream oriented socket will only\n     * call the callback after all data has been sent. This means that the\n     * secure socket will automatically resend the remaining data until\n     * all data has been sent.\n     *\n     * Please note that when this option is specified, it is possible that\n     * error is reported after partial data has been sent. Also setting\n     * this will disable the ioqueue concurrency for the socket.\n     *\n     * Default value is 1.\n     */\n    pj_bool_t whole_data;\n\n    /**\n     * Specify buffer size for sending operation. Buffering sending data\n     * is used for allowing application to perform multiple outstanding \n     * send operations. Whenever application specifies this setting too\n     * small, sending operation may return PJ_ENOMEM.\n     *  \n     * Default value is 8192 bytes.\n     */\n    pj_size_t send_buffer_size;\n\n    /**\n     * Specify buffer size for receiving encrypted (and perhaps compressed)\n     * data on underlying socket. This setting is unused on Symbian, since \n     * SSL/TLS Symbian backend, CSecureSocket, can use application buffer \n     * directly.\n     *\n     * Default value is 1500.\n     */\n    pj_size_t read_buffer_size;\n\n    /**\n     * Number of ciphers contained in the specified cipher preference. \n     * If this is set to zero, then the cipher list used will be determined\n     * by the backend default (for OpenSSL backend, setting \n     * PJ_SSL_SOCK_OSSL_CIPHERS will be used).\n     */\n    unsigned ciphers_num;\n\n    /**\n     * Ciphers and order preference. If empty, then default cipher list and\n     * its default order of the backend will be used.\n     */\n    pj_ssl_cipher *ciphers;\n\n    /**\n     * Security negotiation timeout. If this is set to zero (both sec and \n     * msec), the negotiation doesn't have a timeout.\n     *\n     * Default value is zero.\n     */\n    pj_time_val\ttimeout;\n\n    /**\n     * Specify whether endpoint should verify peer certificate.\n     *\n     * Default value is PJ_FALSE.\n     */\n    pj_bool_t verify_peer;\n    \n    /**\n     * When secure socket is acting as server (handles incoming connection),\n     * it will require the client to provide certificate.\n     *\n     * Default value is PJ_FALSE.\n     */\n    pj_bool_t require_client_cert;\n\n    /**\n     * Server name indication. When secure socket is acting as client \n     * (perform outgoing connection) and the server may host multiple\n     * 'virtual' servers at a single underlying network address, setting\n     * this will allow client to tell the server a name of the server\n     * it is contacting.\n     *\n     * Default value is zero/not-set.\n     */\n    pj_str_t server_name;\n\n    /**\n     * Specify if SO_REUSEADDR should be used for listening socket. This\n     * option will only be used with accept() operation.\n     *\n     * Default is PJ_FALSE.\n     */\n    pj_bool_t reuse_addr;\n\n    /**\n     * QoS traffic type to be set on this transport. When application wants\n     * to apply QoS tagging to the transport, it's preferable to set this\n     * field rather than \\a qos_param fields since this is more portable.\n     *\n     * Default value is PJ_QOS_TYPE_BEST_EFFORT.\n     */\n    pj_qos_type qos_type;\n\n    /**\n     * Set the low level QoS parameters to the transport. This is a lower\n     * level operation than setting the \\a qos_type field and may not be\n     * supported on all platforms.\n     *\n     * By default all settings in this structure are disabled.\n     */\n    pj_qos_params qos_params;\n\n    /**\n     * Specify if the transport should ignore any errors when setting the QoS\n     * traffic type/parameters.\n     *\n     * Default: PJ_TRUE\n     */\n    pj_bool_t qos_ignore_error;\n\n    /**\n     * Specify options to be set on the transport. \n     *\n     * By default there is no options.\n     * \n     */\n    pj_sockopt_params sockopt_params;\n\n    /**\n     * Specify if the transport should ignore any errors when setting the \n     * sockopt parameters.\n     *\n     * Default: PJ_TRUE\n     * \n     */\n    pj_bool_t sockopt_ignore_error;\n\n} pj_ssl_sock_param;\n\n\n/**\n * Initialize the secure socket parameters for its creation with \n * the default values.\n *\n * @param param\t\tThe parameter to be initialized.\n */\nPJ_DECL(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param);\n\n\n/**\n * Duplicate pj_ssl_sock_param.\n *\n * @param pool\tPool to allocate memory.\n * @param dst\tDestination parameter.\n * @param src\tSource parameter.\n */\nPJ_DECL(void) pj_ssl_sock_param_copy(pj_pool_t *pool, \n\t\t\t\t     pj_ssl_sock_param *dst,\n\t\t\t\t     const pj_ssl_sock_param *src);\n\n\n/**\n * Create secure socket instance.\n *\n * @param pool\t\tThe pool for allocating secure socket instance.\n * @param param\t\tThe secure socket parameter, see #pj_ssl_sock_param.\n * @param p_ssock\tPointer to secure socket instance to be created.\n *\n * @return\t\tPJ_SUCCESS when successful.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_create(pj_pool_t *pool,\n\t\t\t\t\tconst pj_ssl_sock_param *param,\n\t\t\t\t\tpj_ssl_sock_t **p_ssock);\n\n\n/**\n * Set secure socket certificate or credentials. Credentials may include \n * certificate, private key and trusted Certification Authorities list. \n * Normally, server socket must provide certificate (and private key).\n * Socket client may also need to provide certificate in case requested\n * by the server.\n *\n * @param ssock\t\tThe secure socket instance.\n * @param pool\t\tThe pool.\n * @param cert\t\tThe endpoint certificate/credentials, see\n *\t\t\t#pj_ssl_cert_t.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_set_certificate(\n\t\t\t\t\t    pj_ssl_sock_t *ssock,\n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    const pj_ssl_cert_t *cert);\n\n\n/**\n * Close and destroy the secure socket.\n *\n * @param ssock\t\tThe secure socket.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock);\n\n\n/**\n * Associate arbitrary data with the secure socket. Application may\n * inspect this data in the callbacks and associate it with higher\n * level processing.\n *\n * @param ssock\t\tThe secure socket.\n * @param user_data\tThe user data to be associated with the secure\n *\t\t\tsocket.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_set_user_data(pj_ssl_sock_t *ssock,\n\t\t\t\t\t       void *user_data);\n\n/**\n * Retrieve the user data previously associated with this secure\n * socket.\n *\n * @param ssock\t\tThe secure socket.\n *\n * @return\t\tThe user data.\n */\nPJ_DECL(void*) pj_ssl_sock_get_user_data(pj_ssl_sock_t *ssock);\n\n\n/**\n * Retrieve the local address and port used by specified secure socket.\n *\n * @param ssock\t\tThe secure socket.\n * @param info\t\tThe info buffer to be set, see #pj_ssl_sock_info.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_get_info(pj_ssl_sock_t *ssock,\n\t\t\t\t\t  pj_ssl_sock_info *info);\n\n\n/**\n * Starts read operation on this secure socket. This function will create\n * \\a async_cnt number of buffers (the \\a async_cnt parameter was given\n * in \\a pj_ssl_sock_create() function) where each buffer is \\a buff_size\n * long. The buffers are allocated from the specified \\a pool. Once the \n * buffers are created, it then issues \\a async_cnt number of asynchronous\n * \\a recv() operations to the socket and returns back to caller. Incoming\n * data on the socket will be reported back to application via the \n * \\a on_data_read() callback.\n *\n * Application only needs to call this function once to initiate read\n * operations. Further read operations will be done automatically by the\n * secure socket when \\a on_data_read() callback returns non-zero. \n *\n * @param ssock\t\tThe secure socket.\n * @param pool\t\tPool used to allocate buffers for incoming data.\n * @param buff_size\tThe size of each buffer, in bytes.\n * @param flags\t\tFlags to be given to pj_ioqueue_recv().\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_start_read(pj_ssl_sock_t *ssock,\n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    unsigned buff_size,\n\t\t\t\t\t    pj_uint32_t flags);\n\n/**\n * Same as #pj_ssl_sock_start_read(), except that the application\n * supplies the buffers for the read operation so that the acive socket\n * does not have to allocate the buffers.\n *\n * @param ssock\t\tThe secure socket.\n * @param pool\t\tPool used to allocate buffers for incoming data.\n * @param buff_size\tThe size of each buffer, in bytes.\n * @param readbuf\tArray of packet buffers, each has buff_size size.\n * @param flags\t\tFlags to be given to pj_ioqueue_recv().\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_start_read2(pj_ssl_sock_t *ssock,\n\t\t\t\t\t     pj_pool_t *pool,\n\t\t\t\t\t     unsigned buff_size,\n\t\t\t\t\t     void *readbuf[],\n\t\t\t\t\t     pj_uint32_t flags);\n\n/**\n * Same as pj_ssl_sock_start_read(), except that this function is used\n * only for datagram sockets, and it will trigger \\a on_data_recvfrom()\n * callback instead.\n *\n * @param ssock\t\tThe secure socket.\n * @param pool\t\tPool used to allocate buffers for incoming data.\n * @param buff_size\tThe size of each buffer, in bytes.\n * @param flags\t\tFlags to be given to pj_ioqueue_recvfrom().\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_start_recvfrom(pj_ssl_sock_t *ssock,\n\t\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\t\tunsigned buff_size,\n\t\t\t\t\t\tpj_uint32_t flags);\n\n/**\n * Same as #pj_ssl_sock_start_recvfrom() except that the recvfrom() \n * operation takes the buffer from the argument rather than creating\n * new ones.\n *\n * @param ssock\t\tThe secure socket.\n * @param pool\t\tPool used to allocate buffers for incoming data.\n * @param buff_size\tThe size of each buffer, in bytes.\n * @param readbuf\tArray of packet buffers, each has buff_size size.\n * @param flags\t\tFlags to be given to pj_ioqueue_recvfrom().\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_start_recvfrom2(pj_ssl_sock_t *ssock,\n\t\t\t\t\t\t pj_pool_t *pool,\n\t\t\t\t\t\t unsigned buff_size,\n\t\t\t\t\t\t void *readbuf[],\n\t\t\t\t\t\t pj_uint32_t flags);\n\n/**\n * Send data using the socket.\n *\n * @param ssock\t\tThe secure socket.\n * @param send_key\tThe operation key to send the data, which is useful\n *\t\t\tif application wants to submit multiple pending\n *\t\t\tsend operations and want to track which exact data \n *\t\t\thas been sent in the \\a on_data_sent() callback.\n * @param data\t\tThe data to be sent. This data must remain valid\n *\t\t\tuntil the data has been sent.\n * @param size\t\tThe size of the data.\n * @param flags\t\tFlags to be given to pj_ioqueue_send().\n *\n * @return\t\tPJ_SUCCESS if data has been sent immediately, or\n *\t\t\tPJ_EPENDING if data cannot be sent immediately or\n *\t\t\tPJ_ENOMEM when sending buffer could not handle all\n *\t\t\tqueued data, see \\a send_buffer_size. The callback\n *\t\t\t\\a on_data_sent() will be called when data is actually\n *\t\t\tsent. Any other return value indicates error condition.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_send(pj_ssl_sock_t *ssock,\n\t\t\t\t      pj_ioqueue_op_key_t *send_key,\n\t\t\t\t      const void *data,\n\t\t\t\t      pj_ssize_t *size,\n\t\t\t\t      unsigned flags);\n\n/**\n * Send datagram using the socket.\n *\n * @param ssock\t\tThe secure socket.\n * @param send_key\tThe operation key to send the data, which is useful\n *\t\t\tif application wants to submit multiple pending\n *\t\t\tsend operations and want to track which exact data \n *\t\t\thas been sent in the \\a on_data_sent() callback.\n * @param data\t\tThe data to be sent. This data must remain valid\n *\t\t\tuntil the data has been sent.\n * @param size\t\tThe size of the data.\n * @param flags\t\tFlags to be given to pj_ioqueue_send().\n * @param addr\t\tThe destination address.\n * @param addr_len\tLength of buffer containing destination address.\n *\n * @return\t\tPJ_SUCCESS if data has been sent immediately, or\n *\t\t\tPJ_EPENDING if data cannot be sent immediately. In\n *\t\t\tthis case the \\a on_data_sent() callback will be\n *\t\t\tcalled when data is actually sent. Any other return\n *\t\t\tvalue indicates error condition.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_sendto(pj_ssl_sock_t *ssock,\n\t\t\t\t\tpj_ioqueue_op_key_t *send_key,\n\t\t\t\t\tconst void *data,\n\t\t\t\t\tpj_ssize_t *size,\n\t\t\t\t\tunsigned flags,\n\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\tint addr_len);\n\n\n/**\n * Starts asynchronous socket accept() operations on this secure socket. \n * This function will issue \\a async_cnt number of asynchronous \\a accept() \n * operations to the socket and returns back to caller. Incoming\n * connection on the socket will be reported back to application via the\n * \\a on_accept_complete() callback.\n *\n * Application only needs to call this function once to initiate accept()\n * operations. Further accept() operations will be done automatically by \n * the secure socket when \\a on_accept_complete() callback returns non-zero.\n *\n * @param ssock\t\tThe secure socket.\n * @param pool\t\tPool used to allocate some internal data for the\n *\t\t\toperation.\n * @param localaddr\tLocal address to bind on.\n * @param addr_len\tLength of buffer containing local address.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_start_accept(pj_ssl_sock_t *ssock,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      const pj_sockaddr_t *local_addr,\n\t\t\t\t\t      int addr_len);\n\n\n/**\n * Same as #pj_ssl_sock_start_accept(), but application can provide\n * a secure socket parameter, which will be used to create a new secure\n * socket reported in \\a on_accept_complete() callback when there is\n * an incoming connection.\n *\n * @param ssock\t\tThe secure socket.\n * @param pool\t\tPool used to allocate some internal data for the\n *\t\t\toperation.\n * @param localaddr\tLocal address to bind on.\n * @param addr_len\tLength of buffer containing local address.\n * @param newsock_param\tSecure socket parameter for new accepted sockets.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t)\npj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock,\n\t\t\t  pj_pool_t *pool,\n\t\t\t  const pj_sockaddr_t *local_addr,\n\t\t\t  int addr_len,\n\t\t\t  const pj_ssl_sock_param *newsock_param);\n\n\n/**\n * Starts asynchronous socket connect() operation and SSL/TLS handshaking \n * for this socket. Once the connection is done (either successfully or not),\n * the \\a on_connect_complete() callback will be called.\n *\n * @param ssock\t\tThe secure socket.\n * @param pool\t\tThe pool to allocate some internal data for the\n *\t\t\toperation.\n * @param localaddr\tLocal address.\n * @param remaddr\tRemote address.\n * @param addr_len\tLength of buffer containing above addresses.\n *\n * @return\t\tPJ_SUCCESS if connection can be established immediately\n *\t\t\tor PJ_EPENDING if connection cannot be established \n *\t\t\timmediately. In this case the \\a on_connect_complete()\n *\t\t\tcallback will be called when connection is complete. \n *\t\t\tAny other return value indicates error condition.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_start_connect(pj_ssl_sock_t *ssock,\n\t\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t\t       const pj_sockaddr_t *localaddr,\n\t\t\t\t\t       const pj_sockaddr_t *remaddr,\n\t\t\t\t\t       int addr_len);\n\n\n/**\n * Starts SSL/TLS renegotiation over an already established SSL connection\n * for this socket. This operation is performed transparently, no callback \n * will be called once the renegotiation completed successfully. However, \n * when the renegotiation fails, the connection will be closed and callback\n * \\a on_data_read() will be invoked with non-PJ_SUCCESS status code.\n *\n * @param ssock\t\tThe secure socket.\n *\n * @return\t\tPJ_SUCCESS if renegotiation is completed immediately,\n *\t\t\tor PJ_EPENDING if renegotiation has been started and\n *\t\t\twaiting for completion, or the appropriate error code \n *\t\t\ton failure.\n */\nPJ_DECL(pj_status_t) pj_ssl_sock_renegotiate(pj_ssl_sock_t *ssock);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJ_SSL_SOCK_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/string.h",
    "content": "/* $Id: string.h 4440 2013-03-14 07:18:13Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_STRING_H__\n#define __PJ_STRING_H__\n\n/**\n * @file string.h\n * @brief PJLIB String Operations.\n */\n\n#include <pj/types.h>\n#include <pj/compat/string.h>\n\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_PSTR String Operations\n * @ingroup PJ_DS\n * @{\n * This module provides string manipulation API.\n *\n * \\section pj_pstr_not_null_sec PJLIB String is NOT Null Terminated!\n *\n * That is the first information that developers need to know. Instead\n * of using normal C string, strings in PJLIB are represented as\n * pj_str_t structure below:\n *\n * <pre>\n *   typedef struct pj_str_t\n *   {\n *       char      *ptr;\n *       pj_size_t  slen;\n *   } pj_str_t;\n * </pre>\n *\n * There are some advantages of using this approach:\n *  - the string can point to arbitrary location in memory even\n *    if the string in that location is not null terminated. This is\n *    most usefull for text parsing, where the parsed text can just\n *    point to the original text in the input. If we use C string,\n *    then we will have to copy the text portion from the input\n *    to a string variable.\n *  - because the length of the string is known, string copy operation\n *    can be made more efficient.\n *\n * Most of APIs in PJLIB that expect or return string will represent\n * the string as pj_str_t instead of normal C string.\n *\n * \\section pj_pstr_examples_sec Examples\n *\n * For some examples, please see:\n *  - @ref page_pjlib_string_test\n */\n\n/**\n * Create string initializer from a normal C string.\n *\n * @param str\tNull terminated string to be stored.\n *\n * @return\tpj_str_t.\n */\nPJ_IDECL(pj_str_t) pj_str(char *str);\n\n/**\n * Create constant string from normal C string.\n *\n * @param str\tThe string to be initialized.\n * @param s\tNull terminated string.\n *\n * @return\tpj_str_t.\n */\nPJ_INLINE(const pj_str_t*) pj_cstr(pj_str_t *str, const char *s)\n{\n    str->ptr = (char*)s;\n    str->slen = s ? (pj_ssize_t)strlen(s) : 0;\n    return str;\n}\n\n/**\n * Set the pointer and length to the specified value.\n *\n * @param str\t    the string.\n * @param ptr\t    pointer to set.\n * @param length    length to set.\n *\n * @return the string.\n */\nPJ_INLINE(pj_str_t*) pj_strset( pj_str_t *str, char *ptr, pj_size_t length)\n{\n    str->ptr = ptr;\n    str->slen = (pj_ssize_t)length;\n    return str;\n}\n\n/**\n * Set the pointer and length of the string to the source string, which\n * must be NULL terminated.\n *\n * @param str\t    the string.\n * @param src\t    pointer to set.\n *\n * @return the string.\n */\nPJ_INLINE(pj_str_t*) pj_strset2( pj_str_t *str, char *src)\n{\n    str->ptr = src;\n    str->slen = src ? (pj_ssize_t)strlen(src) : 0;\n    return str;\n}\n\n/**\n * Set the pointer and the length of the string.\n *\n * @param str\t    The target string.\n * @param begin\t    The start of the string.\n * @param end\t    The end of the string.\n *\n * @return the target string.\n */\nPJ_INLINE(pj_str_t*) pj_strset3( pj_str_t *str, char *begin, char *end )\n{\n    str->ptr = begin;\n    str->slen = (pj_ssize_t)(end-begin);\n    return str;\n}\n\n/**\n * Assign string.\n *\n * @param dst\t    The target string.\n * @param src\t    The source string.\n *\n * @return the target string.\n */\nPJ_IDECL(pj_str_t*) pj_strassign( pj_str_t *dst, pj_str_t *src );\n\n/**\n * Copy string contents.\n *\n * @param dst\t    The target string.\n * @param src\t    The source string.\n *\n * @return the target string.\n */\nPJ_IDECL(pj_str_t*) pj_strcpy(pj_str_t *dst, const pj_str_t *src);\n\n/**\n * Copy string contents.\n *\n * @param dst\t    The target string.\n * @param src\t    The source string.\n *\n * @return the target string.\n */\nPJ_IDECL(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src);\n\n/**\n * Copy source string to destination up to the specified max length.\n *\n * @param dst\t    The target string.\n * @param src\t    The source string.\n * @param max\t    Maximum characters to copy.\n *\n * @return the target string.\n */\nPJ_IDECL(pj_str_t*) pj_strncpy(pj_str_t *dst, const pj_str_t *src, \n\t\t\t       pj_ssize_t max);\n\n/**\n * Copy source string to destination up to the specified max length,\n * and NULL terminate the destination. If source string length is\n * greater than or equal to max, then max-1 will be copied.\n *\n * @param dst\t    The target string.\n * @param src\t    The source string.\n * @param max\t    Maximum characters to copy.\n *\n * @return the target string.\n */\nPJ_IDECL(pj_str_t*) pj_strncpy_with_null(pj_str_t *dst, const pj_str_t *src,\n\t\t\t\t\t pj_ssize_t max);\n\n/**\n * Duplicate string.\n *\n * @param pool\t    The pool.\n * @param dst\t    The string result.\n * @param src\t    The string to duplicate.\n *\n * @return the string result.\n */\nPJ_IDECL(pj_str_t*) pj_strdup(pj_pool_t *pool,\n\t\t\t      pj_str_t *dst,\n\t\t\t      const pj_str_t *src);\n\n/**\n * Duplicate string and NULL terminate the destination string.\n *\n * @param pool\t    The pool.\n * @param dst\t    The string result.\n * @param src\t    The string to duplicate.\n *\n * @return\t    The string result.\n */\nPJ_IDECL(pj_str_t*) pj_strdup_with_null(pj_pool_t *pool,\n\t\t\t\t\tpj_str_t *dst,\n\t\t\t\t\tconst pj_str_t *src);\n\n/**\n * Duplicate string.\n *\n * @param pool\t    The pool.\n * @param dst\t    The string result.\n * @param src\t    The string to duplicate.\n *\n * @return the string result.\n */\nPJ_IDECL(pj_str_t*) pj_strdup2(pj_pool_t *pool,\n\t\t\t       pj_str_t *dst,\n\t\t\t       const char *src);\n\n/**\n * Duplicate string and NULL terminate the destination string.\n *\n * @param pool\t    The pool.\n * @param dst\t    The string result.\n * @param src\t    The string to duplicate.\n *\n * @return\t    The string result.\n */\nPJ_IDECL(pj_str_t*) pj_strdup2_with_null(pj_pool_t *pool,\n\t\t\t\t\t pj_str_t *dst,\n\t\t\t\t\t const char *src);\n\n\n/**\n * Duplicate string.\n *\n * @param pool\t    The pool.\n * @param src\t    The string to duplicate.\n *\n * @return the string result.\n */\nPJ_IDECL(pj_str_t) pj_strdup3(pj_pool_t *pool, const char *src);\n\n/**\n * Return the length of the string.\n *\n * @param str\t    The string.\n *\n * @return the length of the string.\n */\nPJ_INLINE(pj_size_t) pj_strlen( const pj_str_t *str )\n{\n    return str->slen;\n}\n\n/**\n * Return the pointer to the string data.\n *\n * @param str\t    The string.\n *\n * @return the pointer to the string buffer.\n */\nPJ_INLINE(const char*) pj_strbuf( const pj_str_t *str )\n{\n    return str->ptr;\n}\n\n/**\n * Compare strings. \n *\n * @param str1\t    The string to compare.\n * @param str2\t    The string to compare.\n *\n * @return \n *\t- < 0 if str1 is less than str2\n *      - 0   if str1 is identical to str2\n *      - > 0 if str1 is greater than str2\n */\nPJ_IDECL(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2);\n\n/**\n * Compare strings.\n *\n * @param str1\t    The string to compare.\n * @param str2\t    The string to compare.\n *\n * @return \n *\t- < 0 if str1 is less than str2\n *      - 0   if str1 is identical to str2\n *      - > 0 if str1 is greater than str2\n */\nPJ_IDECL(int) pj_strcmp2( const pj_str_t *str1, const char *str2 );\n\n/**\n * Compare strings. \n *\n * @param str1\t    The string to compare.\n * @param str2\t    The string to compare.\n * @param len\t    The maximum number of characters to compare.\n *\n * @return \n *\t- < 0 if str1 is less than str2\n *      - 0   if str1 is identical to str2\n *      - > 0 if str1 is greater than str2\n */\nPJ_IDECL(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2, \n\t\t\t  pj_size_t len);\n\n/**\n * Compare strings. \n *\n * @param str1\t    The string to compare.\n * @param str2\t    The string to compare.\n * @param len\t    The maximum number of characters to compare.\n *\n * @return \n *\t- < 0 if str1 is less than str2\n *      - 0   if str1 is identical to str2\n *      - > 0 if str1 is greater than str2\n */\nPJ_IDECL(int) pj_strncmp2( const pj_str_t *str1, const char *str2, \n\t\t\t   pj_size_t len);\n\n/**\n * Perform case-insensitive comparison to the strings.\n *\n * @param str1\t    The string to compare.\n * @param str2\t    The string to compare.\n *\n * @return \n *\t- < 0 if str1 is less than str2\n *      - 0   if str1 is equal to str2\n *      - > 0 if str1 is greater than str2\n */\nPJ_IDECL(int) pj_stricmp(const pj_str_t *str1, const pj_str_t *str2);\n\n/**\n * Perform lowercase comparison to the strings which consists of only\n * alnum characters. More over, it will only return non-zero if both\n * strings are not equal, not the usual negative or positive value.\n *\n * If non-alnum inputs are given, then the function may mistakenly \n * treat two strings as equal.\n *\n * @param str1\t    The string to compare.\n * @param str2\t    The string to compare.\n * @param len\t    The length to compare.\n *\n * @return \n *      - 0\t    if str1 is equal to str2\n *      - (-1)\t    if not equal.\n */\n#if defined(PJ_HAS_STRICMP_ALNUM) && PJ_HAS_STRICMP_ALNUM!=0\nPJ_IDECL(int) strnicmp_alnum(const char *str1, const char *str2,\n\t\t\t     int len);\n#else\n#define strnicmp_alnum\tpj_ansi_strnicmp\n#endif\n\n/**\n * Perform lowercase comparison to the strings which consists of only\n * alnum characters. More over, it will only return non-zero if both\n * strings are not equal, not the usual negative or positive value.\n *\n * If non-alnum inputs are given, then the function may mistakenly \n * treat two strings as equal.\n *\n * @param str1\t    The string to compare.\n * @param str2\t    The string to compare.\n *\n * @return \n *      - 0\t    if str1 is equal to str2\n *      - (-1)\t    if not equal.\n */\n#if defined(PJ_HAS_STRICMP_ALNUM) && PJ_HAS_STRICMP_ALNUM!=0\nPJ_IDECL(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2);\n#else\n#define pj_stricmp_alnum    pj_stricmp\n#endif\n\n/**\n * Perform case-insensitive comparison to the strings.\n *\n * @param str1\t    The string to compare.\n * @param str2\t    The string to compare.\n *\n * @return \n *\t- < 0 if str1 is less than str2\n *      - 0   if str1 is identical to str2\n *      - > 0 if str1 is greater than str2\n */\nPJ_IDECL(int) pj_stricmp2( const pj_str_t *str1, const char *str2);\n\n/**\n * Perform case-insensitive comparison to the strings.\n *\n * @param str1\t    The string to compare.\n * @param str2\t    The string to compare.\n * @param len\t    The maximum number of characters to compare.\n *\n * @return \n *\t- < 0 if str1 is less than str2\n *      - 0   if str1 is identical to str2\n *      - > 0 if str1 is greater than str2\n */\nPJ_IDECL(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2, \n\t\t\t   pj_size_t len);\n\n/**\n * Perform case-insensitive comparison to the strings.\n *\n * @param str1\t    The string to compare.\n * @param str2\t    The string to compare.\n * @param len\t    The maximum number of characters to compare.\n *\n * @return \n *\t- < 0 if str1 is less than str2\n *      - 0   if str1 is identical to str2\n *      - > 0 if str1 is greater than str2\n */\nPJ_IDECL(int) pj_strnicmp2( const pj_str_t *str1, const char *str2, \n\t\t\t    pj_size_t len);\n\n/**\n * Concatenate strings.\n *\n * @param dst\t    The destination string.\n * @param src\t    The source string.\n */\nPJ_IDECL(void) pj_strcat(pj_str_t *dst, const pj_str_t *src);\n\n\n/**\n * Concatenate strings.\n *\n * @param dst\t    The destination string.\n * @param src\t    The source string.\n */\nPJ_IDECL(void) pj_strcat2(pj_str_t *dst, const char *src);\n\n\n/**\n * Finds a character in a string.\n *\n * @param str\t    The string.\n * @param chr\t    The character to find.\n *\n * @return the pointer to first character found, or NULL.\n */\nPJ_INLINE(char*) pj_strchr( const pj_str_t *str, int chr)\n{\n    return (char*) memchr((char*)str->ptr, chr, str->slen);\n}\n\n/**\n * Find the occurence of a substring substr in string str.\n *\n * @param str\t    The string to search.\n * @param substr    The string to search fo.\n *\n * @return the pointer to the position of substr in str, or NULL. Note\n *         that if str is not NULL terminated, the returned pointer\n *         is pointing to non-NULL terminated string.\n */\nPJ_DECL(char*) pj_strstr(const pj_str_t *str, const pj_str_t *substr);\n\n/**\n * Performs substring lookup like pj_strstr() but ignores the case of\n * both strings.\n *\n * @param str\t    The string to search.\n * @param substr    The string to search fo.\n *\n * @return the pointer to the position of substr in str, or NULL. Note\n *         that if str is not NULL terminated, the returned pointer\n *         is pointing to non-NULL terminated string.\n */\nPJ_DECL(char*) pj_stristr(const pj_str_t *str, const pj_str_t *substr);\n\n/**\n * Remove (trim) leading whitespaces from the string.\n *\n * @param str\t    The string.\n *\n * @return the string.\n */\nPJ_DECL(pj_str_t*) pj_strltrim( pj_str_t *str );\n\n/**\n * Remove (trim) the trailing whitespaces from the string.\n *\n * @param str\t    The string.\n *\n * @return the string.\n */\nPJ_DECL(pj_str_t*) pj_strrtrim( pj_str_t *str );\n\n/**\n * Remove (trim) leading and trailing whitespaces from the string.\n *\n * @param str\t    The string.\n *\n * @return the string.\n */\nPJ_IDECL(pj_str_t*) pj_strtrim( pj_str_t *str );\n\n/**\n * Initialize the buffer with some random string. Note that the \n * generated string is not NULL terminated.\n *\n * @param str\t    the string to store the result.\n * @param length    the length of the random string to generate.\n *\n * @return the string.\n */\nPJ_DECL(char*) pj_create_random_string(char *str, pj_size_t length);\n\n/**\n * Convert string to signed integer. The conversion will stop as\n * soon as non-digit character is found or all the characters have\n * been processed.\n *\n * @param str\tthe string.\n *\n * @return the integer.\n */\nPJ_DECL(long) pj_strtol(const pj_str_t *str);\n\n/**\n * Convert string to unsigned integer. The conversion will stop as\n * soon as non-digit character is found or all the characters have\n * been processed.\n *\n * @param str\tthe string.\n *\n * @return the unsigned integer.\n */\nPJ_DECL(unsigned long) pj_strtoul(const pj_str_t *str);\n\n/**\n * Convert strings to an unsigned long-integer value.\n * This function stops reading the string input either when the number\n * of characters has exceeded the length of the input or it has read \n * the first character it cannot recognize as part of a number, that is\n * a character greater than or equal to base. \n *\n * @param str\t    The input string.\n * @param endptr    Optional pointer to receive the remainder/unparsed\n *\t\t    portion of the input.\n * @param base\t    Number base to use.\n *\n * @return the unsigned integer number.\n */\nPJ_DECL(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr,\n\t\t\t\t   unsigned base);\n\n/**\n * Convert string to float.\n *\n * @param str\tthe string.\n *\n * @return the value.\n */\nPJ_DECL(float) pj_strtof(const pj_str_t *str);\n\n/**\n * Utility to convert unsigned integer to string. Note that the\n * string will be NULL terminated.\n *\n * @param val\t    the unsigned integer value.\n * @param buf\t    the buffer\n *\n * @return the number of characters written\n */\nPJ_DECL(int) pj_utoa(unsigned long val, char *buf);\n\n/**\n * Convert unsigned integer to string with minimum digits. Note that the\n * string will be NULL terminated.\n *\n * @param val\t    The unsigned integer value.\n * @param buf\t    The buffer.\n * @param min_dig   Minimum digits to be printed, or zero to specify no\n *\t\t    minimum digit.\n * @param pad\t    The padding character to be put in front of the string\n *\t\t    when the digits is less than minimum.\n *\n * @return the number of characters written.\n */\nPJ_DECL(int) pj_utoa_pad( unsigned long val, char *buf, int min_dig, int pad);\n\n\n/**\n * Fill the memory location with zero.\n *\n * @param dst\t    The destination buffer.\n * @param size\t    The number of bytes.\n */\nPJ_INLINE(void) pj_bzero(void *dst, pj_size_t size)\n{\n#if defined(PJ_HAS_BZERO) && PJ_HAS_BZERO!=0\n    bzero(dst, size);\n#else\n    memset(dst, 0, size);\n#endif\n}\n\n\n/**\n * Fill the memory location with value.\n *\n * @param dst\t    The destination buffer.\n * @param c\t    Character to set.\n * @param size\t    The number of characters.\n *\n * @return the value of dst.\n */\nPJ_INLINE(void*) pj_memset(void *dst, int c, pj_size_t size)\n{\n    return memset(dst, c, size);\n}\n\n/**\n * Copy buffer.\n *\n * @param dst\t    The destination buffer.\n * @param src\t    The source buffer.\n * @param size\t    The size to copy.\n *\n * @return the destination buffer.\n */\nPJ_INLINE(void*) pj_memcpy(void *dst, const void *src, pj_size_t size)\n{\n    return memcpy(dst, src, size);\n}\n\n/**\n * Move memory.\n *\n * @param dst\t    The destination buffer.\n * @param src\t    The source buffer.\n * @param size\t    The size to copy.\n *\n * @return the destination buffer.\n */\nPJ_INLINE(void*) pj_memmove(void *dst, const void *src, pj_size_t size)\n{\n    return memmove(dst, src, size);\n}\n\n/**\n * Compare buffers.\n *\n * @param buf1\t    The first buffer.\n * @param buf2\t    The second buffer.\n * @param size\t    The size to compare.\n *\n * @return negative, zero, or positive value.\n */\nPJ_INLINE(int) pj_memcmp(const void *buf1, const void *buf2, pj_size_t size)\n{\n    return memcmp(buf1, buf2, size);\n}\n\n/**\n * Find character in the buffer.\n *\n * @param buf\t    The buffer.\n * @param c\t    The character to find.\n * @param size\t    The size to check.\n *\n * @return the pointer to location where the character is found, or NULL if\n *         not found.\n */\nPJ_INLINE(void*) pj_memchr(const void *buf, int c, pj_size_t size)\n{\n    return (void*)memchr((void*)buf, c, size);\n}\n\n\n/**\n * @}\n */\n\n#if PJ_FUNCTIONS_ARE_INLINED\n#  include <pj/string_i.h>\n#endif\n\nPJ_END_DECL\n\n#endif\t/* __PJ_STRING_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/string_i.h",
    "content": "/* $Id: string_i.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pj/assert.h>\n#include <pj/pool.h>\n\nPJ_IDEF(pj_str_t) pj_str(char *str)\n{\n    pj_str_t dst;\n    dst.ptr = str;\n    dst.slen = str ? pj_ansi_strlen(str) : 0;\n    return dst;\n}\n\nPJ_IDEF(pj_str_t*) pj_strdup(pj_pool_t *pool,\n\t\t\t      pj_str_t *dst,\n\t\t\t      const pj_str_t *src)\n{\n    /* Without this, destination will be corrupted */\n    if (dst == src)\n\treturn dst;\n\n    if (src->slen) {\n\tdst->ptr = (char*)pj_pool_alloc(pool, src->slen);\n\tpj_memcpy(dst->ptr, src->ptr, src->slen);\n    }\n    dst->slen = src->slen;\n    return dst;\n}\n\nPJ_IDEF(pj_str_t*) pj_strdup_with_null( pj_pool_t *pool,\n\t\t\t\t\tpj_str_t *dst,\n\t\t\t\t\tconst pj_str_t *src)\n{\n    dst->ptr = (char*)pj_pool_alloc(pool, src->slen+1);\n    if (src->slen) {\n\tpj_memcpy(dst->ptr, src->ptr, src->slen);\n    }\n    dst->slen = src->slen;\n    dst->ptr[dst->slen] = '\\0';\n    return dst;\n}\n\nPJ_IDEF(pj_str_t*) pj_strdup2(pj_pool_t *pool,\n\t\t\t      pj_str_t *dst,\n\t\t\t      const char *src)\n{\n    dst->slen = src ? pj_ansi_strlen(src) : 0;\n    if (dst->slen) {\n\tdst->ptr = (char*)pj_pool_alloc(pool, dst->slen);\n\tpj_memcpy(dst->ptr, src, dst->slen);\n    } else {\n\tdst->ptr = NULL;\n    }\n    return dst;\n}\n\nPJ_IDEF(pj_str_t*) pj_strdup2_with_null( pj_pool_t *pool,\n\t\t\t\t\t pj_str_t *dst,\n\t\t\t\t\t const char *src)\n{\n    dst->slen = src ? pj_ansi_strlen(src) : 0;\n    dst->ptr = (char*)pj_pool_alloc(pool, dst->slen+1);\n    if (dst->slen) {\n\tpj_memcpy(dst->ptr, src, dst->slen);\n    }\n    dst->ptr[dst->slen] = '\\0';\n    return dst;\n}\n\nPJ_IDEF(pj_str_t) pj_strdup3(pj_pool_t *pool, const char *src)\n{\n    pj_str_t temp;\n    pj_strdup2(pool, &temp, src);\n    return temp;\n}\n\nPJ_IDEF(pj_str_t*) pj_strassign( pj_str_t *dst, pj_str_t *src )\n{\n    dst->ptr = src->ptr;\n    dst->slen = src->slen;\n    return dst;\n}\n\nPJ_IDEF(pj_str_t*) pj_strcpy(pj_str_t *dst, const pj_str_t *src)\n{\n    dst->slen = src->slen;\n    if (src->slen > 0)\n\tpj_memcpy(dst->ptr, src->ptr, src->slen);\n    return dst;\n}\n\nPJ_IDEF(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src)\n{\n    dst->slen = src ? pj_ansi_strlen(src) : 0;\n    if (dst->slen > 0)\n\tpj_memcpy(dst->ptr, src, dst->slen);\n    return dst;\n}\n\nPJ_IDEF(pj_str_t*) pj_strncpy( pj_str_t *dst, const pj_str_t *src, \n\t\t\t       pj_ssize_t max)\n{\n    pj_assert(max >= 0);\n    if (max > src->slen) max = src->slen;\n    pj_memcpy(dst->ptr, src->ptr, max);\n    dst->slen = max;\n    return dst;\n}\n\nPJ_IDEF(pj_str_t*) pj_strncpy_with_null( pj_str_t *dst, const pj_str_t *src,\n\t\t\t\t\t pj_ssize_t max)\n{\n    pj_assert(max > 0);\n\n    if (max <= src->slen)\n\tmax = max-1;\n    else\n\tmax = src->slen;\n\n    pj_memcpy(dst->ptr, src->ptr, max);\n    dst->ptr[max] = '\\0';\n    dst->slen = max;\n    return dst;\n}\n\n\nPJ_IDEF(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2)\n{\n    if (str1->slen == 0) {\n\treturn str2->slen==0 ? 0 : -1;\n    } else if (str2->slen == 0) {\n\treturn 1;\n    } else {\n\tpj_size_t min = (str1->slen < str2->slen)? str1->slen : str2->slen;\n\tint res = pj_memcmp(str1->ptr, str2->ptr, min);\n\tif (res == 0) {\n\t    return (str1->slen < str2->slen) ? -1 :\n\t\t    (str1->slen == str2->slen ? 0 : 1);\n\t} else {\n\t    return res;\n\t}\n    }\n}\n\nPJ_IDEF(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2, \n\t\t\t pj_size_t len)\n{\n    pj_str_t copy1, copy2;\n\n    if (len < (unsigned)str1->slen) {\n\tcopy1.ptr = str1->ptr;\n\tcopy1.slen = len;\n\tstr1 = &copy1;\n    }\n\n    if (len < (unsigned)str2->slen) {\n\tcopy2.ptr = str2->ptr;\n\tcopy2.slen = len;\n\tstr2 = &copy2;\n    }\n\n    return pj_strcmp(str1, str2);\n}\n\nPJ_IDEF(int) pj_strncmp2( const pj_str_t *str1, const char *str2, \n\t\t\t  pj_size_t len)\n{\n    pj_str_t copy2;\n\n    if (str2) {\n\tcopy2.ptr = (char*)str2;\n\tcopy2.slen = pj_ansi_strlen(str2);\n    } else {\n\tcopy2.slen = 0;\n    }\n\n    return pj_strncmp(str1, &copy2, len);\n}\n\nPJ_IDEF(int) pj_strcmp2( const pj_str_t *str1, const char *str2 )\n{\n    pj_str_t copy2;\n\n    if (str2) {\n\tcopy2.ptr = (char*)str2;\n\tcopy2.slen = pj_ansi_strlen(str2);\n    } else {\n\tcopy2.ptr = NULL;\n\tcopy2.slen = 0;\n    }\n\n    return pj_strcmp(str1, &copy2);\n}\n\nPJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2)\n{\n    if (str1->slen == 0) {\n\treturn str2->slen==0 ? 0 : -1;\n    } else if (str2->slen == 0) {\n\treturn 1;\n    } else {\n\tpj_size_t min = (str1->slen < str2->slen)? str1->slen : str2->slen;\n\tint res = pj_ansi_strnicmp(str1->ptr, str2->ptr, min);\n\tif (res == 0) {\n\t    return (str1->slen < str2->slen) ? -1 :\n\t\t    (str1->slen == str2->slen ? 0 : 1);\n\t} else {\n\t    return res;\n\t}\n    }\n}\n\n#if defined(PJ_HAS_STRICMP_ALNUM) && PJ_HAS_STRICMP_ALNUM!=0\nPJ_IDEF(int) strnicmp_alnum( const char *str1, const char *str2,\n\t\t\t     int len)\n{\n    if (len==0)\n\treturn 0;\n    else {\n\tregister const pj_uint32_t *p1 = (pj_uint32_t*)str1, \n\t\t                   *p2 = (pj_uint32_t*)str2;\n\twhile (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))\n\t    ++p1, ++p2, len-=4;\n\n\tif (len > 3)\n\t    return -1;\n#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0\n\telse if (len==3)\n\t    return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;\n\telse if (len==2)\n\t    return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;\n\telse if (len==1)\n\t    return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;\n#else\n\telse if (len==3)\n\t    return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;\n\telse if (len==2)\n\t    return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;\n\telse if (len==1)\n\t    return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;\n#endif\n\telse \n\t    return 0;\n    }\n}\n\nPJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2)\n{\n    register int len = str1->slen;\n\n    if (len != str2->slen) {\n\treturn (len < str2->slen) ? -1 : 1;\n    } else if (len == 0) {\n\treturn 0;\n    } else {\n\tregister const pj_uint32_t *p1 = (pj_uint32_t*)str1->ptr, \n\t\t                   *p2 = (pj_uint32_t*)str2->ptr;\n\twhile (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))\n\t    ++p1, ++p2, len-=4;\n\n\tif (len > 3)\n\t    return -1;\n#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0\n\telse if (len==3)\n\t    return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;\n\telse if (len==2)\n\t    return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;\n\telse if (len==1)\n\t    return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;\n#else\n\telse if (len==3)\n\t    return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;\n\telse if (len==2)\n\t    return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;\n\telse if (len==1)\n\t    return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;\n#endif\n\telse \n\t    return 0;\n    }\n}\n#endif\t/* PJ_HAS_STRICMP_ALNUM */\n\nPJ_IDEF(int) pj_stricmp2( const pj_str_t *str1, const char *str2)\n{\n    pj_str_t copy2;\n\n    if (str2) {\n\tcopy2.ptr = (char*)str2;\n\tcopy2.slen = pj_ansi_strlen(str2);\n    } else {\n\tcopy2.ptr = NULL;\n\tcopy2.slen = 0;\n    }\n\n    return pj_stricmp(str1, &copy2);\n}\n\nPJ_IDEF(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2, \n\t\t\t  pj_size_t len)\n{\n    pj_str_t copy1, copy2;\n\n    if (len < (unsigned)str1->slen) {\n\tcopy1.ptr = str1->ptr;\n\tcopy1.slen = len;\n\tstr1 = &copy1;\n    }\n\n    if (len < (unsigned)str2->slen) {\n\tcopy2.ptr = str2->ptr;\n\tcopy2.slen = len;\n\tstr2 = &copy2;\n    }\n\n    return pj_stricmp(str1, str2);\n}\n\nPJ_IDEF(int) pj_strnicmp2( const pj_str_t *str1, const char *str2, \n\t\t\t   pj_size_t len)\n{\n    pj_str_t copy2;\n\n    if (str2) {\n\tcopy2.ptr = (char*)str2;\n\tcopy2.slen = pj_ansi_strlen(str2);\n    } else {\n\tcopy2.slen = 0;\n    }\n\n    return pj_strnicmp(str1, &copy2, len);\n}\n\nPJ_IDEF(void) pj_strcat(pj_str_t *dst, const pj_str_t *src)\n{\n    if (src->slen) {\n\tpj_memcpy(dst->ptr + dst->slen, src->ptr, src->slen);\n\tdst->slen += src->slen;\n    }\n}\n\nPJ_IDEF(void) pj_strcat2(pj_str_t *dst, const char *str)\n{\n    pj_size_t len = str? pj_ansi_strlen(str) : 0;\n    if (len) {\n\tpj_memcpy(dst->ptr + dst->slen, str, len);\n\tdst->slen += len;\n    }\n}\n\nPJ_IDEF(pj_str_t*) pj_strtrim( pj_str_t *str )\n{\n    pj_strltrim(str);\n    pj_strrtrim(str);\n    return str;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/timer.h",
    "content": "/* $Id: timer.h 4359 2013-02-21 11:18:36Z bennylp $ */\n/* \n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#ifndef __PJ_TIMER_H__\n#define __PJ_TIMER_H__\n\n/**\n * @file timer.h\n * @brief Timer Heap\n */\n\n#include <pj/types.h>\n#include <pj/lock.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_TIMER Timer Heap Management.\n * @ingroup PJ_MISC\n * @brief\n * The timer scheduling implementation here is based on ACE library's \n * ACE_Timer_Heap, with only little modification to suit our library's style\n * (I even left most of the comments in the original source).\n *\n * To quote the original quote in ACE_Timer_Heap_T class:\n *\n *      This implementation uses a heap-based callout queue of\n *      absolute times.  Therefore, in the average and worst case,\n *      scheduling, canceling, and expiring timers is O(log N) (where\n *      N is the total number of timers).  In addition, we can also\n *      preallocate as many \\a ACE_Timer_Nodes as there are slots in\n *      the heap.  This allows us to completely remove the need for\n *      dynamic memory allocation, which is important for real-time\n *      systems.\n *\n * You can find the fine ACE library at:\n *  http://www.cs.wustl.edu/~schmidt/ACE.html\n *\n * ACE is Copyright (C)1993-2006 Douglas C. Schmidt <d.schmidt@vanderbilt.edu>\n *\n * @{\n *\n * \\section pj_timer_examples_sec Examples\n *\n * For some examples on how to use the timer heap, please see the link below.\n *\n *  - \\ref page_pjlib_timer_test\n */\n\n\n/**\n * The type for internal timer ID.\n */\ntypedef int pj_timer_id_t;\n\n/** \n * Forward declaration for pj_timer_entry. \n */\nstruct pj_timer_entry;\n\n/**\n * The type of callback function to be called by timer scheduler when a timer\n * has expired.\n *\n * @param timer_heap    The timer heap.\n * @param entry         Timer entry which timer's has expired.\n */\ntypedef void pj_timer_heap_callback(pj_timer_heap_t *timer_heap,\n\t\t\t\t    struct pj_timer_entry *entry);\n\n\n/**\n * This structure represents an entry to the timer.\n */\ntypedef struct pj_timer_entry\n{\n    /** \n     * User data to be associated with this entry. \n     * Applications normally will put the instance of object that\n     * owns the timer entry in this field.\n     */\n    void *user_data;\n\n    /** \n     * Arbitrary ID assigned by the user/owner of this entry. \n     * Applications can use this ID to distinguish multiple\n     * timer entries that share the same callback and user_data.\n     */\n    int id;\n\n    /** \n     * Callback to be called when the timer expires. \n     */\n    pj_timer_heap_callback *cb;\n\n    /** \n     * Internal unique timer ID, which is assigned by the timer heap. \n     * Application should not touch this ID.\n     */\n    pj_timer_id_t _timer_id;\n\n    /** \n     * The future time when the timer expires, which the value is updated\n     * by timer heap when the timer is scheduled.\n     */\n    pj_time_val _timer_value;\n\n    /**\n     * Internal: the group lock used by this entry, set when\n     * pj_timer_heap_schedule_w_lock() is used.\n     */\n    pj_grp_lock_t *_grp_lock;\n\n#if PJ_TIMER_DEBUG\n    const char\t*src_file;\n    int\t\t src_line;\n#endif\n} pj_timer_entry;\n\n\n/**\n * Calculate memory size required to create a timer heap.\n *\n * @param count     Number of timer entries to be supported.\n * @return          Memory size requirement in bytes.\n */\nPJ_DECL(pj_size_t) pj_timer_heap_mem_size(pj_size_t count);\n\n/**\n * Create a timer heap.\n *\n * @param pool      The pool where allocations in the timer heap will be \n *                  allocated. The timer heap will dynamicly allocate \n *                  more storate from the pool if the number of timer \n *                  entries registered is more than the size originally \n *                  requested when calling this function.\n * @param count     The maximum number of timer entries to be supported \n *                  initially. If the application registers more entries \n *                  during runtime, then the timer heap will resize.\n * @param ht        Pointer to receive the created timer heap.\n *\n * @return          PJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_timer_heap_create( pj_pool_t *pool,\n\t\t\t\t\t   pj_size_t count,\n                                           pj_timer_heap_t **ht);\n\n/**\n * Destroy the timer heap.\n *\n * @param ht        The timer heap.\n */\nPJ_DECL(void) pj_timer_heap_destroy( pj_timer_heap_t *ht );\n\n\n/**\n * Set lock object to be used by the timer heap. By default, the timer heap\n * uses dummy synchronization.\n *\n * @param ht        The timer heap.\n * @param lock      The lock object to be used for synchronization.\n * @param auto_del  If nonzero, the lock object will be destroyed when\n *                  the timer heap is destroyed.\n */\nPJ_DECL(void) pj_timer_heap_set_lock( pj_timer_heap_t *ht,\n                                      pj_lock_t *lock,\n                                      pj_bool_t auto_del );\n\n/**\n * Set maximum number of timed out entries to process in a single poll.\n *\n * @param ht        The timer heap.\n * @param count     Number of entries.\n *\n * @return          The old number.\n */\nPJ_DECL(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht,\n                                                           unsigned count );\n\n/**\n * Initialize a timer entry. Application should call this function at least\n * once before scheduling the entry to the timer heap, to properly initialize\n * the timer entry.\n *\n * @param entry     The timer entry to be initialized.\n * @param id        Arbitrary ID assigned by the user/owner of this entry.\n *                  Applications can use this ID to distinguish multiple\n *                  timer entries that share the same callback and user_data.\n * @param user_data User data to be associated with this entry. \n *                  Applications normally will put the instance of object that\n *                  owns the timer entry in this field.\n * @param cb        Callback function to be called when the timer elapses.\n *\n * @return          The timer entry itself.\n */\nPJ_DECL(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry,\n                                              int id,\n                                              void *user_data,\n                                              pj_timer_heap_callback *cb );\n\n/**\n * Queries whether a timer entry is currently running.\n *\n * @param entry     The timer entry to query.\n *\n * @return          PJ_TRUE if the timer is running.  PJ_FALSE if not.\n */\nPJ_DECL(pj_bool_t) pj_timer_entry_running( pj_timer_entry *entry );\n\n/**\n * Schedule a timer entry which will expire AFTER the specified delay.\n *\n * @param ht        The timer heap.\n * @param entry     The entry to be registered. \n * @param delay     The interval to expire.\n * @return          PJ_SUCCESS, or the appropriate error code.\n */\n#if PJ_TIMER_DEBUG\n#  define pj_timer_heap_schedule(ht,e,d) \\\n\t\t\tpj_timer_heap_schedule_dbg(ht,e,d,__FILE__,__LINE__)\n\n  PJ_DECL(pj_status_t) pj_timer_heap_schedule_dbg( pj_timer_heap_t *ht,\n        \t\t\t\t\t   pj_timer_entry *entry,\n        \t\t\t\t\t   const pj_time_val *delay,\n        \t\t\t\t\t   const char *src_file,\n        \t\t\t\t\t   int src_line);\n#else\nPJ_DECL(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht,\n\t\t\t\t\t     pj_timer_entry *entry, \n\t\t\t\t\t     const pj_time_val *delay);\n#endif\t/* PJ_TIMER_DEBUG */\n\n/**\n * Schedule a timer entry which will expire AFTER the specified delay, and\n * increment the reference counter of the group lock while the timer entry\n * is active. The group lock reference counter will automatically be released\n * after the timer callback is called or when the timer is cancelled.\n *\n * @param ht        The timer heap.\n * @param entry     The entry to be registered.\n * @param id_val    The value to be set to the \"id\" field of the timer entry\n * \t\t    once the timer is scheduled.\n * @param delay     The interval to expire.\n * @param grp_lock  The group lock.\n *\n * @return          PJ_SUCCESS, or the appropriate error code.\n */\n#if PJ_TIMER_DEBUG\n#  define pj_timer_heap_schedule_w_grp_lock(ht,e,d,id,g) \\\n\tpj_timer_heap_schedule_w_grp_lock_dbg(ht,e,d,id,g,__FILE__,__LINE__)\n\n  PJ_DECL(pj_status_t) pj_timer_heap_schedule_w_grp_lock_dbg(\n\t\t\t\t\t\t   pj_timer_heap_t *ht,\n        \t\t\t\t\t   pj_timer_entry *entry,\n        \t\t\t\t\t   const pj_time_val *delay,\n        \t\t\t\t\t   int id_val,\n        \t\t\t\t\t   pj_grp_lock_t *grp_lock,\n        \t\t\t\t\t   const char *src_file,\n        \t\t\t\t\t   int src_line);\n#else\nPJ_DECL(pj_status_t) pj_timer_heap_schedule_w_grp_lock(\n\t\t\t\t\t\t    pj_timer_heap_t *ht,\n\t\t\t\t\t\t    pj_timer_entry *entry,\n\t\t\t\t\t\t    const pj_time_val *delay,\n\t\t\t\t\t\t    int id_val,\n\t\t\t\t\t\t    pj_grp_lock_t *grp_lock);\n#endif\t/* PJ_TIMER_DEBUG */\n\n\n/**\n * Cancel a previously registered timer. This will also decrement the\n * reference counter of the group lock associated with the timer entry,\n * if the entry was scheduled with one.\n *\n * @param ht        The timer heap.\n * @param entry     The entry to be cancelled.\n * @return          The number of timer cancelled, which should be one if the\n *                  entry has really been registered, or zero if no timer was\n *                  cancelled.\n */\nPJ_DECL(int) pj_timer_heap_cancel( pj_timer_heap_t *ht,\n\t\t\t\t   pj_timer_entry *entry);\n\n/**\n * Cancel only if the previously registered timer is active. This will\n * also decrement the reference counter of the group lock associated\n * with the timer entry, if the entry was scheduled with one. In any\n * case, set the \"id\" to the specified value.\n *\n * @param ht        The timer heap.\n * @param entry     The entry to be cancelled.\n * @param id_val    Value to be set to \"id\"\n *\n * @return          The number of timer cancelled, which should be one if the\n *                  entry has really been registered, or zero if no timer was\n *                  cancelled.\n */\nPJ_DECL(int) pj_timer_heap_cancel_if_active(pj_timer_heap_t *ht,\n                                            pj_timer_entry *entry,\n                                            int id_val);\n\n/**\n * Get the number of timer entries.\n *\n * @param ht        The timer heap.\n * @return          The number of timer entries.\n */\nPJ_DECL(pj_size_t) pj_timer_heap_count( pj_timer_heap_t *ht );\n\n/**\n * Get the earliest time registered in the timer heap. The timer heap\n * MUST have at least one timer being scheduled (application should use\n * #pj_timer_heap_count() before calling this function).\n *\n * @param ht        The timer heap.\n * @param timeval   The time deadline of the earliest timer entry.\n *\n * @return          PJ_SUCCESS, or PJ_ENOTFOUND if no entry is scheduled.\n */\nPJ_DECL(pj_status_t) pj_timer_heap_earliest_time( pj_timer_heap_t *ht, \n\t\t\t\t\t          pj_time_val *timeval);\n\n/**\n * Poll the timer heap, check for expired timers and call the callback for\n * each of the expired timers.\n *\n * Note: polling the timer heap is not necessary in Symbian. Please see\n * @ref PJ_SYMBIAN_OS for more info.\n *\n * @param ht         The timer heap.\n * @param next_delay If this parameter is not NULL, it will be filled up with\n *\t\t     the time delay until the next timer elapsed, or \n *\t\t     PJ_MAXINT32 in the sec part if no entry exist.\n *\n * @return           The number of timers expired.\n */\nPJ_DECL(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht, \n                                      pj_time_val *next_delay);\n\n#if PJ_TIMER_DEBUG\n/**\n * Dump timer heap entries.\n *\n * @param ht\t    The timer heap.\n */\nPJ_DECL(void) pj_timer_heap_dump(pj_timer_heap_t *ht);\n#endif\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJ_TIMER_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/types.h",
    "content": "/* $Id: types.h 4359 2013-02-21 11:18:36Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_TYPES_H__\n#define __PJ_TYPES_H__\n\n\n/**\n * @file types.h\n * @brief Declaration of basic types and utility.\n */\n/**\n * @defgroup PJ_BASIC Basic Data Types and Library Functionality.\n * @ingroup PJ_DS\n * @{\n */\n#include <pj/config.h>\n\nPJ_BEGIN_DECL\n\n/* ************************************************************************* */\n\n/** Signed 32bit integer. */\ntypedef int\t\tpj_int32_t;\n\n/** Unsigned 32bit integer. */\ntypedef unsigned int\tpj_uint32_t;\n\n/** Signed 16bit integer. */\ntypedef short\t\tpj_int16_t;\n\n/** Unsigned 16bit integer. */\ntypedef unsigned short\tpj_uint16_t;\n\n/** Signed 8bit integer. */\ntypedef signed char\tpj_int8_t;\n\n/** Unsigned 8bit integer. */\ntypedef unsigned char\tpj_uint8_t;\n\n/** Large unsigned integer. */\ntypedef size_t\t\tpj_size_t;\n\n/** Large signed integer. */\n#if defined(PJ_WIN64) && PJ_WIN64!=0\n    typedef pj_int64_t     pj_ssize_t;\n#else\n    typedef long           pj_ssize_t;\n#endif\n\n/** Status code. */\ntypedef int\t\tpj_status_t;\n\n/** Boolean. */\ntypedef int\t\tpj_bool_t;\n\n/** Native char type, which will be equal to wchar_t for Unicode\n * and char for ANSI. */\n#if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0\n    typedef wchar_t pj_char_t;\n#else\n    typedef char pj_char_t;\n#endif\n\n/** This macro creates Unicode or ANSI literal string depending whether\n *  native platform string is Unicode or ANSI. */\n#if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0\n#   define PJ_T(literal_str)\tL##literal_str\n#else\n#   define PJ_T(literal_str)\tliteral_str\n#endif\n\n/** Some constants */\nenum pj_constants_\n{\n    /** Status is OK. */\n    PJ_SUCCESS=0,\n\n    /** True value. */\n    PJ_TRUE=1,\n\n    /** False value. */\n    PJ_FALSE=0\n};\n\n/**\n * File offset type.\n */\n#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0\ntypedef pj_int64_t pj_off_t;\n#else\ntypedef pj_ssize_t pj_off_t;\n#endif\n\n/* ************************************************************************* */\n/*\n * Data structure types.\n */\n/**\n * This type is used as replacement to legacy C string, and used throughout\n * the library. By convention, the string is NOT null terminated.\n */\nstruct pj_str_t\n{\n    /** Buffer pointer, which is by convention NOT null terminated. */\n    char       *ptr;\n\n    /** The length of the string. */\n    pj_ssize_t  slen;\n};\n\n/**\n * This structure represents high resolution (64bit) time value. The time\n * values represent time in cycles, which is retrieved by calling\n * #pj_get_timestamp().\n */\ntypedef union pj_timestamp\n{\n    struct\n    {\n#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0\n\tpj_uint32_t lo;     /**< Low 32-bit value of the 64-bit value. */\n\tpj_uint32_t hi;     /**< high 32-bit value of the 64-bit value. */\n#else\n\tpj_uint32_t hi;     /**< high 32-bit value of the 64-bit value. */\n\tpj_uint32_t lo;     /**< Low 32-bit value of the 64-bit value. */\n#endif\n    } u32;                  /**< The 64-bit value as two 32-bit values. */\n\n#if PJ_HAS_INT64\n    pj_uint64_t u64;        /**< The whole 64-bit value, where available. */\n#endif\n} pj_timestamp;\n\n\n\n/**\n * The opaque data type for linked list, which is used as arguments throughout\n * the linked list operations.\n */\ntypedef void pj_list_type;\n\n/** \n * List.\n */\ntypedef struct pj_list pj_list;\n\n/**\n * Opaque data type for hash tables.\n */\ntypedef struct pj_hash_table_t pj_hash_table_t;\n\n/**\n * Opaque data type for hash entry (only used internally by hash table).\n */\ntypedef struct pj_hash_entry pj_hash_entry;\n\n/**\n * Data type for hash search iterator.\n * This structure should be opaque, however applications need to declare\n * concrete variable of this type, that's why the declaration is visible here.\n */\ntypedef struct pj_hash_iterator_t\n{\n    pj_uint32_t\t     index;     /**< Internal index.     */\n    pj_hash_entry   *entry;     /**< Internal entry.     */\n} pj_hash_iterator_t;\n\n\n/**\n * Forward declaration for memory pool factory.\n */\ntypedef struct pj_pool_factory pj_pool_factory;\n\n/**\n * Opaque data type for memory pool.\n */\ntypedef struct pj_pool_t pj_pool_t;\n\n/**\n * Forward declaration for caching pool, a pool factory implementation.\n */\ntypedef struct pj_caching_pool pj_caching_pool;\n\n/**\n * This type is used as replacement to legacy C string, and used throughout\n * the library.\n */\ntypedef struct pj_str_t pj_str_t;\n\n/**\n * Opaque data type for I/O Queue structure.\n */\ntypedef struct pj_ioqueue_t pj_ioqueue_t;\n\n/**\n * Opaque data type for key that identifies a handle registered to the\n * I/O queue framework.\n */\ntypedef struct pj_ioqueue_key_t pj_ioqueue_key_t;\n\n/**\n * Opaque data to identify timer heap.\n */\ntypedef struct pj_timer_heap_t pj_timer_heap_t;\n\n/** \n * Opaque data type for atomic operations.\n */\ntypedef struct pj_atomic_t pj_atomic_t;\n\n/**\n * Value type of an atomic variable.\n */\ntypedef PJ_ATOMIC_VALUE_TYPE pj_atomic_value_t;\n \n/* ************************************************************************* */\n\n/** Thread handle. */\ntypedef struct pj_thread_t pj_thread_t;\n\n/** Lock object. */\ntypedef struct pj_lock_t pj_lock_t;\n\n/** Group lock */\ntypedef struct pj_grp_lock_t pj_grp_lock_t;\n\n/** Mutex handle. */\ntypedef struct pj_mutex_t pj_mutex_t;\n\n/** Semaphore handle. */\ntypedef struct pj_sem_t pj_sem_t;\n\n/** Event object. */\ntypedef struct pj_event_t pj_event_t;\n\n/** Unidirectional stream pipe object. */\ntypedef struct pj_pipe_t pj_pipe_t;\n\n/** Operating system handle. */\ntypedef void *pj_oshandle_t;\n\n/** Socket handle. */\n#if defined(PJ_WIN64) && PJ_WIN64!=0\n    typedef pj_int64_t pj_sock_t;\n#else\n    typedef long pj_sock_t;\n#endif\n\n/** Generic socket address. */\ntypedef void pj_sockaddr_t;\n\n/** Forward declaration. */\ntypedef struct pj_sockaddr_in pj_sockaddr_in;\n\n/** Color type. */\ntypedef unsigned int pj_color_t;\n\n/** Exception id. */\ntypedef int pj_exception_id_t;\n\n/* ************************************************************************* */\n\n/** Utility macro to compute the number of elements in static array. */\n#define PJ_ARRAY_SIZE(a)    (sizeof(a)/sizeof(a[0]))\n\n/** Maximum value for signed 32-bit integer. */\n#define PJ_MAXINT32  0x7FFFFFFFL\n\n/**\n * Length of object names.\n */\n#define PJ_MAX_OBJ_NAME\t32\n\n/* ************************************************************************* */\n/*\n * General.\n */\n/**\n * Initialize the PJ Library.\n * This function must be called before using the library. The purpose of this\n * function is to initialize static library data, such as character table used\n * in random string generation, and to initialize operating system dependent\n * functionality (such as WSAStartup() in Windows).\n *\n * Apart from calling pj_init(), application typically should also initialize\n * the random seed by calling pj_srand().\n *\n * @return PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pj_init(void);\n\n\n/**\n * Shutdown PJLIB.\n */\nPJ_DECL(void) pj_shutdown(void);\n\n/**\n * Type of callback to register to pj_atexit().\n */\ntypedef void (*pj_exit_callback)(void);\n\n/**\n * Register cleanup function to be called by PJLIB when pj_shutdown() is \n * called.\n *\n * @param func\t    The function to be registered.\n *\n * @return PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pj_atexit(pj_exit_callback func);\n\n\n\n/**\n * Swap the byte order of an 16bit data.\n *\n * @param val16\t    The 16bit data.\n *\n * @return\t    An 16bit data with swapped byte order.\n */\nPJ_INLINE(pj_int16_t) pj_swap16(pj_int16_t val16)\n{\n    pj_uint8_t *p = (pj_uint8_t*)&val16;\n    pj_uint8_t tmp = *p;\n    *p = *(p+1);\n    *(p+1) = tmp;\n    return val16;\n}\n\n/**\n * Swap the byte order of an 32bit data.\n *\n * @param val32\t    The 32bit data.\n *\n * @return\t    An 32bit data with swapped byte order.\n */\nPJ_INLINE(pj_int32_t) pj_swap32(pj_int32_t val32)\n{\n    pj_uint8_t *p = (pj_uint8_t*)&val32;\n    pj_uint8_t tmp = *p;\n    *p = *(p+3);\n    *(p+3) = tmp;\n    tmp = *(p+1);\n    *(p+1) = *(p+2);\n    *(p+2) = tmp;\n    return val32;\n}\n\n\n/**\n * @}\n */\n/**\n * @addtogroup PJ_TIME Time Data Type and Manipulation.\n * @ingroup PJ_MISC\n * @{\n */\n\n/**\n * Representation of time value in this library.\n * This type can be used to represent either an interval or a specific time\n * or date. \n */\ntypedef struct pj_time_val\n{\n    /** The seconds part of the time. */\n    long    sec;\n\n    /** The miliseconds fraction of the time. */\n    long    msec;\n\n} pj_time_val;\n\n/**\n * Normalize the value in time value.\n * @param t     Time value to be normalized.\n */\nPJ_DECL(void) pj_time_val_normalize(pj_time_val *t);\n\n/**\n * Get the total time value in miliseconds. This is the same as\n * multiplying the second part with 1000 and then add the miliseconds\n * part to the result.\n *\n * @param t     The time value.\n * @return      Total time in miliseconds.\n * @hideinitializer\n */\n#define PJ_TIME_VAL_MSEC(t)\t((t).sec * 1000 + (t).msec)\n\n/**\n * This macro will check if \\a t1 is equal to \\a t2.\n *\n * @param t1    The first time value to compare.\n * @param t2    The second time value to compare.\n * @return      Non-zero if both time values are equal.\n * @hideinitializer\n */\n#define PJ_TIME_VAL_EQ(t1, t2)\t((t1).sec==(t2).sec && (t1).msec==(t2).msec)\n\n/**\n * This macro will check if \\a t1 is greater than \\a t2\n *\n * @param t1    The first time value to compare.\n * @param t2    The second time value to compare.\n * @return      Non-zero if t1 is greater than t2.\n * @hideinitializer\n */\n#define PJ_TIME_VAL_GT(t1, t2)\t((t1).sec>(t2).sec || \\\n                                ((t1).sec==(t2).sec && (t1).msec>(t2).msec))\n\n/**\n * This macro will check if \\a t1 is greater than or equal to \\a t2\n *\n * @param t1    The first time value to compare.\n * @param t2    The second time value to compare.\n * @return      Non-zero if t1 is greater than or equal to t2.\n * @hideinitializer\n */\n#define PJ_TIME_VAL_GTE(t1, t2)\t(PJ_TIME_VAL_GT(t1,t2) || \\\n                                 PJ_TIME_VAL_EQ(t1,t2))\n\n/**\n * This macro will check if \\a t1 is less than \\a t2\n *\n * @param t1    The first time value to compare.\n * @param t2    The second time value to compare.\n * @return      Non-zero if t1 is less than t2.\n * @hideinitializer\n */\n#define PJ_TIME_VAL_LT(t1, t2)\t(!(PJ_TIME_VAL_GTE(t1,t2)))\n\n/**\n * This macro will check if \\a t1 is less than or equal to \\a t2.\n *\n * @param t1    The first time value to compare.\n * @param t2    The second time value to compare.\n * @return      Non-zero if t1 is less than or equal to t2.\n * @hideinitializer\n */\n#define PJ_TIME_VAL_LTE(t1, t2)\t(!PJ_TIME_VAL_GT(t1, t2))\n\n/**\n * Add \\a t2 to \\a t1 and store the result in \\a t1. Effectively\n *\n * this macro will expand as: (\\a t1 += \\a t2).\n * @param t1    The time value to add.\n * @param t2    The time value to be added to \\a t1.\n * @hideinitializer\n */\n#define PJ_TIME_VAL_ADD(t1, t2)\t    do {\t\t\t    \\\n\t\t\t\t\t(t1).sec += (t2).sec;\t    \\\n\t\t\t\t\t(t1).msec += (t2).msec;\t    \\\n\t\t\t\t\tpj_time_val_normalize(&(t1)); \\\n\t\t\t\t    } while (0)\n\n\n/**\n * Substract \\a t2 from \\a t1 and store the result in \\a t1. Effectively\n * this macro will expand as (\\a t1 -= \\a t2).\n *\n * @param t1    The time value to subsctract.\n * @param t2    The time value to be substracted from \\a t1.\n * @hideinitializer\n */\n#define PJ_TIME_VAL_SUB(t1, t2)\t    do {\t\t\t    \\\n\t\t\t\t\t(t1).sec -= (t2).sec;\t    \\\n\t\t\t\t\t(t1).msec -= (t2).msec;\t    \\\n\t\t\t\t\tpj_time_val_normalize(&(t1)); \\\n\t\t\t\t    } while (0)\n\n\n/**\n * This structure represent the parsed representation of time.\n * It is acquired by calling #pj_time_decode().\n */\ntypedef struct pj_parsed_time\n{\n    /** This represents day of week where value zero means Sunday */\n    int wday;\n\n    /* This represents day of the year, 0-365, where zero means\n     *  1st of January.\n     */\n    /*int yday; */\n\n    /** This represents day of month: 1-31 */\n    int day;\n\n    /** This represents month, with the value is 0 - 11 (zero is January) */\n    int mon;\n\n    /** This represent the actual year (unlike in ANSI libc where\n     *  the value must be added by 1900).\n     */\n    int year;\n\n    /** This represents the second part, with the value is 0-59 */\n    int sec;\n\n    /** This represents the minute part, with the value is: 0-59 */\n    int min;\n\n    /** This represents the hour part, with the value is 0-23 */\n    int hour;\n\n    /** This represents the milisecond part, with the value is 0-999 */\n    int msec;\n\n} pj_parsed_time;\n\n\n/**\n * @}\t// Time Management\n */\n\n/* ************************************************************************* */\n/*\n * Terminal.\n */\n/**\n * Color code combination.\n */\nenum {\n    PJ_TERM_COLOR_R\t= 2,    /**< Red            */\n    PJ_TERM_COLOR_G\t= 4,    /**< Green          */\n    PJ_TERM_COLOR_B\t= 1,    /**< Blue.          */\n    PJ_TERM_COLOR_BRIGHT = 8    /**< Bright mask.   */\n};\n\n\n\n\nPJ_END_DECL\n\n\n#endif /* __PJ_TYPES_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj/unicode.h",
    "content": "/* $Id: unicode.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_UNICODE_H__\n#define __PJ_UNICODE_H__\n\n#include <pj/types.h>\n\n\n/**\n * @defgroup PJ_UNICODE Unicode Support\n * @ingroup PJ_MISC\n * @{\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * @file unicode.h\n * @brief Provides Unicode conversion for Unicode OSes\n */\n\n/**\n * Convert ANSI strings to Unicode strings.\n *\n * @param str\t\t    The ANSI string to be converted.\n * @param len\t\t    The length of the input string.\n * @param wbuf\t\t    Buffer to hold the Unicode string output.\n * @param wbuf_count\t    Buffer size, in number of elements (not bytes).\n *\n * @return\t\t    The Unicode string, NULL terminated.\n */\nPJ_DECL(wchar_t*) pj_ansi_to_unicode(const char *str, int len,\n\t\t\t\t     wchar_t *wbuf, int wbuf_count);\n\n\n/**\n * Convert Unicode string to ANSI string.\n *\n * @param wstr\t\t    The Unicode string to be converted.\n * @param len\t\t    The length of the input string.\n * @param buf\t\t    Buffer to hold the ANSI string output.\n * @param buf_size\t    Size of the output buffer.\n *\n * @return\t\t    The ANSI string, NULL terminated.\n */\nPJ_DECL(char*) pj_unicode_to_ansi(const wchar_t *wstr, pj_ssize_t len,\n\t\t\t\t  char *buf, int buf_size);\n\n\n#if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0\n\n/**\n * This macro is used to declare temporary Unicode buffer for ANSI to \n * Unicode conversion, and should be put in declaration section of a block.\n * When PJ_NATIVE_STRING_IS_UNICODE macro is not defined, this \n * macro will expand to nothing.\n */\n#   define PJ_DECL_UNICODE_TEMP_BUF(buf,size)   wchar_t buf[size];\n\n/**\n * This macro will convert ANSI string to native, when the platform's\n * native string is Unicode (PJ_NATIVE_STRING_IS_UNICODE is non-zero).\n */\n#   define PJ_STRING_TO_NATIVE(s,buf,max)\tpj_ansi_to_unicode( \\\n\t\t\t\t\t\t    s, strlen(s), \\\n\t\t\t\t\t\t    buf, max)\n\n/**\n * This macro is used to declare temporary ANSI buffer for Unicode to \n * ANSI conversion, and should be put in declaration section of a block.\n * When PJ_NATIVE_STRING_IS_UNICODE macro is not defined, this \n * macro will expand to nothing.\n */\n#   define PJ_DECL_ANSI_TEMP_BUF(buf,size)\tchar buf[size];\n\n\n/**\n * This macro will convert Unicode string to ANSI, when the platform's\n * native string is Unicode (PJ_NATIVE_STRING_IS_UNICODE is non-zero).\n */\n#   define PJ_NATIVE_TO_STRING(cs,buf,max)\tpj_unicode_to_ansi( \\\n\t\t\t\t\t\t    cs, wcslen(cs), \\\n\t\t\t\t\t\t    buf, max)\n\n#else\n\n/**\n * This macro is used to declare temporary Unicode buffer for ANSI to \n * Unicode conversion, and should be put in declaration section of a block.\n * When PJ_NATIVE_STRING_IS_UNICODE macro is not defined, this \n * macro will expand to nothing.\n */\n#   define PJ_DECL_UNICODE_TEMP_BUF(var,size)\n/**\n * This macro will convert ANSI string to native, when the platform's\n * native string is Unicode (PJ_NATIVE_STRING_IS_UNICODE is non-zero).\n */\n#   define PJ_STRING_TO_NATIVE(s,buf,max)\t((char*)s)\n/**\n * This macro is used to declare temporary ANSI buffer for Unicode to \n * ANSI conversion, and should be put in declaration section of a block.\n * When PJ_NATIVE_STRING_IS_UNICODE macro is not defined, this \n * macro will expand to nothing.\n */\n#   define PJ_DECL_ANSI_TEMP_BUF(buf,size)\n/**\n * This macro will convert Unicode string to ANSI, when the platform's\n * native string is Unicode (PJ_NATIVE_STRING_IS_UNICODE is non-zero).\n */\n#   define PJ_NATIVE_TO_STRING(cs,buf,max)\t((char*)(const char*)cs)\n\n#endif\n\n\n\nPJ_END_DECL\n\n/*\n * @}\n */\n\n\n#endif\t/* __PJ_UNICODE_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj++/file.hpp",
    "content": "/* $Id: file.hpp 2394 2008-12-23 17:27:53Z bennylp $  */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJPP_FILE_HPP__\n#define __PJPP_FILE_HPP__\n\n#include <pj/file_io.h>\n#include <pj/file_access.h>\n#include <pj++/types.hpp>\n#include <pj++/pool.hpp>\n\n//\n// File API.\n//\nclass Pj_File_API\n{\npublic:\n    //\n    // Check file existance.\n    //\n    static bool file_exists(const char *filename)\n    {\n        return pj_file_exists(filename) != 0;\n    }\n\n    //\n    // Get file size.\n    //\n    static pj_off_t file_size(const char *filename)\n    {\n        return pj_file_size(filename);\n    }\n\n    //\n    // Delete file.\n    //\n    static pj_status_t file_delete(const char *filename)\n    {\n        return pj_file_delete(filename);\n    }\n\n    //\n    // Move/rename file.\n    //\n    static pj_status_t file_move(const char *oldname, const char *newname)\n    {\n        return pj_file_move(oldname, newname);\n    }\n\n    //\n    // Get stat.\n    //\n    static pj_status_t file_stat(const char *filename, pj_file_stat *buf)\n    {\n        return pj_file_getstat(filename, buf);\n    }\n};\n\n\n//\n// File.\n//\nclass Pj_File : public Pj_Object\n{\npublic:\n    //\n    // Offset type to be used in setpos.\n    //\n    enum Offset_Type\n    {\n        PJ_SEEK_SET = PJ_SEEK_SET,\n        PJ_SEEK_CUR = PJ_SEEK_CUR,\n        PJ_SEEK_END = PJ_SEEK_END,\n    };\n\n    //\n    // Default constructor.\n    //\n    Pj_File()\n        : hnd_(0)\n    {\n    }\n\n    //\n    // Construct and open a file.\n    //\n    Pj_File(Pj_Pool *pool, const char *filename,\n            unsigned access = PJ_O_RDONLY)\n    : hnd_(NULL)\n    {\n        open(pool, filename, access);\n    }\n\n    //\n    // Destructor closes the file.\n    //\n    ~Pj_File()\n    {\n        close();\n    }\n\n    //\n    // Open a file.\n    //\n    pj_status_t open(Pj_Pool *pool, const char *filename, \n                     unsigned access = PJ_O_RDONLY )\n    {\n        close();\n        return pj_file_open(pool->pool_(), filename, access, &hnd_);\n    }\n\n    //\n    // Close a file.\n    //\n    void close()\n    {\n        if (hnd_ != 0) {\n            pj_file_close(hnd_);\n            hnd_ = 0;\n        }\n    }\n\n    //\n    // Write data.\n    //\n    pj_ssize_t write(const void *buff, pj_size_t size)\n    {\n        pj_ssize_t bytes = size;\n        if (pj_file_write(hnd_, buff, &bytes) != PJ_SUCCESS)\n            return -1;\n        return bytes;\n    }\n\n    //\n    // Read data.\n    //\n    pj_ssize_t read(void *buf, pj_size_t size)\n    {\n        pj_ssize_t bytes = size;\n        if (pj_file_read(hnd_, buf, &bytes) != PJ_SUCCESS)\n            return -1;\n        return bytes;\n    }\n\n    //\n    // Set file position.\n    //\n    pj_status_t setpos(pj_off_t offset, Offset_Type whence)\n    {\n        return pj_file_setpos(hnd_, offset, \n                              (enum pj_file_seek_type)whence);\n    }\n\n    //\n    // Get file position.\n    //\n    pj_off_t getpos()\n    {\n        pj_off_t pos;\n        if (pj_file_getpos(hnd_, &pos) != PJ_SUCCESS)\n            return -1;\n        return pos;\n    }\n\nprivate:\n    pj_oshandle_t hnd_;\n};\n\n\n\n#endif  /* __PJPP_FILE_HPP__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj++/hash.hpp",
    "content": "/* $Id: hash.hpp 2394 2008-12-23 17:27:53Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJPP_HASH_HPP__\n#define __PJPP_HASH_HPP__\n\n#include <pj++/types.hpp>\n#include <pj++/pool.hpp>\n#include <pj/hash.h>\n\n//\n// Hash table.\n//\nclass Pj_Hash_Table : public Pj_Object\n{\npublic:\n    //\n    // Hash table iterator.\n    //\n    class iterator\n    {\n    public:\n\titerator() \n        {\n        }\n\texplicit iterator(pj_hash_table_t *h, pj_hash_iterator_t *i) \n        : ht_(h), it_(i) \n        {\n        }\n\titerator(const iterator &rhs) \n        : ht_(rhs.ht_), it_(rhs.it_) \n        {\n        }\n\tvoid operator++() \n        { \n            it_ = pj_hash_next(ht_, it_); \n        }\n\tbool operator==(const iterator &rhs) \n        { \n            return ht_ == rhs.ht_ && it_ == rhs.it_; \n        }\n\titerator & operator=(const iterator &rhs) \n        { \n            ht_=rhs.ht_; it_=rhs.it_; \n            return *this; \n        }\n    private:\n\tpj_hash_table_t *ht_;\n\tpj_hash_iterator_t it_val_;\n\tpj_hash_iterator_t *it_;\n\n\tfriend class Pj_Hash_Table;\n    };\n\n    //\n    // Construct hash table.\n    //\n    Pj_Hash_Table(Pj_Pool *pool, unsigned size)\n    {\n\ttable_ = pj_hash_create(pool->pool_(), size);\n    }\n\n    //\n    // Destroy hash table.\n    //\n    ~Pj_Hash_Table()\n    {\n    }\n\n    //\n    // Calculate hash value.\n    //\n    static pj_uint32_t calc( pj_uint32_t initial_hval, \n                             const void *key, \n                             unsigned keylen = PJ_HASH_KEY_STRING)\n    {\n\treturn pj_hash_calc(initial_hval, key, keylen);\n    }\n\n    //\n    // Return pjlib compatible hash table object.\n    //\n    pj_hash_table_t *pj_hash_table_t_()\n    {\n\treturn table_;\n    }\n\n    //\n    // Get the value associated with the specified key.\n    //\n    void *get(const void *key, unsigned keylen = PJ_HASH_KEY_STRING)\n    {\n\treturn pj_hash_get(table_, key, keylen);\n    }\n\n    //\n    // Associate a value with a key.\n    // Set the value to NULL to delete the key from the hash table.\n    //\n    void set(Pj_Pool *pool, \n             const void *key, \n             void *value,\n             unsigned keylen = PJ_HASH_KEY_STRING)\n    {\n\tpj_hash_set(pool->pool_(), table_, key, keylen, value);\n    }\n\n    //\n    // Get number of items in the hash table.\n    //\n    unsigned count()\n    {\n\treturn pj_hash_count(table_);\n    }\n\n    //\n    // Iterate hash table.\n    //\n    iterator begin()\n    {\n\titerator it(table_, NULL);\n\tit.it_ = pj_hash_first(table_, &it.it_val_);\n\treturn it;\n    }\n\n    //\n    // End of items.\n    //\n    iterator end()\n    {\n\treturn iterator(table_, NULL);\n    }\n\nprivate:\n    pj_hash_table_t *table_;\n};\n\n\n#endif\t/* __PJPP_HASH_HPP__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj++/list.hpp",
    "content": "/* $Id: list.hpp 2394 2008-12-23 17:27:53Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJPP_LIST_HPP__\n#define __PJPP_LIST_HPP__\n\n#include <pj/list.h>\n#include <pj++/pool.hpp>\n\n\n//\n// Linked-list.\n//\n// Note:\n//  List_Node must have public member next and prev. Normally\n//  it will be declared like:\n//\n//  struct my_node\n//  {\n//      PJ_DECL_LIST_MEMBER(struct my_node);\n//      ..\n//  };\n//\n//\ntemplate <class List_Node>\nclass Pj_List : public Pj_Object\n{\npublic:\n    //\n    // List const_iterator.\n    //\n    class const_iterator\n    {\n    public:\n\tconst_iterator() \n            : node_(NULL) \n        {}\n\tconst_iterator(const List_Node *nd) \n            : node_((List_Node*)nd) \n        {}\n\tconst List_Node * operator *() \n        { \n            return node_; \n        }\n\tconst List_Node * operator -> () \n        { \n            return node_; \n        }\n\tconst_iterator operator++() \n        { \n            return const_iterator((const List_Node *)node_->next); \n        }\n\tbool operator==(const const_iterator &rhs) \n        { \n            return node_ == rhs.node_; \n        }\n\tbool operator!=(const const_iterator &rhs) \n        { \n            return node_ != rhs.node_; \n        }\n\n    protected:\n\tList_Node *node_;\n    };\n\n    //\n    // List iterator.\n    //\n    class iterator : public const_iterator\n    {\n    public:\n\titerator() \n        {}\n\titerator(List_Node *nd) \n            : const_iterator(nd) \n        {}\n\tList_Node * operator *() \n        { \n            return node_; \n        }\n\tList_Node * operator -> () \n        { \n            return node_; \n        }\n\titerator operator++() \n        { \n            return iterator((List_Node*)node_->next); \n        }\n\tbool operator==(const iterator &rhs) \n        { \n            return node_ == rhs.node_; \n        }\n\tbool operator!=(const iterator &rhs) \n        { \n            return node_ != rhs.node_; \n        }\n    };\n\n    //\n    // Default constructor.\n    //\n    Pj_List() \n    { \n        pj_list_init(&root_); \n        if (0) compiletest(); \n    }\n\n    //\n    // You can cast Pj_List to pj_list\n    //\n    operator pj_list&()\n    {\n\treturn (pj_list&)root_;\n    }\n    operator const pj_list&()\n    {\n\treturn (const pj_list&)root_;\n    }\n\n    //\n    // You can cast Pj_List to pj_list* too\n    //\n    operator pj_list*()\n    {\n\treturn (pj_list*)&root_;\n    }\n    operator const pj_list*()\n    {\n\treturn (const pj_list*)&root_;\n    }\n\n    //\n    // Check if list is empty.\n    // \n    bool empty() const\n    {\n\treturn pj_list_empty(&root_);\n    }\n\n    //\n    // Get first element.\n    //\n    iterator begin()\n    {\n\treturn iterator(root_.next);\n    }\n\n    //\n    // Get first element.\n    //\n    const_iterator begin() const\n    {\n\treturn const_iterator(root_.next);\n    }\n\n    //\n    // Get end-of-element\n    //\n    const_iterator end() const\n    {\n\treturn const_iterator((List_Node*)&root_);\n    }\n\n    //\n    // Get end-of-element\n    //\n    iterator end()\n    {\n\treturn iterator((List_Node*)&root_);\n    }\n\n    //\n    // Insert node.\n    //\n    void insert_before (iterator &pos, List_Node *node)\n    {\n\tpj_list_insert_before( *pos, node );\n    }\n\n    //\n    // Insert node.\n    //\n    void insert_after(iterator &pos, List_Node *node)\n    {\n\tpj_list_insert_after(*pos, node);\n    }\n\n    //\n    // Merge list.\n    //\n    void merge_first(List_Node *list2)\n    {\n\tpj_list_merge_first(&root_, list2);\n    }\n\n    //\n    // Merge list.\n    //\n    void merge_last(Pj_List *list)\n    {\n\tpj_list_merge_last(&root_, &list->root_);\n    }\n\n    //\n    // Insert list.\n    //\n    void insert_nodes_before(iterator &pos, Pj_List *list2)\n    {\n\tpj_list_insert_nodes_before(*pos, &list2->root_);\n    }\n\n    //\n    // Insert list.\n    //\n    void insert_nodes_after(iterator &pos, Pj_List *list2)\n    {\n\tpj_list_insert_nodes_after(*pos, &list2->root_);\n    }\n\n    //\n    // Erase an element.\n    //\n    void erase(iterator &it)\n    {\n\tpj_list_erase(*it);\n    }\n\n    //\n    // Get first element.\n    //\n    List_Node *front()\n    {\n\treturn root_.next;\n    }\n\n    //\n    // Get first element.\n    //\n    const List_Node *front() const\n    {\n\treturn root_.next;\n    }\n\n    //\n    // Remove first element.\n    //\n    void pop_front()\n    {\n\tpj_list_erase(root_.next);\n    }\n\n    //\n    // Get last element.\n    //\n    List_Node *back()\n    {\n\treturn root_.prev;\n    }\n\n    //\n    // Get last element.\n    //\n    const List_Node *back() const\n    {\n\treturn root_.prev;\n    }\n\n    //\n    // Remove last element.\n    //\n    void pop_back()\n    {\n\tpj_list_erase(root_.prev);\n    }\n\n    //\n    // Find a node.\n    //\n    iterator find(List_Node *node)\n    {\n\tList_Node *n = pj_list_find_node(&root_, node);\n\treturn n ? iterator(n) : end();\n    }\n\n    //\n    // Find a node.\n    //\n    const_iterator find(List_Node *node) const\n    {\n\tList_Node *n = pj_list_find_node(&root_, node);\n\treturn n ? const_iterator(n) : end();\n    }\n\n    //\n    // Insert a node in the back.\n    //\n    void push_back(List_Node *node)\n    {\n\tpj_list_insert_after(root_.prev, node);\n    }\n\n    //\n    // Insert a node in the front.\n    //\n    void push_front(List_Node *node)\n    {\n\tpj_list_insert_before(root_.next, node);\n    }\n\n    //\n    // Remove all elements.\n    //\n    void clear()\n    {\n\troot_.next = &root_;\n\troot_.prev = &root_;\n    }\n\nprivate:\n    struct RootNode\n    {\n\tPJ_DECL_LIST_MEMBER(List_Node);\n    } root_;\n\n    void compiletest()\n    {\n\t// If you see error in this line, \n\t// it's because List_Node is not derived from Pj_List_Node.\n\tList_Node *n = (List_Node*)0;\n\tn = (List_Node *)n->next; n = (List_Node *)n->prev;\n    }\n};\n\n\n#endif\t/* __PJPP_LIST_HPP__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj++/lock.hpp",
    "content": "/* $Id: lock.hpp 2394 2008-12-23 17:27:53Z bennylp $  */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJPP_LOCK_HPP__\n#define __PJPP_LOCK_HPP__\n\n#include <pj++/types.hpp>\n#include <pj/lock.h>\n#include <pj++/pool.hpp>\n\n//////////////////////////////////////////////////////////////////////////////\n// Lock object.\n//\nclass Pj_Lock : public Pj_Object\n{\npublic:\n    //\n    // Constructor.\n    //\n    explicit Pj_Lock(pj_lock_t *lock)\n        : lock_(lock)\n    {\n    }\n\n    //\n    // Destructor.\n    //\n    ~Pj_Lock()\n    {\n        if (lock_)\n            pj_lock_destroy(lock_);\n    }\n\n    //\n    // Get pjlib compatible lock object.\n    //\n    pj_lock_t *pj_lock_t_()\n    {\n        return lock_;\n    }\n\n    //\n    // acquire lock.\n    //\n    pj_status_t acquire()\n    {\n        return pj_lock_acquire(lock_);\n    }\n\n    //\n    // release lock,.\n    //\n    pj_status_t release()\n    {\n        return pj_lock_release(lock_);\n    }\n\nprotected:\n    pj_lock_t *lock_;\n};\n\n\n//////////////////////////////////////////////////////////////////////////////\n// Null lock object.\n//\nclass Pj_Null_Lock : public Pj_Lock\n{\npublic:\n    //\n    // Default constructor.\n    //\n    explicit Pj_Null_Lock(Pj_Pool *pool, const char *name = NULL)\n        : Pj_Lock(NULL)\n    {\n        pj_lock_create_null_mutex(pool->pool_(), name, &lock_);\n    }\n};\n\n//////////////////////////////////////////////////////////////////////////////\n// Simple mutex lock object.\n//\nclass Pj_Simple_Mutex_Lock : public Pj_Lock\n{\npublic:\n    //\n    // Default constructor.\n    //\n    explicit Pj_Simple_Mutex_Lock(Pj_Pool *pool, const char *name = NULL)\n        : Pj_Lock(NULL)\n    {\n        pj_lock_create_simple_mutex(pool->pool_(), name, &lock_);\n    }\n};\n\n//////////////////////////////////////////////////////////////////////////////\n// Recursive mutex lock object.\n//\nclass Pj_Recursive_Mutex_Lock : public Pj_Lock\n{\npublic:\n    //\n    // Default constructor.\n    //\n    explicit Pj_Recursive_Mutex_Lock(Pj_Pool *pool, const char *name = NULL)\n        : Pj_Lock(NULL)\n    {\n        pj_lock_create_recursive_mutex(pool->pool_(), name, &lock_);\n    }\n};\n\n//////////////////////////////////////////////////////////////////////////////\n// Semaphore lock object.\n//\nclass Pj_Semaphore_Lock : public Pj_Lock\n{\npublic:\n    //\n    // Default constructor.\n    //\n    explicit Pj_Semaphore_Lock(Pj_Pool *pool, \n                               unsigned max=PJ_MAXINT32,\n                               unsigned initial=0,\n                               const char *name=NULL)\n        : Pj_Lock(NULL)\n    {\n        pj_lock_create_semaphore(pool->pool_(), name, initial, max, &lock_);\n    }\n};\n\n\n\n#endif\t/* __PJPP_LOCK_HPP__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj++/os.hpp",
    "content": "/* $Id: os.hpp 2394 2008-12-23 17:27:53Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJPP_OS_HPP__\n#define __PJPP_OS_HPP__\n\n#include <pj/os.h>\n#include <pj/string.h>\n#include <pj++/types.hpp>\n#include <pj++/pool.hpp>\n\nclass Pj_Thread;\n\n//\n// Thread API.\n//\nclass Pj_Thread_API\n{\npublic:\n    //\n    // Create a thread.\n    //\n    static pj_status_t create( Pj_Pool *pool, pj_thread_t **thread,\n                               pj_thread_proc *proc, void *arg,\n                               unsigned flags = 0,\n                               const char *name = NULL,\n                               pj_size_t stack_size = 0 )\n    {\n        return pj_thread_create(pool->pool_(), name, proc, arg, stack_size,\n                                flags, thread);\n    }\n\n    //\n    // Register a thread.\n    //\n    static pj_status_t register_this_thread( pj_thread_desc desc,\n                                             pj_thread_t **thread,\n                                             const char *name = NULL )\n    {\n        return pj_thread_register( name, desc, thread );\n    }\n\n    //\n    // Get current thread.\n    // Will return pj_thread_t (sorry folks, not Pj_Thread).\n    //\n    static pj_thread_t *this_thread()\n    {\n        return pj_thread_this();\n    }\n\n    //\n    // Get thread name.\n    //\n    static const char *get_name(pj_thread_t *thread)\n    {\n        return pj_thread_get_name(thread);\n    }\n\n    //\n    // Resume thread.\n    //\n    static pj_status_t resume(pj_thread_t *thread)\n    {\n        return pj_thread_resume(thread);\n    }\n\n    //\n    // Sleep.\n    //\n    static pj_status_t sleep(unsigned msec)\n    {\n\treturn pj_thread_sleep(msec);\n    }\n\n    //\n    // Join the specified thread.\n    //\n    static pj_status_t join(pj_thread_t *thread)\n    {\n        return pj_thread_join(thread);\n    }\n\n    //\n    // Destroy thread\n    //\n    static pj_status_t destroy(pj_thread_t *thread)\n    {\n        return pj_thread_destroy(thread);\n    }\n};\n\n\n\n//\n// Thread object.\n//\n// How to use:\n//  Derive a class from this class, then override main().\n//\nclass Pj_Thread : public Pj_Object\n{\npublic:\n    enum Flags\n    {\n\tFLAG_SUSPENDED = PJ_THREAD_SUSPENDED\n    };\n\n    //\n    // Default constructor.\n    //\n    Pj_Thread()\n        : thread_(NULL)\n    {\n    }\n\n    //\n    // Destroy thread.\n    //\n    ~Pj_Thread()\n    {\n        destroy();\n    }\n\n    //\n    // This is the main thread function.\n    //\n    virtual int main() = 0;\n\n    //\n    // Start a thread.\n    //\n    pj_status_t create( Pj_Pool *pool, \n                        unsigned flags = 0,\n                        const char *thread_name = NULL,\n\t\t\tpj_size_t stack_size = PJ_THREAD_DEFAULT_STACK_SIZE)\n    {\n        destroy();\n        return Pj_Thread_API::create( pool, &thread_, &thread_proc, this,\n                                      flags, thread_name, stack_size);\n    }\n\n    //\n    // Get pjlib compatible thread object.\n    //\n    pj_thread_t *pj_thread_t_()\n    {\n\treturn thread_;\n    }\n\n    //\n    // Get thread name.\n    //\n    const char *get_name()\n    {\n        return Pj_Thread_API::get_name(thread_);\n    }\n\n    //\n    // Resume a suspended thread.\n    //\n    pj_status_t resume()\n    {\n        return Pj_Thread_API::resume(thread_);\n    }\n\n    //\n    // Join this thread.\n    //\n    pj_status_t join()\n    {\n        return Pj_Thread_API::join(thread_);\n    }\n\n    //\n    // Destroy thread.\n    //\n    pj_status_t destroy()\n    {\n        if (thread_) {\n            Pj_Thread_API::destroy(thread_);\n            thread_ = NULL;\n        }\n    }\n\nprotected:\n    pj_thread_t *thread_;\n\n    static int PJ_THREAD_FUNC thread_proc(void *obj)\n    {\n        Pj_Thread *thread_class = (Pj_Thread*)obj;\n        return thread_class->main();\n    }\n};\n\n\n//\n// External Thread\n//  (threads that were started by external means, i.e. not \n//   with Pj_Thread::create).\n//\n// This class will normally be defined as local variable in\n// external thread's stack, normally inside thread's main proc.\n// But be aware that the handle will be destroyed on destructor!\n//\nclass Pj_External_Thread : public Pj_Thread\n{\npublic:\n    Pj_External_Thread()\n    {\n    }\n\n    //\n    // Register external thread so that pjlib functions can work\n    // in that thread.\n    //\n    pj_status_t register_this_thread( const char *name=NULL )\n    {\n        return Pj_Thread_API::register_this_thread(desc_, &thread_,name);\n    }\n\nprivate:\n    pj_thread_desc desc_;\n};\n\n\n//\n// Thread specific data/thread local storage/TLS.\n//\nclass Pj_Thread_Local_API\n{\npublic:\n    //\n    // Allocate thread local storage (TLS) index.\n    //\n    static pj_status_t alloc(long *index)\n    {\n        return pj_thread_local_alloc(index);\n    }\n\n    //\n    // Free TLS index.\n    //\n    static void free(long index)\n    {\n        pj_thread_local_free(index);\n    }\n\n    //\n    // Set thread specific data.\n    //\n    static pj_status_t set(long index, void *value)\n    {\n        return pj_thread_local_set(index, value);\n    }\n\n    //\n    // Get thread specific data.\n    //\n    static void *get(long index)\n    {\n        return pj_thread_local_get(index);\n    }\n\n};\n\n//\n// Atomic variable\n//\n// How to use:\n//   Pj_Atomic_Var var(pool, 0);\n//   var.set(..);\n//\nclass Pj_Atomic_Var : public Pj_Object\n{\npublic:\n    //\n    // Default constructor, initialize variable with NULL.\n    //\n    Pj_Atomic_Var()\n        : var_(NULL)\n    {\n    }\n\n    //\n    // Construct atomic variable.\n    //\n    Pj_Atomic_Var(Pj_Pool *pool, pj_atomic_value_t value)\n        : var_(NULL)\n    {\n        create(pool, value);\n    }\n\n    //\n    // Destructor.\n    //\n    ~Pj_Atomic_Var()\n    {\n        destroy();\n    }\n\n    //\n    // Create atomic variable.\n    //\n    pj_status_t create( Pj_Pool *pool, pj_atomic_value_t value)\n    {\n        destroy();\n\treturn pj_atomic_create(pool->pool_(), value, &var_);\n    }\n\n    //\n    // Destroy.\n    //\n    void destroy()\n    {\n        if (var_) {\n            pj_atomic_destroy(var_);\n            var_ = NULL;\n        }\n    }\n\n    //\n    // Get pjlib compatible atomic variable.\n    //\n    pj_atomic_t *pj_atomic_t_()\n    {\n\treturn var_;\n    }\n\n    //\n    // Set the value.\n    //\n    void set(pj_atomic_value_t val)\n    {\n\tpj_atomic_set(var_, val);\n    }\n\n    //\n    // Get the value.\n    //\n    pj_atomic_value_t get()\n    {\n\treturn pj_atomic_get(var_);\n    }\n\n    //\n    // Increment.\n    //\n    void inc()\n    {\n\tpj_atomic_inc(var_);\n    }\n\n    //\n    // Increment and get the result.\n    //\n    pj_atomic_value_t inc_and_get()\n    {\n        return pj_atomic_inc_and_get(var_);\n    }\n\n    //\n    // Decrement.\n    //\n    void dec()\n    {\n\tpj_atomic_dec(var_);\n    }\n\n    //\n    // Decrement and get the result.\n    //\n    pj_atomic_value_t dec_and_get()\n    {\n        return pj_atomic_dec_and_get(var_);\n    }\n\n    //\n    // Add the variable.\n    //\n    void add(pj_atomic_value_t value)\n    {\n        pj_atomic_add(var_, value);\n    }\n\n    //\n    // Add the variable and get the value.\n    //\n    pj_atomic_value_t add_and_get(pj_atomic_value_t value)\n    {\n        return pj_atomic_add_and_get(var_, value );\n    }\n\nprivate:\n    pj_atomic_t *var_;\n};\n\n\n//\n// Mutex\n//\nclass Pj_Mutex : public Pj_Object\n{\npublic:\n    //\n    // Mutex type.\n    //\n    enum Type\n    {\n\tDEFAULT = PJ_MUTEX_DEFAULT,\n\tSIMPLE = PJ_MUTEX_SIMPLE,\n\tRECURSE = PJ_MUTEX_RECURSE,\n    };\n\n    //\n    // Default constructor will create default mutex.\n    //\n    explicit Pj_Mutex(Pj_Pool *pool, Type type = DEFAULT,\n                      const char *name = NULL)\n        : mutex_(NULL)\n    {\n        create(pool, type, name);\n    }\n\n    //\n    // Destructor.\n    //\n    ~Pj_Mutex()\n    {\n        destroy();\n    }\n\n    //\n    // Create mutex.\n    //\n    pj_status_t create( Pj_Pool *pool, Type type, const char *name = NULL)\n    {\n        destroy();\n\treturn pj_mutex_create( pool->pool_(), name, type,\n                                &mutex_ );\n    }\n\n    //\n    // Create simple mutex.\n    //\n    pj_status_t create_simple( Pj_Pool *pool,const char *name = NULL)\n    {\n        return create(pool, SIMPLE, name);\n    }\n\n    //\n    // Create recursive mutex.\n    //\n    pj_status_t create_recursive( Pj_Pool *pool, const char *name = NULL )\n    {\n        return create(pool, RECURSE, name);\n    }\n\n    //\n    // Get pjlib compatible mutex object.\n    //\n    pj_mutex_t *pj_mutex_t_()\n    {\n\treturn mutex_;\n    }\n\n    //\n    // Destroy mutex.\n    //\n    void destroy()\n    {\n        if (mutex_) {\n\t    pj_mutex_destroy(mutex_);\n            mutex_ = NULL;\n        }\n    }\n\n    //\n    // Lock mutex.\n    //\n    pj_status_t acquire()\n    {\n\treturn pj_mutex_lock(mutex_);\n    }\n\n    //\n    // Unlock mutex.\n    //\n    pj_status_t release()\n    {\n\treturn pj_mutex_unlock(mutex_);\n    }\n\n    //\n    // Try locking the mutex.\n    //\n    pj_status_t tryacquire()\n    {\n\treturn pj_mutex_trylock(mutex_);\n    }\n\nprivate:\n    pj_mutex_t *mutex_;\n};\n\n\n//\n// Semaphore\n//\nclass Pj_Semaphore : public Pj_Object\n{\npublic:\n    //\n    // Construct semaphore\n    //\n    Pj_Semaphore(Pj_Pool *pool, unsigned max,\n                 unsigned initial = 0, const char *name = NULL)\n    : sem_(NULL)\n    {\n\tcreate(pool, max, initial, name);\n    }\n\n    //\n    // Destructor.\n    //\n    ~Pj_Semaphore()\n    {\n        destroy();\n    }\n\n    //\n    // Create semaphore\n    //\n    pj_status_t create( Pj_Pool *pool, unsigned max,\n                        unsigned initial = 0, const char *name = NULL )\n    {\n        destroy();\n\treturn pj_sem_create( pool->pool_(), name, initial, max, &sem_);\n    }\n\n    //\n    // Destroy semaphore.\n    //\n    void destroy()\n    {\n        if (sem_) {\n            pj_sem_destroy(sem_);\n            sem_ = NULL;\n        }\n    }\n\n    //\n    // Get pjlib compatible semaphore object.\n    //\n    pj_sem_t *pj_sem_t_()\n    {\n\treturn (pj_sem_t*)this;\n    }\n\n    //\n    // Wait semaphore.\n    //\n    pj_status_t wait()\n    {\n\treturn pj_sem_wait(this->pj_sem_t_());\n    }\n\n    //\n    // Wait semaphore.\n    //\n    pj_status_t acquire()\n    {\n\treturn wait();\n    }\n\n    //\n    // Try wait semaphore.\n    //\n    pj_status_t trywait()\n    {\n\treturn pj_sem_trywait(this->pj_sem_t_());\n    }\n\n    //\n    // Try wait semaphore.\n    //\n    pj_status_t tryacquire()\n    {\n\treturn trywait();\n    }\n\n    //\n    // Post semaphore.\n    //\n    pj_status_t post()\n    {\n\treturn pj_sem_post(this->pj_sem_t_());\n    }\n\n    //\n    // Post semaphore.\n    //\n    pj_status_t release()\n    {\n\treturn post();\n    }\n\nprivate:\n    pj_sem_t *sem_;\n};\n\n\n//\n// Event object.\n//\nclass Pj_Event\n{\npublic:\n    //\n    // Construct event object.\n    //\n    Pj_Event( Pj_Pool *pool, bool manual_reset = false,\n              bool initial = false, const char *name = NULL )\n    : event_(NULL)\n    {\n        create(pool, manual_reset, initial, name);\n    }\n\n    //\n    // Destructor.\n    //\n    ~Pj_Event()\n    {\n        destroy();\n    }\n\n    //\n    // Create event object.\n    //\n    pj_status_t create( Pj_Pool *pool, bool manual_reset = false, \n                        bool initial = false, const char *name = NULL)\n    {\n        destroy();\n\treturn pj_event_create(pool->pool_(), name, manual_reset, initial,\n                               &event_);\n    }\n\n    //\n    // Get pjlib compatible event object.\n    //\n    pj_event_t *pj_event_t_()\n    {\n\treturn event_;\n    }\n\n    //\n    // Destroy event object.\n    //\n    void destroy()\n    {\n        if (event_) {\n\t    pj_event_destroy(event_);\n            event_ = NULL;\n        }\n    }\n\n    //\n    // Wait.\n    //\n    pj_status_t wait()\n    {\n\treturn pj_event_wait(event_);\n    }\n\n    //\n    // Try wait.\n    //\n    pj_status_t trywait()\n    {\n\treturn pj_event_trywait(event_);\n    }\n\n    //\n    // Set event state to signalled.\n    //\n    pj_status_t set()\n    {\n\treturn pj_event_set(this->pj_event_t_());\n    }\n\n    //\n    // Release one waiting thread.\n    //\n    pj_status_t pulse()\n    {\n\treturn pj_event_pulse(this->pj_event_t_());\n    }\n\n    //\n    // Set a non-signalled.\n    //\n    pj_status_t reset()\n    {\n\treturn pj_event_reset(this->pj_event_t_());\n    }\n\nprivate:\n    pj_event_t *event_;\n};\n\n//\n// Timestamp\n//\nclass Pj_Timestamp\n{\npublic:\n    pj_status_t get_timestamp()\n    {\n\treturn pj_get_timestamp(&ts_);\n    }\n\n    Pj_Timestamp& operator += (const Pj_Timestamp &rhs)\n    {\n\tpj_add_timestamp(&ts_, &rhs.ts_);\n\treturn *this;\n    }\n\n    Pj_Timestamp& operator -= (const Pj_Timestamp &rhs)\n    {\n\tpj_sub_timestamp(&ts_, &rhs.ts_);\n\treturn *this;\n    }\n\n    Pj_Time_Val to_time() const\n    {\n\tPj_Timestamp zero;\n\tpj_memset(&zero, 0, sizeof(zero));\n\treturn Pj_Time_Val(pj_elapsed_time(&zero.ts_, &ts_));\n    }\n\n    pj_uint32_t to_msec() const\n    {\n\tPj_Timestamp zero;\n\tpj_memset(&zero, 0, sizeof(zero));\n\treturn pj_elapsed_msec(&zero.ts_, &ts_);\n    }\n\n    pj_uint32_t to_usec() const\n    {\n\tPj_Timestamp zero;\n\tpj_memset(&zero, 0, sizeof(zero));\n\treturn pj_elapsed_usec(&zero.ts_, &ts_);\n    }\n\n    pj_uint32_t to_nanosec() const\n    {\n\tPj_Timestamp zero;\n\tpj_memset(&zero, 0, sizeof(zero));\n\treturn pj_elapsed_nanosec(&zero.ts_, &ts_);\n    }\n\n    pj_uint32_t to_cycle() const\n    {\n\tPj_Timestamp zero;\n\tpj_memset(&zero, 0, sizeof(zero));\n\treturn pj_elapsed_cycle(&zero.ts_, &ts_);\n    }\n\nprivate:\n    pj_timestamp    ts_;\n};\n\n\n//\n// OS abstraction.\n//\nclass Pj_OS_API\n{\npublic:\n    //\n    // Get current time.\n    //\n    static pj_status_t gettimeofday( Pj_Time_Val *tv )\n    {\n\treturn pj_gettimeofday(tv);\n    }\n\n    //\n    // Parse to time of day.\n    //\n    static pj_status_t time_decode( const Pj_Time_Val *tv, \n                                    pj_parsed_time *pt )\n    {\n\treturn pj_time_decode(tv, pt);\n    }\n\n    //\n    // Parse from time of day.\n    //\n    static pj_status_t time_encode( const pj_parsed_time *pt, \n                                    Pj_Time_Val *tv)\n    {\n\treturn pj_time_encode(pt, tv);\n    }\n\n    //\n    // Convert to GMT.\n    //\n    static pj_status_t time_local_to_gmt( Pj_Time_Val *tv )\n    {\n\treturn pj_time_local_to_gmt( tv );\n    }\n\n    //\n    // Convert time to local.\n    //\n    static pj_status_t time_gmt_to_local( Pj_Time_Val *tv) \n    {\n\treturn pj_time_gmt_to_local( tv );\n    }\n};\n\n//\n// Timeval inlines.\n//\ninline pj_status_t Pj_Time_Val::gettimeofday()\n{\n    return Pj_OS_API::gettimeofday(this);\n}\n\ninline pj_parsed_time Pj_Time_Val::decode()\n{\n    pj_parsed_time pt;\n    Pj_OS_API::time_decode(this, &pt);\n    return pt;\n}\n\ninline pj_status_t Pj_Time_Val::encode(const pj_parsed_time *pt)\n{\n    return Pj_OS_API::time_encode(pt, this);\n}\n\ninline pj_status_t Pj_Time_Val::to_gmt()\n{\n    return Pj_OS_API::time_local_to_gmt(this);\n}\n\ninline pj_status_t Pj_Time_Val::to_local()\n{\n    return Pj_OS_API::time_gmt_to_local(this);\n}\n\n#endif\t/* __PJPP_OS_HPP__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj++/pool.hpp",
    "content": "/* $Id: pool.hpp 2394 2008-12-23 17:27:53Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJPP_POOL_HPP__\n#define __PJPP_POOL_HPP__\n\n#include <pj/pool.h>\n\nclass Pj_Pool;\nclass Pj_Caching_Pool;\n\n//\n// Base class for all Pjlib objects\n//\nclass Pj_Object\n{\npublic:\n    void *operator new(unsigned int class_size, Pj_Pool *pool);\n    void *operator new(unsigned int class_size, Pj_Pool &pool);\n\n    void operator delete(void*)\n    {\n    }\n\n    void operator delete(void*, Pj_Pool*)\n    {\n    }\n\n    void operator delete(void*, Pj_Pool&)\n    {\n    }\n\n    //\n    // Inline implementations at the end of this file.\n    //\n\nprivate:\n    // Can not use normal new operator; must use pool.\n    // e.g.:\n    //   obj = new(pool) Pj_The_Object(pool, ...);\n    //\n    void *operator new(unsigned int)\n    {}\n};\n\n\n//\n// Pool.\n//\nclass Pj_Pool : public Pj_Object\n{\npublic:\n    //\n    // Default constructor, initializes internal pool to NULL.\n    // Application must call attach() some time later.\n    //\n    Pj_Pool()\n        : p_(NULL)\n    {\n    }\n\n    //\n    // Create pool.\n    //\n    Pj_Pool(Pj_Caching_Pool &caching_pool,\n            pj_size_t initial_size, \n            pj_size_t increment_size, \n            const char *name = NULL, \n            pj_pool_callback *callback = NULL);\n\n    //\n    // Construct from existing pool.\n    //\n    explicit Pj_Pool(pj_pool_t *pool)\n        : p_(pool)\n    {\n    }\n\n    //\n    // Attach existing pool.\n    //\n    void attach(pj_pool_t *pool)\n    {\n        p_ = pool;\n    }\n\n    //\n    // Destructor.\n    //\n    // Release pool back to factory. Remember: if you delete pool, then \n    // make sure that all objects that have been allocated from this pool\n    // have been properly destroyed.\n    //\n    // This is where C++ is trickier than plain C!!\n    //\n    ~Pj_Pool()\n    {\n        if (p_)\n\t    pj_pool_release(p_);\n    }\n\n    //\n    // Get name.\n    //\n    const char *getobjname() const\n    {\n\treturn pj_pool_getobjname(p_);\n    }\n\n    //\n    // You can cast Pj_Pool to pj_pool_t*\n    //\n    operator pj_pool_t*()\n    {\n\treturn p_;\n    }\n\n    //\n    // Get pjlib compatible pool object.\n    //\n    pj_pool_t *pool_()\n    {\n\treturn p_;\n    }\n\n    //\n    // Get pjlib compatible pool object.\n    //\n    const pj_pool_t *pool_() const\n    {\n\treturn p_;\n    }\n\n    //\n    // Get pjlib compatible pool object.\n    //\n    pj_pool_t *pj_pool_t_()\n    {\n\treturn p_;\n    }\n\n    //\n    // Reset pool.\n    //\n    void reset()\n    {\n\tpj_pool_reset(p_);\n    }\n\n    //\n    // Get current capacity.\n    //\n    pj_size_t get_capacity()\n    {\n\tpj_pool_get_capacity(p_);\n    }\n\n    //\n    // Get current total bytes allocated from the pool.\n    //\n    pj_size_t get_used_size()\n    {\n\tpj_pool_get_used_size(p_);\n    }\n\n    //\n    // Allocate.\n    //\n    void *alloc(pj_size_t size)\n    {\n\treturn pj_pool_alloc(p_, size);\n    }\n\n    //\n    // Allocate elements and zero fill the memory.\n    //\n    void *calloc(pj_size_t count, pj_size_t elem)\n    {\n\treturn pj_pool_calloc(p_, count, elem);\n    }\n\n    //\n    // Allocate and zero fill memory.\n    //\n    void *zalloc(pj_size_t size)\n    {\n        return pj_pool_zalloc(p_, size);\n    }\n\nprivate:\n    pj_pool_t *p_;\n};\n\n\n//\n// Caching pool.\n//\nclass Pj_Caching_Pool\n{\npublic:\n    //\n    // Construct caching pool.\n    //\n    Pj_Caching_Pool( pj_size_t cache_capacity = 0,\n\t             const pj_pool_factory_policy *pol=&pj_pool_factory_default_policy)\n    {\n\tpj_caching_pool_init(&cp_, pol, cache_capacity);\n    }\n\n    //\n    // Destroy caching pool.\n    //\n    ~Pj_Caching_Pool()\n    {\n\tpj_caching_pool_destroy(&cp_);\n    }\n\n    //\n    // Create pool.\n    //\n    pj_pool_t *create_pool( pj_size_t initial_size, \n                            pj_size_t increment_size, \n                            const char *name = NULL, \n                            pj_pool_callback *callback = NULL)\n    {\n\treturn (pj_pool_t*)(*cp_.factory.create_pool)(&cp_.factory, name, \n                                                     initial_size, \n                                                     increment_size, \n                                                     callback);\n    }\n\nprivate:\n    pj_caching_pool cp_;\n};\n\n//\n// Inlines for Pj_Object\n//\ninline void *Pj_Object::operator new(unsigned int class_size, Pj_Pool *pool)\n{\n    return pool->alloc(class_size);\n}\ninline void *Pj_Object::operator new(unsigned int class_size, Pj_Pool &pool)\n{\n    return pool.alloc(class_size);\n}\n\n//\n// Inlines for Pj_Pool\n//\ninline Pj_Pool::Pj_Pool( Pj_Caching_Pool &caching_pool,\n                         pj_size_t initial_size, \n                         pj_size_t increment_size, \n                         const char *name, \n                         pj_pool_callback *callback)\n{\n    p_ = caching_pool.create_pool(initial_size, increment_size, name,\n                                  callback);\n}\n\n\n#endif\t/* __PJPP_POOL_HPP__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj++/proactor.hpp",
    "content": "/* $Id: proactor.hpp 2394 2008-12-23 17:27:53Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJPP_PROACTOR_HPP__\n#define __PJPP_PROACTOR_HPP__\n\n#include <pj/ioqueue.h>\n#include <pj++/pool.hpp>\n#include <pj++/sock.hpp>\n#include <pj++/timer.hpp>\n#include <pj/errno.h>\n\nclass Pj_Proactor;\nclass Pj_Event_Handler;\n\n\n//////////////////////////////////////////////////////////////////////////////\n// Asynchronous operation key.\n//\n// Applications may inheric this class to put their application\n// specific data.\n//\nclass Pj_Async_Op : public pj_ioqueue_op_key_t\n{\npublic:\n    //\n    // Construct with null handler.\n    // App must call set_handler() before use.\n    //\n    Pj_Async_Op()\n        : handler_(NULL)\n    {\n\tpj_ioqueue_op_key_init(this, sizeof(*this));\n    }\n\n    //\n    // Constructor.\n    //\n    explicit Pj_Async_Op(Pj_Event_Handler *handler)\n        : handler_(handler)\n    {\n\tpj_ioqueue_op_key_init(this, sizeof(*this));\n    }\n\n    //\n    // Set handler.\n    //\n    void set_handler(Pj_Event_Handler *handler)\n    {\n        handler_ = handler;\n    }\n\n    //\n    // Check whether operation is still pending for this key.\n    //\n    bool is_pending();\n\n    //\n    // Cancel the operation.\n    //\n    bool cancel(pj_ssize_t bytes_status=-PJ_ECANCELLED);\n\nprotected:\n    Pj_Event_Handler *handler_;\n};\n\n\n//////////////////////////////////////////////////////////////////////////////\n// Event handler.\n//\n// Applications should inherit this class to receive various event\n// notifications.\n//\n// Applications should implement get_socket_handle().\n//\nclass Pj_Event_Handler : public Pj_Object\n{\n    friend class Pj_Proactor;\npublic:\n    //\n    // Default constructor.\n    //\n    Pj_Event_Handler()\n        : key_(NULL)\n    {\n        pj_memset(&timer_, 0, sizeof(timer_));\n        timer_.user_data = this;\n        timer_.cb = &timer_callback;\n    }\n    \n    //\n    // Destroy.\n    //\n    virtual ~Pj_Event_Handler()\n    {\n        unregister();\n    }\n\n    //\n    // Unregister this handler from the ioqueue.\n    //\n    void unregister()\n    {\n        if (key_) {\n            pj_ioqueue_unregister(key_);\n            key_ = NULL;\n        }\n    }\n\n    //\n    // Get socket handle associated with this.\n    //\n    virtual pj_sock_t get_socket_handle()\n    {\n        return PJ_INVALID_SOCKET;\n    }\n\n    //\n    // Start async receive.\n    //\n    pj_status_t recv( Pj_Async_Op *op_key, \n                      void *buf, pj_ssize_t *len, \n                      unsigned flags)\n    {\n        return pj_ioqueue_recv( key_, op_key,\n                                buf, len, flags);\n    }\n\n    //\n    // Start async recvfrom()\n    //\n    pj_status_t recvfrom( Pj_Async_Op *op_key, \n                          void *buf, pj_ssize_t *len, unsigned flags,\n                          Pj_Inet_Addr *addr)\n    {\n        addr->addrlen_ = sizeof(Pj_Inet_Addr);\n        return pj_ioqueue_recvfrom( key_, op_key, buf, len, flags,\n                                    addr, &addr->addrlen_ );\n    }\n\n    //\n    // Start async send()\n    //\n    pj_status_t send( Pj_Async_Op *op_key, \n                      const void *data, pj_ssize_t *len, \n                      unsigned flags)\n    {\n        return pj_ioqueue_send( key_, op_key, data, len, flags);\n    }\n\n    //\n    // Start async sendto()\n    //\n    pj_status_t sendto( Pj_Async_Op *op_key,\n                        const void *data, pj_ssize_t *len, unsigned flags,\n                        const Pj_Inet_Addr &addr)\n    {\n        return pj_ioqueue_sendto(key_, op_key, data, len, flags,\n                                 &addr, sizeof(addr));\n    }\n\n#if PJ_HAS_TCP\n    //\n    // Start async connect()\n    //\n    pj_status_t connect(const Pj_Inet_Addr &addr)\n    {\n        return pj_ioqueue_connect(key_, &addr, sizeof(addr));\n    }\n\n    //\n    // Start async accept().\n    //\n    pj_status_t accept( Pj_Async_Op *op_key,\n                        Pj_Socket *sock, \n                        Pj_Inet_Addr *local = NULL, \n                        Pj_Inet_Addr *remote = NULL)\n    {\n        int *addrlen = local ? &local->addrlen_ : NULL;\n        return pj_ioqueue_accept( key_, op_key, &sock->sock_,\n                                  local, remote, addrlen );\n    }\n\n#endif\n\nprotected:\n    //////////////////\n    // Overridables\n    //////////////////\n\n    //\n    // Timeout callback.\n    //\n    virtual void on_timeout(int) \n    {\n    }\n\n    //\n    // On read complete callback.\n    //\n    virtual void on_read_complete( Pj_Async_Op*, pj_ssize_t) \n    {\n    }\n\n    //\n    // On write complete callback.\n    //\n    virtual void on_write_complete( Pj_Async_Op *, pj_ssize_t) \n    {\n    }\n\n#if PJ_HAS_TCP\n    //\n    // On connect complete callback.\n    //\n    virtual void on_connect_complete(pj_status_t) \n    {\n    }\n\n    //\n    // On new connection callback.\n    //\n    virtual void on_accept_complete( Pj_Async_Op*, pj_sock_t, pj_status_t) \n    {\n    }\n\n#endif\n\n\nprivate:\n    pj_ioqueue_key_t *key_;\n    pj_timer_entry    timer_;\n\n    friend class Pj_Proactor;\n    friend class Pj_Async_Op;\n\n    //\n    // Static timer callback.\n    //\n    static void timer_callback( pj_timer_heap_t*, \n                                struct pj_timer_entry *entry)\n    {\n        Pj_Event_Handler *handler = \n            (Pj_Event_Handler*) entry->user_data;\n\n        handler->on_timeout(entry->id);\n    }\n};\n\ninline bool Pj_Async_Op::is_pending()\n{\n    return pj_ioqueue_is_pending(handler_->key_, this) != 0;\n}\n\ninline bool Pj_Async_Op::cancel(pj_ssize_t bytes_status)\n{\n    return pj_ioqueue_post_completion(handler_->key_, this, \n                                      bytes_status) == PJ_SUCCESS;\n}\n\n//////////////////////////////////////////////////////////////////////////////\n// Proactor\n//\nclass Pj_Proactor : public Pj_Object\n{\npublic:\n    //\n    // Default constructor, initializes to NULL.\n    //\n    Pj_Proactor()\n        : ioq_(NULL), th_(NULL)\n    {\n        cb_.on_read_complete    = &read_complete_cb;\n        cb_.on_write_complete   = &write_complete_cb;\n        cb_.on_accept_complete  = &accept_complete_cb;\n        cb_.on_connect_complete = &connect_complete_cb;\n    }\n\n    //\n    // Construct proactor.\n    //\n    Pj_Proactor( Pj_Pool *pool, pj_size_t max_fd,\n                 pj_size_t max_timer_entries )\n    : ioq_(NULL), th_(NULL)\n    {\n        cb_.on_read_complete    = &read_complete_cb;\n        cb_.on_write_complete   = &write_complete_cb;\n        cb_.on_accept_complete  = &accept_complete_cb;\n        cb_.on_connect_complete = &connect_complete_cb;\n\n        create(pool, max_fd, max_timer_entries);\n    }\n\n    //\n    // Destructor.\n    //\n    ~Pj_Proactor()\n    {\n        destroy();\n    }\n\n    //\n    // Create proactor.\n    //\n    pj_status_t create( Pj_Pool *pool, pj_size_t max_fd, \n\t\t\tpj_size_t timer_entry_count)\n    {\n        pj_status_t status;\n\n        destroy();\n\n        status = pj_ioqueue_create(pool->pool_(), max_fd, &ioq_);\n        if (status != PJ_SUCCESS) \n            return status;\n        \n        status = pj_timer_heap_create(pool->pool_(), \n                                      timer_entry_count, &th_);\n        if (status != PJ_SUCCESS) {\n            pj_ioqueue_destroy(ioq_);\n            ioq_ = NULL;\n            return NULL;\n        }\n        \n        return status;\n    }\n\n    //\n    // Destroy proactor.\n    //\n    void destroy()\n    {\n        if (ioq_) {\n            pj_ioqueue_destroy(ioq_);\n            ioq_ = NULL;\n        }\n        if (th_) {\n            pj_timer_heap_destroy(th_);\n            th_ = NULL;\n        }\n    }\n\n    //\n    // Register handler.\n    // This will call handler->get_socket_handle()\n    //\n    pj_status_t register_socket_handler(Pj_Pool *pool, \n                                        Pj_Event_Handler *handler)\n    {\n        return   pj_ioqueue_register_sock( pool->pool_(), ioq_,\n                                           handler->get_socket_handle(),\n                                           handler, &cb_, &handler->key_ );\n    }\n\n    //\n    // Unregister handler.\n    //\n    static void unregister_handler(Pj_Event_Handler *handler)\n    {\n        if (handler->key_) {\n            pj_ioqueue_unregister( handler->key_ );\n            handler->key_ = NULL;\n        }\n    }\n\n    //\n    // Scheduler timer.\n    //\n    bool schedule_timer( Pj_Event_Handler *handler, \n                         const Pj_Time_Val &delay, \n                         int id=-1)\n    {\n        return schedule_timer(th_, handler, delay, id);\n    }\n\n    //\n    // Cancel timer.\n    //\n    bool cancel_timer(Pj_Event_Handler *handler)\n    {\n        return pj_timer_heap_cancel(th_, &handler->timer_) == 1;\n    }\n\n    //\n    // Handle events.\n    //\n    int handle_events(Pj_Time_Val *max_timeout)\n    {\n        Pj_Time_Val timeout(0, 0);\n        int timer_count;\n\n        timer_count = pj_timer_heap_poll( th_, &timeout );\n\n        if (timeout.get_sec() < 0) \n            timeout.sec = PJ_MAXINT32;\n\n        /* If caller specifies maximum time to wait, then compare the value \n         * with the timeout to wait from timer, and use the minimum value.\n         */\n        if (max_timeout && timeout >= *max_timeout) {\n\t    timeout = *max_timeout;\n        }\n\n        /* Poll events in ioqueue. */\n        int ioqueue_count;\n\n        ioqueue_count = pj_ioqueue_poll(ioq_, &timeout);\n        if (ioqueue_count < 0)\n\t    return ioqueue_count;\n\n        return ioqueue_count + timer_count;\n    }\n\n    //\n    // Get the internal ioqueue object.\n    //\n    pj_ioqueue_t *get_io_queue()\n    {\n        return ioq_;\n    }\n\n    //\n    // Get the internal timer heap object.\n    //\n    pj_timer_heap_t *get_timer_heap()\n    {\n        return th_;\n    }\n\nprivate:\n    pj_ioqueue_t *ioq_;\n    pj_timer_heap_t *th_;\n    pj_ioqueue_callback cb_;\n\n    static bool schedule_timer( pj_timer_heap_t *timer, \n                                Pj_Event_Handler *handler,\n\t\t\t\tconst Pj_Time_Val &delay, \n                                int id=-1)\n    {\n        handler->timer_.id = id;\n        return pj_timer_heap_schedule(timer, &handler->timer_, &delay) == 0;\n    }\n\n\n    //\n    // Static read completion callback.\n    //\n    static void read_complete_cb( pj_ioqueue_key_t *key, \n                                  pj_ioqueue_op_key_t *op_key, \n                                  pj_ssize_t bytes_read)\n    {\n        Pj_Event_Handler *handler = \n\t    (Pj_Event_Handler*) pj_ioqueue_get_user_data(key);\n\n        handler->on_read_complete((Pj_Async_Op*)op_key, bytes_read);\n    }\n\n    //\n    // Static write completion callback.\n    //\n    static void write_complete_cb(pj_ioqueue_key_t *key, \n                                  pj_ioqueue_op_key_t *op_key,\n                                  pj_ssize_t bytes_sent)\n    {\n        Pj_Event_Handler *handler = \n\t    (Pj_Event_Handler*) pj_ioqueue_get_user_data(key);\n\n        handler->on_write_complete((Pj_Async_Op*)op_key, bytes_sent);\n    }\n\n    //\n    // Static accept completion callback.\n    //\n    static void accept_complete_cb(pj_ioqueue_key_t *key, \n                                   pj_ioqueue_op_key_t *op_key,\n                                   pj_sock_t new_sock,\n                                   pj_status_t status)\n    {\n        Pj_Event_Handler *handler = \n\t    (Pj_Event_Handler*) pj_ioqueue_get_user_data(key);\n\n        handler->on_accept_complete((Pj_Async_Op*)op_key, new_sock, status);\n    }\n\n    //\n    // Static connect completion callback.\n    //\n    static void connect_complete_cb(pj_ioqueue_key_t *key, \n                                    pj_status_t status)\n    {\n        Pj_Event_Handler *handler = \n\t    (Pj_Event_Handler*) pj_ioqueue_get_user_data(key);\n\n        handler->on_connect_complete(status);\n    }\n\n};\n\n#endif\t/* __PJPP_PROACTOR_HPP__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj++/scanner.hpp",
    "content": "/* $Id: scanner.hpp 2394 2008-12-23 17:27:53Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJPP_SCANNER_HPP__\n#define __PJPP_SCANNER_HPP__\n\n#include <pjlib-util/scanner.h>\n#include <pj++/string.hpp>\n\nclass Pj_Cis;\nclass Pj_Cis_Buffer;\nclass Pj_Scanner;\n\nclass Pj_Cis_Buffer\n{\n    friend class Pj_Cis;\n\npublic:\n    Pj_Cis_Buffer() \n    { \n\tpj_cis_buf_init(&buf_); \n    }\n\nprivate:\n    pj_cis_buf_t buf_;\n};\n\n\nclass Pj_Cis\n{\n    friend class Pj_Scanner;\n\npublic:\n    Pj_Cis(Pj_Cis_Buffer *buf)\n    {\n\tpj_cis_init(&buf->buf_, &cis_);\n    }\n\n    Pj_Cis(const Pj_Cis &rhs)\n    {\n\tpj_cis_dup(&cis_, (pj_cis_t*)&rhs.cis_);\n    }\n\n    void add_range(int start, int end)\n    {\n\tpj_cis_add_range(&cis_, start, end);\n    }\n\n    void add_alpha()\n    {\n\tpj_cis_add_alpha(&cis_);\n    }\n\n    void add_num()\n    {\n\tpj_cis_add_num(&cis_);\n    }\n\n    void add_str(const char *str)\n    {\n\tpj_cis_add_str(&cis_, str);\n    }\n\n    void add_cis(const Pj_Cis &rhs)\n    {\n\tpj_cis_add_cis(&cis_, &rhs.cis_);\n    }\n\n    void del_range(int start, int end)\n    {\n\tpj_cis_del_range(&cis_, start, end);\n    }\n\n    void del_str(const char *str)\n    {\n\tpj_cis_del_str(&cis_, str);\n    }\n\n    void invert()\n    {\n\tpj_cis_invert(&cis_);\n    }\n\n    bool match(int c) const\n    {\n\treturn pj_cis_match(&cis_, c) != 0;\n    }\n\nprivate:\n    pj_cis_t cis_;\n};\n\n\n\nclass Pj_Scanner\n{\npublic:\n    Pj_Scanner() {}\n\n    enum\n    {\n\tSYNTAX_ERROR = 101\n    };\n    static void syntax_error_handler_throw_pj(pj_scanner *);\n\n    typedef pj_scan_state State;\n\n    void init(char *buf, int len, unsigned options=PJ_SCAN_AUTOSKIP_WS, \n\t      pj_syn_err_func_ptr callback = &syntax_error_handler_throw_pj)\n    {\n\tpj_scan_init(&scanner_, buf, len, options, callback);\n    }\n\n    void fini()\n    {\n\tpj_scan_fini(&scanner_);\n    }\n\n    int eof() const\n    {\n\treturn pj_scan_is_eof(&scanner_);\n    }\n\n    int peek_char() const\n    {\n\treturn *scanner_.curptr;\n    }\n\n    int peek(const Pj_Cis *cis, Pj_String *out)\n    {\n\treturn pj_scan_peek(&scanner_,  &cis->cis_, out);\n    }\n\n    int peek_n(pj_size_t len, Pj_String *out)\n    {\n\treturn pj_scan_peek_n(&scanner_, len, out);\n    }\n\n    int peek_until(const Pj_Cis *cis, Pj_String *out)\n    {\n\treturn pj_scan_peek_until(&scanner_, &cis->cis_, out);\n    }\n\n    void get(const Pj_Cis *cis, Pj_String *out)\n    {\n\tpj_scan_get(&scanner_, &cis->cis_, out);\n    }\n\n    void get_n(unsigned N, Pj_String *out)\n    {\n\tpj_scan_get_n(&scanner_, N, out);\n    }\n\n    int get_char()\n    {\n\treturn pj_scan_get_char(&scanner_);\n    }\n\n    void get_quote(int begin_quote, int end_quote, Pj_String *out)\n    {\n\tpj_scan_get_quote(&scanner_, begin_quote, end_quote, out);\n    }\n\n    void get_newline()\n    {\n\tpj_scan_get_newline(&scanner_);\n    }\n\n    void get_until(const Pj_Cis *cis, Pj_String *out)\n    {\n\tpj_scan_get_until(&scanner_, &cis->cis_, out);\n    }\n\n    void get_until_ch(int until_ch, Pj_String *out)\n    {\n\tpj_scan_get_until_ch(&scanner_, until_ch, out);\n    }\n\n    void get_until_chr(const char *spec, Pj_String *out)\n    {\n\tpj_scan_get_until_chr(&scanner_, spec, out);\n    }\n\n    void advance_n(unsigned N, bool skip_ws=true)\n    {\n\tpj_scan_advance_n(&scanner_, N, skip_ws);\n    }\n\n    int strcmp(const char *s, int len)\n    {\n\treturn pj_scan_strcmp(&scanner_, s, len);\n    }\n\n    int stricmp(const char *s, int len)\n    {\n\treturn pj_scan_stricmp(&scanner_, s, len);\n    }\n\n    void skip_ws()\n    {\n\tpj_scan_skip_whitespace(&scanner_);\n    }\n\n    void save_state(State *state) const\n    {\n\tpj_scan_save_state(&scanner_, state);\n    }\n\n    void restore_state(State *state)\n    {\n\tpj_scan_restore_state(&scanner_, state);\n    }\n\n    int get_pos_line() const\n    {\n\treturn scanner_.line;\n    }\n\n    int get_pos_col() const\n    {\n\treturn pj_scan_get_col(&scanner_);\n    }\n\n\nprivate:\n    pj_scanner scanner_;\n};\n\n#endif\t/* __PJPP_SCANNER_HPP__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj++/sock.hpp",
    "content": "/* $Id: sock.hpp 2394 2008-12-23 17:27:53Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJPP_SOCK_HPP__\n#define __PJPP_SOCK_HPP__\n\n#include <pj/sock.h>\n#include <pj/string.h>\n\nclass Pj_Event_Handler;\n\n//\n// Base class for address.\n//\nclass Pj_Addr\n{\n};\n\n//\n// Internet address.\n//\nclass Pj_Inet_Addr : public pj_sockaddr_in, public Pj_Addr\n{\npublic:\n    //\n    // Get port number.\n    //\n    pj_uint16_t get_port_number() const\n    {\n\treturn pj_sockaddr_in_get_port(this);\n    }\n\n    //\n    // Set port number.\n    //\n    void set_port_number(pj_uint16_t port)\n    {\n\tsin_family = PJ_AF_INET;\n\tpj_sockaddr_in_set_port(this, port);\n    }\n\n    //\n    // Get IP address.\n    //\n    pj_uint32_t get_ip_address() const\n    {\n\treturn pj_sockaddr_in_get_addr(this).s_addr;\n    }\n\n    //\n    // Get address string.\n    //\n    const char *get_address() const\n    {\n\treturn pj_inet_ntoa(sin_addr);\n    }\n\n    //\n    // Set IP address.\n    //\n    void set_ip_address(pj_uint32_t addr)\n    {\n\tsin_family = PJ_AF_INET;\n\tpj_sockaddr_in_set_addr(this, addr);\n    }\n\n    //\n    // Set address.\n    //\n    pj_status_t set_address(const pj_str_t *addr)\n    {\n\treturn pj_sockaddr_in_set_str_addr(this, addr);\n    }\n\n    //\n    // Set address.\n    //\n    pj_status_t set_address(const char *addr)\n    {\n        pj_str_t s;\n\treturn pj_sockaddr_in_set_str_addr(this, pj_cstr(&s, addr));\n    }\n\n    //\n    // Compare for equality.\n    //\n    bool operator==(const Pj_Inet_Addr &rhs) const\n    {\n\treturn sin_family == rhs.sin_family &&\n               sin_addr.s_addr == rhs.sin_addr.s_addr &&\n               sin_port == rhs.sin_port;\n    }\n\nprivate:\n    //\n    // Dummy length used in pj_ioqueue_recvfrom() etc\n    //\n    friend class Pj_Event_Handler;\n    friend class Pj_Socket;\n    friend class Pj_Sock_Stream;\n    friend class Pj_Sock_Dgram;\n\n    int addrlen_;\n};\n\n\n//\n// Socket base class.\n//\n// Note:\n//  socket will not automatically be closed on destructor.\n//\nclass Pj_Socket\n{\npublic:\n    //\n    // Default constructor.\n    //\n    Pj_Socket()\n        : sock_(PJ_INVALID_SOCKET) \n    {\n    }\n\n    //\n    // Initialize from a socket handle.\n    //\n    explicit Pj_Socket(pj_sock_t sock)\n        : sock_(sock)\n    {\n    }\n\n    //\n    // Copy constructor.\n    //\n    Pj_Socket(const Pj_Socket &rhs) \n        : sock_(rhs.sock_) \n    {\n    }\n\n    //\n    // Destructor will not close the socket.\n    // You must call close() explicitly.\n    //\n    ~Pj_Socket()\n    {\n    }\n\n    //\n    // Set socket handle.\n    //\n    void set_handle(pj_sock_t sock)\n    {\n\tsock_ = sock;\n    }\n\n    //\n    // Get socket handle.\n    //\n    pj_sock_t get_handle() const\n    {\n\treturn sock_;\n    }\n\n    //\n    // Get socket handle.\n    //\n    pj_sock_t& get_handle()\n    {\n\treturn sock_;\n    }\n\n    //\n    // See if the socket is valid.\n    //\n    bool is_valid() const\n    {\n        return sock_ != PJ_INVALID_SOCKET;\n    }\n\n    //\n    // Create the socket.\n    //\n    pj_status_t create(int af, int type, int proto)\n    {\n\treturn pj_sock_socket(af, type, proto, &sock_);\n    }\n\n    //\n    // Bind socket.\n    //\n    pj_status_t bind(const Pj_Inet_Addr &addr)\n    {\n\treturn pj_sock_bind(sock_, &addr, sizeof(Pj_Inet_Addr));\n    }\n\n    //\n    // Close socket.\n    //\n    pj_status_t close()\n    {\n\tpj_sock_close(sock_);\n    }\n\n    //\n    // Get peer socket name.\n    //\n    pj_status_t getpeername(Pj_Inet_Addr *addr)\n    {\n\treturn pj_sock_getpeername(sock_, addr, &addr->addrlen_);\n    }\n\n    //\n    // getsockname\n    //\n    pj_status_t getsockname(Pj_Inet_Addr *addr)\n    {\n\treturn pj_sock_getsockname(sock_, addr, &addr->addrlen_);\n    }\n\n    //\n    // getsockopt.\n    //\n    pj_status_t getsockopt(pj_uint16_t level, pj_uint16_t optname, \n                           void *optval, int *optlen)\n    {\n\treturn pj_sock_getsockopt(sock_, level, optname, optval, optlen);\n    }\n\n    //\n    // setsockopt\n    // \n    pj_status_t setsockopt(pj_uint16_t level, pj_uint16_t optname, \n                           const void *optval, int optlen)\n    {\n\treturn pj_sock_setsockopt(sock_, level, optname, optval, optlen);\n    }\n\n    //\n    // receive data.\n    //\n    pj_ssize_t recv(void *buf, pj_size_t len, int flag = 0)\n    {\n        pj_ssize_t bytes = len;\n\tif (pj_sock_recv(sock_, buf, &bytes, flag) != PJ_SUCCESS)\n            return -1;\n        return bytes;\n    }\n\n    //\n    // send data.\n    //\n    pj_ssize_t send(const void *buf, pj_ssize_t len, int flag = 0)\n    {\n        pj_ssize_t bytes = len;\n\tif (pj_sock_send(sock_, buf, &bytes, flag) != PJ_SUCCESS)\n            return -1;\n        return bytes;\n    }\n\n    //\n    // connect.\n    //\n    pj_status_t connect(const Pj_Inet_Addr &addr)\n    {\n\treturn pj_sock_connect(sock_, &addr, sizeof(Pj_Inet_Addr));\n    }\n\n    //\n    // assignment.\n    //\n    Pj_Socket &operator=(const Pj_Socket &rhs)\n    {\n        sock_ = rhs.sock_;\n        return *this;\n    }\n\nprotected:\n    friend class Pj_Event_Handler;\n    pj_sock_t sock_;\n};\n\n\n#if PJ_HAS_TCP\n//\n// Stream socket.\n//\nclass Pj_Sock_Stream : public Pj_Socket\n{\npublic:\n    //\n    // Default constructor.\n    //\n    Pj_Sock_Stream() \n    {\n    }\n\n    //\n    // Initialize from a socket handle.\n    //\n    explicit Pj_Sock_Stream(pj_sock_t sock)\n        : Pj_Socket(sock)\n    {\n    }\n\n    //\n    // Copy constructor.\n    //\n    Pj_Sock_Stream(const Pj_Sock_Stream &rhs) : Pj_Socket(rhs) \n    {\n    }\n\n    //\n    // Assignment.\n    //\n    Pj_Sock_Stream &operator=(const Pj_Sock_Stream &rhs) \n    { \n        sock_ = rhs.sock_; \n        return *this; \n    }\n\n    //\n    // listen()\n    //\n    pj_status_t listen(int backlog = 5)\n    {\n\treturn pj_sock_listen(sock_, backlog);\n    }\n\n    //\n    // blocking accept()\n    //\n    Pj_Sock_Stream accept(Pj_Inet_Addr *remote_addr = NULL)\n    {\n        pj_sock_t newsock;\n        int *addrlen = remote_addr ? &remote_addr->addrlen_ : NULL;\n        pj_status_t status;\n        \n        status = pj_sock_accept(sock_, &newsock, remote_addr, addrlen);\n        if (status != PJ_SUCCESS)\n            return Pj_Sock_Stream(-1);\n\n        return Pj_Sock_Stream(newsock);\n    }\n\n    //\n    // shutdown()\n    //\n    pj_status_t shutdown(int how = PJ_SHUT_RDWR)\n    {\n\treturn pj_sock_shutdown(sock_, how);\n    }\n\n};\n#endif\n\n//\n// Datagram socket.\n//\nclass Pj_Sock_Dgram : public Pj_Socket\n{\npublic:\n    //\n    // Default constructor.\n    //\n    Pj_Sock_Dgram() \n    {\n    }\n\n    //\n    // Initialize from a socket handle.\n    //\n    explicit Pj_Sock_Dgram(pj_sock_t sock)\n        : Pj_Socket(sock)\n    {\n    }\n\n    //\n    // Copy constructor.\n    //\n    Pj_Sock_Dgram(const Pj_Sock_Dgram &rhs) \n        : Pj_Socket(rhs) \n    {\n    }\n\n    //\n    // Assignment.\n    //\n    Pj_Sock_Dgram &operator=(const Pj_Sock_Dgram &rhs) \n    { \n        Pj_Socket::operator =(rhs);\n        return *this; \n    }\n\n    //\n    // recvfrom()\n    //\n    pj_ssize_t recvfrom( void *buf, pj_size_t len, int flag = 0, \n                         Pj_Inet_Addr *fromaddr = NULL)\n    {\n        pj_ssize_t bytes = len;\n        int *addrlen = fromaddr ? &fromaddr->addrlen_ : NULL;\n\tif (pj_sock_recvfrom( sock_, buf, &bytes, flag, \n                              fromaddr, addrlen) != PJ_SUCCESS)\n        {\n            return -1;\n        }\n        return bytes;\n    }\n\n    //\n    // sendto()\n    //\n    pj_ssize_t sendto( const void *buf, pj_size_t len, int flag, \n                       const Pj_Inet_Addr &addr)\n    {\n        pj_ssize_t bytes = len;\n\tif (pj_sock_sendto( sock_, buf, &bytes, flag, \n                            &addr, sizeof(pj_sockaddr_in)) != PJ_SUCCESS)\n        {\n            return -1;\n        }\n        return bytes;\n    }\n};\n\n\n#endif\t/* __PJPP_SOCK_HPP__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj++/string.hpp",
    "content": "/* $Id: string.hpp 2394 2008-12-23 17:27:53Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJPP_STRING_HPP__\n#define __PJPP_STRING_HPP__\n\n#include <pj/string.h>\n#include <pj++/pool.hpp>\n#include <pj/assert.h>\n\n//\n// String wrapper class for pj_str_t.\n//\nclass Pj_String : public pj_str_t\n{\npublic:\n    //\n    // Default constructor.\n    //\n    Pj_String() \n    { \n\tpj_assert(sizeof(Pj_String) == sizeof(pj_str_t));\n\tptr=NULL; \n        slen=0; \n    }\n\n    //\n    // Construct the buffer from a char* (use with care)\n    //\n    Pj_String(char *str) \n    { \n\tset(str);\n    }\n\n    //\n    // Construct from a const char*.\n    //\n    Pj_String(Pj_Pool &pool, const char *src)\n    {\n\tset(pool, src);\n    }\n\n    //\n    // Construct from pj_str_t&.\n    //\n    explicit Pj_String(pj_str_t &s)\n    {\n\tptr = s.ptr;\n\tslen = s.slen;\n    }\n\n    //\n    // Construct from const pj_str_t& (use with care!).\n    //\n    explicit Pj_String(const pj_str_t &s)\n    {\n\tptr = (char*)s.ptr;\n\tslen = s.slen;\n    }\n\n    //\n    // Construct by copying from const pj_str_t*.\n    //\n    Pj_String(Pj_Pool &pool, const pj_str_t *s)\n    {\n\tset(pool, s);\n    }\n\n    //\n    // Construct by copying from Pj_String\n    //\n    Pj_String(Pj_Pool &pool, const Pj_String &rhs)\n    {\n\tset(pool, rhs);\n    }\n\n    //\n    // Construct from another Pj_String, use with care!\n    //\n    explicit Pj_String(const Pj_String &rhs)\n    {\n\tptr = rhs.ptr;\n\tslen = rhs.slen;\n    }\n\n    //\n    // Construct from a char* and a length.\n    //\n    Pj_String(char *str, pj_size_t len)\n    {\n\tset(str, len);\n    }\n\n    //\n    // Construct from pair of pointer.\n    //\n    Pj_String(char *begin, char *end)\n    {\n\tpj_strset3(this, begin, end);\n    }\n\n    //\n    // You can cast Pj_String to pj_str_t*\n    //\n    operator pj_str_t*()\n    {\n\treturn this;\n    }\n\n    //\n    // You can cast const Pj_String to const pj_str_t*\n    //\n    operator const pj_str_t*() const\n    {\n\treturn this;\n    }\n\n    //\n    // Get the length of the string.\n    //\n    pj_size_t length() const\n    {\n\treturn pj_strlen(this);\n    }\n\n    //\n    // Get the length of the string.\n    //\n    pj_size_t size() const\n    {\n\treturn length();\n    }\n\n    //\n    // Get the string buffer.\n    //\n    const char *buf() const\n    {\n\treturn ptr;\n    }\n\n    //\n    // Initialize buffer from char*.\n    //\n    void set(char *str)\n    {\n\tpj_strset2(this, str);\n    }\n\n    //\n    // Initialize by copying from a const char*.\n    //\n    void set(Pj_Pool &pool, const char *s)\n    {\n\tpj_strdup2(pool, this, s);\n    }\n\n    //\n    // Initialize from pj_str_t*.\n    //\n    void set(pj_str_t *s)\n    {\n\tpj_strassign(this, s);\n    }\n\n    //\n    // Initialize by copying from const pj_str_t*.\n    //\n    void set(Pj_Pool &pool, const pj_str_t *s)\n    {\n\tpj_strdup(pool, this, s);\n    }\n\n    //\n    // Initialize from char* and length.\n    //\n    void set(char *str, pj_size_t len)\n    {\n\tpj_strset(this, str, len);\n    }\n\n    //\n    // Initialize from pair of pointers.\n    //\n    void set(char *begin, char *end)\n    {\n\tpj_strset3(this, begin, end);\n    }\n\n    //\n    // Initialize from other Pj_String.\n    //\n    void set(Pj_String &rhs)\n    {\n\tpj_strassign(this, &rhs);\n    }\n\n    //\n    // Initialize by copying from a Pj_String*.\n    //\n    void set(Pj_Pool &pool, const Pj_String *s)\n    {\n\tpj_strdup(pool, this, s);\n    }\n\n    //\n    // Initialize by copying from other Pj_String.\n    //\n    void set(Pj_Pool &pool, const Pj_String &s)\n    {\n\tpj_strdup(pool, this, &s);\n    }\n\n    //\n    // Copy the contents of other string.\n    //\n    void strcpy(const pj_str_t *s)\n    {\n\tpj_strcpy(this, s);\n    }\n\n    //\n    // Copy the contents of other string.\n    //\n    void strcpy(const Pj_String &rhs)\n    {\n\tpj_strcpy(this, &rhs);\n    }\n\n    //\n    // Copy the contents of other string.\n    //\n    void strcpy(const char *s)\n    {\n\tpj_strcpy2(this, s);\n    }\n\n    //\n    // Compare string.\n    //\n    int strcmp(const char *s) const\n    {\n\treturn pj_strcmp2(this, s);\n    }\n\n    //\n    // Compare string.\n    //\n    int strcmp(const pj_str_t *s) const\n    {\n\treturn pj_strcmp(this, s);\n    }\n\n    //\n    // Compare string.\n    //\n    int strcmp(const Pj_String &rhs) const\n    {\n\treturn pj_strcmp(this, &rhs);\n    }\n\n    //\n    // Compare string.\n    //\n    int strncmp(const char *s, pj_size_t len) const\n    {\n\treturn pj_strncmp2(this, s, len);\n    }\n\n    //\n    // Compare string.\n    //\n    int strncmp(const pj_str_t *s, pj_size_t len) const\n    {\n\treturn pj_strncmp(this, s, len);\n    }\n\n    //\n    // Compare string.\n    //\n    int strncmp(const Pj_String &rhs, pj_size_t len) const\n    {\n\treturn pj_strncmp(this, &rhs, len);\n    }\n\n    //\n    // Compare string.\n    //\n    int stricmp(const char *s) const\n    {\n\treturn pj_stricmp2(this, s);\n    }\n\n    //\n    // Compare string.\n    //\n    int stricmp(const pj_str_t *s) const\n    {\n\treturn pj_stricmp(this, s);\n    }\n\n    //\n    // Compare string.\n    //\n    int stricmp(const Pj_String &rhs) const\n    {\n\treturn stricmp(&rhs);\n    }\n\n    //\n    // Compare string.\n    //\n    int strnicmp(const char *s, pj_size_t len) const\n    {\n\treturn pj_strnicmp2(this, s, len);\n    }\n\n    //\n    // Compare string.\n    //\n    int strnicmp(const pj_str_t *s, pj_size_t len) const\n    {\n\treturn pj_strnicmp(this, s, len);\n    }\n\n    //\n    // Compare string.\n    //\n    int strnicmp(const Pj_String &rhs, pj_size_t len) const\n    {\n\treturn strnicmp(&rhs, len);\n    }\n\n    //\n    // Compare contents for equality.\n    //\n    bool operator==(const char *s) const\n    {\n\treturn strcmp(s) == 0;\n    }\n\n    //\n    // Compare contents for equality.\n    //\n    bool operator==(const pj_str_t *s) const\n    {\n\treturn strcmp(s) == 0;\n    }\n\n    //\n    // Compare contents for equality.\n    //\n    bool operator==(const Pj_String &rhs) const\n    {\n\treturn pj_strcmp(this, &rhs) == 0;\n    }\n\n    //\n    // Assign from char*\n    //\n    Pj_String& operator=(char *s)\n    {\n\tset(s);\n\treturn *this;\n    }\n\n    ///\n    // Assign from another Pj_String, use with care!\n    //\n    Pj_String& operator=(const Pj_String &rhs)\n    {\n\tptr = rhs.ptr;\n\tslen = rhs.slen;\n\treturn *this;\n    }\n\n    //\n    // Find a character in the string.\n    //\n    char *strchr(int chr)\n    {\n\treturn pj_strchr(this, chr);\n    }\n\n    //\n    // Find a character in the string.\n    //\n    char *find(int chr)\n    {\n\treturn strchr(chr);\n    }\n\n    //\n    // Concatenate string.\n    //\n    void strcat(const Pj_String &rhs)\n    {\n\tpj_strcat(this, &rhs);\n    }\n\n    //\n    // Left trim.\n    //\n    void ltrim()\n    {\n\tpj_strltrim(this);\n    }\n\n    //\n    // Right trim.\n    //\n    void rtrim()\n    {\n\tpj_strrtrim(this);\n    }\n\n    //\n    // Left and right trim.\n    //\n    void trim()\n    {\n\tpj_strtrim(this);\n    }\n\n    //\n    // Convert to unsigned long.\n    //\n    unsigned long to_ulong() const\n    {\n\treturn pj_strtoul(this);\n    }\n\n    //\n    // Convert from unsigned long.\n    //\n    void from_ulong(unsigned long value)\n    {\n        slen = pj_utoa(value, ptr);\n    }\n\n    //\n    // Convert from unsigned long with padding.\n    //\n    void from_ulong_with_pad(unsigned long value, int min_dig=0, int pad=' ')\n    {\n        slen = pj_utoa_pad(value, ptr, min_dig, pad);\n    }\n\n};\n\n#endif\t/* __PJPP_STRING_HPP__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj++/timer.hpp",
    "content": "/* $Id: timer.hpp 2394 2008-12-23 17:27:53Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJPP_TIMER_HPP__\n#define __PJPP_TIMER_HPP__\n\n#include <pj/timer.h>\n#include <pj++/types.hpp>\n#include <pj/assert.h>\n#include <pj++/lock.hpp>\n\nclass Pj_Timer_Heap;\n\n//////////////////////////////////////////////////////////////////////////////\n// Timer entry.\n//\n// How to use:\n//  Derive class from Pj_Timer_Entry and override on_timeout().\n//  Scheduler timer in Pj_Timer_Heap.\n//\nclass Pj_Timer_Entry : public Pj_Object\n{\n    friend class Pj_Timer_Heap;\n\npublic:\n    //\n    // Default constructor.\n    //\n    Pj_Timer_Entry() \n    { \n        entry_.user_data = this;\n        entry_.cb = &timer_heap_callback; \n    }\n\n    //\n    // Destructor, do nothing.\n    //\n    ~Pj_Timer_Entry()\n    {\n    }\n\n    //\n    // Override this to get the timeout notification.\n    //\n    virtual void on_timeout(int id) = 0;\n\nprivate:\n    pj_timer_entry entry_;\n\n    static void timer_heap_callback(pj_timer_heap_t*, pj_timer_entry *e)\n    {\n        Pj_Timer_Entry *entry = (Pj_Timer_Entry*) e->user_data;\n        entry->on_timeout(e->id);\n    }\n\n};\n\n//////////////////////////////////////////////////////////////////////////////\n// Timer heap.\n//\nclass Pj_Timer_Heap : public Pj_Object\n{\npublic:\n    //\n    // Default constructor.\n    //\n    Pj_Timer_Heap() \n        : ht_(NULL) \n    {\n    }\n\n    //\n    // Construct timer heap.\n    //\n    Pj_Timer_Heap(Pj_Pool *pool, pj_size_t initial_count)\n        : ht_(NULL)\n    {\n        create(pool, initial_count);\n    }\n\n    //\n    // Destructor.\n    //\n    ~Pj_Timer_Heap()\n    {\n        destroy();\n    }\n\n    //\n    // Create\n    // \n    pj_status_t create(Pj_Pool *pool, pj_size_t initial_count)\n    {\n        destroy();\n\treturn pj_timer_heap_create(pool->pool_(), initial_count, &ht_);\n    }\n\n    //\n    // Destroy\n    //\n    void destroy()\n    {\n        if (ht_) {\n            pj_timer_heap_destroy(ht_);\n            ht_ = NULL;\n        }\n    }\n\n    //\n    // Get pjlib compatible timer heap object.\n    //\n    pj_timer_heap_t *get_timer_heap()\n    {\n\treturn ht_;\n    }\n\n    //\n    // Set the lock object.\n    //\n    void set_lock( Pj_Lock *lock, bool auto_delete )\n    {\n        pj_timer_heap_set_lock( ht_, lock->pj_lock_t_(), auto_delete);\n    }\n\n    //\n    // Set maximum number of timed out entries to be processed per poll.\n    //\n    unsigned set_max_timed_out_per_poll(unsigned count)\n    {\n        return pj_timer_heap_set_max_timed_out_per_poll(ht_, count);\n    }\n\n    //\n    // Schedule a timer.\n    //\n    bool schedule( Pj_Timer_Entry *ent, const Pj_Time_Val &delay,\n                   int id)\n    {\n        ent->entry_.id = id;\n\treturn pj_timer_heap_schedule(ht_, &ent->entry_, &delay) == 0;\n    }\n\n    //\n    // Cancel a timer.\n    //\n    bool cancel(Pj_Timer_Entry *ent)\n    {\n\treturn pj_timer_heap_cancel(ht_, &ent->entry_) == 1;\n    }\n\n    //\n    // Get current number of timers\n    //\n    pj_size_t count()\n    {\n\treturn pj_timer_heap_count(ht_);\n    }\n\n    //\n    // Get the earliest time.\n    // Return false if no timer is found.\n    //\n    bool earliest_time(Pj_Time_Val *t)\n    {\n\treturn pj_timer_heap_earliest_time(ht_, t) == PJ_SUCCESS;\n    }\n\n    //\n    // Poll the timer.\n    // Return number of timed out entries has been called.\n    //\n    unsigned poll(Pj_Time_Val *next_delay = NULL)\n    {\n\treturn pj_timer_heap_poll(ht_, next_delay);\n    }\n\nprivate:\n    pj_timer_heap_t *ht_;\n};\n\n#endif\t/* __PJPP_TIMER_HPP__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj++/tree.hpp",
    "content": "/* $Id: tree.hpp 2394 2008-12-23 17:27:53Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJPP_TREE_HPP__\n#define __PJPP_TREE_HPP__\n\n#include <pj/rbtree.h>\n\n//\n// Tree.\n//\nclass PJ_Tree\n{\npublic:\n    typedef pj_rbtree_comp Comp;\n    class iterator;\n    class reverse_iterator;\n\n    class Node : private pj_rbtree_node\n    {\n\tfriend class PJ_Tree;\n\tfriend class iterator;\n\tfriend class reverse_iterator;\n\n    public:\n\tNode() {}\n\texplicit Node(void *data) { user_data = data; }\n\tvoid  set_user_data(void *data) { user_data = data; }\n\tvoid *get_user_data() const { return user_data; }\n    };\n\n    class iterator\n    {\n    public:\n\titerator() {}\n\titerator(const iterator &rhs) : tr_(rhs.tr_), nd_(rhs.nd_) {}\n\titerator(pj_rbtree *tr, pj_rbtree_node *nd) : tr_(tr), nd_(nd) {}\n\tNode *operator*() { return (Node*)nd_; }\n\tbool operator==(const iterator &rhs) const { return tr_==rhs.tr_ && nd_==rhs.nd_; }\n\titerator &operator=(const iterator &rhs) { tr_=rhs.tr_; nd_=rhs.nd_; return *this; }\n\tvoid operator++() { nd_=pj_rbtree_next(tr_, nd_); }\n\tvoid operator--() { nd_=pj_rbtree_prev(tr_, nd_); }\n    protected:\n\tpj_rbtree *tr_;\n\tpj_rbtree_node *nd_;\n    };\n\n    class reverse_iterator : public iterator\n    {\n    public:\n\treverse_iterator() {}\n\treverse_iterator(const reverse_iterator &it) : iterator(it) {}\n\treverse_iterator(pj_rbtree *t, pj_rbtree_node *n) : iterator(t, n) {}\n\treverse_iterator &operator=(const reverse_iterator &rhs) { iterator::operator=(rhs); return *this; }\n\tNode *operator*() { return (Node*)nd_; }\n\tbool operator==(const reverse_iterator &rhs) const { return iterator::operator==(rhs); }\n\tvoid operator++() { nd_=pj_rbtree_prev(tr_, nd_); }\n\tvoid operator--() { nd_=pj_rbtree_next(tr_, nd_); }\n    };\n\n    explicit PJ_Tree(Comp *comp) { pj_rbtree_init(&t_, comp); }\n\n    iterator begin()\n    {\n\treturn iterator(&t_, pj_rbtree_first(&t_));\n    }\n\n    iterator end()\n    {\n\treturn iterator(&t_, NULL);\n    }\n\n    reverse_iterator rbegin()\n    {\n\treturn reverse_iterator(&t_, pj_rbtree_last(&t_));\n    }\n\n    reverse_iterator rend()\n    {\n\treturn reverse_iterator(&t_, NULL);\n    }\n\n    bool insert(Node *node)\n    {\n\treturn pj_rbtree_insert(&t_, node)==0 ? true : false;\n    }\n\n    Node *find(const void *key)\n    {\n\treturn (Node*)pj_rbtree_find(&t_, key);\n    }\n\n    Node *erase(Node *node)\n    {\n\treturn (Node*)pj_rbtree_erase(&t_, node);\n    }\n\n    unsigned max_height(Node *node=NULL)\n    {\n\treturn pj_rbtree_max_height(&t_, node);\n    }\n\n    unsigned min_height(Node *node=NULL)\n    {\n\treturn pj_rbtree_min_height(&t_, node);\n    }\n\nprivate:\n    pj_rbtree t_;\n};\n\n#endif\t/* __PJPP_TREE_HPP__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pj++/types.hpp",
    "content": "/* $Id: types.hpp 2394 2008-12-23 17:27:53Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJPP_TYPES_HPP__\n#define __PJPP_TYPES_HPP__\n\n#include <pj/types.h>\n\nclass Pj_Pool;\nclass Pj_Socket ;\nclass Pj_Lock;\n\n\n//\n// PJLIB initializer.\n//\nclass Pjlib\n{\npublic:\n    Pjlib()\n    {\n        pj_init();\n    }\n};\n\n//\n// Class Pj_Object is declared in pool.hpp\n//\n\n//\n// Time value wrapper.\n//\nclass Pj_Time_Val : public pj_time_val\n{\npublic:\n    Pj_Time_Val()\n    {\n    }\n\n    Pj_Time_Val(long init_sec, long init_msec)\n    {\n        sec = init_sec;\n        msec = init_msec;\n    }\n\n    Pj_Time_Val(const Pj_Time_Val &rhs) \n    { \n        sec=rhs.sec; \n        msec=rhs.msec; \n    }\n\n    explicit Pj_Time_Val(const pj_time_val &tv) \n    { \n        sec = tv.sec; \n        msec = tv.msec; \n    }\n\n    long get_sec()  const    \n    { \n        return sec; \n    }\n\n    long get_msec() const    \n    { \n        return msec; \n    }\n\n    void set_sec (long s)    \n    { \n        sec = s; \n    }\n\n    void set_msec(long ms)   \n    { \n        msec = ms; \n        normalize(); \n    }\n\n    long to_msec() const \n    { \n        return PJ_TIME_VAL_MSEC((*this)); \n    }\n\n    bool operator == (const Pj_Time_Val &rhs) const \n    { \n        return PJ_TIME_VAL_EQ((*this), rhs);  \n    }\n\n    bool operator >  (const Pj_Time_Val &rhs) const \n    { \n        return PJ_TIME_VAL_GT((*this), rhs);  \n    }\n\n    bool operator >= (const Pj_Time_Val &rhs) const \n    { \n        return PJ_TIME_VAL_GTE((*this), rhs); \n    }\n\n    bool operator <  (const Pj_Time_Val &rhs) const \n    { \n        return PJ_TIME_VAL_LT((*this), rhs);  \n    }\n\n    bool operator <= (const Pj_Time_Val &rhs) const \n    { \n        return PJ_TIME_VAL_LTE((*this), rhs); \n    }\n\n    Pj_Time_Val & operator = (const Pj_Time_Val &rhs) \n    {\n\tsec = rhs.sec;\n\tmsec = rhs.msec;\n\treturn *this;\n    }\n \n    Pj_Time_Val & operator += (const Pj_Time_Val &rhs) \n    {\n\tPJ_TIME_VAL_ADD((*this), rhs);\n\treturn *this;\n    }\n\n    Pj_Time_Val & operator -= (const Pj_Time_Val &rhs) \n    {\n\tPJ_TIME_VAL_SUB((*this), rhs);\n\treturn *this;\n    }\n\n    /* Must include os.hpp to use these, otherwise unresolved in linking */\n    inline pj_status_t\t   gettimeofday();\n    inline pj_parsed_time  decode();\n    inline pj_status_t     encode(const pj_parsed_time *pt);\n    inline pj_status_t     to_gmt();\n    inline pj_status_t     to_local();\n\n\nprivate:\n    void normalize() \n    { \n        pj_time_val_normalize(this); \n    }\n\n};\n\n//\n// Macro to declare common object comparison operators.\n//\n#define PJ_DECLARE_OPERATORS(rhs_type)\t\t\t    \\\n\t    bool operator!=(rhs_type rhs) const {\t    \\\n\t\treturn !operator==(rhs); }\t\t    \\\n\t    bool operator<=(rhs_type rhs) const {\t    \\\n\t\treturn operator<(rhs) || operator==(rhs); } \\\n\t    bool operator>(rhs_type rhs) const {\t    \\\n\t\treturn !operator<=(rhs); }\t\t    \\\n\t    bool operator>=(rhs_type rhs) const {\t    \\\n\t\treturn !operator<(rhs); }\n\n\n#endif\t/* __PJPP_TYPES_HPP__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pjlib++.hpp",
    "content": "/* $Id: pjlib++.hpp 2394 2008-12-23 17:27:53Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIBPP_H__\n#define __PJLIBPP_H__\n\n#include <pj++/file.hpp>\n#include <pj++/pool.hpp>\n#include <pj++/hash.hpp>\n#include <pj++/list.hpp>\n#include <pj++/os.hpp>\n#include <pj++/proactor.hpp>\n#include <pj++/scanner.hpp>\n#include <pj++/sock.hpp>\n#include <pj++/string.hpp>\n#include <pj++/timer.hpp>\n#include <pj++/tree.hpp>\n\n#endif\t/* __PJLIBPP_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib/include/pjlib.h",
    "content": "/* $Id: pjlib.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#ifndef __PJLIB_H__\n#define __PJLIB_H__\n\n/**\n * @file pjlib.h\n * @brief Include all PJLIB header files.\n */\n\n#include <pj/activesock.h>\n#include <pj/addr_resolv.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n#include <pj/errno.h>\n#include <pj/except.h>\n#include <pj/fifobuf.h>\n#include <pj/file_access.h>\n#include <pj/file_io.h>\n#include <pj/guid.h>\n#include <pj/hash.h>\n#include <pj/ioqueue.h>\n#include <pj/ip_helper.h>\n#include <pj/list.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/math.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/pool_buf.h>\n#include <pj/rand.h>\n#include <pj/rbtree.h>\n#include <pj/sock.h>\n#include <pj/sock_qos.h>\n#include <pj/sock_select.h>\n#include <pj/ssl_sock.h>\n#include <pj/string.h>\n#include <pj/timer.h>\n#include <pj/unicode.h>\n\n#include <pj/compat/high_precision.h>\n\n#endif  /* __PJLIB_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/activesock.c",
    "content": "/* $Id: activesock.c 4461 2013-04-05 03:02:19Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/activesock.h>\n#include <pj/compat/socket.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/sock.h>\n#include <pj/string.h>\n\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\n#   include <CFNetwork/CFNetwork.h>\n\n    static pj_bool_t ios_bg_support = PJ_TRUE;\n#endif\n\n#define PJ_ACTIVESOCK_MAX_LOOP\t    50\n\n\nenum read_type\n{\n    TYPE_NONE,\n    TYPE_RECV,\n    TYPE_RECV_FROM\n};\n\nenum shutdown_dir\n{\n    SHUT_NONE = 0,\n    SHUT_RX = 1,\n    SHUT_TX = 2\n};\n\nstruct read_op\n{\n    pj_ioqueue_op_key_t\t op_key;\n    pj_uint8_t\t\t*pkt;\n    unsigned\t\t max_size;\n    pj_size_t\t\t size;\n    pj_sockaddr\t\t src_addr;\n    int\t\t\t src_addr_len;\n};\n\nstruct accept_op\n{\n    pj_ioqueue_op_key_t\t op_key;\n    pj_sock_t\t\t new_sock;\n    pj_sockaddr\t\t rem_addr;\n    int\t\t\t rem_addr_len;\n};\n\nstruct send_data\n{\n    pj_uint8_t\t\t*data;\n    pj_ssize_t\t\t len;\n    pj_ssize_t\t\t sent;\n    unsigned\t\t flags;\n};\n\nstruct pj_activesock_t\n{\n    pj_ioqueue_key_t\t*key;\n    pj_bool_t\t\t stream_oriented;\n    pj_bool_t\t\t whole_data;\n    pj_ioqueue_t\t*ioqueue;\n    void\t\t*user_data;\n    unsigned\t\t async_count;\n    unsigned\t \t shutdown;\n    unsigned\t\t max_loop;\n    pj_activesock_cb\t cb;\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\n    int\t\t\t bg_setting;\n    pj_sock_t\t\t sock;\n    CFReadStreamRef\t readStream;\n#endif\n    \n    unsigned\t\t err_counter;\n    pj_status_t\t\t last_err;\n\n    struct send_data\t send_data;\n\n    struct read_op\t*read_op;\n    pj_uint32_t\t\t read_flags;\n    enum read_type\t read_type;\n\n    struct accept_op\t*accept_op;\n};\n\n\nstatic void ioqueue_on_read_complete(pj_ioqueue_key_t *key, \n\t\t\t\t     pj_ioqueue_op_key_t *op_key, \n\t\t\t\t     pj_ssize_t bytes_read);\nstatic void ioqueue_on_write_complete(pj_ioqueue_key_t *key, \n\t\t\t\t      pj_ioqueue_op_key_t *op_key,\n\t\t\t\t      pj_ssize_t bytes_sent);\n#if PJ_HAS_TCP\nstatic void ioqueue_on_accept_complete(pj_ioqueue_key_t *key, \n\t\t\t\t       pj_ioqueue_op_key_t *op_key,\n\t\t\t\t       pj_sock_t sock, \n\t\t\t\t       pj_status_t status);\nstatic void ioqueue_on_connect_complete(pj_ioqueue_key_t *key, \n\t\t\t\t\tpj_status_t status);\n#endif\n\nPJ_DEF(void) pj_activesock_cfg_default(pj_activesock_cfg *cfg)\n{\n    pj_bzero(cfg, sizeof(*cfg));\n    cfg->async_cnt = 1;\n    cfg->concurrency = -1;\n    cfg->whole_data = PJ_TRUE;\n}\n\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\nstatic void activesock_destroy_iphone_os_stream(pj_activesock_t *asock)\n{\n    if (asock->readStream) {\n\tCFReadStreamClose(asock->readStream);\n\tCFRelease(asock->readStream);\n\tasock->readStream = NULL;\n    }\n}\n\nstatic void activesock_create_iphone_os_stream(pj_activesock_t *asock)\n{\n    if (ios_bg_support && asock->bg_setting && asock->stream_oriented) {\n\tactivesock_destroy_iphone_os_stream(asock);\n\n\tCFStreamCreatePairWithSocket(kCFAllocatorDefault, asock->sock,\n\t\t\t\t     &asock->readStream, NULL);\n\n\tif (!asock->readStream ||\n\t    CFReadStreamSetProperty(asock->readStream,\n\t\t\t\t    kCFStreamNetworkServiceType,\n\t\t\t\t    kCFStreamNetworkServiceTypeVoIP)\n\t    != TRUE ||\n\t    CFReadStreamOpen(asock->readStream) != TRUE)\n\t{\n\t    PJ_LOG(2,(\"\", \"Failed to configure TCP transport for VoIP \"\n\t\t      \"usage. Usage of THIS particular TCP transport in \"\n\t\t      \"background mode will not be supported.\"));\n\n\t    \n\t    activesock_destroy_iphone_os_stream(asock);\n\t}\n    }\n}\n\n\nPJ_DEF(void) pj_activesock_set_iphone_os_bg(pj_activesock_t *asock,\n\t\t\t\t\t    int val)\n{\n    asock->bg_setting = val;\n    if (asock->bg_setting)\n\tactivesock_create_iphone_os_stream(asock);\n    else\n\tactivesock_destroy_iphone_os_stream(asock);\n}\n\nPJ_DEF(void) pj_activesock_enable_iphone_os_bg(pj_bool_t val)\n{\n    ios_bg_support = val;\n}\n#endif\n\nPJ_DEF(pj_status_t) pj_activesock_create( pj_pool_t *pool,\n\t\t\t\t\t  pj_sock_t sock,\n\t\t\t\t\t  int sock_type,\n\t\t\t\t\t  const pj_activesock_cfg *opt,\n\t\t\t\t\t  pj_ioqueue_t *ioqueue,\n\t\t\t\t\t  const pj_activesock_cb *cb,\n\t\t\t\t\t  void *user_data,\n\t\t\t\t\t  pj_activesock_t **p_asock)\n{\n    pj_activesock_t *asock;\n    pj_ioqueue_callback ioq_cb;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && ioqueue && cb && p_asock, PJ_EINVAL);\n    PJ_ASSERT_RETURN(sock!=0 && sock!=PJ_INVALID_SOCKET, PJ_EINVAL);\n    PJ_ASSERT_RETURN(sock_type==pj_SOCK_STREAM() ||\n\t\t     sock_type==pj_SOCK_DGRAM(), PJ_EINVAL);\n    PJ_ASSERT_RETURN(!opt || opt->async_cnt >= 1, PJ_EINVAL);\n\n    asock = PJ_POOL_ZALLOC_T(pool, pj_activesock_t);\n    asock->ioqueue = ioqueue;\n    asock->stream_oriented = (sock_type == pj_SOCK_STREAM());\n    asock->async_count = (opt? opt->async_cnt : 1);\n    asock->whole_data = (opt? opt->whole_data : 1);\n    asock->max_loop = PJ_ACTIVESOCK_MAX_LOOP;\n    asock->user_data = user_data;\n    pj_memcpy(&asock->cb, cb, sizeof(*cb));\n\n    pj_bzero(&ioq_cb, sizeof(ioq_cb));\n    ioq_cb.on_read_complete = &ioqueue_on_read_complete;\n    ioq_cb.on_write_complete = &ioqueue_on_write_complete;\n#if PJ_HAS_TCP\n    ioq_cb.on_connect_complete = &ioqueue_on_connect_complete;\n    ioq_cb.on_accept_complete = &ioqueue_on_accept_complete;\n#endif\n\n    status = pj_ioqueue_register_sock2(pool, ioqueue, sock,\n                                       (opt? opt->grp_lock : NULL),\n                                       asock, &ioq_cb, &asock->key);\n    if (status != PJ_SUCCESS) {\n\tpj_activesock_close(asock);\n\treturn status;\n    }\n    \n    if (asock->whole_data) {\n\t/* Must disable concurrency otherwise there is a race condition */\n\tpj_ioqueue_set_concurrency(asock->key, 0);\n    } else if (opt && opt->concurrency >= 0) {\n\tpj_ioqueue_set_concurrency(asock->key, opt->concurrency);\n    }\n\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\n    asock->sock = sock;\n    asock->bg_setting = PJ_ACTIVESOCK_TCP_IPHONE_OS_BG;\n#endif\n\n    *p_asock = asock;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_activesock_create_udp( pj_pool_t *pool,\n\t\t\t\t\t      const pj_sockaddr *addr,\n\t\t\t\t\t      const pj_activesock_cfg *opt,\n\t\t\t\t\t      pj_ioqueue_t *ioqueue,\n\t\t\t\t\t      const pj_activesock_cb *cb,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      pj_activesock_t **p_asock,\n\t\t\t\t\t      pj_sockaddr *bound_addr)\n{\n    pj_sock_t sock_fd;\n    pj_sockaddr default_addr;\n    pj_status_t status;\n\n    if (addr == NULL) {\n\tpj_sockaddr_init(pj_AF_INET(), &default_addr, NULL, 0);\n\taddr = &default_addr;\n    }\n\n    status = pj_sock_socket(addr->addr.sa_family, pj_SOCK_DGRAM(), 0, \n\t\t\t    &sock_fd);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    status = pj_sock_bind(sock_fd, addr, pj_sockaddr_get_len(addr));\n    if (status != PJ_SUCCESS) {\n\tpj_sock_close(sock_fd);\n\treturn status;\n    }\n\n    status = pj_activesock_create(pool, sock_fd, pj_SOCK_DGRAM(), opt,\n\t\t\t\t  ioqueue, cb, user_data, p_asock);\n    if (status != PJ_SUCCESS) {\n\tpj_sock_close(sock_fd);\n\treturn status;\n    }\n\n    if (bound_addr) {\n\tint addr_len = sizeof(*bound_addr);\n\tstatus = pj_sock_getsockname(sock_fd, bound_addr, &addr_len);\n\tif (status != PJ_SUCCESS) {\n\t    pj_activesock_close(*p_asock);\n\t    return status;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_activesock_close(pj_activesock_t *asock)\n{\n    PJ_ASSERT_RETURN(asock, PJ_EINVAL);\n    asock->shutdown = SHUT_RX | SHUT_TX;\n    if (asock->key) {\n\tpj_ioqueue_unregister(asock->key);\n\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\n\tactivesock_destroy_iphone_os_stream(asock);\n#endif\t\n\n\tasock->key = NULL;\n    }\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_activesock_set_user_data( pj_activesock_t *asock,\n\t\t\t\t\t\t void *user_data)\n{\n    PJ_ASSERT_RETURN(asock, PJ_EINVAL);\n    asock->user_data = user_data;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(void*) pj_activesock_get_user_data(pj_activesock_t *asock)\n{\n    PJ_ASSERT_RETURN(asock, NULL);\n    return asock->user_data;\n}\n\n\nPJ_DEF(pj_status_t) pj_activesock_start_read(pj_activesock_t *asock,\n\t\t\t\t\t     pj_pool_t *pool,\n\t\t\t\t\t     unsigned buff_size,\n\t\t\t\t\t     pj_uint32_t flags)\n{\n    void **readbuf;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(asock && pool && buff_size, PJ_EINVAL);\n\n    readbuf = (void**) pj_pool_calloc(pool, asock->async_count, \n\t\t\t\t      sizeof(void*));\n\n    for (i=0; i<asock->async_count; ++i) {\n\treadbuf[i] = pj_pool_alloc(pool, buff_size);\n    }\n\n    return pj_activesock_start_read2(asock, pool, buff_size, readbuf, flags);\n}\n\n\nPJ_DEF(pj_status_t) pj_activesock_start_read2( pj_activesock_t *asock,\n\t\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t\t       unsigned buff_size,\n\t\t\t\t\t       void *readbuf[],\n\t\t\t\t\t       pj_uint32_t flags)\n{\n    unsigned i;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(asock && pool && buff_size, PJ_EINVAL);\n    PJ_ASSERT_RETURN(asock->read_type == TYPE_NONE, PJ_EINVALIDOP);\n    PJ_ASSERT_RETURN(asock->read_op == NULL, PJ_EINVALIDOP);\n\n    asock->read_op = (struct read_op*)\n\t\t     pj_pool_calloc(pool, asock->async_count, \n\t\t\t\t    sizeof(struct read_op));\n    asock->read_type = TYPE_RECV;\n    asock->read_flags = flags;\n\n    for (i=0; i<asock->async_count; ++i) {\n\tstruct read_op *r = &asock->read_op[i];\n\tpj_ssize_t size_to_read;\n\n\tr->pkt = (pj_uint8_t*)readbuf[i];\n\tsize_to_read = r->max_size = buff_size;\n\n\tstatus = pj_ioqueue_recv(asock->key, &r->op_key, r->pkt, &size_to_read,\n\t\t\t\t PJ_IOQUEUE_ALWAYS_ASYNC | flags);\n\tPJ_ASSERT_RETURN(status != PJ_SUCCESS, PJ_EBUG);\n\n\tif (status != PJ_EPENDING)\n\t    return status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_activesock_start_recvfrom(pj_activesock_t *asock,\n\t\t\t\t\t\t pj_pool_t *pool,\n\t\t\t\t\t\t unsigned buff_size,\n\t\t\t\t\t\t pj_uint32_t flags)\n{\n    void **readbuf;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(asock && pool && buff_size, PJ_EINVAL);\n\n    readbuf = (void**) pj_pool_calloc(pool, asock->async_count, \n\t\t\t\t      sizeof(void*));\n\n    for (i=0; i<asock->async_count; ++i) {\n\treadbuf[i] = pj_pool_alloc(pool, buff_size);\n    }\n\n    return pj_activesock_start_recvfrom2(asock, pool, buff_size, \n\t\t\t\t\t readbuf, flags);\n}\n\n\nPJ_DEF(pj_status_t) pj_activesock_start_recvfrom2( pj_activesock_t *asock,\n\t\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t\t   unsigned buff_size,\n\t\t\t\t\t\t   void *readbuf[],\n\t\t\t\t\t\t   pj_uint32_t flags)\n{\n    unsigned i;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(asock && pool && buff_size, PJ_EINVAL);\n    PJ_ASSERT_RETURN(asock->read_type == TYPE_NONE, PJ_EINVALIDOP);\n\n    asock->read_op = (struct read_op*)\n\t\t     pj_pool_calloc(pool, asock->async_count, \n\t\t\t\t    sizeof(struct read_op));\n    asock->read_type = TYPE_RECV_FROM;\n    asock->read_flags = flags;\n\n    for (i=0; i<asock->async_count; ++i) {\n\tstruct read_op *r = &asock->read_op[i];\n\tpj_ssize_t size_to_read;\n\n\tr->pkt = (pj_uint8_t*) readbuf[i];\n\tsize_to_read = r->max_size = buff_size;\n\tr->src_addr_len = sizeof(r->src_addr);\n\n\tstatus = pj_ioqueue_recvfrom(asock->key, &r->op_key, r->pkt,\n\t\t\t\t     &size_to_read, \n\t\t\t\t     PJ_IOQUEUE_ALWAYS_ASYNC | flags,\n\t\t\t\t     &r->src_addr, &r->src_addr_len);\n\tPJ_ASSERT_RETURN(status != PJ_SUCCESS, PJ_EBUG);\n\n\tif (status != PJ_EPENDING)\n\t    return status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void ioqueue_on_read_complete(pj_ioqueue_key_t *key, \n\t\t\t\t     pj_ioqueue_op_key_t *op_key, \n\t\t\t\t     pj_ssize_t bytes_read)\n{\n    pj_activesock_t *asock;\n    struct read_op *r = (struct read_op*)op_key;\n    unsigned loop = 0;\n    pj_status_t status;\n\n    asock = (pj_activesock_t*) pj_ioqueue_get_user_data(key);\n\n    /* Ignore if we've been shutdown */\n    if (asock->shutdown & SHUT_RX)\n\treturn;\n\n    do {\n\tunsigned flags;\n\n\tif (bytes_read > 0) {\n\t    /*\n\t     * We've got new data.\n\t     */\n\t    pj_size_t remainder;\n\t    pj_bool_t ret;\n\n\t    /* Append this new data to existing data. If socket is stream \n\t     * oriented, user might have left some data in the buffer. \n\t     * Otherwise if socket is datagram there will be nothing in \n\t     * existing packet hence the packet will contain only the new\n\t     * packet.\n\t     */\n\t    r->size += bytes_read;\n\n\t    /* Set default remainder to zero */\n\t    remainder = 0;\n\n\t    /* And return value to TRUE */\n\t    ret = PJ_TRUE;\n\n\t    /* Notify callback */\n\t    if (asock->read_type == TYPE_RECV && asock->cb.on_data_read) {\n\t\tret = (*asock->cb.on_data_read)(asock, r->pkt, r->size,\n\t\t\t\t\t\tPJ_SUCCESS, &remainder);\n\t    } else if (asock->read_type == TYPE_RECV_FROM && \n\t\t       asock->cb.on_data_recvfrom) \n\t    {\n\t\tret = (*asock->cb.on_data_recvfrom)(asock, r->pkt, r->size,\n\t\t\t\t\t\t    &r->src_addr, \n\t\t\t\t\t\t    r->src_addr_len,\n\t\t\t\t\t\t    PJ_SUCCESS);\n\t    }\n\n\t    /* If callback returns false, we have been destroyed! */\n\t    if (!ret)\n\t\treturn;\n\n\t    /* Only stream oriented socket may leave data in the packet */\n\t    if (asock->stream_oriented) {\n\t\tr->size = remainder;\n\t    } else {\n\t\tr->size = 0;\n\t    }\n\n\t} else if (bytes_read <= 0 &&\n\t\t   -bytes_read != PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK) &&\n\t\t   -bytes_read != PJ_STATUS_FROM_OS(OSERR_EINPROGRESS) && \n\t\t   (asock->stream_oriented ||\n\t\t    -bytes_read != PJ_STATUS_FROM_OS(OSERR_ECONNRESET))) \n\t{\n\t    pj_size_t remainder;\n\t    pj_bool_t ret;\n\n\t    if (bytes_read == 0) {\n\t\t/* For stream/connection oriented socket, this means the \n\t\t * connection has been closed. For datagram sockets, it means\n\t\t * we've received datagram with zero length.\n\t\t */\n\t\tif (asock->stream_oriented)\n\t\t    status = PJ_EEOF;\n\t\telse\n\t\t    status = PJ_SUCCESS;\n\t    } else {\n\t\t/* This means we've got an error. If this is stream/connection\n\t\t * oriented, it means connection has been closed. For datagram\n\t\t * sockets, it means we've got some error (e.g. EWOULDBLOCK).\n\t\t */\n\t\tstatus = (pj_status_t)-bytes_read;\n\t    }\n\n\t    /* Set default remainder to zero */\n\t    remainder = 0;\n\n\t    /* And return value to TRUE */\n\t    ret = PJ_TRUE;\n\n\t    /* Notify callback */\n\t    if (asock->read_type == TYPE_RECV && asock->cb.on_data_read) {\n\t\t/* For connection oriented socket, we still need to report \n\t\t * the remainder data (if any) to the user to let user do \n\t\t * processing with the remainder data before it closes the\n\t\t * connection.\n\t\t * If there is no remainder data, set the packet to NULL.\n\t\t */\n\n\t\t/* Shouldn't set the packet to NULL, as there may be active \n\t\t * socket user, such as SSL socket, that needs to have access\n\t\t * to the read buffer packet.\n\t\t */\n\t\t//ret = (*asock->cb.on_data_read)(asock, (r->size? r->pkt:NULL),\n\t\t//\t\t\t\tr->size, status, &remainder);\n\t\tret = (*asock->cb.on_data_read)(asock, r->pkt, r->size,\n\t\t\t\t\t\tstatus, &remainder);\n\n\t    } else if (asock->read_type == TYPE_RECV_FROM && \n\t\t       asock->cb.on_data_recvfrom) \n\t    {\n\t\t/* This would always be datagram oriented hence there's \n\t\t * nothing in the packet. We can't be sure if there will be\n\t\t * anything useful in the source_addr, so just put NULL\n\t\t * there too.\n\t\t */\n\t\t/* In some scenarios, status may be PJ_SUCCESS. The upper \n\t\t * layer application may not expect the callback to be called\n\t\t * with successful status and NULL data, so lets not call the\n\t\t * callback if the status is PJ_SUCCESS.\n\t\t */\n\t\tif (status != PJ_SUCCESS ) {\n\t\t    ret = (*asock->cb.on_data_recvfrom)(asock, NULL, 0,\n\t\t\t\t\t\t\tNULL, 0, status);\n\t\t}\n\t    }\n\n\t    /* If callback returns false, we have been destroyed! */\n\t    if (!ret)\n\t\treturn;\n\n\t    /* Also stop further read if we've been shutdown */\n\t    if (asock->shutdown & SHUT_RX)\n\t\treturn;\n\n\t    /* Only stream oriented socket may leave data in the packet */\n\t    if (asock->stream_oriented) {\n\t\tr->size = remainder;\n\t    } else {\n\t\tr->size = 0;\n\t    }\n\t}\n\n\t/* Read next data. We limit ourselves to processing max_loop immediate\n\t * data, so when the loop counter has exceeded this value, force the\n\t * read()/recvfrom() to return pending operation to allow the program\n\t * to do other jobs.\n\t */\n\tbytes_read = r->max_size - r->size;\n\tflags = asock->read_flags;\n\tif (++loop >= asock->max_loop)\n\t    flags |= PJ_IOQUEUE_ALWAYS_ASYNC;\n\n\tif (asock->read_type == TYPE_RECV) {\n\t    status = pj_ioqueue_recv(key, op_key, r->pkt + r->size, \n\t\t\t\t     &bytes_read, flags);\n\t} else {\n\t    r->src_addr_len = sizeof(r->src_addr);\n\t    status = pj_ioqueue_recvfrom(key, op_key, r->pkt + r->size,\n\t\t\t\t         &bytes_read, flags,\n\t\t\t\t\t &r->src_addr, &r->src_addr_len);\n\t}\n\n\tif (status == PJ_SUCCESS) {\n\t    /* Immediate data */\n\t    ;\n\t} else if (status != PJ_EPENDING && status != PJ_ECANCELLED) {\n\t    /* Error */\n\t    bytes_read = -status;\n\t} else {\n\t    break;\n\t}\n    } while (1);\n\n}\n\n\nstatic pj_status_t send_remaining(pj_activesock_t *asock, \n\t\t\t\t  pj_ioqueue_op_key_t *send_key)\n{\n    struct send_data *sd = (struct send_data*)send_key->activesock_data;\n    pj_status_t status;\n\n    do {\n\tpj_ssize_t size;\n\n\tsize = sd->len - sd->sent;\n\tstatus = pj_ioqueue_send(asock->key, send_key, \n\t\t\t\t sd->data+sd->sent, &size, sd->flags);\n\tif (status != PJ_SUCCESS) {\n\t    /* Pending or error */\n\t    break;\n\t}\n\n\tsd->sent += size;\n\tif (sd->sent == sd->len) {\n\t    /* The whole data has been sent. */\n\t    return PJ_SUCCESS;\n\t}\n\n    } while (sd->sent < sd->len);\n\n    return status;\n}\n\n\nPJ_DEF(pj_status_t) pj_activesock_send( pj_activesock_t *asock,\n\t\t\t\t\tpj_ioqueue_op_key_t *send_key,\n\t\t\t\t\tconst void *data,\n\t\t\t\t\tpj_ssize_t *size,\n\t\t\t\t\tunsigned flags)\n{\n    PJ_ASSERT_RETURN(asock && send_key && data && size, PJ_EINVAL);\n\n    if (asock->shutdown & SHUT_TX)\n\treturn PJ_EINVALIDOP;\n\n    send_key->activesock_data = NULL;\n\n    if (asock->whole_data) {\n\tpj_ssize_t whole;\n\tpj_status_t status;\n\n\twhole = *size;\n\n\tstatus = pj_ioqueue_send(asock->key, send_key, data, size, flags);\n\tif (status != PJ_SUCCESS) {\n\t    /* Pending or error */\n\t    return status;\n\t}\n\n\tif (*size == whole) {\n\t    /* The whole data has been sent. */\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* Data was partially sent */\n\tasock->send_data.data = (pj_uint8_t*)data;\n\tasock->send_data.len = whole;\n\tasock->send_data.sent = *size;\n\tasock->send_data.flags = flags;\n\tsend_key->activesock_data = &asock->send_data;\n\n\t/* Try again */\n\tstatus = send_remaining(asock, send_key);\n\tif (status == PJ_SUCCESS) {\n\t    *size = whole;\n\t}\n\treturn status;\n\n    } else {\n\treturn pj_ioqueue_send(asock->key, send_key, data, size, flags);\n    }\n}\n\n\nPJ_DEF(pj_status_t) pj_activesock_sendto( pj_activesock_t *asock,\n\t\t\t\t\t  pj_ioqueue_op_key_t *send_key,\n\t\t\t\t\t  const void *data,\n\t\t\t\t\t  pj_ssize_t *size,\n\t\t\t\t\t  unsigned flags,\n\t\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t\t  int addr_len)\n{\n    PJ_ASSERT_RETURN(asock && send_key && data && size && addr && addr_len, \n\t\t     PJ_EINVAL);\n\n    if (asock->shutdown & SHUT_TX)\n\treturn PJ_EINVALIDOP;\n\n    return pj_ioqueue_sendto(asock->key, send_key, data, size, flags,\n\t\t\t     addr, addr_len);\n}\n\n\nstatic void ioqueue_on_write_complete(pj_ioqueue_key_t *key, \n\t\t\t\t      pj_ioqueue_op_key_t *op_key,\n\t\t\t\t      pj_ssize_t bytes_sent)\n{\n    pj_activesock_t *asock;\n\n    asock = (pj_activesock_t*) pj_ioqueue_get_user_data(key);\n\n    /* Ignore if we've been shutdown. This may cause data to be partially\n     * sent even when 'wholedata' was requested if the OS only sent partial\n     * buffer.\n     */\n    if (asock->shutdown & SHUT_TX)\n\treturn;\n\n    if (bytes_sent > 0 && op_key->activesock_data) {\n\t/* whole_data is requested. Make sure we send all the data */\n\tstruct send_data *sd = (struct send_data*)op_key->activesock_data;\n\n\tsd->sent += bytes_sent;\n\tif (sd->sent == sd->len) {\n\t    /* all has been sent */\n\t    bytes_sent = sd->sent;\n\t    op_key->activesock_data = NULL;\n\t} else {\n\t    /* send remaining data */\n\t    pj_status_t status;\n\n\t    status = send_remaining(asock, op_key);\n\t    if (status == PJ_EPENDING)\n\t\treturn;\n\t    else if (status == PJ_SUCCESS)\n\t\tbytes_sent = sd->sent;\n\t    else\n\t\tbytes_sent = -status;\n\n\t    op_key->activesock_data = NULL;\n\t}\n    } \n\n    if (asock->cb.on_data_sent) {\n\tpj_bool_t ret;\n\n\tret = (*asock->cb.on_data_sent)(asock, op_key, bytes_sent);\n\n\t/* If callback returns false, we have been destroyed! */\n\tif (!ret)\n\t    return;\n    }\n}\n\n#if PJ_HAS_TCP\nPJ_DEF(pj_status_t) pj_activesock_start_accept(pj_activesock_t *asock,\n\t\t\t\t\t       pj_pool_t *pool)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(asock, PJ_EINVAL);\n    PJ_ASSERT_RETURN(asock->accept_op==NULL, PJ_EINVALIDOP);\n\n    /* Ignore if we've been shutdown */\n    if (asock->shutdown)\n\treturn PJ_EINVALIDOP;\n\n    asock->accept_op = (struct accept_op*)\n\t\t       pj_pool_calloc(pool, asock->async_count,\n\t\t\t\t      sizeof(struct accept_op));\n    for (i=0; i<asock->async_count; ++i) {\n\tstruct accept_op *a = &asock->accept_op[i];\n\tpj_status_t status;\n\n\tdo {\n\t    a->new_sock = PJ_INVALID_SOCKET;\n\t    a->rem_addr_len = sizeof(a->rem_addr);\n\n\t    status = pj_ioqueue_accept(asock->key, &a->op_key, &a->new_sock,\n\t\t\t\t       NULL, &a->rem_addr, &a->rem_addr_len);\n\t    if (status == PJ_SUCCESS) {\n\t\t/* We've got immediate connection. Not sure if it's a good\n\t\t * idea to call the callback now (probably application will\n\t\t * not be prepared to process it), so lets just silently\n\t\t * close the socket.\n\t\t */\n\t\tpj_sock_close(a->new_sock);\n\t    }\n\t} while (status == PJ_SUCCESS);\n\n\tif (status != PJ_EPENDING) {\n\t    return status;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void ioqueue_on_accept_complete(pj_ioqueue_key_t *key, \n\t\t\t\t       pj_ioqueue_op_key_t *op_key,\n\t\t\t\t       pj_sock_t new_sock, \n\t\t\t\t       pj_status_t status)\n{\n    pj_activesock_t *asock = (pj_activesock_t*) pj_ioqueue_get_user_data(key);\n    struct accept_op *accept_op = (struct accept_op*) op_key;\n\n    PJ_UNUSED_ARG(new_sock);\n\n    /* Ignore if we've been shutdown */\n    if (asock->shutdown)\n\treturn;\n\n    do {\n\tif (status == asock->last_err && status != PJ_SUCCESS) {\n\t    asock->err_counter++;\n\t    if (asock->err_counter >= PJ_ACTIVESOCK_MAX_CONSECUTIVE_ACCEPT_ERROR) {\n\t\tPJ_LOG(3, (\"\", \"Received %d consecutive errors: %d for the accept()\"\n\t\t\t       \" operation, stopping further ioqueue accepts.\",\n\t\t\t       asock->err_counter, asock->last_err));\n\t\t\n\t\tif ((status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) && \n\t\t    (asock->cb.on_accept_complete2)) \n\t\t{\n\t\t    (*asock->cb.on_accept_complete2)(asock, \n\t\t\t\t\t\t     accept_op->new_sock,\n\t\t\t\t\t\t     &accept_op->rem_addr,\n\t\t\t\t\t\t     accept_op->rem_addr_len,\n\t\t\t\t\t\t     PJ_ESOCKETSTOP);\n\t\t}\n\t\treturn;\n\t    }\n\t} else {\n\t    asock->err_counter = 0;\n\t    asock->last_err = status;\n\t}\n\n\tif (status==PJ_SUCCESS && (asock->cb.on_accept_complete2 || \n\t\t\t\t   asock->cb.on_accept_complete)) {\n\t    pj_bool_t ret;\n\n\t    /* Notify callback */\n\t    if (asock->cb.on_accept_complete2) {\n\t\tret = (*asock->cb.on_accept_complete2)(asock, \n\t\t\t\t\t\t       accept_op->new_sock,\n\t\t\t\t\t\t       &accept_op->rem_addr,\n\t\t\t\t\t\t       accept_op->rem_addr_len,\n\t\t\t\t\t\t       status);\n\t    } else {\n\t\tret = (*asock->cb.on_accept_complete)(asock, \n\t\t\t\t\t\t      accept_op->new_sock,\n\t\t\t\t\t\t      &accept_op->rem_addr,\n\t\t\t\t\t\t      accept_op->rem_addr_len);\t    \n\t    }\n\n\t    /* If callback returns false, we have been destroyed! */\n\t    if (!ret)\n\t\treturn;\n\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\n\t    activesock_create_iphone_os_stream(asock);\n#endif\n\t} else if (status==PJ_SUCCESS) {\n\t    /* Application doesn't handle the new socket, we need to \n\t     * close it to avoid resource leak.\n\t     */\n\t    pj_sock_close(accept_op->new_sock);\n\t}\n\n\t/* Don't start another accept() if we've been shutdown */\n\tif (asock->shutdown)\n\t    return;\n\n\t/* Prepare next accept() */\n\taccept_op->new_sock = PJ_INVALID_SOCKET;\n\taccept_op->rem_addr_len = sizeof(accept_op->rem_addr);\n\n\tstatus = pj_ioqueue_accept(asock->key, op_key, &accept_op->new_sock,\n\t\t\t\t   NULL, &accept_op->rem_addr, \n\t\t\t\t   &accept_op->rem_addr_len);\n\n    } while (status != PJ_EPENDING && status != PJ_ECANCELLED);\n}\n\n\nPJ_DEF(pj_status_t) pj_activesock_start_connect( pj_activesock_t *asock,\n\t\t\t\t\t\t pj_pool_t *pool,\n\t\t\t\t\t\t const pj_sockaddr_t *remaddr,\n\t\t\t\t\t\t int addr_len)\n{\n    PJ_UNUSED_ARG(pool);\n\n    if (asock->shutdown)\n\treturn PJ_EINVALIDOP;\n\n    return pj_ioqueue_connect(asock->key, remaddr, addr_len);\n}\n\nstatic void ioqueue_on_connect_complete(pj_ioqueue_key_t *key, \n\t\t\t\t\tpj_status_t status)\n{\n    pj_activesock_t *asock = (pj_activesock_t*) pj_ioqueue_get_user_data(key);\n\n    /* Ignore if we've been shutdown */\n    if (asock->shutdown)\n\treturn;\n\n    if (asock->cb.on_connect_complete) {\n\tpj_bool_t ret;\n\n\tret = (*asock->cb.on_connect_complete)(asock, status);\n\n\tif (!ret) {\n\t    /* We've been destroyed */\n\t    return;\n\t}\n\t\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\n\tactivesock_create_iphone_os_stream(asock);\n#endif\n\t\n    }\n}\n#endif\t/* PJ_HAS_TCP */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/addr_resolv_linux_kernel.c",
    "content": "/* $Id: addr_resolv_linux_kernel.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/addr_resolv.h>\n\nPJ_DEF(pj_status_t) pj_gethostbyname(const pj_str_t *hostname, pj_hostent *phe)\n{\n    return -1;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/addr_resolv_sock.c",
    "content": "/* $Id: addr_resolv_sock.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/addr_resolv.h>\n#include <pj/assert.h>\n#include <pj/string.h>\n#include <pj/errno.h>\n#include <pj/ip_helper.h>\n#include <pj/compat/socket.h>\n\n#if defined(PJ_GETADDRINFO_USE_CFHOST) && PJ_GETADDRINFO_USE_CFHOST!=0\n#   include <CoreFoundation/CFString.h>\n#   include <CFNetwork/CFHost.h>\n#endif\n\nPJ_DEF(pj_status_t) pj_gethostbyname(const pj_str_t *hostname, pj_hostent *phe)\n{\n    struct hostent *he;\n    char copy[PJ_MAX_HOSTNAME];\n\n    pj_assert(hostname && hostname ->slen < PJ_MAX_HOSTNAME);\n    \n    if (hostname->slen >= PJ_MAX_HOSTNAME)\n\treturn PJ_ENAMETOOLONG;\n\n    pj_memcpy(copy, hostname->ptr, hostname->slen);\n    copy[ hostname->slen ] = '\\0';\n\n    he = gethostbyname(copy);\n    if (!he) {\n\treturn PJ_ERESOLVE;\n\t/* DO NOT use pj_get_netos_error() since host resolution error\n\t * is reported in h_errno instead of errno!\n\treturn pj_get_netos_error();\n\t */\n    }\n\n    phe->h_name = he->h_name;\n    phe->h_aliases = he->h_aliases;\n    phe->h_addrtype = he->h_addrtype;\n    phe->h_length = he->h_length;\n    phe->h_addr_list = he->h_addr_list;\n\n    return PJ_SUCCESS;\n}\n\n/* Resolve IPv4/IPv6 address */\nPJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename,\n\t\t\t\t   unsigned *count, pj_addrinfo ai[])\n{\n#if defined(PJ_SOCK_HAS_GETADDRINFO) && PJ_SOCK_HAS_GETADDRINFO!=0\n    char nodecopy[PJ_MAX_HOSTNAME];\n    pj_bool_t has_addr = PJ_FALSE;\n    unsigned i;\n#if defined(PJ_GETADDRINFO_USE_CFHOST) && PJ_GETADDRINFO_USE_CFHOST!=0\n    CFStringRef hostname;\n    CFHostRef hostRef;\n    pj_status_t status = PJ_SUCCESS;\n#else\n    int rc;\n    struct addrinfo hint, *res, *orig_res;\n#endif\n\n    PJ_ASSERT_RETURN(nodename && count && *count && ai, PJ_EINVAL);\n    PJ_ASSERT_RETURN(nodename->ptr && nodename->slen, PJ_EINVAL);\n    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6 ||\n\t\t     af==PJ_AF_UNSPEC, PJ_EINVAL);\n\n    /* Check if nodename is IP address */\n    pj_bzero(&ai[0], sizeof(ai[0]));\n    if ((af==PJ_AF_INET || af==PJ_AF_UNSPEC) &&\n\tpj_inet_pton(PJ_AF_INET, nodename,\n\t\t     &ai[0].ai_addr.ipv4.sin_addr) == PJ_SUCCESS)\n    {\n\taf = PJ_AF_INET;\n\thas_addr = PJ_TRUE;\n    } else if ((af==PJ_AF_INET6 || af==PJ_AF_UNSPEC) &&\n\t       pj_inet_pton(PJ_AF_INET6, nodename,\n\t                    &ai[0].ai_addr.ipv6.sin6_addr) == PJ_SUCCESS)\n    {\n\taf = PJ_AF_INET6;\n\thas_addr = PJ_TRUE;\n    }\n\n    if (has_addr) {\n\tpj_str_t tmp;\n\n\ttmp.ptr = ai[0].ai_canonname;\n\tpj_strncpy_with_null(&tmp, nodename, PJ_MAX_HOSTNAME);\n\tai[0].ai_addr.addr.sa_family = (pj_uint16_t)af;\n\t*count = 1;\n\n\treturn PJ_SUCCESS;\n    }\n\n    /* Copy node name to null terminated string. */\n    if (nodename->slen >= PJ_MAX_HOSTNAME)\n\treturn PJ_ENAMETOOLONG;\n    pj_memcpy(nodecopy, nodename->ptr, nodename->slen);\n    nodecopy[nodename->slen] = '\\0';\n\n#if defined(PJ_GETADDRINFO_USE_CFHOST) && PJ_GETADDRINFO_USE_CFHOST!=0\n    hostname =  CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, nodecopy,\n\t\t\t\t\t\tkCFStringEncodingASCII,\n\t\t\t\t\t\tkCFAllocatorNull);\n    hostRef = CFHostCreateWithName(kCFAllocatorDefault, hostname);\n    if (CFHostStartInfoResolution(hostRef, kCFHostAddresses, nil)) {\n\tCFArrayRef addrRef = CFHostGetAddressing(hostRef, nil);\n\ti = 0;\n\tif (addrRef != nil) {\n\t    CFIndex idx, naddr;\n\t    \n\t    naddr = CFArrayGetCount(addrRef);\n\t    for (idx = 0; idx < naddr && i < *count; idx++) {\n\t\tstruct sockaddr *addr;\n\t\tsize_t addr_size;\n\t\t\n\t\taddr = (struct sockaddr *)\n\t\t       CFDataGetBytePtr(CFArrayGetValueAtIndex(addrRef, idx));\n\t\t/* This should not happen. */\n\t\tpj_assert(addr);\n\t\t\n\t\t/* Ignore unwanted address families */\n\t\tif (af!=PJ_AF_UNSPEC && addr->sa_family != af)\n\t\t    continue;\n\n\t\t/* Store canonical name */\n\t\tpj_ansi_strcpy(ai[i].ai_canonname, nodecopy);\n\t\t\n\t\t/* Store address */\n\t\taddr_size = sizeof(*addr);\n\t\tif (af == PJ_AF_INET6) {\n\t\t    addr_size = addr->sa_len;\n\t\t}\n\t\tPJ_ASSERT_ON_FAIL(addr_size <= sizeof(pj_sockaddr), \t\t\t\t  continue);\n\t\tpj_memcpy(&ai[i].ai_addr, addr, addr_size);\n\t\tPJ_SOCKADDR_RESET_LEN(&ai[i].ai_addr);\n\t\t\n\t\ti++;\n\t    }\n\t}\n\t\n\t*count = i;\n    } else {\n\tstatus = PJ_ERESOLVE;\n    }\n    \n    CFRelease(hostRef);\n    CFRelease(hostname);\n    \n    return status;\n#else\n    /* Call getaddrinfo() */\n    pj_bzero(&hint, sizeof(hint));\n    hint.ai_family = af;\n\n    rc = getaddrinfo(nodecopy, NULL, &hint, &res);\n    if (rc != 0)\n\treturn PJ_ERESOLVE;\n\n    orig_res = res;\n\n    /* Enumerate each item in the result */\n    for (i=0; i<*count && res; res=res->ai_next) {\n\t/* Ignore unwanted address families */\n\tif (af!=PJ_AF_UNSPEC && res->ai_family != af)\n\t    continue;\n\n\t/* Store canonical name (possibly truncating the name) */\n\tif (res->ai_canonname) {\n\t    pj_ansi_strncpy(ai[i].ai_canonname, res->ai_canonname,\n\t\t\t    sizeof(ai[i].ai_canonname));\n\t    ai[i].ai_canonname[sizeof(ai[i].ai_canonname)-1] = '\\0';\n\t} else {\n\t    pj_ansi_strcpy(ai[i].ai_canonname, nodecopy);\n\t}\n\n\t/* Store address */\n\tPJ_ASSERT_ON_FAIL(res->ai_addrlen <= sizeof(pj_sockaddr), continue);\n\tpj_memcpy(&ai[i].ai_addr, res->ai_addr, res->ai_addrlen);\n\tPJ_SOCKADDR_RESET_LEN(&ai[i].ai_addr);\n\n\t/* Next slot */\n\t++i;\n    }\n\n    *count = i;\n\n    freeaddrinfo(orig_res);\n\n    /* Done */\n    return PJ_SUCCESS;\n#endif\n\n#else\t/* PJ_SOCK_HAS_GETADDRINFO */\n    pj_bool_t has_addr = PJ_FALSE;\n\n    PJ_ASSERT_RETURN(count && *count, PJ_EINVAL);\n\n    /* Check if nodename is IP address */\n    pj_bzero(&ai[0], sizeof(ai[0]));\n    if ((af==PJ_AF_INET || af==PJ_AF_UNSPEC) &&\n\tpj_inet_pton(PJ_AF_INET, nodename,\n\t\t     &ai[0].ai_addr.ipv4.sin_addr) == PJ_SUCCESS)\n    {\n\taf = PJ_AF_INET;\n\thas_addr = PJ_TRUE;\n    }\n    else if ((af==PJ_AF_INET6 || af==PJ_AF_UNSPEC) &&\n\t     pj_inet_pton(PJ_AF_INET6, nodename,\n\t\t\t  &ai[0].ai_addr.ipv6.sin6_addr) == PJ_SUCCESS)\n    {\n\taf = PJ_AF_INET6;\n\thas_addr = PJ_TRUE;\n    }\n\n    if (has_addr) {\n\tpj_str_t tmp;\n\n\ttmp.ptr = ai[0].ai_canonname;\n\tpj_strncpy_with_null(&tmp, nodename, PJ_MAX_HOSTNAME);\n\tai[0].ai_addr.addr.sa_family = (pj_uint16_t)af;\n\t*count = 1;\n\n\treturn PJ_SUCCESS;\n    }\n\n    if (af == PJ_AF_INET || af == PJ_AF_UNSPEC) {\n\tpj_hostent he;\n\tunsigned i, max_count;\n\tpj_status_t status;\n\t\n\t/* VC6 complains that \"he\" is uninitialized */\n\t#ifdef _MSC_VER\n\tpj_bzero(&he, sizeof(he));\n\t#endif\n\n\tstatus = pj_gethostbyname(nodename, &he);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tmax_count = *count;\n\t*count = 0;\n\n\tpj_bzero(ai, max_count * sizeof(pj_addrinfo));\n\n\tfor (i=0; he.h_addr_list[i] && *count<max_count; ++i) {\n\t    pj_ansi_strncpy(ai[*count].ai_canonname, he.h_name,\n\t\t\t    sizeof(ai[*count].ai_canonname));\n\t    ai[*count].ai_canonname[sizeof(ai[*count].ai_canonname)-1] = '\\0';\n\n\t    ai[*count].ai_addr.ipv4.sin_family = PJ_AF_INET;\n\t    pj_memcpy(&ai[*count].ai_addr.ipv4.sin_addr,\n\t\t      he.h_addr_list[i], he.h_length);\n\t    PJ_SOCKADDR_RESET_LEN(&ai[*count].ai_addr);\n\n\t    (*count)++;\n\t}\n\n\treturn PJ_SUCCESS;\n\n    } else {\n\t/* IPv6 is not supported */\n\t*count = 0;\n\n\treturn PJ_EIPV6NOTSUP;\n    }\n#endif\t/* PJ_SOCK_HAS_GETADDRINFO */\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/addr_resolv_symbian.cpp",
    "content": "/* $Id: addr_resolv_symbian.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/addr_resolv.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/ip_helper.h>\n#include <pj/log.h>\n#include <pj/sock.h>\n#include <pj/string.h>\n#include <pj/unicode.h>\n\n#include \"os_symbian.h\"\n \n#define THIS_FILE \t\"addr_resolv_symbian.cpp\"\n#define TRACE_ME\t0\n\n\n// PJLIB API: resolve hostname\nPJ_DEF(pj_status_t) pj_gethostbyname(const pj_str_t *name, pj_hostent *he)\n{\n    static pj_addrinfo ai;\n    static char *aliases[2];\n    static char *addrlist[2];\n    unsigned count = 1;\n    pj_status_t status;\n    \n    status = pj_getaddrinfo(PJ_AF_INET, name, &count, &ai);\n    if (status != PJ_SUCCESS)\n    \treturn status;\n    \n    aliases[0] = ai.ai_canonname;\n    aliases[1] = NULL;\n    \n    addrlist[0] = (char*) &ai.ai_addr.ipv4.sin_addr;\n    addrlist[1] = NULL;\n    \n    pj_bzero(he, sizeof(*he));\n    he->h_name = aliases[0];\n    he->h_aliases = aliases;\n    he->h_addrtype = PJ_AF_INET;\n    he->h_length = 4;\n    he->h_addr_list = addrlist;\n    \n    return PJ_SUCCESS;\n}\n\n\n// Resolve for specific address family\nstatic pj_status_t getaddrinfo_by_af(int af, const pj_str_t *name,\n\t\t\t\t     unsigned *count, pj_addrinfo ai[]) \n{\n    unsigned i;\n    pj_status_t status;\n    \n    PJ_ASSERT_RETURN(name && count && ai, PJ_EINVAL);\n\n#if !defined(PJ_HAS_IPV6) || !PJ_HAS_IPV6\n    if (af == PJ_AF_INET6)\n    \treturn PJ_EIPV6NOTSUP;\n#endif\n\t\n    // Return failure if access point is marked as down by app.\n    PJ_SYMBIAN_CHECK_CONNECTION();\n\n    // Get resolver for the specified address family\n    RHostResolver &resv = PjSymbianOS::Instance()->GetResolver(af);\n\n    // Convert name to Unicode\n    wchar_t name16[PJ_MAX_HOSTNAME];\n    pj_ansi_to_unicode(name->ptr, name->slen, name16, PJ_ARRAY_SIZE(name16));\n    TPtrC16 data((const TUint16*)name16);\n\n    // Resolve!\n    TNameEntry nameEntry;\n    TRequestStatus reqStatus;\n    \n    resv.GetByName(data, nameEntry, reqStatus);\n    User::WaitForRequest(reqStatus);\n    \n    // Iterate each result\n    i = 0;\n    while (reqStatus == KErrNone && i < *count) {\n    \t\n\t\t// Get the resolved TInetAddr\n\t\tTInetAddr inetAddr(nameEntry().iAddr);\n\t\tint addrlen;\n\n#if TRACE_ME\n\t\tif (1) {\n\t\t\tpj_sockaddr a;\n\t\t\tchar ipaddr[PJ_INET6_ADDRSTRLEN+2];\n\t\t\tint namelen;\n\t\t\t\n\t\t\tnamelen = sizeof(pj_sockaddr);\n\t\t\tif (PjSymbianOS::Addr2pj(inetAddr, a, &namelen, \n\t\t\t\t\t\t\t\t\t PJ_FALSE) == PJ_SUCCESS) \n\t\t\t{\n\t\t\t\tPJ_LOG(5,(THIS_FILE, \"resolve %.*s: %s\", \n\t\t\t\t\t\t(int)name->slen, name->ptr,\n\t\t\t\t\t\tpj_sockaddr_print(&a, ipaddr, sizeof(ipaddr), 2)));\n\t\t\t}\n\t\t}\n#endif\n\t\t\n\t\t// Ignore if this is not the same address family\n\t\t// Not a good idea, as Symbian mapps IPv4 to IPv6.\n\t\t//fam = inetAddr.Family();\n\t\t//if (fam != af) {\n\t\t//    resv.Next(nameEntry, reqStatus);\n\t\t//    User::WaitForRequest(reqStatus);\n\t\t//    continue;\n\t\t//}\n\t\t\n\t\t// Convert IP address first to get IPv4 mapped address\n\t\taddrlen = sizeof(ai[i].ai_addr);\n\t\tstatus = PjSymbianOS::Addr2pj(inetAddr, ai[i].ai_addr, \n\t\t\t\t\t\t\t\t\t  &addrlen, PJ_TRUE);\n\t\tif (status != PJ_SUCCESS)\n\t\t    return status;\n\t\t\n\t\t// Ignore if address family doesn't match\n\t\tif (ai[i].ai_addr.addr.sa_family != af) {\n\t\t    resv.Next(nameEntry, reqStatus);\n\t\t    User::WaitForRequest(reqStatus);\n\t\t    continue;\n\t\t}\n\n\t\t// Convert the official address to ANSI.\n\t\tpj_unicode_to_ansi((const wchar_t*)nameEntry().iName.Ptr(), \n\t\t\t\t   nameEntry().iName.Length(),\n\t\t\t       \t   ai[i].ai_canonname, sizeof(ai[i].ai_canonname));\n\t\n\t\t// Next\n\t\t++i;\n\t\tresv.Next(nameEntry, reqStatus);\n\t\tUser::WaitForRequest(reqStatus);\n    }\n\n    *count = i;\n    return PJ_SUCCESS;\n}\n\n/* Resolve IPv4/IPv6 address */\nPJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename,\n\t\t\t\t   unsigned *count, pj_addrinfo ai[]) \n{\n    unsigned start;\n    pj_status_t status = PJ_EAFNOTSUP;\n    \n    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6 || af==PJ_AF_UNSPEC,\n    \t\t     PJ_EAFNOTSUP);\n    PJ_ASSERT_RETURN(nodename && count && *count && ai, PJ_EINVAL);\n    \n    start = 0;\n    \n    if (af==PJ_AF_INET6 || af==PJ_AF_UNSPEC) {\n        unsigned max = *count;\n    \tstatus = getaddrinfo_by_af(PJ_AF_INET6, nodename, \n    \t\t\t\t   &max, &ai[start]);\n    \tif (status == PJ_SUCCESS) {\n    \t    (*count) -= max;\n    \t    start += max;\n    \t}\n    }\n    \n    if (af==PJ_AF_INET || af==PJ_AF_UNSPEC) {\n        unsigned max = *count;\n    \tstatus = getaddrinfo_by_af(PJ_AF_INET, nodename, \n    \t\t\t\t   &max, &ai[start]);\n    \tif (status == PJ_SUCCESS) {\n    \t    (*count) -= max;\n    \t    start += max;\n    \t}\n    }\n    \n    *count = start;\n    \n    if (*count) {\n    \treturn PJ_SUCCESS;\n    } else {\n    \treturn status!=PJ_SUCCESS ? status : PJ_ENOTFOUND;\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/array.c",
    "content": "/* $Id: array.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/array.h>\n#include <pj/string.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n\nPJ_DEF(void) pj_array_insert( void *array,\n\t\t\t      unsigned elem_size,\n\t\t\t      unsigned count,\n\t\t\t      unsigned pos,\n\t\t\t      const void *value)\n{\n    if (count && pos < count) {\n\tpj_memmove( (char*)array + (pos+1)*elem_size,\n\t\t    (char*)array + pos*elem_size,\n\t\t    (count-pos)*elem_size);\n    }\n    pj_memmove((char*)array + pos*elem_size, value, elem_size);\n}\n\nPJ_DEF(void) pj_array_erase( void *array,\n\t\t\t     unsigned elem_size,\n\t\t\t     unsigned count,\n\t\t\t     unsigned pos)\n{\n    pj_assert(count != 0);\n    if (pos < count-1) {\n\tpj_memmove( (char*)array + pos*elem_size,\n\t\t    (char*)array + (pos+1)*elem_size,\n\t\t    (count-pos-1)*elem_size);\n    }\n}\n\nPJ_DEF(pj_status_t) pj_array_find( const void *array, \n\t\t\t\t   unsigned elem_size, \n\t\t\t\t   unsigned count, \n\t\t\t\t   pj_status_t (*matching)(const void *value),\n\t\t\t\t   void **result)\n{\n    unsigned i;\n    const char *char_array = (const char*)array;\n    for (i=0; i<count; ++i) {\n\tif ( (*matching)(char_array) == PJ_SUCCESS) {\n\t    if (result) {\n\t\t*result = (void*)char_array;\n\t    }\n\t    return PJ_SUCCESS;\n\t}\n\tchar_array += elem_size;\n    }\n    return PJ_ENOTFOUND;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/compat/longjmp_i386.S",
    "content": "/* longjmp for i386.\n   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Library General Public License as\n   published by the Free Software Foundation; either version 2 of the\n   License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Library General Public License for more details.\n\n   You should have received a copy of the GNU Library General Public\n   License along with the GNU C Library; see the file COPYING.LIB.  If not,\n   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n   Boston, MA 02111-1307, USA.  */\n\n#define _ASM\n#define _SETJMP_H\n#define PJ_LINUX_KERNEL\t    1\n#include <pj/compat/setjmp.h>\n\n.global __longjmp\n.type   __longjmp,%function\n.align 4\n__longjmp:\n\tmovl 4(%esp), %ecx\t/* User's jmp_buf in %ecx.  */\n\tmovl 8(%esp), %eax\t/* Second argument is return value.  */\n\t/* Save the return address now.  */\n\tmovl (JB_PC*4)(%ecx), %edx\n\t/* Restore registers.  */\n\tmovl (JB_BX*4)(%ecx), %ebx\n\tmovl (JB_SI*4)(%ecx), %esi\n\tmovl (JB_DI*4)(%ecx), %edi\n\tmovl (JB_BP*4)(%ecx), %ebp\n\tmovl (JB_SP*4)(%ecx), %esp\n\t/* Jump to saved PC.  */\n\tjmp *%edx\n.size __longjmp,.-__longjmp\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/compat/setjmp_i386.S",
    "content": "/* setjmp for i386, ELF version.\n   Copyright (C) 1995, 1996, 1997, 2000, 2001 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, write to the Free\n   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA\n   02111-1307 USA.  */\n\n#define _ASM\n#define _SETJMP_H\n#define PJ_LINUX_KERNEL\t    1\n#include <pj/compat/setjmp.h>\n\n\n.global __sigsetjmp\n.type   __sigsetjmp,%function\n.align 4\n\n__sigsetjmp:\n        movl 4   (%esp), %eax\n     \t/* Save registers.  */\n        movl %ebx, (0 *4)(%eax)\n        movl %esi, (1 *4)(%eax)\n        movl %edi, (2 *4)(%eax)\n\t/* Save SP as it will be after we return.  */\n        leal 4(%esp), %ecx       \n        movl %ecx, (4 *4)(%eax)\n\t/* Save PC we are returning to now.  */\n        movl 0(%esp), %ecx       \n        movl %ecx, (5 *4)(%eax)\n\t/* Save caller's frame pointer.  */\n        movl %ebp, (3 *4)(%eax)  \n\n\t/* Make a tail call to __sigjmp_save; it takes the same args.  */\n#ifdef\t__PIC__\n\t/* We cannot use the PLT, because it requires that %ebx be set, but\n           we can't save and restore our caller's value.  Instead, we do an\n           indirect jump through the GOT, using for the temporary register\n           %ecx, which is call-clobbered.  */\n\tcall .Lhere\n.Lhere:\n\tpopl %ecx\n\taddl $_GLOBAL_OFFSET_TABLE_+[.- .Lhere  ], %ecx\n\tmovl    __sigjmp_save    @GOT  (%ecx), %ecx\n\tjmp *%ecx\n#else\n\tjmp   __sigjmp_save\n#endif\n.size __sigsetjmp,.-__sigsetjmp\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/compat/sigjmp.c",
    "content": "/* $Id: sigjmp.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/config.h>\n#include <pj/compat/setjmp.h>\n\nint __sigjmp_save(sigjmp_buf env, int savemask)\n{\n    return 0;\n}\n\nextern int __sigsetjmp(pj_jmp_buf env, int savemask);\nextern void __longjmp(pj_jmp_buf env, int val) __attribute__((noreturn));\n\nPJ_DEF(int) pj_setjmp(pj_jmp_buf env)\n{\n    return __sigsetjmp(env, 0);\n}\n\nPJ_DEF(void) pj_longjmp(pj_jmp_buf env, int val)\n{\n    __longjmp(env, val);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/compat/string.c",
    "content": "/* $Id: string.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/types.h>\n#include <pj/compat/string.h>\n#include <pj/ctype.h>\n\nPJ_DEF(int) strcasecmp(const char *s1, const char *s2)\n{\n    while ((*s1==*s2) || (pj_tolower(*s1)==pj_tolower(*s2))) {\n\tif (!*s1++)\n\t    return 0;\n\t++s2;\n    }\n    return (pj_tolower(*s1) < pj_tolower(*s2)) ? -1 : 1;\n}\n\nPJ_DEF(int) strncasecmp(const char *s1, const char *s2, int len)\n{\n    if (!len) return 0;\n\n    while ((*s1==*s2) || (pj_tolower(*s1)==pj_tolower(*s2))) {\n\tif (!*s1++ || --len <= 0)\n\t    return 0;\n\t++s2;\n    }\n    return (pj_tolower(*s1) < pj_tolower(*s2)) ? -1 : 1;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/compat/string_compat.c",
    "content": "/* $Id: string_compat.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/types.h>\n#include <pj/compat/string.h>\n#include <pj/ctype.h>\n#include <pj/assert.h>\n\n\n#if defined(PJ_HAS_STRING_H) && PJ_HAS_STRING_H != 0\n/* Nothing to do */\n#else\nPJ_DEF(int) strcasecmp(const char *s1, const char *s2)\n{\n    while ((*s1==*s2) || (pj_tolower(*s1)==pj_tolower(*s2))) {\n\tif (!*s1++)\n\t    return 0;\n\t++s2;\n    }\n    return (pj_tolower(*s1) < pj_tolower(*s2)) ? -1 : 1;\n}\n\nPJ_DEF(int) strncasecmp(const char *s1, const char *s2, int len)\n{\n    if (!len) return 0;\n\n    while ((*s1==*s2) || (pj_tolower(*s1)==pj_tolower(*s2))) {\n\tif (!*s1++ || --len <= 0)\n\t    return 0;\n\t++s2;\n    }\n    return (pj_tolower(*s1) < pj_tolower(*s2)) ? -1 : 1;\n}\n#endif\n\n#if defined(PJ_HAS_NO_SNPRINTF) && PJ_HAS_NO_SNPRINTF != 0\n\nPJ_DEF(int) snprintf(char *s1, pj_size_t len, const char *s2, ...)\n{\n    int ret;\n    va_list arg;\n\n    PJ_UNUSED_ARG(len);\n\n    va_start(arg, s2);\n    ret = vsprintf(s1, s2, arg);\n    va_end(arg);\n    \n    return ret;\n}\n\nPJ_DEF(int) vsnprintf(char *s1, pj_size_t len, const char *s2, va_list arg)\n{\n#define MARK_CHAR   ((char)255)\n    int rc;\n\n    s1[len-1] = MARK_CHAR;\n\n    rc = vsprintf(s1,s2,arg);\n\n    pj_assert(s1[len-1] == MARK_CHAR || s1[len-1] == '\\0');\n\n    return rc;\n}\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/config.c",
    "content": "/* $Id: config.c 4112 2012-04-27 09:47:20Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/config.h>\n#include <pj/log.h>\n#include <pj/ioqueue.h>\n\nstatic const char *id = \"config.c\";\n\n#define PJ_MAKE_VERSION3_1(a,b,d) \t#a \".\" #b d\n#define PJ_MAKE_VERSION3_2(a,b,d)\tPJ_MAKE_VERSION3_1(a,b,d)\n\n#define PJ_MAKE_VERSION4_1(a,b,c,d) \t#a \".\" #b \".\" #c d\n#define PJ_MAKE_VERSION4_2(a,b,c,d)\tPJ_MAKE_VERSION4_1(a,b,c,d)\n\n#if PJ_VERSION_NUM_REV\nPJ_DEF_DATA(const char*) PJ_VERSION = PJ_MAKE_VERSION4_2(PJ_VERSION_NUM_MAJOR,\n\t\t\t\t\t\t         PJ_VERSION_NUM_MINOR,\n\t\t\t\t\t\t         PJ_VERSION_NUM_REV,\n\t\t\t\t\t\t         PJ_VERSION_NUM_EXTRA);\n#else\nPJ_DEF_DATA(const char*) PJ_VERSION = PJ_MAKE_VERSION3_2(PJ_VERSION_NUM_MAJOR,\n\t\t\t\t\t\t         PJ_VERSION_NUM_MINOR,\n\t\t\t\t\t\t         PJ_VERSION_NUM_EXTRA);\n#endif\n\n/*\n * Get PJLIB version string.\n */\nPJ_DEF(const char*) pj_get_version(void)\n{\n    return PJ_VERSION;\n}\n\nPJ_DEF(void) pj_dump_config(void)\n{\n    PJ_LOG(3, (id, \"PJLIB (c)2008-2009 Teluu Inc.\"));\n    PJ_LOG(3, (id, \"Dumping configurations:\"));\n    PJ_LOG(3, (id, \" PJ_VERSION                : %s\", PJ_VERSION));\n    PJ_LOG(3, (id, \" PJ_M_NAME                 : %s\", PJ_M_NAME));\n    PJ_LOG(3, (id, \" PJ_HAS_PENTIUM            : %d\", PJ_HAS_PENTIUM));\n    PJ_LOG(3, (id, \" PJ_OS_NAME                : %s\", PJ_OS_NAME));\n    PJ_LOG(3, (id, \" PJ_CC_NAME/VER_(1,2,3)    : %s-%d.%d.%d\", PJ_CC_NAME,\n\t       PJ_CC_VER_1, PJ_CC_VER_2, PJ_CC_VER_3));\n    PJ_LOG(3, (id, \" PJ_IS_(BIG/LITTLE)_ENDIAN : %s\", \n\t       (PJ_IS_BIG_ENDIAN?\"big-endian\":\"little-endian\")));\n    PJ_LOG(3, (id, \" PJ_HAS_INT64              : %d\", PJ_HAS_INT64));\n    PJ_LOG(3, (id, \" PJ_HAS_FLOATING_POINT     : %d\", PJ_HAS_FLOATING_POINT));\n    PJ_LOG(3, (id, \" PJ_DEBUG                  : %d\", PJ_DEBUG));\n    PJ_LOG(3, (id, \" PJ_FUNCTIONS_ARE_INLINED  : %d\", PJ_FUNCTIONS_ARE_INLINED));\n    PJ_LOG(3, (id, \" PJ_LOG_MAX_LEVEL          : %d\", PJ_LOG_MAX_LEVEL));\n    PJ_LOG(3, (id, \" PJ_LOG_MAX_SIZE           : %d\", PJ_LOG_MAX_SIZE));\n    PJ_LOG(3, (id, \" PJ_LOG_USE_STACK_BUFFER   : %d\", PJ_LOG_USE_STACK_BUFFER));\n    PJ_LOG(3, (id, \" PJ_POOL_DEBUG             : %d\", PJ_POOL_DEBUG));\n    PJ_LOG(3, (id, \" PJ_HAS_POOL_ALT_API       : %d\", PJ_HAS_POOL_ALT_API));\n    PJ_LOG(3, (id, \" PJ_HAS_TCP                : %d\", PJ_HAS_TCP));\n    PJ_LOG(3, (id, \" PJ_MAX_HOSTNAME           : %d\", PJ_MAX_HOSTNAME));\n    PJ_LOG(3, (id, \" ioqueue type              : %s\", pj_ioqueue_name()));\n    PJ_LOG(3, (id, \" PJ_IOQUEUE_MAX_HANDLES    : %d\", PJ_IOQUEUE_MAX_HANDLES));\n    PJ_LOG(3, (id, \" PJ_IOQUEUE_HAS_SAFE_UNREG : %d\", PJ_IOQUEUE_HAS_SAFE_UNREG));\n    PJ_LOG(3, (id, \" PJ_HAS_THREADS            : %d\", PJ_HAS_THREADS));\n    PJ_LOG(3, (id, \" PJ_LOG_USE_STACK_BUFFER   : %d\", PJ_LOG_USE_STACK_BUFFER));\n    PJ_LOG(3, (id, \" PJ_HAS_SEMAPHORE          : %d\", PJ_HAS_SEMAPHORE));\n    PJ_LOG(3, (id, \" PJ_HAS_EVENT_OBJ          : %d\", PJ_HAS_EVENT_OBJ));\n    PJ_LOG(3, (id, \" PJ_ENABLE_EXTRA_CHECK     : %d\", PJ_ENABLE_EXTRA_CHECK));\n    PJ_LOG(3, (id, \" PJ_HAS_EXCEPTION_NAMES    : %d\", PJ_HAS_EXCEPTION_NAMES));\n    PJ_LOG(3, (id, \" PJ_MAX_EXCEPTION_ID       : %d\", PJ_MAX_EXCEPTION_ID));\n    PJ_LOG(3, (id, \" PJ_EXCEPTION_USE_WIN32_SEH: %d\", PJ_EXCEPTION_USE_WIN32_SEH));\n    PJ_LOG(3, (id, \" PJ_TIMESTAMP_USE_RDTSC:   : %d\", PJ_TIMESTAMP_USE_RDTSC));\n    PJ_LOG(3, (id, \" PJ_OS_HAS_CHECK_STACK     : %d\", PJ_OS_HAS_CHECK_STACK));\n    PJ_LOG(3, (id, \" PJ_HAS_HIGH_RES_TIMER     : %d\", PJ_HAS_HIGH_RES_TIMER));\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ctype.c",
    "content": "/* $Id: ctype.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/ctype.h>\n\n/*\nchar pj_hex_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7',\n\t\t\t'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };\n*/\n\nint pjlib_ctype_c_dummy_symbol;\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/errno.c",
    "content": "/* $Id: errno.c 4461 2013-04-05 03:02:19Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/errno.h>\n#include <pj/log.h>\n#include <pj/string.h>\n#include <pj/compat/string.h>\n#include <pj/compat/stdarg.h>\n#include <pj/assert.h>\n\n/* Prototype for platform specific error message, which will be defined \n * in separate file.\n */\nPJ_BEGIN_DECL\n\n    PJ_DECL(int) platform_strerror(pj_os_err_type code, \n                              \t   char *buf, pj_size_t bufsize );\nPJ_END_DECL\n\n#ifndef PJLIB_MAX_ERR_MSG_HANDLER\n#\tdefine PJLIB_MAX_ERR_MSG_HANDLER   10\n#endif\n\n/* Error message handler. */\nstatic unsigned err_msg_hnd_cnt;\nstatic struct err_msg_hnd\n{\n    pj_status_t\t    begin;\n    pj_status_t\t    end;\n    pj_str_t\t  (*strerror)(pj_status_t, char*, pj_size_t);\n\n} err_msg_hnd[PJLIB_MAX_ERR_MSG_HANDLER];\n\n/* PJLIB's own error codes/messages */\n#if defined(PJ_HAS_ERROR_STRING) && PJ_HAS_ERROR_STRING!=0\n\nstatic const struct \n{\n    int code;\n    const char *msg;\n} err_str[] = \n{\n    PJ_BUILD_ERR(PJ_EUNKNOWN,      \"Unknown Error\" ),\n    PJ_BUILD_ERR(PJ_EPENDING,      \"Pending operation\" ),\n    PJ_BUILD_ERR(PJ_ETOOMANYCONN,  \"Too many connecting sockets\" ),\n    PJ_BUILD_ERR(PJ_EINVAL,        \"Invalid value or argument\" ),\n    PJ_BUILD_ERR(PJ_ENAMETOOLONG,  \"Name too long\" ),\n    PJ_BUILD_ERR(PJ_ENOTFOUND,     \"Not found\" ),\n    PJ_BUILD_ERR(PJ_ENOMEM,        \"Not enough memory\" ),\n    PJ_BUILD_ERR(PJ_EBUG,          \"BUG DETECTED!\" ),\n    PJ_BUILD_ERR(PJ_ETIMEDOUT,     \"Operation timed out\" ),\n    PJ_BUILD_ERR(PJ_ETOOMANY,      \"Too many objects of the specified type\"),\n    PJ_BUILD_ERR(PJ_EBUSY,         \"Object is busy\"),\n    PJ_BUILD_ERR(PJ_ENOTSUP,\t   \"Option/operation is not supported\"),\n    PJ_BUILD_ERR(PJ_EINVALIDOP,\t   \"Invalid operation\"),\n    PJ_BUILD_ERR(PJ_ECANCELLED,    \"Operation cancelled\"),\n    PJ_BUILD_ERR(PJ_EEXISTS,       \"Object already exists\" ),\n    PJ_BUILD_ERR(PJ_EEOF,\t   \"End of file\" ),\n    PJ_BUILD_ERR(PJ_ETOOBIG,\t   \"Size is too big\"),\n    PJ_BUILD_ERR(PJ_ERESOLVE,\t   \"gethostbyname() has returned error\"),\n    PJ_BUILD_ERR(PJ_ETOOSMALL,\t   \"Size is too short\"),\n    PJ_BUILD_ERR(PJ_EIGNORED,\t   \"Ignored\"),\n    PJ_BUILD_ERR(PJ_EIPV6NOTSUP,   \"IPv6 is not supported\"),\n    PJ_BUILD_ERR(PJ_EAFNOTSUP,\t   \"Unsupported address family\"),\n    PJ_BUILD_ERR(PJ_EGONE,\t   \"Object no longer exists\"),\n    PJ_BUILD_ERR(PJ_ESOCKETSTOP,   \"Socket is in bad state\")\n};\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n\n/*\n * pjlib_error()\n *\n * Retrieve message string for PJLIB's own error code.\n */\nstatic int pjlib_error(pj_status_t code, char *buf, pj_size_t size)\n{\n    int len;\n\n#if defined(PJ_HAS_ERROR_STRING) && PJ_HAS_ERROR_STRING!=0\n    unsigned i;\n\n    for (i=0; i<sizeof(err_str)/sizeof(err_str[0]); ++i) {\n        if (err_str[i].code == code) {\n            pj_size_t len2 = pj_ansi_strlen(err_str[i].msg);\n            if (len2 >= size) len2 = size-1;\n            pj_memcpy(buf, err_str[i].msg, len2);\n            buf[len2] = '\\0';\n            return (int)len2;\n        }\n    }\n#endif\n\n    len = pj_ansi_snprintf( buf, size, \"Unknown pjlib error %d\", code);\n    if (len < 1 || len >= (int)size)\n\tlen = (int)(size - 1);\n    return len;\n}\n\n#define IN_RANGE(val,start,end)\t    ((val)>=(start) && (val)<(end))\n\n/* Register strerror handle. */\nPJ_DEF(pj_status_t) pj_register_strerror( pj_status_t start,\n\t\t\t\t\t  pj_status_t space,\n\t\t\t\t\t  pj_error_callback f)\n{\n    unsigned i;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(start && space && f, PJ_EINVAL);\n\n    /* Check if there aren't too many handlers registered. */\n    PJ_ASSERT_RETURN(err_msg_hnd_cnt < PJ_ARRAY_SIZE(err_msg_hnd),\n\t\t     PJ_ETOOMANY);\n\n    /* Start error must be greater than PJ_ERRNO_START_USER */\n    PJ_ASSERT_RETURN(start >= PJ_ERRNO_START_USER, PJ_EEXISTS);\n\n    /* Check that no existing handler has covered the specified range. */\n    for (i=0; i<err_msg_hnd_cnt; ++i) {\n\tif (IN_RANGE(start, err_msg_hnd[i].begin, err_msg_hnd[i].end) ||\n\t    IN_RANGE(start+space-1, err_msg_hnd[i].begin, err_msg_hnd[i].end))\n\t{\n\t    if (err_msg_hnd[i].begin == start && \n\t\terr_msg_hnd[i].end == (start+space) &&\n\t\terr_msg_hnd[i].strerror == f)\n\t    {\n\t\t/* The same range and handler has already been registered */\n\t\treturn PJ_SUCCESS;\n\t    }\n\n\t    return PJ_EEXISTS;\n\t}\n    }\n\n    /* Register the handler. */\n    err_msg_hnd[err_msg_hnd_cnt].begin = start;\n    err_msg_hnd[err_msg_hnd_cnt].end = start + space;\n    err_msg_hnd[err_msg_hnd_cnt].strerror = f;\n\n    ++err_msg_hnd_cnt;\n\n    return PJ_SUCCESS;\n}\n\n/* Internal PJLIB function called by pj_shutdown() to clear error handlers */\nvoid pj_errno_clear_handlers(void)\n{\n    err_msg_hnd_cnt = 0;\n    pj_bzero(err_msg_hnd, sizeof(err_msg_hnd));\n}\n\n\n/*\n * pj_strerror()\n */\nPJ_DEF(pj_str_t) pj_strerror( pj_status_t statcode, \n\t\t\t      char *buf, pj_size_t bufsize )\n{\n    int len = -1;\n    pj_str_t errstr;\n\n    pj_assert(buf && bufsize);\n\n    if (statcode == PJ_SUCCESS) {\n\tlen = pj_ansi_snprintf( buf, bufsize, \"Success\");\n\n    } else if (statcode < PJ_ERRNO_START + PJ_ERRNO_SPACE_SIZE) {\n        len = pj_ansi_snprintf( buf, bufsize, \"Unknown error %d\", statcode);\n\n    } else if (statcode < PJ_ERRNO_START_STATUS + PJ_ERRNO_SPACE_SIZE) {\n        len = pjlib_error(statcode, buf, bufsize);\n\n    } else if (statcode < PJ_ERRNO_START_SYS + PJ_ERRNO_SPACE_SIZE) {\n        len = platform_strerror(PJ_STATUS_TO_OS(statcode), buf, bufsize);\n\n    } else {\n\tunsigned i;\n\n\t/* Find user handler to get the error message. */\n\tfor (i=0; i<err_msg_hnd_cnt; ++i) {\n\t    if (IN_RANGE(statcode, err_msg_hnd[i].begin, err_msg_hnd[i].end)) {\n\t\treturn (*err_msg_hnd[i].strerror)(statcode, buf, bufsize);\n\t    }\n\t}\n\n\t/* Handler not found! */\n\tlen = pj_ansi_snprintf( buf, bufsize, \"Unknown error %d\", statcode);\n    }\n\n    if (len < 1 || len >= (int)bufsize) {\n\tlen = (int)(bufsize - 1);\n\tbuf[len] = '\\0';\n    }\n\n    errstr.ptr = buf;\n    errstr.slen = len;\n\n    return errstr;\n}\n\n#if PJ_LOG_MAX_LEVEL >= 1\nstatic void invoke_log(const char *sender, int level, const char *format, ...)\n{\n    va_list arg;\n    va_start(arg, format);\n    pj_log(sender, level, format, arg);\n    va_end(arg);\n}\n\nstatic void pj_perror_imp(int log_level, const char *sender, \n\t\t\t  pj_status_t status,\n\t\t          const char *title_fmt, va_list marker)\n{\n    char titlebuf[PJ_PERROR_TITLE_BUF_SIZE];\n    char errmsg[PJ_ERR_MSG_SIZE];\n    int len;\n\n    /* Build the title */\n    len = pj_ansi_vsnprintf(titlebuf, sizeof(titlebuf), title_fmt, marker);\n    if (len < 0 || len >= (int)sizeof(titlebuf))\n\tpj_ansi_strcpy(titlebuf, \"Error\");\n\n    /* Get the error */\n    pj_strerror(status, errmsg, sizeof(errmsg));\n\n    /* Send to log */\n    invoke_log(sender, log_level, \"%s: %s\", titlebuf, errmsg);\n}\n\nPJ_DEF(void) pj_perror(int log_level, const char *sender, pj_status_t status,\n\t\t       const char *title_fmt, ...)\n{\n    va_list marker;\n    va_start(marker, title_fmt);\n    pj_perror_imp(log_level, sender, status, title_fmt, marker);\n    va_end(marker);\n}\n\nPJ_DEF(void) pj_perror_1(const char *sender, pj_status_t status,\n\t\t\t const char *title_fmt, ...)\n{\n    va_list marker;\n    va_start(marker, title_fmt);\n    pj_perror_imp(1, sender, status, title_fmt, marker);\n    va_end(marker);\n}\n\n#else /* #if PJ_LOG_MAX_LEVEL >= 1 */\nPJ_DEF(void) pj_perror(int log_level, const char *sender, pj_status_t status,\n\t\t       const char *title_fmt, ...)\n{\n}\n#endif\t/* #if PJ_LOG_MAX_LEVEL >= 1 */\n\n\n#if PJ_LOG_MAX_LEVEL >= 2\nPJ_DEF(void) pj_perror_2(const char *sender, pj_status_t status,\n\t\t\t const char *title_fmt, ...)\n{\n    va_list marker;\n    va_start(marker, title_fmt);\n    pj_perror_imp(2, sender, status, title_fmt, marker);\n    va_end(marker);\n}\n#endif\n\n#if PJ_LOG_MAX_LEVEL >= 3\nPJ_DEF(void) pj_perror_3(const char *sender, pj_status_t status,\n\t\t\t const char *title_fmt, ...)\n{\n    va_list marker;\n    va_start(marker, title_fmt);\n    pj_perror_imp(3, sender, status, title_fmt, marker);\n    va_end(marker);\n}\n#endif\n\n#if PJ_LOG_MAX_LEVEL >= 4\nPJ_DEF(void) pj_perror_4(const char *sender, pj_status_t status,\n\t\t\t const char *title_fmt, ...)\n{\n    va_list marker;\n    va_start(marker, title_fmt);\n    pj_perror_imp(4, sender, status, title_fmt, marker);\n    va_end(marker);\n}\n#endif\n\n#if PJ_LOG_MAX_LEVEL >= 5\nPJ_DEF(void) pj_perror_5(const char *sender, pj_status_t status,\n\t\t\t const char *title_fmt, ...)\n{\n    va_list marker;\n    va_start(marker, title_fmt);\n    pj_perror_imp(5, sender, status, title_fmt, marker);\n    va_end(marker);\n}\n#endif\n\n#if PJ_LOG_MAX_LEVEL >= 6\nPJ_DEF(void) pj_perror_6(const char *sender, pj_status_t status,\n\t\t\t const char *title_fmt, ...)\n{\n    va_list marker;\n    va_start(marker, title_fmt);\n    pj_perror_imp(6, sender, status, title_fmt, marker);\n    va_end(marker);\n}\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/except.c",
    "content": "/* $Id: except.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/except.h>\n#include <pj/os.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/errno.h>\n#include <pj/string.h>\n\nstatic long thread_local_id = -1;\n\n#if defined(PJ_HAS_EXCEPTION_NAMES) && PJ_HAS_EXCEPTION_NAMES != 0\n    static const char *exception_id_names[PJ_MAX_EXCEPTION_ID];\n#else\n    /*\n     * Start from 1 (not 0)!!!\n     * Exception 0 is reserved for normal path of setjmp()!!!\n     */\n    static int last_exception_id = 1;\n#endif  /* PJ_HAS_EXCEPTION_NAMES */\n\n\n#if !defined(PJ_EXCEPTION_USE_WIN32_SEH) || PJ_EXCEPTION_USE_WIN32_SEH==0\nPJ_DEF(void) pj_throw_exception_(int exception_id)\n{\n    struct pj_exception_state_t *handler;\n\n    handler = (struct pj_exception_state_t*) \n\t      pj_thread_local_get(thread_local_id);\n    if (handler == NULL) {\n        PJ_LOG(1,(\"except.c\", \"!!!FATAL: unhandled exception %s!\\n\", \n\t\t   pj_exception_id_name(exception_id)));\n        pj_assert(handler != NULL);\n        /* This will crash the system! */\n    }\n    pj_pop_exception_handler_(handler);\n    pj_longjmp(handler->state, exception_id);\n}\n\nstatic void exception_cleanup(void)\n{\n    if (thread_local_id != -1) {\n\tpj_thread_local_free(thread_local_id);\n\tthread_local_id = -1;\n    }\n\n#if defined(PJ_HAS_EXCEPTION_NAMES) && PJ_HAS_EXCEPTION_NAMES != 0\n    {\n\tunsigned i;\n\tfor (i=0; i<PJ_MAX_EXCEPTION_ID; ++i)\n\t    exception_id_names[i] = NULL;\n    }\n#else\n    last_exception_id = 1;\n#endif\n}\n\nPJ_DEF(void) pj_push_exception_handler_(struct pj_exception_state_t *rec)\n{\n    struct pj_exception_state_t *parent_handler = NULL;\n\n    if (thread_local_id == -1) {\n\tpj_thread_local_alloc(&thread_local_id);\n\tpj_assert(thread_local_id != -1);\n\tpj_atexit(&exception_cleanup);\n    }\n    parent_handler = (struct pj_exception_state_t *)\n\t\t      pj_thread_local_get(thread_local_id);\n    rec->prev = parent_handler;\n    pj_thread_local_set(thread_local_id, rec);\n}\n\nPJ_DEF(void) pj_pop_exception_handler_(struct pj_exception_state_t *rec)\n{\n    struct pj_exception_state_t *handler;\n\n    handler = (struct pj_exception_state_t *)\n\t      pj_thread_local_get(thread_local_id);\n    if (handler && handler==rec) {\n\tpj_thread_local_set(thread_local_id, handler->prev);\n    }\n}\n#endif\n\n#if defined(PJ_HAS_EXCEPTION_NAMES) && PJ_HAS_EXCEPTION_NAMES != 0\nPJ_DEF(pj_status_t) pj_exception_id_alloc( const char *name,\n                                           pj_exception_id_t *id)\n{\n    unsigned i;\n\n    pj_enter_critical_section();\n\n    /*\n     * Start from 1 (not 0)!!!\n     * Exception 0 is reserved for normal path of setjmp()!!!\n     */\n    for (i=1; i<PJ_MAX_EXCEPTION_ID; ++i) {\n        if (exception_id_names[i] == NULL) {\n            exception_id_names[i] = name;\n            *id = i;\n            pj_leave_critical_section();\n            return PJ_SUCCESS;\n        }\n    }\n\n    pj_leave_critical_section();\n    return PJ_ETOOMANY;\n}\n\nPJ_DEF(pj_status_t) pj_exception_id_free( pj_exception_id_t id )\n{\n    /*\n     * Start from 1 (not 0)!!!\n     * Exception 0 is reserved for normal path of setjmp()!!!\n     */\n    PJ_ASSERT_RETURN(id>0 && id<PJ_MAX_EXCEPTION_ID, PJ_EINVAL);\n    \n    pj_enter_critical_section();\n    exception_id_names[id] = NULL;\n    pj_leave_critical_section();\n\n    return PJ_SUCCESS;\n\n}\n\nPJ_DEF(const char*) pj_exception_id_name(pj_exception_id_t id)\n{\n    static char unknown_name[32];\n\n    /*\n     * Start from 1 (not 0)!!!\n     * Exception 0 is reserved for normal path of setjmp()!!!\n     */\n    PJ_ASSERT_RETURN(id>0 && id<PJ_MAX_EXCEPTION_ID, \"<Invalid ID>\");\n\n    if (exception_id_names[id] == NULL) {\n        pj_ansi_snprintf(unknown_name, sizeof(unknown_name), \n\t\t\t \"exception %d\", id);\n\treturn unknown_name;\n    }\n\n    return exception_id_names[id];\n}\n\n#else   /* PJ_HAS_EXCEPTION_NAMES */\nPJ_DEF(pj_status_t) pj_exception_id_alloc( const char *name,\n                                           pj_exception_id_t *id)\n{\n    PJ_ASSERT_RETURN(last_exception_id < PJ_MAX_EXCEPTION_ID-1, PJ_ETOOMANY);\n\n    *id = last_exception_id++;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_exception_id_free( pj_exception_id_t id )\n{\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(const char*) pj_exception_id_name(pj_exception_id_t id)\n{\n    return \"\";\n}\n\n#endif  /* PJ_HAS_EXCEPTION_NAMES */\n\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/exception_symbian.cpp",
    "content": "/* $Id: exception_symbian.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/except.h>\n#include <pj/os.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/errno.h>\n\n\n#if defined(PJ_HAS_EXCEPTION_NAMES) && PJ_HAS_EXCEPTION_NAMES != 0\n    static const char *exception_id_names[PJ_MAX_EXCEPTION_ID];\n#else\n    /*\n     * Start from 1 (not 0)!!!\n     * Exception 0 is reserved for normal path of setjmp()!!!\n     */\n    static int last_exception_id = 1;\n#endif  /* PJ_HAS_EXCEPTION_NAMES */\n\n\n#if defined(PJ_HAS_EXCEPTION_NAMES) && PJ_HAS_EXCEPTION_NAMES != 0\nPJ_DEF(pj_status_t) pj_exception_id_alloc( const char *name,\n                                           pj_exception_id_t *id)\n{\n    unsigned i;\n\n    pj_enter_critical_section();\n\n    /*\n     * Start from 1 (not 0)!!!\n     * Exception 0 is reserved for normal path of setjmp()!!!\n     */\n    for (i=1; i<PJ_MAX_EXCEPTION_ID; ++i) {\n        if (exception_id_names[i] == NULL) {\n            exception_id_names[i] = name;\n            *id = i;\n            pj_leave_critical_section();\n            return PJ_SUCCESS;\n        }\n    }\n\n    pj_leave_critical_section();\n    return PJ_ETOOMANY;\n}\n\nPJ_DEF(pj_status_t) pj_exception_id_free( pj_exception_id_t id )\n{\n    /*\n     * Start from 1 (not 0)!!!\n     * Exception 0 is reserved for normal path of setjmp()!!!\n     */\n    PJ_ASSERT_RETURN(id>0 && id<PJ_MAX_EXCEPTION_ID, PJ_EINVAL);\n    \n    pj_enter_critical_section();\n    exception_id_names[id] = NULL;\n    pj_leave_critical_section();\n\n    return PJ_SUCCESS;\n\n}\n\nPJ_DEF(const char*) pj_exception_id_name(pj_exception_id_t id)\n{\n    /*\n     * Start from 1 (not 0)!!!\n     * Exception 0 is reserved for normal path of setjmp()!!!\n     */\n    PJ_ASSERT_RETURN(id>0 && id<PJ_MAX_EXCEPTION_ID, \"<Invalid ID>\");\n\n    if (exception_id_names[id] == NULL)\n        return \"<Unallocated ID>\";\n\n    return exception_id_names[id];\n}\n\n#else   /* PJ_HAS_EXCEPTION_NAMES */\nPJ_DEF(pj_status_t) pj_exception_id_alloc( const char *name,\n                                           pj_exception_id_t *id)\n{\n    PJ_ASSERT_RETURN(last_exception_id < PJ_MAX_EXCEPTION_ID-1, PJ_ETOOMANY);\n\n    *id = last_exception_id++;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_exception_id_free( pj_exception_id_t id )\n{\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(const char*) pj_exception_id_name(pj_exception_id_t id)\n{\n    return \"\";\n}\n\n#endif  /* PJ_HAS_EXCEPTION_NAMES */\n\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/extra-exports.c",
    "content": "/* $Id: extra-exports.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <linux/module.h>\n#include <linux/syscalls.h>\n\nEXPORT_SYMBOL(sys_select);\n\nEXPORT_SYMBOL(sys_epoll_create);\nEXPORT_SYMBOL(sys_epoll_ctl);\nEXPORT_SYMBOL(sys_epoll_wait);\n\nEXPORT_SYMBOL(sys_socket);\nEXPORT_SYMBOL(sys_bind);\nEXPORT_SYMBOL(sys_getpeername);\nEXPORT_SYMBOL(sys_getsockname);\nEXPORT_SYMBOL(sys_sendto);\nEXPORT_SYMBOL(sys_recvfrom);\nEXPORT_SYMBOL(sys_getsockopt);\nEXPORT_SYMBOL(sys_setsockopt);\nEXPORT_SYMBOL(sys_listen);\nEXPORT_SYMBOL(sys_shutdown);\nEXPORT_SYMBOL(sys_connect);\nEXPORT_SYMBOL(sys_accept);\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/fifobuf.c",
    "content": "/* $Id: fifobuf.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/fifobuf.h>\n#include <pj/log.h>\n#include <pj/assert.h>\n#include <pj/os.h>\n\n#define THIS_FILE   \"fifobuf\"\n\n#define SZ  sizeof(unsigned)\n\nPJ_DEF(void) pj_fifobuf_init (pj_fifobuf_t *fifobuf, void *buffer, unsigned size)\n{\n    PJ_CHECK_STACK();\n\n    PJ_LOG(6, (THIS_FILE, \n\t       \"fifobuf_init fifobuf=%p buffer=%p, size=%d\", \n\t       fifobuf, buffer, size));\n\n    fifobuf->first = (char*)buffer;\n    fifobuf->last = fifobuf->first + size;\n    fifobuf->ubegin = fifobuf->uend = fifobuf->first;\n    fifobuf->full = 0;\n}\n\nPJ_DEF(unsigned) pj_fifobuf_max_size (pj_fifobuf_t *fifobuf)\n{\n    unsigned s1, s2;\n\n    PJ_CHECK_STACK();\n\n    if (fifobuf->uend >= fifobuf->ubegin) {\n\ts1 = (unsigned)(fifobuf->last - fifobuf->uend);\n\ts2 = (unsigned)(fifobuf->ubegin - fifobuf->first);\n    } else {\n\ts1 = s2 = (unsigned)(fifobuf->ubegin - fifobuf->uend);\n    }\n    \n    return s1<s2 ? s2 : s1;\n}\n\nPJ_DEF(void*) pj_fifobuf_alloc (pj_fifobuf_t *fifobuf, unsigned size)\n{\n    unsigned available;\n    char *start;\n\n    PJ_CHECK_STACK();\n\n    if (fifobuf->full) {\n\tPJ_LOG(6, (THIS_FILE, \n\t\t   \"fifobuf_alloc fifobuf=%p, size=%d: full!\", \n\t\t   fifobuf, size));\n\treturn NULL;\n    }\n\n    /* try to allocate from the end part of the fifo */\n    if (fifobuf->uend >= fifobuf->ubegin) {\n\tavailable = (unsigned)(fifobuf->last - fifobuf->uend);\n\tif (available >= size+SZ) {\n\t    char *ptr = fifobuf->uend;\n\t    fifobuf->uend += (size+SZ);\n\t    if (fifobuf->uend == fifobuf->last)\n\t\tfifobuf->uend = fifobuf->first;\n\t    if (fifobuf->uend == fifobuf->ubegin)\n\t\tfifobuf->full = 1;\n\t    *(unsigned*)ptr = size+SZ;\n\t    ptr += SZ;\n\n\t    PJ_LOG(6, (THIS_FILE, \n\t\t       \"fifobuf_alloc fifobuf=%p, size=%d: returning %p, p1=%p, p2=%p\", \n\t\t       fifobuf, size, ptr, fifobuf->ubegin, fifobuf->uend));\n\t    return ptr;\n\t}\n    }\n\n    /* try to allocate from the start part of the fifo */\n    start = (fifobuf->uend <= fifobuf->ubegin) ? fifobuf->uend : fifobuf->first;\n    available = (unsigned)(fifobuf->ubegin - start);\n    if (available >= size+SZ) {\n\tchar *ptr = start;\n\tfifobuf->uend = start + size + SZ;\n\tif (fifobuf->uend == fifobuf->ubegin)\n\t    fifobuf->full = 1;\n\t*(unsigned*)ptr = size+SZ;\n\tptr += SZ;\n\n\tPJ_LOG(6, (THIS_FILE, \n\t\t   \"fifobuf_alloc fifobuf=%p, size=%d: returning %p, p1=%p, p2=%p\", \n\t\t   fifobuf, size, ptr, fifobuf->ubegin, fifobuf->uend));\n\treturn ptr;\n    }\n\n    PJ_LOG(6, (THIS_FILE, \n\t       \"fifobuf_alloc fifobuf=%p, size=%d: no space left! p1=%p, p2=%p\", \n\t       fifobuf, size, fifobuf->ubegin, fifobuf->uend));\n    return NULL;\n}\n\nPJ_DEF(pj_status_t) pj_fifobuf_unalloc (pj_fifobuf_t *fifobuf, void *buf)\n{\n    char *ptr = (char*)buf;\n    char *endptr;\n    unsigned sz;\n\n    PJ_CHECK_STACK();\n\n    ptr -= SZ;\n    sz = *(unsigned*)ptr;\n\n    endptr = fifobuf->uend;\n    if (endptr == fifobuf->first)\n\tendptr = fifobuf->last;\n\n    if (ptr+sz != endptr) {\n\tpj_assert(!\"Invalid pointer to undo alloc\");\n\treturn -1;\n    }\n\n    fifobuf->uend = ptr;\n    fifobuf->full = 0;\n\n    PJ_LOG(6, (THIS_FILE, \n\t       \"fifobuf_unalloc fifobuf=%p, ptr=%p, size=%d, p1=%p, p2=%p\", \n\t       fifobuf, buf, sz, fifobuf->ubegin, fifobuf->uend));\n\n    return 0;\n}\n\nPJ_DEF(pj_status_t) pj_fifobuf_free (pj_fifobuf_t *fifobuf, void *buf)\n{\n    char *ptr = (char*)buf;\n    char *end;\n    unsigned sz;\n\n    PJ_CHECK_STACK();\n\n    ptr -= SZ;\n    if (ptr < fifobuf->first || ptr >= fifobuf->last) {\n\tpj_assert(!\"Invalid pointer to free\");\n\treturn -1;\n    }\n\n    if (ptr != fifobuf->ubegin && ptr != fifobuf->first) {\n\tpj_assert(!\"Invalid free() sequence!\");\n\treturn -1;\n    }\n\n    end = (fifobuf->uend > fifobuf->ubegin) ? fifobuf->uend : fifobuf->last;\n    sz = *(unsigned*)ptr;\n    if (ptr+sz > end) {\n\tpj_assert(!\"Invalid size!\");\n\treturn -1;\n    }\n\n    fifobuf->ubegin = ptr + sz;\n\n    /* Rollover */\n    if (fifobuf->ubegin == fifobuf->last)\n\tfifobuf->ubegin = fifobuf->first;\n\n    /* Reset if fifobuf is empty */\n    if (fifobuf->ubegin == fifobuf->uend)\n\tfifobuf->ubegin = fifobuf->uend = fifobuf->first;\n\n    fifobuf->full = 0;\n\n    PJ_LOG(6, (THIS_FILE, \n\t       \"fifobuf_free fifobuf=%p, ptr=%p, size=%d, p1=%p, p2=%p\", \n\t       fifobuf, buf, sz, fifobuf->ubegin, fifobuf->uend));\n\n    return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/file_access_unistd.c",
    "content": "/* $Id: file_access_unistd.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/file_access.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <unistd.h>\n#include <stdio.h>\t/* rename() */\n#include <errno.h>\n\n/*\n * pj_file_exists()\n */\nPJ_DEF(pj_bool_t) pj_file_exists(const char *filename)\n{\n    struct stat buf;\n\n    PJ_ASSERT_RETURN(filename, 0);\n\n    if (stat(filename, &buf) != 0)\n\treturn 0;\n\n    return PJ_TRUE;\n}\n\n\n/*\n * pj_file_size()\n */\nPJ_DEF(pj_off_t) pj_file_size(const char *filename)\n{\n    struct stat buf;\n\n    PJ_ASSERT_RETURN(filename, -1);\n\n    if (stat(filename, &buf) != 0)\n\treturn -1;\n\n    return buf.st_size;\n}\n\n\n/*\n * pj_file_delete()\n */\nPJ_DEF(pj_status_t) pj_file_delete(const char *filename)\n{\n    PJ_ASSERT_RETURN(filename, PJ_EINVAL);\n\n    if (unlink(filename)!=0) {\n\treturn PJ_RETURN_OS_ERROR(errno);\n    }\n    return PJ_SUCCESS;\n}\n\n\n/*\n * pj_file_move()\n */\nPJ_DEF(pj_status_t) pj_file_move( const char *oldname, const char *newname)\n{\n    PJ_ASSERT_RETURN(oldname && newname, PJ_EINVAL);\n\n    if (rename(oldname, newname) != 0) {\n\treturn PJ_RETURN_OS_ERROR(errno);\n    }\n    return PJ_SUCCESS;\n}\n\n\n/*\n * pj_file_getstat()\n */\nPJ_DEF(pj_status_t) pj_file_getstat(const char *filename, \n\t\t\t\t    pj_file_stat *statbuf)\n{\n    struct stat buf;\n\n    PJ_ASSERT_RETURN(filename && statbuf, PJ_EINVAL);\n\n    if (stat(filename, &buf) != 0) {\n\treturn PJ_RETURN_OS_ERROR(errno);\n    }\n\n    statbuf->size = buf.st_size;\n    statbuf->ctime.sec = buf.st_ctime;\n    statbuf->ctime.msec = 0;\n    statbuf->mtime.sec = buf.st_mtime;\n    statbuf->mtime.msec = 0;\n    statbuf->atime.sec = buf.st_atime;\n    statbuf->atime.msec = 0;\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/file_access_win32.c",
    "content": "/* $Id: file_access_win32.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/file_access.h>\n#include <pj/unicode.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/string.h>\n#include <pj/os.h>\n#include <windows.h>\n#include <time.h>\n\n#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0\n    /* WinCE lacks READ_CONTROL so we must use GENERIC_READ */\n#   define CONTROL_ACCESS   GENERIC_READ\n#else\n#   define CONTROL_ACCESS   READ_CONTROL\n#endif\n\n\n/*\n * pj_file_exists()\n */\nPJ_DEF(pj_bool_t) pj_file_exists(const char *filename)\n{\n    PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)\n    HANDLE hFile;\n\n    PJ_ASSERT_RETURN(filename != NULL, 0);\n\n    hFile = CreateFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename)), \n\t\t       CONTROL_ACCESS, \n\t\t       FILE_SHARE_READ, NULL,\n                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\n    if (hFile == INVALID_HANDLE_VALUE)\n        return 0;\n\n    CloseHandle(hFile);\n    return PJ_TRUE;\n}\n\n\n/*\n * pj_file_size()\n */\nPJ_DEF(pj_off_t) pj_file_size(const char *filename)\n{\n    PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)\n    HANDLE hFile;\n    DWORD sizeLo, sizeHi;\n    pj_off_t size;\n\n    PJ_ASSERT_RETURN(filename != NULL, -1);\n\n    hFile = CreateFile(PJ_STRING_TO_NATIVE(filename, wfilename,sizeof(wfilename)), \n\t\t       CONTROL_ACCESS, \n                       FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,\n                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\n    if (hFile == INVALID_HANDLE_VALUE)\n        return -1;\n\n    sizeLo = GetFileSize(hFile, &sizeHi);\n    if (sizeLo == INVALID_FILE_SIZE) {\n        DWORD dwStatus = GetLastError();\n        if (dwStatus != NO_ERROR) {\n            CloseHandle(hFile);\n            return -1;\n        }\n    }\n\n    size = sizeHi;\n    size = (size << 32) + sizeLo;\n\n    CloseHandle(hFile);\n    return size;\n}\n\n\n/*\n * pj_file_delete()\n */\nPJ_DEF(pj_status_t) pj_file_delete(const char *filename)\n{\n    PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)\n\n    PJ_ASSERT_RETURN(filename != NULL, PJ_EINVAL);\n\n    if (DeleteFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename))) == FALSE)\n        return PJ_RETURN_OS_ERROR(GetLastError());\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * pj_file_move()\n */\nPJ_DEF(pj_status_t) pj_file_move( const char *oldname, const char *newname)\n{\n    PJ_DECL_UNICODE_TEMP_BUF(woldname,256)\n    PJ_DECL_UNICODE_TEMP_BUF(wnewname,256)\n    BOOL rc;\n\n    PJ_ASSERT_RETURN(oldname!=NULL && newname!=NULL, PJ_EINVAL);\n\n#if PJ_WIN32_WINNT >= 0x0400\n    rc = MoveFileEx(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)), \n\t\t    PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname)), \n                    MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING);\n#else\n    rc = MoveFile(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)), \n\t\t  PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname)));\n#endif\n\n    if (!rc)\n        return PJ_RETURN_OS_ERROR(GetLastError());\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t file_time_to_time_val(const FILETIME *file_time,\n                                         pj_time_val *time_val)\n{\n    FILETIME local_file_time;\n    SYSTEMTIME localTime;\n    pj_parsed_time pt;\n\n    if (!FileTimeToLocalFileTime(file_time, &local_file_time))\n\treturn PJ_RETURN_OS_ERROR(GetLastError());\n\n    if (!FileTimeToSystemTime(file_time, &localTime))\n        return PJ_RETURN_OS_ERROR(GetLastError());\n\n    //if (!SystemTimeToTzSpecificLocalTime(NULL, &systemTime, &localTime))\n    //    return PJ_RETURN_OS_ERROR(GetLastError());\n\n    pj_bzero(&pt, sizeof(pt));\n    pt.year = localTime.wYear;\n    pt.mon = localTime.wMonth-1;\n    pt.day = localTime.wDay;\n    pt.wday = localTime.wDayOfWeek;\n\n    pt.hour = localTime.wHour;\n    pt.min = localTime.wMinute;\n    pt.sec = localTime.wSecond;\n    pt.msec = localTime.wMilliseconds;\n\n    return pj_time_encode(&pt, time_val);\n}\n\n/*\n * pj_file_getstat()\n */\nPJ_DEF(pj_status_t) pj_file_getstat(const char *filename, pj_file_stat *stat)\n{\n    PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)\n    HANDLE hFile;\n    DWORD sizeLo, sizeHi;\n    FILETIME creationTime, accessTime, writeTime;\n\n    PJ_ASSERT_RETURN(filename!=NULL && stat!=NULL, PJ_EINVAL);\n\n    hFile = CreateFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename)), \n\t\t       CONTROL_ACCESS, \n\t\t       FILE_SHARE_READ, NULL,\n                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\n    if (hFile == INVALID_HANDLE_VALUE)\n        return PJ_RETURN_OS_ERROR(GetLastError());\n\n    sizeLo = GetFileSize(hFile, &sizeHi);\n    if (sizeLo == INVALID_FILE_SIZE) {\n        DWORD dwStatus = GetLastError();\n        if (dwStatus != NO_ERROR) {\n            CloseHandle(hFile);\n            return PJ_RETURN_OS_ERROR(dwStatus);\n        }\n    }\n\n    stat->size = sizeHi;\n    stat->size = (stat->size << 32) + sizeLo;\n\n    if (GetFileTime(hFile, &creationTime, &accessTime, &writeTime)==FALSE) {\n        DWORD dwStatus = GetLastError();\n        CloseHandle(hFile);\n        return PJ_RETURN_OS_ERROR(dwStatus);\n    }\n\n    CloseHandle(hFile);\n\n    if (file_time_to_time_val(&creationTime, &stat->ctime) != PJ_SUCCESS)\n        return PJ_RETURN_OS_ERROR(GetLastError());\n\n    file_time_to_time_val(&accessTime, &stat->atime);\n    file_time_to_time_val(&writeTime, &stat->mtime);\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/file_io_ansi.c",
    "content": "/* $Id: file_io_ansi.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/file_io.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <stdio.h>\n#include <errno.h>\n\nPJ_DEF(pj_status_t) pj_file_open( pj_pool_t *pool,\n                                  const char *pathname, \n                                  unsigned flags,\n                                  pj_oshandle_t *fd)\n{\n    char mode[8];\n    char *p = mode;\n\n    PJ_ASSERT_RETURN(pathname && fd, PJ_EINVAL);\n    PJ_UNUSED_ARG(pool);\n\n    if ((flags & PJ_O_APPEND) == PJ_O_APPEND) {\n        if ((flags & PJ_O_WRONLY) == PJ_O_WRONLY) {\n            *p++ = 'a';\n            if ((flags & PJ_O_RDONLY) == PJ_O_RDONLY)\n                *p++ = '+';\n        } else {\n            /* This is invalid.\n             * Can not specify PJ_O_RDONLY with PJ_O_APPEND! \n             */\n        }\n    } else {\n        if ((flags & PJ_O_RDONLY) == PJ_O_RDONLY) {\n            *p++ = 'r';\n            if ((flags & PJ_O_WRONLY) == PJ_O_WRONLY)\n                *p++ = '+';\n        } else {\n            *p++ = 'w';\n        }\n    }\n\n    if (p==mode)\n        return PJ_EINVAL;\n\n    *p++ = 'b';\n    *p++ = '\\0';\n\n    *fd = fopen(pathname, mode);\n    if (*fd == NULL)\n        return PJ_RETURN_OS_ERROR(errno);\n    \n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_file_close(pj_oshandle_t fd)\n{\n    PJ_ASSERT_RETURN(fd, PJ_EINVAL);\n    if (fclose((FILE*)fd) != 0)\n        return PJ_RETURN_OS_ERROR(errno);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_file_write( pj_oshandle_t fd,\n                                   const void *data,\n                                   pj_ssize_t *size)\n{\n    size_t written;\n\n    clearerr((FILE*)fd);\n    written = fwrite(data, 1, *size, (FILE*)fd);\n    if (ferror((FILE*)fd)) {\n        *size = -1;\n        return PJ_RETURN_OS_ERROR(errno);\n    }\n\n    *size = written;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_file_read( pj_oshandle_t fd,\n                                  void *data,\n                                  pj_ssize_t *size)\n{\n    size_t bytes;\n\n    clearerr((FILE*)fd);\n    bytes = fread(data, 1, *size, (FILE*)fd);\n    if (ferror((FILE*)fd)) {\n        *size = -1;\n        return PJ_RETURN_OS_ERROR(errno);\n    }\n\n    *size = bytes;\n    return PJ_SUCCESS;\n}\n\n/*\nPJ_DEF(pj_bool_t) pj_file_eof(pj_oshandle_t fd, enum pj_file_access access)\n{\n    PJ_UNUSED_ARG(access);\n    return feof((FILE*)fd) ? PJ_TRUE : 0;\n}\n*/\n\nPJ_DEF(pj_status_t) pj_file_setpos( pj_oshandle_t fd,\n                                    pj_off_t offset,\n                                    enum pj_file_seek_type whence)\n{\n    int mode;\n\n    switch (whence) {\n    case PJ_SEEK_SET:\n        mode = SEEK_SET; break;\n    case PJ_SEEK_CUR:\n        mode = SEEK_CUR; break;\n    case PJ_SEEK_END:\n        mode = SEEK_END; break;\n    default:\n        pj_assert(!\"Invalid whence in file_setpos\");\n        return PJ_EINVAL;\n    }\n\n    if (fseek((FILE*)fd, (long)offset, mode) != 0)\n        return PJ_RETURN_OS_ERROR(errno);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_file_getpos( pj_oshandle_t fd,\n                                    pj_off_t *pos)\n{\n    long offset;\n\n    offset = ftell((FILE*)fd);\n    if (offset == -1) {\n        *pos = -1;\n        return PJ_RETURN_OS_ERROR(errno);\n    }\n\n    *pos = offset;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_file_flush(pj_oshandle_t fd)\n{\n    int rc;\n\n    rc = fflush((FILE*)fd);\n    if (rc == EOF) {\n\treturn PJ_RETURN_OS_ERROR(errno);\n    }\n\n    return PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/file_io_win32.c",
    "content": "/* $Id: file_io_win32.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/file_io.h>\n#include <pj/unicode.h>\n#include <pj/errno.h>\n#include <pj/assert.h>\n\n#include <windows.h>\n\n#ifndef INVALID_SET_FILE_POINTER\n#   define INVALID_SET_FILE_POINTER     ((DWORD)-1)\n#endif\n\n/**\n * Check for end-of-file condition on the specified descriptor.\n *\n * @param fd            The file descriptor.\n * @param access        The desired access.\n *\n * @return              Non-zero if file is EOF.\n */\nPJ_DECL(pj_bool_t) pj_file_eof(pj_oshandle_t fd, \n                               enum pj_file_access access);\n\n\nPJ_DEF(pj_status_t) pj_file_open( pj_pool_t *pool,\n                                  const char *pathname, \n                                  unsigned flags,\n                                  pj_oshandle_t *fd)\n{\n    PJ_DECL_UNICODE_TEMP_BUF(wpathname,256)\n    HANDLE hFile;\n    DWORD dwDesiredAccess = 0;\n    DWORD dwShareMode = 0;\n    DWORD dwCreationDisposition = 0;\n    DWORD dwFlagsAndAttributes = 0;\n\n    PJ_UNUSED_ARG(pool);\n\n    PJ_ASSERT_RETURN(pathname!=NULL, PJ_EINVAL);\n\n    if ((flags & PJ_O_WRONLY) == PJ_O_WRONLY) {\n        dwDesiredAccess |= GENERIC_WRITE;\n        if ((flags & PJ_O_APPEND) == PJ_O_APPEND) {\n#if !defined(PJ_WIN32_WINCE) || !PJ_WIN32_WINCE\n\t    /* FILE_APPEND_DATA is invalid on WM2003 and WM5, but it seems\n\t     * to be working on WM6. All are tested on emulator though.\n\t     * Removing this also seem to work (i.e. data is appended), so\n\t     * I guess this flag is \"optional\".\n\t     * See http://trac.pjsip.org/repos/ticket/825\n\t     */\n            dwDesiredAccess |= FILE_APPEND_DATA;\n#endif\n\t    dwCreationDisposition |= OPEN_ALWAYS;\n        } else {\n            dwDesiredAccess &= ~(FILE_APPEND_DATA);\n            dwCreationDisposition |= CREATE_ALWAYS;\n        }\n    }\n    if ((flags & PJ_O_RDONLY) == PJ_O_RDONLY) {\n        dwDesiredAccess |= GENERIC_READ;\n        if (flags == PJ_O_RDONLY)\n            dwCreationDisposition |= OPEN_EXISTING;\n    }\n\n    if (dwDesiredAccess == 0) {\n        pj_assert(!\"Invalid file open flags\");\n        return PJ_EINVAL;\n    }\n\n    dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;\n    dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;\n\n    hFile = CreateFile(PJ_STRING_TO_NATIVE(pathname,wpathname,sizeof(wpathname)), \n\t\t       dwDesiredAccess, dwShareMode, NULL,\n                       dwCreationDisposition, dwFlagsAndAttributes, NULL);\n    if (hFile == INVALID_HANDLE_VALUE) {\n        *fd = 0;\n        return PJ_RETURN_OS_ERROR(GetLastError());\n    }\n\n    if ((flags & PJ_O_APPEND) == PJ_O_APPEND) {\n\tpj_status_t status;\n\n\tstatus = pj_file_setpos(hFile, 0, PJ_SEEK_END);\n\tif (status != PJ_SUCCESS) {\n\t    pj_file_close(hFile);\n\t    return status;\n\t}\n    }\n\n    *fd = hFile;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_file_close(pj_oshandle_t fd)\n{\n    if (CloseHandle(fd)==0)\n        return PJ_RETURN_OS_ERROR(GetLastError());\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_file_write( pj_oshandle_t fd,\n                                   const void *data,\n                                   pj_ssize_t *size)\n{\n    BOOL rc;\n    DWORD bytesWritten;\n\n    rc = WriteFile(fd, data, (DWORD)*size, &bytesWritten, NULL);\n    if (!rc) {\n        *size = -1;\n        return PJ_RETURN_OS_ERROR(GetLastError());\n    }\n\n    *size = bytesWritten;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_file_read( pj_oshandle_t fd,\n                                  void *data,\n                                  pj_ssize_t *size)\n{\n    BOOL rc;\n    DWORD bytesRead;\n\n    rc = ReadFile(fd, data, (DWORD)*size, &bytesRead, NULL);\n    if (!rc) {\n        *size = -1;\n        return PJ_RETURN_OS_ERROR(GetLastError());\n    }\n\n    *size = bytesRead;\n    return PJ_SUCCESS;\n}\n\n/*\nPJ_DEF(pj_bool_t) pj_file_eof(pj_oshandle_t fd, enum pj_file_access access)\n{\n    BOOL rc;\n    DWORD dummy = 0, bytes;\n    DWORD dwStatus;\n\n    if ((access & PJ_O_RDONLY) == PJ_O_RDONLY) {\n        rc = ReadFile(fd, &dummy, 0, &bytes, NULL);\n    } else if ((access & PJ_O_WRONLY) == PJ_O_WRONLY) {\n        rc = WriteFile(fd, &dummy, 0, &bytes, NULL);\n    } else {\n        pj_assert(!\"Invalid access\");\n        return PJ_TRUE;\n    }\n\n    dwStatus = GetLastError();\n    if (dwStatus==ERROR_HANDLE_EOF)\n        return PJ_TRUE;\n\n    return 0;\n}\n*/\n\nPJ_DEF(pj_status_t) pj_file_setpos( pj_oshandle_t fd,\n                                    pj_off_t offset,\n                                    enum pj_file_seek_type whence)\n{\n    DWORD dwMoveMethod;\n    DWORD dwNewPos;\n    LONG  hi32;\n\n    if (whence == PJ_SEEK_SET)\n        dwMoveMethod = FILE_BEGIN;\n    else if (whence == PJ_SEEK_CUR)\n        dwMoveMethod = FILE_CURRENT;\n    else if (whence == PJ_SEEK_END)\n        dwMoveMethod = FILE_END;\n    else {\n        pj_assert(!\"Invalid whence in file_setpos\");\n        return PJ_EINVAL;\n    }\n\n    hi32 = (LONG)(offset >> 32);\n    dwNewPos = SetFilePointer(fd, (long)offset, &hi32, dwMoveMethod);\n    if (dwNewPos == (DWORD)INVALID_SET_FILE_POINTER) {\n        DWORD dwStatus = GetLastError();\n        if (dwStatus != 0)\n            return PJ_RETURN_OS_ERROR(dwStatus);\n        /* dwNewPos actually is not an error. */\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_file_getpos( pj_oshandle_t fd,\n                                    pj_off_t *pos)\n{\n    LONG hi32 = 0;\n    DWORD lo32;\n\n    lo32 = SetFilePointer(fd, 0, &hi32, FILE_CURRENT);\n    if (lo32 == (DWORD)INVALID_SET_FILE_POINTER) {\n        DWORD dwStatus = GetLastError();\n        if (dwStatus != 0)\n            return PJ_RETURN_OS_ERROR(dwStatus);\n    }\n\n    *pos = hi32;\n    *pos = (*pos << 32) + lo32;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_file_flush(pj_oshandle_t fd)\n{\n    BOOL rc;\n\n    rc = FlushFileBuffers(fd);\n\n    if (!rc) {\n\tDWORD dwStatus = GetLastError();\n        if (dwStatus != 0)\n            return PJ_RETURN_OS_ERROR(dwStatus);\n    }\n\n    return PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/guid.c",
    "content": "/* $Id: guid.c 4208 2012-07-18 07:52:33Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/ctype.h>\n#include <pj/guid.h>\n#include <pj/pool.h>\n\nPJ_DEF(pj_str_t*) pj_generate_unique_string_lower(pj_str_t *str)\n{\n    int i;\n\n    pj_generate_unique_string(str);\n    for (i = 0; i < str->slen; i++)\n\tstr->ptr[i] = (char)pj_tolower(str->ptr[i]);\n\n    return str;\n}\n\nPJ_DEF(void) pj_create_unique_string(pj_pool_t *pool, pj_str_t *str)\n{\n    str->ptr = (char*)pj_pool_alloc(pool, PJ_GUID_STRING_LENGTH);\n    pj_generate_unique_string(str);\n}\n\nPJ_DEF(void) pj_create_unique_string_lower(pj_pool_t *pool, pj_str_t *str)\n{\n    int i;\n\n    pj_create_unique_string(pool, str);\n    for (i = 0; i < str->slen; i++)\n\tstr->ptr[i] = (char)pj_tolower(str->ptr[i]);\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/guid_simple.c",
    "content": "/* $Id: guid_simple.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/guid.h>\n#include <pj/assert.h>\n#include <pj/rand.h>\n#include <pj/os.h>\n#include <pj/string.h>\n\nPJ_DEF_DATA(const unsigned) PJ_GUID_STRING_LENGTH=32;\n\nstatic char guid_chars[64];\n\nPJ_DEF(unsigned) pj_GUID_STRING_LENGTH()\n{\n    return PJ_GUID_STRING_LENGTH;\n}\n\nstatic void init_guid_chars(void)\n{\n    char *p = guid_chars;\n    unsigned i;\n\n    for (i=0; i<10; ++i)\n\t*p++ = '0'+i;\n\n    for (i=0; i<26; ++i) {\n\t*p++ = 'a'+i;\n\t*p++ = 'A'+i;\n    }\n\n    *p++ = '-';\n    *p++ = '.';\n}\n\nPJ_DEF(pj_str_t*) pj_generate_unique_string(pj_str_t *str)\n{\n    char *p, *end;\n\n    PJ_CHECK_STACK();\n\n    if (guid_chars[0] == '\\0') {\n\tpj_enter_critical_section();\n\tif (guid_chars[0] == '\\0') {\n\t    init_guid_chars();\n\t}\n\tpj_leave_critical_section();\n    }\n\n    /* This would only work if PJ_GUID_STRING_LENGTH is multiple of 2 bytes */\n    pj_assert(PJ_GUID_STRING_LENGTH % 2 == 0);\n\n    for (p=str->ptr, end=p+PJ_GUID_STRING_LENGTH; p<end; ) {\n\tpj_uint32_t rand_val = pj_rand();\n\tpj_uint32_t rand_idx = RAND_MAX;\n\n\tfor ( ; rand_idx>0 && p<end; rand_idx>>=8, rand_val>>=8, p++) {\n\t    *p = guid_chars[(rand_val & 0xFF) & 63];\n\t}\n    }\n\n    str->slen = PJ_GUID_STRING_LENGTH;\n    return str;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/guid_uuid.c",
    "content": "/* $Id: guid_uuid.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/guid.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/os.h>\n#include <pj/string.h>\n\n#include <uuid/uuid.h>\n\nPJ_DEF_DATA(const unsigned) PJ_GUID_STRING_LENGTH=36;\n\nPJ_DEF(unsigned) pj_GUID_STRING_LENGTH()\n{\n    return PJ_GUID_STRING_LENGTH;\n}\n\nPJ_DEF(pj_str_t*) pj_generate_unique_string(pj_str_t *str)\n{\n    enum {GUID_LEN = 36};\n    char sguid[GUID_LEN + 1];\n    uuid_t uuid = {0};\n    \n    PJ_ASSERT_RETURN(GUID_LEN <= PJ_GUID_STRING_LENGTH, NULL);\n    PJ_ASSERT_RETURN(str->ptr != NULL, NULL);\n    PJ_CHECK_STACK();\n    \n    uuid_generate(uuid);\n    uuid_unparse(uuid, sguid);\n    \n    pj_memcpy(str->ptr, sguid, GUID_LEN);\n    str->slen = GUID_LEN;\n\n    return str;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/guid_win32.c",
    "content": "/* $Id: guid_win32.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/guid.h>\n#include <pj/string.h>\n#include <pj/sock.h>\n#include <windows.h>\n#include <objbase.h>\n#include <pj/os.h>\n\n\nPJ_DEF_DATA(const unsigned) PJ_GUID_STRING_LENGTH=32;\n\nPJ_DEF(unsigned) pj_GUID_STRING_LENGTH()\n{\n    return PJ_GUID_STRING_LENGTH;\n}\n\nPJ_INLINE(void) hex2digit(unsigned value, char *p)\n{\n    static char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7',\n\t\t\t '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };\n    *p++ = hex[ (value & 0xF0) >> 4 ];\n    *p++ = hex[ (value & 0x0F) ];\n}\n\nstatic void guid_to_str( GUID *guid, pj_str_t *str )\n{\n    unsigned i;\n    const unsigned char *src = (const unsigned char*)guid;\n    char *dst = str->ptr;\n\n    guid->Data1 = pj_ntohl(guid->Data1);\n    guid->Data2 = pj_ntohs(guid->Data2);\n    guid->Data3 = pj_ntohs(guid->Data3);\n\n    for (i=0; i<16; ++i) {\n\thex2digit( *src, dst );\n\tdst += 2;\n\t++src;\n    }\n    str->slen = 32;\n}\n\n\nPJ_DEF(pj_str_t*) pj_generate_unique_string(pj_str_t *str)\n{\n    GUID guid;\n\n    PJ_CHECK_STACK();\n\n    CoCreateGuid(&guid);\n    guid_to_str( &guid, str );\n    return str;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/hash.c",
    "content": "/* $Id: hash.c 4296 2012-11-07 04:56:26Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/hash.h>\n#include <pj/log.h>\n#include <pj/string.h>\n#include <pj/pool.h>\n#include <pj/os.h>\n#include <pj/ctype.h>\n#include <pj/assert.h>\n\n/**\n * The hash multiplier used to calculate hash value.\n */\n#define PJ_HASH_MULTIPLIER\t33\n\n\nstruct pj_hash_entry\n{\n    struct pj_hash_entry *next;\n    void *key;\n    pj_uint32_t hash;\n    pj_uint32_t keylen;\n    void *value;\n};\n\n\nstruct pj_hash_table_t\n{\n    pj_hash_entry     **table;\n    unsigned\t\tcount, rows;\n    pj_hash_iterator_t\titerator;\n};\n\n\n\nPJ_DEF(pj_uint32_t) pj_hash_calc(pj_uint32_t hash, const void *key, \n\t\t\t\t unsigned keylen)\n{\n    PJ_CHECK_STACK();\n\n    if (keylen==PJ_HASH_KEY_STRING) {\n\tconst pj_uint8_t *p = (const pj_uint8_t*)key;\n\tfor ( ; *p; ++p ) {\n\t    hash = (hash * PJ_HASH_MULTIPLIER) + *p;\n\t}\n    } else {\n\tconst pj_uint8_t *p = (const pj_uint8_t*)key,\n\t\t\t      *end = p + keylen;\n\tfor ( ; p!=end; ++p) {\n\t    hash = (hash * PJ_HASH_MULTIPLIER) + *p;\n\t}\n    }\n    return hash;\n}\n\nPJ_DEF(pj_uint32_t) pj_hash_calc_tolower( pj_uint32_t hval,\n                                          char *result,\n                                          const pj_str_t *key)\n{\n    long i;\n\n#if defined(PJ_HASH_USE_OWN_TOLOWER) && PJ_HASH_USE_OWN_TOLOWER != 0\n    for (i=0; i<key->slen; ++i) {\n\tpj_uint8_t c = key->ptr[i];\n        char lower;\n\tif (c & 64)\n\t    lower = (char)(c | 32);\n\telse\n\t    lower = (char)c;\n\tif (result)\n            result[i] = lower;\n\thval = hval * PJ_HASH_MULTIPLIER + lower;\n    }\n#else\n    for (i=0; i<key->slen; ++i) {\n        char lower = (char)pj_tolower(key->ptr[i]);\n\tif (result)\n            result[i] = lower;\n\thval = hval * PJ_HASH_MULTIPLIER + lower;\n    }\n#endif\n\n    return hval;\n}\n\n\nPJ_DEF(pj_hash_table_t*) pj_hash_create(pj_pool_t *pool, unsigned size)\n{\n    pj_hash_table_t *h;\n    unsigned table_size;\n    \n    /* Check that PJ_HASH_ENTRY_BUF_SIZE is correct. */\n    PJ_ASSERT_RETURN(sizeof(pj_hash_entry)<=PJ_HASH_ENTRY_BUF_SIZE, NULL);\n\n    h = PJ_POOL_ALLOC_T(pool, pj_hash_table_t);\n    h->count = 0;\n\n    PJ_LOG( 6, (\"hashtbl\", \"hash table %p created from pool %s\", h, pj_pool_getobjname(pool)));\n\n    /* size must be 2^n - 1.\n       round-up the size to this rule, except when size is 2^n, then size\n       will be round-down to 2^n-1.\n     */\n    table_size = 8;\n    do {\n\ttable_size <<= 1;    \n    } while (table_size < size);\n    table_size -= 1;\n    \n    h->rows = table_size;\n    h->table = (pj_hash_entry**)\n    \t       pj_pool_calloc(pool, table_size+1, sizeof(pj_hash_entry*));\n    return h;\n}\n\nstatic pj_hash_entry **find_entry( pj_pool_t *pool, pj_hash_table_t *ht, \n\t\t\t\t   const void *key, unsigned keylen,\n\t\t\t\t   void *val, pj_uint32_t *hval,\n\t\t\t\t   void *entry_buf, pj_bool_t lower)\n{\n    pj_uint32_t hash;\n    pj_hash_entry **p_entry, *entry;\n\n    if (hval && *hval != 0) {\n\thash = *hval;\n\tif (keylen==PJ_HASH_KEY_STRING) {\n\t    keylen = (unsigned)pj_ansi_strlen((const char*)key);\n\t}\n    } else {\n\t/* This slightly differs with pj_hash_calc() because we need \n\t * to get the keylen when keylen is PJ_HASH_KEY_STRING.\n\t */\n\thash=0;\n\tif (keylen==PJ_HASH_KEY_STRING) {\n\t    const pj_uint8_t *p = (const pj_uint8_t*)key;\n\t    for ( ; *p; ++p ) {\n                if (lower)\n                    hash = hash * PJ_HASH_MULTIPLIER + pj_tolower(*p);\n                else \n\t\t    hash = hash * PJ_HASH_MULTIPLIER + *p;\n\t    }\n\t    keylen = (unsigned)(p - (const unsigned char*)key);\n\t} else {\n\t    const pj_uint8_t *p = (const pj_uint8_t*)key,\n\t\t\t\t  *end = p + keylen;\n\t    for ( ; p!=end; ++p) {\n\t\tif (lower)\n                    hash = hash * PJ_HASH_MULTIPLIER + pj_tolower(*p);\n                else\n                    hash = hash * PJ_HASH_MULTIPLIER + *p;\n\t    }\n\t}\n\n\t/* Report back the computed hash. */\n\tif (hval)\n\t    *hval = hash;\n    }\n\n    /* scan the linked list */\n    for (p_entry = &ht->table[hash & ht->rows], entry=*p_entry; \n\t entry; \n\t p_entry = &entry->next, entry = *p_entry)\n    {\n\tif (entry->hash==hash && entry->keylen==keylen &&\n            ((lower && pj_ansi_strnicmp((const char*)entry->key,\n        \t\t\t        (const char*)key, keylen)==0) ||\n\t     (!lower && pj_memcmp(entry->key, key, keylen)==0)))\n\t{\n\t    break;\n\t}\n    }\n\n    if (entry || val==NULL)\n\treturn p_entry;\n\n    /* Entry not found, create a new one. \n     * If entry_buf is specified, use it. Otherwise allocate from pool.\n     */\n    if (entry_buf) {\n\tentry = (pj_hash_entry*)entry_buf;\n    } else {\n\t/* Pool must be specified! */\n\tPJ_ASSERT_RETURN(pool != NULL, NULL);\n\n\tentry = PJ_POOL_ALLOC_T(pool, pj_hash_entry);\n\tPJ_LOG(6, (\"hashtbl\", \n\t\t   \"%p: New p_entry %p created, pool used=%u, cap=%u\", \n\t\t   ht, entry,  pj_pool_get_used_size(pool), \n\t\t   pj_pool_get_capacity(pool)));\n    }\n    entry->next = NULL;\n    entry->hash = hash;\n    if (pool) {\n\tentry->key = pj_pool_alloc(pool, keylen);\n\tpj_memcpy(entry->key, key, keylen);\n    } else {\n\tentry->key = (void*)key;\n    }\n    entry->keylen = keylen;\n    entry->value = val;\n    *p_entry = entry;\n    \n    ++ht->count;\n    \n    return p_entry;\n}\n\nPJ_DEF(void *) pj_hash_get( pj_hash_table_t *ht,\n\t\t\t    const void *key, unsigned keylen,\n\t\t\t    pj_uint32_t *hval)\n{\n    pj_hash_entry *entry;\n    entry = *find_entry( NULL, ht, key, keylen, NULL, hval, NULL, PJ_FALSE);\n    return entry ? entry->value : NULL;\n}\n\nPJ_DEF(void *) pj_hash_get_lower( pj_hash_table_t *ht,\n\t\t\t          const void *key, unsigned keylen,\n\t\t\t          pj_uint32_t *hval)\n{\n    pj_hash_entry *entry;\n    entry = *find_entry( NULL, ht, key, keylen, NULL, hval, NULL, PJ_TRUE);\n    return entry ? entry->value : NULL;\n}\n\nstatic void hash_set( pj_pool_t *pool, pj_hash_table_t *ht,\n\t              const void *key, unsigned keylen, pj_uint32_t hval,\n\t\t      void *value, void *entry_buf, pj_bool_t lower )\n{\n    pj_hash_entry **p_entry;\n\n    p_entry = find_entry( pool, ht, key, keylen, value, &hval, entry_buf,\n                          lower);\n    if (*p_entry) {\n\tif (value == NULL) {\n\t    /* delete entry */\n\t    PJ_LOG(6, (\"hashtbl\", \"%p: p_entry %p deleted\", ht, *p_entry));\n\t    *p_entry = (*p_entry)->next;\n\t    --ht->count;\n\t    \n\t} else {\n\t    /* overwrite */\n\t    (*p_entry)->value = value;\n\t    PJ_LOG(6, (\"hashtbl\", \"%p: p_entry %p value set to %p\", ht, \n\t\t       *p_entry, value));\n\t}\n    }\n}\n\nPJ_DEF(void) pj_hash_set( pj_pool_t *pool, pj_hash_table_t *ht,\n\t\t\t  const void *key, unsigned keylen, pj_uint32_t hval,\n\t\t\t  void *value )\n{\n    hash_set(pool, ht, key, keylen, hval, value, NULL, PJ_FALSE);\n}\n\nPJ_DEF(void) pj_hash_set_lower( pj_pool_t *pool, pj_hash_table_t *ht,\n\t\t\t        const void *key, unsigned keylen,\n                                pj_uint32_t hval, void *value )\n{\n    hash_set(pool, ht, key, keylen, hval, value, NULL, PJ_TRUE);\n}\n\nPJ_DEF(void) pj_hash_set_np( pj_hash_table_t *ht,\n\t\t\t     const void *key, unsigned keylen, \n\t\t\t     pj_uint32_t hval, pj_hash_entry_buf entry_buf, \n\t\t\t     void *value)\n{\n    hash_set(NULL, ht, key, keylen, hval, value, (void *)entry_buf, PJ_FALSE);\n}\n\nPJ_DEF(void) pj_hash_set_np_lower( pj_hash_table_t *ht,\n\t\t\t           const void *key, unsigned keylen,\n\t\t\t           pj_uint32_t hval,\n                                   pj_hash_entry_buf entry_buf,\n\t\t\t           void *value)\n{\n    hash_set(NULL, ht, key, keylen, hval, value, (void *)entry_buf, PJ_TRUE);\n}\n\nPJ_DEF(unsigned) pj_hash_count( pj_hash_table_t *ht )\n{\n    return ht->count;\n}\n\nPJ_DEF(pj_hash_iterator_t*) pj_hash_first( pj_hash_table_t *ht,\n\t\t\t\t\t   pj_hash_iterator_t *it )\n{\n    it->index = 0;\n    it->entry = NULL;\n\n    for (; it->index <= ht->rows; ++it->index) {\n\tit->entry = ht->table[it->index];\n\tif (it->entry) {\n\t    break;\n\t}\n    }\n\n    return it->entry ? it : NULL;\n}\n\nPJ_DEF(pj_hash_iterator_t*) pj_hash_next( pj_hash_table_t *ht, \n\t\t\t\t\t  pj_hash_iterator_t *it )\n{\n    it->entry = it->entry->next;\n    if (it->entry) {\n\treturn it;\n    }\n\n    for (++it->index; it->index <= ht->rows; ++it->index) {\n\tit->entry = ht->table[it->index];\n\tif (it->entry) {\n\t    break;\n\t}\n    }\n\n    return it->entry ? it : NULL;\n}\n\nPJ_DEF(void*) pj_hash_this( pj_hash_table_t *ht, pj_hash_iterator_t *it )\n{\n    PJ_CHECK_STACK();\n    PJ_UNUSED_ARG(ht);\n    return it->entry->value;\n}\n\n#if 0\nvoid pj_hash_dump_collision( pj_hash_table_t *ht )\n{\n    unsigned min=0xFFFFFFFF, max=0;\n    unsigned i;\n    char line[120];\n    int len, totlen = 0;\n\n    for (i=0; i<=ht->rows; ++i) {\n\tunsigned count = 0;    \n\tpj_hash_entry *entry = ht->table[i];\n\twhile (entry) {\n\t    ++count;\n\t    entry = entry->next;\n\t}\n\tif (count < min)\n\t    min = count;\n\tif (count > max)\n\t    max = count;\n\tlen = pj_snprintf( line+totlen, sizeof(line)-totlen, \"%3d:%3d \", i, count);\n\tif (len < 1)\n\t    break;\n\ttotlen += len;\n\n\tif ((i+1) % 10 == 0) {\n\t    line[totlen] = '\\0';\n\t    PJ_LOG(4,(__FILE__, line));\n\t}\n    }\n\n    PJ_LOG(4,(__FILE__,\"Count: %d, min: %d, max: %d\\n\", ht->count, min, max));\n}\n#endif\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ioqueue_common_abs.c",
    "content": "/* $Id: ioqueue_common_abs.c 4359 2013-02-21 11:18:36Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * ioqueue_common_abs.c\n *\n * This contains common functionalities to emulate proactor pattern with\n * various event dispatching mechanisms (e.g. select, epoll).\n *\n * This file will be included by the appropriate ioqueue implementation.\n * This file is NOT supposed to be compiled as stand-alone source.\n */\n\n#define PENDING_RETRY\t2\n\nstatic void ioqueue_init( pj_ioqueue_t *ioqueue )\n{\n    ioqueue->lock = NULL;\n    ioqueue->auto_delete_lock = 0;\n    ioqueue->default_concurrency = PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY;\n}\n\nstatic pj_status_t ioqueue_destroy(pj_ioqueue_t *ioqueue)\n{\n    if (ioqueue->auto_delete_lock && ioqueue->lock ) {\n\tpj_lock_release(ioqueue->lock);\n        return pj_lock_destroy(ioqueue->lock);\n    }\n    \n    return PJ_SUCCESS;\n}\n\n/*\n * pj_ioqueue_set_lock()\n */\nPJ_DEF(pj_status_t) pj_ioqueue_set_lock( pj_ioqueue_t *ioqueue, \n\t\t\t\t\t pj_lock_t *lock,\n\t\t\t\t\t pj_bool_t auto_delete )\n{\n    PJ_ASSERT_RETURN(ioqueue && lock, PJ_EINVAL);\n\n    if (ioqueue->auto_delete_lock && ioqueue->lock) {\n        pj_lock_destroy(ioqueue->lock);\n    }\n\n    ioqueue->lock = lock;\n    ioqueue->auto_delete_lock = auto_delete;\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t ioqueue_init_key( pj_pool_t *pool,\n                                     pj_ioqueue_t *ioqueue,\n                                     pj_ioqueue_key_t *key,\n                                     pj_sock_t sock,\n                                     pj_grp_lock_t *grp_lock,\n                                     void *user_data,\n                                     const pj_ioqueue_callback *cb)\n{\n    pj_status_t rc;\n    int optlen;\n\n    PJ_UNUSED_ARG(pool);\n\n    key->ioqueue = ioqueue;\n    key->fd = sock;\n    key->user_data = user_data;\n    pj_list_init(&key->read_list);\n    pj_list_init(&key->write_list);\n#if PJ_HAS_TCP\n    pj_list_init(&key->accept_list);\n    key->connecting = 0;\n#endif\n\n    /* Save callback. */\n    pj_memcpy(&key->cb, cb, sizeof(pj_ioqueue_callback));\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Set initial reference count to 1 */\n    pj_assert(key->ref_count == 0);\n    ++key->ref_count;\n\n    key->closing = 0;\n#endif\n\n    rc = pj_ioqueue_set_concurrency(key, ioqueue->default_concurrency);\n    if (rc != PJ_SUCCESS)\n\treturn rc;\n\n    /* Get socket type. When socket type is datagram, some optimization\n     * will be performed during send to allow parallel send operations.\n     */\n    optlen = sizeof(key->fd_type);\n    rc = pj_sock_getsockopt(sock, pj_SOL_SOCKET(), pj_SO_TYPE(),\n                            &key->fd_type, &optlen);\n    if (rc != PJ_SUCCESS)\n        key->fd_type = pj_SOCK_STREAM();\n\n    /* Create mutex for the key. */\n#if !PJ_IOQUEUE_HAS_SAFE_UNREG\n    rc = pj_lock_create_simple_mutex(poll, NULL, &key->lock);\n#endif\n    if (rc != PJ_SUCCESS)\n\treturn rc;\n\n    /* Group lock */\n    key->grp_lock = grp_lock;\n    if (key->grp_lock) {\n\tpj_grp_lock_add_ref_dbg(key->grp_lock, \"ioqueue\", 0);\n    }\n    \n    return PJ_SUCCESS;\n}\n\n/*\n * pj_ioqueue_get_user_data()\n *\n * Obtain value associated with a key.\n */\nPJ_DEF(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key )\n{\n    PJ_ASSERT_RETURN(key != NULL, NULL);\n    return key->user_data;\n}\n\n/*\n * pj_ioqueue_set_user_data()\n */\nPJ_DEF(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key,\n                                              void *user_data,\n                                              void **old_data)\n{\n    PJ_ASSERT_RETURN(key, PJ_EINVAL);\n\n    if (old_data)\n        *old_data = key->user_data;\n    key->user_data = user_data;\n\n    return PJ_SUCCESS;\n}\n\nPJ_INLINE(int) key_has_pending_write(pj_ioqueue_key_t *key)\n{\n    return !pj_list_empty(&key->write_list);\n}\n\nPJ_INLINE(int) key_has_pending_read(pj_ioqueue_key_t *key)\n{\n    return !pj_list_empty(&key->read_list);\n}\n\nPJ_INLINE(int) key_has_pending_accept(pj_ioqueue_key_t *key)\n{\n#if PJ_HAS_TCP\n    return !pj_list_empty(&key->accept_list);\n#else\n    PJ_UNUSED_ARG(key);\n    return 0;\n#endif\n}\n\nPJ_INLINE(int) key_has_pending_connect(pj_ioqueue_key_t *key)\n{\n    return key->connecting;\n}\n\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n#   define IS_CLOSING(key)  (key->closing)\n#else\n#   define IS_CLOSING(key)  (0)\n#endif\n\n\n/*\n * ioqueue_dispatch_event()\n *\n * Report occurence of an event in the key to be processed by the\n * framework.\n */\npj_bool_t ioqueue_dispatch_write_event( pj_ioqueue_t *ioqueue,\n\t\t\t\t        pj_ioqueue_key_t *h)\n{\n    pj_status_t rc;\n\n    /* Try lock the key. */\n    rc = pj_ioqueue_trylock_key(h);\n    if (rc != PJ_SUCCESS) {\n\treturn PJ_FALSE;\n    }\n\n    if (IS_CLOSING(h)) {\n\tpj_ioqueue_unlock_key(h);\n\treturn PJ_TRUE;\n    }\n\n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP!=0\n    if (h->connecting) {\n\t/* Completion of connect() operation */\n\tpj_status_t status;\n\tpj_bool_t has_lock;\n\n\t/* Clear operation. */\n\th->connecting = 0;\n\n        ioqueue_remove_from_set(ioqueue, h, WRITEABLE_EVENT);\n        ioqueue_remove_from_set(ioqueue, h, EXCEPTION_EVENT);\n\n\n#if (defined(PJ_HAS_SO_ERROR) && PJ_HAS_SO_ERROR!=0)\n\t/* from connect(2): \n\t * On Linux, use getsockopt to read the SO_ERROR option at\n\t * level SOL_SOCKET to determine whether connect() completed\n\t * successfully (if SO_ERROR is zero).\n\t */\n\t{\n\t  int value;\n\t  int vallen = sizeof(value);\n\t  int gs_rc = pj_sock_getsockopt(h->fd, SOL_SOCKET, SO_ERROR, \n\t\t\t\t\t &value, &vallen);\n\t  if (gs_rc != 0) {\n\t    /* Argh!! What to do now??? \n\t     * Just indicate that the socket is connected. The\n\t     * application will get error as soon as it tries to use\n\t     * the socket to send/receive.\n\t     */\n\t      status = PJ_SUCCESS;\n\t  } else {\n\t      status = PJ_STATUS_FROM_OS(value);\n\t  }\n \t}\n#elif (defined(PJ_WIN32) && PJ_WIN32!=0) || (defined(PJ_WIN64) && PJ_WIN64!=0) \n\tstatus = PJ_SUCCESS; /* success */\n#else\n\t/* Excellent information in D.J. Bernstein page:\n\t * http://cr.yp.to/docs/connect.html\n\t *\n\t * Seems like the most portable way of detecting connect()\n\t * failure is to call getpeername(). If socket is connected,\n\t * getpeername() will return 0. If the socket is not connected,\n\t * it will return ENOTCONN, and read(fd, &ch, 1) will produce\n\t * the right errno through error slippage. This is a combination\n\t * of suggestions from Douglas C. Schmidt and Ken Keys.\n\t */\n\t{\n\t    struct sockaddr_in addr;\n\t    int addrlen = sizeof(addr);\n\n\t    status = pj_sock_getpeername(h->fd, (struct sockaddr*)&addr,\n\t\t\t\t         &addrlen);\n\t}\n#endif\n\n        /* Unlock; from this point we don't need to hold key's mutex\n\t * (unless concurrency is disabled, which in this case we should\n\t * hold the mutex while calling the callback) */\n\tif (h->allow_concurrent) {\n\t    /* concurrency may be changed while we're in the callback, so\n\t     * save it to a flag.\n\t     */\n\t    has_lock = PJ_FALSE;\n\t    pj_ioqueue_unlock_key(h);\n\t} else {\n\t    has_lock = PJ_TRUE;\n\t}\n\n\t/* Call callback. */\n        if (h->cb.on_connect_complete && !IS_CLOSING(h))\n\t    (*h->cb.on_connect_complete)(h, status);\n\n\t/* Unlock if we still hold the lock */\n\tif (has_lock) {\n\t    pj_ioqueue_unlock_key(h);\n\t}\n\n        /* Done. */\n\n    } else \n#endif /* PJ_HAS_TCP */\n    if (key_has_pending_write(h)) {\n\t/* Socket is writable. */\n        struct write_operation *write_op;\n        pj_ssize_t sent;\n        pj_status_t send_rc = PJ_SUCCESS;\n\n        /* Get the first in the queue. */\n        write_op = h->write_list.next;\n\n        /* For datagrams, we can remove the write_op from the list\n         * so that send() can work in parallel.\n         */\n        if (h->fd_type == pj_SOCK_DGRAM()) {\n            pj_list_erase(write_op);\n\n            if (pj_list_empty(&h->write_list))\n                ioqueue_remove_from_set(ioqueue, h, WRITEABLE_EVENT);\n\n        }\n\n        /* Send the data. \n         * Unfortunately we must do this while holding key's mutex, thus\n         * preventing parallel write on a single key.. :-((\n         */\n        sent = write_op->size - write_op->written;\n        if (write_op->op == PJ_IOQUEUE_OP_SEND) {\n            send_rc = pj_sock_send(h->fd, write_op->buf+write_op->written,\n                                   &sent, write_op->flags);\n\t    /* Can't do this. We only clear \"op\" after we're finished sending\n\t     * the whole buffer.\n\t     */\n\t    //write_op->op = 0;\n        } else if (write_op->op == PJ_IOQUEUE_OP_SEND_TO) {\n\t    int retry = 2;\n\t    while (--retry >= 0) {\n\t\tsend_rc = pj_sock_sendto(h->fd, \n\t\t\t\t\t write_op->buf+write_op->written,\n\t\t\t\t\t &sent, write_op->flags,\n\t\t\t\t\t &write_op->rmt_addr, \n\t\t\t\t\t write_op->rmt_addrlen);\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n\t    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\n\t\t/* Special treatment for dead UDP sockets here, see ticket #1107 */\n\t\tif (send_rc==PJ_STATUS_FROM_OS(EPIPE) && !IS_CLOSING(h) &&\n\t\t    h->fd_type==pj_SOCK_DGRAM())\n\t\t{\n\t\t    PJ_PERROR(4,(THIS_FILE, send_rc,\n\t\t\t\t \"Send error for socket %d, retrying\",\n\t\t\t\t h->fd));\n\t\t    replace_udp_sock(h);\n\t\t    continue;\n\t\t}\n#endif\n\t\tbreak;\n\t    }\n\n\t    /* Can't do this. We only clear \"op\" after we're finished sending\n\t     * the whole buffer.\n\t     */\n\t    //write_op->op = 0;\n        } else {\n            pj_assert(!\"Invalid operation type!\");\n\t    write_op->op = PJ_IOQUEUE_OP_NONE;\n            send_rc = PJ_EBUG;\n        }\n\n        if (send_rc == PJ_SUCCESS) {\n            write_op->written += sent;\n        } else {\n            pj_assert(send_rc > 0);\n            write_op->written = -send_rc;\n        }\n\n        /* Are we finished with this buffer? */\n        if (send_rc!=PJ_SUCCESS || \n            write_op->written == (pj_ssize_t)write_op->size ||\n            h->fd_type == pj_SOCK_DGRAM()) \n        {\n\t    pj_bool_t has_lock;\n\n\t    write_op->op = PJ_IOQUEUE_OP_NONE;\n\n            if (h->fd_type != pj_SOCK_DGRAM()) {\n                /* Write completion of the whole stream. */\n                pj_list_erase(write_op);\n\n                /* Clear operation if there's no more data to send. */\n                if (pj_list_empty(&h->write_list))\n                    ioqueue_remove_from_set(ioqueue, h, WRITEABLE_EVENT);\n\n            }\n\n\t    /* Unlock; from this point we don't need to hold key's mutex\n\t     * (unless concurrency is disabled, which in this case we should\n\t     * hold the mutex while calling the callback) */\n\t    if (h->allow_concurrent) {\n\t\t/* concurrency may be changed while we're in the callback, so\n\t\t * save it to a flag.\n\t\t */\n\t\thas_lock = PJ_FALSE;\n\t\tpj_ioqueue_unlock_key(h);\n\t\tPJ_RACE_ME(5);\n\t    } else {\n\t\thas_lock = PJ_TRUE;\n\t    }\n\n\t    /* Call callback. */\n            if (h->cb.on_write_complete && !IS_CLOSING(h)) {\n\t        (*h->cb.on_write_complete)(h, \n                                           (pj_ioqueue_op_key_t*)write_op,\n                                           write_op->written);\n            }\n\n\t    if (has_lock) {\n\t\tpj_ioqueue_unlock_key(h);\n\t    }\n\n        } else {\n            pj_ioqueue_unlock_key(h);\n        }\n\n        /* Done. */\n    } else {\n        /*\n         * This is normal; execution may fall here when multiple threads\n         * are signalled for the same event, but only one thread eventually\n         * able to process the event.\n         */\n\tpj_ioqueue_unlock_key(h);\n\n\treturn PJ_FALSE;\n    }\n\n    return PJ_TRUE;\n}\n\npj_bool_t ioqueue_dispatch_read_event( pj_ioqueue_t *ioqueue,\n\t\t\t\t       pj_ioqueue_key_t *h )\n{\n    pj_status_t rc;\n\n    /* Try lock the key. */\n    rc = pj_ioqueue_trylock_key(h);\n    if (rc != PJ_SUCCESS) {\n\treturn PJ_FALSE;\n    }\n\n    if (IS_CLOSING(h)) {\n\tpj_ioqueue_unlock_key(h);\n\treturn PJ_TRUE;\n    }\n\n#   if PJ_HAS_TCP\n    if (!pj_list_empty(&h->accept_list)) {\n\n        struct accept_operation *accept_op;\n\tpj_bool_t has_lock;\n\t\n        /* Get one accept operation from the list. */\n\taccept_op = h->accept_list.next;\n        pj_list_erase(accept_op);\n        accept_op->op = PJ_IOQUEUE_OP_NONE;\n\n\t/* Clear bit in fdset if there is no more pending accept */\n        if (pj_list_empty(&h->accept_list))\n            ioqueue_remove_from_set(ioqueue, h, READABLE_EVENT);\n\n\trc=pj_sock_accept(h->fd, accept_op->accept_fd, \n                          accept_op->rmt_addr, accept_op->addrlen);\n\tif (rc==PJ_SUCCESS && accept_op->local_addr) {\n\t    rc = pj_sock_getsockname(*accept_op->accept_fd, \n                                     accept_op->local_addr,\n\t\t\t\t     accept_op->addrlen);\n\t}\n\n\t/* Unlock; from this point we don't need to hold key's mutex\n\t * (unless concurrency is disabled, which in this case we should\n\t * hold the mutex while calling the callback) */\n\tif (h->allow_concurrent) {\n\t    /* concurrency may be changed while we're in the callback, so\n\t     * save it to a flag.\n\t     */\n\t    has_lock = PJ_FALSE;\n\t    pj_ioqueue_unlock_key(h);\n\t    PJ_RACE_ME(5);\n\t} else {\n\t    has_lock = PJ_TRUE;\n\t}\n\n\t/* Call callback. */\n        if (h->cb.on_accept_complete && !IS_CLOSING(h)) {\n\t    (*h->cb.on_accept_complete)(h, \n                                        (pj_ioqueue_op_key_t*)accept_op,\n                                        *accept_op->accept_fd, rc);\n\t}\n\n\tif (has_lock) {\n\t    pj_ioqueue_unlock_key(h);\n\t}\n    }\n    else\n#   endif\n    if (key_has_pending_read(h)) {\n        struct read_operation *read_op;\n        pj_ssize_t bytes_read;\n\tpj_bool_t has_lock;\n\n        /* Get one pending read operation from the list. */\n        read_op = h->read_list.next;\n        pj_list_erase(read_op);\n\n        /* Clear fdset if there is no pending read. */\n        if (pj_list_empty(&h->read_list))\n            ioqueue_remove_from_set(ioqueue, h, READABLE_EVENT);\n\n        bytes_read = read_op->size;\n\n\tif (read_op->op == PJ_IOQUEUE_OP_RECV_FROM) {\n\t    read_op->op = PJ_IOQUEUE_OP_NONE;\n\t    rc = pj_sock_recvfrom(h->fd, read_op->buf, &bytes_read, \n\t\t\t\t  read_op->flags,\n\t\t\t\t  read_op->rmt_addr, \n                                  read_op->rmt_addrlen);\n\t} else if (read_op->op == PJ_IOQUEUE_OP_RECV) {\n\t    read_op->op = PJ_IOQUEUE_OP_NONE;\n\t    rc = pj_sock_recv(h->fd, read_op->buf, &bytes_read, \n\t\t\t      read_op->flags);\n        } else {\n            pj_assert(read_op->op == PJ_IOQUEUE_OP_READ);\n\t    read_op->op = PJ_IOQUEUE_OP_NONE;\n            /*\n             * User has specified pj_ioqueue_read().\n             * On Win32, we should do ReadFile(). But because we got\n             * here because of select() anyway, user must have put a\n             * socket descriptor on h->fd, which in this case we can\n             * just call pj_sock_recv() instead of ReadFile().\n             * On Unix, user may put a file in h->fd, so we'll have\n             * to call read() here.\n             * This may not compile on systems which doesn't have \n             * read(). That's why we only specify PJ_LINUX here so\n             * that error is easier to catch.\n             */\n#\t    if defined(PJ_WIN32) && PJ_WIN32 != 0 || \\\n\t       defined(PJ_WIN64) && PJ_WIN64 != 0 || \\\n\t       defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE != 0\n                rc = pj_sock_recv(h->fd, read_op->buf, &bytes_read, \n\t\t\t\t  read_op->flags);\n                //rc = ReadFile((HANDLE)h->fd, read_op->buf, read_op->size,\n                //              &bytes_read, NULL);\n#           elif (defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H != 0)\n                bytes_read = read(h->fd, read_op->buf, bytes_read);\n                rc = (bytes_read >= 0) ? PJ_SUCCESS : pj_get_os_error();\n#\t    elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL != 0\n                bytes_read = sys_read(h->fd, read_op->buf, bytes_read);\n                rc = (bytes_read >= 0) ? PJ_SUCCESS : -bytes_read;\n#           else\n#               error \"Implement read() for this platform!\"\n#           endif\n        }\n\t\n\tif (rc != PJ_SUCCESS) {\n#\t    if (defined(PJ_WIN32) && PJ_WIN32 != 0) || \\\n\t       (defined(PJ_WIN64) && PJ_WIN64 != 0) \n\t    /* On Win32, for UDP, WSAECONNRESET on the receive side \n\t     * indicates that previous sending has triggered ICMP Port \n\t     * Unreachable message.\n\t     * But we wouldn't know at this point which one of previous \n\t     * key that has triggered the error, since UDP socket can\n\t     * be shared!\n\t     * So we'll just ignore it!\n\t     */\n\n\t    if (rc == PJ_STATUS_FROM_OS(WSAECONNRESET)) {\n\t\t//PJ_LOG(4,(THIS_FILE, \n                //          \"Ignored ICMP port unreach. on key=%p\", h));\n\t    }\n#\t    endif\n\n            /* In any case we would report this to caller. */\n            bytes_read = -rc;\n\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\n\t    /* Special treatment for dead UDP sockets here, see ticket #1107 */\n\t    if (rc == PJ_STATUS_FROM_OS(ENOTCONN) && !IS_CLOSING(h) &&\n\t\th->fd_type==pj_SOCK_DGRAM())\n\t    {\n\t\treplace_udp_sock(h);\n\t    }\n#endif\n\t}\n\n\t/* Unlock; from this point we don't need to hold key's mutex\n\t * (unless concurrency is disabled, which in this case we should\n\t * hold the mutex while calling the callback) */\n\tif (h->allow_concurrent) {\n\t    /* concurrency may be changed while we're in the callback, so\n\t     * save it to a flag.\n\t     */\n\t    has_lock = PJ_FALSE;\n\t    pj_ioqueue_unlock_key(h);\n\t    PJ_RACE_ME(5);\n\t} else {\n\t    has_lock = PJ_TRUE;\n\t}\n\n\t/* Call callback. */\n        if (h->cb.on_read_complete && !IS_CLOSING(h)) {\n\t    (*h->cb.on_read_complete)(h, \n                                      (pj_ioqueue_op_key_t*)read_op,\n                                      bytes_read);\n        }\n\n\tif (has_lock) {\n\t    pj_ioqueue_unlock_key(h);\n\t}\n\n    } else {\n        /*\n         * This is normal; execution may fall here when multiple threads\n         * are signalled for the same event, but only one thread eventually\n         * able to process the event.\n         */\n\tpj_ioqueue_unlock_key(h);\n\n\treturn PJ_FALSE;\n    }\n\n    return PJ_TRUE;\n}\n\n\npj_bool_t ioqueue_dispatch_exception_event( pj_ioqueue_t *ioqueue,\n\t\t\t\t\t    pj_ioqueue_key_t *h )\n{\n    pj_bool_t has_lock;\n    pj_status_t rc;\n\n    /* Try lock the key. */\n    rc = pj_ioqueue_trylock_key(h);\n    if (rc != PJ_SUCCESS) {\n\treturn PJ_FALSE;\n    }\n\n    if (!h->connecting) {\n        /* It is possible that more than one thread was woken up, thus\n         * the remaining thread will see h->connecting as zero because\n         * it has been processed by other thread.\n         */\n\tpj_ioqueue_unlock_key(h);\n\treturn PJ_TRUE;\n    }\n\n    if (IS_CLOSING(h)) {\n\tpj_ioqueue_unlock_key(h);\n\treturn PJ_TRUE;\n    }\n\n    /* Clear operation. */\n    h->connecting = 0;\n\n    ioqueue_remove_from_set(ioqueue, h, WRITEABLE_EVENT);\n    ioqueue_remove_from_set(ioqueue, h, EXCEPTION_EVENT);\n\n    /* Unlock; from this point we don't need to hold key's mutex\n     * (unless concurrency is disabled, which in this case we should\n     * hold the mutex while calling the callback) */\n    if (h->allow_concurrent) {\n\t/* concurrency may be changed while we're in the callback, so\n\t * save it to a flag.\n\t */\n\thas_lock = PJ_FALSE;\n\tpj_ioqueue_unlock_key(h);\n\tPJ_RACE_ME(5);\n    } else {\n\thas_lock = PJ_TRUE;\n    }\n\n    /* Call callback. */\n    if (h->cb.on_connect_complete && !IS_CLOSING(h)) {\n\tpj_status_t status = -1;\n#if (defined(PJ_HAS_SO_ERROR) && PJ_HAS_SO_ERROR!=0)\n\tint value;\n\tint vallen = sizeof(value);\n\tint gs_rc = pj_sock_getsockopt(h->fd, SOL_SOCKET, SO_ERROR, \n\t\t\t\t       &value, &vallen);\n\tif (gs_rc == 0) {\n\t    status = PJ_RETURN_OS_ERROR(value);\n\t}\n#endif\n\n\t(*h->cb.on_connect_complete)(h, status);\n    }\n\n    if (has_lock) {\n\tpj_ioqueue_unlock_key(h);\n    }\n\n    return PJ_TRUE;\n}\n\n/*\n * pj_ioqueue_recv()\n *\n * Start asynchronous recv() from the socket.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_recv(  pj_ioqueue_key_t *key,\n                                      pj_ioqueue_op_key_t *op_key,\n\t\t\t\t      void *buffer,\n\t\t\t\t      pj_ssize_t *length,\n\t\t\t\t      unsigned flags )\n{\n    struct read_operation *read_op;\n\n    PJ_ASSERT_RETURN(key && op_key && buffer && length, PJ_EINVAL);\n    PJ_CHECK_STACK();\n\n    /* Check if key is closing (need to do this first before accessing\n     * other variables, since they might have been destroyed. See ticket\n     * #469).\n     */\n    if (IS_CLOSING(key))\n\treturn PJ_ECANCELLED;\n\n    read_op = (struct read_operation*)op_key;\n    read_op->op = PJ_IOQUEUE_OP_NONE;\n\n    /* Try to see if there's data immediately available. \n     */\n    if ((flags & PJ_IOQUEUE_ALWAYS_ASYNC) == 0) {\n\tpj_status_t status;\n\tpj_ssize_t size;\n\n\tsize = *length;\n\tstatus = pj_sock_recv(key->fd, buffer, &size, flags);\n\tif (status == PJ_SUCCESS) {\n\t    /* Yes! Data is available! */\n\t    *length = size;\n\t    return PJ_SUCCESS;\n\t} else {\n\t    /* If error is not EWOULDBLOCK (or EAGAIN on Linux), report\n\t     * the error to caller.\n\t     */\n\t    if (status != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL))\n\t\treturn status;\n\t}\n    }\n\n    flags &= ~(PJ_IOQUEUE_ALWAYS_ASYNC);\n\n    /*\n     * No data is immediately available.\n     * Must schedule asynchronous operation to the ioqueue.\n     */\n    read_op->op = PJ_IOQUEUE_OP_RECV;\n    read_op->buf = buffer;\n    read_op->size = *length;\n    read_op->flags = flags;\n\n    pj_ioqueue_lock_key(key);\n    /* Check again. Handle may have been closed after the previous check\n     * in multithreaded app. If we add bad handle to the set it will\n     * corrupt the ioqueue set. See #913\n     */\n    if (IS_CLOSING(key)) {\n\tpj_ioqueue_unlock_key(key);\n\treturn PJ_ECANCELLED;\n    }\n    pj_list_insert_before(&key->read_list, read_op);\n    ioqueue_add_to_set(key->ioqueue, key, READABLE_EVENT);\n    pj_ioqueue_unlock_key(key);\n\n    return PJ_EPENDING;\n}\n\n/*\n * pj_ioqueue_recvfrom()\n *\n * Start asynchronous recvfrom() from the socket.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_key_t *key,\n                                         pj_ioqueue_op_key_t *op_key,\n\t\t\t\t         void *buffer,\n\t\t\t\t         pj_ssize_t *length,\n                                         unsigned flags,\n\t\t\t\t         pj_sockaddr_t *addr,\n\t\t\t\t         int *addrlen)\n{\n    struct read_operation *read_op;\n\n    PJ_ASSERT_RETURN(key && op_key && buffer && length, PJ_EINVAL);\n    PJ_CHECK_STACK();\n\n    /* Check if key is closing. */\n    if (IS_CLOSING(key))\n\treturn PJ_ECANCELLED;\n\n    read_op = (struct read_operation*)op_key;\n    read_op->op = PJ_IOQUEUE_OP_NONE;\n\n    /* Try to see if there's data immediately available. \n     */\n    if ((flags & PJ_IOQUEUE_ALWAYS_ASYNC) == 0) {\n\tpj_status_t status;\n\tpj_ssize_t size;\n\n\tsize = *length;\n\tstatus = pj_sock_recvfrom(key->fd, buffer, &size, flags,\n\t\t\t\t  addr, addrlen);\n\tif (status == PJ_SUCCESS) {\n\t    /* Yes! Data is available! */\n\t    *length = size;\n\t    return PJ_SUCCESS;\n\t} else {\n\t    /* If error is not EWOULDBLOCK (or EAGAIN on Linux), report\n\t     * the error to caller.\n\t     */\n\t    if (status != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL))\n\t\treturn status;\n\t}\n    }\n\n    flags &= ~(PJ_IOQUEUE_ALWAYS_ASYNC);\n\n    /*\n     * No data is immediately available.\n     * Must schedule asynchronous operation to the ioqueue.\n     */\n    read_op->op = PJ_IOQUEUE_OP_RECV_FROM;\n    read_op->buf = buffer;\n    read_op->size = *length;\n    read_op->flags = flags;\n    read_op->rmt_addr = addr;\n    read_op->rmt_addrlen = addrlen;\n\n    pj_ioqueue_lock_key(key);\n    /* Check again. Handle may have been closed after the previous check\n     * in multithreaded app. If we add bad handle to the set it will\n     * corrupt the ioqueue set. See #913\n     */\n    if (IS_CLOSING(key)) {\n\tpj_ioqueue_unlock_key(key);\n\treturn PJ_ECANCELLED;\n    }\n    pj_list_insert_before(&key->read_list, read_op);\n    ioqueue_add_to_set(key->ioqueue, key, READABLE_EVENT);\n    pj_ioqueue_unlock_key(key);\n\n    return PJ_EPENDING;\n}\n\n/*\n * pj_ioqueue_send()\n *\n * Start asynchronous send() to the descriptor.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_send( pj_ioqueue_key_t *key,\n                                     pj_ioqueue_op_key_t *op_key,\n\t\t\t             const void *data,\n\t\t\t             pj_ssize_t *length,\n                                     unsigned flags)\n{\n    struct write_operation *write_op;\n    pj_status_t status;\n    unsigned retry;\n    pj_ssize_t sent;\n\n    PJ_ASSERT_RETURN(key && op_key && data && length, PJ_EINVAL);\n    PJ_CHECK_STACK();\n\n    /* Check if key is closing. */\n    if (IS_CLOSING(key))\n\treturn PJ_ECANCELLED;\n\n    /* We can not use PJ_IOQUEUE_ALWAYS_ASYNC for socket write. */\n    flags &= ~(PJ_IOQUEUE_ALWAYS_ASYNC);\n\n    /* Fast track:\n     *   Try to send data immediately, only if there's no pending write!\n     * Note:\n     *  We are speculating that the list is empty here without properly\n     *  acquiring ioqueue's mutex first. This is intentional, to maximize\n     *  performance via parallelism.\n     *\n     *  This should be safe, because:\n     *      - by convention, we require caller to make sure that the\n     *        key is not unregistered while other threads are invoking\n     *        an operation on the same key.\n     *      - pj_list_empty() is safe to be invoked by multiple threads,\n     *        even when other threads are modifying the list.\n     */\n    if (pj_list_empty(&key->write_list)) {\n        /*\n         * See if data can be sent immediately.\n         */\n        sent = *length;\n        status = pj_sock_send(key->fd, data, &sent, flags);\n        if (status == PJ_SUCCESS) {\n            /* Success! */\n            *length = sent;\n            return PJ_SUCCESS;\n        } else {\n            /* If error is not EWOULDBLOCK (or EAGAIN on Linux), report\n             * the error to caller.\n             */\n            if (status != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL)) {\n                return status;\n            }\n        }\n    }\n\n    /*\n     * Schedule asynchronous send.\n     */\n    write_op = (struct write_operation*)op_key;\n\n    /* Spin if write_op has pending operation */\n    for (retry=0; write_op->op != 0 && retry<PENDING_RETRY; ++retry)\n\tpj_thread_sleep(0);\n\n    /* Last chance */\n    if (write_op->op) {\n\t/* Unable to send packet because there is already pending write in the\n\t * write_op. We could not put the operation into the write_op\n\t * because write_op already contains a pending operation! And\n\t * we could not send the packet directly with send() either,\n\t * because that will break the order of the packet. So we can\n\t * only return error here.\n\t *\n\t * This could happen for example in multithreads program,\n\t * where polling is done by one thread, while other threads are doing\n\t * the sending only. If the polling thread runs on lower priority\n\t * than the sending thread, then it's possible that the pending\n\t * write flag is not cleared in-time because clearing is only done\n\t * during polling. \n\t *\n\t * Aplication should specify multiple write operation keys on\n\t * situation like this.\n\t */\n\t//pj_assert(!\"ioqueue: there is pending operation on this key!\");\n\treturn PJ_EBUSY;\n    }\n\n    write_op->op = PJ_IOQUEUE_OP_SEND;\n    write_op->buf = (char*)data;\n    write_op->size = *length;\n    write_op->written = 0;\n    write_op->flags = flags;\n    \n    pj_ioqueue_lock_key(key);\n    /* Check again. Handle may have been closed after the previous check\n     * in multithreaded app. If we add bad handle to the set it will\n     * corrupt the ioqueue set. See #913\n     */\n    if (IS_CLOSING(key)) {\n\tpj_ioqueue_unlock_key(key);\n\treturn PJ_ECANCELLED;\n    }\n    pj_list_insert_before(&key->write_list, write_op);\n    ioqueue_add_to_set(key->ioqueue, key, WRITEABLE_EVENT);\n    pj_ioqueue_unlock_key(key);\n\n    return PJ_EPENDING;\n}\n\n\n/*\n * pj_ioqueue_sendto()\n *\n * Start asynchronous write() to the descriptor.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key,\n                                       pj_ioqueue_op_key_t *op_key,\n\t\t\t               const void *data,\n\t\t\t               pj_ssize_t *length,\n                                       pj_uint32_t flags,\n\t\t\t               const pj_sockaddr_t *addr,\n\t\t\t               int addrlen)\n{\n    struct write_operation *write_op;\n    unsigned retry;\n    pj_bool_t restart_retry = PJ_FALSE;\n    pj_status_t status;\n    pj_ssize_t sent;\n\n    PJ_ASSERT_RETURN(key && op_key && data && length, PJ_EINVAL);\n    PJ_CHECK_STACK();\n\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n\t    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\nretry_on_restart:\n#else\n    PJ_UNUSED_ARG(restart_retry);\n#endif\n    /* Check if key is closing. */\n    if (IS_CLOSING(key))\n\treturn PJ_ECANCELLED;\n\n    /* We can not use PJ_IOQUEUE_ALWAYS_ASYNC for socket write */\n    flags &= ~(PJ_IOQUEUE_ALWAYS_ASYNC);\n\n    /* Fast track:\n     *   Try to send data immediately, only if there's no pending write!\n     * Note:\n     *  We are speculating that the list is empty here without properly\n     *  acquiring ioqueue's mutex first. This is intentional, to maximize\n     *  performance via parallelism.\n     *\n     *  This should be safe, because:\n     *      - by convention, we require caller to make sure that the\n     *        key is not unregistered while other threads are invoking\n     *        an operation on the same key.\n     *      - pj_list_empty() is safe to be invoked by multiple threads,\n     *        even when other threads are modifying the list.\n     */\n    if (pj_list_empty(&key->write_list)) {\n        /*\n         * See if data can be sent immediately.\n         */\n        sent = *length;\n        status = pj_sock_sendto(key->fd, data, &sent, flags, addr, addrlen);\n        if (status == PJ_SUCCESS) {\n            /* Success! */\n            *length = sent;\n            return PJ_SUCCESS;\n        } else {\n            /* If error is not EWOULDBLOCK (or EAGAIN on Linux), report\n             * the error to caller.\n             */\n            if (status != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL)) {\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n\t    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\n\t\t/* Special treatment for dead UDP sockets here, see ticket #1107 */\n\t\tif (status==PJ_STATUS_FROM_OS(EPIPE) && !IS_CLOSING(key) &&\n\t\t    key->fd_type==pj_SOCK_DGRAM() && !restart_retry)\n\t\t{\n\t\t    PJ_PERROR(4,(THIS_FILE, status,\n\t\t\t\t \"Send error for socket %d, retrying\",\n\t\t\t\t key->fd));\n\t\t    replace_udp_sock(key);\n\t\t    restart_retry = PJ_TRUE;\n\t\t    goto retry_on_restart;\n\t\t}\n#endif\n\n                return status;\n            }\n        }\n    }\n\n    /*\n     * Check that address storage can hold the address parameter.\n     */\n    PJ_ASSERT_RETURN(addrlen <= (int)sizeof(pj_sockaddr_in), PJ_EBUG);\n\n    /*\n     * Schedule asynchronous send.\n     */\n    write_op = (struct write_operation*)op_key;\n    \n    /* Spin if write_op has pending operation */\n    for (retry=0; write_op->op != 0 && retry<PENDING_RETRY; ++retry)\n\tpj_thread_sleep(0);\n\n    /* Last chance */\n    if (write_op->op) {\n\t/* Unable to send packet because there is already pending write on the\n\t * write_op. We could not put the operation into the write_op\n\t * because write_op already contains a pending operation! And\n\t * we could not send the packet directly with sendto() either,\n\t * because that will break the order of the packet. So we can\n\t * only return error here.\n\t *\n\t * This could happen for example in multithreads program,\n\t * where polling is done by one thread, while other threads are doing\n\t * the sending only. If the polling thread runs on lower priority\n\t * than the sending thread, then it's possible that the pending\n\t * write flag is not cleared in-time because clearing is only done\n\t * during polling. \n\t *\n\t * Aplication should specify multiple write operation keys on\n\t * situation like this.\n\t */\n\t//pj_assert(!\"ioqueue: there is pending operation on this key!\");\n\treturn PJ_EBUSY;\n    }\n\n    write_op->op = PJ_IOQUEUE_OP_SEND_TO;\n    write_op->buf = (char*)data;\n    write_op->size = *length;\n    write_op->written = 0;\n    write_op->flags = flags;\n    pj_memcpy(&write_op->rmt_addr, addr, addrlen);\n    write_op->rmt_addrlen = addrlen;\n    \n    pj_ioqueue_lock_key(key);\n    /* Check again. Handle may have been closed after the previous check\n     * in multithreaded app. If we add bad handle to the set it will\n     * corrupt the ioqueue set. See #913\n     */\n    if (IS_CLOSING(key)) {\n\tpj_ioqueue_unlock_key(key);\n\treturn PJ_ECANCELLED;\n    }\n    pj_list_insert_before(&key->write_list, write_op);\n    ioqueue_add_to_set(key->ioqueue, key, WRITEABLE_EVENT);\n    pj_ioqueue_unlock_key(key);\n\n    return PJ_EPENDING;\n}\n\n#if PJ_HAS_TCP\n/*\n * Initiate overlapped accept() operation.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key,\n                                       pj_ioqueue_op_key_t *op_key,\n\t\t\t               pj_sock_t *new_sock,\n\t\t\t               pj_sockaddr_t *local,\n\t\t\t               pj_sockaddr_t *remote,\n\t\t\t               int *addrlen)\n{\n    struct accept_operation *accept_op;\n    pj_status_t status;\n\n    /* check parameters. All must be specified! */\n    PJ_ASSERT_RETURN(key && op_key && new_sock, PJ_EINVAL);\n\n    /* Check if key is closing. */\n    if (IS_CLOSING(key))\n\treturn PJ_ECANCELLED;\n\n    accept_op = (struct accept_operation*)op_key;\n    accept_op->op = PJ_IOQUEUE_OP_NONE;\n\n    /* Fast track:\n     *  See if there's new connection available immediately.\n     */\n    if (pj_list_empty(&key->accept_list)) {\n        status = pj_sock_accept(key->fd, new_sock, remote, addrlen);\n        if (status == PJ_SUCCESS) {\n            /* Yes! New connection is available! */\n            if (local && addrlen) {\n                status = pj_sock_getsockname(*new_sock, local, addrlen);\n                if (status != PJ_SUCCESS) {\n                    pj_sock_close(*new_sock);\n                    *new_sock = PJ_INVALID_SOCKET;\n                    return status;\n                }\n            }\n            return PJ_SUCCESS;\n        } else {\n            /* If error is not EWOULDBLOCK (or EAGAIN on Linux), report\n             * the error to caller.\n             */\n            if (status != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL)) {\n                return status;\n            }\n        }\n    }\n\n    /*\n     * No connection is available immediately.\n     * Schedule accept() operation to be completed when there is incoming\n     * connection available.\n     */\n    accept_op->op = PJ_IOQUEUE_OP_ACCEPT;\n    accept_op->accept_fd = new_sock;\n    accept_op->rmt_addr = remote;\n    accept_op->addrlen= addrlen;\n    accept_op->local_addr = local;\n\n    pj_ioqueue_lock_key(key);\n    /* Check again. Handle may have been closed after the previous check\n     * in multithreaded app. If we add bad handle to the set it will\n     * corrupt the ioqueue set. See #913\n     */\n    if (IS_CLOSING(key)) {\n\tpj_ioqueue_unlock_key(key);\n\treturn PJ_ECANCELLED;\n    }\n    pj_list_insert_before(&key->accept_list, accept_op);\n    ioqueue_add_to_set(key->ioqueue, key, READABLE_EVENT);\n    pj_ioqueue_unlock_key(key);\n\n    return PJ_EPENDING;\n}\n\n/*\n * Initiate overlapped connect() operation (well, it's non-blocking actually,\n * since there's no overlapped version of connect()).\n */\nPJ_DEF(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key,\n\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\tint addrlen )\n{\n    pj_status_t status;\n    \n    /* check parameters. All must be specified! */\n    PJ_ASSERT_RETURN(key && addr && addrlen, PJ_EINVAL);\n\n    /* Check if key is closing. */\n    if (IS_CLOSING(key))\n\treturn PJ_ECANCELLED;\n\n    /* Check if socket has not been marked for connecting */\n    if (key->connecting != 0)\n        return PJ_EPENDING;\n    \n    status = pj_sock_connect(key->fd, addr, addrlen);\n    if (status == PJ_SUCCESS) {\n\t/* Connected! */\n\treturn PJ_SUCCESS;\n    } else {\n\tif (status == PJ_STATUS_FROM_OS(PJ_BLOCKING_CONNECT_ERROR_VAL)) {\n\t    /* Pending! */\n\t    pj_ioqueue_lock_key(key);\n\t    /* Check again. Handle may have been closed after the previous \n\t     * check in multithreaded app. See #913\n\t     */\n\t    if (IS_CLOSING(key)) {\n\t\tpj_ioqueue_unlock_key(key);\n\t\treturn PJ_ECANCELLED;\n\t    }\n\t    key->connecting = PJ_TRUE;\n            ioqueue_add_to_set(key->ioqueue, key, WRITEABLE_EVENT);\n            ioqueue_add_to_set(key->ioqueue, key, EXCEPTION_EVENT);\n            pj_ioqueue_unlock_key(key);\n\t    return PJ_EPENDING;\n\t} else {\n\t    /* Error! */\n\t    return status;\n\t}\n    }\n}\n#endif\t/* PJ_HAS_TCP */\n\n\nPJ_DEF(void) pj_ioqueue_op_key_init( pj_ioqueue_op_key_t *op_key,\n\t\t\t\t     pj_size_t size )\n{\n    pj_bzero(op_key, size);\n}\n\n\n/*\n * pj_ioqueue_is_pending()\n */\nPJ_DEF(pj_bool_t) pj_ioqueue_is_pending( pj_ioqueue_key_t *key,\n                                         pj_ioqueue_op_key_t *op_key )\n{\n    struct generic_operation *op_rec;\n\n    PJ_UNUSED_ARG(key);\n\n    op_rec = (struct generic_operation*)op_key;\n    return op_rec->op != 0;\n}\n\n\n/*\n * pj_ioqueue_post_completion()\n */\nPJ_DEF(pj_status_t) pj_ioqueue_post_completion( pj_ioqueue_key_t *key,\n                                                pj_ioqueue_op_key_t *op_key,\n                                                pj_ssize_t bytes_status )\n{\n    struct generic_operation *op_rec;\n\n    /*\n     * Find the operation key in all pending operation list to\n     * really make sure that it's still there; then call the callback.\n     */\n    pj_ioqueue_lock_key(key);\n\n    /* Find the operation in the pending read list. */\n    op_rec = (struct generic_operation*)key->read_list.next;\n    while (op_rec != (void*)&key->read_list) {\n        if (op_rec == (void*)op_key) {\n            pj_list_erase(op_rec);\n            op_rec->op = PJ_IOQUEUE_OP_NONE;\n            pj_ioqueue_unlock_key(key);\n\n            (*key->cb.on_read_complete)(key, op_key, bytes_status);\n            return PJ_SUCCESS;\n        }\n        op_rec = op_rec->next;\n    }\n\n    /* Find the operation in the pending write list. */\n    op_rec = (struct generic_operation*)key->write_list.next;\n    while (op_rec != (void*)&key->write_list) {\n        if (op_rec == (void*)op_key) {\n            pj_list_erase(op_rec);\n            op_rec->op = PJ_IOQUEUE_OP_NONE;\n            pj_ioqueue_unlock_key(key);\n\n            (*key->cb.on_write_complete)(key, op_key, bytes_status);\n            return PJ_SUCCESS;\n        }\n        op_rec = op_rec->next;\n    }\n\n    /* Find the operation in the pending accept list. */\n    op_rec = (struct generic_operation*)key->accept_list.next;\n    while (op_rec != (void*)&key->accept_list) {\n        if (op_rec == (void*)op_key) {\n            pj_list_erase(op_rec);\n            op_rec->op = PJ_IOQUEUE_OP_NONE;\n            pj_ioqueue_unlock_key(key);\n\n            (*key->cb.on_accept_complete)(key, op_key, \n                                          PJ_INVALID_SOCKET,\n                                          (pj_status_t)bytes_status);\n            return PJ_SUCCESS;\n        }\n        op_rec = op_rec->next;\n    }\n\n    pj_ioqueue_unlock_key(key);\n    \n    return PJ_EINVALIDOP;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_set_default_concurrency( pj_ioqueue_t *ioqueue,\n\t\t\t\t\t\t\tpj_bool_t allow)\n{\n    PJ_ASSERT_RETURN(ioqueue != NULL, PJ_EINVAL);\n    ioqueue->default_concurrency = allow;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_ioqueue_set_concurrency(pj_ioqueue_key_t *key,\n\t\t\t\t\t       pj_bool_t allow)\n{\n    PJ_ASSERT_RETURN(key, PJ_EINVAL);\n\n    /* PJ_IOQUEUE_HAS_SAFE_UNREG must be enabled if concurrency is\n     * disabled.\n     */\n    PJ_ASSERT_RETURN(allow || PJ_IOQUEUE_HAS_SAFE_UNREG, PJ_EINVAL);\n\n    key->allow_concurrent = allow;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_lock_key(pj_ioqueue_key_t *key)\n{\n    if (key->grp_lock)\n\treturn pj_grp_lock_acquire(key->grp_lock);\n    else\n\treturn pj_lock_acquire(key->lock);\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_trylock_key(pj_ioqueue_key_t *key)\n{\n    if (key->grp_lock)\n\treturn pj_grp_lock_tryacquire(key->grp_lock);\n    else\n\treturn pj_lock_tryacquire(key->lock);\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_unlock_key(pj_ioqueue_key_t *key)\n{\n    if (key->grp_lock)\n\treturn pj_grp_lock_release(key->grp_lock);\n    else\n\treturn pj_lock_release(key->lock);\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ioqueue_common_abs.h",
    "content": "/* $Id */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/* ioqueue_common_abs.h\n *\n * This file contains private declarations for abstracting various \n * event polling/dispatching mechanisms (e.g. select, poll, epoll) \n * to the ioqueue. \n */\n\n#include <pj/list.h>\n\n/*\n * The select ioqueue relies on socket functions (pj_sock_xxx()) to return\n * the correct error code.\n */\n#if PJ_RETURN_OS_ERROR(100) != PJ_STATUS_FROM_OS(100)\n#   error \"Proper error reporting must be enabled for ioqueue to work!\"\n#endif\n\n\nstruct generic_operation\n{\n    PJ_DECL_LIST_MEMBER(struct generic_operation);\n    pj_ioqueue_operation_e  op;\n};\n\nstruct read_operation\n{\n    PJ_DECL_LIST_MEMBER(struct read_operation);\n    pj_ioqueue_operation_e  op;\n\n    void\t\t   *buf;\n    pj_size_t\t\t    size;\n    unsigned                flags;\n    pj_sockaddr_t\t   *rmt_addr;\n    int\t\t\t   *rmt_addrlen;\n};\n\nstruct write_operation\n{\n    PJ_DECL_LIST_MEMBER(struct write_operation);\n    pj_ioqueue_operation_e  op;\n\n    char\t\t   *buf;\n    pj_size_t\t\t    size;\n    pj_ssize_t              written;\n    unsigned                flags;\n    pj_sockaddr_in\t    rmt_addr;\n    int\t\t\t    rmt_addrlen;\n};\n\nstruct accept_operation\n{\n    PJ_DECL_LIST_MEMBER(struct accept_operation);\n    pj_ioqueue_operation_e  op;\n\n    pj_sock_t              *accept_fd;\n    pj_sockaddr_t\t   *local_addr;\n    pj_sockaddr_t\t   *rmt_addr;\n    int\t\t\t   *addrlen;\n};\n\nunion operation_key\n{\n    struct generic_operation generic;\n    struct read_operation    read;\n    struct write_operation   write;\n#if PJ_HAS_TCP\n    struct accept_operation  accept;\n#endif\n};\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n#   define UNREG_FIELDS\t\t\t\\\n\tunsigned\t    ref_count;\t\\\n\tpj_bool_t\t    closing;\t\\\n\tpj_time_val\t    free_time;\t\\\n\t\n#else\n#   define UNREG_FIELDS\n#endif\n\n#define DECLARE_COMMON_KEY                          \\\n    PJ_DECL_LIST_MEMBER(struct pj_ioqueue_key_t);   \\\n    pj_ioqueue_t           *ioqueue;                \\\n    pj_grp_lock_t \t   *grp_lock;\t\t    \\\n    pj_lock_t              *lock;                   \\\n    pj_bool_t\t\t    inside_callback;\t    \\\n    pj_bool_t\t\t    destroy_requested;\t    \\\n    pj_bool_t\t\t    allow_concurrent;\t    \\\n    pj_sock_t\t\t    fd;                     \\\n    int                     fd_type;                \\\n    void\t\t   *user_data;              \\\n    pj_ioqueue_callback\t    cb;                     \\\n    int                     connecting;             \\\n    struct read_operation   read_list;              \\\n    struct write_operation  write_list;             \\\n    struct accept_operation accept_list;\t    \\\n    UNREG_FIELDS\n\n\n#define DECLARE_COMMON_IOQUEUE                      \\\n    pj_lock_t          *lock;                       \\\n    pj_bool_t           auto_delete_lock;\t    \\\n    pj_bool_t\t\tdefault_concurrency;\n\n\nenum ioqueue_event_type\n{\n    NO_EVENT,\n    READABLE_EVENT,\n    WRITEABLE_EVENT,\n    EXCEPTION_EVENT,\n};\n\nstatic void ioqueue_add_to_set( pj_ioqueue_t *ioqueue,\n                                pj_ioqueue_key_t *key,\n                                enum ioqueue_event_type event_type );\nstatic void ioqueue_remove_from_set( pj_ioqueue_t *ioqueue,\n                                     pj_ioqueue_key_t *key, \n                                     enum ioqueue_event_type event_type);\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ioqueue_dummy.c",
    "content": "/* $Id: ioqueue_dummy.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/ioqueue.h>\n#include <pj/os.h>\n#include <pj/log.h>\n#include <pj/list.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/assert.h>\n#include <pj/sock.h>\n#include <pj/errno.h>\n\n#define THIS_FILE   \"ioqueue\"\n\n#define PJ_IOQUEUE_IS_READ_OP(op)   \\\n\t((op & PJ_IOQUEUE_OP_READ)  || (op & PJ_IOQUEUE_OP_RECV_FROM))\n#define PJ_IOQUEUE_IS_WRITE_OP(op)  \\\n\t((op & PJ_IOQUEUE_OP_WRITE) || (op & PJ_IOQUEUE_OP_SEND_TO))\n\n\n#if PJ_HAS_TCP\n#  define PJ_IOQUEUE_IS_ACCEPT_OP(op)\t(op & PJ_IOQUEUE_OP_ACCEPT)\n#  define PJ_IOQUEUE_IS_CONNECT_OP(op)\t(op & PJ_IOQUEUE_OP_CONNECT)\n#else\n#  define PJ_IOQUEUE_IS_ACCEPT_OP(op)\t0\n#  define PJ_IOQUEUE_IS_CONNECT_OP(op)\t0\n#endif\n\n#if defined(PJ_DEBUG) && PJ_DEBUG != 0\n#  define VALIDATE_FD_SET\t\t1\n#else\n#  define VALIDATE_FD_SET\t\t0\n#endif\n\nstruct pj_ioqueue_key_t\n{\n    PJ_DECL_LIST_MEMBER(struct pj_ioqueue_key_t)\n    pj_sock_t\t\t    fd;\n    pj_ioqueue_operation_e  op;\n    void\t\t   *user_data;\n    pj_ioqueue_callback\t    cb;\n};\n\nstruct pj_ioqueue_t\n{\n};\n\nPJ_DEF(pj_status_t) pj_ioqueue_create( pj_pool_t *pool, \n\t\t\t\t       pj_size_t max_fd,\n\t\t\t\t       int max_threads,\n\t\t\t\t       pj_ioqueue_t **ptr_ioqueue)\n{\n    return PJ_ENOTSUP;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_destroy(pj_ioqueue_t *ioque)\n{\n    return PJ_ENOTSUP;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_set_lock( pj_ioqueue_t *ioque, \n\t\t\t\t\t pj_lock_t *lock,\n\t\t\t\t\t pj_bool_t auto_delete )\n{\n    return PJ_ENOTSUP;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,\n\t\t\t\t\t      pj_ioqueue_t *ioque,\n\t\t\t\t\t      pj_sock_t sock,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      const pj_ioqueue_callback *cb,\n\t\t\t\t\t      pj_ioqueue_key_t **ptr_key)\n{\n    return PJ_ENOTSUP;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_t *ioque,\n\t\t\t\t\t   pj_ioqueue_key_t *key)\n{\n    return PJ_ENOTSUP;\n}\n\nPJ_DEF(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key )\n{\n    return NULL;\n}\n\n\nPJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioque, const pj_time_val *timeout)\n{\n    return -1;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_read( pj_ioqueue_t *ioque,\n\t\t\t\t     pj_ioqueue_key_t *key,\n\t\t\t\t     void *buffer,\n\t\t\t\t     pj_size_t buflen)\n{\n    return -1;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_recv( pj_ioqueue_t *ioque,\n\t\t\t\t     pj_ioqueue_key_t *key,\n\t\t\t\t     void *buffer,\n\t\t\t\t     pj_size_t buflen,\n\t\t\t\t     unsigned flags)\n{\n    return -1;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_t *ioque,\n\t\t\t\t\t pj_ioqueue_key_t *key,\n\t\t\t\t\t void *buffer,\n\t\t\t\t\t pj_size_t buflen,\n\t\t\t\t\t unsigned flags,\n\t\t\t\t\t pj_sockaddr_t *addr,\n\t\t\t\t\t int *addrlen)\n{\n    return -1;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_write( pj_ioqueue_t *ioque,\n\t\t\t\t      pj_ioqueue_key_t *key,\n\t\t\t\t      const void *data,\n\t\t\t\t      pj_size_t datalen)\n{\n    return -1;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_send( pj_ioqueue_t *ioque,\n\t\t\t\t     pj_ioqueue_key_t *key,\n\t\t\t\t     const void *data,\n\t\t\t\t     pj_size_t datalen,\n\t\t\t\t     unsigned flags)\n{\n    return -1;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_t *ioque,\n\t\t\t\t       pj_ioqueue_key_t *key,\n\t\t\t\t       const void *data,\n\t\t\t\t       pj_size_t datalen,\n\t\t\t\t       unsigned flags,\n\t\t\t\t       const pj_sockaddr_t *addr,\n\t\t\t\t       int addrlen)\n{\n    return -1;\n}\n\n#if PJ_HAS_TCP\n/*\n * Initiate overlapped accept() operation.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_accept( pj_ioqueue_t *ioqueue,\n\t\t\t\t       pj_ioqueue_key_t *key,\n\t\t\t\t       pj_sock_t *new_sock,\n\t\t\t\t       pj_sockaddr_t *local,\n\t\t\t\t       pj_sockaddr_t *remote,\n\t\t\t\t      int *addrlen)\n{\n    return -1;\n}\n\n/*\n * Initiate overlapped connect() operation (well, it's non-blocking actually,\n * since there's no overlapped version of connect()).\n */\nPJ_DEF(pj_status_t) pj_ioqueue_connect( pj_ioqueue_t *ioqueue,\n\t\t\t\t\tpj_ioqueue_key_t *key,\n\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\tint addrlen )\n{\n    return -1;\n}\n#endif\t/* PJ_HAS_TCP */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ioqueue_epoll.c",
    "content": "/* $Id: ioqueue_epoll.c 4528 2013-05-30 07:01:11Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n/*\n * ioqueue_epoll.c\n *\n * This is the implementation of IOQueue framework using /dev/epoll\n * API in _both_ Linux user-mode and kernel-mode.\n */\n\n#include <pj/ioqueue.h>\n#include <pj/os.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/list.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/sock.h>\n#include <pj/compat/socket.h>\n#include <pj/rand.h>\n\n#if !defined(PJ_LINUX_KERNEL) || PJ_LINUX_KERNEL==0\n    /*\n     * Linux user mode\n     */\n#   include <sys/epoll.h>\n#   include <errno.h>\n#   include <unistd.h>\n\n#   define epoll_data\t\tdata.ptr\n#   define epoll_data_type\tvoid*\n#   define ioctl_val_type\tunsigned long\n#   define getsockopt_val_ptr\tint*\n#   define os_getsockopt\tgetsockopt\n#   define os_ioctl\t\tioctl\n#   define os_read\t\tread\n#   define os_close\t\tclose\n#   define os_epoll_create\tepoll_create\n#   define os_epoll_ctl\t\tepoll_ctl\n#   define os_epoll_wait\tepoll_wait\n#else\n    /*\n     * Linux kernel mode.\n     */\n#   include <linux/config.h>\n#   include <linux/version.h>\n#   if defined(MODVERSIONS)\n#\tinclude <linux/modversions.h>\n#   endif\n#   include <linux/kernel.h>\n#   include <linux/poll.h>\n#   include <linux/eventpoll.h>\n#   include <linux/syscalls.h>\n#   include <linux/errno.h>\n#   include <linux/unistd.h>\n#   include <asm/ioctls.h>\n    enum EPOLL_EVENTS\n    {\n\tEPOLLIN = 0x001,\n\tEPOLLOUT = 0x004,\n\tEPOLLERR = 0x008,\n    };\n#   define os_epoll_create\t\tsys_epoll_create\n    static int os_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)\n    {\n\tlong rc;\n\tmm_segment_t oldfs = get_fs();\n\tset_fs(KERNEL_DS);\n\trc = sys_epoll_ctl(epfd, op, fd, event);\n\tset_fs(oldfs);\n\tif (rc) {\n\t    errno = -rc;\n\t    return -1;\n\t} else {\n\t    return 0;\n\t}\n    }\n    static int os_epoll_wait(int epfd, struct epoll_event *events,\n\t\t\t  int maxevents, int timeout)\n    {\n\tint count;\n\tmm_segment_t oldfs = get_fs();\n\tset_fs(KERNEL_DS);\n\tcount = sys_epoll_wait(epfd, events, maxevents, timeout);\n\tset_fs(oldfs);\n\treturn count;\n    }\n#   define os_close\t\tsys_close\n#   define os_getsockopt\tpj_sock_getsockopt\n    static int os_read(int fd, void *buf, size_t len)\n    {\n\tlong rc;\n\tmm_segment_t oldfs = get_fs();\n\tset_fs(KERNEL_DS);\n\trc = sys_read(fd, buf, len);\n\tset_fs(oldfs);\n\tif (rc) {\n\t    errno = -rc;\n\t    return -1;\n\t} else {\n\t    return 0;\n\t}\n    }\n#   define socklen_t\t\tunsigned\n#   define ioctl_val_type\tunsigned long\n    int ioctl(int fd, int opt, ioctl_val_type value);\n    static int os_ioctl(int fd, int opt, ioctl_val_type value)\n    {\n\tint rc;\n        mm_segment_t oldfs = get_fs();\n\tset_fs(KERNEL_DS);\n\trc = ioctl(fd, opt, value);\n\tset_fs(oldfs);\n\tif (rc < 0) {\n\t    errno = -rc;\n\t    return rc;\n\t} else\n\t    return rc;\n    }\n#   define getsockopt_val_ptr\tchar*\n\n#   define epoll_data\t\tdata\n#   define epoll_data_type\t__u32\n#endif\n\n#define THIS_FILE   \"ioq_epoll\"\n\n//#define TRACE_(expr) PJ_LOG(3,expr)\n#define TRACE_(expr)\n\n/*\n * Include common ioqueue abstraction.\n */\n#include \"ioqueue_common_abs.h\"\n\n/*\n * This describes each key.\n */\nstruct pj_ioqueue_key_t\n{\n    DECLARE_COMMON_KEY\n};\n\nstruct queue\n{\n    pj_ioqueue_key_t\t    *key;\n    enum ioqueue_event_type  event_type;\n};\n\n/*\n * This describes the I/O queue.\n */\nstruct pj_ioqueue_t\n{\n    DECLARE_COMMON_IOQUEUE\n\n    unsigned\t\tmax, count;\n    //pj_ioqueue_key_t\thlist;\n    pj_ioqueue_key_t\tactive_list;    \n    int\t\t\tepfd;\n    //struct epoll_event *events;\n    //struct queue       *queue;\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    pj_mutex_t\t       *ref_cnt_mutex;\n    pj_ioqueue_key_t\tclosing_list;\n    pj_ioqueue_key_t\tfree_list;\n#endif\n};\n\n/* Include implementation for common abstraction after we declare\n * pj_ioqueue_key_t and pj_ioqueue_t.\n */\n#include \"ioqueue_common_abs.c\"\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n/* Scan closing keys to be put to free list again */\nstatic void scan_closing_keys(pj_ioqueue_t *ioqueue);\n#endif\n\n/*\n * pj_ioqueue_name()\n */\nPJ_DEF(const char*) pj_ioqueue_name(void)\n{\n#if defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL!=0\n\treturn \"epoll-kernel\";\n#else\n\treturn \"epoll\";\n#endif\n}\n\n/*\n * pj_ioqueue_create()\n *\n * Create select ioqueue.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_create( pj_pool_t *pool, \n                                       pj_size_t max_fd,\n                                       pj_ioqueue_t **p_ioqueue)\n{\n    pj_ioqueue_t *ioqueue;\n    pj_status_t rc;\n    pj_lock_t *lock;\n    int i;\n\n    /* Check that arguments are valid. */\n    PJ_ASSERT_RETURN(pool != NULL && p_ioqueue != NULL && \n                     max_fd > 0, PJ_EINVAL);\n\n    /* Check that size of pj_ioqueue_op_key_t is sufficient */\n    PJ_ASSERT_RETURN(sizeof(pj_ioqueue_op_key_t)-sizeof(void*) >=\n                     sizeof(union operation_key), PJ_EBUG);\n\n    ioqueue = pj_pool_alloc(pool, sizeof(pj_ioqueue_t));\n\n    ioqueue_init(ioqueue);\n\n    ioqueue->max = max_fd;\n    ioqueue->count = 0;\n    pj_list_init(&ioqueue->active_list);\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* When safe unregistration is used (the default), we pre-create\n     * all keys and put them in the free list.\n     */\n\n    /* Mutex to protect key's reference counter \n     * We don't want to use key's mutex or ioqueue's mutex because\n     * that would create deadlock situation in some cases.\n     */\n    rc = pj_mutex_create_simple(pool, NULL, &ioqueue->ref_cnt_mutex);\n    if (rc != PJ_SUCCESS)\n\treturn rc;\n\n\n    /* Init key list */\n    pj_list_init(&ioqueue->free_list);\n    pj_list_init(&ioqueue->closing_list);\n\n\n    /* Pre-create all keys according to max_fd */\n    for ( i=0; i<max_fd; ++i) {\n\tpj_ioqueue_key_t *key;\n\n\tkey = PJ_POOL_ALLOC_T(pool, pj_ioqueue_key_t);\n\tkey->ref_count = 0;\n\trc = pj_lock_create_recursive_mutex(pool, NULL, &key->lock);\n\tif (rc != PJ_SUCCESS) {\n\t    key = ioqueue->free_list.next;\n\t    while (key != &ioqueue->free_list) {\n\t\tpj_lock_destroy(key->lock);\n\t\tkey = key->next;\n\t    }\n\t    pj_mutex_destroy(ioqueue->ref_cnt_mutex);\n\t    return rc;\n\t}\n\n\tpj_list_push_back(&ioqueue->free_list, key);\n    }\n#endif\n\n    rc = pj_lock_create_simple_mutex(pool, \"ioq%p\", &lock);\n    if (rc != PJ_SUCCESS)\n\treturn rc;\n\n    rc = pj_ioqueue_set_lock(ioqueue, lock, PJ_TRUE);\n    if (rc != PJ_SUCCESS)\n        return rc;\n\n    ioqueue->epfd = os_epoll_create(max_fd);\n    if (ioqueue->epfd < 0) {\n\tioqueue_destroy(ioqueue);\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_os_error());\n    }\n    \n    /*ioqueue->events = pj_pool_calloc(pool, max_fd, sizeof(struct epoll_event));\n    PJ_ASSERT_RETURN(ioqueue->events != NULL, PJ_ENOMEM);\n\n    ioqueue->queue = pj_pool_calloc(pool, max_fd, sizeof(struct queue));\n    PJ_ASSERT_RETURN(ioqueue->queue != NULL, PJ_ENOMEM);\n   */\n    PJ_LOG(4, (\"pjlib\", \"epoll I/O Queue created (%p)\", ioqueue));\n\n    *p_ioqueue = ioqueue;\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_ioqueue_destroy()\n *\n * Destroy ioqueue.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_destroy(pj_ioqueue_t *ioqueue)\n{\n    pj_ioqueue_key_t *key;\n\n    PJ_ASSERT_RETURN(ioqueue, PJ_EINVAL);\n    PJ_ASSERT_RETURN(ioqueue->epfd > 0, PJ_EINVALIDOP);\n\n    pj_lock_acquire(ioqueue->lock);\n    os_close(ioqueue->epfd);\n    ioqueue->epfd = 0;\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Destroy reference counters */\n    key = ioqueue->active_list.next;\n    while (key != &ioqueue->active_list) {\n\tpj_lock_destroy(key->lock);\n\tkey = key->next;\n    }\n\n    key = ioqueue->closing_list.next;\n    while (key != &ioqueue->closing_list) {\n\tpj_lock_destroy(key->lock);\n\tkey = key->next;\n    }\n\n    key = ioqueue->free_list.next;\n    while (key != &ioqueue->free_list) {\n\tpj_lock_destroy(key->lock);\n\tkey = key->next;\n    }\n\n    pj_mutex_destroy(ioqueue->ref_cnt_mutex);\n#endif\n    return ioqueue_destroy(ioqueue);\n}\n\n/*\n * pj_ioqueue_register_sock()\n *\n * Register a socket to ioqueue.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_register_sock2(pj_pool_t *pool,\n\t\t\t\t\t      pj_ioqueue_t *ioqueue,\n\t\t\t\t\t      pj_sock_t sock,\n\t\t\t\t\t      pj_grp_lock_t *grp_lock,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      const pj_ioqueue_callback *cb,\n                                              pj_ioqueue_key_t **p_key)\n{\n    pj_ioqueue_key_t *key = NULL;\n    pj_uint32_t value;\n    struct epoll_event ev;\n    int status;\n    pj_status_t rc = PJ_SUCCESS;\n    \n    PJ_ASSERT_RETURN(pool && ioqueue && sock != PJ_INVALID_SOCKET &&\n                     cb && p_key, PJ_EINVAL);\n\n    pj_lock_acquire(ioqueue->lock);\n\n    if (ioqueue->count >= ioqueue->max) {\n        rc = PJ_ETOOMANY;\n\tTRACE_((THIS_FILE, \"pj_ioqueue_register_sock error: too many files\"));\n\tgoto on_return;\n    }\n\n    /* Set socket to nonblocking. */\n    value = 1;\n    if ((rc=os_ioctl(sock, FIONBIO, (ioctl_val_type)&value))) {\n\tTRACE_((THIS_FILE, \"pj_ioqueue_register_sock error: ioctl rc=%d\", \n                rc));\n        rc = pj_get_netos_error();\n\tgoto on_return;\n    }\n\n    /* If safe unregistration (PJ_IOQUEUE_HAS_SAFE_UNREG) is used, get\n     * the key from the free list. Otherwise allocate a new one. \n     */\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\n    /* Scan closing_keys first to let them come back to free_list */\n    scan_closing_keys(ioqueue);\n\n    pj_assert(!pj_list_empty(&ioqueue->free_list));\n    if (pj_list_empty(&ioqueue->free_list)) {\n\trc = PJ_ETOOMANY;\n\tgoto on_return;\n    }\n\n    key = ioqueue->free_list.next;\n    pj_list_erase(key);\n#else\n    /* Create key. */\n    key = (pj_ioqueue_key_t*)pj_pool_zalloc(pool, sizeof(pj_ioqueue_key_t));\n#endif\n\n    rc = ioqueue_init_key(pool, ioqueue, key, sock, grp_lock, user_data, cb);\n    if (rc != PJ_SUCCESS) {\n\tkey = NULL;\n\tgoto on_return;\n    }\n\n    /* Create key's mutex */\n /*   rc = pj_mutex_create_recursive(pool, NULL, &key->mutex);\n    if (rc != PJ_SUCCESS) {\n\tkey = NULL;\n\tgoto on_return;\n    }\n*/\n    /* os_epoll_ctl. */\n    ev.events = EPOLLIN | EPOLLERR;\n    ev.epoll_data = (epoll_data_type)key;\n    status = os_epoll_ctl(ioqueue->epfd, EPOLL_CTL_ADD, sock, &ev);\n    if (status < 0) {\n\trc = pj_get_os_error();\n\tpj_lock_destroy(key->lock);\n\tkey = NULL;\n\tTRACE_((THIS_FILE, \n                \"pj_ioqueue_register_sock error: os_epoll_ctl rc=%d\", \n                status));\n\tgoto on_return;\n    }\n    \n    /* Register */\n    pj_list_insert_before(&ioqueue->active_list, key);\n    ++ioqueue->count;\n\n    //TRACE_((THIS_FILE, \"socket registered, count=%d\", ioqueue->count));\n\non_return:\n    if (rc != PJ_SUCCESS) {\n\tif (key && key->grp_lock)\n\t    pj_grp_lock_dec_ref_dbg(key->grp_lock, \"ioqueue\", 0);\n    }\n    *p_key = key;\n    pj_lock_release(ioqueue->lock);\n    \n    return rc;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,\n\t\t\t\t\t      pj_ioqueue_t *ioqueue,\n\t\t\t\t\t      pj_sock_t sock,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      const pj_ioqueue_callback *cb,\n\t\t\t\t\t      pj_ioqueue_key_t **p_key)\n{\n    return pj_ioqueue_register_sock2(pool, ioqueue, sock, NULL, user_data,\n                                     cb, p_key);\n}\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n/* Increment key's reference counter */\nstatic void increment_counter(pj_ioqueue_key_t *key)\n{\n    pj_mutex_lock(key->ioqueue->ref_cnt_mutex);\n    ++key->ref_count;\n    pj_mutex_unlock(key->ioqueue->ref_cnt_mutex);\n}\n\n/* Decrement the key's reference counter, and when the counter reach zero,\n * destroy the key.\n *\n * Note: MUST NOT CALL THIS FUNCTION WHILE HOLDING ioqueue's LOCK.\n */\nstatic void decrement_counter(pj_ioqueue_key_t *key)\n{\n    pj_lock_acquire(key->ioqueue->lock);\n    pj_mutex_lock(key->ioqueue->ref_cnt_mutex);\n    --key->ref_count;\n    if (key->ref_count == 0) {\n\n\tpj_assert(key->closing == 1);\n\tpj_gettickcount(&key->free_time);\n\tkey->free_time.msec += PJ_IOQUEUE_KEY_FREE_DELAY;\n\tpj_time_val_normalize(&key->free_time);\n\n\tpj_list_erase(key);\n\tpj_list_push_back(&key->ioqueue->closing_list, key);\n\n    }\n    pj_mutex_unlock(key->ioqueue->ref_cnt_mutex);\n    pj_lock_release(key->ioqueue->lock);\n}\n#endif\n\n/*\n * pj_ioqueue_unregister()\n *\n * Unregister handle from ioqueue.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key)\n{\n    pj_ioqueue_t *ioqueue;\n    struct epoll_event ev;\n    int status;\n    \n    PJ_ASSERT_RETURN(key != NULL, PJ_EINVAL);\n\n    ioqueue = key->ioqueue;\n\n    /* Lock the key to make sure no callback is simultaneously modifying\n     * the key. We need to lock the key before ioqueue here to prevent\n     * deadlock.\n     */\n    pj_ioqueue_lock_key(key);\n\n    /* Also lock ioqueue */\n    pj_lock_acquire(ioqueue->lock);\n\n    pj_assert(ioqueue->count > 0);\n    --ioqueue->count;\n#if !PJ_IOQUEUE_HAS_SAFE_UNREG\n    pj_list_erase(key);\n#endif\n\n    ev.events = 0;\n    ev.epoll_data = (epoll_data_type)key;\n    status = os_epoll_ctl( ioqueue->epfd, EPOLL_CTL_DEL, key->fd, &ev);\n    if (status != 0) {\n\tpj_status_t rc = pj_get_os_error();\n\tpj_lock_release(ioqueue->lock);\n\treturn rc;\n    }\n\n    /* Destroy the key. */\n    pj_sock_close(key->fd);\n\n    pj_lock_release(ioqueue->lock);\n\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Mark key is closing. */\n    key->closing = 1;\n\n    /* Decrement counter. */\n    decrement_counter(key);\n\n    /* Done. */\n    if (key->grp_lock) {\n\t/* just dec_ref and unlock. we will set grp_lock to NULL\n\t * elsewhere */\n\tpj_grp_lock_t *grp_lock = key->grp_lock;\n\t// Don't set grp_lock to NULL otherwise the other thread\n\t// will crash. Just leave it as dangling pointer, but this\n\t// should be safe\n\t//key->grp_lock = NULL;\n\tpj_grp_lock_dec_ref_dbg(grp_lock, \"ioqueue\", 0);\n\tpj_grp_lock_release(grp_lock);\n    } else {\n\tpj_ioqueue_unlock_key(key);\n    }\n#else\n    if (key->grp_lock) {\n\t/* set grp_lock to NULL and unlock */\n\tpj_grp_lock_t *grp_lock = key->grp_lock;\n\t// Don't set grp_lock to NULL otherwise the other thread\n\t// will crash. Just leave it as dangling pointer, but this\n\t// should be safe\n\t//key->grp_lock = NULL;\n\tpj_grp_lock_dec_ref_dbg(grp_lock, \"ioqueue\", 0);\n\tpj_grp_lock_release(grp_lock);\n    } else {\n\tpj_ioqueue_unlock_key(key);\n    }\n\n    pj_lock_destroy(key->lock);\n#endif\n\n    return PJ_SUCCESS;\n}\n\n/* ioqueue_remove_from_set()\n * This function is called from ioqueue_dispatch_event() to instruct\n * the ioqueue to remove the specified descriptor from ioqueue's descriptor\n * set for the specified event.\n */\nstatic void ioqueue_remove_from_set( pj_ioqueue_t *ioqueue,\n                                     pj_ioqueue_key_t *key, \n                                     enum ioqueue_event_type event_type)\n{\n    if (event_type == WRITEABLE_EVENT) {\n\tstruct epoll_event ev;\n\n\tev.events = EPOLLIN | EPOLLERR;\n\tev.epoll_data = (epoll_data_type)key;\n\tos_epoll_ctl( ioqueue->epfd, EPOLL_CTL_MOD, key->fd, &ev);\n    }\t\n}\n\n/*\n * ioqueue_add_to_set()\n * This function is called from pj_ioqueue_recv(), pj_ioqueue_send() etc\n * to instruct the ioqueue to add the specified handle to ioqueue's descriptor\n * set for the specified event.\n */\nstatic void ioqueue_add_to_set( pj_ioqueue_t *ioqueue,\n                                pj_ioqueue_key_t *key,\n                                enum ioqueue_event_type event_type )\n{\n    if (event_type == WRITEABLE_EVENT) {\n\tstruct epoll_event ev;\n\n\tev.events = EPOLLIN | EPOLLOUT | EPOLLERR;\n\tev.epoll_data = (epoll_data_type)key;\n\tos_epoll_ctl( ioqueue->epfd, EPOLL_CTL_MOD, key->fd, &ev);\n    }\t\n}\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n/* Scan closing keys to be put to free list again */\nstatic void scan_closing_keys(pj_ioqueue_t *ioqueue)\n{\n    pj_time_val now;\n    pj_ioqueue_key_t *h;\n\n    pj_gettickcount(&now);\n    h = ioqueue->closing_list.next;\n    while (h != &ioqueue->closing_list) {\n\tpj_ioqueue_key_t *next = h->next;\n\n\tpj_assert(h->closing != 0);\n\n\tif (PJ_TIME_VAL_GTE(now, h->free_time)) {\n\t    pj_list_erase(h);\n\t    // Don't set grp_lock to NULL otherwise the other thread\n\t    // will crash. Just leave it as dangling pointer, but this\n\t    // should be safe\n\t    //h->grp_lock = NULL;\n\t    pj_list_push_back(&ioqueue->free_list, h);\n\t}\n\th = next;\n    }\n}\n#endif\n\n/*\n * pj_ioqueue_poll()\n *\n */\nPJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioqueue, const pj_time_val *timeout)\n{\n    int i, count, event_cnt, processed_cnt;\n    int msec;\n    //struct epoll_event *events = ioqueue->events;\n    //struct queue *queue = ioqueue->queue;\n    enum { MAX_EVENTS = PJ_IOQUEUE_MAX_CAND_EVENTS };\n    struct epoll_event events[MAX_EVENTS];\n    struct queue queue[MAX_EVENTS];\n    pj_timestamp t1, t2;\n    \n    PJ_CHECK_STACK();\n\n    msec = timeout ? PJ_TIME_VAL_MSEC(*timeout) : 9000;\n\n    TRACE_((THIS_FILE, \"start os_epoll_wait, msec=%d\", msec));\n    pj_get_timestamp(&t1);\n \n    //count = os_epoll_wait( ioqueue->epfd, events, ioqueue->max, msec);\n    count = os_epoll_wait( ioqueue->epfd, events, MAX_EVENTS, msec);\n    if (count == 0) {\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Check the closing keys only when there's no activity and when there are\n     * pending closing keys.\n     */\n    if (count == 0 && !pj_list_empty(&ioqueue->closing_list)) {\n\tpj_lock_acquire(ioqueue->lock);\n\tscan_closing_keys(ioqueue);\n\tpj_lock_release(ioqueue->lock);\n    }\n#endif\n\tTRACE_((THIS_FILE, \"os_epoll_wait timed out\"));\n\treturn count;\n    }\n    else if (count < 0) {\n\tTRACE_((THIS_FILE, \"os_epoll_wait error\"));\n\treturn -pj_get_netos_error();\n    }\n\n    pj_get_timestamp(&t2);\n    TRACE_((THIS_FILE, \"os_epoll_wait returns %d, time=%d usec\",\n\t\t       count, pj_elapsed_usec(&t1, &t2)));\n\n    /* Lock ioqueue. */\n    pj_lock_acquire(ioqueue->lock);\n\n    for (event_cnt=0, i=0; i<count; ++i) {\n\tpj_ioqueue_key_t *h = (pj_ioqueue_key_t*)(epoll_data_type)\n\t\t\t\tevents[i].epoll_data;\n\n\tTRACE_((THIS_FILE, \"event %d: events=%d\", i, events[i].events));\n\n\t/*\n\t * Check readability.\n\t */\n\tif ((events[i].events & EPOLLIN) && \n\t    (key_has_pending_read(h) || key_has_pending_accept(h)) && !IS_CLOSING(h) ) {\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\t    increment_counter(h);\n#endif\n\t    queue[event_cnt].key = h;\n\t    queue[event_cnt].event_type = READABLE_EVENT;\n\t    ++event_cnt;\n\t    continue;\n\t}\n\n\t/*\n\t * Check for writeability.\n\t */\n\tif ((events[i].events & EPOLLOUT) && key_has_pending_write(h) && !IS_CLOSING(h)) {\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\t    increment_counter(h);\n#endif\n\t    queue[event_cnt].key = h;\n\t    queue[event_cnt].event_type = WRITEABLE_EVENT;\n\t    ++event_cnt;\n\t    continue;\n\t}\n\n#if PJ_HAS_TCP\n\t/*\n\t * Check for completion of connect() operation.\n\t */\n\tif ((events[i].events & EPOLLOUT) && (h->connecting) && !IS_CLOSING(h)) {\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\t    increment_counter(h);\n#endif\n\t    queue[event_cnt].key = h;\n\t    queue[event_cnt].event_type = WRITEABLE_EVENT;\n\t    ++event_cnt;\n\t    continue;\n\t}\n#endif /* PJ_HAS_TCP */\n\n\t/*\n\t * Check for error condition.\n\t */\n\tif ((events[i].events & EPOLLERR) && !IS_CLOSING(h)) {\n\t    /*\n\t     * We need to handle this exception event.  If it's related to us\n\t     * connecting, report it as such.  If not, just report it as a\n\t     * read event and the higher layers will handle it.\n\t     */\n\t    if (h->connecting) {\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\t\tincrement_counter(h);\n#endif\n\t\tqueue[event_cnt].key = h;\n\t\tqueue[event_cnt].event_type = EXCEPTION_EVENT;\n\t\t++event_cnt;\n\t    } else if (key_has_pending_read(h) || key_has_pending_accept(h)) {\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\t\tincrement_counter(h);\n#endif\n\t\tqueue[event_cnt].key = h;\n\t\tqueue[event_cnt].event_type = READABLE_EVENT;\n\t\t++event_cnt;\n\t    }\n\t    continue;\n\t}\n    }\n    for (i=0; i<event_cnt; ++i) {\n\tif (queue[i].key->grp_lock)\n\t    pj_grp_lock_add_ref_dbg(queue[i].key->grp_lock, \"ioqueue\", 0);\n    }\n\n    PJ_RACE_ME(5);\n\n    pj_lock_release(ioqueue->lock);\n\n    PJ_RACE_ME(5);\n\n    processed_cnt = 0;\n\n    /* Now process the events. */\n    for (i=0; i<event_cnt; ++i) {\n\n\t/* Just do not exceed PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL */\n\tif (processed_cnt < PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL) {\n\t    switch (queue[i].event_type) {\n\t    case READABLE_EVENT:\n\t\tif (ioqueue_dispatch_read_event(ioqueue, queue[i].key))\n\t\t    ++processed_cnt;\n\t\tbreak;\n\t    case WRITEABLE_EVENT:\n\t\tif (ioqueue_dispatch_write_event(ioqueue, queue[i].key))\n\t\t    ++processed_cnt;\n\t\tbreak;\n\t    case EXCEPTION_EVENT:\n\t\tif (ioqueue_dispatch_exception_event(ioqueue, queue[i].key))\n\t\t    ++processed_cnt;\n\t\tbreak;\n\t    case NO_EVENT:\n\t\tpj_assert(!\"Invalid event!\");\n\t\tbreak;\n\t    }\n\t}\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\tdecrement_counter(queue[i].key);\n#endif\n\n\tif (queue[i].key->grp_lock)\n\t    pj_grp_lock_dec_ref_dbg(queue[i].key->grp_lock,\n\t                            \"ioqueue\", 0);\n    }\n\n    /* Special case:\n     * When epoll returns > 0 but no descriptors are actually set!\n     */\n    if (count > 0 && !event_cnt && msec > 0) {\n\tpj_thread_sleep(msec);\n    }\n\n    TRACE_((THIS_FILE, \"     poll: count=%d events=%d processed=%d\",\n\t\t       count, event_cnt, processed_cnt));\n\n    pj_get_timestamp(&t1);\n    TRACE_((THIS_FILE, \"ioqueue_poll() returns %d, time=%d usec\",\n\t\t       processed, pj_elapsed_usec(&t2, &t1)));\n\n    return processed_cnt;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ioqueue_linux_kernel.c",
    "content": "/* $Id: ioqueue_linux_kernel.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/ioqueue.h>\n#include <pj/os.h>\n#include <pj/log.h>\n#include <pj/list.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/assert.h>\n#include <pj/sock.h>\n\n#define THIS_FILE   \"ioqueue\"\n\n#define PJ_IOQUEUE_IS_READ_OP(op)   \\\n\t((op & PJ_IOQUEUE_OP_READ)  || (op & PJ_IOQUEUE_OP_RECV_FROM))\n#define PJ_IOQUEUE_IS_WRITE_OP(op)  \\\n\t((op & PJ_IOQUEUE_OP_WRITE) || (op & PJ_IOQUEUE_OP_SEND_TO))\n\n\n#if PJ_HAS_TCP\n#  define PJ_IOQUEUE_IS_ACCEPT_OP(op)\t(op & PJ_IOQUEUE_OP_ACCEPT)\n#  define PJ_IOQUEUE_IS_CONNECT_OP(op)\t(op & PJ_IOQUEUE_OP_CONNECT)\n#else\n#  define PJ_IOQUEUE_IS_ACCEPT_OP(op)\t0\n#  define PJ_IOQUEUE_IS_CONNECT_OP(op)\t0\n#endif\n\n#if defined(PJ_DEBUG) && PJ_DEBUG != 0\n#  define VALIDATE_FD_SET\t\t1\n#else\n#  define VALIDATE_FD_SET\t\t0\n#endif\n\nstruct pj_ioqueue_key_t\n{\n    PJ_DECL_LIST_MEMBER(struct pj_ioqueue_key_t)\n    pj_sock_t\t\t    fd;\n    pj_ioqueue_operation_e  op;\n    void\t\t   *user_data;\n    pj_ioqueue_callback\t    cb;\n};\n\nstruct pj_ioqueue_t\n{\n};\n\nPJ_DEF(pj_ioqueue_t*) pj_ioqueue_create(pj_pool_t *pool, pj_size_t max_fd)\n{\n    return NULL;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_destroy(pj_ioqueue_t *ioque)\n{\n    return 0;\n}\n\nPJ_DEF(pj_ioqueue_key_t*) pj_ioqueue_register( pj_pool_t *pool,\n\t\t\t\t\t       pj_ioqueue_t *ioque,\n\t\t\t\t\t       pj_oshandle_t sock,\n\t\t\t\t\t       void *user_data,\n\t\t\t\t\t       const pj_ioqueue_callback *cb)\n{\n    return NULL;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_t *ioque,\n\t\t\t\t\t   pj_ioqueue_key_t *key)\n{\n    return -1;\n}\n\nPJ_DEF(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key )\n{\n    return NULL;\n}\n\n\nPJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioque, const pj_time_val *timeout)\n{\n    return -1;\n}\n\nPJ_DEF(int) pj_ioqueue_read( pj_ioqueue_t *ioque,\n\t\t\t     pj_ioqueue_key_t *key,\n\t\t\t     void *buffer,\n\t\t\t     pj_size_t buflen)\n{\n    return -1;\n}\n\nPJ_DEF(int) pj_ioqueue_recvfrom( pj_ioqueue_t *ioque,\n\t\t\t\t pj_ioqueue_key_t *key,\n\t\t\t\t void *buffer,\n\t\t\t\t pj_size_t buflen,\n\t\t\t\t pj_sockaddr_t *addr,\n\t\t\t\t int *addrlen)\n{\n    return -1;\n}\n\nPJ_DEF(int) pj_ioqueue_write( pj_ioqueue_t *ioque,\n\t\t\t      pj_ioqueue_key_t *key,\n\t\t\t      const void *data,\n\t\t\t      pj_size_t datalen)\n{\n    return -1;\n}\n\nPJ_DEF(int) pj_ioqueue_sendto( pj_ioqueue_t *ioque,\n\t\t\t       pj_ioqueue_key_t *key,\n\t\t\t       const void *data,\n\t\t\t       pj_size_t datalen,\n\t\t\t       const pj_sockaddr_t *addr,\n\t\t\t       int addrlen)\n{\n    return -1;\n}\n\n#if PJ_HAS_TCP\n/*\n * Initiate overlapped accept() operation.\n */\nPJ_DEF(int) pj_ioqueue_accept( pj_ioqueue_t *ioqueue,\n\t\t\t       pj_ioqueue_key_t *key,\n\t\t\t       pj_sock_t *new_sock,\n\t\t\t       pj_sockaddr_t *local,\n\t\t\t       pj_sockaddr_t *remote,\n\t\t\t       int *addrlen)\n{\n    return -1;\n}\n\n/*\n * Initiate overlapped connect() operation (well, it's non-blocking actually,\n * since there's no overlapped version of connect()).\n */\nPJ_DEF(pj_status_t) pj_ioqueue_connect( pj_ioqueue_t *ioqueue,\n\t\t\t\t\tpj_ioqueue_key_t *key,\n\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\tint addrlen )\n{\n    return -1;\n}\n#endif\t/* PJ_HAS_TCP */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ioqueue_select.c",
    "content": "/* $Id: ioqueue_select.c 4514 2013-05-03 09:07:43Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * sock_select.c\n *\n * This is the implementation of IOQueue using pj_sock_select().\n * It runs anywhere where pj_sock_select() is available (currently\n * Win32, Linux, Linux kernel, etc.).\n */\n\n#include <pj/ioqueue.h>\n#include <pj/os.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/list.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/assert.h>\n#include <pj/sock.h>\n#include <pj/compat/socket.h>\n#include <pj/sock_select.h>\n#include <pj/sock_qos.h>\n#include <pj/errno.h>\n#include <pj/rand.h>\n\n/* Now that we have access to OS'es <sys/select>, lets check again that\n * PJ_IOQUEUE_MAX_HANDLES is not greater than FD_SETSIZE\n */\n#if PJ_IOQUEUE_MAX_HANDLES > FD_SETSIZE\n#   error \"PJ_IOQUEUE_MAX_HANDLES cannot be greater than FD_SETSIZE\"\n#endif\n\n\n/*\n * Include declaration from common abstraction.\n */\n#include \"ioqueue_common_abs.h\"\n\n/*\n * ISSUES with ioqueue_select()\n *\n * EAGAIN/EWOULDBLOCK error in recv():\n *  - when multiple threads are working with the ioqueue, application\n *    may receive EAGAIN or EWOULDBLOCK in the receive callback.\n *    This error happens because more than one thread is watching for\n *    the same descriptor set, so when all of them call recv() or recvfrom()\n *    simultaneously, only one will succeed and the rest will get the error.\n *\n */\n#define THIS_FILE   \"ioq_select\"\n\n/*\n * The select ioqueue relies on socket functions (pj_sock_xxx()) to return\n * the correct error code.\n */\n#if PJ_RETURN_OS_ERROR(100) != PJ_STATUS_FROM_OS(100)\n#   error \"Error reporting must be enabled for this function to work!\"\n#endif\n\n/*\n * During debugging build, VALIDATE_FD_SET is set.\n * This will check the validity of the fd_sets.\n */\n/*\n#if defined(PJ_DEBUG) && PJ_DEBUG != 0\n#  define VALIDATE_FD_SET\t\t1\n#else\n#  define VALIDATE_FD_SET\t\t0\n#endif\n*/\n#define VALIDATE_FD_SET     0\n\n#if 0\n#  define TRACE__(args)\tPJ_LOG(3,args)\n#else\n#  define TRACE__(args)\n#endif\n\n/*\n * This describes each key.\n */\nstruct pj_ioqueue_key_t\n{\n    DECLARE_COMMON_KEY\n};\n\n/*\n * This describes the I/O queue itself.\n */\nstruct pj_ioqueue_t\n{\n    DECLARE_COMMON_IOQUEUE\n\n    unsigned\t\tmax, count;\t/* Max and current key count\t    */\n    int\t\t\tnfds;\t\t/* The largest fd value (for select)*/\n    pj_ioqueue_key_t\tactive_list;\t/* List of active keys.\t\t    */\n    pj_fd_set_t\t\trfdset;\n    pj_fd_set_t\t\twfdset;\n#if PJ_HAS_TCP\n    pj_fd_set_t\t\txfdset;\n#endif\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    pj_mutex_t\t       *ref_cnt_mutex;\n    pj_ioqueue_key_t\tclosing_list;\n    pj_ioqueue_key_t\tfree_list;\n#endif\n};\n\n/* Proto */\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n\t    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\nstatic pj_status_t replace_udp_sock(pj_ioqueue_key_t *h);\n#endif\n\n/* Include implementation for common abstraction after we declare\n * pj_ioqueue_key_t and pj_ioqueue_t.\n */\n#include \"ioqueue_common_abs.c\"\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n/* Scan closing keys to be put to free list again */\nstatic void scan_closing_keys(pj_ioqueue_t *ioqueue);\n#endif\n\n/*\n * pj_ioqueue_name()\n */\nPJ_DEF(const char*) pj_ioqueue_name(void)\n{\n    return \"select\";\n}\n\n/* \n * Scan the socket descriptor sets for the largest descriptor.\n * This value is needed by select().\n */\n#if defined(PJ_SELECT_NEEDS_NFDS) && PJ_SELECT_NEEDS_NFDS!=0\nstatic void rescan_fdset(pj_ioqueue_t *ioqueue)\n{\n    pj_ioqueue_key_t *key = ioqueue->active_list.next;\n    int max = 0;\n\n    while (key != &ioqueue->active_list) {\n\tif (key->fd > max)\n\t    max = key->fd;\n\tkey = key->next;\n    }\n\n    ioqueue->nfds = max;\n}\n#else\nstatic void rescan_fdset(pj_ioqueue_t *ioqueue)\n{\n    ioqueue->nfds = FD_SETSIZE-1;\n}\n#endif\n\n\n/*\n * pj_ioqueue_create()\n *\n * Create select ioqueue.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_create( pj_pool_t *pool, \n                                       pj_size_t max_fd,\n                                       pj_ioqueue_t **p_ioqueue)\n{\n    pj_ioqueue_t *ioqueue;\n    pj_lock_t *lock;\n    unsigned i;\n    pj_status_t rc;\n\n    /* Check that arguments are valid. */\n    PJ_ASSERT_RETURN(pool != NULL && p_ioqueue != NULL && \n                     max_fd > 0 && max_fd <= PJ_IOQUEUE_MAX_HANDLES, \n                     PJ_EINVAL);\n\n    /* Check that size of pj_ioqueue_op_key_t is sufficient */\n    PJ_ASSERT_RETURN(sizeof(pj_ioqueue_op_key_t)-sizeof(void*) >=\n                     sizeof(union operation_key), PJ_EBUG);\n\n    /* Create and init common ioqueue stuffs */\n    ioqueue = PJ_POOL_ALLOC_T(pool, pj_ioqueue_t);\n    ioqueue_init(ioqueue);\n\n    ioqueue->max = (unsigned)max_fd;\n    ioqueue->count = 0;\n    PJ_FD_ZERO(&ioqueue->rfdset);\n    PJ_FD_ZERO(&ioqueue->wfdset);\n#if PJ_HAS_TCP\n    PJ_FD_ZERO(&ioqueue->xfdset);\n#endif\n    pj_list_init(&ioqueue->active_list);\n\n    rescan_fdset(ioqueue);\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* When safe unregistration is used (the default), we pre-create\n     * all keys and put them in the free list.\n     */\n\n    /* Mutex to protect key's reference counter \n     * We don't want to use key's mutex or ioqueue's mutex because\n     * that would create deadlock situation in some cases.\n     */\n    rc = pj_mutex_create_simple(pool, NULL, &ioqueue->ref_cnt_mutex);\n    if (rc != PJ_SUCCESS)\n\treturn rc;\n\n\n    /* Init key list */\n    pj_list_init(&ioqueue->free_list);\n    pj_list_init(&ioqueue->closing_list);\n\n\n    /* Pre-create all keys according to max_fd */\n    for (i=0; i<max_fd; ++i) {\n\tpj_ioqueue_key_t *key;\n\n\tkey = PJ_POOL_ALLOC_T(pool, pj_ioqueue_key_t);\n\tkey->ref_count = 0;\n\trc = pj_lock_create_recursive_mutex(pool, NULL, &key->lock);\n\tif (rc != PJ_SUCCESS) {\n\t    key = ioqueue->free_list.next;\n\t    while (key != &ioqueue->free_list) {\n\t\tpj_lock_destroy(key->lock);\n\t\tkey = key->next;\n\t    }\n\t    pj_mutex_destroy(ioqueue->ref_cnt_mutex);\n\t    return rc;\n\t}\n\n\tpj_list_push_back(&ioqueue->free_list, key);\n    }\n#endif\n\n    /* Create and init ioqueue mutex */\n    rc = pj_lock_create_simple_mutex(pool, \"ioq%p\", &lock);\n    if (rc != PJ_SUCCESS)\n\treturn rc;\n\n    rc = pj_ioqueue_set_lock(ioqueue, lock, PJ_TRUE);\n    if (rc != PJ_SUCCESS)\n        return rc;\n\n    PJ_LOG(4, (\"pjlib\", \"select() I/O Queue created (%p)\", ioqueue));\n\n    *p_ioqueue = ioqueue;\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_ioqueue_destroy()\n *\n * Destroy ioqueue.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_destroy(pj_ioqueue_t *ioqueue)\n{\n    pj_ioqueue_key_t *key;\n\n    PJ_ASSERT_RETURN(ioqueue, PJ_EINVAL);\n\n    pj_lock_acquire(ioqueue->lock);\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Destroy reference counters */\n    key = ioqueue->active_list.next;\n    while (key != &ioqueue->active_list) {\n\tpj_lock_destroy(key->lock);\n\tkey = key->next;\n    }\n\n    key = ioqueue->closing_list.next;\n    while (key != &ioqueue->closing_list) {\n\tpj_lock_destroy(key->lock);\n\tkey = key->next;\n    }\n\n    key = ioqueue->free_list.next;\n    while (key != &ioqueue->free_list) {\n\tpj_lock_destroy(key->lock);\n\tkey = key->next;\n    }\n\n    pj_mutex_destroy(ioqueue->ref_cnt_mutex);\n#endif\n\n    return ioqueue_destroy(ioqueue);\n}\n\n\n/*\n * pj_ioqueue_register_sock()\n *\n * Register socket handle to ioqueue.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_register_sock2(pj_pool_t *pool,\n\t\t\t\t\t      pj_ioqueue_t *ioqueue,\n\t\t\t\t\t      pj_sock_t sock,\n\t\t\t\t\t      pj_grp_lock_t *grp_lock,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      const pj_ioqueue_callback *cb,\n                                              pj_ioqueue_key_t **p_key)\n{\n    pj_ioqueue_key_t *key = NULL;\n#if defined(PJ_WIN32) && PJ_WIN32!=0 || \\\n    defined(PJ_WIN64) && PJ_WIN64 != 0 || \\\n    defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0\n    u_long value;\n#else\n    pj_uint32_t value;\n#endif\n    pj_status_t rc = PJ_SUCCESS;\n    \n    PJ_ASSERT_RETURN(pool && ioqueue && sock != PJ_INVALID_SOCKET &&\n                     cb && p_key, PJ_EINVAL);\n\n    /* On platforms with fd_set containing fd bitmap such as *nix family,\n     * avoid potential memory corruption caused by select() when given\n     * an fd that is higher than FD_SETSIZE.\n     */\n    if (sizeof(fd_set) < FD_SETSIZE && sock >= FD_SETSIZE) {\n\tPJ_LOG(4, (\"pjlib\", \"Failed to register socket to ioqueue because \"\n\t\t   \t    \"socket fd is too big (fd=%d/FD_SETSIZE=%d)\",\n\t\t   \t    sock, FD_SETSIZE));\n    \treturn PJ_ETOOBIG;\n    }\n\n    pj_lock_acquire(ioqueue->lock);\n\n    if (ioqueue->count >= ioqueue->max) {\n        rc = PJ_ETOOMANY;\n\tgoto on_return;\n    }\n\n    /* If safe unregistration (PJ_IOQUEUE_HAS_SAFE_UNREG) is used, get\n     * the key from the free list. Otherwise allocate a new one. \n     */\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\n    /* Scan closing_keys first to let them come back to free_list */\n    scan_closing_keys(ioqueue);\n\n    pj_assert(!pj_list_empty(&ioqueue->free_list));\n    if (pj_list_empty(&ioqueue->free_list)) {\n\trc = PJ_ETOOMANY;\n\tgoto on_return;\n    }\n\n    key = ioqueue->free_list.next;\n    pj_list_erase(key);\n#else\n    key = (pj_ioqueue_key_t*)pj_pool_zalloc(pool, sizeof(pj_ioqueue_key_t));\n#endif\n\n    rc = ioqueue_init_key(pool, ioqueue, key, sock, grp_lock, user_data, cb);\n    if (rc != PJ_SUCCESS) {\n\tkey = NULL;\n\tgoto on_return;\n    }\n\n    /* Set socket to nonblocking. */\n    value = 1;\n#if defined(PJ_WIN32) && PJ_WIN32!=0 || \\\n    defined(PJ_WIN64) && PJ_WIN64 != 0 || \\\n    defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0\n    if (ioctlsocket(sock, FIONBIO, &value)) {\n#else\n    if (ioctl(sock, FIONBIO, &value)) {\n#endif\n        rc = pj_get_netos_error();\n\tgoto on_return;\n    }\n\n\n    /* Put in active list. */\n    pj_list_insert_before(&ioqueue->active_list, key);\n    ++ioqueue->count;\n\n    /* Rescan fdset to get max descriptor */\n    rescan_fdset(ioqueue);\n\non_return:\n    /* On error, socket may be left in non-blocking mode. */\n    if (rc != PJ_SUCCESS) {\n\tif (key && key->grp_lock)\n\t    pj_grp_lock_dec_ref_dbg(key->grp_lock, \"ioqueue\", 0);\n    }\n    *p_key = key;\n    pj_lock_release(ioqueue->lock);\n    \n    return rc;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,\n\t\t\t\t\t      pj_ioqueue_t *ioqueue,\n\t\t\t\t\t      pj_sock_t sock,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      const pj_ioqueue_callback *cb,\n\t\t\t\t\t      pj_ioqueue_key_t **p_key)\n{\n    return pj_ioqueue_register_sock2(pool, ioqueue, sock, NULL, user_data,\n                                     cb, p_key);\n}\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n/* Increment key's reference counter */\nstatic void increment_counter(pj_ioqueue_key_t *key)\n{\n    pj_mutex_lock(key->ioqueue->ref_cnt_mutex);\n    ++key->ref_count;\n    pj_mutex_unlock(key->ioqueue->ref_cnt_mutex);\n}\n\n/* Decrement the key's reference counter, and when the counter reach zero,\n * destroy the key.\n *\n * Note: MUST NOT CALL THIS FUNCTION WHILE HOLDING ioqueue's LOCK.\n */\nstatic void decrement_counter(pj_ioqueue_key_t *key)\n{\n    pj_lock_acquire(key->ioqueue->lock);\n    pj_mutex_lock(key->ioqueue->ref_cnt_mutex);\n    --key->ref_count;\n    if (key->ref_count == 0) {\n\n\tpj_assert(key->closing == 1);\n\tpj_gettickcount(&key->free_time);\n\tkey->free_time.msec += PJ_IOQUEUE_KEY_FREE_DELAY;\n\tpj_time_val_normalize(&key->free_time);\n\n\tpj_list_erase(key);\n\tpj_list_push_back(&key->ioqueue->closing_list, key);\n\t/* Rescan fdset to get max descriptor */\n\trescan_fdset(key->ioqueue);\n    }\n    pj_mutex_unlock(key->ioqueue->ref_cnt_mutex);\n    pj_lock_release(key->ioqueue->lock);\n}\n#endif\n\n\n/*\n * pj_ioqueue_unregister()\n *\n * Unregister handle from ioqueue.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key)\n{\n    pj_ioqueue_t *ioqueue;\n\n    PJ_ASSERT_RETURN(key, PJ_EINVAL);\n\n    ioqueue = key->ioqueue;\n\n    /* Lock the key to make sure no callback is simultaneously modifying\n     * the key. We need to lock the key before ioqueue here to prevent\n     * deadlock.\n     */\n    pj_ioqueue_lock_key(key);\n\n    /* Also lock ioqueue */\n    pj_lock_acquire(ioqueue->lock);\n\n    pj_assert(ioqueue->count > 0);\n    --ioqueue->count;\n#if !PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Ticket #520, key will be erased more than once */\n    pj_list_erase(key);\n#endif\n    PJ_FD_CLR(key->fd, &ioqueue->rfdset);\n    PJ_FD_CLR(key->fd, &ioqueue->wfdset);\n#if PJ_HAS_TCP\n    PJ_FD_CLR(key->fd, &ioqueue->xfdset);\n#endif\n\n    /* Close socket. */\n    pj_sock_close(key->fd);\n\n    /* Clear callback */\n    key->cb.on_accept_complete = NULL;\n    key->cb.on_connect_complete = NULL;\n    key->cb.on_read_complete = NULL;\n    key->cb.on_write_complete = NULL;\n\n    /* Must release ioqueue lock first before decrementing counter, to\n     * prevent deadlock.\n     */\n    pj_lock_release(ioqueue->lock);\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Mark key is closing. */\n    key->closing = 1;\n\n    /* Decrement counter. */\n    decrement_counter(key);\n\n    /* Done. */\n    if (key->grp_lock) {\n\t/* just dec_ref and unlock. we will set grp_lock to NULL\n\t * elsewhere */\n\tpj_grp_lock_t *grp_lock = key->grp_lock;\n\t// Don't set grp_lock to NULL otherwise the other thread\n\t// will crash. Just leave it as dangling pointer, but this\n\t// should be safe\n\t//key->grp_lock = NULL;\n\tpj_grp_lock_dec_ref_dbg(grp_lock, \"ioqueue\", 0);\n\tpj_grp_lock_release(grp_lock);\n    } else {\n\tpj_ioqueue_unlock_key(key);\n    }\n#else\n    if (key->grp_lock) {\n\t/* set grp_lock to NULL and unlock */\n\tpj_grp_lock_t *grp_lock = key->grp_lock;\n\t// Don't set grp_lock to NULL otherwise the other thread\n\t// will crash. Just leave it as dangling pointer, but this\n\t// should be safe\n\t//key->grp_lock = NULL;\n\tpj_grp_lock_dec_ref_dbg(grp_lock, \"ioqueue\", 0);\n\tpj_grp_lock_release(grp_lock);\n    } else {\n\tpj_ioqueue_unlock_key(key);\n    }\n\n    pj_lock_destroy(key->lock);\n#endif\n\n    return PJ_SUCCESS;\n}\n\n\n/* This supposed to check whether the fd_set values are consistent\n * with the operation currently set in each key.\n */\n#if VALIDATE_FD_SET\nstatic void validate_sets(const pj_ioqueue_t *ioqueue,\n\t\t\t  const pj_fd_set_t *rfdset,\n\t\t\t  const pj_fd_set_t *wfdset,\n\t\t\t  const pj_fd_set_t *xfdset)\n{\n    pj_ioqueue_key_t *key;\n\n    /*\n     * This basicly would not work anymore.\n     * We need to lock key before performing the check, but we can't do\n     * so because we're holding ioqueue mutex. If we acquire key's mutex\n     * now, the will cause deadlock.\n     */\n    pj_assert(0);\n\n    key = ioqueue->active_list.next;\n    while (key != &ioqueue->active_list) {\n\tif (!pj_list_empty(&key->read_list)\n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0\n\t    || !pj_list_empty(&key->accept_list)\n#endif\n\t    ) \n\t{\n\t    pj_assert(PJ_FD_ISSET(key->fd, rfdset));\n\t} \n\telse {\n\t    pj_assert(PJ_FD_ISSET(key->fd, rfdset) == 0);\n\t}\n\tif (!pj_list_empty(&key->write_list)\n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0\n\t    || key->connecting\n#endif\n\t   )\n\t{\n\t    pj_assert(PJ_FD_ISSET(key->fd, wfdset));\n\t}\n\telse {\n\t    pj_assert(PJ_FD_ISSET(key->fd, wfdset) == 0);\n\t}\n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0\n\tif (key->connecting)\n\t{\n\t    pj_assert(PJ_FD_ISSET(key->fd, xfdset));\n\t}\n\telse {\n\t    pj_assert(PJ_FD_ISSET(key->fd, xfdset) == 0);\n\t}\n#endif /* PJ_HAS_TCP */\n\n\tkey = key->next;\n    }\n}\n#endif\t/* VALIDATE_FD_SET */\n\n\n/* ioqueue_remove_from_set()\n * This function is called from ioqueue_dispatch_event() to instruct\n * the ioqueue to remove the specified descriptor from ioqueue's descriptor\n * set for the specified event.\n */\nstatic void ioqueue_remove_from_set( pj_ioqueue_t *ioqueue,\n                                     pj_ioqueue_key_t *key, \n                                     enum ioqueue_event_type event_type)\n{\n    pj_lock_acquire(ioqueue->lock);\n\n    if (event_type == READABLE_EVENT)\n        PJ_FD_CLR((pj_sock_t)key->fd, &ioqueue->rfdset);\n    else if (event_type == WRITEABLE_EVENT)\n        PJ_FD_CLR((pj_sock_t)key->fd, &ioqueue->wfdset);\n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP!=0\n    else if (event_type == EXCEPTION_EVENT)\n        PJ_FD_CLR((pj_sock_t)key->fd, &ioqueue->xfdset);\n#endif\n    else\n        pj_assert(0);\n\n    pj_lock_release(ioqueue->lock);\n}\n\n/*\n * ioqueue_add_to_set()\n * This function is called from pj_ioqueue_recv(), pj_ioqueue_send() etc\n * to instruct the ioqueue to add the specified handle to ioqueue's descriptor\n * set for the specified event.\n */\nstatic void ioqueue_add_to_set( pj_ioqueue_t *ioqueue,\n                                pj_ioqueue_key_t *key,\n                                enum ioqueue_event_type event_type )\n{\n    pj_lock_acquire(ioqueue->lock);\n\n    if (event_type == READABLE_EVENT)\n        PJ_FD_SET((pj_sock_t)key->fd, &ioqueue->rfdset);\n    else if (event_type == WRITEABLE_EVENT)\n        PJ_FD_SET((pj_sock_t)key->fd, &ioqueue->wfdset);\n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP!=0\n    else if (event_type == EXCEPTION_EVENT)\n        PJ_FD_SET((pj_sock_t)key->fd, &ioqueue->xfdset);\n#endif\n    else\n        pj_assert(0);\n\n    pj_lock_release(ioqueue->lock);\n}\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n/* Scan closing keys to be put to free list again */\nstatic void scan_closing_keys(pj_ioqueue_t *ioqueue)\n{\n    pj_time_val now;\n    pj_ioqueue_key_t *h;\n\n    pj_gettickcount(&now);\n    h = ioqueue->closing_list.next;\n    while (h != &ioqueue->closing_list) {\n\tpj_ioqueue_key_t *next = h->next;\n\n\tpj_assert(h->closing != 0);\n\n\tif (PJ_TIME_VAL_GTE(now, h->free_time)) {\n\t    pj_list_erase(h);\n\t    // Don't set grp_lock to NULL otherwise the other thread\n\t    // will crash. Just leave it as dangling pointer, but this\n\t    // should be safe\n\t    //h->grp_lock = NULL;\n\t    pj_list_push_back(&ioqueue->free_list, h);\n\t}\n\th = next;\n    }\n}\n#endif\n\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\nstatic pj_status_t replace_udp_sock(pj_ioqueue_key_t *h)\n{\n    enum flags {\n\tHAS_PEER_ADDR = 1,\n\tHAS_QOS = 2\n    };\n    pj_sock_t old_sock, new_sock = PJ_INVALID_SOCKET;\n    pj_sockaddr local_addr, rem_addr;\n    int val, addr_len;\n    pj_fd_set_t *fds[3];\n    unsigned i, fds_cnt, flags=0;\n    pj_qos_params qos_params;\n    unsigned msec;\n    pj_status_t status;\n\n    pj_lock_acquire(h->ioqueue->lock);\n\n    old_sock = h->fd;\n\n    /* Can only replace UDP socket */\n    pj_assert(h->fd_type == pj_SOCK_DGRAM());\n\n    PJ_LOG(4,(THIS_FILE, \"Attempting to replace UDP socket %d\", old_sock));\n\n    /* Investigate the old socket */\n    addr_len = sizeof(local_addr);\n    status = pj_sock_getsockname(old_sock, &local_addr, &addr_len);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n    \n    addr_len = sizeof(rem_addr);\n    status = pj_sock_getpeername(old_sock, &rem_addr, &addr_len);\n    if (status == PJ_SUCCESS)\n\tflags |= HAS_PEER_ADDR;\n\n    status = pj_sock_get_qos_params(old_sock, &qos_params);\n    if (status == PJ_SUCCESS)\n\tflags |= HAS_QOS;\n\n    /* We're done with the old socket, close it otherwise we'll get\n     * error in bind()\n     */\n    pj_sock_close(old_sock);\n\n    /* Prepare the new socket */\n    status = pj_sock_socket(local_addr.addr.sa_family, PJ_SOCK_DGRAM, 0,\n\t\t\t    &new_sock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Even after the socket is closed, we'll still get \"Address in use\"\n     * errors, so force it with SO_REUSEADDR\n     */\n    val = 1;\n    status = pj_sock_setsockopt(new_sock, SOL_SOCKET, SO_REUSEADDR,\n\t\t\t\t&val, sizeof(val));\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* The loop is silly, but what else can we do? */\n    addr_len = pj_sockaddr_get_len(&local_addr);\n    for (msec=20; ; msec<1000? msec=msec*2 : 1000) {\n\tstatus = pj_sock_bind(new_sock, &local_addr, addr_len);\n\tif (status != PJ_STATUS_FROM_OS(EADDRINUSE))\n\t    break;\n\tPJ_LOG(4,(THIS_FILE, \"Address is still in use, retrying..\"));\n\tpj_thread_sleep(msec);\n    }\n\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    if (flags & HAS_QOS) {\n\tstatus = pj_sock_set_qos_params(new_sock, &qos_params);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n    }\n\n    if (flags & HAS_PEER_ADDR) {\n\tstatus = pj_sock_connect(new_sock, &rem_addr, addr_len);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n    }\n\n    /* Set socket to nonblocking. */\n    val = 1;\n#if defined(PJ_WIN32) && PJ_WIN32!=0 || \\\n    defined(PJ_WIN64) && PJ_WIN64 != 0 || \\\n    defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0\n    if (ioctlsocket(new_sock, FIONBIO, &val)) {\n#else\n    if (ioctl(new_sock, FIONBIO, &val)) {\n#endif\n        status = pj_get_netos_error();\n\tgoto on_error;\n    }\n\n    /* Replace the occurrence of old socket with new socket in the\n     * fd sets.\n     */\n    fds_cnt = 0;\n    fds[fds_cnt++] = &h->ioqueue->rfdset;\n    fds[fds_cnt++] = &h->ioqueue->wfdset;\n#if PJ_HAS_TCP\n    fds[fds_cnt++] = &h->ioqueue->xfdset;\n#endif\n\n    for (i=0; i<fds_cnt; ++i) {\n\tif (PJ_FD_ISSET(old_sock, fds[i])) {\n\t    PJ_FD_CLR(old_sock, fds[i]);\n\t    PJ_FD_SET(new_sock, fds[i]);\n\t}\n    }\n\n    /* And finally replace the fd in the key */\n    h->fd = new_sock;\n\n    PJ_LOG(4,(THIS_FILE, \"UDP has been replaced successfully!\"));\n\n    pj_lock_release(h->ioqueue->lock);\n\n    return PJ_SUCCESS;\n\non_error:\n    if (new_sock != PJ_INVALID_SOCKET)\n\tpj_sock_close(new_sock);\n    PJ_PERROR(1,(THIS_FILE, status, \"Error replacing socket\"));\n    pj_lock_release(h->ioqueue->lock);\n    return status;\n}\n#endif\n\n\n/*\n * pj_ioqueue_poll()\n *\n * Few things worth written:\n *\n *  - we used to do only one callback called per poll, but it didn't go\n *    very well. The reason is because on some situation, the write \n *    callback gets called all the time, thus doesn't give the read\n *    callback to get called. This happens, for example, when user\n *    submit write operation inside the write callback.\n *    As the result, we changed the behaviour so that now multiple\n *    callbacks are called in a single poll. It should be fast too,\n *    just that we need to be carefull with the ioqueue data structs.\n *\n *  - to guarantee preemptiveness etc, the poll function must strictly\n *    work on fd_set copy of the ioqueue (not the original one).\n */\nPJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioqueue, const pj_time_val *timeout)\n{\n    pj_fd_set_t rfdset, wfdset, xfdset;\n    int nfds;\n    int i, count, event_cnt, processed_cnt;\n    pj_ioqueue_key_t *h;\n    enum { MAX_EVENTS = PJ_IOQUEUE_MAX_CAND_EVENTS };\n    struct event\n    {\n        pj_ioqueue_key_t\t*key;\n        enum ioqueue_event_type  event_type;\n    } event[MAX_EVENTS];\n\n    PJ_ASSERT_RETURN(ioqueue, -PJ_EINVAL);\n\n    /* Lock ioqueue before making fd_set copies */\n    pj_lock_acquire(ioqueue->lock);\n\n    /* We will only do select() when there are sockets to be polled.\n     * Otherwise select() will return error.\n     */\n    if (PJ_FD_COUNT(&ioqueue->rfdset)==0 &&\n        PJ_FD_COUNT(&ioqueue->wfdset)==0 \n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP!=0\n        && PJ_FD_COUNT(&ioqueue->xfdset)==0\n#endif\n\t)\n    {\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\tscan_closing_keys(ioqueue);\n#endif\n\tpj_lock_release(ioqueue->lock);\n\tTRACE__((THIS_FILE, \"     poll: no fd is set\"));\n        if (timeout)\n            pj_thread_sleep(PJ_TIME_VAL_MSEC(*timeout));\n        return 0;\n    }\n\n    /* Copy ioqueue's pj_fd_set_t to local variables. */\n    pj_memcpy(&rfdset, &ioqueue->rfdset, sizeof(pj_fd_set_t));\n    pj_memcpy(&wfdset, &ioqueue->wfdset, sizeof(pj_fd_set_t));\n#if PJ_HAS_TCP\n    pj_memcpy(&xfdset, &ioqueue->xfdset, sizeof(pj_fd_set_t));\n#else\n    PJ_FD_ZERO(&xfdset);\n#endif\n\n#if VALIDATE_FD_SET\n    validate_sets(ioqueue, &rfdset, &wfdset, &xfdset);\n#endif\n\n    nfds = ioqueue->nfds;\n\n    /* Unlock ioqueue before select(). */\n    pj_lock_release(ioqueue->lock);\n\n    count = pj_sock_select(nfds+1, &rfdset, &wfdset, &xfdset, \n\t\t\t   timeout);\n    \n    if (count == 0)\n\treturn 0;\n    else if (count < 0)\n\treturn -pj_get_netos_error();\n\n    /* Scan descriptor sets for event and add the events in the event\n     * array to be processed later in this function. We do this so that\n     * events can be processed in parallel without holding ioqueue lock.\n     */\n    pj_lock_acquire(ioqueue->lock);\n\n    event_cnt = 0;\n\n    /* Scan for writable sockets first to handle piggy-back data\n     * coming with accept().\n     */\n    for (h = ioqueue->active_list.next;\n\t h != &ioqueue->active_list && event_cnt < MAX_EVENTS;\n\t h = h->next)\n    {\n\n\tif ( (key_has_pending_write(h) || key_has_pending_connect(h))\n\t     && PJ_FD_ISSET(h->fd, &wfdset) && !IS_CLOSING(h))\n        {\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\t    increment_counter(h);\n#endif\n            event[event_cnt].key = h;\n            event[event_cnt].event_type = WRITEABLE_EVENT;\n            ++event_cnt;\n        }\n\n        /* Scan for readable socket. */\n\tif ((key_has_pending_read(h) || key_has_pending_accept(h))\n            && PJ_FD_ISSET(h->fd, &rfdset) && !IS_CLOSING(h) &&\n\t    event_cnt < MAX_EVENTS)\n        {\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\t    increment_counter(h);\n#endif\n            event[event_cnt].key = h;\n            event[event_cnt].event_type = READABLE_EVENT;\n            ++event_cnt;\n\t}\n\n#if PJ_HAS_TCP\n        if (key_has_pending_connect(h) && PJ_FD_ISSET(h->fd, &xfdset) &&\n\t    !IS_CLOSING(h) && event_cnt < MAX_EVENTS)\n\t{\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\t    increment_counter(h);\n#endif\n            event[event_cnt].key = h;\n            event[event_cnt].event_type = EXCEPTION_EVENT;\n            ++event_cnt;\n        }\n#endif\n    }\n\n    for (i=0; i<event_cnt; ++i) {\n\tif (event[i].key->grp_lock)\n\t    pj_grp_lock_add_ref_dbg(event[i].key->grp_lock, \"ioqueue\", 0);\n    }\n\n    PJ_RACE_ME(5);\n\n    pj_lock_release(ioqueue->lock);\n\n    PJ_RACE_ME(5);\n\n    processed_cnt = 0;\n\n    /* Now process all events. The dispatch functions will take care\n     * of locking in each of the key\n     */\n    for (i=0; i<event_cnt; ++i) {\n\n\t/* Just do not exceed PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL */\n\tif (processed_cnt < PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL) {\n\t    switch (event[i].event_type) {\n\t    case READABLE_EVENT:\n\t\tif (ioqueue_dispatch_read_event(ioqueue, event[i].key))\n\t\t    ++processed_cnt;\n\t\tbreak;\n\t    case WRITEABLE_EVENT:\n\t\tif (ioqueue_dispatch_write_event(ioqueue, event[i].key))\n\t\t    ++processed_cnt;\n\t\tbreak;\n\t    case EXCEPTION_EVENT:\n\t\tif (ioqueue_dispatch_exception_event(ioqueue, event[i].key))\n\t\t    ++processed_cnt;\n\t\tbreak;\n\t    case NO_EVENT:\n\t\tpj_assert(!\"Invalid event!\");\n\t\tbreak;\n\t    }\n\t}\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\tdecrement_counter(event[i].key);\n#endif\n\n\tif (event[i].key->grp_lock)\n\t    pj_grp_lock_dec_ref_dbg(event[i].key->grp_lock,\n\t                            \"ioqueue\", 0);\n    }\n\n    TRACE__((THIS_FILE, \"     poll: count=%d events=%d processed=%d\",\n\t     count, event_cnt, processed_cnt));\n\n    return processed_cnt;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ioqueue_symbian.cpp",
    "content": "/* $Id: ioqueue_symbian.cpp 4374 2013-02-27 07:15:57Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/ioqueue.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/list.h>\n#include <pj/lock.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#include \"os_symbian.h\"\n\nclass CIoqueueCallback;\n\n/*\n * IO Queue structure.\n */\nstruct pj_ioqueue_t\n{\n    int\t\t     eventCount;\n};\n\n\n/////////////////////////////////////////////////////////////////////////////\n// Class to encapsulate asynchronous socket operation.\n//\nclass CIoqueueCallback : public CActive\n{\npublic:\n    static CIoqueueCallback* NewL(pj_ioqueue_t *ioqueue,\n\t\t\t\t  pj_ioqueue_key_t *key, \n\t\t\t\t  pj_sock_t sock, \n\t\t\t\t  const pj_ioqueue_callback *cb, \n\t\t\t\t  void *user_data);\n\n    //\n    // Start asynchronous recv() operation\n    //\n    pj_status_t StartRead(pj_ioqueue_op_key_t *op_key, \n\t\t\t  void *buf, pj_ssize_t *size, unsigned flags,\n\t\t\t  pj_sockaddr_t *addr, int *addrlen);\n\n    //\n    // Start asynchronous accept() operation.\n    //\n    pj_status_t StartAccept(pj_ioqueue_op_key_t *op_key,\n\t\t\t    pj_sock_t *new_sock,\n\t\t\t    pj_sockaddr_t *local,\n\t\t\t    pj_sockaddr_t *remote,\n\t\t\t    int *addrlen );\n\n    //\n    // Completion callback.\n    //\n    void RunL();\n\n    //\n    // CActive's DoCancel()\n    //\n    void DoCancel();\n\n    //\n    // Cancel operation and call callback.\n    //\n    void CancelOperation(pj_ioqueue_op_key_t *op_key, \n\t\t\t pj_ssize_t bytes_status);\n\n    //\n    // Accessors\n    //\n    void* get_user_data() const\n    {\n\treturn user_data_;\n    }\n    void set_user_data(void *user_data)\n    {\n\tuser_data_ = user_data;\n    }\n    pj_ioqueue_op_key_t *get_op_key() const\n    {\n\treturn pending_data_.common_.op_key_;\n    }\n    CPjSocket* get_pj_socket()\n    {\n\treturn sock_;\n    }\n\nprivate:\n    // Type of pending operation.\n    enum Type {\n\tTYPE_NONE,\n\tTYPE_READ,\n\tTYPE_ACCEPT,\n    };\n\n    // Static data.\n    pj_ioqueue_t\t\t*ioqueue_;\n    pj_ioqueue_key_t\t\t*key_;\n    CPjSocket\t\t\t*sock_;\n    pj_ioqueue_callback\t\t cb_;\n    void\t\t\t*user_data_;\n\n    // Symbian data.\n    TPtr8\t\t\t aBufferPtr_;\n    TInetAddr\t\t\t aAddress_;\n\n    // Application data.\n    Type\t\t\t type_;\n\n    union Pending_Data\n    {\n\tstruct Common\n\t{\n\t    pj_ioqueue_op_key_t\t*op_key_;\n\t} common_;\n\n\tstruct Pending_Read\n\t{\n\t    pj_ioqueue_op_key_t\t*op_key_;\n\t    pj_sockaddr_t\t*addr_;\n\t    int\t\t\t*addrlen_;\n\t} read_;\n\n\tstruct Pending_Accept\n\t{\n\t    pj_ioqueue_op_key_t *op_key_;\n\t    pj_sock_t\t\t*new_sock_;\n\t    pj_sockaddr_t\t*local_;\n\t    pj_sockaddr_t\t*remote_;\n\t    int\t\t\t*addrlen_;\n\t} accept_;\n    };\n\n    union Pending_Data\t\t pending_data_;\n    RSocket\t\t\tblank_sock_;\n\n    CIoqueueCallback(pj_ioqueue_t *ioqueue,\n\t\t     pj_ioqueue_key_t *key, pj_sock_t sock, \n\t\t     const pj_ioqueue_callback *cb, void *user_data)\n    : CActive(CActive::EPriorityStandard),\n\t  ioqueue_(ioqueue), key_(key), sock_((CPjSocket*)sock), \n\t  user_data_(user_data), aBufferPtr_(NULL, 0), type_(TYPE_NONE)\n    {\n    \tpj_memcpy(&cb_, cb, sizeof(*cb));\n    }\n\n\n    void ConstructL()\n    {\n\tCActiveScheduler::Add(this);\n    }\n    \n    void HandleReadCompletion();\n    CPjSocket *HandleAcceptCompletion();\n};\n\n\nCIoqueueCallback* CIoqueueCallback::NewL(pj_ioqueue_t *ioqueue,\n\t\t\t\t\t pj_ioqueue_key_t *key, \n\t\t\t\t\t pj_sock_t sock, \n\t\t\t\t\t const pj_ioqueue_callback *cb, \n\t\t\t\t\t void *user_data)\n{\n    CIoqueueCallback *self = new CIoqueueCallback(ioqueue, key, sock, \n\t\t\t\t\t\t  cb, user_data);\n    CleanupStack::PushL(self);\n    self->ConstructL();\n    CleanupStack::Pop(self);\n\n    return self;\n}\n\n\n//\n// Start asynchronous recv() operation\n//\npj_status_t CIoqueueCallback::StartRead(pj_ioqueue_op_key_t *op_key, \n\t\t\t\t\tvoid *buf, pj_ssize_t *size, \n\t\t\t\t\tunsigned flags,\n\t\t\t\t\tpj_sockaddr_t *addr, int *addrlen)\n{\n    PJ_ASSERT_RETURN(IsActive()==false, PJ_EBUSY);\n    PJ_ASSERT_RETURN(pending_data_.common_.op_key_==NULL, PJ_EBUSY);\n\n    flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC;\n\n    pending_data_.read_.op_key_ = op_key;\n    pending_data_.read_.addr_ = addr;\n    pending_data_.read_.addrlen_ = addrlen;\n\n    aBufferPtr_.Set((TUint8*)buf, 0, (TInt)*size);\n\n    type_ = TYPE_READ;\n    if (addr && addrlen) {\n\tsock_->Socket().RecvFrom(aBufferPtr_, aAddress_, flags, iStatus);\n    } else {\n\taAddress_.SetAddress(0);\n\taAddress_.SetPort(0);\n\n\tif (sock_->IsDatagram()) {\n\t    sock_->Socket().Recv(aBufferPtr_, flags, iStatus);\n\t} else {\n\t    // Using static like this is not pretty, but we don't need to use\n\t    // the value anyway, hence doing it like this is probably most\n\t    // optimal.\n\t    static TSockXfrLength len;\n\t    sock_->Socket().RecvOneOrMore(aBufferPtr_, flags, iStatus, len);\n\t}\n    }\n\n    SetActive();\n    return PJ_EPENDING;\n}\n\n\n//\n// Start asynchronous accept() operation.\n//\npj_status_t CIoqueueCallback::StartAccept(pj_ioqueue_op_key_t *op_key,\n\t\t\t\t\t  pj_sock_t *new_sock,\n\t\t\t\t\t  pj_sockaddr_t *local,\n\t\t\t\t\t  pj_sockaddr_t *remote,\n\t\t\t\t\t  int *addrlen )\n{\n    PJ_ASSERT_RETURN(IsActive()==false, PJ_EBUSY);\n    PJ_ASSERT_RETURN(pending_data_.common_.op_key_==NULL, PJ_EBUSY);\n\n    // addrlen must be specified if local or remote is specified\n    PJ_ASSERT_RETURN((!local && !remote) ||\n    \t\t     (addrlen && *addrlen), PJ_EINVAL);\n    \n    pending_data_.accept_.op_key_ = op_key;\n    pending_data_.accept_.new_sock_ = new_sock;\n    pending_data_.accept_.local_ = local;\n    pending_data_.accept_.remote_ = remote;\n    pending_data_.accept_.addrlen_ = addrlen;\n\n    // Create blank socket\n    blank_sock_.Open(PjSymbianOS::Instance()->SocketServ());\n\n    type_ = TYPE_ACCEPT;\n    sock_->Socket().Accept(blank_sock_, iStatus);\n\n    SetActive();\n    return PJ_EPENDING;\n}\n\n\n//\n// Handle asynchronous RecvFrom() completion\n//\nvoid CIoqueueCallback::HandleReadCompletion() \n{\n    if (pending_data_.read_.addr_ && pending_data_.read_.addrlen_) {\n\tPjSymbianOS::Addr2pj(aAddress_, \n\t\t\t     *(pj_sockaddr*)pending_data_.read_.addr_,\n\t\t\t     pending_data_.read_.addrlen_);\n\tpending_data_.read_.addr_ = NULL;\n\tpending_data_.read_.addrlen_ = NULL;\n    }\n\t\n    pending_data_.read_.op_key_ = NULL;\n}\n\n\n//\n// Handle asynchronous Accept() completion.\n//\nCPjSocket *CIoqueueCallback::HandleAcceptCompletion() \n{\n\tCPjSocket *pjNewSock = new CPjSocket(get_pj_socket()->GetAf(), \n\t\t\t\t\t     get_pj_socket()->GetSockType(),\n\t\t\t\t\t     blank_sock_);\n\tint addrlen = 0;\n\t\n\tif (pending_data_.accept_.new_sock_) {\n\t    *pending_data_.accept_.new_sock_ = (pj_sock_t)pjNewSock;\n\t    pending_data_.accept_.new_sock_ = NULL;\n\t}\n\n\tif (pending_data_.accept_.local_) {\n\t    TInetAddr aAddr;\n\t    pj_sockaddr *ptr_sockaddr;\n\t    \n\t    blank_sock_.LocalName(aAddr);\n\t    ptr_sockaddr = (pj_sockaddr*)pending_data_.accept_.local_;\n\t    addrlen = *pending_data_.accept_.addrlen_;\n\t    PjSymbianOS::Addr2pj(aAddr, *ptr_sockaddr, &addrlen);\n\t    pending_data_.accept_.local_ = NULL;\n\t}\n\n\tif (pending_data_.accept_.remote_) {\n\t    TInetAddr aAddr;\n\t    pj_sockaddr *ptr_sockaddr;\n\n\t    blank_sock_.RemoteName(aAddr);\n\t    ptr_sockaddr = (pj_sockaddr*)pending_data_.accept_.remote_;\n\t    addrlen = *pending_data_.accept_.addrlen_;\n\t    PjSymbianOS::Addr2pj(aAddr, *ptr_sockaddr, &addrlen);\n\t    pending_data_.accept_.remote_ = NULL;\n\t}\n\n\tif (pending_data_.accept_.addrlen_) {\n\t    if (addrlen == 0) {\n\t    \tif (pjNewSock->GetAf() == PJ_AF_INET)\n\t    \t    addrlen = sizeof(pj_sockaddr_in);\n\t    \telse if (pjNewSock->GetAf() == PJ_AF_INET6)\n\t    \t    addrlen = sizeof(pj_sockaddr_in6);\n\t    \telse {\n\t    \t    pj_assert(!\"Unsupported address family\");\n\t    \t}\n\t    }\n\t    *pending_data_.accept_.addrlen_ = addrlen;\n\t    pending_data_.accept_.addrlen_ = NULL;\n\t}\n\t\n\treturn pjNewSock;\n}\n\n\n//\n// Completion callback.\n//\nvoid CIoqueueCallback::RunL()\n{\n    pj_ioqueue_t *ioq = ioqueue_;\n    Type cur_type = type_;\n\n    type_ = TYPE_NONE;\n\n    if (cur_type == TYPE_READ) {\n\t//\n\t// Completion of asynchronous RecvFrom()\n\t//\n\n\t/* Clear op_key (save it to temp variable first!) */\n\tpj_ioqueue_op_key_t\t*op_key = pending_data_.read_.op_key_;\n\tpending_data_.read_.op_key_ = NULL;\n\n\t// Handle failure condition\n\tif (iStatus != KErrNone) {\n\t    if (cb_.on_read_complete) {\n\t    \tcb_.on_read_complete( key_, op_key, \n\t\t\t\t      -PJ_RETURN_OS_ERROR(iStatus.Int()));\n\t    }\n\t    return;\n\t}\n\n\tHandleReadCompletion();\n\n\t/* Call callback */\n\tif (cb_.on_read_complete) {\n\t    cb_.on_read_complete(key_, op_key, aBufferPtr_.Length());\n\t}\n\n    } else if (cur_type == TYPE_ACCEPT) {\n\t//\n\t// Completion of asynchronous Accept()\n\t//\n\t\n\t/* Clear op_key (save it to temp variable first!) */\n\tpj_ioqueue_op_key_t\t*op_key = pending_data_.read_.op_key_;\n\tpending_data_.read_.op_key_ = NULL;\n\n\t// Handle failure condition\n\tif (iStatus != KErrNone) {\n\t    if (pending_data_.accept_.new_sock_)\n\t\t*pending_data_.accept_.new_sock_ = PJ_INVALID_SOCKET;\n\t    \n\t    if (cb_.on_accept_complete) {\n\t    \tcb_.on_accept_complete( key_, op_key, PJ_INVALID_SOCKET,\n\t\t\t\t        -PJ_RETURN_OS_ERROR(iStatus.Int()));\n\t    }\n\t    return;\n\t}\n\n\tCPjSocket *pjNewSock = HandleAcceptCompletion();\n\t\n\t// Call callback.\n\tif (cb_.on_accept_complete) {\n\t    cb_.on_accept_complete( key_, op_key, (pj_sock_t)pjNewSock, \n\t\t\t\t    PJ_SUCCESS);\n\t}\n    }\n\n    ioq->eventCount++;\n}\n\n//\n// CActive's DoCancel()\n//\nvoid CIoqueueCallback::DoCancel()\n{\n    if (type_ == TYPE_READ)\n\tsock_->Socket().CancelRecv();\n    else if (type_ == TYPE_ACCEPT)\n\tsock_->Socket().CancelAccept();\n\n    type_ = TYPE_NONE;\n    pending_data_.common_.op_key_ = NULL;\n}\n\n//\n// Cancel operation and call callback.\n//\nvoid CIoqueueCallback::CancelOperation(pj_ioqueue_op_key_t *op_key, \n\t\t\t\t       pj_ssize_t bytes_status)\n{\n    Type cur_type = type_;\n\n    pj_assert(op_key == pending_data_.common_.op_key_);\n\n    Cancel();\n\n    if (cur_type == TYPE_READ) {\n    \tif (cb_.on_read_complete)\n    \t    cb_.on_read_complete(key_, op_key, bytes_status);\n    } else if (cur_type == TYPE_ACCEPT)\n\t;    \n}\n\n\n/////////////////////////////////////////////////////////////////////////////\n/*\n * IO Queue key structure.\n */\nstruct pj_ioqueue_key_t\n{\n    CIoqueueCallback\t*cbObj;\n};\n\n\n/*\n * Return the name of the ioqueue implementation.\n */\nPJ_DEF(const char*) pj_ioqueue_name(void)\n{\n    return \"ioqueue-symbian\";\n}\n\n\n/*\n * Create a new I/O Queue framework.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_create(\tpj_pool_t *pool, \n\t\t\t\t\tpj_size_t max_fd,\n\t\t\t\t\tpj_ioqueue_t **p_ioqueue)\n{\n    pj_ioqueue_t *ioq;\n\n    PJ_UNUSED_ARG(max_fd);\n\n    ioq = PJ_POOL_ZALLOC_T(pool, pj_ioqueue_t);\n    *p_ioqueue = ioq;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy the I/O queue.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_destroy( pj_ioqueue_t *ioq )\n{\n    PJ_UNUSED_ARG(ioq);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Set the lock object to be used by the I/O Queue. \n */\nPJ_DEF(pj_status_t) pj_ioqueue_set_lock( pj_ioqueue_t *ioq, \n\t\t\t\t\t pj_lock_t *lock,\n\t\t\t\t\t pj_bool_t auto_delete )\n{\n    /* Don't really need lock for now */\n    PJ_UNUSED_ARG(ioq);\n    \n    if (auto_delete) {\n\tpj_lock_destroy(lock);\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_set_default_concurrency(pj_ioqueue_t *ioqueue,\n\t\t\t\t\t\t\t\t\t\t\t\t\t   pj_bool_t allow)\n{\n\t/* Not supported, just return PJ_SUCCESS silently */\n\tPJ_UNUSED_ARG(ioqueue);\n\tPJ_UNUSED_ARG(allow);\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Register a socket to the I/O queue framework. \n */\nPJ_DEF(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,\n\t\t\t\t\t      pj_ioqueue_t *ioq,\n\t\t\t\t\t      pj_sock_t sock,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      const pj_ioqueue_callback *cb,\n                                              pj_ioqueue_key_t **p_key )\n{\n    pj_ioqueue_key_t *key;\n\n    key = PJ_POOL_ZALLOC_T(pool, pj_ioqueue_key_t);\n    key->cbObj = CIoqueueCallback::NewL(ioq, key, sock, cb, user_data);\n\n    *p_key = key;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_register_sock2(pj_pool_t *pool,\n\t\t\t\t\t      pj_ioqueue_t *ioqueue,\n\t\t\t\t\t      pj_sock_t sock,\n\t\t\t\t\t      pj_grp_lock_t *grp_lock,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      const pj_ioqueue_callback *cb,\n                                              pj_ioqueue_key_t **p_key)\n{\n    PJ_UNUSED_ARG(grp_lock);\n\n    return pj_ioqueue_register_sock(pool, ioqueue, sock, user_data, cb, p_key);\n}\n\n/*\n * Unregister from the I/O Queue framework. \n */\nPJ_DEF(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key )\n{\n    if (key == NULL || key->cbObj == NULL)\n\treturn PJ_SUCCESS;\n\n    // Cancel pending async object\n    if (key->cbObj) {\n\tkey->cbObj->Cancel();\n    }\n\n    // Close socket.\n    key->cbObj->get_pj_socket()->Socket().Close();\n    delete key->cbObj->get_pj_socket();\n\n    // Delete async object.\n    if (key->cbObj) {\n\tdelete key->cbObj;\n\tkey->cbObj = NULL;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get user data associated with an ioqueue key.\n */\nPJ_DEF(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key )\n{\n    return key->cbObj->get_user_data();\n}\n\n\n/*\n * Set or change the user data to be associated with the file descriptor or\n * handle or socket descriptor.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key,\n                                              void *user_data,\n                                              void **old_data)\n{\n    if (old_data)\n\t*old_data = key->cbObj->get_user_data();\n    key->cbObj->set_user_data(user_data);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Initialize operation key.\n */\nPJ_DEF(void) pj_ioqueue_op_key_init( pj_ioqueue_op_key_t *op_key,\n\t\t\t\t     pj_size_t size )\n{\n    pj_bzero(op_key, size);\n}\n\n\n/*\n * Check if operation is pending on the specified operation key.\n */\nPJ_DEF(pj_bool_t) pj_ioqueue_is_pending( pj_ioqueue_key_t *key,\n                                         pj_ioqueue_op_key_t *op_key )\n{\n    return key->cbObj->get_op_key()==op_key &&\n\t   key->cbObj->IsActive();\n}\n\n\n/*\n * Post completion status to the specified operation key and call the\n * appropriate callback. \n */\nPJ_DEF(pj_status_t) pj_ioqueue_post_completion( pj_ioqueue_key_t *key,\n                                                pj_ioqueue_op_key_t *op_key,\n                                                pj_ssize_t bytes_status )\n{\n    if (pj_ioqueue_is_pending(key, op_key)) {\n\tkey->cbObj->CancelOperation(op_key, bytes_status);\n    }\n    return PJ_SUCCESS;\n}\n\n\n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0\n/**\n * Instruct I/O Queue to accept incoming connection on the specified \n * listening socket.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key,\n                                       pj_ioqueue_op_key_t *op_key,\n\t\t\t\t       pj_sock_t *new_sock,\n\t\t\t\t       pj_sockaddr_t *local,\n\t\t\t\t       pj_sockaddr_t *remote,\n\t\t\t\t       int *addrlen )\n{\n    \n    return key->cbObj->StartAccept(op_key, new_sock, local, remote, addrlen);\n}\n\n\n/*\n * Initiate non-blocking socket connect.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key,\n\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\tint addrlen )\n{\n    pj_status_t status;\n    \n    RSocket &rSock = key->cbObj->get_pj_socket()->Socket();\n    TInetAddr inetAddr;\n    TRequestStatus reqStatus;\n\n    // Return failure if access point is marked as down by app.\n    PJ_SYMBIAN_CHECK_CONNECTION();\n    \n    // Convert address\n    status = PjSymbianOS::pj2Addr(*(const pj_sockaddr*)addr, addrlen, \n    \t\t\t\t  inetAddr);\n    if (status != PJ_SUCCESS)\n    \treturn status;\n    \n    // We don't support async connect for now.\n    PJ_TODO(IOQUEUE_SUPPORT_ASYNC_CONNECT);\n\n    rSock.Connect(inetAddr, reqStatus);\n    User::WaitForRequest(reqStatus);\n\n    if (reqStatus == KErrNone)\n\treturn PJ_SUCCESS;\n\n    return PJ_RETURN_OS_ERROR(reqStatus.Int());\n}\n\n\n#endif\t/* PJ_HAS_TCP */\n\n/*\n * Poll the I/O Queue for completed events.\n */\nPJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioq,\n\t\t\t     const pj_time_val *timeout)\n{\n    /* Polling is not necessary on Symbian, since all async activities\n     * are registered to active scheduler.\n     */\n    PJ_UNUSED_ARG(ioq);\n    PJ_UNUSED_ARG(timeout);\n    return 0;\n}\n\n\n/*\n * Instruct the I/O Queue to read from the specified handle.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_recv( pj_ioqueue_key_t *key,\n                                     pj_ioqueue_op_key_t *op_key,\n\t\t\t\t     void *buffer,\n\t\t\t\t     pj_ssize_t *length,\n\t\t\t\t     pj_uint32_t flags )\n{\n    // If socket has reader, delete it.\n    if (key->cbObj->get_pj_socket()->Reader())\n    \tkey->cbObj->get_pj_socket()->DestroyReader();\n    \n    // Clear flag\n    flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC;\n    return key->cbObj->StartRead(op_key, buffer, length, flags, NULL, NULL);\n}\n\n\n/*\n * This function behaves similarly as #pj_ioqueue_recv(), except that it is\n * normally called for socket, and the remote address will also be returned\n * along with the data.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_key_t *key,\n                                         pj_ioqueue_op_key_t *op_key,\n\t\t\t\t\t void *buffer,\n\t\t\t\t\t pj_ssize_t *length,\n                                         pj_uint32_t flags,\n\t\t\t\t\t pj_sockaddr_t *addr,\n\t\t\t\t\t int *addrlen)\n{\n    CPjSocket *sock = key->cbObj->get_pj_socket();\n    \n    // If address is specified, check that the length match the\n    // address family\n    if (addr || addrlen) {\n    \tPJ_ASSERT_RETURN(addr && addrlen && *addrlen, PJ_EINVAL);\n    \tif (sock->GetAf() == PJ_AF_INET) {\n    \t    PJ_ASSERT_RETURN(*addrlen>=(int)sizeof(pj_sockaddr_in), PJ_EINVAL);\n    \t} else if (sock->GetAf() == PJ_AF_INET6) {\n    \t    PJ_ASSERT_RETURN(*addrlen>=(int)sizeof(pj_sockaddr_in6), PJ_EINVAL);\n    \t}\n    }\n    \n    // If socket has reader, delete it.\n    if (sock->Reader())\n    \tsock->DestroyReader();\n    \n    if (key->cbObj->IsActive())\n\treturn PJ_EBUSY;\n\n    // Clear flag\n    flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC;\n    return key->cbObj->StartRead(op_key, buffer, length, flags, addr, addrlen);\n}\n\n\n/*\n * Instruct the I/O Queue to write to the handle.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_send( pj_ioqueue_key_t *key,\n                                     pj_ioqueue_op_key_t *op_key,\n\t\t\t\t     const void *data,\n\t\t\t\t     pj_ssize_t *length,\n\t\t\t\t     pj_uint32_t flags )\n{\n    TRequestStatus reqStatus;\n    TPtrC8 aBuffer((const TUint8*)data, (TInt)*length);\n    TSockXfrLength aLen;\n    \n    PJ_UNUSED_ARG(op_key);\n\n    // Forcing pending operation is not supported.\n    PJ_ASSERT_RETURN((flags & PJ_IOQUEUE_ALWAYS_ASYNC)==0, PJ_EINVAL);\n\n    // Return failure if access point is marked as down by app.\n    PJ_SYMBIAN_CHECK_CONNECTION();\n\n    // Clear flag\n    flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC;\n\n    key->cbObj->get_pj_socket()->Socket().Send(aBuffer, flags, reqStatus, aLen);\n    User::WaitForRequest(reqStatus);\n\n    if (reqStatus.Int() != KErrNone)\n\treturn PJ_RETURN_OS_ERROR(reqStatus.Int());\n\n    //At least in UIQ Emulator, aLen.Length() reports incorrect length\n    //for UDP (some newlc.com users seem to have reported this too).\n    //*length = aLen.Length();\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Instruct the I/O Queue to write to the handle.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key,\n                                       pj_ioqueue_op_key_t *op_key,\n\t\t\t\t       const void *data,\n\t\t\t\t       pj_ssize_t *length,\n                                       pj_uint32_t flags,\n\t\t\t\t       const pj_sockaddr_t *addr,\n\t\t\t\t       int addrlen)\n{\n    TRequestStatus reqStatus;\n    TPtrC8 aBuffer;\n    TInetAddr inetAddr;\n    TSockXfrLength aLen;\n    pj_status_t status;\n    \n    PJ_UNUSED_ARG(op_key);\n\n    // Forcing pending operation is not supported.\n    PJ_ASSERT_RETURN((flags & PJ_IOQUEUE_ALWAYS_ASYNC)==0, PJ_EINVAL);\n\n    // Return failure if access point is marked as down by app.\n    PJ_SYMBIAN_CHECK_CONNECTION();\n\n    // Convert address\n    status = PjSymbianOS::pj2Addr(*(const pj_sockaddr*)addr, addrlen, \n    \t\t\t\t  inetAddr);\n    if (status != PJ_SUCCESS)\n    \treturn status;\n    \n    // Clear flag\n    flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC;\n\n    aBuffer.Set((const TUint8*)data, (TInt)*length);\n    CPjSocket *pjSock = key->cbObj->get_pj_socket();\n\n    pjSock->Socket().SendTo(aBuffer, inetAddr, flags, reqStatus, aLen);\n    User::WaitForRequest(reqStatus);\n\n    if (reqStatus.Int() != KErrNone)\n\treturn PJ_RETURN_OS_ERROR(reqStatus.Int());\n\n    //At least in UIQ Emulator, aLen.Length() reports incorrect length\n    //for UDP (some newlc.com users seem to have reported this too).\n    //*length = aLen.Length();\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_set_concurrency(pj_ioqueue_key_t *key,\n\t\t\t\t\t\t\t\t\t\t\t   pj_bool_t allow)\n{\n\t/* Not supported, just return PJ_SUCCESS silently */\n\tPJ_UNUSED_ARG(key);\n\tPJ_UNUSED_ARG(allow);\n\treturn PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_lock_key(pj_ioqueue_key_t *key)\n{\n\t/* Not supported, just return PJ_SUCCESS silently */\n\tPJ_UNUSED_ARG(key);\n\treturn PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_unlock_key(pj_ioqueue_key_t *key)\n{\n\t/* Not supported, just return PJ_SUCCESS silently */\n\tPJ_UNUSED_ARG(key);\n\treturn PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ioqueue_winnt.c",
    "content": "/* $Id: ioqueue_winnt.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/ioqueue.h>\n#include <pj/os.h>\n#include <pj/lock.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/sock.h>\n#include <pj/array.h>\n#include <pj/log.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/compat/socket.h>\n\n\n#if defined(PJ_HAS_WINSOCK2_H) && PJ_HAS_WINSOCK2_H != 0\n#  include <winsock2.h>\n#elif defined(PJ_HAS_WINSOCK_H) && PJ_HAS_WINSOCK_H != 0\n#  include <winsock.h>\n#endif\n\n#if defined(PJ_HAS_MSWSOCK_H) && PJ_HAS_MSWSOCK_H != 0\n#  include <mswsock.h>\n#endif\n\n\n/* The address specified in AcceptEx() must be 16 more than the size of\n * SOCKADDR (source: MSDN).\n */\n#define ACCEPT_ADDR_LEN\t    (sizeof(pj_sockaddr_in)+16)\n\ntypedef struct generic_overlapped\n{\n    WSAOVERLAPPED\t   overlapped;\n    pj_ioqueue_operation_e operation;\n} generic_overlapped;\n\n/*\n * OVERLAPPPED structure for send and receive.\n */\ntypedef struct ioqueue_overlapped\n{\n    WSAOVERLAPPED\t   overlapped;\n    pj_ioqueue_operation_e operation;\n    WSABUF\t\t   wsabuf;\n    pj_sockaddr_in         dummy_addr;\n    int                    dummy_addrlen;\n} ioqueue_overlapped;\n\n#if PJ_HAS_TCP\n/*\n * OVERLAP structure for accept.\n */\ntypedef struct ioqueue_accept_rec\n{\n    WSAOVERLAPPED\t    overlapped;\n    pj_ioqueue_operation_e  operation;\n    pj_sock_t\t\t    newsock;\n    pj_sock_t\t\t   *newsock_ptr;\n    int\t\t\t   *addrlen;\n    void\t\t   *remote;\n    void\t\t   *local;\n    char\t\t    accept_buf[2 * ACCEPT_ADDR_LEN];\n} ioqueue_accept_rec;\n#endif\n\n/*\n * Structure to hold pending operation key.\n */\nunion operation_key\n{\n    generic_overlapped      generic;\n    ioqueue_overlapped      overlapped;\n#if PJ_HAS_TCP\n    ioqueue_accept_rec      accept;\n#endif\n};\n\n/* Type of handle in the key. */\nenum handle_type\n{\n    HND_IS_UNKNOWN,\n    HND_IS_FILE,\n    HND_IS_SOCKET,\n};\n\nenum { POST_QUIT_LEN = 0xFFFFDEADUL };\n\n/*\n * Structure for individual socket.\n */\nstruct pj_ioqueue_key_t\n{\n    PJ_DECL_LIST_MEMBER(struct pj_ioqueue_key_t);\n\n    pj_ioqueue_t       *ioqueue;\n    HANDLE\t\thnd;\n    void\t       *user_data;\n    enum handle_type    hnd_type;\n    pj_ioqueue_callback\tcb;\n    pj_bool_t\t\tallow_concurrent;\n\n#if PJ_HAS_TCP\n    int\t\t\tconnecting;\n#endif\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    pj_atomic_t\t       *ref_count;\n    pj_bool_t\t\tclosing;\n    pj_time_val\t\tfree_time;\n    pj_mutex_t\t       *mutex;\n#endif\n\n};\n\n/*\n * IO Queue structure.\n */\nstruct pj_ioqueue_t\n{\n    HANDLE\t      iocp;\n    pj_lock_t        *lock;\n    pj_bool_t         auto_delete_lock;\n    pj_bool_t\t      default_concurrency;\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    pj_ioqueue_key_t  active_list;\n    pj_ioqueue_key_t  free_list;\n    pj_ioqueue_key_t  closing_list;\n#endif\n\n    /* These are to keep track of connecting sockets */\n#if PJ_HAS_TCP\n    unsigned\t      event_count;\n    HANDLE\t      event_pool[MAXIMUM_WAIT_OBJECTS+1];\n    unsigned\t      connecting_count;\n    HANDLE\t      connecting_handles[MAXIMUM_WAIT_OBJECTS+1];\n    pj_ioqueue_key_t *connecting_keys[MAXIMUM_WAIT_OBJECTS+1];\n#endif\n};\n\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n/* Prototype */\nstatic void scan_closing_keys(pj_ioqueue_t *ioqueue);\n#endif\n\n\n#if PJ_HAS_TCP\n/*\n * Process the socket when the overlapped accept() completed.\n */\nstatic void ioqueue_on_accept_complete(pj_ioqueue_key_t *key,\n                                       ioqueue_accept_rec *accept_overlapped)\n{\n    struct sockaddr *local;\n    struct sockaddr *remote;\n    int locallen, remotelen;\n    pj_status_t status;\n\n    PJ_CHECK_STACK();\n\n    /* On WinXP or later, use SO_UPDATE_ACCEPT_CONTEXT so that socket \n     * addresses can be obtained with getsockname() and getpeername().\n     */\n    status = setsockopt(accept_overlapped->newsock, SOL_SOCKET,\n                        SO_UPDATE_ACCEPT_CONTEXT, \n                        (char*)&key->hnd, \n                        sizeof(SOCKET));\n    /* SO_UPDATE_ACCEPT_CONTEXT is for WinXP or later.\n     * So ignore the error status.\n     */\n\n    /* Operation complete immediately. */\n    if (accept_overlapped->addrlen) {\n\tGetAcceptExSockaddrs( accept_overlapped->accept_buf,\n\t\t\t      0, \n\t\t\t      ACCEPT_ADDR_LEN,\n\t\t\t      ACCEPT_ADDR_LEN,\n\t\t\t      &local,\n\t\t\t      &locallen,\n\t\t\t      &remote,\n\t\t\t      &remotelen);\n\tif (*accept_overlapped->addrlen >= locallen) {\n\t    if (accept_overlapped->local)\n\t\tpj_memcpy(accept_overlapped->local, local, locallen);\n\t    if (accept_overlapped->remote)\n\t\tpj_memcpy(accept_overlapped->remote, remote, locallen);\n\t} else {\n\t    if (accept_overlapped->local)\n\t\tpj_bzero(accept_overlapped->local, \n\t\t\t *accept_overlapped->addrlen);\n\t    if (accept_overlapped->remote)\n\t\tpj_bzero(accept_overlapped->remote, \n\t\t\t *accept_overlapped->addrlen);\n\t}\n\n\t*accept_overlapped->addrlen = locallen;\n    }\n    if (accept_overlapped->newsock_ptr)\n        *accept_overlapped->newsock_ptr = accept_overlapped->newsock;\n    accept_overlapped->operation = 0;\n}\n\nstatic void erase_connecting_socket( pj_ioqueue_t *ioqueue, unsigned pos)\n{\n    pj_ioqueue_key_t *key = ioqueue->connecting_keys[pos];\n    HANDLE hEvent = ioqueue->connecting_handles[pos];\n\n    /* Remove key from array of connecting handles. */\n    pj_array_erase(ioqueue->connecting_keys, sizeof(key),\n\t\t   ioqueue->connecting_count, pos);\n    pj_array_erase(ioqueue->connecting_handles, sizeof(HANDLE),\n\t\t   ioqueue->connecting_count, pos);\n    --ioqueue->connecting_count;\n\n    /* Disassociate the socket from the event. */\n    WSAEventSelect((pj_sock_t)key->hnd, hEvent, 0);\n\n    /* Put event object to pool. */\n    if (ioqueue->event_count < MAXIMUM_WAIT_OBJECTS) {\n\tioqueue->event_pool[ioqueue->event_count++] = hEvent;\n    } else {\n\t/* Shouldn't happen. There should be no more pending connections\n\t * than max. \n\t */\n\tpj_assert(0);\n\tCloseHandle(hEvent);\n    }\n\n}\n\n/*\n * Poll for the completion of non-blocking connect().\n * If there's a completion, the function return the key of the completed\n * socket, and 'result' argument contains the connect() result. If connect()\n * succeeded, 'result' will have value zero, otherwise will have the error\n * code.\n */\nstatic int check_connecting( pj_ioqueue_t *ioqueue )\n{\n    if (ioqueue->connecting_count) {\n\tint i, count;\n\tstruct \n\t{\n\t    pj_ioqueue_key_t *key;\n\t    pj_status_t\t      status;\n\t} events[PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL-1];\n\n\tpj_lock_acquire(ioqueue->lock);\n\tfor (count=0; count<PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL-1; ++count) {\n\t    DWORD result;\n\n\t    result = WaitForMultipleObjects(ioqueue->connecting_count,\n\t\t\t\t\t    ioqueue->connecting_handles,\n\t\t\t\t\t    FALSE, 0);\n\t    if (result >= WAIT_OBJECT_0 && \n\t\tresult < WAIT_OBJECT_0+ioqueue->connecting_count) \n\t    {\n\t\tWSANETWORKEVENTS net_events;\n\n\t\t/* Got completed connect(). */\n\t\tunsigned pos = result - WAIT_OBJECT_0;\n\t\tevents[count].key = ioqueue->connecting_keys[pos];\n\n\t\t/* See whether connect has succeeded. */\n\t\tWSAEnumNetworkEvents((pj_sock_t)events[count].key->hnd, \n\t\t\t\t     ioqueue->connecting_handles[pos], \n\t\t\t\t     &net_events);\n\t\tevents[count].status = \n\t\t    PJ_STATUS_FROM_OS(net_events.iErrorCode[FD_CONNECT_BIT]);\n\n\t\t/* Erase socket from pending connect. */\n\t\terase_connecting_socket(ioqueue, pos);\n\t    } else {\n\t\t/* No more events */\n\t\tbreak;\n\t    }\n\t}\n\tpj_lock_release(ioqueue->lock);\n\n\t/* Call callbacks. */\n\tfor (i=0; i<count; ++i) {\n\t    if (events[i].key->cb.on_connect_complete) {\n\t\tevents[i].key->cb.on_connect_complete(events[i].key, \n\t\t\t\t\t\t      events[i].status);\n\t    }\n\t}\n\n\treturn count;\n    }\n\n    return 0;\n    \n}\n#endif\n\n/*\n * pj_ioqueue_name()\n */\nPJ_DEF(const char*) pj_ioqueue_name(void)\n{\n    return \"iocp\";\n}\n\n/*\n * pj_ioqueue_create()\n */\nPJ_DEF(pj_status_t) pj_ioqueue_create( pj_pool_t *pool, \n\t\t\t\t       pj_size_t max_fd,\n\t\t\t\t       pj_ioqueue_t **p_ioqueue)\n{\n    pj_ioqueue_t *ioqueue;\n    unsigned i;\n    pj_status_t rc;\n\n    PJ_UNUSED_ARG(max_fd);\n    PJ_ASSERT_RETURN(pool && p_ioqueue, PJ_EINVAL);\n\n    rc = sizeof(union operation_key);\n\n    /* Check that sizeof(pj_ioqueue_op_key_t) makes sense. */\n    PJ_ASSERT_RETURN(sizeof(pj_ioqueue_op_key_t)-sizeof(void*) >= \n                     sizeof(union operation_key), PJ_EBUG);\n\n    /* Create IOCP */\n    ioqueue = pj_pool_zalloc(pool, sizeof(*ioqueue));\n    ioqueue->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);\n    if (ioqueue->iocp == NULL)\n\treturn PJ_RETURN_OS_ERROR(GetLastError());\n\n    /* Create IOCP mutex */\n    rc = pj_lock_create_recursive_mutex(pool, NULL, &ioqueue->lock);\n    if (rc != PJ_SUCCESS) {\n\tCloseHandle(ioqueue->iocp);\n\treturn rc;\n    }\n\n    ioqueue->auto_delete_lock = PJ_TRUE;\n    ioqueue->default_concurrency = PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY;\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /*\n     * Create and initialize key pools.\n     */\n    pj_list_init(&ioqueue->active_list);\n    pj_list_init(&ioqueue->free_list);\n    pj_list_init(&ioqueue->closing_list);\n\n    /* Preallocate keys according to max_fd setting, and put them\n     * in free_list.\n     */\n    for (i=0; i<max_fd; ++i) {\n\tpj_ioqueue_key_t *key;\n\n\tkey = pj_pool_alloc(pool, sizeof(pj_ioqueue_key_t));\n\n\trc = pj_atomic_create(pool, 0, &key->ref_count);\n\tif (rc != PJ_SUCCESS) {\n\t    key = ioqueue->free_list.next;\n\t    while (key != &ioqueue->free_list) {\n\t\tpj_atomic_destroy(key->ref_count);\n\t\tpj_mutex_destroy(key->mutex);\n\t\tkey = key->next;\n\t    }\n\t    CloseHandle(ioqueue->iocp);\n\t    return rc;\n\t}\n\n\trc = pj_mutex_create_recursive(pool, \"ioqkey\", &key->mutex);\n\tif (rc != PJ_SUCCESS) {\n\t    pj_atomic_destroy(key->ref_count);\n\t    key = ioqueue->free_list.next;\n\t    while (key != &ioqueue->free_list) {\n\t\tpj_atomic_destroy(key->ref_count);\n\t\tpj_mutex_destroy(key->mutex);\n\t\tkey = key->next;\n\t    }\n\t    CloseHandle(ioqueue->iocp);\n\t    return rc;\n\t}\n\n\tpj_list_push_back(&ioqueue->free_list, key);\n    }\n#endif\n\n    *p_ioqueue = ioqueue;\n\n    PJ_LOG(4, (\"pjlib\", \"WinNT IOCP I/O Queue created (%p)\", ioqueue));\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_ioqueue_destroy()\n */\nPJ_DEF(pj_status_t) pj_ioqueue_destroy( pj_ioqueue_t *ioqueue )\n{\n#if PJ_HAS_TCP\n    unsigned i;\n#endif\n    pj_ioqueue_key_t *key;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(ioqueue, PJ_EINVAL);\n\n    pj_lock_acquire(ioqueue->lock);\n\n#if PJ_HAS_TCP\n    /* Destroy events in the pool */\n    for (i=0; i<ioqueue->event_count; ++i) {\n\tCloseHandle(ioqueue->event_pool[i]);\n    }\n    ioqueue->event_count = 0;\n#endif\n\n    if (CloseHandle(ioqueue->iocp) != TRUE)\n\treturn PJ_RETURN_OS_ERROR(GetLastError());\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Destroy reference counters */\n    key = ioqueue->active_list.next;\n    while (key != &ioqueue->active_list) {\n\tpj_atomic_destroy(key->ref_count);\n\tpj_mutex_destroy(key->mutex);\n\tkey = key->next;\n    }\n\n    key = ioqueue->closing_list.next;\n    while (key != &ioqueue->closing_list) {\n\tpj_atomic_destroy(key->ref_count);\n\tpj_mutex_destroy(key->mutex);\n\tkey = key->next;\n    }\n\n    key = ioqueue->free_list.next;\n    while (key != &ioqueue->free_list) {\n\tpj_atomic_destroy(key->ref_count);\n\tpj_mutex_destroy(key->mutex);\n\tkey = key->next;\n    }\n#endif\n\n    if (ioqueue->auto_delete_lock)\n        pj_lock_destroy(ioqueue->lock);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_ioqueue_set_default_concurrency(pj_ioqueue_t *ioqueue,\n\t\t\t\t\t\t       pj_bool_t allow)\n{\n    PJ_ASSERT_RETURN(ioqueue != NULL, PJ_EINVAL);\n    ioqueue->default_concurrency = allow;\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_ioqueue_set_lock()\n */\nPJ_DEF(pj_status_t) pj_ioqueue_set_lock( pj_ioqueue_t *ioqueue, \n\t\t\t\t\t pj_lock_t *lock,\n\t\t\t\t\t pj_bool_t auto_delete )\n{\n    PJ_ASSERT_RETURN(ioqueue && lock, PJ_EINVAL);\n\n    if (ioqueue->auto_delete_lock) {\n        pj_lock_destroy(ioqueue->lock);\n    }\n\n    ioqueue->lock = lock;\n    ioqueue->auto_delete_lock = auto_delete;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_ioqueue_register_sock()\n */\nPJ_DEF(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,\n\t\t\t\t\t      pj_ioqueue_t *ioqueue,\n\t\t\t\t\t      pj_sock_t sock,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      const pj_ioqueue_callback *cb,\n\t\t\t\t\t      pj_ioqueue_key_t **key )\n{\n    HANDLE hioq;\n    pj_ioqueue_key_t *rec;\n    u_long value;\n    int rc;\n\n    PJ_ASSERT_RETURN(pool && ioqueue && cb && key, PJ_EINVAL);\n\n    pj_lock_acquire(ioqueue->lock);\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Scan closing list first to release unused keys.\n     * Must do this with lock acquired.\n     */\n    scan_closing_keys(ioqueue);\n\n    /* If safe unregistration is used, then get the key record from\n     * the free list.\n     */\n    if (pj_list_empty(&ioqueue->free_list)) {\n\tpj_lock_release(ioqueue->lock);\n\treturn PJ_ETOOMANY;\n    }\n\n    rec = ioqueue->free_list.next;\n    pj_list_erase(rec);\n\n    /* Set initial reference count to 1 */\n    pj_assert(pj_atomic_get(rec->ref_count) == 0);\n    pj_atomic_inc(rec->ref_count);\n\n    rec->closing = 0;\n\n#else\n    rec = pj_pool_zalloc(pool, sizeof(pj_ioqueue_key_t));\n#endif\n\n    /* Build the key for this socket. */\n    rec->ioqueue = ioqueue;\n    rec->hnd = (HANDLE)sock;\n    rec->hnd_type = HND_IS_SOCKET;\n    rec->user_data = user_data;\n    pj_memcpy(&rec->cb, cb, sizeof(pj_ioqueue_callback));\n\n    /* Set concurrency for this handle */\n    rc = pj_ioqueue_set_concurrency(rec, ioqueue->default_concurrency);\n    if (rc != PJ_SUCCESS) {\n\tpj_lock_release(ioqueue->lock);\n\treturn rc;\n    }\n\n#if PJ_HAS_TCP\n    rec->connecting = 0;\n#endif\n\n    /* Set socket to nonblocking. */\n    value = 1;\n    rc = ioctlsocket(sock, FIONBIO, &value);\n    if (rc != 0) {\n\tpj_lock_release(ioqueue->lock);\n        return PJ_RETURN_OS_ERROR(WSAGetLastError());\n    }\n\n    /* Associate with IOCP */\n    hioq = CreateIoCompletionPort((HANDLE)sock, ioqueue->iocp, (DWORD)rec, 0);\n    if (!hioq) {\n\tpj_lock_release(ioqueue->lock);\n\treturn PJ_RETURN_OS_ERROR(GetLastError());\n    }\n\n    *key = rec;\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    pj_list_push_back(&ioqueue->active_list, rec);\n#endif\n\n    pj_lock_release(ioqueue->lock);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * pj_ioqueue_get_user_data()\n */\nPJ_DEF(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key )\n{\n    PJ_ASSERT_RETURN(key, NULL);\n    return key->user_data;\n}\n\n/*\n * pj_ioqueue_set_user_data()\n */\nPJ_DEF(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key,\n                                              void *user_data,\n                                              void **old_data )\n{\n    PJ_ASSERT_RETURN(key, PJ_EINVAL);\n    \n    if (old_data)\n        *old_data = key->user_data;\n\n    key->user_data = user_data;\n    return PJ_SUCCESS;\n}\n\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n/* Decrement the key's reference counter, and when the counter reach zero,\n * destroy the key.\n */\nstatic void decrement_counter(pj_ioqueue_key_t *key)\n{\n    if (pj_atomic_dec_and_get(key->ref_count) == 0) {\n\n\tpj_lock_acquire(key->ioqueue->lock);\n\n\tpj_assert(key->closing == 1);\n\tpj_gettickcount(&key->free_time);\n\tkey->free_time.msec += PJ_IOQUEUE_KEY_FREE_DELAY;\n\tpj_time_val_normalize(&key->free_time);\n\n\tpj_list_erase(key);\n\tpj_list_push_back(&key->ioqueue->closing_list, key);\n\n\tpj_lock_release(key->ioqueue->lock);\n    }\n}\n#endif\n\n/*\n * Poll the I/O Completion Port, execute callback, \n * and return the key and bytes transferred of the last operation.\n */\nstatic pj_bool_t poll_iocp( HANDLE hIocp, DWORD dwTimeout, \n\t\t\t    pj_ssize_t *p_bytes, pj_ioqueue_key_t **p_key )\n{\n    DWORD dwBytesTransferred, dwKey;\n    generic_overlapped *pOv;\n    pj_ioqueue_key_t *key;\n    pj_ssize_t size_status = -1;\n    BOOL rcGetQueued;\n\n    /* Poll for completion status. */\n    rcGetQueued = GetQueuedCompletionStatus(hIocp, &dwBytesTransferred,\n\t\t\t\t\t    &dwKey, (OVERLAPPED**)&pOv, \n\t\t\t\t\t    dwTimeout);\n\n    /* The return value is:\n     * - nonzero if event was dequeued.\n     * - zero and pOv==NULL if no event was dequeued.\n     * - zero and pOv!=NULL if event for failed I/O was dequeued.\n     */\n    if (pOv) {\n\tpj_bool_t has_lock;\n\n\t/* Event was dequeued for either successfull or failed I/O */\n\tkey = (pj_ioqueue_key_t*)dwKey;\n\tsize_status = dwBytesTransferred;\n\n\t/* Report to caller regardless */\n\tif (p_bytes)\n\t    *p_bytes = size_status;\n\tif (p_key)\n\t    *p_key = key;\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\t/* We shouldn't call callbacks if key is quitting. */\n\tif (key->closing)\n\t    return PJ_TRUE;\n\n\t/* If concurrency is disabled, lock the key \n\t * (and save the lock status to local var since app may change\n\t * concurrency setting while in the callback) */\n\tif (key->allow_concurrent == PJ_FALSE) {\n\t    pj_mutex_lock(key->mutex);\n\t    has_lock = PJ_TRUE;\n\t} else {\n\t    has_lock = PJ_FALSE;\n\t}\n\n\t/* Now that we get the lock, check again that key is not closing */\n\tif (key->closing) {\n\t    if (has_lock) {\n\t\tpj_mutex_unlock(key->mutex);\n\t    }\n\t    return PJ_TRUE;\n\t}\n\n\t/* Increment reference counter to prevent this key from being\n\t * deleted\n\t */\n\tpj_atomic_inc(key->ref_count);\n#else\n\tPJ_UNUSED_ARG(has_lock);\n#endif\n\n\t/* Carry out the callback */\n\tswitch (pOv->operation) {\n\tcase PJ_IOQUEUE_OP_READ:\n\tcase PJ_IOQUEUE_OP_RECV:\n\tcase PJ_IOQUEUE_OP_RECV_FROM:\n            pOv->operation = 0;\n            if (key->cb.on_read_complete)\n\t        key->cb.on_read_complete(key, (pj_ioqueue_op_key_t*)pOv, \n                                         size_status);\n\t    break;\n\tcase PJ_IOQUEUE_OP_WRITE:\n\tcase PJ_IOQUEUE_OP_SEND:\n\tcase PJ_IOQUEUE_OP_SEND_TO:\n            pOv->operation = 0;\n            if (key->cb.on_write_complete)\n\t        key->cb.on_write_complete(key, (pj_ioqueue_op_key_t*)pOv, \n                                                size_status);\n\t    break;\n#if PJ_HAS_TCP\n\tcase PJ_IOQUEUE_OP_ACCEPT:\n\t    /* special case for accept. */\n\t    ioqueue_on_accept_complete(key, (ioqueue_accept_rec*)pOv);\n            if (key->cb.on_accept_complete) {\n                ioqueue_accept_rec *accept_rec = (ioqueue_accept_rec*)pOv;\n\t\tpj_status_t status = PJ_SUCCESS;\n\t\tpj_sock_t newsock;\n\n\t\tnewsock = accept_rec->newsock;\n\t\taccept_rec->newsock = PJ_INVALID_SOCKET;\n\n\t\tif (newsock == PJ_INVALID_SOCKET) {\n\t\t    int dwError = WSAGetLastError();\n\t\t    if (dwError == 0) dwError = OSERR_ENOTCONN;\n\t\t    status = PJ_RETURN_OS_ERROR(dwError);\n\t\t}\n\n\t        key->cb.on_accept_complete(key, (pj_ioqueue_op_key_t*)pOv,\n                                           newsock, status);\n\t\t\n            }\n\t    break;\n\tcase PJ_IOQUEUE_OP_CONNECT:\n#endif\n\tcase PJ_IOQUEUE_OP_NONE:\n\t    pj_assert(0);\n\t    break;\n\t}\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n\tdecrement_counter(key);\n\tif (has_lock)\n\t    pj_mutex_unlock(key->mutex);\n#endif\n\n\treturn PJ_TRUE;\n    }\n\n    /* No event was queued. */\n    return PJ_FALSE;\n}\n\n/*\n * pj_ioqueue_unregister()\n */\nPJ_DEF(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key )\n{\n    unsigned i;\n    pj_bool_t has_lock;\n    enum { RETRY = 10 };\n\n    PJ_ASSERT_RETURN(key, PJ_EINVAL);\n\n#if PJ_HAS_TCP\n    if (key->connecting) {\n\tunsigned pos;\n        pj_ioqueue_t *ioqueue;\n\n        ioqueue = key->ioqueue;\n\n\t/* Erase from connecting_handles */\n\tpj_lock_acquire(ioqueue->lock);\n\tfor (pos=0; pos < ioqueue->connecting_count; ++pos) {\n\t    if (ioqueue->connecting_keys[pos] == key) {\n\t\terase_connecting_socket(ioqueue, pos);\n\t\tbreak;\n\t    }\n\t}\n\tkey->connecting = 0;\n\tpj_lock_release(ioqueue->lock);\n    }\n#endif\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Mark key as closing before closing handle. */\n    key->closing = 1;\n\n    /* If concurrency is disabled, wait until the key has finished\n     * processing the callback\n     */\n    if (key->allow_concurrent == PJ_FALSE) {\n\tpj_mutex_lock(key->mutex);\n\thas_lock = PJ_TRUE;\n    } else {\n\thas_lock = PJ_FALSE;\n    }\n#else\n    PJ_UNUSED_ARG(has_lock);\n#endif\n    \n    /* Close handle (the only way to disassociate handle from IOCP). \n     * We also need to close handle to make sure that no further events\n     * will come to the handle.\n     */\n    /* Update 2008/07/18 (http://trac.pjsip.org/repos/ticket/575):\n     *  - It seems that CloseHandle() in itself does not actually close\n     *    the socket (i.e. it will still appear in \"netstat\" output). Also\n     *    if we only use CloseHandle(), an \"Invalid Handle\" exception will\n     *    be raised in WSACleanup().\n     *  - MSDN documentation says that CloseHandle() must be called after \n     *    closesocket() call (see\n     *    http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx).\n     *    But turns out that this will raise \"Invalid Handle\" exception\n     *    in debug mode.\n     *  So because of this, we replaced CloseHandle() with closesocket()\n     *  instead. These was tested on WinXP SP2.\n     */\n    //CloseHandle(key->hnd);\n    pj_sock_close((pj_sock_t)key->hnd);\n\n    /* Reset callbacks */\n    key->cb.on_accept_complete = NULL;\n    key->cb.on_connect_complete = NULL;\n    key->cb.on_read_complete = NULL;\n    key->cb.on_write_complete = NULL;\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Even after handle is closed, I suspect that IOCP may still try to\n     * do something with the handle, causing memory corruption when pool\n     * debugging is enabled.\n     *\n     * Forcing context switch seems to have fixed that, but this is quite\n     * an ugly solution..\n     *\n     * Update 2008/02/13:\n     *\tThis should not happen if concurrency is disallowed for the key.\n     *  So at least application has a solution for this (i.e. by disallowing\n     *  concurrency in the key).\n     */\n    //This will loop forever if unregistration is done on the callback.\n    //Doing this with RETRY I think should solve the IOCP setting the \n    //socket signalled, without causing the deadlock.\n    //while (pj_atomic_get(key->ref_count) != 1)\n    //\tpj_thread_sleep(0);\n    for (i=0; pj_atomic_get(key->ref_count) != 1 && i<RETRY; ++i)\n\tpj_thread_sleep(0);\n\n    /* Decrement reference counter to destroy the key. */\n    decrement_counter(key);\n\n    if (has_lock)\n\tpj_mutex_unlock(key->mutex);\n#endif\n\n    return PJ_SUCCESS;\n}\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n/* Scan the closing list, and put pending closing keys to free list.\n * Must do this with ioqueue mutex held.\n */\nstatic void scan_closing_keys(pj_ioqueue_t *ioqueue)\n{\n    if (!pj_list_empty(&ioqueue->closing_list)) {\n\tpj_time_val now;\n\tpj_ioqueue_key_t *key;\n\n\tpj_gettickcount(&now);\n\t\n\t/* Move closing keys to free list when they've finished the closing\n\t * idle time.\n\t */\n\tkey = ioqueue->closing_list.next;\n\twhile (key != &ioqueue->closing_list) {\n\t    pj_ioqueue_key_t *next = key->next;\n\n\t    pj_assert(key->closing != 0);\n\n\t    if (PJ_TIME_VAL_GTE(now, key->free_time)) {\n\t\tpj_list_erase(key);\n\t\tpj_list_push_back(&ioqueue->free_list, key);\n\t    }\n\t    key = next;\n\t}\n    }\n}\n#endif\n\n/*\n * pj_ioqueue_poll()\n *\n * Poll for events.\n */\nPJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioqueue, const pj_time_val *timeout)\n{\n    DWORD dwMsec;\n#if PJ_HAS_TCP\n    int connect_count = 0;\n#endif\n    int event_count = 0;\n\n    PJ_ASSERT_RETURN(ioqueue, -PJ_EINVAL);\n\n    /* Calculate miliseconds timeout for GetQueuedCompletionStatus */\n    dwMsec = timeout ? timeout->sec*1000 + timeout->msec : INFINITE;\n\n    /* Poll for completion status. */\n    event_count = poll_iocp(ioqueue->iocp, dwMsec, NULL, NULL);\n\n#if PJ_HAS_TCP\n    /* Check the connecting array, only when there's no activity. */\n    if (event_count == 0) {\n\tconnect_count = check_connecting(ioqueue);\n\tif (connect_count > 0)\n\t    event_count += connect_count;\n    }\n#endif\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Check the closing keys only when there's no activity and when there are\n     * pending closing keys.\n     */\n    if (event_count == 0 && !pj_list_empty(&ioqueue->closing_list)) {\n\tpj_lock_acquire(ioqueue->lock);\n\tscan_closing_keys(ioqueue);\n\tpj_lock_release(ioqueue->lock);\n    }\n#endif\n\n    /* Return number of events. */\n    return event_count;\n}\n\n/*\n * pj_ioqueue_recv()\n *\n * Initiate overlapped WSARecv() operation.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_recv(  pj_ioqueue_key_t *key,\n                                      pj_ioqueue_op_key_t *op_key,\n\t\t\t\t      void *buffer,\n\t\t\t\t      pj_ssize_t *length,\n\t\t\t\t      pj_uint32_t flags )\n{\n    /*\n     * Ideally we should just call pj_ioqueue_recvfrom() with NULL addr and\n     * addrlen here. But unfortunately it generates EINVAL... :-(\n     *  -bennylp\n     */\n    int rc;\n    DWORD bytesRead;\n    DWORD dwFlags = 0;\n    union operation_key *op_key_rec;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(key && op_key && buffer && length, PJ_EINVAL);\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Check key is not closing */\n    if (key->closing)\n\treturn PJ_ECANCELLED;\n#endif\n\n    op_key_rec = (union operation_key*)op_key->internal__;\n    op_key_rec->overlapped.wsabuf.buf = buffer;\n    op_key_rec->overlapped.wsabuf.len = *length;\n\n    dwFlags = flags;\n    \n    /* Try non-overlapped received first to see if data is\n     * immediately available.\n     */\n    if ((flags & PJ_IOQUEUE_ALWAYS_ASYNC) == 0) {\n\trc = WSARecv((SOCKET)key->hnd, &op_key_rec->overlapped.wsabuf, 1,\n\t\t     &bytesRead, &dwFlags, NULL, NULL);\n\tif (rc == 0) {\n\t    *length = bytesRead;\n\t    return PJ_SUCCESS;\n\t} else {\n\t    DWORD dwError = WSAGetLastError();\n\t    if (dwError != WSAEWOULDBLOCK) {\n\t\t*length = -1;\n\t\treturn PJ_RETURN_OS_ERROR(dwError);\n\t    }\n\t}\n    }\n\n    dwFlags &= ~(PJ_IOQUEUE_ALWAYS_ASYNC);\n\n    /*\n     * No immediate data available.\n     * Register overlapped Recv() operation.\n     */\n    pj_bzero( &op_key_rec->overlapped.overlapped, \n              sizeof(op_key_rec->overlapped.overlapped));\n    op_key_rec->overlapped.operation = PJ_IOQUEUE_OP_RECV;\n\n    rc = WSARecv((SOCKET)key->hnd, &op_key_rec->overlapped.wsabuf, 1, \n                  &bytesRead, &dwFlags, \n\t\t  &op_key_rec->overlapped.overlapped, NULL);\n    if (rc == SOCKET_ERROR) {\n\tDWORD dwStatus = WSAGetLastError();\n        if (dwStatus!=WSA_IO_PENDING) {\n            *length = -1;\n            return PJ_STATUS_FROM_OS(dwStatus);\n        }\n    }\n\n    /* Pending operation has been scheduled. */\n    return PJ_EPENDING;\n}\n\n/*\n * pj_ioqueue_recvfrom()\n *\n * Initiate overlapped RecvFrom() operation.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_key_t *key,\n                                         pj_ioqueue_op_key_t *op_key,\n\t\t\t\t\t void *buffer,\n\t\t\t\t\t pj_ssize_t *length,\n                                         pj_uint32_t flags,\n\t\t\t\t\t pj_sockaddr_t *addr,\n\t\t\t\t\t int *addrlen)\n{\n    int rc;\n    DWORD bytesRead;\n    DWORD dwFlags = 0;\n    union operation_key *op_key_rec;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(key && op_key && buffer, PJ_EINVAL);\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Check key is not closing */\n    if (key->closing)\n\treturn PJ_ECANCELLED;\n#endif\n\n    op_key_rec = (union operation_key*)op_key->internal__;\n    op_key_rec->overlapped.wsabuf.buf = buffer;\n    op_key_rec->overlapped.wsabuf.len = *length;\n\n    dwFlags = flags;\n    \n    /* Try non-overlapped received first to see if data is\n     * immediately available.\n     */\n    if ((flags & PJ_IOQUEUE_ALWAYS_ASYNC) == 0) {\n\trc = WSARecvFrom((SOCKET)key->hnd, &op_key_rec->overlapped.wsabuf, 1,\n\t\t\t &bytesRead, &dwFlags, addr, addrlen, NULL, NULL);\n\tif (rc == 0) {\n\t    *length = bytesRead;\n\t    return PJ_SUCCESS;\n\t} else {\n\t    DWORD dwError = WSAGetLastError();\n\t    if (dwError != WSAEWOULDBLOCK) {\n\t\t*length = -1;\n\t\treturn PJ_RETURN_OS_ERROR(dwError);\n\t    }\n\t}\n    }\n\n    dwFlags &= ~(PJ_IOQUEUE_ALWAYS_ASYNC);\n\n    /*\n     * No immediate data available.\n     * Register overlapped Recv() operation.\n     */\n    pj_bzero( &op_key_rec->overlapped.overlapped, \n              sizeof(op_key_rec->overlapped.overlapped));\n    op_key_rec->overlapped.operation = PJ_IOQUEUE_OP_RECV;\n\n    rc = WSARecvFrom((SOCKET)key->hnd, &op_key_rec->overlapped.wsabuf, 1, \n                     &bytesRead, &dwFlags, addr, addrlen,\n\t\t     &op_key_rec->overlapped.overlapped, NULL);\n    if (rc == SOCKET_ERROR) {\n\tDWORD dwStatus = WSAGetLastError();\n        if (dwStatus!=WSA_IO_PENDING) {\n            *length = -1;\n            return PJ_STATUS_FROM_OS(dwStatus);\n        }\n    } \n    \n    /* Pending operation has been scheduled. */\n    return PJ_EPENDING;\n}\n\n/*\n * pj_ioqueue_send()\n *\n * Initiate overlapped Send operation.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_send(  pj_ioqueue_key_t *key,\n                                      pj_ioqueue_op_key_t *op_key,\n\t\t\t\t      const void *data,\n\t\t\t\t      pj_ssize_t *length,\n\t\t\t\t      pj_uint32_t flags )\n{\n    return pj_ioqueue_sendto(key, op_key, data, length, flags, NULL, 0);\n}\n\n\n/*\n * pj_ioqueue_sendto()\n *\n * Initiate overlapped SendTo operation.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key,\n                                       pj_ioqueue_op_key_t *op_key,\n\t\t\t\t       const void *data,\n\t\t\t\t       pj_ssize_t *length,\n                                       pj_uint32_t flags,\n\t\t\t\t       const pj_sockaddr_t *addr,\n\t\t\t\t       int addrlen)\n{\n    int rc;\n    DWORD bytesWritten;\n    DWORD dwFlags;\n    union operation_key *op_key_rec;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(key && op_key && data, PJ_EINVAL);\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Check key is not closing */\n    if (key->closing)\n\treturn PJ_ECANCELLED;\n#endif\n\n    op_key_rec = (union operation_key*)op_key->internal__;\n\n    /*\n     * First try blocking write.\n     */\n    op_key_rec->overlapped.wsabuf.buf = (void*)data;\n    op_key_rec->overlapped.wsabuf.len = *length;\n\n    dwFlags = flags;\n\n    if ((flags & PJ_IOQUEUE_ALWAYS_ASYNC) == 0) {\n\trc = WSASendTo((SOCKET)key->hnd, &op_key_rec->overlapped.wsabuf, 1,\n\t\t       &bytesWritten, dwFlags, addr, addrlen,\n\t\t       NULL, NULL);\n\tif (rc == 0) {\n\t    *length = bytesWritten;\n\t    return PJ_SUCCESS;\n\t} else {\n\t    DWORD dwStatus = WSAGetLastError();\n\t    if (dwStatus != WSAEWOULDBLOCK) {\n\t\t*length = -1;\n\t\treturn PJ_RETURN_OS_ERROR(dwStatus);\n\t    }\n\t}\n    }\n\n    dwFlags &= ~(PJ_IOQUEUE_ALWAYS_ASYNC);\n\n    /*\n     * Data can't be sent immediately.\n     * Schedule asynchronous WSASend().\n     */\n    pj_bzero( &op_key_rec->overlapped.overlapped, \n              sizeof(op_key_rec->overlapped.overlapped));\n    op_key_rec->overlapped.operation = PJ_IOQUEUE_OP_SEND;\n\n    rc = WSASendTo((SOCKET)key->hnd, &op_key_rec->overlapped.wsabuf, 1,\n                   &bytesWritten,  dwFlags, addr, addrlen,\n\t\t   &op_key_rec->overlapped.overlapped, NULL);\n    if (rc == SOCKET_ERROR) {\n\tDWORD dwStatus = WSAGetLastError();\n        if (dwStatus!=WSA_IO_PENDING)\n            return PJ_STATUS_FROM_OS(dwStatus);\n    }\n\n    /* Asynchronous operation successfully submitted. */\n    return PJ_EPENDING;\n}\n\n#if PJ_HAS_TCP\n\n/*\n * pj_ioqueue_accept()\n *\n * Initiate overlapped accept() operation.\n */\nPJ_DEF(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key,\n                                       pj_ioqueue_op_key_t *op_key,\n\t\t\t               pj_sock_t *new_sock,\n\t\t\t               pj_sockaddr_t *local,\n\t\t\t               pj_sockaddr_t *remote,\n\t\t\t               int *addrlen)\n{\n    BOOL rc;\n    DWORD bytesReceived;\n    pj_status_t status;\n    union operation_key *op_key_rec;\n    SOCKET sock;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(key && op_key && new_sock, PJ_EINVAL);\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Check key is not closing */\n    if (key->closing)\n\treturn PJ_ECANCELLED;\n#endif\n\n    /*\n     * See if there is a new connection immediately available.\n     */\n    sock = WSAAccept((SOCKET)key->hnd, remote, addrlen, NULL, 0);\n    if (sock != INVALID_SOCKET) {\n        /* Yes! New socket is available! */\n\tif (local && addrlen) {\n\t    int status;\n\n\t    /* On WinXP or later, use SO_UPDATE_ACCEPT_CONTEXT so that socket \n\t     * addresses can be obtained with getsockname() and getpeername().\n\t     */\n\t    status = setsockopt(sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,\n\t\t\t\t(char*)&key->hnd, sizeof(SOCKET));\n\t    /* SO_UPDATE_ACCEPT_CONTEXT is for WinXP or later.\n\t     * So ignore the error status.\n\t     */\n\n\t    status = getsockname(sock, local, addrlen);\n\t    if (status != 0) {\n\t\tDWORD dwError = WSAGetLastError();\n\t\tclosesocket(sock);\n\t\treturn PJ_RETURN_OS_ERROR(dwError);\n\t    }\n\t}\n\n        *new_sock = sock;\n        return PJ_SUCCESS;\n\n    } else {\n        DWORD dwError = WSAGetLastError();\n        if (dwError != WSAEWOULDBLOCK) {\n            return PJ_RETURN_OS_ERROR(dwError);\n        }\n    }\n\n    /*\n     * No connection is immediately available.\n     * Must schedule an asynchronous operation.\n     */\n    op_key_rec = (union operation_key*)op_key->internal__;\n    \n    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, \n                            &op_key_rec->accept.newsock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    op_key_rec->accept.operation = PJ_IOQUEUE_OP_ACCEPT;\n    op_key_rec->accept.addrlen = addrlen;\n    op_key_rec->accept.local = local;\n    op_key_rec->accept.remote = remote;\n    op_key_rec->accept.newsock_ptr = new_sock;\n    pj_bzero( &op_key_rec->accept.overlapped, \n\t      sizeof(op_key_rec->accept.overlapped));\n\n    rc = AcceptEx( (SOCKET)key->hnd, (SOCKET)op_key_rec->accept.newsock,\n\t\t   op_key_rec->accept.accept_buf,\n\t\t   0, ACCEPT_ADDR_LEN, ACCEPT_ADDR_LEN,\n\t\t   &bytesReceived,\n\t\t   &op_key_rec->accept.overlapped );\n\n    if (rc == TRUE) {\n\tioqueue_on_accept_complete(key, &op_key_rec->accept);\n\treturn PJ_SUCCESS;\n    } else {\n\tDWORD dwStatus = WSAGetLastError();\n\tif (dwStatus!=WSA_IO_PENDING)\n            return PJ_STATUS_FROM_OS(dwStatus);\n    }\n\n    /* Asynchronous Accept() has been submitted. */\n    return PJ_EPENDING;\n}\n\n\n/*\n * pj_ioqueue_connect()\n *\n * Initiate overlapped connect() operation (well, it's non-blocking actually,\n * since there's no overlapped version of connect()).\n */\nPJ_DEF(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key,\n\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\tint addrlen )\n{\n    HANDLE hEvent;\n    pj_ioqueue_t *ioqueue;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(key && addr && addrlen, PJ_EINVAL);\n\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    /* Check key is not closing */\n    if (key->closing)\n\treturn PJ_ECANCELLED;\n#endif\n\n    /* Initiate connect() */\n    if (connect((pj_sock_t)key->hnd, addr, addrlen) != 0) {\n\tDWORD dwStatus;\n\tdwStatus = WSAGetLastError();\n        if (dwStatus != WSAEWOULDBLOCK) {\n\t    return PJ_RETURN_OS_ERROR(dwStatus);\n\t}\n    } else {\n\t/* Connect has completed immediately! */\n\treturn PJ_SUCCESS;\n    }\n\n    ioqueue = key->ioqueue;\n\n    /* Add to the array of connecting socket to be polled */\n    pj_lock_acquire(ioqueue->lock);\n\n    if (ioqueue->connecting_count >= MAXIMUM_WAIT_OBJECTS) {\n\tpj_lock_release(ioqueue->lock);\n\treturn PJ_ETOOMANYCONN;\n    }\n\n    /* Get or create event object. */\n    if (ioqueue->event_count) {\n\thEvent = ioqueue->event_pool[ioqueue->event_count - 1];\n\t--ioqueue->event_count;\n    } else {\n\thEvent = CreateEvent(NULL, TRUE, FALSE, NULL);\n\tif (hEvent == NULL) {\n\t    DWORD dwStatus = GetLastError();\n\t    pj_lock_release(ioqueue->lock);\n\t    return PJ_STATUS_FROM_OS(dwStatus);\n\t}\n    }\n\n    /* Mark key as connecting.\n     * We can't use array index since key can be removed dynamically. \n     */\n    key->connecting = 1;\n\n    /* Associate socket events to the event object. */\n    if (WSAEventSelect((pj_sock_t)key->hnd, hEvent, FD_CONNECT) != 0) {\n\tCloseHandle(hEvent);\n\tpj_lock_release(ioqueue->lock);\n\treturn PJ_RETURN_OS_ERROR(WSAGetLastError());\n    }\n\n    /* Add to array. */\n    ioqueue->connecting_keys[ ioqueue->connecting_count ] = key;\n    ioqueue->connecting_handles[ ioqueue->connecting_count ] = hEvent;\n    ioqueue->connecting_count++;\n\n    pj_lock_release(ioqueue->lock);\n\n    return PJ_EPENDING;\n}\n#endif\t/* #if PJ_HAS_TCP */\n\n\nPJ_DEF(void) pj_ioqueue_op_key_init( pj_ioqueue_op_key_t *op_key,\n\t\t\t\t     pj_size_t size )\n{\n    pj_bzero(op_key, size);\n}\n\nPJ_DEF(pj_bool_t) pj_ioqueue_is_pending( pj_ioqueue_key_t *key,\n                                         pj_ioqueue_op_key_t *op_key )\n{\n    BOOL rc;\n    DWORD bytesTransferred;\n\n    rc = GetOverlappedResult( key->hnd, (LPOVERLAPPED)op_key,\n                              &bytesTransferred, FALSE );\n\n    if (rc == FALSE) {\n        return GetLastError()==ERROR_IO_INCOMPLETE;\n    }\n\n    return FALSE;\n}\n\n\nPJ_DEF(pj_status_t) pj_ioqueue_post_completion( pj_ioqueue_key_t *key,\n                                                pj_ioqueue_op_key_t *op_key,\n                                                pj_ssize_t bytes_status )\n{\n    BOOL rc;\n\n    rc = PostQueuedCompletionStatus(key->ioqueue->iocp, bytes_status,\n                                    (long)key, (OVERLAPPED*)op_key );\n    if (rc == FALSE) {\n        return PJ_RETURN_OS_ERROR(GetLastError());\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_set_concurrency(pj_ioqueue_key_t *key,\n\t\t\t\t\t       pj_bool_t allow)\n{\n    PJ_ASSERT_RETURN(key, PJ_EINVAL);\n\n    /* PJ_IOQUEUE_HAS_SAFE_UNREG must be enabled if concurrency is\n     * disabled.\n     */\n    PJ_ASSERT_RETURN(allow || PJ_IOQUEUE_HAS_SAFE_UNREG, PJ_EINVAL);\n\n    key->allow_concurrent = allow;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_lock_key(pj_ioqueue_key_t *key)\n{\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    return pj_mutex_lock(key->mutex);\n#else\n    PJ_ASSERT_RETURN(!\"PJ_IOQUEUE_HAS_SAFE_UNREG is disabled\", PJ_EINVALIDOP);\n#endif\n}\n\nPJ_DEF(pj_status_t) pj_ioqueue_unlock_key(pj_ioqueue_key_t *key)\n{\n#if PJ_IOQUEUE_HAS_SAFE_UNREG\n    return pj_mutex_unlock(key->mutex);\n#else\n    PJ_ASSERT_RETURN(!\"PJ_IOQUEUE_HAS_SAFE_UNREG is disabled\", PJ_EINVALIDOP);\n#endif\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ip_helper_generic.c",
    "content": "/* $Id: ip_helper_generic.c 4355 2013-02-19 16:27:37Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/ip_helper.h>\n#include <pj/addr_resolv.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/string.h>\n#include <pj/compat/socket.h>\n#include <pj/sock.h>\n\n/* Set to 1 to enable tracing */\n#if 0\n#   include <pj/log.h>\n#   define THIS_FILE\t\"ip_helper_generic.c\"\n#   define TRACE_(exp)\tPJ_LOG(5,exp)\n    static const char *get_os_errmsg(void)\n    {\n\tstatic char errmsg[PJ_ERR_MSG_SIZE];\n\tpj_strerror(pj_get_os_error(), errmsg, sizeof(errmsg));\n\treturn errmsg;\n    }\n    static const char *get_addr(void *addr)\n    {\n\tstatic char txt[PJ_INET6_ADDRSTRLEN];\n\tstruct sockaddr *ad = (struct sockaddr*)addr;\n\tif (ad->sa_family != PJ_AF_INET && ad->sa_family != PJ_AF_INET6)\n\t    return \"?\";\n\treturn pj_inet_ntop2(ad->sa_family, pj_sockaddr_get_addr(ad), \n\t\t\t     txt, sizeof(txt));\n    }\n#else\n#   define TRACE_(exp)\n#endif\n\n\n#if 0\n    /* dummy */\n\n#elif defined(PJ_HAS_IFADDRS_H) && PJ_HAS_IFADDRS_H != 0 && \\\n      defined(PJ_HAS_NET_IF_H) && PJ_HAS_NET_IF_H != 0\n/* Using getifaddrs() is preferred since it can work with both IPv4 and IPv6 */\nstatic pj_status_t if_enum_by_af(int af,\n\t\t\t\t unsigned *p_cnt,\n\t\t\t\t pj_sockaddr ifs[])\n{\n    struct ifaddrs *ifap = NULL, *it;\n    unsigned max;\n\n    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EINVAL);\n    \n    TRACE_((THIS_FILE, \"Starting interface enum with getifaddrs() for af=%d\",\n\t    af));\n\n    if (getifaddrs(&ifap) != 0) {\n\tTRACE_((THIS_FILE, \" getifarrds() failed: %s\", get_os_errmsg()));\n\treturn PJ_RETURN_OS_ERROR(pj_get_netos_error());\n    }\n\n    it = ifap;\n    max = *p_cnt;\n    *p_cnt = 0;\n    for (; it!=NULL && *p_cnt < max; it = it->ifa_next) {\n\tstruct sockaddr *ad = it->ifa_addr;\n\n\tTRACE_((THIS_FILE, \" checking %s\", it->ifa_name));\n\n\tif ((it->ifa_flags & IFF_UP)==0) {\n\t    TRACE_((THIS_FILE, \"  interface is down\"));\n\t    continue; /* Skip when interface is down */\n\t}\n\n#if PJ_IP_HELPER_IGNORE_LOOPBACK_IF\n\tif (it->ifa_flags & IFF_LOOPBACK) {\n\t    TRACE_((THIS_FILE, \"  loopback interface\"));\n\t    continue; /* Skip loopback interface */\n\t}\n#endif\n\n\tif (ad==NULL) {\n\t    TRACE_((THIS_FILE, \"  NULL address ignored\"));\n\t    continue; /* reported to happen on Linux 2.6.25.9 \n\t\t\t with ppp interface */\n\t}\n\n\tif (ad->sa_family != af) {\n\t    TRACE_((THIS_FILE, \"  address %s ignored (af=%d)\", \n\t\t    get_addr(ad), ad->sa_family));\n\t    continue; /* Skip when interface is down */\n\t}\n\n\t/* Ignore 0.0.0.0/8 address. This is a special address\n\t * which doesn't seem to have practical use.\n\t */\n\tif (af==pj_AF_INET() &&\n\t    (pj_ntohl(((pj_sockaddr_in*)ad)->sin_addr.s_addr) >> 24) == 0)\n\t{\n\t    TRACE_((THIS_FILE, \"  address %s ignored (0.0.0.0/8 class)\", \n\t\t    get_addr(ad), ad->sa_family));\n\t    continue;\n\t}\n\n\tTRACE_((THIS_FILE, \"  address %s (af=%d) added at index %d\", \n\t\tget_addr(ad), ad->sa_family, *p_cnt));\n\n\tpj_bzero(&ifs[*p_cnt], sizeof(ifs[0]));\n\tpj_memcpy(&ifs[*p_cnt], ad, pj_sockaddr_get_len(ad));\n\tPJ_SOCKADDR_RESET_LEN(&ifs[*p_cnt]);\n\t(*p_cnt)++;\n    }\n\n    freeifaddrs(ifap);\n    TRACE_((THIS_FILE, \"done, found %d address(es)\", *p_cnt));\n    return (*p_cnt != 0) ? PJ_SUCCESS : PJ_ENOTFOUND;\n}\n\n#elif defined(SIOCGIFCONF) && \\\n      defined(PJ_HAS_NET_IF_H) && PJ_HAS_NET_IF_H != 0\n\n/* Note: this does not work with IPv6 */\nstatic pj_status_t if_enum_by_af(int af,\n\t\t\t\t unsigned *p_cnt,\n\t\t\t\t pj_sockaddr ifs[])\n{\n    pj_sock_t sock;\n    char buf[512];\n    struct ifconf ifc;\n    struct ifreq *ifr;\n    int i, count;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EINVAL);\n    \n    TRACE_((THIS_FILE, \"Starting interface enum with SIOCGIFCONF for af=%d\",\n\t    af));\n\n    status = pj_sock_socket(af, PJ_SOCK_DGRAM, 0, &sock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Query available interfaces */\n    ifc.ifc_len = sizeof(buf);\n    ifc.ifc_buf = buf;\n\n    if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {\n\tint oserr = pj_get_netos_error();\n\tTRACE_((THIS_FILE, \" ioctl(SIOCGIFCONF) failed: %s\", get_os_errmsg()));\n\tpj_sock_close(sock);\n\treturn PJ_RETURN_OS_ERROR(oserr);\n    }\n\n    /* Interface interfaces */\n    ifr = (struct ifreq*) ifc.ifc_req;\n    count = ifc.ifc_len / sizeof(struct ifreq);\n    if (count > *p_cnt)\n\tcount = *p_cnt;\n\n    *p_cnt = 0;\n    for (i=0; i<count; ++i) {\n\tstruct ifreq *itf = &ifr[i];\n        struct ifreq iff = *itf;\n\tstruct sockaddr *ad = &itf->ifr_addr;\n\t\n\tTRACE_((THIS_FILE, \" checking interface %s\", itf->ifr_name));\n\n\t/* Skip address with different family */\n\tif (ad->sa_family != af) {\n\t    TRACE_((THIS_FILE, \"  address %s (af=%d) ignored\",\n\t\t    get_addr(ad), (int)ad->sa_family));\n\t    continue;\n\t}\n\n        if (ioctl(sock, SIOCGIFFLAGS, &iff) != 0) {\n\t    TRACE_((THIS_FILE, \"  ioctl(SIOCGIFFLAGS) failed: %s\",\n\t\t    get_os_errmsg()));\n\t    continue;\t/* Failed to get flags, continue */\n\t}\n\n\tif ((iff.ifr_flags & IFF_UP)==0) {\n\t    TRACE_((THIS_FILE, \"  interface is down\"));\n\t    continue; /* Skip when interface is down */\n\t}\n\n#if PJ_IP_HELPER_IGNORE_LOOPBACK_IF\n\tif (iff.ifr_flags & IFF_LOOPBACK) {\n\t    TRACE_((THIS_FILE, \"  loopback interface\"));\n\t    continue; /* Skip loopback interface */\n\t}\n#endif\n\n\t/* Ignore 0.0.0.0/8 address. This is a special address\n\t * which doesn't seem to have practical use.\n\t */\n\tif (af==pj_AF_INET() &&\n\t    (pj_ntohl(((pj_sockaddr_in*)ad)->sin_addr.s_addr) >> 24) == 0)\n\t{\n\t    TRACE_((THIS_FILE, \"  address %s ignored (0.0.0.0/8 class)\", \n\t\t    get_addr(ad), ad->sa_family));\n\t    continue;\n\t}\n\n\tTRACE_((THIS_FILE, \"  address %s (af=%d) added at index %d\", \n\t\tget_addr(ad), ad->sa_family, *p_cnt));\n\n\tpj_bzero(&ifs[*p_cnt], sizeof(ifs[0]));\n\tpj_memcpy(&ifs[*p_cnt], ad, pj_sockaddr_get_len(ad));\n\tPJ_SOCKADDR_RESET_LEN(&ifs[*p_cnt]);\n\t(*p_cnt)++;\n    }\n\n    /* Done with socket */\n    pj_sock_close(sock);\n\n    TRACE_((THIS_FILE, \"done, found %d address(es)\", *p_cnt));\n    return (*p_cnt != 0) ? PJ_SUCCESS : PJ_ENOTFOUND;\n}\n\n\n#elif defined(PJ_HAS_NET_IF_H) && PJ_HAS_NET_IF_H != 0\n/* Note: this does not work with IPv6 */\nstatic pj_status_t if_enum_by_af(int af, unsigned *p_cnt, pj_sockaddr ifs[])\n{\n    struct if_nameindex *if_list;\n    struct ifreq ifreq;\n    pj_sock_t sock;\n    unsigned i, max_count;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EINVAL);\n\n    TRACE_((THIS_FILE, \"Starting if_nameindex() for af=%d\", af));\n\n    status = pj_sock_socket(af, PJ_SOCK_DGRAM, 0, &sock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if_list = if_nameindex();\n    if (if_list == NULL)\n\treturn PJ_ENOTFOUND;\n\n    max_count = *p_cnt;\n    *p_cnt = 0;\n    for (i=0; if_list[i].if_index && *p_cnt<max_count; ++i) {\n\tstruct sockaddr *ad;\n\tint rc;\n\n\tstrncpy(ifreq.ifr_name, if_list[i].if_name, IFNAMSIZ);\n\n\tTRACE_((THIS_FILE, \" checking interface %s\", ifreq.ifr_name));\n\n\tif ((rc=ioctl(sock, SIOCGIFFLAGS, &ifreq)) != 0) {\n\t    TRACE_((THIS_FILE, \"  ioctl(SIOCGIFFLAGS) failed: %s\",\n\t\t    get_os_errmsg()));\n\t    continue;\t/* Failed to get flags, continue */\n\t}\n\n\tif ((ifreq.ifr_flags & IFF_UP)==0) {\n\t    TRACE_((THIS_FILE, \"  interface is down\"));\n\t    continue; /* Skip when interface is down */\n\t}\n\n#if PJ_IP_HELPER_IGNORE_LOOPBACK_IF\n\tif (ifreq.ifr_flags & IFF_LOOPBACK) {\n\t    TRACE_((THIS_FILE, \"  loopback interface\"));\n\t    continue; /* Skip loopback interface */\n\t}\n#endif\n\n\t/* Note: SIOCGIFADDR does not work for IPv6! */\n\tif ((rc=ioctl(sock, SIOCGIFADDR, &ifreq)) != 0) {\n\t    TRACE_((THIS_FILE, \"  ioctl(SIOCGIFADDR) failed: %s\",\n\t\t    get_os_errmsg()));\n\t    continue;\t/* Failed to get address, continue */\n\t}\n\n\tad = (struct sockaddr*) &ifreq.ifr_addr;\n\n\tif (ad->sa_family != af) {\n\t    TRACE_((THIS_FILE, \"  address %s family %d ignored\", \n\t\t\t       get_addr(&ifreq.ifr_addr),\n\t\t\t       ifreq.ifr_addr.sa_family));\n\t    continue;\t/* Not address family that we want, continue */\n\t}\n\n\t/* Ignore 0.0.0.0/8 address. This is a special address\n\t * which doesn't seem to have practical use.\n\t */\n\tif (af==pj_AF_INET() &&\n\t    (pj_ntohl(((pj_sockaddr_in*)ad)->sin_addr.s_addr) >> 24) == 0)\n\t{\n\t    TRACE_((THIS_FILE, \"  address %s ignored (0.0.0.0/8 class)\", \n\t\t    get_addr(ad), ad->sa_family));\n\t    continue;\n\t}\n\n\t/* Got an address ! */\n\tTRACE_((THIS_FILE, \"  address %s (af=%d) added at index %d\", \n\t\tget_addr(ad), ad->sa_family, *p_cnt));\n\n\tpj_bzero(&ifs[*p_cnt], sizeof(ifs[0]));\n\tpj_memcpy(&ifs[*p_cnt], ad, pj_sockaddr_get_len(ad));\n\tPJ_SOCKADDR_RESET_LEN(&ifs[*p_cnt]);\n\t(*p_cnt)++;\n    }\n\n    if_freenameindex(if_list);\n    pj_sock_close(sock);\n\n    TRACE_((THIS_FILE, \"done, found %d address(es)\", *p_cnt));\n    return (*p_cnt != 0) ? PJ_SUCCESS : PJ_ENOTFOUND;\n}\n\n#else\nstatic pj_status_t if_enum_by_af(int af,\n\t\t\t\t unsigned *p_cnt,\n\t\t\t\t pj_sockaddr ifs[])\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(p_cnt && *p_cnt > 0 && ifs, PJ_EINVAL);\n\n    pj_bzero(ifs, sizeof(ifs[0]) * (*p_cnt));\n\n    /* Just get one default route */\n    status = pj_getdefaultipinterface(af, &ifs[0]);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    *p_cnt = 1;\n    return PJ_SUCCESS;\n}\n#endif /* SIOCGIFCONF */\n\n/*\n * Enumerate the local IP interface currently active in the host.\n */\nPJ_DEF(pj_status_t) pj_enum_ip_interface(int af,\n\t\t\t\t\t unsigned *p_cnt,\n\t\t\t\t\t pj_sockaddr ifs[])\n{\n    unsigned start;\n    pj_status_t status;\n\n    start = 0;\n    if (af==PJ_AF_INET6 || af==PJ_AF_UNSPEC) {\n\tunsigned max = *p_cnt;\n\tstatus = if_enum_by_af(PJ_AF_INET6, &max, &ifs[start]);\n\tif (status == PJ_SUCCESS) {\n\t    start += max;\n\t    (*p_cnt) -= max;\n\t}\n    }\n\n    if (af==PJ_AF_INET || af==PJ_AF_UNSPEC) {\n\tunsigned max = *p_cnt;\n\tstatus = if_enum_by_af(PJ_AF_INET, &max, &ifs[start]);\n\tif (status == PJ_SUCCESS) {\n\t    start += max;\n\t    (*p_cnt) -= max;\n\t}\n    }\n\n    *p_cnt = start;\n\n    return (*p_cnt != 0) ? PJ_SUCCESS : PJ_ENOTFOUND;\n}\n\n/*\n * Enumerate the IP routing table for this host.\n */\nPJ_DEF(pj_status_t) pj_enum_ip_route(unsigned *p_cnt,\n\t\t\t\t     pj_ip_route_entry routes[])\n{\n    pj_sockaddr itf;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(p_cnt && *p_cnt > 0 && routes, PJ_EINVAL);\n\n    pj_bzero(routes, sizeof(routes[0]) * (*p_cnt));\n\n    /* Just get one default route */\n    status = pj_getdefaultipinterface(PJ_AF_INET, &itf);\n    if (status != PJ_SUCCESS)\n\treturn status;\n    \n    routes[0].ipv4.if_addr.s_addr = itf.ipv4.sin_addr.s_addr;\n    routes[0].ipv4.dst_addr.s_addr = 0;\n    routes[0].ipv4.mask.s_addr = 0;\n    *p_cnt = 1;\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ip_helper_symbian.cpp",
    "content": "/* $Id: ip_helper_symbian.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/ip_helper.h>\n#include <pj/addr_resolv.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/log.h>\n#include <pj/string.h>\n#include <pj/compat/socket.h>\n\n\n#include \"os_symbian.h\"\n\n#define THIS_FILE\t\"ip_helper_symbian.cpp\"\n#define TRACE_ME\t0\n\nstatic pj_status_t rsock_enum_interface(int af,\n\t\t\t\t\tunsigned *p_cnt,\n\t\t\t\t\tpj_sockaddr ifs[]) \n{\n    TInt rc;\n    RSocket rSock;\n    TPckgBuf<TSoInetInterfaceInfo> info;\n    unsigned i;\n    \n    if (PjSymbianOS::Instance()->Connection()) {\n    \t\n    \trc = rSock.Open(PjSymbianOS::Instance()->SocketServ(), \n    \t\t\taf, PJ_SOCK_DGRAM, KProtocolInetUdp,\n    \t\t\t*PjSymbianOS::Instance()->Connection());\n    } else {\n    \t\n    \trc = rSock.Open(PjSymbianOS::Instance()->SocketServ(), \n    \t\t\taf, PJ_SOCK_DGRAM, KProtocolInetUdp);\n    \t\t\t\n    }\n        \n    if (rc != KErrNone)\n\treturn PJ_RETURN_OS_ERROR(rc);\n    \n    rSock.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl);\n    \n    for (i=0; i<*p_cnt &&\n    \t\trSock.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, \n    \t\t             info) == KErrNone; ) \n    {\n    \tTInetAddr &iAddress = info().iAddress;\n    \tint namelen;\n\n#if TRACE_ME\n\t\tif (1) {\n\t\t\tpj_sockaddr a;\n\t\t\tchar ipaddr[PJ_INET6_ADDRSTRLEN+2];\n\t\t\t\n\t\t\tnamelen = sizeof(pj_sockaddr);\n\t\t\tif (PjSymbianOS::Addr2pj(iAddress, a, &namelen, \n\t\t\t\t\t\t\t\t\t PJ_FALSE) == PJ_SUCCESS) \n\t\t\t{\n\t\t\t\tPJ_LOG(5,(THIS_FILE, \"Enum: found address %s\", \n\t\t\t\t\t\tpj_sockaddr_print(&a, ipaddr, sizeof(ipaddr), 2)));\n\t\t\t}\n\t\t}\n#endif\n    \t\n    \tnamelen = sizeof(ifs[i]);\n    \tif (PjSymbianOS::Addr2pj(iAddress, ifs[i], &namelen, \n    \t\t\t\t\t\t\t PJ_TRUE) != PJ_SUCCESS)\n    \t{\n    \t    continue;\n    \t}\n\n    \tif (ifs[i].addr.sa_family != af)\n\t\t    continue;\n    \t\n    \t++i;\n    }\n    \n    rSock.Close();\n    \n    // Done\n    *p_cnt = i;\n    \n    return PJ_SUCCESS;\n}\n\t\t\t\t\t\n/*\n * Enumerate the local IP interface currently active in the host.\n */\nPJ_DEF(pj_status_t) pj_enum_ip_interface(int af,\n\t\t\t\t\t unsigned *p_cnt,\n\t\t\t\t\t pj_sockaddr ifs[])\n{\n    unsigned start;\n    pj_status_t status = PJ_SUCCESS;\n\n    start = 0;\n    \t    \n    /* Get IPv6 interface first. */\n    if (af==PJ_AF_INET6 || af==PJ_AF_UNSPEC) {\n    \tunsigned max = *p_cnt;\n    \tstatus = rsock_enum_interface(PJ_AF_INET6, &max, &ifs[start]);\n    \tif (status == PJ_SUCCESS) {\n    \t    (*p_cnt) -= max;\n    \t    start += max;\n    \t}\n    }\n    \n    /* Get IPv4 interface. */\n    if (af==PJ_AF_INET || af==PJ_AF_UNSPEC) {\n    \tunsigned max = *p_cnt;\n    \tstatus = rsock_enum_interface(PJ_AF_INET, &max, &ifs[start]);\n    \tif (status == PJ_SUCCESS) {\n    \t    (*p_cnt) -= max;\n    \t    start += max;\n    \t}\n    }\n    \n    *p_cnt = start;\n    \n    return start ? PJ_SUCCESS : PJ_ENOTFOUND;\n}\n\n/*\n * Enumerate the IP routing table for this host.\n */\nPJ_DEF(pj_status_t) pj_enum_ip_route(unsigned *p_cnt,\n\t\t\t\t     pj_ip_route_entry routes[])\n{\n    PJ_ASSERT_RETURN(p_cnt && *p_cnt > 0 && routes, PJ_EINVAL);\n    *p_cnt = 0;\n    return PJ_ENOTSUP;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ip_helper_win32.c",
    "content": "/* $Id: ip_helper_win32.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/config.h>\n\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n\n/* PMIB_ICMP_EX is not declared in VC6, causing error.\n * But EVC4, which also claims to be VC6, does have it! \n */\n#if defined(_MSC_VER) && _MSC_VER==1200 && !defined(PJ_WIN32_WINCE)\n#   define PMIB_ICMP_EX void*\n#endif\n#include <winsock2.h>\n\n/* If you encounter error \"Cannot open include file: 'Iphlpapi.h' here,\n * you need to install newer Platform SDK. Presumably you're using\n * Microsoft Visual Studio 6?\n */\n#include <Iphlpapi.h>\n\n#include <pj/ip_helper.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/string.h>\n\n/* Dealing with Unicode quirks:\n\n There seems to be a difference with GetProcAddress() API signature between\n Windows (i.e. Win32) and Windows CE (e.g. Windows Mobile). On Windows, the\n API is declared as:\n\n   FARPROC GetProcAddress(\n     HMODULE hModule,\n     LPCSTR lpProcName);\n \n while on Windows CE:\n\n   FARPROC GetProcAddress(\n     HMODULE hModule,\n     LPCWSTR lpProcName);\n\n Notice the difference with lpProcName argument type. This means that on \n Windows, even on Unicode Windows, the lpProcName always takes ANSI format, \n while on Windows CE, the argument follows the UNICODE setting.\n\n Because of this, we use a different Unicode treatment here than the usual\n PJ_NATIVE_STRING_IS_UNICODE PJLIB setting (<pj/unicode.h>):\n   - GPA_TEXT macro: convert literal string to platform's native literal \n         string\n   - gpa_char: the platform native character type\n\n Note that \"GPA\" and \"gpa\" are abbreviations for GetProcAddress.\n*/\n#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0\n    /* on CE, follow the PJLIB Unicode setting */\n#   define GPA_TEXT(x)\tPJ_T(x)\n#   define gpa_char\tpj_char_t\n#else\n    /* on non-CE, always use ANSI format */\n#   define GPA_TEXT(x)\tx\n#   define gpa_char\tchar\n#endif\n\n\ntypedef DWORD (WINAPI *PFN_GetIpAddrTable)(PMIB_IPADDRTABLE pIpAddrTable, \n\t\t\t\t\t   PULONG pdwSize, \n\t\t\t\t\t   BOOL bOrder);\ntypedef DWORD (WINAPI *PFN_GetAdapterAddresses)(ULONG Family,\n\t\t\t\t\t        ULONG Flags,\n\t\t\t\t\t        PVOID Reserved,\n\t\t\t\t\t        PIP_ADAPTER_ADDRESSES AdapterAddresses,\n\t\t\t\t\t        PULONG SizePointer);\ntypedef DWORD (WINAPI *PFN_GetIpForwardTable)(PMIB_IPFORWARDTABLE pIpForwardTable,\n\t\t\t\t\t      PULONG pdwSize, \n\t\t\t\t\t      BOOL bOrder);\ntypedef DWORD (WINAPI *PFN_GetIfEntry)(PMIB_IFROW pIfRow);\n\nstatic HANDLE s_hDLL;\nstatic PFN_GetIpAddrTable s_pfnGetIpAddrTable;\nstatic PFN_GetAdapterAddresses s_pfnGetAdapterAddresses;\nstatic PFN_GetIpForwardTable s_pfnGetIpForwardTable;\nstatic PFN_GetIfEntry s_pfnGetIfEntry;\n\n\nstatic void unload_iphlp_module(void)\n{\n    FreeLibrary(s_hDLL);\n    s_hDLL = NULL;\n    s_pfnGetIpAddrTable = NULL;\n    s_pfnGetIpForwardTable = NULL;\n    s_pfnGetIfEntry = NULL;\n    s_pfnGetAdapterAddresses = NULL;\n}\n\nstatic FARPROC GetIpHlpApiProc(gpa_char *lpProcName)\n{\n    if(NULL == s_hDLL) {\n\ts_hDLL = LoadLibrary(PJ_T(\"IpHlpApi\"));\n\tif(NULL != s_hDLL) {\n\t    pj_atexit(&unload_iphlp_module);\n\t}\n    }\n\t\n    if(NULL != s_hDLL)\n\treturn GetProcAddress(s_hDLL, lpProcName);\n    \n    return NULL;\n}\n\nstatic DWORD MyGetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, \n\t\t\t      PULONG pdwSize, \n\t\t\t      BOOL bOrder)\n{\n    if(NULL == s_pfnGetIpAddrTable) {\n\ts_pfnGetIpAddrTable = (PFN_GetIpAddrTable) \n\t    GetIpHlpApiProc(GPA_TEXT(\"GetIpAddrTable\"));\n    }\n    \n    if(NULL != s_pfnGetIpAddrTable) {\n\treturn s_pfnGetIpAddrTable(pIpAddrTable, pdwSize, bOrder);\n    }\n    \n    return ERROR_NOT_SUPPORTED;\n}\n\nstatic DWORD MyGetAdapterAddresses(ULONG Family,\n\t\t\t\t   ULONG Flags,\n\t\t\t\t   PVOID Reserved,\n\t\t\t\t   PIP_ADAPTER_ADDRESSES AdapterAddresses,\n\t\t\t\t   PULONG SizePointer)\n{\n    if(NULL == s_pfnGetAdapterAddresses) {\n\ts_pfnGetAdapterAddresses = (PFN_GetAdapterAddresses) \n\t    GetIpHlpApiProc(GPA_TEXT(\"GetAdaptersAddresses\"));\n    }\n    \n    if(NULL != s_pfnGetAdapterAddresses) {\n\treturn s_pfnGetAdapterAddresses(Family, Flags, Reserved,\n\t\t\t\t\tAdapterAddresses, SizePointer);\n    }\n    \n    return ERROR_NOT_SUPPORTED;\n}\n\n#if PJ_IP_HELPER_IGNORE_LOOPBACK_IF\nstatic DWORD MyGetIfEntry(MIB_IFROW *pIfRow)\n{\n    if(NULL == s_pfnGetIfEntry) {\n\ts_pfnGetIfEntry = (PFN_GetIfEntry) \n\t    GetIpHlpApiProc(GPA_TEXT(\"GetIfEntry\"));\n    }\n    \n    if(NULL != s_pfnGetIfEntry) {\n\treturn s_pfnGetIfEntry(pIfRow);\n    }\n    \n    return ERROR_NOT_SUPPORTED;\n}\n#endif\n\n\nstatic DWORD MyGetIpForwardTable(PMIB_IPFORWARDTABLE pIpForwardTable, \n\t\t\t\t PULONG pdwSize, \n\t\t\t\t BOOL bOrder)\n{\n    if(NULL == s_pfnGetIpForwardTable) {\n\ts_pfnGetIpForwardTable = (PFN_GetIpForwardTable) \n\t    GetIpHlpApiProc(GPA_TEXT(\"GetIpForwardTable\"));\n    }\n    \n    if(NULL != s_pfnGetIpForwardTable) {\n\treturn s_pfnGetIpForwardTable(pIpForwardTable, pdwSize, bOrder);\n    }\n    \n    return ERROR_NOT_SUPPORTED;\n}\n\n/* Enumerate local IP interface using GetIpAddrTable()\n * for IPv4 addresses only.\n */\nstatic pj_status_t enum_ipv4_interface(unsigned *p_cnt,\n\t\t\t\t       pj_sockaddr ifs[])\n{\n    char ipTabBuff[512];\n    MIB_IPADDRTABLE *pTab = (MIB_IPADDRTABLE*)ipTabBuff;\n    ULONG tabSize = sizeof(ipTabBuff);\n    unsigned i, count;\n    DWORD rc = NO_ERROR;\n\n    PJ_ASSERT_RETURN(p_cnt && ifs, PJ_EINVAL);\n\n    /* Get IP address table */\n    rc = MyGetIpAddrTable(pTab, &tabSize, FALSE);\n    if (rc != NO_ERROR) {\n\tif (rc == ERROR_INSUFFICIENT_BUFFER) {\n\t    /* Retry with larger buffer */\n\t    pTab = (MIB_IPADDRTABLE*)malloc(tabSize);\n\t    if (pTab)\n\t\trc = MyGetIpAddrTable(pTab, &tabSize, FALSE);\n\t}\n\n\tif (rc != NO_ERROR) {\n\t    if (pTab != (MIB_IPADDRTABLE*)ipTabBuff)\n\t\tfree(pTab);\n\t    return PJ_RETURN_OS_ERROR(rc);\n\t}\n    }\n\n    /* Reset result */\n    pj_bzero(ifs, sizeof(ifs[0]) * (*p_cnt));\n\n    /* Now fill out the entries */\n    count = (pTab->dwNumEntries < *p_cnt) ? pTab->dwNumEntries : *p_cnt;\n    *p_cnt = 0;\n    for (i=0; i<count; ++i) {\n\tMIB_IFROW ifRow;\n\n\t/* Ignore 0.0.0.0 address (interface is down?) */\n\tif (pTab->table[i].dwAddr == 0)\n\t    continue;\n\n\t/* Ignore 0.0.0.0/8 address. This is a special address\n\t * which doesn't seem to have practical use.\n\t */\n\tif ((pj_ntohl(pTab->table[i].dwAddr) >> 24) == 0)\n\t    continue;\n\n#if PJ_IP_HELPER_IGNORE_LOOPBACK_IF\n\t/* Investigate the type of this interface */\n\tpj_bzero(&ifRow, sizeof(ifRow));\n\tifRow.dwIndex = pTab->table[i].dwIndex;\n\tif (MyGetIfEntry(&ifRow) != 0)\n\t    continue;\n\n\tif (ifRow.dwType == MIB_IF_TYPE_LOOPBACK)\n\t    continue;\n#endif\n\n\tifs[*p_cnt].ipv4.sin_family = PJ_AF_INET;\n\tifs[*p_cnt].ipv4.sin_addr.s_addr = pTab->table[i].dwAddr;\n\t(*p_cnt)++;\n    }\n\n    if (pTab != (MIB_IPADDRTABLE*)ipTabBuff)\n\tfree(pTab);\n\n    return (*p_cnt) ? PJ_SUCCESS : PJ_ENOTFOUND;\n}\n\n/* Enumerate local IP interface using GetAdapterAddresses(),\n * which works for both IPv4 and IPv6.\n */\nstatic pj_status_t enum_ipv4_ipv6_interface(int af,\n\t\t\t\t\t    unsigned *p_cnt,\n\t\t\t\t\t    pj_sockaddr ifs[])\n{\n    pj_uint8_t buffer[600];\n    IP_ADAPTER_ADDRESSES *adapter = (IP_ADAPTER_ADDRESSES*)buffer;\n    void *adapterBuf = NULL;\n    ULONG size = sizeof(buffer);\n    ULONG flags;\n    unsigned i;\n    DWORD rc;\n\n    flags = GAA_FLAG_SKIP_FRIENDLY_NAME |\n\t    GAA_FLAG_SKIP_DNS_SERVER |\n\t    GAA_FLAG_SKIP_MULTICAST;\n\n    rc = MyGetAdapterAddresses(af, flags, NULL, adapter, &size);\n    if (rc != ERROR_SUCCESS) {\n\tif (rc == ERROR_BUFFER_OVERFLOW) {\n\t    /* Retry with larger memory size */\n\t    adapterBuf = malloc(size);\n\t    adapter = (IP_ADAPTER_ADDRESSES*) adapterBuf;\n\t    if (adapter != NULL)\n\t\trc = MyGetAdapterAddresses(af, flags, NULL, adapter, &size);\n\t} \n\n\tif (rc != ERROR_SUCCESS) {\n\t    if (adapterBuf)\n\t\tfree(adapterBuf);\n\t    return PJ_RETURN_OS_ERROR(rc);\n\t}\n    }\n\n    /* Reset result */\n    pj_bzero(ifs, sizeof(ifs[0]) * (*p_cnt));\n\n    /* Enumerate interface */\n    for (i=0; i<*p_cnt && adapter; adapter = adapter->Next) {\n\tif (adapter->FirstUnicastAddress) {\n\t    SOCKET_ADDRESS *pAddr = &adapter->FirstUnicastAddress->Address;\n\n\t    /* Ignore address family which we didn't request, just in case */\n\t    if (pAddr->lpSockaddr->sa_family != PJ_AF_INET &&\n\t\tpAddr->lpSockaddr->sa_family != PJ_AF_INET6)\n\t    {\n\t\tcontinue;\n\t    }\n\n\t    /* Apply some filtering to known IPv4 unusable addresses */\n\t    if (pAddr->lpSockaddr->sa_family == PJ_AF_INET) {\n\t\tconst pj_sockaddr_in *addr_in = \n\t\t    (const pj_sockaddr_in*)pAddr->lpSockaddr;\n\n\t\t/* Ignore 0.0.0.0 address (interface is down?) */\n\t\tif (addr_in->sin_addr.s_addr == 0)\n\t\t    continue;\n\n\t\t/* Ignore 0.0.0.0/8 address. This is a special address\n\t\t * which doesn't seem to have practical use.\n\t\t */\n\t\tif ((pj_ntohl(addr_in->sin_addr.s_addr) >> 24) == 0)\n\t\t    continue;\n\t    }\n\n#if PJ_IP_HELPER_IGNORE_LOOPBACK_IF\n\t    /* Ignore loopback interfaces */\n\t    /* This should have been IF_TYPE_SOFTWARE_LOOPBACK according to\n\t     * MSDN, and this macro should have been declared in Ipifcons.h, \n\t     * but some SDK versions don't have it.\n\t     */\n\t    if (adapter->IfType == MIB_IF_TYPE_LOOPBACK)\n\t\tcontinue;\n#endif\n\n\t    /* Ignore down interface */\n\t    if (adapter->OperStatus != IfOperStatusUp)\n\t\tcontinue;\n\n\t    ifs[i].addr.sa_family = pAddr->lpSockaddr->sa_family;\n\t    pj_memcpy(&ifs[i], pAddr->lpSockaddr, pAddr->iSockaddrLength);\n\t    ++i;\n\t}\n    }\n\n    if (adapterBuf)\n\tfree(adapterBuf);\n\n    *p_cnt = i;\n    return (*p_cnt) ? PJ_SUCCESS : PJ_ENOTFOUND;\n}\n\n\n/*\n * Enumerate the local IP interface currently active in the host.\n */\nPJ_DEF(pj_status_t) pj_enum_ip_interface(int af,\n\t\t\t\t\t unsigned *p_cnt,\n\t\t\t\t\t pj_sockaddr ifs[])\n{\n    pj_status_t status = -1;\n\n    PJ_ASSERT_RETURN(p_cnt && ifs, PJ_EINVAL);\n    PJ_ASSERT_RETURN(af==PJ_AF_UNSPEC || af==PJ_AF_INET || af==PJ_AF_INET6,\n\t\t     PJ_EAFNOTSUP);\n\n    status = enum_ipv4_ipv6_interface(af, p_cnt, ifs);\n    if (status != PJ_SUCCESS && (af==PJ_AF_INET || af==PJ_AF_UNSPEC))\n\tstatus = enum_ipv4_interface(p_cnt, ifs);\n    return status;\n}\n\n/*\n * Enumerate the IP routing table for this host.\n */\nPJ_DEF(pj_status_t) pj_enum_ip_route(unsigned *p_cnt,\n\t\t\t\t     pj_ip_route_entry routes[])\n{\n    char ipTabBuff[1024];\n    MIB_IPADDRTABLE *pIpTab;\n    char rtabBuff[1024];\n    MIB_IPFORWARDTABLE *prTab;\n    ULONG tabSize;\n    unsigned i, count;\n    DWORD rc = NO_ERROR;\n\n    PJ_ASSERT_RETURN(p_cnt && routes, PJ_EINVAL);\n\n    pIpTab = (MIB_IPADDRTABLE *)ipTabBuff;\n    prTab = (MIB_IPFORWARDTABLE *)rtabBuff;\n\n    /* First get IP address table */\n    tabSize = sizeof(ipTabBuff);\n    rc = MyGetIpAddrTable(pIpTab, &tabSize, FALSE);\n    if (rc != NO_ERROR)\n\treturn PJ_RETURN_OS_ERROR(rc);\n\n    /* Next get IP route table */\n    tabSize = sizeof(rtabBuff);\n\n    rc = MyGetIpForwardTable(prTab, &tabSize, 1);\n    if (rc != NO_ERROR)\n\treturn PJ_RETURN_OS_ERROR(rc);\n\n    /* Reset routes */\n    pj_bzero(routes, sizeof(routes[0]) * (*p_cnt));\n\n    /* Now fill out the route entries */\n    count = (prTab->dwNumEntries < *p_cnt) ? prTab->dwNumEntries : *p_cnt;\n    *p_cnt = 0;\n    for (i=0; i<count; ++i) {\n\tunsigned j;\n\n\t/* Find interface entry */\n\tfor (j=0; j<pIpTab->dwNumEntries; ++j) {\n\t    if (pIpTab->table[j].dwIndex == prTab->table[i].dwForwardIfIndex)\n\t\tbreak;\n\t}\n\n\tif (j==pIpTab->dwNumEntries)\n\t    continue;\t/* Interface not found */\n\n\troutes[*p_cnt].ipv4.if_addr.s_addr = pIpTab->table[j].dwAddr;\n\troutes[*p_cnt].ipv4.dst_addr.s_addr = prTab->table[i].dwForwardDest;\n\troutes[*p_cnt].ipv4.mask.s_addr = prTab->table[i].dwForwardMask;\n\n\t(*p_cnt)++;\n    }\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/list.c",
    "content": "/* $Id: list.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/list.h>\n\n#if !PJ_FUNCTIONS_ARE_INLINED\n#  include <pj/list_i.h>\n#endif\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/lock.c",
    "content": "/* $Id: lock.c 4412 2013-03-05 03:12:32Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/lock.h>\n#include <pj/os.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/errno.h>\n\n#define THIS_FILE\t\"lock.c\"\n\ntypedef void LOCK_OBJ;\n\n/*\n * Lock structure.\n */\nstruct pj_lock_t\n{\n    LOCK_OBJ *lock_object;\n\n    pj_status_t\t(*acquire)\t(LOCK_OBJ*);\n    pj_status_t\t(*tryacquire)\t(LOCK_OBJ*);\n    pj_status_t\t(*release)\t(LOCK_OBJ*);\n    pj_status_t\t(*destroy)\t(LOCK_OBJ*);\n};\n\ntypedef pj_status_t (*FPTR)(LOCK_OBJ*);\n\n/******************************************************************************\n * Implementation of lock object with mutex.\n */\nstatic pj_lock_t mutex_lock_template = \n{\n    NULL,\n    (FPTR) &pj_mutex_lock,\n    (FPTR) &pj_mutex_trylock,\n    (FPTR) &pj_mutex_unlock,\n    (FPTR) &pj_mutex_destroy\n};\n\nstatic pj_status_t create_mutex_lock( pj_pool_t *pool,\n\t\t\t\t      const char *name,\n\t\t\t\t      int type,\n\t\t\t\t      pj_lock_t **lock )\n{\n    pj_lock_t *p_lock;\n    pj_mutex_t *mutex;\n    pj_status_t rc;\n\n    PJ_ASSERT_RETURN(pool && lock, PJ_EINVAL);\n\n    p_lock = PJ_POOL_ALLOC_T(pool, pj_lock_t);\n    if (!p_lock)\n\treturn PJ_ENOMEM;\n\n    pj_memcpy(p_lock, &mutex_lock_template, sizeof(pj_lock_t));\n    rc = pj_mutex_create(pool, name, type, &mutex);\n    if (rc != PJ_SUCCESS)\n\treturn rc;\n\n    p_lock->lock_object = mutex;\n    *lock = p_lock;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_lock_create_simple_mutex( pj_pool_t *pool,\n\t\t\t\t\t\t const char *name,\n\t\t\t\t\t\t pj_lock_t **lock )\n{\n    return create_mutex_lock(pool, name, PJ_MUTEX_SIMPLE, lock);\n}\n\nPJ_DEF(pj_status_t) pj_lock_create_recursive_mutex( pj_pool_t *pool,\n\t\t\t\t\t\t    const char *name,\n\t\t\t\t\t\t    pj_lock_t **lock )\n{\n    return create_mutex_lock(pool, name, PJ_MUTEX_RECURSE, lock);\n}\n\n\n/******************************************************************************\n * Implementation of NULL lock object.\n */\nstatic pj_status_t null_op(void *arg)\n{\n    PJ_UNUSED_ARG(arg);\n    return PJ_SUCCESS;\n}\n\nstatic pj_lock_t null_lock_template = \n{\n    NULL,\n    &null_op,\n    &null_op,\n    &null_op,\n    &null_op\n};\n\nPJ_DEF(pj_status_t) pj_lock_create_null_mutex( pj_pool_t *pool,\n\t\t\t\t\t       const char *name,\n\t\t\t\t\t       pj_lock_t **lock )\n{\n    PJ_UNUSED_ARG(name);\n    PJ_UNUSED_ARG(pool);\n\n    PJ_ASSERT_RETURN(lock, PJ_EINVAL);\n\n    *lock = &null_lock_template;\n    return PJ_SUCCESS;\n}\n\n\n/******************************************************************************\n * Implementation of semaphore lock object.\n */\n#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0\n\nstatic pj_lock_t sem_lock_template = \n{\n    NULL,\n    (FPTR) &pj_sem_wait,\n    (FPTR) &pj_sem_trywait,\n    (FPTR) &pj_sem_post,\n    (FPTR) &pj_sem_destroy\n};\n\nPJ_DEF(pj_status_t) pj_lock_create_semaphore(  pj_pool_t *pool,\n\t\t\t\t\t       const char *name,\n\t\t\t\t\t       unsigned initial,\n\t\t\t\t\t       unsigned max,\n\t\t\t\t\t       pj_lock_t **lock )\n{\n    pj_lock_t *p_lock;\n    pj_sem_t *sem;\n    pj_status_t rc;\n\n    PJ_ASSERT_RETURN(pool && lock, PJ_EINVAL);\n\n    p_lock = PJ_POOL_ALLOC_T(pool, pj_lock_t);\n    if (!p_lock)\n\treturn PJ_ENOMEM;\n\n    pj_memcpy(p_lock, &sem_lock_template, sizeof(pj_lock_t));\n    rc = pj_sem_create( pool, name, initial, max, &sem);\n    if (rc != PJ_SUCCESS)\n        return rc;\n\n    p_lock->lock_object = sem;\n    *lock = p_lock;\n\n    return PJ_SUCCESS;\n}\n\n\n#endif\t/* PJ_HAS_SEMAPHORE */\n\n\nPJ_DEF(pj_status_t) pj_lock_acquire( pj_lock_t *lock )\n{\n    PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);\n    return (*lock->acquire)(lock->lock_object);\n}\n\nPJ_DEF(pj_status_t) pj_lock_tryacquire( pj_lock_t *lock )\n{\n    PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);\n    return (*lock->tryacquire)(lock->lock_object);\n}\n\nPJ_DEF(pj_status_t) pj_lock_release( pj_lock_t *lock )\n{\n    PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);\n    return (*lock->release)(lock->lock_object);\n}\n\nPJ_DEF(pj_status_t) pj_lock_destroy( pj_lock_t *lock )\n{\n    PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);\n    return (*lock->destroy)(lock->lock_object);\n}\n\n\n/******************************************************************************\n * Group lock\n */\n\n/* Individual lock in the group lock */\ntypedef struct grp_lock_item\n{\n    PJ_DECL_LIST_MEMBER(struct grp_lock_item);\n    int\t\t prio;\n    pj_lock_t\t*lock;\n\n} grp_lock_item;\n\n/* Destroy callbacks */\ntypedef struct grp_destroy_callback\n{\n    PJ_DECL_LIST_MEMBER(struct grp_destroy_callback);\n    void\t*comp;\n    void\t(*handler)(void*);\n} grp_destroy_callback;\n\n#if PJ_GRP_LOCK_DEBUG\n/* Store each add_ref caller */\ntypedef struct grp_lock_ref\n{\n    PJ_DECL_LIST_MEMBER(struct grp_lock_ref);\n    const char\t*file;\n    int\t\t line;\n} grp_lock_ref;\n#endif\n\n/* The group lock */\nstruct pj_grp_lock_t\n{\n    pj_lock_t\t \t base;\n\n    pj_pool_t\t\t*pool;\n    pj_atomic_t\t\t*ref_cnt;\n    pj_lock_t\t\t*own_lock;\n\n    pj_thread_t\t\t*owner;\n    int\t\t\t owner_cnt;\n\n    grp_lock_item\t lock_list;\n    grp_destroy_callback destroy_list;\n\n#if PJ_GRP_LOCK_DEBUG\n    grp_lock_ref\t ref_list;\n    grp_lock_ref\t ref_free_list;\n#endif\n};\n\n\nPJ_DEF(void) pj_grp_lock_config_default(pj_grp_lock_config *cfg)\n{\n    pj_bzero(cfg, sizeof(*cfg));\n}\n\nstatic void grp_lock_set_owner_thread(pj_grp_lock_t *glock)\n{\n    if (!glock->owner) {\n\tglock->owner = pj_thread_this();\n\tglock->owner_cnt = 1;\n    } else {\n\tpj_assert(glock->owner == pj_thread_this());\n\tglock->owner_cnt++;\n    }\n}\n\nstatic void grp_lock_unset_owner_thread(pj_grp_lock_t *glock)\n{\n    pj_assert(glock->owner == pj_thread_this());\n    pj_assert(glock->owner_cnt > 0);\n    if (--glock->owner_cnt <= 0) {\n\tglock->owner = NULL;\n\tglock->owner_cnt = 0;\n    }\n}\n\nstatic pj_status_t grp_lock_acquire(LOCK_OBJ *p)\n{\n    pj_grp_lock_t *glock = (pj_grp_lock_t*)p;\n    grp_lock_item *lck;\n\n    pj_assert(pj_atomic_get(glock->ref_cnt) > 0);\n\n    lck = glock->lock_list.next;\n    while (lck != &glock->lock_list) {\n\tpj_lock_acquire(lck->lock);\n\tlck = lck->next;\n    }\n    grp_lock_set_owner_thread(glock);\n    pj_grp_lock_add_ref(glock);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t grp_lock_tryacquire(LOCK_OBJ *p)\n{\n    pj_grp_lock_t *glock = (pj_grp_lock_t*)p;\n    grp_lock_item *lck;\n\n    pj_assert(pj_atomic_get(glock->ref_cnt) > 0);\n\n    lck = glock->lock_list.next;\n    while (lck != &glock->lock_list) {\n\tpj_status_t status = pj_lock_tryacquire(lck->lock);\n\tif (status != PJ_SUCCESS) {\n\t    lck = lck->prev;\n\t    while (lck != &glock->lock_list) {\n\t\tpj_lock_release(lck->lock);\n\t\tlck = lck->prev;\n\t    }\n\t    return status;\n\t}\n\tlck = lck->next;\n    }\n    grp_lock_set_owner_thread(glock);\n    pj_grp_lock_add_ref(glock);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t grp_lock_release(LOCK_OBJ *p)\n{\n    pj_grp_lock_t *glock = (pj_grp_lock_t*)p;\n    grp_lock_item *lck;\n\n    grp_lock_unset_owner_thread(glock);\n\n    lck = glock->lock_list.prev;\n    while (lck != &glock->lock_list) {\n\tpj_lock_release(lck->lock);\n\tlck = lck->prev;\n    }\n    return pj_grp_lock_dec_ref(glock);\n}\n\nstatic pj_status_t grp_lock_add_handler( pj_grp_lock_t *glock,\n                             \t\t pj_pool_t *pool,\n                             \t\t void *comp,\n                             \t\t void (*destroy)(void *comp),\n                             \t\t pj_bool_t acquire_lock)\n{\n    grp_destroy_callback *cb;\n\n    if (acquire_lock)\n        grp_lock_acquire(glock);\n\n    if (pool == NULL)\n\tpool = glock->pool;\n\n    cb = PJ_POOL_ZALLOC_T(pool, grp_destroy_callback);\n    cb->comp = comp;\n    cb->handler = destroy;\n    pj_list_push_back(&glock->destroy_list, cb);\n\n    if (acquire_lock)\n        grp_lock_release(glock);\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t grp_lock_destroy(LOCK_OBJ *p)\n{\n    pj_grp_lock_t *glock = (pj_grp_lock_t*)p;\n    pj_pool_t *pool = glock->pool;\n    grp_lock_item *lck;\n    grp_destroy_callback *cb;\n\n    if (!glock->pool) {\n\t/* already destroyed?! */\n\treturn PJ_EINVAL;\n    }\n\n    /* Release all chained locks */\n    lck = glock->lock_list.next;\n    while (lck != &glock->lock_list) {\n\tif (lck->lock != glock->own_lock) {\n\t    int i;\n\t    for (i=0; i<glock->owner_cnt; ++i)\n\t\tpj_lock_release(lck->lock);\n\t}\n\tlck = lck->next;\n    }\n\n    /* Call callbacks */\n    cb = glock->destroy_list.next;\n    while (cb != &glock->destroy_list) {\n\tgrp_destroy_callback *next = cb->next;\n\tcb->handler(cb->comp);\n\tcb = next;\n    }\n\n    pj_lock_destroy(glock->own_lock);\n    pj_atomic_destroy(glock->ref_cnt);\n    glock->pool = NULL;\n    pj_pool_release(pool);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_grp_lock_create( pj_pool_t *pool,\n                                        const pj_grp_lock_config *cfg,\n                                        pj_grp_lock_t **p_grp_lock)\n{\n    pj_grp_lock_t *glock;\n    grp_lock_item *own_lock;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && p_grp_lock, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(cfg);\n\n    pool = pj_pool_create(pool->factory, \"glck%p\", 512, 512, NULL);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    glock = PJ_POOL_ZALLOC_T(pool, pj_grp_lock_t);\n    glock->base.lock_object = glock;\n    glock->base.acquire = &grp_lock_acquire;\n    glock->base.tryacquire = &grp_lock_tryacquire;\n    glock->base.release = &grp_lock_release;\n    glock->base.destroy = &grp_lock_destroy;\n\n    glock->pool = pool;\n    pj_list_init(&glock->lock_list);\n    pj_list_init(&glock->destroy_list);\n#if PJ_GRP_LOCK_DEBUG\n    pj_list_init(&glock->ref_list);\n    pj_list_init(&glock->ref_free_list);\n#endif\n\n    status = pj_atomic_create(pool, 0, &glock->ref_cnt);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    status = pj_lock_create_recursive_mutex(pool, pool->obj_name,\n                                            &glock->own_lock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    own_lock = PJ_POOL_ZALLOC_T(pool, grp_lock_item);\n    own_lock->lock = glock->own_lock;\n    pj_list_push_back(&glock->lock_list, own_lock);\n\n    *p_grp_lock = glock;\n    return PJ_SUCCESS;\n\non_error:\n    grp_lock_destroy(glock);\n    return status;\n}\n\nPJ_DEF(pj_status_t) pj_grp_lock_create_w_handler( pj_pool_t *pool,\n                                        \t  const pj_grp_lock_config *cfg,\n                                        \t  void *member,\n                                                  void (*handler)(void *member),\n                                        \t  pj_grp_lock_t **p_grp_lock)\n{\n    pj_status_t status;\n\n    status = pj_grp_lock_create(pool, cfg, p_grp_lock);\n    if (status == PJ_SUCCESS) {\n        grp_lock_add_handler(*p_grp_lock, pool, member, handler, PJ_FALSE);\n    }\n    \n    return status;\n}\n\nPJ_DEF(pj_status_t) pj_grp_lock_destroy( pj_grp_lock_t *grp_lock)\n{\n    return grp_lock_destroy(grp_lock);\n}\n\nPJ_DEF(pj_status_t) pj_grp_lock_acquire( pj_grp_lock_t *grp_lock)\n{\n    return grp_lock_acquire(grp_lock);\n}\n\nPJ_DEF(pj_status_t) pj_grp_lock_tryacquire( pj_grp_lock_t *grp_lock)\n{\n    return grp_lock_tryacquire(grp_lock);\n}\n\nPJ_DEF(pj_status_t) pj_grp_lock_release( pj_grp_lock_t *grp_lock)\n{\n    return grp_lock_release(grp_lock);\n}\n\nPJ_DEF(pj_status_t) pj_grp_lock_replace( pj_grp_lock_t *old_lock,\n                                         pj_grp_lock_t *new_lock)\n{\n    grp_destroy_callback *ocb;\n\n    /* Move handlers from old to new */\n    ocb = old_lock->destroy_list.next;\n    while (ocb != &old_lock->destroy_list) {\n\tgrp_destroy_callback *ncb;\n\n\tncb = PJ_POOL_ALLOC_T(new_lock->pool, grp_destroy_callback);\n\tncb->comp = ocb->comp;\n\tncb->handler = ocb->handler;\n\tpj_list_push_back(&new_lock->destroy_list, ncb);\n\n\tocb = ocb->next;\n    }\n\n    pj_list_init(&old_lock->destroy_list);\n\n    grp_lock_destroy(old_lock);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_grp_lock_add_handler( pj_grp_lock_t *glock,\n                                             pj_pool_t *pool,\n                                             void *comp,\n                                             void (*destroy)(void *comp))\n{\n    return grp_lock_add_handler(glock, pool, comp, destroy, PJ_TRUE);\n}\n\nPJ_DEF(pj_status_t) pj_grp_lock_del_handler( pj_grp_lock_t *glock,\n                                             void *comp,\n                                             void (*destroy)(void *comp))\n{\n    grp_destroy_callback *cb;\n\n    grp_lock_acquire(glock);\n\n    cb = glock->destroy_list.next;\n    while (cb != &glock->destroy_list) {\n\tif (cb->comp == comp && cb->handler == destroy)\n\t    break;\n\tcb = cb->next;\n    }\n\n    if (cb != &glock->destroy_list)\n\tpj_list_erase(cb);\n\n    grp_lock_release(glock);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t grp_lock_add_ref(pj_grp_lock_t *glock)\n{\n    pj_atomic_inc(glock->ref_cnt);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t grp_lock_dec_ref(pj_grp_lock_t *glock)\n{\n    int cnt; /* for debugging */\n    if ((cnt=pj_atomic_dec_and_get(glock->ref_cnt)) == 0) {\n\tgrp_lock_destroy(glock);\n\treturn PJ_EGONE;\n    }\n    pj_assert(cnt > 0);\n    pj_grp_lock_dump(glock);\n    return PJ_SUCCESS;\n}\n\n#if PJ_GRP_LOCK_DEBUG\nPJ_DEF(pj_status_t) pj_grp_lock_add_ref_dbg(pj_grp_lock_t *glock,\n                                            const char *file,\n                                            int line)\n{\n    grp_lock_ref *ref;\n    pj_status_t status;\n\n    pj_enter_critical_section();\n    if (!pj_list_empty(&glock->ref_free_list)) {\n\tref = glock->ref_free_list.next;\n\tpj_list_erase(ref);\n    } else {\n\tref = PJ_POOL_ALLOC_T(glock->pool, grp_lock_ref);\n    }\n\n    ref->file = file;\n    ref->line = line;\n    pj_list_push_back(&glock->ref_list, ref);\n\n    pj_leave_critical_section();\n\n    status = grp_lock_add_ref(glock);\n\n    if (status != PJ_SUCCESS) {\n\tpj_enter_critical_section();\n\tpj_list_erase(ref);\n\tpj_list_push_back(&glock->ref_free_list, ref);\n\tpj_leave_critical_section();\n    }\n\n    return status;\n}\n\nPJ_DEF(pj_status_t) pj_grp_lock_dec_ref_dbg(pj_grp_lock_t *glock,\n                                            const char *file,\n                                            int line)\n{\n    grp_lock_ref *ref;\n\n    pj_enter_critical_section();\n    /* Find the same source file */\n    ref = glock->ref_list.next;\n    while (ref != &glock->ref_list) {\n\tif (strcmp(ref->file, file) == 0) {\n\t    pj_list_erase(ref);\n\t    pj_list_push_back(&glock->ref_free_list, ref);\n\t    break;\n\t}\n\tref = ref->next;\n    }\n    pj_leave_critical_section();\n\n    if (ref == &glock->ref_list) {\n\tPJ_LOG(2,(THIS_FILE, \"pj_grp_lock_dec_ref_dbg() could not find \"\n\t\t\t      \"matching ref for %s\", file));\n    }\n\n    return grp_lock_dec_ref(glock);\n}\n#else\nPJ_DEF(pj_status_t) pj_grp_lock_add_ref(pj_grp_lock_t *glock)\n{\n    return grp_lock_add_ref(glock);\n}\n\nPJ_DEF(pj_status_t) pj_grp_lock_dec_ref(pj_grp_lock_t *glock)\n{\n    return grp_lock_dec_ref(glock);\n}\n#endif\n\nPJ_DEF(int) pj_grp_lock_get_ref(pj_grp_lock_t *glock)\n{\n    return pj_atomic_get(glock->ref_cnt);\n}\n\nPJ_DEF(pj_status_t) pj_grp_lock_chain_lock( pj_grp_lock_t *glock,\n                                            pj_lock_t *lock,\n                                            int pos)\n{\n    grp_lock_item *lck, *new_lck;\n    int i;\n\n    grp_lock_acquire(glock);\n\n    for (i=0; i<glock->owner_cnt; ++i)\n\tpj_lock_acquire(lock);\n\n    lck = glock->lock_list.next;\n    while (lck != &glock->lock_list) {\n\tif (lck->prio >= pos)\n\t    break;\n\tlck = lck->next;\n    }\n\n    new_lck = PJ_POOL_ZALLOC_T(glock->pool, grp_lock_item);\n    new_lck->prio = pos;\n    new_lck->lock = lock;\n    pj_list_insert_before(lck, new_lck);\n\n    /* this will also release the new lock */\n    grp_lock_release(glock);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_grp_lock_unchain_lock( pj_grp_lock_t *glock,\n                                              pj_lock_t *lock)\n{\n    grp_lock_item *lck;\n\n    grp_lock_acquire(glock);\n\n    lck = glock->lock_list.next;\n    while (lck != &glock->lock_list) {\n\tif (lck->lock == lock)\n\t    break;\n\tlck = lck->next;\n    }\n\n    if (lck != &glock->lock_list) {\n\tint i;\n\n\tpj_list_erase(lck);\n\tfor (i=0; i<glock->owner_cnt; ++i)\n\t    pj_lock_release(lck->lock);\n    }\n\n    grp_lock_release(glock);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void) pj_grp_lock_dump(pj_grp_lock_t *grp_lock)\n{\n#if PJ_GRP_LOCK_DEBUG\n    grp_lock_ref *ref = grp_lock->ref_list.next;\n    char info_buf[1000];\n    pj_str_t info;\n\n    info.ptr = info_buf;\n    info.slen = 0;\n\n    pj_grp_lock_acquire(grp_lock);\n    pj_enter_critical_section();\n\n    while (ref != &grp_lock->ref_list && info.slen < sizeof(info_buf)) {\n\tchar *start = info.ptr + info.slen;\n\tint max_len = sizeof(info_buf) - info.slen;\n\tint len;\n\n\tlen = pj_ansi_snprintf(start, max_len, \"%s:%d \", ref->file, ref->line);\n\tif (len < 1 || len >= max_len) {\n\t    len = strlen(ref->file);\n\t    if (len > max_len - 1)\n\t\tlen = max_len - 1;\n\n\t    memcpy(start, ref->file, len);\n\t    start[len++] = ' ';\n\t}\n\n\tinfo.slen += len;\n\n\tref = ref->next;\n    }\n\n    if (ref != &grp_lock->ref_list) {\n\tint i;\n\tfor (i=0; i<4; ++i)\n\t    info_buf[sizeof(info_buf)-i-1] = '.';\n    }\n    info.ptr[info.slen-1] = '\\0';\n\n    pj_leave_critical_section();\n    pj_grp_lock_release(grp_lock);\n\n    PJ_LOG(4,(THIS_FILE, \"Group lock %p, ref_cnt=%d. Reference holders: %s\",\n\t       grp_lock, pj_grp_lock_get_ref(grp_lock), info.ptr));\n#else\n    PJ_UNUSED_ARG(grp_lock);\n#endif\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/log.c",
    "content": "/* $Id: log.c 3752 2011-09-18 14:38:46Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/types.h>\n#include <pj/log.h>\n#include <pj/string.h>\n#include <pj/os.h>\n#include <pj/compat/stdarg.h>\n\n#if PJ_LOG_MAX_LEVEL >= 1\n\n#if 0\nPJ_DEF_DATA(int) pj_log_max_level = PJ_LOG_MAX_LEVEL;\n#else\nstatic int pj_log_max_level = PJ_LOG_MAX_LEVEL;\n#endif\n\nstatic void *g_last_thread;\n\n#if PJ_HAS_THREADS\nstatic long thread_suspended_tls_id = -1;\n#  if PJ_LOG_ENABLE_INDENT\nstatic long thread_indent_tls_id = -1;\n#  endif\n#endif\n\n#if !PJ_LOG_ENABLE_INDENT || !PJ_HAS_THREADS\nstatic int log_indent;\n#endif\n\nstatic pj_log_func *log_writer = &pj_log_write;\nstatic unsigned log_decor = PJ_LOG_HAS_TIME | PJ_LOG_HAS_MICRO_SEC |\n\t\t\t    PJ_LOG_HAS_SENDER | PJ_LOG_HAS_NEWLINE |\n\t\t\t    PJ_LOG_HAS_SPACE | PJ_LOG_HAS_THREAD_SWC |\n\t\t\t    PJ_LOG_HAS_INDENT\n#if (defined(PJ_WIN32) && PJ_WIN32!=0) || \\\n    (defined(PJ_WIN64) && PJ_WIN64!=0)\n\t\t\t    | PJ_LOG_HAS_COLOR\n#endif\n\t\t\t    ;\n\nstatic pj_color_t PJ_LOG_COLOR_0 = PJ_TERM_COLOR_BRIGHT | PJ_TERM_COLOR_R;\nstatic pj_color_t PJ_LOG_COLOR_1 = PJ_TERM_COLOR_BRIGHT | PJ_TERM_COLOR_R;\nstatic pj_color_t PJ_LOG_COLOR_2 = PJ_TERM_COLOR_BRIGHT | \n\t\t\t\t   PJ_TERM_COLOR_R | \n\t\t\t\t   PJ_TERM_COLOR_G;\nstatic pj_color_t PJ_LOG_COLOR_3 = PJ_TERM_COLOR_BRIGHT | \n\t\t\t\t   PJ_TERM_COLOR_R | \n\t\t\t\t   PJ_TERM_COLOR_G | \n\t\t\t\t   PJ_TERM_COLOR_B;\nstatic pj_color_t PJ_LOG_COLOR_4 = PJ_TERM_COLOR_R | \n\t\t\t\t   PJ_TERM_COLOR_G | \n\t\t\t\t   PJ_TERM_COLOR_B;\nstatic pj_color_t PJ_LOG_COLOR_5 = PJ_TERM_COLOR_R | \n\t\t\t\t   PJ_TERM_COLOR_G | \n\t\t\t\t   PJ_TERM_COLOR_B;\nstatic pj_color_t PJ_LOG_COLOR_6 = PJ_TERM_COLOR_R | \n\t\t\t\t   PJ_TERM_COLOR_G | \n\t\t\t\t   PJ_TERM_COLOR_B;\n/* Default terminal color */\nstatic pj_color_t PJ_LOG_COLOR_77 = PJ_TERM_COLOR_R | \n\t\t\t\t    PJ_TERM_COLOR_G | \n\t\t\t\t    PJ_TERM_COLOR_B;\n\n#if PJ_LOG_USE_STACK_BUFFER==0\nstatic char log_buffer[PJ_LOG_MAX_SIZE];\n#endif\n\n#define LOG_MAX_INDENT\t\t80\n\n#if PJ_HAS_THREADS\nstatic void logging_shutdown(void)\n{\n    if (thread_suspended_tls_id != -1) {\n\tpj_thread_local_free(thread_suspended_tls_id);\n\tthread_suspended_tls_id = -1;\n    }\n#  if PJ_LOG_ENABLE_INDENT\n    if (thread_indent_tls_id != -1) {\n\tpj_thread_local_free(thread_indent_tls_id);\n\tthread_indent_tls_id = -1;\n    }\n#  endif\n}\n#endif\t/* PJ_HAS_THREADS */\n\n#if PJ_LOG_ENABLE_INDENT && PJ_HAS_THREADS\nstatic void log_set_indent(int indent)\n{\n    if (indent < 0) indent = 0;\n    pj_thread_local_set(thread_indent_tls_id, (void*)(pj_ssize_t)indent);\n}\n\nstatic int log_get_raw_indent(void)\n{\n    return (long)(pj_ssize_t)pj_thread_local_get(thread_indent_tls_id);\n}\n\n#else\nstatic void log_set_indent(int indent)\n{\n    log_indent = indent;\n    if (log_indent < 0) log_indent = 0;\n}\n\nstatic int log_get_raw_indent(void)\n{\n    return log_indent;\n}\n#endif\t/* PJ_LOG_ENABLE_INDENT && PJ_HAS_THREADS */\n\nstatic int log_get_indent(void)\n{\n    int indent = log_get_raw_indent();\n    return indent > LOG_MAX_INDENT ? LOG_MAX_INDENT : indent;\n}\n\nPJ_DEF(void) pj_log_add_indent(int indent)\n{\n    log_set_indent(log_get_raw_indent() + indent);\n}\n\nPJ_DEF(void) pj_log_push_indent(void)\n{\n    pj_log_add_indent(PJ_LOG_INDENT_SIZE);\n}\n\nPJ_DEF(void) pj_log_pop_indent(void)\n{\n    pj_log_add_indent(-PJ_LOG_INDENT_SIZE);\n}\n\npj_status_t pj_log_init(void)\n{\n#if PJ_HAS_THREADS\n    if (thread_suspended_tls_id == -1) {\n\tpj_status_t status;\n\tstatus = pj_thread_local_alloc(&thread_suspended_tls_id);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n#  if PJ_LOG_ENABLE_INDENT\n\tstatus = pj_thread_local_alloc(&thread_indent_tls_id);\n\tif (status != PJ_SUCCESS) {\n\t    pj_thread_local_free(thread_suspended_tls_id);\n\t    thread_suspended_tls_id = -1;\n\t    return status;\n\t}\n#  endif\n\tpj_atexit(&logging_shutdown);\n    }\n#endif\n    g_last_thread = NULL;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void) pj_log_set_decor(unsigned decor)\n{\n    log_decor = decor;\n}\n\nPJ_DEF(unsigned) pj_log_get_decor(void)\n{\n    return log_decor;\n}\n\nPJ_DEF(void) pj_log_set_color(int level, pj_color_t color)\n{\n    switch (level) \n    {\n\tcase 0: PJ_LOG_COLOR_0 = color; \n\t    break;\n\tcase 1: PJ_LOG_COLOR_1 = color; \n\t    break;\n\tcase 2: PJ_LOG_COLOR_2 = color; \n\t    break;\n\tcase 3: PJ_LOG_COLOR_3 = color; \n\t    break;\n\tcase 4: PJ_LOG_COLOR_4 = color; \n\t    break;\n\tcase 5: PJ_LOG_COLOR_5 = color; \n\t    break;\n\tcase 6: PJ_LOG_COLOR_6 = color; \n\t    break;\n\t/* Default terminal color */\n\tcase 77: PJ_LOG_COLOR_77 = color; \n\t    break;\n\tdefault:\n\t    /* Do nothing */\n\t    break;\n    }\n}\n\nPJ_DEF(pj_color_t) pj_log_get_color(int level)\n{\n    switch (level) {\n\tcase 0:\n\t    return PJ_LOG_COLOR_0;\n\tcase 1:\n\t    return PJ_LOG_COLOR_1;\n\tcase 2:\n\t    return PJ_LOG_COLOR_2;\n\tcase 3:\n\t    return PJ_LOG_COLOR_3;\n\tcase 4:\n\t    return PJ_LOG_COLOR_4;\n\tcase 5:\n\t    return PJ_LOG_COLOR_5;\n\tcase 6:\n\t    return PJ_LOG_COLOR_6;\n\tdefault:\n\t    /* Return default terminal color */\n\t    return PJ_LOG_COLOR_77;\n    }\n}\n\nPJ_DEF(void) pj_log_set_level(int level)\n{\n    pj_log_max_level = level;\n}\n\n#if 1\nPJ_DEF(int) pj_log_get_level(void)\n{\n    return pj_log_max_level;\n}\n#endif\n\nPJ_DEF(void) pj_log_set_log_func( pj_log_func *func )\n{\n    log_writer = func;\n}\n\nPJ_DEF(pj_log_func*) pj_log_get_log_func(void)\n{\n    return log_writer;\n}\n\n/* Temporarily suspend logging facility for this thread.\n * If thread local storage/variable is not used or not initialized, then\n * we can only suspend the logging globally across all threads. This may\n * happen e.g. when log function is called before PJLIB is fully initialized\n * or after PJLIB is shutdown.\n */\nstatic void suspend_logging(int *saved_level)\n{\n\t/* Save the level regardless, just in case PJLIB is shutdown\n\t * between suspend and resume.\n\t */\n\t*saved_level = pj_log_max_level;\n\n#if PJ_HAS_THREADS\n    if (thread_suspended_tls_id != -1) \n    {\n\tpj_thread_local_set(thread_suspended_tls_id, \n\t\t\t    (void*)(pj_ssize_t)PJ_TRUE);\n    } \n    else\n#endif\n    {\n\tpj_log_max_level = 0;\n    }\n}\n\n/* Resume logging facility for this thread */\nstatic void resume_logging(int *saved_level)\n{\n#if PJ_HAS_THREADS\n    if (thread_suspended_tls_id != -1) \n    {\n\tpj_thread_local_set(thread_suspended_tls_id,\n\t\t\t    (void*)(pj_size_t)PJ_FALSE);\n    }\n    else\n#endif\n    {\n\t/* Only revert the level if application doesn't change the\n\t * logging level between suspend and resume.\n\t */\n\tif (pj_log_max_level==0 && *saved_level)\n\t    pj_log_max_level = *saved_level;\n    }\n}\n\n/* Is logging facility suspended for this thread? */\nstatic pj_bool_t is_logging_suspended(void)\n{\n#if PJ_HAS_THREADS\n    if (thread_suspended_tls_id != -1) \n    {\n\treturn pj_thread_local_get(thread_suspended_tls_id) != NULL;\n    }\n    else\n#endif\n    {\n\treturn pj_log_max_level == 0;\n    }\n}\n\nPJ_DEF(void) pj_log( const char *sender, int level, \n\t\t     const char *format, va_list marker)\n{\n    pj_time_val now;\n    pj_parsed_time ptime;\n    char *pre;\n#if PJ_LOG_USE_STACK_BUFFER\n    char log_buffer[PJ_LOG_MAX_SIZE];\n#endif\n    int saved_level, len, print_len, indent;\n\n    PJ_CHECK_STACK();\n\n    if (level > pj_log_max_level)\n\treturn;\n\n    if (is_logging_suspended())\n\treturn;\n\n    /* Temporarily disable logging for this thread. Some of PJLIB APIs that\n     * this function calls below will recursively call the logging function \n     * back, hence it will cause infinite recursive calls if we allow that.\n     */\n    suspend_logging(&saved_level);\n\n    /* Get current date/time. */\n    pj_gettimeofday(&now);\n    pj_time_decode(&now, &ptime);\n\n    pre = log_buffer;\n    if (log_decor & PJ_LOG_HAS_LEVEL_TEXT) {\n\tstatic const char *ltexts[] = { \"FATAL:\", \"ERROR:\", \" WARN:\", \n\t\t\t      \" INFO:\", \"DEBUG:\", \"TRACE:\", \"DETRC:\"};\n\tpj_ansi_strcpy(pre, ltexts[level]);\n\tpre += 6;\n    }\n    if (log_decor & PJ_LOG_HAS_DAY_NAME) {\n\tstatic const char *wdays[] = { \"Sun\", \"Mon\", \"Tue\", \"Wed\",\n\t\t\t\t       \"Thu\", \"Fri\", \"Sat\"};\n\tpj_ansi_strcpy(pre, wdays[ptime.wday]);\n\tpre += 3;\n    }\n    if (log_decor & PJ_LOG_HAS_YEAR) {\n\tif (pre!=log_buffer) *pre++ = ' ';\n\tpre += pj_utoa(ptime.year, pre);\n    }\n    if (log_decor & PJ_LOG_HAS_MONTH) {\n\t*pre++ = '-';\n\tpre += pj_utoa_pad(ptime.mon+1, pre, 2, '0');\n    }\n    if (log_decor & PJ_LOG_HAS_DAY_OF_MON) {\n\t*pre++ = '-';\n\tpre += pj_utoa_pad(ptime.day, pre, 2, '0');\n    }\n    if (log_decor & PJ_LOG_HAS_TIME) {\n\tif (pre!=log_buffer) *pre++ = ' ';\n\tpre += pj_utoa_pad(ptime.hour, pre, 2, '0');\n\t*pre++ = ':';\n\tpre += pj_utoa_pad(ptime.min, pre, 2, '0');\n\t*pre++ = ':';\n\tpre += pj_utoa_pad(ptime.sec, pre, 2, '0');\n    }\n    if (log_decor & PJ_LOG_HAS_MICRO_SEC) {\n\t*pre++ = '.';\n\tpre += pj_utoa_pad(ptime.msec, pre, 3, '0');\n    }\n    if (log_decor & PJ_LOG_HAS_SENDER) {\n\tenum { SENDER_WIDTH = 14 };\n\tpj_size_t sender_len = strlen(sender);\n\tif (pre!=log_buffer) *pre++ = ' ';\n\tif (sender_len <= SENDER_WIDTH) {\n\t    while (sender_len < SENDER_WIDTH)\n\t\t*pre++ = ' ', ++sender_len;\n\t    while (*sender)\n\t\t*pre++ = *sender++;\n\t} else {\n\t    int i;\n\t    for (i=0; i<SENDER_WIDTH; ++i)\n\t\t*pre++ = *sender++;\n\t}\n    }\n    if (log_decor & PJ_LOG_HAS_THREAD_ID) {\n\tenum { THREAD_WIDTH = 12 };\n\tconst char *thread_name = pj_thread_get_name(pj_thread_this());\n\tpj_size_t thread_len = strlen(thread_name);\n\t*pre++ = ' ';\n\tif (thread_len <= THREAD_WIDTH) {\n\t    while (thread_len < THREAD_WIDTH)\n\t\t*pre++ = ' ', ++thread_len;\n\t    while (*thread_name)\n\t\t*pre++ = *thread_name++;\n\t} else {\n\t    int i;\n\t    for (i=0; i<THREAD_WIDTH; ++i)\n\t\t*pre++ = *thread_name++;\n\t}\n    }\n\n    if (log_decor != 0 && log_decor != PJ_LOG_HAS_NEWLINE)\n\t*pre++ = ' ';\n\n    if (log_decor & PJ_LOG_HAS_THREAD_SWC) {\n\tvoid *current_thread = (void*)pj_thread_this();\n\tif (current_thread != g_last_thread) {\n\t    *pre++ = '!';\n\t    g_last_thread = current_thread;\n\t} else {\n\t    *pre++ = ' ';\n\t}\n    } else if (log_decor & PJ_LOG_HAS_SPACE) {\n\t*pre++ = ' ';\n    }\n\n#if PJ_LOG_ENABLE_INDENT\n    if (log_decor & PJ_LOG_HAS_INDENT) {\n\tindent = log_get_indent();\n\tif (indent > 0) {\n\t    pj_memset(pre, PJ_LOG_INDENT_CHAR, indent);\n\t    pre += indent;\n\t}\n    }\n#endif\n\n    len = (int)(pre - log_buffer);\n\n    /* Print the whole message to the string log_buffer. */\n    print_len = pj_ansi_vsnprintf(pre, sizeof(log_buffer)-len, format, \n\t\t\t\t  marker);\n    if (print_len < 0) {\n\tlevel = 1;\n\tprint_len = pj_ansi_snprintf(pre, sizeof(log_buffer)-len, \n\t\t\t\t     \"<logging error: msg too long>\");\n    }\n    if (print_len < 1 || print_len >= (int)(sizeof(log_buffer)-len)) {\n\tprint_len = sizeof(log_buffer) - len - 1;\n    }\n    len = len + print_len;\n    if (len > 0 && len < (int)sizeof(log_buffer)-2) {\n\tif (log_decor & PJ_LOG_HAS_CR) {\n\t    log_buffer[len++] = '\\r';\n\t}\n\tif (log_decor & PJ_LOG_HAS_NEWLINE) {\n\t    log_buffer[len++] = '\\n';\n\t}\n\tlog_buffer[len] = '\\0';\n    } else {\n\tlen = sizeof(log_buffer)-1;\n\tif (log_decor & PJ_LOG_HAS_CR) {\n\t    log_buffer[sizeof(log_buffer)-3] = '\\r';\n\t}\n\tif (log_decor & PJ_LOG_HAS_NEWLINE) {\n\t    log_buffer[sizeof(log_buffer)-2] = '\\n';\n\t}\n\tlog_buffer[sizeof(log_buffer)-1] = '\\0';\n    }\n\n    /* It should be safe to resume logging at this point. Application can\n     * recursively call the logging function inside the callback.\n     */\n    resume_logging(&saved_level);\n\n    if (log_writer)\n\t(*log_writer)(level, log_buffer, len);\n}\n\n/*\nPJ_DEF(void) pj_log_0(const char *obj, const char *format, ...)\n{\n    va_list arg;\n    va_start(arg, format);\n    pj_log(obj, 0, format, arg);\n    va_end(arg);\n}\n*/\n\nPJ_DEF(void) pj_log_1(const char *obj, const char *format, ...)\n{\n    va_list arg;\n    va_start(arg, format);\n    pj_log(obj, 1, format, arg);\n    va_end(arg);\n}\n#endif\t/* PJ_LOG_MAX_LEVEL >= 1 */\n\n#if PJ_LOG_MAX_LEVEL >= 2\nPJ_DEF(void) pj_log_2(const char *obj, const char *format, ...)\n{\n    va_list arg;\n    va_start(arg, format);\n    pj_log(obj, 2, format, arg);\n    va_end(arg);\n}\n#endif\n\n#if PJ_LOG_MAX_LEVEL >= 3\nPJ_DEF(void) pj_log_3(const char *obj, const char *format, ...)\n{\n    va_list arg;\n    va_start(arg, format);\n    pj_log(obj, 3, format, arg);\n    va_end(arg);\n}\n#endif\n\n#if PJ_LOG_MAX_LEVEL >= 4\nPJ_DEF(void) pj_log_4(const char *obj, const char *format, ...)\n{\n    va_list arg;\n    va_start(arg, format);\n    pj_log(obj, 4, format, arg);\n    va_end(arg);\n}\n#endif\n\n#if PJ_LOG_MAX_LEVEL >= 5\nPJ_DEF(void) pj_log_5(const char *obj, const char *format, ...)\n{\n    va_list arg;\n    va_start(arg, format);\n    pj_log(obj, 5, format, arg);\n    va_end(arg);\n}\n#endif\n\n#if PJ_LOG_MAX_LEVEL >= 6\nPJ_DEF(void) pj_log_6(const char *obj, const char *format, ...)\n{\n    va_list arg;\n    va_start(arg, format);\n    pj_log(obj, 6, format, arg);\n    va_end(arg);\n}\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/log_writer_printk.c",
    "content": "/* $Id: log_writer_printk.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/log.h>\n#include <pj/os.h>\n\nPJ_DEF(void) pj_log_write(int level, const char *buffer, int len)\n{\n    PJ_CHECK_STACK();\n    printk(KERN_INFO \"%s\", buffer);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/log_writer_stdout.c",
    "content": "/* $Id: log_writer_stdout.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/compat/stdfileio.h>\n\n\nstatic void term_set_color(int level)\n{\n#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0\n    pj_term_set_color(pj_log_get_color(level));\n#else\n    PJ_UNUSED_ARG(level);\n#endif\n}\n\nstatic void term_restore_color(void)\n{\n#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0\n    /* Set terminal to its default color */\n    pj_term_set_color(pj_log_get_color(77));\n#endif\n}\n\n\nPJ_DEF(void) pj_log_write(int level, const char *buffer, int len)\n{\n    PJ_CHECK_STACK();\n    PJ_UNUSED_ARG(len);\n\n    /* Copy to terminal/file. */\n    if (pj_log_get_decor() & PJ_LOG_HAS_COLOR) {\n\tterm_set_color(level);\n\tprintf(\"%s\", buffer);\n\tterm_restore_color();\n    } else {\n\tprintf(\"%s\", buffer);\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/log_writer_symbian_console.cpp",
    "content": "/* $Id: log_writer_symbian_console.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/unicode.h>\n\n#include \"os_symbian.h\"\n#include <e32cons.h>\n\nPJ_DEF(void) pj_log_write(int level, const char *buffer, int len)\n{\n#if 0\n    wchar_t wbuffer[PJ_LOG_MAX_SIZE];\n    CConsoleBase *cons = PjSymbianOS::Instance->Console();\n\n    pj_ansi_to_unicode(buffer, len, wbuffer, PJ_ARRAY_SIZE(wbuffer));\n\n    \n    TPtrC16 aPtr((TUint16*)wbuffer, len);\n    console->Write(aPtr);\n#else\n    PJ_UNUSED_ARG(level);\n    PJ_UNUSED_ARG(buffer);\n    PJ_UNUSED_ARG(len);\n#endif\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_core_darwin.m",
    "content": "/* $Id: os_core_darwin.m 3670 2011-07-20 03:00:48Z ming $ */\n/* \n * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/os.h>\n#include \"TargetConditionals.h\"\n\n#if TARGET_OS_IPHONE\n\nPJ_DEF(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],\n                       unsigned flags)\n{\n    return (*main_func)(argc, argv);\n}\n\n#else\n\n#include <pthread.h>\n#include <AppKit/AppKit.h>\n#include <CoreFoundation/CFRunLoop.h>\n#include <Foundation/Foundation.h>\n\n#define THIS_FILE   \"os_core_darwin.m\"\n\ntypedef struct run_app_t {\n    pj_main_func_ptr  main_func;\n    int               argc;\n    char            **argv;\n    int               retval;\n} run_app_t;\n\n@interface DeadThread: NSObject { ;; }\n+ (void)enterMultiThreadedMode;\n+ (void)emptyThreadMethod:(id)obj;\n@end\n\n@implementation DeadThread\n+ (void)enterMultiThreadedMode\n{\n    [NSThread detachNewThreadSelector:@selector(emptyThreadMethod:)\n              toTarget:[DeadThread class] withObject:nil];\n}\n\n+ (void)emptyThreadMethod:(id)obj { ; }\n@end\n\nstatic void* main_thread(void *data)\n{\n    run_app_t *param = (run_app_t *)data;\n    \n    param->retval = (*param->main_func)(param->argc, param->argv);\n    CFRunLoopStop(CFRunLoopGetMain());\n    \n    return NULL;\n}\n\n/*\n * pj_run_app()\n * This function has to be called from the main thread. The purpose of\n * this function is to initialize the application's memory pool, event\n * loop management, and multi-threading environment.\n */\nPJ_DEF(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],\n                       unsigned flags)\n{\n    pthread_t thread;\n    run_app_t param;\n    NSAutoreleasePool *pool;\n    \n    pool = [[NSAutoreleasePool alloc] init];\n    [NSApplication sharedApplication];\n    [DeadThread enterMultiThreadedMode];\n\n    param.argc = argc;\n    param.argv = (char **)argv;\n    param.main_func = main_func;\n    if (pthread_create(&thread, NULL, &main_thread, &param) == 0) {\n        CFRunLoopRun();\n    }\n    \n    PJ_UNUSED_ARG(pool);\n    \n    return param.retval;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_core_linux_kernel.c",
    "content": "/* $Id: os_core_linux_kernel.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/os.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n#include <pj/log.h>\n#include <pj/except.h>\n#include <pj/errno.h>\n#include <pj/string.h>\n#include <pj/compat/high_precision.h>\n#include <pj/compat/sprintf.h>\n\n#include <linux/config.h>\n#include <linux/version.h>\n#if defined(MODVERSIONS)\n#include <linux/modversions.h>\n#endif\n#include <linux/kernel.h>\n#include <linux/sched.h>\n//#include <linux/tqueue.h>\n#include <linux/wait.h>\n#include <linux/signal.h>\n\n#include <asm/atomic.h>\n#include <asm/unistd.h>\n#include <asm/semaphore.h>\n\n#define THIS_FILE   \"oslinuxkern\"\n\nstruct pj_thread_t\n{\n    /** Thread's name. */\n    char obj_name[PJ_MAX_OBJ_NAME];\n\n    /** Linux task structure for thread. */\n    struct task_struct *thread;\t\n\n    /** Flags (specified in pj_thread_create) */\n    unsigned flags;\n\n    /** Task queue needed to launch thread. */\n    //struct tq_struct\ttq;\t\n\n    /** Semaphore needed to control thread startup. */\n    struct semaphore\tstartstop_sem;\n\n    /** Semaphore to suspend thread during startup. */\n    struct semaphore\tsuspend_sem;\n\n    /** Queue thread is waiting on. Gets initialized by\n        thread_initialize, can be used by thread itself.\n     */\n    wait_queue_head_t\tqueue;\n\n    /** Flag to tell thread whether to die or not.\n        When the thread receives a signal, it must check\n        the value of terminate and call thread_deinitialize and terminate\n        if set.\n     */\n    int terminate;    \n\n    /** Thread's entry. */\n    pj_thread_proc *func;\n\n    /** Argument. */\n    void *arg;\n};\n\nstruct pj_atomic_t\n{\n    atomic_t atom;\n};\n\nstruct pj_mutex_t\n{\n    struct semaphore sem;\n    pj_bool_t\t     recursive;\n    pj_thread_t\t    *owner;\n    int\t\t     own_count;\n};\n\nstruct pj_sem_t\n{\n    struct semaphore sem;\n};\n\n/*\n * Static global variables.\n */\n#define MAX_TLS_ID  32\nstatic void *tls_values[MAX_TLS_ID];\nstatic int tls_id;\nstatic long thread_tls_id;\nstatic spinlock_t critical_section = SPIN_LOCK_UNLOCKED;\nstatic unsigned long spinlock_flags;\nstatic pj_thread_t main_thread;\n\n/* private functions */\n//#define TRACE_(expr)\tPJ_LOG(3,expr)\n#define TRACE_(x)\n\n\n/* This must be called in the context of the new thread. */\nstatic void thread_initialize( pj_thread_t *thread )\n{\n    TRACE_((THIS_FILE, \"---new thread initializing...\"));\n\n    /* Set TLS */\n    pj_thread_local_set(thread_tls_id, thread);\n\n    /* fill in thread structure */\n    thread->thread = current;\n    pj_assert(thread->thread != NULL);\n\n    /* set signal mask to what we want to respond */\n    siginitsetinv(&current->blocked, \n\t\t  sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM));\n\n    /* initialise wait queue */\n    init_waitqueue_head(&thread->queue);\n\n    /* initialise termination flag */\n    thread->terminate = 0;\n\n    /* set name of this process (making sure obj_name is null \n     * terminated first) \n     */\n    thread->obj_name[PJ_MAX_OBJ_NAME-1] = '\\0';\n    sprintf(current->comm, thread->obj_name);\n        \n    /* tell the creator that we are ready and let him continue */\n    up(&thread->startstop_sem);\t\n}\n\n/* cleanup of thread. Called by the exiting thread. */\nstatic void thread_deinitialize(pj_thread_t *thread)\n{\n    /* we are terminating */\n\n    /* lock the kernel, the exit will unlock it */\n    thread->thread = NULL;\n    mb();\n\n    /* notify the stop_kthread() routine that we are terminating. */\n    up(&thread->startstop_sem);\n\n    /* the kernel_thread that called clone() does a do_exit here. */\n\n    /* there is no race here between execution of the \"killer\" and \n       real termination of the thread (race window between up and do_exit), \n       since both the thread and the \"killer\" function are running with \n       the kernel lock held.\n       The kernel lock will be freed after the thread exited, so the code\n       is really not executed anymore as soon as the unload functions gets\n       the kernel lock back.\n       The init process may not have made the cleanup of the process here,\n       but the cleanup can be done safely with the module unloaded.\n    */\n\n}\n\nstatic int thread_proc(void *arg)\n{\n    pj_thread_t *thread = arg;\n\n    TRACE_((THIS_FILE, \"---new thread starting!\"));\n\n    /* Initialize thread. */\n    thread_initialize( thread );\n\n    /* Wait if created suspended. */\n    if (thread->flags & PJ_THREAD_SUSPENDED) {\n\tTRACE_((THIS_FILE, \"---new thread suspended...\"));\n\tdown(&thread->suspend_sem);\n    }\n\n    TRACE_((THIS_FILE, \"---new thread running...\"));\n\n    pj_assert(thread->func != NULL);\n\n    /* Call thread's entry. */\n    (*thread->func)(thread->arg);\n\n    TRACE_((THIS_FILE, \"---thread exiting...\"));\n\n    /* Cleanup thread. */\n    thread_deinitialize(thread);\n\n    return 0;\n}\n\n/* The very task entry. */\nstatic void kthread_launcher(void *arg)\n{\n    TRACE_((THIS_FILE, \"...launching thread!...\"));\n    kernel_thread(&thread_proc, arg, 0);\n}\n\nPJ_DEF(pj_status_t) pj_init(void)\n{\n    pj_status_t rc;\n\n    PJ_LOG(5, (\"pj_init\", \"Initializing PJ Library..\"));\n\n    rc = pj_thread_init();\n    if (rc != PJ_SUCCESS)\n\treturn rc;\n\n    /* Initialize exception ID for the pool. \n     * Must do so after critical section is configured.\n     */\n    rc = pj_exception_id_alloc(\"PJLIB/No memory\", &PJ_NO_MEMORY_EXCEPTION);\n    if (rc != PJ_SUCCESS)\n        return rc;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_uint32_t) pj_getpid(void)\n{\n    return 1;\n}\n\nPJ_DEF(pj_status_t) pj_thread_register ( const char *cstr_thread_name,\n\t\t\t\t\t pj_thread_desc desc,\n\t\t\t\t\t pj_thread_t **ptr_thread)\n{\n    char stack_ptr;\n    pj_thread_t *thread = (pj_thread_t *)desc;\n    pj_str_t thread_name = pj_str((char*)cstr_thread_name);\n\n    /* Size sanity check. */\n    if (sizeof(pj_thread_desc) < sizeof(pj_thread_t)) {\n\tpj_assert(!\"Not enough pj_thread_desc size!\");\n\treturn PJ_EBUG;\n    }\n\n    /* If a thread descriptor has been registered before, just return it. */\n    if (pj_thread_local_get (thread_tls_id) != 0) {\n\t// 2006-02-26 bennylp:\n\t//  This wouldn't work in all cases!.\n\t//  If thread is created by external module (e.g. sound thread),\n\t//  thread may be reused while the pool used for the thread descriptor\n\t//  has been deleted by application.\n\t//*thread_ptr = (pj_thread_t*)pj_thread_local_get (thread_tls_id);\n        //return PJ_SUCCESS;\n    }\n\n    /* Initialize and set the thread entry. */\n    pj_bzero(desc, sizeof(struct pj_thread_t));\n\n    if(cstr_thread_name && pj_strlen(&thread_name) < sizeof(thread->obj_name)-1)\n\tpj_sprintf(thread->obj_name, cstr_thread_name, thread->thread);\n    else\n\tpj_snprintf(thread->obj_name, sizeof(thread->obj_name), \n\t\t    \"thr%p\", (void*)thread->thread);\n    \n    /* Initialize. */\n    thread_initialize(thread);\n\n    /* Eat semaphore. */\n    down(&thread->startstop_sem);\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n    thread->stk_start = &stack_ptr;\n    thread->stk_size = 0xFFFFFFFFUL;\n    thread->stk_max_usage = 0;\n#else\n    stack_ptr = '\\0';\n#endif\n\n    *ptr_thread = thread;\n    return PJ_SUCCESS;\n}\n\n\npj_status_t pj_thread_init(void)\n{\n    pj_status_t rc;\n    pj_thread_t *dummy;\n    \n    rc = pj_thread_local_alloc(&thread_tls_id);\n    if (rc != PJ_SUCCESS)\n\treturn rc;\n\n    return pj_thread_register(\"pjlib-main\", (long*)&main_thread, &dummy);\n}\n\nPJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool, const char *thread_name,\n\t\t\t\t      pj_thread_proc *proc, void *arg,\n\t\t\t\t      pj_size_t stack_size, unsigned flags,\n\t\t\t\t      pj_thread_t **ptr_thread)\n{\n    pj_thread_t *thread;\n\n    TRACE_((THIS_FILE, \"pj_thread_create()\"));\n    \n    PJ_ASSERT_RETURN(pool && proc && ptr_thread, PJ_EINVAL);\n\n    thread = pj_pool_zalloc(pool, sizeof(pj_thread_t));\n    if (!thread)\n\treturn PJ_ENOMEM;\n\n    PJ_UNUSED_ARG(stack_size);\n\n    /* Thread name. */\n    if (!thread_name) \n\tthread_name = \"thr%p\";\n    \n    if (strchr(thread_name, '%')) {\n\tpj_snprintf(thread->obj_name, PJ_MAX_OBJ_NAME, thread_name, thread);\n    } else {\n\tstrncpy(thread->obj_name, thread_name, PJ_MAX_OBJ_NAME);\n\tthread->obj_name[PJ_MAX_OBJ_NAME-1] = '\\0';\n    }\n    \n    /* Init thread's semaphore. */\n    TRACE_((THIS_FILE, \"...init semaphores...\"));\n    init_MUTEX_LOCKED(&thread->startstop_sem);\n    init_MUTEX_LOCKED(&thread->suspend_sem);\n\n    thread->flags = flags;\n\n    if ((flags & PJ_THREAD_SUSPENDED) == 0) {\n\tup(&thread->suspend_sem);\n    }\n\n    /* Store the functions and argument. */\n    thread->func = proc;\n    thread->arg = arg;\n    \n    /* Save return value. */\n    *ptr_thread = thread;\n    \n    /* Create the new thread by running a task through keventd. */\n\n#if 0\n    /* Initialize the task queue struct. */\n    thread->tq.sync = 0;\n    INIT_LIST_HEAD(&thread->tq.list);\n    thread->tq.routine = kthread_launcher;\n    thread->tq.data = thread;\n\n    /* and schedule it for execution. */\n    schedule_task(&thread->tq);\n#endif\n    kthread_launcher(thread);\n\n    /* Wait until thread has reached the setup_thread routine. */\n    TRACE_((THIS_FILE, \"...wait for the new thread...\"));\n    down(&thread->startstop_sem);\n\n    TRACE_((THIS_FILE, \"...main thread resumed...\"));\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(const char*) pj_thread_get_name(pj_thread_t *thread)\n{\n    return thread->obj_name;\n}\n\nPJ_DEF(pj_status_t) pj_thread_resume(pj_thread_t *thread)\n{\n    up(&thread->suspend_sem);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_thread_t*) pj_thread_this(void)\n{\n    return (pj_thread_t*)pj_thread_local_get(thread_tls_id);\n}\n\nPJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)\n{\n    TRACE_((THIS_FILE, \"pj_thread_join()\"));\n    down(&p->startstop_sem);\n    TRACE_((THIS_FILE, \"  joined!\"));\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_thread_destroy(pj_thread_t *thread)\n{\n    PJ_ASSERT_RETURN(thread != NULL, PJ_EINVALIDOP);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)\n{\n    pj_highprec_t ticks;\n    pj_thread_t *thread = pj_thread_this();\n\n    PJ_ASSERT_RETURN(thread != NULL, PJ_EBUG);\n    \n    /* Use high precision calculation to make sure we don't\n     * crop values:\n     *\n     *\tticks = HZ * msec / 1000\n     */\n    ticks = HZ;\n    pj_highprec_mul(ticks, msec);\n    pj_highprec_div(ticks, 1000);\n\n    TRACE_((THIS_FILE, \"this thread will sleep for %u ticks\", ticks));\n    interruptible_sleep_on_timeout( &thread->queue, ticks);\n    return PJ_SUCCESS;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\nPJ_DEF(pj_status_t) pj_atomic_create( pj_pool_t *pool, \n\t\t\t\t      pj_atomic_value_t value,\n\t\t\t\t      pj_atomic_t **ptr_var)\n{\n    pj_atomic_t *t = pj_pool_calloc(pool, 1, sizeof(pj_atomic_t));\n    if (!t) return PJ_ENOMEM;\n\n    atomic_set(&t->atom, value);\n    *ptr_var = t;\n    \n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_atomic_destroy( pj_atomic_t *var )\n{\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void) pj_atomic_set(pj_atomic_t *var, pj_atomic_value_t value)\n{\n    atomic_set(&var->atom, value);\n}\n\nPJ_DEF(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *var)\n{\n    return atomic_read(&var->atom);\n}\n\nPJ_DEF(void) pj_atomic_inc(pj_atomic_t *var)\n{\n    atomic_inc(&var->atom);\n}\n\nPJ_DEF(void) pj_atomic_dec(pj_atomic_t *var)\n{\n    atomic_dec(&var->atom);\n}\n\nPJ_DEF(void) pj_atomic_add( pj_atomic_t *var, pj_atomic_value_t value )\n{\n    atomic_add(value, &var->atom);\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\nPJ_DEF(pj_status_t) pj_thread_local_alloc(long *index)\n{\n    if (tls_id >= MAX_TLS_ID)\n\treturn PJ_ETOOMANY;\n    \n    *index = tls_id++;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void) pj_thread_local_free(long index)\n{\n    pj_assert(index >= 0 && index < MAX_TLS_ID);\n}\n\nPJ_DEF(pj_status_t) pj_thread_local_set(long index, void *value)\n{\n    pj_assert(index >= 0 && index < MAX_TLS_ID);\n    tls_values[index] = value;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void*) pj_thread_local_get(long index)\n{\n    pj_assert(index >= 0 && index < MAX_TLS_ID);\n    return tls_values[index];\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\nPJ_DEF(void) pj_enter_critical_section(void)\n{\n    spin_lock_irqsave(&critical_section, spinlock_flags);\n}\n\nPJ_DEF(void) pj_leave_critical_section(void)\n{\n    spin_unlock_irqrestore(&critical_section, spinlock_flags);\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\nPJ_DEF(pj_status_t) pj_mutex_create( pj_pool_t *pool, \n\t\t\t\t     const char *name, \n\t\t\t\t     int type,\n\t\t\t\t     pj_mutex_t **ptr_mutex)\n{\n    pj_mutex_t *mutex;\n    \n    PJ_UNUSED_ARG(name);\n\n    mutex = pj_pool_alloc(pool, sizeof(pj_mutex_t));\n    if (!mutex)\n\treturn PJ_ENOMEM;\n\n    init_MUTEX(&mutex->sem);\n\n    mutex->recursive = (type == PJ_MUTEX_RECURSE);\n    mutex->owner = NULL;\n    mutex->own_count = 0;\n    \n    /* Done. */\n    *ptr_mutex = mutex;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,\n\t\t\t\t\t    pj_mutex_t **mutex )\n{\n    return pj_mutex_create(pool, name, PJ_MUTEX_SIMPLE, mutex);\n}\n\nPJ_DEF(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,\n\t\t\t\t\t       const char *name,\n\t\t\t\t\t       pj_mutex_t **mutex )\n{\n    return pj_mutex_create( pool, name, PJ_MUTEX_RECURSE, mutex);\n}\n\nPJ_DEF(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex)\n{\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n\n    if (mutex->recursive) {\n\tpj_thread_t *this_thread = pj_thread_this();\n\tif (mutex->owner == this_thread) {\n\t    ++mutex->own_count;\n\t} else {\n\t    down(&mutex->sem);\n\t    pj_assert(mutex->own_count == 0);\n\t    mutex->owner = this_thread;\n\t    mutex->own_count = 1;\n\t}\n    } else {\n\tdown(&mutex->sem);\n    }\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex)\n{\n    long rc;\n\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n\n    if (mutex->recursive) {\n\tpj_thread_t *this_thread = pj_thread_this();\n\tif (mutex->owner == this_thread) {\n\t    ++mutex->own_count;\n\t} else {\n\t    rc = down_interruptible(&mutex->sem);\n\t    if (rc != 0)\n\t\treturn PJ_RETURN_OS_ERROR(-rc);\n\t    pj_assert(mutex->own_count == 0);\n\t    mutex->owner = this_thread;\n\t    mutex->own_count = 1;\n\t}\n    } else {\n\tint rc = down_trylock(&mutex->sem);\n\tif (rc != 0)\n\t    return PJ_RETURN_OS_ERROR(-rc);\n    }\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex)\n{\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n\n    if (mutex->recursive) {\n\tpj_thread_t *this_thread = pj_thread_this();\n\tif (mutex->owner == this_thread) {\n\t    pj_assert(mutex->own_count > 0);\n\t    --mutex->own_count;\n\t    if (mutex->own_count == 0) {\n\t\tmutex->owner = NULL;\n\t\tup(&mutex->sem);\n\t    }\n\t} else {\n\t    pj_assert(!\"Not owner!\");\n\t    return PJ_EINVALIDOP;\n\t}\n    } else {\n\tup(&mutex->sem);\n    }\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex)\n{\n    PJ_ASSERT_RETURN(mutex != NULL, PJ_EINVAL);\n\n    return PJ_SUCCESS;\n}\n\n#if defined(PJ_DEBUG) && PJ_DEBUG != 0\nPJ_DEF(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex)\n{\n    if (mutex->recursive)\n\treturn mutex->owner == pj_thread_this();\n    else\n\treturn 1;\n}\n#endif\t/* PJ_DEBUG */\n\n\n#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0\n\nPJ_DEF(pj_status_t) pj_sem_create(  pj_pool_t *pool, \n                                    const char *name,\n\t\t\t\t    unsigned initial, \n                                    unsigned max,\n\t\t\t\t    pj_sem_t **sem)\n{\n    pj_sem_t *sem;\n\n    PJ_UNUSED_ARG(max);\n\n    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);\n    \n    sem = pj_pool_alloc(pool, sizeof(pj_sem_t));\n    sema_init(&sem->sem, initial);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_sem_wait(pj_sem_t *sem)\n{\n    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);\n\n    down(&sem->sem);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_sem_trywait(pj_sem_t *sem)\n{\n    int rc;\n\n    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);\n\n    rc = down_trylock(&sem->sem);\n    if (rc != 0) {\n\treturn PJ_RETURN_OS_ERROR(-rc);\n    } else {\n\treturn PJ_SUCCESS;\n    }\n}\n\nPJ_DEF(pj_status_t) pj_sem_post(pj_sem_t *sem)\n{\n    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);\n\n    up(&sem->sem);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_sem_destroy(pj_sem_t *sem)\n{\n    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJ_HAS_SEMAPHORE */\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_core_symbian.cpp",
    "content": "/* $Id: os_core_symbian.cpp 3999 2012-03-30 07:10:13Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pj/os.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n#include <pj/log.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n#include <pj/guid.h>\n#include <pj/except.h>\n#include <pj/errno.h>\n\n#include \"os_symbian.h\"\n\n\n#define PJ_MAX_TLS\t    32\n#define DUMMY_MUTEX\t    ((pj_mutex_t*)101)\n#define DUMMY_SEMAPHORE\t    ((pj_sem_t*)102)\n#define THIS_FILE\t    \"os_core_symbian.c\"\n\n/* Default message slot number for RSocketServ::Connect().\n * Increase it to 32 from the default 8 (KESockDefaultMessageSlots)\n */\n#ifndef PJ_SYMBIAN_SOCK_MSG_SLOTS\n#  define PJ_SYMBIAN_SOCK_MSG_SLOTS  32\n#endif\n\n/*\n * Note:\n *\n * The Symbian implementation does not support threading!\n */ \n\nstruct pj_thread_t\n{\n    char\t    obj_name[PJ_MAX_OBJ_NAME];\n    void\t   *tls_values[PJ_MAX_TLS];\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n    pj_uint32_t\t    stk_size;\n    pj_uint32_t\t    stk_max_usage;\n    char\t   *stk_start;\n    const char\t   *caller_file;\n    int\t\t    caller_line;\n#endif\n\n} main_thread;\n\nstruct pj_atomic_t\n{\n    pj_atomic_value_t\tvalue;\n};\n\nstruct pj_sem_t\n{\n    int value;\n    int max;\n};\n\n/* Flag and reference counter for PJLIB instance */\nstatic int initialized;\n\n/* Flags to indicate which TLS variables have been used */\nstatic int tls_vars[PJ_MAX_TLS];\n\n/* atexit handlers */\nstatic unsigned atexit_count;\nstatic void (*atexit_func[32])(void);\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// CPjTimeoutTimer implementation\n//\n\nCPjTimeoutTimer::CPjTimeoutTimer()\n: CActive(PJ_SYMBIAN_TIMER_PRIORITY), hasTimedOut_(PJ_FALSE)\n{\n}\n\nCPjTimeoutTimer::~CPjTimeoutTimer()\n{\n    Cancel();\n    timer_.Close();\n}\n\nvoid CPjTimeoutTimer::ConstructL()\n{\n    hasTimedOut_ = PJ_FALSE;\n    timer_.CreateLocal();\n    CActiveScheduler::Add(this);\n}\n\nCPjTimeoutTimer *CPjTimeoutTimer::NewL()\n{\n    CPjTimeoutTimer *self = new CPjTimeoutTimer;\n    CleanupStack::PushL(self);\n\n    self->ConstructL();\n\n    CleanupStack::Pop(self);\n    return self;\n\n}\n\nvoid CPjTimeoutTimer::StartTimer(TUint miliSeconds)\n{\n    Cancel();\n\n    hasTimedOut_ = PJ_FALSE;\n    timer_.After(iStatus, miliSeconds * 1000);\n    SetActive();\n}\n\nbool CPjTimeoutTimer::HasTimedOut() const\n{\n    return hasTimedOut_ != 0;\n}\n\nvoid CPjTimeoutTimer::RunL()\n{\n    hasTimedOut_ = PJ_TRUE;\n}\n\nvoid CPjTimeoutTimer::DoCancel()\n{\n    timer_.Cancel();\n}\n\nTInt CPjTimeoutTimer::RunError(TInt aError)\n{\n    PJ_UNUSED_ARG(aError);\n    return KErrNone;\n}\n\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// PjSymbianOS implementation\n//\n\nPjSymbianOS::PjSymbianOS()\n: isConnectionUp_(false),\n  isSocketServInitialized_(false), isResolverInitialized_(false),\n  console_(NULL), selectTimeoutTimer_(NULL),\n  appSocketServ_(NULL), appConnection_(NULL), appHostResolver_(NULL),\n  appHostResolver6_(NULL)\n{\n}\n\n// Set parameters\nvoid PjSymbianOS::SetParameters(pj_symbianos_params *params) \n{\n    appSocketServ_ = (RSocketServ*) params->rsocketserv;\n    appConnection_ = (RConnection*) params->rconnection;\n    appHostResolver_ = (RHostResolver*) params->rhostresolver;\n    appHostResolver6_ = (RHostResolver*) params->rhostresolver6;\n}\n\n// Get PjSymbianOS instance\nPjSymbianOS *PjSymbianOS::Instance()\n{\n    static PjSymbianOS instance_;\n    return &instance_;\n}\n\n\n// Initialize\nTInt PjSymbianOS::Initialize()\n{\n    TInt err;\n\n    selectTimeoutTimer_ = CPjTimeoutTimer::NewL();\n\n#if 0\n    pj_assert(console_ == NULL);\n    TRAPD(err, console_ = Console::NewL(_L(\"PJLIB\"), \n\t\t\t\t        TSize(KConsFullScreen,KConsFullScreen)));\n    return err;\n#endif\n\n    /* Only create RSocketServ if application doesn't specify it\n     * in the parameters\n     */\n    if (!isSocketServInitialized_ && appSocketServ_ == NULL) {\n\terr = socketServ_.Connect(PJ_SYMBIAN_SOCK_MSG_SLOTS);\n\tif (err != KErrNone)\n\t    goto on_error;\n\n\tisSocketServInitialized_ = true;\n    }\n\n    if (!isResolverInitialized_) {\n    \tif (appHostResolver_ == NULL) {\n    \t    if (Connection())\n    \t    \terr = hostResolver_.Open(SocketServ(), KAfInet, KSockStream,\n    \t    \t\t\t     \t *Connection());\n    \t    else\n\t    \terr = hostResolver_.Open(SocketServ(), KAfInet, KSockStream);\n    \t\n\t    if (err != KErrNone)\n\t    \tgoto on_error;\n    \t}\n    \t\n#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0\n    \tif (appHostResolver6_ == NULL) {\n    \t    if (Connection())\n    \t    \terr = hostResolver6_.Open(SocketServ(), KAfInet6, KSockStream,\n    \t    \t\t\t     \t  *Connection());\n    \t    else\n\t    \terr = hostResolver6_.Open(SocketServ(), KAfInet6, KSockStream);\n    \t\n\t    if (err != KErrNone)\n\t    \tgoto on_error;\n    \t}\n#endif\n    \t\n    \t\n\tisResolverInitialized_ = true;\n    }\n\n    isConnectionUp_ = true;\n    \n    return KErrNone;\n\non_error:\n    Shutdown();\n    return err;\n}\n\n// Shutdown\nvoid PjSymbianOS::Shutdown()\n{\n    isConnectionUp_ = false;\n    \n    if (isResolverInitialized_) {\n\t\thostResolver_.Close();\n#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0\n    \thostResolver6_.Close();\n#endif\n    \tisResolverInitialized_ = false;\n    }\n\n    if (isSocketServInitialized_) {\n\tsocketServ_.Close();\n\tisSocketServInitialized_ = false;\n    }\n\n    delete console_;\n    console_ = NULL;\n\n    delete selectTimeoutTimer_;\n    selectTimeoutTimer_ = NULL;\n    \n    appSocketServ_ = NULL;\n    appConnection_ = NULL;\n    appHostResolver_ = NULL;\n    appHostResolver6_ = NULL;\n}\n\n// Convert to Unicode\nTInt PjSymbianOS::ConvertToUnicode(TDes16 &aUnicode, const TDesC8 &aForeign)\n{\n#if 0\n    pj_assert(conv_ != NULL);\n    return conv_->ConvertToUnicode(aUnicode, aForeign, convToUnicodeState_);\n#else\n    return CnvUtfConverter::ConvertToUnicodeFromUtf8(aUnicode, aForeign);\n#endif\n}\n\n// Convert from Unicode\nTInt PjSymbianOS::ConvertFromUnicode(TDes8 &aForeign, const TDesC16 &aUnicode)\n{\n#if 0\n    pj_assert(conv_ != NULL);\n    return conv_->ConvertFromUnicode(aForeign, aUnicode, convToAnsiState_);\n#else\n    return CnvUtfConverter::ConvertFromUnicodeToUtf8(aForeign, aUnicode);\n#endif\n}\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// PJLIB os.h implementation\n//\n\nPJ_DEF(pj_uint32_t) pj_getpid(void)\n{\n    return 0;\n}\n\n\n/* Set Symbian specific parameters */\nPJ_DEF(pj_status_t) pj_symbianos_set_params(pj_symbianos_params *prm) \n{\n    PJ_ASSERT_RETURN(prm != NULL, PJ_EINVAL);\n    PjSymbianOS::Instance()->SetParameters(prm);\n    return PJ_SUCCESS;\n}\n\n\n/* Set connection status */\nPJ_DEF(void) pj_symbianos_set_connection_status(pj_bool_t up)\n{\n    PjSymbianOS::Instance()->SetConnectionStatus(up != 0);\n}\n\n\n/*\n * pj_init(void).\n * Init PJLIB!\n */\nPJ_DEF(pj_status_t) pj_init(void)\n{\n\tchar stack_ptr;\n    pj_status_t status;\n    \n    /* Check if PJLIB have been initialized */\n    if (initialized) {\n\t++initialized;\n\treturn PJ_SUCCESS;\n    }\n\n    pj_ansi_strcpy(main_thread.obj_name, \"pjthread\");\n\n    // Init main thread\n    pj_memset(&main_thread, 0, sizeof(main_thread));\n\n    // Initialize PjSymbianOS instance\n    PjSymbianOS *os = PjSymbianOS::Instance();\n\n    PJ_LOG(4,(THIS_FILE, \"Initializing PJLIB for Symbian OS..\"));\n\n    TInt err; \n    err = os->Initialize();\n    if (err != KErrNone)\n    \treturn PJ_RETURN_OS_ERROR(err);\n\n    /* Init logging */\n    pj_log_init();\n\n    /* Initialize exception ID for the pool. \n     * Must do so after critical section is configured.\n     */ \n    status = pj_exception_id_alloc(\"PJLIB/No memory\", &PJ_NO_MEMORY_EXCEPTION);\n    if (status != PJ_SUCCESS)\n        goto on_error;\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n    main_thread.stk_start = &stack_ptr;\n    main_thread.stk_size = 0xFFFFFFFFUL;\n    main_thread.stk_max_usage = 0;\n#else\n    stack_ptr = '\\0';\n#endif\n\n    /* Flag PJLIB as initialized */\n    ++initialized;\n    pj_assert(initialized == 1);\n\n    PJ_LOG(5,(THIS_FILE, \"PJLIB initialized.\"));\n    return PJ_SUCCESS;\n\non_error:\n    pj_shutdown();\n    return PJ_RETURN_OS_ERROR(err);\n}\n\n\nPJ_DEF(pj_status_t) pj_atexit(pj_exit_callback func)\n{\n    if (atexit_count >= PJ_ARRAY_SIZE(atexit_func))\n\treturn PJ_ETOOMANY;\n\n    atexit_func[atexit_count++] = func;\n    return PJ_SUCCESS;\n}\n\n\n\nPJ_DEF(void) pj_shutdown(void)\n{\n    /* Only perform shutdown operation when 'initialized' reaches zero */\n    pj_assert(initialized > 0);\n    if (--initialized != 0)\n\treturn;\n\n    /* Call atexit() functions */\n    while (atexit_count > 0) {\n\t(*atexit_func[atexit_count-1])();\n\t--atexit_count;\n    }\n\n    /* Free exception ID */\n    if (PJ_NO_MEMORY_EXCEPTION != -1) {\n\tpj_exception_id_free(PJ_NO_MEMORY_EXCEPTION);\n\tPJ_NO_MEMORY_EXCEPTION = -1;\n    }\n\n    /* Clear static variables */\n    pj_errno_clear_handlers();\n\n    PjSymbianOS *os = PjSymbianOS::Instance();\n    os->Shutdown();\n}\n\n/////////////////////////////////////////////////////////////////////////////\n\nclass CPollTimeoutTimer : public CActive \n{\npublic:\n    static CPollTimeoutTimer* NewL(int msec, TInt prio);\n    ~CPollTimeoutTimer();\n    \n    virtual void RunL();\n    virtual void DoCancel();\n\nprivate:\t\n    RTimer\t     rtimer_;\n    \n    explicit CPollTimeoutTimer(TInt prio);\n    void ConstructL(int msec);\n};\n\nCPollTimeoutTimer::CPollTimeoutTimer(TInt prio)\n: CActive(prio)\n{\n}\n\n\nCPollTimeoutTimer::~CPollTimeoutTimer() \n{\n    rtimer_.Close();\n}\n\nvoid CPollTimeoutTimer::ConstructL(int msec) \n{\n    rtimer_.CreateLocal();\n    CActiveScheduler::Add(this);\n    rtimer_.After(iStatus, msec*1000);\n    SetActive();\n}\n\nCPollTimeoutTimer* CPollTimeoutTimer::NewL(int msec, TInt prio) \n{\n    CPollTimeoutTimer *self = new CPollTimeoutTimer(prio);\n    CleanupStack::PushL(self);\n    self->ConstructL(msec);    \n    CleanupStack::Pop(self);\n\n    return self;\n}\n\nvoid CPollTimeoutTimer::RunL() \n{\n}\n\nvoid CPollTimeoutTimer::DoCancel() \n{\n     rtimer_.Cancel();\n}\n\n\n/*\n * Wait the completion of any Symbian active objects. \n */\nPJ_DEF(pj_bool_t) pj_symbianos_poll(int priority, int ms_timeout)\n{\n    CPollTimeoutTimer *timer = NULL;\n    \n    if (priority==-1)\n    \tpriority = EPriorityNull;\n    \n    if (ms_timeout >= 0) {\n    \ttimer = CPollTimeoutTimer::NewL(ms_timeout, priority);\n    }\n    \n    PjSymbianOS::Instance()->WaitForActiveObjects(priority);\n    \n    if (timer) {\n        bool timer_is_active = timer->IsActive();\n    \n\ttimer->Cancel();\n        \n        delete timer;\n        \n    \treturn timer_is_active ? PJ_TRUE : PJ_FALSE;\n    \t\n    } else {\n    \treturn PJ_TRUE;\n    }\n}\n\n\n/*\n * pj_thread_is_registered()\n */\nPJ_DEF(pj_bool_t) pj_thread_is_registered(void)\n{\n    return PJ_FALSE;\n}\n\n\n/*\n * Get thread priority value for the thread.\n */\nPJ_DEF(int) pj_thread_get_prio(pj_thread_t *thread)\n{\n    PJ_UNUSED_ARG(thread);\n    return 1;\n}\n\n\n/*\n * Set the thread priority.\n */\nPJ_DEF(pj_status_t) pj_thread_set_prio(pj_thread_t *thread,  int prio)\n{\n    PJ_UNUSED_ARG(thread);\n    PJ_UNUSED_ARG(prio);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the lowest priority value available on this system.\n */\nPJ_DEF(int) pj_thread_get_prio_min(pj_thread_t *thread)\n{\n    PJ_UNUSED_ARG(thread);\n    return 1;\n}\n\n\n/*\n * Get the highest priority value available on this system.\n */\nPJ_DEF(int) pj_thread_get_prio_max(pj_thread_t *thread)\n{\n    PJ_UNUSED_ARG(thread);\n    return 1;\n}\n\n\n/*\n * pj_thread_get_os_handle()\n */\nPJ_DEF(void*) pj_thread_get_os_handle(pj_thread_t *thread) \n{\n    PJ_UNUSED_ARG(thread);\n    return NULL;\n}\n\n/*\n * pj_thread_register(..)\n */\nPJ_DEF(pj_status_t) pj_thread_register ( const char *cstr_thread_name,\n\t\t\t\t\t pj_thread_desc desc,\n                                         pj_thread_t **thread_ptr)\n{\n    PJ_UNUSED_ARG(cstr_thread_name);\n    PJ_UNUSED_ARG(desc);\n    PJ_UNUSED_ARG(thread_ptr);\n    return PJ_EINVALIDOP;\n}\n\n\n/*\n * pj_thread_create(...)\n */\nPJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool, \n\t\t\t\t      const char *thread_name,\n\t\t\t\t      pj_thread_proc *proc, \n\t\t\t\t      void *arg,\n\t\t\t\t      pj_size_t stack_size, \n\t\t\t\t      unsigned flags,\n\t\t\t\t      pj_thread_t **ptr_thread)\n{\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(thread_name);\n    PJ_UNUSED_ARG(proc);\n    PJ_UNUSED_ARG(arg);\n    PJ_UNUSED_ARG(stack_size);\n    PJ_UNUSED_ARG(flags);\n    PJ_UNUSED_ARG(ptr_thread);\n\n    /* Sorry mate, we don't support threading */\n    return PJ_ENOTSUP;\n}\n\n/*\n * pj_thread-get_name()\n */\nPJ_DEF(const char*) pj_thread_get_name(pj_thread_t *p)\n{\n    pj_assert(p == &main_thread);\n    return p->obj_name;\n}\n\n/*\n * pj_thread_resume()\n */\nPJ_DEF(pj_status_t) pj_thread_resume(pj_thread_t *p)\n{\n    PJ_UNUSED_ARG(p);\n    return PJ_EINVALIDOP;\n}\n\n/*\n * pj_thread_this()\n */\nPJ_DEF(pj_thread_t*) pj_thread_this(void)\n{\n    return &main_thread;\n}\n\n/*\n * pj_thread_join()\n */\nPJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *rec)\n{\n    PJ_UNUSED_ARG(rec);\n    return PJ_EINVALIDOP;\n}\n\n/*\n * pj_thread_destroy()\n */\nPJ_DEF(pj_status_t) pj_thread_destroy(pj_thread_t *rec)\n{\n    PJ_UNUSED_ARG(rec);\n    return PJ_EINVALIDOP;\n}\n\n/*\n * pj_thread_sleep()\n */\nPJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)\n{\n    User::After(msec*1000);\n\n    return PJ_SUCCESS;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * pj_thread_local_alloc()\n */\n\nPJ_DEF(pj_status_t) pj_thread_local_alloc(long *index)\n{\n    unsigned i;\n\n    /* Find unused TLS variable */\n    for (i=0; i<PJ_ARRAY_SIZE(tls_vars); ++i) {\n\tif (tls_vars[i] == 0)\n\t    break;\n    }\n\n    if (i == PJ_ARRAY_SIZE(tls_vars))\n\treturn PJ_ETOOMANY;\n\n    tls_vars[i] = 1;\n    *index = i;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_thread_local_free()\n */\nPJ_DEF(void) pj_thread_local_free(long index)\n{\n    PJ_ASSERT_ON_FAIL(index >= 0 && index < (int)PJ_ARRAY_SIZE(tls_vars) &&\n\t\t     tls_vars[index] != 0, return);\n\n    tls_vars[index] = 0;\n}\n\n\n/*\n * pj_thread_local_set()\n */\nPJ_DEF(pj_status_t) pj_thread_local_set(long index, void *value)\n{\n    pj_thread_t *rec = pj_thread_this();\n\n    PJ_ASSERT_RETURN(index >= 0 && index < (int)PJ_ARRAY_SIZE(tls_vars) &&\n\t\t     tls_vars[index] != 0, PJ_EINVAL);\n\n    rec->tls_values[index] = value;\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_thread_local_get()\n */\nPJ_DEF(void*) pj_thread_local_get(long index)\n{\n    pj_thread_t *rec = pj_thread_this();\n\n    PJ_ASSERT_RETURN(index >= 0 && index < (int)PJ_ARRAY_SIZE(tls_vars) &&\n\t\t     tls_vars[index] != 0, NULL);\n\n    return rec->tls_values[index];\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Create atomic variable.\n */\nPJ_DEF(pj_status_t) pj_atomic_create( pj_pool_t *pool, \n\t\t\t\t      pj_atomic_value_t initial,\n\t\t\t\t      pj_atomic_t **atomic )\n{\n    *atomic = (pj_atomic_t*)pj_pool_alloc(pool, sizeof(struct pj_atomic_t));\n    (*atomic)->value = initial;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy atomic variable.\n */\nPJ_DEF(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var )\n{\n    PJ_UNUSED_ARG(atomic_var);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Set the value of an atomic type, and return the previous value.\n */\nPJ_DEF(void) pj_atomic_set( pj_atomic_t *atomic_var, \n\t\t\t    pj_atomic_value_t value)\n{\n    atomic_var->value = value;\n}\n\n\n/*\n * Get the value of an atomic type.\n */\nPJ_DEF(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var)\n{\n    return atomic_var->value;\n}\n\n\n/*\n * Increment the value of an atomic type.\n */\nPJ_DEF(void) pj_atomic_inc(pj_atomic_t *atomic_var)\n{\n    ++atomic_var->value;\n}\n\n\n/*\n * Increment the value of an atomic type and get the result.\n */\nPJ_DEF(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var)\n{\n    return ++atomic_var->value;\n}\n\n\n/*\n * Decrement the value of an atomic type.\n */\nPJ_DEF(void) pj_atomic_dec(pj_atomic_t *atomic_var)\n{\n    --atomic_var->value;\n}\t\n\n\n/*\n * Decrement the value of an atomic type and get the result.\n */\nPJ_DEF(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var)\n{\n    return --atomic_var->value;\n}\n\n\n/*\n * Add a value to an atomic type.\n */\nPJ_DEF(void) pj_atomic_add( pj_atomic_t *atomic_var,\n\t\t\t    pj_atomic_value_t value)\n{\n    atomic_var->value += value;\n}\n\n\n/*\n * Add a value to an atomic type and get the result.\n */\nPJ_DEF(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,\n\t\t\t                         pj_atomic_value_t value)\n{\n    atomic_var->value += value;\n    return atomic_var->value;\n}\n\n\n\n/////////////////////////////////////////////////////////////////////////////\n\nPJ_DEF(pj_status_t) pj_mutex_create( pj_pool_t *pool, \n                                     const char *name,\n\t\t\t\t     int type, \n                                     pj_mutex_t **mutex)\n{\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(name);\n    PJ_UNUSED_ARG(type);\n\n    *mutex = DUMMY_MUTEX;\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_mutex_create_simple()\n */\nPJ_DEF(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, \n                                            const char *name,\n\t\t\t\t\t    pj_mutex_t **mutex )\n{\n    return pj_mutex_create(pool, name, PJ_MUTEX_SIMPLE, mutex);\n}\n\n\nPJ_DEF(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,\n\t\t\t\t\t       const char *name,\n\t\t\t\t\t       pj_mutex_t **mutex )\n{\n    return pj_mutex_create(pool, name, PJ_MUTEX_RECURSE, mutex);\n}\n\n\n/*\n * pj_mutex_lock()\n */\nPJ_DEF(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex)\n{\n    pj_assert(mutex == DUMMY_MUTEX);\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_mutex_trylock()\n */\nPJ_DEF(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex)\n{\n    pj_assert(mutex == DUMMY_MUTEX);\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_mutex_unlock()\n */\nPJ_DEF(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex)\n{\n    pj_assert(mutex == DUMMY_MUTEX);\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_mutex_destroy()\n */\nPJ_DEF(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex)\n{\n    pj_assert(mutex == DUMMY_MUTEX);\n    return PJ_SUCCESS;\n}\n\n\n/////////////////////////////////////////////////////////////////////////////\n/*\n * RW Mutex\n */\n#include \"os_rwmutex.c\"\n\n\n/////////////////////////////////////////////////////////////////////////////\n\n/*\n * Enter critical section.\n */\nPJ_DEF(void) pj_enter_critical_section(void)\n{\n    /* Nothing to do */\n}\n\n\n/*\n * Leave critical section.\n */\nPJ_DEF(void) pj_leave_critical_section(void)\n{\n    /* Nothing to do */\n}\n\n\n/////////////////////////////////////////////////////////////////////////////\n\n/*\n * Create semaphore.\n */\nPJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool, \n                                   const char *name,\n\t\t\t\t   unsigned initial, \n                                   unsigned max,\n\t\t\t\t   pj_sem_t **p_sem)\n{\n    pj_sem_t *sem;\n \n    PJ_UNUSED_ARG(name);\n\n    sem = (pj_sem_t*) pj_pool_zalloc(pool, sizeof(pj_sem_t));\n    sem->value = initial;\n    sem->max = max;\n\n    *p_sem = sem;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Wait for semaphore.\n */\nPJ_DEF(pj_status_t) pj_sem_wait(pj_sem_t *sem)\n{\n    if (sem->value > 0) {\n\tsem->value--;\n\treturn PJ_SUCCESS;\n    } else {\n\tpj_assert(!\"Unexpected!\");\n\treturn PJ_EINVALIDOP;\n    }\n}\n\n\n/*\n * Try wait for semaphore.\n */\nPJ_DEF(pj_status_t) pj_sem_trywait(pj_sem_t *sem)\n{\n    if (sem->value > 0) {\n\tsem->value--;\n\treturn PJ_SUCCESS;\n    } else {\n\tpj_assert(!\"Unexpected!\");\n\treturn PJ_EINVALIDOP;\n    }\n}\n\n\n/*\n * Release semaphore.\n */\nPJ_DEF(pj_status_t) pj_sem_post(pj_sem_t *sem)\n{\n    sem->value++;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy semaphore.\n */\nPJ_DEF(pj_status_t) pj_sem_destroy(pj_sem_t *sem)\n{\n    PJ_UNUSED_ARG(sem);\n    return PJ_SUCCESS;\n}\n\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK != 0\n/*\n * The implementation of stack checking. \n */\nPJ_DEF(void) pj_thread_check_stack(const char *file, int line)\n{\n    char stk_ptr;\n    pj_uint32_t usage;\n    pj_thread_t *thread = pj_thread_this();\n\n    pj_assert(thread);\n\n    /* Calculate current usage. */\n    usage = (&stk_ptr > thread->stk_start) ? &stk_ptr - thread->stk_start :\n\t\tthread->stk_start - &stk_ptr;\n\n    /* Assert if stack usage is dangerously high. */\n    pj_assert(\"STACK OVERFLOW!! \" && (usage <= thread->stk_size - 128));\n\n    /* Keep statistic. */\n    if (usage > thread->stk_max_usage) {\n\tthread->stk_max_usage = usage;\n\tthread->caller_file = file;\n\tthread->caller_line = line;\n    }\n}\n\n/*\n * Get maximum stack usage statistic. \n */\nPJ_DEF(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread)\n{\n    return thread->stk_max_usage;\n}\n\n/*\n * Dump thread stack status. \n */\nPJ_DEF(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,\n\t\t\t\t\t     const char **file,\n\t\t\t\t\t     int *line)\n{\n    pj_assert(thread);\n\n    *file = thread->caller_file;\n    *line = thread->caller_line;\n    return 0;\n}\n\n#endif\t/* PJ_OS_HAS_CHECK_STACK */\n\n/*\n * pj_run_app()\n */\nPJ_DEF(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],\n                       unsigned flags)\n{\n    return (*main_func)(argc, argv);\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_core_unix.c",
    "content": "/* $Id: os_core_unix.c 4359 2013-02-21 11:18:36Z bennylp $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n/*\n * Contributors:\n * - Thanks for Zetron, Inc. (Phil Torre, ptorre@zetron.com) for donating\n *   the RTEMS port.\n */\n#ifndef _GNU_SOURCE\n#   define _GNU_SOURCE\n#endif\n#include <pj/os.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n#include <pj/log.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n#include <pj/guid.h>\n#include <pj/except.h>\n#include <pj/errno.h>\n\n#if defined(PJ_HAS_SEMAPHORE_H) && PJ_HAS_SEMAPHORE_H != 0\n#  include <semaphore.h>\n#  if defined(PJ_DARWINOS) && PJ_DARWINOS!=0\n#    include <mach/mach.h>\n#    include <mach/task.h>\n#    include <mach/semaphore.h>\n#  endif\n#endif\n\n#include <unistd.h>\t    // getpid()\n#include <errno.h>\t    // errno\n\n#include <pthread.h>\n\n#define THIS_FILE   \"os_core_unix.c\"\n\n#define SIGNATURE1  0xDEAFBEEF\n#define SIGNATURE2  0xDEADC0DE\n\n#ifndef PJ_JNI_HAS_JNI_ONLOAD\n#  define PJ_JNI_HAS_JNI_ONLOAD    PJ_ANDROID\n#endif\n\n#if defined(PJ_JNI_HAS_JNI_ONLOAD) && PJ_JNI_HAS_JNI_ONLOAD != 0\n\n#include <jni.h>\n\nJavaVM *pj_jni_jvm = NULL;\n\nJNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)\n{\n    pj_jni_jvm = vm;\n    \n    return JNI_VERSION_1_4;\n}\n#endif\n\nstruct pj_thread_t\n{\n    char\t    obj_name[PJ_MAX_OBJ_NAME];\n    pthread_t\t    thread;\n    pj_thread_proc *proc;\n    void\t   *arg;\n    pj_uint32_t\t    signature1;\n    pj_uint32_t\t    signature2;\n\n    pj_mutex_t\t   *suspended_mutex;\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n    pj_uint32_t\t    stk_size;\n    pj_uint32_t\t    stk_max_usage;\n    char\t   *stk_start;\n    const char\t   *caller_file;\n    int\t\t    caller_line;\n#endif\n};\n\nstruct pj_atomic_t\n{\n    pj_mutex_t\t       *mutex;\n    pj_atomic_value_t\tvalue;\n};\n\nstruct pj_mutex_t\n{\n    pthread_mutex_t     mutex;\n    char\t\tobj_name[PJ_MAX_OBJ_NAME];\n#if PJ_DEBUG\n    int\t\t        nesting_level;\n    pj_thread_t\t       *owner;\n    char\t\towner_name[PJ_MAX_OBJ_NAME];\n#endif\n};\n\n#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0\nstruct pj_sem_t\n{\n#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0\n    semaphore_t        *sem;\n#else\n    sem_t\t       *sem;\n#endif\n    char\t\tobj_name[PJ_MAX_OBJ_NAME];\n};\n#endif /* PJ_HAS_SEMAPHORE */\n\n#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0\nstruct pj_event_t\n{\n    enum event_state {\n\tEV_STATE_OFF,\n\tEV_STATE_SET,\n\tEV_STATE_PULSED\n    } state;\n\n    pj_mutex_t\t\tmutex;\n    pthread_cond_t\tcond;\n\n    pj_bool_t\t\tauto_reset;\n    unsigned\t\tthreads_waiting;\n    unsigned\t\tthreads_to_release;\n};\n#endif\t/* PJ_HAS_EVENT_OBJ */\n\n\n/*\n * Flag and reference counter for PJLIB instance.\n */\nstatic int initialized;\n\n#if PJ_HAS_THREADS\n    static pj_thread_t main_thread;\n    static long thread_tls_id;\n    static pj_mutex_t critical_section;\n#else\n#   define MAX_THREADS 32\n    static int tls_flag[MAX_THREADS];\n    static void *tls[MAX_THREADS];\n#endif\n\nstatic unsigned atexit_count;\nstatic void (*atexit_func[32])(void);\n\nstatic pj_status_t init_mutex(pj_mutex_t *mutex, const char *name, int type);\n\n/*\n * pj_init(void).\n * Init PJLIB!\n */\nPJ_DEF(pj_status_t) pj_init(void)\n{\n    char dummy_guid[PJ_GUID_MAX_LENGTH];\n    pj_str_t guid;\n    pj_status_t rc;\n\n    /* Check if PJLIB have been initialized */\n    if (initialized) {\n\t++initialized;\n\treturn PJ_SUCCESS;\n    }\n\n#if PJ_HAS_THREADS\n    /* Init this thread's TLS. */\n    if ((rc=pj_thread_init()) != 0) {\n\treturn rc;\n    }\n\n    /* Critical section. */\n    if ((rc=init_mutex(&critical_section, \"critsec\", PJ_MUTEX_RECURSE)) != 0)\n\treturn rc;\n\n#endif\n\n    /* Init logging */\n    pj_log_init();\n\n    /* Initialize exception ID for the pool.\n     * Must do so after critical section is configured.\n     */\n    rc = pj_exception_id_alloc(\"PJLIB/No memory\", &PJ_NO_MEMORY_EXCEPTION);\n    if (rc != PJ_SUCCESS)\n        return rc;\n\n    /* Init random seed. */\n    /* Or probably not. Let application in charge of this */\n    /* pj_srand( clock() ); */\n\n    /* Startup GUID. */\n    guid.ptr = dummy_guid;\n    pj_generate_unique_string( &guid );\n\n    /* Startup timestamp */\n#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0\n    {\n\tpj_timestamp dummy_ts;\n\tif ((rc=pj_get_timestamp(&dummy_ts)) != 0) {\n\t    return rc;\n\t}\n    }\n#endif\n\n    /* Flag PJLIB as initialized */\n    ++initialized;\n    pj_assert(initialized == 1);\n\n    PJ_LOG(4,(THIS_FILE, \"pjlib %s for POSIX initialized\",\n\t      PJ_VERSION));\n\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_atexit()\n */\nPJ_DEF(pj_status_t) pj_atexit(void (*func)(void))\n{\n    if (atexit_count >= PJ_ARRAY_SIZE(atexit_func))\n\treturn PJ_ETOOMANY;\n\n    atexit_func[atexit_count++] = func;\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_shutdown(void)\n */\nPJ_DEF(void) pj_shutdown()\n{\n    int i;\n\n    /* Only perform shutdown operation when 'initialized' reaches zero */\n    pj_assert(initialized > 0);\n    if (--initialized != 0)\n\treturn;\n\n    /* Call atexit() functions */\n    for (i=atexit_count-1; i>=0; --i) {\n\t(*atexit_func[i])();\n    }\n    atexit_count = 0;\n\n    /* Free exception ID */\n    if (PJ_NO_MEMORY_EXCEPTION != -1) {\n\tpj_exception_id_free(PJ_NO_MEMORY_EXCEPTION);\n\tPJ_NO_MEMORY_EXCEPTION = -1;\n    }\n\n#if PJ_HAS_THREADS\n    /* Destroy PJLIB critical section */\n    pj_mutex_destroy(&critical_section);\n\n    /* Free PJLIB TLS */\n    if (thread_tls_id != -1) {\n\tpj_thread_local_free(thread_tls_id);\n\tthread_tls_id = -1;\n    }\n\n    /* Ticket #1132: Assertion when (re)starting PJLIB on different thread */\n    pj_bzero(&main_thread, sizeof(main_thread));\n#endif\n\n    /* Clear static variables */\n    pj_errno_clear_handlers();\n}\n\n\n/*\n * pj_getpid(void)\n */\nPJ_DEF(pj_uint32_t) pj_getpid(void)\n{\n    PJ_CHECK_STACK();\n    return getpid();\n}\n\n/*\n * Check if this thread has been registered to PJLIB.\n */\nPJ_DEF(pj_bool_t) pj_thread_is_registered(void)\n{\n#if PJ_HAS_THREADS\n    return pj_thread_local_get(thread_tls_id) != 0;\n#else\n    pj_assert(\"pj_thread_is_registered() called in non-threading mode!\");\n    return PJ_TRUE;\n#endif\n}\n\n\n/*\n * Get thread priority value for the thread.\n */\nPJ_DEF(int) pj_thread_get_prio(pj_thread_t *thread)\n{\n#if PJ_HAS_THREADS\n    struct sched_param param;\n    int policy;\n    int rc;\n\n    rc = pthread_getschedparam (thread->thread, &policy, &param);\n    if (rc != 0)\n\treturn -1;\n\n    return param.sched_priority;\n#else\n    PJ_UNUSED_ARG(thread);\n    return 1;\n#endif\n}\n\n\n/*\n * Set the thread priority.\n */\nPJ_DEF(pj_status_t) pj_thread_set_prio(pj_thread_t *thread,  int prio)\n{\n#if PJ_HAS_THREADS\n    struct sched_param param;\n    int policy;\n    int rc;\n\n    rc = pthread_getschedparam (thread->thread, &policy, &param);\n    if (rc != 0)\n\treturn PJ_RETURN_OS_ERROR(rc);\n\n    param.sched_priority = prio;\n\n    rc = pthread_setschedparam(thread->thread, policy, &param);\n    if (rc != 0)\n\treturn PJ_RETURN_OS_ERROR(rc);\n\n    return PJ_SUCCESS;\n#else\n    PJ_UNUSED_ARG(thread);\n    PJ_UNUSED_ARG(prio);\n    pj_assert(\"pj_thread_set_prio() called in non-threading mode!\");\n    return 1;\n#endif\n}\n\n\n/*\n * Get the lowest priority value available on this system.\n */\nPJ_DEF(int) pj_thread_get_prio_min(pj_thread_t *thread)\n{\n    struct sched_param param;\n    int policy;\n    int rc;\n\n    rc = pthread_getschedparam(thread->thread, &policy, &param);\n    if (rc != 0)\n\treturn -1;\n\n#if defined(_POSIX_PRIORITY_SCHEDULING)\n    return sched_get_priority_min(policy);\n#elif defined __OpenBSD__\n    /* Thread prio min/max are declared in OpenBSD private hdr */\n    return 0;\n#else\n    pj_assert(\"pj_thread_get_prio_min() not supported!\");\n    return 0;\n#endif\n}\n\n\n/*\n * Get the highest priority value available on this system.\n */\nPJ_DEF(int) pj_thread_get_prio_max(pj_thread_t *thread)\n{\n    struct sched_param param;\n    int policy;\n    int rc;\n\n    rc = pthread_getschedparam(thread->thread, &policy, &param);\n    if (rc != 0)\n\treturn -1;\n\n#if defined(_POSIX_PRIORITY_SCHEDULING)\n    return sched_get_priority_max(policy);\n#elif defined __OpenBSD__\n    /* Thread prio min/max are declared in OpenBSD private hdr */\n    return 31;\n#else\n    pj_assert(\"pj_thread_get_prio_max() not supported!\");\n    return 0;\n#endif\n}\n\n\n/*\n * Get native thread handle\n */\nPJ_DEF(void*) pj_thread_get_os_handle(pj_thread_t *thread)\n{\n    PJ_ASSERT_RETURN(thread, NULL);\n\n#if PJ_HAS_THREADS\n    return &thread->thread;\n#else\n    pj_assert(\"pj_thread_is_registered() called in non-threading mode!\");\n    return NULL;\n#endif\n}\n\n/*\n * pj_thread_register(..)\n */\nPJ_DEF(pj_status_t) pj_thread_register ( const char *cstr_thread_name,\n\t\t\t\t\t pj_thread_desc desc,\n\t\t\t\t\t pj_thread_t **ptr_thread)\n{\n#if PJ_HAS_THREADS\n    char stack_ptr;\n    pj_status_t rc;\n    pj_thread_t *thread = (pj_thread_t *)desc;\n    pj_str_t thread_name = pj_str((char*)cstr_thread_name);\n\n    /* Size sanity check. */\n    if (sizeof(pj_thread_desc) < sizeof(pj_thread_t)) {\n\tpj_assert(!\"Not enough pj_thread_desc size!\");\n\treturn PJ_EBUG;\n    }\n\n    /* Warn if this thread has been registered before */\n    if (pj_thread_local_get (thread_tls_id) != 0) {\n\t// 2006-02-26 bennylp:\n\t//  This wouldn't work in all cases!.\n\t//  If thread is created by external module (e.g. sound thread),\n\t//  thread may be reused while the pool used for the thread descriptor\n\t//  has been deleted by application.\n\t//*thread_ptr = (pj_thread_t*)pj_thread_local_get (thread_tls_id);\n        //return PJ_SUCCESS;\n\tPJ_LOG(4,(THIS_FILE, \"Info: possibly re-registering existing \"\n\t\t\t     \"thread\"));\n    }\n\n    /* On the other hand, also warn if the thread descriptor buffer seem to\n     * have been used to register other threads.\n     */\n    pj_assert(thread->signature1 != SIGNATURE1 ||\n\t      thread->signature2 != SIGNATURE2 ||\n\t      (thread->thread == pthread_self()));\n\n    /* Initialize and set the thread entry. */\n    pj_bzero(desc, sizeof(struct pj_thread_t));\n    thread->thread = pthread_self();\n    thread->signature1 = SIGNATURE1;\n    thread->signature2 = SIGNATURE2;\n\n    if(cstr_thread_name && pj_strlen(&thread_name) < sizeof(thread->obj_name)-1)\n\tpj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name),\n\t\t\t cstr_thread_name, thread->thread);\n    else\n\tpj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name),\n\t\t\t \"thr%p\", (void*)thread->thread);\n\n    rc = pj_thread_local_set(thread_tls_id, thread);\n    if (rc != PJ_SUCCESS) {\n\tpj_bzero(desc, sizeof(struct pj_thread_t));\n\treturn rc;\n    }\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n    thread->stk_start = &stack_ptr;\n    thread->stk_size = 0xFFFFFFFFUL;\n    thread->stk_max_usage = 0;\n#else\n    PJ_UNUSED_ARG(stack_ptr);\n#endif\n\n    *ptr_thread = thread;\n    return PJ_SUCCESS;\n#else\n    pj_thread_t *thread = (pj_thread_t*)desc;\n    *ptr_thread = thread;\n    return PJ_SUCCESS;\n#endif\n}\n\n/*\n * pj_thread_init(void)\n */\npj_status_t pj_thread_init(void)\n{\n#if PJ_HAS_THREADS\n    pj_status_t rc;\n    pj_thread_t *dummy;\n\n    rc = pj_thread_local_alloc(&thread_tls_id );\n    if (rc != PJ_SUCCESS) {\n\treturn rc;\n    }\n    return pj_thread_register(\"thr%p\", (long*)&main_thread, &dummy);\n#else\n    PJ_LOG(2,(THIS_FILE, \"Thread init error. Threading is not enabled!\"));\n    return PJ_EINVALIDOP;\n#endif\n}\n\n#if PJ_HAS_THREADS\n/*\n * thread_main()\n *\n * This is the main entry for all threads.\n */\nstatic void *thread_main(void *param)\n{\n    pj_thread_t *rec = (pj_thread_t*)param;\n    void *result;\n    pj_status_t rc;\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n    rec->stk_start = (char*)&rec;\n#endif\n\n    /* Set current thread id. */\n    rc = pj_thread_local_set(thread_tls_id, rec);\n    if (rc != PJ_SUCCESS) {\n\tpj_assert(!\"Thread TLS ID is not set (pj_init() error?)\");\n    }\n\n    /* Check if suspension is required. */\n    if (rec->suspended_mutex) {\n\tpj_mutex_lock(rec->suspended_mutex);\n\tpj_mutex_unlock(rec->suspended_mutex);\n    }\n\n    PJ_LOG(6,(rec->obj_name, \"Thread started\"));\n\n    /* Call user's entry! */\n    result = (void*)(long)(*rec->proc)(rec->arg);\n\n    /* Done. */\n    PJ_LOG(6,(rec->obj_name, \"Thread quitting\"));\n\n    return result;\n}\n#endif\n\n/*\n * pj_thread_create(...)\n */\nPJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool,\n\t\t\t\t      const char *thread_name,\n\t\t\t\t      pj_thread_proc *proc,\n\t\t\t\t      void *arg,\n\t\t\t\t      pj_size_t stack_size,\n\t\t\t\t      unsigned flags,\n\t\t\t\t      pj_thread_t **ptr_thread)\n{\n#if PJ_HAS_THREADS\n    pj_thread_t *rec;\n    pthread_attr_t thread_attr;\n    void *stack_addr;\n    int rc;\n\n    PJ_UNUSED_ARG(stack_addr);\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(pool && proc && ptr_thread, PJ_EINVAL);\n\n    /* Create thread record and assign name for the thread */\n    rec = (struct pj_thread_t*) pj_pool_zalloc(pool, sizeof(pj_thread_t));\n    PJ_ASSERT_RETURN(rec, PJ_ENOMEM);\n\n    /* Set name. */\n    if (!thread_name)\n\tthread_name = \"thr%p\";\n\n    if (strchr(thread_name, '%')) {\n\tpj_ansi_snprintf(rec->obj_name, PJ_MAX_OBJ_NAME, thread_name, rec);\n    } else {\n\tstrncpy(rec->obj_name, thread_name, PJ_MAX_OBJ_NAME);\n\trec->obj_name[PJ_MAX_OBJ_NAME-1] = '\\0';\n    }\n\n    /* Set default stack size */\n    if (stack_size == 0)\n\tstack_size = PJ_THREAD_DEFAULT_STACK_SIZE;\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n    rec->stk_size = stack_size;\n    rec->stk_max_usage = 0;\n#endif\n\n    /* Emulate suspended thread with mutex. */\n    if (flags & PJ_THREAD_SUSPENDED) {\n\trc = pj_mutex_create_simple(pool, NULL, &rec->suspended_mutex);\n\tif (rc != PJ_SUCCESS) {\n\t    return rc;\n\t}\n\n\tpj_mutex_lock(rec->suspended_mutex);\n    } else {\n\tpj_assert(rec->suspended_mutex == NULL);\n    }\n\n\n    /* Init thread attributes */\n    pthread_attr_init(&thread_attr);\n\n#if defined(PJ_THREAD_SET_STACK_SIZE) && PJ_THREAD_SET_STACK_SIZE!=0\n    /* Set thread's stack size */\n    rc = pthread_attr_setstacksize(&thread_attr, stack_size);\n    if (rc != 0)\n\treturn PJ_RETURN_OS_ERROR(rc);\n#endif\t/* PJ_THREAD_SET_STACK_SIZE */\n\n\n#if defined(PJ_THREAD_ALLOCATE_STACK) && PJ_THREAD_ALLOCATE_STACK!=0\n    /* Allocate memory for the stack */\n    stack_addr = pj_pool_alloc(pool, stack_size);\n    PJ_ASSERT_RETURN(stack_addr, PJ_ENOMEM);\n\n    rc = pthread_attr_setstackaddr(&thread_attr, stack_addr);\n    if (rc != 0)\n\treturn PJ_RETURN_OS_ERROR(rc);\n#endif\t/* PJ_THREAD_ALLOCATE_STACK */\n\n\n    /* Create the thread. */\n    rec->proc = proc;\n    rec->arg = arg;\n    rc = pthread_create( &rec->thread, &thread_attr, &thread_main, rec);\n    if (rc != 0) {\n\treturn PJ_RETURN_OS_ERROR(rc);\n    }\n\n    *ptr_thread = rec;\n\n    PJ_LOG(6, (rec->obj_name, \"Thread created\"));\n    return PJ_SUCCESS;\n#else\n    pj_assert(!\"Threading is disabled!\");\n    return PJ_EINVALIDOP;\n#endif\n}\n\n/*\n * pj_thread-get_name()\n */\nPJ_DEF(const char*) pj_thread_get_name(pj_thread_t *p)\n{\n#if PJ_HAS_THREADS\n    pj_thread_t *rec = (pj_thread_t*)p;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(p, \"\");\n\n    return rec->obj_name;\n#else\n    return \"\";\n#endif\n}\n\n/*\n * pj_thread_resume()\n */\nPJ_DEF(pj_status_t) pj_thread_resume(pj_thread_t *p)\n{\n    pj_status_t rc;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(p, PJ_EINVAL);\n\n    rc = pj_mutex_unlock(p->suspended_mutex);\n\n    return rc;\n}\n\n/*\n * pj_thread_this()\n */\nPJ_DEF(pj_thread_t*) pj_thread_this(void)\n{\n#if PJ_HAS_THREADS\n    pj_thread_t *rec = (pj_thread_t*)pj_thread_local_get(thread_tls_id);\n\n    if (rec == NULL) {\n\tpj_assert(!\"Calling pjlib from unknown/external thread. You must \"\n\t\t   \"register external threads with pj_thread_register() \"\n\t\t   \"before calling any pjlib functions.\");\n    }\n\n    /*\n     * MUST NOT check stack because this function is called\n     * by PJ_CHECK_STACK() itself!!!\n     *\n     */\n\n    return rec;\n#else\n    pj_assert(!\"Threading is not enabled!\");\n    return NULL;\n#endif\n}\n\n/*\n * pj_thread_join()\n */\nPJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)\n{\n#if PJ_HAS_THREADS\n    pj_thread_t *rec = (pj_thread_t *)p;\n    void *ret;\n    int result;\n\n    PJ_CHECK_STACK();\n\n    if (p == pj_thread_this())\n\treturn PJ_ECANCELLED;\n\n    PJ_LOG(6, (pj_thread_this()->obj_name, \"Joining thread %s\", p->obj_name));\n    result = pthread_join( rec->thread, &ret);\n\n    if (result == 0)\n\treturn PJ_SUCCESS;\n    else {\n\t/* Calling pthread_join() on a thread that no longer exists and\n\t * getting back ESRCH isn't an error (in this context).\n\t * Thanks Phil Torre <ptorre@zetron.com>.\n\t */\n\treturn result==ESRCH ? PJ_SUCCESS : PJ_RETURN_OS_ERROR(result);\n    }\n#else\n    PJ_CHECK_STACK();\n    pj_assert(!\"No multithreading support!\");\n    return PJ_EINVALIDOP;\n#endif\n}\n\n/*\n * pj_thread_destroy()\n */\nPJ_DEF(pj_status_t) pj_thread_destroy(pj_thread_t *p)\n{\n    PJ_CHECK_STACK();\n\n    /* Destroy mutex used to suspend thread */\n    if (p->suspended_mutex) {\n\tpj_mutex_destroy(p->suspended_mutex);\n\tp->suspended_mutex = NULL;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_thread_sleep()\n */\nPJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)\n{\n/* TODO: should change this to something like PJ_OS_HAS_NANOSLEEP */\n#if defined(PJ_RTEMS) && PJ_RTEMS!=0\n    enum { NANOSEC_PER_MSEC = 1000000 };\n    struct timespec req;\n\n    PJ_CHECK_STACK();\n    req.tv_sec = msec / 1000;\n    req.tv_nsec = (msec % 1000) * NANOSEC_PER_MSEC;\n\n    if (nanosleep(&req, NULL) == 0)\n\treturn PJ_SUCCESS;\n\n    return PJ_RETURN_OS_ERROR(pj_get_native_os_error());\n#else\n    PJ_CHECK_STACK();\n\n    pj_set_os_error(0);\n\n    usleep(msec * 1000);\n\n    /* MacOS X (reported on 10.5) seems to always set errno to ETIMEDOUT.\n     * It does so because usleep() is declared to return int, and we're\n     * supposed to check for errno only when usleep() returns non-zero.\n     * Unfortunately, usleep() is declared to return void in other platforms\n     * so it's not possible to always check for the return value (unless\n     * we add a detection routine in autoconf).\n     *\n     * As a workaround, here we check if ETIMEDOUT is returned and\n     * return successfully if it is.\n     */\n    if (pj_get_native_os_error() == ETIMEDOUT)\n\treturn PJ_SUCCESS;\n\n    return pj_get_os_error();\n\n#endif\t/* PJ_RTEMS */\n}\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n/*\n * pj_thread_check_stack()\n * Implementation for PJ_CHECK_STACK()\n */\nPJ_DEF(void) pj_thread_check_stack(const char *file, int line)\n{\n    char stk_ptr;\n    pj_uint32_t usage;\n    pj_thread_t *thread = pj_thread_this();\n\n    /* Calculate current usage. */\n    usage = (&stk_ptr > thread->stk_start) ? &stk_ptr - thread->stk_start :\n\t\tthread->stk_start - &stk_ptr;\n\n    /* Assert if stack usage is dangerously high. */\n    pj_assert(\"STACK OVERFLOW!! \" && (usage <= thread->stk_size - 128));\n\n    /* Keep statistic. */\n    if (usage > thread->stk_max_usage) {\n\tthread->stk_max_usage = usage;\n\tthread->caller_file = file;\n\tthread->caller_line = line;\n    }\n}\n\n/*\n * pj_thread_get_stack_max_usage()\n */\nPJ_DEF(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread)\n{\n    return thread->stk_max_usage;\n}\n\n/*\n * pj_thread_get_stack_info()\n */\nPJ_DEF(pj_status_t) pj_thread_get_stack_info( pj_thread_t *thread,\n\t\t\t\t\t      const char **file,\n\t\t\t\t\t      int *line )\n{\n    pj_assert(thread);\n\n    *file = thread->caller_file;\n    *line = thread->caller_line;\n    return 0;\n}\n\n#endif\t/* PJ_OS_HAS_CHECK_STACK */\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * pj_atomic_create()\n */\nPJ_DEF(pj_status_t) pj_atomic_create( pj_pool_t *pool,\n\t\t\t\t      pj_atomic_value_t initial,\n\t\t\t\t      pj_atomic_t **ptr_atomic)\n{\n    pj_status_t rc;\n    pj_atomic_t *atomic_var;\n\n    atomic_var = PJ_POOL_ZALLOC_T(pool, pj_atomic_t);\n\n    PJ_ASSERT_RETURN(atomic_var, PJ_ENOMEM);\n\n#if PJ_HAS_THREADS\n    rc = pj_mutex_create(pool, \"atm%p\", PJ_MUTEX_SIMPLE, &atomic_var->mutex);\n    if (rc != PJ_SUCCESS)\n\treturn rc;\n#endif\n    atomic_var->value = initial;\n\n    *ptr_atomic = atomic_var;\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_atomic_destroy()\n */\nPJ_DEF(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var )\n{\n    PJ_ASSERT_RETURN(atomic_var, PJ_EINVAL);\n#if PJ_HAS_THREADS\n    return pj_mutex_destroy( atomic_var->mutex );\n#else\n    return 0;\n#endif\n}\n\n/*\n * pj_atomic_set()\n */\nPJ_DEF(void) pj_atomic_set(pj_atomic_t *atomic_var, pj_atomic_value_t value)\n{\n    PJ_CHECK_STACK();\n\n#if PJ_HAS_THREADS\n    pj_mutex_lock( atomic_var->mutex );\n#endif\n    atomic_var->value = value;\n#if PJ_HAS_THREADS\n    pj_mutex_unlock( atomic_var->mutex);\n#endif\n}\n\n/*\n * pj_atomic_get()\n */\nPJ_DEF(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var)\n{\n    pj_atomic_value_t oldval;\n\n    PJ_CHECK_STACK();\n\n#if PJ_HAS_THREADS\n    pj_mutex_lock( atomic_var->mutex );\n#endif\n    oldval = atomic_var->value;\n#if PJ_HAS_THREADS\n    pj_mutex_unlock( atomic_var->mutex);\n#endif\n    return oldval;\n}\n\n/*\n * pj_atomic_inc_and_get()\n */\nPJ_DEF(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var)\n{\n    pj_atomic_value_t new_value;\n\n    PJ_CHECK_STACK();\n\n#if PJ_HAS_THREADS\n    pj_mutex_lock( atomic_var->mutex );\n#endif\n    new_value = ++atomic_var->value;\n#if PJ_HAS_THREADS\n    pj_mutex_unlock( atomic_var->mutex);\n#endif\n\n    return new_value;\n}\n/*\n * pj_atomic_inc()\n */\nPJ_DEF(void) pj_atomic_inc(pj_atomic_t *atomic_var)\n{\n    pj_atomic_inc_and_get(atomic_var);\n}\n\n/*\n * pj_atomic_dec_and_get()\n */\nPJ_DEF(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var)\n{\n    pj_atomic_value_t new_value;\n\n    PJ_CHECK_STACK();\n\n#if PJ_HAS_THREADS\n    pj_mutex_lock( atomic_var->mutex );\n#endif\n    new_value = --atomic_var->value;\n#if PJ_HAS_THREADS\n    pj_mutex_unlock( atomic_var->mutex);\n#endif\n\n    return new_value;\n}\n\n/*\n * pj_atomic_dec()\n */\nPJ_DEF(void) pj_atomic_dec(pj_atomic_t *atomic_var)\n{\n    pj_atomic_dec_and_get(atomic_var);\n}\n\n/*\n * pj_atomic_add_and_get()\n */\nPJ_DEF(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,\n                                                 pj_atomic_value_t value )\n{\n    pj_atomic_value_t new_value;\n\n#if PJ_HAS_THREADS\n    pj_mutex_lock(atomic_var->mutex);\n#endif\n\n    atomic_var->value += value;\n    new_value = atomic_var->value;\n\n#if PJ_HAS_THREADS\n    pj_mutex_unlock(atomic_var->mutex);\n#endif\n\n    return new_value;\n}\n\n/*\n * pj_atomic_add()\n */\nPJ_DEF(void) pj_atomic_add( pj_atomic_t *atomic_var,\n                            pj_atomic_value_t value )\n{\n    pj_atomic_add_and_get(atomic_var, value);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * pj_thread_local_alloc()\n */\nPJ_DEF(pj_status_t) pj_thread_local_alloc(long *p_index)\n{\n#if PJ_HAS_THREADS\n    pthread_key_t key;\n    int rc;\n\n    PJ_ASSERT_RETURN(p_index != NULL, PJ_EINVAL);\n\n    pj_assert( sizeof(pthread_key_t) <= sizeof(long));\n    if ((rc=pthread_key_create(&key, NULL)) != 0)\n\treturn PJ_RETURN_OS_ERROR(rc);\n\n    *p_index = key;\n    return PJ_SUCCESS;\n#else\n    int i;\n    for (i=0; i<MAX_THREADS; ++i) {\n\tif (tls_flag[i] == 0)\n\t    break;\n    }\n    if (i == MAX_THREADS)\n\treturn PJ_ETOOMANY;\n\n    tls_flag[i] = 1;\n    tls[i] = NULL;\n\n    *p_index = i;\n    return PJ_SUCCESS;\n#endif\n}\n\n/*\n * pj_thread_local_free()\n */\nPJ_DEF(void) pj_thread_local_free(long index)\n{\n    PJ_CHECK_STACK();\n#if PJ_HAS_THREADS\n    pthread_key_delete(index);\n#else\n    tls_flag[index] = 0;\n#endif\n}\n\n/*\n * pj_thread_local_set()\n */\nPJ_DEF(pj_status_t) pj_thread_local_set(long index, void *value)\n{\n    //Can't check stack because this function is called in the\n    //beginning before main thread is initialized.\n    //PJ_CHECK_STACK();\n#if PJ_HAS_THREADS\n    int rc=pthread_setspecific(index, value);\n    return rc==0 ? PJ_SUCCESS : PJ_RETURN_OS_ERROR(rc);\n#else\n    pj_assert(index >= 0 && index < MAX_THREADS);\n    tls[index] = value;\n    return PJ_SUCCESS;\n#endif\n}\n\nPJ_DEF(void*) pj_thread_local_get(long index)\n{\n    //Can't check stack because this function is called\n    //by PJ_CHECK_STACK() itself!!!\n    //PJ_CHECK_STACK();\n#if PJ_HAS_THREADS\n    return pthread_getspecific(index);\n#else\n    pj_assert(index >= 0 && index < MAX_THREADS);\n    return tls[index];\n#endif\n}\n\n///////////////////////////////////////////////////////////////////////////////\nPJ_DEF(void) pj_enter_critical_section(void)\n{\n#if PJ_HAS_THREADS\n    pj_mutex_lock(&critical_section);\n#endif\n}\n\nPJ_DEF(void) pj_leave_critical_section(void)\n{\n#if PJ_HAS_THREADS\n    pj_mutex_unlock(&critical_section);\n#endif\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n#if defined(PJ_LINUX) && PJ_LINUX!=0\nPJ_BEGIN_DECL\nPJ_DECL(int) pthread_mutexattr_settype(pthread_mutexattr_t*,int);\nPJ_END_DECL\n#endif\n\nstatic pj_status_t init_mutex(pj_mutex_t *mutex, const char *name, int type)\n{\n#if PJ_HAS_THREADS\n    pthread_mutexattr_t attr;\n    int rc;\n\n    PJ_CHECK_STACK();\n\n    rc = pthread_mutexattr_init(&attr);\n    if (rc != 0)\n\treturn PJ_RETURN_OS_ERROR(rc);\n\n    if (type == PJ_MUTEX_SIMPLE) {\n#if (defined(PJ_LINUX) && PJ_LINUX!=0) || \\\n    defined(PJ_HAS_PTHREAD_MUTEXATTR_SETTYPE)\n\trc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_FAST_NP);\n#elif (defined(PJ_RTEMS) && PJ_RTEMS!=0) || \\\n       defined(PJ_PTHREAD_MUTEXATTR_T_HAS_RECURSIVE)\n\t/* Nothing to do, default is simple */\n#else\n\trc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);\n#endif\n    } else {\n#if (defined(PJ_LINUX) && PJ_LINUX!=0) || \\\n     defined(PJ_HAS_PTHREAD_MUTEXATTR_SETTYPE)\n\trc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);\n#elif (defined(PJ_RTEMS) && PJ_RTEMS!=0) || \\\n       defined(PJ_PTHREAD_MUTEXATTR_T_HAS_RECURSIVE)\n\t// Phil Torre <ptorre@zetron.com>:\n\t// The RTEMS implementation of POSIX mutexes doesn't include\n\t// pthread_mutexattr_settype(), so what follows is a hack\n\t// until I get RTEMS patched to support the set/get functions.\n\t//\n\t// More info:\n\t//   newlib's pthread also lacks pthread_mutexattr_settype(),\n\t//   but it seems to have mutexattr.recursive.\n\tPJ_TODO(FIX_RTEMS_RECURSIVE_MUTEX_TYPE)\n\tattr.recursive = 1;\n#else\n\trc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);\n#endif\n    }\n\n    if (rc != 0) {\n\treturn PJ_RETURN_OS_ERROR(rc);\n    }\n\n    rc = pthread_mutex_init(&mutex->mutex, &attr);\n    if (rc != 0) {\n\treturn PJ_RETURN_OS_ERROR(rc);\n    }\n\n    rc = pthread_mutexattr_destroy(&attr);\n    if (rc != 0) {\n\tpj_status_t status = PJ_RETURN_OS_ERROR(rc);\n\tpthread_mutex_destroy(&mutex->mutex);\n\treturn status;\n    }\n\n#if PJ_DEBUG\n    /* Set owner. */\n    mutex->nesting_level = 0;\n    mutex->owner = NULL;\n    mutex->owner_name[0] = '\\0';\n#endif\n\n    /* Set name. */\n    if (!name) {\n\tname = \"mtx%p\";\n    }\n    if (strchr(name, '%')) {\n\tpj_ansi_snprintf(mutex->obj_name, PJ_MAX_OBJ_NAME, name, mutex);\n    } else {\n\tstrncpy(mutex->obj_name, name, PJ_MAX_OBJ_NAME);\n\tmutex->obj_name[PJ_MAX_OBJ_NAME-1] = '\\0';\n    }\n\n    PJ_LOG(6, (mutex->obj_name, \"Mutex created\"));\n    return PJ_SUCCESS;\n#else /* PJ_HAS_THREADS */\n    return PJ_SUCCESS;\n#endif\n}\n\n/*\n * pj_mutex_create()\n */\nPJ_DEF(pj_status_t) pj_mutex_create(pj_pool_t *pool,\n\t\t\t\t    const char *name,\n\t\t\t\t    int type,\n\t\t\t\t    pj_mutex_t **ptr_mutex)\n{\n#if PJ_HAS_THREADS\n    pj_status_t rc;\n    pj_mutex_t *mutex;\n\n    PJ_ASSERT_RETURN(pool && ptr_mutex, PJ_EINVAL);\n\n    mutex = PJ_POOL_ALLOC_T(pool, pj_mutex_t);\n    PJ_ASSERT_RETURN(mutex, PJ_ENOMEM);\n\n    if ((rc=init_mutex(mutex, name, type)) != PJ_SUCCESS)\n\treturn rc;\n\n    *ptr_mutex = mutex;\n    return PJ_SUCCESS;\n#else /* PJ_HAS_THREADS */\n    *ptr_mutex = (pj_mutex_t*)1;\n    return PJ_SUCCESS;\n#endif\n}\n\n/*\n * pj_mutex_create_simple()\n */\nPJ_DEF(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool,\n                                            const char *name,\n\t\t\t\t\t    pj_mutex_t **mutex )\n{\n    return pj_mutex_create(pool, name, PJ_MUTEX_SIMPLE, mutex);\n}\n\n/*\n * pj_mutex_create_recursive()\n */\nPJ_DEF(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,\n\t\t\t\t\t       const char *name,\n\t\t\t\t\t       pj_mutex_t **mutex )\n{\n    return pj_mutex_create(pool, name, PJ_MUTEX_RECURSE, mutex);\n}\n\n/*\n * pj_mutex_lock()\n */\nPJ_DEF(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex)\n{\n#if PJ_HAS_THREADS\n    pj_status_t status;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n\n#if PJ_DEBUG\n    PJ_LOG(6,(mutex->obj_name, \"Mutex: thread %s is waiting (mutex owner=%s)\",\n\t\t\t\tpj_thread_this()->obj_name,\n\t\t\t\tmutex->owner_name));\n#else\n    PJ_LOG(6,(mutex->obj_name, \"Mutex: thread %s is waiting\",\n\t\t\t\tpj_thread_this()->obj_name));\n#endif\n\n    status = pthread_mutex_lock( &mutex->mutex );\n\n\n#if PJ_DEBUG\n    if (status == PJ_SUCCESS) {\n\tmutex->owner = pj_thread_this();\n\tpj_ansi_strcpy(mutex->owner_name, mutex->owner->obj_name);\n\t++mutex->nesting_level;\n    }\n\n    PJ_LOG(6,(mutex->obj_name,\n\t      (status==0 ?\n\t\t\"Mutex acquired by thread %s (level=%d)\" :\n\t\t\"Mutex acquisition FAILED by %s (level=%d)\"),\n\t      pj_thread_this()->obj_name,\n\t      mutex->nesting_level));\n#else\n    PJ_LOG(6,(mutex->obj_name,\n\t      (status==0 ? \"Mutex acquired by thread %s\" : \"FAILED by %s\"),\n\t      pj_thread_this()->obj_name));\n#endif\n\n    if (status == 0)\n\treturn PJ_SUCCESS;\n    else\n\treturn PJ_RETURN_OS_ERROR(status);\n#else\t/* PJ_HAS_THREADS */\n    pj_assert( mutex == (pj_mutex_t*)1 );\n    return PJ_SUCCESS;\n#endif\n}\n\n/*\n * pj_mutex_unlock()\n */\nPJ_DEF(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex)\n{\n#if PJ_HAS_THREADS\n    pj_status_t status;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n\n#if PJ_DEBUG\n    pj_assert(mutex->owner == pj_thread_this());\n    if (--mutex->nesting_level == 0) {\n\tmutex->owner = NULL;\n\tmutex->owner_name[0] = '\\0';\n    }\n\n    PJ_LOG(6,(mutex->obj_name, \"Mutex released by thread %s (level=%d)\",\n\t\t\t\tpj_thread_this()->obj_name,\n\t\t\t\tmutex->nesting_level));\n#else\n    PJ_LOG(6,(mutex->obj_name, \"Mutex released by thread %s\",\n\t\t\t\tpj_thread_this()->obj_name));\n#endif\n\n    status = pthread_mutex_unlock( &mutex->mutex );\n    if (status == 0)\n\treturn PJ_SUCCESS;\n    else\n\treturn PJ_RETURN_OS_ERROR(status);\n\n#else /* PJ_HAS_THREADS */\n    pj_assert( mutex == (pj_mutex_t*)1 );\n    return PJ_SUCCESS;\n#endif\n}\n\n/*\n * pj_mutex_trylock()\n */\nPJ_DEF(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex)\n{\n#if PJ_HAS_THREADS\n    int status;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n\n    PJ_LOG(6,(mutex->obj_name, \"Mutex: thread %s is trying\",\n\t\t\t\tpj_thread_this()->obj_name));\n\n    status = pthread_mutex_trylock( &mutex->mutex );\n\n    if (status==0) {\n#if PJ_DEBUG\n\tmutex->owner = pj_thread_this();\n\tpj_ansi_strcpy(mutex->owner_name, mutex->owner->obj_name);\n\t++mutex->nesting_level;\n\n\tPJ_LOG(6,(mutex->obj_name, \"Mutex acquired by thread %s (level=%d)\",\n\t\t\t\t   pj_thread_this()->obj_name,\n\t\t\t\t   mutex->nesting_level));\n#else\n\tPJ_LOG(6,(mutex->obj_name, \"Mutex acquired by thread %s\",\n\t\t\t\t  pj_thread_this()->obj_name));\n#endif\n    } else {\n\tPJ_LOG(6,(mutex->obj_name, \"Mutex: thread %s's trylock() failed\",\n\t\t\t\t    pj_thread_this()->obj_name));\n    }\n\n    if (status==0)\n\treturn PJ_SUCCESS;\n    else\n\treturn PJ_RETURN_OS_ERROR(status);\n#else\t/* PJ_HAS_THREADS */\n    pj_assert( mutex == (pj_mutex_t*)1);\n    return PJ_SUCCESS;\n#endif\n}\n\n/*\n * pj_mutex_destroy()\n */\nPJ_DEF(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex)\n{\n    enum { RETRY = 4 };\n    int status = 0;\n    unsigned retry;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n\n#if PJ_HAS_THREADS\n    PJ_LOG(6,(mutex->obj_name, \"Mutex destroyed by thread %s\",\n\t\t\t       pj_thread_this()->obj_name));\n\n    for (retry=0; retry<RETRY; ++retry) {\n\tstatus = pthread_mutex_destroy( &mutex->mutex );\n\tif (status == PJ_SUCCESS)\n\t    break;\n\telse if (retry<RETRY-1 && status == EBUSY)\n\t    pthread_mutex_unlock(&mutex->mutex);\n    }\n\n    if (status == 0)\n\treturn PJ_SUCCESS;\n    else {\n\treturn PJ_RETURN_OS_ERROR(status);\n    }\n#else\n    pj_assert( mutex == (pj_mutex_t*)1 );\n    status = PJ_SUCCESS;\n    return status;\n#endif\n}\n\n#if PJ_DEBUG\nPJ_DEF(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex)\n{\n#if PJ_HAS_THREADS\n    return mutex->owner == pj_thread_this();\n#else\n    return 1;\n#endif\n}\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Include Read/Write mutex emulation for POSIX platforms that lack it (e.g.\n * RTEMS). Otherwise use POSIX rwlock.\n */\n#if defined(PJ_EMULATE_RWMUTEX) && PJ_EMULATE_RWMUTEX!=0\n    /* We need semaphore functionality to emulate rwmutex */\n#   if !defined(PJ_HAS_SEMAPHORE) || PJ_HAS_SEMAPHORE==0\n#\terror \"Semaphore support needs to be enabled to emulate rwmutex\"\n#   endif\n#   include \"os_rwmutex.c\"\n#else\nstruct pj_rwmutex_t\n{\n    pthread_rwlock_t rwlock;\n};\n\nPJ_DEF(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,\n\t\t\t\t      pj_rwmutex_t **p_mutex)\n{\n    pj_rwmutex_t *rwm;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(name);\n\n    rwm = PJ_POOL_ALLOC_T(pool, pj_rwmutex_t);\n    PJ_ASSERT_RETURN(rwm, PJ_ENOMEM);\n\n    status = pthread_rwlock_init(&rwm->rwlock, NULL);\n    if (status != 0)\n\treturn PJ_RETURN_OS_ERROR(status);\n\n    *p_mutex = rwm;\n    return PJ_SUCCESS;\n}\n\n/*\n * Lock the mutex for reading.\n *\n */\nPJ_DEF(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex)\n{\n    pj_status_t status;\n\n    status = pthread_rwlock_rdlock(&mutex->rwlock);\n    if (status != 0)\n\treturn PJ_RETURN_OS_ERROR(status);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Lock the mutex for writing.\n *\n */\nPJ_DEF(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex)\n{\n    pj_status_t status;\n\n    status = pthread_rwlock_wrlock(&mutex->rwlock);\n    if (status != 0)\n\treturn PJ_RETURN_OS_ERROR(status);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Release read lock.\n *\n */\nPJ_DEF(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex)\n{\n    return pj_rwmutex_unlock_write(mutex);\n}\n\n/*\n * Release write lock.\n *\n */\nPJ_DEF(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex)\n{\n    pj_status_t status;\n\n    status = pthread_rwlock_unlock(&mutex->rwlock);\n    if (status != 0)\n\treturn PJ_RETURN_OS_ERROR(status);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Destroy reader/writer mutex.\n *\n */\nPJ_DEF(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex)\n{\n    pj_status_t status;\n\n    status = pthread_rwlock_destroy(&mutex->rwlock);\n    if (status != 0)\n\treturn PJ_RETURN_OS_ERROR(status);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJ_EMULATE_RWMUTEX */\n\n\n///////////////////////////////////////////////////////////////////////////////\n#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0\n\n/*\n * pj_sem_create()\n */\nPJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool,\n\t\t\t\t   const char *name,\n\t\t\t\t   unsigned initial,\n\t\t\t\t   unsigned max,\n\t\t\t\t   pj_sem_t **ptr_sem)\n{\n#if PJ_HAS_THREADS\n    pj_sem_t *sem;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(pool != NULL && ptr_sem != NULL, PJ_EINVAL);\n\n    sem = PJ_POOL_ALLOC_T(pool, pj_sem_t);\n    PJ_ASSERT_RETURN(sem, PJ_ENOMEM);\n\n#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0\n    {\n        kern_return_t err;\n        sem->sem = PJ_POOL_ALLOC_T(pool, semaphore_t);\n        err = semaphore_create(mach_task_self(), sem->sem, SYNC_POLICY_FIFO, initial);\n        if (err != KERN_SUCCESS) {\n            if (err == KERN_RESOURCE_SHORTAGE)\n                return PJ_RETURN_OS_ERROR(ENOMEM);\n            else\n                return PJ_RETURN_OS_ERROR(EINVAL);\n        }\n    }\n#else\n    sem->sem = PJ_POOL_ALLOC_T(pool, sem_t);\n    if (sem_init( sem->sem, 0, initial) != 0)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_os_error());\n#endif\n\n    /* Set name. */\n    if (!name) {\n\tname = \"sem%p\";\n    }\n    if (strchr(name, '%')) {\n\tpj_ansi_snprintf(sem->obj_name, PJ_MAX_OBJ_NAME, name, sem);\n    } else {\n\tstrncpy(sem->obj_name, name, PJ_MAX_OBJ_NAME);\n\tsem->obj_name[PJ_MAX_OBJ_NAME-1] = '\\0';\n    }\n\n    PJ_LOG(6, (sem->obj_name, \"Semaphore created\"));\n\n    *ptr_sem = sem;\n    return PJ_SUCCESS;\n#else\n    *ptr_sem = (pj_sem_t*)1;\n    return PJ_SUCCESS;\n#endif\n}\n\n/*\n * pj_sem_wait()\n */\nPJ_DEF(pj_status_t) pj_sem_wait(pj_sem_t *sem)\n{\n#if PJ_HAS_THREADS\n    int result;\n    int error;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(sem, PJ_EINVAL);\n\n    PJ_LOG(6, (sem->obj_name, \"Semaphore: thread %s is waiting\",\n\t\t\t      pj_thread_this()->obj_name));\n\n#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0\n    {\n        do\n            result = semaphore_wait(*(sem->sem));\n        while (result == KERN_ABORTED);\n\n        if (result == KERN_SUCCESS) {\n            result = error = 0;\n        } else {\n            result = -1;\n            error = EINVAL;\n        }\n    }\n#else\n    result = sem_wait( sem->sem );\n\n    if (result == 0) {\n\tPJ_LOG(6, (sem->obj_name, \"Semaphore acquired by thread %s\",\n\t\t\t\t  pj_thread_this()->obj_name));\n    } else {\n\tPJ_LOG(6, (sem->obj_name, \"Semaphore: thread %s FAILED to acquire\",\n\t\t\t\t  pj_thread_this()->obj_name));\n\terror = pj_get_native_os_error();\n    }\n#endif\n\n    if (result == 0)\n\treturn PJ_SUCCESS;\n    else\n\treturn PJ_RETURN_OS_ERROR(error);\n#else\n    pj_assert( sem == (pj_sem_t*) 1 );\n    return PJ_SUCCESS;\n#endif\n}\n\n/*\n * pj_sem_trywait()\n */\nPJ_DEF(pj_status_t) pj_sem_trywait(pj_sem_t *sem)\n{\n#if PJ_HAS_THREADS\n    int result;\n    int error;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(sem, PJ_EINVAL);\n\n#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0\n    {\n        mach_timespec_t interval;\n        kern_return_t err;\n\n        interval.tv_sec = 0;\n        interval.tv_nsec = 0;\n\n        err = semaphore_timedwait(*(sem->sem), interval);\n        if (err == KERN_SUCCESS) {\n            result = error = 0;\n        } else if (err == KERN_OPERATION_TIMED_OUT) {\n            result = -1;\n            error = EAGAIN;\n        } else {\n            result = -1;\n            error = EINVAL;\n        }\n    }\n#else\n    result = sem_trywait( sem->sem );\n\n    if (result == 0) {\n\tPJ_LOG(6, (sem->obj_name, \"Semaphore acquired by thread %s\",\n\t\t\t\t  pj_thread_this()->obj_name));\n    } else {\n        error = pj_get_native_os_error();\n    }\n#endif\n\n    if (result == 0)\n\treturn PJ_SUCCESS;\n    else\n\treturn PJ_RETURN_OS_ERROR(error);\n#else\n    pj_assert( sem == (pj_sem_t*)1 );\n    return PJ_SUCCESS;\n#endif\n}\n\n/*\n * pj_sem_post()\n */\nPJ_DEF(pj_status_t) pj_sem_post(pj_sem_t *sem)\n{\n#if PJ_HAS_THREADS\n    int result;\n    int error;\n    PJ_LOG(6, (sem->obj_name, \"Semaphore released by thread %s\",\n\t\t\t      pj_thread_this()->obj_name));\n#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0\n    {\n        kern_return_t err;\n        err = semaphore_signal(*(sem->sem));\n        if (err == KERN_SUCCESS) {\n            result = error = 0;\n        } else {\n            result = -1;\n            error = EINVAL;\n        }\n    }\n#else\n    result = sem_post( sem->sem );\n    if (result != 0)\n        error = pj_get_native_os_error();\n#endif\n\n    if (result == 0)\n\treturn PJ_SUCCESS;\n    else\n\treturn PJ_RETURN_OS_ERROR(error);\n#else\n    pj_assert( sem == (pj_sem_t*) 1);\n    return PJ_SUCCESS;\n#endif\n}\n\n/*\n * pj_sem_destroy()\n */\nPJ_DEF(pj_status_t) pj_sem_destroy(pj_sem_t *sem)\n{\n#if PJ_HAS_THREADS\n    int result;\n    int error;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(sem, PJ_EINVAL);\n\n    PJ_LOG(6, (sem->obj_name, \"Semaphore destroyed by thread %s\",\n\t\t\t      pj_thread_this()->obj_name));\n#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0\n    {\n        kern_return_t err;\n        err = semaphore_destroy(mach_task_self(), *(sem->sem));\n        if (err == KERN_SUCCESS) {\n            result = error = -1;\n        } else {\n            result = -1;\n            error = EINVAL;\n        }\n    }\n#else\n    result = sem_destroy( sem->sem );\n    if (result != 0)\n        error = pj_get_native_os_error();\n#endif\n\n    if (result == 0)\n\treturn PJ_SUCCESS;\n    else\n\treturn PJ_RETURN_OS_ERROR(error);\n#else\n    pj_assert( sem == (pj_sem_t*) 1 );\n    return PJ_SUCCESS;\n#endif\n}\n\n#endif\t/* PJ_HAS_SEMAPHORE */\n\n///////////////////////////////////////////////////////////////////////////////\n#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0\n\n/*\n * pj_event_create()\n */\nPJ_DEF(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,\n\t\t\t\t    pj_bool_t manual_reset, pj_bool_t initial,\n\t\t\t\t    pj_event_t **ptr_event)\n{\n    pj_event_t *event;\n\n    event = PJ_POOL_ALLOC_T(pool, pj_event_t);\n\n    init_mutex(&event->mutex, name, PJ_MUTEX_SIMPLE);\n    pthread_cond_init(&event->cond, 0);\n    event->auto_reset = !manual_reset;\n    event->threads_waiting = 0;\n\n    if (initial) {\n\tevent->state = EV_STATE_SET;\n\tevent->threads_to_release = 1;\n    } else {\n\tevent->state = EV_STATE_OFF;\n\tevent->threads_to_release = 0;\n    }\n\n    *ptr_event = event;\n    return PJ_SUCCESS;\n}\n\nstatic void event_on_one_release(pj_event_t *event)\n{\n    if (event->state == EV_STATE_SET) {\n\tif (event->auto_reset) {\n\t    event->threads_to_release = 0;\n\t    event->state = EV_STATE_OFF;\n\t} else {\n\t    /* Manual reset remains on */\n\t}\n    } else {\n\tif (event->auto_reset) {\n\t    /* Only release one */\n\t    event->threads_to_release = 0;\n\t    event->state = EV_STATE_OFF;\n\t} else {\n\t    event->threads_to_release--;\n\t    pj_assert(event->threads_to_release >= 0);\n\t    if (event->threads_to_release==0)\n\t\tevent->state = EV_STATE_OFF;\n\t}\n    }\n}\n\n/*\n * pj_event_wait()\n */\nPJ_DEF(pj_status_t) pj_event_wait(pj_event_t *event)\n{\n    pthread_mutex_lock(&event->mutex.mutex);\n    event->threads_waiting++;\n    while (event->state == EV_STATE_OFF)\n\tpthread_cond_wait(&event->cond, &event->mutex.mutex);\n    event->threads_waiting--;\n    event_on_one_release(event);\n    pthread_mutex_unlock(&event->mutex.mutex);\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_event_trywait()\n */\nPJ_DEF(pj_status_t) pj_event_trywait(pj_event_t *event)\n{\n    pj_status_t status;\n\n    pthread_mutex_lock(&event->mutex.mutex);\n    status = event->state != EV_STATE_OFF ? PJ_SUCCESS : -1;\n    if (status==PJ_SUCCESS) {\n\tevent_on_one_release(event);\n    }\n    pthread_mutex_unlock(&event->mutex.mutex);\n\n    return status;\n}\n\n/*\n * pj_event_set()\n */\nPJ_DEF(pj_status_t) pj_event_set(pj_event_t *event)\n{\n    pthread_mutex_lock(&event->mutex.mutex);\n    event->threads_to_release = 1;\n    event->state = EV_STATE_SET;\n    if (event->auto_reset)\n\tpthread_cond_signal(&event->cond);\n    else\n\tpthread_cond_broadcast(&event->cond);\n    pthread_mutex_unlock(&event->mutex.mutex);\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_event_pulse()\n */\nPJ_DEF(pj_status_t) pj_event_pulse(pj_event_t *event)\n{\n    pthread_mutex_lock(&event->mutex.mutex);\n    if (event->threads_waiting) {\n\tevent->threads_to_release = event->auto_reset ? 1 :\n\t\t\t\t\tevent->threads_waiting;\n\tevent->state = EV_STATE_PULSED;\n\tif (event->threads_to_release==1)\n\t    pthread_cond_signal(&event->cond);\n\telse\n\t    pthread_cond_broadcast(&event->cond);\n    }\n    pthread_mutex_unlock(&event->mutex.mutex);\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_event_reset()\n */\nPJ_DEF(pj_status_t) pj_event_reset(pj_event_t *event)\n{\n    pthread_mutex_lock(&event->mutex.mutex);\n    event->state = EV_STATE_OFF;\n    event->threads_to_release = 0;\n    pthread_mutex_unlock(&event->mutex.mutex);\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_event_destroy()\n */\nPJ_DEF(pj_status_t) pj_event_destroy(pj_event_t *event)\n{\n    pj_mutex_destroy(&event->mutex);\n    pthread_cond_destroy(&event->cond);\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJ_HAS_EVENT_OBJ */\n\n///////////////////////////////////////////////////////////////////////////////\n#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0\n/*\n * Terminal\n */\n\n/**\n * Set terminal color.\n */\nPJ_DEF(pj_status_t) pj_term_set_color(pj_color_t color)\n{\n    /* put bright prefix to ansi_color */\n    char ansi_color[12] = \"\\033[01;3\";\n\n    if (color & PJ_TERM_COLOR_BRIGHT) {\n\tcolor ^= PJ_TERM_COLOR_BRIGHT;\n    } else {\n\tstrcpy(ansi_color, \"\\033[00;3\");\n    }\n\n    switch (color) {\n    case 0:\n\t/* black color */\n\tstrcat(ansi_color, \"0m\");\n\tbreak;\n    case PJ_TERM_COLOR_R:\n\t/* red color */\n\tstrcat(ansi_color, \"1m\");\n\tbreak;\n    case PJ_TERM_COLOR_G:\n\t/* green color */\n\tstrcat(ansi_color, \"2m\");\n\tbreak;\n    case PJ_TERM_COLOR_B:\n\t/* blue color */\n\tstrcat(ansi_color, \"4m\");\n\tbreak;\n    case PJ_TERM_COLOR_R | PJ_TERM_COLOR_G:\n\t/* yellow color */\n\tstrcat(ansi_color, \"3m\");\n\tbreak;\n    case PJ_TERM_COLOR_R | PJ_TERM_COLOR_B:\n\t/* magenta color */\n\tstrcat(ansi_color, \"5m\");\n\tbreak;\n    case PJ_TERM_COLOR_G | PJ_TERM_COLOR_B:\n\t/* cyan color */\n\tstrcat(ansi_color, \"6m\");\n\tbreak;\n    case PJ_TERM_COLOR_R | PJ_TERM_COLOR_G | PJ_TERM_COLOR_B:\n\t/* white color */\n\tstrcat(ansi_color, \"7m\");\n\tbreak;\n    default:\n\t/* default console color */\n\tstrcpy(ansi_color, \"\\033[00m\");\n\tbreak;\n    }\n\n    fputs(ansi_color, stdout);\n\n    return PJ_SUCCESS;\n}\n\n/**\n * Get current terminal foreground color.\n */\nPJ_DEF(pj_color_t) pj_term_get_color(void)\n{\n    return 0;\n}\n\n#endif\t/* PJ_TERM_HAS_COLOR */\n\n#if !defined(PJ_DARWINOS) || PJ_DARWINOS == 0\n/*\n * pj_run_app()\n */\nPJ_DEF(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],\n                       unsigned flags)\n{\n    return (*main_func)(argc, argv);\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_core_win32.c",
    "content": "/* $Id: os_core_win32.c 3999 2012-03-30 07:10:13Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/log.h>\n#include <pj/string.h>\n#include <pj/guid.h>\n#include <pj/rand.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/except.h>\n#include <stddef.h>\n#include <stdlib.h>\n#include <stdio.h>\n\n#if defined(PJ_HAS_WINSOCK_H) && PJ_HAS_WINSOCK_H != 0\n#  include <winsock.h>\n#endif\n\n#if defined(PJ_HAS_WINSOCK2_H) && PJ_HAS_WINSOCK2_H != 0\n#  include <winsock2.h>\n#endif\n\n/* Activate mutex related logging if PJ_DEBUG_MUTEX is set, otherwise\n * use default level 6 logging.\n */\n#if defined(PJ_DEBUG_MUTEX) && PJ_DEBUG_MUTEX\n#   undef PJ_DEBUG\n#   define PJ_DEBUG\t    1\n#   define LOG_MUTEX(expr)  PJ_LOG(5,expr)\n#else\n#   define LOG_MUTEX(expr)  PJ_LOG(6,expr)\n#endif\n\n#define THIS_FILE\t\"os_core_win32.c\"\n\n/*\n * Implementation of pj_thread_t.\n */\nstruct pj_thread_t\n{\n    char\t    obj_name[PJ_MAX_OBJ_NAME];\n    HANDLE\t    hthread;\n    DWORD\t    idthread;\n    pj_thread_proc *proc;\n    void\t   *arg;\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n    pj_uint32_t\t    stk_size;\n    pj_uint32_t\t    stk_max_usage;\n    char\t   *stk_start;\n    const char\t   *caller_file;\n    int\t\t    caller_line;\n#endif\n};\n\n\n/*\n * Implementation of pj_mutex_t.\n */\nstruct pj_mutex_t\n{\n#if PJ_WIN32_WINNT >= 0x0400\n    CRITICAL_SECTION\tcrit;\n#else\n    HANDLE\t\thMutex;\n#endif\n    char\t\tobj_name[PJ_MAX_OBJ_NAME];\n#if PJ_DEBUG\n    int\t\t        nesting_level;\n    pj_thread_t\t       *owner;\n#endif\n};\n\n/*\n * Implementation of pj_sem_t.\n */\ntypedef struct pj_sem_t\n{\n    HANDLE\t\thSemaphore;\n    char\t\tobj_name[PJ_MAX_OBJ_NAME];\n} pj_mem_t;\n\n\n/*\n * Implementation of pj_event_t.\n */\nstruct pj_event_t\n{\n    HANDLE\t\thEvent;\n    char\t\tobj_name[PJ_MAX_OBJ_NAME];\n};\n\n/*\n * Implementation of pj_atomic_t.\n */\nstruct pj_atomic_t\n{\n    long value;\n};\n\n/*\n * Flag and reference counter for PJLIB instance.\n */\nstatic int initialized;\n\n/*\n * Static global variables.\n */\nstatic pj_thread_desc main_thread;\nstatic long thread_tls_id = -1;\nstatic pj_mutex_t critical_section_mutex;\nstatic unsigned atexit_count;\nstatic void (*atexit_func[32])(void);\n\n/*\n * Some static prototypes.\n */\nstatic pj_status_t init_mutex(pj_mutex_t *mutex, const char *name);\n\n\n/*\n * pj_init(void).\n * Init PJLIB!\n */\nPJ_DEF(pj_status_t) pj_init(void)\n{\n    WSADATA wsa;\n    char dummy_guid[32]; /* use maximum GUID length */\n    pj_str_t guid;\n    pj_status_t rc;\n\n    /* Check if PJLIB have been initialized */\n    if (initialized) {\n\t++initialized;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Init Winsock.. */\n    if (WSAStartup(MAKEWORD(2,0), &wsa) != 0) {\n\treturn PJ_RETURN_OS_ERROR(WSAGetLastError());\n    }\n\n    /* Init this thread's TLS. */\n    if ((rc=pj_thread_init()) != PJ_SUCCESS) {\n\treturn rc;\n    }\n    \n    /* Init logging */\n    pj_log_init();\n\n    /* Init random seed. */\n    /* Or probably not. Let application in charge of this */\n    /* pj_srand( GetCurrentProcessId() ); */\n\n    /* Initialize critical section. */\n    if ((rc=init_mutex(&critical_section_mutex, \"pj%p\")) != PJ_SUCCESS)\n\treturn rc;\n\n    /* Startup GUID. */\n    guid.ptr = dummy_guid;\n    pj_generate_unique_string( &guid );\n\n    /* Initialize exception ID for the pool. \n     * Must do so after critical section is configured.\n     */\n    rc = pj_exception_id_alloc(\"PJLIB/No memory\", &PJ_NO_MEMORY_EXCEPTION);\n    if (rc != PJ_SUCCESS)\n        return rc;\n\n    /* Startup timestamp */\n#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0\n    {\n\tpj_timestamp dummy_ts;\n\tif ((rc=pj_get_timestamp_freq(&dummy_ts)) != PJ_SUCCESS) {\n\t    return rc;\n\t}\n\tif ((rc=pj_get_timestamp(&dummy_ts)) != PJ_SUCCESS) {\n\t    return rc;\n\t}\n    }\n#endif   \n\n    /* Flag PJLIB as initialized */\n    ++initialized;\n    pj_assert(initialized == 1);\n\n    PJ_LOG(4,(THIS_FILE, \"pjlib %s for win32 initialized\",\n\t      PJ_VERSION));\n\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_atexit()\n */\nPJ_DEF(pj_status_t) pj_atexit(void (*func)(void))\n{\n    if (atexit_count >= PJ_ARRAY_SIZE(atexit_func))\n\treturn PJ_ETOOMANY;\n\n    atexit_func[atexit_count++] = func;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * pj_shutdown(void)\n */\nPJ_DEF(void) pj_shutdown()\n{\n    int i;\n\n    /* Only perform shutdown operation when 'initialized' reaches zero */\n    pj_assert(initialized > 0);\n    if (--initialized != 0)\n\treturn;\n\n    /* Display stack usage */\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n    {\n\tpj_thread_t *rec = (pj_thread_t*)main_thread;\n\tPJ_LOG(5,(rec->obj_name, \"Main thread stack max usage=%u by %s:%d\", \n\t\t  rec->stk_max_usage, rec->caller_file, rec->caller_line));\n    }\n#endif\n\n    /* Call atexit() functions */\n    for (i=atexit_count-1; i>=0; --i) {\n\t(*atexit_func[i])();\n    }\n    atexit_count = 0;\n\n    /* Free exception ID */\n    if (PJ_NO_MEMORY_EXCEPTION != -1) {\n\tpj_exception_id_free(PJ_NO_MEMORY_EXCEPTION);\n\tPJ_NO_MEMORY_EXCEPTION = -1;\n    }\n\n    /* Destroy PJLIB critical section */\n    pj_mutex_destroy(&critical_section_mutex);\n\n    /* Free PJLIB TLS */\n    if (thread_tls_id != -1) {\n\tpj_thread_local_free(thread_tls_id);\n\tthread_tls_id = -1;\n    }\n\n    /* Clear static variables */\n    pj_errno_clear_handlers();\n\n    /* Ticket #1132: Assertion when (re)starting PJLIB on different thread */\n    pj_bzero(main_thread, sizeof(main_thread));\n\n    /* Shutdown Winsock */\n    WSACleanup();\n}\n\n\n/*\n * pj_getpid(void)\n */\nPJ_DEF(pj_uint32_t) pj_getpid(void)\n{\n    PJ_CHECK_STACK();\n    return GetCurrentProcessId();\n}\n\n/*\n * Check if this thread has been registered to PJLIB.\n */\nPJ_DEF(pj_bool_t) pj_thread_is_registered(void)\n{\n    return pj_thread_local_get(thread_tls_id) != 0;\n}\n\n\n/*\n * Get thread priority value for the thread.\n */\nPJ_DEF(int) pj_thread_get_prio(pj_thread_t *thread)\n{\n    return GetThreadPriority(thread->hthread);\n}\n\n\n/*\n * Set the thread priority.\n */\nPJ_DEF(pj_status_t) pj_thread_set_prio(pj_thread_t *thread,  int prio)\n{\n#if PJ_HAS_THREADS\n    PJ_ASSERT_RETURN(thread, PJ_EINVAL);\n    PJ_ASSERT_RETURN(prio>=THREAD_PRIORITY_IDLE && \n\t\t\tprio<=THREAD_PRIORITY_TIME_CRITICAL,\n\t\t     PJ_EINVAL);\n\n    if (SetThreadPriority(thread->hthread, prio) == FALSE)\n\treturn PJ_RETURN_OS_ERROR(GetLastError());\n\n    return PJ_SUCCESS;\n\n#else\n    PJ_UNUSED_ARG(thread);\n    PJ_UNUSED_ARG(prio);\n    pj_assert(\"pj_thread_set_prio() called in non-threading mode!\");\n    return PJ_EINVALIDOP;\n#endif\n}\n\n\n/*\n * Get the lowest priority value available on this system.\n */\nPJ_DEF(int) pj_thread_get_prio_min(pj_thread_t *thread)\n{\n    PJ_UNUSED_ARG(thread);\n    return THREAD_PRIORITY_IDLE;\n}\n\n\n/*\n * Get the highest priority value available on this system.\n */\nPJ_DEF(int) pj_thread_get_prio_max(pj_thread_t *thread)\n{\n    PJ_UNUSED_ARG(thread);\n    return THREAD_PRIORITY_TIME_CRITICAL;\n}\n\n\n/*\n * Get native thread handle\n */\nPJ_DEF(void*) pj_thread_get_os_handle(pj_thread_t *thread) \n{\n    PJ_ASSERT_RETURN(thread, NULL);\n\n#if PJ_HAS_THREADS\n    return thread->hthread;\n#else\n    pj_assert(\"pj_thread_is_registered() called in non-threading mode!\");\n    return NULL;\n#endif\n}\n\n/*\n * pj_thread_register(..)\n */\nPJ_DEF(pj_status_t) pj_thread_register ( const char *cstr_thread_name,\n\t\t\t\t\t pj_thread_desc desc,\n                                         pj_thread_t **thread_ptr)\n{\n    char stack_ptr;\n    pj_status_t rc;\n    pj_thread_t *thread = (pj_thread_t *)desc;\n    pj_str_t thread_name = pj_str((char*)cstr_thread_name);\n\n    /* Size sanity check. */\n    if (sizeof(pj_thread_desc) < sizeof(pj_thread_t)) {\n\tpj_assert(!\"Not enough pj_thread_desc size!\");\n\treturn PJ_EBUG;\n    }\n\n    /* If a thread descriptor has been registered before, just return it. */\n    if (pj_thread_local_get (thread_tls_id) != 0) {\n\t// 2006-02-26 bennylp:\n\t//  This wouldn't work in all cases!.\n\t//  If thread is created by external module (e.g. sound thread),\n\t//  thread may be reused while the pool used for the thread descriptor\n\t//  has been deleted by application.\n\t//*thread_ptr = (pj_thread_t*)pj_thread_local_get (thread_tls_id);\n        //return PJ_SUCCESS;\n    }\n\n    /* Initialize and set the thread entry. */\n    pj_bzero(desc, sizeof(struct pj_thread_t));\n    thread->hthread = GetCurrentThread();\n    thread->idthread = GetCurrentThreadId();\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n    thread->stk_start = &stack_ptr;\n    thread->stk_size = 0xFFFFFFFFUL;\n    thread->stk_max_usage = 0;\n#else\n    stack_ptr = '\\0';\n#endif\n\n    if (cstr_thread_name && pj_strlen(&thread_name) < sizeof(thread->obj_name)-1)\n\tpj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name), \n\t\t\t cstr_thread_name, thread->idthread);\n    else\n\tpj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name), \n\t\t         \"thr%p\", (void*)(pj_ssize_t)thread->idthread);\n    \n    rc = pj_thread_local_set(thread_tls_id, thread);\n    if (rc != PJ_SUCCESS)\n\treturn rc;\n\n    *thread_ptr = thread;\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_thread_init(void)\n */\npj_status_t pj_thread_init(void)\n{\n    pj_status_t rc;\n    pj_thread_t *thread;\n\n    rc = pj_thread_local_alloc(&thread_tls_id);\n    if (rc != PJ_SUCCESS)\n\treturn rc;\n\n    return pj_thread_register(\"thr%p\", main_thread, &thread);\n}\n\nstatic DWORD WINAPI thread_main(void *param)\n{\n    pj_thread_t *rec = param;\n    DWORD result;\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n    rec->stk_start = (char*)&rec;\n#endif\n\n    if (pj_thread_local_set(thread_tls_id, rec) != PJ_SUCCESS) {\n\tpj_assert(!\"TLS is not set (pj_init() error?)\");\n    }\n\n    PJ_LOG(6,(rec->obj_name, \"Thread started\"));\n\n    result = (*rec->proc)(rec->arg);\n\n    PJ_LOG(6,(rec->obj_name, \"Thread quitting\"));\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n    PJ_LOG(5,(rec->obj_name, \"Thread stack max usage=%u by %s:%d\", \n\t      rec->stk_max_usage, rec->caller_file, rec->caller_line));\n#endif\n\n    return (DWORD)result;\n}\n\n/*\n * pj_thread_create(...)\n */\nPJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool, \n                                      const char *thread_name,\n\t\t\t\t      pj_thread_proc *proc, \n                                      void *arg,\n\t\t\t\t      pj_size_t stack_size, \n\t\t\t\t      unsigned flags,\n                                      pj_thread_t **thread_ptr)\n{\n    DWORD dwflags = 0;\n    pj_thread_t *rec;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(pool && proc && thread_ptr, PJ_EINVAL);\n\n    /* Set flags */\n    if (flags & PJ_THREAD_SUSPENDED)\n\tdwflags |= CREATE_SUSPENDED;\n\n    /* Create thread record and assign name for the thread */\n    rec = (struct pj_thread_t*) pj_pool_calloc(pool, 1, sizeof(pj_thread_t));\n    if (!rec)\n\treturn PJ_ENOMEM;\n\n    /* Set name. */\n    if (!thread_name)\n\tthread_name = \"thr%p\";\n\n    if (strchr(thread_name, '%')) {\n\tpj_ansi_snprintf(rec->obj_name, PJ_MAX_OBJ_NAME, thread_name, rec);\n    } else {\n\tpj_ansi_strncpy(rec->obj_name, thread_name, PJ_MAX_OBJ_NAME);\n\trec->obj_name[PJ_MAX_OBJ_NAME-1] = '\\0';\n    }\n\n    PJ_LOG(6, (rec->obj_name, \"Thread created\"));\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0\n    rec->stk_size = stack_size ? (pj_uint32_t)stack_size : 0xFFFFFFFFUL;\n    rec->stk_max_usage = 0;\n#endif\n\n    /* Create the thread. */\n    rec->proc = proc;\n    rec->arg = arg;\n    rec->hthread = CreateThread(NULL, stack_size, \n\t\t\t\tthread_main, rec,\n\t\t\t\tdwflags, &rec->idthread);\n    if (rec->hthread == NULL)\n\treturn PJ_RETURN_OS_ERROR(GetLastError());\n\n    /* Success! */\n    *thread_ptr = rec;\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_thread-get_name()\n */\nPJ_DEF(const char*) pj_thread_get_name(pj_thread_t *p)\n{\n    pj_thread_t *rec = (pj_thread_t*)p;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(p, \"\");\n\n    return rec->obj_name;\n}\n\n/*\n * pj_thread_resume()\n */\nPJ_DEF(pj_status_t) pj_thread_resume(pj_thread_t *p)\n{\n    pj_thread_t *rec = (pj_thread_t*)p;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(p, PJ_EINVAL);\n\n    if (ResumeThread(rec->hthread) == (DWORD)-1)\n        return PJ_RETURN_OS_ERROR(GetLastError());\n    else\n        return PJ_SUCCESS;\n}\n\n/*\n * pj_thread_this()\n */\nPJ_DEF(pj_thread_t*) pj_thread_this(void)\n{\n    pj_thread_t *rec = pj_thread_local_get(thread_tls_id);\n\n    if (rec == NULL) {\n\tpj_assert(!\"Calling pjlib from unknown/external thread. You must \"\n\t\t   \"register external threads with pj_thread_register() \"\n\t\t   \"before calling any pjlib functions.\");\n    }\n\n    /*\n     * MUST NOT check stack because this function is called\n     * by PJ_CHECK_STACK() itself!!!\n     *\n     */\n\n    return rec;\n}\n\n/*\n * pj_thread_join()\n */\nPJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)\n{\n    pj_thread_t *rec = (pj_thread_t *)p;\n    DWORD rc;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(p, PJ_EINVAL);\n\n    if (p == pj_thread_this())\n\treturn PJ_ECANCELLED;\n\n    PJ_LOG(6, (pj_thread_this()->obj_name, \"Joining thread %s\", p->obj_name));\n\n    rc = WaitForSingleObject(rec->hthread, INFINITE);\n\n    if (rc==WAIT_OBJECT_0)\n        return PJ_SUCCESS;\n    else if (rc==WAIT_TIMEOUT)\n        return PJ_ETIMEDOUT;\n    else\n        return PJ_RETURN_OS_ERROR(GetLastError());\n}\n\n/*\n * pj_thread_destroy()\n */\nPJ_DEF(pj_status_t) pj_thread_destroy(pj_thread_t *p)\n{\n    pj_thread_t *rec = (pj_thread_t *)p;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(p, PJ_EINVAL);\n\n    if (CloseHandle(rec->hthread) == TRUE)\n        return PJ_SUCCESS;\n    else\n        return PJ_RETURN_OS_ERROR(GetLastError());\n}\n\n/*\n * pj_thread_sleep()\n */\nPJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)\n{\n    PJ_CHECK_STACK();\n    Sleep(msec);\n    return PJ_SUCCESS;\n}\n\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK != 0\n/*\n * pj_thread_check_stack()\n * Implementation for PJ_CHECK_STACK()\n */\nPJ_DEF(void) pj_thread_check_stack(const char *file, int line)\n{\n    char stk_ptr;\n    pj_uint32_t usage;\n    pj_thread_t *thread = pj_thread_this();\n\n    pj_assert(thread);\n\n    /* Calculate current usage. */\n    usage = (&stk_ptr > thread->stk_start) ? \n\t\t(pj_uint32_t)(&stk_ptr - thread->stk_start) :\n\t\t(pj_uint32_t)(thread->stk_start - &stk_ptr);\n\n    /* Assert if stack usage is dangerously high. */\n    pj_assert(\"STACK OVERFLOW!! \" && (usage <= thread->stk_size - 128));\n\n    /* Keep statistic. */\n    if (usage > thread->stk_max_usage) {\n\tthread->stk_max_usage = usage;\n\tthread->caller_file = file;\n\tthread->caller_line = line;\n    }\n\n}\n\n/*\n * pj_thread_get_stack_max_usage()\n */\nPJ_DEF(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread)\n{\n    return thread->stk_max_usage;\n}\n\n/*\n * pj_thread_get_stack_info()\n */\nPJ_DEF(pj_status_t) pj_thread_get_stack_info( pj_thread_t *thread,\n\t\t\t\t\t      const char **file,\n\t\t\t\t\t      int *line )\n{\n    pj_assert(thread);\n\n    *file = thread->caller_file;\n    *line = thread->caller_line;\n    return 0;\n}\n\n#endif\t/* PJ_OS_HAS_CHECK_STACK */\n\n\n///////////////////////////////////////////////////////////////////////////////\n\n/*\n * pj_atomic_create()\n */\nPJ_DEF(pj_status_t) pj_atomic_create( pj_pool_t *pool, \n                                      pj_atomic_value_t initial,\n                                      pj_atomic_t **atomic_ptr)\n{\n    pj_atomic_t *atomic_var = pj_pool_alloc(pool, sizeof(pj_atomic_t));\n    if (!atomic_var)\n\treturn PJ_ENOMEM;\n\n    atomic_var->value = initial;\n    *atomic_ptr = atomic_var;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_atomic_destroy()\n */\nPJ_DEF(pj_status_t) pj_atomic_destroy( pj_atomic_t *var )\n{\n    PJ_UNUSED_ARG(var);\n    PJ_ASSERT_RETURN(var, PJ_EINVAL);\n\n    return 0;\n}\n\n/*\n * pj_atomic_set()\n */\nPJ_DEF(void) pj_atomic_set( pj_atomic_t *atomic_var, pj_atomic_value_t value)\n{\n    PJ_CHECK_STACK();\n\n    InterlockedExchange(&atomic_var->value, value);\n}\n\n/*\n * pj_atomic_get()\n */\nPJ_DEF(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(atomic_var, 0);\n\n    return atomic_var->value;\n}\n\n/*\n * pj_atomic_inc_and_get()\n */\nPJ_DEF(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var)\n{\n    PJ_CHECK_STACK();\n\n#if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400\n    return InterlockedIncrement(&atomic_var->value);\n#else\n    return InterlockedIncrement(&atomic_var->value);\n#endif\n}\n\n/*\n * pj_atomic_inc()\n */\nPJ_DEF(void) pj_atomic_inc(pj_atomic_t *atomic_var)\n{\n    pj_atomic_inc_and_get(atomic_var);\n}\n\n/*\n * pj_atomic_dec_and_get()\n */\nPJ_DEF(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var)\n{\n    PJ_CHECK_STACK();\n\n#if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400\n    return InterlockedDecrement(&atomic_var->value);\n#else\n    return InterlockedDecrement(&atomic_var->value);\n#endif\n}\n\n/*\n * pj_atomic_dec()\n */\nPJ_DEF(void) pj_atomic_dec(pj_atomic_t *atomic_var)\n{\n    pj_atomic_dec_and_get(atomic_var);\n}\n\n/*\n * pj_atomic_add()\n */\nPJ_DEF(void) pj_atomic_add( pj_atomic_t *atomic_var,\n\t\t\t    pj_atomic_value_t value )\n{\n#if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400\n    InterlockedExchangeAdd( &atomic_var->value, value );\n#else\n    InterlockedExchangeAdd( &atomic_var->value, value );\n#endif\n}\n\n/*\n * pj_atomic_add_and_get()\n */\nPJ_DEF(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,\n\t\t\t                         pj_atomic_value_t value)\n{\n#if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400\n    long oldValue = InterlockedExchangeAdd( &atomic_var->value, value);\n    return oldValue + value;\n#else\n    long oldValue = InterlockedExchangeAdd( &atomic_var->value, value);\n    return oldValue + value;\n#endif\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * pj_thread_local_alloc()\n */\nPJ_DEF(pj_status_t) pj_thread_local_alloc(long *index)\n{\n    PJ_ASSERT_RETURN(index != NULL, PJ_EINVAL);\n\n    //Can't check stack because this function is called in the\n    //beginning before main thread is initialized.\n    //PJ_CHECK_STACK();\n\n    *index = TlsAlloc();\n\n    if (*index == TLS_OUT_OF_INDEXES)\n        return PJ_RETURN_OS_ERROR(GetLastError());\n    else\n        return PJ_SUCCESS;\n}\n\n/*\n * pj_thread_local_free()\n */\nPJ_DEF(void) pj_thread_local_free(long index)\n{\n    PJ_CHECK_STACK();\n    TlsFree(index);\n}\n\n/*\n * pj_thread_local_set()\n */\nPJ_DEF(pj_status_t) pj_thread_local_set(long index, void *value)\n{\n    BOOL rc;\n\n    //Can't check stack because this function is called in the\n    //beginning before main thread is initialized.\n    //PJ_CHECK_STACK();\n    rc = TlsSetValue(index, value);\n    return rc!=0 ? PJ_SUCCESS : PJ_RETURN_OS_ERROR(GetLastError());\n}\n\n/*\n * pj_thread_local_get()\n */\nPJ_DEF(void*) pj_thread_local_get(long index)\n{\n    //Can't check stack because this function is called\n    //by PJ_CHECK_STACK() itself!!!\n    //PJ_CHECK_STACK();\n    return TlsGetValue(index);\n}\n\n///////////////////////////////////////////////////////////////////////////////\nstatic pj_status_t init_mutex(pj_mutex_t *mutex, const char *name)\n{\n\n    PJ_CHECK_STACK();\n\n#if PJ_WIN32_WINNT >= 0x0400\n    InitializeCriticalSection(&mutex->crit);\n#else\n    mutex->hMutex = CreateMutex(NULL, FALSE, NULL);\n    if (!mutex->hMutex) {\n\treturn PJ_RETURN_OS_ERROR(GetLastError());\n    }\n#endif\n\n#if PJ_DEBUG\n    /* Set owner. */\n    mutex->nesting_level = 0;\n    mutex->owner = NULL;\n#endif\n\n    /* Set name. */\n    if (!name) {\n\tname = \"mtx%p\";\n    }\n    if (strchr(name, '%')) {\n\tpj_ansi_snprintf(mutex->obj_name, PJ_MAX_OBJ_NAME, name, mutex);\n    } else {\n\tpj_ansi_strncpy(mutex->obj_name, name, PJ_MAX_OBJ_NAME);\n\tmutex->obj_name[PJ_MAX_OBJ_NAME-1] = '\\0';\n    }\n\n    PJ_LOG(6, (mutex->obj_name, \"Mutex created\"));\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_mutex_create()\n */\nPJ_DEF(pj_status_t) pj_mutex_create(pj_pool_t *pool, \n                                    const char *name, \n                                    int type,\n                                    pj_mutex_t **mutex_ptr)\n{\n    pj_status_t rc;\n    pj_mutex_t *mutex;\n\n    PJ_UNUSED_ARG(type);\n    PJ_ASSERT_RETURN(pool && mutex_ptr, PJ_EINVAL);\n\n    mutex = pj_pool_alloc(pool, sizeof(*mutex));\n    if (!mutex)\n        return PJ_ENOMEM;\n\n    rc = init_mutex(mutex, name);\n    if (rc != PJ_SUCCESS)\n        return rc;\n\n    *mutex_ptr = mutex;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * pj_mutex_create_simple()\n */\nPJ_DEF(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, \n                                            const char *name,\n\t\t\t\t\t    pj_mutex_t **mutex )\n{\n    return pj_mutex_create(pool, name, PJ_MUTEX_SIMPLE, mutex);\n}\n\n/*\n * pj_mutex_create_recursive()\n */\nPJ_DEF(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,\n\t\t\t\t\t       const char *name,\n\t\t\t\t\t       pj_mutex_t **mutex )\n{\n    return pj_mutex_create(pool, name, PJ_MUTEX_RECURSE, mutex);\n}\n\n/*\n * pj_mutex_lock()\n */\nPJ_DEF(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex)\n{\n    pj_status_t status;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n\n    LOG_MUTEX((mutex->obj_name, \"Mutex: thread %s is waiting\", \n\t\t\t\tpj_thread_this()->obj_name));\n\n#if PJ_WIN32_WINNT >= 0x0400\n    EnterCriticalSection(&mutex->crit);\n    status=PJ_SUCCESS;\n#else\n    if (WaitForSingleObject(mutex->hMutex, INFINITE)==WAIT_OBJECT_0)\n        status = PJ_SUCCESS;\n    else\n        status = PJ_STATUS_FROM_OS(GetLastError());\n\n#endif\n    LOG_MUTEX((mutex->obj_name, \n\t      (status==PJ_SUCCESS ? \"Mutex acquired by thread %s\" : \"FAILED by %s\"),\n\t      pj_thread_this()->obj_name));\n\n#if PJ_DEBUG\n    if (status == PJ_SUCCESS) {\n\tmutex->owner = pj_thread_this();\n\t++mutex->nesting_level;\n    }\n#endif\n\n    return status;\n}\n\n/*\n * pj_mutex_unlock()\n */\nPJ_DEF(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex)\n{\n    pj_status_t status;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n\n#if PJ_DEBUG\n    pj_assert(mutex->owner == pj_thread_this());\n    if (--mutex->nesting_level == 0) {\n\tmutex->owner = NULL;\n    }\n#endif\n\n    LOG_MUTEX((mutex->obj_name, \"Mutex released by thread %s\", \n\t\t\t\tpj_thread_this()->obj_name));\n\n#if PJ_WIN32_WINNT >= 0x0400\n    LeaveCriticalSection(&mutex->crit);\n    status=PJ_SUCCESS;\n#else\n    status = ReleaseMutex(mutex->hMutex) ? PJ_SUCCESS : \n                PJ_STATUS_FROM_OS(GetLastError());\n#endif\n    return status;\n}\n\n/*\n * pj_mutex_trylock()\n */\nPJ_DEF(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex)\n{\n    pj_status_t status;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n\n    LOG_MUTEX((mutex->obj_name, \"Mutex: thread %s is trying\", \n\t\t\t\tpj_thread_this()->obj_name));\n\n#if PJ_WIN32_WINNT >= 0x0400\n    status=TryEnterCriticalSection(&mutex->crit) ? PJ_SUCCESS : PJ_EUNKNOWN;\n#else\n    status = WaitForSingleObject(mutex->hMutex, 0)==WAIT_OBJECT_0 ? \n                PJ_SUCCESS : PJ_ETIMEDOUT;\n#endif\n    if (status==PJ_SUCCESS) {\n\tLOG_MUTEX((mutex->obj_name, \"Mutex acquired by thread %s\", \n\t\t\t\t  pj_thread_this()->obj_name));\n\n#if PJ_DEBUG\n\tmutex->owner = pj_thread_this();\n\t++mutex->nesting_level;\n#endif\n    } else {\n\tLOG_MUTEX((mutex->obj_name, \"Mutex: thread %s's trylock() failed\", \n\t\t\t\t    pj_thread_this()->obj_name));\n    }\n\n    return status;\n}\n\n/*\n * pj_mutex_destroy()\n */\nPJ_DEF(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n\n    LOG_MUTEX((mutex->obj_name, \"Mutex destroyed\"));\n\n#if PJ_WIN32_WINNT >= 0x0400\n    DeleteCriticalSection(&mutex->crit);\n    return PJ_SUCCESS;\n#else\n    return CloseHandle(mutex->hMutex) ? PJ_SUCCESS : \n            PJ_RETURN_OS_ERROR(GetLastError());\n#endif\n}\n\n/*\n * pj_mutex_is_locked()\n */\nPJ_DEF(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex)\n{\n#if PJ_DEBUG\n    return mutex->owner == pj_thread_this();\n#else\n    PJ_UNUSED_ARG(mutex);\n    pj_assert(!\"PJ_DEBUG is not set!\");\n    return 1;\n#endif\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Win32 lacks Read/Write mutex, so include the emulation.\n */\n#include \"os_rwmutex.c\"\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * pj_enter_critical_section()\n */\nPJ_DEF(void) pj_enter_critical_section(void)\n{\n    pj_mutex_lock(&critical_section_mutex);\n}\n\n\n/*\n * pj_leave_critical_section()\n */\nPJ_DEF(void) pj_leave_critical_section(void)\n{\n    pj_mutex_unlock(&critical_section_mutex);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0\n\n/*\n * pj_sem_create()\n */\nPJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool, \n                                   const char *name,\n\t\t\t\t   unsigned initial, \n                                   unsigned max,\n                                   pj_sem_t **sem_ptr)\n{\n    pj_sem_t *sem;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(pool && sem_ptr, PJ_EINVAL);\n\n    sem = pj_pool_alloc(pool, sizeof(*sem));    \n    sem->hSemaphore = CreateSemaphore(NULL, initial, max, NULL);\n    if (!sem->hSemaphore)\n\treturn PJ_RETURN_OS_ERROR(GetLastError());\n\n    /* Set name. */\n    if (!name) {\n\tname = \"sem%p\";\n    }\n    if (strchr(name, '%')) {\n\tpj_ansi_snprintf(sem->obj_name, PJ_MAX_OBJ_NAME, name, sem);\n    } else {\n\tpj_ansi_strncpy(sem->obj_name, name, PJ_MAX_OBJ_NAME);\n\tsem->obj_name[PJ_MAX_OBJ_NAME-1] = '\\0';\n    }\n\n    LOG_MUTEX((sem->obj_name, \"Semaphore created\"));\n\n    *sem_ptr = sem;\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t pj_sem_wait_for(pj_sem_t *sem, unsigned timeout)\n{\n    DWORD result;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(sem, PJ_EINVAL);\n\n    LOG_MUTEX((sem->obj_name, \"Semaphore: thread %s is waiting\", \n\t\t\t      pj_thread_this()->obj_name));\n\n    result = WaitForSingleObject(sem->hSemaphore, timeout);\n    if (result == WAIT_OBJECT_0) {\n\tLOG_MUTEX((sem->obj_name, \"Semaphore acquired by thread %s\", \n\t\t\t\t  pj_thread_this()->obj_name));\n    } else {\n\tLOG_MUTEX((sem->obj_name, \"Semaphore: thread %s FAILED to acquire\", \n\t\t\t\t  pj_thread_this()->obj_name));\n    }\n\n    if (result==WAIT_OBJECT_0)\n        return PJ_SUCCESS;\n    else if (result==WAIT_TIMEOUT)\n        return PJ_ETIMEDOUT;\n    else\n        return PJ_RETURN_OS_ERROR(GetLastError());\n}\n\n/*\n * pj_sem_wait()\n */\nPJ_DEF(pj_status_t) pj_sem_wait(pj_sem_t *sem)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(sem, PJ_EINVAL);\n\n    return pj_sem_wait_for(sem, INFINITE);\n}\n\n/*\n * pj_sem_trywait()\n */\nPJ_DEF(pj_status_t) pj_sem_trywait(pj_sem_t *sem)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(sem, PJ_EINVAL);\n\n    return pj_sem_wait_for(sem, 0);\n}\n\n/*\n * pj_sem_post()\n */\nPJ_DEF(pj_status_t) pj_sem_post(pj_sem_t *sem)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(sem, PJ_EINVAL);\n\n    LOG_MUTEX((sem->obj_name, \"Semaphore released by thread %s\",\n\t\t\t      pj_thread_this()->obj_name));\n\n    if (ReleaseSemaphore(sem->hSemaphore, 1, NULL))\n        return PJ_SUCCESS;\n    else\n        return PJ_RETURN_OS_ERROR(GetLastError());\n}\n\n/*\n * pj_sem_destroy()\n */\nPJ_DEF(pj_status_t) pj_sem_destroy(pj_sem_t *sem)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(sem, PJ_EINVAL);\n\n    LOG_MUTEX((sem->obj_name, \"Semaphore destroyed by thread %s\",\n\t\t\t      pj_thread_this()->obj_name));\n\n    if (CloseHandle(sem->hSemaphore))\n        return PJ_SUCCESS;\n    else\n        return PJ_RETURN_OS_ERROR(GetLastError());\n}\n\n#endif\t/* PJ_HAS_SEMAPHORE */\n///////////////////////////////////////////////////////////////////////////////\n\n\n#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0\n\n/*\n * pj_event_create()\n */\nPJ_DEF(pj_status_t) pj_event_create( pj_pool_t *pool, \n                                     const char *name,\n\t\t\t\t     pj_bool_t manual_reset, \n                                     pj_bool_t initial,\n                                     pj_event_t **event_ptr)\n{\n    pj_event_t *event;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(pool && event_ptr, PJ_EINVAL);\n\n    event = pj_pool_alloc(pool, sizeof(*event));\n    if (!event)\n        return PJ_ENOMEM;\n\n    event->hEvent = CreateEvent(NULL, manual_reset?TRUE:FALSE, \n\t\t\t\tinitial?TRUE:FALSE, NULL);\n\n    if (!event->hEvent)\n\treturn PJ_RETURN_OS_ERROR(GetLastError());\n\n    /* Set name. */\n    if (!name) {\n\tname = \"evt%p\";\n    }\n    if (strchr(name, '%')) {\n\tpj_ansi_snprintf(event->obj_name, PJ_MAX_OBJ_NAME, name, event);\n    } else {\n\tpj_ansi_strncpy(event->obj_name, name, PJ_MAX_OBJ_NAME);\n\tevent->obj_name[PJ_MAX_OBJ_NAME-1] = '\\0';\n    }\n\n    PJ_LOG(6, (event->obj_name, \"Event created\"));\n\n    *event_ptr = event;\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t pj_event_wait_for(pj_event_t *event, unsigned timeout)\n{\n    DWORD result;\n\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(event, PJ_EINVAL);\n\n    PJ_LOG(6, (event->obj_name, \"Event: thread %s is waiting\", \n\t\t\t        pj_thread_this()->obj_name));\n\n    result = WaitForSingleObject(event->hEvent, timeout);\n    if (result == WAIT_OBJECT_0) {\n\tPJ_LOG(6, (event->obj_name, \"Event: thread %s is released\", \n\t\t\t\t    pj_thread_this()->obj_name));\n    } else {\n\tPJ_LOG(6, (event->obj_name, \"Event: thread %s FAILED to acquire\", \n\t\t\t\t    pj_thread_this()->obj_name));\n    }\n\n    if (result==WAIT_OBJECT_0)\n        return PJ_SUCCESS;\n    else if (result==WAIT_TIMEOUT)\n        return PJ_ETIMEDOUT;\n    else\n        return PJ_RETURN_OS_ERROR(GetLastError());\n}\n\n/*\n * pj_event_wait()\n */\nPJ_DEF(pj_status_t) pj_event_wait(pj_event_t *event)\n{\n    PJ_ASSERT_RETURN(event, PJ_EINVAL);\n\n    return pj_event_wait_for(event, INFINITE);\n}\n\n/*\n * pj_event_trywait()\n */\nPJ_DEF(pj_status_t) pj_event_trywait(pj_event_t *event)\n{\n    PJ_ASSERT_RETURN(event, PJ_EINVAL);\n\n    return pj_event_wait_for(event, 0);\n}\n\n/*\n * pj_event_set()\n */\nPJ_DEF(pj_status_t) pj_event_set(pj_event_t *event)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(event, PJ_EINVAL);\n\n    PJ_LOG(6, (event->obj_name, \"Setting event\"));\n\n    if (SetEvent(event->hEvent))\n        return PJ_SUCCESS;\n    else\n        return PJ_RETURN_OS_ERROR(GetLastError());\n}\n\n/*\n * pj_event_pulse()\n */\nPJ_DEF(pj_status_t) pj_event_pulse(pj_event_t *event)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(event, PJ_EINVAL);\n\n    PJ_LOG(6, (event->obj_name, \"Pulsing event\"));\n\n    if (PulseEvent(event->hEvent))\n        return PJ_SUCCESS;\n    else\n        return PJ_RETURN_OS_ERROR(GetLastError());\n}\n\n/*\n * pj_event_reset()\n */\nPJ_DEF(pj_status_t) pj_event_reset(pj_event_t *event)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(event, PJ_EINVAL);\n\n    PJ_LOG(6, (event->obj_name, \"Event is reset\"));\n\n    if (ResetEvent(event->hEvent))\n        return PJ_SUCCESS;\n    else\n        return PJ_RETURN_OS_ERROR(GetLastError());\n}\n\n/*\n * pj_event_destroy()\n */\nPJ_DEF(pj_status_t) pj_event_destroy(pj_event_t *event)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(event, PJ_EINVAL);\n\n    PJ_LOG(6, (event->obj_name, \"Event is destroying\"));\n\n    if (CloseHandle(event->hEvent))\n        return PJ_SUCCESS;\n    else\n        return PJ_RETURN_OS_ERROR(GetLastError());\n}\n\n#endif\t/* PJ_HAS_EVENT_OBJ */\n\n///////////////////////////////////////////////////////////////////////////////\n#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0\n/*\n * Terminal color\n */\n\nstatic WORD pj_color_to_os_attr(pj_color_t color)\n{\n    WORD attr = 0;\n\n    if (color & PJ_TERM_COLOR_R)\n\tattr |= FOREGROUND_RED;\n    if (color & PJ_TERM_COLOR_G)\n\tattr |= FOREGROUND_GREEN;\n    if (color & PJ_TERM_COLOR_B)\n\tattr |= FOREGROUND_BLUE;\n    if (color & PJ_TERM_COLOR_BRIGHT)\n\tattr |= FOREGROUND_INTENSITY;\n\n    return attr;\n}\n\nstatic pj_color_t os_attr_to_pj_color(WORD attr)\n{\n    int color = 0;\n\n    if (attr & FOREGROUND_RED)\n\tcolor |= PJ_TERM_COLOR_R;\n    if (attr & FOREGROUND_GREEN)\n\tcolor |= PJ_TERM_COLOR_G;\n    if (attr & FOREGROUND_BLUE)\n\tcolor |= PJ_TERM_COLOR_B;\n    if (attr & FOREGROUND_INTENSITY)\n\tcolor |= PJ_TERM_COLOR_BRIGHT;\n\n    return color;\n}\n\n\n/*\n * pj_term_set_color()\n */\nPJ_DEF(pj_status_t) pj_term_set_color(pj_color_t color)\n{\n    BOOL rc;\n    WORD attr = 0;\n\n    PJ_CHECK_STACK();\n\n    attr = pj_color_to_os_attr(color);\n    rc = SetConsoleTextAttribute( GetStdHandle(STD_OUTPUT_HANDLE), attr);\n    return rc ? PJ_SUCCESS : PJ_RETURN_OS_ERROR(GetLastError());\n}\n\n/*\n * pj_term_get_color()\n * Get current terminal foreground color.\n */\nPJ_DEF(pj_color_t) pj_term_get_color(void)\n{\n    CONSOLE_SCREEN_BUFFER_INFO info;\n\n    PJ_CHECK_STACK();\n\n    GetConsoleScreenBufferInfo( GetStdHandle(STD_OUTPUT_HANDLE), &info);\n    return os_attr_to_pj_color(info.wAttributes);\n}\n\n#endif\t/* PJ_TERM_HAS_COLOR */\n\n/*\n * pj_run_app()\n */\nPJ_DEF(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],\n                       unsigned flags)\n{\n    PJ_UNUSED_ARG(flags);\n    return (*main_func)(argc, argv);\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_error_linux_kernel.c",
    "content": "/* $Id: os_error_linux_kernel.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/string.h>\n#include <pj/compat/errno.h>\n#include <linux/config.h>\n#include <linux/version.h>\n#if defined(MODVERSIONS)\n#include <linux/modversions.h>\n#endif\n#include <linux/kernel.h>\n#include <linux/errno.h>\n\nint kernel_errno;\n\nPJ_DEF(pj_status_t) pj_get_os_error(void)\n{\n    return errno;\n}\n\nPJ_DEF(void) pj_set_os_error(pj_status_t code)\n{\n    errno = code;\n}\n\nPJ_DEF(pj_status_t) pj_get_netos_error(void)\n{\n    return errno;\n}\n\nPJ_DEF(void) pj_set_netos_error(pj_status_t code)\n{\n    errno = code;\n}\n\n/* \n * platform_strerror()\n *\n * Platform specific error message. This file is called by pj_strerror() \n * in errno.c \n */\nint platform_strerror( pj_os_err_type os_errcode, \n                       char *buf, pj_size_t bufsize)\n{\n    char errmsg[PJ_ERR_MSG_SIZE];\n    int len;\n    \n    /* Handle EINVAL as special case so that it'll pass errno test. */\n    if (os_errcode==EINVAL)\n\tstrcpy(errmsg, \"Invalid value\");\n    else\n\tsnprintf(errmsg, sizeof(errmsg), \"errno=%d\", os_errcode);\n    \n    len = strlen(errmsg);\n\n    if (len >= bufsize)\n\tlen = bufsize-1;\n\n    pj_memcpy(buf, errmsg, len);\n    buf[len] = '\\0';\n\n    return len;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_error_symbian.cpp",
    "content": "/* $Id: os_error_symbian.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/errno.h>\n#include <pj/assert.h>\n#include <pj/compat/stdarg.h>\n#include <pj/unicode.h>\n#include <pj/string.h>\n\n#include <e32err.h>\n#include <in_sock.h>\n\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING!=0)\nstatic const struct {\n    pj_os_err_type code;\n    const char *msg;\n} gaErrorList[] = {\n    /*\n     * Generic error -1 to -46\n     */\n    PJ_BUILD_ERR( KErrNotFound,\t    \"Unable to find the specified object\"),\n    PJ_BUILD_ERR( KErrGeneral,\t    \"General (unspecified) error\"),\n    PJ_BUILD_ERR( KErrCancel,\t    \"The operation was cancelled\"),\n    PJ_BUILD_ERR( KErrNoMemory,\t    \"Not enough memory\"),\n    PJ_BUILD_ERR( KErrNotSupported, \"The operation requested is not supported\"),\n    PJ_BUILD_ERR( KErrArgument,\t    \"Bad request\"),\n    PJ_BUILD_ERR( KErrTotalLossOfPrecision, \"Total loss of precision\"),\n    PJ_BUILD_ERR( KErrBadHandle,    \"Bad object\"),\n    PJ_BUILD_ERR( KErrOverflow,\t    \"Overflow\"),\n    PJ_BUILD_ERR( KErrUnderflow,    \"Underflow\"),\n    PJ_BUILD_ERR( KErrAlreadyExists,\"Already exists\"),\n    PJ_BUILD_ERR( KErrPathNotFound, \"Unable to find the specified folder\"),\n    PJ_BUILD_ERR( KErrDied,\t    \"Closed\"),\n    PJ_BUILD_ERR( KErrInUse,\t    \"The specified object is currently in use by another program\"),\n    PJ_BUILD_ERR( KErrServerTerminated,\t    \"Server has closed\"),\n    PJ_BUILD_ERR( KErrServerBusy,   \"Server busy\"),\n    PJ_BUILD_ERR( KErrCompletion,   \"Completion error\"),\n    PJ_BUILD_ERR( KErrNotReady,\t    \"Not ready\"),\n    PJ_BUILD_ERR( KErrUnknown,\t    \"Unknown error\"),\n    PJ_BUILD_ERR( KErrCorrupt,\t    \"Corrupt\"),\n    PJ_BUILD_ERR( KErrAccessDenied, \"Access denied\"),\n    PJ_BUILD_ERR( KErrLocked,\t    \"Locked\"),\n    PJ_BUILD_ERR( KErrWrite,\t    \"Failed to write\"),\n    PJ_BUILD_ERR( KErrDisMounted,   \"Wrong disk present\"),\n    PJ_BUILD_ERR( KErrEof,\t    \"Unexpected end of file\"),\n    PJ_BUILD_ERR( KErrDiskFull,\t    \"Disk full\"),\n    PJ_BUILD_ERR( KErrBadDriver,    \"Bad device driver\"),\n    PJ_BUILD_ERR( KErrBadName,\t    \"Bad name\"),\n    PJ_BUILD_ERR( KErrCommsLineFail,\"Comms line failed\"),\n    PJ_BUILD_ERR( KErrCommsFrame,   \"Comms frame error\"),\n    PJ_BUILD_ERR( KErrCommsOverrun, \"Comms overrun error\"),\n    PJ_BUILD_ERR( KErrCommsParity,  \"Comms parity error\"),\n    PJ_BUILD_ERR( KErrTimedOut,\t    \"Timed out\"),\n    PJ_BUILD_ERR( KErrCouldNotConnect, \"Failed to connect\"),\n    PJ_BUILD_ERR( KErrCouldNotDisconnect, \"Failed to disconnect\"),\n    PJ_BUILD_ERR( KErrDisconnected, \"Disconnected\"),\n    PJ_BUILD_ERR( KErrBadLibraryEntryPoint, \"Bad library entry point\"),\n    PJ_BUILD_ERR( KErrBadDescriptor,\"Bad descriptor\"),\n    PJ_BUILD_ERR( KErrAbort,\t    \"Interrupted\"),\n    PJ_BUILD_ERR( KErrTooBig,\t    \"Too big\"),\n    PJ_BUILD_ERR( KErrDivideByZero, \"Divide by zero\"),\n    PJ_BUILD_ERR( KErrBadPower,\t    \"Batteries too low\"),\n    PJ_BUILD_ERR( KErrDirFull,\t    \"Folder full\"),\n    PJ_BUILD_ERR( KErrHardwareNotAvailable, \"\"),\n    PJ_BUILD_ERR( KErrSessionClosed,\t    \"\"),\n    PJ_BUILD_ERR( KErrPermissionDenied,     \"\"),\n\n    /*\n     * Socket errors (-190 - -1000)\n     */\n    PJ_BUILD_ERR( KErrNetUnreach,   \"Could not connect to the network. Currently unreachable\"),\n    PJ_BUILD_ERR( KErrHostUnreach,  \"Could not connect to the specified server\"),\n    PJ_BUILD_ERR( KErrNoProtocolOpt,\"The specified server refuses the selected protocol\"),\n    PJ_BUILD_ERR( KErrUrgentData,   \"\"),\n    PJ_BUILD_ERR( KErrWouldBlock,   \"Conflicts with KErrExtended, but cannot occur in practice\"),\n\n    {0, NULL}\n};\n\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n\nPJ_DEF(pj_status_t) pj_get_os_error(void)\n{\n    return -1;\n}\n\nPJ_DEF(void) pj_set_os_error(pj_status_t code)\n{\n    PJ_UNUSED_ARG(code);\n}\n\nPJ_DEF(pj_status_t) pj_get_netos_error(void)\n{\n    return -1;\n}\n\nPJ_DEF(void) pj_set_netos_error(pj_status_t code)\n{\n    PJ_UNUSED_ARG(code);\n}\n\nPJ_BEGIN_DECL\n\n    PJ_DECL(int) platform_strerror( pj_os_err_type os_errcode, \n                       \t\t    char *buf, pj_size_t bufsize);\nPJ_END_DECL\n\n/* \n * platform_strerror()\n *\n * Platform specific error message. This file is called by pj_strerror() \n * in errno.c \n */\nPJ_DEF(int) platform_strerror( pj_os_err_type os_errcode, \n\t\t\t       char *buf, pj_size_t bufsize)\n{\n    int len = 0;\n\n    pj_assert(buf != NULL);\n    pj_assert(bufsize >= 0);\n\n    /*\n     * MUST NOT check stack here.\n     * This function might be called from PJ_CHECK_STACK() itself!\n       //PJ_CHECK_STACK();\n     */\n\n    if (!len) {\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING!=0)\n\tint i;\n        for (i = 0; gaErrorList[i].msg; ++i) {\n            if (gaErrorList[i].code == os_errcode) {\n                len = strlen(gaErrorList[i].msg);\n\t\tif ((pj_size_t)len >= bufsize) {\n\t\t    len = bufsize-1;\n\t\t}\n\t\tpj_memcpy(buf, gaErrorList[i].msg, len);\n\t\tbuf[len] = '\\0';\n                break;\n            }\n        }\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n    }\n\n    if (!len) {\n\tlen = pj_ansi_snprintf( buf, bufsize-1, \"Symbian native error %d\",\n\t\t\t\tos_errcode);\n\tbuf[len] = '\\0';\n    }\n\n    return len;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_error_unix.c",
    "content": "/* $Id: os_error_unix.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/errno.h>\n#include <pj/string.h>\n#include <errno.h>\n\nPJ_DEF(pj_status_t) pj_get_os_error(void)\n{\n    return PJ_STATUS_FROM_OS(errno);\n}\n\nPJ_DEF(void) pj_set_os_error(pj_status_t code)\n{\n    errno = PJ_STATUS_TO_OS(code);\n}\n\nPJ_DEF(pj_status_t) pj_get_netos_error(void)\n{\n    return PJ_STATUS_FROM_OS(errno);\n}\n\nPJ_DEF(void) pj_set_netos_error(pj_status_t code)\n{\n    errno = PJ_STATUS_TO_OS(code);\n}\n\nPJ_BEGIN_DECL\n\n    PJ_DECL(int) platform_strerror(pj_os_err_type code, \n                              \t   char *buf, pj_size_t bufsize );\nPJ_END_DECL\n\n/* \n * platform_strerror()\n *\n * Platform specific error message. This file is called by pj_strerror() \n * in errno.c \n */\nint platform_strerror( pj_os_err_type os_errcode, \n                       char *buf, pj_size_t bufsize)\n{\n    const char *syserr = strerror(os_errcode);\n    pj_size_t len = syserr ? strlen(syserr) : 0;\n\n    if (len >= bufsize) len = bufsize - 1;\n    if (len > 0)\n\tpj_memcpy(buf, syserr, len);\n    buf[len] = '\\0';\n    return len;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_error_win32.c",
    "content": "/* $Id: os_error_win32.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/errno.h>\n#include <pj/assert.h>\n#include <pj/compat/stdarg.h>\n#include <pj/unicode.h>\n#include <pj/string.h>\n\n\n#if defined(PJ_HAS_WINSOCK2_H) && PJ_HAS_WINSOCK2_H != 0\n#  include <winsock2.h>\n#elif defined(PJ_HAS_WINSOCK_H) && PJ_HAS_WINSOCK_H != 0\n#  include <winsock.h>\n#endif\n\n\n/*\n * From Apache's APR:\n */\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING!=0)\n\nstatic const struct {\n    pj_os_err_type code;\n    const char *msg;\n} gaErrorList[] = {\n    PJ_BUILD_ERR( WSAEINTR,           \"Interrupted system call\"),\n    PJ_BUILD_ERR( WSAEBADF,           \"Bad file number\"),\n    PJ_BUILD_ERR( WSAEACCES,          \"Permission denied\"),\n    PJ_BUILD_ERR( WSAEFAULT,          \"Bad address\"),\n    PJ_BUILD_ERR( WSAEINVAL,          \"Invalid argument\"),\n    PJ_BUILD_ERR( WSAEMFILE,          \"Too many open sockets\"),\n    PJ_BUILD_ERR( WSAEWOULDBLOCK,     \"Operation would block\"),\n    PJ_BUILD_ERR( WSAEINPROGRESS,     \"Operation now in progress\"),\n    PJ_BUILD_ERR( WSAEALREADY,        \"Operation already in progress\"),\n    PJ_BUILD_ERR( WSAENOTSOCK,        \"Socket operation on non-socket\"),\n    PJ_BUILD_ERR( WSAEDESTADDRREQ,    \"Destination address required\"),\n    PJ_BUILD_ERR( WSAEMSGSIZE,        \"Message too long\"),\n    PJ_BUILD_ERR( WSAEPROTOTYPE,      \"Protocol wrong type for socket\"),\n    PJ_BUILD_ERR( WSAENOPROTOOPT,     \"Bad protocol option\"),\n    PJ_BUILD_ERR( WSAEPROTONOSUPPORT, \"Protocol not supported\"),\n    PJ_BUILD_ERR( WSAESOCKTNOSUPPORT, \"Socket type not supported\"),\n    PJ_BUILD_ERR( WSAEOPNOTSUPP,      \"Operation not supported on socket\"),\n    PJ_BUILD_ERR( WSAEPFNOSUPPORT,    \"Protocol family not supported\"),\n    PJ_BUILD_ERR( WSAEAFNOSUPPORT,    \"Address family not supported\"),\n    PJ_BUILD_ERR( WSAEADDRINUSE,      \"Address already in use\"),\n    PJ_BUILD_ERR( WSAEADDRNOTAVAIL,   \"Can't assign requested address\"),\n    PJ_BUILD_ERR( WSAENETDOWN,        \"Network is down\"),\n    PJ_BUILD_ERR( WSAENETUNREACH,     \"Network is unreachable\"),\n    PJ_BUILD_ERR( WSAENETRESET,       \"Net connection reset\"),\n    PJ_BUILD_ERR( WSAECONNABORTED,    \"Software caused connection abort\"),\n    PJ_BUILD_ERR( WSAECONNRESET,      \"Connection reset by peer\"),\n    PJ_BUILD_ERR( WSAENOBUFS,         \"No buffer space available\"),\n    PJ_BUILD_ERR( WSAEISCONN,         \"Socket is already connected\"),\n    PJ_BUILD_ERR( WSAENOTCONN,        \"Socket is not connected\"),\n    PJ_BUILD_ERR( WSAESHUTDOWN,       \"Can't send after socket shutdown\"),\n    PJ_BUILD_ERR( WSAETOOMANYREFS,    \"Too many references, can't splice\"),\n    PJ_BUILD_ERR( WSAETIMEDOUT,       \"Connection timed out\"),\n    PJ_BUILD_ERR( WSAECONNREFUSED,    \"Connection refused\"),\n    PJ_BUILD_ERR( WSAELOOP,           \"Too many levels of symbolic links\"),\n    PJ_BUILD_ERR( WSAENAMETOOLONG,    \"File name too long\"),\n    PJ_BUILD_ERR( WSAEHOSTDOWN,       \"Host is down\"),\n    PJ_BUILD_ERR( WSAEHOSTUNREACH,    \"No route to host\"),\n    PJ_BUILD_ERR( WSAENOTEMPTY,       \"Directory not empty\"),\n    PJ_BUILD_ERR( WSAEPROCLIM,        \"Too many processes\"),\n    PJ_BUILD_ERR( WSAEUSERS,          \"Too many users\"),\n    PJ_BUILD_ERR( WSAEDQUOT,          \"Disc quota exceeded\"),\n    PJ_BUILD_ERR( WSAESTALE,          \"Stale NFS file handle\"),\n    PJ_BUILD_ERR( WSAEREMOTE,         \"Too many levels of remote in path\"),\n    PJ_BUILD_ERR( WSASYSNOTREADY,     \"Network system is unavailable\"),\n    PJ_BUILD_ERR( WSAVERNOTSUPPORTED, \"Winsock version out of range\"),\n    PJ_BUILD_ERR( WSANOTINITIALISED,  \"WSAStartup not yet called\"),\n    PJ_BUILD_ERR( WSAEDISCON,         \"Graceful shutdown in progress\"),\n/*\n#define WSAENOMORE              (WSABASEERR+102)\n#define WSAECANCELLED           (WSABASEERR+103)\n#define WSAEINVALIDPROCTABLE    (WSABASEERR+104)\n#define WSAEINVALIDPROVIDER     (WSABASEERR+105)\n#define WSAEPROVIDERFAILEDINIT  (WSABASEERR+106)\n#define WSASYSCALLFAILURE       (WSABASEERR+107)\n#define WSASERVICE_NOT_FOUND    (WSABASEERR+108)\n#define WSATYPE_NOT_FOUND       (WSABASEERR+109)\n#define WSA_E_NO_MORE           (WSABASEERR+110)\n#define WSA_E_CANCELLED         (WSABASEERR+111)\n#define WSAEREFUSED             (WSABASEERR+112)\n */\n    PJ_BUILD_ERR( WSAHOST_NOT_FOUND,  \"Host not found\"),\n/*\n#define WSATRY_AGAIN            (WSABASEERR+1002)\n#define WSANO_RECOVERY          (WSABASEERR+1003)\n */\n    PJ_BUILD_ERR( WSANO_DATA,         \"No host data of that type was found\"),\n    {0, NULL}\n};\n\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n\n\nPJ_DEF(pj_status_t) pj_get_os_error(void)\n{\n    return PJ_STATUS_FROM_OS(GetLastError());\n}\n\nPJ_DEF(void) pj_set_os_error(pj_status_t code)\n{\n    SetLastError(PJ_STATUS_TO_OS(code));\n}\n\nPJ_DEF(pj_status_t) pj_get_netos_error(void)\n{\n    return PJ_STATUS_FROM_OS(WSAGetLastError());\n}\n\nPJ_DEF(void) pj_set_netos_error(pj_status_t code)\n{\n    WSASetLastError(PJ_STATUS_TO_OS(code));\n}\n\n/* \n * platform_strerror()\n *\n * Platform specific error message. This file is called by pj_strerror() \n * in errno.c \n */\nint platform_strerror( pj_os_err_type os_errcode, \n                       char *buf, pj_size_t bufsize)\n{\n    pj_size_t len = 0;\n    PJ_DECL_UNICODE_TEMP_BUF(wbuf,128);\n\n    pj_assert(buf != NULL);\n    pj_assert(bufsize >= 0);\n\n    /*\n     * MUST NOT check stack here.\n     * This function might be called from PJ_CHECK_STACK() itself!\n       //PJ_CHECK_STACK();\n     */\n\n    if (!len) {\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING!=0)\n\tint i;\n        for (i = 0; gaErrorList[i].msg; ++i) {\n            if (gaErrorList[i].code == os_errcode) {\n                len = strlen(gaErrorList[i].msg);\n\t\tif ((pj_size_t)len >= bufsize) {\n\t\t    len = bufsize-1;\n\t\t}\n\t\tpj_memcpy(buf, gaErrorList[i].msg, len);\n\t\tbuf[len] = '\\0';\n                break;\n            }\n        }\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n    }\n\n\n    if (!len) {\n#if PJ_NATIVE_STRING_IS_UNICODE\n\tlen = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM \n\t\t\t     | FORMAT_MESSAGE_IGNORE_INSERTS,\n\t\t\t     NULL,\n\t\t\t     os_errcode,\n\t\t\t     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), \n\t\t\t     wbuf,\n\t\t\t     sizeof(wbuf),\n\t\t\t     NULL);\n\tif (len) {\n\t    pj_unicode_to_ansi(wbuf, len, buf, bufsize);\n\t}\n#else\n\tlen = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM \n\t\t\t     | FORMAT_MESSAGE_IGNORE_INSERTS,\n\t\t\t     NULL,\n\t\t\t     os_errcode,\n\t\t\t     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), \n\t\t\t     buf,\n\t\t\t     (int)bufsize,\n\t\t\t     NULL);\n\tbuf[bufsize-1] = '\\0';\n#endif\n\n\tif (len) {\n\t    /* Remove trailing newlines. */\n\t    while (len && (buf[len-1] == '\\n' || buf[len-1] == '\\r')) {\n\t\tbuf[len-1] = '\\0';\n\t\t--len;\n\t    }\n\t}\n    }\n\n    if (!len) {\n\tlen = pj_ansi_snprintf( buf, bufsize, \"Win32 error code %u\", \n\t\t\t\t(unsigned)os_errcode);\n\tif (len < 0 || len >= (int)bufsize)\n\t    len = bufsize-1;\n\tbuf[len] = '\\0';\n    }\n\n    return (int)len;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_info.c",
    "content": "/* $Id: os_info.c 4411 2013-03-04 04:34:38Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/os.h>\n#include <pj/ctype.h>\n#include <pj/errno.h>\n#include <pj/string.h>\n\n/*\n * FYI these links contain useful infos about predefined macros across\n * platforms:\n *  - http://predef.sourceforge.net/preos.html\n */\n\n#if defined(PJ_HAS_SYS_UTSNAME_H) && PJ_HAS_SYS_UTSNAME_H != 0\n/* For uname() */\n#   include <sys/utsname.h>\n#   include <stdlib.h>\n#   define PJ_HAS_UNAME\t\t1\n#endif\n\n#if defined(PJ_HAS_LIMITS_H) && PJ_HAS_LIMITS_H != 0\n/* Include <limits.h> to get <features.h> to get various glibc macros.\n * See http://predef.sourceforge.net/prelib.html\n */\n#   include <limits.h>\n#endif\n\n#if defined(_MSC_VER)\n/* For all Windows including mobile */\n#   include <windows.h>\n#endif\n\n#if defined(PJ_DARWINOS) && PJ_DARWINOS != 0\n#   include \"TargetConditionals.h\"\n#endif\n\n#ifndef PJ_SYS_INFO_BUFFER_SIZE\n#   define PJ_SYS_INFO_BUFFER_SIZE\t64\n#endif\n\n\n#if defined(PJ_DARWINOS) && PJ_DARWINOS != 0 && TARGET_OS_IPHONE\n#   include <sys/types.h>\n#   include <sys/sysctl.h>\n    void pj_iphone_os_get_sys_info(pj_sys_info *si, pj_str_t *si_buffer);\n#endif\n    \n#if defined(PJ_SYMBIAN) && PJ_SYMBIAN != 0\n    PJ_BEGIN_DECL\n    unsigned pj_symbianos_get_model_info(char *buf, unsigned buf_size);\n    unsigned pj_symbianos_get_platform_info(char *buf, unsigned buf_size);\n    void pj_symbianos_get_sdk_info(pj_str_t *name, pj_uint32_t *ver);\n    PJ_END_DECL\n#endif\n\n\nstatic char *ver_info(pj_uint32_t ver, char *buf)\n{\n    pj_size_t len;\n\n    if (ver == 0) {\n\t*buf = '\\0';\n\treturn buf;\n    }\n\n    sprintf(buf, \"-%u.%u\",\n\t    (ver & 0xFF000000) >> 24,\n\t    (ver & 0x00FF0000) >> 16);\n    len = strlen(buf);\n\n    if (ver & 0xFFFF) {\n\tsprintf(buf+len, \".%u\", (ver & 0xFF00) >> 8);\n\tlen = strlen(buf);\n\n\tif (ver & 0x00FF) {\n\t    sprintf(buf+len, \".%u\", (ver & 0xFF));\n\t}\n    }\n\n    return buf;\n}\n\nstatic pj_uint32_t parse_version(char *str)\n{\n    char *tok;\n    int i, maxtok;\n    pj_uint32_t version = 0;\n    \n    while (*str && !pj_isdigit(*str))\n\tstr++;\n\n    maxtok = 4;\n    for (tok = strtok(str, \".-\"), i=0; tok && i<maxtok;\n\t ++i, tok=strtok(NULL, \".-\"))\n    {\n\tint n;\n\n\tif (!pj_isdigit(*tok))\n\t    break;\n\t\n\tn = atoi(tok);\n\tversion |= (n << ((3-i)*8));\n    }\n    \n    return version;\n}\n\nPJ_DEF(const pj_sys_info*) pj_get_sys_info(void)\n{\n    static char si_buffer[PJ_SYS_INFO_BUFFER_SIZE];\n    static pj_sys_info si;\n    static pj_bool_t si_initialized;\n    pj_size_t left = PJ_SYS_INFO_BUFFER_SIZE, len;\n\n    if (si_initialized)\n\treturn &si;\n\n    si.machine.ptr = si.os_name.ptr = si.sdk_name.ptr = si.info.ptr = \"\";\n\n#define ALLOC_CP_STR(str,field)\t\\\n\tdo { \\\n\t    len = pj_ansi_strlen(str); \\\n\t    if (len && left >= len+1) { \\\n\t\tsi.field.ptr = si_buffer + PJ_SYS_INFO_BUFFER_SIZE - left; \\\n\t\tsi.field.slen = len; \\\n\t\tpj_memcpy(si.field.ptr, str, len+1); \\\n\t\tleft -= (len+1); \\\n\t    } \\\n\t} while (0)\n\n    /*\n     * Machine and OS info.\n     */\n#if defined(PJ_HAS_UNAME) && PJ_HAS_UNAME\n    #if defined(PJ_DARWINOS) && PJ_DARWINOS != 0 && TARGET_OS_IPHONE && \\\n\t(!defined TARGET_IPHONE_SIMULATOR || TARGET_IPHONE_SIMULATOR == 0)\n    {\n\tpj_str_t buf = {si_buffer + PJ_SYS_INFO_BUFFER_SIZE - left, left};\n\tpj_str_t machine = {\"arm-\", 4};\n\tpj_str_t sdk_name = {\"iOS-SDK\", 7};\n        size_t size = PJ_SYS_INFO_BUFFER_SIZE - machine.slen;\n\tchar tmp[PJ_SYS_INFO_BUFFER_SIZE];\n        int name[] = {CTL_HW,HW_MACHINE};\n\n\tpj_iphone_os_get_sys_info(&si, &buf);\n\tleft -= si.os_name.slen + 1;\n\n\tsi.os_ver = parse_version(si.machine.ptr);\n\n\tpj_memcpy(tmp, machine.ptr, machine.slen);\n        sysctl(name, 2, tmp+machine.slen, &size, NULL, 0);\n        ALLOC_CP_STR(tmp, machine);\n\tsi.sdk_name = sdk_name;\n\n\t#ifdef PJ_SDK_NAME\n\tpj_memcpy(tmp, PJ_SDK_NAME, pj_ansi_strlen(PJ_SDK_NAME) + 1);\n\tsi.sdk_ver = parse_version(tmp);\n\t#endif\n    }\n    #else    \n    {\n\tstruct utsname u;\n\n\t/* Successful uname() returns zero on Linux and positive value\n\t * on OpenSolaris.\n\t */\n\tif (uname(&u) == -1)\n\t    goto get_sdk_info;\n\n\tALLOC_CP_STR(u.machine, machine);\n\tALLOC_CP_STR(u.sysname, os_name);\n\t\n\tsi.os_ver = parse_version(u.release);\n    }\n    #endif\n#elif defined(_MSC_VER)\n    {\n\tOSVERSIONINFO ovi;\n\n\tovi.dwOSVersionInfoSize = sizeof(ovi);\n\n\tif (GetVersionEx(&ovi) == FALSE)\n\t    goto get_sdk_info;\n\n\tsi.os_ver = (ovi.dwMajorVersion << 24) |\n\t\t    (ovi.dwMinorVersion << 16);\n\t#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE\n\t    si.os_name = pj_str(\"wince\");\n\t#else\n\t    si.os_name = pj_str(\"win32\");\n\t#endif\n    }\n\n    {\n\tSYSTEM_INFO wsi;\n\n\tGetSystemInfo(&wsi);\n\tswitch (wsi.wProcessorArchitecture) {\n    #if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE\n\tcase PROCESSOR_ARCHITECTURE_ARM:\n\t    si.machine = pj_str(\"arm\");\n\t    break;\n\tcase PROCESSOR_ARCHITECTURE_SHX:\n\t    si.machine = pj_str(\"shx\");\n\t    break;\n    #else\n\tcase PROCESSOR_ARCHITECTURE_AMD64:\n\t    si.machine = pj_str(\"x86_64\");\n\t    break;\n\tcase PROCESSOR_ARCHITECTURE_IA64:\n\t    si.machine = pj_str(\"ia64\");\n\t    break;\n\tcase PROCESSOR_ARCHITECTURE_INTEL:\n\t    si.machine = pj_str(\"i386\");\n\t    break;\n    #endif\t/* PJ_WIN32_WINCE */\n\t}\n    }\n#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN != 0\n    {\n\tpj_symbianos_get_model_info(si_buffer, sizeof(si_buffer));\n\tALLOC_CP_STR(si_buffer, machine);\n\t\n\tchar *p = si_buffer + sizeof(si_buffer) - left;\n\tunsigned plen;\n\tplen = pj_symbianos_get_platform_info(p, left);\n\tif (plen) {\n\t    /* Output format will be \"Series60vX.X\" */\n\t    si.os_name = pj_str(\"S60\");\n\t    si.os_ver  = parse_version(p+9);\n\t} else {\n\t    si.os_name = pj_str(\"Unknown\");\n\t}\n\t\n\t/* Avoid compile warning on Symbian. */\n\tgoto get_sdk_info;\n    }\n#endif\n\n    /*\n     * SDK info.\n     */\nget_sdk_info:\n\n#if defined(__GLIBC__)\n    si.sdk_ver = (__GLIBC__ << 24) |\n\t\t (__GLIBC_MINOR__ << 16);\n    si.sdk_name = pj_str(\"glibc\");\n#elif defined(__GNU_LIBRARY__)\n    si.sdk_ver = (__GNU_LIBRARY__ << 24) |\n\t         (__GNU_LIBRARY_MINOR__ << 16);\n    si.sdk_name = pj_str(\"libc\");\n#elif defined(__UCLIBC__)\n    si.sdk_ver = (__UCLIBC_MAJOR__ << 24) |\n    \t         (__UCLIBC_MINOR__ << 16);\n    si.sdk_name = pj_str(\"uclibc\");\n#elif defined(_WIN32_WCE) && _WIN32_WCE\n    /* Old window mobile declares _WIN32_WCE as decimal (e.g. 300, 420, etc.),\n     * but then it was changed to use hex, e.g. 0x420, etc. See\n     * http://social.msdn.microsoft.com/forums/en-US/vssmartdevicesnative/thread/8a97c59f-5a1c-4bc6-99e6-427f065ff439/\n     */\n    #if _WIN32_WCE <= 500\n\tsi.sdk_ver = ( (_WIN32_WCE / 100) << 24) |\n\t\t     ( ((_WIN32_WCE % 100) / 10) << 16) |\n\t\t     ( (_WIN32_WCE % 10) << 8);\n    #else\n\tsi.sdk_ver = ( ((_WIN32_WCE & 0xFF00) >> 8) << 24) |\n\t\t     ( ((_WIN32_WCE & 0x00F0) >> 4) << 16) |\n\t\t     ( ((_WIN32_WCE & 0x000F) >> 0) << 8);\n    #endif\n    si.sdk_name = pj_str(\"cesdk\");\n#elif defined(_MSC_VER)\n    /* No SDK info is easily obtainable for Visual C, so lets just use\n     * _MSC_VER. The _MSC_VER macro reports the major and minor versions\n     * of the compiler. For example, 1310 for Microsoft Visual C++ .NET 2003.\n     * 1310 represents version 13 and a 1.0 point release.\n     * The Visual C++ 2005 compiler version is 1400.\n     */\n    si.sdk_ver = ((_MSC_VER / 100) << 24) |\n    \t         (((_MSC_VER % 100) / 10) << 16) |\n    \t         ((_MSC_VER % 10) << 8);\n    si.sdk_name = pj_str(\"msvc\");\n#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN != 0\n    pj_symbianos_get_sdk_info(&si.sdk_name, &si.sdk_ver);\n#endif\n\n    /*\n     * Build the info string.\n     */\n    {\n\tchar tmp[PJ_SYS_INFO_BUFFER_SIZE];\n\tchar os_ver[20], sdk_ver[20];\n\tint cnt;\n\n\tcnt = pj_ansi_snprintf(tmp, sizeof(tmp),\n\t\t\t       \"%s%s%s%s%s%s%s\",\n\t\t\t       si.os_name.ptr,\n\t\t\t       ver_info(si.os_ver, os_ver),\n\t\t\t       (si.machine.slen ? \"/\" : \"\"),\n\t\t\t       si.machine.ptr,\n\t\t\t       (si.sdk_name.slen ? \"/\" : \"\"),\n\t\t\t       si.sdk_name.ptr,\n\t\t\t       ver_info(si.sdk_ver, sdk_ver));\n\tif (cnt > 0 && cnt < (int)sizeof(tmp)) {\n\t    ALLOC_CP_STR(tmp, info);\n\t}\n    }\n\n    si_initialized = PJ_TRUE;\n    return &si;\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_info_iphone.m",
    "content": "/* $Id: os_info_iphone.m 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include \"TargetConditionals.h\"\n\n#if !defined TARGET_IPHONE_SIMULATOR || TARGET_IPHONE_SIMULATOR == 0\n\n#include <pj/os.h>\n#include <pj/string.h>\n\n#include <UIKit/UIDevice.h>\n\nvoid pj_iphone_os_get_sys_info(pj_sys_info *si, pj_str_t *si_buffer)\n{\n    unsigned buf_len = si_buffer->slen, left = si_buffer->slen, len;\n    UIDevice *device = [UIDevice currentDevice];\n    \n    if ([device respondsToSelector:@selector(isMultitaskingSupported)])\n\tsi->flags |= PJ_SYS_HAS_IOS_BG;\n    \n#define ALLOC_CP_STR(str,field)\t\\\n    do { \\\n\tlen = [str length]; \\\n\tif (len && left >= len+1) { \\\n\t    si->field.ptr = si_buffer->ptr + buf_len - left; \\\n\t    si->field.slen = len; \\\n\t    [str getCString:si->field.ptr maxLength:len+1 \\\n\t\t encoding:NSASCIIStringEncoding]; \\\n\t    left -= (len+1); \\\n\t} \\\n    } while (0)\n\n    ALLOC_CP_STR([device systemName], os_name);\n    ALLOC_CP_STR([device systemVersion], machine);\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_info_symbian.cpp",
    "content": "/* $Id: os_info_symbian.cpp 3437 2011-03-08 06:30:34Z nanang $ */\n/* \n * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#if !defined(PJ_SYMBIAN) || PJ_SYMBIAN == 0\n#   error This file is only for Symbian platform\n#endif\n\n#include <pj/ctype.h>\n#include <pj/string.h>\n\n#include <f32file.h>\t/* link against efsrv.lib\t*/\n#include <hal.h>\t/* link against hal.lib\t\t*/\n#include <utf.h>\t/* link against charconv.lib\t*/\n\n\nPJ_BEGIN_DECL\nunsigned pj_symbianos_get_model_info(char *buf, unsigned buf_size);\nunsigned pj_symbianos_get_platform_info(char *buf, unsigned buf_size);\nvoid pj_symbianos_get_sdk_info(pj_str_t *name, pj_uint32_t *ver);\nPJ_END_DECL\n\n\n/* Get Symbian phone model info, returning length of model info */\nunsigned pj_symbianos_get_model_info(char *buf, unsigned buf_size)\n{\n    pj_str_t model_name;\n\n    /* Get machine UID */\n    TInt hal_val;\n    HAL::Get(HAL::EMachineUid, hal_val);\n    pj_ansi_snprintf(buf, buf_size, \"0x%08X\", hal_val);\n    pj_strset2(&model_name, buf);\n\n    /* Get model name */\n    const pj_str_t st_copyright = {\"(C)\", 3};\n    const pj_str_t st_nokia = {\"Nokia\", 5};\n    char tmp_buf[64];\n    pj_str_t tmp_str;\n\n    _LIT(KModelFilename,\"Z:\\\\resource\\\\versions\\\\model.txt\");\n    RFile file;\n    RFs fs;\n    TInt err;\n    \n    fs.Connect(1);\n    err = file.Open(fs, KModelFilename, EFileRead);\n    if (err == KErrNone) {\n\tTFileText text;\n\ttext.Set(file);\n\tTBuf16<64> ModelName16;\n\terr = text.Read(ModelName16);\n\tif (err == KErrNone) {\n\t    TPtr8 ptr8((TUint8*)tmp_buf, sizeof(tmp_buf));\n\t    ptr8.Copy(ModelName16);\n\t    pj_strset(&tmp_str, tmp_buf, ptr8.Length());\n\t    pj_strtrim(&tmp_str);\n\t}\n\tfile.Close();\n    }\n    fs.Close();\n    if (err != KErrNone)\n\tgoto on_return;\n    \n    /* The retrieved model name is usually in long format, e.g: \n     * \" Nokia N95 (01.01)\", \"(C) Nokia E52\". As we need only\n     * the short version, let's clean it up.\n     */\n    \n    /* Remove preceding non-ASCII chars, e.g: \"\" */\n    char *p = tmp_str.ptr;\n    while (!pj_isascii(*p)) { p++; }\n    pj_strset(&tmp_str, p, tmp_str.slen - (p - tmp_str.ptr));\n    \n    /* Remove \"(C)\" */\n    p = pj_stristr(&tmp_str, &st_copyright);\n    if (p) {\n\tp += st_copyright.slen;\n\tpj_strset(&tmp_str, p, tmp_str.slen - (p - tmp_str.ptr));\n    }\n\n    /* Remove \"Nokia\" */\n    p = pj_stristr(&tmp_str, &st_nokia);\n    if (p) {\n\tp += st_nokia.slen;\n\tpj_strset(&tmp_str, p, tmp_str.slen - (p - tmp_str.ptr));\n    }\n    \n    /* Remove language version, e.g: \"(01.01)\" */\n    p = pj_strchr(&tmp_str, '(');\n    if (p) {\n\ttmp_str.slen = p - tmp_str.ptr;\n    }\n    \n    pj_strtrim(&tmp_str);\n    \n    if (tmp_str.slen == 0)\n\tgoto on_return;\n    \n    if ((unsigned)tmp_str.slen > buf_size - model_name.slen - 3)\n\ttmp_str.slen = buf_size - model_name.slen - 3;\n    \n    pj_strcat2(&model_name, \"(\");\n    pj_strcat(&model_name, &tmp_str);\n    pj_strcat2(&model_name, \")\");\n    \n    /* Zero terminate */\n    buf[model_name.slen] = '\\0';\n    \non_return:\n    return model_name.slen;\n}\n\n\n/* Get platform info, returned format will be \"Series60vX.X\" */\nunsigned pj_symbianos_get_platform_info(char *buf, unsigned buf_size)\n{\n    /* OS info */\n    _LIT(KS60ProductIDFile, \"Series60v*.sis\");\n    _LIT(KROMInstallDir, \"z:\\\\system\\\\install\\\\\");\n\n    RFs fs;\n    TFindFile ff(fs);\n    CDir* result;\n    pj_str_t plat_info = {NULL, 0};\n    TInt err;\n\n    fs.Connect(1);\n    err = ff.FindWildByDir(KS60ProductIDFile, KROMInstallDir, result);\n    if (err == KErrNone) {\n\terr = result->Sort(ESortByName|EDescending);\n\tif (err == KErrNone) {\n\t    TPtr8 tmp_ptr8((TUint8*)buf, buf_size);\n\t    const pj_str_t tmp_ext = {\".sis\", 4};\n\t    char *p;\n\t    \n\t    tmp_ptr8.Copy((*result)[0].iName);\n\t    pj_strset(&plat_info, buf, (pj_size_t)tmp_ptr8.Length());\n\t    p = pj_stristr(&plat_info, &tmp_ext);\n\t    if (p)\n\t\tplat_info.slen -= (p - plat_info.ptr);\n\t}\n\tdelete result;\n    }\n    fs.Close();\n    buf[plat_info.slen] = '\\0';\n    \n    return plat_info.slen;\n}\n\n\n/* Get SDK info */\nvoid pj_symbianos_get_sdk_info(pj_str_t *name, pj_uint32_t *ver)\n{\n    const pj_str_t S60 = {\"S60\", 3};\n    #if defined(__SERIES60_30__)\n\t*name = S60;\n\t*ver  = (3 << 24);\n    #elif defined(__SERIES60_31__)\n\t*name = S60;\n\t*ver  = (3 << 24) | (1 << 16);\n    #elif defined(__S60_32__)\n\t*name = S60;\n\t*ver  = (3 << 24) | (2 << 16);\n    #elif defined(__S60_50__)\n\t*name = S60;\n\t*ver  = (5 << 24);\n    #elif defined(__NOKIA_N97__)\n\t*name = pj_str(\"N97\");\n\t*ver  = (1 << 24);\n    #else\n\t*name = pj_str(\"Unknown\");\n\t*ver  = 0;\n    #endif\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_rwmutex.c",
    "content": "/* $Id: os_rwmutex.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/* \n * Note: \n * \n * DO NOT BUILD THIS FILE DIRECTLY. THIS FILE WILL BE INCLUDED BY os_core_*.c\n * WHEN MACRO PJ_EMULATE_RWMUTEX IS SET.\n */\n\n/*\n * os_rwmutex.c:\n *\n * Implementation of Read-Write mutex for platforms that lack it (e.g.\n * Win32, RTEMS).\n */\n\n\nstruct pj_rwmutex_t\n{\n    pj_mutex_t *read_lock;\n    /* write_lock must use semaphore, because write_lock may be released\n     * by thread other than the thread that acquire the write_lock in the\n     * first place.\n     */\n    pj_sem_t   *write_lock;\n    pj_int32_t  reader_count;\n};\n\n/*\n * Create reader/writer mutex.\n *\n */\nPJ_DEF(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,\n\t\t\t\t      pj_rwmutex_t **p_mutex)\n{\n    pj_status_t status;\n    pj_rwmutex_t *rwmutex;\n\n    PJ_ASSERT_RETURN(pool && p_mutex, PJ_EINVAL);\n\n    *p_mutex = NULL;\n    rwmutex = PJ_POOL_ALLOC_T(pool, pj_rwmutex_t);\n\n    status = pj_mutex_create_simple(pool, name, &rwmutex ->read_lock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    status = pj_sem_create(pool, name, 1, 1, &rwmutex->write_lock);\n    if (status != PJ_SUCCESS) {\n\tpj_mutex_destroy(rwmutex->read_lock);\n\treturn status;\n    }\n\n    rwmutex->reader_count = 0;\n    *p_mutex = rwmutex;\n    return PJ_SUCCESS;\n}\n\n/*\n * Lock the mutex for reading.\n *\n */\nPJ_DEF(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n\n    status = pj_mutex_lock(mutex->read_lock);\n    if (status != PJ_SUCCESS) {\n\tpj_assert(!\"This pretty much is unexpected\");\n\treturn status;\n    }\n\n    mutex->reader_count++;\n\n    pj_assert(mutex->reader_count < 0x7FFFFFF0L);\n\n    if (mutex->reader_count == 1)\n\tpj_sem_wait(mutex->write_lock);\n\n    status = pj_mutex_unlock(mutex->read_lock);\n    return status;\n}\n\n/*\n * Lock the mutex for writing.\n *\n */\nPJ_DEF(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex)\n{\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n    return pj_sem_wait(mutex->write_lock);\n}\n\n/*\n * Release read lock.\n *\n */\nPJ_DEF(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n\n    status = pj_mutex_lock(mutex->read_lock);\n    if (status != PJ_SUCCESS) {\n\tpj_assert(!\"This pretty much is unexpected\");\n\treturn status;\n    }\n\n    pj_assert(mutex->reader_count >= 1);\n\n    --mutex->reader_count;\n    if (mutex->reader_count == 0)\n\tpj_sem_post(mutex->write_lock);\n\n    status = pj_mutex_unlock(mutex->read_lock);\n    return status;\n}\n\n/*\n * Release write lock.\n *\n */\nPJ_DEF(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex)\n{\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n    pj_assert(mutex->reader_count <= 1);\n    return pj_sem_post(mutex->write_lock);\n}\n\n\n/*\n * Destroy reader/writer mutex.\n *\n */\nPJ_DEF(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex)\n{\n    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);\n    pj_mutex_destroy(mutex->read_lock);\n    pj_sem_destroy(mutex->write_lock);\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_symbian.h",
    "content": "/* $Id: os_symbian.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __OS_SYMBIAN_H__\n#define __OS_SYMBIAN_H__\n\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/sock.h>\n#include <pj/os.h>\n#include <pj/string.h>\n\n#include <e32base.h>\n#include <e32cmn.h>\n#include <e32std.h>\n#include <es_sock.h>\n#include <in_sock.h>\n#include <charconv.h>\n#include <utf.h>\n#include <e32cons.h>\n\n// Forward declarations\nclass CPjSocketReader;\n\n#ifndef PJ_SYMBIAN_TIMER_PRIORITY\n#    define PJ_SYMBIAN_TIMER_PRIORITY\tEPriorityNormal\n#endif\n\n//\n// PJLIB Symbian's Socket\n//\nclass CPjSocket\n{\npublic:\n    enum\n    {\n\tMAX_LEN = 1500,\n    };\n\n    // Construct CPjSocket\n    CPjSocket(int af, int sock_type, RSocket &sock)\n\t: af_(af), sock_(sock), sock_type_(sock_type), connected_(false), \n\t  sockReader_(NULL)\n    { \n    }\n\n    // Destroy CPjSocket\n    ~CPjSocket();\n\n    // Get address family\n    int GetAf() const \n    {\n    \treturn af_;\t\n    }\n    \n    // Get the internal RSocket\n    RSocket& Socket()\n    {\n\treturn sock_;\n    }\n\n    // Get socket connected flag.\n    bool IsConnected() const\n    {\n\treturn connected_;\n    }\n\n    // Set socket connected flag.\n    void SetConnected(bool connected)\n    {\n\tconnected_ = connected;\n    }\n\n    // Get socket type\n    int GetSockType() const\n    {\n\treturn sock_type_;\n    }\n    \n    // Returns true if socket is a datagram\n    bool IsDatagram() const\n    {\n\treturn sock_type_ == KSockDatagram;\n    }\n    \n    // Get socket reader, if any.\n    // May return NULL.\n    CPjSocketReader *Reader()\n    {\n\treturn sockReader_;\n    }\n\n    // Create socket reader.\n    CPjSocketReader *CreateReader(unsigned max_len=CPjSocket::MAX_LEN);\n\n    // Delete socket reader when it's not wanted.\n    void DestroyReader();\n    \nprivate:\n    int\t\t     af_;\n    RSocket\t     sock_;\t    // Must not be reference, or otherwise\n\t\t\t\t    // it may point to local variable!\n    unsigned   \t     sock_type_;\n    \n    bool\t     connected_;\n    CPjSocketReader *sockReader_;\n};\n\n\n//\n// Socket reader, used by select() and ioqueue abstraction\n//\nclass CPjSocketReader : public CActive\n{\npublic:\n    // Construct.\n    static CPjSocketReader *NewL(CPjSocket &sock, unsigned max_len=CPjSocket::MAX_LEN);\n\n    // Destroy;\n    ~CPjSocketReader();\n\n    // Start asynchronous read from the socket.\n    void StartRecv(void (*cb)(void *key)=NULL, \n\t\t   void *key=NULL, \n\t\t   TDes8 *aDesc = NULL,\n\t\t   TUint flags = 0);\n\n    // Start asynchronous read from the socket.\n    void StartRecvFrom(void (*cb)(void *key)=NULL, \n\t\t       void *key=NULL, \n\t\t       TDes8 *aDesc = NULL,\n\t\t       TUint flags = 0,\n\t\t       TSockAddr *fromAddr = NULL);\n\n    // Cancel asynchronous read.\n    void DoCancel();\n\n    // Implementation: called when read has completed.\n    void RunL();\n\n    // Check if there's pending data.\n    bool HasData() const\n    {\n\treturn buffer_.Length() != 0;\n    }\n\n    // Append data to aDesc, up to aDesc's maximum size.\n    // If socket is datagram based, buffer_ will be clared.\n    void ReadData(TDes8 &aDesc, TInetAddr *addr=NULL);\n\nprivate:\n    CPjSocket\t   &sock_;\n    bool\t    isDatagram_;\n    TPtr8\t    buffer_;\n    TInetAddr\t    recvAddr_;\n\n    void\t   (*readCb_)(void *key);\n    void\t    *key_;\n\n    //\n    // Constructor\n    //\n    CPjSocketReader(CPjSocket &sock);\n    void ConstructL(unsigned max_len);\n};\n\n\n\n//\n// Time-out Timer Active Object\n//\nclass CPjTimeoutTimer : public CActive\n{\npublic:\n    static CPjTimeoutTimer *NewL();\n    ~CPjTimeoutTimer();\n\n    void StartTimer(TUint miliSeconds);\n    bool HasTimedOut() const;\n\nprotected:\n    virtual void RunL();\n    virtual void DoCancel();\n    virtual TInt RunError(TInt aError);\n\nprivate:\n    RTimer\ttimer_;\n    pj_bool_t\thasTimedOut_;\n\n    CPjTimeoutTimer();\n    void ConstructL();\n};\n\n\n\n//\n// Symbian OS helper for PJLIB\n//\nclass PjSymbianOS\n{\npublic:\n    //\n    // Get the singleton instance of PjSymbianOS\n    //\n    static PjSymbianOS *Instance();\n\n    //\n    // Set parameters\n    //\n    void SetParameters(pj_symbianos_params *params);\n    \n    //\n    // Initialize.\n    //\n    TInt Initialize();\n\n    //\n    // Shutdown.\n    //\n    void Shutdown();\n\n\n    //\n    // Socket helper.\n    //\n\n    // Get RSocketServ instance to be used by all sockets.\n    RSocketServ &SocketServ()\n    {\n\treturn appSocketServ_ ? *appSocketServ_ : socketServ_;\n    }\n\n    // Get RConnection instance, if any.\n    RConnection *Connection() \n    {\n    \treturn appConnection_;\n    }\n    \n    // Convert TInetAddr to pj_sockaddr_in\n    static inline pj_status_t Addr2pj(const TInetAddr & sym_addr,\n\t\t\t       \t      pj_sockaddr &pj_addr,\n\t\t\t       \t      int *addr_len,\n\t\t\t       \t      pj_bool_t convert_ipv4_mapped_addr = PJ_FALSE)\n    {\n    TUint fam = sym_addr.Family();\n\tpj_bzero(&pj_addr, *addr_len);\n\tif (fam == PJ_AF_INET || \n\t\t\t(convert_ipv4_mapped_addr && \n\t\t\t fam == PJ_AF_INET6 && \n\t\t\t sym_addr.IsV4Mapped())) \n\t{\n\t\tpj_addr.addr.sa_family = PJ_AF_INET;\n\t    PJ_ASSERT_RETURN(*addr_len>=(int)sizeof(pj_sockaddr_in), PJ_ETOOSMALL);\n\t    pj_addr.ipv4.sin_addr.s_addr = pj_htonl(sym_addr.Address());\n\t    pj_addr.ipv4.sin_port = pj_htons((pj_uint16_t) sym_addr.Port());\n\t    *addr_len = sizeof(pj_sockaddr_in);\n\t} else if (fam == PJ_AF_INET6) {\n\t    PJ_ASSERT_RETURN(*addr_len>=(int)sizeof(pj_sockaddr_in6), PJ_ETOOSMALL);\n\t    const TIp6Addr & ip6 = sym_addr.Ip6Address();\n\t    pj_addr.addr.sa_family = PJ_AF_INET6;\n\t    pj_memcpy(&pj_addr.ipv6.sin6_addr, ip6.u.iAddr8, 16);\n\t    pj_addr.ipv6.sin6_port = pj_htons((pj_uint16_t) sym_addr.Port());\n\t    pj_addr.ipv6.sin6_scope_id = pj_htonl(sym_addr.Scope());\n\t    pj_addr.ipv6.sin6_flowinfo = pj_htonl(sym_addr.FlowLabel());\n\t    *addr_len = sizeof(pj_sockaddr_in6);\n\t} else {\n\t    pj_assert(!\"Unsupported address family\");\n\t    return PJ_EAFNOTSUP;\n\t}\n\t\n\treturn PJ_SUCCESS;\n    }\n\n\n    // Convert pj_sockaddr_in to TInetAddr\n    static inline pj_status_t pj2Addr(const pj_sockaddr &pj_addr,\n    \t\t\t\t      int addrlen,\n\t\t\t       \t      TInetAddr & sym_addr)\n    {\n    \tif (pj_addr.addr.sa_family == PJ_AF_INET) {\n    \t    PJ_ASSERT_RETURN(addrlen >= (int)sizeof(pj_sockaddr_in), PJ_EINVAL);\n\t    sym_addr.Init(KAfInet);\n    \t    sym_addr.SetAddress((TUint32)pj_ntohl(pj_addr.ipv4.sin_addr.s_addr));\n    \t    sym_addr.SetPort(pj_ntohs(pj_addr.ipv4.sin_port));\n    \t} else if (pj_addr.addr.sa_family == PJ_AF_INET6) {\n    \t    TIp6Addr ip6;\n    \t\n    \t    PJ_ASSERT_RETURN(addrlen>=(int)sizeof(pj_sockaddr_in6), PJ_EINVAL);\n    \t    pj_memcpy(ip6.u.iAddr8, &pj_addr.ipv6.sin6_addr, 16);\n    \t    sym_addr.Init(KAfInet6);\n    \t    sym_addr.SetAddress(ip6);\n    \t    sym_addr.SetScope(pj_ntohl(pj_addr.ipv6.sin6_scope_id));\n    \t    sym_addr.SetFlowLabel(pj_ntohl(pj_addr.ipv6.sin6_flowinfo));\n    \t} else {\n    \t    pj_assert(!\"Unsupported address family\");\n    \t}\n    \treturn PJ_SUCCESS;\n    }\n\n\n    //\n    // Resolver helper\n    //\n\n    // Get RHostResolver instance\n    RHostResolver & GetResolver(int af)\n    {\n    \tif (af==PJ_AF_INET6) {\n    \t    return appHostResolver6_ ? *appHostResolver6_ : hostResolver6_;\n    \t} else {\n    \t    return appHostResolver_ ? *appHostResolver_ : hostResolver_;\n    \t}\n    }\n\n    //\n    // Return true if the access point connection is up\n    //\n    bool IsConnectionUp() const\n    {\n\treturn isConnectionUp_;\n    }\n\n    //\n    // Set access point connection status\n    //\n    void SetConnectionStatus(bool up)\n    {\n\tisConnectionUp_ = up;\n    }\n\n    //\n    // Unicode Converter\n    //\n\n    // Convert to Unicode\n    TInt ConvertToUnicode(TDes16 &aUnicode, const TDesC8 &aForeign);\n\n    // Convert from Unicode\n    TInt ConvertFromUnicode(TDes8 &aForeign, const TDesC16 &aUnicode);\n\n    //\n    // Get console\n    //\n    \n    // Get console\n    CConsoleBase *Console()\n    {\n\treturn console_;\n    }\n    \n    //\n    // Get select() timeout timer.\n    //\n    CPjTimeoutTimer *SelectTimeoutTimer()\n    {\n\treturn selectTimeoutTimer_;\n    }\n\n    //\n    // Wait for any active objects to run.\n    //\n    void WaitForActiveObjects(TInt aPriority = CActive::EPriorityStandard)\n    {\n\tTInt aError;\n\tCActiveScheduler::Current()->WaitForAnyRequest();\n\tCActiveScheduler::RunIfReady(aError, aPriority);\n    }\n\nprivate:\n    bool isConnectionUp_;\n    \n    bool isSocketServInitialized_;\n    RSocketServ socketServ_;\n\n    bool isResolverInitialized_;\n    RHostResolver hostResolver_;\n    RHostResolver hostResolver6_;\n\n    CConsoleBase* console_;\n\n    CPjTimeoutTimer *selectTimeoutTimer_;\n\n    // App parameters\n    RSocketServ *appSocketServ_;\n    RConnection *appConnection_;\n    RHostResolver *appHostResolver_;\n    RHostResolver *appHostResolver6_;\n    \nprivate:\n    PjSymbianOS();\n};\n\n// This macro is used to check the access point connection status and return\n// failure if the AP connection is down or unusable. See the documentation\n// of pj_symbianos_set_connection_status() for more info\n#define PJ_SYMBIAN_CHECK_CONNECTION() \\\n    PJ_SYMBIAN_CHECK_CONNECTION2(PJ_ECANCELLED)\n\n#define PJ_SYMBIAN_CHECK_CONNECTION2(retval) \\\n    do { \\\n\tif (!PjSymbianOS::Instance()->IsConnectionUp()) \\\n\t    return retval; \\\n    } while (0);\n\n#endif\t/* __OS_SYMBIAN_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_time_bsd.c",
    "content": "/* $Id: os_time_bsd.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/os.h>\n#include <pj/compat/time.h>\n\n///////////////////////////////////////////////////////////////////////////////\n\nPJ_DEF(pj_status_t) pj_gettimeofday(pj_time_val *tv)\n{\n    struct timeb tb;\n\n    PJ_CHECK_STACK();\n\n    ftime(&tb);\n    tv->sec = tb.time;\n    tv->msec = tb.millitm;\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_time_common.c",
    "content": "/* $Id: os_time_common.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/os.h>\n#include <pj/compat/time.h>\n#include <pj/errno.h>\n\n\n///////////////////////////////////////////////////////////////////////////////\n\n#if !defined(PJ_WIN32) || PJ_WIN32==0\n\nPJ_DEF(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt)\n{\n    struct tm *local_time;\n\n    PJ_CHECK_STACK();\n\n    local_time = localtime((time_t*)&tv->sec);\n\n    pt->year = local_time->tm_year+1900;\n    pt->mon = local_time->tm_mon;\n    pt->day = local_time->tm_mday;\n    pt->hour = local_time->tm_hour;\n    pt->min = local_time->tm_min;\n    pt->sec = local_time->tm_sec;\n    pt->wday = local_time->tm_wday;\n    pt->msec = tv->msec;\n\n    return PJ_SUCCESS;\n}\n\n/**\n * Encode parsed time to time value.\n */\nPJ_DEF(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv)\n{\n    struct tm local_time;\n\n    local_time.tm_year = pt->year-1900;\n    local_time.tm_mon = pt->mon;\n    local_time.tm_mday = pt->day;\n    local_time.tm_hour = pt->hour;\n    local_time.tm_min = pt->min;\n    local_time.tm_sec = pt->sec;\n    local_time.tm_isdst = 0;\n    \n    tv->sec = mktime(&local_time);\n    tv->msec = pt->msec;\n\n    return PJ_SUCCESS;\n}\n\n#endif /* !PJ_WIN32 */\n\n\n/**\n * Convert local time to GMT.\n */\nPJ_DEF(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv)\n{\n    PJ_UNUSED_ARG(tv);\n    return PJ_EBUG;\n}\n\n/**\n * Convert GMT to local time.\n */\nPJ_DEF(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv)\n{\n    PJ_UNUSED_ARG(tv);\n    return PJ_EBUG;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_time_linux_kernel.c",
    "content": "/* $Id: os_time_linux_kernel.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/os.h>\n#include <linux/time.h>\n\n///////////////////////////////////////////////////////////////////////////////\n\nPJ_DEF(pj_status_t) pj_gettimeofday(pj_time_val *tv)\n{\n    struct timeval tval;\n  \n    do_gettimeofday(&tval);\n    tv->sec = tval.tv_sec;\n    tv->msec = tval.tv_usec / 1000;\n\n    return 0;\n}\n\nPJ_DEF(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt)\n{\n    pt->year = 2005;\n    pt->mon = 8;\n    pt->day = 20;\n    pt->hour = 16;\n    pt->min = 30;\n    pt->sec = 30;\n    pt->wday = 3;\n    pt->yday = 200;\n    pt->msec = 777;\n\n    return -1;\n}\n\n/**\n * Encode parsed time to time value.\n */\nPJ_DEF(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);\n\n/**\n * Convert local time to GMT.\n */\nPJ_DEF(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);\n\n/**\n * Convert GMT to local time.\n */\nPJ_DEF(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_time_unix.c",
    "content": "/* $Id: os_time_unix.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/os.h>\n#include <pj/errno.h>\n#include <pj/compat/time.h>\n\n#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H!=0\n#    include <unistd.h>\n#endif\n\n#include <errno.h>\n\n///////////////////////////////////////////////////////////////////////////////\n\nPJ_DEF(pj_status_t) pj_gettimeofday(pj_time_val *p_tv)\n{\n    struct timeval the_time;\n    int rc;\n\n    PJ_CHECK_STACK();\n\n    rc = gettimeofday(&the_time, NULL);\n    if (rc != 0)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_os_error());\n\n    p_tv->sec = the_time.tv_sec;\n    p_tv->msec = the_time.tv_usec / 1000;\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_time_win32.c",
    "content": "/* $Id: os_time_win32.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/os.h>\n#include <pj/string.h>\n#include <pj/log.h>\n#include <windows.h>\n\n///////////////////////////////////////////////////////////////////////////////\n\n#define SECS_TO_FT_MULT 10000000\n\nstatic LARGE_INTEGER base_time;\n\n#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE\n#   define WINCE_TIME\n#endif\n\n#ifdef WINCE_TIME\n/* Note:\n *  In Windows CE/Windows Mobile platforms, the availability of milliseconds\n *  time resolution in SYSTEMTIME.wMilliseconds depends on the OEM, and most\n *  likely it won't be available. When it's not available, the \n *  SYSTEMTIME.wMilliseconds will contain a constant arbitrary value.\n *\n *  Because of that, we need to emulate the milliseconds time resolution\n *  using QueryPerformanceCounter() (via pj_get_timestamp() API). However \n *  there is limitation on using this, i.e. the time returned by \n *  pj_gettimeofday() may be off by up to plus/minus 999 msec (the second\n *  part will be correct, however the msec part may be off), because we're \n *  not synchronizing the msec field with the change of value of the \"second\"\n *  field of the system time.\n *\n *  Also there is other caveat which need to be handled (and they are \n *  handled by this implementation):\n *   - user may change system time, so pj_gettimeofday() needs to periodically\n *     checks if system time has changed. The period on which system time is\n *     checked is controlled by PJ_WINCE_TIME_CHECK_INTERVAL macro.\n */\nstatic LARGE_INTEGER g_start_time;  /* Time gettimeofday() is first called  */\nstatic pj_timestamp  g_start_tick;  /* TS gettimeofday() is first called  */\nstatic pj_timestamp  g_last_update; /* Last time check_system_time() is \n\t\t\t\t       called, to periodically synchronize\n\t\t\t\t       with up-to-date system time (in case\n\t\t\t\t       user changes system time).\t    */\nstatic pj_uint64_t   g_update_period; /* Period (in TS) check_system_time()\n\t\t\t\t         should be called.\t\t    */\n\n/* Period on which check_system_time() is called, in seconds\t\t    */\n#ifndef PJ_WINCE_TIME_CHECK_INTERVAL\n#   define PJ_WINCE_TIME_CHECK_INTERVAL (10)\n#endif\n\n#endif\n\n#ifdef WINCE_TIME\nstatic pj_status_t init_start_time(void)\n{\n    SYSTEMTIME st;\n    FILETIME ft;\n    pj_timestamp freq;\n    pj_status_t status;\n\n    GetLocalTime(&st);\n    SystemTimeToFileTime(&st, &ft);\n\n    g_start_time.LowPart = ft.dwLowDateTime;\n    g_start_time.HighPart = ft.dwHighDateTime;\n    g_start_time.QuadPart /= SECS_TO_FT_MULT;\n    g_start_time.QuadPart -= base_time.QuadPart;\n\n    status = pj_get_timestamp(&g_start_tick);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    g_last_update.u64 = g_start_tick.u64;\n\n    status = pj_get_timestamp_freq(&freq);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    g_update_period = PJ_WINCE_TIME_CHECK_INTERVAL * freq.u64;\n\n    PJ_LOG(4,(\"os_time_win32.c\", \"WinCE time (re)started\"));\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t check_system_time(pj_uint64_t ts_elapsed)\n{\n    enum { MIS = 5 };\n    SYSTEMTIME st;\n    FILETIME ft;\n    LARGE_INTEGER cur, calc;\n    DWORD diff;\n    pj_timestamp freq;\n    pj_status_t status;\n\n    /* Get system's current time */\n    GetLocalTime(&st);\n    SystemTimeToFileTime(&st, &ft);\n    \n    cur.LowPart = ft.dwLowDateTime;\n    cur.HighPart = ft.dwHighDateTime;\n    cur.QuadPart /= SECS_TO_FT_MULT;\n    cur.QuadPart -= base_time.QuadPart;\n\n    /* Get our calculated system time */\n    status = pj_get_timestamp_freq(&freq);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    calc.QuadPart = g_start_time.QuadPart + ts_elapsed / freq.u64;\n\n    /* See the difference between calculated and actual system time */\n    if (calc.QuadPart >= cur.QuadPart) {\n\tdiff = (DWORD)(calc.QuadPart - cur.QuadPart);\n    } else {\n\tdiff = (DWORD)(cur.QuadPart - calc.QuadPart);\n    }\n\n    if (diff > MIS) {\n\t/* System time has changed */\n\tPJ_LOG(3,(\"os_time_win32.c\", \"WinCE system time changed detected \"\n\t\t\t\t      \"(diff=%u)\", diff));\n\tstatus = init_start_time();\n    } else {\n\tstatus = PJ_SUCCESS;\n    }\n\n    return status;\n}\n\n#endif\n\n// Find 1st Jan 1970 as a FILETIME \nstatic pj_status_t get_base_time(void)\n{\n    SYSTEMTIME st;\n    FILETIME ft;\n    pj_status_t status = PJ_SUCCESS;\n\n    memset(&st,0,sizeof(st));\n    st.wYear=1970;\n    st.wMonth=1;\n    st.wDay=1;\n    SystemTimeToFileTime(&st, &ft);\n    \n    base_time.LowPart = ft.dwLowDateTime;\n    base_time.HighPart = ft.dwHighDateTime;\n    base_time.QuadPart /= SECS_TO_FT_MULT;\n\n#ifdef WINCE_TIME\n    pj_enter_critical_section();\n    status = init_start_time();\n    pj_leave_critical_section();\n#endif\n\n    return status;\n}\n\nPJ_DEF(pj_status_t) pj_gettimeofday(pj_time_val *tv)\n{\n#ifdef WINCE_TIME\n    pj_timestamp tick;\n    pj_uint64_t msec_elapsed;\n#else\n    SYSTEMTIME st;\n    FILETIME ft;\n    LARGE_INTEGER li;\n#endif\n    pj_status_t status;\n\n    if (base_time.QuadPart == 0) {\n\tstatus = get_base_time();\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n#ifdef WINCE_TIME\n    do {\n\tstatus = pj_get_timestamp(&tick);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tif (tick.u64 - g_last_update.u64 >= g_update_period) {\n\t    pj_enter_critical_section();\n\t    if (tick.u64 - g_last_update.u64 >= g_update_period) {\n\t\tg_last_update.u64 = tick.u64;\n\t\tcheck_system_time(tick.u64 - g_start_tick.u64);\n\t    }\n\t    pj_leave_critical_section();\n\t} else {\n\t    break;\n\t}\n    } while (1);\n\n    msec_elapsed = pj_elapsed_msec64(&g_start_tick, &tick);\n\n    tv->sec = (long)(g_start_time.QuadPart + msec_elapsed/1000);\n    tv->msec = (long)(msec_elapsed % 1000);\n#else\n    /* Standard Win32 GetLocalTime */\n    GetLocalTime(&st);\n    SystemTimeToFileTime(&st, &ft);\n\n    li.LowPart = ft.dwLowDateTime;\n    li.HighPart = ft.dwHighDateTime;\n    li.QuadPart /= SECS_TO_FT_MULT;\n    li.QuadPart -= base_time.QuadPart;\n\n    tv->sec = li.LowPart;\n    tv->msec = st.wMilliseconds;\n#endif\t/* WINCE_TIME */\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt)\n{\n    LARGE_INTEGER li;\n    FILETIME ft;\n    SYSTEMTIME st;\n\n    li.QuadPart = tv->sec;\n    li.QuadPart += base_time.QuadPart;\n    li.QuadPart *= SECS_TO_FT_MULT;\n\n    ft.dwLowDateTime = li.LowPart;\n    ft.dwHighDateTime = li.HighPart;\n    FileTimeToSystemTime(&ft, &st);\n\n    pt->year = st.wYear;\n    pt->mon = st.wMonth-1;\n    pt->day = st.wDay;\n    pt->wday = st.wDayOfWeek;\n\n    pt->hour = st.wHour;\n    pt->min = st.wMinute;\n    pt->sec = st.wSecond;\n    pt->msec = tv->msec;\n\n    return PJ_SUCCESS;\n}\n\n/**\n * Encode parsed time to time value.\n */\nPJ_DEF(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv)\n{\n    SYSTEMTIME st;\n    FILETIME ft;\n    LARGE_INTEGER li;\n\n    pj_bzero(&st, sizeof(st));\n    st.wYear = (pj_uint16_t) pt->year;\n    st.wMonth = (pj_uint16_t) (pt->mon + 1);\n    st.wDay = (pj_uint16_t) pt->day;\n    st.wHour = (pj_uint16_t) pt->hour;\n    st.wMinute = (pj_uint16_t) pt->min;\n    st.wSecond = (pj_uint16_t) pt->sec;\n    st.wMilliseconds = (pj_uint16_t) pt->msec;\n    \n    SystemTimeToFileTime(&st, &ft);\n\n    li.LowPart = ft.dwLowDateTime;\n    li.HighPart = ft.dwHighDateTime;\n    li.QuadPart /= SECS_TO_FT_MULT;\n    li.QuadPart -= base_time.QuadPart;\n\n    tv->sec = li.LowPart;\n    tv->msec = st.wMilliseconds;\n\n    return PJ_SUCCESS;\n}\n\n/**\n * Convert local time to GMT.\n */\nPJ_DEF(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);\n\n/**\n * Convert GMT to local time.\n */\nPJ_DEF(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_timestamp_common.c",
    "content": "/* $Id: os_timestamp_common.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/os.h>\n#include <pj/compat/high_precision.h>\n\n#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0\n\n#define U32MAX  (0xFFFFFFFFUL)\n#define NANOSEC (1000000000UL)\n#define USEC    (1000000UL)\n#define MSEC    (1000)\n\n#define u64tohighprec(u64)\t((pj_highprec_t)((pj_int64_t)(u64)))\n\nstatic pj_highprec_t get_elapsed( const pj_timestamp *start,\n                                  const pj_timestamp *stop )\n{\n#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0\n    return u64tohighprec(stop->u64 - start->u64);\n#else\n    pj_highprec_t elapsed_hi, elapsed_lo;\n\n    elapsed_hi = stop->u32.hi - start->u32.hi;\n    elapsed_lo = stop->u32.lo - start->u32.lo;\n\n    /* elapsed_hi = elapsed_hi * U32MAX */\n    pj_highprec_mul(elapsed_hi, U32MAX);\n\n    return elapsed_hi + elapsed_lo;\n#endif\n}\n\nstatic pj_highprec_t elapsed_msec( const pj_timestamp *start,\n                                   const pj_timestamp *stop )\n{\n    pj_timestamp ts_freq;\n    pj_highprec_t freq, elapsed;\n\n    if (pj_get_timestamp_freq(&ts_freq) != PJ_SUCCESS)\n        return 0;\n\n    /* Convert frequency timestamp */\n#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0\n    freq = u64tohighprec(ts_freq.u64);\n#else\n    freq = ts_freq.u32.hi;\n    pj_highprec_mul(freq, U32MAX);\n    freq += ts_freq.u32.lo;\n#endif\n\n    /* Avoid division by zero. */\n    if (freq == 0) freq = 1;\n\n    /* Get elapsed time in cycles. */\n    elapsed = get_elapsed(start, stop);\n\n    /* usec = elapsed * MSEC / freq */\n    pj_highprec_mul(elapsed, MSEC);\n    pj_highprec_div(elapsed, freq);\n\n    return elapsed;\n}\n\nstatic pj_highprec_t elapsed_usec( const pj_timestamp *start,\n                                   const pj_timestamp *stop )\n{\n    pj_timestamp ts_freq;\n    pj_highprec_t freq, elapsed;\n\n    if (pj_get_timestamp_freq(&ts_freq) != PJ_SUCCESS)\n        return 0;\n\n    /* Convert frequency timestamp */\n#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0\n    freq = u64tohighprec(ts_freq.u64);\n#else\n    freq = ts_freq.u32.hi;\n    pj_highprec_mul(freq, U32MAX);\n    freq += ts_freq.u32.lo;\n#endif\n\n    /* Avoid division by zero. */\n    if (freq == 0) freq = 1;\n\n    /* Get elapsed time in cycles. */\n    elapsed = get_elapsed(start, stop);\n\n    /* usec = elapsed * USEC / freq */\n    pj_highprec_mul(elapsed, USEC);\n    pj_highprec_div(elapsed, freq);\n\n    return elapsed;\n}\n\nPJ_DEF(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,\n                                        const pj_timestamp *stop )\n{\n    pj_timestamp ts_freq;\n    pj_highprec_t freq, elapsed;\n\n    if (pj_get_timestamp_freq(&ts_freq) != PJ_SUCCESS)\n        return 0;\n\n    /* Convert frequency timestamp */\n#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0\n    freq = u64tohighprec(ts_freq.u64);\n#else\n    freq = ts_freq.u32.hi;\n    pj_highprec_mul(freq, U32MAX);\n    freq += ts_freq.u32.lo;\n#endif\n\n    /* Avoid division by zero. */\n    if (freq == 0) freq = 1;\n\n    /* Get elapsed time in cycles. */\n    elapsed = get_elapsed(start, stop);\n\n    /* usec = elapsed * USEC / freq */\n    pj_highprec_mul(elapsed, NANOSEC);\n    pj_highprec_div(elapsed, freq);\n\n    return (pj_uint32_t)elapsed;\n}\n\nPJ_DEF(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,\n                                     const pj_timestamp *stop )\n{\n    return (pj_uint32_t)elapsed_usec(start, stop);\n}\n\nPJ_DEF(pj_uint32_t) pj_elapsed_msec( const pj_timestamp *start,\n                                     const pj_timestamp *stop )\n{\n    return (pj_uint32_t)elapsed_msec(start, stop);\n}\n\nPJ_DEF(pj_uint64_t) pj_elapsed_msec64(const pj_timestamp *start,\n                                      const pj_timestamp *stop )\n{\n    return (pj_uint64_t)elapsed_msec(start, stop);\n}\n\nPJ_DEF(pj_time_val) pj_elapsed_time( const pj_timestamp *start,\n                                     const pj_timestamp *stop )\n{\n    pj_highprec_t elapsed = elapsed_msec(start, stop);\n    pj_time_val tv_elapsed;\n\n    if (PJ_HIGHPREC_VALUE_IS_ZERO(elapsed)) {\n        tv_elapsed.sec = tv_elapsed.msec = 0;\n        return tv_elapsed;\n    } else {\n        pj_highprec_t sec, msec;\n\n        sec = elapsed;\n        pj_highprec_div(sec, MSEC);\n        tv_elapsed.sec = (long)sec;\n\n        msec = elapsed;\n        pj_highprec_mod(msec, MSEC);\n        tv_elapsed.msec = (long)msec;\n\n        return tv_elapsed;\n    }\n}\n\nPJ_DEF(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,\n                                      const pj_timestamp *stop )\n{\n    return stop->u32.lo - start->u32.lo;\n}\n\nPJ_DEF(pj_status_t) pj_gettickcount(pj_time_val *tv)\n{\n    pj_timestamp ts, start;\n    pj_status_t status;\n\n    if ((status = pj_get_timestamp(&ts)) != PJ_SUCCESS)\n        return status;\n\n    pj_set_timestamp32(&start, 0, 0);\n    *tv = pj_elapsed_time(&start, &ts);\n\n    return PJ_SUCCESS;\n}\n\n#endif  /* PJ_HAS_HIGH_RES_TIMER */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_timestamp_linux_kernel.c",
    "content": "/* $Id: os_timestamp_linux_kernel.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/os.h>\n#include <linux/time.h>\n\n#if 0\nPJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)\n{\n    ts->u32.hi = 0;\n    ts->u32.lo = jiffies;\n    return 0;\n}\n\nPJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)\n{\n    freq->u32.hi = 0;\n    freq->u32.lo = HZ;\n    return 0;\n}\n#elif 0\nPJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)\n{\n    struct timespec tv;\n    \n    tv = CURRENT_TIME;\n\n    ts->u64 = tv.tv_sec;\n    ts->u64 *= NSEC_PER_SEC;\n    ts->u64 += tv.tv_nsec;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)\n{\n    freq->u32.hi = 0;\n    freq->u32.lo = NSEC_PER_SEC;\n    return 0;\n}\n#else\nPJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)\n{\n    struct timeval tv;\n    \n    do_gettimeofday(&tv);\n\n    ts->u64 = tv.tv_sec;\n    ts->u64 *= USEC_PER_SEC;\n    ts->u64 += tv.tv_usec;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)\n{\n    freq->u32.hi = 0;\n    freq->u32.lo = USEC_PER_SEC;\n    return 0;\n}\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_timestamp_posix.c",
    "content": "/* $Id: os_timestamp_posix.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/os.h>\n#include <pj/errno.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <ctype.h>\n\n#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H != 0\n#   include <unistd.h>\n\n#   if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && \\\n       defined(_POSIX_MONOTONIC_CLOCK)\n#       define USE_POSIX_TIMERS 1\n#   endif\n\n#endif\n\n#if defined(PJ_HAS_PENTIUM) && PJ_HAS_PENTIUM!=0 && \\\n    defined(PJ_TIMESTAMP_USE_RDTSC) && PJ_TIMESTAMP_USE_RDTSC!=0 && \\\n    defined(PJ_M_I386) && PJ_M_I386!=0 && \\\n    defined(PJ_LINUX) && PJ_LINUX!=0\nstatic int machine_speed_mhz;\nstatic pj_timestamp machine_speed;\n\nstatic __inline__ unsigned long long int rdtsc()\n{\n    unsigned long long int x;\n    __asm__ volatile (\".byte 0x0f, 0x31\" : \"=A\" (x));\n    return x;\n}\n\n/* Determine machine's CPU MHz to get the counter's frequency.\n */\nstatic int get_machine_speed_mhz()\n{\n    FILE *strm;\n    char buf[512];\n    int len;\n    char *pos, *end;\n\t\n    PJ_CHECK_STACK();\n\t\n    /* Open /proc/cpuinfo and read the file */\n    strm = fopen(\"/proc/cpuinfo\", \"r\");\n    if (!strm)\n        return -1;\n    len = fread(buf, 1, sizeof(buf), strm);\n    fclose(strm);\n    if (len < 1) {\n        return -1;\n    }\n    buf[len] = '\\0';\n\n    /* Locate the MHz digit. */\n    pos = strstr(buf, \"cpu MHz\");\n    if (!pos)\n        return -1;\n    pos = strchr(pos, ':');\n    if (!pos)\n        return -1;\n    end = (pos += 2);\n    while (isdigit(*end)) ++end;\n    *end = '\\0';\n\n    /* Return the Mhz part, and give it a +1. */\n    return atoi(pos)+1;\n}\n\nPJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)\n{\n    if (machine_speed_mhz == 0) {\n\tmachine_speed_mhz = get_machine_speed_mhz();\n\tif (machine_speed_mhz > 0) {\n\t    machine_speed.u64 = machine_speed_mhz * 1000000.0;\n\t}\n    }\n    \n    if (machine_speed_mhz == -1) {\n\tts->u64 = 0;\n\treturn -1;\n    } \n    ts->u64 = rdtsc();\n    return 0;\n}\n\nPJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)\n{\n    if (machine_speed_mhz == 0) {\n\tmachine_speed_mhz = get_machine_speed_mhz();\n\tif (machine_speed_mhz > 0) {\n\t    machine_speed.u64 = machine_speed_mhz * 1000000.0;\n\t}\n    }\n    \n    if (machine_speed_mhz == -1) {\n\tfreq->u64 = 1;\t/* return 1 to prevent division by zero in apps. */\n\treturn -1;\n    } \n\n    freq->u64 = machine_speed.u64;\n    return 0;\n}\n\n#elif defined(PJ_DARWINOS) && PJ_DARWINOS != 0\n#include <mach/mach.h>\n#include <mach/clock.h>\n#include <errno.h>\n\n#ifndef NSEC_PER_SEC\n#\tdefine NSEC_PER_SEC\t1000000000\n#endif\n\nPJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)\n{\n    mach_timespec_t tp;\n    int ret;\n    clock_serv_t serv;\n\n    ret = host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &serv);\n    if (ret != KERN_SUCCESS) {\n\treturn PJ_RETURN_OS_ERROR(EINVAL);\n    }\n\n    ret = clock_get_time(serv, &tp);\n    if (ret != KERN_SUCCESS) {\n\treturn PJ_RETURN_OS_ERROR(EINVAL);\n    }\n\n    ts->u64 = tp.tv_sec;\n    ts->u64 *= NSEC_PER_SEC;\n    ts->u64 += tp.tv_nsec;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)\n{\n    freq->u32.hi = 0;\n    freq->u32.lo = NSEC_PER_SEC;\n\n    return PJ_SUCCESS;\n}\n\n#elif defined(USE_POSIX_TIMERS) && USE_POSIX_TIMERS != 0\n#include <sys/time.h>\n#include <time.h>\n#include <errno.h>\n\n#define NSEC_PER_SEC\t1000000000\n\nPJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)\n{\n    struct timespec tp;\n\n    if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0) {\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_os_error());\n    }\n\n    ts->u64 = tp.tv_sec;\n    ts->u64 *= NSEC_PER_SEC;\n    ts->u64 += tp.tv_nsec;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)\n{\n    freq->u32.hi = 0;\n    freq->u32.lo = NSEC_PER_SEC;\n\n    return PJ_SUCCESS;\n}\n\n#else\n#include <sys/time.h>\n#include <errno.h>\n\n#define USEC_PER_SEC\t1000000\n\nPJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)\n{\n    struct timeval tv;\n\n    if (gettimeofday(&tv, NULL) != 0) {\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_os_error());\n    }\n\n    ts->u64 = tv.tv_sec;\n    ts->u64 *= USEC_PER_SEC;\n    ts->u64 += tv.tv_usec;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)\n{\n    freq->u32.hi = 0;\n    freq->u32.lo = USEC_PER_SEC;\n\n    return PJ_SUCCESS;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/os_timestamp_win32.c",
    "content": "/* $Id: os_timestamp_win32.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/os.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/log.h>\n#include <windows.h>\n\n#define THIS_FILE   \"os_timestamp_win32.c\"\n\n\n#if 1\n#   define TRACE_(x)\t    PJ_LOG(3,x)\n#else\n#   define TRACE_(x)\t    ;\n#endif\n\n\n/////////////////////////////////////////////////////////////////////////////\n\n#if defined(PJ_TIMESTAMP_USE_RDTSC) && PJ_TIMESTAMP_USE_RDTSC!=0 && \\\n    defined(PJ_M_I386) && PJ_M_I386 != 0 && \\\n    defined(PJ_HAS_PENTIUM) && PJ_HAS_PENTIUM!=0 && \\\n    defined(_MSC_VER)\n\n/*\n * Use rdtsc to get the OS timestamp.\n */\nstatic LONG CpuMhz;\nstatic pj_int64_t CpuHz;\n \nstatic pj_status_t GetCpuHz(void)\n{\n    HKEY key;\n    LONG rc;\n    DWORD size;\n\n#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0\n    rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,\n\t\t      L\"HARDWARE\\\\DESCRIPTION\\\\System\\\\CentralProcessor\\\\0\",\n\t\t      0, 0, &key);\n#else\n    rc = RegOpenKey( HKEY_LOCAL_MACHINE,\n\t\t     \"HARDWARE\\\\DESCRIPTION\\\\System\\\\CentralProcessor\\\\0\",\n\t\t     &key);\n#endif\n\n    if (rc != ERROR_SUCCESS)\n\treturn PJ_RETURN_OS_ERROR(rc);\n\n    size = sizeof(CpuMhz);\n    rc = RegQueryValueEx(key, \"~MHz\", NULL, NULL, (BYTE*)&CpuMhz, &size);\n    RegCloseKey(key);\n\n    if (rc != ERROR_SUCCESS) {\n\treturn PJ_RETURN_OS_ERROR(rc);\n    }\n\n    CpuHz = CpuMhz;\n    CpuHz = CpuHz * 1000000;\n\n    return PJ_SUCCESS;\n}\n\n/* __int64 is nicely returned in EDX:EAX */\n__declspec(naked) __int64 rdtsc() \n{\n    __asm \n    {\n\tRDTSC\n\tRET\n    }\n}\n\nPJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)\n{\n    ts->u64 = rdtsc();\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)\n{\n    pj_status_t status;\n\n    if (CpuHz == 0) {\n\tstatus = GetCpuHz();\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    freq->u64 = CpuHz;\n    return PJ_SUCCESS;\n}\n\n/////////////////////////////////////////////////////////////////////////////\n\n#elif defined(PJ_TIMESTAMP_WIN32_USE_SAFE_QPC) && \\\n         PJ_TIMESTAMP_WIN32_USE_SAFE_QPC!=0\n\n/* Use safe QueryPerformanceCounter.\n * This implementation has some protection against bug in KB Q274323:\n *   Performance counter value may unexpectedly leap forward\n *   http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323\n *\n * THIS SHOULD NOT BE USED YET AS IT DOESN'T HANDLE SYSTEM TIME\n * CHANGE.\n */\n\nstatic pj_timestamp g_ts_freq;\nstatic pj_timestamp g_ts_base;\nstatic pj_int64_t   g_time_base;\n\nPJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)\n{\n    enum { MAX_RETRY = 10 };\n    unsigned i;\n\n\n    /* pj_get_timestamp_freq() must have been called before.\n     * This is done when application called pj_init().\n     */\n    pj_assert(g_ts_freq.u64 != 0);\n\n    /* Retry QueryPerformanceCounter() until we're sure that the\n     * value returned makes sense.\n     */\n    i = 0;\n    do {\n\tLARGE_INTEGER val;\n\tpj_int64_t counter64, time64, diff;\n\tpj_time_val time_now;\n\n\t/* Retrieve the counter */\n\tif (!QueryPerformanceCounter(&val))\n\t    return PJ_RETURN_OS_ERROR(GetLastError());\n\n\t/* Regardless of the goodness of the value, we should put\n\t * the counter here, because normally application wouldn't\n\t * check the error result of this function.\n\t */\n\tts->u64 = val.QuadPart;\n\n\t/* Retrieve time */\n\tpj_gettimeofday(&time_now);\n\n\t/* Get the counter elapsed time in miliseconds */\n\tcounter64 = (val.QuadPart - g_ts_base.u64) * 1000 / g_ts_freq.u64;\n\t\n\t/* Get the time elapsed in miliseconds. \n\t * We don't want to use PJ_TIME_VAL_MSEC() since it's using\n\t * 32bit calculation, which limits the maximum elapsed time\n\t * to around 49 days only.\n\t */\n\ttime64 = time_now.sec;\n\ttime64 = time64 * 1000 + time_now.msec;\n\t//time64 = GetTickCount();\n\n\t/* It's good if the difference between two clocks are within\n\t * some compile time constant (default: 20ms, which to allow\n\t * context switch happen between QueryPerformanceCounter and\n\t * pj_gettimeofday()).\n\t */\n\tdiff = (time64 - g_time_base) - counter64;\n\tif (diff >= -20 && diff <= 20) {\n\t    /* It's good */\n\t    return PJ_SUCCESS;\n\t}\n\n\t++i;\n\n    } while (i < MAX_RETRY);\n\n    TRACE_((THIS_FILE, \"QueryPerformanceCounter returned bad value\"));\n    return PJ_ETIMEDOUT;\n}\n\nstatic pj_status_t init_performance_counter(void)\n{\n    LARGE_INTEGER val;\n    pj_time_val time_base;\n    pj_status_t status;\n\n    /* Get the frequency */\n    if (!QueryPerformanceFrequency(&val))\n\treturn PJ_RETURN_OS_ERROR(GetLastError());\n\n    g_ts_freq.u64 = val.QuadPart;\n\n    /* Get the base timestamp */\n    if (!QueryPerformanceCounter(&val))\n\treturn PJ_RETURN_OS_ERROR(GetLastError());\n\n    g_ts_base.u64 = val.QuadPart;\n\n\n    /* Get the base time */\n    status = pj_gettimeofday(&time_base);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Convert time base to 64bit value in msec */\n    g_time_base = time_base.sec;\n    g_time_base  = g_time_base * 1000 + time_base.msec;\n    //g_time_base = GetTickCount();\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)\n{\n    if (g_ts_freq.u64 == 0) {\n\tenum { MAX_REPEAT = 10 };\n\tunsigned i;\n\tpj_status_t status;\n\n\t/* Make unellegant compiler happy */\n\tstatus = 0;\n\n\t/* Repeat initializing performance counter until we're sure\n\t * the base timing is correct. It is possible that the system\n\t * returns bad counter during this initialization!\n\t */\n\tfor (i=0; i<MAX_REPEAT; ++i) {\n\n\t    pj_timestamp dummy;\n\n\t    /* Init base time */\n\t    status = init_performance_counter();\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    /* Try the base time */\n\t    status = pj_get_timestamp(&dummy);\n\t    if (status == PJ_SUCCESS)\n\t\tbreak;\n\t}\n\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    freq->u64 = g_ts_freq.u64;\n    return PJ_SUCCESS;\n}\n\n/////////////////////////////////////////////////////////////////////////////\n\n#else\n\n/*\n * Use QueryPerformanceCounter and QueryPerformanceFrequency.\n * This should be the default implementation to be used on Windows.\n */\nPJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)\n{\n    LARGE_INTEGER val;\n\n    if (!QueryPerformanceCounter(&val))\n\treturn PJ_RETURN_OS_ERROR(GetLastError());\n\n    ts->u64 = val.QuadPart;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)\n{\n    LARGE_INTEGER val;\n\n    if (!QueryPerformanceFrequency(&val))\n\treturn PJ_RETURN_OS_ERROR(GetLastError());\n\n    freq->u64 = val.QuadPart;\n    return PJ_SUCCESS;\n}\n\n\n#endif\t/* PJ_TIMESTAMP_USE_RDTSC */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/pool.c",
    "content": "/* $Id: pool.c 4298 2012-11-22 05:00:01Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/pool.h>\n#include <pj/log.h>\n#include <pj/except.h>\n#include <pj/assert.h>\n#include <pj/os.h>\n\n#if !PJ_HAS_POOL_ALT_API\n\n\n/* Include inline definitions when inlining is disabled. */\n#if !PJ_FUNCTIONS_ARE_INLINED\n#  include <pj/pool_i.h>\n#endif\n\n#define LOG(expr)   \t\t    PJ_LOG(6,expr)\n#define ALIGN_PTR(PTR,ALIGNMENT)    (PTR + (-(pj_ssize_t)(PTR) & (ALIGNMENT-1)))\n\nPJ_DEF_DATA(int) PJ_NO_MEMORY_EXCEPTION;\n\nPJ_DEF(int) pj_NO_MEMORY_EXCEPTION()\n{\n    return PJ_NO_MEMORY_EXCEPTION;\n}\n\n/*\n * Create new block.\n * Create a new big chunk of memory block, from which user allocation will be\n * taken from.\n */\nstatic pj_pool_block *pj_pool_create_block( pj_pool_t *pool, pj_size_t size)\n{\n    pj_pool_block *block;\n\n    PJ_CHECK_STACK();\n    pj_assert(size >= sizeof(pj_pool_block));\n\n    LOG((pool->obj_name, \"create_block(sz=%u), cur.cap=%u, cur.used=%u\", \n\t size, pool->capacity, pj_pool_get_used_size(pool)));\n\n    /* Request memory from allocator. */\n    block = (pj_pool_block*) \n\t(*pool->factory->policy.block_alloc)(pool->factory, size);\n    if (block == NULL) {\n\t(*pool->callback)(pool, size);\n\treturn NULL;\n    }\n\n    /* Add capacity. */\n    pool->capacity += size;\n\n    /* Set start and end of buffer. */\n    block->buf = ((unsigned char*)block) + sizeof(pj_pool_block);\n    block->end = ((unsigned char*)block) + size;\n\n    /* Set the start pointer, aligning it as needed */\n    block->cur = ALIGN_PTR(block->buf, PJ_POOL_ALIGNMENT);\n\n    /* Insert in the front of the list. */\n    pj_list_insert_after(&pool->block_list, block);\n\n    LOG((pool->obj_name,\" block created, buffer=%p-%p\",block->buf, block->end));\n\n    return block;\n}\n\n/*\n * Allocate memory chunk for user from available blocks.\n * This will iterate through block list to find space to allocate the chunk.\n * If no space is available in all the blocks, a new block might be created\n * (depending on whether the pool is allowed to resize).\n */\nPJ_DEF(void*) pj_pool_allocate_find(pj_pool_t *pool, pj_size_t size)\n{\n    pj_pool_block *block = pool->block_list.next;\n    void *p;\n    pj_size_t block_size;\n\n    PJ_CHECK_STACK();\n\n    while (block != &pool->block_list) {\n\tp = pj_pool_alloc_from_block(block, size);\n\tif (p != NULL)\n\t    return p;\n\tblock = block->next;\n    }\n    /* No available space in all blocks. */\n\n    /* If pool is configured NOT to expand, return error. */\n    if (pool->increment_size == 0) {\n\tLOG((pool->obj_name, \"Can't expand pool to allocate %u bytes \"\n\t     \"(used=%u, cap=%u)\",\n\t     size, pj_pool_get_used_size(pool), pool->capacity));\n\t(*pool->callback)(pool, size);\n\treturn NULL;\n    }\n\n    /* If pool is configured to expand, but the increment size\n     * is less than the required size, expand the pool by multiple\n     * increment size. Also count the size wasted due to aligning\n     * the block.\n     */\n    if (pool->increment_size < \n\t    size + sizeof(pj_pool_block) + PJ_POOL_ALIGNMENT) \n    {\n        pj_size_t count;\n        count = (size + pool->increment_size + sizeof(pj_pool_block) +\n                 PJ_POOL_ALIGNMENT) / \n                pool->increment_size;\n        block_size = count * pool->increment_size;\n\n    } else {\n        block_size = pool->increment_size;\n    }\n\n    LOG((pool->obj_name, \n\t \"%u bytes requested, resizing pool by %u bytes (used=%u, cap=%u)\",\n\t size, block_size, pj_pool_get_used_size(pool), pool->capacity));\n\n    block = pj_pool_create_block(pool, block_size);\n    if (!block)\n\treturn NULL;\n\n    p = pj_pool_alloc_from_block(block, size);\n    pj_assert(p != NULL);\n#if PJ_DEBUG\n    if (p == NULL) {\n\tPJ_UNUSED_ARG(p);\n    }\n#endif\n    return p;\n}\n\n/*\n * Internal function to initialize pool.\n */\nPJ_DEF(void) pj_pool_init_int(  pj_pool_t *pool, \n\t\t\t\tconst char *name,\n\t\t\t\tpj_size_t increment_size,\n\t\t\t\tpj_pool_callback *callback)\n{\n    PJ_CHECK_STACK();\n\n    pool->increment_size = increment_size;\n    pool->callback = callback;\n\n    if (name) {\n\tif (strchr(name, '%') != NULL) {\n\t    pj_ansi_snprintf(pool->obj_name, sizeof(pool->obj_name), \n\t\t\t     name, pool);\n\t} else {\n\t    pj_ansi_strncpy(pool->obj_name, name, PJ_MAX_OBJ_NAME);\n\t    pool->obj_name[PJ_MAX_OBJ_NAME-1] = '\\0';\n\t}\n    } else {\n\tpool->obj_name[0] = '\\0';\n    }\n}\n\n/*\n * Create new memory pool.\n */\nPJ_DEF(pj_pool_t*) pj_pool_create_int( pj_pool_factory *f, const char *name,\n\t\t\t\t       pj_size_t initial_size, \n\t\t\t\t       pj_size_t increment_size,\n\t\t\t\t       pj_pool_callback *callback)\n{\n    pj_pool_t *pool;\n    pj_pool_block *block;\n    pj_uint8_t *buffer;\n\n    PJ_CHECK_STACK();\n\n    /* Size must be at least sizeof(pj_pool)+sizeof(pj_pool_block) */\n    PJ_ASSERT_RETURN(initial_size >= sizeof(pj_pool_t)+sizeof(pj_pool_block),\n\t\t     NULL);\n\n    /* If callback is NULL, set calback from the policy */\n    if (callback == NULL)\n\tcallback = f->policy.callback;\n\n    /* Allocate initial block */\n    buffer = (pj_uint8_t*) (*f->policy.block_alloc)(f, initial_size);\n    if (!buffer)\n\treturn NULL;\n\n    /* Set pool administrative data. */\n    pool = (pj_pool_t*)buffer;\n    pj_bzero(pool, sizeof(*pool));\n\n    pj_list_init(&pool->block_list);\n    pool->factory = f;\n\n    /* Create the first block from the memory. */\n    block = (pj_pool_block*) (buffer + sizeof(*pool));\n    block->buf = ((unsigned char*)block) + sizeof(pj_pool_block);\n    block->end = buffer + initial_size;\n\n    /* Set the start pointer, aligning it as needed */\n    block->cur = ALIGN_PTR(block->buf, PJ_POOL_ALIGNMENT);\n\n    pj_list_insert_after(&pool->block_list, block);\n\n    pj_pool_init_int(pool, name, increment_size, callback);\n\n    /* Pool initial capacity and used size */\n    pool->capacity = initial_size;\n\n    LOG((pool->obj_name, \"pool created, size=%u\", pool->capacity));\n    return pool;\n}\n\n/*\n * Reset the pool to the state when it was created.\n * All blocks will be deallocated except the first block. All memory areas\n * are marked as free.\n */\nstatic void reset_pool(pj_pool_t *pool)\n{\n    pj_pool_block *block;\n\n    PJ_CHECK_STACK();\n\n    block = pool->block_list.prev;\n    if (block == &pool->block_list)\n\treturn;\n\n    /* Skip the first block because it is occupying the same memory\n       as the pool itself.\n    */\n    block = block->prev;\n    \n    while (block != &pool->block_list) {\n\tpj_pool_block *prev = block->prev;\n\tpj_list_erase(block);\n\t(*pool->factory->policy.block_free)(pool->factory, block, \n\t\t\t\t\t    block->end - (unsigned char*)block);\n\tblock = prev;\n    }\n\n    block = pool->block_list.next;\n\n    /* Set the start pointer, aligning it as needed */\n    block->cur = ALIGN_PTR(block->buf, PJ_POOL_ALIGNMENT);\n\n    pool->capacity = block->end - (unsigned char*)pool;\n}\n\n/*\n * The public function to reset pool.\n */\nPJ_DEF(void) pj_pool_reset(pj_pool_t *pool)\n{\n    LOG((pool->obj_name, \"reset(): cap=%d, used=%d(%d%%)\", \n\tpool->capacity, pj_pool_get_used_size(pool), \n\tpj_pool_get_used_size(pool)*100/pool->capacity));\n\n    reset_pool(pool);\n}\n\n/*\n * Destroy the pool.\n */\nPJ_DEF(void) pj_pool_destroy_int(pj_pool_t *pool)\n{\n    pj_size_t initial_size;\n\n    LOG((pool->obj_name, \"destroy(): cap=%d, used=%d(%d%%), block0=%p-%p\", \n\tpool->capacity, pj_pool_get_used_size(pool), \n\tpj_pool_get_used_size(pool)*100/pool->capacity,\n\t((pj_pool_block*)pool->block_list.next)->buf, \n\t((pj_pool_block*)pool->block_list.next)->end));\n\n    reset_pool(pool);\n    initial_size = ((pj_pool_block*)pool->block_list.next)->end - \n\t\t   (unsigned char*)pool;\n    if (pool->factory->policy.block_free)\n\t(*pool->factory->policy.block_free)(pool->factory, pool, initial_size);\n}\n\n\n#endif\t/* PJ_HAS_POOL_ALT_API */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/pool_buf.c",
    "content": "/* $Id: pool_buf.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/pool_buf.h>\n#include <pj/assert.h>\n#include <pj/os.h>\n\nstatic struct pj_pool_factory stack_based_factory;\n\nstruct creation_param\n{\n    void\t*stack_buf;\n    pj_size_t\t size;\n};\n\nstatic int is_initialized;\nstatic long tls = -1;\nstatic void* stack_alloc(pj_pool_factory *factory, pj_size_t size);\n\nstatic void pool_buf_cleanup(void)\n{\n    if (tls != -1) {\n\tpj_thread_local_free(tls);\n\ttls = -1;\n    }\n    if (is_initialized)\n\tis_initialized = 0;\n}\n\nstatic pj_status_t pool_buf_initialize(void)\n{\n    pj_atexit(&pool_buf_cleanup);\n\n    stack_based_factory.policy.block_alloc = &stack_alloc;\n    return pj_thread_local_alloc(&tls);\n}\n\nstatic void* stack_alloc(pj_pool_factory *factory, pj_size_t size)\n{\n    struct creation_param *param;\n    void *buf;\n\n    PJ_UNUSED_ARG(factory);\n\n    param = (struct creation_param*) pj_thread_local_get(tls);\n    if (param == NULL) {\n\t/* Don't assert(), this is normal no-memory situation */\n\treturn NULL;\n    }\n\n    pj_thread_local_set(tls, NULL);\n\n    PJ_ASSERT_RETURN(size <= param->size, NULL);\n\n    buf = param->stack_buf;\n\n    /* Prevent the buffer from being reused */\n    param->stack_buf = NULL;\n\n    return buf;\n}\n\n\nPJ_DEF(pj_pool_t*) pj_pool_create_on_buf(const char *name,\n\t\t\t\t\t void *buf,\n\t\t\t\t\t pj_size_t size)\n{\n#if PJ_HAS_POOL_ALT_API == 0\n    struct creation_param param;\n    pj_size_t align_diff;\n\n    PJ_ASSERT_RETURN(buf && size, NULL);\n\n    if (!is_initialized) {\n\tif (pool_buf_initialize() != PJ_SUCCESS)\n\t    return NULL;\n\tis_initialized = 1;\n    }\n\n    /* Check and align buffer */\n    align_diff = (pj_size_t)buf;\n    if (align_diff & (PJ_POOL_ALIGNMENT-1)) {\n\talign_diff &= (PJ_POOL_ALIGNMENT-1);\n\tbuf = (void*) (((char*)buf) + align_diff);\n\tsize -= align_diff;\n    }\n\n    param.stack_buf = buf;\n    param.size = size;\n    pj_thread_local_set(tls, &param);\n\n    return pj_pool_create_int(&stack_based_factory, name, size, 0, \n\t\t\t      pj_pool_factory_default_policy.callback);\n#else\n    PJ_UNUSED_ARG(buf);\n    return pj_pool_create(NULL, name, size, size, NULL);\n#endif\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/pool_caching.c",
    "content": "/* $Id: pool_caching.c 4298 2012-11-22 05:00:01Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/pool.h>\n#include <pj/log.h>\n#include <pj/string.h>\n#include <pj/assert.h>\n#include <pj/lock.h>\n#include <pj/os.h>\n#include <pj/pool_buf.h>\n\n#if !PJ_HAS_POOL_ALT_API\n\nstatic pj_pool_t* cpool_create_pool(pj_pool_factory *pf, \n\t\t\t\t    const char *name,\n\t\t\t\t    pj_size_t initial_size, \n\t\t\t\t    pj_size_t increment_sz,\n\t\t\t\t    pj_pool_callback *callback);\nstatic void cpool_release_pool(pj_pool_factory *pf, pj_pool_t *pool);\nstatic void cpool_dump_status(pj_pool_factory *factory, pj_bool_t detail );\nstatic pj_bool_t cpool_on_block_alloc(pj_pool_factory *f, pj_size_t sz);\nstatic void cpool_on_block_free(pj_pool_factory *f, pj_size_t sz);\n\n\nstatic pj_size_t pool_sizes[PJ_CACHING_POOL_ARRAY_SIZE] = \n{\n    256, 512, 1024, 2048, 4096, 8192, 12288, 16384, \n    20480, 24576, 28672, 32768, 40960, 49152, 57344, 65536\n};\n\n/* Index where the search for size should begin.\n * Start with pool_sizes[5], which is 8192.\n */\n#define START_SIZE  5\n\n\nPJ_DEF(void) pj_caching_pool_init( pj_caching_pool *cp, \n\t\t\t\t   const pj_pool_factory_policy *policy,\n\t\t\t\t   pj_size_t max_capacity)\n{\n    int i;\n    pj_pool_t *pool;\n\n    PJ_CHECK_STACK();\n\n    pj_bzero(cp, sizeof(*cp));\n    \n    cp->max_capacity = max_capacity;\n    pj_list_init(&cp->used_list);\n    for (i=0; i<PJ_CACHING_POOL_ARRAY_SIZE; ++i)\n\tpj_list_init(&cp->free_list[i]);\n\n    if (policy == NULL) {\n    \tpolicy = &pj_pool_factory_default_policy;\n    }\n    \n    pj_memcpy(&cp->factory.policy, policy, sizeof(pj_pool_factory_policy));\n    cp->factory.create_pool = &cpool_create_pool;\n    cp->factory.release_pool = &cpool_release_pool;\n    cp->factory.dump_status = &cpool_dump_status;\n    cp->factory.on_block_alloc = &cpool_on_block_alloc;\n    cp->factory.on_block_free = &cpool_on_block_free;\n\n    pool = pj_pool_create_on_buf(\"cachingpool\", cp->pool_buf, sizeof(cp->pool_buf));\n    pj_lock_create_simple_mutex(pool, \"cachingpool\", &cp->lock);\n}\n\nPJ_DEF(void) pj_caching_pool_destroy( pj_caching_pool *cp )\n{\n    int i;\n    pj_pool_t *pool;\n\n    PJ_CHECK_STACK();\n\n    /* Delete all pool in free list */\n    for (i=0; i < PJ_CACHING_POOL_ARRAY_SIZE; ++i) {\n\tpj_pool_t *next;\n\tpool = (pj_pool_t*) cp->free_list[i].next;\n\tfor (; pool != (void*)&cp->free_list[i]; pool = next) {\n\t    next = pool->next;\n\t    pj_list_erase(pool);\n\t    pj_pool_destroy_int(pool);\n\t}\n    }\n\n    /* Delete all pools in used list */\n    pool = (pj_pool_t*) cp->used_list.next;\n    while (pool != (pj_pool_t*) &cp->used_list) {\n\tpj_pool_t *next = pool->next;\n\tpj_list_erase(pool);\n\tPJ_LOG(4,(pool->obj_name, \n\t\t  \"Pool is not released by application, releasing now\"));\n\tpj_pool_destroy_int(pool);\n\tpool = next;\n    }\n\n    if (cp->lock) {\n\tpj_lock_destroy(cp->lock);\n\tpj_lock_create_null_mutex(NULL, \"cachingpool\", &cp->lock);\n    }\n}\n\nstatic pj_pool_t* cpool_create_pool(pj_pool_factory *pf, \n\t\t\t\t\t      const char *name, \n\t\t\t\t\t      pj_size_t initial_size, \n\t\t\t\t\t      pj_size_t increment_sz, \n\t\t\t\t\t      pj_pool_callback *callback)\n{\n    pj_caching_pool *cp = (pj_caching_pool*)pf;\n    pj_pool_t *pool;\n    int idx;\n\n    PJ_CHECK_STACK();\n\n    pj_lock_acquire(cp->lock);\n\n    /* Use pool factory's policy when callback is NULL */\n    if (callback == NULL) {\n\tcallback = pf->policy.callback;\n    }\n\n    /* Search the suitable size for the pool. \n     * We'll just do linear search to the size array, as the array size itself\n     * is only a few elements. Binary search I suspect will be less efficient\n     * for this purpose.\n     */\n    if (initial_size <= pool_sizes[START_SIZE]) {\n\tfor (idx=START_SIZE-1; \n\t     idx >= 0 && pool_sizes[idx] >= initial_size;\n\t     --idx)\n\t    ;\n\t++idx;\n    } else {\n\tfor (idx=START_SIZE+1; \n\t     idx < PJ_CACHING_POOL_ARRAY_SIZE && \n\t\t  pool_sizes[idx] < initial_size;\n\t     ++idx)\n\t    ;\n    }\n\n    /* Check whether there's a pool in the list. */\n    if (idx==PJ_CACHING_POOL_ARRAY_SIZE || pj_list_empty(&cp->free_list[idx])) {\n\t/* No pool is available. */\n\t/* Set minimum size. */\n\tif (idx < PJ_CACHING_POOL_ARRAY_SIZE)\n\t    initial_size =  pool_sizes[idx];\n\n\t/* Create new pool */\n\tpool = pj_pool_create_int(&cp->factory, name, initial_size, \n\t\t\t\t  increment_sz, callback);\n\tif (!pool) {\n\t    pj_lock_release(cp->lock);\n\t    return NULL;\n\t}\n\n    } else {\n\t/* Get one pool from the list. */\n\tpool = (pj_pool_t*) cp->free_list[idx].next;\n\tpj_list_erase(pool);\n\n\t/* Initialize the pool. */\n\tpj_pool_init_int(pool, name, increment_sz, callback);\n\n\t/* Update pool manager's free capacity. */\n\tif (cp->capacity > pj_pool_get_capacity(pool)) {\n\t    cp->capacity -= pj_pool_get_capacity(pool);\n\t} else {\n\t    cp->capacity = 0;\n\t}\n\n\tPJ_LOG(6, (pool->obj_name, \"pool reused, size=%u\", pool->capacity));\n    }\n\n    /* Put in used list. */\n    pj_list_insert_before( &cp->used_list, pool );\n\n    /* Mark factory data */\n    pool->factory_data = (void*) (pj_ssize_t) idx;\n\n    /* Increment used count. */\n    ++cp->used_count;\n\n    pj_lock_release(cp->lock);\n    return pool;\n}\n\nstatic void cpool_release_pool( pj_pool_factory *pf, pj_pool_t *pool)\n{\n    pj_caching_pool *cp = (pj_caching_pool*)pf;\n    pj_size_t pool_capacity;\n    unsigned i;\n\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_ON_FAIL(pf && pool, return);\n\n    pj_lock_acquire(cp->lock);\n\n#if PJ_SAFE_POOL\n    /* Make sure pool is still in our used list */\n    if (pj_list_find_node(&cp->used_list, pool) != pool) {\n\tpj_assert(!\"Attempt to destroy pool that has been destroyed before\");\n\treturn;\n    }\n#endif\n\n    /* Erase from the used list. */\n    pj_list_erase(pool);\n\n    /* Decrement used count. */\n    --cp->used_count;\n\n    pool_capacity = pj_pool_get_capacity(pool);\n\n    /* Destroy the pool if the size is greater than our size or if the total\n     * capacity in our recycle list (plus the size of the pool) exceeds \n     * maximum capacity.\n   . */\n    if (pool_capacity > pool_sizes[PJ_CACHING_POOL_ARRAY_SIZE-1] ||\n\tcp->capacity + pool_capacity > cp->max_capacity)\n    {\n\tpj_pool_destroy_int(pool);\n\tpj_lock_release(cp->lock);\n\treturn;\n    }\n\n    /* Reset pool. */\n    PJ_LOG(6, (pool->obj_name, \"recycle(): cap=%d, used=%d(%d%%)\", \n\t       pool_capacity, pj_pool_get_used_size(pool), \n\t       pj_pool_get_used_size(pool)*100/pool_capacity));\n    pj_pool_reset(pool);\n\n    pool_capacity = pj_pool_get_capacity(pool);\n\n    /*\n     * Otherwise put the pool in our recycle list.\n     */\n    i = (unsigned) (unsigned long) (pj_ssize_t) pool->factory_data;\n\n    pj_assert(i<PJ_CACHING_POOL_ARRAY_SIZE);\n    if (i >= PJ_CACHING_POOL_ARRAY_SIZE ) {\n\t/* Something has gone wrong with the pool. */\n\tpj_pool_destroy_int(pool);\n\tpj_lock_release(cp->lock);\n\treturn;\n    }\n\n    pj_list_insert_after(&cp->free_list[i], pool);\n    cp->capacity += pool_capacity;\n\n    pj_lock_release(cp->lock);\n}\n\nstatic void cpool_dump_status(pj_pool_factory *factory, pj_bool_t detail )\n{\n#if PJ_LOG_MAX_LEVEL >= 3\n    pj_caching_pool *cp = (pj_caching_pool*)factory;\n\n    pj_lock_acquire(cp->lock);\n\n    PJ_LOG(3,(\"cachpool\", \" Dumping caching pool:\"));\n    PJ_LOG(3,(\"cachpool\", \"   Capacity=%u, max_capacity=%u, used_cnt=%u\", \\\n\t\t\t     cp->capacity, cp->max_capacity, cp->used_count));\n    if (detail) {\n\tpj_pool_t *pool = (pj_pool_t*) cp->used_list.next;\n\tpj_size_t total_used = 0, total_capacity = 0;\n        PJ_LOG(3,(\"cachpool\", \"  Dumping all active pools:\"));\n\twhile (pool != (void*)&cp->used_list) {\n\t    pj_size_t pool_capacity = pj_pool_get_capacity(pool);\n\t    PJ_LOG(3,(\"cachpool\", \"   %16s: %8d of %8d (%d%%) used\", \n\t\t\t\t  pj_pool_getobjname(pool), \n\t\t\t\t  pj_pool_get_used_size(pool), \n\t\t\t\t  pool_capacity,\n\t\t\t\t  pj_pool_get_used_size(pool)*100/pool_capacity));\n\t    total_used += pj_pool_get_used_size(pool);\n\t    total_capacity += pool_capacity;\n\t    pool = pool->next;\n\t}\n\tif (total_capacity) {\n\t    PJ_LOG(3,(\"cachpool\", \"  Total %9d of %9d (%d %%) used!\",\n\t\t\t\t  total_used, total_capacity,\n\t\t\t\t  total_used * 100 / total_capacity));\n\t}\n    }\n\n    pj_lock_release(cp->lock);\n#else\n    PJ_UNUSED_ARG(factory);\n    PJ_UNUSED_ARG(detail);\n#endif\n}\n\n\nstatic pj_bool_t cpool_on_block_alloc(pj_pool_factory *f, pj_size_t sz)\n{\n    pj_caching_pool *cp = (pj_caching_pool*)f;\n\n    //Can't lock because mutex is not recursive\n    //if (cp->mutex) pj_mutex_lock(cp->mutex);\n\n    cp->used_size += sz;\n    if (cp->used_size > cp->peak_used_size)\n\tcp->peak_used_size = cp->used_size;\n\n    //if (cp->mutex) pj_mutex_unlock(cp->mutex);\n\n    return PJ_TRUE;\n}\n\n\nstatic void cpool_on_block_free(pj_pool_factory *f, pj_size_t sz)\n{\n    pj_caching_pool *cp = (pj_caching_pool*)f;\n\n    //pj_mutex_lock(cp->mutex);\n    cp->used_size -= sz;\n    //pj_mutex_unlock(cp->mutex);\n}\n\n\n#endif\t/* PJ_HAS_POOL_ALT_API */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/pool_dbg.c",
    "content": "/* $Id: pool_dbg.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#if PJ_HAS_POOL_ALT_API\n\n#if PJ_HAS_MALLOC_H\n#   include <malloc.h>\n#endif\n\n\n#if PJ_HAS_STDLIB_H\n#   include <stdlib.h>\n#endif\n\n\n#if ((defined(PJ_WIN32) && PJ_WIN32!=0) || \\\n     (defined(PJ_WIN64) && PJ_WIN64 != 0)) && \\\n     defined(PJ_DEBUG) && PJ_DEBUG!=0 && !PJ_NATIVE_STRING_IS_UNICODE\n#   include <windows.h>\n#   define TRACE_(msg)\tOutputDebugString(msg)\n#endif\n\n/* Uncomment this to enable TRACE_ */\n//#undef TRACE_\n\n\n\nint PJ_NO_MEMORY_EXCEPTION;\n\n\nPJ_DEF(int) pj_NO_MEMORY_EXCEPTION()\n{\n    return PJ_NO_MEMORY_EXCEPTION;\n}\n\n/* Create pool */\nPJ_DEF(pj_pool_t*) pj_pool_create_imp( const char *file, int line,\n\t\t\t\t       void *factory,\n\t\t\t\t       const char *name,\n\t\t\t\t       pj_size_t initial_size,\n\t\t\t\t       pj_size_t increment_size,\n\t\t\t\t       pj_pool_callback *callback)\n{\n    pj_pool_t *pool;\n\n    PJ_UNUSED_ARG(file);\n    PJ_UNUSED_ARG(line);\n    PJ_UNUSED_ARG(factory);\n    PJ_UNUSED_ARG(initial_size);\n    PJ_UNUSED_ARG(increment_size);\n\n    pool = malloc(sizeof(struct pj_pool_t));\n    if (!pool)\n\treturn NULL;\n\n    if (name) {\n\tpj_ansi_strncpy(pool->obj_name, name, sizeof(pool->obj_name));\n\tpool->obj_name[sizeof(pool->obj_name)-1] = '\\0';\n    } else {\n\tstrcpy(pool->obj_name, \"altpool\");\n    }\n\n    pool->factory = NULL;\n    pool->first_mem = NULL;\n    pool->used_size = 0;\n    pool->cb = callback;\n\n    return pool;\n}\n\n\n/* Release pool */\nPJ_DEF(void) pj_pool_release_imp(pj_pool_t *pool)\n{\n    pj_pool_reset(pool);\n    free(pool);\n}\n\n/* Get pool name */\nPJ_DEF(const char*) pj_pool_getobjname_imp(pj_pool_t *pool)\n{\n    PJ_UNUSED_ARG(pool);\n    return \"pooldbg\";\n}\n\n/* Reset pool */\nPJ_DEF(void) pj_pool_reset_imp(pj_pool_t *pool)\n{\n    struct pj_pool_mem *mem;\n\n    mem = pool->first_mem;\n    while (mem) {\n\tstruct pj_pool_mem *next = mem->next;\n\tfree(mem);\n\tmem = next;\n    }\n\n    pool->first_mem = NULL;\n}\n\n/* Get capacity */\nPJ_DEF(pj_size_t) pj_pool_get_capacity_imp(pj_pool_t *pool)\n{\n    PJ_UNUSED_ARG(pool);\n\n    /* Unlimited capacity */\n    return 0x7FFFFFFFUL;\n}\n\n/* Get total used size */\nPJ_DEF(pj_size_t) pj_pool_get_used_size_imp(pj_pool_t *pool)\n{\n    return pool->used_size;\n}\n\n/* Allocate memory from the pool */\nPJ_DEF(void*) pj_pool_alloc_imp( const char *file, int line, \n\t\t\t\t pj_pool_t *pool, pj_size_t sz)\n{\n    struct pj_pool_mem *mem;\n\n    PJ_UNUSED_ARG(file);\n    PJ_UNUSED_ARG(line);\n\n    mem = malloc(sz + sizeof(struct pj_pool_mem));\n    if (!mem) {\n\tif (pool->cb)\n\t    (*pool->cb)(pool, sz);\n\treturn NULL;\n    }\n\n    mem->next = pool->first_mem;\n    pool->first_mem = mem;\n\n#ifdef TRACE_\n    {\n\tchar msg[120];\n\tpj_ansi_sprintf(msg, \"Mem %X (%d+%d bytes) allocated by %s:%d\\r\\n\",\n\t\t\tmem, sz, sizeof(struct pj_pool_mem), \n\t\t\tfile, line);\n\tTRACE_(msg);\n    }\n#endif\n\n    return ((char*)mem) + sizeof(struct pj_pool_mem);\n}\n\n/* Allocate memory from the pool and zero the memory */\nPJ_DEF(void*) pj_pool_calloc_imp( const char *file, int line, \n\t\t\t\t  pj_pool_t *pool, unsigned cnt, \n\t\t\t\t  unsigned elemsz)\n{\n    void *mem;\n\n    mem = pj_pool_alloc_imp(file, line, pool, cnt*elemsz);\n    if (!mem)\n\treturn NULL;\n\n    pj_bzero(mem, cnt*elemsz);\n    return mem;\n}\n\n/* Allocate memory from the pool and zero the memory */\nPJ_DEF(void*) pj_pool_zalloc_imp( const char *file, int line, \n\t\t\t\t  pj_pool_t *pool, pj_size_t sz)\n{\n    return pj_pool_calloc_imp(file, line, pool, 1, sz); \n}\n\n\n\n#endif\t/* PJ_HAS_POOL_ALT_API */\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/pool_policy_kmalloc.c",
    "content": "/* $Id: pool_policy_kmalloc.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/pool.h>\n#include <pj/except.h>\n#include <pj/os.h>\n\n\nstatic void *default_block_alloc(pj_pool_factory *factory, pj_size_t size)\n{\n    PJ_CHECK_STACK();\n    PJ_UNUSED_ARG(factory);\n\n    return kmalloc(size, GFP_ATOMIC);\n}\n\nstatic void default_block_free(pj_pool_factory *factory, \n\t\t\t       void *mem, pj_size_t size)\n{\n    PJ_CHECK_STACK();\n    PJ_UNUSED_ARG(factory);\n    PJ_UNUSED_ARG(size);\n\n    kfree(mem);\n}\n\nstatic void default_pool_callback(pj_pool_t *pool, pj_size_t size)\n{\n    PJ_CHECK_STACK();\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(size);\n\n    PJ_THROW(PJ_NO_MEMORY_EXCEPTION);\n}\n\npj_pool_factory_policy pj_pool_factory_default_policy = \n{\n    &default_block_alloc,\n    &default_block_free,\n    &default_pool_callback,\n    0\n};\n\nPJ_DEF(const pj_pool_factory_policy*) pj_pool_factory_get_default_policy(void)\n{\n    return &pj_pool_factory_default_policy;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/pool_policy_malloc.c",
    "content": "/* $Id: pool_policy_malloc.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/pool.h>\n#include <pj/except.h>\n#include <pj/os.h>\n#include <pj/compat/malloc.h>\n\n#if !PJ_HAS_POOL_ALT_API\n\n/*\n * This file contains pool default policy definition and implementation.\n */\n#include \"pool_signature.h\"\n\n\nstatic void *default_block_alloc(pj_pool_factory *factory, pj_size_t size)\n{\n    void *p;\n\n    PJ_CHECK_STACK();\n\n    if (factory->on_block_alloc) {\n\tint rc;\n\trc = factory->on_block_alloc(factory, size);\n\tif (!rc)\n\t    return NULL;\n    }\n\n    p = malloc(size+(SIG_SIZE << 1));\n\n    if (p == NULL) {\n\tif (factory->on_block_free) \n\t    factory->on_block_free(factory, size);\n    } else {\n\t/* Apply signature when PJ_SAFE_POOL is set. It will move\n\t * \"p\" pointer forward.\n\t */\n\tAPPLY_SIG(p, size);\n    }\n\n    return p;\n}\n\nstatic void default_block_free(pj_pool_factory *factory, void *mem, \n\t\t\t       pj_size_t size)\n{\n    PJ_CHECK_STACK();\n\n    if (factory->on_block_free) \n        factory->on_block_free(factory, size);\n\n    /* Check and remove signature when PJ_SAFE_POOL is set. It will\n     * move \"mem\" pointer backward.\n     */\n    REMOVE_SIG(mem, size);\n\n    /* Note that when PJ_SAFE_POOL is set, the actual size of the block\n     * is size + SIG_SIZE*2.\n     */\n\n    free(mem);\n}\n\nstatic void default_pool_callback(pj_pool_t *pool, pj_size_t size)\n{\n    PJ_CHECK_STACK();\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(size);\n\n    PJ_THROW(PJ_NO_MEMORY_EXCEPTION);\n}\n\nPJ_DEF_DATA(pj_pool_factory_policy) pj_pool_factory_default_policy =\n{\n    &default_block_alloc,\n    &default_block_free,\n    &default_pool_callback,\n    0\n};\n\nPJ_DEF(const pj_pool_factory_policy*) pj_pool_factory_get_default_policy(void)\n{\n    return &pj_pool_factory_default_policy;\n}\n\n\n#endif\t/* PJ_HAS_POOL_ALT_API */\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/pool_policy_new.cpp",
    "content": "/* $Id: pool_policy_new.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/pool.h>\n#include <pj/except.h>\n#include <pj/os.h>\n\n#if !PJ_HAS_POOL_ALT_API\n\n/*\n * This file contains pool default policy definition and implementation.\n */\n#include \"pool_signature.h\"\n \n\nstatic void *operator_new(pj_pool_factory *factory, pj_size_t size)\n{\n    void *mem;\n\n    PJ_CHECK_STACK();\n\n    if (factory->on_block_alloc) {\n\t\tint rc;\n\t\trc = factory->on_block_alloc(factory, size);\n\t\tif (!rc)\n\t\t    return NULL;\n    }\n    \n    mem = (void*) new char[size+(SIG_SIZE << 1)];\n    \n    /* Exception for new operator may be disabled, so.. */\n    if (mem) {\n\t/* Apply signature when PJ_SAFE_POOL is set. It will move\n\t * \"mem\" pointer forward.\n\t */\n\tAPPLY_SIG(mem, size);\n    }\n\n    return mem;\n}\n\nstatic void operator_delete(pj_pool_factory *factory, void *mem, pj_size_t size)\n{\n    PJ_CHECK_STACK();\n\n    if (factory->on_block_free) \n        factory->on_block_free(factory, size);\n    \n    /* Check and remove signature when PJ_SAFE_POOL is set. It will\n     * move \"mem\" pointer backward.\n     */\n    REMOVE_SIG(mem, size);\n\n    /* Note that when PJ_SAFE_POOL is set, the actual size of the block\n     * is size + SIG_SIZE*2.\n     */\n\n    char *p = (char*)mem;\n    delete [] p;\n}\n\nstatic void default_pool_callback(pj_pool_t *pool, pj_size_t size)\n{\n    PJ_CHECK_STACK();\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(size);\n\n    PJ_THROW(PJ_NO_MEMORY_EXCEPTION);\n}\n\nPJ_DEF_DATA(pj_pool_factory_policy) pj_pool_factory_default_policy = \n{\n    &operator_new,\n    &operator_delete,\n    &default_pool_callback,\n    0\n};\n\nPJ_DEF(const pj_pool_factory_policy*) pj_pool_factory_get_default_policy(void)\n{\n    return &pj_pool_factory_default_policy;\n}\n\n \n#endif\t/* PJ_HAS_POOL_ALT_API */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/pool_signature.h",
    "content": "/* $Id: pool_signature.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/assert.h>\n#include <pj/string.h>\n\n#if PJ_SAFE_POOL\n#   define SIG_SIZE\t\tsizeof(pj_uint32_t)\n\nstatic void apply_signature(void *p, pj_size_t size);\nstatic void check_pool_signature(void *p, pj_size_t size);\n\n#   define APPLY_SIG(p,sz)\tapply_signature(p,sz), \\\n\t\t\t\tp=(void*)(((char*)p)+SIG_SIZE)\n#   define REMOVE_SIG(p,sz)\tcheck_pool_signature(p,sz), \\\n\t\t\t\tp=(void*)(((char*)p)-SIG_SIZE)\n\n#   define SIG_BEGIN\t    0x600DC0DE\n#   define SIG_END\t    0x0BADC0DE\n\nstatic void apply_signature(void *p, pj_size_t size)\n{\n    pj_uint32_t sig;\n\n    sig = SIG_BEGIN;\n    pj_memcpy(p, &sig, SIG_SIZE);\n\n    sig = SIG_END;\n    pj_memcpy(((char*)p)+SIG_SIZE+size, &sig, SIG_SIZE);\n}\n\nstatic void check_pool_signature(void *p, pj_size_t size)\n{\n    pj_uint32_t sig;\n    pj_uint8_t *mem = (pj_uint8_t*)p;\n\n    /* Check that signature at the start of the block is still intact */\n    sig = SIG_BEGIN;\n    pj_assert(!pj_memcmp(mem-SIG_SIZE, &sig, SIG_SIZE));\n\n    /* Check that signature at the end of the block is still intact.\n     * Note that \"mem\" has been incremented by SIG_SIZE \n     */\n    sig = SIG_END;\n    pj_assert(!pj_memcmp(mem+size, &sig, SIG_SIZE));\n}\n\n#else\n#   define SIG_SIZE\t    0\n#   define APPLY_SIG(p,sz)\n#   define REMOVE_SIG(p,sz)\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/rand.c",
    "content": "/* $Id: rand.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/rand.h>\n#include <pj/os.h>\n#include <pj/compat/rand.h>\n\nPJ_DEF(void) pj_srand(unsigned int seed)\n{\n    PJ_CHECK_STACK();\n    platform_srand(seed);\n}\n\nPJ_DEF(int) pj_rand(void)\n{\n    PJ_CHECK_STACK();\n    return platform_rand();\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/rbtree.c",
    "content": "/* $Id: rbtree.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/rbtree.h>\n#include <pj/os.h>\n\nstatic void left_rotate( pj_rbtree *tree, pj_rbtree_node *node ) \n{\n    pj_rbtree_node *rnode, *parent;\n\n    PJ_CHECK_STACK();\n\n    rnode = node->right;\n    if (rnode == tree->null)\n        return;\n    \n    node->right = rnode->left;\n    if (rnode->left != tree->null)\n        rnode->left->parent = node;\n    parent = node->parent;\n    rnode->parent = parent;\n    if (parent != tree->null) {\n        if (parent->left == node)\n\t   parent->left = rnode;\n        else\n\t   parent->right = rnode;\n    } else {\n        tree->root = rnode;\n    }\n    rnode->left = node;\n    node->parent = rnode;\n}\n\nstatic void right_rotate( pj_rbtree *tree, pj_rbtree_node *node ) \n{\n    pj_rbtree_node *lnode, *parent;\n\n    PJ_CHECK_STACK();\n\n    lnode = node->left;\n    if (lnode == tree->null)\n        return;\n\n    node->left = lnode->right;\n    if (lnode->right != tree->null)\n\tlnode->right->parent = node;\n    parent = node->parent;\n    lnode->parent = parent;\n\n    if (parent != tree->null) {\n        if (parent->left == node)\n\t    parent->left = lnode;\n\telse\n\t    parent->right = lnode;\n    } else {\n        tree->root = lnode;\n    }\n    lnode->right = node;\n    node->parent = lnode;\n}\n\nstatic void insert_fixup( pj_rbtree *tree, pj_rbtree_node *node ) \n{\n    pj_rbtree_node *temp, *parent;\n\n    PJ_CHECK_STACK();\n\n    while (node != tree->root && node->parent->color == PJ_RBCOLOR_RED) {\n        parent = node->parent;\n        if (parent == parent->parent->left) {\n\t    temp = parent->parent->right;\n\t    if (temp->color == PJ_RBCOLOR_RED) {\n\t        temp->color = PJ_RBCOLOR_BLACK;\n\t        node = parent;\n\t        node->color = PJ_RBCOLOR_BLACK;\n\t        node = node->parent;\n\t        node->color = PJ_RBCOLOR_RED;\n\t    } else {\n\t        if (node == parent->right) {\n\t\t   node = parent;\n\t\t   left_rotate(tree, node);\n\t        }\n\t        temp = node->parent;\n\t        temp->color = PJ_RBCOLOR_BLACK;\n\t        temp = temp->parent;\n\t        temp->color = PJ_RBCOLOR_RED;\n\t        right_rotate( tree, temp);\n\t    }\n        } else {\n\t    temp = parent->parent->left;\n\t    if (temp->color == PJ_RBCOLOR_RED) {\n\t        temp->color = PJ_RBCOLOR_BLACK;\n\t        node = parent;\n\t        node->color = PJ_RBCOLOR_BLACK;\n\t        node = node->parent;\n\t        node->color = PJ_RBCOLOR_RED;\n\t    } else {\n\t        if (node == parent->left) {\n\t\t    node = parent;\n\t\t    right_rotate(tree, node);\n\t        }\n\t        temp = node->parent;\n\t        temp->color = PJ_RBCOLOR_BLACK;\n\t        temp = temp->parent;\n\t        temp->color = PJ_RBCOLOR_RED;\n\t        left_rotate(tree, temp);\n\t   }\n        }\n    }\n\t\n    tree->root->color = PJ_RBCOLOR_BLACK;\n}\n\n\nstatic void delete_fixup( pj_rbtree *tree, pj_rbtree_node *node )\n{\n    pj_rbtree_node *temp;\n\n    PJ_CHECK_STACK();\n\n    while (node != tree->root && node->color == PJ_RBCOLOR_BLACK) {\n        if (node->parent->left == node) {\n\t    temp = node->parent->right;\n\t    if (temp->color == PJ_RBCOLOR_RED) {\n\t        temp->color = PJ_RBCOLOR_BLACK;\n\t        node->parent->color = PJ_RBCOLOR_RED;\n\t        left_rotate(tree, node->parent);\n\t        temp = node->parent->right;\n\t    }\n\t    if (temp->left->color == PJ_RBCOLOR_BLACK && \n\t        temp->right->color == PJ_RBCOLOR_BLACK) \n\t    {\n\t        temp->color = PJ_RBCOLOR_RED;\n\t        node = node->parent;\n\t    } else {\n\t        if (temp->right->color == PJ_RBCOLOR_BLACK) {\n\t\t    temp->left->color = PJ_RBCOLOR_BLACK;\n\t\t    temp->color = PJ_RBCOLOR_RED;\n\t\t    right_rotate( tree, temp);\n\t\t    temp = node->parent->right;\n\t        }\n\t        temp->color = node->parent->color;\n\t        temp->right->color = PJ_RBCOLOR_BLACK;\n\t        node->parent->color = PJ_RBCOLOR_BLACK;\n\t        left_rotate(tree, node->parent);\n\t        node = tree->root;\n\t    }\n        } else {\n\t    temp = node->parent->left;\n\t    if (temp->color == PJ_RBCOLOR_RED) {\n\t        temp->color = PJ_RBCOLOR_BLACK;\n\t        node->parent->color = PJ_RBCOLOR_RED;\n\t        right_rotate( tree, node->parent);\n\t        temp = node->parent->left;\n\t    }\n\t    if (temp->right->color == PJ_RBCOLOR_BLACK && \n\t\ttemp->left->color == PJ_RBCOLOR_BLACK) \n\t    {\n\t        temp->color = PJ_RBCOLOR_RED;\n\t        node = node->parent;\n\t    } else {\n\t        if (temp->left->color == PJ_RBCOLOR_BLACK) {\n\t\t    temp->right->color = PJ_RBCOLOR_BLACK;\n\t\t    temp->color = PJ_RBCOLOR_RED;\n\t\t    left_rotate( tree, temp);\n\t\t    temp = node->parent->left;\n\t        }\n\t        temp->color = node->parent->color;\n\t        node->parent->color = PJ_RBCOLOR_BLACK;\n\t        temp->left->color = PJ_RBCOLOR_BLACK;\n\t        right_rotate(tree, node->parent);\n\t        node = tree->root;\n\t    }\n        }\n    }\n\t\n    node->color = PJ_RBCOLOR_BLACK;\n}\n\n\nPJ_DEF(void) pj_rbtree_init( pj_rbtree *tree, pj_rbtree_comp *comp )\n{\n    PJ_CHECK_STACK();\n\n    tree->null = tree->root = &tree->null_node;\n    tree->null->key = NULL;\n    tree->null->user_data = NULL;\n    tree->size = 0;\n    tree->null->left = tree->null->right = tree->null->parent = tree->null;\n    tree->null->color = PJ_RBCOLOR_BLACK;\n    tree->comp = comp;\n}\n\nPJ_DEF(pj_rbtree_node*) pj_rbtree_first( pj_rbtree *tree )\n{\n    register pj_rbtree_node *node = tree->root;\n    register pj_rbtree_node *null = tree->null;\n    \n    PJ_CHECK_STACK();\n\n    while (node->left != null)\n\tnode = node->left;\n    return node != null ? node : NULL;\n}\n\nPJ_DEF(pj_rbtree_node*) pj_rbtree_last( pj_rbtree *tree )\n{\n    register pj_rbtree_node *node = tree->root;\n    register pj_rbtree_node *null = tree->null;\n    \n    PJ_CHECK_STACK();\n\n    while (node->right != null)\n\tnode = node->right;\n    return node != null ? node : NULL;\n}\n\nPJ_DEF(pj_rbtree_node*) pj_rbtree_next( pj_rbtree *tree, \n\t\t\t\t\tregister pj_rbtree_node *node )\n{\n    register pj_rbtree_node *null = tree->null;\n    \n    PJ_CHECK_STACK();\n\n    if (node->right != null) {\n\tfor (node=node->right; node->left!=null; node = node->left)\n\t    /* void */;\n    } else {\n        register pj_rbtree_node *temp = node->parent;\n        while (temp!=null && temp->right==node) {\n\t    node = temp;\n\t    temp = temp->parent;\n\t}\n\tnode = temp;\n    }    \n    return node != null ? node : NULL;\n}\n\nPJ_DEF(pj_rbtree_node*) pj_rbtree_prev( pj_rbtree *tree, \n\t\t\t\t\tregister pj_rbtree_node *node )\n{\n    register pj_rbtree_node *null = tree->null;\n    \n    PJ_CHECK_STACK();\n\n    if (node->left != null) {\n        for (node=node->left; node->right!=null; node=node->right)\n\t   /* void */;\n    } else {\n        register pj_rbtree_node *temp = node->parent;\n        while (temp!=null && temp->left==node) {\n\t    node = temp;\n\t    temp = temp->parent;\n        }\n        node = temp;\n    }    \n    return node != null ? node : NULL;\n}\n\nPJ_DEF(int) pj_rbtree_insert( pj_rbtree *tree, \n\t\t\t      pj_rbtree_node *element )\n{\n    int rv = 0;\n    pj_rbtree_node *node, *parent = tree->null, \n\t\t   *null = tree->null;\n    pj_rbtree_comp *comp = tree->comp;\n\t\n    PJ_CHECK_STACK();\n\n    node = tree->root;\t\n    while (node != null) {\n        rv = (*comp)(element->key, node->key);\n        if (rv == 0) {\n\t    /* found match, i.e. entry with equal key already exist */\n\t    return -1;\n\t}    \n\tparent = node;\n        node = rv < 0 ? node->left : node->right;\n    }\n\n    element->color = PJ_RBCOLOR_RED;\n    element->left = element->right = null;\n\n    node = element;\n    if (parent != null) {\n        node->parent = parent;\n        if (rv < 0)\n\t   parent->left = node;\n        else\n\t   parent->right = node;\n        insert_fixup( tree, node);\n    } else {\n        tree->root = node;\n        node->parent = null;\n        node->color = PJ_RBCOLOR_BLACK;\n    }\n\t\n    ++tree->size;\n    return 0;\n}\n\n\nPJ_DEF(pj_rbtree_node*) pj_rbtree_find( pj_rbtree *tree,\n\t\t\t\t\tconst void *key )\n{\n    int rv;\n    pj_rbtree_node *node = tree->root;\n    pj_rbtree_node *null = tree->null;\n    pj_rbtree_comp *comp = tree->comp;\n    \n    while (node != null) {\n        rv = (*comp)(key, node->key);\n        if (rv == 0)\n\t    return node;\n        node = rv < 0 ? node->left : node->right;\n    }\n    return node != null ? node : NULL;\n}\n\nPJ_DEF(pj_rbtree_node*) pj_rbtree_erase( pj_rbtree *tree,\n\t\t\t\t\t pj_rbtree_node *node )\n{\n    pj_rbtree_node *succ;\n    pj_rbtree_node *null = tree->null;\n    pj_rbtree_node *child;\n    pj_rbtree_node *parent;\n    \n    PJ_CHECK_STACK();\n\n    if (node->left == null || node->right == null) {\n        succ = node;\n    } else {\n        for (succ=node->right; succ->left!=null; succ=succ->left)\n\t   /* void */;\n    }\n\n    child = succ->left != null ? succ->left : succ->right;\n    parent = succ->parent;\n    child->parent = parent;\n    \n    if (parent != null) {\n\tif (parent->left == succ)\n\t    parent->left = child;\n        else\n\t   parent->right = child;\n    } else\n        tree->root = child;\n\n    if (succ != node) {\n        succ->parent = node->parent;\n        succ->left = node->left;\n        succ->right = node->right;\n        succ->color = node->color;\n\n        parent = node->parent;\n        if (parent != null) {\n\t   if (parent->left==node)\n\t        parent->left=succ;\n\t   else\n\t\tparent->right=succ;\n        }\n        if (node->left != null)\n\t   node->left->parent = succ;;\n        if (node->right != null)\n\t    node->right->parent = succ;\n\n        if (tree->root == node)\n\t   tree->root = succ;\n    }\n\n    if (succ->color == PJ_RBCOLOR_BLACK) {\n\tif (child != null) \n\t    delete_fixup(tree, child);\n        tree->null->color = PJ_RBCOLOR_BLACK;\n    }\n\n    --tree->size;\n    return node;\n}\n\n\nPJ_DEF(unsigned) pj_rbtree_max_height( pj_rbtree *tree,\n\t\t\t\t       pj_rbtree_node *node )\n{\n    unsigned l, r;\n    \n    PJ_CHECK_STACK();\n\n    if (node==NULL) \n\tnode = tree->root;\n    \n    l = node->left != tree->null ? pj_rbtree_max_height(tree,node->left)+1 : 0;\n    r = node->right != tree->null ? pj_rbtree_max_height(tree,node->right)+1 : 0;\n    return l > r ? l : r;\n}\n\nPJ_DEF(unsigned) pj_rbtree_min_height( pj_rbtree *tree,\n\t\t\t\t       pj_rbtree_node *node )\n{\n    unsigned l, r;\n    \n    PJ_CHECK_STACK();\n\n    if (node==NULL) \n\tnode=tree->root;\n    \n    l = (node->left != tree->null) ? pj_rbtree_max_height(tree,node->left)+1 : 0;\n    r = (node->right != tree->null) ? pj_rbtree_max_height(tree,node->right)+1 : 0;\n    return l > r ? r : l;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/sock_bsd.c",
    "content": "/* $Id: sock_bsd.c 4233 2012-08-21 11:16:06Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/sock.h>\n#include <pj/os.h>\n#include <pj/assert.h>\n#include <pj/string.h>\n#include <pj/compat/socket.h>\n#include <pj/addr_resolv.h>\n#include <pj/errno.h>\n#include <pj/unicode.h>\n\n#define THIS_FILE\t\"sock_bsd.c\"\n\n/*\n * Address families conversion.\n * The values here are indexed based on pj_addr_family.\n */\nconst pj_uint16_t PJ_AF_UNSPEC\t= AF_UNSPEC;\nconst pj_uint16_t PJ_AF_UNIX\t= AF_UNIX;\nconst pj_uint16_t PJ_AF_INET\t= AF_INET;\nconst pj_uint16_t PJ_AF_INET6\t= AF_INET6;\n#ifdef AF_PACKET\nconst pj_uint16_t PJ_AF_PACKET\t= AF_PACKET;\n#else\nconst pj_uint16_t PJ_AF_PACKET\t= 0xFFFF;\n#endif\n#ifdef AF_IRDA\nconst pj_uint16_t PJ_AF_IRDA\t= AF_IRDA;\n#else\nconst pj_uint16_t PJ_AF_IRDA\t= 0xFFFF;\n#endif\n\n/*\n * Socket types conversion.\n * The values here are indexed based on pj_sock_type\n */\nconst pj_uint16_t PJ_SOCK_STREAM= SOCK_STREAM;\nconst pj_uint16_t PJ_SOCK_DGRAM\t= SOCK_DGRAM;\nconst pj_uint16_t PJ_SOCK_RAW\t= SOCK_RAW;\nconst pj_uint16_t PJ_SOCK_RDM\t= SOCK_RDM;\n\n/*\n * Socket level values.\n */\nconst pj_uint16_t PJ_SOL_SOCKET\t= SOL_SOCKET;\n#ifdef SOL_IP\nconst pj_uint16_t PJ_SOL_IP\t= SOL_IP;\n#elif (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_WIN64) && PJ_WIN64) \nconst pj_uint16_t PJ_SOL_IP\t= IPPROTO_IP;\n#else\nconst pj_uint16_t PJ_SOL_IP\t= 0;\n#endif /* SOL_IP */\n\n#if defined(SOL_TCP)\nconst pj_uint16_t PJ_SOL_TCP\t= SOL_TCP;\n#elif defined(IPPROTO_TCP)\nconst pj_uint16_t PJ_SOL_TCP\t= IPPROTO_TCP;\n#elif (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_WIN64) && PJ_WIN64)\nconst pj_uint16_t PJ_SOL_TCP\t= IPPROTO_TCP;\n#else\nconst pj_uint16_t PJ_SOL_TCP\t= 6;\n#endif /* SOL_TCP */\n\n#ifdef SOL_UDP\nconst pj_uint16_t PJ_SOL_UDP\t= SOL_UDP;\n#elif defined(IPPROTO_UDP)\nconst pj_uint16_t PJ_SOL_UDP\t= IPPROTO_UDP;\n#elif (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_WIN64) && PJ_WIN64)\nconst pj_uint16_t PJ_SOL_UDP\t= IPPROTO_UDP;\n#else\nconst pj_uint16_t PJ_SOL_UDP\t= 17;\n#endif /* SOL_UDP */\n\n#ifdef SOL_IPV6\nconst pj_uint16_t PJ_SOL_IPV6\t= SOL_IPV6;\n#elif (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_WIN64) && PJ_WIN64)\n#   if defined(IPPROTO_IPV6) || (_WIN32_WINNT >= 0x0501)\n\tconst pj_uint16_t PJ_SOL_IPV6\t= IPPROTO_IPV6;\n#   else\n\tconst pj_uint16_t PJ_SOL_IPV6\t= 41;\n#   endif\n#else\nconst pj_uint16_t PJ_SOL_IPV6\t= 41;\n#endif /* SOL_IPV6 */\n\n/* IP_TOS */\n#ifdef IP_TOS\nconst pj_uint16_t PJ_IP_TOS\t= IP_TOS;\n#else\nconst pj_uint16_t PJ_IP_TOS\t= 1;\n#endif\n\n\n/* TOS settings (declared in netinet/ip.h) */\n#ifdef IPTOS_LOWDELAY\nconst pj_uint16_t PJ_IPTOS_LOWDELAY\t= IPTOS_LOWDELAY;\n#else\nconst pj_uint16_t PJ_IPTOS_LOWDELAY\t= 0x10;\n#endif\n#ifdef IPTOS_THROUGHPUT\nconst pj_uint16_t PJ_IPTOS_THROUGHPUT\t= IPTOS_THROUGHPUT;\n#else\nconst pj_uint16_t PJ_IPTOS_THROUGHPUT\t= 0x08;\n#endif\n#ifdef IPTOS_RELIABILITY\nconst pj_uint16_t PJ_IPTOS_RELIABILITY\t= IPTOS_RELIABILITY;\n#else\nconst pj_uint16_t PJ_IPTOS_RELIABILITY\t= 0x04;\n#endif\n#ifdef IPTOS_MINCOST\nconst pj_uint16_t PJ_IPTOS_MINCOST\t= IPTOS_MINCOST;\n#else\nconst pj_uint16_t PJ_IPTOS_MINCOST\t= 0x02;\n#endif\n\n\n/* optname values. */\nconst pj_uint16_t PJ_SO_TYPE    = SO_TYPE;\nconst pj_uint16_t PJ_SO_RCVBUF  = SO_RCVBUF;\nconst pj_uint16_t PJ_SO_SNDBUF  = SO_SNDBUF;\nconst pj_uint16_t PJ_TCP_NODELAY= TCP_NODELAY;\nconst pj_uint16_t PJ_SO_REUSEADDR= SO_REUSEADDR;\n#ifdef SO_NOSIGPIPE\nconst pj_uint16_t PJ_SO_NOSIGPIPE = SO_NOSIGPIPE;\n#else\nconst pj_uint16_t PJ_SO_NOSIGPIPE = 0xFFFF;\n#endif\n#if defined(SO_PRIORITY)\nconst pj_uint16_t PJ_SO_PRIORITY = SO_PRIORITY;\n#else\n/* This is from Linux, YMMV */\nconst pj_uint16_t PJ_SO_PRIORITY = 12;\n#endif\n\n/* Multicasting is not supported e.g. in PocketPC 2003 SDK */\n#ifdef IP_MULTICAST_IF\nconst pj_uint16_t PJ_IP_MULTICAST_IF    = IP_MULTICAST_IF;\nconst pj_uint16_t PJ_IP_MULTICAST_TTL   = IP_MULTICAST_TTL;\nconst pj_uint16_t PJ_IP_MULTICAST_LOOP  = IP_MULTICAST_LOOP;\nconst pj_uint16_t PJ_IP_ADD_MEMBERSHIP  = IP_ADD_MEMBERSHIP;\nconst pj_uint16_t PJ_IP_DROP_MEMBERSHIP = IP_DROP_MEMBERSHIP;\n#else\nconst pj_uint16_t PJ_IP_MULTICAST_IF    = 0xFFFF;\nconst pj_uint16_t PJ_IP_MULTICAST_TTL   = 0xFFFF;\nconst pj_uint16_t PJ_IP_MULTICAST_LOOP  = 0xFFFF;\nconst pj_uint16_t PJ_IP_ADD_MEMBERSHIP  = 0xFFFF;\nconst pj_uint16_t PJ_IP_DROP_MEMBERSHIP = 0xFFFF;\n#endif\n\n/* recv() and send() flags */\nconst int PJ_MSG_OOB\t\t= MSG_OOB;\nconst int PJ_MSG_PEEK\t\t= MSG_PEEK;\nconst int PJ_MSG_DONTROUTE\t= MSG_DONTROUTE;\n\n\n#if 0\nstatic void CHECK_ADDR_LEN(const pj_sockaddr *addr, int len)\n{\n    pj_sockaddr *a = (pj_sockaddr*)addr;\n    pj_assert((a->addr.sa_family==PJ_AF_INET && len==sizeof(pj_sockaddr_in)) ||\n\t      (a->addr.sa_family==PJ_AF_INET6 && len==sizeof(pj_sockaddr_in6)));\n\n}\n#else\n#define CHECK_ADDR_LEN(addr,len)\n#endif\n\n/*\n * Convert 16-bit value from network byte order to host byte order.\n */\nPJ_DEF(pj_uint16_t) pj_ntohs(pj_uint16_t netshort)\n{\n    return ntohs(netshort);\n}\n\n/*\n * Convert 16-bit value from host byte order to network byte order.\n */\nPJ_DEF(pj_uint16_t) pj_htons(pj_uint16_t hostshort)\n{\n    return htons(hostshort);\n}\n\n/*\n * Convert 32-bit value from network byte order to host byte order.\n */\nPJ_DEF(pj_uint32_t) pj_ntohl(pj_uint32_t netlong)\n{\n    return ntohl(netlong);\n}\n\n/*\n * Convert 32-bit value from host byte order to network byte order.\n */\nPJ_DEF(pj_uint32_t) pj_htonl(pj_uint32_t hostlong)\n{\n    return htonl(hostlong);\n}\n\n/*\n * Convert an Internet host address given in network byte order\n * to string in standard numbers and dots notation.\n */\nPJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)\n{\n#if !defined(PJ_LINUX) && !defined(PJ_LINUX_KERNEL)\n    return inet_ntoa(*(struct in_addr*)&inaddr);\n#else\n    struct in_addr addr;\n    addr.s_addr = inaddr.s_addr;\n    return inet_ntoa(addr);\n#endif\n}\n\n/*\n * This function converts the Internet host address cp from the standard\n * numbers-and-dots notation into binary data and stores it in the structure\n * that inp points to. \n */\nPJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp)\n{\n    char tempaddr[PJ_INET_ADDRSTRLEN];\n\n    /* Initialize output with PJ_INADDR_NONE.\n     * Some apps relies on this instead of the return value\n     * (and anyway the return value is quite confusing!)\n     */\n    inp->s_addr = PJ_INADDR_NONE;\n\n    /* Caution:\n     *\tthis function might be called with cp->slen >= 16\n     *  (i.e. when called with hostname to check if it's an IP addr).\n     */\n    PJ_ASSERT_RETURN(cp && cp->slen && inp, 0);\n    if (cp->slen >= PJ_INET_ADDRSTRLEN) {\n\treturn 0;\n    }\n\n    pj_memcpy(tempaddr, cp->ptr, cp->slen);\n    tempaddr[cp->slen] = '\\0';\n\n#if defined(PJ_SOCK_HAS_INET_ATON) && PJ_SOCK_HAS_INET_ATON != 0\n    return inet_aton(tempaddr, (struct in_addr*)inp);\n#else\n    inp->s_addr = inet_addr(tempaddr);\n    return inp->s_addr == PJ_INADDR_NONE ? 0 : 1;\n#endif\n}\n\n/*\n * Convert text to IPv4/IPv6 address.\n */\nPJ_DEF(pj_status_t) pj_inet_pton(int af, const pj_str_t *src, void *dst)\n{\n    char tempaddr[PJ_INET6_ADDRSTRLEN];\n\n    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EAFNOTSUP);\n    PJ_ASSERT_RETURN(src && src->slen && dst, PJ_EINVAL);\n\n    /* Initialize output with PJ_IN_ADDR_NONE for IPv4 (to be \n     * compatible with pj_inet_aton()\n     */\n    if (af==PJ_AF_INET) {\n\t((pj_in_addr*)dst)->s_addr = PJ_INADDR_NONE;\n    }\n\n    /* Caution:\n     *\tthis function might be called with cp->slen >= 46\n     *  (i.e. when called with hostname to check if it's an IP addr).\n     */\n    if (src->slen >= PJ_INET6_ADDRSTRLEN) {\n\treturn PJ_ENAMETOOLONG;\n    }\n\n    pj_memcpy(tempaddr, src->ptr, src->slen);\n    tempaddr[src->slen] = '\\0';\n\n#if defined(PJ_SOCK_HAS_INET_PTON) && PJ_SOCK_HAS_INET_PTON != 0\n    /*\n     * Implementation using inet_pton()\n     */\n    if (inet_pton(af, tempaddr, dst) != 1) {\n\tpj_status_t status = pj_get_netos_error();\n\tif (status == PJ_SUCCESS)\n\t    status = PJ_EUNKNOWN;\n\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n\n#elif defined(PJ_WIN32) || defined(PJ_WIN64) || defined(PJ_WIN32_WINCE)\n    /*\n     * Implementation on Windows, using WSAStringToAddress().\n     * Should also work on Unicode systems.\n     */\n    {\n\tPJ_DECL_UNICODE_TEMP_BUF(wtempaddr,PJ_INET6_ADDRSTRLEN)\n\tpj_sockaddr sock_addr;\n\tint addr_len = sizeof(sock_addr);\n\tint rc;\n\n\tsock_addr.addr.sa_family = (pj_uint16_t)af;\n\trc = WSAStringToAddress(\n\t\tPJ_STRING_TO_NATIVE(tempaddr,wtempaddr,sizeof(wtempaddr)), \n\t\taf, NULL, (LPSOCKADDR)&sock_addr, &addr_len);\n\tif (rc != 0) {\n\t    /* If you get rc 130022 Invalid argument (WSAEINVAL) with IPv6,\n\t     * check that you have IPv6 enabled (install it in the network\n\t     * adapter).\n\t     */\n\t    pj_status_t status = pj_get_netos_error();\n\t    if (status == PJ_SUCCESS)\n\t\tstatus = PJ_EUNKNOWN;\n\n\t    return status;\n\t}\n\n\tif (sock_addr.addr.sa_family == PJ_AF_INET) {\n\t    pj_memcpy(dst, &sock_addr.ipv4.sin_addr, 4);\n\t    return PJ_SUCCESS;\n\t} else if (sock_addr.addr.sa_family == PJ_AF_INET6) {\n\t    pj_memcpy(dst, &sock_addr.ipv6.sin6_addr, 16);\n\t    return PJ_SUCCESS;\n\t} else {\n\t    pj_assert(!\"Shouldn't happen\");\n\t    return PJ_EBUG;\n\t}\n    }\n#elif !defined(PJ_HAS_IPV6) || PJ_HAS_IPV6==0\n    /* IPv6 support is disabled, just return error without raising assertion */\n    return PJ_EIPV6NOTSUP;\n#else\n    pj_assert(!\"Not supported\");\n    return PJ_EIPV6NOTSUP;\n#endif\n}\n\n/*\n * Convert IPv4/IPv6 address to text.\n */\nPJ_DEF(pj_status_t) pj_inet_ntop(int af, const void *src,\n\t\t\t\t char *dst, int size)\n\n{\n    PJ_ASSERT_RETURN(src && dst && size, PJ_EINVAL);\n\n    *dst = '\\0';\n\n    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EAFNOTSUP);\n\n#if defined(PJ_SOCK_HAS_INET_NTOP) && PJ_SOCK_HAS_INET_NTOP != 0\n    /*\n     * Implementation using inet_ntop()\n     */\n    if (inet_ntop(af, src, dst, size) == NULL) {\n\tpj_status_t status = pj_get_netos_error();\n\tif (status == PJ_SUCCESS)\n\t    status = PJ_EUNKNOWN;\n\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n\n#elif defined(PJ_WIN32) || defined(PJ_WIN64) || defined(PJ_WIN32_WINCE)\n    /*\n     * Implementation on Windows, using WSAAddressToString().\n     * Should also work on Unicode systems.\n     */\n    {\n\tPJ_DECL_UNICODE_TEMP_BUF(wtempaddr,PJ_INET6_ADDRSTRLEN)\n\tpj_sockaddr sock_addr;\n\tDWORD addr_len, addr_str_len;\n\tint rc;\n\n\tpj_bzero(&sock_addr, sizeof(sock_addr));\n\tsock_addr.addr.sa_family = (pj_uint16_t)af;\n\tif (af == PJ_AF_INET) {\n\t    if (size < PJ_INET_ADDRSTRLEN)\n\t\treturn PJ_ETOOSMALL;\n\t    pj_memcpy(&sock_addr.ipv4.sin_addr, src, 4);\n\t    addr_len = sizeof(pj_sockaddr_in);\n\t    addr_str_len = PJ_INET_ADDRSTRLEN;\n\t} else if (af == PJ_AF_INET6) {\n\t    if (size < PJ_INET6_ADDRSTRLEN)\n\t\treturn PJ_ETOOSMALL;\n\t    pj_memcpy(&sock_addr.ipv6.sin6_addr, src, 16);\n\t    addr_len = sizeof(pj_sockaddr_in6);\n\t    addr_str_len = PJ_INET6_ADDRSTRLEN;\n\t} else {\n\t    pj_assert(!\"Unsupported address family\");\n\t    return PJ_EAFNOTSUP;\n\t}\n\n#if PJ_NATIVE_STRING_IS_UNICODE\n\trc = WSAAddressToString((LPSOCKADDR)&sock_addr, addr_len,\n\t\t\t\tNULL, wtempaddr, &addr_str_len);\n\tif (rc == 0) {\n\t    pj_unicode_to_ansi(wtempaddr, wcslen(wtempaddr), dst, size);\n\t}\n#else\n\trc = WSAAddressToString((LPSOCKADDR)&sock_addr, addr_len,\n\t\t\t\tNULL, dst, &addr_str_len);\n#endif\n\n\tif (rc != 0) {\n\t    pj_status_t status = pj_get_netos_error();\n\t    if (status == PJ_SUCCESS)\n\t\tstatus = PJ_EUNKNOWN;\n\n\t    return status;\n\t}\n\n\treturn PJ_SUCCESS;\n    }\n\n#elif !defined(PJ_HAS_IPV6) || PJ_HAS_IPV6==0\n    /* IPv6 support is disabled, just return error without raising assertion */\n    return PJ_EIPV6NOTSUP;\n#else\n    pj_assert(!\"Not supported\");\n    return PJ_EIPV6NOTSUP;\n#endif\n}\n\n/*\n * Get hostname.\n */\nPJ_DEF(const pj_str_t*) pj_gethostname(void)\n{\n    static char buf[PJ_MAX_HOSTNAME];\n    static pj_str_t hostname;\n\n    PJ_CHECK_STACK();\n\n    if (hostname.ptr == NULL) {\n\thostname.ptr = buf;\n\tif (gethostname(buf, sizeof(buf)) != 0) {\n\t    hostname.ptr[0] = '\\0';\n\t    hostname.slen = 0;\n\t} else {\n            hostname.slen = strlen(buf);\n\t}\n    }\n    return &hostname;\n}\n\n#if defined(PJ_WIN32) || defined(PJ_WIN64)\n/*\n * Create new socket/endpoint for communication and returns a descriptor.\n */\nPJ_DEF(pj_status_t) pj_sock_socket(int af, \n\t\t\t\t   int type, \n\t\t\t\t   int proto,\n\t\t\t\t   pj_sock_t *sock)\n{\n    PJ_CHECK_STACK();\n\n    /* Sanity checks. */\n    PJ_ASSERT_RETURN(sock!=NULL, PJ_EINVAL);\n    PJ_ASSERT_RETURN((SOCKET)PJ_INVALID_SOCKET==INVALID_SOCKET, \n                     (*sock=PJ_INVALID_SOCKET, PJ_EINVAL));\n\n    *sock = WSASocket(af, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED);\n\n    if (*sock == PJ_INVALID_SOCKET) \n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    \n#if PJ_SOCK_DISABLE_WSAECONNRESET && \\\n    (!defined(PJ_WIN32_WINCE) || PJ_WIN32_WINCE==0)\n\n#ifndef SIO_UDP_CONNRESET\n    #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)\n#endif\n\n    /* Disable WSAECONNRESET for UDP.\n     * See https://trac.pjsip.org/repos/ticket/1197\n     */\n    if (type==PJ_SOCK_DGRAM) {\n\tDWORD dwBytesReturned = 0;\n\tBOOL bNewBehavior = FALSE;\n\tDWORD rc;\n\n\trc = WSAIoctl(*sock, SIO_UDP_CONNRESET,\n\t\t      &bNewBehavior, sizeof(bNewBehavior),\n\t\t      NULL, 0, &dwBytesReturned,\n\t\t      NULL, NULL);\n\n\tif (rc==SOCKET_ERROR) {\n\t    // Ignored..\n\t}\n    }\n#endif\n\n    return PJ_SUCCESS;\n}\n\n#else\n/*\n * Create new socket/endpoint for communication and returns a descriptor.\n */\nPJ_DEF(pj_status_t) pj_sock_socket(int af, \n\t\t\t\t   int type, \n\t\t\t\t   int proto, \n\t\t\t\t   pj_sock_t *sock)\n{\n\n    PJ_CHECK_STACK();\n\n    /* Sanity checks. */\n    PJ_ASSERT_RETURN(sock!=NULL, PJ_EINVAL);\n    PJ_ASSERT_RETURN(PJ_INVALID_SOCKET==-1, \n                     (*sock=PJ_INVALID_SOCKET, PJ_EINVAL));\n    \n    *sock = socket(af, type, proto);\n    if (*sock == PJ_INVALID_SOCKET)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else {\n\tpj_int32_t val = 1;\n\tif (type == pj_SOCK_STREAM()) {\n\t    pj_sock_setsockopt(*sock, pj_SOL_SOCKET(), pj_SO_NOSIGPIPE(),\n\t\t\t       &val, sizeof(val));\n\t}\n#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \\\n    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0\n\tif (type == pj_SOCK_DGRAM()) {\n\t    pj_sock_setsockopt(*sock, pj_SOL_SOCKET(), SO_NOSIGPIPE, \n\t\t\t       &val, sizeof(val));\n\t}\n#endif\n\treturn PJ_SUCCESS;\n    }\n}\n#endif\n\n/*\n * Bind socket.\n */\nPJ_DEF(pj_status_t) pj_sock_bind( pj_sock_t sock, \n\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t  int len)\n{\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(addr && len >= (int)sizeof(struct sockaddr_in), PJ_EINVAL);\n\n    CHECK_ADDR_LEN(addr, len);\n\n    if (bind(sock, (struct sockaddr*)addr, len) != 0)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else\n\treturn PJ_SUCCESS;\n}\n\n\n/*\n * Bind socket.\n */\nPJ_DEF(pj_status_t) pj_sock_bind_in( pj_sock_t sock, \n\t\t\t\t     pj_uint32_t addr32,\n\t\t\t\t     pj_uint16_t port)\n{\n    pj_sockaddr_in addr;\n\n    PJ_CHECK_STACK();\n\n    PJ_SOCKADDR_SET_LEN(&addr, sizeof(pj_sockaddr_in));\n    addr.sin_family = PJ_AF_INET;\n    pj_bzero(addr.sin_zero, sizeof(addr.sin_zero));\n    addr.sin_addr.s_addr = pj_htonl(addr32);\n    addr.sin_port = pj_htons(port);\n\n    return pj_sock_bind(sock, &addr, sizeof(pj_sockaddr_in));\n}\n\n\n/*\n * Close socket.\n */\nPJ_DEF(pj_status_t) pj_sock_close(pj_sock_t sock)\n{\n    int rc;\n\n    PJ_CHECK_STACK();\n#if defined(PJ_WIN32) && PJ_WIN32!=0 || \\\n    defined(PJ_WIN64) && PJ_WIN64 != 0 || \\\n    defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0\n    rc = closesocket(sock);\n#else\n    rc = close(sock);\n#endif\n\n    if (rc != 0)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Get remote's name.\n */\nPJ_DEF(pj_status_t) pj_sock_getpeername( pj_sock_t sock,\n\t\t\t\t\t pj_sockaddr_t *addr,\n\t\t\t\t\t int *namelen)\n{\n    PJ_CHECK_STACK();\n    if (getpeername(sock, (struct sockaddr*)addr, (socklen_t*)namelen) != 0)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else {\n\tPJ_SOCKADDR_RESET_LEN(addr);\n\treturn PJ_SUCCESS;\n    }\n}\n\n/*\n * Get socket name.\n */\nPJ_DEF(pj_status_t) pj_sock_getsockname( pj_sock_t sock,\n\t\t\t\t\t pj_sockaddr_t *addr,\n\t\t\t\t\t int *namelen)\n{\n    PJ_CHECK_STACK();\n    if (getsockname(sock, (struct sockaddr*)addr, (socklen_t*)namelen) != 0)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else {\n\tPJ_SOCKADDR_RESET_LEN(addr);\n\treturn PJ_SUCCESS;\n    }\n}\n\n/*\n * Send data\n */\nPJ_DEF(pj_status_t) pj_sock_send(pj_sock_t sock,\n\t\t\t\t const void *buf,\n\t\t\t\t pj_ssize_t *len,\n\t\t\t\t unsigned flags)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(len, PJ_EINVAL);\n\n#ifdef MSG_NOSIGNAL\n    /* Suppress SIGPIPE. See https://trac.pjsip.org/repos/ticket/1538 */\n    flags |= MSG_NOSIGNAL;\n#endif\n\n    *len = send(sock, (const char*)buf, (int)(*len), flags);\n\n    if (*len < 0)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else\n\treturn PJ_SUCCESS;\n}\n\n\n/*\n * Send data.\n */\nPJ_DEF(pj_status_t) pj_sock_sendto(pj_sock_t sock,\n\t\t\t\t   const void *buf,\n\t\t\t\t   pj_ssize_t *len,\n\t\t\t\t   unsigned flags,\n\t\t\t\t   const pj_sockaddr_t *to,\n\t\t\t\t   int tolen)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(len, PJ_EINVAL);\n    \n    CHECK_ADDR_LEN(to, tolen);\n\n    *len = sendto(sock, (const char*)buf, (int)(*len), flags, \n\t\t  (const struct sockaddr*)to, tolen);\n\n    if (*len < 0) \n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else \n\treturn PJ_SUCCESS;\n}\n\n/*\n * Receive data.\n */\nPJ_DEF(pj_status_t) pj_sock_recv(pj_sock_t sock,\n\t\t\t\t void *buf,\n\t\t\t\t pj_ssize_t *len,\n\t\t\t\t unsigned flags)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(buf && len, PJ_EINVAL);\n\n    *len = recv(sock, (char*)buf, (int)(*len), flags);\n\n    if (*len < 0) \n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Receive data.\n */\nPJ_DEF(pj_status_t) pj_sock_recvfrom(pj_sock_t sock,\n\t\t\t\t     void *buf,\n\t\t\t\t     pj_ssize_t *len,\n\t\t\t\t     unsigned flags,\n\t\t\t\t     pj_sockaddr_t *from,\n\t\t\t\t     int *fromlen)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(buf && len, PJ_EINVAL);\n\n    *len = recvfrom(sock, (char*)buf, (int)(*len), flags, \n\t\t    (struct sockaddr*)from, (socklen_t*)fromlen);\n\n    if (*len < 0) \n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else {\n        if (from) {\n            PJ_SOCKADDR_RESET_LEN(from);\n        }\n\treturn PJ_SUCCESS;\n    }\n}\n\n/*\n * Get socket option.\n */\nPJ_DEF(pj_status_t) pj_sock_getsockopt( pj_sock_t sock,\n\t\t\t\t\tpj_uint16_t level,\n\t\t\t\t\tpj_uint16_t optname,\n\t\t\t\t\tvoid *optval,\n\t\t\t\t\tint *optlen)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(optval && optlen, PJ_EINVAL);\n\n    if (getsockopt(sock, level, optname, (char*)optval, (socklen_t*)optlen)!=0)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Set socket option.\n */\nPJ_DEF(pj_status_t) pj_sock_setsockopt( pj_sock_t sock,\n\t\t\t\t\tpj_uint16_t level,\n\t\t\t\t\tpj_uint16_t optname,\n\t\t\t\t\tconst void *optval,\n\t\t\t\t\tint optlen)\n{\n    int status;\n    PJ_CHECK_STACK();\n    \n#if (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_SUNOS) && PJ_SUNOS)\n    /* Some opt may still need int value (e.g:SO_EXCLUSIVEADDRUSE in win32). */\n    status = setsockopt(sock, \n\t\t     level, \n\t\t     ((optname&0xff00)==0xff00)?(int)optname|0xffff0000:optname, \t\t     \n\t\t     (const char*)optval, optlen);\n#else\n    status = setsockopt(sock, level, optname, (const char*)optval, optlen);\n#endif\n\n    if (status != 0)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Set socket option.\n */\nPJ_DEF(pj_status_t) pj_sock_setsockopt_params( pj_sock_t sockfd,\n\t\t\t\t\t       const pj_sockopt_params *params)\n{\n    unsigned int i = 0;\n    pj_status_t retval = PJ_SUCCESS;\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(params, PJ_EINVAL);\n    \n    for (;i<params->cnt && i<PJ_MAX_SOCKOPT_PARAMS;++i) {\n\tpj_status_t status = pj_sock_setsockopt(sockfd, \n\t\t\t\t\t(pj_uint16_t)params->options[i].level,\n\t\t\t\t\t(pj_uint16_t)params->options[i].optname,\n\t\t\t\t\tparams->options[i].optval, \n\t\t\t\t\tparams->options[i].optlen);\n\tif (status != PJ_SUCCESS) {\n\t    retval = status;\n\t    PJ_PERROR(4,(THIS_FILE, status,\n\t\t\t \"Warning: error applying sock opt %d\",\n\t\t\t params->options[i].optname));\n\t}\n    }\n\n    return retval;\n}\n\n/*\n * Connect socket.\n */\nPJ_DEF(pj_status_t) pj_sock_connect( pj_sock_t sock,\n\t\t\t\t     const pj_sockaddr_t *addr,\n\t\t\t\t     int namelen)\n{\n    PJ_CHECK_STACK();\n    if (connect(sock, (struct sockaddr*)addr, namelen) != 0)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else\n\treturn PJ_SUCCESS;\n}\n\n\n/*\n * Shutdown socket.\n */\n#if PJ_HAS_TCP\nPJ_DEF(pj_status_t) pj_sock_shutdown( pj_sock_t sock,\n\t\t\t\t      int how)\n{\n    PJ_CHECK_STACK();\n    if (shutdown(sock, how) != 0)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Start listening to incoming connections.\n */\nPJ_DEF(pj_status_t) pj_sock_listen( pj_sock_t sock,\n\t\t\t\t    int backlog)\n{\n    PJ_CHECK_STACK();\n    if (listen(sock, backlog) != 0)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Accept incoming connections\n */\nPJ_DEF(pj_status_t) pj_sock_accept( pj_sock_t serverfd,\n\t\t\t\t    pj_sock_t *newsock,\n\t\t\t\t    pj_sockaddr_t *addr,\n\t\t\t\t    int *addrlen)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(newsock != NULL, PJ_EINVAL);\n\n#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0\n    if (addr) {\n\tPJ_SOCKADDR_SET_LEN(addr, *addrlen);\n    }\n#endif\n    \n    *newsock = accept(serverfd, (struct sockaddr*)addr, (socklen_t*)addrlen);\n    if (*newsock==PJ_INVALID_SOCKET)\n\treturn PJ_RETURN_OS_ERROR(pj_get_native_netos_error());\n    else {\n\t\n#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0\n\tif (addr) {\n\t    PJ_SOCKADDR_RESET_LEN(addr);\n\t}\n#endif\n\t    \n\treturn PJ_SUCCESS;\n    }\n}\n#endif\t/* PJ_HAS_TCP */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/sock_common.c",
    "content": "/* $Id: sock_common.c 4343 2013-02-07 09:35:34Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/sock.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n#include <pj/errno.h>\n#include <pj/ip_helper.h>\n#include <pj/os.h>\n#include <pj/addr_resolv.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n#include <pj/compat/socket.h>\n\n#if 0\n    /* Enable some tracing */\n    #include <pj/log.h>\n    #define THIS_FILE   \"sock_common.c\"\n    #define TRACE_(arg)\tPJ_LOG(4,arg)\n#else\n    #define TRACE_(arg)\n#endif\n\n\n/*\n * Convert address string with numbers and dots to binary IP address.\n */ \nPJ_DEF(pj_in_addr) pj_inet_addr(const pj_str_t *cp)\n{\n    pj_in_addr addr;\n\n    pj_inet_aton(cp, &addr);\n    return addr;\n}\n\n/*\n * Convert address string with numbers and dots to binary IP address.\n */ \nPJ_DEF(pj_in_addr) pj_inet_addr2(const char *cp)\n{\n    pj_str_t str = pj_str((char*)cp);\n    return pj_inet_addr(&str);\n}\n\n/*\n * Get text representation.\n */\nPJ_DEF(char*) pj_inet_ntop2( int af, const void *src,\n\t\t\t     char *dst, int size)\n{\n    pj_status_t status;\n\n    status = pj_inet_ntop(af, src, dst, size);\n    return (status==PJ_SUCCESS)? dst : NULL;\n}\n\n/*\n * Print socket address.\n */\nPJ_DEF(char*) pj_sockaddr_print( const pj_sockaddr_t *addr,\n\t\t\t\t char *buf, int size,\n\t\t\t\t unsigned flags)\n{\n    enum {\n\tWITH_PORT = 1,\n\tWITH_BRACKETS = 2\n    };\n\n    char txt[PJ_INET6_ADDRSTRLEN];\n    char port[32];\n    const pj_addr_hdr *h = (const pj_addr_hdr*)addr;\n    char *bquote, *equote;\n    pj_status_t status;\n\n    status = pj_inet_ntop(h->sa_family, pj_sockaddr_get_addr(addr),\n\t\t\t  txt, sizeof(txt));\n    if (status != PJ_SUCCESS)\n\treturn \"\";\n\n    if (h->sa_family != PJ_AF_INET6 || (flags & WITH_BRACKETS)==0) {\n\tbquote = \"\"; equote = \"\";\n    } else {\n\tbquote = \"[\"; equote = \"]\";\n    }\n\n    if (flags & WITH_PORT) {\n\tpj_ansi_snprintf(port, sizeof(port), \":%d\",\n\t\t\t pj_sockaddr_get_port(addr));\n    } else {\n\tport[0] = '\\0';\n    }\n\n    pj_ansi_snprintf(buf, size, \"%s%s%s%s\",\n\t\t     bquote, txt, equote, port);\n\n    return buf;\n}\n\n/*\n * Set the IP address of an IP socket address from string address, \n * with resolving the host if necessary. The string address may be in a\n * standard numbers and dots notation or may be a hostname. If hostname\n * is specified, then the function will resolve the host into the IP\n * address.\n */\nPJ_DEF(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr,\n\t\t\t\t\t         const pj_str_t *str_addr)\n{\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(!str_addr || str_addr->slen < PJ_MAX_HOSTNAME, \n                     (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL));\n\n    PJ_SOCKADDR_RESET_LEN(addr);\n    addr->sin_family = PJ_AF_INET;\n    pj_bzero(addr->sin_zero, sizeof(addr->sin_zero));\n\n    if (str_addr && str_addr->slen) {\n\taddr->sin_addr = pj_inet_addr(str_addr);\n\tif (addr->sin_addr.s_addr == PJ_INADDR_NONE) {\n    \t    pj_hostent he;\n\t    pj_status_t rc;\n\n\t    rc = pj_gethostbyname(str_addr, &he);\n\t    if (rc == 0) {\n\t\taddr->sin_addr.s_addr = *(pj_uint32_t*)he.h_addr;\n\t    } else {\n\t\taddr->sin_addr.s_addr = PJ_INADDR_NONE;\n\t\treturn rc;\n\t    }\n\t}\n\n    } else {\n\taddr->sin_addr.s_addr = 0;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* Set address from a name */\nPJ_DEF(pj_status_t) pj_sockaddr_set_str_addr(int af,\n\t\t\t\t\t     pj_sockaddr *addr,\n\t\t\t\t\t     const pj_str_t *str_addr)\n{\n    pj_status_t status;\n\n    if (af == PJ_AF_INET) {\n\treturn pj_sockaddr_in_set_str_addr(&addr->ipv4, str_addr);\n    }\n\n    PJ_ASSERT_RETURN(af==PJ_AF_INET6, PJ_EAFNOTSUP);\n\n    /* IPv6 specific */\n\n    addr->ipv6.sin6_family = PJ_AF_INET6;\n    PJ_SOCKADDR_RESET_LEN(addr);\n\n    if (str_addr && str_addr->slen) {\n\tstatus = pj_inet_pton(PJ_AF_INET6, str_addr, &addr->ipv6.sin6_addr);\n\tif (status != PJ_SUCCESS) {\n    \t    pj_addrinfo ai;\n\t    unsigned count = 1;\n\n\t    status = pj_getaddrinfo(PJ_AF_INET6, str_addr, &count, &ai);\n\t    if (status==PJ_SUCCESS) {\n\t\tpj_memcpy(&addr->ipv6.sin6_addr, &ai.ai_addr.ipv6.sin6_addr,\n\t\t\t  sizeof(addr->ipv6.sin6_addr));\n\t    }\n\t}\n    } else {\n\tstatus = PJ_SUCCESS;\n    }\n\n    return status;\n}\n\n/*\n * Set the IP address and port of an IP socket address.\n * The string address may be in a standard numbers and dots notation or \n * may be a hostname. If hostname is specified, then the function will \n * resolve the host into the IP address.\n */\nPJ_DEF(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr,\n\t\t\t\t         const pj_str_t *str_addr,\n\t\t\t\t\t pj_uint16_t port)\n{\n    PJ_ASSERT_RETURN(addr, (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL));\n\n    PJ_SOCKADDR_RESET_LEN(addr);\n    addr->sin_family = PJ_AF_INET;\n    pj_bzero(addr->sin_zero, sizeof(addr->sin_zero));\n    pj_sockaddr_in_set_port(addr, port);\n    return pj_sockaddr_in_set_str_addr(addr, str_addr);\n}\n\n/*\n * Initialize IP socket address based on the address and port info.\n */\nPJ_DEF(pj_status_t) pj_sockaddr_init(int af, \n\t\t\t\t     pj_sockaddr *addr,\n\t\t\t\t     const pj_str_t *cp,\n\t\t\t\t     pj_uint16_t port)\n{\n    pj_status_t status;\n\n    if (af == PJ_AF_INET) {\n\treturn pj_sockaddr_in_init(&addr->ipv4, cp, port);\n    }\n\n    /* IPv6 specific */\n    PJ_ASSERT_RETURN(af==PJ_AF_INET6, PJ_EAFNOTSUP);\n\n    pj_bzero(addr, sizeof(pj_sockaddr_in6));\n    addr->addr.sa_family = PJ_AF_INET6;\n    \n    status = pj_sockaddr_set_str_addr(af, addr, cp);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    addr->ipv6.sin6_port = pj_htons(port);\n    return PJ_SUCCESS;\n}\n\n/*\n * Compare two socket addresses.\n */\nPJ_DEF(int) pj_sockaddr_cmp( const pj_sockaddr_t *addr1,\n\t\t\t     const pj_sockaddr_t *addr2)\n{\n    const pj_sockaddr *a1 = (const pj_sockaddr*) addr1;\n    const pj_sockaddr *a2 = (const pj_sockaddr*) addr2;\n    int port1, port2;\n    int result;\n\n    /* Compare address family */\n    if (a1->addr.sa_family < a2->addr.sa_family)\n\treturn -1;\n    else if (a1->addr.sa_family > a2->addr.sa_family)\n\treturn 1;\n\n    /* Compare addresses */\n    result = pj_memcmp(pj_sockaddr_get_addr(a1),\n\t\t       pj_sockaddr_get_addr(a2),\n\t\t       pj_sockaddr_get_addr_len(a1));\n    if (result != 0)\n\treturn result;\n\n    /* Compare port number */\n    port1 = pj_sockaddr_get_port(a1);\n    port2 = pj_sockaddr_get_port(a2);\n\n    if (port1 < port2)\n\treturn -1;\n    else if (port1 > port2)\n\treturn 1;\n\n    /* TODO:\n     *\tDo we need to compare flow label and scope id in IPv6? \n     */\n    \n    /* Looks equal */\n    return 0;\n}\n\n/*\n * Get first IP address associated with the hostname.\n */\nPJ_DEF(pj_in_addr) pj_gethostaddr(void)\n{\n    pj_sockaddr_in addr;\n    const pj_str_t *hostname = pj_gethostname();\n\n    pj_sockaddr_in_set_str_addr(&addr, hostname);\n    return addr.sin_addr;\n}\n\n/*\n * Get port number of a pj_sockaddr_in\n */\nPJ_DEF(pj_uint16_t) pj_sockaddr_in_get_port(const pj_sockaddr_in *addr)\n{\n    return pj_ntohs(addr->sin_port);\n}\n\n/*\n * Get the address part\n */\nPJ_DEF(void*) pj_sockaddr_get_addr(const pj_sockaddr_t *addr)\n{\n    const pj_sockaddr *a = (const pj_sockaddr*)addr;\n\n    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||\n\t\t     a->addr.sa_family == PJ_AF_INET6, NULL);\n\n    if (a->addr.sa_family == PJ_AF_INET6)\n\treturn (void*) &a->ipv6.sin6_addr;\n    else\n\treturn (void*) &a->ipv4.sin_addr;\n}\n\n/*\n * Check if sockaddr contains a non-zero address\n */\nPJ_DEF(pj_bool_t) pj_sockaddr_has_addr(const pj_sockaddr_t *addr)\n{\n    const pj_sockaddr *a = (const pj_sockaddr*)addr;\n\n    /* It's probably not wise to raise assertion here if\n     * the address doesn't contain a valid address family, and\n     * just return PJ_FALSE instead.\n     * \n     * The reason is because application may need to distinguish \n     * these three conditions with sockaddr:\n     *\ta) sockaddr is not initialized. This is by convention\n     *\t   indicated by sa_family==0.\n     *\tb) sockaddr is initialized with zero address. This is\n     *\t   indicated with the address field having zero address.\n     *\tc) sockaddr is initialized with valid address/port.\n     *\n     * If we enable this assertion, then application will loose\n     * the capability to specify condition a), since it will be\n     * forced to always initialize sockaddr (even with zero address).\n     * This may break some parts of upper layer libraries.\n     */\n    //PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||\n    //\t\t     a->addr.sa_family == PJ_AF_INET6, PJ_FALSE);\n\n    if (a->addr.sa_family!=PJ_AF_INET && a->addr.sa_family!=PJ_AF_INET6) {\n\treturn PJ_FALSE;\n    } else if (a->addr.sa_family == PJ_AF_INET6) {\n\tpj_uint8_t zero[24];\n\tpj_bzero(zero, sizeof(zero));\n\treturn pj_memcmp(a->ipv6.sin6_addr.s6_addr, zero, \n\t\t\t sizeof(pj_in6_addr)) != 0;\n    } else\n\treturn a->ipv4.sin_addr.s_addr != PJ_INADDR_ANY;\n}\n\n/*\n * Get port number\n */\nPJ_DEF(pj_uint16_t) pj_sockaddr_get_port(const pj_sockaddr_t *addr)\n{\n    const pj_sockaddr *a = (const pj_sockaddr*) addr;\n\n    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||\n\t\t     a->addr.sa_family == PJ_AF_INET6, (pj_uint16_t)0xFFFF);\n\n    return pj_ntohs((pj_uint16_t)(a->addr.sa_family == PJ_AF_INET6 ?\n\t\t\t\t    a->ipv6.sin6_port : a->ipv4.sin_port));\n}\n\n/*\n * Get the length of the address part.\n */\nPJ_DEF(unsigned) pj_sockaddr_get_addr_len(const pj_sockaddr_t *addr)\n{\n    const pj_sockaddr *a = (const pj_sockaddr*) addr;\n    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||\n\t\t     a->addr.sa_family == PJ_AF_INET6, 0);\n    return a->addr.sa_family == PJ_AF_INET6 ?\n\t    sizeof(pj_in6_addr) : sizeof(pj_in_addr);\n}\n\n/*\n * Get socket address length.\n */\nPJ_DEF(unsigned) pj_sockaddr_get_len(const pj_sockaddr_t *addr)\n{\n    const pj_sockaddr *a = (const pj_sockaddr*) addr;\n    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||\n\t\t     a->addr.sa_family == PJ_AF_INET6, 0);\n    return a->addr.sa_family == PJ_AF_INET6 ?\n\t    sizeof(pj_sockaddr_in6) : sizeof(pj_sockaddr_in);\n}\n\n/*\n * Copy only the address part (sin_addr/sin6_addr) of a socket address.\n */\nPJ_DEF(void) pj_sockaddr_copy_addr( pj_sockaddr *dst,\n\t\t\t\t    const pj_sockaddr *src)\n{\n    /* Destination sockaddr might not be initialized */\n    const char *srcbuf = (char*)pj_sockaddr_get_addr(src);\n    char *dstbuf = ((char*)dst) + (srcbuf - (char*)src);\n    pj_memcpy(dstbuf, srcbuf, pj_sockaddr_get_addr_len(src));\n}\n\n/*\n * Copy socket address.\n */\nPJ_DEF(void) pj_sockaddr_cp(pj_sockaddr_t *dst, const pj_sockaddr_t *src)\n{\n    pj_memcpy(dst, src, pj_sockaddr_get_len(src));\n}\n\n/*\n * Set port number of pj_sockaddr_in\n */\nPJ_DEF(void) pj_sockaddr_in_set_port(pj_sockaddr_in *addr, \n\t\t\t\t     pj_uint16_t hostport)\n{\n    addr->sin_port = pj_htons(hostport);\n}\n\n/*\n * Set port number of pj_sockaddr\n */\nPJ_DEF(pj_status_t) pj_sockaddr_set_port(pj_sockaddr *addr, \n\t\t\t\t\t pj_uint16_t hostport)\n{\n    int af = addr->addr.sa_family;\n\n    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EINVAL);\n\n    if (af == PJ_AF_INET6)\n\taddr->ipv6.sin6_port = pj_htons(hostport);\n    else\n\taddr->ipv4.sin_port = pj_htons(hostport);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get IPv4 address\n */\nPJ_DEF(pj_in_addr) pj_sockaddr_in_get_addr(const pj_sockaddr_in *addr)\n{\n    pj_in_addr in_addr;\n    in_addr.s_addr = pj_ntohl(addr->sin_addr.s_addr);\n    return in_addr;\n}\n\n/*\n * Set IPv4 address\n */\nPJ_DEF(void) pj_sockaddr_in_set_addr(pj_sockaddr_in *addr,\n\t\t\t\t     pj_uint32_t hostaddr)\n{\n    addr->sin_addr.s_addr = pj_htonl(hostaddr);\n}\n\n/*\n * Parse address\n */\nPJ_DEF(pj_status_t) pj_sockaddr_parse2(int af, unsigned options,\n\t\t\t\t       const pj_str_t *str,\n\t\t\t\t       pj_str_t *p_hostpart,\n\t\t\t\t       pj_uint16_t *p_port,\n\t\t\t\t       int *raf)\n{\n    const char *end = str->ptr + str->slen;\n    const char *last_colon_pos = NULL;\n    unsigned colon_cnt = 0;\n    const char *p;\n\n    PJ_ASSERT_RETURN((af==PJ_AF_INET || af==PJ_AF_INET6 || af==PJ_AF_UNSPEC) &&\n\t\t     options==0 &&\n\t\t     str!=NULL, PJ_EINVAL);\n\n    /* Special handling for empty input */\n    if (str->slen==0 || str->ptr==NULL) {\n\tif (p_hostpart)\n\t    p_hostpart->slen = 0;\n\tif (p_port)\n\t    *p_port = 0;\n\tif (raf)\n\t    *raf = PJ_AF_INET;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Count the colon and get the last colon */\n    for (p=str->ptr; p!=end; ++p) {\n\tif (*p == ':') {\n\t    ++colon_cnt;\n\t    last_colon_pos = p;\n\t}\n    }\n\n    /* Deduce address family if it's not given */\n    if (af == PJ_AF_UNSPEC) {\n\tif (colon_cnt > 1)\n\t    af = PJ_AF_INET6;\n\telse\n\t    af = PJ_AF_INET;\n    } else if (af == PJ_AF_INET && colon_cnt > 1)\n\treturn PJ_EINVAL;\n\n    if (raf)\n\t*raf = af;\n\n    if (af == PJ_AF_INET) {\n\t/* Parse as IPv4. Supported formats:\n\t *  - \"10.0.0.1:80\"\n\t *  - \"10.0.0.1\"\n\t *  - \"10.0.0.1:\"\n\t *  - \":80\"\n\t *  - \":\"\n\t */\n\tpj_str_t hostpart;\n\tunsigned long port;\n\n\thostpart.ptr = (char*)str->ptr;\n\n\tif (last_colon_pos) {\n\t    pj_str_t port_part;\n\t    int i;\n\n\t    hostpart.slen = last_colon_pos - str->ptr;\n\n\t    port_part.ptr = (char*)last_colon_pos + 1;\n\t    port_part.slen = end - port_part.ptr;\n\n\t    /* Make sure port number is valid */\n\t    for (i=0; i<port_part.slen; ++i) {\n\t\tif (!pj_isdigit(port_part.ptr[i]))\n\t\t    return PJ_EINVAL;\n\t    }\n\t    port = pj_strtoul(&port_part);\n\t    if (port > 65535)\n\t\treturn PJ_EINVAL;\n\t} else {\n\t    hostpart.slen = str->slen;\n\t    port = 0;\n\t}\n\n\tif (p_hostpart)\n\t    *p_hostpart = hostpart;\n\tif (p_port)\n\t    *p_port = (pj_uint16_t)port;\n\n\treturn PJ_SUCCESS;\n\n    } else if (af == PJ_AF_INET6) {\n\n\t/* Parse as IPv6. Supported formats:\n\t *  - \"fe::01:80\"  ==> note: port number is zero in this case, not 80!\n\t *  - \"[fe::01]:80\"\n\t *  - \"fe::01\"\n\t *  - \"fe::01:\"\n\t *  - \"[fe::01]\"\n\t *  - \"[fe::01]:\"\n\t *  - \"[::]:80\"\n\t *  - \":::80\"\n\t *  - \"[::]\"\n\t *  - \"[::]:\"\n\t *  - \":::\"\n\t *  - \"::\"\n\t */\n\tpj_str_t hostpart, port_part;\n\n\tif (*str->ptr == '[') {\n\t    char *end_bracket;\n\t    int i;\n\t    unsigned long port;\n\n\t    if (last_colon_pos == NULL)\n\t\treturn PJ_EINVAL;\n\n\t    end_bracket = pj_strchr(str, ']');\n\t    if (end_bracket == NULL)\n\t\treturn PJ_EINVAL;\n\n\t    hostpart.ptr = (char*)str->ptr + 1;\n\t    hostpart.slen = end_bracket - hostpart.ptr;\n\n\t    if (last_colon_pos < end_bracket) {\n\t\tport_part.ptr = NULL;\n\t\tport_part.slen = 0;\n\t    } else {\n\t\tport_part.ptr = (char*)last_colon_pos + 1;\n\t\tport_part.slen = end - port_part.ptr;\n\t    }\n\n\t    /* Make sure port number is valid */\n\t    for (i=0; i<port_part.slen; ++i) {\n\t\tif (!pj_isdigit(port_part.ptr[i]))\n\t\t    return PJ_EINVAL;\n\t    }\n\t    port = pj_strtoul(&port_part);\n\t    if (port > 65535)\n\t\treturn PJ_EINVAL;\n\n\t    if (p_hostpart)\n\t\t*p_hostpart = hostpart;\n\t    if (p_port)\n\t\t*p_port = (pj_uint16_t)port;\n\n\t    return PJ_SUCCESS;\n\n\t} else {\n\t    /* Treat everything as part of the IPv6 IP address */\n\t    if (p_hostpart)\n\t\t*p_hostpart = *str;\n\t    if (p_port)\n\t\t*p_port = 0;\n\n\t    return PJ_SUCCESS;\n\t}\n\n    } else {\n\treturn PJ_EAFNOTSUP;\n    }\n\n}\n\n/*\n * Parse address\n */\nPJ_DEF(pj_status_t) pj_sockaddr_parse( int af, unsigned options,\n\t\t\t\t       const pj_str_t *str,\n\t\t\t\t       pj_sockaddr *addr)\n{\n    pj_str_t hostpart;\n    pj_uint16_t port;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(addr, PJ_EINVAL);\n    PJ_ASSERT_RETURN(af==PJ_AF_UNSPEC ||\n\t\t     af==PJ_AF_INET ||\n\t\t     af==PJ_AF_INET6, PJ_EINVAL);\n    PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);\n\n    status = pj_sockaddr_parse2(af, options, str, &hostpart, &port, &af);\n    if (status != PJ_SUCCESS)\n\treturn status;\n    \n#if !defined(PJ_HAS_IPV6) || !PJ_HAS_IPV6\n    if (af==PJ_AF_INET6)\n\treturn PJ_EIPV6NOTSUP;\n#endif\n\n    status = pj_sockaddr_init(af, addr, &hostpart, port);\n#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6\n    if (status != PJ_SUCCESS && af == PJ_AF_INET6) {\n\t/* Parsing does not yield valid address. Try to treat the last \n\t * portion after the colon as port number.\n\t */\n\tconst char *last_colon_pos=NULL, *p;\n\tconst char *end = str->ptr + str->slen;\n\tunsigned long long_port;\n\tpj_str_t port_part;\n\tint i;\n\n\t/* Parse as IPv6:port */\n\tfor (p=str->ptr; p!=end; ++p) {\n\t    if (*p == ':')\n\t\tlast_colon_pos = p;\n\t}\n\n\tif (last_colon_pos == NULL)\n\t    return status;\n\n\thostpart.ptr = (char*)str->ptr;\n\thostpart.slen = last_colon_pos - str->ptr;\n\n\tport_part.ptr = (char*)last_colon_pos + 1;\n\tport_part.slen = end - port_part.ptr;\n\n\t/* Make sure port number is valid */\n\tfor (i=0; i<port_part.slen; ++i) {\n\t    if (!pj_isdigit(port_part.ptr[i]))\n\t\treturn status;\n\t}\n\tlong_port = pj_strtoul(&port_part);\n\tif (long_port > 65535)\n\t    return status;\n\n\tport = (pj_uint16_t)long_port;\n\n\tstatus = pj_sockaddr_init(PJ_AF_INET6, addr, &hostpart, port);\n    }\n#endif\n    \n    return status;\n}\n\n/* Resolve the IP address of local machine */\nPJ_DEF(pj_status_t) pj_gethostip(int af, pj_sockaddr *addr)\n{\n    unsigned i, count, cand_cnt;\n    enum {\n\tCAND_CNT = 8,\n\n\t/* Weighting to be applied to found addresses */\n\tWEIGHT_HOSTNAME\t= 1,\t/* hostname IP is not always valid! */\n\tWEIGHT_DEF_ROUTE = 2,\n\tWEIGHT_INTERFACE = 1,\n\tWEIGHT_LOOPBACK = -5,\n\tWEIGHT_LINK_LOCAL = -4,\n\tWEIGHT_DISABLED = -50,\n\n\tMIN_WEIGHT = WEIGHT_DISABLED+1\t/* minimum weight to use */\n    };\n    /* candidates: */\n    pj_sockaddr cand_addr[CAND_CNT];\n    int\t\tcand_weight[CAND_CNT];\n    int\t        selected_cand;\n    char\tstrip[PJ_INET6_ADDRSTRLEN+10];\n    /* Special IPv4 addresses. */\n    struct spec_ipv4_t\n    {\n\tpj_uint32_t addr;\n\tpj_uint32_t mask;\n\tint\t    weight;\n    } spec_ipv4[] =\n    {\n\t/* 127.0.0.0/8, loopback addr will be used if there is no other\n\t * addresses.\n\t */\n\t{ 0x7f000000, 0xFF000000, WEIGHT_LOOPBACK },\n\n\t/* 0.0.0.0/8, special IP that doesn't seem to be practically useful */\n\t{ 0x00000000, 0xFF000000, WEIGHT_DISABLED },\n\n\t/* 169.254.0.0/16, a zeroconf/link-local address, which has higher\n\t * priority than loopback and will be used if there is no other\n\t * valid addresses.\n\t */\n\t{ 0xa9fe0000, 0xFFFF0000, WEIGHT_LINK_LOCAL }\n    };\n    /* Special IPv6 addresses */\n    struct spec_ipv6_t\n    {\n\tpj_uint8_t addr[16];\n\tpj_uint8_t mask[16];\n\tint\t   weight;\n    } spec_ipv6[] =\n    {\n\t/* Loopback address, ::1/128 */\n\t{ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},\n\t  {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n\t   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},\n\t  WEIGHT_LOOPBACK\n\t},\n\n\t/* Link local, fe80::/10 */\n\t{ {0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\n\t  {0xff,0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\n\t  WEIGHT_LINK_LOCAL\n\t},\n\n\t/* Disabled, ::/128 */\n\t{ {0x0,0x0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\n\t{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n\t  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},\n\t  WEIGHT_DISABLED\n\t}\n    };\n    pj_addrinfo ai;\n    pj_status_t status;\n\n    /* May not be used if TRACE_ is disabled */\n    PJ_UNUSED_ARG(strip);\n\n#ifdef _MSC_VER\n    /* Get rid of \"uninitialized he variable\" with MS compilers */\n    pj_bzero(&ai, sizeof(ai));\n#endif\n\n    cand_cnt = 0;\n    pj_bzero(cand_addr, sizeof(cand_addr));\n    pj_bzero(cand_weight, sizeof(cand_weight));\n    for (i=0; i<PJ_ARRAY_SIZE(cand_addr); ++i) {\n\tcand_addr[i].addr.sa_family = (pj_uint16_t)af;\n\tPJ_SOCKADDR_RESET_LEN(&cand_addr[i]);\n    }\n\n    addr->addr.sa_family = (pj_uint16_t)af;\n    PJ_SOCKADDR_RESET_LEN(addr);\n\n#if !defined(PJ_GETHOSTIP_DISABLE_LOCAL_RESOLUTION) || \\\n    PJ_GETHOSTIP_DISABLE_LOCAL_RESOLUTION == 0\n    /* Get hostname's IP address */\n    count = 1;\n    status = pj_getaddrinfo(af, pj_gethostname(), &count, &ai);\n    if (status == PJ_SUCCESS) {\n    \tpj_assert(ai.ai_addr.addr.sa_family == (pj_uint16_t)af);\n    \tpj_sockaddr_copy_addr(&cand_addr[cand_cnt], &ai.ai_addr);\n\tpj_sockaddr_set_port(&cand_addr[cand_cnt], 0);\n\tcand_weight[cand_cnt] += WEIGHT_HOSTNAME;\n\t++cand_cnt;\n\n\tTRACE_((THIS_FILE, \"hostname IP is %s\",\n\t\tpj_sockaddr_print(&ai.ai_addr, strip, sizeof(strip), 0)));\n    }\n#else\n    PJ_UNUSED_ARG(ai);\n#endif\n\n    /* Get default interface (interface for default route) */\n    if (cand_cnt < PJ_ARRAY_SIZE(cand_addr)) {\n\tstatus = pj_getdefaultipinterface(af, addr);\n\tif (status == PJ_SUCCESS) {\n\t    TRACE_((THIS_FILE, \"default IP is %s\",\n\t\t    pj_sockaddr_print(addr, strip, sizeof(strip), 0)));\n\n\t    pj_sockaddr_set_port(addr, 0);\n\t    for (i=0; i<cand_cnt; ++i) {\n\t\tif (pj_sockaddr_cmp(&cand_addr[i], addr)==0)\n\t\t    break;\n\t    }\n\n\t    cand_weight[i] += WEIGHT_DEF_ROUTE;\n\t    if (i >= cand_cnt) {\n\t\tpj_sockaddr_copy_addr(&cand_addr[i], addr);\n\t\t++cand_cnt;\n\t    }\n\t}\n    }\n\n\n    /* Enumerate IP interfaces */\n    if (cand_cnt < PJ_ARRAY_SIZE(cand_addr)) {\n\tunsigned start_if = cand_cnt;\n\tcount = PJ_ARRAY_SIZE(cand_addr) - start_if;\n\n\tstatus = pj_enum_ip_interface(af, &count, &cand_addr[start_if]);\n\tif (status == PJ_SUCCESS && count) {\n\t    /* Clear the port number */\n\t    for (i=0; i<count; ++i)\n\t\tpj_sockaddr_set_port(&cand_addr[start_if+i], 0);\n\n\t    /* For each candidate that we found so far (that is the hostname\n\t     * address and default interface address, check if they're found\n\t     * in the interface list. If found, add the weight, and if not,\n\t     * decrease the weight.\n\t     */\n\t    for (i=0; i<cand_cnt; ++i) {\n\t\tunsigned j;\n\t\tfor (j=0; j<count; ++j) {\n\t\t    if (pj_sockaddr_cmp(&cand_addr[i], \n\t\t\t\t\t&cand_addr[start_if+j])==0)\n\t\t\tbreak;\n\t\t}\n\n\t\tif (j == count) {\n\t\t    /* Not found */\n\t\t    cand_weight[i] -= WEIGHT_INTERFACE;\n\t\t} else {\n\t\t    cand_weight[i] += WEIGHT_INTERFACE;\n\t\t}\n\t    }\n\n\t    /* Add remaining interface to candidate list. */\n\t    for (i=0; i<count; ++i) {\n\t\tunsigned j;\n\t\tfor (j=0; j<cand_cnt; ++j) {\n\t\t    if (pj_sockaddr_cmp(&cand_addr[start_if+i], \n\t\t\t\t\t&cand_addr[j])==0)\n\t\t\tbreak;\n\t\t}\n\n\t\tif (j == cand_cnt) {\n\t\t    pj_sockaddr_copy_addr(&cand_addr[cand_cnt], \n\t\t\t\t\t  &cand_addr[start_if+i]);\n\t\t    cand_weight[cand_cnt] += WEIGHT_INTERFACE;\n\t\t    ++cand_cnt;\n\t\t}\n\t    }\n\t}\n    }\n\n    /* Apply weight adjustment for special IPv4/IPv6 addresses\n     * See http://trac.pjsip.org/repos/ticket/1046\n     */\n    if (af == PJ_AF_INET) {\n\tfor (i=0; i<cand_cnt; ++i) {\n\t    unsigned j;\n\t    for (j=0; j<PJ_ARRAY_SIZE(spec_ipv4); ++j) {\n\t\t    pj_uint32_t a = pj_ntohl(cand_addr[i].ipv4.sin_addr.s_addr);\n\t\t    pj_uint32_t pa = spec_ipv4[j].addr;\n\t\t    pj_uint32_t pm = spec_ipv4[j].mask;\n\n\t\t    if ((a & pm) == pa) {\n\t\t\tcand_weight[i] += spec_ipv4[j].weight;\n\t\t\tbreak;\n\t\t    }\n\t    }\n\t}\n    } else if (af == PJ_AF_INET6) {\n\tfor (i=0; i<PJ_ARRAY_SIZE(spec_ipv6); ++i) {\n\t\tunsigned j;\n\t\tfor (j=0; j<cand_cnt; ++j) {\n\t\t    pj_uint8_t *a = cand_addr[j].ipv6.sin6_addr.s6_addr;\n\t\t    pj_uint8_t am[16];\n\t\t    pj_uint8_t *pa = spec_ipv6[i].addr;\n\t\t    pj_uint8_t *pm = spec_ipv6[i].mask;\n\t\t    unsigned k;\n\n\t\t    for (k=0; k<16; ++k) {\n\t\t\tam[k] = (pj_uint8_t)((a[k] & pm[k]) & 0xFF);\n\t\t    }\n\n\t\t    if (pj_memcmp(am, pa, 16)==0) {\n\t\t\tcand_weight[j] += spec_ipv6[i].weight;\n\t\t    }\n\t\t}\n\t}\n    } else {\n\treturn PJ_EAFNOTSUP;\n    }\n\n    /* Enumerate candidates to get the best IP address to choose */\n    selected_cand = -1;\n    for (i=0; i<cand_cnt; ++i) {\n\tTRACE_((THIS_FILE, \"Checking candidate IP %s, weight=%d\",\n\t\tpj_sockaddr_print(&cand_addr[i], strip, sizeof(strip), 0),\n\t\tcand_weight[i]));\n\n\tif (cand_weight[i] < MIN_WEIGHT) {\n\t    continue;\n\t}\n\n\tif (selected_cand == -1)\n\t    selected_cand = i;\n\telse if (cand_weight[i] > cand_weight[selected_cand])\n\t    selected_cand = i;\n    }\n\n    /* If else fails, returns loopback interface as the last resort */\n    if (selected_cand == -1) {\n\tif (af==PJ_AF_INET) {\n\t    addr->ipv4.sin_addr.s_addr = pj_htonl (0x7f000001);\n\t} else {\n\t    pj_in6_addr *s6_addr;\n\n\t    s6_addr = (pj_in6_addr*) pj_sockaddr_get_addr(addr);\n\t    pj_bzero(s6_addr, sizeof(pj_in6_addr));\n\t    s6_addr->s6_addr[15] = 1;\n\t}\n\tTRACE_((THIS_FILE, \"Loopback IP %s returned\",\n\t\tpj_sockaddr_print(addr, strip, sizeof(strip), 0)));\n    } else {\n\tpj_sockaddr_copy_addr(addr, &cand_addr[selected_cand]);\n\tTRACE_((THIS_FILE, \"Candidate %s selected\",\n\t\tpj_sockaddr_print(addr, strip, sizeof(strip), 0)));\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* Get IP interface for sending to the specified destination */\nPJ_DEF(pj_status_t) pj_getipinterface(int af,\n                                      const pj_str_t *dst,\n                                      pj_sockaddr *itf_addr,\n                                      pj_bool_t allow_resolve,\n                                      pj_sockaddr *p_dst_addr)\n{\n    pj_sockaddr dst_addr;\n    pj_sock_t fd;\n    int len;\n    pj_uint8_t zero[64];\n    pj_status_t status;\n\n    pj_sockaddr_init(af, &dst_addr, NULL, 53);\n    status = pj_inet_pton(af, dst, pj_sockaddr_get_addr(&dst_addr));\n    if (status != PJ_SUCCESS) {\n\t/* \"dst\" is not an IP address. */\n\tif (allow_resolve) {\n\t    status = pj_sockaddr_init(af, &dst_addr, dst, 53);\n\t} else {\n\t    pj_str_t cp;\n\n\t    if (af == PJ_AF_INET) {\n\t\tcp = pj_str(\"1.1.1.1\");\n\t    } else {\n\t\tcp = pj_str(\"1::1\");\n\t    }\n\t    status = pj_sockaddr_init(af, &dst_addr, &cp, 53);\n\t}\n\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    /* Create UDP socket and connect() to the destination IP */\n    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &fd);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    status = pj_sock_connect(fd, &dst_addr, pj_sockaddr_get_len(&dst_addr));\n    if (status != PJ_SUCCESS) {\n\tpj_sock_close(fd);\n\treturn status;\n    }\n\n    len = sizeof(*itf_addr);\n    status = pj_sock_getsockname(fd, itf_addr, &len);\n    if (status != PJ_SUCCESS) {\n\tpj_sock_close(fd);\n\treturn status;\n    }\n\n    pj_sock_close(fd);\n\n    /* Check that the address returned is not zero */\n    pj_bzero(zero, sizeof(zero));\n    if (pj_memcmp(pj_sockaddr_get_addr(itf_addr), zero,\n\t\t  pj_sockaddr_get_addr_len(itf_addr))==0)\n    {\n\treturn PJ_ENOTFOUND;\n    }\n\n    if (p_dst_addr)\n\t*p_dst_addr = dst_addr;\n\n    return PJ_SUCCESS;\n}\n\n/* Get the default IP interface */\nPJ_DEF(pj_status_t) pj_getdefaultipinterface(int af, pj_sockaddr *addr)\n{\n    pj_str_t cp;\n\n    if (af == PJ_AF_INET) {\n\tcp = pj_str(\"1.1.1.1\");\n    } else {\n\tcp = pj_str(\"1::1\");\n    }\n\n    return pj_getipinterface(af, &cp, addr, PJ_FALSE, NULL);\n}\n\n\n/*\n * Bind socket at random port.\n */\nPJ_DEF(pj_status_t) pj_sock_bind_random(  pj_sock_t sockfd,\n\t\t\t\t          const pj_sockaddr_t *addr,\n\t\t\t\t          pj_uint16_t port_range,\n\t\t\t\t          pj_uint16_t max_try)\n{\n    pj_sockaddr bind_addr;\n    int addr_len;\n    pj_uint16_t base_port;\n    pj_status_t status = PJ_SUCCESS;\n\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(addr, PJ_EINVAL);\n\n    pj_sockaddr_cp(&bind_addr, addr);\n    addr_len = pj_sockaddr_get_len(addr);\n    base_port = pj_sockaddr_get_port(addr);\n\n    if (base_port == 0 || port_range == 0) {\n\treturn pj_sock_bind(sockfd, &bind_addr, addr_len);\n    }\n\n    for (; max_try; --max_try) {\n\tpj_uint16_t port;\n\tport = (pj_uint16_t)(base_port + pj_rand() % (port_range + 1));\n\tpj_sockaddr_set_port(&bind_addr, port);\n\tstatus = pj_sock_bind(sockfd, &bind_addr, addr_len);\n\tif (status == PJ_SUCCESS)\n\t    break;\n    }\n\n    return status;\n}\n\n\n/*\n * Adjust socket send/receive buffer size.\n */\nPJ_DEF(pj_status_t) pj_sock_setsockopt_sobuf( pj_sock_t sockfd,\n\t\t\t\t\t      pj_uint16_t optname,\n\t\t\t\t\t      pj_bool_t auto_retry,\n\t\t\t\t\t      unsigned *buf_size)\n{\n    pj_status_t status;\n    int try_size, cur_size, i, step, size_len;\n    enum { MAX_TRY = 20 };\n\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(sockfd != PJ_INVALID_SOCKET &&\n\t\t     buf_size &&\n\t\t     *buf_size > 0 &&\n\t\t     (optname == pj_SO_RCVBUF() ||\n\t\t      optname == pj_SO_SNDBUF()),\n\t\t     PJ_EINVAL);\n\n    size_len = sizeof(cur_size);\n    status = pj_sock_getsockopt(sockfd, pj_SOL_SOCKET(), optname,\n\t\t\t\t&cur_size, &size_len);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    try_size = *buf_size;\n    step = (try_size - cur_size) / MAX_TRY;\n    if (step < 4096)\n\tstep = 4096;\n\n    for (i = 0; i < (MAX_TRY-1); ++i) {\n\tif (try_size <= cur_size) {\n\t    /* Done, return current size */\n\t    *buf_size = cur_size;\n\t    break;\n\t}\n\n\tstatus = pj_sock_setsockopt(sockfd, pj_SOL_SOCKET(), optname,\n\t\t\t\t    &try_size, sizeof(try_size));\n\tif (status == PJ_SUCCESS) {\n\t    status = pj_sock_getsockopt(sockfd, pj_SOL_SOCKET(), optname,\n\t\t\t\t\t&cur_size, &size_len);\n\t    if (status != PJ_SUCCESS) {\n\t\t/* Ops! No info about current size, just return last try size\n\t\t * and quit.\n\t\t */\n\t\t*buf_size = try_size;\n\t\tbreak;\n\t    }\n\t}\n\n\tif (!auto_retry)\n\t    break;\n\n\ttry_size -= step;\n    }\n\n    return status;\n}\n\n\n/* Only need to implement these in DLL build */\n#if defined(PJ_DLL)\n\nPJ_DEF(pj_uint16_t) pj_AF_UNSPEC(void)\n{\n    return PJ_AF_UNSPEC;\n}\n\nPJ_DEF(pj_uint16_t) pj_AF_UNIX(void)\n{\n    return PJ_AF_UNIX;\n}\n\nPJ_DEF(pj_uint16_t) pj_AF_INET(void)\n{\n    return PJ_AF_INET;\n}\n\nPJ_DEF(pj_uint16_t) pj_AF_INET6(void)\n{\n    return PJ_AF_INET6;\n}\n\nPJ_DEF(pj_uint16_t) pj_AF_PACKET(void)\n{\n    return PJ_AF_PACKET;\n}\n\nPJ_DEF(pj_uint16_t) pj_AF_IRDA(void)\n{\n    return PJ_AF_IRDA;\n}\n\nPJ_DEF(int) pj_SOCK_STREAM(void)\n{\n    return PJ_SOCK_STREAM;\n}\n\nPJ_DEF(int) pj_SOCK_DGRAM(void)\n{\n    return PJ_SOCK_DGRAM;\n}\n\nPJ_DEF(int) pj_SOCK_RAW(void)\n{\n    return PJ_SOCK_RAW;\n}\n\nPJ_DEF(int) pj_SOCK_RDM(void)\n{\n    return PJ_SOCK_RDM;\n}\n\nPJ_DEF(pj_uint16_t) pj_SOL_SOCKET(void)\n{\n    return PJ_SOL_SOCKET;\n}\n\nPJ_DEF(pj_uint16_t) pj_SOL_IP(void)\n{\n    return PJ_SOL_IP;\n}\n\nPJ_DEF(pj_uint16_t) pj_SOL_TCP(void)\n{\n    return PJ_SOL_TCP;\n}\n\nPJ_DEF(pj_uint16_t) pj_SOL_UDP(void)\n{\n    return PJ_SOL_UDP;\n}\n\nPJ_DEF(pj_uint16_t) pj_SOL_IPV6(void)\n{\n    return PJ_SOL_IPV6;\n}\n\nPJ_DEF(int) pj_IP_TOS(void)\n{\n    return PJ_IP_TOS;\n}\n\nPJ_DEF(int) pj_IPTOS_LOWDELAY(void)\n{\n    return PJ_IPTOS_LOWDELAY;\n}\n\nPJ_DEF(int) pj_IPTOS_THROUGHPUT(void)\n{\n    return PJ_IPTOS_THROUGHPUT;\n}\n\nPJ_DEF(int) pj_IPTOS_RELIABILITY(void)\n{\n    return PJ_IPTOS_RELIABILITY;\n}\n\nPJ_DEF(int) pj_IPTOS_MINCOST(void)\n{\n    return PJ_IPTOS_MINCOST;\n}\n\nPJ_DEF(pj_uint16_t) pj_SO_TYPE(void)\n{\n    return PJ_SO_TYPE;\n}\n\nPJ_DEF(pj_uint16_t) pj_SO_RCVBUF(void)\n{\n    return PJ_SO_RCVBUF;\n}\n\nPJ_DEF(pj_uint16_t) pj_SO_SNDBUF(void)\n{\n    return PJ_SO_SNDBUF;\n}\n\nPJ_DEF(pj_uint16_t) pj_TCP_NODELAY(void)\n{\n    return PJ_TCP_NODELAY;\n}\n\nPJ_DEF(pj_uint16_t) pj_SO_REUSEADDR(void)\n{\n    return PJ_SO_REUSEADDR;\n}\n\nPJ_DEF(pj_uint16_t) pj_SO_NOSIGPIPE(void)\n{\n    return PJ_SO_NOSIGPIPE;\n}\n\nPJ_DEF(pj_uint16_t) pj_SO_PRIORITY(void)\n{\n    return PJ_SO_PRIORITY;\n}\n\nPJ_DEF(pj_uint16_t) pj_IP_MULTICAST_IF(void)\n{\n    return PJ_IP_MULTICAST_IF;\n}\n\nPJ_DEF(pj_uint16_t) pj_IP_MULTICAST_TTL(void)\n{\n    return PJ_IP_MULTICAST_TTL;\n}\n\nPJ_DEF(pj_uint16_t) pj_IP_MULTICAST_LOOP(void)\n{\n    return PJ_IP_MULTICAST_LOOP;\n}\n\nPJ_DEF(pj_uint16_t) pj_IP_ADD_MEMBERSHIP(void)\n{\n    return PJ_IP_ADD_MEMBERSHIP;\n}\n\nPJ_DEF(pj_uint16_t) pj_IP_DROP_MEMBERSHIP(void)\n{\n    return PJ_IP_DROP_MEMBERSHIP;\n}\n\nPJ_DEF(int) pj_MSG_OOB(void)\n{\n    return PJ_MSG_OOB;\n}\n\nPJ_DEF(int) pj_MSG_PEEK(void)\n{\n    return PJ_MSG_PEEK;\n}\n\nPJ_DEF(int) pj_MSG_DONTROUTE(void)\n{\n    return PJ_MSG_DONTROUTE;\n}\n\n#endif\t/* PJ_DLL */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/sock_linux_kernel.c",
    "content": "/* $Id: sock_linux_kernel.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/sock.h>\n#include <pj/assert.h>\n#include <pj/string.h>\t    /* pj_memcpy()\t    */\n#include <pj/os.h>\t    /* PJ_CHECK_STACK()\t    */\n#include <pj/addr_resolv.h> /* pj_gethostbyname()   */\n#include <pj/ctype.h>\n#include <pj/compat/sprintf.h>\n#include <pj/log.h>\n#include <pj/errno.h>\n\n/* Linux kernel specific. */\n#include <linux/socket.h>\n#include <linux/net.h>\n//#include <net/sock.h>\n#include <linux/security.h>\n#include <linux/syscalls.h>\t/* sys_xxx()\t*/\n#include <asm/ioctls.h>\t\t/* FIONBIO\t*/\n#include <linux/utsname.h>\t/* for pj_gethostname() */\n\n#define THIS_FILE   \"sock_linux_kernel.c\"\n\n/*\n * Address families conversion.\n * The values here are indexed based on pj_addr_family-0xFF00.\n */\nconst pj_uint16_t PJ_AF_UNIX\t= AF_UNIX;\nconst pj_uint16_t PJ_AF_INET\t= AF_INET;\nconst pj_uint16_t PJ_AF_INET6\t= AF_INET6;\n#ifdef AF_PACKET\nconst pj_uint16_t PJ_AF_PACKET\t= AF_PACKET;\n#else\n#  error \"AF_PACKET undeclared!\"\n#endif\n#ifdef AF_IRDA\nconst pj_uint16_t PJ_AF_IRDA\t= AF_IRDA;\n#else\n#  error \"AF_IRDA undeclared!\"\n#endif\n\n/*\n * Socket types conversion.\n * The values here are indexed based on pj_sock_type-0xFF00\n */\nconst pj_uint16_t PJ_SOCK_STREAM= SOCK_STREAM;\nconst pj_uint16_t PJ_SOCK_DGRAM\t= SOCK_DGRAM;\nconst pj_uint16_t PJ_SOCK_RAW\t= SOCK_RAW;\nconst pj_uint16_t PJ_SOCK_RDM\t= SOCK_RDM;\n\n/*\n * Socket level values.\n */\nconst pj_uint16_t PJ_SOL_SOCKET\t= SOL_SOCKET;\n#ifdef SOL_IP\nconst pj_uint16_t PJ_SOL_IP\t= SOL_IP;\n#else\n#  error \"SOL_IP undeclared!\"\n#endif /* SOL_IP */\n#if defined(SOL_TCP)\nconst pj_uint16_t PJ_SOL_TCP\t= SOL_TCP;\n#else\n#  error \"SOL_TCP undeclared!\"\n#endif /* SOL_TCP */\n#ifdef SOL_UDP\nconst pj_uint16_t PJ_SOL_UDP\t= SOL_UDP;\n#else\n#  error \"SOL_UDP undeclared!\"\n#endif\n#ifdef SOL_IPV6\nconst pj_uint16_t PJ_SOL_IPV6\t= SOL_IPV6;\n#else\n#  error \"SOL_IPV6 undeclared!\"\n#endif\n\n/* optname values. */\nconst pj_uint16_t PJ_SO_TYPE    = SO_TYPE;\nconst pj_uint16_t PJ_SO_RCVBUF  = SO_RCVBUF;\nconst pj_uint16_t PJ_SO_SNDBUF  = SO_SNDBUF;\n\n/*\n * Convert 16-bit value from network byte order to host byte order.\n */\nPJ_DEF(pj_uint16_t) pj_ntohs(pj_uint16_t netshort)\n{\n    return ntohs(netshort);\n}\n\n/*\n * Convert 16-bit value from host byte order to network byte order.\n */\nPJ_DEF(pj_uint16_t) pj_htons(pj_uint16_t hostshort)\n{\n    return htons(hostshort);\n}\n\n/*\n * Convert 32-bit value from network byte order to host byte order.\n */\nPJ_DEF(pj_uint32_t) pj_ntohl(pj_uint32_t netlong)\n{\n    return ntohl(netlong);\n}\n\n/*\n * Convert 32-bit value from host byte order to network byte order.\n */\nPJ_DEF(pj_uint32_t) pj_htonl(pj_uint32_t hostlong)\n{\n    return htonl(hostlong);\n}\n\n/*\n * Convert an Internet host address given in network byte order\n * to string in standard numbers and dots notation.\n */\nPJ_DEF(char*) pj_inet_ntoa(pj_in_addr in)\n{\n#define\tUC(b)\t(((int)b)&0xff)\n    static char b[18];\n    char *p;\n\n    p = (char *)&in;\n    pj_snprintf(b, sizeof(b), \"%d.%d.%d.%d\", \n\t       UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));\n\n    return b;\n}\n\n/*\n * This function converts the Internet host address ccp from the standard\n * numbers-and-dots notation into binary data and stores it in the structure\n * that inp points to. \n */\nPJ_DEF(int) pj_inet_aton(const pj_str_t *ccp, struct pj_in_addr *addr)\n{\n    pj_uint32_t val;\n    int base, n;\n    char c;\n    unsigned parts[4];\n    unsigned *pp = parts;\n    char cp_copy[18];\n    char *cp = cp_copy;\n    \n    addr->s_addr = PJ_INADDR_NONE;\n\n    if (ccp->slen > 15) return 0;\n\n    pj_memcpy(cp, ccp->ptr, ccp->slen);\n    cp[ccp->slen] = '\\0';\n\n    c = *cp;\n    for (;;) {\n\t/*\n\t * Collect number up to ``.''.\n\t * Values are specified as for C:\n\t * 0x=hex, 0=octal, isdigit=decimal.\n\t */\n\tif (!pj_isdigit((int)c))\n\t    return (0);\n\tval = 0; base = 10;\n\tif (c == '0') {\n\t    c = *++cp;\n\t    if (c == 'x' || c == 'X')\n\t\tbase = 16, c = *++cp;\n\t    else\n\t\tbase = 8;\n\t}\n\n\tfor (;;) {\n\t    if (pj_isascii((int)c) && pj_isdigit((int)c)) {\n\t\tval = (val * base) + (c - '0');\n\t\tc = *++cp;\n\t    } else if (base==16 && pj_isascii((int)c) && pj_isxdigit((int)c)) {\n\t\tval = (val << 4) |\n\t\t      (c + 10 - (pj_islower((int)c) ? 'a' : 'A'));\n\t\tc = *++cp;\n\t    } else\n\t\tbreak;\n\t}\n\n\tif (c == '.') {\n\t    /*\n\t     * Internet format:\n\t     *  a.b.c.d\n\t     *  a.b.c   (with c treated as 16 bits)\n\t     *  a.b\t(with b treated as 24 bits)\n\t     */\n\t    if (pp >= parts + 3)\n\t\treturn (0);\n\t    *pp++ = val;\n\t    c = *++cp;\n\t} else\n\t    break;\n    }\n\n    /*\n     * Check for trailing characters.\n     */\n    if (c != '\\0' && (!pj_isascii((int)c) || !pj_isspace((int)c)))\n        return (0);\n    /*\n     * Concoct the address according to\n     * the number of parts specified.\n     */\n    n = pp - parts + 1;\n    switch (n) {\n    case 0:\n\treturn (0);\t    /* initial nondigit */\n    case 1:\t\t/* a -- 32 bits */\n\tbreak;\n    case 2:\t\t/* a.b -- 8.24 bits */\n\tif (val > 0xffffff)\n\t    return (0);\n\tval |= parts[0] << 24;\n\tbreak;\n    case 3:\t\t/* a.b.c -- 8.8.16 bits */\n\tif (val > 0xffff)\n\t    return (0);\n\tval |= (parts[0] << 24) | (parts[1] << 16);\n\tbreak;\n    case 4:\t\t/* a.b.c.d -- 8.8.8.8 bits */\n\tif (val > 0xff)\n\t    return (0);\n\tval |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);\n\tbreak;\n    }\n\n    if (addr)\n\taddr->s_addr = pj_htonl(val);\n    return (1);\n}\n\n/*\n * Convert address string with numbers and dots to binary IP address.\n */ \nPJ_DEF(pj_in_addr) pj_inet_addr(const pj_str_t *cp)\n{\n    pj_in_addr addr;\n    pj_inet_aton(cp, &addr);\n    return addr;\n}\n\n/*\n * Set the IP address of an IP socket address from string address, \n * with resolving the host if necessary. The string address may be in a\n * standard numbers and dots notation or may be a hostname. If hostname\n * is specified, then the function will resolve the host into the IP\n * address.\n */\nPJ_DEF(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr,\n\t\t\t\t\t         const pj_str_t *str_addr)\n{\n    PJ_CHECK_STACK();\n\n    pj_assert(str_addr && str_addr->slen < PJ_MAX_HOSTNAME);\n\n    addr->sin_family = AF_INET;\n\n    if (str_addr && str_addr->slen) {\n\taddr->sin_addr = pj_inet_addr(str_addr);\n\tif (addr->sin_addr.s_addr == PJ_INADDR_NONE) {\n    \t    pj_hostent he;\n\t    if (pj_gethostbyname(str_addr, &he) == 0) {\n\t\taddr->sin_addr.s_addr = *(pj_uint32_t*)he.h_addr;\n\t    } else {\n\t\taddr->sin_addr.s_addr = PJ_INADDR_NONE;\n\t\treturn -1;\n\t    }\n\t}\n\n    } else {\n\taddr->sin_addr.s_addr = 0;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Set the IP address and port of an IP socket address.\n * The string address may be in a standard numbers and dots notation or \n * may be a hostname. If hostname is specified, then the function will \n * resolve the host into the IP address.\n */\nPJ_DEF(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr,\n\t\t\t\t         const pj_str_t *str_addr,\n\t\t\t\t\t pj_uint16_t port)\n{\n    pj_assert(addr && str_addr);\n\n    addr->sin_family = PJ_AF_INET;\n    pj_sockaddr_in_set_port(addr, port);\n    return pj_sockaddr_in_set_str_addr(addr, str_addr);\n}\n\n\n/*\n * Get hostname.\n */\nPJ_DEF(const pj_str_t*) pj_gethostname(void)\n{\n    static char buf[PJ_MAX_HOSTNAME];\n    static pj_str_t hostname;\n\n    PJ_CHECK_STACK();\n\n    if (hostname.ptr == NULL) {\n\thostname.ptr = buf;\n\tdown_read(&uts_sem);\n\thostname.slen = strlen(system_utsname.nodename);\n\tif (hostname.slen > PJ_MAX_HOSTNAME) {\n\t    hostname.ptr[0] = '\\0';\n\t    hostname.slen = 0;\n\t} else {\n\t    pj_memcpy(hostname.ptr, system_utsname.nodename, hostname.slen);\n\t}\n\tup_read(&uts_sem);\n    }\n    return &hostname;\n}\n\n/*\n * Get first IP address associated with the hostname.\n */\nPJ_DEF(pj_in_addr) pj_gethostaddr(void)\n{\n    pj_sockaddr_in addr;\n    const pj_str_t *hostname = pj_gethostname();\n\n    pj_sockaddr_in_set_str_addr(&addr, hostname);\n    return addr.sin_addr;\n}\n\n\n/*\n * Create new socket/endpoint for communication and returns a descriptor.\n */\nPJ_DEF(pj_status_t) pj_sock_socket(int af, int type, int proto, \n\t\t\t\t   pj_sock_t *sock_fd)\n{\n    long result;\n\n    PJ_CHECK_STACK();\n\n    /* Sanity checks. */\n    PJ_ASSERT_RETURN(PJ_INVALID_SOCKET == -1 && sock_fd != NULL, PJ_EINVAL);\n\n    /* Initialize returned socket */\n    *sock_fd = PJ_INVALID_SOCKET;\n\n    /* Create socket. */\n    result = sys_socket(af, type, proto);\n    if (result < 0) {\n\treturn PJ_RETURN_OS_ERROR((-result));\n    }\n\n    *sock_fd = result;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Bind socket.\n */\nPJ_DEF(pj_status_t) pj_sock_bind( pj_sock_t sockfd, \n\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t  int len)\n{\n    long err;\n    mm_segment_t oldfs;\n\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(addr!=NULL && len >= sizeof(struct pj_sockaddr),\n\t\t     PJ_EINVAL);\n\n    oldfs = get_fs();\n    set_fs(KERNEL_DS);\n    \n    err = sys_bind(sockfd, (struct sockaddr*)addr, len);\n\n    set_fs(oldfs);\n\n    if (err)\n\treturn PJ_RETURN_OS_ERROR(-err);\n    else\n\treturn PJ_SUCCESS;\n}\n\n\n/*\n * Bind socket.\n */\nPJ_DEF(pj_status_t) pj_sock_bind_in( pj_sock_t sockfd, \n\t\t\t\t     pj_uint32_t addr32,\n\t\t\t\t     pj_uint16_t port)\n{\n    pj_sockaddr_in addr;\n\n    PJ_CHECK_STACK();\n\n    addr.sin_family = PJ_AF_INET;\n    addr.sin_addr.s_addr = pj_htonl(addr32);\n    addr.sin_port = pj_htons(port);\n\n    return pj_sock_bind(sockfd, &addr, sizeof(pj_sockaddr_in));\n}\n\n/*\n * Close socket.\n */\nPJ_DEF(pj_status_t) pj_sock_close(pj_sock_t sockfd)\n{\n    long err;\n\n    err = sys_close(sockfd);\n\n    if (err != 0)\n\treturn PJ_RETURN_OS_ERROR(-err);\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Get remote's name.\n */\nPJ_DEF(pj_status_t) pj_sock_getpeername( pj_sock_t sockfd,\n\t\t\t\t\t pj_sockaddr_t *addr,\n\t\t\t\t\t int *namelen)\n{\n    mm_segment_t oldfs;\n    long err;\n\n    PJ_CHECK_STACK();\n\n    oldfs = get_fs();\n    set_fs(KERNEL_DS);\n\n    err = sys_getpeername( sockfd, addr, namelen);\n\n    set_fs(oldfs);\n\n    if (err)\n\treturn PJ_RETURN_OS_ERROR(-err);\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Get socket name.\n */\nPJ_DEF(pj_status_t) pj_sock_getsockname( pj_sock_t sockfd,\n\t\t\t\t\t pj_sockaddr_t *addr,\n\t\t\t\t\t int *namelen)\n{\n    mm_segment_t oldfs;\n    int err;\n\n    PJ_CHECK_STACK();\n\n    oldfs = get_fs();\n    set_fs(KERNEL_DS);\n    \n    err = sys_getsockname( sockfd, addr, namelen );\n\n    set_fs(oldfs);\n\n    if (err)\n\treturn PJ_RETURN_OS_ERROR(-err);\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Send data\n */\nPJ_DEF(pj_status_t) pj_sock_send( pj_sock_t sockfd,\n\t\t\t\t  const void *buf,\n\t\t\t\t  pj_ssize_t *len,\n\t\t\t\t  unsigned flags)\n{\n    return pj_sock_sendto(sockfd, buf, len, flags, NULL, 0);\n}\n\n\n/*\n * Send data.\n */\nPJ_DEF(pj_status_t) pj_sock_sendto( pj_sock_t sockfd,\n\t\t\t\t    const void *buff,\n\t\t\t\t    pj_ssize_t *len,\n\t\t\t\t    unsigned flags,\n\t\t\t\t    const pj_sockaddr_t *addr,\n\t\t\t\t    int addr_len)\n{\n    long err;\n    mm_segment_t oldfs;\n\n    PJ_CHECK_STACK();\n\n    oldfs = get_fs();\n    set_fs(KERNEL_DS);\n    \n    err = *len = sys_sendto( sockfd, (void*)buff, *len, flags, \n\t\t\t     (void*)addr, addr_len );\n\n    set_fs(oldfs);\n    \n    if (err >= 0) {\n\treturn PJ_SUCCESS;\n    }\n    else {\n\treturn PJ_RETURN_OS_ERROR(-err);\n    }\n}\n\n/*\n * Receive data.\n */\nPJ_DEF(pj_status_t) pj_sock_recv( pj_sock_t sockfd,\n\t\t\t\t  void *buf,\n\t\t\t\t  pj_ssize_t *len,\n\t\t\t\t  unsigned flags)\n{\n    return pj_sock_recvfrom(sockfd, buf, len, flags, NULL, NULL);\n}\n\n/*\n * Receive data.\n */\nPJ_DEF(pj_status_t) pj_sock_recvfrom( pj_sock_t sockfd,\n\t\t\t\t      void *buff,\n\t\t\t\t      pj_ssize_t *size,\n\t\t\t\t      unsigned flags,\n\t\t\t\t      pj_sockaddr_t *from,\n\t\t\t\t      int *fromlen)\n{\n    mm_segment_t oldfs;\n    long err;\n\n    PJ_CHECK_STACK();\n\n    oldfs = get_fs();\n    set_fs(KERNEL_DS);\n\n    err = *size = sys_recvfrom( sockfd, buff, *size, flags, from, fromlen);\n\n    set_fs(oldfs);\n\n    if (err >= 0) {\n\treturn PJ_SUCCESS;\n    }\n    else {\n\treturn PJ_RETURN_OS_ERROR(-err);\n    }\n}\n\n/*\n * Get socket option.\n */\nPJ_DEF(pj_status_t) pj_sock_getsockopt( pj_sock_t sockfd,\n\t\t\t\t\tpj_uint16_t level,\n\t\t\t\t\tpj_uint16_t optname,\n\t\t\t\t\tvoid *optval,\n\t\t\t\t\tint *optlen)\n{\n    mm_segment_t oldfs;\n    long err;\n\n    PJ_CHECK_STACK();\n\n    oldfs = get_fs();\n    set_fs(KERNEL_DS);\n\n    err = sys_getsockopt( sockfd, level, optname, optval, optlen);\n\n    set_fs(oldfs);\n\n    if (err)\n\treturn PJ_RETURN_OS_ERROR(-err);\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Set socket option.\n */\nPJ_DEF(pj_status_t) pj_sock_setsockopt( pj_sock_t sockfd,\n\t\t\t\t\tpj_uint16_t level,\n\t\t\t\t\tpj_uint16_t optname,\n\t\t\t\t\tconst void *optval,\n\t\t\t\t\tint optlen)\n{\n    long err;\n    mm_segment_t oldfs;\n\n    PJ_CHECK_STACK();\n\n\n    oldfs = get_fs();\n    set_fs(KERNEL_DS);\n\n    err = sys_setsockopt( sockfd, level, optname, (void*)optval, optlen);\n\n    set_fs(oldfs);\n\n    if (err)\n\treturn PJ_RETURN_OS_ERROR(-err);\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Set socket option.\n */\nPJ_DEF(pj_status_t) pj_sock_setsockopt_params( pj_sock_t sockfd,\n\t\t\t\t\t       const pj_sockopt_params *params)\n{\n    unsigned int i = 0;\n    pj_status_t retval = PJ_SUCCESS;\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(params, PJ_EINVAL);\n    \n    for (;i<params->cnt && i<PJ_MAX_SOCKOPT_PARAMS;++i) {\n\tpj_status_t status = pj_sock_setsockopt(sockfd, \n\t\t\t\t\t\tparams->options[i].level,\n\t\t\t\t\t\tparams->options[i].optname,\n\t\t\t\t\t\tparams->options[i].optval, \n\t\t\t\t\t\tparams->options[i].optlen);\n\tif (status != PJ_SUCCESS) {\n\t    retval = status;\n\t    PJ_PERROR(4,(THIS_FILE, status,\n\t\t\t \"Warning: error applying sock opt %d\",\n\t\t\t params->options[i].optname));\n\t}\n    }\n\n    return retval;\n}\n\n/*\n * Shutdown socket.\n */\n#if PJ_HAS_TCP\nPJ_DEF(pj_status_t) pj_sock_shutdown( pj_sock_t sockfd,\n\t\t\t\t      int how)\n{\n    long err;\n\n    PJ_CHECK_STACK();\n\n    err = sys_shutdown(sockfd, how);\n\n    if (err)\n\treturn PJ_RETURN_OS_ERROR(-err);\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Start listening to incoming connections.\n */\nPJ_DEF(pj_status_t) pj_sock_listen( pj_sock_t sockfd,\n\t\t\t\t    int backlog)\n{\n    long err;\n\n    PJ_CHECK_STACK();\n\n    err = sys_listen( sockfd, backlog );\n\n    if (err)\n\treturn PJ_RETURN_OS_ERROR(-err);\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Connect socket.\n */\nPJ_DEF(pj_status_t) pj_sock_connect( pj_sock_t sockfd,\n\t\t\t\t     const pj_sockaddr_t *addr,\n\t\t\t\t     int namelen)\n{\n    long err;\n    mm_segment_t oldfs;\n    \n    PJ_CHECK_STACK();\n\n    oldfs = get_fs();\n    set_fs(KERNEL_DS);\n\n    err = sys_connect( sockfd, (void*)addr, namelen );\n\n    set_fs(oldfs);\n\n    if (err)\n\treturn PJ_RETURN_OS_ERROR(-err);\n    else\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Accept incoming connections\n */\nPJ_DEF(pj_status_t) pj_sock_accept( pj_sock_t sockfd,\n\t\t\t\t    pj_sock_t *newsockfd,\n\t\t\t\t    pj_sockaddr_t *addr,\n\t\t\t\t    int *addrlen)\n{\n    long err;\n\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(newsockfd != NULL, PJ_EINVAL);\n\n    err = sys_accept( sockfd, addr, addrlen);\n\n    if (err < 0) {\n\t*newsockfd = PJ_INVALID_SOCKET;\n\treturn PJ_RETURN_OS_ERROR(-err);\n    }\n    else {\n\t*newsockfd = err;\n\treturn PJ_SUCCESS;\n    }\n}\n#endif\t/* PJ_HAS_TCP */\n\n\n\n/*\n * Permission to steal inet_ntoa() and inet_aton() as long as this notice below\n * is included:\n */\n/*\n * Copyright (c) 1983, 1993\n *  The Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. All advertising materials mentioning features or use of this software\n *    must display the following acknowledgement:\n *  This product includes software developed by the University of\n *  California, Berkeley and its contributors.\n * 4. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/sock_qos_bsd.c",
    "content": "/* $Id: sock_qos_bsd.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/sock_qos.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/string.h>\n\n/* This is the implementation of QoS with BSD socket's setsockopt(),\n * using IP_TOS and SO_PRIORITY\n */ \n#if !defined(PJ_QOS_IMPLEMENTATION) || PJ_QOS_IMPLEMENTATION==PJ_QOS_BSD\n\nPJ_DEF(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,\n\t\t\t\t\t   pj_qos_params *param)\n{\n    pj_status_t last_err = PJ_ENOTSUP;\n    pj_status_t status;\n\n    /* No op? */\n    if (!param->flags)\n\treturn PJ_SUCCESS;\n\n    /* Clear WMM field since we don't support it */\n    param->flags &= ~(PJ_QOS_PARAM_HAS_WMM);\n\n    /* Set TOS/DSCP */\n    if (param->flags & PJ_QOS_PARAM_HAS_DSCP) {\n\t/* Value is dscp_val << 2 */\n\tint val = (param->dscp_val << 2);\n\tstatus = pj_sock_setsockopt(sock, pj_SOL_IP(), pj_IP_TOS(), \n\t\t\t\t    &val, sizeof(val));\n\tif (status != PJ_SUCCESS) {\n\t    param->flags &= ~(PJ_QOS_PARAM_HAS_DSCP);\n\t    last_err = status;\n\t}\n    }\n\n    /* Set SO_PRIORITY */\n    if (param->flags & PJ_QOS_PARAM_HAS_SO_PRIO) {\n\tint val = param->so_prio;\n\tstatus = pj_sock_setsockopt(sock, pj_SOL_SOCKET(), pj_SO_PRIORITY(),\n\t\t\t\t    &val, sizeof(val));\n\tif (status != PJ_SUCCESS) {\n\t    param->flags &= ~(PJ_QOS_PARAM_HAS_SO_PRIO);\n\t    last_err = status;\n\t}\n    }\n\n    return param->flags ? PJ_SUCCESS : last_err;\n}\n\nPJ_DEF(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,\n\t\t\t\t\t pj_qos_type type)\n{\n    pj_qos_params param;\n    pj_status_t status;\n\n    status = pj_qos_get_params(type, &param);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return pj_sock_set_qos_params(sock, &param);\n}\n\n\nPJ_DEF(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,\n\t\t\t\t\t   pj_qos_params *p_param)\n{\n    pj_status_t last_err = PJ_ENOTSUP;\n    int val, optlen;\n    pj_status_t status;\n\n    pj_bzero(p_param, sizeof(*p_param));\n\n    /* Get DSCP/TOS value */\n    optlen = sizeof(val);\n    status = pj_sock_getsockopt(sock, pj_SOL_IP(), pj_IP_TOS(), \n\t\t\t\t&val, &optlen);\n    if (status == PJ_SUCCESS) {\n\tp_param->flags |= PJ_QOS_PARAM_HAS_DSCP;\n\tp_param->dscp_val = (pj_uint8_t)(val >> 2);\n    } else {\n\tlast_err = status;\n    }\n\n    /* Get SO_PRIORITY */\n    optlen = sizeof(val);\n    status = pj_sock_getsockopt(sock, pj_SOL_SOCKET(), pj_SO_PRIORITY(),\n\t\t\t\t&val, &optlen);\n    if (status == PJ_SUCCESS) {\n\tp_param->flags |= PJ_QOS_PARAM_HAS_SO_PRIO;\n\tp_param->so_prio = (pj_uint8_t)val;\n    } else {\n\tlast_err = status;\n    }\n\n    /* WMM is not supported */\n\n    return p_param->flags ? PJ_SUCCESS : last_err;\n}\n\nPJ_DEF(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,\n\t\t\t\t\t pj_qos_type *p_type)\n{\n    pj_qos_params param;\n    pj_status_t status;\n\n    status = pj_sock_get_qos_params(sock, &param);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return pj_qos_get_type(&param, p_type);\n}\n\n#endif\t/* PJ_QOS_IMPLEMENTATION */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/sock_qos_common.c",
    "content": "/* $Id: sock_qos_common.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/sock_qos.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/log.h>\n#include <pj/string.h>\n\n#define THIS_FILE   \"sock_qos_common.c\"\n#define ALL_FLAGS   (PJ_QOS_PARAM_HAS_DSCP | PJ_QOS_PARAM_HAS_SO_PRIO | \\\n                     PJ_QOS_PARAM_HAS_WMM)\n\n/* \"Standard\" mapping between traffic type and QoS params */\nstatic const pj_qos_params qos_map[] = \n{\n    /* flags\tdscp  prio wmm_prio */\n    {ALL_FLAGS, 0x00, 0,    PJ_QOS_WMM_PRIO_BULK_EFFORT},   /* BE */\n    {ALL_FLAGS, 0x08, 2,    PJ_QOS_WMM_PRIO_BULK},\t    /* BK */\n    {ALL_FLAGS, 0x28, 5,    PJ_QOS_WMM_PRIO_VIDEO},\t    /* VI */\n    {ALL_FLAGS, 0x30, 6,    PJ_QOS_WMM_PRIO_VOICE},\t    /* VO */\n    {ALL_FLAGS, 0x38, 7,    PJ_QOS_WMM_PRIO_VOICE}\t    /* CO */\n};\n\n\n/* Retrieve the mapping for the specified type */\nPJ_DEF(pj_status_t) pj_qos_get_params(pj_qos_type type, \n\t\t\t\t      pj_qos_params *p_param)\n{\n    PJ_ASSERT_RETURN(type<=PJ_QOS_TYPE_CONTROL && p_param, PJ_EINVAL);\n    pj_memcpy(p_param, &qos_map[type], sizeof(*p_param));\n    return PJ_SUCCESS;\n}\n\n/* Get the matching traffic type */\nPJ_DEF(pj_status_t) pj_qos_get_type( const pj_qos_params *param,\n\t\t\t\t     pj_qos_type *p_type)\n{\n    unsigned dscp_type = PJ_QOS_TYPE_BEST_EFFORT,\n\t     prio_type = PJ_QOS_TYPE_BEST_EFFORT,\n\t     wmm_type = PJ_QOS_TYPE_BEST_EFFORT;\n    unsigned i, count=0;\n\n    PJ_ASSERT_RETURN(param && p_type, PJ_EINVAL);\n\n    if (param->flags & PJ_QOS_PARAM_HAS_DSCP)  {\n\tfor (i=0; i<=PJ_QOS_TYPE_CONTROL; ++i) {\n\t    if (param->dscp_val >= qos_map[i].dscp_val)\n\t\tdscp_type = (pj_qos_type)i;\n\t}\n\t++count;\n    }\n\n    if (param->flags & PJ_QOS_PARAM_HAS_SO_PRIO) {\n\tfor (i=0; i<=PJ_QOS_TYPE_CONTROL; ++i) {\n\t    if (param->so_prio >= qos_map[i].so_prio)\n\t\tprio_type = (pj_qos_type)i;\n\t}\n\t++count;\n    }\n\n    if (param->flags & PJ_QOS_PARAM_HAS_WMM) {\n\tfor (i=0; i<=PJ_QOS_TYPE_CONTROL; ++i) {\n\t    if (param->wmm_prio >= qos_map[i].wmm_prio)\n\t\twmm_type = (pj_qos_type)i;\n\t}\n\t++count;\n    }\n\n    if (count)\n\t*p_type = (pj_qos_type)((dscp_type + prio_type + wmm_type) / count);\n    else\n\t*p_type = PJ_QOS_TYPE_BEST_EFFORT;\n\n    return PJ_SUCCESS;\n}\n\n/* Apply QoS */\nPJ_DEF(pj_status_t) pj_sock_apply_qos( pj_sock_t sock,\n\t\t\t\t       pj_qos_type qos_type,\n\t\t\t\t       pj_qos_params *qos_params,\n\t\t\t\t       unsigned log_level,\n\t\t\t\t       const char *log_sender,\n\t\t\t\t       const char *sock_name)\n{\n    pj_status_t qos_type_rc = PJ_SUCCESS,\n\t\tqos_params_rc = PJ_SUCCESS;\n\n    if (!log_sender)\n\tlog_sender = THIS_FILE;\n    if (!sock_name)\n\tsock_name = \"socket\";\n\n    if (qos_type != PJ_QOS_TYPE_BEST_EFFORT) {\n\tqos_type_rc = pj_sock_set_qos_type(sock, qos_type);\n\n\tif (qos_type_rc != PJ_SUCCESS) {\n\t    pj_perror(log_level, log_sender,  qos_type_rc, \n\t\t      \"Error setting QoS type %d to %s\", \n\t\t      qos_type, sock_name);\n\t}\n    }\n\n    if (qos_params && qos_params->flags) {\n\tqos_params_rc = pj_sock_set_qos_params(sock, qos_params);\n\tif (qos_params_rc != PJ_SUCCESS) {\n\t    pj_perror(log_level, log_sender,  qos_params_rc, \n\t\t      \"Error setting QoS params (flags=%d) to %s\", \n\t\t      qos_params->flags, sock_name);\n\t    if (qos_type_rc != PJ_SUCCESS)\n\t\treturn qos_params_rc;\n\t}\n    } else if (qos_type_rc != PJ_SUCCESS)\n\treturn qos_type_rc;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_sock_apply_qos2( pj_sock_t sock,\n \t\t\t\t        pj_qos_type qos_type,\n\t\t\t\t        const pj_qos_params *qos_params,\n\t\t\t\t        unsigned log_level,\n\t\t\t\t        const char *log_sender,\n\t\t\t\t        const char *sock_name)\n{\n    pj_qos_params qos_params_buf, *qos_params_copy = NULL;\n\n    if (qos_params) {\n\tpj_memcpy(&qos_params_buf, qos_params, sizeof(*qos_params));\n\tqos_params_copy = &qos_params_buf;\n    }\n\n    return pj_sock_apply_qos(sock, qos_type, qos_params_copy,\n\t\t\t     log_level, log_sender, sock_name);\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/sock_qos_dummy.c",
    "content": "/* $Id: sock_qos_dummy.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/sock_qos.h>\n#include <pj/errno.h>\n#include <pj/log.h>\n\n/* Dummy implementation of QoS API. \n * (this is controlled by pjlib's config.h)\n */\n#if defined(PJ_QOS_IMPLEMENTATION) && PJ_QOS_IMPLEMENTATION==PJ_QOS_DUMMY\n\n#define THIS_FILE   \"sock_qos_dummy.c\"\n\n\nPJ_DEF(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,\n\t\t\t\t\t   pj_qos_params *param)\n{\n    PJ_UNUSED_ARG(sock);\n    PJ_UNUSED_ARG(param);\n\n    PJ_LOG(4,(THIS_FILE, \"pj_sock_set_qos_params() is not implemented \"\n\t\t\t \"for this platform\"));\n    return PJ_ENOTSUP;\n}\n\nPJ_DEF(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,\n\t\t\t\t\t pj_qos_type type)\n{\n    PJ_UNUSED_ARG(sock);\n    PJ_UNUSED_ARG(type);\n\n    PJ_LOG(4,(THIS_FILE, \"pj_sock_set_qos_type() is not implemented \"\n\t\t\t \"for this platform\"));\n    return PJ_ENOTSUP;\n}\n\n\nPJ_DEF(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,\n\t\t\t\t\t   pj_qos_params *p_param)\n{\n    PJ_UNUSED_ARG(sock);\n    PJ_UNUSED_ARG(p_param);\n\n    PJ_LOG(4,(THIS_FILE, \"pj_sock_get_qos_params() is not implemented \"\n\t\t\t \"for this platform\"));\n    return PJ_ENOTSUP;\n}\n\nPJ_DEF(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,\n\t\t\t\t\t pj_qos_type *p_type)\n{\n    PJ_UNUSED_ARG(sock);\n    PJ_UNUSED_ARG(p_type);\n\n    PJ_LOG(4,(THIS_FILE, \"pj_sock_get_qos_type() is not implemented \"\n\t\t\t \"for this platform\"));\n    return PJ_ENOTSUP;\n}\n\n#endif\t/* PJ_QOS_DUMMY */\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/sock_qos_symbian.cpp",
    "content": "/* $Id: sock_qos_symbian.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/sock_qos.h>\n#include \"os_symbian.h\"\n\nPJ_DEF(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,\n\t\t\t\t\t   pj_qos_params *param)\n{\n    PJ_ASSERT_RETURN(sock!=0 && sock!=PJ_INVALID_SOCKET, PJ_EINVAL);\n    \n    CPjSocket *pjsock = (CPjSocket*)sock;\n    RSocket & rsock = pjsock->Socket();\n    pj_status_t last_err = PJ_ENOTSUP;\n    \n    /* SO_PRIORITY and WMM are not supported */\n    param->flags &= ~(PJ_QOS_PARAM_HAS_SO_PRIO | PJ_QOS_PARAM_HAS_WMM);\n    \n    if (param->flags & PJ_QOS_PARAM_HAS_DSCP) {\n\tTInt err;\n\t\n\terr = rsock.SetOpt(KSoIpTOS, KProtocolInetIp,\n\t\t           (param->dscp_val << 2));\n\tif (err != KErrNone) {\n\t    last_err = PJ_RETURN_OS_ERROR(err);\n\t    param->flags &= ~(PJ_QOS_PARAM_HAS_DSCP);\n\t}\n    }\n    \n    return param->flags ? PJ_SUCCESS : last_err;\n}\n\nPJ_DEF(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,\n\t\t\t\t\t pj_qos_type type)\n{\n    pj_qos_params param;\n    pj_status_t status;\n    \n    status = pj_qos_get_params(type, &param);\n    if (status != PJ_SUCCESS)\n\treturn status;\n    \n    return pj_sock_set_qos_params(sock, &param);\n}\n\n\nPJ_DEF(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,\n\t\t\t\t\t   pj_qos_params *p_param)\n{\n    PJ_ASSERT_RETURN(sock!=0 && sock!=PJ_INVALID_SOCKET, PJ_EINVAL);\n    \n    CPjSocket *pjsock = (CPjSocket*)sock;\n    RSocket & rsock = pjsock->Socket();\n    TInt err, dscp;\n    \n    pj_bzero(p_param, sizeof(*p_param));\n\n    err = rsock.GetOpt(KSoIpTOS, KProtocolInetIp, dscp);\n    if (err == KErrNone) {\n\tp_param->flags |= PJ_QOS_PARAM_HAS_DSCP;\n\tp_param->dscp_val = (dscp >> 2);\n\treturn PJ_SUCCESS;\n    } else {\n\treturn PJ_RETURN_OS_ERROR(err);\n    }\n}\n\nPJ_DEF(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,\n\t\t\t\t\t pj_qos_type *p_type)\n{\n    pj_qos_params param;\n    pj_status_t status;\n    \n    status = pj_sock_get_qos_params(sock, &param);\n    if (status != PJ_SUCCESS)\n\treturn status;\n    \n    return pj_qos_get_type(&param, p_type);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/sock_qos_wm.c",
    "content": "/* $Id: sock_qos_wm.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/sock_qos.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/log.h>\n\n#include <winsock.h>\n\n/* QoS implementation for Windows Mobile 6, must be enabled explicitly\n * (this is controlled by pjlib's config.h)\n */\n#if defined(PJ_QOS_IMPLEMENTATION) && PJ_QOS_IMPLEMENTATION==PJ_QOS_WM\n\n#define THIS_FILE   \"sock_qos_wm.c\"\n\n/* Mapping between our traffic type and WM's DSCP traffic types */\nstatic const int dscp_map[] = \n{\n    DSCPBestEffort,\n    DSCPBackground,\n    DSCPVideo,\n    DSCPAudio,\n    DSCPControl\n};\n\nPJ_DEF(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,\n\t\t\t\t\t   pj_qos_params *param)\n{\n    PJ_UNUSED_ARG(sock);\n    PJ_UNUSED_ARG(param);\n\n    PJ_LOG(4,(THIS_FILE, \"pj_sock_set_qos_params() is not implemented \"\n\t\t\t \"for this platform\"));\n    return PJ_ENOTSUP;\n}\n\nPJ_DEF(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,\n\t\t\t\t\t pj_qos_type type)\n{\n    int value;\n\n    PJ_ASSERT_RETURN(type < PJ_ARRAY_SIZE(dscp_map), PJ_EINVAL);\n\n    value = dscp_map[type];\n    return pj_sock_setsockopt(sock, IPPROTO_IP, IP_DSCP_TRAFFIC_TYPE,\n\t\t\t      &value, sizeof(value));\n}\n\n\nPJ_DEF(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,\n\t\t\t\t\t   pj_qos_params *p_param)\n{\n    PJ_UNUSED_ARG(sock);\n    PJ_UNUSED_ARG(p_param);\n\n    PJ_LOG(4,(THIS_FILE, \"pj_sock_get_qos_params() is not implemented \"\n\t\t\t \"for this platform\"));\n    return PJ_ENOTSUP;\n}\n\nPJ_DEF(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,\n\t\t\t\t\t pj_qos_type *p_type)\n{\n    pj_status_t status;\n    int value, optlen;\n    unsigned i;\n\n    optlen = sizeof(value);\n    value = 0;\n    status = pj_sock_getsockopt(sock, IPPROTO_IP, IP_DSCP_TRAFFIC_TYPE,\n\t\t\t        &value, &optlen);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    *p_type = PJ_QOS_TYPE_BEST_EFFORT;\n    for (i=0; i<PJ_ARRAY_SIZE(dscp_map); ++i) {\n\tif (value == dscp_map[i]) {\n\t    *p_type = (pj_qos_type)i;\n\t    break;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJ_QOS_IMPLEMENTATION */\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/sock_select.c",
    "content": "/* $Id: sock_select.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/sock_select.h>\n#include <pj/compat/socket.h>\n#include <pj/os.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n\n#if defined(PJ_HAS_STRING_H) && PJ_HAS_STRING_H!=0\n#   include <string.h>\n#endif\n\n#if defined(PJ_HAS_SYS_TIME_H) && PJ_HAS_SYS_TIME_H!=0\n#   include <sys/time.h>\n#endif\n\n#ifdef _MSC_VER\n#   pragma warning(disable: 4018)    // Signed/unsigned mismatch in FD_*\n#   pragma warning(disable: 4389)    // Signed/unsigned mismatch in FD_*\n#endif\n\n#define PART_FDSET(ps)\t\t((fd_set*)&ps->data[1])\n#define PART_FDSET_OR_NULL(ps)\t(ps ? PART_FDSET(ps) : NULL)\n#define PART_COUNT(ps)\t\t(ps->data[0])\n\nPJ_DEF(void) PJ_FD_ZERO(pj_fd_set_t *fdsetp)\n{\n    PJ_CHECK_STACK();\n    pj_assert(sizeof(pj_fd_set_t)-sizeof(pj_sock_t) >= sizeof(fd_set));\n\n    FD_ZERO(PART_FDSET(fdsetp));\n    PART_COUNT(fdsetp) = 0;\n}\n\n\nPJ_DEF(void) PJ_FD_SET(pj_sock_t fd, pj_fd_set_t *fdsetp)\n{\n    PJ_CHECK_STACK();\n    pj_assert(sizeof(pj_fd_set_t)-sizeof(pj_sock_t) >= sizeof(fd_set));\n\n    if (!PJ_FD_ISSET(fd, fdsetp))\n        ++PART_COUNT(fdsetp);\n    FD_SET(fd, PART_FDSET(fdsetp));\n}\n\n\nPJ_DEF(void) PJ_FD_CLR(pj_sock_t fd, pj_fd_set_t *fdsetp)\n{\n    PJ_CHECK_STACK();\n    pj_assert(sizeof(pj_fd_set_t)-sizeof(pj_sock_t) >= sizeof(fd_set));\n\n    if (PJ_FD_ISSET(fd, fdsetp))\n        --PART_COUNT(fdsetp);\n    FD_CLR(fd, PART_FDSET(fdsetp));\n}\n\n\nPJ_DEF(pj_bool_t) PJ_FD_ISSET(pj_sock_t fd, const pj_fd_set_t *fdsetp)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(sizeof(pj_fd_set_t)-sizeof(pj_sock_t) >= sizeof(fd_set),\n                     0);\n\n    return FD_ISSET(fd, PART_FDSET(fdsetp));\n}\n\nPJ_DEF(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp)\n{\n    return PART_COUNT(fdsetp);\n}\n\nPJ_DEF(int) pj_sock_select( int n, \n\t\t\t    pj_fd_set_t *readfds, \n\t\t\t    pj_fd_set_t *writefds,\n\t\t\t    pj_fd_set_t *exceptfds, \n\t\t\t    const pj_time_val *timeout)\n{\n    struct timeval os_timeout, *p_os_timeout;\n\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(sizeof(pj_fd_set_t)-sizeof(pj_sock_t) >= sizeof(fd_set),\n                     PJ_EBUG);\n\n    if (timeout) {\n\tos_timeout.tv_sec = timeout->sec;\n\tos_timeout.tv_usec = timeout->msec * 1000;\n\tp_os_timeout = &os_timeout;\n    } else {\n\tp_os_timeout = NULL;\n    }\n\n    return select(n, PART_FDSET_OR_NULL(readfds), PART_FDSET_OR_NULL(writefds),\n\t\t  PART_FDSET_OR_NULL(exceptfds), p_os_timeout);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/sock_select_symbian.cpp",
    "content": "/* $Id: sock_select_symbian.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/sock_select.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/os.h>\n#include \"os_symbian.h\"\n\n \nstruct symbian_fd_set\n{\n    unsigned\t count;\n    CPjSocket\t*sock[PJ_IOQUEUE_MAX_HANDLES];\n};\n\n\nPJ_DEF(void) PJ_FD_ZERO(pj_fd_set_t *fdsetp)\n{\n    symbian_fd_set *fds = (symbian_fd_set *)fdsetp;\n    fds->count = 0;\n}\n\n\nPJ_DEF(void) PJ_FD_SET(pj_sock_t fd, pj_fd_set_t *fdsetp)\n{\n    symbian_fd_set *fds = (symbian_fd_set *)fdsetp;\n\n    PJ_ASSERT_ON_FAIL(fds->count < PJ_IOQUEUE_MAX_HANDLES, return);\n    fds->sock[fds->count++] = (CPjSocket*)fd;\n}\n\n\nPJ_DEF(void) PJ_FD_CLR(pj_sock_t fd, pj_fd_set_t *fdsetp)\n{\n    symbian_fd_set *fds = (symbian_fd_set *)fdsetp;\n    unsigned i;\n    \n    for (i=0; i<fds->count; ++i) {\n\tif (fds->sock[i] == (CPjSocket*)fd) {\n\t    pj_array_erase(fds->sock, sizeof(fds->sock[0]), fds->count, i);\n\t    --fds->count;\n\t    return;\n\t}\n    }\n}\n\n\nPJ_DEF(pj_bool_t) PJ_FD_ISSET(pj_sock_t fd, const pj_fd_set_t *fdsetp)\n{\n    symbian_fd_set *fds = (symbian_fd_set *)fdsetp;\n    unsigned i;\n    \n    for (i=0; i<fds->count; ++i) {\n\tif (fds->sock[i] == (CPjSocket*)fd) {\n\t    return PJ_TRUE;\n\t}\n    }\n\n    return PJ_FALSE;\n}\n\nPJ_DEF(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp)\n{\n    symbian_fd_set *fds = (symbian_fd_set *)fdsetp;\n    return fds->count;\n}\n\n\nPJ_DEF(int) pj_sock_select( int n, \n\t\t\t    pj_fd_set_t *readfds, \n\t\t\t    pj_fd_set_t *writefds,\n\t\t\t    pj_fd_set_t *exceptfds, \n\t\t\t    const pj_time_val *timeout)\n{\n    CPjTimeoutTimer *pjTimer;\n    unsigned i;\n\n    PJ_UNUSED_ARG(n);\n    PJ_UNUSED_ARG(writefds);\n    PJ_UNUSED_ARG(exceptfds);\n\n    if (timeout) {\n\tpjTimer = PjSymbianOS::Instance()->SelectTimeoutTimer();\n\tpjTimer->StartTimer(timeout->sec*1000 + timeout->msec);\n\n    } else {\n\tpjTimer = NULL;\n    }\n\n    /* Scan for readable sockets */\n\n    if (readfds) {\n\tsymbian_fd_set *fds = (symbian_fd_set *)readfds;\n\n\tdo {\n\t    /* Scan sockets for readily available data */\n\t    for (i=0; i<fds->count; ++i) {\n\t\tCPjSocket *pjsock = fds->sock[i];\n\n\t\tif (pjsock->Reader()) {\n\t\t    if (pjsock->Reader()->HasData() && !pjsock->Reader()->IsActive()) {\n\n\t\t\t/* Found socket with data ready */\n\t\t\tPJ_FD_ZERO(readfds);\n\t\t\tPJ_FD_SET((pj_sock_t)pjsock, readfds);\n\n\t\t\t/* Cancel timer, if any */\n\t\t\tif (pjTimer) {\n\t\t\t    pjTimer->Cancel();\n\t\t\t}\n\n\t\t\t/* Clear writable and exception fd_set */\n\t\t\tif (writefds)\n\t\t\t    PJ_FD_ZERO(writefds);\n\t\t\tif (exceptfds)\n\t\t\t    PJ_FD_ZERO(exceptfds);\n\n\t\t\treturn 1;\n\n\t\t    } else if (!pjsock->Reader()->IsActive())\n\t\t\tpjsock->Reader()->StartRecvFrom();\n\n\t\t} else {\n\t\t    pjsock->CreateReader();\n\t\t    pjsock->Reader()->StartRecvFrom();\n\t\t}\n\t    }\n\n\t    PjSymbianOS::Instance()->WaitForActiveObjects();\n\n\t} while (pjTimer==NULL || !pjTimer->HasTimedOut());\n    }\n\n\n    /* Timeout */\n\n    if (readfds)\n\tPJ_FD_ZERO(readfds);\n    if (writefds)\n\tPJ_FD_ZERO(writefds);\n    if (exceptfds)\n\tPJ_FD_ZERO(exceptfds);\n\n    return 0;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/sock_symbian.cpp",
    "content": "/* $Id: sock_symbian.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/sock.h>\n#include <pj/addr_resolv.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/os.h>\n#include <pj/string.h>\n#include <pj/unicode.h>\n\n#include \"os_symbian.h\"\n\n\n/*\n * Address families.\n */\nconst pj_uint16_t PJ_AF_UNSPEC\t= KAFUnspec;\nconst pj_uint16_t PJ_AF_UNIX\t= 0xFFFF;\nconst pj_uint16_t PJ_AF_INET\t= KAfInet;\nconst pj_uint16_t PJ_AF_INET6\t= KAfInet6;\nconst pj_uint16_t PJ_AF_PACKET\t= 0xFFFF;\nconst pj_uint16_t PJ_AF_IRDA\t= 0xFFFF;\n\n/*\n * Socket types conversion.\n * The values here are indexed based on pj_sock_type\n */\nconst pj_uint16_t PJ_SOCK_STREAM= KSockStream;\nconst pj_uint16_t PJ_SOCK_DGRAM\t= KSockDatagram;\nconst pj_uint16_t PJ_SOCK_RAW\t= 0xFFFF;\nconst pj_uint16_t PJ_SOCK_RDM\t= 0xFFFF;\n\n/* we don't support setsockopt(), these are just dummy values */\nconst pj_uint16_t PJ_SOL_SOCKET\t= 0xFFFF;\nconst pj_uint16_t PJ_SOL_IP\t= 0xFFFF;\nconst pj_uint16_t PJ_SOL_TCP\t= 0xFFFF;\nconst pj_uint16_t PJ_SOL_UDP\t= 0xFFFF;\nconst pj_uint16_t PJ_SOL_IPV6\t= 0xFFFF;\nconst pj_uint16_t PJ_SO_NOSIGPIPE = 0xFFFF;\n\n/* TOS */\nconst pj_uint16_t PJ_IP_TOS\t\t= 0;\nconst pj_uint16_t PJ_IPTOS_LOWDELAY\t= 0;\nconst pj_uint16_t PJ_IPTOS_THROUGHPUT\t= 0;\nconst pj_uint16_t PJ_IPTOS_RELIABILITY\t= 0;\nconst pj_uint16_t PJ_IPTOS_MINCOST\t= 0;\n\n/* Misc */\nconst pj_uint16_t PJ_TCP_NODELAY = 0xFFFF;\nconst pj_uint16_t PJ_SO_REUSEADDR = 0xFFFF;\nconst pj_uint16_t PJ_SO_PRIORITY = 0xFFFF;\n\n/* ioctl() is also not supported. */\nconst pj_uint16_t PJ_SO_TYPE    = 0xFFFF;\nconst pj_uint16_t PJ_SO_RCVBUF  = 0xFFFF;\nconst pj_uint16_t PJ_SO_SNDBUF  = 0xFFFF;\n\n/* IP multicast is also not supported. */\nconst pj_uint16_t PJ_IP_MULTICAST_IF    = 0xFFFF;\nconst pj_uint16_t PJ_IP_MULTICAST_TTL   = 0xFFFF;\nconst pj_uint16_t PJ_IP_MULTICAST_LOOP  = 0xFFFF;\nconst pj_uint16_t PJ_IP_ADD_MEMBERSHIP  = 0xFFFF;\nconst pj_uint16_t PJ_IP_DROP_MEMBERSHIP = 0xFFFF;\n\n/* Flags */\nconst int PJ_MSG_OOB\t     = 0;\nconst int PJ_MSG_PEEK\t     = KSockReadPeek;\nconst int PJ_MSG_DONTROUTE   = 0;\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// CPjSocket implementation.\n// (declaration is in os_symbian.h)\n//\n\nCPjSocket::~CPjSocket()\n{\n    DestroyReader();\n    sock_.Close();\n}\n\n\n// Create socket reader.\nCPjSocketReader *CPjSocket::CreateReader(unsigned max_len)\n{\n    pj_assert(sockReader_ == NULL);\n    return sockReader_ = CPjSocketReader::NewL(*this, max_len);\n}\n\n// Delete socket reader when it's not wanted.\nvoid CPjSocket::DestroyReader() \n{\n    if (sockReader_) {\n\tsockReader_->Cancel();\n\tdelete sockReader_;\n\tsockReader_ = NULL;\n    }\n}\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// CPjSocketReader implementation\n// (declaration in os_symbian.h)\n//\n\n\nCPjSocketReader::CPjSocketReader(CPjSocket &sock)\n: CActive(EPriorityStandard), \n  sock_(sock), buffer_(NULL, 0), readCb_(NULL), key_(NULL)\n{\n}\n\n\nvoid CPjSocketReader::ConstructL(unsigned max_len)\n{\n    isDatagram_ = sock_.IsDatagram();\n\n    TUint8 *ptr = new TUint8[max_len];\n    buffer_.Set(ptr, 0, (TInt)max_len);\n    CActiveScheduler::Add(this);\n}\n\nCPjSocketReader *CPjSocketReader::NewL(CPjSocket &sock, unsigned max_len)\n{\n    CPjSocketReader *self = new (ELeave) CPjSocketReader(sock);\n    CleanupStack::PushL(self);\n    self->ConstructL(max_len);\n    CleanupStack::Pop(self);\n\n    return self;\n}\n\n\nCPjSocketReader::~CPjSocketReader()\n{\n    const TUint8 *data = buffer_.Ptr();\n    delete [] data;\n}\n\nvoid CPjSocketReader::StartRecv(void (*cb)(void *key), \n\t\t\t        void *key, \n\t\t\t        TDes8 *aDesc,\n\t\t\t        TUint flags)\n{\n    StartRecvFrom(cb, key, aDesc, flags, NULL);\n}\n\nvoid CPjSocketReader::StartRecvFrom(void (*cb)(void *key), \n\t\t\t\t    void *key, \n\t\t\t\t    TDes8 *aDesc,\n\t\t\t\t    TUint flags,\n\t\t\t\t    TSockAddr *fromAddr)\n{\n    readCb_ = cb;\n    key_ = key;\n\n    if (aDesc == NULL) aDesc = &buffer_;\n    if (fromAddr == NULL) fromAddr = &recvAddr_;\n\n    sock_.Socket().RecvFrom(*aDesc, *fromAddr, flags, iStatus);\n    SetActive();\n}\n\nvoid CPjSocketReader::DoCancel()\n{\n    sock_.Socket().CancelRecv();\n}\n\nvoid CPjSocketReader::RunL()\n{\n    void (*old_cb)(void *key) = readCb_;\n    void *old_key = key_;\n\n    readCb_ = NULL;\n    key_ = NULL;\n\n    if (old_cb) {\n\t(*old_cb)(old_key);\n    }\n}\n\n// Append data to aDesc, up to aDesc's maximum size.\n// If socket is datagram based, buffer_ will be clared.\nvoid CPjSocketReader::ReadData(TDes8 &aDesc, TInetAddr *addr)\n{\n    if (isDatagram_)\n\taDesc.Zero();\n\n    if (buffer_.Length() == 0)\n\treturn;\n\n    TInt size_to_copy = aDesc.MaxLength() - aDesc.Length();\n    if (size_to_copy > buffer_.Length())\n\tsize_to_copy = buffer_.Length();\n\n    aDesc.Append(buffer_.Ptr(), size_to_copy);\n\n    if (isDatagram_)\n\tbuffer_.Zero();\n    else\n\tbuffer_.Delete(0, size_to_copy);\n\n    if (addr)\n\t*addr = recvAddr_;\n}\n\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// PJLIB's sock.h implementation\n//\n\n/*\n * Convert 16-bit value from network byte order to host byte order.\n */\nPJ_DEF(pj_uint16_t) pj_ntohs(pj_uint16_t netshort)\n{\n#if PJ_IS_LITTLE_ENDIAN\n    return pj_swap16(netshort);\n#else\n    return netshort;\n#endif\n}\n\n/*\n * Convert 16-bit value from host byte order to network byte order.\n */\nPJ_DEF(pj_uint16_t) pj_htons(pj_uint16_t hostshort)\n{\n#if PJ_IS_LITTLE_ENDIAN\n    return pj_swap16(hostshort);\n#else\n    return hostshort;\n#endif\n}\n\n/*\n * Convert 32-bit value from network byte order to host byte order.\n */\nPJ_DEF(pj_uint32_t) pj_ntohl(pj_uint32_t netlong)\n{\n#if PJ_IS_LITTLE_ENDIAN\n    return pj_swap32(netlong);\n#else\n    return netlong;\n#endif\n}\n\n/*\n * Convert 32-bit value from host byte order to network byte order.\n */\nPJ_DEF(pj_uint32_t) pj_htonl(pj_uint32_t hostlong)\n{\n#if PJ_IS_LITTLE_ENDIAN\n    return pj_swap32(hostlong);\n#else\n    return netlong;\n#endif\n}\n\n/*\n * Convert an Internet host address given in network byte order\n * to string in standard numbers and dots notation.\n */\nPJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)\n{\n\tstatic char str8[PJ_INET_ADDRSTRLEN];\n    TBuf<PJ_INET_ADDRSTRLEN> str16(0);\n\n    /* (Symbian IP address is in host byte order) */\n    TInetAddr temp_addr((TUint32)pj_ntohl(inaddr.s_addr), (TUint)0);\n    temp_addr.Output(str16);\n \n    return pj_unicode_to_ansi((const wchar_t*)str16.PtrZ(), str16.Length(),\n\t\t\t      str8, sizeof(str8));\n}\n\n/*\n * This function converts the Internet host address cp from the standard\n * numbers-and-dots notation into binary data and stores it in the structure\n * that inp points to. \n */\nPJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp)\n{\n    enum { MAXIPLEN = PJ_INET_ADDRSTRLEN };\n\n    /* Initialize output with PJ_INADDR_NONE.\n     * Some apps relies on this instead of the return value\n     * (and anyway the return value is quite confusing!)\n     */\n    inp->s_addr = PJ_INADDR_NONE;\n\n    /* Caution:\n     *\tthis function might be called with cp->slen >= 16\n     *  (i.e. when called with hostname to check if it's an IP addr).\n     */\n    PJ_ASSERT_RETURN(cp && cp->slen && inp, 0);\n    if (cp->slen >= 16) {\n\treturn 0;\n    }\n\n    char tempaddr8[MAXIPLEN];\n    pj_memcpy(tempaddr8, cp->ptr, cp->slen);\n    tempaddr8[cp->slen] = '\\0';\n\n    wchar_t tempaddr16[MAXIPLEN];\n    pj_ansi_to_unicode(tempaddr8, pj_ansi_strlen(tempaddr8),\n\t\t       tempaddr16, sizeof(tempaddr16));\n\n    TBuf<MAXIPLEN> ip_addr((const TText*)tempaddr16);\n\n    TInetAddr addr;\n    addr.Init(KAfInet);\n    if (addr.Input(ip_addr) == KErrNone) {\n\t/* Success (Symbian IP address is in host byte order) */\n\tinp->s_addr = pj_htonl(addr.Address());\n\treturn 1;\n    } else {\n\t/* Error */\n\treturn 0;\n    }\n}\n\n/*\n * Convert text to IPv4/IPv6 address.\n */\nPJ_DEF(pj_status_t) pj_inet_pton(int af, const pj_str_t *src, void *dst)\n{\n    char tempaddr[PJ_INET6_ADDRSTRLEN];\n\n    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EINVAL);\n    PJ_ASSERT_RETURN(src && src->slen && dst, PJ_EINVAL);\n\n    /* Initialize output with PJ_IN_ADDR_NONE for IPv4 (to be \n     * compatible with pj_inet_aton()\n     */\n    if (af==PJ_AF_INET) {\n\t((pj_in_addr*)dst)->s_addr = PJ_INADDR_NONE;\n    }\n\n    /* Caution:\n     *\tthis function might be called with cp->slen >= 46\n     *  (i.e. when called with hostname to check if it's an IP addr).\n     */\n    if (src->slen >= PJ_INET6_ADDRSTRLEN) {\n\treturn PJ_ENAMETOOLONG;\n    }\n\n    pj_memcpy(tempaddr, src->ptr, src->slen);\n    tempaddr[src->slen] = '\\0';\n\n\n    wchar_t tempaddr16[PJ_INET6_ADDRSTRLEN];\n    pj_ansi_to_unicode(tempaddr, pj_ansi_strlen(tempaddr),\n\t\t       tempaddr16, sizeof(tempaddr16));\n\n    TBuf<PJ_INET6_ADDRSTRLEN> ip_addr((const TText*)tempaddr16);\n\n    TInetAddr addr;\n    addr.Init(KAfInet6);\n    if (addr.Input(ip_addr) == KErrNone) {\n\tif (af==PJ_AF_INET) {\n\t    /* Success (Symbian IP address is in host byte order) */\n\t    pj_uint32_t ip = pj_htonl(addr.Address());\n\t    pj_memcpy(dst, &ip, 4);\n\t} else if (af==PJ_AF_INET6) {\n\t    const TIp6Addr & ip6 = addr.Ip6Address();\n\t    pj_memcpy(dst, ip6.u.iAddr8, 16);\n\t} else {\n\t    pj_assert(!\"Unexpected!\");\n\t    return PJ_EBUG;\n\t}\n\treturn PJ_SUCCESS;\n    } else {\n\t/* Error */\n\treturn PJ_EINVAL;\n    }\n}\n\n/*\n * Convert IPv4/IPv6 address to text.\n */\nPJ_DEF(pj_status_t) pj_inet_ntop(int af, const void *src,\n\t\t\t\t char *dst, int size)\n\n{\n    PJ_ASSERT_RETURN(src && dst && size, PJ_EINVAL);\n\n    *dst = '\\0';\n\n    if (af==PJ_AF_INET) {\n\n\tTBuf<PJ_INET_ADDRSTRLEN> str16;\n\tpj_in_addr inaddr;\n\n\tif (size < PJ_INET_ADDRSTRLEN)\n\t    return PJ_ETOOSMALL;\n\n\tpj_memcpy(&inaddr, src, 4);\n\n\t/* Symbian IP address is in host byte order */\n\tTInetAddr temp_addr((TUint32)pj_ntohl(inaddr.s_addr), (TUint)0);\n\ttemp_addr.Output(str16);\n \n\tpj_unicode_to_ansi((const wchar_t*)str16.PtrZ(), str16.Length(),\n\t\t\t   dst, size);\n\treturn PJ_SUCCESS;\n\n    } else if (af==PJ_AF_INET6) {\n\tTBuf<PJ_INET6_ADDRSTRLEN> str16;\n\n\tif (size < PJ_INET6_ADDRSTRLEN)\n\t    return PJ_ETOOSMALL;\n\n\tTIp6Addr ip6;\n\tpj_memcpy(ip6.u.iAddr8, src, 16);\n\n\tTInetAddr temp_addr(ip6, (TUint)0);\n\ttemp_addr.Output(str16);\n \n\tpj_unicode_to_ansi((const wchar_t*)str16.PtrZ(), str16.Length(),\n\t\t\t   dst, size);\n\treturn PJ_SUCCESS;\n\n    } else {\n\tpj_assert(!\"Unsupport address family\");\n\treturn PJ_EINVAL;\n    }\n\n}\n\n/*\n * Get hostname.\n */\nPJ_DEF(const pj_str_t*) pj_gethostname(void)\n{\n    static char buf[PJ_MAX_HOSTNAME];\n    static pj_str_t hostname;\n\n    PJ_CHECK_STACK();\n\n    if (hostname.ptr == NULL) {\n\tRHostResolver &resv = PjSymbianOS::Instance()->GetResolver(PJ_AF_INET);\n\tTRequestStatus reqStatus;\n\tTHostName tmpName;\n\n\t// Return empty hostname if access point is marked as down by app.\n\tPJ_SYMBIAN_CHECK_CONNECTION2(&hostname);\n\n\tresv.GetHostName(tmpName, reqStatus);\n\tUser::WaitForRequest(reqStatus);\n\n\thostname.ptr = pj_unicode_to_ansi((const wchar_t*)tmpName.Ptr(), tmpName.Length(),\n\t\t\t\t\t  buf, sizeof(buf));\n\thostname.slen = tmpName.Length();\n    }\n    return &hostname;\n}\n\n/*\n * Create new socket/endpoint for communication and returns a descriptor.\n */\nPJ_DEF(pj_status_t) pj_sock_socket(int af, \n\t\t\t\t   int type, \n\t\t\t\t   int proto,\n\t\t\t\t   pj_sock_t *p_sock)\n{\n    TInt rc;\n\n    PJ_CHECK_STACK();\n\n    /* Sanity checks. */\n    PJ_ASSERT_RETURN(p_sock!=NULL, PJ_EINVAL);\n\n    // Return failure if access point is marked as down by app.\n    PJ_SYMBIAN_CHECK_CONNECTION();\n    \n    /* Set proto if none is specified. */\n    if (proto == 0) {\n\tif (type == pj_SOCK_STREAM())\n\t    proto = KProtocolInetTcp;\n\telse if (type == pj_SOCK_DGRAM())\n\t    proto = KProtocolInetUdp;\n    }\n\n    /* Create Symbian RSocket */\n    RSocket rSock;\n    if (PjSymbianOS::Instance()->Connection())\n    \trc = rSock.Open(PjSymbianOS::Instance()->SocketServ(), \n    \t\t\taf, type, proto,\n    \t\t\t*PjSymbianOS::Instance()->Connection());\n    else\n    \trc = rSock.Open(PjSymbianOS::Instance()->SocketServ(), \n    \t\t\taf, type, proto);\n        \n    if (rc != KErrNone)\n\treturn PJ_RETURN_OS_ERROR(rc);\n\n\n    /* Wrap Symbian RSocket into PJLIB's CPjSocket, and return to caller */\n    CPjSocket *pjSock = new CPjSocket(af, type, rSock);\n    *p_sock = (pj_sock_t)pjSock;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Bind socket.\n */\nPJ_DEF(pj_status_t) pj_sock_bind( pj_sock_t sock, \n\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t  int len)\n{\n    pj_status_t status;\n    TInt rc;\n\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(sock != 0, PJ_EINVAL);\n    PJ_ASSERT_RETURN(addr && len>=(int)sizeof(pj_sockaddr_in), PJ_EINVAL);\n\n    // Convert PJLIB's pj_sockaddr into Symbian's TInetAddr\n    TInetAddr inetAddr;\n    status = PjSymbianOS::pj2Addr(*(pj_sockaddr*)addr, len, inetAddr);\n    if (status != PJ_SUCCESS)\n    \treturn status;\n\n    // Get the RSocket instance\n    RSocket &rSock = ((CPjSocket*)sock)->Socket();\n\n    // Bind\n    rc = rSock.Bind(inetAddr);\n\n    return (rc==KErrNone) ? PJ_SUCCESS : PJ_RETURN_OS_ERROR(rc);\n}\n\n\n/*\n * Bind socket.\n */\nPJ_DEF(pj_status_t) pj_sock_bind_in( pj_sock_t sock, \n\t\t\t\t     pj_uint32_t addr32,\n\t\t\t\t     pj_uint16_t port)\n{\n    pj_sockaddr_in addr;\n\n    PJ_CHECK_STACK();\n\n    pj_bzero(&addr, sizeof(addr));\n    addr.sin_family = PJ_AF_INET;\n    addr.sin_addr.s_addr = pj_htonl(addr32);\n    addr.sin_port = pj_htons(port);\n\n    return pj_sock_bind(sock, &addr, sizeof(pj_sockaddr_in));\n}\n\n\n/*\n * Close socket.\n */\nPJ_DEF(pj_status_t) pj_sock_close(pj_sock_t sock)\n{\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(sock != 0, PJ_EINVAL);\n\n    CPjSocket *pjSock = (CPjSocket*)sock;\n\n    // This will close the socket.\n    delete pjSock;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get remote's name.\n */\nPJ_DEF(pj_status_t) pj_sock_getpeername( pj_sock_t sock,\n\t\t\t\t\t pj_sockaddr_t *addr,\n\t\t\t\t\t int *namelen)\n{\n    PJ_CHECK_STACK();\n    \n    PJ_ASSERT_RETURN(sock && addr && namelen && \n\t\t     *namelen>=(int)sizeof(pj_sockaddr_in), PJ_EINVAL);\n\n    CPjSocket *pjSock = (CPjSocket*)sock;\n    RSocket &rSock = pjSock->Socket();\n\n    // Socket must be connected.\n    PJ_ASSERT_RETURN(pjSock->IsConnected(), PJ_EINVALIDOP);\n\n    TInetAddr inetAddr;\n    rSock.RemoteName(inetAddr);\n\n    return PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr*)addr, namelen);\n}\n\n/*\n * Get socket name.\n */\nPJ_DEF(pj_status_t) pj_sock_getsockname( pj_sock_t sock,\n\t\t\t\t\t pj_sockaddr_t *addr,\n\t\t\t\t\t int *namelen)\n{\n    PJ_CHECK_STACK();\n    \n    PJ_ASSERT_RETURN(sock && addr && namelen && \n\t\t     *namelen>=(int)sizeof(pj_sockaddr_in), PJ_EINVAL);\n\n    CPjSocket *pjSock = (CPjSocket*)sock;\n    RSocket &rSock = pjSock->Socket();\n\n    TInetAddr inetAddr;\n    rSock.LocalName(inetAddr);\n\n    return PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr*)addr, namelen);\n}\n\n/*\n * Send data\n */\nPJ_DEF(pj_status_t) pj_sock_send(pj_sock_t sock,\n\t\t\t\t const void *buf,\n\t\t\t\t pj_ssize_t *len,\n\t\t\t\t unsigned flags)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(sock && buf && len, PJ_EINVAL);\n\n    // Return failure if access point is marked as down by app.\n    PJ_SYMBIAN_CHECK_CONNECTION();\n    \n    CPjSocket *pjSock = (CPjSocket*)sock;\n    RSocket &rSock = pjSock->Socket();\n\n    // send() should only be called to connected socket\n    PJ_ASSERT_RETURN(pjSock->IsConnected(), PJ_EINVALIDOP);\n\n    TPtrC8 data((const TUint8*)buf, (TInt)*len);\n    TRequestStatus reqStatus;\n    TSockXfrLength sentLen;\n\n    rSock.Send(data, flags, reqStatus, sentLen);\n    User::WaitForRequest(reqStatus);\n\n    if (reqStatus.Int()==KErrNone) {\n\t//*len = (TInt) sentLen.Length();\n\treturn PJ_SUCCESS;\n    } else\n\treturn PJ_RETURN_OS_ERROR(reqStatus.Int());\n}\n\n\n/*\n * Send data.\n */\nPJ_DEF(pj_status_t) pj_sock_sendto(pj_sock_t sock,\n\t\t\t\t   const void *buf,\n\t\t\t\t   pj_ssize_t *len,\n\t\t\t\t   unsigned flags,\n\t\t\t\t   const pj_sockaddr_t *to,\n\t\t\t\t   int tolen)\n{\n    pj_status_t status;\n    \n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(sock && buf && len, PJ_EINVAL);\n\n    // Return failure if access point is marked as down by app.\n    PJ_SYMBIAN_CHECK_CONNECTION();\n    \n    CPjSocket *pjSock = (CPjSocket*)sock;\n    RSocket &rSock = pjSock->Socket();\n\n    // Only supports AF_INET for now\n    PJ_ASSERT_RETURN(tolen>=(int)sizeof(pj_sockaddr_in), PJ_EINVAL);\n\n    TInetAddr inetAddr;\n    status = PjSymbianOS::pj2Addr(*(pj_sockaddr*)to, tolen, inetAddr);\n    if (status != PJ_SUCCESS)\n    \treturn status;\n\n    TPtrC8 data((const TUint8*)buf, (TInt)*len);\n    TRequestStatus reqStatus;\n    TSockXfrLength sentLen;\n\n    rSock.SendTo(data, inetAddr, flags, reqStatus, sentLen);\n    User::WaitForRequest(reqStatus);\n\n    if (reqStatus.Int()==KErrNone) {\n\t//For some reason TSockXfrLength is not returning correctly!\n\t//*len = (TInt) sentLen.Length();\n\treturn PJ_SUCCESS;\n    } else \n\treturn PJ_RETURN_OS_ERROR(reqStatus.Int());\n}\n\n/*\n * Receive data.\n */\nPJ_DEF(pj_status_t) pj_sock_recv(pj_sock_t sock,\n\t\t\t\t void *buf,\n\t\t\t\t pj_ssize_t *len,\n\t\t\t\t unsigned flags)\n{\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(sock && buf && len, PJ_EINVAL);\n    PJ_ASSERT_RETURN(*len > 0, PJ_EINVAL);\n\n    // Return failure if access point is marked as down by app.\n    PJ_SYMBIAN_CHECK_CONNECTION();\n\n    CPjSocket *pjSock = (CPjSocket*)sock;\n\n    if (pjSock->Reader()) {\n\tCPjSocketReader *reader = pjSock->Reader();\n\n\twhile (reader->IsActive() && !reader->HasData()) {\n\t    User::WaitForAnyRequest();\n\t}\n\n\tif (reader->HasData()) {\n\t    TPtr8 data((TUint8*)buf, (TInt)*len);\n\t    TInetAddr inetAddr;\n\n\t    reader->ReadData(data, &inetAddr);\n\n\t    *len = data.Length();\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    TRequestStatus reqStatus;\n    TSockXfrLength recvLen;\n    TPtr8 data((TUint8*)buf, (TInt)*len, (TInt)*len);\n\n    if (pjSock->IsDatagram()) {\n\tpjSock->Socket().Recv(data, flags, reqStatus);\n    } else {\n\t// Using static like this is not pretty, but we don't need to use\n\t// the value anyway, hence doing it like this is probably most\n\t// optimal.\n\tstatic TSockXfrLength len;\n\tpjSock->Socket().RecvOneOrMore(data, flags, reqStatus, len);\n    }\n    User::WaitForRequest(reqStatus);\n\n    if (reqStatus == KErrNone) {\n\t//*len = (TInt)recvLen.Length();\n\t*len = data.Length();\n\treturn PJ_SUCCESS;\n    } else {\n\t*len = -1;\n\treturn PJ_RETURN_OS_ERROR(reqStatus.Int());\n    }\n}\n\n/*\n * Receive data.\n */\nPJ_DEF(pj_status_t) pj_sock_recvfrom(pj_sock_t sock,\n\t\t\t\t     void *buf,\n\t\t\t\t     pj_ssize_t *len,\n\t\t\t\t     unsigned flags,\n\t\t\t\t     pj_sockaddr_t *from,\n\t\t\t\t     int *fromlen)\n{\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(sock && buf && len && from && fromlen, PJ_EINVAL);\n    PJ_ASSERT_RETURN(*len > 0, PJ_EINVAL);\n    PJ_ASSERT_RETURN(*fromlen >= (int)sizeof(pj_sockaddr_in), PJ_EINVAL);\n\n    // Return failure if access point is marked as down by app.\n    PJ_SYMBIAN_CHECK_CONNECTION();\n\n    CPjSocket *pjSock = (CPjSocket*)sock;\n    RSocket &rSock = pjSock->Socket();\n\n    if (pjSock->Reader()) {\n\tCPjSocketReader *reader = pjSock->Reader();\n\n\twhile (reader->IsActive() && !reader->HasData()) {\n\t    User::WaitForAnyRequest();\n\t}\n\n\tif (reader->HasData()) {\n\t    TPtr8 data((TUint8*)buf, (TInt)*len);\n\t    TInetAddr inetAddr;\n\n\t    reader->ReadData(data, &inetAddr);\n\n\t    *len = data.Length();\n\n\t    if (from && fromlen) {\n\t\treturn PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr*)from, \n\t\t\t\t\t    fromlen);\n\t    } else {\n\t    \treturn PJ_SUCCESS;\n\t    }\n\t}\n    }\n\n    TInetAddr inetAddr;\n    TRequestStatus reqStatus;\n    TSockXfrLength recvLen;\n    TPtr8 data((TUint8*)buf, (TInt)*len, (TInt)*len);\n\n    rSock.RecvFrom(data, inetAddr, flags, reqStatus, recvLen);\n    User::WaitForRequest(reqStatus);\n\n    if (reqStatus == KErrNone) {\n\t//*len = (TInt)recvLen.Length();\n\t*len = data.Length();\n\treturn PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr*)from, fromlen);\n    } else {\n\t*len = -1;\n\t*fromlen = -1;\n\treturn PJ_RETURN_OS_ERROR(reqStatus.Int());\n    }\n}\n\n/*\n * Get socket option.\n */\nPJ_DEF(pj_status_t) pj_sock_getsockopt( pj_sock_t sock,\n\t\t\t\t\tpj_uint16_t level,\n\t\t\t\t\tpj_uint16_t optname,\n\t\t\t\t\tvoid *optval,\n\t\t\t\t\tint *optlen)\n{\n    // Not supported for now.\n    PJ_UNUSED_ARG(sock);\n    PJ_UNUSED_ARG(level);\n    PJ_UNUSED_ARG(optname);\n    PJ_UNUSED_ARG(optval);\n    PJ_UNUSED_ARG(optlen);\n    return PJ_EINVALIDOP;\n}\n\n/*\n * Set socket option.\n */\nPJ_DEF(pj_status_t) pj_sock_setsockopt( pj_sock_t sock,\n\t\t\t\t\tpj_uint16_t level,\n\t\t\t\t\tpj_uint16_t optname,\n\t\t\t\t\tconst void *optval,\n\t\t\t\t\tint optlen)\n{\n    // Not supported for now.\n    PJ_UNUSED_ARG(sock);\n    PJ_UNUSED_ARG(level);\n    PJ_UNUSED_ARG(optname);\n    PJ_UNUSED_ARG(optval);\n    PJ_UNUSED_ARG(optlen);\n    return PJ_EINVALIDOP;\n}\n\n/*\n * Connect socket.\n */\nPJ_DEF(pj_status_t) pj_sock_connect( pj_sock_t sock,\n\t\t\t\t     const pj_sockaddr_t *addr,\n\t\t\t\t     int namelen)\n{\n    pj_status_t status;\n    \n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(sock && addr && namelen, PJ_EINVAL);\n    PJ_ASSERT_RETURN(((pj_sockaddr*)addr)->addr.sa_family == PJ_AF_INET, \n\t\t     PJ_EINVAL);\n\n    // Return failure if access point is marked as down by app.\n    PJ_SYMBIAN_CHECK_CONNECTION();\n    \n    CPjSocket *pjSock = (CPjSocket*)sock;\n    RSocket &rSock = pjSock->Socket();\n\n    TInetAddr inetAddr;\n    TRequestStatus reqStatus;\n\n    status = PjSymbianOS::pj2Addr(*(pj_sockaddr*)addr, namelen, inetAddr);\n    if (status != PJ_SUCCESS)\n    \treturn status;\n\n    rSock.Connect(inetAddr, reqStatus);\n    User::WaitForRequest(reqStatus);\n\n    if (reqStatus == KErrNone) {\n\tpjSock->SetConnected(true);\n\treturn PJ_SUCCESS;\n    } else {\n\treturn PJ_RETURN_OS_ERROR(reqStatus.Int());\n    }\n}\n\n\n/*\n * Shutdown socket.\n */\n#if PJ_HAS_TCP\nPJ_DEF(pj_status_t) pj_sock_shutdown( pj_sock_t sock,\n\t\t\t\t      int how)\n{\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(sock, PJ_EINVAL);\n\n    CPjSocket *pjSock = (CPjSocket*)sock;\n    RSocket &rSock = pjSock->Socket();\n\n    RSocket::TShutdown aHow;\n    if (how == PJ_SD_RECEIVE)\n\taHow = RSocket::EStopInput;\n    else if (how == PJ_SHUT_WR)\n\taHow = RSocket::EStopOutput;\n    else\n\taHow = RSocket::ENormal;\n\n    TRequestStatus reqStatus;\n\n    rSock.Shutdown(aHow, reqStatus);\n    User::WaitForRequest(reqStatus);\n\n    if (reqStatus == KErrNone) {\n\treturn PJ_SUCCESS;\n    } else {\n\treturn PJ_RETURN_OS_ERROR(reqStatus.Int());\n    }\n}\n\n/*\n * Start listening to incoming connections.\n */\nPJ_DEF(pj_status_t) pj_sock_listen( pj_sock_t sock,\n\t\t\t\t    int backlog)\n{\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(sock && backlog, PJ_EINVAL);\n\n    CPjSocket *pjSock = (CPjSocket*)sock;\n    RSocket &rSock = pjSock->Socket();\n\n    TInt rc = rSock.Listen((TUint)backlog);\n\n    if (rc == KErrNone) {\n\treturn PJ_SUCCESS;\n    } else {\n\treturn PJ_RETURN_OS_ERROR(rc);\n    }\n}\n\n/*\n * Accept incoming connections\n */\nPJ_DEF(pj_status_t) pj_sock_accept( pj_sock_t serverfd,\n\t\t\t\t    pj_sock_t *newsock,\n\t\t\t\t    pj_sockaddr_t *addr,\n\t\t\t\t    int *addrlen)\n{\n    PJ_CHECK_STACK();\n\n    PJ_ASSERT_RETURN(serverfd && newsock, PJ_EINVAL);\n\n    CPjSocket *pjSock = (CPjSocket*)serverfd;\n    RSocket &rSock = pjSock->Socket();\n\n    // Create a 'blank' socket\n    RSocket newSock;\n    newSock.Open(PjSymbianOS::Instance()->SocketServ());\n\n    // Call Accept()\n    TRequestStatus reqStatus;\n\n    rSock.Accept(newSock, reqStatus);\n    User::WaitForRequest(reqStatus);\n\n    if (reqStatus != KErrNone) {\n\treturn PJ_RETURN_OS_ERROR(reqStatus.Int());\n    }\n\n    // Create PJ socket\n    CPjSocket *newPjSock = new CPjSocket(pjSock->GetAf(), pjSock->GetSockType(),\n\t\t\t\t\t newSock);\n    newPjSock->SetConnected(true);\n\n    *newsock = (pj_sock_t) newPjSock;\n\n    if (addr && addrlen) {\n\treturn pj_sock_getpeername(*newsock, addr, addrlen);\n    }\n\n    return PJ_SUCCESS;\n}\n#endif\t/* PJ_HAS_TCP */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ssl_sock_common.c",
    "content": "/* $Id: ssl_sock_common.c 3999 2012-03-30 07:10:13Z bennylp $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/ssl_sock.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n/*\n * Initialize the SSL socket configuration with the default values.\n */\nPJ_DEF(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param)\n{\n    pj_bzero(param, sizeof(*param));\n\n    /* Socket config */\n    param->sock_af = PJ_AF_INET;\n    param->sock_type = pj_SOCK_STREAM();\n    param->async_cnt = 1;\n    param->concurrency = -1;\n    param->whole_data = PJ_TRUE;\n    param->send_buffer_size = 8192;\n#if !defined(PJ_SYMBIAN) || PJ_SYMBIAN==0\n    param->read_buffer_size = 1500;\n#endif\n    param->qos_type = PJ_QOS_TYPE_BEST_EFFORT;\n    param->qos_ignore_error = PJ_TRUE;\n\n    param->sockopt_ignore_error = PJ_TRUE;\n\n    /* Security config */\n    param->proto = PJ_SSL_SOCK_PROTO_DEFAULT;\n}\n\n\n/*\n * Duplicate SSL socket parameter.\n */\nPJ_DEF(void) pj_ssl_sock_param_copy( pj_pool_t *pool, \n\t\t\t\t     pj_ssl_sock_param *dst,\n\t\t\t\t     const pj_ssl_sock_param *src)\n{\n    /* Init secure socket param */\n    pj_memcpy(dst, src, sizeof(*dst));\n    if (src->ciphers_num > 0) {\n\tunsigned i;\n\tdst->ciphers = (pj_ssl_cipher*)\n\t\t\tpj_pool_calloc(pool, src->ciphers_num, \n\t\t\t\t       sizeof(pj_ssl_cipher));\n\tfor (i = 0; i < src->ciphers_num; ++i)\n\t    dst->ciphers[i] = src->ciphers[i];\n    }\n\n    if (src->server_name.slen) {\n        /* Server name must be null-terminated */\n        pj_strdup_with_null(pool, &dst->server_name, &src->server_name);\n    }\n}\n\n\nPJ_DEF(pj_status_t) pj_ssl_cert_get_verify_status_strings(\n\t\t\t\t\t\tpj_uint32_t verify_status, \n\t\t\t\t\t\tconst char *error_strings[],\n\t\t\t\t\t\tunsigned *count)\n{\n    unsigned i = 0, shift_idx = 0;\n    unsigned unknown = 0;\n    pj_uint32_t errs;\n\n    PJ_ASSERT_RETURN(error_strings && count, PJ_EINVAL);\n\n    if (verify_status == PJ_SSL_CERT_ESUCCESS && *count) {\n\terror_strings[0] = \"OK\";\n\t*count = 1;\n\treturn PJ_SUCCESS;\n    }\n\n    errs = verify_status;\n\n    while (errs && i < *count) {\n\tpj_uint32_t err;\n\tconst char *p = NULL;\n\n\tif ((errs & 1) == 0) {\n\t    shift_idx++;\n\t    errs >>= 1;\n\t    continue;\n\t}\n\n\terr = (1 << shift_idx);\n\n\tswitch (err) {\n\tcase PJ_SSL_CERT_EISSUER_NOT_FOUND:\n\t    p = \"The issuer certificate cannot be found\";\n\t    break;\n\tcase PJ_SSL_CERT_EUNTRUSTED:\n\t    p = \"The certificate is untrusted\";\n\t    break;\n\tcase PJ_SSL_CERT_EVALIDITY_PERIOD:\n\t    p = \"The certificate has expired or not yet valid\";\n\t    break;\n\tcase PJ_SSL_CERT_EINVALID_FORMAT:\n\t    p = \"One or more fields of the certificate cannot be decoded \"\n\t\t\"due to invalid format\";\n\t    break;\n\tcase PJ_SSL_CERT_EISSUER_MISMATCH:\n\t    p = \"The issuer info in the certificate does not match to the \"\n\t\t\"(candidate) issuer certificate\";\n\t    break;\n\tcase PJ_SSL_CERT_ECRL_FAILURE:\n\t    p = \"The CRL certificate cannot be found or cannot be read \"\n\t\t\"properly\";\n\t    break;\n\tcase PJ_SSL_CERT_EREVOKED:\n\t    p = \"The certificate has been revoked\";\n\t    break;\n\tcase PJ_SSL_CERT_EINVALID_PURPOSE:\n\t    p = \"The certificate or CA certificate cannot be used for the \"\n\t\t\"specified purpose\";\n\t    break;\n\tcase PJ_SSL_CERT_ECHAIN_TOO_LONG:\n\t    p = \"The certificate chain length is too long\";\n\t    break;\n\tcase PJ_SSL_CERT_EIDENTITY_NOT_MATCH:\n\t    p = \"The server identity does not match to any identities \"\n\t\t\"specified in the certificate\";\n\t    break;\n\tcase PJ_SSL_CERT_EUNKNOWN:\n\tdefault:\n\t    unknown++;\n\t    break;\n\t}\n\t\n\t/* Set error string */\n\tif (p)\n\t    error_strings[i++] = p;\n\n\t/* Next */\n\tshift_idx++;\n\terrs >>= 1;\n    }\n\n    /* Unknown error */\n    if (unknown && i < *count)\n\terror_strings[i++] = \"Unknown verification error\";\n\n    *count = i;\n\n    return PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ssl_sock_dump.c",
    "content": "/* $Id: ssl_sock_dump.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/ssl_sock.h>\n#include <pj/errno.h>\n#include <pj/os.h>\n#include <pj/string.h>\n\n\n/* Only build when PJ_HAS_SSL_SOCK is enabled */\n#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK!=0\n\n#define THIS_FILE\t\"ssl_sock_dump.c\"\n\n#define CHECK_BUF_LEN()\t\t\t\t\t\t\\\n    if ((len < 0) || (len >= end-p)) {\t\t\t\t\\\n\t*p = '\\0';\t\t\t\t\t\t\\\n\treturn -1;\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\\\n    p += len;\n\nPJ_DEF(pj_ssize_t) pj_ssl_cert_info_dump(const pj_ssl_cert_info *ci,\n\t\t\t\t\t const char *indent,\n\t\t\t\t\t char *buf,\n\t\t\t\t\t pj_size_t buf_size)\n{\n    const char *wdays[] = {\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"};\n    pj_parsed_time pt1;\n    pj_parsed_time pt2;\n    unsigned i;\n    int len = 0;\n    char *p, *end;\n\n    p = buf;\n    end = buf + buf_size;\n\n    pj_time_decode(&ci->validity.start, &pt1);\n    pj_time_decode(&ci->validity.end, &pt2);\n\n    /* Version */\n    len = pj_ansi_snprintf(p, end-p, \"%sVersion    : v%d\\n\", \n\t\t\t   indent, ci->version);\n    CHECK_BUF_LEN();\n    \n    /* Serial number */\n    len = pj_ansi_snprintf(p, end-p, \"%sSerial     : \", indent);\n    CHECK_BUF_LEN();\n\n    for (i = 0; i < sizeof(ci->serial_no) && !ci->serial_no[i]; ++i);\n    for (; i < sizeof(ci->serial_no); ++i) {\n\tlen = pj_ansi_snprintf(p, end-p, \"%02X \", ci->serial_no[i] & 0xFF);\n\tCHECK_BUF_LEN();\n    }\n    *(p-1) = '\\n';\n    \n    /* Subject */\n    len = pj_ansi_snprintf( p, end-p, \"%sSubject    : %.*s\\n\", indent,\n\t\t\t    (int)ci->subject.cn.slen,\n\t\t\t    ci->subject.cn.ptr);\n    CHECK_BUF_LEN();\n    len = pj_ansi_snprintf( p, end-p, \"%s             %.*s\\n\", indent,\n\t\t\t    (int)ci->subject.info.slen,\n\t\t\t    ci->subject.info.ptr);\n    CHECK_BUF_LEN();\n\n    /* Issuer */\n    len = pj_ansi_snprintf( p, end-p, \"%sIssuer     : %.*s\\n\", indent,\n\t\t\t    (int)ci->issuer.cn.slen,\n\t\t\t    ci->issuer.cn.ptr);\n    CHECK_BUF_LEN();\n    len = pj_ansi_snprintf( p, end-p, \"%s             %.*s\\n\", indent,\n\t\t\t    (int)ci->issuer.info.slen,\n\t\t\t    ci->issuer.info.ptr);\n    CHECK_BUF_LEN();\n\n    /* Validity period */\n    len = pj_ansi_snprintf( p, end-p, \"%sValid from : %s %4d-%02d-%02d \"\n\t\t\t    \"%02d:%02d:%02d.%03d %s\\n\", indent,\n\t\t\t    wdays[pt1.wday], pt1.year, pt1.mon+1, pt1.day,\n\t\t\t    pt1.hour, pt1.min, pt1.sec, pt1.msec,\n\t\t\t    (ci->validity.gmt? \"GMT\":\"\"));\n    CHECK_BUF_LEN();\n\n    len = pj_ansi_snprintf( p, end-p, \"%sValid to   : %s %4d-%02d-%02d \"\n\t\t\t    \"%02d:%02d:%02d.%03d %s\\n\", indent,\n\t\t\t    wdays[pt2.wday], pt2.year, pt2.mon+1, pt2.day,\n\t\t\t    pt2.hour, pt2.min, pt2.sec, pt2.msec,\n\t\t\t    (ci->validity.gmt? \"GMT\":\"\"));\n    CHECK_BUF_LEN();\n\n    /* Subject alternative name extension */\n    if (ci->subj_alt_name.cnt) {\n\tunsigned i;\n\n\tlen = pj_ansi_snprintf(p, end-p, \"%ssubjectAltName extension\\n\", \n\t\t\t       indent);\n\tCHECK_BUF_LEN();\n\n\tfor (i = 0; i < ci->subj_alt_name.cnt; ++i) {\n\t    const char *type = NULL;\n\n\t    switch(ci->subj_alt_name.entry[i].type) {\n\t    case PJ_SSL_CERT_NAME_RFC822:\n\t\ttype = \"MAIL\";\n\t\tbreak;\n\t    case PJ_SSL_CERT_NAME_DNS:\n\t\ttype = \" DNS\";\n\t\tbreak;\n\t    case PJ_SSL_CERT_NAME_URI:\n\t\ttype = \" URI\";\n\t\tbreak;\n\t    case PJ_SSL_CERT_NAME_IP:\n\t\ttype = \"  IP\";\n\t\tbreak;\n\t    default:\n\t\tbreak;\n\t    }\n\t    if (type) {\n\t\tlen = pj_ansi_snprintf( p, end-p, \"%s      %s : %.*s\\n\", indent, \n\t\t\t\t\ttype, \n\t\t\t\t\t(int)ci->subj_alt_name.entry[i].name.slen,\n\t\t\t\t\tci->subj_alt_name.entry[i].name.ptr);\n\t\tCHECK_BUF_LEN();\n\t    }\n\t}\n    }\n\n    return (p-buf);\n}\n\n\n#endif  /* PJ_HAS_SSL_SOCK */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ssl_sock_ossl.c",
    "content": "/* $Id: ssl_sock_ossl.c 4506 2013-04-26 06:01:43Z bennylp $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/ssl_sock.h>\n#include <pj/activesock.h>\n#include <pj/compat/socket.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/file_access.h>\n#include <pj/list.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/math.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/timer.h>\n\n\n/* Only build when PJ_HAS_SSL_SOCK is enabled */\n#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK!=0\n\n#define THIS_FILE\t\t\"ssl_sock_ossl.c\"\n\n/* Workaround for ticket #985 */\n#define DELAYED_CLOSE_TIMEOUT\t200\n\n/* \n * Include OpenSSL headers \n */\n#include <openssl/asn1.h>\n#include <openssl/bio.h>\n#include <openssl/ssl.h>\n#include <openssl/err.h>\n#include <openssl/x509v3.h>\n\n\n#if !USING_LIBRESSL && OPENSSL_VERSION_NUMBER >= 0x10100000L\n#  define OPENSSL_NO_SSL2\t    /* seems to be removed in 1.1.0 */\n#  define M_ASN1_STRING_data(x)\t    ASN1_STRING_get0_data(x)\n#  define M_ASN1_STRING_length(x)   ASN1_STRING_length(x)\n#  if defined(OPENSSL_API_COMPAT) && OPENSSL_API_COMPAT >= 0x10100000L\n#     define X509_get_notBefore(x)  X509_get0_notBefore(x)\n#     define X509_get_notAfter(x)   X509_get0_notAfter(x)\n#  endif\n#else\n#  define SSL_CIPHER_get_id(c)\t    (c)->id\n#  define SSL_set_session(ssl, s)   (ssl)->session = (s)\n#endif\n\n\n#ifdef _MSC_VER\n#  pragma comment( lib, \"libeay32\")\n#  pragma comment( lib, \"ssleay32\")\n#  pragma comment( lib, \"crypt32\")\n#endif\n\n\n/* Suppress compile warning of OpenSSL deprecation (OpenSSL is deprecated\n * since MacOSX 10.7).\n */\n#if defined(PJ_DARWINOS) && PJ_DARWINOS==1\n#  pragma GCC diagnostic push\n#  pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n#endif\n\n\n/*\n * SSL/TLS state enumeration.\n */\nenum ssl_state {\n    SSL_STATE_NULL,\n    SSL_STATE_HANDSHAKING,\n    SSL_STATE_ESTABLISHED\n};\n\n/*\n * Internal timer types.\n */\nenum timer_id\n{\n    TIMER_NONE,\n    TIMER_HANDSHAKE_TIMEOUT,\n    TIMER_CLOSE\n};\n\n/*\n * Structure of SSL socket read buffer.\n */\ntypedef struct read_data_t\n{\n    void\t\t *data;\n    pj_size_t\t\t  len;\n} read_data_t;\n\n/*\n * Get the offset of pointer to read-buffer of SSL socket from read-buffer\n * of active socket. Note that both SSL socket and active socket employ \n * different but correlated read-buffers (as much as async_cnt for each),\n * and to make it easier/faster to find corresponding SSL socket's read-buffer\n * from known active socket's read-buffer, the pointer of corresponding \n * SSL socket's read-buffer is stored right after the end of active socket's\n * read-buffer.\n */\n#define OFFSET_OF_READ_DATA_PTR(ssock, asock_rbuf) \\\n\t\t\t\t\t(read_data_t**) \\\n\t\t\t\t\t((pj_int8_t*)(asock_rbuf) + \\\n\t\t\t\t\tssock->param.read_buffer_size)\n\n/*\n * Structure of SSL socket write data.\n */\ntypedef struct write_data_t {\n    PJ_DECL_LIST_MEMBER(struct write_data_t);\n    pj_ioqueue_op_key_t\t key;\n    pj_size_t \t \t record_len;\n    pj_ioqueue_op_key_t\t*app_key;\n    pj_size_t \t \t plain_data_len;\n    pj_size_t \t \t data_len;\n    unsigned\t\t flags;\n    union {\n\tchar\t\t content[1];\n\tconst char\t*ptr;\n    } data;\n} write_data_t;\n\n/*\n * Structure of SSL socket write buffer (circular buffer).\n */\ntypedef struct send_buf_t {\n    char\t\t*buf;\n    pj_size_t\t\t max_len;    \n    char\t\t*start;\n    pj_size_t\t\t len;\n} send_buf_t;\n\n/*\n * Secure socket structure definition.\n */\nstruct pj_ssl_sock_t\n{\n    pj_pool_t\t\t *pool;\n    pj_ssl_sock_t\t *parent;\n    pj_ssl_sock_param\t  param;\n    pj_ssl_sock_param\t  newsock_param;\n    pj_ssl_cert_t\t *cert;\n    \n    pj_ssl_cert_info\t  local_cert_info;\n    pj_ssl_cert_info\t  remote_cert_info;\n\n    pj_bool_t\t\t  is_server;\n    enum ssl_state\t  ssl_state;\n    pj_ioqueue_op_key_t\t  handshake_op_key;\n    pj_timer_entry\t  timer;\n    pj_status_t\t\t  verify_status;\n\n    unsigned long\t  last_err;\n\n    pj_sock_t\t\t  sock;\n    pj_activesock_t\t *asock;\n\n    pj_sockaddr\t\t  local_addr;\n    pj_sockaddr\t\t  rem_addr;\n    int\t\t\t  addr_len;\n    \n    pj_bool_t\t\t  read_started;\n    pj_size_t\t\t  read_size;\n    pj_uint32_t\t\t  read_flags;\n    void\t\t**asock_rbuf;\n    read_data_t\t\t *ssock_rbuf;\n\n    write_data_t\t  write_pending;/* list of pending write to OpenSSL */\n    write_data_t\t  write_pending_empty; /* cache for write_pending   */\n    pj_bool_t\t\t  flushing_write_pend; /* flag of flushing is ongoing*/\n    send_buf_t\t\t  send_buf;\n    write_data_t\t  send_pending;\t/* list of pending write to network */\n    pj_lock_t\t\t *write_mutex;\t/* protect write BIO and send_buf   */\n    pj_lock_t\t\t *state_mutex;\t/* protect the socket state (sending on one thread, destroying it in another   */\n\n    SSL_CTX\t\t *ossl_ctx;\n    SSL\t\t\t *ossl_ssl;\n    BIO\t\t\t *ossl_rbio;\n    BIO\t\t\t *ossl_wbio;\n};\n\n\n/*\n * Certificate/credential structure definition.\n */\nstruct pj_ssl_cert_t\n{\n    pj_str_t CA_file;\n    pj_str_t CA_path;\n    pj_str_t cert_file;\n    pj_str_t privkey_file;\n    pj_str_t privkey_pass;\n};\n\n\nstatic write_data_t* alloc_send_data(pj_ssl_sock_t *ssock, pj_size_t len);\nstatic void free_send_data(pj_ssl_sock_t *ssock, write_data_t *wdata);\nstatic pj_status_t flush_delayed_send(pj_ssl_sock_t *ssock);\n\n/*\n *******************************************************************\n * Static/internal functions.\n *******************************************************************\n */\n\n/**\n * Mapping from OpenSSL error codes to pjlib error space.\n */\n\n#define PJ_SSL_ERRNO_START\t\t(PJ_ERRNO_START_USER + \\\n\t\t\t\t\t PJ_ERRNO_SPACE_SIZE*6)\n\n#define PJ_SSL_ERRNO_SPACE_SIZE\t\tPJ_ERRNO_SPACE_SIZE\n\n/* Expected maximum value of reason component in OpenSSL error code */\n#define MAX_OSSL_ERR_REASON\t\t1200\n\nstatic pj_status_t STATUS_FROM_SSL_ERR(pj_ssl_sock_t *ssock,\n\t\t\t\t       unsigned long err)\n{\n    pj_status_t status;\n\n    /* General SSL error, dig more from OpenSSL error queue */\n    if (err == SSL_ERROR_SSL)\n\terr = ERR_get_error();\n\n    /* OpenSSL error range is much wider than PJLIB errno space, so\n     * if it exceeds the space, only the error reason will be kept.\n     * Note that the last native error will be kept as is and can be\n     * retrieved via SSL socket info.\n     */\n    status = ERR_GET_LIB(err)*MAX_OSSL_ERR_REASON + ERR_GET_REASON(err);\n    if (status > PJ_SSL_ERRNO_SPACE_SIZE)\n\tstatus = ERR_GET_REASON(err);\n\n    status += PJ_SSL_ERRNO_START;\n    ssock->last_err = err;\n    return status;\n}\n\nstatic pj_status_t GET_SSL_STATUS(pj_ssl_sock_t *ssock)\n{\n    return STATUS_FROM_SSL_ERR(ssock, ERR_get_error());\n}\n\n\n/*\n * Get error string of OpenSSL.\n */\nstatic pj_str_t ssl_strerror(pj_status_t status, \n\t\t\t     char *buf, pj_size_t bufsize)\n{\n    pj_str_t errstr;\n    unsigned long ssl_err = status;\n\n    if (ssl_err) {\n\tunsigned long l, r;\n\tssl_err -= PJ_SSL_ERRNO_START;\n\tl = ssl_err / MAX_OSSL_ERR_REASON;\n\tr = ssl_err % MAX_OSSL_ERR_REASON;\n\tssl_err = ERR_PACK(l, 0, r);\n    }\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n\n    {\n\tconst char *tmp = NULL;\n\ttmp = ERR_reason_error_string(ssl_err);\n\tif (tmp) {\n\t    pj_ansi_strncpy(buf, tmp, bufsize);\n\t    errstr = pj_str(buf);\n\t    return errstr;\n\t}\n    }\n\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n    errstr.ptr = buf;\n    errstr.slen = pj_ansi_snprintf(buf, bufsize, \n\t\t\t\t   \"Unknown OpenSSL error %lu\",\n\t\t\t\t   ssl_err);\n    if (errstr.slen < 1 || errstr.slen >= (int)bufsize)\n\terrstr.slen = bufsize - 1;\n    return errstr;\n}\n\n\n/* OpenSSL library initialization counter */\nstatic int openssl_init_count;\n\n/* OpenSSL available ciphers */\nstatic unsigned openssl_cipher_num;\nstatic struct openssl_ciphers_t {\n    pj_ssl_cipher    id;\n    const char\t    *name;\n} openssl_ciphers[PJ_SSL_SOCK_MAX_CIPHERS];\n\n/* OpenSSL application data index */\nstatic int sslsock_idx;\n\n\n/* Initialize OpenSSL */\nstatic pj_status_t init_openssl(void)\n{\n    pj_status_t status;\n\n    if (openssl_init_count)\n\treturn PJ_SUCCESS;\n\n    openssl_init_count = 1;\n\n    /* Register error subsystem */\n    status = pj_register_strerror(PJ_SSL_ERRNO_START, \n\t\t\t\t  PJ_SSL_ERRNO_SPACE_SIZE, \n\t\t\t\t  &ssl_strerror);\n    pj_assert(status == PJ_SUCCESS);\n\n    /* Init OpenSSL lib */\n#if OPENSSL_VERSION_NUMBER < 0x10100000L\n    SSL_library_init();\n    SSL_load_error_strings();\n#else\n    OPENSSL_init_ssl(0, NULL);\n#endif\n#if OPENSSL_VERSION_NUMBER < 0x009080ffL\n    /* This is now synonym of SSL_library_init() */\n    OpenSSL_add_all_algorithms();\n#endif\n\n    /* Init available ciphers */\n    if (openssl_cipher_num == 0) {\n\tSSL_METHOD *meth = NULL;\n\tSSL_CTX *ctx;\n\tSSL *ssl;\n\tSTACK_OF(SSL_CIPHER) *sk_cipher;\n\tunsigned i, n;\n\n#if OPENSSL_VERSION_NUMBER < 0x10100000L\n\tmeth = (SSL_METHOD*)SSLv23_server_method();\n\tif (!meth)\n\t    meth = (SSL_METHOD*)TLSv1_server_method();\n#ifndef OPENSSL_NO_SSL3_METHOD\n\tif (!meth)\n\t    meth = (SSL_METHOD*)SSLv3_server_method();\n#endif\n#ifndef OPENSSL_NO_SSL2\n\tif (!meth)\n\t    meth = (SSL_METHOD*)SSLv2_server_method();\n#endif\n\n#else\n\t/* Specific version methods are deprecated in 1.1.0 */\n\tmeth = (SSL_METHOD*)TLS_method();\n#endif\n\n\tpj_assert(meth);\n\n\tctx=SSL_CTX_new(meth);\n\tSSL_CTX_set_cipher_list(ctx, \"ALL:COMPLEMENTOFALL\");\n\n\tssl = SSL_new(ctx);\n\tsk_cipher = SSL_get_ciphers(ssl);\n\n\tn = sk_SSL_CIPHER_num(sk_cipher);\n\tif (n > PJ_ARRAY_SIZE(openssl_ciphers))\n\t    n = PJ_ARRAY_SIZE(openssl_ciphers);\n\n\tfor (i = 0; i < n; ++i) {\n\t    const SSL_CIPHER *c;\n\t    c = sk_SSL_CIPHER_value(sk_cipher,i);\n\t    openssl_ciphers[i].id = (pj_ssl_cipher)\n\t\t\t\t    (pj_uint32_t)SSL_CIPHER_get_id(c) & 0x00FFFFFF;\n\t    openssl_ciphers[i].name = SSL_CIPHER_get_name(c);\n\t}\n\n\tSSL_free(ssl);\n\tSSL_CTX_free(ctx);\n\n\topenssl_cipher_num = n;\n    }\n\n    /* Create OpenSSL application data index for SSL socket */\n    sslsock_idx = SSL_get_ex_new_index(0, \"SSL socket\", NULL, NULL, NULL);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Shutdown OpenSSL */\nstatic void shutdown_openssl(void)\n{\n    PJ_UNUSED_ARG(openssl_init_count);\n}\n\n\n/* SSL password callback. */\nstatic int password_cb(char *buf, int num, int rwflag, void *user_data)\n{\n    pj_ssl_cert_t *cert = (pj_ssl_cert_t*) user_data;\n\n    PJ_UNUSED_ARG(rwflag);\n\n    if(num < cert->privkey_pass.slen)\n\treturn 0;\n    \n    pj_memcpy(buf, cert->privkey_pass.ptr, cert->privkey_pass.slen);\n    return (int)cert->privkey_pass.slen;\n}\n\n\n/* SSL password callback. */\nstatic int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)\n{\n    pj_ssl_sock_t *ssock;\n    SSL *ossl_ssl;\n    int err;\n\n    /* Get SSL instance */\n    ossl_ssl = X509_STORE_CTX_get_ex_data(x509_ctx, \n\t\t\t\t    SSL_get_ex_data_X509_STORE_CTX_idx());\n    pj_assert(ossl_ssl);\n\n    /* Get SSL socket instance */\n    ssock = SSL_get_ex_data(ossl_ssl, sslsock_idx);\n    pj_assert(ssock);\n\n    /* Store verification status */\n    err = X509_STORE_CTX_get_error(x509_ctx);\n    switch (err) {\n    case X509_V_OK:\n\tbreak;\n\n    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:\n\tssock->verify_status |= PJ_SSL_CERT_EISSUER_NOT_FOUND;\n\tbreak;\n\n    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:\n    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:\n    case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:\n    case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:\n\tssock->verify_status |= PJ_SSL_CERT_EINVALID_FORMAT;\n\tbreak;\n\n    case X509_V_ERR_CERT_NOT_YET_VALID:\n    case X509_V_ERR_CERT_HAS_EXPIRED:\n\tssock->verify_status |= PJ_SSL_CERT_EVALIDITY_PERIOD;\n\tbreak;\n\n    case X509_V_ERR_UNABLE_TO_GET_CRL:\n    case X509_V_ERR_CRL_NOT_YET_VALID:\n    case X509_V_ERR_CRL_HAS_EXPIRED:\n    case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:\n    case X509_V_ERR_CRL_SIGNATURE_FAILURE:\n    case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:\n    case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:\n\tssock->verify_status |= PJ_SSL_CERT_ECRL_FAILURE;\n\tbreak;\t\n\n    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:\n    case X509_V_ERR_CERT_UNTRUSTED:\n    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:\n    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:\n\tssock->verify_status |= PJ_SSL_CERT_EUNTRUSTED;\n\tbreak;\t\n\n    case X509_V_ERR_CERT_SIGNATURE_FAILURE:\n    case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:\n    case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:\n    case X509_V_ERR_AKID_SKID_MISMATCH:\n    case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:\n    case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:\n\tssock->verify_status |= PJ_SSL_CERT_EISSUER_MISMATCH;\n\tbreak;\n\n    case X509_V_ERR_CERT_REVOKED:\n\tssock->verify_status |= PJ_SSL_CERT_EREVOKED;\n\tbreak;\t\n\n    case X509_V_ERR_INVALID_PURPOSE:\n    case X509_V_ERR_CERT_REJECTED:\n    case X509_V_ERR_INVALID_CA:\n\tssock->verify_status |= PJ_SSL_CERT_EINVALID_PURPOSE;\n\tbreak;\n\n    case X509_V_ERR_CERT_CHAIN_TOO_LONG: /* not really used */\n    case X509_V_ERR_PATH_LENGTH_EXCEEDED:\n\tssock->verify_status |= PJ_SSL_CERT_ECHAIN_TOO_LONG;\n\tbreak;\n\n    /* Unknown errors */\n    case X509_V_ERR_OUT_OF_MEM:\n    default:\n\tssock->verify_status |= PJ_SSL_CERT_EUNKNOWN;\n\tbreak;\n    }\n\n    /* When verification is not requested just return ok here, however\n     * application can still get the verification status.\n     */\n    if (PJ_FALSE == ssock->param.verify_peer)\n\tpreverify_ok = 1;\n\n    return preverify_ok;\n}\n\n/* Setting SSL sock cipher list */\nstatic pj_status_t set_cipher_list(pj_ssl_sock_t *ssock);\n\n\n/* Create and initialize new SSL context and instance */\nstatic pj_status_t create_ssl(pj_ssl_sock_t *ssock)\n{\n    BIO *bio;\n    DH *dh;\n    long options;\n#if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10000000L\n    EC_KEY *ecdh;\n#endif\n    SSL_METHOD *ssl_method = NULL;\n    SSL_CTX *ctx;\n    pj_uint32_t ssl_opt = 0;\n    pj_ssl_cert_t *cert;\n    int mode, rc;\n    pj_status_t status;\n        \n    pj_assert(ssock);\n\n    cert = ssock->cert;\n\n    /* Make sure OpenSSL library has been initialized */\n    init_openssl();\n\n    if (ssock->param.proto == PJ_SSL_SOCK_PROTO_DEFAULT)\n\tssock->param.proto = PJ_SSL_SOCK_PROTO_SSL23;\n\n    /* Determine SSL method to use */\n#if OPENSSL_VERSION_NUMBER < 0x10100000L\n    switch (ssock->param.proto) {\n    case PJ_SSL_SOCK_PROTO_TLS1:\n\tssl_method = (SSL_METHOD*)TLSv1_method();\n\tbreak;\n#ifndef OPENSSL_NO_SSL2\n    case PJ_SSL_SOCK_PROTO_SSL2:\n\tssl_method = (SSL_METHOD*)SSLv2_method();\n\tbreak;\n#endif\n#ifndef OPENSSL_NO_SSL3_METHOD\n    case PJ_SSL_SOCK_PROTO_SSL3:\n\tssl_method = (SSL_METHOD*)SSLv3_method();\n#endif\n\tbreak;\n    }\n#else\n    /* Specific version methods are deprecated in 1.1.0 */\n    ssl_method = (SSL_METHOD*)TLS_method();\n#endif\n\n    if (!ssl_method) {\n\tssl_method = (SSL_METHOD*)SSLv23_method();\n\n#ifdef SSL_OP_NO_SSLv2\n\t/** Check if SSLv2 is enabled */\n\tssl_opt |= ((ssock->param.proto & PJ_SSL_SOCK_PROTO_SSL2)==0)?\n\t\t    SSL_OP_NO_SSLv2:0;\n#endif\n\n#ifdef SSL_OP_NO_SSLv3\n\t/** Check if SSLv3 is enabled */\n\tssl_opt |= ((ssock->param.proto & PJ_SSL_SOCK_PROTO_SSL3)==0)?\n\t\t    SSL_OP_NO_SSLv3:0;\n#endif\n\n#ifdef SSL_OP_NO_TLSv1\n\t/** Check if TLSv1 is enabled */\n\tssl_opt |= ((ssock->param.proto & PJ_SSL_SOCK_PROTO_TLS1)==0)?\n\t\t    SSL_OP_NO_TLSv1:0;\n#endif\n\n#ifdef SSL_OP_NO_TLSv1_1\n\t/** Check if TLSv1_1 is enabled */\n\tssl_opt |= ((ssock->param.proto & PJ_SSL_SOCK_PROTO_TLS1_1)==0)?\n\t\t    SSL_OP_NO_TLSv1_1:0;\n#endif\n\n#ifdef SSL_OP_NO_TLSv1_2\n\t/** Check if TLSv1_2 is enabled */\n\tssl_opt |= ((ssock->param.proto & PJ_SSL_SOCK_PROTO_TLS1_2)==0)?\n\t\t    SSL_OP_NO_TLSv1_2:0;\n\n#endif\n\n    }\n\n    /* Create SSL context */\n    ctx = SSL_CTX_new(ssl_method);\n    if (ctx == NULL) {\n\treturn GET_SSL_STATUS(ssock);\n    }\n    if (ssl_opt)\n\tSSL_CTX_set_options(ctx, ssl_opt);\n\n    /* Apply credentials */\n    if (cert) {\n\t/* Load CA list if one is specified. */\n\tif (cert->CA_file.slen || cert->CA_path.slen) {\n\n\t    rc = SSL_CTX_load_verify_locations(\n\t\t\tctx,\n\t\t\tcert->CA_file.slen == 0 ? NULL : cert->CA_file.ptr,\n\t\t\tcert->CA_path.slen == 0 ? NULL : cert->CA_path.ptr);\n\n\t    if (rc != 1) {\n\t\tstatus = GET_SSL_STATUS(ssock);\n\t\tif (cert->CA_file.slen) {\n\t\t    PJ_LOG(1,(ssock->pool->obj_name,\n\t\t\t      \"Error loading CA list file '%s'\",\n\t\t\t      cert->CA_file.ptr));\n\t\t}\n\t\tif (cert->CA_path.slen) {\n\t\t    PJ_LOG(1,(ssock->pool->obj_name,\n\t\t\t      \"Error loading CA path '%s'\",\n\t\t\t      cert->CA_path.ptr));\n\t\t}\n\t\tSSL_CTX_free(ctx);\n\t\treturn status;\n\t    }\n\t}\n    \n\t/* Set password callback */\n\tif (cert->privkey_pass.slen) {\n\t    SSL_CTX_set_default_passwd_cb(ctx, password_cb);\n\t    SSL_CTX_set_default_passwd_cb_userdata(ctx, cert);\n\t}\n\n\n\t/* Load certificate if one is specified */\n\tif (cert->cert_file.slen) {\n\n\t    /* Load certificate chain from file into ctx */\n\t    rc = SSL_CTX_use_certificate_chain_file(ctx, cert->cert_file.ptr);\n\n\t    if(rc != 1) {\n\t\tstatus = GET_SSL_STATUS(ssock);\n\t\tPJ_LOG(1,(ssock->pool->obj_name, \"Error loading certificate \"\n\t\t\t  \"chain file '%s'\", cert->cert_file.ptr));\n\t\tSSL_CTX_free(ctx);\n\t\treturn status;\n\t    }\n\t}\n\n\n\t/* Load private key if one is specified */\n\tif (cert->privkey_file.slen) {\n\t    /* Adds the first private key found in file to ctx */\n\t    rc = SSL_CTX_use_PrivateKey_file(ctx, cert->privkey_file.ptr, \n\t\t\t\t\t     SSL_FILETYPE_PEM);\n\n\t    if(rc != 1) {\n\t\tstatus = GET_SSL_STATUS(ssock);\n\t\tPJ_LOG(1,(ssock->pool->obj_name, \"Error adding private key \"\n\t\t\t  \"from '%s'\", cert->privkey_file.ptr));\n\t\tSSL_CTX_free(ctx);\n\t\treturn status;\n\t    }\n\n\t    if (ssock->is_server) {\n\t\tbio = BIO_new_file(cert->privkey_file.ptr, \"r\");\n\t\tif (bio != NULL) {\n\t\t    dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);\n\t\t    if (dh != NULL) {\n\t\t\tif (SSL_CTX_set_tmp_dh(ctx, dh)) {\n\t\t\t    options = SSL_OP_CIPHER_SERVER_PREFERENCE |\n    #if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10000000L\n\t\t\t\t      SSL_OP_SINGLE_ECDH_USE |\n    #endif\n\t\t\t\t      SSL_OP_SINGLE_DH_USE;\n\t\t\t    options = SSL_CTX_set_options(ctx, options);\n\t\t\t    PJ_LOG(4,(ssock->pool->obj_name, \"SSL DH \"\n\t\t\t\t     \"initialized, PFS cipher-suites enabled\"));\n\t\t\t}\n\t\t\tDH_free(dh);\n\t\t    }\n\t\t    BIO_free(bio);\n\t\t}\n\t    }\n\t}\n    }\n\n    if (ssock->is_server) {\n\tchar *p = NULL;\n\n\t/* If certificate file name contains \"_rsa.\", let's check if there are\n\t * ecc and dsa certificates too.\n\t */\n\tif (cert && cert->cert_file.slen) {\n\t    const pj_str_t RSA = {\"_rsa.\", 5};\n\t    p = pj_strstr(&cert->cert_file, &RSA);\n\t    if (p) p++; /* Skip underscore */\n\t}\n\tif (p) {\n\t    /* Certificate type string length must be exactly 3 */\n\t    enum { CERT_TYPE_LEN = 3 };\n\t    const char* cert_types[] = { \"ecc\", \"dsa\" };\n\t    char *cf = cert->cert_file.ptr;\n\t    int i;\n\n\t    /* Check and load ECC & DSA certificates & private keys */\n\t    for (i = 0; i < PJ_ARRAY_SIZE(cert_types); ++i) {\n\t\tint err;\n\n\t\tpj_memcpy(p, cert_types[i], CERT_TYPE_LEN);\n\t\tif (!pj_file_exists(cf))\n\t\t    continue;\n\n\t\terr = SSL_CTX_use_certificate_chain_file(ctx, cf);\n\t\tif (err == 1)\n\t\t    err = SSL_CTX_use_PrivateKey_file(ctx, cf,\n\t\t\t\t\t\t      SSL_FILETYPE_PEM);\n\t\tif (err == 1) {\n\t\t    PJ_LOG(4,(ssock->pool->obj_name,\n\t\t\t      \"Additional certificate '%s' loaded.\", cf));\n\t\t} else {\n\t\t    pj_perror(1, ssock->pool->obj_name, GET_SSL_STATUS(ssock),\n\t\t\t      \"Error loading certificate file '%s'\", cf);\n\t\t    ERR_clear_error();\n\t\t}\n\t    }\n\n\t    /* Put back original name */\n\t    pj_memcpy(p, \"rsa\", CERT_TYPE_LEN);\n\t}\n\n    #ifndef SSL_CTRL_SET_ECDH_AUTO\n\t#define SSL_CTRL_SET_ECDH_AUTO 94\n    #endif\n\n\t/* SSL_CTX_set_ecdh_auto(ctx,on) requires OpenSSL 1.0.2 which wraps: */\n\tif (SSL_CTX_ctrl(ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL)) {\n\t    PJ_LOG(4,(ssock->pool->obj_name, \"SSL ECDH initialized \"\n\t\t      \"(automatic), faster PFS ciphers enabled\"));\n    #if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10000000L\n\t} else {\n\t    /* enables AES-128 ciphers, to get AES-256 use NID_secp384r1 */\n\t    ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);\n\t    if (ecdh != NULL) {\n\t\tif (SSL_CTX_set_tmp_ecdh(ctx, ecdh)) {\n\t\t    PJ_LOG(4,(ssock->pool->obj_name, \"SSL ECDH initialized \"\n\t\t\t      \"(secp256r1), faster PFS cipher-suites enabled\"));\n\t\t}\n\t\tEC_KEY_free(ecdh);\n\t    }\n    #endif\n\t}\n    } else {\n\tX509_STORE *pkix_validation_store = SSL_CTX_get_cert_store(ctx);\n\tif (NULL != pkix_validation_store) {\n#if defined(X509_V_FLAG_TRUSTED_FIRST)\n\t    X509_STORE_set_flags(pkix_validation_store, \n\t\t\t\t X509_V_FLAG_TRUSTED_FIRST);\n#endif\n#if defined(X509_V_FLAG_PARTIAL_CHAIN)\n\t    X509_STORE_set_flags(pkix_validation_store, \n\t\t\t\t X509_V_FLAG_PARTIAL_CHAIN);\n#endif\n\t}\n    }\n\n    /* Create SSL instance */\n    ssock->ossl_ctx = ctx;\n    ssock->ossl_ssl = SSL_new(ssock->ossl_ctx);\n    if (ssock->ossl_ssl == NULL) {\n\treturn GET_SSL_STATUS(ssock);\n    }\n\n    /* Set SSL sock as application data of SSL instance */\n    SSL_set_ex_data(ssock->ossl_ssl, sslsock_idx, ssock);\n\n    /* SSL verification options */\n    mode = SSL_VERIFY_PEER;\n    if (ssock->is_server && ssock->param.require_client_cert)\n\tmode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;\n\n    SSL_set_verify(ssock->ossl_ssl, mode, &verify_cb);\n\n    /* Set cipher list */\n    status = set_cipher_list(ssock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Setup SSL BIOs */\n    ssock->ossl_rbio = BIO_new(BIO_s_mem());\n    ssock->ossl_wbio = BIO_new(BIO_s_mem());\n    (void)BIO_set_close(ssock->ossl_rbio, BIO_CLOSE);\n    (void)BIO_set_close(ssock->ossl_wbio, BIO_CLOSE);\n    SSL_set_bio(ssock->ossl_ssl, ssock->ossl_rbio, ssock->ossl_wbio);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Destroy SSL context and instance */\nstatic void destroy_ssl(pj_ssl_sock_t *ssock)\n{\n    /* Destroy SSL instance */\n    if (ssock->ossl_ssl) {\n\tSSL_shutdown(ssock->ossl_ssl);\n\tSSL_free(ssock->ossl_ssl); /* this will also close BIOs */\n\tssock->ossl_ssl = NULL;\n    }\n\n    /* Destroy SSL context */\n    if (ssock->ossl_ctx) {\n\tSSL_CTX_free(ssock->ossl_ctx);\n\tssock->ossl_ctx = NULL;\n    }\n\n    /* Potentially shutdown OpenSSL library if this is the last\n     * context exists.\n     */\n    shutdown_openssl();\n}\n\n\n/* Reset SSL socket state */\nstatic void reset_ssl_sock_state(pj_ssl_sock_t *ssock)\n{\n    pj_lock_acquire(ssock->state_mutex);\n\n    ssock->ssl_state = SSL_STATE_NULL;\n\n    destroy_ssl(ssock);\n\n    if (ssock->asock) {\n\tpj_activesock_close(ssock->asock);\n\tssock->asock = NULL;\n\tssock->sock = PJ_INVALID_SOCKET;\n    }\n    if (ssock->sock != PJ_INVALID_SOCKET) {\n\tpj_sock_close(ssock->sock);\n\tssock->sock = PJ_INVALID_SOCKET;\n    }\n\n    /* Upon error, OpenSSL may leave any error description in the thread \n     * error queue, which sometime may cause next call to SSL API returning\n     * false error alarm, e.g: in Linux, SSL_CTX_use_certificate_chain_file()\n     * returning false error after a handshake error (in different SSL_CTX!).\n     * For now, just clear thread error queue here.\n     */\n    ERR_clear_error();\n\n    pj_lock_release(ssock->state_mutex);\n}\n\n\n/* Generate cipher list with user preference order in OpenSSL format */\nstatic pj_status_t set_cipher_list(pj_ssl_sock_t *ssock)\n{\n    char buf[1024];\n    pj_str_t cipher_list;\n    STACK_OF(SSL_CIPHER) *sk_cipher;\n    unsigned i;\n    int j, ret;\n\n    if (ssock->param.ciphers_num == 0) {\n\tret = SSL_set_cipher_list(ssock->ossl_ssl, PJ_SSL_SOCK_OSSL_CIPHERS);\n    \tif (ret < 1) {\n\t    return GET_SSL_STATUS(ssock);\n    \t}    \n\t\n\treturn PJ_SUCCESS;\n    }\n\n    pj_strset(&cipher_list, buf, 0);\n\n    /* Set SSL with ALL available ciphers */\n    SSL_set_cipher_list(ssock->ossl_ssl, \"ALL:COMPLEMENTOFALL\");\n\n    /* Generate user specified cipher list in OpenSSL format */\n    sk_cipher = SSL_get_ciphers(ssock->ossl_ssl);\n    for (i = 0; i < ssock->param.ciphers_num; ++i) {\n\tfor (j = 0; j < sk_SSL_CIPHER_num(sk_cipher); ++j) {\n\t    const SSL_CIPHER *c;\n\t    c = sk_SSL_CIPHER_value(sk_cipher, j);\n\t    if (ssock->param.ciphers[i] == (pj_ssl_cipher)\n\t\t\t\t\t   ((pj_uint32_t)SSL_CIPHER_get_id(c) &\n\t\t\t\t\t   0x00FFFFFF))\n\t    {\n\t\tconst char *c_name;\n\n\t\tc_name = SSL_CIPHER_get_name(c);\n\n\t\t/* Check buffer size */\n\t\tif (cipher_list.slen + pj_ansi_strlen(c_name) + 2 >\n\t\t    sizeof(buf))\n\t\t{\n\t\t    pj_assert(!\"Insufficient temporary buffer for cipher\");\n\t\t    return PJ_ETOOMANY;\n\t\t}\n\n\t\t/* Add colon separator */\n\t\tif (cipher_list.slen)\n\t\t    pj_strcat2(&cipher_list, \":\");\n\n\t\t/* Add the cipher */\n\t\tpj_strcat2(&cipher_list, c_name);\n\t\tbreak;\n\t    }\n\t}\n    }\n\n    /* Put NULL termination in the generated cipher list */\n    cipher_list.ptr[cipher_list.slen] = '\\0';\n\n    /* Finally, set chosen cipher list */\n    ret = SSL_set_cipher_list(ssock->ossl_ssl, buf);\n    if (ret < 1) {\n\treturn GET_SSL_STATUS(ssock);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* Parse OpenSSL ASN1_TIME to pj_time_val and GMT info */\nstatic pj_bool_t parse_ossl_asn1_time(pj_time_val *tv, pj_bool_t *gmt,\n\t\t\t\t      const ASN1_TIME *tm)\n{\n    unsigned long parts[7] = {0};\n    char *p, *end;\n    unsigned len;\n    pj_bool_t utc;\n    pj_parsed_time pt;\n    int i;\n\n    utc = tm->type == V_ASN1_UTCTIME;\n    p = (char*)tm->data;\n    len = tm->length;\n    end = p + len - 1;\n\n    /* GMT */\n    *gmt = (*end == 'Z');\n\n    /* parse parts */\n    for (i = 0; i < 7 && p < end; ++i) {\n\tpj_str_t st;\n\n\tif (i==0 && !utc) {\n\t    /* 4 digits year part for non-UTC time format */\n\t    st.slen = 4;\n\t} else if (i==6) {\n\t    /* fraction of seconds */\n\t    if (*p == '.') ++p;\n\t    st.slen = end - p + 1;\n\t} else {\n\t    /* other parts always 2 digits length */\n\t    st.slen = 2;\n\t}\n\tst.ptr = p;\n\n\tparts[i] = pj_strtoul(&st);\n\tp += st.slen;\n    }\n\n    /* encode parts to pj_time_val */\n    pt.year = parts[0];\n    if (utc)\n\tpt.year += (pt.year < 50)? 2000:1900;\n    pt.mon = parts[1] - 1;\n    pt.day = parts[2];\n    pt.hour = parts[3];\n    pt.min = parts[4];\n    pt.sec = parts[5];\n    pt.msec = parts[6];\n\n    pj_time_encode(&pt, tv);\n\n    return PJ_TRUE;\n}\n\n\n/* Get Common Name field string from a general name string */\nstatic void get_cn_from_gen_name(const pj_str_t *gen_name, pj_str_t *cn)\n{\n    pj_str_t CN_sign = {\"/CN=\", 4};\n    char *p, *q;\n\n    pj_bzero(cn, sizeof(pj_str_t));\n\n    p = pj_strstr(gen_name, &CN_sign);\n    if (!p)\n\treturn;\n\n    p += 4; /* shift pointer to value part */\n    pj_strset(cn, p, gen_name->slen - (p - gen_name->ptr));\n    q = pj_strchr(cn, '/');\n    if (q)\n\tcn->slen = q - p;\n}\n\n\n/* Get certificate info from OpenSSL X509, in case the certificate info\n * hal already populated, this function will check if the contents need \n * to be updated by inspecting the issuer and the serial number.\n */\nstatic void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci, X509 *x,\n\t\t\t  pj_bool_t get_pem)\n{\n    pj_bool_t update_needed;\n    char buf[512];\n    pj_uint8_t serial_no[64] = {0}; /* should be >= sizeof(ci->serial_no) */\n    const pj_uint8_t *q;\n    unsigned len;\n    GENERAL_NAMES *names = NULL;\n\n    pj_assert(pool && ci && x);\n\n    /* Get issuer */\n    X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof(buf));\n\n    /* Get serial no */\n    q = (const pj_uint8_t*) M_ASN1_STRING_data(X509_get_serialNumber(x));\n    len = M_ASN1_STRING_length(X509_get_serialNumber(x));\n    if (len > sizeof(ci->serial_no)) \n\tlen = sizeof(ci->serial_no);\n    pj_memcpy(serial_no + sizeof(ci->serial_no) - len, q, len);\n\n    /* Check if the contents need to be updated. */\n    update_needed = pj_strcmp2(&ci->issuer.info, buf) || \n\t            pj_memcmp(ci->serial_no, serial_no, sizeof(ci->serial_no));\n    if (!update_needed)\n\treturn;\n\n    /* Update cert info */\n\n    pj_bzero(ci, sizeof(pj_ssl_cert_info));\n\n    /* Version */\n    ci->version = X509_get_version(x) + 1;\n\n    /* Issuer */\n    pj_strdup2(pool, &ci->issuer.info, buf);\n    get_cn_from_gen_name(&ci->issuer.info, &ci->issuer.cn);\n\n    /* Serial number */\n    pj_memcpy(ci->serial_no, serial_no, sizeof(ci->serial_no));\n\n    /* Subject */\n    pj_strdup2(pool, &ci->subject.info, \n\t       X509_NAME_oneline(X509_get_subject_name(x),\n\t\t\t\t buf, sizeof(buf)));\n    get_cn_from_gen_name(&ci->subject.info, &ci->subject.cn);\n\n    /* Validity */\n    parse_ossl_asn1_time(&ci->validity.start, &ci->validity.gmt,\n\t\t\t X509_get_notBefore(x));\n    parse_ossl_asn1_time(&ci->validity.end, &ci->validity.gmt,\n\t\t\t X509_get_notAfter(x));\n\n    /* Subject Alternative Name extension */\n    if (ci->version >= 3) {\n\tnames = (GENERAL_NAMES*) X509_get_ext_d2i(x, NID_subject_alt_name,\n\t\t\t\t\t\t  NULL, NULL);\n    }\n    if (names) {\n        unsigned i, cnt;\n\n        cnt = sk_GENERAL_NAME_num(names);\n\tci->subj_alt_name.entry = pj_pool_calloc(pool, cnt, \n\t\t\t\t\t    sizeof(*ci->subj_alt_name.entry));\n\n        for (i = 0; i < cnt; ++i) {\n\t    unsigned char *p = 0;\n\t    pj_ssl_cert_name_type type = PJ_SSL_CERT_NAME_UNKNOWN;\n            const GENERAL_NAME *name;\n\t    \n\t    name = sk_GENERAL_NAME_value(names, i);\n\n            switch (name->type) {\n                case GEN_EMAIL:\n                    len = ASN1_STRING_to_UTF8(&p, name->d.ia5);\n\t\t    type = PJ_SSL_CERT_NAME_RFC822;\n                    break;\n                case GEN_DNS:\n                    len = ASN1_STRING_to_UTF8(&p, name->d.ia5);\n\t\t    type = PJ_SSL_CERT_NAME_DNS;\n                    break;\n                case GEN_URI:\n                    len = ASN1_STRING_to_UTF8(&p, name->d.ia5);\n\t\t    type = PJ_SSL_CERT_NAME_URI;\n                    break;\n                case GEN_IPADD:\n\t\t    p = (unsigned char*)M_ASN1_STRING_data(name->d.ip);\n\t\t    len = M_ASN1_STRING_length(name->d.ip);\n\t\t    type = PJ_SSL_CERT_NAME_IP;\n                    break;\n\t\tdefault:\n\t\t    break;\n            }\n\n\t    if (p && len && type != PJ_SSL_CERT_NAME_UNKNOWN) {\n\t\tci->subj_alt_name.entry[ci->subj_alt_name.cnt].type = type;\n\t\tif (type == PJ_SSL_CERT_NAME_IP) {\n\t\t    int af = pj_AF_INET();\n\t\t    if (len == sizeof(pj_in6_addr)) af = pj_AF_INET6();\n\t\t    pj_inet_ntop2(af, p, buf, sizeof(buf));\n\t\t    pj_strdup2(pool, \n\t\t          &ci->subj_alt_name.entry[ci->subj_alt_name.cnt].name,\n\t\t          buf);\n\t\t} else {\n\t\t    pj_strdup2(pool, \n\t\t\t  &ci->subj_alt_name.entry[ci->subj_alt_name.cnt].name, \n\t\t\t  (char*)p);\n\t\t    OPENSSL_free(p);\n\t\t}\n\t\tci->subj_alt_name.cnt++;\n\t    }\n        }\n    }\n\n    if (get_pem) {\n\t/* Update raw Certificate info in PEM format. */\n\tBIO *bio;\t\n\tBUF_MEM *ptr;\n\t\n\tbio = BIO_new(BIO_s_mem());\n\tif (!PEM_write_bio_X509(bio, x)) {\n\t    PJ_LOG(3,(THIS_FILE, \"Error retrieving raw certificate info\"));\n\t    ci->raw.ptr = NULL;\n\t    ci->raw.slen = 0;\n\t} else {\n\t    BIO_write(bio, \"\\0\", 1);\n\t    BIO_get_mem_ptr(bio, &ptr);\n\t    pj_strdup2(pool, &ci->raw, ptr->data);\t\n\t}\t\n\tBIO_free(bio);\t    \n    }\t \n}\n\n\n/* Update local & remote certificates info. This function should be\n * called after handshake or renegotiation successfully completed.\n */\nstatic void update_certs_info(pj_ssl_sock_t *ssock)\n{\n    X509 *x;\n\n    pj_assert(ssock->ssl_state == SSL_STATE_ESTABLISHED);\n\n    /* Active local certificate */\n    x = SSL_get_certificate(ssock->ossl_ssl);\n    if (x) {\n\tget_cert_info(ssock->pool, &ssock->local_cert_info, x, PJ_FALSE);\n\t/* Don't free local's X509! */\n    } else {\n\tpj_bzero(&ssock->local_cert_info, sizeof(pj_ssl_cert_info));\n    }\n\n    /* Active remote certificate */\n    x = SSL_get_peer_certificate(ssock->ossl_ssl);\n    if (x) {\n\tget_cert_info(ssock->pool, &ssock->remote_cert_info, x, PJ_TRUE);\n\t/* Free peer's X509 */\n\tX509_free(x);\n    } else {\n\tpj_bzero(&ssock->remote_cert_info, sizeof(pj_ssl_cert_info));\n    }\n}\n\n\n/* When handshake completed:\n * - notify application\n * - if handshake failed, reset SSL state\n * - return PJ_FALSE when SSL socket instance is destroyed by application.\n */\nstatic pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock, \n\t\t\t\t       pj_status_t status)\n{\n    /* Cancel handshake timer */\n    if (ssock->timer.id == TIMER_HANDSHAKE_TIMEOUT) {\n\tpj_timer_heap_cancel(ssock->param.timer_heap, &ssock->timer);\n\tssock->timer.id = TIMER_NONE;\n    }\n\n    /* Update certificates info on successful handshake */\n    if (status == PJ_SUCCESS)\n\tupdate_certs_info(ssock);\n\n    /* Accepting */\n    if (ssock->is_server) {\n\tif (status != PJ_SUCCESS) {\n\t    /* Handshake failed in accepting, destroy our self silently. */\n\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\t    char buf[PJ_INET6_ADDRSTRLEN+10];\n\n\t    pj_strerror(status, errmsg, sizeof(errmsg));\n\t    PJ_LOG(3,(ssock->pool->obj_name, \"Handshake failed in accepting \"\n\t\t      \"%s: %s\",\n\t\t      pj_sockaddr_print(&ssock->rem_addr, buf, sizeof(buf), 3),\n\t\t      errmsg));\n\n\t    /* Workaround for ticket #985 */\n#if (defined(PJ_WIN32) && PJ_WIN32!=0) || (defined(PJ_WIN64) && PJ_WIN64!=0)\n\t    if (ssock->param.timer_heap) {\n\t\tpj_time_val interval = {0, DELAYED_CLOSE_TIMEOUT};\n\n\t\treset_ssl_sock_state(ssock);\n\n\t\tssock->timer.id = TIMER_CLOSE;\n\t\tpj_time_val_normalize(&interval);\n\t\tif (pj_timer_heap_schedule(ssock->param.timer_heap, \n\t\t\t\t\t   &ssock->timer, &interval) != 0)\n\t\t{\n\t\t    ssock->timer.id = TIMER_NONE;\n\t\t    pj_ssl_sock_close(ssock);\n\t\t}\n\t    } else \n#endif\t/* PJ_WIN32 */\n\t    {\n\t\tpj_ssl_sock_close(ssock);\n\t    }\n\t    return PJ_FALSE;\n\t}\n\t/* Notify application the newly accepted SSL socket */\n\tif (ssock->param.cb.on_accept_complete) {\n\t    pj_bool_t ret;\n\t    ret = (*ssock->param.cb.on_accept_complete)\n\t\t      (ssock->parent, ssock, (pj_sockaddr_t*)&ssock->rem_addr,\n\t\t       pj_sockaddr_get_len((pj_sockaddr_t*)&ssock->rem_addr));\n\t    if (ret == PJ_FALSE)\n\t\treturn PJ_FALSE;\n\t}\n    }\n\n    /* Connecting */\n    else {\n\t/* On failure, reset SSL socket state first, as app may try to \n\t * reconnect in the callback.\n\t */\n\tif (status != PJ_SUCCESS) {\n\t    /* Server disconnected us, possibly due to SSL nego failure */\n\t    if (status == PJ_EEOF) {\n\t\tunsigned long err;\n\t\terr = ERR_get_error();\n\t\tif (err != SSL_ERROR_NONE)\n\t\t    status = STATUS_FROM_SSL_ERR(ssock, err);\n\t    }\n\t    reset_ssl_sock_state(ssock);\n\t}\n\tif (ssock->param.cb.on_connect_complete) {\n\t    pj_bool_t ret;\n\t    ret = (*ssock->param.cb.on_connect_complete)(ssock, status);\n\t    if (ret == PJ_FALSE)\n\t\treturn PJ_FALSE;\n\t}\n    }\n\n    return PJ_TRUE;\n}\n\nstatic write_data_t* alloc_send_data(pj_ssl_sock_t *ssock, pj_size_t len)\n{\n    send_buf_t *send_buf = &ssock->send_buf;\n    pj_size_t avail_len, skipped_len = 0;\n    char *reg1, *reg2;\n    pj_size_t reg1_len, reg2_len;\n    write_data_t *p;\n\n    /* Check buffer availability */\n    avail_len = send_buf->max_len - send_buf->len;\n    if (avail_len < len)\n\treturn NULL;\n\n    /* If buffer empty, reset start pointer and return it */\n    if (send_buf->len == 0) {\n\tsend_buf->start = send_buf->buf;\n\tsend_buf->len   = len;\n\tp = (write_data_t*)send_buf->start;\n\tgoto init_send_data;\n    }\n\n    /* Free space may be wrapped/splitted into two regions, so let's\n     * analyze them if any region can hold the write data.\n     */\n    reg1 = send_buf->start + send_buf->len;\n    if (reg1 >= send_buf->buf + send_buf->max_len)\n\treg1 -= send_buf->max_len;\n    reg1_len = send_buf->max_len - send_buf->len;\n    if (reg1 + reg1_len > send_buf->buf + send_buf->max_len) {\n\treg1_len = send_buf->buf + send_buf->max_len - reg1;\n\treg2 = send_buf->buf;\n\treg2_len = send_buf->start - send_buf->buf;\n    } else {\n\treg2 = NULL;\n\treg2_len = 0;\n    }\n\n    /* More buffer availability check, note that the write data must be in\n     * a contigue buffer.\n     */\n    avail_len = PJ_MAX(reg1_len, reg2_len);\n    if (avail_len < len)\n\treturn NULL;\n\n    /* Get the data slot */\n    if (reg1_len >= len) {\n\tp = (write_data_t*)reg1;\n    } else {\n\tp = (write_data_t*)reg2;\n\tskipped_len = reg1_len;\n    }\n\n    /* Update buffer length */\n    send_buf->len += len + skipped_len;\n\ninit_send_data:\n    /* Init the new send data */\n    pj_bzero(p, sizeof(*p));\n    pj_list_init(p);\n    pj_list_push_back(&ssock->send_pending, p);\n\n    return p;\n}\n\nstatic void free_send_data(pj_ssl_sock_t *ssock, write_data_t *wdata)\n{\n    send_buf_t *buf = &ssock->send_buf;\n    write_data_t *spl = &ssock->send_pending;\n\n    pj_assert(!pj_list_empty(&ssock->send_pending));\n    \n    /* Free slot from the buffer */\n    if (spl->next == wdata && spl->prev == wdata) {\n\t/* This is the only data, reset the buffer */\n\tbuf->start = buf->buf;\n\tbuf->len = 0;\n    } else if (spl->next == wdata) {\n\t/* This is the first data, shift start pointer of the buffer and\n\t * adjust the buffer length.\n\t */\n\tbuf->start = (char*)wdata->next;\n\tif (wdata->next > wdata) {\n\t    buf->len -= ((char*)wdata->next - buf->start);\n\t} else {\n\t    /* Overlapped */\n\t    pj_size_t right_len, left_len;\n\t    right_len = buf->buf + buf->max_len - (char*)wdata;\n\t    left_len  = (char*)wdata->next - buf->buf;\n\t    buf->len -= (right_len + left_len);\n\t}\n    } else if (spl->prev == wdata) {\n\t/* This is the last data, just adjust the buffer length */\n\tif (wdata->prev < wdata) {\n\t    pj_size_t jump_len;\n\t    jump_len = (char*)wdata -\n\t\t       ((char*)wdata->prev + wdata->prev->record_len);\n\t    buf->len -= (wdata->record_len + jump_len);\n\t} else {\n\t    /* Overlapped */\n\t    pj_size_t right_len, left_len;\n\t    right_len = buf->buf + buf->max_len -\n\t\t\t((char*)wdata->prev + wdata->prev->record_len);\n\t    left_len  = (char*)wdata + wdata->record_len - buf->buf;\n\t    buf->len -= (right_len + left_len);\n\t}\n    }\n    /* For data in the middle buffer, just do nothing on the buffer. The slot\n     * will be freed later when freeing the first/last data.\n     */\n    \n    /* Remove the data from send pending list */\n    pj_list_erase(wdata);\n}\n\n#if 0\n/* Just for testing send buffer alloc/free */\n#include <pj/rand.h>\npj_status_t pj_ssl_sock_ossl_test_send_buf(pj_pool_t *pool)\n{\n    enum { MAX_CHUNK_NUM = 20 };\n    unsigned chunk_size, chunk_cnt, i;\n    write_data_t *wdata[MAX_CHUNK_NUM] = {0};\n    pj_time_val now;\n    pj_ssl_sock_t *ssock = NULL;\n    pj_ssl_sock_param param;\n    pj_status_t status;\n\n    pj_gettimeofday(&now);\n    pj_srand((unsigned)now.sec);\n\n    pj_ssl_sock_param_default(&param);\n    status = pj_ssl_sock_create(pool, &param, &ssock);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    if (ssock->send_buf.max_len == 0) {\n\tssock->send_buf.buf = (char*)\n\t\t\t      pj_pool_alloc(ssock->pool, \n\t\t\t\t\t    ssock->param.send_buffer_size);\n\tssock->send_buf.max_len = ssock->param.send_buffer_size;\n\tssock->send_buf.start = ssock->send_buf.buf;\n\tssock->send_buf.len = 0;\n    }\n\n    chunk_size = ssock->param.send_buffer_size / MAX_CHUNK_NUM / 2;\n    chunk_cnt = 0;\n    for (i = 0; i < MAX_CHUNK_NUM; i++) {\n\twdata[i] = alloc_send_data(ssock, pj_rand() % chunk_size + 321);\n\tif (wdata[i])\n\t    chunk_cnt++;\n\telse\n\t    break;\n    }\n\n    while (chunk_cnt) {\n\ti = pj_rand() % MAX_CHUNK_NUM;\n\tif (wdata[i]) {\n\t    free_send_data(ssock, wdata[i]);\n\t    wdata[i] = NULL;\n\t    chunk_cnt--;\n\t}\n    }\n\n    if (ssock->send_buf.len != 0)\n\tstatus = PJ_EBUG;\n\n    pj_ssl_sock_close(ssock);\n    return status;\n}\n#endif\n\n\n/* Flush write BIO to network socket. Note that any access to write BIO\n * MUST be serialized, so mutex protection must cover any call to OpenSSL\n * API (that possibly generate data for write BIO) along with the call to\n * this function (flushing all data in write BIO generated by above \n * OpenSSL API call).\n */\nstatic pj_status_t flush_write_bio(pj_ssl_sock_t *ssock, \n\t\t\t\t   pj_ioqueue_op_key_t *send_key,\n\t\t\t\t   pj_size_t orig_len,\n\t\t\t\t   unsigned flags)\n{\n    char *data;\n    pj_ssize_t len;\n    write_data_t *wdata;\n    pj_size_t needed_len;\n    pj_status_t status;\n\n    pj_lock_acquire(ssock->write_mutex);\n\n    /* Check if there is data in write BIO, flush it if any */\n    if (!BIO_pending(ssock->ossl_wbio)) {\n\tpj_lock_release(ssock->write_mutex);\n\treturn PJ_SUCCESS;\n    }\n\n    /* Get data and its length */\n    len = BIO_get_mem_data(ssock->ossl_wbio, &data);\n    if (len == 0) {\n\tpj_lock_release(ssock->write_mutex);\n\treturn PJ_SUCCESS;\n    }\n\n    /* Calculate buffer size needed, and align it to 8 */\n    needed_len = len + sizeof(write_data_t);\n    needed_len = ((needed_len + 7) >> 3) << 3;\n\n    /* Allocate buffer for send data */\n    wdata = alloc_send_data(ssock, needed_len);\n    if (wdata == NULL) {\n\tpj_lock_release(ssock->write_mutex);\n\treturn PJ_ENOMEM;\n    }\n\n    /* Copy the data and set its properties into the send data */\n    pj_ioqueue_op_key_init(&wdata->key, sizeof(pj_ioqueue_op_key_t));\n    wdata->key.user_data = wdata;\n    wdata->app_key = send_key;\n    wdata->record_len = needed_len;\n    wdata->data_len = len;\n    wdata->plain_data_len = orig_len;\n    wdata->flags = flags;\n    pj_memcpy(&wdata->data, data, len);\n\n    /* Reset write BIO */\n    (void)BIO_reset(ssock->ossl_wbio);\n\n    /* Ticket #1573: Don't hold mutex while calling PJLIB socket send(). */\n    pj_lock_release(ssock->write_mutex);\n\n    /* Send it */\n    if (ssock->param.sock_type == pj_SOCK_STREAM()) {\n\tstatus = pj_activesock_send(ssock->asock, &wdata->key, \n\t\t\t\t    wdata->data.content, &len,\n\t\t\t\t    flags);\n    } else {\n\tstatus = pj_activesock_sendto(ssock->asock, &wdata->key, \n\t\t\t\t      wdata->data.content, &len,\n\t\t\t\t      flags,\n\t\t\t\t      (pj_sockaddr_t*)&ssock->rem_addr,\n\t\t\t\t      ssock->addr_len);\n    }\n\n    if (status != PJ_EPENDING) {\n\t/* When the sending is not pending, remove the wdata from send\n\t * pending list.\n\t */\n\tpj_lock_acquire(ssock->write_mutex);\n\tfree_send_data(ssock, wdata);\n\tpj_lock_release(ssock->write_mutex);\n    }\n\n    return status;\n}\n\n\nstatic void on_timer(pj_timer_heap_t *th, struct pj_timer_entry *te)\n{\n    pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)te->user_data;\n    int timer_id = te->id;\n\n    te->id = TIMER_NONE;\n\n    PJ_UNUSED_ARG(th);\n\n    switch (timer_id) {\n    case TIMER_HANDSHAKE_TIMEOUT:\n\tPJ_LOG(1,(ssock->pool->obj_name, \"SSL timeout after %d.%ds\",\n\t\t  ssock->param.timeout.sec, ssock->param.timeout.msec));\n\n\ton_handshake_complete(ssock, PJ_ETIMEDOUT);\n\tbreak;\n    case TIMER_CLOSE:\n\tpj_ssl_sock_close(ssock);\n\tbreak;\n    default:\n\tpj_assert(!\"Unknown timer\");\n\tbreak;\n    }\n}\n\n\n/* Asynchronouse handshake */\nstatic pj_status_t do_handshake(pj_ssl_sock_t *ssock)\n{\n    pj_status_t status;\n    int err;\n\n    /* Perform SSL handshake */\n    pj_lock_acquire(ssock->write_mutex);\n    err = SSL_do_handshake(ssock->ossl_ssl);\n    pj_lock_release(ssock->write_mutex);\n\n    /* SSL_do_handshake() may put some pending data into SSL write BIO, \n     * flush it if any.\n     */\n    status = flush_write_bio(ssock, &ssock->handshake_op_key, 0, 0);\n    if (status != PJ_SUCCESS && status != PJ_EPENDING) {\n\treturn status;\n    }\n\n    if (err < 0) {\n\terr = SSL_get_error(ssock->ossl_ssl, err);\n\tif (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ) \n\t{\n\t    /* Handshake fails */\n\t    status = STATUS_FROM_SSL_ERR(ssock, err);\n\t    return status;\n\t}\n    }\n\n    /* Check if handshake has been completed */\n    if (SSL_is_init_finished(ssock->ossl_ssl)) {\n\tssock->ssl_state = SSL_STATE_ESTABLISHED;\n\treturn PJ_SUCCESS;\n    }\n\n    return PJ_EPENDING;\n}\n\n\n/*\n *******************************************************************\n * Active socket callbacks.\n *******************************************************************\n */\n\nstatic pj_bool_t asock_on_data_read (pj_activesock_t *asock,\n\t\t\t\t     void *data,\n\t\t\t\t     pj_size_t size,\n\t\t\t\t     pj_status_t status,\n\t\t\t\t     pj_size_t *remainder)\n{\n    pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)\n\t\t\t   pj_activesock_get_user_data(asock);\n    pj_size_t nwritten;\n\n    /* Socket error or closed */\n    if (data && size > 0) {\n\t/* Consume the whole data */\n\tnwritten = BIO_write(ssock->ossl_rbio, data, (int)size);\n\tif (nwritten < size) {\n\t    status = GET_SSL_STATUS(ssock);\n\t    goto on_error;\n\t}\n    }\n\n    /* Check if SSL handshake hasn't finished yet */\n    if (ssock->ssl_state == SSL_STATE_HANDSHAKING) {\n\tpj_bool_t ret = PJ_TRUE;\n\n\tif (status == PJ_SUCCESS)\n\t    status = do_handshake(ssock);\n\n\t/* Not pending is either success or failed */\n\tif (status != PJ_EPENDING)\n\t    ret = on_handshake_complete(ssock, status);\n\n\treturn ret;\n    }\n\n    /* See if there is any decrypted data for the application */\n    if (ssock->read_started) {\n\tdo {\n\t    read_data_t *buf = *(OFFSET_OF_READ_DATA_PTR(ssock, data));\n\t    void *data_ = (pj_int8_t*)buf->data + buf->len;\n\t    int size_ = (int)(ssock->read_size - buf->len);\n\n\t    /* SSL_read() may write some data to BIO write when re-negotiation\n\t     * is on progress, so let's protect it with write mutex.\n\t     */\n\t    pj_lock_acquire(ssock->write_mutex);\n\t    size_ = SSL_read(ssock->ossl_ssl, data_, size_);\n\t    pj_lock_release(ssock->write_mutex);\n\n\t    if (size_ > 0 || status != PJ_SUCCESS) {\n\t\tif (ssock->param.cb.on_data_read) {\n\t\t    pj_bool_t ret;\n\t\t    pj_size_t remainder_ = 0;\n\n\t\t    if (size_ > 0)\n\t\t\tbuf->len += size_;\n    \t\t\n\t\t    ret = (*ssock->param.cb.on_data_read)(ssock, buf->data,\n\t\t\t\t\t\t\t  buf->len, status,\n\t\t\t\t\t\t\t  &remainder_);\n\t\t    if (!ret) {\n\t\t\t/* We've been destroyed */\n\t\t\treturn PJ_FALSE;\n\t\t    }\n\n\t\t    /* Application may have left some data to be consumed \n\t\t     * later.\n\t\t     */\n\t\t    buf->len = remainder_;\n\t\t}\n\n\t\t/* Active socket signalled connection closed/error, this has\n\t\t * been signalled to the application along with any remaining\n\t\t * buffer. So, let's just reset SSL socket now.\n\t\t */\n\t\tif (status != PJ_SUCCESS) {\n\t\t    reset_ssl_sock_state(ssock);\n\t\t    return PJ_FALSE;\n\t\t}\n\n\t    } else {\n\n\t\tint err = SSL_get_error(ssock->ossl_ssl, size_);\n\t\t\n\t\t/* SSL might just return SSL_ERROR_WANT_READ in \n\t\t * re-negotiation.\n\t\t */\n\t\tif (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ)\n\t\t{\n\t\t    /* Reset SSL socket state, then return PJ_FALSE */\n\t\t    status = STATUS_FROM_SSL_ERR(ssock, err);\n\t\t    reset_ssl_sock_state(ssock);\n\t\t    goto on_error;\n\t\t}\n\n\t\tstatus = do_handshake(ssock);\n\t\tif (status == PJ_SUCCESS) {\n\t\t    /* Renegotiation completed */\n\n\t\t    /* Update certificates */\n\t\t    update_certs_info(ssock);\n\n\t\t    // Ticket #1573: Don't hold mutex while calling\n\t\t    //               PJLIB socket send(). \n\t\t    //pj_lock_acquire(ssock->write_mutex);\n\t\t    status = flush_delayed_send(ssock);\n\t\t    //pj_lock_release(ssock->write_mutex);\n\n\t\t    /* If flushing is ongoing, treat it as success */\n\t\t    if (status == PJ_EBUSY)\n\t\t\tstatus = PJ_SUCCESS;\n\n\t\t    if (status != PJ_SUCCESS && status != PJ_EPENDING) {\n\t\t\tPJ_PERROR(1,(ssock->pool->obj_name, status, \n\t\t\t\t     \"Failed to flush delayed send\"));\n\t\t\tgoto on_error;\n\t\t    }\n\t\t} else if (status != PJ_EPENDING) {\n\t\t    PJ_PERROR(1,(ssock->pool->obj_name, status, \n\t\t\t         \"Renegotiation failed\"));\n\t\t    goto on_error;\n\t\t}\n\n\t\tbreak;\n\t    }\n\t} while (1);\n    }\n\n    return PJ_TRUE;\n\non_error:\n    if (ssock->ssl_state == SSL_STATE_HANDSHAKING)\n\treturn on_handshake_complete(ssock, status);\n\n    if (ssock->read_started && ssock->param.cb.on_data_read) {\n\tpj_bool_t ret;\n\tret = (*ssock->param.cb.on_data_read)(ssock, NULL, 0, status,\n\t\t\t\t\t      remainder);\n\tif (!ret) {\n\t    /* We've been destroyed */\n\t    return PJ_FALSE;\n\t}\n    }\n\n    reset_ssl_sock_state(ssock);\n    return PJ_FALSE;\n}\n\n\nstatic pj_bool_t asock_on_data_sent (pj_activesock_t *asock,\n\t\t\t\t     pj_ioqueue_op_key_t *send_key,\n\t\t\t\t     pj_ssize_t sent)\n{\n    pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)\n\t\t\t   pj_activesock_get_user_data(asock);\n\n    PJ_UNUSED_ARG(send_key);\n    PJ_UNUSED_ARG(sent);\n\n    if (ssock->ssl_state == SSL_STATE_HANDSHAKING) {\n\t/* Initial handshaking */\n\tpj_status_t status;\n\t\n\tstatus = do_handshake(ssock);\n\t/* Not pending is either success or failed */\n\tif (status != PJ_EPENDING)\n\t    return on_handshake_complete(ssock, status);\n\n    } else if (send_key != &ssock->handshake_op_key) {\n\t/* Some data has been sent, notify application */\n\twrite_data_t *wdata = (write_data_t*)send_key->user_data;\n\tif (ssock->param.cb.on_data_sent) {\n\t    pj_bool_t ret;\n\t    pj_ssize_t sent_len;\n\n\t    sent_len = (sent > 0)? wdata->plain_data_len : sent;\n\t    ret = (*ssock->param.cb.on_data_sent)(ssock, wdata->app_key, \n\t\t\t\t\t\t  sent_len);\n\t    if (!ret) {\n\t\t/* We've been destroyed */\n\t\treturn PJ_FALSE;\n\t    }\n\t}\n\n\t/* Update write buffer state */\n\tpj_lock_acquire(ssock->write_mutex);\n\tfree_send_data(ssock, wdata);\n\tpj_lock_release(ssock->write_mutex);\n\n    } else {\n\t/* SSL re-negotiation is on-progress, just do nothing */\n    }\n\n    return PJ_TRUE;\n}\n\n\nstatic pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,\n\t\t\t\t\t   pj_sock_t newsock,\n\t\t\t\t\t   const pj_sockaddr_t *src_addr,\n\t\t\t\t\t   int src_addr_len)\n{\n    pj_ssl_sock_t *ssock_parent = (pj_ssl_sock_t*)\n\t\t\t\t  pj_activesock_get_user_data(asock);\n    pj_ssl_sock_t *ssock;\n    pj_activesock_cb asock_cb;\n    pj_activesock_cfg asock_cfg;\n    unsigned i;\n    pj_status_t status;\n\n    /* Create new SSL socket instance */\n    status = pj_ssl_sock_create(ssock_parent->pool,\n    \t\t\t\t&ssock_parent->newsock_param, &ssock);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Update new SSL socket attributes */\n    ssock->sock = newsock;\n    ssock->parent = ssock_parent;\n    ssock->is_server = PJ_TRUE;\n    if (ssock_parent->cert) {\n\tstatus = pj_ssl_sock_set_certificate(ssock, ssock->pool, \n\t\t\t\t\t     ssock_parent->cert);\n\tif (status != PJ_SUCCESS)\n\t    goto on_return;\n    }\n\n    /* Apply QoS, if specified */\n    status = pj_sock_apply_qos2(ssock->sock, ssock->param.qos_type,\n\t\t\t\t&ssock->param.qos_params, 1, \n\t\t\t\tssock->pool->obj_name, NULL);\n    if (status != PJ_SUCCESS && !ssock->param.qos_ignore_error)\n\tgoto on_return;\n\n    /* Apply socket options, if specified */\n    if (ssock->param.sockopt_params.cnt) {\n\tstatus = pj_sock_setsockopt_params(ssock->sock, \n\t\t\t\t\t   &ssock->param.sockopt_params);\n\tif (status != PJ_SUCCESS && !ssock->param.sockopt_ignore_error)\n\t    goto on_return;\n    }\n\n    /* Update local address */\n    ssock->addr_len = src_addr_len;\n    status = pj_sock_getsockname(ssock->sock, &ssock->local_addr, \n\t\t\t\t &ssock->addr_len);\n    if (status != PJ_SUCCESS) {\n\t/* This fails on few envs, e.g: win IOCP, just tolerate this and\n\t * use parent local address instead.\n\t */\n\tpj_sockaddr_cp(&ssock->local_addr, &ssock_parent->local_addr);\n    }\n\n    /* Set remote address */\n    pj_sockaddr_cp(&ssock->rem_addr, src_addr);\n\n    /* Create SSL context */\n    status = create_ssl(ssock);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Prepare read buffer */\n    ssock->asock_rbuf = (void**)pj_pool_calloc(ssock->pool, \n\t\t\t\t\t       ssock->param.async_cnt,\n\t\t\t\t\t       sizeof(void*));\n    for (i = 0; i<ssock->param.async_cnt; ++i) {\n\tssock->asock_rbuf[i] = (void*) pj_pool_alloc(\n\t\t\t\t\t    ssock->pool, \n\t\t\t\t\t    ssock->param.read_buffer_size + \n\t\t\t\t\t    sizeof(read_data_t*));\n    }\n\n    /* Create active socket */\n    pj_activesock_cfg_default(&asock_cfg);\n    asock_cfg.async_cnt = ssock->param.async_cnt;\n    asock_cfg.concurrency = ssock->param.concurrency;\n    asock_cfg.whole_data = PJ_TRUE;\n    \n    /* If listener socket has group lock, automatically create group lock\n     * for the new socket.\n     */\n    if (ssock_parent->param.grp_lock) {\n\tpj_grp_lock_t *glock;\n\n\tstatus = pj_grp_lock_create(ssock->pool, NULL, &glock);\n\tif (status != PJ_SUCCESS)\n\t    goto on_return;\n\n\t/* Temporarily add ref the group lock until active socket creation,\n\t * to make sure that group lock is destroyed if the active socket\n\t * creation fails.\n\t */\n\tpj_grp_lock_add_ref(glock);\n\tasock_cfg.grp_lock = ssock->param.grp_lock = glock;\n    }\n\n    pj_bzero(&asock_cb, sizeof(asock_cb));\n    asock_cb.on_data_read = asock_on_data_read;\n    asock_cb.on_data_sent = asock_on_data_sent;\n\n    status = pj_activesock_create(ssock->pool,\n\t\t\t\t  ssock->sock, \n\t\t\t\t  ssock->param.sock_type,\n\t\t\t\t  &asock_cfg,\n\t\t\t\t  ssock->param.ioqueue, \n\t\t\t\t  &asock_cb,\n\t\t\t\t  ssock,\n\t\t\t\t  &ssock->asock);\n\n    /* This will destroy the group lock if active socket creation fails */\n    if (asock_cfg.grp_lock) {\n\tpj_grp_lock_dec_ref(asock_cfg.grp_lock);\n    }\n\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Start read */\n    status = pj_activesock_start_read2(ssock->asock, ssock->pool, \n\t\t\t\t       (unsigned)ssock->param.read_buffer_size,\n\t\t\t\t       ssock->asock_rbuf,\n\t\t\t\t       PJ_IOQUEUE_ALWAYS_ASYNC);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Prepare write/send state */\n    pj_assert(ssock->send_buf.max_len == 0);\n    ssock->send_buf.buf = (char*)\n\t\t\t  pj_pool_alloc(ssock->pool, \n\t\t\t\t\tssock->param.send_buffer_size);\n    ssock->send_buf.max_len = ssock->param.send_buffer_size;\n    ssock->send_buf.start = ssock->send_buf.buf;\n    ssock->send_buf.len = 0;\n\n    /* Start handshake timer */\n    if (ssock->param.timer_heap && (ssock->param.timeout.sec != 0 ||\n\tssock->param.timeout.msec != 0))\n    {\n\tpj_assert(ssock->timer.id == TIMER_NONE);\n\tssock->timer.id = TIMER_HANDSHAKE_TIMEOUT;\n\tstatus = pj_timer_heap_schedule(ssock->param.timer_heap, \n\t\t\t\t        &ssock->timer,\n\t\t\t\t\t&ssock->param.timeout);\n\tif (status != PJ_SUCCESS)\n\t    ssock->timer.id = TIMER_NONE;\n    }\n\n    /* Start SSL handshake */\n    ssock->ssl_state = SSL_STATE_HANDSHAKING;\n    SSL_set_accept_state(ssock->ossl_ssl);\n    status = do_handshake(ssock);\n\non_return:\n    if (ssock && status != PJ_EPENDING)\n\ton_handshake_complete(ssock, status);\n\n    /* Must return PJ_TRUE whatever happened, as active socket must \n     * continue listening.\n     */\n    return PJ_TRUE;\n}\n\n\nstatic pj_bool_t asock_on_connect_complete (pj_activesock_t *asock,\n\t\t\t\t\t    pj_status_t status)\n{\n    pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)\n\t\t\t   pj_activesock_get_user_data(asock);\n    unsigned i;\n\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Update local address */\n    ssock->addr_len = sizeof(pj_sockaddr);\n    status = pj_sock_getsockname(ssock->sock, &ssock->local_addr, \n\t\t\t\t &ssock->addr_len);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Create SSL context */\n    status = create_ssl(ssock);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Prepare read buffer */\n    ssock->asock_rbuf = (void**)pj_pool_calloc(ssock->pool, \n\t\t\t\t\t       ssock->param.async_cnt,\n\t\t\t\t\t       sizeof(void*));\n    for (i = 0; i<ssock->param.async_cnt; ++i) {\n\tssock->asock_rbuf[i] = (void*) pj_pool_alloc(\n\t\t\t\t\t    ssock->pool, \n\t\t\t\t\t    ssock->param.read_buffer_size + \n\t\t\t\t\t    sizeof(read_data_t*));\n    }\n\n    /* Start read */\n    status = pj_activesock_start_read2(ssock->asock, ssock->pool, \n\t\t\t\t       (unsigned)ssock->param.read_buffer_size,\n\t\t\t\t       ssock->asock_rbuf,\n\t\t\t\t       PJ_IOQUEUE_ALWAYS_ASYNC);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Prepare write/send state */\n    pj_assert(ssock->send_buf.max_len == 0);\n    ssock->send_buf.buf = (char*)\n\t\t\t     pj_pool_alloc(ssock->pool, \n\t\t\t\t\t   ssock->param.send_buffer_size);\n    ssock->send_buf.max_len = ssock->param.send_buffer_size;\n    ssock->send_buf.start = ssock->send_buf.buf;\n    ssock->send_buf.len = 0;\n\n#ifdef SSL_set_tlsext_host_name\n    /* Set server name to connect */\n    if (ssock->param.server_name.slen) {\n\t/* Server name is null terminated already */\n\tif (!SSL_set_tlsext_host_name(ssock->ossl_ssl, \n\t\t\t\t      ssock->param.server_name.ptr))\n\t{\n\t    char err_str[PJ_ERR_MSG_SIZE];\n\n\t    ERR_error_string_n(ERR_get_error(), err_str, sizeof(err_str));\n\t    PJ_LOG(3,(ssock->pool->obj_name, \"SSL_set_tlsext_host_name() \"\n\t\t\"failed: %s\", err_str));\n\t}\n    }\n#endif\n\n    /* Start SSL handshake */\n    ssock->ssl_state = SSL_STATE_HANDSHAKING;\n    SSL_set_connect_state(ssock->ossl_ssl);\n\n    status = do_handshake(ssock);\n    if (status != PJ_EPENDING)\n\tgoto on_return;\n\n    return PJ_TRUE;\n\non_return:\n    return on_handshake_complete(ssock, status);\n}\n\n\n\n/*\n *******************************************************************\n * API\n *******************************************************************\n */\n\n/* Load credentials from files. */\nPJ_DEF(pj_status_t) pj_ssl_cert_load_from_files (pj_pool_t *pool,\n\t\t\t\t\t\t const pj_str_t *CA_file,\n\t\t\t\t\t\t const pj_str_t *cert_file,\n\t\t\t\t\t\t const pj_str_t *privkey_file,\n\t\t\t\t\t\t const pj_str_t *privkey_pass,\n\t\t\t\t\t\t pj_ssl_cert_t **p_cert)\n{\n    return pj_ssl_cert_load_from_files2(pool, CA_file, NULL, cert_file,\n\t\t\t\t\tprivkey_file, privkey_pass, p_cert);\n}\n\nPJ_DEF(pj_status_t) pj_ssl_cert_load_from_files2(pj_pool_t *pool,\n\t\t\t\t\t\t const pj_str_t *CA_file,\n\t\t\t\t\t\t const pj_str_t *CA_path,\n\t\t\t\t\t\t const pj_str_t *cert_file,\n\t\t\t\t\t\t const pj_str_t *privkey_file,\n\t\t\t\t\t\t const pj_str_t *privkey_pass,\n\t\t\t\t\t\t pj_ssl_cert_t **p_cert)\n{\n    pj_ssl_cert_t *cert;\n\n    PJ_ASSERT_RETURN(pool && (CA_file || CA_path) && cert_file &&\n\t\t     privkey_file,\n\t\t     PJ_EINVAL);\n\n    cert = PJ_POOL_ZALLOC_T(pool, pj_ssl_cert_t);\n    if (CA_file) {\n    \tpj_strdup_with_null(pool, &cert->CA_file, CA_file);\n    }\n    if (CA_path) {\n    \tpj_strdup_with_null(pool, &cert->CA_path, CA_path);\n    }\n    pj_strdup_with_null(pool, &cert->cert_file, cert_file);\n    pj_strdup_with_null(pool, &cert->privkey_file, privkey_file);\n    pj_strdup_with_null(pool, &cert->privkey_pass, privkey_pass);\n\n    *p_cert = cert;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Set SSL socket credentials. */\nPJ_DEF(pj_status_t) pj_ssl_sock_set_certificate(\n\t\t\t\t\t    pj_ssl_sock_t *ssock,\n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    const pj_ssl_cert_t *cert)\n{\n    pj_ssl_cert_t *cert_;\n\n    PJ_ASSERT_RETURN(ssock && pool && cert, PJ_EINVAL);\n\n    cert_ = PJ_POOL_ZALLOC_T(pool, pj_ssl_cert_t);\n    pj_memcpy(cert_, cert, sizeof(pj_ssl_cert_t));\n    pj_strdup_with_null(pool, &cert_->CA_file, &cert->CA_file);\n    pj_strdup_with_null(pool, &cert_->CA_path, &cert->CA_path);\n    pj_strdup_with_null(pool, &cert_->cert_file, &cert->cert_file);\n    pj_strdup_with_null(pool, &cert_->privkey_file, &cert->privkey_file);\n    pj_strdup_with_null(pool, &cert_->privkey_pass, &cert->privkey_pass);\n\n    ssock->cert = cert_;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Get available ciphers. */\nPJ_DEF(pj_status_t) pj_ssl_cipher_get_availables(pj_ssl_cipher ciphers[],\n\t\t\t\t\t         unsigned *cipher_num)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(ciphers && cipher_num, PJ_EINVAL);\n\n    if (openssl_cipher_num == 0) {\n\tinit_openssl();\n\tshutdown_openssl();\n    }\n\n    if (openssl_cipher_num == 0) {\n\t*cipher_num = 0;\n\treturn PJ_ENOTFOUND;\n    }\n\n    *cipher_num = PJ_MIN(*cipher_num, openssl_cipher_num);\n\n    for (i = 0; i < *cipher_num; ++i)\n\tciphers[i] = openssl_ciphers[i].id;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Get cipher name string */\nPJ_DEF(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher)\n{\n    unsigned i;\n\n    if (openssl_cipher_num == 0) {\n\tinit_openssl();\n\tshutdown_openssl();\n    }\n\n    for (i = 0; i < openssl_cipher_num; ++i) {\n\tif (cipher == openssl_ciphers[i].id)\n\t    return openssl_ciphers[i].name;\n    }\n\n    return NULL;\n}\n\n/* Get cipher identifier */\nPJ_DEF(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name)\n{\n    unsigned i;\n\n    if (openssl_cipher_num == 0) {\n        init_openssl();\n        shutdown_openssl();\n    }\n\n    for (i = 0; i < openssl_cipher_num; ++i) {\n        if (!pj_ansi_stricmp(openssl_ciphers[i].name, cipher_name))\n            return openssl_ciphers[i].id;\n    }\n\n    return PJ_TLS_UNKNOWN_CIPHER;\n}\n\n/* Check if the specified cipher is supported by SSL/TLS backend. */\nPJ_DEF(pj_bool_t) pj_ssl_cipher_is_supported(pj_ssl_cipher cipher)\n{\n    unsigned i;\n\n    if (openssl_cipher_num == 0) {\n\tinit_openssl();\n\tshutdown_openssl();\n    }\n\n    for (i = 0; i < openssl_cipher_num; ++i) {\n\tif (cipher == openssl_ciphers[i].id)\n\t    return PJ_TRUE;\n    }\n\n    return PJ_FALSE;\n}\n\n\n/*\n * Create SSL socket instance. \n */\nPJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,\n\t\t\t\t\tconst pj_ssl_sock_param *param,\n\t\t\t\t\tpj_ssl_sock_t **p_ssock)\n{\n    pj_ssl_sock_t *ssock;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && param && p_ssock, PJ_EINVAL);\n    PJ_ASSERT_RETURN(param->sock_type == pj_SOCK_STREAM(), PJ_ENOTSUP);\n\n    pool = pj_pool_create(pool->factory, \"ssl%p\", 512, 512, NULL);\n\n    /* Create secure socket */\n    ssock = PJ_POOL_ZALLOC_T(pool, pj_ssl_sock_t);\n    ssock->pool = pool;\n    ssock->sock = PJ_INVALID_SOCKET;\n    ssock->ssl_state = SSL_STATE_NULL;\n    pj_list_init(&ssock->write_pending);\n    pj_list_init(&ssock->write_pending_empty);\n    pj_list_init(&ssock->send_pending);\n    pj_timer_entry_init(&ssock->timer, 0, ssock, &on_timer);\n    pj_ioqueue_op_key_init(&ssock->handshake_op_key,\n\t\t\t   sizeof(pj_ioqueue_op_key_t));\n\n    /* Create secure socket mutex */\n    status = pj_lock_create_recursive_mutex(pool, pool->obj_name,\n\t\t\t\t\t    &ssock->write_mutex);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Create socket state mutex */\n    status = pj_lock_create_recursive_mutex(pool, pool->obj_name,\n\t\t\t\t\t    &ssock->state_mutex);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Init secure socket param */\n    pj_ssl_sock_param_copy(pool, &ssock->param, param);\n    ssock->param.read_buffer_size = ((ssock->param.read_buffer_size+7)>>3)<<3;\n\n    /* Finally */\n    *p_ssock = ssock;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Close the secure socket. This will unregister the socket from the\n * ioqueue and ultimately close the socket.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock)\n{\n    pj_pool_t *pool;\n\n    PJ_ASSERT_RETURN(ssock, PJ_EINVAL);\n\n    if (!ssock->pool)\n\treturn PJ_SUCCESS;\n\n    if (ssock->timer.id != TIMER_NONE) {\n\tpj_timer_heap_cancel(ssock->param.timer_heap, &ssock->timer);\n\tssock->timer.id = TIMER_NONE;\n    }\n\n    reset_ssl_sock_state(ssock);\n    pj_lock_destroy(ssock->write_mutex);\n    pj_lock_destroy(ssock->state_mutex);\n    \n    pool = ssock->pool;\n    ssock->pool = NULL;\n    if (pool)\n\tpj_pool_release(pool);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Associate arbitrary data with the secure socket.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_set_user_data(pj_ssl_sock_t *ssock,\n\t\t\t\t\t      void *user_data)\n{\n    PJ_ASSERT_RETURN(ssock, PJ_EINVAL);\n\n    ssock->param.user_data = user_data;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Retrieve the user data previously associated with this secure\n * socket.\n */\nPJ_DEF(void*) pj_ssl_sock_get_user_data(pj_ssl_sock_t *ssock)\n{\n    PJ_ASSERT_RETURN(ssock, NULL);\n\n    return ssock->param.user_data;\n}\n\n\n/*\n * Retrieve the local address and port used by specified SSL socket.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_get_info (pj_ssl_sock_t *ssock,\n\t\t\t\t\t  pj_ssl_sock_info *info)\n{\n    pj_bzero(info, sizeof(*info));\n\n    /* Established flag */\n    info->established = (ssock->ssl_state == SSL_STATE_ESTABLISHED);\n\n    /* Protocol */\n    info->proto = ssock->param.proto;\n\n    /* Local address */\n    pj_sockaddr_cp(&info->local_addr, &ssock->local_addr);\n    \n    if (info->established) {\n\tconst SSL_CIPHER *cipher;\n\n\t/* Current cipher */\n\tcipher = SSL_get_current_cipher(ssock->ossl_ssl);\n\tinfo->cipher = (SSL_CIPHER_get_id(cipher) & 0x00FFFFFF);\n\n\t/* Remote address */\n\tpj_sockaddr_cp(&info->remote_addr, &ssock->rem_addr);\n\n\t/* Certificates info */\n\tinfo->local_cert_info = &ssock->local_cert_info;\n\tinfo->remote_cert_info = &ssock->remote_cert_info;\n\n\t/* Verification status */\n\tinfo->verify_status = ssock->verify_status;\n    }\n\n    /* Last known OpenSSL error code */\n    info->last_native_err = ssock->last_err;\n\n    /* Group lock */\n    info->grp_lock = ssock->param.grp_lock;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Starts read operation on this secure socket.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_start_read (pj_ssl_sock_t *ssock,\n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    unsigned buff_size,\n\t\t\t\t\t    pj_uint32_t flags)\n{\n    void **readbuf;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(ssock && pool && buff_size, PJ_EINVAL);\n\n    if (ssock->ssl_state != SSL_STATE_ESTABLISHED) \n\treturn PJ_EINVALIDOP;\n\n    readbuf = (void**) pj_pool_calloc(pool, ssock->param.async_cnt, \n\t\t\t\t      sizeof(void*));\n\n    for (i=0; i<ssock->param.async_cnt; ++i) {\n\treadbuf[i] = pj_pool_alloc(pool, buff_size);\n    }\n\n    return pj_ssl_sock_start_read2(ssock, pool, buff_size, \n\t\t\t\t   readbuf, flags);\n}\n\n\n/*\n * Same as #pj_ssl_sock_start_read(), except that the application\n * supplies the buffers for the read operation so that the acive socket\n * does not have to allocate the buffers.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_start_read2 (pj_ssl_sock_t *ssock,\n\t\t\t\t\t     pj_pool_t *pool,\n\t\t\t\t\t     unsigned buff_size,\n\t\t\t\t\t     void *readbuf[],\n\t\t\t\t\t     pj_uint32_t flags)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(ssock && pool && buff_size && readbuf, PJ_EINVAL);\n\n    if (ssock->ssl_state != SSL_STATE_ESTABLISHED) \n\treturn PJ_EINVALIDOP;\n\n    /* Create SSL socket read buffer */\n    ssock->ssock_rbuf = (read_data_t*)pj_pool_calloc(pool, \n\t\t\t\t\t       ssock->param.async_cnt,\n\t\t\t\t\t       sizeof(read_data_t));\n\n    /* Store SSL socket read buffer pointer in the activesock read buffer */\n    for (i=0; i<ssock->param.async_cnt; ++i) {\n\tread_data_t **p_ssock_rbuf = \n\t\t\tOFFSET_OF_READ_DATA_PTR(ssock, ssock->asock_rbuf[i]);\n\n\tssock->ssock_rbuf[i].data = readbuf[i];\n\tssock->ssock_rbuf[i].len = 0;\n\n\t*p_ssock_rbuf = &ssock->ssock_rbuf[i];\n    }\n\n    ssock->read_size = buff_size;\n    ssock->read_started = PJ_TRUE;\n    ssock->read_flags = flags;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Same as pj_ssl_sock_start_read(), except that this function is used\n * only for datagram sockets, and it will trigger \\a on_data_recvfrom()\n * callback instead.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_start_recvfrom (pj_ssl_sock_t *ssock,\n\t\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\t\tunsigned buff_size,\n\t\t\t\t\t\tpj_uint32_t flags)\n{\n    PJ_UNUSED_ARG(ssock);\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(buff_size);\n    PJ_UNUSED_ARG(flags);\n\n    return PJ_ENOTSUP;\n}\n\n\n/*\n * Same as #pj_ssl_sock_start_recvfrom() except that the recvfrom() \n * operation takes the buffer from the argument rather than creating\n * new ones.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_start_recvfrom2 (pj_ssl_sock_t *ssock,\n\t\t\t\t\t\t pj_pool_t *pool,\n\t\t\t\t\t\t unsigned buff_size,\n\t\t\t\t\t\t void *readbuf[],\n\t\t\t\t\t\t pj_uint32_t flags)\n{\n    PJ_UNUSED_ARG(ssock);\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(buff_size);\n    PJ_UNUSED_ARG(readbuf);\n    PJ_UNUSED_ARG(flags);\n\n    return PJ_ENOTSUP;\n}\n\n/* Write plain data to SSL and flush write BIO. */\nstatic pj_status_t ssl_write(pj_ssl_sock_t *ssock, \n\t\t\t     pj_ioqueue_op_key_t *send_key,\n\t\t\t     const void *data,\n\t\t\t     pj_ssize_t size,\n\t\t\t     unsigned flags)\n{\n    pj_status_t status;\n    int nwritten;\n\n    /* Write the plain data to SSL, after SSL encrypts it, write BIO will\n     * contain the secured data to be sent via socket. Note that re-\n     * negotitation may be on progress, so sending data should be delayed\n     * until re-negotiation is completed.\n     */\n    pj_lock_acquire(ssock->write_mutex);\n    nwritten = SSL_write(ssock->ossl_ssl, data, (int)size);\n    pj_lock_release(ssock->write_mutex);\n    \n    if (nwritten == size) {\n\t/* All data written, flush write BIO to network socket */\n\tstatus = flush_write_bio(ssock, send_key, size, flags);\n    } else if (nwritten <= 0) {\n\t/* SSL failed to process the data, it may just that re-negotiation\n\t * is on progress.\n\t */\n\tint err;\n\terr = SSL_get_error(ssock->ossl_ssl, nwritten);\n\tif (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_NONE) {\n\t    /* Re-negotiation is on progress, flush re-negotiation data */\n\t    status = flush_write_bio(ssock, &ssock->handshake_op_key, 0, 0);\n\t    if (status == PJ_SUCCESS || status == PJ_EPENDING)\n\t\t/* Just return PJ_EBUSY when re-negotiation is on progress */\n\t\tstatus = PJ_EBUSY;\n\t} else {\n\t    /* Some problem occured */\n\t    status = STATUS_FROM_SSL_ERR(ssock, err);\n\t}\n    } else {\n\t/* nwritten < *size, shouldn't happen, unless write BIO cannot hold \n\t * the whole secured data, perhaps because of insufficient memory.\n\t */\n\tstatus = PJ_ENOMEM;\n    }\n\n    return status;\n}\n\n/* Flush delayed data sending in the write pending list. */\nstatic pj_status_t flush_delayed_send(pj_ssl_sock_t *ssock)\n{\n    /* Check for another ongoing flush */\n    if (ssock->flushing_write_pend)\n\treturn PJ_EBUSY;\n\n    pj_lock_acquire(ssock->write_mutex);\n\n    /* Again, check for another ongoing flush */\n    if (ssock->flushing_write_pend) {\n\tpj_lock_release(ssock->write_mutex);\n\treturn PJ_EBUSY;\n    }\n\n    /* Set ongoing flush flag */\n    ssock->flushing_write_pend = PJ_TRUE;\n\n    while (!pj_list_empty(&ssock->write_pending)) {\n        write_data_t *wp;\n\tpj_status_t status;\n\n\twp = ssock->write_pending.next;\n\n\t/* Ticket #1573: Don't hold mutex while calling socket send. */\n\tpj_lock_release(ssock->write_mutex);\n\n\tstatus = ssl_write(ssock, &wp->key, wp->data.ptr, \n\t\t\t   wp->plain_data_len, wp->flags);\n\tif (status != PJ_SUCCESS) {\n\t    /* Reset ongoing flush flag first. */\n\t    ssock->flushing_write_pend = PJ_FALSE;\n\t    return status;\n\t}\n\n\tpj_lock_acquire(ssock->write_mutex);\n\tpj_list_erase(wp);\n\tpj_list_push_back(&ssock->write_pending_empty, wp);\n    }\n\n    /* Reset ongoing flush flag */\n    ssock->flushing_write_pend = PJ_FALSE;\n\n    pj_lock_release(ssock->write_mutex);\n\n    return PJ_SUCCESS;\n}\n\n/* Sending is delayed, push back the sending data into pending list. */\nstatic pj_status_t delay_send (pj_ssl_sock_t *ssock,\n\t\t\t       pj_ioqueue_op_key_t *send_key,\n\t\t\t       const void *data,\n\t\t\t       pj_ssize_t size,\n\t\t\t       unsigned flags)\n{\n    write_data_t *wp;\n\n    pj_lock_acquire(ssock->write_mutex);\n\n    /* Init write pending instance */\n    if (!pj_list_empty(&ssock->write_pending_empty)) {\n\twp = ssock->write_pending_empty.next;\n\tpj_list_erase(wp);\n    } else {\n\twp = PJ_POOL_ZALLOC_T(ssock->pool, write_data_t);\n    }\n\n    wp->app_key = send_key;\n    wp->plain_data_len = size;\n    wp->data.ptr = data;\n    wp->flags = flags;\n\n    pj_list_push_back(&ssock->write_pending, wp);\n    \n    pj_lock_release(ssock->write_mutex);\n\n    /* Must return PJ_EPENDING */\n    return PJ_EPENDING;\n}\n\n/**\n * Send data using the socket.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_send (pj_ssl_sock_t *ssock,\n\t\t\t\t      pj_ioqueue_op_key_t *send_key,\n\t\t\t\t      const void *data,\n\t\t\t\t      pj_ssize_t *size,\n\t\t\t\t      unsigned flags)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(ssock && data && size && (*size>0), PJ_EINVAL);\n\n    pj_lock_acquire(ssock->state_mutex);\n\n    if (ssock->ssl_state != SSL_STATE_ESTABLISHED) {\n        status = PJ_EINVALIDOP;\n        goto on_return;\n    }\n\n    // Ticket #1573: Don't hold mutex while calling PJLIB socket send().\n    //pj_lock_acquire(ssock->write_mutex);\n\n    /* Flush delayed send first. Sending data might be delayed when \n     * re-negotiation is on-progress.\n     */\n    status = flush_delayed_send(ssock);\n    if (status == PJ_EBUSY) {\n\t/* Re-negotiation or flushing is on progress, delay sending */\n\tstatus = delay_send(ssock, send_key, data, *size, flags);\n\tgoto on_return;\n    } else if (status != PJ_SUCCESS) {\n\tgoto on_return;\n    }\n\n    /* Write data to SSL */\n    status = ssl_write(ssock, send_key, data, *size, flags);\n    if (status == PJ_EBUSY) {\n\t/* Re-negotiation is on progress, delay sending */\n\tstatus = delay_send(ssock, send_key, data, *size, flags);\n    }\n\non_return:\n    //pj_lock_release(ssock->write_mutex);\n    pj_lock_release(ssock->state_mutex);\n    return status;\n}\n\n\n/**\n * Send datagram using the socket.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_sendto (pj_ssl_sock_t *ssock,\n\t\t\t\t\tpj_ioqueue_op_key_t *send_key,\n\t\t\t\t\tconst void *data,\n\t\t\t\t\tpj_ssize_t *size,\n\t\t\t\t\tunsigned flags,\n\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\tint addr_len)\n{\n    PJ_UNUSED_ARG(ssock);\n    PJ_UNUSED_ARG(send_key);\n    PJ_UNUSED_ARG(data);\n    PJ_UNUSED_ARG(size);\n    PJ_UNUSED_ARG(flags);\n    PJ_UNUSED_ARG(addr);\n    PJ_UNUSED_ARG(addr_len);\n\n    return PJ_ENOTSUP;\n}\n\n\n/**\n * Starts asynchronous socket accept() operations on this secure socket. \n */\nPJ_DEF(pj_status_t) pj_ssl_sock_start_accept (pj_ssl_sock_t *ssock,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      const pj_sockaddr_t *localaddr,\n\t\t\t\t\t      int addr_len)\n{\n    return pj_ssl_sock_start_accept2(ssock, pool, localaddr, addr_len,\n    \t\t\t\t     &ssock->param);\n}\n\n\n/**\n * Same as #pj_ssl_sock_start_accept(), but application provides parameter\n * for new accepted secure sockets.\n */\nPJ_DEF(pj_status_t)\npj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock,\n\t\t\t  pj_pool_t *pool,\n\t\t\t  const pj_sockaddr_t *localaddr,\n\t\t\t  int addr_len,\n\t\t\t  const pj_ssl_sock_param *newsock_param)\n{\n    pj_activesock_cb asock_cb;\n    pj_activesock_cfg asock_cfg;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(ssock && pool && localaddr && addr_len, PJ_EINVAL);\n\n    /* Verify new socket parameters */\n    if (newsock_param->grp_lock != ssock->param.grp_lock ||\n        newsock_param->sock_af != ssock->param.sock_af ||\n        newsock_param->sock_type != ssock->param.sock_type)\n    {\n        return PJ_EINVAL;\n    }\n\n    /* Create socket */\n    status = pj_sock_socket(ssock->param.sock_af, ssock->param.sock_type, 0, \n\t\t\t    &ssock->sock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Apply SO_REUSEADDR */\n    if (ssock->param.reuse_addr) {\n\tint enabled = 1;\n\tstatus = pj_sock_setsockopt(ssock->sock, pj_SOL_SOCKET(),\n\t\t\t\t    pj_SO_REUSEADDR(),\n\t\t\t\t    &enabled, sizeof(enabled));\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(ssock->pool->obj_name, status,\n\t\t         \"Warning: error applying SO_REUSEADDR\"));\n\t}\n    }\n\n    /* Apply QoS, if specified */\n    status = pj_sock_apply_qos2(ssock->sock, ssock->param.qos_type,\n\t\t\t\t&ssock->param.qos_params, 2, \n\t\t\t\tssock->pool->obj_name, NULL);\n\n    if (status != PJ_SUCCESS && !ssock->param.qos_ignore_error)\n\tgoto on_error;\n\n    /* Apply socket options, if specified */\n    if (ssock->param.sockopt_params.cnt) {\n\tstatus = pj_sock_setsockopt_params(ssock->sock, \n\t\t\t\t\t   &ssock->param.sockopt_params);\n\n\tif (status != PJ_SUCCESS && !ssock->param.sockopt_ignore_error)\n\t    goto on_error;\n    }\n\n    /* Bind socket */\n    status = pj_sock_bind(ssock->sock, localaddr, addr_len);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Start listening to the address */\n    status = pj_sock_listen(ssock->sock, PJ_SOMAXCONN);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Create active socket */\n    pj_activesock_cfg_default(&asock_cfg);\n    asock_cfg.async_cnt = ssock->param.async_cnt;\n    asock_cfg.concurrency = ssock->param.concurrency;\n    asock_cfg.whole_data = PJ_TRUE;\n    asock_cfg.grp_lock = ssock->param.grp_lock;\n\n    pj_bzero(&asock_cb, sizeof(asock_cb));\n    asock_cb.on_accept_complete = asock_on_accept_complete;\n\n    status = pj_activesock_create(pool,\n\t\t\t\t  ssock->sock, \n\t\t\t\t  ssock->param.sock_type,\n\t\t\t\t  &asock_cfg,\n\t\t\t\t  ssock->param.ioqueue, \n\t\t\t\t  &asock_cb,\n\t\t\t\t  ssock,\n\t\t\t\t  &ssock->asock);\n\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Start accepting */\n    pj_ssl_sock_param_copy(pool, &ssock->newsock_param, newsock_param);\n    status = pj_activesock_start_accept(ssock->asock, pool);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Update local address */\n    ssock->addr_len = addr_len;\n    status = pj_sock_getsockname(ssock->sock, &ssock->local_addr, \n\t\t\t\t &ssock->addr_len);\n    if (status != PJ_SUCCESS)\n\tpj_sockaddr_cp(&ssock->local_addr, localaddr);\n\n    ssock->is_server = PJ_TRUE;\n\n    return PJ_SUCCESS;\n\non_error:\n    reset_ssl_sock_state(ssock);\n    return status;\n}\n\n\n/**\n * Starts asynchronous socket connect() operation.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_start_connect( pj_ssl_sock_t *ssock,\n\t\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t\t       const pj_sockaddr_t *localaddr,\n\t\t\t\t\t       const pj_sockaddr_t *remaddr,\n\t\t\t\t\t       int addr_len)\n{\n    pj_activesock_cb asock_cb;\n    pj_activesock_cfg asock_cfg;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(ssock && pool && localaddr && remaddr && addr_len,\n\t\t     PJ_EINVAL);\n\n    /* Create socket */\n    status = pj_sock_socket(ssock->param.sock_af, ssock->param.sock_type, 0, \n\t\t\t    &ssock->sock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Apply QoS, if specified */\n    status = pj_sock_apply_qos2(ssock->sock, ssock->param.qos_type,\n\t\t\t\t&ssock->param.qos_params, 2, \n\t\t\t\tssock->pool->obj_name, NULL);\n    if (status != PJ_SUCCESS && !ssock->param.qos_ignore_error)\n\tgoto on_error;\n\n    /* Apply socket options, if specified */\n    if (ssock->param.sockopt_params.cnt) {\n\tstatus = pj_sock_setsockopt_params(ssock->sock, \n\t\t\t\t\t   &ssock->param.sockopt_params);\n\n\tif (status != PJ_SUCCESS && !ssock->param.sockopt_ignore_error)\n\t    goto on_error;\n    }\n\n    /* Bind socket */\n    status = pj_sock_bind(ssock->sock, localaddr, addr_len);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Create active socket */\n    pj_activesock_cfg_default(&asock_cfg);\n    asock_cfg.async_cnt = ssock->param.async_cnt;\n    asock_cfg.concurrency = ssock->param.concurrency;\n    asock_cfg.whole_data = PJ_TRUE;\n    asock_cfg.grp_lock = ssock->param.grp_lock;\n\n    pj_bzero(&asock_cb, sizeof(asock_cb));\n    asock_cb.on_connect_complete = asock_on_connect_complete;\n    asock_cb.on_data_read = asock_on_data_read;\n    asock_cb.on_data_sent = asock_on_data_sent;\n\n    status = pj_activesock_create(pool,\n\t\t\t\t  ssock->sock, \n\t\t\t\t  ssock->param.sock_type,\n\t\t\t\t  &asock_cfg,\n\t\t\t\t  ssock->param.ioqueue, \n\t\t\t\t  &asock_cb,\n\t\t\t\t  ssock,\n\t\t\t\t  &ssock->asock);\n\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Save remote address */\n    pj_sockaddr_cp(&ssock->rem_addr, remaddr);\n\n    /* Start timer */\n    if (ssock->param.timer_heap && (ssock->param.timeout.sec != 0 ||\n\tssock->param.timeout.msec != 0))\n    {\n\tpj_assert(ssock->timer.id == TIMER_NONE);\n\tssock->timer.id = TIMER_HANDSHAKE_TIMEOUT;\n\tstatus = pj_timer_heap_schedule(ssock->param.timer_heap,\n\t\t\t\t\t&ssock->timer,\n\t\t\t\t        &ssock->param.timeout);\n\tif (status != PJ_SUCCESS)\n\t    ssock->timer.id = TIMER_NONE;\n    }\n\n    status = pj_activesock_start_connect(ssock->asock, pool, remaddr,\n\t\t\t\t\t addr_len);\n\n    if (status == PJ_SUCCESS)\n\tasock_on_connect_complete(ssock->asock, PJ_SUCCESS);\n    else if (status != PJ_EPENDING)\n\tgoto on_error;\n\n    /* Update local address */\n    ssock->addr_len = addr_len;\n    status = pj_sock_getsockname(ssock->sock, &ssock->local_addr,\n\t\t\t\t &ssock->addr_len);\n    /* Note that we may not get an IP address here. This can\n     * happen for example on Windows, where getsockname()\n     * would return 0.0.0.0 if socket has just started the\n     * async connect. In this case, just leave the local\n     * address with 0.0.0.0 for now; it will be updated\n     * once the socket is established.\n     */\n\n    /* Update SSL state */\n    ssock->is_server = PJ_FALSE;\n\n    return PJ_EPENDING;\n\non_error:\n    reset_ssl_sock_state(ssock);\n    return status;\n}\n\n\nPJ_DEF(pj_status_t) pj_ssl_sock_renegotiate(pj_ssl_sock_t *ssock)\n{\n    int ret;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(ssock, PJ_EINVAL);\n\n    if (ssock->ssl_state != SSL_STATE_ESTABLISHED) \n\treturn PJ_EINVALIDOP;\n\n    if (SSL_renegotiate_pending(ssock->ossl_ssl))\n\treturn PJ_EPENDING;\n\n    ret = SSL_renegotiate(ssock->ossl_ssl);\n    if (ret <= 0) {\n\tstatus = GET_SSL_STATUS(ssock);\n    } else {\n\tstatus = do_handshake(ssock);\n    }\n\n    return status;\n}\n\n\n/* Put back deprecation warning setting */\n#if defined(PJ_DARWINOS) && PJ_DARWINOS==1\n#  pragma GCC diagnostic pop\n#endif\n\n\n#endif  /* PJ_HAS_SSL_SOCK */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/ssl_sock_symbian.cpp",
    "content": "/* $Id: ssl_sock_symbian.cpp 3999 2012-03-30 07:10:13Z bennylp $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/ssl_sock.h>\n#include <pj/compat/socket.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/math.h>\n#include <pj/pool.h>\n#include <pj/sock.h>\n#include <pj/string.h>\n\n#include \"os_symbian.h\"\n#include <securesocket.h>\n#include <x509cert.h>\n#include <e32des8.h>\n\n#define THIS_FILE \"ssl_sock_symbian.cpp\"\n\n\n/* Cipher name structure */\ntypedef struct cipher_name_t {\n    pj_ssl_cipher    cipher;\n    const char\t    *name;\n} cipher_name_t;\n\n/* Cipher name constants */\nstatic cipher_name_t cipher_names[] =\n{\n    {PJ_TLS_UNKNOWN_CIPHER,                    \"UNKNOWN\"},\n    {PJ_TLS_NULL_WITH_NULL_NULL,               \"NULL\"},\n\n    /* TLS/SSLv3 */\n    {PJ_TLS_RSA_WITH_NULL_MD5,                 \"TLS_RSA_WITH_NULL_MD5\"},\n    {PJ_TLS_RSA_WITH_NULL_SHA,                 \"TLS_RSA_WITH_NULL_SHA\"},\n    {PJ_TLS_RSA_WITH_NULL_SHA256,              \"TLS_RSA_WITH_NULL_SHA256\"},\n    {PJ_TLS_RSA_WITH_RC4_128_MD5,              \"TLS_RSA_WITH_RC4_128_MD5\"},\n    {PJ_TLS_RSA_WITH_RC4_128_SHA,              \"TLS_RSA_WITH_RC4_128_SHA\"},\n    {PJ_TLS_RSA_WITH_3DES_EDE_CBC_SHA,         \"TLS_RSA_WITH_3DES_EDE_CBC_SHA\"},\n    {PJ_TLS_RSA_WITH_AES_128_CBC_SHA,          \"TLS_RSA_WITH_AES_128_CBC_SHA\"},\n    {PJ_TLS_RSA_WITH_AES_256_CBC_SHA,          \"TLS_RSA_WITH_AES_256_CBC_SHA\"},\n    {PJ_TLS_RSA_WITH_AES_128_CBC_SHA256,       \"TLS_RSA_WITH_AES_128_CBC_SHA256\"},\n    {PJ_TLS_RSA_WITH_AES_256_CBC_SHA256,       \"TLS_RSA_WITH_AES_256_CBC_SHA256\"},\n    {PJ_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,      \"TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA\"},\n    {PJ_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,      \"TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA\"},\n    {PJ_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,     \"TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA\"},\n    {PJ_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,     \"TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA\"},\n    {PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA,       \"TLS_DH_DSS_WITH_AES_128_CBC_SHA\"},\n    {PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA,       \"TLS_DH_RSA_WITH_AES_128_CBC_SHA\"},\n    {PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA,      \"TLS_DHE_DSS_WITH_AES_128_CBC_SHA\"},\n    {PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,      \"TLS_DHE_RSA_WITH_AES_128_CBC_SHA\"},\n    {PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA,       \"TLS_DH_DSS_WITH_AES_256_CBC_SHA\"},\n    {PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA,       \"TLS_DH_RSA_WITH_AES_256_CBC_SHA\"},\n    {PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA,      \"TLS_DHE_DSS_WITH_AES_256_CBC_SHA\"},\n    {PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,      \"TLS_DHE_RSA_WITH_AES_256_CBC_SHA\"},\n    {PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA256,    \"TLS_DH_DSS_WITH_AES_128_CBC_SHA256\"},\n    {PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA256,    \"TLS_DH_RSA_WITH_AES_128_CBC_SHA256\"},\n    {PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,   \"TLS_DHE_DSS_WITH_AES_128_CBC_SHA256\"},\n    {PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,   \"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256\"},\n    {PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA256,    \"TLS_DH_DSS_WITH_AES_256_CBC_SHA256\"},\n    {PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA256,    \"TLS_DH_RSA_WITH_AES_256_CBC_SHA256\"},\n    {PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,   \"TLS_DHE_DSS_WITH_AES_256_CBC_SHA256\"},\n    {PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,   \"TLS_DHE_RSA_WITH_AES_256_CBC_SHA256\"},\n    {PJ_TLS_DH_anon_WITH_RC4_128_MD5,          \"TLS_DH_anon_WITH_RC4_128_MD5\"},\n    {PJ_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,     \"TLS_DH_anon_WITH_3DES_EDE_CBC_SHA\"},\n    {PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA,      \"TLS_DH_anon_WITH_AES_128_CBC_SHA\"},\n    {PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA,      \"TLS_DH_anon_WITH_AES_256_CBC_SHA\"},\n    {PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA256,   \"TLS_DH_anon_WITH_AES_128_CBC_SHA256\"},\n    {PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA256,   \"TLS_DH_anon_WITH_AES_256_CBC_SHA256\"},\n\n    /* TLS (deprecated) */\n    {PJ_TLS_RSA_EXPORT_WITH_RC4_40_MD5,        \"TLS_RSA_EXPORT_WITH_RC4_40_MD5\"},\n    {PJ_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,    \"TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5\"},\n    {PJ_TLS_RSA_WITH_IDEA_CBC_SHA,             \"TLS_RSA_WITH_IDEA_CBC_SHA\"},\n    {PJ_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,     \"TLS_RSA_EXPORT_WITH_DES40_CBC_SHA\"},\n    {PJ_TLS_RSA_WITH_DES_CBC_SHA,              \"TLS_RSA_WITH_DES_CBC_SHA\"},\n    {PJ_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,  \"TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA\"},\n    {PJ_TLS_DH_DSS_WITH_DES_CBC_SHA,           \"TLS_DH_DSS_WITH_DES_CBC_SHA\"},\n    {PJ_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,  \"TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA\"},\n    {PJ_TLS_DH_RSA_WITH_DES_CBC_SHA,           \"TLS_DH_RSA_WITH_DES_CBC_SHA\"},\n    {PJ_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, \"TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA\"},\n    {PJ_TLS_DHE_DSS_WITH_DES_CBC_SHA,          \"TLS_DHE_DSS_WITH_DES_CBC_SHA\"},\n    {PJ_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, \"TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA\"},\n    {PJ_TLS_DHE_RSA_WITH_DES_CBC_SHA,          \"TLS_DHE_RSA_WITH_DES_CBC_SHA\"},\n    {PJ_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5,    \"TLS_DH_anon_EXPORT_WITH_RC4_40_MD5\"},\n    {PJ_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, \"TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA\"},\n    {PJ_TLS_DH_anon_WITH_DES_CBC_SHA,          \"TLS_DH_anon_WITH_DES_CBC_SHA\"},\n\n    /* SSLv3 */\n    {PJ_SSL_FORTEZZA_KEA_WITH_NULL_SHA,        \"SSL_FORTEZZA_KEA_WITH_NULL_SHA\"},\n    {PJ_SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA,\"SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA\"},\n    {PJ_SSL_FORTEZZA_KEA_WITH_RC4_128_SHA,     \"SSL_FORTEZZA_KEA_WITH_RC4_128_SHA\"},\n\n    /* SSLv2 */\n    {PJ_SSL_CK_RC4_128_WITH_MD5,               \"SSL_CK_RC4_128_WITH_MD5\"},\n    {PJ_SSL_CK_RC4_128_EXPORT40_WITH_MD5,      \"SSL_CK_RC4_128_EXPORT40_WITH_MD5\"},\n    {PJ_SSL_CK_RC2_128_CBC_WITH_MD5,           \"SSL_CK_RC2_128_CBC_WITH_MD5\"},\n    {PJ_SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5,  \"SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5\"},\n    {PJ_SSL_CK_IDEA_128_CBC_WITH_MD5,          \"SSL_CK_IDEA_128_CBC_WITH_MD5\"},\n    {PJ_SSL_CK_DES_64_CBC_WITH_MD5,            \"SSL_CK_DES_64_CBC_WITH_MD5\"},\n    {PJ_SSL_CK_DES_192_EDE3_CBC_WITH_MD5,      \"SSL_CK_DES_192_EDE3_CBC_WITH_MD5\"}\n};\n\n\n/* Get cipher name string */\nstatic const char* get_cipher_name(pj_ssl_cipher cipher)\n{\n    unsigned i, n;\n\n    n = PJ_ARRAY_SIZE(cipher_names);\n    for (i = 0; i < n; ++i) {\n       if (cipher == cipher_names[i].cipher)\n           return cipher_names[i].name;\n    }\n\n    return \"CIPHER_UNKNOWN\";\n}\n\ntypedef void (*CPjSSLSocket_cb)(int err, void *key);\n\nclass CPjSSLSocketReader : public CActive\n{\npublic:\n    static CPjSSLSocketReader *NewL(CSecureSocket &sock) \n    {\n\tCPjSSLSocketReader *self = new (ELeave) \n\t\t\t\t   CPjSSLSocketReader(sock);\n\tCleanupStack::PushL(self);\n\tself->ConstructL();\n\tCleanupStack::Pop(self);\n\treturn self;\n    }\n\n    ~CPjSSLSocketReader() {\n\tCancel();\n    }\n\n    /* Asynchronous read from the socket. */\n    int Read(CPjSSLSocket_cb cb, void *key, TPtr8 &data, TUint flags)\n    {\n\tPJ_ASSERT_RETURN(!IsActive(), PJ_EBUSY);\n\t\n\tcb_ = cb;\n\tkey_ = key;\n\tsock_.RecvOneOrMore(data, iStatus, len_received_);\n\tSetActive();\n\t\n\treturn PJ_EPENDING;\n    }\n\nprivate:\n    CSecureSocket  \t&sock_;\n    CPjSSLSocket_cb\t cb_;\n    void\t\t*key_;\n    TSockXfrLength  \t len_received_; /* not really useful? */\n\n    void DoCancel() {\n\tsock_.CancelAll();\n    }\n    \n    void RunL() {\n\t(*cb_)(iStatus.Int(), key_);\n    }\n\n    CPjSSLSocketReader(CSecureSocket &sock) : \n\tCActive(0), sock_(sock), cb_(NULL), key_(NULL) \n    {}\n    \n    void ConstructL() {\n\tCActiveScheduler::Add(this);\n    }\n};\n\nclass CPjSSLSocket : public CActive\n{\npublic:\n    enum ssl_state {\n\tSSL_STATE_NULL,\n\tSSL_STATE_CONNECTING,\n\tSSL_STATE_HANDSHAKING,\n\tSSL_STATE_ESTABLISHED\n    };\n    \n    static CPjSSLSocket *NewL(const TDesC8 &ssl_proto,\n\t\t\t      pj_qos_type qos_type,\n\t\t\t      const pj_qos_params &qos_params) \n    {\n\tCPjSSLSocket *self = new (ELeave) CPjSSLSocket(qos_type, qos_params);\n\tCleanupStack::PushL(self);\n\tself->ConstructL(ssl_proto);\n\tCleanupStack::Pop(self);\n\treturn self;\n    }\n\n    ~CPjSSLSocket() {\n\tCancel();\n\tCleanupSubObjects();\n    }\n\n    int Connect(CPjSSLSocket_cb cb, void *key, const TInetAddr &local_addr, \n\t\tconst TInetAddr &rem_addr, \n\t\tconst TDesC8 &servername = TPtrC8(NULL,0),\n\t\tconst TDesC8 &ciphers = TPtrC8(NULL,0));\n    int Send(CPjSSLSocket_cb cb, void *key, const TDesC8 &aDesc, TUint flags);\n    int SendSync(const TDesC8 &aDesc, TUint flags);\n\n    CPjSSLSocketReader* GetReader();\n    enum ssl_state GetState() const { return state_; }\n    const TInetAddr* GetLocalAddr() const { return &local_addr_; }\n    int GetCipher(TDes8 &cipher) const {\n\tif (securesock_)\n\t    return securesock_->CurrentCipherSuite(cipher);\n\treturn KErrNotFound;\n    }\n    const CX509Certificate *GetPeerCert() {\n\tif (securesock_)\n\t    return securesock_->ServerCert();\n\treturn NULL;\n    }\n\nprivate:\n    enum ssl_state\t state_;\n    pj_sock_t\t    \t sock_;\n    CSecureSocket  \t*securesock_;\n    bool\t    \t is_connected_;\n    \n    pj_qos_type \t qos_type_;\n    pj_qos_params \t qos_params_;\n    \t\t\t      \n    CPjSSLSocketReader  *reader_;\n    TBuf<32> \t    \t ssl_proto_;\n    TInetAddr       \t rem_addr_;\n    TPtrC8\t\t servername_;\n    TPtrC8\t\t ciphers_;\n    TInetAddr       \t local_addr_;\n    TSockXfrLength \t sent_len_;\n\n    CPjSSLSocket_cb \t cb_;\n    void \t   \t*key_;\n    \n    void DoCancel();\n    void RunL();\n\n    CPjSSLSocket(pj_qos_type qos_type, const pj_qos_params &qos_params) :\n\tCActive(0), state_(SSL_STATE_NULL), sock_(PJ_INVALID_SOCKET), \n\tsecuresock_(NULL), is_connected_(false),\n\tqos_type_(qos_type), qos_params_(qos_params),\n\treader_(NULL), \tcb_(NULL), key_(NULL)\n    {}\n    \n    void ConstructL(const TDesC8 &ssl_proto) {\n\tssl_proto_.Copy(ssl_proto);\n\tCActiveScheduler::Add(this);\n    }\n\n    void CleanupSubObjects() {\n\tdelete reader_;\n\treader_ = NULL;\n\tif (securesock_) {\n\t    if (state_ == SSL_STATE_ESTABLISHED)\n\t\tsecuresock_->Close();\n\t    delete securesock_;\n\t    securesock_ = NULL;\n\t}\n\tif (sock_ != PJ_INVALID_SOCKET) {\n\t    pj_sock_close(sock_);\n\t    sock_ = PJ_INVALID_SOCKET;\n\t}\t    \n    }\n};\n\nint CPjSSLSocket::Connect(CPjSSLSocket_cb cb, void *key, \n\t\t\t  const TInetAddr &local_addr, \n\t\t\t  const TInetAddr &rem_addr,\n\t\t\t  const TDesC8 &servername,\n\t\t\t  const TDesC8 &ciphers)\n{\n    pj_status_t status;\n    \n    PJ_ASSERT_RETURN(state_ == SSL_STATE_NULL, PJ_EINVALIDOP);\n    \n    status = pj_sock_socket(rem_addr.Family(), pj_SOCK_STREAM(), 0, &sock_);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    // Apply QoS\n    status = pj_sock_apply_qos2(sock_, qos_type_, &qos_params_, \n    \t\t\t\t2,  THIS_FILE, NULL);\n    \n    RSocket &rSock = ((CPjSocket*)sock_)->Socket();\n\n    local_addr_ = local_addr;\n    \n    if (!local_addr_.IsUnspecified()) {\n\tTInt err = rSock.Bind(local_addr_);\n\tif (err != KErrNone)\n\t    return PJ_RETURN_OS_ERROR(err);\n    }\n    \n    cb_ = cb;\n    key_ = key;\n    rem_addr_ = rem_addr;\n    \n    /* Note: the following members only keep the pointer, not the data */\n    servername_.Set(servername);\n    ciphers_.Set(ciphers);\n\n    rSock.Connect(rem_addr_, iStatus);\n    SetActive();\n    state_ = SSL_STATE_CONNECTING;\n    \n    rSock.LocalName(local_addr_);\n\n    return PJ_EPENDING;\n}\n\nint CPjSSLSocket::Send(CPjSSLSocket_cb cb, void *key, const TDesC8 &aDesc, \n\t\t       TUint flags)\n{\n    PJ_UNUSED_ARG(flags);\n\n    PJ_ASSERT_RETURN(state_ == SSL_STATE_ESTABLISHED, PJ_EINVALIDOP);\n    \n    if (IsActive())\n\treturn PJ_EBUSY;\n    \n    cb_ = cb;\n    key_ = key;\n    \n    securesock_->Send(aDesc, iStatus, sent_len_);\n    SetActive();\n    \n    return PJ_EPENDING;\n}\n\nint CPjSSLSocket::SendSync(const TDesC8 &aDesc, TUint flags)\n{\n    PJ_UNUSED_ARG(flags);\n\n    PJ_ASSERT_RETURN(state_ == SSL_STATE_ESTABLISHED, PJ_EINVALIDOP);\n    \n    TRequestStatus reqStatus;\n    securesock_->Send(aDesc, reqStatus, sent_len_);\n    User::WaitForRequest(reqStatus);\n    \n    return PJ_RETURN_OS_ERROR(reqStatus.Int());\n}\n\nCPjSSLSocketReader* CPjSSLSocket::GetReader()\n{\n    PJ_ASSERT_RETURN(state_ == SSL_STATE_ESTABLISHED, NULL);\n    \n    if (reader_)\n\treturn reader_;\n    \n    TRAPD(err,\treader_ = CPjSSLSocketReader::NewL(*securesock_));\n    if (err != KErrNone)\n\treturn NULL;\n    \n    return reader_;\n}\n\nvoid CPjSSLSocket::DoCancel()\n{\n    /* Operation to be cancelled depends on current state */\n    switch (state_) {\n    case SSL_STATE_CONNECTING:\n\t{\n\t    RSocket &rSock = ((CPjSocket*)sock_)->Socket();\n\n\t    rSock.CancelConnect();\n\t    CleanupSubObjects();\n\t    state_ = SSL_STATE_NULL;\n\t}\n\tbreak;\n    case SSL_STATE_HANDSHAKING:\n\t{\n\t    securesock_->CancelHandshake();\n\t    CleanupSubObjects();\n\t    state_ = SSL_STATE_NULL;\n\t}\n\tbreak;\n    case SSL_STATE_ESTABLISHED:\n\tsecuresock_->CancelSend();\n\tbreak;\n    default:\n\tbreak;\n    }\n}\n\nvoid CPjSSLSocket::RunL()\n{\n    switch (state_) {\n    case SSL_STATE_CONNECTING:\n\tif (iStatus != KErrNone) {\n\t    CleanupSubObjects();\n\t    state_ = SSL_STATE_NULL;\n\t    /* Dispatch connect failure notification */\n\t    if (cb_) (*cb_)(iStatus.Int(), key_);\n\t} else {\n\t    RSocket &rSock = ((CPjSocket*)sock_)->Socket();\n\n\t    /* Get local addr */\n\t    rSock.LocalName(local_addr_);\n\t    \n\t    /* Prepare and start handshake */\n\t    securesock_ = CSecureSocket::NewL(rSock, ssl_proto_);\n\t    securesock_->SetDialogMode(EDialogModeAttended);\n\t    if (servername_.Length() > 0)\n\t\tsecuresock_->SetOpt(KSoSSLDomainName, KSolInetSSL,\n\t\t\t\t    servername_);\n\t    if (ciphers_.Length() > 0)\n\t\tsecuresock_->SetAvailableCipherSuites(ciphers_);\n\n\t    // FlushSessionCache() seems to also fire signals to all \n\t    // completed AOs (something like CActiveScheduler::RunIfReady())\n\t    // which may cause problem, e.g: we've experienced that when \n\t    // SSL timeout is set to 1s, the SSL timeout timer fires up\n\t    // at this point and securesock_ instance gets deleted here!\n\t    // So be careful using this. And we don't think we need it here.\n\t    //securesock_->FlushSessionCache();\n\n\t    securesock_->StartClientHandshake(iStatus);\n\t    SetActive();\n\t    state_ = SSL_STATE_HANDSHAKING;\n\t}\n\tbreak;\n    case SSL_STATE_HANDSHAKING:\n\tif (iStatus == KErrNone) {\n\t    state_ = SSL_STATE_ESTABLISHED;\n\t} else {\n\t    state_ = SSL_STATE_NULL;\n\t    CleanupSubObjects();\n\t}\n\t/* Dispatch connect status notification */\n\tif (cb_) (*cb_)(iStatus.Int(), key_);\n\tbreak;\n    case SSL_STATE_ESTABLISHED:\n\t/* Dispatch data sent notification */\n\tif (cb_) (*cb_)(iStatus.Int(), key_);\n\tbreak;\n    default:\n\tpj_assert(0);\n\tbreak;\n    }\n}\n\ntypedef void (*CPjTimer_cb)(void *user_data);\n\nclass CPjTimer : public CActive \n{\npublic:\n    CPjTimer(const pj_time_val *delay, CPjTimer_cb cb, void *user_data) : \n\tCActive(0), cb_(cb), user_data_(user_data)\n    {\n\tCActiveScheduler::Add(this);\n\n\trtimer_.CreateLocal();\n\tpj_int32_t interval = PJ_TIME_VAL_MSEC(*delay) * 1000;\n\tif (interval < 0) {\n\t    interval = 0;\n\t}\n\trtimer_.After(iStatus, interval);\n\tSetActive();\n    }\n    \n    ~CPjTimer() { Cancel(); }\n    \nprivate:\t\n    RTimer\t\t rtimer_;\n    CPjTimer_cb\t\t cb_;\n    void\t\t*user_data_;\n    \n    void RunL() { if (cb_) (*cb_)(user_data_); }\n    void DoCancel() { rtimer_.Cancel(); }\n};\n\n/*\n * Structure of recv/read state.\n */\ntypedef struct read_state_t {\n    TPtr8\t\t*read_buf;\n    TPtr8\t\t*orig_buf;\n    pj_uint32_t\t\t flags;    \n} read_state_t;\n\n/*\n * Structure of send/write data.\n */\ntypedef struct write_data_t {\n    pj_size_t \t \t len;\n    pj_ioqueue_op_key_t\t*key;\n    pj_size_t \t \t data_len;\n    char\t\t data[1];\n} write_data_t;\n\n/*\n * Structure of send/write state.\n */\ntypedef struct write_state_t {\n    char\t\t*buf;\n    pj_size_t\t\t max_len;    \n    char\t\t*start;\n    pj_size_t\t\t len;\n    write_data_t\t*current_data;\n    TPtrC8\t\t send_ptr;\n} write_state_t;\n\n/*\n * Secure socket structure definition.\n */\nstruct pj_ssl_sock_t\n{\n    pj_pool_t\t\t*pool;\n    pj_ssl_sock_cb\t cb;\n    void\t\t*user_data;\n    \n    pj_bool_t\t\t established;\n    write_state_t\t write_state;\n    read_state_t\t read_state;\n    CPjTimer\t\t*connect_timer;\n\n    CPjSSLSocket   \t*sock;\n    int\t\t\t sock_af;\n    int\t\t\t sock_type;\n    pj_sockaddr\t\t local_addr;\n    pj_sockaddr\t\t rem_addr;\n\n    /* QoS settings */\n    pj_qos_type\t\t qos_type;\n    pj_qos_params\t qos_params;\n    pj_bool_t\t\t qos_ignore_error;\n\n\n    pj_ssl_sock_proto\t proto;\n    pj_time_val\t\t timeout;\n    pj_str_t\t\t servername;\n    pj_str_t\t\t ciphers;\n    pj_ssl_cert_info\t remote_cert_info;\n};\n\n\nstatic pj_str_t get_cert_name(char *buf, unsigned buf_len,\n                              const CX500DistinguishedName &name)\n{\n    TInt i;\n    TUint8 *p;\n    TInt l = buf_len;\n    \n    p = (TUint8*)buf;\n    for(i = 0; i < name.Count(); ++i) {\n\tconst CX520AttributeTypeAndValue &attr = name.Element(i);\n\n\t/* Print element separator */\n\t*p++ = '/';\n\tif (0 == --l) break;\n\n\t/* Print the type. */\n\tTPtr8 type(p, l);\n\ttype.Copy(attr.Type());\n\tp += type.Length();\n\tl -= type.Length();\n\tif (0 >= --l) break;\n\n\t/* Print equal sign */\n\t*p++ = '=';\n\tif (0 == --l) break;\n\t\n\t/* Print the value. Let's just get the raw data here */\n\tTPtr8 value(p, l);\n\tvalue.Copy(attr.EncodedValue().Mid(2));\n\tp += value.Length();\n\tl -= value.Length();\n\tif (0 >= --l) break;\n    }\n    \n    pj_str_t src;\n    pj_strset(&src, buf, buf_len - l);\n    \n    return src;\n}\n                            \n/* Get certificate info from CX509Certificate.\n */\nstatic void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci,\n                          const CX509Certificate *x)\n{\n    enum { tmp_buf_len = 512 };\n    char *tmp_buf;\n    unsigned len;\n    \n    pj_assert(pool && ci && x);\n    \n    /* Init */\n    tmp_buf = new char[tmp_buf_len];\n    pj_bzero(ci, sizeof(*ci));\n    \n    /* Version */\n    ci->version = x->Version();\n    \n    /* Serial number */\n    len = x->SerialNumber().Length();\n    if (len > sizeof(ci->serial_no)) \n\tlen = sizeof(ci->serial_no);\n    pj_memcpy(ci->serial_no + sizeof(ci->serial_no) - len, \n              x->SerialNumber().Ptr(), len);\n    \n    /* Subject */\n    {\n\tHBufC *subject = NULL;\n\tTRAPD(err, subject = x->SubjectL());\n\tif (err == KErrNone) {\n\t    TPtr16 ptr16(subject->Des());\n\t    len = ptr16.Length();\n\t    TPtr8 ptr8((TUint8*)pj_pool_alloc(pool, len), len);\n\t    ptr8.Copy(ptr16);\n\t    pj_strset(&ci->subject.cn, (char*)ptr8.Ptr(), ptr8.Length());\n\t}\n\tpj_str_t tmp = get_cert_name(tmp_buf, tmp_buf_len,\n\t\t\t\t     x->SubjectName());\n\tpj_strdup(pool, &ci->subject.info, &tmp);\n    }\n\n    /* Issuer */\n    {\n\tHBufC *issuer = NULL;\n\tTRAPD(err, issuer = x->IssuerL());\n\tif (err == KErrNone) {\n\t    TPtr16 ptr16(issuer->Des());\n\t    len = ptr16.Length();\n\t    TPtr8 ptr8((TUint8*)pj_pool_alloc(pool, len), len);\n\t    ptr8.Copy(ptr16);\n\t    pj_strset(&ci->issuer.cn, (char*)ptr8.Ptr(), ptr8.Length());\n\t}\n\tpj_str_t tmp = get_cert_name(tmp_buf, tmp_buf_len,\n\t\t\t\t     x->IssuerName());\n\tpj_strdup(pool, &ci->issuer.info, &tmp);\n    }\n    \n    /* Validity */\n    const CValidityPeriod &valid_period = x->ValidityPeriod();\n    TTime base_time(TDateTime(1970, EJanuary, 0, 0, 0, 0, 0));\n    TTimeIntervalSeconds tmp_sec;\n    valid_period.Start().SecondsFrom(base_time, tmp_sec);\n    ci->validity.start.sec = tmp_sec.Int(); \n    valid_period.Finish().SecondsFrom(base_time, tmp_sec);\n    ci->validity.end.sec = tmp_sec.Int();\n    \n    /* Deinit */\n    delete [] tmp_buf;\n}\n\n\n/* Update certificates info. This function should be called after handshake\n * or renegotiation successfully completed.\n */\nstatic void update_certs_info(pj_ssl_sock_t *ssock)\n{\n    const CX509Certificate *x;\n\n    pj_assert(ssock && ssock->sock &&\n              ssock->sock->GetState() == CPjSSLSocket::SSL_STATE_ESTABLISHED);\n        \n    /* Active remote certificate */\n    x = ssock->sock->GetPeerCert();\n    if (x) {\n\tget_cert_info(ssock->pool, &ssock->remote_cert_info, x);\n    } else {\n\tpj_bzero(&ssock->remote_cert_info, sizeof(pj_ssl_cert_info));\n    }\n}\n\n\n/* Available ciphers */\nstatic unsigned ciphers_num_ = 0;\nstatic struct ciphers_t\n{\n    pj_ssl_cipher    id;\n    const char\t    *name;\n} ciphers_[64];\n\n/*\n * Get cipher list supported by SSL/TLS backend.\n */\nPJ_DEF(pj_status_t) pj_ssl_cipher_get_availables (pj_ssl_cipher ciphers[],\n\t\t\t\t\t          unsigned *cipher_num)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(ciphers && cipher_num, PJ_EINVAL);\n    \n    if (ciphers_num_ == 0) {\n        RSocket sock;\n        CSecureSocket *secure_sock;\n        TPtrC16 proto(_L16(\"TLS1.0\"));\n\n        secure_sock = CSecureSocket::NewL(sock, proto);\n        if (secure_sock) {\n            TBuf8<128> ciphers_buf(0);\n            secure_sock->AvailableCipherSuites(ciphers_buf);\n            \n            ciphers_num_ = ciphers_buf.Length() / 2;\n            if (ciphers_num_ > PJ_ARRAY_SIZE(ciphers_))\n        \tciphers_num_ = PJ_ARRAY_SIZE(ciphers_);\n            for (i = 0; i < ciphers_num_; ++i) {\n                ciphers_[i].id = (pj_ssl_cipher)(ciphers_buf[i*2]*10 + \n\t\t\t\t\t         ciphers_buf[i*2+1]);\n\t\tciphers_[i].name = get_cipher_name(ciphers_[i].id);\n\t    }\n        }\n        \n        delete secure_sock;\n    }\n    \n    if (ciphers_num_ == 0) {\n\t*cipher_num = 0;\n\treturn PJ_ENOTFOUND;\n    }\n    \n    *cipher_num = PJ_MIN(*cipher_num, ciphers_num_);\n    for (i = 0; i < *cipher_num; ++i)\n        ciphers[i] = ciphers_[i].id;\n    \n    return PJ_SUCCESS;\n}\n\n\n/* Get cipher name string */\nPJ_DEF(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher)\n{\n    unsigned i;\n\n    if (ciphers_num_ == 0) {\n\tpj_ssl_cipher c[1];\n\ti = 0;\n\tpj_ssl_cipher_get_availables(c, &i);\n    }\n\t\n    for (i = 0; i < ciphers_num_; ++i) {\n\tif (cipher == ciphers_[i].id)\n\t    return ciphers_[i].name;\n    }\n\n    return NULL;\n}\n\n\n/* Get cipher identifier */\nPJ_DEF(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name)\n{\n    unsigned i;\n    \n    if (ciphers_num_ == 0) {\n\tpj_ssl_cipher c[1];\n\ti = 0;\n\tpj_ssl_cipher_get_availables(c, &i);\n    }\n    \n    for (i = 0; i < ciphers_num_; ++i) {\n        if (!pj_ansi_stricmp(ciphers_[i].name, cipher_name))\n            return ciphers_[i].id;\n    }\n\n    return PJ_TLS_UNKNOWN_CIPHER;\n}\n\n\n/* Check if the specified cipher is supported by SSL/TLS backend. */\nPJ_DEF(pj_bool_t) pj_ssl_cipher_is_supported(pj_ssl_cipher cipher)\n{\n    unsigned i;\n\n    if (ciphers_num_ == 0) {\n\tpj_ssl_cipher c[1];\n\ti = 0;\n\tpj_ssl_cipher_get_availables(c, &i);\n    }\n\t\n    for (i = 0; i < ciphers_num_; ++i) {\n\tif (cipher == ciphers_[i].id)\n\t    return PJ_TRUE;\n    }\n\n    return PJ_FALSE;\n}\n\n\n/*\n * Create SSL socket instance. \n */\nPJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,\n\t\t\t\t\tconst pj_ssl_sock_param *param,\n\t\t\t\t\tpj_ssl_sock_t **p_ssock)\n{\n    pj_ssl_sock_t *ssock;\n\n    PJ_ASSERT_RETURN(param->async_cnt == 1, PJ_EINVAL);\n    PJ_ASSERT_RETURN(pool && param && p_ssock, PJ_EINVAL);\n\n    /* Allocate secure socket */\n    ssock = PJ_POOL_ZALLOC_T(pool, pj_ssl_sock_t);\n    \n    /* Allocate write buffer */\n    ssock->write_state.buf = (char*)pj_pool_alloc(pool, \n\t\t\t\t\t\t  param->send_buffer_size);\n    ssock->write_state.max_len = param->send_buffer_size;\n    ssock->write_state.start = ssock->write_state.buf;\n    \n    /* Init secure socket */\n    ssock->pool = pool;\n    ssock->sock_af = param->sock_af;\n    ssock->sock_type = param->sock_type;\n    ssock->cb = param->cb;\n    ssock->user_data = param->user_data;\n    ssock->timeout = param->timeout;\n    if (param->ciphers_num > 0) {\n\t/* Cipher list in Symbian is represented as array of two-octets. */\n\tssock->ciphers.slen = param->ciphers_num*2;\n\tssock->ciphers.ptr  = (char*)pj_pool_alloc(pool, ssock->ciphers.slen);\n\tpj_uint8_t *c = (pj_uint8_t*)ssock->ciphers.ptr;\n\tfor (unsigned i = 0; i < param->ciphers_num; ++i) {\n\t    *c++ = (pj_uint8_t)(param->ciphers[i] & 0xFF00) >> 8;\n\t    *c++ = (pj_uint8_t)(param->ciphers[i] & 0xFF);\n\t}\n    }\n    pj_strdup_with_null(pool, &ssock->servername, &param->server_name);\n\n    ssock->qos_type = param->qos_type;\n    ssock->qos_ignore_error = param->qos_ignore_error;\n    pj_memcpy(&ssock->qos_params, &param->qos_params,\n\t      sizeof(param->qos_params));\n\n    /* Finally */\n    *p_ssock = ssock;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_ssl_cert_load_from_files(pj_pool_t *pool,\n                                        \tconst pj_str_t *CA_file,\n                                        \tconst pj_str_t *cert_file,\n                                        \tconst pj_str_t *privkey_file,\n                                        \tconst pj_str_t *privkey_pass,\n                                        \tpj_ssl_cert_t **p_cert)\n{\n    return pj_ssl_cert_load_from_files2(pool, CA_file, NULL, cert_file,\n\t\t\t\t\tprivkey_file, privkey_pass, p_cert);\n}\n\nPJ_DEF(pj_status_t) pj_ssl_cert_load_from_files2(pj_pool_t *pool,\n                                        \t const pj_str_t *CA_file,\n                                        \t const pj_str_t *CA_path,\n                                        \t const pj_str_t *cert_file,\n                                        \t const pj_str_t *privkey_file,\n                                        \t const pj_str_t *privkey_pass,\n                                        \t pj_ssl_cert_t **p_cert)\n{\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(CA_file);\n    PJ_UNUSED_ARG(CA_path);\n    PJ_UNUSED_ARG(cert_file);\n    PJ_UNUSED_ARG(privkey_file);\n    PJ_UNUSED_ARG(privkey_pass);\n    PJ_UNUSED_ARG(p_cert);\n    return PJ_ENOTSUP;\n}\n\n/*\n * Set SSL socket credential.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_set_certificate(\n\t\t\t\t\t    pj_ssl_sock_t *ssock,\n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    const pj_ssl_cert_t *cert)\n{\n    PJ_UNUSED_ARG(ssock);\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(cert);\n    return PJ_ENOTSUP;\n}\n\n/*\n * Close the SSL socket.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock)\n{\n    PJ_ASSERT_RETURN(ssock, PJ_EINVAL);\n    \n    delete ssock->connect_timer;\n    ssock->connect_timer = NULL;\n    \n    delete ssock->sock;\n    ssock->sock = NULL;\n\n    delete ssock->read_state.read_buf;\n    delete ssock->read_state.orig_buf;\n    ssock->read_state.read_buf = NULL;\n    ssock->read_state.orig_buf = NULL;\n    \n    return PJ_SUCCESS;\n}\n\n\n/*\n * Associate arbitrary data with the SSL socket.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_set_user_data (pj_ssl_sock_t *ssock,\n\t\t\t\t\t       void *user_data)\n{\n    PJ_ASSERT_RETURN(ssock, PJ_EINVAL);\n    \n    ssock->user_data = user_data;\n    \n    return PJ_SUCCESS;\n}\n\t\t\t\t\t       \n\n/*\n * Retrieve the user data previously associated with this SSL\n * socket.\n */\nPJ_DEF(void*) pj_ssl_sock_get_user_data(pj_ssl_sock_t *ssock)\n{\n    PJ_ASSERT_RETURN(ssock, NULL);\n    \n    return ssock->user_data;\n}\n\n\n/*\n * Retrieve the local address and port used by specified SSL socket.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_get_info (pj_ssl_sock_t *ssock,\n\t\t\t\t\t  pj_ssl_sock_info *info)\n{\n    PJ_ASSERT_RETURN(ssock && info, PJ_EINVAL);\n    \n    pj_bzero(info, sizeof(*info));\n    \n    info->established = ssock->established;\n    \n    /* Local address */\n    if (ssock->sock) {\n\tconst TInetAddr* local_addr_ = ssock->sock->GetLocalAddr();\n\tint addrlen = sizeof(pj_sockaddr);\n\tpj_status_t status;\n\t\n\tstatus = PjSymbianOS::Addr2pj(*local_addr_, info->local_addr, &addrlen);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    } else {\n\tpj_sockaddr_cp(&info->local_addr, &ssock->local_addr);\n    }\n\n    if (info->established) {\n\t/* Cipher suite */\n\tTBuf8<4> cipher;\n\tif (ssock->sock->GetCipher(cipher) == KErrNone) {\n\t    info->cipher = (pj_ssl_cipher)cipher[1]; \n\t}\n\n\t/* Remote address */\n        pj_sockaddr_cp((pj_sockaddr_t*)&info->remote_addr, \n    \t\t       (pj_sockaddr_t*)&ssock->rem_addr);\n        \n        /* Certificates info */\n        info->remote_cert_info = &ssock->remote_cert_info;\n    }\n\n    /* Protocol */\n    info->proto = ssock->proto;\n    \n    return PJ_SUCCESS;\n}\n\n\n/*\n * Starts read operation on this SSL socket.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_start_read (pj_ssl_sock_t *ssock,\n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    unsigned buff_size,\n\t\t\t\t\t    pj_uint32_t flags)\n{\n    PJ_ASSERT_RETURN(ssock && pool && buff_size, PJ_EINVAL);\n    PJ_ASSERT_RETURN(ssock->established, PJ_EINVALIDOP);\n\n    /* Reading is already started */\n    if (ssock->read_state.orig_buf) {\n\treturn PJ_SUCCESS;\n    }\n\n    void *readbuf[1];\n    readbuf[0] = pj_pool_alloc(pool, buff_size);\n    return pj_ssl_sock_start_read2(ssock, pool, buff_size, readbuf, flags);\n}\n\nstatic void read_cb(int err, void *key)\n{\n    pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)key;\n    pj_status_t status;\n\n    status = (err == KErrNone)? PJ_SUCCESS : PJ_RETURN_OS_ERROR(err);\n\n    /* Check connection status */\n    if (err == KErrEof || !PjSymbianOS::Instance()->IsConnectionUp() ||\n\t!ssock->established) \n    {\n\tstatus = PJ_EEOF;\n    }\n    \n    /* Notify data arrival */\n    if (ssock->cb.on_data_read) {\n\tpj_size_t remainder = 0;\n\tchar *data = (char*)ssock->read_state.orig_buf->Ptr();\n\tpj_size_t data_len = ssock->read_state.read_buf->Length() + \n\t\t\t     ssock->read_state.read_buf->Ptr() -\n\t\t\t     ssock->read_state.orig_buf->Ptr();\n\t\n\tif (data_len > 0) {\n\t    /* Notify received data */\n\t    pj_bool_t ret = (*ssock->cb.on_data_read)(ssock, data, data_len, \n\t\t\t\t\t\t      status, &remainder);\n\t    if (!ret) {\n\t\t/* We've been destroyed */\n\t\treturn;\n\t    }\n\t    \n\t    /* Calculate available data for next READ operation */\n\t    if (remainder > 0) {\n\t\tpj_size_t data_maxlen = ssock->read_state.orig_buf->MaxLength();\n\t\t\n\t\t/* There is some data left unconsumed by application, we give\n\t\t * smaller buffer for next READ operation.\n\t\t */\n\t\tssock->read_state.read_buf->Set((TUint8*)data+remainder, 0, \n\t\t\t\t\t        data_maxlen - remainder);\n\t    } else {\n\t\t/* Give all buffer for next READ operation. \n\t\t */\n\t\tssock->read_state.read_buf->Set(*ssock->read_state.orig_buf);\n\t    }\n\t}\n    }\n\n    if (status == PJ_SUCCESS) {\n\t/* Perform the \"next\" READ operation */\n\tCPjSSLSocketReader *reader = ssock->sock->GetReader(); \n\tssock->read_state.read_buf->SetLength(0);\n\tstatus = reader->Read(&read_cb, ssock, *ssock->read_state.read_buf, \n\t\t\t      ssock->read_state.flags);\n    }\n    \n    /* Connection closed or something goes wrong */\n    if (status != PJ_SUCCESS && status != PJ_EPENDING) {\n\t/* Notify error */\n\tif (ssock->cb.on_data_read) {\n\t    pj_bool_t ret = (*ssock->cb.on_data_read)(ssock, NULL, 0, \n\t\t\t\t\t\t      status, NULL);\n\t    if (!ret) {\n\t\t/* We've been destroyed */\n\t\treturn;\n\t    }\n\t}\n\t\n\tdelete ssock->read_state.read_buf;\n\tdelete ssock->read_state.orig_buf;\n\tssock->read_state.read_buf = NULL;\n\tssock->read_state.orig_buf = NULL;\n\tssock->established = PJ_FALSE;\n    }\n}\n\n/*\n * Same as #pj_ssl_sock_start_read(), except that the application\n * supplies the buffers for the read operation so that the acive socket\n * does not have to allocate the buffers.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_start_read2 (pj_ssl_sock_t *ssock,\n\t\t\t\t\t     pj_pool_t *pool,\n\t\t\t\t\t     unsigned buff_size,\n\t\t\t\t\t     void *readbuf[],\n\t\t\t\t\t     pj_uint32_t flags)\n{\n    PJ_ASSERT_RETURN(ssock && buff_size && readbuf, PJ_EINVAL);\n    PJ_ASSERT_RETURN(ssock->established, PJ_EINVALIDOP);\n    \n    /* Return failure if access point is marked as down by app. */\n    PJ_SYMBIAN_CHECK_CONNECTION();\n    \n    /* Reading is already started */\n    if (ssock->read_state.orig_buf) {\n\treturn PJ_SUCCESS;\n    }\n    \n    PJ_UNUSED_ARG(pool);\n\n    /* Get reader instance */\n    CPjSSLSocketReader *reader = ssock->sock->GetReader();\n    if (!reader)\n\treturn PJ_ENOMEM;\n    \n    /* We manage two buffer pointers here:\n     * 1. orig_buf keeps the orginal buffer address (and its max length).\n     * 2. read_buf provides buffer for READ operation, mind that there may be\n     *    some remainder data left by application.\n     */\n    ssock->read_state.read_buf = new TPtr8((TUint8*)readbuf[0], 0, buff_size);\n    ssock->read_state.orig_buf = new TPtr8((TUint8*)readbuf[0], 0, buff_size);\n    ssock->read_state.flags = flags;\n    \n    pj_status_t status;\n    status = reader->Read(&read_cb, ssock, *ssock->read_state.read_buf, \n\t\t\t  ssock->read_state.flags);\n    \n    if (status != PJ_SUCCESS && status != PJ_EPENDING) {\n\tdelete ssock->read_state.read_buf;\n\tdelete ssock->read_state.orig_buf;\n\tssock->read_state.read_buf = NULL;\n\tssock->read_state.orig_buf = NULL;\n\t\n\treturn status;\n    }\n    \n    return PJ_SUCCESS;\n}\n\n/*\n * Same as pj_ssl_sock_start_read(), except that this function is used\n * only for datagram sockets, and it will trigger \\a on_data_recvfrom()\n * callback instead.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_start_recvfrom (pj_ssl_sock_t *ssock,\n\t\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\t\tunsigned buff_size,\n\t\t\t\t\t\tpj_uint32_t flags)\n{\n    PJ_UNUSED_ARG(ssock);\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(buff_size);\n    PJ_UNUSED_ARG(flags);\n    return PJ_ENOTSUP;\n}\n\n/*\n * Same as #pj_ssl_sock_start_recvfrom() except that the recvfrom() \n * operation takes the buffer from the argument rather than creating\n * new ones.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_start_recvfrom2 (pj_ssl_sock_t *ssock,\n\t\t\t\t\t\t pj_pool_t *pool,\n\t\t\t\t\t\t unsigned buff_size,\n\t\t\t\t\t\t void *readbuf[],\n\t\t\t\t\t\t pj_uint32_t flags)\n{\n    PJ_UNUSED_ARG(ssock);\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(buff_size);\n    PJ_UNUSED_ARG(readbuf);\n    PJ_UNUSED_ARG(flags);\n    return PJ_ENOTSUP;\n}\n\nstatic void send_cb(int err, void *key)\n{\n    pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)key;\n    write_state_t *st = &ssock->write_state;\n\n    /* Check connection status */\n    if (err != KErrNone || !PjSymbianOS::Instance()->IsConnectionUp() ||\n\t!ssock->established) \n    {\n\tssock->established = PJ_FALSE;\n\treturn;\n    }\n\n    /* Remove sent data from buffer */\n    st->start += st->current_data->len;\n    st->len -= st->current_data->len;\n\n    /* Reset current outstanding send */\n    st->current_data = NULL;\n\n    /* Let's check if there is pending data to send */\n    if (st->len) {\n\twrite_data_t *wdata = (write_data_t*)st->start;\n\tpj_status_t status;\n\t\n\tst->send_ptr.Set((TUint8*)wdata->data, (TInt)wdata->data_len);\n\tst->current_data = wdata;\n\tstatus = ssock->sock->Send(&send_cb, ssock, st->send_ptr, 0);\n\tif (status != PJ_EPENDING) {\n\t    ssock->established = PJ_FALSE;\n\t    st->len = 0;\n\t    return;\n\t}\n    } else {\n        /* Buffer empty, reset the start position */\n        st->start = st->buf;\n    }\n}\n\n/*\n * Send data using the socket.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_send (pj_ssl_sock_t *ssock,\n\t\t\t\t      pj_ioqueue_op_key_t *send_key,\n\t\t\t\t      const void *data,\n\t\t\t\t      pj_ssize_t *size,\n\t\t\t\t      unsigned flags)\n{\n    PJ_CHECK_STACK();\n    PJ_ASSERT_RETURN(ssock && data && size, PJ_EINVAL);\n    PJ_ASSERT_RETURN(ssock->write_state.max_len == 0 || \n\t\t     ssock->write_state.max_len >= (pj_size_t)*size, \n\t\t     PJ_ETOOSMALL);\n    \n    /* Check connection status */\n    if (!PjSymbianOS::Instance()->IsConnectionUp() || !ssock->established) \n    {\n\tssock->established = PJ_FALSE;\n\treturn PJ_ECANCELLED;\n    }\n\n    write_state_t *st = &ssock->write_state;\n    \n    /* Synchronous mode */\n    if (st->max_len == 0) {\n\tst->send_ptr.Set((TUint8*)data, (TInt)*size);\n\treturn ssock->sock->SendSync(st->send_ptr, flags);\n    }\n\n    /* CSecureSocket only allows one outstanding send operation, so\n     * we use buffering mechanism to allow application to perform send \n     * operations at any time.\n     */\n    \n    pj_size_t needed_len = *size + sizeof(write_data_t) - 1;\n    \n    /* Align needed_len to be multiplication of 4 */\n    needed_len = ((needed_len + 3) >> 2) << 2; \n\n    /* Block until there is buffer slot available and contiguous! */\n    while (st->start + st->len + needed_len > st->buf + st->max_len) {\n\tpj_symbianos_poll(-1, -1);\n    }\n\n    /* Push back the send data into the buffer */\n    write_data_t *wdata = (write_data_t*)(st->start + st->len);\n    \n    wdata->len = needed_len;\n    wdata->key = send_key;\n    wdata->data_len = (pj_size_t)*size;\n    pj_memcpy(wdata->data, data, *size);\n    st->len += needed_len;\n\n    /* If no outstanding send, send it */\n    if (st->current_data == NULL) {\n\tpj_status_t status;\n\t    \n\twdata = (write_data_t*)st->start;\n\tst->current_data = wdata;\n\tst->send_ptr.Set((TUint8*)wdata->data, (TInt)wdata->data_len);\n\tstatus = ssock->sock->Send(&send_cb, ssock, st->send_ptr, flags);\n\t\n\tif (status != PJ_EPENDING) {\n\t    *size = -status;\n\t    return status;\n\t}\n    }\n    \n    return PJ_SUCCESS;\n}\n\n/*\n * Send datagram using the socket.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_sendto (pj_ssl_sock_t *ssock,\n\t\t\t\t\tpj_ioqueue_op_key_t *send_key,\n\t\t\t\t\tconst void *data,\n\t\t\t\t\tpj_ssize_t *size,\n\t\t\t\t\tunsigned flags,\n\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\tint addr_len)\n{\n    PJ_UNUSED_ARG(ssock);\n    PJ_UNUSED_ARG(send_key);\n    PJ_UNUSED_ARG(data);\n    PJ_UNUSED_ARG(size);\n    PJ_UNUSED_ARG(flags);\n    PJ_UNUSED_ARG(addr);\n    PJ_UNUSED_ARG(addr_len);\n    return PJ_ENOTSUP;\n}\n\n/*\n * Starts asynchronous socket accept() operations on this SSL socket. \n */\nPJ_DEF(pj_status_t) pj_ssl_sock_start_accept (pj_ssl_sock_t *ssock,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      const pj_sockaddr_t *local_addr,\n\t\t\t\t\t      int addr_len)\n{\n    PJ_UNUSED_ARG(ssock);\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(local_addr);\n    PJ_UNUSED_ARG(addr_len);\n    \n    return PJ_ENOTSUP;\n}\n\nstatic void connect_cb(int err, void *key)\n{\n    pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)key;\n    pj_status_t status;\n    \n    if (ssock->connect_timer) {\n\tdelete ssock->connect_timer;\n\tssock->connect_timer = NULL;\n    }\n\n    status = (err == KErrNone)? PJ_SUCCESS : PJ_RETURN_OS_ERROR(err);\n    if (status == PJ_SUCCESS) {\n\tssock->established = PJ_TRUE;\n\tupdate_certs_info(ssock);\n    } else {\n\tdelete ssock->sock;\n\tssock->sock = NULL;\n\tif (err == KErrTimedOut) status = PJ_ETIMEDOUT;\n    }\n    \n    if (ssock->cb.on_connect_complete) {\n\tpj_bool_t ret = (*ssock->cb.on_connect_complete)(ssock, status);\n\tif (!ret) {\n\t    /* We've been destroyed */\n\t    return;\n\t}\n    }\n}\n\nstatic void connect_timer_cb(void *key)\n{\n    connect_cb(KErrTimedOut, key);\n}\n\n/*\n * Starts asynchronous socket connect() operation and SSL/TLS handshaking \n * for this socket. Once the connection is done (either successfully or not),\n * the \\a on_connect_complete() callback will be called.\n */\nPJ_DEF(pj_status_t) pj_ssl_sock_start_connect (pj_ssl_sock_t *ssock,\n\t\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t\t       const pj_sockaddr_t *localaddr,\n\t\t\t\t\t       const pj_sockaddr_t *remaddr,\n\t\t\t\t\t       int addr_len)\n{\n    CPjSSLSocket *sock = NULL;\n    pj_status_t status;\n    \n    PJ_ASSERT_RETURN(ssock && pool && localaddr && remaddr && addr_len,\n\t\t     PJ_EINVAL);\n\n    /* Check connection status */\n    PJ_SYMBIAN_CHECK_CONNECTION();\n    \n    if (ssock->sock != NULL) {\n\tCPjSSLSocket::ssl_state state = ssock->sock->GetState();\n\tswitch (state) {\n\tcase CPjSSLSocket::SSL_STATE_ESTABLISHED:\n\t    return PJ_SUCCESS;\n\tdefault:\n\t    return PJ_EPENDING;\n\t}\n    }\n\n    /* Set SSL protocol */\n    TPtrC8 proto;\n    \n    if (ssock->proto == PJ_SSL_SOCK_PROTO_DEFAULT)\n\tssock->proto = PJ_SSL_SOCK_PROTO_TLS1;\n\n    /* CSecureSocket only support TLS1.0 and SSL3.0 */\n    if (ssock->proto & PJ_SSL_SOCK_PROTO_TLS1==PJ_SSL_SOCK_PROTO_TLS1) {\n\tproto.Set((const TUint8*)\"TLS1.0\", 6);\n    } else if (ssock->proto & PJ_SSL_SOCK_PROTO_SSL3==PJ_SSL_SOCK_PROTO_SSL3) {\n\tproto.Set((const TUint8*)\"SSL3.0\", 6);\n    } else {\n\treturn PJ_ENOTSUP;\n    }\n\n    /* Prepare addresses */\n    TInetAddr localaddr_, remaddr_;\n    status = PjSymbianOS::pj2Addr(*(pj_sockaddr*)localaddr, addr_len, \n\t\t\t\t  localaddr_);\n    if (status != PJ_SUCCESS)\n\treturn status;\n    \n    status = PjSymbianOS::pj2Addr(*(pj_sockaddr*)remaddr, addr_len,\n\t\t\t\t  remaddr_);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_sockaddr_cp((pj_sockaddr_t*)&ssock->rem_addr, remaddr);\n\n    /* Init SSL engine */\n    TRAPD(err, sock = CPjSSLSocket::NewL(proto, ssock->qos_type, \n\t\t\t\t         ssock->qos_params));\n    if (err != KErrNone)\n\treturn PJ_ENOMEM;\n    \n    if (ssock->timeout.sec != 0 || ssock->timeout.msec != 0) {\n\tssock->connect_timer = new CPjTimer(&ssock->timeout, \n\t\t\t\t\t    &connect_timer_cb, ssock);\n    }\n    \n    /* Convert server name to Symbian descriptor */\n    TPtrC8 servername_((TUint8*)ssock->servername.ptr, \n\t\t       ssock->servername.slen);\n    \n    /* Convert cipher list to Symbian descriptor */\n    TPtrC8 ciphers_((TUint8*)ssock->ciphers.ptr, \n\t\t    ssock->ciphers.slen);\n    \n    /* Try to connect */\n    status = sock->Connect(&connect_cb, ssock, localaddr_, remaddr_,\n\t\t\t   servername_, ciphers_);\n    if (status != PJ_SUCCESS && status != PJ_EPENDING) {\n\tdelete sock;\n\treturn status;\n    }\n\n    ssock->sock = sock;\n    return status;\n}\n\n\nPJ_DEF(pj_status_t) pj_ssl_sock_renegotiate(pj_ssl_sock_t *ssock)\n{\n    PJ_UNUSED_ARG(ssock);\n    return PJ_ENOTSUP;\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/string.c",
    "content": "/* $Id: string.c 4440 2013-03-14 07:18:13Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/string.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n#include <pj/ctype.h>\n#include <pj/rand.h>\n#include <pj/os.h>\n\n#if PJ_FUNCTIONS_ARE_INLINED==0\n#  include <pj/string_i.h>\n#endif\n\n\nPJ_DEF(char*) pj_strstr(const pj_str_t *str, const pj_str_t *substr)\n{\n    const char *s, *ends;\n\n    /* Special case when substr is zero */\n    if (substr->slen == 0) {\n\treturn (char*)str->ptr;\n    }\n\n    s = str->ptr;\n    ends = str->ptr + str->slen - substr->slen;\n    for (; s<=ends; ++s) {\n\tif (pj_ansi_strncmp(s, substr->ptr, substr->slen)==0)\n\t    return (char*)s;\n    }\n    return NULL;\n}\n\n\nPJ_DEF(char*) pj_stristr(const pj_str_t *str, const pj_str_t *substr)\n{\n    const char *s, *ends;\n\n    /* Special case when substr is zero */\n    if (substr->slen == 0) {\n\treturn (char*)str->ptr;\n    }\n\n    s = str->ptr;\n    ends = str->ptr + str->slen - substr->slen;\n    for (; s<=ends; ++s) {\n\tif (pj_ansi_strnicmp(s, substr->ptr, substr->slen)==0)\n\t    return (char*)s;\n    }\n    return NULL;\n}\n\n\nPJ_DEF(pj_str_t*) pj_strltrim( pj_str_t *str )\n{\n    char *end = str->ptr + str->slen;\n    register char *p = str->ptr;\n    while (p < end && pj_isspace(*p))\n\t++p;\n    str->slen -= (p - str->ptr);\n    str->ptr = p;\n    return str;\n}\n\nPJ_DEF(pj_str_t*) pj_strrtrim( pj_str_t *str )\n{\n    char *end = str->ptr + str->slen;\n    register char *p = end - 1;\n    while (p >= str->ptr && pj_isspace(*p))\n        --p;\n    str->slen -= ((end - p) - 1);\n    return str;\n}\n\nPJ_DEF(char*) pj_create_random_string(char *str, pj_size_t len)\n{\n    unsigned i;\n    char *p = str;\n\n    PJ_CHECK_STACK();\n\n    for (i=0; i<len/8; ++i) {\n\tpj_uint32_t val = pj_rand();\n\tpj_val_to_hex_digit( (val & 0xFF000000) >> 24, p+0 );\n\tpj_val_to_hex_digit( (val & 0x00FF0000) >> 16, p+2 );\n\tpj_val_to_hex_digit( (val & 0x0000FF00) >>  8, p+4 );\n\tpj_val_to_hex_digit( (val & 0x000000FF) >>  0, p+6 );\n\tp += 8;\n    }\n    for (i=i * 8; i<len; ++i) {\n\t*p++ = pj_hex_digits[ pj_rand() & 0x0F ];\n    }\n    return str;\n}\n\nPJ_DEF(long) pj_strtol(const pj_str_t *str)\n{\n    PJ_CHECK_STACK();\n\n    if (str->slen > 0 && (str->ptr[0] == '+' || str->ptr[0] == '-')) {\n        pj_str_t s;\n        \n        s.ptr = str->ptr + 1;\n        s.slen = str->slen - 1;\n        return (str->ptr[0] == '-'? -(long)pj_strtoul(&s) : pj_strtoul(&s));\n    } else\n        return pj_strtoul(str);\n}\n\nPJ_DEF(unsigned long) pj_strtoul(const pj_str_t *str)\n{\n    unsigned long value;\n    unsigned i;\n\n    PJ_CHECK_STACK();\n\n    value = 0;\n    for (i=0; i<(unsigned)str->slen; ++i) {\n\tif (!pj_isdigit(str->ptr[i]))\n\t    break;\n\tvalue = value * 10 + (str->ptr[i] - '0');\n    }\n    return value;\n}\n\nPJ_DEF(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr,\n\t\t\t\t  unsigned base)\n{\n    unsigned long value;\n    unsigned i;\n\n    PJ_CHECK_STACK();\n\n    value = 0;\n    if (base <= 10) {\n\tfor (i=0; i<(unsigned)str->slen; ++i) {\n\t    unsigned c = (str->ptr[i] - '0');\n\t    if (c >= base)\n\t\tbreak;\n\t    value = value * base + c;\n\t}\n    } else if (base == 16) {\n\tfor (i=0; i<(unsigned)str->slen; ++i) {\n\t    if (!pj_isxdigit(str->ptr[i]))\n\t\tbreak;\n\t    value = value * 16 + pj_hex_digit_to_val(str->ptr[i]);\n\t}\n    } else {\n\tpj_assert(!\"Unsupported base\");\n\ti = 0;\n\tvalue = 0xFFFFFFFFUL;\n    }\n\n    if (endptr) {\n\tendptr->ptr = str->ptr + i;\n\tendptr->slen = str->slen - i;\n    }\n\n    return value;\n}\n\nPJ_DEF(float) pj_strtof(const pj_str_t *str)\n{\n    pj_str_t part;\n    char *pdot;\n    float val;\n\n    if (str->slen == 0)\n\treturn 0;\n\n    pdot = (char*)pj_memchr(str->ptr, '.', str->slen);\n    part.ptr = str->ptr;\n    part.slen = pdot ? pdot - str->ptr : str->slen;\n\n    if (part.slen)\n\tval = (float)pj_strtol(&part);\n    else\n\tval = 0;\n\n    if (pdot) {\n\tpart.ptr = pdot + 1;\n\tpart.slen = (str->ptr + str->slen - pdot - 1);\n\tif (part.slen) {\n\t    pj_str_t endptr;\n\t    float fpart, fdiv;\n\t    int i;\n\t    fpart = (float)pj_strtoul2(&part, &endptr, 10);\n\t    fdiv = 1.0;\n\t    for (i=0; i<(part.slen - endptr.slen); ++i)\n\t\t    fdiv = fdiv * 10;\n\t    if (val >= 0)\n\t\tval += (fpart / fdiv);\n\t    else\n\t\tval -= (fpart / fdiv);\n\t}\n    }\n    return val;\n}\n\nPJ_DEF(int) pj_utoa(unsigned long val, char *buf)\n{\n    return pj_utoa_pad(val, buf, 0, 0);\n}\n\nPJ_DEF(int) pj_utoa_pad( unsigned long val, char *buf, int min_dig, int pad)\n{\n    char *p;\n    int len;\n\n    PJ_CHECK_STACK();\n\n    p = buf;\n    do {\n        unsigned long digval = (unsigned long) (val % 10);\n        val /= 10;\n        *p++ = (char) (digval + '0');\n    } while (val > 0);\n\n    len = (int)(p-buf);\n    while (len < min_dig) {\n\t*p++ = (char)pad;\n\t++len;\n    }\n    *p-- = '\\0';\n\n    do {\n        char temp = *p;\n        *p = *buf;\n        *buf = temp;\n        --p;\n        ++buf;\n    } while (buf < p);\n\n    return len;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/symbols.c",
    "content": "/* $Id: symbols.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib.h>\n\n/*\n * addr_resolv.h\n */\nPJ_EXPORT_SYMBOL(pj_gethostbyname)\n\n/*\n * array.h\n */\nPJ_EXPORT_SYMBOL(pj_array_insert)\nPJ_EXPORT_SYMBOL(pj_array_erase)\nPJ_EXPORT_SYMBOL(pj_array_find)\n\n/*\n * config.h\n */\nPJ_EXPORT_SYMBOL(pj_dump_config)\n\t\n/*\n * errno.h\n */\nPJ_EXPORT_SYMBOL(pj_get_os_error)\nPJ_EXPORT_SYMBOL(pj_set_os_error)\nPJ_EXPORT_SYMBOL(pj_get_netos_error)\nPJ_EXPORT_SYMBOL(pj_set_netos_error)\nPJ_EXPORT_SYMBOL(pj_strerror)\n\n/*\n * except.h\n */\nPJ_EXPORT_SYMBOL(pj_throw_exception_)\nPJ_EXPORT_SYMBOL(pj_push_exception_handler_)\nPJ_EXPORT_SYMBOL(pj_pop_exception_handler_)\nPJ_EXPORT_SYMBOL(pj_setjmp)\nPJ_EXPORT_SYMBOL(pj_longjmp)\nPJ_EXPORT_SYMBOL(pj_exception_id_alloc)\nPJ_EXPORT_SYMBOL(pj_exception_id_free)\nPJ_EXPORT_SYMBOL(pj_exception_id_name)\n\n\n/*\n * fifobuf.h\n */\nPJ_EXPORT_SYMBOL(pj_fifobuf_init)\nPJ_EXPORT_SYMBOL(pj_fifobuf_max_size)\nPJ_EXPORT_SYMBOL(pj_fifobuf_alloc)\nPJ_EXPORT_SYMBOL(pj_fifobuf_unalloc)\nPJ_EXPORT_SYMBOL(pj_fifobuf_free)\n\n/*\n * guid.h\n */\nPJ_EXPORT_SYMBOL(pj_generate_unique_string)\nPJ_EXPORT_SYMBOL(pj_create_unique_string)\n\n/*\n * hash.h\n */\nPJ_EXPORT_SYMBOL(pj_hash_calc)\nPJ_EXPORT_SYMBOL(pj_hash_create)\nPJ_EXPORT_SYMBOL(pj_hash_get)\nPJ_EXPORT_SYMBOL(pj_hash_set)\nPJ_EXPORT_SYMBOL(pj_hash_count)\nPJ_EXPORT_SYMBOL(pj_hash_first)\nPJ_EXPORT_SYMBOL(pj_hash_next)\nPJ_EXPORT_SYMBOL(pj_hash_this)\n\n/*\n * ioqueue.h\n */\nPJ_EXPORT_SYMBOL(pj_ioqueue_create)\nPJ_EXPORT_SYMBOL(pj_ioqueue_destroy)\nPJ_EXPORT_SYMBOL(pj_ioqueue_set_lock)\nPJ_EXPORT_SYMBOL(pj_ioqueue_register_sock)\nPJ_EXPORT_SYMBOL(pj_ioqueue_unregister)\nPJ_EXPORT_SYMBOL(pj_ioqueue_get_user_data)\nPJ_EXPORT_SYMBOL(pj_ioqueue_poll)\nPJ_EXPORT_SYMBOL(pj_ioqueue_read)\nPJ_EXPORT_SYMBOL(pj_ioqueue_recv)\nPJ_EXPORT_SYMBOL(pj_ioqueue_recvfrom)\nPJ_EXPORT_SYMBOL(pj_ioqueue_write)\nPJ_EXPORT_SYMBOL(pj_ioqueue_send)\nPJ_EXPORT_SYMBOL(pj_ioqueue_sendto)\n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0\nPJ_EXPORT_SYMBOL(pj_ioqueue_accept)\nPJ_EXPORT_SYMBOL(pj_ioqueue_connect)\n#endif\n\n/*\n * list.h\n */\nPJ_EXPORT_SYMBOL(pj_list_insert_before)\nPJ_EXPORT_SYMBOL(pj_list_insert_nodes_before)\nPJ_EXPORT_SYMBOL(pj_list_insert_after)\nPJ_EXPORT_SYMBOL(pj_list_insert_nodes_after)\nPJ_EXPORT_SYMBOL(pj_list_merge_first)\nPJ_EXPORT_SYMBOL(pj_list_merge_last)\nPJ_EXPORT_SYMBOL(pj_list_erase)\nPJ_EXPORT_SYMBOL(pj_list_find_node)\nPJ_EXPORT_SYMBOL(pj_list_search)\n\n\n/*\n * log.h\n */\nPJ_EXPORT_SYMBOL(pj_log_write)\n#if PJ_LOG_MAX_LEVEL >= 1\nPJ_EXPORT_SYMBOL(pj_log_set_log_func)\nPJ_EXPORT_SYMBOL(pj_log_get_log_func)\nPJ_EXPORT_SYMBOL(pj_log_set_level)\nPJ_EXPORT_SYMBOL(pj_log_get_level)\nPJ_EXPORT_SYMBOL(pj_log_set_decor)\nPJ_EXPORT_SYMBOL(pj_log_get_decor)\nPJ_EXPORT_SYMBOL(pj_log_1)\n#endif\n#if PJ_LOG_MAX_LEVEL >= 2\nPJ_EXPORT_SYMBOL(pj_log_2)\n#endif\n#if PJ_LOG_MAX_LEVEL >= 3\nPJ_EXPORT_SYMBOL(pj_log_3)\n#endif\n#if PJ_LOG_MAX_LEVEL >= 4\nPJ_EXPORT_SYMBOL(pj_log_4)\n#endif\n#if PJ_LOG_MAX_LEVEL >= 5\nPJ_EXPORT_SYMBOL(pj_log_5)\n#endif\n#if PJ_LOG_MAX_LEVEL >= 6\nPJ_EXPORT_SYMBOL(pj_log_6)\n#endif\n\n/*\n * os.h\n */\nPJ_EXPORT_SYMBOL(pj_init)\nPJ_EXPORT_SYMBOL(pj_getpid)\nPJ_EXPORT_SYMBOL(pj_thread_register)\nPJ_EXPORT_SYMBOL(pj_thread_create)\nPJ_EXPORT_SYMBOL(pj_thread_get_name)\nPJ_EXPORT_SYMBOL(pj_thread_resume)\nPJ_EXPORT_SYMBOL(pj_thread_this)\nPJ_EXPORT_SYMBOL(pj_thread_join)\nPJ_EXPORT_SYMBOL(pj_thread_destroy)\nPJ_EXPORT_SYMBOL(pj_thread_sleep)\n#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK != 0\nPJ_EXPORT_SYMBOL(pj_thread_check_stack)\nPJ_EXPORT_SYMBOL(pj_thread_get_stack_max_usage)\nPJ_EXPORT_SYMBOL(pj_thread_get_stack_info)\n#endif\nPJ_EXPORT_SYMBOL(pj_atomic_create)\nPJ_EXPORT_SYMBOL(pj_atomic_destroy)\nPJ_EXPORT_SYMBOL(pj_atomic_set)\nPJ_EXPORT_SYMBOL(pj_atomic_get)\nPJ_EXPORT_SYMBOL(pj_atomic_inc)\nPJ_EXPORT_SYMBOL(pj_atomic_dec)\nPJ_EXPORT_SYMBOL(pj_thread_local_alloc)\nPJ_EXPORT_SYMBOL(pj_thread_local_free)\nPJ_EXPORT_SYMBOL(pj_thread_local_set)\nPJ_EXPORT_SYMBOL(pj_thread_local_get)\nPJ_EXPORT_SYMBOL(pj_enter_critical_section)\nPJ_EXPORT_SYMBOL(pj_leave_critical_section)\nPJ_EXPORT_SYMBOL(pj_mutex_create)\nPJ_EXPORT_SYMBOL(pj_mutex_lock)\nPJ_EXPORT_SYMBOL(pj_mutex_unlock)\nPJ_EXPORT_SYMBOL(pj_mutex_trylock)\nPJ_EXPORT_SYMBOL(pj_mutex_destroy)\n#if defined(PJ_DEBUG) && PJ_DEBUG != 0\nPJ_EXPORT_SYMBOL(pj_mutex_is_locked)\n#endif\n#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0\nPJ_EXPORT_SYMBOL(pj_sem_create)\nPJ_EXPORT_SYMBOL(pj_sem_wait)\nPJ_EXPORT_SYMBOL(pj_sem_trywait)\nPJ_EXPORT_SYMBOL(pj_sem_post)\nPJ_EXPORT_SYMBOL(pj_sem_destroy)\n#endif\nPJ_EXPORT_SYMBOL(pj_gettimeofday)\nPJ_EXPORT_SYMBOL(pj_time_decode)\n#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0\nPJ_EXPORT_SYMBOL(pj_gettickcount)\nPJ_EXPORT_SYMBOL(pj_get_timestamp)\nPJ_EXPORT_SYMBOL(pj_get_timestamp_freq)\nPJ_EXPORT_SYMBOL(pj_elapsed_time)\nPJ_EXPORT_SYMBOL(pj_elapsed_usec)\nPJ_EXPORT_SYMBOL(pj_elapsed_nanosec)\nPJ_EXPORT_SYMBOL(pj_elapsed_cycle)\n#endif\n\n\t\n/*\n * pool.h\n */\nPJ_EXPORT_SYMBOL(pj_pool_create)\nPJ_EXPORT_SYMBOL(pj_pool_release)\nPJ_EXPORT_SYMBOL(pj_pool_getobjname)\nPJ_EXPORT_SYMBOL(pj_pool_reset)\nPJ_EXPORT_SYMBOL(pj_pool_get_capacity)\nPJ_EXPORT_SYMBOL(pj_pool_get_used_size)\nPJ_EXPORT_SYMBOL(pj_pool_alloc)\nPJ_EXPORT_SYMBOL(pj_pool_calloc)\nPJ_EXPORT_SYMBOL(pj_pool_factory_default_policy)\nPJ_EXPORT_SYMBOL(pj_pool_create_int)\nPJ_EXPORT_SYMBOL(pj_pool_init_int)\nPJ_EXPORT_SYMBOL(pj_pool_destroy_int)\nPJ_EXPORT_SYMBOL(pj_caching_pool_init)\nPJ_EXPORT_SYMBOL(pj_caching_pool_destroy)\n\n/*\n * rand.h\n */\nPJ_EXPORT_SYMBOL(pj_rand)\nPJ_EXPORT_SYMBOL(pj_srand)\n\n/*\n * rbtree.h\n */\nPJ_EXPORT_SYMBOL(pj_rbtree_init)\nPJ_EXPORT_SYMBOL(pj_rbtree_first)\nPJ_EXPORT_SYMBOL(pj_rbtree_last)\nPJ_EXPORT_SYMBOL(pj_rbtree_next)\nPJ_EXPORT_SYMBOL(pj_rbtree_prev)\nPJ_EXPORT_SYMBOL(pj_rbtree_insert)\nPJ_EXPORT_SYMBOL(pj_rbtree_find)\nPJ_EXPORT_SYMBOL(pj_rbtree_erase)\nPJ_EXPORT_SYMBOL(pj_rbtree_max_height)\nPJ_EXPORT_SYMBOL(pj_rbtree_min_height)\n\n/*\n * sock.h\n */\nPJ_EXPORT_SYMBOL(PJ_AF_UNIX)\nPJ_EXPORT_SYMBOL(PJ_AF_INET)\nPJ_EXPORT_SYMBOL(PJ_AF_INET6)\nPJ_EXPORT_SYMBOL(PJ_AF_PACKET)\nPJ_EXPORT_SYMBOL(PJ_AF_IRDA)\nPJ_EXPORT_SYMBOL(PJ_SOCK_STREAM)\nPJ_EXPORT_SYMBOL(PJ_SOCK_DGRAM)\nPJ_EXPORT_SYMBOL(PJ_SOCK_RAW)\nPJ_EXPORT_SYMBOL(PJ_SOCK_RDM)\nPJ_EXPORT_SYMBOL(PJ_SOL_SOCKET)\nPJ_EXPORT_SYMBOL(PJ_SOL_IP)\nPJ_EXPORT_SYMBOL(PJ_SOL_TCP)\nPJ_EXPORT_SYMBOL(PJ_SOL_UDP)\nPJ_EXPORT_SYMBOL(PJ_SOL_IPV6)\nPJ_EXPORT_SYMBOL(pj_ntohs)\nPJ_EXPORT_SYMBOL(pj_htons)\nPJ_EXPORT_SYMBOL(pj_ntohl)\nPJ_EXPORT_SYMBOL(pj_htonl)\nPJ_EXPORT_SYMBOL(pj_inet_ntoa)\nPJ_EXPORT_SYMBOL(pj_inet_aton)\nPJ_EXPORT_SYMBOL(pj_inet_addr)\nPJ_EXPORT_SYMBOL(pj_sockaddr_in_set_str_addr)\nPJ_EXPORT_SYMBOL(pj_sockaddr_in_init)\nPJ_EXPORT_SYMBOL(pj_gethostname)\nPJ_EXPORT_SYMBOL(pj_gethostaddr)\nPJ_EXPORT_SYMBOL(pj_sock_socket)\nPJ_EXPORT_SYMBOL(pj_sock_close)\nPJ_EXPORT_SYMBOL(pj_sock_bind)\nPJ_EXPORT_SYMBOL(pj_sock_bind_in)\n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0\nPJ_EXPORT_SYMBOL(pj_sock_listen)\nPJ_EXPORT_SYMBOL(pj_sock_accept)\nPJ_EXPORT_SYMBOL(pj_sock_shutdown)\n#endif\nPJ_EXPORT_SYMBOL(pj_sock_connect)\nPJ_EXPORT_SYMBOL(pj_sock_getpeername)\nPJ_EXPORT_SYMBOL(pj_sock_getsockname)\nPJ_EXPORT_SYMBOL(pj_sock_getsockopt)\nPJ_EXPORT_SYMBOL(pj_sock_setsockopt)\nPJ_EXPORT_SYMBOL(pj_sock_recv)\nPJ_EXPORT_SYMBOL(pj_sock_recvfrom)\nPJ_EXPORT_SYMBOL(pj_sock_send)\nPJ_EXPORT_SYMBOL(pj_sock_sendto)\n\n/*\n * sock_select.h\n */\nPJ_EXPORT_SYMBOL(PJ_FD_ZERO)\nPJ_EXPORT_SYMBOL(PJ_FD_SET)\nPJ_EXPORT_SYMBOL(PJ_FD_CLR)\nPJ_EXPORT_SYMBOL(PJ_FD_ISSET)\nPJ_EXPORT_SYMBOL(pj_sock_select)\n\n/*\n * string.h\n */\nPJ_EXPORT_SYMBOL(pj_str)\nPJ_EXPORT_SYMBOL(pj_strassign)\nPJ_EXPORT_SYMBOL(pj_strcpy)\nPJ_EXPORT_SYMBOL(pj_strcpy2)\nPJ_EXPORT_SYMBOL(pj_strdup)\nPJ_EXPORT_SYMBOL(pj_strdup_with_null)\nPJ_EXPORT_SYMBOL(pj_strdup2)\nPJ_EXPORT_SYMBOL(pj_strdup3)\nPJ_EXPORT_SYMBOL(pj_strcmp)\nPJ_EXPORT_SYMBOL(pj_strcmp2)\nPJ_EXPORT_SYMBOL(pj_strncmp)\nPJ_EXPORT_SYMBOL(pj_strncmp2)\nPJ_EXPORT_SYMBOL(pj_stricmp)\nPJ_EXPORT_SYMBOL(pj_stricmp2)\nPJ_EXPORT_SYMBOL(pj_strnicmp)\nPJ_EXPORT_SYMBOL(pj_strnicmp2)\nPJ_EXPORT_SYMBOL(pj_strcat)\nPJ_EXPORT_SYMBOL(pj_strltrim)\nPJ_EXPORT_SYMBOL(pj_strrtrim)\nPJ_EXPORT_SYMBOL(pj_strtrim)\nPJ_EXPORT_SYMBOL(pj_create_random_string)\nPJ_EXPORT_SYMBOL(pj_strtoul)\nPJ_EXPORT_SYMBOL(pj_utoa)\nPJ_EXPORT_SYMBOL(pj_utoa_pad)\n\n/*\n * timer.h\n */\nPJ_EXPORT_SYMBOL(pj_timer_heap_mem_size)\nPJ_EXPORT_SYMBOL(pj_timer_heap_create)\nPJ_EXPORT_SYMBOL(pj_timer_entry_init)\nPJ_EXPORT_SYMBOL(pj_timer_heap_schedule)\nPJ_EXPORT_SYMBOL(pj_timer_heap_cancel)\nPJ_EXPORT_SYMBOL(pj_timer_heap_count)\nPJ_EXPORT_SYMBOL(pj_timer_heap_earliest_time)\nPJ_EXPORT_SYMBOL(pj_timer_heap_poll)\n\n/*\n * types.h\n */\nPJ_EXPORT_SYMBOL(pj_time_val_normalize)\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/timer.c",
    "content": "/* $Id: timer.c 4449 2013-03-22 03:16:35Z bennylp $ */\n/* \n * The PJLIB's timer heap is based (or more correctly, copied and modied)\n * from ACE library by Douglas C. Schmidt. ACE is an excellent OO framework\n * that implements many core patterns for concurrent communication software.\n * If you're looking for C++ alternative of PJLIB, then ACE is your best\n * solution.\n *\n * You may use this file according to ACE open source terms or PJLIB open\n * source terms. You can find the fine ACE library at:\n *  http://www.cs.wustl.edu/~schmidt/ACE.html\n *\n * ACE is Copyright (C)1993-2006 Douglas C. Schmidt <d.schmidt@vanderbilt.edu>\n *\n * GNU Public License:\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/timer.h>\n#include <pj/pool.h>\n#include <pj/os.h>\n#include <pj/string.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/rand.h>\n\n#define THIS_FILE\t\"timer.c\"\n\n#define HEAP_PARENT(X)\t(X == 0 ? 0 : (((X) - 1) / 2))\n#define HEAP_LEFT(X)\t(((X)+(X))+1)\n\n\n#define DEFAULT_MAX_TIMED_OUT_PER_POLL  (64)\n\nenum\n{\n    F_DONT_CALL = 1,\n    F_DONT_ASSERT = 2,\n    F_SET_ID = 4\n};\n\n\n/**\n * The implementation of timer heap.\n */\nstruct pj_timer_heap_t\n{\n    /** Pool from which the timer heap resize will get the storage from */\n    pj_pool_t *pool;\n\n    /** Maximum size of the heap. */\n    pj_size_t max_size;\n\n    /** Current size of the heap. */\n    pj_size_t cur_size;\n\n    /** Max timed out entries to process per poll. */\n    unsigned max_entries_per_poll;\n\n    /** Lock object. */\n    pj_lock_t *lock;\n\n    /** Autodelete lock. */\n    pj_bool_t auto_delete_lock;\n\n    /**\n     * Current contents of the Heap, which is organized as a \"heap\" of\n     * pj_timer_entry *'s.  In this context, a heap is a \"partially\n     * ordered, almost complete\" binary tree, which is stored in an\n     * array.\n     */\n    pj_timer_entry **heap;\n\n    /**\n     * An array of \"pointers\" that allows each pj_timer_entry in the\n     * <heap_> to be located in O(1) time.  Basically, <timer_id_[i]>\n     * contains the slot in the <heap_> array where an pj_timer_entry\n     * with timer id <i> resides.  Thus, the timer id passed back from\n     * <schedule_entry> is really an slot into the <timer_ids> array.  The\n     * <timer_ids_> array serves two purposes: negative values are\n     * treated as \"pointers\" for the <freelist_>, whereas positive\n     * values are treated as \"pointers\" into the <heap_> array.\n     */\n    pj_timer_id_t *timer_ids;\n\n    /**\n     * \"Pointer\" to the first element in the freelist contained within\n     * the <timer_ids_> array, which is organized as a stack.\n     */\n    pj_timer_id_t timer_ids_freelist;\n\n    /** Callback to be called when a timer expires. */\n    pj_timer_heap_callback *callback;\n\n};\n\n\n\nPJ_INLINE(void) lock_timer_heap( pj_timer_heap_t *ht )\n{\n    if (ht->lock) {\n\tpj_lock_acquire(ht->lock);\n    }\n}\n\nPJ_INLINE(void) unlock_timer_heap( pj_timer_heap_t *ht )\n{\n    if (ht->lock) {\n\tpj_lock_release(ht->lock);\n    }\n}\n\n\nstatic void copy_node( pj_timer_heap_t *ht, pj_size_t slot, \n\t\t       pj_timer_entry *moved_node )\n{\n    PJ_CHECK_STACK();\n\n    // Insert <moved_node> into its new location in the heap.\n    ht->heap[slot] = moved_node;\n    \n    // Update the corresponding slot in the parallel <timer_ids_> array.\n    ht->timer_ids[moved_node->_timer_id] = (int)slot;\n}\n\nstatic pj_timer_id_t pop_freelist( pj_timer_heap_t *ht )\n{\n    // We need to truncate this to <int> for backwards compatibility.\n    pj_timer_id_t new_id = ht->timer_ids_freelist;\n    \n    PJ_CHECK_STACK();\n\n    // The freelist values in the <timer_ids_> are negative, so we need\n    // to negate them to get the next freelist \"pointer.\"\n    ht->timer_ids_freelist =\n\t-ht->timer_ids[ht->timer_ids_freelist];\n    \n    return new_id;\n    \n}\n\nstatic void push_freelist (pj_timer_heap_t *ht, pj_timer_id_t old_id)\n{\n    PJ_CHECK_STACK();\n\n    // The freelist values in the <timer_ids_> are negative, so we need\n    // to negate them to get the next freelist \"pointer.\"\n    ht->timer_ids[old_id] = -ht->timer_ids_freelist;\n    ht->timer_ids_freelist = old_id;\n}\n\n\nstatic void reheap_down(pj_timer_heap_t *ht, pj_timer_entry *moved_node,\n                        size_t slot, size_t child)\n{\n    PJ_CHECK_STACK();\n\n    // Restore the heap property after a deletion.\n    \n    while (child < ht->cur_size)\n    {\n\t// Choose the smaller of the two children.\n\tif (child + 1 < ht->cur_size\n\t    && PJ_TIME_VAL_LT(ht->heap[child + 1]->_timer_value, ht->heap[child]->_timer_value))\n\t    child++;\n\t\n\t// Perform a <copy> if the child has a larger timeout value than\n\t// the <moved_node>.\n\tif (PJ_TIME_VAL_LT(ht->heap[child]->_timer_value, moved_node->_timer_value))\n        {\n\t    copy_node( ht, slot, ht->heap[child]);\n\t    slot = child;\n\t    child = HEAP_LEFT(child);\n        }\n\telse\n\t    // We've found our location in the heap.\n\t    break;\n    }\n    \n    copy_node( ht, slot, moved_node);\n}\n\nstatic void reheap_up( pj_timer_heap_t *ht, pj_timer_entry *moved_node,\n\t\t       size_t slot, size_t parent)\n{\n    // Restore the heap property after an insertion.\n    \n    while (slot > 0)\n    {\n\t// If the parent node is greater than the <moved_node> we need\n\t// to copy it down.\n\tif (PJ_TIME_VAL_LT(moved_node->_timer_value, ht->heap[parent]->_timer_value))\n        {\n\t    copy_node(ht, slot, ht->heap[parent]);\n\t    slot = parent;\n\t    parent = HEAP_PARENT(slot);\n        }\n\telse\n\t    break;\n    }\n    \n    // Insert the new node into its proper resting place in the heap and\n    // update the corresponding slot in the parallel <timer_ids> array.\n    copy_node(ht, slot, moved_node);\n}\n\n\nstatic pj_timer_entry * remove_node( pj_timer_heap_t *ht, size_t slot)\n{\n    pj_timer_entry *removed_node = ht->heap[slot];\n    \n    // Return this timer id to the freelist.\n    push_freelist( ht, removed_node->_timer_id );\n    \n    // Decrement the size of the heap by one since we're removing the\n    // \"slot\"th node.\n    ht->cur_size--;\n    \n    // Set the ID\n    removed_node->_timer_id = -1;\n\n    // Only try to reheapify if we're not deleting the last entry.\n    \n    if (slot < ht->cur_size)\n    {\n\tpj_size_t parent;\n\tpj_timer_entry *moved_node = ht->heap[ht->cur_size];\n\t\n\t// Move the end node to the location being removed and update\n\t// the corresponding slot in the parallel <timer_ids> array.\n\tcopy_node( ht, slot, moved_node);\n\t\n\t// If the <moved_node->time_value_> is great than or equal its\n\t// parent it needs be moved down the heap.\n\tparent = HEAP_PARENT (slot);\n\t\n\tif (PJ_TIME_VAL_GTE(moved_node->_timer_value, ht->heap[parent]->_timer_value))\n\t    reheap_down( ht, moved_node, slot, HEAP_LEFT(slot));\n\telse\n\t    reheap_up( ht, moved_node, slot, parent);\n    }\n    \n    return removed_node;\n}\n\nstatic void grow_heap(pj_timer_heap_t *ht)\n{\n    // All the containers will double in size from max_size_\n    size_t new_size = ht->max_size * 2;\n    pj_timer_id_t *new_timer_ids;\n    pj_size_t i;\n    \n    // First grow the heap itself.\n    \n    pj_timer_entry **new_heap = 0;\n    \n    new_heap = (pj_timer_entry**) \n    \t       pj_pool_alloc(ht->pool, sizeof(pj_timer_entry*) * new_size);\n    memcpy(new_heap, ht->heap, ht->max_size * sizeof(pj_timer_entry*));\n    //delete [] this->heap_;\n    ht->heap = new_heap;\n    \n    // Grow the array of timer ids.\n    \n    new_timer_ids = 0;\n    new_timer_ids = (pj_timer_id_t*)\n    \t\t    pj_pool_alloc(ht->pool, new_size * sizeof(pj_timer_id_t));\n    \n    memcpy( new_timer_ids, ht->timer_ids, ht->max_size * sizeof(pj_timer_id_t));\n    \n    //delete [] timer_ids_;\n    ht->timer_ids = new_timer_ids;\n    \n    // And add the new elements to the end of the \"freelist\".\n    for (i = ht->max_size; i < new_size; i++)\n\tht->timer_ids[i] = -((pj_timer_id_t) (i + 1));\n    \n    ht->max_size = new_size;\n}\n\nstatic void insert_node(pj_timer_heap_t *ht, pj_timer_entry *new_node)\n{\n    if (ht->cur_size + 2 >= ht->max_size)\n\tgrow_heap(ht);\n    \n    reheap_up( ht, new_node, ht->cur_size, HEAP_PARENT(ht->cur_size));\n    ht->cur_size++;\n}\n\n\nstatic pj_status_t schedule_entry( pj_timer_heap_t *ht,\n\t\t\t\t   pj_timer_entry *entry, \n\t\t\t\t   const pj_time_val *future_time )\n{\n    if (ht->cur_size < ht->max_size)\n    {\n\t// Obtain the next unique sequence number.\n\t// Set the entry\n\tentry->_timer_id = pop_freelist(ht);\n\tentry->_timer_value = *future_time;\n\tinsert_node( ht, entry);\n\treturn 0;\n    }\n    else\n\treturn -1;\n}\n\n\nstatic int cancel( pj_timer_heap_t *ht, \n\t\t   pj_timer_entry *entry, \n\t\t   unsigned flags)\n{\n  long timer_node_slot;\n\n  PJ_CHECK_STACK();\n\n  // Check to see if the timer_id is out of range\n  if (entry->_timer_id < 0 || (pj_size_t)entry->_timer_id > ht->max_size) {\n    entry->_timer_id = -1;\n    return 0;\n  }\n\n  timer_node_slot = ht->timer_ids[entry->_timer_id];\n\n  if (timer_node_slot < 0) { // Check to see if timer_id is still valid.\n    entry->_timer_id = -1;\n    return 0;\n  }\n\n  if (entry != ht->heap[timer_node_slot])\n    {\n      if ((flags & F_DONT_ASSERT) == 0)\n\t  pj_assert(entry == ht->heap[timer_node_slot]);\n      entry->_timer_id = -1;\n      return 0;\n    }\n  else\n    {\n      remove_node( ht, timer_node_slot);\n\n      if ((flags & F_DONT_CALL) == 0)\n        // Call the close hook.\n\t(*ht->callback)(ht, entry);\n      return 1;\n    }\n}\n\n\n/*\n * Calculate memory size required to create a timer heap.\n */\nPJ_DEF(pj_size_t) pj_timer_heap_mem_size(pj_size_t count)\n{\n    return /* size of the timer heap itself: */\n           sizeof(pj_timer_heap_t) + \n           /* size of each entry: */\n           (count+2) * (sizeof(pj_timer_entry*)+sizeof(pj_timer_id_t)) +\n           /* lock, pool etc: */\n           132;\n}\n\n/*\n * Create a new timer heap.\n */\nPJ_DEF(pj_status_t) pj_timer_heap_create( pj_pool_t *pool,\n\t\t\t\t\t  pj_size_t size,\n                                          pj_timer_heap_t **p_heap)\n{\n    pj_timer_heap_t *ht;\n    pj_size_t i;\n\n    PJ_ASSERT_RETURN(pool && p_heap, PJ_EINVAL);\n\n    *p_heap = NULL;\n\n    /* Magic? */\n    size += 2;\n\n    /* Allocate timer heap data structure from the pool */\n    ht = PJ_POOL_ALLOC_T(pool, pj_timer_heap_t);\n    if (!ht)\n        return PJ_ENOMEM;\n\n    /* Initialize timer heap sizes */\n    ht->max_size = size;\n    ht->cur_size = 0;\n    ht->max_entries_per_poll = DEFAULT_MAX_TIMED_OUT_PER_POLL;\n    ht->timer_ids_freelist = 1;\n    ht->pool = pool;\n\n    /* Lock. */\n    ht->lock = NULL;\n    ht->auto_delete_lock = 0;\n\n    // Create the heap array.\n    ht->heap = (pj_timer_entry**)\n    \t       pj_pool_alloc(pool, sizeof(pj_timer_entry*) * size);\n    if (!ht->heap)\n        return PJ_ENOMEM;\n\n    // Create the parallel\n    ht->timer_ids = (pj_timer_id_t *)\n    \t\t    pj_pool_alloc( pool, sizeof(pj_timer_id_t) * size);\n    if (!ht->timer_ids)\n        return PJ_ENOMEM;\n\n    // Initialize the \"freelist,\" which uses negative values to\n    // distinguish freelist elements from \"pointers\" into the <heap_>\n    // array.\n    for (i=0; i<size; ++i)\n\tht->timer_ids[i] = -((pj_timer_id_t) (i + 1));\n\n    *p_heap = ht;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void) pj_timer_heap_destroy( pj_timer_heap_t *ht )\n{\n    if (ht->lock && ht->auto_delete_lock) {\n        pj_lock_destroy(ht->lock);\n        ht->lock = NULL;\n    }\n}\n\nPJ_DEF(void) pj_timer_heap_set_lock(  pj_timer_heap_t *ht,\n                                      pj_lock_t *lock,\n                                      pj_bool_t auto_del )\n{\n    if (ht->lock && ht->auto_delete_lock)\n        pj_lock_destroy(ht->lock);\n\n    ht->lock = lock;\n    ht->auto_delete_lock = auto_del;\n}\n\n\nPJ_DEF(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht,\n                                                          unsigned count )\n{\n    unsigned old_count = ht->max_entries_per_poll;\n    ht->max_entries_per_poll = count;\n    return old_count;\n}\n\nPJ_DEF(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry,\n                                             int id,\n                                             void *user_data,\n                                             pj_timer_heap_callback *cb )\n{\n    pj_assert(entry && cb);\n\n    entry->_timer_id = -1;\n    entry->id = id;\n    entry->user_data = user_data;\n    entry->cb = cb;\n    entry->_grp_lock = NULL;\n\n    return entry;\n}\n\nPJ_DEF(pj_bool_t) pj_timer_entry_running( pj_timer_entry *entry )\n{\n    return (entry->_timer_id >= 1);\n}\n\n#if PJ_TIMER_DEBUG\nstatic pj_status_t schedule_w_grp_lock_dbg(pj_timer_heap_t *ht,\n                                           pj_timer_entry *entry,\n                                           const pj_time_val *delay,\n                                           pj_bool_t set_id,\n                                           int id_val,\n\t\t\t\t\t   pj_grp_lock_t *grp_lock,\n\t\t\t\t\t   const char *src_file,\n\t\t\t\t\t   int src_line)\n#else\nstatic pj_status_t schedule_w_grp_lock(pj_timer_heap_t *ht,\n                                       pj_timer_entry *entry,\n                                       const pj_time_val *delay,\n                                       pj_bool_t set_id,\n                                       int id_val,\n                                       pj_grp_lock_t *grp_lock)\n#endif\n{\n    pj_status_t status;\n    pj_time_val expires;\n\n    PJ_ASSERT_RETURN(ht && entry && delay, PJ_EINVAL);\n    PJ_ASSERT_RETURN(entry->cb != NULL, PJ_EINVAL);\n\n    /* Prevent same entry from being scheduled more than once */\n    PJ_ASSERT_RETURN(entry->_timer_id < 1, PJ_EINVALIDOP);\n\n#if PJ_TIMER_DEBUG\n    entry->src_file = src_file;\n    entry->src_line = src_line;\n#endif\n    pj_gettickcount(&expires);\n    PJ_TIME_VAL_ADD(expires, *delay);\n    \n    lock_timer_heap(ht);\n    status = schedule_entry(ht, entry, &expires);\n    if (status == PJ_SUCCESS) {\n\tif (set_id)\n\t    entry->id = id_val;\n\tentry->_grp_lock = grp_lock;\n\tif (entry->_grp_lock) {\n\t    pj_grp_lock_add_ref(entry->_grp_lock);\n\t}\n    }\n    unlock_timer_heap(ht);\n\n    return status;\n}\n\n\n#if PJ_TIMER_DEBUG\nPJ_DEF(pj_status_t) pj_timer_heap_schedule_dbg( pj_timer_heap_t *ht,\n\t\t\t\t\t\tpj_timer_entry *entry,\n\t\t\t\t\t\tconst pj_time_val *delay,\n\t\t\t\t\t\tconst char *src_file,\n\t\t\t\t\t\tint src_line)\n{\n    return schedule_w_grp_lock_dbg(ht, entry, delay, PJ_FALSE, 1, NULL,\n                                   src_file, src_line);\n}\n\nPJ_DEF(pj_status_t) pj_timer_heap_schedule_w_grp_lock_dbg(\n\t\t\t\t\t\tpj_timer_heap_t *ht,\n\t\t\t\t\t\tpj_timer_entry *entry,\n\t\t\t\t\t\tconst pj_time_val *delay,\n\t\t\t\t\t\tint id_val,\n                                                pj_grp_lock_t *grp_lock,\n\t\t\t\t\t\tconst char *src_file,\n\t\t\t\t\t\tint src_line)\n{\n    return schedule_w_grp_lock_dbg(ht, entry, delay, PJ_TRUE, id_val,\n                                   grp_lock, src_file, src_line);\n}\n\n#else\nPJ_DEF(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht,\n                                            pj_timer_entry *entry,\n                                            const pj_time_val *delay)\n{\n    return schedule_w_grp_lock(ht, entry, delay, PJ_FALSE, 1, NULL);\n}\n\nPJ_DEF(pj_status_t) pj_timer_heap_schedule_w_grp_lock(pj_timer_heap_t *ht,\n                                                      pj_timer_entry *entry,\n                                                      const pj_time_val *delay,\n                                                      int id_val,\n                                                      pj_grp_lock_t *grp_lock)\n{\n    return schedule_w_grp_lock(ht, entry, delay, PJ_TRUE, id_val, grp_lock);\n}\n#endif\n\nstatic int cancel_timer(pj_timer_heap_t *ht,\n\t\t\tpj_timer_entry *entry,\n\t\t\tunsigned flags,\n\t\t\tint id_val)\n{\n    int count;\n\n    PJ_ASSERT_RETURN(ht && entry, PJ_EINVAL);\n\n    lock_timer_heap(ht);\n    count = cancel(ht, entry, flags | F_DONT_CALL);\n    if (flags & F_SET_ID) {\n\tentry->id = id_val;\n    }\n    if (entry->_grp_lock) {\n\tpj_grp_lock_t *grp_lock = entry->_grp_lock;\n\tentry->_grp_lock = NULL;\n\tpj_grp_lock_dec_ref(grp_lock);\n    }\n    unlock_timer_heap(ht);\n\n    return count;\n}\n\nPJ_DEF(int) pj_timer_heap_cancel( pj_timer_heap_t *ht,\n\t\t\t\t  pj_timer_entry *entry)\n{\n    return cancel_timer(ht, entry, 0, 0);\n}\n\nPJ_DEF(int) pj_timer_heap_cancel_if_active(pj_timer_heap_t *ht,\n                                           pj_timer_entry *entry,\n                                           int id_val)\n{\n    return cancel_timer(ht, entry, F_SET_ID | F_DONT_ASSERT, id_val);\n}\n\nPJ_DEF(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht, \n                                     pj_time_val *next_delay )\n{\n    pj_time_val now;\n    unsigned count;\n\n    PJ_ASSERT_RETURN(ht, 0);\n\n    lock_timer_heap(ht);\n    if (!ht->cur_size && next_delay) {\n\tnext_delay->sec = next_delay->msec = PJ_MAXINT32;\n        unlock_timer_heap(ht);\n\treturn 0;\n    }\n\n    count = 0;\n    pj_gettickcount(&now);\n\n    while ( ht->cur_size && \n\t    PJ_TIME_VAL_LTE(ht->heap[0]->_timer_value, now) &&\n            count < ht->max_entries_per_poll ) \n    {\n\tpj_timer_entry *node = remove_node(ht, 0);\n\tpj_grp_lock_t *grp_lock;\n\n\t++count;\n\n\tgrp_lock = node->_grp_lock;\n\tnode->_grp_lock = NULL;\n\n\tunlock_timer_heap(ht);\n\n\tPJ_RACE_ME(5);\n\n\tif (node->cb)\n\t    (*node->cb)(ht, node);\n\n\tif (grp_lock)\n\t    pj_grp_lock_dec_ref(grp_lock);\n\n\tlock_timer_heap(ht);\n    }\n    if (ht->cur_size && next_delay) {\n\t*next_delay = ht->heap[0]->_timer_value;\n\tPJ_TIME_VAL_SUB(*next_delay, now);\n\tif (next_delay->sec < 0 || next_delay->msec < 0)\n\t    next_delay->sec = next_delay->msec = 0;\n    } else if (next_delay) {\n\tnext_delay->sec = next_delay->msec = PJ_MAXINT32;\n    }\n    unlock_timer_heap(ht);\n\n    return count;\n}\n\nPJ_DEF(pj_size_t) pj_timer_heap_count( pj_timer_heap_t *ht )\n{\n    PJ_ASSERT_RETURN(ht, 0);\n\n    return ht->cur_size;\n}\n\nPJ_DEF(pj_status_t) pj_timer_heap_earliest_time( pj_timer_heap_t * ht,\n\t\t\t\t\t         pj_time_val *timeval)\n{\n    pj_assert(ht->cur_size != 0);\n    if (ht->cur_size == 0)\n        return PJ_ENOTFOUND;\n\n    lock_timer_heap(ht);\n    *timeval = ht->heap[0]->_timer_value;\n    unlock_timer_heap(ht);\n\n    return PJ_SUCCESS;\n}\n\n#if PJ_TIMER_DEBUG\nPJ_DEF(void) pj_timer_heap_dump(pj_timer_heap_t *ht)\n{\n    lock_timer_heap(ht);\n\n    PJ_LOG(3,(THIS_FILE, \"Dumping timer heap:\"));\n    PJ_LOG(3,(THIS_FILE, \"  Cur size: %d entries, max: %d\",\n\t\t\t (int)ht->cur_size, (int)ht->max_size));\n\n    if (ht->cur_size) {\n\tunsigned i;\n\tpj_time_val now;\n\n\tPJ_LOG(3,(THIS_FILE, \"  Entries: \"));\n\tPJ_LOG(3,(THIS_FILE, \"    _id\\tId\\tElapsed\\tSource\"));\n\tPJ_LOG(3,(THIS_FILE, \"    ----------------------------------\"));\n\n\tpj_gettickcount(&now);\n\n\tfor (i=0; i<(unsigned)ht->cur_size; ++i) {\n\t    pj_timer_entry *e = ht->heap[i];\n\t    pj_time_val delta;\n\n\t    if (PJ_TIME_VAL_LTE(e->_timer_value, now))\n\t\tdelta.sec = delta.msec = 0;\n\t    else {\n\t\tdelta = e->_timer_value;\n\t\tPJ_TIME_VAL_SUB(delta, now);\n\t    }\n\n\t    PJ_LOG(3,(THIS_FILE, \"    %d\\t%d\\t%d.%03d\\t%s:%d\",\n\t\t      e->_timer_id, e->id,\n\t\t      (int)delta.sec, (int)delta.msec,\n\t\t      e->src_file, e->src_line));\n\t}\n    }\n\n    unlock_timer_heap(ht);\n}\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/timer_symbian.cpp",
    "content": "/* $Id: timer_symbian.cpp 4374 2013-02-27 07:15:57Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/timer.h>\n#include <pj/pool.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/lock.h>\n\n#include \"os_symbian.h\"\n\n\n#define DEFAULT_MAX_TIMED_OUT_PER_POLL  (64)\n\n// Maximum number of miliseconds that RTimer.At() supports\n#define MAX_RTIMER_INTERVAL\t\t2147\n\n/* Absolute maximum number of timer entries */\n#ifndef PJ_SYMBIAN_TIMER_MAX_COUNT\n#  define PJ_SYMBIAN_TIMER_MAX_COUNT\t65535\n#endif\n\n/* Get the number of free slots in the timer heap */\n#define FREECNT(th)\t(th->max_size - th->cur_size)\n\n// Forward declaration\nclass CPjTimerEntry;\n\n/**\n * The implementation of timer heap.\n */\nstruct pj_timer_heap_t\n{\n    /** Maximum size of the heap. */\n    pj_size_t max_size;\n\n    /** Current size of the heap. */\n    pj_size_t cur_size;\n\n    /** Array of timer entries. A scheduled timer will occupy one slot, and\n     *  the slot number will be saved in entry->_timer_id\n     */\n    CPjTimerEntry **entries;\n    \n    /** Array of free slot indexes in the \"entries\" array */\n    int *free_slots;\n};\n\n/**\n * Active object for each timer entry.\n */\nclass CPjTimerEntry : public CActive \n{\npublic:\n    pj_timer_entry  *entry_;\n    \n    static CPjTimerEntry* NewL(\tpj_timer_heap_t *timer_heap,\n    \t\t\t\tpj_timer_entry *entry,\n    \t\t\t\tconst pj_time_val *delay);\n    \n    ~CPjTimerEntry();\n    \n    virtual void RunL();\n    virtual void DoCancel();\n\nprivate:\t\n    pj_timer_heap_t *timer_heap_;\n    RTimer\t     rtimer_;\n    pj_uint32_t\t     interval_left_;\n    \n    CPjTimerEntry(pj_timer_heap_t *timer_heap, pj_timer_entry *entry);\n    void ConstructL(const pj_time_val *delay);\n    void Schedule();\n};\n\n//////////////////////////////////////////////////////////////////////////////\n/*\n * Implementation.\n */\n\n/* Grow timer heap to the specified size */\nstatic pj_status_t realloc_timer_heap(pj_timer_heap_t *th, pj_size_t new_size)\n{\n    typedef CPjTimerEntry *entry_ptr;\n    CPjTimerEntry **entries = NULL;\n    int *free_slots = NULL;\n    unsigned i, j;\n \n    if (new_size > PJ_SYMBIAN_TIMER_MAX_COUNT) {\n\t/* Just some sanity limit */\n\tnew_size = PJ_SYMBIAN_TIMER_MAX_COUNT;\n\tif (new_size <= th->max_size) {\n\t    /* We've grown large enough */\n\t    pj_assert(!\"Too many timer heap entries\");\n\t    return PJ_ETOOMANY;\n\t}\n    }\n    \n    /* Allocate entries, move entries from the old array if there is one */\n    entries = new entry_ptr[new_size];\n    if (th->entries) {\n\tpj_memcpy(entries, th->entries, th->max_size * sizeof(th->entries[0]));\n    }\n    /* Initialize the remaining new area */\n    pj_bzero(&entries[th->max_size], \n\t    (new_size - th->max_size) * sizeof(th->entries[0]));\n    \n    /* Allocate free slots array */\n    free_slots = new int[new_size];\n    if (th->free_slots) {\n\tpj_memcpy(free_slots, th->free_slots, \n\t\t  FREECNT(th) * sizeof(th->free_slots[0]));\n    }\n    /* Initialize the remaining new area */\n    for (i=FREECNT(th), j=th->max_size; j<new_size; ++i, ++j) {\n\tfree_slots[i] = j;\n    }\n    for ( ; i<new_size; ++i) {\n\tfree_slots[i] = -1;\n    }\n    \n    /* Apply */\n    delete [] th->entries;\n    th->entries = entries;\n    th->max_size = new_size;\n    delete [] th->free_slots;\n    th->free_slots = free_slots;\n\n    return PJ_SUCCESS;\n}\n\n/* Allocate and register an entry to timer heap for newly scheduled entry */\nstatic pj_status_t add_entry(pj_timer_heap_t *th, CPjTimerEntry *entry)\n{\n    pj_status_t status;\n    int slot;\n    \n    /* Check that there's still capacity left in the timer heap */\n    if (FREECNT(th) < 1) {\n\t// Grow the timer heap twice the capacity\n\tstatus = realloc_timer_heap(th, th->max_size * 2);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n    \n    /* Allocate one free slot. Use LIFO */\n    slot = th->free_slots[FREECNT(th)-1];\n    PJ_ASSERT_RETURN((slot >= 0) && (slot < (int)th->max_size) && \n\t\t     (th->entries[slot]==NULL), PJ_EBUG);\n    \n    th->free_slots[FREECNT(th)-1] = -1;\n    th->entries[slot] = entry;\n    entry->entry_->_timer_id = slot;\n    ++th->cur_size;\n    \n    return PJ_SUCCESS;\n}\n\n/* Free a slot when an entry's timer has elapsed or cancel */\nstatic pj_status_t remove_entry(pj_timer_heap_t *th, CPjTimerEntry *entry)\n{\n    int slot = entry->entry_->_timer_id;\n    \n    PJ_ASSERT_RETURN(slot >= 0 && slot < (int)th->max_size, PJ_EBUG);\n    PJ_ASSERT_RETURN(FREECNT(th) < th->max_size, PJ_EBUG);\n    PJ_ASSERT_RETURN(th->entries[slot]==entry, PJ_EBUG);\n    PJ_ASSERT_RETURN(th->free_slots[FREECNT(th)]==-1, PJ_EBUG);\n    \n    th->entries[slot] = NULL;\n    th->free_slots[FREECNT(th)] = slot;\n    entry->entry_->_timer_id = -1;\n    --th->cur_size;\n    \n    return PJ_SUCCESS;\n}\n\n\nCPjTimerEntry::CPjTimerEntry(pj_timer_heap_t *timer_heap,\n\t\t\t     pj_timer_entry *entry)\n: CActive(PJ_SYMBIAN_TIMER_PRIORITY), entry_(entry), timer_heap_(timer_heap), \n  interval_left_(0)\n{\n}\n\nCPjTimerEntry::~CPjTimerEntry() \n{\n    Cancel();\n    rtimer_.Close();\n}\n\nvoid CPjTimerEntry::Schedule()\n{\n    pj_int32_t interval;\n    \n    if (interval_left_ > MAX_RTIMER_INTERVAL) {\n\tinterval = MAX_RTIMER_INTERVAL;\n    } else {\n\tinterval = interval_left_;\n    }\n    \n    interval_left_ -= interval;\n    rtimer_.After(iStatus, interval * 1000);\n    SetActive();\n}\n\nvoid CPjTimerEntry::ConstructL(const pj_time_val *delay) \n{\n    rtimer_.CreateLocal();\n    CActiveScheduler::Add(this);\n    \n    interval_left_ = PJ_TIME_VAL_MSEC(*delay);\n    Schedule();\n}\n\nCPjTimerEntry* CPjTimerEntry::NewL(pj_timer_heap_t *timer_heap,\n\t\t\t\t   pj_timer_entry *entry,\n\t\t\t\t   const pj_time_val *delay) \n{\n    CPjTimerEntry *self = new CPjTimerEntry(timer_heap, entry);\n    CleanupStack::PushL(self);\n    self->ConstructL(delay);\n    CleanupStack::Pop(self);\n\n    return self;\n}\n\nvoid CPjTimerEntry::RunL() \n{\n    if (interval_left_ > 0) {\n\tSchedule();\n\treturn;\n    }\n    \n    remove_entry(timer_heap_, this);\n    entry_->cb(timer_heap_, entry_);\n    \n    // Finger's crossed!\n    delete this;\n}\n\nvoid CPjTimerEntry::DoCancel() \n{\n    /* It's possible that _timer_id is -1, see schedule(). In this case,\n     * the entry has not been added to the timer heap, so don't remove\n     * it.\n     */\n    if (entry_ && entry_->_timer_id != -1)\n\tremove_entry(timer_heap_, this);\n    \n    rtimer_.Cancel();\n}\n\n\n//////////////////////////////////////////////////////////////////////////////\n\n\n/*\n * Calculate memory size required to create a timer heap.\n */\nPJ_DEF(pj_size_t) pj_timer_heap_mem_size(pj_size_t count)\n{\n    return /* size of the timer heap itself: */\n           sizeof(pj_timer_heap_t) + \n           /* size of each entry: */\n           (count+2) * (sizeof(void*)+sizeof(int)) +\n           /* lock, pool etc: */\n           132;\n}\n\n/*\n * Create a new timer heap.\n */\nPJ_DEF(pj_status_t) pj_timer_heap_create( pj_pool_t *pool,\n\t\t\t\t\t  pj_size_t size,\n                                          pj_timer_heap_t **p_heap)\n{\n    pj_timer_heap_t *ht;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && p_heap, PJ_EINVAL);\n\n    *p_heap = NULL;\n\n    /* Allocate timer heap data structure from the pool */\n    ht = PJ_POOL_ZALLOC_T(pool, pj_timer_heap_t);\n    if (!ht)\n        return PJ_ENOMEM;\n\n    /* Allocate slots */\n    status = realloc_timer_heap(ht, size);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    *p_heap = ht;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void) pj_timer_heap_destroy( pj_timer_heap_t *ht )\n{\n    /* Cancel and delete pending active objects */\n    if (ht->entries) {\n\tunsigned i;\n\tfor (i=0; i<ht->max_size; ++i) {\n\t    if (ht->entries[i]) {\n\t\tht->entries[i]->entry_ = NULL;\n\t\tht->entries[i]->Cancel();\n\t\tdelete ht->entries[i];\n\t\tht->entries[i] = NULL;\n\t    }\n\t}\n    }\n    \n    delete [] ht->entries;\n    delete [] ht->free_slots;\n    \n    ht->entries = NULL;\n    ht->free_slots = NULL;\n}\n\nPJ_DEF(void) pj_timer_heap_set_lock(  pj_timer_heap_t *ht,\n                                      pj_lock_t *lock,\n                                      pj_bool_t auto_del )\n{\n    PJ_UNUSED_ARG(ht);\n    if (auto_del)\n    \tpj_lock_destroy(lock);\n}\n\n\nPJ_DEF(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht,\n                                                          unsigned count )\n{\n    /* Not applicable */\n    PJ_UNUSED_ARG(count);\n    return ht->max_size;\n}\n\nPJ_DEF(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry,\n                                             int id,\n                                             void *user_data,\n                                             pj_timer_heap_callback *cb )\n{\n    pj_assert(entry && cb);\n\n    entry->_timer_id = -1;\n    entry->id = id;\n    entry->user_data = user_data;\n    entry->cb = cb;\n\n    return entry;\n}\n\nPJ_DEF(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht,\n\t\t\t\t\t    pj_timer_entry *entry, \n\t\t\t\t\t    const pj_time_val *delay)\n{\n    CPjTimerEntry *timerObj;\n    pj_status_t status;\n    \n    PJ_ASSERT_RETURN(ht && entry && delay, PJ_EINVAL);\n    PJ_ASSERT_RETURN(entry->cb != NULL, PJ_EINVAL);\n\n    /* Prevent same entry from being scheduled more than once */\n    PJ_ASSERT_RETURN(entry->_timer_id < 1, PJ_EINVALIDOP);\n\n    entry->_timer_id = -1;\n    \n    timerObj = CPjTimerEntry::NewL(ht, entry, delay);\n    status = add_entry(ht, timerObj);\n    if (status != PJ_SUCCESS) {\n\ttimerObj->Cancel();\n\tdelete timerObj;\n\treturn status;\n    }\n    \n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_timer_heap_schedule_w_grp_lock(pj_timer_heap_t *ht,\n                                                      pj_timer_entry *entry,\n                                                      const pj_time_val *delay,\n                                                      int id_val,\n                                                      pj_grp_lock_t *grp_lock)\n{\n    pj_status_t status;\n\t    \n    PJ_UNUSED_ARG(grp_lock);\n\n    status = pj_timer_heap_schedule(ht, entry, delay);\n    \n    if (status == PJ_SUCCESS)\n    \tentry->id = id_val;\n    \n    return status;\n}\n\nPJ_DEF(int) pj_timer_heap_cancel( pj_timer_heap_t *ht,\n\t\t\t\t  pj_timer_entry *entry)\n{\n    PJ_ASSERT_RETURN(ht && entry, PJ_EINVAL);\n    \n    if (entry->_timer_id >= 0 && entry->_timer_id < (int)ht->max_size) {\n    \tCPjTimerEntry *timerObj = ht->entries[entry->_timer_id];\n    \tif (timerObj) {\n    \t    timerObj->Cancel();\n    \t    delete timerObj;\n    \t    return 1;\n    \t} else {\n    \t    return 0;\n    \t}\n    } else {\n    \treturn 0;\n    }\n}\n\nPJ_DEF(int) pj_timer_heap_cancel_if_active(pj_timer_heap_t *ht,\n                                           pj_timer_entry *entry,\n                                           int id_val)\n{\n    int count = pj_timer_heap_cancel(ht, entry);\n    if (count == 1)\n    \tentry->id = id_val;\n    \n    return count;\n}\n\nPJ_DEF(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht, \n                                     pj_time_val *next_delay )\n{\n    /* Polling is not necessary on Symbian, since all async activities\n     * are registered to active scheduler.\n     */\n    PJ_UNUSED_ARG(ht);\n    if (next_delay) {\n    \tnext_delay->sec = 1;\n    \tnext_delay->msec = 0;\n    }\n    return 0;\n}\n\nPJ_DEF(pj_size_t) pj_timer_heap_count( pj_timer_heap_t *ht )\n{\n    PJ_ASSERT_RETURN(ht, 0);\n\n    return ht->cur_size;\n}\n\nPJ_DEF(pj_status_t) pj_timer_heap_earliest_time( pj_timer_heap_t * ht,\n\t\t\t\t\t         pj_time_val *timeval)\n{\n    /* We don't support this! */\n    PJ_UNUSED_ARG(ht);\n    \n    timeval->sec = 1;\n    timeval->msec = 0;\n    \n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/types.c",
    "content": "/* $Id: types.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/types.h>\n#include <pj/os.h>\n\nPJ_DEF(void) pj_time_val_normalize(pj_time_val *t)\n{\n    PJ_CHECK_STACK();\n\n    if (t->msec >= 1000) {\n\tt->sec += (t->msec / 1000);\n\tt->msec = (t->msec % 1000);\n    }\n    else if (t->msec <= -1000) {\n\tdo {\n\t    t->sec--;\n\t    t->msec += 1000;\n        } while (t->msec <= -1000);\n    }\n\n    if (t->sec >= 1 && t->msec < 0) {\n\tt->sec--;\n\tt->msec += 1000;\n\n    } else if (t->sec < 0 && t->msec > 0) {\n\tt->sec++;\n\tt->msec -= 1000;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/unicode_symbian.cpp",
    "content": "/* $Id: unicode_symbian.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/unicode.h>\n\n#include \"os_symbian.h\"\n\n\n/*\n * Convert ANSI strings to Unicode strings.\n */\nPJ_DEF(wchar_t*) pj_ansi_to_unicode( const char *str, pj_size_t len,\n\t\t\t\t     wchar_t *wbuf, pj_size_t wbuf_count)\n{\n    TPtrC8 aForeign((const TUint8*)str, (TInt)len);\n    TPtr16 aUnicode((TUint16*)wbuf, (TInt)(wbuf_count-1));\n    TInt left;\n\n    left = PjSymbianOS::Instance()->ConvertToUnicode(aUnicode, aForeign);\n\n    if (left != 0) {\n\t// Error, or there are unconvertable characters\n\t*wbuf = 0;\n    } else {\n\tif (len < wbuf_count)\n\t    wbuf[len] = 0;\n\telse\n\t    wbuf[len-1] = 0;\n    }\n\n    return wbuf;\n}\n\n\n/*\n * Convert Unicode string to ANSI string.\n */\nPJ_DEF(char*) pj_unicode_to_ansi( const wchar_t *wstr, pj_size_t len,\n\t\t\t\t  char *buf, pj_size_t buf_size)\n{\n    TPtrC16 aUnicode((const TUint16*)wstr, (TInt)len);\n    TPtr8 aForeign((TUint8*)buf, (TInt)(buf_size-1));\n    TInt left;\n\n    left = PjSymbianOS::Instance()->ConvertFromUnicode(aForeign, aUnicode);\n\n    if (left != 0) {\n\t// Error, or there are unconvertable characters\n\tbuf[0] = '\\0';\n    } else {\n\tif (len < buf_size)\n\t    buf[len] = '\\0';\n\telse\n\t    buf[len-1] = '\\0';\n    }\n\n    return buf;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib/src/pj/unicode_win32.c",
    "content": "/* $Id: unicode_win32.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pj/unicode.h>\n#include <pj/assert.h>\n#include <pj/string.h>\n#include <windows.h>\n\n\nPJ_DEF(wchar_t*) pj_ansi_to_unicode(const char *s, int len,\n\t\t\t\t    wchar_t *buf, int buf_count)\n{\n    PJ_ASSERT_RETURN(s && buf, NULL);\n\n    len = MultiByteToWideChar(CP_ACP, 0, s, len, \n\t\t\t      buf, buf_count);\n    if (buf_count) {\n\tif (len < buf_count)\n\t    buf[len] = 0;\n\telse\n\t    buf[len-1] = 0;\n    }\n\n    return buf;\n}\n\n\nPJ_DEF(char*) pj_unicode_to_ansi( const wchar_t *wstr, pj_ssize_t len,\n\t\t\t\t  char *buf, int buf_size)\n{\n    PJ_ASSERT_RETURN(wstr && buf, NULL);\n\n    len = WideCharToMultiByte(CP_ACP, 0, wstr, (int)len, buf, buf_size, \n\t\t\t      NULL, NULL);\n    if (buf_size) {\n\tif (len < buf_size)\n\t    buf[len] = '\\0';\n\telse\n\t    buf[len-1] = '\\0';\n    }\n\n    return buf;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/build/Makefile",
    "content": "\ninclude ../../build.mak\ninclude ../../version.mak\ninclude $(PJDIR)/build/common.mak\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\nPJLIB_LIB:=$(PJDIR)/pjlib/lib/libpj-$(TARGET_NAME)$(LIBEXT)\nexport PJLIB_UTIL_LIB:=../lib/libpjlib-util-$(TARGET_NAME)$(LIBEXT)\n\n###############################################################################\n# Gather all flags.\n#\nexport _CFLAGS \t:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t\t   $(CFLAGS) $(CC_INC)../include $(CC_INC)../../pjlib/include\nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\nexport _LDFLAGS := $(subst /,$(HOST_PSEP),$(PJLIB_UTIL_LIB)) \\\n\t\t   $(subst /,$(HOST_PSEP),$(PJLIB_LIB)) \\\n\t\t   $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(LDFLAGS) \n\n###############################################################################\n# Defines for building PJLIB-UTIL library\n#\nexport PJLIB_UTIL_SRCDIR = ../src/pjlib-util\nexport PJLIB_UTIL_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \\\n\t\tbase64.o crc32.o errno.o dns.o \\\n\t\tdns_dump.o dns_server.o getopt.o hmac_md5.o hmac_sha1.o \\\n\t\thttp_client.o md5.o pcap.o resolver.o scanner.o sha1.o \\\n\t\tsrv_resolver.o string.o stun_simple.o \\\n\t\tstun_simple_client.o xml.o\nexport PJLIB_UTIL_CFLAGS += $(_CFLAGS)\n\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT \n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\nTARGETS := pjlib-util\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && rm -rf docs/$(PJ_VERSION) && doxygen docs/doxygen.cfg\n\t@if [ -n \"$(WWWDIR)\" ] && ! [ -d \"$(WWWDIR)/docs/$(PJ_VERSION)/pjlib-util/docs/html\" ] ; then \\\n\t\techo \"Creating docs/$(PJ_VERSION)/pjlib-util/docs/html\" ; \\\n\t\tmkdir -p $(WWWDIR)/docs/$(PJ_VERSION)/pjlib-util/docs/html ; \\\n\tfi \n\t@if [ -n \"$(WWWDIR)\" ] && [ -d \"$(WWWDIR)/docs/$(PJ_VERSION)/pjlib-util/docs/html\" ] ; then \\\n\t\techo \"Copying docs/$(PJ_VERSION) to $(WWWDIR)/docs/$(PJ_VERSION)/pjlib-util/docs/html..\" ; \\\n\t\tcp -v -a ../docs/$(PJ_VERSION)/html/* $(WWWDIR)/docs/$(PJ_VERSION)/pjlib-util/docs/html/ ; \\\n\tfi\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend pjlib pjlib-test clean realclean distclean\n\npjlib-util:\n\t$(MAKE) -f $(RULES_MAK) APP=PJLIB_UTIL app=pjlib-util $(PJLIB_UTIL_LIB)\n\n.PHONY: ../lib/pjlib-util.ko\n../lib/pjlib-util.ko:\n\techo Making $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJLIB_UTIL app=pjlib-util $@\n\nclean:\n\t$(MAKE) -f $(RULES_MAK) APP=PJLIB_UTIL app=pjlib-util $@\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjlib-util-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjlib-util-test-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(MAKE) -f $(RULES_MAK) APP=PJLIB_UTIL app=pjlib-util $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=PJLIB_UTIL app=pjlib-util $@\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/docs/doxygen.cfg",
    "content": "# Doxyfile 1.3-rc3\r\n\r\n# This file describes the settings to be used by the documentation system\r\n# doxygen (www.doxygen.org) for a project\r\n#\r\n# All text after a hash (#) is considered a comment and will be ignored\r\n# The format is:\r\n#       TAG = value [value, ...]\r\n# For lists items can also be appended using:\r\n#       TAG += value [value, ...]\r\n# Values that contain spaces should be placed between quotes (\" \")\r\n\r\n#---------------------------------------------------------------------------\r\n# General configuration options\r\n#---------------------------------------------------------------------------\r\n\r\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded \r\n# by quotes) that should identify the project.\r\n\r\nPROJECT_NAME           =  \"PJLIB-UTIL Reference\"\r\n\r\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. \r\n# This could be handy for archiving the generated documentation or \r\n# if some version control system is used.\r\n\r\nPROJECT_NUMBER         = $(PJ_VERSION)\r\n\r\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) \r\n# base path where the generated documentation will be put. \r\n# If a relative path is entered, it will be relative to the location \r\n# where doxygen was started. If left blank the current directory will be used.\r\n\r\nOUTPUT_DIRECTORY       = docs/$(PJ_VERSION)\r\n\r\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all \r\n# documentation generated by doxygen is written. Doxygen will use this \r\n# information to generate all constant output in the proper language. \r\n# The default language is English, other supported languages are: \r\n# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, \r\n# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en \r\n# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, \r\n# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian.\r\n\r\nOUTPUT_LANGUAGE        = English\r\n\r\n# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in \r\n# documentation are documented, even if no documentation was available. \r\n# Private class members and static file members will be hidden unless \r\n# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES\r\n\r\nEXTRACT_ALL            = NO\r\n\r\n# If the EXTRACT_PRIVATE tag is set to YES all private members of a class \r\n# will be included in the documentation.\r\n\r\nEXTRACT_PRIVATE        = NO\r\n\r\n# If the EXTRACT_STATIC tag is set to YES all static members of a file \r\n# will be included in the documentation.\r\n\r\nEXTRACT_STATIC         = NO\r\n\r\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) \r\n# defined locally in source files will be included in the documentation. \r\n# If set to NO only classes defined in header files are included.\r\n\r\nEXTRACT_LOCAL_CLASSES  = YES\r\n\r\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all \r\n# undocumented members of documented classes, files or namespaces. \r\n# If set to NO (the default) these members will be included in the \r\n# various overviews, but no documentation section is generated. \r\n# This option has no effect if EXTRACT_ALL is enabled.\r\n\r\nHIDE_UNDOC_MEMBERS     = NO\r\n\r\n# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all \r\n# undocumented classes that are normally visible in the class hierarchy. \r\n# If set to NO (the default) these class will be included in the various \r\n# overviews. This option has no effect if EXTRACT_ALL is enabled.\r\n\r\nHIDE_UNDOC_CLASSES     = NO\r\n\r\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all \r\n# friend (class|struct|union) declarations. \r\n# If set to NO (the default) these declarations will be included in the \r\n# documentation.\r\n\r\nHIDE_FRIEND_COMPOUNDS  = NO\r\n\r\n# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any \r\n# documentation blocks found inside the body of a function. \r\n# If set to NO (the default) these blocks will be appended to the \r\n# function's detailed documentation block.\r\n\r\nHIDE_IN_BODY_DOCS      = NO\r\n\r\n# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will \r\n# include brief member descriptions after the members that are listed in \r\n# the file and class documentation (similar to JavaDoc). \r\n# Set to NO to disable this.\r\n\r\nBRIEF_MEMBER_DESC      = YES\r\n\r\n# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend \r\n# the brief description of a member or function before the detailed description. \r\n# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the \r\n# brief descriptions will be completely suppressed.\r\n\r\nREPEAT_BRIEF           = YES\r\n\r\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then \r\n# Doxygen will generate a detailed section even if there is only a brief \r\n# description.\r\n\r\nALWAYS_DETAILED_SEC    = NO\r\n\r\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited \r\n# members of a class in the documentation of that class as if those members were \r\n# ordinary class members. Constructors, destructors and assignment operators of \r\n# the base classes will not be shown.\r\n\r\nINLINE_INHERITED_MEMB  = NO\r\n\r\n# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full \r\n# path before files name in the file list and in the header files. If set \r\n# to NO the shortest path that makes the file name unique will be used.\r\n\r\nFULL_PATH_NAMES        = NO\r\n\r\n# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag \r\n# can be used to strip a user defined part of the path. Stripping is \r\n# only done if one of the specified strings matches the left-hand part of \r\n# the path. It is allowed to use relative paths in the argument list.\r\n\r\nSTRIP_FROM_PATH        = \"c:\\project\\pjproject\"\r\n\r\n# The INTERNAL_DOCS tag determines if documentation \r\n# that is typed after a \\internal command is included. If the tag is set \r\n# to NO (the default) then the documentation will be excluded. \r\n# Set it to YES to include the internal documentation.\r\n\r\nINTERNAL_DOCS          = NO\r\n\r\n# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate \r\n# file names in lower case letters. If set to YES upper case letters are also \r\n# allowed. This is useful if you have classes or files whose names only differ \r\n# in case and if your file system supports case sensitive file names. Windows \r\n# users are adviced to set this option to NO.\r\n\r\nCASE_SENSE_NAMES       = YES\r\n\r\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter \r\n# (but less readable) file names. This can be useful is your file systems \r\n# doesn't support long names like on DOS, Mac, or CD-ROM.\r\n\r\nSHORT_NAMES            = NO\r\n\r\n# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen \r\n# will show members with their full class and namespace scopes in the \r\n# documentation. If set to YES the scope will be hidden.\r\n\r\nHIDE_SCOPE_NAMES       = NO\r\n\r\n# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen \r\n# will generate a verbatim copy of the header file for each class for \r\n# which an include is specified. Set to NO to disable this.\r\n\r\nVERBATIM_HEADERS       = YES\r\n\r\n# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen \r\n# will put list of the files that are included by a file in the documentation \r\n# of that file.\r\n\r\nSHOW_INCLUDE_FILES     = NO\r\n\r\n# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen \r\n# will interpret the first line (until the first dot) of a JavaDoc-style \r\n# comment as the brief description. If set to NO, the JavaDoc \r\n# comments  will behave just like the Qt-style comments (thus requiring an \r\n# explict @brief command for a brief description.\r\n\r\nJAVADOC_AUTOBRIEF      = NO\r\n\r\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen \r\n# treat a multi-line C++ special comment block (i.e. a block of //! or /// \r\n# comments) as a brief description. This used to be the default behaviour. \r\n# The new default is to treat a multi-line C++ comment block as a detailed \r\n# description. Set this tag to YES if you prefer the old behaviour instead.\r\n\r\nMULTILINE_CPP_IS_BRIEF = NO\r\n\r\n# If the DETAILS_AT_TOP tag is set to YES then Doxygen \r\n# will output the detailed description near the top, like JavaDoc.\r\n# If set to NO, the detailed description appears after the member \r\n# documentation.\r\n\r\nDETAILS_AT_TOP         = YES\r\n\r\n# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented \r\n# member inherits the documentation from any documented member that it \r\n# reimplements.\r\n\r\nINHERIT_DOCS           = YES\r\n\r\n# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] \r\n# is inserted in the documentation for inline members.\r\n\r\nINLINE_INFO            = YES\r\n\r\n# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen \r\n# will sort the (detailed) documentation of file and class members \r\n# alphabetically by member name. If set to NO the members will appear in \r\n# declaration order.\r\n\r\nSORT_MEMBER_DOCS       = YES\r\n\r\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC \r\n# tag is set to YES, then doxygen will reuse the documentation of the first \r\n# member in the group (if any) for the other members of the group. By default \r\n# all members of a group must be documented explicitly.\r\n\r\nDISTRIBUTE_GROUP_DOC   = NO\r\n\r\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. \r\n# Doxygen uses this value to replace tabs by spaces in code fragments.\r\n\r\nTAB_SIZE               = 8\r\n\r\n# The GENERATE_TODOLIST tag can be used to enable (YES) or \r\n# disable (NO) the todo list. This list is created by putting \\todo \r\n# commands in the documentation.\r\n\r\nGENERATE_TODOLIST      = YES\r\n\r\n# The GENERATE_TESTLIST tag can be used to enable (YES) or \r\n# disable (NO) the test list. This list is created by putting \\test \r\n# commands in the documentation.\r\n\r\nGENERATE_TESTLIST      = YES\r\n\r\n# The GENERATE_BUGLIST tag can be used to enable (YES) or \r\n# disable (NO) the bug list. This list is created by putting \\bug \r\n# commands in the documentation.\r\n\r\nGENERATE_BUGLIST       = YES\r\n\r\n# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or \r\n# disable (NO) the deprecated list. This list is created by putting \r\n# \\deprecated commands in the documentation.\r\n\r\nGENERATE_DEPRECATEDLIST= YES\r\n\r\n# This tag can be used to specify a number of aliases that acts \r\n# as commands in the documentation. An alias has the form \"name=value\". \r\n# For example adding \"sideeffect=\\par Side Effects:\\n\" will allow you to \r\n# put the command \\sideeffect (or @sideeffect) in the documentation, which \r\n# will result in a user defined paragraph with heading \"Side Effects:\". \r\n# You can put \\n's in the value part of an alias to insert newlines.\r\n\r\nALIASES                = \r\n\r\n# The ENABLED_SECTIONS tag can be used to enable conditional \r\n# documentation sections, marked by \\if sectionname ... \\endif.\r\n\r\nENABLED_SECTIONS       = \r\n\r\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines \r\n# the initial value of a variable or define consist of for it to appear in \r\n# the documentation. If the initializer consists of more lines than specified \r\n# here it will be hidden. Use a value of 0 to hide initializers completely. \r\n# The appearance of the initializer of individual variables and defines in the \r\n# documentation can be controlled using \\showinitializer or \\hideinitializer \r\n# command in the documentation regardless of this setting.\r\n\r\nMAX_INITIALIZER_LINES  = 30\r\n\r\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources \r\n# only. Doxygen will then generate output that is more tailored for C. \r\n# For instance some of the names that are used will be different. The list \r\n# of all members will be omitted, etc.\r\n\r\nOPTIMIZE_OUTPUT_FOR_C  = YES\r\n\r\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources \r\n# only. Doxygen will then generate output that is more tailored for Java. \r\n# For instance namespaces will be presented as packages, qualified scopes \r\n# will look different, etc.\r\n\r\nOPTIMIZE_OUTPUT_JAVA   = NO\r\n\r\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated \r\n# at the bottom of the documentation of classes and structs. If set to YES the \r\n# list will mention the files that were used to generate the documentation.\r\n\r\nSHOW_USED_FILES        = YES\r\nTYPEDEF_HIDES_STRUCT\t= YES\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to warning and progress messages\r\n#---------------------------------------------------------------------------\r\n\r\n# The QUIET tag can be used to turn on/off the messages that are generated \r\n# by doxygen. Possible values are YES and NO. If left blank NO is used.\r\n\r\nQUIET                  = NO\r\n\r\n# The WARNINGS tag can be used to turn on/off the warning messages that are \r\n# generated by doxygen. Possible values are YES and NO. If left blank \r\n# NO is used.\r\n\r\nWARNINGS               = YES\r\n\r\n# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings \r\n# for undocumented members. If EXTRACT_ALL is set to YES then this flag will \r\n# automatically be disabled.\r\n\r\nWARN_IF_UNDOCUMENTED   = YES\r\n\r\n# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for \r\n# potential errors in the documentation, such as not documenting some \r\n# parameters in a documented function, or documenting parameters that \r\n# don't exist or using markup commands wrongly.\r\n\r\nWARN_IF_DOC_ERROR      = YES\r\n\r\n# The WARN_FORMAT tag determines the format of the warning messages that \r\n# doxygen can produce. The string should contain the $file, $line, and $text \r\n# tags, which will be replaced by the file and line number from which the \r\n# warning originated and the warning text.\r\n\r\nWARN_FORMAT            = \"$file:$line: $text\"\r\n\r\n# The WARN_LOGFILE tag can be used to specify a file to which warning \r\n# and error messages should be written. If left blank the output is written \r\n# to stderr.\r\n\r\nWARN_LOGFILE           = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the input files\r\n#---------------------------------------------------------------------------\r\n\r\n# The INPUT tag can be used to specify the files and/or directories that contain \r\n# documented source files. You may enter file names like \"myfile.cpp\" or \r\n# directories like \"/usr/src/myproject\". Separate the files or directories \r\n# with spaces.\r\n\r\nINPUT                  =  include/pjlib-util\r\n\r\n# If the value of the INPUT tag contains directories, you can use the \r\n# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \r\n# and *.h) to filter out the source-files in the directories. If left \r\n# blank the following patterns are tested: \r\n# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp \r\n# *.h++ *.idl *.odl\r\n\r\nFILE_PATTERNS          = *.h *.c\r\n\r\n# The RECURSIVE tag can be used to turn specify whether or not subdirectories \r\n# should be searched for input files as well. Possible values are YES and NO. \r\n# If left blank NO is used.\r\n\r\nRECURSIVE              = YES\r\n\r\n# The EXCLUDE tag can be used to specify files and/or directories that should \r\n# excluded from the INPUT source files. This way you can easily exclude a \r\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\r\n\r\nEXCLUDE                = \r\n\r\n# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories \r\n# that are symbolic links (a Unix filesystem feature) are excluded from the input.\r\n\r\nEXCLUDE_SYMLINKS       = NO\r\n\r\n# If the value of the INPUT tag contains directories, you can use the \r\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude \r\n# certain files from those directories.\r\n\r\nEXCLUDE_PATTERNS       = \"*_i.h\" \"*/compat/*\"\r\n\r\n# The EXAMPLE_PATH tag can be used to specify one or more files or \r\n# directories that contain example code fragments that are included (see \r\n# the \\include command).\r\n\r\nEXAMPLE_PATH           = .\r\n\r\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the \r\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \r\n# and *.h) to filter out the source-files in the directories. If left \r\n# blank all files are included.\r\n\r\nEXAMPLE_PATTERNS       = \r\n\r\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be \r\n# searched for input files to be used with the \\include or \\dontinclude \r\n# commands irrespective of the value of the RECURSIVE tag. \r\n# Possible values are YES and NO. If left blank NO is used.\r\n\r\nEXAMPLE_RECURSIVE      = YES\r\n\r\n# The IMAGE_PATH tag can be used to specify one or more files or \r\n# directories that contain image that are included in the documentation (see \r\n# the \\image command).\r\n\r\nIMAGE_PATH             = \r\n\r\n# The INPUT_FILTER tag can be used to specify a program that doxygen should \r\n# invoke to filter for each input file. Doxygen will invoke the filter program \r\n# by executing (via popen()) the command <filter> <input-file>, where <filter> \r\n# is the value of the INPUT_FILTER tag, and <input-file> is the name of an \r\n# input file. Doxygen will then use the output that the filter program writes \r\n# to standard output.\r\n\r\nINPUT_FILTER           = \r\n\r\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using \r\n# INPUT_FILTER) will be used to filter the input files when producing source \r\n# files to browse (i.e. when SOURCE_BROWSER is set to YES).\r\n\r\nFILTER_SOURCE_FILES    = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to source browsing\r\n#---------------------------------------------------------------------------\r\n\r\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will \r\n# be generated. Documented entities will be cross-referenced with these sources.\r\n\r\nSOURCE_BROWSER         = NO\r\n\r\n# Setting the INLINE_SOURCES tag to YES will include the body \r\n# of functions and classes directly in the documentation.\r\n\r\nINLINE_SOURCES         = NO\r\n\r\n# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct \r\n# doxygen to hide any special comment blocks from generated source code \r\n# fragments. Normal C and C++ comments will always remain visible.\r\n\r\nSTRIP_CODE_COMMENTS    = YES\r\n\r\n# If the REFERENCED_BY_RELATION tag is set to YES (the default) \r\n# then for each documented function all documented \r\n# functions referencing it will be listed.\r\n\r\nREFERENCED_BY_RELATION = YES\r\n\r\n# If the REFERENCES_RELATION tag is set to YES (the default) \r\n# then for each documented function all documented entities \r\n# called/used by that function will be listed.\r\n\r\nREFERENCES_RELATION    = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the alphabetical class index\r\n#---------------------------------------------------------------------------\r\n\r\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index \r\n# of all compounds will be generated. Enable this if the project \r\n# contains a lot of classes, structs, unions or interfaces.\r\n\r\nALPHABETICAL_INDEX     = NO\r\n\r\n# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then \r\n# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns \r\n# in which this list will be split (can be a number in the range [1..20])\r\n\r\nCOLS_IN_ALPHA_INDEX    = 5\r\n\r\n# In case all classes in a project start with a common prefix, all \r\n# classes will be put under the same header in the alphabetical index. \r\n# The IGNORE_PREFIX tag can be used to specify one or more prefixes that \r\n# should be ignored while generating the index headers.\r\n\r\nIGNORE_PREFIX          = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the HTML output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_HTML tag is set to YES (the default) Doxygen will \r\n# generate HTML output.\r\n\r\nGENERATE_HTML          = YES\r\n\r\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `html' will be used as the default path.\r\n\r\nHTML_OUTPUT            = html\r\n\r\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for \r\n# each generated HTML page (for example: .htm,.php,.asp). If it is left blank \r\n# doxygen will generate files with .html extension.\r\n\r\nHTML_FILE_EXTENSION    = .htm\r\n\r\n# The HTML_HEADER tag can be used to specify a personal HTML header for \r\n# each generated HTML page. If it is left blank doxygen will generate a \r\n# standard header.\r\n\r\nHTML_HEADER            = docs/header.html\r\n\r\n# The HTML_FOOTER tag can be used to specify a personal HTML footer for \r\n# each generated HTML page. If it is left blank doxygen will generate a \r\n# standard footer.\r\n\r\nHTML_FOOTER            = docs/footer.html\r\n\r\n# The HTML_STYLESHEET tag can be used to specify a user defined cascading \r\n# style sheet that is used by each HTML page. It can be used to \r\n# fine-tune the look of the HTML output. If the tag is left blank doxygen \r\n# will generate a default style sheet\r\n\r\nHTML_STYLESHEET        = docs/doxygen.css\r\n\r\n# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, \r\n# files or namespaces will be aligned in HTML using tables. If set to \r\n# NO a bullet list will be used.\r\n\r\nHTML_ALIGN_MEMBERS     = YES\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, additional index files \r\n# will be generated that can be used as input for tools like the \r\n# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) \r\n# of the generated HTML documentation.\r\n\r\nGENERATE_HTMLHELP      = NO\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can \r\n# be used to specify the file name of the resulting .chm file. You \r\n# can add a path in front of the file if the result should not be \r\n# written to the html output dir.\r\n\r\nCHM_FILE               = \r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can \r\n# be used to specify the location (absolute path including file name) of \r\n# the HTML help compiler (hhc.exe). If non empty doxygen will try to run \r\n# the html help compiler on the generated index.hhp.\r\n\r\nHHC_LOCATION           = \r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag \r\n# controls if a separate .chi index file is generated (YES) or that \r\n# it should be included in the master .chm file (NO).\r\n\r\nGENERATE_CHI           = NO\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag \r\n# controls whether a binary table of contents is generated (YES) or a \r\n# normal table of contents (NO) in the .chm file.\r\n\r\nBINARY_TOC             = NO\r\n\r\n# The TOC_EXPAND flag can be set to YES to add extra items for group members \r\n# to the contents of the Html help documentation and to the tree view.\r\n\r\nTOC_EXPAND             = NO\r\n\r\n# The DISABLE_INDEX tag can be used to turn on/off the condensed index at \r\n# top of each HTML page. The value NO (the default) enables the index and \r\n# the value YES disables it.\r\n\r\nDISABLE_INDEX          = NO\r\n\r\n# This tag can be used to set the number of enum values (range [1..20]) \r\n# that doxygen will group on one line in the generated HTML documentation.\r\n\r\nENUM_VALUES_PER_LINE   = 4\r\n\r\n# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be\r\n# generated containing a tree-like index structure (just like the one that \r\n# is generated for HTML Help). For this to work a browser that supports \r\n# JavaScript, DHTML, CSS and frames is required (for instance Mozilla, \r\n# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are \r\n# probably better off using the HTML help feature.\r\n\r\nGENERATE_TREEVIEW      = NO\r\n\r\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be \r\n# used to set the initial width (in pixels) of the frame in which the tree \r\n# is shown.\r\n\r\nTREEVIEW_WIDTH         = 250\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the LaTeX output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will \r\n# generate Latex output.\r\n\r\nGENERATE_LATEX         = YES\r\n\r\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `latex' will be used as the default path.\r\n\r\nLATEX_OUTPUT           = latex\r\n\r\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be \r\n# invoked. If left blank `latex' will be used as the default command name.\r\n\r\nLATEX_CMD_NAME         = latex\r\n\r\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to \r\n# generate index for LaTeX. If left blank `makeindex' will be used as the \r\n# default command name.\r\n\r\nMAKEINDEX_CMD_NAME     = makeindex\r\n\r\n# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact \r\n# LaTeX documents. This may be useful for small projects and may help to \r\n# save some trees in general.\r\n\r\nCOMPACT_LATEX          = NO\r\n\r\n# The PAPER_TYPE tag can be used to set the paper type that is used \r\n# by the printer. Possible values are: a4, a4wide, letter, legal and \r\n# executive. If left blank a4wide will be used.\r\n\r\nPAPER_TYPE             = a4wide\r\n\r\n# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX \r\n# packages that should be included in the LaTeX output.\r\n\r\nEXTRA_PACKAGES         = \r\n\r\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for \r\n# the generated latex document. The header should contain everything until \r\n# the first chapter. If it is left blank doxygen will generate a \r\n# standard header. Notice: only use this tag if you know what you are doing!\r\n\r\nLATEX_HEADER           = \r\n\r\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated \r\n# is prepared for conversion to pdf (using ps2pdf). The pdf file will \r\n# contain links (just like the HTML output) instead of page references \r\n# This makes the output suitable for online browsing using a pdf viewer.\r\n\r\nPDF_HYPERLINKS         = YES\r\n\r\n# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of \r\n# plain latex in the generated Makefile. Set this option to YES to get a \r\n# higher quality PDF documentation.\r\n\r\nUSE_PDFLATEX           = YES\r\n\r\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\\\batchmode. \r\n# command to the generated LaTeX files. This will instruct LaTeX to keep \r\n# running if errors occur, instead of asking the user for help. \r\n# This option is also used when generating formulas in HTML.\r\n\r\nLATEX_BATCHMODE        = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the RTF output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output \r\n# The RTF output is optimised for Word 97 and may not look very pretty with \r\n# other RTF readers or editors.\r\n\r\nGENERATE_RTF           = NO\r\n\r\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `rtf' will be used as the default path.\r\n\r\nRTF_OUTPUT             = rtf\r\n\r\n# If the COMPACT_RTF tag is set to YES Doxygen generates more compact \r\n# RTF documents. This may be useful for small projects and may help to \r\n# save some trees in general.\r\n\r\nCOMPACT_RTF            = NO\r\n\r\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated \r\n# will contain hyperlink fields. The RTF file will \r\n# contain links (just like the HTML output) instead of page references. \r\n# This makes the output suitable for online browsing using WORD or other \r\n# programs which support those fields. \r\n# Note: wordpad (write) and others do not support links.\r\n\r\nRTF_HYPERLINKS         = NO\r\n\r\n# Load stylesheet definitions from file. Syntax is similar to doxygen's \r\n# config file, i.e. a series of assigments. You only have to provide \r\n# replacements, missing definitions are set to their default value.\r\n\r\nRTF_STYLESHEET_FILE    = \r\n\r\n# Set optional variables used in the generation of an rtf document. \r\n# Syntax is similar to doxygen's config file.\r\n\r\nRTF_EXTENSIONS_FILE    = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the man page output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_MAN tag is set to YES (the default) Doxygen will \r\n# generate man pages\r\n\r\nGENERATE_MAN           = NO\r\n\r\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `man' will be used as the default path.\r\n\r\nMAN_OUTPUT             = man\r\n\r\n# The MAN_EXTENSION tag determines the extension that is added to \r\n# the generated man pages (default is the subroutine's section .3)\r\n\r\nMAN_EXTENSION          = .3\r\n\r\n# If the MAN_LINKS tag is set to YES and Doxygen generates man output, \r\n# then it will generate one additional man file for each entity \r\n# documented in the real man page(s). These additional files \r\n# only source the real man page, but without them the man command \r\n# would be unable to find the correct page. The default is NO.\r\n\r\nMAN_LINKS              = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the XML output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_XML tag is set to YES Doxygen will \r\n# generate an XML file that captures the structure of \r\n# the code including all documentation. Note that this \r\n# feature is still experimental and incomplete at the \r\n# moment.\r\n\r\nGENERATE_XML           = NO\r\n\r\n# The XML_SCHEMA tag can be used to specify an XML schema, \r\n# which can be used by a validating XML parser to check the \r\n# syntax of the XML files.\r\n\r\nXML_SCHEMA             = \r\n\r\n# The XML_DTD tag can be used to specify an XML DTD, \r\n# which can be used by a validating XML parser to check the \r\n# syntax of the XML files.\r\n\r\nXML_DTD                = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options for the AutoGen Definitions output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will \r\n# generate an AutoGen Definitions (see autogen.sf.net) file \r\n# that captures the structure of the code including all \r\n# documentation. Note that this feature is still experimental \r\n# and incomplete at the moment.\r\n\r\nGENERATE_AUTOGEN_DEF   = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the Perl module output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_PERLMOD tag is set to YES Doxygen will \r\n# generate a Perl module file that captures the structure of \r\n# the code including all documentation. Note that this \r\n# feature is still experimental and incomplete at the \r\n# moment.\r\n\r\nGENERATE_PERLMOD       = NO\r\n\r\n# If the PERLMOD_LATEX tag is set to YES Doxygen will generate \r\n# the necessary Makefile rules, Perl scripts and LaTeX code to be able \r\n# to generate PDF and DVI output from the Perl module output.\r\n\r\nPERLMOD_LATEX          = NO\r\n\r\n# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be \r\n# nicely formatted so it can be parsed by a human reader.  This is useful \r\n# if you want to understand what is going on.  On the other hand, if this \r\n# tag is set to NO the size of the Perl module output will be much smaller \r\n# and Perl will parse it just the same.\r\n\r\nPERLMOD_PRETTY         = YES\r\n\r\n# The names of the make variables in the generated doxyrules.make file \r\n# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. \r\n# This is useful so different doxyrules.make files included by the same \r\n# Makefile don't overwrite each other's variables.\r\n\r\nPERLMOD_MAKEVAR_PREFIX = \r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration options related to the preprocessor   \r\n#---------------------------------------------------------------------------\r\n\r\n# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will \r\n# evaluate all C-preprocessor directives found in the sources and include \r\n# files.\r\n\r\nENABLE_PREPROCESSING   = YES\r\n\r\n# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro \r\n# names in the source code. If set to NO (the default) only conditional \r\n# compilation will be performed. Macro expansion can be done in a controlled \r\n# way by setting EXPAND_ONLY_PREDEF to YES.\r\n\r\nMACRO_EXPANSION        = YES\r\n\r\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES \r\n# then the macro expansion is limited to the macros specified with the \r\n# PREDEFINED and EXPAND_AS_PREDEFINED tags.\r\n\r\nEXPAND_ONLY_PREDEF     = NO\r\n\r\n# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files \r\n# in the INCLUDE_PATH (see below) will be search if a #include is found.\r\n\r\nSEARCH_INCLUDES        = YES\r\n\r\n# The INCLUDE_PATH tag can be used to specify one or more directories that \r\n# contain include files that are not input files but should be processed by \r\n# the preprocessor.\r\n\r\nINCLUDE_PATH           = \r\n\r\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard \r\n# patterns (like *.h and *.hpp) to filter out the header-files in the \r\n# directories. If left blank, the patterns specified with FILE_PATTERNS will \r\n# be used.\r\n\r\nINCLUDE_FILE_PATTERNS  = \r\n\r\n# The PREDEFINED tag can be used to specify one or more macro names that \r\n# are defined before the preprocessor is started (similar to the -D option of \r\n# gcc). The argument of the tag is a list of macros of the form: name \r\n# or name=definition (no spaces). If the definition and the = are \r\n# omitted =1 is assumed.\r\n\r\nPREDEFINED             = PJ_DECL(x)=x PJ_DEF(x)=x PJ_IDECL(x)=x \\\r\n\t\t\t PJ_IDEF(x)=x PJ_INLINE(x)=x \\\r\n\t\t\t PJ_DECL_DATA(x)=x \\\r\n\t\t\t PJ_DECL_NO_RETURN(x)=x \\\r\n\t\t\t PJ_NO_RETURN=x \\\r\n\t\t\t PJ_HAS_HIGH_RES_TIMER=1 \\\r\n\t\t\t PJ_LOG_MAX_LEVEL=4 \\\r\n\t\t\t PJ_HAS_SEMAPHORE=1 \\\r\n\t\t\t PJ_HAS_EVENT_OBJ=1 \\\r\n\t\t\t PJ_HAS_TCP=1\r\n\r\n\r\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then \r\n# this tag can be used to specify a list of macro names that should be expanded. \r\n# The macro definition that is found in the sources will be used. \r\n# Use the PREDEFINED tag if you want to use a different macro definition.\r\n\r\nEXPAND_AS_DEFINED      = \r\n\r\n# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then \r\n# doxygen's preprocessor will remove all function-like macros that are alone \r\n# on a line, have an all uppercase name, and do not end with a semicolon. Such \r\n# function macros are typically used for boiler-plate code, and will confuse the \r\n# parser if not removed.\r\n\r\nSKIP_FUNCTION_MACROS   = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration::addtions related to external references   \r\n#---------------------------------------------------------------------------\r\n\r\n# The TAGFILES tag can be used to specify one or more tagfiles.\r\n\r\nTAGFILES               = ../pjlib/docs/pjlib.tag=../../../pjlib/docs/html ../pjnath/docs/pjnath.tag=../../../pjnath/docs/html ../pjsip/docs/pjsip.tag=../../../pjsip/docs/html ../pjmedia/docs/pjmedia.tag=../../../pjmedia/docs/html\r\n\r\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create \r\n# a tag file that is based on the input files it reads.\r\n\r\nGENERATE_TAGFILE       = docs/pjlib-util.tag\r\n\r\n# If the ALLEXTERNALS tag is set to YES all external classes will be listed \r\n# in the class index. If set to NO only the inherited external classes \r\n# will be listed.\r\n\r\nALLEXTERNALS           = NO\r\n\r\n# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed \r\n# in the modules index. If set to NO, only the current project's groups will \r\n# be listed.\r\n\r\nEXTERNAL_GROUPS        = NO\r\n\r\n# The PERL_PATH should be the absolute path and name of the perl script \r\n# interpreter (i.e. the result of `which perl').\r\n\r\n#PERL_PATH              = /usr/bin/perl\r\nPERL_PATH              = /c/Perl/bin/perl\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration options related to the dot tool   \r\n#---------------------------------------------------------------------------\r\n\r\n# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will \r\n# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or \r\n# super classes. Setting the tag to NO turns the diagrams off. Note that this \r\n# option is superceded by the HAVE_DOT option below. This is only a fallback. It is \r\n# recommended to install and use dot, since it yield more powerful graphs.\r\n\r\nCLASS_DIAGRAMS         = NO\r\n\r\n# If set to YES, the inheritance and collaboration graphs will hide \r\n# inheritance and usage relations if the target is undocumented \r\n# or is not a class.\r\n\r\nHIDE_UNDOC_RELATIONS   = YES\r\n\r\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is \r\n# available from the path. This tool is part of Graphviz, a graph visualization \r\n# toolkit from AT&T and Lucent Bell Labs. The other options in this section \r\n# have no effect if this option is set to NO (the default)\r\n\r\nHAVE_DOT               = NO\r\n\r\n# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen \r\n# will generate a graph for each documented class showing the direct and \r\n# indirect inheritance relations. Setting this tag to YES will force the \r\n# the CLASS_DIAGRAMS tag to NO.\r\n\r\nCLASS_GRAPH            = YES\r\n\r\n# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen \r\n# will generate a graph for each documented class showing the direct and \r\n# indirect implementation dependencies (inheritance, containment, and \r\n# class references variables) of the class with other documented classes.\r\n\r\nCOLLABORATION_GRAPH    = YES\r\n\r\n# If set to YES, the inheritance and collaboration graphs will show the \r\n# relations between templates and their instances.\r\n\r\nTEMPLATE_RELATIONS     = YES\r\n\r\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT \r\n# tags are set to YES then doxygen will generate a graph for each documented \r\n# file showing the direct and indirect include dependencies of the file with \r\n# other documented files.\r\n\r\nINCLUDE_GRAPH          = YES\r\n\r\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and \r\n# HAVE_DOT tags are set to YES then doxygen will generate a graph for each \r\n# documented header file showing the documented files that directly or \r\n# indirectly include this file.\r\n\r\nINCLUDED_BY_GRAPH      = YES\r\n\r\n# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen \r\n# will graphical hierarchy of all classes instead of a textual one.\r\n\r\nGRAPHICAL_HIERARCHY    = YES\r\n\r\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images \r\n# generated by dot. Possible values are png, jpg, or gif\r\n# If left blank png will be used.\r\n\r\nDOT_IMAGE_FORMAT       = png\r\n\r\n# The tag DOT_PATH can be used to specify the path where the dot tool can be \r\n# found. If left blank, it is assumed the dot tool can be found on the path.\r\n\r\nDOT_PATH               = \r\n\r\n# The DOTFILE_DIRS tag can be used to specify one or more directories that \r\n# contain dot files that are included in the documentation (see the \r\n# \\dotfile command).\r\n\r\nDOTFILE_DIRS           = \r\n\r\n# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width \r\n# (in pixels) of the graphs generated by dot. If a graph becomes larger than \r\n# this value, doxygen will try to truncate the graph, so that it fits within \r\n# the specified constraint. Beware that most browsers cannot cope with very \r\n# large images.\r\n\r\nMAX_DOT_GRAPH_WIDTH    = 1024\r\n\r\n# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height \r\n# (in pixels) of the graphs generated by dot. If a graph becomes larger than \r\n# this value, doxygen will try to truncate the graph, so that it fits within \r\n# the specified constraint. Beware that most browsers cannot cope with very \r\n# large images.\r\n\r\nMAX_DOT_GRAPH_HEIGHT   = 1024\r\n\r\n# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will \r\n# generate a legend page explaining the meaning of the various boxes and \r\n# arrows in the dot generated graphs.\r\n\r\nGENERATE_LEGEND        = YES\r\n\r\n# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will \r\n# remove the intermedate dot files that are used to generate \r\n# the various graphs.\r\n\r\nDOT_CLEANUP            = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration::addtions related to the search engine   \r\n#---------------------------------------------------------------------------\r\n\r\n# The SEARCHENGINE tag specifies whether or not a search engine should be \r\n# used. If set to NO the values of all tags below this one will be ignored.\r\n\r\nSEARCHENGINE           = NO\r\n\r\n# The CGI_NAME tag should be the name of the CGI script that \r\n# starts the search engine (doxysearch) with the correct parameters. \r\n# A script with this name will be generated by doxygen.\r\n\r\n#CGI_NAME               = search.cgi\r\n\r\n# The CGI_URL tag should be the absolute URL to the directory where the \r\n# cgi binaries are located. See the documentation of your http daemon for \r\n# details.\r\n\r\n#CGI_URL                = \r\n\r\n# The DOC_URL tag should be the absolute URL to the directory where the \r\n# documentation is located. If left blank the absolute path to the \r\n# documentation, with file:// prepended to it, will be used.\r\n\r\n#DOC_URL                = \r\n\r\n# The DOC_ABSPATH tag should be the absolute path to the directory where the \r\n# documentation is located. If left blank the directory on the local machine \r\n# will be used.\r\n\r\n#DOC_ABSPATH            = \r\n\r\n# The BIN_ABSPATH tag must point to the directory where the doxysearch binary \r\n# is installed.\r\n\r\n#BIN_ABSPATH            = /usr/local/bin/\r\n\r\n# The EXT_DOC_PATHS tag can be used to specify one or more paths to \r\n# documentation generated for other projects. This allows doxysearch to search \r\n# the documentation for these projects as well.\r\n\r\n#EXT_DOC_PATHS          = \r\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/docs/doxygen.css",
    "content": "BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {\n\tfont-family: Geneva, Arial, Helvetica, sans-serif;\n}\nBODY,TD {\n       font-size: 80%;\n}\nCODE {\n\tfont-size: 120%;\n       font-family: monospace;\n}\n.fragment, pre {\n\tfont-size: 110%;\n       font-family: monospace;\n}\nH1 {\n\ttext-align: center;\n       font-size: 240%;\n}\nH2 {\n       \tfont-size: 200%;\n\tmargin-top     : 60px;\n}\nH3 {\n       font-size: 160%;\n}\nH4 {\n       font-size: 120%;\n}\nCAPTION { font-weight: bold }\nDIV.qindex {\n\twidth: 100%;\n\tbackground-color: #eeeeff;\n\tborder: 1px solid #b0b0b0;\n\ttext-align: center;\n\tmargin: 2px;\n\tpadding: 2px;\n\tline-height: 140%;\n}\nDIV.nav {\n\twidth: 100%;\n\tbackground-color: #eeeeff;\n\tborder: 1px solid #b0b0b0;\n\ttext-align: center;\n\tmargin: 2px;\n\tpadding: 2px;\n\tline-height: 140%;\n}\nA.qindex {\n       text-decoration: none;\n       font-size: 120%;\n       color: #1A419D;\n}\nA.qindex:visited {\n       text-decoration: none;\n       color: #1A419D\n}\nA.qindex:hover {\n\ttext-decoration: none;\n\tbackground-color: #ddddff;\n}\nA.qindexHL {\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tbackground-color: #6666cc;\n\tcolor: #ffffff;\n\tborder: 1px double #9295C2;\n}\nA.qindexHL:hover {\n\ttext-decoration: none;\n\tbackground-color: #6666cc;\n\tcolor: #ffffff;\n}\nA.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }\nA.el { text-decoration: none; font-weight: bold }\nA.elRef { font-weight: bold }\nA.code:link { text-decoration: none; font-weight: normal; color: #0000FF; }\nA.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}\nA.codeRef:link { font-weight: normal; color: #0000FF}\nA.codeRef:visited { font-weight: normal; color: #0000FF}\nA:hover { text-decoration: none; background-color: #f2f2ff }\nDL.el { margin-left: -1cm }\nPRE.fragment {\n\tborder: 1px solid #CCCCCC;\n\tbackground-color: #f5f5f5;\n\tmargin-top: 4px;\n\tmargin-bottom: 4px;\n\tmargin-left: 2px;\n\tmargin-right: 8px;\n\tpadding-left: 6px;\n\tpadding-right: 6px;\n\tpadding-top: 4px;\n\tpadding-bottom: 4px;\n}\nDIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }\nTD.md { background-color: #F4F4FB; font-weight: bold; }\nTD.mdPrefix {\n       background-color: #F4F4FB;\n       color: #606060;\n\tfont-size: 80%;\n}\nTD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; }\nTD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; }\nDIV.groupHeader {\n       margin-left: 16px;\n       margin-top: 12px;\n       margin-bottom: 6px;\n       font-weight: bold;\n}\nDIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }\nBODY {\n\tbackground: white;\n\tcolor: black;\n\tmargin-right: 20px;\n\tmargin-left: 20px;\n}\nTD.indexkey {\n\tbackground-color: #eeeeff;\n\tfont-weight: bold;\n\tpadding-right  : 10px;\n\tpadding-top    : 2px;\n\tpadding-left   : 10px;\n\tpadding-bottom : 2px;\n\tmargin-left    : 0px;\n\tmargin-right   : 0px;\n\tmargin-top     : 2px;\n\tmargin-bottom  : 2px;\n\tborder: 1px solid #CCCCCC;\n}\nTD.indexvalue {\n\tbackground-color: #eeeeff;\n\tfont-style: italic;\n\tpadding-right  : 10px;\n\tpadding-top    : 2px;\n\tpadding-left   : 10px;\n\tpadding-bottom : 2px;\n\tmargin-left    : 0px;\n\tmargin-right   : 0px;\n\tmargin-top     : 2px;\n\tmargin-bottom  : 2px;\n\tborder: 1px solid #CCCCCC;\n}\nTR.memlist {\n   background-color: #f0f0f0; \n}\nP.formulaDsp { text-align: center; }\nIMG.formulaDsp { }\nIMG.formulaInl { vertical-align: middle; }\nSPAN.keyword       { color: #008000 }\nSPAN.keywordtype   { color: #604020 }\nSPAN.keywordflow   { color: #e08000 }\nSPAN.comment       { color: #800000 }\nSPAN.preprocessor  { color: #806020 }\nSPAN.stringliteral { color: #002080 }\nSPAN.charliteral   { color: #008080 }\n.mdTable {\n\tborder: 1px solid #868686;\n\tbackground-color: #F4F4FB;\n}\n.mdRow {\n\tpadding: 8px 10px;\n}\n.mdescLeft {\n       padding: 0px 8px 4px 8px;\n\tfont-size: 80%;\n\tfont-style: italic;\n\tbackground-color: #FAFAFA;\n\tborder-top: 1px none #E0E0E0;\n\tborder-right: 1px none #E0E0E0;\n\tborder-bottom: 1px none #E0E0E0;\n\tborder-left: 1px none #E0E0E0;\n\tmargin: 0px;\n}\n.mdescRight {\n       padding: 0px 8px 4px 8px;\n\tfont-size: 80%;\n\tfont-style: italic;\n\tbackground-color: #FAFAFA;\n\tborder-top: 1px none #E0E0E0;\n\tborder-right: 1px none #E0E0E0;\n\tborder-bottom: 1px none #E0E0E0;\n\tborder-left: 1px none #E0E0E0;\n\tmargin: 0px;\n}\n.memItemLeft {\n\tpadding: 1px 0px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: solid;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.memItemRight {\n\tpadding: 1px 8px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: solid;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.memTemplItemLeft {\n\tpadding: 1px 0px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: none;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.memTemplItemRight {\n\tpadding: 1px 8px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: none;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.memTemplParams {\n\tpadding: 1px 0px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: solid;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n       color: #606060;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.search     { color: #003399;\n              font-weight: bold;\n}\nFORM.search {\n              margin-bottom: 0px;\n              margin-top: 0px;\n}\nINPUT.search { font-size: 75%;\n               color: #000080;\n               font-weight: normal;\n               background-color: #eeeeff;\n}\nTD.tiny      { font-size: 75%;\n}\na {\n\tcolor: #252E78;\n}\na:visited {\n\tcolor: #3D2185;\n}\n.dirtab { padding: 4px;\n          border-collapse: collapse;\n          border: 1px solid #b0b0b0;\n}\nTH.dirtab { background: #eeeeff;\n            font-weight: bold;\n}\nHR { height: 1px;\n     border: none;\n     border-top: 1px solid black;\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/docs/footer.html",
    "content": "<p>&nbsp;</p>\r\n<hr><center>\r\nPJLIB-UTIL Open Source, small footprint, and portable asynchronous/caching DNS resolver, text scanner, STUN client, and XML library<br>\r\nCopyright (C) 2006-2009 Teluu Inc.\r\n</center>\r\n\r\n\r\n<!--#include virtual=\"/footer.html\" -->\r\n\r\n</BODY>\r\n</HTML>\r\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/docs/header.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=iso-8859-1\">\r\n<title>$title ($projectnumber)</title>\r\n<link href=\"/style/style.css\" rel=\"stylesheet\" type=\"text/css\">\r\n</head><body>\r\n\t<!--#include virtual=\"/header.html\" -->\r\n\t<p><A HREF=\"/\">Home</A> --&gt; <A HREF=\"/docs.htm\">Documentations</A> --&gt; PJLIB-UTIL Reference</p>\r\n\r\n\r\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/base64.h",
    "content": "/* $Id: base64.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_BASE64_H__\n#define __PJLIB_UTIL_BASE64_H__\n\n/**\n * @file base64.h\n * @brief Base64 encoding and decoding\n */\n\n#include <pjlib-util/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJLIB_UTIL_BASE64 Base64 Encoding/Decoding\n * @ingroup PJLIB_UTIL_ENCRYPTION\n * @{\n * This module implements base64 encoding and decoding.\n */\n\n/**\n * Helper macro to calculate the approximate length required for base256 to\n * base64 conversion.\n */\n#define PJ_BASE256_TO_BASE64_LEN(len)\t(len * 4 / 3 + 3)\n\n/**\n * Helper macro to calculate the approximage length required for base64 to\n * base256 conversion.\n */\n#define PJ_BASE64_TO_BASE256_LEN(len)\t(len * 3 / 4)\n\n\n/**\n * Encode a buffer into base64 encoding.\n *\n * @param input\t    The input buffer.\n * @param in_len    Size of the input buffer.\n * @param output    Output buffer. Caller must allocate this buffer with\n *\t\t    the appropriate size.\n * @param out_len   On entry, it specifies the length of the output buffer. \n *\t\t    Upon return, this will be filled with the actual\n *\t\t    length of the output buffer.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pj_base64_encode(const pj_uint8_t *input, int in_len,\n\t\t\t\t     char *output, int *out_len);\n\n\n/**\n * Decode base64 string.\n *\n * @param input\t    Input string.\n * @param out\t    Buffer to store the output. Caller must allocate\n *\t\t    this buffer with the appropriate size.\n * @param out_len   On entry, it specifies the length of the output buffer. \n *\t\t    Upon return, this will be filled with the actual\n *\t\t    length of the output.\n */\nPJ_DECL(pj_status_t) pj_base64_decode(const pj_str_t *input, \n\t\t\t\t      pj_uint8_t *out, int *out_len);\n\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJLIB_UTIL_BASE64_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/config.h",
    "content": "/* $Id: config.h 4461 2013-04-05 03:02:19Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_CONFIG_H__\n#define __PJLIB_UTIL_CONFIG_H__\n\n\n/**\n * @file config.h\n * @brief Compile time settings\n */\n\n/**\n * @defgroup PJLIB_UTIL_CONFIG Configuration\n * @ingroup PJLIB_UTIL_BASE\n * @{\n */\n\n\n/* **************************************************************************\n * DNS CONFIGURATION\n */\n\n/**\n * Maximum number of IP addresses in DNS A response.\n */\n#ifndef PJ_DNS_MAX_IP_IN_A_REC\n#   define PJ_DNS_MAX_IP_IN_A_REC   8\n#endif\n\n\n/**\n * Maximum server address entries per one SRV record\n */\n#ifndef PJ_DNS_SRV_MAX_ADDR\n#   define PJ_DNS_SRV_MAX_ADDR\t    8\n#endif\n\n\n/**\n * This constant specifies the maximum names to keep in the temporary name\n * table when performing name compression scheme when duplicating DNS packet\n * (the #pj_dns_packet_dup() function).\n *\n * Generally name compression is desired, since it saves some memory (see\n * PJ_DNS_RESOLVER_RES_BUF_SIZE setting). However it comes at the expense of \n * a little processing overhead to perform name scanning and also a little\n * bit more stack usage (8 bytes per entry on 32bit platform).\n *\n * Default: 16\n */\n#ifndef PJ_DNS_MAX_NAMES_IN_NAMETABLE\n#   define PJ_DNS_MAX_NAMES_IN_NAMETABLE\t    16\n#endif\n\n\n/* **************************************************************************\n * RESOLVER CONFIGURATION\n */\n\n\n/**\n * Maximum numbers of DNS nameservers that can be configured in resolver.\n */\n#ifndef PJ_DNS_RESOLVER_MAX_NS\n#   define PJ_DNS_RESOLVER_MAX_NS\t\t    16\n#endif\n\n\n/**\n * Default retransmission delay, in miliseconds. The combination of \n * retransmission delay and count determines the query timeout.\n *\n * Default: 2000 (2 seconds, according to RFC 1035)\n */\n#ifndef PJ_DNS_RESOLVER_QUERY_RETRANSMIT_DELAY\n#   define PJ_DNS_RESOLVER_QUERY_RETRANSMIT_DELAY   2000\n#endif\n\n\n/**\n * Maximum number of transmissions before timeout is declared for\n * the query.\n *\n * Default: 5\n */\n#ifndef PJ_DNS_RESOLVER_QUERY_RETRANSMIT_COUNT\n#   define PJ_DNS_RESOLVER_QUERY_RETRANSMIT_COUNT   5\n#endif\n\n\n/**\n * Maximum life-time of DNS response in the resolver response cache, \n * in seconds. If the value is zero, then DNS response caching will be \n * disabled.\n *\n * Default is 300 seconds (5 minutes).\n *\n * @see PJ_DNS_RESOLVER_INVALID_TTL\n */\n#ifndef PJ_DNS_RESOLVER_MAX_TTL\n#   define PJ_DNS_RESOLVER_MAX_TTL\t\t    (5*60)\n#endif\n\n/**\n * The life-time of invalid DNS response in the resolver response cache.\n * An invalid DNS response is a response which RCODE is non-zero and \n * response without any answer section. These responses can be put in \n * the cache too to minimize message round-trip.\n *\n * Default: 60 (one minute).\n *\n * @see PJ_DNS_RESOLVER_MAX_TTL\n */\n#ifndef PJ_DNS_RESOLVER_INVALID_TTL\n#   define PJ_DNS_RESOLVER_INVALID_TTL\t\t    60\n#endif\n\n/**\n * The interval on which nameservers which are known to be good to be \n * probed again to determine whether they are still good. Note that\n * this applies to both active nameserver (the one currently being used)\n * and idle nameservers (good nameservers that are not currently selected).\n * The probing to query the \"goodness\" of nameservers involves sending\n * the same query to multiple servers, so it's probably not a good idea\n * to send this probing too often.\n *\n * Default: 600 (ten minutes)\n *\n * @see PJ_DNS_RESOLVER_BAD_NS_TTL\n */\n#ifndef PJ_DNS_RESOLVER_GOOD_NS_TTL\n#   define PJ_DNS_RESOLVER_GOOD_NS_TTL\t\t    (10*60)\n#endif\n\n/**\n * The interval on which nameservers which known to be bad to be probed\n * again to determine whether it is still bad.\n *\n * Default: 60 (one minute)\n *\n * @see PJ_DNS_RESOLVER_GOOD_NS_TTL\n */\n#ifndef PJ_DNS_RESOLVER_BAD_NS_TTL\n#   define PJ_DNS_RESOLVER_BAD_NS_TTL\t\t    (1*60)\n#endif\n\n\n/**\n * Maximum size of UDP packet. RFC 1035 states that maximum size of\n * DNS packet carried over UDP is 512 bytes.\n *\n * Default: 512 byes\n */\n#ifndef PJ_DNS_RESOLVER_MAX_UDP_SIZE\n#   define PJ_DNS_RESOLVER_MAX_UDP_SIZE\t\t    512\n#endif\n\n\n/**\n * Size of memory pool allocated for each individual DNS response cache.\n * This value here should be more or less the same as maximum UDP packet\n * size (PJ_DNS_RESOLVER_MAX_UDP_SIZE), since the DNS replicator function\n * (#pj_dns_packet_dup()) is also capable of performing name compressions.\n *\n * Default: 512\n */\n#ifndef PJ_DNS_RESOLVER_RES_BUF_SIZE\n#   define PJ_DNS_RESOLVER_RES_BUF_SIZE\t\t    512\n#endif\n\n\n/**\n * Size of temporary pool buffer for parsing DNS packets in resolver.\n *\n * default: 4000\n */\n#ifndef PJ_DNS_RESOLVER_TMP_BUF_SIZE\n#   define PJ_DNS_RESOLVER_TMP_BUF_SIZE\t\t    4000\n#endif\n\n\n/* **************************************************************************\n * SCANNER CONFIGURATION\n */\n\n\n/**\n * Macro PJ_SCANNER_USE_BITWISE is defined and non-zero (by default yes)\n * will enable the use of bitwise for character input specification (cis).\n * This would save several kilobytes of .bss memory in the SIP parser.\n */\n#ifndef PJ_SCANNER_USE_BITWISE\n#  define PJ_SCANNER_USE_BITWISE\t\t    1\n#endif\n\n\n\n/* **************************************************************************\n * STUN CLIENT CONFIGURATION\n */\n\n/**\n * Maximum number of attributes in the STUN packet (for the old STUN\n * library).\n *\n * Default: 16\n */\n#ifndef PJSTUN_MAX_ATTR\n#   define PJSTUN_MAX_ATTR\t\t\t    16\n#endif\n\n\n/**\n * Maximum number of attributes in the STUN packet (for the new STUN\n * library).\n *\n * Default: 16\n */\n#ifndef PJ_STUN_MAX_ATTR\n#   define PJ_STUN_MAX_ATTR\t\t\t    16\n#endif\n\n\n/* **************************************************************************\n * ENCRYPTION\n */\n\n/**\n * Specifies whether CRC32 algorithm should use the table based lookup table\n * for faster calculation, at the expense of about 1KB table size on the\n * executable. If zero, the CRC32 will use non-table based which is more than\n * an order of magnitude slower.\n *\n * Default: 1\n */\n#ifndef PJ_CRC32_HAS_TABLES\n#   define PJ_CRC32_HAS_TABLES\t\t\t    1\n#endif\n\n\n/* **************************************************************************\n * HTTP Client configuration\n */\n/**\n * Timeout value for HTTP request operation. The value is in ms.\n * Default: 60000ms\n */\n#ifndef PJ_HTTP_DEFAULT_TIMEOUT\n#   define PJ_HTTP_DEFAULT_TIMEOUT         (60000)\n#endif\n\n/**\n * @}\n */\n\n#endif\t/* __PJLIB_UTIL_CONFIG_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/crc32.h",
    "content": "/* $Id: crc32.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_CRC32_H__\n#define __PJLIB_UTIL_CRC32_H__\n\n/**\n * @file crc32.h\n * @brief CRC32 implementation\n */\n\n#include <pjlib-util/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJLIB_UTIL_CRC32 CRC32 (Cyclic Redundancy Check)\n * @ingroup PJLIB_UTIL_ENCRYPTION\n * @{\n * This implements CRC32 algorithm. See ITU-T V.42 for the formal \n * specification.\n */\n\n/** CRC32 context. */\ntypedef struct pj_crc32_context\n{\n    pj_uint32_t\tcrc_state;\t/**< Current state. */\n} pj_crc32_context;\n\n\n/**\n * Initialize CRC32 context.\n *\n * @param ctx\t    CRC32 context.\n */\nPJ_DECL(void) pj_crc32_init(pj_crc32_context *ctx);\n\n/**\n * Feed data incrementally to the CRC32 algorithm.\n *\n * @param ctx\t    CRC32 context.\n * @param data\t    Input data.\n * @param nbytes    Length of the input data.\n *\n * @return\t    The current CRC32 value.\n */\nPJ_DECL(pj_uint32_t) pj_crc32_update(pj_crc32_context *ctx, \n\t\t\t\t     const pj_uint8_t *data,\n\t\t\t\t     pj_size_t nbytes);\n\n/**\n * Finalize CRC32 calculation and retrieve the CRC32 value.\n *\n * @param ctx\t    CRC32 context.\n *\n * @return\t    The current CRC value.\n */\nPJ_DECL(pj_uint32_t) pj_crc32_final(pj_crc32_context *ctx);\n\n/**\n * Perform one-off CRC32 calculation to the specified data.\n *\n * @param data\t    Input data.\n * @param nbytes    Length of input data.\n *\n * @return\t    CRC value of the data.\n */\nPJ_DECL(pj_uint32_t) pj_crc32_calc(const pj_uint8_t *data,\n\t\t\t\t   pj_size_t nbytes);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJLIB_UTIL_CRC32_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/dns.h",
    "content": "/* $Id: dns.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_DNS_H__\n#define __PJLIB_UTIL_DNS_H__\n\n\n/**\n * @file dns.h\n * @brief Low level DNS message parsing and packetization.\n */\n#include <pjlib-util/types.h>\n#include <pj/sock.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_DNS DNS and Asynchronous DNS Resolver\n * @ingroup PJ_PROTOCOLS\n */\n\n/**\n * @defgroup PJ_DNS_PARSING Low-level DNS Message Parsing and Packetization\n * @ingroup PJ_DNS\n * @{\n *\n * This module provides low-level services to parse and packetize DNS queries\n * and responses. The functions support building a DNS query packet and parse\n * the data in the DNS response. This implementation conforms to the \n * following specifications:\n *  - RFC 1035: DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION\n *  - RFC 1886: DNS Extensions to support IP version 6\n *\n * To create a DNS query packet, application should call #pj_dns_make_query()\n * function, specifying the desired DNS query type, the name to be resolved,\n * and the buffer where the DNS packet will be built into. \n *\n * When incoming DNS query or response packet arrives, application can use\n * #pj_dns_parse_packet() to parse the TCP/UDP payload into parsed DNS packet\n * structure.\n *\n * This module does not provide any networking functionalities to send or\n * receive DNS packets. This functionality should be provided by higher layer\n * modules such as @ref PJ_DNS_RESOLVER.\n */\n\nenum\n{\n    PJ_DNS_CLASS_IN\t= 1\t/**< DNS class IN.\t\t\t    */\n};\n\n/**\n * This enumeration describes standard DNS record types as described by\n * RFC 1035, RFC 2782, and others.\n */\ntypedef enum pj_dns_type\n{\n    PJ_DNS_TYPE_A\t= 1,    /**< Host address (A) record.\t\t    */\n    PJ_DNS_TYPE_NS\t= 2,    /**< Authoritative name server (NS)\t    */\n    PJ_DNS_TYPE_MD\t= 3,    /**< Mail destination (MD) record.\t    */\n    PJ_DNS_TYPE_MF\t= 4,    /**< Mail forwarder (MF) record.\t    */\n    PJ_DNS_TYPE_CNAME\t= 5,\t/**< Canonical name (CNAME) record.\t    */\n    PJ_DNS_TYPE_SOA\t= 6,    /**< Marks start of zone authority.\t    */\n    PJ_DNS_TYPE_MB\t= 7,    /**< Mailbox domain name (MB).\t\t    */\n    PJ_DNS_TYPE_MG\t= 8,    /**< Mail group member (MG).\t\t    */\n    PJ_DNS_TYPE_MR\t= 9,    /**< Mail rename domain name.\t\t    */\n    PJ_DNS_TYPE_NULL\t= 10,\t/**< NULL RR.\t\t\t\t    */\n    PJ_DNS_TYPE_WKS\t= 11,\t/**< Well known service description\t    */\n    PJ_DNS_TYPE_PTR\t= 12,\t/**< Domain name pointer.\t\t    */\n    PJ_DNS_TYPE_HINFO\t= 13,\t/**< Host information.\t\t\t    */\n    PJ_DNS_TYPE_MINFO\t= 14,\t/**< Mailbox or mail list information.\t    */\n    PJ_DNS_TYPE_MX\t= 15,\t/**< Mail exchange record.\t\t    */\n    PJ_DNS_TYPE_TXT\t= 16,\t/**< Text string.\t\t\t    */\n    PJ_DNS_TYPE_RP\t= 17,\t/**< Responsible person.\t\t    */\n    PJ_DNS_TYPE_AFSB\t= 18,\t/**< AFS cell database.\t\t\t    */\n    PJ_DNS_TYPE_X25\t= 19,\t/**< X.25 calling address.\t\t    */\n    PJ_DNS_TYPE_ISDN\t= 20,\t/**< ISDN calling address.\t\t    */\n    PJ_DNS_TYPE_RT\t= 21,\t/**< Router.\t\t\t\t    */\n    PJ_DNS_TYPE_NSAP\t= 22,\t/**< NSAP address.\t\t\t    */\n    PJ_DNS_TYPE_NSAP_PTR= 23,\t/**< NSAP reverse address.\t\t    */\n    PJ_DNS_TYPE_SIG\t= 24,\t/**< Signature.\t\t\t\t    */\n    PJ_DNS_TYPE_KEY\t= 25,\t/**< Key.\t\t\t\t    */\n    PJ_DNS_TYPE_PX\t= 26,\t/**< X.400 mail mapping.\t\t    */\n    PJ_DNS_TYPE_GPOS\t= 27,\t/**< Geographical position (withdrawn)\t    */\n    PJ_DNS_TYPE_AAAA\t= 28,\t/**< IPv6 address.\t\t\t    */\n    PJ_DNS_TYPE_LOC\t= 29,\t/**< Location.\t\t\t\t    */\n    PJ_DNS_TYPE_NXT\t= 30,\t/**< Next valid name in the zone.\t    */\n    PJ_DNS_TYPE_EID\t= 31,\t/**< Endpoint idenfitier.\t\t    */\n    PJ_DNS_TYPE_NIMLOC\t= 32,\t/**< Nimrod locator.\t\t\t    */\n    PJ_DNS_TYPE_SRV\t= 33,\t/**< Server selection (SRV) record.\t    */\n    PJ_DNS_TYPE_ATMA\t= 34,\t/**< DNS ATM address record.\t\t    */\n    PJ_DNS_TYPE_NAPTR\t= 35,\t/**< DNS Naming authority pointer record.   */\n    PJ_DNS_TYPE_KX\t= 36,\t/**< DNS key exchange record.\t\t    */\n    PJ_DNS_TYPE_CERT\t= 37,\t/**< DNS certificate record.\t\t    */\n    PJ_DNS_TYPE_A6\t= 38,\t/**< DNS IPv6 address (experimental)\t    */\n    PJ_DNS_TYPE_DNAME\t= 39,\t/**< DNS non-terminal name redirection rec. */\n\n    PJ_DNS_TYPE_OPT\t= 41,\t/**< DNS options - contains EDNS metadata.  */\n    PJ_DNS_TYPE_APL\t= 42,\t/**< DNS Address Prefix List (APL) record.  */\n    PJ_DNS_TYPE_DS\t= 43,\t/**< DNS Delegation Signer (DS)\t\t    */\n    PJ_DNS_TYPE_SSHFP\t= 44,\t/**< DNS SSH Key Fingerprint\t\t    */\n    PJ_DNS_TYPE_IPSECKEY= 45,\t/**< DNS IPSEC Key.\t\t\t    */\n    PJ_DNS_TYPE_RRSIG\t= 46,\t/**< DNS Resource Record signature.\t    */\n    PJ_DNS_TYPE_NSEC\t= 47,\t/**< DNS Next Secure Name.\t\t    */\n    PJ_DNS_TYPE_DNSKEY\t= 48\t/**< DNSSEC Key.\t\t\t    */\n} pj_dns_type;\n\n\n\n/**\n * Standard DNS header, according to RFC 1035, which will be present in\n * both DNS query and DNS response. \n *\n * Note that all values seen by application would be in\n * host by order. The library would convert them to network\n * byte order as necessary.\n */\ntypedef struct pj_dns_hdr\n{\n    pj_uint16_t  id;\t    /**< Transaction ID.\t    */\n    pj_uint16_t  flags;\t    /**< Flags.\t\t\t    */\n    pj_uint16_t  qdcount;   /**< Nb. of queries.\t    */\n    pj_uint16_t  anscount;  /**< Nb. of res records\t    */\n    pj_uint16_t  nscount;   /**< Nb. of NS records.\t    */\n    pj_uint16_t  arcount;   /**< Nb. of additional records  */\n} pj_dns_hdr;\n\n/** Create RCODE flag */\n#define PJ_DNS_SET_RCODE(c)\t((pj_uint16_t)((c) & 0x0F))\n\n/** Create RA (Recursion Available) bit */\n#define PJ_DNS_SET_RA(on)\t((pj_uint16_t)((on) << 7))\n\n/** Create RD (Recursion Desired) bit */\n#define PJ_DNS_SET_RD(on)\t((pj_uint16_t)((on) << 8))\n\n/** Create TC (Truncated) bit */\n#define PJ_DNS_SET_TC(on)\t((pj_uint16_t)((on) << 9))\n\n/** Create AA (Authoritative Answer) bit */\n#define PJ_DNS_SET_AA(on)\t((pj_uint16_t)((on) << 10))\n\n/** Create four bits opcode */\n#define PJ_DNS_SET_OPCODE(o)\t((pj_uint16_t)((o)  << 11))\n\n/** Create query/response bit */\n#define PJ_DNS_SET_QR(on)\t((pj_uint16_t)((on) << 15))\n\n\n/** Get RCODE value */\n#define PJ_DNS_GET_RCODE(val)\t(((val) & PJ_DNS_SET_RCODE(0x0F)) >> 0)\n\n/** Get RA bit */\n#define PJ_DNS_GET_RA(val)\t(((val) & PJ_DNS_SET_RA(1)) >> 7)\n\n/** Get RD bit */\n#define PJ_DNS_GET_RD(val)\t(((val) & PJ_DNS_SET_RD(1)) >> 8)\n\n/** Get TC bit */\n#define PJ_DNS_GET_TC(val)\t(((val) & PJ_DNS_SET_TC(1)) >> 9)\n\n/** Get AA bit */\n#define PJ_DNS_GET_AA(val)\t(((val) & PJ_DNS_SET_AA(1)) >> 10)\n\n/** Get OPCODE value */\n#define PJ_DNS_GET_OPCODE(val)\t(((val) & PJ_DNS_SET_OPCODE(0x0F)) >> 11)\n\n/** Get QR bit */\n#define PJ_DNS_GET_QR(val)\t(((val) & PJ_DNS_SET_QR(1)) >> 15)\n\n\n/** \n * These constants describe DNS RCODEs. Application can fold these constants\n * into PJLIB pj_status_t namespace by calling #PJ_STATUS_FROM_DNS_RCODE()\n * macro.\n */\ntypedef enum pj_dns_rcode\n{\n    PJ_DNS_RCODE_FORMERR    = 1,    /**< Format error.\t\t\t    */\n    PJ_DNS_RCODE_SERVFAIL   = 2,    /**< Server failure.\t\t    */\n    PJ_DNS_RCODE_NXDOMAIN   = 3,    /**< Name Error.\t\t\t    */\n    PJ_DNS_RCODE_NOTIMPL    = 4,    /**< Not Implemented.\t\t    */\n    PJ_DNS_RCODE_REFUSED    = 5,    /**< Refused.\t\t\t    */\n    PJ_DNS_RCODE_YXDOMAIN   = 6,    /**< The name exists.\t\t    */\n    PJ_DNS_RCODE_YXRRSET    = 7,    /**< The RRset (name, type) exists.\t    */\n    PJ_DNS_RCODE_NXRRSET    = 8,    /**< The RRset (name, type) doesn't exist*/\n    PJ_DNS_RCODE_NOTAUTH    = 9,    /**< Not authorized.\t\t    */\n    PJ_DNS_RCODE_NOTZONE    = 10    /**< The zone specified is not a zone.  */\n\n} pj_dns_rcode;\n\n\n/**\n * This structure describes a DNS query record.\n */\ntypedef struct pj_dns_parsed_query\n{\n    pj_str_t\tname;\t    /**< The domain in the query.\t\t    */\n    pj_uint16_t\ttype;\t    /**< Type of the query (pj_dns_type)\t    */\n    pj_uint16_t\tdnsclass;   /**< Network class (PJ_DNS_CLASS_IN=1)\t    */\n} pj_dns_parsed_query;\n\n\n/**\n * This structure describes a Resource Record parsed from the DNS packet.\n * All integral values are in host byte order.\n */\ntypedef struct pj_dns_parsed_rr\n{\n    pj_str_t\t name;\t    /**< The domain name which this rec pertains.   */\n    pj_uint16_t\t type;\t    /**< RR type code.\t\t\t\t    */\n    pj_uint16_t\t dnsclass;  /**< Class of data (PJ_DNS_CLASS_IN=1).\t    */\n    pj_uint32_t\t ttl;\t    /**< Time to live.\t\t\t\t    */\n    pj_uint16_t\t rdlength;  /**< Resource data length.\t\t\t    */\n    void\t*data;\t    /**< Pointer to the raw resource data, only\n\t\t\t\t when the type is not known. If it is known,\n\t\t\t\t the data will be put in rdata below.\t    */\n    \n    /** For resource types that are recognized/supported by this library,\n     *  the parsed resource data will be placed in this rdata union.\n     */\n    union rdata\n    {\n\t/** SRV Resource Data (PJ_DNS_TYPE_SRV, 33) */\n\tstruct srv {\n\t    pj_uint16_t\tprio;\t/**< Target priority (lower is higher).\t    */\n\t    pj_uint16_t weight;\t/**< Weight/proportion\t\t\t    */\n\t    pj_uint16_t port;\t/**< Port number of the service\t\t    */\n\t    pj_str_t\ttarget;\t/**< Target name.\t\t\t    */\n\t} srv;\n\n\t/** CNAME Resource Data (PJ_DNS_TYPE_CNAME, 5) */\n\tstruct cname {\n\t    pj_str_t\tname;\t/**< Primary canonical name for an alias.   */\n\t} cname;\n\n\t/** NS Resource Data (PJ_DNS_TYPE_NS, 2) */\n\tstruct ns {\n\t    pj_str_t\tname;\t/**< Primary name server.\t\t    */\n\t} ns;\n\n\t/** PTR Resource Data (PJ_DNS_TYPE_PTR, 12) */\n\tstruct ptr {\n\t    pj_str_t\tname;\t/**< PTR name.\t\t\t\t    */\n\t} ptr;\n\n\t/** A Resource Data (PJ_DNS_TYPE_A, 1) */\n\tstruct a {\n\t    pj_in_addr\tip_addr;/**< IPv4 address in network byte order.    */\n\t} a;\n\n\t/** AAAA Resource Data (PJ_DNS_TYPE_AAAA, 28) */\n\tstruct aaaa {\n\t    pj_in6_addr\tip_addr;/**< IPv6 address in network byte order.    */\n\t} aaaa;\n\n    } rdata;\n\n} pj_dns_parsed_rr;\n\n\n/**\n * This structure describes the parsed repersentation of the raw DNS packet.\n * Note that all integral values in the parsed packet are represented in\n * host byte order.\n */\ntypedef struct pj_dns_parsed_packet\n{\n    pj_dns_hdr\t\t hdr;\t/**< Pointer to DNS hdr, in host byte order */\n    pj_dns_parsed_query\t*q;\t/**< Array of DNS queries.\t\t    */\n    pj_dns_parsed_rr\t*ans;\t/**< Array of DNS RR answer.\t\t    */\n    pj_dns_parsed_rr\t*ns;\t/**< Array of NS record in the answer.\t    */\n    pj_dns_parsed_rr\t*arr;\t/**< Array of additional RR answer.\t    */\n} pj_dns_parsed_packet;\n\n\n/**\n * Option flags to be specified when calling #pj_dns_packet_dup() function.\n * These flags can be combined with bitwise OR operation.\n */\nenum pj_dns_dup_options\n{\n    PJ_DNS_NO_QD    = 1, /**< Do not duplicate the query section.\t    */\n    PJ_DNS_NO_ANS   = 2, /**< Do not duplicate the answer section.\t    */\n    PJ_DNS_NO_NS    = 4, /**< Do not duplicate the NS section.\t\t    */\n    PJ_DNS_NO_AR    = 8  /**< Do not duplicate the additional rec section   */\n};\n\n\n/**\n * Create DNS query packet to resolve the specified names. This function\n * can be used to build any types of DNS query, such as A record or DNS SRV\n * record.\n *\n * Application specifies the type of record and the name to be queried,\n * and the function will build the DNS query packet into the buffer\n * specified. Once the packet is successfully built, application can send\n * the packet via TCP or UDP connection.\n *\n * @param packet\tThe buffer to put the DNS query packet.\n * @param size\t\tOn input, it specifies the size of the buffer.\n *\t\t\tOn output, it will be filled with the actual size of\n *\t\t\tthe DNS query packet.\n * @param id\t\tDNS query ID to associate DNS response with the\n *\t\t\tquery.\n * @param qtype\t\tDNS type of record to be queried (see #pj_dns_type).\n * @param name\t\tName to be queried from the DNS server.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_dns_make_query(void *packet,\n\t\t\t\t       unsigned *size,\n\t\t\t\t       pj_uint16_t id,\n\t\t\t\t       int qtype,\n\t\t\t\t       const pj_str_t *name);\n\n/**\n * Parse raw DNS packet into parsed DNS packet structure. This function is\n * able to parse few DNS resource records such as A record, PTR record,\n * CNAME record, NS record, and SRV record.\n *\n * @param pool\t\tPool to allocate memory for the parsed packet.\n * @param packet\tPointer to the DNS packet (the TCP/UDP payload of \n *\t\t\tthe raw packet).\n * @param size\t\tThe size of the DNS packet.\n * @param p_res\t\tPointer to store the resulting parsed packet.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_dns_parse_packet(pj_pool_t *pool,\n\t\t\t\t\t const void *packet,\n\t\t\t\t\t unsigned size,\n\t\t\t\t\t pj_dns_parsed_packet **p_res);\n\n/**\n * Duplicate DNS packet.\n *\n * @param pool\t\tThe pool to allocate memory for the duplicated packet.\n * @param p\t\tThe DNS packet to be cloned.\n * @param options\tOption flags, from pj_dns_dup_options.\n * @param p_dst\t\tPointer to store the cloned DNS packet.\n */\nPJ_DECL(void) pj_dns_packet_dup(pj_pool_t *pool,\n\t\t\t\tconst pj_dns_parsed_packet*p,\n\t\t\t\tunsigned options,\n\t\t\t\tpj_dns_parsed_packet **p_dst);\n\n\n/**\n * Utility function to get the type name string of the specified DNS type.\n *\n * @param type\t\tDNS type (see #pj_dns_type).\n *\n * @return\t\tString name of the type (e.g. \"A\", \"SRV\", etc.).\n */\nPJ_DECL(const char *) pj_dns_get_type_name(int type);\n\n\n/**\n * Initialize DNS record as DNS SRV record.\n *\n * @param rec\t\tThe DNS resource record to be initialized as DNS\n *\t\t\tSRV record.\n * @param res_name\tResource name.\n * @param dnsclass\tDNS class.\n * @param ttl\t\tResource TTL value.\n * @param prio\t\tDNS SRV priority.\n * @param weight\tDNS SRV weight.\n * @param port\t\tTarget port.\n * @param target\tTarget name.\n */\nPJ_DECL(void) pj_dns_init_srv_rr(pj_dns_parsed_rr *rec,\n\t\t\t\t const pj_str_t *res_name,\n\t\t\t\t unsigned dnsclass,\n\t\t\t\t unsigned ttl,\n\t\t\t\t unsigned prio,\n\t\t\t\t unsigned weight,\n\t\t\t\t unsigned port,\n\t\t\t\t const pj_str_t *target);\n\n/**\n * Initialize DNS record as DNS CNAME record.\n *\n * @param rec\t\tThe DNS resource record to be initialized as DNS\n *\t\t\tCNAME record.\n * @param res_name\tResource name.\n * @param dnsclass\tDNS class.\n * @param ttl\t\tResource TTL value.\n * @param name\t\tHost name.\n */\nPJ_DECL(void) pj_dns_init_cname_rr(pj_dns_parsed_rr *rec,\n\t\t\t\t   const pj_str_t *res_name,\n\t\t\t\t   unsigned dnsclass,\n\t\t\t\t   unsigned ttl,\n\t\t\t\t   const pj_str_t *name);\n\n/**\n * Initialize DNS record as DNS A record.\n *\n * @param rec\t\tThe DNS resource record to be initialized as DNS\n *\t\t\tA record.\n * @param res_name\tResource name.\n * @param dnsclass\tDNS class.\n * @param ttl\t\tResource TTL value.\n * @param ip_addr\tHost address.\n */\nPJ_DECL(void) pj_dns_init_a_rr(pj_dns_parsed_rr *rec,\n\t\t\t       const pj_str_t *res_name,\n\t\t\t       unsigned dnsclass,\n\t\t\t       unsigned ttl,\n\t\t\t       const pj_in_addr *ip_addr);\n\n/**\n * Dump DNS packet to standard log.\n *\n * @param res\t\tThe DNS packet.\n */\nPJ_DECL(void) pj_dns_dump_packet(const pj_dns_parsed_packet *res);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJLIB_UTIL_DNS_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/dns_server.h",
    "content": "/* $Id: dns_server.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_DNS_SERVER_H__\n#define __PJLIB_UTIL_DNS_SERVER_H__\n\n/**\n * @file dns_server.h\n * @brief Simple DNS server\n */\n#include <pjlib-util/types.h>\n#include <pjlib-util/dns.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_DNS_SERVER Simple DNS Server\n * @ingroup PJ_DNS\n * @{\n * This contains a simple but fully working DNS server implementation, \n * mostly for testing purposes. It supports serving various DNS resource \n * records such as SRV, CNAME, A, and AAAA.\n */\n\n/**\n * Opaque structure to hold DNS server instance.\n */\ntypedef struct pj_dns_server pj_dns_server;\n\n/**\n * Create the DNS server instance. The instance will run immediately.\n *\n * @param pf\t    The pool factory to create memory pools.\n * @param ioqueue   Ioqueue instance where the server socket will be\n *\t\t    registered to.\n * @param af\t    Address family of the server socket (valid values\n *\t\t    are pj_AF_INET() for IPv4 and pj_AF_INET6() for IPv6).\n * @param port\t    The UDP port to listen.\n * @param flags\t    Flags, currently must be zero.\n * @param p_srv\t    Pointer to receive the DNS server instance.\n *\n * @return\t    PJ_SUCCESS if server has been created successfully,\n *\t\t    otherwise the function will return the appropriate\n *\t\t    error code.\n */\nPJ_DECL(pj_status_t) pj_dns_server_create(pj_pool_factory *pf,\n\t\t\t\t          pj_ioqueue_t *ioqueue,\n\t\t\t\t\t  int af,\n\t\t\t\t\t  unsigned port,\n\t\t\t\t\t  unsigned flags,\n\t\t\t\t          pj_dns_server **p_srv);\n\n/**\n * Destroy DNS server instance.\n *\n * @param srv\t    The DNS server instance.\n *\n * @return\t    PJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_dns_server_destroy(pj_dns_server *srv);\n\n\n/**\n * Add generic resource record entries to the server.\n *\n * @param srv\t    The DNS server instance.\n * @param count\t    Number of records to be added.\n * @param rr\t    Array of records to be added.\n *\n * @return\t    PJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_dns_server_add_rec(pj_dns_server *srv,\n\t\t\t\t\t   unsigned count,\n\t\t\t\t\t   const pj_dns_parsed_rr rr[]);\n\n/**\n * Remove the specified record from the server.\n *\n * @param srv\t    The DNS server instance.\n * @param dns_class The resource's DNS class. Valid value is PJ_DNS_CLASS_IN.\n * @param type\t    The resource type.\n * @param name\t    The resource name to be removed.\n *\n * @return\t    PJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_dns_server_del_rec(pj_dns_server *srv,\n\t\t\t\t\t   int dns_class,\n\t\t\t\t\t   pj_dns_type type,\n\t\t\t\t\t   const pj_str_t *name);\n\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJLIB_UTIL_DNS_SERVER_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/errno.h",
    "content": "/* $Id: errno.h 4440 2013-03-14 07:18:13Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_ERRNO_H__\n#define __PJLIB_UTIL_ERRNO_H__\n\n\n#include <pj/errno.h>\n\n/**\n * @defgroup PJLIB_UTIL_ERROR Error Codes\n * @ingroup PJLIB_UTIL_BASE\n * @{\n */\n\n/**\n * Start of error code relative to PJ_ERRNO_START_USER.\n * This value is 320000.\n */\n#define PJLIB_UTIL_ERRNO_START    (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*3)\n\n\n/************************************************************\n * STUN ERROR\n ***********************************************************/\n/**\n * @hideinitializer\n * Unable to resolve STUN server\n */\n#define PJLIB_UTIL_ESTUNRESOLVE\t    (PJLIB_UTIL_ERRNO_START+1)\t/* 320001 */\n/**\n * @hideinitializer\n * Unknown STUN message type.\n */\n#define PJLIB_UTIL_ESTUNINMSGTYPE   (PJLIB_UTIL_ERRNO_START+2)\t/* 320002 */\n/**\n * @hideinitializer\n * Invalid STUN message length\n */\n#define PJLIB_UTIL_ESTUNINMSGLEN    (PJLIB_UTIL_ERRNO_START+3)\t/* 320003 */\n/**\n * @hideinitializer\n * Invalid STUN attribute length\n */\n#define PJLIB_UTIL_ESTUNINATTRLEN   (PJLIB_UTIL_ERRNO_START+4)\t/* 320004 */\n/**\n * @hideinitializer\n * Invalid STUN attribute type\n */\n#define PJLIB_UTIL_ESTUNINATTRTYPE  (PJLIB_UTIL_ERRNO_START+5)\t/* 320005 */\n/**\n * @hideinitializer\n * Invalid STUN server/socket index\n */\n#define PJLIB_UTIL_ESTUNININDEX     (PJLIB_UTIL_ERRNO_START+6)\t/* 320006 */\n/**\n * @hideinitializer\n * No STUN binding response in the message\n */\n#define PJLIB_UTIL_ESTUNNOBINDRES   (PJLIB_UTIL_ERRNO_START+7)\t/* 320007 */\n/**\n * @hideinitializer\n * Received STUN error attribute\n */\n#define PJLIB_UTIL_ESTUNRECVERRATTR (PJLIB_UTIL_ERRNO_START+8)\t/* 320008 */\n/**\n * @hideinitializer\n * No STUN mapped address attribute\n */\n#define PJLIB_UTIL_ESTUNNOMAP       (PJLIB_UTIL_ERRNO_START+9)\t/* 320009 */\n/**\n * @hideinitializer\n * Received no response from STUN server\n */\n#define PJLIB_UTIL_ESTUNNOTRESPOND  (PJLIB_UTIL_ERRNO_START+10)\t/* 320010 */\n/**\n * @hideinitializer\n * Symetric NAT detected by STUN\n */\n#define PJLIB_UTIL_ESTUNSYMMETRIC   (PJLIB_UTIL_ERRNO_START+11)\t/* 320011 */\n/**\n * @hideinitializer\n * Invalid STUN magic value\n */\n#define PJLIB_UTIL_ESTUNNOTMAGIC    (PJLIB_UTIL_ERRNO_START+12)\t/* 320012 */\n/**\n * @hideinitializer\n * Invalid STUN fingerprint value\n */\n#define PJLIB_UTIL_ESTUNFINGERPRINT (PJLIB_UTIL_ERRNO_START+13)\t/* 320013 */\n\n\n\n/************************************************************\n * XML ERROR\n ***********************************************************/\n/**\n * @hideinitializer\n * General invalid XML message.\n */\n#define PJLIB_UTIL_EINXML\t    (PJLIB_UTIL_ERRNO_START+20)\t/* 320020 */\n\n\n/************************************************************\n * JSON ERROR\n ***********************************************************/\n/**\n * @hideinitializer\n * General invalid JSON message.\n */\n#define PJLIB_UTIL_EINJSON\t    (PJLIB_UTIL_ERRNO_START+30)\t/* 320030 */\n\n\n/************************************************************\n * DNS ERROR\n ***********************************************************/\n/**\n * @hideinitializer\n * DNS query packet buffer is too small.\n * This error occurs when the user supplied buffer for creating DNS\n * query (#pj_dns_make_query() function) is too small.\n */\n#define PJLIB_UTIL_EDNSQRYTOOSMALL  (PJLIB_UTIL_ERRNO_START+40)\t/* 320040 */\n/**\n * @hideinitializer\n * Invalid DNS packet length.\n * This error occurs when the received DNS response packet does not\n * match all the fields length.\n */\n#define PJLIB_UTIL_EDNSINSIZE\t    (PJLIB_UTIL_ERRNO_START+41)\t/* 320041 */\n/**\n * @hideinitializer\n * Invalid DNS class.\n * This error occurs when the received DNS response contains network\n * class other than IN (Internet).\n */\n#define PJLIB_UTIL_EDNSINCLASS\t    (PJLIB_UTIL_ERRNO_START+42)\t/* 320042 */\n/**\n * @hideinitializer\n * Invalid DNS name pointer.\n * This error occurs when parsing the compressed names inside DNS\n * response packet, when the name pointer points to an invalid address\n * or the parsing has triggerred too much recursion.\n */\n#define PJLIB_UTIL_EDNSINNAMEPTR    (PJLIB_UTIL_ERRNO_START+43)\t/* 320043 */\n/**\n * @hideinitializer\n * Invalid DNS nameserver address. If hostname was specified for nameserver\n * address, this error means that the function was unable to resolve\n * the nameserver hostname.\n */\n#define PJLIB_UTIL_EDNSINNSADDR\t    (PJLIB_UTIL_ERRNO_START+44)\t/* 320044 */\n/**\n * @hideinitializer\n * No nameserver is in DNS resolver. No nameserver is configured in the \n * resolver.\n */\n#define PJLIB_UTIL_EDNSNONS\t    (PJLIB_UTIL_ERRNO_START+45)\t/* 320045 */\n/**\n * @hideinitializer\n * No working DNS nameserver. All nameservers have been queried,\n * but none was able to serve any DNS requests. These \"bad\" nameservers\n * will be re-tested again for \"goodness\" after some period.\n */\n#define PJLIB_UTIL_EDNSNOWORKINGNS  (PJLIB_UTIL_ERRNO_START+46)\t/* 320046 */\n/**\n * @hideinitializer\n * No answer record in the DNS response.\n */\n#define PJLIB_UTIL_EDNSNOANSWERREC  (PJLIB_UTIL_ERRNO_START+47)\t/* 320047 */\n/**\n * @hideinitializer\n * Invalid DNS answer. This error is raised for example when the DNS\n * answer does not have a query section, or the type of RR in the answer\n * doesn't match the query.\n */\n#define PJLIB_UTIL_EDNSINANSWER\t    (PJLIB_UTIL_ERRNO_START+48)\t/* 320048 */\n\n\n/* DNS ERRORS MAPPED FROM RCODE: */\n\n/**\n * Start of error code mapped from DNS RCODE\n */\n#define PJLIB_UTIL_DNS_RCODE_START  (PJLIB_UTIL_ERRNO_START+50)\t/* 320050 */\n\n/**\n * Map DNS RCODE status into pj_status_t.\n */\n#define PJ_STATUS_FROM_DNS_RCODE(rcode)\t(rcode==0 ? PJ_SUCCESS : \\\n\t\t\t\t\t PJLIB_UTIL_DNS_RCODE_START+rcode)\n/**\n * @hideinitializer\n * Format error - The name server was unable to interpret the query.\n * This corresponds to DNS RCODE 1.\n */\n#define PJLIB_UTIL_EDNS_FORMERR\t    PJ_STATUS_FROM_DNS_RCODE(1)\t/* 320051 */\n/**\n * @hideinitializer\n * Server failure - The name server was unable to process this query due to a\n * problem with the name server.\n * This corresponds to DNS RCODE 2.\n */\n#define PJLIB_UTIL_EDNS_SERVFAIL    PJ_STATUS_FROM_DNS_RCODE(2)\t/* 320052 */\n/**\n * @hideinitializer\n * Name Error - Meaningful only for responses from an authoritative name\n * server, this code signifies that the domain name referenced in the query \n * does not exist.\n * This corresponds to DNS RCODE 3.\n */\n#define PJLIB_UTIL_EDNS_NXDOMAIN    PJ_STATUS_FROM_DNS_RCODE(3)\t/* 320053 */\n/**\n * @hideinitializer\n * Not Implemented - The name server does not support the requested kind of \n * query.\n * This corresponds to DNS RCODE 4.\n */\n#define PJLIB_UTIL_EDNS_NOTIMPL    PJ_STATUS_FROM_DNS_RCODE(4)\t/* 320054 */\n/**\n * @hideinitializer\n * Refused - The name server refuses to perform the specified operation for\n * policy reasons.\n * This corresponds to DNS RCODE 5.\n */\n#define PJLIB_UTIL_EDNS_REFUSED\t    PJ_STATUS_FROM_DNS_RCODE(5)\t/* 320055 */\n/**\n * @hideinitializer\n * The name exists.\n * This corresponds to DNS RCODE 6.\n */\n#define PJLIB_UTIL_EDNS_YXDOMAIN    PJ_STATUS_FROM_DNS_RCODE(6)\t/* 320056 */\n/**\n * @hideinitializer\n * The RRset (name, type) exists.\n * This corresponds to DNS RCODE 7.\n */\n#define PJLIB_UTIL_EDNS_YXRRSET\t    PJ_STATUS_FROM_DNS_RCODE(7)\t/* 320057 */\n/**\n * @hideinitializer\n * The RRset (name, type) does not exist.\n * This corresponds to DNS RCODE 8.\n */\n#define PJLIB_UTIL_EDNS_NXRRSET\t    PJ_STATUS_FROM_DNS_RCODE(8)\t/* 320058 */\n/**\n * @hideinitializer\n * The requestor is not authorized to perform this operation.\n * This corresponds to DNS RCODE 9.\n */\n#define PJLIB_UTIL_EDNS_NOTAUTH\t    PJ_STATUS_FROM_DNS_RCODE(9)\t/* 320059 */\n/**\n * @hideinitializer\n * The zone specified is not a zone.\n * This corresponds to DNS RCODE 10.\n */\n#define PJLIB_UTIL_EDNS_NOTZONE\t    PJ_STATUS_FROM_DNS_RCODE(10)/* 320060 */\n\n\n/************************************************************\n * NEW STUN ERROR\n ***********************************************************/\n/* Messaging errors */\n/**\n * @hideinitializer\n * Too many STUN attributes.\n */\n#define PJLIB_UTIL_ESTUNTOOMANYATTR (PJLIB_UTIL_ERRNO_START+110)/* 320110 */\n/**\n * @hideinitializer\n * Unknown STUN attribute. This error happens when the decoder encounters\n * mandatory attribute type which it doesn't understand.\n */\n#define PJLIB_UTIL_ESTUNUNKNOWNATTR (PJLIB_UTIL_ERRNO_START+111)/* 320111 */\n/**\n * @hideinitializer\n * Invalid STUN socket address length.\n */\n#define PJLIB_UTIL_ESTUNINADDRLEN   (PJLIB_UTIL_ERRNO_START+112)/* 320112 */\n/**\n * @hideinitializer\n * STUN IPv6 attribute not supported\n */\n#define PJLIB_UTIL_ESTUNIPV6NOTSUPP (PJLIB_UTIL_ERRNO_START+113)/* 320113 */\n/**\n * @hideinitializer\n * Expecting STUN response message.\n */\n#define PJLIB_UTIL_ESTUNNOTRESPONSE (PJLIB_UTIL_ERRNO_START+114)/* 320114 */\n/**\n * @hideinitializer\n * STUN transaction ID mismatch.\n */\n#define PJLIB_UTIL_ESTUNINVALIDID   (PJLIB_UTIL_ERRNO_START+115)/* 320115 */\n/**\n * @hideinitializer\n * Unable to find handler for the request.\n */\n#define PJLIB_UTIL_ESTUNNOHANDLER   (PJLIB_UTIL_ERRNO_START+116)/* 320116 */\n/**\n * @hideinitializer\n * Found non-FINGERPRINT attribute after MESSAGE-INTEGRITY. This is not\n * valid since MESSAGE-INTEGRITY MUST be the last attribute or the\n * attribute right before FINGERPRINT before the message.\n */\n#define PJLIB_UTIL_ESTUNMSGINTPOS    (PJLIB_UTIL_ERRNO_START+118)/* 320118 */\n/**\n * @hideinitializer\n * Found attribute after FINGERPRINT. This is not valid since FINGERPRINT\n * MUST be the last attribute in the message.\n */\n#define PJLIB_UTIL_ESTUNFINGERPOS   (PJLIB_UTIL_ERRNO_START+119)/* 320119 */\n/**\n * @hideinitializer\n * Missing STUN USERNAME attribute.\n * When credential is included in the STUN message (MESSAGE-INTEGRITY is\n * present), the USERNAME attribute must be present in the message.\n */\n#define PJLIB_UTIL_ESTUNNOUSERNAME  (PJLIB_UTIL_ERRNO_START+120)/* 320120 */\n/**\n * @hideinitializer\n * Unknown STUN username/credential.\n */\n#define PJLIB_UTIL_ESTUNUSERNAME    (PJLIB_UTIL_ERRNO_START+121)/* 320121 */\n/**\n * @hideinitializer\n * Missing/invalidSTUN MESSAGE-INTEGRITY attribute.\n */\n#define PJLIB_UTIL_ESTUNMSGINT\t    (PJLIB_UTIL_ERRNO_START+122)/* 320122 */\n/**\n * @hideinitializer\n * Found duplicate STUN attribute.\n */\n#define PJLIB_UTIL_ESTUNDUPATTR\t    (PJLIB_UTIL_ERRNO_START+123)/* 320123 */\n/**\n * @hideinitializer\n * Missing STUN REALM attribute.\n */\n#define PJLIB_UTIL_ESTUNNOREALM\t    (PJLIB_UTIL_ERRNO_START+124)/* 320124 */\n/**\n * @hideinitializer\n * Missing/stale STUN NONCE attribute value.\n */\n#define PJLIB_UTIL_ESTUNNONCE\t    (PJLIB_UTIL_ERRNO_START+125)/* 320125 */\n/**\n * @hideinitializer\n * STUN transaction terminates with failure.\n */\n#define PJLIB_UTIL_ESTUNTSXFAILED    (PJLIB_UTIL_ERRNO_START+126)/* 320126 */\n\n\n//#define PJ_STATUS_FROM_STUN_CODE(code)\t(PJLIB_UTIL_ERRNO_START+code)\n\n/************************************************************\n * HTTP Client ERROR\n ***********************************************************/\n/**\n * @hideinitializer\n * Invalid URL format\n */\n#define PJLIB_UTIL_EHTTPINURL\t    (PJLIB_UTIL_ERRNO_START+151)/* 320151 */\n/**\n * @hideinitializer\n * Invalid port number\n */\n#define PJLIB_UTIL_EHTTPINPORT\t    (PJLIB_UTIL_ERRNO_START+152)/* 320152 */\n/**\n * @hideinitializer\n * Incomplete headers received\n */\n#define PJLIB_UTIL_EHTTPINCHDR\t    (PJLIB_UTIL_ERRNO_START+153)/* 320153 */\n/**\n * @hideinitializer\n * Insufficient buffer\n */\n#define PJLIB_UTIL_EHTTPINSBUF\t    (PJLIB_UTIL_ERRNO_START+154)/* 320154 */\n/**\n * @hideinitializer\n * Connection lost\n */\n#define PJLIB_UTIL_EHTTPLOST\t    (PJLIB_UTIL_ERRNO_START+155)/* 320155 */\n\n/************************************************************\n * CLI ERROR\n ***********************************************************/\n\n/**\n * @hideinitializer\n * End the current session. This is a special error code returned by\n * pj_cli_sess_exec() to indicate that \"exit\" or equivalent command has been\n * called to end the current session.\n */\n#define PJ_CLI_EEXIT        \t    (PJLIB_UTIL_ERRNO_START+201)/* 320201 */\n/**\n * @hideinitializer\n * A required CLI argument is not specified.\n */\n#define PJ_CLI_EMISSINGARG    \t    (PJLIB_UTIL_ERRNO_START+202)/* 320202 */\n /**\n * @hideinitializer\n * Too many CLI arguments.\n */\n#define PJ_CLI_ETOOMANYARGS    \t    (PJLIB_UTIL_ERRNO_START+203)/* 320203 */\n/**\n * @hideinitializer\n * Invalid CLI argument. Typically this is caused by extra characters\n * specified in the command line which does not match any arguments.\n */\n#define PJ_CLI_EINVARG        \t    (PJLIB_UTIL_ERRNO_START+204)/* 320204 */\n/**\n * @hideinitializer\n * CLI command with the specified name already exist.\n */\n#define PJ_CLI_EBADNAME        \t    (PJLIB_UTIL_ERRNO_START+205)/* 320205 */\n/**\n * @hideinitializer\n * CLI command with the specified id already exist.\n */\n#define PJ_CLI_EBADID        \t    (PJLIB_UTIL_ERRNO_START+206)/* 320206 */\n/**\n * @hideinitializer\n * Invalid XML format for CLI command specification.\n */\n#define PJ_CLI_EBADXML        \t    (PJLIB_UTIL_ERRNO_START+207)/* 320207 */\n/**\n * @hideinitializer\n * CLI command entered by user match with more than one command/argument \n * specification.\n */\n#define PJ_CLI_EAMBIGUOUS\t    (PJLIB_UTIL_ERRNO_START+208)/* 320208 */\n/**\n * @hideinitializer\n * Telnet connection lost.\n */\n#define PJ_CLI_ETELNETLOST          (PJLIB_UTIL_ERRNO_START+211)/* 320211 */\n\n/**\n * @}\n */\n\n#endif\t/* __PJLIB_UTIL_ERRNO_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/getopt.h",
    "content": "/* $Id: getopt.h 2037 2008-06-20 21:39:02Z bennylp $ */\n/* Declarations for pj_getopt.\n   Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Library General Public License as\n   published by the Free Software Foundation; either version 2 of the\n   License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Library General Public License for more details.\n\n   You should have received a copy of the GNU Library General Public\n   License along with the GNU C Library; see the file COPYING.LIB.  If not,\n   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n   Boston, MA 02111-1307, USA.  */\n\n#ifndef __PJ_GETOPT_H__\n#define __PJ_GETOPT_H__ 1\n\n/**\n * @file getopt.h\n * @brief Compile time settings\n */\n\n/**\n * @defgroup PJLIB_UTIL_GETOPT Getopt\n * @ingroup PJLIB_TEXT\n * @{\n */\n\n#ifdef\t__cplusplus\nextern \"C\" {\n#endif\n\n/* For communication from `pj_getopt' to the caller.\n   When `pj_getopt' finds an option that takes an argument,\n   the argument value is returned here.\n   Also, when `ordering' is RETURN_IN_ORDER,\n   each non-option ARGV-element is returned here.  */\n\nextern char *pj_optarg;\n\n/* Index in ARGV of the next element to be scanned.\n   This is used for communication to and from the caller\n   and for communication between successive calls to `pj_getopt'.\n\n   On entry to `pj_getopt', zero means this is the first call; initialize.\n\n   When `pj_getopt' returns -1, this is the index of the first of the\n   non-option elements that the caller should itself scan.\n\n   Otherwise, `pj_optind' communicates from one call to the next\n   how much of ARGV has been scanned so far.  */\n\nextern int pj_optind;\n\n/* Set to an option character which was unrecognized.  */\n\nextern int pj_optopt;\n\n/* Describe the long-named options requested by the application.\n   The LONG_OPTIONS argument to pj_getopt_long or pj_getopt_long_only is a vector\n   of `struct pj_getopt_option' terminated by an element containing a name which is\n   zero.\n\n   The field `has_arg' is:\n   no_argument\t\t(or 0) if the option does not take an argument,\n   required_argument\t(or 1) if the option requires an argument,\n   optional_argument \t(or 2) if the option takes an optional argument.\n\n   If the field `flag' is not NULL, it points to a variable that is set\n   to the value given in the field `val' when the option is found, but\n   left unchanged if the option is not found.\n\n   To have a long-named option do something other than set an `int' to\n   a compiled-in constant, such as set a value from `pj_optarg', set the\n   option's `flag' field to zero and its `val' field to a nonzero\n   value (the equivalent single-letter option character, if there is\n   one).  For long options that have a zero `flag' field, `pj_getopt'\n   returns the contents of the `val' field.  */\n\nstruct pj_getopt_option\n{\n  const char *name;\n  /* has_arg can't be an enum because some compilers complain about\n     type mismatches in all the code that assumes it is an int.  */\n  int has_arg;\n  int *flag;\n  int val;\n};\n\n/* Names for the values of the `has_arg' field of `struct pj_getopt_option'.  */\n\n# define no_argument\t\t0\n# define required_argument\t1\n# define optional_argument\t2\n\n\n/* Get definitions and prototypes for functions to process the\n   arguments in ARGV (ARGC of them, minus the program name) for\n   options given in OPTS.\n\n   Return the option character from OPTS just read.  Return -1 when\n   there are no more options.  For unrecognized options, or options\n   missing arguments, `pj_optopt' is set to the option letter, and '?' is\n   returned.\n\n   The OPTS string is a list of characters which are recognized option\n   letters, optionally followed by colons, specifying that that letter\n   takes an argument, to be placed in `pj_optarg'.\n\n   If a letter in OPTS is followed by two colons, its argument is\n   optional.  This behavior is specific to the GNU `pj_getopt'.\n\n   The argument `--' causes premature termination of argument\n   scanning, explicitly telling `pj_getopt' that there are no more\n   options.\n\n   If OPTS begins with `--', then non-option arguments are treated as\n   arguments to the option '\\0'.  This behavior is specific to the GNU\n   `pj_getopt'.  */\n\nint pj_getopt (int argc, char *const *argv, const char *shortopts);\n\nint pj_getopt_long (int argc, char *const *argv, const char *options,\n\t\t        const struct pj_getopt_option *longopts, int *longind);\nint pj_getopt_long_only (int argc, char *const *argv,\n\t\t\t     const char *shortopts,\n\t\t             const struct pj_getopt_option *longopts, int *longind);\n\n\n#ifdef\t__cplusplus\n}\n#endif\n\n/**\n * @}\n */\n\n#endif /* pj_getopt.h */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/hmac_md5.h",
    "content": "/* $Id: hmac_md5.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_HMAC_MD5_H__\n#define __PJLIB_UTIL_HMAC_MD5_H__\n\n/**\n * @file hmac_md5.h\n * @brief HMAC MD5 Message Authentication\n */\n\n/**\n * @defgroup PJLIB_UTIL_ENCRYPTION Encryption Algorithms\n */\n\n#include <pj/types.h>\n#include <pjlib-util/md5.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJLIB_UTIL_HMAC_MD5 HMAC MD5 Message Authentication\n * @ingroup PJLIB_UTIL_ENCRYPTION\n * @{\n *\n * This module contains the implementation of HMAC: Keyed-Hashing \n * for Message Authentication, as described in RFC 2104\n */\n\n/**\n * The HMAC-MD5 context used in the incremental HMAC calculation.\n */\ntypedef struct pj_hmac_md5_context\n{\n    pj_md5_context  context;\t/**< MD5 context\t    */\n    pj_uint8_t\t    k_opad[64];\t/**< opad xor-ed with key   */\n} pj_hmac_md5_context;\n\n\n/**\n * Calculate HMAC MD5 digest for the specified input and key.\n *\n * @param input\t\tPointer to the input stream.\n * @param input_len\tLength of input stream in bytes.\n * @param key\t\tPointer to the authentication key.\n * @param key_len\tLength of the authentication key.\n * @param digest\tBuffer to be filled with HMAC MD5 digest.\n */\nPJ_DECL(void) pj_hmac_md5(const pj_uint8_t *input, unsigned input_len, \n\t\t\t  const pj_uint8_t *key, unsigned key_len, \n\t\t\t  pj_uint8_t digest[16]);\n\n\n/**\n * Initiate HMAC-MD5 context for incremental hashing.\n *\n * @param hctx\t\tHMAC-MD5 context.\n * @param key\t\tPointer to the authentication key.\n * @param key_len\tLength of the authentication key.\n */\nPJ_DECL(void) pj_hmac_md5_init(pj_hmac_md5_context *hctx, \n\t\t\t       const pj_uint8_t *key, unsigned key_len);\n\n/**\n * Append string to the message.\n *\n * @param hctx\t\tHMAC-MD5 context.\n * @param input\t\tPointer to the input stream.\n * @param input_len\tLength of input stream in bytes.\n */\nPJ_DECL(void) pj_hmac_md5_update(pj_hmac_md5_context *hctx,\n\t\t\t\t const pj_uint8_t *input, \n\t\t\t\t unsigned input_len);\n\n/**\n * Finish the message and return the digest. \n *\n * @param hctx\t\tHMAC-MD5 context.\n * @param digest\tBuffer to be filled with HMAC MD5 digest.\n */\nPJ_DECL(void) pj_hmac_md5_final(pj_hmac_md5_context *hctx,\n\t\t\t\tpj_uint8_t digest[16]);\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJLIB_UTIL_HMAC_MD5_H__ */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/hmac_sha1.h",
    "content": "/* $Id: hmac_sha1.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_HMAC_SHA1_H__\n#define __PJLIB_UTIL_HMAC_SHA1_H__\n\n/**\n * @file hmac_sha1.h\n * @brief HMAC SHA1 Message Authentication\n */\n\n#include <pj/types.h>\n#include <pjlib-util/sha1.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJLIB_UTIL_HMAC_SHA1 HMAC SHA1 Message Authentication\n * @ingroup PJLIB_UTIL_ENCRYPTION\n * @{\n *\n * This module contains the implementation of HMAC: Keyed-Hashing \n * for Message Authentication, as described in RFC 2104.\n */\n\n/**\n * The HMAC-SHA1 context used in the incremental HMAC calculation.\n */\ntypedef struct pj_hmac_sha1_context\n{\n    pj_sha1_context context;\t/**< SHA1 context\t    */\n    pj_uint8_t\t    k_opad[64];\t/**< opad xor-ed with key   */\n} pj_hmac_sha1_context;\n\n\n/**\n * Calculate HMAC-SHA1 digest for the specified input and key with this\n * single function call.\n *\n * @param input\t\tPointer to the input stream.\n * @param input_len\tLength of input stream in bytes.\n * @param key\t\tPointer to the authentication key.\n * @param key_len\tLength of the authentication key.\n * @param digest\tBuffer to be filled with HMAC SHA1 digest.\n */\nPJ_DECL(void) pj_hmac_sha1(const pj_uint8_t *input, unsigned input_len, \n\t\t\t   const pj_uint8_t *key, unsigned key_len, \n\t\t\t   pj_uint8_t digest[20]);\n\n\n/**\n * Initiate HMAC-SHA1 context for incremental hashing.\n *\n * @param hctx\t\tHMAC-SHA1 context.\n * @param key\t\tPointer to the authentication key.\n * @param key_len\tLength of the authentication key.\n */\nPJ_DECL(void) pj_hmac_sha1_init(pj_hmac_sha1_context *hctx, \n\t\t\t        const pj_uint8_t *key, unsigned key_len);\n\n/**\n * Append string to the message.\n *\n * @param hctx\t\tHMAC-SHA1 context.\n * @param input\t\tPointer to the input stream.\n * @param input_len\tLength of input stream in bytes.\n */\nPJ_DECL(void) pj_hmac_sha1_update(pj_hmac_sha1_context *hctx,\n\t\t\t\t  const pj_uint8_t *input, \n\t\t\t\t  unsigned input_len);\n\n/**\n * Finish the message and return the digest. \n *\n * @param hctx\t\tHMAC-SHA1 context.\n * @param digest\tBuffer to be filled with HMAC SHA1 digest.\n */\nPJ_DECL(void) pj_hmac_sha1_final(pj_hmac_sha1_context *hctx,\n\t\t\t\t pj_uint8_t digest[20]);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJLIB_UTIL_HMAC_SHA1_H__ */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/http_client.h",
    "content": "/* $Id: http_client.h 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_HTTP_CLIENT_H__\n#define __PJLIB_UTIL_HTTP_CLIENT_H__\n\n/**\n * @file http_client.h\n * @brief Simple HTTP Client\n */\n#include <pj/activesock.h>\n#include <pjlib-util/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_HTTP_CLIENT Simple HTTP Client\n * @ingroup PJ_PROTOCOLS\n * @{\n * This contains a simple HTTP client implementation.\n * Some known limitations: \n * - Does not support chunked Transfer-Encoding.\n */\n\n/**\n * This opaque structure describes the http request.\n */\ntypedef struct pj_http_req pj_http_req;\n\n/**\n * Defines the maximum number of elements in a pj_http_headers\n * structure.\n */\n#define PJ_HTTP_HEADER_SIZE 32\n\n/**\n * HTTP header representation.\n */\ntypedef struct pj_http_header_elmt\n{\n    pj_str_t name;\t/**< Header name */\n    pj_str_t value;\t/**< Header value */\n} pj_http_header_elmt;\n\n/**\n * This structure describes http request/response headers.\n * Application should call #pj_http_headers_add_elmt() to\n * add a header field.\n */\ntypedef struct pj_http_headers\n{\n    /**< Number of header fields */\n    unsigned     count;\n\n    /** Header elements/fields */\n    pj_http_header_elmt header[PJ_HTTP_HEADER_SIZE];\n} pj_http_headers;\n\n/**\n * Structure to save HTTP authentication credential.\n */\ntypedef struct pj_http_auth_cred\n{\n    /**\n     * Specify specific authentication schemes to be responded. Valid values\n     * are \"basic\" and \"digest\". If this field is not set, any authentication\n     * schemes will be responded.\n     *\n     * Default is empty.\n     */\n    pj_str_t\tscheme;\n\n    /**\n     * Specify specific authentication realm to be responded. If this field\n     * is set, only 401/407 response with matching realm will be responded.\n     * If this field is not set, any realms will be responded.\n     *\n     * Default is empty.\n     */\n    pj_str_t\trealm;\n\n    /**\n     * Specify authentication username.\n     *\n     * Default is empty.\n     */\n    pj_str_t\tusername;\n\n    /**\n     * The type of password in \\a data field. Currently only 0 is\n     * supported, meaning the \\a data contains plain-text password.\n     *\n     * Default is 0.\n     */\n    unsigned\tdata_type;\n\n    /**\n     * Specify authentication password. The encoding of the password depends\n     * on the value of \\a data_type field above.\n     *\n     * Default is empty.\n     */\n    pj_str_t\tdata;\n\n} pj_http_auth_cred;\n\n\n/**\n * Parameters that can be given during http request creation. Application\n * must initialize this structure with #pj_http_req_param_default().\n */\ntypedef struct pj_http_req_param \n{\n    /** \n     * The address family of the URL.\n     *  Default is pj_AF_INET().\n     */\n    int             addr_family;\n\n    /** \n     * The HTTP request method.\n     * Default is GET.\n     */\n    pj_str_t        method;\n\n    /** \n     * The HTTP protocol version (\"1.0\" or \"1.1\").\n     * Default is \"1.0\".\n     */\n    pj_str_t        version;\n\n    /** \n     * HTTP request operation timeout.\n     * Default is PJ_HTTP_DEFAULT_TIMEOUT.\n     */\n    pj_time_val     timeout;\n\n    /** \n     * User-defined data.\n     * Default is NULL.\n     */\n    void            *user_data;\n\n    /** \n     * HTTP request headers.\n     * Default is empty.\n     */\n    pj_http_headers headers;\n\n    /**\n      * This structure describes the http request body. If application\n      * specifies the data to send, the data must remain valid until \n      * the HTTP request is sent. Alternatively, application can choose\n      * to specify total_size as the total data size to send instead\n      * while leaving the data NULL (and its size 0). In this case,\n      * HTTP request will then call on_send_data() callback once it is \n      * ready to send the request body. This will be useful if \n      * application does not wish to load the data into the buffer at \n      * once.\n      * \n      * Default is empty.\n      */\n    struct pj_http_reqdata\n    {\n        void       *data;          /**< Request body data */\n        pj_size_t  size;           /**< Request body size */\n        pj_size_t  total_size;     /**< If total_size > 0, data */\n                                   /**< will be provided later  */\n    } reqdata;\n\n    /**\n     * Authentication credential needed to respond to 401/407 response.\n     */\n    pj_http_auth_cred\tauth_cred;\n\n    /**\n     * Optional source port range to use when binding the socket.\n     * This can be used if the source port needs to be within a certain range\n     * for instance due to strict firewall settings. The port used will be\n     * randomized within the range.\n     *\n     * Note that if authentication is configured, the authentication response\n     * will be a new transaction\n     *\n     * Default is 0 (The OS will select the source port automatically)\n     */\n    pj_uint16_t\t\tsource_port_range_start;\n\n    /**\n     * Optional source port range to use when binding.\n     * The size of the port restriction range\n     *\n     * Default is 0 (The OS will select the source port automatically))\n     */\n    pj_uint16_t\t\tsource_port_range_size;\n\n    /**\n     * Max number of retries if binding to a port fails.\n     * Note that this does not adress the scenario where a request times out\n     * or errors. This needs to be taken care of by the on_complete callback.\n     *\n     * Default is 3\n     */\n    pj_uint16_t\t\tmax_retries;\n\n} pj_http_req_param;\n\n/**\n * HTTP authentication challenge, parsed from WWW-Authenticate header.\n */\ntypedef struct pj_http_auth_chal\n{\n    pj_str_t\tscheme;\t\t/**< Auth scheme.\t\t*/\n    pj_str_t\trealm;\t\t/**< Realm for the challenge.\t*/\n    pj_str_t\tdomain;\t\t/**< Domain.\t\t\t*/\n    pj_str_t\tnonce;\t\t/**< Nonce challenge.\t\t*/\n    pj_str_t\topaque;\t\t/**< Opaque value.\t\t*/\n    int\t\tstale;\t\t/**< Stale parameter.\t\t*/\n    pj_str_t\talgorithm;\t/**< Algorithm parameter.\t*/\n    pj_str_t\tqop;\t\t/**< Quality of protection.\t*/\n} pj_http_auth_chal;\n\n/**\n * This structure describes HTTP response.\n */\ntypedef struct pj_http_resp\n{\n    pj_str_t        version;        /**< HTTP version of the server */\n    pj_uint16_t     status_code;    /**< Status code of the request */\n    pj_str_t        reason;         /**< Reason phrase */\n    pj_http_headers headers;        /**< Response headers */\n    pj_http_auth_chal auth_chal;    /**< Parsed WWW-Authenticate header, if\n\t\t\t\t         any. */\n    pj_int32_t      content_length; /**< The value of content-length header\n\t\t\t\t\t field. -1 if not specified. */\n    void            *data;          /**< Data received */\n    pj_size_t       size;           /**< Data size */\n} pj_http_resp;\n\n/**\n * This structure describes HTTP URL.\n */\ntypedef struct pj_http_url\n{\n    pj_str_t\tusername;\t    /**< Username part */\n    pj_str_t\tpasswd;\t\t    /**< Password part */\n    pj_str_t    protocol;           /**< Protocol used */\n    pj_str_t    host;               /**< Host name */\n    pj_uint16_t port;               /**< Port number */\n    pj_str_t    path;               /**< Path */\n} pj_http_url;\n\n/**\n * This structure describes the callbacks to be called by the HTTP request.\n */\ntypedef struct pj_http_req_callback\n{\n    /**\n     * This callback is called when a complete HTTP response header \n     * is received.\n     *\n     * @param http_req\tThe http request.\n     * @param resp\tThe response of the request.\n     */\n    void (*on_response)(pj_http_req *http_req, const pj_http_resp *resp);\n\n    /**\n     * This callback is called when the HTTP request is ready to send\n     * its request body. Application may wish to use this callback if\n     * it wishes to load the data at a later time or if it does not \n     * wish to load the whole data into memory. In order for this\n     * callback to be called, application MUST set http_req_param.total_size\n     * to a value greater than 0.\n     *\n     * @param http_req\tThe http request.\n     * @param data\tPointer to the data that will be sent. Application\n     *                  must set the pointer to the current data chunk/segment\n     *                  to be sent. Data must remain valid until the next \n     *                  on_send_data() callback or for the last segment,\n     *                  until it is sent.\n     * @param size\tPointer to the data size that will be sent.\n     */\n    void (*on_send_data)(pj_http_req *http_req,\n                         void **data, pj_size_t *size);\n\n    /**\n     * This callback is called when a segment of response body data\n     * arrives. If this callback is specified (i.e. not NULL), the\n     * on_complete() callback will be called with zero-length data\n     * (within the response parameter), hence the application must \n     * store and manage its own data buffer, otherwise the \n     * on_complete() callback will be called with the response \n     * parameter containing the complete data. \n     * \n     * @param http_req\tThe http request.\n     * @param data\tThe buffer containing the data.\n     * @param size\tThe length of data in the buffer.\n     */\n    void (*on_data_read)(pj_http_req *http_req,\n                         void *data, pj_size_t size);\n\n    /**\n     * This callback is called when the HTTP request is completed.\n     * If the callback on_data_read() is specified, the variable\n     * response->data will be set to NULL, otherwise it will\n     * contain the complete data. Response data is allocated from\n     * pj_http_req's internal memory pool so the data remain valid\n     * as long as pj_http_req is not destroyed and application does\n     * not start a new request.\n     *\n     * If no longer required, application may choose to destroy \n     * pj_http_req immediately by calling #pj_http_req_destroy() inside \n     * the callback.\n     *\n     * @param http_req\tThe http request.\n     * @param status\tThe status of the request operation. PJ_SUCCESS\n     *                  if the operation completed successfully\n     *                  (connection-wise). To check the server's \n     *                  status-code response to the HTTP request, \n     *                  application should check resp->status_code instead.\n     * @param resp\tThe response of the corresponding request. If \n     *\t\t\tthe status argument is non-PJ_SUCCESS, this \n     *\t\t\targument will be set to NULL.\n     */\n    void (*on_complete)(pj_http_req *http_req,\n                        pj_status_t status,\n                        const pj_http_resp *resp);\n\n} pj_http_req_callback;\n\n\n/**\n * Initialize the http request parameters with the default values.\n *\n * @param param\t\tThe parameter to be initialized.\n */\nPJ_DECL(void) pj_http_req_param_default(pj_http_req_param *param);\n\n/**\n * Add a header element/field. Application MUST make sure that \n * name and val pointer remains valid until the HTTP request is sent.\n *\n * @param headers\tThe headers.\n * @param name\t        The header field name.\n * @param value\t        The header field value.\n *\n * @return\t        PJ_SUCCESS if the operation has been successful,\n *\t\t        or the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_http_headers_add_elmt(pj_http_headers *headers, \n                                              pj_str_t *name, \n                                              pj_str_t *val);\n\n/** \n * The same as #pj_http_headers_add_elmt() with char * as\n * its parameters. Application MUST make sure that name and val pointer \n * remains valid until the HTTP request is sent.\n *\n * @param headers\tThe headers.\n * @param name\t        The header field name.\n * @param value\t        The header field value.\n *\n * @return\t        PJ_SUCCESS if the operation has been successful,\n *\t\t        or the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_http_headers_add_elmt2(pj_http_headers *headers, \n                                               char *name, char *val);\n\n/**\n * Parse a http URL into its components.\n *\n * @param url\t        The URL to be parsed.\n * @param hurl\t        Pointer to receive the parsed result.\n *\n * @return\t        PJ_SUCCESS if the operation has been successful,\n *\t\t        or the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_http_req_parse_url(const pj_str_t *url, \n                                           pj_http_url *hurl);\n\n/**\n * Create the HTTP request.\n *\n * @param pool\t\tPool to use. HTTP request will use the pool's factory\n *                      to allocate its own memory pool.\n * @param url\t\tHTTP URL request.\n * @param timer\t        The timer to use.\n * @param ioqueue\tThe ioqueue to use.\n * @param param\t\tOptional parameters. When this parameter is not \n *                      specifed (NULL), the default values will be used.\n * @param hcb\t\tPointer to structure containing application\n *\t\t\tcallbacks.\n * @param http_req\tPointer to receive the http request instance.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_http_req_create(pj_pool_t *pool,\n                                        const pj_str_t *url,\n\t\t\t\t\tpj_timer_heap_t *timer,\n\t\t\t\t\tpj_ioqueue_t *ioqueue,\n                                        const pj_http_req_param *param,\n                                        const pj_http_req_callback *hcb,\n                                        pj_http_req **http_req);\n\n/**\n * Set the timeout of the HTTP request operation. Note that if the \n * HTTP request is currently running, the timeout will only affect \n * subsequent request operations.\n *\n * @param http_req  The http request.\n * @param timeout   Timeout value for HTTP request operation.\n */\nPJ_DECL(void) pj_http_req_set_timeout(pj_http_req *http_req,\n                                      const pj_time_val* timeout);\n\n/**\n * Starts an asynchronous HTTP request to the URL specified.\n *\n * @param http_req  The http request.\n *\n * @return\n *  - PJ_SUCCESS    if success\n *  - non-zero      which indicates the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_http_req_start(pj_http_req *http_req);\n\n/**\n * Cancel the asynchronous HTTP request. \n *\n * @param http_req  The http request.\n * @param notify    If non-zero, the on_complete() callback will be \n *                  called with status PJ_ECANCELLED to notify that \n *                  the query has been cancelled.\n *\n * @return\n *  - PJ_SUCCESS    if success\n *  - non-zero      which indicates the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_http_req_cancel(pj_http_req *http_req,\n                                        pj_bool_t notify);\n\n/**\n * Destroy the http request.\n *\n * @param http_req\tThe http request to be destroyed.\n *\n * @return              PJ_SUCCESS if success.\n */\nPJ_DECL(pj_status_t) pj_http_req_destroy(pj_http_req *http_req);\n\n/**\n * Find out whether the http request is running.\n *\n * @param http_req      The http request.\n *\n * @return\t        PJ_TRUE if a request is pending, or\n *\t\t        PJ_FALSE if idle\n */\nPJ_DECL(pj_bool_t) pj_http_req_is_running(const pj_http_req *http_req);\n\n/**\n * Retrieve the user data previously associated with this http\n * request.\n *\n * @param http_req  The http request.\n *\n * @return\t    The user data.\n */\nPJ_DECL(void *) pj_http_req_get_user_data(pj_http_req *http_req);\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJLIB_UTIL_HTTP_CLIENT_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/json.h",
    "content": "/* $Id$ */\n/*\n * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef __PJLIB_UTIL_JSON_H__\n#define __PJLIB_UTIL_JSON_H__\n\n\n/**\n * @file json.h\n * @brief PJLIB JSON Implementation\n */\n\n#include <pj/types.h>\n#include <pj/list.h>\n#include <pj/pool.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_JSON JSON Writer and Loader\n * @ingroup PJ_FILE_FMT\n * @{\n * This API implements JSON file format according to RFC 4627. It can be used\n * to parse, write, and manipulate JSON documents.\n */\n\n/**\n * Type of JSON value.\n */\ntypedef enum pj_json_val_type\n{\n    PJ_JSON_VAL_NULL,\t\t/**< Null value (null)\t\t\t*/\n    PJ_JSON_VAL_BOOL,\t\t/**< Boolean value (true, false)\t*/\n    PJ_JSON_VAL_NUMBER,\t\t/**< Numeric (float or fixed point)\t*/\n    PJ_JSON_VAL_STRING,\t\t/**< Literal string value.\t\t*/\n    PJ_JSON_VAL_ARRAY,\t\t/**< Array\t\t\t\t*/\n    PJ_JSON_VAL_OBJ\t\t/**< Object.\t\t\t\t*/\n} pj_json_val_type;\n\n/* Forward declaration for JSON element */\ntypedef struct pj_json_elem pj_json_elem;\n\n/**\n * JSON list to store child elements.\n */\ntypedef struct pj_json_list\n{\n    PJ_DECL_LIST_MEMBER(pj_json_elem);\n} pj_json_list;\n\n/**\n * This represents JSON element. A JSON element is basically a name/value\n * pair, where the name is a string and the value can be one of null, boolean\n * (true and false constants), number, string, array (containing zero or more\n * elements), or object. An object can be viewed as C struct, that is a\n * compound element containing other elements, each having name/value pair.\n */\nstruct pj_json_elem\n{\n    PJ_DECL_LIST_MEMBER(pj_json_elem);\n    pj_str_t\t\tname;\t\t/**< ELement name.\t\t*/\n    pj_json_val_type\ttype;\t\t/**< Element type.\t\t*/\n    union\n    {\n\tpj_bool_t\tis_true;\t/**< Boolean value.\t\t*/\n\tfloat\t\tnum;\t\t/**< Number value.\t\t*/\n\tpj_str_t\tstr;\t\t/**< String value.\t\t*/\n\tpj_json_list\tchildren;\t/**< Object and array children\t*/\n    } value;\t\t\t\t/**< Element value.\t\t*/\n};\n\n/**\n * Structure to be specified to pj_json_parse() to be filled with additional\n * info when parsing failed.\n */\ntypedef struct pj_json_err_info\n{\n    unsigned\tline;\t\t/**< Line location of the error\t\t*/\n    unsigned\tcol;\t\t/**< Column location of the error\t*/\n    int\t\terr_char;\t/**< The offending character.\t\t*/\n} pj_json_err_info;\n\n/**\n * Type of function callback to write JSON document in pj_json_writef().\n *\n * @param s\t\tThe string to be written to the document.\n * @param size\t\tThe length of the string\n * @param user_data\tUser data that was specified to pj_json_writef()\n *\n * @return\t\tIf the callback returns non-PJ_SUCCESS, it will\n * \t\t\tstop the pj_json_writef() function and this error\n * \t\t\twill be returned to caller.\n */\ntypedef pj_status_t (*pj_json_writer)(const char *s,\n\t\t\t\t      unsigned size,\n\t\t\t\t      void *user_data);\n\n/**\n * Initialize null element.\n *\n * @param el\t\tThe element.\n * @param name\t\tName to be given to the element, or NULL.\n */\nPJ_DECL(void) pj_json_elem_null(pj_json_elem *el, pj_str_t *name);\n\n/**\n * Initialize boolean element with the specified value.\n *\n * @param el\t\tThe element.\n * @param name\t\tName to be given to the element, or NULL.\n * @param val\t\tThe value.\n */\nPJ_DECL(void) pj_json_elem_bool(pj_json_elem *el, pj_str_t *name,\n                                pj_bool_t val);\n\n/**\n * Initialize number element with the specified value.\n *\n * @param el\t\tThe element.\n * @param name\t\tName to be given to the element, or NULL.\n * @param val\t\tThe value.\n */\nPJ_DECL(void) pj_json_elem_number(pj_json_elem *el, pj_str_t *name,\n                                  float val);\n\n/**\n * Initialize string element with the specified value.\n *\n * @param el\t\tThe element.\n * @param name\t\tName to be given to the element, or NULL.\n * @param val\t\tThe value.\n */\nPJ_DECL(void) pj_json_elem_string(pj_json_elem *el, pj_str_t *name,\n                                  pj_str_t *val);\n\n/**\n * Initialize element as an empty array\n *\n * @param el\t\tThe element.\n * @param name\t\tName to be given to the element, or NULL.\n */\nPJ_DECL(void) pj_json_elem_array(pj_json_elem *el, pj_str_t *name);\n\n/**\n * Initialize element as an empty object\n *\n * @param el\t\tThe element.\n * @param name\t\tName to be given to the element, or NULL.\n */\nPJ_DECL(void) pj_json_elem_obj(pj_json_elem *el, pj_str_t *name);\n\n/**\n * Add an element to an object or array.\n *\n * @param el\t\tThe object or array element.\n * @param child\t\tElement to be added to the object or array.\n */\nPJ_DECL(void) pj_json_elem_add(pj_json_elem *el, pj_json_elem *child);\n\n/**\n * Parse a JSON document in the buffer. The buffer MUST be NULL terminated,\n * or if not then it must have enough size to put the NULL character.\n *\n * @param pool\t\tThe pool to allocate memory for creating elements.\n * @param buffer\tString buffer containing JSON document.\n * @param size\t\tSize of the document.\n * @param err_info\tOptional structure to be filled with info when\n * \t\t\tparsing failed.\n *\n * @return\t\tThe root element from the document.\n */\nPJ_DECL(pj_json_elem*) pj_json_parse(pj_pool_t *pool,\n                                     char *buffer,\n                                     unsigned *size,\n                                     pj_json_err_info *err_info);\n\n/**\n * Write the specified element to the string buffer.\n *\n * @param elem\t\tThe element to be written.\n * @param buffer\tOutput buffer.\n * @param size\t\tOn input, it must be set to the size of the buffer.\n * \t\t\tUpon successful return, this will be set to\n * \t\t\tthe length of the written string.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error.\n */\nPJ_DECL(pj_status_t)   pj_json_write(const pj_json_elem *elem,\n                                     char *buffer, unsigned *size);\n\n/**\n * Incrementally write the element to arbitrary medium using the specified\n * callback to write the document chunks.\n *\n * @param elem\t\tThe element to be written.\n * @param writer\tCallback function which will be called to write\n * \t\t\ttext chunks.\n * @param user_data\tArbitrary user data which will be given back when\n * \t\t\tcalling the callback.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error.\n */\nPJ_DECL(pj_status_t)   pj_json_writef(const pj_json_elem *elem,\n                                      pj_json_writer writer,\n                                      void *user_data);\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJLIB_UTIL_JSON_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/md5.h",
    "content": "/* $Id: md5.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_MD5_H__\n#define __PJLIB_UTIL_MD5_H__\n\n/**\n * @file md5.h\n * @brief MD5 Functions\n */\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJLIB_UTIL_MD5 MD5\n * @ingroup PJLIB_UTIL_ENCRYPTION\n * @{\n */\n\n\n/** MD5 context. */\ntypedef struct pj_md5_context\n{\n\tpj_uint32_t buf[4];\t/**< buf    */\n\tpj_uint32_t bits[2];\t/**< bits   */\n\tpj_uint8_t  in[64];\t/**< in\t    */\n} pj_md5_context;\n\n/** Initialize the algorithm. \n *  @param pms\t\tMD5 context.\n */\nPJ_DECL(void) pj_md5_init(pj_md5_context *pms);\n\n/** Append a string to the message. \n *  @param pms\t\tMD5 context.\n *  @param data\t\tData.\n *  @param nbytes\tLength of data.\n */\nPJ_DECL(void) pj_md5_update( pj_md5_context *pms, \n\t\t\t     const pj_uint8_t *data, unsigned nbytes);\n\n/** Finish the message and return the digest. \n *  @param pms\t\tMD5 context.\n *  @param digest\t16 byte digest.\n */\nPJ_DECL(void) pj_md5_final(pj_md5_context *pms, pj_uint8_t digest[16]);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJLIB_UTIL_MD5_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/pcap.h",
    "content": "/* $Id: pcap.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_PCAP_H__\n#define __PJLIB_UTIL_PCAP_H__\n\n/**\n * @file pcap.h\n * @brief Simple PCAP file reader\n */\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_PCAP Simple PCAP file reader\n * @ingroup PJ_FILE_FMT\n * @{\n * This module describes simple utility to read PCAP file. It is not intended\n * to support all PCAP features (that's what libpcap is for!), but it can\n * be useful for example to playback or stream PCAP contents.\n */\n\n/**\n * Enumeration to describe supported data link types.\n */\ntypedef enum pj_pcap_link_type\n{\n    /** Ethernet data link */\n    PJ_PCAP_LINK_TYPE_ETH   = 1\n\n} pj_pcap_link_type;\n\n\n/**\n * Enumeration to describe supported protocol types.\n */\ntypedef enum pj_pcap_proto_type\n{\n    /** UDP protocol */\n    PJ_PCAP_PROTO_TYPE_UDP  = 17\n\n} pj_pcap_proto_type;\n\n\n/**\n * This describes UDP header, which may optionally be returned in\n * #pj_pcap_read_udp() function. All fields are in network byte order.\n */\ntypedef struct pj_pcap_udp_hdr\n{\n    pj_uint16_t\tsrc_port;   /**< Source port.\t    */\n    pj_uint16_t\tdst_port;   /**< Destination port   */\n    pj_uint16_t\tlen;\t    /**< Length.\t    */\n    pj_uint16_t\tcsum;\t    /**< Checksum.\t    */\n} pj_pcap_udp_hdr;\n\n\n/**\n * This structure describes the filter to be used when reading packets from\n * a PCAP file. When a filter is configured, only packets matching all the\n * filter specifications will be read from PCAP file.\n */\ntypedef struct pj_pcap_filter\n{\n    /**\n     * Select data link type, or zero to include any supported data links.\n     */\n    pj_pcap_link_type\tlink;\n\n    /**\n     * Select protocol, or zero to include all supported protocols.\n     */\n    pj_pcap_proto_type\tproto;\n\n    /**\n     * Specify source IP address of the packets, or zero to include packets\n     * from any IP addresses. Note that IP address here must be in\n     * network byte order.\n     */\n    pj_uint32_t\t\tip_src;\n\n    /**\n     * Specify destination IP address of the packets, or zero to include packets\n     * destined to any IP addresses. Note that IP address here must be in\n     * network byte order.\n     */\n    pj_uint32_t\t\tip_dst;\n\n    /**\n     * Specify source port of the packets, or zero to include packets with\n     * any source port number. Note that the port number must be in network\n     * byte order.\n     */\n    pj_uint16_t\t\tsrc_port;\n\n    /**\n     * Specify destination port of the packets, or zero to include packets with\n     * any destination port number. Note that the port number must be in network\n     * byte order.\n     */\n    pj_uint16_t\t\tdst_port;\n\n} pj_pcap_filter;\n\n\n/** Opaque declaration for PCAP file */\ntypedef struct pj_pcap_file pj_pcap_file;\n\n\n/**\n * Initialize filter with default values. The default value is to allow\n * any packets.\n *\n * @param filter    Filter to be initialized.\n */\nPJ_DECL(void) pj_pcap_filter_default(pj_pcap_filter *filter);\n\n/**\n * Open PCAP file.\n *\n * @param pool\t    Pool to allocate memory.\n * @param path\t    File/path name.\n * @param p_file    Pointer to receive PCAP file handle.\n *\n * @return\t    PJ_SUCCESS if file can be opened successfully.\n */\nPJ_DECL(pj_status_t) pj_pcap_open(pj_pool_t *pool,\n\t\t\t\t  const char *path,\n\t\t\t\t  pj_pcap_file **p_file);\n\n/**\n * Close PCAP file.\n *\n * @param file\t    PCAP file handle.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_pcap_close(pj_pcap_file *file);\n\n/**\n * Configure filter for reading the file. When filter is configured,\n * only packets matching all the filter settings will be returned.\n *\n * @param file\t    PCAP file handle.\n * @param filter    The filter.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_pcap_set_filter(pj_pcap_file *file,\n\t\t\t\t        const pj_pcap_filter *filter);\n\n/**\n * Read UDP payload from the next packet in the PCAP file. Optionally it\n * can return the UDP header, if caller supplies it.\n *\n * @param file\t\t    PCAP file handle.\n * @param udp_hdr\t    Optional buffer to receive UDP header.\n * @param udp_payload\t    Buffer to receive the UDP payload.\n * @param udp_payload_size  On input, specify the size of the buffer.\n *\t\t\t    On output, it will be filled with the actual size\n *\t\t\t    of the payload as read from the packet.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_pcap_read_udp(pj_pcap_file *file,\n\t\t\t\t      pj_pcap_udp_hdr *udp_hdr,\n\t\t\t\t      pj_uint8_t *udp_payload,\n\t\t\t\t      pj_size_t *udp_payload_size);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJLIB_UTIL_PCAP_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/resolver.h",
    "content": "/* $Id: resolver.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_RESOLVER_H__\n#define __PJLIB_UTIL_RESOLVER_H__\n\n/**\n * @file resolver.h\n * @brief Asynchronous DNS resolver\n */\n#include <pjlib-util/dns.h>\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJ_DNS_RESOLVER DNS Asynchronous/Caching Resolution Engine\n * @ingroup PJ_DNS\n * @{\n *\n * This module manages the host/server resolution by performing asynchronous\n * DNS queries and caching the results in the cache. It uses PJLIB-UTIL \n * low-level DNS parsing functions (see @ref PJ_DNS) and currently supports\n * several types of DNS resource records such as A record (typical query with\n * gethostbyname()) and SRV record.\n *\n * \\section PJ_DNS_RESOLVER_FEATURES Features\n *\n * \\subsection PJ_DNS_RESOLVER_FEATURES_ASYNC Asynchronous Query and Query Aggregation\n * \n * The DNS queries are performed asychronously, with timeout setting \n * configured on per resolver instance basis. Application can issue multiple\n * asynchronous queries simultaneously. Subsequent queries to the same resource\n * (name and DNS resource type) while existing query is still pending will be\n * merged into one query, so that only one DNS request packet is issued.\n * \n * \\subsection PJ_DNS_RESOLVER_FEATURES_RETRANSMISSION Query Retransmission\n *\n * Asynchronous query will be retransmitted if no response is received\n * within the preconfigured time. Once maximum retransmission count is\n * exceeded and no response is received, the query will time out and the\n * callback will be called when error status.\n *\n * \\subsection PJ_DNS_RESOLVER_FEATURES_CACHING Response Caching with TTL\n *\n * The resolver instance caches the results returned by nameservers, to\n * enhance the performance by minimizing the message round-trip to the server.\n * The TTL of the cached resposne is calculated from minimum TTL value found \n * across all resource record (RR) TTL in the response and further more it can\n * be limited to some preconfigured maximum TTL in the resolver. \n *\n * Response caching can be  disabled by setting the maximum TTL value of the \n * resolver to zero.\n *\n * \\subsection PJ_DNS_RESOLVER_FEATURES_PARALLEL Parallel and Backup Name Servers\n *\n * When the resolver is configured with multiple nameservers, initially the\n * queries will be issued to multiple name servers simultaneously to probe\n * which servers are not active. Once the probing stage is done, subsequent \n * queries will be directed to only one ACTIVE server which provides the best\n * response time.\n *\n * Name servers are probed periodically to see which nameservers are active\n * and which are down. This probing is done when a query is sent, thus no\n * timer is needed to maintain this. Also probing will be done in parallel\n * so that there would be no additional delay for the query.\n *\n *\n * \\subsection PJ_DNS_RESOLVER_FEATURES_REC Supported Resource Records\n *\n * The low-level DNS parsing utility (see @ref PJ_DNS) supports parsing of\n * the following DNS resource records (RR):\n *  - DNS A record\n *  - DNS SRV record\n *  - DNS PTR record\n *  - DNS NS record\n *  - DNS CNAME record\n *\n * For other types of record, application can parse the raw resource \n * record data (rdata) from the parsed DNS packet (#pj_dns_parsed_packet).\n *\n *\n * \\section PJ_DNS_RESOLVER_USING Using the Resolver\n *\n * To use the resolver, application first creates the resolver instance by\n * calling #pj_dns_resolver_create(). If application already has its own\n * timer and ioqueue instances, it can instruct the resolver to use these\n * instances so that application does not need to poll the resolver \n * periodically to process events. If application does not specify the\n * timer and ioqueue instance for the resolver, an internal timer and\n * ioqueue will be created by the resolver. And since the resolver does not\n * create it's own thread, application MUST poll the resolver periodically\n * by calling #pj_dns_resolver_handle_events() to allow events (network and \n * timer) to be processed.\n *\n * Next, application MUST configure the nameservers to be used by the\n * resolver, by calling #pj_dns_resolver_set_ns().\n *\n * Application performs asynchronous query by submitting the query with\n * #pj_dns_resolver_start_query(). Once the query completes (either \n * successfully or times out), the callback will be called.\n *\n * Application can cancel a pending query by calling #pj_dns_resolver_cancel_query().\n *\n * Resolver must be destroyed by calling #pj_dns_resolver_destroy() to\n * release all resources back to the system.\n *\n *\n * \\section PJ_DNS_RESOLVER_LIMITATIONS Resolver Limitations\n *\n * Current implementation mainly suffers from a growing memory problem,\n * which mainly is caused by the response caching. Although there is only\n * one cache entry per {query, name} combination, these cache entry will\n * never get deleted since there is no timer is created to invalidate these\n * entries. So the more unique names being queried by application, there more\n * enties will be created in the response cache.\n *\n * Note that a single response entry will occupy about 600-700 bytes of \n * pool memory (the PJ_DNS_RESOLVER_RES_BUF_SIZE value plus internal\n * structure). \n *\n * Application can work around this problem by doing one of these:\n *  - disable caching by setting PJ_DNS_RESOLVER_MAX_TTL and \n *    PJ_DNS_RESOLVER_INVALID_TTL to zero.\n *  - periodically query #pj_dns_resolver_get_cached_count() and destroy-\n *    recreate the resolver to recycle the memory used by the resolver.\n *\n * Note that future improvement may solve this problem by introducing \n * expiration timer to the cached entries.\n *\n *\n * \\section PJ_DNS_RESOLVER_REFERENCE Reference\n *\n * The PJLIB-UTIL resolver was built from the information in the following\n * standards:\n *  - <A HREF=\"http://www.faqs.org/rfcs/rfc1035.html\">\n *    RFC 1035: \"Domain names - implementation and specification\"</A>\n *  - <A HREF=\"http://www.faqs.org/rfcs/rfc2782.html\">\n *    RFC 2782: \"A DNS RR for specifying the location of services (DNS SRV)\"\n *    </A>\n */\n\n\n\n/**\n * Opaque data type for DNS resolver object.\n */\ntypedef struct pj_dns_resolver pj_dns_resolver;\n\n/**\n * Opaque data type for asynchronous DNS query object.\n */\ntypedef struct pj_dns_async_query pj_dns_async_query;\n\n/**\n * Type of asynchronous callback which will be called when the asynchronous\n * query completes.\n *\n * @param user_data\tThe user data set by application when creating the\n *\t\t\tasynchronous query.\n * @param status\tStatus of the DNS resolution.\n * @param response\tThe response packet received from the server. This\n *\t\t\targument may be NULL when status is not PJ_SUCCESS.\n */\ntypedef void pj_dns_callback(void *user_data,\n\t\t\t     pj_status_t status,\n\t\t\t     pj_dns_parsed_packet *response);\n\n\n/**\n * This structure describes resolver settings.\n */\ntypedef struct pj_dns_settings\n{\n    unsigned\toptions;\t/**< Options flags.\t\t\t    */\n    unsigned\tqretr_delay;\t/**< Query retransmit delay in msec.\t    */\n    unsigned\tqretr_count;\t/**< Query maximum retransmission count.    */\n    unsigned\tcache_max_ttl;\t/**< Maximum TTL for cached responses. If the\n\t\t\t\t     value is zero, caching is disabled.    */\n    unsigned\tgood_ns_ttl;\t/**< See #PJ_DNS_RESOLVER_GOOD_NS_TTL\t    */\n    unsigned\tbad_ns_ttl;\t/**< See #PJ_DNS_RESOLVER_BAD_NS_TTL\t    */\n} pj_dns_settings;\n\n\n/**\n * This structure represents DNS A record, as the result of parsing\n * DNS response packet using #pj_dns_parse_a_response().\n */\ntypedef struct pj_dns_a_record\n{\n    /** The target name being queried.   */\n    pj_str_t\t\tname;\n\n    /** If target name corresponds to a CNAME entry, the alias contains\n     *  the value of the CNAME entry, otherwise it will be empty.\n     */\n    pj_str_t\t\talias;\n\n    /** Number of IP addresses. */\n    unsigned\t\taddr_count;\n\n    /** IP addresses of the host found in the response */\n    pj_in_addr\t\taddr[PJ_DNS_MAX_IP_IN_A_REC];\n\n    /** Internal buffer for hostname and alias. */\n    char\t\tbuf_[128];\n\n} pj_dns_a_record;\n\n\n/**\n * Set default values to the DNS settings.\n *\n * @param s\t    The DNS settings to be initialized.\n */\nPJ_DECL(void) pj_dns_settings_default(pj_dns_settings *s);\n\n\n/**\n * Create DNS resolver instance. After the resolver is created, application\n * MUST configure the nameservers with #pj_dns_resolver_set_ns().\n *\n * When creating the resolver, application may specify both timer heap\n * and ioqueue instance, so that it doesn't need to poll the resolver\n * periodically.\n *\n * @param pf\t     Pool factory where the memory pool will be created from.\n * @param name\t     Optional resolver name to identify the instance in \n *\t\t     the log.\n * @param options    Optional options, must be zero for now.\n * @param timer\t     Optional timer heap instance to be used by the resolver.\n *\t\t     If timer heap is not specified, an internal timer will be\n *\t\t     created, and application would need to poll the resolver\n *\t\t     periodically.\n * @param ioqueue    Optional I/O Queue instance to be used by the resolver.\n *\t\t     If ioqueue is not specified, an internal one will be\n *\t\t     created, and application would need to poll the resolver\n *\t\t     periodically.\n * @param p_resolver Pointer to receive the resolver instance.\n *\n * @return\t     PJ_SUCCESS on success, or the appropriate error code,\n */\nPJ_DECL(pj_status_t) pj_dns_resolver_create(pj_pool_factory *pf,\n\t\t\t\t\t    const char *name,\n\t\t\t\t\t    unsigned options,\n\t\t\t\t\t    pj_timer_heap_t *timer,\n\t\t\t\t\t    pj_ioqueue_t *ioqueue,\n\t\t\t\t\t    pj_dns_resolver **p_resolver);\n\n\n/**\n * Update the name servers for the DNS resolver. The name servers MUST be\n * configured before any resolution can be done. The order of nameservers\n * specifies their priority; the first name server will be tried first\n * before the next in the list.\n *\n * @param resolver  The resolver instance.\n * @param count     Number of name servers in the array.\n * @param servers   Array of name server IP addresses or hostnames. If\n *\t\t    hostname is specified, the hostname must be resolvable\n *\t\t    with pj_gethostbyname().\n * @param ports\t    Optional array of ports. If this argument is NULL,\n *\t\t    the nameserver will use default port.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code,\n */\nPJ_DECL(pj_status_t) pj_dns_resolver_set_ns(pj_dns_resolver *resolver,\n\t\t\t\t\t    unsigned count,\n\t\t\t\t\t    const pj_str_t servers[],\n\t\t\t\t\t    const pj_uint16_t ports[]);\n\n\n/**\n * Get the resolver current settings.\n *\n * @param resolver  The resolver instance.\n * @param st\t    Buffer to be filled up with resolver settings.\n *\n * @return\t    The query timeout setting, in seconds.\n */\nPJ_DECL(pj_status_t) pj_dns_resolver_get_settings(pj_dns_resolver *resolver,\n\t\t\t\t\t\t  pj_dns_settings *st);\n\n\n/**\n * Modify the resolver settings. Application should initialize the settings\n * by retrieving current settings first before applying new settings, to\n * ensure that all fields are initialized properly.\n *\n * @param resolver  The resolver instance.\n * @param st\t    The resolver settings.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code,\n */\nPJ_DECL(pj_status_t) pj_dns_resolver_set_settings(pj_dns_resolver *resolver,\n\t\t\t\t\t\t  const pj_dns_settings *st);\n\n\n/**\n * Poll for events from the resolver. This function MUST be called \n * periodically when the resolver is using it's own timer or ioqueue\n * (in other words, when NULL is specified as either \\a timer or\n * \\a ioqueue argument in #pj_dns_resolver_create()).\n *\n * @param resolver  The resolver instance.\n * @param timeout   Maximum time to wait for event occurence. If this\n *\t\t    argument is NULL, this function will wait forever\n *\t\t    until events occur.\n */\nPJ_DECL(void) pj_dns_resolver_handle_events(pj_dns_resolver *resolver,\n\t\t\t\t\t    const pj_time_val *timeout);\n\n\n/**\n * Destroy DNS resolver instance.\n *\n * @param resolver  The resolver object to be destryed\n * @param notify    If non-zero, all pending asynchronous queries will be\n *\t\t    cancelled and its callback will be called. If FALSE,\n *\t\t    then no callback will be called.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code,\n */\nPJ_DECL(pj_status_t) pj_dns_resolver_destroy(pj_dns_resolver *resolver,\n\t\t\t\t\t     pj_bool_t notify);\n\n\n/**\n * Create and start asynchronous DNS query for a single resource. Depending\n * on whether response cache is available, this function will either start\n * an asynchronous DNS query or call the callback immediately.\n *\n * If response is not available in the cache, an asynchronous query will be\n * started, and callback will be called at some time later when the query\n * completes. If \\a p_query argument is not NULL, it will be filled with\n * the asynchronous query object.\n *\n * If response is available in the cache, the callback will be called \n * immediately before this function returns. In this case, if \\a p_query\n * argument is not NULL, the value will be set to NULL since no new query\n * is started.\n *\n * @param resolver  The resolver object.\n * @param name\t    The name to be resolved.\n * @param type\t    The type of resource (see #pj_dns_type constants).\n * @param options   Optional options, must be zero for now.\n * @param cb\t    Callback to be called when the query completes,\n *\t\t    either successfully or with failure.\n * @param user_data Arbitrary user data to be associated with the query,\n *\t\t    and which will be given back in the callback.\n * @param p_query   Optional pointer to receive the query object, if one\n *\t\t    was started. If this pointer is specified, a NULL may\n *\t\t    be returned if response cache is available immediately.\n *\n * @return\t    PJ_SUCCESS if either an asynchronous query has been \n *\t\t    started successfully or response cache is available and\n *\t\t    the user callback has been called.\n */\nPJ_DECL(pj_status_t) pj_dns_resolver_start_query(pj_dns_resolver *resolver,\n\t\t\t\t\t\t const pj_str_t *name,\n\t\t\t\t\t\t int type,\n\t\t\t\t\t\t unsigned options,\n\t\t\t\t\t\t pj_dns_callback *cb,\n\t\t\t\t\t\t void *user_data,\n\t\t\t\t\t\t pj_dns_async_query **p_query);\n\n/**\n * Cancel a pending query.\n *\n * @param query\t    The pending asynchronous query to be cancelled.\n * @param notify    If non-zero, the callback will be called with failure\n *\t\t    status to notify that the query has been cancelled.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code,\n */\nPJ_DECL(pj_status_t) pj_dns_resolver_cancel_query(pj_dns_async_query *query,\n\t\t\t\t\t\t  pj_bool_t notify);\n\n/**\n * A utility function to parse a DNS response containing A records into \n * DNS A record.\n *\n * @param pkt\t    The DNS response packet.\n * @param rec\t    The structure to be initialized with the parsed\n *\t\t    DNS A record from the packet.\n *\n * @return\t    PJ_SUCCESS if response can be parsed successfully.\n */\nPJ_DECL(pj_status_t) pj_dns_parse_a_response(const pj_dns_parsed_packet *pkt,\n\t\t\t\t\t     pj_dns_a_record *rec);\n\n\n/**\n * Put the specified DNS packet into DNS cache. This function is mainly used\n * for testing the resolver, however it can also be used to inject entries\n * into the resolver.\n *\n * The packet MUST contain either answer section or query section so that\n * it can be indexed.\n *\n * @param resolver  The resolver instance.\n * @param pkt\t    DNS packet to be added to the DNS cache. If the packet\n *\t\t    matches existing entry, it will update the entry.\n * @param set_ttl   If the value is PJ_FALSE, the entry will not expire \n *\t\t    (so use with care). Otherwise cache expiration will be\n *\t\t    calculated based on the TTL of the answeres.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_dns_resolver_add_entry(pj_dns_resolver *resolver,\n\t\t\t\t\t       const pj_dns_parsed_packet *pkt,\n\t\t\t\t\t       pj_bool_t set_ttl);\n\n/**\n * Get the total number of response in the response cache.\n *\n * @param resolver  The resolver instance.\n *\n * @return\t    Current number of entries being stored in the response\n *\t\t    cache.\n */\nPJ_DECL(unsigned) pj_dns_resolver_get_cached_count(pj_dns_resolver *resolver);\n\n\n/**\n * Dump resolver state to the log.\n *\n * @param resolver  The resolver instance.\n * @param detail    Will print detailed entries.\n */\nPJ_DECL(void) pj_dns_resolver_dump(pj_dns_resolver *resolver,\n\t\t\t\t   pj_bool_t detail);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJLIB_UTIL_RESOLVER_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/scanner.h",
    "content": "/* $Id: scanner.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_SCANNER_H__\n#define __PJ_SCANNER_H__\n\n/**\n * @file scanner.h\n * @brief Text Scanning.\n */\n\n#include <pjlib-util/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_SCAN Fast Text Scanning\n * @ingroup PJLIB_TEXT\n * @brief Text scanning utility.\n *\n * This module describes a fast text scanning functions.\n *\n * @{\n */\n#if defined(PJ_SCANNER_USE_BITWISE) && PJ_SCANNER_USE_BITWISE != 0\n#  include <pjlib-util/scanner_cis_bitwise.h>\n#else\n#  include <pjlib-util/scanner_cis_uint.h>\n#endif\n\n/**\n * Initialize scanner input specification buffer.\n *\n * @param cs_buf    The scanner character specification.\n */\nPJ_DECL(void) pj_cis_buf_init(pj_cis_buf_t *cs_buf);\n\n/**\n * Create a new input specification.\n *\n * @param cs_buf    Specification buffer.\n * @param cis       Character input specification to be initialized.\n *\n * @return          PJ_SUCCESS if new specification has been successfully\n *                  created, or PJ_ETOOMANY if there are already too many\n *                  specifications in the buffer.\n */\nPJ_DECL(pj_status_t) pj_cis_init(pj_cis_buf_t *cs_buf, pj_cis_t *cis);\n\n/**\n * Create a new input specification based on an existing specification.\n *\n * @param new_cis   The new specification to be initialized.\n * @param existing  The existing specification, from which the input\n *                  bitmask will be copied to the new specification.\n *\n * @return          PJ_SUCCESS if new specification has been successfully\n *                  created, or PJ_ETOOMANY if there are already too many\n *                  specifications in the buffer.\n */\nPJ_DECL(pj_status_t) pj_cis_dup(pj_cis_t *new_cis, pj_cis_t *existing);\n\n/**\n * Add the characters in the specified range '[cstart, cend)' to the \n * specification (the last character itself ('cend') is not added).\n *\n * @param cis       The scanner character specification.\n * @param cstart    The first character in the range.\n * @param cend      The next character after the last character in the range.\n */\nPJ_DECL(void) pj_cis_add_range( pj_cis_t *cis, int cstart, int cend);\n\n/**\n * Add alphabetic characters to the specification.\n *\n * @param cis       The scanner character specification.\n */\nPJ_DECL(void) pj_cis_add_alpha( pj_cis_t *cis);\n\n/**\n * Add numeric characters to the specification.\n *\n * @param cis       The scanner character specification.\n */\nPJ_DECL(void) pj_cis_add_num( pj_cis_t *cis);\n\n/**\n * Add the characters in the string to the specification.\n *\n * @param cis       The scanner character specification.\n * @param str       The string.\n */\nPJ_DECL(void) pj_cis_add_str( pj_cis_t *cis, const char *str);\n\n/**\n * Add specification from another specification.\n *\n * @param cis\t    The specification is to be set.\n * @param rhs\t    The specification to be copied.\n */\nPJ_DECL(void) pj_cis_add_cis( pj_cis_t *cis, const pj_cis_t *rhs);\n\n/**\n * Delete characters in the specified range from the specification.\n *\n * @param cis       The scanner character specification.\n * @param cstart    The first character in the range.\n * @param cend      The next character after the last character in the range.\n */\nPJ_DECL(void) pj_cis_del_range( pj_cis_t *cis, int cstart, int cend);\n\n/**\n * Delete characters in the specified string from the specification.\n *\n * @param cis       The scanner character specification.\n * @param str       The string.\n */\nPJ_DECL(void) pj_cis_del_str( pj_cis_t *cis, const char *str);\n\n/**\n * Invert specification.\n *\n * @param cis       The scanner character specification.\n */\nPJ_DECL(void) pj_cis_invert( pj_cis_t *cis );\n\n/**\n * Check whether the specified character belongs to the specification.\n *\n * @param cis       The scanner character specification.\n * @param c         The character to check for matching.\n *\n * @return\t    Non-zero if match (not necessarily one).\n */\nPJ_INLINE(int) pj_cis_match( const pj_cis_t *cis, pj_uint8_t c )\n{\n    return PJ_CIS_ISSET(cis, c);\n}\n\n\n/**\n * Flags for scanner.\n */\nenum\n{\n    /** This flags specifies that the scanner should automatically skip\n\twhitespaces \n     */\n    PJ_SCAN_AUTOSKIP_WS = 1,\n\n    /** This flags specifies that the scanner should automatically skip\n        SIP header continuation. This flag implies PJ_SCAN_AUTOSKIP_WS.\n     */\n    PJ_SCAN_AUTOSKIP_WS_HEADER = 3,\n\n    /** Auto-skip new lines.\n     */\n    PJ_SCAN_AUTOSKIP_NEWLINE = 4\n};\n\n\n/* Forward decl. */\nstruct pj_scanner;\n\n\n/**\n * The callback function type to be called by the scanner when it encounters\n * syntax error.\n *\n * @param scanner       The scanner instance that calls the callback .\n */\ntypedef void (*pj_syn_err_func_ptr)(struct pj_scanner *scanner);\n\n\n/**\n * The text scanner structure.\n */\ntypedef struct pj_scanner\n{\n    char *begin;        /**< Start of input buffer.\t*/\n    char *end;          /**< End of input buffer.\t*/\n    char *curptr;       /**< Current pointer.\t\t*/\n    int   line;         /**< Current line.\t\t*/\n    char *start_line;   /**< Where current line starts.\t*/\n    int   skip_ws;      /**< Skip whitespace flag.\t*/\n    pj_syn_err_func_ptr callback;   /**< Syntax error callback. */\n} pj_scanner;\n\n\n/**\n * This structure can be used by application to store the state of the parser,\n * so that the scanner state can be rollback to this state when necessary.\n */\ntypedef struct pj_scan_state\n{\n    char *curptr;       /**< Current scanner's pointer. */\n    int   line;         /**< Current line.\t\t*/\n    char *start_line;   /**< Start of current line.\t*/\n} pj_scan_state;\n\n\n/**\n * Initialize the scanner. Note that the input string buffer must have\n * length at least buflen+1 because the scanner will NULL terminate the\n * string during initialization.\n *\n * @param scanner   The scanner to be initialized.\n * @param bufstart  The input buffer to scan. Note that buffer[buflen] will be \n *\t\t    filled with NULL char until scanner is destroyed, so\n *\t\t    the actual buffer length must be at least buflen+1.\n * @param buflen    The length of the input buffer, which normally is\n *\t\t    strlen(bufstart).\n * @param options   Zero, or combination of PJ_SCAN_AUTOSKIP_WS or\n *\t\t    PJ_SCAN_AUTOSKIP_WS_HEADER\n * @param callback  Callback to be called when the scanner encounters syntax\n *\t\t    error condition.\n */\nPJ_DECL(void) pj_scan_init( pj_scanner *scanner, char *bufstart, \n\t\t\t    pj_size_t buflen, \n\t\t\t    unsigned options,\n\t\t\t    pj_syn_err_func_ptr callback );\n\n\n/** \n * Call this function when application has finished using the scanner.\n *\n * @param scanner   The scanner.\n */\nPJ_DECL(void) pj_scan_fini( pj_scanner *scanner );\n\n\n/** \n * Determine whether the EOF condition for the scanner has been met.\n *\n * @param scanner   The scanner.\n *\n * @return Non-zero if scanner is EOF.\n */\nPJ_INLINE(int) pj_scan_is_eof( const pj_scanner *scanner)\n{\n    return scanner->curptr >= scanner->end;\n}\n\n\n/** \n * Peek strings in current position according to parameter spec, and return\n * the strings in parameter out. The current scanner position will not be\n * moved. If the scanner is already in EOF state, syntax error callback will\n * be called thrown.\n *\n * @param scanner   The scanner.\n * @param spec\t    The spec to match input string.\n * @param out\t    String to store the result.\n *\n * @return the character right after the peek-ed position or zero if there's\n *\t   no more characters.\n */\nPJ_DECL(int) pj_scan_peek( pj_scanner *scanner,\n\t\t\t   const pj_cis_t *spec, pj_str_t *out);\n\n\n/** \n * Peek len characters in current position, and return them in out parameter.\n * Note that whitespaces or newlines will be returned as it is, regardless\n * of PJ_SCAN_AUTOSKIP_WS settings. If the character left is less than len, \n * syntax error callback will be called.\n *\n * @param scanner   The scanner.\n * @param len\t    Length to peek.\n * @param out\t    String to store the result.\n *\n * @return the character right after the peek-ed position or zero if there's\n *\t   no more characters.\n */\nPJ_DECL(int) pj_scan_peek_n( pj_scanner *scanner,\n\t\t\t     pj_size_t len, pj_str_t *out);\n\n\n/** \n * Peek strings in current position until spec is matched, and return\n * the strings in parameter out. The current scanner position will not be\n * moved. If the scanner is already in EOF state, syntax error callback will\n * be called.\n *\n * @param scanner   The scanner.\n * @param spec\t    The peeking will stop when the input match this spec.\n * @param out\t    String to store the result.\n *\n * @return the character right after the peek-ed position.\n */\nPJ_DECL(int) pj_scan_peek_until( pj_scanner *scanner,\n\t\t\t\t const pj_cis_t *spec, \n\t\t\t\t pj_str_t *out);\n\n\n/** \n * Get characters from the buffer according to the spec, and return them\n * in out parameter. The scanner will attempt to get as many characters as\n * possible as long as the spec matches. If the first character doesn't\n * match the spec, or scanner is already in EOF when this function is called,\n * an exception will be thrown.\n *\n * @param scanner   The scanner.\n * @param spec\t    The spec to match input string.\n * @param out\t    String to store the result.\n */\nPJ_DECL(void) pj_scan_get( pj_scanner *scanner,\n\t\t\t   const pj_cis_t *spec, pj_str_t *out);\n\n\n/** \n * Just like #pj_scan_get(), but additionally performs unescaping when\n * escaped ('%') character is found. The input spec MUST NOT contain the\n * specification for '%' characted.\n *\n * @param scanner   The scanner.\n * @param spec\t    The spec to match input string.\n * @param out\t    String to store the result.\n */\nPJ_DECL(void) pj_scan_get_unescape( pj_scanner *scanner,\n\t\t\t\t    const pj_cis_t *spec, pj_str_t *out);\n\n\n/** \n * Get characters between quotes. If current input doesn't match begin_quote,\n * syntax error will be thrown. Note that the resulting string will contain\n * the enclosing quote.\n *\n * @param scanner\tThe scanner.\n * @param begin_quote\tThe character to begin the quote.\n * @param end_quote\tThe character to end the quote.\n * @param out\t\tString to store the result.\n */\nPJ_DECL(void) pj_scan_get_quote( pj_scanner *scanner,\n\t\t\t\t int begin_quote, int end_quote, \n\t\t\t\t pj_str_t *out);\n\n/** \n * Get characters between quotes. If current input doesn't match begin_quote,\n * syntax error will be thrown. Note that the resulting string will contain\n * the enclosing quote.\n *\n * @param scanner\tThe scanner.\n * @param begin_quotes  The character array to begin the quotes. For example,\n *                      the two characters \" and '.\n * @param end_quotes    The character array to end the quotes. The position\n *                      found in the begin_quotes array will be used to match\n *                      the end quotes. So if the begin_quotes was the array\n *                      of \"'< the end_quotes should be \"'>. If begin_array\n *                      matched the ' then the end_quotes will look for ' to\n *                      match at the end.\n * @param qsize         The size of the begin_quotes and end_quotes arrays.\n * @param out           String to store the result.\n */\nPJ_DECL(void) pj_scan_get_quotes(pj_scanner *scanner,\n                                 const char *begin_quotes,\n                                 const char *end_quotes, int qsize,\n                                 pj_str_t *out);\n\n\n/**\n * Get N characters from the scanner.\n *\n * @param scanner   The scanner.\n * @param N\t    Number of characters to get.\n * @param out\t    String to store the result.\n */\nPJ_DECL(void) pj_scan_get_n( pj_scanner *scanner,\n\t\t\t     unsigned N, pj_str_t *out);\n\n\n/** \n * Get one character from the scanner.\n *\n * @param scanner   The scanner.\n *\n * @return The character.\n */\nPJ_DECL(int) pj_scan_get_char( pj_scanner *scanner );\n\n\n/** \n * Get characters from the scanner and move the scanner position until the\n * current character matches the spec.\n *\n * @param scanner   The scanner.\n * @param spec\t    Get until the input match this spec.\n * @param out\t    String to store the result.\n */\nPJ_DECL(void) pj_scan_get_until( pj_scanner *scanner,\n\t\t\t\t const pj_cis_t *spec, pj_str_t *out);\n\n\n/** \n * Get characters from the scanner and move the scanner position until the\n * current character matches until_char.\n *\n * @param scanner\tThe scanner.\n * @param until_char    Get until the input match this character.\n * @param out\t\tString to store the result.\n */\nPJ_DECL(void) pj_scan_get_until_ch( pj_scanner *scanner, \n\t\t\t\t    int until_char, pj_str_t *out);\n\n\n/** \n * Get characters from the scanner and move the scanner position until the\n * current character matches until_char.\n *\n * @param scanner\tThe scanner.\n * @param until_spec\tGet until the input match any of these characters.\n * @param out\t\tString to store the result.\n */\nPJ_DECL(void) pj_scan_get_until_chr( pj_scanner *scanner,\n\t\t\t\t     const char *until_spec, pj_str_t *out);\n\n/** \n * Advance the scanner N characters, and skip whitespace\n * if necessary.\n *\n * @param scanner   The scanner.\n * @param N\t    Number of characters to skip.\n * @param skip\t    Flag to specify whether whitespace should be skipped\n *\t\t    after skipping the characters.\n */\nPJ_DECL(void) pj_scan_advance_n( pj_scanner *scanner,\n\t\t\t\t unsigned N, pj_bool_t skip);\n\n\n/** \n * Compare string in current position with the specified string.\n * \n * @param scanner   The scanner.\n * @param s\t    The string to compare with.\n * @param len\t    Length of the string to compare.\n *\n * @return zero, <0, or >0 (just like strcmp()).\n */\nPJ_DECL(int) pj_scan_strcmp( pj_scanner *scanner, const char *s, int len);\n\n\n/** \n * Case-less string comparison of current position with the specified\n * string.\n *\n * @param scanner   The scanner.\n * @param s\t    The string to compare with.\n * @param len\t    Length of the string to compare with.\n *\n * @return zero, <0, or >0 (just like strcmp()).\n */\nPJ_DECL(int) pj_scan_stricmp( pj_scanner *scanner, const char *s, int len);\n\n/**\n * Perform case insensitive string comparison of string in current position,\n * knowing that the string to compare only consists of alphanumeric\n * characters.\n *\n * Note that unlike #pj_scan_stricmp, this function can only return zero or\n * -1.\n *\n * @param scanner   The scanner.\n * @param s\t    The string to compare with.\n * @param len\t    Length of the string to compare with.\n *\n * @return\t    zero if equal or -1.\n *\n * @see strnicmp_alnum, pj_stricmp_alnum\n */\nPJ_DECL(int) pj_scan_stricmp_alnum( pj_scanner *scanner, const char *s, \n\t\t\t\t    int len);\n\n\n/** \n * Get a newline from the scanner. A newline is defined as '\\\\n', or '\\\\r', or\n * \"\\\\r\\\\n\". If current input is not newline, syntax error will be thrown.\n *\n * @param scanner   The scanner.\n */\nPJ_DECL(void) pj_scan_get_newline( pj_scanner *scanner );\n\n\n/** \n * Manually skip whitespaces according to flag that was specified when\n * the scanner was initialized.\n *\n * @param scanner   The scanner.\n */\nPJ_DECL(void) pj_scan_skip_whitespace( pj_scanner *scanner );\n\n\n/**\n * Skip current line.\n *\n * @param scanner   The scanner.\n */\nPJ_DECL(void) pj_scan_skip_line( pj_scanner *scanner );\n\n/** \n * Save the full scanner state.\n *\n * @param scanner   The scanner.\n * @param state\t    Variable to store scanner's state.\n */\nPJ_DECL(void) pj_scan_save_state( const pj_scanner *scanner, \n\t\t\t\t  pj_scan_state *state);\n\n\n/** \n * Restore the full scanner state.\n * Note that this would not restore the string if application has modified\n * it. This will only restore the scanner scanning position.\n *\n * @param scanner   The scanner.\n * @param state\t    State of the scanner.\n */\nPJ_DECL(void) pj_scan_restore_state( pj_scanner *scanner, \n\t\t\t\t     pj_scan_state *state);\n\n/**\n * Get current column position.\n *\n * @param scanner   The scanner.\n *\n * @return\t    The column position.\n */\nPJ_INLINE(int) pj_scan_get_col( const pj_scanner *scanner )\n{\n    return (int)(scanner->curptr - scanner->start_line);\n}\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/scanner_cis_bitwise.h",
    "content": "/* $Id: scanner_cis_bitwise.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_SCANNER_CIS_BIT_H__\n#define __PJLIB_UTIL_SCANNER_CIS_BIT_H__\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * This describes the type of individual character specification in\n * #pj_cis_buf_t. Basicly the number of bits here\n */\n#ifndef PJ_CIS_ELEM_TYPE\n#   define PJ_CIS_ELEM_TYPE pj_uint32_t\n#endif\n\n/**\n * This describes the type of individual character specification in\n * #pj_cis_buf_t.\n */\ntypedef PJ_CIS_ELEM_TYPE pj_cis_elem_t;\n\n/**\n * Maximum number of input specification in a buffer.\n * Effectively this means the number of bits in pj_cis_elem_t.\n */\n#define PJ_CIS_MAX_INDEX   (sizeof(pj_cis_elem_t) << 3)\n\n/**\n * The scanner input specification buffer.\n */\ntypedef struct pj_cis_buf_t\n{\n    pj_cis_elem_t    cis_buf[256];  /**< Must be 256 (not 128)! */\n    pj_cis_elem_t    use_mask;      /**< To keep used indexes.  */\n} pj_cis_buf_t;\n\n/**\n * Character input specification.\n */\ntypedef struct pj_cis_t\n{\n    pj_cis_elem_t   *cis_buf;       /**< Pointer to buffer.     */\n    int              cis_id;        /**< Id.                    */\n} pj_cis_t;\n\n\n/**\n * Set the membership of the specified character.\n * Note that this is a macro, and arguments may be evaluated more than once.\n *\n * @param cis       Pointer to character input specification.\n * @param c         The character.\n */\n#define PJ_CIS_SET(cis,c)   ((cis)->cis_buf[(int)(c)] |= (1 << (cis)->cis_id))\n\n/**\n * Remove the membership of the specified character.\n * Note that this is a macro, and arguments may be evaluated more than once.\n *\n * @param cis       Pointer to character input specification.\n * @param c         The character to be removed from the membership.\n */\n#define PJ_CIS_CLR(cis,c)   ((cis)->cis_buf[(int)c] &= ~(1 << (cis)->cis_id))\n\n/**\n * Check the membership of the specified character.\n * Note that this is a macro, and arguments may be evaluated more than once.\n *\n * @param cis       Pointer to character input specification.\n * @param c         The character.\n */\n#define PJ_CIS_ISSET(cis,c) ((cis)->cis_buf[(int)c] & (1 << (cis)->cis_id))\n\n\n\nPJ_END_DECL\n\n#endif\t/* __PJLIB_UTIL_SCANNER_CIS_BIT_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/scanner_cis_uint.h",
    "content": "/* $Id: scanner_cis_uint.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_SCANNER_CIS_BIT_H__\n#define __PJLIB_UTIL_SCANNER_CIS_BIT_H__\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * This describes the type of individual character specification in\n * #pj_cis_buf_t. Basicly the number of bits here\n */\n#ifndef PJ_CIS_ELEM_TYPE\n#   define PJ_CIS_ELEM_TYPE int\n#endif\n\n/**\n * This describes the type of individual character specification in\n * #pj_cis_buf_t.\n */\ntypedef PJ_CIS_ELEM_TYPE pj_cis_elem_t;\n\n/** pj_cis_buf_t is not used when uint back-end is used. */\ntypedef int pj_cis_buf_t;\n\n/**\n * Character input specification.\n */\ntypedef struct pj_cis_t\n{\n    PJ_CIS_ELEM_TYPE\tcis_buf[256];\t/**< Internal buffer.\t*/\n} pj_cis_t;\n\n\n/**\n * Set the membership of the specified character.\n * Note that this is a macro, and arguments may be evaluated more than once.\n *\n * @param cis       Pointer to character input specification.\n * @param c         The character.\n */\n#define PJ_CIS_SET(cis,c)   ((cis)->cis_buf[(int)(c)] = 1)\n\n/**\n * Remove the membership of the specified character.\n * Note that this is a macro, and arguments may be evaluated more than once.\n *\n * @param cis       Pointer to character input specification.\n * @param c         The character to be removed from the membership.\n */\n#define PJ_CIS_CLR(cis,c)   ((cis)->cis_buf[(int)c] = 0)\n\n/**\n * Check the membership of the specified character.\n * Note that this is a macro, and arguments may be evaluated more than once.\n *\n * @param cis       Pointer to character input specification.\n * @param c         The character.\n */\n#define PJ_CIS_ISSET(cis,c) ((cis)->cis_buf[(int)c])\n\n\n\nPJ_END_DECL\n\n#endif\t/* __PJLIB_UTIL_SCANNER_CIS_BIT_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/sha1.h",
    "content": "/* $Id: sha1.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_SHA1_H__\n#define __PJLIB_UTIL_SHA1_H__\n\n/**\n * @file sha1.h\n * @brief SHA1 encryption implementation\n */\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJLIB_UTIL_SHA1 SHA1\n * @ingroup PJLIB_UTIL_ENCRYPTION\n * @{\n */\n\n/** SHA1 context */\ntypedef struct pj_sha1_context\n{\n    pj_uint32_t state[5];\t/**< State  */\n    pj_uint32_t count[2];\t/**< Count  */\n    pj_uint8_t\tbuffer[64];\t/**< Buffer */\n} pj_sha1_context;\n\n/** SHA1 digest size is 20 bytes */\n#define PJ_SHA1_DIGEST_SIZE\t20\n\n\n/** Initialize the algorithm. \n *  @param ctx\t\tSHA1 context.\n */\nPJ_DECL(void) pj_sha1_init(pj_sha1_context *ctx);\n\n/** Append a stream to the message. \n *  @param ctx\t\tSHA1 context.\n *  @param data\t\tData.\n *  @param nbytes\tLength of data.\n */\nPJ_DECL(void) pj_sha1_update(pj_sha1_context *ctx, \n\t\t\t     const pj_uint8_t *data, \n\t\t\t     const pj_size_t nbytes);\n\n/** Finish the message and return the digest. \n *  @param ctx\t\tSHA1 context.\n *  @param digest\t16 byte digest.\n */\nPJ_DECL(void) pj_sha1_final(pj_sha1_context *ctx, \n\t\t\t    pj_uint8_t digest[PJ_SHA1_DIGEST_SIZE]);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJLIB_UTIL_SHA1_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/srv_resolver.h",
    "content": "/* $Id: srv_resolver.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_SRV_RESOLVER_H__\n#define __PJLIB_UTIL_SRV_RESOLVER_H__\n\n/**\n * @file srv_resolver.h\n * @brief DNS SRV resolver\n */\n#include <pjlib-util/resolver.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_DNS_SRV_RESOLVER DNS SRV Resolution Helper\n * @ingroup PJ_DNS\n * @{\n *\n * \\section PJ_DNS_SRV_RESOLVER_INTRO DNS SRV Resolution Helper\n *\n * This module provides an even higher layer of abstraction for the DNS\n * resolution framework, to resolve DNS SRV names.\n *\n * The #pj_dns_srv_resolve() function will asynchronously resolve the server\n * name into IP address(es) with a single function call. If the SRV name\n * contains multiple names, then each will be resolved with individual\n * DNS A resolution to get the IP addresses. Upon successful completion, \n * application callback will be called with each IP address of the\n * target selected based on the load-balancing and fail-over criteria\n * below.\n *\n * When the resolver fails to resolve the name using DNS SRV resolution\n * (for example when the DNS SRV record is not present in the DNS server),\n * the resolver will fallback to using DNS A record resolution to resolve\n * the name.\n *\n * \\subsection PJ_DNS_SRV_RESOLVER_FAILOVER_LOADBALANCE Load-Balancing and Fail-Over\n *\n * When multiple targets are returned in the DNS SRV response, server entries\n * are selected based on the following rule (which is described in RFC 2782):\n *  - targets will be sorted based on the priority first.\n *  - for targets with the same priority, #pj_dns_srv_resolve() will select\n *    only one target according to its weight. To select this one target,\n *    the function associates running-sum for all targets, and generates \n *    a random number between zero and the total running-sum (inclusive).\n *    The target selected is the first target with running-sum greater than\n *    or equal to this random number.\n *\n * The above procedure will select one target for each priority, allowing\n * application to fail-over to the next target when the previous target fails.\n * These targets are returned in the #pj_dns_srv_record structure \n * argument of the callback. \n *\n * \\section PJ_DNS_SRV_RESOLVER_REFERENCE Reference\n *\n * Reference:\n *  - <A HREF=\"http://www.ietf.org/rfc/rfc2782.txt\">RFC 2782</A>: \n *\tA DNS RR for specifying the location of services (DNS SRV)\n */\n\n/**\n * Flags to be specified when starting the DNS SRV query.\n */\ntypedef enum pj_dns_srv_option\n{\n    /**\n     * Specify if the resolver should fallback with DNS A\n     * resolution when the SRV resolution fails. This option may\n     * be specified together with PJ_DNS_SRV_FALLBACK_AAAA to\n     * make the resolver fallback to AAAA if SRV resolution fails,\n     * and then to DNS A resolution if the AAAA resolution fails.\n     */\n    PJ_DNS_SRV_FALLBACK_A\t= 1,\n\n    /**\n     * Specify if the resolver should fallback with DNS AAAA\n     * resolution when the SRV resolution fails. This option may\n     * be specified together with PJ_DNS_SRV_FALLBACK_A to\n     * make the resolver fallback to AAAA if SRV resolution fails,\n     * and then to DNS A resolution if the AAAA resolution fails.\n     */\n    PJ_DNS_SRV_FALLBACK_AAAA\t= 2,\n\n    /**\n     * Specify if the resolver should try to resolve with DNS AAAA\n     * resolution first of each targets in the DNS SRV record. If\n     * this option is not specified, the SRV resolver will query\n     * the DNS A record for the target instead.\n     */\n    PJ_DNS_SRV_RESOLVE_AAAA\t= 4\n\n} pj_dns_srv_option;\n\n\n/**\n * This structure represents DNS SRV records as the result of DNS SRV\n * resolution using #pj_dns_srv_resolve().\n */\ntypedef struct pj_dns_srv_record\n{\n    /** Number of address records. */\n    unsigned\tcount;\n\n    /** Address records. */\n    struct\n    {\n\t/** Server priority (the lower the higher the priority). */\n\tunsigned\t\tpriority;\n\n\t/** Server weight (the higher the more load it can handle). */\n\tunsigned\t\tweight;\n\n\t/** Port number. */\n\tpj_uint16_t\t\tport;\n\n\t/** The host address. */\n\tpj_dns_a_record\t\tserver;\n\n    } entry[PJ_DNS_SRV_MAX_ADDR];\n\n} pj_dns_srv_record;\n\n\n/** Opaque declaration for DNS SRV query */\ntypedef struct pj_dns_srv_async_query pj_dns_srv_async_query;\n\n/**\n * Type of callback function to receive notification from the resolver\n * when the resolution process completes.\n */\ntypedef void pj_dns_srv_resolver_cb(void *user_data,\n\t\t\t\t    pj_status_t status,\n\t\t\t\t    const pj_dns_srv_record *rec);\n\n\n/**\n * Start DNS SRV resolution for the specified name. The full name of the\n * entry will be concatenated from \\a res_name and \\a domain_name fragments.\n *\n * @param domain_name\tThe domain name part of the name.\n * @param res_name\tThe full service name, including the transport name\n *\t\t\tand with all the leading underscore characters and\n *\t\t\tending dot (e.g. \"_sip._udp.\", \"_stun._udp.\").\n * @param def_port\tThe port number to be assigned to the resolved address\n *\t\t\twhen the DNS SRV resolution fails and the name is \n *\t\t\tresolved with DNS A resolution.\n * @param pool\t\tMemory pool used to allocate memory for the query.\n * @param resolver\tThe resolver instance.\n * @param option\tOption flags, which can be constructed from\n *\t\t\t#pj_dns_srv_option bitmask. Note that this argument\n *\t\t\twas called \"fallback_a\" in pjsip version 0.8.0 and\n *\t\t\tolder, but the new option should be backward \n *\t\t\tcompatible with existing applications. If application\n *\t\t\tspecifies PJ_TRUE as \"fallback_a\" value, it will\n *\t\t\tcorrespond to PJ_DNS_SRV_FALLBACK_A option.\n * @param token\t\tArbitrary data to be associated with this query when\n *\t\t\tthe calback is called.\n * @param cb\t\tPointer to callback function to receive the\n *\t\t\tnotification when the resolution process completes.\n * @param p_query\tOptional pointer to receive the query object, if one\n *\t\t\twas started. If this pointer is specified, a NULL may\n *\t\t\tbe returned if response cache is available immediately.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_dns_srv_resolve(const pj_str_t *domain_name,\n\t\t\t\t\tconst pj_str_t *res_name,\n\t\t\t\t\tunsigned def_port,\n\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\tpj_dns_resolver *resolver,\n\t\t\t\t\tunsigned option,\n\t\t\t\t\tvoid *token,\n\t\t\t\t\tpj_dns_srv_resolver_cb *cb,\n\t\t\t\t\tpj_dns_srv_async_query **p_query);\n\n\n/**\n * Cancel an outstanding DNS SRV query.\n *\n * @param query\t    The pending asynchronous query to be cancelled.\n * @param notify    If non-zero, the callback will be called with failure\n *\t\t    status to notify that the query has been cancelled.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code,\n */\nPJ_DECL(pj_status_t) pj_dns_srv_cancel_query(pj_dns_srv_async_query *query,\n\t\t\t\t\t     pj_bool_t notify);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJLIB_UTIL_SRV_RESOLVER_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/string.h",
    "content": "/* $Id: string.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_STRING_H__\n#define __PJLIB_UTIL_STRING_H__\n\n/**\n * @file string.h\n * @brief More string functions.\n */\n\n#include <pj/types.h>\n#include <pjlib-util/scanner.h>\n\n/**\n * @defgroup PJLIB_UTIL_STRING String Escaping Utilities\n * @ingroup PJLIB_TEXT\n * @{\n */\n\nPJ_BEGIN_DECL\n\n/**\n * Unescape string. If source string does not contain any escaped\n * characters, the function would simply return the original string.\n * Otherwise a new string will be allocated.\n *\n * @param pool\t    Pool to allocate the string.\n * @param src\t    Source string to unescape.\n *\n * @return\t    String with no escaped characters.\n */\nPJ_DECL(pj_str_t) pj_str_unescape( pj_pool_t *pool, const pj_str_t *src);\n\n/**\n * Unescape string to destination.\n *\n * @param dst\t    Target string.\n * @param src\t    Source string.\n *\n * @return\t    Target string.\n */\nPJ_DECL(pj_str_t*) pj_strcpy_unescape(pj_str_t *dst, const pj_str_t *src);\n\n/**\n * Copy string to destination while escaping reserved characters, up to\n * the specified maximum length.\n *\n * @param dst\t    Target string.\n * @param src\t    Source string.\n * @param max\t    Maximum length to copy to target string.\n * @param unres\t    Unreserved characters, which are allowed to appear \n *\t\t    unescaped.\n *\n * @return\t    The target string if all characters have been copied \n *\t\t    successfully, or NULL if there's not enough buffer to\n *\t\t    escape the strings.\n */\nPJ_DECL(pj_str_t*) pj_strncpy_escape(pj_str_t *dst, const pj_str_t *src,\n\t\t\t\t     pj_ssize_t max, const pj_cis_t *unres);\n\n\n/**\n * Copy string to destination while escaping reserved characters, up to\n * the specified maximum length.\n *\n * @param dst\t    Target string.\n * @param src\t    Source string.\n * @param max\t    Maximum length to copy to target string.\n * @param unres\t    Unreserved characters, which are allowed to appear \n *\t\t    unescaped.\n *\n * @return\t    The length of the destination, or -1 if there's not\n *\t\t    enough buffer.\n */\nPJ_DECL(pj_ssize_t) pj_strncpy2_escape(char *dst, const pj_str_t *src,\n\t\t\t\t       pj_ssize_t max, const pj_cis_t *unres);\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n#endif\t/* __PJLIB_UTIL_STRING_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/stun_simple.h",
    "content": "/* $Id: stun_simple.h 4224 2012-08-09 05:21:25Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSTUN_H__\n#define __PJSTUN_H__\n\n/**\n * @file stun.h\n * @brief STUN client.\n */\n\n#include <pjlib-util/types.h>\n#include <pj/sock.h>\n\n\nPJ_BEGIN_DECL\n\n/*\n * This enumeration describes STUN message types.\n */\ntypedef enum pjstun_msg_type\n{\n    PJSTUN_BINDING_REQUEST\t\t    = 0x0001,\n    PJSTUN_BINDING_RESPONSE\t\t    = 0x0101,\n    PJSTUN_BINDING_ERROR_RESPONSE\t    = 0x0111,\n    PJSTUN_SHARED_SECRET_REQUEST\t    = 0x0002,\n    PJSTUN_SHARED_SECRET_RESPONSE\t    = 0x0102,\n    PJSTUN_SHARED_SECRET_ERROR_RESPONSE    = 0x0112\n} pjstun_msg_type;\n\n\n/*\n * This enumeration describes STUN attribute types.\n */\ntypedef enum pjstun_attr_type\n{\n    PJSTUN_ATTR_MAPPED_ADDR = 1,\n    PJSTUN_ATTR_RESPONSE_ADDR,\n    PJSTUN_ATTR_CHANGE_REQUEST,\n    PJSTUN_ATTR_SOURCE_ADDR,\n    PJSTUN_ATTR_CHANGED_ADDR,\n    PJSTUN_ATTR_USERNAME,\n    PJSTUN_ATTR_PASSWORD,\n    PJSTUN_ATTR_MESSAGE_INTEGRITY,\n    PJSTUN_ATTR_ERROR_CODE,\n    PJSTUN_ATTR_UNKNOWN_ATTRIBUTES,\n    PJSTUN_ATTR_REFLECTED_FROM,\n    PJSTUN_ATTR_XOR_MAPPED_ADDR = 0x0020\n} pjstun_attr_type;\n\n\n/*\n * This structre describes STUN message header.\n */\ntypedef struct pjstun_msg_hdr\n{\n    pj_uint16_t\t\ttype;\n    pj_uint16_t\t\tlength;\n    pj_uint32_t\t\ttsx[4];\n} pjstun_msg_hdr;\n\n\n/*\n * This structre describes STUN attribute header.\n */\ntypedef struct pjstun_attr_hdr\n{\n    pj_uint16_t\t\ttype;\n    pj_uint16_t\t\tlength;\n} pjstun_attr_hdr;\n\n\n/*\n * This structre describes STUN MAPPED-ADDR attribute.\n */\ntypedef struct pjstun_mapped_addr_attr\n{\n    pjstun_attr_hdr\thdr;\n    pj_uint8_t\t\tignored;\n    pj_uint8_t\t\tfamily;\n    pj_uint16_t\t\tport;\n    pj_uint32_t\t\taddr;\n} pjstun_mapped_addr_attr;\n\ntypedef pjstun_mapped_addr_attr pjstun_response_addr_attr;\ntypedef pjstun_mapped_addr_attr pjstun_changed_addr_attr;\ntypedef pjstun_mapped_addr_attr pjstun_src_addr_attr;\ntypedef pjstun_mapped_addr_attr pjstun_reflected_form_attr;\n\ntypedef struct pjstun_change_request_attr\n{\n    pjstun_attr_hdr\thdr;\n    pj_uint32_t\t\tvalue;\n} pjstun_change_request_attr;\n\ntypedef struct pjstun_username_attr\n{\n    pjstun_attr_hdr\thdr;\n    pj_uint32_t\t\tvalue[1];\n} pjstun_username_attr;\n\ntypedef pjstun_username_attr pjstun_password_attr;\n\ntypedef struct pjstun_error_code_attr\n{\n    pjstun_attr_hdr\thdr;\n    pj_uint16_t\t\tignored;\n    pj_uint8_t\t\terr_class;\n    pj_uint8_t\t\tnumber;\n    char\t\treason[4];\n} pjstun_error_code_attr;\n\ntypedef struct pjstun_msg\n{\n    pjstun_msg_hdr    *hdr;\n    int\t\t\tattr_count;\n    pjstun_attr_hdr   *attr[PJSTUN_MAX_ATTR];\n} pjstun_msg;\n\n/* STUN message API (stun.c). */\n\nPJ_DECL(pj_status_t) pjstun_create_bind_req( pj_pool_t *pool, \n\t\t\t\t\t      void **msg, pj_size_t *len,\n\t\t\t\t\t      pj_uint32_t id_hi,\n\t\t\t\t\t      pj_uint32_t id_lo);\nPJ_DECL(pj_status_t) pjstun_parse_msg( void *buf, pj_size_t len,\n\t\t\t\t        pjstun_msg *msg);\nPJ_DECL(void*) pjstun_msg_find_attr( pjstun_msg *msg, pjstun_attr_type t);\n\n\n/**\n * @defgroup PJLIB_UTIL_STUN_CLIENT Simple STUN Helper\n * @ingroup PJ_PROTOCOLS\n * @brief A simple and small footprint STUN resolution helper\n * @{\n *\n * This is the older implementation of STUN client, with only one function\n * provided (pjstun_get_mapped_addr()) to retrieve the public IP address\n * of multiple sockets.\n */\n\n/**\n * This is the main function to request the mapped address of local sockets\n * to multiple STUN servers. This function is able to find the mapped \n * addresses of multiple sockets simultaneously, and for each socket, two\n * requests will be sent to two different STUN servers to see if both servers\n * get the same public address for the same socket. (Note that application can\n * specify the same address for the two servers, but still two requests will\n * be sent for each server).\n *\n * This function will perform necessary retransmissions of the requests if\n * response is not received within a predetermined period. When all responses\n * have been received, the function will compare the mapped addresses returned\n * by the servers, and when both are equal, the address will be returned in\n * \\a mapped_addr argument.\n *\n * @param pf\t\tThe pool factory where memory will be allocated from.\n * @param sock_cnt\tNumber of sockets in the socket array.\n * @param sock\t\tArray of local UDP sockets which public addresses are\n *\t\t\tto be queried from the STUN servers.\n * @param srv1\t\tHost name or IP address string of the first STUN\n *\t\t\tserver.\n * @param port1\t\tThe port number of the first STUN server. \n * @param srv2\t\tHost name or IP address string of the second STUN\n *\t\t\tserver.\n * @param port2\t\tThe port number of the second STUN server. \n * @param mapped_addr\tArray to receive the mapped public address of the local\n *\t\t\tUDP sockets, when the function returns PJ_SUCCESS.\n *\n * @return\t\tThis functions returns PJ_SUCCESS if responses are\n *\t\t\treceived from all servers AND all servers returned the\n *\t\t\tsame mapped public address. Otherwise this function may\n *\t\t\treturn one of the following error codes:\n *\t\t\t- PJLIB_UTIL_ESTUNNOTRESPOND: no respons from servers.\n *\t\t\t- PJLIB_UTIL_ESTUNSYMMETRIC: different mapped addresses\n *\t\t\t  are returned by servers.\n *\t\t\t- etc.\n *\n */\nPJ_DECL(pj_status_t) pjstun_get_mapped_addr( pj_pool_factory *pf,\n\t\t\t\t\t      int sock_cnt, pj_sock_t sock[],\n\t\t\t\t\t      const pj_str_t *srv1, int port1,\n\t\t\t\t\t      const pj_str_t *srv2, int port2,\n\t\t\t\t\t      pj_sockaddr_in mapped_addr[]);\n\n\n/*\n * This structre describes configurable setting for requesting mapped address.\n */\ntypedef struct pjstun_setting\n{\n    /**\n     * Specifies whether STUN request generated by old STUN library should\n     * insert magic cookie (specified in RFC 5389) in the transaction ID.\n     */\n    pj_bool_t\tuse_stun2;\n\n    /**\n     * Host name or IP address string of the first STUN server.\n     */\n    pj_str_t srv1;\n\n    /**\n     * The port number of the first STUN server.\n     */\n    int port1;\n\n    /**\n     * Host name or IP address string of the second STUN server.\n     */\n    pj_str_t srv2;\n\n    /**\n     * The port number of the second STUN server.\n     */\n    int port2;\n\n} pjstun_setting;\n\n\n/**\n * Another version of mapped address resolution of local sockets to multiple\n * STUN servers configured in #pjstun_setting. This function is able to find\n * the mapped addresses of multiple sockets simultaneously, and for each\n * socket, two requests will be sent to two different STUN servers to see if\n * both servers get the same public address for the same socket. (Note that\n * application can specify the same address for the two servers, but still\n * two requests will be sent for each server).\n *\n * This function will perform necessary retransmissions of the requests if\n * response is not received within a predetermined period. When all responses\n * have been received, the function will compare the mapped addresses returned\n * by the servers, and when both are equal, the address will be returned in\n * \\a mapped_addr argument.\n *\n * @param pf\t\tThe pool factory where memory will be allocated from.\n * @param opt\t\tThe STUN settings.\n * @param sock_cnt\tNumber of sockets in the socket array.\n * @param sock\t\tArray of local UDP sockets which public addresses are\n *\t\t\tto be queried from the STUN servers.\n * @param mapped_addr\tArray to receive the mapped public address of the local\n *\t\t\tUDP sockets, when the function returns PJ_SUCCESS.\n *\n * @return\t\tThis functions returns PJ_SUCCESS if responses are\n *\t\t\treceived from all servers AND all servers returned the\n *\t\t\tsame mapped public address. Otherwise this function may\n *\t\t\treturn one of the following error codes:\n *\t\t\t- PJLIB_UTIL_ESTUNNOTRESPOND: no respons from servers.\n *\t\t\t- PJLIB_UTIL_ESTUNSYMMETRIC: different mapped addresses\n *\t\t\t  are returned by servers.\n *\t\t\t- etc.\n *\n */\nPJ_DECL(pj_status_t) pjstun_get_mapped_addr2( pj_pool_factory *pf,\n\t\t\t\t\t      const pjstun_setting *opt,\n\t\t\t\t\t      int sock_cnt,\n\t\t\t\t\t      pj_sock_t sock[],\n\t\t\t\t\t      pj_sockaddr_in mapped_addr[]);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJSTUN_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/types.h",
    "content": "/* $Id: types.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_TYPES_H__\n#define __PJLIB_UTIL_TYPES_H__\n\n/**\n * @file types.h\n * @brief PJLIB-UTIL types.\n */\n\n#include <pj/types.h>\n#include <pjlib-util/config.h>\n\n/**\n * @defgroup PJLIB_UTIL_BASE Base\n * @{\n */\n\nPJ_BEGIN_DECL\n\n/**\n * Initialize PJLIB UTIL (defined in errno.c)\n *\n * @return PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjlib_util_init(void);\n\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n/**\n * @defgroup PJLIB_TEXT Text and String Manipulation\n */\n\n/**\n * @defgroup PJ_PROTOCOLS Protocols\n */\n\n/**\n * @defgroup PJ_FILE_FMT File Formats\n */\n\n/**\n * @mainpage PJLIB-UTIL\n *\n * \\n\n * \\n\n * \\n\n * This is the documentation of PJLIB-UTIL, an auxiliary library providing\n * adjunct functions to PJLIB.\n * \n * Please go to the <A HREF=\"modules.htm\"><B>Table of Contents</B></A> page\n * for list of modules.\n *\n *\n * \\n\n * \\n\n * \\n\n * \\n\n * \\n\n * \\n\n * \\n\n * \\n\n * \\n\n * \\n\n * \\n\n * \\n\n * \\n\n */\n\n#endif\t/* __PJLIB_UTIL_TYPES_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util/xml.h",
    "content": "/* $Id: xml.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_XML_H__\n#define __PJ_XML_H__\n\n/**\n * @file xml.h\n * @brief PJLIB XML Parser/Helper.\n */\n\n#include <pj/types.h>\n#include <pj/list.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJ_TINY_XML Mini/Tiny XML Parser/Helper\n * @ingroup PJ_FILE_FMT\n * @{\n */\n\n/** Typedef for XML attribute. */\ntypedef struct pj_xml_attr pj_xml_attr;\n\n/** Typedef for XML nodes. */\ntypedef struct pj_xml_node pj_xml_node;\n\n/** This structure declares XML attribute. */\nstruct pj_xml_attr\n{\n    PJ_DECL_LIST_MEMBER(pj_xml_attr);   /**< Standard list elements.    */\n    pj_str_t\tname;\t                /**< Attribute name.            */\n    pj_str_t\tvalue;\t                /**< Attribute value.           */\n};\n\n/** This structure describes XML node head inside XML node structure.\n */\ntypedef struct pj_xml_node_head\n{\n    PJ_DECL_LIST_MEMBER(pj_xml_node);   /**< Standard list elements.    */\n} pj_xml_node_head;\n\n/** This structure describes XML node. */\nstruct pj_xml_node\n{\n    PJ_DECL_LIST_MEMBER(pj_xml_node);   /**< List @a prev and @a next member */\n    pj_str_t\t\tname;\t\t/**< Node name.                      */\n    pj_xml_attr\t\tattr_head;      /**< Attribute list.                 */\n    pj_xml_node_head\tnode_head;      /**< Node list.                      */\n    pj_str_t\t\tcontent;\t/**< Node content.                   */\n};\n\n/**\n * Parse XML message into XML document with a single root node. The parser\n * is capable of parsing XML processing instruction construct (\"<?\") and \n * XML comments (\"<!--\"), however such constructs will be ignored and will not \n * be included in the resulted XML node tree.\n *\n * @param pool\t    Pool to allocate memory from.\n * @param msg\t    The XML message to parse.\n * @param len\t    The length of the message.\n *\n * @return\t    XML root node, or NULL if the XML document can not be parsed.\n */\nPJ_DECL(pj_xml_node*) pj_xml_parse( pj_pool_t *pool, char *msg, pj_size_t len);\n\n\n/**\n * Print XML into XML message. Note that the function WILL NOT NULL terminate\n * the output.\n *\n * @param node\t    The XML node to print.\n * @param buf\t    Buffer to hold the output message.\n * @param len\t    The length of the buffer.\n * @param prolog    If set to nonzero, will print XML prolog (\"<?xml..\")\n *\n * @return\t    The size of the printed message, or -1 if there is not \n *\t\t    sufficient space in the buffer to print the message.\n */\nPJ_DECL(int) pj_xml_print( const pj_xml_node *node, char *buf, pj_size_t len,\n\t\t\t   pj_bool_t prolog);\n\n/**\n * Clone XML node and all subnodes.\n *\n * @param pool\t    Pool to allocate memory for new nodes.\n * @param rhs\t    The node to clone.\n *\n * @return\t    Cloned XML node, or NULL on fail.\n */\nPJ_DECL(pj_xml_node*) pj_xml_clone( pj_pool_t *pool, const pj_xml_node *rhs);\n\n\n/**\n * Create an empty node.\n *\n * @param pool\t    Pool.\n * @param name\t    Node name.\n *\n * @return\t    The new node.\n */\nPJ_DECL(pj_xml_node*) pj_xml_node_new(pj_pool_t *pool, const pj_str_t *name);\n\n\n/**\n * Create new XML attribute.\n *\n * @param pool\t    Pool.\n * @param name\t    Attribute name.\n * @param value\t    Attribute value.\n *\n * @return\t    The new XML attribute.\n */\nPJ_DECL(pj_xml_attr*) pj_xml_attr_new(pj_pool_t *pool, const pj_str_t *name,\n\t\t\t\t      const pj_str_t *value);\n\n/**\n * Add node to another node.\n *\n * @param parent    Parent node.\n * @param node\t    Node to be added to parent.\n */\nPJ_DECL(void) pj_xml_add_node( pj_xml_node *parent, pj_xml_node *node );\n\n\n/**\n * Add attribute to a node.\n *\n * @param node\t    Node.\n * @param attr\t    Attribute to add to node.\n */\nPJ_DECL(void) pj_xml_add_attr( pj_xml_node *node, pj_xml_attr *attr );\n\n/**\n * Find first direct child node with the specified name.\n *\n * @param parent    Parent node.\n * @param name\t    Node name to find.\n *\n * @return\t    XML node found or NULL.\n */\nPJ_DECL(pj_xml_node*) pj_xml_find_node(const pj_xml_node *parent, \n\t\t\t\t       const pj_str_t *name);\n\n/**\n * Find next direct child node with the specified name.\n *\n * @param parent    Parent node.\n * @param node\t    node->next is the starting point.\n * @param name\t    Node name to find.\n *\n * @return\t    XML node found or NULL.\n */\nPJ_DECL(pj_xml_node*) pj_xml_find_next_node(const pj_xml_node *parent, \n\t\t\t\t\t    const pj_xml_node *node,\n\t\t\t\t\t    const pj_str_t *name);\n\n/**\n * Recursively find the first node with the specified name in the child nodes\n * and their children.\n *\n * @param parent    Parent node.\n * @param name\t    Node name to find.\n *\n * @return\t    XML node found or NULL.\n */\nPJ_DECL(pj_xml_node*) pj_xml_find_node_rec(const pj_xml_node *parent, \n\t\t\t\t\t   const pj_str_t *name);\n\n\n/**\n * Find first attribute within a node with the specified name and optional \n * value.\n *\n * @param node\t    XML Node.\n * @param name\t    Attribute name to find.\n * @param value\t    Optional value to match.\n *\n * @return\t    XML attribute found, or NULL.\n */\nPJ_DECL(pj_xml_attr*) pj_xml_find_attr(const pj_xml_node *node, \n\t\t\t\t       const pj_str_t *name,\n\t\t\t\t       const pj_str_t *value);\n\n\n/**\n * Find a direct child node with the specified name and match the function.\n *\n * @param parent    Parent node.\n * @param name\t    Optional name. If this is NULL, the name will not be\n *\t\t    matched.\n * @param data\t    Data to be passed to matching function.\n * @param match\t    Optional matching function.\n *\n * @return\t    The first matched node, or NULL.\n */\nPJ_DECL(pj_xml_node*) pj_xml_find( const pj_xml_node *parent, \n\t\t\t\t   const pj_str_t *name,\n\t\t\t\t   const void *data, \n\t\t\t\t   pj_bool_t (*match)(const pj_xml_node *, \n\t\t\t\t\t\t      const void*));\n\n\n/**\n * Recursively find a child node with the specified name and match the \n * function.\n *\n * @param parent    Parent node.\n * @param name\t    Optional name. If this is NULL, the name will not be\n *\t\t    matched.\n * @param data\t    Data to be passed to matching function.\n * @param match\t    Optional matching function.\n *\n * @return\t    The first matched node, or NULL.\n */\nPJ_DECL(pj_xml_node*) pj_xml_find_rec(const pj_xml_node *parent, \n\t\t\t\t      const pj_str_t *name,\n\t\t\t\t      const void *data, \n\t\t\t\t      pj_bool_t (*match)(const pj_xml_node*, \n\t\t\t\t\t\t\t const void*));\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJ_XML_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/include/pjlib-util.h",
    "content": "/* $Id: pjlib-util.h 4476 2013-04-19 06:05:06Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJLIB_UTIL_H__\n#define __PJLIB_UTIL_H__\n\n/**\n * @file pjlib-util.h\n * @brief pjlib-util.h\n */\n\n/* Base */\n#include <pjlib-util/errno.h>\n#include <pjlib-util/types.h>\n\n/* Getopt */\n#include <pjlib-util/getopt.h>\n\n/* Crypto */\n#include <pjlib-util/base64.h>\n#include <pjlib-util/crc32.h>\n#include <pjlib-util/hmac_md5.h>\n#include <pjlib-util/hmac_sha1.h>\n#include <pjlib-util/md5.h>\n#include <pjlib-util/sha1.h>\n\n/* DNS and resolver */\n#include <pjlib-util/dns.h>\n#include <pjlib-util/resolver.h>\n#include <pjlib-util/srv_resolver.h>\n\n/* Simple DNS server */\n#include <pjlib-util/dns_server.h>\n\n/* Text scanner and utilities */\n#include <pjlib-util/scanner.h>\n#include <pjlib-util/string.h>\n\n/* XML */\n#include <pjlib-util/xml.h>\n\n/* JSON */\n#include <pjlib-util/json.h>\n\n/* Old STUN */\n#include <pjlib-util/stun_simple.h>\n\n/* PCAP */\n#include <pjlib-util/pcap.h>\n\n/* HTTP */\n#include <pjlib-util/http_client.h>\n\n#endif\t/* __PJLIB_UTIL_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/base64.c",
    "content": "/* $Id: base64.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/base64.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n\n#define INV\t    -1\n#define PADDING\t    '='\n\nstatic const char base64_char[] = {\n    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',\n    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',\n    'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',\n    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',\n    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',\n    'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',\n    '8', '9', '+', '/' \n};\n\nstatic int base256_char(char c)\n{\n    if (c >= 'A' && c <= 'Z')\n\treturn (c - 'A');\n    else if (c >= 'a' && c <= 'z')\n\treturn (c - 'a' + 26);\n    else if (c >= '0' && c <= '9')\n\treturn (c - '0' + 52);\n    else if (c == '+')\n\treturn (62);\n    else if (c == '/')\n\treturn (63);\n    else {\n\t/* It *may* happen on bad input, so this is not a good idea.\n\t * pj_assert(!\"Should not happen as '=' should have been filtered\");\n\t */\n\treturn INV;\n    }\n}\n\n\nstatic void base256to64(pj_uint8_t c1, pj_uint8_t c2, pj_uint8_t c3, \n\t\t\tint padding, char *output)\n{\n    *output++ = base64_char[c1>>2];\n    *output++ = base64_char[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];\n    switch (padding) {\n    case 0:\n\t*output++ = base64_char[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];\n\t*output = base64_char[c3 & 0x3F];\n\tbreak;\n    case 1:\n\t*output++ = base64_char[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];\n\t*output = PADDING;\n\tbreak;\n    case 2:\n    default:\n\t*output++ = PADDING;\n\t*output = PADDING;\n\tbreak;\n    }\n}\n\n\nPJ_DEF(pj_status_t) pj_base64_encode(const pj_uint8_t *input, int in_len,\n\t\t\t\t     char *output, int *out_len)\n{\n    const pj_uint8_t *pi = input;\n    pj_uint8_t c1, c2, c3;\n    int i = 0;\n    char *po = output;\n\n    PJ_ASSERT_RETURN(input && output && out_len, PJ_EINVAL);\n    PJ_ASSERT_RETURN(*out_len >= PJ_BASE256_TO_BASE64_LEN(in_len), \n\t\t     PJ_ETOOSMALL);\n\n    while (i < in_len) {\n\tc1 = *pi++;\n\t++i;\n\n\tif (i == in_len) {\n\t    base256to64(c1, 0, 0, 2, po);\n\t    po += 4;\n\t    break;\n\t} else {\n\t    c2 = *pi++;\n\t    ++i;\n\n\t    if (i == in_len) {\n\t\tbase256to64(c1, c2, 0, 1, po);\n\t\tpo += 4;\n\t\tbreak;\n\t    } else {\n\t\tc3 = *pi++;\n\t\t++i;\n\t\tbase256to64(c1, c2, c3, 0, po);\n\t    }\n\t}\n\n\tpo += 4;\n    }\n\n    *out_len = (int)(po - output);\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_base64_decode(const pj_str_t *input, \n\t\t\t\t     pj_uint8_t *out, int *out_len)\n{\n    const char *buf = input->ptr;\n    int len = (int)input->slen;\n    int i, j, k;\n    int c[4];\n\n    PJ_ASSERT_RETURN(input && out && out_len, PJ_EINVAL);\n\n    while (buf[len-1] == '=' && len)\n\t--len;\n\n    PJ_ASSERT_RETURN(*out_len >= PJ_BASE64_TO_BASE256_LEN(len), \n\t\t     PJ_ETOOSMALL);\n\n    for (i=0, j=0; i<len; ) {\n\t/* Fill up c, silently ignoring invalid characters */\n\tfor (k=0; k<4 && i<len; ++k) {\n\t    do {\n\t\tc[k] = base256_char(buf[i++]);\n\t    } while (c[k]==INV && i<len);\n\t}\n\n\tif (k<4) {\n\t    if (k > 1) {\n\t\tout[j++] = (pj_uint8_t)((c[0]<<2) | ((c[1] & 0x30)>>4));\n\t\tif (k > 2) {\n\t\t    out[j++] = (pj_uint8_t)\n\t\t\t       (((c[1] & 0x0F)<<4) | ((c[2] & 0x3C)>>2));\n\t\t}\n\t    }\n\t    break;\n\t}\n\n\tout[j++] = (pj_uint8_t)((c[0]<<2) | ((c[1] & 0x30)>>4));\n\tout[j++] = (pj_uint8_t)(((c[1] & 0x0F)<<4) | ((c[2] & 0x3C)>>2));\n\tout[j++] = (pj_uint8_t)(((c[2] & 0x03)<<6) | (c[3] & 0x3F));\n    }\n\n    pj_assert(j < *out_len);\n    *out_len = j;\n\n    return PJ_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/crc32.c",
    "content": "/* $Id: crc32.c 2511 2009-03-13 12:28:00Z bennylp $ */\n/*\n * This is an implementation of CRC32. See ISO 3309 and ITU-T V.42 \n * for a formal specification\n *\n * This file is partly taken from Crypto++ library (http://www.cryptopp.com)\n * and http://www.di-mgt.com.au/crypto.html#CRC.\n *\n * Since the original version of the code is put in public domain,\n * this file is put on public domain as well.\n */\n#include <pjlib-util/crc32.h>\n\n\n#define CRC32_NEGL  0xffffffffL\n\n#if defined(PJ_CRC32_HAS_TABLES) && PJ_CRC32_HAS_TABLES!=0\n// crc.cpp - written and placed in the public domain by Wei Dai\n\n/* Table of CRC-32's of all single byte values (made by makecrc.c) */\n#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN != 0\n\n#define CRC32_INDEX(c)\t    (c & 0xff)\n#define CRC32_SHIFTED(c)    (c >> 8)\n#define CRC32_SWAP(c)       (c)\n\nstatic const pj_uint32_t crc_tab[] = {\n    0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,\n    0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,\n    0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,\n    0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,\n    0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,\n    0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,\n    0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,\n    0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,\n    0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,\n    0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,\n    0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,\n    0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,\n    0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,\n    0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,\n    0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,\n    0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,\n    0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,\n    0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,\n    0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,\n    0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,\n    0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,\n    0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,\n    0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,\n    0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,\n    0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,\n    0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,\n    0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,\n    0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,\n    0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,\n    0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,\n    0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,\n    0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,\n    0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,\n    0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,\n    0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,\n    0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,\n    0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,\n    0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,\n    0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,\n    0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,\n    0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,\n    0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,\n    0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,\n    0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,\n    0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,\n    0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,\n    0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,\n    0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,\n    0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,\n    0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,\n    0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,\n    0x2d02ef8dL\n};\n\n\n#elif defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN != 0\n#define CRC32_INDEX(c)\t    (c >> 24)\n#define CRC32_SHIFTED(c)    (c << 8)\n#define CRC32_SWAP(c)       ((((c) & 0xff000000) >> 24) | \\\n                             (((c) & 0x00ff0000) >>  8) | \\\n                             (((c) & 0x0000ff00) <<  8) | \\\n                             (((c) & 0x000000ff) << 24))\n\nstatic const pj_uint32_t crc_tab[] = {\n    0x00000000L, 0x96300777L, 0x2c610eeeL, 0xba510999L, 0x19c46d07L,\n    0x8ff46a70L, 0x35a563e9L, 0xa395649eL, 0x3288db0eL, 0xa4b8dc79L,\n    0x1ee9d5e0L, 0x88d9d297L, 0x2b4cb609L, 0xbd7cb17eL, 0x072db8e7L,\n    0x911dbf90L, 0x6410b71dL, 0xf220b06aL, 0x4871b9f3L, 0xde41be84L,\n    0x7dd4da1aL, 0xebe4dd6dL, 0x51b5d4f4L, 0xc785d383L, 0x56986c13L,\n    0xc0a86b64L, 0x7af962fdL, 0xecc9658aL, 0x4f5c0114L, 0xd96c0663L,\n    0x633d0ffaL, 0xf50d088dL, 0xc8206e3bL, 0x5e10694cL, 0xe44160d5L,\n    0x727167a2L, 0xd1e4033cL, 0x47d4044bL, 0xfd850dd2L, 0x6bb50aa5L,\n    0xfaa8b535L, 0x6c98b242L, 0xd6c9bbdbL, 0x40f9bcacL, 0xe36cd832L,\n    0x755cdf45L, 0xcf0dd6dcL, 0x593dd1abL, 0xac30d926L, 0x3a00de51L,\n    0x8051d7c8L, 0x1661d0bfL, 0xb5f4b421L, 0x23c4b356L, 0x9995bacfL,\n    0x0fa5bdb8L, 0x9eb80228L, 0x0888055fL, 0xb2d90cc6L, 0x24e90bb1L,\n    0x877c6f2fL, 0x114c6858L, 0xab1d61c1L, 0x3d2d66b6L, 0x9041dc76L,\n    0x0671db01L, 0xbc20d298L, 0x2a10d5efL, 0x8985b171L, 0x1fb5b606L,\n    0xa5e4bf9fL, 0x33d4b8e8L, 0xa2c90778L, 0x34f9000fL, 0x8ea80996L,\n    0x18980ee1L, 0xbb0d6a7fL, 0x2d3d6d08L, 0x976c6491L, 0x015c63e6L,\n    0xf4516b6bL, 0x62616c1cL, 0xd8306585L, 0x4e0062f2L, 0xed95066cL,\n    0x7ba5011bL, 0xc1f40882L, 0x57c40ff5L, 0xc6d9b065L, 0x50e9b712L,\n    0xeab8be8bL, 0x7c88b9fcL, 0xdf1ddd62L, 0x492dda15L, 0xf37cd38cL,\n    0x654cd4fbL, 0x5861b24dL, 0xce51b53aL, 0x7400bca3L, 0xe230bbd4L,\n    0x41a5df4aL, 0xd795d83dL, 0x6dc4d1a4L, 0xfbf4d6d3L, 0x6ae96943L,\n    0xfcd96e34L, 0x468867adL, 0xd0b860daL, 0x732d0444L, 0xe51d0333L,\n    0x5f4c0aaaL, 0xc97c0dddL, 0x3c710550L, 0xaa410227L, 0x10100bbeL,\n    0x86200cc9L, 0x25b56857L, 0xb3856f20L, 0x09d466b9L, 0x9fe461ceL,\n    0x0ef9de5eL, 0x98c9d929L, 0x2298d0b0L, 0xb4a8d7c7L, 0x173db359L,\n    0x810db42eL, 0x3b5cbdb7L, 0xad6cbac0L, 0x2083b8edL, 0xb6b3bf9aL,\n    0x0ce2b603L, 0x9ad2b174L, 0x3947d5eaL, 0xaf77d29dL, 0x1526db04L,\n    0x8316dc73L, 0x120b63e3L, 0x843b6494L, 0x3e6a6d0dL, 0xa85a6a7aL,\n    0x0bcf0ee4L, 0x9dff0993L, 0x27ae000aL, 0xb19e077dL, 0x44930ff0L,\n    0xd2a30887L, 0x68f2011eL, 0xfec20669L, 0x5d5762f7L, 0xcb676580L,\n    0x71366c19L, 0xe7066b6eL, 0x761bd4feL, 0xe02bd389L, 0x5a7ada10L,\n    0xcc4add67L, 0x6fdfb9f9L, 0xf9efbe8eL, 0x43beb717L, 0xd58eb060L,\n    0xe8a3d6d6L, 0x7e93d1a1L, 0xc4c2d838L, 0x52f2df4fL, 0xf167bbd1L,\n    0x6757bca6L, 0xdd06b53fL, 0x4b36b248L, 0xda2b0dd8L, 0x4c1b0aafL,\n    0xf64a0336L, 0x607a0441L, 0xc3ef60dfL, 0x55df67a8L, 0xef8e6e31L,\n    0x79be6946L, 0x8cb361cbL, 0x1a8366bcL, 0xa0d26f25L, 0x36e26852L,\n    0x95770cccL, 0x03470bbbL, 0xb9160222L, 0x2f260555L, 0xbe3bbac5L,\n    0x280bbdb2L, 0x925ab42bL, 0x046ab35cL, 0xa7ffd7c2L, 0x31cfd0b5L,\n    0x8b9ed92cL, 0x1daede5bL, 0xb0c2649bL, 0x26f263ecL, 0x9ca36a75L,\n    0x0a936d02L, 0xa906099cL, 0x3f360eebL, 0x85670772L, 0x13570005L,\n    0x824abf95L, 0x147ab8e2L, 0xae2bb17bL, 0x381bb60cL, 0x9b8ed292L,\n    0x0dbed5e5L, 0xb7efdc7cL, 0x21dfdb0bL, 0xd4d2d386L, 0x42e2d4f1L,\n    0xf8b3dd68L, 0x6e83da1fL, 0xcd16be81L, 0x5b26b9f6L, 0xe177b06fL,\n    0x7747b718L, 0xe65a0888L, 0x706a0fffL, 0xca3b0666L, 0x5c0b0111L,\n    0xff9e658fL, 0x69ae62f8L, 0xd3ff6b61L, 0x45cf6c16L, 0x78e20aa0L,\n    0xeed20dd7L, 0x5483044eL, 0xc2b30339L, 0x612667a7L, 0xf71660d0L,\n    0x4d476949L, 0xdb776e3eL, 0x4a6ad1aeL, 0xdc5ad6d9L, 0x660bdf40L,\n    0xf03bd837L, 0x53aebca9L, 0xc59ebbdeL, 0x7fcfb247L, 0xe9ffb530L,\n    0x1cf2bdbdL, 0x8ac2bacaL, 0x3093b353L, 0xa6a3b424L, 0x0536d0baL,\n    0x9306d7cdL, 0x2957de54L, 0xbf67d923L, 0x2e7a66b3L, 0xb84a61c4L,\n    0x021b685dL, 0x942b6f2aL, 0x37be0bb4L, 0xa18e0cc3L, 0x1bdf055aL,\n    0x8def022dL\n};\n\n#else\n#   error \"Endianness not defined\"\n#endif\n\n\nPJ_DEF(void) pj_crc32_init(pj_crc32_context *ctx)\n{\n    ctx->crc_state = 0;\n}\n\nPJ_DEF(pj_uint32_t) pj_crc32_update(pj_crc32_context *ctx, \n\t\t\t\t    const pj_uint8_t *data,\n\t\t\t\t    pj_size_t nbytes)\n{\n    pj_uint32_t crc = ctx->crc_state ^ CRC32_NEGL;\n\n    for( ; (((unsigned long)(pj_ssize_t)data) & 0x03) && nbytes > 0; --nbytes) {\n\tcrc = crc_tab[CRC32_INDEX(crc) ^ *data++] ^ CRC32_SHIFTED(crc);\n    }\n\n    while (nbytes >= 4) {\n\tcrc ^= *(const pj_uint32_t *)data;\n\tcrc = crc_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);\n\tcrc = crc_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);\n\tcrc = crc_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);\n\tcrc = crc_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);\n\tnbytes -= 4;\n\tdata += 4;\n    }\n\n    while (nbytes--) {\n\tcrc = crc_tab[CRC32_INDEX(crc) ^ *data++] ^ CRC32_SHIFTED(crc);\n    }\n\n    ctx->crc_state = crc ^ CRC32_NEGL;\n\n    return ctx->crc_state;\n}\n\nPJ_DEF(pj_uint32_t) pj_crc32_final(pj_crc32_context *ctx)\n{\n    return CRC32_SWAP(ctx->crc_state);\n}\n\n\n#else\n\nPJ_DEF(void) pj_crc32_init(pj_crc32_context *ctx)\n{\n    ctx->crc_state = CRC32_NEGL;\n}\n\n\nPJ_DEF(pj_uint32_t) pj_crc32_update(pj_crc32_context *ctx, \n\t\t\t\t    const pj_uint8_t *octets,\n\t\t\t\t    pj_size_t len)\n\n{\n    pj_uint32_t crc = ctx->crc_state;\n    \n    while (len--) {\n\tpj_uint32_t temp;\n\tint j;\n\n\ttemp = (pj_uint32_t)((crc & 0xFF) ^ *octets++);\n\tfor (j = 0; j < 8; j++)\n\t{\n\t    if (temp & 0x1)\n\t\ttemp = (temp >> 1) ^ 0xEDB88320;\n\t    else\n\t\ttemp >>= 1;\n\t}\n\tcrc = (crc >> 8) ^ temp;\n    }\n    ctx->crc_state = crc;\n\n    return crc ^ CRC32_NEGL;\n}\n\nPJ_DEF(pj_uint32_t) pj_crc32_final(pj_crc32_context *ctx)\n{\n    ctx->crc_state ^= CRC32_NEGL;\n    return ctx->crc_state;\n}\n\n#endif\n\n\nPJ_DEF(pj_uint32_t) pj_crc32_calc( const pj_uint8_t *data,\n\t\t\t\t   pj_size_t nbytes)\n{\n    pj_crc32_context ctx;\n\n    pj_crc32_init(&ctx);\n    pj_crc32_update(&ctx, data, nbytes);\n    return pj_crc32_final(&ctx);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/dns.c",
    "content": "/* $Id: dns.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/dns.h>\n#include <pjlib-util/errno.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/pool.h>\n#include <pj/sock.h>\n#include <pj/string.h>\n\n\nPJ_DEF(const char *) pj_dns_get_type_name(int type)\n{\n    switch (type) {\n    case PJ_DNS_TYPE_A:\t    return \"A\";\n    case PJ_DNS_TYPE_AAAA:  return \"AAAA\";\n    case PJ_DNS_TYPE_SRV:   return \"SRV\";\n    case PJ_DNS_TYPE_NS:    return \"NS\";\n    case PJ_DNS_TYPE_CNAME: return \"CNAME\";\n    case PJ_DNS_TYPE_PTR:   return \"PTR\";\n    case PJ_DNS_TYPE_MX:    return \"MX\";\n    case PJ_DNS_TYPE_TXT:   return \"TXT\";\n    case PJ_DNS_TYPE_NAPTR: return \"NAPTR\";\n    }\n    return \"(Unknown)\";\n}\n\n\nstatic void write16(pj_uint8_t *p, pj_uint16_t val)\n{\n    p[0] = (pj_uint8_t)(val >> 8);\n    p[1] = (pj_uint8_t)(val & 0xFF);\n}\n\n\n/**\n * Initialize a DNS query transaction.\n */\nPJ_DEF(pj_status_t) pj_dns_make_query( void *packet,\n\t\t\t\t       unsigned *size,\n\t\t\t\t       pj_uint16_t id,\n\t\t\t\t       int qtype,\n\t\t\t\t       const pj_str_t *name)\n{\n    pj_uint8_t *p = (pj_uint8_t*)packet;\n    const char *startlabel, *endlabel, *endname;\n    pj_size_t d;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(packet && size && qtype && name, PJ_EINVAL);\n\n    /* Calculate total number of bytes required. */\n    d = sizeof(pj_dns_hdr) + name->slen + 4;\n\n    /* Check that size is sufficient. */\n    PJ_ASSERT_RETURN(*size >= d, PJLIB_UTIL_EDNSQRYTOOSMALL);\n\n    /* Initialize header */\n    pj_assert(sizeof(pj_dns_hdr)==12);\n    pj_bzero(p, sizeof(struct pj_dns_hdr));\n    write16(p+0, id);\n    write16(p+2, (pj_uint16_t)PJ_DNS_SET_RD(1));\n    write16(p+4, (pj_uint16_t)1);\n\n    /* Initialize query */\n    p = ((pj_uint8_t*)packet)+sizeof(pj_dns_hdr);\n\n    /* Tokenize name */\n    startlabel = endlabel = name->ptr;\n    endname = name->ptr + name->slen;\n    while (endlabel != endname) {\n\twhile (endlabel != endname && *endlabel != '.')\n\t    ++endlabel;\n\t*p++ = (pj_uint8_t)(endlabel - startlabel);\n\tpj_memcpy(p, startlabel, endlabel-startlabel);\n\tp += (endlabel-startlabel);\n\tif (endlabel != endname && *endlabel == '.')\n\t    ++endlabel;\n\tstartlabel = endlabel;\n    }\n    *p++ = '\\0';\n\n    /* Set type */\n    write16(p, (pj_uint16_t)qtype);\n    p += 2;\n\n    /* Set class (IN=1) */\n    write16(p, 1);\n    p += 2;\n\n    /* Done, calculate length */\n    *size = (unsigned)(p - (pj_uint8_t*)packet);\n\n    return 0;\n}\n\n\n/* Get a name length (note: name consists of multiple labels and\n * it may contain pointers when name compression is applied) \n */\nstatic pj_status_t get_name_len(int rec_counter, const pj_uint8_t *pkt, \n\t\t\t\tconst pj_uint8_t *start, const pj_uint8_t *max, \n\t\t\t\tint *parsed_len, int *name_len)\n{\n    const pj_uint8_t *p;\n    pj_status_t status;\n\n    /* Limit the number of recursion */\n    if (rec_counter > 10) {\n\t/* Too many name recursion */\n\treturn PJLIB_UTIL_EDNSINNAMEPTR;\n    }\n\n    *name_len = *parsed_len = 0;\n    p = start;\n    while (*p) {\n\tif ((*p & 0xc0) == 0xc0) {\n\t    /* Compression is found! */\n\t    int ptr_len = 0;\n\t    int dummy;\n\t    pj_uint16_t offset;\n\n\t    /* Get the 14bit offset */\n\t    pj_memcpy(&offset, p, 2);\n\t    offset ^= pj_htons((pj_uint16_t)(0xc0 << 8));\n\t    offset = pj_ntohs(offset);\n\n\t    /* Check that offset is valid */\n\t    if (offset >= max - pkt)\n\t\treturn PJLIB_UTIL_EDNSINNAMEPTR;\n\n\t    /* Get the name length from that offset. */\n\t    status = get_name_len(rec_counter+1, pkt, pkt + offset, max, \n\t\t\t\t  &dummy, &ptr_len);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    *parsed_len += 2;\n\t    *name_len += ptr_len;\n\n\t    return PJ_SUCCESS;\n\t} else {\n\t    unsigned label_len = *p;\n\n\t    /* Check that label length is valid */\n\t    if (pkt+label_len > max)\n\t\treturn PJLIB_UTIL_EDNSINNAMEPTR;\n\n\t    p += (label_len + 1);\n\t    *parsed_len += (label_len + 1);\n\n\t    if (*p != 0)\n\t\t++label_len;\n\t    \n\t    *name_len += label_len;\n\n\t    if (p >= max)\n\t\treturn PJLIB_UTIL_EDNSINSIZE;\n\t}\n    }\n    ++p;\n    (*parsed_len)++;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Parse and copy name (note: name consists of multiple labels and\n * it may contain pointers when compression is applied).\n */\nstatic pj_status_t get_name(int rec_counter, const pj_uint8_t *pkt, \n\t\t\t    const pj_uint8_t *start, const pj_uint8_t *max,\n\t\t\t    pj_str_t *name)\n{\n    const pj_uint8_t *p;\n    pj_status_t status;\n\n    /* Limit the number of recursion */\n    if (rec_counter > 10) {\n\t/* Too many name recursion */\n\treturn PJLIB_UTIL_EDNSINNAMEPTR;\n    }\n\n    p = start;\n    while (*p) {\n\tif ((*p & 0xc0) == 0xc0) {\n\t    /* Compression is found! */\n\t    pj_uint16_t offset;\n\n\t    /* Get the 14bit offset */\n\t    pj_memcpy(&offset, p, 2);\n\t    offset ^= pj_htons((pj_uint16_t)(0xc0 << 8));\n\t    offset = pj_ntohs(offset);\n\n\t    /* Check that offset is valid */\n\t    if (offset >= max - pkt)\n\t\treturn PJLIB_UTIL_EDNSINNAMEPTR;\n\n\t    /* Retrieve the name from that offset. */\n\t    status = get_name(rec_counter+1, pkt, pkt + offset, max, name);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    return PJ_SUCCESS;\n\t} else {\n\t    unsigned label_len = *p;\n\n\t    /* Check that label length is valid */\n\t    if (pkt+label_len > max)\n\t\treturn PJLIB_UTIL_EDNSINNAMEPTR;\n\n\t    pj_memcpy(name->ptr + name->slen, p+1, label_len);\n\t    name->slen += label_len;\n\n\t    p += label_len + 1;\n\t    if (*p != 0) {\n\t\t*(name->ptr + name->slen) = '.';\n\t\t++name->slen;\n\t    }\n\n\t    if (p >= max)\n\t\treturn PJLIB_UTIL_EDNSINSIZE;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* Parse query records. */\nstatic pj_status_t parse_query(pj_dns_parsed_query *q, pj_pool_t *pool,\n\t\t\t       const pj_uint8_t *pkt, const pj_uint8_t *start,\n\t\t\t       const pj_uint8_t *max, int *parsed_len)\n{\n    const pj_uint8_t *p = start;\n    int name_len, name_part_len;\n    pj_status_t status;\n\n    /* Get the length of the name */\n    status = get_name_len(0, pkt, start, max, &name_part_len, &name_len);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Allocate memory for the name */\n    q->name.ptr = (char*) pj_pool_alloc(pool, name_len+4);\n    q->name.slen = 0;\n\n    /* Get the name */\n    status = get_name(0, pkt, start, max, &q->name);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    p = (start + name_part_len);\n\n    /* Get the type */\n    pj_memcpy(&q->type, p, 2);\n    q->type = pj_ntohs(q->type);\n    p += 2;\n\n    /* Get the class */\n    pj_memcpy(&q->dnsclass, p, 2);\n    q->dnsclass = pj_ntohs(q->dnsclass);\n    p += 2;\n\n    *parsed_len = (int)(p - start);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Parse RR records */\nstatic pj_status_t parse_rr(pj_dns_parsed_rr *rr, pj_pool_t *pool,\n\t\t\t    const pj_uint8_t *pkt,\n\t\t\t    const pj_uint8_t *start, const pj_uint8_t *max,\n\t\t\t    int *parsed_len)\n{\n    const pj_uint8_t *p = start;\n    int name_len, name_part_len;\n    pj_status_t status;\n\n    /* Get the length of the name */\n    status = get_name_len(0, pkt, start, max, &name_part_len, &name_len);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Allocate memory for the name */\n    rr->name.ptr = (char*) pj_pool_alloc(pool, name_len+4);\n    rr->name.slen = 0;\n\n    /* Get the name */\n    status = get_name(0, pkt, start, max, &rr->name);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    p = (start + name_part_len);\n\n    /* Check the size can accomodate next few fields. */\n    if (p+10 > max)\n\treturn PJLIB_UTIL_EDNSINSIZE;\n\n    /* Get the type */\n    pj_memcpy(&rr->type, p, 2);\n    rr->type = pj_ntohs(rr->type);\n    p += 2;\n    \n    /* Get the class */\n    pj_memcpy(&rr->dnsclass, p, 2);\n    rr->dnsclass = pj_ntohs(rr->dnsclass);\n    p += 2;\n\n    /* Class MUST be IN */\n    if (rr->dnsclass != 1) {\n\t/* Class is not IN, return error only if type is known (see #1889) */\n\tif (rr->type == PJ_DNS_TYPE_A     || rr->type == PJ_DNS_TYPE_AAAA  ||\n\t    rr->type == PJ_DNS_TYPE_CNAME || rr->type == PJ_DNS_TYPE_NS    ||\n\t    rr->type == PJ_DNS_TYPE_PTR   || rr->type == PJ_DNS_TYPE_SRV)\n\t{\n\t    return PJLIB_UTIL_EDNSINCLASS;\n\t}\n    }\n\n    /* Get TTL */\n    pj_memcpy(&rr->ttl, p, 4);\n    rr->ttl = pj_ntohl(rr->ttl);\n    p += 4;\n\n    /* Get rdlength */\n    pj_memcpy(&rr->rdlength, p, 2);\n    rr->rdlength = pj_ntohs(rr->rdlength);\n    p += 2;\n\n    /* Check that length is valid */\n    if (p + rr->rdlength > max)\n\treturn PJLIB_UTIL_EDNSINSIZE;\n\n    /* Parse some well known records */\n    if (rr->type == PJ_DNS_TYPE_A) {\n\tpj_memcpy(&rr->rdata.a.ip_addr, p, 4);\n\tp += 4;\n\n    } else if (rr->type == PJ_DNS_TYPE_AAAA) {\n\tpj_memcpy(&rr->rdata.aaaa.ip_addr, p, 16);\n\tp += 16;\n\n    } else if (rr->type == PJ_DNS_TYPE_CNAME ||\n\t       rr->type == PJ_DNS_TYPE_NS ||\n\t       rr->type == PJ_DNS_TYPE_PTR) \n    {\n\n\t/* Get the length of the target name */\n\tstatus = get_name_len(0, pkt, p, max, &name_part_len, &name_len);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Allocate memory for the name */\n\trr->rdata.cname.name.ptr = (char*) pj_pool_alloc(pool, name_len);\n\trr->rdata.cname.name.slen = 0;\n\n\t/* Get the name */\n\tstatus = get_name(0, pkt, p, max, &rr->rdata.cname.name);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tp += name_part_len;\n\n    } else if (rr->type == PJ_DNS_TYPE_SRV) {\n\n\t/* Priority */\n\tpj_memcpy(&rr->rdata.srv.prio, p, 2);\n\trr->rdata.srv.prio = pj_ntohs(rr->rdata.srv.prio);\n\tp += 2;\n\n\t/* Weight */\n\tpj_memcpy(&rr->rdata.srv.weight, p, 2);\n\trr->rdata.srv.weight = pj_ntohs(rr->rdata.srv.weight);\n\tp += 2;\n\n\t/* Port */\n\tpj_memcpy(&rr->rdata.srv.port, p, 2);\n\trr->rdata.srv.port = pj_ntohs(rr->rdata.srv.port);\n\tp += 2;\n\t\n\t/* Get the length of the target name */\n\tstatus = get_name_len(0, pkt, p, max, &name_part_len, &name_len);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Allocate memory for the name */\n\trr->rdata.srv.target.ptr = (char*) pj_pool_alloc(pool, name_len);\n\trr->rdata.srv.target.slen = 0;\n\n\t/* Get the name */\n\tstatus = get_name(0, pkt, p, max, &rr->rdata.srv.target);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\tp += name_part_len;\n\n    } else {\n\t/* Copy the raw data */\n\trr->data = pj_pool_alloc(pool, rr->rdlength);\n\tpj_memcpy(rr->data, p, rr->rdlength);\n\n\tp += rr->rdlength;\n    }\n\n    *parsed_len = (int)(p - start);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Parse raw DNS packet into DNS packet structure.\n */\nPJ_DEF(pj_status_t) pj_dns_parse_packet( pj_pool_t *pool,\n\t\t\t\t  \t const void *packet,\n\t\t\t\t\t unsigned size,\n\t\t\t\t\t pj_dns_parsed_packet **p_res)\n{\n    pj_dns_parsed_packet *res;\n    const pj_uint8_t *start, *end;\n    pj_status_t status;\n    unsigned i;\n\n    /* Sanity checks */\n    PJ_ASSERT_RETURN(pool && packet && size && p_res, PJ_EINVAL);\n\n    /* Packet size must be at least as big as the header */\n    if (size < sizeof(pj_dns_hdr))\n\treturn PJLIB_UTIL_EDNSINSIZE;\n\n    /* Create the structure */\n    res = PJ_POOL_ZALLOC_T(pool, pj_dns_parsed_packet);\n\n    /* Copy the DNS header, and convert endianness to host byte order */\n    pj_memcpy(&res->hdr, packet, sizeof(pj_dns_hdr));\n    res->hdr.id\t      = pj_ntohs(res->hdr.id);\n    res->hdr.flags    = pj_ntohs(res->hdr.flags);\n    res->hdr.qdcount  = pj_ntohs(res->hdr.qdcount);\n    res->hdr.anscount = pj_ntohs(res->hdr.anscount);\n    res->hdr.nscount  = pj_ntohs(res->hdr.nscount);\n    res->hdr.arcount  = pj_ntohs(res->hdr.arcount);\n\n    /* Mark start and end of payload */\n    start = ((const pj_uint8_t*)packet) + sizeof(pj_dns_hdr);\n    end = ((const pj_uint8_t*)packet) + size;\n\n    /* Parse query records (if any).\n     */\n    if (res->hdr.qdcount) {\n\tres->q = (pj_dns_parsed_query*)\n\t\t pj_pool_zalloc(pool, res->hdr.qdcount *\n\t\t\t\t      sizeof(pj_dns_parsed_query));\n\tfor (i=0; i<res->hdr.qdcount; ++i) {\n\t    int parsed_len = 0;\n\t    \n\t    status = parse_query(&res->q[i], pool, (const pj_uint8_t*)packet, \n\t    \t\t\t start, end, &parsed_len);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    start += parsed_len;\n\t}\n    }\n\n    /* Parse answer, if any */\n    if (res->hdr.anscount) {\n\tres->ans = (pj_dns_parsed_rr*)\n\t\t   pj_pool_zalloc(pool, res->hdr.anscount * \n\t\t\t\t\tsizeof(pj_dns_parsed_rr));\n\n\tfor (i=0; i<res->hdr.anscount; ++i) {\n\t    int parsed_len;\n\n\t    status = parse_rr(&res->ans[i], pool, (const pj_uint8_t*)packet, \n\t    \t\t      start, end, &parsed_len);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    start += parsed_len;\n\t}\n    }\n\n    /* Parse authoritative NS records, if any */\n    if (res->hdr.nscount) {\n\tres->ns = (pj_dns_parsed_rr*)\n\t\t  pj_pool_zalloc(pool, res->hdr.nscount *\n\t\t\t\t       sizeof(pj_dns_parsed_rr));\n\n\tfor (i=0; i<res->hdr.nscount; ++i) {\n\t    int parsed_len;\n\n\t    status = parse_rr(&res->ns[i], pool, (const pj_uint8_t*)packet, \n\t    \t\t      start, end, &parsed_len);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    start += parsed_len;\n\t}\n    }\n\n    /* Parse additional RR answer, if any */\n    if (res->hdr.arcount) {\n\tres->arr = (pj_dns_parsed_rr*)\n\t\t   pj_pool_zalloc(pool, res->hdr.arcount *\n\t\t\t\t\tsizeof(pj_dns_parsed_rr));\n\n\tfor (i=0; i<res->hdr.arcount; ++i) {\n\t    int parsed_len;\n\n\t    status = parse_rr(&res->arr[i], pool, (const pj_uint8_t*)packet, \n\t    \t\t      start, end, &parsed_len);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    start += parsed_len;\n\t}\n    }\n\n    /* Looks like everything is okay */\n    *p_res = res;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Perform name compression scheme.\n * If a name is already in the nametable, when no need to duplicate\n * the string with the pool, but rather just use the pointer there.\n */\nstatic void apply_name_table( unsigned *count,\n\t\t\t      pj_str_t nametable[],\n\t\t    \t      const pj_str_t *src,\n\t\t\t      pj_pool_t *pool,\n\t\t\t      pj_str_t *dst)\n{\n    unsigned i;\n\n    /* Scan strings in nametable */\n    for (i=0; i<*count; ++i) {\n\tif (pj_stricmp(&nametable[i], src) == 0)\n\t    break;\n    }\n\n    /* If name is found in nametable, use the pointer in the nametable */\n    if (i != *count) {\n\tdst->ptr = nametable[i].ptr;\n\tdst->slen = nametable[i].slen;\n\treturn;\n    }\n\n    /* Otherwise duplicate the string, and insert new name in nametable */\n    pj_strdup(pool, dst, src);\n\n    if (*count < PJ_DNS_MAX_NAMES_IN_NAMETABLE) {\n\tnametable[*count].ptr = dst->ptr;\n\tnametable[*count].slen = dst->slen;\n\n\t++(*count);\n    }\n}\n\nstatic void copy_query(pj_pool_t *pool, pj_dns_parsed_query *dst,\n\t\t       const pj_dns_parsed_query *src,\n\t\t       unsigned *nametable_count,\n\t\t       pj_str_t nametable[])\n{\n    pj_memcpy(dst, src, sizeof(*src));\n    apply_name_table(nametable_count, nametable, &src->name, pool, &dst->name);\n}\n\n\nstatic void copy_rr(pj_pool_t *pool, pj_dns_parsed_rr *dst,\n\t\t    const pj_dns_parsed_rr *src,\n\t\t    unsigned *nametable_count,\n\t\t    pj_str_t nametable[])\n{\n    pj_memcpy(dst, src, sizeof(*src));\n    apply_name_table(nametable_count, nametable, &src->name, pool, &dst->name);\n\n    if (src->data) {\n\tdst->data = pj_pool_alloc(pool, src->rdlength);\n\tpj_memcpy(dst->data, src->data, src->rdlength);\n    }\n\n    if (src->type == PJ_DNS_TYPE_SRV) {\n\tapply_name_table(nametable_count, nametable, &src->rdata.srv.target, \n\t\t\t pool, &dst->rdata.srv.target);\n    } else if (src->type == PJ_DNS_TYPE_A) {\n\tdst->rdata.a.ip_addr.s_addr =  src->rdata.a.ip_addr.s_addr;\n    } else if (src->type == PJ_DNS_TYPE_AAAA) {\n\tpj_memcpy(&dst->rdata.aaaa.ip_addr, &src->rdata.aaaa.ip_addr,\n\t\t  sizeof(pj_in6_addr));\n    } else if (src->type == PJ_DNS_TYPE_CNAME) {\n\tpj_strdup(pool, &dst->rdata.cname.name, &src->rdata.cname.name);\n    } else if (src->type == PJ_DNS_TYPE_NS) {\n\tpj_strdup(pool, &dst->rdata.ns.name, &src->rdata.ns.name);\n    } else if (src->type == PJ_DNS_TYPE_PTR) {\n\tpj_strdup(pool, &dst->rdata.ptr.name, &src->rdata.ptr.name);\n    }\n}\n\n/*\n * Duplicate DNS packet.\n */\nPJ_DEF(void) pj_dns_packet_dup(pj_pool_t *pool,\n\t\t\t       const pj_dns_parsed_packet*p,\n\t\t\t       unsigned options,\n\t\t\t       pj_dns_parsed_packet **p_dst)\n{\n    pj_dns_parsed_packet *dst;\n    unsigned nametable_count = 0;\n#if PJ_DNS_MAX_NAMES_IN_NAMETABLE\n    pj_str_t nametable[PJ_DNS_MAX_NAMES_IN_NAMETABLE];\n#else\n    pj_str_t *nametable = NULL;\n#endif\n    unsigned i;\n\n    PJ_ASSERT_ON_FAIL(pool && p && p_dst, return);\n\n    /* Create packet and copy header */\n    *p_dst = dst = PJ_POOL_ZALLOC_T(pool, pj_dns_parsed_packet);\n    pj_memcpy(&dst->hdr, &p->hdr, sizeof(p->hdr));\n\n    /* Initialize section counts in the target packet to zero.\n     * If memory allocation fails during copying process, the target packet\n     * should have a correct section counts.\n     */\n    dst->hdr.qdcount = 0;\n    dst->hdr.anscount = 0;\n    dst->hdr.nscount = 0;\n    dst->hdr.arcount = 0;\n\t\n\n    /* Copy query section */\n    if (p->hdr.qdcount && (options & PJ_DNS_NO_QD)==0) {\n\tdst->q = (pj_dns_parsed_query*)\n\t\t pj_pool_alloc(pool, p->hdr.qdcount * \n\t\t\t\t     sizeof(pj_dns_parsed_query));\n\tfor (i=0; i<p->hdr.qdcount; ++i) {\n\t    copy_query(pool, &dst->q[i], &p->q[i], \n\t\t       &nametable_count, nametable);\n\t    ++dst->hdr.qdcount;\n\t}\n    }\n\n    /* Copy answer section */\n    if (p->hdr.anscount && (options & PJ_DNS_NO_ANS)==0) {\n\tdst->ans = (pj_dns_parsed_rr*)\n\t\t   pj_pool_alloc(pool, p->hdr.anscount * \n\t\t\t\t       sizeof(pj_dns_parsed_rr));\n\tfor (i=0; i<p->hdr.anscount; ++i) {\n\t    copy_rr(pool, &dst->ans[i], &p->ans[i],\n\t\t    &nametable_count, nametable);\n\t    ++dst->hdr.anscount;\n\t}\n    }\n\n    /* Copy NS section */\n    if (p->hdr.nscount && (options & PJ_DNS_NO_NS)==0) {\n\tdst->ns = (pj_dns_parsed_rr*)\n\t\t  pj_pool_alloc(pool, p->hdr.nscount * \n\t\t\t\t      sizeof(pj_dns_parsed_rr));\n\tfor (i=0; i<p->hdr.nscount; ++i) {\n\t    copy_rr(pool, &dst->ns[i], &p->ns[i],\n\t\t    &nametable_count, nametable);\n\t    ++dst->hdr.nscount;\n\t}\n    }\n\n    /* Copy additional info section */\n    if (p->hdr.arcount && (options & PJ_DNS_NO_AR)==0) {\n\tdst->arr = (pj_dns_parsed_rr*)\n\t\t   pj_pool_alloc(pool, p->hdr.arcount * \n\t\t\t\t       sizeof(pj_dns_parsed_rr));\n\tfor (i=0; i<p->hdr.arcount; ++i) {\n\t    copy_rr(pool, &dst->arr[i], &p->arr[i],\n\t\t    &nametable_count, nametable);\n\t    ++dst->hdr.arcount;\n\t}\n    }\n}\n\n\nPJ_DEF(void) pj_dns_init_srv_rr( pj_dns_parsed_rr *rec,\n\t\t\t\t const pj_str_t *res_name,\n\t\t\t\t unsigned dnsclass,\n\t\t\t\t unsigned ttl,\n\t\t\t\t unsigned prio,\n\t\t\t\t unsigned weight,\n\t\t\t\t unsigned port,\n\t\t\t\t const pj_str_t *target)\n{\n    pj_bzero(rec, sizeof(*rec));\n    rec->name = *res_name;\n    rec->type = PJ_DNS_TYPE_SRV;\n    rec->dnsclass = (pj_uint16_t) dnsclass;\n    rec->ttl = ttl;\n    rec->rdata.srv.prio = (pj_uint16_t) prio;\n    rec->rdata.srv.weight = (pj_uint16_t) weight;\n    rec->rdata.srv.port = (pj_uint16_t) port;\n    rec->rdata.srv.target = *target;\n}\n\n\nPJ_DEF(void) pj_dns_init_cname_rr( pj_dns_parsed_rr *rec,\n\t\t\t\t   const pj_str_t *res_name,\n\t\t\t\t   unsigned dnsclass,\n\t\t\t\t   unsigned ttl,\n\t\t\t\t   const pj_str_t *name)\n{\n    pj_bzero(rec, sizeof(*rec));\n    rec->name = *res_name;\n    rec->type = PJ_DNS_TYPE_CNAME;\n    rec->dnsclass = (pj_uint16_t) dnsclass;\n    rec->ttl = ttl;\n    rec->rdata.cname.name = *name;\n}\n\n\nPJ_DEF(void) pj_dns_init_a_rr( pj_dns_parsed_rr *rec,\n\t\t\t       const pj_str_t *res_name,\n\t\t\t       unsigned dnsclass,\n\t\t\t       unsigned ttl,\n\t\t\t       const pj_in_addr *ip_addr)\n{\n    pj_bzero(rec, sizeof(*rec));\n    rec->name = *res_name;\n    rec->type = PJ_DNS_TYPE_A;\n    rec->dnsclass = (pj_uint16_t) dnsclass;\n    rec->ttl = ttl;\n    rec->rdata.a.ip_addr = *ip_addr;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/dns_dump.c",
    "content": "/* $Id: dns_dump.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/dns.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/string.h>\n\n#define THIS_FILE   \"dns_dump.c\"\n#define LEVEL\t    3\n\nstatic const char *spell_ttl(char *buf, int size, unsigned ttl)\n{\n#define DAY\t(3600*24)\n#define HOUR\t(3600)\n#define MINUTE\t(60)\n\n    char *p = buf;\n    int len;\n\n    if (ttl > DAY) {\n\tlen = pj_ansi_snprintf(p, size, \"%dd \", ttl/DAY);\n\tif (len < 1 || len >= size)\n\t    return \"-err-\";\n\tsize -= len;\n\tp += len;\n\tttl %= DAY;\n    }\n\n    if (ttl > HOUR) {\n\tlen = pj_ansi_snprintf(p, size, \"%dh \", ttl/HOUR);\n\tif (len < 1 || len >= size)\n\t    return \"-err-\";\n\tsize -= len;\n\tp += len;\n\tttl %= HOUR;\n    }\n\n    if (ttl > MINUTE) {\n\tlen = pj_ansi_snprintf(p, size, \"%dm \", ttl/MINUTE);\n\tif (len < 1 || len >= size)\n\t    return \"-err-\";\n\tsize -= len;\n\tp += len;\n\tttl %= MINUTE;\n    }\n\n    if (ttl > 0) {\n\tlen = pj_ansi_snprintf(p, size, \"%ds \", ttl);\n\tif (len < 1 || len >= size)\n\t    return \"-err-\";\n\tsize -= len;\n\tp += len;\n\tttl = 0;\n    }\n\n    *p = '\\0';\n    return buf;\n}\n\n\nstatic void dump_query(unsigned index, const pj_dns_parsed_query *q)\n{\n    PJ_LOG(3,(THIS_FILE, \" %d. Name: %.*s\", \n\t\t\t index, (int)q->name.slen, q->name.ptr));\n    PJ_LOG(3,(THIS_FILE, \"    Type: %s (%d)\", \n\t\t\t pj_dns_get_type_name(q->type), q->type));\n    PJ_LOG(3,(THIS_FILE, \"    Class: %s (%d)\", \n\t\t         (q->dnsclass==1 ? \"IN\" : \"<Unknown>\"), q->dnsclass));\n}\n\nstatic void dump_answer(unsigned index, const pj_dns_parsed_rr *rr)\n{\n    const pj_str_t root_name = { \"<Root>\", 6 };\n    const pj_str_t *name = &rr->name;\n    char ttl_words[32];\n\n    if (name->slen == 0)\n\tname = &root_name;\n\n    PJ_LOG(3,(THIS_FILE, \" %d. %s record (type=%d)\", \n\t\t\t index, pj_dns_get_type_name(rr->type),\n\t\t\trr->type));\n    PJ_LOG(3,(THIS_FILE, \"    Name: %.*s\", (int)name->slen, name->ptr));\n    PJ_LOG(3,(THIS_FILE, \"    TTL: %u (%s)\", rr->ttl, \n\t\t\t  spell_ttl(ttl_words, sizeof(ttl_words), rr->ttl)));\n    PJ_LOG(3,(THIS_FILE, \"    Data length: %u\", rr->rdlength));\n\n    if (rr->type == PJ_DNS_TYPE_SRV) {\n\tPJ_LOG(3,(THIS_FILE, \"    SRV: prio=%d, weight=%d %.*s:%d\", \n\t\t\t     rr->rdata.srv.prio, rr->rdata.srv.weight,\n\t\t\t     (int)rr->rdata.srv.target.slen, \n\t\t\t     rr->rdata.srv.target.ptr,\n\t\t\t     rr->rdata.srv.port));\n    } else if (rr->type == PJ_DNS_TYPE_CNAME ||\n\t       rr->type == PJ_DNS_TYPE_NS ||\n\t       rr->type == PJ_DNS_TYPE_PTR) \n    {\n\tPJ_LOG(3,(THIS_FILE, \"    Name: %.*s\",\n\t\t  (int)rr->rdata.cname.name.slen,\n\t\t  rr->rdata.cname.name.ptr));\n    } else if (rr->type == PJ_DNS_TYPE_A) {\n\tPJ_LOG(3,(THIS_FILE, \"    IP address: %s\",\n\t\t  pj_inet_ntoa(rr->rdata.a.ip_addr)));\n    } else if (rr->type == PJ_DNS_TYPE_AAAA) {\n\tchar addr[PJ_INET6_ADDRSTRLEN];\n\tPJ_LOG(3,(THIS_FILE, \"    IPv6 address: %s\",\n\t\t  pj_inet_ntop2(pj_AF_INET6(), &rr->rdata.aaaa.ip_addr,\n\t\t\t        addr, sizeof(addr))));\n    }\n}\n\n\nPJ_DEF(void) pj_dns_dump_packet(const pj_dns_parsed_packet *res)\n{\n    unsigned i;\n\n    PJ_ASSERT_ON_FAIL(res != NULL, return);\n\n    /* Header part */\n    PJ_LOG(3,(THIS_FILE, \"Domain Name System packet (%s):\",\n\t\t(PJ_DNS_GET_QR(res->hdr.flags) ? \"response\" : \"query\")));\n    PJ_LOG(3,(THIS_FILE, \" Transaction ID: %d\", res->hdr.id));\n    PJ_LOG(3,(THIS_FILE, \n\t      \" Flags: opcode=%d, authoritative=%d, truncated=%d, rcode=%d\",\n\t\t PJ_DNS_GET_OPCODE(res->hdr.flags),\n\t\t PJ_DNS_GET_AA(res->hdr.flags),\n\t\t PJ_DNS_GET_TC(res->hdr.flags),\n\t\t PJ_DNS_GET_RCODE(res->hdr.flags)));\n    PJ_LOG(3,(THIS_FILE, \" Nb of queries: %d\", res->hdr.qdcount));\n    PJ_LOG(3,(THIS_FILE, \" Nb of answer RR: %d\", res->hdr.anscount));\n    PJ_LOG(3,(THIS_FILE, \" Nb of authority RR: %d\", res->hdr.nscount));\n    PJ_LOG(3,(THIS_FILE, \" Nb of additional RR: %d\", res->hdr.arcount));\n    PJ_LOG(3,(THIS_FILE, \"\"));\n\n    /* Dump queries */\n    if (res->hdr.qdcount) {\n\tPJ_LOG(3,(THIS_FILE, \" Queries:\"));\n\n\tfor (i=0; i<res->hdr.qdcount; ++i) {\n\t    dump_query(i, &res->q[i]);\n\t}\n\tPJ_LOG(3,(THIS_FILE, \"\"));\n    }\n\n    /* Dump answers */\n    if (res->hdr.anscount) {\n\tPJ_LOG(3,(THIS_FILE, \" Answers RR:\"));\n\n\tfor (i=0; i<res->hdr.anscount; ++i) {\n\t    dump_answer(i, &res->ans[i]);\n\t}\n\tPJ_LOG(3,(THIS_FILE, \"\"));\n    }\n\n    /* Dump NS sections */\n    if (res->hdr.nscount) {\n\tPJ_LOG(3,(THIS_FILE, \" NS Authority RR:\"));\n\n\tfor (i=0; i<res->hdr.nscount; ++i) {\n\t    dump_answer(i, &res->ns[i]);\n\t}\n\tPJ_LOG(3,(THIS_FILE, \"\"));\n    }\n\n    /* Dump Additional info sections */\n    if (res->hdr.arcount) {\n\tPJ_LOG(3,(THIS_FILE, \" Additional Info RR:\"));\n\n\tfor (i=0; i<res->hdr.arcount; ++i) {\n\t    dump_answer(i, &res->arr[i]);\n\t}\n\tPJ_LOG(3,(THIS_FILE, \"\"));\n    }\n\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/dns_server.c",
    "content": "/* $Id: dns_server.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/dns_server.h>\n#include <pjlib-util/errno.h>\n#include <pj/activesock.h>\n#include <pj/assert.h>\n#include <pj/list.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#define THIS_FILE   \"dns_server.c\"\n#define MAX_ANS\t    16\n#define MAX_PKT\t    1500\n#define MAX_LABEL   32\n\nstruct label_tab\n{\n    unsigned count;\n\n    struct {\n\tunsigned pos;\n\tpj_str_t label;\n    } a[MAX_LABEL];\n};\n\nstruct rr\n{\n    PJ_DECL_LIST_MEMBER(struct rr);\n    pj_dns_parsed_rr\trec;\n};\n\n\nstruct pj_dns_server\n{\n    pj_pool_t\t\t*pool;\n    pj_pool_factory\t*pf;\n    pj_activesock_t\t*asock;\n    pj_ioqueue_op_key_t\t send_key;\n    struct rr\t\t rr_list;\n};\n\n\nstatic pj_bool_t on_data_recvfrom(pj_activesock_t *asock,\n\t\t\t\t  void *data,\n\t\t\t\t  pj_size_t size,\n\t\t\t\t  const pj_sockaddr_t *src_addr,\n\t\t\t\t  int addr_len,\n\t\t\t\t  pj_status_t status);\n\n\nPJ_DEF(pj_status_t) pj_dns_server_create( pj_pool_factory *pf,\n\t\t\t\t          pj_ioqueue_t *ioqueue,\n\t\t\t\t\t  int af,\n\t\t\t\t\t  unsigned port,\n\t\t\t\t\t  unsigned flags,\n\t\t\t\t          pj_dns_server **p_srv)\n{\n    pj_pool_t *pool;\n    pj_dns_server *srv;\n    pj_sockaddr sock_addr;\n    pj_activesock_cb sock_cb;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pf && ioqueue && p_srv && flags==0, PJ_EINVAL);\n    PJ_ASSERT_RETURN(af==pj_AF_INET() || af==pj_AF_INET6(), PJ_EINVAL);\n    \n    pool = pj_pool_create(pf, \"dnsserver\", 256, 256, NULL);\n    srv = (pj_dns_server*) PJ_POOL_ZALLOC_T(pool, pj_dns_server);\n    srv->pool = pool;\n    srv->pf = pf;\n    pj_list_init(&srv->rr_list);\n\n    pj_bzero(&sock_addr, sizeof(sock_addr));\n    sock_addr.addr.sa_family = (pj_uint16_t)af;\n    pj_sockaddr_set_port(&sock_addr, (pj_uint16_t)port);\n    \n    pj_bzero(&sock_cb, sizeof(sock_cb));\n    sock_cb.on_data_recvfrom = &on_data_recvfrom;\n\n    status = pj_activesock_create_udp(pool, &sock_addr, NULL, ioqueue,\n\t\t\t\t      &sock_cb, srv, &srv->asock, NULL);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    pj_ioqueue_op_key_init(&srv->send_key, sizeof(srv->send_key));\n\n    status = pj_activesock_start_recvfrom(srv->asock, pool, MAX_PKT, 0);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    *p_srv = srv;\n    return PJ_SUCCESS;\n\non_error:\n    pj_dns_server_destroy(srv);\n    return status;\n}\n\n\nPJ_DEF(pj_status_t) pj_dns_server_destroy(pj_dns_server *srv)\n{\n    PJ_ASSERT_RETURN(srv, PJ_EINVAL);\n\n    if (srv->asock) {\n\tpj_activesock_close(srv->asock);\n\tsrv->asock = NULL;\n    }\n\n    if (srv->pool) {\n\tpj_pool_t *pool = srv->pool;\n\tsrv->pool = NULL;\n\tpj_pool_release(pool);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nstatic struct rr* find_rr( pj_dns_server *srv,\n\t\t\t   unsigned dns_class,\n\t\t\t   unsigned type\t/* pj_dns_type */,\n\t\t\t   const pj_str_t *name)\n{\n    struct rr *r;\n\n    r = srv->rr_list.next;\n    while (r != &srv->rr_list) {\n\tif (r->rec.dnsclass == dns_class && r->rec.type == type && \n\t    pj_stricmp(&r->rec.name, name)==0)\n\t{\n\t    return r;\n\t}\n\tr = r->next;\n    }\n\n    return NULL;\n}\n\n\nPJ_DEF(pj_status_t) pj_dns_server_add_rec( pj_dns_server *srv,\n\t\t\t\t\t   unsigned count,\n\t\t\t\t\t   const pj_dns_parsed_rr rr_param[])\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(srv && count && rr_param, PJ_EINVAL);\n\n    for (i=0; i<count; ++i) {\n\tstruct rr *rr;\n\n\tPJ_ASSERT_RETURN(find_rr(srv, rr_param[i].dnsclass, rr_param[i].type,\n\t\t\t\t &rr_param[i].name) == NULL,\n\t\t\t PJ_EEXISTS);\n\n\trr = (struct rr*) PJ_POOL_ZALLOC_T(srv->pool, struct rr);\n\tpj_memcpy(&rr->rec, &rr_param[i], sizeof(pj_dns_parsed_rr));\n\n\tpj_list_push_back(&srv->rr_list, rr);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_dns_server_del_rec( pj_dns_server *srv,\n\t\t\t\t\t   int dns_class,\n\t\t\t\t\t   pj_dns_type type,\n\t\t\t\t\t   const pj_str_t *name)\n{\n    struct rr *rr;\n\n    PJ_ASSERT_RETURN(srv && type && name, PJ_EINVAL);\n\n    rr = find_rr(srv, dns_class, type, name);\n    if (!rr)\n\treturn PJ_ENOTFOUND;\n\n    pj_list_erase(rr);\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void write16(pj_uint8_t *p, pj_uint16_t val)\n{\n    p[0] = (pj_uint8_t)(val >> 8);\n    p[1] = (pj_uint8_t)(val & 0xFF);\n}\n\nstatic void write32(pj_uint8_t *p, pj_uint32_t val)\n{\n    val = pj_htonl(val);\n    pj_memcpy(p, &val, 4);\n}\n\nstatic int print_name(pj_uint8_t *pkt, int size,\n\t\t      pj_uint8_t *pos, const pj_str_t *name,\n\t\t      struct label_tab *tab)\n{\n    pj_uint8_t *p = pos;\n    const char *endlabel, *endname;\n    unsigned i;\n    pj_str_t label;\n\n    /* Check if name is in the table */\n    for (i=0; i<tab->count; ++i) {\n\tif (pj_strcmp(&tab->a[i].label, name)==0)\n\t    break;\n    }\n\n    if (i != tab->count) {\n\twrite16(p, (pj_uint16_t)(tab->a[i].pos | (0xc0 << 8)));\n\treturn 2;\n    } else {\n\tif (tab->count < MAX_LABEL) {\n\t    tab->a[tab->count].pos = (unsigned)(p-pkt);\n\t    tab->a[tab->count].label.ptr = (char*)(p+1);\n\t    tab->a[tab->count].label.slen = name->slen;\n\t    ++tab->count;\n\t}\n    }\n\n    endlabel = name->ptr;\n    endname = name->ptr + name->slen;\n\n    label.ptr = (char*)name->ptr;\n\n    while (endlabel != endname) {\n\n\twhile (endlabel != endname && *endlabel != '.')\n\t    ++endlabel;\n\n\tlabel.slen = (endlabel - label.ptr);\n\n\tif (size < label.slen+1)\n\t    return -1;\n\n\t*p = (pj_uint8_t)label.slen;\n\tpj_memcpy(p+1, label.ptr, label.slen);\n\n\tsize -= (int)(label.slen+1);\n\tp += (label.slen+1);\n\n\tif (endlabel != endname && *endlabel == '.')\n\t    ++endlabel;\n\tlabel.ptr = (char*)endlabel;\n    }\n\n    if (size == 0)\n\treturn -1;\n\n    *p++ = '\\0';\n\n    return (int)(p-pos);\n}\n\nstatic int print_rr(pj_uint8_t *pkt, int size, pj_uint8_t *pos,\n\t\t    const pj_dns_parsed_rr *rr, struct label_tab *tab)\n{\n    pj_uint8_t *p = pos;\n    int len;\n\n    len = print_name(pkt, size, pos, &rr->name, tab);\n    if (len < 0)\n\treturn -1;\n\n    p += len;\n    size -= len;\n\n    if (size < 8)\n\treturn -1;\n\n    pj_assert(rr->dnsclass == 1);\n\n    write16(p+0, (pj_uint16_t)rr->type);\t/* type\t    */\n    write16(p+2, (pj_uint16_t)rr->dnsclass);\t/* class    */\n    write32(p+4, rr->ttl);\t\t\t/* TTL\t    */\n\n    p += 8;\n    size -= 8;\n\n    if (rr->type == PJ_DNS_TYPE_A) {\n\n\tif (size < 6)\n\t    return -1;\n\n\t/* RDLEN is 4 */\n\twrite16(p, 4);\n\n\t/* Address */\n\tpj_memcpy(p+2, &rr->rdata.a.ip_addr, 4);\n\n\tp += 6;\n\tsize -= 6;\n\n    } else if (rr->type == PJ_DNS_TYPE_CNAME ||\n\t       rr->type == PJ_DNS_TYPE_NS ||\n\t       rr->type == PJ_DNS_TYPE_PTR) {\n\n\tif (size < 4)\n\t    return -1;\n\n\tlen = print_name(pkt, size-2, p+2, &rr->rdata.cname.name, tab);\n\tif (len < 0)\n\t    return -1;\n\n\twrite16(p, (pj_uint16_t)len);\n\n\tp += (len + 2);\n\tsize -= (len + 2);\n\n    } else if (rr->type == PJ_DNS_TYPE_SRV) {\n\n\tif (size < 10)\n\t    return -1;\n\n\twrite16(p+2, rr->rdata.srv.prio);   /* Priority */\n\twrite16(p+4, rr->rdata.srv.weight); /* Weight */\n\twrite16(p+6, rr->rdata.srv.port);   /* Port */\n\n\t/* Target */\n\tlen = print_name(pkt, size-8, p+8, &rr->rdata.srv.target, tab);\n\tif (len < 0)\n\t    return -1;\n\n\t/* RDLEN */\n\twrite16(p, (pj_uint16_t)(len + 6));\n\n\tp += (len + 8);\n\tsize -= (len + 8);\n\n    } else {\n\tpj_assert(!\"Not supported\");\n\treturn -1;\n    }\n\n    return (int)(p-pos);\n}\n\nstatic int print_packet(const pj_dns_parsed_packet *rec, pj_uint8_t *pkt,\n\t\t\tint size)\n{\n    pj_uint8_t *p = pkt;\n    struct label_tab tab;\n    int i, len;\n\n    tab.count = 0;\n\n    pj_assert(sizeof(pj_dns_hdr)==12);\n    if (size < (int)sizeof(pj_dns_hdr))\n\treturn -1;\n\n    /* Initialize header */\n    write16(p+0,  rec->hdr.id);\n    write16(p+2,  rec->hdr.flags);\n    write16(p+4,  rec->hdr.qdcount);\n    write16(p+6,  rec->hdr.anscount);\n    write16(p+8,  rec->hdr.nscount);\n    write16(p+10, rec->hdr.arcount);\n\n    p = pkt + sizeof(pj_dns_hdr);\n    size -= sizeof(pj_dns_hdr);\n\n    /* Print queries */\n    for (i=0; i<rec->hdr.qdcount; ++i) {\n\n\tlen = print_name(pkt, size, p, &rec->q[i].name, &tab);\n\tif (len < 0)\n\t    return -1;\n\n\tp += len;\n\tsize -= len;\n\n\tif (size < 4)\n\t    return -1;\n\n\t/* Set type */\n\twrite16(p+0, (pj_uint16_t)rec->q[i].type);\n\n\t/* Set class (IN=1) */\n\tpj_assert(rec->q[i].dnsclass == 1);\n\twrite16(p+2, rec->q[i].dnsclass);\n\n\tp += 4;\n    }\n\n    /* Print answers */\n    for (i=0; i<rec->hdr.anscount; ++i) {\n\tlen = print_rr(pkt, size, p, &rec->ans[i], &tab);\n\tif (len < 0)\n\t    return -1;\n\n\tp += len;\n\tsize -= len;\n    }\n\n    /* Print NS records */\n    for (i=0; i<rec->hdr.nscount; ++i) {\n\tlen = print_rr(pkt, size, p, &rec->ns[i], &tab);\n\tif (len < 0)\n\t    return -1;\n\n\tp += len;\n\tsize -= len;\n    }\n\n    /* Print additional records */\n    for (i=0; i<rec->hdr.arcount; ++i) {\n\tlen = print_rr(pkt, size, p, &rec->arr[i], &tab);\n\tif (len < 0)\n\t    return -1;\n\n\tp += len;\n\tsize -= len;\n    }\n\n    return (int)(p - pkt);\n}\n\n\nstatic pj_bool_t on_data_recvfrom(pj_activesock_t *asock,\n\t\t\t\t  void *data,\n\t\t\t\t  pj_size_t size,\n\t\t\t\t  const pj_sockaddr_t *src_addr,\n\t\t\t\t  int addr_len,\n\t\t\t\t  pj_status_t status)\n{\n    pj_dns_server *srv;\n    pj_pool_t *pool;\n    pj_dns_parsed_packet *req;\n    pj_dns_parsed_packet ans;\n    struct rr *rr;\n    pj_ssize_t pkt_len;\n    unsigned i;\n\n    if (status != PJ_SUCCESS)\n\treturn PJ_TRUE;\n\n    srv = (pj_dns_server*) pj_activesock_get_user_data(asock);\n    pool = pj_pool_create(srv->pf, \"dnssrvrx\", 512, 256, NULL);\n\n    status = pj_dns_parse_packet(pool, data, (unsigned)size, &req);\n    if (status != PJ_SUCCESS) {\n\tchar addrinfo[PJ_INET6_ADDRSTRLEN+10];\n\tpj_sockaddr_print(src_addr, addrinfo, sizeof(addrinfo), 3);\n\tPJ_LOG(4,(THIS_FILE, \"Error parsing query from %s\", addrinfo));\n\tgoto on_return;\n    }\n\n    /* Init answer */\n    pj_bzero(&ans, sizeof(ans));\n    ans.hdr.id = req->hdr.id;\n    ans.hdr.qdcount = 1;\n    ans.q = (pj_dns_parsed_query*) PJ_POOL_ALLOC_T(pool, pj_dns_parsed_query);\n    pj_memcpy(ans.q, req->q, sizeof(pj_dns_parsed_query));\n\n    if (req->hdr.qdcount != 1) {\n\tans.hdr.flags = PJ_DNS_SET_RCODE(PJ_DNS_RCODE_FORMERR);\n\tgoto send_pkt;\n    }\n\n    if (req->q[0].dnsclass != PJ_DNS_CLASS_IN) {\n\tans.hdr.flags = PJ_DNS_SET_RCODE(PJ_DNS_RCODE_NOTIMPL);\n\tgoto send_pkt;\n    }\n\n    /* Find the record */\n    rr = find_rr(srv, req->q->dnsclass, req->q->type, &req->q->name);\n    if (rr == NULL) {\n\tans.hdr.flags = PJ_DNS_SET_RCODE(PJ_DNS_RCODE_NXDOMAIN);\n\tgoto send_pkt;\n    }\n\n    /* Init answer record */\n    ans.hdr.anscount = 0;\n    ans.ans = (pj_dns_parsed_rr*)\n\t      pj_pool_calloc(pool, MAX_ANS, sizeof(pj_dns_parsed_rr));\n\n    /* DNS SRV query needs special treatment since it returns multiple\n     * records\n     */\n    if (req->q->type == PJ_DNS_TYPE_SRV) {\n\tstruct rr *r;\n\n\tr = srv->rr_list.next;\n\twhile (r != &srv->rr_list) {\n\t    if (r->rec.dnsclass == req->q->dnsclass && \n\t\tr->rec.type == PJ_DNS_TYPE_SRV && \n\t\tpj_stricmp(&r->rec.name, &req->q->name)==0 &&\n\t\tans.hdr.anscount < MAX_ANS)\n\t    {\n\t\tpj_memcpy(&ans.ans[ans.hdr.anscount], &r->rec,\n\t\t\t  sizeof(pj_dns_parsed_rr));\n\t\t++ans.hdr.anscount;\n\t    }\n\t    r = r->next;\n\t}\n    } else {\n\t/* Otherwise just copy directly from the server record */\n\tpj_memcpy(&ans.ans[ans.hdr.anscount], &rr->rec,\n\t\t\t  sizeof(pj_dns_parsed_rr));\n\t++ans.hdr.anscount;\n    }\n\n    /* For each CNAME entry, add A entry */\n    for (i=0; i<ans.hdr.anscount && ans.hdr.anscount < MAX_ANS; ++i) {\n\tif (ans.ans[i].type == PJ_DNS_TYPE_CNAME) {\n\t    struct rr *r;\n\n\t    r = find_rr(srv, ans.ans[i].dnsclass, PJ_DNS_TYPE_A,\n\t\t        &ans.ans[i].name);\n\t    pj_memcpy(&ans.ans[ans.hdr.anscount], &r->rec,\n\t\t\t      sizeof(pj_dns_parsed_rr));\n\t    ++ans.hdr.anscount;\n\t}\n    }\n\nsend_pkt:\n    pkt_len = print_packet(&ans, (pj_uint8_t*)data, MAX_PKT);\n    if (pkt_len < 1) {\n\tPJ_LOG(4,(THIS_FILE, \"Error: answer too large\"));\n\tgoto on_return;\n    }\n\n    status = pj_activesock_sendto(srv->asock, &srv->send_key, data, &pkt_len,\n\t\t\t\t  0, src_addr, addr_len);\n    if (status != PJ_SUCCESS && status != PJ_EPENDING) {\n\tPJ_LOG(4,(THIS_FILE, \"Error sending answer, status=%d\", status));\n\tgoto on_return;\n    }\n\non_return:\n    pj_pool_release(pool);\n    return PJ_TRUE;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/errno.c",
    "content": "/* $Id: errno.c 4440 2013-03-14 07:18:13Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/errno.h>\n#include <pjlib-util/types.h>\n#include <pj/assert.h>\n#include <pj/string.h>\n\n\n\n/* PJLIB_UTIL's own error codes/messages \n * MUST KEEP THIS ARRAY SORTED!!\n * Message must be limited to 64 chars!\n */\n#if defined(PJ_HAS_ERROR_STRING) && PJ_HAS_ERROR_STRING!=0\nstatic const struct \n{\n    int code;\n    const char *msg;\n} err_str[] = \n{\n    /* STUN errors */\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNRESOLVE,\t\"Unable to resolve STUN server\" ),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINMSGTYPE,\t\"Unknown STUN message type\" ),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINMSGLEN,\t\"Invalid STUN message length\" ),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINATTRLEN,\t\"STUN attribute length error\" ),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINATTRTYPE,\t\"Invalid STUN attribute type\" ),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNININDEX,\t\"Invalid STUN server/socket index\" ),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOBINDRES,\t\"No STUN binding response in the message\" ),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNRECVERRATTR,\t\"Received STUN error attribute\" ),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOMAP,\t\"No STUN mapped address attribute\" ),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOTRESPOND,\t\"Received no response from STUN server\" ),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNSYMMETRIC,\t\"Symetric NAT detected by STUN\" ),\n\n    /* XML errors */\n    PJ_BUILD_ERR( PJLIB_UTIL_EINXML,\t\t\"Invalid XML message\" ),\n\n    /* JSON errors */\n    PJ_BUILD_ERR( PJLIB_UTIL_EINJSON,\t\t\"Invalid JSON document\" ),\n\n    /* DNS errors */\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNSQRYTOOSMALL,\t\"DNS query packet buffer is too small\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNSINSIZE,\t\"Invalid DNS packet length\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNSINCLASS,\t\"Invalid DNS class\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNSINNAMEPTR,\t\"Invalid DNS name pointer\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNSINNSADDR,\t\"Invalid DNS nameserver address\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNSNONS,\t\t\"No nameserver is in DNS resolver\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNSNOWORKINGNS,\t\"No working DNS nameserver\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNSNOANSWERREC,\t\"No answer record in the DNS response\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNSINANSWER,\t\"Invalid DNS answer\"),\n\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_FORMERR,\t\"DNS \\\"Format error\\\"\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_SERVFAIL,\t\"DNS \\\"Server failure\\\"\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NXDOMAIN,\t\"DNS \\\"Name Error\\\"\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTIMPL,\t\"DNS \\\"Not Implemented\\\"\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_REFUSED,\t\"DNS \\\"Refused\\\"\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_YXDOMAIN,\t\"DNS \\\"The name exists\\\"\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_YXRRSET,\t\"DNS \\\"The RRset (name, type) exists\\\"\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NXRRSET,\t\"DNS \\\"The RRset (name, type) does not exist\\\"\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTAUTH,\t\"DNS \\\"Not authorized\\\"\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTZONE,\t\"DNS \\\"The zone specified is not a zone\\\"\"),\n\n    /* STUN */\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNTOOMANYATTR,\t\"Too many STUN attributes\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNUNKNOWNATTR,\t\"Unknown STUN attribute\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINADDRLEN,\t\"Invalid STUN socket address length\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNIPV6NOTSUPP,\t\"STUN IPv6 attribute not supported\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOTRESPONSE,\t\"Expecting STUN response message\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINVALIDID,\t\"STUN transaction ID mismatch\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOHANDLER,\t\"Unable to find STUN handler for the request\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNMSGINTPOS,\t\"Found non-FINGERPRINT attr. after MESSAGE-INTEGRITY\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNFINGERPOS,\t\"Found STUN attribute after FINGERPRINT\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOUSERNAME,\t\"Missing STUN USERNAME attribute\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNMSGINT,\t\"Missing/invalid STUN MESSAGE-INTEGRITY attribute\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNDUPATTR,\t\"Found duplicate STUN attribute\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOREALM,\t\"Missing STUN REALM attribute\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNONCE,\t\"Missing/stale STUN NONCE attribute value\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNTSXFAILED,\t\"STUN transaction terminates with failure\"),\n\n    /* HTTP Client */\n    PJ_BUILD_ERR( PJLIB_UTIL_EHTTPINURL,\t\"Invalid URL format\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EHTTPINPORT,\t\"Invalid URL port number\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EHTTPINCHDR,\t\"Incomplete response header received\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EHTTPINSBUF,\t\"Insufficient buffer\"),\n    PJ_BUILD_ERR( PJLIB_UTIL_EHTTPLOST,\t        \"Connection lost\"),\n\n    /* CLI */\n    PJ_BUILD_ERR( PJ_CLI_EEXIT,\t                \"Exit current session\"),\n    PJ_BUILD_ERR( PJ_CLI_EMISSINGARG,\t        \"Missing argument\"),\n    PJ_BUILD_ERR( PJ_CLI_ETOOMANYARGS,\t        \"Too many arguments\"),\n    PJ_BUILD_ERR( PJ_CLI_EINVARG,\t        \"Invalid argument\"),\n    PJ_BUILD_ERR( PJ_CLI_EBADNAME,\t        \"Command name already exists\"),\n    PJ_BUILD_ERR( PJ_CLI_EBADID,\t        \"Command id already exists\"),\n    PJ_BUILD_ERR( PJ_CLI_EBADXML,\t        \"Invalid XML format\"),\n    PJ_BUILD_ERR( PJ_CLI_ETELNETLOST,\t        \"Connection lost\"),\n};\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n\n/*\n * pjlib_util_strerror()\n */\npj_str_t pjlib_util_strerror(pj_status_t statcode, \n\t\t\t     char *buf, pj_size_t bufsize )\n{\n    pj_str_t errstr;\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n\n    if (statcode >= PJLIB_UTIL_ERRNO_START && \n\tstatcode < PJLIB_UTIL_ERRNO_START + PJ_ERRNO_SPACE_SIZE)\n    {\n\t/* Find the error in the table.\n\t * Use binary search!\n\t */\n\tint first = 0;\n\tint n = PJ_ARRAY_SIZE(err_str);\n\n\twhile (n > 0) {\n\t    int half = n/2;\n\t    int mid = first + half;\n\n\t    if (err_str[mid].code < statcode) {\n\t\tfirst = mid+1;\n\t\tn -= (half+1);\n\t    } else if (err_str[mid].code > statcode) {\n\t\tn = half;\n\t    } else {\n\t\tfirst = mid;\n\t\tbreak;\n\t    }\n\t}\n\n\n\tif (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {\n\t    pj_str_t msg;\n\t    \n\t    msg.ptr = (char*)err_str[first].msg;\n\t    msg.slen = pj_ansi_strlen(err_str[first].msg);\n\n\t    errstr.ptr = buf;\n\t    pj_strncpy_with_null(&errstr, &msg, bufsize);\n\t    return errstr;\n\n\t} \n    }\n\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n\n    /* Error not found. */\n    errstr.ptr = buf;\n    errstr.slen = pj_ansi_snprintf(buf, bufsize, \n\t\t\t\t   \"Unknown pjlib-util error %d\",\n\t\t\t\t   statcode);\n    if (errstr.slen < 1 || errstr.slen >= (pj_ssize_t)bufsize)\n\terrstr.slen = bufsize - 1;\n    return errstr;\n}\n\n\nPJ_DEF(pj_status_t) pjlib_util_init(void)\n{\n    pj_status_t status;\n    \n    status = pj_register_strerror(PJLIB_UTIL_ERRNO_START, \n\t\t\t\t  PJ_ERRNO_SPACE_SIZE, \n\t\t\t\t  &pjlib_util_strerror);\n    pj_assert(status == PJ_SUCCESS);\n\n    return PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/getopt.c",
    "content": "/* $Id: getopt.c 3550 2011-05-05 05:33:27Z nanang $ */\n/* \n * pj_getopt entry points\n *\n * modified by Mike Borella <mike_borella@mw.3com.com>\n */\n\n#include <pjlib-util/getopt.h>\n#include <pj/string.h>\n\n/* Internal only.  Users should not call this directly.  */\nstatic\nint _getopt_internal (int argc, char *const *argv,\n\t\t      const char *shortopts,\n\t\t      const struct pj_getopt_option *longopts, int *longind,\n\t\t      int long_only);\n\n/* pj_getopt_long and pj_getopt_long_only entry points for GNU pj_getopt.\n   Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Library General Public License as\n   published by the Free Software Foundation; either version 2 of the\n   License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Library General Public License for more details.\n\n   You should have received a copy of the GNU Library General Public\n   License along with the GNU C Library; see the file COPYING.LIB.  If not,\n   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n   Boston, MA 02111-1307, USA.  */\n\n\n/* Comment out all this code if we are using the GNU C Library, and are not\n   actually compiling the library itself.  This code is part of the GNU C\n   Library, but also included in many other GNU distributions.  Compiling\n   and linking in this code is a waste when using the GNU C library\n   (especially if it is a shared library).  Rather than having every GNU\n   program understand `configure --with-gnu-libc' and omit the object files,\n   it is simpler to just do this in the source for each such file.  */\n\n#   define GETOPT_INTERFACE_VERSION 2\n\n\nint\npj_getopt_long (int argc, char *const *argv, const char *options, \n\t     const struct pj_getopt_option *long_options, int *opt_index)\n{\n  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);\n}\n\n/* Like pj_getopt_long, but '-' as well as '--' can indicate a long option.\n   If an option that starts with '-' (not '--') doesn't match a long option,\n   but does match a short option, it is parsed as a short option\n   instead.  */\n \nint\npj_getopt (int argc, char * const * argv, const char * optstring)\n{\n  return _getopt_internal (argc, argv, optstring,\n\t\t\t   (const struct pj_getopt_option *) 0,\n\t\t\t   (int *) 0,\n\t\t\t   0);\n}\n\n\n#define _(msgid)\t(msgid)\n\n/* This version of `pj_getopt' appears to the caller like standard Unix `pj_getopt'\n   but it behaves differently for the user, since it allows the user\n   to intersperse the options with the other arguments.\n\n   As `pj_getopt' works, it permutes the elements of ARGV so that,\n   when it is done, all the options precede everything else.  Thus\n   all application programs are extended to handle flexible argument order.\n\n   Setting the environment variable POSIXLY_CORRECT disables permutation.\n   Then the behavior is completely standard.\n\n   GNU application programs can use a third alternative mode in which\n   they can distinguish the relative order of options and other arguments.  */\n\n/* For communication from `pj_getopt' to the caller.\n   When `pj_getopt' finds an option that takes an argument,\n   the argument value is returned here.\n   Also, when `ordering' is RETURN_IN_ORDER,\n   each non-option ARGV-element is returned here.  */\n\nchar *pj_optarg = NULL;\n\n/* Index in ARGV of the next element to be scanned.\n   This is used for communication to and from the caller\n   and for communication between successive calls to `pj_getopt'.\n\n   On entry to `pj_getopt', zero means this is the first call; initialize.\n\n   When `pj_getopt' returns -1, this is the index of the first of the\n   non-option elements that the caller should itself scan.\n\n   Otherwise, `pj_optind' communicates from one call to the next\n   how much of ARGV has been scanned so far.  */\n\n/* 1003.2 says this must be 1 before any call.  */\nint pj_optind = 1;\n\n/* Formerly, initialization of pj_getopt depended on pj_optind==0, which\n   causes problems with re-calling pj_getopt as programs generally don't\n   know that. */\n\nstatic int __getopt_initialized = 0;\n\n/* The next char to be scanned in the option-element\n   in which the last option character we returned was found.\n   This allows us to pick up the scan where we left off.\n\n   If this is zero, or a null string, it means resume the scan\n   by advancing to the next ARGV-element.  */\n\nstatic char *nextchar;\n\n/* Set to an option character which was unrecognized.\n   This must be initialized on some systems to avoid linking in the\n   system's own pj_getopt implementation.  */\n\nint pj_optopt = '?';\n\n/* Describe how to deal with options that follow non-option ARGV-elements.\n\n   If the caller did not specify anything,\n   the default is REQUIRE_ORDER if the environment variable\n   POSIXLY_CORRECT is defined, PERMUTE otherwise.\n\n   REQUIRE_ORDER means don't recognize them as options;\n   stop option processing when the first non-option is seen.\n   This is what Unix does.\n   This mode of operation is selected by either setting the environment\n   variable POSIXLY_CORRECT, or using `+' as the first character\n   of the list of option characters.\n\n   PERMUTE is the default.  We permute the contents of ARGV as we scan,\n   so that eventually all the non-options are at the end.  This allows options\n   to be given in any order, even with programs that were not written to\n   expect this.\n\n   RETURN_IN_ORDER is an option available to programs that were written\n   to expect options and other ARGV-elements in any order and that care about\n   the ordering of the two.  We describe each non-option ARGV-element\n   as if it were the argument of an option with character code 1.\n   Using `-' as the first character of the list of option characters\n   selects this mode of operation.\n\n   The special argument `--' forces an end of option-scanning regardless\n   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only\n   `--' can cause `pj_getopt' to return -1 with `pj_optind' != ARGC.  */\n\nstatic enum\n{\n  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER\n} ordering;\n\n/* Value of POSIXLY_CORRECT environment variable.  */\nstatic char *posixly_correct;\n\nstatic char *\nmy_index (const char *str, int chr)\n{\n  while (*str)\n    {\n      if (*str == chr)\n\treturn (char *) str;\n      str++;\n    }\n  return 0;\n}\n\n\n/* Handle permutation of arguments.  */\n\n/* Describe the part of ARGV that contains non-options that have\n   been skipped.  `first_nonopt' is the index in ARGV of the first of them;\n   `last_nonopt' is the index after the last of them.  */\n\nstatic int first_nonopt;\nstatic int last_nonopt;\n\n#   define SWAP_FLAGS(ch1, ch2)\n\n/* Exchange two adjacent subsequences of ARGV.\n   One subsequence is elements [first_nonopt,last_nonopt)\n   which contains all the non-options that have been skipped so far.\n   The other is elements [last_nonopt,pj_optind), which contains all\n   the options processed since those non-options were skipped.\n\n   `first_nonopt' and `last_nonopt' are relocated so that they describe\n   the new indices of the non-options in ARGV after they are moved.  */\n\nstatic void\nexchange (char **argv)\n{\n  int bottom = first_nonopt;\n  int middle = last_nonopt;\n  int top = pj_optind;\n  char *tem;\n\n  /* Exchange the shorter segment with the far end of the longer segment.\n     That puts the shorter segment into the right place.\n     It leaves the longer segment in the right place overall,\n     but it consists of two parts that need to be swapped next.  */\n\n  while (top > middle && middle > bottom)\n    {\n      if (top - middle > middle - bottom)\n\t{\n\t  /* Bottom segment is the short one.  */\n\t  int len = middle - bottom;\n\t  register int i;\n\n\t  /* Swap it with the top part of the top segment.  */\n\t  for (i = 0; i < len; i++)\n\t    {\n\t      tem = argv[bottom + i];\n\t      argv[bottom + i] = argv[top - (middle - bottom) + i];\n\t      argv[top - (middle - bottom) + i] = tem;\n\t      SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);\n\t    }\n\t  /* Exclude the moved bottom segment from further swapping.  */\n\t  top -= len;\n\t}\n      else\n\t{\n\t  /* Top segment is the short one.  */\n\t  int len = top - middle;\n\t  register int i;\n\n\t  /* Swap it with the bottom part of the bottom segment.  */\n\t  for (i = 0; i < len; i++)\n\t    {\n\t      tem = argv[bottom + i];\n\t      argv[bottom + i] = argv[middle + i];\n\t      argv[middle + i] = tem;\n\t      SWAP_FLAGS (bottom + i, middle + i);\n\t    }\n\t  /* Exclude the moved top segment from further swapping.  */\n\t  bottom += len;\n\t}\n    }\n\n  /* Update records for the slots the non-options now occupy.  */\n\n  first_nonopt += (pj_optind - last_nonopt);\n  last_nonopt = pj_optind;\n}\n\n/* Initialize the internal data when the first call is made.  */\n\nstatic const char *_getopt_initialize (int argc, char *const *argv, \n\t\t\t\t       const char *optstring)\n{\n    PJ_UNUSED_ARG(argc);\n    PJ_UNUSED_ARG(argv);\n\n  /* Start processing options with ARGV-element 1 (since ARGV-element 0\n     is the program name); the sequence of previously skipped\n     non-option ARGV-elements is empty.  */\n\n  first_nonopt = last_nonopt = pj_optind;\n\n  nextchar = NULL;\n\n  //posixly_correct = getenv (\"POSIXLY_CORRECT\");\n  posixly_correct = NULL;\n\n  /* Determine how to handle the ordering of options and nonoptions.  */\n\n  if (optstring[0] == '-')\n    {\n      ordering = RETURN_IN_ORDER;\n      ++optstring;\n    }\n  else if (optstring[0] == '+')\n    {\n      ordering = REQUIRE_ORDER;\n      ++optstring;\n    }\n  else if (posixly_correct != NULL)\n    ordering = REQUIRE_ORDER;\n  else\n    ordering = PERMUTE;\n\n  return optstring;\n}\n\n/* Scan elements of ARGV (whose length is ARGC) for option characters\n   given in OPTSTRING.\n\n   If an element of ARGV starts with '-', and is not exactly \"-\" or \"--\",\n   then it is an option element.  The characters of this element\n   (aside from the initial '-') are option characters.  If `pj_getopt'\n   is called repeatedly, it returns successively each of the option characters\n   from each of the option elements.\n\n   If `pj_getopt' finds another option character, it returns that character,\n   updating `pj_optind' and `nextchar' so that the next call to `pj_getopt' can\n   resume the scan with the following option character or ARGV-element.\n\n   If there are no more option characters, `pj_getopt' returns -1.\n   Then `pj_optind' is the index in ARGV of the first ARGV-element\n   that is not an option.  (The ARGV-elements have been permuted\n   so that those that are not options now come last.)\n\n   OPTSTRING is a string containing the legitimate option characters.\n   If an option character is seen that is not listed in OPTSTRING,\n   return '?' after printing an error message.  If you set `pj_opterr' to\n   zero, the error message is suppressed but we still return '?'.\n\n   If a char in OPTSTRING is followed by a colon, that means it wants an arg,\n   so the following text in the same ARGV-element, or the text of the following\n   ARGV-element, is returned in `pj_optarg'.  Two colons mean an option that\n   wants an optional arg; if there is text in the current ARGV-element,\n   it is returned in `pj_optarg', otherwise `pj_optarg' is set to zero.\n\n   If OPTSTRING starts with `-' or `+', it requests different methods of\n   handling the non-option ARGV-elements.\n   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.\n\n   Long-named options begin with `--' instead of `-'.\n   Their names may be abbreviated as long as the abbreviation is unique\n   or is an exact match for some defined option.  If they have an\n   argument, it follows the option name in the same ARGV-element, separated\n   from the option name by a `=', or else the in next ARGV-element.\n   When `pj_getopt' finds a long-named option, it returns 0 if that option's\n   `flag' field is nonzero, the value of the option's `val' field\n   if the `flag' field is zero.\n\n   The elements of ARGV aren't really const, because we permute them.\n   But we pretend they're const in the prototype to be compatible\n   with other systems.\n\n   LONGOPTS is a vector of `struct pj_getopt_option' terminated by an\n   element containing a name which is zero.\n\n   LONGIND returns the index in LONGOPT of the long-named option found.\n   It is only valid when a long-named option has been found by the most\n   recent call.\n\n   If LONG_ONLY is nonzero, '-' as well as '--' can introduce\n   long-named options.  */\n\nstatic int\n_getopt_internal (int argc, char *const *argv, const char *optstring, \n\t\t  const struct pj_getopt_option *longopts, int *longind, \n\t\t  int long_only)\n{\n  pj_optarg = NULL;\n\n  if (pj_optind == 0 || !__getopt_initialized)\n    {\n      if (pj_optind == 0)\n\tpj_optind = 1;\t/* Don't scan ARGV[0], the program name.  */\n      optstring = _getopt_initialize (argc, argv, optstring);\n      __getopt_initialized = 1;\n    }\n\n  /* Test whether ARGV[pj_optind] points to a non-option argument.\n     Either it does not have option syntax, or there is an environment flag\n     from the shell indicating it is not an option.  The later information\n     is only used when the used in the GNU libc.  */\n#define NONOPTION_P (argv[pj_optind][0] != '-' || argv[pj_optind][1] == '\\0')\n\n  if (nextchar == NULL || *nextchar == '\\0')\n    {\n      /* Advance to the next ARGV-element.  */\n\n      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been\n\t moved back by the user (who may also have changed the arguments).  */\n      if (last_nonopt > pj_optind)\n\tlast_nonopt = pj_optind;\n      if (first_nonopt > pj_optind)\n\tfirst_nonopt = pj_optind;\n\n      if (ordering == PERMUTE)\n\t{\n\t  /* If we have just processed some options following some non-options,\n\t     exchange them so that the options come first.  */\n\n\t  if (first_nonopt != last_nonopt && last_nonopt != pj_optind)\n\t    exchange ((char **) argv);\n\t  else if (last_nonopt != pj_optind)\n\t    first_nonopt = pj_optind;\n\n\t  /* Skip any additional non-options\n\t     and extend the range of non-options previously skipped.  */\n\n\t  while (pj_optind < argc && NONOPTION_P)\n\t    pj_optind++;\n\t  last_nonopt = pj_optind;\n\t}\n\n      /* The special ARGV-element `--' means premature end of options.\n\t Skip it like a null option,\n\t then exchange with previous non-options as if it were an option,\n\t then skip everything else like a non-option.  */\n\n      if (pj_optind != argc && !pj_ansi_strcmp(argv[pj_optind], \"--\"))\n\t{\n\t  pj_optind++;\n\n\t  if (first_nonopt != last_nonopt && last_nonopt != pj_optind)\n\t    exchange ((char **) argv);\n\t  else if (first_nonopt == last_nonopt)\n\t    first_nonopt = pj_optind;\n\t  last_nonopt = argc;\n\n\t  pj_optind = argc;\n\t}\n\n      /* If we have done all the ARGV-elements, stop the scan\n\t and back over any non-options that we skipped and permuted.  */\n\n      if (pj_optind == argc)\n\t{\n\t  /* Set the next-arg-index to point at the non-options\n\t     that we previously skipped, so the caller will digest them.  */\n\t  if (first_nonopt != last_nonopt)\n\t    pj_optind = first_nonopt;\n\t  return -1;\n\t}\n\n      /* If we have come to a non-option and did not permute it,\n\t either stop the scan or describe it to the caller and pass it by.  */\n\n      if (NONOPTION_P)\n\t{\n\t  if (ordering == REQUIRE_ORDER)\n\t    return -1;\n\t  pj_optarg = argv[pj_optind++];\n\t  return 1;\n\t}\n\n      /* We have found another option-ARGV-element.\n\t Skip the initial punctuation.  */\n\n      nextchar = (argv[pj_optind] + 1\n\t\t  + (longopts != NULL && argv[pj_optind][1] == '-'));\n    }\n\n  /* Decode the current option-ARGV-element.  */\n\n  /* Check whether the ARGV-element is a long option.\n\n     If long_only and the ARGV-element has the form \"-f\", where f is\n     a valid short option, don't consider it an abbreviated form of\n     a long option that starts with f.  Otherwise there would be no\n     way to give the -f short option.\n\n     On the other hand, if there's a long option \"fubar\" and\n     the ARGV-element is \"-fu\", do consider that an abbreviation of\n     the long option, just like \"--fu\", and not \"-f\" with arg \"u\".\n\n     This distinction seems to be the most useful approach.  */\n\n  if (longopts != NULL\n      && (argv[pj_optind][1] == '-'\n\t  || (long_only && (argv[pj_optind][2] || !my_index (optstring, argv[pj_optind][1])))))\n    {\n      char *nameend;\n      const struct pj_getopt_option *p;\n      const struct pj_getopt_option *pfound = NULL;\n      int exact = 0;\n      int ambig = 0;\n      int indfound = -1;\n      int option_index;\n\n      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)\n\t/* Do nothing.  */ ;\n\n      /* Test all long options for either exact match\n\t or abbreviated matches.  */\n      for (p = longopts, option_index = 0; p->name; p++, option_index++)\n\tif (!strncmp (p->name, nextchar, nameend - nextchar))\n\t  {\n\t    if ((unsigned int) (nameend - nextchar)\n\t\t== (unsigned int) strlen (p->name))\n\t      {\n\t\t/* Exact match found.  */\n\t\tpfound = p;\n\t\tindfound = option_index;\n\t\texact = 1;\n\t\tbreak;\n\t      }\n\t    else if (pfound == NULL)\n\t      {\n\t\t/* First nonexact match found.  */\n\t\tpfound = p;\n\t\tindfound = option_index;\n\t      }\n\t    else\n\t      /* Second or later nonexact match found.  */\n\t      ambig = 1;\n\t  }\n\n      if (ambig && !exact)\n\t{\n\t  nextchar += strlen (nextchar);\n\t  pj_optind++;\n\t  pj_optopt = 0;\n\t  return '?';\n\t}\n\n      if (pfound != NULL)\n\t{\n\t  option_index = indfound;\n\t  pj_optind++;\n\t  if (*nameend)\n\t    {\n\t      /* Don't test has_arg with >, because some C compilers don't\n\t\t allow it to be used on enums.  */\n\t      if (pfound->has_arg)\n\t\tpj_optarg = nameend + 1;\n\t      else\n\t\t{\n\t\t  nextchar += strlen (nextchar);\n\n\t\t  pj_optopt = pfound->val;\n\t\t  return '?';\n\t\t}\n\t    }\n\t  else if (pfound->has_arg == 1)\n\t    {\n\t      if (pj_optind < argc)\n\t\tpj_optarg = argv[pj_optind++];\n\t      else\n\t\t{\n\t\t  nextchar += strlen (nextchar);\n\t\t  pj_optopt = pfound->val;\n\t\t  return optstring[0] == ':' ? ':' : '?';\n\t\t}\n\t    }\n\t  nextchar += strlen (nextchar);\n\t  if (longind != NULL)\n\t    *longind = option_index;\n\t  if (pfound->flag)\n\t    {\n\t      *(pfound->flag) = pfound->val;\n\t      return 0;\n\t    }\n\t  return pfound->val;\n\t}\n\n      /* Can't find it as a long option.  If this is not pj_getopt_long_only,\n\t or the option starts with '--' or is not a valid short\n\t option, then it's an error.\n\t Otherwise interpret it as a short option.  */\n      if (!long_only || argv[pj_optind][1] == '-'\n\t  || my_index (optstring, *nextchar) == NULL)\n\t{\n\t  nextchar = (char *) \"\";\n\t  pj_optind++;\n\t  pj_optopt = 0;\n\t  return '?';\n\t}\n    }\n\n  /* Look at and handle the next short option-character.  */\n\n  {\n    char c = *nextchar++;\n    char *temp = my_index (optstring, c);\n\n    /* Increment `pj_optind' when we start to process its last character.  */\n    if (*nextchar == '\\0')\n      ++pj_optind;\n\n    if (temp == NULL || c == ':')\n      {\n\tpj_optopt = c;\n\treturn '?';\n      }\n    /* Convenience. Treat POSIX -W foo same as long option --foo */\n    if (temp[0] == 'W' && temp[1] == ';')\n      {\n\tchar *nameend;\n\tconst struct pj_getopt_option *p;\n\tconst struct pj_getopt_option *pfound = NULL;\n\tint exact = 0;\n\tint ambig = 0;\n\tint indfound = 0;\n\tint option_index;\n\n\t/* This is an option that requires an argument.  */\n\tif (*nextchar != '\\0')\n\t  {\n\t    pj_optarg = nextchar;\n\t    /* If we end this ARGV-element by taking the rest as an arg,\n\t       we must advance to the next element now.  */\n\t    pj_optind++;\n\t  }\n\telse if (pj_optind == argc)\n\t  {\n\t    pj_optopt = c;\n\t    if (optstring[0] == ':')\n\t      c = ':';\n\t    else\n\t      c = '?';\n\t    return c;\n\t  }\n\telse\n\t  /* We already incremented `pj_optind' once;\n\t     increment it again when taking next ARGV-elt as argument.  */\n\t  pj_optarg = argv[pj_optind++];\n\n\t/* pj_optarg is now the argument, see if it's in the\n\t   table of longopts.  */\n\n\tfor (nextchar = nameend = pj_optarg; *nameend && *nameend != '='; nameend++)\n\t  /* Do nothing.  */ ;\n\n\t/* Test all long options for either exact match\n\t   or abbreviated matches.  */\n\tfor (p = longopts, option_index = 0; p->name; p++, option_index++)\n\t  if (!strncmp (p->name, nextchar, nameend - nextchar))\n\t    {\n\t      if ((unsigned int) (nameend - nextchar) == strlen (p->name))\n\t\t{\n\t\t  /* Exact match found.  */\n\t\t  pfound = p;\n\t\t  indfound = option_index;\n\t\t  exact = 1;\n\t\t  break;\n\t\t}\n\t      else if (pfound == NULL)\n\t\t{\n\t\t  /* First nonexact match found.  */\n\t\t  pfound = p;\n\t\t  indfound = option_index;\n\t\t}\n\t      else\n\t\t/* Second or later nonexact match found.  */\n\t\tambig = 1;\n\t    }\n\tif (ambig && !exact)\n\t  {\n\t    nextchar += strlen (nextchar);\n\t    pj_optind++;\n\t    return '?';\n\t  }\n\tif (pfound != NULL)\n\t  {\n\t    option_index = indfound;\n\t    if (*nameend)\n\t      {\n\t\t/* Don't test has_arg with >, because some C compilers don't\n\t\t   allow it to be used on enums.  */\n\t\tif (pfound->has_arg)\n\t\t  pj_optarg = nameend + 1;\n\t\telse\n\t\t  {\n\t\t    nextchar += strlen (nextchar);\n\t\t    return '?';\n\t\t  }\n\t      }\n\t    else if (pfound->has_arg == 1)\n\t      {\n\t\tif (pj_optind < argc)\n\t\t  pj_optarg = argv[pj_optind++];\n\t\telse\n\t\t  {\n\t\t    nextchar += strlen (nextchar);\n\t\t    return optstring[0] == ':' ? ':' : '?';\n\t\t  }\n\t      }\n\t    nextchar += strlen (nextchar);\n\t    if (longind != NULL)\n\t      *longind = option_index;\n\t    if (pfound->flag)\n\t      {\n\t\t*(pfound->flag) = pfound->val;\n\t\treturn 0;\n\t      }\n\t    return pfound->val;\n\t  }\n\t  nextchar = NULL;\n\t  return 'W';\t/* Let the application handle it.   */\n      }\n    if (temp[1] == ':')\n      {\n\tif (temp[2] == ':')\n\t  {\n\t    /* This is an option that accepts an argument optionally.  */\n\t    if (*nextchar != '\\0')\n\t      {\n\t\tpj_optarg = nextchar;\n\t\tpj_optind++;\n\t      }\n\t    else\n\t      pj_optarg = NULL;\n\t    nextchar = NULL;\n\t  }\n\telse\n\t  {\n\t    /* This is an option that requires an argument.  */\n\t    if (*nextchar != '\\0')\n\t      {\n\t\tpj_optarg = nextchar;\n\t\t/* If we end this ARGV-element by taking the rest as an arg,\n\t\t   we must advance to the next element now.  */\n\t\tpj_optind++;\n\t      }\n\t    else if (pj_optind == argc)\n\t      {\n\t\tpj_optopt = c;\n\t\tif (optstring[0] == ':')\n\t\t  c = ':';\n\t\telse\n\t\t  c = '?';\n\t      }\n\t    else\n\t      /* We already incremented `pj_optind' once;\n\t\t increment it again when taking next ARGV-elt as argument.  */\n\t      pj_optarg = argv[pj_optind++];\n\t    nextchar = NULL;\n\t  }\n      }\n    return c;\n  }\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/hmac_md5.c",
    "content": "/* $Id: hmac_md5.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/hmac_md5.h>\n#include <pj/string.h>\n\n\nPJ_DEF(void) pj_hmac_md5_init(pj_hmac_md5_context *hctx, \n\t\t\t      const pj_uint8_t *key, unsigned key_len)\n{\n    pj_uint8_t k_ipad[64];\n    pj_uint8_t tk[16];\n    int i;\n\n    /* if key is longer than 64 bytes reset it to key=MD5(key) */\n    if (key_len > 64) {\n        pj_md5_context      tctx;\n\n        pj_md5_init(&tctx);\n        pj_md5_update(&tctx, key, key_len);\n        pj_md5_final(&tctx, tk);\n\n        key = tk;\n        key_len = 16;\n    }\n\n    /*\n     * HMAC = H(K XOR opad, H(K XOR ipad, text))\n     */\n\n    /* start out by storing key in pads */\n    pj_bzero( k_ipad, sizeof(k_ipad));\n    pj_bzero( hctx->k_opad, sizeof(hctx->k_opad));\n    pj_memcpy( k_ipad, key, key_len);\n    pj_memcpy( hctx->k_opad, key, key_len);\n\n    /* XOR key with ipad and opad values */\n    for (i=0; i<64; i++) {\n        k_ipad[i] ^= 0x36;\n        hctx->k_opad[i] ^= 0x5c;\n    }\n    /*\n     * perform inner MD5\n     */\n    pj_md5_init(&hctx->context);\n    pj_md5_update(&hctx->context, k_ipad, 64);\n\n}\n\nPJ_DEF(void) pj_hmac_md5_update(pj_hmac_md5_context *hctx,\n\t\t\t\t const pj_uint8_t *input, \n\t\t\t\t unsigned input_len)\n{\n    pj_md5_update(&hctx->context, input, input_len);\n}\n\nPJ_DEF(void) pj_hmac_md5_final(pj_hmac_md5_context *hctx,\n\t\t\t\tpj_uint8_t digest[16])\n{\n    pj_md5_final(&hctx->context, digest);\n\n    /*\n     * perform outer MD5\n     */\n    pj_md5_init(&hctx->context);\n    pj_md5_update(&hctx->context, hctx->k_opad, 64);\n    pj_md5_update(&hctx->context, digest, 16);\n    pj_md5_final(&hctx->context, digest);\n}\n\nPJ_DEF(void) pj_hmac_md5( const pj_uint8_t *input, unsigned input_len, \n\t\t\t  const pj_uint8_t *key, unsigned key_len, \n\t\t\t  pj_uint8_t digest[16] )\n{\n    pj_hmac_md5_context ctx;\n\n    pj_hmac_md5_init(&ctx, key, key_len);\n    pj_hmac_md5_update(&ctx, input, input_len);\n    pj_hmac_md5_final(&ctx, digest);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/hmac_sha1.c",
    "content": "/* $Id: hmac_sha1.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/hmac_sha1.h>\n#include <pj/string.h>\n\n\nPJ_DEF(void) pj_hmac_sha1_init(pj_hmac_sha1_context *hctx, \n\t\t\t       const pj_uint8_t *key, unsigned key_len)\n{\n    pj_uint8_t k_ipad[64];\n    pj_uint8_t tk[20];\n    unsigned i;\n\n    /* if key is longer than 64 bytes reset it to key=SHA1(key) */\n    if (key_len > 64) {\n        pj_sha1_context      tctx;\n\n        pj_sha1_init(&tctx);\n        pj_sha1_update(&tctx, key, key_len);\n        pj_sha1_final(&tctx, tk);\n\n        key = tk;\n        key_len = 20;\n    }\n\n    /*\n     * HMAC = H(K XOR opad, H(K XOR ipad, text))\n     */\n\n    /* start out by storing key in pads */\n    pj_bzero( k_ipad, sizeof(k_ipad));\n    pj_bzero( hctx->k_opad, sizeof(hctx->k_opad));\n    pj_memcpy( k_ipad, key, key_len);\n    pj_memcpy( hctx->k_opad, key, key_len);\n\n    /* XOR key with ipad and opad values */\n    for (i=0; i<64; i++) {\n        k_ipad[i] ^= 0x36;\n        hctx->k_opad[i] ^= 0x5c;\n    }\n    /*\n     * perform inner SHA1\n     */\n    pj_sha1_init(&hctx->context);\n    pj_sha1_update(&hctx->context, k_ipad, 64);\n}\n\nPJ_DEF(void) pj_hmac_sha1_update(pj_hmac_sha1_context *hctx,\n\t\t\t\t const pj_uint8_t *input, unsigned input_len)\n{\n    pj_sha1_update(&hctx->context, input, input_len);\n}\n\nPJ_DEF(void) pj_hmac_sha1_final(pj_hmac_sha1_context *hctx,\n\t\t\t\tpj_uint8_t digest[20])\n{\n    pj_sha1_final(&hctx->context, digest);\n\n    /*\n     * perform outer SHA1\n     */\n    pj_sha1_init(&hctx->context);\n    pj_sha1_update(&hctx->context, hctx->k_opad, 64);\n    pj_sha1_update(&hctx->context, digest, 20);\n    pj_sha1_final(&hctx->context, digest);\n}\n\nPJ_DEF(void) pj_hmac_sha1(const pj_uint8_t *input, unsigned input_len, \n\t\t\t  const pj_uint8_t *key, unsigned key_len, \n\t\t\t  pj_uint8_t digest[20] )\n{\n    pj_hmac_sha1_context ctx;\n\n    pj_hmac_sha1_init(&ctx, key, key_len);\n    pj_hmac_sha1_update(&ctx, input, input_len);\n    pj_hmac_sha1_final(&ctx, digest);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/http_client.c",
    "content": "/* $Id: http_client.c 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pjlib-util/http_client.h>\n#include <pj/activesock.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n#include <pj/errno.h>\n#include <pj/except.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/timer.h>\n#include <pj/rand.h>\n#include <pjlib-util/base64.h>\n#include <pjlib-util/errno.h>\n#include <pjlib-util/md5.h>\n#include <pjlib-util/scanner.h>\n#include <pjlib-util/string.h>\n\n#define THIS_FILE   \"http_client.c\"\n\n#if 0\n    /* Enable some tracing */\n    #define TRACE_(arg)\tPJ_LOG(3,arg)\n#else\n    #define TRACE_(arg)\n#endif\n\n#define NUM_PROTOCOL            2\n#define HTTP_1_0                \"1.0\"\n#define HTTP_1_1                \"1.1\"\n#define CONTENT_LENGTH          \"Content-Length\"\n/* Buffer size for sending/receiving messages. */\n#define BUF_SIZE                2048\n/* Initial data buffer size to store the data in case content-\n * length is not specified in the server's response.\n */\n#define INITIAL_DATA_BUF_SIZE   2048\n#define INITIAL_POOL_SIZE       1024\n#define POOL_INCREMENT_SIZE     512\n\nenum http_protocol\n{\n    PROTOCOL_HTTP,\n    PROTOCOL_HTTPS\n};\n\nstatic const char *http_protocol_names[NUM_PROTOCOL] =\n{\n    \"HTTP\",\n    \"HTTPS\"\n};\n\nstatic const unsigned int http_default_port[NUM_PROTOCOL] =\n{\n    80,\n    443\n};\n\nenum http_method\n{\n    HTTP_GET,\n    HTTP_PUT,\n    HTTP_DELETE\n};\n\nstatic const char *http_method_names[3] =\n{\n    \"GET\",\n    \"PUT\",\n    \"DELETE\"\n};\n\nenum http_state\n{\n    IDLE,\n    CONNECTING,\n    SENDING_REQUEST,\n    SENDING_REQUEST_BODY,\n    REQUEST_SENT,\n    READING_RESPONSE,\n    READING_DATA,\n    READING_COMPLETE,\n    ABORTING,\n};\n\nenum auth_state\n{\n    AUTH_NONE,\t\t/* Not authenticating */\n    AUTH_RETRYING,\t/* New request with auth has been submitted */\n    AUTH_DONE\t\t/* Done retrying the request with auth. */\n};\n\nstruct pj_http_req\n{\n    pj_str_t                url;        /* Request URL */\n    pj_http_url             hurl;       /* Parsed request URL */\n    pj_sockaddr             addr;       /* The host's socket address */\n    pj_http_req_param       param;      /* HTTP request parameters */\n    pj_pool_t               *pool;      /* Pool to allocate memory from */\n    pj_timer_heap_t         *timer;     /* Timer for timeout management */\n    pj_ioqueue_t            *ioqueue;   /* Ioqueue to use */\n    pj_http_req_callback    cb;         /* Callbacks */\n    pj_activesock_t         *asock;     /* Active socket */\n    pj_status_t             error;      /* Error status */\n    pj_str_t                buffer;     /* Buffer to send/receive msgs */\n    enum http_state         state;      /* State of the HTTP request */\n    enum auth_state\t    auth_state; /* Authentication state */\n    pj_timer_entry          timer_entry;/* Timer entry */\n    pj_bool_t               resolved;   /* Whether URL's host is resolved */\n    pj_http_resp            response;   /* HTTP response */\n    pj_ioqueue_op_key_t\t    op_key;\n    struct tcp_state\n    {\n        /* Total data sent so far if the data is sent in segments (i.e.\n         * if on_send_data() is not NULL and if param.reqdata.total_size > 0)\n         */\n        pj_size_t tot_chunk_size;\n        /* Size of data to be sent (in a single activesock operation).*/\n        pj_size_t send_size;\n        /* Data size sent so far. */\n        pj_size_t current_send_size;\n        /* Total data received so far. */\n        pj_size_t current_read_size;\n    } tcp_state;\n};\n\n/* Start sending the request */\nstatic pj_status_t http_req_start_sending(pj_http_req *hreq);\n/* Start reading the response */\nstatic pj_status_t http_req_start_reading(pj_http_req *hreq);\n/* End the request */\nstatic pj_status_t http_req_end_request(pj_http_req *hreq);\n/* Parse the header data and populate the header fields with the result. */\nstatic pj_status_t http_headers_parse(char *hdata, pj_size_t size, \n                                      pj_http_headers *headers);\n/* Parse the response */\nstatic pj_status_t http_response_parse(pj_pool_t *pool,\n                                       pj_http_resp *response,\n                                       void *data, pj_size_t size,\n                                       pj_size_t *remainder);\n/* Restart the request with authentication */\nstatic void restart_req_with_auth(pj_http_req *hreq);\n/* Parse authentication challenge */\nstatic pj_status_t parse_auth_chal(pj_pool_t *pool, pj_str_t *input,\n\t\t\t\t   pj_http_auth_chal *chal);\n\nstatic pj_uint16_t get_http_default_port(const pj_str_t *protocol)\n{\n    int i;\n\n    for (i = 0; i < NUM_PROTOCOL; i++) {\n        if (!pj_stricmp2(protocol, http_protocol_names[i])) {\n            return (pj_uint16_t)http_default_port[i];\n        }\n    }\n    return 0;\n}\n\nstatic const char * get_protocol(const pj_str_t *protocol)\n{\n    int i;\n\n    for (i = 0; i < NUM_PROTOCOL; i++) {\n        if (!pj_stricmp2(protocol, http_protocol_names[i])) {\n            return http_protocol_names[i];\n        }\n    }\n\n    /* Should not happen */\n    pj_assert(0);\n    return NULL;\n}\n\n\n/* Syntax error handler for parser. */\nstatic void on_syntax_error(pj_scanner *scanner)\n{\n    PJ_UNUSED_ARG(scanner);\n    PJ_THROW(PJ_EINVAL);  // syntax error\n}\n\n/* Callback when connection is established to the server */\nstatic pj_bool_t http_on_connect(pj_activesock_t *asock,\n\t\t\t\t pj_status_t status)\n{\n    pj_http_req *hreq = (pj_http_req*) pj_activesock_get_user_data(asock);\n\n    if (hreq->state == ABORTING || hreq->state == IDLE)\n        return PJ_FALSE;\n\n    if (status != PJ_SUCCESS) {\n        hreq->error = status;\n        pj_http_req_cancel(hreq, PJ_TRUE);\n        return PJ_FALSE;\n    }\n\n    /* OK, we are connected. Start sending the request */\n    hreq->state = SENDING_REQUEST;\n    http_req_start_sending(hreq);\n    return PJ_TRUE;\n}\n\nstatic pj_bool_t http_on_data_sent(pj_activesock_t *asock,\n \t\t\t\t   pj_ioqueue_op_key_t *op_key,\n\t\t\t\t   pj_ssize_t sent)\n{\n    pj_http_req *hreq = (pj_http_req*) pj_activesock_get_user_data(asock);\n\n    PJ_UNUSED_ARG(op_key);\n\n    if (hreq->state == ABORTING || hreq->state == IDLE)\n        return PJ_FALSE;\n\n    if (sent <= 0) {\n        hreq->error = (sent < 0 ? (pj_status_t)-sent : PJLIB_UTIL_EHTTPLOST);\n        pj_http_req_cancel(hreq, PJ_TRUE);\n        return PJ_FALSE;\n    } \n\n    hreq->tcp_state.current_send_size += sent;\n    TRACE_((THIS_FILE, \"\\nData sent: %d out of %d bytes\", \n           hreq->tcp_state.current_send_size, hreq->tcp_state.send_size));\n    if (hreq->tcp_state.current_send_size == hreq->tcp_state.send_size) {\n        /* Find out whether there is a request body to send. */\n        if (hreq->param.reqdata.total_size > 0 || \n            hreq->param.reqdata.size > 0) \n        {\n            if (hreq->state == SENDING_REQUEST) {\n                /* Start sending the request body */\n                hreq->state = SENDING_REQUEST_BODY;\n                hreq->tcp_state.tot_chunk_size = 0;\n                pj_assert(hreq->param.reqdata.total_size == 0 ||\n                          (hreq->param.reqdata.total_size > 0 && \n                          hreq->param.reqdata.size == 0));\n            } else {\n                /* Continue sending the next chunk of the request body */\n                hreq->tcp_state.tot_chunk_size += hreq->tcp_state.send_size;\n                if (hreq->tcp_state.tot_chunk_size == \n                    hreq->param.reqdata.total_size ||\n                    hreq->param.reqdata.total_size == 0) \n                {\n                    /* Finish sending all the chunks, start reading \n                     * the response.\n                     */\n                    hreq->state = REQUEST_SENT;\n                    http_req_start_reading(hreq);\n                    return PJ_TRUE;\n                }\n            }\n            if (hreq->param.reqdata.total_size > 0 &&\n                hreq->cb.on_send_data) \n            {\n                /* Call the callback for the application to provide\n                 * the next chunk of data to be sent.\n                 */\n                (*hreq->cb.on_send_data)(hreq, &hreq->param.reqdata.data, \n                                         &hreq->param.reqdata.size);\n                /* Make sure the total data size given by the user does not\n                 * exceed what the user originally said.\n                 */\n                pj_assert(hreq->tcp_state.tot_chunk_size + \n                          hreq->param.reqdata.size <=\n                          hreq->param.reqdata.total_size);\n            }\n            http_req_start_sending(hreq);\n        } else {\n            /* No request body, proceed to reading the server's response. */\n            hreq->state = REQUEST_SENT;\n            http_req_start_reading(hreq);\n        }\n    }\n    return PJ_TRUE;\n}\n\nstatic pj_bool_t http_on_data_read(pj_activesock_t *asock,\n\t\t\t\t  void *data,\n\t\t\t\t  pj_size_t size,\n\t\t\t\t  pj_status_t status,\n\t\t\t\t  pj_size_t *remainder)\n{\n    pj_http_req *hreq = (pj_http_req*) pj_activesock_get_user_data(asock);\n\n    TRACE_((THIS_FILE, \"\\nData received: %d bytes\", size));\n\n    if (hreq->state == ABORTING || hreq->state == IDLE)\n        return PJ_FALSE;\n\n    if (hreq->state == READING_RESPONSE) {\n        pj_status_t st;\n        pj_size_t rem;\n\n        if (status != PJ_SUCCESS && status != PJ_EPENDING) {\n            hreq->error = status;\n            pj_http_req_cancel(hreq, PJ_TRUE);\n            return PJ_FALSE;\n        }\n\n        /* Parse the response. */\n        st = http_response_parse(hreq->pool, &hreq->response,\n                                 data, size, &rem);\n        if (st == PJLIB_UTIL_EHTTPINCHDR) {\n            /* If we already use up all our buffer and still\n             * hasn't received the whole header, return error\n             */\n            if (size == BUF_SIZE) {\n                hreq->error = PJ_ETOOBIG; // response header size is too big\n                pj_http_req_cancel(hreq, PJ_TRUE);\n                return PJ_FALSE;\n            }\n            /* Keep the data if we do not get the whole response header */\n            *remainder = size;\n        } else {\n            hreq->state = READING_DATA;\n            if (st != PJ_SUCCESS) {\n                /* Server replied with an invalid (or unknown) response \n                 * format. We'll just pass the whole (unparsed) response \n                 * to the user.\n                 */\n                hreq->response.data = data;\n                hreq->response.size = size - rem;\n            }\n\n            /* If code is 401 or 407, find and parse WWW-Authenticate or\n             * Proxy-Authenticate header\n             */\n            if (hreq->response.status_code == 401 ||\n        \threq->response.status_code == 407)\n            {\n        \tconst pj_str_t STR_WWW_AUTH = { \"WWW-Authenticate\", 16 };\n        \tconst pj_str_t STR_PROXY_AUTH = { \"Proxy-Authenticate\", 18 };\n        \tpj_http_resp *response = &hreq->response;\n        \tpj_http_headers *hdrs = &response->headers;\n        \tunsigned i;\n\n        \tstatus = PJ_ENOTFOUND;\n        \tfor (i = 0; i < hdrs->count; i++) {\n        \t    if (!pj_stricmp(&hdrs->header[i].name, &STR_WWW_AUTH) ||\n        \t\t!pj_stricmp(&hdrs->header[i].name, &STR_PROXY_AUTH))\n        \t    {\n        \t\tstatus = parse_auth_chal(hreq->pool,\n        \t\t\t\t\t &hdrs->header[i].value,\n        \t\t\t\t\t &response->auth_chal);\n        \t\tbreak;\n        \t    }\n        \t}\n\n                /* Check if we should perform authentication */\n                if (status == PJ_SUCCESS &&\n\t\t    hreq->auth_state == AUTH_NONE &&\n\t\t    hreq->response.auth_chal.scheme.slen &&\n\t\t    hreq->param.auth_cred.username.slen &&\n\t\t    (hreq->param.auth_cred.scheme.slen == 0 ||\n\t\t     !pj_stricmp(&hreq->response.auth_chal.scheme,\n\t\t\t\t &hreq->param.auth_cred.scheme)) &&\n\t\t    (hreq->param.auth_cred.realm.slen == 0 ||\n\t\t     !pj_stricmp(&hreq->response.auth_chal.realm,\n\t\t\t\t &hreq->param.auth_cred.realm))\n\t\t    )\n\t\t    {\n\t\t    /* Yes, authentication is required and we have been\n\t\t     * configured with credential.\n\t\t     */\n\t\t    restart_req_with_auth(hreq);\n\t\t    if (hreq->auth_state == AUTH_RETRYING) {\n\t\t\t/* We'll be resending the request with auth. This\n\t\t\t * connection has been closed.\n\t\t\t */\n\t\t\treturn PJ_FALSE;\n\t\t    }\n                }\n            }\n\n            /* We already received the response header, call the \n             * appropriate callback.\n             */\n            if (hreq->cb.on_response)\n                (*hreq->cb.on_response)(hreq, &hreq->response);\n            hreq->response.data = NULL;\n            hreq->response.size = 0;\n\n\t    if (rem > 0 || hreq->response.content_length == 0)\n\t\treturn http_on_data_read(asock, (rem == 0 ? NULL:\n\t\t   \t                 (char *)data + size - rem),\n\t\t\t\t         rem, PJ_SUCCESS, NULL);\n        }\n\n        return PJ_TRUE;\n    }\n\n    if (hreq->state != READING_DATA)\n\treturn PJ_FALSE;\n    if (hreq->cb.on_data_read) {\n        /* If application wishes to receive the data once available, call\n         * its callback.\n         */\n        if (size > 0)\n            (*hreq->cb.on_data_read)(hreq, data, size);\n    } else {\n        if (hreq->response.size == 0) {\n            /* If we know the content length, allocate the data based\n             * on that, otherwise we'll use initial buffer size and grow \n             * it later if necessary.\n             */\n            hreq->response.size = (hreq->response.content_length == -1 ? \n                                   INITIAL_DATA_BUF_SIZE : \n                                   hreq->response.content_length);\n            hreq->response.data = pj_pool_alloc(hreq->pool, \n                                                hreq->response.size);\n        }\n\n        /* If the size of data received exceeds its current size,\n         * grow the buffer by a factor of 2.\n         */\n        if (hreq->tcp_state.current_read_size + size > \n            hreq->response.size) \n        {\n            void *olddata = hreq->response.data;\n\n            hreq->response.data = pj_pool_alloc(hreq->pool, \n                                                hreq->response.size << 1);\n            pj_memcpy(hreq->response.data, olddata, hreq->response.size);\n            hreq->response.size <<= 1;\n        }\n\n        /* Append the response data. */\n        pj_memcpy((char *)hreq->response.data + \n                  hreq->tcp_state.current_read_size, data, size);\n    }\n    hreq->tcp_state.current_read_size += size;\n\n    /* If the total data received so far is equal to the content length\n     * or if it's already EOF.\n     */\n    if ((hreq->response.content_length >=0 &&\n\t(pj_ssize_t)hreq->tcp_state.current_read_size >=\n        hreq->response.content_length) ||\n        (status == PJ_EEOF && hreq->response.content_length == -1)) \n    {\n\t/* Finish reading */\n        http_req_end_request(hreq);\n        hreq->response.size = hreq->tcp_state.current_read_size;\n\n        /* HTTP request is completed, call the callback. */\n        if (hreq->cb.on_complete) {\n            (*hreq->cb.on_complete)(hreq, PJ_SUCCESS, &hreq->response);\n        }\n\n        return PJ_FALSE;\n    }\n\n    /* Error status or premature EOF. */\n    if ((status != PJ_SUCCESS && status != PJ_EPENDING && status != PJ_EEOF)\n        || (status == PJ_EEOF && hreq->response.content_length > -1)) \n    {\n        hreq->error = status;\n        pj_http_req_cancel(hreq, PJ_TRUE);\n        return PJ_FALSE;\n    }\n    \n    return PJ_TRUE;\n}\n\n/* Callback to be called when query has timed out */\nstatic void on_timeout( pj_timer_heap_t *timer_heap,\n\t\t\tstruct pj_timer_entry *entry)\n{\n    pj_http_req *hreq = (pj_http_req *) entry->user_data;\n\n    PJ_UNUSED_ARG(timer_heap);\n\n    /* Recheck that the request is still not completed, since there is a \n     * slight possibility of race condition (timer elapsed while at the \n     * same time response arrives).\n     */\n    if (hreq->state == READING_COMPLETE) {\n\t/* Yeah, we finish on time */\n\treturn;\n    }\n\n    /* Invalidate id. */\n    hreq->timer_entry.id = 0;\n\n    /* Request timed out. */\n    hreq->error = PJ_ETIMEDOUT;\n    pj_http_req_cancel(hreq, PJ_TRUE);\n}\n\n/* Parse authentication challenge */\nstatic pj_status_t parse_auth_chal(pj_pool_t *pool, pj_str_t *input,\n\t\t\t\t   pj_http_auth_chal *chal)\n{\n    pj_scanner scanner;\n    const pj_str_t REALM_STR \t=    { \"realm\", 5},\n    \t\tNONCE_STR \t=    { \"nonce\", 5},\n    \t\tALGORITHM_STR \t=    { \"algorithm\", 9 },\n    \t\tSTALE_STR \t=    { \"stale\", 5},\n    \t\tQOP_STR \t=    { \"qop\", 3},\n    \t\tOPAQUE_STR \t=    { \"opaque\", 6};\n    pj_status_t status = PJ_SUCCESS;\n    PJ_USE_EXCEPTION ;\n\n    pj_scan_init(&scanner, input->ptr, input->slen, PJ_SCAN_AUTOSKIP_WS,\n\t\t &on_syntax_error);\n    PJ_TRY {\n\t/* Get auth scheme */\n\tif (*scanner.curptr == '\"') {\n\t    pj_scan_get_quote(&scanner, '\"', '\"', &chal->scheme);\n\t    chal->scheme.ptr++;\n\t    chal->scheme.slen -= 2;\n\t} else {\n\t    pj_scan_get_until_chr(&scanner, \" \\t\\r\\n\", &chal->scheme);\n\t}\n\n\t/* Loop parsing all parameters */\n\tfor (;;) {\n\t    const char *end_param = \", \\t\\r\\n;\";\n\t    pj_str_t name, value;\n\n\t    /* Get pair of parameter name and value */\n\t    value.ptr = NULL;\n\t    value.slen = 0;\n\t    pj_scan_get_until_chr(&scanner, \"=, \\t\\r\\n\", &name);\n\t    if (*scanner.curptr == '=') {\n\t\tpj_scan_get_char(&scanner);\n\t\tif (!pj_scan_is_eof(&scanner)) {\n\t\t    if (*scanner.curptr == '\"' || *scanner.curptr == '\\'') {\n\t\t\tint quote_char = *scanner.curptr;\n\t\t\tpj_scan_get_quote(&scanner, quote_char, quote_char,\n\t\t\t\t\t  &value);\n\t\t\tvalue.ptr++;\n\t\t\tvalue.slen -= 2;\n\t\t    } else if (!strchr(end_param, *scanner.curptr)) {\n\t\t\tpj_scan_get_until_chr(&scanner, end_param, &value);\n\t\t    }\n\t\t}\n\t\tvalue = pj_str_unescape(pool, &value);\n\t    }\n\n\t    if (!pj_stricmp(&name, &REALM_STR)) {\n\t\tchal->realm = value;\n\n\t    } else if (!pj_stricmp(&name, &NONCE_STR)) {\n\t\tchal->nonce = value;\n\n\t    } else if (!pj_stricmp(&name, &ALGORITHM_STR)) {\n\t\tchal->algorithm = value;\n\n\t    } else if (!pj_stricmp(&name, &OPAQUE_STR)) {\n\t\tchal->opaque = value;\n\n\t    } else if (!pj_stricmp(&name, &QOP_STR)) {\n\t\tchal->qop = value;\n\n\t    } else if (!pj_stricmp(&name, &STALE_STR)) {\n\t\tchal->stale = value.slen &&\n\t\t\t      (*value.ptr != '0') &&\n\t\t\t      (*value.ptr != 'f') &&\n\t\t\t      (*value.ptr != 'F');\n\n\t    }\n\n\t    /* Eat comma */\n\t    if (!pj_scan_is_eof(&scanner) && *scanner.curptr == ',')\n\t\tpj_scan_get_char(&scanner);\n\t    else\n\t\tbreak;\n\t}\n\n    }\n    PJ_CATCH_ANY {\n\tstatus = PJ_GET_EXCEPTION();\n\tpj_bzero(chal, sizeof(*chal));\n\tTRACE_((THIS_FILE, \"Error: parsing of auth header failed\"));\n    }\n    PJ_END;\n    pj_scan_fini(&scanner);\n    return status;\n}\n\n/* The same as #pj_http_headers_add_elmt() with char * as\n * its parameters.\n */\nPJ_DEF(pj_status_t) pj_http_headers_add_elmt2(pj_http_headers *headers, \n                                              char *name, char *val)\n{\n    pj_str_t f, v;\n    pj_cstr(&f, name);\n    pj_cstr(&v, val);\n    return pj_http_headers_add_elmt(headers, &f, &v);\n}   \n\nPJ_DEF(pj_status_t) pj_http_headers_add_elmt(pj_http_headers *headers, \n                                             pj_str_t *name, \n                                             pj_str_t *val)\n{\n    PJ_ASSERT_RETURN(headers && name && val, PJ_FALSE);\n    if (headers->count >= PJ_HTTP_HEADER_SIZE)\n        return PJ_ETOOMANY;\n    pj_strassign(&headers->header[headers->count].name, name);\n    pj_strassign(&headers->header[headers->count++].value, val);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t http_response_parse(pj_pool_t *pool,\n                                       pj_http_resp *response,\n                                       void *data, pj_size_t size,\n                                       pj_size_t *remainder)\n{\n    pj_size_t i;\n    char *cptr;\n    char *end_status, *newdata;\n    pj_scanner scanner;\n    pj_str_t s;\n    const pj_str_t STR_CONTENT_LENGTH = { CONTENT_LENGTH, 14 };\n    pj_status_t status;\n\n    PJ_USE_EXCEPTION;\n\n    PJ_ASSERT_RETURN(response, PJ_EINVAL);\n    if (size < 2)\n        return PJLIB_UTIL_EHTTPINCHDR;\n    /* Detect whether we already receive the response's status-line\n     * and its headers. We're looking for a pair of CRLFs. A pair of\n     * LFs is also supported although it is not RFC standard.\n     */\n    cptr = (char *)data;\n    for (i = 1, cptr++; i < size; i++, cptr++) {\n        if (*cptr == '\\n') {\n            if (*(cptr - 1) == '\\n')\n                break;\n            if (*(cptr - 1) == '\\r') {\n                if (i >= 3 && *(cptr - 2) == '\\n' && *(cptr - 3) == '\\r')\n                    break;\n            }\n        }\n    }\n    if (i == size)\n        return PJLIB_UTIL_EHTTPINCHDR;\n    *remainder = size - 1 - i;\n\n    pj_bzero(response, sizeof(*response));\n    response->content_length = -1;\n\n    newdata = (char*) pj_pool_alloc(pool, i);\n    pj_memcpy(newdata, data, i);\n\n    /* Parse the status-line. */\n    pj_scan_init(&scanner, newdata, i, 0, &on_syntax_error);\n    PJ_TRY {\n        pj_scan_get_until_ch(&scanner, ' ', &response->version);\n        pj_scan_advance_n(&scanner, 1, PJ_FALSE);\n        pj_scan_get_until_ch(&scanner, ' ', &s);\n        response->status_code = (pj_uint16_t)pj_strtoul(&s);\n        pj_scan_advance_n(&scanner, 1, PJ_FALSE);\n        pj_scan_get_until_ch(&scanner, '\\n', &response->reason);\n        if (response->reason.ptr[response->reason.slen-1] == '\\r')\n            response->reason.slen--;\n    }\n    PJ_CATCH_ANY {\n        pj_scan_fini(&scanner);\n        return PJ_GET_EXCEPTION();\n    }\n    PJ_END;\n\n    end_status = scanner.curptr;\n    pj_scan_fini(&scanner);\n\n    /* Parse the response headers. */\n    size = i - 2 - (end_status - newdata);\n    if (size > 0) {\n        status = http_headers_parse(end_status + 1, size,\n                                    &response->headers);\n    } else {\n        status = PJ_SUCCESS;\n    }\n\n    /* Find content-length header field. */\n    for (i = 0; i < response->headers.count; i++) {\n        if (!pj_stricmp(&response->headers.header[i].name,\n                        &STR_CONTENT_LENGTH))\n        {\n            response->content_length = \n                pj_strtoul(&response->headers.header[i].value);\n            /* If content length is zero, make sure that it is because the\n             * header value is really zero and not due to parsing error.\n             */\n            if (response->content_length == 0) {\n                if (pj_strcmp2(&response->headers.header[i].value, \"0\")) {\n                    response->content_length = -1;\n                }\n            }\n            break;\n        }\n    }\n\n    return status;\n}\n\nstatic pj_status_t http_headers_parse(char *hdata, pj_size_t size, \n                                      pj_http_headers *headers)\n{\n    pj_scanner scanner;\n    pj_str_t s, s2;\n    pj_status_t status;\n    PJ_USE_EXCEPTION;\n\n    PJ_ASSERT_RETURN(headers, PJ_EINVAL);\n\n    pj_scan_init(&scanner, hdata, size, 0, &on_syntax_error);\n\n    /* Parse each line of header field consisting of header field name and\n     * value, separated by \":\" and any number of white spaces.\n     */\n    PJ_TRY {\n        do {\n            pj_scan_get_until_chr(&scanner, \":\\n\", &s);\n            if (*scanner.curptr == ':') {\n                pj_scan_advance_n(&scanner, 1, PJ_TRUE);\n                pj_scan_get_until_ch(&scanner, '\\n', &s2);\n                if (s2.ptr[s2.slen-1] == '\\r')\n                    s2.slen--;\n                status = pj_http_headers_add_elmt(headers, &s, &s2);\n                if (status != PJ_SUCCESS)\n                    PJ_THROW(status);\n            }\n            pj_scan_advance_n(&scanner, 1, PJ_TRUE);\n            /* Finish parsing */\n            if (pj_scan_is_eof(&scanner))\n                break;\n        } while (1);\n    }\n    PJ_CATCH_ANY {\n        pj_scan_fini(&scanner);\n        return PJ_GET_EXCEPTION();\n    }\n    PJ_END;\n\n    pj_scan_fini(&scanner);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void) pj_http_req_param_default(pj_http_req_param *param)\n{\n    pj_assert(param);\n    pj_bzero(param, sizeof(*param));\n    param->addr_family = pj_AF_INET();\n    pj_strset2(&param->method, (char*)http_method_names[HTTP_GET]);\n    pj_strset2(&param->version, (char*)HTTP_1_0);\n    param->timeout.msec = PJ_HTTP_DEFAULT_TIMEOUT;\n    pj_time_val_normalize(&param->timeout);\n    param->max_retries = 3;\n}\n\n/* Get the location of '@' character to indicate the end of\n * user:passwd part of an URI. If user:passwd part is not\n * present, NULL will be returned.\n */\nstatic char *get_url_at_pos(const char *str, pj_size_t len)\n{\n    const char *end = str + len;\n    const char *p = str;\n\n    /* skip scheme: */\n    while (p!=end && *p!='/') ++p;\n    if (p!=end && *p=='/') ++p;\n    if (p!=end && *p=='/') ++p;\n    if (p==end) return NULL;\n\n    for (; p!=end; ++p) {\n\tswitch (*p) {\n\tcase '/':\n\t    return NULL;\n\tcase '@':\n\t    return (char*)p;\n\t}\n    }\n\n    return NULL;\n}\n\n\nPJ_DEF(pj_status_t) pj_http_req_parse_url(const pj_str_t *url, \n                                          pj_http_url *hurl)\n{\n    pj_scanner scanner;\n    pj_size_t len = url->slen;\n    PJ_USE_EXCEPTION;\n\n    if (!len) return -1;\n    \n    pj_bzero(hurl, sizeof(*hurl));\n    pj_scan_init(&scanner, url->ptr, url->slen, 0, &on_syntax_error);\n\n    PJ_TRY {\n\tpj_str_t s;\n\n        /* Exhaust any whitespaces. */\n        pj_scan_skip_whitespace(&scanner);\n\n        /* Parse the protocol */\n        pj_scan_get_until_ch(&scanner, ':', &s);\n        if (!pj_stricmp2(&s, http_protocol_names[PROTOCOL_HTTP])) {\n            pj_strset2(&hurl->protocol,\n        \t       (char*)http_protocol_names[PROTOCOL_HTTP]);\n        } else if (!pj_stricmp2(&s, http_protocol_names[PROTOCOL_HTTPS])) {\n            pj_strset2(&hurl->protocol,\n\t\t       (char*)http_protocol_names[PROTOCOL_HTTPS]);\n        } else {\n            PJ_THROW(PJ_ENOTSUP); // unsupported protocol\n        }\n\n        if (pj_scan_strcmp(&scanner, \"://\", 3)) {\n            PJ_THROW(PJLIB_UTIL_EHTTPINURL); // no \"://\" after protocol name\n        }\n        pj_scan_advance_n(&scanner, 3, PJ_FALSE);\n\n        if (get_url_at_pos(url->ptr, url->slen)) {\n            /* Parse username and password */\n            pj_scan_get_until_chr(&scanner, \":@\", &hurl->username);\n            if (*scanner.curptr == ':') {\n        \tpj_scan_get_char(&scanner);\n        \tpj_scan_get_until_chr(&scanner, \"@\", &hurl->passwd);\n            } else {\n        \thurl->passwd.slen = 0;\n            }\n            pj_scan_get_char(&scanner);\n        }\n\n        /* Parse the host and port number (if any) */\n        pj_scan_get_until_chr(&scanner, \":/\", &s);\n        pj_strassign(&hurl->host, &s);\n        if (hurl->host.slen==0)\n            PJ_THROW(PJ_EINVAL);\n        if (pj_scan_is_eof(&scanner) || *scanner.curptr == '/') {\n            /* No port number specified */\n            /* Assume default http/https port number */\n            hurl->port = get_http_default_port(&hurl->protocol);\n            pj_assert(hurl->port > 0);\n        } else {\n            pj_scan_advance_n(&scanner, 1, PJ_FALSE);\n            pj_scan_get_until_ch(&scanner, '/', &s);\n            /* Parse the port number */\n            hurl->port = (pj_uint16_t)pj_strtoul(&s);\n            if (!hurl->port)\n                PJ_THROW(PJLIB_UTIL_EHTTPINPORT); // invalid port number\n        }\n\n        if (!pj_scan_is_eof(&scanner)) {\n            hurl->path.ptr = scanner.curptr;\n            hurl->path.slen = scanner.end - scanner.curptr;\n        } else {\n            /* no path, append '/' */\n            pj_cstr(&hurl->path, \"/\");\n        }\n    }\n    PJ_CATCH_ANY {\n        pj_scan_fini(&scanner);\n\treturn PJ_GET_EXCEPTION();\n    }\n    PJ_END;\n\n    pj_scan_fini(&scanner);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void) pj_http_req_set_timeout(pj_http_req *http_req,\n                                     const pj_time_val* timeout)\n{\n    pj_memcpy(&http_req->param.timeout, timeout, sizeof(*timeout));\n}\n\nPJ_DEF(pj_status_t) pj_http_req_create(pj_pool_t *pool,\n                                       const pj_str_t *url,\n                                       pj_timer_heap_t *timer,\n                                       pj_ioqueue_t *ioqueue,\n                                       const pj_http_req_param *param,\n                                       const pj_http_req_callback *hcb,\n                                       pj_http_req **http_req)\n{\n    pj_pool_t *own_pool;\n    pj_http_req *hreq;\n    char *at_pos;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && url && timer && ioqueue && \n                     hcb && http_req, PJ_EINVAL);\n\n    *http_req = NULL;\n    own_pool = pj_pool_create(pool->factory, NULL, INITIAL_POOL_SIZE, \n                              POOL_INCREMENT_SIZE, NULL);\n    hreq = PJ_POOL_ZALLOC_T(own_pool, struct pj_http_req);\n    if (!hreq)\n        return PJ_ENOMEM;\n\n    /* Initialization */\n    hreq->pool = own_pool;\n    hreq->ioqueue = ioqueue;\n    hreq->timer = timer;\n    hreq->asock = NULL;\n    pj_memcpy(&hreq->cb, hcb, sizeof(*hcb));\n    hreq->state = IDLE;\n    hreq->resolved = PJ_FALSE;\n    hreq->buffer.ptr = NULL;\n    pj_timer_entry_init(&hreq->timer_entry, 0, hreq, &on_timeout);\n\n    /* Initialize parameter */\n    if (param) {\n        pj_memcpy(&hreq->param, param, sizeof(*param));\n        /* TODO: validate the param here\n         * Should we validate the method as well? If yes, based on all HTTP\n         * methods or based on supported methods only? For the later, one \n         * drawback would be that you can't use this if the method is not \n         * officially supported\n         */\n        PJ_ASSERT_RETURN(hreq->param.addr_family==PJ_AF_UNSPEC || \n                         hreq->param.addr_family==PJ_AF_INET || \n                         hreq->param.addr_family==PJ_AF_INET6, PJ_EAFNOTSUP);\n        PJ_ASSERT_RETURN(!pj_strcmp2(&hreq->param.version, HTTP_1_0) || \n                         !pj_strcmp2(&hreq->param.version, HTTP_1_1), \n                         PJ_ENOTSUP); \n        pj_time_val_normalize(&hreq->param.timeout);\n    } else {\n        pj_http_req_param_default(&hreq->param);\n    }\n\n    /* Parse the URL */\n    if (!pj_strdup_with_null(hreq->pool, &hreq->url, url)) {\n\tpj_pool_release(hreq->pool);\n        return PJ_ENOMEM;\n    }\n    status = pj_http_req_parse_url(&hreq->url, &hreq->hurl);\n    if (status != PJ_SUCCESS) {\n\tpj_pool_release(hreq->pool);\n        return status; // Invalid URL supplied\n    }\n\n    /* If URL contains username/password, move them to credential and\n     * remove them from the URL.\n     */\n    if ((at_pos=get_url_at_pos(hreq->url.ptr, hreq->url.slen)) != NULL) {\n\tpj_str_t tmp;\n\tchar *user_pos = pj_strchr(&hreq->url, '/');\n\tint removed_len;\n\n\t/* Save credential first, unescape the string */\n\ttmp = pj_str_unescape(hreq->pool, &hreq->hurl.username);;\n\tpj_strdup(hreq->pool, &hreq->param.auth_cred.username, &tmp);\n\n\ttmp = pj_str_unescape(hreq->pool, &hreq->hurl.passwd);\n\tpj_strdup(hreq->pool, &hreq->param.auth_cred.data, &tmp);\n\n\threq->hurl.username.ptr = hreq->hurl.passwd.ptr = NULL;\n\threq->hurl.username.slen = hreq->hurl.passwd.slen = 0;\n\n\t/* Remove \"username:password@\" from the URL */\n\tpj_assert(user_pos != 0 && user_pos < at_pos);\n\tuser_pos += 2;\n\tremoved_len = (int)(at_pos + 1 - user_pos);\n\tpj_memmove(user_pos, at_pos+1, hreq->url.ptr+hreq->url.slen-at_pos-1);\n\threq->url.slen -= removed_len;\n\n\t/* Need to adjust hostname and path pointers due to memmove*/\n\tif (hreq->hurl.host.ptr > user_pos &&\n\t    hreq->hurl.host.ptr < user_pos + hreq->url.slen)\n\t{\n\t    hreq->hurl.host.ptr -= removed_len;\n\t}\n\t/* path may come from a string constant, don't shift it if so */\n\tif (hreq->hurl.path.ptr > user_pos &&\n\t    hreq->hurl.path.ptr < user_pos + hreq->url.slen)\n\t{\n\t    hreq->hurl.path.ptr -= removed_len;\n\t}\n    }\n\n    *http_req = hreq;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_bool_t) pj_http_req_is_running(const pj_http_req *http_req)\n{\n   PJ_ASSERT_RETURN(http_req, PJ_FALSE);\n   return (http_req->state != IDLE);\n}\n\nPJ_DEF(void*) pj_http_req_get_user_data(pj_http_req *http_req)\n{\n    PJ_ASSERT_RETURN(http_req, NULL);\n    return http_req->param.user_data;\n}\n\nstatic pj_status_t start_http_req(pj_http_req *http_req,\n                                  pj_bool_t notify_on_fail)\n{\n    pj_sock_t sock = PJ_INVALID_SOCKET;\n    pj_status_t status;\n    pj_activesock_cb asock_cb;\n    int retry = 0;\n\n    PJ_ASSERT_RETURN(http_req, PJ_EINVAL);\n    /* Http request is not idle, a request was initiated before and \n     * is still in progress\n     */\n    PJ_ASSERT_RETURN(http_req->state == IDLE, PJ_EBUSY);\n\n    /* Reset few things to make sure restarting works */\n    http_req->error = 0;\n    http_req->response.headers.count = 0;\n    pj_bzero(&http_req->tcp_state, sizeof(http_req->tcp_state));\n\n    if (!http_req->resolved) {\n        /* Resolve the Internet address of the host */\n        status = pj_sockaddr_init(http_req->param.addr_family, \n                                  &http_req->addr, &http_req->hurl.host,\n\t\t\t\t  http_req->hurl.port);\n\tif (status != PJ_SUCCESS ||\n\t    !pj_sockaddr_has_addr(&http_req->addr) ||\n\t    (http_req->param.addr_family==pj_AF_INET() &&\n\t     http_req->addr.ipv4.sin_addr.s_addr==PJ_INADDR_NONE))\n\t{\n\t    goto on_return;\n        }\n        http_req->resolved = PJ_TRUE;\n    }\n\n    status = pj_sock_socket(http_req->param.addr_family, pj_SOCK_STREAM(), \n                            0, &sock);\n    if (status != PJ_SUCCESS)\n        goto on_return; // error creating socket\n\n    pj_bzero(&asock_cb, sizeof(asock_cb));\n    asock_cb.on_data_read = &http_on_data_read;\n    asock_cb.on_data_sent = &http_on_data_sent;\n    asock_cb.on_connect_complete = &http_on_connect;\n\t\n    do\n    {\n\tpj_sockaddr_in bound_addr;\n\tpj_uint16_t port = 0;\n\n\t/* If we are using port restriction.\n\t * Get a random port within the range\n\t */\n\tif (http_req->param.source_port_range_start != 0) {\n\t    port = (pj_uint16_t)\n\t\t   (http_req->param.source_port_range_start +\n\t\t    (pj_rand() % http_req->param.source_port_range_size));\n\t}\n\n\tpj_sockaddr_in_init(&bound_addr, NULL, port);\n\tstatus = pj_sock_bind(sock, &bound_addr, sizeof(bound_addr));\n\n    } while (status != PJ_SUCCESS && (retry++ < http_req->param.max_retries));\n\n    if (status != PJ_SUCCESS) {\n\tPJ_PERROR(1,(THIS_FILE, status,\n\t\t     \"Unable to bind to the requested port\"));\n\tpj_sock_close(sock);\n\tgoto on_return;\n    }\n\n    // TODO: should we set whole data to 0 by default?\n    // or add it in the param?\n    status = pj_activesock_create(http_req->pool, sock, pj_SOCK_STREAM(), \n                                  NULL, http_req->ioqueue,\n\t\t\t\t  &asock_cb, http_req, &http_req->asock);\n    if (status != PJ_SUCCESS) {\n        pj_sock_close(sock);\n\tgoto on_return; // error creating activesock\n    }\n\n    /* Schedule timeout timer for the request */\n    pj_assert(http_req->timer_entry.id == 0);\n    http_req->timer_entry.id = 1;\n    status = pj_timer_heap_schedule(http_req->timer, &http_req->timer_entry, \n                                    &http_req->param.timeout);\n    if (status != PJ_SUCCESS) {\n        http_req->timer_entry.id = 0;\n\tgoto on_return; // error scheduling timer\n    }\n\n    /* Connect to host */\n    http_req->state = CONNECTING;\n    status = pj_activesock_start_connect(http_req->asock, http_req->pool, \n                                         (pj_sock_t *)&(http_req->addr), \n                                         pj_sockaddr_get_len(&http_req->addr));\n    if (status == PJ_SUCCESS) {\n        http_req->state = SENDING_REQUEST;\n        status =  http_req_start_sending(http_req);\n        if (status != PJ_SUCCESS)\n            goto on_return;\n    } else if (status != PJ_EPENDING) {\n        goto on_return; // error connecting\n    }\n\n    return PJ_SUCCESS;\n\non_return:\n    http_req->error = status;\n    if (notify_on_fail)\n\tpj_http_req_cancel(http_req, PJ_TRUE);\n    else\n\thttp_req_end_request(http_req);\n\n    return status;\n}\n\n/* Starts an asynchronous HTTP request to the URL specified. */\nPJ_DEF(pj_status_t) pj_http_req_start(pj_http_req *http_req)\n{\n    return start_http_req(http_req, PJ_FALSE);\n}\n\n/* Respond to basic authentication challenge */\nstatic pj_status_t auth_respond_basic(pj_http_req *hreq)\n{\n    /* Basic authentication:\n     *      credentials       = \"Basic\" basic-credentials\n     *      basic-credentials = base64-user-pass\n     *      base64-user-pass  = <base64 [4] encoding of user-pass>\n     *      user-pass         = userid \":\" password\n     *\n     * Sample:\n     *       Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n     */\n    pj_str_t user_pass;\n    pj_http_header_elmt *phdr;\n    int len;\n\n    /* Use send buffer to store userid \":\" password */\n    user_pass.ptr = hreq->buffer.ptr;\n    pj_strcpy(&user_pass, &hreq->param.auth_cred.username);\n    pj_strcat2(&user_pass, \":\");\n    pj_strcat(&user_pass, &hreq->param.auth_cred.data);\n\n    /* Create Authorization header */\n    phdr = &hreq->param.headers.header[hreq->param.headers.count++];\n    pj_bzero(phdr, sizeof(*phdr));\n    if (hreq->response.status_code == 401)\n\tphdr->name = pj_str(\"Authorization\");\n    else\n\tphdr->name = pj_str(\"Proxy-Authorization\");\n\n    len = (int)(PJ_BASE256_TO_BASE64_LEN(user_pass.slen) + 10);\n    phdr->value.ptr = (char*)pj_pool_alloc(hreq->pool, len);\n    phdr->value.slen = 0;\n\n    pj_strcpy2(&phdr->value, \"Basic \");\n    len -= (int)phdr->value.slen;\n    pj_base64_encode((pj_uint8_t*)user_pass.ptr, (int)user_pass.slen,\n\t\t     phdr->value.ptr + phdr->value.slen, &len);\n    phdr->value.slen += len;\n\n    return PJ_SUCCESS;\n}\n\n/** Length of digest string. */\n#define MD5_STRLEN 32\n/* A macro just to get rid of type mismatch between char and unsigned char */\n#define MD5_APPEND(pms,buf,len)\tpj_md5_update(pms, (const pj_uint8_t*)buf, \\\n\t\t   (unsigned)len)\n\n/* Transform digest to string.\n * output must be at least PJSIP_MD5STRLEN+1 bytes.\n *\n * NOTE: THE OUTPUT STRING IS NOT NULL TERMINATED!\n */\nstatic void digest2str(const unsigned char digest[], char *output)\n{\n    int i;\n    for (i = 0; i<16; ++i) {\n\tpj_val_to_hex_digit(digest[i], output);\n\toutput += 2;\n    }\n}\n\nstatic void auth_create_digest_response(pj_str_t *result,\n\t\t\t\t\tconst pj_http_auth_cred *cred,\n\t\t\t\t        const pj_str_t *nonce,\n\t\t\t\t        const pj_str_t *nc,\n\t\t\t\t        const pj_str_t *cnonce,\n\t\t\t\t        const pj_str_t *qop,\n\t\t\t\t        const pj_str_t *uri,\n\t\t\t\t        const pj_str_t *realm,\n\t\t\t\t        const pj_str_t *method)\n{\n    char ha1[MD5_STRLEN];\n    char ha2[MD5_STRLEN];\n    unsigned char digest[16];\n    pj_md5_context pms;\n\n    pj_assert(result->slen >= MD5_STRLEN);\n\n    TRACE_((THIS_FILE, \"Begin creating digest\"));\n\n    if (cred->data_type == 0) {\n\t/***\n\t *** ha1 = MD5(username \":\" realm \":\" password)\n\t ***/\n\tpj_md5_init(&pms);\n\tMD5_APPEND( &pms, cred->username.ptr, cred->username.slen);\n\tMD5_APPEND( &pms, \":\", 1);\n\tMD5_APPEND( &pms, realm->ptr, realm->slen);\n\tMD5_APPEND( &pms, \":\", 1);\n\tMD5_APPEND( &pms, cred->data.ptr, cred->data.slen);\n\tpj_md5_final(&pms, digest);\n\n\tdigest2str(digest, ha1);\n\n    } else if (cred->data_type == 1) {\n\tpj_assert(cred->data.slen == 32);\n\tpj_memcpy( ha1, cred->data.ptr, cred->data.slen );\n    } else {\n\tpj_assert(!\"Invalid data_type\");\n    }\n\n    TRACE_((THIS_FILE, \"  ha1=%.32s\", ha1));\n\n    /***\n     *** ha2 = MD5(method \":\" req_uri)\n     ***/\n    pj_md5_init(&pms);\n    MD5_APPEND( &pms, method->ptr, method->slen);\n    MD5_APPEND( &pms, \":\", 1);\n    MD5_APPEND( &pms, uri->ptr, uri->slen);\n    pj_md5_final(&pms, digest);\n    digest2str(digest, ha2);\n\n    TRACE_((THIS_FILE, \"  ha2=%.32s\", ha2));\n\n    /***\n     *** When qop is not used:\n     ***    response = MD5(ha1 \":\" nonce \":\" ha2)\n     ***\n     *** When qop=auth is used:\n     ***    response = MD5(ha1 \":\" nonce \":\" nc \":\" cnonce \":\" qop \":\" ha2)\n     ***/\n    pj_md5_init(&pms);\n    MD5_APPEND( &pms, ha1, MD5_STRLEN);\n    MD5_APPEND( &pms, \":\", 1);\n    MD5_APPEND( &pms, nonce->ptr, nonce->slen);\n    if (qop && qop->slen != 0) {\n\tMD5_APPEND( &pms, \":\", 1);\n\tMD5_APPEND( &pms, nc->ptr, nc->slen);\n\tMD5_APPEND( &pms, \":\", 1);\n\tMD5_APPEND( &pms, cnonce->ptr, cnonce->slen);\n\tMD5_APPEND( &pms, \":\", 1);\n\tMD5_APPEND( &pms, qop->ptr, qop->slen);\n    }\n    MD5_APPEND( &pms, \":\", 1);\n    MD5_APPEND( &pms, ha2, MD5_STRLEN);\n\n    /* This is the final response digest. */\n    pj_md5_final(&pms, digest);\n\n    /* Convert digest to string and store in chal->response. */\n    result->slen = MD5_STRLEN;\n    digest2str(digest, result->ptr);\n\n    TRACE_((THIS_FILE, \"  digest=%.32s\", result->ptr));\n    TRACE_((THIS_FILE, \"Digest created\"));\n}\n\n/* Find out if qop offer contains \"auth\" token */\nstatic pj_bool_t auth_has_qop( pj_pool_t *pool, const pj_str_t *qop_offer)\n{\n    pj_str_t qop;\n    char *p;\n\n    pj_strdup_with_null( pool, &qop, qop_offer);\n    p = qop.ptr;\n    while (*p) {\n\t*p = (char)pj_tolower(*p);\n\t++p;\n    }\n\n    p = qop.ptr;\n    while (*p) {\n\tif (*p=='a' && *(p+1)=='u' && *(p+2)=='t' && *(p+3)=='h') {\n\t    int e = *(p+4);\n\t    if (e=='\"' || e==',' || e==0)\n\t\treturn PJ_TRUE;\n\t    else\n\t\tp += 4;\n\t} else {\n\t    ++p;\n\t}\n    }\n\n    return PJ_FALSE;\n}\n\n#define STR_PREC(s) (int)(s).slen, (s).ptr\n\n/* Respond to digest authentication */\nstatic pj_status_t auth_respond_digest(pj_http_req *hreq)\n{\n    const pj_http_auth_chal *chal = &hreq->response.auth_chal;\n    const pj_http_auth_cred *cred = &hreq->param.auth_cred;\n    pj_http_header_elmt *phdr;\n    char digest_response_buf[MD5_STRLEN];\n    int len;\n    pj_str_t digest_response;\n\n    /* Check algorithm is supported. We only support MD5 */\n    if (chal->algorithm.slen!=0 &&\n\tpj_stricmp2(&chal->algorithm, \"MD5\"))\n    {\n\tTRACE_((THIS_FILE, \"Error: Unsupported digest algorithm \\\"%.*s\\\"\",\n\t\t  chal->algorithm.slen, chal->algorithm.ptr));\n\treturn PJ_ENOTSUP;\n    }\n\n    /* Add Authorization header */\n    phdr = &hreq->param.headers.header[hreq->param.headers.count++];\n    pj_bzero(phdr, sizeof(*phdr));\n    if (hreq->response.status_code == 401)\n\tphdr->name = pj_str(\"Authorization\");\n    else\n\tphdr->name = pj_str(\"Proxy-Authorization\");\n\n    /* Allocate space for the header */\n    len = (int)(8 + /* Digest */\n\t  16 + hreq->param.auth_cred.username.slen + /* username= */\n\t  12 + chal->realm.slen + /* realm= */\n\t  12 + chal->nonce.slen + /* nonce= */\n\t  8 + hreq->hurl.path.slen + /* uri= */\n\t  16 + /* algorithm=MD5 */\n\t  16 + MD5_STRLEN + /* response= */\n\t  12 + /* qop=auth */\n\t  8 + /* nc=.. */\n\t  30 + /* cnonce= */\n\t  12 + chal->opaque.slen + /* opaque=\"..\" */\n\t  0);\n    phdr->value.ptr = (char*)pj_pool_alloc(hreq->pool, len);\n\n    /* Configure buffer to temporarily store the digest */\n    digest_response.ptr = digest_response_buf;\n    digest_response.slen = MD5_STRLEN;\n\n    if (chal->qop.slen == 0) {\n\tconst pj_str_t STR_MD5 = { \"MD5\", 3 };\n\tint max_len;\n\n\t/* Server doesn't require quality of protection. */\n\tauth_create_digest_response(&digest_response, cred,\n\t\t\t\t    &chal->nonce, NULL, NULL,  NULL,\n\t\t\t\t    &hreq->hurl.path, &chal->realm,\n\t\t\t\t    &hreq->param.method);\n\n\tmax_len = len;\n\tlen = pj_ansi_snprintf(\n\t\tphdr->value.ptr, max_len,\n\t\t\"Digest username=\\\"%.*s\\\", \"\n\t\t\"realm=\\\"%.*s\\\", \"\n\t\t\"nonce=\\\"%.*s\\\", \"\n\t\t\"uri=\\\"%.*s\\\", \"\n\t\t\"algorithm=%.*s, \"\n\t\t\"response=\\\"%.*s\\\"\",\n\t\tSTR_PREC(cred->username),\n\t\tSTR_PREC(chal->realm),\n\t\tSTR_PREC(chal->nonce),\n\t\tSTR_PREC(hreq->hurl.path),\n\t\tSTR_PREC(STR_MD5),\n\t\tSTR_PREC(digest_response));\n\tif (len < 0 || len >= max_len)\n\t    return PJ_ETOOSMALL;\n\tphdr->value.slen = len;\n\n    } else if (auth_has_qop(hreq->pool, &chal->qop)) {\n\t/* Server requires quality of protection.\n\t * We respond with selecting \"qop=auth\" protection.\n\t */\n\tconst pj_str_t STR_MD5 = { \"MD5\", 3 };\n\tconst pj_str_t qop = pj_str(\"auth\");\n\tconst pj_str_t nc = pj_str(\"00000001\");\n\tconst pj_str_t cnonce = pj_str(\"b39971\");\n\tint max_len;\n\n\tauth_create_digest_response(&digest_response, cred,\n\t\t\t\t    &chal->nonce, &nc, &cnonce, &qop,\n\t\t\t\t    &hreq->hurl.path, &chal->realm,\n\t\t\t\t    &hreq->param.method);\n\tmax_len = len;\n\tlen = pj_ansi_snprintf(\n\t\tphdr->value.ptr, max_len,\n\t\t\"Digest username=\\\"%.*s\\\", \"\n\t\t\"realm=\\\"%.*s\\\", \"\n\t\t\"nonce=\\\"%.*s\\\", \"\n\t\t\"uri=\\\"%.*s\\\", \"\n\t\t\"algorithm=%.*s, \"\n\t\t\"response=\\\"%.*s\\\", \"\n\t\t\"qop=%.*s, \"\n\t\t\"nc=%.*s, \"\n\t\t\"cnonce=\\\"%.*s\\\"\",\n\t\tSTR_PREC(cred->username),\n\t\tSTR_PREC(chal->realm),\n\t\tSTR_PREC(chal->nonce),\n\t\tSTR_PREC(hreq->hurl.path),\n\t\tSTR_PREC(STR_MD5),\n\t\tSTR_PREC(digest_response),\n\t\tSTR_PREC(qop),\n\t\tSTR_PREC(nc),\n\t\tSTR_PREC(cnonce));\n\tif (len < 0 || len >= max_len)\n\t    return PJ_ETOOSMALL;\n\tphdr->value.slen = len;\n\n\tif (chal->opaque.slen) {\n\t    pj_strcat2(&phdr->value, \", opaque=\\\"\");\n\t    pj_strcat(&phdr->value, &chal->opaque);\n\t    pj_strcat2(&phdr->value, \"\\\"\");\n\t}\n\n    } else {\n\t/* Server requires quality protection that we don't support. */\n\tTRACE_((THIS_FILE, \"Error: Unsupported qop offer %.*s\",\n\t\tchal->qop.slen, chal->qop.ptr));\n\treturn PJ_ENOTSUP;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void restart_req_with_auth(pj_http_req *hreq)\n{\n    pj_http_auth_chal *chal = &hreq->response.auth_chal;\n    pj_http_auth_cred *cred = &hreq->param.auth_cred;\n    pj_status_t status;\n\n    if (hreq->param.headers.count >= PJ_HTTP_HEADER_SIZE) {\n\tTRACE_((THIS_FILE, \"Error: no place to put Authorization header\"));\n\threq->auth_state = AUTH_DONE;\n\treturn;\n    }\n\n    /* If credential specifies specific scheme, make sure they match */\n    if (cred->scheme.slen && pj_stricmp(&chal->scheme, &cred->scheme)) {\n\tstatus = PJ_ENOTSUP;\n\tTRACE_((THIS_FILE, \"Error: auth schemes mismatch\"));\n\tgoto on_error;\n    }\n\n    /* If credential specifies specific realm, make sure they match */\n    if (cred->realm.slen && pj_stricmp(&chal->realm, &cred->realm)) {\n\tstatus = PJ_ENOTSUP;\n\tTRACE_((THIS_FILE, \"Error: auth realms mismatch\"));\n\tgoto on_error;\n    }\n\n    if (!pj_stricmp2(&chal->scheme, \"basic\")) {\n\tstatus = auth_respond_basic(hreq);\n    } else if (!pj_stricmp2(&chal->scheme, \"digest\")) {\n\tstatus = auth_respond_digest(hreq);\n    } else {\n\tTRACE_((THIS_FILE, \"Error: unsupported HTTP auth scheme\"));\n\tstatus = PJ_ENOTSUP;\n    }\n\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    http_req_end_request(hreq);\n\n    status = start_http_req(hreq, PJ_TRUE);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    hreq->auth_state = AUTH_RETRYING;\n    return;\n\non_error:\n    hreq->auth_state = AUTH_DONE;\n}\n\n\n/* snprintf() to a pj_str_t struct with an option to append the \n * result at the back of the string.\n */\nstatic void str_snprintf(pj_str_t *s, size_t size, \n\t\t\t pj_bool_t append, const char *format, ...)\n{\n    va_list arg;\n    int retval;\n\n    va_start(arg, format);\n    if (!append)\n        s->slen = 0;\n    size -= s->slen;\n    retval = pj_ansi_vsnprintf(s->ptr + s->slen, \n                               size, format, arg);\n    s->slen += ((retval < (int)size) ? retval : size - 1);\n    va_end(arg);\n}\n\nstatic pj_status_t http_req_start_sending(pj_http_req *hreq)\n{\n    pj_status_t status;\n    pj_str_t pkt;\n    pj_ssize_t len;\n    pj_size_t i;\n\n    PJ_ASSERT_RETURN(hreq->state == SENDING_REQUEST || \n                     hreq->state == SENDING_REQUEST_BODY, PJ_EBUG);\n\n    if (hreq->state == SENDING_REQUEST) {\n        /* Prepare the request data */\n        if (!hreq->buffer.ptr)\n            hreq->buffer.ptr = (char*)pj_pool_alloc(hreq->pool, BUF_SIZE);\n        pj_strassign(&pkt, &hreq->buffer);\n        pkt.slen = 0;\n        /* Start-line */\n        str_snprintf(&pkt, BUF_SIZE, PJ_TRUE, \"%.*s %.*s %s/%.*s\\r\\n\",\n                     STR_PREC(hreq->param.method), \n                     STR_PREC(hreq->hurl.path),\n                     get_protocol(&hreq->hurl.protocol), \n                     STR_PREC(hreq->param.version));\n        /* Header field \"Host\" */\n        str_snprintf(&pkt, BUF_SIZE, PJ_TRUE, \"Host: %.*s:%d\\r\\n\",\n                     STR_PREC(hreq->hurl.host), hreq->hurl.port);\n        if (!pj_strcmp2(&hreq->param.method, http_method_names[HTTP_PUT])) {\n            char buf[16];\n\n            /* Header field \"Content-Length\" */\n            pj_utoa(hreq->param.reqdata.total_size ? \n                    (unsigned long)hreq->param.reqdata.total_size: \n                    (unsigned long)hreq->param.reqdata.size, buf);\n            str_snprintf(&pkt, BUF_SIZE, PJ_TRUE, \"%s: %s\\r\\n\",\n                         CONTENT_LENGTH, buf);\n        }\n\n        /* Append user-specified headers */\n        for (i = 0; i < hreq->param.headers.count; i++) {\n            str_snprintf(&pkt, BUF_SIZE, PJ_TRUE, \"%.*s: %.*s\\r\\n\",\n                         STR_PREC(hreq->param.headers.header[i].name),\n                         STR_PREC(hreq->param.headers.header[i].value));\n        }\n        if (pkt.slen >= BUF_SIZE - 1) {\n            status = PJLIB_UTIL_EHTTPINSBUF;\n            goto on_return;\n        }\n\n        pj_strcat2(&pkt, \"\\r\\n\");\n        pkt.ptr[pkt.slen] = 0;\n        TRACE_((THIS_FILE, \"%s\", pkt.ptr));\n    } else {\n        pkt.ptr = (char*)hreq->param.reqdata.data;\n        pkt.slen = hreq->param.reqdata.size;\n    }\n\n    /* Send the request */\n    len = pj_strlen(&pkt);\n    pj_ioqueue_op_key_init(&hreq->op_key, sizeof(hreq->op_key));\n    hreq->tcp_state.send_size = len;\n    hreq->tcp_state.current_send_size = 0;\n    status = pj_activesock_send(hreq->asock, &hreq->op_key, \n                                pkt.ptr, &len, 0);\n\n    if (status == PJ_SUCCESS) {\n        http_on_data_sent(hreq->asock, &hreq->op_key, len);\n    } else if (status != PJ_EPENDING) {\n        goto on_return; // error sending data\n    }\n\n    return PJ_SUCCESS;\n\non_return:\n    http_req_end_request(hreq);\n    return status;\n}\n\nstatic pj_status_t http_req_start_reading(pj_http_req *hreq)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(hreq->state == REQUEST_SENT, PJ_EBUG);\n\n    /* Receive the response */\n    hreq->state = READING_RESPONSE;\n    hreq->tcp_state.current_read_size = 0;\n    pj_assert(hreq->buffer.ptr);\n    status = pj_activesock_start_read2(hreq->asock, hreq->pool, BUF_SIZE, \n                                       (void**)&hreq->buffer.ptr, 0);\n    if (status != PJ_SUCCESS) {\n        /* Error reading */\n        http_req_end_request(hreq);\n        return status;\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t http_req_end_request(pj_http_req *hreq)\n{\n    if (hreq->asock) {\n\tpj_activesock_close(hreq->asock);\n        hreq->asock = NULL;\n    }\n\n    /* Cancel query timeout timer. */\n    if (hreq->timer_entry.id != 0) {\n        pj_timer_heap_cancel(hreq->timer, &hreq->timer_entry);\n        /* Invalidate id. */\n        hreq->timer_entry.id = 0;\n    }\n\n    hreq->state = IDLE;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_http_req_cancel(pj_http_req *http_req,\n                                       pj_bool_t notify)\n{\n    http_req->state = ABORTING;\n\n    http_req_end_request(http_req);\n\n    if (notify && http_req->cb.on_complete) {\n        (*http_req->cb.on_complete)(http_req, (!http_req->error? \n                                    PJ_ECANCELLED: http_req->error), NULL);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_http_req_destroy(pj_http_req *http_req)\n{\n    PJ_ASSERT_RETURN(http_req, PJ_EINVAL);\n    \n    /* If there is any pending request, cancel it */\n    if (http_req->state != IDLE) {\n        pj_http_req_cancel(http_req, PJ_FALSE);\n    }\n\n    pj_pool_release(http_req->pool);\n\n    return PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/json.c",
    "content": "/* $Id$ */\n/*\n * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjlib-util/json.h>\n#include <pjlib-util/errno.h>\n#include <pjlib-util/scanner.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n#include <pj/except.h>\n#include <pj/string.h>\n\n#define EL_INIT(p_el, nm, typ)\tdo { \\\n\t\t\t\t    if (nm) { \\\n\t\t\t\t\tp_el->name = *nm; \\\n\t\t\t\t    } else { \\\n\t\t\t\t\tp_el->name.ptr = (char*)\"\"; \\\n\t\t\t\t\tp_el->name.slen = 0; \\\n\t\t\t\t    } \\\n\t\t\t\t    p_el->type = typ; \\\n\t\t\t\t} while (0)\n\nstruct write_state;\nstruct parse_state;\n\n#define NO_NAME\t1\n\nstatic pj_status_t elem_write(const pj_json_elem *elem,\n                              struct write_state *st,\n                              unsigned flags);\nstatic pj_json_elem* parse_elem_throw(struct parse_state *st,\n                                      pj_json_elem *elem);\n\n\nPJ_DEF(void) pj_json_elem_null(pj_json_elem *el, pj_str_t *name)\n{\n    EL_INIT(el, name, PJ_JSON_VAL_NULL);\n}\n\nPJ_DEF(void) pj_json_elem_bool(pj_json_elem *el, pj_str_t *name,\n                                pj_bool_t val)\n{\n    EL_INIT(el, name, PJ_JSON_VAL_BOOL);\n    el->value.is_true = val;\n}\n\nPJ_DEF(void) pj_json_elem_number(pj_json_elem *el, pj_str_t *name,\n                                  float val)\n{\n    EL_INIT(el, name, PJ_JSON_VAL_NUMBER);\n    el->value.num = val;\n}\n\nPJ_DEF(void) pj_json_elem_string( pj_json_elem *el, pj_str_t *name,\n                                  pj_str_t *value)\n{\n    EL_INIT(el, name, PJ_JSON_VAL_STRING);\n    el->value.str = *value;\n}\n\nPJ_DEF(void) pj_json_elem_array(pj_json_elem *el, pj_str_t *name)\n{\n    EL_INIT(el, name, PJ_JSON_VAL_ARRAY);\n    pj_list_init(&el->value.children);\n}\n\nPJ_DEF(void) pj_json_elem_obj(pj_json_elem *el, pj_str_t *name)\n{\n    EL_INIT(el, name, PJ_JSON_VAL_OBJ);\n    pj_list_init(&el->value.children);\n}\n\nPJ_DEF(void) pj_json_elem_add(pj_json_elem *el, pj_json_elem *child)\n{\n    pj_assert(el->type == PJ_JSON_VAL_OBJ || el->type == PJ_JSON_VAL_ARRAY);\n    pj_list_push_back(&el->value.children, child);\n}\n\nstruct parse_state\n{\n    pj_pool_t\t\t*pool;\n    pj_scanner\t\t scanner;\n    pj_json_err_info \t*err_info;\n    pj_cis_t\t\t float_spec;\t/* numbers with dot! */\n};\n\nstatic pj_status_t parse_children(struct parse_state *st,\n                                  pj_json_elem *parent)\n{\n    char end_quote = (parent->type == PJ_JSON_VAL_ARRAY)? ']' : '}';\n\n    pj_scan_get_char(&st->scanner);\n\n    while (*st->scanner.curptr != end_quote) {\n\tpj_json_elem *child;\n\n\twhile (*st->scanner.curptr == ',')\n\t    pj_scan_get_char(&st->scanner);\n\n\tif (*st->scanner.curptr == end_quote)\n\t    break;\n\n\tchild = parse_elem_throw(st, NULL);\n\tif (!child)\n\t    return PJLIB_UTIL_EINJSON;\n\n\tpj_json_elem_add(parent, child);\n    }\n\n    pj_scan_get_char(&st->scanner);\n    return PJ_SUCCESS;\n}\n\n/* Return 0 if success or the index of the invalid char in the string */\nstatic unsigned parse_quoted_string(struct parse_state *st,\n                                    pj_str_t *output)\n{\n    pj_str_t token;\n    char *op, *ip, *iend;\n\n    pj_scan_get_quote(&st->scanner, '\"', '\"', &token);\n\n    /* Remove the quote characters */\n    token.ptr++;\n    token.slen-=2;\n\n    if (pj_strchr(&token, '\\\\') == NULL) {\n\t*output = token;\n\treturn 0;\n    }\n\n    output->ptr = op = pj_pool_alloc(st->pool, token.slen);\n\n    ip = token.ptr;\n    iend = token.ptr + token.slen;\n\n    while (ip != iend) {\n\tif (*ip == '\\\\') {\n\t    ++ip;\n\t    if (ip==iend) {\n\t\tgoto on_error;\n\t    }\n\t    if (*ip == 'u') {\n\t\tip++;\n\t\tif (iend - ip < 4) {\n\t\t    ip = iend -1;\n\t\t    goto on_error;\n\t\t}\n\t\t/* Only use the last two hext digits because we're on\n\t\t * ASCII */\n\t\t*op++ = (char)(pj_hex_digit_to_val(ip[2]) * 16 +\n\t\t\t       pj_hex_digit_to_val(ip[3]));\n\t\tip += 4;\n\t    } else if (*ip=='\"' || *ip=='\\\\' || *ip=='/') {\n\t\t*op++ = *ip++;\n\t    } else if (*ip=='b') {\n\t\t*op++ = '\\b';\n\t\tip++;\n\t    } else if (*ip=='f') {\n\t\t*op++ = '\\f';\n\t\tip++;\n\t    } else if (*ip=='n') {\n\t\t*op++ = '\\n';\n\t\tip++;\n\t    } else if (*ip=='r') {\n\t\t*op++ = '\\r';\n\t\tip++;\n\t    } else if (*ip=='t') {\n\t\t*op++ = '\\t';\n\t\tip++;\n\t    } else {\n\t\tgoto on_error;\n\t    }\n\t} else {\n\t    *op++ = *ip++;\n\t}\n    }\n\n    output->slen = op - output->ptr;\n    return 0;\n\non_error:\n    output->slen = op - output->ptr;\n    return (unsigned)(ip - token.ptr);\n}\n\nstatic pj_json_elem* parse_elem_throw(struct parse_state *st,\n                                      pj_json_elem *elem)\n{\n    pj_str_t name = {NULL, 0}, value = {NULL, 0};\n    pj_str_t token;\n\n    if (!elem)\n\telem = pj_pool_alloc(st->pool, sizeof(*elem));\n\n    /* Parse name */\n    if (*st->scanner.curptr == '\"') {\n\tpj_scan_get_char(&st->scanner);\n\tpj_scan_get_until_ch(&st->scanner, '\"', &token);\n\tpj_scan_get_char(&st->scanner);\n\n\tif (*st->scanner.curptr == ':') {\n\t    pj_scan_get_char(&st->scanner);\n\t    name = token;\n\t} else {\n\t    value = token;\n\t}\n    }\n\n    if (value.slen) {\n\t/* Element with string value and no name */\n\tpj_json_elem_string(elem, &name, &value);\n\treturn elem;\n    }\n\n    /* Parse value */\n    if (pj_cis_match(&st->float_spec, *st->scanner.curptr) ||\n\t*st->scanner.curptr == '-')\n    {\n\tfloat val;\n\tpj_bool_t neg = PJ_FALSE;\n\n\tif (*st->scanner.curptr == '-') {\n\t    pj_scan_get_char(&st->scanner);\n\t    neg = PJ_TRUE;\n\t}\n\n\tpj_scan_get(&st->scanner, &st->float_spec, &token);\n\tval = pj_strtof(&token);\n\tif (neg) val = -val;\n\n\tpj_json_elem_number(elem, &name, val);\n\n    } else if (*st->scanner.curptr == '\"') {\n\tunsigned err;\n\tchar *start = st->scanner.curptr;\n\n\terr = parse_quoted_string(st, &token);\n\tif (err) {\n\t    st->scanner.curptr = start + err;\n\t    return NULL;\n\t}\n\n\tpj_json_elem_string(elem, &name, &token);\n\n    } else if (pj_isalpha(*st->scanner.curptr)) {\n\n\tif (pj_scan_strcmp(&st->scanner, \"false\", 5)==0) {\n\t    pj_json_elem_bool(elem, &name, PJ_FALSE);\n\t    pj_scan_advance_n(&st->scanner, 5, PJ_TRUE);\n\t} else if (pj_scan_strcmp(&st->scanner, \"true\", 4)==0) {\n\t    pj_json_elem_bool(elem, &name, PJ_TRUE);\n\t    pj_scan_advance_n(&st->scanner, 4, PJ_TRUE);\n\t} else if (pj_scan_strcmp(&st->scanner, \"null\", 4)==0) {\n\t    pj_json_elem_null(elem, &name);\n\t    pj_scan_advance_n(&st->scanner, 4, PJ_TRUE);\n\t} else {\n\t    return NULL;\n\t}\n\n    } else if (*st->scanner.curptr == '[') {\n\tpj_json_elem_array(elem, &name);\n\tif (parse_children(st, elem) != PJ_SUCCESS)\n\t    return NULL;\n\n    } else if (*st->scanner.curptr == '{') {\n\tpj_json_elem_obj(elem, &name);\n\tif (parse_children(st, elem) != PJ_SUCCESS)\n\t    return NULL;\n\n    } else {\n\treturn NULL;\n    }\n\n    return elem;\n}\n\nstatic void on_syntax_error(pj_scanner *scanner)\n{\n    PJ_UNUSED_ARG(scanner);\n    PJ_THROW(11);\n}\n\nPJ_DEF(pj_json_elem*) pj_json_parse(pj_pool_t *pool,\n                                    char *buffer,\n                                    unsigned *size,\n                                    pj_json_err_info *err_info)\n{\n    pj_cis_buf_t cis_buf;\n    struct parse_state st;\n    pj_json_elem *root;\n    PJ_USE_EXCEPTION;\n\n    PJ_ASSERT_RETURN(pool && buffer && size, NULL);\n\n    if (!*size)\n\treturn NULL;\n\n    pj_bzero(&st, sizeof(st));\n    st.pool = pool;\n    st.err_info = err_info;\n    pj_scan_init(&st.scanner, buffer, *size,\n                 PJ_SCAN_AUTOSKIP_WS | PJ_SCAN_AUTOSKIP_NEWLINE,\n                 &on_syntax_error);\n    pj_cis_buf_init(&cis_buf);\n    pj_cis_init(&cis_buf, &st.float_spec);\n    pj_cis_add_str(&st.float_spec, \".0123456789\");\n\n    PJ_TRY {\n\troot = parse_elem_throw(&st, NULL);\n    }\n    PJ_CATCH_ANY {\n\troot = NULL;\n    }\n    PJ_END\n\n    if (!root && err_info) {\n\terr_info->line = st.scanner.line;\n\terr_info->col = pj_scan_get_col(&st.scanner) + 1;\n\terr_info->err_char = *st.scanner.curptr;\n    }\n\n    *size = (unsigned)((buffer + *size) - st.scanner.curptr);\n\n    pj_scan_fini(&st.scanner);\n\n    return root;\n}\n\nstruct buf_writer_data\n{\n    char\t*pos;\n    unsigned\t size;\n};\n\nstatic pj_status_t buf_writer(const char *s,\n\t\t\t      unsigned size,\n\t\t\t      void *user_data)\n{\n    struct buf_writer_data *buf_data = (struct buf_writer_data*)user_data;\n    if (size+1 >= buf_data->size)\n\treturn PJ_ETOOBIG;\n\n    pj_memcpy(buf_data->pos, s, size);\n    buf_data->pos += size;\n    buf_data->size -= size;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_json_write(const pj_json_elem *elem,\n                                  char *buffer, unsigned *size)\n{\n    struct buf_writer_data buf_data;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(elem && buffer && size, PJ_EINVAL);\n\n    buf_data.pos = buffer;\n    buf_data.size = *size;\n\n    status = pj_json_writef(elem, &buf_writer, &buf_data);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    *buf_data.pos = '\\0';\n    *size = (unsigned)(buf_data.pos - buffer);\n    return PJ_SUCCESS;\n}\n\n#define MAX_INDENT \t\t100\n#ifndef PJ_JSON_NAME_MIN_LEN\n#  define PJ_JSON_NAME_MIN_LEN\t20\n#endif\n#define ESC_BUF_LEN\t\t64\n#ifndef PJ_JSON_INDENT_SIZE\n#  define PJ_JSON_INDENT_SIZE\t3\n#endif\n\nstruct write_state\n{\n    pj_json_writer\t writer;\n    void \t\t*user_data;\n    char\t\t indent_buf[MAX_INDENT];\n    int\t\t\t indent;\n    char\t\t space[PJ_JSON_NAME_MIN_LEN];\n};\n\n#define CHECK(expr) do { \\\n\t\t\tstatus=expr; if (status!=PJ_SUCCESS) return status; } \\\n\t\t    while (0)\n\nstatic pj_status_t write_string_escaped(const pj_str_t *value,\n                                        struct write_state *st)\n{\n    const char *ip = value->ptr;\n    const char *iend = value->ptr + value->slen;\n    char buf[ESC_BUF_LEN];\n    char *op = buf;\n    char *oend = buf + ESC_BUF_LEN;\n    pj_status_t status;\n\n    while (ip != iend) {\n\t/* Write to buffer to speedup writing instead of calling\n\t * the callback one by one for each character.\n\t */\n\twhile (ip != iend && op != oend) {\n\t    if (oend - op < 2)\n\t\tbreak;\n\n\t    if (*ip == '\"') {\n\t\t*op++ = '\\\\';\n\t\t*op++ = '\"';\n\t\tip++;\n\t    } else if (*ip == '\\\\') {\n\t\t*op++ = '\\\\';\n\t\t*op++ = '\\\\';\n\t\tip++;\n\t    } else if (*ip == '/') {\n\t\t*op++ = '\\\\';\n\t\t*op++ = '/';\n\t\tip++;\n\t    } else if (*ip == '\\b') {\n\t\t*op++ = '\\\\';\n\t\t*op++ = 'b';\n\t\tip++;\n\t    } else if (*ip == '\\f') {\n\t\t*op++ = '\\\\';\n\t\t*op++ = 'f';\n\t\tip++;\n\t    } else if (*ip == '\\n') {\n\t\t*op++ = '\\\\';\n\t\t*op++ = 'n';\n\t\tip++;\n\t    } else if (*ip == '\\r') {\n\t\t*op++ = '\\\\';\n\t\t*op++ = 'r';\n\t\tip++;\n\t    } else if (*ip == '\\t') {\n\t\t*op++ = '\\\\';\n\t\t*op++ = 't';\n\t\tip++;\n\t    } else if ((*ip >= 32 && *ip < 127)) {\n\t\t/* unescaped */\n\t\t*op++ = *ip++;\n\t    } else {\n\t\t/* escaped */\n\t\tif (oend - op < 6)\n\t\t    break;\n\t\t*op++ = '\\\\';\n\t\t*op++ = 'u';\n\t\t*op++ = '0';\n\t\t*op++ = '0';\n\t\tpj_val_to_hex_digit(*ip, op);\n\t\top+=2;\n\t\tip++;\n\t    }\n\t}\n\n\tCHECK( st->writer( buf, (unsigned)(op-buf), st->user_data) );\n\top = buf;\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t write_children(const pj_json_list *list,\n                                  const char quotes[2],\n                                  struct write_state *st)\n{\n    unsigned flags = (quotes[0]=='[') ? NO_NAME : 0;\n    pj_status_t status;\n\n    //CHECK( st->writer( st->indent_buf, st->indent, st->user_data) );\n    CHECK( st->writer( &quotes[0], 1, st->user_data) );\n    CHECK( st->writer( \" \", 1, st->user_data) );\n\n    if (!pj_list_empty(list)) {\n\tpj_bool_t indent_added = PJ_FALSE;\n\tpj_json_elem *child = list->next;\n\n\tif (child->name.slen == 0) {\n\t    /* Simple list */\n\t    while (child != (pj_json_elem*)list) {\n\t\tstatus = elem_write(child, st, flags);\n\t\tif (status != PJ_SUCCESS)\n\t\t    return status;\n\n\t\tif (child->next != (pj_json_elem*)list)\n\t\t    CHECK( st->writer( \", \", 2, st->user_data) );\n\t\tchild = child->next;\n\t    }\n\t} else {\n\t    if (st->indent < sizeof(st->indent_buf)) {\n\t\tst->indent += PJ_JSON_INDENT_SIZE;\n\t\tindent_added = PJ_TRUE;\n\t    }\n\t    CHECK( st->writer( \"\\n\", 1, st->user_data) );\n\t    while (child != (pj_json_elem*)list) {\n\t\tstatus = elem_write(child, st, flags);\n\t\tif (status != PJ_SUCCESS)\n\t\t    return status;\n\n\t\tif (child->next != (pj_json_elem*)list)\n\t\t    CHECK( st->writer( \",\\n\", 2, st->user_data) );\n\t\telse\n\t\t    CHECK( st->writer( \"\\n\", 1, st->user_data) );\n\t\tchild = child->next;\n\t    }\n\t    if (indent_added) {\n\t\tst->indent -= PJ_JSON_INDENT_SIZE;\n\t    }\n\t    CHECK( st->writer( st->indent_buf, st->indent, st->user_data) );\n\t}\n    }\n    CHECK( st->writer( &quotes[1], 1, st->user_data) );\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t elem_write(const pj_json_elem *elem,\n                              struct write_state *st,\n                              unsigned flags)\n{\n    pj_status_t status;\n\n    if (elem->name.slen) {\n\tCHECK( st->writer( st->indent_buf, st->indent, st->user_data) );\n\tif ((flags & NO_NAME)==0) {\n\t    CHECK( st->writer( \"\\\"\", 1, st->user_data) );\n\t    CHECK( write_string_escaped(&elem->name, st) );\n\t    CHECK( st->writer( \"\\\": \", 3, st->user_data) );\n\t    if (elem->name.slen < PJ_JSON_NAME_MIN_LEN /*&&\n\t\telem->type != PJ_JSON_VAL_OBJ &&\n\t\telem->type != PJ_JSON_VAL_ARRAY*/)\n\t    {\n\t\tCHECK( st->writer( st->space,\n\t\t                   (unsigned)(PJ_JSON_NAME_MIN_LEN -\n\t\t\t\t\t      elem->name.slen),\n\t\t\t\t   st->user_data) );\n\t    }\n\t}\n    }\n\n    switch (elem->type) {\n    case PJ_JSON_VAL_NULL:\n\tCHECK( st->writer( \"null\", 4, st->user_data) );\n\tbreak;\n    case PJ_JSON_VAL_BOOL:\n\tif (elem->value.is_true)\n\t    CHECK( st->writer( \"true\", 4, st->user_data) );\n\telse\n\t    CHECK( st->writer( \"false\", 5, st->user_data) );\n\tbreak;\n    case PJ_JSON_VAL_NUMBER:\n\t{\n\t    char num_buf[65];\n\t    int len;\n\n\t    if (elem->value.num == (int)elem->value.num)\n\t\tlen = pj_ansi_snprintf(num_buf, sizeof(num_buf), \"%d\",\n\t\t                       (int)elem->value.num);\n\t    else\n\t\tlen = pj_ansi_snprintf(num_buf, sizeof(num_buf), \"%f\",\n\t\t                       elem->value.num);\n\n\t    if (len < 0 || len >= sizeof(num_buf))\n\t\treturn PJ_ETOOBIG;\n\t    CHECK( st->writer( num_buf, len, st->user_data) );\n\t}\n\tbreak;\n    case PJ_JSON_VAL_STRING:\n\tCHECK( st->writer( \"\\\"\", 1, st->user_data) );\n\tCHECK( write_string_escaped( &elem->value.str, st) );\n\tCHECK( st->writer( \"\\\"\", 1, st->user_data) );\n\tbreak;\n    case PJ_JSON_VAL_ARRAY:\n\tCHECK( write_children(&elem->value.children, \"[]\", st) );\n\tbreak;\n    case PJ_JSON_VAL_OBJ:\n\tCHECK( write_children(&elem->value.children, \"{}\", st) );\n\tbreak;\n    default:\n\tpj_assert(!\"Unhandled value type\");\n    }\n\n    return PJ_SUCCESS;\n}\n\n#undef CHECK\n\nPJ_DEF(pj_status_t) pj_json_writef( const pj_json_elem *elem,\n                                    pj_json_writer writer,\n                                    void *user_data)\n{\n    struct write_state st;\n\n    PJ_ASSERT_RETURN(elem && writer, PJ_EINVAL);\n\n    st.writer \t\t= writer;\n    st.user_data\t= user_data,\n    st.indent \t\t= 0;\n    pj_memset(st.indent_buf, ' ', MAX_INDENT);\n    pj_memset(st.space, ' ', PJ_JSON_NAME_MIN_LEN);\n\n    return elem_write(elem, &st, 0);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/md5.c",
    "content": "/* $Id: md5.c 1001 2007-02-25 15:38:32Z bennylp $ */\n/* \n * This is the implementation of MD5 algorithm, based on the code\n * written by Colin Plumb. This file is put in public domain.\n */\n#include <pjlib-util/md5.h>\n#include <pj/string.h>\t\t/* pj_memcpy */\n/*\n * This code implements the MD5 message-digest algorithm.\n * The algorithm is due to Ron Rivest.  This code was\n * written by Colin Plumb in 1993, no copyright is claimed.\n * This code is in the public domain; do with it what you wish.\n *\n * Equivalent code is available from RSA Data Security, Inc.\n * This code has been tested against that, and is equivalent,\n * except that you don't need to include two pages of legalese\n * with every copy.\n *\n * To compute the message digest of a chunk of bytes, declare an\n * MD5Context structure, pass it to MD5Init, call MD5Update as\n * needed on buffers full of bytes, and then call MD5Final, which\n * will fill a supplied 16-byte array with the digest.\n */\n\n#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN != 0\n#define HIGHFIRST 1\n#endif\n\n#ifndef HIGHFIRST\n#define byteReverse(buf, len)\t/* Nothing */\n#else\nvoid byteReverse(unsigned char *buf, unsigned longs);\n\n#ifndef ASM_MD5\n/*\n * Note: this code is harmless on little-endian machines.\n */\nvoid byteReverse(unsigned char *buf, unsigned longs)\n{\n    pj_uint32_t t;\n    do {\n\tt = (pj_uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |\n\t    ((unsigned) buf[1] << 8 | buf[0]);\n\t*(pj_uint32_t *) buf = t;\n\tbuf += 4;\n    } while (--longs);\n}\n#endif\n#endif\n\nstatic void MD5Transform(pj_uint32_t buf[4], pj_uint32_t const in[16]);\n\n\n/*\n * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious\n * initialization constants.\n */\nPJ_DEF(void) pj_md5_init(pj_md5_context *ctx)\n{\n    ctx->buf[0] = 0x67452301;\n    ctx->buf[1] = 0xefcdab89;\n    ctx->buf[2] = 0x98badcfe;\n    ctx->buf[3] = 0x10325476;\n\n    ctx->bits[0] = 0;\n    ctx->bits[1] = 0;\n}\n\n/*\n * Update context to reflect the concatenation of another buffer full\n * of bytes.\n */\nPJ_DEF(void) pj_md5_update( pj_md5_context *ctx, \n\t\t\t    unsigned char const *buf, unsigned len)\n{\n    pj_uint32_t t;\n\n    /* Update bitcount */\n\n    t = ctx->bits[0];\n    if ((ctx->bits[0] = t + ((pj_uint32_t) len << 3)) < t)\n\tctx->bits[1]++;\t\t/* Carry from low to high */\n    ctx->bits[1] += len >> 29;\n\n    t = (t >> 3) & 0x3f;\t/* Bytes already in shsInfo->data */\n\n    /* Handle any leading odd-sized chunks */\n\n    if (t) {\n\tunsigned char *p = (unsigned char *) ctx->in + t;\n\n\tt = 64 - t;\n\tif (len < t) {\n\t    pj_memcpy(p, buf, len);\n\t    return;\n\t}\n\tpj_memcpy(p, buf, t);\n\tbyteReverse(ctx->in, 16);\n\tMD5Transform(ctx->buf, (pj_uint32_t *) ctx->in);\n\tbuf += t;\n\tlen -= t;\n    }\n    /* Process data in 64-byte chunks */\n\n    while (len >= 64) {\n\tpj_memcpy(ctx->in, buf, 64);\n\tbyteReverse(ctx->in, 16);\n\tMD5Transform(ctx->buf, (pj_uint32_t *) ctx->in);\n\tbuf += 64;\n\tlen -= 64;\n    }\n\n    /* Handle any remaining bytes of data. */\n\n    pj_memcpy(ctx->in, buf, len);\n}\n\n/*\n * Final wrapup - pad to 64-byte boundary with the bit pattern \n * 1 0* (64-bit count of bits processed, MSB-first)\n */\nPJ_DEF(void) pj_md5_final(pj_md5_context *ctx, unsigned char digest[16])\n{\n    unsigned count;\n    unsigned char *p;\n\n    /* Compute number of bytes mod 64 */\n    count = (ctx->bits[0] >> 3) & 0x3F;\n\n    /* Set the first char of padding to 0x80.  This is safe since there is\n       always at least one byte free */\n    p = ctx->in + count;\n    *p++ = 0x80;\n\n    /* Bytes of padding needed to make 64 bytes */\n    count = 64 - 1 - count;\n\n    /* Pad out to 56 mod 64 */\n    if (count < 8) {\n\t/* Two lots of padding:  Pad the first block to 64 bytes */\n\tpj_bzero(p, count);\n\tbyteReverse(ctx->in, 16);\n\tMD5Transform(ctx->buf, (pj_uint32_t *) ctx->in);\n\n\t/* Now fill the next block with 56 bytes */\n\tpj_bzero(ctx->in, 56);\n    } else {\n\t/* Pad block to 56 bytes */\n\tpj_bzero(p, count - 8);\n    }\n    byteReverse(ctx->in, 14);\n\n    /* Append length in bits and transform */\n    ((pj_uint32_t *) ctx->in)[14] = ctx->bits[0];\n    ((pj_uint32_t *) ctx->in)[15] = ctx->bits[1];\n\n    MD5Transform(ctx->buf, (pj_uint32_t *) ctx->in);\n    byteReverse((unsigned char *) ctx->buf, 4);\n    pj_memcpy(digest, ctx->buf, 16);\n    pj_bzero(ctx, sizeof(*ctx));\t/* In case it's sensitive */\n}\n\n#ifndef ASM_MD5\n\n/* The four core functions - F1 is optimized somewhat */\n\n/* #define F1(x, y, z) (x & y | ~x & z) */\n#define F1(x, y, z) (z ^ (x & (y ^ z)))\n#define F2(x, y, z) F1(z, x, y)\n#define F3(x, y, z) (x ^ y ^ z)\n#define F4(x, y, z) (y ^ (x | ~z))\n\n/* This is the central step in the MD5 algorithm. */\n#define MD5STEP(f, w, x, y, z, data, s) \\\n\t( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )\n\n/*\n * The core of the MD5 algorithm, this alters an existing MD5 hash to\n * reflect the addition of 16 longwords of new data.  MD5Update blocks\n * the data and converts bytes into longwords for this routine.\n */\nstatic void MD5Transform(pj_uint32_t buf[4], pj_uint32_t const in[16])\n{\n    register pj_uint32_t a, b, c, d;\n\n    a = buf[0];\n    b = buf[1];\n    c = buf[2];\n    d = buf[3];\n\n    MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);\n    MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);\n    MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);\n    MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);\n    MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);\n    MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);\n    MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);\n    MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);\n    MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);\n    MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);\n    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);\n    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);\n    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);\n    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);\n    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);\n    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);\n\n    MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);\n    MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);\n    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);\n    MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);\n    MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);\n    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);\n    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);\n    MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);\n    MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);\n    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);\n    MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);\n    MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);\n    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);\n    MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);\n    MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);\n    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);\n\n    MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);\n    MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);\n    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);\n    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);\n    MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);\n    MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);\n    MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);\n    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);\n    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);\n    MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);\n    MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);\n    MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);\n    MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);\n    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);\n    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);\n    MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);\n\n    MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);\n    MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);\n    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);\n    MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);\n    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);\n    MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);\n    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);\n    MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);\n    MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);\n    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);\n    MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);\n    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);\n    MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);\n    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);\n    MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);\n    MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);\n\n    buf[0] += a;\n    buf[1] += b;\n    buf[2] += c;\n    buf[3] += d;\n}\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/pcap.c",
    "content": "/* $Id: pcap.c 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/pcap.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/file_io.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/sock.h>\n#include <pj/string.h>\n\n#if 0\n#   define TRACE_(x)\tPJ_LOG(5,x)\n#else\n#   define TRACE_(x)\n#endif\n\n\n#pragma pack(1)\n\ntypedef struct pj_pcap_hdr \n{\n    pj_uint32_t magic_number;   /* magic number */\n    pj_uint16_t version_major;  /* major version number */\n    pj_uint16_t version_minor;  /* minor version number */\n    pj_int32_t  thiszone;       /* GMT to local correction */\n    pj_uint32_t sigfigs;        /* accuracy of timestamps */\n    pj_uint32_t snaplen;        /* max length of captured packets, in octets */\n    pj_uint32_t network;        /* data link type */\n} pj_pcap_hdr;\n\ntypedef struct pj_pcap_rec_hdr \n{\n    pj_uint32_t ts_sec;         /* timestamp seconds */\n    pj_uint32_t ts_usec;        /* timestamp microseconds */\n    pj_uint32_t incl_len;       /* number of octets of packet saved in file */\n    pj_uint32_t orig_len;       /* actual length of packet */\n} pj_pcap_rec_hdr;\n\n#if 0\n/* gcc insisted on aligning this struct to 32bit on ARM */\ntypedef struct pj_pcap_eth_hdr \n{\n    pj_uint8_t  dest[6];\n    pj_uint8_t  src[6];\n    pj_uint8_t  len[2];\n} pj_pcap_eth_hdr;\n#else\ntypedef pj_uint8_t pj_pcap_eth_hdr[14];\n#endif\n\ntypedef struct pj_pcap_ip_hdr \n{\n    pj_uint8_t\tv_ihl;\n    pj_uint8_t\ttos;\n    pj_uint16_t\tlen;\n    pj_uint16_t\tid;\n    pj_uint16_t\tflags_fragment;\n    pj_uint8_t\tttl;\n    pj_uint8_t\tproto;\n    pj_uint16_t\tcsum;\n    pj_uint32_t\tip_src;\n    pj_uint32_t\tip_dst;\n} pj_pcap_ip_hdr;\n\n/* Implementation of pcap file */\nstruct pj_pcap_file\n{\n    char\t    obj_name[PJ_MAX_OBJ_NAME];\n    pj_oshandle_t   fd;\n    pj_bool_t\t    swap;\n    pj_pcap_hdr\t    hdr;\n    pj_pcap_filter  filter;\n};\n\n/* Init default filter */\nPJ_DEF(void) pj_pcap_filter_default(pj_pcap_filter *filter)\n{\n    pj_bzero(filter, sizeof(*filter));\n}\n\n/* Open pcap file */\nPJ_DEF(pj_status_t) pj_pcap_open(pj_pool_t *pool,\n\t\t\t\t const char *path,\n\t\t\t\t pj_pcap_file **p_file)\n{\n    pj_pcap_file *file;\n    pj_ssize_t sz;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && path && p_file, PJ_EINVAL);\n\n    /* More sanity checks */\n    TRACE_((\"pcap\", \"sizeof(pj_pcap_eth_hdr)=%d\",\n\t    sizeof(pj_pcap_eth_hdr)));\n    PJ_ASSERT_RETURN(sizeof(pj_pcap_eth_hdr)==14, PJ_EBUG);\n    TRACE_((\"pcap\", \"sizeof(pj_pcap_ip_hdr)=%d\",\n\t    sizeof(pj_pcap_ip_hdr)));\n    PJ_ASSERT_RETURN(sizeof(pj_pcap_ip_hdr)==20, PJ_EBUG);\n    TRACE_((\"pcap\", \"sizeof(pj_pcap_udp_hdr)=%d\",\n\t    sizeof(pj_pcap_udp_hdr)));\n    PJ_ASSERT_RETURN(sizeof(pj_pcap_udp_hdr)==8, PJ_EBUG);\n    \n    file = PJ_POOL_ZALLOC_T(pool, pj_pcap_file);\n\n    pj_ansi_strcpy(file->obj_name, \"pcap\");\n\n    status = pj_file_open(pool, path, PJ_O_RDONLY, &file->fd);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Read file pcap header */\n    sz = sizeof(file->hdr);\n    status = pj_file_read(file->fd, &file->hdr, &sz);\n    if (status != PJ_SUCCESS) {\n\tpj_file_close(file->fd);\n\treturn status;\n    }\n\n    /* Check magic number */\n    if (file->hdr.magic_number == 0xa1b2c3d4) {\n\tfile->swap = PJ_FALSE;\n    } else if (file->hdr.magic_number == 0xd4c3b2a1) {\n\tfile->swap = PJ_TRUE;\n\tfile->hdr.network = pj_ntohl(file->hdr.network);\n    } else {\n\t/* Not PCAP file */\n\tpj_file_close(file->fd);\n\treturn PJ_EINVALIDOP;\n    }\n\n    TRACE_((file->obj_name, \"PCAP file %s opened\", path));\n    \n    *p_file = file;\n    return PJ_SUCCESS;\n}\n\n/* Close pcap file */\nPJ_DEF(pj_status_t) pj_pcap_close(pj_pcap_file *file)\n{\n    PJ_ASSERT_RETURN(file, PJ_EINVAL);\n    TRACE_((file->obj_name, \"PCAP file closed\"));\n    return pj_file_close(file->fd);\n}\n\n/* Setup filter */\nPJ_DEF(pj_status_t) pj_pcap_set_filter(pj_pcap_file *file,\n\t\t\t\t       const pj_pcap_filter *fil)\n{\n    PJ_ASSERT_RETURN(file && fil, PJ_EINVAL);\n    pj_memcpy(&file->filter, fil, sizeof(pj_pcap_filter));\n    return PJ_SUCCESS;\n}\n\n/* Read file */\nstatic pj_status_t read_file(pj_pcap_file *file,\n\t\t\t     void *buf,\n\t\t\t     pj_ssize_t *sz)\n{\n    pj_status_t status;\n    status = pj_file_read(file->fd, buf, sz);\n    if (status != PJ_SUCCESS)\n\treturn status;\n    if (*sz == 0)\n\treturn PJ_EEOF;\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t skip(pj_oshandle_t fd, pj_off_t bytes)\n{\n    pj_status_t status;\n    status = pj_file_setpos(fd, bytes, PJ_SEEK_CUR);\n    if (status != PJ_SUCCESS)\n\treturn status; \n    return PJ_SUCCESS;\n}\n\n\n#define SKIP_PKT()  \\\n\tif (rec_incl > sz_read) { \\\n\t    status = skip(file->fd, rec_incl-sz_read);\\\n\t    if (status != PJ_SUCCESS) \\\n\t\treturn status; \\\n\t}\n\n/* Read UDP packet */\nPJ_DEF(pj_status_t) pj_pcap_read_udp(pj_pcap_file *file,\n\t\t\t\t     pj_pcap_udp_hdr *udp_hdr,\n\t\t\t\t     pj_uint8_t *udp_payload,\n\t\t\t\t     pj_size_t *udp_payload_size)\n{\n    PJ_ASSERT_RETURN(file && udp_payload && udp_payload_size, PJ_EINVAL);\n    PJ_ASSERT_RETURN(*udp_payload_size, PJ_EINVAL);\n\n    /* Check data link type in PCAP file header */\n    if ((file->filter.link && \n\t    file->hdr.network != (pj_uint32_t)file->filter.link) ||\n\tfile->hdr.network != PJ_PCAP_LINK_TYPE_ETH)\n    {\n\t/* Link header other than Ethernet is not supported for now */\n\treturn PJ_ENOTSUP;\n    }\n\n    /* Loop until we have the packet */\n    for (;;) {\n\tunion {\n\t    pj_pcap_rec_hdr rec;\n\t    pj_pcap_eth_hdr eth;\n\t    pj_pcap_ip_hdr ip;\n\t    pj_pcap_udp_hdr udp;\n\t} tmp;\n\tunsigned rec_incl;\n\tpj_ssize_t sz;\n\tpj_size_t sz_read = 0;\n\tpj_status_t status;\n\n\tTRACE_((file->obj_name, \"Reading packet..\"));\n\n\t/* Read PCAP packet header */\n\tsz = sizeof(tmp.rec);\n\tstatus = read_file(file, &tmp.rec, &sz); \n\tif (status != PJ_SUCCESS) {\n\t    TRACE_((file->obj_name, \"read_file() error: %d\", status));\n\t    return status;\n\t}\n\n\trec_incl = tmp.rec.incl_len;\n\n\t/* Swap byte ordering */\n\tif (file->swap) {\n\t    tmp.rec.incl_len = pj_ntohl(tmp.rec.incl_len);\n\t    tmp.rec.orig_len = pj_ntohl(tmp.rec.orig_len);\n\t    tmp.rec.ts_sec = pj_ntohl(tmp.rec.ts_sec);\n\t    tmp.rec.ts_usec = pj_ntohl(tmp.rec.ts_usec);\n\t}\n\n\t/* Read link layer header */\n\tswitch (file->hdr.network) {\n\tcase PJ_PCAP_LINK_TYPE_ETH:\n\t    sz = sizeof(tmp.eth);\n\t    status = read_file(file, &tmp.eth, &sz);\n\t    break;\n\tdefault:\n\t    TRACE_((file->obj_name, \"Error: link layer not Ethernet\"));\n\t    return PJ_ENOTSUP;\n\t}\n\n\tif (status != PJ_SUCCESS) {\n\t    TRACE_((file->obj_name, \"Error reading Eth header: %d\", status));\n\t    return status;\n\t}\n\n\tsz_read += sz;\n\t    \n\t/* Read IP header */\n\tsz = sizeof(tmp.ip);\n\tstatus = read_file(file, &tmp.ip, &sz);\n\tif (status != PJ_SUCCESS) {\n\t    TRACE_((file->obj_name, \"Error reading IP header: %d\", status));\n\t    return status;\n\t}\n\n\tsz_read += sz;\n\n\t/* Skip if IP source mismatch */\n\tif (file->filter.ip_src && tmp.ip.ip_src != file->filter.ip_src) {\n\t    TRACE_((file->obj_name, \"IP source %s mismatch, skipping\", \n\t\t    pj_inet_ntoa(*(pj_in_addr*)&tmp.ip.ip_src)));\n\t    SKIP_PKT();\n\t    continue;\n\t}\n\n\t/* Skip if IP destination mismatch */\n\tif (file->filter.ip_dst && tmp.ip.ip_dst != file->filter.ip_dst) {\n\t    TRACE_((file->obj_name, \"IP detination %s mismatch, skipping\", \n\t\t    pj_inet_ntoa(*(pj_in_addr*)&tmp.ip.ip_dst)));\n\t    SKIP_PKT();\n\t    continue;\n\t}\n\n\t/* Skip if proto mismatch */\n\tif (file->filter.proto && tmp.ip.proto != file->filter.proto) {\n\t    TRACE_((file->obj_name, \"IP proto %d mismatch, skipping\", \n\t\t    tmp.ip.proto));\n\t    SKIP_PKT();\n\t    continue;\n\t}\n\n\t/* Read transport layer header */\n\tswitch (tmp.ip.proto) {\n\tcase PJ_PCAP_PROTO_TYPE_UDP:\n\t    sz = sizeof(tmp.udp);\n\t    status = read_file(file, &tmp.udp, &sz);\n\t    if (status != PJ_SUCCESS) {\n\t\tTRACE_((file->obj_name, \"Error reading UDP header: %d\",status));\n\t\treturn status;\n\t    }\n\n\t    sz_read += sz;\n\n\t    /* Skip if source port mismatch */\n\t    if (file->filter.src_port && \n\t        tmp.udp.src_port != file->filter.src_port) \n\t    {\n\t\tTRACE_((file->obj_name, \"UDP src port %d mismatch, skipping\", \n\t\t\tpj_ntohs(tmp.udp.src_port)));\n\t\tSKIP_PKT();\n\t\tcontinue;\n\t    }\n\n\t    /* Skip if destination port mismatch */\n\t    if (file->filter.dst_port && \n\t\ttmp.udp.dst_port != file->filter.dst_port) \n\t    {\n\t\tTRACE_((file->obj_name, \"UDP dst port %d mismatch, skipping\", \n\t\t\tpj_ntohs(tmp.udp.dst_port)));\n\t\tSKIP_PKT();\n\t\tcontinue;\n\t    }\n\n\t    /* Copy UDP header if caller wants it */\n\t    if (udp_hdr) {\n\t\tpj_memcpy(udp_hdr, &tmp.udp, sizeof(*udp_hdr));\n\t    }\n\n\t    /* Calculate payload size */\n\t    sz = pj_ntohs(tmp.udp.len) - sizeof(tmp.udp);\n\t    break;\n\tdefault:\n\t    TRACE_((file->obj_name, \"Not UDP, skipping\"));\n\t    SKIP_PKT();\n\t    continue;\n\t}\n\n\t/* Check if payload fits the buffer */\n\tif (sz > (pj_ssize_t)*udp_payload_size) {\n\t    TRACE_((file->obj_name, \n\t\t    \"Error: packet too large (%d bytes required)\", sz));\n\t    SKIP_PKT();\n\t    return PJ_ETOOSMALL;\n\t}\n\n\t/* Read the payload */\n\tstatus = read_file(file, udp_payload, &sz);\n\tif (status != PJ_SUCCESS) {\n\t    TRACE_((file->obj_name, \"Error reading payload: %d\", status));\n\t    return status;\n\t}\n\n\tsz_read += sz;\n\n\t*udp_payload_size = sz;\n\n\t// Some layers may have trailer, e.g: link eth2.\n\t/* Check that we've read all the packets */\n\t//PJ_ASSERT_RETURN(sz_read == rec_incl, PJ_EBUG);\n\n\t/* Skip trailer */\n\twhile (sz_read < rec_incl) {\n\t    sz = rec_incl - sz_read;\n\t    status = read_file(file, &tmp.eth, &sz);\n\t    if (status != PJ_SUCCESS) {\n\t\tTRACE_((file->obj_name, \"Error reading trailer: %d\", status));\n\t\treturn status;\n\t    }\n\t    sz_read += sz;\n\t}\n\n\treturn PJ_SUCCESS;\n    }\n\n    /* Does not reach here */\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/resolver.c",
    "content": "/* $Id: resolver.c 4333 2013-01-23 09:53:39Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/resolver.h>\n#include <pjlib-util/errno.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n#include <pj/except.h>\n#include <pj/hash.h>\n#include <pj/ioqueue.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/pool_buf.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n#include <pj/sock.h>\n#include <pj/timer.h>\n\n\n#define THIS_FILE\t    \"resolver.c\"\n\n\n/* Check that maximum DNS nameservers is not too large. \n * This has got todo with the datatype to index the nameserver in the query.\n */\n#if PJ_DNS_RESOLVER_MAX_NS > 256\n#   error \"PJ_DNS_RESOLVER_MAX_NS is too large (max=256)\"\n#endif\n\n\n#define RES_HASH_TABLE_SIZE 127\t\t/**< Hash table size (must be 2^n-1 */\n#define PORT\t\t    53\t\t/**< Default NS port.\t\t    */\n#define Q_HASH_TABLE_SIZE   127\t\t/**< Query hash table size\t    */\n#define TIMER_SIZE\t    127\t\t/**< Initial number of timers.\t    */\n#define MAX_FD\t\t    3\t\t/**< Maximum internal sockets.\t    */\n\n#define RES_BUF_SZ\t    PJ_DNS_RESOLVER_RES_BUF_SIZE\n#define UDPSZ\t\t    PJ_DNS_RESOLVER_MAX_UDP_SIZE\n#define TMP_SZ\t\t    PJ_DNS_RESOLVER_TMP_BUF_SIZE\n\n\n/* Nameserver state */\nenum ns_state\n{\n    STATE_PROBING,\n    STATE_ACTIVE,\n    STATE_BAD,\n};\n\nstatic const char *state_names[3] =\n{\n    \"Probing\",\n    \"Active\",\n    \"Bad\"\n};\n\n\n/* \n * Each nameserver entry.\n * A name server is identified by its socket address (IP and port).\n * Each NS will have a flag to indicate whether it's properly functioning.\n */\nstruct nameserver\n{\n    pj_sockaddr_in  addr;\t\t/**< Server address.\t\t    */\n\n    enum ns_state   state;\t\t/**< Nameserver state.\t\t    */\n    pj_time_val\t    state_expiry;\t/**< Time set next state.\t    */\n    pj_time_val\t    rt_delay;\t\t/**< Response time.\t\t    */\n    \n\n    /* For calculating rt_delay: */\n    pj_uint16_t\t    q_id;\t\t/**< Query ID.\t\t\t    */\n    pj_time_val\t    sent_time;\t\t/**< Time this query is sent.\t    */\n};\n\n\n/* Child query list head \n * See comments on pj_dns_async_query below.\n */\nstruct query_head\n{\n    PJ_DECL_LIST_MEMBER(pj_dns_async_query);\n};\n\n\n/* Key to look for outstanding query and/or cached response */\nstruct res_key\n{\n    pj_uint16_t\t\t     qtype;\t\t    /**< Query type.\t    */\n    char\t\t     name[PJ_MAX_HOSTNAME]; /**< Name being queried */\n};\n\n\n/* \n * This represents each asynchronous query entry.\n * This entry will be put in two hash tables, the first one keyed on the DNS \n * transaction ID to match response with the query, and the second one keyed\n * on \"res_key\" structure above to match a new request against outstanding \n * requests.\n *\n * An asynchronous entry may have child entries; child entries are subsequent\n * queries to the same resource while there is pending query on the same\n * DNS resource name and type. When a query has child entries, once the\n * response is received (or error occurs), the response will trigger callback\n * invocations for all childs entries.\n *\n * Note: when application cancels the query, the callback member will be\n *       set to NULL, but for simplicity, the query will be let running.\n */\nstruct pj_dns_async_query\n{\n    PJ_DECL_LIST_MEMBER(pj_dns_async_query);\t/**< List member.\t    */\n\n    pj_dns_resolver\t*resolver;\t/**< The resolver instance.\t    */\n    pj_uint16_t\t\t id;\t\t/**< Transaction ID.\t\t    */\n\n    unsigned\t\t transmit_cnt;\t/**< Number of transmissions.\t    */\n\n    struct res_key\t key;\t\t/**< Key to index this query.\t    */\n    pj_hash_entry_buf\t hbufid;\t/**< Hash buffer 1\t\t    */\n    pj_hash_entry_buf\t hbufkey;\t/**< Hash buffer 2\t\t    */\n    pj_timer_entry\t timer_entry;\t/**< Timer to manage timeouts\t    */\n    unsigned\t\t options;\t/**< Query options.\t\t    */\n    void\t\t*user_data;\t/**< Application data.\t\t    */\n    pj_dns_callback\t*cb;\t\t/**< Callback to be called.\t    */\n    struct query_head\t child_head;\t/**< Child queries list head.\t    */\n};\n\n\n/* This structure is used to keep cached response entry.\n * The cache is a hash table keyed on \"res_key\" structure above.\n */\nstruct cached_res\n{\n    PJ_DECL_LIST_MEMBER(struct cached_res);\n\n    pj_pool_t\t\t    *pool;\t    /**< Cache's pool.\t\t    */\n    struct res_key\t     key;\t    /**< Resource key.\t\t    */\n    pj_hash_entry_buf\t     hbuf;\t    /**< Hash buffer\t\t    */\n    pj_time_val\t\t     expiry_time;   /**< Expiration time.\t    */\n    pj_dns_parsed_packet    *pkt;\t    /**< The response packet.\t    */\n    unsigned\t\t     ref_cnt;\t    /**< Reference counter.\t    */\n};\n\n\n/* Resolver entry */\nstruct pj_dns_resolver\n{\n    pj_str_t\t\t name;\t\t/**< Resolver instance name for id. */\n\n    /* Internals */\n    pj_pool_t\t\t*pool;\t\t/**< Internal pool.\t\t    */\n    pj_mutex_t\t\t*mutex;\t\t/**< Mutex protection.\t\t    */\n    pj_bool_t\t\t own_timer;\t/**< Do we own timer?\t\t    */\n    pj_timer_heap_t\t*timer;\t\t/**< Timer instance.\t\t    */\n    pj_bool_t\t\t own_ioqueue;\t/**< Do we own ioqueue?\t\t    */\n    pj_ioqueue_t\t*ioqueue;\t/**< Ioqueue instance.\t\t    */\n    char\t\t tmp_pool[TMP_SZ];/**< Temporary pool buffer.\t    */\n\n    /* Socket */\n    pj_sock_t\t\t udp_sock;\t/**< UDP socket.\t\t    */\n    pj_ioqueue_key_t\t*udp_key;\t/**< UDP socket ioqueue key.\t    */\n    unsigned char\t udp_rx_pkt[UDPSZ];/**< UDP receive buffer.\t    */\n    unsigned char\t udp_tx_pkt[UDPSZ];/**< UDP receive buffer.\t    */\n    pj_ssize_t\t\t udp_len;\t/**< Length of received packet.\t    */\n    pj_ioqueue_op_key_t\t udp_op_rx_key;\t/**< UDP read operation key.\t    */\n    pj_ioqueue_op_key_t\t udp_op_tx_key;\t/**< UDP write operation key.\t    */\n    pj_sockaddr_in\t udp_src_addr;\t/**< Source address of packet\t    */\n    int\t\t\t udp_addr_len;\t/**< Source address length.\t    */\n\n    /* Settings */\n    pj_dns_settings\t settings;\t/**< Resolver settings.\t\t    */\n\n    /* Nameservers */\n    unsigned\t\t ns_count;\t/**< Number of name servers.\t    */\n    struct nameserver\t ns[PJ_DNS_RESOLVER_MAX_NS];\t/**< Array of NS.   */\n\n    /* Last DNS transaction ID used. */\n    pj_uint16_t\t\t last_id;\n\n    /* Hash table for cached response */\n    pj_hash_table_t\t*hrescache;\t/**< Cached response in hash table  */\n\n    /* Pending asynchronous query, hashed by transaction ID. */\n    pj_hash_table_t\t*hquerybyid;\n\n    /* Pending asynchronous query, hashed by \"res_key\" */\n    pj_hash_table_t\t*hquerybyres;\n\n    /* Query entries free list */\n    struct query_head\t query_free_nodes;\n};\n\n\n/* Callback from ioqueue when packet is received */\nstatic void on_read_complete(pj_ioqueue_key_t *key, \n                             pj_ioqueue_op_key_t *op_key, \n                             pj_ssize_t bytes_read);\n\n/* Callback to be called when query has timed out */\nstatic void on_timeout( pj_timer_heap_t *timer_heap,\n\t\t\tstruct pj_timer_entry *entry);\n\n/* Select which nameserver to use */\nstatic pj_status_t select_nameservers(pj_dns_resolver *resolver,\n\t\t\t\t      unsigned *count,\n\t\t\t\t      unsigned servers[]);\n\n\n/* Close UDP socket */\nstatic void close_sock(pj_dns_resolver *resv)\n{\n    /* Close existing socket */\n    if (resv->udp_key != NULL) {\n\tpj_ioqueue_unregister(resv->udp_key);\n\tresv->udp_key = NULL;\n\tresv->udp_sock = PJ_INVALID_SOCKET;\n    } else if (resv->udp_sock != PJ_INVALID_SOCKET) {\n\tpj_sock_close(resv->udp_sock);\n\tresv->udp_sock = PJ_INVALID_SOCKET;\n    }\n}\n\n\n/* Initialize UDP socket */\nstatic pj_status_t init_sock(pj_dns_resolver *resv)\n{\n    pj_ioqueue_callback socket_cb;\n    pj_status_t status;\n\n    /* Create the UDP socket */\n    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &resv->udp_sock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Bind to any address/port */\n    status = pj_sock_bind_in(resv->udp_sock, 0, 0);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Register to ioqueue */\n    pj_bzero(&socket_cb, sizeof(socket_cb));\n    socket_cb.on_read_complete = &on_read_complete;\n    status = pj_ioqueue_register_sock(resv->pool, resv->ioqueue,\n\t\t\t\t      resv->udp_sock, resv, &socket_cb,\n\t\t\t\t      &resv->udp_key);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_ioqueue_op_key_init(&resv->udp_op_rx_key, sizeof(resv->udp_op_rx_key));\n    pj_ioqueue_op_key_init(&resv->udp_op_tx_key, sizeof(resv->udp_op_tx_key));\n\n    /* Start asynchronous read to the UDP socket */\n    resv->udp_len = sizeof(resv->udp_rx_pkt);\n    resv->udp_addr_len = sizeof(resv->udp_src_addr);\n    status = pj_ioqueue_recvfrom(resv->udp_key, &resv->udp_op_rx_key,\n\t\t\t\t resv->udp_rx_pkt, &resv->udp_len,\n\t\t\t\t PJ_IOQUEUE_ALWAYS_ASYNC,\n\t\t\t\t &resv->udp_src_addr, &resv->udp_addr_len);\n    if (status != PJ_EPENDING)\n\treturn status;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Initialize DNS settings with default values */\nPJ_DEF(void) pj_dns_settings_default(pj_dns_settings *s)\n{\n    pj_bzero(s, sizeof(pj_dns_settings));\n    s->qretr_delay = PJ_DNS_RESOLVER_QUERY_RETRANSMIT_DELAY;\n    s->qretr_count = PJ_DNS_RESOLVER_QUERY_RETRANSMIT_COUNT;\n    s->cache_max_ttl = PJ_DNS_RESOLVER_MAX_TTL;\n    s->good_ns_ttl = PJ_DNS_RESOLVER_GOOD_NS_TTL;\n    s->bad_ns_ttl = PJ_DNS_RESOLVER_BAD_NS_TTL;\n}\n\n\n/*\n * Create the resolver.\n */\nPJ_DEF(pj_status_t) pj_dns_resolver_create( pj_pool_factory *pf,\n\t\t\t\t\t    const char *name,\n\t\t\t\t\t    unsigned options,\n\t\t\t\t\t    pj_timer_heap_t *timer,\n\t\t\t\t\t    pj_ioqueue_t *ioqueue,\n\t\t\t\t\t    pj_dns_resolver **p_resolver)\n{\n    pj_pool_t *pool;\n    pj_dns_resolver *resv;\n    pj_status_t status;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(pf && p_resolver, PJ_EINVAL);\n\n    if (name == NULL)\n\tname = THIS_FILE;\n\n    /* Create and initialize resolver instance */\n    pool = pj_pool_create(pf, name, 4000, 4000, NULL);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    /* Create pool and name */\n    resv = PJ_POOL_ZALLOC_T(pool, struct pj_dns_resolver);\n    resv->pool = pool;\n    resv->udp_sock = PJ_INVALID_SOCKET;\n    pj_strdup2_with_null(pool, &resv->name, name);\n    \n    /* Create the mutex */\n    status = pj_mutex_create_recursive(pool, name, &resv->mutex);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Timer, ioqueue, and settings */\n    resv->timer = timer;\n    resv->ioqueue = ioqueue;\n    resv->last_id = 1;\n\n    pj_dns_settings_default(&resv->settings);\n    resv->settings.options = options;\n\n    /* Create the timer heap if one is not specified */\n    if (resv->timer == NULL) {\n\tstatus = pj_timer_heap_create(pool, TIMER_SIZE, &resv->timer);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n    }\n\n    /* Create the ioqueue if one is not specified */\n    if (resv->ioqueue == NULL) {\n\tstatus = pj_ioqueue_create(pool, MAX_FD, &resv->ioqueue);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n    }\n\n    /* Response cache hash table */\n    resv->hrescache = pj_hash_create(pool, RES_HASH_TABLE_SIZE);\n\n    /* Query hash table and free list. */\n    resv->hquerybyid = pj_hash_create(pool, Q_HASH_TABLE_SIZE);\n    resv->hquerybyres = pj_hash_create(pool, Q_HASH_TABLE_SIZE);\n    pj_list_init(&resv->query_free_nodes);\n\n    /* Initialize the UDP socket */\n    status = init_sock(resv);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Looks like everything is okay */\n    *p_resolver = resv;\n    return PJ_SUCCESS;\n\non_error:\n    pj_dns_resolver_destroy(resv, PJ_FALSE);\n    return status;\n}\n\n\n/*\n * Destroy DNS resolver instance.\n */\nPJ_DEF(pj_status_t) pj_dns_resolver_destroy( pj_dns_resolver *resolver,\n\t\t\t\t\t     pj_bool_t notify)\n{\n    pj_hash_iterator_t it_buf, *it;\n    PJ_ASSERT_RETURN(resolver, PJ_EINVAL);\n\n    if (notify) {\n\t/*\n\t * Notify pending queries if requested.\n\t */\n\tit = pj_hash_first(resolver->hquerybyid, &it_buf);\n\twhile (it) {\n\t    pj_dns_async_query *q = (pj_dns_async_query *)\n\t    \t\t\t    pj_hash_this(resolver->hquerybyid, it);\n\t    pj_dns_async_query *cq;\n\t    if (q->cb)\n\t\t(*q->cb)(q->user_data, PJ_ECANCELLED, NULL);\n\n\t    cq = q->child_head.next;\n\t    while (cq != (pj_dns_async_query*)&q->child_head) {\n\t\tif (cq->cb)\n\t\t    (*cq->cb)(cq->user_data, PJ_ECANCELLED, NULL);\n\t\tcq = cq->next;\n\t    }\n\t    it = pj_hash_next(resolver->hquerybyid, it);\n\t}\n    }\n\n    /* Destroy cached entries */\n    it = pj_hash_first(resolver->hrescache, &it_buf);\n    while (it) {\n\tstruct cached_res *cache;\n\n\tcache = (struct cached_res*) pj_hash_this(resolver->hrescache, it);\n\tpj_hash_set(NULL, resolver->hrescache, &cache->key, \n\t\t    sizeof(cache->key), 0, NULL);\n\tpj_pool_release(cache->pool);\n\n\tit = pj_hash_first(resolver->hrescache, &it_buf);\n    }\n\n    if (resolver->own_timer && resolver->timer) {\n\tpj_timer_heap_destroy(resolver->timer);\n\tresolver->timer = NULL;\n    }\n\n    close_sock(resolver);\n\n    if (resolver->own_ioqueue && resolver->ioqueue) {\n\tpj_ioqueue_destroy(resolver->ioqueue);\n\tresolver->ioqueue = NULL;\n    }\n\n    if (resolver->mutex) {\n\tpj_mutex_destroy(resolver->mutex);\n\tresolver->mutex = NULL;\n    }\n\n    if (resolver->pool) {\n\tpj_pool_t *pool = resolver->pool;\n\tresolver->pool = NULL;\n\tpj_pool_release(pool);\n    }\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Configure name servers for the DNS resolver. \n */\nPJ_DEF(pj_status_t) pj_dns_resolver_set_ns( pj_dns_resolver *resolver,\n\t\t\t\t\t    unsigned count,\n\t\t\t\t\t    const pj_str_t servers[],\n\t\t\t\t\t    const pj_uint16_t ports[])\n{\n    unsigned i;\n    pj_time_val now;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(resolver && count && servers, PJ_EINVAL);\n    PJ_ASSERT_RETURN(count < PJ_DNS_RESOLVER_MAX_NS, PJ_EINVAL);\n\n    pj_mutex_lock(resolver->mutex);\n\n    if (count > PJ_DNS_RESOLVER_MAX_NS)\n\tcount = PJ_DNS_RESOLVER_MAX_NS;\n\n    resolver->ns_count = 0;\n    pj_bzero(resolver->ns, sizeof(resolver->ns));\n\n    pj_gettimeofday(&now);\n\n    for (i=0; i<count; ++i) {\n\tstruct nameserver *ns = &resolver->ns[i];\n\n\tstatus = pj_sockaddr_in_init(&ns->addr, &servers[i], \n\t\t\t\t     (pj_uint16_t)(ports ? ports[i] : PORT));\n\tif (status != PJ_SUCCESS) {\n\t    pj_mutex_unlock(resolver->mutex);\n\t    return PJLIB_UTIL_EDNSINNSADDR;\n\t}\n\n\tns->state = STATE_ACTIVE;\n\tns->state_expiry = now;\n\tns->rt_delay.sec = 10;\n    }\n    \n    resolver->ns_count = count;\n\n    pj_mutex_unlock(resolver->mutex);\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Modify the resolver settings.\n */\nPJ_DEF(pj_status_t) pj_dns_resolver_set_settings(pj_dns_resolver *resolver,\n\t\t\t\t\t\t const pj_dns_settings *st)\n{\n    PJ_ASSERT_RETURN(resolver && st, PJ_EINVAL);\n\n    pj_mutex_lock(resolver->mutex);\n    pj_memcpy(&resolver->settings, st, sizeof(*st));\n    pj_mutex_unlock(resolver->mutex);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the resolver current settings.\n */\nPJ_DEF(pj_status_t) pj_dns_resolver_get_settings( pj_dns_resolver *resolver,\n\t\t\t\t\t\t  pj_dns_settings *st)\n{\n    PJ_ASSERT_RETURN(resolver && st, PJ_EINVAL);\n\n    pj_mutex_lock(resolver->mutex);\n    pj_memcpy(st, &resolver->settings, sizeof(*st));\n    pj_mutex_unlock(resolver->mutex);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Poll for events from the resolver. \n */\nPJ_DEF(void) pj_dns_resolver_handle_events(pj_dns_resolver *resolver,\n\t\t\t\t\t   const pj_time_val *timeout)\n{\n    PJ_ASSERT_ON_FAIL(resolver, return);\n\n    pj_mutex_lock(resolver->mutex);\n    pj_timer_heap_poll(resolver->timer, NULL);\n    pj_mutex_unlock(resolver->mutex);\n\n    pj_ioqueue_poll(resolver->ioqueue, timeout);\n}\n\n\n/* Get one query node from the free node, if any, or allocate \n * a new one.\n */\nstatic pj_dns_async_query *alloc_qnode(pj_dns_resolver *resolver,\n\t\t\t\t       unsigned options,\n\t\t\t\t       void *user_data,\n\t\t\t\t       pj_dns_callback *cb)\n{\n    pj_dns_async_query *q;\n\n    /* Merge query options with resolver options */\n    options |= resolver->settings.options;\n\n    if (!pj_list_empty(&resolver->query_free_nodes)) {\n\tq = resolver->query_free_nodes.next;\n\tpj_list_erase(q);\n\tpj_bzero(q, sizeof(*q));\n    } else {\n\tq = PJ_POOL_ZALLOC_T(resolver->pool, pj_dns_async_query);\n    }\n\n    /* Init query */\n    q->resolver = resolver;\n    q->options = options;\n    q->user_data = user_data;\n    q->cb = cb;\n    pj_list_init(&q->child_head);\n\n    return q;\n}\n\n\n/*\n * Transmit query.\n */\nstatic pj_status_t transmit_query(pj_dns_resolver *resolver,\n\t\t\t\t  pj_dns_async_query *q)\n{\n    unsigned pkt_size;\n    unsigned i, server_cnt;\n    unsigned servers[PJ_DNS_RESOLVER_MAX_NS];\n    pj_time_val now;\n    pj_str_t name;\n    pj_time_val delay;\n    pj_status_t status;\n\n    /* Select which nameserver(s) to send requests to. */\n    server_cnt = PJ_ARRAY_SIZE(servers);\n    status = select_nameservers(resolver, &server_cnt, servers);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    if (server_cnt == 0) {\n\treturn PJLIB_UTIL_EDNSNOWORKINGNS;\n    }\n\n    /* Start retransmit/timeout timer for the query */\n    pj_assert(q->timer_entry.id == 0);\n    q->timer_entry.id = 1;\n    q->timer_entry.user_data = q;\n    q->timer_entry.cb = &on_timeout;\n\n    delay.sec = 0;\n    delay.msec = resolver->settings.qretr_delay;\n    pj_time_val_normalize(&delay);\n    status = pj_timer_heap_schedule(resolver->timer, &q->timer_entry, &delay);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    /* Check if the socket is available for sending */\n    if (pj_ioqueue_is_pending(resolver->udp_key, &resolver->udp_op_tx_key)) {\n\t++q->transmit_cnt;\n\tPJ_LOG(4,(resolver->name.ptr,\n\t\t  \"Socket busy in transmitting DNS %s query for %s%s\",\n\t\t  pj_dns_get_type_name(q->key.qtype),\n\t\t  q->key.name,\n\t\t  (q->transmit_cnt < resolver->settings.qretr_count?\n\t\t   \", will try again later\":\"\")));\n\treturn PJ_SUCCESS;\n    }\n\n    /* Create DNS query packet */\n    pkt_size = sizeof(resolver->udp_tx_pkt);\n    name = pj_str(q->key.name);\n    status = pj_dns_make_query(resolver->udp_tx_pkt, &pkt_size,\n\t\t\t       q->id, q->key.qtype, &name);\n    if (status != PJ_SUCCESS) {\n\tpj_timer_heap_cancel(resolver->timer, &q->timer_entry);\n\treturn status;\n    }\n\n    /* Get current time. */\n    pj_gettimeofday(&now);\n\n    /* Send the packet to name servers */\n    for (i=0; i<server_cnt; ++i) {\n\tpj_ssize_t sent  = (pj_ssize_t) pkt_size;\n\tstruct nameserver *ns = &resolver->ns[servers[i]];\n\n\tstatus = pj_ioqueue_sendto(resolver->udp_key,\n\t\t\t\t   &resolver->udp_op_tx_key,\n\t\t\t\t   resolver->udp_tx_pkt, &sent, 0,\n\t\t\t\t   &resolver->ns[servers[i]].addr,\n\t\t\t\t   sizeof(pj_sockaddr_in));\n\n\tPJ_PERROR(4,(resolver->name.ptr, status,\n\t\t  \"%s %d bytes to NS %d (%s:%d): DNS %s query for %s\",\n\t\t  (q->transmit_cnt==0? \"Transmitting\":\"Re-transmitting\"),\n\t\t  (int)pkt_size, servers[i],\n\t\t  pj_inet_ntoa(ns->addr.sin_addr), \n\t\t  (int)pj_ntohs(ns->addr.sin_port),\n\t\t  pj_dns_get_type_name(q->key.qtype), \n\t\t  q->key.name));\n\n\tif (ns->q_id == 0) {\n\t    ns->q_id = q->id;\n\t    ns->sent_time = now;\n\t}\n    }\n\n    ++q->transmit_cnt;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Initialize resource key for hash table lookup.\n */\nstatic void init_res_key(struct res_key *key, int type, const pj_str_t *name)\n{\n    unsigned i;\n    pj_size_t len;\n    char *dst = key->name;\n    const char *src = name->ptr;\n\n    pj_bzero(key, sizeof(struct res_key));\n    key->qtype = (pj_uint16_t)type;\n\n    len = name->slen;\n    if (len > PJ_MAX_HOSTNAME) len = PJ_MAX_HOSTNAME;\n\n    /* Copy key, in lowercase */\n    for (i=0; i<len; ++i) {\n\t*dst++ = (char)pj_tolower(*src++);\n    }\n}\n\n\n/* Allocate new cache entry */\nstatic struct cached_res *alloc_entry(pj_dns_resolver *resolver)\n{\n    pj_pool_t *pool;\n    struct cached_res *cache;\n\n    pool = pj_pool_create(resolver->pool->factory, \"dnscache\",\n\t\t\t  RES_BUF_SZ, 256, NULL);\n    cache = PJ_POOL_ZALLOC_T(pool, struct cached_res);\n    cache->pool = pool;\n    cache->ref_cnt = 1;\n\n    return cache;\n}\n\n/* Re-allocate cache entry, to free cached packet */\nstatic void reset_entry(struct cached_res **p_cached)\n{\n    pj_pool_t *pool;\n    struct cached_res *cache = *p_cached;\n    unsigned ref_cnt;\n\n    pool = cache->pool;\n    ref_cnt = cache->ref_cnt;\n\n    pj_pool_reset(pool);\n\n    cache = PJ_POOL_ZALLOC_T(pool, struct cached_res);\n    cache->pool = pool;\n    cache->ref_cnt = ref_cnt;\n    *p_cached = cache;\n}\n\n/* Put unused/expired cached entry to the free list */\nstatic void free_entry(pj_dns_resolver *resolver, struct cached_res *cache)\n{\n    PJ_UNUSED_ARG(resolver);\n    pj_pool_release(cache->pool);\n}\n\n\n/*\n * Create and start asynchronous DNS query for a single resource.\n */\nPJ_DEF(pj_status_t) pj_dns_resolver_start_query( pj_dns_resolver *resolver,\n\t\t\t\t\t\t const pj_str_t *name,\n\t\t\t\t\t\t int type,\n\t\t\t\t\t\t unsigned options,\n\t\t\t\t\t\t pj_dns_callback *cb,\n\t\t\t\t\t\t void *user_data,\n\t\t\t\t\t\t pj_dns_async_query **p_query)\n{\n    pj_time_val now;\n    struct res_key key;\n    struct cached_res *cache;\n    pj_dns_async_query *q;\n    pj_uint32_t hval;\n    pj_status_t status = PJ_SUCCESS;\n\n    /* Validate arguments */\n    PJ_ASSERT_RETURN(resolver && name && type, PJ_EINVAL);\n\n    /* Check name is not too long. */\n    PJ_ASSERT_RETURN(name->slen>0 && name->slen < PJ_MAX_HOSTNAME,\n\t\t     PJ_ENAMETOOLONG);\n\n    /* Check type */\n    PJ_ASSERT_RETURN(type > 0 && type < 0xFFFF, PJ_EINVAL);\n\n    if (p_query)\n\t*p_query = NULL;\n\n    /* Build resource key for looking up hash tables */\n    init_res_key(&key, type, name);\n\n    /* Start working with the resolver */\n    pj_mutex_lock(resolver->mutex);\n\n    /* Get current time. */\n    pj_gettimeofday(&now);\n\n    /* First, check if we have cached response for the specified name/type,\n     * and the cached entry has not expired.\n     */\n    hval = 0;\n    cache = (struct cached_res *) pj_hash_get(resolver->hrescache, &key, \n    \t\t\t\t\t      sizeof(key), &hval);\n    if (cache) {\n\t/* We've found a cached entry. */\n\n\t/* Check for expiration */\n\tif (PJ_TIME_VAL_GT(cache->expiry_time, now)) {\n\n\t    /* Log */\n\t    PJ_LOG(5,(resolver->name.ptr, \n\t\t      \"Picked up DNS %s record for %.*s from cache, ttl=%d\",\n\t\t      pj_dns_get_type_name(type),\n\t\t      (int)name->slen, name->ptr,\n\t\t      (int)(cache->expiry_time.sec - now.sec)));\n\n\t    /* Map DNS Rcode in the response into PJLIB status name space */\n\t    status = PJ_DNS_GET_RCODE(cache->pkt->hdr.flags);\n\t    status = PJ_STATUS_FROM_DNS_RCODE(status);\n\n\t    /* Workaround for deadlock problem. Need to increment the cache's\n\t     * ref counter first before releasing mutex, so the cache won't be\n\t     * destroyed by other thread while in callback.\n\t     */\n\t    cache->ref_cnt++;\n\t    pj_mutex_unlock(resolver->mutex);\n\n\t    /* This cached response is still valid. Just return this\n\t     * response to caller.\n\t     */\n\t    if (cb) {\n\t\t(*cb)(user_data, status, cache->pkt);\n\t    }\n\n\t    /* Done. No host resolution is necessary */\n\t    pj_mutex_lock(resolver->mutex);\n\n\t    /* Decrement the ref counter. Also check if it is time to free\n\t     * the cache (as it has been expired).\n\t     */\n\t    cache->ref_cnt--;\n\t    if (cache->ref_cnt <= 0)\n\t\tfree_entry(resolver, cache);\n\n\t    /* Must return PJ_SUCCESS */\n\t    status = PJ_SUCCESS;\n\n\t    goto on_return;\n\t}\n\n\t/* At this point, we have a cached entry, but this entry has expired.\n\t * Remove this entry from the cached list.\n\t */\n\tpj_hash_set(NULL, resolver->hrescache, &key, sizeof(key), 0, NULL);\n\n\t/* Also free the cache, if it is not being used (by callback). */\n\tcache->ref_cnt--;\n\tif (cache->ref_cnt <= 0)\n\t    free_entry(resolver, cache);\n\n\t/* Must continue with creating a query now */\n    }\n\n    /* Next, check if we have pending query on the same resource */\n    q = (pj_dns_async_query *) pj_hash_get(resolver->hquerybyres, &key, \n    \t\t\t\t\t   sizeof(key), NULL);\n    if (q) {\n\t/* Yes, there's another pending query to the same key.\n\t * Just create a new child query and add this query to\n\t * pending query's child queries.\n\t */\n\tpj_dns_async_query *nq;\n\n\tnq = alloc_qnode(resolver, options, user_data, cb);\n\tpj_list_push_back(&q->child_head, nq);\n\n\t/* Done. This child query will be notified once the \"parent\"\n\t * query completes.\n\t */\n\tstatus = PJ_SUCCESS;\n\tgoto on_return;\n    } \n\n    /* There's no pending query to the same key, initiate a new one. */\n    q = alloc_qnode(resolver, options, user_data, cb);\n\n    /* Save the ID and key */\n    /* TODO: dnsext-forgery-resilient: randomize id for security */\n    q->id = resolver->last_id++;\n    if (resolver->last_id == 0)\n\tresolver->last_id = 1;\n    pj_memcpy(&q->key, &key, sizeof(struct res_key));\n\n    /* Send the query */\n    status = transmit_query(resolver, q);\n    if (status != PJ_SUCCESS) {\n\tpj_list_push_back(&resolver->query_free_nodes, q);\n\tgoto on_return;\n    }\n\n    /* Add query entry to the hash tables */\n    pj_hash_set_np(resolver->hquerybyid, &q->id, sizeof(q->id), \n\t\t   0, q->hbufid, q);\n    pj_hash_set_np(resolver->hquerybyres, &q->key, sizeof(q->key),\n\t\t   0, q->hbufkey, q);\n\n    if (p_query)\n\t*p_query = q;\n\non_return:\n    pj_mutex_unlock(resolver->mutex);\n    return status;\n}\n\n\n/*\n * Cancel a pending query.\n */\nPJ_DEF(pj_status_t) pj_dns_resolver_cancel_query(pj_dns_async_query *query,\n\t\t\t\t\t\t pj_bool_t notify)\n{\n    pj_dns_callback *cb;\n\n    PJ_ASSERT_RETURN(query, PJ_EINVAL);\n\n    pj_mutex_lock(query->resolver->mutex);\n\n    cb = query->cb;\n    query->cb = NULL;\n\n    if (notify)\n\t(*cb)(query->user_data, PJ_ECANCELLED, NULL);\n\n    pj_mutex_unlock(query->resolver->mutex);\n    return PJ_SUCCESS;\n}\n\n\n/* \n * DNS response containing A packet. \n */\nPJ_DEF(pj_status_t) pj_dns_parse_a_response(const pj_dns_parsed_packet *pkt,\n\t\t\t\t\t    pj_dns_a_record *rec)\n{\n    enum { MAX_SEARCH = 20 };\n    pj_str_t hostname, alias = {NULL, 0}, *resname;\n    pj_size_t bufstart = 0;\n    pj_size_t bufleft = sizeof(rec->buf_);\n    unsigned i, ansidx, search_cnt=0;\n\n    PJ_ASSERT_RETURN(pkt && rec, PJ_EINVAL);\n\n    /* Init the record */\n    pj_bzero(rec, sizeof(pj_dns_a_record));\n\n    /* Return error if there's error in the packet. */\n    if (PJ_DNS_GET_RCODE(pkt->hdr.flags))\n\treturn PJ_STATUS_FROM_DNS_RCODE(PJ_DNS_GET_RCODE(pkt->hdr.flags));\n\n    /* Return error if there's no query section */\n    if (pkt->hdr.qdcount == 0)\n\treturn PJLIB_UTIL_EDNSINANSWER;\n\n    /* Return error if there's no answer */\n    if (pkt->hdr.anscount == 0)\n\treturn PJLIB_UTIL_EDNSNOANSWERREC;\n\n    /* Get the hostname from the query. */\n    hostname = pkt->q[0].name;\n\n    /* Copy hostname to the record */\n    if (hostname.slen > (int)bufleft) {\n\treturn PJ_ENAMETOOLONG;\n    }\n\n    pj_memcpy(&rec->buf_[bufstart], hostname.ptr, hostname.slen);\n    rec->name.ptr = &rec->buf_[bufstart];\n    rec->name.slen = hostname.slen;\n\n    bufstart += hostname.slen;\n    bufleft -= hostname.slen;\n\n    /* Find the first RR which name matches the hostname */\n    for (ansidx=0; ansidx < pkt->hdr.anscount; ++ansidx) {\n\tif (pj_stricmp(&pkt->ans[ansidx].name, &hostname)==0)\n\t    break;\n    }\n\n    if (ansidx == pkt->hdr.anscount)\n\treturn PJLIB_UTIL_EDNSNOANSWERREC;\n\n    resname = &hostname;\n\n    /* Keep following CNAME records. */\n    while (pkt->ans[ansidx].type == PJ_DNS_TYPE_CNAME &&\n\t   search_cnt++ < MAX_SEARCH)\n    {\n\tresname = &pkt->ans[ansidx].rdata.cname.name;\n\n\tif (!alias.slen)\n\t    alias = *resname;\n\n\tfor (i=0; i < pkt->hdr.anscount; ++i) {\n\t    if (pj_stricmp(resname, &pkt->ans[i].name)==0) {\n\t\tbreak;\n\t    }\n\t}\n\n\tif (i==pkt->hdr.anscount)\n\t    return PJLIB_UTIL_EDNSNOANSWERREC;\n\n\tansidx = i;\n    }\n\n    if (search_cnt >= MAX_SEARCH)\n\treturn PJLIB_UTIL_EDNSINANSWER;\n\n    if (pkt->ans[ansidx].type != PJ_DNS_TYPE_A)\n\treturn PJLIB_UTIL_EDNSINANSWER;\n\n    /* Copy alias to the record, if present. */\n    if (alias.slen) {\n\tif (alias.slen > (int)bufleft)\n\t    return PJ_ENAMETOOLONG;\n\n\tpj_memcpy(&rec->buf_[bufstart], alias.ptr, alias.slen);\n\trec->alias.ptr = &rec->buf_[bufstart];\n\trec->alias.slen = alias.slen;\n\n\tbufstart += alias.slen;\n\tbufleft -= alias.slen;\n    }\n\n    /* Get the IP addresses. */\n    for (i=0; i < pkt->hdr.anscount; ++i) {\n\tif (pkt->ans[i].type == PJ_DNS_TYPE_A &&\n\t    pj_stricmp(&pkt->ans[i].name, resname)==0 &&\n\t    rec->addr_count < PJ_DNS_MAX_IP_IN_A_REC)\n\t{\n\t    rec->addr[rec->addr_count++].s_addr =\n\t\tpkt->ans[i].rdata.a.ip_addr.s_addr;\n\t}\n    }\n\n    if (rec->addr_count == 0)\n\treturn PJLIB_UTIL_EDNSNOANSWERREC;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Set nameserver state */\nstatic void set_nameserver_state(pj_dns_resolver *resolver,\n\t\t\t\t unsigned index,\n\t\t\t\t enum ns_state state,\n\t\t\t\t const pj_time_val *now)\n{\n    struct nameserver *ns = &resolver->ns[index];\n    enum ns_state old_state = ns->state;\n\n    ns->state = state;\n    ns->state_expiry = *now;\n\n    if (state == STATE_PROBING)\n\tns->state_expiry.sec += ((resolver->settings.qretr_count + 2) *\n\t\t\t\t resolver->settings.qretr_delay) / 1000;\n    else if (state == STATE_ACTIVE)\n\tns->state_expiry.sec += resolver->settings.good_ns_ttl;\n    else\n\tns->state_expiry.sec += resolver->settings.bad_ns_ttl;\n\n    PJ_LOG(5, (resolver->name.ptr, \"Nameserver %s:%d state changed %s --> %s\",\n\t       pj_inet_ntoa(ns->addr.sin_addr),\n\t       (int)pj_ntohs(ns->addr.sin_port),\n\t       state_names[old_state], state_names[state]));\n}\n\n\n/* Select which nameserver(s) to use. Note this may return multiple\n * name servers. The algorithm to select which nameservers to be\n * sent the request to is as follows:\n *  - select the first nameserver that is known to be good for the\n *    last PJ_DNS_RESOLVER_GOOD_NS_TTL interval.\n *  - for all NSes, if last_known_good >= PJ_DNS_RESOLVER_GOOD_NS_TTL, \n *    include the NS to re-check again that the server is still good,\n *    unless the NS is known to be bad in the last PJ_DNS_RESOLVER_BAD_NS_TTL\n *    interval.\n *  - for all NSes, if last_known_bad >= PJ_DNS_RESOLVER_BAD_NS_TTL, \n *    also include the NS to re-check again that the server is still bad.\n */\nstatic pj_status_t select_nameservers(pj_dns_resolver *resolver,\n\t\t\t\t      unsigned *count,\n\t\t\t\t      unsigned servers[])\n{\n    unsigned i, max_count=*count;\n    int min;\n    pj_time_val now;\n\n    pj_assert(max_count > 0);\n\n    *count = 0;\n    servers[0] = 0xFFFF;\n\n    /* Check that nameservers are configured. */\n    if (resolver->ns_count == 0)\n\treturn PJLIB_UTIL_EDNSNONS;\n\n    pj_gettimeofday(&now);\n\n    /* Select one Active nameserver with best response time. */\n    for (min=-1, i=0; i<resolver->ns_count; ++i) {\n\tstruct nameserver *ns = &resolver->ns[i];\n\n\tif (ns->state != STATE_ACTIVE)\n\t    continue;\n\n\tif (min == -1)\n\t    min = i;\n\telse if (PJ_TIME_VAL_LT(ns->rt_delay, resolver->ns[min].rt_delay))\n\t    min = i;\n    }\n    if (min != -1) {\n\tservers[0] = min;\n\t++(*count);\n    }\n\n    /* Scan nameservers. */\n    for (i=0; i<resolver->ns_count && *count < max_count; ++i) {\n\tstruct nameserver *ns = &resolver->ns[i];\n\n\tif (PJ_TIME_VAL_LTE(ns->state_expiry, now)) {\n\t    if (ns->state == STATE_PROBING) {\n\t\tset_nameserver_state(resolver, i, STATE_BAD, &now);\n\t    } else {\n\t\tset_nameserver_state(resolver, i, STATE_PROBING, &now);\n\t\tif ((int)i != min) {\n\t\t    servers[*count] = i;\n\t\t    ++(*count);\n\t\t}\n\t    }\n\t} else if (ns->state == STATE_PROBING && (int)i != min) {\n\t    servers[*count] = i;\n\t    ++(*count);\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* Update name server status */\nstatic void report_nameserver_status(pj_dns_resolver *resolver,\n\t\t\t\t     const pj_sockaddr_in *ns_addr,\n\t\t\t\t     const pj_dns_parsed_packet *pkt)\n{\n    unsigned i;\n    int rcode;\n    pj_uint32_t q_id;\n    pj_time_val now;\n    pj_bool_t is_good;\n\n    /* Only mark nameserver as \"bad\" if it returned non-parseable response or\n     * it returned the following status codes\n     */\n    if (pkt) {\n\trcode = PJ_DNS_GET_RCODE(pkt->hdr.flags);\n\tq_id = pkt->hdr.id;\n    } else {\n\trcode = 0;\n\tq_id = (pj_uint32_t)-1;\n    }\n\n    if (!pkt || rcode == PJ_DNS_RCODE_SERVFAIL ||\n\t        rcode == PJ_DNS_RCODE_REFUSED ||\n\t        rcode == PJ_DNS_RCODE_NOTAUTH) \n    {\n\tis_good = PJ_FALSE;\n    } else {\n\tis_good = PJ_TRUE;\n    }\n\n\n    /* Mark time */\n    pj_gettimeofday(&now);\n\n    /* Recheck all nameservers. */\n    for (i=0; i<resolver->ns_count; ++i) {\n\tstruct nameserver *ns = &resolver->ns[i];\n\n\tif (ns->addr.sin_addr.s_addr == ns_addr->sin_addr.s_addr &&\n\t    ns->addr.sin_port == ns_addr->sin_port &&\n\t    ns->addr.sin_family == ns_addr->sin_family)\n\t{\n\t    if (q_id == ns->q_id) {\n\t\t/* Calculate response time */\n\t\tpj_time_val rt = now;\n\t\tPJ_TIME_VAL_SUB(rt, ns->sent_time);\n\t\tns->rt_delay = rt;\n\t\tns->q_id = 0;\n\t    }\n\t    set_nameserver_state(resolver, i, \n\t\t\t\t (is_good ? STATE_ACTIVE : STATE_BAD), &now);\n\t    break;\n\t}\n    }\n}\n\n\n/* Update response cache */\nstatic void update_res_cache(pj_dns_resolver *resolver,\n\t\t\t     const struct res_key *key,\n\t\t\t     pj_status_t status,\n\t\t\t     pj_bool_t set_expiry,\n\t\t\t     const pj_dns_parsed_packet *pkt)\n{\n    struct cached_res *cache;\n    pj_uint32_t hval=0, ttl;\n\n    /* If status is unsuccessful, clear the same entry from the cache */\n    if (status != PJ_SUCCESS) {\n\tcache = (struct cached_res *) pj_hash_get(resolver->hrescache, key, \n\t\t\t\t\t\t  sizeof(*key), &hval);\n\t/* Remove the entry before releasing its pool (see ticket #1710) */\n\tpj_hash_set(NULL, resolver->hrescache, key, sizeof(*key), hval, NULL);\n\t\n\t/* Free the entry */\n\tif (cache && --cache->ref_cnt <= 0)\n\t    free_entry(resolver, cache);\n    }\n\n\n    /* Calculate expiration time. */\n    if (set_expiry) {\n\tif (pkt->hdr.anscount == 0 || status != PJ_SUCCESS) {\n\t    /* If we don't have answers for the name, then give a different\n\t     * ttl value (note: PJ_DNS_RESOLVER_INVALID_TTL may be zero, \n\t     * which means that invalid names won't be kept in the cache)\n\t     */\n\t    ttl = PJ_DNS_RESOLVER_INVALID_TTL;\n\n\t} else {\n\t    /* Otherwise get the minimum TTL from the answers */\n\t    unsigned i;\n\t    ttl = 0xFFFFFFFF;\n\t    for (i=0; i<pkt->hdr.anscount; ++i) {\n\t\tif (pkt->ans[i].ttl < ttl)\n\t\t    ttl = pkt->ans[i].ttl;\n\t    }\n\t}\n    } else {\n\tttl = 0xFFFFFFFF;\n    }\n\n    /* Apply maximum TTL */\n    if (ttl > resolver->settings.cache_max_ttl)\n\tttl = resolver->settings.cache_max_ttl;\n\n    /* If TTL is zero, clear the same entry in the hash table */\n    if (ttl == 0) {\n\tcache = (struct cached_res *) pj_hash_get(resolver->hrescache, key, \n\t\t\t\t\t\t  sizeof(*key), &hval);\n\t/* Remove the entry before releasing its pool (see ticket #1710) */\n\tpj_hash_set(NULL, resolver->hrescache, key, sizeof(*key), hval, NULL);\n\n\t/* Free the entry */\n\tif (cache && --cache->ref_cnt <= 0)\n\t    free_entry(resolver, cache);\n\treturn;\n    }\n\n    /* Get a cache response entry */\n    cache = (struct cached_res *) pj_hash_get(resolver->hrescache, key, \n    \t\t\t\t\t      sizeof(*key), &hval);\n    if (cache == NULL) {\n\tcache = alloc_entry(resolver);\n    } else if (cache->ref_cnt > 1) {\n\t/* When cache entry is being used by callback (to app), just decrement\n\t * ref_cnt so it will be freed after the callback returns and allocate\n\t * new entry.\n\t */\n\tcache->ref_cnt--;\n\tcache = alloc_entry(resolver);\n    } else {\n\t/* Remove the entry before resetting its pool (see ticket #1710) */\n\tpj_hash_set(NULL, resolver->hrescache, key, sizeof(*key), hval, NULL);\n\n\t/* Reset cache to avoid bloated cache pool */\n\treset_entry(&cache);\n    }\n\n    /* Duplicate the packet.\n     * We don't need to keep the NS and AR sections from the packet,\n     * so exclude from duplication. We do need to keep the Query\n     * section since DNS A parser needs the query section to know\n     * the name being requested.\n     */\n    pj_dns_packet_dup(cache->pool, pkt, \n\t\t      PJ_DNS_NO_NS | PJ_DNS_NO_AR,\n\t\t      &cache->pkt);\n\n    /* Calculate expiration time */\n    if (set_expiry) {\n\tpj_gettimeofday(&cache->expiry_time);\n\tcache->expiry_time.sec += ttl;\n    } else {\n\tcache->expiry_time.sec = 0x7FFFFFFFL;\n\tcache->expiry_time.msec = 0;\n    }\n\n    /* Copy key to the cached response */\n    pj_memcpy(&cache->key, key, sizeof(*key));\n\n    /* Update the hash table */\n    pj_hash_set_np(resolver->hrescache, &cache->key, sizeof(*key), hval,\n\t\t   cache->hbuf, cache);\n\n}\n\n\n/* Callback to be called when query has timed out */\nstatic void on_timeout( pj_timer_heap_t *timer_heap,\n\t\t\tstruct pj_timer_entry *entry)\n{\n    pj_dns_resolver *resolver;\n    pj_dns_async_query *q, *cq;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(timer_heap);\n\n    q = (pj_dns_async_query *) entry->user_data;\n    resolver = q->resolver;\n\n    pj_mutex_lock(resolver->mutex);\n\n    /* Recheck that this query is still pending, since there is a slight\n     * possibility of race condition (timer elapsed while at the same time\n     * response arrives)\n     */\n    if (pj_hash_get(resolver->hquerybyid, &q->id, sizeof(q->id), NULL)==NULL) {\n\t/* Yeah, this query is done. */\n\tpj_mutex_unlock(resolver->mutex);\n\treturn;\n    }\n\n    /* Invalidate id. */\n    q->timer_entry.id = 0;\n\n    /* Check to see if we should retransmit instead of time out */\n    if (q->transmit_cnt < resolver->settings.qretr_count) {\n\tstatus = transmit_query(resolver, q);\n\tif (status == PJ_SUCCESS) {\n\t    pj_mutex_unlock(resolver->mutex);\n\t    return;\n\t} else {\n\t    /* Error occurs */\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\n\t    pj_strerror(status, errmsg, sizeof(errmsg));\n\t    PJ_LOG(4,(resolver->name.ptr,\n\t\t      \"Error transmitting request: %s\", errmsg));\n\n\t    /* Let it fallback to timeout section below */\n\t}\n    }\n\n    /* Clear hash table entries */\n    pj_hash_set(NULL, resolver->hquerybyid, &q->id, sizeof(q->id), 0, NULL);\n    pj_hash_set(NULL, resolver->hquerybyres, &q->key, sizeof(q->key), 0, NULL);\n\n    /* Workaround for deadlock problem in #1565 (similar to #1108) */\n    pj_mutex_unlock(resolver->mutex);\n\n    /* Call application callback, if any. */\n    if (q->cb)\n\t(*q->cb)(q->user_data, PJ_ETIMEDOUT, NULL);\n\n    /* Call application callback for child queries. */\n    cq = q->child_head.next;\n    while (cq != (void*)&q->child_head) {\n\tif (cq->cb)\n\t    (*cq->cb)(cq->user_data, PJ_ETIMEDOUT, NULL);\n\tcq = cq->next;\n    }\n\n    /* Workaround for deadlock problem in #1565 (similar to #1108) */\n    pj_mutex_lock(resolver->mutex);\n\n    /* Clear data */\n    q->timer_entry.id = 0;\n    q->user_data = NULL;\n\n    /* Put child entries into recycle list */\n    cq = q->child_head.next;\n    while (cq != (void*)&q->child_head) {\n\tpj_dns_async_query *next = cq->next;\n\tpj_list_push_back(&resolver->query_free_nodes, cq);\n\tcq = next;\n    }\n\n    /* Put query entry into recycle list */\n    pj_list_push_back(&resolver->query_free_nodes, q);\n\n    pj_mutex_unlock(resolver->mutex);\n}\n\n\n/* Callback from ioqueue when packet is received */\nstatic void on_read_complete(pj_ioqueue_key_t *key, \n                             pj_ioqueue_op_key_t *op_key, \n                             pj_ssize_t bytes_read)\n{\n    pj_dns_resolver *resolver;\n    pj_pool_t *pool = NULL;\n    pj_dns_parsed_packet *dns_pkt;\n    pj_dns_async_query *q;\n    pj_status_t status;\n    PJ_USE_EXCEPTION;\n\n\n    resolver = (pj_dns_resolver *) pj_ioqueue_get_user_data(key);\n    pj_mutex_lock(resolver->mutex);\n\n\n    /* Check for errors */\n    if (bytes_read < 0) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\n\tstatus = (pj_status_t)-bytes_read;\n\tpj_strerror(status, errmsg, sizeof(errmsg));\n\tPJ_LOG(4,(resolver->name.ptr, \n\t\t  \"DNS resolver read error from %s:%d: %s\", \n\t\t  pj_inet_ntoa(resolver->udp_src_addr.sin_addr),\n\t\t  pj_ntohs(resolver->udp_src_addr.sin_port),\n\t\t  errmsg));\n\n\tgoto read_next_packet;\n    }\n\n    PJ_LOG(5,(resolver->name.ptr, \n\t      \"Received %d bytes DNS response from %s:%d\",\n\t      (int)bytes_read, \n\t      pj_inet_ntoa(resolver->udp_src_addr.sin_addr),\n\t      pj_ntohs(resolver->udp_src_addr.sin_port)));\n\n\n    /* Check for zero packet */\n    if (bytes_read == 0)\n\tgoto read_next_packet;\n\n    /* Create temporary pool from a fixed buffer */\n    pool = pj_pool_create_on_buf(\"restmp\", resolver->tmp_pool, \n\t\t\t\t sizeof(resolver->tmp_pool));\n\n    /* Parse DNS response */\n    status = -1;\n    dns_pkt = NULL;\n    PJ_TRY {\n\tstatus = pj_dns_parse_packet(pool, resolver->udp_rx_pkt, \n\t\t\t\t     (unsigned)bytes_read, &dns_pkt);\n    }\n    PJ_CATCH_ANY {\n\tstatus = PJ_ENOMEM;\n    }\n    PJ_END;\n\n    /* Update nameserver status */\n    report_nameserver_status(resolver, &resolver->udp_src_addr, dns_pkt);\n\n    /* Handle parse error */\n    if (status != PJ_SUCCESS) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\n\tpj_strerror(status, errmsg, sizeof(errmsg));\n\tPJ_LOG(3,(resolver->name.ptr, \n\t\t  \"Error parsing DNS response from %s:%d: %s\", \n\t\t  pj_inet_ntoa(resolver->udp_src_addr.sin_addr), \n\t\t  pj_ntohs(resolver->udp_src_addr.sin_port), \n\t\t  errmsg));\n\tgoto read_next_packet;\n    }\n\n    /* Find the query based on the transaction ID */\n    q = (pj_dns_async_query*) \n        pj_hash_get(resolver->hquerybyid, &dns_pkt->hdr.id,\n\t\t    sizeof(dns_pkt->hdr.id), NULL);\n    if (!q) {\n\tPJ_LOG(5,(resolver->name.ptr, \n\t\t  \"DNS response from %s:%d id=%d discarded\",\n\t\t  pj_inet_ntoa(resolver->udp_src_addr.sin_addr), \n\t\t  pj_ntohs(resolver->udp_src_addr.sin_port),\n\t\t  (unsigned)dns_pkt->hdr.id));\n\tgoto read_next_packet;\n    }\n\n    /* Map DNS Rcode in the response into PJLIB status name space */\n    status = PJ_STATUS_FROM_DNS_RCODE(PJ_DNS_GET_RCODE(dns_pkt->hdr.flags));\n\n    /* Cancel query timeout timer. */\n    pj_assert(q->timer_entry.id != 0);\n    pj_timer_heap_cancel(resolver->timer, &q->timer_entry);\n    q->timer_entry.id = 0;\n\n    /* Clear hash table entries */\n    pj_hash_set(NULL, resolver->hquerybyid, &q->id, sizeof(q->id), 0, NULL);\n    pj_hash_set(NULL, resolver->hquerybyres, &q->key, sizeof(q->key), 0, NULL);\n\n    /* Workaround for deadlock problem in #1108 */\n    pj_mutex_unlock(resolver->mutex);\n\n    /* Notify applications first, to allow application to modify the \n     * record before it is saved to the hash table.\n     */\n    if (q->cb)\n\t(*q->cb)(q->user_data, status, dns_pkt);\n\n    /* If query has subqueries, notify subqueries's application callback */\n    if (!pj_list_empty(&q->child_head)) {\n\tpj_dns_async_query *child_q;\n\n\tchild_q = q->child_head.next;\n\twhile (child_q != (pj_dns_async_query*)&q->child_head) {\n\t    if (child_q->cb)\n\t\t(*child_q->cb)(child_q->user_data, status, dns_pkt);\n\t    child_q = child_q->next;\n\t}\n    }\n\n    /* Workaround for deadlock problem in #1108 */\n    pj_mutex_lock(resolver->mutex);\n\n    /* Save/update response cache. */\n    update_res_cache(resolver, &q->key, status, PJ_TRUE, dns_pkt);\n    \n    /* Recycle query objects, starting with the child queries */\n    if (!pj_list_empty(&q->child_head)) {\n\tpj_dns_async_query *child_q;\n\n\tchild_q = q->child_head.next;\n\twhile (child_q != (pj_dns_async_query*)&q->child_head) {\n\t    pj_dns_async_query *next = child_q->next;\n\t    pj_list_erase(child_q);\n\t    pj_list_push_back(&resolver->query_free_nodes, child_q);\n\t    child_q = next;\n\t}\n    }\n    pj_list_push_back(&resolver->query_free_nodes, q);\n\nread_next_packet:\n    if (pool) {\n\t/* needed just in case PJ_HAS_POOL_ALT_API is set */\n\tpj_pool_release(pool);\n    }\n    bytes_read = sizeof(resolver->udp_rx_pkt);\n    resolver->udp_addr_len = sizeof(resolver->udp_src_addr);\n    status = pj_ioqueue_recvfrom(resolver->udp_key, op_key, \n\t\t\t\t resolver->udp_rx_pkt,\n\t\t\t\t &bytes_read, PJ_IOQUEUE_ALWAYS_ASYNC,\n\t\t\t\t &resolver->udp_src_addr, \n\t\t\t\t &resolver->udp_addr_len);\n    if (status != PJ_EPENDING) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\n\tpj_strerror(status, errmsg, sizeof(errmsg));\t\n\tPJ_LOG(4,(resolver->name.ptr, \"DNS resolver ioqueue read error: %s\",\n\t\t  errmsg));\n\n\tpj_assert(!\"Unhandled error\");\n    }\n\n    pj_mutex_unlock(resolver->mutex);\n}\n\n\n/*\n * Put the specified DNS packet into DNS cache. This function is mainly used\n * for testing the resolver, however it can also be used to inject entries\n * into the resolver.\n */\nPJ_DEF(pj_status_t) pj_dns_resolver_add_entry( pj_dns_resolver *resolver,\n\t\t\t\t\t       const pj_dns_parsed_packet *pkt,\n\t\t\t\t\t       pj_bool_t set_ttl)\n{\n    struct res_key key;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(resolver && pkt, PJ_EINVAL);\n\n    /* Packet must be a DNS response */\n    PJ_ASSERT_RETURN(PJ_DNS_GET_QR(pkt->hdr.flags) & 1, PJ_EINVAL);\n\n    /* Make sure there are answers in the packet */\n    PJ_ASSERT_RETURN((pkt->hdr.anscount && pkt->ans) ||\n\t\t      (pkt->hdr.qdcount && pkt->q),\n\t\t     PJLIB_UTIL_EDNSNOANSWERREC);\n\n    pj_mutex_lock(resolver->mutex);\n\n    /* Build resource key for looking up hash tables */\n    pj_bzero(&key, sizeof(struct res_key));\n    if (pkt->hdr.anscount) {\n\t/* Make sure name is not too long. */\n\tPJ_ASSERT_RETURN(pkt->ans[0].name.slen < PJ_MAX_HOSTNAME, \n\t\t\t PJ_ENAMETOOLONG);\n\n\tinit_res_key(&key, pkt->ans[0].type, &pkt->ans[0].name);\n\n    } else {\n\t/* Make sure name is not too long. */\n\tPJ_ASSERT_RETURN(pkt->q[0].name.slen < PJ_MAX_HOSTNAME, \n\t\t\t PJ_ENAMETOOLONG);\n\n\tinit_res_key(&key, pkt->q[0].type, &pkt->q[0].name);\n    }\n\n    /* Insert entry. */\n    update_res_cache(resolver, &key, PJ_SUCCESS, set_ttl, pkt);\n\n    pj_mutex_unlock(resolver->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the total number of response in the response cache.\n */\nPJ_DEF(unsigned) pj_dns_resolver_get_cached_count(pj_dns_resolver *resolver)\n{\n    unsigned count;\n\n    PJ_ASSERT_RETURN(resolver, 0);\n\n    pj_mutex_lock(resolver->mutex);\n    count = pj_hash_count(resolver->hrescache);\n    pj_mutex_unlock(resolver->mutex);\n\n    return count;\n}\n\n\n/*\n * Dump resolver state to the log.\n */\nPJ_DEF(void) pj_dns_resolver_dump(pj_dns_resolver *resolver,\n\t\t\t\t  pj_bool_t detail)\n{\n#if PJ_LOG_MAX_LEVEL >= 3\n    unsigned i;\n    pj_time_val now;\n\n    pj_mutex_lock(resolver->mutex);\n\n    pj_gettimeofday(&now);\n\n    PJ_LOG(3,(resolver->name.ptr, \" Dumping resolver state:\"));\n\n    PJ_LOG(3,(resolver->name.ptr, \"  Name servers:\"));\n    for (i=0; i<resolver->ns_count; ++i) {\n\tstruct nameserver *ns = &resolver->ns[i];\n\n\tPJ_LOG(3,(resolver->name.ptr,\n\t\t  \"   NS %d: %s:%d (state=%s until %ds, rtt=%d ms)\",\n\t\t  i, pj_inet_ntoa(ns->addr.sin_addr),\n\t\t  pj_ntohs(ns->addr.sin_port),\n\t\t  state_names[ns->state],\n\t\t  ns->state_expiry.sec - now.sec,\n\t\t  PJ_TIME_VAL_MSEC(ns->rt_delay)));\n    }\n\n    PJ_LOG(3,(resolver->name.ptr, \"  Nb. of cached responses: %u\",\n\t      pj_hash_count(resolver->hrescache)));\n    if (detail) {\n\tpj_hash_iterator_t itbuf, *it;\n\tit = pj_hash_first(resolver->hrescache, &itbuf);\n\twhile (it) {\n\t    struct cached_res *cache;\n\t    cache = (struct cached_res*)pj_hash_this(resolver->hrescache, it);\n\t    PJ_LOG(3,(resolver->name.ptr, \n\t\t      \"   Type %s: %s\",\n\t\t      pj_dns_get_type_name(cache->key.qtype), \n\t\t      cache->key.name));\n\t    it = pj_hash_next(resolver->hrescache, it);\n\t}\n    }\n    PJ_LOG(3,(resolver->name.ptr, \"  Nb. of pending queries: %u (%u)\",\n\t      pj_hash_count(resolver->hquerybyid),\n\t      pj_hash_count(resolver->hquerybyres)));\n    if (detail) {\n\tpj_hash_iterator_t itbuf, *it;\n\tit = pj_hash_first(resolver->hquerybyid, &itbuf);\n\twhile (it) {\n\t    struct pj_dns_async_query *q;\n\t    q = (pj_dns_async_query*) pj_hash_this(resolver->hquerybyid, it);\n\t    PJ_LOG(3,(resolver->name.ptr, \n\t\t      \"   Type %s: %s\",\n\t\t      pj_dns_get_type_name(q->key.qtype), \n\t\t      q->key.name));\n\t    it = pj_hash_next(resolver->hquerybyid, it);\n\t}\n    }\n    PJ_LOG(3,(resolver->name.ptr, \"  Nb. of pending query free nodes: %u\",\n\t      pj_list_size(&resolver->query_free_nodes)));\n    PJ_LOG(3,(resolver->name.ptr, \"  Nb. of timer entries: %u\",\n\t      pj_timer_heap_count(resolver->timer)));\n    PJ_LOG(3,(resolver->name.ptr, \"  Pool capacity: %d, used size: %d\",\n\t      pj_pool_get_capacity(resolver->pool),\n\t      pj_pool_get_used_size(resolver->pool)));\n\n    pj_mutex_unlock(resolver->mutex);\n#endif\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/resolver_wrap.cpp",
    "content": "/* $Id: resolver_wrap.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * This file is a C++ wrapper, see ticket #886 for details.\n */\n\n#include \"resolver.c\"\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/scanner.c",
    "content": "/* $Id: scanner.c 4209 2012-07-18 10:21:00Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/scanner.h>\n#include <pj/ctype.h>\n#include <pj/string.h>\n#include <pj/except.h>\n#include <pj/os.h>\n#include <pj/errno.h>\n#include <pj/assert.h>\n\n#define PJ_SCAN_IS_SPACE(c)\t\t((c)==' ' || (c)=='\\t')\n#define PJ_SCAN_IS_NEWLINE(c)\t\t((c)=='\\r' || (c)=='\\n')\n#define PJ_SCAN_IS_PROBABLY_SPACE(c)\t((c) <= 32)\n#define PJ_SCAN_CHECK_EOF(s)\t\t(s != scanner->end)\n\n\n#if defined(PJ_SCANNER_USE_BITWISE) && PJ_SCANNER_USE_BITWISE != 0\n#  include \"scanner_cis_bitwise.c\"\n#else\n#  include \"scanner_cis_uint.c\"\n#endif\n\n\nstatic void pj_scan_syntax_err(pj_scanner *scanner)\n{\n    (*scanner->callback)(scanner);\n}\n\n\nPJ_DEF(void) pj_cis_add_range(pj_cis_t *cis, int cstart, int cend)\n{\n    /* Can not set zero. This is the requirement of the parser. */\n    pj_assert(cstart > 0);\n\n    while (cstart != cend) {\n        PJ_CIS_SET(cis, cstart);\n\t++cstart;\n    }\n}\n\nPJ_DEF(void) pj_cis_add_alpha(pj_cis_t *cis)\n{\n    pj_cis_add_range( cis, 'a', 'z'+1);\n    pj_cis_add_range( cis, 'A', 'Z'+1);\n}\n\nPJ_DEF(void) pj_cis_add_num(pj_cis_t *cis)\n{\n    pj_cis_add_range( cis, '0', '9'+1);\n}\n\nPJ_DEF(void) pj_cis_add_str( pj_cis_t *cis, const char *str)\n{\n    while (*str) {\n        PJ_CIS_SET(cis, *str);\n\t++str;\n    }\n}\n\nPJ_DEF(void) pj_cis_add_cis( pj_cis_t *cis, const pj_cis_t *rhs)\n{\n    int i;\n    for (i=0; i<256; ++i) {\n\tif (PJ_CIS_ISSET(rhs, i))\n\t    PJ_CIS_SET(cis, i);\n    }\n}\n\nPJ_DEF(void) pj_cis_del_range( pj_cis_t *cis, int cstart, int cend)\n{\n    while (cstart != cend) {\n        PJ_CIS_CLR(cis, cstart);\n        cstart++;\n    }\n}\n\nPJ_DEF(void) pj_cis_del_str( pj_cis_t *cis, const char *str)\n{\n    while (*str) {\n        PJ_CIS_CLR(cis, *str);\n\t++str;\n    }\n}\n\nPJ_DEF(void) pj_cis_invert( pj_cis_t *cis )\n{\n    unsigned i;\n    /* Can not set zero. This is the requirement of the parser. */\n    for (i=1; i<256; ++i) {\n\tif (PJ_CIS_ISSET(cis,i))\n            PJ_CIS_CLR(cis,i);\n        else\n            PJ_CIS_SET(cis,i);\n    }\n}\n\nPJ_DEF(void) pj_scan_init( pj_scanner *scanner, char *bufstart, \n\t\t\t   pj_size_t buflen, unsigned options, \n\t\t\t   pj_syn_err_func_ptr callback )\n{\n    PJ_CHECK_STACK();\n\n    scanner->begin = scanner->curptr = bufstart;\n    scanner->end = bufstart + buflen;\n    scanner->line = 1;\n    scanner->start_line = scanner->begin;\n    scanner->callback = callback;\n    scanner->skip_ws = options;\n\n    if (scanner->skip_ws) \n\tpj_scan_skip_whitespace(scanner);\n}\n\n\nPJ_DEF(void) pj_scan_fini( pj_scanner *scanner )\n{\n    PJ_CHECK_STACK();\n    PJ_UNUSED_ARG(scanner);\n}\n\nPJ_DEF(void) pj_scan_skip_whitespace( pj_scanner *scanner )\n{\n    register char *s = scanner->curptr;\n\n    while (PJ_SCAN_IS_SPACE(*s)) {\n\t++s;\n    }\n\n    if (PJ_SCAN_IS_NEWLINE(*s) && (scanner->skip_ws & PJ_SCAN_AUTOSKIP_NEWLINE)) {\n\tfor (;;) {\n\t    if (*s == '\\r') {\n\t\t++s;\n\t\tif (*s == '\\n') ++s;\n\t\t++scanner->line;\n\t\tscanner->curptr = scanner->start_line = s;\n\t    } else if (*s == '\\n') {\n\t\t++s;\n\t\t++scanner->line;\n\t\tscanner->curptr = scanner->start_line = s;\n\t    } else if (PJ_SCAN_IS_SPACE(*s)) {\n\t\tdo {\n\t\t    ++s;\n\t\t} while (PJ_SCAN_IS_SPACE(*s));\n\t    } else {\n\t\tbreak;\n\t    }\n\t}\n    }\n\n    if (PJ_SCAN_IS_NEWLINE(*s) && (scanner->skip_ws & PJ_SCAN_AUTOSKIP_WS_HEADER)==PJ_SCAN_AUTOSKIP_WS_HEADER) {\n\t/* Check for header continuation. */\n\tscanner->curptr = s;\n\n\tif (*s == '\\r') {\n\t    ++s;\n\t}\n\tif (*s == '\\n') {\n\t    ++s;\n\t}\n\tscanner->start_line = s;\n\n\tif (PJ_SCAN_IS_SPACE(*s)) {\n\t    register char *t = s;\n\t    do {\n\t\t++t;\n\t    } while (PJ_SCAN_IS_SPACE(*t));\n\n\t    ++scanner->line;\n\t    scanner->curptr = t;\n\t}\n    } else {\n\tscanner->curptr = s;\n    }\n}\n\nPJ_DEF(void) pj_scan_skip_line( pj_scanner *scanner )\n{\n    char *s = pj_ansi_strchr(scanner->curptr, '\\n');\n    if (!s) {\n\tscanner->curptr = scanner->end;\n    } else {\n\tscanner->curptr = scanner->start_line = s+1;\n\tscanner->line++;\n   }\n}\n\nPJ_DEF(int) pj_scan_peek( pj_scanner *scanner,\n\t\t\t  const pj_cis_t *spec, pj_str_t *out)\n{\n    register char *s = scanner->curptr;\n\n    if (s >= scanner->end) {\n\tpj_scan_syntax_err(scanner);\n\treturn -1;\n    }\n\n    /* Don't need to check EOF with PJ_SCAN_CHECK_EOF(s) */\n    while (pj_cis_match(spec, *s))\n\t++s;\n\n    pj_strset3(out, scanner->curptr, s);\n    return *s;\n}\n\n\nPJ_DEF(int) pj_scan_peek_n( pj_scanner *scanner,\n\t\t\t     pj_size_t len, pj_str_t *out)\n{\n    char *endpos = scanner->curptr + len;\n\n    if (endpos > scanner->end) {\n\tpj_scan_syntax_err(scanner);\n\treturn -1;\n    }\n\n    pj_strset(out, scanner->curptr, len);\n    return *endpos;\n}\n\n\nPJ_DEF(int) pj_scan_peek_until( pj_scanner *scanner,\n\t\t\t\tconst pj_cis_t *spec, \n\t\t\t\tpj_str_t *out)\n{\n    register char *s = scanner->curptr;\n\n    if (s >= scanner->end) {\n\tpj_scan_syntax_err(scanner);\n\treturn -1;\n    }\n\n    while (PJ_SCAN_CHECK_EOF(s) && !pj_cis_match( spec, *s))\n\t++s;\n\n    pj_strset3(out, scanner->curptr, s);\n    return *s;\n}\n\n\nPJ_DEF(void) pj_scan_get( pj_scanner *scanner,\n\t\t\t  const pj_cis_t *spec, pj_str_t *out)\n{\n    register char *s = scanner->curptr;\n\n    pj_assert(pj_cis_match(spec,0)==0);\n\n    /* EOF is detected implicitly */\n    if (!pj_cis_match(spec, *s)) {\n\tpj_scan_syntax_err(scanner);\n\treturn;\n    }\n\n    do {\n\t++s;\n    } while (pj_cis_match(spec, *s));\n    /* No need to check EOF here (PJ_SCAN_CHECK_EOF(s)) because\n     * buffer is NULL terminated and pj_cis_match(spec,0) should be\n     * false.\n     */\n\n    pj_strset3(out, scanner->curptr, s);\n\n    scanner->curptr = s;\n\n    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {\n\tpj_scan_skip_whitespace(scanner);    \n    }\n}\n\n\nPJ_DEF(void) pj_scan_get_unescape( pj_scanner *scanner,\n\t\t\t\t   const pj_cis_t *spec, pj_str_t *out)\n{\n    register char *s = scanner->curptr;\n    char *dst = s;\n\n    pj_assert(pj_cis_match(spec,0)==0);\n\n    /* Must not match character '%' */\n    pj_assert(pj_cis_match(spec,'%')==0);\n\n    /* EOF is detected implicitly */\n    if (!pj_cis_match(spec, *s) && *s != '%') {\n\tpj_scan_syntax_err(scanner);\n\treturn;\n    }\n\n    out->ptr = s;\n    do {\n\tif (*s == '%') {\n\t    if (s+3 <= scanner->end && pj_isxdigit(*(s+1)) && \n\t\tpj_isxdigit(*(s+2))) \n\t    {\n\t\t*dst = (pj_uint8_t) ((pj_hex_digit_to_val(*(s+1)) << 4) +\n\t\t\t\t      pj_hex_digit_to_val(*(s+2)));\n\t\t++dst;\n\t\ts += 3;\n\t    } else {\n\t\t*dst++ = *s++;\n\t\t*dst++ = *s++;\n\t\tbreak;\n\t    }\n\t}\n\t\n\tif (pj_cis_match(spec, *s)) {\n\t    char *start = s;\n\t    do {\n\t\t++s;\n\t    } while (pj_cis_match(spec, *s));\n\n\t    if (dst != start) pj_memmove(dst, start, s-start);\n\t    dst += (s-start);\n\t} \n\t\n    } while (*s == '%');\n\n    scanner->curptr = s;\n    out->slen = (dst - out->ptr);\n\n    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {\n\tpj_scan_skip_whitespace(scanner);    \n    }\n}\n\n\nPJ_DEF(void) pj_scan_get_quote( pj_scanner *scanner,\n\t\t\t\tint begin_quote, int end_quote, \n\t\t\t\tpj_str_t *out)\n{\n    char beg = (char)begin_quote;\n    char end = (char)end_quote;\n    pj_scan_get_quotes(scanner, &beg, &end, 1, out);\n}\n\nPJ_DEF(void) pj_scan_get_quotes(pj_scanner *scanner,\n                                const char *begin_quote, const char *end_quote,\n                                int qsize, pj_str_t *out)\n{\n    register char *s = scanner->curptr;\n    int qpair = -1;\n    int i;\n\n    pj_assert(qsize > 0);\n\n    /* Check and eat the begin_quote. */\n    for (i = 0; i < qsize; ++i) {\n\tif (*s == begin_quote[i]) {\n\t    qpair = i;\n\t    break;\n\t}\n    }\n    if (qpair == -1) {\n\tpj_scan_syntax_err(scanner);\n\treturn;\n    }\n    ++s;\n\n    /* Loop until end_quote is found. \n     */\n    do {\n\t/* loop until end_quote is found. */\n\twhile (PJ_SCAN_CHECK_EOF(s) && *s != '\\n' && *s != end_quote[qpair]) {\n\t    ++s;\n\t}\n\n\t/* check that no backslash character precedes the end_quote. */\n\tif (*s == end_quote[qpair]) {\n\t    if (*(s-1) == '\\\\') {\n\t\tchar *q = s-2;\n\t\tchar *r = s-2;\n\n\t\twhile (r != scanner->begin && *r == '\\\\') {\n\t\t    --r;\n\t\t}\n\t\t/* break from main loop if we have odd number of backslashes */\n\t\tif (((unsigned)(q-r) & 0x01) == 1) {\n\t\t    break;\n\t\t}\n\t\t++s;\n\t    } else {\n\t\t/* end_quote is not preceeded by backslash. break now. */\n\t\tbreak;\n\t    }\n\t} else {\n\t    /* loop ended by non-end_quote character. break now. */\n\t    break;\n\t}\n    } while (1);\n\n    /* Check and eat the end quote. */\n    if (*s != end_quote[qpair]) {\n\tpj_scan_syntax_err(scanner);\n\treturn;\n    }\n    ++s;\n\n    pj_strset3(out, scanner->curptr, s);\n\n    scanner->curptr = s;\n\n    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {\n\tpj_scan_skip_whitespace(scanner);\n    }\n}\n\n\nPJ_DEF(void) pj_scan_get_n( pj_scanner *scanner,\n\t\t\t    unsigned N, pj_str_t *out)\n{\n    if (scanner->curptr + N > scanner->end) {\n\tpj_scan_syntax_err(scanner);\n\treturn;\n    }\n\n    pj_strset(out, scanner->curptr, N);\n    \n    scanner->curptr += N;\n\n    if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {\n\tpj_scan_skip_whitespace(scanner);\n    }\n}\n\n\nPJ_DEF(int) pj_scan_get_char( pj_scanner *scanner )\n{\n    int chr = *scanner->curptr;\n\n    if (!chr) {\n\tpj_scan_syntax_err(scanner);\n\treturn 0;\n    }\n\n    ++scanner->curptr;\n\n    if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {\n\tpj_scan_skip_whitespace(scanner);\n    }\n    return chr;\n}\n\n\nPJ_DEF(void) pj_scan_get_newline( pj_scanner *scanner )\n{\n    if (!PJ_SCAN_IS_NEWLINE(*scanner->curptr)) {\n\tpj_scan_syntax_err(scanner);\n\treturn;\n    }\n\n    if (*scanner->curptr == '\\r') {\n\t++scanner->curptr;\n    }\n    if (*scanner->curptr == '\\n') {\n\t++scanner->curptr;\n    }\n\n    ++scanner->line;\n    scanner->start_line = scanner->curptr;\n\n    /**\n     * This probably is a bug, see PROTOS test #2480.\n     * This would cause scanner to incorrectly eat two new lines, e.g.\n     * when parsing:\n     *   \n     *\tContent-Length: 120\\r\\n\n     *\t\\r\\n\n     *\t<space><space><space>...\n     *\n     * When pj_scan_get_newline() is called to parse the first newline\n     * in the Content-Length header, it will eat the second newline\n     * too because it thinks that it's a header continuation.\n     *\n     * if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {\n     *    pj_scan_skip_whitespace(scanner);\n     * }\n     */\n}\n\n\nPJ_DEF(void) pj_scan_get_until( pj_scanner *scanner,\n\t\t\t\tconst pj_cis_t *spec, pj_str_t *out)\n{\n    register char *s = scanner->curptr;\n\n    if (s >= scanner->end) {\n\tpj_scan_syntax_err(scanner);\n\treturn;\n    }\n\n    while (PJ_SCAN_CHECK_EOF(s) && !pj_cis_match(spec, *s)) {\n\t++s;\n    }\n\n    pj_strset3(out, scanner->curptr, s);\n\n    scanner->curptr = s;\n\n    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {\n\tpj_scan_skip_whitespace(scanner);\n    }\n}\n\n\nPJ_DEF(void) pj_scan_get_until_ch( pj_scanner *scanner, \n\t\t\t\t   int until_char, pj_str_t *out)\n{\n    register char *s = scanner->curptr;\n\n    if (s >= scanner->end) {\n\tpj_scan_syntax_err(scanner);\n\treturn;\n    }\n\n    while (PJ_SCAN_CHECK_EOF(s) && *s != until_char) {\n\t++s;\n    }\n\n    pj_strset3(out, scanner->curptr, s);\n\n    scanner->curptr = s;\n\n    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {\n\tpj_scan_skip_whitespace(scanner);\n    }\n}\n\n\nPJ_DEF(void) pj_scan_get_until_chr( pj_scanner *scanner,\n\t\t\t\t     const char *until_spec, pj_str_t *out)\n{\n    register char *s = scanner->curptr;\n    pj_size_t speclen;\n\n    if (s >= scanner->end) {\n\tpj_scan_syntax_err(scanner);\n\treturn;\n    }\n\n    speclen = strlen(until_spec);\n    while (PJ_SCAN_CHECK_EOF(s) && !memchr(until_spec, *s, speclen)) {\n\t++s;\n    }\n\n    pj_strset3(out, scanner->curptr, s);\n\n    scanner->curptr = s;\n\n    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {\n\tpj_scan_skip_whitespace(scanner);\n    }\n}\n\nPJ_DEF(void) pj_scan_advance_n( pj_scanner *scanner,\n\t\t\t\t unsigned N, pj_bool_t skip_ws)\n{\n    if (scanner->curptr + N > scanner->end) {\n\tpj_scan_syntax_err(scanner);\n\treturn;\n    }\n\n    scanner->curptr += N;\n\n    if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && skip_ws) {\n\tpj_scan_skip_whitespace(scanner);\n    }\n}\n\n\nPJ_DEF(int) pj_scan_strcmp( pj_scanner *scanner, const char *s, int len)\n{\n    if (scanner->curptr + len > scanner->end) {\n\tpj_scan_syntax_err(scanner);\n\treturn -1;\n    }\n    return strncmp(scanner->curptr, s, len);\n}\n\n\nPJ_DEF(int) pj_scan_stricmp( pj_scanner *scanner, const char *s, int len)\n{\n    if (scanner->curptr + len > scanner->end) {\n\tpj_scan_syntax_err(scanner);\n\treturn -1;\n    }\n    return pj_ansi_strnicmp(scanner->curptr, s, len);\n}\n\nPJ_DEF(int) pj_scan_stricmp_alnum( pj_scanner *scanner, const char *s, \n\t\t\t\t   int len)\n{\n    if (scanner->curptr + len > scanner->end) {\n\tpj_scan_syntax_err(scanner);\n\treturn -1;\n    }\n    return strnicmp_alnum(scanner->curptr, s, len);\n}\n\nPJ_DEF(void) pj_scan_save_state( const pj_scanner *scanner, \n\t\t\t\t pj_scan_state *state)\n{\n    state->curptr = scanner->curptr;\n    state->line = scanner->line;\n    state->start_line = scanner->start_line;\n}\n\n\nPJ_DEF(void) pj_scan_restore_state( pj_scanner *scanner, \n\t\t\t\t    pj_scan_state *state)\n{\n    scanner->curptr = state->curptr;\n    scanner->line = state->line;\n    scanner->start_line = state->start_line;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/scanner_cis_bitwise.c",
    "content": "/* $Id: scanner_cis_bitwise.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * THIS FILE IS INCLUDED BY scanner.c.\n * DO NOT COMPILE THIS FILE ALONE!\n */\n\nPJ_DEF(void) pj_cis_buf_init( pj_cis_buf_t *cis_buf)\n{\n    pj_bzero(cis_buf->cis_buf, sizeof(cis_buf->cis_buf));\n    cis_buf->use_mask = 0;\n}\n\nPJ_DEF(pj_status_t) pj_cis_init(pj_cis_buf_t *cis_buf, pj_cis_t *cis)\n{\n    unsigned i;\n\n    cis->cis_buf = cis_buf->cis_buf;\n\n    for (i=0; i<PJ_CIS_MAX_INDEX; ++i) {\n        if ((cis_buf->use_mask & (1 << i)) == 0) {\n            cis->cis_id = i;\n\t    cis_buf->use_mask |= (1 << i);\n            return PJ_SUCCESS;\n        }\n    }\n\n    cis->cis_id = PJ_CIS_MAX_INDEX;\n    return PJ_ETOOMANY;\n}\n\nPJ_DEF(pj_status_t) pj_cis_dup( pj_cis_t *new_cis, pj_cis_t *existing)\n{\n    pj_status_t status;\n    unsigned i;\n\n    /* Warning: typecasting here! */\n    status = pj_cis_init((pj_cis_buf_t*)existing->cis_buf, new_cis);\n    if (status != PJ_SUCCESS)\n        return status;\n\n    for (i=0; i<256; ++i) {\n        if (PJ_CIS_ISSET(existing, i))\n            PJ_CIS_SET(new_cis, i);\n        else\n            PJ_CIS_CLR(new_cis, i);\n    }\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/scanner_cis_uint.c",
    "content": "/* $Id: scanner_cis_uint.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * THIS FILE IS INCLUDED BY scanner.c.\n * DO NOT COMPILE THIS FILE ALONE!\n */\n\n\nPJ_DEF(void) pj_cis_buf_init( pj_cis_buf_t *cis_buf)\n{\n    /* Do nothing. */\n    PJ_UNUSED_ARG(cis_buf);\n}\n\nPJ_DEF(pj_status_t) pj_cis_init(pj_cis_buf_t *cis_buf, pj_cis_t *cis)\n{\n    PJ_UNUSED_ARG(cis_buf);\n    pj_bzero(cis->cis_buf, sizeof(cis->cis_buf));\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_cis_dup( pj_cis_t *new_cis, pj_cis_t *existing)\n{\n    pj_memcpy(new_cis, existing, sizeof(pj_cis_t));\n    return PJ_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/sha1.c",
    "content": "/* $Id: sha1.c 3549 2011-05-05 05:10:06Z nanang $ */\n/*\n * Modified 2/07\n * By Benny Prijono <benny@prijono.org>\n * Still 100% Public Domain\n *\n * This is the implementation of SHA-1 encryption algorithm based on\n * Steve Reid work. Modified to work with PJLIB.\n */\n\n/*\nSHA-1 in C\nBy Steve Reid <sreid@sea-to-sky.net>\n100% Public Domain\n\n-----------------\nModified 7/98 \nBy James H. Brown <jbrown@burgoyne.com>\nStill 100% Public Domain\n\nCorrected a problem which generated improper hash values on 16 bit machines\nRoutine SHA1Update changed from\n\tvoid SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int\nlen)\nto\n\tvoid SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned\nlong len)\n\nThe 'len' parameter was declared an int which works fine on 32 bit machines.\nHowever, on 16 bit machines an int is too small for the shifts being done\nagainst\nit.  This caused the hash function to generate incorrect values if len was\ngreater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().\n\nSince the file IO in main() reads 16K at a time, any file 8K or larger would\nbe guaranteed to generate the wrong hash (e.g. Test Vector #3, a million\n\"a\"s).\n\nI also changed the declaration of variables i & j in SHA1Update to \nunsigned long from unsigned int for the same reason.\n\nThese changes should make no difference to any 32 bit implementations since\nan\nint and a long are the same size in those environments.\n\n--\nI also corrected a few compiler warnings generated by Borland C.\n1. Added #include <process.h> for exit() prototype\n2. Removed unused variable 'j' in SHA1Final\n3. Changed exit(0) to return(0) at end of main.\n\nALL changes I made can be located by searching for comments containing 'JHB'\n-----------------\nModified 8/98\nBy Steve Reid <sreid@sea-to-sky.net>\nStill 100% public domain\n\n1- Removed #include <process.h> and used return() instead of exit()\n2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)\n3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net\n\n-----------------\nModified 4/01\nBy Saul Kravitz <Saul.Kravitz@celera.com>\nStill 100% PD\nModified to run on Compaq Alpha hardware.  \n\n-----------------\nModified 07/2002\nBy Ralph Giles <giles@ghostscript.com>\nStill 100% public domain\nmodified for use with stdint types, autoconf\ncode cleanup, removed attribution comments\nswitched SHA1Final() argument order for consistency\nuse SHA1_ prefix for public api\nmove public api to sha1.h\n*/\n\n/*\nTest Vectors (from FIPS PUB 180-1)\n\"abc\"\n  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D\n\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\"\n  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1\nA million repetitions of \"a\"\n  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F\n*/\n\n/* #define SHA1HANDSOFF  */\n/* blp:\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdio.h>\n#include <string.h>\n\n#include \"os_types.h\"\n\n#include \"sha1.h\"\n*/\n#include <pjlib-util/sha1.h>\n#include <pj/string.h>\n\n#undef SHA1HANDSOFF\n\n\nstatic void SHA1_Transform(pj_uint32_t state[5], pj_uint8_t buffer[64]);\n\n#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))\n\n/* blk0() and blk() perform the initial expand. */\n/* I got the idea of expanding during the round function from SSLeay */\n/* FIXME: can we do this in an endian-proof way? */\n/* #ifdef WORDS_BIGENDIAN */\n#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN != 0\n#define blk0(i) block->l[i]\n#else\n#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \\\n    |(rol(block->l[i],8)&0x00FF00FF))\n#endif\n#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \\\n    ^block->l[(i+2)&15]^block->l[i&15],1))\n\n/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */\n#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);\n#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);\n#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);\n#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);\n#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);\n\n\n/* Hash a single 512-bit block. This is the core of the algorithm. */\nstatic void SHA1_Transform(pj_uint32_t state[5], pj_uint8_t buffer[64])\n{\n    pj_uint32_t a, b, c, d, e;\n    typedef union {\n        pj_uint8_t c[64];\n        pj_uint32_t l[16];\n    } CHAR64LONG16;\n    CHAR64LONG16* block;\n\n#ifdef SHA1HANDSOFF\n    static pj_uint8_t workspace[64];\n    block = (CHAR64LONG16*)workspace;\n    pj_memcpy(block, buffer, 64);\n#else\n    block = (CHAR64LONG16*)buffer;\n#endif\n\n    /* Copy context->state[] to working vars */\n    a = state[0];\n    b = state[1];\n    c = state[2];\n    d = state[3];\n    e = state[4];\n\n    /* 4 rounds of 20 operations each. Loop unrolled. */\n    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);\n    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);\n    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);\n    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);\n    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);\n    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);\n    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);\n    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);\n    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);\n    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);\n    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);\n    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);\n    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);\n    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);\n    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);\n    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);\n    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);\n    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);\n    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);\n    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);\n\n    /* Add the working vars back into context.state[] */\n    state[0] += a;\n    state[1] += b;\n    state[2] += c;\n    state[3] += d;\n    state[4] += e;\n\n    /* Wipe variables */\n    a = b = c = d = e = 0;\n}\n\n\n/* SHA1Init - Initialize new context */\nPJ_DEF(void) pj_sha1_init(pj_sha1_context* context)\n{\n    /* SHA1 initialization constants */\n    context->state[0] = 0x67452301;\n    context->state[1] = 0xEFCDAB89;\n    context->state[2] = 0x98BADCFE;\n    context->state[3] = 0x10325476;\n    context->state[4] = 0xC3D2E1F0;\n    context->count[0] = context->count[1] = 0;\n}\n\n\n/* Run your data through this. */\nPJ_DEF(void) pj_sha1_update(pj_sha1_context* context, \n\t\t\t    const pj_uint8_t* data, const pj_size_t len)\n{\n    pj_size_t i, j;\n\n    j = (context->count[0] >> 3) & 63;\n    if ((context->count[0] += (pj_uint32_t)len << 3) < (len << 3)) \n\tcontext->count[1]++;\n    context->count[1] += ((pj_uint32_t)len >> 29);\n    if ((j + len) > 63) {\n        pj_memcpy(&context->buffer[j], data, (i = 64-j));\n        SHA1_Transform(context->state, context->buffer);\n        for ( ; i + 63 < len; i += 64) {\n\t    pj_uint8_t tmp[64];\n\t    pj_memcpy(tmp, data + i, 64);\n            SHA1_Transform(context->state, tmp);\n        }\n        j = 0;\n    }\n    else i = 0;\n    pj_memcpy(&context->buffer[j], &data[i], len - i);\n\n}\n\n\n/* Add padding and return the message digest. */\nPJ_DEF(void) pj_sha1_final(pj_sha1_context* context, \n\t\t\t   pj_uint8_t digest[PJ_SHA1_DIGEST_SIZE])\n{\n    pj_uint32_t i;\n    pj_uint8_t  finalcount[8];\n\n    for (i = 0; i < 8; i++) {\n        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]\n         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */\n    }\n    pj_sha1_update(context, (pj_uint8_t *)\"\\200\", 1);\n    while ((context->count[0] & 504) != 448) {\n        pj_sha1_update(context, (pj_uint8_t *)\"\\0\", 1);\n    }\n    pj_sha1_update(context, finalcount, 8);  /* Should cause a SHA1_Transform() */\n    for (i = 0; i < PJ_SHA1_DIGEST_SIZE; i++) {\n        digest[i] = (pj_uint8_t)\n         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);\n    }\n    \n    /* Wipe variables */\n    i = 0;\n    pj_memset(context->buffer, 0, 64);\n    pj_memset(context->state, 0, 20);\n    pj_memset(context->count, 0, 8);\n    pj_memset(finalcount, 0, 8);\t/* SWR */\n\n#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite its own static vars */\n    SHA1_Transform(context->state, context->buffer);\n#endif\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/srv_resolver.c",
    "content": "/* $Id: srv_resolver.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/srv_resolver.h>\n#include <pjlib-util/errno.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n\n\n#define THIS_FILE   \"srv_resolver.c\"\n\n#define ADDR_MAX_COUNT\t    PJ_DNS_MAX_IP_IN_A_REC\n\nstruct common\n{\n    pj_dns_type\t\t     type;\t    /**< Type of this structure.*/\n};\n\nstruct srv_target\n{\n    struct common\t    common;\n    pj_dns_srv_async_query *parent;\n    pj_str_t\t\t    target_name;\n    pj_dns_async_query\t   *q_a;\n    char\t\t    target_buf[PJ_MAX_HOSTNAME];\n    pj_str_t\t\t    cname;\n    char\t\t    cname_buf[PJ_MAX_HOSTNAME];\n    unsigned\t\t    port;\n    unsigned\t\t    priority;\n    unsigned\t\t    weight;\n    unsigned\t\t    sum;\n    unsigned\t\t    addr_cnt;\n    pj_in_addr\t\t    addr[ADDR_MAX_COUNT];\n};\n\nstruct pj_dns_srv_async_query\n{\n    struct common\t     common;\n    char\t\t    *objname;\n\n    pj_dns_type\t\t     dns_state;\t    /**< DNS type being resolved.   */\n    pj_dns_resolver\t    *resolver;\t    /**< Resolver SIP instance.\t    */\n    void\t\t    *token;\n    pj_dns_async_query\t    *q_srv;\n    pj_dns_srv_resolver_cb  *cb;\n    pj_status_t\t\t     last_error;\n\n    /* Original request: */\n    unsigned\t\t     option;\n    pj_str_t\t\t     full_name;\n    pj_str_t\t\t     domain_part;\n    pj_uint16_t\t\t     def_port;\n\n    /* SRV records and their resolved IP addresses: */\n    unsigned\t\t     srv_cnt;\n    struct srv_target\t     srv[PJ_DNS_SRV_MAX_ADDR];\n\n    /* Number of hosts in SRV records that the IP address has been resolved */\n    unsigned\t\t     host_resolved;\n\n};\n\n\n/* Async resolver callback, forward decl. */\nstatic void dns_callback(void *user_data,\n\t\t\t pj_status_t status,\n\t\t\t pj_dns_parsed_packet *pkt);\n\n\n\n/*\n * The public API to invoke DNS SRV resolution.\n */\nPJ_DEF(pj_status_t) pj_dns_srv_resolve( const pj_str_t *domain_name,\n\t\t\t\t        const pj_str_t *res_name,\n\t\t\t\t\tunsigned def_port,\n\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\tpj_dns_resolver *resolver,\n\t\t\t\t\tunsigned option,\n\t\t\t\t\tvoid *token,\n\t\t\t\t\tpj_dns_srv_resolver_cb *cb,\n\t\t\t\t\tpj_dns_srv_async_query **p_query)\n{\n    pj_size_t len;\n    pj_str_t target_name;\n    pj_dns_srv_async_query *query_job;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(domain_name && domain_name->slen &&\n\t\t     res_name && res_name->slen &&\n\t\t     pool && resolver && cb, PJ_EINVAL);\n\n    /* Build full name */\n    len = domain_name->slen + res_name->slen + 2;\n    target_name.ptr = (char*) pj_pool_alloc(pool, len);\n    pj_strcpy(&target_name, res_name);\n    if (res_name->ptr[res_name->slen-1] != '.')\n\tpj_strcat2(&target_name, \".\");\n    len = target_name.slen;\n    pj_strcat(&target_name, domain_name);\n    target_name.ptr[target_name.slen] = '\\0';\n\n\n    /* Build the query_job state */\n    query_job = PJ_POOL_ZALLOC_T(pool, pj_dns_srv_async_query);\n    query_job->common.type = PJ_DNS_TYPE_SRV;\n    query_job->objname = target_name.ptr;\n    query_job->resolver = resolver;\n    query_job->token = token;\n    query_job->cb = cb;\n    query_job->option = option;\n    query_job->full_name = target_name;\n    query_job->domain_part.ptr = target_name.ptr + len;\n    query_job->domain_part.slen = target_name.slen - len;\n    query_job->def_port = (pj_uint16_t)def_port;\n\n    /* Start the asynchronous query_job */\n\n    query_job->dns_state = PJ_DNS_TYPE_SRV;\n\n    PJ_LOG(5, (query_job->objname, \n\t       \"Starting async DNS %s query_job: target=%.*s:%d\",\n\t       pj_dns_get_type_name(query_job->dns_state),\n\t       (int)target_name.slen, target_name.ptr,\n\t       def_port));\n\n    status = pj_dns_resolver_start_query(resolver, &target_name, \n\t\t\t\t         query_job->dns_state, 0, \n\t\t\t\t\t &dns_callback,\n    \t\t\t\t\t query_job, &query_job->q_srv);\n    if (status==PJ_SUCCESS && p_query)\n\t*p_query = query_job;\n\n    return status;\n}\n\n\n/*\n * Cancel pending query.\n */\nPJ_DEF(pj_status_t) pj_dns_srv_cancel_query(pj_dns_srv_async_query *query,\n\t\t\t\t\t    pj_bool_t notify)\n{\n    pj_bool_t has_pending = PJ_FALSE;\n    unsigned i;\n\n    if (query->q_srv) {\n\tpj_dns_resolver_cancel_query(query->q_srv, PJ_FALSE);\n\tquery->q_srv = NULL;\n\thas_pending = PJ_TRUE;\n    }\n\n    for (i=0; i<query->srv_cnt; ++i) {\n\tstruct srv_target *srv = &query->srv[i];\n\tif (srv->q_a) {\n\t    pj_dns_resolver_cancel_query(srv->q_a, PJ_FALSE);\n\t    srv->q_a = NULL;\n\t    has_pending = PJ_TRUE;\n\t}\n    }\n\n    if (has_pending && notify && query->cb) {\n\t(*query->cb)(query->token, PJ_ECANCELLED, NULL);\n    }\n\n    return has_pending? PJ_SUCCESS : PJ_EINVALIDOP;\n}\n\n\n#define SWAP(type,ptr1,ptr2) if (ptr1 != ptr2) { \\\n\t\t\t\ttype tmp; \\\n\t\t\t\tpj_memcpy(&tmp, ptr1, sizeof(type)); \\\n\t\t\t\tpj_memcpy(ptr1, ptr2, sizeof(type)); \\\n\t\t\t\t(ptr1)->target_name.ptr = (ptr1)->target_buf;\\\n\t\t\t\tpj_memcpy(ptr2, &tmp, sizeof(type)); \\\n\t\t\t\t(ptr2)->target_name.ptr = (ptr2)->target_buf;\\\n\t\t\t     } else {}\n\n\n/* Build server entries in the query_job based on received SRV response */\nstatic void build_server_entries(pj_dns_srv_async_query *query_job, \n\t\t\t\t pj_dns_parsed_packet *response)\n{\n    unsigned i;\n\n    /* Save the Resource Records in DNS answer into SRV targets. */\n    query_job->srv_cnt = 0;\n    for (i=0; i<response->hdr.anscount && \n\t      query_job->srv_cnt < PJ_DNS_SRV_MAX_ADDR; ++i) \n    {\n\tpj_dns_parsed_rr *rr = &response->ans[i];\n\tstruct srv_target *srv = &query_job->srv[query_job->srv_cnt];\n\n\tif (rr->type != PJ_DNS_TYPE_SRV) {\n\t    PJ_LOG(4,(query_job->objname, \n\t\t      \"Received non SRV answer for SRV query_job!\"));\n\t    continue;\n\t}\n\n\tif (rr->rdata.srv.target.slen > PJ_MAX_HOSTNAME) {\n\t    PJ_LOG(4,(query_job->objname, \"Hostname is too long!\"));\n\t    continue;\n\t}\n\n\t/* Build the SRV entry for RR */\n\tpj_bzero(srv, sizeof(*srv));\n\tsrv->target_name.ptr = srv->target_buf;\n\tpj_strncpy(&srv->target_name, &rr->rdata.srv.target,\n\t\t   sizeof(srv->target_buf));\n\tsrv->port = rr->rdata.srv.port;\n\tsrv->priority = rr->rdata.srv.prio;\n\tsrv->weight = rr->rdata.srv.weight;\n\t\n\t++query_job->srv_cnt;\n    }\n\n    if (query_job->srv_cnt == 0) {\n\tPJ_LOG(4,(query_job->objname, \n\t\t  \"Could not find SRV record in DNS answer!\"));\n\treturn;\n    }\n\n    /* First pass: \n     *\torder the entries based on priority.\n     */\n    for (i=0; i<query_job->srv_cnt-1; ++i) {\n\tunsigned min = i, j;\n\tfor (j=i+1; j<query_job->srv_cnt; ++j) {\n\t    if (query_job->srv[j].priority < query_job->srv[min].priority)\n\t\tmin = j;\n\t}\n\tSWAP(struct srv_target, &query_job->srv[i], &query_job->srv[min]);\n    }\n\n    /* Second pass:\n     *\tOrder the entry in a list.\n     *\n     *  The algorithm for selecting server among servers with the same\n     *  priority is described in RFC 2782.\n     */\n    for (i=0; i<query_job->srv_cnt; ++i) {\n\tunsigned j, count=1, sum;\n\n\t/* Calculate running sum for servers with the same priority */\n\tsum = query_job->srv[i].sum = query_job->srv[i].weight;\n\tfor (j=i+1; j<query_job->srv_cnt && \n\t\t    query_job->srv[j].priority == query_job->srv[i].priority; ++j)\n\t{\n\t    sum += query_job->srv[j].weight;\n\t    query_job->srv[j].sum = sum;\n\t    ++count;\n\t}\n\n\tif (count > 1) {\n\t    unsigned r;\n\n\t    /* Elect one random number between zero and the total sum of\n\t     * weight (inclusive).\n\t     */\n\t    r = pj_rand() % (sum + 1);\n\n\t    /* Select the first server which running sum is greater than or\n\t     * equal to the random number.\n\t     */\n\t    for (j=i; j<i+count; ++j) {\n\t\tif (query_job->srv[j].sum >= r)\n\t\t    break;\n\t    }\n\n\t    /* Must have selected one! */\n\t    pj_assert(j != i+count);\n\n\t    /* Put this entry in front (of entries with same priority) */\n\t    SWAP(struct srv_target, &query_job->srv[i], &query_job->srv[j]);\n\n\t    /* Remove all other entries (of the same priority) */\n\t    /* Don't need to do this.\n\t     * See https://trac.pjsip.org/repos/ticket/1719\n\t    while (count > 1) {\n\t\tpj_array_erase(query_job->srv, sizeof(struct srv_target), \n\t\t\t       query_job->srv_cnt, i+1);\n\t\t--count;\n\t\t--query_job->srv_cnt;\n\t    }\n\t    */\n\t}\n    }\n\n    /* Since we've been moving around SRV entries, update the pointers\n     * in target_name.\n     */\n    for (i=0; i<query_job->srv_cnt; ++i) {\n\tquery_job->srv[i].target_name.ptr = query_job->srv[i].target_buf;\n    }\n\n    /* Check for Additional Info section if A records are available, and\n     * fill in the IP address (so that we won't need to resolve the A \n     * record with another DNS query_job). \n     */\n    for (i=0; i<response->hdr.arcount; ++i) {\n\tpj_dns_parsed_rr *rr = &response->arr[i];\n\tunsigned j;\n\n\tif (rr->type != PJ_DNS_TYPE_A)\n\t    continue;\n\n\t/* Yippeaiyee!! There is an \"A\" record! \n\t * Update the IP address of the corresponding SRV record.\n\t */\n\tfor (j=0; j<query_job->srv_cnt; ++j) {\n            if (pj_stricmp(&rr->name, &query_job->srv[j].target_name)==0 &&\n                query_job->srv[j].addr_cnt < ADDR_MAX_COUNT)\n            {\n\t\tunsigned cnt = query_job->srv[j].addr_cnt;\n\t\tquery_job->srv[j].addr[cnt].s_addr = rr->rdata.a.ip_addr.s_addr;\n\t\t/* Only increment host_resolved once per SRV record */\n\t\tif (query_job->srv[j].addr_cnt == 0)\n\t\t    ++query_job->host_resolved;\n\t\t++query_job->srv[j].addr_cnt;\n\t\tbreak;\n\t    }\n\t}\n\n\t/* Not valid message; SRV entry might have been deleted in\n\t * server selection process.\n\t */\n\t/*\n\tif (j == query_job->srv_cnt) {\n\t    PJ_LOG(4,(query_job->objname, \n\t\t      \"Received DNS SRV answer with A record, but \"\n\t\t      \"couldn't find matching name (name=%.*s)\",\n\t\t      (int)rr->name.slen,\n\t\t      rr->name.ptr));\n\t}\n\t*/\n    }\n\n    /* Rescan again the name specified in the SRV record to see if IP\n     * address is specified as the target name (unlikely, but well, who \n     * knows..).\n     */\n    for (i=0; i<query_job->srv_cnt; ++i) {\n\tpj_in_addr addr;\n\n\tif (query_job->srv[i].addr_cnt != 0) {\n\t    /* IP address already resolved */\n\t    continue;\n\t}\n\n\tif (pj_inet_aton(&query_job->srv[i].target_name, &addr) != 0) {\n\t    query_job->srv[i].addr[query_job->srv[i].addr_cnt++] = addr;\n\t    ++query_job->host_resolved;\n\t}\n    }\n\n    /* Print resolved entries to the log */\n    PJ_LOG(5,(query_job->objname, \n\t      \"SRV query_job for %.*s completed, \"\n\t      \"%d of %d total entries selected%c\",\n\t      (int)query_job->full_name.slen,\n\t      query_job->full_name.ptr,\n\t      query_job->srv_cnt,\n\t      response->hdr.anscount,\n\t      (query_job->srv_cnt ? ':' : ' ')));\n\n    for (i=0; i<query_job->srv_cnt; ++i) {\n\tconst char *addr;\n\n\tif (query_job->srv[i].addr_cnt != 0)\n\t    addr = pj_inet_ntoa(query_job->srv[i].addr[0]);\n\telse\n\t    addr = \"-\";\n\n\tPJ_LOG(5,(query_job->objname, \n\t\t  \" %d: SRV %d %d %d %.*s (%s)\",\n\t\t  i, query_job->srv[i].priority, \n\t\t  query_job->srv[i].weight, \n\t\t  query_job->srv[i].port, \n\t\t  (int)query_job->srv[i].target_name.slen, \n\t\t  query_job->srv[i].target_name.ptr,\n\t\t  addr));\n    }\n}\n\n\n/* Start DNS A record queries for all SRV records in the query_job structure */\nstatic pj_status_t resolve_hostnames(pj_dns_srv_async_query *query_job)\n{\n    unsigned i, err_cnt = 0;\n    pj_status_t err=PJ_SUCCESS, status;\n\n    query_job->dns_state = PJ_DNS_TYPE_A;\n    for (i=0; i<query_job->srv_cnt; ++i) {\n\tstruct srv_target *srv = &query_job->srv[i];\n\n\tPJ_LOG(5, (query_job->objname, \n\t\t   \"Starting async DNS A query_job for %.*s\",\n\t\t   (int)srv->target_name.slen, \n\t\t   srv->target_name.ptr));\n\n\tsrv->common.type = PJ_DNS_TYPE_A;\n\tsrv->parent = query_job;\n\n\t/* See also #1809: dns_callback() will be invoked synchronously when response\n\t * is available in the cache, and var 'query_job->host_resolved' will get\n\t * incremented within the dns_callback(), which will cause this function\n\t * returning false error, so don't use that variable for counting errors.\n\t */\n\tstatus = pj_dns_resolver_start_query(query_job->resolver,\n\t\t\t\t\t     &srv->target_name,\n\t\t\t\t\t     PJ_DNS_TYPE_A, 0,\n\t\t\t\t\t     &dns_callback,\n\t\t\t\t\t     srv, &srv->q_a);\n\tif (status != PJ_SUCCESS) {\n\t    query_job->host_resolved++;\n\t    err_cnt++;\n\t    err = status;\n\t}\n    }\n    \n    return (err_cnt == query_job->srv_cnt) ? err : PJ_SUCCESS;\n}\n\n/* \n * This callback is called by PJLIB-UTIL DNS resolver when asynchronous\n * query_job has completed (successfully or with error).\n */\nstatic void dns_callback(void *user_data,\n\t\t\t pj_status_t status,\n\t\t\t pj_dns_parsed_packet *pkt)\n{\n    struct common *common = (struct common*) user_data;\n    pj_dns_srv_async_query *query_job;\n    struct srv_target *srv = NULL;\n    unsigned i;\n\n    if (common->type == PJ_DNS_TYPE_SRV) {\n\tquery_job = (pj_dns_srv_async_query*) common;\n\tsrv = NULL;\n    } else if (common->type == PJ_DNS_TYPE_A) {\n\tsrv = (struct srv_target*) common;\n\tquery_job = srv->parent;\n    } else {\n\tpj_assert(!\"Unexpected user data!\");\n\treturn;\n    }\n\n    /* Proceed to next stage */\n    if (query_job->dns_state == PJ_DNS_TYPE_SRV) {\n\n\t/* We are getting SRV response */\n\n\tquery_job->q_srv = NULL;\n\n\tif (status == PJ_SUCCESS && pkt->hdr.anscount != 0) {\n\t    /* Got SRV response, build server entry. If A records are available\n\t     * in additional records section of the DNS response, save them too.\n\t     */\n\t    build_server_entries(query_job, pkt);\n\n\t} else if (status != PJ_SUCCESS) {\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\n\t    /* Update query_job last error */\n\t    query_job->last_error = status;\n\n\t    pj_strerror(status, errmsg, sizeof(errmsg));\n\t    PJ_LOG(4,(query_job->objname, \n\t\t      \"DNS SRV resolution failed for %.*s: %s\", \n\t\t      (int)query_job->full_name.slen, \n\t\t      query_job->full_name.ptr,\n\t\t      errmsg));\n\n\t    /* Trigger error when fallback is disabled */\n\t    if ((query_job->option &\n\t\t (PJ_DNS_SRV_FALLBACK_A | PJ_DNS_SRV_FALLBACK_AAAA)) == 0) \n\t    {\n\t\tgoto on_error;\n\t    }\n\t}\n\n\t/* If we can't build SRV record, assume the original target is\n\t * an A record and resolve with DNS A resolution.\n\t */\n\tif (query_job->srv_cnt == 0) {\n\t    /* Looks like we aren't getting any SRV responses.\n\t     * Resolve the original target as A record by creating a \n\t     * single \"dummy\" srv record and start the hostname resolution.\n\t     */\n\t    PJ_LOG(4, (query_job->objname, \n\t\t       \"DNS SRV resolution failed for %.*s, trying \"\n\t\t       \"resolving A record for %.*s\",\n\t\t       (int)query_job->full_name.slen, \n\t\t       query_job->full_name.ptr,\n\t\t       (int)query_job->domain_part.slen,\n\t\t       query_job->domain_part.ptr));\n\n\t    /* Create a \"dummy\" srv record using the original target */\n\t    i = query_job->srv_cnt++;\n\t    pj_bzero(&query_job->srv[i], sizeof(query_job->srv[i]));\n\t    query_job->srv[i].target_name = query_job->domain_part;\n\t    query_job->srv[i].priority = 0;\n\t    query_job->srv[i].weight = 0;\n\t    query_job->srv[i].port = query_job->def_port;\n\t} \n\t\n\n\t/* Resolve server hostnames (DNS A record) for hosts which don't have\n\t * A record yet.\n\t */\n\tif (query_job->host_resolved != query_job->srv_cnt) {\n\t    status = resolve_hostnames(query_job);\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_error;\n\n\t    /* Must return now. Callback may have been called and query_job\n\t     * may have been destroyed.\n\t     */\n\t    return;\n\t}\n\n    } else if (query_job->dns_state == PJ_DNS_TYPE_A) {\n\n\t/* Clear the outstanding job */\n\tsrv->q_a = NULL;\n\n\t/* Check that we really have answer */\n\tif (status==PJ_SUCCESS && pkt->hdr.anscount != 0) {\n\t    pj_dns_a_record rec;\n\n\t    /* Parse response */\n\t    status = pj_dns_parse_a_response(pkt, &rec);\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_error;\n\n\t    pj_assert(rec.addr_count != 0);\n\n\t    /* Update CNAME alias, if present. */\n\t    if (rec.alias.slen) {\n\t\tpj_assert(rec.alias.slen <= (int)sizeof(srv->cname_buf));\n\t\tsrv->cname.ptr = srv->cname_buf;\n\t\tpj_strcpy(&srv->cname, &rec.alias);\n\t    } else {\n\t\tsrv->cname.slen = 0;\n\t    }\n\n\t    /* Update IP address of the corresponding hostname or CNAME */\n\t    if (srv->addr_cnt < ADDR_MAX_COUNT) {\n\t\tsrv->addr[srv->addr_cnt++].s_addr = rec.addr[0].s_addr;\n\n\t\tPJ_LOG(5,(query_job->objname, \n\t\t\t  \"DNS A for %.*s: %s\",\n\t\t\t  (int)srv->target_name.slen, \n\t\t\t  srv->target_name.ptr,\n\t\t\t  pj_inet_ntoa(rec.addr[0])));\n\t    }\n\n\t    /* Check for multiple IP addresses */\n\t    for (i=1; i<rec.addr_count && srv->addr_cnt < ADDR_MAX_COUNT; ++i)\n\t    {\n\t\tsrv->addr[srv->addr_cnt++].s_addr = rec.addr[i].s_addr;\n\n\t\tPJ_LOG(5,(query_job->objname, \n\t\t\t  \"Additional DNS A for %.*s: %s\",\n\t\t\t  (int)srv->target_name.slen, \n\t\t\t  srv->target_name.ptr,\n\t\t\t  pj_inet_ntoa(rec.addr[i])));\n\t    }\n\n\t} else if (status != PJ_SUCCESS) {\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\n\t    /* Update last error */\n\t    query_job->last_error = status;\n\n\t    /* Log error */\n\t    pj_strerror(status, errmsg, sizeof(errmsg));\n\t    PJ_LOG(4,(query_job->objname, \"DNS A record resolution failed: %s\", \n\t\t      errmsg));\n\t}\n\n\t++query_job->host_resolved;\n\n    } else {\n\tpj_assert(!\"Unexpected state!\");\n\tquery_job->last_error = status = PJ_EINVALIDOP;\n\tgoto on_error;\n    }\n\n    /* Check if all hosts have been resolved */\n    if (query_job->host_resolved == query_job->srv_cnt) {\n\t/* Got all answers, build server addresses */\n\tpj_dns_srv_record srv_rec;\n\n\tsrv_rec.count = 0;\n\tfor (i=0; i<query_job->srv_cnt; ++i) {\n\t    unsigned j;\n\t    struct srv_target *srv2 = &query_job->srv[i];\n\n\t    srv_rec.entry[srv_rec.count].priority = srv2->priority;\n\t    srv_rec.entry[srv_rec.count].weight = srv2->weight;\n\t    srv_rec.entry[srv_rec.count].port = (pj_uint16_t)srv2->port ;\n\n\t    srv_rec.entry[srv_rec.count].server.name = srv2->target_name;\n\t    srv_rec.entry[srv_rec.count].server.alias = srv2->cname;\n\t    srv_rec.entry[srv_rec.count].server.addr_count = 0;\n\n\t    pj_assert(srv2->addr_cnt <= PJ_DNS_MAX_IP_IN_A_REC);\n\n\t    for (j=0; j<srv2->addr_cnt; ++j) {\n\t\tsrv_rec.entry[srv_rec.count].server.addr[j].s_addr = \n\t\t    srv2->addr[j].s_addr;\n\t\t++srv_rec.entry[srv_rec.count].server.addr_count;\n\t    }\n\n\t    if (srv2->addr_cnt > 0) {\n\t\t++srv_rec.count;\n\t\tif (srv_rec.count == PJ_DNS_SRV_MAX_ADDR)\n\t\t    break;\n\t    }\n\t}\n\n\tPJ_LOG(5,(query_job->objname, \n\t\t  \"Server resolution complete, %d server entry(s) found\",\n\t\t  srv_rec.count));\n\n\n\tif (srv_rec.count > 0)\n\t    status = PJ_SUCCESS;\n\telse {\n\t    status = query_job->last_error;\n\t    if (status == PJ_SUCCESS)\n\t\tstatus = PJLIB_UTIL_EDNSNOANSWERREC;\n\t}\n\n\t/* Call the callback */\n\t(*query_job->cb)(query_job->token, status, &srv_rec);\n    }\n\n\n    return;\n\non_error:\n    /* Check for failure */\n    if (status != PJ_SUCCESS) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\tPJ_UNUSED_ARG(errmsg);\n\tPJ_LOG(4,(query_job->objname, \n\t\t  \"DNS %s record resolution error for '%.*s'.\"\n\t\t  \" Err=%d (%s)\",\n\t\t  pj_dns_get_type_name(query_job->dns_state),\n\t\t  (int)query_job->domain_part.slen,\n\t\t  query_job->domain_part.ptr,\n\t\t  status,\n\t\t  pj_strerror(status,errmsg,sizeof(errmsg)).ptr));\n\t(*query_job->cb)(query_job->token, status, NULL);\n\treturn;\n    }\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/string.c",
    "content": "/* $Id: string.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/string.h>\n#include <pj/ctype.h>\n#include <pj/string.h>\n#include <pj/pool.h>\n\nPJ_DEF(pj_str_t) pj_str_unescape( pj_pool_t *pool, const pj_str_t *src_str)\n{\n    char *src = src_str->ptr;\n    char *end = src + src_str->slen;\n    pj_str_t dst_str;\n    char *dst;\n    \n    if (pj_strchr(src_str, '%')==NULL)\n\treturn *src_str;\n\n    dst = dst_str.ptr = (char*) pj_pool_alloc(pool, src_str->slen);\n\n    while (src != end) {\n\tif (*src == '%' && src < end-2 && pj_isxdigit(*(src+1)) && \n\t    pj_isxdigit(*(src+2))) \n\t{\n\t    *dst = (pj_uint8_t) ((pj_hex_digit_to_val(*(src+1)) << 4) + \n\t\t\t\t pj_hex_digit_to_val(*(src+2)));\n\t    ++dst;\n\t    src += 3;\n\t} else {\n\t    *dst++ = *src++;\n\t}\n    }\n    dst_str.slen = dst - dst_str.ptr;\n    return dst_str;\n}\n\nPJ_DEF(pj_str_t*) pj_strcpy_unescape(pj_str_t *dst_str,\n\t\t\t\t     const pj_str_t *src_str)\n{\n    const char *src = src_str->ptr;\n    const char *end = src + src_str->slen;\n    char *dst = dst_str->ptr;\n    \n    while (src != end) {\n\tif (*src == '%' && src < end-2) {\n\t    *dst = (pj_uint8_t) ((pj_hex_digit_to_val(*(src+1)) << 4) + \n\t\t\t\t pj_hex_digit_to_val(*(src+2)));\n\t    ++dst;\n\t    src += 3;\n\t} else {\n\t    *dst++ = *src++;\n\t}\n    }\n    dst_str->slen = dst - dst_str->ptr;\n    return dst_str;\n}\n\nPJ_DEF(pj_ssize_t) pj_strncpy2_escape( char *dst_str, const pj_str_t *src_str,\n\t\t\t\t       pj_ssize_t max, const pj_cis_t *unres)\n{\n    const char *src = src_str->ptr;\n    const char *src_end = src + src_str->slen;\n    char *dst = dst_str;\n    char *dst_end = dst + max;\n\n    if (max < src_str->slen)\n\treturn -1;\n\n    while (src != src_end && dst != dst_end) {\n\tif (pj_cis_match(unres, *src)) {\n\t    *dst++ = *src++;\n\t} else {\n\t    if (dst < dst_end-2) {\n\t\t*dst++ = '%';\n\t\tpj_val_to_hex_digit(*src, dst);\n\t\tdst+=2;\n\t\t++src;\n\t    } else {\n\t\tbreak;\n\t    }\n\t}\n    }\n\n    return src==src_end ? dst-dst_str : -1;\n}\n\nPJ_DEF(pj_str_t*) pj_strncpy_escape(pj_str_t *dst_str, \n\t\t\t\t    const pj_str_t *src_str,\n\t\t\t\t    pj_ssize_t max, const pj_cis_t *unres)\n{\n    dst_str->slen = pj_strncpy2_escape(dst_str->ptr, src_str, max, unres);\n    return dst_str->slen < 0 ? NULL : dst_str;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/stun_simple.c",
    "content": "/* $Id: stun_simple.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/stun_simple.h>\n#include <pjlib-util/errno.h>\n#include <pj/pool.h>\n#include <pj/log.h>\n#include <pj/sock.h>\n#include <pj/os.h>\n\n#define THIS_FILE   \"stun_simple.c\"\n\nPJ_DEF(pj_status_t) pjstun_create_bind_req( pj_pool_t *pool, \n\t\t\t\t\t     void **msg, pj_size_t *len,\n\t\t\t\t\t     pj_uint32_t id_hi, \n\t\t\t\t\t     pj_uint32_t id_lo)\n{\n    pjstun_msg_hdr *hdr;\n    \n    PJ_CHECK_STACK();\n\n\n    hdr = PJ_POOL_ZALLOC_T(pool, pjstun_msg_hdr);\n    if (!hdr)\n\treturn PJ_ENOMEM;\n\n    hdr->type = pj_htons(PJSTUN_BINDING_REQUEST);\n    hdr->tsx[2] = pj_htonl(id_hi);\n    hdr->tsx[3] = pj_htonl(id_lo);\n    *msg = hdr;\n    *len = sizeof(pjstun_msg_hdr);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjstun_parse_msg( void *buf, pj_size_t buf_len, \n\t\t\t\t      pjstun_msg *msg)\n{\n    pj_uint16_t msg_type, msg_len;\n    char *p_attr;\n\n    PJ_CHECK_STACK();\n\n    msg->hdr = (pjstun_msg_hdr*)buf;\n    msg_type = pj_ntohs(msg->hdr->type);\n\n    switch (msg_type) {\n    case PJSTUN_BINDING_REQUEST:\n    case PJSTUN_BINDING_RESPONSE:\n    case PJSTUN_BINDING_ERROR_RESPONSE:\n    case PJSTUN_SHARED_SECRET_REQUEST:\n    case PJSTUN_SHARED_SECRET_RESPONSE:\n    case PJSTUN_SHARED_SECRET_ERROR_RESPONSE:\n\tbreak;\n    default:\n\tPJ_LOG(4,(THIS_FILE, \"Error: unknown msg type %d\", msg_type));\n\treturn PJLIB_UTIL_ESTUNINMSGTYPE;\n    }\n\n    msg_len = pj_ntohs(msg->hdr->length);\n    if (msg_len != buf_len - sizeof(pjstun_msg_hdr)) {\n\tPJ_LOG(4,(THIS_FILE, \"Error: invalid msg_len %d (expecting %d)\", \n\t\t\t     msg_len, buf_len - sizeof(pjstun_msg_hdr)));\n\treturn PJLIB_UTIL_ESTUNINMSGLEN;\n    }\n\n    msg->attr_count = 0;\n    p_attr = (char*)buf + sizeof(pjstun_msg_hdr);\n\n    while (msg_len > 0) {\n\tpjstun_attr_hdr **attr = &msg->attr[msg->attr_count];\n\tpj_uint32_t len;\n\tpj_uint16_t attr_type;\n\n\t*attr = (pjstun_attr_hdr*)p_attr;\n\tlen = pj_ntohs((pj_uint16_t) ((*attr)->length)) + sizeof(pjstun_attr_hdr);\n\tlen = (len + 3) & ~3;\n\n\tif (msg_len < len) {\n\t    PJ_LOG(4,(THIS_FILE, \"Error: length mismatch in attr %d\", \n\t\t\t\t msg->attr_count));\n\t    return PJLIB_UTIL_ESTUNINATTRLEN;\n\t}\n\n\tattr_type = pj_ntohs((*attr)->type);\n\tif (attr_type > PJSTUN_ATTR_REFLECTED_FROM &&\n\t    attr_type != PJSTUN_ATTR_XOR_MAPPED_ADDR)\n\t{\n\t    PJ_LOG(5,(THIS_FILE, \"Warning: unknown attr type %x in attr %d. \"\n\t\t\t\t \"Attribute was ignored.\",\n\t\t\t\t attr_type, msg->attr_count));\n\t}\n\n\tmsg_len = (pj_uint16_t)(msg_len - len);\n\tp_attr += len;\n\t++msg->attr_count;\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void*) pjstun_msg_find_attr( pjstun_msg *msg, pjstun_attr_type t)\n{\n    int i;\n\n    PJ_CHECK_STACK();\n\n    for (i=0; i<msg->attr_count; ++i) {\n\tpjstun_attr_hdr *attr = msg->attr[i];\n\tif (pj_ntohs(attr->type) == t)\n\t    return attr;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/stun_simple_client.c",
    "content": "/* $Id: stun_simple_client.c 4297 2012-11-13 08:46:42Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/stun_simple.h>\n#include <pjlib-util/errno.h>\n#include <pj/compat/socket.h> \n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/sock_select.h>\n#include <pj/string.h>\n\n\nenum { MAX_REQUEST = 4 };\nstatic int stun_timer[] = {500, 500, 500, 500 };\n#define STUN_MAGIC 0x2112A442\n\n#define THIS_FILE\t\"stun_client.c\"\n#define LOG_ADDR(addr)\tpj_inet_ntoa(addr.sin_addr), pj_ntohs(addr.sin_port)\n\n#define TRACE_(x)\tPJ_LOG(6,x)\n\nPJ_DEF(pj_status_t) pjstun_get_mapped_addr( pj_pool_factory *pf,\n\t\t\t\t\t    int sock_cnt, pj_sock_t sock[],\n\t\t\t\t\t    const pj_str_t *srv1, int port1,\n\t\t\t\t\t    const pj_str_t *srv2, int port2,\n\t\t\t\t\t    pj_sockaddr_in mapped_addr[])\n{\n    pjstun_setting opt;\n\n    pj_bzero(&opt, sizeof(opt));\n    opt.use_stun2 = PJ_FALSE;\n    opt.srv1 = *srv1;\n    opt.port1 = port1;\n    opt.srv2 = *srv2;\n    opt.port2 = port2;\n\n    return pjstun_get_mapped_addr2(pf, &opt, sock_cnt, sock, mapped_addr);\n}\n\nPJ_DEF(pj_status_t) pjstun_get_mapped_addr2(pj_pool_factory *pf,\n\t\t\t\t\t    const pjstun_setting *opt,\n\t\t\t\t\t    int sock_cnt,\n\t\t\t\t\t    pj_sock_t sock[],\n\t\t\t\t\t    pj_sockaddr_in mapped_addr[])\n{\n    unsigned srv_cnt;\n    const pj_str_t *srv1, *srv2;\n    int port1, port2;\n    pj_sockaddr_in srv_addr[2];\n    int i, send_cnt = 0, nfds;\n    pj_pool_t *pool;\n    struct query_rec {\n\tstruct {\n\t    pj_uint32_t\tmapped_addr;\n\t    pj_uint32_t\tmapped_port;\n\t} srv[2];\n    } *rec;\n    void       *out_msg;\n    pj_size_t\tout_msg_len;\n    int wait_resp = 0;\n    pj_status_t status;\n\n    PJ_CHECK_STACK();\n\n    srv1 = &opt->srv1;\n    port1 = opt->port1;\n    srv2 = &opt->srv1;\n    port2 = opt->port2;\n\n    TRACE_((THIS_FILE, \"Entering pjstun_get_mapped_addr()\"));\n\n    /* Create pool. */\n    pool = pj_pool_create(pf, \"stun%p\", 400, 400, NULL);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n\n    /* Allocate client records */\n    rec = (struct query_rec*) pj_pool_calloc(pool, sock_cnt, sizeof(*rec));\n    if (!rec) {\n\tstatus = PJ_ENOMEM;\n\tgoto on_error;\n    }\n\n    TRACE_((THIS_FILE, \"  Memory allocated.\"));\n\n    /* Create the outgoing BIND REQUEST message template */\n    status = pjstun_create_bind_req( pool, &out_msg, &out_msg_len, \n\t\t\t\t      pj_rand(), pj_rand());\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Insert magic cookie (specified in RFC 5389) when requested to. */\n    if (opt->use_stun2) {\n\tpjstun_msg_hdr *hdr = (pjstun_msg_hdr*)out_msg;\n\thdr->tsx[0] = pj_htonl(STUN_MAGIC);\n    }\n\n    TRACE_((THIS_FILE, \"  Binding request created.\"));\n\n    /* Resolve servers. */\n    status = pj_sockaddr_in_init(&srv_addr[0], srv1, (pj_uint16_t)port1);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    srv_cnt = 1;\n\n    if (srv2 && port2) {\n\tstatus = pj_sockaddr_in_init(&srv_addr[1], srv2, (pj_uint16_t)port2);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n\tif (srv_addr[1].sin_addr.s_addr != srv_addr[0].sin_addr.s_addr &&\n\t    srv_addr[1].sin_port != srv_addr[0].sin_port)\n\t{\n\t    srv_cnt++;\n\t}\n    }\n\n    TRACE_((THIS_FILE, \"  Server initialized, using %d server(s)\", srv_cnt));\n\n    /* Init mapped addresses to zero */\n    pj_memset(mapped_addr, 0, sock_cnt * sizeof(pj_sockaddr_in));\n\n    /* We need these many responses */\n    wait_resp = sock_cnt * srv_cnt;\n\n    TRACE_((THIS_FILE, \"  Done initialization.\"));\n\n#if defined(PJ_SELECT_NEEDS_NFDS) && PJ_SELECT_NEEDS_NFDS!=0\n    nfds = -1;\n    for (i=0; i<sock_cnt; ++i) {\n\tif (sock[i] > nfds) {\n\t    nfds = sock[i];\n\t}\n    }\n#else\n    nfds = FD_SETSIZE-1;\n#endif\n\n    /* Main retransmission loop. */\n    for (send_cnt=0; send_cnt<MAX_REQUEST; ++send_cnt) {\n\tpj_time_val next_tx, now;\n\tpj_fd_set_t r;\n\tint select_rc;\n\n\tPJ_FD_ZERO(&r);\n\n\t/* Send messages to servers that has not given us response. */\n\tfor (i=0; i<sock_cnt && status==PJ_SUCCESS; ++i) {\n\t    unsigned j;\n\t    for (j=0; j<srv_cnt && status==PJ_SUCCESS; ++j) {\n\t\tpjstun_msg_hdr *msg_hdr = (pjstun_msg_hdr*) out_msg;\n                pj_ssize_t sent_len;\n\n\t\tif (rec[i].srv[j].mapped_port != 0)\n\t\t    continue;\n\n\t\t/* Modify message so that we can distinguish response. */\n\t\tmsg_hdr->tsx[2] = pj_htonl(i);\n\t\tmsg_hdr->tsx[3] = pj_htonl(j);\n\n\t\t/* Send! */\n                sent_len = out_msg_len;\n\t\tstatus = pj_sock_sendto(sock[i], out_msg, &sent_len, 0,\n\t\t\t\t\t(pj_sockaddr_t*)&srv_addr[j],\n\t\t\t\t\tsizeof(pj_sockaddr_in));\n\t    }\n\t}\n\n\t/* All requests sent.\n\t * The loop below will wait for responses until all responses have\n\t * been received (i.e. wait_resp==0) or timeout occurs, which then\n\t * we'll go to the next retransmission iteration.\n\t */\n\tTRACE_((THIS_FILE, \"  Request(s) sent, counter=%d\", send_cnt));\n\n\t/* Calculate time of next retransmission. */\n\tpj_gettickcount(&next_tx);\n\tnext_tx.sec += (stun_timer[send_cnt]/1000);\n\tnext_tx.msec += (stun_timer[send_cnt]%1000);\n\tpj_time_val_normalize(&next_tx);\n\n\tfor (pj_gettickcount(&now), select_rc=1;\n\t     status==PJ_SUCCESS && select_rc>=1 && wait_resp>0 \n\t       && PJ_TIME_VAL_LT(now, next_tx); \n\t     pj_gettickcount(&now))\n\t{\n\t    pj_time_val timeout;\n\n\t    timeout = next_tx;\n\t    PJ_TIME_VAL_SUB(timeout, now);\n\n\t    for (i=0; i<sock_cnt; ++i) {\n\t\tPJ_FD_SET(sock[i], &r);\n\t    }\n\n\t    select_rc = pj_sock_select(nfds+1, &r, NULL, NULL, &timeout);\n\t    TRACE_((THIS_FILE, \"  select() rc=%d\", select_rc));\n\t    if (select_rc < 1)\n\t\tcontinue;\n\n\t    for (i=0; i<sock_cnt; ++i) {\n\t\tint sock_idx, srv_idx;\n                pj_ssize_t len;\n\t\tpjstun_msg msg;\n\t\tpj_sockaddr_in addr;\n\t\tint addrlen = sizeof(addr);\n\t\tpjstun_mapped_addr_attr *attr;\n\t\tchar recv_buf[128];\n\n\t\tif (!PJ_FD_ISSET(sock[i], &r))\n\t\t    continue;\n\n                len = sizeof(recv_buf);\n\t\tstatus = pj_sock_recvfrom( sock[i], recv_buf, \n\t\t\t\t           &len, 0,\n\t\t\t\t           (pj_sockaddr_t*)&addr,\n\t\t\t\t\t   &addrlen);\n\n\t\tif (status != PJ_SUCCESS) {\n\t\t    char errmsg[PJ_ERR_MSG_SIZE];\n\n\t\t    PJ_LOG(4,(THIS_FILE, \"recvfrom() error ignored: %s\",\n\t\t\t      pj_strerror(status, errmsg,sizeof(errmsg)).ptr));\n\n\t\t    /* Ignore non-PJ_SUCCESS status.\n\t\t     * It possible that other SIP entity is currently \n\t\t     * sending SIP request to us, and because SIP message\n\t\t     * is larger than STUN, we could get EMSGSIZE when\n\t\t     * we call recvfrom().\n\t\t     */\n\t\t    status = PJ_SUCCESS;\n\t\t    continue;\n\t\t}\n\n\t\tstatus = pjstun_parse_msg(recv_buf, len, &msg);\n\t\tif (status != PJ_SUCCESS) {\n\t\t    char errmsg[PJ_ERR_MSG_SIZE];\n\n\t\t    PJ_LOG(4,(THIS_FILE, \"STUN parsing error ignored: %s\",\n\t\t\t      pj_strerror(status, errmsg,sizeof(errmsg)).ptr));\n\n\t\t    /* Also ignore non-successful parsing. This may not\n\t\t     * be STUN response at all. See the comment above.\n\t\t     */\n\t\t    status = PJ_SUCCESS;\n\t\t    continue;\n\t\t}\n\n\t\tsock_idx = pj_ntohl(msg.hdr->tsx[2]);\n\t\tsrv_idx = pj_ntohl(msg.hdr->tsx[3]);\n\n\t\tif (sock_idx<0 || sock_idx>=sock_cnt || sock_idx!=i ||\n\t\t\tsrv_idx<0 || srv_idx>=2)\n\t\t{\n\t\t    status = PJLIB_UTIL_ESTUNININDEX;\n\t\t    continue;\n\t\t}\n\n\t\tif (pj_ntohs(msg.hdr->type) != PJSTUN_BINDING_RESPONSE) {\n\t\t    status = PJLIB_UTIL_ESTUNNOBINDRES;\n\t\t    continue;\n\t\t}\n\n\t\tif (rec[sock_idx].srv[srv_idx].mapped_port != 0) {\n\t\t    /* Already got response */\n\t\t    continue;\n\t\t}\n\n\t\t/* From this part, we consider the packet as a valid STUN\n\t\t * response for our request.\n\t\t */\n\t\t--wait_resp;\n\n\t\tif (pjstun_msg_find_attr(&msg, PJSTUN_ATTR_ERROR_CODE) != NULL) {\n\t\t    status = PJLIB_UTIL_ESTUNRECVERRATTR;\n\t\t    continue;\n\t\t}\n\n\t\tattr = (pjstun_mapped_addr_attr*) \n\t\t       pjstun_msg_find_attr(&msg, PJSTUN_ATTR_MAPPED_ADDR);\n\t\tif (!attr) {\n\t\t    attr = (pjstun_mapped_addr_attr*) \n\t\t\t   pjstun_msg_find_attr(&msg, PJSTUN_ATTR_XOR_MAPPED_ADDR);\n\t\t    if (!attr || attr->family != 1) {\n\t\t\tstatus = PJLIB_UTIL_ESTUNNOMAP;\n\t\t\tcontinue;\n\t\t    }\n\t\t}\n\n\t\trec[sock_idx].srv[srv_idx].mapped_addr = attr->addr;\n\t\trec[sock_idx].srv[srv_idx].mapped_port = attr->port;\n\t\tif (pj_ntohs(attr->hdr.type) == PJSTUN_ATTR_XOR_MAPPED_ADDR) {\n\t\t    rec[sock_idx].srv[srv_idx].mapped_addr ^= pj_htonl(STUN_MAGIC);\n\t\t    rec[sock_idx].srv[srv_idx].mapped_port ^= pj_htons(STUN_MAGIC >> 16);\n\t\t}\n\t    }\n\t}\n\n\t/* The best scenario is if all requests have been replied.\n\t * Then we don't need to go to the next retransmission iteration.\n\t */\n\tif (wait_resp <= 0)\n\t    break;\n    }\n\n    TRACE_((THIS_FILE, \"  All responses received, calculating result..\"));\n\n    for (i=0; i<sock_cnt && status==PJ_SUCCESS; ++i) {\n\tif (srv_cnt == 1) {\n\t    mapped_addr[i].sin_family = pj_AF_INET();\n\t    mapped_addr[i].sin_addr.s_addr = rec[i].srv[0].mapped_addr;\n\t    mapped_addr[i].sin_port = (pj_uint16_t)rec[i].srv[0].mapped_port;\n\n\t    if (rec[i].srv[0].mapped_addr == 0 || rec[i].srv[0].mapped_port == 0) {\n\t\tstatus = PJLIB_UTIL_ESTUNNOTRESPOND;\n\t\tbreak;\n\t    }\n\t} else if (rec[i].srv[0].mapped_addr == rec[i].srv[1].mapped_addr &&\n\t           rec[i].srv[0].mapped_port == rec[i].srv[1].mapped_port)\n\t{\n\t    mapped_addr[i].sin_family = pj_AF_INET();\n\t    mapped_addr[i].sin_addr.s_addr = rec[i].srv[0].mapped_addr;\n\t    mapped_addr[i].sin_port = (pj_uint16_t)rec[i].srv[0].mapped_port;\n\n\t    if (rec[i].srv[0].mapped_addr == 0 || rec[i].srv[0].mapped_port == 0) {\n\t\tstatus = PJLIB_UTIL_ESTUNNOTRESPOND;\n\t\tbreak;\n\t    }\n\t} else {\n\t    status = PJLIB_UTIL_ESTUNSYMMETRIC;\n\t    break;\n\t}\n    }\n\n    TRACE_((THIS_FILE, \"  Pool usage=%d of %d\", pj_pool_get_used_size(pool),\n\t    pj_pool_get_capacity(pool)));\n\n    pj_pool_release(pool);\n\n    TRACE_((THIS_FILE, \"  Done.\"));\n    return status;\n\non_error:\n    if (pool) pj_pool_release(pool);\n    return status;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/symbols.c",
    "content": "/* $Id: symbols.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib.h>\n#include <pjlib-util.h>\n\n/*\n * md5.h\n */\nPJ_EXPORT_SYMBOL(md5_init)\nPJ_EXPORT_SYMBOL(md5_append)\nPJ_EXPORT_SYMBOL(md5_finish)\n\n/*\n * scanner.h\n */\nPJ_EXPORT_SYMBOL(pj_cs_init)\nPJ_EXPORT_SYMBOL(pj_cs_set)\nPJ_EXPORT_SYMBOL(pj_cs_add_range)\nPJ_EXPORT_SYMBOL(pj_cs_add_alpha)\nPJ_EXPORT_SYMBOL(pj_cs_add_num)\nPJ_EXPORT_SYMBOL(pj_cs_add_str)\nPJ_EXPORT_SYMBOL(pj_cs_del_range)\nPJ_EXPORT_SYMBOL(pj_cs_del_str)\nPJ_EXPORT_SYMBOL(pj_cs_invert)\nPJ_EXPORT_SYMBOL(pj_scan_init)\nPJ_EXPORT_SYMBOL(pj_scan_fini)\nPJ_EXPORT_SYMBOL(pj_scan_peek)\nPJ_EXPORT_SYMBOL(pj_scan_peek_n)\nPJ_EXPORT_SYMBOL(pj_scan_peek_until)\nPJ_EXPORT_SYMBOL(pj_scan_get)\nPJ_EXPORT_SYMBOL(pj_scan_get_quote)\nPJ_EXPORT_SYMBOL(pj_scan_get_n)\nPJ_EXPORT_SYMBOL(pj_scan_get_char)\nPJ_EXPORT_SYMBOL(pj_scan_get_newline)\nPJ_EXPORT_SYMBOL(pj_scan_get_until)\nPJ_EXPORT_SYMBOL(pj_scan_get_until_ch)\nPJ_EXPORT_SYMBOL(pj_scan_get_until_chr)\nPJ_EXPORT_SYMBOL(pj_scan_advance_n)\nPJ_EXPORT_SYMBOL(pj_scan_strcmp)\nPJ_EXPORT_SYMBOL(pj_scan_stricmp)\nPJ_EXPORT_SYMBOL(pj_scan_skip_whitespace)\nPJ_EXPORT_SYMBOL(pj_scan_save_state)\nPJ_EXPORT_SYMBOL(pj_scan_restore_state)\n\n/*\n * stun.h\n */\nPJ_EXPORT_SYMBOL(pj_stun_create_bind_req)\nPJ_EXPORT_SYMBOL(pj_stun_parse_msg)\nPJ_EXPORT_SYMBOL(pj_stun_msg_find_attr)\nPJ_EXPORT_SYMBOL(pj_stun_get_mapped_addr)\nPJ_EXPORT_SYMBOL(pj_stun_get_err_msg)\n\n/*\n * xml.h\n */\nPJ_EXPORT_SYMBOL(pj_xml_parse)\nPJ_EXPORT_SYMBOL(pj_xml_print)\nPJ_EXPORT_SYMBOL(pj_xml_add_node)\nPJ_EXPORT_SYMBOL(pj_xml_add_attr)\nPJ_EXPORT_SYMBOL(pj_xml_find_node)\nPJ_EXPORT_SYMBOL(pj_xml_find_next_node)\nPJ_EXPORT_SYMBOL(pj_xml_find_attr)\nPJ_EXPORT_SYMBOL(pj_xml_find)\n\n\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/xml.c",
    "content": "/* $Id: xml.c 3999 2012-03-30 07:10:13Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjlib-util/xml.h>\n#include <pjlib-util/scanner.h>\n#include <pj/except.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/log.h>\n#include <pj/os.h>\n\n#define EX_SYNTAX_ERROR\t12\n#define THIS_FILE\t\"xml.c\"\n\nstatic void on_syntax_error(struct pj_scanner *scanner)\n{\n    PJ_UNUSED_ARG(scanner);\n    PJ_THROW(EX_SYNTAX_ERROR);\n}\n\nstatic pj_xml_node *alloc_node( pj_pool_t *pool )\n{\n    pj_xml_node *node;\n\n    node = PJ_POOL_ZALLOC_T(pool, pj_xml_node);\n    pj_list_init( &node->attr_head );\n    pj_list_init( &node->node_head );\n\n    return node;\n}\n\nstatic pj_xml_attr *alloc_attr( pj_pool_t *pool )\n{\n    return PJ_POOL_ZALLOC_T(pool, pj_xml_attr);\n}\n\n/* This is a recursive function! */\nstatic pj_xml_node *xml_parse_node( pj_pool_t *pool, pj_scanner *scanner)\n{\n    pj_xml_node *node;\n    pj_str_t end_name;\n\n    PJ_CHECK_STACK();\n\n    if (*scanner->curptr != '<')\n\ton_syntax_error(scanner);\n\n    /* Handle Processing Instructino (PI) construct (i.e. \"<?\") */\n    if (*scanner->curptr == '<' && *(scanner->curptr+1) == '?') {\n\tpj_scan_advance_n(scanner, 2, PJ_FALSE);\n\tfor (;;) {\n\t    pj_str_t dummy;\n\t    pj_scan_get_until_ch(scanner, '?', &dummy);\n\t    if (*scanner->curptr=='?' && *(scanner->curptr+1)=='>') {\n\t\tpj_scan_advance_n(scanner, 2, PJ_TRUE);\n\t\tbreak;\n\t    } else {\n\t\tpj_scan_advance_n(scanner, 1, PJ_FALSE);\n\t    }\n\t}\n\treturn xml_parse_node(pool, scanner);\n    }\n\n    /* Handle comments construct (i.e. \"<!\") */\n    if (pj_scan_strcmp(scanner, \"<!\", 2) == 0) {\n\tpj_scan_advance_n(scanner, 2, PJ_FALSE);\n\tfor (;;) {\n\t    pj_str_t dummy;\n\t    pj_scan_get_until_ch(scanner, '>', &dummy);\n\t    if (pj_scan_strcmp(scanner, \">\", 1) == 0) {\n\t\tpj_scan_advance_n(scanner, 1, PJ_TRUE);\n\t\tbreak;\n\t    } else {\n\t\tpj_scan_advance_n(scanner, 1, PJ_FALSE);\n\t    }\n\t}\n\treturn xml_parse_node(pool, scanner);\n    }\n\n    /* Alloc node. */\n    node = alloc_node(pool);\n\n    /* Get '<' */\n    pj_scan_get_char(scanner);\n\n    /* Get node name. */\n    pj_scan_get_until_chr( scanner, \" />\\t\\r\\n\", &node->name);\n\n    /* Get attributes. */\n    while (*scanner->curptr != '>' && *scanner->curptr != '/') {\n\tpj_xml_attr *attr = alloc_attr(pool);\n\t\n\tpj_scan_get_until_chr( scanner, \"=> \\t\\r\\n\", &attr->name);\n\tif (*scanner->curptr == '=') {\n\t    pj_scan_get_char( scanner );\n            pj_scan_get_quotes(scanner, \"\\\"'\", \"\\\"'\", 2, &attr->value);\n\t    /* remove quote characters */\n\t    ++attr->value.ptr;\n\t    attr->value.slen -= 2;\n\t}\n\t\n\tpj_list_push_back( &node->attr_head, attr );\n    }\n\n    if (*scanner->curptr == '/') {\n\tpj_scan_get_char(scanner);\n\tif (pj_scan_get_char(scanner) != '>')\n\t    on_syntax_error(scanner);\n\treturn node;\n    }\n\n    /* Enclosing bracket. */\n    if (pj_scan_get_char(scanner) != '>')\n\ton_syntax_error(scanner);\n\n    /* Sub nodes. */\n    while (*scanner->curptr == '<' && *(scanner->curptr+1) != '/'\n\t\t\t\t   && *(scanner->curptr+1) != '!')\n    {\n\tpj_xml_node *sub_node = xml_parse_node(pool, scanner);\n\tpj_list_push_back( &node->node_head, sub_node );\n    }\n\n    /* Content. */\n    if (!pj_scan_is_eof(scanner) && *scanner->curptr != '<') {\n\tpj_scan_get_until_ch(scanner, '<', &node->content);\n    }\n\n    /* CDATA content. */\n    if (*scanner->curptr == '<' && *(scanner->curptr+1) == '!' &&\n\tpj_scan_strcmp(scanner, \"<![CDATA[\", 9) == 0)\n    {\n\tpj_scan_advance_n(scanner, 9, PJ_FALSE);\n\tpj_scan_get_until_ch(scanner, ']', &node->content);\n\twhile (pj_scan_strcmp(scanner, \"]]>\", 3)) {\n\t    pj_str_t dummy;\n\t    pj_scan_get_until_ch(scanner, ']', &dummy);\n\t}\n\tnode->content.slen = scanner->curptr - node->content.ptr;\n\tpj_scan_advance_n(scanner, 3, PJ_TRUE);\n    }\n\n    /* Enclosing node. */\n    if (pj_scan_get_char(scanner) != '<' || pj_scan_get_char(scanner) != '/')\n\ton_syntax_error(scanner);\n\n    pj_scan_get_until_chr(scanner, \" \\t>\", &end_name);\n\n    /* Compare name. */\n    if (pj_stricmp(&node->name, &end_name) != 0)\n\ton_syntax_error(scanner);\n\n    /* Enclosing '>' */\n    if (pj_scan_get_char(scanner) != '>')\n\ton_syntax_error(scanner);\n\n    return node;\n}\n\nPJ_DEF(pj_xml_node*) pj_xml_parse( pj_pool_t *pool, char *msg, pj_size_t len)\n{\n    pj_xml_node *node = NULL;\n    pj_scanner scanner;\n    PJ_USE_EXCEPTION;\n\n    if (!msg || !len || !pool)\n\treturn NULL;\n\n    pj_scan_init( &scanner, msg, len, \n\t\t  PJ_SCAN_AUTOSKIP_WS|PJ_SCAN_AUTOSKIP_NEWLINE, \n\t\t  &on_syntax_error);\n    PJ_TRY {\n\tnode =  xml_parse_node(pool, &scanner);\n    }\n    PJ_CATCH_ANY {\n\tPJ_LOG(4,(THIS_FILE, \"Syntax error parsing XML in line %d column %d\",\n\t\t  scanner.line, pj_scan_get_col(&scanner)));\n    }\n    PJ_END;\n    pj_scan_fini( &scanner );\n    return node;\n}\n\n/* This is a recursive function. */\nstatic int xml_print_node( const pj_xml_node *node, int indent, \n\t\t\t   char *buf, pj_size_t len )\n{\n    int i;\n    char *p = buf;\n    pj_xml_attr *attr;\n    pj_xml_node *sub_node;\n\n#define SIZE_LEFT()\t((int)(len - (p-buf)))\n\n    PJ_CHECK_STACK();\n\n    /* Print name. */\n    if (SIZE_LEFT() < node->name.slen + indent + 5)\n\treturn -1;\n    for (i=0; i<indent; ++i)\n\t*p++ = ' ';\n    *p++ = '<';\n    pj_memcpy(p, node->name.ptr, node->name.slen);\n    p += node->name.slen;\n\n    /* Print attributes. */\n    attr = node->attr_head.next;\n    while (attr != &node->attr_head) {\n\n\tif (SIZE_LEFT() < attr->name.slen + attr->value.slen + 4)\n\t    return -1;\n\n\t*p++ = ' ';\n\n\t/* Attribute name. */\n\tpj_memcpy(p, attr->name.ptr, attr->name.slen);\n\tp += attr->name.slen;\n\n\t/* Attribute value. */\n\tif (attr->value.slen) {\n\t    *p++ = '=';\n\t    *p++ = '\"';\n\t    pj_memcpy(p, attr->value.ptr, attr->value.slen);\n\t    p += attr->value.slen;\n\t    *p++ = '\"';\n\t}\n\n\tattr = attr->next;\n    }\n\n    /* Check for empty node. */\n    if (node->content.slen==0 &&\n\tnode->node_head.next==(pj_xml_node*)&node->node_head)\n    {\n\t*p++ = ' ';\n\t*p++ = '/';\n\t*p++ = '>';\n\treturn (int)(p-buf);\n    }\n\n    /* Enclosing '>' */\n    if (SIZE_LEFT() < 1) return -1;\n    *p++ = '>';\n\n    /* Print sub nodes. */\n    sub_node = node->node_head.next;\n    while (sub_node != (pj_xml_node*)&node->node_head) {\n\tint printed;\n\n\tif (SIZE_LEFT() < indent + 3)\n\t    return -1;\n\t//*p++ = '\\r';\n\t*p++ = '\\n';\n\n\tprinted = xml_print_node(sub_node, indent + 1, p, SIZE_LEFT());\n\tif (printed < 0)\n\t    return -1;\n\n\tp += printed;\n\tsub_node = sub_node->next;\n    }\n\n    /* Content. */\n    if (node->content.slen) {\n\tif (SIZE_LEFT() < node->content.slen) return -1;\n\tpj_memcpy(p, node->content.ptr, node->content.slen);\n\tp += node->content.slen;\n    }\n\n    /* Enclosing node. */\n    if (node->node_head.next != (pj_xml_node*)&node->node_head) {\n\tif (SIZE_LEFT() < node->name.slen + 5 + indent)\n\t    return -1;\n\t//*p++ = '\\r';\n\t*p++ = '\\n';\n\tfor (i=0; i<indent; ++i)\n\t    *p++ = ' ';\n    } else {\n\tif (SIZE_LEFT() < node->name.slen + 3)\n\t    return -1;\n    }\n    *p++ = '<';\n    *p++ = '/';\n    pj_memcpy(p, node->name.ptr, node->name.slen);\n    p += node->name.slen;\n    *p++ = '>';\n\n#undef SIZE_LEFT\n\n    return (int)(p-buf);\n}\n\nPJ_DEF(int) pj_xml_print(const pj_xml_node *node, char *buf, pj_size_t len,\n\t\t\t pj_bool_t include_prolog)\n{\n    int prolog_len = 0;\n    int printed;\n\n    if (!node || !buf || !len)\n\treturn 0;\n\n    if (include_prolog) {\n\tpj_str_t prolog = {\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\", 39};\n\tif ((int)len < prolog.slen)\n\t    return -1;\n\tpj_memcpy(buf, prolog.ptr, prolog.slen);\n\tprolog_len = (int)prolog.slen;\n    }\n\n    printed = xml_print_node(node, 0, buf+prolog_len, len-prolog_len) + prolog_len;\n    if (printed > 0 && len-printed >= 1) {\n\tbuf[printed++] = '\\n';\n    }\n    return printed;\n}\n\nPJ_DEF(pj_xml_node*) pj_xml_node_new(pj_pool_t *pool, const pj_str_t *name)\n{\n    pj_xml_node *node = alloc_node(pool);\n    pj_strdup(pool, &node->name, name);\n    return node;\n}\n\nPJ_DEF(pj_xml_attr*) pj_xml_attr_new( pj_pool_t *pool, const pj_str_t *name,\n\t\t\t\t      const pj_str_t *value)\n{\n    pj_xml_attr *attr = alloc_attr(pool);\n    pj_strdup( pool, &attr->name, name);\n    pj_strdup( pool, &attr->value, value);\n    return attr;\n}\n\nPJ_DEF(void) pj_xml_add_node( pj_xml_node *parent, pj_xml_node *node )\n{\n    pj_list_push_back(&parent->node_head, node);\n}\n\nPJ_DEF(void) pj_xml_add_attr( pj_xml_node *node, pj_xml_attr *attr )\n{\n    pj_list_push_back(&node->attr_head, attr);\n}\n\nPJ_DEF(pj_xml_node*) pj_xml_find_node(const pj_xml_node *parent, \n\t\t\t\t      const pj_str_t *name)\n{\n    const pj_xml_node *node = parent->node_head.next;\n\n    PJ_CHECK_STACK();\n\n    while (node != (void*)&parent->node_head) {\n\tif (pj_stricmp(&node->name, name) == 0)\n\t    return (pj_xml_node*)node;\n\tnode = node->next;\n    }\n    return NULL;\n}\n\nPJ_DEF(pj_xml_node*) pj_xml_find_node_rec(const pj_xml_node *parent, \n\t\t\t\t\t  const pj_str_t *name)\n{\n    const pj_xml_node *node = parent->node_head.next;\n\n    PJ_CHECK_STACK();\n\n    while (node != (void*)&parent->node_head) {\n\tpj_xml_node *found;\n\tif (pj_stricmp(&node->name, name) == 0)\n\t    return (pj_xml_node*)node;\n\tfound = pj_xml_find_node_rec(node, name);\n\tif (found)\n\t    return (pj_xml_node*)found;\n\tnode = node->next;\n    }\n    return NULL;\n}\n\nPJ_DEF(pj_xml_node*) pj_xml_find_next_node( const pj_xml_node *parent, \n\t\t\t\t\t    const pj_xml_node *node,\n\t\t\t\t\t    const pj_str_t *name)\n{\n    PJ_CHECK_STACK();\n\n    node = node->next;\n    while (node != (void*)&parent->node_head) {\n\tif (pj_stricmp(&node->name, name) == 0)\n\t    return (pj_xml_node*)node;\n\tnode = node->next;\n    }\n    return NULL;\n}\n\n\nPJ_DEF(pj_xml_attr*) pj_xml_find_attr( const pj_xml_node *node, \n\t\t\t\t       const pj_str_t *name,\n\t\t\t\t       const pj_str_t *value)\n{\n    const pj_xml_attr *attr = node->attr_head.next;\n    while (attr != (void*)&node->attr_head) {\n\tif (pj_stricmp(&attr->name, name)==0) {\n\t    if (value) {\n\t\tif (pj_stricmp(&attr->value, value)==0)\n\t\t    return (pj_xml_attr*)attr;\n\t    } else {\n\t\treturn (pj_xml_attr*)attr;\n\t    }\n\t}\n\tattr = attr->next;\n    }\n    return NULL;\n}\n\n\n\nPJ_DEF(pj_xml_node*) pj_xml_find( const pj_xml_node *parent, \n\t\t\t\t  const pj_str_t *name,\n\t\t\t\t  const void *data, \n\t\t\t\t  pj_bool_t (*match)(const pj_xml_node *, \n\t\t\t\t\t\t     const void*))\n{\n    const pj_xml_node *node = (const pj_xml_node *)parent->node_head.next;\n\n    if (!name && !match)\n\treturn NULL;\n\n    while (node != (const pj_xml_node*) &parent->node_head) {\n\tif (name) {\n\t    if (pj_stricmp(&node->name, name)!=0) {\n\t\tnode = node->next;\n\t\tcontinue;\n\t    }\n\t}\n\tif (match) {\n\t    if (match(node, data))\n\t\treturn (pj_xml_node*)node;\n\t} else {\n\t    return (pj_xml_node*)node;\n\t}\n\n\tnode = node->next;\n    }\n    return NULL;\n}\n\nPJ_DEF(pj_xml_node*) pj_xml_find_rec( const pj_xml_node *parent, \n\t\t\t\t      const pj_str_t *name,\n\t\t\t\t      const void *data, \n\t\t\t\t      pj_bool_t (*match)(const pj_xml_node*, \n\t\t\t\t\t\t\t const void*))\n{\n    const pj_xml_node *node = (const pj_xml_node *)parent->node_head.next;\n\n    if (!name && !match)\n\treturn NULL;\n\n    while (node != (const pj_xml_node*) &parent->node_head) {\n\tpj_xml_node *found;\n\n\tif (name) {\n\t    if (pj_stricmp(&node->name, name)==0) {\n\t\tif (match) {\n\t\t    if (match(node, data))\n\t\t\treturn (pj_xml_node*)node;\n\t\t} else {\n\t\t    return (pj_xml_node*)node;\n\t\t}\n\t    }\n\n\t} else if (match) {\n\t    if (match(node, data))\n\t\treturn (pj_xml_node*)node;\n\t}\n\n\tfound = pj_xml_find_rec(node, name, data, match);\n\tif (found)\n\t    return found;\n\n\tnode = node->next;\n    }\n    return NULL;\n}\n\nPJ_DEF(pj_xml_node*) pj_xml_clone( pj_pool_t *pool, const pj_xml_node *rhs)\n{\n    pj_xml_node *node;\n    const pj_xml_attr *r_attr;\n    const pj_xml_node *child;\n\n    node = alloc_node(pool);\n\n    pj_strdup(pool, &node->name, &rhs->name);\n    pj_strdup(pool, &node->content, &rhs->content);\n\n    /* Clone all attributes */\n    r_attr = rhs->attr_head.next;\n    while (r_attr != &rhs->attr_head) {\n\n\tpj_xml_attr *attr;\n\n\tattr = alloc_attr(pool);\n\tpj_strdup(pool, &attr->name, &r_attr->name);\n\tpj_strdup(pool, &attr->value, &r_attr->value);\n\n\tpj_list_push_back(&node->attr_head, attr);\n\n\tr_attr = r_attr->next;\n    }\n\n    /* Clone all child nodes. */\n    child = rhs->node_head.next;\n    while (child != (pj_xml_node*) &rhs->node_head) {\n\tpj_xml_node *new_child;\n\n\tnew_child = pj_xml_clone(pool, child);\n\tpj_list_push_back(&node->node_head, new_child);\n\n\tchild = child->next;\n    }\n\n    return node;\n}\n"
  },
  {
    "path": "deps/pjsip/pjlib-util/src/pjlib-util/xml_wrap.cpp",
    "content": "/* $Id: xml_wrap.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * This file is a C++ wrapper, see ticket #886 for details.\n */\n\n#include \"xml.c\"\n"
  },
  {
    "path": "deps/pjsip/pjmedia/README.txt",
    "content": "[Last Update: 2006/03/04]\n\nThis directory contains two static libraries:\n - pjmedia\n   The multimedia framework.\n\n - pjmedia-codec\n   Codec collections.\n\npjmedia has G711 codecs (Alaw and ULaw).\n\npjmedia-codec has:\n - GSM-FR implementation\n   Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n   Universitaet Berlin\n\n - Speex 1.1.12\n   http://www.speex.org\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/build/Makefile",
    "content": "include ../../build.mak\ninclude ../../version.mak\n\nTHIRD_PARTY:=$(PJDIR)/third_party\n\nSRTP_INC=$(CC_INC)$(THIRD_PARTY)/build/srtp \\\n\t $(CC_INC)$(THIRD_PARTY)/srtp/crypto/include \\\n\t $(CC_INC)$(THIRD_PARTY)/srtp/include\n\ninclude $(PJDIR)/build/common.mak\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\nPJLIB_LIB:=$(PJDIR)/pjlib/lib/libpj-$(TARGET_NAME)$(LIBEXT)\nPJLIB_UTIL_LIB:=$(PJDIR)/pjlib-util/lib/libpjlib-util-$(TARGET_NAME)$(LIBEXT)\nPJNATH_LIB:=$(PJDIR)/pjnath/lib/libpjnath-$(TARGET_NAME)$(LIBEXT)\n\nexport PJMEDIA_LIB:=../lib/libpjmedia-$(TARGET_NAME)$(LIBEXT)\nexport PJMEDIA_CODEC_LIB:=../lib/libpjmedia-codec-$(TARGET_NAME)$(LIBEXT)\nexport PJSDP_LIB:=../lib/libpjsdp-$(TARGET_NAME)$(LIBEXT)\nexport PJMEDIA_AUDIODEV_LIB:=../lib/libpjmedia-audiodev-$(TARGET_NAME)$(LIBEXT)\nexport PJMEDIA_VIDEODEV_LIB:=../lib/libpjmedia-videodev-$(TARGET_NAME)$(LIBEXT)\n\n\n###############################################################################\n# Gather all flags.\n#\nexport _CFLAGS \t:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t\t   $(CFLAGS) $(CC_INC)../include \\\n\t\t   $(CC_INC)../../pjlib/include \\\n\t\t   $(CC_INC)../../pjlib-util/include \\\n\t\t   $(CC_INC)../../pjmedia/include \\\n\t\t   $(CC_INC)../../pjnath/include \\\n\t\t   $(CC_INC)../.. \\\n\t\t   $(SRTP_INC) \nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\nexport _LDFLAGS := $(subst /,$(HOST_PSEP),$(PJMEDIA_VIDEODEV_LIB)) \\\n\t\t   $(subst /,$(HOST_PSEP),$(PJMEDIA_CODEC_LIB)) \\\n\t\t   $(subst /,$(HOST_PSEP),$(PJMEDIA_LIB)) \\\n\t\t   $(subst /,$(HOST_PSEP),$(PJMEDIA_AUDIODEV_LIB)) \\\n\t\t   $(subst /,$(HOST_PSEP),$(PJLIB_LIB)) \\\n\t\t   $(subst /,$(HOST_PSEP),$(PJLIB_UTIL_LIB)) \\\n\t\t   $(subst /,$(HOST_PSEP),$(PJNATH_LIB)) \\\n\t\t   -L$(PJDIR)/third_party/lib \\\n\t\t   $(APP_THIRD_PARTY_LIBS) \\\n\t\t   $(APP_THIRD_PARTY_EXT) \\\n\t\t   $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(LDFLAGS) \n\n###############################################################################\n# Defines for building PJMEDIA library\n#\nexport PJMEDIA_SRCDIR = ../src/pjmedia\nexport PJMEDIA_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \\\n\t\t\talaw_ulaw.o alaw_ulaw_table.o avi_player.o \\\n\t\t\tbidirectional.o clock_thread.o codec.o conference.o \\\n\t\t\tconf_switch.o converter.o  converter_libswscale.o converter_libyuv.o \\\n\t\t\tdelaybuf.o echo_common.o \\\n\t\t\techo_port.o echo_suppress.o endpoint.o errno.o \\\n\t\t\tevent.o format.o ffmpeg_util.o \\\n\t\t\tg711.o jbuf.o master_port.o mem_capture.o mem_player.o \\\n\t\t\tmixer_port.o null_port.o plc_common.o port.o splitcomb.o \\\n\t\t\tresample_resample.o resample_libsamplerate.o \\\n\t\t\tresample_port.o rtcp.o rtcp_xr.o rtp.o \\\n\t\t\tsdp.o sdp_cmp.o sdp_neg.o session.o silencedet.o \\\n\t\t\tsound_legacy.o sound_port.o stereo_port.o stream_common.o \\\n\t\t\tstream.o stream_info.o tonegen.o transport_adapter_sample.o \\\n\t\t\ttransport_ice.o transport_loop.o transport_srtp.o transport_zrtp.o transport_udp.o \\\n\t\t\ttypes.o vid_codec.o vid_codec_util.o \\\n\t\t\tvid_port.o vid_stream.o vid_stream_info.o vid_tee.o \\\n\t\t\twav_player.o wav_playlist.o wav_writer.o wave.o \\\n\t\t\twsola.o\n\nexport PJMEDIA_CFLAGS += $(_CFLAGS)\n\n\n###############################################################################\n# Defines for building PJMEDIA-AUDIODEV library\n#\nexport PJMEDIA_AUDIODEV_SRCDIR = ../src/pjmedia-audiodev\nexport PJMEDIA_AUDIODEV_OBJS +=  audiodev.o errno.o null_dev.o wmme_dev.o alsa_dev.o\nexport PJMEDIA_AUDIODEV_CFLAGS += $(_CFLAGS)\n\n\n###############################################################################\n# Defines for building PJMEDIA-VIDEODEV library\n#\nexport PJMEDIA_VIDEODEV_SRCDIR = ../src/pjmedia-videodev\nexport PJMEDIA_VIDEODEV_OBJS +=  errno.o videodev.o avi_dev.o colorbar_dev.o v4l2_dev.o fb_dev.o null_dev.o util.o\nexport PJMEDIA_VIDEODEV_CFLAGS += $(_CFLAGS)\nexport PJMEDIA_VIDEODEV_CXXFLAGS += $(_CXXFLAGS)\n\n\n###############################################################################\n# Defines for building PJSDP library\n# Note that SDP functionality is already INCLUDED in PJMEDIA.\n# The PJSDP library should only be used for applications that want SDP\n# but don't want to use the rest of the media framework.\n#\nexport PJSDP_SRCDIR = ../src/pjmedia\nexport PJSDP_OBJS += \t$(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \\\n\t\t\terrno.o sdp.o sdp_cmp.o sdp_neg.o\nexport PJSDP_CFLAGS += $(_CFLAGS)\n\n\n###############################################################################\n# Defines for building PJMEDIA-Codec library\n#\nexport PJMEDIA_CODEC_SRCDIR = ../src/pjmedia-codec\nexport PJMEDIA_CODEC_OBJS += audio_codecs.o ffmpeg_vid_codecs.o openh264.o \\\n\t\t\th263_packetizer.o h264_packetizer.o vpx.o \\\n\t\t\t$(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \\\n\t\t\t$(CODEC_OBJS) \\\n                        g7221_sdp_match.o\nexport PJMEDIA_CODEC_CFLAGS += $(_CFLAGS) $(GSM_CFLAGS) $(SPEEX_CFLAGS) \\\n\t\t\t$(ILBC_CFLAGS) $(IPP_CFLAGS) $(G7221_CFLAGS)\nexport PJMEDIA_CODEC_CXXFLAGS += $(_CXXFLAGS) $(GSM_CFLAGS) $(SPEEX_CFLAGS) \\\n\t\t\t$(ILBC_CFLAGS) $(IPP_CFLAGS) $(G7221_CFLAGS)\n\n\n###############################################################################\n# Defines for building test application\n#\nexport PJMEDIA_TEST_SRCDIR = ../src/test\nexport PJMEDIA_TEST_OBJS += codec_vectors.o jbuf_test.o main.o mips_test.o \\\n\t\t\t    vid_codec_test.o vid_dev_test.o vid_port_test.o \\\n\t\t\t    rtp_test.o test.o\nexport PJMEDIA_TEST_OBJS += sdp_neg_test.o \nexport PJMEDIA_TEST_CFLAGS += $(_CFLAGS)\nexport PJMEDIA_TEST_LDFLAGS += $(_LDFLAGS)\nexport PJMEDIA_TEST_EXE:=../bin/pjmedia-test-$(TARGET_NAME)$(HOST_EXE)\n\n\t\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT \n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\nTARGETS := pjmedia pjmedia-videodev pjmedia-audiodev pjmedia-codec pjsdp\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && rm -rf docs/$(PJ_VERSION) && doxygen docs/doxygen.cfg\n\t@if [ -n \"$(WWWDIR)\" ] && ! [ -d \"$(WWWDIR)/docs/$(PJ_VERSION)/pjmedia/docs/html\" ] ; then \\\n\t\techo \"Creating docs/$(PJ_VERSION)/pjmedia/docs/html\" ; \\\n\t\tmkdir -p $(WWWDIR)/docs/$(PJ_VERSION)/pjmedia/docs/html ; \\\n\tfi \n\t@if [ -n \"$(WWWDIR)\" ] && [ -d \"$(WWWDIR)/docs/$(PJ_VERSION)/pjmedia/docs/html\" ] ; then \\\n\t\techo \"Copying docs/$(PJ_VERSION) to $(WWWDIR)/docs/$(PJ_VERSION)/pjmedia/docs/html..\" ; \\\n\t\tcp -v -a ../docs/$(PJ_VERSION)/html/* $(WWWDIR)/docs/$(PJ_VERSION)/pjmedia/docs/html/ ; \\\n\tfi\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend pjmedia pjmedia-codec pjmedia-videodev pjmedia-audiodev pjmedia-test clean realclean distclean\n\npjmedia:\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $(PJMEDIA_LIB)\n\npjmedia-codec:\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $(PJMEDIA_CODEC_LIB)\n\npjmedia-videodev:\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $(PJMEDIA_VIDEODEV_LIB)\n\npjmedia-audiodev:\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $(PJMEDIA_AUDIODEV_LIB)\n\npjsdp:\n\t$(MAKE) -f $(RULES_MAK) APP=PJSDP app=pjsdp $(PJSDP_LIB)\n\n$(PJMEDIA_LIB): pjmedia\n\npjmedia-test: $(PJMEDIA_LIB) pjmedia\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_TEST app=pjmedia-test $(PJMEDIA_TEST_EXE)\n\n.PHONY: ../lib/pjmedia.ko\n../lib/pjmedia.ko:\n\techo Making $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $@\n\n.PHONY: ../lib/pjmedia-codec.ko\n../lib/pjmedia-codec.ko:\n\techo Making $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $@\n\n.PHONY: ../lib/pjmedia-test.ko\n../lib/pjmedia-test.ko:\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_TEST app=pjmedia-test $@\n\nclean:\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJSDP app=pjsdp $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_TEST app=pjmedia-test $@\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-videodev-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-audiodev-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-codec-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-test-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjsdp-$(TARGET_NAME).depend),$(HOST_RMR))\n\t\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_TEST app=pjmedia-test $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJSDP app=pjsdp $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_TEST app=pjmedia-test $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJSDP app=pjsdp $@\n\techo '$(PJMEDIA_TEST_EXE): $(PJMEDIA_LIB) $(PJMEDIA_CODEC_LIB) $(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB)' >> .pjmedia-test-$(TARGET_NAME).depend\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/build/os-auto.mak.in",
    "content": "# @configure_input@\n\n# Define the desired video device backend\n# Valid values are:\n#   - mac_os\n#   - iphone_os\n#   - android_os\nAC_PJMEDIA_VIDEO = @ac_pjmedia_video@\n\n# FFMPEG dlags\nFFMPEG_CFLAGS = @ac_ffmpeg_cflags@ \nFFMPEG_LDFLAGS =  @ac_ffmpeg_ldflags@\n\n# VPX flags\nVPX_CFLAGS = @ac_vpx_cflags@\nVPX_LDFLAGS =  @ac_vpx_ldflags@\n\n# Video4Linux2\nV4L2_CFLAGS = @ac_v4l2_cflags@\nV4L2_LDFLAGS = @ac_v4l2_ldflags@\n\n# AVF\nAC_PJMEDIA_VIDEO_HAS_AVF = @ac_pjmedia_video_has_avf@\nAVF_CFLAGS = @ac_avf_cflags@\n\n# iOS\nIOS_CFLAGS = @ac_ios_cflags@\n\n# Dshow\nAC_PJMEDIA_VIDEO_HAS_DSHOW = @ac_pjmedia_video_has_dshow@\nDSHOW_CFLAGS = @ac_dshow_cflags@\nDSHOW_LDFLAGS = @ac_dshow_ldflags@\n\n# libyuv\nLIBYUV_CFLAGS = @ac_libyuv_cflags@\nLIBYUV_LDFLAGS = @ac_libyuv_ldflags@\n\n# openh264\nOPENH264_CFLAGS = @ac_openh264_cflags@\nOPENH264_LDFLAGS = @ac_openh264_ldflags@\n\n# PJMEDIA features exclusion\nexport CFLAGS += @ac_no_small_filter@ @ac_no_large_filter@ @ac_no_speex_aec@ \\\n\t\t $(FFMPEG_CFLAGS) $(V4L2_CFLAGS) $(AVF_CFLAGS) \\\n\t\t $(IOS_CFLAGS) $(DSHOW_CFLAGS) $(LIBYUV_CFLAGS) $(OPENH264_CFLAGS) \\\n\t\t $(VPX_CFLAGS)\nexport LDFLAGS += $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS) $(DSHOW_LDFLAGS) \\\n    \t\t  $(LIBYUV_LDFLAGS) $(OPENH264_LDFLAGS) $(VPX_LDFLAGS)\n\n\n#\n# Codecs\n#\nAC_NO_G7221_CODEC=@ac_no_g7221_codec@\n\nexport CODEC_OBJS=\n\nexport PJMEDIA_AUDIODEV_OBJS += @ac_pjmedia_audiodev_objs@\n\nexport CODEC_OBJS += gsm.o\n\nexport CFLAGS += -I$(THIRD_PARTY)/build/speex -I$(THIRD_PARTY)/speex/include\nexport CODEC_OBJS += speex_codec.o\n\nifneq (@ac_no_speex_aec@,1)\nexport PJMEDIA_OBJS += echo_speex.o\nendif\n\nexport CFLAGS += -I$(THIRD_PARTY)/webrtc/src\nexport PJMEDIA_OBJS += echo_webrtc_aec.o\n\nexport CODEC_OBJS += ilbc.o\n\nexport CODEC_OBJS += g722.o g722/g722_enc.o g722/g722_dec.o\n\nifeq ($(AC_NO_G7221_CODEC),1)\nexport CFLAGS += -DPJMEDIA_HAS_G7221_CODEC=0\nelse\nexport CODEC_OBJS += g7221.o\nexport G7221_CFLAGS += -I$(THIRD_PARTY)\nendif\n\nexport CODEC_OBJS += opus.o\n\n#\n# Dshow video device\n#\nifeq ($(AC_PJMEDIA_VIDEO_HAS_DSHOW),yes)\nexport PJMEDIA_VIDEODEV_OBJS += dshow_dev.o dshow_filter.o\nendif\n\n#\n# AVF video device\n#\nifeq ($(AC_PJMEDIA_VIDEO_HAS_AVF),yes)\nexport PJMEDIA_VIDEODEV_OBJS += avf_dev.o\nendif\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/docs/doxygen.cfg",
    "content": "# Doxyfile 1.3-rc3\r\n\r\n# This file describes the settings to be used by the documentation system\r\n# doxygen (www.doxygen.org) for a project\r\n#\r\n# All text after a hash (#) is considered a comment and will be ignored\r\n# The format is:\r\n#       TAG = value [value, ...]\r\n# For lists items can also be appended using:\r\n#       TAG += value [value, ...]\r\n# Values that contain spaces should be placed between quotes (\" \")\r\n\r\n#---------------------------------------------------------------------------\r\n# General configuration options\r\n#---------------------------------------------------------------------------\r\n\r\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded \r\n# by quotes) that should identify the project.\r\n\r\nPROJECT_NAME           =  \"PJMEDIA Reference\"\r\n\r\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. \r\n# This could be handy for archiving the generated documentation or \r\n# if some version control system is used.\r\n\r\nPROJECT_NUMBER         = $(PJ_VERSION)\r\n\r\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) \r\n# base path where the generated documentation will be put. \r\n# If a relative path is entered, it will be relative to the location \r\n# where doxygen was started. If left blank the current directory will be used.\r\n\r\nOUTPUT_DIRECTORY       = docs/$(PJ_VERSION)\r\n\r\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all \r\n# documentation generated by doxygen is written. Doxygen will use this \r\n# information to generate all constant output in the proper language. \r\n# The default language is English, other supported languages are: \r\n# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, \r\n# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en \r\n# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, \r\n# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian.\r\n\r\nOUTPUT_LANGUAGE        = English\r\n\r\n# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in \r\n# documentation are documented, even if no documentation was available. \r\n# Private class members and static file members will be hidden unless \r\n# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES\r\n\r\nEXTRACT_ALL            = NO\r\n\r\n# If the EXTRACT_PRIVATE tag is set to YES all private members of a class \r\n# will be included in the documentation.\r\n\r\nEXTRACT_PRIVATE        = NO\r\n\r\n# If the EXTRACT_STATIC tag is set to YES all static members of a file \r\n# will be included in the documentation.\r\n\r\nEXTRACT_STATIC         = NO\r\n\r\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) \r\n# defined locally in source files will be included in the documentation. \r\n# If set to NO only classes defined in header files are included.\r\n\r\nEXTRACT_LOCAL_CLASSES  = YES\r\n\r\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all \r\n# undocumented members of documented classes, files or namespaces. \r\n# If set to NO (the default) these members will be included in the \r\n# various overviews, but no documentation section is generated. \r\n# This option has no effect if EXTRACT_ALL is enabled.\r\n\r\nHIDE_UNDOC_MEMBERS     = NO\r\n\r\n# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all \r\n# undocumented classes that are normally visible in the class hierarchy. \r\n# If set to NO (the default) these class will be included in the various \r\n# overviews. This option has no effect if EXTRACT_ALL is enabled.\r\n\r\nHIDE_UNDOC_CLASSES     = NO\r\n\r\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all \r\n# friend (class|struct|union) declarations. \r\n# If set to NO (the default) these declarations will be included in the \r\n# documentation.\r\n\r\nHIDE_FRIEND_COMPOUNDS  = NO\r\n\r\n# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any \r\n# documentation blocks found inside the body of a function. \r\n# If set to NO (the default) these blocks will be appended to the \r\n# function's detailed documentation block.\r\n\r\nHIDE_IN_BODY_DOCS      = NO\r\n\r\n# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will \r\n# include brief member descriptions after the members that are listed in \r\n# the file and class documentation (similar to JavaDoc). \r\n# Set to NO to disable this.\r\n\r\nBRIEF_MEMBER_DESC      = YES\r\n\r\n# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend \r\n# the brief description of a member or function before the detailed description. \r\n# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the \r\n# brief descriptions will be completely suppressed.\r\n\r\nREPEAT_BRIEF           = NO\r\n\r\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then \r\n# Doxygen will generate a detailed section even if there is only a brief \r\n# description.\r\n\r\nALWAYS_DETAILED_SEC    = NO\r\n\r\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited \r\n# members of a class in the documentation of that class as if those members were \r\n# ordinary class members. Constructors, destructors and assignment operators of \r\n# the base classes will not be shown.\r\n\r\nINLINE_INHERITED_MEMB  = NO\r\n\r\n# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full \r\n# path before files name in the file list and in the header files. If set \r\n# to NO the shortest path that makes the file name unique will be used.\r\n\r\nFULL_PATH_NAMES        = NO\r\n\r\n# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag \r\n# can be used to strip a user defined part of the path. Stripping is \r\n# only done if one of the specified strings matches the left-hand part of \r\n# the path. It is allowed to use relative paths in the argument list.\r\n\r\nSTRIP_FROM_PATH        = \"/c/project/pjproject/pjmedia\"\r\n\r\n# The INTERNAL_DOCS tag determines if documentation \r\n# that is typed after a \\internal command is included. If the tag is set \r\n# to NO (the default) then the documentation will be excluded. \r\n# Set it to YES to include the internal documentation.\r\n\r\nINTERNAL_DOCS          = NO\r\n\r\n# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate \r\n# file names in lower case letters. If set to YES upper case letters are also \r\n# allowed. This is useful if you have classes or files whose names only differ \r\n# in case and if your file system supports case sensitive file names. Windows \r\n# users are adviced to set this option to NO.\r\n\r\nCASE_SENSE_NAMES       = YES\r\n\r\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter \r\n# (but less readable) file names. This can be useful is your file systems \r\n# doesn't support long names like on DOS, Mac, or CD-ROM.\r\n\r\nSHORT_NAMES            = NO\r\n\r\n# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen \r\n# will show members with their full class and namespace scopes in the \r\n# documentation. If set to YES the scope will be hidden.\r\n\r\nHIDE_SCOPE_NAMES       = NO\r\n\r\n# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen \r\n# will generate a verbatim copy of the header file for each class for \r\n# which an include is specified. Set to NO to disable this.\r\n\r\nVERBATIM_HEADERS       = NO\r\n\r\n# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen \r\n# will put list of the files that are included by a file in the documentation \r\n# of that file.\r\n\r\nSHOW_INCLUDE_FILES     = NO\r\n\r\n# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen \r\n# will interpret the first line (until the first dot) of a JavaDoc-style \r\n# comment as the brief description. If set to NO, the JavaDoc \r\n# comments  will behave just like the Qt-style comments (thus requiring an \r\n# explict @brief command for a brief description.\r\n\r\nJAVADOC_AUTOBRIEF      = NO\r\n\r\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen \r\n# treat a multi-line C++ special comment block (i.e. a block of //! or /// \r\n# comments) as a brief description. This used to be the default behaviour. \r\n# The new default is to treat a multi-line C++ comment block as a detailed \r\n# description. Set this tag to YES if you prefer the old behaviour instead.\r\n\r\nMULTILINE_CPP_IS_BRIEF = NO\r\n\r\n# If the DETAILS_AT_TOP tag is set to YES then Doxygen \r\n# will output the detailed description near the top, like JavaDoc.\r\n# If set to NO, the detailed description appears after the member \r\n# documentation.\r\n\r\nDETAILS_AT_TOP         = YES\r\n\r\n# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented \r\n# member inherits the documentation from any documented member that it \r\n# reimplements.\r\n\r\nINHERIT_DOCS           = YES\r\n\r\n# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] \r\n# is inserted in the documentation for inline members.\r\n\r\nINLINE_INFO            = YES\r\n\r\n# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen \r\n# will sort the (detailed) documentation of file and class members \r\n# alphabetically by member name. If set to NO the members will appear in \r\n# declaration order.\r\n\r\nSORT_MEMBER_DOCS       = NO\r\n\r\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC \r\n# tag is set to YES, then doxygen will reuse the documentation of the first \r\n# member in the group (if any) for the other members of the group. By default \r\n# all members of a group must be documented explicitly.\r\n\r\nDISTRIBUTE_GROUP_DOC   = NO\r\n\r\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. \r\n# Doxygen uses this value to replace tabs by spaces in code fragments.\r\n\r\nTAB_SIZE               = 8\r\n\r\n# The GENERATE_TODOLIST tag can be used to enable (YES) or \r\n# disable (NO) the todo list. This list is created by putting \\todo \r\n# commands in the documentation.\r\n\r\nGENERATE_TODOLIST      = YES\r\n\r\n# The GENERATE_TESTLIST tag can be used to enable (YES) or \r\n# disable (NO) the test list. This list is created by putting \\test \r\n# commands in the documentation.\r\n\r\nGENERATE_TESTLIST      = YES\r\n\r\n# The GENERATE_BUGLIST tag can be used to enable (YES) or \r\n# disable (NO) the bug list. This list is created by putting \\bug \r\n# commands in the documentation.\r\n\r\nGENERATE_BUGLIST       = YES\r\n\r\n# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or \r\n# disable (NO) the deprecated list. This list is created by putting \r\n# \\deprecated commands in the documentation.\r\n\r\nGENERATE_DEPRECATEDLIST= YES\r\n\r\n# This tag can be used to specify a number of aliases that acts \r\n# as commands in the documentation. An alias has the form \"name=value\". \r\n# For example adding \"sideeffect=\\par Side Effects:\\n\" will allow you to \r\n# put the command \\sideeffect (or @sideeffect) in the documentation, which \r\n# will result in a user defined paragraph with heading \"Side Effects:\". \r\n# You can put \\n's in the value part of an alias to insert newlines.\r\n\r\nALIASES                = \r\n\r\n# The ENABLED_SECTIONS tag can be used to enable conditional \r\n# documentation sections, marked by \\if sectionname ... \\endif.\r\n\r\nENABLED_SECTIONS       = \r\n\r\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines \r\n# the initial value of a variable or define consist of for it to appear in \r\n# the documentation. If the initializer consists of more lines than specified \r\n# here it will be hidden. Use a value of 0 to hide initializers completely. \r\n# The appearance of the initializer of individual variables and defines in the \r\n# documentation can be controlled using \\showinitializer or \\hideinitializer \r\n# command in the documentation regardless of this setting.\r\n\r\nMAX_INITIALIZER_LINES  = 30\r\n\r\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources \r\n# only. Doxygen will then generate output that is more tailored for C. \r\n# For instance some of the names that are used will be different. The list \r\n# of all members will be omitted, etc.\r\n\r\nOPTIMIZE_OUTPUT_FOR_C  = YES\r\n\r\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources \r\n# only. Doxygen will then generate output that is more tailored for Java. \r\n# For instance namespaces will be presented as packages, qualified scopes \r\n# will look different, etc.\r\n\r\nOPTIMIZE_OUTPUT_JAVA   = NO\r\n\r\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated \r\n# at the bottom of the documentation of classes and structs. If set to YES the \r\n# list will mention the files that were used to generate the documentation.\r\n\r\nSHOW_USED_FILES        = YES\r\n\r\nTYPEDEF_HIDES_STRUCT\t= YES\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to warning and progress messages\r\n#---------------------------------------------------------------------------\r\n\r\n# The QUIET tag can be used to turn on/off the messages that are generated \r\n# by doxygen. Possible values are YES and NO. If left blank NO is used.\r\n\r\nQUIET                  = NO\r\n\r\n# The WARNINGS tag can be used to turn on/off the warning messages that are \r\n# generated by doxygen. Possible values are YES and NO. If left blank \r\n# NO is used.\r\n\r\nWARNINGS               = YES\r\n\r\n# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings \r\n# for undocumented members. If EXTRACT_ALL is set to YES then this flag will \r\n# automatically be disabled.\r\n\r\nWARN_IF_UNDOCUMENTED   = NO\r\n\r\n# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for \r\n# potential errors in the documentation, such as not documenting some \r\n# parameters in a documented function, or documenting parameters that \r\n# don't exist or using markup commands wrongly.\r\n\r\nWARN_IF_DOC_ERROR      = YES\r\n\r\n# The WARN_FORMAT tag determines the format of the warning messages that \r\n# doxygen can produce. The string should contain the $file, $line, and $text \r\n# tags, which will be replaced by the file and line number from which the \r\n# warning originated and the warning text.\r\n\r\nWARN_FORMAT            = \"$file:$line: $text\"\r\n\r\n# The WARN_LOGFILE tag can be used to specify a file to which warning \r\n# and error messages should be written. If left blank the output is written \r\n# to stderr.\r\n\r\nWARN_LOGFILE           = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the input files\r\n#---------------------------------------------------------------------------\r\n\r\n# The INPUT tag can be used to specify the files and/or directories that contain \r\n# documented source files. You may enter file names like \"myfile.cpp\" or \r\n# directories like \"/usr/src/myproject\". Separate the files or directories \r\n# with spaces.\r\n\r\nINPUT                  =  include ../pjsip-apps/src/samples\r\n\r\n# If the value of the INPUT tag contains directories, you can use the \r\n# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \r\n# and *.h) to filter out the source-files in the directories. If left \r\n# blank the following patterns are tested: \r\n# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp \r\n# *.h++ *.idl *.odl\r\n\r\nFILE_PATTERNS          = *.h *.c\r\n\r\n# The RECURSIVE tag can be used to turn specify whether or not subdirectories \r\n# should be searched for input files as well. Possible values are YES and NO. \r\n# If left blank NO is used.\r\n\r\nRECURSIVE              = YES\r\n\r\n# The EXCLUDE tag can be used to specify files and/or directories that should \r\n# excluded from the INPUT source files. This way you can easily exclude a \r\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\r\n\r\nEXCLUDE                = *_i.h\r\n\r\n# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories \r\n# that are symbolic links (a Unix filesystem feature) are excluded from the input.\r\n\r\nEXCLUDE_SYMLINKS       = NO\r\n\r\n# If the value of the INPUT tag contains directories, you can use the \r\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude \r\n# certain files from those directories.\r\n\r\nEXCLUDE_PATTERNS       = \r\n\r\n# The EXAMPLE_PATH tag can be used to specify one or more files or \r\n# directories that contain example code fragments that are included (see \r\n# the \\include command).\r\n\r\nEXAMPLE_PATH           = ../pjsip-apps/src/samples\r\n\r\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the \r\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \r\n# and *.h) to filter out the source-files in the directories. If left \r\n# blank all files are included.\r\n\r\nEXAMPLE_PATTERNS       = \r\n\r\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be \r\n# searched for input files to be used with the \\include or \\dontinclude \r\n# commands irrespective of the value of the RECURSIVE tag. \r\n# Possible values are YES and NO. If left blank NO is used.\r\n\r\nEXAMPLE_RECURSIVE      = NO\r\n\r\n# The IMAGE_PATH tag can be used to specify one or more files or \r\n# directories that contain image that are included in the documentation (see \r\n# the \\image command).\r\n\r\nIMAGE_PATH             = docs\r\n\r\n# The INPUT_FILTER tag can be used to specify a program that doxygen should \r\n# invoke to filter for each input file. Doxygen will invoke the filter program \r\n# by executing (via popen()) the command <filter> <input-file>, where <filter> \r\n# is the value of the INPUT_FILTER tag, and <input-file> is the name of an \r\n# input file. Doxygen will then use the output that the filter program writes \r\n# to standard output.\r\n\r\nINPUT_FILTER           = \r\n\r\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using \r\n# INPUT_FILTER) will be used to filter the input files when producing source \r\n# files to browse (i.e. when SOURCE_BROWSER is set to YES).\r\n\r\nFILTER_SOURCE_FILES    = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to source browsing\r\n#---------------------------------------------------------------------------\r\n\r\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will \r\n# be generated. Documented entities will be cross-referenced with these sources.\r\n\r\nSOURCE_BROWSER         = NO\r\n\r\n# Setting the INLINE_SOURCES tag to YES will include the body \r\n# of functions and classes directly in the documentation.\r\n\r\nINLINE_SOURCES         = NO\r\n\r\n# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct \r\n# doxygen to hide any special comment blocks from generated source code \r\n# fragments. Normal C and C++ comments will always remain visible.\r\n\r\nSTRIP_CODE_COMMENTS    = YES\r\n\r\n# If the REFERENCED_BY_RELATION tag is set to YES (the default) \r\n# then for each documented function all documented \r\n# functions referencing it will be listed.\r\n\r\nREFERENCED_BY_RELATION = YES\r\n\r\n# If the REFERENCES_RELATION tag is set to YES (the default) \r\n# then for each documented function all documented entities \r\n# called/used by that function will be listed.\r\n\r\nREFERENCES_RELATION    = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the alphabetical class index\r\n#---------------------------------------------------------------------------\r\n\r\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index \r\n# of all compounds will be generated. Enable this if the project \r\n# contains a lot of classes, structs, unions or interfaces.\r\n\r\nALPHABETICAL_INDEX     = NO\r\n\r\n# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then \r\n# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns \r\n# in which this list will be split (can be a number in the range [1..20])\r\n\r\nCOLS_IN_ALPHA_INDEX    = 5\r\n\r\n# In case all classes in a project start with a common prefix, all \r\n# classes will be put under the same header in the alphabetical index. \r\n# The IGNORE_PREFIX tag can be used to specify one or more prefixes that \r\n# should be ignored while generating the index headers.\r\n\r\nIGNORE_PREFIX          = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the HTML output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_HTML tag is set to YES (the default) Doxygen will \r\n# generate HTML output.\r\n\r\nGENERATE_HTML          = YES\r\n\r\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `html' will be used as the default path.\r\n\r\nHTML_OUTPUT            = html\r\n\r\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for \r\n# each generated HTML page (for example: .htm,.php,.asp). If it is left blank \r\n# doxygen will generate files with .html extension.\r\n\r\nHTML_FILE_EXTENSION    = .htm\r\n\r\n# The HTML_HEADER tag can be used to specify a personal HTML header for \r\n# each generated HTML page. If it is left blank doxygen will generate a \r\n# standard header.\r\n\r\nHTML_HEADER            = docs/header.html\r\n\r\n# The HTML_FOOTER tag can be used to specify a personal HTML footer for \r\n# each generated HTML page. If it is left blank doxygen will generate a \r\n# standard footer.\r\n\r\nHTML_FOOTER            = docs/footer.html\r\n\r\n# The HTML_STYLESHEET tag can be used to specify a user defined cascading \r\n# style sheet that is used by each HTML page. It can be used to \r\n# fine-tune the look of the HTML output. If the tag is left blank doxygen \r\n# will generate a default style sheet\r\n\r\nHTML_STYLESHEET        = ../pjlib/docs/doxygen.css\r\n\r\n# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, \r\n# files or namespaces will be aligned in HTML using tables. If set to \r\n# NO a bullet list will be used.\r\n\r\nHTML_ALIGN_MEMBERS     = YES\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, additional index files \r\n# will be generated that can be used as input for tools like the \r\n# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) \r\n# of the generated HTML documentation.\r\n\r\nGENERATE_HTMLHELP      = NO\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can \r\n# be used to specify the file name of the resulting .chm file. You \r\n# can add a path in front of the file if the result should not be \r\n# written to the html output dir.\r\n\r\nCHM_FILE               = \r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can \r\n# be used to specify the location (absolute path including file name) of \r\n# the HTML help compiler (hhc.exe). If non empty doxygen will try to run \r\n# the html help compiler on the generated index.hhp.\r\n\r\nHHC_LOCATION           = \r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag \r\n# controls if a separate .chi index file is generated (YES) or that \r\n# it should be included in the master .chm file (NO).\r\n\r\nGENERATE_CHI           = NO\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag \r\n# controls whether a binary table of contents is generated (YES) or a \r\n# normal table of contents (NO) in the .chm file.\r\n\r\nBINARY_TOC             = NO\r\n\r\n# The TOC_EXPAND flag can be set to YES to add extra items for group members \r\n# to the contents of the Html help documentation and to the tree view.\r\n\r\nTOC_EXPAND             = NO\r\n\r\n# The DISABLE_INDEX tag can be used to turn on/off the condensed index at \r\n# top of each HTML page. The value NO (the default) enables the index and \r\n# the value YES disables it.\r\n\r\nDISABLE_INDEX          = NO\r\n\r\n# This tag can be used to set the number of enum values (range [1..20]) \r\n# that doxygen will group on one line in the generated HTML documentation.\r\n\r\nENUM_VALUES_PER_LINE   = 1\r\n\r\n# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be\r\n# generated containing a tree-like index structure (just like the one that \r\n# is generated for HTML Help). For this to work a browser that supports \r\n# JavaScript, DHTML, CSS and frames is required (for instance Mozilla, \r\n# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are \r\n# probably better off using the HTML help feature.\r\n\r\nGENERATE_TREEVIEW      = NO\r\n\r\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be \r\n# used to set the initial width (in pixels) of the frame in which the tree \r\n# is shown.\r\n\r\nTREEVIEW_WIDTH         = 250\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the LaTeX output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will \r\n# generate Latex output.\r\n\r\nGENERATE_LATEX         = NO\r\n\r\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `latex' will be used as the default path.\r\n\r\nLATEX_OUTPUT           = latex\r\n\r\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be \r\n# invoked. If left blank `latex' will be used as the default command name.\r\n\r\nLATEX_CMD_NAME         = latex\r\n\r\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to \r\n# generate index for LaTeX. If left blank `makeindex' will be used as the \r\n# default command name.\r\n\r\nMAKEINDEX_CMD_NAME     = makeindex\r\n\r\n# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact \r\n# LaTeX documents. This may be useful for small projects and may help to \r\n# save some trees in general.\r\n\r\nCOMPACT_LATEX          = NO\r\n\r\n# The PAPER_TYPE tag can be used to set the paper type that is used \r\n# by the printer. Possible values are: a4, a4wide, letter, legal and \r\n# executive. If left blank a4wide will be used.\r\n\r\nPAPER_TYPE             = a4wide\r\n\r\n# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX \r\n# packages that should be included in the LaTeX output.\r\n\r\nEXTRA_PACKAGES         = \r\n\r\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for \r\n# the generated latex document. The header should contain everything until \r\n# the first chapter. If it is left blank doxygen will generate a \r\n# standard header. Notice: only use this tag if you know what you are doing!\r\n\r\nLATEX_HEADER           = \r\n\r\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated \r\n# is prepared for conversion to pdf (using ps2pdf). The pdf file will \r\n# contain links (just like the HTML output) instead of page references \r\n# This makes the output suitable for online browsing using a pdf viewer.\r\n\r\nPDF_HYPERLINKS         = NO\r\n\r\n# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of \r\n# plain latex in the generated Makefile. Set this option to YES to get a \r\n# higher quality PDF documentation.\r\n\r\nUSE_PDFLATEX           = NO\r\n\r\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\\\batchmode. \r\n# command to the generated LaTeX files. This will instruct LaTeX to keep \r\n# running if errors occur, instead of asking the user for help. \r\n# This option is also used when generating formulas in HTML.\r\n\r\nLATEX_BATCHMODE        = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the RTF output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output \r\n# The RTF output is optimised for Word 97 and may not look very pretty with \r\n# other RTF readers or editors.\r\n\r\nGENERATE_RTF           = NO\r\n\r\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `rtf' will be used as the default path.\r\n\r\nRTF_OUTPUT             = rtf\r\n\r\n# If the COMPACT_RTF tag is set to YES Doxygen generates more compact \r\n# RTF documents. This may be useful for small projects and may help to \r\n# save some trees in general.\r\n\r\nCOMPACT_RTF            = NO\r\n\r\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated \r\n# will contain hyperlink fields. The RTF file will \r\n# contain links (just like the HTML output) instead of page references. \r\n# This makes the output suitable for online browsing using WORD or other \r\n# programs which support those fields. \r\n# Note: wordpad (write) and others do not support links.\r\n\r\nRTF_HYPERLINKS         = NO\r\n\r\n# Load stylesheet definitions from file. Syntax is similar to doxygen's \r\n# config file, i.e. a series of assigments. You only have to provide \r\n# replacements, missing definitions are set to their default value.\r\n\r\nRTF_STYLESHEET_FILE    = \r\n\r\n# Set optional variables used in the generation of an rtf document. \r\n# Syntax is similar to doxygen's config file.\r\n\r\nRTF_EXTENSIONS_FILE    = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the man page output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_MAN tag is set to YES (the default) Doxygen will \r\n# generate man pages\r\n\r\nGENERATE_MAN           = NO\r\n\r\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `man' will be used as the default path.\r\n\r\nMAN_OUTPUT             = man\r\n\r\n# The MAN_EXTENSION tag determines the extension that is added to \r\n# the generated man pages (default is the subroutine's section .3)\r\n\r\nMAN_EXTENSION          = .3\r\n\r\n# If the MAN_LINKS tag is set to YES and Doxygen generates man output, \r\n# then it will generate one additional man file for each entity \r\n# documented in the real man page(s). These additional files \r\n# only source the real man page, but without them the man command \r\n# would be unable to find the correct page. The default is NO.\r\n\r\nMAN_LINKS              = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the XML output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_XML tag is set to YES Doxygen will \r\n# generate an XML file that captures the structure of \r\n# the code including all documentation. Note that this \r\n# feature is still experimental and incomplete at the \r\n# moment.\r\n\r\nGENERATE_XML           = NO\r\n\r\n# The XML_SCHEMA tag can be used to specify an XML schema, \r\n# which can be used by a validating XML parser to check the \r\n# syntax of the XML files.\r\n\r\nXML_SCHEMA             = \r\n\r\n# The XML_DTD tag can be used to specify an XML DTD, \r\n# which can be used by a validating XML parser to check the \r\n# syntax of the XML files.\r\n\r\nXML_DTD                = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options for the AutoGen Definitions output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will \r\n# generate an AutoGen Definitions (see autogen.sf.net) file \r\n# that captures the structure of the code including all \r\n# documentation. Note that this feature is still experimental \r\n# and incomplete at the moment.\r\n\r\nGENERATE_AUTOGEN_DEF   = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the Perl module output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_PERLMOD tag is set to YES Doxygen will \r\n# generate a Perl module file that captures the structure of \r\n# the code including all documentation. Note that this \r\n# feature is still experimental and incomplete at the \r\n# moment.\r\n\r\nGENERATE_PERLMOD       = NO\r\n\r\n# If the PERLMOD_LATEX tag is set to YES Doxygen will generate \r\n# the necessary Makefile rules, Perl scripts and LaTeX code to be able \r\n# to generate PDF and DVI output from the Perl module output.\r\n\r\nPERLMOD_LATEX          = NO\r\n\r\n# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be \r\n# nicely formatted so it can be parsed by a human reader.  This is useful \r\n# if you want to understand what is going on.  On the other hand, if this \r\n# tag is set to NO the size of the Perl module output will be much smaller \r\n# and Perl will parse it just the same.\r\n\r\nPERLMOD_PRETTY         = YES\r\n\r\n# The names of the make variables in the generated doxyrules.make file \r\n# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. \r\n# This is useful so different doxyrules.make files included by the same \r\n# Makefile don't overwrite each other's variables.\r\n\r\nPERLMOD_MAKEVAR_PREFIX = \r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration options related to the preprocessor   \r\n#---------------------------------------------------------------------------\r\n\r\n# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will \r\n# evaluate all C-preprocessor directives found in the sources and include \r\n# files.\r\n\r\nENABLE_PREPROCESSING   = YES\r\n\r\n# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro \r\n# names in the source code. If set to NO (the default) only conditional \r\n# compilation will be performed. Macro expansion can be done in a controlled \r\n# way by setting EXPAND_ONLY_PREDEF to YES.\r\n\r\nMACRO_EXPANSION        = YES\r\n\r\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES \r\n# then the macro expansion is limited to the macros specified with the \r\n# PREDEFINED and EXPAND_AS_PREDEFINED tags.\r\n\r\nEXPAND_ONLY_PREDEF     = NO\r\n\r\n# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files \r\n# in the INCLUDE_PATH (see below) will be search if a #include is found.\r\n\r\nSEARCH_INCLUDES        = YES\r\n\r\n# The INCLUDE_PATH tag can be used to specify one or more directories that \r\n# contain include files that are not input files but should be processed by \r\n# the preprocessor.\r\n\r\nINCLUDE_PATH           = \r\n\r\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard \r\n# patterns (like *.h and *.hpp) to filter out the header-files in the \r\n# directories. If left blank, the patterns specified with FILE_PATTERNS will \r\n# be used.\r\n\r\nINCLUDE_FILE_PATTERNS  = \r\n\r\n# The PREDEFINED tag can be used to specify one or more macro names that \r\n# are defined before the preprocessor is started (similar to the -D option of \r\n# gcc). The argument of the tag is a list of macros of the form: name \r\n# or name=definition (no spaces). If the definition and the = are \r\n# omitted =1 is assumed.\r\n\r\nPREDEFINED             = PJ_DECL(x)=x PJ_DEF(x)=x PJ_IDECL(x)=x \\\r\n\t\t\t PJ_IDEF(x)=x PJ_INLINE(x)=x \\\r\n\t\t\t PJ_DECL_DATA(x)=x \\\r\n\t\t\t PJ_DECL_NO_RETURN(x)=x \\\r\n\t\t\t PJ_NO_RETURN=x \\\r\n\t\t\t PJ_HAS_HIGH_RES_TIMER=1 \\\r\n\t\t\t PJ_LOG_MAX_LEVEL=4 \\\r\n\t\t\t PJ_HAS_SEMAPHORE=1 \\\r\n\t\t\t PJ_HAS_EVENT_OBJ=1 \\\r\n\t\t\t PJ_HAS_TCP=1 \\\r\n\t\t\t PJMEDIA_HAS_SRTP=1 \\\r\n\t\t\t PJMEDIA_STREAM_ENABLE_KA=1\r\n\r\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then \r\n# this tag can be used to specify a list of macro names that should be expanded. \r\n# The macro definition that is found in the sources will be used. \r\n# Use the PREDEFINED tag if you want to use a different macro definition.\r\n\r\nEXPAND_AS_DEFINED      = \r\n\r\n# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then \r\n# doxygen's preprocessor will remove all function-like macros that are alone \r\n# on a line, have an all uppercase name, and do not end with a semicolon. Such \r\n# function macros are typically used for boiler-plate code, and will confuse the \r\n# parser if not removed.\r\n\r\nSKIP_FUNCTION_MACROS   = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration::addtions related to external references   \r\n#---------------------------------------------------------------------------\r\n\r\n# The TAGFILES tag can be used to specify one or more tagfiles.\r\n\r\nTAGFILES               = ../pjlib/docs/pjlib.tag=../../../pjlib/docs/html ../pjlib-util/docs/pjlib-util.tag=../../../pjlib-util/docs/html ../pjnath/docs/pjnath.tag=../../../pjnath/docs/html ../pjsip/docs/pjmedia.tag=../../../pjmedia/docs/html\r\n\r\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create \r\n# a tag file that is based on the input files it reads.\r\n\r\nGENERATE_TAGFILE       = docs/pjmedia.tag\r\n\r\n# If the ALLEXTERNALS tag is set to YES all external classes will be listed \r\n# in the class index. If set to NO only the inherited external classes \r\n# will be listed.\r\n\r\nALLEXTERNALS           = NO\r\n\r\n# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed \r\n# in the modules index. If set to NO, only the current project's groups will \r\n# be listed.\r\n\r\nEXTERNAL_GROUPS        = NO\r\n\r\n# The PERL_PATH should be the absolute path and name of the perl script \r\n# interpreter (i.e. the result of `which perl').\r\n\r\n#PERL_PATH              = /usr/bin/perl\r\nPERL_PATH              = /c/Perl/bin/perl\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration options related to the dot tool   \r\n#---------------------------------------------------------------------------\r\n\r\n# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will \r\n# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or \r\n# super classes. Setting the tag to NO turns the diagrams off. Note that this \r\n# option is superceded by the HAVE_DOT option below. This is only a fallback. It is \r\n# recommended to install and use dot, since it yield more powerful graphs.\r\n\r\nCLASS_DIAGRAMS         = NO\r\n\r\n# If set to YES, the inheritance and collaboration graphs will hide \r\n# inheritance and usage relations if the target is undocumented \r\n# or is not a class.\r\n\r\nHIDE_UNDOC_RELATIONS   = YES\r\n\r\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is \r\n# available from the path. This tool is part of Graphviz, a graph visualization \r\n# toolkit from AT&T and Lucent Bell Labs. The other options in this section \r\n# have no effect if this option is set to NO (the default)\r\n\r\nHAVE_DOT               = NO\r\n\r\n# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen \r\n# will generate a graph for each documented class showing the direct and \r\n# indirect inheritance relations. Setting this tag to YES will force the \r\n# the CLASS_DIAGRAMS tag to NO.\r\n\r\nCLASS_GRAPH            = YES\r\n\r\n# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen \r\n# will generate a graph for each documented class showing the direct and \r\n# indirect implementation dependencies (inheritance, containment, and \r\n# class references variables) of the class with other documented classes.\r\n\r\nCOLLABORATION_GRAPH    = YES\r\n\r\n# If set to YES, the inheritance and collaboration graphs will show the \r\n# relations between templates and their instances.\r\n\r\nTEMPLATE_RELATIONS     = YES\r\n\r\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT \r\n# tags are set to YES then doxygen will generate a graph for each documented \r\n# file showing the direct and indirect include dependencies of the file with \r\n# other documented files.\r\n\r\nINCLUDE_GRAPH          = YES\r\n\r\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and \r\n# HAVE_DOT tags are set to YES then doxygen will generate a graph for each \r\n# documented header file showing the documented files that directly or \r\n# indirectly include this file.\r\n\r\nINCLUDED_BY_GRAPH      = YES\r\n\r\n# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen \r\n# will graphical hierarchy of all classes instead of a textual one.\r\n\r\nGRAPHICAL_HIERARCHY    = YES\r\n\r\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images \r\n# generated by dot. Possible values are png, jpg, or gif\r\n# If left blank png will be used.\r\n\r\nDOT_IMAGE_FORMAT       = png\r\n\r\n# The tag DOT_PATH can be used to specify the path where the dot tool can be \r\n# found. If left blank, it is assumed the dot tool can be found on the path.\r\n\r\nDOT_PATH               = \r\n\r\n# The DOTFILE_DIRS tag can be used to specify one or more directories that \r\n# contain dot files that are included in the documentation (see the \r\n# \\dotfile command).\r\n\r\nDOTFILE_DIRS           = \r\n\r\n# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will \r\n# generate a legend page explaining the meaning of the various boxes and \r\n# arrows in the dot generated graphs.\r\n\r\nGENERATE_LEGEND        = YES\r\n\r\n# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will \r\n# remove the intermedate dot files that are used to generate \r\n# the various graphs.\r\n\r\nDOT_CLEANUP            = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration::addtions related to the search engine   \r\n#---------------------------------------------------------------------------\r\n\r\n# The SEARCHENGINE tag specifies whether or not a search engine should be \r\n# used. If set to NO the values of all tags below this one will be ignored.\r\n\r\nSEARCHENGINE           = NO\r\n\r\n"
  },
  {
    "path": "deps/pjsip/pjmedia/docs/footer.html",
    "content": "<p>&nbsp;</p>\n<hr><center>\nPJMEDIA small footprint Open Source media stack<br>\nCopyright (C) 2006-2008 Teluu Inc.\n</center>\n<!--#include virtual=\"/footer.html\" -->\n</BODY>\n</HTML>\n"
  },
  {
    "path": "deps/pjsip/pjmedia/docs/header.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=iso-8859-1\">\n<title>$title ($projectnumber)</title>\n<link href=\"/style/style.css\" rel=\"stylesheet\" type=\"text/css\">\n</head><body>\n\t<!--#include virtual=\"/header.html\" -->\n\n\t<p><A HREF=\"/\">Home</A> --&gt; <A HREF=\"/docs.htm\">Documentations</A> --&gt; PJMEDIA Reference</p>\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/alaw_ulaw.h",
    "content": "/* $Id: alaw_ulaw.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_ALAW_ULAW_H__\n#define __PJMEDIA_ALAW_ULAW_H__\n\n#include <pjmedia/types.h>\n\nPJ_BEGIN_DECL\n\n#if defined(PJMEDIA_HAS_ALAW_ULAW_TABLE) && PJMEDIA_HAS_ALAW_ULAW_TABLE!=0\n\nextern const pj_uint8_t pjmedia_linear2ulaw_tab[16384];\nextern const pj_uint8_t pjmedia_linear2alaw_tab[16384];\nextern const pj_int16_t pjmedia_ulaw2linear_tab[256];\nextern const pj_int16_t pjmedia_alaw2linear_tab[256];\n\n\n/**\n * Convert 16-bit linear PCM value to 8-bit A-Law.\n *\n * @param pcm_val   16-bit linear PCM value.\n * @return\t    8-bit A-Law value.\n */\n#define pjmedia_linear2alaw(pcm_val)\t\\\n\t    pjmedia_linear2alaw_tab[(((pj_int16_t)pcm_val) >> 2) & 0x3fff]\n\n/**\n * Convert 8-bit A-Law value to 16-bit linear PCM value.\n *\n * @param chara_val 8-bit A-Law value.\n * @return\t    16-bit linear PCM value.\n */\n#define pjmedia_alaw2linear(chara_val)\t\\\n\t    pjmedia_alaw2linear_tab[chara_val]\n\n/**\n * Convert 16-bit linear PCM value to 8-bit U-Law.\n *\n * @param pcm_val   16-bit linear PCM value.\n * @return\t    U-bit A-Law value.\n */\n#define pjmedia_linear2ulaw(pcm_val)\t\\\n\t    pjmedia_linear2ulaw_tab[(((pj_int16_t)pcm_val) >> 2) & 0x3fff]\n\n/**\n * Convert 8-bit U-Law value to 16-bit linear PCM value.\n *\n * @param u_val\t    8-bit U-Law value.\n * @return\t    16-bit linear PCM value.\n */\n#define pjmedia_ulaw2linear(u_val)\t\\\n\t    pjmedia_ulaw2linear_tab[u_val]\n\n/**\n * Convert 8-bit A-Law value to 8-bit U-Law value.\n *\n * @param aval\t    8-bit A-Law value.\n * @return\t    8-bit U-Law value.\n */\n#define pjmedia_alaw2ulaw(aval)\t\t\\\n\t    pjmedia_linear2ulaw(pjmedia_alaw2linear(aval))\n\n/**\n * Convert 8-bit U-Law value to 8-bit A-Law value.\n *\n * @param uval\t    8-bit U-Law value.\n * @return\t    8-bit A-Law value.\n */\n#define pjmedia_ulaw2alaw(uval)\t\t\\\n\t    pjmedia_linear2alaw(pjmedia_ulaw2linear(uval))\n\n\n#else\n\n/**\n * Convert 16-bit linear PCM value to 8-bit A-Law.\n *\n * @param pcm_val   16-bit linear PCM value.\n * @return\t    8-bit A-Law value.\n */\nPJ_DECL(pj_uint8_t) pjmedia_linear2alaw(int pcm_val);\n\n/**\n * Convert 8-bit A-Law value to 16-bit linear PCM value.\n *\n * @param chara_val 8-bit A-Law value.\n * @return\t    16-bit linear PCM value.\n */\nPJ_DECL(int) pjmedia_alaw2linear(unsigned chara_val);\n\n/**\n * Convert 16-bit linear PCM value to 8-bit U-Law.\n *\n * @param pcm_val   16-bit linear PCM value.\n * @return\t    U-bit A-Law value.\n */\nPJ_DECL(unsigned char) pjmedia_linear2ulaw(int pcm_val);\n\n/**\n * Convert 8-bit U-Law value to 16-bit linear PCM value.\n *\n * @param u_val\t    8-bit U-Law value.\n * @return\t    16-bit linear PCM value.\n */\nPJ_DECL(int) pjmedia_ulaw2linear(unsigned char u_val);\n\n/**\n * Convert 8-bit A-Law value to 8-bit U-Law value.\n *\n * @param aval\t    8-bit A-Law value.\n * @return\t    8-bit U-Law value.\n */\nPJ_DECL(unsigned char) pjmedia_alaw2ulaw(unsigned char aval);\n\n/**\n * Convert 8-bit U-Law value to 8-bit A-Law value.\n *\n * @param uval\t    8-bit U-Law value.\n * @return\t    8-bit A-Law value.\n */\nPJ_DECL(unsigned char) pjmedia_ulaw2alaw(unsigned char uval);\n\n#endif\n\n/**\n * Encode 16-bit linear PCM data to 8-bit U-Law data.\n *\n * @param dst\t    Destination buffer for 8-bit U-Law data.\n * @param src\t    Source, 16-bit linear PCM data.\n * @param count\t    Number of samples.\n */\nPJ_INLINE(void) pjmedia_ulaw_encode(pj_uint8_t *dst, const pj_int16_t *src, \n\t\t\t\t    pj_size_t count)\n{\n    const pj_int16_t *end = src + count;\n    \n    while (src < end) {\n\t*dst++ = pjmedia_linear2ulaw(*src++);\n    }\n}\n\n/**\n * Encode 16-bit linear PCM data to 8-bit A-Law data.\n *\n * @param dst\t    Destination buffer for 8-bit A-Law data.\n * @param src\t    Source, 16-bit linear PCM data.\n * @param count\t    Number of samples.\n */\nPJ_INLINE(void) pjmedia_alaw_encode(pj_uint8_t *dst, const pj_int16_t *src, \n\t\t\t\t    pj_size_t count)\n{\n    const pj_int16_t *end = src + count;\n    \n    while (src < end) {\n\t*dst++ = pjmedia_linear2alaw(*src++);\n    }\n}\n\n/**\n * Decode 8-bit U-Law data to 16-bit linear PCM data.\n *\n * @param dst\t    Destination buffer for 16-bit PCM data.\n * @param src\t    Source, 8-bit U-Law data.\n * @param len\t    Encoded frame/source length in bytes.\n */\nPJ_INLINE(void) pjmedia_ulaw_decode(pj_int16_t *dst, const pj_uint8_t *src, \n\t\t\t\t    pj_size_t len)\n{\n    const pj_uint8_t *end = src + len;\n    \n    while (src < end) {\n\t*dst++ = pjmedia_ulaw2linear(*src++);\n    }\n}\n\n/**\n * Decode 8-bit A-Law data to 16-bit linear PCM data.\n *\n * @param dst\t    Destination buffer for 16-bit PCM data.\n * @param src\t    Source, 8-bit A-Law data.\n * @param len\t    Encoded frame/source length in bytes.\n */\nPJ_INLINE(void) pjmedia_alaw_decode(pj_int16_t *dst, const pj_uint8_t *src, \n\t\t\t\t    pj_size_t len)\n{\n    const pj_uint8_t *end = src + len;\n    \n    while (src < end) {\n\t*dst++ = pjmedia_alaw2linear(*src++);\n    }\n}\n\nPJ_END_DECL\n\n#endif\t/* __PJMEDIA_ALAW_ULAW_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/avi.h",
    "content": "/* $Id: avi.h 4058 2012-04-17 06:57:50Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_AVI_H__\n#define __PJMEDIA_AVI_H__\n\n\n/**\n * @file avi.h\n * @brief AVI file manipulation.\n */\n\n/**\n * @defgroup PJMEDIA_FILE_FORMAT File Formats\n * @brief Supported file formats\n */\n\n\n/**\n * @defgroup PJMEDIA_AVI AVI Header\n * @ingroup PJMEDIA_FILE_FORMAT\n * @brief Representation of RIFF/AVI file format\n * @{\n *\n * This the the low level representation of RIFF/AVI file format. For\n * higher abstraction, please see \\ref PJMEDIA_FILE_PLAY and \n * \\ref PJMEDIA_FILE_REC.\n */\n\n\nPJ_BEGIN_DECL\n\n#define PJMEDIA_AVI_MAX_NUM_STREAMS 4\n\nstatic const char avi_tags[][4] = {\n    { 'R', 'I', 'F', 'F' }, { 'A', 'V', 'I', ' ' },\n    { 'h', 'd', 'r', 'l' }, { 'a', 'v', 'i', 'h' },\n    { 's', 't', 'r', 'l' }, { 's', 't', 'r', 'h' },\n    { 'a', 'u', 'd', 's' }, { 'v', 'i', 'd', 's' },\n    { 's', 't', 'r', 'f' }, { 'm', 'o', 'v', 'i' },\n    { 'L', 'I', 'S', 'T' }, { 'J', 'U', 'N', 'K' },\n};\n\ntypedef enum {\n    PJMEDIA_AVI_RIFF_TAG = 0,\n    PJMEDIA_AVI_AVI_TAG,\n    PJMEDIA_AVI_HDRL_TAG,\n    PJMEDIA_AVI_AVIH_TAG,\n    PJMEDIA_AVI_STRL_TAG,\n    PJMEDIA_AVI_STRH_TAG,\n    PJMEDIA_AVI_AUDS_TAG,\n    PJMEDIA_AVI_VIDS_TAG,\n    PJMEDIA_AVI_STRF_TAG,\n    PJMEDIA_AVI_MOVI_TAG,\n    PJMEDIA_AVI_LIST_TAG,\n    PJMEDIA_AVI_JUNK_TAG,\n} pjmedia_avi_tag;\n\n\n/**\n * These types describe the simpler/canonical version of an AVI file.\n * They do not support the full AVI RIFF format specification.\n */\n#pragma pack(2)\n\n/** This structure describes RIFF AVI file header */\ntypedef struct riff_hdr_t {\n    pj_uint32_t riff;\t\t/**< \"RIFF\" ASCII tag.\t\t*/\n    pj_uint32_t file_len;       /**< File length minus 8 bytes\t*/\n    pj_uint32_t avi;\t\t/**< \"AVI\" ASCII tag.\t\t*/\n} riff_hdr_t;\n\n/** This structure describes avih header  */\ntypedef struct avih_hdr_t {\n    pj_uint32_t list_tag;\n    pj_uint32_t list_sz;\n    pj_uint32_t hdrl_tag;\n    pj_uint32_t avih;\n    pj_uint32_t size;\n    pj_uint32_t usec_per_frame;     /**< microsecs between frames   */\n    pj_uint32_t max_Bps;\n    pj_uint32_t pad;\n    pj_uint32_t flags;\n    pj_uint32_t tot_frames;\n    pj_uint32_t init_frames;\n    pj_uint32_t num_streams;\n    pj_uint32_t buf_size;\n    pj_uint32_t width;\n    pj_uint32_t height;\n    pj_uint32_t reserved[4];\n} avih_hdr_t;\n\n/** This structure describes strl header  */\ntypedef struct strl_hdr_t {\n    pj_uint32_t list_tag;\n    pj_uint32_t list_sz;\n    pj_uint32_t strl_tag;\n\n    pj_uint32_t strh;\n    pj_uint32_t strh_size;\n    pj_uint32_t data_type;\n    pj_uint32_t codec;\n    pj_uint32_t flags;\n    pj_uint32_t bogus_priority_language; /**< Do not access this data */\n    pj_uint32_t init_frames;\n    pj_uint32_t scale;\n    pj_uint32_t rate;\n    pj_uint32_t start;\n    pj_uint32_t length;\n    pj_uint32_t buf_size;\n    pj_uint32_t quality;\n    pj_uint32_t sample_size;\n    pj_uint32_t bogus_frame[2];          /**< Do not access this data */\n} strl_hdr_t;\n\ntypedef struct {\n    pj_uint32_t strf;\n    pj_uint32_t strf_size;\n    pj_uint16_t fmt_tag;\t    /**< 1 for PCM\t\t\t*/\n    pj_uint16_t nchannels;          /**< Number of channels.\t        */\n    pj_uint32_t sample_rate;\t    /**< Sampling rate.\t\t        */\n    pj_uint32_t bytes_per_sec;\t    /**< Average bytes per second.\t*/\n    pj_uint16_t block_align;\t    /**< nchannels * bits / 8\t        */\n    pj_uint16_t bits_per_sample;    /**< Bits per sample.\t\t*/\n    pj_uint16_t extra_size;\n} strf_audio_hdr_t;\n\n/**\n * Sizes of strf_audio_hdr_t struct, started by the size (in bytes) of\n * 32-bits struct members, alternated with the size of 16-bits members.\n */\nstatic const pj_uint8_t strf_audio_hdr_sizes [] = {8, 4, 8, 6};\n\ntypedef struct {\n    pj_uint32_t strf;\n    pj_uint32_t strf_size;\n    pj_uint32_t biSize; \n    pj_int32_t biWidth; \n    pj_int32_t biHeight; \n    pj_uint16_t biPlanes; \n    pj_uint16_t biBitCount;\n    pj_uint32_t biCompression; \n    pj_uint32_t biSizeImage; \n    pj_int32_t biXPelsPerMeter; \n    pj_int32_t biYPelsPerMeter; \n    pj_uint32_t biClrUsed; \n    pj_uint32_t biClrImportant; \n} strf_video_hdr_t;\n\nstatic const pj_uint8_t strf_video_hdr_sizes [] = {20, 4, 24};\n\nstruct pjmedia_avi_hdr\n{\n    riff_hdr_t  riff_hdr;\n    avih_hdr_t  avih_hdr;\n    strl_hdr_t  strl_hdr[PJMEDIA_AVI_MAX_NUM_STREAMS];\n    union {\n        strf_audio_hdr_t strf_audio_hdr;\n        strf_video_hdr_t strf_video_hdr;\n    } strf_hdr[PJMEDIA_AVI_MAX_NUM_STREAMS];\n};\n\n#pragma pack()\n\n/**\n * @see pjmedia_avi_hdr\n */\ntypedef struct pjmedia_avi_hdr pjmedia_avi_hdr;\n\n/**\n * This structure describes generic RIFF subchunk header.\n */\ntypedef struct pjmedia_avi_subchunk\n{\n    pj_uint32_t\t    id;\t\t\t/**< Subchunk ASCII tag.\t    */\n    pj_uint32_t\t    len;\t\t/**< Length following this field    */\n} pjmedia_avi_subchunk;\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_AVI_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/avi_stream.h",
    "content": "/* $Id: avi_stream.h 3715 2011-08-19 09:35:25Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_AVI_STREAM_H__\n#define __PJMEDIA_AVI_STREAM_H__\n\n/**\n * @file avi_stream.h\n * @brief AVI file player.\n */\n#include <pjmedia/port.h>\n\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJMEDIA_FILE_PLAY AVI File Player\n * @ingroup PJMEDIA_PORT\n * @brief Video and audio playback from AVI file\n * @{\n */\n\n/**\n * AVI file player options.\n */\nenum pjmedia_avi_file_player_option\n{\n    /**\n     * Tell the file player to return NULL frame when the whole\n     * file has been played.\n     */\n    PJMEDIA_AVI_FILE_NO_LOOP = 1\n};\n\n/**\n * AVI stream data type.\n */\ntypedef pjmedia_port pjmedia_avi_stream;\n\n/**\n * Opaque data type for AVI streams. AVI streams is a collection of\n * zero or more AVI stream.\n */\ntypedef struct pjmedia_avi_streams pjmedia_avi_streams;\n\n/**\n * Create avi streams to play an AVI file. AVI player supports \n * reading AVI file with uncompressed video format and \n * 16 bit PCM or compressed G.711 A-law/U-law audio format.\n *\n * @param pool\t\tPool to create the streams.\n * @param filename\tFile name to open.\n * @param flags\t\tAvi streams creation flags.\n * @param p_streams\tPointer to receive the avi streams instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t)\npjmedia_avi_player_create_streams(pj_pool_t *pool,\n                                  const char *filename,\n                                  unsigned flags,\n                                  pjmedia_avi_streams **p_streams);\n\n/**\n * Get the number of AVI stream.\n *\n * @param streams\tThe AVI streams.\n *\n * @return\t\tThe number of AVI stream.\n */\nPJ_DECL(unsigned)\npjmedia_avi_streams_get_num_streams(pjmedia_avi_streams *streams);\n\n/**\n * Return the idx-th stream of the AVI streams.\n *\n * @param streams\tThe AVI streams.\n * @param idx\t        The stream index.\n *\n * @return\t\tThe AVI stream or NULL if it does not exist.\n */\nPJ_DECL(pjmedia_avi_stream *)\npjmedia_avi_streams_get_stream(pjmedia_avi_streams *streams,\n                               unsigned idx);\n\n/**\n * Return an AVI stream with a certain media type from the AVI streams.\n *\n * @param streams\tThe AVI streams.\n * @param start_idx     The starting index.\n * @param media_type    The media type of the stream.\n *\n * @return\t\tThe AVI stream or NULL if it does not exist.\n */\nPJ_DECL(pjmedia_avi_stream *)\npjmedia_avi_streams_get_stream_by_media(pjmedia_avi_streams *streams,\n                                        unsigned start_idx,\n                                        pjmedia_type media_type);\n\n/**\n * Return the media port of an AVI stream.\n *\n * @param stream\tThe AVI stream.\n *\n * @return\t\tThe media port.\n */\nPJ_INLINE(pjmedia_port *)\npjmedia_avi_stream_get_port(pjmedia_avi_stream *stream)\n{\n    return (pjmedia_port *)stream;\n}\n\n/**\n * Get the data length, in bytes.\n *\n * @param stream        The AVI stream.\n *\n * @return\t\tThe length of the data, in bytes. Upon error it will\n *\t\t\treturn negative value.\n */\nPJ_DECL(pj_ssize_t) pjmedia_avi_stream_get_len(pjmedia_avi_stream *stream);\n\n\n/**\n * Register a callback to be called when the file reading has reached the\n * end of file. If the file is set to play repeatedly, then the callback\n * will be called multiple times. Note that only one callback can be \n * registered for each AVI stream.\n *\n * @param stream\tThe AVI stream.\n * @param user_data\tUser data to be specified in the callback\n * @param cb\t\tCallback to be called. If the callback returns non-\n *\t\t\tPJ_SUCCESS, the playback will stop. Note that if\n *\t\t\tapplication destroys the file port in the callback,\n *\t\t\tit must return non-PJ_SUCCESS here.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_avi_stream_set_eof_cb(pjmedia_avi_stream *stream,\n\t\t\t      void *user_data,\n\t\t\t      pj_status_t (*cb)(pjmedia_avi_stream *stream,\n\t\t\t\t\t        void *usr_data));\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_AVI_STREAM_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/bidirectional.h",
    "content": "/* $Id: bidirectional.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_BIDIRECTIONAL_H__\n#define __PJMEDIA_BIDIRECTIONAL_H__\n\n/**\n * @file bidirectional.h\n * @brief Bidirectional media port.\n */\n#include <pjmedia/port.h>\n\n\n/**\n * @defgroup PJMEDIA_BIDIRECTIONAL_PORT Bidirectional Port\n * @ingroup PJMEDIA_PORT\n * @brief A bidirectional port combines two unidirectional ports into one\n * bidirectional port\n * @{\n */\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * Create bidirectional port from two unidirectional ports\n *\n * @param pool\t\tPool to allocate memory.\n * @param get_port\tPort where get_frame() will be directed to.\n * @param put_port\tPort where put_frame() will be directed to.\n * @param p_port\tPointer to receive the port instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_bidirectional_port_create(pj_pool_t *pool,\n\t\t\t\t\t\t       pjmedia_port *get_port,\n\t\t\t\t\t\t       pjmedia_port *put_port,\n\t\t\t\t\t\t       pjmedia_port **p_port );\n\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_BIDIRECTIONAL_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/circbuf.h",
    "content": "/* $Id: circbuf.h 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#ifndef __PJMEDIA_CIRC_BUF_H__\n#define __PJMEDIA_CIRC_BUF_H__\n\n/**\n * @file circbuf.h\n * @brief Circular Buffer.\n */\n\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/pool.h>\n#include <pjmedia/frame.h>\n\n/**\n * @defgroup PJMED_CIRCBUF Circular Buffer\n * @ingroup PJMEDIA_FRAME_OP\n * @brief Circular buffer manages read and write contiguous audio samples in a \n * non-contiguous buffer as if the buffer were contiguous. This should give\n * better performance than keeping contiguous samples in a contiguous buffer,\n * since read/write operations will only update the pointers, instead of \n * shifting audio samples.\n *\n * @{\n *\n * This section describes PJMEDIA's implementation of circular buffer.\n */\n\n/* Algorithm checkings, for development purpose only */\n#if 0\n#   define PJMEDIA_CIRC_BUF_CHECK(x) pj_assert(x)\n#else\n#   define PJMEDIA_CIRC_BUF_CHECK(x)\n#endif\n\nPJ_BEGIN_DECL\n\n/** \n * Circular buffer structure\n */\ntypedef struct pjmedia_circ_buf {\n    pj_int16_t\t    *buf;\t    /**< The buffer\t\t\t*/\n    unsigned\t     capacity;\t    /**< Buffer capacity, in samples\t*/\n\n    pj_int16_t\t    *start;\t    /**< Pointer to the first sample\t*/\n    unsigned\t     len;\t    /**< Audio samples length, \n\t\t\t\t\t in samples\t\t\t*/\n} pjmedia_circ_buf;\n\n\n/**\n * Create the circular buffer.\n *\n * @param pool\t\t    Pool where the circular buffer will be allocated\n *\t\t\t    from.\n * @param capacity\t    Capacity of the buffer, in samples.\n * @param p_cb\t\t    Pointer to receive the circular buffer instance.\n *\n * @return\t\t    PJ_SUCCESS if the circular buffer has been\n *\t\t\t    created successfully, otherwise the appropriate\n *\t\t\t    error will be returned.\n */\nPJ_INLINE(pj_status_t) pjmedia_circ_buf_create(pj_pool_t *pool, \n\t\t\t\t\t       unsigned capacity, \n\t\t\t\t\t       pjmedia_circ_buf **p_cb)\n{\n    pjmedia_circ_buf *cbuf;\n\n    cbuf = PJ_POOL_ZALLOC_T(pool, pjmedia_circ_buf);\n    cbuf->buf = (pj_int16_t*) pj_pool_calloc(pool, capacity, \n\t\t\t\t\t     sizeof(pj_int16_t));\n    cbuf->capacity = capacity;\n    cbuf->start = cbuf->buf;\n    cbuf->len = 0;\n\n    *p_cb = cbuf;\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Reset the circular buffer.\n *\n * @param circbuf\t    The circular buffer.\n *\n * @return\t\t    PJ_SUCCESS when successful.\n */\nPJ_INLINE(pj_status_t) pjmedia_circ_buf_reset(pjmedia_circ_buf *circbuf)\n{\n    circbuf->start = circbuf->buf;\n    circbuf->len = 0;\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Get the circular buffer length, it is number of samples buffered in the \n * circular buffer.\n *\n * @param circbuf\t    The circular buffer.\n *\n * @return\t\t    The buffer length.\n */\nPJ_INLINE(unsigned) pjmedia_circ_buf_get_len(pjmedia_circ_buf *circbuf)\n{\n    return circbuf->len;\n}\n\n\n/**\n * Set circular buffer length. This is useful when audio buffer is manually \n * manipulated by the user, e.g: shrinked, expanded.\n *\n * @param circbuf\t    The circular buffer.\n * @param len\t\t    The new buffer length.\n */\nPJ_INLINE(void) pjmedia_circ_buf_set_len(pjmedia_circ_buf *circbuf,\n\t\t\t\t\t unsigned len)\n{\n    PJMEDIA_CIRC_BUF_CHECK(len <= circbuf->capacity);\n    circbuf->len = len;\n}\n\n\n/**\n * Advance the read pointer of circular buffer. This function will discard\n * the skipped samples while advancing the read pointer, thus reducing \n * the buffer length.\n *\n * @param circbuf\t    The circular buffer.\n * @param count\t\t    Distance from current read pointer, can only be\n *\t\t\t    possitive number, in samples.\n *\n * @return\t\t    PJ_SUCCESS when successful, otherwise \n *\t\t\t    the appropriate error will be returned.\n */\nPJ_INLINE(pj_status_t) pjmedia_circ_buf_adv_read_ptr(pjmedia_circ_buf *circbuf, \n\t\t\t\t\t\t     unsigned count)\n{\n    if (count >= circbuf->len)\n\treturn pjmedia_circ_buf_reset(circbuf);\n\n    PJMEDIA_CIRC_BUF_CHECK(count <= circbuf->len);\n\n    circbuf->start += count;\n    if (circbuf->start >= circbuf->buf + circbuf->capacity) \n\tcircbuf->start -= circbuf->capacity;\n    circbuf->len -= count;\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Advance the write pointer of circular buffer. Since write pointer is always\n * pointing to a sample after the end of sample, so this function also means\n * increasing the buffer length.\n *\n * @param circbuf\t    The circular buffer.\n * @param count\t\t    Distance from current write pointer, can only be\n *\t\t\t    possitive number, in samples.\n *\n * @return\t\t    PJ_SUCCESS when successful, otherwise \n *\t\t\t    the appropriate error will be returned.\n */\nPJ_INLINE(pj_status_t) pjmedia_circ_buf_adv_write_ptr(pjmedia_circ_buf *circbuf,\n\t\t\t\t\t\t      unsigned count)\n{\n    if (count + circbuf->len > circbuf->capacity)\n\treturn PJ_ETOOBIG;\n\n    circbuf->len += count;\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Get the real buffer addresses containing the audio samples.\n *\n * @param circbuf\t    The circular buffer.\n * @param reg1\t\t    Pointer to store the first buffer address.\n * @param reg1_len\t    Pointer to store the length of the first buffer, \n *\t\t\t    in samples.\n * @param reg2\t\t    Pointer to store the second buffer address.\n * @param reg2_len\t    Pointer to store the length of the second buffer, \n *\t\t\t    in samples.\n */\nPJ_INLINE(void) pjmedia_circ_buf_get_read_regions(pjmedia_circ_buf *circbuf, \n\t\t\t\t\t\t  pj_int16_t **reg1, \n\t\t\t\t\t\t  unsigned *reg1_len, \n\t\t\t\t\t\t  pj_int16_t **reg2, \n\t\t\t\t\t\t  unsigned *reg2_len)\n{\n    *reg1 = circbuf->start;\n    *reg1_len = circbuf->len;\n    if (*reg1 + *reg1_len > circbuf->buf + circbuf->capacity) {\n\t*reg1_len = (unsigned)(circbuf->buf + circbuf->capacity - \n\t\t\t       circbuf->start);\n\t*reg2 = circbuf->buf;\n\t*reg2_len = circbuf->len - *reg1_len;\n    } else {\n\t*reg2 = NULL;\n\t*reg2_len = 0;\n    }\n\n    PJMEDIA_CIRC_BUF_CHECK(*reg1_len != 0 || (*reg1_len == 0 && \n\t\t\t\t\t      circbuf->len == 0));\n    PJMEDIA_CIRC_BUF_CHECK(*reg1_len + *reg2_len == circbuf->len);\n}\n\n\n/**\n * Get the real buffer addresses that is empty or writeable.\n *\n * @param circbuf\t    The circular buffer.\n * @param reg1\t\t    Pointer to store the first buffer address.\n * @param reg1_len\t    Pointer to store the length of the first buffer, \n *\t\t\t    in samples.\n * @param reg2\t\t    Pointer to store the second buffer address.\n * @param reg2_len\t    Pointer to store the length of the second buffer, \n *\t\t\t    in samples.\n */\nPJ_INLINE(void) pjmedia_circ_buf_get_write_regions(pjmedia_circ_buf *circbuf, \n\t\t\t\t\t\t   pj_int16_t **reg1, \n\t\t\t\t\t\t   unsigned *reg1_len, \n\t\t\t\t\t\t   pj_int16_t **reg2, \n\t\t\t\t\t\t   unsigned *reg2_len)\n{\n    *reg1 = circbuf->start + circbuf->len;\n    if (*reg1 >= circbuf->buf + circbuf->capacity)\n\t*reg1 -= circbuf->capacity;\n    *reg1_len = circbuf->capacity - circbuf->len;\n    if (*reg1 + *reg1_len > circbuf->buf + circbuf->capacity) {\n\t*reg1_len = (unsigned)(circbuf->buf + circbuf->capacity - *reg1);\n\t*reg2 = circbuf->buf;\n\t*reg2_len = (unsigned)(circbuf->start - circbuf->buf);\n    } else {\n\t*reg2 = NULL;\n\t*reg2_len = 0;\n    }\n\n    PJMEDIA_CIRC_BUF_CHECK(*reg1_len != 0 || (*reg1_len == 0 && \n\t\t\t\t\t      circbuf->len == 0));\n    PJMEDIA_CIRC_BUF_CHECK(*reg1_len + *reg2_len == circbuf->capacity - \n\t\t\t   circbuf->len);\n}\n\n\n/**\n * Read audio samples from the circular buffer.\n *\n * @param circbuf\t    The circular buffer.\n * @param data\t\t    Buffer to store the read audio samples.\n * @param count\t\t    Number of samples being read.\n *\n * @return\t\t    PJ_SUCCESS when successful, otherwise \n *\t\t\t    the appropriate error will be returned.\n */\nPJ_INLINE(pj_status_t) pjmedia_circ_buf_read(pjmedia_circ_buf *circbuf, \n\t\t\t\t\t     pj_int16_t *data, \n\t\t\t\t\t     unsigned count)\n{\n    pj_int16_t *reg1, *reg2;\n    unsigned reg1cnt, reg2cnt;\n\n    /* Data in the buffer is less than requested */\n    if (count > circbuf->len)\n\treturn PJ_ETOOBIG;\n\n    pjmedia_circ_buf_get_read_regions(circbuf, &reg1, &reg1cnt, \n\t\t\t\t      &reg2, &reg2cnt);\n    if (reg1cnt >= count) {\n\tpjmedia_copy_samples(data, reg1, count);\n    } else {\n\tpjmedia_copy_samples(data, reg1, reg1cnt);\n\tpjmedia_copy_samples(data + reg1cnt, reg2, count - reg1cnt);\n    }\n\n    return pjmedia_circ_buf_adv_read_ptr(circbuf, count);\n}\n\n\n/**\n * Write audio samples to the circular buffer.\n *\n * @param circbuf\t    The circular buffer.\n * @param data\t\t    Audio samples to be written.\n * @param count\t\t    Number of samples being written.\n *\n * @return\t\t    PJ_SUCCESS when successful, otherwise\n *\t\t\t    the appropriate error will be returned.\n */\nPJ_INLINE(pj_status_t) pjmedia_circ_buf_write(pjmedia_circ_buf *circbuf, \n\t\t\t\t\t      pj_int16_t *data, \n\t\t\t\t\t      unsigned count)\n{\n    pj_int16_t *reg1, *reg2;\n    unsigned reg1cnt, reg2cnt;\n\n    /* Data to write is larger than buffer can store */\n    if (count > circbuf->capacity - circbuf->len)\n\treturn PJ_ETOOBIG;\n\n    pjmedia_circ_buf_get_write_regions(circbuf, &reg1, &reg1cnt, \n\t\t\t\t       &reg2, &reg2cnt);\n    if (reg1cnt >= count) {\n\tpjmedia_copy_samples(reg1, data, count);\n    } else {\n\tpjmedia_copy_samples(reg1, data, reg1cnt);\n\tpjmedia_copy_samples(reg2, data + reg1cnt, count - reg1cnt);\n    }\n\n    return pjmedia_circ_buf_adv_write_ptr(circbuf, count);\n}\n\n\n/**\n * Copy audio samples from the circular buffer without changing its state. \n *\n * @param circbuf\t    The circular buffer.\n * @param start_idx\t    Starting sample index to be copied.\n * @param data\t\t    Buffer to store the read audio samples.\n * @param count\t\t    Number of samples being read.\n *\n * @return\t\t    PJ_SUCCESS when successful, otherwise \n *\t\t\t    the appropriate error will be returned.\n */\nPJ_INLINE(pj_status_t) pjmedia_circ_buf_copy(pjmedia_circ_buf *circbuf, \n\t\t\t\t\t     unsigned start_idx,\n\t\t\t\t\t     pj_int16_t *data, \n\t\t\t\t\t     unsigned count)\n{\n    pj_int16_t *reg1, *reg2;\n    unsigned reg1cnt, reg2cnt;\n\n    /* Data in the buffer is less than requested */\n    if (count + start_idx > circbuf->len)\n\treturn PJ_ETOOBIG;\n\n    pjmedia_circ_buf_get_read_regions(circbuf, &reg1, &reg1cnt, \n\t\t\t\t      &reg2, &reg2cnt);\n    if (reg1cnt > start_idx) {\n\tunsigned tmp_len;\n\ttmp_len = reg1cnt - start_idx;\n\tif (tmp_len > count)\n\t    tmp_len = count;\n\tpjmedia_copy_samples(data, reg1 + start_idx, tmp_len);\n\tif (tmp_len < count)\n\t    pjmedia_copy_samples(data + tmp_len, reg2, count - tmp_len);\n    } else {\n\tpjmedia_copy_samples(data, reg2 + start_idx - reg1cnt, count);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Pack the buffer so the first sample will be in the beginning of the buffer.\n * This will also make the buffer contiguous.\n *\n * @param circbuf\t    The circular buffer.\n *\n * @return\t\t    PJ_SUCCESS when successful, otherwise \n *\t\t\t    the appropriate error will be returned.\n */\nPJ_INLINE(pj_status_t) pjmedia_circ_buf_pack_buffer(pjmedia_circ_buf *circbuf)\n{\n    pj_int16_t *reg1, *reg2;\n    unsigned reg1cnt, reg2cnt;\n    unsigned gap;\n\n    pjmedia_circ_buf_get_read_regions(circbuf, &reg1, &reg1cnt, \n\t\t\t\t      &reg2, &reg2cnt);\n\n    /* Check if not contigue */\n    if (reg2cnt != 0) {\n\t/* Check if no space left to roll the buffer \n\t * (or should this function provide temporary buffer?)\n\t */\n\tgap = circbuf->capacity - pjmedia_circ_buf_get_len(circbuf);\n\tif (gap == 0)\n\t    return PJ_ETOOBIG;\n\n\t/* Roll buffer left using the gap until reg2cnt == 0 */\n\tdo {\n\t    if (gap > reg2cnt)\n\t\tgap = reg2cnt;\n\t    pjmedia_move_samples(reg1 - gap, reg1, reg1cnt);\n\t    pjmedia_copy_samples(reg1 + reg1cnt - gap, reg2, gap);\n\t    if (gap < reg2cnt)\n\t\tpjmedia_move_samples(reg2, reg2 + gap, reg2cnt - gap);\n\t    reg1 -= gap;\n\t    reg1cnt += gap;\n\t    reg2cnt -= gap;\n\t} while (reg2cnt > 0);\n    }\n\n    /* Finally, Shift samples to the left edge */\n    if (reg1 != circbuf->buf)\n\tpjmedia_move_samples(circbuf->buf, reg1, \n\t\t\t     pjmedia_circ_buf_get_len(circbuf));\n    circbuf->start = circbuf->buf;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/clock.h",
    "content": "/* $Id: clock.h 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CLOCK_H__\n#define __PJMEDIA_CLOCK_H__\n\n/**\n * @file clock.h\n * @brief Media clock.\n */\n#include <pjmedia/types.h>\n\n\n/**\n * @defgroup PJMEDIA_PORT_CLOCK Clock/Timing\n * @ingroup PJMEDIA_PORT\n * @brief Various types of classes that provide timing.\n * @{\n\n The media clock/timing extends the media port concept that is explained \n in @ref PJMEDIA_PORT. When clock is present in the ports \n interconnection, media will flow automatically (and with correct timing too!)\n from one media port to another.\n \n There are few objects in PJMEDIA that are able to provide clock/timing\n to media ports interconnection:\n\n - @ref PJMED_SND_PORT\\n\n   The sound device makes a good candidate as the clock source, and\n   PJMEDIA @ref PJMED_SND is designed so that it is able to invoke\n   operations according to timing driven by the sound hardware clock\n   (this may sound complicated, but actually it just means that\n   the sound device abstraction provides callbacks to be called when\n   it has/wants media frames).\\n\n   See @ref PJMED_SND_PORT for more details.\n\n - @ref PJMEDIA_MASTER_PORT\\n\n   The master port uses @ref PJMEDIA_CLOCK as the clock source. By using\n   @ref PJMEDIA_MASTER_PORT, it is possible to interconnect passive\n   media ports and let the frames flow automatically in timely manner.\\n\n   Please see @ref PJMEDIA_MASTER_PORT for more details.\n\n @}\n */\n\n\n/**\n * @addtogroup PJMEDIA_CLOCK Clock Generator\n * @ingroup PJMEDIA_PORT_CLOCK\n * @brief Interface for generating clock.\n * @{\n * \n * The clock generator provides the application with media timing,\n * and it is used by the @ref PJMEDIA_MASTER_PORT for its sound clock.\n *\n * The clock generator may be configured to run <b>asynchronously</b> \n * (the default behavior) or <b>synchronously</b>. When it is run \n * asynchronously, it will call the application's callback every time\n * the clock <b>tick</b> expires. When it is run synchronously, \n * application must continuously polls the clock generator to synchronize\n * the timing.\n */\n\nPJ_BEGIN_DECL\n\n/**\n * Media clock source.\n */\ntypedef struct pjmedia_clock_src\n{\n    pjmedia_type    media_type;     /**< Media type.                */\n    unsigned        clock_rate;     /**< Clock rate.                */\n    unsigned        ptime_usec;     /**< Frame interval (in usec).  */\n    /**\n     * The timestamp field holds an increasing value in samples and its\n     * value is expected to be increased by clock_rate samples per second.\n     */\n    pj_timestamp    timestamp;\n    /**\n     * Timestamp's last update. The last_update field contains a value in\n     * ticks, and it is expected to be increased by pj_get_timestamp_freq()\n     * ticks per second.\n     */\n    pj_timestamp    last_update;\n} pjmedia_clock_src;\n\n/**\n * This is an auxiliary function to initialize the media clock source.\n *\n * @param clocksrc          The clock source to be initialized.\n * @param media_type        The media type.\n * @param clock_rate\t    The clock rate.\n * @param ptime_usec        Media frame interval (in usec).\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_clock_src_init( pjmedia_clock_src *clocksrc,\n                                             pjmedia_type media_type,\n                                             unsigned clock_rate,\n                                             unsigned ptime_usec );\n\n/**\n * This function updates the clock source's timestamp. Application should\n * use this function instead of updating the timestamp directly since this\n * function will also update the last_update field of the clock source.\n *\n * @param clocksrc          The clock source to be updated.\n * @param timestamp         The new timestamp, can be NULL if the current\n *                          timestamp does not change (in this case it\n *                          will only update the last_update field).\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_clock_src_update( pjmedia_clock_src *clocksrc,\n                                               const pj_timestamp *timestamp );\n\n/**\n * This function gets the clock source's current timestamp. Application\n * should use this function instead of accessing the timestamp directly\n * since this function will calculate the predicted timestamp for current\n * time, based on the values of timestamp, last_update, and clock_rate.\n *\n * @param clocksrc          The clock source.\n * @param timestamp         Argument to receive the current timestamp\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t)\npjmedia_clock_src_get_current_timestamp( const pjmedia_clock_src *clocksrc,\n                                         pj_timestamp *timestamp);\n\n/**\n * This function gets the clock source's time in msec.\n *\n * @param clocksrc          The clock source.\n *\n * @return\t\t    The clock source's time (in msec).\n */\nPJ_DECL(pj_uint32_t)\npjmedia_clock_src_get_time_msec( const pjmedia_clock_src *clocksrc );\n\n\n/**\n * Opaque declaration for media clock.\n */\ntypedef struct pjmedia_clock pjmedia_clock;\n\n\n/**\n * Options when creating the clock.\n */\nenum pjmedia_clock_options\n{\n    /**\n     * Prevents the clock from running asynchronously. In this case,\n     * application must poll the clock continuously by calling\n     * #pjmedia_clock_wait() in order to synchronize timing.\n     */\n    PJMEDIA_CLOCK_NO_ASYNC  = 1,\n\n    /**\n     * Prevent the clock from setting it's thread to highest priority.\n     */\n    PJMEDIA_CLOCK_NO_HIGHEST_PRIO = 2\n};\n\n\ntypedef struct pjmedia_clock_param\n{\n    /**\n     * The frame interval, in microseconds.\n     */\n    unsigned usec_interval;\n    /**\n     * The media clock rate, to determine timestamp\n     * increment for each call.\n     */\n    unsigned clock_rate;\n} pjmedia_clock_param;\n\n/**\n * Type of media clock callback.\n *\n * @param ts\t\t    Current timestamp, in samples.\n * @param user_data\t    Application data that is passed when\n *\t\t\t    the clock was created.\n */\ntypedef void pjmedia_clock_callback(const pj_timestamp *ts,\n\t\t\t\t    void *user_data);\n\n\n\n/**\n * Create media clock. This creates a media clock object that will run\n * periodically at an interval that is calculated from the audio parameters.\n * Once created, application must call #pjmedia_clock_start() to actually\n * start the clock.\n *\n * @see pjmedia_clock_create2()\n *\n * @param pool\t\t    Pool to allocate memory.\n * @param clock_rate\t    Number of samples per second.\n * @param channel_count\t    Number of channel.\n * @param samples_per_frame Number of samples per frame. This argument\n *\t\t\t    along with clock_rate and channel_count, specifies \n *\t\t\t    the interval of each clock run (or clock ticks).\n * @param options\t    Bitmask of pjmedia_clock_options.\n * @param cb\t\t    Callback to be called for each clock tick.\n * @param user_data\t    User data, which will be passed to the callback.\n * @param p_clock\t    Pointer to receive the clock instance.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error\n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) pjmedia_clock_create( pj_pool_t *pool,\n\t\t\t\t\t   unsigned clock_rate,\n\t\t\t\t\t   unsigned channel_count,\n\t\t\t\t\t   unsigned samples_per_frame,\n\t\t\t\t\t   unsigned options,\n\t\t\t\t\t   pjmedia_clock_callback *cb,\n\t\t\t\t\t   void *user_data,\n\t\t\t\t\t   pjmedia_clock **p_clock);\n\n\n/**\n * Create media clock. This creates a media clock object that will run\n * periodically at the specified interval. Once created, application must\n * call #pjmedia_clock_start() to actually start the clock.\n *\n * @param pool\t\t    Pool to allocate memory.\n * @param param\t            The clock parameter.\n * @param options\t    Bitmask of pjmedia_clock_options.\n * @param cb\t\t    Callback to be called for each clock tick.\n * @param user_data\t    User data, which will be passed to the callback.\n * @param p_clock\t    Pointer to receive the clock instance.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error\n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) pjmedia_clock_create2(pj_pool_t *pool,\n                                           const pjmedia_clock_param *param,\n\t\t\t\t\t   unsigned options,\n\t\t\t\t\t   pjmedia_clock_callback *cb,\n\t\t\t\t\t   void *user_data,\n\t\t\t\t\t   pjmedia_clock **p_clock);\n\n/**\n * Start the clock. For clock created with asynchronous flag set to TRUE,\n * this may start a worker thread for the clock (depending on the \n * backend clock implementation being used).\n *\n * @param clock\t\t    The media clock.\n *\n * @return\t\t    PJ_SUCCES on success.\n */\nPJ_DECL(pj_status_t) pjmedia_clock_start(pjmedia_clock *clock);\n\n\n/**\n * Stop the clock.\n *\n * @param clock\t\t    The media clock.\n *\n * @return\t\t    PJ_SUCCES on success.\n */\nPJ_DECL(pj_status_t) pjmedia_clock_stop(pjmedia_clock *clock);\n\n\n/**\n * Modify the clock's parameter.\n *\n * @param clock\t\t    The media clock.\n * @param param\t            The clock's new parameter.\n * @return\t\t    PJ_SUCCES on success.\n */\nPJ_DECL(pj_status_t) pjmedia_clock_modify(pjmedia_clock *clock,\n                                          const pjmedia_clock_param *param);\n\n\n/**\n * Poll the media clock, and execute the callback when the clock tick has\n * elapsed. This operation is only valid if the clock is created with async\n * flag set to FALSE.\n *\n * @param clock\t\t    The media clock.\n * @param wait\t\t    If non-zero, then the function will block until\n *\t\t\t    a clock tick elapsed and callback has been called.\n * @param ts\t\t    Optional argument to receive the current \n *\t\t\t    timestamp.\n *\n * @return\t\t    Non-zero if clock tick has elapsed, or FALSE if\n *\t\t\t    the function returns before a clock tick has\n *\t\t\t    elapsed.\n */\nPJ_DECL(pj_bool_t) pjmedia_clock_wait(pjmedia_clock *clock,\n\t\t\t\t      pj_bool_t wait,\n\t\t\t\t      pj_timestamp *ts);\n\n\n/**\n * Destroy the clock.\n *\n * @param clock\t\t    The media clock.\n *\n * @return\t\t    PJ_SUCCES on success.\n */\nPJ_DECL(pj_status_t) pjmedia_clock_destroy(pjmedia_clock *clock);\n\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_CLOCK_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/codec.h",
    "content": "/* $Id: codec.h 4278 2012-10-05 10:04:54Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODEC_H__\n#define __PJMEDIA_CODEC_H__\n\n\n/**\n * @file codec.h\n * @brief Codec framework.\n */\n\n#include <pjmedia/port.h>\n#include <pj/errno.h>\n#include <pj/list.h>\n#include <pj/pool.h>\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJMEDIA_CODEC Codec Framework\n * @brief Media codec framework and management\n * @{\n *\n * @section codec_mgmt_sec Codec Management\n * @subsection codec_fact_sec Codec Manager\n *\n * The codec manager is used to manage all codec capabilities in the endpoint.\n * When used with media endpoint (pjmedia_endpt), application can retrieve\n * the codec manager instance by calling #pjmedia_endpt_get_codec_mgr().\n *\n * @subsection reg_new_codec Registering New Codec\n *\n * New codec types can be registered to PJMEDIA (or to be precise, to the \n * codec manager) during run-time. \n * To do this, application needs to initialize an instance of\n * codec factory (#pjmedia_codec_factory) and registers this codec factory\n * by calling #pjmedia_codec_mgr_register_factory().\n *\n * For codecs implemented/supported by PJMEDIA, this process is normally\n * concealed in an easy to use function such as #pjmedia_codec_g711_init().\n *\n * @subsection codec_factory Codec Factory\n *\n * A codec factory (#pjmedia_codec_factory) is registered to codec manager, \n * and it is used to create and release codec instance.\n *\n * The most important member of the codec factory is the \"virtual\" function\n * table #pjmedia_codec_factory_op, where it contains, among other thing, \n * pointer to functions to allocate and deallocate codec instance.\n *\n * @subsection codec_inst Codec Instance\n *\n * Application allocates codec instance by calling #pjmedia_codec_mgr_alloc_codec().\n * One codec instance (#pjmedia_codec) can be used for simultaneous encoding\n * and decoding.\n *\n * The most important member of the codec instance is the \"virtual\" function\n * table #pjmedia_codec_op, where it holds pointer to functions to\n * encode/decode media frames.\n *\n * @subsection codec_ident Codec Identification\n *\n * A particular codec type in PJMEDIA can be uniquely identified by two\n * keys: by #pjmedia_codec_info, or by #pjmedia_codec_id string. A fully\n * qualified codec ID string consists of codec name, sampling rate, and\n * number of channels. However, application may use only first parts of\n * the tokens as long as it will make to codec ID unique. For example, \"gsm\"\n * is a fully qualified codec name, since it will always have 8000 clock\n * rate and 1 channel. Other examples of fully qualified codec ID strings\n * are \"pcma\", \"speex/8000\", \"speex/16000\", and \"L16/16000/1\". A codec\n * id \"speex\" (without clock rate) is not fully qualified, since it will\n * match the narrowband, wideband, and ultrawideband Speex codec.\n *\n * The two keys can be converted to one another, with\n * #pjmedia_codec_info_to_id() and #pjmedia_codec_mgr_find_codecs_by_id()\n * functions.\n *\n * Codec ID string is not case sensitive.\n *\n *\n * @section using_codec Using the Codec Framework\n * @subsection init_alloc_codec Allocating Codec\n *\n * Application needs to allocate one codec instance for encoding and decoding\n * media frames. One codec instance can be used to perform both encoding\n * and decoding.\n *\n * Application allocates codec by calling #pjmedia_codec_mgr_alloc_codec().\n * This function takes #pjmedia_codec_info argument, which is used to locate\n * the particular codec factory to be used to allocate the codec.\n *\n * Application can build #pjmedia_codec_info structure manually for\n * the specific codec, or alternatively it may get the #pjmedia_codec_info\n * from the codec ID string, by using #pjmedia_codec_mgr_find_codecs_by_id()\n * function.\n *\n * The following snippet shows an example to allocate a codec:\n *\n \\code\n    pj_str_t codec_id;\n    pjmedia_codec_info *codec_info;\n    unsigned count = 1;\n    pjmedia_codec *codec;\n\n    codec_id = pj_str(\"pcma\");\n\n    // Find codec info for the specified coded ID (i.e. \"pcma\").\n    status = pjmedia_codec_mgr_find_codecs_by_id( codec_mgr, &codec_id,\n\t\t\t\t\t\t  &count, &codec_info, NULL);\n\n    // Allocate the codec.\n    status = pjmedia_codec_mgr_alloc_codec( codec_mgr, codec_info, &codec );\n\n \\endcode\n *\n *\n * @subsection opening_codec Initializing Codec\n *\n * Once codec is allocated, application needs to initialize the codec\n * by calling <b><tt>open</tt></b> member of the codec. This function\n * takes #pjmedia_codec_param as the argument, which contains the\n * settings for the codec.\n *\n * Application shoud use #pjmedia_codec_mgr_get_default_param() function\n * to initiaize #pjmedia_codec_param. The <tt>setting</tt> part of\n * #pjmedia_codec_param then can be tuned to suit the application's\n * requirements.\n *\n * The following snippet shows an example to initialize codec:\n *\n \\code\n    pjmedia_codec_param param;\n\n    // Retrieve default codec param for the specified codec.\n    pjmedia_codec_mgr_get_default_param(codec_mgr, codec_info\n\t\t\t\t\t&param);\n\n    // Application may change the \"settings\" part of codec param,\n    // for example, to disable VAD\n    param.setting.vad = 0;\n\n    // Open the codec using the specified settings.\n    codec->op->open( codec, &param );\n\n \\endcode\n *\n *\n * @subsection enc_dec_codec Encoding and Decoding Media Frames\n *\n * Application encodes and decodes media frames by calling\n * <tt>encode</tt> and <tt>decode</tt> member of the codec's \"virtual\"\n * function table (#pjmedia_codec_op).\n *\n * @subsection plc_codec Concealing Lost Frames\n *\n * All codecs has Packet Lost Concealment (PLC) feature, and application\n * can activate the PLC to conceal lost frames by calling <tt>recover</tt>\n * member of the codec's \"virtual\" function table (#pjmedia_codec_op).\n *\n * If the codec's algorithm supports PLC, the <tt>recover</tt> function\n * will use the codec's PLC. Otherwise for codecs that don't have\n * intrinsic PLC, PJMEDIA will suply the PLC implementation from the\n * @ref PJMED_PLC implementation.\n *\n * @subsection close_codec Closing and Releasing the Codec\n *\n * The codec must be closed by calling <tt>close</tt> member of the codec's\n * operation. Then it must be released by calling \n * #pjmedia_codec_mgr_dealloc_codec().\n */\n\n\n/** \n * Standard RTP static payload types, as defined by RFC 3551. \n * The header file <pjmedia-codec/types.h> also declares dynamic payload\n * type numbers that are used by PJMEDIA when advertising the capability\n * for example in SDP message.\n */\nenum pjmedia_rtp_pt\n{\n    PJMEDIA_RTP_PT_PCMU = 0,\t    /**< audio PCMU\t\t\t    */\n    PJMEDIA_RTP_PT_G721 = 2,\t    /**< audio G721 (old def for G726-32)   */\n    PJMEDIA_RTP_PT_GSM  = 3,\t    /**< audio GSM\t\t\t    */\n    PJMEDIA_RTP_PT_G723 = 4,\t    /**< audio G723\t\t\t    */\n    PJMEDIA_RTP_PT_DVI4_8K = 5,\t    /**< audio DVI4 8KHz\t\t    */\n    PJMEDIA_RTP_PT_DVI4_16K = 6,    /**< audio DVI4 16Khz\t\t    */\n    PJMEDIA_RTP_PT_LPC = 7,\t    /**< audio LPC\t\t\t    */\n    PJMEDIA_RTP_PT_PCMA = 8,\t    /**< audio PCMA\t\t\t    */\n    PJMEDIA_RTP_PT_G722 = 9,\t    /**< audio G722\t\t\t    */\n    PJMEDIA_RTP_PT_L16_2 = 10,\t    /**< audio 16bit linear 44.1KHz stereo  */\n    PJMEDIA_RTP_PT_L16_1 = 11,\t    /**< audio 16bit linear 44.1KHz mono    */\n    PJMEDIA_RTP_PT_QCELP = 12,\t    /**< audio QCELP\t\t\t    */\n    PJMEDIA_RTP_PT_CN = 13,\t    /**< audio Comfort Noise\t\t    */\n    PJMEDIA_RTP_PT_MPA = 14,\t    /**< audio MPEG1/MPEG2 elemetr. streams */\n    PJMEDIA_RTP_PT_G728 = 15,\t    /**< audio G728\t\t\t    */\n    PJMEDIA_RTP_PT_DVI4_11K = 16,   /**< audio DVI4 11.025KHz mono\t    */\n    PJMEDIA_RTP_PT_DVI4_22K = 17,   /**< audio DVI4 22.050KHz mono\t    */\n    PJMEDIA_RTP_PT_G729 = 18,\t    /**< audio G729\t\t\t    */\n\n    PJMEDIA_RTP_PT_CELB = 25,\t    /**< video/comb Cell-B by Sun (RFC2029) */\n    PJMEDIA_RTP_PT_JPEG = 26,\t    /**< video JPEG\t\t\t    */\n    PJMEDIA_RTP_PT_NV = 28,\t    /**< video NV  by nv program by Xerox   */\n    PJMEDIA_RTP_PT_H261 = 31,\t    /**< video H261\t\t\t    */\n    PJMEDIA_RTP_PT_MPV = 32,\t    /**< video MPEG1 or MPEG2 elementary    */\n    PJMEDIA_RTP_PT_MP2T = 33,\t    /**< video MPEG2 transport\t\t    */\n    PJMEDIA_RTP_PT_H263 = 34,\t    /**< video H263\t\t\t    */\n\n    PJMEDIA_RTP_PT_DYNAMIC = 96     /**< start of dynamic RTP payload\t    */\n\n};\n\n\n/** \n * Identification used to search for codec factory that supports specific \n * codec specification. \n */\ntypedef struct pjmedia_codec_info\n{\n    pjmedia_type    type;\t    /**< Media type.\t\t\t*/\n    unsigned\t    pt;\t\t    /**< Payload type (can be dynamic). */\n    pj_str_t\t    encoding_name;  /**< Encoding name.\t\t\t*/\n    unsigned\t    clock_rate;\t    /**< Sampling rate.\t\t\t*/\n    unsigned\t    channel_cnt;    /**< Channel count.\t\t\t*/\n} pjmedia_codec_info;\n\n/** \n * Structure of codec specific parameters which contains name=value pairs.\n * The codec specific parameters are to be used with SDP according to \n * the standards (e.g: RFC 3555) in SDP 'a=fmtp' attribute.\n */\ntypedef struct pjmedia_codec_fmtp\n{\n    pj_uint8_t\t    cnt;\t    /**< Number of parameters.\t\t*/\n    struct param {\n\tpj_str_t    name;\t    /**< Parameter name.\t\t*/\n\tpj_str_t    val;\t    /**< Parameter value.\t\t*/\n    } param [PJMEDIA_CODEC_MAX_FMTP_CNT]; /**< The parameters.\t\t*/\n} pjmedia_codec_fmtp;\n\n/** \n * Detailed codec attributes used in configuring a codec and in querying\n * the capability of codec factories. Default attributes of any codecs could\n * be queried using #pjmedia_codec_mgr_get_default_param() and modified\n * using #pjmedia_codec_mgr_set_default_param().\n *\n * Please note that codec parameter also contains SDP specific setting, \n * #dec_fmtp and #enc_fmtp, which may need to be set appropriately based on\n * the effective setting. See each codec documentation for more detail.\n */\ntypedef struct pjmedia_codec_param\n{\n    /**\n     * The \"info\" part of codec param describes the capability of the codec,\n     * and the value should NOT be changed by application.\n     */\n    struct {\n       unsigned\t   clock_rate;\t\t/**< Sampling rate in Hz\t    */\n       unsigned\t   channel_cnt;\t\t/**< Channel count.\t\t    */\n       pj_uint32_t avg_bps;\t\t/**< Average bandwidth in bits/sec  */\n       pj_uint32_t max_bps;\t\t/**< Maximum bandwidth in bits/sec  */\n       unsigned    max_rx_frame_size;   /**< Maximum frame size             */\n       pj_uint16_t frm_ptime;\t\t/**< Decoder frame ptime in msec.   */\n       pj_uint16_t enc_ptime;\t\t/**< Encoder ptime, or zero if it's\n\t\t\t\t\t     equal to decoder ptime.\t    */\n       pj_uint8_t  pcm_bits_per_sample;\t/**< Bits/sample in the PCM side    */\n       pj_uint8_t  pt;\t\t\t/**< Payload type.\t\t    */\n       pjmedia_format_id fmt_id;\t/**< Source format, it's format of\n\t\t\t\t\t     encoder input and decoder \n\t\t\t\t\t     output.\t\t\t    */\n    } info;\n\n    /**\n     * The \"setting\" part of codec param describes various settings to be\n     * applied to the codec. When the codec param is retrieved from the codec\n     * or codec factory, the values of these will be filled by the capability\n     * of the codec. Any features that are supported by the codec (e.g. vad\n     * or plc) will be turned on, so that application can query which \n     * capabilities are supported by the codec. Application may change the\n     * settings here before instantiating the codec/stream.\n     */\n    struct {\n\tpj_uint8_t  frm_per_pkt;    /**< Number of frames per packet.\t*/\n\tunsigned    vad:1;\t    /**< Voice Activity Detector.\t*/\n\tunsigned    cng:1;\t    /**< Comfort Noise Generator.\t*/\n\tunsigned    penh:1;\t    /**< Perceptual Enhancement\t\t*/\n\tunsigned    plc:1;\t    /**< Packet loss concealment\t*/\n\tunsigned    reserved:1;\t    /**< Reserved, must be zero.\t*/\n\tpjmedia_codec_fmtp enc_fmtp;/**< Encoder's fmtp params.\t\t*/\n\tpjmedia_codec_fmtp dec_fmtp;/**< Decoder's fmtp params.\t\t*/\n    } setting;\n} pjmedia_codec_param;\n\n\n/**\n * Duplicate codec parameter.\n *\n * @param pool\t    The pool.\n * @param src\t    The codec parameter to be duplicated.\n *\n * @return\t    Duplicated codec parameter.\n */\nPJ_DECL(pjmedia_codec_param*) pjmedia_codec_param_clone(\n\t\t\t\t\tpj_pool_t *pool, \n\t\t\t\t\tconst pjmedia_codec_param *src);\n\n\n/*\n * Forward declaration for pjmedia_codec.\n */\ntypedef struct pjmedia_codec pjmedia_codec;\n\n\n/**\n * This structure describes codec operations. Each codec MUST implement\n * all of these functions.\n */\ntypedef struct pjmedia_codec_op\n{\n    /** \n     * Initialize codec using the specified attribute.\n     *\n     * Application should call #pjmedia_codec_init() instead of \n     * calling this function directly.\n     *\n     * @param codec\tThe codec instance.\n     * @param pool\tPool to use when the codec needs to allocate\n     *\t\t\tsome memory.\n     *\n     * @return\t\tPJ_SUCCESS on success.\n     */\n    pj_status_t\t(*init)(pjmedia_codec *codec, \n\t\t\tpj_pool_t *pool );\n\n    /** \n     * Open the codec and initialize with the specified parameter.\n     * Upon successful initialization, the codec may modify the parameter\n     * and fills in the unspecified values (such as enc_ptime, when\n     * encoder ptime is different than decoder ptime).\n     *\n     * Application should call #pjmedia_codec_open() instead of \n     * calling this function directly.\n     *\n     * @param codec\tThe codec instance.\n     * @param param\tCodec initialization parameter.\n     *\n     * @return\t\tPJ_SUCCESS on success.\n     */\n    pj_status_t\t(*open)(pjmedia_codec *codec, \n\t\t\tpjmedia_codec_param *param );\n\n    /** \n     * Close and shutdown codec, releasing all resources allocated by\n     * this codec, if any.\n     *\n     * Application should call #pjmedia_codec_close() instead of \n     * calling this function directly.\n     *\n     * @param codec\tThe codec instance.\n     *\n     * @return\t\tPJ_SUCCESS on success.\n     */\n    pj_status_t (*close)(pjmedia_codec *codec);\n\n    /** \n     * Modify the codec parameter after the codec is open. \n     * Note that not all codec parameters can be modified during run-time. \n     * When the parameter cannot be changed, this function will return \n     * non-PJ_SUCCESS, and the original parameters will not be changed.\n     *\n     * Application can expect changing trivial codec settings such as\n     * changing VAD setting to succeed.\n     *\n     * Application should call #pjmedia_codec_modify() instead of \n     * calling this function directly.\n     *\n     * @param codec\tThe codec instance.\n     * @param param\tThe new codec parameter.\n     *\n     * @return\t\tPJ_SUCCESS on success.\n     */\n    pj_status_t\t(*modify)(pjmedia_codec *codec, \n\t\t\t  const pjmedia_codec_param *param );\n\n    /**\n     * Instruct the codec to inspect the specified payload/packet and\n     * split the packet into individual base frames. Each output frames will\n     * have ptime that is equal to basic frame ptime (i.e. the value of\n     * info.frm_ptime in #pjmedia_codec_param).\n     *\n     * Application should call #pjmedia_codec_parse() instead of \n     * calling this function directly.\n     *\n     * @param codec\tThe codec instance\n     * @param pkt\tThe input packet.\n     * @param pkt_size\tSize of the packet.\n     * @param timestamp\tThe timestamp of the first sample in the packet.\n     * @param frame_cnt\tOn input, specifies the maximum number of frames\n     *\t\t\tin the array. On output, the codec must fill\n     *\t\t\twith number of frames detected in the packet.\n     * @param frames\tOn output, specifies the frames that have been\n     *\t\t\tdetected in the packet.\n     *\n     * @return\t\tPJ_SUCCESS on success.\n     */\n    pj_status_t (*parse)( pjmedia_codec *codec,\n\t\t\t  void *pkt,\n\t\t\t  pj_size_t pkt_size,\n\t\t\t  const pj_timestamp *timestamp,\n\t\t\t  unsigned *frame_cnt,\n\t\t\t  pjmedia_frame frames[]);\n\n    /** \n     * Instruct the codec to encode the specified input frame. The input\n     * PCM samples MUST have ptime that is multiplication of base frame\n     * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param).\n     *\n     * Application should call #pjmedia_codec_encode() instead of \n     * calling this function directly.\n     *\n     * @param codec\tThe codec instance.\n     * @param input\tThe input frame.\n     * @param out_size\tThe length of buffer in the output frame.\n     * @param output\tThe output frame.\n     *\n     * @return\t\tPJ_SUCCESS on success;\n     */\n    pj_status_t (*encode)(pjmedia_codec *codec, \n\t\t\t  const struct pjmedia_frame *input,\n\t\t\t  unsigned out_size, \n\t\t\t  struct pjmedia_frame *output);\n\n    /** \n     * Instruct the codec to decode the specified input frame. The input\n     * frame MUST have ptime that is exactly equal to base frame\n     * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param).\n     * Application can achieve this by parsing the packet into base\n     * frames before decoding each frame.\n     *\n     * Application should call #pjmedia_codec_decode() instead of \n     * calling this function directly.\n     *\n     * @param codec\tThe codec instance.\n     * @param input\tThe input frame.\n     * @param out_size\tThe length of buffer in the output frame.\n     * @param output\tThe output frame.\n     *\n     * @return\t\tPJ_SUCCESS on success;\n     */\n    pj_status_t (*decode)(pjmedia_codec *codec, \n\t\t\t  const struct pjmedia_frame *input,\n\t\t\t  unsigned out_size, \n\t\t\t  struct pjmedia_frame *output);\n\n    /**\n     * Instruct the codec to recover a missing frame.\n     *\n     * Application should call #pjmedia_codec_recover() instead of \n     * calling this function directly.\n     *\n     * @param codec\tThe codec instance.\n     * @param out_size\tThe length of buffer in the output frame.\n     * @param output\tThe output frame where generated signal\n     *\t\t\twill be placed.\n     *\n     * @return\t\tPJ_SUCCESS on success;\n     */\n    pj_status_t (*recover)(pjmedia_codec *codec,\n\t\t\t   unsigned out_size,\n\t\t\t   struct pjmedia_frame *output);\n} pjmedia_codec_op;\n\n\n\n/*\n * Forward declaration for pjmedia_codec_factory.\n */\ntypedef struct pjmedia_codec_factory pjmedia_codec_factory;\n\n\n/**\n * This structure describes a codec instance. \n */\nstruct pjmedia_codec\n{\n    /** Entries to put this codec instance in codec factory's list. */\n    PJ_DECL_LIST_MEMBER(struct pjmedia_codec);\n\n    /** Codec's private data. */\n    void\t\t    *codec_data;\n\n    /** Codec factory where this codec was allocated. */\n    pjmedia_codec_factory   *factory;\n\n    /** Operations to codec. */\n    pjmedia_codec_op\t    *op;\n};\n\n\n\n/**\n * This structure describes operations that must be supported by codec \n * factories.\n */\ntypedef struct pjmedia_codec_factory_op\n{\n    /** \n     * Check whether the factory can create codec with the specified \n     * codec info.\n     *\n     * @param factory\tThe codec factory.\n     * @param info\tThe codec info.\n     *\n     * @return\t\tPJ_SUCCESS if this factory is able to create an\n     *\t\t\tinstance of codec with the specified info.\n     */\n    pj_status_t\t(*test_alloc)(pjmedia_codec_factory *factory, \n\t\t\t      const pjmedia_codec_info *info );\n\n    /** \n     * Create default attributes for the specified codec ID. This function\n     * can be called by application to get the capability of the codec.\n     *\n     * @param factory\tThe codec factory.\n     * @param info\tThe codec info.\n     * @param attr\tThe attribute to be initialized.\n     *\n     * @return\t\tPJ_SUCCESS if success.\n     */\n    pj_status_t (*default_attr)(pjmedia_codec_factory *factory, \n    \t\t\t\tconst pjmedia_codec_info *info,\n    \t\t\t\tpjmedia_codec_param *attr );\n\n    /** \n     * Enumerate supported codecs that can be created using this factory.\n     * \n     *  @param factory\tThe codec factory.\n     *  @param count\tOn input, specifies the number of elements in\n     *\t\t\tthe array. On output, the value will be set to\n     *\t\t\tthe number of elements that have been initialized\n     *\t\t\tby this function.\n     *  @param info\tThe codec info array, which contents will be \n     *\t\t\tinitialized upon return.\n     *\n     *  @return\t\tPJ_SUCCESS on success.\n     */\n    pj_status_t (*enum_info)(pjmedia_codec_factory *factory, \n\t\t\t     unsigned *count, \n\t\t\t     pjmedia_codec_info codecs[]);\n\n    /** \n     * Create one instance of the codec with the specified codec info.\n     *\n     * @param factory\tThe codec factory.\n     * @param info\tThe codec info.\n     * @param p_codec\tPointer to receive the codec instance.\n     *\n     * @return\t\tPJ_SUCCESS on success.\n     */\n    pj_status_t (*alloc_codec)(pjmedia_codec_factory *factory, \n\t\t\t       const pjmedia_codec_info *info,\n\t\t\t       pjmedia_codec **p_codec);\n\n    /** \n     * This function is called by codec manager to return a particular \n     * instance of codec back to the codec factory.\n     *\n     * @param factory\tThe codec factory.\n     * @param codec\tThe codec instance to be returned.\n     *\n     * @return\t\tPJ_SUCCESS on success.\n     */\n    pj_status_t (*dealloc_codec)(pjmedia_codec_factory *factory, \n\t\t\t\t pjmedia_codec *codec );\n\n    /**\n     * This callback will be called to deinitialize and destroy this factory.\n     */\n    pj_status_t (*destroy)(void);\n\n} pjmedia_codec_factory_op;\n\n\n\n/**\n * Codec factory describes a module that is able to create codec with specific\n * capabilities. These capabilities can be queried by codec manager to create\n * instances of codec.\n */\nstruct pjmedia_codec_factory\n{\n    /** Entries to put this structure in the codec manager list. */\n    PJ_DECL_LIST_MEMBER(struct pjmedia_codec_factory);\n\n    /** The factory's private data. */\n    void\t\t     *factory_data;\n\n    /** Operations to the factory. */\n    pjmedia_codec_factory_op *op;\n\n};\n\n\n/**\n * Declare maximum codecs\n */\n#define PJMEDIA_CODEC_MGR_MAX_CODECS\t    32\n\n\n/**\n * Specify these values to set the codec priority, by calling\n * #pjmedia_codec_mgr_set_codec_priority().\n */\ntypedef enum pjmedia_codec_priority\n{\n    /**\n     * This priority makes the codec the highest in the order.\n     * The last codec specified with this priority will get the\n     * highest place in the order, and will change the priority\n     * of previously highest priority codec to NEXT_HIGHER.\n     */\n    PJMEDIA_CODEC_PRIO_HIGHEST = 255,\n\n    /**\n     * This priority will put the codec as the next codec after\n     * codecs with this same priority.\n     */\n    PJMEDIA_CODEC_PRIO_NEXT_HIGHER = 254,\n\n    /**\n     * This is the initial codec priority when it is registered to\n     * codec manager by codec factory.\n     */\n    PJMEDIA_CODEC_PRIO_NORMAL = 128,\n\n    /**\n     * This priority makes the codec the lowest in the order.\n     * The last codec specified with this priority will be put\n     * in the last place in the order.\n     */\n    PJMEDIA_CODEC_PRIO_LOWEST = 1,\n\n    /**\n     * This priority will prevent the codec from being listed in the\n     * SDP created by media endpoint, thus should prevent the codec\n     * from being used in the sessions. However, the codec will still\n     * be listed by #pjmedia_codec_mgr_enum_codecs() and other codec\n     * query functions.\n     */\n    PJMEDIA_CODEC_PRIO_DISABLED = 0\n\n} pjmedia_codec_priority;\n\n\n/** \n * Codec identification (e.g. \"pcmu/8000/1\").\n * See @ref codec_ident for more info.\n */\ntypedef char pjmedia_codec_id[32];\n\n\n/**\n * Opaque declaration of default codecs parameters.\n */\ntypedef struct pjmedia_codec_default_param pjmedia_codec_default_param;\n\n/** \n * Codec manager maintains array of these structs for each supported\n * codec.\n */\nstruct pjmedia_codec_desc\n{\n    pjmedia_codec_info\t    info;\t/**< Codec info.\t    */\n    pjmedia_codec_id\t    id;\t\t/**< Fully qualified name   */\n    pjmedia_codec_priority  prio;\t/**< Priority.\t\t    */\n    pjmedia_codec_factory  *factory;\t/**< The factory.\t    */\n    pjmedia_codec_default_param *param; /**< Default codecs \n\t\t\t\t\t     parameters.\t    */\n};\n\n\n/**\n * The declaration for codec manager. Application doesn't normally need\n * to see this declaration, but nevertheless this declaration is needed\n * by media endpoint to instantiate the codec manager.\n */\ntypedef struct pjmedia_codec_mgr\n{\n    /** Media endpoint instance. */\n    pj_pool_factory\t\t*pf;\n\n    /** Codec manager pool. */\n    pj_pool_t\t\t\t*pool;\n\n    /** Codec manager mutex. */\n    pj_mutex_t\t\t\t*mutex;\n\n    /** List of codec factories registered to codec manager. */\n    pjmedia_codec_factory\t factory_list;\n\n    /** Number of supported codecs. */\n    unsigned\t\t\t codec_cnt;\n\n    /** Array of codec descriptor. */\n    struct pjmedia_codec_desc\t codec_desc[PJMEDIA_CODEC_MGR_MAX_CODECS];\n\n} pjmedia_codec_mgr;\n\n\n\n/**\n * Initialize codec manager. Normally this function is called by pjmedia\n * endpoint's initialization code.\n *\n * @param mgr\t    Codec manager instance.\n * @param pf\t    Pool factory instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_mgr_init(pjmedia_codec_mgr *mgr, \n\t\t\t\t\t    pj_pool_factory *pf);\n\n\n/**\n * Destroy codec manager. Normally this function is called by pjmedia\n * endpoint's deinitialization code.\n *\n * @param mgr\t    Codec manager instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_mgr_destroy(pjmedia_codec_mgr *mgr);\n\n\n/** \n * Register codec factory to codec manager. This will also register\n * all supported codecs in the factory to the codec manager.\n *\n * @param mgr\t    The codec manager instance. Application can get the\n *\t\t    instance by calling #pjmedia_endpt_get_codec_mgr().\n * @param factory   The codec factory to be registered.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_codec_mgr_register_factory( pjmedia_codec_mgr *mgr,\n\t\t\t\t    pjmedia_codec_factory *factory);\n\n/**\n * Unregister codec factory from the codec manager. This will also\n * remove all the codecs registered by the codec factory from the\n * codec manager's list of supported codecs. This function should\n * only be called by the codec implementers and not by application.\n *\n * @param mgr\t    The codec manager instance, use\n * \t\t\t#pjmedia_endpt_get_codec_mgr().\n * @param factory   The codec factory to be unregistered.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_codec_mgr_unregister_factory( pjmedia_codec_mgr *mgr, \n\t\t\t\t      pjmedia_codec_factory *factory);\n\n/**\n * Enumerate all supported codecs that have been registered to the\n * codec manager by codec factories.\n *\n * @param mgr\t    The codec manager instance. Application can get the\n *\t\t    instance by calling #pjmedia_endpt_get_codec_mgr().\n * @param count\t    On input, specifies the number of elements in\n *\t\t    the array. On output, the value will be set to\n *\t\t    the number of elements that have been initialized\n *\t\t    by this function.\n * @param info\t    The codec info array, which contents will be \n *\t\t    initialized upon return.\n * @param prio\t    Optional pointer to receive array of codec priorities.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_mgr_enum_codecs( pjmedia_codec_mgr *mgr, \n\t\t\t\t\t\t    unsigned *count, \n\t\t\t\t\t\t    pjmedia_codec_info info[],\n\t\t\t\t\t\t    unsigned *prio);\n\n/**\n * Get codec info for the specified static payload type. Note that\n * this can only find codec with static payload types. This function can\n * be used to find codec info for a payload type inside SDP which doesn't\n * have the corresponding rtpmap attribute.\n *\n * @param mgr\t    The codec manager instance. Application can get the\n *\t\t    instance by calling #pjmedia_endpt_get_codec_mgr().\n * @param pt\t    Static payload type/number.\n * @param inf\t    Pointer to receive codec info.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_codec_mgr_get_codec_info( pjmedia_codec_mgr *mgr,\n\t\t\t\t  unsigned pt,\n\t\t\t\t  const pjmedia_codec_info **inf);\n\n/**\n * Convert codec info struct into a unique codec identifier.\n * A codec identifier looks something like \"L16/44100/2\".\n *\n * @param info\t    The codec info\n * @param id\t    Buffer to put the codec info string.\n * @param max_len   The length of the buffer.\n *\n * @return\t    The null terminated codec info string, or NULL if\n *\t\t    the buffer is not long enough.\n */\nPJ_DECL(char*) pjmedia_codec_info_to_id(const pjmedia_codec_info *info,\n\t\t\t\t        char *id, unsigned max_len );\n\n\n/**\n * Find codecs by the unique codec identifier. This function will find\n * all codecs that match the codec identifier prefix. For example, if\n * \"L16\" is specified, then it will find \"L16/8000/1\", \"L16/16000/1\",\n * and so on, up to the maximum count specified in the argument.\n *\n * @param mgr\t    The codec manager instance. Application can get the\n *\t\t    instance by calling #pjmedia_endpt_get_codec_mgr().\n * @param codec_id  The full codec ID or codec ID prefix. If an empty\n *\t\t    string is given, it will match all codecs.\n * @param count\t    Maximum number of codecs to find. On return, it\n *\t\t    contains the actual number of codecs found.\n * @param p_info    Array of pointer to codec info to be filled. This\n *\t\t    argument may be NULL, which in this case, only\n *\t\t    codec count will be returned.\n * @param prio\t    Optional array of codec priorities.\n *\n * @return\t    PJ_SUCCESS if at least one codec info is found.\n */\nPJ_DECL(pj_status_t) \npjmedia_codec_mgr_find_codecs_by_id( pjmedia_codec_mgr *mgr,\n\t\t\t\t     const pj_str_t *codec_id,\n\t\t\t\t     unsigned *count,\n\t\t\t\t     const pjmedia_codec_info *p_info[],\n\t\t\t\t     unsigned prio[]);\n\n\n/**\n * Set codec priority. The codec priority determines the order of\n * the codec in the SDP created by the endpoint. If more than one codecs\n * are found with the same codec_id prefix, then the function sets the\n * priorities of all those codecs.\n *\n * @param mgr\t    The codec manager instance. Application can get the\n *\t\t    instance by calling #pjmedia_endpt_get_codec_mgr().\n * @param codec_id  The full codec ID or codec ID prefix. If an empty\n *\t\t    string is given, it will match all codecs.\n * @param prio\t    Priority to be set. The priority can have any value\n *\t\t    between 1 to 255. When the priority is set to zero,\n *\t\t    the codec will be disabled.\n *\n * @return\t    PJ_SUCCESS if at least one codec info is found.\n */\nPJ_DECL(pj_status_t)\npjmedia_codec_mgr_set_codec_priority(pjmedia_codec_mgr *mgr, \n\t\t\t\t     const pj_str_t *codec_id,\n\t\t\t\t     pj_uint8_t prio);\n\n\n/**\n * Get default codec param for the specified codec info.\n *\n * @param mgr\t    The codec manager instance. Application can get the\n *\t\t    instance by calling #pjmedia_endpt_get_codec_mgr().\n * @param info\t    The codec info, which default parameter's is being\n *\t\t    queried.\n * @param param\t    On return, will be filled with the default codec\n *\t\t    parameter.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_codec_mgr_get_default_param( pjmedia_codec_mgr *mgr,\n\t\t\t\t     const pjmedia_codec_info *info,\n\t\t\t\t     pjmedia_codec_param *param );\n\n\n/**\n * Set default codec param for the specified codec info.\n *\n * @param mgr\t    The codec manager instance. Application can get the\n *\t\t    instance by calling #pjmedia_endpt_get_codec_mgr().\n * @param info\t    The codec info, which default parameter's is being\n *\t\t    updated.\n * @param param\t    The new default codec parameter. Set to NULL to reset\n *\t\t    codec parameter to library default settings.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_codec_mgr_set_default_param( pjmedia_codec_mgr *mgr,\n\t\t\t\t     const pjmedia_codec_info *info,\n\t\t\t\t     const pjmedia_codec_param *param );\n\n\n/**\n * Request the codec manager to allocate one instance of codec with the\n * specified codec info. The codec will enumerate all codec factories\n * until it finds factory that is able to create the specified codec.\n *\n * @param mgr\t    The codec manager instance. Application can get the\n *\t\t    instance by calling #pjmedia_endpt_get_codec_mgr().\n * @param info\t    The information about the codec to be created.\n * @param p_codec   Pointer to receive the codec instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_codec_mgr_alloc_codec( pjmedia_codec_mgr *mgr, \n\t\t\t       const pjmedia_codec_info *info,\n\t\t\t       pjmedia_codec **p_codec);\n\n/**\n * Deallocate the specified codec instance. The codec manager will return\n * the instance of the codec back to its factory.\n *\n * @param mgr\t    The codec manager instance. Application can get the\n *\t\t    instance by calling #pjmedia_endpt_get_codec_mgr().\n * @param codec\t    The codec instance.\n *\n * @return\t    PJ_SUCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_mgr_dealloc_codec(pjmedia_codec_mgr *mgr, \n\t\t\t\t\t\t     pjmedia_codec *codec);\n\n\n\n/** \n * Initialize codec using the specified attribute.\n *\n * @param codec\t    The codec instance.\n * @param pool\t    Pool to use when the codec needs to allocate some memory.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_INLINE(pj_status_t) pjmedia_codec_init( pjmedia_codec *codec, \n\t\t\t\t\t   pj_pool_t *pool )\n{\n    return (*codec->op->init)(codec, pool);\n}\n\n\n/** \n * Open the codec and initialize with the specified parameter.\n * Upon successful initialization, the codec may modify the parameter\n * and fills in the unspecified values (such as enc_ptime, when\n * encoder ptime is different than decoder ptime).\n *\n * @param codec\t    The codec instance.\n * @param param\t    Codec initialization parameter.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_INLINE(pj_status_t) pjmedia_codec_open( pjmedia_codec *codec, \n\t\t\t\t\t   pjmedia_codec_param *param )\n{\n    return (*codec->op->open)(codec, param);\n}\n\n\n/** \n * Close and shutdown codec, releasing all resources allocated by\n * this codec, if any.\n *\n * @param codec\t    The codec instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_INLINE(pj_status_t) pjmedia_codec_close( pjmedia_codec *codec )\n{\n    return (*codec->op->close)(codec);\n}\n\n\n/** \n * Modify the codec parameter after the codec is open. \n * Note that not all codec parameters can be modified during run-time. \n * When the parameter cannot be changed, this function will return \n * non-PJ_SUCCESS, and the original parameters will not be changed.\n *\n * Application can expect changing trivial codec settings such as\n * changing VAD setting to succeed.\n *\n * @param codec\t    The codec instance.\n * @param param\t    The new codec parameter.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_INLINE(pj_status_t) pjmedia_codec_modify(pjmedia_codec *codec, \n\t\t\t\t\t    const pjmedia_codec_param *param)\n{\n    return (*codec->op->modify)(codec, param);\n}\n\n\n/**\n * Instruct the codec to inspect the specified payload/packet and\n * split the packet into individual base frames. Each output frames will\n * have ptime that is equal to basic frame ptime (i.e. the value of\n * info.frm_ptime in #pjmedia_codec_param).\n *\n * @param codec\t    The codec instance\n * @param pkt\t    The input packet.\n * @param pkt_size  Size of the packet.\n * @param timestamp The timestamp of the first sample in the packet.\n * @param frame_cnt On input, specifies the maximum number of frames\n *\t\t    in the array. On output, the codec must fill\n *\t\t    with number of frames detected in the packet.\n * @param frames    On output, specifies the frames that have been\n *\t\t    detected in the packet.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_INLINE(pj_status_t) pjmedia_codec_parse( pjmedia_codec *codec,\n\t\t\t\t\t    void *pkt,\n\t\t\t\t\t    pj_size_t pkt_size,\n\t\t\t\t\t    const pj_timestamp *timestamp,\n\t\t\t\t\t    unsigned *frame_cnt,\n\t\t\t\t\t    pjmedia_frame frames[] )\n{\n    return (*codec->op->parse)(codec, pkt, pkt_size, timestamp,\n\t\t\t       frame_cnt, frames);\n}\n\n\n/** \n * Instruct the codec to encode the specified input frame. The input\n * PCM samples MUST have ptime that is multiplication of base frame\n * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param).\n *\n * @param codec\t\tThe codec instance.\n * @param input\t\tThe input frame.\n * @param out_size\tThe length of buffer in the output frame.\n * @param output\tThe output frame.\n *\n * @return\t\tPJ_SUCCESS on success;\n */\nPJ_INLINE(pj_status_t) pjmedia_codec_encode( \n\t\t\t\t\tpjmedia_codec *codec, \n\t\t\t\t\tconst struct pjmedia_frame *input,\n\t\t\t\t\tunsigned out_size, \n\t\t\t\t\tstruct pjmedia_frame *output )\n{\n    return (*codec->op->encode)(codec, input, out_size, output);\n}\n\n\n/** \n * Instruct the codec to decode the specified input frame. The input\n * frame MUST have ptime that is exactly equal to base frame\n * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param).\n * Application can achieve this by parsing the packet into base\n * frames before decoding each frame.\n *\n * @param codec\t\tThe codec instance.\n * @param input\t\tThe input frame.\n * @param out_size\tThe length of buffer in the output frame.\n * @param output\tThe output frame.\n *\n * @return\t\tPJ_SUCCESS on success;\n */\nPJ_INLINE(pj_status_t) pjmedia_codec_decode( \n\t\t\t\t\tpjmedia_codec *codec, \n\t\t\t\t\tconst struct pjmedia_frame *input,\n\t\t\t\t\tunsigned out_size, \n\t\t\t\t\tstruct pjmedia_frame *output )\n{\n    return (*codec->op->decode)(codec, input, out_size, output);\n}\n\n\n/**\n * Instruct the codec to recover a missing frame.\n *\n * @param codec\t\tThe codec instance.\n * @param out_size\tThe length of buffer in the output frame.\n * @param output\tThe output frame where generated signal\n *\t\t\twill be placed.\n *\n * @return\t\tPJ_SUCCESS on success;\n */\nPJ_INLINE(pj_status_t) pjmedia_codec_recover( pjmedia_codec *codec,\n\t\t\t\t\t      unsigned out_size,\n\t\t\t\t\t      struct pjmedia_frame *output )\n{\n    if (codec->op && codec->op->recover)\n\treturn (*codec->op->recover)(codec, out_size, output);\n    else\n\treturn PJ_ENOTSUP;\n}\n\n\n/**\n * @}\n */\n\n/**\n * @defgroup PJMEDIA_CODEC_CODECS Supported codecs\n * @ingroup PJMEDIA_CODEC\n * @brief Documentation about individual codec supported by PJMEDIA\n * @{\n * Please see the APIs provided by the individual codecs below.\n */\n/**\n * @}\n */\n\n\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_CODEC_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/conference.h",
    "content": "/* $Id: conference.h 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CONF_H__\n#define __PJMEDIA_CONF_H__\n\n\n/**\n * @file conference.h\n * @brief Conference bridge.\n */\n#include <pjmedia/port.h>\n\n/**\n * @defgroup PJMEDIA_CONF Conference Bridge\n * @ingroup PJMEDIA_PORT\n * @brief Audio conference bridge implementation\n * @{\n *\n * This describes the conference bridge implementation in PJMEDIA. The\n * conference bridge provides powerful and very efficient mechanism to\n * route the audio flow and mix the audio signal when required.\n *\n * Some more information about the media flow when conference bridge is\n * used is described in http://www.pjsip.org/trac/wiki/media-flow .\n */\n\nPJ_BEGIN_DECL\n\n/**\n * The conference bridge signature in pjmedia_port_info.\n */\n#define PJMEDIA_CONF_BRIDGE_SIGNATURE\tPJMEDIA_SIG_PORT_CONF\n\n/**\n * The audio switchboard signature in pjmedia_port_info.\n */\n#define PJMEDIA_CONF_SWITCH_SIGNATURE\tPJMEDIA_SIG_PORT_CONF_SWITCH\n\n\n/**\n * Opaque type for conference bridge.\n */\ntypedef struct pjmedia_conf pjmedia_conf;\n\n/**\n * Conference port info.\n */\ntypedef struct pjmedia_conf_port_info\n{\n    unsigned\t\tslot;\t\t    /**< Slot number.\t\t    */\n    pj_str_t\t\tname;\t\t    /**< Port name.\t\t    */\n    pjmedia_format\tformat;\t\t    /**< Format.\t\t    */\n    pjmedia_port_op\ttx_setting;\t    /**< Transmit settings.\t    */\n    pjmedia_port_op\trx_setting;\t    /**< Receive settings.\t    */\n    unsigned\t\tlistener_cnt;\t    /**< Number of listeners.\t    */\n    unsigned\t       *listener_slots;\t    /**< Array of listeners.\t    */\n    unsigned\t\ttransmitter_cnt;    /**< Number of transmitter.\t    */\n    unsigned\t\tclock_rate;\t    /**< Clock rate of the port.    */\n    unsigned\t\tchannel_count;\t    /**< Number of channels.\t    */\n    unsigned\t\tsamples_per_frame;  /**< Samples per frame\t    */\n    unsigned\t\tbits_per_sample;    /**< Bits per sample.\t    */\n    int\t\t\ttx_adj_level;\t    /**< Tx level adjustment.\t    */\n    int\t\t\trx_adj_level;\t    /**< Rx level adjustment.\t    */\n} pjmedia_conf_port_info;\n\n\n/**\n * Conference port options. The values here can be combined in bitmask to\n * be specified when the conference bridge is created.\n */\nenum pjmedia_conf_option\n{\n    PJMEDIA_CONF_NO_MIC  = 1,\t/**< Disable audio streams from the\n\t\t\t\t     microphone device.\t\t\t    */\n    PJMEDIA_CONF_NO_DEVICE = 2,\t/**< Do not create sound device.\t    */\n    PJMEDIA_CONF_SMALL_FILTER=4,/**< Use small filter table when resampling */\n    PJMEDIA_CONF_USE_LINEAR=8\t/**< Use linear resampling instead of filter\n\t\t\t\t     based.\t\t\t\t    */\n};\n\n\n/**\n * Create conference bridge with the specified parameters. The sampling rate,\n * samples per frame, and bits per sample will be used for the internal\n * operation of the bridge (e.g. when mixing audio frames). However, ports \n * with different configuration may be connected to the bridge. In this case,\n * the bridge is able to perform sampling rate conversion, and buffering in \n * case the samples per frame is different.\n *\n * For this version of PJMEDIA, only 16bits per sample is supported.\n *\n * For this version of PJMEDIA, the channel count of the ports MUST match\n * the channel count of the bridge.\n *\n * Under normal operation (i.e. when PJMEDIA_CONF_NO_DEVICE option is NOT\n * specified), the bridge internally create an instance of sound device\n * and connect the sound device to port zero of the bridge. \n *\n * If PJMEDIA_CONF_NO_DEVICE options is specified, no sound device will\n * be created in the conference bridge. Application MUST acquire the port\n * interface of the bridge by calling #pjmedia_conf_get_master_port(), and\n * connect this port interface to a sound device port by calling\n * #pjmedia_snd_port_connect(), or to a master port (pjmedia_master_port)\n * if application doesn't want to instantiate any sound devices.\n *\n * The sound device or master port are crucial for the bridge's operation, \n * because it provides the bridge with necessary clock to process the audio\n * frames periodically. Internally, the bridge runs when get_frame() to \n * port zero is called.\n *\n * @param pool\t\t    Pool to use to allocate the bridge and \n *\t\t\t    additional buffers for the sound device.\n * @param max_slots\t    Maximum number of slots/ports to be created in\n *\t\t\t    the bridge. Note that the bridge internally uses\n *\t\t\t    one port for the sound device, so the actual \n *\t\t\t    maximum number of ports will be less one than\n *\t\t\t    this value.\n * @param sampling_rate\t    Set the sampling rate of the bridge. This value\n *\t\t\t    is also used to set the sampling rate of the\n *\t\t\t    sound device.\n * @param channel_count\t    Number of channels in the PCM stream. Normally\n *\t\t\t    the value will be 1 for mono, but application may\n *\t\t\t    specify a value of 2 for stereo. Note that all\n *\t\t\t    ports that will be connected to the bridge MUST \n *\t\t\t    have the same number of channels as the bridge.\n * @param samples_per_frame Set the number of samples per frame. This value\n *\t\t\t    is also used to set the sound device.\n * @param bits_per_sample   Set the number of bits per sample. This value\n *\t\t\t    is also used to set the sound device. Currently\n *\t\t\t    only 16bit per sample is supported.\n * @param options\t    Bitmask options to be set for the bridge. The\n *\t\t\t    options are constructed from #pjmedia_conf_option\n *\t\t\t    enumeration.\n * @param p_conf\t    Pointer to receive the conference bridge instance.\n *\n * @return\t\t    PJ_SUCCESS if conference bridge can be created.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_create( pj_pool_t *pool,\n\t\t\t\t\t  unsigned max_slots,\n\t\t\t\t\t  unsigned sampling_rate,\n\t\t\t\t\t  unsigned channel_count,\n\t\t\t\t\t  unsigned samples_per_frame,\n\t\t\t\t\t  unsigned bits_per_sample,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t\t  pjmedia_conf **p_conf );\n\n\n/**\n * Destroy conference bridge.\n *\n * @param conf\t\t    The conference bridge.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_destroy( pjmedia_conf *conf );\n\n\n/**\n * Get the master port interface of the conference bridge. The master port\n * corresponds to the port zero of the bridge. This is only usefull when \n * application wants to manage the sound device by itself, instead of \n * allowing the bridge to automatically create a sound device implicitly.\n *\n * This function will only return a port interface if PJMEDIA_CONF_NO_DEVICE\n * option was specified when the bridge was created.\n *\n * Application can connect the port returned by this function to a \n * sound device by calling #pjmedia_snd_port_connect().\n *\n * @param conf\t\t    The conference bridge.\n *\n * @return\t\t    The port interface of port zero of the bridge,\n *\t\t\t    only when PJMEDIA_CONF_NO_DEVICE options was\n *\t\t\t    specified when the bridge was created.\n */\nPJ_DECL(pjmedia_port*) pjmedia_conf_get_master_port(pjmedia_conf *conf);\n\n\n/**\n * Set master port name.\n *\n * @param conf\t\t    The conference bridge.\n * @param name\t\t    Name to be assigned.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_set_port0_name(pjmedia_conf *conf,\n\t\t\t\t\t\t const pj_str_t *name);\n\n\n/**\n * Add media port to the conference bridge.\n *\n * By default, the new conference port will have both TX and RX enabled, \n * but it is not connected to any other ports. Application SHOULD call \n * #pjmedia_conf_connect_port() to  enable audio transmission and receipt \n * to/from this port.\n *\n * Once the media port is connected to other port(s) in the bridge,\n * the bridge will continuosly call get_frame() and put_frame() to the\n * port, allowing media to flow to/from the port.\n *\n * @param conf\t\tThe conference bridge.\n * @param pool\t\tPool to allocate buffers for this port.\n * @param strm_port\tStream port interface.\n * @param name\t\tOptional name for the port. If this value is NULL,\n *\t\t\tthe name will be taken from the name in the port \n *\t\t\tinfo.\n * @param p_slot\tPointer to receive the slot index of the port in\n *\t\t\tthe conference bridge.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_add_port( pjmedia_conf *conf,\n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    pjmedia_port *strm_port,\n\t\t\t\t\t    const pj_str_t *name,\n\t\t\t\t\t    unsigned *p_slot );\n\n\n/**\n * <i><b>Warning:</b> This API has been deprecated since 1.3 and will be\n * removed in the future release, use @ref PJMEDIA_SPLITCOMB instead.</i>\n *\n * Create and add a passive media port to the conference bridge. Unlike\n * \"normal\" media port that is added with #pjmedia_conf_add_port(), media\n * port created with this function will not have its get_frame() and\n * put_frame() called by the bridge; instead, application MUST continuosly\n * call these functions to the port, to allow media to flow from/to the\n * port.\n *\n * Upon return of this function, application will be given two objects:\n * the slot number of the port in the bridge, and pointer to the media\n * port where application MUST start calling get_frame() and put_frame()\n * to the port.\n *\n * @param conf\t\t    The conference bridge.\n * @param pool\t\t    Pool to allocate buffers etc for this port.\n * @param name\t\t    Name to be assigned to the port.\n * @param clock_rate\t    Clock rate/sampling rate.\n * @param channel_count\t    Number of channels.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Number of bits per sample.\n * @param options\t    Options (should be zero at the moment).\n * @param p_slot\t    Pointer to receive the slot index of the port in\n *\t\t\t    the conference bridge.\n * @param p_port\t    Pointer to receive the port instance.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error \n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_add_passive_port( pjmedia_conf *conf,\n\t\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t\t    const pj_str_t *name,\n\t\t\t\t\t\t    unsigned clock_rate,\n\t\t\t\t\t\t    unsigned channel_count,\n\t\t\t\t\t\t    unsigned samples_per_frame,\n\t\t\t\t\t\t    unsigned bits_per_sample,\n\t\t\t\t\t\t    unsigned options,\n\t\t\t\t\t\t    unsigned *p_slot,\n\t\t\t\t\t\t    pjmedia_port **p_port );\n\n\n/**\n * Change TX and RX settings for the port.\n *\n * @param conf\t\tThe conference bridge.\n * @param slot\t\tPort number/slot in the conference bridge.\n * @param tx\t\tSettings for the transmission TO this port.\n * @param rx\t\tSettings for the receipt FROM this port.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_configure_port( pjmedia_conf *conf,\n\t\t\t\t\t\t  unsigned slot,\n\t\t\t\t\t\t  pjmedia_port_op tx,\n\t\t\t\t\t\t  pjmedia_port_op rx);\n\n\n/**\n * Enable unidirectional audio from the specified source slot to the\n * specified sink slot.\n *\n * @param conf\t\tThe conference bridge.\n * @param src_slot\tSource slot.\n * @param sink_slot\tSink slot.\n * @param level\t\tThis argument is reserved for future improvements\n *\t\t\twhere it is possible to adjust the level of signal\n *\t\t\ttransmitted in a specific connection. For now,\n *\t\t\tthis argument MUST be zero.\n *\n * @return\t\tPJ_SUCCES on success.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_connect_port( pjmedia_conf *conf,\n\t\t\t\t\t\tunsigned src_slot,\n\t\t\t\t\t\tunsigned sink_slot,\n\t\t\t\t\t\tint level );\n\n\n/**\n * Disconnect unidirectional audio from the specified source to the specified\n * sink slot.\n *\n * @param conf\t\tThe conference bridge.\n * @param src_slot\tSource slot.\n * @param sink_slot\tSink slot.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf,\n\t\t\t\t\t\t   unsigned src_slot,\n\t\t\t\t\t\t   unsigned sink_slot );\n\n\n/**\n * Get number of ports currently registered to the conference bridge.\n *\n * @param conf\t\tThe conference bridge.\n *\n * @return\t\tNumber of ports currently registered to the conference\n *\t\t\tbridge.\n */\nPJ_DECL(unsigned) pjmedia_conf_get_port_count(pjmedia_conf *conf);\n\n\n/**\n * Get total number of ports connections currently set up in the bridge.\n * \n * @param conf\t\tThe conference bridge.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(unsigned) pjmedia_conf_get_connect_count(pjmedia_conf *conf);\n\n\n/**\n * Remove the specified port from the conference bridge.\n *\n * @param conf\t\tThe conference bridge.\n * @param slot\t\tThe port index to be removed.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf,\n\t\t\t\t\t       unsigned slot );\n\n\n\n/**\n * Enumerate occupied ports in the bridge.\n *\n * @param conf\t\tThe conference bridge.\n * @param ports\t\tArray of port numbers to be filled in.\n * @param count\t\tOn input, specifies the maximum number of ports\n *\t\t\tin the array. On return, it will be filled with\n *\t\t\tthe actual number of ports.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_enum_ports( pjmedia_conf *conf,\n\t\t\t\t\t      unsigned ports[],\n\t\t\t\t\t      unsigned *count );\n\n\n/**\n * Get port info.\n *\n * @param conf\t\tThe conference bridge.\n * @param slot\t\tPort index.\n * @param info\t\tPointer to receive the info.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_get_port_info( pjmedia_conf *conf,\n\t\t\t\t\t\t unsigned slot,\n\t\t\t\t\t\t pjmedia_conf_port_info *info);\n\n\n/**\n * Get occupied ports info.\n *\n * @param conf\t\tThe conference bridge.\n * @param size\t\tOn input, contains maximum number of infos\n *\t\t\tto be retrieved. On output, contains the actual\n *\t\t\tnumber of infos that have been copied.\n * @param info\t\tArray of info.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_get_ports_info(pjmedia_conf *conf,\n\t\t\t\t\t\t unsigned *size,\n\t\t\t\t\t\t pjmedia_conf_port_info info[]\n\t\t\t\t\t\t );\n\n\n/**\n * Get last signal level transmitted to or received from the specified port.\n * This will retrieve the \"real-time\" signal level of the audio as they are\n * transmitted or received by the specified port. Application may call this\n * function periodically to display the signal level to a VU meter.\n *\n * The signal level is an integer value in zero to 255, with zero indicates\n * no signal, and 255 indicates the loudest signal level.\n *\n * @param conf\t\tThe conference bridge.\n * @param slot\t\tSlot number.\n * @param tx_level\tOptional argument to receive the level of signal\n *\t\t\ttransmitted to the specified port (i.e. the direction\n *\t\t\tis from the bridge to the port).\n * @param rx_level\tOptional argument to receive the level of signal\n *\t\t\treceived from the port (i.e. the direction is from the\n *\t\t\tport to the bridge).\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_get_signal_level(pjmedia_conf *conf,\n\t\t\t\t\t\t   unsigned slot,\n\t\t\t\t\t\t   unsigned *tx_level,\n\t\t\t\t\t\t   unsigned *rx_level);\n\n\n/**\n * Adjust the level of signal received from the specified port.\n * Application may adjust the level to make signal received from the port\n * either louder or more quiet. The level adjustment is calculated with this\n * formula: <b><tt>output = input * (adj_level+128) / 128</tt></b>. Using \n * this, zero indicates no adjustment, the value -128 will mute the signal, \n * and the value of +128 will make the signal 100% louder, +256 will make it\n * 200% louder, etc.\n *\n * The level adjustment value will stay with the port until the port is\n * removed from the bridge or new adjustment value is set. The current\n * level adjustment value is reported in the media port info when\n * the #pjmedia_conf_get_port_info() function is called.\n *\n * @param conf\t\tThe conference bridge.\n * @param slot\t\tSlot number of the port.\n * @param adj_level\tAdjustment level, which must be greater than or equal\n *\t\t\tto -128. A value of zero means there is no level\n *\t\t\tadjustment to be made, the value -128 will mute the \n *\t\t\tsignal, and the value of +128 will make the signal \n *\t\t\t100% louder, +256 will make it 200% louder, etc. \n *\t\t\tSee the function description for the formula.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_adjust_rx_level( pjmedia_conf *conf,\n\t\t\t\t\t\t   unsigned slot,\n\t\t\t\t\t\t   int adj_level );\n\n\n/**\n * Adjust the level of signal to be transmitted to the specified port.\n * Application may adjust the level to make signal transmitted to the port\n * either louder or more quiet. The level adjustment is calculated with this\n * formula: <b><tt>output = input * (adj_level+128) / 128</tt></b>. Using \n * this, zero indicates no adjustment, the value -128 will mute the signal, \n * and the value of +128 will make the signal 100% louder, +256 will make it\n * 200% louder, etc.\n *\n * The level adjustment value will stay with the port until the port is\n * removed from the bridge or new adjustment value is set. The current\n * level adjustment value is reported in the media port info when\n * the #pjmedia_conf_get_port_info() function is called.\n *\n * @param conf\t\tThe conference bridge.\n * @param slot\t\tSlot number of the port.\n * @param adj_level\tAdjustment level, which must be greater than or equal\n *\t\t\tto -128. A value of zero means there is no level\n *\t\t\tadjustment to be made, the value -128 will mute the \n *\t\t\tsignal, and the value of +128 will make the signal \n *\t\t\t100% louder, +256 will make it 200% louder, etc. \n *\t\t\tSee the function description for the formula.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_conf_adjust_tx_level( pjmedia_conf *conf,\n\t\t\t\t\t\t   unsigned slot,\n\t\t\t\t\t\t   int adj_level );\n\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_CONF_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/config.h",
    "content": "/* $Id: config.h 4443 2013-03-20 06:56:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CONFIG_H__\n#define __PJMEDIA_CONFIG_H__\n\n/**\n * @file pjmedia/config.h Compile time config\n * @brief Contains some compile time constants.\n */\n#include <pj/config.h>\n\n/**\n * @defgroup PJMEDIA_BASE Base Types and Configurations\n */\n\n/**\n * @defgroup PJMEDIA_CONFIG Compile time configuration\n * @ingroup PJMEDIA_BASE\n * @brief Some compile time configuration settings.\n * @{\n */\n\n/*\n * Include config_auto.h if autoconf is used (PJ_AUTOCONF is set)\n */\n#if defined(PJ_AUTOCONF)\n#   include <pjmedia/config_auto.h>\n#endif\n\n/**\n * Specify whether we prefer to use audio switch board rather than \n * conference bridge.\n *\n * Audio switch board is a kind of simplified version of conference \n * bridge, but not really the subset of conference bridge. It has \n * stricter rules on audio routing among the pjmedia ports and has\n * no audio mixing capability. The power of it is it could work with\n * encoded audio frames where conference brigde couldn't.\n *\n * Default: 0\n */\n#ifndef PJMEDIA_CONF_USE_SWITCH_BOARD\n#   define PJMEDIA_CONF_USE_SWITCH_BOARD    0\n#endif\n\n/**\n * Specify buffer size for audio switch board, in bytes. This buffer will\n * be used for transmitting/receiving audio frame data (and some overheads,\n * i.e: pjmedia_frame structure) among conference ports in the audio\n * switch board. For example, if a port uses PCM format @44100Hz mono\n * and frame time 20ms, the PCM audio data will require 1764 bytes,\n * so with overhead, a safe buffer size will be ~1900 bytes.\n *\n * Default: PJMEDIA_MAX_MTU\n */\n#ifndef PJMEDIA_CONF_SWITCH_BOARD_BUF_SIZE\n#   define PJMEDIA_CONF_SWITCH_BOARD_BUF_SIZE    PJMEDIA_MAX_MTU\n#endif\n\n\n/*\n * Types of sound stream backends.\n */\n\n/**\n * This macro has been deprecated in releasee 1.1. Please see\n * http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more information.\n */\n#if defined(PJMEDIA_SOUND_IMPLEMENTATION)\n#   error PJMEDIA_SOUND_IMPLEMENTATION has been deprecated\n#endif\n\n/**\n * This macro has been deprecated in releasee 1.1. Please see\n * http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more information.\n */\n#if defined(PJMEDIA_PREFER_DIRECT_SOUND)\n#   error PJMEDIA_PREFER_DIRECT_SOUND has been deprecated\n#endif\n\n/**\n * This macro controls whether the legacy sound device API is to be\n * implemented, for applications that still use the old sound device\n * API (sound.h). If this macro is set to non-zero, the sound_legacy.c\n * will be included in the compilation. The sound_legacy.c is an\n * implementation of old sound device (sound.h) using the new Audio\n * Device API.\n *\n * Please see http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more\n * info.\n */\n#ifndef PJMEDIA_HAS_LEGACY_SOUND_API\n#   define PJMEDIA_HAS_LEGACY_SOUND_API\t    1\n#endif\n\n/**\n * Specify default sound device latency, in milisecond.\n */\n#ifndef PJMEDIA_SND_DEFAULT_REC_LATENCY\n#   define PJMEDIA_SND_DEFAULT_REC_LATENCY  100\n#endif\n\n/**\n * Specify default sound device latency, in milisecond. \n *\n * Default is 160ms for Windows Mobile and 140ms for other platforms.\n */\n#ifndef PJMEDIA_SND_DEFAULT_PLAY_LATENCY\n#   if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0\n#\tdefine PJMEDIA_SND_DEFAULT_PLAY_LATENCY\t    160\n#   else\n#\tdefine PJMEDIA_SND_DEFAULT_PLAY_LATENCY\t    140\n#   endif\n#endif\n\n\n/*\n * Types of WSOLA backend algorithm.\n */\n\n/**\n * This denotes implementation of WSOLA using null algorithm. Expansion\n * will generate zero frames, and compression will just discard some\n * samples from the input.\n *\n * This type of implementation may be used as it requires the least\n * processing power.\n */\n#define PJMEDIA_WSOLA_IMP_NULL\t\t    0\n\n/**\n * This denotes implementation of WSOLA using fixed or floating point WSOLA\n * algorithm. This implementation provides the best quality of the result,\n * at the expense of one frame delay and intensive processing power \n * requirement.\n */\n#define PJMEDIA_WSOLA_IMP_WSOLA\t\t    1\n\n/**\n * This denotes implementation of WSOLA algorithm with faster waveform \n * similarity calculation. This implementation provides fair quality of \n * the result with the main advantage of low processing power requirement.\n */\n#define PJMEDIA_WSOLA_IMP_WSOLA_LITE\t    2\n\n/**\n * Specify type of Waveform based Similarity Overlap and Add (WSOLA) backend\n * implementation to be used. WSOLA is an algorithm to expand and/or compress \n * audio frames without changing the pitch, and used by the delaybuf and as PLC\n * backend algorithm.\n *\n * Default is PJMEDIA_WSOLA_IMP_WSOLA\n */\n#ifndef PJMEDIA_WSOLA_IMP\n#   define PJMEDIA_WSOLA_IMP\t\t    PJMEDIA_WSOLA_IMP_WSOLA\n#endif\n\n\n/**\n * Specify the default maximum duration of synthetic audio that is generated\n * by WSOLA. This value should be long enough to cover burst of packet losses. \n * but not too long, because as the duration increases the quality would \n * degrade considerably.\n *\n * Note that this limit is only applied when fading is enabled in the WSOLA\n * session.\n *\n * Default: 80\n */\n#ifndef PJMEDIA_WSOLA_MAX_EXPAND_MSEC\n#   define PJMEDIA_WSOLA_MAX_EXPAND_MSEC    80\n#endif\n\n\n/**\n * Specify WSOLA template length, in milliseconds. The longer the template,\n * the smoother signal to be generated at the expense of more computation\n * needed, since the algorithm will have to compare more samples to find\n * the most similar pitch.\n *\n * Default: 5\n */\n#ifndef PJMEDIA_WSOLA_TEMPLATE_LENGTH_MSEC\n#   define PJMEDIA_WSOLA_TEMPLATE_LENGTH_MSEC\t5\n#endif\n\n\n/**\n * Specify WSOLA algorithm delay, in milliseconds. The algorithm delay is\n * used to merge synthetic samples with real samples in the transition\n * between real to synthetic and vice versa. The longer the delay, the \n * smoother signal to be generated, at the expense of longer latency and\n * a slighty more computation.\n *\n * Default: 5\n */\n#ifndef PJMEDIA_WSOLA_DELAY_MSEC\n#   define PJMEDIA_WSOLA_DELAY_MSEC\t    5\n#endif\n\n\n/**\n * Set this to non-zero to disable fade-out/in effect in the PLC when it\n * instructs WSOLA to generate synthetic frames. The use of fading may\n * or may not improve the quality of audio, depending on the nature of\n * packet loss and the type of audio input (e.g. speech vs music).\n * Disabling fading also implicitly remove the maximum limit of synthetic\n * audio samples generated by WSOLA (see PJMEDIA_WSOLA_MAX_EXPAND_MSEC).\n *\n * Default: 0\n */\n#ifndef PJMEDIA_WSOLA_PLC_NO_FADING\n#   define PJMEDIA_WSOLA_PLC_NO_FADING\t    0\n#endif\n\n\n/**\n * Limit the number of calls by stream to the PLC to generate synthetic\n * frames to this duration. If packets are still lost after this maximum\n * duration, silence will be generated by the stream instead. Since the\n * PLC normally should have its own limit on the maximum duration of\n * synthetic frames to be generated (for PJMEDIA's PLC, the limit is\n * PJMEDIA_WSOLA_MAX_EXPAND_MSEC), we can set this value to a large number\n * to give additional flexibility should the PLC wants to do something\n * clever with the lost frames.\n *\n * Default: 240 ms\n */\n#ifndef PJMEDIA_MAX_PLC_DURATION_MSEC\n#   define PJMEDIA_MAX_PLC_DURATION_MSEC    240\n#endif\n\n\n/**\n * Specify number of sound buffers. Larger number is better for sound\n * stability and to accommodate sound devices that are unable to send frames\n * in timely manner, however it would probably cause more audio delay (and \n * definitely will take more memory). One individual buffer is normally 10ms\n * or 20 ms long, depending on ptime settings (samples_per_frame value).\n *\n * The setting here currently is used by the conference bridge, the splitter\n * combiner port, and dsound.c.\n *\n * Default: (PJMEDIA_SND_DEFAULT_PLAY_LATENCY+20)/20\n */\n#ifndef PJMEDIA_SOUND_BUFFER_COUNT\n#   define PJMEDIA_SOUND_BUFFER_COUNT\t    ((PJMEDIA_SND_DEFAULT_PLAY_LATENCY+20)/20)\n#endif\n\n\n/**\n * Specify which A-law/U-law conversion algorithm to use.\n * By default the conversion algorithm uses A-law/U-law table which gives\n * the best performance, at the expense of 33 KBytes of static data.\n * If this option is disabled, a smaller but slower algorithm will be used.\n */\n#ifndef PJMEDIA_HAS_ALAW_ULAW_TABLE\n#   define PJMEDIA_HAS_ALAW_ULAW_TABLE\t    1\n#endif\n\n\n/**\n * Unless specified otherwise, G711 codec is included by default.\n */\n#ifndef PJMEDIA_HAS_G711_CODEC\n#   define PJMEDIA_HAS_G711_CODEC\t    1\n#endif\n\n\n/*\n * Warn about obsolete macros.\n *\n * PJMEDIA_HAS_SMALL_FILTER has been deprecated in 0.7.\n */\n#if defined(PJMEDIA_HAS_SMALL_FILTER)\n#   ifdef _MSC_VER\n#\tpragma message(\"Warning: PJMEDIA_HAS_SMALL_FILTER macro is deprecated\"\\\n\t\t       \" and has no effect\")\n#   else\n#\twarning \"PJMEDIA_HAS_SMALL_FILTER macro is deprecated and has no effect\"\n#   endif\n#endif\n\n\n/*\n * Warn about obsolete macros.\n *\n * PJMEDIA_HAS_LARGE_FILTER has been deprecated in 0.7.\n */\n#if defined(PJMEDIA_HAS_LARGE_FILTER)\n#   ifdef _MSC_VER\n#\tpragma message(\"Warning: PJMEDIA_HAS_LARGE_FILTER macro is deprecated\"\\\n\t\t       \" and has no effect\")\n#   else\n#\twarning \"PJMEDIA_HAS_LARGE_FILTER macro is deprecated\"\n#   endif\n#endif\n\n\n/*\n * These macros are obsolete in 0.7.1 so it will trigger compilation error.\n * Please use PJMEDIA_RESAMPLE_IMP to select the resample implementation\n * to use.\n */\n#ifdef PJMEDIA_HAS_LIBRESAMPLE\n#   error \"PJMEDIA_HAS_LIBRESAMPLE macro is deprecated. Use '#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_LIBRESAMPLE'\"\n#endif\n\n#ifdef PJMEDIA_HAS_SPEEX_RESAMPLE\n#   error \"PJMEDIA_HAS_SPEEX_RESAMPLE macro is deprecated. Use '#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_SPEEX'\"\n#endif\n\n\n/*\n * Sample rate conversion backends.\n * Select one of these backends in PJMEDIA_RESAMPLE_IMP.\n */\n#define PJMEDIA_RESAMPLE_NONE\t\t    1\t/**< No resampling.\t    */\n#define PJMEDIA_RESAMPLE_LIBRESAMPLE\t    2\t/**< Sample rate conversion \n\t\t\t\t\t\t     using libresample.  */\n#define PJMEDIA_RESAMPLE_SPEEX\t\t    3\t/**< Sample rate conversion \n\t\t\t\t\t\t     using Speex. */\n#define PJMEDIA_RESAMPLE_LIBSAMPLERATE\t    4\t/**< Sample rate conversion \n\t\t\t\t\t\t     using libsamplerate \n\t\t\t\t\t\t     (a.k.a Secret Rabbit Code)\n\t\t\t\t\t\t */\n\n/**\n * Select which resample implementation to use. Currently pjmedia supports:\n *  - #PJMEDIA_RESAMPLE_LIBRESAMPLE, to use libresample-1.7, this is the default\n *    implementation to be used.\n *  - #PJMEDIA_RESAMPLE_LIBSAMPLERATE, to use libsamplerate implementation\n *    (a.k.a. Secret Rabbit Code).\n *  - #PJMEDIA_RESAMPLE_SPEEX, to use experimental sample rate conversion in\n *    Speex library.\n *  - #PJMEDIA_RESAMPLE_NONE, to disable sample rate conversion. Any calls to\n *    resample function will return error.\n *\n * Default is PJMEDIA_RESAMPLE_LIBRESAMPLE\n */\n#ifndef PJMEDIA_RESAMPLE_IMP\n#   define PJMEDIA_RESAMPLE_IMP\t\t    PJMEDIA_RESAMPLE_LIBRESAMPLE\n#endif\n\n\n/**\n * Specify whether libsamplerate, when used, should be linked statically\n * into the application. This option is only useful for Visual Studio\n * projects, and when this static linking is enabled\n */\n\n\n/**\n * Default file player/writer buffer size.\n */\n#ifndef PJMEDIA_FILE_PORT_BUFSIZE\n#   define PJMEDIA_FILE_PORT_BUFSIZE\t\t4000\n#endif\n\n\n/**\n * Maximum frame duration (in msec) to be supported.\n * This (among other thing) will affect the size of buffers to be allocated\n * for outgoing packets.\n */\n#ifndef PJMEDIA_MAX_FRAME_DURATION_MS   \n#   define PJMEDIA_MAX_FRAME_DURATION_MS   \t200\n#endif\n\n\n/**\n * Max packet size for transmitting direction.\n */\n#ifndef PJMEDIA_MAX_MTU\t\t\t\n#  define PJMEDIA_MAX_MTU\t\t\t1500\n#endif\n\n\n/**\n * Max packet size for receiving direction.\n */\n#ifndef PJMEDIA_MAX_MRU\t\t\t\n#  define PJMEDIA_MAX_MRU\t\t\t2000\n#endif\n\n\n/**\n * DTMF/telephone-event duration, in timestamp.\n */\n#ifndef PJMEDIA_DTMF_DURATION\t\t\n#  define PJMEDIA_DTMF_DURATION\t\t\t1600\t/* in timestamp */\n#endif\n\n\n/**\n * Number of RTP packets received from different source IP address from the\n * remote address required to make the stream switch transmission\n * to the source address.\n */\n#ifndef PJMEDIA_RTP_NAT_PROBATION_CNT\t\n#  define PJMEDIA_RTP_NAT_PROBATION_CNT\t\t10\n#endif\n\n\n/**\n * Number of RTCP packets received from different source IP address from the\n * remote address required to make the stream switch RTCP transmission\n * to the source address.\n */\n#ifndef PJMEDIA_RTCP_NAT_PROBATION_CNT\n#  define PJMEDIA_RTCP_NAT_PROBATION_CNT\t3\n#endif\n\n\n/**\n * Specify whether RTCP should be advertised in SDP. This setting would\n * affect whether RTCP candidate will be added in SDP when ICE is used.\n * Application might want to disable RTCP advertisement in SDP to\n * reduce the message size.\n *\n * Default: 1 (yes)\n */\n#ifndef PJMEDIA_ADVERTISE_RTCP\n#   define PJMEDIA_ADVERTISE_RTCP\t\t1\n#endif\n\n\n/**\n * Interval to send RTCP packets, in msec\n */\n#ifndef PJMEDIA_RTCP_INTERVAL\n#\tdefine PJMEDIA_RTCP_INTERVAL\t\t5000\t/* msec*/\n#endif\n\n\n/**\n * Tell RTCP to ignore the first N packets when calculating the\n * jitter statistics. From experimentation, the first few packets\n * (25 or so) have relatively big jitter, possibly because during\n * this time, the program is also busy setting up the signaling,\n * so they make the average jitter big.\n *\n * Default: 25.\n */\n#ifndef PJMEDIA_RTCP_IGNORE_FIRST_PACKETS\n#   define  PJMEDIA_RTCP_IGNORE_FIRST_PACKETS\t25\n#endif\n\n\n/**\n * Specify whether RTCP statistics includes raw jitter statistics.\n * Raw jitter is defined as absolute value of network transit time\n * difference of two consecutive packets; refering to \"difference D\"\n * term in interarrival jitter calculation in RFC 3550 section 6.4.1.\n *\n * Default: 0 (no).\n */\n#ifndef PJMEDIA_RTCP_STAT_HAS_RAW_JITTER\n#   define PJMEDIA_RTCP_STAT_HAS_RAW_JITTER\t0\n#endif\n\n/**\n * Specify the factor with wich RTCP RTT statistics should be normalized \n * if exceptionally high. For e.g. mobile networks with potentially large\n * fluctuations, this might be unwanted.\n *\n * Use (0) to disable this feature.\n *\n * Default: 3.\n */\n#ifndef PJMEDIA_RTCP_NORMALIZE_FACTOR\n#   define PJMEDIA_RTCP_NORMALIZE_FACTOR\t3\n#endif\n\n\n/**\n * Specify whether RTCP statistics includes IP Delay Variation statistics.\n * IPDV is defined as network transit time difference of two consecutive\n * packets. The IPDV statistic can be useful to inspect clock skew existance\n * and level, e.g: when the IPDV mean values were stable in positive numbers,\n * then the remote clock (used in sending RTP packets) is faster than local\n * system clock. Ideally, the IPDV mean values are always equal to 0.\n *\n * Default: 0 (no).\n */\n#ifndef PJMEDIA_RTCP_STAT_HAS_IPDV\n#   define PJMEDIA_RTCP_STAT_HAS_IPDV\t\t0\n#endif\n\n\n/**\n * Specify whether RTCP XR support should be built into PJMEDIA. Disabling\n * this feature will reduce footprint slightly. Note that even when this \n * setting is enabled, RTCP XR processing will only be performed in stream \n * if it is enabled on run-time on per stream basis. See  \n * PJMEDIA_STREAM_ENABLE_XR setting for more info.\n *\n * Default: 0 (no).\n */\n#ifndef PJMEDIA_HAS_RTCP_XR\n#   define PJMEDIA_HAS_RTCP_XR\t\t\t0\n#endif\n\n\n/**\n * The RTCP XR feature is activated and used by stream if \\a enable_rtcp_xr\n * field of \\a pjmedia_stream_info structure is non-zero. This setting \n * controls the default value of this field.\n *\n * Default: 0 (disabled)\n */\n#ifndef PJMEDIA_STREAM_ENABLE_XR\n#   define PJMEDIA_STREAM_ENABLE_XR\t\t0\n#endif\n\n\n/**\n * Specify the buffer length for storing any received RTCP SDES text\n * in a stream session. Usually RTCP contains only the mandatory SDES\n * field, i.e: CNAME.\n * \n * Default: 64 bytes.\n */\n#ifndef PJMEDIA_RTCP_RX_SDES_BUF_LEN\n#   define PJMEDIA_RTCP_RX_SDES_BUF_LEN\t\t64\n#endif\n\n\n/**\n * Specify how long (in miliseconds) the stream should suspend the\n * silence detector/voice activity detector (VAD) during the initial\n * period of the session. This feature is useful to open bindings in\n * all NAT routers between local and remote endpoint since most NATs\n * do not allow incoming packet to get in before local endpoint sends\n * outgoing packets.\n *\n * Specify zero to disable this feature.\n *\n * Default: 600 msec (which gives good probability that some RTP \n *                    packets will reach the destination, but without\n *                    filling up the jitter buffer on the remote end).\n */\n#ifndef PJMEDIA_STREAM_VAD_SUSPEND_MSEC\n#   define PJMEDIA_STREAM_VAD_SUSPEND_MSEC\t600\n#endif\n\n/**\n * Perform RTP payload type checking in the stream. Normally the peer\n * MUST send RTP with payload type as we specified in our SDP. Certain\n * agents may not be able to follow this hence the only way to have\n * communication is to disable this check.\n *\n * Default: 1\n */\n#ifndef PJMEDIA_STREAM_CHECK_RTP_PT\n#   define PJMEDIA_STREAM_CHECK_RTP_PT\t\t1\n#endif\n\n/**\n * Reserve some space for application extra data, e.g: SRTP auth tag,\n * in RTP payload, so the total payload length will not exceed the MTU.\n */\n#ifndef PJMEDIA_STREAM_RESV_PAYLOAD_LEN\n#   define PJMEDIA_STREAM_RESV_PAYLOAD_LEN\t20\n#endif\n\n\n/**\n * Specify the maximum duration of silence period in the codec, in msec. \n * This is useful for example to keep NAT binding open in the firewall\n * and to prevent server from disconnecting the call because no \n * RTP packet is received.\n *\n * This only applies to codecs that use PJMEDIA's VAD (pretty much\n * everything including iLBC, except Speex, which has its own DTX \n * mechanism).\n *\n * Use (-1) to disable this feature.\n *\n * Default: 5000 ms\n *\n */\n#ifndef PJMEDIA_CODEC_MAX_SILENCE_PERIOD\n#   define PJMEDIA_CODEC_MAX_SILENCE_PERIOD\t5000\n#endif\n\n\n/**\n * Suggested or default threshold to be set for fixed silence detection\n * or as starting threshold for adaptive silence detection. The threshold\n * has the range from zero to 0xFFFF.\n */\n#ifndef PJMEDIA_SILENCE_DET_THRESHOLD\n#   define PJMEDIA_SILENCE_DET_THRESHOLD\t4\n#endif\n\n\n/**\n * Maximum silence threshold in the silence detector. The silence detector\n * will not cut the audio transmission if the audio level is above this\n * level.\n *\n * Use 0x10000 (or greater) to disable this feature.\n *\n * Default: 0x10000 (disabled)\n */\n#ifndef PJMEDIA_SILENCE_DET_MAX_THRESHOLD\n#   define PJMEDIA_SILENCE_DET_MAX_THRESHOLD\t0x10000\n#endif\n\n\n/**\n * Speex Accoustic Echo Cancellation (AEC).\n * By default is enabled.\n */\n#ifndef PJMEDIA_HAS_SPEEX_AEC\n#   define PJMEDIA_HAS_SPEEX_AEC\t\t1\n#endif\n\n\n/**\n * Specify whether Automatic Gain Control (AGC) should also be enabled in\n * Speex AEC.\n *\n * Default: 1 (yes)\n */\n#ifndef PJMEDIA_SPEEX_AEC_USE_AGC\n#   define PJMEDIA_SPEEX_AEC_USE_AGC\t\t1\n#endif\n\n\n/**\n * Specify whether denoise should also be enabled in Speex AEC.\n *\n * Default: 1 (yes)\n */\n#ifndef PJMEDIA_SPEEX_AEC_USE_DENOISE\n#   define PJMEDIA_SPEEX_AEC_USE_DENOISE\t1\n#endif\n\n\n/**\n * Maximum number of parameters in SDP fmtp attribute.\n *\n * Default: 16\n */\n#ifndef PJMEDIA_CODEC_MAX_FMTP_CNT\n#   define PJMEDIA_CODEC_MAX_FMTP_CNT\t\t16\n#endif\n\n\n/**\n * This specifies the behavior of the SDP negotiator when responding to an\n * offer, whether it should rather use the codec preference as set by\n * remote, or should it rather use the codec preference as specified by\n * local endpoint.\n *\n * For example, suppose incoming call has codec order \"8 0 3\", while \n * local codec order is \"3 0 8\". If remote codec order is preferable,\n * the selected codec will be 8, while if local codec order is preferable,\n * the selected codec will be 3.\n *\n * If set to non-zero, the negotiator will use the codec order as specified\n * by remote in the offer.\n *\n * Note that this behavior can be changed during run-time by calling\n * pjmedia_sdp_neg_set_prefer_remote_codec_order().\n *\n * Default is 1 (to maintain backward compatibility)\n */\n#ifndef PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER\n#   define PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER\t1\n#endif\n\n/**\n * This specifies the behavior of the SDP negotiator when responding to an\n * offer, whether it should answer with multiple formats or not.\n *\n * Note that this behavior can be changed during run-time by calling\n * pjmedia_sdp_neg_set_allow_multiple_codecs().\n *\n * Default is 0 (to maintain backward compatibility)\n */\n#ifndef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS\n#   define PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS\t0\n#endif\n\n\n/**\n * This specifies the maximum number of the customized SDP format\n * negotiation callbacks.\n */\n#ifndef PJMEDIA_SDP_NEG_MAX_CUSTOM_FMT_NEG_CB\n#   define PJMEDIA_SDP_NEG_MAX_CUSTOM_FMT_NEG_CB\t8\n#endif\n\n\n/**\n * This specifies if the SDP negotiator should rewrite answer payload\n * type numbers to use the same payload type numbers as the remote offer\n * for all matched codecs.\n *\n * Default is 1 (yes)\n */\n#ifndef PJMEDIA_SDP_NEG_ANSWER_SYMMETRIC_PT\n#   define PJMEDIA_SDP_NEG_ANSWER_SYMMETRIC_PT\t\t1\n#endif\n\n\n/**\n * Support for sending and decoding RTCP port in SDP (RFC 3605).\n * Default is equal to PJMEDIA_ADVERTISE_RTCP setting.\n */\n#ifndef PJMEDIA_HAS_RTCP_IN_SDP\n#   define PJMEDIA_HAS_RTCP_IN_SDP\t\t(PJMEDIA_ADVERTISE_RTCP)\n#endif\n\n\n/**\n * This macro controls whether pjmedia should include SDP\n * bandwidth modifier \"TIAS\" (RFC3890).\n *\n * Note that there is also a run-time variable to turn this setting\n * on or off, defined in endpoint.c. To access this variable, use\n * the following construct\n *\n \\verbatim\n    extern pj_bool_t pjmedia_add_bandwidth_tias_in_sdp;\n\n    // Do not enable bandwidth information inclusion in sdp\n    pjmedia_add_bandwidth_tias_in_sdp = PJ_FALSE;\n \\endverbatim\n *\n * Default: 1 (yes)\n */\n#ifndef PJMEDIA_ADD_BANDWIDTH_TIAS_IN_SDP\n#   define PJMEDIA_ADD_BANDWIDTH_TIAS_IN_SDP\t1\n#endif\n\n\n/**\n * This macro controls whether pjmedia should include SDP rtpmap \n * attribute for static payload types. SDP rtpmap for static\n * payload types are optional, although they are normally included\n * for interoperability reason.\n *\n * Note that there is also a run-time variable to turn this setting\n * on or off, defined in endpoint.c. To access this variable, use\n * the following construct\n *\n \\verbatim\n    extern pj_bool_t pjmedia_add_rtpmap_for_static_pt;\n\n    // Do not include rtpmap for static payload types (<96)\n    pjmedia_add_rtpmap_for_static_pt = PJ_FALSE;\n \\endverbatim\n *\n * Default: 1 (yes)\n */\n#ifndef PJMEDIA_ADD_RTPMAP_FOR_STATIC_PT\n#   define PJMEDIA_ADD_RTPMAP_FOR_STATIC_PT\t1\n#endif\n\n\n/**\n * This macro declares the payload type for telephone-event\n * that is advertised by PJMEDIA for outgoing SDP. If this macro\n * is set to zero, telephone events would not be advertised nor\n * supported.\n *\n * If this value is changed to other number, please update the\n * PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR too.\n */\n#ifndef PJMEDIA_RTP_PT_TELEPHONE_EVENTS\n#   define PJMEDIA_RTP_PT_TELEPHONE_EVENTS\t    96\n#endif\n\n\n/**\n * Macro to get the string representation of the telephone-event\n * payload type.\n */\n#ifndef PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR\n#   define PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR\t    \"96\"\n#endif\n\n\n/**\n * Maximum tones/digits that can be enqueued in the tone generator.\n */\n#ifndef PJMEDIA_TONEGEN_MAX_DIGITS\n#   define PJMEDIA_TONEGEN_MAX_DIGITS\t\t    32\n#endif\n\n\n/* \n * Below specifies the various tone generator backend algorithm.\n */\n\n/** \n * The math's sine(), floating point. This has very good precision \n * but it's the slowest and requires floating point support and\n * linking with the math library.\n */\n#define PJMEDIA_TONEGEN_SINE\t\t\t    1\n\n/**\n * Floating point approximation of sine(). This has relatively good\n * precision and much faster than plain sine(), but it requires floating-\n * point support and linking with the math library.\n */\n#define PJMEDIA_TONEGEN_FLOATING_POINT\t\t    2\n\n/**\n * Fixed point using sine signal generated by Cordic algorithm. This\n * algorithm can be tuned to provide balance between precision and\n * performance by tuning the PJMEDIA_TONEGEN_FIXED_POINT_CORDIC_LOOP \n * setting, and may be suitable for platforms that lack floating-point\n * support.\n */\n#define PJMEDIA_TONEGEN_FIXED_POINT_CORDIC\t    3\n\n/**\n * Fast fixed point using some approximation to generate sine waves.\n * The tone generated by this algorithm is not very precise, however\n * the algorithm is very fast.\n */\n#define PJMEDIA_TONEGEN_FAST_FIXED_POINT\t    4\n\n\n/**\n * Specify the tone generator algorithm to be used. Please see \n * http://trac.pjsip.org/repos/wiki/Tone_Generator for the performance\n * analysis results of the various tone generator algorithms.\n *\n * Default value:\n *  - PJMEDIA_TONEGEN_FLOATING_POINT when PJ_HAS_FLOATING_POINT is set\n *  - PJMEDIA_TONEGEN_FIXED_POINT_CORDIC when PJ_HAS_FLOATING_POINT is not set\n */\n#ifndef PJMEDIA_TONEGEN_ALG\n#   if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT\n#\tdefine PJMEDIA_TONEGEN_ALG\tPJMEDIA_TONEGEN_FLOATING_POINT\n#   else\n#\tdefine PJMEDIA_TONEGEN_ALG\tPJMEDIA_TONEGEN_FIXED_POINT_CORDIC\n#   endif\n#endif\n\n\n/**\n * Specify the number of calculation loops to generate the tone, when\n * PJMEDIA_TONEGEN_FIXED_POINT_CORDIC algorithm is used. With more calculation\n * loops, the tone signal gets more precise, but this will add more \n * processing.\n *\n * Valid values are 1 to 28.\n *\n * Default value: 10\n */\n#ifndef PJMEDIA_TONEGEN_FIXED_POINT_CORDIC_LOOP\n#   define PJMEDIA_TONEGEN_FIXED_POINT_CORDIC_LOOP  10\n#endif\n\n\n/**\n * Enable high quality of tone generation, the better quality will cost\n * more CPU load. This is only applied to floating point enabled machines.\n *\n * By default it is enabled when PJ_HAS_FLOATING_POINT is set.\n *\n * This macro has been deprecated in version 1.0-rc3.\n */\n#ifdef PJMEDIA_USE_HIGH_QUALITY_TONEGEN\n#   error   \"The PJMEDIA_USE_HIGH_QUALITY_TONEGEN macro is obsolete\"\n#endif\n\n\n/**\n * Fade-in duration for the tone, in milliseconds. Set to zero to disable\n * this feature.\n *\n * Default: 1 (msec)\n */\n#ifndef PJMEDIA_TONEGEN_FADE_IN_TIME\n#   define PJMEDIA_TONEGEN_FADE_IN_TIME\t\t    1\n#endif\n\n\n/**\n * Fade-out duration for the tone, in milliseconds. Set to zero to disable\n * this feature.\n *\n * Default: 2 (msec)\n */\n#ifndef PJMEDIA_TONEGEN_FADE_OUT_TIME\n#   define PJMEDIA_TONEGEN_FADE_OUT_TIME\t    2\n#endif\n\n\n/**\n * The default tone generator amplitude (1-32767).\n *\n * Default value: 12288\n */\n#ifndef PJMEDIA_TONEGEN_VOLUME\n#   define PJMEDIA_TONEGEN_VOLUME\t\t    12288\n#endif\n\n\n/**\n * Enable support for SRTP media transport. This will require linking\n * with libsrtp from the third_party directory.\n *\n * By default it is enabled.\n */\n#ifndef PJMEDIA_HAS_SRTP\n#   define PJMEDIA_HAS_SRTP\t\t\t    1\n#endif\n\n\n/**\n * Let the library handle libsrtp initialization and deinitialization.\n * Application may want to disable this and manually perform libsrtp\n * initialization and deinitialization when it needs to use libsrtp\n * before the library is initialized or after the library is shutdown.\n *\n * By default it is enabled.\n */\n#ifndef PJMEDIA_LIBSRTP_AUTO_INIT_DEINIT\n#   define PJMEDIA_LIBSRTP_AUTO_INIT_DEINIT\t    1\n#endif\n\n\n/**\n * Enable support to handle codecs with inconsistent clock rate\n * between clock rate in SDP/RTP & the clock rate that is actually used.\n * This happens for example with G.722 and MPEG audio codecs.\n * See:\n *  - G.722      : RFC 3551 4.5.2\n *  - MPEG audio : RFC 3551 4.5.13 & RFC 3119\n *\n * Also when this feature is enabled, some handling will be performed\n * to deal with clock rate incompatibilities of some phones.\n *\n * By default it is enabled.\n */\n#ifndef PJMEDIA_HANDLE_G722_MPEG_BUG\n#   define PJMEDIA_HANDLE_G722_MPEG_BUG\t\t    1\n#endif\n\n\n/**\n * Transport info (pjmedia_transport_info) contains a socket info and list\n * of transport specific info, since transports can be chained together \n * (for example, SRTP transport uses UDP transport as the underlying \n * transport). This constant specifies maximum number of transport specific\n * infos that can be held in a transport info.\n */\n#ifndef PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT\n#   define PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT   4\n#endif\n\n\n/**\n * Maximum size in bytes of storage buffer of a transport specific info.\n */\n#ifndef PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE\n#   define PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE  (36*sizeof(long))\n#endif\n\n\n/**\n * Value to be specified in PJMEDIA_STREAM_ENABLE_KA setting.\n * This indicates that an empty RTP packet should be used as\n * the keep-alive packet.\n */\n#define PJMEDIA_STREAM_KA_EMPTY_RTP\t\t    1\n\n/**\n * Value to be specified in PJMEDIA_STREAM_ENABLE_KA setting.\n * This indicates that a user defined packet should be used\n * as the keep-alive packet. The content of the user-defined\n * packet is specified by PJMEDIA_STREAM_KA_USER_PKT. Default\n * content is a CR-LF packet.\n */\n#define PJMEDIA_STREAM_KA_USER\t\t\t    2\n\n/**\n * The content of the user defined keep-alive packet. The format\n * of the packet is initializer to pj_str_t structure. Note that\n * the content may contain NULL character.\n */\n#ifndef PJMEDIA_STREAM_KA_USER_PKT\n#   define PJMEDIA_STREAM_KA_USER_PKT\t{ \"\\r\\n\", 2 }\n#endif\n\n/**\n * Specify another type of keep-alive and NAT hole punching \n * mechanism (the other type is PJMEDIA_STREAM_VAD_SUSPEND_MSEC\n * and PJMEDIA_CODEC_MAX_SILENCE_PERIOD) to be used by stream. \n * When this feature is enabled, the stream will initially \n * transmit one packet to punch a hole in NAT, and periodically\n * transmit keep-alive packets.\n *\n * When this alternative keep-alive mechanism is used, application\n * may disable the other keep-alive mechanisms, i.e: by setting \n * PJMEDIA_STREAM_VAD_SUSPEND_MSEC to zero and \n * PJMEDIA_CODEC_MAX_SILENCE_PERIOD to -1.\n *\n * The value of this macro specifies the type of packet used\n * for the keep-alive mechanism. Valid values are\n * PJMEDIA_STREAM_KA_EMPTY_RTP and PJMEDIA_STREAM_KA_USER.\n * \n * The duration of the keep-alive interval further can be set\n * with PJMEDIA_STREAM_KA_INTERVAL setting.\n *\n * Default: 0 (disabled)\n */\n#ifndef PJMEDIA_STREAM_ENABLE_KA\n#   define PJMEDIA_STREAM_ENABLE_KA\t\t    0\n#endif\n\n\n/**\n * Specify the keep-alive interval of PJMEDIA_STREAM_ENABLE_KA\n * mechanism, in seconds.\n *\n * Default: 5 seconds\n */\n#ifndef PJMEDIA_STREAM_KA_INTERVAL\n#   define PJMEDIA_STREAM_KA_INTERVAL\t\t    5\n#endif\n\n\n/*\n * .... new stuffs ...\n */\n\n/*\n * Video\n */\n\n/**\n * Top level option to enable/disable video features.\n *\n * Default: 1 (enabled)\n */\n#ifndef PJMEDIA_HAS_VIDEO\n#   define PJMEDIA_HAS_VIDEO\t\t\t\t1\n#endif\n\n\n/**\n * Specify if FFMPEG is available. The value here will be used as the default\n * value for other FFMPEG settings below.\n *\n * Default: 0\n */\n#ifndef PJMEDIA_HAS_FFMPEG\n#   define PJMEDIA_HAS_FFMPEG\t\t\t\t0\n#endif\n\n/**\n * Specify if FFMPEG libavformat is available.\n *\n * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)\n */\n#ifndef PJMEDIA_HAS_LIBAVFORMAT\n#   define PJMEDIA_HAS_LIBAVFORMAT\t\t\tPJMEDIA_HAS_FFMPEG\n#endif\n\n/**\n * Specify if FFMPEG libavformat is available.\n *\n * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)\n */\n#ifndef PJMEDIA_HAS_LIBAVCODEC\n#   define PJMEDIA_HAS_LIBAVCODEC\t\t\tPJMEDIA_HAS_FFMPEG\n#endif\n\n/**\n * Specify if FFMPEG libavutil is available.\n *\n * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)\n */\n#ifndef PJMEDIA_HAS_LIBAVUTIL\n#   define PJMEDIA_HAS_LIBAVUTIL\t\t\tPJMEDIA_HAS_FFMPEG\n#endif\n\n/**\n * Specify if FFMPEG libswscale is available.\n *\n * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)\n */\n#ifndef PJMEDIA_HAS_LIBSWSCALE\n#   define PJMEDIA_HAS_LIBSWSCALE\t\t\tPJMEDIA_HAS_FFMPEG\n#endif\n\n/**\n * Specify if FFMPEG libavcore is available.\n *\n * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)\n */\n#ifndef PJMEDIA_HAS_LIBAVCORE\n#   define PJMEDIA_HAS_LIBAVCORE\t\t\tPJMEDIA_HAS_FFMPEG\n#endif\n\n/**\n * Specify if libvpx is available.\n *\n * Default: 0 (or detected by configure)\n */\n#ifndef PJMEDIA_HAS_LIBVPX\n#   define PJMEDIA_HAS_LIBVPX\t\t\t        0\n#endif\n\n/**\n * Maximum video planes.\n *\n * Default: 4\n */\n#ifndef PJMEDIA_MAX_VIDEO_PLANES\n#   define PJMEDIA_MAX_VIDEO_PLANES\t\t\t4\n#endif\n\n/**\n * Maximum number of video formats.\n *\n * Default: 32\n */\n#ifndef PJMEDIA_MAX_VIDEO_FORMATS\n#   define PJMEDIA_MAX_VIDEO_FORMATS\t\t\t32\n#endif\n\n/**\n * Specify the maximum time difference (in ms) for synchronization between\n * two medias. If the synchronization media source is ahead of time\n * greater than this duration, it is considered to make a very large jump\n * and the synchronization will be reset.\n *\n * Default: 20000\n */\n#ifndef PJMEDIA_CLOCK_SYNC_MAX_SYNC_MSEC\n#   define PJMEDIA_CLOCK_SYNC_MAX_SYNC_MSEC         20000\n#endif\n\n/**\n * Maximum video frame size.\n * Default: 128kB\n */\n#ifndef PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE\n#  define PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE\t    (1<<17)\n#endif\n\n\n/**\n * Specify the maximum duration (in ms) for resynchronization. When a media\n * is late to another media it is supposed to be synchronized to, it is\n * guaranteed to be synchronized again after this duration. While if the\n * media is ahead/early by t ms, it is guaranteed to be synchronized after\n * t + this duration. This timing only applies if there is no additional\n * resynchronization required during the specified duration.\n *\n * Default: 2000\n */\n#ifndef PJMEDIA_CLOCK_SYNC_MAX_RESYNC_DURATION\n#   define PJMEDIA_CLOCK_SYNC_MAX_RESYNC_DURATION 2000\n#endif\n\n\n/**\n * Minimum gap between two consecutive discards in jitter buffer,\n * in milliseconds.\n *\n * Default: 200 ms\n */\n#ifndef PJMEDIA_JBUF_DISC_MIN_GAP\n#   define PJMEDIA_JBUF_DISC_MIN_GAP\t\t    200\n#endif\n\n\n/**\n * Minimum burst level reference used for calculating discard duration\n * in jitter buffer progressive discard algorithm, in frames.\n * \n * Default: 1 frame\n */\n#ifndef PJMEDIA_JBUF_PRO_DISC_MIN_BURST\n#   define PJMEDIA_JBUF_PRO_DISC_MIN_BURST\t    1\n#endif\n\n\n/**\n * Maximum burst level reference used for calculating discard duration\n * in jitter buffer progressive discard algorithm, in frames.\n * \n * Default: 200 frames\n */\n#ifndef PJMEDIA_JBUF_PRO_DISC_MAX_BURST\n#   define PJMEDIA_JBUF_PRO_DISC_MAX_BURST\t    100\n#endif\n\n\n/**\n * Duration for progressive discard algotithm in jitter buffer to discard\n * an excessive frame when burst is equal to or lower than\n * PJMEDIA_JBUF_PRO_DISC_MIN_BURST, in milliseconds.\n *\n * Default: 2000 ms\n */\n#ifndef PJMEDIA_JBUF_PRO_DISC_T1\n#   define PJMEDIA_JBUF_PRO_DISC_T1\t\t    2000\n#endif\n\n\n/**\n * Duration for progressive discard algotithm in jitter buffer to discard\n * an excessive frame when burst is equal to or greater than\n * PJMEDIA_JBUF_PRO_DISC_MAX_BURST, in milliseconds.\n *\n * Default: 10000 ms\n */\n#ifndef PJMEDIA_JBUF_PRO_DISC_T2\n#   define PJMEDIA_JBUF_PRO_DISC_T2\t\t    10000\n#endif\n\n\n/**\n * Video stream will discard old picture from the jitter buffer as soon as\n * new picture is received, to reduce latency.\n *\n * Default: 0\n */\n#ifndef PJMEDIA_VID_STREAM_SKIP_PACKETS_TO_REDUCE_LATENCY\n#   define PJMEDIA_VID_STREAM_SKIP_PACKETS_TO_REDUCE_LATENCY\t0\n#endif\n\n\n/**\n * Maximum video payload size. Note that this must not be greater than\n * PJMEDIA_MAX_MTU.\n *\n * Default: (PJMEDIA_MAX_MTU - 100)\n */\n#ifndef PJMEDIA_MAX_VID_PAYLOAD_SIZE\t\t\t\n#  define PJMEDIA_MAX_VID_PAYLOAD_SIZE\t\t(PJMEDIA_MAX_MTU - 100)\n#endif\n\n\n/**\n * Specify target value for socket receive buffer size. It will be\n * applied to RTP socket of media transport using setsockopt(). When\n * transport failed to set the specified size, it will try with lower\n * value until the highest possible is successfully set.\n *\n * Setting this to zero will leave the socket receive buffer size to\n * OS default (e.g: usually 8 KB on desktop platforms).\n *\n * Default: 64 KB when video is enabled, otherwise zero (OS default)\n */\n#ifndef PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE\n#   if PJMEDIA_HAS_VIDEO\n#\tdefine PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE\t(64*1024)\n#   else\n#\tdefine PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE\t0\n#   endif\n#endif\n\n\n/**\n * Specify target value for socket send buffer size. It will be\n * applied to RTP socket of media transport using setsockopt(). When\n * transport failed to set the specified size, it will try with lower\n * value until the highest possible is successfully set.\n *\n * Setting this to zero will leave the socket send buffer size to\n * OS default (e.g: usually 8 KB on desktop platforms).\n *\n * Default: 64 KB when video is enabled, otherwise zero (OS default)\n */\n#ifndef PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE\n#   if PJMEDIA_HAS_VIDEO\n#\tdefine PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE\t(64*1024)\n#   else\n#\tdefine PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE\t0\n#   endif\n#endif\n\n/**\n * Specify if libyuv is available.\n *\n * Default: 0 (disable)\n */\n#ifndef PJMEDIA_HAS_LIBYUV\n#   define PJMEDIA_HAS_LIBYUV\t\t\t\t0\n#endif\n\n\n/**\n * Specify if dtmf flash in RFC 2833 is available.\n */\n#ifndef PJMEDIA_HAS_DTMF_FLASH\n#   define PJMEDIA_HAS_DTMF_FLASH\t\t\t1\n#endif\n\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_CONFIG_H__ */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/config_auto.h.in",
    "content": "/* $Id: config_auto.h.in 3295 2010-08-25 12:51:29Z bennylp $ */\n/*\n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef __PJMEDIA_CONFIG_AUTO_H_\n#define __PJMEDIA_CONFIG_AUTO_H_\n\n/**\n * @file config_auto.h\n * @brief PJMEDIA configuration as set by autoconf script\n */\n\n/*\n * Note:\n *\tThe configuration in config_site.h overrides any other settings,\n *\tincluding the setting as detected by autoconf. \n */\n \n/* G711 codec */\n#ifndef PJMEDIA_HAS_G711_CODEC\n#undef PJMEDIA_HAS_G711_CODEC\n#endif\n\n\n#endif\t/* __PJMEDIA_CONFIG_AUTO_H_ */\n\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/converter.h",
    "content": "/* $Id: converter.h 3664 2011-07-19 03:42:28Z nanang $ */\n/*\n * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef __PJMEDIA_CONVERTER_H__\n#define __PJMEDIA_CONVERTER_H__\n\n\n/**\n * @file pjmedia/converter.h Format conversion utilities\n * @brief Format conversion utilities\n */\n\n#include <pjmedia/frame.h>\n#include <pjmedia/format.h>\n#include <pj/list.h>\n#include <pj/pool.h>\n\n\n/**\n * @defgroup PJMEDIA_CONVERTER Format converter\n * @ingroup PJMEDIA_FRAME_OP\n * @brief Audio and video converter utilities\n * @{\n */\n\nPJ_BEGIN_DECL\n\n/**\n * This describes conversion parameter. It specifies the source and\n * destination formats of the conversion.\n */\ntypedef struct pjmedia_conversion_param\n{\n    pjmedia_format\tsrc;\t/**< Source format.\t\t*/\n    pjmedia_format\tdst;\t/**< Destination format.\t*/\n} pjmedia_conversion_param;\n\n\n/** Forward declaration of factory operation structure */\ntypedef struct pjmedia_converter_factory_op pjmedia_converter_factory_op;\n\n/**\n * Converter priority guides. Converter priority determines which converter\n * instance to be used if more than one converters are able to perform the\n * requested conversion. Converter implementor can use this value to order\n * the preference based on attributes such as quality or performance. Higher\n * number indicates higher priority.\n */\ntypedef enum pjmedia_converter_priority_guide\n{\n    /** Lowest priority. */\n    PJMEDIA_CONVERTER_PRIORITY_LOWEST \t\t= 0,\n\n    /** Normal priority. */\n    PJMEDIA_CONVERTER_PRIORITY_NORMAL \t\t= 15000,\n\n    /** Highest priority. */\n    PJMEDIA_CONVERTER_PRIORITY_HIGHEST \t\t= 32000\n} pjmedia_converter_priority_guide;\n\n/**\n * Converter factory. The converter factory registers a callback function\n * to create converters.\n */\ntypedef struct pjmedia_converter_factory\n{\n    /**\n     * Standard list members.\n     */\n    PJ_DECL_LIST_MEMBER(struct pjmedia_converter_factory);\n\n    /**\n     * Factory name.\n     */\n    const char \t\t\t *name;\n\n    /**\n     * Converter priority determines which converter instance to be used if\n     * more than one converters are able to perform the requested conversion.\n     * Converter implementor can use this value to order the preference based\n     * on attributes such as quality or performance. Higher number indicates\n     * higher priority. The pjmedia_converter_priority_guide enumeration shall\n     * be used as the base value to set the priority.\n     */\n    int priority;\n\n    /**\n     * Pointer to factory operation.\n     */\n    pjmedia_converter_factory_op *op;\n\n} pjmedia_converter_factory;\n\n/** Forward declaration for converter operation. */\ntypedef struct pjmedia_converter_op pjmedia_converter_op;\n\n/**\n * This structure describes a converter instance.\n */\ntypedef struct pjmedia_converter\n{\n    /**\n     * Pointer to converter operation.\n     */\n    pjmedia_converter_op *op;\n\n} pjmedia_converter;\n\n\n/**\n * Converter factory operation.\n */\nstruct pjmedia_converter_factory_op\n{\n    /**\n     * This function creates a converter with the specified conversion format,\n     * if such format is supported.\n     *\n     * @param cf\tThe converter factory.\n     * @param pool\tPool to allocate memory from.\n     * @param prm\tConversion parameter.\n     * @param p_cv\tPointer to hold the created converter instance.\n     *\n     * @return\t\tPJ_SUCCESS if converter has been created successfully.\n     */\n    pj_status_t (*create_converter)(pjmedia_converter_factory *cf,\n\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t    const pjmedia_conversion_param *prm,\n\t\t\t\t    pjmedia_converter **p_cv);\n\n    /**\n     * Destroy the factory.\n     *\n     * @param cf\tThe converter factory.\n     */\n    void (*destroy_factory)(pjmedia_converter_factory *cf);\n};\n\n/**\n * Converter operation.\n */\nstruct pjmedia_converter_op\n{\n    /**\n     * Convert the buffer in the source frame and save the result in the\n     * buffer of the destination frame, according to conversion format that\n     * was specified when the converter was created.\n     *\n     * Note that application should use #pjmedia_converter_convert() instead\n     * of calling this function directly.\n     *\n     * @param cv\tThe converter instance.\n     * @param src_frame\tThe source frame.\n     * @param dst_frame\tThe destination frame.\n     *\n     * @return\t\tPJ_SUCCESS if conversion has been performed\n     * \t\t\tsuccessfully.\n     */\n    pj_status_t (*convert)(pjmedia_converter *cv,\n\t\t\t   pjmedia_frame *src_frame,\n\t\t\t   pjmedia_frame *dst_frame);\n\n    /**\n     * Destroy the converter instance.\n     *\n     * Note that application should use #pjmedia_converter_destroy() instead\n     * of calling this function directly.\n     *\n     * @param cv\tThe converter.\n     */\n    void (*destroy)(pjmedia_converter *cv);\n\n};\n\n\n/**\n * Opaque data type for conversion manager. Typically, the conversion manager\n * is a singleton instance, although application may instantiate more than one\n * instances of this if required.\n */\ntypedef struct pjmedia_converter_mgr pjmedia_converter_mgr;\n\n\n/**\n * Create a new conversion manager instance. This will also set the pointer\n * to the singleton instance if the value is still NULL.\n *\n * @param pool\t\tPool to allocate memory from.\n * @param mgr\t\tPointer to hold the created instance of the\n * \t\t\tconversion manager.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_converter_mgr_create(pj_pool_t *pool,\n\t\t\t\t\t\t  pjmedia_converter_mgr **mgr);\n\n/**\n * Get the singleton instance of the conversion manager.\n *\n * @return\t\tThe instance.\n */\nPJ_DECL(pjmedia_converter_mgr*) pjmedia_converter_mgr_instance(void);\n\n/**\n * Manually assign a specific video manager instance as the singleton\n * instance. Normally this is not needed if only one instance is ever\n * going to be created, as the library automatically assign the singleton\n * instance.\n *\n * @param mgr\t\tThe instance to be used as the singleton instance.\n * \t\t\tApplication may specify NULL to clear the singleton\n * \t\t\tsingleton instance.\n */\nPJ_DECL(void) pjmedia_converter_mgr_set_instance(pjmedia_converter_mgr *mgr);\n\n/**\n * Destroy a converter manager. If the manager happens to be the singleton\n * instance, the singleton instance will be set to NULL.\n *\n * @param mgr\t\tThe converter manager. Specify NULL to use\n * \t\t\tthe singleton instance.\n */\nPJ_DECL(void) pjmedia_converter_mgr_destroy(pjmedia_converter_mgr *mgr);\n\n/**\n * Register a converter factory to the converter manager.\n *\n * @param mgr\t\tThe converter manager. Specify NULL to use\n * \t\t\tthe singleton instance.\n * @param f\t\tThe converter factory to be registered.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t)\npjmedia_converter_mgr_register_factory(pjmedia_converter_mgr *mgr,\n\t\t\t\t       pjmedia_converter_factory *f);\n\n/**\n * Unregister a previously registered converter factory from the converter\n * manager.\n *\n * @param mgr\t\tThe converter manager. Specify NULL to use\n * \t\t\tthe singleton instance.\n * @param f\t\tThe converter factory to be unregistered.\n * @param call_destroy\tIf this is set to non-zero, the \\a destroy_factory()\n * \t\t\tcallback of the factory will be called while\n * \t\t\tunregistering the factory from the manager.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t)\npjmedia_converter_mgr_unregister_factory(pjmedia_converter_mgr *mgr,\n\t\t\t\t         pjmedia_converter_factory *f,\n\t\t\t\t         pj_bool_t call_destroy);\n\n/**\n * Create a converter instance to perform the specified format conversion\n * as specified in \\a param.\n *\n * @param mgr\t\tThe converter manager. Specify NULL to use\n * \t\t\tthe singleton instance.\n * @param pool\t\tPool to allocate the memory from.\n * @param param\t\tConversion parameter.\n * @param p_cv\t\tPointer to hold the created converter.\n *\n * @return\t\tPJ_SUCCESS if a converter has been created successfully\n * \t\t\tor the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_converter_create(pjmedia_converter_mgr *mgr,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      pjmedia_conversion_param *param,\n\t\t\t\t\t      pjmedia_converter **p_cv);\n\n/**\n * Convert the buffer in the source frame and save the result in the\n * buffer of the destination frame, according to conversion format that\n * was specified when the converter was created.\n *\n * @param cv\t\tThe converter instance.\n * @param src_frame\tThe source frame.\n * @param dst_frame\tThe destination frame.\n *\n * @return\t\tPJ_SUCCESS if conversion has been performed\n * \t\t\tsuccessfully.\n */\nPJ_DECL(pj_status_t) pjmedia_converter_convert(pjmedia_converter *cv,\n\t\t\t\t\t       pjmedia_frame *src_frame,\n\t\t\t\t\t       pjmedia_frame *dst_frame);\n\n/**\n * Destroy the converter.\n *\n * @param cv\t\tThe converter instance.\n */\nPJ_DECL(void) pjmedia_converter_destroy(pjmedia_converter *cv);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif /* __PJMEDIA_CONVERTER_H__ */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/delaybuf.h",
    "content": "/* $Id: delaybuf.h 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#ifndef __PJMEDIA_DELAYBUF_H__\n#define __PJMEDIA_DELAYBUF_H__\n\n\n/**\n * @file delaybuf.h\n * @brief Delay Buffer.\n */\n\n#include <pjmedia/types.h>\n\n/**\n * @defgroup PJMED_DELAYBUF Adaptive Delay Buffer\n * @ingroup PJMEDIA_FRAME_OP\n * @brief Adaptive delay buffer with high-quality time-scale\n * modification\n * @{\n *\n * This section describes PJMEDIA's implementation of delay buffer.\n * Delay buffer works quite similarly like a fixed jitter buffer, that\n * is it will delay the frame retrieval by some interval so that caller\n * will get continuous frame from the buffer. This can be useful when\n * the put() and get() operations are not evenly interleaved, for example\n * when caller performs burst of put() operations and then followed by\n * burst of get() operations. With using this delay buffer, the buffer\n * will put the burst frames into a buffer so that get() operations\n * will always get a frame from the buffer (assuming that the number of\n * get() and put() are matched).\n *\n * The buffer is adaptive, that is it continuously learns the optimal delay\n * to be applied to the audio flow at run-time. Once the optimal delay has \n * been learned, the delay buffer will apply this delay to the audio flow,\n * expanding or shrinking the audio samples as necessary when the actual\n * audio samples in the buffer are too low or too high. It does this without\n * distorting the audio quality of the audio, by using \\a PJMED_WSOLA.\n *\n * The delay buffer is used in \\ref PJMED_SND_PORT, \\ref PJMEDIA_SPLITCOMB,\n * and \\ref PJMEDIA_CONF.\n */\n\nPJ_BEGIN_DECL\n\n/** Opaque declaration for delay buffer. */\ntypedef struct pjmedia_delay_buf pjmedia_delay_buf;\n\n/**\n * Delay buffer options.\n */\ntypedef enum pjmedia_delay_buf_flag\n{\n    /**\n     * Use simple FIFO mechanism for the delay buffer, i.e.\n     * without WSOLA for expanding and shrinking audio samples.\n     */\n    PJMEDIA_DELAY_BUF_SIMPLE_FIFO = 1\n\n} pjmedia_delay_buf_flag;\n\n/**\n * Create the delay buffer. Once the delay buffer is created, it will\n * enter learning state unless the delay argument is specified, which\n * in this case it will directly enter the running state.\n *\n * @param pool\t\t    Pool where the delay buffer will be allocated\n *\t\t\t    from.\n * @param name\t\t    Optional name for the buffer for log \n *\t\t\t    identification.\n * @param clock_rate\t    Number of samples processed per second.\n * @param samples_per_frame Number of samples per frame.\n * @param channel_count\t    Number of channel per frame.\n * @param max_delay\t    Maximum number of delay to be accommodated,\n *\t\t\t    in ms, if this value is negative or less than \n *\t\t\t    one frame time, default maximum delay used is\n *\t\t\t    400 ms.\n * @param options\t    Options. If PJMEDIA_DELAY_BUF_SIMPLE_FIFO is\n *                          specified, then a simple FIFO mechanism\n *\t\t\t    will be used instead of the adaptive\n *                          implementation (which uses WSOLA to expand\n *                          or shrink audio samples).\n *\t\t\t    See #pjmedia_delay_buf_flag for other options.\n * @param p_b\t\t    Pointer to receive the delay buffer instance.\n *\n * @return\t\t    PJ_SUCCESS if the delay buffer has been\n *\t\t\t    created successfully, otherwise the appropriate\n *\t\t\t    error will be returned.\n */\nPJ_DECL(pj_status_t) pjmedia_delay_buf_create(pj_pool_t *pool,\n\t\t\t\t\t      const char *name,\n\t\t\t\t\t      unsigned clock_rate,\n\t\t\t\t\t      unsigned samples_per_frame,\n\t\t\t\t\t      unsigned channel_count,\n\t\t\t\t\t      unsigned max_delay,\n\t\t\t\t\t      unsigned options,\n\t\t\t\t\t      pjmedia_delay_buf **p_b);\n\n/**\n * Put one frame into the buffer.\n *\n * @param b\t\t    The delay buffer.\n * @param frame\t\t    Frame to be put into the buffer. This frame\n *\t\t\t    must have samples_per_frame length.\n *\n * @return\t\t    PJ_SUCCESS if frames can be put successfully.\n *\t\t\t    PJ_EPENDING if the buffer is still at learning\n *\t\t\t    state. PJ_ETOOMANY if the number of frames\n *\t\t\t    will exceed maximum delay level, which in this\n *\t\t\t    case the new frame will overwrite the oldest\n *\t\t\t    frame in the buffer.\n */\nPJ_DECL(pj_status_t) pjmedia_delay_buf_put(pjmedia_delay_buf *b,\n\t\t\t\t\t   pj_int16_t frame[]);\n\n/**\n * Get one frame from the buffer.\n *\n * @param b\t\t    The delay buffer.\n * @param frame\t\t    Buffer to receive the frame from the delay\n *\t\t\t    buffer.\n *\n * @return\t\t    PJ_SUCCESS if frame has been copied successfully.\n *\t\t\t    PJ_EPENDING if no frame is available, either\n *\t\t\t    because the buffer is still at learning state or\n *\t\t\t    no buffer is available during running state.\n *\t\t\t    On non-successful return, the frame will be\n *\t\t\t    filled with zeroes.\n */\nPJ_DECL(pj_status_t) pjmedia_delay_buf_get(pjmedia_delay_buf *b,\n\t\t\t\t\t   pj_int16_t frame[]);\n\n/**\n * Reset delay buffer. This will clear the buffer's content. But keep\n * the learning result.\n *\n * @param b\t\t    The delay buffer.\n *\n * @return\t\t    PJ_SUCCESS on success or the appropriate error.\n */\nPJ_DECL(pj_status_t) pjmedia_delay_buf_reset(pjmedia_delay_buf *b);\n\n/**\n * Destroy delay buffer.\n *\n * @param b\t    Delay buffer session.\n *\n * @return\t    PJ_SUCCESS normally.\n */\nPJ_DECL(pj_status_t) pjmedia_delay_buf_destroy(pjmedia_delay_buf *b);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_DELAYBUF_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/doxygen.h",
    "content": "/* $Id: doxygen.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_DOXYGEN_H__\n#define __PJMEDIA_DOXYGEN_H__\n\n/**\n * @file doxygen.h\n * @brief Doxygen's mainpage.\n */\n\n\n/*////////////////////////////////////////////////////////////////////////// */\n/*\n\tINTRODUCTION PAGE\n */\n\n/**\n * @mainpage PJMEDIA\n *\n * \\n\n * @section intro2 Introduction to PJMEDIA\n *\n * PJMEDIA is a fully featured media stack, distributed under Open Source/GPL\n * terms, and featuring small footprint and good extensibility and excellent\n * portability. Here are some brief overview of PJMEDIA benefits.\n *\n * @subsection benefit Benefits\n * @subsubsection full_feature Many Features\n * PJMEDIA has many features, and rather than to list them all here, please\n * see the <A HREF=\"modules.htm\"><b>Modules</b></A> page for more info.\n *\n * Video is planned to arrive at version 2.\n *\n * @subsubsection portable Excellent Portability\n * It's been ported to all desktop systems and many mobile platforms including\n * Symbian, Windows Mobile, iPhone, and Android. Thanks to its zero thread\n * design, users have been able to run PJMEDIA on deeply embedded platforms,\n * even without operating systems (those typically found in DSP platforms).\n * Except the echo suppressor, all other PJMEDIA components have fixed point\n * implementation, which makes it ideal for embedded systems which lack FPU.\n * PJMEDIA also has tiny footprint, as explained below\n *\n * @subsubsection footprint Tiny Footprint\n * Lets not talk about less meaningful and potentially misleading term such as\n * core footprint, and instead here is the footprint of all components\n * typically used to build a full streaming media:\n *\n * \\verbatim\nCategory        Component       text    data    bss     dec     filename\n-------------------------------------------------------------------------------\nCore            Error subsystem 135     0       0       135     errno.o\nCore            Endpoint        4210    4       4       4218    endpoint.o\nCore            Port framework  652     0       0       652     port.o\nCore            Codec framework 6257    0       0       6257    codec.o\nCodec           Alaw/ulaw conv. 1060    16      0       1076    alaw_ulaw.o\nCodec           G.711           3298    128     96      3522    g711.o\nCodec           PLC             883     24      0       907     plc_common.o\nCodec           PLC             7130    0       0       7130    wsola.o\nSession         Stream          12222   0       1920    14142   stream.o\nTransport       RTCP            3732    0       0       3732    rtcp.o\nTransport       RTP             2568    0       0       2568    rtp.o\nTransport       UDP             6612    96      0       6708    transport_udp.o\nTransport       Jitter buffer   6473    0       0       6473    jbuf.o\n-------------------------------------------------------------------------------\nTOTAL                          55,232   268    2,020    57,520\n\n \\endverbatim\n * The 56KB are for media streaming components, complete with codec, RTP, and\n * RTCP. The footprint above was done for PJSIP version 1.8.2 on a Linux x86\n * machine, using footprintopimization as explained in PJSIP FAQ. Numbers are\n * in bytes.\n *\n * @subsubsection quality Good Quality\n * PJMEDIA supports wideband, ultra-wideband, and beyond, as well as multiple\n * audio channels. The jitter buffer has been proven to work on lower\n * bandwidth links such as 3G, and to some extent, Edge and GPRS. We've grown\n * our own algorithm to compensate for packet losses and clock drifts in audio\n * transmission, as well as feature to use codec's built in PLC if available.\n *\n * @subsubsection hw Hardware Support\n * PJMEDIA supports hardware, firmware, or other built-in feature that comes\n * with the device. These are crucial for mobile devices to allow the best\n * use of the very limited CPU and battery power of the device. Among other\n * things, device's on-board codec and echo cancellation may be used if\n * available.\n *\n * @subsubsection extensible Extensible\n * Despite its tiny footprint, PJMEDIA uses a flexible port concept, which is\n * adapted from filter based concept found in other media framework. It is not\n * as flexible as those found in Direct Show or gstreamer (and that would be\n * unnecessary since it serves different purpose), but it's flexible enough\n * to allow components to be assembled one after another to achieve certain\n * task, and easy creation of such components by application and interconnect\n * them to the rest of the framework.\n *\n * @subsubsection doc (Fairly Okay) Documentation\n * We understand that any documentation can always be improved, but we put\n * a lot of efforts in creating and maintaining our documentation, because\n * we know it matters.\n *\n * \\n\n * @subsection org1 Organization\n *\n * At the top-most level, PJMEDIA library suite contains the following\n * libraries.\n *\n * @subsubsection libpjmedia PJMEDIA\n * This contains all main media components. Please see the\n * <A HREF=\"modules.htm\"><b>Modules</b></A> page for complete list of\n * components that PJMEDIA provides.\n *\n * @subsubsection libpjmediacodec PJMEDIA Codec\n * PJMEDIA-CODEC is a static library containing various codec implementations,\n * wrapped into PJMEDIA codec framework. The static library is designed as\n * such so that only codecs that are explicitly initialized are linked with \n * the application, therefore keeping the application size in control.\n *\n * Please see @ref PJMEDIA_CODEC for more info.\n *\n * @subsubsection libpjmediaaudiodev PJMEDIA Audio Device\n * PJMEDIA-Audiodev is audio device framework and abstraction library. Please\n * see @ref audio_device_api for more info.\n *\n * \\n\n * @section pjmedia_concepts PJMEDIA Key Concepts\n * Below are some key concepts in PJMEDIA:\n *  - @ref PJMEDIA_PORT\n *  - @ref PJMEDIA_PORT_CLOCK\n *  - @ref PJMEDIA_TRANSPORT\n *  - @ref PJMEDIA_SESSION\n */\n\n\n/**\n  @page page_pjmedia_samples PJMEDIA and PJMEDIA-CODEC Examples\n\n  @section pjmedia_samples_sec PJMEDIA and PJMEDIA-CODEC Examples\n\n  Please find below some PJMEDIA related examples that may help in giving\n  some more info:\n\n  - @ref page_pjmedia_samples_level_c\\n\n    This is a good place to start learning about @ref PJMEDIA_PORT,\n    as it shows that @ref PJMEDIA_PORT are only \"passive\" objects\n    with <tt>get_frame()</tt> and <tt>put_frame()</tt> interface, and\n    someone has to call these to retrieve/store media frames.\n\n  - @ref page_pjmedia_samples_playfile_c\\n\n    This example shows that when application connects a media port (in this\n    case a @ref PJMEDIA_FILE_PLAY) to @ref PJMED_SND_PORT, media will flow\n    automatically since the @ref PJMED_SND_PORT provides @ref PJMEDIA_PORT_CLOCK.\n\n  - @ref page_pjmedia_samples_recfile_c\\n\n    Demonstrates how to capture audio from microphone to WAV file.\n\n  - @ref page_pjmedia_samples_playsine_c\\n\n    Demonstrates how to create a custom @ref PJMEDIA_PORT (in this\n    case a sine wave generator) and integrate it to PJMEDIA.\n\n  - @ref page_pjmedia_samples_confsample_c\\n\n    This demonstrates how to use the @ref PJMEDIA_CONF. The sample program can \n    open multiple WAV files, and instruct the conference bridge to mix the\n    signal before playing it to the sound device.\n\n  - @ref page_pjmedia_samples_confbench_c\\n\n    I use this to benchmark/optimize the conference bridge algorithm, but\n    readers may find the source useful.\n\n  - @ref page_pjmedia_samples_resampleplay_c\\n\n    Demonstrates how to use @ref PJMEDIA_RESAMPLE_PORT to change the\n    sampling rate of a media port (in this case, a @ref PJMEDIA_FILE_PLAY).\n\n  - @ref page_pjmedia_samples_sndtest_c\\n\n    This program performs some tests to the sound device to get some\n    quality parameters (such as sound jitter and clock drifts).\\n\n    Screenshots on WinXP: \\image html sndtest.jpg \"sndtest screenshot on WinXP\"\n\n  - @ref page_pjmedia_samples_streamutil_c\\n\n    This example mainly demonstrates how to stream media (in this case a\n    @ref PJMEDIA_FILE_PLAY) to remote peer using RTP.\n\n  - @ref page_pjmedia_samples_siprtp_c\\n\n    This is a useful program (integrated with PJSIP) to actively measure \n    the network quality/impairment parameters by making one or more SIP \n    calls (or receiving one or more SIP calls) and display the network\n    impairment of each stream direction at the end of the call.\n    The program is able to measure network quality parameters such as\n    jitter, packet lost/reorder/duplicate, round trip time, etc.\\n\n    Note that the remote peer MUST support RTCP so that network quality\n    of each direction can be calculated. Using siprtp for both endpoints\n    is recommended.\\n\n    Screenshots on WinXP: \\image html siprtp.jpg \"siprtp screenshot on WinXP\"\n\n  - @ref page_pjmedia_samples_tonegen_c\\n\n    This is a simple program to generate a tone and write the samples to\n    a raw PCM file. The main purpose of this file is to analyze the\n    quality of the tones/sine wave generated by PJMEDIA tone/sine wave\n    generator.\n\n  - @ref page_pjmedia_samples_aectest_c\\n\n    Play a file to speaker, run AEC, and record the microphone input\n    to see if echo is coming.\n */\n\n/**\n * \\page page_pjmedia_samples_siprtp_c Samples: Using SIP and Custom RTP/RTCP to Monitor Quality\n *\n * This source is an example to demonstrate using SIP and RTP/RTCP framework\n * to measure the network quality/impairment from the SIP call. This\n * program can be used to make calls or to receive calls from other\n * SIP endpoint (or other siprtp program), and to display the media\n * quality statistics at the end of the call.\n *\n * Note that the remote peer must support RTCP.\n *\n * The layout of the program has been designed so that custom reporting\n * can be generated instead of plain human readable text.\n *\n * The source code of the file is pjsip-apps/src/samples/siprtp.c\n *\n * Screenshots on WinXP: \\image html siprtp.jpg\n *\n * \\includelineno siprtp.c\n */\n\n#endif /* __PJMEDIA_DOXYGEN_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/echo.h",
    "content": "/* $Id: echo.h 4082 2012-04-24 13:09:14Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_ECHO_H__\n#define __PJMEDIA_ECHO_H__\n\n\n/**\n * @file echo.h\n * @brief Echo Cancellation  API.\n */\n#include <pjmedia/types.h>\n\n\n\n/**\n * @defgroup PJMEDIA_Echo_Cancel Accoustic Echo Cancellation API\n * @ingroup PJMEDIA_PORT\n * @brief Echo Cancellation API.\n * @{\n *\n * This section describes API to perform echo cancellation to audio signal.\n * There may be multiple echo canceller implementation in PJMEDIA, ranging\n * from simple echo suppressor to a full Accoustic Echo Canceller/AEC. By \n * using this API, application should be able to use which EC backend to\n * use base on the requirement and capability of the platform.\n */\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * Opaque type for PJMEDIA Echo Canceller state.\n */\ntypedef struct pjmedia_echo_state pjmedia_echo_state;\n\n\n/**\n * Echo cancellation options.\n */\ntypedef enum pjmedia_echo_flag\n{\n    /**\n     * Use any available backend echo canceller algorithm. This is\n     * the default settings. This setting is mutually exclusive with\n     * PJMEDIA_ECHO_SIMPLE and PJMEDIA_ECHO_SPEEX.\n     */\n    PJMEDIA_ECHO_DEFAULT= 0,\n\n    /**\n     * Force to use Speex AEC as the backend echo canceller algorithm.\n     * This setting is mutually exclusive with PJMEDIA_ECHO_SIMPLE.\n     */\n    PJMEDIA_ECHO_SPEEX\t= 1,\n\n    /**\n     * If PJMEDIA_ECHO_SIMPLE flag is specified during echo canceller\n     * creation, then a simple echo suppressor will be used instead of\n     * an accoustic echo cancellation. This setting is mutually exclusive\n     * with PJMEDIA_ECHO_SPEEX.\n     */\n    PJMEDIA_ECHO_SIMPLE\t= 2,\n\n    /**\n     * Force to use WebRTC AEC as the backend echo canceller algorithm.\n     * This setting is mutually exclusive with PJMEDIA_ECHO_SIMPLE & PJMEDIA_ECHO_SPEEX.\n     */\n    PJMEDIA_ECHO_WEBRTC = 3,\n\n    /**\n     * For internal use.\n     */\n    PJMEDIA_ECHO_ALGO_MASK = 15,\n\n    /**\n     * If PJMEDIA_ECHO_NO_LOCK flag is specified, no mutex will be created\n     * for the echo canceller, but application will guarantee that echo\n     * canceller will not be called by different threads at the same time.\n     */\n    PJMEDIA_ECHO_NO_LOCK = 16,\n\n    /**\n     * If PJMEDIA_ECHO_USE_SIMPLE_FIFO flag is specified, the delay buffer\n     * created for the echo canceller will use simple FIFO mechanism, i.e.\n     * without using WSOLA to expand and shrink audio samples.\n     */\n    PJMEDIA_ECHO_USE_SIMPLE_FIFO = 32,\n\n    /**\n     * If PJMEDIA_ECHO_USE_SW_ECHO flag is specified, software echo canceller\n     * will be used instead of device EC.\n     */\n    PJMEDIA_ECHO_USE_SW_ECHO = 64\n\n} pjmedia_echo_flag;\n\n\n\n\n/**\n * Create the echo canceller. \n *\n * @param pool\t\t    Pool to allocate memory.\n * @param clock_rate\t    Media clock rate/sampling rate.\n * @param samples_per_frame Number of samples per frame.\n * @param tail_ms\t    Tail length, miliseconds.\n * @param latency_ms\t    Total lacency introduced by playback and \n *\t\t\t    recording device. Set to zero if the latency\n *\t\t\t    is not known.\n * @param options\t    Options. If PJMEDIA_ECHO_SIMPLE is specified,\n *\t\t\t    then a simple echo suppressor implementation \n *\t\t\t    will be used instead of an accoustic echo \n *\t\t\t    cancellation.\n *\t\t\t    See #pjmedia_echo_flag for other options.\n * @param p_echo\t    Pointer to receive the Echo Canceller state.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate status.\n */\nPJ_DECL(pj_status_t) pjmedia_echo_create(pj_pool_t *pool,\n\t\t\t\t\t unsigned clock_rate,\n\t\t\t\t\t unsigned samples_per_frame,\n\t\t\t\t\t unsigned tail_ms,\n\t\t\t\t\t unsigned latency_ms,\n\t\t\t\t\t unsigned options,\n\t\t\t\t\t pjmedia_echo_state **p_echo );\n\n/**\n * Create multi-channel the echo canceller. \n *\n * @param pool\t\t    Pool to allocate memory.\n * @param clock_rate\t    Media clock rate/sampling rate.\n * @param channel_count\t    Number of channels.\n * @param samples_per_frame Number of samples per frame.\n * @param tail_ms\t    Tail length, miliseconds.\n * @param latency_ms\t    Total lacency introduced by playback and \n *\t\t\t    recording device. Set to zero if the latency\n *\t\t\t    is not known.\n * @param options\t    Options. If PJMEDIA_ECHO_SIMPLE is specified,\n *\t\t\t    then a simple echo suppressor implementation \n *\t\t\t    will be used instead of an accoustic echo \n *\t\t\t    cancellation.\n *\t\t\t    See #pjmedia_echo_flag for other options.\n * @param p_echo\t    Pointer to receive the Echo Canceller state.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate status.\n */\nPJ_DECL(pj_status_t) pjmedia_echo_create2(pj_pool_t *pool,\n\t\t\t\t\t  unsigned clock_rate,\n\t\t\t\t\t  unsigned channel_count,\n\t\t\t\t\t  unsigned samples_per_frame,\n\t\t\t\t\t  unsigned tail_ms,\n\t\t\t\t\t  unsigned latency_ms,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t\t  pjmedia_echo_state **p_echo );\n\n/**\n * Destroy the Echo Canceller. \n *\n * @param echo\t\tThe Echo Canceller.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_echo_destroy(pjmedia_echo_state *echo );\n\n\n/**\n * Reset the echo canceller.\n *\n * @param echo\t\tThe Echo Canceller.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_echo_reset(pjmedia_echo_state *echo );\n\n\n/**\n * Let the Echo Canceller know that a frame has been played to the speaker.\n * The Echo Canceller will keep the frame in its internal buffer, to be used\n * when cancelling the echo with #pjmedia_echo_capture().\n *\n * @param echo\t\tThe Echo Canceller.\n * @param play_frm\tSample buffer containing frame to be played\n *\t\t\t(or has been played) to the playback device.\n *\t\t\tThe frame must contain exactly samples_per_frame \n *\t\t\tnumber of samples.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_echo_playback(pjmedia_echo_state *echo,\n\t\t\t\t\t   pj_int16_t *play_frm );\n\n\n/**\n * Let the Echo Canceller know that a frame has been captured from the \n * microphone. The Echo Canceller will cancel the echo from the captured\n * signal, using the internal buffer (supplied by #pjmedia_echo_playback())\n * as the FES (Far End Speech) reference.\n *\n * @param echo\t\tThe Echo Canceller.\n * @param rec_frm\tOn input, it contains the input signal (captured \n *\t\t\tfrom microphone) which echo is to be removed.\n *\t\t\tUpon returning this function, this buffer contain\n *\t\t\tthe processed signal with the echo removed.\n *\t\t\tThe frame must contain exactly samples_per_frame \n *\t\t\tnumber of samples.\n * @param options\tEcho cancellation options, reserved for future use.\n *\t\t\tPut zero for now.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_echo_capture(pjmedia_echo_state *echo,\n\t\t\t\t\t  pj_int16_t *rec_frm,\n\t\t\t\t\t  unsigned options );\n\n\n/**\n * Perform echo cancellation.\n *\n * @param echo\t\tThe Echo Canceller.\n * @param rec_frm\tOn input, it contains the input signal (captured \n *\t\t\tfrom microphone) which echo is to be removed.\n *\t\t\tUpon returning this function, this buffer contain\n *\t\t\tthe processed signal with the echo removed.\n * @param play_frm\tSample buffer containing frame to be played\n *\t\t\t(or has been played) to the playback device.\n *\t\t\tThe frame must contain exactly samples_per_frame \n *\t\t\tnumber of samples.\n * @param options\tEcho cancellation options, reserved for future use.\n *\t\t\tPut zero for now.\n * @param reserved\tReserved for future use, put NULL for now.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_echo_cancel( pjmedia_echo_state *echo,\n\t\t\t\t\t  pj_int16_t *rec_frm,\n\t\t\t\t\t  const pj_int16_t *play_frm,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t\t  void *reserved );\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_ECHO_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/echo_port.h",
    "content": "/* $Id: echo_port.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_AEC_PORT_H__\n#define __PJMEDIA_AEC_PORT_H__\n\n/**\n * @file echo_port.h\n * @brief AEC (Accoustic Echo Cancellation) media port.\n */\n#include <pjmedia/port.h>\n\n\n\n/**\n * @defgroup PJMEDIA_ECHO_PORT Echo Cancellation Port\n * @ingroup PJMEDIA_PORT\n * @brief Echo Cancellation\n * @{\n *\n * Wrapper to \\ref PJMEDIA_Echo_Cancel into media port interface.\n */\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * Create echo canceller port. \n *\n * @param pool\t\tPool to allocate memory.\n * @param dn_port\tDownstream port.\n * @param tail_ms\tTail length in miliseconds.\n * @param latency_ms\tTotal lacency introduced by playback and \n *\t\t\trecording device. Set to zero if the latency\n *\t\t\tis not known.\n * @param options\tOptions, as in #pjmedia_echo_create().\n * @param p_port\tPointer to receive the port instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_echo_port_create(pj_pool_t *pool,\n\t\t\t\t\t      pjmedia_port *dn_port,\n\t\t\t\t\t      unsigned tail_ms,\n\t\t\t\t\t      unsigned latency_ms,\n\t\t\t\t\t      unsigned options,\n\t\t\t\t\t      pjmedia_port **p_port );\n\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_AEC_PORT_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/endpoint.h",
    "content": "/* $Id: endpoint.h 4474 2013-04-16 09:12:59Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_MEDIAMGR_H__\n#define __PJMEDIA_MEDIAMGR_H__\n\n\n/**\n * @file endpoint.h\n * @brief Media endpoint.\n */\n/**\n * @defgroup PJMED_ENDPT The Endpoint\n * @{\n *\n * The media endpoint acts as placeholder for endpoint capabilities. Each \n * media endpoint will have a codec manager to manage list of codecs installed\n * in the endpoint and a sound device factory.\n *\n * A reference to media endpoint instance is required when application wants\n * to create a media session (#pjmedia_session_create()).\n */\n\n#include <pjmedia/codec.h>\n#include <pjmedia/sdp.h>\n#include <pjmedia/transport.h>\n\n\nPJ_BEGIN_DECL\n\n/**\n * This enumeration describes various flags that can be set or retrieved in\n * the media endpoint, by using pjmedia_endpt_set_flag() and\n * pjmedia_endpt_get_flag() respectively.\n */\ntypedef enum pjmedia_endpt_flag\n{\n    /**\n     * This flag controls whether telephony-event should be offered in SDP.\n     * Value is boolean.\n     */\n    PJMEDIA_ENDPT_HAS_TELEPHONE_EVENT_FLAG\n\n} pjmedia_endpt_flag;\n\n\n/**\n * Type of callback to register to pjmedia_endpt_atexit().\n */\ntypedef void (*pjmedia_endpt_exit_callback)(pjmedia_endpt *endpt);\n\n\n/**\n * Create an instance of media endpoint.\n *\n * @param pf\t\tPool factory, which will be used by the media endpoint\n *\t\t\tthroughout its lifetime.\n * @param ioqueue\tOptional ioqueue instance to be registered to the \n *\t\t\tendpoint. The ioqueue instance is used to poll all RTP\n *\t\t\tand RTCP sockets. If this argument is NULL, the \n *\t\t\tendpoint will create an internal ioqueue instance.\n * @param worker_cnt\tSpecify the number of worker threads to be created\n *\t\t\tto poll the ioqueue.\n * @param p_endpt\tPointer to receive the endpoint instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_endpt_create( pj_pool_factory *pf,\n\t\t\t\t\t   pj_ioqueue_t *ioqueue,\n\t\t\t\t\t   unsigned worker_cnt,\n\t\t\t\t\t   pjmedia_endpt **p_endpt);\n\n/**\n * Destroy media endpoint instance.\n *\n * @param endpt\t\tMedia endpoint instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_endpt_destroy(pjmedia_endpt *endpt);\n\n/**\n * Change the value of a flag.\n *\n * @param endpt\t\tMedia endpoint.\n * @param flag\t\tThe flag.\n * @param value\t\tPointer to the value to be set.\n *\n * @reurn\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_endpt_set_flag(pjmedia_endpt *endpt,\n\t\t\t\t\t    pjmedia_endpt_flag flag,\n\t\t\t\t\t    const void *value);\n\n/**\n *  Retrieve the value of a flag.\n *\n *  @param endpt\tMedia endpoint.\n *  @param flag\t\tThe flag.\n *  @param value\tPointer to store the result.\n *\n *  @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_endpt_get_flag(pjmedia_endpt *endpt,\n\t\t\t\t\t    pjmedia_endpt_flag flag,\n\t\t\t\t\t    void *value);\n\n/**\n * Get the ioqueue instance of the media endpoint.\n *\n * @param endpt\t\tThe media endpoint instance.\n *\n * @return\t\tThe ioqueue instance of the media endpoint.\n */\nPJ_DECL(pj_ioqueue_t*) pjmedia_endpt_get_ioqueue(pjmedia_endpt *endpt);\n\n\n/**\n * Get the number of worker threads on the media endpoint\n *\n * @param endpt\t\tThe media endpoint instance.\n * @return\t\tThe number of worker threads on the media endpoint\n */\nPJ_DECL(unsigned) pjmedia_endpt_get_thread_count(pjmedia_endpt *endpt);\n\n/**\n * Get a reference to one of the worker threads of the media endpoint \n *\n * @param endpt\t\tThe media endpoint instance.\n * @param index\t\tThe index of the thread: 0<= index < thread_cnt\n *\n * @return\t\tpj_thread_t or NULL\n */\nPJ_DECL(pj_thread_t*) pjmedia_endpt_get_thread(pjmedia_endpt *endpt, \n\t\t\t\t\t       unsigned index);\n\n/**\n * Stop and destroy the worker threads of the media endpoint\n *\n * @param endpt\t\tThe media endpoint instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_endpt_stop_threads(pjmedia_endpt *endpt);\n\n\n/**\n * Request the media endpoint to create pool.\n *\n * @param endpt\t\tThe media endpoint instance.\n * @param name\t\tName to be assigned to the pool.\n * @param initial\tInitial pool size, in bytes.\n * @param increment\tIncrement size, in bytes.\n *\n * @return\t\tMemory pool.\n */\nPJ_DECL(pj_pool_t*) pjmedia_endpt_create_pool( pjmedia_endpt *endpt,\n\t\t\t\t\t       const char *name,\n\t\t\t\t\t       pj_size_t initial,\n\t\t\t\t\t       pj_size_t increment);\n\n/**\n * Get the codec manager instance of the media endpoint.\n *\n * @param endpt\t\tThe media endpoint instance.\n *\n * @return\t\tThe instance of codec manager belonging to\n *\t\t\tthis media endpoint.\n */\nPJ_DECL(pjmedia_codec_mgr*) pjmedia_endpt_get_codec_mgr(pjmedia_endpt *endpt);\n\n\n/**\n * Create a SDP session description that describes the endpoint\n * capability.\n *\n * @param endpt\t\tThe media endpoint.\n * @param pool\t\tPool to use to create the SDP descriptor.\n * @param stream_cnt\tNumber of elements in the sock_info array. This\n *\t\t\talso denotes the maximum number of streams (i.e.\n *\t\t\tthe \"m=\" lines) that will be created in the SDP.\n *\t\t\tBy convention, if this value is greater than one,\n *\t\t\tthe first media will be audio and the remaining\n *\t\t\tmedia is video.\n * @param sock_info\tArray of socket transport information. One \n *\t\t\ttransport is needed for each media stream, and\n *\t\t\teach transport consists of an RTP and RTCP socket\n *\t\t\tpair.\n * @param p_sdp\t\tPointer to receive SDP session descriptor.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,\n\t\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t\t       unsigned stream_cnt,\n\t\t\t\t\t       const pjmedia_sock_info sock_info[],\n\t\t\t\t\t       pjmedia_sdp_session **p_sdp );\n\n/**\n * Create a \"blank\" SDP session description. The SDP will contain basic SDP\n * fields such as origin, time, and name, but without any media lines.\n *\n * @param endpt\t\tThe media endpoint.\n * @param pool\t\tPool to allocate memory from.\n * @param sess_name\tOptional SDP session name, or NULL to use default\n * \t\t\tvalue.\n * @param origin\tAddress to put in the origin field.\n * @param p_sdp\t\tPointer to receive the created SDP session.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_endpt_create_base_sdp(pjmedia_endpt *endpt,\n\t\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t\t   const pj_str_t *sess_name,\n\t\t\t\t\t\t   const pj_sockaddr *origin,\n\t\t\t\t\t\t   pjmedia_sdp_session **p_sdp);\n\n/**\n * Create SDP media line for audio media.\n *\n * @param endpt\t\tThe media endpoint.\n * @param pool\t\tPool to allocate memory from.\n * @param si\t\tSocket information.\n * @param options\tOption flags, must be zero for now.\n * @param p_m\t\tPointer to receive the created SDP media.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_endpt_create_audio_sdp(pjmedia_endpt *endpt,\n                                                    pj_pool_t *pool,\n                                                    const pjmedia_sock_info*si,\n                                                    unsigned options,\n                                                    pjmedia_sdp_media **p_m);\n\n/**\n * Create SDP media line for video media.\n *\n * @param endpt\t\tThe media endpoint.\n * @param pool\t\tPool to allocate memory from.\n * @param si\t\tSocket information.\n * @param options\tOption flags, must be zero for now.\n * @param p_m\t\tPointer to receive the created SDP media.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_endpt_create_video_sdp(pjmedia_endpt *endpt,\n                                                    pj_pool_t *pool,\n                                                    const pjmedia_sock_info*si,\n                                                    unsigned options,\n                                                    pjmedia_sdp_media **p_m);\n\n/**\n * Dump media endpoint capabilities.\n *\n * @param endpt\t\tThe media endpoint.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_endpt_dump(pjmedia_endpt *endpt);\n\n\n/**\n * Register cleanup function to be called by media endpoint when \n * #pjmedia_endpt_destroy() is called. Note that application should not\n * use or access any endpoint resource (such as pool, ioqueue) from within\n * the callback as such resource may have been released when the callback\n * function is invoked.\n *\n * @param endpt\t\tThe media endpoint.\n * @param func\t\tThe function to be registered.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_endpt_atexit(pjmedia_endpt *endpt,\n\t\t\t\t\t  pjmedia_endpt_exit_callback func);\n\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n\n\n#endif\t/* __PJMEDIA_MEDIAMGR_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/errno.h",
    "content": "/* $Id: errno.h 3945 2012-01-27 09:12:59Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_ERRNO_H__\n#define __PJMEDIA_ERRNO_H__\n\n/**\n * @file errno.h Error Codes\n * @brief PJMEDIA specific error codes.\n */\n\n#include <pjmedia/types.h>\n#include <pj/errno.h>\n\n/**\n * @defgroup PJMEDIA_ERRNO Error Codes\n * @ingroup PJMEDIA_BASE\n * @brief PJMEDIA specific error codes.\n * @{\n */\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * Start of error code relative to PJ_ERRNO_START_USER.\n */\n#define PJMEDIA_ERRNO_START       (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE)\n#define PJMEDIA_ERRNO_END         (PJMEDIA_ERRNO_START + PJ_ERRNO_SPACE_SIZE - 1)\n\n\n#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)\n\n /**\n * Mapping from LibSRTP error codes to pjmedia error space.\n */\n#define PJMEDIA_LIBSRTP_ERRNO_START (PJMEDIA_ERRNO_END-10200)\n#define PJMEDIA_LIBSRTP_ERRNO_END   (PJMEDIA_LIBSRTP_ERRNO_START + 200 - 1)\n/**\n * Convert LibSRTP error code to PJMEDIA error code.\n * LibSRTP error code range: 0 <= err < 200\n */\n#define PJMEDIA_ERRNO_FROM_LIBSRTP(err)   (PJMEDIA_LIBSRTP_ERRNO_START+err)\n\n#endif\n\n/************************************************************\n * GENERIC/GENERAL PJMEDIA ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * General/unknown PJMEDIA error.\n */\n#define PJMEDIA_ERROR\t\t    (PJMEDIA_ERRNO_START+1)\t/* 220001 */\n\n\n/************************************************************\n * SDP ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * Generic invalid SDP descriptor.\n */\n#define PJMEDIA_SDP_EINSDP\t    (PJMEDIA_ERRNO_START+20)    /* 220020 */\n/**\n * @hideinitializer\n * Invalid SDP version.\n */\n#define PJMEDIA_SDP_EINVER\t    (PJMEDIA_ERRNO_START+21)    /* 220021 */\n/**\n * @hideinitializer\n * Invalid SDP origin (o=) line.\n */\n#define PJMEDIA_SDP_EINORIGIN\t    (PJMEDIA_ERRNO_START+22)    /* 220022 */\n/**\n * @hideinitializer\n * Invalid SDP time (t=) line.\n */\n#define PJMEDIA_SDP_EINTIME\t    (PJMEDIA_ERRNO_START+23)    /* 220023 */\n/**\n * @hideinitializer\n * Empty SDP subject/name (s=) line.\n */\n#define PJMEDIA_SDP_EINNAME\t    (PJMEDIA_ERRNO_START+24)    /* 220024 */\n/**\n * @hideinitializer\n * Invalid SDP connection info (c=) line.\n */\n#define PJMEDIA_SDP_EINCONN\t    (PJMEDIA_ERRNO_START+25)    /* 220025 */\n/**\n * @hideinitializer\n * Missing SDP connection info line.\n */\n#define PJMEDIA_SDP_EMISSINGCONN    (PJMEDIA_ERRNO_START+26)    /* 220026 */\n/**\n * @hideinitializer\n * Invalid attribute (a=) line.\n */\n#define PJMEDIA_SDP_EINATTR\t    (PJMEDIA_ERRNO_START+27)    /* 220027 */\n/**\n * @hideinitializer\n * Invalid rtpmap attribute.\n */\n#define PJMEDIA_SDP_EINRTPMAP\t    (PJMEDIA_ERRNO_START+28)    /* 220028 */\n/**\n * @hideinitializer\n * rtpmap attribute is too long.\n */\n#define PJMEDIA_SDP_ERTPMAPTOOLONG  (PJMEDIA_ERRNO_START+29)    /* 220029 */\n/**\n * @hideinitializer\n * rtpmap is missing for dynamic payload type.\n */\n#define PJMEDIA_SDP_EMISSINGRTPMAP  (PJMEDIA_ERRNO_START+30)    /* 220030 */\n/**\n * @hideinitializer\n * Invalid SDP media (m=) line.\n */\n#define PJMEDIA_SDP_EINMEDIA\t    (PJMEDIA_ERRNO_START+31)    /* 220031 */\n/**\n * @hideinitializer\n * No payload format in the media stream.\n */\n#define PJMEDIA_SDP_ENOFMT\t    (PJMEDIA_ERRNO_START+32)    /* 220032 */\n/**\n * @hideinitializer\n * Invalid payload type in media.\n */\n#define PJMEDIA_SDP_EINPT\t    (PJMEDIA_ERRNO_START+33)    /* 220033 */\n/**\n * @hideinitializer\n * Invalid SDP \"fmtp\" attribute.\n */\n#define PJMEDIA_SDP_EINFMTP\t    (PJMEDIA_ERRNO_START+34)    /* 220034 */\n/**\n * @hideinitializer\n * Invalid SDP \"rtcp\" attribute.\n */\n#define PJMEDIA_SDP_EINRTCP\t    (PJMEDIA_ERRNO_START+35)    /* 220035 */\n/**\n * @hideinitializer\n * Invalid SDP media transport protocol.\n */\n#define PJMEDIA_SDP_EINPROTO\t    (PJMEDIA_ERRNO_START+36)    /* 220036 */\n/**\n * @hideinitializer\n * Invalid SDP bandwidth info (b=) line.\n */\n#define PJMEDIA_SDP_EINBANDW\t    (PJMEDIA_ERRNO_START+37)    /* 220037 */\n\n\n/************************************************************\n * SDP NEGOTIATOR ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * Invalid state to perform the specified operation.\n */\n#define PJMEDIA_SDPNEG_EINSTATE\t    (PJMEDIA_ERRNO_START+40)    /* 220040 */\n/**\n * @hideinitializer\n * No initial local SDP.\n */\n#define PJMEDIA_SDPNEG_ENOINITIAL   (PJMEDIA_ERRNO_START+41)    /* 220041 */\n/**\n * @hideinitializer\n * No currently active SDP.\n */\n#define PJMEDIA_SDPNEG_ENOACTIVE    (PJMEDIA_ERRNO_START+42)    /* 220042 */\n/**\n * @hideinitializer\n * No current offer or answer.\n */\n#define PJMEDIA_SDPNEG_ENONEG\t    (PJMEDIA_ERRNO_START+43)    /* 220043 */\n/**\n * @hideinitializer\n * Media count mismatch in offer and answer.\n */\n#define PJMEDIA_SDPNEG_EMISMEDIA    (PJMEDIA_ERRNO_START+44)    /* 220044 */\n/**\n * @hideinitializer\n * Media type is different in the remote answer.\n */\n#define PJMEDIA_SDPNEG_EINVANSMEDIA (PJMEDIA_ERRNO_START+45)    /* 220045 */\n/**\n * @hideinitializer\n * Transport type is different in the remote answer.\n */\n#define PJMEDIA_SDPNEG_EINVANSTP    (PJMEDIA_ERRNO_START+46)    /* 220046 */\n/**\n * @hideinitializer\n * No common media payload is provided in the answer.\n */\n#define PJMEDIA_SDPNEG_EANSNOMEDIA  (PJMEDIA_ERRNO_START+47)    /* 220047 */\n/**\n * @hideinitializer\n * No media is active after negotiation.\n */\n#define PJMEDIA_SDPNEG_ENOMEDIA\t    (PJMEDIA_ERRNO_START+48)    /* 220048 */\n/**\n * @hideinitializer\n * No suitable codec for remote offer.\n */\n#define PJMEDIA_SDPNEG_NOANSCODEC   (PJMEDIA_ERRNO_START+49)    /* 220049 */\n/**\n * @hideinitializer\n * No suitable telephone-event for remote offer.\n */\n#define PJMEDIA_SDPNEG_NOANSTELEVENT (PJMEDIA_ERRNO_START+50)   /* 220050 */\n/**\n * @hideinitializer\n * No suitable answer for unknown remote offer.\n */\n#define PJMEDIA_SDPNEG_NOANSUNKNOWN (PJMEDIA_ERRNO_START+51)    /* 220051 */\n\n\n/************************************************************\n * SDP COMPARISON STATUS\n ***********************************************************/\n/**\n * @hideinitializer\n * SDP media stream not equal.\n */\n#define PJMEDIA_SDP_EMEDIANOTEQUAL  (PJMEDIA_ERRNO_START+60)    /* 220060 */\n/**\n * @hideinitializer\n * Port number in SDP media descriptor not equal.\n */\n#define PJMEDIA_SDP_EPORTNOTEQUAL   (PJMEDIA_ERRNO_START+61)    /* 220061 */\n/**\n * @hideinitializer\n * Transport in SDP media descriptor not equal.\n */\n#define PJMEDIA_SDP_ETPORTNOTEQUAL  (PJMEDIA_ERRNO_START+62)    /* 220062 */\n/**\n * @hideinitializer\n * Media format in SDP media descriptor not equal.\n */\n#define PJMEDIA_SDP_EFORMATNOTEQUAL (PJMEDIA_ERRNO_START+63)    /* 220063 */\n/**\n * @hideinitializer\n * SDP connection description not equal.\n */\n#define PJMEDIA_SDP_ECONNNOTEQUAL   (PJMEDIA_ERRNO_START+64)    /* 220064 */\n/**\n * @hideinitializer\n * SDP attributes not equal.\n */\n#define PJMEDIA_SDP_EATTRNOTEQUAL   (PJMEDIA_ERRNO_START+65)    /* 220065 */\n/**\n * @hideinitializer\n * SDP media direction not equal.\n */\n#define PJMEDIA_SDP_EDIRNOTEQUAL    (PJMEDIA_ERRNO_START+66)    /* 220066 */\n/**\n * @hideinitializer\n * SDP fmtp attribute not equal.\n */\n#define PJMEDIA_SDP_EFMTPNOTEQUAL   (PJMEDIA_ERRNO_START+67)    /* 220067 */\n/**\n * @hideinitializer\n * SDP ftpmap attribute not equal.\n */\n#define PJMEDIA_SDP_ERTPMAPNOTEQUAL (PJMEDIA_ERRNO_START+68)    /* 220068 */\n/**\n * @hideinitializer\n * SDP session descriptor not equal.\n */\n#define PJMEDIA_SDP_ESESSNOTEQUAL   (PJMEDIA_ERRNO_START+69)    /* 220069 */\n/**\n * @hideinitializer\n * SDP origin not equal.\n */\n#define PJMEDIA_SDP_EORIGINNOTEQUAL (PJMEDIA_ERRNO_START+70)    /* 220070 */\n/**\n * @hideinitializer\n * SDP name/subject not equal.\n */\n#define PJMEDIA_SDP_ENAMENOTEQUAL   (PJMEDIA_ERRNO_START+71)    /* 220071 */\n/**\n * @hideinitializer\n * SDP time not equal.\n */\n#define PJMEDIA_SDP_ETIMENOTEQUAL   (PJMEDIA_ERRNO_START+72)    /* 220072 */\n\n\n/************************************************************\n * CODEC\n ***********************************************************/\n/**\n * @hideinitializer\n * Unsupported codec.\n */\n#define PJMEDIA_CODEC_EUNSUP\t    (PJMEDIA_ERRNO_START+80)    /* 220080 */\n/**\n * @hideinitializer\n * Codec internal creation error.\n */\n#define PJMEDIA_CODEC_EFAILED\t    (PJMEDIA_ERRNO_START+81)    /* 220081 */\n/**\n * @hideinitializer\n * Codec frame is too short.\n */\n#define PJMEDIA_CODEC_EFRMTOOSHORT  (PJMEDIA_ERRNO_START+82)    /* 220082 */\n/**\n * @hideinitializer\n * PCM buffer is too short.\n */\n#define PJMEDIA_CODEC_EPCMTOOSHORT  (PJMEDIA_ERRNO_START+83)    /* 220083 */\n/**\n * @hideinitializer\n * Invalid codec frame length.\n */\n#define PJMEDIA_CODEC_EFRMINLEN\t    (PJMEDIA_ERRNO_START+84)    /* 220084 */\n/**\n * @hideinitializer\n * Invalid PCM frame length.\n */\n#define PJMEDIA_CODEC_EPCMFRMINLEN  (PJMEDIA_ERRNO_START+85)    /* 220085 */\n/**\n * @hideinitializer\n * Invalid mode.\n */\n#define PJMEDIA_CODEC_EINMODE\t    (PJMEDIA_ERRNO_START+86)    /* 220086 */\n/**\n * @hideinitializer\n * Bad or corrupted bitstream.\n */\n#define PJMEDIA_CODEC_EBADBITSTREAM (PJMEDIA_ERRNO_START+87)    /* 220087 */\n\n\n/************************************************************\n * MEDIA\n ***********************************************************/\n/**\n * @hideinitializer\n * Invalid remote IP address (in SDP).\n */\n#define PJMEDIA_EINVALIDIP\t    (PJMEDIA_ERRNO_START+100)    /* 220100 */\n/**\n * @hideinitializer\n * Asymetric codec is not supported.\n */\n#define PJMEDIA_EASYMCODEC\t    (PJMEDIA_ERRNO_START+101)    /* 220101 */\n/**\n * @hideinitializer\n * Invalid payload type.\n */\n#define PJMEDIA_EINVALIDPT\t    (PJMEDIA_ERRNO_START+102)    /* 220102 */\n/**\n * @hideinitializer\n * Missing rtpmap.\n */\n#define PJMEDIA_EMISSINGRTPMAP\t    (PJMEDIA_ERRNO_START+103)    /* 220103 */\n/**\n * @hideinitializer\n * Invalid media type.\n */\n#define PJMEDIA_EINVALIMEDIATYPE    (PJMEDIA_ERRNO_START+104)    /* 220104 */\n/**\n * @hideinitializer\n * Remote does not support DTMF.\n */\n#define PJMEDIA_EREMOTENODTMF\t    (PJMEDIA_ERRNO_START+105)    /* 220105 */\n/**\n * @hideinitializer\n * Invalid DTMF digit.\n */\n#define PJMEDIA_RTP_EINDTMF\t    (PJMEDIA_ERRNO_START+106)    /* 220106 */\n/**\n * @hideinitializer\n * Remote does not support RFC 2833\n */\n#define PJMEDIA_RTP_EREMNORFC2833   (PJMEDIA_ERRNO_START+107)    /* 220107 */\n/**\n * @hideinitializer\n * Invalid or bad format\n */\n#define PJMEDIA_EBADFMT             (PJMEDIA_ERRNO_START+108)    /* 220108 */\n\n\n/************************************************************\n * RTP SESSION ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * General invalid RTP packet error.\n */\n#define PJMEDIA_RTP_EINPKT\t    (PJMEDIA_ERRNO_START+120)    /* 220120 */\n/**\n * @hideinitializer\n * Invalid RTP packet packing.\n */\n#define PJMEDIA_RTP_EINPACK\t    (PJMEDIA_ERRNO_START+121)    /* 220121 */\n/**\n * @hideinitializer\n * Invalid RTP packet version.\n */\n#define PJMEDIA_RTP_EINVER\t    (PJMEDIA_ERRNO_START+122)    /* 220122 */\n/**\n * @hideinitializer\n * RTP SSRC id mismatch.\n */\n#define PJMEDIA_RTP_EINSSRC\t    (PJMEDIA_ERRNO_START+123)    /* 220123 */\n/**\n * @hideinitializer\n * RTP payload type mismatch.\n */\n#define PJMEDIA_RTP_EINPT\t    (PJMEDIA_ERRNO_START+124)    /* 220124 */\n/**\n * @hideinitializer\n * Invalid RTP packet length.\n */\n#define PJMEDIA_RTP_EINLEN\t    (PJMEDIA_ERRNO_START+125)    /* 220125 */\n/**\n * @hideinitializer\n * RTP session restarted.\n */\n#define PJMEDIA_RTP_ESESSRESTART    (PJMEDIA_ERRNO_START+130)    /* 220130 */\n/**\n * @hideinitializer\n * RTP session in probation\n */\n#define PJMEDIA_RTP_ESESSPROBATION  (PJMEDIA_ERRNO_START+131)    /* 220131 */\n/**\n * @hideinitializer\n * Bad RTP sequence number\n */\n#define PJMEDIA_RTP_EBADSEQ\t    (PJMEDIA_ERRNO_START+132)    /* 220132 */\n/**\n * @hideinitializer\n * RTP media port destination is not configured\n */\n#define PJMEDIA_RTP_EBADDEST\t    (PJMEDIA_ERRNO_START+133)    /* 220133 */\n/**\n * @hideinitializer\n * RTP is not configured.\n */\n#define PJMEDIA_RTP_ENOCONFIG\t    (PJMEDIA_ERRNO_START+134)    /* 220134 */\n\n\n/************************************************************\n * PORT ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * Generic incompatible port error.\n */\n#define PJMEDIA_ENOTCOMPATIBLE\t    (PJMEDIA_ERRNO_START+160)    /* 220160 */\n/**\n * @hideinitializer\n * Incompatible clock rate\n */\n#define PJMEDIA_ENCCLOCKRATE\t    (PJMEDIA_ERRNO_START+161)    /* 220161 */\n/**\n * @hideinitializer\n * Incompatible samples per frame\n */\n#define PJMEDIA_ENCSAMPLESPFRAME    (PJMEDIA_ERRNO_START+162)    /* 220162 */\n/**\n * @hideinitializer\n * Incompatible media type\n */\n#define PJMEDIA_ENCTYPE\t\t    (PJMEDIA_ERRNO_START+163)    /* 220163 */\n/**\n * @hideinitializer\n * Incompatible bits per sample\n */\n#define PJMEDIA_ENCBITS\t\t    (PJMEDIA_ERRNO_START+164)    /* 220164 */\n/**\n * @hideinitializer\n * Incompatible bytes per frame\n */\n#define PJMEDIA_ENCBYTES\t    (PJMEDIA_ERRNO_START+165)    /* 220165 */\n/**\n * @hideinitializer\n * Incompatible number of channels\n */\n#define PJMEDIA_ENCCHANNEL\t    (PJMEDIA_ERRNO_START+166)    /* 220166 */\n\n\n/************************************************************\n * FILE ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * Not a valid WAVE file.\n */\n#define PJMEDIA_ENOTVALIDWAVE\t    (PJMEDIA_ERRNO_START+180)    /* 220180 */\n/**\n * @hideinitializer\n * Unsupported WAVE file.\n */\n#define PJMEDIA_EWAVEUNSUPP\t    (PJMEDIA_ERRNO_START+181)    /* 220181 */\n/**\n * @hideinitializer\n * Wave file too short.\n */\n#define PJMEDIA_EWAVETOOSHORT\t    (PJMEDIA_ERRNO_START+182)    /* 220182 */\n/**\n * @hideinitializer\n * Sound frame is too large for file buffer.\n */\n#define PJMEDIA_EFRMFILETOOBIG\t    (PJMEDIA_ERRNO_START+183)    /* 220183 */\n/**\n * @hideinitializer\n * Unsupported AVI file.\n */\n#define PJMEDIA_EAVIUNSUPP\t    (PJMEDIA_ERRNO_START+191)    /* 220191 */\n\n\n/************************************************************\n * SOUND DEVICE ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * No suitable audio capture device.\n */\n#define PJMEDIA_ENOSNDREC\t    (PJMEDIA_ERRNO_START+200)    /* 220200 */\n/**\n * @hideinitializer\n * No suitable audio playback device.\n */\n#define PJMEDIA_ENOSNDPLAY\t    (PJMEDIA_ERRNO_START+201)    /* 220201 */\n/**\n * @hideinitializer\n * Invalid sound device ID.\n */\n#define PJMEDIA_ESNDINDEVID\t    (PJMEDIA_ERRNO_START+202)    /* 220202 */\n/**\n * @hideinitializer\n * Invalid sample format for sound device.\n */\n#define PJMEDIA_ESNDINSAMPLEFMT\t    (PJMEDIA_ERRNO_START+203)    /* 220203 */\n\n\n#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)\n/************************************************************\n * SRTP TRANSPORT ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * SRTP crypto-suite name not match the offerer tag.\n */\n#define PJMEDIA_SRTP_ECRYPTONOTMATCH (PJMEDIA_ERRNO_START+220)   /* 220220 */\n/**\n * @hideinitializer\n * Invalid SRTP key length for specific crypto.\n */\n#define PJMEDIA_SRTP_EINKEYLEN\t    (PJMEDIA_ERRNO_START+221)    /* 220221 */\n/**\n * @hideinitializer\n * Unsupported SRTP crypto-suite.\n */\n#define PJMEDIA_SRTP_ENOTSUPCRYPTO  (PJMEDIA_ERRNO_START+222)    /* 220222 */\n/**\n * @hideinitializer\n * SRTP SDP contains ambigue answer.\n */\n#define PJMEDIA_SRTP_ESDPAMBIGUEANS (PJMEDIA_ERRNO_START+223)    /* 220223 */\n/**\n * @hideinitializer\n * Duplicated crypto tag.\n */\n#define PJMEDIA_SRTP_ESDPDUPCRYPTOTAG (PJMEDIA_ERRNO_START+224)  /* 220224 */\n/**\n * @hideinitializer\n * Invalid crypto attribute.\n */\n#define PJMEDIA_SRTP_ESDPINCRYPTO   (PJMEDIA_ERRNO_START+225)    /* 220225 */\n/**\n * @hideinitializer\n * Invalid crypto tag.\n */\n#define PJMEDIA_SRTP_ESDPINCRYPTOTAG (PJMEDIA_ERRNO_START+226)   /* 220226 */\n/**\n * @hideinitializer\n * Invalid SDP media transport for SRTP.\n */\n#define PJMEDIA_SRTP_ESDPINTRANSPORT (PJMEDIA_ERRNO_START+227)   /* 220227 */\n/**\n * @hideinitializer\n * SRTP crypto attribute required in SDP.\n */\n#define PJMEDIA_SRTP_ESDPREQCRYPTO  (PJMEDIA_ERRNO_START+228)    /* 220228 */\n/**\n * @hideinitializer\n * Secure transport required in SDP media descriptor.\n */\n#define PJMEDIA_SRTP_ESDPREQSECTP   (PJMEDIA_ERRNO_START+229)    /* 220229 */\n\n#endif /* PJMEDIA_HAS_SRTP */\n\n\n/**\n * Get error message for the specified error code. Note that this\n * function is only able to decode PJMEDIA specific error code.\n * Application should use pj_strerror(), which should be able to\n * decode all error codes belonging to all subsystems (e.g. pjlib,\n * pjmedia, pjsip, etc).\n *\n * @param status    The error code.\n * @param buffer    The buffer where to put the error message.\n * @param bufsize   Size of the buffer.\n *\n * @return\t    The error message as NULL terminated string,\n *                  wrapped with pj_str_t.\n */\nPJ_DECL(pj_str_t) pjmedia_strerror( pj_status_t status, char *buffer,\n\t\t\t\t    pj_size_t bufsize);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_ERRNO_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/event.h",
    "content": "/* $Id: event.h 3905 2011-12-09 05:15:39Z ming $ */\n/* \n * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_EVENT_H__\n#define __PJMEDIA_EVENT_H__\n\n/**\n * @file pjmedia/event.h\n * @brief Event framework\n */\n#include <pjmedia/format.h>\n#include <pjmedia/signatures.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJMEDIA_EVENT Event Framework\n * @brief PJMEDIA event framework\n * @{\n */\n\n/**\n * This enumeration describes list of media events.\n */\ntypedef enum pjmedia_event_type\n{\n    /**\n     * No event.\n     */\n    PJMEDIA_EVENT_NONE,\n\n    /**\n     * Media format has changed event.\n     */\n    PJMEDIA_EVENT_FMT_CHANGED\t= PJMEDIA_FOURCC('F', 'M', 'C', 'H'),\n\n    /**\n     * Video window is being closed.\n     */\n    PJMEDIA_EVENT_WND_CLOSING\t= PJMEDIA_FOURCC('W', 'N', 'C', 'L'),\n\n    /**\n     * Video window has been closed event.\n     */\n    PJMEDIA_EVENT_WND_CLOSED\t= PJMEDIA_FOURCC('W', 'N', 'C', 'O'),\n\n    /**\n     * Video window has been resized event.\n     */\n    PJMEDIA_EVENT_WND_RESIZED\t= PJMEDIA_FOURCC('W', 'N', 'R', 'Z'),\n\n    /**\n     * Mouse button has been pressed event.\n     */\n    PJMEDIA_EVENT_MOUSE_BTN_DOWN = PJMEDIA_FOURCC('M', 'S', 'D', 'N'),\n\n    /**\n     * Video keyframe has just been decoded event.\n     */\n    PJMEDIA_EVENT_KEYFRAME_FOUND = PJMEDIA_FOURCC('I', 'F', 'R', 'F'),\n\n    /**\n     * Video decoding error due to missing keyframe event.\n     */\n    PJMEDIA_EVENT_KEYFRAME_MISSING = PJMEDIA_FOURCC('I', 'F', 'R', 'M'),\n\n    /**\n     * Remote video decoder asked for a keyframe.\n     */\n    PJMEDIA_EVENT_KEYFRAME_REQUESTED = PJMEDIA_FOURCC('I', 'F', 'R', 'R'),\n\n    /**\n     * Video orientation has been changed event.\n     */\n    PJMEDIA_EVENT_ORIENT_CHANGED = PJMEDIA_FOURCC('O', 'R', 'N', 'T')\n\n} pjmedia_event_type;\n\n/**\n * Additional data/parameters for media format changed event\n * (PJMEDIA_EVENT_FMT_CHANGED).\n */\ntypedef struct pjmedia_event_fmt_changed_data\n{\n    /** The media flow direction */\n    pjmedia_dir\t\tdir;\n\n    /** The new media format. */\n    pjmedia_format\tnew_fmt;\n} pjmedia_event_fmt_changed_data;\n\n/**\n * Additional data/parameters are not needed.\n */\ntypedef struct pjmedia_event_dummy_data\n{\n    /** Dummy data */\n    int\t\t\tdummy;\n} pjmedia_event_dummy_data;\n\n/**\n * Additional data/parameters for window resized event\n * (PJMEDIA_EVENT_WND_RESIZED).\n */\ntypedef struct pjmedia_event_wnd_resized_data\n{\n    /**\n     * The new window size.\n     */\n    pjmedia_rect_size\tnew_size;\n} pjmedia_event_wnd_resized_data;\n\n/**\n * Additional data/parameters for window closing event.\n */\ntypedef struct pjmedia_event_wnd_closing_data\n{\n    /** Consumer may set this field to PJ_TRUE to cancel the closing */\n    pj_bool_t\t\tcancel;\n} pjmedia_event_wnd_closing_data;\n\n/** Additional parameters for window changed event. */\ntypedef pjmedia_event_dummy_data pjmedia_event_wnd_closed_data;\n\n/** Additional parameters for mouse button down event */\ntypedef pjmedia_event_dummy_data pjmedia_event_mouse_btn_down_data;\n\n/** Additional parameters for keyframe found event */\ntypedef pjmedia_event_dummy_data pjmedia_event_keyframe_found_data;\n\n/** Additional parameters for keyframe missing event */\ntypedef pjmedia_event_dummy_data pjmedia_event_keyframe_missing_data;\n\n/**\n * Maximum size of additional parameters section in pjmedia_event structure\n */\n#define PJMEDIA_EVENT_DATA_MAX_SIZE\tsizeof(pjmedia_event_fmt_changed_data)\n\n/** Type of storage to hold user data in pjmedia_event structure */\ntypedef char pjmedia_event_user_data[PJMEDIA_EVENT_DATA_MAX_SIZE];\n\n/**\n * This structure describes a media event. It consists mainly of the event\n * type and additional data/parameters for the event. Applications can\n * use #pjmedia_event_init() to initialize this event structure with\n * basic information about the event.\n */\ntypedef struct pjmedia_event\n{\n    /**\n     * The event type.\n     */\n    pjmedia_event_type\t\t\t type;\n\n    /**\n     * The media timestamp when the event occurs.\n     */\n    pj_timestamp\t\t \t timestamp;\n\n    /**\n     * Pointer information about the source of this event. This field\n     * is provided mainly for comparison purpose so that event subscribers\n     * can check which source the event originated from. Usage of this\n     * pointer for other purpose may require special care such as mutex\n     * locking or checking whether the object is already destroyed.\n     */\n    const void\t                        *src;\n\n    /**\n     * Pointer information about the publisher of this event. This field\n     * is provided mainly for comparison purpose so that event subscribers\n     * can check which object published the event. Usage of this\n     * pointer for other purpose may require special care such as mutex\n     * locking or checking whether the object is already destroyed.\n     */\n    const void\t                        *epub;\n\n    /**\n     * Additional data/parameters about the event. The type of data\n     * will be specific to the event type being reported.\n     */\n    union {\n\t/** Media format changed event data. */\n\tpjmedia_event_fmt_changed_data\t\tfmt_changed;\n\n\t/** Window resized event data */\n\tpjmedia_event_wnd_resized_data\t\twnd_resized;\n\n\t/** Window closing event data. */\n\tpjmedia_event_wnd_closing_data\t\twnd_closing;\n\n\t/** Window closed event data */\n\tpjmedia_event_wnd_closed_data\t\twnd_closed;\n\n\t/** Mouse button down event data */\n\tpjmedia_event_mouse_btn_down_data\tmouse_btn_down;\n\n\t/** Keyframe found event data */\n\tpjmedia_event_keyframe_found_data\tkeyframe_found;\n\n\t/** Keyframe missing event data */\n\tpjmedia_event_keyframe_missing_data\tkeyframe_missing;\n\n\t/** Storage for user event data */\n\tpjmedia_event_user_data\t\t\tuser;\n\n\t/** Pointer to storage to user event data, if it's outside\n\t * this struct\n\t */\n\tvoid\t\t\t\t\t*ptr;\n    } data;\n} pjmedia_event;\n\n/**\n * The callback to receive media events.\n *\n * @param event\t\tThe media event.\n * @param user_data\tThe user data associated with the callback.\n *\n * @return\t\tIf the callback returns non-PJ_SUCCESS, this return\n * \t\t\tcode may be propagated back to the caller.\n */\ntypedef pj_status_t pjmedia_event_cb(pjmedia_event *event,\n                                     void *user_data);\n\n/**\n * This enumeration describes flags for event publication via\n * #pjmedia_event_publish().\n */\ntypedef enum pjmedia_event_publish_flag\n{\n    /**\n     * Default flag.\n     */\n    PJMEDIA_EVENT_PUBLISH_DEFAULT,\n\n    /**\n     * Publisher will only post the event to the event manager. It is the\n     * event manager that will later notify all the publisher's subscribers.\n     */\n    PJMEDIA_EVENT_PUBLISH_POST_EVENT = 1\n\n} pjmedia_event_publish_flag;\n\n/**\n * Event manager flag.\n */\ntypedef enum pjmedia_event_mgr_flag\n{\n    /**\n     * Tell the event manager not to create any event worker thread.\n     */\n    PJMEDIA_EVENT_MGR_NO_THREAD = 1\n\n} pjmedia_event_mgr_flag;\n\n/**\n * Opaque data type for event manager. Typically, the event manager\n * is a singleton instance, although application may instantiate more than one\n * instances of this if required.\n */\ntypedef struct pjmedia_event_mgr pjmedia_event_mgr;\n\n/**\n * Create a new event manager instance. This will also set the pointer\n * to the singleton instance if the value is still NULL.\n *\n * @param pool\t\tPool to allocate memory from.\n * @param options       Options. Bitmask flags from #pjmedia_event_mgr_flag\n * @param mgr\t\tPointer to hold the created instance of the\n * \t\t\tevent manager.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_event_mgr_create(pj_pool_t *pool,\n                                              unsigned options,\n\t\t\t\t              pjmedia_event_mgr **mgr);\n\n/**\n * Get the singleton instance of the event manager.\n *\n * @return\t\tThe instance.\n */\nPJ_DECL(pjmedia_event_mgr*) pjmedia_event_mgr_instance(void);\n\n/**\n * Manually assign a specific event manager instance as the singleton\n * instance. Normally this is not needed if only one instance is ever\n * going to be created, as the library automatically assign the singleton\n * instance.\n *\n * @param mgr\t\tThe instance to be used as the singleton instance.\n * \t\t\tApplication may specify NULL to clear the singleton\n * \t\t\tsingleton instance.\n */\nPJ_DECL(void) pjmedia_event_mgr_set_instance(pjmedia_event_mgr *mgr);\n\n/**\n * Destroy an event manager. If the manager happens to be the singleton\n * instance, the singleton instance will be set to NULL.\n *\n * @param mgr\t\tThe eventmanager. Specify NULL to use\n * \t\t\tthe singleton instance.\n */\nPJ_DECL(void) pjmedia_event_mgr_destroy(pjmedia_event_mgr *mgr);\n\n/**\n * Initialize event structure with basic data about the event.\n *\n * @param event\t\tThe event to be initialized.\n * @param type\t\tThe event type to be set for this event.\n * @param ts\t\tEvent timestamp. May be set to NULL to set the event\n * \t\t\ttimestamp to zero.\n * @param src\t\tEvent source.\n */\nPJ_DECL(void) pjmedia_event_init(pjmedia_event *event,\n                                 pjmedia_event_type type,\n                                 const pj_timestamp *ts,\n                                 const void *src);\n\n/**\n * Subscribe a callback function to events published by the specified\n * publisher. Note that the subscriber may receive not only events emitted by\n * the specific publisher specified in the argument, but also from other\n * publishers contained by the publisher, if the publisher is republishing\n * events from other publishers.\n *\n * @param mgr\t\tThe event manager.\n * @param cb            The callback function to receive the event.\n * @param user_data     The user data to be associated with the callback\n *                      function.\n * @param epub\t\tThe event publisher.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_event_subscribe(pjmedia_event_mgr *mgr,\n                                             pjmedia_event_cb *cb,\n                                             void *user_data,\n                                             void *epub);\n\n/**\n * Unsubscribe the callback associated with the user data from a publisher.\n * If the user data is not specified, this function will do the\n * unsubscription for all user data. If the publisher, epub, is not\n * specified, this function will do the unsubscription from all publishers.\n *\n * @param mgr\t\tThe event manager.\n * @param cb            The callback function.\n * @param user_data     The user data associated with the callback\n *                      function, can be NULL.\n * @param epub\t\tThe event publisher, can be NULL.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t)\npjmedia_event_unsubscribe(pjmedia_event_mgr *mgr,\n                          pjmedia_event_cb *cb,\n                          void *user_data,\n                          void *epub);\n\n/**\n * Publish the specified event to all subscribers of the specified event\n * publisher. By default, the function will call all the subcribers'\n * callbacks immediately. If the publisher uses the flag\n * PJMEDIA_EVENT_PUBLISH_POST_EVENT, publisher will only post the event\n * to the event manager and return immediately. It is the event manager\n * that will later notify all the publisher's subscribers.\n *\n * @param mgr\t\tThe event manager.\n * @param epub\t\tThe event publisher.\n * @param event\t\tThe event to be published.\n * @param flag          Publication flag.\n *\n * @return\t\tPJ_SUCCESS only if all subscription callbacks returned\n * \t\t\tPJ_SUCCESS.\n */\nPJ_DECL(pj_status_t) pjmedia_event_publish(pjmedia_event_mgr *mgr,\n                                           void *epub,\n                                           pjmedia_event *event,\n                                           pjmedia_event_publish_flag flag);\n\n\n/**\n * @}  PJMEDIA_EVENT\n */\n\n\nPJ_END_DECL\n\n#endif\t/* __PJMEDIA_EVENT_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/format.h",
    "content": "/* $Id: format.h 4470 2013-04-15 10:40:26Z bennylp $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef __PJMEDIA_FORMAT_H__\n#define __PJMEDIA_FORMAT_H__\n\n/**\n * @file pjmedia/format.h Media format\n * @brief Media format\n */\n#include <pjmedia/types.h>\n\n/**\n * @defgroup PJMEDIA_FORMAT Media format\n * @ingroup PJMEDIA_TYPES\n * @brief Media format\n * @{\n */\n\nPJ_BEGIN_DECL\n\n/**\n * Macro for packing format from a four character code, similar to FOURCC.\n * This macro is used for building the constants in pjmedia_format_id\n * enumeration.\n */\n#define PJMEDIA_FORMAT_PACK(C1, C2, C3, C4) PJMEDIA_FOURCC(C1, C2, C3, C4)\n\n/**\n * This enumeration uniquely identify audio sample and/or video pixel formats.\n * Some well known formats are listed here. The format ids are built by\n * combining four character codes, similar to FOURCC. The format id is\n * extensible, as application may define and use format ids not declared\n * on this enumeration.\n *\n * This format id along with other information will fully describe the media\n * in #pjmedia_format structure.\n */\ntypedef enum pjmedia_format_id\n{\n    /*\n     * Audio formats\n     */\n\n    /** 16bit signed integer linear PCM audio */\n    PJMEDIA_FORMAT_L16\t    = 0,\n\n    /** Alias for PJMEDIA_FORMAT_L16 */\n    PJMEDIA_FORMAT_PCM\t    = PJMEDIA_FORMAT_L16,\n\n    /** G.711 ALAW */\n    PJMEDIA_FORMAT_PCMA\t    = PJMEDIA_FORMAT_PACK('A', 'L', 'A', 'W'),\n\n    /** Alias for PJMEDIA_FORMAT_PCMA */\n    PJMEDIA_FORMAT_ALAW\t    = PJMEDIA_FORMAT_PCMA,\n\n    /** G.711 ULAW */\n    PJMEDIA_FORMAT_PCMU\t    = PJMEDIA_FORMAT_PACK('u', 'L', 'A', 'W'),\n\n    /** Aliaw for PJMEDIA_FORMAT_PCMU */\n    PJMEDIA_FORMAT_ULAW\t    = PJMEDIA_FORMAT_PCMU,\n\n    /** AMR narrowband */\n    PJMEDIA_FORMAT_AMR\t    = PJMEDIA_FORMAT_PACK(' ', 'A', 'M', 'R'),\n\n    /** ITU G.729 */\n    PJMEDIA_FORMAT_G729\t    = PJMEDIA_FORMAT_PACK('G', '7', '2', '9'),\n\n    /** Internet Low Bit-Rate Codec (ILBC) */\n    PJMEDIA_FORMAT_ILBC\t    = PJMEDIA_FORMAT_PACK('I', 'L', 'B', 'C'),\n\n\n    /*\n     * Video formats.\n     */\n    /**\n     * 24bit RGB\n     */\n    PJMEDIA_FORMAT_RGB24    = PJMEDIA_FORMAT_PACK('R', 'G', 'B', '3'),\n\n    /**\n     * 32bit RGB with alpha channel\n     */\n    PJMEDIA_FORMAT_ARGB     = PJMEDIA_FORMAT_PACK('A', 'R', 'G', 'B'),\n    PJMEDIA_FORMAT_RGBA     = PJMEDIA_FORMAT_PACK('R', 'G', 'B', 'A'),\n    PJMEDIA_FORMAT_BGRA     = PJMEDIA_FORMAT_PACK('B', 'G', 'R', 'A'),\n\n    /**\n     * Alias for PJMEDIA_FORMAT_RGBA\n     */\n    PJMEDIA_FORMAT_RGB32    = PJMEDIA_FORMAT_RGBA,\n\n    /**\n     * Device Independent Bitmap, alias for 24 bit RGB\n     */\n    PJMEDIA_FORMAT_DIB      = PJMEDIA_FORMAT_PACK('D', 'I', 'B', ' '),\n\n    /**\n     * This is planar 4:4:4/24bpp RGB format, the data can be treated as\n     * three planes of color components, where the first plane contains\n     * only the G samples, the second plane contains only the B samples,\n     * and the third plane contains only the R samples.\n     */\n    PJMEDIA_FORMAT_GBRP    = PJMEDIA_FORMAT_PACK('G', 'B', 'R', 'P'),\n\n    /**\n     * This is a packed 4:4:4/32bpp format, where each pixel is encoded as\n     * four consecutive bytes, arranged in the following sequence: V0, U0,\n     * Y0, A0. Source:\n     * http://msdn.microsoft.com/en-us/library/dd206750%28v=VS.85%29.aspx#ayuv\n     */\n    PJMEDIA_FORMAT_AYUV\t    = PJMEDIA_FORMAT_PACK('A', 'Y', 'U', 'V'),\n\n    /**\n     * This is packed 4:2:2/16bpp YUV format, the data can be treated as\n     * an array of unsigned char values, where the first byte contains\n     * the first Y sample, the second byte contains the first U (Cb) sample,\n     * the third byte contains the second Y sample, and the fourth byte\n     * contains the first V (Cr) sample, and so forth. Source:\n     * http://msdn.microsoft.com/en-us/library/dd206750%28v=VS.85%29.aspx#yuy2\n     */\n    PJMEDIA_FORMAT_YUY2\t    = PJMEDIA_FORMAT_PACK('Y', 'U', 'Y', '2'),\n\n    /**\n     * This format is the same as the YUY2 format except the byte order is\n     * reversed -- that is, the chroma and luma bytes are flipped. If the\n     * image is addressed as an array of two little-endian WORD values, the\n     * first WORD contains U in the LSBs and Y0 in the MSBs, and the second\n     * WORD contains V in the LSBs and Y1 in the MSBs. Source:\n     * http://msdn.microsoft.com/en-us/library/dd206750%28v=VS.85%29.aspx#uyvy\n     */\n    PJMEDIA_FORMAT_UYVY\t    = PJMEDIA_FORMAT_PACK('U', 'Y', 'V', 'Y'),\n\n    /**\n     * This format is the same as the YUY2 and UYVY format except the byte\n     * order is reversed -- that is, the chroma and luma bytes are flipped.\n     * If the image is addressed as an array of two little-endian WORD values,\n     * the first WORD contains Y0 in the LSBs and V in the MSBs, and the second\n     * WORD contains Y1 in the LSBs and U in the MSBs.\n     */\n    PJMEDIA_FORMAT_YVYU\t    = PJMEDIA_FORMAT_PACK('Y', 'V', 'Y', 'U'),\n\n    /**\n     * This is planar 4:2:0/12bpp YUV format, the data can be treated as\n     * three planes of color components, where the first plane contains\n     * only the Y samples, the second plane contains only the U (Cb) samples,\n     * and the third plane contains only the V (Cr) sample.\n     */\n    PJMEDIA_FORMAT_I420\t    = PJMEDIA_FORMAT_PACK('I', '4', '2', '0'),\n\n    /**\n     * IYUV is alias for I420.\n     */\n    PJMEDIA_FORMAT_IYUV\t    = PJMEDIA_FORMAT_I420,\n\n    /**\n     * This is planar 4:2:0/12bpp YUV format, similar to I420 or IYUV but\n     * the U (Cb) and V (Cr) planes order is switched, i.e: the second plane\n     * contains the V (Cb) samples and the third plane contains the V (Cr)\n     * samples.\n     */\n    PJMEDIA_FORMAT_YV12\t    = PJMEDIA_FORMAT_PACK('Y', 'V', '1', '2'),\n\n    /**\n     * This is planar 4:2:0/12bpp YUV format, the data can be treated as\n     * two planes of color components, where the first plane contains\n     * only the Y samples, the second plane contains interleaved\n     * V (Cr) - U (Cb) samples.\n     */\n    PJMEDIA_FORMAT_NV21\t    = PJMEDIA_FORMAT_PACK('N', 'V', '2', '1'),\n    \n    /**\n     * This is planar 4:2:2/16bpp YUV format, the data can be treated as\n     * three planes of color components, where the first plane contains\n     * only the Y samples, the second plane contains only the U (Cb) samples,\n     * and the third plane contains only the V (Cr) sample.\n     */\n    PJMEDIA_FORMAT_I422\t    = PJMEDIA_FORMAT_PACK('I', '4', '2', '2'),\n\n    /**\n     * The JPEG version of planar 4:2:0/12bpp YUV format.\n     */\n    PJMEDIA_FORMAT_I420JPEG = PJMEDIA_FORMAT_PACK('J', '4', '2', '0'),\n\n    /**\n     * The JPEG version of planar 4:2:2/16bpp YUV format.\n     */\n    PJMEDIA_FORMAT_I422JPEG = PJMEDIA_FORMAT_PACK('J', '4', '2', '2'),\n\n    /**\n     * Encoded video formats\n     */\n\n    PJMEDIA_FORMAT_H261     = PJMEDIA_FORMAT_PACK('H', '2', '6', '1'),\n    PJMEDIA_FORMAT_H263     = PJMEDIA_FORMAT_PACK('H', '2', '6', '3'),\n    PJMEDIA_FORMAT_H263P    = PJMEDIA_FORMAT_PACK('P', '2', '6', '3'),\n    PJMEDIA_FORMAT_H264     = PJMEDIA_FORMAT_PACK('H', '2', '6', '4'),\n\n    PJMEDIA_FORMAT_MJPEG    = PJMEDIA_FORMAT_PACK('M', 'J', 'P', 'G'),\n    PJMEDIA_FORMAT_MPEG1VIDEO = PJMEDIA_FORMAT_PACK('M', 'P', '1', 'V'),\n    PJMEDIA_FORMAT_MPEG2VIDEO = PJMEDIA_FORMAT_PACK('M', 'P', '2', 'V'),\n    PJMEDIA_FORMAT_MPEG4    = PJMEDIA_FORMAT_PACK('M', 'P', 'G', '4'),\n\n    PJMEDIA_FORMAT_VP8 = PJMEDIA_FORMAT_PACK('L', 'V', 'P', '8'),\n} pjmedia_format_id;\n\n/**\n * This enumeration specifies what type of detail is included in a\n * #pjmedia_format structure.\n */\ntypedef enum pjmedia_format_detail_type\n{\n    /** Format detail is not specified. */\n    PJMEDIA_FORMAT_DETAIL_NONE,\n\n    /** Audio format detail. */\n    PJMEDIA_FORMAT_DETAIL_AUDIO,\n\n    /** Video format detail. */\n    PJMEDIA_FORMAT_DETAIL_VIDEO,\n\n    /** Number of format detail type that has been defined. */\n    PJMEDIA_FORMAT_DETAIL_MAX\n\n} pjmedia_format_detail_type;\n\n/**\n * This structure is put in \\a detail field of #pjmedia_format to describe\n * detail information about an audio media.\n */\ntypedef struct pjmedia_audio_format_detail\n{\n    unsigned\tclock_rate;\t/**< Audio clock rate in samples or Hz. */\n    unsigned\tchannel_count;\t/**< Number of channels.\t\t*/\n    unsigned\tframe_time_usec;/**< Frame interval, in microseconds.\t*/\n    unsigned\tbits_per_sample;/**< Number of bits per sample.\t\t*/\n    pj_uint32_t\tavg_bps;\t/**< Average bitrate\t\t\t*/\n    pj_uint32_t\tmax_bps;\t/**< Maximum bitrate\t\t\t*/\n} pjmedia_audio_format_detail;\n\n/**\n * This structure is put in \\a detail field of #pjmedia_format to describe\n * detail information about a video media.\n *\n * Additional information about a video format can also be retrieved by\n * calling #pjmedia_get_video_format_info().\n */\ntypedef struct pjmedia_video_format_detail\n{\n    pjmedia_rect_size\tsize;\t/**< Video size (width, height) \t*/\n    pjmedia_ratio\tfps;\t/**< Number of frames per second.\t*/\n    pj_uint32_t\t\tavg_bps;/**< Average bitrate.\t\t\t*/\n    pj_uint32_t\t\tmax_bps;/**< Maximum bitrate.\t\t\t*/\n} pjmedia_video_format_detail;\n\n/**\n * This macro declares the size of the detail section in #pjmedia_format\n * to be reserved for user defined detail.\n */\n#ifndef PJMEDIA_FORMAT_DETAIL_USER_SIZE\n#   define PJMEDIA_FORMAT_DETAIL_USER_SIZE\t\t1\n#endif\n\n/**\n * This structure contains all the information needed to completely describe\n * a media.\n */\ntypedef struct pjmedia_format\n{\n    /**\n     * The format id that specifies the audio sample or video pixel format.\n     * Some well known formats ids are declared in pjmedia_format_id\n     * enumeration.\n     *\n     * @see pjmedia_format_id\n     */\n    pj_uint32_t\t\t \t id;\n\n    /**\n     * The top-most type of the media, as an information.\n     */\n    pjmedia_type\t\t type;\n\n    /**\n     * The type of detail structure in the \\a detail pointer.\n     */\n    pjmedia_format_detail_type\t detail_type;\n\n    /**\n     * Detail section to describe the media.\n     */\n    union\n    {\n\t/**\n\t * Detail section for audio format.\n\t */\n\tpjmedia_audio_format_detail\taud;\n\n\t/**\n\t * Detail section for video format.\n\t */\n\tpjmedia_video_format_detail\tvid;\n\n\t/**\n\t * Reserved area for user-defined format detail.\n\t */\n\tchar\t\t\t\tuser[PJMEDIA_FORMAT_DETAIL_USER_SIZE];\n    } det;\n\n} pjmedia_format;\n\n/**\n * This enumeration describes video color model. It mostly serves as\n * information only.\n */\ntypedef enum pjmedia_color_model\n{\n    /** The color model is unknown or unspecified. */\n    PJMEDIA_COLOR_MODEL_NONE,\n\n    /** RGB color model. */\n    PJMEDIA_COLOR_MODEL_RGB,\n\n    /** YUV color model. */\n    PJMEDIA_COLOR_MODEL_YUV\n} pjmedia_color_model;\n\n/**\n * This structure holds information to apply a specific video format\n * against size and buffer information, and get additional information\n * from it. To do that, application fills up the input fields of this\n * structure, and give this structure to \\a apply_fmt() function\n * of #pjmedia_video_format_info structure.\n */\ntypedef struct pjmedia_video_apply_fmt_param\n{\n    /* input fields: */\n\n    /**\n     * [IN] The image size. This field is mandatory, and has to be set\n     * correctly prior to calling \\a apply_fmt() function.\n     */\n    pjmedia_rect_size\t size;\n\n    /**\n     * [IN] Pointer to the buffer that holds the frame. The \\a apply_fmt()\n     * function uses this pointer to calculate the pointer for each video\n     * planes of the media. This field is optional -- however, the\n     * \\a apply_fmt() would still fill up the \\a planes[] array with the\n     * correct pointer even though the buffer is set to NULL. This could be\n     * useful to calculate the size (in bytes) of each plane.\n     */\n    pj_uint8_t\t\t*buffer;\n\n    /* output fields: */\n\n    /**\n     * [OUT] The size (in bytes) required of the buffer to hold the video\n     * frame of the particular frame size (width, height).\n     */\n    pj_size_t\t\t framebytes;\n\n    /**\n     * [OUT] Array of strides value (in bytes) for each video plane.\n     */\n    int\t\t         strides[PJMEDIA_MAX_VIDEO_PLANES];\n\n    /**\n     * [OUT] Array of pointers to each of the video planes. The values are\n     * calculated from the \\a buffer field.\n     */\n    pj_uint8_t\t\t*planes[PJMEDIA_MAX_VIDEO_PLANES];\n\n    /**\n     * [OUT] Array of video plane sizes.\n     */\n    pj_size_t\t\t plane_bytes[PJMEDIA_MAX_VIDEO_PLANES];\n\n} pjmedia_video_apply_fmt_param;\n\n/**\n * This structure holds information to describe a video format. Application\n * can retrieve this structure by calling #pjmedia_get_video_format_info()\n * funcion.\n */\ntypedef struct pjmedia_video_format_info\n{\n    /**\n     * The unique format ID of the media. Well known format ids are declared\n     * in pjmedia_format_id enumeration.\n     */\n    pj_uint32_t\t\tid;\n\n    /**\n     * Null terminated string containing short identification about the\n     * format.\n     */\n    char\t\tname[8];\n\n    /**\n     * Information about the color model of this video format.\n     */\n    pjmedia_color_model\tcolor_model;\n\n    /**\n     * Number of bits needed to store one pixel of this video format.\n     */\n    pj_uint8_t\t\tbpp;\n\n    /**\n     * Number of video planes that this format uses. Value 1 indicates\n     * packed format, while value greater than 1 indicates planar format.\n     */\n    pj_uint8_t\t\tplane_cnt;\n\n    /**\n     * Pointer to function to apply this format against size and buffer\n     * information in pjmedia_video_apply_fmt_param argument. Application\n     * uses this function to obtain various information such as the\n     * memory size of a frame buffer, strides value of the image, the\n     * location of the planes, and so on. See pjmedia_video_apply_fmt_param\n     * for additional information.\n     *\n     * @param vfi\tThe video format info.\n     * @param vafp\tThe parameters to investigate.\n     *\n     * @return\t\tPJ_SUCCESS if the function has calculated the\n     * \t\t\tinformation in \\a vafp successfully.\n     */\n    pj_status_t (*apply_fmt)(const struct pjmedia_video_format_info *vfi,\n\t                     pjmedia_video_apply_fmt_param *vafp);\n\n} pjmedia_video_format_info;\n\n\n/*****************************************************************************\n * UTILITIES:\n */\n\n/**\n * General utility routine to calculate samples per frame value from clock\n * rate, ptime (in usec), and channel count. Application should use this\n * macro whenever possible due to possible overflow in the math calculation.\n *\n * @param clock_rate\t\tClock rate.\n * @param usec_ptime\t\tFrame interval, in microsecond.\n * @param channel_count\t\tNumber of channels.\n *\n * @return\t\t\tThe samples per frame value.\n */\nPJ_INLINE(unsigned) PJMEDIA_SPF(unsigned clock_rate, unsigned usec_ptime,\n\t\t\t\tunsigned channel_count)\n{\n#if PJ_HAS_INT64\n    return ((unsigned)((pj_uint64_t)usec_ptime * \\\n\t\t       clock_rate * channel_count / 1000000));\n#elif PJ_HAS_FLOATING_POINT\n    return ((unsigned)(1.0*usec_ptime * clock_rate * channel_count / 1000000));\n#else\n    return ((unsigned)(usec_ptime / 1000L * clock_rate * \\\n\t\t       channel_count / 1000));\n#endif\n}\n\n/**\n * Variant of #PJMEDIA_SPF() which takes frame rate instead of ptime.\n */\nPJ_INLINE(unsigned) PJMEDIA_SPF2(unsigned clock_rate, const pjmedia_ratio *fr,\n\t\t\t\t unsigned channel_count)\n{\n#if PJ_HAS_INT64\n    return ((unsigned)((pj_uint64_t)clock_rate * fr->denum \\\n\t\t       / fr->num / channel_count));\n#elif PJ_HAS_FLOATING_POINT\n    return ((unsigned)(1.0* clock_rate * fr->denum / fr->num /channel_count));\n#else\n    return ((unsigned)(1L * clock_rate * fr->denum / fr->num / channel_count));\n#endif\n}\n\n\n/**\n * Utility routine to calculate frame size (in bytes) from bitrate and frame\n * interval values. Application should use this macro whenever possible due\n * to possible overflow in the math calculation.\n *\n * @param bps\t\t\tThe bitrate of the stream.\n * @param usec_ptime\t\tFrame interval, in microsecond.\n *\n * @return\t\t\tFrame size in bytes.\n */\nPJ_INLINE(unsigned) PJMEDIA_FSZ(unsigned bps, unsigned usec_ptime)\n{\n#if PJ_HAS_INT64\n    return ((unsigned)((pj_uint64_t)bps * usec_ptime / PJ_UINT64(8000000)));\n#elif PJ_HAS_FLOATING_POINT\n    return ((unsigned)(1.0 * bps * usec_ptime / 8000000.0));\n#else\n    return ((unsigned)(bps / 8L * usec_ptime / 1000000));\n#endif\n}\n\n/**\n * General utility routine to calculate ptime value from frame rate.\n * Application should use this macro whenever possible due to possible\n * overflow in the math calculation.\n *\n * @param frame_rate\t\tFrame rate\n *\n * @return\t\t\tThe ptime value (in usec).\n */\nPJ_INLINE(unsigned) PJMEDIA_PTIME(const pjmedia_ratio *frame_rate)\n{\n#if PJ_HAS_INT64\n    return ((unsigned)((pj_uint64_t)1000000 * \\\n\t\t       frame_rate->denum / frame_rate->num));\n#elif PJ_HAS_FLOATING_POINT\n    return ((unsigned)(1000000.0 * frame_rate->denum /\n                       frame_rate->num));\n#else\n    return ((unsigned)((1000L * frame_rate->denum /\n                       frame_rate->num) * 1000));\n#endif\n}\n\n/**\n * Utility to retrieve samples_per_frame value from\n * pjmedia_audio_format_detail.\n *\n * @param pafd\t\tPointer to pjmedia_audio_format_detail\n * @return\t\tSamples per frame\n */\nPJ_INLINE(unsigned) PJMEDIA_AFD_SPF(const pjmedia_audio_format_detail *pafd)\n{\n    return PJMEDIA_SPF(pafd->clock_rate, pafd->frame_time_usec,\n\t\t       pafd->channel_count);\n}\n\n/**\n * Utility to retrieve average frame size from pjmedia_audio_format_detail.\n * The average frame size is derived from the average bitrate of the audio\n * stream.\n *\n * @param afd\t\tPointer to pjmedia_audio_format_detail\n * @return\t\tAverage frame size.\n */\nPJ_INLINE(unsigned) PJMEDIA_AFD_AVG_FSZ(const pjmedia_audio_format_detail *afd)\n{\n    return PJMEDIA_FSZ(afd->avg_bps, afd->frame_time_usec);\n}\n\n/**\n * Utility to retrieve maximum frame size from pjmedia_audio_format_detail.\n * The maximum frame size is derived from the maximum bitrate of the audio\n * stream.\n *\n * @param afd\t\tPointer to pjmedia_audio_format_detail\n * @return\t\tAverage frame size.\n */\nPJ_INLINE(unsigned) PJMEDIA_AFD_MAX_FSZ(const pjmedia_audio_format_detail *afd)\n{\n    return PJMEDIA_FSZ(afd->max_bps, afd->frame_time_usec);\n}\n\n\n/**\n * Initialize the format as audio format with the specified parameters.\n *\n * @param fmt\t\t\tThe format to be initialized.\n * @param fmt_id\t\tFormat ID. See #pjmedia_format_id\n * @param clock_rate\t\tAudio clock rate.\n * @param channel_count\t\tNumber of channels.\n * @param bits_per_sample\tNumber of bits per sample.\n * @param frame_time_usec\tFrame interval, in microsecond.\n * @param avg_bps\t\tAverage bitrate.\n * @param max_bps\t\tMaximum bitrate.\n */\nPJ_INLINE(void) pjmedia_format_init_audio(pjmedia_format *fmt,\n\t\t\t\t          pj_uint32_t fmt_id,\n\t\t\t\t\t  unsigned clock_rate,\n\t\t\t\t\t  unsigned channel_count,\n\t\t\t\t\t  unsigned bits_per_sample,\n\t\t\t\t\t  unsigned frame_time_usec,\n\t\t\t\t\t  pj_uint32_t avg_bps,\n\t\t\t\t\t  pj_uint32_t max_bps)\n{\n    /* This function is inlined to avoid build problem due to circular\n     * dependency, i.e: this function is part of pjmedia and is needed\n     * by pjmedia-audiodev, while pjmedia depends on pjmedia-audiodev.\n     */\n\n    fmt->id = fmt_id;\n    fmt->type = PJMEDIA_TYPE_AUDIO;\n    fmt->detail_type = PJMEDIA_FORMAT_DETAIL_AUDIO;\n\n    fmt->det.aud.clock_rate = clock_rate;\n    fmt->det.aud.channel_count = channel_count;\n    fmt->det.aud.bits_per_sample = bits_per_sample;\n    fmt->det.aud.frame_time_usec = frame_time_usec;\n    fmt->det.aud.avg_bps = avg_bps;\n    fmt->det.aud.max_bps = max_bps;\n}\n\n\n/**\n * Initialize the format as video format with the specified parameters.\n * A format manager should have been created, as this function will need\n * to consult to a format manager in order to fill in detailed\n * information about the format.\n *\n * @param fmt\t\tThe format to be initialised.\n * @param fmt_id\tFormat ID. See #pjmedia_format_id\n * @param width\t\tImage width.\n * @param height\tImage heigth.\n * @param fps_num\tFPS numerator.\n * @param fps_denum\tFPS denumerator.\n * @param avg_bps\tAverage bitrate.\n * @param max_bps\tMaximum bitrate.\n */\nPJ_DECL(void) pjmedia_format_init_video(pjmedia_format *fmt,\n\t\t\t\t\tpj_uint32_t fmt_id,\n\t\t\t\t\tunsigned width,\n\t\t\t\t\tunsigned height,\n\t\t\t\t\tunsigned fps_num,\n\t\t\t\t\tunsigned fps_denum);\n\n/**\n * Copy format to another.\n *\n * @param dst\t\tThe destination format.\n * @param src\t\tThe source format.\n *\n * @return\t\tPointer to destination format.\n */\nPJ_DECL(pjmedia_format*) pjmedia_format_copy(pjmedia_format *dst,\n\t\t\t\t\t     const pjmedia_format *src);\n\n/**\n * Check if the format contains audio format, and retrieve the audio format\n * detail in the format.\n *\n * @param fmt\t\tThe format structure.\n * @param assert_valid\tIf this is set to non-zero, an assertion will be\n * \t\t\traised if the detail type is not audio or if the\n * \t\t\tthe detail is NULL.\n *\n * @return\t\tThe instance of audio format detail in the format\n * \t\t\tstructure, or NULL if the format doesn't contain\n * \t\t\taudio detail.\n */\nPJ_DECL(pjmedia_audio_format_detail*)\npjmedia_format_get_audio_format_detail(const pjmedia_format *fmt,\n\t\t\t\t       pj_bool_t assert_valid);\n\n/**\n * Check if the format contains video format, and retrieve the video format\n * detail in the format.\n *\n * @param fmt\t\tThe format structure.\n * @param assert_valid\tIf this is set to non-zero, an assertion will be\n * \t\t\traised if the detail type is not video or if the\n * \t\t\tthe detail is NULL.\n *\n * @return\t\tThe instance of video format detail in the format\n * \t\t\tstructure, or NULL if the format doesn't contain\n * \t\t\tvideo detail.\n */\nPJ_DECL(pjmedia_video_format_detail*)\npjmedia_format_get_video_format_detail(const pjmedia_format *fmt,\n\t\t\t\t       pj_bool_t assert_valid);\n\n/*****************************************************************************\n * FORMAT MANAGEMENT:\n */\n\n/**\n * Opaque data type for video format manager. The video format manager manages\n * the repository of video formats that the framework recognises. Typically it\n * is a singleton instance, although application may instantiate more than one\n * instances of this if required.\n */\ntypedef struct pjmedia_video_format_mgr pjmedia_video_format_mgr;\n\n\n/**\n * Create a new video format manager instance. This will also set the pointer\n * to the singleton instance if the value is still NULL.\n *\n * @param pool\t\tThe pool to allocate memory.\n * @param max_fmt\tMaximum number of formats to accommodate.\n * @param options\tOption flags. Must be zero for now.\n * @param p_mgr\t\tPointer to hold the created instance.\n *\n * @return\t\tPJ_SUCCESS on success, or the appripriate error value.\n */\nPJ_DECL(pj_status_t)\npjmedia_video_format_mgr_create(pj_pool_t *pool,\n\t\t\t\tunsigned max_fmt,\n\t\t\t\tunsigned options,\n\t\t\t\tpjmedia_video_format_mgr **p_mgr);\n\n/**\n * Get the singleton instance of the video format manager.\n *\n * @return\t\tThe instance.\n */\nPJ_DECL(pjmedia_video_format_mgr*) pjmedia_video_format_mgr_instance(void);\n\n/**\n * Manually assign a specific video manager instance as the singleton\n * instance. Normally this is not needed if only one instance is ever\n * going to be created, as the library automatically assign the singleton\n * instance.\n *\n * @param mgr\t\tThe instance to be used as the singleton instance.\n * \t\t\tApplication may specify NULL to clear the singleton\n * \t\t\tsingleton instance.\n */\nPJ_DECL(void)\npjmedia_video_format_mgr_set_instance(pjmedia_video_format_mgr *mgr);\n\n/**\n * Retrieve a video format info for the specified format id.\n *\n * @param mgr\t\tThe video format manager. Specify NULL to use\n * \t\t\tthe singleton instance (however, a video format\n * \t\t\tmanager still must have been created prior to\n * \t\t\tcalling this function).\n * @param id\t\tThe format id which format info is to be\n * \t\t\tretrieved.\n *\n * @return\t\tThe video format info.\n */\nPJ_DECL(const pjmedia_video_format_info*)\npjmedia_get_video_format_info(pjmedia_video_format_mgr *mgr,\n\t\t\t      pj_uint32_t id);\n\n/**\n * Register a new video format to the framework. By default, built-in\n * formats will be registered automatically to the format manager when\n * it is created (note: built-in formats are ones which format id is\n * listed in pjmedia_format_id enumeration). This function allows\n * application to use user defined format id by registering that format\n * into the framework.\n *\n * @param mgr\t\tThe video format manager. Specify NULL to use\n * \t\t\tthe singleton instance (however, a video format\n * \t\t\tmanager still must have been created prior to\n * \t\t\tcalling this function).\n * @param vfi\t\tThe video format info to be registered. This\n * \t\t\tstructure must remain valid until the format\n * \t\t\tmanager is destroyed.\n *\n * @return\t\tPJ_SUCCESS on success, or the appripriate error value.\n */\nPJ_DECL(pj_status_t)\npjmedia_register_video_format_info(pjmedia_video_format_mgr *mgr,\n\t\t\t\t   pjmedia_video_format_info *vfi);\n\n/**\n * Destroy a video format manager. If the manager happens to be the singleton\n * instance, the singleton instance will be set to NULL.\n *\n * @param mgr\t\tThe video format manager. Specify NULL to use\n * \t\t\tthe singleton instance (however, a video format\n * \t\t\tmanager still must have been created prior to\n * \t\t\tcalling this function).\n */\nPJ_DECL(void) pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr *mgr);\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_FORMAT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/frame.h",
    "content": "/* $Id: frame.h 3715 2011-08-19 09:35:25Z nanang $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef __PJMEDIA_FRAME_H__\n#define __PJMEDIA_FRAME_H__\n\n/**\n * @file pjmedia/frame.h Media frame\n * @brief Frame\n */\n#include <pjmedia/types.h>\n#include <pj/string.h>\n\n/**\n * @defgroup PJMEDIA_FRAME Media frame\n * @ingroup PJMEDIA_TYPES\n * @brief Frame\n * @{\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Types of media frame.\n */\ntypedef enum pjmedia_frame_type\n{\n    PJMEDIA_FRAME_TYPE_NONE,\t    /**< No frame.\t\t*/\n    PJMEDIA_FRAME_TYPE_AUDIO,\t    /**< Normal audio frame.\t*/\n    PJMEDIA_FRAME_TYPE_EXTENDED,    /**< Extended audio frame.\t*/\n    PJMEDIA_FRAME_TYPE_VIDEO        /**< Video frame.           */\n\n} pjmedia_frame_type;\n\n\n/**\n * This structure describes a media frame.\n */\ntypedef struct pjmedia_frame\n{\n    pjmedia_frame_type\t type;\t    /**< Frame type.\t\t\t    */\n    void\t\t*buf;\t    /**< Pointer to buffer.\t\t    */\n    pj_size_t\t\t size;\t    /**< Frame size in bytes.\t\t    */\n    pj_timestamp\t timestamp; /**< Frame timestamp.\t\t    */\n    pj_uint32_t\t\t bit_info;  /**< Bit info of the frame, sample case:\n\t\t\t\t\t a frame may not exactly start and end\n\t\t\t\t\t at the octet boundary, so this field\n\t\t\t\t\t may be used for specifying start &\n\t\t\t\t\t end bit offset.\t\t    */\n} pjmedia_frame;\n\n\n/**\n * The pjmedia_frame_ext is used to carry a more complex audio frames than\n * the typical PCM audio frames, and it is signaled by setting the \"type\"\n * field of a pjmedia_frame to PJMEDIA_FRAME_TYPE_EXTENDED. With this set,\n * application may typecast pjmedia_frame to pjmedia_frame_ext.\n *\n * This structure may contain more than one audio frames, which subsequently\n * will be called subframes in this structure. The subframes section\n * immediately follows the end of this structure, and each subframe is\n * represented by pjmedia_frame_ext_subframe structure. Every next\n * subframe immediately follows the previous subframe, and all subframes\n * are byte-aligned although its payload may not be byte-aligned.\n */\n\n#pragma pack(1)\ntypedef struct pjmedia_frame_ext {\n    pjmedia_frame   base;\t    /**< Base frame info */\n    pj_uint16_t     samples_cnt;    /**< Number of samples in this frame */\n    pj_uint16_t     subframe_cnt;   /**< Number of (sub)frames in this frame */\n\n    /* Zero or more (sub)frames follows immediately after this,\n     * each will be represented by pjmedia_frame_ext_subframe\n     */\n} pjmedia_frame_ext;\n#pragma pack()\n\n/**\n * This structure represents the individual subframes in the\n * pjmedia_frame_ext structure.\n */\n#pragma pack(1)\ntypedef struct pjmedia_frame_ext_subframe {\n    pj_uint16_t     bitlen;\t    /**< Number of bits in the data */\n    pj_uint8_t      data[1];\t    /**< Start of encoded data */\n} pjmedia_frame_ext_subframe;\n\n#pragma pack()\n\n/**\n * Copy one frame to another. If the destination frame's size is smaller than\n * the source frame's, the destination buffer will be truncated.\n *\n * @param src\t\t    Source frame.\n * @param dst\t\t    Destination frame.\n */\nPJ_INLINE(void) pjmedia_frame_copy(pjmedia_frame *dst,\n\t\t\t\t   const pjmedia_frame *src)\n{\n    dst->type = src->type;\n    dst->timestamp = src->timestamp;\n    dst->bit_info = src->bit_info;\n    dst->size = (dst->size < src->size? dst->size: src->size);\n    pj_memcpy(dst->buf, src->buf, dst->size);\n}\n\n/**\n * Append one subframe to #pjmedia_frame_ext.\n *\n * @param frm\t\t    The #pjmedia_frame_ext.\n * @param src\t\t    Subframe data.\n * @param bitlen\t    Length of subframe, in bits.\n * @param samples_cnt\t    Number of audio samples in subframe.\n */\nPJ_INLINE(void) pjmedia_frame_ext_append_subframe(pjmedia_frame_ext *frm,\n\t\t\t\t\t\t  const void *src,\n\t\t\t\t\t          unsigned bitlen,\n\t\t\t\t\t\t  unsigned samples_cnt)\n{\n    pjmedia_frame_ext_subframe *fsub;\n    pj_uint8_t *p;\n    unsigned i;\n\n    p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext);\n    for (i = 0; i < frm->subframe_cnt; ++i) {\n\tfsub = (pjmedia_frame_ext_subframe*) p;\n\tp += sizeof(fsub->bitlen) + ((fsub->bitlen+7) >> 3);\n    }\n\n    fsub = (pjmedia_frame_ext_subframe*) p;\n    fsub->bitlen = (pj_uint16_t)bitlen;\n    if (bitlen)\n\tpj_memcpy(fsub->data, src, (bitlen+7) >> 3);\n\n    frm->subframe_cnt++;\n    frm->samples_cnt = (pj_uint16_t)(frm->samples_cnt + samples_cnt);\n}\n\n/**\n * Get a subframe from #pjmedia_frame_ext.\n *\n * @param frm\t\t    The #pjmedia_frame_ext.\n * @param n\t\t    Subframe index, zero based.\n *\n * @return\t\t    The n-th subframe, or NULL if n is out-of-range.\n */\nPJ_INLINE(pjmedia_frame_ext_subframe*)\npjmedia_frame_ext_get_subframe(const pjmedia_frame_ext *frm, unsigned n)\n{\n    pjmedia_frame_ext_subframe *sf = NULL;\n\n    if (n < frm->subframe_cnt) {\n\tpj_uint8_t *p;\n\tunsigned i;\n\n\tp = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext);\n\tfor (i = 0; i < n; ++i) {\n\t    sf = (pjmedia_frame_ext_subframe*) p;\n\t    p += sizeof(sf->bitlen) + ((sf->bitlen+7) >> 3);\n\t}\n\n\tsf = (pjmedia_frame_ext_subframe*) p;\n    }\n\n    return sf;\n}\n\n/**\n * Extract all frame payload to the specified buffer.\n *\n * @param frm\t\t    The frame.\n * @param dst\t\t    Destination buffer.\n * @param maxlen\t    Maximum size to copy (i.e. the size of the\n *\t\t\t    destination buffer).\n *\n * @return\t\t    Total size of payload copied.\n */\nPJ_INLINE(unsigned)\npjmedia_frame_ext_copy_payload(const pjmedia_frame_ext *frm,\n\t\t\t       void *dst,\n\t\t\t       unsigned maxlen)\n{\n    unsigned i, copied=0;\n    for (i=0; i<frm->subframe_cnt; ++i) {\n\tpjmedia_frame_ext_subframe *sf;\n\tunsigned sz;\n\n\tsf = pjmedia_frame_ext_get_subframe(frm, i);\n\tif (!sf)\n\t    continue;\n\n\tsz = ((sf->bitlen + 7) >> 3);\n\tif (sz + copied > maxlen)\n\t    break;\n\n\tpj_memcpy(((pj_uint8_t*)dst) + copied, sf->data, sz);\n\tcopied += sz;\n    }\n    return copied;\n}\n\n\n/**\n * Pop out first n subframes from #pjmedia_frame_ext.\n *\n * @param frm\t\t    The #pjmedia_frame_ext.\n * @param n\t\t    Number of first subframes to be popped out.\n *\n * @return\t\t    PJ_SUCCESS when successful.\n */\nPJ_INLINE(pj_status_t)\npjmedia_frame_ext_pop_subframes(pjmedia_frame_ext *frm, unsigned n)\n{\n    pjmedia_frame_ext_subframe *sf;\n    pj_uint8_t *move_src;\n    pj_size_t move_len;\n\n    if (frm->subframe_cnt <= n) {\n\tfrm->subframe_cnt = 0;\n\tfrm->samples_cnt = 0;\n\treturn PJ_SUCCESS;\n    }\n\n    move_src = (pj_uint8_t*)pjmedia_frame_ext_get_subframe(frm, n);\n    sf = pjmedia_frame_ext_get_subframe(frm, frm->subframe_cnt-1);\n    move_len = ((pj_uint8_t*)sf - move_src + sizeof(sf->bitlen) +\n\t       ((sf->bitlen+7) >> 3));\n    pj_memmove((pj_uint8_t*)frm+sizeof(pjmedia_frame_ext),\n\t       move_src, move_len);\n\n    frm->samples_cnt = (pj_uint16_t)\n\t\t   (frm->samples_cnt - n*frm->samples_cnt/frm->subframe_cnt);\n    frm->subframe_cnt = (pj_uint16_t) (frm->subframe_cnt - n);\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * This is a general purpose function set PCM samples to zero.\n * Since this function is needed by many parts of the library,\n * by putting this functionality in one place, it enables some.\n * clever people to optimize this function.\n *\n * @param samples\tThe 16bit PCM samples.\n * @param count\t\tNumber of samples.\n */\nPJ_INLINE(void) pjmedia_zero_samples(pj_int16_t *samples, unsigned count)\n{\n#if 1\n    pj_bzero(samples, (count<<1));\n#elif 0\n    unsigned i;\n    for (i=0; i<count; ++i) samples[i] = 0;\n#else\n    unsigned i;\n    count >>= 1;\n    for (i=0; i<count; ++i) ((pj_int32_t*)samples)[i] = (pj_int32_t)0;\n#endif\n}\n\n\n/**\n * This is a general purpose function to copy samples from/to buffers with\n * equal size. Since this function is needed by many parts of the library,\n * by putting this functionality in one place, it enables some.\n * clever people to optimize this function.\n */\nPJ_INLINE(void) pjmedia_copy_samples(pj_int16_t *dst, const pj_int16_t *src,\n\t\t\t\t     unsigned count)\n{\n#if 1\n    pj_memcpy(dst, src, (count<<1));\n#elif 0\n    unsigned i;\n    for (i=0; i<count; ++i) dst[i] = src[i];\n#else\n    unsigned i;\n    count >>= 1;\n    for (i=0; i<count; ++i)\n\t((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i];\n#endif\n}\n\n\n/**\n * This is a general purpose function to copy samples from/to buffers with\n * equal size. Since this function is needed by many parts of the library,\n * by putting this functionality in one place, it enables some.\n * clever people to optimize this function.\n */\nPJ_INLINE(void) pjmedia_move_samples(pj_int16_t *dst, const pj_int16_t *src,\n\t\t\t\t     unsigned count)\n{\n#if 1\n    pj_memmove(dst, src, (count<<1));\n#elif 0\n    unsigned i;\n    for (i=0; i<count; ++i) dst[i] = src[i];\n#else\n    unsigned i;\n    count >>= 1;\n    for (i=0; i<count; ++i)\n\t((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i];\n#endif\n}\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif /* __PJMEDIA_FRAME_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/g711.h",
    "content": "/* $Id: g711.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_G711_H__\n#define __PJMEDIA_G711_H__\n\n/**\n * @file g711.h\n * @brief G711 Codec\n */\n\n#include <pjmedia-codec/types.h>\n\n/**\n * @defgroup PJMED_G711 G.711 Codec\n * @ingroup PJMEDIA_CODEC_CODECS\n * @brief Standard G.711/PCMA and PCMU codec.\n * @{\n *\n * This section describes functions to initialize and register G.711 codec\n * factory to the codec manager. After the codec factory has been registered,\n * application can use @ref PJMEDIA_CODEC API to manipulate the codec.\n *\n * The G.711 is an ultra low complexity codecs and in trade-off it results\n * in high bitrate, i.e: 64kbps for 16-bit PCM with sampling rate 8000Hz.\n *\n * The factory contains two main compression algorithms, PCMU/u-Law and \n * PCMA/A-Law.\n *\n * \\section codec_setting Codec Settings\n *\n * \\subsection general_setting General Settings\n *\n * General codec settings for this codec such as VAD and PLC can be \n * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param. \n * Please see the documentation of #pjmedia_codec_param for more info.\n *\n * \\subsection specific_setting Codec Specific Settings\n *\n * Currently none.\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Initialize and register G711 codec factory to pjmedia endpoint.\n * This will register PCMU and PCMA codec, in that order.\n *\n * @param endpt\t\tThe pjmedia endpoint.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_g711_init(pjmedia_endpt *endpt);\n\n\n\n/**\n * Unregister G711 codec factory from pjmedia endpoint.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_g711_deinit(void);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_G711_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/jbuf.h",
    "content": "/* $Id: jbuf.h 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n/*\n * Based on implementation kindly contributed by Switchlab, Ltd.\n */\n#ifndef __PJMEDIA_JBUF_H__\n#define __PJMEDIA_JBUF_H__\n\n\n/**\n * @file jbuf.h\n * @brief Adaptive jitter buffer implementation.\n */\n#include <pjmedia/types.h>\n\n/**\n * @defgroup PJMED_JBUF Adaptive jitter buffer\n * @ingroup PJMEDIA_FRAME_OP\n * @brief Adaptive de-jitter buffering implementation\n * @{\n *\n * This section describes PJMEDIA's implementation of de-jitter buffer.\n * The de-jitter buffer may be set to operate in adaptive mode or fixed\n * delay mode.\n */\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * Types of frame returned by the jitter buffer.\n */\ntypedef enum pjmedia_jb_frame_type \n{\n    PJMEDIA_JB_MISSING_FRAME\t   = 0, /**< No frame because it's missing  */\n    PJMEDIA_JB_NORMAL_FRAME\t   = 1, /**< Normal frame is being returned */\n    PJMEDIA_JB_ZERO_PREFETCH_FRAME = 2, /**< Zero frame is being returned  \n\t\t\t\t\t     because JB is bufferring.\t    */\n    PJMEDIA_JB_ZERO_EMPTY_FRAME\t   = 3\t/**< Zero frame is being returned\n\t\t\t\t\t     because JB is empty.\t    */\n} pjmedia_jb_frame_type;\n\n\n/**\n * Enumeration of jitter buffer discard algorithm. The jitter buffer\n * continuously calculates the jitter level to get the optimum latency at\n * any time and in order to adjust the latency, the jitter buffer may need\n * to discard some frames.\n */\ntypedef enum pjmedia_jb_discard_algo\n{\n    /**\n     * Jitter buffer should not discard any frame, except when the jitter\n     * buffer is full and a new frame arrives, one frame will be discarded\n     * to make space for the new frame.\n     */\n    PJMEDIA_JB_DISCARD_NONE\t   = 0,\n\n    /**\n     * Only discard one frame in at least 200ms when the latency is considered\n     * much higher than it should be. When the jitter buffer is full and a new\n     * frame arrives, one frame will be discarded to make space for the new\n     * frame.\n     */\n    PJMEDIA_JB_DISCARD_STATIC,\n\n    /**\n     * The discard rate is dynamically calculated based on actual parameters\n     * such as jitter level and latency. When the jitter buffer is full and\n     * a new frame arrives, one frame will be discarded to make space for the\n     * new frame.\n     */\n    PJMEDIA_JB_DISCARD_PROGRESSIVE\n\n} pjmedia_jb_discard_algo;\n\n\n/**\n * This structure describes jitter buffer state.\n */\ntypedef struct pjmedia_jb_state\n{\n    /* Setting */\n    unsigned\tframe_size;\t    /**< Individual frame size, in bytes.   */\n    unsigned\tmin_prefetch;\t    /**< Minimum allowed prefetch, in frms. */\n    unsigned\tmax_prefetch;\t    /**< Maximum allowed prefetch, in frms. */\n\n    /* Status */\n    unsigned\tburst;\t\t    /**< Current burst level, in frames\t    */\n    unsigned\tprefetch;\t    /**< Current prefetch value, in frames  */\n    unsigned\tsize;\t\t    /**< Current buffer size, in frames.    */\n\n    /* Statistic */\n    unsigned\tavg_delay;\t    /**< Average delay, in ms.\t\t    */\n    unsigned\tmin_delay;\t    /**< Minimum delay, in ms.\t\t    */\n    unsigned\tmax_delay;\t    /**< Maximum delay, in ms.\t\t    */\n    unsigned\tdev_delay;\t    /**< Standard deviation of delay, in ms.*/\n    unsigned\tavg_burst;\t    /**< Average burst, in frames.\t    */\n    unsigned\tlost;\t\t    /**< Number of lost frames.\t\t    */\n    unsigned\tdiscard;\t    /**< Number of discarded frames.\t    */\n    unsigned\tempty;\t\t    /**< Number of empty on GET events.\t    */\n} pjmedia_jb_state;\n\n\n/**\n * The constant PJMEDIA_JB_DEFAULT_INIT_DELAY specifies default jitter\n * buffer prefetch count during jitter buffer creation.\n */\n#define PJMEDIA_JB_DEFAULT_INIT_DELAY    15\n\n/**\n * Opaque declaration for jitter buffer.\n */\ntypedef struct pjmedia_jbuf pjmedia_jbuf;\n\n\n/**\n * Create an adaptive jitter buffer according to the specification. If\n * application wants to have a fixed jitter buffer, it may call\n * #pjmedia_jbuf_set_fixed() after the jitter buffer is created. Also\n * if application wants to alter the discard algorithm, which the default\n * PJMEDIA_JB_DISCARD_PROGRESSIVE, it may call #pjmedia_jbuf_set_discard().\n *\n * This function may allocate large chunk of memory to keep the frames in \n * the buffer.\n *\n * @param pool\t\tThe pool to allocate memory.\n * @param name\t\tName to identify the jitter buffer for logging\n *\t\t\tpurpose.\n * @param frame_size\tThe size of each frame that will be kept in the\n *\t\t\tjitter buffer, in bytes. This should correspond\n *\t\t\tto the minimum frame size supported by the codec.\n *\t\t\tFor example, a 10ms frame (80 bytes) would be \n *\t\t\trecommended for G.711 codec.\n * @param max_count\tMaximum number of frames that can be kept in the\n *\t\t\tjitter buffer. This effectively means the maximum\n *\t\t\tdelay that may be introduced by this jitter \n *\t\t\tbuffer.\n * @param ptime\t\tIndication of frame duration, used to calculate \n *\t\t\tthe interval between jitter recalculation.\n * @param p_jb\t\tPointer to receive jitter buffer instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_jbuf_create(pj_pool_t *pool,\n\t\t\t\t\t const pj_str_t *name,\n\t\t\t\t\t unsigned frame_size,\n\t\t\t\t\t unsigned ptime,\n\t\t\t\t\t unsigned max_count,\n\t\t\t\t\t pjmedia_jbuf **p_jb);\n\n/**\n * Set the jitter buffer to fixed delay mode. The default behavior\n * is to adapt the delay with actual packet delay.\n *\n * @param jb\t\tThe jitter buffer\n * @param prefetch\tThe fixed delay value, in number of frames.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_jbuf_set_fixed( pjmedia_jbuf *jb,\n\t\t\t\t\t     unsigned prefetch);\n\n\n/**\n * Set the jitter buffer to adaptive mode.\n *\n * @param jb\t\tThe jitter buffer.\n * @param prefetch\tThe initial prefetch value to be applied to the\n *\t\t\tjitter buffer. Setting this to other than 0 will\n *\t\t\tactivate prefetch buffering, a jitter buffer feature\n *\t\t\tthat each time it gets empty, it won't return a \n *\t\t\tnormal frame until its size reaches the number\n *\t\t\tspecified here.\n * @param min_prefetch\tThe minimum delay that must be applied to each\n *\t\t\tincoming packets, in number of frames.\n * @param max_prefetch\tThe maximum allowable value for prefetch delay,\n *\t\t\tin number of frames.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_jbuf_set_adaptive( pjmedia_jbuf *jb,\n\t\t\t\t\t        unsigned prefetch,\n\t\t\t\t\t        unsigned min_prefetch,\n\t\t\t\t\t\tunsigned max_prefetch);\n\n\n/**\n * Set the jitter buffer discard algorithm. The default discard algorithm,\n * set in jitter buffer creation, is PJMEDIA_JB_DISCARD_PROGRESSIVE.\n *\n * @param jb\t\tThe jitter buffer.\n * @param algo\t\tThe discard algorithm to be used.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_jbuf_set_discard(pjmedia_jbuf *jb,\n\t\t\t\t\t      pjmedia_jb_discard_algo algo);\n\n\n/**\n * Destroy jitter buffer instance.\n *\n * @param jb\t\tThe jitter buffer.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_jbuf_destroy(pjmedia_jbuf *jb);\n\n\n/**\n * Restart jitter. This function flushes all packets in the buffer and\n * reset the internal sequence number.\n *\n * @param jb\t\tThe jitter buffer.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_jbuf_reset(pjmedia_jbuf *jb);\n\n/**\n * Put a frame to the jitter buffer. If the frame can be accepted (based\n * on the sequence number), the jitter buffer will copy the frame and put\n * it in the appropriate position in the buffer.\n *\n * Application MUST manage it's own synchronization when multiple threads\n * are accessing the jitter buffer at the same time.\n *\n * @param jb\t\tThe jitter buffer.\n * @param frame\t\tPointer to frame buffer to be stored in the jitter\n *\t\t\tbuffer.\n * @param size\t\tThe frame size.\n * @param frame_seq\tThe frame sequence number.\n */\nPJ_DECL(void) pjmedia_jbuf_put_frame( pjmedia_jbuf *jb, \n\t\t\t\t      const void *frame, \n\t\t\t\t      pj_size_t size, \n\t\t\t\t      int frame_seq);\n\n/**\n * Put a frame to the jitter buffer. If the frame can be accepted (based\n * on the sequence number), the jitter buffer will copy the frame and put\n * it in the appropriate position in the buffer.\n *\n * Application MUST manage it's own synchronization when multiple threads\n * are accessing the jitter buffer at the same time.\n *\n * @param jb\t\tThe jitter buffer.\n * @param frame\t\tPointer to frame buffer to be stored in the jitter\n *\t\t\tbuffer.\n * @param size\t\tThe frame size.\n * @param bit_info\tBit precise info of the frame, e.g: a frame may not \n *\t\t\texactly start and end at the octet boundary, so this\n *\t\t\tfield may be used for specifying start & end bit offset.\n * @param frame_seq\tThe frame sequence number.\n * @param discarded\tFlag whether the frame is discarded by jitter buffer.\n */\nPJ_DECL(void) pjmedia_jbuf_put_frame2( pjmedia_jbuf *jb, \n\t\t\t\t       const void *frame, \n\t\t\t\t       pj_size_t size, \n\t\t\t\t       pj_uint32_t bit_info,\n\t\t\t\t       int frame_seq,\n\t\t\t\t       pj_bool_t *discarded);\n\n/**\n * Put a frame to the jitter buffer. If the frame can be accepted (based\n * on the sequence number), the jitter buffer will copy the frame and put\n * it in the appropriate position in the buffer.\n *\n * Application MUST manage it's own synchronization when multiple threads\n * are accessing the jitter buffer at the same time.\n *\n * @param jb\t\tThe jitter buffer.\n * @param frame\t\tPointer to frame buffer to be stored in the jitter\n *\t\t\tbuffer.\n * @param size\t\tThe frame size.\n * @param bit_info\tBit precise info of the frame, e.g: a frame may not \n *\t\t\texactly start and end at the octet boundary, so this\n *\t\t\tfield may be used for specifying start & end bit offset.\n * @param frame_seq\tThe frame sequence number.\n * @param frame_ts\tThe frame timestamp.\n * @param discarded\tFlag whether the frame is discarded by jitter buffer.\n */\nPJ_DECL(void) pjmedia_jbuf_put_frame3( pjmedia_jbuf *jb, \n\t\t\t\t       const void *frame, \n\t\t\t\t       pj_size_t size, \n\t\t\t\t       pj_uint32_t bit_info,\n\t\t\t\t       int frame_seq,\n\t\t\t\t       pj_uint32_t frame_ts,\n\t\t\t\t       pj_bool_t *discarded);\n/**\n * Get a frame from the jitter buffer. The jitter buffer will return the\n * oldest frame from it's buffer, when it is available.\n *\n * Application MUST manage it's own synchronization when multiple threads\n * are accessing the jitter buffer at the same time.\n *\n * @param jb\t\tThe jitter buffer.\n * @param frame\t\tBuffer to receive the payload from the jitter buffer.\n *\t\t\tApplication MUST make sure that the buffer has\n *\t\t\tappropriate size (i.e. not less than the frame size,\n *\t\t\tas specified when the jitter buffer was created).\n *\t\t\tThe jitter buffer only copied a frame to this \n *\t\t\tbuffer when the frame type returned by this function\n *\t\t\tis PJMEDIA_JB_NORMAL_FRAME.\n * @param p_frm_type\tPointer to receive frame type. If jitter buffer is\n *\t\t\tcurrently empty or bufferring, the frame type will\n *\t\t\tbe set to PJMEDIA_JB_ZERO_FRAME, and no frame will\n *\t\t\tbe copied. If the jitter buffer detects that frame is\n *\t\t\tmissing with current sequence number, the frame type\n *\t\t\twill be set to PJMEDIA_JB_MISSING_FRAME, and no\n *\t\t\tframe will be copied. If there is a frame, the jitter\n *\t\t\tbuffer will copy the frame to the buffer, and frame\n *\t\t\ttype will be set to PJMEDIA_JB_NORMAL_FRAME.\n */\nPJ_DECL(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb, \n\t\t\t\t      void *frame, \n\t\t\t\t      char *p_frm_type);\n\n/**\n * Get a frame from the jitter buffer. The jitter buffer will return the\n * oldest frame from it's buffer, when it is available.\n *\n * @param jb\t\tThe jitter buffer.\n * @param frame\t\tBuffer to receive the payload from the jitter buffer.\n *\t\t\t@see pjmedia_jbuf_get_frame().    \n * @param size\t\tPointer to receive frame size.\n * @param p_frm_type\tPointer to receive frame type.\n *\t\t\t@see pjmedia_jbuf_get_frame().    \n * @param bit_info\tBit precise info of the frame, e.g: a frame may not \n *\t\t\texactly start and end at the octet boundary, so this\n *\t\t\tfield may be used for specifying start & end bit offset.\n */\nPJ_DECL(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb, \n\t\t\t\t      void *frame, \n\t\t\t\t      pj_size_t *size, \n\t\t\t\t      char *p_frm_type,\n\t\t\t\t      pj_uint32_t *bit_info);\n\n\n/**\n * Get a frame from the jitter buffer. The jitter buffer will return the\n * oldest frame from it's buffer, when it is available.\n *\n * @param jb\t\tThe jitter buffer.\n * @param frame\t\tBuffer to receive the payload from the jitter buffer.\n *\t\t\t@see pjmedia_jbuf_get_frame().    \n * @param size\t\tPointer to receive frame size.\n * @param p_frm_type\tPointer to receive frame type.\n *\t\t\t@see pjmedia_jbuf_get_frame().    \n * @param bit_info\tBit precise info of the frame, e.g: a frame may not \n *\t\t\texactly start and end at the octet boundary, so this\n *\t\t\tfield may be used for specifying start & end bit offset.\n * @param ts\t\tFrame timestamp.\n * @param seq\t\tFrame sequence number.\n */\nPJ_DECL(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb, \n\t\t\t\t      void *frame, \n\t\t\t\t      pj_size_t *size, \n\t\t\t\t      char *p_frm_type,\n\t\t\t\t      pj_uint32_t *bit_info,\n\t\t\t\t      pj_uint32_t *ts,\n\t\t\t\t      int *seq);\n\n\n/**\n * Peek a frame from the jitter buffer. The jitter buffer state will not be\n * modified.\n *\n * @param jb\t\tThe jitter buffer.\n * @param offset\tOffset from the oldest frame to be peeked.\n * @param frame\t\tBuffer to receive the payload from the jitter buffer.\n *\t\t\t@see pjmedia_jbuf_get_frame().    \n * @param size\t\tPointer to receive frame size.\n * @param p_frm_type\tPointer to receive frame type.\n *\t\t\t@see pjmedia_jbuf_get_frame().    \n * @param bit_info\tBit precise info of the frame, e.g: a frame may not \n *\t\t\texactly start and end at the octet boundary, so this\n *\t\t\tfield may be used for specifying start & end bit offset.\n * @param ts\t\tFrame timestamp.\n * @param seq\t\tFrame sequence number.\n */\nPJ_DECL(void) pjmedia_jbuf_peek_frame(pjmedia_jbuf *jb,\n\t\t\t\t      unsigned offset,\n\t\t\t\t      const void **frame, \n\t\t\t\t      pj_size_t *size, \n\t\t\t\t      char *p_frm_type,\n\t\t\t\t      pj_uint32_t *bit_info,\n\t\t\t\t      pj_uint32_t *ts,\n\t\t\t\t      int *seq);\n\n\n/**\n * Remove frames from the jitter buffer.\n *\n * @param jb\t\tThe jitter buffer.\n * @param frame_cnt\tNumber of frames to be removed.\n *\n * @return\t\tThe number of frame successfully removed.\n */\nPJ_DECL(unsigned) pjmedia_jbuf_remove_frame(pjmedia_jbuf *jb, \n\t\t\t\t\t    unsigned frame_cnt);\n\n/**\n * Check if the jitter buffer is full.\n *\n * @param jb\t\tThe jitter buffer.\n *\n * @return\t\tPJ_TRUE if it is full.\n */\nPJ_DECL(pj_bool_t) pjmedia_jbuf_is_full(const pjmedia_jbuf *jb);\n\n\n/**\n * Get jitter buffer current state/settings.\n *\n * @param jb\t\tThe jitter buffer.\n * @param state\t\tBuffer to receive jitter buffer state.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_jbuf_get_state( const pjmedia_jbuf *jb,\n\t\t\t\t\t     pjmedia_jb_state *state );\n\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_JBUF_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/master_port.h",
    "content": "/* $Id: master_port.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_MASTER_PORT_H__\n#define __PJMEDIA_MASTER_PORT_H__\n\n\n/**\n * @file master_port.h\n * @brief Master port.\n */\n#include <pjmedia/port.h>\n\n/**\n * @defgroup PJMEDIA_MASTER_PORT Master Port\n * @ingroup PJMEDIA_PORT_CLOCK\n * @brief Thread based media clock provider\n * @{\n *\n * A master port has two media ports connected to it, and by convention\n * thay are called downstream and upstream ports. The media stream flowing to\n * the downstream port is called encoding or send direction, and media stream \n * flowing to the upstream port is called decoding or receive direction\n * (imagine the downstream as stream to remote endpoint, and upstream as\n * local media port; media flowing to remote endpoint (downstream) will need\n * to be encoded before it is transmitted to remote endpoint).\n *\n * A master port internally has an instance of @ref PJMEDIA_CLOCK, which\n * provides the essensial timing for the master port. The @ref PJMEDIA_CLOCK\n * runs asynchronously, and whenever a clock <b>tick</b> expires, a callback\n * will be called, and the master port performs the following tasks:\n *  - it calls <b><tt>get_frame()</tt></b> from the downstream port,\n *    when give the frame to the upstream port by calling <b><tt>put_frame\n *    </tt></b> to the upstream port, and\n *  - performs the same task, but on the reverse direction (i.e. get the stream\n *    from upstream port and give it to the downstream port).\n *\n * Because master port enables media stream to flow automatically, it is\n * said that the master port supplies @ref PJMEDIA_PORT_CLOCK to the \n * media ports interconnection.\n *\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Opaque declaration for master port.\n */\ntypedef struct pjmedia_master_port pjmedia_master_port;\n\n\n/**\n * Create a master port.\n *\n * @param pool\t\tPool to allocate master port from.\n * @param u_port\tUpstream port.\n * @param d_port\tDownstream port.\n * @param options\tOptions flags, from bitmask combinations from\n *\t\t\tpjmedia_clock_options.\n * @param p_m\t\tPointer to receive the master port instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_master_port_create(pj_pool_t *pool,\n\t\t\t\t\t\tpjmedia_port *u_port,\n\t\t\t\t\t\tpjmedia_port *d_port,\n\t\t\t\t\t\tunsigned options,\n\t\t\t\t\t\tpjmedia_master_port **p_m);\n\n\n/**\n * Start the media flow.\n *\n * @param m\t\tThe master port.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_master_port_start(pjmedia_master_port *m);\n\n\n/**\n * Stop the media flow.\n *\n * @param m\t\tThe master port.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_master_port_stop(pjmedia_master_port *m);\n\n\n/**\n * Poll the master port clock and execute the callback when the clock tick has\n * elapsed. This operation is only valid if the master port is created with\n * #PJMEDIA_CLOCK_NO_ASYNC flag.\n *\n * @param m\t\t    The master port.\n * @param wait\t\t    If non-zero, then the function will block until\n *\t\t\t    a clock tick elapsed and callback has been called.\n * @param ts\t\t    Optional argument to receive the current \n *\t\t\t    timestamp.\n *\n * @return\t\t    Non-zero if clock tick has elapsed, or FALSE if\n *\t\t\t    the function returns before a clock tick has\n *\t\t\t    elapsed.\n */\nPJ_DECL(pj_bool_t) pjmedia_master_port_wait(pjmedia_master_port *m,\n\t\t\t\t\t    pj_bool_t wait,\n\t\t\t\t\t    pj_timestamp *ts);\n\n\n/**\n * Change the upstream port. Note that application is responsible to destroy\n * current upstream port (the one that is going to be replaced with the\n * new port).\n *\n * @param m\t\tThe master port.\n * @param port\t\tPort to be used for upstream port.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_master_port_set_uport(pjmedia_master_port *m,\n\t\t\t\t\t\t   pjmedia_port *port);\n\n\n/**\n * Get the upstream port.\n *\n * @param m\t\tThe master port.\n *\n * @return\t\tThe upstream port.\n */\nPJ_DECL(pjmedia_port*) pjmedia_master_port_get_uport(pjmedia_master_port*m);\n\n\n/**\n * Change the downstream port. Note that application is responsible to destroy\n * current downstream port (the one that is going to be replaced with the\n * new port).\n *\n * @param m\t\tThe master port.\n * @param port\t\tPort to be used for downstream port.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_master_port_set_dport(pjmedia_master_port *m,\n\t\t\t\t\t\t   pjmedia_port *port);\n\n\n/**\n * Get the downstream port.\n *\n * @param m\t\tThe master port.\n *\n * @return\t\tThe downstream port.\n */\nPJ_DECL(pjmedia_port*) pjmedia_master_port_get_dport(pjmedia_master_port*m);\n\n\n/**\n * Destroy the master port, and optionally destroy the upstream and \n * downstream ports.\n *\n * @param m\t\tThe master port.\n * @param destroy_ports\tIf non-zero, the function will destroy both\n *\t\t\tupstream and downstream ports too.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_master_port_destroy(pjmedia_master_port *m,\n\t\t\t\t\t\t pj_bool_t destroy_ports);\n\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_MASTER_PORT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/mem_port.h",
    "content": "/* $Id: mem_port.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_MEM_PORT_H__\n#define __PJMEDIA_MEM_PORT_H__\n\n/**\n * @file mem_port.h\n * @brief Memory based media playback/capture port\n */\n#include <pjmedia/port.h>\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJMEDIA_MEM_PLAYER Memory/Buffer-based Playback Port\n * @ingroup PJMEDIA_PORT\n * @brief Media playback from a fixed size memory buffer\n * @{\n *\n * A memory/buffer based playback port is used to play media from a fixed\n * size buffer. This is useful over @ref PJMEDIA_FILE_PLAY for \n * situation where filesystems are not available in the target system.\n */\n\n\n/**\n * Memory player options.\n */\nenum pjmedia_mem_player_option\n{\n    /**\n     * Tell the memory player to return NULL frame when the whole\n     * buffer has been played instead of rewinding the buffer back\n     * to start position.\n     */\n    PJMEDIA_MEM_NO_LOOP = 1\n};\n\n\n/**\n * Create the buffer based playback to play the media from the specified\n * buffer.\n *\n * @param pool\t\t    Pool to allocate memory for the port structure.\n * @param buffer\t    The buffer to play the media from, which should\n *\t\t\t    be available throughout the life time of the port.\n *\t\t\t    The player plays the media directly from this\n *\t\t\t    buffer (i.e. no copying is done).\n * @param size\t\t    The size of the buffer, in bytes.\n * @param clock_rate\t    Sampling rate.\n * @param channel_count\t    Number of channels.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Number of bits per sample.\n * @param options\t    Option flags, see #pjmedia_mem_player_option\n * @param p_port\t    Pointer to receive the port instance.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate\n *\t\t\t    error code.\n */\nPJ_DECL(pj_status_t) pjmedia_mem_player_create(pj_pool_t *pool,\n\t\t\t\t\t       const void *buffer,\n\t\t\t\t\t       pj_size_t size,\n\t\t\t\t\t       unsigned clock_rate,\n\t\t\t\t\t       unsigned channel_count,\n\t\t\t\t\t       unsigned samples_per_frame,\n\t\t\t\t\t       unsigned bits_per_sample,\n\t\t\t\t\t       unsigned options,\n\t\t\t\t\t       pjmedia_port **p_port );\n\n\n/**\n * Register a callback to be called when the buffer reading has reached the\n * end of buffer. If the player is set to play repeatedly, then the callback\n * will be called multiple times. Note that only one callback can be \n * registered for each player port.\n *\n * @param port\t\tThe memory player port.\n * @param user_data\tUser data to be specified in the callback\n * @param cb\t\tCallback to be called. If the callback returns non-\n *\t\t\tPJ_SUCCESS, the playback will stop. Note that if\n *\t\t\tapplication destroys the player port in the callback,\n *\t\t\tit must return non-PJ_SUCCESS here.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_mem_player_set_eof_cb( pjmedia_port *port,\n\t\t\t       void *user_data,\n\t\t\t       pj_status_t (*cb)(pjmedia_port *port,\n\t\t\t\t\t\t void *usr_data));\n\n\n/**\n * @}\n */\n\n/**\n * @defgroup PJMEDIA_MEM_CAPTURE Memory/Buffer-based Capture Port\n * @ingroup PJMEDIA_PORT\n * @brief Media capture to fixed size memory buffer\n * @{\n *\n * A memory based capture is used to save media streams to a fixed size\n * buffer. This is useful over @ref PJMEDIA_FILE_REC for \n * situation where filesystems are not available in the target system.\n */\n\n/**\n * Create media port to capture/record media into a fixed size buffer.\n *\n * @param pool\t\t    Pool to allocate memory for the port structure.\n * @param buffer\t    The buffer to record the media to, which should\n *\t\t\t    be available throughout the life time of the port.\n * @param size\t\t    The maximum size of the buffer, in bytes.\n * @param clock_rate\t    Sampling rate.\n * @param channel_count\t    Number of channels.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Number of bits per sample.\n * @param options\t    Option flags.\n * @param p_port\t    Pointer to receive the port instance.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate\n *\t\t\t    error code.\n */\nPJ_DECL(pj_status_t) pjmedia_mem_capture_create(pj_pool_t *pool,\n\t\t\t\t\t\tvoid *buffer,\n\t\t\t\t\t\tpj_size_t size,\n\t\t\t\t\t\tunsigned clock_rate,\n\t\t\t\t\t\tunsigned channel_count,\n\t\t\t\t\t\tunsigned samples_per_frame,\n\t\t\t\t\t\tunsigned bits_per_sample,\n\t\t\t\t\t\tunsigned options,\n\t\t\t\t\t\tpjmedia_port **p_port);\n\n\n/**\n * Register a callback to be called when no space left in the buffer.\n * Note that when a callback is registered, this callback will also be\n * called when application destroys the port and the callback has not \n * been called before.\n *\n * @param port\t\tThe memory recorder port.\n * @param user_data\tUser data to be specified in the callback\n * @param cb\t\tCallback to be called. If the callback returns non-\n *\t\t\tPJ_SUCCESS, the recording will stop. In other cases\n *                      recording will be restarted and the rest of the frame\n *                      will be stored starting from the beginning of the \n *\t\t\tbuffer. Note that if application destroys the capture\n *\t\t\tport in the callback, it must return non-PJ_SUCCESS \n *\t\t\there.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t)\npjmedia_mem_capture_set_eof_cb(pjmedia_port *port,\n                               void *user_data,\n                               pj_status_t (*cb)(pjmedia_port *port,\n\t\t\t\t\t\t void *usr_data));\n\n/**\n * Return the current size of the recorded data in the buffer.\n *\n * @param port\t\tThe memory recorder port.\n * @return\t\tThe size of buffer data..\n */\nPJ_DECL(pj_size_t)\npjmedia_mem_capture_get_size(pjmedia_port *port);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_MEM_PORT_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/mixer_port.h",
    "content": "/* \n * Copyright (C) 2010 AG Projects\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#ifndef __PJMEDIA_MIXER_PORT_H__\n#define __PJMEDIA_MIXER_PORT_H__\n\n/**\n * @file mixer_port.h\n * @brief Mixer media port.\n */\n#include <pjmedia/port.h>\n\n\n\n/**\n * @defgroup PJMEDIA_MIXER_PORT Mixer Port\n * @ingroup PJMEDIA_PORT\n * @brief The second simplest type of media port which forwards the frames it\n *        gets unchanged.\n * @{\n */\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * Create Mixer port.\n *\n * @param pool              Pool to allocate memory.\n * @param sampling_rate     Sampling rate of the port.\n * @param channel_count     Number of channels.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Number of bits per sample.\n * @param p_port            Pointer to receive the port instance.\n *\n * @return                  PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_mixer_port_create(pj_pool_t *pool,\n                                               unsigned sampling_rate,\n                                               unsigned channel_count,\n                                               unsigned samples_per_frame,\n                                               unsigned bits_per_sample,\n                                               pjmedia_port **p_port);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_MIXER_PORT_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/null_port.h",
    "content": "/* $Id: null_port.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_NULL_PORT_H__\n#define __PJMEDIA_NULL_PORT_H__\n\n/**\n * @file null_port.h\n * @brief Null media port.\n */\n#include <pjmedia/port.h>\n\n\n\n/**\n * @defgroup PJMEDIA_NULL_PORT Null Port\n * @ingroup PJMEDIA_PORT\n * @brief The simplest type of media port which does nothing.\n * @{\n */\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * Create Null port. \n *\n * @param pool\t\t\tPool to allocate memory.\n * @param sampling_rate\t\tSampling rate of the port.\n * @param channel_count\t\tNumber of channels.\n * @param samples_per_frame\tNumber of samples per frame.\n * @param bits_per_sample\tNumber of bits per sample.\n * @param p_port\t\tPointer to receive the port instance.\n *\n * @return\t\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_null_port_create( pj_pool_t *pool,\n\t\t\t\t\t       unsigned sampling_rate,\n\t\t\t\t\t       unsigned channel_count,\n\t\t\t\t\t       unsigned samples_per_frame,\n\t\t\t\t\t       unsigned bits_per_sample,\n\t\t\t\t\t       pjmedia_port **p_port );\n\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_NULL_PORT_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/plc.h",
    "content": "/* $Id: plc.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_PLC_H__\n#define __PJMEDIA_PLC_H__\n\n\n/**\n * @file plc.h\n * @brief Packet Lost Concealment (PLC) API.\n */\n#include <pjmedia/types.h>\n\n/**\n * @defgroup PJMED_PLC Packet Lost Concealment (PLC)\n * @ingroup PJMEDIA_FRAME_OP\n * @brief Packet lost compensation algorithm\n * @{\n *\n * This section describes PJMEDIA's implementation of Packet Lost\n * Concealment algorithm. This algorithm is used to implement PLC for\n * codecs that do not have built-in support for one (e.g. G.711 or GSM \n * codecs).\n *\n * The PLC algorithm (either built-in or external) is embedded in\n * PJMEDIA codec instance, and application can conceal lost frames\n * by calling <b><tt>recover()</tt></b> member of the codec's member\n * operation (#pjmedia_codec_op).\n *\n * See also @ref plc_codec for more info.\n */\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * Opaque declaration for PLC.\n */\ntypedef struct pjmedia_plc pjmedia_plc;\n\n\n\n/**\n * Create PLC session. This function will select the PLC algorithm to\n * use based on the arguments.\n *\n * @param pool\t\t    Pool to allocate memory for the PLC.\n * @param clock_rate\t    Media sampling rate.\n * @param samples_per_frame Number of samples per frame.\n * @param options\t    Must be zero for now.\n * @param p_plc\t\t    Pointer to receive the PLC instance.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_plc_create( pj_pool_t *pool,\n\t\t\t\t\t unsigned clock_rate,\n\t\t\t\t\t unsigned samples_per_frame,\n\t\t\t\t\t unsigned options,\n\t\t\t\t\t pjmedia_plc **p_plc);\n\n\n/**\n * Save a good frame to PLC.\n *\n * @param plc\t\t    The PLC session.\n * @param frame\t\t    The good frame to be stored to PLC. This frame\n *\t\t\t    must have the same length as the configured\n *\t\t\t    samples per frame.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_plc_save( pjmedia_plc *plc,\n\t\t\t\t       pj_int16_t *frame );\n\n\n/**\n * Generate a replacement for lost frame.\n *\n * @param plc\t\t    The PLC session.\n * @param frame\t\t    Buffer to receive the generated frame. This buffer\n *\t\t\t    must be able to store the frame.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_plc_generate( pjmedia_plc *plc,\n\t\t\t\t\t   pj_int16_t *frame );\n\n\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_PLC_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/port.h",
    "content": "/* $Id: port.h 3893 2011-12-01 10:49:07Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_PORT_H__\n#define __PJMEDIA_PORT_H__\n\n/**\n * @file port.h\n * @brief Port interface declaration\n */\n#include <pjmedia/clock.h>\n#include <pjmedia/event.h>\n#include <pjmedia/format.h>\n#include <pjmedia/frame.h>\n#include <pjmedia/signatures.h>\n#include <pj/assert.h>\n#include <pj/os.h>\n\n\n/**\n  @addtogroup PJMEDIA_PORT Media Ports Framework\n  @{\n\n  @section media_port_intro Media Port Concepts\n  \n  @subsection The Media Port\n  A media port (represented with pjmedia_port \"class\") provides a generic\n  and extensible framework for implementing media elements. Media element\n  itself could be a media source, sink, or processing element. A media\n  port interface basically has the following properties:\n  - media port information (pjmedia_port_info) to describe the\n  media port properties (sampling rate, number of channels, etc.),\n  - optional pointer to function to acquire frames from the port (the\n    <tt>get_frame() </tt> interface), which will be called by\n    #pjmedia_port_get_frame() public API, and\n  - optional pointer to function to store frames to the port (the\n    <tt>put_frame()</tt> interface) which will be called by\n    #pjmedia_port_put_frame() public API.\n\n  The <tt>get_frame()</tt> and <tt>put_frame()</tt> interface of course\n  would only need to be implemented if the media port emits and/or takes\n  media frames respectively.\n  \n  Media ports are passive \"objects\". By default, there is no worker thread\n  to run the media flow. Applications (or other PJMEDIA\n  components, as explained in @ref PJMEDIA_PORT_CLOCK) must actively call\n  #pjmedia_port_get_frame() or #pjmedia_port_put_frame() from/to the media\n  port in order to retrieve/store media frames.\n  \n  Some media ports (such as @ref PJMEDIA_CONF and @ref PJMEDIA_RESAMPLE_PORT)\n  may be interconnected with (or encapsulate) other port, to perform the\n  combined task of the ports, while some\n  others represent the ultimate source/sink termination for the media. \n  Interconnection means the upstream media port will call <tt>get_frame()</tt>\n  and <tt>put_frame()</tt> to its downstream media port. For this to happen,\n  the media ports need to have the same format, where format is defined as\n  combination of sample format, clock rate, channel count, bits per sample,\n  and samples per frame for audio media.\n\n\n  @subsection port_clock_ex1 Example: Manual Resampling\n\n  For example, suppose application wants to convert the sampling rate\n  of one WAV file to another. In this case, application would create and\n  arrange media ports connection as follows:\n\n    \\image html sample-manual-resampling.jpg\n\n  Application would setup the media ports using the following pseudo-\n  code:\n\n  \\code\n  \n      pjmedia_port *player, *resample, *writer;\n      pj_status_t status;\n  \n      // Create the file player port.\n      status = pjmedia_wav_player_port_create(pool, \n  \t\t\t\t\t      \"Input.WAV\",\t    // file name\n  \t\t\t\t\t      20,\t\t    // ptime.\n  \t\t\t\t\t      PJMEDIA_FILE_NO_LOOP, // flags\n  \t\t\t\t\t      0,\t\t    // buffer size\n  \t\t\t\t\t      NULL,\t\t    // user data.\n  \t\t\t\t\t      &player );\n      PJ_ASSERT_RETURN(status==PJ_SUCCESS, PJ_SUCCESS);\n  \n      // Create the resample port with specifying the target sampling rate, \n      // and with the file port as the source. This will effectively\n      // connect the resample port with the player port.\n      status = pjmedia_resample_port_create( pool, player, 8000, \n  \t\t\t\t\t     0, &resample);\n      PJ_ASSERT_RETURN(status==PJ_SUCCESS, PJ_SUCCESS);\n  \n      // Create the file writer, specifying the resample port's configuration\n      // as the WAV parameters.\n      status pjmedia_wav_writer_port_create(pool, \n  \t\t\t\t\t    \"Output.WAV\",  // file name.\n  \t\t\t\t\t    resample->info.clock_rate,\n  \t\t\t\t\t    resample->info.channel_count,\n  \t\t\t\t\t    resample->info.samples_per_frame,\n  \t\t\t\t\t    resample->info.bits_per_sample,\n  \t\t\t\t\t    0,\t\t// flags\n  \t\t\t\t\t    0,\t\t// buffer size\n  \t\t\t\t\t    NULL,\t// user data.\n  \t\t\t\t\t    &writer);\n  \n  \\endcode\n\n  \n  After the ports have been set up, application can perform the conversion\n  process by running this loop:\n \n  \\code\n  \n  \tpj_int16_t samplebuf[MAX_FRAME];\n  \t\n  \twhile (1) {\n  \t    pjmedia_frame frame;\n  \t    pj_status_t status;\n  \n  \t    frame.buf = samplebuf;\n  \t    frame.size = sizeof(samplebuf);\n  \n  \t    // Get the frame from resample port.\n  \t    status = pjmedia_port_get_frame(resample, &frame);\n  \t    if (status != PJ_SUCCESS || frame.type == PJMEDIA_FRAME_TYPE_NONE) {\n  \t\t// End-of-file, end the conversion.\n  \t\tbreak;\n  \t    }\n  \n  \t    // Put the frame to write port.\n  \t    status = pjmedia_port_put_frame(writer, &frame);\n  \t    if (status != PJ_SUCCESS) {\n  \t\t// Error in writing the file.\n  \t\tbreak;\n  \t    }\n  \t}\n  \n  \\endcode\n \n  For the sake of completeness, after the resampling process is done, \n  application would need to destroy the ports:\n  \n  \\code\n\t// Note: by default, destroying resample port will destroy the\n\t//\t the downstream port too.\n  \tpjmedia_port_destroy(resample);\n  \tpjmedia_port_destroy(writer);\n  \\endcode\n \n \n  The above steps are okay for our simple purpose of changing file's sampling\n  rate. But for other purposes, the process of reading and writing frames\n  need to be done in timely manner (for example, sending RTP packets to\n  remote stream). And more over, as the application's scope goes bigger,\n  the same pattern of manually reading/writing frames comes up more and more often,\n  thus perhaps it would be better if PJMEDIA provides mechanism to \n  automate this process.\n  \n  And indeed PJMEDIA does provide such mechanism, which is described in \n  @ref PJMEDIA_PORT_CLOCK section.\n\n\n  @subsection media_port_autom Automating Media Flow\n\n  PJMEDIA provides few mechanisms to make media flows automatically\n  among media ports. This concept is described in @ref PJMEDIA_PORT_CLOCK \n  section.\n*/\n\nPJ_BEGIN_DECL\n\n\n/**\n * Create 32bit port signature from ASCII characters.\n */\n#define PJMEDIA_PORT_SIG(a,b,c,d)\t    \tPJMEDIA_OBJ_SIG(a,b,c,d)\n\n\n/**\n * Port operation setting.\n */\ntypedef enum pjmedia_port_op\n{\n    /** \n     * No change to the port TX or RX settings.\n     */\n    PJMEDIA_PORT_NO_CHANGE,\n\n    /**\n     * TX or RX is disabled from the port. It means get_frame() or\n     * put_frame() WILL NOT be called for this port.\n     */\n    PJMEDIA_PORT_DISABLE,\n\n    /**\n     * TX or RX is muted, which means that get_frame() or put_frame()\n     * will still be called, but the audio frame is discarded.\n     */\n    PJMEDIA_PORT_MUTE,\n\n    /**\n     * Enable TX and RX to/from this port.\n     */\n    PJMEDIA_PORT_ENABLE\n\n} pjmedia_port_op;\n\n\n/**\n * Port info.\n */\ntypedef struct pjmedia_port_info\n{\n    pj_str_t\t    name;\t\t/**< Port name.\t\t\t    */\n    pj_uint32_t\t    signature;\t\t/**< Port signature.\t\t    */\n    pjmedia_dir     dir;                /**< Port direction.                */\n    pjmedia_format  fmt;                /**< Format.\t\t            */\n} pjmedia_port_info;\n\n/**\n * Utility to retrieve audio clock rate/sampling rate value from\n * pjmedia_port_info.\n *\n * @param pia\t\tPointer to port info containing audio format.\n * @return\t\tAudio clock rate.\n */\nPJ_INLINE(unsigned) PJMEDIA_PIA_SRATE(const pjmedia_port_info *pia)\n{\n    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&\n\t      pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);\n    return pia->fmt.det.aud.clock_rate;\n}\n\n/**\n * Utility to retrieve audio channel count value from pjmedia_port_info.\n *\n * @param pia\t\tPointer to port info containing audio format.\n * @return\t\tAudio channel count.\n */\nPJ_INLINE(unsigned) PJMEDIA_PIA_CCNT(const pjmedia_port_info *pia)\n{\n    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&\n\t      pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);\n    return pia->fmt.det.aud.channel_count;\n}\n\n/**\n * Utility to retrieve audio bits per sample value from pjmedia_port_info.\n *\n * @param pia\t\tPointer to port info containing audio format.\n * @return\t\tNumber of bits per sample.\n */\nPJ_INLINE(unsigned) PJMEDIA_PIA_BITS(const pjmedia_port_info *pia)\n{\n    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&\n\t      pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);\n    return pia->fmt.det.aud.bits_per_sample;\n}\n\n/**\n * Utility to retrieve audio frame interval (ptime) value from\n * pjmedia_port_info.\n *\n * @param pia\t\tPointer to port info containing audio format.\n * @return\t\tFrame interval in msec.\n */\nPJ_INLINE(unsigned) PJMEDIA_PIA_PTIME(const pjmedia_port_info *pia)\n{\n    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&\n\t      pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);\n    return pia->fmt.det.aud.frame_time_usec / 1000;\n}\n\n/**\n * This is a utility routine to retrieve the audio samples_per_frame value\n * from port info.\n *\n * @param pia\t\tPointer to port info containing audio format.\n * @return\t\tSamples per frame value.\n */\nPJ_INLINE(unsigned) PJMEDIA_PIA_SPF(const pjmedia_port_info *pia)\n{\n    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&\n\t      pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);\n    return PJMEDIA_AFD_SPF(&pia->fmt.det.aud);\n}\n\n/**\n * This is a utility routine to retrieve the average bitrate value\n * from port info.\n *\n * @param pia\t\tPointer to port info containing audio format.\n * @return\t\tBitrate, in bits per second.\n */\nPJ_INLINE(unsigned) PJMEDIA_PIA_AVG_BPS(const pjmedia_port_info *pia)\n{\n    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&\n\t      pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);\n    return pia->fmt.det.aud.avg_bps;\n}\n\n/**\n * This is a utility routine to retrieve the maximum bitrate value\n * from port info.\n *\n * @param pia\t\tPointer to port info containing audio format.\n * @return\t\tBitrate, in bits per second.\n */\nPJ_INLINE(unsigned) PJMEDIA_PIA_MAX_BPS(const pjmedia_port_info *pia)\n{\n    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&\n\t      pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);\n    return pia->fmt.det.aud.max_bps;\n}\n\n/**\n * This is a utility routine to retrieve the average audio frame size value\n * from pjmedia_port_info.\n *\n * @param pia\t\tPointer to port info containing audio format.\n * @return\t\tFrame size in bytes.\n */\nPJ_INLINE(unsigned) PJMEDIA_PIA_AVG_FSZ(const pjmedia_port_info *pia)\n{\n    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&\n\t      pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);\n    return PJMEDIA_AFD_AVG_FSZ(&pia->fmt.det.aud);\n}\n\n/**\n * Utility to retrieve audio frame size from maximum bitrate from\n * pjmedia_port_info.\n *\n * @param pia\t\tPointer to port info containing audio format.\n * @return\t\tFrame size in bytes.\n */\nPJ_INLINE(unsigned) PJMEDIA_PIA_MAX_FSZ(const pjmedia_port_info *pia)\n{\n    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&\n\t      pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);\n    return PJMEDIA_AFD_MAX_FSZ(&pia->fmt.det.aud);\n}\n\n/**\n * Port interface.\n */\ntypedef struct pjmedia_port\n{\n    pjmedia_port_info\t info;\t\t    /**< Port information.  */\n\n    /** Port data can be used by the port creator to attach arbitrary\n     *  value to be associated with the port.\n     */\n    struct port_data {\n\tvoid\t\t*pdata;\t\t    /**< Pointer data.\t    */\n\tlong\t\t ldata;\t\t    /**< Long data.\t    */\n    } port_data;\n\n    /**\n     * Get clock source.\n     * This should only be called by #pjmedia_port_get_clock_src().\n     */\n    pjmedia_clock_src* (*get_clock_src)(struct pjmedia_port *this_port,\n                                        pjmedia_dir dir);\n\n    /**\n     * Sink interface. \n     * This should only be called by #pjmedia_port_put_frame().\n     */\n    pj_status_t (*put_frame)(struct pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame);\n\n    /**\n     * Source interface. \n     * This should only be called by #pjmedia_port_get_frame().\n     */\n    pj_status_t (*get_frame)(struct pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame);\n\n    /**\n     * Called to destroy this port.\n     */\n    pj_status_t (*on_destroy)(struct pjmedia_port *this_port);\n\n} pjmedia_port;\n\n\n/**\n * This is an auxiliary function to initialize port info for\n * ports which deal with PCM audio.\n *\n * @param info\t\t    The port info to be initialized.\n * @param name\t\t    Port name.\n * @param signature\t    Port signature.\n * @param clock_rate\t    Port's clock rate.\n * @param channel_count\t    Number of channels.\n * @param bits_per_sample   Bits per sample.\n * @param samples_per_frame Number of samples per frame.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_port_info_init( pjmedia_port_info *info,\n\t\t\t\t\t     const pj_str_t *name,\n\t\t\t\t\t     unsigned signature,\n\t\t\t\t\t     unsigned clock_rate,\n\t\t\t\t\t     unsigned channel_count,\n\t\t\t\t\t     unsigned bits_per_sample,\n\t\t\t\t\t     unsigned samples_per_frame);\n\n/**\n * This is an auxiliary function to initialize port info for\n * ports which deal with PCM audio.\n *\n * @param info\t\t    The port info to be initialized.\n * @param name\t\t    Port name.\n * @param signature\t    Port signature.\n * @param dir\t            Port's direction.\n * @param fmt\t            Port's media format.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_port_info_init2(pjmedia_port_info *info,\n\t\t\t\t\t     const pj_str_t *name,\n\t\t\t\t\t     unsigned signature,\n\t\t\t\t\t     pjmedia_dir dir,\n\t\t\t\t\t     const pjmedia_format *fmt);\n\n\n/**\n * Get a clock source from the port.\n *\n * @param port\t    The media port.\n * @param dir       Media port's direction.\n *\n * @return\t    The clock source or NULL if clock source is not present\n *                  in the port.\n */\nPJ_DECL(pjmedia_clock_src *) pjmedia_port_get_clock_src( pjmedia_port *port,\n                                                         pjmedia_dir dir );\n\n\n/**\n * Get a frame from the port (and subsequent downstream ports).\n *\n * @param port\t    The media port.\n * @param frame\t    Frame to store samples.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_port_get_frame( pjmedia_port *port,\n\t\t\t\t\t     pjmedia_frame *frame );\n\n/**\n * Put a frame to the port (and subsequent downstream ports).\n *\n * @param port\t    The media port.\n * @param frame\t    Frame to the put to the port.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_port_put_frame( pjmedia_port *port,\n\t\t\t\t\t     pjmedia_frame *frame );\n\n/**\n * Destroy port (and subsequent downstream ports)\n *\n * @param port\t    The media port.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_port_destroy( pjmedia_port *port );\n\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_PORT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/resample.h",
    "content": "/* $Id: resample.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_RESAMPLE_H__\n#define __PJMEDIA_RESAMPLE_H__\n\n\n\n/**\n * @file resample.h\n * @brief Sample rate converter.\n */\n#include <pjmedia/types.h>\n#include <pjmedia/port.h>\n\n/**\n * @defgroup PJMEDIA_RESAMPLE Resampling Algorithm\n * @ingroup PJMEDIA_FRAME_OP\n * @brief Sample rate conversion algorithm\n * @{\n *\n * This section describes the base resampling functions. In addition to this,\n * application can use the @ref PJMEDIA_RESAMPLE_PORT which provides\n * media port abstraction for the base resampling algorithm.\n */\n\nPJ_BEGIN_DECL\n\n/*\n * This file declares two types of API:\n *\n * Application can use #pjmedia_resample_create() and #pjmedia_resample_run()\n * to convert a frame from source rate to destination rate. The inpuit frame \n * must have a constant length.\n *\n * Alternatively, application can create a resampling port with\n * #pjmedia_resample_port_create() and connect the port to other ports to\n * change the sampling rate of the samples.\n */\n\n\n/**\n * Opaque resample session.\n */\ntypedef struct pjmedia_resample pjmedia_resample;\n\n/**\n * Create a frame based resample session.\n *\n * @param pool\t\t\tPool to allocate the structure and buffers.\n * @param high_quality\t\tIf true, then high quality conversion will be\n *\t\t\t\tused, at the expense of more CPU and memory,\n *\t\t\t\tbecause temporary buffer needs to be created.\n * @param large_filter\t\tIf true, large filter size will be used.\n * @param channel_count\t\tNumber of channels.\n * @param rate_in\t\tClock rate of the input samples.\n * @param rate_out\t\tClock rate of the output samples.\n * @param samples_per_frame\tNumber of samples per frame in the input.\n * @param p_resample\t\tPointer to receive the resample session.\n *\n * @return PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_resample_create(pj_pool_t *pool,\n\t\t\t\t\t     pj_bool_t high_quality,\n\t\t\t\t\t     pj_bool_t large_filter,\n\t\t\t\t\t     unsigned channel_count,\n\t\t\t\t\t     unsigned rate_in,\n\t\t\t\t\t     unsigned rate_out,\n\t\t\t\t\t     unsigned samples_per_frame,\n\t\t\t\t\t     pjmedia_resample **p_resample);\n\n\n/**\n * Use the resample session to resample a frame. The frame must have the\n * same size and settings as the resample session, or otherwise the\n * behavior is undefined.\n *\n * @param resample\t\tThe resample session.\n * @param input\t\t\tBuffer containing the input samples.\n * @param output\t\tBuffer to store the output samples.\n */\nPJ_DECL(void) pjmedia_resample_run( pjmedia_resample *resample,\n\t\t\t\t    const pj_int16_t *input,\n\t\t\t\t    pj_int16_t *output );\n\n\n/**\n * Get the input frame size of a resample session.\n *\n * @param resample\t\tThe resample session.\n *\n * @return\t\t\tThe frame size, in number of samples.\n */\nPJ_DECL(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample);\n\n\n/**\n * Destroy the resample.\n *\n * @param resample\t\tThe resample session.\n */\nPJ_DECL(void) pjmedia_resample_destroy(pjmedia_resample *resample);\n\n/**\n * @}\n */\n\n/**\n * @defgroup PJMEDIA_RESAMPLE_PORT Resample Port\n * @ingroup PJMEDIA_PORT\n * @brief Audio sample rate conversion\n * @{\n *\n * This section describes media port abstraction for @ref PJMEDIA_RESAMPLE.\n */\n\n\n/**\n * Option flags that can be specified when creating resample port.\n */\nenum pjmedia_resample_port_options\n{\n    /**\n     * Do not use high quality resampling algorithm, but use linear\n     * algorithm instead.\n     */\n    PJMEDIA_RESAMPLE_USE_LINEAR = 1,\n\n    /**\n     * Use small filter workspace when high quality resampling is\n     * used.\n     */\n    PJMEDIA_RESAMPLE_USE_SMALL_FILTER = 2,\n\n    /**\n     * Do not destroy downstream port when resample port is destroyed.\n     */\n    PJMEDIA_RESAMPLE_DONT_DESTROY_DN = 4\n};\n\n\n\n/**\n * Create a resample port. This creates a bidirectional resample session,\n * which will resample frames when the port's get_frame() and put_frame()\n * is called.\n *\n * When the resample port's get_frame() is called, this port will get\n * a frame from the downstream port and resample the frame to the target\n * clock rate before returning it to the caller.\n *\n * When the resample port's put_frame() is called, this port will resample\n * the frame to the downstream port's clock rate before giving the frame\n * to the downstream port.\n *\n * @param pool\t\t\tPool to allocate the structure and buffers.\n * @param dn_port\t\tThe downstream port, which clock rate is to\n *\t\t\t\tbe converted to the target clock rate.\n * @param clock_rate\t\tTarget clock rate.\n * @param options\t\tFlags from #pjmedia_resample_port_options.\n *\t\t\t\tWhen this flag is zero, the default behavior\n *\t\t\t\tis to use high quality resampling with\n *\t\t\t\tlarge filter, and to destroy downstream port\n *\t\t\t\twhen resample port is destroyed.\n * @param p_port\t\tPointer to receive the resample port instance.\n *\n * @return PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_resample_port_create( pj_pool_t *pool,\n\t\t\t\t\t\t   pjmedia_port *dn_port,\n\t\t\t\t\t\t   unsigned clock_rate,\n\t\t\t\t\t\t   unsigned options,\n\t\t\t\t\t\t   pjmedia_port **p_port );\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_RESAMPLE_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/rtcp.h",
    "content": "/* $Id: rtcp.h 3999 2012-03-30 07:10:13Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_RTCP_H__\n#define __PJMEDIA_RTCP_H__\n\n/**\n * @file rtcp.h\n * @brief RTCP implementation.\n */\n\n#include <pjmedia/types.h>\n#include <pjmedia/rtcp_xr.h>\n#include <pjmedia/rtp.h>\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJMED_RTCP RTCP Session and Encapsulation (RFC 3550)\n * @ingroup PJMEDIA_SESSION\n * @brief RTCP format and session management\n * @{\n *\n * PJMEDIA implements subsets of RTCP specification (RFC 3550) to monitor\n * the quality of the real-time media (audio/video) transmission. In\n * addition to the standard quality monitoring and reporting with RTCP\n * SR and RR types, PJMEDIA's RTCP implementation is able to report\n * extended statistics for incoming streams, such as packet duplications,\n * reorder, discarded, and loss period (to distinguish between random\n * and burst loss).\n *\n * The bidirectional media quality statistic is represented with\n * #pjmedia_rtcp_stat structure.\n *\n * When application uses the stream interface (see @ref PJMED_STRM),\n * application may retrieve the RTCP statistic by calling \n * #pjmedia_stream_get_stat() function.\n */\n\n \n#pragma pack(1)\n\n/**\n * RTCP sender report.\n */\ntypedef struct pjmedia_rtcp_sr\n{\n    pj_uint32_t\t    ntp_sec;\t    /**< NTP time, seconds part.\t*/\n    pj_uint32_t\t    ntp_frac;\t    /**< NTP time, fractions part.\t*/\n    pj_uint32_t\t    rtp_ts;\t    /**< RTP timestamp.\t\t\t*/\n    pj_uint32_t\t    sender_pcount;  /**< Sender packet cound.\t\t*/\n    pj_uint32_t\t    sender_bcount;  /**< Sender octet/bytes count.\t*/\n} pjmedia_rtcp_sr;\n\n\n/**\n * RTCP receiver report.\n */\ntypedef struct pjmedia_rtcp_rr\n{\n    pj_uint32_t\t    ssrc;\t    /**< SSRC identification.\t\t*/\n#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0\n    pj_uint32_t\t    fract_lost:8;   /**< Fraction lost.\t\t\t*/\n    pj_uint32_t\t    total_lost_2:8; /**< Total lost, bit 16-23.\t\t*/\n    pj_uint32_t\t    total_lost_1:8; /**< Total lost, bit 8-15.\t\t*/\n    pj_uint32_t\t    total_lost_0:8; /**< Total lost, bit 0-7.\t\t*/\n#else\n    pj_uint32_t\t    fract_lost:8;   /**< Fraction lost.\t\t\t*/\n    pj_uint32_t\t    total_lost_2:8; /**< Total lost, bit 0-7.\t\t*/\n    pj_uint32_t\t    total_lost_1:8; /**< Total lost, bit 8-15.\t\t*/\n    pj_uint32_t\t    total_lost_0:8; /**< Total lost, bit 16-23.\t\t*/\n#endif\t\n    pj_uint32_t\t    last_seq;\t    /**< Last sequence number.\t\t*/\n    pj_uint32_t\t    jitter;\t    /**< Jitter.\t\t\t*/\n    pj_uint32_t\t    lsr;\t    /**< Last SR.\t\t\t*/\n    pj_uint32_t\t    dlsr;\t    /**< Delay since last SR.\t\t*/\n} pjmedia_rtcp_rr;\n\n\n/**\n * RTCP common header.\n */\ntypedef struct pjmedia_rtcp_common\n{\n#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0\n    unsigned\t    version:2;\t/**< packet type            */\n    unsigned\t    p:1;\t/**< padding flag           */\n    unsigned\t    count:5;\t/**< varies by payload type */\n    unsigned\t    pt:8;\t/**< payload type           */\n#else\n    unsigned\t    count:5;\t/**< varies by payload type */\n    unsigned\t    p:1;\t/**< padding flag           */\n    unsigned\t    version:2;\t/**< packet type            */\n    unsigned\t    pt:8;\t/**< payload type           */\n#endif\n    unsigned\t    length:16;\t/**< packet length          */\n    pj_uint32_t\t    ssrc;\t/**< SSRC identification    */\n} pjmedia_rtcp_common;\n\n\n/**\n * This structure declares default RTCP packet (SR) that is sent by pjmedia.\n * Incoming RTCP packet may have different format, and must be parsed\n * manually by application.\n */\ntypedef struct pjmedia_rtcp_sr_pkt\n{\n    pjmedia_rtcp_common  common;\t/**< Common header.\t    */\n    pjmedia_rtcp_sr\t sr;\t\t/**< Sender report.\t    */\n    pjmedia_rtcp_rr\t rr;\t\t/**< variable-length list   */\n} pjmedia_rtcp_sr_pkt;\n\n/**\n * This structure declares RTCP RR (Receiver Report) packet.\n */\ntypedef struct pjmedia_rtcp_rr_pkt\n{\n    pjmedia_rtcp_common  common;\t/**< Common header.\t    */\n    pjmedia_rtcp_rr\t rr;\t\t/**< variable-length list   */\n} pjmedia_rtcp_rr_pkt;\n\n\n#pragma pack()\n\n\n/**\n * RTCP SDES structure.\n */\ntypedef struct pjmedia_rtcp_sdes\n{\n    pj_str_t\tcname;\t\t/**< RTCP SDES type CNAME.\t*/\n    pj_str_t\tname;\t\t/**< RTCP SDES type NAME.\t*/\n    pj_str_t\temail;\t\t/**< RTCP SDES type EMAIL.\t*/\n    pj_str_t\tphone;\t\t/**< RTCP SDES type PHONE.\t*/\n    pj_str_t\tloc;\t\t/**< RTCP SDES type LOC.\t*/\n    pj_str_t\ttool;\t\t/**< RTCP SDES type TOOL.\t*/\n    pj_str_t\tnote;\t\t/**< RTCP SDES type NOTE.\t*/\n} pjmedia_rtcp_sdes;\n\n\n/**\n * NTP time representation.\n */\ntypedef struct pjmedia_rtcp_ntp_rec\n{\n    pj_uint32_t\t    hi;\t\t/**< High order 32-bit part.\t*/\n    pj_uint32_t\t    lo;\t\t/**< Lo order 32-bit part.\t*/\n} pjmedia_rtcp_ntp_rec;\n\n\n/**\n * Unidirectional RTP stream statistics.\n */\ntypedef struct pjmedia_rtcp_stream_stat\n{\n    pj_time_val\t    update;\t/**< Time of last update.\t\t    */\n    unsigned\t    update_cnt;\t/**< Number of updates (to calculate avg)   */\n    pj_uint32_t\t    pkt;\t/**< Total number of packets\t\t    */\n    pj_uint32_t\t    bytes;\t/**< Total number of payload/bytes\t    */\n    unsigned\t    discard;\t/**< Total number of discarded packets.\t    */\n    unsigned\t    loss;\t/**< Total number of packets lost\t    */\n    unsigned\t    reorder;\t/**< Total number of out of order packets   */\n    unsigned\t    dup;\t/**< Total number of duplicates packets\t    */\n\n    pj_math_stat    loss_period;/**< Loss period statistics (in usec)\t    */\n\n    struct {\n\tunsigned    burst:1;\t/**< Burst/sequential packet lost detected  */\n    \tunsigned    random:1;\t/**< Random packet lost detected.\t    */\n    } loss_type;\t\t/**< Types of loss detected.\t\t    */\n\n    pj_math_stat    jitter;\t/**< Jitter statistics (in usec)\t    */\n\n} pjmedia_rtcp_stream_stat;\n\n\n/**\n * Bidirectional RTP stream statistics.\n */\ntypedef struct pjmedia_rtcp_stat\n{\n    pj_time_val\t\t     start; /**< Time when session was created\t    */\n\n    pjmedia_rtcp_stream_stat tx;    /**< Encoder stream statistics.\t    */\n    pjmedia_rtcp_stream_stat rx;    /**< Decoder stream statistics.\t    */\n    \n    pj_math_stat\t     rtt;   /**< Round trip delay statistic(in usec)*/\n\n    pj_uint32_t\t\t     rtp_tx_last_ts; /**< Last TX RTP timestamp.    */\n    pj_uint16_t\t\t     rtp_tx_last_seq;/**< Last TX RTP sequence.\t    */\n\n#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0\n    pj_math_stat\t     rx_ipdv;/**< Statistics of IP packet delay\n\t\t\t\t          variation in receiving direction\n\t\t\t\t\t  (in usec).\t\t\t    */\n#endif\n\n#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0\n    pj_math_stat\t     rx_raw_jitter;/**< Statistic of raw jitter in\n\t\t\t\t\t\treceiving direction \n\t\t\t\t\t\t(in usec).\t\t    */\n#endif\n\n    pjmedia_rtcp_sdes\t     peer_sdes;\t/**< Peer SDES.\t\t\t    */\n    char\t\t     peer_sdes_buf_[PJMEDIA_RTCP_RX_SDES_BUF_LEN];\n\t\t\t\t\t/**< Peer SDES buffer.\t\t    */\n\n} pjmedia_rtcp_stat;\n\n\n/**\n * RTCP session is used to monitor the RTP session of one endpoint. There\n * should only be one RTCP session for a bidirectional RTP streams.\n */\ntypedef struct pjmedia_rtcp_session\n{\n    char\t\t   *name;\t/**< Name identification.\t    */\n    pjmedia_rtcp_sr_pkt\t    rtcp_sr_pkt;/**< Cached RTCP SR packet.\t    */\n    pjmedia_rtcp_rr_pkt\t    rtcp_rr_pkt;/**< Cached RTCP RR packet.\t    */\n    \n    pjmedia_rtp_seq_session seq_ctrl;\t/**< RTCP sequence number control.  */\n    unsigned\t\t    rtp_last_ts;/**< Last timestamp in RX RTP pkt.  */\n\n    unsigned\t\t    clock_rate;\t/**< Clock rate of the stream\t    */\n    unsigned\t\t    pkt_size;\t/**< Avg pkt size, in samples.\t    */\n    pj_uint32_t\t\t    received;   /**< # pkt received\t\t    */\n    pj_uint32_t\t\t    exp_prior;\t/**< # pkt expected at last interval*/\n    pj_uint32_t\t\t    rx_prior;\t/**< # pkt received at last interval*/\n    pj_int32_t\t\t    transit;    /**< Rel transit time for prev pkt  */\n    pj_uint32_t\t\t    jitter;\t/**< Scaled jitter\t\t    */\n    pj_time_val\t\t    tv_base;\t/**< Base time, in seconds.\t    */\n    pj_timestamp\t    ts_base;\t/**< Base system timestamp.\t    */\n    pj_timestamp\t    ts_freq;\t/**< System timestamp frequency.    */\n    pj_uint32_t\t\t    rtp_ts_base;/**< Base RTP timestamp.\t    */\n\n    pj_uint32_t\t\t    rx_lsr;\t/**< NTP ts in last SR received\t    */\n    pj_timestamp\t    rx_lsr_time;/**< Time when last SR is received  */\n    pj_uint32_t\t\t    peer_ssrc;\t/**< Peer SSRC\t\t\t    */\n    \n    pjmedia_rtcp_stat\t    stat;\t/**< Bidirectional stream stat.\t    */\n\n    pj_bool_t               keyframe_requested;    /** Set to true when RTCP PLI is received */\n\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n    /**\n     * Specify whether RTCP XR processing is enabled on this session.\n     */\n    pj_bool_t\t\t    xr_enabled;\n\n    /**\n     * RTCP XR session, only valid if RTCP XR processing is enabled\n     * on this session.\n     */\n    pjmedia_rtcp_xr_session xr_session;\n#endif\n} pjmedia_rtcp_session;\n\n\n/**\n * RTCP session settings.\n */\ntypedef struct pjmedia_rtcp_session_setting\n{\n    char\t    *name;\t\t/**< RTCP session name.\t\t*/\n    unsigned\t     clock_rate;\t/**< Sequence.\t\t\t*/\n    unsigned\t     samples_per_frame;\t/**< Timestamp.\t\t\t*/\n    pj_uint32_t\t     ssrc;\t\t/**< Sender SSRC.\t\t*/\n    pj_uint32_t\t     rtp_ts_base;\t/**< Base RTP timestamp.\t*/\n} pjmedia_rtcp_session_setting;\n\n\n/**\n * Initialize RTCP session setting.\n *\n * @param settings\t    The RTCP session setting to be initialized.\n */\nPJ_DECL(void) pjmedia_rtcp_session_setting_default(\n\t\t\t\t    pjmedia_rtcp_session_setting *settings);\n\n\n/**\n * Initialize bidirectional RTCP statistics.\n *\n * @param stat\t\t    The bidirectional RTCP statistics.\n */\nPJ_DECL(void) pjmedia_rtcp_init_stat(pjmedia_rtcp_stat *stat);\n\n\n/**\n * Initialize RTCP session.\n *\n * @param session\t    The session\n * @param name\t\t    Optional name to identify the session (for\n *\t\t\t    logging purpose).\n * @param clock_rate\t    Codec clock rate in samples per second.\n * @param samples_per_frame Average number of samples per frame.\n * @param ssrc\t\t    The SSRC used in to identify the session.\n */\nPJ_DECL(void) pjmedia_rtcp_init( pjmedia_rtcp_session *session, \n\t\t\t\t char *name,\n\t\t\t\t unsigned clock_rate,\n\t\t\t\t unsigned samples_per_frame,\n\t\t\t\t pj_uint32_t ssrc );\n\n\n/**\n * Initialize RTCP session.\n *\n * @param session\t    The session\n * @param settings\t    The RTCP session settings.\n */\nPJ_DECL(void) pjmedia_rtcp_init2(pjmedia_rtcp_session *session,\n\t\t\t\t const pjmedia_rtcp_session_setting *settings);\n\n\n/**\n * Utility function to retrieve current NTP timestamp.\n *\n * @param sess\t\t    RTCP session.\n * @param ntp\t\t    NTP record.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_rtcp_get_ntp_time(const pjmedia_rtcp_session *sess,\n\t\t\t\t\t       pjmedia_rtcp_ntp_rec *ntp);\n\n\n/**\n * Deinitialize RTCP session.\n *\n * @param session   The session.\n */\nPJ_DECL(void) pjmedia_rtcp_fini( pjmedia_rtcp_session *session);\n\n\n/**\n * Call this function everytime an RTP packet is received to let the RTCP\n * session do its internal calculations.\n *\n * @param session   The session.\n * @param seq\t    The RTP packet sequence number, in host byte order.\n * @param ts\t    The RTP packet timestamp, in host byte order.\n * @param payload   Size of the payload.\n */\nPJ_DECL(void) pjmedia_rtcp_rx_rtp( pjmedia_rtcp_session *session, \n\t\t\t\t   unsigned seq, \n\t\t\t\t   unsigned ts,\n\t\t\t\t   unsigned payload);\n\n\n/**\n * Call this function everytime an RTP packet is received to let the RTCP\n * session do its internal calculations.\n *\n * @param session   The session.\n * @param seq\t    The RTP packet sequence number, in host byte order.\n * @param ts\t    The RTP packet timestamp, in host byte order.\n * @param payload   Size of the payload.\n * @param discarded Flag to specify whether the packet is discarded.\n */\nPJ_DECL(void) pjmedia_rtcp_rx_rtp2(pjmedia_rtcp_session *session, \n\t\t\t\t   unsigned seq, \n\t\t\t\t   unsigned ts,\n\t\t\t\t   unsigned payload,\n\t\t\t\t   pj_bool_t discarded);\n\n\n/**\n * Call this function everytime an RTP packet is sent to let the RTCP session\n * do its internal calculations.\n *\n * @param session   The session.\n * @param ptsize    The payload size of the RTP packet (ie packet minus\n *\t\t    RTP header) in bytes.\n */\nPJ_DECL(void) pjmedia_rtcp_tx_rtp( pjmedia_rtcp_session *session, \n\t\t\t\t   unsigned ptsize );\n\n\n/**\n * Call this function when an RTCP packet is received from remote peer.\n * This RTCP packet received from remote is used to calculate the end-to-\n * end delay of the network.\n *\n * @param session   RTCP session.\n * @param rtcp_pkt  The received RTCP packet.\n * @param size\t    Size of the incoming packet.\n */\nPJ_DECL(void) pjmedia_rtcp_rx_rtcp( pjmedia_rtcp_session *session,\n\t\t\t\t    const void *rtcp_pkt,\n\t\t\t\t    pj_size_t size);\n\n\n/**\n * Build a RTCP packet to be transmitted to remote RTP peer. This will\n * create RTCP Sender Report (SR) or Receiver Report (RR) depending on\n * whether the endpoint has been transmitting RTP since the last interval.\n * Note that this function will reset the interval counters (such as\n * the ones to calculate fraction lost) in the session.\n *\n * @param session   The RTCP session.\n * @param rtcp_pkt  Upon return, it will contain pointer to the \n *\t\t    RTCP packet, which can be RTCP SR or RR.\n * @param len\t    Upon return, it will indicate the size of \n *\t\t    the RTCP packet.\n */\nPJ_DECL(void) pjmedia_rtcp_build_rtcp( pjmedia_rtcp_session *session, \n\t\t\t\t       void **rtcp_pkt, int *len);\n\n\n/**\n * Build an RTCP SDES (source description) packet. This packet can be\n * appended to other RTCP packets, e.g: RTCP RR/SR, to compose a compound\n * RTCP packet.\n *\n * @param session   The RTCP session.\n * @param buf\t    The buffer to receive RTCP SDES packet.\n * @param length    On input, it will contain the buffer length.\n *\t\t    On output, it will contain the generated RTCP SDES\n *\t\t    packet length.\n * @param sdes\t    The source description, see #pjmedia_rtcp_sdes.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_rtcp_build_rtcp_sdes(\n\t\t\t\t\t    pjmedia_rtcp_session *session, \n\t\t\t\t\t    void *buf,\n\t\t\t\t\t    pj_size_t *length,\n\t\t\t\t\t    const pjmedia_rtcp_sdes *sdes);\n\n/**\n * Build an RTCP BYE packet. This packet can be appended to other RTCP\n * packets, e.g: RTCP RR/SR, to compose a compound RTCP packet.\n *\n * @param session   The RTCP session.\n * @param buf\t    The buffer to receive RTCP BYE packet.\n * @param length    On input, it will contain the buffer length.\n *\t\t    On output, it will contain the generated RTCP BYE\n *\t\t    packet length.\n * @param reason    Optional, the BYE reason.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_rtcp_build_rtcp_bye(\n\t\t\t\t\t    pjmedia_rtcp_session *session, \n\t\t\t\t\t    void *buf,\n\t\t\t\t\t    pj_size_t *length,\n\t\t\t\t\t    const pj_str_t *reason);\n\n/**\n * Build an RTCP PLI packet. This packet can be appended to other RTCP\n * packets, e.g: RTCP RR/SR, to compose a compound RTCP packet.\n *\n * @param session   The RTCP session.\n * @param buf\t    The buffer to receive RTCP PLI packet.\n * @param length    On input, it will contain the buffer length.\n *\t\t    On output, it will contain the generated RTCP PLI\n *\t\t    packet length.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_rtcp_build_rtcp_pli(\n\t\t\t\t\t    pjmedia_rtcp_session *session, \n\t\t\t\t\t    void *buf,\n\t\t\t\t\t    pj_size_t *length);\n\n/**\n * Call this function if RTCP XR needs to be enabled/disabled in the \n * RTCP session.\n *\n * @param session   The RTCP session.\n * @param enable    Enable/disable RTCP XR.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_rtcp_enable_xr( pjmedia_rtcp_session *session, \n\t\t\t\t\t     pj_bool_t enable);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_RTCP_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/rtcp_xr.h",
    "content": "/* $Id: rtcp_xr.h 3999 2012-03-30 07:10:13Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_RTCP_XR_H__\n#define __PJMEDIA_RTCP_XR_H__\n\n/**\n * @file rtcp_xr.h\n * @brief RTCP XR implementation.\n */\n\n#include <pjmedia/types.h>\n#include <pj/math.h>\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJMED_RTCP_XR RTCP Extended Report (XR) - RFC 3611\n * @ingroup PJMEDIA_SESSION\n * @brief RTCP XR extension to RTCP session\n * @{\n *\n * PJMEDIA implements subsets of RTCP XR specification (RFC 3611) to monitor\n * the quality of the real-time media (audio/video) transmission.\n */\n\n/**\n * Enumeration of report types of RTCP XR. Useful for user to enable varying\n * combinations of RTCP XR report blocks.\n */\ntypedef enum {\n    PJMEDIA_RTCP_XR_LOSS_RLE\t    = (1 << 0),\n    PJMEDIA_RTCP_XR_DUP_RLE\t    = (1 << 1),\n    PJMEDIA_RTCP_XR_RCPT_TIMES\t    = (1 << 2),\n    PJMEDIA_RTCP_XR_RR_TIME\t    = (1 << 3),\n    PJMEDIA_RTCP_XR_DLRR\t    = (1 << 4),\n    PJMEDIA_RTCP_XR_STATS\t    = (1 << 5),\n    PJMEDIA_RTCP_XR_VOIP_METRICS    = (1 << 6)\n} pjmedia_rtcp_xr_type;\n\n/**\n * Enumeration of info need to be updated manually to RTCP XR. Most info\n * could be updated automatically each time RTP received.\n */\ntypedef enum {\n    PJMEDIA_RTCP_XR_INFO_SIGNAL_LVL = 1,\n    PJMEDIA_RTCP_XR_INFO_NOISE_LVL  = 2,\n    PJMEDIA_RTCP_XR_INFO_RERL\t    = 3,\n    PJMEDIA_RTCP_XR_INFO_R_FACTOR   = 4,\n    PJMEDIA_RTCP_XR_INFO_MOS_LQ\t    = 5,\n    PJMEDIA_RTCP_XR_INFO_MOS_CQ\t    = 6,\n    PJMEDIA_RTCP_XR_INFO_CONF_PLC   = 7,\n    PJMEDIA_RTCP_XR_INFO_CONF_JBA   = 8,\n    PJMEDIA_RTCP_XR_INFO_CONF_JBR   = 9,\n    PJMEDIA_RTCP_XR_INFO_JB_NOM\t    = 10,\n    PJMEDIA_RTCP_XR_INFO_JB_MAX\t    = 11,\n    PJMEDIA_RTCP_XR_INFO_JB_ABS_MAX = 12\n} pjmedia_rtcp_xr_info;\n\n/**\n * Enumeration of PLC types definitions for RTCP XR report.\n */\ntypedef enum {\n    PJMEDIA_RTCP_XR_PLC_UNK\t    = 0,\n    PJMEDIA_RTCP_XR_PLC_DIS\t    = 1,\n    PJMEDIA_RTCP_XR_PLC_ENH\t    = 2,\n    PJMEDIA_RTCP_XR_PLC_STD\t    = 3\n} pjmedia_rtcp_xr_plc_type;\n\n/**\n * Enumeration of jitter buffer types definitions for RTCP XR report.\n */\ntypedef enum {\n    PJMEDIA_RTCP_XR_JB_UNKNOWN      = 0,\n    PJMEDIA_RTCP_XR_JB_FIXED        = 2,\n    PJMEDIA_RTCP_XR_JB_ADAPTIVE     = 3\n} pjmedia_rtcp_xr_jb_type;\n\n\n#pragma pack(1)\n\n/**\n * This type declares RTCP XR Report Header.\n */\ntypedef struct pjmedia_rtcp_xr_rb_header\n{\n    pj_uint8_t\t\t bt;\t\t/**< Block type.\t\t*/\n    pj_uint8_t\t\t specific;\t/**< Block specific data.\t*/\n    pj_uint16_t\t\t length;\t/**< Block length.\t\t*/\n} pjmedia_rtcp_xr_rb_header;\n\n/**\n * This type declares RTCP XR Receiver Reference Time Report Block.\n */\ntypedef struct pjmedia_rtcp_xr_rb_rr_time\n{\n    pjmedia_rtcp_xr_rb_header header;\t/**< Block header.\t\t*/\n    pj_uint32_t\t\t ntp_sec;\t/**< NTP time, seconds part.\t*/\n    pj_uint32_t\t\t ntp_frac;\t/**< NTP time, fractions part.\t*/\n} pjmedia_rtcp_xr_rb_rr_time;\n\n\n/**\n * This type declares RTCP XR DLRR Report Sub-block\n */\ntypedef struct pjmedia_rtcp_xr_rb_dlrr_item\n{\n    pj_uint32_t\t\t ssrc;\t\t/**< receiver SSRC\t\t*/\n    pj_uint32_t\t\t lrr;\t\t/**< last receiver report\t*/\n    pj_uint32_t\t\t dlrr;\t\t/**< delay since last receiver\n\t\t\t\t\t     report\t\t\t*/\n} pjmedia_rtcp_xr_rb_dlrr_item;\n\n/**\n * This type declares RTCP XR DLRR Report Block\n */\ntypedef struct pjmedia_rtcp_xr_rb_dlrr\n{\n    pjmedia_rtcp_xr_rb_header header;\t/**< Block header.\t\t*/\n    pjmedia_rtcp_xr_rb_dlrr_item item;\t/**< Block contents, \n\t\t\t\t\t     variable length list\t*/\n} pjmedia_rtcp_xr_rb_dlrr;\n\n/**\n * This type declares RTCP XR Statistics Summary Report Block\n */\ntypedef struct pjmedia_rtcp_xr_rb_stats\n{\n    pjmedia_rtcp_xr_rb_header header;\t/**< Block header.\t\t     */\n    pj_uint32_t\t\t ssrc;\t\t/**< Receiver SSRC\t\t     */\n    pj_uint16_t\t\t begin_seq;\t/**< Begin RTP sequence reported     */\n    pj_uint16_t\t\t end_seq;\t/**< End RTP sequence reported       */\n    pj_uint32_t\t\t lost;\t\t/**< Number of packet lost in this \n\t\t\t\t\t     interval  */\n    pj_uint32_t\t\t dup;\t\t/**< Number of duplicated packet in \n\t\t\t\t\t     this interval */\n    pj_uint32_t\t\t jitter_min;\t/**< Minimum jitter in this interval */\n    pj_uint32_t\t\t jitter_max;\t/**< Maximum jitter in this interval */\n    pj_uint32_t\t\t jitter_mean;\t/**< Average jitter in this interval */\n    pj_uint32_t\t\t jitter_dev;\t/**< Jitter deviation in this \n\t\t\t\t\t     interval */\n    pj_uint32_t\t\t toh_min:8;\t/**< Minimum ToH in this interval    */\n    pj_uint32_t\t\t toh_max:8;\t/**< Maximum ToH in this interval    */\n    pj_uint32_t\t\t toh_mean:8;\t/**< Average ToH in this interval    */\n    pj_uint32_t\t\t toh_dev:8;\t/**< ToH deviation in this interval  */\n} pjmedia_rtcp_xr_rb_stats;\n\n/**\n * This type declares RTCP XR VoIP Metrics Report Block\n */\ntypedef struct pjmedia_rtcp_xr_rb_voip_mtc\n{\n    pjmedia_rtcp_xr_rb_header header;\t/**< Block header.\t\t*/\n    pj_uint32_t\t\t ssrc;\t\t/**< Receiver SSRC\t\t*/\n    pj_uint8_t\t\t loss_rate;\t/**< Packet loss rate\t\t*/\n    pj_uint8_t\t\t discard_rate;\t/**< Packet discarded rate\t*/\n    pj_uint8_t\t\t burst_den;\t/**< Burst density\t\t*/\n    pj_uint8_t\t\t gap_den;\t/**< Gap density\t\t*/\n    pj_uint16_t\t\t burst_dur;\t/**< Burst duration\t\t*/\n    pj_uint16_t\t\t gap_dur;\t/**< Gap duration\t\t*/\n    pj_uint16_t\t\t rnd_trip_delay;/**< Round trip delay\t\t*/\n    pj_uint16_t\t\t end_sys_delay; /**< End system delay\t\t*/\n    pj_uint8_t\t\t signal_lvl;\t/**< Signal level\t\t*/\n    pj_uint8_t\t\t noise_lvl;\t/**< Noise level\t\t*/\n    pj_uint8_t\t\t rerl;\t\t/**< Residual Echo Return Loss\t*/\n    pj_uint8_t\t\t gmin;\t\t/**< The gap threshold\t\t*/\n    pj_uint8_t\t\t r_factor;\t/**< Voice quality metric carried\n\t\t\t\t\t     over this RTP session\t*/\n    pj_uint8_t\t\t ext_r_factor;  /**< Voice quality metric carried \n\t\t\t\t\t     outside of this RTP session*/\n    pj_uint8_t\t\t mos_lq;\t/**< Mean Opinion Score for \n\t\t\t\t\t     Listening Quality          */\n    pj_uint8_t\t\t mos_cq;\t/**< Mean Opinion Score for \n\t\t\t\t\t     Conversation Quality       */\n    pj_uint8_t\t\t rx_config;\t/**< Receiver configuration\t*/\n    pj_uint8_t\t\t reserved2;\t/**< Not used\t\t\t*/\n    pj_uint16_t\t\t jb_nom;\t/**< Current delay by jitter\n\t\t\t\t\t     buffer\t\t\t*/\n    pj_uint16_t\t\t jb_max;\t/**< Maximum delay by jitter\n\t\t\t\t\t     buffer\t\t\t*/\n    pj_uint16_t\t\t jb_abs_max;\t/**< Maximum possible delay by\n\t\t\t\t\t     jitter buffer\t\t*/\n} pjmedia_rtcp_xr_rb_voip_mtc;\n\n\n/**\n * Constant of RTCP-XR content size.\n */\n#define PJMEDIA_RTCP_XR_BUF_SIZE \\\n    sizeof(pjmedia_rtcp_xr_rb_rr_time) + \\\n    sizeof(pjmedia_rtcp_xr_rb_dlrr) + \\\n    sizeof(pjmedia_rtcp_xr_rb_stats) + \\\n    sizeof(pjmedia_rtcp_xr_rb_voip_mtc)\n\n\n/**\n * This structure declares RTCP XR (Extended Report) packet.\n */\ntypedef struct pjmedia_rtcp_xr_pkt\n{\n    struct {\n#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0\n\tunsigned\t version:2;\t/**< packet type            */\n\tunsigned\t p:1;\t\t/**< padding flag           */\n\tunsigned\t count:5;\t/**< varies by payload type */\n\tunsigned\t pt:8;\t\t/**< payload type           */\n#else\n\tunsigned\t count:5;\t/**< varies by payload type */\n\tunsigned\t p:1;\t\t/**< padding flag           */\n\tunsigned\t version:2;\t/**< packet type            */\n\tunsigned\t pt:8;\t\t/**< payload type           */\n#endif\n\tunsigned\t length:16;\t/**< packet length          */\n\tpj_uint32_t\t ssrc;\t\t/**< SSRC identification    */\n    } common;\n\n    pj_int8_t\t\t buf[PJMEDIA_RTCP_XR_BUF_SIZE];\n\t\t\t\t\t/**< Content buffer   */\n} pjmedia_rtcp_xr_pkt;\n\n#pragma pack()\n\n\n/**\n * This structure describes RTCP XR statitic.\n */\ntypedef struct pjmedia_rtcp_xr_stream_stat\n{\n    struct {\n\tpj_time_val\t    update;\t/**< Time of last update.\t    */\n\n\tpj_uint32_t\t    begin_seq;\t/**< Begin # seq of this interval.  */\n\tpj_uint32_t\t    end_seq;\t/**< End # seq of this interval.    */\n\tunsigned\t    count;\t/**< Number of packets.\t\t    */\n\n\t/**\n\t * Flags represent whether the such report is valid/updated\n\t */\n\tunsigned\t    l:1;\t/**< Lost flag\t\t\t    */\n\tunsigned\t    d:1;\t/**< Duplicated flag\t\t    */\n\tunsigned\t    j:1;\t/**< Jitter flag\t\t    */\n\tunsigned\t    t:2;\t/**< TTL or Hop Limit, \n\t\t\t\t\t     0=none, 1=TTL, 2=HL\t    */\n\n\tunsigned\t    lost;\t/**< Number of packets lost\t    */\n\tunsigned\t    dup;\t/**< Number of duplicated packets   */\n\tpj_math_stat\t    jitter;\t/**< Jitter statistics (in usec)    */\n\tpj_math_stat\t    toh;\t/**< TTL of hop limit statistics.   */\n    } stat_sum;\n\n    struct {\n\tpj_time_val\t    update;\t    /**< Time of last update.\t    */\n\n\tpj_uint8_t\t    loss_rate;\t    /**< Packet loss rate\t    */\n\tpj_uint8_t\t    discard_rate;   /**< Packet discarded rate\t    */\n\tpj_uint8_t\t    burst_den;\t    /**< Burst density\t\t    */\n\tpj_uint8_t\t    gap_den;\t    /**< Gap density\t\t    */\n\tpj_uint16_t\t    burst_dur;\t    /**< Burst duration\t\t    */\n\tpj_uint16_t\t    gap_dur;\t    /**< Gap duration\t\t    */\n\tpj_uint16_t\t    rnd_trip_delay; /**< Round trip delay\t    */\n\tpj_uint16_t\t    end_sys_delay;  /**< End system delay\t    */\n\tpj_int8_t\t    signal_lvl;\t    /**< Signal level\t\t    */\n\tpj_int8_t\t    noise_lvl;\t    /**< Noise level\t\t    */\n\tpj_uint8_t\t    rerl;\t    /**< Residual Echo Return Loss  */\n\tpj_uint8_t\t    gmin;\t    /**< The gap threshold\t    */\n\tpj_uint8_t\t    r_factor;\t    /**< Voice quality metric carried\n\t\t\t\t\t\t over this RTP session\t    */\n\tpj_uint8_t\t    ext_r_factor;   /**< Voice quality metric carried \n\t\t\t\t\t\t outside of this RTP session*/\n\tpj_uint8_t\t    mos_lq;\t    /**< Mean Opinion Score for \n\t\t\t\t\t\t Listening Quality          */\n\tpj_uint8_t\t    mos_cq;\t    /**< Mean Opinion Score for \n\t\t\t\t\t\t Conversation Quality       */\n\tpj_uint8_t\t    rx_config;\t    /**< Receiver configuration\t    */\n\tpj_uint16_t\t    jb_nom;\t    /**< Current delay by jitter\n\t\t\t\t\t\t buffer\t\t\t    */\n\tpj_uint16_t\t    jb_max;\t    /**< Maximum delay by jitter\n\t\t\t\t\t\t buffer\t\t\t    */\n\tpj_uint16_t\t    jb_abs_max;\t    /**< Maximum possible delay by\n\t\t\t\t\t\t jitter buffer\t\t    */\n    } voip_mtc;\n\n} pjmedia_rtcp_xr_stream_stat;\n\ntypedef struct pjmedia_rtcp_xr_stat\n{\n    pjmedia_rtcp_xr_stream_stat\t rx;  /**< Decoding direction statistics.   */\n    pjmedia_rtcp_xr_stream_stat\t tx;  /**< Encoding direction statistics.   */\n    pj_math_stat\t\t rtt; /**< Round-trip delay stat (in usec) \n\t\t\t\t\t   the value is calculated from \n\t\t\t\t\t   receiver side.\t\t    */\n} pjmedia_rtcp_xr_stat;\n\n/**\n * Forward declaration of RTCP session\n */\nstruct pjmedia_rtcp_session;\n\n/**\n * RTCP session is used to monitor the RTP session of one endpoint. There\n * should only be one RTCP session for a bidirectional RTP streams.\n */\nstruct pjmedia_rtcp_xr_session\n{\n    char\t\t   *name;\t/**< Name identification.\t    */\n    pjmedia_rtcp_xr_pkt\t    pkt;\t/**< Cached RTCP XR packet.\t    */\n\n    pj_uint32_t\t\t    rx_lrr;\t/**< NTP ts in last RR received.    */\n    pj_timestamp\t    rx_lrr_time;/**< Time when last RR is received. */\n    pj_uint32_t\t\t    rx_last_rr; /**< # pkt received since last \n\t\t\t\t             sending RR time.\t\t    */\n\n    pjmedia_rtcp_xr_stat    stat;\t/**< RTCP XR statistics.\t    */\n\n    /* The reference sequence number is an extended sequence number\n     * that serves as the basis for determining whether a new 16 bit\n     * sequence number comes earlier or later in the 32 bit sequence\n     * space.\n     */\n    pj_uint32_t\t\t    src_ref_seq;\n    pj_bool_t\t\t    uninitialized_src_ref_seq;\n\n    /* This structure contains variables needed for calculating \n     * burst metrics.\n     */\n    struct {\n\tpj_uint32_t\t    pkt;\n\tpj_uint32_t\t    lost;\n\tpj_uint32_t\t    loss_count;\n\tpj_uint32_t\t    discard_count;\n\tpj_uint32_t\t    c11;\n\tpj_uint32_t\t    c13;\n\tpj_uint32_t\t    c14;\n\tpj_uint32_t\t    c22;\n\tpj_uint32_t\t    c23;\n\tpj_uint32_t\t    c33;\n    } voip_mtc_stat;\n\n    unsigned ptime;\t\t\t/**< Packet time.\t\t    */\n    unsigned frames_per_packet;\t\t/**< # frames per packet.\t    */\n\n    struct pjmedia_rtcp_session *rtcp_session;\n\t\t\t\t\t/**< Parent/RTCP session.\t    */\n};\n\ntypedef struct pjmedia_rtcp_xr_session pjmedia_rtcp_xr_session;\n\n/**\n * Build an RTCP XR packet which contains one or more RTCP XR report blocks.\n * There are seven report types as defined in RFC 3611.\n *\n * @param session   The RTCP XR session.\n * @param rpt_types Report types to be included in the packet, report types\n *\t\t    are defined in pjmedia_rtcp_xr_type, set this to zero\n *\t\t    will make this function build all reports appropriately.\n * @param rtcp_pkt  Upon return, it will contain pointer to the RTCP XR packet.\n * @param len\t    Upon return, it will indicate the size of the generated \n *\t\t    RTCP XR packet.\n */\nPJ_DECL(void) pjmedia_rtcp_build_rtcp_xr( pjmedia_rtcp_xr_session *session,\n\t\t\t\t\t  unsigned rpt_types,\n\t\t\t\t\t  void **rtcp_pkt, int *len);\n\n/**\n * Call this function to manually update some info needed by RTCP XR to \n * generate report which could not be populated directly when receiving\n * RTP.\n *\n * @param session   The RTCP XR session.\n * @param info\t    Info type to be updated, @see pjmedia_rtcp_xr_info.\n * @param val\t    Value.\n */\nPJ_DECL(pj_status_t) pjmedia_rtcp_xr_update_info(\n\t\t\t\t\t  pjmedia_rtcp_xr_session *session,\n\t\t\t\t\t  unsigned info,\n\t\t\t\t\t  pj_int32_t val);\n\n/*\n * Private APIs:\n */\n\n/**\n * This function is called internally by RTCP session when RTCP XR is enabled\n * to initialize the RTCP XR session.\n *\n * @param session   RTCP XR session.\n * @param r_session RTCP session.\n * @param gmin      Gmin value (defined in RFC 3611), set to 0 for default (16).\n * @param frames_per_packet\n\t\t    Number of frames per packet.\n */\nvoid pjmedia_rtcp_xr_init( pjmedia_rtcp_xr_session *session, \n\t\t\t   struct pjmedia_rtcp_session *r_session,\n\t\t\t   pj_uint8_t gmin,\n\t\t\t   unsigned frames_per_packet);\n\n/**\n * This function is called internally by RTCP session to destroy \n * the RTCP XR session.\n *\n * @param session   RTCP XR session.\n */\nvoid pjmedia_rtcp_xr_fini( pjmedia_rtcp_xr_session *session );\n\n/**\n * This function is called internally by RTCP session when it receives \n * incoming RTCP XR packets.\n *\n * @param session   RTCP XR session.\n * @param rtcp_pkt  The received RTCP XR packet.\n * @param size\t    Size of the incoming packet.\n */\nvoid pjmedia_rtcp_xr_rx_rtcp_xr( pjmedia_rtcp_xr_session *session,\n\t\t\t\t const void *rtcp_pkt,\n\t\t\t\t pj_size_t size);\n\n/**\n * This function is called internally by RTCP session whenever an RTP packet\n * is received or lost to let the RTCP XR session update its statistics.\n * Data passed to this function is a result of analyzation by RTCP and the\n * jitter buffer. Whenever some info is available, the value should be zero\n * or more (no negative info), otherwise if info is not available the info\n * should be -1 so no update will be done for this info in the RTCP XR session.\n *\n * @param session   RTCP XR session.\n * @param seq\t    Sequence number of RTP packet.\n * @param lost\t    Info if this packet is lost. \n * @param dup\t    Info if this packet is a duplication. \n * @param discarded Info if this packet is discarded \n *\t\t    (not because of duplication).\n * @param jitter    Info jitter of this packet.\n * @param toh\t    Info Time To Live or Hops Limit of this packet.\n * @param toh_ipv4  Set PJ_TRUE if packet is transported over IPv4.\n */\nvoid pjmedia_rtcp_xr_rx_rtp( pjmedia_rtcp_xr_session *session,\n\t\t\t     unsigned seq, \n\t\t\t     int lost,\n\t\t\t     int dup,\n\t\t\t     int discarded,\n\t\t\t     int jitter,\n\t\t\t     int toh, pj_bool_t toh_ipv4);\n\n/**\n * This function is called internally by RTCP session whenever an RTP \n * packet is sent to let the RTCP XR session do its internal calculations.\n *\n * @param session   RTCP XR session.\n * @param ptsize    Size of RTP payload being sent.\n */\nvoid pjmedia_rtcp_xr_tx_rtp( pjmedia_rtcp_xr_session *session, \n\t\t\t     unsigned ptsize );\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_RTCP_XR_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/rtp.h",
    "content": "/* $Id: rtp.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_RTP_H__\n#define __PJMEDIA_RTP_H__\n\n\n/**\n * @file rtp.h\n * @brief RTP packet and RTP session declarations.\n */\n#include <pjmedia/types.h>\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJMED_RTP RTP Session and Encapsulation (RFC 3550)\n * @ingroup PJMEDIA_SESSION\n * @brief RTP format and session management\n * @{\n *\n * The RTP module is designed to be dependent only to PJLIB, it does not depend\n * on any other parts of PJMEDIA library. The RTP module does not even depend\n * on any transports (sockets), to promote even more use, such as in DSP\n * development (where transport may be handled by different processor).\n *\n * An RTCP implementation is available, in separate module. Please see \n * @ref PJMED_RTCP.\n *\n * The functions that are provided by this module:\n *  - creating RTP header for each outgoing packet.\n *  - decoding RTP packet into RTP header and payload.\n *  - provide simple RTP session management (sequence number, etc.)\n *\n * The RTP module does not use any dynamic memory at all.\n *\n * \\section P1 How to Use the RTP Module\n * \n * First application must call #pjmedia_rtp_session_init() to initialize the RTP \n * session.\n *\n * When application wants to send RTP packet, it needs to call \n * #pjmedia_rtp_encode_rtp() to build the RTP header. Note that this WILL NOT build\n * the complete RTP packet, but instead only the header. Application can\n * then either concatenate the header with the payload, or send the two\n * fragments (the header and the payload) using scatter-gather transport API\n * (e.g. \\a sendv()).\n *\n * When application receives an RTP packet, first it should call\n * #pjmedia_rtp_decode_rtp to decode RTP header and payload, then it should call\n * #pjmedia_rtp_session_update to check whether we can process the RTP payload,\n * and to let the RTP session updates its internal status. The decode function\n * is guaranteed to point the payload to the correct position regardless of\n * any options present in the RTP packet.\n *\n */\n\n#ifdef _MSC_VER\n#   pragma warning(disable:4214)    // bit field types other than int\n#endif\n\n\n/**\n * RTP packet header. Note that all RTP functions here will work with this\n * header in network byte order.\n */\n#pragma pack(1)\nstruct pjmedia_rtp_hdr\n{\n#if defined(PJ_IS_BIG_ENDIAN) && (PJ_IS_BIG_ENDIAN!=0)\n    pj_uint16_t v:2;\t\t/**< packet type/version\t    */\n    pj_uint16_t p:1;\t\t/**< padding flag\t\t    */\n    pj_uint16_t x:1;\t\t/**< extension flag\t\t    */\n    pj_uint16_t cc:4;\t\t/**< CSRC count\t\t\t    */\n    pj_uint16_t m:1;\t\t/**< marker bit\t\t\t    */\n    pj_uint16_t pt:7;\t\t/**< payload type\t\t    */\n#else\n    pj_uint16_t cc:4;\t\t/**< CSRC count\t\t\t    */\n    pj_uint16_t x:1;\t\t/**< header extension flag\t    */ \n    pj_uint16_t p:1;\t\t/**< padding flag\t\t    */\n    pj_uint16_t v:2;\t\t/**< packet type/version\t    */\n    pj_uint16_t pt:7;\t\t/**< payload type\t\t    */\n    pj_uint16_t m:1;\t\t/**< marker bit\t\t\t    */\n#endif\n    pj_uint16_t seq;\t\t/**< sequence number\t\t    */\n    pj_uint32_t ts;\t\t/**< timestamp\t\t\t    */\n    pj_uint32_t ssrc;\t\t/**< synchronization source\t    */\n};\n#pragma pack()\n\n/**\n * @see pjmedia_rtp_hdr\n */\ntypedef struct pjmedia_rtp_hdr pjmedia_rtp_hdr;\n\n\n/**\n * RTP extendsion header.\n */\nstruct pjmedia_rtp_ext_hdr\n{\n    pj_uint16_t\tprofile_data;\t/**< Profile data.\t    */\n    pj_uint16_t\tlength;\t\t/**< Length.\t\t    */\n};\n\n/**\n * @see pjmedia_rtp_ext_hdr\n */\ntypedef struct pjmedia_rtp_ext_hdr pjmedia_rtp_ext_hdr;\n\n\n#pragma pack(1)\n\n/**\n * Declaration for DTMF telephony-events (RFC2833).\n */\nstruct pjmedia_rtp_dtmf_event\n{\n    pj_uint8_t\tevent;\t    /**< Event type ID.\t    */\n    pj_uint8_t\te_vol;\t    /**< Event volume.\t    */\n    pj_uint16_t\tduration;   /**< Event duration.    */\n};\n\n/**\n * @see pjmedia_rtp_dtmf_event\n */\ntypedef struct pjmedia_rtp_dtmf_event pjmedia_rtp_dtmf_event;\n\n#pragma pack()\n\n\n/**\n * A generic sequence number management, used by both RTP and RTCP.\n */\nstruct pjmedia_rtp_seq_session\n{\n    pj_uint16_t\t    max_seq;\t    /**< Highest sequence number heard\t    */\n    pj_uint32_t\t    cycles;\t    /**< Shifted count of seq number cycles */\n    pj_uint32_t\t    base_seq;\t    /**< Base seq number\t\t    */\n    pj_uint32_t\t    bad_seq;        /**< Last 'bad' seq number + 1\t    */\n    pj_uint32_t\t    probation;      /**< Sequ. packets till source is valid */\n};\n\n/**\n * @see pjmedia_rtp_seq_session\n */\ntypedef struct pjmedia_rtp_seq_session pjmedia_rtp_seq_session;\n\n\n/**\n * RTP session descriptor.\n */\nstruct pjmedia_rtp_session\n{\n    pjmedia_rtp_hdr\t    out_hdr;    /**< Saved hdr for outgoing pkts.   */\n    pjmedia_rtp_seq_session seq_ctrl;   /**< Sequence number management.    */\n    pj_uint16_t\t\t    out_pt;\t/**< Default outgoing payload type. */\n    pj_uint32_t\t\t    out_extseq; /**< Outgoing extended seq #.\t    */\n    pj_uint32_t\t\t    peer_ssrc;  /**< Peer SSRC.\t\t\t    */\n    pj_uint32_t\t\t    received;   /**< Number of received packets.    */\n};\n\n/**\n * @see pjmedia_rtp_session\n */\ntypedef struct pjmedia_rtp_session pjmedia_rtp_session;\n\n\n/**\n * This structure is used to receive additional information about the\n * state of incoming RTP packet.\n */\nstruct pjmedia_rtp_status\n{\n    union {\n\tstruct flag {\n\t    int\tbad:1;\t    /**< General flag to indicate that sequence is\n\t\t\t\t bad, and application should not process\n\t\t\t\t this packet. More information will be given\n\t\t\t\t in other flags.\t\t\t    */\n\t    int badpt:1;    /**< Bad payload type.\t\t\t    */\n\t    int badssrc:1;  /**< Bad SSRC\t\t\t\t    */\n\t    int\tdup:1;\t    /**< Indicates duplicate packet\t\t    */\n\t    int\toutorder:1; /**< Indicates out of order packet\t\t    */\n\t    int\tprobation:1;/**< Indicates that session is in probation\n\t\t\t\t until more packets are received.\t    */\n\t    int\trestart:1;  /**< Indicates that sequence number has made\n\t\t\t\t a large jump, and internal base sequence\n\t\t\t\t number has been adjusted.\t\t    */\n\t} flag;\t\t    /**< Status flags.\t\t\t\t    */\n\n\tpj_uint16_t value;  /**< Status value, to conveniently address all\n\t\t\t\t flags.\t\t\t\t\t    */\n\n    } status;\t\t    /**< Status information union.\t\t    */\n\n    pj_uint16_t\tdiff;\t    /**< Sequence number difference from previous\n\t\t\t\t packet. Normally the value should be 1.    \n\t\t\t\t Value greater than one may indicate packet\n\t\t\t\t loss. If packet with lower sequence is\n\t\t\t\t received, the value will be set to zero.\n\t\t\t\t If base sequence has been restarted, the\n\t\t\t\t value will be one.\t\t\t    */\n};\n\n\n/**\n * RTP session settings.\n */\ntypedef struct pjmedia_rtp_session_setting\n{\n    pj_uint8_t\t     flags;\t    /**< Bitmask flags to specify whether such\n\t\t\t\t         field is set. Bitmask contents are:\n\t\t\t\t\t (bit #0 is LSB)\n\t\t\t\t\t bit #0: default payload type\n\t\t\t\t\t bit #1: sender SSRC\n\t\t\t\t\t bit #2: sequence\n\t\t\t\t\t bit #3: timestamp\t\t    */\n    int\t\t     default_pt;    /**< Default payload type.\t\t    */\n    pj_uint32_t\t     sender_ssrc;   /**< Sender SSRC.\t\t\t    */\n    pj_uint16_t\t     seq;\t    /**< Sequence.\t\t\t    */\n    pj_uint32_t\t     ts;\t    /**< Timestamp.\t\t\t    */\n} pjmedia_rtp_session_setting;\n\n\n/**\n * @see pjmedia_rtp_status\n */\ntypedef struct pjmedia_rtp_status pjmedia_rtp_status;\n\n\n/**\n * This function will initialize the RTP session according to given parameters.\n *\n * @param ses\t\tThe session.\n * @param default_pt\tDefault payload type.\n * @param sender_ssrc\tSSRC used for outgoing packets, in host byte order.\n *\n * @return\t\tPJ_SUCCESS if successfull.\n */\nPJ_DECL(pj_status_t) pjmedia_rtp_session_init( pjmedia_rtp_session *ses,\n\t\t\t\t\t       int default_pt, \n\t\t\t\t\t       pj_uint32_t sender_ssrc );\n\n/**\n * This function will initialize the RTP session according to given parameters\n * defined in RTP session settings.\n *\n * @param ses\t\tThe session.\n * @param settings\tRTP session settings.\n *\n * @return\t\tPJ_SUCCESS if successfull.\n */\nPJ_DECL(pj_status_t) pjmedia_rtp_session_init2( \n\t\t\t\t    pjmedia_rtp_session *ses,\n\t\t\t\t    pjmedia_rtp_session_setting settings);\n\n\n/**\n * Create the RTP header based on arguments and current state of the RTP\n * session.\n *\n * @param ses\t\tThe session.\n * @param pt\t\tPayload type.\n * @param m\t\tMarker flag.\n * @param payload_len\tPayload length in bytes.\n * @param ts_len\tTimestamp length.\n * @param rtphdr\tUpon return will point to RTP packet header.\n * @param hdrlen\tUpon return will indicate the size of RTP packet header\n *\n * @return\t\tPJ_SUCCESS if successfull.\n */\nPJ_DECL(pj_status_t) pjmedia_rtp_encode_rtp( pjmedia_rtp_session *ses, \n\t\t\t\t\t     int pt, int m,\n\t\t\t\t\t     int payload_len, int ts_len,\n\t\t\t\t\t     const void **rtphdr, \n\t\t\t\t\t     int *hdrlen );\n\n/**\n * This function decodes incoming packet into RTP header and payload.\n * The decode function is guaranteed to point the payload to the correct \n * position regardless of any options present in the RTP packet.\n *\n * Note that this function does not modify the returned RTP header to\n * host byte order.\n *\n * @param ses\t\tThe session.\n * @param pkt\t\tThe received RTP packet.\n * @param pkt_len\tThe length of the packet.\n * @param hdr\t\tUpon return will point to the location of the RTP \n *\t\t\theader inside the packet. Note that the RTP header\n *\t\t\twill be given back as is, meaning that the fields\n *\t\t\twill be in network byte order.\n * @param payload\tUpon return will point to the location of the\n *\t\t\tpayload inside the packet.\n * @param payloadlen\tUpon return will indicate the size of the payload.\n *\n * @return\t\tPJ_SUCCESS if successfull.\n */\nPJ_DECL(pj_status_t) pjmedia_rtp_decode_rtp( pjmedia_rtp_session *ses, \n\t\t\t\t\t     const void *pkt, int pkt_len,\n\t\t\t\t\t     const pjmedia_rtp_hdr **hdr,\n\t\t\t\t\t     const void **payload,\n\t\t\t\t\t     unsigned *payloadlen);\n\n/**\n * Call this function everytime an RTP packet is received to check whether \n * the packet can be received and to let the RTP session performs its internal\n * calculations.\n *\n * @param ses\t    The session.\n * @param hdr\t    The RTP header of the incoming packet. The header must\n *\t\t    be given with fields in network byte order.\n * @param seq_st    Optional structure to receive the status of the RTP packet\n *\t\t    processing.\n */\nPJ_DECL(void) pjmedia_rtp_session_update( pjmedia_rtp_session *ses, \n\t\t\t\t\t  const pjmedia_rtp_hdr *hdr,\n\t\t\t\t\t  pjmedia_rtp_status *seq_st);\n\n\n/**\n * Call this function everytime an RTP packet is received to check whether \n * the packet can be received and to let the RTP session performs its internal\n * calculations.\n *\n * @param ses\t    The session.\n * @param hdr\t    The RTP header of the incoming packet. The header must\n *\t\t    be given with fields in network byte order.\n * @param seq_st    Optional structure to receive the status of the RTP packet\n *\t\t    processing.\n * @param check_pt  Flag to indicate whether payload type needs to be validate.\n *\n * @see pjmedia_rtp_session_update()\n */\nPJ_DECL(void) pjmedia_rtp_session_update2(pjmedia_rtp_session *ses, \n\t\t\t\t\t  const pjmedia_rtp_hdr *hdr,\n\t\t\t\t\t  pjmedia_rtp_status *seq_st,\n\t\t\t\t\t  pj_bool_t check_pt);\n\n\n/*\n * INTERNAL:\n */\n\n/** \n * Internal function for creating sequence number control, shared by RTCP \n * implementation. \n *\n * @param seq_ctrl  The sequence control instance.\n * @param seq\t    Sequence number to initialize.\n */\nvoid pjmedia_rtp_seq_init(pjmedia_rtp_seq_session *seq_ctrl, \n\t\t\t  pj_uint16_t seq);\n\n\n/** \n * Internal function update sequence control, shared by RTCP implementation.\n *\n * @param seq_ctrl\tThe sequence control instance.\n * @param seq\t\tSequence number to update.\n * @param seq_status\tOptional structure to receive additional information \n *\t\t\tabout the packet.\n */\nvoid pjmedia_rtp_seq_update( pjmedia_rtp_seq_session *seq_ctrl, \n\t\t\t     pj_uint16_t seq,\n\t\t\t     pjmedia_rtp_status *seq_status);\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_RTP_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/sdp.h",
    "content": "/* $Id: sdp.h 4367 2013-02-21 20:49:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_SDP_H__\n#define __PJMEDIA_SDP_H__\n\n/**\n * @file sdp.h\n * @brief SDP header file.\n */\n#include <pjmedia/types.h>\n#include <pj/sock.h>\n\n/**\n * @defgroup PJMEDIA_SDP SDP Parsing and Data Structure\n * @ingroup PJMEDIA_SESSION\n * @brief SDP data structure representation and parsing\n * @{\n *\n * The basic SDP session descriptor and elements are described in header\n * file <b><pjmedia/sdp.h></b>. This file contains declaration for\n * SDP session descriptor and SDP media descriptor, along with their\n * attributes. This file also declares functions to parse SDP message.\n */\n\n\nPJ_BEGIN_DECL\n\n/**\n * The PJMEDIA_MAX_SDP_FMT macro defines maximum format in a media line.\n */\n#ifndef PJMEDIA_MAX_SDP_FMT\n#   define PJMEDIA_MAX_SDP_FMT\t\t32\n#endif\n\n/**\n * The PJMEDIA_MAX_SDP_BANDW macro defines maximum bandwidth information\n * lines in a media line.\n */\n#ifndef PJMEDIA_MAX_SDP_BANDW\n#   define PJMEDIA_MAX_SDP_BANDW\t4\n#endif\n\n/**\n * The PJMEDIA_MAX_SDP_ATTR macro defines maximum SDP attributes in media and\n * session descriptor.\n */\n#ifndef PJMEDIA_MAX_SDP_ATTR\n#   define PJMEDIA_MAX_SDP_ATTR\t\t(PJMEDIA_MAX_SDP_FMT*2 + 4)\n#endif\n\n/**\n * The PJMEDIA_MAX_SDP_MEDIA macro defines maximum SDP media lines in a\n * SDP session descriptor.\n */\n#ifndef PJMEDIA_MAX_SDP_MEDIA\n#   define PJMEDIA_MAX_SDP_MEDIA\t16\n#endif\n\n\n/* **************************************************************************\n * SDP ATTRIBUTES\n ***************************************************************************\n */\n\n/** \n * Generic representation of attribute.\n */\nstruct pjmedia_sdp_attr\n{\n    pj_str_t\t\tname;\t    /**< Attribute name.    */\n    pj_str_t\t\tvalue;\t    /**< Attribute value.   */\n};\n\n/**\n * @see pjmedia_sdp_attr\n */\ntypedef struct pjmedia_sdp_attr pjmedia_sdp_attr;\n\n\n/**\n * Create SDP attribute.\n *\n * @param pool\t\tPool to create the attribute.\n * @param name\t\tAttribute name.\n * @param value\t\tOptional attribute value.\n *\n * @return\t\tThe new SDP attribute.\n */\nPJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_create(pj_pool_t *pool,\n\t\t\t\t\t\t   const char *name,\n\t\t\t\t\t\t   const pj_str_t *value);\n\n/** \n * Clone attribute \n *\n * @param pool\t\tPool to be used.\n * @param attr\t\tThe attribute to clone.\n *\n * @return\t\tNew attribute as cloned from the attribute.\n */\nPJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_clone(pj_pool_t *pool, \n\t\t\t\t\t\t  const pjmedia_sdp_attr*attr);\n\n/** \n * Find the first attribute with the specified type.\n *\n * @param count\t\tNumber of attributes in the array.\n * @param attr_array\tArray of attributes.\n * @param name\t\tAttribute name to find.\n * @param fmt\t\tOptional string to indicate which payload format\n *\t\t\tto find for \\a rtpmap and \\a fmt attributes. For other\n *\t\t\ttypes of attributes, the value should be NULL.\n *\n * @return\t\tThe specified attribute, or NULL if it can't be found.\n *\n * @see pjmedia_sdp_attr_find2, pjmedia_sdp_media_find_attr, \n *\tpjmedia_sdp_media_find_attr2\n */\nPJ_DECL(pjmedia_sdp_attr*) \npjmedia_sdp_attr_find(unsigned count, \n\t\t      pjmedia_sdp_attr *const attr_array[],\n\t\t      const pj_str_t *name, const pj_str_t *fmt);\n\n/** \n * Find the first attribute with the specified type.\n *\n * @param count\t\tNumber of attributes in the array.\n * @param attr_array\tArray of attributes.\n * @param name\t\tAttribute name to find.\n * @param fmt\t\tOptional string to indicate which payload format\n *\t\t\tto find for \\a rtpmap and \\a fmt attributes. For other\n *\t\t\ttypes of attributes, the value should be NULL.\n *\n * @return\t\tThe specified attribute, or NULL if it can't be found.\n *\n * @see pjmedia_sdp_attr_find, pjmedia_sdp_media_find_attr,\n *\tpjmedia_sdp_media_find_attr2\n */\nPJ_DECL(pjmedia_sdp_attr*) \npjmedia_sdp_attr_find2(unsigned count, \n\t\t       pjmedia_sdp_attr *const attr_array[],\n\t\t       const char *name, const pj_str_t *fmt);\n\n/**\n * Add a new attribute to array of attributes.\n *\n * @param count\t\tNumber of attributes in the array.\n * @param attr_array\tArray of attributes.\n * @param attr\t\tThe attribute to add.\n *\n * @return\t\tPJ_SUCCESS or the error code.\n *\n * @see pjmedia_sdp_media_add_attr\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_attr_add(unsigned *count,\n\t\t\t\t\t  pjmedia_sdp_attr *attr_array[],\n\t\t\t\t\t  pjmedia_sdp_attr *attr);\n\n/**\n * Remove all attributes with the specified name in array of attributes.\n *\n * @param count\t\tNumber of attributes in the array.\n * @param attr_array\tArray of attributes.\n * @param name\t\tAttribute name to find.\n *\n * @return\t\tNumber of attributes removed.\n *\n * @see pjmedia_sdp_media_remove_all_attr\n */\nPJ_DECL(unsigned) pjmedia_sdp_attr_remove_all(unsigned *count,\n\t\t\t\t\t      pjmedia_sdp_attr *attr_array[],\n\t\t\t\t\t      const char *name);\n\n\n/**\n * Remove the specified attribute from the attribute array.\n *\n * @param count\t\tNumber of attributes in the array.\n * @param attr_array\tArray of attributes.\n * @param attr\t\tThe attribute instance to remove.\n *\n * @return\t\tPJ_SUCCESS when attribute has been removed, or \n *\t\t\tPJ_ENOTFOUND when the attribute can not be found.\n *\n * @see pjmedia_sdp_media_remove_attr\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_attr_remove(unsigned *count,\n\t\t\t\t\t     pjmedia_sdp_attr *attr_array[],\n\t\t\t\t\t     pjmedia_sdp_attr *attr);\n\n\n/**\n * This structure declares SDP \\a rtpmap attribute.\n */\nstruct pjmedia_sdp_rtpmap\n{\n    pj_str_t\t\tpt;\t    /**< Payload type.\t    */\n    pj_str_t\t\tenc_name;   /**< Encoding name.\t    */\n    unsigned\t\tclock_rate; /**< Clock rate.\t    */\n    pj_str_t\t\tparam;\t    /**< Parameter.\t    */\n};\n\n/**\n * @see pjmedia_sdp_rtpmap\n */\ntypedef struct pjmedia_sdp_rtpmap pjmedia_sdp_rtpmap;\n\n\n/**\n * Convert generic attribute to SDP \\a rtpmap. This function allocates\n * a new attribute and call #pjmedia_sdp_attr_get_rtpmap().\n *\n * @param pool\t\tPool used to create the rtpmap attribute.\n * @param attr\t\tGeneric attribute to be converted to rtpmap, which\n *\t\t\tname must be \"rtpmap\".\n * @param p_rtpmap\tPointer to receive SDP rtpmap attribute.\n *\n * @return\t\tPJ_SUCCESS if the attribute can be successfully\n *\t\t\tconverted to \\a rtpmap type.\n *\n * @see pjmedia_sdp_attr_get_rtpmap\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_attr_to_rtpmap(pj_pool_t *pool,\n\t\t\t\t\t\tconst pjmedia_sdp_attr *attr,\n\t\t\t\t\t\tpjmedia_sdp_rtpmap **p_rtpmap);\n\n\n/**\n * Get the rtpmap representation of the same SDP attribute.\n *\n * @param attr\t\tGeneric attribute to be converted to rtpmap, which\n *\t\t\tname must be \"rtpmap\".\n * @param rtpmap\tSDP \\a rtpmap attribute to be initialized.\n *\n * @return\t\tPJ_SUCCESS if the attribute can be successfully\n *\t\t\tconverted to \\a rtpmap attribute.\n *\n * @see pjmedia_sdp_attr_to_rtpmap\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_attr_get_rtpmap(const pjmedia_sdp_attr *attr,\n\t\t\t\t\t\t pjmedia_sdp_rtpmap *rtpmap);\n\n\n/**\n * Convert \\a rtpmap attribute to generic attribute.\n *\n * @param pool\t\tPool to be used.\n * @param rtpmap\tThe \\a rtpmap attribute.\n * @param p_attr\tPointer to receive the generic SDP attribute.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_sdp_rtpmap_to_attr( pj_pool_t *pool,\n\t\t\t    const pjmedia_sdp_rtpmap *rtpmap,\n\t\t\t    pjmedia_sdp_attr **p_attr);\n\n\n/**\n * This structure describes SDP \\a fmtp attribute.\n */\ntypedef struct pjmedia_sdp_fmtp\n{\n    pj_str_t\t\tfmt;\t    /**< Format type.\t\t    */\n    pj_str_t\t\tfmt_param;  /**< Format specific parameter. */\n} pjmedia_sdp_fmtp;\n\n\n/**\n * Get the fmtp representation of the same SDP attribute.\n *\n * @param attr\t\tGeneric attribute to be converted to fmtp, which\n *\t\t\tname must be \"fmtp\".\n * @param fmtp\t\tSDP fmtp attribute to be initialized.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_attr_get_fmtp(const pjmedia_sdp_attr *attr,\n\t\t\t\t\t       pjmedia_sdp_fmtp *fmtp);\n\n\n/**\n * This structure describes SDP \\a rtcp attribute.\n */\ntypedef struct pjmedia_sdp_rtcp_attr\n{\n    unsigned\tport;\t    /**< RTCP port number.\t    */\n    pj_str_t\tnet_type;   /**< Optional network type.\t    */\n    pj_str_t\taddr_type;  /**< Optional address type.\t    */\n    pj_str_t\taddr;\t    /**< Optional address.\t    */\n} pjmedia_sdp_rtcp_attr;\n\n\n/**\n * Parse a generic SDP attribute to get SDP rtcp attribute values.\n *\n * @param attr\t\tGeneric attribute to be converted to rtcp, which\n *\t\t\tname must be \"rtcp\".\n * @param rtcp\t\tSDP rtcp attribute to be initialized.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_attr_get_rtcp(const pjmedia_sdp_attr *attr,\n\t\t\t\t\t       pjmedia_sdp_rtcp_attr *rtcp);\n\n\n/**\n * Create a=rtcp attribute.\n *\n * @param pool\t\tPool to create the attribute.\n * @param a\t\tSocket address.\n *\n * @return\t\tSDP RTCP attribute.\n */\nPJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_create_rtcp(pj_pool_t *pool,\n\t\t\t\t\t\t\tconst pj_sockaddr *a);\n\n\n/* **************************************************************************\n * SDP CONNECTION INFO\n ****************************************************************************\n */\n\n/**\n * This structure describes SDP connection info (\"c=\" line). \n */\nstruct pjmedia_sdp_conn\n{\n    pj_str_t\tnet_type;\t/**< Network type (\"IN\").\t\t*/\n    pj_str_t\taddr_type;\t/**< Address type (\"IP4\", \"IP6\").\t*/\n    pj_str_t\taddr;\t\t/**< The address.\t\t\t*/\n};\n\n\n/**\n * @see pjmedia_sdp_conn\n */\ntypedef struct pjmedia_sdp_conn pjmedia_sdp_conn;\n\n\n/** \n * Clone connection info. \n * \n * @param pool\t    Pool to allocate memory for the new connection info.\n * @param rhs\t    The connection into to clone.\n *\n * @return\t    The new connection info.\n */\nPJ_DECL(pjmedia_sdp_conn*) pjmedia_sdp_conn_clone(pj_pool_t *pool, \n\t\t\t\t\t\t  const pjmedia_sdp_conn *rhs);\n\n\n/** \n * Compare connection info. \n * \n * @param conn1\t    The first connection info to compare.\n * @param conn1\t    The second connection info to compare.\n * @param option    Comparison option, which should be zero for now.\n *\n * @return\t    PJ_SUCCESS when both connection info are equal, otherwise\n *\t\t    returns PJMEDIA_SDP_ECONNNOTEQUAL.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_conn_cmp(const pjmedia_sdp_conn *conn1, \n\t\t\t\t\t  const pjmedia_sdp_conn *conn2,\n\t\t\t\t\t  unsigned option);\n\n\n/* **************************************************************************\n * SDP BANDWIDTH INFO\n ****************************************************************************\n */\n\n/**\n * This structure describes SDP bandwidth info (\"b=\" line). \n */\ntypedef struct pjmedia_sdp_bandw\n{\n    pj_str_t\tmodifier;\t/**< Bandwidth modifier.\t\t*/\n    pj_uint32_t\tvalue;\t        /**< Bandwidth value.\t                */\n} pjmedia_sdp_bandw;\n\n\n/** \n * Clone bandwidth info. \n * \n * @param pool\t    Pool to allocate memory for the new bandwidth info.\n * @param rhs\t    The bandwidth into to clone.\n *\n * @return\t    The new bandwidth info.\n */\nPJ_DECL(pjmedia_sdp_bandw*)\npjmedia_sdp_bandw_clone(pj_pool_t *pool, const pjmedia_sdp_bandw *rhs);\n\n\n\n/* **************************************************************************\n * SDP MEDIA INFO/LINE\n ****************************************************************************\n */\n\n/**\n * This structure describes SDP media descriptor. A SDP media descriptor\n * starts with \"m=\" line and contains the media attributes and optional\n * connection line.\n */\nstruct pjmedia_sdp_media\n{\n    /** Media descriptor line (\"m=\" line) */\n    struct\n    {\n\tpj_str_t    media;\t\t/**< Media type (\"audio\", \"video\")  */\n\tpj_uint16_t port;\t\t/**< Port number.\t\t    */\n\tunsigned    port_count;\t\t/**< Port count, used only when >2  */\n\tpj_str_t    transport;\t\t/**< Transport (\"RTP/AVP\")\t    */\n\tunsigned    fmt_count;\t\t/**< Number of formats.\t\t    */\n\tpj_str_t    fmt[PJMEDIA_MAX_SDP_FMT];       /**< Media formats.\t    */\n    } desc;\n\n    pjmedia_sdp_conn   *conn;\t\t/**< Optional connection info.\t    */\n    unsigned\t        bandw_count;\t/**< Number of bandwidth info.\t    */\n    pjmedia_sdp_bandw  *bandw[PJMEDIA_MAX_SDP_BANDW]; /**< Bandwidth info.  */\n    unsigned\t        attr_count;\t/**< Number of attributes.\t    */\n    pjmedia_sdp_attr   *attr[PJMEDIA_MAX_SDP_ATTR];   /**< Attributes.\t    */\n\n};\n\n\n/**\n * @see pjmedia_sdp_media\n */\ntypedef struct pjmedia_sdp_media pjmedia_sdp_media;\n\n\n/** \n * Clone SDP media description. \n *\n * @param pool\t    Pool to allocate memory for the new media description.\n * @param rhs\t    The media descriptin to clone.\n *\n * @return\t    New media description.\n */\nPJ_DECL(pjmedia_sdp_media*) \npjmedia_sdp_media_clone( pj_pool_t *pool, \n\t\t\t const pjmedia_sdp_media *rhs);\n\n/**\n * Find the first occurence of the specified attribute name in the media \n * descriptor. Optionally the format may be specified.\n *\n * @param m\t\tThe SDP media description.\n * @param name\t\tAttribute name to find.\n * @param fmt\t\tOptional payload type to match in the\n *\t\t\tattribute list, when the attribute is \\a rtpmap\n *\t\t\tor \\a fmtp. For other types of SDP attributes, this\n *\t\t\tvalue should be NULL.\n *\n * @return\t\tThe first instance of the specified attribute or NULL.\n */\nPJ_DECL(pjmedia_sdp_attr*) \npjmedia_sdp_media_find_attr(const pjmedia_sdp_media *m,\n\t\t\t    const pj_str_t *name, const pj_str_t *fmt);\n\n\n/**\n * Find the first occurence of the specified attribute name in the SDP media \n * descriptor. Optionally the format may be specified.\n *\n * @param m\t\tThe SDP media description.\n * @param name\t\tAttribute name to find.\n * @param fmt\t\tOptional payload type to match in the\n *\t\t\tattribute list, when the attribute is \\a rtpmap\n *\t\t\tor \\a fmtp. For other types of SDP attributes, this\n *\t\t\tvalue should be NULL.\n *\n * @return\t\tThe first instance of the specified attribute or NULL.\n */\nPJ_DECL(pjmedia_sdp_attr*) \npjmedia_sdp_media_find_attr2(const pjmedia_sdp_media *m,\n\t\t\t     const char *name, const pj_str_t *fmt);\n\n/**\n * Add new attribute to the media descriptor.\n *\n * @param m\t\tThe SDP media description.\n * @param attr\t\tAttribute to add.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_media_add_attr(pjmedia_sdp_media *m,\n\t\t\t\t\t\tpjmedia_sdp_attr *attr);\n\n/**\n * Remove all attributes with the specified name from the SDP media\n * descriptor.\n *\n * @param m\t\tThe SDP media description.\n * @param name\t\tAttribute name to remove.\n *\n * @return\t\tThe number of attributes removed.\n */\nPJ_DECL(unsigned) \npjmedia_sdp_media_remove_all_attr(pjmedia_sdp_media *m,\n\t\t\t\t  const char *name);\n\n\n/**\n * Remove the occurence of the specified attribute from the SDP media\n * descriptor.\n *\n * @param m\t\tThe SDP media descriptor.\n * @param attr\t\tThe attribute to find and remove.\n *\n * @return\t\tPJ_SUCCESS if the attribute can be found and has\n *\t\t\tbeen removed from the array.\n */\nPJ_DECL(pj_status_t)\npjmedia_sdp_media_remove_attr(pjmedia_sdp_media *m,\n\t\t\t      pjmedia_sdp_attr *attr);\n\n\n/**\n * Compare two SDP media for equality.\n *\n * @param sd1\t    The first SDP media to compare.\n * @param sd2\t    The second SDP media to compare.\n * @param option    Comparison option, which should be zero for now.\n *\n * @return\t    PJ_SUCCESS when both SDP medias are equal, or the\n *\t\t    appropriate status code describing which part of\n *\t\t    the descriptors that are not equal.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_media_cmp(const pjmedia_sdp_media *sd1,\n\t\t\t\t\t   const pjmedia_sdp_media *sd2,\n\t\t\t\t\t   unsigned option);\n\n\n/**\n * Compare two media transports for compatibility.\n *\n * @param t1\t    The first media transport to compare.\n * @param t2\t    The second media transport to compare.\n *\n * @return\t    PJ_SUCCESS when both media transports are compatible,\n *\t\t    otherwise returns PJMEDIA_SDP_ETPORTNOTEQUAL.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_transport_cmp(const pj_str_t *t1,\n\t\t\t\t\t       const pj_str_t *t2);\n\n\n/**\n * Deactivate SDP media.\n *\n * @param pool\t    Memory pool to allocate memory from.\n * @param m\t    The SDP media to deactivate.\n *\n * @return\t    PJ_SUCCESS when SDP media successfully deactivated,\n *\t\t    otherwise appropriate status code returned.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_media_deactivate(pj_pool_t *pool,\n\t\t\t\t\t\t  pjmedia_sdp_media *m);\n\n\n/**\n * Clone SDP media description and deactivate the new SDP media.\n *\n * @param pool\t    Memory pool to allocate memory for the clone.\n * @param rhs\t    The SDP media to clone.\n *\n * @return\t    New media descrption with deactivated indication.\n */\nPJ_DECL(pjmedia_sdp_media*) pjmedia_sdp_media_clone_deactivate(\n\t\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\t\tconst pjmedia_sdp_media *rhs);\n\n\n/* **************************************************************************\n * SDP SESSION DESCRIPTION\n ****************************************************************************\n */\n\n\n/**\n * This structure describes SDP session description. A SDP session descriptor\n * contains complete information about a session, and normally is exchanged\n * with remote media peer using signaling protocol such as SIP.\n */\nstruct pjmedia_sdp_session\n{\n    /** Session origin (o= line) */\n    struct\n    {\n\tpj_str_t    user;\t    /**< User \t\t\t\t*/\n\tpj_uint32_t id;\t\t    /**< Session ID\t\t\t*/\n\tpj_uint32_t version;\t    /**< Session version\t\t*/\n\tpj_str_t    net_type;\t    /**< Network type (\"IN\")\t\t*/\n\tpj_str_t    addr_type;\t    /**< Address type (\"IP4\", \"IP6\")\t*/\n\tpj_str_t    addr;\t    /**< The address.\t\t\t*/\n    } origin;\n\n    pj_str_t\t       name;\t    /**< Subject line (s=)\t\t*/\n    pjmedia_sdp_conn  *conn;\t    /**< Connection line (c=)\t\t*/\n    unsigned\t       bandw_count; /**< Number of bandwidth info (b=)\t*/\n    pjmedia_sdp_bandw *bandw[PJMEDIA_MAX_SDP_BANDW];\n\t\t\t\t    /**< Bandwidth info array (b=)\t*/\n    \n    /** Session time (t= line)\t*/\n    struct\n    {\n\tpj_uint32_t start;\t    /**< Start time.\t\t\t*/\n\tpj_uint32_t stop;\t    /**< Stop time.\t\t\t*/\n    } time;\n\n    unsigned\t       attr_count;\t\t/**< Number of attributes.  */\n    pjmedia_sdp_attr  *attr[PJMEDIA_MAX_SDP_ATTR]; /**< Attributes array.   */\n\n    unsigned\t       media_count;\t\t/**< Number of media.\t    */\n    pjmedia_sdp_media *media[PJMEDIA_MAX_SDP_MEDIA];\t/**< Media array.   */\n\n};\n\n/**\n * @see pjmedia_sdp_session\n */\ntypedef struct pjmedia_sdp_session pjmedia_sdp_session;\n\n\n\n/**\n * Parse SDP message.\n *\n * @param pool\t    The pool to allocate SDP session description.\n * @param buf\t    The message buffer.\n * @param len\t    The length of the message.\n * @param p_sdp\t    Pointer to receive the SDP session descriptor.\n *\n * @return\t    PJ_SUCCESS if message was successfully parsed into\n *\t\t    SDP session descriptor.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_parse( pj_pool_t *pool,\n\t\t\t\t        char *buf, pj_size_t len, \n\t\t\t\t\tpjmedia_sdp_session **p_sdp );\n\n/**\n * Print SDP description to a buffer.\n *\n * @param sdp\t    The SDP session description.\n * @param buf\t    The buffer.\n * @param size\t    The buffer length.\n *\n * @return\t    the length printed, or -1 if the buffer is too\n *\t\t    short.\n */\nPJ_DECL(int) pjmedia_sdp_print( const pjmedia_sdp_session *sdp, \n\t\t\t\tchar *buf, pj_size_t size);\n\n\n/**\n * Perform semantic validation for the specified SDP session descriptor.\n * This function perform validation beyond just syntactic verification,\n * such as to verify the value of network type and address type, check\n * the connection line, and verify that \\a rtpmap attribute is present\n * when dynamic payload type is used.\n *\n * @param sdp\t    The SDP session descriptor to validate.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_validate(const pjmedia_sdp_session *sdp);\n\n\n/**\n * Perform semantic validation for the specified SDP session descriptor.\n * This function perform validation beyond just syntactic verification,\n * such as to verify the value of network type and address type, check\n * the connection line, and verify that \\a rtpmap attribute is present\n * when dynamic payload type is used.\n *\n * @param sdp\t    The SDP session descriptor to validate.\n * @param strict    Flag whether the check should be strict, i.e: allow\n *\t\t    media without connection line when port is zero.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_validate2(const pjmedia_sdp_session *sdp,\n\t\t\t\t\t   pj_bool_t strict);\n\n\n/**\n * Clone SDP session descriptor.\n *\n * @param pool\t    The pool used to clone the session.\n * @param sdp\t    The SDP session to clone.\n *\n * @return\t    New SDP session.\n */\nPJ_DECL(pjmedia_sdp_session*) \npjmedia_sdp_session_clone( pj_pool_t *pool,\n\t\t\t   const pjmedia_sdp_session *sdp);\n\n\n/**\n * Compare two SDP session for equality.\n *\n * @param sd1\t    The first SDP session to compare.\n * @param sd2\t    The second SDP session to compare.\n * @param option    Must be zero for now.\n *\n * @return\t    PJ_SUCCESS when both SDPs are equal, or otherwise\n *\t\t    the status code indicates which part of the session\n *\t\t    descriptors are not equal.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_session_cmp(const pjmedia_sdp_session *sd1,\n\t\t\t\t\t     const pjmedia_sdp_session *sd2,\n\t\t\t\t\t     unsigned option);\n\n\n/**\n * Add new attribute to the session descriptor.\n *\n * @param s\t\tThe SDP session description.\n * @param attr\t\tAttribute to add.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_session_add_attr(pjmedia_sdp_session *s,\n\t\t\t\t\t\t  pjmedia_sdp_attr *attr);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_SDP_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/sdp_neg.h",
    "content": "/* $Id: sdp_neg.h 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_SDP_NEG_H__\n#define __PJMEDIA_SDP_NEG_H__\n\n\n/**\n * @file sdp_neg.h\n * @brief SDP negotiator header file.\n */\n/**\n * @defgroup PJMEDIA_SDP_NEG SDP Negotiation State Machine (Offer/Answer Model, RFC 3264)\n * @ingroup PJMEDIA_SESSION\n * @brief SDP Negotiation State Machine (Offer/Answer Model, RFC 3264)\n * @{\n *\n * The header file <b><pjmedia/sdp_neg.h></b> contains the declaration\n * of SDP offer and answer negotiator. SDP offer and answer model is described\n * in RFC 3264 <b>\"An Offer/Answer Model with Session Description Protocol \n * (SDP)\"</b>.\n *\n * The SDP negotiator is represented with opaque type \\a pjmedia_sdp_neg.\n * This structure contains negotiation state and several SDP session \n * descriptors currently being used in the negotiation.\n *\n *\n * \\section sdpneg_state_dia SDP Negotiator State Diagram\n *\n * The following diagram describes the state transition diagram of the\n * SDP negotiator.\n * \n * <pre>\n *                                              \n *                                              modify_local_offer()\n *     create_w_local_offer()  +-------------+  send_local_offer()\n *     ----------------------->| LOCAL_OFFER |<-----------------------\n *    |                        +-------------+______                  |\n *    |                               |             \\_____________    |\n *    |           set_remote_answer() |           cancel_offer()  \\   |\n *    |                               V                            v  |\n * +--+---+                     +-----------+     negotiate()     +-~----+\n * | NULL |                     | WAIT_NEGO |-------------------->| DONE |\n * +------+                     +-----------+                     +------+\n *    |                               A      ______________________^  |\n *    |            set_local_answer() |     /     cancel_offer()      |\n *    |                               |    /                          |\n *    |                        +--------------+   set_remote_offer()  |\n *     ----------------------->| REMOTE_OFFER |<----------------------\n *     create_w_remote_offer() +--------------+\n *\n * </pre>\n *\n *\n *\n * \\section sdpneg_offer_answer SDP Offer/Answer Model with Negotiator\n *\n * \\subsection sdpneg_create_offer Creating Initial Offer\n *\n * Application creates an offer by manualy building the SDP session descriptor\n * (pjmedia_sdp_session), or request PJMEDIA endpoint (pjmedia_endpt) to \n * create SDP session descriptor based on capabilities that present in the\n * endpoint by calling #pjmedia_endpt_create_sdp().\n *\n * Application then creates SDP negotiator instance by calling\n * #pjmedia_sdp_neg_create_w_local_offer(), passing the SDP offer in the\n * function arguments. The SDP negotiator keeps a copy of current local offer,\n * and update its state to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER.\n *\n * Application can then send the initial SDP offer that it creates to\n * remote peer using signaling protocol such as SIP.\n *\n *\n * \\subsection sdpneg_subseq_offer Generating Subsequent Offer\n *\n * The negotiator can only create subsequent offer after it has finished\n * the negotiation process of previous offer/answer session (i.e. the\n * negotiator state is PJMEDIA_SDP_NEG_STATE_DONE).\n *\n * If any previous negotiation process was successfull (i.e. the return \n * value of #pjmedia_sdp_neg_negotiate() was PJ_SUCCESS), the negotiator\n * keeps both active local and active remote SDP.\n *\n * If application does not want send modified offer, it can just send\n * the active local SDP as the offer. In this case, application calls\n * #pjmedia_sdp_neg_send_local_offer() to get the active local SDP.\n * \n * If application wants to modify it's local offer, it MUST inform \n * the negotiator about the modified SDP by calling \n * #pjmedia_sdp_neg_modify_local_offer().\n *\n * In both cases, the negotiator will internally create a copy of the offer,\n * and move it's state to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, where it\n * waits until application passes the remote answer.\n *\n *\n * \\subsection sdpneg_receive_offer Receiving Initial Offer\n *\n * Application receives an offer in the incoming request from remote to\n * establish multimedia session, such as incoming INVITE message with SDP\n * body. \n *\n * Initially, when the initial offer is received, application creates the \n * SDP negotiator by calling #pjmedia_sdp_neg_create_w_remote_offer(),\n * specifying the remote SDP offer in one of the argument. \n *\n * At this stage, application may or may not ready to create an answer.\n * For example, a SIP B2BUA needs to make outgoing call and receive SDP\n * from the outgoing call leg in order to create a SDP answer to the\n * incoming call leg.\n *\n * If application is not ready to create an answer, it passes NULL as\n * the local SDP when it calls #pjmedia_sdp_neg_create_w_remote_offer().\n *\n * The section @ref sdpneg_create_answer describes the case when \n * application is ready to create a SDP answer.\n *\n *\n * \\subsection sdpneg_subseq_offer Receiving Subsequent Offer\n *\n * Application passes subsequent SDP offer received from remote by\n * calling #pjmedia_sdp_neg_set_remote_offer().\n *\n * The negotiator can only receive subsequent offer after it has finished\n * the negotiation process of previous offer/answer session (i.e. the\n * negotiator state is PJMEDIA_SDP_NEG_STATE_DONE).\n *\n *\n * \\subsection sdpneg_recv_answer Receiving SDP Answer\n *\n * When application receives SDP answer from remote, it informs the\n * negotiator by calling #pjmedia_sdp_neg_set_remote_answer(). The\n * negotiator validates the answer (#pjmedia_sdp_validate()), and if\n * succeeds, it moves it's state to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO.\n *\n * Application then instruct the negotiator to negotiate the remote\n * answer by calling #pjmedia_sdp_neg_negotiate(). The purpose of\n * this negotiation is to verify remote answer, and update the initial\n * offer according to the answer. For example, the initial offer may\n * specify that a stream is \\a sendrecv, while the answer specifies\n * that remote stream is \\a inactive. In this case, the negotiator\n * will update the stream in the local active media as \\a inactive\n * too.\n *\n * If #pjmedia_sdp_neg_negotiate() returns PJ_SUCCESS, the negotiator will\n * keep the updated local answer and remote answer internally. These two \n * SDPs are called active local SDP and active remote SDP, as it describes \n * currently active session.\n *\n * Application can retrieve the active local SDP by calling\n * #pjmedia_sdp_neg_get_active_local(), and active remote SDP by calling\n * #pjmedia_sdp_neg_get_active_remote().\n *\n * If #pjmedia_sdp_neg_negotiate() returns failure (i.e. not PJ_SUCCESS),\n * it WILL NOT update its active local and active remote SDP.\n *\n * Regardless of the return status of the #pjmedia_sdp_neg_negotiate(), \n * the negotiator state will move to PJMEDIA_SDP_NEG_STATE_DONE.\n * \n *\n * \\subsection sdpneg_cancel_offer Cancelling an Offer\n *\n * In other case, after an offer is generated (negotiator state is in\n * PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER), the answer may not be received, and\n * application wants the negotiator to reset itself to its previous state.\n * Consider this example:\n *\n *  - media has been established, and negotiator state is\n *    PJMEDIA_SDP_NEG_STATE_DONE.\n *  - application generates a new offer for re-INVITE, so in this case\n *    it would either call #pjmedia_sdp_neg_send_local_offer() or\n *    #pjmedia_sdp_neg_modify_local_offer()\n *  - the negotiator state moves to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER\n *  - the re-INVITE was rejected with an error\n *\n * Since an answer is not received, it is necessary to reset the negotiator\n * state back to PJMEDIA_SDP_NEG_STATE_DONE so that the negotiator can\n * create or receive new offer.\n *\n * This can be accomplished by calling #pjmedia_sdp_neg_cancel_offer(),\n * to reset the negotiator state back to PJMEDIA_SDP_NEG_STATE_DONE. In\n * this case, both active local and active remote will not be modified.\n *\n * \\subsection sdpneg_create_answer Generating SDP Answer\n *\n * After remote offer has been set in the negotiator, application can \n * request the SDP negotiator to generate appropriate answer based on local \n * capability.\n *\n * To do this, first the application MUST have an SDP describing its local\n * capabilities. This SDP can be built manually, or application can generate\n * SDP to describe local media endpoint capability by calling \n * #pjmedia_endpt_create_sdp(). When the application is a SIP B2BUA, \n * application can treat the SDP received from the outgoing call leg as if\n * it was it's local capability.\n * \n * The local SDP session descriptor DOES NOT have to match the SDP offer.\n * For example, it can have more or less media lines than the offer, or\n * their order may be different than the offer. The negotiator is capable\n * to match and reorder local SDP according to remote offer, and create\n * an answer that is suitable for the offer.\n *\n * After local SDP capability has been acquired, application can create\n * a SDP answer.\n *\n * If application does not already have the negotiator instance, it creates\n * one by calling #pjmedia_sdp_neg_create_w_remote_offer(), specifying \n * both remote SDP offer and local SDP as the arguments. The SDP negotiator\n * validates both remote and local SDP by calling #pjmedia_sdp_validate(),\n * and if both SDPs are valid, the negotiator state will move to\n * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO where it is ready to negotiate the\n * offer and answer.\n *\n * If application already has the negotiator instance, it sets the local\n * SDP in the negotiator by calling #pjmedia_sdp_neg_set_local_answer().\n * The SDP negotiator then validates local SDP (#pjmedia_sdp_validate() ),\n * and if it is  valid, the negotiator state will move to\n * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO where it is ready to negotiate the\n * offer and answer.\n *\n * After the SDP negotiator state has moved to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO,\n * application calls #pjmedia_sdp_neg_negotiate() to instruct the SDP\n * negotiator to negotiate both offer and answer. This function returns\n * PJ_SUCCESS if an answer can be generated AND at least one media stream\n * is active in the session.\n *\n * If #pjmedia_sdp_neg_negotiate() returns PJ_SUCCESS, the negotiator will\n * keep the remote offer and local answer internally. These two SDPs are\n * called active local SDP and active remote SDP, as it describes currently\n * active session.\n *\n * Application can retrieve the active local SDP by calling\n * #pjmedia_sdp_neg_get_active_local(), and send this SDP to remote as the\n * SDP answer.\n *\n * If #pjmedia_sdp_neg_negotiate() returns failure (i.e. not PJ_SUCCESS),\n * it WILL NOT update its active local and active remote SDP.\n *\n * Regardless of the return status of the #pjmedia_sdp_neg_negotiate(), \n * the negotiator state will move to PJMEDIA_SDP_NEG_STATE_DONE.\n *\n *\n */\n\n#include <pjmedia/sdp.h>\n\nPJ_BEGIN_DECL\n\n/**\n * This enumeration describes SDP negotiation state. \n */\nenum pjmedia_sdp_neg_state\n{\n    /** \n     * This is the state of SDP negoator before it is initialized. \n     */\n    PJMEDIA_SDP_NEG_STATE_NULL,\n\n    /** \n     * This state occurs when SDP negotiator has sent our offer to remote and\n     * it is waiting for answer. \n     */\n    PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,\n\n    /** \n     * This state occurs when SDP negotiator has received offer from remote\n     * and currently waiting for local answer.\n     */\n    PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER,\n\n    /**\n     * This state occurs when an offer (either local or remote) has been \n     * provided with answer. The SDP negotiator is ready to negotiate both\n     * session descriptors. Application can call #pjmedia_sdp_neg_negotiate()\n     * immediately to begin negotiation process.\n     */\n    PJMEDIA_SDP_NEG_STATE_WAIT_NEGO,\n\n    /**\n     * This state occurs when SDP negotiation has completed, either \n     * successfully or not.\n     */\n    PJMEDIA_SDP_NEG_STATE_DONE\n};\n\n\n/**\n * @see pjmedia_sdp_neg_state\n */\ntypedef enum pjmedia_sdp_neg_state pjmedia_sdp_neg_state;\n\n\n/**\n * Opaque declaration of SDP negotiator.\n */\ntypedef struct pjmedia_sdp_neg pjmedia_sdp_neg;\n\n\n/**\n * Flags to be given to pjmedia_sdp_neg_modify_local_offer2().\n */\ntypedef enum pjmedia_mod_offer_flag\n{\n   /**\n    * Allow media type in the SDP to be changed.\n    * When generating a new offer, in the case that a media line doesn't match\n    * the active SDP, the new media line will be considered to replace the\n    * existing media at the same position.\n    */\n   PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE = 1\n\n} pjmedia_mod_offer_flag;\n\n\n/**\n * Get the state string description of the specified state.\n *\n * @param state\t\tNegotiator state.\n *\n * @return\t\tString description of the state.\n */\nPJ_DECL(const char*) pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_state state);\n\n\n/**\n * Create the SDP negotiator with local offer. The SDP negotiator then\n * will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER state, where it waits\n * until it receives answer from remote. When SDP answer from remote is\n * received, application must call #pjmedia_sdp_neg_set_remote_answer().\n *\n * After calling this function, application should send the local SDP offer\n * to remote party using signaling protocol such as SIP and wait for SDP \n * answer.\n *\n * @param pool\t\tPool to allocate memory. The pool's lifetime needs\n *\t\t\tto be valid for the duration of the negotiator.\n * @param local\t\tThe initial local capability.\n * @param p_neg\t\tPointer to receive the negotiator instance.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error\n *\t\t\tcode.\n */\nPJ_DECL(pj_status_t) \npjmedia_sdp_neg_create_w_local_offer( pj_pool_t *pool,\n\t\t\t\t      const pjmedia_sdp_session *local,\n\t\t\t\t      pjmedia_sdp_neg **p_neg);\n\n/**\n * Initialize the SDP negotiator with remote offer, and optionally\n * specify the initial local capability, if known. Application normally \n * calls this function when it receives initial offer from remote. \n *\n * If local media capability is specified, this capability will be set as\n * initial local capability of the negotiator, and after this function is\n * called, the SDP negotiator state will move to state\n * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and the negotiation function can be \n * called. \n *\n * If local SDP is not specified, the negotiator will not have initial local\n * capability, and after this function is called the negotiator state will \n * move to PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER state. Application MUST supply\n * local answer later with #pjmedia_sdp_neg_set_local_answer(), before\n * calling the negotiation function.\n *\n * @param pool\t\tPool to allocate memory. The pool's lifetime needs\n *\t\t\tto be valid for the duration of the negotiator.\n * @param initial\tOptional initial local capability.\n * @param remote\tThe remote offer.\n * @param p_neg\t\tPointer to receive the negotiator instance.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error\n *\t\t\tcode.\n */\nPJ_DECL(pj_status_t) \npjmedia_sdp_neg_create_w_remote_offer(pj_pool_t *pool,\n\t\t\t\t      const pjmedia_sdp_session *initial,\n\t\t\t\t      const pjmedia_sdp_session *remote,\n\t\t\t\t      pjmedia_sdp_neg **p_neg);\n\n/**\n * This specifies the behavior of the SDP negotiator when responding to an\n * offer, whether it should rather use the codec preference as set by\n * remote, or should it rather use the codec preference as specified by\n * local endpoint.\n *\n * For example, suppose incoming call has codec order \"8 0 3\", while \n * local codec order is \"3 0 8\". If remote codec order is preferable,\n * the selected codec will be 8, while if local codec order is preferable,\n * the selected codec will be 3.\n *\n * By default, the value in PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER will\n * be used.\n *\n * @param neg\t\tThe SDP negotiator instance.\n * @param prefer_remote\tIf non-zero, the negotiator will use the codec\n *\t\t\torder as specified in remote offer. If zero, it\n *\t\t\twill prefer to use the local codec order.\n */\nPJ_DECL(pj_status_t)\npjmedia_sdp_neg_set_prefer_remote_codec_order(pjmedia_sdp_neg *neg,\n\t\t\t\t\t      pj_bool_t prefer_remote);\n\n/**\n * This specifies the behavior of the SDP negotiator when responding to an\n * offer, whether it should answer with multiple formats or not.\n *\n * By default, the value in PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS will\n * be used.\n *\n * @param neg           The SDP negotiator instance.\n * @param answer_multiple\n *                      If non-zero, the negotiator will respond with\n *                      multiple formats. If zero only a single format\n *                      will be returned.\n */\nPJ_DECL(pj_status_t)\npjmedia_sdp_neg_set_answer_multiple_codecs(pjmedia_sdp_neg *neg,\n                                           pj_bool_t answer_multiple);\n\n\n/**\n * Get SDP negotiator state.\n *\n * @param neg\t\tThe SDP negotiator instance.\n *\n * @return\t\tThe negotiator state.\n */\nPJ_DECL(pjmedia_sdp_neg_state)\npjmedia_sdp_neg_get_state( pjmedia_sdp_neg *neg );\n\n/**\n * Get the currently active local SDP. Application can only call this\n * function after negotiation has been done, or otherwise there won't be\n * active SDPs. Calling this function will not change the state of the \n * negotiator.\n *\n * @param neg\t\tThe SDP negotiator instance.\n * @param local\t\tPointer to receive the local active SDP.\n *\n * @return\t\tPJ_SUCCESS if local active SDP is present.\n */\nPJ_DECL(pj_status_t) \npjmedia_sdp_neg_get_active_local( pjmedia_sdp_neg *neg,\n\t\t\t\t  const pjmedia_sdp_session **local);\n\n/**\n * Get the currently active remote SDP. Application can only call this\n * function after negotiation has been done, or otherwise there won't be\n * active SDPs. Calling this function will not change the state of the \n * negotiator.\n *\n * @param neg\t\tThe SDP negotiator instance.\n * @param remote\tPointer to receive the remote active SDP.\n *\n * @return\t\tPJ_SUCCESS if remote active SDP is present.\n */\nPJ_DECL(pj_status_t) \npjmedia_sdp_neg_get_active_remote( pjmedia_sdp_neg *neg,\n\t\t\t\t   const pjmedia_sdp_session **remote);\n\n\n/**\n * Determine whether remote sent answer (as opposed to offer) on the\n * last negotiation. This function can only be called in state\n * PJMEDIA_SDP_NEG_STATE_DONE.\n *\n * @param neg\t\tThe SDP negotiator instance.\n *\n * @return\t\tNon-zero if it was remote who sent answer,\n *\t\t\totherwise zero if it was local who supplied\n *\t\t\tanswer.\n */\nPJ_DECL(pj_bool_t)\npjmedia_sdp_neg_was_answer_remote(pjmedia_sdp_neg *neg);\n\n\n/**\n * Get the current remote SDP offer or answer. Application can only \n * call this function in state PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER or\n * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, or otherwise there won't be remote \n * SDP offer/answer. Calling this  function will not change the state \n * of the negotiator.\n *\n * @param neg\t\tThe SDP negotiator instance.\n * @param remote\tPointer to receive the current remote offer or\n *\t\t\tanswer.\n *\n * @return\t\tPJ_SUCCESS if the negotiator currently has\n *\t\t\tremote offer or answer.\n */\nPJ_DECL(pj_status_t)\npjmedia_sdp_neg_get_neg_remote( pjmedia_sdp_neg *neg,\n\t\t\t\tconst pjmedia_sdp_session **remote);\n\n\n/**\n * Get the current local SDP offer or answer. Application can only \n * call this function in state PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER or\n * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, or otherwise there won't be local \n * SDP offer/answer. Calling this function will not change the state \n * of the negotiator.\n *\n * @param neg\t\tThe SDP negotiator instance.\n * @param local\t\tPointer to receive the current local offer or\n *\t\t\tanswer.\n *\n * @return\t\tPJ_SUCCESS if the negotiator currently has\n *\t\t\tlocal offer or answer.\n */\nPJ_DECL(pj_status_t) \npjmedia_sdp_neg_get_neg_local( pjmedia_sdp_neg *neg,\n\t\t\t       const pjmedia_sdp_session **local);\n\n/**\n * Modify local session with a new SDP and treat this as a new offer. \n * This function can only be called in state PJMEDIA_SDP_NEG_STATE_DONE.\n * After calling this function, application can send the SDP as offer \n * to remote party, using signaling protocol such as SIP.\n * The negotiator state will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,\n * where it waits for SDP answer from remote. See also\n * #pjmedia_sdp_neg_modify_local_offer2()\n *\n * @param pool\t\tPool to allocate memory. The pool's lifetime needs\n *\t\t\tto be valid for the duration of the negotiator.\n * @param neg\t\tThe SDP negotiator instance.\n * @param local\t\tThe new local SDP.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) \npjmedia_sdp_neg_modify_local_offer( pj_pool_t *pool,\n\t\t\t\t    pjmedia_sdp_neg *neg,\n\t\t\t\t    const pjmedia_sdp_session *local);\n\n/**\n * Modify local session with a new SDP and treat this as a new offer. \n * This function can only be called in state PJMEDIA_SDP_NEG_STATE_DONE.\n * After calling this function, application can send the SDP as offer \n * to remote party, using signaling protocol such as SIP.\n * The negotiator state will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,\n * where it waits for SDP answer from remote.\n *\n * @param pool\t\tPool to allocate memory. The pool's lifetime needs\n *\t\t\tto be valid for the duration of the negotiator.\n * @param neg\t\tThe SDP negotiator instance.\n * @param flags         Bitmask from pjmedia_mod_offer_flag.\n * @param local\t\tThe new local SDP.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) \npjmedia_sdp_neg_modify_local_offer2( pj_pool_t *pool,\n\t\t\t\t     pjmedia_sdp_neg *neg,\n                                     unsigned flags,\n\t\t\t\t     const pjmedia_sdp_session *local);\n\n/**\n * This function can only be called in PJMEDIA_SDP_NEG_STATE_DONE state.\n * Application calls this function to retrieve currently active\n * local SDP, and then send the SDP to remote as an offer. The negotiator\n * state will then move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, where it waits\n * for SDP answer from remote. \n *\n * When SDP answer has been received from remote, application must call \n * #pjmedia_sdp_neg_set_remote_answer().\n *\n * @param pool\t\tPool to allocate memory. The pool's lifetime needs\n *\t\t\tto be valid for the duration of the negotiator.\n * @param neg\t\tThe SDP negotiator instance.\n * @param offer\t\tPointer to receive active local SDP to be\n *\t\t\toffered to remote.\n *\n * @return\t\tPJ_SUCCESS if local offer can be created.\n */\nPJ_DECL(pj_status_t) \npjmedia_sdp_neg_send_local_offer( pj_pool_t *pool,\n\t\t\t          pjmedia_sdp_neg *neg,\n\t\t\t\t  const pjmedia_sdp_session **offer);\n\n/**\n * This function can only be called in PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER\n * state, i.e. after application calls #pjmedia_sdp_neg_send_local_offer()\n * function. Application calls this function when it receives SDP answer\n * from remote. After this function is called, the negotiator state will\n * move to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and application can call the\n * negotiation function #pjmedia_sdp_neg_negotiate().\n *\n * @param pool\t\tPool to allocate memory. The pool's lifetime needs\n *\t\t\tto be valid for the duration of the negotiator.\n * @param neg\t\tThe SDP negotiator instance.\n * @param remote\tThe remote answer.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_sdp_neg_set_remote_answer( pj_pool_t *pool,\n\t\t\t\t   pjmedia_sdp_neg *neg,\n\t\t\t\t   const pjmedia_sdp_session *remote);\n\n\n\n/**\n * This function can only be called in PJMEDIA_SDP_NEG_STATE_DONE state. \n * Application calls this function when it receives SDP offer from remote.\n * After this function is called, the negotiator state will move to \n * PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER, and application MUST call the\n * #pjmedia_sdp_neg_set_local_answer() to set local answer before it can\n * call the negotiation function.\n *\n * @param pool\t\tPool to allocate memory. The pool's lifetime needs\n *\t\t\tto be valid for the duration of the negotiator.\n * @param neg\t\tThe SDP negotiator instance.\n * @param remote\tThe remote offer.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_sdp_neg_set_remote_offer( pj_pool_t *pool,\n\t\t\t\t  pjmedia_sdp_neg *neg,\n\t\t\t\t  const pjmedia_sdp_session *remote);\n\n\n\n/**\n * This function can only be called in PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER\n * state, i.e. after application calls #pjmedia_sdp_neg_set_remote_offer()\n * function. After this function is called, the negotiator state will\n * move to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and application can call the\n * negotiation function #pjmedia_sdp_neg_negotiate().\n *\n * @param pool\t\tPool to allocate memory. The pool's lifetime needs\n *\t\t\tto be valid for the duration of the negotiator.\n * @param neg\t\tThe SDP negotiator instance.\n * @param local\t\tOptional local answer. If negotiator has initial\n *\t\t\tlocal capability, application can specify NULL on\n *\t\t\tthis argument; in this case, the negotiator will\n *\t\t\tcreate answer by by negotiating remote offer with\n *\t\t\tinitial local capability. If negotiator doesn't have\n *\t\t\tinitial local capability, application MUST specify\n *\t\t\tlocal answer here.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_sdp_neg_set_local_answer( pj_pool_t *pool,\n\t\t\t\t  pjmedia_sdp_neg *neg,\n\t\t\t\t  const pjmedia_sdp_session *local);\n\n\n/**\n * Call this function when the negotiator is in PJMEDIA_SDP_NEG_STATE_WAIT_NEGO\n * state to see if it was local who is answering the offer (instead of\n * remote).\n *\n * @param neg\t\tThe negotiator.\n *\n * @return\t\tPJ_TRUE if it is local is answering an offer, PJ_FALSE\n *\t\t\tif remote has answered local offer.\n */\nPJ_DECL(pj_bool_t) pjmedia_sdp_neg_has_local_answer(pjmedia_sdp_neg *neg);\n\n\n/**\n * Cancel any pending offer, whether the offer is initiated by local or\n * remote, and move negotiator state back to previous stable state\n * (PJMEDIA_SDP_NEG_STATE_DONE). The negotiator must be in\n * PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER or PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER\n * state.\n *\n * @param neg\t\tThe negotiator.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_neg_cancel_offer(pjmedia_sdp_neg *neg);\n\n\n/**\n * Negotiate local and remote answer. Before calling this function, the\n * SDP negotiator must be in PJMEDIA_SDP_NEG_STATE_WAIT_NEGO state.\n * After calling this function, the negotiator state will move to\n * PJMEDIA_SDP_NEG_STATE_DONE regardless whether the negotiation has\n * been successfull or not.\n *\n * If the negotiation succeeds (i.e. the return value is PJ_SUCCESS),\n * the active local and remote SDP will be replaced with the new SDP\n * from the negotiation process.\n *\n * If the negotiation fails, the active local and remote SDP will not\n * change.\n *\n * @param pool\t\tPool to allocate memory. The pool's lifetime needs\n *\t\t\tto be valid for the duration of the negotiator.\n * @param neg\t\tThe SDP negotiator instance.\n * @param allow_asym\tShould be zero.\n *\n * @return\t\tPJ_SUCCESS when there is at least one media\n *\t\t\tis actuve common in both offer and answer, or \n *\t\t\tfailure code when negotiation has failed.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool,\n\t\t\t\t\t        pjmedia_sdp_neg *neg,\n\t\t\t\t\t\tpj_bool_t allow_asym);\n\n\n/**\n * Enumeration of customized SDP format matching option flags. See\n * #pjmedia_sdp_neg_register_fmt_match_cb() for more info.\n */\ntypedef enum pjmedia_sdp_neg_fmt_match_flag\n{\n    /**\n     * In generating answer, the SDP fmtp in the answer candidate may need\n     * to be modified by the customized SDP format matching callback to\n     * achieve flexible SDP negotiation, e.g: AMR fmtp 'octet-align' field\n     * can be adjusted with the offer when the codec implementation support\n     * both packetization modes octet-aligned and bandwidth-efficient.\n     */\n    PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER = 1,\n\n} pjmedia_sdp_neg_fmt_match_flag;\n\n\n/**\n * The declaration of customized SDP format matching callback. See\n * #pjmedia_sdp_neg_register_fmt_match_cb() for more info.\n *\n * @param pool\t\tThe memory pool.\n * @param offer\t\tThe SDP media offer.\n * @param o_fmt_idx\tIndex of the format in the SDP media offer.\n * @param answer\tThe SDP media answer.\n * @param a_fmt_idx\tIndex of the format in the SDP media answer.\n * @param option\tThe format matching option, see\n *\t\t\t#pjmedia_sdp_neg_fmt_match_flag.\n *\n * @return\t\tPJ_SUCCESS when the formats in offer and answer match.\n */\ntypedef pj_status_t (*pjmedia_sdp_neg_fmt_match_cb)(pj_pool_t *pool,\n\t\t\t\t\t\t    pjmedia_sdp_media *offer,\n\t\t\t\t\t\t    unsigned o_fmt_idx,\n\t\t\t\t\t\t    pjmedia_sdp_media *answer,\n\t\t\t\t\t\t    unsigned a_fmt_idx,\n\t\t\t\t\t\t    unsigned option);\n\n\n/**\n * Register customized SDP format matching callback function for the specified\n * format. The customized SDP format matching is needed when the format\n * identification in a media stream session cannot be simply determined by\n * encoding name and clock rate, but also involves one or more format specific\n * parameters, which are specified in SDP fmtp attribute. For example,\n * an H.264 video stream is also identified by profile, level, and\n * packetization-mode parameters. As those parameters are format specifics,\n * the negotiation must be done by the format or codec implementation.\n *\n * To unregister the callback of specific format, just call this function with\n * parameter #cb set to NULL.\n *\n * @param fmt_name\tThe format name, e.g: \"H.264\", \"AMR\", \"G7221\". Note\n *\t\t\tthat the string buffer must remain valid until the\n *\t\t\tcallback is unregistered.\n * @param cb\t\tThe customized SDP format negotiation callback or\n *\t\t\tNULL to unregister the specified format callback.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_neg_register_fmt_match_cb(\n\t\t\t\t\tconst pj_str_t *fmt_name,\n\t\t\t\t\tpjmedia_sdp_neg_fmt_match_cb cb);\n\n\n/**\n * Match format in the SDP media offer and answer. The matching mechanism\n * will be done by comparing the encoding name, clock rate, and encoding\n * parameters (if any), and if the custom format matching callback\n * for the specified format is registered, see\n * #pjmedia_sdp_neg_register_fmt_match_cb(), it will be called for\n * more detail verification, e.g: format parameters specified in SDP fmtp.\n *\n * @param pool\t\tThe memory pool.\n * @param offer\t\tThe SDP media offer.\n * @param o_fmt_idx\tIndex of the format in the SDP media offer.\n * @param answer\tThe SDP media answer.\n * @param a_fmt_idx\tIndex of the format in the SDP media answer.\n * @param option\tThe format matching option, see\n *\t\t\t#pjmedia_sdp_neg_fmt_match_flag.\n *\n * @return\t\tPJ_SUCCESS when the formats in offer and answer match.\n */\nPJ_DECL(pj_status_t) pjmedia_sdp_neg_fmt_match( pj_pool_t *pool,\n\t\t\t\t\t        pjmedia_sdp_media *offer,\n\t\t\t\t\t        unsigned o_fmt_idx,\n\t\t\t\t\t        pjmedia_sdp_media *answer,\n\t\t\t\t\t        unsigned a_fmt_idx,\n\t\t\t\t\t        unsigned option);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_SDP_NEG_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/session.h",
    "content": "/* $Id: session.h 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_SESSION_H__\n#define __PJMEDIA_SESSION_H__\n\n\n/**\n * @file session.h\n * @brief Media Session.\n */\n\n#include <pjmedia/endpoint.h>\n#include <pjmedia/stream.h>\n#include <pjmedia/sdp.h>\n\nPJ_BEGIN_DECL \n\n/**\n * @defgroup PJMEDIA_SESSION Media Sessions\n * @brief Management of media sessions\n * @{\n *\n * A media session represents multimedia communication between two\n * parties. A media session represents the multimedia session that\n * is described by SDP session descriptor. A media session consists \n * of one or more media streams (pjmedia_stream), where each stream \n * represents one media line (m= line) in SDP.\n *\n * This module provides functions to create and manage multimedia\n * sessions.\n *\n * Application creates the media session by calling #pjmedia_session_create(),\n * normally after it has completed negotiating both SDP offer and answer.\n * The session creation function creates the media session (including\n * media streams) based on the content of local and remote SDP.\n */\n\n\n/**\n * Session info, retrieved from a session by calling\n * #pjmedia_session_get_info().\n */\nstruct pjmedia_session_info\n{\n    /** Number of streams. */\n    unsigned\t\tstream_cnt;\n\n    /** Individual stream info. */\n    pjmedia_stream_info\tstream_info[PJMEDIA_MAX_SDP_MEDIA];\n};\n\n\n/** \n * Opaque declaration of media session. \n */\ntypedef struct pjmedia_session pjmedia_session;\n\n\n/**\n * @see pjmedia_session_info.\n */\ntypedef struct pjmedia_session_info pjmedia_session_info;\n\n\n/**\n * This function will initialize the session info based on information\n * in both SDP session descriptors. The remaining information will be\n * taken from default codec parameters. If socket info array is specified,\n * the socket will be copied to the session info as well.\n *\n * @param pool\t\tPool to allocate memory.\n * @param endpt\t\tPjmedia endpoint.\n * @param max_streams\tMaximum number of stream infos to be created.\n * @param si\t\tSession info structure to be initialized.\n * @param local\t\tLocal SDP session descriptor.\n * @param remote\tRemote SDP session descriptor.\n *\n * @return\t\tPJ_SUCCESS if stream info is successfully initialized.\n */\nPJ_DECL(pj_status_t)\npjmedia_session_info_from_sdp( pj_pool_t *pool,\n\t\t\t       pjmedia_endpt *endpt,\n\t\t\t       unsigned max_streams,\n\t\t\t       pjmedia_session_info *si,\n\t\t\t       const pjmedia_sdp_session *local,\n\t\t\t       const pjmedia_sdp_session *remote);\n\n\n/**\n * This function will initialize the stream info based on information\n * in both SDP session descriptors for the specified stream index. \n * The remaining information will be taken from default codec parameters. \n * If socket info array is specified, the socket will be copied to the \n * session info as well.\n *\n * @param si\t\tStream info structure to be initialized.\n * @param pool\t\tPool to allocate memory.\n * @param endpt\t\tPJMEDIA endpoint instance.\n * @param local\t\tLocal SDP session descriptor.\n * @param remote\tRemote SDP session descriptor.\n * @param stream_idx\tMedia stream index in the session descriptor.\n *\n * @return\t\tPJ_SUCCESS if stream info is successfully initialized.\n */\nPJ_DECL(pj_status_t)\npjmedia_stream_info_from_sdp( pjmedia_stream_info *si,\n\t\t\t      pj_pool_t *pool,\n\t\t\t      pjmedia_endpt *endpt,\n\t\t\t      const pjmedia_sdp_session *local,\n\t\t\t      const pjmedia_sdp_session *remote,\n\t\t\t      unsigned stream_idx);\n\n/**\n * Create media session based on the local and remote SDP. After the session\n * has been created, application normally would want to get the media port \n * interface of each streams, by calling #pjmedia_session_get_port(). The \n * media port interface exports put_frame() and get_frame() function, used\n * to transmit and receive media frames from the stream.\n *\n * Without application calling put_frame() and get_frame(), there will be \n * no media frames transmitted or received by the session.\n * \n * @param endpt\t\tThe PJMEDIA endpoint instance.\n * @param si\t\tSession info containing stream count and array of\n *\t\t\tstream info. The stream count indicates how many\n *\t\t\tstreams to be created in the session.\n * @param transports\tArray of media stream transports, with \n *\t\t\tsufficient number of elements (one for each stream).\n * @param user_data\tArbitrary user data to be kept in the session.\n * @param p_session\tPointer to receive the media session.\n *\n * @return\t\tPJ_SUCCESS if media session can be created \n *\t\t\tsuccessfully.\n */\nPJ_DECL(pj_status_t) \npjmedia_session_create( pjmedia_endpt *endpt, \n\t\t\tconst pjmedia_session_info *si,\n\t\t\tpjmedia_transport *transports[],\n\t\t\tvoid *user_data,\n\t\t\tpjmedia_session **p_session );\n\n\n/**\n * Get media session info of the session.\n *\n * @param session\tThe session which info is being queried.\n * @param info\t\tPointer to receive session info.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_session_get_info( pjmedia_session *session,\n\t\t\t\t\t       pjmedia_session_info *info );\n\n/**\n * Get user data of the session.\n *\n * @param session\tThe session being queried.\n *\n * @return\t\tUser data of the session.\n */\nPJ_DECL(void*) pjmedia_session_get_user_data( pjmedia_session *session);\n\n\n/**\n * Activate all streams in media session for the specified direction.\n * Application only needs to call this function if it previously paused\n * the session.\n *\n * @param session\tThe media session.\n * @param dir\t\tThe direction to activate.\n *\n * @return\t\tPJ_SUCCESS if success.\n */\nPJ_DECL(pj_status_t) pjmedia_session_resume(pjmedia_session *session,\n\t\t\t\t\t    pjmedia_dir dir);\n\n\n/**\n * Suspend receipt and transmission of all streams in media session\n * for the specified direction.\n *\n * @param session\tThe media session.\n * @param dir\t\tThe media direction to suspend.\n *\n * @return\t\tPJ_SUCCESS if success.\n */\nPJ_DECL(pj_status_t) pjmedia_session_pause(pjmedia_session *session,\n\t\t\t\t\t   pjmedia_dir dir);\n\n/**\n * Suspend receipt and transmission of individual stream in media session\n * for the specified direction.\n *\n * @param session\tThe media session.\n * @param index\t\tThe stream index.\n * @param dir\t\tThe media direction to pause.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_session_pause_stream( pjmedia_session *session,\n\t\t\t\t\t\t   unsigned index,\n\t\t\t\t\t\t   pjmedia_dir dir);\n\n/**\n * Activate individual stream in media session for the specified direction.\n *\n * @param session\tThe media session.\n * @param index\t\tThe stream index.\n * @param dir\t\tThe media direction to activate.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_session_resume_stream(pjmedia_session *session,\n\t\t\t\t\t\t   unsigned index,\n\t\t\t\t\t\t   pjmedia_dir dir);\n\n/**\n * Send RTCP SDES for the session.\n *\n * @param session\tThe media session.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_session_send_rtcp_sdes( const pjmedia_session *session );\n\n/**\n * Send RTCP BYE for the session.\n *\n * @param session\tThe media session.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_session_send_rtcp_bye( const pjmedia_session *session );\n\n/**\n * Enumerate media streams in the session.\n *\n * @param session\tThe media session.\n * @param count\t\tOn input, specifies the number of elements in\n *\t\t\tthe array. On output, the number will be filled\n *\t\t\twith number of streams in the session.\n * @param strm_info\tArray of stream info.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_session_enum_streams( const pjmedia_session *session,\n\t\t\t      unsigned *count, \n\t\t\t      pjmedia_stream_info strm_info[]);\n\n\n/**\n * Get the media port interface of the specified stream. The media port\n * interface declares put_frame() and get_frame() function, which is the \n * only  way for application to transmit and receive media frames from the\n * stream.\n *\n * @param session\tThe media session.\n * @param index\t\tStream index.\n * @param p_port\tPointer to receive the media port interface for\n *\t\t\tthe specified stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_session_get_port( pjmedia_session *session,\n\t\t\t\t\t       unsigned index,\n\t\t\t\t\t       pjmedia_port **p_port);\n\n\n/**\n * Get session statistics. The stream statistic shows various\n * indicators such as packet count, packet lost, jitter, delay, etc.\n * See also #pjmedia_session_get_stream_stat_jbuf()\n *\n * @param session\tThe media session.\n * @param index\t\tStream index.\n * @param stat\t\tStream statistic.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_session_get_stream_stat(pjmedia_session *session,\n\t\t\t\t\t\t     unsigned index,\n\t\t\t\t\t\t     pjmedia_rtcp_stat *stat);\n\n\n/**\n * Reset session statistics.\n *\n * @param session\tThe media session.\n * @param index\t\tStream index.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_session_reset_stream_stat(pjmedia_session *session,\n\t\t\t\t\t\t       unsigned index);\n\n\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n/**\n * Get extended session statistics. The extended statistic shows reports\n * from RTCP XR, such as per interval statistics summary (packet count, \n * packet lost, jitter, etc), VoIP metrics (delay, quality, etc)\n *\n * @param session\tThe media session.\n * @param index\t\tStream index.\n * @param stat_xr\tStream extended statistics.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_session_get_stream_stat_xr(\n\t\t\t\t\t     pjmedia_session *session,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_rtcp_xr_stat *stat_xr);\n#endif\n\n\n/**\n * Get current jitter buffer state for the specified stream.\n * See also #pjmedia_session_get_stream_stat()\n *\n * @param session\tThe media session.\n * @param index\t\tStream index.\n * @param state\t\tJitter buffer state.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_session_get_stream_stat_jbuf(\n\t\t\t\t\t    pjmedia_session *session,\n\t\t\t\t\t    unsigned index,\n\t\t\t\t\t    pjmedia_jb_state *state);\n\n/**\n * Dial DTMF digit to the stream, using RFC 2833 mechanism.\n *\n * @param session\tThe media session.\n * @param index\t\tThe stream index.\n * @param ascii_digits\tString of ASCII digits (i.e. 0-9*##A-B).\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_session_dial_dtmf( pjmedia_session *session,\n\t\t\t\t\t        unsigned index,\n\t\t\t\t\t\tconst pj_str_t *ascii_digits );\n\n\n/**\n * Check if the specified stream has received DTMF digits.\n *\n * @param session\tThe media session.\n * @param index\t\tThe stream index.\n *\n * @return\t\tNon-zero (PJ_TRUE) if the stream has DTMF digits.\n */\nPJ_DECL(pj_status_t) pjmedia_session_check_dtmf( pjmedia_session *session,\n\t\t\t\t\t         unsigned index);\n\n\n/**\n * Retrieve DTMF digits from the specified stream.\n *\n * @param session\tThe media session.\n * @param index\t\tThe stream index.\n * @param ascii_digits\tBuffer to receive the digits. The length of this\n *\t\t\tbuffer is indicated in the \"size\" argument.\n * @param size\t\tOn input, contains the maximum digits to be copied\n *\t\t\tto the buffer.\n *\t\t\tOn output, it contains the actual digits that has\n *\t\t\tbeen copied to the buffer.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_session_get_dtmf( pjmedia_session *session,\n\t\t\t\t\t       unsigned index,\n\t\t\t\t\t       char *ascii_digits,\n\t\t\t\t\t       unsigned *size );\n\n/**\n * Set callback to be called upon receiving DTMF digits. If callback is\n * registered, the stream will not buffer incoming DTMF but rather call\n * the callback as soon as DTMF digit is received completely.\n *\n * @param session\tThe media session.\n * @param index\t\tThe stream index.\n * @param cb\t\tCallback to be called upon receiving DTMF digits.\n *\t\t\tThe DTMF digits will be given to the callback as\n *\t\t\tASCII digits.\n * @param user_data\tUser data to be returned back when the callback\n *\t\t\tis called.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t)\npjmedia_session_set_dtmf_callback(pjmedia_session *session,\n\t\t\t\t  unsigned index,\n\t\t\t\t  void (*cb)(pjmedia_stream*, \n\t\t\t\t \t     void *user_data, \n\t\t\t\t\t     int digit), \n\t\t\t\t  void *user_data);\n\n/**\n * Destroy media session.\n *\n * @param session\tThe media session.\n *\n * @return\t\tPJ_SUCCESS if success.\n */\nPJ_DECL(pj_status_t) pjmedia_session_destroy(pjmedia_session *session);\n\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJMEDIA_SESSION_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/signatures.h",
    "content": "/* $Id: signatures.h 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_SIGNATURES_H__\n#define __PJMEDIA_SIGNATURES_H__\n\n/**\n * @file pjmedia/signatures.h\n * @brief Standard PJMEDIA object signatures\n */\n#include <pjmedia/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJMEDIA_SIG Object Signatures\n * @ingroup PJMEDIA_BASE\n * @brief Standard PJMEDIA object signatures\n * @{\n *\n * Object signature is a 32-bit integral value similar to FOURCC to help\n * identify PJMEDIA objects such as media ports, transports, codecs, etc.\n * There are several uses of this signature, for example a media port can\n * use the port object signature to verify that the given port instance\n * is the one that it created, and a receiver of \\ref PJMEDIA_EVENT can\n * use the signature of the publisher to know which object emitted the\n * event.\n *\n * The 32-bit value of an object signature is generated by the following\n * macro:\n *\n * \\verbatim\n   #define PJMEDIA_SIGNATURE(a,b,c,d)\t(a<<24 | b<<16 | c<<8 | d)\n * \\endverbatim\n *\n * The following convention is used to maintain order to the signature\n * values so that application can make use of it more effectively, and to\n * avoid conflict between the values themselves. For each object type or\n * class, a specific prefix will be assigned as signature, and a macro\n * is created to build a signature for such object:\n *\n * \\verbatim\n    Class               Signature  Signature creation and test macros\n    ---------------------------------------------------------------\n    Codec    \t\tCxxx\t   PJMEDIA_SIG_CLASS_CODEC(b,c,d)\n\t\t\t\t   PJMEDIA_SIG_IS_CLASS_CODEC(sig)\n\n    Audio codec \tCAxx\t   PJMEDIA_SIG_CLASS_AUD_CODEC(c,d)\n\t\t\t\t   PJMEDIA_SIG_IS_CLASS_AUD_CODEC(sig)\n\n    Video codec \tCVxx\t   PJMEDIA_SIG_CLASS_VID_CODEC(c,d)\n\t\t\t\t   PJMEDIA_SIG_IS_CLASS_VID_CODEC(sig)\n\n    Media port\t\tPxxx\t   PJMEDIA_SIG_CLASS_PORT(b,c,d)\n\t\t\t\t   PJMEDIA_SIG_IS_CLASS_PORT(sig)\n\n    Audio media port    PAxx\t   PJMEDIA_SIG_CLASS_PORT_AUD(c,d)\n\t\t\t\t   PJMEDIA_SIG_IS_CLASS_PORT_AUD(sig)\n\n    Video media port    PVxx\t   PJMEDIA_SIG_CLASS_PORT_VID(c,d)\n\t\t\t\t   PJMEDIA_SIG_IS_CLASS_PORT_VID(sig)\n\n    Video device\tVDxx\t   PJMEDIA_SIG_CLASS_VID_DEV(c,d)\n\t\t\t\t   PJMEDIA_SIG_IS_CLASS_VID_DEV(sig)\n\n    Video other\t\tVOxx\t   PJMEDIA_SIG_CLASS_VID_OTHER(c,d)\n\t\t\t\t   PJMEDIA_SIG_IS_CLASS_VID_OTHER(sig)\n\n    Application object\tAxxx\t   PJMEDIA_SIG_CLASS_APP(b,c,d)\n\t\t\t\t   PJMEDIA_SIG_IS_CLASS_APP(sig)\n\n * \\endverbatim\n *\n * In addition, signatures created in application code should have lowercase\n * letters to avoid conflict with built-in objects.\n */\n\n/**\n * Type to store object signature.\n */\ntypedef pj_uint32_t pjmedia_obj_sig;\n\n/**\n * A utility function to convert signature to four letters string.\n *\n * @param sig\t\tThe signature value.\n * @param buf\t\tBuffer to store the string, which MUST be at least\n * \t\t\tfive bytes long.\n *\n * @return\t\tThe string.\n */\nPJ_INLINE(const char*) pjmedia_sig_name(pjmedia_obj_sig sig, char buf[])\n{\n    return pjmedia_fourcc_name(sig, buf);\n}\n\n/**\n * Macro to generate signature from four ASCII letters.\n */\n#define PJMEDIA_SIGNATURE(a,b,c,d)\tPJMEDIA_FOURCC(a,b,c,d)\n\n/*************************************************************************\n * Codec signature ('Cxxx'). Please keep the constant names sorted.\n */\n#define PJMEDIA_SIG_CLASS_CODEC(b,c,d)\tPJMEDIA_SIGNATURE('C',b,c,d)\n#define PJMEDIA_SIG_IS_CLASS_CODEC(sig)\t((sig) >> 24 == 'C')\n\n/*************************************************************************\n * Audio codec signatures ('CAxx'). Please keep the constant names sorted.\n */\n#define PJMEDIA_SIG_CLASS_AUD_CODEC(c,d) PJMEDIA_SIG_CLASS_CODEC('A',c,d)\n#define PJMEDIA_SIG_IS_CLASS_AUD_CODEC(s) ((s)>>24=='C' && (s)>>16=='A')\n\n/*************************************************************************\n * Video codec signatures ('CVxx'). Please keep the constant names sorted.\n */\n#define PJMEDIA_SIG_CLASS_VID_CODEC(c,d) PJMEDIA_SIG_CLASS_CODEC('V',c,d)\n#define PJMEDIA_SIG_IS_CLASS_VID_CODEC(sig) ((s)>>24=='C' && (s)>>16=='V')\n\n#define PJMEDIA_SIG_VID_CODEC_FFMPEG\tPJMEDIA_SIG_CLASS_VID_CODEC('F','F')\n\n/*************************************************************************\n * Port signatures ('Pxxx'). Please keep the constant names sorted.\n */\n#define PJMEDIA_SIG_CLASS_PORT(b,c,d)\tPJMEDIA_SIGNATURE('P',b,c,d)\n#define PJMEDIA_SIG_IS_CLASS_PORT(sig)\t((sig) >> 24 == 'P')\n\n/*************************************************************************\n * Audio ports signatures ('PAxx'). Please keep the constant names sorted.\n */\n#define PJMEDIA_SIG_CLASS_PORT_AUD(c,d)\tPJMEDIA_SIG_CLASS_PORT('A',c,d)\n#define PJMEDIA_SIG_IS_CLASS_PORT_AUD(s) ((s)>>24=='P' && (s)>>16=='A')\n\n#define PJMEDIA_SIG_PORT_BIDIR\t\tPJMEDIA_SIG_CLASS_PORT_AUD('B','D')\n#define PJMEDIA_SIG_PORT_CONF\t\tPJMEDIA_SIG_CLASS_PORT_AUD('C','F')\n#define PJMEDIA_SIG_PORT_CONF_PASV\tPJMEDIA_SIG_CLASS_PORT_AUD('C','P')\n#define PJMEDIA_SIG_PORT_CONF_SWITCH\tPJMEDIA_SIG_CLASS_PORT_AUD('C','S')\n#define PJMEDIA_SIG_PORT_ECHO\t\tPJMEDIA_SIG_CLASS_PORT_AUD('E','C')\n#define PJMEDIA_SIG_PORT_MEM_CAPTURE\tPJMEDIA_SIG_CLASS_PORT_AUD('M','C')\n#define PJMEDIA_SIG_PORT_MEM_PLAYER\tPJMEDIA_SIG_CLASS_PORT_AUD('M','P')\n#define PJMEDIA_SIG_PORT_MIXER\t        PJMEDIA_SIG_CLASS_PORT_AUD('M','X')\n#define PJMEDIA_SIG_PORT_NULL\t\tPJMEDIA_SIG_CLASS_PORT_AUD('N','U')\n#define PJMEDIA_SIG_PORT_RESAMPLE\tPJMEDIA_SIG_CLASS_PORT_AUD('R','E')\n#define PJMEDIA_SIG_PORT_SPLIT_COMB\tPJMEDIA_SIG_CLASS_PORT_AUD('S','C')\n#define PJMEDIA_SIG_PORT_SPLIT_COMB_P\tPJMEDIA_SIG_CLASS_PORT_AUD('S','P')\n#define PJMEDIA_SIG_PORT_STEREO\t\tPJMEDIA_SIG_CLASS_PORT_AUD('S','R')\n#define PJMEDIA_SIG_PORT_STREAM\t\tPJMEDIA_SIG_CLASS_PORT_AUD('S','T')\n#define PJMEDIA_SIG_PORT_TONEGEN\tPJMEDIA_SIG_CLASS_PORT_AUD('T','O')\n#define PJMEDIA_SIG_PORT_WAV_PLAYER\tPJMEDIA_SIG_CLASS_PORT_AUD('W','P')\n#define PJMEDIA_SIG_PORT_WAV_PLAYLIST\tPJMEDIA_SIG_CLASS_PORT_AUD('W','Y')\n#define PJMEDIA_SIG_PORT_WAV_WRITER\tPJMEDIA_SIG_CLASS_PORT_AUD('W','W')\n\n\n/*************************************************************************\n * Video ports signatures ('PVxx'). Please keep the constant names sorted.\n */\n#define PJMEDIA_SIG_CLASS_PORT_VID(c,d)\tPJMEDIA_SIG_CLASS_PORT('V',c,d)\n#define PJMEDIA_SIG_IS_CLASS_PORT_VID(s) ((s)>>24=='P' && (s)>>16=='V')\n\n/** AVI player signature. */\n#define PJMEDIA_SIG_PORT_VID_AVI_PLAYER\tPJMEDIA_SIG_CLASS_PORT_VID('A','V')\n#define PJMEDIA_SIG_PORT_VID_STREAM\tPJMEDIA_SIG_CLASS_PORT_VID('S','T')\n#define PJMEDIA_SIG_PORT_VID_TEE\tPJMEDIA_SIG_CLASS_PORT_VID('T','E')\n\n\n/**************************************************************************\n * Video device signatures ('VDxx'). Please keep the constant names sorted.\n */\n#define PJMEDIA_SIG_CLASS_VID_DEV(c,d)\tPJMEDIA_SIGNATURE('V','D',c,d)\n#define PJMEDIA_SIG_IS_CLASS_VID_DEV(s) ((s)>>24=='V' && (s)>>16=='D')\n\n#define PJMEDIA_SIG_VID_DEV_COLORBAR\tPJMEDIA_SIG_CLASS_VID_DEV('C','B')\n#define PJMEDIA_SIG_VID_DEV_SDL\t\tPJMEDIA_SIG_CLASS_VID_DEV('S','D')\n#define PJMEDIA_SIG_VID_DEV_V4L2\tPJMEDIA_SIG_CLASS_VID_DEV('V','2')\n#define PJMEDIA_SIG_VID_DEV_DSHOW\tPJMEDIA_SIG_CLASS_VID_DEV('D','S')\n#define PJMEDIA_SIG_VID_DEV_QT\t\tPJMEDIA_SIG_CLASS_VID_DEV('Q','T')\n#define PJMEDIA_SIG_VID_DEV_IOS\t\tPJMEDIA_SIG_CLASS_VID_DEV('I','P')\n\n\n/*********************************************************************\n * Other video objects ('VOxx'). Please keep the constant names sorted.\n */\n#define PJMEDIA_SIG_CLASS_VID_OTHER(c,d) PJMEDIA_SIGNATURE('V','O',c,d)\n#define PJMEDIA_SIG_IS_CLASS_VID_OTHER(s) ((s)>>24=='V' && (s)>>16=='O')\n\n#define PJMEDIA_SIG_VID_PORT\t\tPJMEDIA_SIG_CLASS_VID_OTHER('P','O')\n\n\n/*********************************************************************\n * Application class ('Axxx').\n */\n#define PJMEDIA_SIG_CLASS_APP(b,c,d)\tPJMEDIA_SIGNATURE('A',b,c,d)\n#define PJMEDIA_SIG_IS_CLASS_APP(s)\t((s)>>24=='A')\n\n\n/**\n * @}  PJSIP_MSG\n */\n\n\nPJ_END_DECL\n\n#endif\t/* __PJMEDIA_SIGNATURES_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/silencedet.h",
    "content": "/* $Id: silencedet.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_SILENCE_DET_H__\n#define __PJMEDIA_SILENCE_DET_H__\n\n\n/**\n * @file silencedet.h\n * @brief Adaptive silence detector.\n */\n#include <pjmedia/types.h>\n\n\n/**\n * @defgroup PJMEDIA_SILENCEDET Adaptive Silence Detection\n * @ingroup PJMEDIA_FRAME_OP\n * @brief Adaptive Silence Detector\n * @{\n */\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * Opaque declaration for silence detector.\n */\ntypedef struct pjmedia_silence_det pjmedia_silence_det;\n\n\n\n/**\n * Create voice activity detector with default settings. The default settings\n * are set to adaptive silence detection with the default threshold.\n *\n * @param pool\t\t    Pool for allocating the structure.\n * @param clock_rate\t    Clock rate.\n * @param samples_per_frame Number of samples per frame. The clock_rate and\n *\t\t\t    samples_per_frame is only used to calculate the\n *\t\t\t    frame time, from which some timing parameters\n *\t\t\t    are calculated from.\n * @param p_sd\t\t    Pointer to receive the silence detector instance.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_silence_det_create( pj_pool_t *pool,\n\t\t\t\t\t\t unsigned clock_rate,\n\t\t\t\t\t\t unsigned samples_per_frame,\n\t\t\t\t\t\t pjmedia_silence_det **p_sd );\n\n\n/**\n * Set silence detector name to identify the particular silence detector\n * instance in the log.\n *\n * @param sd\t\t    The silence detector.\n * @param name\t\t    Name.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_silence_det_set_name(pjmedia_silence_det *sd,\n\t\t\t\t\t\t  const char *name);\n\n\n/**\n * Set the sd to operate in fixed threshold mode. With fixed threshold mode,\n * the threshold will not be changed adaptively.\n *\n * @param sd\t\t    The silence detector\n * @param threshold\t    The silence threshold, or -1 to use default\n *\t\t\t    threshold.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_silence_det_set_fixed( pjmedia_silence_det *sd,\n\t\t\t\t\t\t    int threshold );\n\n/**\n * Set the sd to operate in adaptive mode. This is the default mode\n * when the silence detector is created.\n *\n * @param sd\t\t    The silence detector\n * @param threshold\t    Initial threshold to be set, or -1 to use default\n *\t\t\t    threshold.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_silence_det_set_adaptive(pjmedia_silence_det *sd,\n\t\t\t\t\t\t      int threshold);\n\n/**\n * Set other silence detector parameters.\n *\n * @param sd\t\t    The silence detector\n * @param before_silence    Minimum duration of silence (in msec) before \n *\t\t\t    silence is reported. If -1 is specified, then\n *\t\t\t    the default value will be used. The default is\n *\t\t\t    400 msec.\n * @param recalc_time1\t    The interval (in msec) to recalculate threshold\n *\t\t\t    in non-silence condition when adaptive silence \n *\t\t\t    detection is set. If -1 is specified, then the \n *\t\t\t    default value will be used. The default is 4000\n *\t\t\t    (msec).\n * @param recalc_time2\t    The interval (in msec) to recalculate threshold\n *\t\t\t    in silence condition when adaptive silence detection\n *\t\t\t    is set. If -1 is specified, then the default value \n *\t\t\t    will be used. The default value is 2000 (msec).\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_silence_det_set_params( pjmedia_silence_det *sd,\n\t\t\t\t\t\t     int before_silence,\n\t\t\t\t\t\t     int recalc_time1,\n\t\t\t\t\t\t     int recalc_time2);\n\n\n/**\n * Disable the silence detector.\n *\n * @param sd\t\tThe silence detector\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_silence_det_disable( pjmedia_silence_det *sd );\n\n\n/**\n * Perform voice activity detection on the given input samples. This\n * function uses #pjmedia_calc_avg_signal() and #pjmedia_silence_det_apply()\n * for its calculation.\n *\n * @param sd\t\tThe silence detector instance.\n * @param samples\tPointer to 16-bit PCM input samples.\n * @param count\t\tNumber of samples in the input.\n * @param p_level\tOptional pointer to receive average signal level\n *\t\t\tof the input samples.\n *\n * @return\t\tNon zero if signal is silence.\n */\nPJ_DECL(pj_bool_t) pjmedia_silence_det_detect( pjmedia_silence_det *sd,\n\t\t\t\t\t       const pj_int16_t samples[],\n\t\t\t\t\t       pj_size_t count,\n\t\t\t\t\t       pj_int32_t *p_level);\n\n\n/**\n * Calculate average signal level for the given samples.\n *\n * @param samples\tPointer to 16-bit PCM samples.\n * @param count\t\tNumber of samples in the input.\n *\n * @return\t\tThe average signal level, which simply is total level\n *\t\t\tdivided by number of samples.\n */\nPJ_DECL(pj_int32_t) pjmedia_calc_avg_signal( const pj_int16_t samples[],\n\t\t\t\t\t     pj_size_t count );\n\n\n\n/**\n * Perform voice activity detection, given the specified average signal\n * level.\n *\n * @param sd\t\tThe silence detector instance.\n * @param level\t\tSignal level.\n *\n * @return\t\tNon zero if signal is silence.\n */\nPJ_DECL(pj_bool_t) pjmedia_silence_det_apply( pjmedia_silence_det *sd,\n\t\t\t\t\t      pj_uint32_t level);\n\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_SILENCE_DET_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/sound.h",
    "content": "/* $Id: sound.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_SOUND_H__\n#define __PJMEDIA_SOUND_H__\n\n\n/**\n * @file sound.h\n * @brief Legacy sound device API\n */\n#include <pjmedia-audiodev/audiodev.h>\n#include <pjmedia/types.h>\n\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJMED_SND Portable Sound Hardware Abstraction\n * @ingroup PJMED_SND_PORT\n * @brief PJMEDIA abstraction for sound device hardware\n * @{\n *\n * <strong>Warning: this sound device API has been deprecated\n * and replaced by PJMEDIA Audio Device API. Please see\n * http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more\n * information.</strong>\n *\n * This section describes lower level abstraction for sound device\n * hardware. Application normally uses the higher layer @ref\n * PJMED_SND_PORT abstraction since it works seamlessly with \n * @ref PJMEDIA_PORT.\n *\n * The sound hardware abstraction basically runs <b>asychronously</b>,\n * and application must register callbacks to be called to receive/\n * supply audio frames from/to the sound hardware.\n *\n * A full duplex sound stream (created with #pjmedia_snd_open()) \n * requires application to supply two callbacks:\n *  - <b><tt>rec_cb</tt></b> callback to be called when it has finished\n *    capturing one media frame, and \n *  - <b><tt>play_cb</tt></b> callback to be called when it needs media \n *    frame to be played to the sound playback hardware.\n *\n * Half duplex sound stream (created with #pjmedia_snd_open_rec() or\n * #pjmedia_snd_open_player()) will only need one of the callback to\n * be specified.\n *\n * After sound stream is created, application need to call\n * #pjmedia_snd_stream_start() to start capturing/playing back media\n * frames from/to the sound device.\n */\n\n/** Opaque declaration for pjmedia_snd_stream. */\ntypedef struct pjmedia_snd_stream pjmedia_snd_stream;\n\n/**\n * Device information structure returned by #pjmedia_snd_get_dev_info.\n */\ntypedef struct pjmedia_snd_dev_info\n{\n    char\tname[PJMEDIA_AUD_DEV_INFO_NAME_LEN];\t        \n    \t\t\t\t\t/**< Device name.\t\t    */\n    unsigned\tinput_count;\t        /**< Max number of input channels.  */\n    unsigned\toutput_count;\t        /**< Max number of output channels. */\n    unsigned\tdefault_samples_per_sec;/**< Default sampling rate.\t    */\n} pjmedia_snd_dev_info;\n\n/** \n * Stream information, can be retrieved from a live stream by calling\n * #pjmedia_snd_stream_get_info().\n */\ntypedef struct pjmedia_snd_stream_info\n{\n    pjmedia_dir\tdir;\t\t    /**< Stream direction.\t\t    */\n    int\t\tplay_id;\t    /**< Playback dev id, or -1 for rec only*/\n    int\t\trec_id;\t\t    /**< Capture dev id, or -1 for play only*/\n    unsigned\tclock_rate;\t    /**< Actual clock rate.\t\t    */\n    unsigned\tchannel_count;\t    /**< Number of channels.\t\t    */\n    unsigned\tsamples_per_frame;  /**< Samples per frame.\t\t    */\n    unsigned\tbits_per_sample;    /**< Bits per sample.\t\t    */\n    unsigned\trec_latency;\t    /**< Record latency, in samples.\t    */\n    unsigned\tplay_latency;\t    /**< Playback latency, in samples.\t    */\n} pjmedia_snd_stream_info;\n\n/** \n * This callback is called by player stream when it needs additional data\n * to be played by the device. Application must fill in the whole of output \n * buffer with sound samples.\n *\n * @param user_data\tUser data associated with the stream.\n * @param timestamp\tTimestamp, in samples.\n * @param output\tBuffer to be filled out by application.\n * @param size\t\tThe size requested in bytes, which will be equal to\n *\t\t\tthe size of one whole packet.\n *\n * @return\t\tNon-zero to stop the stream.\n */\ntypedef pj_status_t (*pjmedia_snd_play_cb)(/* in */   void *user_data,\n\t\t\t\t      /* in */   pj_uint32_t timestamp,\n\t\t\t\t      /* out */  void *output,\n\t\t\t\t      /* out */  unsigned size);\n\n/**\n * This callback is called by recorder stream when it has captured the whole\n * packet worth of audio samples.\n *\n * @param user_data\tUser data associated with the stream.\n * @param timestamp\tTimestamp, in samples.\n * @param output\tBuffer containing the captured audio samples.\n * @param size\t\tThe size of the data in the buffer, in bytes.\n *\n * @return\t\tNon-zero to stop the stream.\n */\ntypedef pj_status_t (*pjmedia_snd_rec_cb)(/* in */   void *user_data,\n\t\t\t\t     /* in */   pj_uint32_t timestamp,\n\t\t\t\t     /* in */   void *input,\n\t\t\t\t     /* in*/    unsigned size);\n\n/**\n * Init the sound library.\n *\n * @param factory\tThe sound factory.\n *\n * @return\t\tZero on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory);\n\n\n/**\n * Get the number of devices detected by the library.\n *\n * @return\t\tNumber of devices.\n */\nPJ_DECL(int) pjmedia_snd_get_dev_count(void);\n\n\n/**\n * Get device info.\n *\n * @param index\t\tThe index of the device, which should be in the range\n *\t\t\tfrom zero to #pjmedia_snd_get_dev_count - 1.\n */\nPJ_DECL(const pjmedia_snd_dev_info*) pjmedia_snd_get_dev_info(unsigned index);\n\n\n/**\n * Set sound device latency, this function must be called before sound device\n * opened, or otherwise default latency setting will be used, @see\n * PJMEDIA_SND_DEFAULT_REC_LATENCY & PJMEDIA_SND_DEFAULT_PLAY_LATENCY.\n *\n * Choosing latency value is not straightforward, it should accomodate both \n * minimum latency and stability. Lower latency tends to cause sound device \n * less reliable (producing audio dropouts) on CPU load disturbance. Moreover,\n * the best latency setting may vary based on many aspects, e.g: sound card, \n * CPU, OS, kernel, etc.\n *\n * @param input_latency\t    The latency of input device, in ms, set to 0\n *\t\t\t    for default PJMEDIA_SND_DEFAULT_REC_LATENCY.\n * @param output_latency    The latency of output device, in ms, set to 0\n *\t\t\t    for default PJMEDIA_SND_DEFAULT_PLAY_LATENCY.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_set_latency(unsigned input_latency, \n\t\t\t\t\t     unsigned output_latency);\n\n\n/**\n * Create sound stream for both capturing audio and audio playback,  from the \n * same device. This is the recommended way to create simultaneous recorder \n * and player streams (instead of creating separate capture and playback\n * streams), because it works on backends that does not allow\n * a device to be opened more than once.\n *\n * @param rec_id\t    Device index for recorder/capture stream, or\n *\t\t\t    -1 to use the first capable device.\n * @param play_id\t    Device index for playback stream, or -1 to use \n *\t\t\t    the first capable device.\n * @param clock_rate\t    Sound device's clock rate to set.\n * @param channel_count\t    Set number of channels, 1 for mono, or 2 for\n *\t\t\t    stereo. The channel count determines the format\n *\t\t\t    of the frame.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Set the number of bits per sample. The normal \n *\t\t\t    value for this parameter is 16 bits per sample.\n * @param rec_cb\t    Callback to handle captured audio samples.\n * @param play_cb\t    Callback to be called when the sound player needs\n *\t\t\t    more audio samples to play.\n * @param user_data\t    User data to be associated with the stream.\n * @param p_snd_strm\t    Pointer to receive the stream instance.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_open(int rec_id,\n\t\t\t\t      int play_id,\n\t\t\t\t      unsigned clock_rate,\n\t\t\t\t      unsigned channel_count,\n\t\t\t\t      unsigned samples_per_frame,\n\t\t\t\t      unsigned bits_per_sample,\n\t\t\t\t      pjmedia_snd_rec_cb rec_cb,\n\t\t\t\t      pjmedia_snd_play_cb play_cb,\n\t\t\t\t      void *user_data,\n\t\t\t\t      pjmedia_snd_stream **p_snd_strm);\n\n\n/**\n * Create a unidirectional audio stream for capturing audio samples from\n * the sound device.\n *\n * @param index\t\t    Device index, or -1 to let the library choose the \n *\t\t\t    first available device.\n * @param clock_rate\t    Sound device's clock rate to set.\n * @param channel_count\t    Set number of channels, 1 for mono, or 2 for\n *\t\t\t    stereo. The channel count determines the format\n *\t\t\t    of the frame.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Set the number of bits per sample. The normal \n *\t\t\t    value for this parameter is 16 bits per sample.\n * @param rec_cb\t    Callback to handle captured audio samples.\n * @param user_data\t    User data to be associated with the stream.\n * @param p_snd_strm\t    Pointer to receive the stream instance.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_open_rec( int index,\n\t\t\t\t\t   unsigned clock_rate,\n\t\t\t\t\t   unsigned channel_count,\n\t\t\t\t\t   unsigned samples_per_frame,\n\t\t\t\t\t   unsigned bits_per_sample,\n\t\t\t\t\t   pjmedia_snd_rec_cb rec_cb,\n\t\t\t\t\t   void *user_data,\n\t\t\t\t\t   pjmedia_snd_stream **p_snd_strm);\n\n/**\n * Create a unidirectional audio stream for playing audio samples to the\n * sound device.\n *\n * @param index\t\t    Device index, or -1 to let the library choose the \n *\t\t\t    first available device.\n * @param clock_rate\t    Sound device's clock rate to set.\n * @param channel_count\t    Set number of channels, 1 for mono, or 2 for\n *\t\t\t    stereo. The channel count determines the format\n *\t\t\t    of the frame.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Set the number of bits per sample. The normal \n *\t\t\t    value for this parameter is 16 bits per sample.\n * @param play_cb\t    Callback to be called when the sound player needs\n *\t\t\t    more audio samples to play.\n * @param user_data\t    User data to be associated with the stream.\n * @param p_snd_strm\t    Pointer to receive the stream instance.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_open_player( int index,\n\t\t\t\t\t unsigned clock_rate,\n\t\t\t\t\t unsigned channel_count,\n\t\t\t\t\t unsigned samples_per_frame,\n\t\t\t\t\t unsigned bits_per_sample,\n\t\t\t\t\t pjmedia_snd_play_cb play_cb,\n\t\t\t\t\t void *user_data,\n\t\t\t\t\t pjmedia_snd_stream **p_snd_strm );\n\n\n/**\n * Get information about live stream.\n *\n * @param strm\t\tThe stream to be queried.\n * @param pi\t\tPointer to stream information to be filled up with\n *\t\t\tinformation about the stream.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_stream_get_info(pjmedia_snd_stream *strm,\n\t\t\t\t\t\t pjmedia_snd_stream_info *pi);\n\n\n/**\n * Start the stream.\n *\n * @param stream\tThe recorder or player stream.\n *\n * @return\t\tZero on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_stream_start(pjmedia_snd_stream *stream);\n\n/**\n * Stop the stream.\n *\n * @param stream\tThe recorder or player stream.\n *\n * @return\t\tZero on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_stream_stop(pjmedia_snd_stream *stream);\n\n/**\n * Destroy the stream.\n *\n * @param stream\tThe recorder of player stream.\n *\n * @return\t\tZero on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_stream_close(pjmedia_snd_stream *stream);\n\n/**\n * Deinitialize sound library.\n *\n * @return\t\tZero on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_deinit(void);\n\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_SOUND_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/sound_port.h",
    "content": "/* $Id: sound_port.h 4082 2012-04-24 13:09:14Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_SOUND_PORT_H__\n#define __PJMEDIA_SOUND_PORT_H__\n\n/**\n * @file sound_port.h\n * @brief Media port connection abstraction to sound device.\n */\n#include <pjmedia-audiodev/audiodev.h>\n#include <pjmedia/clock.h>\n#include <pjmedia/port.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJMED_SND_PORT Sound Device Port\n * @ingroup PJMEDIA_PORT_CLOCK\n * @brief Media Port Connection Abstraction to the Sound Device\n @{\n\n As explained in @ref PJMED_SND, the sound hardware abstraction provides\n some callbacks for its user:\n - it calls <b><tt>rec_cb</tt></b> callback when it has finished capturing\n   one media frame, and \n - it calls <b><tt>play_cb</tt></b> when it needs media frame to be \n   played to the sound playback hardware.\n\n The @ref PJMED_SND_PORT (the object being explained here) add a\n thin wrapper to the hardware abstraction:\n - it will call downstream port's <tt>put_frame()</tt>\n   when <b><tt>rec_cb()</tt></b> is called (i.e. when the sound hardware \n   has finished capturing frame), and \n - it will call downstream port's <tt>get_frame()</tt> when \n   <b><tt>play_cb()</tt></b> is called (i.e. every time the \n   sound hardware needs more frames to be played to the playback hardware).\n\n This simple abstraction enables media to flow automatically (and\n in timely manner) from the downstream media port to the sound device.\n In other words, the sound device port supplies media clock to\n the ports. The media clock concept is explained in @ref PJMEDIA_PORT_CLOCK\n section.\n\n Application registers downstream port to the sound device port by\n calling #pjmedia_snd_port_connect();\n \n */\n\n/**\n * Sound port options.\n */\nenum pjmedia_snd_port_option\n{\n    /** \n     * Don't start the audio device when creating a sound port.\n     */    \n    PJMEDIA_SND_PORT_NO_AUTO_START = 1\n};\n\n/**\n * This structure specifies the parameters to create the sound port.\n * Use pjmedia_snd_port_param_default() to initialize this structure with\n * default values (mostly zeroes)\n */\ntypedef struct pjmedia_snd_port_param\n{\n    /**\n     * Base structure.\n     */\n    pjmedia_aud_param base;\n    \n    /**\n     * Sound port creation options.\n     */\n    unsigned options;\n\n    /**\n     * Echo cancellation options/flags.\n     */\n    unsigned ec_options;\n\n    /**\n     * Arbitrary user data for playback and record preview callbacks below.\n     */\n    void *user_data;\n\n    /**\n     * Optional callback for audio frame preview right before queued to\n     * the speaker.\n     * Notes:\n     * - application MUST NOT block or perform long operation in the callback\n     *   as the callback may be executed in sound device thread\n     * - when using software echo cancellation, application MUST NOT modify\n     *   the audio data from within the callback, otherwise the echo canceller\n     *   will not work properly.\n     * - the return value of the callback will be ignored\n     */\n    pjmedia_aud_play_cb on_play_frame;\n\n    /**\n     * Optional callback for audio frame preview recorded from the microphone\n     * before being processed by any media component such as software echo\n     * canceller.\n     * Notes:\n     * - application MUST NOT block or perform long operation in the callback\n     *   as the callback may be executed in sound device thread\n     * - when using software echo cancellation, application MUST NOT modify\n     *   the audio data from within the callback, otherwise the echo canceller\n     *   will not work properly.\n     * - the return value of the callback will be ignored\n     */\n    pjmedia_aud_rec_cb on_rec_frame;\n\n} pjmedia_snd_port_param;\n\n/**\n * Initialize pjmedia_snd_port_param with default values.\n *\n * @param prm\t\t    The parameter.\n */\nPJ_DECL(void) pjmedia_snd_port_param_default(pjmedia_snd_port_param *prm);\n\n/**\n * This opaque type describes sound device port connection.\n * Sound device port is not a media port, but it is used to connect media\n * port to the sound device.\n */\ntypedef struct pjmedia_snd_port pjmedia_snd_port;\n\n\n/**\n * Create bidirectional sound port for both capturing and playback of\n * audio samples.\n *\n * @param pool\t\t    Pool to allocate sound port structure.\n * @param rec_id\t    Device index for recorder/capture stream, or\n *\t\t\t    -1 to use the first capable device.\n * @param play_id\t    Device index for playback stream, or -1 to use \n *\t\t\t    the first capable device.\n * @param clock_rate\t    Sound device's clock rate to set.\n * @param channel_count\t    Set number of channels, 1 for mono, or 2 for\n *\t\t\t    stereo. The channel count determines the format\n *\t\t\t    of the frame.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Set the number of bits per sample. The normal \n *\t\t\t    value for this parameter is 16 bits per sample.\n * @param options\t    Options flag.\n * @param p_port\t    Pointer to receive the sound device port instance.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error\n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_port_create( pj_pool_t *pool,\n\t\t\t\t\t      int rec_id,\n\t\t\t\t\t      int play_id,\n\t\t\t\t\t      unsigned clock_rate,\n\t\t\t\t\t      unsigned channel_count,\n\t\t\t\t\t      unsigned samples_per_frame,\n\t\t\t\t\t      unsigned bits_per_sample,\n\t\t\t\t\t      unsigned options,\n\t\t\t\t\t      pjmedia_snd_port **p_port);\n\n/**\n * Create unidirectional sound device port for capturing audio streams from \n * the sound device with the specified parameters.\n *\n * @param pool\t\t    Pool to allocate sound port structure.\n * @param index\t\t    Device index, or -1 to let the library choose the \n *\t\t\t    first available device.\n * @param clock_rate\t    Sound device's clock rate to set.\n * @param channel_count\t    Set number of channels, 1 for mono, or 2 for\n *\t\t\t    stereo. The channel count determines the format\n *\t\t\t    of the frame.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Set the number of bits per sample. The normal \n *\t\t\t    value for this parameter is 16 bits per sample.\n * @param options\t    Options flag.\n * @param p_port\t    Pointer to receive the sound device port instance.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error\n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_port_create_rec(pj_pool_t *pool,\n\t\t\t\t\t\t int index,\n\t\t\t\t\t\t unsigned clock_rate,\n\t\t\t\t\t\t unsigned channel_count,\n\t\t\t\t\t\t unsigned samples_per_frame,\n\t\t\t\t\t\t unsigned bits_per_sample,\n\t\t\t\t\t\t unsigned options,\n\t\t\t\t\t\t pjmedia_snd_port **p_port);\n\t\t\t\t\t      \n/**\n * Create unidirectional sound device port for playing audio streams with the \n * specified parameters.\n *\n * @param pool\t\t    Pool to allocate sound port structure.\n * @param index\t\t    Device index, or -1 to let the library choose the \n *\t\t\t    first available device.\n * @param clock_rate\t    Sound device's clock rate to set.\n * @param channel_count\t    Set number of channels, 1 for mono, or 2 for\n *\t\t\t    stereo. The channel count determines the format\n *\t\t\t    of the frame.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Set the number of bits per sample. The normal \n *\t\t\t    value for this parameter is 16 bits per sample.\n * @param options\t    Options flag.\n * @param p_port\t    Pointer to receive the sound device port instance.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error\n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_port_create_player(pj_pool_t *pool,\n\t\t\t\t\t\t    int index,\n\t\t\t\t\t\t    unsigned clock_rate,\n\t\t\t\t\t\t    unsigned channel_count,\n\t\t\t\t\t\t    unsigned samples_per_frame,\n\t\t\t\t\t\t    unsigned bits_per_sample,\n\t\t\t\t\t\t    unsigned options,\n\t\t\t\t\t\t    pjmedia_snd_port **p_port);\n\n\n/**\n * Create sound device port according to the specified parameters.\n *\n * @param pool\t\t    Pool to allocate sound port structure.\n * @param prm\t\t    Sound port parameter.\n * @param p_port\t    Pointer to receive the sound device port instance.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error\n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_port_create2(pj_pool_t *pool,\n\t\t\t\t\t      const pjmedia_snd_port_param *prm,\n\t\t\t\t\t      pjmedia_snd_port **p_port);\n\n\n/**\n * Destroy sound device port.\n *\n * @param snd_port\t    The sound device port.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error\n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_port_destroy(pjmedia_snd_port *snd_port);\n\n\n/**\n * Retrieve the sound stream associated by this sound device port.\n *\n * @param snd_port\t    The sound device port.\n *\n * @return\t\t    The sound stream instance.\n */\nPJ_DECL(pjmedia_aud_stream*) pjmedia_snd_port_get_snd_stream(\n\t\t\t\t\t\tpjmedia_snd_port *snd_port);\n\n\n/**\n * Change the echo cancellation settings. The echo cancellation settings \n * should have been specified when this sound port was created, by setting\n * the appropriate fields in the pjmedia_aud_param, because not all sound\n * device implementation supports changing the EC setting once the device\n * has been opened.\n *\n * The behavior of this function depends on whether device or software AEC\n * is being used. If the device supports AEC, this function will forward\n * the change request to the device and it will be up to the device whether\n * to support the request. If software AEC is being used (the software EC\n * will be used if the device does not support AEC), this function will\n * change the software EC settings.\n *\n * @param snd_port\t    The sound device port.\n * @param pool\t\t    Pool to re-create the echo canceller if necessary.\n * @param tail_ms\t    Maximum echo tail length to be supported, in\n *\t\t\t    miliseconds. If zero is specified, the EC would\n *\t\t\t    be disabled.\n * @param options\t    The options to be passed to #pjmedia_echo_create().\n *\t\t\t    This is only used if software EC is being used.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_port_set_ec( pjmedia_snd_port *snd_port,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      unsigned tail_ms,\n\t\t\t\t\t      unsigned options);\n\n\n/**\n * Get current echo canceller tail length, in miliseconds. The tail length \n * will be zero if EC is not enabled.\n *\n * @param snd_port\t    The sound device port.\n * @param p_length\t    Pointer to receive the tail length.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_port_get_ec_tail(pjmedia_snd_port *snd_port,\n\t\t\t\t\t\t  unsigned *p_length);\n\n\n/**\n * Get a clock source from the sound port.\n *\n * @param snd_port  The sound port.\n * @param dir       Sound port's direction.\n *\n * @return\t    The clock source.\n */\nPJ_DECL(pjmedia_clock_src *)\npjmedia_snd_port_get_clock_src( pjmedia_snd_port *snd_port,\n                                pjmedia_dir dir );\n\n\n/**\n * Reset the EC state in the sound port.\n *\n * @param snd_port\t    The sound device port.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_port_reset_ec_state(pjmedia_snd_port *snd_port);\n\n\n/**\n * Connect a port to the sound device port. If the sound device port has a\n * sound recorder device, then this will start periodic function call to\n * the port's put_frame() function. If the sound device has a sound player\n * device, then this will start periodic function call to the port's\n * get_frame() function.\n *\n * For this version of PJMEDIA, the media port MUST have the same audio\n * settings as the sound device port, or otherwise the connection will\n * fail. This means the port MUST have the same clock_rate, channel count,\n * samples per frame, and bits per sample as the sound device port.\n *\n * @param snd_port\t    The sound device port.\n * @param port\t\t    The media port to be connected.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error\n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_port_connect(pjmedia_snd_port *snd_port,\n\t\t\t\t\t      pjmedia_port *port);\n\n\n/**\n * Retrieve the port instance currently attached to the sound port, if any.\n *\n * @param snd_port\t    The sound device port.\n *\n * @return\t\t    The port instance currently attached to the \n *\t\t\t    sound device port, or NULL if there is no port\n *\t\t\t    currently attached to the sound device port.\n */\nPJ_DECL(pjmedia_port*) pjmedia_snd_port_get_port(pjmedia_snd_port *snd_port);\n\n\n/**\n * Disconnect currently attached port from the sound device port.\n *\n * @param snd_port\t    The sound device port.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_port_disconnect(pjmedia_snd_port *snd_port);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_SOUND_PORT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/splitcomb.h",
    "content": "/* $Id: splitcomb.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_SPLITCOMB_H__\n#define __PJMEDIA_SPLITCOMB_H__\n\n\n/**\n * @file splitcomb.h\n * @brief Media channel splitter/combiner port.\n */\n#include <pjmedia/port.h>\n\n\n/**\n * @addtogroup PJMEDIA_SPLITCOMB Media channel splitter/combiner\n * @ingroup PJMEDIA_PORT\n * @brief Split and combine multiple mono-channel media ports into\n *  a single multiple-channels media port\n * @{\n *\n * This section describes media port to split and combine media\n * channels in the stream.\n *\n * A splitter/combiner splits a single stereo/multichannels audio frame into\n * multiple audio frames to each channel when put_frame() is called, \n * and combines mono frames from each channel into a stereo/multichannel \n * frame when get_frame() is called. A common application for the splitter/\n * combiner is to split frames from stereo to mono and vise versa.\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Create a media splitter/combiner with the specified parameters.\n * When the splitter/combiner is created, it creates an instance of\n * pjmedia_port. This media port represents the stereo/multichannel side\n * of the splitter/combiner. Application needs to supply the splitter/\n * combiner with a media port for each audio channels.\n *\n * @param pool\t\t    Pool to allocate memory to create the splitter/\n *\t\t\t    combiner.\n * @param clock_rate\t    Audio clock rate/sampling rate.\n * @param channel_count\t    Number of channels.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Bits per sample.\n * @param options\t    Optional flags.\n * @param p_splitcomb\t    Pointer to receive the splitter/combiner.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate\n *\t\t\t    error code.\n */\nPJ_DECL(pj_status_t) pjmedia_splitcomb_create(pj_pool_t *pool,\n\t\t\t\t\t      unsigned clock_rate,\n\t\t\t\t\t      unsigned channel_count,\n\t\t\t\t\t      unsigned samples_per_frame,\n\t\t\t\t\t      unsigned bits_per_sample,\n\t\t\t\t\t      unsigned options,\n\t\t\t\t\t      pjmedia_port **p_splitcomb);\n\n/**\n * Supply the splitter/combiner with media port for the specified channel \n * number. The media port will be called at the\n * same phase as the splitter/combiner; which means that when application\n * calls get_frame() of the splitter/combiner, it will call get_frame()\n * for all ports that have the same phase. And similarly for put_frame().\n *\n * @param splitcomb\t    The splitter/combiner.\n * @param ch_num\t    Audio channel starting number (zero based).\n * @param options\t    Must be zero at the moment.\n * @param port\t\t    The media port.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error\n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) pjmedia_splitcomb_set_channel(pjmedia_port *splitcomb,\n\t\t\t\t\t\t   unsigned ch_num,\n\t\t\t\t\t\t   unsigned options,\n\t\t\t\t\t\t   pjmedia_port *port);\n\n/**\n * Create a reverse phase media port for the specified channel number.\n * For channels with reversed phase, when application calls put_frame() to\n * the splitter/combiner, the splitter/combiner will only put the frame to\n * a buffer. Later on, when application calls get_frame() on the channel's\n * media port, it will return the frame that are available in the buffer.\n * The same process happens when application calls put_frame() to the\n * channel's media port, it will only put the frame to another buffer, which\n * will be returned when application calls get_frame() to the splitter's \n * media port. So this effectively reverse the phase of the media port.\n *\n * @param pool\t\t    The pool to allocate memory for the port and\n *\t\t\t    buffers.\n * @param splitcomb\t    The splitter/combiner.\n * @param ch_num\t    Audio channel starting number (zero based).\n * @param options\t    Normally is zero, but the lower 8-bit of the \n *\t\t\t    options can be used to specify the number of \n *\t\t\t    buffers in the circular buffer. If zero, then\n *\t\t\t    default number will be used (default: 8).\n * @param p_chport\t    The media port created with reverse phase for\n *\t\t\t    the specified audio channel.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error\n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) \npjmedia_splitcomb_create_rev_channel( pj_pool_t *pool,\n\t\t\t\t      pjmedia_port *splitcomb,\n\t\t\t\t      unsigned ch_num,\n\t\t\t\t      unsigned options,\n\t\t\t\t      pjmedia_port **p_chport);\n\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_SPLITCOMB_H__ */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/stereo.h",
    "content": "/* $Id: stereo.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_STEREO_H__\n#define __PJMEDIA_STEREO_H__\n\n/**\n * @file stereo.h\n * @brief Monochannel and multichannel converter.\n */\n\n#include <pjmedia/errno.h>\n#include <pjmedia/port.h>\n#include <pjmedia/types.h>\n#include <pj/assert.h>\n\n\n/**\n * @defgroup PJMEDIA_STEREO Monochannel and multichannel audio frame converter\n * @ingroup PJMEDIA_FRAME_OP\n * @brief Mono - multi-channels audio conversion\n * @{\n *\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Multichannel to monochannel conversion mixes samples from all channels\n * into the monochannel.\n */\n#define PJMEDIA_STEREO_MIX  PJ_TRUE\n\n\n\n/**\n * Multichannel to monochannel conversion, it has two operation mode specified\n * by param options, @see pjmedia_stereo_options. This function can work safely\n * using the same buffer (in place conversion).\n *\n * @param mono\t\t    Output buffer to store the mono frame extracted \n *\t\t\t    from the multichannels frame.\n * @param multi\t\t    Input frame containing multichannels audio.\n * @param channel_count\t    Number of channels in the input frame.\n * @param samples_per_frame Number of samples in the input frame.\n * @param mix\t\t    If the value is PJ_TRUE then the input channels \n *\t\t\t    will be mixed to produce output frame, otherwise\n *\t\t\t    only frame from channel_src will be copied to the\n *\t\t\t    output frame.\n * @param channel_src\t    When mixing is disabled, the mono output frame\n *\t\t\t    will be copied from this channel number.\n *\n * @return\t\t    PJ_SUCCESS on success;\n */\nPJ_INLINE(pj_status_t) pjmedia_convert_channel_nto1(pj_int16_t mono[],\n\t\t\t\t\t\t    const pj_int16_t multi[],\n\t\t\t\t\t\t    unsigned channel_count,\n\t\t\t\t\t\t    unsigned samples_per_frame,\n\t\t\t\t\t\t    pj_bool_t mix,\n\t\t\t\t\t\t    unsigned channel_src)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(mono && multi && channel_count && samples_per_frame &&\n\t\t     channel_src < channel_count,  PJ_EINVAL);\n\n    if (mix==PJ_FALSE) {\n\tfor (i = channel_src; i < samples_per_frame; i += channel_count) {\n\t    *mono = multi[i];\n\t    ++mono;\n\t}\n    } else {\n\tunsigned j;\n\tfor (i = 0; i < samples_per_frame; i += channel_count) {\n\t    int tmp = 0;\n\t    for(j = 0; j < channel_count; ++j)\n\t\ttmp += multi[i+j];\n\n\t    if (tmp > 32767) tmp = 32767;\n\t    else if (tmp < -32768) tmp = -32768;\n\t    *mono = (pj_int16_t) tmp;\n\t    ++mono;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Monochannel to multichannel conversion, it will just duplicate the samples\n * from monochannel frame to all channels in the multichannel frame. \n * This function can work safely using the same buffer (in place conversion)\n * as long as the buffer is big enough for the multichannel samples.\n *\n * @param multi\t\t    Output buffer to store the multichannels frame \n *\t\t\t    mixed from the mono frame.\n * @param mono\t\t    The input monochannel audio frame.\n * @param channel_count\t    Desired number of channels in the output frame.\n * @param samples_per_frame Number of samples in the input frame.\n * @param options\t    Options for conversion, currently must be zero.\n *\n * @return\t\t    PJ_SUCCESS on success;\n */\nPJ_INLINE(pj_status_t) pjmedia_convert_channel_1ton(pj_int16_t multi[],\n\t\t\t\t\t\t    const pj_int16_t mono[],\n\t\t\t\t\t\t    unsigned channel_count,\n\t\t\t\t\t\t    unsigned samples_per_frame,\n\t\t\t\t\t\t    unsigned options)\n{\n    const pj_int16_t *src;\n\n    PJ_ASSERT_RETURN(mono && multi && channel_count && samples_per_frame, \n\t\t     PJ_EINVAL);\n    PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(options);\n\n    src = mono + samples_per_frame - 1;\n    samples_per_frame *= channel_count;\n    while (samples_per_frame) {\n\tunsigned i;\n\tfor (i=1; i<=channel_count; ++i)\n\t    multi[samples_per_frame-i] = *src;\n\tsamples_per_frame -= channel_count;\n\t--src;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/** \n * Options for channel converter port. The #pjmedia_stereo_options is also\n * valid for this port options.\n */\ntypedef enum pjmedia_stereo_port_options\n{\n    /**\n     * Specifies whether this port should not destroy downstream port when \n     * this port is destroyed.\n     */\n    PJMEDIA_STEREO_DONT_DESTROY_DN  = 4\n} pjmedia_stereo_port_options;\n\n\n/**\n * Create a mono-multi channel converter port. This creates a converter session,\n * which will adjust the samples of audio frame to a different channel count\n * when the port's get_frame() and put_frame() is called.\n *\n * When the port's get_frame() is called, this port will get a frame from \n * the downstream port and convert the frame to the target channel count before\n * returning it to the caller.\n *\n * When the port's put_frame() is called, this port will convert the frame\n * to the downstream port's channel count before giving the frame to the \n * downstream port.\n *\n * @param pool\t\t\tPool to allocate the structure and buffers.\n * @param dn_port\t\tThe downstream port, which channel count is to\n *\t\t\t\tbe converted to the target channel count.\n * @param channel_count\t\tThis port channel count.\n * @param options\t\tBitmask flags from #pjmedia_stereo_port_options\n *\t\t\t\tand also application may add PJMEDIA_STEREO_MIX\n *\t\t\t\tto mix channels.\n *\t\t\t\tWhen this flag is zero, the default behavior\n *\t\t\t\tis to use simple N-to-1 channel converter and \n *\t\t\t\tto destroy downstream port when this port is \n *\t\t\t\tdestroyed.\n * @param p_port\t\tPointer to receive the stereo port instance.\n *\n * @return PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_stereo_port_create( pj_pool_t *pool,\n\t\t\t\t\t\t pjmedia_port *dn_port,\n\t\t\t\t\t\t unsigned channel_count,\n\t\t\t\t\t\t unsigned options,\n\t\t\t\t\t\t pjmedia_port **p_port );\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_STEREO_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/stream.h",
    "content": "/* $Id: stream.h 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_STREAM_H__\n#define __PJMEDIA_STREAM_H__\n\n\n/**\n * @file stream.h\n * @brief Media Stream.\n */\n\n#include <pjmedia/codec.h>\n#include <pjmedia/endpoint.h>\n#include <pjmedia/jbuf.h>\n#include <pjmedia/port.h>\n#include <pjmedia/rtcp.h>\n#include <pjmedia/transport.h>\n#include <pjmedia/vid_codec.h>\n#include <pj/sock.h>\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJMED_STRM Streams\n * @ingroup PJMEDIA_PORT\n * @brief Communicating with remote peer via the network\n * @{\n *\n * A media stream is a bidirectional multimedia communication between two\n * endpoints. It corresponds to a media description (m= line) in SDP\n * session descriptor.\n *\n * A media stream consists of two unidirectional channels:\n *  - encoding channel, which transmits unidirectional media to remote, and\n *  - decoding channel, which receives unidirectional media from remote.\n *\n * A media stream exports media port interface (see @ref PJMEDIA_PORT)\n * and application normally uses this interface to interconnect the stream\n * to other PJMEDIA components.\n *\n * A media stream internally manages the following objects:\n *  - an instance of media codec (see @ref PJMEDIA_CODEC),\n *  - an @ref PJMED_JBUF,\n *  - two instances of RTP sessions (#pjmedia_rtp_session, one for each\n *    direction),\n *  - one instance of RTCP session (#pjmedia_rtcp_session),\n *  - and a reference to media transport to send and receive packets\n *    to/from the network (see @ref PJMEDIA_TRANSPORT).\n *\n * Streams are created by calling #pjmedia_stream_create(), specifying\n * #pjmedia_stream_info structure in the parameter. Application can construct\n * the #pjmedia_stream_info structure manually, or use \n * #pjmedia_stream_info_from_sdp() or #pjmedia_session_info_from_sdp() \n * functions to construct the #pjmedia_stream_info from local and remote \n * SDP session descriptors.\n *\n * Application can also use @ref PJMEDIA_SESSION to indirectly create the\n * streams.\n */\n\n/**\n * Opaque declaration for media channel.\n * Media channel is unidirectional flow of media from sender to\n * receiver.\n */\ntypedef struct pjmedia_channel pjmedia_channel;\n\n/** \n * This structure describes media stream information. Each media stream\n * corresponds to one \"m=\" line in SDP session descriptor, and it has\n * its own RTP/RTCP socket pair.\n */\ntypedef struct pjmedia_stream_info\n{\n    pjmedia_type\ttype;\t    /**< Media type (audio, video)\t    */\n    pjmedia_tp_proto\tproto;\t    /**< Transport protocol (RTP/AVP, etc.) */\n    pjmedia_dir\t\tdir;\t    /**< Media direction.\t\t    */\n    pj_sockaddr\t\trem_addr;   /**< Remote RTP address\t\t    */\n    pj_sockaddr\t\trem_rtcp;   /**< Optional remote RTCP address. If\n\t\t\t\t\t sin_family is zero, the RTP address\n\t\t\t\t\t will be calculated from RTP.\t    */\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n    pj_bool_t\t\trtcp_xr_enabled;\n\t\t\t\t    /**< Specify whether RTCP XR is enabled.*/\n    pj_uint32_t\t\trtcp_xr_interval; /**< RTCP XR interval.            */\n    pj_sockaddr\t\trtcp_xr_dest;/**<Additional remote RTCP XR address.\n\t\t\t\t         This is useful for third-party (e.g:\n\t\t\t\t\t network monitor) to monitor the \n\t\t\t\t\t stream. If sin_family is zero, \n\t\t\t\t\t this will be ignored.\t\t    */\n#endif\n    pjmedia_codec_info\tfmt;\t    /**< Incoming codec format info.\t    */\n    pjmedia_codec_param *param;\t    /**< Optional codec param.\t\t    */\n    unsigned\t\ttx_pt;\t    /**< Outgoing codec paylaod type.\t    */\n    unsigned\t\trx_pt;\t    /**< Incoming codec paylaod type.\t    */\n    unsigned\t\ttx_maxptime;/**< Outgoing codec max ptime.\t    */\n    int\t\t        tx_event_pt;/**< Outgoing pt for telephone-events.  */\n    int\t\t\trx_event_pt;/**< Incoming pt for telephone-events.  */\n    pj_uint32_t\t\tssrc;\t    /**< RTP SSRC.\t\t\t    */\n    pj_uint32_t\t\trtp_ts;\t    /**< Initial RTP timestamp.\t\t    */\n    pj_uint16_t\t\trtp_seq;    /**< Initial RTP sequence number.\t    */\n    pj_uint8_t\t\trtp_seq_ts_set;\n\t\t\t\t    /**< Bitmask flags if initial RTP sequence \n\t\t\t\t         and/or timestamp for sender are set.\n\t\t\t\t\t bit 0/LSB : sequence flag \n\t\t\t\t\t bit 1     : timestamp flag \t    */\n    int\t\t\tjb_init;    /**< Jitter buffer init delay in msec.  \n\t\t\t\t\t (-1 for default).\t\t    */\n    int\t\t\tjb_min_pre; /**< Jitter buffer minimum prefetch\n\t\t\t\t\t delay in msec (-1 for default).    */\n    int\t\t\tjb_max_pre; /**< Jitter buffer maximum prefetch\n\t\t\t\t\t delay in msec (-1 for default).    */\n    int\t\t\tjb_max;\t    /**< Jitter buffer max delay in msec.   */\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0\n    pj_bool_t\t\tuse_ka;\t    /**< Stream keep-alive and NAT hole punch\n\t\t\t\t\t (see #PJMEDIA_STREAM_ENABLE_KA)\n\t\t\t\t\t is enabled?\t\t\t    */\n#endif\n    pj_bool_t           rtcp_sdes_bye_disabled; \n                                    /**< Disable automatic sending of RTCP\n                                         SDES and BYE.                      */\n} pjmedia_stream_info;\n\n\n/**\n * This function will initialize the stream info based on information\n * in both SDP session descriptors for the specified stream index. \n * The remaining information will be taken from default codec parameters. \n * If socket info array is specified, the socket will be copied to the \n * session info as well.\n *\n * @param si\t\tStream info structure to be initialized.\n * @param pool\t\tPool to allocate memory.\n * @param endpt\t\tPJMEDIA endpoint instance.\n * @param local\t\tLocal SDP session descriptor.\n * @param remote\tRemote SDP session descriptor.\n * @param stream_idx\tMedia stream index in the session descriptor.\n *\n * @return\t\tPJ_SUCCESS if stream info is successfully initialized.\n */\nPJ_DECL(pj_status_t)\npjmedia_stream_info_from_sdp( pjmedia_stream_info *si,\n\t\t\t      pj_pool_t *pool,\n\t\t\t      pjmedia_endpt *endpt,\n\t\t\t      const pjmedia_sdp_session *local,\n\t\t\t      const pjmedia_sdp_session *remote,\n\t\t\t      unsigned stream_idx);\n\n\n/**\n * Create a media stream based on the specified parameter. After the stream\n * has been created, application normally would want to get the media port \n * interface of the streams, by calling pjmedia_stream_get_port(). The \n * media port interface exports put_frame() and get_frame() function, used\n * to transmit and receive media frames from the stream.\n *\n * Without application calling put_frame() and get_frame(), there will be \n * no media frames transmitted or received by the stream.\n *\n * @param endpt\t\tMedia endpoint.\n * @param pool\t\tPool to allocate memory for the stream. A large\n *\t\t\tnumber of memory may be needed because jitter\n *\t\t\tbuffer needs to preallocate some storage.\n * @param info\t\tStream information.\n * @param tp\t\tStream transport instance used to transmit \n *\t\t\tand receive RTP/RTCP packets to/from the underlying \n *\t\t\ttransport. \n * @param user_data\tArbitrary user data (for future callback feature).\n * @param p_stream\tPointer to receive the media stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_stream_create(pjmedia_endpt *endpt,\n\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t   const pjmedia_stream_info *info,\n\t\t\t\t\t   pjmedia_transport *tp,\n\t\t\t\t\t   void *user_data,\n\t\t\t\t\t   pjmedia_stream **p_stream);\n\n/**\n * Destroy the media stream.\n *\n * @param stream\tThe media stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_stream_destroy(pjmedia_stream *stream);\n\n\n/**\n * Get the last frame type retreived from the jitter buffer.\n *\n * @param stream\tThe media stream.\n *\n * @return\t\tJitter buffer frame type.\n */\nPJ_DEF(char) pjmedia_stream_get_last_jb_frame_type(pjmedia_stream *stream);\n\n\n/**\n * Get the media port interface of the stream. The media port interface\n * declares put_frame() and get_frame() function, which is the only \n * way for application to transmit and receive media frames from the\n * stream.\n *\n * @param stream\tThe media stream.\n * @param p_port\tPointer to receive the port interface.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_stream_get_port(pjmedia_stream *stream,\n\t\t\t\t\t     pjmedia_port **p_port );\n\n\n/**\n * Get the media transport object associated with this stream.\n *\n * @param st\t\tThe media stream.\n *\n * @return\t\tThe transport object being used by the stream.\n */\nPJ_DECL(pjmedia_transport*) pjmedia_stream_get_transport(pjmedia_stream *st);\n\n\n/**\n * Start the media stream. This will start the appropriate channels\n * in the media stream, depending on the media direction that was set\n * when the stream was created.\n *\n * @param stream\tThe media stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_stream_start(pjmedia_stream *stream);\n\n\n/**\n * Get the stream info.\n *\n * @param stream\tThe media stream.\n * @param info\t\tStream info.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_stream_get_info( const pjmedia_stream *stream,\n\t\t\t\t\t      pjmedia_stream_info *info);\n\n/**\n * Get the stream statistics. See also\n * #pjmedia_stream_get_stat_jbuf()\n *\n * @param stream\tThe media stream.\n * @param stat\t\tMedia stream statistics.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_stream_get_stat( const pjmedia_stream *stream,\n\t\t\t\t\t      pjmedia_rtcp_stat *stat);\n\n\n/**\n * Reset the stream statistics.\n *\n * @param stream\tThe media stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_stream_reset_stat(pjmedia_stream *stream);\n\n\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n/**\n * Get the stream extended report statistics (RTCP XR).\n *\n * @param stream\tThe media stream.\n * @param stat\t\tMedia stream extended report statistics.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_stream_get_stat_xr( const pjmedia_stream *stream,\n\t\t\t\t\t         pjmedia_rtcp_xr_stat *stat);\n#endif\n\n/**\n * Get current jitter buffer state. See also\n * #pjmedia_stream_get_stat()\n *\n * @param stream\tThe media stream.\n * @param state\t\tJitter buffer state.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_stream_get_stat_jbuf(const pjmedia_stream *stream,\n\t\t\t\t\t\t  pjmedia_jb_state *state);\n\n\n/**\n * Pause the individual channel in the stream.\n *\n * @param stream\tThe media channel.\n * @param dir\t\tWhich direction to pause.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_stream_pause( pjmedia_stream *stream,\n\t\t\t\t\t   pjmedia_dir dir);\n\n/**\n * Resume the individual channel in the stream.\n *\n * @param stream\tThe media channel.\n * @param dir\t\tWhich direction to resume.\n *\n * @return\t\tPJ_SUCCESS on success;\n */\nPJ_DECL(pj_status_t) pjmedia_stream_resume(pjmedia_stream *stream,\n\t\t\t\t\t   pjmedia_dir dir);\n\n/**\n * Transmit DTMF to this stream. The DTMF will be transmitted uisng\n * RTP telephone-events as described in RFC 2833. This operation is\n * only valid for audio stream.\n *\n * @param stream\tThe media stream.\n * @param ascii_digit\tString containing digits to be sent to remote as \n *\t\t\tdescribed on RFC 2833 section 3.10. \n *\t\t\tIf PJMEDIA_HAS_DTMF_FLASH is enabled, character 'R' is\n *\t\t\tused to represent the event type 16 (flash) as stated \n *\t\t\tin RFC 4730.\n *\t\t\tCurrently the maximum number of digits are 32.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_stream_dial_dtmf(pjmedia_stream *stream,\n\t\t\t\t\t      const pj_str_t *ascii_digit);\n\n\n/**\n * Check if the stream has incoming DTMF digits in the incoming DTMF\n * queue. Incoming DTMF digits received via RFC 2833 mechanism are\n * saved in the incoming digits queue.\n *\n * @param stream\tThe media stream.\n *\n * @return\t\tNon-zero (PJ_TRUE) if the stream has received DTMF\n *\t\t\tdigits in the .\n */\nPJ_DECL(pj_bool_t) pjmedia_stream_check_dtmf(pjmedia_stream *stream);\n\n\n/**\n * Retrieve the incoming DTMF digits from the stream, and remove the digits\n * from stream's DTMF buffer. Note that the digits buffer will not be NULL \n * terminated.\n *\n * @param stream\tThe media stream.\n * @param ascii_digits\tBuffer to receive the digits. The length of this\n *\t\t\tbuffer is indicated in the \"size\" argument.\n * @param size\t\tOn input, contains the maximum digits to be copied\n *\t\t\tto the buffer.\n *\t\t\tOn output, it contains the actual digits that has\n *\t\t\tbeen copied to the buffer.\n *\n * @return\t\tNon-zero (PJ_TRUE) if the stream has received DTMF\n *\t\t\tdigits in the .\n */\nPJ_DECL(pj_status_t) pjmedia_stream_get_dtmf( pjmedia_stream *stream,\n\t\t\t\t\t      char *ascii_digits,\n\t\t\t\t\t      unsigned *size);\n\n\n/**\n * Set callback to be called upon receiving DTMF digits. If callback is\n * registered, the stream will not buffer incoming DTMF but rather call\n * the callback as soon as DTMF digit is received completely.\n *\n * @param stream\tThe media stream.\n * @param cb\t\tCallback to be called upon receiving DTMF digits.\n *\t\t\tThe DTMF digits will be given to the callback as\n *\t\t\tASCII digits.\n * @param user_data\tUser data to be returned back when the callback\n *\t\t\tis called.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t)\npjmedia_stream_set_dtmf_callback(pjmedia_stream *stream,\n\t\t\t\t void (*cb)(pjmedia_stream*, \n\t\t\t\t\t    void *user_data, \n\t\t\t\t\t    int digit), \n\t\t\t\t void *user_data);\n\n\n/**\n * Send RTCP SDES for the media stream.\n *\n * @param stream\tThe media stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_stream_send_rtcp_sdes( pjmedia_stream *stream );\n\n/**\n * Send RTCP BYE for the media stream.\n *\n * @param stream\tThe media stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t)\npjmedia_stream_send_rtcp_bye( pjmedia_stream *stream );\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_STREAM_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/stream_common.h",
    "content": "/* $Id: stream_common.h 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_STREAM_COMMON_H__\n#define __PJMEDIA_STREAM_COMMON_H__\n\n\n/**\n * @file stream_common.h\n * @brief Stream common functions.\n */\n\n#include <pjmedia/codec.h>\n#include <pjmedia/sdp.h>\n\n\nPJ_BEGIN_DECL\n\n/**\n * This is internal function for parsing SDP format parameter of specific\n * format or payload type, used by stream in generating stream info from SDP.\n *\n * @param pool\t\tPool to allocate memory, if pool is NULL, the fmtp\n *\t\t\tstring pointers will point to the original string in\n *\t\t\tthe SDP media descriptor.\n * @param m\t\tThe SDP media containing the format parameter to\n *\t\t\tbe parsed.\n * @param pt\t\tThe format or payload type.\n * @param fmtp\t\tThe format parameter to store the parsing result.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_stream_info_parse_fmtp(pj_pool_t *pool,\n\t\t\t\t\t\t    const pjmedia_sdp_media *m,\n\t\t\t\t\t\t    unsigned pt,\n\t\t\t\t\t\t    pjmedia_codec_fmtp *fmtp);\n\n\nPJ_END_DECL\n\n\n#endif /* __PJMEDIA_STREAM_COMMON_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/symbian_sound_aps.h",
    "content": "/* $Id: symbian_sound_aps.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_SYMBIAN_SOUND_APS_H__\n#define __PJMEDIA_SYMBIAN_SOUND_APS_H__\n\n\n/**\n * @file symbian_sound_aps.h\n * @brief Sound device wrapper using Audio Proxy Server on \n * Symbian S60 3rd edition.\n */\n#include <pjmedia/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * Set audio routing for APS sound device.\n *\n * @param stream\tThe sound device stream, the stream should be started \n *\t\t\tbefore calling this function.\n * @param route\t\tAudio routing to be set.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_snd_aps_set_route( pjmedia_snd_stream *stream,\n\t\t\t\t\t\tpjmedia_snd_route route);\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_SYMBIAN_SOUND_APS_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/tonegen.h",
    "content": "/* $Id: tonegen.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_TONEGEN_PORT_H__\n#define __PJMEDIA_TONEGEN_PORT_H__\n\n/**\n * @file tonegen.h\n * @brief Tone (sine, MF, DTMF) generator media port.\n */\n#include <pjmedia/port.h>\n\n\n/**\n * @defgroup PJMEDIA_MF_DTMF_TONE_GENERATOR Multi-frequency tone generator\n * @ingroup PJMEDIA_PORT\n * @brief Multi-frequency tone generator\n * @{\n *\n * This page describes tone generator media port. A tone generator can be\n * used to generate a single frequency sine wave or dual frequency tones\n * such as DTMF.\n *\n * The tone generator media port provides two functions to generate tones.\n * The function #pjmedia_tonegen_play() can be used to generate arbitrary\n * single or dual frequency tone, and #pjmedia_tonegen_play_digits() is\n * used to play digits such as DTMF. Each tone specified in the playback\n * function has individual on and off signal duration that must be\n * specified by application.\n *\n * In order to play digits such as DTMF, the tone generator is equipped\n * with digit map, which contain information about the frequencies of\n * the digits. The default digit map is DTMF (0-9,a-d,*,#), but application\n * may specifiy different digit map to the tone generator by calling\n * #pjmedia_tonegen_set_digit_map() function.\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * This structure describes individual MF digits to be played\n * with #pjmedia_tonegen_play().\n */\ntypedef struct pjmedia_tone_desc\n{\n    short   freq1;\t    /**< First frequency.\t\t\t    */\n    short   freq2;\t    /**< Optional second frequency.\t\t    */\n    short   on_msec;\t    /**< Playback ON duration, in miliseconds.\t    */\n    short   off_msec;\t    /**< Playback OFF duration, ini miliseconds.    */\n    short   volume;\t    /**< Volume (1-32767), or 0 for default, which\n\t\t\t\t PJMEDIA_TONEGEN_VOLUME will be used.\t    */\n    short   flags;\t    /**< Currently internal flags, must be 0\t    */\n} pjmedia_tone_desc;\n\n\n\n/**\n * This structure describes individual MF digits to be played\n * with #pjmedia_tonegen_play_digits().\n */\ntypedef struct pjmedia_tone_digit\n{\n    char    digit;\t    /**< The ASCI identification for the digit.\t    */\n    short   on_msec;\t    /**< Playback ON duration, in miliseconds.\t    */\n    short   off_msec;\t    /**< Playback OFF duration, ini miliseconds.    */\n    short   volume;\t    /**< Volume (1-32767), or 0 for default, which\n\t\t\t\t PJMEDIA_TONEGEN_VOLUME will be used.\t    */\n} pjmedia_tone_digit;\n\n\n/**\n * This structure describes the digit map which is used by the tone generator\n * to produce tones from an ASCII digits.\n * Digit map used by a particular tone generator can be retrieved/set with\n * #pjmedia_tonegen_get_digit_map() and #pjmedia_tonegen_set_digit_map().\n */\ntypedef struct pjmedia_tone_digit_map\n{\n    unsigned count;\t    /**< Number of digits in the map.\t\t*/\n\n    struct {\n\tchar    digit;\t    /**< The ASCI identification for the digit.\t*/\n\tshort   freq1;\t    /**< First frequency.\t\t\t*/\n\tshort   freq2;\t    /**< Optional second frequency.\t\t*/\n    } digits[16];\t    /**< Array of digits in the digit map.\t*/\n} pjmedia_tone_digit_map;\n\n\n/**\n * Tone generator options.\n */\nenum\n{\n    /**\n     * Play the tones in loop, restarting playing the first tone after\n     * the last tone has been played.\n     */\n    PJMEDIA_TONEGEN_LOOP    = 1,\n\n    /**\n     * Disable mutex protection to the tone generator.\n     */\n    PJMEDIA_TONEGEN_NO_LOCK = 2\n};\n\n\n/**\n * Create an instance of tone generator with the specified parameters.\n * When the tone generator is first created, it will be loaded with the\n * default digit map.\n *\n * @param pool\t\t    Pool to allocate memory for the port structure.\n * @param clock_rate\t    Sampling rate.\n * @param channel_count\t    Number of channels. Currently only mono and stereo\n *\t\t\t    are supported.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Number of bits per sample. This version of PJMEDIA\n *\t\t\t    only supports 16bit per sample.\n * @param options\t    Option flags. Application may specify \n *\t\t\t    PJMEDIA_TONEGEN_LOOP to play the tone in a loop.\n * @param p_port\t    Pointer to receive the port instance.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate\n *\t\t\t    error code.\n */\nPJ_DECL(pj_status_t) pjmedia_tonegen_create(pj_pool_t *pool,\n\t\t\t\t\t    unsigned clock_rate,\n\t\t\t\t\t    unsigned channel_count,\n\t\t\t\t\t    unsigned samples_per_frame,\n\t\t\t\t\t    unsigned bits_per_sample,\n\t\t\t\t\t    unsigned options,\n\t\t\t\t\t    pjmedia_port **p_port);\n\n\n/**\n * Create an instance of tone generator with the specified parameters.\n * When the tone generator is first created, it will be loaded with the\n * default digit map.\n *\n * @param pool\t\t    Pool to allocate memory for the port structure.\n * @param name\t\t    Optional name for the tone generator.\n * @param clock_rate\t    Sampling rate.\n * @param channel_count\t    Number of channels. Currently only mono and stereo\n *\t\t\t    are supported.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Number of bits per sample. This version of PJMEDIA\n *\t\t\t    only supports 16bit per sample.\n * @param options\t    Option flags. Application may specify \n *\t\t\t    PJMEDIA_TONEGEN_LOOP to play the tone in a loop.\n * @param p_port\t    Pointer to receive the port instance.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate\n *\t\t\t    error code.\n */\nPJ_DECL(pj_status_t) pjmedia_tonegen_create2(pj_pool_t *pool,\n\t\t\t\t\t     const pj_str_t *name,\n\t\t\t\t\t     unsigned clock_rate,\n\t\t\t\t\t     unsigned channel_count,\n\t\t\t\t\t     unsigned samples_per_frame,\n\t\t\t\t\t     unsigned bits_per_sample,\n\t\t\t\t\t     unsigned options,\n\t\t\t\t\t     pjmedia_port **p_port);\n\n\n/**\n * Check if the tone generator is still busy producing some tones.\n *\n * @param tonegen\t    The tone generator instance.\n *\n * @return\t\t    Non-zero if busy.\n */\nPJ_DECL(pj_bool_t) pjmedia_tonegen_is_busy(pjmedia_port *tonegen);\n\n\n/**\n * Instruct the tone generator to stop current processing.\n *\n * @param tonegen\t    The tone generator instance.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_tonegen_stop(pjmedia_port *tonegen);\n\n\n/**\n * Rewind the playback. This will start the playback to the first\n * tone in the playback list.\n *\n * @param tonegen\t    The tone generator instance.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_tonegen_rewind(pjmedia_port *tonegen);\n\n\n/**\n * Instruct the tone generator to play single or dual frequency tones \n * with the specified duration. The new tones will be appended to currently\n * playing tones, unless #pjmedia_tonegen_stop() is called before calling\n * this function. The playback will begin as soon as  the first get_frame()\n * is called to the generator.\n *\n * @param tonegen\t    The tone generator instance.\n * @param count\t\t    The number of tones in the array.\n * @param tones\t\t    Array of tones to be played.\n * @param options\t    Option flags. Application may specify \n *\t\t\t    PJMEDIA_TONEGEN_LOOP to play the tone in a loop.\n *\n * @return\t\t    PJ_SUCCESS on success, or PJ_ETOOMANY if\n *\t\t\t    there are too many digits in the queue.\n */\nPJ_DECL(pj_status_t) pjmedia_tonegen_play(pjmedia_port *tonegen,\n\t\t\t\t\t  unsigned count,\n\t\t\t\t\t  const pjmedia_tone_desc tones[],\n\t\t\t\t\t  unsigned options);\n\n/**\n * Instruct the tone generator to play multiple MF digits with each of\n * the digits having individual ON/OFF duration. Each of the digit in the\n * digit array must have the corresponding descriptor in the digit map.\n * The new tones will be appended to currently playing tones, unless \n * #pjmedia_tonegen_stop() is called before calling this function. \n * The playback will begin as soon as the first get_frame() is called \n * to the generator.\n *\n * @param tonegen\t    The tone generator instance.\n * @param count\t\t    Number of digits in the array.\n * @param digits\t    Array of MF digits.\n * @param options\t    Option flags. Application may specify \n *\t\t\t    PJMEDIA_TONEGEN_LOOP to play the tone in a loop.\n *\n * @return\t\t    PJ_SUCCESS on success, or PJ_ETOOMANY if\n *\t\t\t    there are too many digits in the queue, or\n *\t\t\t    PJMEDIA_RTP_EINDTMF if invalid digit is\n *\t\t\t    specified.\n */\nPJ_DECL(pj_status_t) pjmedia_tonegen_play_digits(pjmedia_port *tonegen,\n\t\t\t\t\t\t unsigned count,\n\t\t\t\t\t\t const pjmedia_tone_digit digits[],\n\t\t\t\t\t\t unsigned options);\n\n\n/**\n * Get the digit-map currently used by this tone generator.\n *\n * @param tonegen\t    The tone generator instance.\n * @param m\t\t    On output, it will be filled with the pointer to\n *\t\t\t    the digitmap currently used by the tone generator.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_tonegen_get_digit_map(pjmedia_port *tonegen,\n\t\t\t\t\t\t   const pjmedia_tone_digit_map **m);\n\n\n/**\n * Set digit map to be used by the tone generator.\n *\n * @param tonegen\t    The tone generator instance.\n * @param m\t\t    Digitmap to be used by the tone generator.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_tonegen_set_digit_map(pjmedia_port *tonegen,\n\t\t\t\t\t\t   pjmedia_tone_digit_map *m);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_TONEGEN_PORT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/transport.h",
    "content": "/* $Id: transport.h 4345 2013-02-13 07:43:32Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_TRANSPORT_H__\n#define __PJMEDIA_TRANSPORT_H__\n\n\n/**\n * @file transport.h Media Transport Interface\n * @brief Transport interface.\n */\n\n#include <pjmedia/types.h>\n#include <pjmedia/errno.h>\n#include <pj/string.h>\n\n/**\n * @defgroup PJMEDIA_TRANSPORT Media Transport\n * @brief Transports.\n * @{\n * The media transport (#pjmedia_transport) is the object to send and\n * receive media packets over the network. The media transport interface\n * allows the library to be extended to support different types of \n * transports to send and receive packets.\n *\n * The media transport is declared as #pjmedia_transport \"class\", which\n * declares \"interfaces\" to use the class in #pjmedia_transport_op\n * structure. For the user of the media transport (normally the user of\n * media transport is media stream, see \\ref PJMED_STRM), these transport\n * \"methods\" are wrapped with API such as #pjmedia_transport_attach(),\n * so it should not need to call the function pointer inside \n * #pjmedia_transport_op directly.\n *\n * The connection between \\ref PJMED_STRM and media transport is shown in\n * the diagram below:\n\n   \\image html media-transport.PNG\n\n\n * \\section PJMEDIA_TRANSPORT_H_USING Basic Media Transport Usage\n *\n * The media transport's life-cycle normally follows the following stages.\n *\n * \\subsection PJMEDIA_TRANSPORT_H_CREATE Creating the Media Transport\n *\n *  Application creates the media transport when it needs to establish\n *    media session to remote peer. The media transport is created using\n *    specific function to create that particular transport; for example,\n *    for UDP media transport, it is created with #pjmedia_transport_udp_create()\n *    or #pjmedia_transport_udp_create2() functions. Different media\n *    transports will provide different API to create those transports.\n *\n *  Alternatively, application may create pool of media transports when\n *    it is first started up. Using this approach probably is better, since\n *    application has to specify the RTP port when sending the initial\n *    session establishment request (e.g. SIP INVITE request), thus if\n *    application only creates the media transport later when media is to be\n *    established (normally when 200/OK is received, or when 18x is received\n *    for early media), there is a possibility that the particular RTP\n *    port might have been occupied by other programs. Also it is more\n *    efficient since sockets don't need to be closed and re-opened between\n *    calls.\n *\n *\n * \\subsection PJMEDIA_TRANSPORT_H_ATTACH Attaching and Using the Media Transport.\n *\n *  Application specifies the media transport instance when creating\n *    the media session (#pjmedia_session_create()). Alternatively, it\n *    may create the media stream directly with #pjmedia_stream_create()\n *    and specify the transport instance in the argument. (Note: media\n *    session is a high-level abstraction for media communications between\n *    two endpoints, and it may contain more than one media streams, for\n *    example, an audio stream and a video stream).\n *\n *  When stream is created, it will \"attach\" itself to the media \n *    transport by calling #pjmedia_transport_attach(), which is a thin\n *    wrapper which calls \"attach()\" method of the media transport's \n *    \"virtual function pointer\" (#pjmedia_transport_op). Among other things,\n *    the stream specifies two callback functions to the transport: one\n *    callback function will be called by transport when it receives RTP\n *    packet, and another callback for incoming RTCP packet. The \n *    #pjmedia_transport_attach() function also establish the destination\n *    of the outgoing RTP and RTCP packets.\n *\n *  When the stream needs to send outgoing RTP/RTCP packets, it will\n *    call #pjmedia_transport_send_rtp() and #pjmedia_transport_send_rtcp()\n *    of the media transport API, which is a thin wrapper to call send_rtp() \n *    and send_rtcp() methods in the media transport's \"virtual function \n *    pointer\"  (#pjmedia_transport_op).\n *\n *  When the stream is destroyed, it will \"detach\" itself from\n *    the media transport by calling #pjmedia_transport_detach(), which is\n *    a thin wrapper which calls \"detach()\" method of the media transport's \n *    \"virtual function pointer\" (#pjmedia_transport_op). After the transport\n *    is detached from its user (the stream), it will no longer report \n *    incoming RTP/RTCP packets to the stream, and it will refuse to send\n *    outgoing packets since the destination has been cleared.\n *\n *\n * \\subsection PJMEDIA_TRANSPORT_H_REUSE Reusing the Media Transport.\n *\n *  After transport has been detached, application may re-attach the\n *    transport to another stream if it wants to. Detaching and re-attaching\n *    media transport may be preferable than closing and re-opening the\n *    transport, since it is more efficient (sockets don't need to be\n *    closed and re-opened). However it is up to the application to choose\n *    which method is most suitable for its uses.\n *\n * \n * \\subsection PJMEDIA_TRANSPORT_H_DESTROY Destroying the Media Transport.\n *\n *  Finally if application no longer needs the media transport, it will\n *    call #pjmedia_transport_close() function, which is thin wrapper which \n *    calls \"destroy()\" method of the media transport's  \"virtual function \n *    pointer\" (#pjmedia_transport_op). This function releases\n *    all resources used by the transport, such as sockets and memory.\n *\n *\n * \\section offer_answer Interaction with SDP Offer/Answer\n \n   For basic UDP transport, the \\ref PJMEDIA_TRANSPORT_H_USING above is\n   sufficient to use the media transport. However, more complex media\n   transports such as \\ref PJMEDIA_TRANSPORT_SRTP and \\ref\n   PJMEDIA_TRANSPORT_ICE requires closer interactions with SDP offer and\n   answer negotiation.\n\n   The media transports can interact with the SDP offer/answer via\n   these APIs:\n     - #pjmedia_transport_media_create(), to initialize the media transport\n       for new media session,\n     - #pjmedia_transport_encode_sdp(), to encode SDP offer or answer,\n     - #pjmedia_transport_media_start(), to activate the settings that\n       have been negotiated by SDP offer answer, and\n     - #pjmedia_transport_media_stop(), to deinitialize the media transport\n       and reset the transport to its idle state.\n   \n   The usage of these API in the context of SDP offer answer will be \n   described below.\n\n   \\subsection media_create Initializing Transport for New Session\n\n   Application must call #pjmedia_transport_media_create() before using\n   the transport for a new session.\n\n   \\subsection creat_oa Creating SDP Offer and Answer\n\n   The #pjmedia_transport_encode_sdp() is used to put additional information\n   from the transport to the local SDP, before the SDP is sent and negotiated\n   with remote SDP.\n\n   When creating an offer, call #pjmedia_transport_encode_sdp() with\n   local SDP (and NULL as \\a rem_sdp). The media transport will add the\n   relevant attributes in the local SDP. Application then gives the local\n   SDP to the invite session to be sent to remote agent.\n\n   When creating an answer, also call #pjmedia_transport_encode_sdp(),\n   but this time specify both local and remote SDP to the function. The \n   media transport will once again modify the local SDP and add relevant\n   attributes to the local SDP, if the appropriate attributes related to\n   the transport functionality are present in remote offer. The remote\n   SDP does not contain the relevant attributes, then the specific transport\n   functionality will not be activated for the session.\n\n   The #pjmedia_transport_encode_sdp() should also be called when application\n   sends subsequent SDP offer or answer. The media transport will encode\n   the appropriate attributes based on the state of the session.\n\n   \\subsection media_start Offer/Answer Completion\n\n   Once both local and remote SDP have been negotiated by the \n   \\ref PJMEDIA_SDP_NEG (normally this is part of PJSIP invite session),\n   application should give both local and remote SDP to \n   #pjmedia_transport_media_start() so that the settings are activated\n   for the session. This function should be called for both initial and\n   subsequent SDP negotiation.\n\n   \\subsection media_stop Stopping Transport\n\n   Once session is stop application must call #pjmedia_transport_media_stop()\n   to deactivate the transport feature. Application may reuse the transport\n   for subsequent media session by repeating the #pjmedia_transport_media_create(),\n   #pjmedia_transport_encode_sdp(), #pjmedia_transport_media_start(), and\n   #pjmedia_transport_media_stop() above.\n\n * \\section PJMEDIA_TRANSPORT_H_IMPL Implementing Media Transport\n *\n * To implement a new type of media transport, one needs to \"subclass\" the\n * media transport \"class\" (#pjmedia_transport) by providing the \"methods\"\n * in the media transport \"interface\" (#pjmedia_transport_op), and provides\n * a function to create this new type of transport (similar to \n * #pjmedia_transport_udp_create() function).\n *\n * The media transport is expected to run indepently, that is there should\n * be no polling like function to poll the transport for incoming RTP/RTCP\n * packets. This normally can be done by registering the media sockets to\n * the media endpoint's IOQueue, which allows the transport to be notified\n * when incoming packet has arrived.\n *\n * Alternatively, media transport may utilize thread(s) internally to wait\n * for incoming packets. The thread then will call the appropriate RTP or\n * RTCP callback provided by its user (stream) whenever packet is received.\n * If the transport's user is a stream, then the callbacks provided by the\n * stream will be thread-safe, so the transport may call these callbacks\n * without having to serialize the access with some mutex protection. But\n * the media transport may still have to protect its internal data with\n * mutex protection, since it may be called by application's thread (for\n * example, to send RTP/RTCP packets).\n *\n */\n\n\n#include <pjmedia/sdp.h>\n\nPJ_BEGIN_DECL\n\n\n/**\n * Forward declaration for media transport.\n */\ntypedef struct pjmedia_transport pjmedia_transport;\n\n/**\n * Forward declaration for media transport info.\n */\ntypedef struct pjmedia_transport_info pjmedia_transport_info;\n\n/**\n * This enumeration specifies the general behaviour of media processing\n */\ntypedef enum pjmedia_tranport_media_option\n{\n    /**\n     * When this flag is specified, the transport will not perform media\n     * transport validation, this is useful when transport is stacked with\n     * other transport, for example when transport UDP is stacked under\n     * transport SRTP, media transport validation only need to be done by \n     * transport SRTP.\n     */\n    PJMEDIA_TPMED_NO_TRANSPORT_CHECKING = 1\n\n} pjmedia_tranport_media_option;\n\n\n/**\n * Media socket info is used to describe the underlying sockets\n * to be used as media transport.\n */\ntypedef struct pjmedia_sock_info\n{\n    /** The RTP socket handle */\n    pj_sock_t\t    rtp_sock;\n\n    /** Address to be advertised as the local address for the RTP\n     *  socket, which does not need to be equal as the bound\n     *  address (for example, this address can be the address resolved\n     *  with STUN).\n     */\n    pj_sockaddr\t    rtp_addr_name;\n\n    /** The RTCP socket handle. */\n    pj_sock_t\t    rtcp_sock;\n\n    /** Address to be advertised as the local address for the RTCP\n     *  socket, which does not need to be equal as the bound\n     *  address (for example, this address can be the address resolved\n     *  with STUN).\n     */\n    pj_sockaddr\t    rtcp_addr_name;\n\n} pjmedia_sock_info;\n\n\n/**\n * This structure describes the operations for the stream transport.\n */\nstruct pjmedia_transport_op\n{\n    /**\n     * Get media socket info from the specified transport.\n     *\n     * Application should call #pjmedia_transport_get_info() instead\n     */\n    pj_status_t (*get_info)(pjmedia_transport *tp,\n\t\t\t    pjmedia_transport_info *info);\n\n    /**\n     * This function is called by the stream when the transport is about\n     * to be used by the stream for the first time, and it tells the transport\n     * about remote RTP address to send the packet and some callbacks to be \n     * called for incoming packets.\n     *\n     * Application should call #pjmedia_transport_attach() instead of \n     * calling this function directly.\n     */\n    pj_status_t (*attach)(pjmedia_transport *tp,\n\t\t\t  void *user_data,\n\t\t\t  const pj_sockaddr_t *rem_addr,\n\t\t\t  const pj_sockaddr_t *rem_rtcp,\n\t\t\t  unsigned addr_len,\n\t\t\t  void (*rtp_cb)(void *user_data,\n\t\t\t\t\t void *pkt,\n\t\t\t\t\t pj_ssize_t size),\n\t\t\t  void (*rtcp_cb)(void *user_data,\n\t\t\t\t\t  void *pkt,\n\t\t\t\t\t  pj_ssize_t size));\n\n    /**\n     * This function is called by the stream when the stream no longer\n     * needs the transport (normally when the stream is about to be closed).\n     * After the transport is detached, it will ignore incoming\n     * RTP/RTCP packets, and will refuse to send outgoing RTP/RTCP packets.\n     * Application may re-attach the media transport to another transport \n     * user (e.g. stream) after the transport has been detached.\n     *\n     * Application should call #pjmedia_transport_detach() instead of \n     * calling this function directly.\n     */\n    void (*detach)(pjmedia_transport *tp,\n\t\t   void *user_data);\n\n    /**\n     * This function is called by the stream to send RTP packet using the \n     * transport.\n     *\n     * Application should call #pjmedia_transport_send_rtp() instead of \n     * calling this function directly.\n     */\n    pj_status_t (*send_rtp)(pjmedia_transport *tp,\n\t\t\t    const void *pkt,\n\t\t\t    pj_size_t size);\n\n    /**\n     * This function is called by the stream to send RTCP packet using the\n     * transport.\n     *\n     * Application should call #pjmedia_transport_send_rtcp() instead of \n     * calling this function directly.\n     */\n    pj_status_t (*send_rtcp)(pjmedia_transport *tp,\n\t\t\t     const void *pkt,\n\t\t\t     pj_size_t size);\n\n    /**\n     * This function is called by the stream to send RTCP packet using the\n     * transport with destination address other than default specified in\n     * #pjmedia_transport_attach().\n     *\n     * Application should call #pjmedia_transport_send_rtcp2() instead of \n     * calling this function directly.\n     */\n    pj_status_t (*send_rtcp2)(pjmedia_transport *tp,\n\t\t\t      const pj_sockaddr_t *addr,\n\t\t\t      unsigned addr_len,\n\t\t\t      const void *pkt,\n\t\t\t      pj_size_t size);\n\n    /**\n     * Prepare the transport for a new media session.\n     *\n     * Application should call #pjmedia_transport_media_create() instead of \n     * calling this function directly.\n     */\n    pj_status_t (*media_create)(pjmedia_transport *tp,\n\t\t\t\tpj_pool_t *sdp_pool,\n\t\t\t\tunsigned options,\n\t\t\t\tconst pjmedia_sdp_session *remote_sdp,\n\t\t\t\tunsigned media_index);\n\n    /**\n     * This function is called by application to generate the SDP parts\n     * related to transport type, e.g: ICE, SRTP.\n     *\n     * Application should call #pjmedia_transport_encode_sdp() instead of\n     * calling this function directly.\n     */\n    pj_status_t (*encode_sdp)(pjmedia_transport *tp,\n\t\t\t      pj_pool_t *sdp_pool,\n\t\t\t      pjmedia_sdp_session *sdp_local,\n\t\t\t      const pjmedia_sdp_session *rem_sdp,\n\t\t\t      unsigned media_index);\n\n    /**\n     * This function is called by application to start the transport\n     * based on local and remote SDP.\n     *\n     * Application should call #pjmedia_transport_media_start() instead of \n     * calling this function directly.\n     */\n    pj_status_t (*media_start) (pjmedia_transport *tp,\n\t\t\t        pj_pool_t *tmp_pool,\n\t\t\t        const pjmedia_sdp_session *sdp_local,\n\t\t\t        const pjmedia_sdp_session *sdp_remote,\n\t\t\t\tunsigned media_index);\n\n    /**\n     * This function is called by application to stop the transport.\n     *\n     * Application should call #pjmedia_transport_media_stop() instead of \n     * calling this function directly.\n     */\n    pj_status_t (*media_stop)  (pjmedia_transport *tp);\n\n    /**\n     * This function can be called to simulate packet lost.\n     *\n     * Application should call #pjmedia_transport_simulate_lost() instead of \n     * calling this function directly.\n     */\n    pj_status_t (*simulate_lost)(pjmedia_transport *tp,\n\t\t\t\t pjmedia_dir dir,\n\t\t\t\t unsigned pct_lost);\n\n    /**\n     * This function can be called to destroy this transport.\n     *\n     * Application should call #pjmedia_transport_close() instead of \n     * calling this function directly.\n     */\n    pj_status_t (*destroy)(pjmedia_transport *tp);\n};\n\n\n/**\n * @see pjmedia_transport_op.\n */\ntypedef struct pjmedia_transport_op pjmedia_transport_op;\n\n\n/** \n * Media transport type.\n */\ntypedef enum pjmedia_transport_type\n{\n    /** Media transport using standard UDP */\n    PJMEDIA_TRANSPORT_TYPE_UDP,\n\n    /** Media transport using ICE */\n    PJMEDIA_TRANSPORT_TYPE_ICE,\n\n    /** \n     * Media transport SRTP, this transport is actually security adapter to be\n     * stacked with other transport to enable encryption on the underlying\n     * transport.\n     */\n    PJMEDIA_TRANSPORT_TYPE_SRTP,\n\n    /**\n     * Start of user defined transport.\n     */\n    PJMEDIA_TRANSPORT_TYPE_USER\n\n} pjmedia_transport_type;\n\n\n/**\n * This structure declares media transport. A media transport is called\n * by the stream to transmit a packet, and will notify stream when\n * incoming packet is arrived.\n */\nstruct pjmedia_transport\n{\n    /** Transport name (for logging purpose). */\n    char\t\t     name[PJ_MAX_OBJ_NAME];\n\n    /** Transport type. */\n    pjmedia_transport_type   type;\n\n    /** Transport's \"virtual\" function table. */\n    pjmedia_transport_op    *op;\n\n    /** Application/user data */\n    void\t\t    *user_data;\n};\n\n/**\n * This structure describes storage buffer of transport specific info.\n * The actual transport specific info contents will be defined by transport\n * implementation. Note that some transport implementations do not need to\n * provide specific info, since the general socket info is enough.\n */\ntypedef struct pjmedia_transport_specific_info\n{\n    /**\n     * Specify media transport type.\n     */\n    pjmedia_transport_type   type;\n\n    /**\n     * Specify storage buffer size of transport specific info.\n     */\n    int\t\t\t     cbsize;\n\n    /**\n     * Storage buffer of transport specific info.\n     */\n    char\t\t     buffer[PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE];\n\n} pjmedia_transport_specific_info;\n\n\n/**\n * This structure describes transport informations, including general \n * socket information and specific information of single transport or \n * stacked transports (e.g: SRTP stacked on top of UDP)\n */\nstruct pjmedia_transport_info\n{\n    /**\n     * General socket info.\n     */\n    pjmedia_sock_info sock_info;\n\n    /**\n     * Remote address where RTP/RTCP originated from. In case this transport\n     * hasn't ever received packet, the \n     */\n    pj_sockaddr\t    src_rtp_name;\n    pj_sockaddr\t    src_rtcp_name;\n\n    /**\n     * Specifies number of transport specific info included.\n     */\n    unsigned specific_info_cnt;\n\n    /**\n     * Buffer storage of transport specific info.\n     */\n    pjmedia_transport_specific_info spc_info[PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT];\n\n};\n\n\n/**\n * Initialize transport info.\n *\n * @param info\t    Transport info to be initialized.\n */\nPJ_INLINE(void) pjmedia_transport_info_init(pjmedia_transport_info *info)\n{\n    pj_bzero(info, sizeof(pjmedia_transport_info));\n    info->sock_info.rtp_sock = info->sock_info.rtcp_sock = PJ_INVALID_SOCKET;\n}\n\n\n/**\n * Get media transport info from the specified transport and all underlying \n * transports if any. The transport also contains information about socket info\n * which describes the local address of the transport, and would be needed\n * for example to fill in the \"c=\" and \"m=\" line of local SDP.\n *\n * @param tp\t    The transport.\n * @param info\t    Media transport info to be initialized.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_INLINE(pj_status_t) pjmedia_transport_get_info(pjmedia_transport *tp,\n\t\t\t\t\t\t  pjmedia_transport_info *info)\n{\n    if (tp && tp->op && tp->op->get_info)\n\treturn (*tp->op->get_info)(tp, info);\n    \n    return PJ_ENOTSUP;\n}\n\n\n/**\n * Utility API to get transport type specific info from the specified media\n * transport info.\n * \n * @param info\t    Media transport info.\n * @param type\t    Media transport type.\n *\n * @return\t    Pointer to media transport specific info, or NULL if\n * \t\t    specific info for the transport type is not found.\n */\nPJ_INLINE(void*) pjmedia_transport_info_get_spc_info(\n\t\t\t\t\t\tpjmedia_transport_info *info,\n\t\t\t\t\t\tpjmedia_transport_type type)\n{\n    unsigned i;\n    for (i = 0; i < info->specific_info_cnt; ++i) {\n\tif (info->spc_info[i].type == type)\n\t    return (void*)info->spc_info[i].buffer;\n    }\n    return NULL;\n}\n\n\n/**\n * Attach callbacks to be called on receipt of incoming RTP/RTCP packets.\n * This is just a simple wrapper which calls <tt>attach()</tt> member of \n * the transport.\n *\n * @param tp\t    The media transport.\n * @param user_data Arbitrary user data to be set when the callbacks are \n *\t\t    called.\n * @param rem_addr  Remote RTP address to send RTP packet to.\n * @param rem_rtcp  Optional remote RTCP address. If the argument is NULL\n *\t\t    or if the address is zero, the RTCP address will be\n *\t\t    calculated from the RTP address (which is RTP port\n *\t\t    plus one).\n * @param addr_len  Length of the remote address.\n * @param rtp_cb    Callback to be called when RTP packet is received on\n *\t\t    the transport.\n * @param rtcp_cb   Callback to be called when RTCP packet is received on\n *\t\t    the transport.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_INLINE(pj_status_t) pjmedia_transport_attach(pjmedia_transport *tp,\n\t\t\t\t\t        void *user_data,\n\t\t\t\t\t        const pj_sockaddr_t *rem_addr,\n\t\t\t\t\t\tconst pj_sockaddr_t *rem_rtcp,\n\t\t\t\t\t        unsigned addr_len,\n\t\t\t\t\t        void (*rtp_cb)(void *user_data,\n\t\t\t\t\t\t\t       void *pkt,\n\t\t\t\t\t\t\t       pj_ssize_t),\n\t\t\t\t\t        void (*rtcp_cb)(void *usr_data,\n\t\t\t\t\t\t\t        void*pkt,\n\t\t\t\t\t\t\t        pj_ssize_t))\n{\n    return tp->op->attach(tp, user_data, rem_addr, rem_rtcp, addr_len, \n\t\t\t  rtp_cb, rtcp_cb);\n}\n\n\n/**\n * Detach callbacks from the transport.\n * This is just a simple wrapper which calls <tt>detach()</tt> member of \n * the transport. After the transport is detached, it will ignore incoming\n * RTP/RTCP packets, and will refuse to send outgoing RTP/RTCP packets.\n * Application may re-attach the media transport to another transport user\n * (e.g. stream) after the transport has been detached.\n *\n * @param tp\t    The media transport.\n * @param user_data User data which must match the previously set value\n *\t\t    on attachment.\n */\nPJ_INLINE(void) pjmedia_transport_detach(pjmedia_transport *tp,\n\t\t\t\t\t void *user_data)\n{\n    tp->op->detach(tp, user_data);\n}\n\n\n/**\n * Send RTP packet with the specified media transport. This is just a simple\n * wrapper which calls <tt>send_rtp()</tt> member of the transport. The \n * RTP packet will be delivered to the destination address specified in\n * #pjmedia_transport_attach() function.\n *\n * @param tp\t    The media transport.\n * @param pkt\t    The packet to send.\n * @param size\t    Size of the packet.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_INLINE(pj_status_t) pjmedia_transport_send_rtp(pjmedia_transport *tp,\n\t\t\t\t\t\t  const void *pkt,\n\t\t\t\t\t\t  pj_size_t size)\n{\n    return (*tp->op->send_rtp)(tp, pkt, size);\n}\n\n\n/**\n * Send RTCP packet with the specified media transport. This is just a simple\n * wrapper which calls <tt>send_rtcp()</tt> member of the transport. The \n * RTCP packet will be delivered to the destination address specified in\n * #pjmedia_transport_attach() function.\n *\n * @param tp\t    The media transport.\n * @param pkt\t    The packet to send.\n * @param size\t    Size of the packet.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_INLINE(pj_status_t) pjmedia_transport_send_rtcp(pjmedia_transport *tp,\n\t\t\t\t\t\t  const void *pkt,\n\t\t\t\t\t\t  pj_size_t size)\n{\n    return (*tp->op->send_rtcp)(tp, pkt, size);\n}\n\n\n/**\n * Send RTCP packet with the specified media transport. This is just a simple\n * wrapper which calls <tt>send_rtcp2()</tt> member of the transport. The \n * RTCP packet will be delivered to the destination address specified in\n * param addr, if addr is NULL, RTCP packet will be delivered to destination \n * address specified in #pjmedia_transport_attach() function.\n *\n * @param tp\t    The media transport.\n * @param addr\t    The destination address.\n * @param addr_len  Length of destination address.\n * @param pkt\t    The packet to send.\n * @param size\t    Size of the packet.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_INLINE(pj_status_t) pjmedia_transport_send_rtcp2(pjmedia_transport *tp,\n\t\t\t\t\t\t    const pj_sockaddr_t *addr,\n\t\t\t\t\t\t    unsigned addr_len,\n\t\t\t\t\t\t    const void *pkt,\n\t\t\t\t\t\t    pj_size_t size)\n{\n    return (*tp->op->send_rtcp2)(tp, addr, addr_len, pkt, size);\n}\n\n\n/**\n * Prepare the media transport for a new media session, Application must\n * call this function before starting a new media session using this\n * transport.\n *\n * This is just a simple wrapper which calls <tt>media_create()</tt> member \n * of the transport.\n *\n * @param tp\t\tThe media transport.\n * @param sdp_pool\tPool object to allocate memory related to SDP\n *\t\t\tmessaging components.\n * @param options\tOption flags, from #pjmedia_tranport_media_option\n * @param rem_sdp\tRemote SDP if local SDP is an answer, otherwise\n *\t\t\tspecify NULL if SDP is an offer.\n * @param media_index\tMedia index in SDP.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_INLINE(pj_status_t) pjmedia_transport_media_create(pjmedia_transport *tp,\n\t\t\t\t    pj_pool_t *sdp_pool,\n\t\t\t\t    unsigned options,\n\t\t\t\t    const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t    unsigned media_index)\n{\n    return (*tp->op->media_create)(tp, sdp_pool, options, rem_sdp, \n\t\t\t\t   media_index);\n}\n\n\n/**\n * Put transport specific information into the SDP. This function can be\n * called to put transport specific information in the initial or\n * subsequent SDP offer or answer.\n *\n * This is just a simple wrapper which calls <tt>encode_sdp()</tt> member \n * of the transport.\n *\n * @param tp\t\tThe media transport.\n * @param sdp_pool\tPool object to allocate memory related to SDP\n *\t\t\tmessaging components.\n * @param sdp\t\tThe local SDP to be filled in information from the\n *\t\t\tmedia transport.\n * @param rem_sdp\tRemote SDP if local SDP is an answer, otherwise\n *\t\t\tspecify NULL if SDP is an offer.\n * @param media_index\tMedia index in SDP.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_INLINE(pj_status_t) pjmedia_transport_encode_sdp(pjmedia_transport *tp,\n\t\t\t\t\t    pj_pool_t *sdp_pool,\n\t\t\t\t\t    pjmedia_sdp_session *sdp,\n\t\t\t\t\t    const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t\t    unsigned media_index)\n{\n    return (*tp->op->encode_sdp)(tp, sdp_pool, sdp, rem_sdp, media_index);\n}\n\n\n/**\n * Start the transport session with the settings in both local and remote \n * SDP. The actual work that is done by this function depends on the \n * underlying transport type. For SRTP, this will activate the encryption\n * and decryption based on the keys found the SDPs. For ICE, this will\n * start ICE negotiation according to the information found in the SDPs.\n *\n * This is just a simple wrapper which calls <tt>media_start()</tt> member \n * of the transport.\n *\n * @param tp\t\tThe media transport.\n * @param tmp_pool\tThe memory pool for allocating temporary objects.\n * @param sdp_local\tLocal SDP.\n * @param sdp_remote\tRemote SDP.\n * @param media_index\tMedia index in the SDP.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_INLINE(pj_status_t) pjmedia_transport_media_start(pjmedia_transport *tp,\n\t\t\t\t    pj_pool_t *tmp_pool,\n\t\t\t\t    const pjmedia_sdp_session *sdp_local,\n\t\t\t\t    const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t    unsigned media_index)\n{\n    return (*tp->op->media_start)(tp, tmp_pool, sdp_local, sdp_remote, \n\t\t\t\t  media_index);\n}\n\n\n/**\n * This API should be called when the session is stopped, to allow the media\n * transport to release its resources used for the session.\n *\n * This is just a simple wrapper which calls <tt>media_stop()</tt> member \n * of the transport.\n *\n * @param tp\t\tThe media transport.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_INLINE(pj_status_t) pjmedia_transport_media_stop(pjmedia_transport *tp)\n{\n    return (*tp->op->media_stop)(tp);\n}\n\n/**\n * Close media transport. This is just a simple wrapper which calls \n * <tt>destroy()</tt> member of the transport. This function will free\n * all resources created by this transport (such as sockets, memory, etc.).\n *\n * @param tp\t    The media transport.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_INLINE(pj_status_t) pjmedia_transport_close(pjmedia_transport *tp)\n{\n    if (tp->op->destroy)\n\treturn (*tp->op->destroy)(tp);\n    else\n\treturn PJ_SUCCESS;\n}\n\n/**\n * Simulate packet lost in the specified direction (for testing purposes).\n * When enabled, the transport will randomly drop packets to the specified\n * direction.\n *\n * @param tp\t    The media transport.\n * @param dir\t    Media direction to which packets will be randomly dropped.\n * @param pct_lost  Percent lost (0-100). Set to zero to disable packet\n *\t\t    lost simulation.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_INLINE(pj_status_t) pjmedia_transport_simulate_lost(pjmedia_transport *tp,\n\t\t\t\t\t\t       pjmedia_dir dir,\n\t\t\t\t\t\t       unsigned pct_lost)\n{\n    return (*tp->op->simulate_lost)(tp, dir, pct_lost);\n}\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_TRANSPORT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/transport_adapter_sample.h",
    "content": "/* $Id: transport_adapter_sample.h 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_TRANSPORT_ADAPTER_SAMPLE_H__\n#define __PJMEDIA_TRANSPORT_ADAPTER_SAMPLE_H__\n\n\n/**\n * @file transport_adapter_sample.h\n * @brief Sample Media Transport Adapter\n */\n\n#include <pjmedia/transport.h>\n\n\n/**\n * @defgroup PJMEDIA_TRANSPORT_ADAPTER_SAMPLE Sample Transport Adapter\n * @ingroup PJMEDIA_TRANSPORT\n * @brief Example on how to create transport adapter.\n * @{\n *\n * This describes a sample implementation of transport adapter, similar to\n * the way the SRTP transport adapter works.\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Create the transport adapter, specifying the underlying transport to be\n * used to send and receive RTP/RTCP packets.\n *\n * @param endpt\t\tThe media endpoint.\n * @param name\t\tOptional name to identify this media transport\n *\t\t\tfor logging purposes.\n * @param base_tp\tThe base/underlying media transport to send and\n * \t\t\treceive RTP/RTCP packets.\n * @param del_base\tSpecify whether the base transport should also be\n * \t\t\tdestroyed when destroy() is called upon us.\n * @param p_tp\t\tPointer to receive the media transport instance.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_tp_adapter_create( pjmedia_endpt *endpt,\n\t\t\t\t\t        const char *name,\n\t\t\t\t\t        pjmedia_transport *base_tp,\n\t\t\t\t\t        pj_bool_t del_base,\n\t\t\t\t\t\tpjmedia_transport **p_tp);\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_TRANSPORT_ADAPTER_SAMPLE_H__ */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/transport_ice.h",
    "content": "/* $Id: transport_ice.h 4350 2013-02-15 03:57:31Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_TRANSPORT_ICE_H__\n#define __PJMEDIA_TRANSPORT_ICE_H__\n\n\n/**\n * @file transport_ice.h\n * @brief ICE capable media transport.\n */\n\n#include <pjmedia/stream.h>\n#include <pjnath/ice_strans.h>\n\n\n/**\n * @defgroup PJMEDIA_TRANSPORT_ICE ICE Media Transport \n * @ingroup PJMEDIA_TRANSPORT\n * @brief Interactive Connectivity Establishment (ICE) transport\n * @{\n *\n * This describes the implementation of media transport using\n * Interactive Connectivity Establishment (ICE) protocol.\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Structure containing callbacks to receive ICE notifications.\n */\ntypedef struct pjmedia_ice_cb\n{\n    /**\n     * This callback will be called when ICE negotiation completes.\n     *\n     * @param tp\tPJMEDIA ICE transport.\n     * @param op\tThe operation\n     * @param status\tOperation status.\n     */\n    void    (*on_ice_complete)(pjmedia_transport *tp,\n\t\t\t       pj_ice_strans_op op,\n\t\t\t       pj_status_t status);\n\n    /**\n     * This callback will be called when ICE state changes.\n     *\n     * @param tp\tPJMEDIA ICE transport.\n     * @param prev\tPrevious state.\n     * @param curr\tCurrent state.\n     */\n    void    (*on_ice_state)(pjmedia_transport *tp,\n\t\t\t    pj_ice_strans_state prev,\n\t\t\t    pj_ice_strans_state curr);\n\n    /**\n     * This callback will be called when ICE is stopped.\n     *\n     * @param tp\tPJMEDIA ICE transport.\n     * @param reason\tReason for stopping ICE.\n     * @param err\tError code\n     */\n    void    (*on_ice_stop)(pjmedia_transport *tp,\n\t\t\t   char *reason,\n\t\t\t   pj_status_t err);\n\n} pjmedia_ice_cb;\n\n\n/**\n * This structure specifies ICE transport specific info. This structure\n * will be filled in media transport specific info.\n */\ntypedef struct pjmedia_ice_transport_info\n{\n    /**\n     * Specifies whether ICE is used, i.e. SDP offer and answer indicates\n     * that both parties support ICE and ICE should be used for the session.\n     */\n    pj_bool_t active;\n\n    /**\n     * ICE sesion state.\n     */\n    pj_ice_strans_state sess_state;\n\n    /**\n     * Session role.\n     */\n    pj_ice_sess_role role;\n\n    /**\n     * Number of components in the component array. Before ICE negotiation\n     * is complete, the number represents the number of components of the\n     * local agent. After ICE negotiation has been completed successfully,\n     * the number represents the number of common components between local\n     * and remote agents.\n     */\n    unsigned comp_cnt;\n\n    /**\n     * Array of ICE components. Typically the first element denotes RTP and\n     * second element denotes RTCP.\n     */\n    struct\n    {\n\t/**\n\t * Local candidate type.\n\t */\n\tpj_ice_cand_type    lcand_type;\n\n\t/**\n\t * The local address.\n\t */\n\tpj_sockaddr\t    lcand_addr;\n\n\t/**\n\t * Remote candidate type.\n\t */\n\tpj_ice_cand_type    rcand_type;\n\n\t/**\n\t * Remote address.\n\t */\n\tpj_sockaddr\t    rcand_addr;\n\n    } comp[2];\n\n} pjmedia_ice_transport_info;\n\n\n/**\n * Options that can be specified when creating ICE transport.\n */\nenum pjmedia_transport_ice_options\n{\n    /**\n     * Normally when remote doesn't use ICE, the ICE transport will \n     * continuously check the source address of incoming packets to see \n     * if it is different than the configured remote address, and switch \n     * the remote address to the source address of the packet if they \n     * are different after several packets are received.\n     * Specifying this option will disable this feature.\n     */\n    PJMEDIA_ICE_NO_SRC_ADDR_CHECKING = 1\n};\n\n\n/**\n * Create the Interactive Connectivity Establishment (ICE) media transport\n * using the specified configuration. When STUN or TURN (or both) is used,\n * the creation operation will complete asynchronously, when STUN resolution\n * and TURN allocation completes. When the initialization completes, the\n * \\a on_ice_complete() complete will be called with \\a op parameter equal\n * to PJ_ICE_STRANS_OP_INIT.\n *\n * In addition, this transport will also notify the application about the\n * result of ICE negotiation, also in \\a on_ice_complete() callback. In this\n * case the callback will be called with \\a op parameter equal to\n * PJ_ICE_STRANS_OP_NEGOTIATION.\n *\n * Other than this, application should use the \\ref PJMEDIA_TRANSPORT API\n * to manipulate this media transport.\n *\n * @param endpt\t\tThe media endpoint.\n * @param name\t\tOptional name to identify this ICE media transport\n *\t\t\tfor logging purposes.\n * @param comp_cnt\tNumber of components to be created.\n * @param cfg\t\tPointer to configuration settings.\n * @param cb\t\tOptional structure containing ICE specific callbacks.\n * @param p_tp\t\tPointer to receive the media transport instance.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_ice_create(pjmedia_endpt *endpt,\n\t\t\t\t\tconst char *name,\n\t\t\t\t\tunsigned comp_cnt,\n\t\t\t\t\tconst pj_ice_strans_cfg *cfg,\n\t\t\t\t\tconst pjmedia_ice_cb *cb,\n\t\t\t\t\tpjmedia_transport **p_tp);\n\n\n/**\n * The same as #pjmedia_ice_create() with additional \\a options param.\n *\n * @param endpt\t\tThe media endpoint.\n * @param name\t\tOptional name to identify this ICE media transport\n *\t\t\tfor logging purposes.\n * @param comp_cnt\tNumber of components to be created.\n * @param cfg\t\tPointer to configuration settings.\n * @param cb\t\tOptional structure containing ICE specific callbacks.\n * @param options\tOptions, see #pjmedia_transport_ice_options.\n * @param p_tp\t\tPointer to receive the media transport instance.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_ice_create2(pjmedia_endpt *endpt,\n\t\t\t\t\t const char *name,\n\t\t\t\t\t unsigned comp_cnt,\n\t\t\t\t\t const pj_ice_strans_cfg *cfg,\n\t\t\t\t\t const pjmedia_ice_cb *cb,\n\t\t\t\t\t unsigned options,\n\t\t\t\t\t pjmedia_transport **p_tp);\n\n/**\n * The same as #pjmedia_ice_create2() with additional \\a user_data param.\n *\n * @param endpt\t\tThe media endpoint.\n * @param name\t\tOptional name to identify this ICE media transport\n *\t\t\tfor logging purposes.\n * @param comp_cnt\tNumber of components to be created.\n * @param cfg\t\tPointer to configuration settings.\n * @param cb\t\tOptional structure containing ICE specific callbacks.\n * @param options\tOptions, see #pjmedia_transport_ice_options.\n * @param user_data\tUser data to be attached to the transport.\n * @param p_tp\t\tPointer to receive the media transport instance.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_ice_create3(pjmedia_endpt *endpt,\n\t\t\t\t\t const char *name,\n\t\t\t\t\t unsigned comp_cnt,\n\t\t\t\t\t const pj_ice_strans_cfg *cfg,\n\t\t\t\t\t const pjmedia_ice_cb *cb,\n\t\t\t\t\t unsigned options,\n\t\t\t\t\t void *user_data,\n\t\t\t\t\t pjmedia_transport **p_tp);\n\n/**\n * Return the ICE stream transport associated with this PJMEDIA transport\n *\n * @param tp\t\tMedia transport instance.\n *\n * @return\t\tPointer to the pj_ice_strans instance associated with this\n *                      media transport.\n */\nPJ_DECL(pj_ice_strans*) pjmedia_ice_get_strans(pjmedia_transport *tp);\n\n/**\n * Get the group lock for the ICE media transport.\n *\n * @param tp\t        The ICE media transport.\n *\n * @return\t\tThe group lock.\n */\nPJ_DECL(pj_grp_lock_t *) pjmedia_ice_get_grp_lock(pjmedia_transport *tp);\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_TRANSPORT_ICE_H__ */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/transport_loop.h",
    "content": "/* $Id: transport_loop.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_TRANSPORT_LOOP_H__\n#define __PJMEDIA_TRANSPORT_LOOP_H__\n\n\n/**\n * @file transport_loop.h\n * @brief Loopback transport\n */\n\n#include <pjmedia/stream.h>\n\n\n/**\n * @defgroup PJMEDIA_TRANSPORT_LOOP Loopback Media Transport\n * @ingroup PJMEDIA_TRANSPORT\n * @brief Loopback transport for testing.\n * @{\n *\n * This is the loopback media transport, where packets sent to this transport\n * will be sent back to the streams attached to this transport. Unlike the\n * other PJMEDIA transports, the loop transport may be attached to multiple\n * streams (in other words, application should specify the same loop transport\n * instance when calling #pjmedia_stream_create()). Any RTP or RTCP packets\n * sent by one stream to this transport by default will be sent back to all \n * streams that are attached to this transport, including to the stream that\n * sends the packet. Application may individually select which stream to\n * receive packets by calling #pjmedia_transport_loop_disable_rx().\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Create the loopback transport.\n *\n * @param endpt\t    The media endpoint instance.\n * @param p_tp\t    Pointer to receive the transport instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_transport_loop_create(pjmedia_endpt *endpt,\n\t\t\t\t\t\t   pjmedia_transport **p_tp);\n\n\n/**\n * Set this stream as the receiver of incoming packets.\n */\nPJ_DECL(pj_status_t) pjmedia_transport_loop_disable_rx(pjmedia_transport *tp,\n\t\t\t\t\t\t       void *user,\n\t\t\t\t\t\t       pj_bool_t disabled);\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_TRANSPORT_LOOP_H__ */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/transport_srtp.h",
    "content": "/* $Id: transport_srtp.h 3999 2012-03-30 07:10:13Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA \n */\n#ifndef __PJMEDIA_TRANSPORT_SRTP_H__\n#define __PJMEDIA_TRANSPORT_SRTP_H__\n\n/**\n * @file transport_srtp.h\n * @brief Secure RTP (SRTP) transport.\n */\n\n#include <pjmedia/transport.h>\n\n\n/**\n * @defgroup PJMEDIA_TRANSPORT_SRTP Secure RTP (SRTP) Media Transport\n * @ingroup PJMEDIA_TRANSPORT\n * @brief Media transport adapter to add SRTP feature to existing transports\n * @{\n *\n * This module implements SRTP as described by RFC 3711, using RFC 4568 as\n * key exchange method. It implements \\ref PJMEDIA_TRANSPORT to integrate\n * with the rest of PJMEDIA framework.\n *\n * As we know, media transport is separated from the stream object (which \n * does the encoding/decoding of PCM frames, (de)packetization of RTP/RTCP \n * packets, and de-jitter buffering). The connection between stream and media\n * transport is established when the stream is created (we need to specify \n * media transport during stream creation), and the interconnection can be \n * depicted from the diagram below:\n *\n   \\image html media-transport.PNG\n\n * I think the diagram above is self-explanatory.\n *\n * SRTP functionality is implemented as some kind of \"adapter\", which is \n * plugged between the stream and the actual media transport that does \n * sending/receiving RTP/RTCP packets. When SRTP is used, the interconnection\n * between stream and transport is like the diagram below:\n *\n    \\image html media-srtp-transport.PNG\n\n * So to stream, the SRTP transport behaves as if it is a media transport \n * (because it is a media transport), and to the media transport it behaves\n * as if it is a stream. The SRTP object then forwards RTP packets back and\n * forth between stream and the actual transport, encrypting/decrypting \n * the RTP/RTCP packets as necessary.\n * \n * The neat thing about this design is the SRTP \"adapter\" then can be used \n * to encrypt any kind of media transports. We currently have UDP and ICE \n * media transports that can benefit SRTP, and we could add SRTP to any \n * media transports that will be added in the future. \n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Crypto option.\n */\ntypedef enum pjmedia_srtp_crypto_option\n{\n    /** When this flag is specified, encryption will be disabled. */\n    PJMEDIA_SRTP_NO_ENCRYPTION  = 1,\n\n    /** When this flag is specified, authentication will be disabled. */\n    PJMEDIA_SRTP_NO_AUTHENTICATION  = 2\n\n} pjmedia_srtp_crypto_option;\n\n\n/**\n * This structure describes an individual crypto setting.\n */\ntypedef struct pjmedia_srtp_crypto\n{\n    /** Optional key. If empty, a random key will be autogenerated. */\n    pj_str_t\tkey;\n\n    /** Crypto name.   */\n    pj_str_t\tname;\n\n    /** Flags, bitmask from #pjmedia_srtp_crypto_option */\n    unsigned\tflags;\n\n} pjmedia_srtp_crypto;\n\n\n/**\n * This enumeration specifies the behavior of the SRTP transport regarding\n * media security offer and answer.\n */\ntypedef enum pjmedia_srtp_use\n{\n    /**\n     * When this flag is specified, SRTP will be disabled, and the transport\n     * will reject RTP/SAVP offer.\n     */\n    PJMEDIA_SRTP_DISABLED,\n\n    /**\n     * When this flag is specified, SRTP will be advertised as optional and\n     * incoming SRTP offer will be accepted.\n     */\n    PJMEDIA_SRTP_OPTIONAL,\n\n    /**\n     * When this flag is specified, the transport will require that RTP/SAVP\n     * media shall be used.\n     */\n    PJMEDIA_SRTP_MANDATORY\n\n} pjmedia_srtp_use;\n\n\n/**\n * Settings to be given when creating SRTP transport. Application should call\n * #pjmedia_srtp_setting_default() to initialize this structure with its \n * default values.\n */\ntypedef struct pjmedia_srtp_setting\n{\n    /**\n     * Specify the usage policy. Default is PJMEDIA_SRTP_OPTIONAL.\n     */\n    pjmedia_srtp_use\t\tuse;\n\n    /**\n     * Specify whether the SRTP transport should close the member transport \n     * when it is destroyed. Default: PJ_TRUE.\n     */\n    pj_bool_t\t\t\tclose_member_tp;\n\n    /**\n     * Specify the number of crypto suite settings.\n     */\n    unsigned\t\t\tcrypto_count;\n\n    /**\n     * Specify individual crypto suite setting.\n     */\n    pjmedia_srtp_crypto\t\tcrypto[8];\n\n} pjmedia_srtp_setting;\n\n\n/**\n * This structure specifies SRTP transport specific info. This will fit\n * into \\a buffer field of pjmedia_transport_specific_info.\n */\ntypedef struct pjmedia_srtp_info\n{\n    /**\n     * Specify whether the SRTP transport is active for SRTP session.\n     */\n    pj_bool_t\t\t\tactive;\n\n    /**\n     * Specify the policy used by the SRTP session for receive direction.\n     */\n    pjmedia_srtp_crypto\t\trx_policy;\n\n    /**\n     * Specify the policy used by the SRTP session for transmit direction.\n     */\n    pjmedia_srtp_crypto\t\ttx_policy;\n\n    /**\n     * Specify the usage policy.\n     */\n    pjmedia_srtp_use\t\tuse;\n\n    /**\n     * Specify the peer's usage policy.\n     */\n    pjmedia_srtp_use\t\tpeer_use;\n\n} pjmedia_srtp_info;\n\n\n/**\n * Initialize SRTP library. This function should be called before\n * any SRTP functions, however calling #pjmedia_transport_srtp_create() \n * will also invoke this function. This function will also register SRTP\n * library deinitialization to #pj_atexit(), so the deinitialization\n * of SRTP library will be performed automatically by PJLIB destructor.\n *\n * @param endpt\t    The media endpoint instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt);\n\n\n/**\n * Initialize SRTP setting with its default values.\n *\n * @param opt\tSRTP setting to be initialized.\n */\nPJ_DECL(void) pjmedia_srtp_setting_default(pjmedia_srtp_setting *opt);\n\n\n/**\n * Create an SRTP media transport.\n *\n * @param endpt\t    The media endpoint instance.\n * @param tp\t    The actual media transport to send and receive \n *\t\t    RTP/RTCP packets. This media transport will be\n *\t\t    kept as member transport of this SRTP instance.\n * @param opt\t    Optional settings. If NULL is given, default\n *\t\t    settings will be used.\n * @param p_tp\t    Pointer to receive the transport SRTP instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_transport_srtp_create(\n\t\t\t\t       pjmedia_endpt *endpt,\n\t\t\t\t       pjmedia_transport *tp,\n\t\t\t\t       const pjmedia_srtp_setting *opt,\n\t\t\t\t       pjmedia_transport **p_tp);\n\n\n/**\n * Manually start SRTP session with the given parameters. Application only\n * needs to call this function when the SRTP transport is used without SDP\n * offer/answer. When SDP offer/answer framework is used, the SRTP transport\n * will be started/stopped by #pjmedia_transport_media_start() and \n * #pjmedia_transport_media_stop() respectively.\n *\n * Please note that even if an RTP stream is only one direction, application\n * will still need to provide both crypto suites, because it is needed by \n * RTCP.\n\n * If application specifies the crypto keys, the keys for transmit and receive\n * direction MUST be different.\n *\n * @param srtp\t    The SRTP transport.\n * @param tx\t    Crypto suite setting for transmit direction.\n * @param rx\t    Crypto suite setting for receive direction.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_transport_srtp_start(\n\t\t\t\t\t    pjmedia_transport *srtp,\n\t\t\t\t\t    const pjmedia_srtp_crypto *tx,\n\t\t\t\t\t    const pjmedia_srtp_crypto *rx);\n\n/**\n * Stop SRTP session.\n *\n * @param srtp\t    The SRTP media transport.\n *\n * @return\t    PJ_SUCCESS on success.\n *\n * @see #pjmedia_transport_srtp_start() \n */\nPJ_DECL(pj_status_t) pjmedia_transport_srtp_stop(pjmedia_transport *srtp);\n\n\n/**\n * This is a utility function to decrypt SRTP packet using SRTP transport.\n * This function is not part of SRTP transport's API, but it can be used\n * to decrypt SRTP packets from non-network (for example, from a saved file)\n * without having to use the transport framework. See pcaputil.c in the\n * samples collection on how to use this function.\n *\n * @param tp\t\tThe SRTP transport.\n * @param is_rtp\tSet to non-zero if the packet is SRTP, otherwise set\n *\t\t\tto zero if the packet is SRTCP.\n * @param pkt\t\tOn input, it contains SRTP or SRTCP packet. On\n *\t\t\toutput, it contains the decrypted RTP/RTCP packet.\n * @param pkt_len\tOn input, specify the length of the buffer. On\n *\t\t\toutput, it will be filled with the actual length\n *\t\t\tof decrypted packet.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_transport_srtp_decrypt_pkt(pjmedia_transport *tp,\n\t\t\t\t\t\t\tpj_bool_t is_rtp,\n\t\t\t\t\t\t\tvoid *pkt,\n\t\t\t\t\t\t\tint *pkt_len);\n\n\n/**\n * Query member transport of SRTP.\n *\n * @param srtp\t\t    The SRTP media transport.\n *\n * @return\t\t    member media transport.\n */\nPJ_DECL(pjmedia_transport*) pjmedia_transport_srtp_get_member(\n\t\t\t\t\t\t    pjmedia_transport *srtp);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif /* __PJMEDIA_TRANSPORT_SRTP_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/transport_udp.h",
    "content": "/* $Id: transport_udp.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_TRANSPORT_UDP_H__\n#define __PJMEDIA_TRANSPORT_UDP_H__\n\n\n/**\n * @file transport_udp.h\n * @brief Stream transport with UDP.\n */\n\n#include <pjmedia/stream.h>\n\n\n/**\n * @defgroup PJMEDIA_TRANSPORT_UDP UDP Media Transport\n * @ingroup PJMEDIA_TRANSPORT\n * @brief Implementation of media transport with UDP sockets.\n * @{\n *\n * The UDP media transport is the standard based media transport\n * as described by RFC 3550/3551. It can be used to facilitate RTP/RTCP\n * unicast or multicast communication.\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Options that can be specified when creating UDP transport.\n */\nenum pjmedia_transport_udp_options\n{\n    /**\n     * Normally the UDP transport will continuously check the source address\n     * of incoming packets to see if it is different than the configured\n     * remote address, and switch the remote address to the source address\n     * of the packet if they are different after several packets are\n     * received.\n     * Specifying this option will disable this feature.\n     */\n    PJMEDIA_UDP_NO_SRC_ADDR_CHECKING = 1\n};\n\n\n/**\n * Create an RTP and RTCP sockets and bind the sockets to the specified\n * port to create media transport.\n *\n * @param endpt\t    The media endpoint instance.\n * @param name\t    Optional name to be assigned to the transport.\n * @param port\t    UDP port number for the RTP socket. The RTCP port number\n *\t\t    will be set to one above RTP port.\n * @param options   Options, bitmask of #pjmedia_transport_udp_options.\n * @param p_tp\t    Pointer to receive the transport instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_transport_udp_create(pjmedia_endpt *endpt,\n\t\t\t\t\t\t  const char *name,\n\t\t\t\t\t\t  int port,\n\t\t\t\t\t\t  unsigned options,\n\t\t\t\t\t\t  pjmedia_transport **p_tp);\n\n\n/**\n * Create an RTP and RTCP sockets and bind the sockets to the specified\n * address and port to create media transport.\n *\n * @param endpt\t    The media endpoint instance.\n * @param name\t    Optional name to be assigned to the transport.\n * @param addr\t    Optional local address to bind the sockets to. If this\n *\t\t    argument is NULL or empty, the sockets will be bound\n *\t\t    to all interface.\n * @param port\t    UDP port number for the RTP socket. The RTCP port number\n *\t\t    will be set to one above RTP port.\n * @param options   Options, bitmask of #pjmedia_transport_udp_options.\n * @param p_tp\t    Pointer to receive the transport instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_transport_udp_create2(pjmedia_endpt *endpt,\n\t\t\t\t\t\t   const char *name,\n\t\t\t\t\t\t   const pj_str_t *addr,\n\t\t\t\t\t\t   int port,\n\t\t\t\t\t\t   unsigned options,\n\t\t\t\t\t\t   pjmedia_transport **p_tp);\n\n/**\n * Another variant of #pjmedia_transport_udp_create() which allows\n * the creation of IPv6 transport.\n *\n * @param endpt\t    The media endpoint instance.\n * @param af\t    Address family, which can be pj_AF_INET() for IPv4 or\n *\t\t    pj_AF_INET6() for IPv6.\n * @param name\t    Optional name to be assigned to the transport.\n * @param addr\t    Optional local address to bind the sockets to. If this\n *\t\t    argument is NULL or empty, the sockets will be bound\n *\t\t    to all interface.\n * @param port\t    UDP port number for the RTP socket. The RTCP port number\n *\t\t    will be set to one above RTP port.\n * @param options   Options, bitmask of #pjmedia_transport_udp_options.\n * @param p_tp\t    Pointer to receive the transport instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_transport_udp_create3(pjmedia_endpt *endpt,\n\t\t\t\t\t\t   int af,\n\t\t\t\t\t\t   const char *name,\n\t\t\t\t\t\t   const pj_str_t *addr,\n\t\t\t\t\t\t   int port,\n\t\t\t\t\t\t   unsigned options,\n\t\t\t\t\t\t   pjmedia_transport **p_tp);\n\n\n/**\n * Create UDP stream transport from existing sockets. Use this function when\n * the sockets have previously been created.\n *\n * @param endpt\t    The media endpoint instance.\n * @param name\t    Optional name to be assigned to the transport.\n * @param si\t    Media socket info containing the RTP and RTCP sockets.\n * @param options   Options, bitmask of #pjmedia_transport_udp_options.\n * @param p_tp\t    Pointer to receive the transport instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_transport_udp_attach(pjmedia_endpt *endpt,\n\t\t\t\t\t\t  const char *name,\n\t\t\t\t\t\t  const pjmedia_sock_info *si,\n\t\t\t\t\t\t  unsigned options,\n\t\t\t\t\t\t  pjmedia_transport **p_tp);\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_TRANSPORT_UDP_H__ */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/transport_zrtp.h",
    "content": "/* $Id$ */\n/*\n  Copyright (C) 2010 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef __PJMEDIA_TRANSPORT_ZRTP_H__\n#define __PJMEDIA_TRANSPORT_ZRTP_H__\n\n/**\n * @file transport_zrtp.h\n * @brief ZRTP Media Transport Adapter\n */\n\n/* transport.h includes types.h -> config.h -> config_auto.h */\n#include <pjmedia/transport.h>\n\n#include \"../../third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpCWrapper.h\"\n\n/**\n * @defgroup PJMEDIA_TRANSPORT_ZRTP ZRTP Transport Adapter\n * @brief This the ZRTP transport adapter.\n * @{\n *\n * PJMEDIA extension to support GNU ZRTP.\n *\n * ZRTP was developed by Phil Zimmermann and provides functions to\n * negotiate keys and other necessary data (crypto data) to set-up\n * the Secure RTP (SRTP) crypto context. Refer to Phil's ZRTP\n * specification at his <a href=\"http://zfoneproject.com/\">Zfone\n * project</a> site to get more detailed information about the\n * capabilities of ZRTP.\n *\n * <b>Short overview of the ZRTP implementation</b>\n *\n * ZRTP is a specific protocol to negotiate encryption algorithms\n * and the required key material. ZRTP uses a RTP session to\n * exchange its protocol messages. Thus ZRTP is independent of any\n * signaling protocol like SIP, XMPP and alike.\n *\n * A complete GNU ZRTP implementation consists of two parts, the\n * GNU ZRTP core and some specific code that binds the GNU ZRTP core to\n * the underlying RTP/SRTP stack and the operating system:\n * <ul>\n * <li>\n *      The GNU ZRTP core is independent of a specific RTP/SRTP\n *      stack and the operationg system and consists of the ZRTP\n *      protocol state engine, the ZRTP protocol messages, and the\n *      GNU ZRTP engine. The GNU ZRTP engine provides methods to\n *      setup ZRTP message and to analyze received ZRTP messages,\n *      to compute the crypto data required for SRTP, and to\n *      maintain the required hashes and HMAC.\n * </li>\n * <li>\n *      The second part of an implementation is specific\n *      <em>glue</em> code the binds the GNU ZRTP core to the\n *      actual RTP/SRTP implementation and other operating system\n *      specific services such as timers, mutexes.\n * </li>\n * </ul>\n *\n * The GNU ZRTP core uses callback methods (refer to\n * zrtp_Callback) to access RTP/SRTP or operating specific methods,\n * for example to send data via the RTP stack, to access\n * timers, provide mutex handling, and to report events to the\n * application.\n *\n * <b>The PJMEDIA ZRTP transport</b>\n *\n * ZRTP transport implements code that is specific to the pjmedia\n * implementation. ZRTP transport also implements the specific code to\n * provide the mutex and timeout handling to the GNU ZRTP\n * core. Both, the mutex and the timeout handling, use the pjlib\n * library to stay independent of the operating\n * seystem.\n *\n * To perform its tasks ZRTP transport\n * <ul>\n * <li> implements the pjmedia transport functions and callbacks.\n * </li>\n * <li> implements the zrtp_Callbacks methods to provide\n *      access and other specific services (timer, mutex) to GNU\n *      ZRTP\n * </li>\n * <li> provides ZRTP specific methods that applications may use\n *      to control and setup GNU ZRTP\n * </li>\n * <li> can register and use an application specific callback\n *      class (refer to zrtp_UserCallbacks)\n * </li>\n * </ul>\n *\n * After instantiating a GNU ZRTP session (see below for a short\n * example) applications may use the methods of\n * ZRTP transport and the ZRTP engine to control and setup GNU ZRTP,\n * for example enable or disable ZRTP processing or getting ZRTP status\n * information.\n *\n * GNU ZRTP defines zrtp_UserCallback methods structure that an application\n * may use and register with ZRTP transport. GNU ZRTP and ZRTP transport\n * use the zrtp_UserCallback methods to report ZRTP events to the\n * application. The application may display this information to\n * the user or act otherwise.\n *\n * The following figure depicts the relationships between\n * ZRTP transport, pjmedia RTP implementation, the GNU ZRTP core,\n * SRTP and an application that provides zrtp_UserCallback methods.\n *\n @verbatim\n                            +-----------+\n                            |           |\n                            | SRTP-ZRTP |\n                            |           |\n                            +-----------+\n                            |C Wrapper  |\n                            +-----+-----+\n                                  |\n                                  | uses\n                                  |\n  +-----------------+      +-------+--------+      +-+-----------------+\n  |  App (pjsua)    |      |                |      |C|                 |\n  |  creates a      | uses | transport_zrtp | uses | |    GNU ZRTP     |\n  | ZRTP transport  +------+   implements   +------+W|      core       |\n  | and implements  |      |  zrtp_Callback |      |r| implementation  |\n  |zrtp_UserCallback|      |                |      |a|  (ZRtp et al)   |\n  +-----------------+      +----------------+      |p|                 |\n                                                   +-+-----------------+\n\n@endverbatim\n *\n * The following short code snippet shows how to use ZRTP transport\n *\n * @code\n *\n * #include <pjmedia/transport_zrtp.h>\n * ...\n * // Create media transport\n * status = pjmedia_transport_udp_create(med_endpt, NULL, local_port,\n *                                       0, &transport);\n * if (status != PJ_SUCCESS)\n *     return status;\n *\n * status = pjmedia_transport_zrtp_create(med_endpt, NULL, transport,\n *                                        &zrtp_tp);\n * app_perror(THIS_FILE, \"Error creating zrtp\", status);\n * transport = zrtp_tp;\n * if (dir == PJMEDIA_DIR_ENCODING)\n *      pjmedia_transport_zrtp_initialize(transport, \"testenc.zid\", 1, NULL);\n * else\n *      pjmedia_transport_zrtp_initialize(transport, \"testdec.zid\", 1, NULL);\n * ...\n * @endcode\n *\n */\n\n#define PJMEDIA_TRANSPORT_TYPE_ZRTP PJMEDIA_TRANSPORT_TYPE_USER+2\n\nPJ_BEGIN_DECL\n\n/**\n * ZRTP option.\n */\ntypedef enum pjmedia_zrtp_use\n{\n    /** When this flag is specified, ZRTP will be disabled. */\n    PJMEDIA_NO_ZRTP  = 1,\n\n    /** When this flag is specified, PJSUA-LIB creates a ZRTP transport\n     * call calls back the applicaion for further process if callback is\n     * set.\n     */\n    PJMEDIA_CREATE_ZRTP  = 2\n\n} pjmedia_zrtp_use;\n\n/**\n * This structure specifies ZRTP transport specific info. This will fit\n * into \\a buffer field of pjmedia_transport_specific_info.\n */\ntypedef struct pjmedia_zrtp_info\n{\n    /**\n     * Specify whether the ZRTP transport is active for this session.\n     */\n    pj_bool_t           active;\n\n    /**\n     * Specify the cipher being used.\n     */\n    char cipher[128];\n\n} pjmedia_zrtp_info;\n\n/**\n * Application callback methods.\n *\n * The RTP stack specific part of GNU ZRTP uses these callback methods\n * to report ZRTP events to the application. Thus the application that\n * instantiates the RTP stack shall implement these methods and show these\n * inforemation to the user.\n *\n * <b>CAVEAT</b><br/>\n * All user callback methods run in the context of the RTP thread. Thus\n * it is of paramount importance to keep the execution time of the methods\n * as short as possible.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\ntypedef struct pjmedia_zrtp_cb\n{\n    /**\n     * Inform user interface that security is active now.\n     *\n     * ZRTP calls this method if the sender and the receiver are\n     * in secure mode now.\n     *\n     * @param cipher\n     *    Name and mode of cipher used to encrypt the SRTP stream\n     */\n    void (*secure_on)(pjmedia_transport *tp, char* cipher);\n\n    /**\n     * Inform user interface that security is not active any more.\n     *\n     * ZRTP calls this method if either the sender or the receiver\n     * left secure mode.\n     *\n     */\n    void (*secure_off)(pjmedia_transport *tp);\n\n    /**\n     * Show the Short Authentication String (SAS) on user interface.\n     *\n     * ZRTP calls this method to display the SAS and inform about the SAS\n     * verification status. The user interface shall enable a SAS verfication\n     * button (or similar UI element). The user shall click on this UI\n     * element after he/she confirmed the SAS code with the partner.\n     *\n     * @param sas\n     *     The string containing the SAS.\n     * @param verified\n     *    If <code>verified</code> is true then SAS was verified by both\n     *    parties during a previous call, otherwise it is set to false.\n     */\n    void (*show_sas)(pjmedia_transport *tp, char* sas, int32_t verified);\n\n    /**\n     * Inform the user that ZRTP received \"go clear\" message from its peer.\n     *\n     * On receipt of a go clear message the user is requested to confirm\n     * a switch to unsecure (clear) modus. Until the user confirms ZRTP\n     * (and the underlying RTP) does not send any data.\n     * \n     */\n    void (*confirm_go_clear)(pjmedia_transport *tp);\n\n    /**\n     * Show some information to user.\n     *\n     * ZRTP calls this method to display some information to the user.\n     * Along with the message ZRTP provides a severity indicator that\n     * defines: Info, Warning, Error, and Alert. Refer to the <code>\n     * MessageSeverity</code> enum in <code>ZrtpCodes.h</code>. The\n     * UI may use this indicator to highlight messages or alike.\n     *\n     * @param sev\n     *     Severity of the message.\n     * @param subCode\n     *     The subcode identifying the reason.\n     */\n    void (*show_message)(pjmedia_transport *tp, int32_t sev, int32_t subCode);\n\n    /**\n     * ZRTP transport calls this if the negotiation failed.\n     *\n     * ZRTPQueue calls this method in case ZRTP negotiation failed. The\n     * parameters show the severity as well as some explanatory text.\n     * Refer to the <code>MessageSeverity</code> enum above.\n     *\n     * @param severity\n     *     This defines the message's severity\n     * @param subCode\n     *     The subcode identifying the reason.\n     */\n    void (*negotiation_failed)(pjmedia_transport *tp, int32_t severity, int32_t subCode);\n\n    /**\n     * ZRTP transport calls this method if the other side does not support ZRTP.\n     *\n     * If the other side does not answer the ZRTP <em>Hello</em> packets then\n     * ZRTP calls this method.\n     *\n     */\n    void (*not_supported_by_other)(pjmedia_transport *tp);\n\n    /**\n     * ZRTP transport calls this method to inform about a PBX enrollment request.\n     *\n     * Please refer to chapter 8.3 ff to get more details about PBX enrollment\n     * and SAS relay.\n     *\n     * @param info\n     *    Give some information to the user about the PBX requesting an\n     *    enrollment.\n     */\n    void (*ask_enrollment)(pjmedia_transport *tp, int32_t info);\n\n    /**\n     * ZRTP transport calls this method to inform about PBX enrollment result.\n     *\n     * Informs the use about the acceptance or denial of an PBX enrollment\n     * request\n     *\n     * @param info\n     *    Give some information to the user about the result of an\n     *    enrollment.\n     */\n    void (*inform_enrollment)(pjmedia_transport *tp, int32_t info);\n\n    /**\n     * ZRTP transport calls this method to request a SAS signature.\n     *\n     * After ZRTP core was able to compute the Short Authentication String\n     * (SAS) it calls this method. The client may now use an approriate\n     * method to sign the SAS. The client may use\n     * setSignatureData() of ZrtpQueue to store the signature\n     * data an enable signature transmission to the other peer. Refer\n     * to chapter 8.2 of ZRTP specification.\n     *\n     * @param sas\n     *    The SAS string to sign.\n     * @see ZrtpQueue#setSignatureData\n     *\n     */\n    void (*sign_sas)(pjmedia_transport *tp, uint8_t* sas);\n\n    /**\n     * ZRTP transport calls this method to request a SAS signature check.\n     *\n     * After ZRTP received a SAS signature in one of the Confirm packets it\n     * call this method. The client may use <code>getSignatureLength()</code>\n     * and <code>getSignatureData()</code>of ZrtpQueue to get the signature\n     * data and perform the signature check. Refer to chapter 8.2 of ZRTP\n     * specification.\n     *\n     * If the signature check fails the client may return false to ZRTP. In\n     * this case ZRTP signals an error to the other peer and terminates\n     * the ZRTP handshake.\n     *\n     * @param sas\n     *    The SAS string that was signed by the other peer.\n     * @return\n     *    true if the signature was ok, false otherwise.\n     *\n     */\n    int32_t (*check_sas_signature)(pjmedia_transport *tp, uint8_t* sas);\n} pjmedia_zrtp_cb;\n\n\n/**\n * Create the transport adapter, specifying the underlying transport to be\n * used to send and receive RTP/RTCP packets.\n *\n * @param endpt     The media endpoint.\n * @param timer_heap  The heap where timers will be scheduled.\n * @param transport The underlying media transport to send and receive\n *          RTP/RTCP packets.\n * @param p_tp      Pointer to receive the media transport instance.\n *\n * @param close_slave\n *          Close the slave transport on transport_destroy. PJSUA-LIB\n *          sets this to PJ_FALSE because it takes care of this.\n *\n * @return      PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_transport_zrtp_create( pjmedia_endpt *endpt,\n                                                    pj_timer_heap_t *timer_heap,\n                                                    pjmedia_transport *transport,\n                                                    pjmedia_transport **p_tp,\n                                                    pj_bool_t close_slave);\n\n/*\n * Implement the specific ZRTP transport functions\n */\n\n/**\n * Initialize the ZRTP transport.\n *\n * Before an application can use ZRTP it has to initialize the\n * ZRTP implementation. This method opens a file that contains ZRTP specific\n * information such as the applications ZID (ZRTP id) and its\n * retained shared secrets.\n *\n * Before an application initializes the ZRTP it may use ZRTP functions\n * to set specific configuration data. See the relevant documentation\n * in @c ZrtpCWrapper.h . The application can peform this after\n * it created transport_zrtp.\n *\n * If one application requires several ZRTP sessions all\n * sessions use the same timeout thread and use the same ZID\n * file. Therefore an application does not need to do any\n * synchronisation regading ZID files or timeouts. This is\n * managed by the ZRTP implementation.\n *\n * The current implementation of ZRTP transport does not support\n * different ZID files for one application instance. This\n * restriction may be removed in later versions.\n *\n * The application may specify its own ZID file name. If no\n * ZID file name is specified it defaults to\n * <code>$HOME/.GNUccRTP.zid</code> if the <code>HOME</code>\n * environment variable is set. If it is not set the current\n * directory is used.\n *\n * If the method could set up the timeout thread and open the ZID\n * file then it enables ZRTP processing and returns.\n *\n * @param tp\n *      Pointer to the ZRTP transport data as returned by\n *      @c pjmedia_transport_zrtp_create.\n *\n * @param zidFilename\n *     The name of the ZID file, can be a relative or absolut\n *     filename.\n *\n * @param autoEnable\n *     if set to true the method automatically sets enableZrtp to\n *     true. This enables the ZRTP auto-sense mode.\n *\n * @param zrtp_cb\n *     Pointer the application's ZRTP callbacks structure. Setting\n *     a NULL switches off the user callbacks\n * @return\n *     PJ_SUCCESS on success, ZRTP processing enabled, other codes\n *     leave ZRTP processing disabled.\n *\n */\nPJ_DECL(pj_status_t) pjmedia_transport_zrtp_initialize(pjmedia_transport *tp,\n                                                       const char *zidFilename,\n                                                       pj_bool_t autoEnable,\n                                                       pjmedia_zrtp_cb *zrtp_cb);\n/**\n * Enable or disable ZRTP processing.\n *\n * Call this method to enable or disable ZRTP processing after\n * calling <code>pjmedia_transport_zrtp_initialize</code> with the\n * parameter @c autoEnable set to false. This can be done before\n * using a RTP session or at any time during a RTP session.\n *\n * Existing SRTP sessions or currently active ZRTP processing will\n * not be stopped or disconnected.\n *\n * If the application enables ZRTP then:\n * <ul>\n * <li>ZRTP transport starts to send ZRTP Hello packets after at least\n * one RTP packet was sent and received on the associated RTP\n * session. Thus if an application enables ZRTP and ZRTP transport\n * detects traffic on the RTP session then ZRTP transport automatically\n * starts the ZRTP protocol. This automatic start is convenient\n * for applications that negotiate RTP parameters and set up RTP\n * sessions but the actual RTP traffic starts some time later.\n * </li>\n * <li>ZRTP transport analyses incoming packets to detect ZRTP\n * messages. If ZRTP was started, either via automatic start (see\n * above) or explicitly via @c zrtp_startZrtp, then ZrtpQueue\n * forwards ZRTP packets to the GNU ZRTP core.\n * </ul>\n *\n * @param tp\n *      Pointer to the ZRTP transport data as returned by\n *      @c pjmedia_transport_zrtp_create.\n *\n * @param onOff\n *     @c 1 to enable ZRTP, @c 0 to disable ZRTP\n */\nPJ_DECL(void) pjmedia_transport_zrtp_setEnableZrtp(pjmedia_transport *tp, pj_bool_t onOff);\n\n/**\n * Return the state of ZRTP enable state.\n *\n * @param tp\n *      Pointer to the ZRTP transport data as returned by\n *      @c pjmedia_transport_zrtp_create.\n *\n * @return @c true if ZRTP processing is enabled, @c false\n * otherwise.\n */\nPJ_DECL(pj_bool_t) pjmedia_transport_zrtp_isEnableZrtp(pjmedia_transport *tp);\n\n/**\n * Starts the ZRTP protocol engine.\n *\n * Applications may call this method to immediatly start the ZRTP protocol\n * engine any time after initializing ZRTP and setting optinal parameters,\n * for example client id or multi-stream parameters.\n *\n * If the application does not call this method but sucessfully initialized\n * the ZRTP engine using @c pjmedia_transport_zrtp_initialize then ZRTP may\n * also start, depending on the autoEnable parameter.\n *\n * @param tp\n *      Pointer to the ZRTP transport data as returned by\n *      @c pjmedia_transport_zrtp_create.\n *\n * @see pjmedia_transport_zrtp_initialize\n */\nPJ_DECL(void) pjmedia_transport_zrtp_startZrtp(pjmedia_transport *tp);\n\n/**\n * Stops the ZRTP protocol engine.\n *\n * Applications call this method to stop the ZRTP protocol\n * engine. The ZRTP transport can not start or process any ZRTP\n * negotiations.\n *\n * This call does not deactivate SRTP processing of ZRTP transport, thus\n * the ZRTP transport still encrypts/decrypts data via SRTP.\n *\n * @param tp\n *      Pointer to the ZRTP transport data as returned by\n *      @c pjmedia_transport_zrtp_create.\n *\n */\nPJ_DECL(void) pjmedia_transport_zrtp_stopZrtp(pjmedia_transport *tp);\n\n/**\n * Set the local SSRC in case of receive-only sessions.\n *\n * Receiver-only RTP sessions never send RTP packets, thus ZRTP cannot learn\n * the local (sender) SSRC. ZRTP requires the SSRC to bind the RTP session\n * to the SRTP and its handshake. In this case the application shall generate\n * a SSRC value and set it.\n *\n * Usually an application knows if a specific RTP session is receive-only, for\n * example by inspecting and parsing the SDP data.\n *\n * If the application later decides to switch this RTP session to full-duplex\n * mode (send and receive) it shall use the generated SSRC to intialize the\n * RTP session. Then the outgoing packets are encrypted by SRTP.\n *\n * @param tp\n *      Pointer to the ZRTP transport data as returned by\n *      @c pjmedia_transport_zrtp_create.\n *\n * @param ssrc\n *      The local ssrc value in host order.\n */\nPJ_DECL(void) pjmedia_transport_zrtp_setLocalSSRC(pjmedia_transport *tp, uint32_t ssrc);\n\n/**\n * Check the state of the MitM mode flag.\n *\n * If true then this ZRTP session acts as MitM, usually enabled by a PBX\n * client (user agent)\n *\n * @return state of mitmMode\n */\nPJ_DECL(pj_bool_t) pjmedia_transport_zrtp_isMitmMode(pjmedia_transport *tp);\n\n/**\n * Set the state of the MitM mode flag.\n *\n * If MitM mode is set to true this ZRTP session acts as MitM, usually\n * enabled by a PBX client (user agent).\n *\n * @param mitmMode defines the new state of the mitmMode flag\n */\nPJ_DECL(void) pjmedia_transport_zrtp_setMitmMode(pjmedia_transport *tp, pj_bool_t mitmMode);\n\n/**\n * Set / reset the SAS verification flag.\n *\n */\nPJ_DECL(void) pjmedia_transport_zrtp_setSASVerified(pjmedia_transport *tp, pj_bool_t verified);\n\n/**\n * Get the peer's ZID.\n *\n */\nPJ_DECL(int) pjmedia_transport_zrtp_getPeerZid(pjmedia_transport *tp, unsigned char* data);\n\n/**\n * Get the peer's name.\n *\n */\nPJ_DECL(char*) pjmedia_transport_zrtp_getPeerName(pjmedia_transport *tp);\n\n/**\n * Set the peer's name.\n *\n */\nPJ_DECL(void) pjmedia_transport_zrtp_putPeerName(pjmedia_transport *tp, const char *name);\n\n\nPJ_DECL(char*) pjmedia_transport_zrtp_getMultiStreamParameters(pjmedia_transport *tp, pj_int32_t *length);\n\nPJ_DECL(void) pjmedia_transport_zrtp_setMultiStreamParameters(pjmedia_transport *tp, const char *parameters, pj_int32_t length, pjmedia_transport *master_tp);\n\n/**\n * Get the ZRTP context pointer.\n *\n * Appplications need the ZRTP context pointer if they call ZRTP specific\n * methods. The ZRTP specific include file @c ZrtpCWrapper contains the\n * descriptions of the ZRTP methods.\n *\n * @return Pointer to ZRTP context\n *\n * @see zrtp_setAuxSecret()\n * @see zrtp_setPbxSecret()\n * @see zrtp_inState()\n * @see zrtp_SASVerified()\n * @see zrtp_resetSASVerified()\n * @see zrtp_getHelloHash()\n * @see zrtp_getMultiStrParams()\n * @see zrtp_setMultiStrParams()\n * @see zrtp_isMultiStream()\n * @see zrtp_isMultiStreamAvailable()\n * @see zrtp_acceptEnrollment()\n * @see zrtp_setSignatureData()\n * @see zrtp_getSignatureData()\n * @see zrtp_getSignatureLength()\n * @see zrtp_getZid();\n */\nPJ_DECL(ZrtpContext*) pjmedia_transport_zrtp_getZrtpContext(pjmedia_transport *tp);\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n#endif  /* __PJMEDIA_TRANSPORT_ADAPTER_SAMPLE_H__ */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/types.h",
    "content": "/* $Id: types.h 3774 2011-09-27 05:24:06Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_TYPES_H__\n#define __PJMEDIA_TYPES_H__\n\n/**\n * @file pjmedia/types.h Basic Types\n * @brief Basic PJMEDIA types.\n */\n\n#include <pjmedia/config.h>\n#include <pj/sock.h>\n#include <pj/types.h>\n\n\n/**\n * @defgroup PJMEDIA_PORT Media Ports Framework\n * @brief Extensible framework for media terminations\n */\n\n\n/**\n * @defgroup PJMEDIA_FRAME_OP Audio Manipulation Algorithms\n * @brief Algorithms to manipulate audio frames\n */\n\n/**\n * @defgroup PJMEDIA_TYPES Basic Types\n * @ingroup PJMEDIA_BASE\n * @brief Basic PJMEDIA types and operations.\n * @{\n */\n\n/**\n * Top most media type. See also #pjmedia_type_name().\n */\ntypedef enum pjmedia_type\n{\n    /** Type is not specified. */\n    PJMEDIA_TYPE_NONE,\n\n    /** The media is audio */\n    PJMEDIA_TYPE_AUDIO,\n\n    /** The media is video. */\n    PJMEDIA_TYPE_VIDEO,\n\n    /** The media is application. */\n    PJMEDIA_TYPE_APPLICATION,\n\n    /** The media type is unknown or unsupported. */\n    PJMEDIA_TYPE_UNKNOWN\n\n} pjmedia_type;\n\n\n/**\n * Media transport protocol.\n */\ntypedef enum pjmedia_tp_proto\n{\n    /** No transport type */\n    PJMEDIA_TP_PROTO_NONE = 0,\n\n    /** RTP using A/V profile */\n    PJMEDIA_TP_PROTO_RTP_AVP,\n\n    /** Secure RTP */\n    PJMEDIA_TP_PROTO_RTP_SAVP,\n\n    /** Unknown */\n    PJMEDIA_TP_PROTO_UNKNOWN\n\n} pjmedia_tp_proto;\n\n\n/**\n * Media direction.\n */\ntypedef enum pjmedia_dir\n{\n    /** None */\n    PJMEDIA_DIR_NONE = 0,\n\n    /** Encoding (outgoing to network) stream, also known as capture */\n    PJMEDIA_DIR_ENCODING = 1,\n\n    /** Same as encoding direction. */\n    PJMEDIA_DIR_CAPTURE = PJMEDIA_DIR_ENCODING,\n\n    /** Decoding (incoming from network) stream, also known as playback. */\n    PJMEDIA_DIR_DECODING = 2,\n\n    /** Same as decoding. */\n    PJMEDIA_DIR_PLAYBACK = PJMEDIA_DIR_DECODING,\n\n    /** Same as decoding. */\n    PJMEDIA_DIR_RENDER = PJMEDIA_DIR_DECODING,\n\n    /** Incoming and outgoing stream, same as PJMEDIA_DIR_CAPTURE_PLAYBACK */\n    PJMEDIA_DIR_ENCODING_DECODING = 3,\n\n    /** Same as ENCODING_DECODING */\n    PJMEDIA_DIR_CAPTURE_PLAYBACK = PJMEDIA_DIR_ENCODING_DECODING,\n\n    /** Same as ENCODING_DECODING */\n    PJMEDIA_DIR_CAPTURE_RENDER = PJMEDIA_DIR_ENCODING_DECODING\n\n} pjmedia_dir;\n\n\n/**\n * Opaque declaration of media endpoint.\n */\ntypedef struct pjmedia_endpt pjmedia_endpt;\n\n/*\n * Forward declaration for stream (needed by transport).\n */\ntypedef struct pjmedia_stream pjmedia_stream;\n\n/**\n * Enumeration for picture coordinate base.\n */\ntypedef enum pjmedia_coord_base\n{\n    /**\n     * This specifies that the pixel [0, 0] location is at the left-top\n     * position.\n     */\n    PJMEDIA_COORD_BASE_LEFT_TOP,\n\n    /**\n     * This specifies that the pixel [0, 0] location is at the left-bottom\n     * position.\n     */\n    PJMEDIA_COORD_BASE_LEFT_BOTTOM\n\n} pjmedia_coord_base;\n\n/**\n * This structure is used to represent rational numbers.\n */\ntypedef struct pjmedia_ratio\n{\n    int\t\tnum;    /** < Numerator. */\n    int\t\tdenum;  /** < Denumerator. */\n} pjmedia_ratio;\n\n/**\n * This structure represent a coordinate.\n */\ntypedef struct pjmedia_coord\n{\n    int\t\tx;\t/**< X position of the coordinate */\n    int\t\ty;\t/**< Y position of the coordinate */\n} pjmedia_coord;\n\n/**\n * This structure represents rectangle size.\n */\ntypedef struct pjmedia_rect_size\n{\n    unsigned\tw;\t/**< The width.\t\t*/\n    unsigned \th;\t/**< The height.\t*/\n} pjmedia_rect_size;\n\n/**\n * This structure describes a rectangle.\n */\ntypedef struct pjmedia_rect\n{\n    pjmedia_coord\tcoord;\t/**< The position.\t*/\n    pjmedia_rect_size\tsize;\t/**< The size.\t\t*/\n} pjmedia_rect;\n\n/**\n * Enumeration for video/picture orientation.\n */\ntypedef enum pjmedia_orient\n{\n    /**\n     * Unknown orientation.\n     */\n    PJMEDIA_ORIENT_UNKNOWN,\n\n    /**\n     * Natural orientation, i.e. the original orientation video will be\n     * displayed/captured without rotation.\n     */\n    PJMEDIA_ORIENT_NATURAL,\n\n    /**\n     * Specifies that the video/picture needs to be rotated 90 degrees\n     * from its natural orientation in clockwise direction from the user's\n     * perspective.\n     * Note that for devices with back cameras (which faces away\n     * from the user), the video will actually need to be rotated\n     * 270 degrees clockwise instead.\n     */\n    PJMEDIA_ORIENT_ROTATE_90DEG,\n\n    /**\n     * Specifies that the video/picture needs to be rotated 180 degrees\n     * from its natural orientation.\n     */\n    PJMEDIA_ORIENT_ROTATE_180DEG,\n\n    /**\n     * Specifies that the video/picture needs to be rotated 270 degrees\n     * from its natural orientation in clockwise direction from the user's\n     * perspective.\n     * Note that for devices with back cameras (which faces away\n     * from the user), the video will actually need to be rotated\n     * 90 degrees clockwise instead.\n     */\n    PJMEDIA_ORIENT_ROTATE_270DEG\n\n} pjmedia_orient;\n\n\n/**\n * Macro for packing format from a four character code, similar to FOURCC.\n */\n#define PJMEDIA_FOURCC(C1, C2, C3, C4) ( C4<<24 | C3<<16 | C2<<8 | C1 )\n\n\n/**\n * Utility function to return the string name for a pjmedia_type.\n *\n * @param t\t\tThe media type.\n *\n * @return\t\tString.\n */\nPJ_DECL(const char*) pjmedia_type_name(pjmedia_type t);\n\n/**\n * A utility function to convert fourcc type of value to four letters string.\n *\n * @param sig\t\tThe fourcc value.\n * @param buf\t\tBuffer to store the string, which MUST be at least\n * \t\t\tfive bytes long.\n *\n * @return\t\tThe string.\n */\nPJ_INLINE(const char*) pjmedia_fourcc_name(pj_uint32_t sig, char buf[])\n{\n    buf[3] = (char)((sig >> 24) & 0xFF);\n    buf[2] = (char)((sig >> 16) & 0xFF);\n    buf[1] = (char)((sig >>  8) & 0xFF);\n    buf[0] = (char)((sig >>  0) & 0xFF);\n    buf[4] = '\\0';\n    return buf;\n}\n\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_TYPES_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/vid_codec.h",
    "content": "/* $Id: vid_codec.h 3956 2012-02-21 08:31:26Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_VID_CODEC_H__\n#define __PJMEDIA_VID_CODEC_H__\n\n\n/**\n * @file vid_codec.h\n * @brief Video codec framework.\n */\n\n#include <pjmedia/codec.h>\n#include <pjmedia/event.h>\n#include <pjmedia/format.h>\n#include <pjmedia/types.h>\n#include <pj/list.h>\n#include <pj/pool.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJMEDIA_VID_CODEC Video Codecs\n * @ingroup PJMEDIA_CODEC\n * @{\n */\n\n#define PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT    8\n#define PJMEDIA_VID_CODEC_MAX_FPS_CNT        16\n\n/**\n * This enumeration specifies the packetization property of video encoding\n * process. The value is bitmask, and smaller value will have higher priority\n * to be used.\n */\ntypedef enum pjmedia_vid_packing\n{\n    /**\n     * This specifies that the packetization is unknown, or if nothing\n     * is supported.\n     */\n    PJMEDIA_VID_PACKING_UNKNOWN,\n\n    /**\n     * This specifies that the result of video encoding process will be\n     * segmented into packets, which is suitable for RTP transmission.\n     * The maximum size of the packets is set in \\a enc_mtu field of\n     * pjmedia_vid_codec_param.\n     */\n    PJMEDIA_VID_PACKING_PACKETS = 1,\n\n    /**\n     * This specifies that video encoding function will produce a whole\n     * or full frame from the source frame. This is normally used for\n     * encoding video for offline storage such as to an AVI file. The\n     * maximum size of the packets is set in \\a enc_mtu field of\n     * pjmedia_vid_codec_param.\n     */\n    PJMEDIA_VID_PACKING_WHOLE = 2\n\n} pjmedia_vid_packing;\n\n\n/**\n * Enumeration of video frame info flag for the bit_info field in the\n * pjmedia_frame.\n */\ntypedef enum pjmedia_vid_frm_bit_info\n{\n    /**\n     * The video frame is keyframe.\n     */\n    PJMEDIA_VID_FRM_KEYFRAME\t= 1\n\n} pjmedia_vid_frm_bit_info;\n\n\n/**\n * Encoding option.\n */\ntypedef struct pjmedia_vid_encode_opt\n{\n    /**\n     * Flag to force the encoder to generate keyframe for the specified input\n     * frame. When this flag is set, application can verify the result by\n     * examining PJMEDIA_VID_FRM_KEYFRAME flag in the bit_info field of the\n     * output frame.\n     */\n    pj_bool_t force_keyframe;\n\n} pjmedia_vid_encode_opt;\n\n\n/** \n * Identification used to search for codec factory that supports specific \n * codec specification. \n */\ntypedef struct pjmedia_vid_codec_info\n{\n    pjmedia_format_id   fmt_id;         /**< Encoded format ID              */\n    unsigned            pt;             /**< Payload type\t\t    */\n    pj_str_t\t        encoding_name;  /**< Encoding name                  */\n    pj_str_t\t        encoding_desc;\t/**< Encoding desc\t\t    */\n    unsigned            clock_rate;     /**< Clock rate\t\t\t    */\n    pjmedia_dir         dir;            /**< Direction                      */\n    unsigned            dec_fmt_id_cnt; /**< # of supported encoding source \n                                             format IDs                     */\n    pjmedia_format_id   dec_fmt_id[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT];\n                                        /**< Supported encoding source \n                                             format IDs                     */\n    unsigned\t\tpackings;\t/**< Supported or requested packings,\n\t\t\t\t\t     strategies, bitmask from\n\t\t\t\t\t     pjmedia_vid_packing\t    */\n    unsigned            fps_cnt;        /**< # of supported frame-rates, can be\n\t\t\t\t\t     zero (support any frame-rate)  */\n    pjmedia_ratio       fps[PJMEDIA_VID_CODEC_MAX_FPS_CNT];\n                                        /**< Supported frame-rates\t    */\n\n} pjmedia_vid_codec_info;\n\n\n/** \n * Detailed codec attributes used in configuring a codec and in querying\n * the capability of codec factories. Default attributes of any codecs could\n * be queried using #pjmedia_vid_codec_mgr_get_default_param() and modified\n * using #pjmedia_vid_codec_mgr_set_default_param().\n *\n * Please note that codec parameter also contains SDP specific setting, \n * #dec_fmtp and #enc_fmtp, which may need to be set appropriately based on\n * the effective setting. See each codec documentation for more detail.\n */\ntypedef struct pjmedia_vid_codec_param\n{\n    pjmedia_dir         dir;            /**< Direction                      */\n    pjmedia_vid_packing packing; \t/**< Packetization strategy.\t    */\n\n    pjmedia_format      enc_fmt;        /**< Encoded format\t            */\n    pjmedia_codec_fmtp  enc_fmtp;       /**< Encoder fmtp params\t    */\n    unsigned            enc_mtu;        /**< MTU or max payload size setting*/\n\n    pjmedia_format      dec_fmt;        /**< Decoded format\t            */\n    pjmedia_codec_fmtp  dec_fmtp;       /**< Decoder fmtp params\t    */\n\n    pj_bool_t\t\tignore_fmtp;\t/**< Ignore fmtp params. If set to\n\t\t\t\t\t     PJ_TRUE, the codec will apply\n\t\t\t\t\t     format settings specified in\n\t\t\t\t\t     enc_fmt and dec_fmt only.\t    */\n\n} pjmedia_vid_codec_param;\n\n\n/**\n * Duplicate video codec parameter.\n *\n * @param pool\t    The pool.\n * @param src\t    The video codec parameter to be duplicated.\n *\n * @return\t    Duplicated codec parameter.\n */\nPJ_DECL(pjmedia_vid_codec_param*) pjmedia_vid_codec_param_clone(\n\t\t\t\t\tpj_pool_t *pool, \n\t\t\t\t\tconst pjmedia_vid_codec_param *src);\n\n/**\n * Forward declaration for video codec.\n */\ntypedef struct pjmedia_vid_codec pjmedia_vid_codec;\n\n\n/**\n * This structure describes codec operations. Each codec MUST implement\n * all of these functions.\n */\ntypedef struct pjmedia_vid_codec_op\n{\n    /** \n     * See #pjmedia_vid_codec_init().\n     */\n    pj_status_t\t(*init)(pjmedia_vid_codec *codec, \n\t\t\tpj_pool_t *pool );\n\n    /** \n     * See #pjmedia_vid_codec_open().\n     */\n    pj_status_t\t(*open)(pjmedia_vid_codec *codec, \n\t\t\tpjmedia_vid_codec_param *param );\n\n    /** \n     * See #pjmedia_vid_codec_close().\n     */\n    pj_status_t (*close)(pjmedia_vid_codec *codec);\n\n    /** \n     * See #pjmedia_vid_codec_modify().\n     */\n    pj_status_t\t(*modify)(pjmedia_vid_codec *codec,\n\t\t\t  const pjmedia_vid_codec_param *param);\n\n    /** \n     * See #pjmedia_vid_codec_get_param().\n     */\n    pj_status_t\t(*get_param)(pjmedia_vid_codec *codec,\n\t\t\t     pjmedia_vid_codec_param *param);\n\n    /**\n     * See #pjmedia_vid_codec_encode_begin().\n     */\n    pj_status_t (*encode_begin)(pjmedia_vid_codec *codec,\n\t\t\t\tconst pjmedia_vid_encode_opt *opt,\n\t\t\t\tconst pjmedia_frame *input,\n\t\t\t\tunsigned out_size,\n\t\t\t\tpjmedia_frame *output,\n\t\t\t\tpj_bool_t *has_more);\n\n    /**\n     * See #pjmedia_vid_codec_encode_more()\n     */\n    pj_status_t (*encode_more)(pjmedia_vid_codec *codec,\n\t\t\t       unsigned out_size,\n\t\t\t       pjmedia_frame *output,\n\t\t\t       pj_bool_t *has_more);\n\n\n    /*\n     * See #pjmedia_vid_codec_decode().\n     */\n    pj_status_t (*decode)(pjmedia_vid_codec *codec,\n\t\t\t  pj_size_t count,\n\t\t\t  pjmedia_frame packets[],\n\t\t\t  unsigned out_size,\n\t\t\t  pjmedia_frame *output);\n\n    /**\n     * See #pjmedia_vid_codec_recover()\n     */\n    pj_status_t (*recover)(pjmedia_vid_codec *codec,\n\t\t\t   unsigned out_size,\n\t\t\t   pjmedia_frame *output);\n\n} pjmedia_vid_codec_op;\n\n\n\n/*\n * Forward declaration for pjmedia_vid_codec_factory.\n */\ntypedef struct pjmedia_vid_codec_factory pjmedia_vid_codec_factory;\n\n\n/**\n * This structure describes a video codec instance. Codec implementers\n * should use #pjmedia_vid_codec_init() to initialize this structure with\n * default values.\n */\nstruct pjmedia_vid_codec\n{\n    /** Entries to put this codec instance in codec factory's list. */\n    PJ_DECL_LIST_MEMBER(struct pjmedia_vid_codec);\n\n    /** Codec's private data. */\n    void\t\t\t*codec_data;\n\n    /** Codec factory where this codec was allocated. */\n    pjmedia_vid_codec_factory   *factory;\n\n    /** Operations to codec. */\n    pjmedia_vid_codec_op\t*op;\n};\n\n\n\n/**\n * This structure describes operations that must be supported by codec \n * factories.\n */\ntypedef struct pjmedia_vid_codec_factory_op\n{\n    /** \n     * Check whether the factory can create codec with the specified \n     * codec info.\n     *\n     * @param factory\tThe codec factory.\n     * @param info\tThe codec info.\n     *\n     * @return\t\tPJ_SUCCESS if this factory is able to create an\n     *\t\t\tinstance of codec with the specified info.\n     */\n    pj_status_t\t(*test_alloc)(pjmedia_vid_codec_factory *factory, \n\t\t\t      const pjmedia_vid_codec_info *info );\n\n    /** \n     * Create default attributes for the specified codec ID. This function\n     * can be called by application to get the capability of the codec.\n     *\n     * @param factory\tThe codec factory.\n     * @param info\tThe codec info.\n     * @param attr\tThe attribute to be initialized.\n     *\n     * @return\t\tPJ_SUCCESS if success.\n     */\n    pj_status_t (*default_attr)(pjmedia_vid_codec_factory *factory, \n    \t\t\t\tconst pjmedia_vid_codec_info *info,\n    \t\t\t\tpjmedia_vid_codec_param *attr );\n\n    /** \n     * Enumerate supported codecs that can be created using this factory.\n     * \n     *  @param factory\tThe codec factory.\n     *  @param count\tOn input, specifies the number of elements in\n     *\t\t\tthe array. On output, the value will be set to\n     *\t\t\tthe number of elements that have been initialized\n     *\t\t\tby this function.\n     *  @param info\tThe codec info array, which contents will be \n     *\t\t\tinitialized upon return.\n     *\n     *  @return\t\tPJ_SUCCESS on success.\n     */\n    pj_status_t (*enum_info)(pjmedia_vid_codec_factory *factory, \n\t\t\t     unsigned *count, \n\t\t\t     pjmedia_vid_codec_info codecs[]);\n\n    /** \n     * Create one instance of the codec with the specified codec info.\n     *\n     * @param factory\tThe codec factory.\n     * @param info\tThe codec info.\n     * @param p_codec\tPointer to receive the codec instance.\n     *\n     * @return\t\tPJ_SUCCESS on success.\n     */\n    pj_status_t (*alloc_codec)(pjmedia_vid_codec_factory *factory, \n\t\t\t       const pjmedia_vid_codec_info *info,\n\t\t\t       pjmedia_vid_codec **p_codec);\n\n    /** \n     * This function is called by codec manager to return a particular \n     * instance of codec back to the codec factory.\n     *\n     * @param factory\tThe codec factory.\n     * @param codec\tThe codec instance to be returned.\n     *\n     * @return\t\tPJ_SUCCESS on success.\n     */\n    pj_status_t (*dealloc_codec)(pjmedia_vid_codec_factory *factory, \n\t\t\t\t pjmedia_vid_codec *codec );\n\n} pjmedia_vid_codec_factory_op;\n\n\n\n/**\n * Codec factory describes a module that is able to create codec with specific\n * capabilities. These capabilities can be queried by codec manager to create\n * instances of codec.\n */\nstruct pjmedia_vid_codec_factory\n{\n    /** Entries to put this structure in the codec manager list. */\n    PJ_DECL_LIST_MEMBER(struct pjmedia_vid_codec_factory);\n\n    /** The factory's private data. */\n    void\t\t     *factory_data;\n\n    /** Operations to the factory. */\n    pjmedia_vid_codec_factory_op *op;\n\n};\n\n\n/**\n * Opaque declaration for codec manager.\n */\ntypedef struct pjmedia_vid_codec_mgr pjmedia_vid_codec_mgr;\n\n/**\n * Declare maximum codecs\n */\n#define PJMEDIA_VID_CODEC_MGR_MAX_CODECS\t    32\n\n\n/**\n * Initialize codec manager. If there is no the default video codec manager,\n * this function will automatically set the default video codec manager to\n * the new codec manager instance. Normally this function is called by pjmedia\n * endpoint's initialization code.\n *\n * @param pool\t    The pool instance.\n * @param mgr\t    The pointer to the new codec manager instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_codec_mgr_create(pj_pool_t *pool,\n                                                  pjmedia_vid_codec_mgr **mgr);\n\n\n/**\n * Destroy codec manager. Normally this function is called by pjmedia\n * endpoint's deinitialization code.\n *\n * @param mgr\t    Codec manager instance.  If NULL, it is the default codec\n *\t\t    manager instance will be destroyed.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr *mgr);\n\n\n/**\n * Get the default codec manager instance.\n *\n * @return\t    The default codec manager instance or NULL if none.\n */\nPJ_DECL(pjmedia_vid_codec_mgr*) pjmedia_vid_codec_mgr_instance(void);\n\n\n/**\n * Set the default codec manager instance.\n *\n * @param mgr\t    The codec manager instance.\n */\nPJ_DECL(void) pjmedia_vid_codec_mgr_set_instance(pjmedia_vid_codec_mgr* mgr);\n\n\n/** \n * Register codec factory to codec manager. This will also register\n * all supported codecs in the factory to the codec manager.\n *\n * @param mgr\t    The codec manager instance. If NULL, the default codec\n *\t\t    manager instance will be used.\n * @param factory   The codec factory to be registered.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_vid_codec_mgr_register_factory( pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t        pjmedia_vid_codec_factory *factory);\n\n/**\n * Unregister codec factory from the codec manager. This will also\n * remove all the codecs registered by the codec factory from the\n * codec manager's list of supported codecs.\n *\n * @param mgr\t    The codec manager instance. If NULL, the default codec\n *\t\t    manager instance will be used.\n * @param factory   The codec factory to be unregistered.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_vid_codec_mgr_unregister_factory( pjmedia_vid_codec_mgr *mgr, \n\t\t\t\t          pjmedia_vid_codec_factory *factory);\n\n/**\n * Enumerate all supported codecs that have been registered to the\n * codec manager by codec factories.\n *\n * @param mgr\t    The codec manager instance. If NULL, the default codec\n *\t\t    manager instance will be used.\n * @param count\t    On input, specifies the number of elements in\n *\t\t    the array. On output, the value will be set to\n *\t\t    the number of elements that have been initialized\n *\t\t    by this function.\n * @param info\t    The codec info array, which contents will be \n *\t\t    initialized upon return.\n * @param prio\t    Optional pointer to receive array of codec priorities.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t)\npjmedia_vid_codec_mgr_enum_codecs(pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t  unsigned *count,\n\t\t\t\t  pjmedia_vid_codec_info info[],\n\t\t\t\t  unsigned *prio);\n\n\n/**\n * Get codec info for the specified payload type. The payload type must be\n * static or locally defined in #pjmedia_video_pt.\n *\n * @param mgr\t    The codec manager instance. If NULL, the default codec\n *\t\t    manager instance will be used.\n * @param pt\t    The payload type/number.\n * @param info\t    Pointer to receive codec info.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_vid_codec_mgr_get_codec_info( pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t      unsigned pt,\n\t\t\t\t      const pjmedia_vid_codec_info **info);\n\n\n/**\n * Get codec info for the specified format ID.\n *\n * @param mgr\t    The codec manager instance. If NULL, the default codec\n *\t\t    manager instance will be used.\n * @param fmt_id    Format ID. See #pjmedia_format_id\n * @param info\t    Pointer to receive codec info.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_vid_codec_mgr_get_codec_info2(pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t      pjmedia_format_id fmt_id,\n\t\t\t\t      const pjmedia_vid_codec_info **info);\n\n\n/**\n * Convert codec info struct into a unique codec identifier.\n * A codec identifier looks something like \"H263/90000\".\n *\n * @param info\t    The codec info\n * @param id\t    Buffer to put the codec info string.\n * @param max_len   The length of the buffer.\n *\n * @return\t    The null terminated codec info string, or NULL if\n *\t\t    the buffer is not long enough.\n */\nPJ_DECL(char*) pjmedia_vid_codec_info_to_id(const pjmedia_vid_codec_info *info,\n                                            char *id, unsigned max_len );\n\n\n/**\n * Find codecs by the unique codec identifier. This function will find\n * all codecs that match the codec identifier prefix. For example, if\n * \"H26\" is specified, then it will find \"H263/90000\", \"H264/90000\",\n * and so on, up to the maximum count specified in the argument.\n *\n * @param mgr\t    The codec manager instance. If NULL, the default codec\n *\t\t    manager instance will be used.\n * @param codec_id  The full codec ID or codec ID prefix. If an empty\n *\t\t    string is given, it will match all codecs.\n * @param count\t    Maximum number of codecs to find. On return, it\n *\t\t    contains the actual number of codecs found.\n * @param p_info    Array of pointer to codec info to be filled. This\n *\t\t    argument may be NULL, which in this case, only\n *\t\t    codec count will be returned.\n * @param prio\t    Optional array of codec priorities.\n *\n * @return\t    PJ_SUCCESS if at least one codec info is found.\n */\nPJ_DECL(pj_status_t) \npjmedia_vid_codec_mgr_find_codecs_by_id(pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t\tconst pj_str_t *codec_id,\n\t\t\t\t\tunsigned *count,\n\t\t\t\t\tconst pjmedia_vid_codec_info *p_info[],\n\t\t\t\t\tunsigned prio[]);\n\n\n/**\n * Set codec priority. The codec priority determines the order of\n * the codec in the SDP created by the endpoint. If more than one codecs\n * are found with the same codec_id prefix, then the function sets the\n * priorities of all those codecs.\n *\n * @param mgr\t    The codec manager instance. If NULL, the default codec\n *\t\t    manager instance will be used.\n * @param codec_id  The full codec ID or codec ID prefix. If an empty\n *\t\t    string is given, it will match all codecs.\n * @param prio\t    Priority to be set. The priority can have any value\n *\t\t    between 1 to 255. When the priority is set to zero,\n *\t\t    the codec will be disabled.\n *\n * @return\t    PJ_SUCCESS if at least one codec info is found.\n */\nPJ_DECL(pj_status_t)\npjmedia_vid_codec_mgr_set_codec_priority(pjmedia_vid_codec_mgr *mgr, \n\t\t\t\t\t const pj_str_t *codec_id,\n\t\t\t\t\t pj_uint8_t prio);\n\n\n/**\n * Get default codec param for the specified codec info.\n *\n * @param mgr\t    The codec manager instance. If NULL, the default codec\n *\t\t    manager instance will be used.\n * @param info\t    The codec info, which default parameter's is being\n *\t\t    queried.\n * @param param\t    On return, will be filled with the default codec\n *\t\t    parameter.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_vid_codec_mgr_get_default_param(pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t\tconst pjmedia_vid_codec_info *info,\n\t\t\t\t\tpjmedia_vid_codec_param *param);\n\n\n/**\n * Set default codec param for the specified codec info.\n *\n * @param mgr\t    The codec manager instance. If NULL, the default codec\n *\t\t    manager instance will be used.\n * @param pool\t    The pool instance.\n * @param info\t    The codec info, which default parameter's is being\n *\t\t    updated.\n * @param param\t    The new default codec parameter. Set to NULL to reset\n *\t\t    codec parameter to library default settings.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_vid_codec_mgr_set_default_param(pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t        const pjmedia_vid_codec_info *info,\n\t\t\t\t        const pjmedia_vid_codec_param *param);\n\n\n/**\n * Request the codec manager to allocate one instance of codec with the\n * specified codec info. The codec will enumerate all codec factories\n * until it finds factory that is able to create the specified codec.\n *\n * @param mgr\t    The codec manager instance. If NULL, the default codec\n *\t\t    manager instance will be used.\n * @param info\t    The information about the codec to be created.\n * @param p_codec   Pointer to receive the codec instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_vid_codec_mgr_alloc_codec( pjmedia_vid_codec_mgr *mgr, \n\t\t\t           const pjmedia_vid_codec_info *info,\n\t\t\t           pjmedia_vid_codec **p_codec);\n\n/**\n * Deallocate the specified codec instance. The codec manager will return\n * the instance of the codec back to its factory.\n *\n * @param mgr\t    The codec manager instance. If NULL, the default codec\n *\t\t    manager instance will be used.\n * @param codec\t    The codec instance.\n *\n * @return\t    PJ_SUCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_codec_mgr_dealloc_codec(\n                                                pjmedia_vid_codec_mgr *mgr, \n\t\t\t\t\t\tpjmedia_vid_codec *codec);\n\n\n\n/** \n * Initialize codec using the specified attribute.\n *\n * @param codec\t    The codec instance.\n * @param pool\t    Pool to use when the codec needs to allocate\n *\t\t    some memory.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_INLINE(pj_status_t) pjmedia_vid_codec_init( pjmedia_vid_codec *codec, \n\t\t\t\t\t       pj_pool_t *pool )\n{\n    return (*codec->op->init)(codec, pool);\n}\n\n\n/** \n * Open the codec and initialize with the specified parameter.\n * Upon successful initialization, the codec may modify the parameter\n * and fills in the unspecified values (such as size or frame rate of\n * the encoder format, as it may need to be negotiated with remote\n * preferences via SDP fmtp).\n *\n * @param codec\t    The codec instance.\n * @param param\t    Codec initialization parameter.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_INLINE(pj_status_t) pjmedia_vid_codec_open(pjmedia_vid_codec *codec,\n                                              pjmedia_vid_codec_param *param)\n{\n    return (*codec->op->open)(codec, param);\n}\n\n\n/** \n * Close and shutdown codec, releasing all resources allocated by\n * this codec, if any.\n *\n * @param codec\t    The codec instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_INLINE(pj_status_t) pjmedia_vid_codec_close( pjmedia_vid_codec *codec )\n{\n    return (*codec->op->close)(codec);\n}\n\n\n/** \n * Modify the codec parameter after the codec is open. \n * Note that not all codec parameters can be modified during run-time. \n * When the parameter cannot be changed, this function will return \n * non-PJ_SUCCESS, and the original parameters will not be changed.\n *\n * @param codec\tThe codec instance.\n * @param param\tThe new codec parameter.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_INLINE(pj_status_t)\npjmedia_vid_codec_modify(pjmedia_vid_codec *codec,\n                         const pjmedia_vid_codec_param *param)\n{\n    return (*codec->op->modify)(codec, param);\n}\n\n\n/** \n * Get the codec parameter after the codec is opened. \n *\n * @param codec\tThe codec instance.\n * @param param\tThe codec parameter.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_INLINE(pj_status_t)\npjmedia_vid_codec_get_param(pjmedia_vid_codec *codec,\n\t\t\t    pjmedia_vid_codec_param *param)\n{\n    return (*codec->op->get_param)(codec, param);\n}\n\n/** \n * Encode the specified input frame. The input MUST contain only one picture\n * with the appropriate format as specified when opening the codec. Depending\n * on the packing or packetization set in the \\a packing param, the process\n * may produce multiple encoded packets or payloads to represent the picture.\n * This is true for example for PJMEDIA_VID_PACKING_PACKETS packing. In this\n * case, the \\a has_more field will be set to PJ_TRUE, and application should\n * call pjmedia_vid_codec_encode_more() to get the remaining results from the\n * codec.\n *\n * @param codec\t\tThe codec instance.\n * @param opt\t\tOptional encoding options.\n * @param input\t\tThe input frame.\n * @param out_size\tThe length of buffer in the output frame. This\n * \t\t\tshould be at least the same as the configured\n * \t\t\tencoding MTU of the codec.\n * @param output\tThe output frame.\n * @param has_more\tPJ_TRUE if more payloads are available; application\n * \t\t\tshould then call pjmedia_vid_codec_encode_more()\n * \t\t\tto retrieve the remaining results.\n *\n * @return\t\tPJ_SUCCESS on success;\n */\nPJ_INLINE(pj_status_t)\npjmedia_vid_codec_encode_begin( pjmedia_vid_codec *codec,\n\t\t\t\tconst pjmedia_vid_encode_opt *opt,\n\t\t\t\tconst pjmedia_frame *input,\n\t\t\t\tunsigned out_size,\n\t\t\t\tpjmedia_frame *output,\n\t\t\t\tpj_bool_t *has_more)\n{\n    return (*codec->op->encode_begin)(codec, opt, input, out_size, output,\n\t\t\t\t      has_more);\n}\n\n/**\n * Retrieve more encoded packets/payloads from the codec. Application\n * should call this function repeatedly until \\a has_more flag is set\n * to PJ_FALSE.\n *\n * @param codec\t\tThe codec instance.\n * @param out_size\tThe length of buffer in the output frame. This\n * \t\t\tshould be at least the same as as the configured\n * \t\t\tencoding MTU of the codec.\n * @param output\tThe output frame.\n * @param has_more\tPJ_TRUE if more payloads are available, which in\n * \t\t\tthis case application should call \\a encode_more()\n * \t\t\tto retrieve them.\n *\n * @return\t\tPJ_SUCCESS on success;\n */\nPJ_INLINE(pj_status_t)\npjmedia_vid_codec_encode_more( pjmedia_vid_codec *codec,\n\t\t\t       unsigned out_size,\n\t\t\t       pjmedia_frame *output,\n\t\t\t       pj_bool_t *has_more)\n{\n    return (*codec->op->encode_more)(codec, out_size, output, has_more);\n}\n\n/** \n * Decode the input packets into one picture. If the packing is set to\n * PJMEDIA_VID_PACKING_PACKETS when opening the codec, the codec is set\n * to decode multiple encoded packets into one picture. These encoded\n * packets are typically retrieved from the jitter buffer. If the packing\n * is set to PJMEDIA_VID_PACKING_WHOLE, then this decode function can only\n * accept one frame as the input.\n *\n * Note that the decoded picture format may different to the configured\n * setting (i.e. the format specified in the #pjmedia_vid_codec_param when\n * opening the codec), in this case the PJMEDIA_EVENT_FMT_CHANGED event will\n * be emitted by the codec to notify the event. The codec parameter will\n * also be updated, and application can query the format by using\n * pjmedia_vid_codec_get_param().\n *\n * @param codec\t\tThe codec instance.\n * @param pkt_count\tNumber of packets in the input.\n * @param packets\tArray of input packets, each containing an encoded\n * \t\t\tframe.\n * @param out_size\tThe length of buffer in the output frame.\n * @param output\tThe output frame.\n *\n * @return\t\tPJ_SUCCESS on success;\n */\nPJ_INLINE(pj_status_t) pjmedia_vid_codec_decode(pjmedia_vid_codec *codec,\n\t\t\t\t\t\tpj_size_t pkt_count,\n\t\t\t\t\t\tpjmedia_frame packets[],\n\t\t\t\t\t\tunsigned out_size,\n\t\t\t\t\t\tpjmedia_frame *output)\n{\n    return (*codec->op->decode)(codec, pkt_count, packets, out_size, output);\n}\n\n/**\n * Recover a missing frame.\n *\n * @param codec\t\tThe codec instance.\n * @param out_size\tThe length of buffer in the output frame.\n * @param output\tThe output frame where generated signal\n *\t\t\twill be placed.\n *\n * @return\t\tPJ_SUCCESS on success;\n */\nPJ_INLINE(pj_status_t) pjmedia_vid_codec_recover(pjmedia_vid_codec *codec,\n                                                 unsigned out_size,\n                                                 pjmedia_frame *output)\n{\n    if (codec->op && codec->op->recover)\n\treturn (*codec->op->recover)(codec, out_size, output);\n    else\n\treturn PJ_ENOTSUP;\n}\n\n\n/**\n * @}\n */\n\n/**\n * @defgroup PJMEDIA_CODEC_VID_CODECS Supported video codecs\n * @ingroup PJMEDIA_VID_CODEC\n */\n\n\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_VID_CODEC_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/vid_codec_util.h",
    "content": "/* $Id: vid_codec_util.h 3715 2011-08-19 09:35:25Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_VID_CODEC_UTIL_H__\n#define __PJMEDIA_VID_CODEC_UTIL_H__\n\n\n/**\n * @file vid_codec_util.h\n * @brief Video codec utilities.\n */\n\n#include <pjmedia/vid_codec.h>\n#include <pjmedia/sdp_neg.h>\n\nPJ_BEGIN_DECL\n\n\n/**\n * Definition of H.263 parameters.\n */\ntypedef struct pjmedia_vid_codec_h263_fmtp\n{\n    unsigned mpi_cnt;\t\t    /**< # of parsed MPI param\t\t    */\n    struct mpi {\n\tpjmedia_rect_size   size;   /**< Picture size/resolution\t    */\n\tunsigned\t    val;    /**< MPI value\t\t\t    */\n    } mpi[32];\t\t\t    /**< Minimum Picture Interval parameter */\n\n} pjmedia_vid_codec_h263_fmtp;\n\n\n/**\n * Parse SDP fmtp of H.263.\n *\n * @param fmtp\t\tThe H.263 SDP fmtp to be parsed.\n * @param h263_fmtp\tThe parsing result.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_codec_h263_parse_fmtp(\n\t\t\t\tconst pjmedia_codec_fmtp *fmtp,\n\t\t\t\tpjmedia_vid_codec_h263_fmtp *h263_fmtp);\n\n\n/**\n * Parse, negotiate, and apply the encoding and decoding SDP fmtp of H.263\n * in the specified codec parameter.\n *\n * @param param\t\tThe codec parameter.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_codec_h263_apply_fmtp(\n\t\t\t\tpjmedia_vid_codec_param *param);\n\n\n/**\n * Definition of H.264 parameters.\n */\ntypedef struct pjmedia_vid_codec_h264_fmtp\n{\n    /* profile-level-id */\n    pj_uint8_t\t    profile_idc;    /**< Profile ID\t\t\t    */\n    pj_uint8_t\t    profile_iop;    /**< Profile constraints bits\t    */\n    pj_uint8_t\t    level;\t    /**< Level\t\t\t\t    */\n\n    /* packetization-mode */\n    pj_uint8_t\t    packetization_mode;\t/**< Packetization mode\t\t    */\n\n    /* max-mbps, max-fs, max-cpb, max-dpb, and max-br */\n    unsigned\t    max_mbps;\t    /**< Max macroblock processing rate\t    */\n    unsigned\t    max_fs;\t    /**< Max frame size (in macroblocks)    */\n    unsigned\t    max_cpb;\t    /**< Max coded picture buffer size\t    */\n    unsigned\t    max_dpb;\t    /**< Max decoded picture buffer size    */\n    unsigned\t    max_br;\t    /**< Max video bit rate\t\t    */\n\n    /* sprop-parameter-sets, in NAL units */\n    pj_size_t\t    sprop_param_sets_len;   /**< Parameter set length\t    */\n    pj_uint8_t\t    sprop_param_sets[256];  /**< Parameter set (SPS & PPS),\n\t\t\t\t\t\t in NAL unit bitstream\t    */\n\n} pjmedia_vid_codec_h264_fmtp;\n\n\n/**\n * Parse SDP fmtp of H.264.\n *\n * @param fmtp\t\tThe H.264 SDP fmtp to be parsed.\n * @param h264_fmtp\tThe parsing result.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_codec_h264_parse_fmtp(\n\t\t\t\tconst pjmedia_codec_fmtp *fmtp,\n\t\t\t\tpjmedia_vid_codec_h264_fmtp *h264_fmtp);\n\n\n/**\n * Match H.264 format in the SDP media offer and answer. This will compare\n * H.264 identifier parameters in SDP fmtp, i.e: \"profile-level-id\" and\n * \"packetization-mode\" fields. For better interoperability, when the option\n * #PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER is set, this function\n * may update the answer so the parameters in the answer match to ones\n * in the offer.\n *\n * @param pool\t\tThe memory pool.\n * @param offer\t\tThe SDP media offer.\n * @param o_fmt_idx\tIndex of the H.264 format in the SDP media offer.\n * @param answer\tThe SDP media answer.\n * @param a_fmt_idx\tIndex of the H.264 format in the SDP media answer.\n * @param option\tThe format matching option, see\n *\t\t\t#pjmedia_sdp_neg_fmt_match_flag.\n *\n * @return\t\tPJ_SUCCESS when the formats in offer and answer match.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_codec_h264_match_sdp(\n\t\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\t\tpjmedia_sdp_media *offer,\n\t\t\t\t\t\tunsigned o_fmt_idx,\n\t\t\t\t\t\tpjmedia_sdp_media *answer,\n\t\t\t\t\t\tunsigned a_fmt_idx,\n\t\t\t\t\t\tunsigned option);\n\n\n/**\n * Parse and apply the encoding and decoding SDP fmtp of H.264 in the\n * specified codec parameter. This will validate size and fps to conform\n * to H.264 level specified in SDP fmtp \"profile-level-id\".\n *\n * @param param\t\tThe codec parameter.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_codec_h264_apply_fmtp(\n\t\t\t\tpjmedia_vid_codec_param *param);\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_VID_CODEC_UTIL_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/vid_port.h",
    "content": "/* $Id: vid_port.h 4168 2012-06-18 05:59:08Z ming $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef __PJMEDIA_VIDPORT_H__\n#define __PJMEDIA_VIDPORT_H__\n\n/**\n * @file pjmedia/videoport.h Video media port\n * @brief Video media port\n */\n\n#include <pjmedia-videodev/videodev.h>\n#include <pjmedia/port.h>\n\n/**\n * @defgroup PJMEDIA_VIDEO_PORT Video media port\n * @ingroup PJMEDIA_PORT_CLOCK\n * @brief Video media port\n * @{\n */\n\nPJ_BEGIN_DECL\n\n/**\n * This structure describes the parameters to create a video port\n */\ntypedef struct pjmedia_vid_port_param\n{\n    /**\n     * Video stream parameter.\n     */\n    pjmedia_vid_dev_param\tvidparam;\n\n    /**\n     * Specify whether the video port should use active or passive interface.\n     * If active interface is selected, the video port will perform as\n     * a media clock, automatically calls pjmedia_port_get_frame() and\n     * pjmedia_port_put_frame() of its slave port (depending on the direction\n     * that is specified when opening the video stream). If passive interface\n     * is selected, application can retrieve the media port of this video\n     * port by calling pjmedia_vid_port_get_passive_port(), and subsequently\n     * calls pjmedia_port_put_frame() or pjmedia_port_get_frame() to that\n     * media port.\n     *\n     * Default: PJ_TRUE\n     */\n    pj_bool_t\t\tactive;\n\n} pjmedia_vid_port_param;\n\n/**\n * Opaque data type for video port.\n */\ntypedef struct pjmedia_vid_port pjmedia_vid_port;\n\n/**\n * Initialize the parameter with the default values. Note that this typically\n * would only fill the structure to zeroes unless they have different default\n * values.\n *\n * @param prm\tThe parameter.\n */\nPJ_DECL(void) pjmedia_vid_port_param_default(pjmedia_vid_port_param *prm);\n\n/**\n * Create a video port with the specified parameter. When video port opens\n * the video stream with different parameter than the requested values in\n * the \\a prm.vidparam argument, it will automatically do the necessary\n * conversion.\n *\n * @param pool\t\tPool to allocate memory from.\n * @param prm\t\tThe video port parameter.\n * @param p_vp\t\tPointer to receive the result.\n *\n * @return\t\tPJ_SUCCESS if video port has been created\n * \t\t\tsuccessfully, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_port_create(pj_pool_t *pool,\n\t\t\t\t\t     const pjmedia_vid_port_param *prm,\n\t\t\t\t\t     pjmedia_vid_port **p_vp);\n\n/**\n * Set the callbacks of the video port's underlying video stream.\n *\n * @param vid_port\tThe video port.\n * @param cb            Pointer to structure containing video stream\n *                      callbacks.\n * @param user_data     Arbitrary user data, which will be given back in the\n *                      callbacks.\n */\nPJ_DECL(void) pjmedia_vid_port_set_cb(pjmedia_vid_port *vid_port,\n\t\t\t\t      const pjmedia_vid_dev_cb *cb,\n                                      void *user_data);\n\n/**\n * Return the underlying video stream of the video port.\n *\n * @param vid_port\tThe video port.\n *\n * @return\t\tThe video stream.\n */\nPJ_DECL(pjmedia_vid_dev_stream*)\npjmedia_vid_port_get_stream(pjmedia_vid_port *vid_port);\n\n/**\n * Return the (passive) media port of the video port. This operation\n * is only valid for video ports created with passive interface selected.\n * Retrieving the media port for active video ports may raise an\n * assertion.\n *\n *  @param vid_port\tThe video port.\n *\n *  @return\t\tThe media port instance, or NULL.\n */\nPJ_DECL(pjmedia_port*)\npjmedia_vid_port_get_passive_port(pjmedia_vid_port *vid_port);\n\n/**\n * Get a clock source from the video port.\n *\n * @param vid_port  The video port.\n *\n * @return\t    The clock source.\n */\nPJ_DECL(pjmedia_clock_src *)\npjmedia_vid_port_get_clock_src( pjmedia_vid_port *vid_port );\n\n/**\n * Set a clock source for the video port.\n *\n * @param vid_port  The video port.\n * @param clocksrc  The clock source.\n *\n * @return\t    PJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t)\npjmedia_vid_port_set_clock_src( pjmedia_vid_port *vid_port,\n                                pjmedia_clock_src *clocksrc );\n\n/**\n * Connect the video port to a downstream (slave) media port. This operation\n * is only valid for video ports created with active interface selected.\n * Connecting a passive video port may raise an assertion.\n *\n * @param vid_port\tThe video port.\n * @param port\t\tA downstream media port to be connected to\n * \t\t\tthis video port.\n * @param destroy\tSpecify if the downstream media port should also be\n * \t\t\tdestroyed by this video port when the video port\n * \t\t\tis destroyed.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_port_connect(pjmedia_vid_port *vid_port,\n\t\t\t\t\t      pjmedia_port *port,\n\t\t\t\t\t      pj_bool_t destroy);\n\n/**\n * Disconnect the video port from its downstream (slave) media port, if any.\n * This operation is only valid for video ports created with active interface\n * selected, and assertion may be triggered if this is invoked on a passive\n * video port.\n *\n * @param vid_port\tThe video port.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_port_disconnect(pjmedia_vid_port *vid_port);\n\n/**\n * Retrieve the media port currently connected as downstream media port of the\n * specified video port. This operation is only valid for video ports created\n * with active interface selected, and assertion may be triggered if this is\n * invoked on a passive video port.\n *\n * @param vid_port\tThe video port.\n *\n * @return\t\tMedia port currently connected to the video port,\n * \t\t\tif any.\n */\nPJ_DECL(pjmedia_port*)\npjmedia_vid_port_get_connected_port(pjmedia_vid_port *vid_port);\n\n/**\n * Start the video port.\n *\n * @param vid_port\tThe video port.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_port_start(pjmedia_vid_port *vid_port);\n\n/**\n * Query whether the video port has been started.\n *\n * @param vid_port\tThe video port.\n *\n * @return\t\tPJ_TRUE if the video port has been started.\n */\nPJ_DECL(pj_bool_t) pjmedia_vid_port_is_running(pjmedia_vid_port *vid_port);\n\n/**\n * Stop the video port.\n *\n * @param vid_port\tThe video port.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_port_stop(pjmedia_vid_port *vid_port);\n\n/**\n * Destroy the video port, along with its video stream. If the video port is\n * an active one, this may also destroy the downstream media port, if the\n * destroy flag is set when the media port is connected.\n *\n * @param vid_port\tThe video port.\n */\nPJ_DECL(void) pjmedia_vid_port_destroy(pjmedia_vid_port *vid_port);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif /* __PJMEDIA_VIDPORT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/vid_stream.h",
    "content": "/* $Id: vid_stream.h 4043 2012-04-12 13:41:50Z nanang $ */\n/* \n * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_VID_STREAM_H__\n#define __PJMEDIA_VID_STREAM_H__\n\n\n/**\n * @file vid_stream.h\n * @brief Video Stream.\n */\n\n#include <pjmedia/endpoint.h>\n#include <pjmedia/jbuf.h>\n#include <pjmedia/port.h>\n#include <pjmedia/rtcp.h>\n#include <pjmedia/transport.h>\n#include <pjmedia/vid_codec.h>\n#include <pj/sock.h>\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJMED_VID_STRM Video streams\n * @ingroup PJMEDIA_PORT\n * @brief Video communication via the network\n * @{\n *\n * A video stream is a bidirectional video communication between two\n * endpoints. It corresponds to a video media description (\"m=video\" line)\n * in SDP session descriptor.\n *\n * A video stream consists of two unidirectional channels:\n *  - encoding channel, which transmits unidirectional video to remote, and\n *  - decoding channel, which receives unidirectional media from remote.\n *\n * A video stream exports two media port interface (see @ref PJMEDIA_PORT),\n * one for each direction, and application normally uses this interface to\n * interconnect the stream to other PJMEDIA components, e.g: the video\n * capture port supplies frames to the encoding port and video renderer\n * consumes frames from the decoding port.\n *\n * A video stream internally manages the following objects:\n *  - an instance of video codec (see @ref PJMEDIA_VID_CODEC),\n *  - an @ref PJMED_JBUF,\n *  - two instances of RTP sessions (#pjmedia_rtp_session, one for each\n *    direction),\n *  - one instance of RTCP session (#pjmedia_rtcp_session),\n *  - and a reference to video transport to send and receive packets\n *    to/from the network (see @ref PJMEDIA_TRANSPORT).\n *\n * Video streams are created by calling #pjmedia_vid_stream_create(),\n * specifying #pjmedia_stream_info structure in the parameter. Application\n * can construct the #pjmedia_vid_stream_info structure manually, or use \n * #pjmedia_vid_stream_info_from_sdp() function to construct the\n * #pjmedia_vid stream_info from local and remote SDP session descriptors.\n */\n\n\n/**\n * Enumeration of video stream sending rate control.\n */\ntypedef enum pjmedia_vid_stream_rc_method\n{\n    /**\n     * No sending rate control. All outgoing RTP packets will be transmitted\n     * immediately right after encoding process is done.\n     */\n    PJMEDIA_VID_STREAM_RC_NONE\t\t    = 0,\n\n    /**\n     * Simple blocking. Each outgoing RTP packet transmission may be delayed\n     * to avoid peak bandwidth that is much higher than specified. The thread\n     * invoking the video stream put_frame(), e.g: video capture device thread,\n     * will be blocked whenever transmission delay takes place.\n     */\n    PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING   = 1\n\n} pjmedia_vid_stream_rc_method;\n\n\n/**\n * Structure of configuration settings for video stream sending rate control.\n */\ntypedef struct pjmedia_vid_stream_rc_config\n{\n    /**\n     * Rate control method.\n     *\n     * Default: PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING.\n     */\n    pjmedia_vid_stream_rc_method    method;\n\n    /**\n     * Upstream/outgoing bandwidth. If this is set to zero, the video stream\n     * will use codec maximum bitrate setting.\n     *\n     * Default: 0 (follow codec maximum bitrate).\n     */\n    unsigned\t\t\t    bandwidth;\n\n} pjmedia_vid_stream_rc_config;\n\n\n/** \n * This structure describes video stream information. Each video stream\n * corresponds to one \"m=\" line in SDP session descriptor, and it has\n * its own RTP/RTCP socket pair.\n */\ntypedef struct pjmedia_vid_stream_info\n{\n    pjmedia_type\ttype;\t    /**< Media type (audio, video)\t    */\n    pjmedia_tp_proto\tproto;\t    /**< Transport protocol (RTP/AVP, etc.) */\n    pjmedia_dir\t\tdir;\t    /**< Media direction.\t\t    */\n    pj_sockaddr\t\trem_addr;   /**< Remote RTP address\t\t    */\n    pj_sockaddr\t\trem_rtcp;   /**< Optional remote RTCP address. If\n\t\t\t\t\t sin_family is zero, the RTP address\n\t\t\t\t\t will be calculated from RTP.\t    */\n    unsigned\t\ttx_pt;\t    /**< Outgoing codec paylaod type.\t    */\n    unsigned\t\trx_pt;\t    /**< Incoming codec paylaod type.\t    */\n    pj_uint32_t\t\tssrc;\t    /**< RTP SSRC.\t\t\t    */\n    pj_uint32_t\t\trtp_ts;\t    /**< Initial RTP timestamp.\t\t    */\n    pj_uint16_t\t\trtp_seq;    /**< Initial RTP sequence number.\t    */\n    pj_uint8_t\t\trtp_seq_ts_set;\n\t\t\t\t    /**< Bitmask flags if initial RTP sequence \n\t\t\t\t         and/or timestamp for sender are set.\n\t\t\t\t\t bit 0/LSB : sequence flag \n\t\t\t\t\t bit 1     : timestamp flag \t    */\n    int\t\t\tjb_init;    /**< Jitter buffer init delay in msec.  \n\t\t\t\t\t (-1 for default).\t\t    */\n    int\t\t\tjb_min_pre; /**< Jitter buffer minimum prefetch\n\t\t\t\t\t delay in msec (-1 for default).    */\n    int\t\t\tjb_max_pre; /**< Jitter buffer maximum prefetch\n\t\t\t\t\t delay in msec (-1 for default).    */\n    int\t\t\tjb_max;\t    /**< Jitter buffer max delay in msec.   */\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0\n    pj_bool_t\t\tuse_ka;\t    /**< Stream keep-alive and NAT hole punch\n\t\t\t\t\t (see #PJMEDIA_STREAM_ENABLE_KA)\n\t\t\t\t\t is enabled?\t\t\t    */\n#endif\n\n    pjmedia_vid_codec_info   codec_info;  /**< Incoming codec format info.  */\n    pjmedia_vid_codec_param *codec_param; /**< Optional codec param.\t    */\n\n    pj_bool_t           rtcp_sdes_bye_disabled; \n                                    /**< Disable automatic sending of RTCP\n                                         SDES and BYE.                      */\n\n    pjmedia_vid_stream_rc_config rc_cfg;\n                                    /**< Stream send rate control settings. */\n} pjmedia_vid_stream_info;\n\n\n/**\n * This function will initialize the video stream info based on information\n * in both SDP session descriptors for the specified stream index. \n * The remaining information will be taken from default codec parameters. \n * If socket info array is specified, the socket will be copied to the \n * session info as well.\n *\n * @param si\t\tStream info structure to be initialized.\n * @param pool\t\tPool to allocate memory.\n * @param endpt\t\tPJMEDIA endpoint instance.\n * @param local\t\tLocal SDP session descriptor.\n * @param remote\tRemote SDP session descriptor.\n * @param stream_idx\tMedia stream index in the session descriptor.\n *\n * @return\t\tPJ_SUCCESS if stream info is successfully initialized.\n */\nPJ_DECL(pj_status_t)\npjmedia_vid_stream_info_from_sdp(pjmedia_vid_stream_info *si,\n\t\t\t         pj_pool_t *pool,\n\t\t\t\t pjmedia_endpt *endpt,\n\t\t\t\t const pjmedia_sdp_session *local,\n\t\t\t\t const pjmedia_sdp_session *remote,\n\t\t\t\t unsigned stream_idx);\n\n\n/**\n * Initialize the video stream rate control with default settings.\n *\n * @param cfg\t\tVideo stream rate control structure to be initialized.\n */\nPJ_DECL(void)\npjmedia_vid_stream_rc_config_default(pjmedia_vid_stream_rc_config *cfg);\n\n\n/*\n * Opaque declaration for video stream.\n */\ntypedef struct pjmedia_vid_stream pjmedia_vid_stream;\n\n\n/**\n * Create a video stream based on the specified parameter. After the video\n * stream has been created, application normally would want to get the media\n * port interface of the stream, by calling pjmedia_vid_stream_get_port().\n * The media port interface exports put_frame() and get_frame() function,\n * used to transmit and receive media frames from the stream.\n *\n * Without application calling put_frame() and get_frame(), there will be \n * no media frames transmitted or received by the stream.\n *\n * @param endpt\t\tMedia endpoint.\n * @param pool\t\tOptional pool to allocate memory for the stream. If\n * \t\t\tthis is not specified, one will be created internally.\n * \t\t\tA large number of memory may be needed because jitter\n *\t\t\tbuffer needs to preallocate some storage.\n * @param info\t\tStream information to create the stream. Upon return,\n * \t\t\tthis info will be updated with the information from\n * \t\t\tthe instantiated codec. Note that if the \"pool\"\n * \t\t\targument is NULL, some fields in this \"info\" parameter\n * \t\t\twill be allocated from the internal pool of the\n * \t\t\tstream, which means that they will only remain valid\n * \t\t\tas long as the stream is not destroyed.\n * @param tp\t\tMedia transport instance used to transmit and receive\n * \t\t\tRTP/RTCP packets to/from the underlying network.\n * @param user_data\tArbitrary user data (for future callback feature).\n * @param p_stream\tPointer to receive the video stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_create(\n\t\t\t\t\tpjmedia_endpt *endpt,\n\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\tpjmedia_vid_stream_info *info,\n\t\t\t\t\tpjmedia_transport *tp,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tpjmedia_vid_stream **p_stream);\n\n/**\n * Destroy the video stream.\n *\n * @param stream\tThe video stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_destroy(pjmedia_vid_stream *stream);\n\n\n/**\n * Get the media port interface of the stream. The media port interface\n * declares put_frame() and get_frame() function, which is the only \n * way for application to transmit and receive media frames from the\n * stream. As bidirectional video streaming may have different video\n * formats in the encoding and decoding direction, there are two media\n * ports exported by the video stream, one for each direction.\n *\n * @param stream\tThe video stream.\n * @param dir\t\tThe video direction.\n * @param p_port\tPointer to receive the port interface.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_get_port(\n\t\t\t\t\t    pjmedia_vid_stream *stream,\n\t\t\t\t\t    pjmedia_dir dir,\n\t\t\t\t\t    pjmedia_port **p_port);\n\n\n/**\n * Get the media transport object associated with this stream.\n *\n * @param st\t\tThe video stream.\n *\n * @return\t\tThe transport object being used by the stream.\n */\nPJ_DECL(pjmedia_transport*) pjmedia_vid_stream_get_transport(\n\t\t\t\t\t    pjmedia_vid_stream *st);\n\n\n/**\n * Get the stream statistics. See also #pjmedia_stream_get_stat_jbuf()\n *\n * @param stream\tThe video stream.\n * @param stat\t\tMedia stream statistics.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_get_stat(\n\t\t\t\t\t    const pjmedia_vid_stream *stream,\n\t\t\t\t\t    pjmedia_rtcp_stat *stat);\n\n/**\n * Reset the video stream statistics.\n *\n * @param stream\tThe video stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_reset_stat(pjmedia_vid_stream *stream);\n\n\n/**\n * Get current jitter buffer state. See also #pjmedia_stream_get_stat()\n *\n * @param stream\tThe video stream.\n * @param state\t\tJitter buffer state.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_get_stat_jbuf(\n\t\t\t\t\t    const pjmedia_vid_stream *stream,\n\t\t\t\t\t    pjmedia_jb_state *state);\n\n\n/**\n * Get the stream info.\n *\n * @param stream\tThe video stream.\n * @param info\t\tVideo stream info.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_get_info(\n\t\t\t\t\t    const pjmedia_vid_stream *stream,\n\t\t\t\t\t    pjmedia_vid_stream_info *info);\n\n\n/**\n * Start the video stream. This will start the appropriate channels\n * in the video stream, depending on the video direction that was set\n * when the stream was created.\n *\n * @param stream\tThe video stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_start(pjmedia_vid_stream *stream);\n\n\n/**\n * Query if the stream is started on the specified direction.\n *\n * @param stream\tThe video stream.\n * @param dir \t\tThe direction to be checked.\n *\n * @return\t\tPJ_TRUE if stream is started.\n */\nPJ_DECL(pj_bool_t) pjmedia_vid_stream_is_running(pjmedia_vid_stream *stream,\n                                                 pjmedia_dir dir);\n\n/**\n * Pause stream channels.\n *\n * @param stream\tThe video stream.\n * @param dir\t\tWhich channel direction to pause.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_pause(pjmedia_vid_stream *stream,\n\t\t\t\t\t      pjmedia_dir dir);\n\n/**\n * Resume stream channels.\n *\n * @param stream\tThe video stream.\n * @param dir\t\tWhich channel direction to resume.\n *\n * @return\t\tPJ_SUCCESS on success;\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_resume(pjmedia_vid_stream *stream,\n\t\t\t\t\t       pjmedia_dir dir);\n\n\n/**\n * Force stream to send video keyframe on the next transmission.\n *\n * @param stream\tThe video stream.\n *\n * @return\t\tPJ_SUCCESS on success;\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_send_keyframe(\n\t\t\t\t\t\tpjmedia_vid_stream *stream);\n\n\n/**\n * Send RTCP SDES for the media stream.\n *\n * @param stream\tThe media stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_send_rtcp_sdes(\n\t\t\t\t\t\tpjmedia_vid_stream *stream);\n\n\n/**\n * Send RTCP BYE for the media stream.\n *\n * @param stream\tThe media stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_send_rtcp_bye(\n\t\t\t\t\t\tpjmedia_vid_stream *stream);\n\n\n/**\n * Send RTCP PLI for the media stream.\n *\n * @param stream\tThe media stream.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_stream_send_rtcp_pli(\n\t\t\t\t\t\tpjmedia_vid_stream *stream);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_VID_STREAM_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/vid_tee.h",
    "content": "/* $Id: vid_tee.h 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_VID_TEE_H__\n#define __PJMEDIA_VID_TEE_H__\n\n/**\n * @file vid_tee.h\n * @brief Video tee (source duplicator).\n */\n#include <pjmedia/port.h>\n\n/**\n * @addtogroup PJMEDIA_VID_TEE Video source duplicator\n * @ingroup PJMEDIA_PORT\n * @brief Duplicate video data from a media port into multiple media port \n *  destinations\n * @{\n *\n * This section describes media port to duplicate video data in the stream.\n *\n * A video tee branches video stream flow from one source port to multiple\n * destination ports by simply duplicating the video data supplied by the\n * source port and delivering the copy to all registered destinations.\n *\n * The video tee is a unidirectional port, i.e: data flows from source port\n * to destination ports only. Also, the video source port MUST actively call\n * pjmedia_port_put_frame() to the video tee and the video destination ports\n * MUST NEVER call pjmedia_port_get_frame() to the video tee. Please note that\n * there is no specific order of which destination port will receive a frame\n * from the video tee.\n *\n * The video tee is not thread-safe, so it is application responsibility\n * to synchronize video tee operations, e.g: make sure the source port is\n * paused during adding or removing a destination port.\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Enumeration of video tee flags.\n */\ntypedef enum pjmedia_vid_tee_flag\n{\n    /**\n     * Tell the video tee that the destination port will do in-place\n     * processing, so the delivered data may be modified by this port.\n     * If this flag is used, buffer will be copied before being given to\n     * the destination port.\n     */\n    PJMEDIA_VID_TEE_DST_DO_IN_PLACE_PROC    = 4,\n\n} pjmedia_vid_tee_flag;\n\n\n/**\n * Create a video tee port with the specified source media port. Application\n * should destroy the tee with pjmedia_port_destroy() as usual. Note that\n * destroying the tee does not destroy its destination ports.\n *\n * @param pool\t\t    The pool.\n * @param fmt\t\t    The source media port's format.\n * @param max_dst_cnt\t    The maximum number of destination ports supported.\n * @param p_vid_tee\t    Pointer to receive the video tee port.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate\n *\t\t\t    error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_tee_create(pj_pool_t *pool,\n\t\t\t\t\t    const pjmedia_format *fmt,\n\t\t\t\t\t    unsigned max_dst_cnt,\n\t\t\t\t\t    pjmedia_port **p_vid_tee);\n\n/**\n * Add a destination media port to the video tee. For this function, the\n * destination port's media format must match the source format.\n *\n * @param vid_tee\t    The video tee.\n * @param option\t    Video tee option, see @pjmedia_vid_tee_flag.\n * @param port\t\t    The destination media port.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error\n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_tee_add_dst_port(pjmedia_port *vid_tee,\n\t\t\t\t\t\t  unsigned option,\n\t\t\t\t\t\t  pjmedia_port *port);\n\n\n/**\n * Add a destination media port to the video tee. This function will also\n * create a converter if the destination port's media format does not match\n * the source format.\n *\n * @param vid_tee\t    The video tee.\n * @param option\t    Video tee option, see @pjmedia_vid_tee_flag.\n * @param port\t\t    The destination media port.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error\n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_tee_add_dst_port2(pjmedia_port *vid_tee,\n                                                   unsigned option,\n\t\t\t\t\t\t   pjmedia_port *port);\n\n\n/**\n * Remove a destination media port from the video tee.\n *\n * @param vid_tee\t    The video tee.\n * @param port\t\t    The destination media port to be removed.\n *\n * @return\t\t    PJ_SUCCESS on success, or the appropriate error\n *\t\t\t    code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_tee_remove_dst_port(pjmedia_port *vid_tee,\n\t\t\t\t\t\t     pjmedia_port *port);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif /* __PJMEDIA_VID_TEE_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/wav_playlist.h",
    "content": "/* $Id: wav_playlist.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_WAV_PLAYLIST_H__\n#define __PJMEDIA_WAV_PLAYLIST_H__\n\n/**\n * @file wav_playlist.h\n * @brief WAV file playlist.\n */\n#include <pjmedia/wav_port.h>\n\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJMEDIA_WAV_PLAYLIST WAV File Play List\n * @ingroup PJMEDIA_PORT\n * @brief Audio playback of multiple WAV files\n * @{\n *\n * The WAV play list port enables application to play back multiple\n * WAV files in a playlist.\n */\n\n/**\n * Create a WAV playlist from the array of WAV file names. The WAV\n * files must have the same clock rate, number of channels, and bits\n * per sample, or otherwise this function will return error.\n *\n * @param pool\t\tPool to create memory buffers for this port.\n * @param port_label\tOptional label to set as the port name.\n * @param file_list\tArray of WAV file names.\n * @param file_count\tNumber of files in the array.\n * @param ptime\t\tThe duration (in miliseconds) of each frame read\n *\t\t\tfrom this port. If the value is zero, the default\n *\t\t\tduration (20ms) will be used.\n * @param options\tOptional options. Application may specify \n *\t\t\tPJMEDIA_FILE_NO_LOOP to prevent play back loop.\n * @param buff_size\tBuffer size to be allocated. If the value is zero or\n *\t\t\tnegative, the port will use default buffer size (which\n *\t\t\tis about 4KB).\n * @param p_port\tPointer to receive the file port instance.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_wav_playlist_create(pj_pool_t *pool,\n\t\t\t\t\t\t const pj_str_t *port_label,\n\t\t\t\t\t\t const pj_str_t file_list[],\n\t\t\t\t\t\t int file_count,\n\t\t\t\t\t\t unsigned ptime,\n\t\t\t\t\t\t unsigned options,\n\t\t\t\t\t\t pj_ssize_t buff_size,\n\t\t\t\t\t\t pjmedia_port **p_port);\n\n\n/**\n * Register a callback to be called when the file reading has reached the\n * end of file of the last file. If the file is set to play repeatedly, \n * then the callback will be called multiple times. Note that only one \n * callback can be registered for each file port.\n *\n * @param port\t\tThe WAV play list port.\n * @param user_data\tUser data to be specified in the callback\n * @param cb\t\tCallback to be called. If the callback returns non-\n *\t\t\tPJ_SUCCESS, the playback will stop. Note that if\n *\t\t\tapplication destroys the file port in the callback,\n *\t\t\tit must return non-PJ_SUCCESS here.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t)\npjmedia_wav_playlist_set_eof_cb(pjmedia_port *port,\n\t\t\t        void *user_data,\n\t\t\t        pj_status_t (*cb)(pjmedia_port *port,\n\t\t\t\t\t\t  void *usr_data));\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_WAV_PLAYLIST_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/wav_port.h",
    "content": "/* $Id: wav_port.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_WAV_PORT_H__\n#define __PJMEDIA_WAV_PORT_H__\n\n/**\n * @file wav_port.h\n * @brief WAV file player and writer.\n */\n#include <pjmedia/port.h>\n\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJMEDIA_FILE_PLAY WAV File Player\n * @ingroup PJMEDIA_PORT\n * @brief Audio playback from WAV file\n * @{\n */\n\n/**\n * WAV file player options.\n */\nenum pjmedia_file_player_option\n{\n    /**\n     * Tell the file player to return NULL frame when the whole\n     * file has been played.\n     */\n    PJMEDIA_FILE_NO_LOOP = 1\n};\n\n\n/**\n * Additional information about the WAV player.\n */\ntypedef struct pjmedia_wav_player_info\n{\n    /**\n     * Format ID of the payload.\n     */\n    pjmedia_format_id\tfmt_id;\n\n    /**\n     * The number of bits per sample of the file payload. For example,\n     * the value is 16 for PCM WAV and 8 for Alaw/Ulas WAV files.\n     */\n    unsigned\t\tpayload_bits_per_sample;\n\n    /**\n     * The WAV payload size in bytes.\n     */\n    pj_uint32_t\t\tsize_bytes;\n\n    /**\n     * The WAV payload size in samples.\n     */\n    pj_uint32_t\t\tsize_samples;\n\n} pjmedia_wav_player_info;\n\n\n/**\n * Create a media port to play streams from a WAV file. WAV player port\n * supports for reading WAV file with uncompressed 16 bit PCM format or \n * compressed G.711 A-law/U-law format.\n *\n * @param pool\t\tPool to create memory buffers for this port.\n * @param filename\tFile name to open.\n * @param ptime\t\tThe duration (in miliseconds) of each frame read\n *\t\t\tfrom this port. If the value is zero, the default\n *\t\t\tduration (20ms) will be used.\n * @param flags\t\tPort creation flags.\n * @param buff_size\tBuffer size to be allocated. If the value is zero or\n *\t\t\tnegative, the port will use default buffer size (which\n *\t\t\tis about 4KB).\n * @param p_port\tPointer to receive the file port instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_wav_player_port_create( pj_pool_t *pool,\n\t\t\t\t\t\t     const char *filename,\n\t\t\t\t\t\t     unsigned ptime,\n\t\t\t\t\t\t     unsigned flags,\n\t\t\t\t\t\t     pj_ssize_t buff_size,\n\t\t\t\t\t\t     pjmedia_port **p_port );\n\n/**\n * Get additional info about the file player.\n *\n * @param port\t\tThe file port.\n * @param i\t\tThe info.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_wav_player_get_info(pjmedia_port *port,\n                                                 pjmedia_wav_player_info *i);\n\n/**\n * Get the data length, in bytes.\n *\n * @param port\t\tThe file player port.\n *\n * @return\t\tThe length of the data, in bytes. On error, the\n * \t\t\terror code is given as negative value.\n */\nPJ_DECL(pj_ssize_t) pjmedia_wav_player_get_len(pjmedia_port *port);\n\n\n/**\n * Set the file play position of WAV player.\n *\n * @param port\t\tThe file player port.\n * @param offset\tPlayback position in bytes, relative to the start of\n *\t\t\tthe payload.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_wav_player_port_set_pos( pjmedia_port *port,\n\t\t\t\t\t\t      pj_uint32_t offset );\n\n\n/**\n * Get the file play position of WAV player, in bytes.\n *\n * @param port\t\tThe file player port.\n *\n * @return\t\tThe current play position, in bytes. On error, the\n * \t\t\terror code is given as negative value.\n */\nPJ_DECL(pj_ssize_t) pjmedia_wav_player_port_get_pos( pjmedia_port *port );\n\n\n/**\n * Register a callback to be called when the file reading has reached the\n * end of file. If the file is set to play repeatedly, then the callback\n * will be called multiple times. Note that only one callback can be \n * registered for each file port.\n *\n * @param port\t\tThe file player port.\n * @param user_data\tUser data to be specified in the callback\n * @param cb\t\tCallback to be called. If the callback returns non-\n *\t\t\tPJ_SUCCESS, the playback will stop. Note that if\n *\t\t\tapplication destroys the file port in the callback,\n *\t\t\tit must return non-PJ_SUCCESS here.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_wav_player_set_eof_cb( pjmedia_port *port,\n\t\t\t       void *user_data,\n\t\t\t       pj_status_t (*cb)(pjmedia_port *port,\n\t\t\t\t\t\t void *usr_data));\n\n/**\n * @}\n */\n\n\n/**\n * @defgroup PJMEDIA_FILE_REC File Writer (Recorder)\n * @ingroup PJMEDIA_PORT\n * @brief Audio capture/recording to WAV file\n * @{\n */\n\n\n/**\n * WAV file writer options.\n */\nenum pjmedia_file_writer_option\n{\n    /**\n     * Tell the file writer to save the audio in PCM format.\n     */\n    PJMEDIA_FILE_WRITE_PCM = 0,\n\n    /**\n     * Tell the file writer to save the audio in G711 Alaw format.\n     */\n    PJMEDIA_FILE_WRITE_ALAW = 1,\n\n    /**\n     * Tell the file writer to save the audio in G711 Alaw format.\n     */\n    PJMEDIA_FILE_WRITE_ULAW = 2,\n};\n\n\n/**\n * Create a media port to record streams to a WAV file. Note that the port\n * must be closed properly (with #pjmedia_port_destroy()) so that the WAV\n * header can be filled with correct values (such as the file length).\n * WAV writer port supports for writing audio in uncompressed 16 bit PCM format\n * or compressed G.711 U-law/A-law format, this needs to be specified in \n * \\a flags param.\n *\n * @param pool\t\t    Pool to create memory buffers for this port.\n * @param filename\t    File name.\n * @param clock_rate\t    The sampling rate.\n * @param channel_count\t    Number of channels.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Number of bits per sample (eg 16).\n * @param flags\t\t    Port creation flags, see\n *\t\t\t    #pjmedia_file_writer_option.\n * @param buff_size\t    Buffer size to be allocated. If the value is \n *\t\t\t    zero or negative, the port will use default buffer\n *\t\t\t    size (which is about 4KB).\n * @param p_port\t    Pointer to receive the file port instance.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_wav_writer_port_create(pj_pool_t *pool,\n\t\t\t\t\t\t    const char *filename,\n\t\t\t\t\t\t    unsigned clock_rate,\n\t\t\t\t\t\t    unsigned channel_count,\n\t\t\t\t\t\t    unsigned samples_per_frame,\n\t\t\t\t\t\t    unsigned bits_per_sample,\n\t\t\t\t\t\t    unsigned flags,\n\t\t\t\t\t\t    pj_ssize_t buff_size,\n\t\t\t\t\t\t    pjmedia_port **p_port );\n\n\n/**\n * Get current writing position. Note that this does not necessarily match\n * the size written to the file, since the WAV writer employs some internal\n * buffering. Also the value reported here only indicates the payload size\n * (it does not include the size of the WAV header),\n *\n * @param port\t\tThe file writer port.\n *\n * @return\t\tPositive value to indicate the position (in bytes), \n *\t\t\tor negative value containing the error code.\n */\nPJ_DECL(pj_ssize_t) pjmedia_wav_writer_port_get_pos( pjmedia_port *port );\n\n\n/**\n * Register the callback to be called when the file writing has reached\n * certain size. Application can use this callback, for example, to limit\n * the size of the output file.\n *\n * @param port\t\tThe file writer port.\n * @param pos\t\tThe file position on which the callback will be called.\n * @param user_data\tUser data to be specified in the callback, and will be\n *\t\t\tgiven on the callback.\n * @param cb\t\tCallback to be called. If the callback returns non-\n *\t\t\tPJ_SUCCESS, the writing will stop. Note that if \n *\t\t\tapplication destroys the port in the callback, it must\n *\t\t\treturn non-PJ_SUCCESS here.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_wav_writer_port_set_cb( pjmedia_port *port,\n\t\t\t\tpj_size_t pos,\n\t\t\t\tvoid *user_data,\n\t\t\t\tpj_status_t (*cb)(pjmedia_port *port,\n\t\t\t\t\t\t  void *usr_data));\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_WAV_PORT_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/wave.h",
    "content": "/* $Id: wave.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_WAVE_H__\n#define __PJMEDIA_WAVE_H__\n\n\n/**\n * @file wave.h\n * @brief WAVE file manipulation.\n */\n#include <pjmedia/types.h>\n\n/**\n * @defgroup PJMEDIA_FILE_FORMAT File Formats\n * @brief Supported file formats\n */\n\n\n/**\n * @defgroup PJMEDIA_WAVE WAVE Header\n * @ingroup PJMEDIA_FILE_FORMAT\n * @brief Representation of RIFF/WAVE file format\n * @{\n *\n * This the the low level representation of RIFF/WAVE file format. For\n * higher abstraction, please see \\ref PJMEDIA_FILE_PLAY and \n * \\ref PJMEDIA_FILE_REC.\n */\n\n\nPJ_BEGIN_DECL\n\n/**\n * Standard RIFF tag to identify RIFF file format in the WAVE header.\n */\n#define PJMEDIA_RIFF_TAG\t('F'<<24|'F'<<16|'I'<<8|'R')\n\n/**\n * Standard WAVE tag to identify WAVE header.\n */\n#define PJMEDIA_WAVE_TAG\t('E'<<24|'V'<<16|'A'<<8|'W')\n\n/**\n * Standard FMT tag to identify format chunks.\n */\n#define PJMEDIA_FMT_TAG\t\t(' '<<24|'t'<<16|'m'<<8|'f')\n\n/**\n * Standard DATA tag to identify data chunks.\n */\n#define PJMEDIA_DATA_TAG\t('a'<<24|'t'<<16|'a'<<8|'d')\n\n/**\n * Standard FACT tag to identify fact chunks.\n */\n#define PJMEDIA_FACT_TAG\t('t'<<24|'c'<<16|'a'<<8|'f')\n\n\n/**\n * Enumeration of format compression tag.\n */\ntypedef enum {\n    PJMEDIA_WAVE_FMT_TAG_PCM\t= 1,\n    PJMEDIA_WAVE_FMT_TAG_ALAW\t= 6,\n    PJMEDIA_WAVE_FMT_TAG_ULAW\t= 7\n} pjmedia_wave_fmt_tag;\n\n\n/**\n * This file describes the simpler/canonical version of a WAVE file.\n * It does not support the full RIFF format specification.\n */\n#pragma pack(2)\nstruct pjmedia_wave_hdr\n{\n    /** This structure describes RIFF WAVE file header */\n    struct {\n\tpj_uint32_t riff;\t\t/**< \"RIFF\" ASCII tag.\t\t*/\n\tpj_uint32_t file_len;\t\t/**< File length minus 8 bytes\t*/\n\tpj_uint32_t wave;\t\t/**< \"WAVE\" ASCII tag.\t\t*/\n    } riff_hdr;\n\n    /** This structure describes format chunks/header  */\n    struct {\n\tpj_uint32_t fmt;\t\t/**< \"fmt \" ASCII tag.\t\t*/\n\tpj_uint32_t len;\t\t/**< 16 for PCM.\t\t*/\n\tpj_uint16_t fmt_tag;\t\t/**< 1 for PCM\t\t\t*/\n\tpj_uint16_t nchan;\t\t/**< Number of channels.\t*/\n\tpj_uint32_t sample_rate;\t/**< Sampling rate.\t\t*/\n\tpj_uint32_t bytes_per_sec;\t/**< Average bytes per second.\t*/\n\tpj_uint16_t block_align;\t/**< nchannels * bits / 8\t*/\n\tpj_uint16_t bits_per_sample;\t/**< Bits per sample.\t\t*/\n    } fmt_hdr;\n\n    /** The data header preceeds the actual data in the file. */\n    struct {\n\tpj_uint32_t data;\t\t/**< \"data\" ASCII tag.\t\t*/\n\tpj_uint32_t len;\t\t/**< Data length.\t\t*/\n    } data_hdr;\n};\n#pragma pack()\n\n/**\n * @see pjmedia_wave_hdr\n */\ntypedef struct pjmedia_wave_hdr pjmedia_wave_hdr;\n\n/**\n * This structure describes generic RIFF subchunk header.\n */\ntypedef struct pjmedia_wave_subchunk\n{\n    pj_uint32_t\t    id;\t\t\t/**< Subchunk ASCII tag.\t    */\n    pj_uint32_t\t    len;\t\t/**< Length following this field    */\n} pjmedia_wave_subchunk;\n\n\n/**\n * Normalize subchunk header from little endian (the representation of\n * RIFF file) into host's endian.\n */\n#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0\n#   define PJMEDIA_WAVE_NORMALIZE_SUBCHUNK(ch)  \\\n\t    do { \\\n\t\t(ch)->id = pj_swap32((ch)->id); \\\n\t\t(ch)->len = pj_swap32((ch)->len); \\\n\t    } while (0)\n#else\n#   define PJMEDIA_WAVE_NORMALIZE_SUBCHUNK(ch)\n#endif\n\n\n/**\n * On big-endian hosts, this function swaps the byte order of the values\n * in the WAVE header fields. On little-endian hosts, this function does \n * nothing.\n *\n * Application SHOULD call this function after reading the WAVE header\n * chunks from a file.\n *\n * @param hdr\t    The WAVE header.\n */\nPJ_DECL(void) pjmedia_wave_hdr_file_to_host( pjmedia_wave_hdr *hdr );\n\n\n/**\n * On big-endian hosts, this function swaps the byte order of the values\n * in the WAVE header fields. On little-endian hosts, this function does \n * nothing.\n *\n * Application SHOULD call this function before writing the WAVE header\n * to a file.\n *\n * @param hdr\t    The WAVE header.\n */\nPJ_DECL(void) pjmedia_wave_hdr_host_to_file( pjmedia_wave_hdr *hdr );\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_WAVE_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia/wsola.h",
    "content": "/* $Id: wsola.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_WSOLA_H__\n#define __PJMEDIA_WSOLA_H__\n\n/**\n * @file wsola.h\n * @brief Waveform Similarity Based Overlap-Add (WSOLA)\n */\n#include <pjmedia/types.h>\n\n/**\n * @defgroup PJMED_WSOLA Waveform Similarity Based Overlap-Add (WSOLA)\n * @ingroup PJMEDIA_FRAME_OP\n * @brief Time-scale modification to audio without affecting the pitch\n * @{\n *\n * This section describes Waveform Similarity Based Overlap-Add (WSOLA)\n * implementation in PJMEDIA. The WSOLA API here can be used both to \n * compress (speed-up) and stretch (expand, slow down) audio playback\n * without altering the pitch, or as a mean for performing packet loss\n * concealment (WSOLA).\n *\n * The WSOLA implementation is used by \\ref PJMED_DELAYBUF and \\ref PJMED_PLC.\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Opaque declaration for WSOLA structure.\n */\ntypedef struct pjmedia_wsola pjmedia_wsola;\n\n\n/**\n * WSOLA options, can be combined with bitmask operation.\n */\nenum pjmedia_wsola_option\n{\n    /**\n     * Disable Hanning window to conserve memory.\n     */\n    PJMEDIA_WSOLA_NO_HANNING\t= 1,\n\n    /**\n     * Specify that the WSOLA will not be used for PLC.\n     */\n    PJMEDIA_WSOLA_NO_PLC = 2,\n\n    /**\n     * Specify that the WSOLA will not be used to discard frames in\n     * non-contiguous buffer.\n     */\n    PJMEDIA_WSOLA_NO_DISCARD = 4,\n\n    /**\n     * Disable fade-in and fade-out feature in the transition between\n     * actual and synthetic frames in WSOLA. With fade feature enabled, \n     * WSOLA will only generate a limited number of synthetic frames \n     * (configurable with #pjmedia_wsola_set_max_expand()), fading out \n     * the volume on every more samples it generates, and when it reaches\n     * the limit it will only generate silence.\n     */\n    PJMEDIA_WSOLA_NO_FADING = 8\n};\n\n\n\n/**\n * Create and initialize WSOLA.\n *\n * @param pool\t\t    Pool to allocate memory for WSOLA.\n * @param clock_rate\t    Sampling rate of audio playback.\n * @param samples_per_frame Number of samples per frame.\n * @param channel_count\t    Number of channels.\n * @param options\t    Option flags, bitmask combination of\n *\t\t\t    #pjmedia_wsola_option.\n * @param p_wsola\t    Pointer to receive WSOLA structure.\n *\n * @return\t\t    PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_wsola_create(pj_pool_t *pool, \n\t\t\t\t\t  unsigned clock_rate,\n\t\t\t\t\t  unsigned samples_per_frame,\n\t\t\t\t\t  unsigned channel_count,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t\t  pjmedia_wsola **p_wsola);\n\n\n/**\n * Specify maximum number of continuous synthetic frames that can be\n * generated by WSOLA, in milliseconds. This option will only take\n * effect if fading is not disabled via the option when the WSOLA\n * session was created. Default value is PJMEDIA_WSOLA_MAX_EXPAND_MSEC\n * (see also the documentation of PJMEDIA_WSOLA_MAX_EXPAND_MSEC for\n * more information).\n *\n * @param wsola\t    The WSOLA session\n * @param msec\t    The duration.\n *\n * @return\t    PJ_SUCCESS normally.\n */\nPJ_DECL(pj_status_t) pjmedia_wsola_set_max_expand(pjmedia_wsola *wsola,\n\t\t\t\t\t\t  unsigned msec);\n\n\n/**\n * Destroy WSOLA.\n *\n * @param wsola\t    WSOLA session.\n *\n * @return\t    PJ_SUCCESS normally.\n */\nPJ_DECL(pj_status_t) pjmedia_wsola_destroy(pjmedia_wsola *wsola);\n\n\n/**\n * Reset the buffer contents of WSOLA.\n *\n * @param wsola\t    WSOLA session.\n * @param options   Reset options, must be zero for now.\n *\n * @return\t    PJ_SUCCESS normally.\n */\nPJ_DECL(pj_status_t) pjmedia_wsola_reset(pjmedia_wsola *wsola,\n\t\t\t\t\t unsigned options);\n\n\n/**\n * Give one good frame to WSOLA to be kept as reference. Application\n * must continuously give WSOLA good frames to keep its session up to\n * date with current playback. Depending on the WSOLA implementation,\n * this function may modify the content of the frame.\n *\n * @param wsola\t    WSOLA session.\n * @param frm\t    The frame, which length must match the samples per\n *\t\t    frame setting of the WSOLA session.\n * @param prev_lost If application previously generated a synthetic\n *\t\t    frame with #pjmedia_wsola_generate() before calling\n *\t\t    this function, specify whether that was because of\n *\t\t    packet lost. If so, set this parameter to PJ_TRUE\n *\t\t    to make WSOLA interpolate this frame with its buffer.\n *\t\t    Otherwise if this value is PJ_FALSE, WSOLA will\n *\t\t    just append this frame to the end of its buffer.\n *\n * @return\t    PJ_SUCCESS normally.\n */\nPJ_DECL(pj_status_t) pjmedia_wsola_save(pjmedia_wsola *wsola, \n\t\t\t\t\tpj_int16_t frm[], \n\t\t\t\t\tpj_bool_t prev_lost);\n\n/**\n * Generate one synthetic frame from WSOLA.\n *\n * @param wsola\t    WSOLA session.\n * @param frm\t    Buffer to receive the frame.\n *\n * @return\t    PJ_SUCCESS normally.\n */\nPJ_DECL(pj_status_t) pjmedia_wsola_generate(pjmedia_wsola *wsola, \n\t\t\t\t\t    pj_int16_t frm[]);\n\n\n/**\n * Compress or compact the specified buffer by removing some audio samples\n * from the buffer, without altering the pitch. For this function to work, \n * total length of the buffer must be more than twice \\a erase_cnt.\n * \n * @param wsola\t    WSOLA session.\n * @param buf1\t    Pointer to buffer. \n * @param buf1_cnt  Number of samples in the buffer.\n * @param buf2\t    Pointer to second buffer, if the buffer is not\n *\t\t    contiguous. Otherwise this parameter must be NULL.\n * @param buf2_cnt  Number of samples in the second buffer, if the buffer\n *\t\t    is not contiguous. Otherwise this parameter should be\n *\t\t    zero.\n * @param erase_cnt On input, specify the number of samples to be erased.\n *\t\t    This function may erase more or less than the requested \n *\t\t    number, and the actual number of samples erased will be \n *\t\t    given on this argument upon returning from the function.\n *\n * @return\t    PJ_SUCCESS if some samples have been erased, PJ_ETOOSMALL\n *\t\t    if buffer is too small to be reduced, PJ_EINVAL if any\n *\t\t    of the parameters are not valid.\n */\nPJ_DECL(pj_status_t) pjmedia_wsola_discard(pjmedia_wsola *wsola, \n\t\t\t\t\t   pj_int16_t buf1[],\n\t\t\t\t\t   unsigned buf1_cnt, \n\t\t\t\t\t   pj_int16_t buf2[],\n\t\t\t\t\t   unsigned buf2_cnt,\n\t\t\t\t\t   unsigned *erase_cnt);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_WSOLA_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-audiodev/audiodev.h",
    "content": "/* $Id: audiodev.h 4243 2012-08-31 11:42:17Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_AUDIODEV_AUDIODEV_H__\n#define __PJMEDIA_AUDIODEV_AUDIODEV_H__\n\n/**\n * @file audiodev.h\n * @brief Audio device API.\n */\n#include <pjmedia-audiodev/config.h>\n#include <pjmedia-audiodev/errno.h>\n#include <pjmedia/format.h>\n#include <pjmedia/frame.h>\n#include <pjmedia/types.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup s2_audio_device_reference Audio Device API Reference\n * @ingroup audio_device_api\n * @brief API Reference\n * @{\n */\n\n/**\n * Type for device index.\n */\ntypedef pj_int32_t pjmedia_aud_dev_index;\n\n/**\n * Device index constants.\n */\nenum\n{\n    /** \n     * Constant to denote default capture device \n     */\n    PJMEDIA_AUD_DEFAULT_CAPTURE_DEV = -1,\n\n    /** \n     * Constant to denote default playback device \n     */\n    PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV = -2,\n\n    /**\n     * Constant to denote invalid device index.\n     */\n    PJMEDIA_AUD_INVALID_DEV = -3\n};\n\n\n/**\n * This enumeration identifies various audio device capabilities. These audio\n * capabilities indicates what features are supported by the underlying\n * audio device implementation.\n *\n * Applications get these capabilities in the #pjmedia_aud_dev_info structure.\n *\n * Application can also set the specific features/capabilities when opening\n * the audio stream by setting the \\a flags member of #pjmedia_aud_param\n * structure.\n *\n * Once audio stream is running, application can also retrieve or set some\n * specific audio capability, by using #pjmedia_aud_stream_get_cap() and\n * #pjmedia_aud_stream_set_cap() and specifying the desired capability. The\n * value of the capability is specified as pointer, and application needs to\n * supply the pointer with the correct value, according to the documentation\n * of each of the capability.\n */\ntypedef enum pjmedia_aud_dev_cap\n{\n    /** \n     * Support for audio formats other than PCM. The value of this capability\n     * is represented by #pjmedia_format structure.\n     */\n    PJMEDIA_AUD_DEV_CAP_EXT_FORMAT = 1,\n\n    /** \n     * Support for audio input latency control or query. The value of this \n     * capability is an unsigned integer containing milliseconds value of\n     * the latency.\n     */\n    PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY = 2,\n\n    /** \n     * Support for audio output latency control or query. The value of this \n     * capability is an unsigned integer containing milliseconds value of\n     * the latency.\n     */\n    PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY = 4,\n\n    /** \n     * Support for setting/retrieving the audio input device volume level.\n     * The value of this capability is an unsigned integer representing \n     * the input audio volume setting in percent.\n     */\n    PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING = 8,\n\n    /** \n     * Support for setting/retrieving the audio output device volume level.\n     * The value of this capability is an unsigned integer representing \n     * the output audio volume setting in percent.\n     */\n    PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING = 16,\n\n    /** \n     * Support for monitoring the current audio input signal volume. \n     * The value of this capability is an unsigned integer representing \n     * the audio volume in percent.\n     */\n    PJMEDIA_AUD_DEV_CAP_INPUT_SIGNAL_METER = 32,\n\n    /** \n     * Support for monitoring the current audio output signal volume. \n     * The value of this capability is an unsigned integer representing \n     * the audio volume in percent.\n     */\n    PJMEDIA_AUD_DEV_CAP_OUTPUT_SIGNAL_METER = 64,\n\n    /** \n     * Support for audio input routing. The value of this capability is an \n     * integer containing #pjmedia_aud_dev_route enumeration.\n     */\n    PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE = 128,\n\n    /** \n     * Support for audio output routing (e.g. loudspeaker vs earpiece). The\n     * value of this capability is an integer containing #pjmedia_aud_dev_route\n     * enumeration.\n     */\n    PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE = 256,\n\n    /** \n     * The audio device has echo cancellation feature. The value of this\n     * capability is a pj_bool_t containing boolean PJ_TRUE or PJ_FALSE.\n     */\n    PJMEDIA_AUD_DEV_CAP_EC = 512,\n\n    /** \n     * The audio device supports setting echo cancellation fail length. The\n     * value of this capability is an unsigned integer representing the\n     * echo tail in milliseconds.\n     */\n    PJMEDIA_AUD_DEV_CAP_EC_TAIL = 1024,\n\n    /** \n     * The audio device has voice activity detection feature. The value\n     * of this capability is a pj_bool_t containing boolean PJ_TRUE or \n     * PJ_FALSE.\n     */\n    PJMEDIA_AUD_DEV_CAP_VAD = 2048,\n\n    /** \n     * The audio device has comfort noise generation feature. The value\n     * of this capability is a pj_bool_t containing boolean PJ_TRUE or \n     * PJ_FALSE.\n     */\n    PJMEDIA_AUD_DEV_CAP_CNG = 4096,\n\n    /** \n     * The audio device has packet loss concealment feature. The value\n     * of this capability is a pj_bool_t containing boolean PJ_TRUE or \n     * PJ_FALSE.\n     */\n    PJMEDIA_AUD_DEV_CAP_PLC = 8192,\n    \n    /**\n     * End of capability\n     */\n    PJMEDIA_AUD_DEV_CAP_MAX = 16384\n\n} pjmedia_aud_dev_cap;\n\n\n/**\n * This enumeration describes audio routing setting.\n */\ntypedef enum pjmedia_aud_dev_route\n{\n    /**\n     * Default route, it is the default audio route of the audio framework\n     * backend, as in opening audio device without specifying any route\n     * setting or with specifying neutral route setting.\n     */\n    PJMEDIA_AUD_DEV_ROUTE_DEFAULT = 0,\n\n    /** Route to loudspeaker */\n    PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER = 1,\n\n    /** Route to earpiece */\n    PJMEDIA_AUD_DEV_ROUTE_EARPIECE = 2,\n\n    /** Route to paired Bluetooth device */\n    PJMEDIA_AUD_DEV_ROUTE_BLUETOOTH = 4\n\n} pjmedia_aud_dev_route;\n\n\n/**\n * Device information structure returned by #pjmedia_aud_dev_get_info().\n */\ntypedef struct pjmedia_aud_dev_info\n{\n    /** \n     * The device name \n     */\n    char name[PJMEDIA_AUD_DEV_INFO_NAME_LEN];\n\n    /** \n     * Maximum number of input channels supported by this device. If the\n     * value is zero, the device does not support input operation (i.e.\n     * it is a playback only device). \n     */\n    unsigned input_count;\n\n    /** \n     * Maximum number of output channels supported by this device. If the\n     * value is zero, the device does not support output operation (i.e. \n     * it is an input only device).\n     */\n    unsigned output_count;\n\n    /** \n     * Default sampling rate.\n     */\n    unsigned default_samples_per_sec;\n\n    /** \n     * The underlying driver name \n     */\n    char driver[32];\n\n    /** \n     * Device capabilities, as bitmask combination of #pjmedia_aud_dev_cap.\n     */\n    unsigned caps;\n\n    /** \n     * Supported audio device routes, as bitmask combination of \n     * #pjmedia_aud_dev_route. The value may be zero if the device\n     * does not support audio routing.\n     */\n    unsigned routes;\n\n    /** \n     * Number of audio formats supported by this device. The value may be\n     * zero if the device does not support non-PCM format.\n     */\n    unsigned ext_fmt_cnt;\n\n    /** \n     * Array of supported extended audio formats \n     */\n    pjmedia_format ext_fmt[8];\n\n\n} pjmedia_aud_dev_info;\n\n\n/** \n * This callback is called by player stream when it needs additional data\n * to be played by the device. Application must fill in the whole of output \n * buffer with audio samples.\n *\n * The frame argument contains the following values:\n *  - timestamp\t    Playback timestamp, in samples.\n *  - buf\t    Buffer to be filled out by application.\n *  - size\t    The size requested in bytes, which will be equal to\n *\t\t    the size of one whole packet.\n *\n * @param user_data User data associated with the stream.\n * @param frame\t    Audio frame, which buffer is to be filled in by\n *\t\t    the application.\n *\n * @return\t    Returning non-PJ_SUCCESS will cause the audio stream\n *\t\t    to stop\n */\ntypedef pj_status_t (*pjmedia_aud_play_cb)(void *user_data,\n\t\t\t\t\t   pjmedia_frame *frame);\n\n/**\n * This callback is called by recorder stream when it has captured the whole\n * packet worth of audio samples.\n *\n * @param user_data User data associated with the stream.\n * @param frame\t    Captured frame.\n *\n * @return\t    Returning non-PJ_SUCCESS will cause the audio stream\n *\t\t    to stop\n */\ntypedef pj_status_t (*pjmedia_aud_rec_cb)(void *user_data,\n\t\t\t\t\t  pjmedia_frame *frame);\n\n/**\n * This structure specifies the parameters to open the audio stream.\n */\ntypedef struct pjmedia_aud_param\n{\n    /**\n     * The audio direction. This setting is mandatory.\n     */\n    pjmedia_dir dir;\n\n    /**\n     * The audio recorder device ID. This setting is mandatory if the audio\n     * direction includes input/capture direction.\n     */\n    pjmedia_aud_dev_index rec_id;\n\n    /**\n     * The audio playback device ID. This setting is mandatory if the audio\n     * direction includes output/playback direction.\n     */\n    pjmedia_aud_dev_index play_id;\n\n    /** \n     * Clock rate/sampling rate. This setting is mandatory. \n     */\n    unsigned clock_rate;\n\n    /** \n     * Number of channels. This setting is mandatory. \n     */\n    unsigned channel_count;\n\n    /** \n     * Number of samples per frame. This setting is mandatory. \n     */\n    unsigned samples_per_frame;\n\n    /** \n     * Number of bits per sample. This setting is mandatory. \n     */\n    unsigned bits_per_sample;\n\n    /** \n     * This flags specifies which of the optional settings are valid in this\n     * structure. The flags is bitmask combination of pjmedia_aud_dev_cap.\n     */\n    unsigned flags;\n\n    /** \n     * Set the audio format. This setting is optional, and will only be used\n     * if PJMEDIA_AUD_DEV_CAP_EXT_FORMAT is set in the flags.\n     */\n    pjmedia_format ext_fmt;\n\n    /**\n     * Input latency, in milliseconds. This setting is optional, and will \n     * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY is set in the flags.\n     */\n    unsigned input_latency_ms;\n\n    /**\n     * Input latency, in milliseconds. This setting is optional, and will \n     * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY is set in the flags.\n     */\n    unsigned output_latency_ms;\n\n    /**\n     * Input volume setting, in percent. This setting is optional, and will \n     * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING is set in \n     * the flags.\n     */\n    unsigned input_vol;\n\n    /**\n     * Output volume setting, in percent. This setting is optional, and will \n     * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING is set in \n     * the flags.\n     */\n    unsigned output_vol;\n\n    /** \n     * Set the audio input route. This setting is optional, and will only be\n     * used if PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE is set in the flags.\n     */\n    pjmedia_aud_dev_route input_route;\n\n    /** \n     * Set the audio output route. This setting is optional, and will only be\n     * used if PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE is set in the flags.\n     */\n    pjmedia_aud_dev_route output_route;\n\n    /**\n     * Enable/disable echo canceller, if the device supports it. This setting\n     * is optional, and will only be used if PJMEDIA_AUD_DEV_CAP_EC is set in\n     * the flags.\n     */\n    pj_bool_t ec_enabled;\n\n    /**\n     * Set echo canceller tail length in milliseconds, if the device supports\n     * it. This setting is optional, and will only be used if\n     * PJMEDIA_AUD_DEV_CAP_EC_TAIL is set in the flags.\n     */\n    unsigned ec_tail_ms;\n\n    /** \n     * Enable/disable PLC. This setting is optional, and will only be used\n     * if PJMEDIA_AUD_DEV_CAP_PLC is set in the flags.\n     */\n    pj_bool_t plc_enabled;\n\n    /** \n     * Enable/disable CNG. This setting is optional, and will only be used\n     * if PJMEDIA_AUD_DEV_CAP_CNG is set in the flags.\n     */\n    pj_bool_t cng_enabled;\n\n    /** \n     * Enable/disable VAD. This setting is optional, and will only be used\n     * if PJMEDIA_AUD_DEV_CAP_VAD is set in the flags.\n     */\n    pj_bool_t vad_enabled;\n\n} pjmedia_aud_param;\n\n\ntypedef enum pjmedia_aud_dev_event {\n    PJMEDIA_AUD_DEV_DEFAULT_INPUT_CHANGED,\n    PJMEDIA_AUD_DEV_DEFAULT_OUTPUT_CHANGED,\n    PJMEDIA_AUD_DEV_LIST_WILL_REFRESH,\n    PJMEDIA_AUD_DEV_LIST_DID_REFRESH\n} pjmedia_aud_dev_event;\n\n\ntypedef void (*pjmedia_aud_dev_observer_callback)(pjmedia_aud_dev_event event);\n\n/**\n * This structure specifies the parameters to set an audio device observer\n */\ntypedef struct pjmedia_aud_dev_observer {\n    pjmedia_aud_dev_observer_callback cb;\n    pj_pool_t *pool;\n    pj_mutex_t *lock;\n    pj_thread_t *thread;\n    pj_thread_desc thread_desc;\n} pjmedia_aud_dev_observer;\n\n\n/** Forward declaration for pjmedia_aud_stream */\ntypedef struct pjmedia_aud_stream pjmedia_aud_stream;\n\n/** Forward declaration for audio device factory */\ntypedef struct pjmedia_aud_dev_factory pjmedia_aud_dev_factory;\n\n/* typedef for factory creation function */\ntypedef pjmedia_aud_dev_factory*\n(*pjmedia_aud_dev_factory_create_func_ptr)(pj_pool_factory*);\n\n\n/**\n * Get string info for the specified capability.\n *\n * @param cap\t\tThe capability ID.\n * @param p_desc\tOptional pointer which will be filled with longer \n *\t\t\tdescription about the capability.\n *\n * @return\t\tCapability name.\n */\nPJ_DECL(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,\n\t\t\t\t\t      const char **p_desc);\n\n\n/**\n * Set a capability field value in #pjmedia_aud_param structure. This will\n * also set the flags field for the specified capability in the structure.\n *\n * @param param\t\tThe structure.\n * @param cap\t\tThe audio capability which value is to be set.\n * @param pval\t\tPointer to value. Please see the type of value to\n *\t\t\tbe supplied in the pjmedia_aud_dev_cap documentation.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_param_set_cap(pjmedia_aud_param *param,\n\t\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t\t       const void *pval);\n\n\n/**\n * Get a capability field value from #pjmedia_aud_param structure. This\n * function will return PJMEDIA_EAUD_INVCAP error if the flag for that\n * capability is not set in the flags field in the structure.\n *\n * @param param\t\tThe structure.\n * @param cap\t\tThe audio capability which value is to be retrieved.\n * @param pval\t\tPointer to value. Please see the type of value to\n *\t\t\tbe supplied in the pjmedia_aud_dev_cap documentation.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_param_get_cap(const pjmedia_aud_param *param,\n\t\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t\t       void *pval);\n\n/**\n * Initialize the audio subsystem. This will register all supported audio \n * device factories to the audio subsystem. This function may be called\n * more than once, but each call to this function must have the\n * corresponding #pjmedia_aud_subsys_shutdown() call.\n *\n * @param pf\t\tThe pool factory.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_subsys_init(pj_pool_factory *pf);\n\n\n/**\n * Get the pool factory registered to the audio subsystem.\n *\n * @return\t\tThe pool factory.\n */\nPJ_DECL(pj_pool_factory*) pjmedia_aud_subsys_get_pool_factory(void);\n\n\n/**\n * Shutdown the audio subsystem. This will destroy all audio device factories\n * registered in the audio subsystem. Note that currently opened audio streams\n * may or may not be closed, depending on the implementation of the audio\n * device factories.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_subsys_shutdown(void);\n\n\n/**\n * Register a supported audio device factory to the audio subsystem. This\n * function can only be called after calling #pjmedia_aud_subsys_init().\n *\n * @param adf\t\tThe audio device factory.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t)\npjmedia_aud_register_factory(pjmedia_aud_dev_factory_create_func_ptr adf);\n\n\n/**\n * Unregister an audio device factory from the audio subsystem. This\n * function can only be called after calling #pjmedia_aud_subsys_init().\n * Devices from this factory will be unlisted. If a device from this factory\n * is currently in use, then the behavior is undefined.\n *\n * @param adf\t\tThe audio device factory.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t)\npjmedia_aud_unregister_factory(pjmedia_aud_dev_factory_create_func_ptr adf);\n\n\n/**\n * Refresh the list of sound devices installed in the system. This function\n * will only refresh the list of audio device so all active audio streams will\n * be unaffected. After refreshing the device list, application MUST make sure\n * to update all index references to audio devices (i.e. all variables of type\n * pjmedia_aud_dev_index) before calling any function that accepts audio device\n * index as its parameter.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_dev_refresh(void);\n\n\n/**\n * Get the number of sound devices installed in the system.\n *\n * @return\t\tThe number of sound devices installed in the system.\n */\nPJ_DECL(unsigned) pjmedia_aud_dev_count(void);\n\n\n/**\n * Get device information.\n *\n * @param id\t\tThe audio device ID.\n * @param info\t\tThe device information which will be filled in by this\n *\t\t\tfunction once it returns successfully.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_index id,\n\t\t\t\t\t      pjmedia_aud_dev_info *info);\n\n\n/**\n * Lookup device index based on the driver and device name.\n *\n * @param drv_name\tThe driver name.\n * @param dev_name\tThe device name.\n * @param id\t\tPointer to store the returned device ID.\n *\n * @return\t\tPJ_SUCCESS if the device can be found.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_dev_lookup(const char *drv_name,\n\t\t\t\t\t    const char *dev_name,\n\t\t\t\t\t    pjmedia_aud_dev_index *id);\n\n\n/**\n * Initialize the audio device parameters with default values for the\n * specified device.\n *\n * @param id\t\tThe audio device ID.\n * @param param\t\tThe audio device parameters which will be initialized\n *\t\t\tby this function once it returns successfully.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_index id,\n\t\t\t\t\t\t   pjmedia_aud_param *param);\n\n\n/**\n * Open audio stream object using the specified parameters.\n *\n * @param param\t\tSound device parameters to be used for the stream.\n * @param rec_cb\tCallback to be called on every input frame captured.\n * @param play_cb\tCallback to be called everytime the sound device needs\n *\t\t\taudio frames to be played back.\n * @param user_data\tArbitrary user data, which will be given back in the\n *\t\t\tcallbacks.\n * @param p_strm\tPointer to receive the audio stream.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_param *param,\n\t\t\t\t\t       pjmedia_aud_rec_cb rec_cb,\n\t\t\t\t\t       pjmedia_aud_play_cb play_cb,\n\t\t\t\t\t       void *user_data,\n\t\t\t\t\t       pjmedia_aud_stream **p_strm);\n\n/**\n * Get the running parameters for the specified audio stream.\n *\n * @param strm\t\tThe audio stream.\n * @param param\t\tAudio stream parameters to be filled in by this \n *\t\t\tfunction once it returns successfully.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm,\n\t\t\t\t\t\t  pjmedia_aud_param *param);\n\n/**\n * Get the value of a specific capability of the audio stream.\n *\n * @param strm\t\tThe audio stream.\n * @param cap\t\tThe audio capability which value is to be retrieved.\n * @param value\t\tPointer to value to be filled in by this function \n *\t\t\tonce it returns successfully.  Please see the type \n *\t\t\tof value to be supplied in the pjmedia_aud_dev_cap\n *\t\t\tdocumentation.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_stream_get_cap(pjmedia_aud_stream *strm,\n\t\t\t\t\t\tpjmedia_aud_dev_cap cap,\n\t\t\t\t\t\tvoid *value);\n\n/**\n * Set the value of a specific capability of the audio stream.\n *\n * @param strm\t\tThe audio stream.\n * @param cap\t\tThe audio capability which value is to be set.\n * @param value\t\tPointer to value. Please see the type of value to\n *\t\t\tbe supplied in the pjmedia_aud_dev_cap documentation.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_stream_set_cap(pjmedia_aud_stream *strm,\n\t\t\t\t\t\tpjmedia_aud_dev_cap cap,\n\t\t\t\t\t\tconst void *value);\n\n/**\n * Start the stream.\n *\n * @param strm\t\tThe audio stream.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_stream_start(pjmedia_aud_stream *strm);\n\n/**\n * Stop the stream.\n *\n * @param strm\t\tThe audio stream.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_stream_stop(pjmedia_aud_stream *strm);\n\n/**\n * Destroy the stream.\n *\n * @param strm\t\tThe audio stream.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_stream_destroy(pjmedia_aud_stream *strm);\n\n/**\n * Set an audio device observer callback.\n *\n * @param cb\t\tThe callback that needs to be registred, or NULL in\n *                      in case it needs to be unregistered. Only one callback\n *                      can be registered.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_aud_dev_set_observer_cb(pjmedia_aud_dev_observer_callback cb);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_AUDIODEV_AUDIODEV_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-audiodev/audiodev_imp.h",
    "content": "/* $Id: audiodev_imp.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __AUDIODEV_IMP_H__\n#define __AUDIODEV_IMP_H__\n\n#include <pjmedia-audiodev/audiodev.h>\n\n/**\n * @defgroup s8_audio_device_implementors_api Audio Device Implementors API\n * @ingroup audio_device_api\n * @brief API for audio device implementors\n * @{\n */\n\ntypedef enum pjmedia_aud_dev_change_event {\n    DEFAULT_INPUT_CHANGED = 1,\n    DEFAULT_OUTPUT_CHANGED,\n    DEVICE_LIST_CHANGED\n} pjmedia_aud_dev_change_event;\n\ntypedef void (*pjmedia_aud_dev_change_callback)(pjmedia_aud_dev_change_event event);\n\n/**\n * Sound device factory operations.\n */\ntypedef struct pjmedia_aud_dev_factory_op\n{\n    /**\n     * Initialize the audio device factory.\n     *\n     * @param f\t\tThe audio device factory.\n     */\n    pj_status_t (*init)(pjmedia_aud_dev_factory *f);\n\n    /**\n     * Close this audio device factory and release all resources back to the\n     * operating system.\n     *\n     * @param f\t\tThe audio device factory.\n     */\n    pj_status_t (*destroy)(pjmedia_aud_dev_factory *f);\n\n    /**\n     * Get the number of audio devices installed in the system.\n     *\n     * @param f\t\tThe audio device factory.\n     */\n    unsigned (*get_dev_count)(pjmedia_aud_dev_factory *f);\n\n    /**\n     * Get the audio device information and capabilities.\n     *\n     * @param f\t\tThe audio device factory.\n     * @param index\tDevice index.\n     * @param info\tThe audio device information structure which will be\n     *\t\t\tinitialized by this function once it returns \n     *\t\t\tsuccessfully.\n     */\n    pj_status_t\t(*get_dev_info)(pjmedia_aud_dev_factory *f, \n\t\t\t\tunsigned index,\n\t\t\t\tpjmedia_aud_dev_info *info);\n\n    /**\n     * Initialize the specified audio device parameter with the default\n     * values for the specified device.\n     *\n     * @param f\t\tThe audio device factory.\n     * @param index\tDevice index.\n     * @param param\tThe audio device parameter.\n     */\n    pj_status_t (*default_param)(pjmedia_aud_dev_factory *f,\n\t\t\t\t unsigned index,\n\t\t\t\t pjmedia_aud_param *param);\n\n    /**\n     * Open the audio device and create audio stream. See\n     * #pjmedia_aud_stream_create()\n     */\n    pj_status_t (*create_stream)(pjmedia_aud_dev_factory *f,\n\t\t\t\t const pjmedia_aud_param *param,\n\t\t\t\t pjmedia_aud_rec_cb rec_cb,\n\t\t\t\t pjmedia_aud_play_cb play_cb,\n\t\t\t\t void *user_data,\n\t\t\t\t pjmedia_aud_stream **p_aud_strm);\n\n    /**\n     * Refresh the list of audio devices installed in the system.\n     *\n     * @param f\t\tThe audio device factory.\n     */\n    pj_status_t (*refresh)(pjmedia_aud_dev_factory *f);\n\n    /**\n     * Set audio device change callback\n     *\n     * @param f\t\tThe audio device factory.\n     * @param cb\tThe audio device change callback.\n     */\n    void (*set_dev_change_cb)(pjmedia_aud_dev_factory *f,\n                              pjmedia_aud_dev_change_callback cb);\n\n    /**\n     * Get default recording device index\n     *\n     * @param f\t\tThe audio device factory.\n     */\n    int (*get_default_rec_dev)(pjmedia_aud_dev_factory *f);\n\n    /**\n     * Get default playback device index\n     *\n     * @param f\t\tThe audio device factory.\n     */\n    int (*get_default_play_dev)(pjmedia_aud_dev_factory *f);\n\n} pjmedia_aud_dev_factory_op;\n\n\n/**\n * This structure describes an audio device factory. \n */\nstruct pjmedia_aud_dev_factory\n{\n    /** Internal data to be initialized by audio subsystem. */\n    struct {\n\t/** Driver index */\n\tunsigned drv_idx;\n    } sys;\n\n    /** Operations */\n    pjmedia_aud_dev_factory_op *op;\n};\n\n\n/**\n * Sound stream operations.\n */\ntypedef struct pjmedia_aud_stream_op\n{\n    /**\n     * See #pjmedia_aud_stream_get_param()\n     */\n    pj_status_t (*get_param)(pjmedia_aud_stream *strm,\n\t\t\t     pjmedia_aud_param *param);\n\n    /**\n     * See #pjmedia_aud_stream_get_cap()\n     */\n    pj_status_t (*get_cap)(pjmedia_aud_stream *strm,\n\t\t\t   pjmedia_aud_dev_cap cap,\n\t\t\t   void *value);\n\n    /**\n     * See #pjmedia_aud_stream_set_cap()\n     */\n    pj_status_t (*set_cap)(pjmedia_aud_stream *strm,\n\t\t\t   pjmedia_aud_dev_cap cap,\n\t\t\t   const void *value);\n\n    /**\n     * See #pjmedia_aud_stream_start()\n     */\n    pj_status_t (*start)(pjmedia_aud_stream *strm);\n\n    /**\n     * See #pjmedia_aud_stream_stop().\n     */\n    pj_status_t (*stop)(pjmedia_aud_stream *strm);\n\n    /**\n     * See #pjmedia_aud_stream_destroy().\n     */\n    pj_status_t (*destroy)(pjmedia_aud_stream *strm);\n\n} pjmedia_aud_stream_op;\n\n\n/**\n * This structure describes the audio device stream.\n */\nstruct pjmedia_aud_stream\n{\n    /** Internal data to be initialized by audio subsystem */\n    struct {\n\t/** Driver index */\n\tunsigned drv_idx;\n    } sys;\n\n    /** Operations */\n    pjmedia_aud_stream_op *op;\n};\n\n\n\n\n/**\n * @}\n */\n\n\n\n#endif /* __AUDIODEV_IMP_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-audiodev/config.h",
    "content": "/* $Id: config.h 4435 2013-03-11 06:32:58Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_AUDIODEV_CONFIG_H__\n#define __PJMEDIA_AUDIODEV_CONFIG_H__\n\n/**\n * @file config.h\n * @brief Audio config.\n */\n#include <pjmedia/types.h>\n#include <pj/pool.h>\n\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup audio_device_api Audio Device API\n * @brief PJMEDIA audio device abstraction API.\n */\n\n/**\n * @defgroup s1_audio_device_config Compile time configurations\n * @ingroup audio_device_api\n * @brief Compile time configurations\n * @{\n */\n\n/**\n * This setting controls whether native ALSA support should be included.\n */\n#ifndef PJMEDIA_AUDIO_DEV_HAS_ALSA\n#   define PJMEDIA_AUDIO_DEV_HAS_ALSA\t\t0\n#endif\n\n\n/**\n * This setting controls whether null audio support should be included.\n */\n#ifndef PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO\n#   define PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO\t0\n#endif\n\n\n/**\n * This setting controls whether coreaudio support should be included.\n */\n#ifndef PJMEDIA_AUDIO_DEV_HAS_COREAUDIO\n#   define PJMEDIA_AUDIO_DEV_HAS_COREAUDIO\t0\n#endif\n\n\n/**\n * This setting controls whether WMME support should be included.\n */\n#ifndef PJMEDIA_AUDIO_DEV_HAS_WMME\n#   define PJMEDIA_AUDIO_DEV_HAS_WMME\t\t0\n#endif\n\n\n/**\n * This setting controls the buffer length of audio device name.\n *\n * Default: 128 for Windows platforms, 64 for others\n */\n#ifndef PJMEDIA_AUD_DEV_INFO_NAME_LEN\n#   if (defined(PJ_WIN32) && PJ_WIN32!=0) || \\\n       (defined(PJ_WIN64) && PJ_WIN64!=0)\n#\tdefine PJMEDIA_AUD_DEV_INFO_NAME_LEN 128\n#   else\n#\tdefine PJMEDIA_AUD_DEV_INFO_NAME_LEN 64\n#   endif\n#endif\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_AUDIODEV_CONFIG_H__ */\n\n/*\n --------------------- DOCUMENTATION FOLLOWS ---------------------------\n */\n\n/**\n * @addtogroup audio_device_api Audio Device API\n * @{\n\nPJMEDIA Audio Device API is a cross-platform audio API appropriate for use with\nVoIP applications and many other types of audio streaming applications. \n\nThe API abstracts many different audio API's on various platforms, such as:\n - PortAudio back-end for Win32, Windows Mobile, Linux, Unix, dan MacOS X.\n - native WMME audio for Win32 and Windows Mobile devices\n - native Symbian audio streaming/multimedia framework (MMF) implementation\n - native Nokia Audio Proxy Server (APS) implementation\n - null-audio implementation\n - and more to be implemented in the future\n\nThe Audio Device API/library is an evolution from PJMEDIA @ref PJMED_SND and \ncontains many enhancements:\n\n - Forward compatibility:\n\\n\n   The new API has been designed to be extensible, it will support new API's as \n   well as new features that may be introduced in the future without breaking \n   compatibility with applications that use this API as well as compatibility \n   with existing device implementations. \n\n - Device capabilities:\n\\n\n   At the heart of the API is device capabilities management, where all possible\n   audio capabilities of audio devices should be able to be handled in a generic\n   manner. With this framework, new capabilities that may be discovered in the \n   future can be handled in manner without breaking existing applications. \n\n - Built-in features:\n\\n\n   The device capabilities framework enables applications to use and control \n   audio features built-in in the device, such as:\n    - echo cancellation, \n    - built-in codecs, \n    - audio routing (e.g. to earpiece or loudspeaker),\n    - volume control,\n    - etc.\n\n - Codec support:\n\\n\n   Some audio devices such as Nokia/Symbian Audio Proxy Server (APS) and Nokia \n   VoIP Audio Services (VAS) support built-in hardware audio codecs (e.g. G.729,\n   iLBC, and AMR), and application can use the sound device in encoded mode to\n   make use of these hardware codecs. \n\n - Multiple backends:\n\\n\n   The new API supports multiple audio backends (called factories or drivers in \n   the code) to be active simultaneously, and audio backends may be added or \n   removed during run-time. \n\n\n@section using Overview on using the API\n\n@subsection getting_started Getting started\n\n -# <b>Configure the application's project settings</b>.\\n\n    Add the following \n    include:\n    \\code\n    #include <pjmedia_audiodev.h>\\endcode\\n\n    And add <b>pjmedia-audiodev</b> library to your application link \n    specifications.\\n\n -# <b>Compile time settings</b>.\\n\n    Use the compile time settings to enable or\n    disable specific audio drivers. For more information, please see\n    \\ref s1_audio_device_config.\n -# <b>API initialization and cleaning up</b>.\\n\n    Before anything else, application must initialize the API by calling:\n    \\code\n    pjmedia_aud_subsys_init(pf);\\endcode\\n\n    And add this in the application cleanup sequence\n    \\code\n    pjmedia_aud_subsys_shutdown();\\endcode\n\n@subsection devices Working with devices\n\n -# The following code prints the list of audio devices detected\n    in the system.\n    \\code\n    int dev_count;\n    pjmedia_aud_dev_index dev_idx;\n    pj_status_t status;\n\n    dev_count = pjmedia_aud_dev_count();\n    printf(\"Got %d audio devices\\n\", dev_count);\n\n    for (dev_idx=0; dev_idx<dev_count; ++i) {\n\tpjmedia_aud_dev_info info;\n\n\tstatus = pjmedia_aud_dev_get_info(dev_idx, &info);\n\tprintf(\"%d. %s (in=%d, out=%d)\\n\",\n\t       dev_idx, info.name, \n\t       info.input_count, info.output_count);\n    }\n    \\endcode\\n\n -# Info: The #PJMEDIA_AUD_DEFAULT_CAPTURE_DEV and #PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV\n    constants are used to denote default capture and playback devices\n    respectively.\n -# Info: You may save the device and driver's name in your application\n    setting, for example to specify the prefered devices to be\n    used by your application. You can then retrieve the device index\n    for the device by calling:\n    \\code\n\tconst char *drv_name = \"WMME\";\n\tconst char *dev_name = \"Wave mapper\";\n\tpjmedia_aud_dev_index dev_idx;\n\n        status = pjmedia_aud_dev_lookup(drv_name, dev_name, &dev_idx);\n\tif (status==PJ_SUCCESS)\n\t    printf(\"Device index is %d\\n\", dev_idx);\n    \\endcode\n\n@subsection caps Device capabilities\n\nCapabilities are encoded as #pjmedia_aud_dev_cap enumeration. Please see\n#pjmedia_aud_dev_cap enumeration for more information.\n\n -# The following snippet prints the capabilities supported by the device:\n    \\code\n    pjmedia_aud_dev_info info;\n    pj_status_t status;\n\n    status = pjmedia_aud_dev_get_info(PJMEDIA_AUD_DEFAULT_CAPTURE_DEV, &info);\n    if (status == PJ_SUCCESS) {\n\tunsigned i;\n\t// Enumerate capability bits\n\tprintf(\"Device capabilities: \");\n\tfor (i=0; i<32; ++i) {\n\t    if (info.caps & (1 << i))\n\t\tprintf(\"%s \", pjmedia_aud_dev_cap_name(1 << i, NULL));\n\t}\n    }\n    \\endcode\\n\n -# Info: You can set the device settings when opening audio stream by setting\n    the flags and the appropriate setting in #pjmedia_aud_param when calling\n    #pjmedia_aud_stream_create()\\n\n -# Info: Once the audio stream is running, you can retrieve or change the stream \n    setting by specifying the capability in #pjmedia_aud_stream_get_cap()\n    and #pjmedia_aud_stream_set_cap() respectively.\n\n\n@subsection creating_stream Creating audio streams\n\nThe audio stream enables audio streaming to capture device, playback device,\nor both.\n\n -# It is recommended to initialize the #pjmedia_aud_param with its default\n    values before using it:\n    \\code\n    pjmedia_aud_param param;\n    pjmedia_aud_dev_index dev_idx;\n    pj_status_t status;\n\n    dev_idx = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;\n    status = pjmedia_aud_dev_default_param(dev_idx, &param);\n    \\endcode\\n\n -# Configure the mandatory parameters:\n    \\code\n    param.dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;\n    param.rec_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;\n    param.play_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;\n    param.clock_rate = 8000;\n    param.channel_count = 1;\n    param.samples_per_frame = 160;\n    param.bits_per_sample = 16;\n    \\endcode\\n\n -# If you want the audio stream to use the device's built-in codec, specify\n    the codec in the #pjmedia_aud_param. You must make sure that the codec\n    is supported by the device, by looking at its supported format list in\n    the #pjmedia_aud_dev_info.\\n\n    The snippet below sets the audio stream to use G.711 ULAW encoding:\n    \\code\n    unsigned i;\n\n    // Make sure Ulaw is supported\n    if ((info.caps & PJMEDIA_AUD_DEV_CAP_EXT_FORMAT) == 0)\n\terror(\"Device does not support extended formats\");\n    for (i = 0; i < info.ext_fmt_cnt; ++i) {\n\tif (info.ext_fmt[i].id == PJMEDIA_FORMAT_ULAW)\n\t    break;\n    }\n    if (i == info.ext_fmt_cnt)\n\terror(\"Device does not support Ulaw format\");\n\n    // Set Ulaw format\n    param.flags |= PJMEDIA_AUD_DEV_CAP_EXT_FORMAT;\n    param.ext_fmt.id = PJMEDIA_FORMAT_ULAW;\n    param.ext_fmt.bitrate = 64000;\n    param.ext_fmt.vad = PJ_FALSE;\n    \\endcode\\n\n -# Note that if non-PCM format is configured on the audio stream, the\n    capture and/or playback functions (#pjmedia_aud_rec_cb and \n    #pjmedia_aud_play_cb respectively) will report the audio frame as\n    #pjmedia_frame_ext structure instead of the #pjmedia_frame.\n -# Optionally configure other device's capabilities. The following snippet\n    shows how to enable echo cancellation on the device (note that this\n    snippet may not be necessary since the setting may have been enabled \n    when calling #pjmedia_aud_dev_default_param() above):\n    \\code\n    if (info.caps & PJMEDIA_AUD_DEV_CAP_EC) {\n\tparam.flags |= PJMEDIA_AUD_DEV_CAP_EC;\n\tparam.ec_enabled = PJ_TRUE;\n    }\n    \\endcode\n -# Open the audio stream, specifying the capture and/or playback callback\n    functions:\n    \\code\n       pjmedia_aud_stream *stream;\n\n       status = pjmedia_aud_stream_create(&param, &rec_cb, &play_cb, \n                                          user_data, &stream);\n    \\endcode\n\n@subsection working_with_stream Working with audio streams\n\n -# To start the audio stream:\n    \\code\n\tstatus = pjmedia_aud_stream_start(stream);\n    \\endcode\\n\n    To stop the stream:\n    \\code\n\tstatus = pjmedia_aud_stream_stop(stream);\n    \\endcode\\n\n    And to destroy the stream:\n    \\code\n\tstatus = pjmedia_aud_stream_destroy(stream);\n    \\endcode\\n\n -# Info: The following shows how to retrieve the capability value of the\n    stream (in this case, the current output volume setting).\n    \\code\n    // Volume setting is an unsigned integer showing the level in percent.\n    unsigned vol;\n    status = pjmedia_aud_stream_get_cap(stream, \n\t\t\t\t\tPJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,\n\t\t\t\t\t&vol);\n    \\endcode\n -# Info: And following shows how to modify the capability value of the\n    stream (in this case, the current output volume setting).\n    \\code\n    // Volume setting is an unsigned integer showing the level in percent.\n    unsigned vol = 50;\n    status = pjmedia_aud_stream_set_cap(stream, \n\t\t\t\t\tPJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,\n\t\t\t\t\t&vol);\n    \\endcode\n\n\n*/\n\n\n/**\n * @}\n */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-audiodev/errno.h",
    "content": "/* $Id: errno.h 4432 2013-03-08 08:02:48Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_AUDIODEV_AUDIODEV_ERRNO_H__\n#define __PJMEDIA_AUDIODEV_AUDIODEV_ERRNO_H__\n\n/**\n * @file errno.h Error Codes\n * @brief Audiodev specific error codes.\n */\n\n#include <pjmedia-audiodev/config.h>\n#include <pj/errno.h>\n\n/**\n * @defgroup error_codes Error Codes\n * @ingroup audio_device_api\n * @brief Audio devive library specific error codes.\n * @{\n */\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * Start of error code relative to PJ_ERRNO_START_USER.\n * This value is 420000.\n */\n#define PJMEDIA_AUDIODEV_ERRNO_START \\\n\t    (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*5)\n#define PJMEDIA_AUDIODEV_ERRNO_END   \\\n\t    (PJMEDIA_AUDIODEV_ERRNO_START + PJ_ERRNO_SPACE_SIZE - 1)\n\n\n/**\n * Mapping from Windows multimedia WaveIn error codes.\n */\n#define PJMEDIA_AUDIODEV_WMME_IN_ERROR_START\t\\\n\t    (PJMEDIA_AUDIODEV_ERRNO_START + 30000)\n#define PJMEDIA_AUDIODEV_WMME_IN_ERROR_END\t\\\n\t    (PJMEDIA_AUDIODEV_WMME_IN_ERROR_START + 1000 - 1)\n/**\n * Convert WaveIn operation error codes to PJLIB error space.\n */\n#define PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_IN(err) \\\n\t    ((int)PJMEDIA_AUDIODEV_WMME_IN_ERROR_START+err)\n\n\n/**\n * Mapping from Windows multimedia WaveOut error codes.\n */\n#define PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START\t\\\n\t    (PJMEDIA_AUDIODEV_WMME_IN_ERROR_END + 1000)\n#define PJMEDIA_AUDIODEV_WMME_OUT_ERROR_END\t\\\n\t    (PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START + 1000)\n/**\n * Convert WaveOut operation error codes to PJLIB error space.\n */\n#define PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(err) \\\n\t    ((int)PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START+err)\n\n\n/**\n * Mapping from CoreAudio error codes to pjmedia error space.\n */\n#define PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_START \\\n\t    (PJMEDIA_AUDIODEV_ERRNO_START+20000)\n#define PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_END   \\\n\t    (PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_START + 20000 -1)\n/**\n * Convert CoreAudio error code to PJLIB error code.\n * CoreAudio error code range: 0 >= err >= -10000\n */\n#define PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(err) \\\n\t    ((int)PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_START-err)\n\n/**\n * Mapping from BDIMAD error codes to pjmedia error space.\n */\n#define PJMEDIA_AUDIODEV_BDIMAD_ERROR_START\t\\\n\t    (PJMEDIA_AUDIODEV_ERRNO_START + 40000)\n#define PJMEDIA_AUDIODEV_BDIMAD_ERROR_END\t\\\n\t    (PJMEDIA_AUDIODEV_BDIMAD_ERROR_START + 2000 - 1)\n/**\n * Convert BDIMAD error codes to PJLIB error space.\n */\n#define PJMEDIA_AUDIODEV_ERRNO_FROM_BDIMAD(err) \\\n\t    ((int)PJMEDIA_AUDIODEV_BDIMAD_ERROR_START+err)\n\n/************************************************************\n * Audio Device API error codes\n ***********************************************************/\n/**\n * @hideinitializer\n * General/unknown error.\n */\n#define PJMEDIA_EAUD_ERR\t(PJMEDIA_AUDIODEV_ERRNO_START+1) /* 420001 */\n\n/**\n * @hideinitializer\n * Unknown error from audio driver\n */\n#define PJMEDIA_EAUD_SYSERR\t(PJMEDIA_AUDIODEV_ERRNO_START+2) /* 420002 */\n\n/**\n * @hideinitializer\n * Audio subsystem not initialized\n */\n#define PJMEDIA_EAUD_INIT\t(PJMEDIA_AUDIODEV_ERRNO_START+3) /* 420003 */\n\n/**\n * @hideinitializer\n * Invalid audio device\n */\n#define PJMEDIA_EAUD_INVDEV\t(PJMEDIA_AUDIODEV_ERRNO_START+4) /* 420004 */\n\n/**\n * @hideinitializer\n * Found no devices\n */\n#define PJMEDIA_EAUD_NODEV\t(PJMEDIA_AUDIODEV_ERRNO_START+5) /* 420005 */\n\n/**\n * @hideinitializer\n * Unable to find default device\n */\n#define PJMEDIA_EAUD_NODEFDEV\t(PJMEDIA_AUDIODEV_ERRNO_START+6) /* 420006 */\n\n/**\n * @hideinitializer\n * Device not ready\n */\n#define PJMEDIA_EAUD_NOTREADY\t(PJMEDIA_AUDIODEV_ERRNO_START+7) /* 420007 */\n\n/**\n * @hideinitializer\n * The audio capability is invalid or not supported\n */\n#define PJMEDIA_EAUD_INVCAP\t(PJMEDIA_AUDIODEV_ERRNO_START+8) /* 420008 */\n\n/**\n * @hideinitializer\n * The operation is invalid or not supported\n */\n#define PJMEDIA_EAUD_INVOP\t(PJMEDIA_AUDIODEV_ERRNO_START+9) /* 420009 */\n\n/**\n * @hideinitializer\n * Bad or invalid audio device format\n */\n#define PJMEDIA_EAUD_BADFORMAT\t(PJMEDIA_AUDIODEV_ERRNO_START+10) /* 4200010 */\n\n/**\n * @hideinitializer\n * Invalid audio device sample format\n */\n#define PJMEDIA_EAUD_SAMPFORMAT\t(PJMEDIA_AUDIODEV_ERRNO_START+11) /* 4200011 */\n\n/**\n * @hideinitializer\n * Bad latency setting\n */\n#define PJMEDIA_EAUD_BADLATENCY\t(PJMEDIA_AUDIODEV_ERRNO_START+12) /* 4200012 */\n\n\n\n\n\n/**\n * Get error message for the specified error code. Note that this\n * function is only able to decode PJMEDIA Audiodev specific error code.\n * Application should use pj_strerror(), which should be able to\n * decode all error codes belonging to all subsystems (e.g. pjlib,\n * pjmedia, pjsip, etc).\n *\n * @param status    The error code.\n * @param buffer    The buffer where to put the error message.\n * @param bufsize   Size of the buffer.\n *\n * @return\t    The error message as NULL terminated string,\n *                  wrapped with pj_str_t.\n */\nPJ_DECL(pj_str_t) pjmedia_audiodev_strerror(pj_status_t status, char *buffer,\n\t\t\t\t\t    pj_size_t bufsize);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_AUDIODEV_AUDIODEV_ERRNO_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/audio_codecs.h",
    "content": "/* $Id: audio_codecs.h 3666 2011-07-19 08:40:20Z nanang $ */\n/* \n * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODEC_ALL_CODECS_H__\n#define __PJMEDIA_CODEC_ALL_CODECS_H__\n\n/**\n * @file pjmedia-codec/all_codecs.h\n * @brief Helper function to register all codecs\n */\n#include <pjmedia/endpoint.h>\n#include <pjmedia-codec/passthrough.h>\n\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJMEDIA_CODEC_REGISTER_ALL Codec registration helper\n * @ingroup PJMEDIA_CODEC_CODECS\n * @brief Helper function to register all codecs\n * @{\n *\n * Helper function to register all codecs that are implemented in\n * PJMEDIA-CODEC library.\n */\n\n/**\n * Codec configuration. Call #pjmedia_audio_codec_config_default() to initialize\n * this structure with the default values.\n */\ntypedef struct pjmedia_audio_codec_config\n{\n    /** Speex codec settings. See #pjmedia_codec_speex_init() for more info */\n    struct {\n\tunsigned\toption;\t\t/**< Bitmask of options.\t*/\n\tint\t\tquality;\t/**< Codec quality.\t\t*/\n\tint\t\tcomplexity;\t/**< Codec complexity.\t\t*/\n    } speex;\n\n    /** iLBC settings */\n    struct {\n\tunsigned\tmode;\t\t/**< iLBC mode.\t\t\t*/\n    } ilbc;\n\n    /** Passthrough */\n    struct {\n\tpjmedia_codec_passthrough_setting setting; /**< Passthrough\t*/\n    } passthrough;\n\n} pjmedia_audio_codec_config;\n\n\n/**\n * Initialize pjmedia_audio_codec_config structure with default values.\n *\n * @param cfg\t\tThe codec config to be initialized.\n */\nPJ_DECL(void)\npjmedia_audio_codec_config_default(pjmedia_audio_codec_config *cfg);\n\n/**\n * Register all known audio codecs implemented in PJMEDA-CODEC library to the\n * specified media endpoint.\n *\n * @param endpt\t\tThe media endpoint.\n * @param c\t\tOptional codec configuration, or NULL to use default\n * \t\t\tvalues.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t)\npjmedia_codec_register_audio_codecs(pjmedia_endpt *endpt,\n                                    const pjmedia_audio_codec_config *c);\n\n\n/**\n * @}  PJMEDIA_CODEC_REGISTER_ALL\n */\n\n\nPJ_END_DECL\n\n#endif\t/* __PJMEDIA_CODEC_ALL_CODECS_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/config.h",
    "content": "/* $Id: config.h 4331 2013-01-23 06:18:18Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODEC_CONFIG_H__\n#define __PJMEDIA_CODEC_CONFIG_H__\n\n/**\n * @file config.h\n * @brief PJMEDIA-CODEC compile time settings\n */\n\n/**\n * @defgroup pjmedia_codec_config PJMEDIA-CODEC Compile Time Settings\n * @ingroup PJMEDIA_CODEC\n * @brief Various compile time settings such as to enable/disable codecs\n * @{\n */\n\n#include <pjmedia/types.h>\n\n/*\n * Include config_auto.h if autoconf is used (PJ_AUTOCONF is set)\n */\n#if defined(PJ_AUTOCONF)\n#   include <pjmedia-codec/config_auto.h>\n#endif\n\n\n/**\n * Unless specified otherwise, L16 codec is included by default.\n */\n#ifndef PJMEDIA_HAS_L16_CODEC\n#   define PJMEDIA_HAS_L16_CODEC    1\n#endif\n\n\n/**\n * Unless specified otherwise, GSM codec is included by default.\n */\n#ifndef PJMEDIA_HAS_GSM_CODEC\n#   define PJMEDIA_HAS_GSM_CODEC    1\n#endif\n\n\n/**\n * Unless specified otherwise, Speex codec is included by default.\n */\n#ifndef PJMEDIA_HAS_SPEEX_CODEC\n#   define PJMEDIA_HAS_SPEEX_CODEC    1\n#endif\n\n/**\n * Speex codec default complexity setting.\n */\n#ifndef PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY\n#   define PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY   2\n#endif\n\n/**\n * Speex codec default quality setting. Please note that pjsua-lib may override\n * this setting via its codec quality setting (i.e PJSUA_DEFAULT_CODEC_QUALITY).\n */\n#ifndef PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY\n#   define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY\t    8\n#endif\n\n\n/**\n * Unless specified otherwise, iLBC codec is included by default.\n */\n#ifndef PJMEDIA_HAS_ILBC_CODEC\n#   define PJMEDIA_HAS_ILBC_CODEC    1\n#endif\n\n\n/**\n * Unless specified otherwise, G.722 codec is included by default.\n */\n#ifndef PJMEDIA_HAS_G722_CODEC\n#   define PJMEDIA_HAS_G722_CODEC    1\n#endif\n\n\n/**\n * Default G.722 codec encoder and decoder level adjustment. The G.722\n * specifies that it uses 14 bit PCM for input and output, while PJMEDIA\n * normally uses 16 bit PCM, so the conversion is done by applying\n * level adjustment. If the value is non-zero, then PCM input samples to\n * the encoder will be shifted right by this value, and similarly PCM\n * output samples from the decoder will be shifted left by this value.\n *\n * This can be changed at run-time after initialization by calling\n * #pjmedia_codec_g722_set_pcm_shift().\n *\n * Default: 2.\n */\n#ifndef PJMEDIA_G722_DEFAULT_PCM_SHIFT\n#   define PJMEDIA_G722_DEFAULT_PCM_SHIFT\t    2\n#endif\n\n\n/**\n * Specifies whether G.722 PCM shifting should be stopped when clipping\n * detected in the decoder. Enabling this feature can be useful when\n * talking to G.722 implementation that uses 16 bit PCM for G.722 input/\n * output (for any reason it seems to work) and the PCM shifting causes\n * audio clipping.\n *\n * See also #PJMEDIA_G722_DEFAULT_PCM_SHIFT.\n *\n * Default: enabled.\n */\n#ifndef PJMEDIA_G722_STOP_PCM_SHIFT_ON_CLIPPING\n#   define PJMEDIA_G722_STOP_PCM_SHIFT_ON_CLIPPING  1\n#endif\n\n\n/**\n * Unless specified otherwise, opus codec is included by default.\n */\n#ifndef PJMEDIA_HAS_OPUS_CODEC\n#   define PJMEDIA_HAS_OPUS_CODEC    1\n#endif\n\n\n/**\n * Enable Passthrough codecs.\n *\n * Default: 0\n */\n#ifndef PJMEDIA_HAS_PASSTHROUGH_CODECS\n#   define PJMEDIA_HAS_PASSTHROUGH_CODECS\t0\n#endif\n\n/**\n * G.722.1 codec is disabled by default.\n */\n#ifndef PJMEDIA_HAS_G7221_CODEC\n#   define PJMEDIA_HAS_G7221_CODEC\t\t0\n#endif\n\n/**\n * Default G.722.1 codec encoder and decoder level adjustment. \n * If the value is non-zero, then PCM input samples to the encoder will \n * be shifted right by this value, and similarly PCM output samples from\n * the decoder will be shifted left by this value.\n *\n * This can be changed at run-time after initialization by calling\n * #pjmedia_codec_g7221_set_pcm_shift().\n */\n#ifndef PJMEDIA_G7221_DEFAULT_PCM_SHIFT\n#   define PJMEDIA_G7221_DEFAULT_PCM_SHIFT\t1\n#endif\n\n\n/**\n * Enabling both G.722.1 codec implementations, internal PJMEDIA and IPP,\n * may cause problem in SDP, i.e: payload types duplications. So, let's \n * just trap such case here at compile time.\n *\n * Application can control which implementation to be used by manipulating\n * PJMEDIA_HAS_G7221_CODEC and PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1 in\n * config_site.h.\n */\n#if (PJMEDIA_HAS_G7221_CODEC != 0) && (PJMEDIA_HAS_INTEL_IPP != 0) && \\\n    (PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1 != 0)\n#   error Only one G.722.1 implementation can be enabled at the same time. \\\n\t  Please use PJMEDIA_HAS_G7221_CODEC and \\\n\t  PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1 in your config_site.h \\\n\t  to control which implementation to be used.\n#endif\n\n\n/**\n * Specify if FFMPEG codecs are available.\n *\n * Default: PJMEDIA_HAS_LIBAVCODEC\n */\n#ifndef PJMEDIA_HAS_FFMPEG_CODEC\n#   define PJMEDIA_HAS_FFMPEG_CODEC\t\tPJMEDIA_HAS_LIBAVCODEC\n#endif\n\n\n/**\n * Specify if FFMPEG video codecs are available.\n *\n * Default: PJMEDIA_HAS_FFMPEG_CODEC\n */\n#ifndef PJMEDIA_HAS_FFMPEG_VID_CODEC\n#   define PJMEDIA_HAS_FFMPEG_VID_CODEC\t\tPJMEDIA_HAS_FFMPEG_CODEC\n#endif\n\n/**\n * Enable FFMPEG H263+/H263-1998 codec.\n *\n * Default: 1\n */\n#ifndef PJMEDIA_HAS_FFMPEG_CODEC_H263P\n#   define PJMEDIA_HAS_FFMPEG_CODEC_H263P\tPJMEDIA_HAS_FFMPEG_VID_CODEC\n#endif\n\n/**\n * Enable FFMPEG H264 codec (requires libx264).\n *\n * Default: 0\n */\n#ifndef PJMEDIA_HAS_FFMPEG_CODEC_H264\n#   define PJMEDIA_HAS_FFMPEG_CODEC_H264\tPJMEDIA_HAS_FFMPEG_VID_CODEC\n#endif\n\n/**\n * Compile VPX support, unless explicitly disabled\n */\n#ifndef PJMEDIA_HAS_VPX_CODEC\n#   define PJMEDIA_HAS_VPX_CODEC                PJMEDIA_HAS_LIBVPX\n#endif\n\n\n/**\n * @}\n */\n\n\n\n#endif\t/* __PJMEDIA_CODEC_CONFIG_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/config_auto.h.in",
    "content": "/* $Id: config_auto.h.in 4331 2013-01-23 06:18:18Z ming $ */\n/*\n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef __PJMEDIA_CODEC_CONFIG_AUTO_H_\n#define __PJMEDIA_CODEC_CONFIG_AUTO_H_\n\n/**\n * @file config_auto.h\n * @brief PJMEDIA-CODEC configuration as set by autoconf script\n */\n\n/*\n * Note:\n *\tThe configuration in config_site.h overrides any other settings,\n *\tincluding the setting as detected by autoconf. \n */\n \n\n/* GSM codec */\n#ifndef PJMEDIA_HAS_GSM_CODEC\n#undef PJMEDIA_HAS_GSM_CODEC\n#endif\n\n/* Speex codec */\n#ifndef PJMEDIA_HAS_SPEEX_CODEC\n#undef PJMEDIA_HAS_SPEEX_CODEC\n#endif\n\n/* iLBC codec */\n#ifndef PJMEDIA_HAS_ILBC_CODEC\n#undef PJMEDIA_HAS_ILBC_CODEC\n#endif\n\n\n/* G722 codec */\n#ifndef PJMEDIA_HAS_G722_CODEC\n#undef PJMEDIA_HAS_G722_CODEC\n#endif\n\n/* G7221 codec */\n#ifndef PJMEDIA_HAS_G7221_CODEC\n#undef PJMEDIA_HAS_G7221_CODEC\n#endif\n\n#endif\t/* __PJMEDIA_CODEC_CONFIG_AUTO_H_ */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/ffmpeg_vid_codecs.h",
    "content": "/* $Id: ffmpeg_vid_codecs.h 4049 2012-04-13 06:24:23Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODECS_FFMPEG_VID_H__\n#define __PJMEDIA_CODECS_FFMPEG_VID_H__\n\n\n#include <pjmedia-codec/types.h>\n#include <pjmedia/vid_codec.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJMEDIA_CODEC_VID_FFMPEG FFmpeg Codecs\n * @ingroup PJMEDIA_CODEC_VID_CODECS\n * @{\n */\n\n/**\n * Initialize and register FFMPEG video codecs factory to pjmedia endpoint.\n *\n * @param mgr\t    The video codec manager instance where this codec will\n * \t\t    be registered to. Specify NULL to use default instance\n * \t\t    (in that case, an instance of video codec manager must\n * \t\t    have been created beforehand).\n * @param pf\t    Pool factory.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_ffmpeg_vid_init(pjmedia_vid_codec_mgr *mgr,\n                                                   pj_pool_factory *pf);\n\n\n/**\n * Unregister FFMPEG video codecs factory from the video codec manager and\n * deinitialize the codecs library.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_ffmpeg_vid_deinit(void);\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_CODECS_FFMPEG_VID_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/g722.h",
    "content": "/* $Id: g722.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODEC_G722_H__\n#define __PJMEDIA_CODEC_G722_H__\n\n/**\n * @file pjmedia-codec/g722.h\n * @brief G.722 codec.\n */\n\n#include <pjmedia-codec/types.h>\n\n/**\n * @defgroup PJMED_G722 G.722 Codec\n * @ingroup PJMEDIA_CODEC_CODECS\n * @brief Implementation of G.722 Codec\n * @{\n *\n * This section describes functions to initialize and register G.722 codec\n * factory to the codec manager. After the codec factory has been registered,\n * application can use @ref PJMEDIA_CODEC API to manipulate the codec.\n *\n * The G.722 implementation uses 16-bit PCM with sampling rate 16000Hz and \n * 20ms frame length resulting in 64kbps bitrate.\n *\n * The G.722 codec implementation is provided as part of pjmedia-codec\n * library, and does not depend on external G.722 codec implementation.\n *\n * \\section codec_setting Codec Settings\n *\n * \\subsection general_setting General Settings\n *\n * General codec settings for this codec such as VAD and PLC can be \n * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param. \n * Please see the documentation of #pjmedia_codec_param for more info.\n *\n * \\subsection specific_setting Codec Specific Settings\n *\n * Currently none.\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Initialize and register G.722 codec factory to pjmedia endpoint.\n *\n * @param endpt\t    The pjmedia endpoint.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_g722_init(pjmedia_endpt *endpt);\n\n\n/**\n * Unregister G.722 codec factory from pjmedia endpoint and cleanup\n * resources allocated by the factory.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_g722_deinit(void);\n\n\n/**\n * Set the G.722 codec encoder and decoder level adjustment.\n * If the value is non-zero, then PCM input samples to the encoder will \n * be shifted right by this value, and similarly PCM output samples from\n * the decoder will be shifted left by this value.\n *\n * Default value is PJMEDIA_G722_DEFAULT_PCM_SHIFT.\n *\n * @param val\t\tThe value\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_g722_set_pcm_shift(unsigned val);\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n#endif /* __PJMEDIA_CODEC_G722_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/g7221.h",
    "content": "/* $Id: g7221.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODECS_G7221_H__\n#define __PJMEDIA_CODECS_G7221_H__\n\n/**\n * @file pjmedia-codec/g7221.h\n * @brief G722.1 codec.\n */\n\n#include <pjmedia-codec/types.h>\n\n/**\n * @defgroup PJMED_G7221_CODEC G.722.1 Codec (Siren7/Siren14)\n * @ingroup PJMEDIA_CODEC_CODECS\n * @brief Implementation of G.722.1 codec\n * @{\n *\n * <b>G.722.1 licensed from Polycom</b><br />\n * <b>G.722.1 Annex C licensed from Polycom</b>\n *\n * This section describes functions to initialize and register G.722.1 codec\n * factory to the codec manager. After the codec factory has been registered,\n * application can use @ref PJMEDIA_CODEC API to manipulate the codec.\n *\n * PJMEDIA G722.1 codec implementation is based on ITU-T Recommendation \n * G.722.1 (05/2005) C fixed point implementation including its Annex C.\n *\n * G.722.1 is a low complexity codec that supports 7kHz and 14kHz audio \n * bandwidth working at bitrates ranging from 16kbps to 48kbps. It may be\n * used with speech or music inputs.\n *\n *\n * \\section codec_setting Codec Settings\n *\n * \\subsection general_setting General Settings\n *\n * General codec settings for this codec such as VAD and PLC can be \n * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param. \n * Please see the documentation of #pjmedia_codec_param for more info.\n *\n * \\subsection specific_setting Codec Specific Settings\n *\n * The following settings are applicable for this codec.\n *\n * \\subsubsection bitrate Bitrate\n *\n * The codec implementation supports standard and non-standard bitrates.\n * Use #pjmedia_codec_g7221_set_mode() to enable or disable the bitrates.\n *\n * By default, only standard bitrates are enabled upon initialization:\n * - for 7kHz audio bandwidth (16kHz sampling rate): 24kbps and 32kbps,\n * - for 14kHz audio bandwidth (32kHz sampling rate): 24kbps, 32kbps, and\n *   48kbps.\n *\n * The usage of non-standard bitrates must follow these requirements:\n * - for 7kHz audio bandwidth (16kHz sampling rate): 16000 to 32000 bps, \n *   multiplication of 400\n * - for 14kHz audio bandwidth (32kHz sampling rate): 24000 to 48000 bps,\n *   multiplication of 400\n *\n * The bitrate is set via <tt>param.setting.dec_fmtp</tt>, if it does not\n * contain bitrate info, the codec will check <tt>param.info.avg_bps</tt>.\n *\n * \\note\n * Currently only up to two non-standard modes can be enabled.\n *\n * \\remark\n * There is a flaw in the codec manager as currently it could not\n * differentiate G.722.1 codecs by bitrates, hence invoking \n * #pjmedia_codec_mgr_set_default_param() may only affect a G.722.1 codec\n * with the highest priority (or first index found in codec enumeration \n * when they have same priority) and invoking\n * #pjmedia_codec_mgr_set_codec_priority() will set priority of all G.722.1\n * codecs with sampling rate as specified.\n */\n\nPJ_BEGIN_DECL\n\n/**\n * Initialize and register G.722.1 codec factory to pjmedia endpoint.\n *\n * @param endpt\t    The pjmedia endpoint.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_g7221_init( pjmedia_endpt *endpt );\n\n\n/**\n * Enable and disable G.722.1 mode. By default, the standard modes are \n * enabled upon initialization, i.e.:\n * - sampling rate 16kHz, bitrate 24kbps and 32kbps.\n * - sampling rate 32kHz, bitrate 24kbps, 32kbps, and 48kbps.\n * This function can also be used for enabling non-standard modes.\n * Note that currently only up to two non-standard modes can be enabled\n * at one time.\n *\n * @param sample_rate\tPCM sampling rate, in Hz, valid values are only \n *\t\t\t16000 and 32000.\n * @param bitrate\tG722.1 bitrate, in bps, the valid values are\n *\t\t\tstandard and non-standard bitrates as described \n *\t\t\tabove.\n * @param enabled\tPJ_TRUE for enabling specified mode.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_g7221_set_mode(unsigned sample_rate, \n\t\t\t\t\t\t  unsigned bitrate, \n\t\t\t\t\t\t  pj_bool_t enabled);\n\n/**\n * Set the G.722.1 codec encoder and decoder level adjustment. \n * If the value is non-zero, then PCM input samples to the encoder will \n * be shifted right by this value, and similarly PCM output samples from\n * the decoder will be shifted left by this value.\n *\n * \\note\n * This function is also applicable for G722.1 implementation with IPP\n * back-end.\n *\n * Default value is PJMEDIA_G7221_DEFAULT_PCM_SHIFT.\n *\n * @param val\t\tThe value\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_g7221_set_pcm_shift(int val);\n\n\n\n/**\n * Unregister G.722.1 codecs factory from pjmedia endpoint.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_g7221_deinit(void);\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_CODECS_G7221_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/g7221_sdp_match.h",
    "content": "/* $Id: g7221_sdp_match.h 3911 2011-12-15 06:45:23Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODEC_G7221_SDP_MATCH_H__\n#define __PJMEDIA_CODEC_G7221_SDP_MATCH_H__\n\n\n/**\n * @file g7221_sdp_match.h\n * @brief Special SDP format match for G722.1.\n */\n\n#include <pjmedia/sdp_neg.h>\n\nPJ_BEGIN_DECL\n\n/**\n * Match G.722.1 format in the SDP media offer and answer. This function\n * will match G.722.1 bitrate setting in the SDP format parameter of\n * offer and answer.\n *\n * @param pool\t\tThe memory pool.\n * @param offer\t\tThe SDP media offer.\n * @param o_fmt_idx\tIndex of the G.722.1 format in the SDP media offer.\n * @param answer\tThe SDP media answer.\n * @param a_fmt_idx\tIndex of the G.722.1 format in the SDP media answer.\n * @param option\tThe format matching option, see\n *\t\t\t#pjmedia_sdp_neg_fmt_match_flag.\n *\n * @return\t\tPJ_SUCCESS when the formats in offer and answer match.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_g7221_match_sdp( pj_pool_t *pool,\n\t\t\t\t\t\t    pjmedia_sdp_media *offer,\n\t\t\t\t\t\t    unsigned o_fmt_idx,\n\t\t\t\t\t\t    pjmedia_sdp_media *answer,\n\t\t\t\t\t\t    unsigned a_fmt_idx,\n\t\t\t\t\t\t    unsigned option);\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_CODEC_G7221_SDP_MATCH_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/gsm.h",
    "content": "/* $Id: gsm.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODEC_GSM_H__\n#define __PJMEDIA_CODEC_GSM_H__\n\n/**\n * @file pjmedia-codec/gsm.h\n * @brief GSM 06.10 codec.\n */\n\n#include <pjmedia-codec/types.h>\n\n/**\n * @defgroup PJMED_GSM GSM 06.10 Codec\n * @ingroup PJMEDIA_CODEC_CODECS\n * @brief Implementation of GSM FR based on GSM 06.10 library\n * @{\n *\n * This section describes functions to initialize and register GSM codec\n * factory to the codec manager. After the codec factory has been registered,\n * application can use @ref PJMEDIA_CODEC API to manipulate the codec.\n *\n * The GSM codec supports 16-bit PCM with sampling rate of 8000Hz resulting\n * in 13.2kbps bitrate.\n *\n * \\section codec_setting Codec Settings\n *\n * \\subsection general_setting General Settings\n *\n * General codec settings for this codec such as VAD and PLC can be \n * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param. \n * Please see the documentation of #pjmedia_codec_param for more info.\n *\n * \\subsection specific_setting Codec Specific Settings\n *\n * Currently none.\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Initialize and register GSM codec factory to pjmedia endpoint.\n *\n * @param endpt\t    The pjmedia endpoint.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_gsm_init( pjmedia_endpt *endpt );\n\n\n\n/**\n * Unregister GSM codec factory from pjmedia endpoint and deinitialize\n * the GSM codec library.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_gsm_deinit(void);\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_CODEC_GSM_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/h263_packetizer.h",
    "content": "/* $Id: h263_packetizer.h 3715 2011-08-19 09:35:25Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_H263_PACKETIZER_H__\n#define __PJMEDIA_H263_PACKETIZER_H__\n\n\n/**\n * @file h263_packetizer.h\n * @brief Packetizes/unpacketizes H.263 bitstream into RTP payload.\n */\n\n#include <pj/pool.h>\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n\n/**\n * Opaque declaration for H.263 packetizer.\n */\ntypedef struct pjmedia_h263_packetizer pjmedia_h263_packetizer;\n\n\n/**\n * Enumeration of H.263 packetization modes.\n */\ntypedef enum\n{\n    /**\n     * H.263 RTP packetization using RFC 4629.\n     */\n    PJMEDIA_H263_PACKETIZER_MODE_RFC4629,\n\n    /**\n     * H.263 RTP packetization using legacy RFC 2190.\n     * This is currently not supported.\n     */\n    PJMEDIA_H263_PACKETIZER_MODE_RFC2190,\n\n} pjmedia_h263_packetizer_mode;\n\n\n/**\n * H.263 packetizer configuration.\n */\ntypedef struct pjmedia_h263_packetizer_cfg\n{\n    /**\n     * Maximum payload length.\n     * Default: PJMEDIA_MAX_MTU\n     */\n    int\tmtu;\n\n    /**\n     * Packetization mode.\n     * Default: PJMEDIA_H263_PACKETIZER_MODE_RFC4629\n     */\n    pjmedia_h263_packetizer_mode mode;\n\n} pjmedia_h263_packetizer_cfg;\n\n\n/**\n * Create H.263 packetizer.\n *\n * @param pool\t\tThe memory pool.\n * @param cfg\t\tPacketizer settings, if NULL, default setting\n *\t\t\twill be used.\n * @param p_pktz\tPointer to receive the packetizer.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_h263_packetizer_create(\n\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t    const pjmedia_h263_packetizer_cfg *cfg,\n\t\t\t\t    pjmedia_h263_packetizer **p_pktz);\n\n\n/**\n * Generate an RTP payload from a H.263 picture bitstream. Note that this\n * function will apply in-place processing, so the bitstream may be modified\n * during the packetization.\n *\n * @param pktz\t\tThe packetizer.\n * @param bits\t\tThe picture bitstream to be packetized.\n * @param bits_len\tThe length of the bitstream.\n * @param bits_pos\tThe bitstream offset to be packetized.\n * @param payload\tThe output payload.\n * @param payload_len\tThe output payload length.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_h263_packetize(pjmedia_h263_packetizer *pktz,\n\t\t\t\t\t    pj_uint8_t *bits,\n                                            pj_size_t bits_len,\n                                            unsigned *bits_pos,\n                                            const pj_uint8_t **payload,\n                                            pj_size_t *payload_len);\n\n\n/**\n * Append an RTP payload to an H.263 picture bitstream. Note that in case of\n * noticing packet lost, application should keep calling this function with\n * payload pointer set to NULL, as the packetizer need to update its internal\n * state.\n *\n * @param pktz\t\tThe packetizer.\n * @param payload\tThe payload to be unpacketized.\n * @param payload_len\tThe payload length.\n * @param bits\t\tThe bitstream buffer.\n * @param bits_size\tThe bitstream buffer size.\n * @param bits_pos\tThe bitstream offset to put the unpacketized payload\n *\t\t\tin the bitstream, upon return, this will be updated\n *\t\t\tto the latest offset as a result of the unpacketized\n *\t\t\tpayload.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_h263_unpacketize(pjmedia_h263_packetizer *pktz,\n\t\t\t\t\t      const pj_uint8_t *payload,\n                                              pj_size_t payload_len,\n                                              pj_uint8_t *bits,\n                                              pj_size_t bits_size,\n\t\t\t\t\t      unsigned *bits_pos);\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_H263_PACKETIZER_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/h264_packetizer.h",
    "content": "/* $Id: h264_packetizer.h 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_H264_PACKETIZER_H__\n#define __PJMEDIA_H264_PACKETIZER_H__\n\n/**\n * @file h264_packetizer.h\n * @brief Packetizes H.264 bitstream into RTP payload and vice versa.\n */\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * Opaque declaration for H.264 packetizer.\n */\ntypedef struct pjmedia_h264_packetizer pjmedia_h264_packetizer;\n\n\n/**\n * Enumeration of H.264 packetization modes.\n */\ntypedef enum\n{\n    /**\n     * Single NAL unit packetization mode will only generate payloads\n     * containing a complete single NAL unit packet. As H.264 NAL unit\n     * size can be very large, this mode is usually not applicable for\n     * network environments with MTU size limitation.\n     */\n    PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL,\n    \n    /**\n     * Non-interleaved packetization mode will generate payloads with the\n     * following possible formats:\n     * - single NAL unit packets,\n     * - NAL units aggregation STAP-A packets,\n     * - fragmented NAL unit FU-A packets.\n     */\n    PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED,\n\n    /**\n     * Interleaved packetization mode will generate payloads with the\n     * following possible formats:\n     * - single NAL unit packets,\n     * - NAL units aggregation STAP-A & STAP-B packets,\n     * - fragmented NAL unit FU-A & FU-B packets.\n     * This packetization mode is currently unsupported.\n     */\n    PJMEDIA_H264_PACKETIZER_MODE_INTERLEAVED,\n} pjmedia_h264_packetizer_mode;\n\n\n/**\n * H.264 packetizer setting.\n */\ntypedef struct pjmedia_h264_packetizer_cfg\n{\n    /**\n     * Maximum payload length.\n     * Default: PJMEDIA_MAX_MTU\n     */\n    int\tmtu;\n\n    /**\n     * Packetization mode.\n     * Default: PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED\n     */\n    pjmedia_h264_packetizer_mode mode;\n}\npjmedia_h264_packetizer_cfg;\n\n\n/**\n * Create H.264 packetizer.\n *\n * @param pool\t\tThe memory pool.\n * @param cfg\t\tPacketizer settings, if NULL, default setting\n *\t\t\twill be used.\n * @param p_pktz\tPointer to receive the packetizer.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_h264_packetizer_create(\n\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t    const pjmedia_h264_packetizer_cfg *cfg,\n\t\t\t\t    pjmedia_h264_packetizer **p_pktz);\n\n\n/**\n * Generate an RTP payload from a H.264 picture bitstream. Note that this\n * function will apply in-place processing, so the bitstream may be modified\n * during the packetization.\n *\n * @param pktz\t\tThe packetizer.\n * @param bits\t\tThe picture bitstream to be packetized.\n * @param bits_len\tThe length of the bitstream.\n * @param bits_pos\tThe bitstream offset to be packetized.\n * @param payload\tThe output payload.\n * @param payload_len\tThe output payload length.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_h264_packetize(pjmedia_h264_packetizer *pktz,\n\t\t\t\t\t    pj_uint8_t *bits,\n                                            pj_size_t bits_len,\n                                            unsigned *bits_pos,\n                                            const pj_uint8_t **payload,\n                                            pj_size_t *payload_len);\n\n\n/**\n * Append an RTP payload to an H.264 picture bitstream. Note that in case of\n * noticing packet lost, application should keep calling this function with\n * payload pointer set to NULL, as the packetizer need to update its internal\n * state.\n *\n * @param pktz\t\tThe packetizer.\n * @param payload\tThe payload to be unpacketized.\n * @param payload_len\tThe payload length.\n * @param bits\t\tThe bitstream buffer.\n * @param bits_size\tThe bitstream buffer size.\n * @param bits_pos\tThe bitstream offset to put the unpacketized payload\n *\t\t\tin the bitstream, upon return, this will be updated\n *\t\t\tto the latest offset as a result of the unpacketized\n *\t\t\tpayload.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_h264_unpacketize(pjmedia_h264_packetizer *pktz,\n\t\t\t\t\t      const pj_uint8_t *payload,\n                                              pj_size_t   payload_len,\n                                              pj_uint8_t *bits,\n                                              pj_size_t   bits_len,\n\t\t\t\t\t      unsigned   *bits_pos);\n\n\nPJ_END_DECL\n\n#endif\t/* __PJMEDIA_H264_PACKETIZER_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/ilbc.h",
    "content": "/* $Id: ilbc.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODEC_ILBC_H__\n#define __PJMEDIA_CODEC_ILBC_H__\n\n/**\n * @file pjmedia-codec/ilbc.h\n * @brief iLBC codec.\n */\n\n#include <pjmedia-codec/types.h>\n\n/**\n * @defgroup PJMED_ILBC iLBC Codec\n * @ingroup PJMEDIA_CODEC_CODECS\n * @brief Implementation of iLBC Codec\n * @{\n *\n * This section describes functions to initialize and register iLBC codec\n * factory to the codec manager. After the codec factory has been registered,\n * application can use @ref PJMEDIA_CODEC API to manipulate the codec.\n *\n * The iLBC codec is developed by Global IP Solutions (GIPS), formerly \n * Global IP Sound. The iLBC offers low bitrate and graceful audio quality \n * degradation on frame losses.\n *\n * The iLBC codec supports 16-bit PCM audio signal with sampling rate of \n * 8000Hz operating at two modes: 20ms and 30ms frame length modes, resulting\n * in bitrates of 15.2kbps for 20ms mode and 13.33kbps for 30ms mode.\n *\n *\n * \\section codec_setting Codec Settings\n *\n * \\subsection general_setting General Settings\n *\n * General codec settings for this codec such as VAD and PLC can be \n * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param. \n * Please see the documentation of #pjmedia_codec_param for more info.\n *\n * \\subsection specific_setting Codec Specific Settings\n *\n * The following settings are applicable for this codec.\n *\n * \\subsubsection mode Mode\n *\n * The default mode should be set upon initialization, see\n * #pjmedia_codec_ilbc_init(). After the codec is initialized, the default\n * mode can be modified using #pjmedia_codec_mgr_set_default_param().\n *\n * In #pjmedia_codec_param, iLBC mode can be set by specifying SDP\n * format parameter \"mode\" in the SDP \"a=fmtp\" attribute for decoding\n * direction. Valid values are \"20\" and \"30\" (for 20ms and 30ms mode \n * respectively).\n *\n * Here is an example to set up #pjmedia_codec_param to use mode 20ms:\n *  \\code\n    pjmedia_codec_param param;\n    ...\n    // setting iLBC mode in SDP\n    param.setting.dec_fmtp.cnt = 1;\n    param.setting.dec_fmtp.param[0].name = pj_str(\"mode\");\n    param.setting.dec_fmtp.param[0].val  = pj_str(\"20\");\n    ...\n \\endcode\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Initialize and register iLBC codec factory to pjmedia endpoint.\n *\n * @param endpt\t    The pjmedia endpoint.\n * @param mode\t    Default decoder mode to be used. Valid values are\n *\t\t    20 and 30 ms. Note that encoder mode follows the\n *\t\t    setting advertised in the remote's SDP.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_ilbc_init( pjmedia_endpt *endpt,\n\t\t\t\t\t      int mode );\n\n\n\n/**\n * Unregister iLBC codec factory from pjmedia endpoint and deinitialize\n * the iLBC codec library.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_ilbc_deinit(void);\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_CODEC_ILBC_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/openh264.h",
    "content": "/* $Id$ */\n/* \n * Copyright (C) 2014 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODEC_OPENH264_H__\n#define __PJMEDIA_CODEC_OPENH264_H__\n\n#include <pjmedia-codec/types.h>\n#include <pjmedia/vid_codec.h>\n\n/**\n * @file pjmedia-codec/openh264.h\n * @brief Open H.264 codec\n */\n\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJMEDIA_CODEC_OPENH264 Open H.264 Codec\n * @ingroup PJMEDIA_CODEC_VID_CODECS\n * @{\n */\n\n/**\n * Initialize and register OpenH264 codec factory.\n *\n * @param mgr\t    The video codec manager instance where this codec will\n * \t\t    be registered to. Specify NULL to use default instance\n * \t\t    (in that case, an instance of video codec manager must\n * \t\t    have been created beforehand).\n * @param pf\t    Pool factory.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_openh264_vid_init(pjmedia_vid_codec_mgr *mgr,\n                                                     pj_pool_factory *pf);\n\n/**\n * Unregister OpenH264 video codecs factory from the video codec manager and\n * deinitialize the codec library.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_openh264_vid_deinit(void);\n\n\n/**\n * @}  PJMEDIA_CODEC_OPENH264\n */\n\n\nPJ_END_DECL\n\n#endif\t/* __PJMEDIA_CODEC_OPENH264_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/opus.h",
    "content": "\n#ifndef __PJMEDIA_CODEC_OPUS_CODEC_H__\n#define __PJMEDIA_CODEC_OPUS_CODEC_H__\n\n/**\n * @file pj_opus.h\n * @brief OPUS codec.\n */\n\n#include <pjmedia-codec/types.h>\n\n\nPJ_BEGIN_DECL\n\nPJ_DECL(pj_status_t) pjmedia_codec_opus_init( pjmedia_endpt *endpt);\nPJ_DECL(pj_status_t) pjmedia_codec_opus_deinit(void);\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_CODEC_OPUS_CODEC_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/passthrough.h",
    "content": "/* $Id: passthrough.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODECS_PASSTHROUGH_H__\n#define __PJMEDIA_CODECS_PASSTHROUGH_H__\n\n/**\n * @file pjmedia-codec/passthrough.h\n * @brief Passthrough codecs.\n */\n\n#include <pjmedia-codec/types.h>\n\n/**\n * @defgroup PJMED_PASSTHROUGH_CODEC Passthrough Codecs\n * @ingroup PJMEDIA_CODEC_CODECS\n * @brief Implementation of passthrough codecs\n * @{\n *\n * This section describes functions to initialize and register passthrough \n * codecs factory to the codec manager. After the codec factory has been \n * registered, application can use @ref PJMEDIA_CODEC API to manipulate \n * the codec.\n *\n * Passthrough codecs are codecs wrapper that does NOT perform encoding \n * or decoding, it just PACK and PARSE encoded audio data from/into RTP \n * payload. This will accomodate pjmedia ports which work with encoded\n * audio data, e.g: encoded audio files, sound device with capability\n * of playing/recording encoded audio data.\n *\n * This codec factory contains various codecs, i.e: G.729, iLBC,\n * AMR, and G.711.\n *\n *\n * \\section pjmedia_codec_passthrough_g729 Passthrough G.729\n *\n * G.729 supports 16-bit PCM audio signal with sampling rate 8000Hz, \n * frame length 10ms, and resulting in bitrate 8000bps.\n *\n * \\subsection codec_setting Codec Settings\n *\n * General codec settings for this codec such as VAD and PLC can be \n * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param. \n * Please see the documentation of #pjmedia_codec_param for more info.\n *\n * Note that G.729 VAD status should be signalled in SDP, see more\n * description below.\n *\n * \\subsubsection annexb Annex B\n *\n * The capability of VAD/DTX is specified in Annex B.\n *\n * By default, Annex B is enabled. This default setting of Annex B can \n * be modified using #pjmedia_codec_mgr_set_default_param().\n *\n * In #pjmedia_codec_param, Annex B is configured via VAD setting and\n * format parameter \"annexb\" in the SDP \"a=fmtp\" attribute in\n * decoding fmtp field. Valid values are \"yes\" and \"no\",\n * the implementation default is \"yes\". When this parameter is omitted\n * in the SDP, the value will be \"yes\" (RFC 4856 Section 2.1.9).\n *\n * Here is an example of modifying default setting of Annex B to\n * be disabled using #pjmedia_codec_mgr_set_default_param():\n \\code\n    pjmedia_codec_param param;\n\n    pjmedia_codec_mgr_get_default_param(.., &param);\n    ...\n    // Set VAD\n    param.setting.vad = 0;\n    // Set SDP format parameter\n    param.setting.dec_fmtp.cnt = 1;\n    param.setting.dec_fmtp.param[0].name = pj_str(\"annexb\");\n    param.setting.dec_fmtp.param[0].val  = pj_str(\"no\");\n    ...\n    pjmedia_codec_mgr_set_default_param(.., &param);\n \\endcode\n *\n * \\note\n * The difference of Annex B status in SDP offer/answer may be considered as \n * incompatible codec in SDP negotiation.\n *\n * \n * \\section pjmedia_codec_passthrough_ilbc Passthrough iLBC\n *\n * The iLBC codec is developed by Global IP Solutions (GIPS), formerly \n * Global IP Sound. The iLBC offers low bitrate and graceful audio quality \n * degradation on frame losses.\n *\n * The iLBC codec supports 16-bit PCM audio signal with sampling rate of \n * 8000Hz operating at two modes: 20ms and 30ms frame length modes, resulting\n * in bitrates of 15.2kbps for 20ms mode and 13.33kbps for 30ms mode.\n *\n * \\subsection codec_setting Codec Settings\n *\n * General codec settings for this codec such as VAD and PLC can be \n * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param. \n * Please see the documentation of #pjmedia_codec_param for more info.\n *\n * \\subsubsection mode Mode\n *\n * The default mode should be set upon initialization, see\n * #pjmedia_codec_passthrough_init2(). After the codec is initialized, the\n * default mode can be modified using #pjmedia_codec_mgr_set_default_param().\n *\n * In #pjmedia_codec_param, iLBC mode can be set by specifying SDP\n * format parameter \"mode\" in the SDP \"a=fmtp\" attribute for decoding\n * direction. Valid values are \"20\" and \"30\" (for 20ms and 30ms mode \n * respectively).\n *\n * Here is an example to set up #pjmedia_codec_param to use mode 20ms:\n *  \\code\n    pjmedia_codec_param param;\n    ...\n    // setting iLBC mode in SDP\n    param.setting.dec_fmtp.cnt = 1;\n    param.setting.dec_fmtp.param[0].name = pj_str(\"mode\");\n    param.setting.dec_fmtp.param[0].val  = pj_str(\"20\");\n    ...\n \\endcode\n *\n *\n * \\section pjmedia_codec_passthrough_amr Passthrough AMR\n *\n * IPP AMR supports 16-bit PCM audio signal with sampling rate 8000Hz,\n * 20ms frame length and producing various bitrates that ranges from 4.75kbps\n * to 12.2kbps.\n *\n * \\subsection codec_setting Codec Settings\n *\n * General codec settings for this codec such as VAD and PLC can be \n * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param. \n * Please see the documentation of #pjmedia_codec_param for more info.\n *\n * \\subsubsection bitrate Bitrate\n *\n * By default, encoding bitrate is 7400bps. This default setting can be \n * modified using #pjmedia_codec_mgr_set_default_param() by specifying \n * prefered AMR bitrate in field <tt>info::avg_bps</tt> of \n * #pjmedia_codec_param. Valid bitrates could be seen in \n * #pjmedia_codec_amrnb_bitrates.\n *\n * \\subsubsection payload_format Payload Format\n *\n * There are two AMR payload format types, bandwidth-efficient and\n * octet-aligned. Default setting is using octet-aligned. This default payload\n * format can be modified using #pjmedia_codec_mgr_set_default_param().\n *\n * In #pjmedia_codec_param, payload format can be set by specifying SDP \n * format parameters \"octet-align\" in the SDP \"a=fmtp\" attribute for \n * decoding direction. Valid values are \"0\" (for bandwidth efficient mode)\n * and \"1\" (for octet-aligned mode).\n *\n * \\subsubsection mode_set Mode-Set\n * \n * Mode-set is used for restricting AMR modes in decoding direction.\n *\n * By default, no mode-set restriction applied. This default setting can be \n * be modified using #pjmedia_codec_mgr_set_default_param().\n *\n * In #pjmedia_codec_param, mode-set could be specified via format parameters\n * \"mode-set\" in the SDP \"a=fmtp\" attribute for decoding direction. Valid \n * value is a comma separated list of modes from the set 0 - 7, e.g: \n * \"4,5,6,7\". When this parameter is omitted, no mode-set restrictions applied.\n *\n * Here is an example of modifying AMR default codec param:\n \\code\n    pjmedia_codec_param param;\n\n    pjmedia_codec_mgr_get_default_param(.., &param);\n    ...\n    // set default encoding bitrate to the highest 12.2kbps\n    param.info.avg_bps = 12200;\n\n    // restrict decoding bitrate to 10.2kbps and 12.2kbps only\n    param.setting.dec_fmtp.param[0].name = pj_str(\"mode-set\");\n    param.setting.dec_fmtp.param[0].val  = pj_str(\"6,7\");\n\n    // also set to use bandwidth-efficient payload format\n    param.setting.dec_fmtp.param[1].name = pj_str(\"octet-align\");\n    param.setting.dec_fmtp.param[1].val  = pj_str(\"0\");\n\n    param.setting.dec_fmtp.cnt = 2;\n    ...\n    pjmedia_codec_mgr_set_default_param(.., &param);\n \\endcode\n * \n *\n * \\section pjmedia_codec_passthrough_g711 Passthrough G.711\n *\n * The G.711 is an ultra low complexity codecs and in trade-off it results\n * in high bitrate, i.e: 64kbps for 16-bit PCM with sampling rate 8000Hz.\n *\n * The factory contains two main compression algorithms, PCMU/u-Law and \n * PCMA/A-Law.\n *\n * \\subsection codec_setting Codec Settings\n *\n * General codec settings for this codec such as VAD and PLC can be \n * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param. \n * Please see the documentation of #pjmedia_codec_param for more info.\n */\n\nPJ_BEGIN_DECL\n\n\n/** \n * Codec passthrough configuration settings.\n */\ntypedef struct pjmedia_codec_passthrough_setting\n{\n    unsigned\t\t fmt_cnt;\t/**< Number of encoding formats\n\t\t\t\t\t     to be enabled.\t\t*/\n    pjmedia_format\t*fmts;\t\t/**< Encoding formats to be \n\t\t\t\t\t     enabled.\t\t\t*/\n    unsigned\t\t ilbc_mode;\t/**< iLBC default mode.\t\t*/\n} pjmedia_codec_passthrough_setting;\n\n\n/**\n * Initialize and register passthrough codecs factory to pjmedia endpoint,\n * all supported encoding formats will be enabled.\n *\n * @param endpt\t    The pjmedia endpoint.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_passthrough_init( pjmedia_endpt *endpt );\n\n\n/**\n * Initialize and register passthrough codecs factory to pjmedia endpoint\n * with only specified encoding formats enabled.\n *\n * @param endpt\t    The pjmedia endpoint.\n * @param setting   The settings.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_passthrough_init2(\n\t\t       pjmedia_endpt *endpt,\n\t\t       const pjmedia_codec_passthrough_setting *setting);\n\n\n/**\n * Unregister passthrough codecs factory from pjmedia endpoint.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_passthrough_deinit(void);\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_CODECS_PASSTHROUGH_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/speex.h",
    "content": "/* $Id: speex.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODEC_SPEEX_H__\n#define __PJMEDIA_CODEC_SPEEX_H__\n\n/**\n * @file speex.h\n * @brief Speex codec header.\n */\n\n#include <pjmedia-codec/types.h>\n\n/**\n * @defgroup PJMED_SPEEX Speex Codec Family\n * @ingroup PJMEDIA_CODEC_CODECS\n * @brief Implementation of Speex codecs (narrow/wide/ultrawide-band).\n * @{\n *\n * This section describes functions to initialize and register speex codec\n * factory to the codec manager. After the codec factory has been registered,\n * application can use @ref PJMEDIA_CODEC API to manipulate the codec.\n *\n * The Speex codec uses multiple bit rates, and supports ultra-wideband \n * (32 kHz sampling rate), wideband (16 kHz sampling rate) and narrowband \n * (telephone quality, 8 kHz sampling rate)\n *\n * By default, the speex codec factory registers three Speex codecs:\n * \"speex/8000\" narrowband codec, \"speex/16000\" wideband codec, and \n * \"speex/32000\" ultra-wideband codec. This behavior can be changed by\n * specifying #pjmedia_speex_options flags during initialization.\n *\n *\n * \\section codec_setting Codec Settings\n *\n * \\subsection general_setting General Settings\n *\n * General codec settings for this codec such as VAD and PLC can be \n * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param. \n * Please see the documentation of #pjmedia_codec_param for more info.\n *\n * \\subsection specific_setting Codec Specific Settings\n *\n * The following settings are applicable for this codec.\n *\n * \\subsubsection quality_vs_complexity Quality vs Complexity\n *\n * The Speex codec quality versus computational complexity and bandwidth\n * requirement can be adjusted by modifying the quality and complexity\n * setting, by calling #pjmedia_codec_speex_set_param(). The RFC 5574\n * Section 5 shows the relationship between quality setting and the\n * resulting bitrate.\n *\n * The default setting of quality is specified in \n * #PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY. And the default setting of\n * complexity is specified in #PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY.\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Bitmask options to be passed during Speex codec factory initialization.\n */\nenum pjmedia_speex_options\n{\n    PJMEDIA_SPEEX_NO_NB\t    = 1,    /**< Disable narrowband mode.\t*/\n    PJMEDIA_SPEEX_NO_WB\t    = 2,    /**< Disable wideband mode.\t\t*/\n    PJMEDIA_SPEEX_NO_UWB    = 4,    /**< Disable ultra-wideband mode.\t*/\n};\n\n\n/**\n * Initialize and register Speex codec factory to pjmedia endpoint.\n *\n * @param endpt\t\tThe pjmedia endpoint.\n * @param options\tBitmask of pjmedia_speex_options (default=0).\n * @param quality\tSpecify encoding quality, or use -1 for default \n *\t\t\t(@see PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY).\n * @param complexity\tSpecify encoding complexity , or use -1 for default \n *\t\t\t(@see PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY).\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_speex_init( pjmedia_endpt *endpt,\n\t\t\t\t\t       unsigned options,\n\t\t\t\t\t       int quality,\n\t\t\t\t\t       int complexity );\n\n\n/**\n * Initialize Speex codec factory using default settings and register to \n * pjmedia endpoint.\n *\n * @param endpt\t\tThe pjmedia endpoint.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_speex_init_default(pjmedia_endpt *endpt);\n\n\n/**\n * Change the settings of Speex codec.\n *\n * @param clock_rate\tClock rate of Speex mode to be set.\n * @param quality\tSpecify encoding quality, or use -1 for default \n *\t\t\t(@see PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY).\n * @param complexity\tSpecify encoding complexity , or use -1 for default \n *\t\t\t(@see PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY).\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_speex_set_param(unsigned clock_rate,\n\t\t\t\t\t\t   int quality,\n\t\t\t\t\t\t   int complexity);\n\n\n/**\n * Unregister Speex codec factory from pjmedia endpoint and deinitialize\n * the Speex codec library.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_speex_deinit(void);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_CODEC_SPEEX_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/types.h",
    "content": "/* $Id: types.h 4264 2012-09-24 06:58:16Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODEC_TYPES_H__\n#define __PJMEDIA_CODEC_TYPES_H__\n\n/**\n * @file types.h\n * @brief PJMEDIA-CODEC types and constants\n */\n\n#include <pjmedia-codec/config.h>\n#include <pjmedia/codec.h>\n\n/**\n * @defgroup pjmedia_codec_types PJMEDIA-CODEC Types and Constants\n * @ingroup PJMEDIA_CODEC\n * @brief Constants used by PJMEDIA-CODEC\n * @{\n */\n\n\n\n/**\n * These are the dynamic payload types that are used by audio codecs in\n * this library. Also see the header file <pjmedia/codec.h> for list\n * of static payload types.\n */\nenum pjmedia_audio_pt\n{\n    /* According to IANA specifications, dynamic payload types are to be in\n     * the range 96-127 (inclusive). This enum is structured to place the\n     * values of the payload types specified below into that range.\n     *\n     * PJMEDIA_RTP_PT_DYNAMIC is defined in <pjmedia/codec.h>. It is defined\n     * to be 96.\n     *\n     * PJMEDIA_RTP_PT_TELEPHONE_EVENTS is defined in <pjmedia/config.h>.\n     * The default value is 96.\n     */\n#if PJMEDIA_RTP_PT_TELEPHONE_EVENTS\n    PJMEDIA_RTP_PT_START = PJMEDIA_RTP_PT_TELEPHONE_EVENTS,\n#else\n    PJMEDIA_RTP_PT_START = (PJMEDIA_RTP_PT_DYNAMIC-1),\n#endif\n\n    PJMEDIA_RTP_PT_SPEEX_NB,\t\t\t/**< Speex narrowband/8KHz  */\n    PJMEDIA_RTP_PT_SPEEX_WB,\t\t\t/**< Speex wideband/16KHz   */\n    PJMEDIA_RTP_PT_SPEEX_UWB,\t\t\t/**< Speex 32KHz\t    */\n    PJMEDIA_RTP_PT_SILK_NB,\t\t\t/**< SILK narrowband/8KHz   */\n    PJMEDIA_RTP_PT_SILK_MB,\t\t\t/**< SILK mediumband/12KHz  */\n    PJMEDIA_RTP_PT_SILK_WB,\t\t\t/**< SILK wideband/16KHz    */\n    PJMEDIA_RTP_PT_SILK_SWB,\t\t\t/**< SILK 24KHz\t\t    */\n    PJMEDIA_RTP_PT_ILBC,\t\t\t/**< iLBC (13.3/15.2Kbps)   */\n    PJMEDIA_RTP_PT_AMR,\t\t\t\t/**< AMR (4.75 - 12.2Kbps)  */\n    PJMEDIA_RTP_PT_AMRWB,\t\t\t/**< AMRWB (6.6 - 23.85Kbps)*/\n    PJMEDIA_RTP_PT_AMRWBE,\t\t\t/**< AMRWBE\t\t    */\n    PJMEDIA_RTP_PT_OPUS,\t\t\t/**< OPUS\t\t    */\n    PJMEDIA_RTP_PT_G726_16,\t\t\t/**< G726 @ 16Kbps\t    */\n    PJMEDIA_RTP_PT_G726_24,\t\t\t/**< G726 @ 24Kbps\t    */\n    PJMEDIA_RTP_PT_G726_32,\t\t\t/**< G726 @ 32Kbps\t    */\n    PJMEDIA_RTP_PT_G726_40,\t\t\t/**< G726 @ 40Kbps\t    */\n    PJMEDIA_RTP_PT_G722_1_16,\t\t\t/**< G722.1 (16Kbps)\t    */\n    PJMEDIA_RTP_PT_G722_1_24,\t\t\t/**< G722.1 (24Kbps)\t    */\n    PJMEDIA_RTP_PT_G722_1_32,\t\t\t/**< G722.1 (32Kbps)\t    */\n    PJMEDIA_RTP_PT_G7221C_24,\t\t\t/**< G722.1 Annex C (24Kbps)*/\n    PJMEDIA_RTP_PT_G7221C_32,\t\t\t/**< G722.1 Annex C (32Kbps)*/\n    PJMEDIA_RTP_PT_G7221C_48,\t\t\t/**< G722.1 Annex C (48Kbps)*/\n    PJMEDIA_RTP_PT_G7221_RSV1,\t\t\t/**< G722.1 reserve\t    */\n    PJMEDIA_RTP_PT_G7221_RSV2,\t\t\t/**< G722.1 reserve\t    */\n    PJMEDIA_RTP_PT_L16_8KHZ_MONO,\t\t/**< L16 @ 8KHz, mono\t    */\n    PJMEDIA_RTP_PT_L16_8KHZ_STEREO,\t\t/**< L16 @ 8KHz, stereo     */\n    //PJMEDIA_RTP_PT_L16_11KHZ_MONO,\t\t/**< L16 @ 11KHz, mono\t    */\n    //PJMEDIA_RTP_PT_L16_11KHZ_STEREO,\t\t/**< L16 @ 11KHz, stereo    */\n    PJMEDIA_RTP_PT_L16_16KHZ_MONO,\t\t/**< L16 @ 16KHz, mono\t    */\n    PJMEDIA_RTP_PT_L16_16KHZ_STEREO,\t\t/**< L16 @ 16KHz, stereo    */\n    //PJMEDIA_RTP_PT_L16_22KHZ_MONO,\t\t/**< L16 @ 22KHz, mono\t    */\n    //PJMEDIA_RTP_PT_L16_22KHZ_STEREO,\t\t/**< L16 @ 22KHz, stereo    */\n    //PJMEDIA_RTP_PT_L16_32KHZ_MONO,\t\t/**< L16 @ 32KHz, mono\t    */\n    //PJMEDIA_RTP_PT_L16_32KHZ_STEREO,\t\t/**< L16 @ 32KHz, stereo    */\n    //PJMEDIA_RTP_PT_L16_48KHZ_MONO,\t\t/**< L16 @ 48KHz, mono\t    */\n    //PJMEDIA_RTP_PT_L16_48KHZ_STEREO,\t\t/**< L16 @ 48KHz, stereo    */\n\n    /* Caution!\n     * Ensure the value of the last pt above is <= 127.\n     */\n};\n\n/**\n * These are the dynamic payload types that are used by video codecs in\n * this library.\n */\nenum pjmedia_video_pt\n{\n     /* Video payload types */\n     PJMEDIA_RTP_PT_VID_START = (PJMEDIA_RTP_PT_DYNAMIC-1),\n     PJMEDIA_RTP_PT_H263P,\n     PJMEDIA_RTP_PT_H264,\n     PJMEDIA_RTP_PT_H264_RSV1,\n     PJMEDIA_RTP_PT_H264_RSV2,\n     PJMEDIA_RTP_PT_H264_RSV3,\n     PJMEDIA_RTP_PT_H264_RSV4,\n     PJMEDIA_RTP_PT_VP8,\n\n     /* Caution!\n      * Ensure the value of the last pt above is <= 127.\n      */\n};\n\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_CODEC_TYPES_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec/vpx.h",
    "content": "/**\n * Copyright (C) 2010 Regis Montoya (aka r3gis - www.r3gis.fr)\n * This file is part of pjsip_android.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __PJMEDIA_CODECS_VPX_H__\n#define __PJMEDIA_CODECS_VPX_H__\n\n\n#include <pjmedia-codec/types.h>\n#include <pjmedia/vid_codec.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJMEDIA_CODEC_VPX libvpx Codecs\n * @ingroup PJMEDIA_CODEC_VID_CODECS\n * @{\n */\n\n/**\n * Initialize and register libvpx video codecs factory to pjmedia endpoint.\n *\n * @param mgr\t    The video codec manager instance where this codec will\n * \t\t    be registered to. Specify NULL to use default instance\n * \t\t    (in that case, an instance of video codec manager must\n * \t\t    have been created beforehand).\n * @param pf\t    Pool factory.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_vpx_init(pjmedia_vid_codec_mgr *mgr,\n                                                   pj_pool_factory *pf);\n\n\n/**\n * Unregister libvpx video codecs factory from the video codec manager and\n * deinitialize the codecs library.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjmedia_codec_vpx_deinit(void);\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n#endif\t/* __PJMEDIA_CODECS_VPX_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-codec.h",
    "content": "/* $Id: pjmedia-codec.h 4331 2013-01-23 06:18:18Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_CODEC_PJMEDIA_CODEC_H__\n#define __PJMEDIA_CODEC_PJMEDIA_CODEC_H__\n\n/**\n * @file pjmedia-codec.h\n * @brief Include all codecs API in PJMEDIA-CODEC\n */\n\n#include <pjmedia-codec/audio_codecs.h>\n#include <pjmedia-codec/ffmpeg_vid_codecs.h>\n#include <pjmedia-codec/vpx.h>\n#include <pjmedia-codec/gsm.h>\n#include <pjmedia-codec/speex.h>\n#include <pjmedia-codec/ilbc.h>\n#include <pjmedia-codec/g722.h>\n#include <pjmedia-codec/g7221.h>\n#include <pjmedia-codec/openh264.h>\n#include <pjmedia-codec/passthrough.h>\n#include <pjmedia-codec/opus.h>\n\n\n#endif\t/* __PJMEDIA_CODEC_PJMEDIA_CODEC_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-videodev/avi_dev.h",
    "content": "/* $Id: avi_dev.h 4016 2012-04-04 05:05:50Z bennylp $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef __PJMEDIA_VIDEODEV_AVI_DEV_H__\n#define __PJMEDIA_VIDEODEV_AVI_DEV_H__\n\n/**\n * @file avi_dev.h\n * @brief AVI player virtual device\n */\n#include <pjmedia-videodev/videodev.h>\n#include <pjmedia/avi_stream.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup avi_dev AVI Player Virtual Device\n * @ingroup video_device_api\n * @brief AVI player virtual device\n * @{\n * This describes a virtual capture device which takes its input from an AVI\n * file.\n */\n\n/**\n * Settings for the AVI player virtual device. This param corresponds to\n * PJMEDIA_VID_DEV_CAP_AVI_PLAY capability of the video device/stream.\n */\ntypedef struct pjmedia_avi_dev_param\n{\n    /**\n     * Specifies the full path of the AVI file to be played.\n     */\n    pj_str_t\tpath;\n\n    /**\n     * If this setting is specified when setting the device, this specifies\n     * the title to be assigned as the device name. If this setting not\n     * specified, the filename part of the path will be used.\n     */\n    pj_str_t\ttitle;\n\n    /**\n     * The underlying AVI streams created by the device. If the value is NULL,\n     * that means the device has not been configured yet. Application can use\n     * this field to retrieve the audio stream of the AVI. This setting is\n     * \"get\"-only and will be ignored in \"set capability\" operation.\n     */\n    pjmedia_avi_streams *avi_streams;\n\n} pjmedia_avi_dev_param;\n\n\n/**\n * Reset pjmedia_avi_dev_param with the default settings. This mostly will\n * reset all values to NULL or zero.\n *\n * @param p\tThe parameter to be initialized.\n */\nPJ_DECL(void) pjmedia_avi_dev_param_default(pjmedia_avi_dev_param *p);\n\n\n/**\n * Create a AVI device factory, and register it to the video device\n * subsystem. At least one factory needs to be created before an AVI\n * device can be allocated and used, and normally only one factory is\n * needed per application.\n *\n * @param pf\t\tPool factory to be used.\n * @param max_dev\tNumber of devices to be reserved.\n * @param p_ret\t\tPointer to return the factory instance, to be\n * \t\t\tused when allocating a virtual device.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_avi_dev_create_factory(\n\t\t\t\t    pj_pool_factory *pf,\n\t\t\t\t    unsigned max_dev,\n\t\t\t\t    pjmedia_vid_dev_factory **p_ret);\n\n/**\n * Allocate one device ID to be used to play the specified AVI file in\n * the parameter.\n *\n * @param param\t\tThe parameter, with at least the AVI file path\n * \t\t\tset.\n * @param p_id\t\tOptional pointer to receive device ID to play\n * \t\t\tthe file.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n *\n */\nPJ_DECL(pj_status_t) pjmedia_avi_dev_alloc(pjmedia_vid_dev_factory *f,\n                                           pjmedia_avi_dev_param *param,\n                                           pjmedia_vid_dev_index *p_id);\n\n/**\n * Retrieve the parameters set for the virtual device.\n *\n * @param id\t\tDevice ID.\n * @param prm\t\tStructure to receive the settings.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_avi_dev_get_param(pjmedia_vid_dev_index id,\n                                               pjmedia_avi_dev_param *param);\n\n/**\n * Free the resources associated with the virtual device.\n *\n * @param id\t\tThe device ID.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjmedia_avi_dev_free(pjmedia_vid_dev_index id);\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif    /* __PJMEDIA_VIDEODEV_AVI_DEV_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-videodev/config.h",
    "content": "/* $Id: config.h 4414 2013-03-05 08:21:02Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_VIDEODEV_CONFIG_H__\n#define __PJMEDIA_VIDEODEV_CONFIG_H__\n\n/**\n * @file config.h\n * @brief Video config.\n */\n#include <pjmedia/types.h>\n#include <pj/pool.h>\n\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup video_device_api Video Device API\n * @brief PJMEDIA video device abstraction API.\n */\n\n/**\n * @defgroup s1_video_device_config Compile time configurations\n * @ingroup video_device_api\n * @brief Compile time configurations\n * @{\n */\n\n/**\n * This setting controls the maximum number of formats that can be\n * supported by a video device.\n *\n * Default: 64\n */\n#ifndef PJMEDIA_VID_DEV_INFO_FMT_CNT\n#   define PJMEDIA_VID_DEV_INFO_FMT_CNT 64\n#endif\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n/**\n * This setting controls the maximum number of supported video device drivers.\n *\n * Default: 8\n */\n#ifndef PJMEDIA_VID_DEV_MAX_DRIVERS\n#   define PJMEDIA_VID_DEV_MAX_DRIVERS 8\n#endif\n\n/**\n * This setting controls the maximum number of supported video devices.\n *\n * Default: 16\n */\n#ifndef PJMEDIA_VID_DEV_MAX_DEVS\n#   define PJMEDIA_VID_DEV_MAX_DEVS 16\n#endif\n\n\n/**\n * This setting controls whether AVFoundation support should be included.\n *\n * Default: 0 (or detected by configure)\n */\n#ifndef PJMEDIA_VIDEO_DEV_HAS_AVF\n#   define PJMEDIA_VIDEO_DEV_HAS_AVF\t\t0\n#endif\n\n\n/**\n * This setting controls whether Direct Show support should be included.\n *\n * Default: 0 (unfinished)\n */\n#ifndef PJMEDIA_VIDEO_DEV_HAS_DSHOW\n#   define PJMEDIA_VIDEO_DEV_HAS_DSHOW\t\t0 //PJ_WIN32\n#endif\n\n\n/**\n * This setting controls whether colorbar source support should be included.\n *\n * Default: 1\n */\n#ifndef PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC\n#   define PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC\t1\n#endif\n\n\n/**\n * Video4Linux2\n *\n * Default: 0 (or detected by configure)\n */\n#ifndef PJMEDIA_VIDEO_DEV_HAS_V4L2\n#   define PJMEDIA_VIDEO_DEV_HAS_V4L2\t\t0\n#endif\n\n\n/**\n * Enable support for AVI player virtual capture device.\n *\n * Default: 1\n */\n#ifndef PJMEDIA_VIDEO_DEV_HAS_AVI\n#   define PJMEDIA_VIDEO_DEV_HAS_AVI\t\t1\n#endif\n\n/**\n * Enable support for frame buffer render device.\n *\n * Default: 1\n */\n#ifndef PJMEDIA_VIDEO_DEV_HAS_FB\n#   define PJMEDIA_VIDEO_DEV_HAS_FB\t\t1\n#endif\n\n\n#endif /* defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) */\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJMEDIA_VIDEODEV_CONFIG_H__ */\n\n/*\n --------------------- DOCUMENTATION FOLLOWS ---------------------------\n */\n\n/**\n * @addtogroup video_device_api Video Device API\n * @{\n\nPJMEDIA Video Device API is a cross-platform video API appropriate for use with\nVoIP applications and many other types of video streaming applications. \n\nThe API abstracts many different video API's on various platforms, such as:\n - native Direct Show video for Win32 and Windows Mobile devices\n - null-video implementation\n - and more to be implemented in the future\n\nThe Video Device API/library is an evolution from PJMEDIA @ref PJMED_SND and \ncontains many enhancements:\n\n - Forward compatibility:\n\\n\n   The new API has been designed to be extensible, it will support new API's as \n   well as new features that may be introduced in the future without breaking \n   compatibility with applications that use this API as well as compatibility \n   with existing device implementations. \n\n - Device capabilities:\n\\n\n   At the heart of the API is device capabilities management, where all possible\n   video capabilities of video devices should be able to be handled in a generic\n   manner. With this framework, new capabilities that may be discovered in the \n   future can be handled in manner without breaking existing applications. \n\n - Built-in features:\n\\n\n   The device capabilities framework enables applications to use and control \n   video features built-in in the device, such as:\n    - built-in formats, \n    - etc.\n\n - Codec support:\n\\n\n   Some video devices support built-in hardware video codecs, and application\n   can use the video device in encoded mode to make use of these hardware \n   codecs. \n\n - Multiple backends:\n\\n\n   The new API supports multiple video backends (called factories or drivers in \n   the code) to be active simultaneously, and video backends may be added or \n   removed during run-time. \n\n*/\n\n\n/**\n * @}\n */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-videodev/errno.h",
    "content": "/* $Id: errno.h 3715 2011-08-19 09:35:25Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_VIDEODEV_VIDEODEV_ERRNO_H__\n#define __PJMEDIA_VIDEODEV_VIDEODEV_ERRNO_H__\n\n/**\n * @file errno.h Error Codes\n * @brief Videodev specific error codes.\n */\n\n#include <pjmedia-videodev/config.h>\n#include <pj/errno.h>\n\n/**\n * @defgroup error_codes Error Codes\n * @ingroup video_device_api\n * @brief Video device library specific error codes.\n * @{\n */\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * Start of error code relative to PJ_ERRNO_START_USER.\n * This value is 520000.\n */\n#define PJMEDIA_VIDEODEV_ERRNO_START \\\n\t    (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*7)\n#define PJMEDIA_VIDEODEV_ERRNO_END   \\\n\t    (PJMEDIA_VIDEODEV_ERRNO_START + PJ_ERRNO_SPACE_SIZE - 1)\n\n\n/************************************************************\n * Video Device API error codes\n ***********************************************************/\n/**\n * @hideinitializer\n * General/unknown error.\n */\n#define PJMEDIA_EVID_ERR\t(PJMEDIA_VIDEODEV_ERRNO_START+1) /* 520001 */\n\n/**\n * @hideinitializer\n * Unknown error from video driver\n */\n#define PJMEDIA_EVID_SYSERR\t(PJMEDIA_VIDEODEV_ERRNO_START+2) /* 520002 */\n\n/**\n * @hideinitializer\n * Video subsystem not initialized\n */\n#define PJMEDIA_EVID_INIT\t(PJMEDIA_VIDEODEV_ERRNO_START+3) /* 520003 */\n\n/**\n * @hideinitializer\n * Invalid video device\n */\n#define PJMEDIA_EVID_INVDEV\t(PJMEDIA_VIDEODEV_ERRNO_START+4) /* 520004 */\n\n/**\n * @hideinitializer\n * Found no devices\n */\n#define PJMEDIA_EVID_NODEV\t(PJMEDIA_VIDEODEV_ERRNO_START+5) /* 520005 */\n\n/**\n * @hideinitializer\n * Unable to find default device\n */\n#define PJMEDIA_EVID_NODEFDEV\t(PJMEDIA_VIDEODEV_ERRNO_START+6) /* 520006 */\n\n/**\n * @hideinitializer\n * Device not ready\n */\n#define PJMEDIA_EVID_NOTREADY\t(PJMEDIA_VIDEODEV_ERRNO_START+7) /* 520007 */\n\n/**\n * @hideinitializer\n * The video capability is invalid or not supported\n */\n#define PJMEDIA_EVID_INVCAP\t(PJMEDIA_VIDEODEV_ERRNO_START+8) /* 520008 */\n\n/**\n * @hideinitializer\n * The operation is invalid or not supported\n */\n#define PJMEDIA_EVID_INVOP\t(PJMEDIA_VIDEODEV_ERRNO_START+9) /* 520009 */\n\n/**\n * @hideinitializer\n * Bad or invalid video device format\n */\n#define PJMEDIA_EVID_BADFORMAT\t(PJMEDIA_VIDEODEV_ERRNO_START+10) /* 520010 */\n\n/**\n * @hideinitializer\n * Invalid video device sample format\n */\n#define PJMEDIA_EVID_SAMPFORMAT\t(PJMEDIA_VIDEODEV_ERRNO_START+11) /* 520011 */\n\n/**\n * @hideinitializer\n * Bad latency setting\n */\n#define PJMEDIA_EVID_BADLATENCY\t(PJMEDIA_VIDEODEV_ERRNO_START+12) /* 520012 */\n\n/**\n * @hideinitializer\n * Bad/unsupported video size\n */\n#define PJMEDIA_EVID_BADSIZE\t(PJMEDIA_VIDEODEV_ERRNO_START+13) /* 520013 */\n\n\n/**\n * Get error message for the specified error code. Note that this\n * function is only able to decode PJMEDIA Videodev specific error code.\n * Application should use pj_strerror(), which should be able to\n * decode all error codes belonging to all subsystems (e.g. pjlib,\n * pjmedia, pjsip, etc).\n *\n * @param status    The error code.\n * @param buffer    The buffer where to put the error message.\n * @param bufsize   Size of the buffer.\n *\n * @return\t    The error message as NULL terminated string,\n *                  wrapped with pj_str_t.\n */\nPJ_DECL(pj_str_t) pjmedia_videodev_strerror(pj_status_t status, char *buffer,\n\t\t\t\t\t    pj_size_t bufsize);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJMEDIA_VIDEODEV_VIDEODEV_ERRNO_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-videodev/fb_dev.h",
    "content": "/* $Id$ */\n/*\n * Copyright (C) 2014-present AG Projects\n * Copyright (C) 2013-2014 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef PJMEDIA_VIDEODEV_FB_DEV_H__\n#define PJMEDIA_VIDEODEV_FB_DEV_H__\n\n#include <pjmedia-videodev/videodev_imp.h>\n\ntypedef void (*pjmedia_vid_dev_fb_frame_cb)(const pjmedia_frame *frame, const pjmedia_rect_size size, void *user_data);\n\npj_status_t\npjmedia_vid_dev_fb_set_callback(pjmedia_vid_dev_stream *strm,\n                                pjmedia_vid_dev_fb_frame_cb cb,\n                                void *user_data);\n\n#endif    /* PJMEDIA_VIDEODEV_FB_DEV_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-videodev/videodev.h",
    "content": "/* $Id: videodev.h 4167 2012-06-15 08:13:43Z ming $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef __PJMEDIA_VIDEODEV_VIDEODEV_H__\n#define __PJMEDIA_VIDEODEV_VIDEODEV_H__\n\n/**\n * @file videodev.h\n * @brief Video device API.\n */\n#include <pjmedia-videodev/config.h>\n#include <pjmedia-videodev/errno.h>\n#include <pjmedia/event.h>\n#include <pjmedia/frame.h>\n#include <pjmedia/format.h>\n#include <pj/pool.h>\n\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup video_device_reference Video Device API Reference\n * @ingroup video_device_api\n * @brief API Reference\n * @{\n */\n \n/**\n * Type for device index.\n */\ntypedef pj_int32_t pjmedia_vid_dev_index;\n\n/**\n * Enumeration of window handle type.\n */\ntypedef enum pjmedia_vid_dev_hwnd_type\n{\n    /**\n     * Type none.\n     */\n    PJMEDIA_VID_DEV_HWND_TYPE_NONE,\n\n    /**\n     * Native window handle on Windows.\n     */\n    PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS,\n\n    /**\n     * Native view on iOS.\n     */\n    PJMEDIA_VID_DEV_HWND_TYPE_IOS,\n\n    /**\n     * Native window handle on Android.\n     */\n    PJMEDIA_VID_DEV_HWND_TYPE_ANDROID\n\n} pjmedia_vid_dev_hwnd_type;\n\n/**\n * Type for window handle.\n */\ntypedef struct pjmedia_vid_dev_hwnd\n{\n    /**\n     * The window handle type.\n     */\n    pjmedia_vid_dev_hwnd_type type;\n\n    /**\n     * The window handle.\n     */\n    union\n    {\n\tstruct {\n\t    void    *hwnd;\t/**< HWND     \t*/\n\t} win;\n\tstruct {\n\t    void    *window;    /**< Window\t*/\n\t    void    *display;   /**< Display\t*/\n\t} x11;\n\tstruct {\n\t    void    *window;    /**< Window\t*/\n\t} cocoa;\n\tstruct {\n\t    void    *window;    /**< Window\t*/\n\t} ios;\n\tstruct {\n\t    void    *window;    /**< Native window */\n\t} android;\n\tvoid \t    *window;\n    } info;\n\n} pjmedia_vid_dev_hwnd;\n\n/**\n * Parameter for switching device with PJMEDIA_VID_DEV_CAP_SWITCH capability.\n * Initialize this with pjmedia_vid_dev_switch_param_default()\n */\ntypedef struct pjmedia_vid_dev_switch_param\n{\n    /**\n     * Target device ID to switch to. Once the switching is successful, the\n     * video stream will use this device and the old device will be closed.\n     */\n    pjmedia_vid_dev_index target_id;\n\n} pjmedia_vid_dev_switch_param;\n\n\n/**\n * Enumeration of window flags.\n */\ntypedef enum pjmedia_vid_dev_wnd_flag\n{\n    /**\n     * Window with border.\n     */\n    PJMEDIA_VID_DEV_WND_BORDER = 1,\n\n    /**\n     * Window can be resized.\n     */\n    PJMEDIA_VID_DEV_WND_RESIZABLE = 2\n\n} pjmedia_vid_dev_wnd_flag;\n\n\n/**\n * Device index constants.\n */\nenum pjmedia_vid_dev_std_index\n{\n    /**\n     * Constant to denote default capture device\n     */\n    PJMEDIA_VID_DEFAULT_CAPTURE_DEV = -1,\n\n    /**\n     * Constant to denote default render device\n     */\n    PJMEDIA_VID_DEFAULT_RENDER_DEV = -2,\n\n    /**\n     * Constant to denote invalid device index.\n     */\n    PJMEDIA_VID_INVALID_DEV = -3\n};\n\n\n/**\n * This enumeration identifies various video device capabilities. These video\n * capabilities indicates what features are supported by the underlying\n * video device implementation.\n *\n * Applications get these capabilities in the #pjmedia_vid_dev_info structure.\n *\n * Application can also set the specific features/capabilities when opening\n * the video stream by setting the \\a flags member of #pjmedia_vid_dev_param\n * structure.\n *\n * Once video stream is running, application can also retrieve or set some\n * specific video capability, by using #pjmedia_vid_dev_stream_get_cap() and\n * #pjmedia_vid_dev_stream_set_cap() and specifying the desired capability. The\n * value of the capability is specified as pointer, and application needs to\n * supply the pointer with the correct value, according to the documentation\n * of each of the capability.\n */\ntypedef enum pjmedia_vid_dev_cap\n{\n    /**\n     * Support for video formats. The value of this capability\n     * is represented by #pjmedia_format structure.\n     */\n    PJMEDIA_VID_DEV_CAP_FORMAT = 1,\n\n    /**\n     * Support for video input scaling\n     */\n    PJMEDIA_VID_DEV_CAP_INPUT_SCALE = 2,\n\n    /**\n     * Support for returning the native window handle of the video window.\n     * For renderer, this means the window handle of the renderer window,\n     * while for capture, this means the window handle of the native preview,\n     * only if the device supports  PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW\n     * capability.\n     *\n     * The value of this capability is pointer to pjmedia_vid_dev_hwnd\n     * structure.\n     */\n    PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW = 4,\n\n    /**\n     * Support for resizing video output. This capability SHOULD be \n     * implemented by renderer, to alter the video output dimension on the fly.\n     * Value is pjmedia_rect_size. \n     */\n    PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE = 8,\n\n    /**\n     * Support for setting the video window's position.\n     * Value is pjmedia_coord specifying the window's new coordinate.\n     */\n    PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION = 16,\n\n    /**\n     * Support for setting the video output's visibility.\n     * The value of this capability is a pj_bool_t containing boolean\n     * PJ_TRUE or PJ_FALSE.\n     */\n    PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE = 32,\n\n    /**\n     * Support for native preview capability in capture devices. Value is\n     * pj_bool_t. With native preview, capture device can be instructed to\n     * show or hide a preview window showing video directly from the camera\n     * by setting this capability to PJ_TRUE or PJ_FALSE. Once the preview\n     * is started, application may use PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW\n     * capability to query the video window.\n     *\n     * The value of this capability is a pj_bool_t containing boolean\n     * PJ_TRUE or PJ_FALSE.\n     */\n    PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW = 64,\n\n    /**\n     * Support for changing video orientation. For a renderer device,\n     * changing video orientation in will potentially affect the size of\n     * render window, i.e: width and height swap. For a capture device,\n     * the video will be rotated but the size of the video frame\n     * will stay the same, so the video may be resized or stretched.\n     *\n     * The value of this capability is pjmedia_orient.\n     */\n    PJMEDIA_VID_DEV_CAP_ORIENTATION = 128,\n\n    /**\n     * Support for fast switching to another device. A video stream with this\n     * capability allows replacing of its underlying device with another\n     * device, saving the user from opening a new video stream and gets a much\n     * faster and smoother switching action.\n     *\n     * Note that even when this capability is supported by a device, it may\n     * not be able to switch to arbitrary device. Application must always\n     * check the return value of the operation to verify that switching has\n     * occurred.\n     *\n     * This capability is currently write-only (i.e. set-only).\n     *\n     * The value of this capability is pointer to pjmedia_vid_dev_switch_param\n     * structure.\n     */\n    PJMEDIA_VID_DEV_CAP_SWITCH = 256,\n\n    /**\n     * Support for setting the output video window's flags.\n     * The value of this capability is a bitmask combination of\n     * #pjmedia_vid_dev_wnd_flag.\n     */\n    PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS = 512,\n\n    /**\n     * End of standard capability\n     */\n    PJMEDIA_VID_DEV_CAP_MAX = 16384\n\n} pjmedia_vid_dev_cap;\n\n/**\n * Device information structure returned by #pjmedia_vid_dev_get_info().\n */\ntypedef struct pjmedia_vid_dev_info\n{\n    /** The device ID */\n    pjmedia_vid_dev_index id;\n\n    /** The device name */\n    char name[64];\n\n    /** The underlying driver name */\n    char driver[32];\n\n    /** \n     * The supported direction of the video device, i.e. whether it supports \n     * capture only, render only, or both.\n     */\n    pjmedia_dir dir;\n\n    /**\n     * Specify whether the device supports callback. Devices that implement\n     * \"active interface\" will actively call the callbacks to give or ask for\n     * video frames. If the device doesn't support callback, application\n     * must actively request or give video frames from/to the device by using\n     * pjmedia_vid_dev_stream_get_frame()/pjmedia_vid_dev_stream_put_frame().\n     */\n    pj_bool_t has_callback;\n\n    /** Device capabilities, as bitmask combination of #pjmedia_vid_dev_cap */\n    unsigned caps;\n\n    /** Number of video formats supported by this device */\n    unsigned fmt_cnt;\n\n    /** \n     * Array of supported video formats. Some fields in each supported video\n     * format may be set to zero or of \"unknown\" value, to indicate that the\n     * value is unknown or should be ignored. When these value are not set\n     * to zero, it indicates that the exact format combination is being used. \n     */\n    pjmedia_format fmt[PJMEDIA_VID_DEV_INFO_FMT_CNT];\n\n} pjmedia_vid_dev_info;\n\n\n/** Forward declaration for pjmedia_vid_dev_stream */\ntypedef struct pjmedia_vid_dev_stream pjmedia_vid_dev_stream;\n\ntypedef struct pjmedia_vid_dev_cb\n{\n    /**\n    * This callback is called by capturer stream when it has captured the\n    * whole packet worth of video samples.\n    *\n    * @param stream\t   The video stream.\n    * @param user_data     User data associated with the stream.\n    * @param frame         Captured frame.\n    *\n    * @return              Returning non-PJ_SUCCESS will cause the video\n    *                      stream to stop\n    */\n    pj_status_t (*capture_cb)(pjmedia_vid_dev_stream *stream,\n\t\t              void *user_data,\n                              pjmedia_frame *frame);\n\n    /**\n    * This callback is called by renderer stream when it needs additional\n    * data to be rendered by the device. Application must fill in the whole\n    * of output buffer with video samples.\n    *\n    * The frame argument contains the following values:\n    *  - timestamp         Rendering timestamp, in samples.\n    *  - buf               Buffer to be filled out by application.\n    *  - size              The size requested in bytes, which will be equal\n    *                      to the size of one whole packet.\n    *\n    * @param stream\t   The video stream.\n    * @param user_data     User data associated with the stream.\n    * @param frame         Video frame, which buffer is to be filled in by\n    *                      the application.\n    *\n    * @return              Returning non-PJ_SUCCESS will cause the video \n    *                      stream to stop\n    */\n    pj_status_t (*render_cb)(pjmedia_vid_dev_stream *stream,\n\t\t\t     void *user_data,\n                             pjmedia_frame *frame);\n\n} pjmedia_vid_dev_cb;\n\n\n/**\n * This structure specifies the parameters to open the video stream.\n */\ntypedef struct pjmedia_vid_dev_param\n{\n    /**\n     * The video direction. This setting is mandatory.\n     */\n    pjmedia_dir dir;\n\n    /**\n     * The video capture device ID. This setting is mandatory if the video\n     * direction includes input/capture direction.\n     */\n    pjmedia_vid_dev_index cap_id;\n\n    /**\n     * The video render device ID. This setting is mandatory if the video\n     * direction includes output/render direction.\n     */\n    pjmedia_vid_dev_index rend_id;\n\n    /** \n     * Video clock rate. This setting is mandatory if the video\n     * direction includes input/capture direction\n     */\n    unsigned clock_rate;\n\n    /**\n     * Video frame rate. This setting is mandatory if the video\n     * direction includes input/capture direction\n     */\n//    pjmedia_ratio frame_rate;\n\n    /**\n     * This flags specifies which of the optional settings are valid in this\n     * structure. The flags is bitmask combination of pjmedia_vid_dev_cap.\n     */\n    unsigned flags;\n\n    /**\n     * Set the video format. This setting is mandatory.\n     */\n    pjmedia_format fmt;\n\n    /**\n     * Window for the renderer to display the video. This setting is optional,\n     * and will only be used if PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW is set in \n     * the flags.\n     */\n    pjmedia_vid_dev_hwnd window;\n\n    /**\n     * Video display size. This setting is optional, and will only be used \n     * if PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE is set in the flags.\n     */\n    pjmedia_rect_size disp_size;\n\n    /**\n     * Video window position. This setting is optional, and will only be used\n     * if PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION is set in the flags.\n     */\n    pjmedia_coord window_pos;\n\n    /**\n     * Video window's visibility. This setting is optional, and will only be\n     * used if PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE is set in the flags.\n     */\n    pj_bool_t window_hide;\n\n    /**\n     * Enable built-in preview. This setting is optional and is only used\n     * if PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW capability is supported and\n     * set in the flags.\n     */\n    pj_bool_t native_preview;\n\n    /**\n     * Video orientation. This setting is optional and is only used if\n     * PJMEDIA_VID_DEV_CAP_ORIENTATION capability is supported and is\n     * set in the flags.\n     */\n    pjmedia_orient orient;\n\n    /**\n     * Video window flags. This setting is optional, and will only be used\n     * if PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS is set in the flags.\n     */\n    unsigned window_flags;\n\n} pjmedia_vid_dev_param;\n\n\n/** Forward declaration for video device factory */\ntypedef struct pjmedia_vid_dev_factory pjmedia_vid_dev_factory;\n\n/* typedef for factory creation function */\ntypedef pjmedia_vid_dev_factory*\n(*pjmedia_vid_dev_factory_create_func_ptr)(pj_pool_factory*);\n\n/**\n * Initialize pjmedia_vid_dev_switch_param.\n *\n * @param p\t    Parameter to be initialized.\n */\nPJ_INLINE(void)\npjmedia_vid_dev_switch_param_default(pjmedia_vid_dev_switch_param *p)\n{\n    pj_bzero(p, sizeof(*p));\n    p->target_id = PJMEDIA_VID_INVALID_DEV;\n}\n\n/**\n * Get string info for the specified capability.\n *\n * @param cap       The capability ID.\n * @param p_desc    Optional pointer which will be filled with longer\n *                  description about the capability.\n *\n * @return          Capability name.\n */\nPJ_DECL(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap,\n                                              const char **p_desc);\n\n\n/**\n * Set a capability field value in #pjmedia_vid_dev_param structure. This will\n * also set the flags field for the specified capability in the structure.\n *\n * @param param     The structure.\n * @param cap       The video capability which value is to be set.\n * @param pval      Pointer to value. Please see the type of value to\n *                  be supplied in the pjmedia_vid_dev_cap documentation.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t)\npjmedia_vid_dev_param_set_cap(pjmedia_vid_dev_param *param,\n                              pjmedia_vid_dev_cap cap,\n                              const void *pval);\n\n\n/**\n * Get a capability field value from #pjmedia_vid_dev_param structure. This\n * function will return PJMEDIA_EVID_INVCAP error if the flag for that\n * capability is not set in the flags field in the structure.\n *\n * @param param     The structure.\n * @param cap       The video capability which value is to be retrieved.\n * @param pval      Pointer to value. Please see the type of value to\n *                  be supplied in the pjmedia_vid_dev_cap documentation.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t)\npjmedia_vid_dev_param_get_cap(const pjmedia_vid_dev_param *param,\n                              pjmedia_vid_dev_cap cap,\n                              void *pval);\n\n/**\n * Initialize the video device subsystem. This will register all supported\n * video device factories to the video device subsystem. This function may be\n * called more than once, but each call to this function must have the\n * corresponding #pjmedia_vid_dev_subsys_shutdown() call.\n *\n * @param pf        The pool factory.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_subsys_init(pj_pool_factory *pf);\n\n\n/**\n * Get the pool factory registered to the video device subsystem.\n *\n * @return          The pool factory.\n */\nPJ_DECL(pj_pool_factory*) pjmedia_vid_dev_subsys_get_pool_factory(void);\n\n\n/**\n * Shutdown the video device subsystem. This will destroy all video device\n * factories registered in the video device subsystem. Note that currently\n * opened video streams may or may not be closed, depending on the\n * implementation of the video device factories.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_subsys_shutdown(void);\n\n\n/**\n * Register a supported video device factory to the video device subsystem.\n * Application can either register a function to create the factory, or\n * an instance of an already created factory.\n *\n * This function can only be called after calling\n * #pjmedia_vid_dev_subsys_init().\n *\n * @param vdf       The factory creation function. Either vdf or factory\n * \t\t    argument must be specified.\n * @param factory   Factory instance. Either vdf or factory\n * \t\t    argument must be specified.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t)\npjmedia_vid_register_factory(pjmedia_vid_dev_factory_create_func_ptr vdf,\n                             pjmedia_vid_dev_factory *factory);\n\n\n/**\n * Unregister a video device factory from the video device subsystem. This\n * function can only be called after calling #pjmedia_vid_dev_subsys_init().\n * Devices from this factory will be unlisted. If a device from this factory\n * is currently in use, then the behavior is undefined.\n *\n * @param vdf       The video device factory. Either vdf or factory argument\n * \t\t    must be specified.\n * @param factory   The factory instance. Either vdf or factory argument\n * \t\t    must be specified.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t)\npjmedia_vid_unregister_factory(pjmedia_vid_dev_factory_create_func_ptr vdf,\n                               pjmedia_vid_dev_factory *factory);\n\n\n/**\n * Refresh the list of video devices installed in the system. This function\n * will only refresh the list of videoo device so all active video streams will\n * be unaffected. After refreshing the device list, application MUST make sure\n * to update all index references to video devices (i.e. all variables of type\n * pjmedia_vid_dev_index) before calling any function that accepts video device\n * index as its parameter.\n *\n * @return\t\tPJ_SUCCESS on successful operation or the appropriate\n *\t\t\terror code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_refresh(void);\n\n\n/**\n * Get the number of video devices installed in the system.\n *\n * @return          The number of video devices installed in the system.\n */\nPJ_DECL(unsigned) pjmedia_vid_dev_count(void);\n\n\n/**\n * Get device information.\n *\n * @param id        The video device ID.\n * @param info      The device information which will be filled in by this\n *                  function once it returns successfully.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id,\n                                              pjmedia_vid_dev_info *info);\n\n\n/**\n * Lookup device index based on the driver and device name.\n *\n * @param drv_name  The driver name.\n * @param dev_name  The device name.\n * @param id        Pointer to store the returned device ID.\n *\n * @return          PJ_SUCCESS if the device can be found.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_lookup(const char *drv_name,\n                                            const char *dev_name,\n                                            pjmedia_vid_dev_index *id);\n\n\n/**\n * Initialize the video device parameters with default values for the\n * specified device.\n *\n * @param id        The video device ID.\n * @param param     The video device parameters which will be initialized\n *                  by this function once it returns successfully.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t)\npjmedia_vid_dev_default_param(pj_pool_t *pool,\n                              pjmedia_vid_dev_index id,\n                              pjmedia_vid_dev_param *param);\n\n\n/**\n * Open video stream object using the specified parameters. If stream is\n * created successfully, this function will return PJ_SUCCESS and the\n * stream pointer will be returned in the p_strm argument.\n *\n * The opened stream may have been opened with different size and fps\n * than the requested values in the \\a param argument. Application should\n * check the actual size and fps that the stream was opened with by inspecting\n * the values in the \\a param argument and see if they have changed. Also\n * if the device ID in the \\a param specifies default device, it may be\n * replaced with the actual device ID upon return.\n *\n * @param param         On input, it specifies the video device parameters\n *                      to be used for the stream. On output, this will be\n *                      set to the actual video device parameters used to\n *                      open the stream.\n * @param cb            Pointer to structure containing video stream\n *                      callbacks.\n * @param user_data     Arbitrary user data, which will be given back in the\n *                      callbacks.\n * @param p_strm        Pointer to receive the video stream.\n *\n * @return              PJ_SUCCESS on successful operation or the appropriate\n *                      error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_stream_create(\n\t\t\t\t\t    pjmedia_vid_dev_param *param,\n\t\t\t\t\t    const pjmedia_vid_dev_cb *cb,\n\t\t\t\t\t    void *user_data,\n\t\t\t\t\t    pjmedia_vid_dev_stream **p_strm);\n\n/**\n * Get the running parameters for the specified video stream.\n *\n * @param strm      The video stream.\n * @param param     Video stream parameters to be filled in by this\n *                  function once it returns successfully.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_param(\n\t\t\t\t\t    pjmedia_vid_dev_stream *strm,\n                                            pjmedia_vid_dev_param *param);\n\n/**\n * Get the value of a specific capability of the video stream.\n *\n * @param strm      The video stream.\n * @param cap       The video capability which value is to be retrieved.\n * @param value     Pointer to value to be filled in by this function\n *                  once it returns successfully.  Please see the type\n *                  of value to be supplied in the pjmedia_vid_dev_cap\n *                  documentation.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_cap(\n\t\t\t\t\t    pjmedia_vid_dev_stream *strm,\n\t\t\t\t\t    pjmedia_vid_dev_cap cap,\n                                            void *value);\n\n/**\n * Set the value of a specific capability of the video stream.\n *\n * @param strm      The video stream.\n * @param cap       The video capability which value is to be set.\n * @param value     Pointer to value. Please see the type of value to\n *                  be supplied in the pjmedia_vid_dev_cap documentation.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_stream_set_cap(\n\t\t\t\t\t    pjmedia_vid_dev_stream *strm,\n\t\t\t\t\t    pjmedia_vid_dev_cap cap,\n\t\t\t\t\t    const void *value);\n\n/**\n * Start the stream.\n *\n * @param strm      The video stream.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_stream_start(\n\t\t\t\t\t    pjmedia_vid_dev_stream *strm);\n\n/**\n * Query whether the stream has been started.\n *\n * @param strm\t    The video stream\n *\n * @return\t    PJ_TRUE if the video stream has been started.\n */\nPJ_DECL(pj_bool_t) pjmedia_vid_dev_stream_is_running(pjmedia_vid_dev_stream *strm);\n\n\n/**\n * Request one frame from the stream. Application needs to call this function\n * periodically only if the stream doesn't support \"active interface\", i.e.\n * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE.\n *\n * @param strm      The video stream.\n * @param frame\t    The video frame to be filled by the device.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_frame(\n\t\t\t\t\t    pjmedia_vid_dev_stream *strm,\n                                            pjmedia_frame *frame);\n\n/**\n * Put one frame to the stream. Application needs to call this function\n * periodically only if the stream doesn't support \"active interface\", i.e.\n * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE.\n *\n * @param strm      The video stream.\n * @param frame\t    The video frame to put to the device.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_stream_put_frame(\n\t\t\t\t\t    pjmedia_vid_dev_stream *strm,\n                                            const pjmedia_frame *frame);\n\n/**\n * Stop the stream.\n *\n * @param strm      The video stream.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_stream_stop(\n\t\t\t\t\t    pjmedia_vid_dev_stream *strm);\n\n/**\n * Destroy the stream.\n *\n * @param strm      The video stream.\n *\n * @return          PJ_SUCCESS on successful operation or the appropriate\n *                  error code.\n */\nPJ_DECL(pj_status_t) pjmedia_vid_dev_stream_destroy(\n\t\t\t\t\t    pjmedia_vid_dev_stream *strm);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif    /* __PJMEDIA_VIDEODEV_VIDEODEV_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia-videodev/videodev_imp.h",
    "content": "/* $Id: videodev_imp.h 4016 2012-04-04 05:05:50Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __VIDEODEV_IMP_H__\n#define __VIDEODEV_IMP_H__\n\n#include <pjmedia-videodev/videodev.h>\n\n/**\n * @defgroup s8_video_device_implementors_api Video Device Implementors API\n * @ingroup video_device_api\n * @brief API for video device implementors\n * @{\n */\n\n/**\n * Video device factory operations.\n */\ntypedef struct pjmedia_vid_dev_factory_op\n{\n    /**\n     * Initialize the video device factory.\n     *\n     * @param f\t\tThe video device factory.\n     */\n    pj_status_t (*init)(pjmedia_vid_dev_factory *f);\n\n    /**\n     * Close this video device factory and release all resources back to the\n     * operating system.\n     *\n     * @param f\t\tThe video device factory.\n     */\n    pj_status_t (*destroy)(pjmedia_vid_dev_factory *f);\n\n    /**\n     * Get the number of video devices installed in the system.\n     *\n     * @param f\t\tThe video device factory.\n     */\n    unsigned (*get_dev_count)(pjmedia_vid_dev_factory *f);\n\n    /**\n     * Get the video device information and capabilities.\n     *\n     * @param f\t\tThe video device factory.\n     * @param index\tDevice index.\n     * @param info\tThe video device information structure which will be\n     *\t\t\tinitialized by this function once it returns \n     *\t\t\tsuccessfully.\n     */\n    pj_status_t\t(*get_dev_info)(pjmedia_vid_dev_factory *f, \n\t\t\t\tunsigned index,\n\t\t\t\tpjmedia_vid_dev_info *info);\n\n    /**\n     * Initialize the specified video device parameter with the default\n     * values for the specified device.\n     *\n     * @param f\t\tThe video device factory.\n     * @param index\tDevice index.\n     * @param param\tThe video device parameter.\n     */\n    pj_status_t (*default_param)(pj_pool_t *pool,\n                                 pjmedia_vid_dev_factory *f,\n\t\t\t\t unsigned index,\n\t\t\t\t pjmedia_vid_dev_param *param);\n\n    /**\n     * Open the video device and create video stream. See\n     * #pjmedia_vid_dev_stream_create()\n     */\n    pj_status_t (*create_stream)(pjmedia_vid_dev_factory *f,\n\t\t\t\t pjmedia_vid_dev_param *param,\n\t\t\t\t const pjmedia_vid_dev_cb *cb,\n\t\t\t\t void *user_data,\n\t\t\t\t pjmedia_vid_dev_stream **p_vid_strm);\n\n    /**\n     * Refresh the list of video devices installed in the system.\n     *\n     * @param f\t\tThe video device factory.\n     */\n    pj_status_t (*refresh)(pjmedia_vid_dev_factory *f);\n\n} pjmedia_vid_dev_factory_op;\n\n\n/**\n * This structure describes a video device factory. \n */\nstruct pjmedia_vid_dev_factory\n{\n    /** Internal data to be initialized by video subsystem. */\n    struct {\n\t/** Driver index */\n\tunsigned drv_idx;\n    } sys;\n\n    /** Operations */\n    pjmedia_vid_dev_factory_op *op;\n};\n\n\n/**\n * Video stream operations.\n */\ntypedef struct pjmedia_vid_dev_stream_op\n{\n    /**\n     * See #pjmedia_vid_dev_stream_get_param()\n     */\n    pj_status_t (*get_param)(pjmedia_vid_dev_stream *strm,\n\t\t\t     pjmedia_vid_dev_param *param);\n\n    /**\n     * See #pjmedia_vid_dev_stream_get_cap()\n     */\n    pj_status_t (*get_cap)(pjmedia_vid_dev_stream *strm,\n\t\t\t   pjmedia_vid_dev_cap cap,\n\t\t\t   void *value);\n\n    /**\n     * See #pjmedia_vid_dev_stream_set_cap()\n     */\n    pj_status_t (*set_cap)(pjmedia_vid_dev_stream *strm,\n\t\t\t   pjmedia_vid_dev_cap cap,\n\t\t\t   const void *value);\n\n    /**\n     * See #pjmedia_vid_dev_stream_start()\n     */\n    pj_status_t (*start)(pjmedia_vid_dev_stream *strm);\n\n    /**\n     * See #pjmedia_vid_dev_stream_get_frame()\n     */\n    pj_status_t (*get_frame)(pjmedia_vid_dev_stream *strm,\n                             pjmedia_frame *frame);\n\n    /**\n     * See #pjmedia_vid_dev_stream_put_frame()\n     */\n    pj_status_t (*put_frame)(pjmedia_vid_dev_stream *strm,\n                             const pjmedia_frame *frame);\n\n    /**\n     * See #pjmedia_vid_dev_stream_stop().\n     */\n    pj_status_t (*stop)(pjmedia_vid_dev_stream *strm);\n\n    /**\n     * See #pjmedia_vid_dev_stream_destroy().\n     */\n    pj_status_t (*destroy)(pjmedia_vid_dev_stream *strm);\n\n} pjmedia_vid_dev_stream_op;\n\n\n/**\n * This structure describes the video device stream.\n */\nstruct pjmedia_vid_dev_stream\n{\n    /** Internal data to be initialized by video subsystem */\n    struct {\n\t/** Driver index */\n\tunsigned drv_idx;\n\n\t/** Has it been started? */\n\tpj_bool_t is_running;\n    } sys;\n\n    /** Operations */\n    pjmedia_vid_dev_stream_op *op;\n};\n\n\n/**\n * Internal API: return the factory instance and device index that's local\n * to the factory for a given device ID.\n *\n * @param id\t\tDevice id.\n * @param p_f\t\tOut: factory instance\n * @param p_local_index Out: device index within the factory\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t)\npjmedia_vid_dev_get_local_index(pjmedia_vid_dev_index id,\n                                pjmedia_vid_dev_factory **p_f,\n                                unsigned *p_local_index);\n\n/**\n * Internal API: return the global device index given a factory instance and\n * a local device index.\n *\n * @param f\t\tFactory.\n * @param local_idx\tLocal index.\n * @param pid\t\tReturned global index.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DEF(pj_status_t)\npjmedia_vid_dev_get_global_index(const pjmedia_vid_dev_factory *f,\n                                 unsigned local_idx,\n                                 pjmedia_vid_dev_index *pid);\n\n/**\n * @}\n */\n\n\n\n#endif /* __VIDEODEV_IMP_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia.h",
    "content": "/* $Id: pjmedia.h 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_H__\n#define __PJMEDIA_H__\n\n/**\n * @file pjmedia.h\n * @brief PJMEDIA main header file.\n */\n#include <pjmedia/alaw_ulaw.h>\n#include <pjmedia/avi_stream.h>\n#include <pjmedia/bidirectional.h>\n#include <pjmedia/circbuf.h>\n#include <pjmedia/clock.h>\n#include <pjmedia/codec.h>\n#include <pjmedia/conference.h>\n#include <pjmedia/converter.h>\n#include <pjmedia/delaybuf.h>\n#include <pjmedia/echo.h>\n#include <pjmedia/echo_port.h>\n#include <pjmedia/endpoint.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/event.h>\n#include <pjmedia/frame.h>\n#include <pjmedia/format.h>\n#include <pjmedia/g711.h>\n#include <pjmedia/jbuf.h>\n#include <pjmedia/master_port.h>\n#include <pjmedia/mem_port.h>\n#include <pjmedia/mixer_port.h>\n#include <pjmedia/null_port.h>\n#include <pjmedia/plc.h>\n#include <pjmedia/port.h>\n#include <pjmedia/resample.h>\n#include <pjmedia/rtcp.h>\n#include <pjmedia/rtcp_xr.h>\n#include <pjmedia/rtp.h>\n#include <pjmedia/sdp.h>\n#include <pjmedia/sdp_neg.h>\n//#include <pjmedia/session.h>\n#include <pjmedia/silencedet.h>\n#include <pjmedia/sound.h>\n#include <pjmedia/sound_port.h>\n#include <pjmedia/splitcomb.h>\n#include <pjmedia/stereo.h>\n#include <pjmedia/stream.h>\n#include <pjmedia/stream_common.h>\n#include <pjmedia/tonegen.h>\n#include <pjmedia/transport.h>\n#include <pjmedia/transport_adapter_sample.h>\n#include <pjmedia/transport_ice.h>\n#include <pjmedia/transport_loop.h>\n#include <pjmedia/transport_srtp.h>\n#include <pjmedia/transport_zrtp.h>\n#include <pjmedia/transport_udp.h>\n#include <pjmedia/vid_port.h>\n#include <pjmedia/vid_codec.h>\n#include <pjmedia/vid_stream.h>\n#include <pjmedia/vid_tee.h>\n#include <pjmedia/wav_playlist.h>\n#include <pjmedia/wav_port.h>\n#include <pjmedia/wave.h>\n#include <pjmedia/wsola.h>\n\n#endif\t/* __PJMEDIA_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia_audiodev.h",
    "content": "/* $Id: pjmedia_audiodev.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_AUDIODEV_H__\n#define __PJMEDIA_AUDIODEV_H__\n\n/**\n * @file pjmedia_audiodev.h\n * @brief PJMEDIA main header file.\n */\n\n#include <pjmedia-audiodev/audiodev.h>\n#include <pjmedia-audiodev/audiodev_imp.h>\n\n#endif\t/* __PJMEDIA_AUDIODEV_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/include/pjmedia_videodev.h",
    "content": "/* $Id: pjmedia_videodev.h 4016 2012-04-04 05:05:50Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_VIDEODEV_H__\n#define __PJMEDIA_VIDEODEV_H__\n\n/**\n * @file pjmedia_videodev.h\n * @brief PJMEDIA main header file.\n */\n\n#include <pjmedia-videodev/videodev.h>\n#include <pjmedia-videodev/videodev_imp.h>\n#include <pjmedia-videodev/avi_dev.h>\n#include <pjmedia-videodev/fb_dev.h>\n\n#endif\t/* __PJMEDIA_VIDEODEV_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/alaw_ulaw.c",
    "content": "/*\n * This source code is a product of Sun Microsystems, Inc. and is provided\n * for unrestricted use.  Users may copy or modify this source code without\n * charge.\n *\n * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING\n * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR\n * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.\n *\n * Sun source code is provided with no support and without any obligation on\n * the part of Sun Microsystems, Inc. to assist in its use, correction,\n * modification or enhancement.\n *\n * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE\n * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE\n * OR ANY PART THEREOF.\n *\n * In no event will Sun Microsystems, Inc. be liable for any lost revenue\n * or profits or other special, indirect and consequential damages, even if\n * Sun has been advised of the possibility of such damages.\n *\n * Sun Microsystems, Inc.\n * 2550 Garcia Avenue\n * Mountain View, California  94043\n */\n#include <pjmedia/alaw_ulaw.h>\n\n#if !defined(PJMEDIA_HAS_ALAW_ULAW_TABLE) || PJMEDIA_HAS_ALAW_ULAW_TABLE==0\n\n#ifdef _MSC_VER\n#  pragma warning ( disable: 4244 ) /* Conversion from int to char etc */\n#endif\n\n/*\n * g711.c\n *\n * u-law, A-law and linear PCM conversions.\n */\n#define\tSIGN_BIT\t(0x80)\t\t/* Sign bit for a A-law byte. */\n#define\tQUANT_MASK\t(0xf)\t\t/* Quantization field mask. */\n#define\tNSEGS\t\t(8)\t\t/* Number of A-law segments. */\n#define\tSEG_SHIFT\t(4)\t\t/* Left shift for segment number. */\n#define\tSEG_MASK\t(0x70)\t\t/* Segment field mask. */\n\nstatic short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,\n\t\t\t    0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};\n\n/* copy from CCITT G.711 specifications */\nstatic unsigned char _u2a[128] = {\t\t/* u- to A-law conversions */\n\t1,\t1,\t2,\t2,\t3,\t3,\t4,\t4,\n\t5,\t5,\t6,\t6,\t7,\t7,\t8,\t8,\n\t9,\t10,\t11,\t12,\t13,\t14,\t15,\t16,\n\t17,\t18,\t19,\t20,\t21,\t22,\t23,\t24,\n\t25,\t27,\t29,\t31,\t33,\t34,\t35,\t36,\n\t37,\t38,\t39,\t40,\t41,\t42,\t43,\t44,\n\t46,\t48,\t49,\t50,\t51,\t52,\t53,\t54,\n\t55,\t56,\t57,\t58,\t59,\t60,\t61,\t62,\n\t64,\t65,\t66,\t67,\t68,\t69,\t70,\t71,\n\t72,\t73,\t74,\t75,\t76,\t77,\t78,\t79,\n\t81,\t82,\t83,\t84,\t85,\t86,\t87,\t88,\n\t89,\t90,\t91,\t92,\t93,\t94,\t95,\t96,\n\t97,\t98,\t99,\t100,\t101,\t102,\t103,\t104,\n\t105,\t106,\t107,\t108,\t109,\t110,\t111,\t112,\n\t113,\t114,\t115,\t116,\t117,\t118,\t119,\t120,\n\t121,\t122,\t123,\t124,\t125,\t126,\t127,\t128};\n\nstatic unsigned char _a2u[128] = {\t\t/* A- to u-law conversions */\n\t1,\t3,\t5,\t7,\t9,\t11,\t13,\t15,\n\t16,\t17,\t18,\t19,\t20,\t21,\t22,\t23,\n\t24,\t25,\t26,\t27,\t28,\t29,\t30,\t31,\n\t32,\t32,\t33,\t33,\t34,\t34,\t35,\t35,\n\t36,\t37,\t38,\t39,\t40,\t41,\t42,\t43,\n\t44,\t45,\t46,\t47,\t48,\t48,\t49,\t49,\n\t50,\t51,\t52,\t53,\t54,\t55,\t56,\t57,\n\t58,\t59,\t60,\t61,\t62,\t63,\t64,\t64,\n\t65,\t66,\t67,\t68,\t69,\t70,\t71,\t72,\n\t73,\t74,\t75,\t76,\t77,\t78,\t79,\t79,\n\t80,\t81,\t82,\t83,\t84,\t85,\t86,\t87,\n\t88,\t89,\t90,\t91,\t92,\t93,\t94,\t95,\n\t96,\t97,\t98,\t99,\t100,\t101,\t102,\t103,\n\t104,\t105,\t106,\t107,\t108,\t109,\t110,\t111,\n\t112,\t113,\t114,\t115,\t116,\t117,\t118,\t119,\n\t120,\t121,\t122,\t123,\t124,\t125,\t126,\t127};\n\nstatic int\nsearch(\n\tint\t\tval,\n\tshort\t\t*table,\n\tint\t\tsize)\n{\n\tint\t\ti;\n\n\tfor (i = 0; i < size; i++) {\n\t\tif (val <= *table++)\n\t\t\treturn (i);\n\t}\n\treturn (size);\n}\n\n/*\n * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law\n *\n * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.\n *\n *\t\tLinear Input Code\tCompressed Code\n *\t------------------------\t---------------\n *\t0000000wxyza\t\t\t000wxyz\n *\t0000001wxyza\t\t\t001wxyz\n *\t000001wxyzab\t\t\t010wxyz\n *\t00001wxyzabc\t\t\t011wxyz\n *\t0001wxyzabcd\t\t\t100wxyz\n *\t001wxyzabcde\t\t\t101wxyz\n *\t01wxyzabcdef\t\t\t110wxyz\n *\t1wxyzabcdefg\t\t\t111wxyz\n *\n * For further information see John C. Bellamy's Digital Telephony, 1982,\n * John Wiley & Sons, pps 98-111 and 472-476.\n */\nPJ_DEF(pj_uint8_t) pjmedia_linear2alaw(\n\tint\t\tpcm_val)\t/* 2's complement (16-bit range) */\n{\n\tint\t\tmask;\n\tint\t\tseg;\n\tunsigned char\taval;\n\n\tif (pcm_val >= 0) {\n\t\tmask = 0xD5;\t\t/* sign (7th) bit = 1 */\n\t} else {\n\t\tmask = 0x55;\t\t/* sign bit = 0 */\n\t\tpcm_val = -pcm_val - 8;\n\n\t\t/* https://trac.pjsip.org/repos/ticket/1301 \n\t\t * Thank you K Johnson - Zetron - 27 May 2011\n\t\t */\n\t\tif (pcm_val < 0)\n\t\t    pcm_val = 0;\n\t}\n\n\t/* Convert the scaled magnitude to segment number. */\n\tseg = search(pcm_val, seg_end, 8);\n\n\t/* Combine the sign, segment, and quantization bits. */\n\n\tif (seg >= 8)\t\t/* out of range, return maximum value. */\n\t\treturn (0x7F ^ mask);\n\telse {\n\t\taval = seg << SEG_SHIFT;\n\t\tif (seg < 2)\n\t\t\taval |= (pcm_val >> 4) & QUANT_MASK;\n\t\telse\n\t\t\taval |= (pcm_val >> (seg + 3)) & QUANT_MASK;\n\t\treturn (aval ^ mask);\n\t}\n}\n\n/*\n * alaw2linear() - Convert an A-law value to 16-bit linear PCM\n *\n */\nPJ_DEF(int) pjmedia_alaw2linear(\n\tunsigned a_val)\n{\n\tint\t\tt;\n\tint\t\tseg;\n\n\ta_val ^= 0x55;\n\n\tt = (a_val & QUANT_MASK) << 4;\n\tseg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;\n\tswitch (seg) {\n\tcase 0:\n\t\tt += 8;\n\t\tbreak;\n\tcase 1:\n\t\tt += 0x108;\n\t\tbreak;\n\tdefault:\n\t\tt += 0x108;\n\t\tt <<= seg - 1;\n\t}\n\treturn ((a_val & SIGN_BIT) ? t : -t);\n}\n\n#define\tBIAS\t\t(0x84)\t\t/* Bias for linear code. */\n\n/*\n * linear2ulaw() - Convert a linear PCM value to u-law\n *\n * In order to simplify the encoding process, the original linear magnitude\n * is biased by adding 33 which shifts the encoding range from (0 - 8158) to\n * (33 - 8191). The result can be seen in the following encoding table:\n *\n *\tBiased Linear Input Code\tCompressed Code\n *\t------------------------\t---------------\n *\t00000001wxyza\t\t\t000wxyz\n *\t0000001wxyzab\t\t\t001wxyz\n *\t000001wxyzabc\t\t\t010wxyz\n *\t00001wxyzabcd\t\t\t011wxyz\n *\t0001wxyzabcde\t\t\t100wxyz\n *\t001wxyzabcdef\t\t\t101wxyz\n *\t01wxyzabcdefg\t\t\t110wxyz\n *\t1wxyzabcdefgh\t\t\t111wxyz\n *\n * Each biased linear code has a leading 1 which identifies the segment\n * number. The value of the segment number is equal to 7 minus the number\n * of leading 0's. The quantization interval is directly available as the\n * four bits wxyz.  * The trailing bits (a - h) are ignored.\n *\n * Ordinarily the complement of the resulting code word is used for\n * transmission, and so the code word is complemented before it is returned.\n *\n * For further information see John C. Bellamy's Digital Telephony, 1982,\n * John Wiley & Sons, pps 98-111 and 472-476.\n */\nPJ_DEF(unsigned char) pjmedia_linear2ulaw(\n\tint\t\tpcm_val)\t/* 2's complement (16-bit range) */\n{\n\tint\t\tmask;\n\tint\t\tseg;\n\tunsigned char\tuval;\n\n\t/* Get the sign and the magnitude of the value. */\n\tif (pcm_val < 0) {\n\t\tpcm_val = BIAS - pcm_val;\n\t\tmask = 0x7F;\n\t} else {\n\t\tpcm_val += BIAS;\n\t\tmask = 0xFF;\n\t}\n\n\t/* Convert the scaled magnitude to segment number. */\n\tseg = search(pcm_val, seg_end, 8);\n\n\t/*\n\t * Combine the sign, segment, quantization bits;\n\t * and complement the code word.\n\t */\n\tif (seg >= 8)\t\t/* out of range, return maximum value. */\n\t\treturn (0x7F ^ mask);\n\telse {\n\t\tuval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);\n\t\treturn (uval ^ mask);\n\t}\n\n}\n\n/*\n * ulaw2linear() - Convert a u-law value to 16-bit linear PCM\n *\n * First, a biased linear code is derived from the code word. An unbiased\n * output can then be obtained by subtracting 33 from the biased code.\n *\n * Note that this function expects to be passed the complement of the\n * original code word. This is in keeping with ISDN conventions.\n */\nPJ_DEF(int) pjmedia_ulaw2linear(\n\tunsigned char\tu_val)\n{\n\tint\t\tt;\n\n\t/* Shortcut: when input is zero, output is zero \n\t * This will also make the VAD works harder.\n\t *  -bennylp\n\t */\n\tif (u_val == 0) return 0;\n\n\t/* Complement to obtain normal u-law value. */\n\tu_val = ~u_val;\n\n\t/*\n\t * Extract and bias the quantization bits. Then\n\t * shift up by the segment number and subtract out the bias.\n\t */\n\tt = ((u_val & QUANT_MASK) << 3) + BIAS;\n\tt <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;\n\n\treturn ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));\n}\n\n/* A-law to u-law conversion */\nPJ_DEF(unsigned char) pjmedia_alaw2ulaw(\n\tunsigned char\taval)\n{\n\taval &= 0xff;\n\treturn ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :\n\t    (0x7F ^ _a2u[aval ^ 0x55]));\n}\n\n/* u-law to A-law conversion */\nPJ_DEF(unsigned char) pjmedia_ulaw2alaw(\n\tunsigned char\tuval)\n{\n\tuval &= 0xff;\n\treturn ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :\n\t    (0x55 ^ (_u2a[0x7F ^ uval] - 1)));\n}\n\n\n#endif\t/* PJMEDIA_HAS_ALAW_ULAW_TABLE */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/alaw_ulaw_table.c",
    "content": "/* $Id: alaw_ulaw_table.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * The tables here and also the conversion ideas are contributed by \n * Toni Rutar <toni at aufbix.org>. Many thanks!\n */\n#include <pjmedia/alaw_ulaw.h>\n\n#if defined(PJMEDIA_HAS_ALAW_ULAW_TABLE) && PJMEDIA_HAS_ALAW_ULAW_TABLE!=0\n\nconst pj_uint8_t pjmedia_linear2ulaw_tab[16384] = \n{\n    0xff,0xfe,0xfe,0xfd,0xfd,0xfc,0xfc,0xfb,\n    0xfb,0xfa,0xfa,0xf9,0xf9,0xf8,0xf8,0xf7,\n    0xf7,0xf6,0xf6,0xf5,0xf5,0xf4,0xf4,0xf3,\n    0xf3,0xf2,0xf2,0xf1,0xf1,0xf0,0xf0,0xef,\n    0xef,0xef,0xef,0xee,0xee,0xee,0xee,0xed,\n    0xed,0xed,0xed,0xec,0xec,0xec,0xec,0xeb,\n    0xeb,0xeb,0xeb,0xea,0xea,0xea,0xea,0xe9,\n    0xe9,0xe9,0xe9,0xe8,0xe8,0xe8,0xe8,0xe7,\n    0xe7,0xe7,0xe7,0xe6,0xe6,0xe6,0xe6,0xe5,\n    0xe5,0xe5,0xe5,0xe4,0xe4,0xe4,0xe4,0xe3,\n    0xe3,0xe3,0xe3,0xe2,0xe2,0xe2,0xe2,0xe1,\n    0xe1,0xe1,0xe1,0xe0,0xe0,0xe0,0xe0,0xdf,\n    0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xde,\n    0xde,0xde,0xde,0xde,0xde,0xde,0xde,0xdd,\n    0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdc,\n    0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdb,\n    0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xda,\n    0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xd9,\n    0xd9,0xd9,0xd9,0xd9,0xd9,0xd9,0xd9,0xd8,\n    0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd7,\n    0xd7,0xd7,0xd7,0xd7,0xd7,0xd7,0xd7,0xd6,\n    0xd6,0xd6,0xd6,0xd6,0xd6,0xd6,0xd6,0xd5,\n    0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd4,\n    0xd4,0xd4,0xd4,0xd4,0xd4,0xd4,0xd4,0xd3,\n    0xd3,0xd3,0xd3,0xd3,0xd3,0xd3,0xd3,0xd2,\n    0xd2,0xd2,0xd2,0xd2,0xd2,0xd2,0xd2,0xd1,\n    0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd0,\n    0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xcf,\n    0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,\n    0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xce,\n    0xce,0xce,0xce,0xce,0xce,0xce,0xce,0xce,\n    0xce,0xce,0xce,0xce,0xce,0xce,0xce,0xcd,\n    0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,\n    0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcc,\n    0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,\n    0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcb,\n    0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,\n    0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xca,\n    0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,\n    0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xc9,\n    0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,\n    0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc8,\n    0xc8,0xc8,0xc8,0xc8,0xc8,0xc8,0xc8,0xc8,\n    0xc8,0xc8,0xc8,0xc8,0xc8,0xc8,0xc8,0xc7,\n    0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,\n    0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc6,\n    0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,\n    0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc5,\n    0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,\n    0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc4,\n    0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,\n    0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc3,\n    0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,\n    0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc2,\n    0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,\n    0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc1,\n    0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,\n    0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc0,\n    0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,\n    0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xbf,\n    0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,\n    0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,\n    0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,\n    0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbe,\n    0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,\n    0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,\n    0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,\n    0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbd,\n    0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,\n    0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,\n    0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,\n    0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbc,\n    0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,\n    0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,\n    0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,\n    0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbb,\n    0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,\n    0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,\n    0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,\n    0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xba,\n    0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,\n    0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,\n    0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,\n    0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xb9,\n    0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,\n    0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,\n    0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,\n    0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb8,\n    0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,\n    0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,\n    0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,\n    0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb7,\n    0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,\n    0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,\n    0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,\n    0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb6,\n    0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,\n    0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,\n    0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,\n    0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb5,\n    0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,\n    0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,\n    0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,\n    0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb4,\n    0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,\n    0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,\n    0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,\n    0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb3,\n    0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,\n    0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,\n    0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,\n    0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb2,\n    0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,\n    0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,\n    0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,\n    0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb1,\n    0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,\n    0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,\n    0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,\n    0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb0,\n    0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,\n    0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,\n    0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,\n    0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xaf,\n    0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,\n    0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,\n    0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,\n    0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,\n    0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,\n    0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,\n    0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,\n    0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xae,\n    0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,\n    0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,\n    0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,\n    0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,\n    0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,\n    0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,\n    0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,\n    0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xad,\n    0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,\n    0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,\n    0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,\n    0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,\n    0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,\n    0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,\n    0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,\n    0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xac,\n    0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,\n    0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,\n    0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,\n    0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,\n    0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,\n    0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,\n    0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,\n    0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xab,\n    0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,\n    0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,\n    0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,\n    0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,\n    0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,\n    0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,\n    0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,\n    0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xaa,\n    0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\n    0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\n    0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\n    0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\n    0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\n    0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\n    0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\n    0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xa9,\n    0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,\n    0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,\n    0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,\n    0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,\n    0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,\n    0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,\n    0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,\n    0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa8,\n    0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,\n    0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,\n    0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,\n    0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,\n    0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,\n    0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,\n    0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,\n    0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa7,\n    0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,\n    0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,\n    0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,\n    0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,\n    0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,\n    0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,\n    0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,\n    0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa6,\n    0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,\n    0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,\n    0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,\n    0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,\n    0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,\n    0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,\n    0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,\n    0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa5,\n    0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,\n    0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,\n    0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,\n    0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,\n    0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,\n    0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,\n    0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,\n    0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa4,\n    0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,\n    0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,\n    0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,\n    0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,\n    0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,\n    0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,\n    0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,\n    0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa3,\n    0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,\n    0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,\n    0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,\n    0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,\n    0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,\n    0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,\n    0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,\n    0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa2,\n    0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,\n    0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,\n    0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,\n    0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,\n    0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,\n    0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,\n    0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,\n    0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa1,\n    0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,\n    0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,\n    0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,\n    0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,\n    0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,\n    0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,\n    0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,\n    0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa0,\n    0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,\n    0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,\n    0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,\n    0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,\n    0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,\n    0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,\n    0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,\n    0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,\n    0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,\n    0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,\n    0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,\n    0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,\n    0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,\n    0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n    0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n    0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n    0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n    0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n    0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n    0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n    0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n    0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n    0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n    0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,\n    0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,\n    0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,\n    0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,\n    0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,\n    0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,\n    0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n    0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n    0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n    0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n    0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n    0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n    0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n    0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n    0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n    0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n    0x03,0x03,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n    0x04,0x04,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n    0x05,0x05,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n    0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n    0x07,0x07,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n    0x08,0x08,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n    0x09,0x09,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,\n    0x0a,0x0a,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,\n    0x0b,0x0b,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,\n    0x0c,0x0c,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,\n    0x0d,0x0d,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,\n    0x0e,0x0e,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,\n    0x0f,0x0f,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n    0x10,0x10,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n    0x11,0x11,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n    0x12,0x12,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n    0x13,0x13,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n    0x14,0x14,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n    0x15,0x15,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n    0x16,0x16,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n    0x17,0x17,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n    0x18,0x18,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n    0x19,0x19,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,\n    0x1a,0x1a,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,\n    0x1b,0x1b,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,\n    0x1c,0x1c,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,\n    0x1d,0x1d,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,\n    0x1e,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,\n    0x1f,0x1f,0x20,0x20,0x20,0x20,0x20,0x20,\n    0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n    0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n    0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n    0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n    0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n    0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n    0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n    0x20,0x20,0x21,0x21,0x21,0x21,0x21,0x21,\n    0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n    0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n    0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n    0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n    0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n    0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n    0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n    0x21,0x21,0x22,0x22,0x22,0x22,0x22,0x22,\n    0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n    0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n    0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n    0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n    0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n    0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n    0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n    0x22,0x22,0x23,0x23,0x23,0x23,0x23,0x23,\n    0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n    0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n    0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n    0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n    0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n    0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n    0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n    0x23,0x23,0x24,0x24,0x24,0x24,0x24,0x24,\n    0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n    0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n    0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n    0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n    0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n    0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n    0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n    0x24,0x24,0x25,0x25,0x25,0x25,0x25,0x25,\n    0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n    0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n    0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n    0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n    0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n    0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n    0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n    0x25,0x25,0x26,0x26,0x26,0x26,0x26,0x26,\n    0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n    0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n    0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n    0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n    0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n    0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n    0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n    0x26,0x26,0x27,0x27,0x27,0x27,0x27,0x27,\n    0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n    0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n    0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n    0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n    0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n    0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n    0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n    0x27,0x27,0x28,0x28,0x28,0x28,0x28,0x28,\n    0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n    0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n    0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n    0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n    0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n    0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n    0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n    0x28,0x28,0x29,0x29,0x29,0x29,0x29,0x29,\n    0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n    0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n    0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n    0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n    0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n    0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n    0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n    0x29,0x29,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,\n    0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,\n    0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,\n    0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,\n    0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,\n    0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,\n    0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,\n    0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,\n    0x2a,0x2a,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,\n    0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,\n    0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,\n    0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,\n    0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,\n    0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,\n    0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,\n    0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,\n    0x2b,0x2b,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,\n    0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,\n    0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,\n    0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,\n    0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,\n    0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,\n    0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,\n    0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,\n    0x2c,0x2c,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,\n    0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,\n    0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,\n    0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,\n    0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,\n    0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,\n    0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,\n    0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,\n    0x2d,0x2d,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,\n    0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,\n    0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,\n    0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,\n    0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,\n    0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,\n    0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,\n    0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,\n    0x2e,0x2e,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,\n    0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,\n    0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,\n    0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,\n    0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,\n    0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,\n    0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,\n    0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,\n    0x2f,0x2f,0x30,0x30,0x30,0x30,0x30,0x30,\n    0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n    0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n    0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n    0x30,0x30,0x31,0x31,0x31,0x31,0x31,0x31,\n    0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n    0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n    0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n    0x31,0x31,0x32,0x32,0x32,0x32,0x32,0x32,\n    0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n    0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n    0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n    0x32,0x32,0x33,0x33,0x33,0x33,0x33,0x33,\n    0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n    0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n    0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n    0x33,0x33,0x34,0x34,0x34,0x34,0x34,0x34,\n    0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n    0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n    0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n    0x34,0x34,0x35,0x35,0x35,0x35,0x35,0x35,\n    0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n    0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n    0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n    0x35,0x35,0x36,0x36,0x36,0x36,0x36,0x36,\n    0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n    0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n    0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n    0x36,0x36,0x37,0x37,0x37,0x37,0x37,0x37,\n    0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n    0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n    0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n    0x37,0x37,0x38,0x38,0x38,0x38,0x38,0x38,\n    0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n    0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n    0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n    0x38,0x38,0x39,0x39,0x39,0x39,0x39,0x39,\n    0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n    0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n    0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n    0x39,0x39,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,\n    0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,\n    0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,\n    0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,\n    0x3a,0x3a,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,\n    0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,\n    0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,\n    0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,\n    0x3b,0x3b,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,\n    0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,\n    0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,\n    0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,\n    0x3c,0x3c,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,\n    0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,\n    0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,\n    0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,\n    0x3d,0x3d,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,\n    0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,\n    0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,\n    0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,\n    0x3e,0x3e,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,\n    0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,\n    0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,\n    0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,\n    0x3f,0x3f,0x40,0x40,0x40,0x40,0x40,0x40,\n    0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,\n    0x40,0x40,0x41,0x41,0x41,0x41,0x41,0x41,\n    0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,\n    0x41,0x41,0x42,0x42,0x42,0x42,0x42,0x42,\n    0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,\n    0x42,0x42,0x43,0x43,0x43,0x43,0x43,0x43,\n    0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,\n    0x43,0x43,0x44,0x44,0x44,0x44,0x44,0x44,\n    0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,\n    0x44,0x44,0x45,0x45,0x45,0x45,0x45,0x45,\n    0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,\n    0x45,0x45,0x46,0x46,0x46,0x46,0x46,0x46,\n    0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,\n    0x46,0x46,0x47,0x47,0x47,0x47,0x47,0x47,\n    0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,\n    0x47,0x47,0x48,0x48,0x48,0x48,0x48,0x48,\n    0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,\n    0x48,0x48,0x49,0x49,0x49,0x49,0x49,0x49,\n    0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,\n    0x49,0x49,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,\n    0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,\n    0x4a,0x4a,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,\n    0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,\n    0x4b,0x4b,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,\n    0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,\n    0x4c,0x4c,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,\n    0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,\n    0x4d,0x4d,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,\n    0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,\n    0x4e,0x4e,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,\n    0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,\n    0x4f,0x4f,0x50,0x50,0x50,0x50,0x50,0x50,\n    0x50,0x50,0x51,0x51,0x51,0x51,0x51,0x51,\n    0x51,0x51,0x52,0x52,0x52,0x52,0x52,0x52,\n    0x52,0x52,0x53,0x53,0x53,0x53,0x53,0x53,\n    0x53,0x53,0x54,0x54,0x54,0x54,0x54,0x54,\n    0x54,0x54,0x55,0x55,0x55,0x55,0x55,0x55,\n    0x55,0x55,0x56,0x56,0x56,0x56,0x56,0x56,\n    0x56,0x56,0x57,0x57,0x57,0x57,0x57,0x57,\n    0x57,0x57,0x58,0x58,0x58,0x58,0x58,0x58,\n    0x58,0x58,0x59,0x59,0x59,0x59,0x59,0x59,\n    0x59,0x59,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,\n    0x5a,0x5a,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,\n    0x5b,0x5b,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,\n    0x5c,0x5c,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,\n    0x5d,0x5d,0x5e,0x5e,0x5e,0x5e,0x5e,0x5e,\n    0x5e,0x5e,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,\n    0x5f,0x5f,0x60,0x60,0x60,0x60,0x61,0x61,\n    0x61,0x61,0x62,0x62,0x62,0x62,0x63,0x63,\n    0x63,0x63,0x64,0x64,0x64,0x64,0x65,0x65,\n    0x65,0x65,0x66,0x66,0x66,0x66,0x67,0x67,\n    0x67,0x67,0x68,0x68,0x68,0x68,0x69,0x69,\n    0x69,0x69,0x6a,0x6a,0x6a,0x6a,0x6b,0x6b,\n    0x6b,0x6b,0x6c,0x6c,0x6c,0x6c,0x6d,0x6d,\n    0x6d,0x6d,0x6e,0x6e,0x6e,0x6e,0x6f,0x6f,\n    0x6f,0x6f,0x70,0x70,0x71,0x71,0x72,0x72,\n    0x73,0x73,0x74,0x74,0x75,0x75,0x76,0x76,\n    0x77,0x77,0x78,0x78,0x79,0x79,0x7a,0x7a,\n    0x7b,0x7b,0x7c,0x7c,0x7d,0x7d,0x7e,0x7e\n};\n\n\nconst pj_uint8_t pjmedia_linear2alaw_tab[16384] = \n{\n     0xD5,0xD5,0xD5,0xD5,0xD4,0xD4,0xD4,0xD4,\n     0xD7,0xD7,0xD7,0xD7,0xD6,0xD6,0xD6,0xD6,\n     0xD1,0xD1,0xD1,0xD1,0xD0,0xD0,0xD0,0xD0,\n     0xD3,0xD3,0xD3,0xD3,0xD2,0xD2,0xD2,0xD2,\n     0xDD,0xDD,0xDD,0xDD,0xDC,0xDC,0xDC,0xDC,\n     0xDF,0xDF,0xDF,0xDF,0xDE,0xDE,0xDE,0xDE,\n     0xD9,0xD9,0xD9,0xD9,0xD8,0xD8,0xD8,0xD8,\n     0xDB,0xDB,0xDB,0xDB,0xDA,0xDA,0xDA,0xDA,\n     0xC5,0xC5,0xC5,0xC5,0xC4,0xC4,0xC4,0xC4,\n     0xC7,0xC7,0xC7,0xC7,0xC6,0xC6,0xC6,0xC6,\n     0xC1,0xC1,0xC1,0xC1,0xC0,0xC0,0xC0,0xC0,\n     0xC3,0xC3,0xC3,0xC3,0xC2,0xC2,0xC2,0xC2,\n     0xCD,0xCD,0xCD,0xCD,0xCC,0xCC,0xCC,0xCC,\n     0xCF,0xCF,0xCF,0xCF,0xCE,0xCE,0xCE,0xCE,\n     0xC9,0xC9,0xC9,0xC9,0xC8,0xC8,0xC8,0xC8,\n     0xCB,0xCB,0xCB,0xCB,0xCA,0xCA,0xCA,0xCA,\n     0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,\n     0xF4,0xF4,0xF4,0xF4,0xF4,0xF4,0xF4,0xF4,\n     0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,\n     0xF6,0xF6,0xF6,0xF6,0xF6,0xF6,0xF6,0xF6,\n     0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,\n     0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,\n     0xF3,0xF3,0xF3,0xF3,0xF3,0xF3,0xF3,0xF3,\n     0xF2,0xF2,0xF2,0xF2,0xF2,0xF2,0xF2,0xF2,\n     0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,\n     0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,\n     0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,\n     0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,\n     0xF9,0xF9,0xF9,0xF9,0xF9,0xF9,0xF9,0xF9,\n     0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,\n     0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,\n     0xFA,0xFA,0xFA,0xFA,0xFA,0xFA,0xFA,0xFA,\n     0xE5,0xE5,0xE5,0xE5,0xE5,0xE5,0xE5,0xE5,\n     0xE5,0xE5,0xE5,0xE5,0xE5,0xE5,0xE5,0xE5,\n     0xE4,0xE4,0xE4,0xE4,0xE4,0xE4,0xE4,0xE4,\n     0xE4,0xE4,0xE4,0xE4,0xE4,0xE4,0xE4,0xE4,\n     0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,\n     0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,\n     0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,\n     0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,\n     0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,\n     0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,\n     0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,\n     0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,\n     0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,\n     0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,\n     0xE2,0xE2,0xE2,0xE2,0xE2,0xE2,0xE2,0xE2,\n     0xE2,0xE2,0xE2,0xE2,0xE2,0xE2,0xE2,0xE2,\n     0xED,0xED,0xED,0xED,0xED,0xED,0xED,0xED,\n     0xED,0xED,0xED,0xED,0xED,0xED,0xED,0xED,\n     0xEC,0xEC,0xEC,0xEC,0xEC,0xEC,0xEC,0xEC,\n     0xEC,0xEC,0xEC,0xEC,0xEC,0xEC,0xEC,0xEC,\n     0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,\n     0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,\n     0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,\n     0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,\n     0xE9,0xE9,0xE9,0xE9,0xE9,0xE9,0xE9,0xE9,\n     0xE9,0xE9,0xE9,0xE9,0xE9,0xE9,0xE9,0xE9,\n     0xE8,0xE8,0xE8,0xE8,0xE8,0xE8,0xE8,0xE8,\n     0xE8,0xE8,0xE8,0xE8,0xE8,0xE8,0xE8,0xE8,\n     0xEB,0xEB,0xEB,0xEB,0xEB,0xEB,0xEB,0xEB,\n     0xEB,0xEB,0xEB,0xEB,0xEB,0xEB,0xEB,0xEB,\n     0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,\n     0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,\n     0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n     0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n     0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n     0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,\n     0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n     0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n     0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n     0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,\n     0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n     0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n     0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n     0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,\n     0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n     0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n     0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n     0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,\n     0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n     0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n     0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n     0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,\n     0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n     0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n     0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n     0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,\n     0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n     0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n     0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n     0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,\n     0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n     0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n     0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n     0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,\n     0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,\n     0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,\n     0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,\n     0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,\n     0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,\n     0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,\n     0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,\n     0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,\n     0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,\n     0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,\n     0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,\n     0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,\n     0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,\n     0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,\n     0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,\n     0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,\n     0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n     0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n     0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n     0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,\n     0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n     0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n     0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n     0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,\n     0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,\n     0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,\n     0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,\n     0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,\n     0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,\n     0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,\n     0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,\n     0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,\n     0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n     0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n     0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n     0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n     0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n     0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n     0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n     0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,\n     0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n     0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n     0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n     0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n     0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n     0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n     0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n     0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,\n     0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n     0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n     0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n     0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n     0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n     0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n     0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n     0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,\n     0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n     0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n     0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n     0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n     0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n     0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n     0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n     0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,\n     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,\n     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,\n     0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n     0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n     0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n     0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n     0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n     0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n     0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n     0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,\n     0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n     0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n     0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n     0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n     0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n     0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n     0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n     0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n     0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,\n     0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,\n     0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,\n     0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,\n     0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,\n     0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,\n     0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,\n     0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,\n     0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,\n     0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,\n     0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,\n     0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,\n     0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,\n     0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,\n     0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,\n     0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,\n     0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,\n     0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,\n     0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,\n     0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,\n     0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,\n     0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,\n     0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,\n     0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,\n     0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,\n     0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,\n     0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,\n     0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,\n     0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,\n     0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,\n     0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,\n     0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,\n     0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n     0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n     0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n     0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n     0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n     0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n     0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n     0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,\n     0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n     0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n     0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n     0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n     0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n     0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n     0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n     0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,\n     0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,\n     0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,\n     0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,\n     0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,\n     0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,\n     0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,\n     0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,\n     0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,\n     0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,\n     0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,\n     0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,\n     0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,\n     0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,\n     0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,\n     0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,\n     0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,\n     0x2A,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,\n     0x2B,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,\n     0x28,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,\n     0x29,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,\n     0x2E,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,\n     0x2F,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,\n     0x2C,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,\n     0x2D,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,\n     0x22,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,\n     0x23,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n     0x20,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,\n     0x21,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,\n     0x26,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,\n     0x27,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,\n     0x24,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,\n     0x25,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,\n     0x3A,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,\n     0x3B,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,\n     0x38,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,\n     0x39,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,\n     0x3E,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,\n     0x3F,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,\n     0x3C,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,\n     0x3D,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,\n     0x32,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,\n     0x33,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,\n     0x30,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,\n     0x31,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,\n     0x36,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,\n     0x37,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,\n     0x34,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,\n     0x35,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,\n     0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,\n     0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,\n     0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,\n     0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,\n     0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,\n     0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,\n     0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,\n     0x0A,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,\n     0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,\n     0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,\n     0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,\n     0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,\n     0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,\n     0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,\n     0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,\n     0x0B,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n     0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n     0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n     0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n     0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n     0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n     0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n     0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\n     0x08,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n     0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n     0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n     0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n     0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n     0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n     0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n     0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\n     0x09,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,\n     0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,\n     0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,\n     0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,\n     0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,\n     0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,\n     0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,\n     0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,\n     0x0E,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,\n     0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,\n     0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,\n     0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,\n     0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,\n     0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,\n     0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,\n     0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,\n     0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,\n     0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,\n     0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,\n     0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,\n     0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,\n     0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,\n     0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,\n     0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,\n     0x0C,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,\n     0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,\n     0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,\n     0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,\n     0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,\n     0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,\n     0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,\n     0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,\n     0x0D,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n     0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n     0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n     0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n     0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n     0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n     0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n     0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n     0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n     0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n     0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n     0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n     0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n     0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n     0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n     0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\n     0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n     0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n     0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n     0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n     0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n     0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n     0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n     0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n     0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\n     0x01,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n     0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n     0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n     0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n     0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n     0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n     0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n     0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\n     0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n     0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n     0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n     0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n     0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n     0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n     0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n     0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\n     0x07,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n     0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n     0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n     0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n     0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n     0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n     0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n     0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\n     0x04,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n     0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n     0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n     0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n     0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n     0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n     0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n     0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\n     0x05,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,\n     0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,\n     0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,\n     0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,\n     0x1A,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,\n     0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,\n     0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,\n     0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,\n     0x1B,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n     0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n     0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n     0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\n     0x18,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n     0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n     0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n     0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\n     0x19,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,\n     0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,\n     0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,\n     0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,\n     0x1E,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,\n     0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,\n     0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,\n     0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,\n     0x1F,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,\n     0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,\n     0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,\n     0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,\n     0x1C,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,\n     0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,\n     0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,\n     0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,\n     0x1D,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n     0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n     0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n     0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\n     0x12,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n     0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n     0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n     0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\n     0x13,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n     0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n     0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n     0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n     0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n     0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n     0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n     0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\n     0x11,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n     0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n     0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n     0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\n     0x16,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n     0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n     0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n     0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\n     0x17,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n     0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n     0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n     0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\n     0x14,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n     0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n     0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n     0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\n     0x15,0x6A,0x6A,0x6A,0x6A,0x6A,0x6A,0x6A,\n     0x6A,0x6A,0x6A,0x6A,0x6A,0x6A,0x6A,0x6A,\n     0x6A,0x6B,0x6B,0x6B,0x6B,0x6B,0x6B,0x6B,\n     0x6B,0x6B,0x6B,0x6B,0x6B,0x6B,0x6B,0x6B,\n     0x6B,0x68,0x68,0x68,0x68,0x68,0x68,0x68,\n     0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,\n     0x68,0x69,0x69,0x69,0x69,0x69,0x69,0x69,\n     0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,\n     0x69,0x6E,0x6E,0x6E,0x6E,0x6E,0x6E,0x6E,\n     0x6E,0x6E,0x6E,0x6E,0x6E,0x6E,0x6E,0x6E,\n     0x6E,0x6F,0x6F,0x6F,0x6F,0x6F,0x6F,0x6F,\n     0x6F,0x6F,0x6F,0x6F,0x6F,0x6F,0x6F,0x6F,\n     0x6F,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,\n     0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,\n     0x6C,0x6D,0x6D,0x6D,0x6D,0x6D,0x6D,0x6D,\n     0x6D,0x6D,0x6D,0x6D,0x6D,0x6D,0x6D,0x6D,\n     0x6D,0x62,0x62,0x62,0x62,0x62,0x62,0x62,\n     0x62,0x62,0x62,0x62,0x62,0x62,0x62,0x62,\n     0x62,0x63,0x63,0x63,0x63,0x63,0x63,0x63,\n     0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,\n     0x63,0x60,0x60,0x60,0x60,0x60,0x60,0x60,\n     0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,\n     0x60,0x61,0x61,0x61,0x61,0x61,0x61,0x61,\n     0x61,0x61,0x61,0x61,0x61,0x61,0x61,0x61,\n     0x61,0x66,0x66,0x66,0x66,0x66,0x66,0x66,\n     0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,\n     0x66,0x67,0x67,0x67,0x67,0x67,0x67,0x67,\n     0x67,0x67,0x67,0x67,0x67,0x67,0x67,0x67,\n     0x67,0x64,0x64,0x64,0x64,0x64,0x64,0x64,\n     0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,\n     0x64,0x65,0x65,0x65,0x65,0x65,0x65,0x65,\n     0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x65,\n     0x65,0x7A,0x7A,0x7A,0x7A,0x7A,0x7A,0x7A,\n     0x7A,0x7B,0x7B,0x7B,0x7B,0x7B,0x7B,0x7B,\n     0x7B,0x78,0x78,0x78,0x78,0x78,0x78,0x78,\n     0x78,0x79,0x79,0x79,0x79,0x79,0x79,0x79,\n     0x79,0x7E,0x7E,0x7E,0x7E,0x7E,0x7E,0x7E,\n     0x7E,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,\n     0x7F,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,\n     0x7C,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,\n     0x7D,0x72,0x72,0x72,0x72,0x72,0x72,0x72,\n     0x72,0x73,0x73,0x73,0x73,0x73,0x73,0x73,\n     0x73,0x70,0x70,0x70,0x70,0x70,0x70,0x70,\n     0x70,0x71,0x71,0x71,0x71,0x71,0x71,0x71,\n     0x71,0x76,0x76,0x76,0x76,0x76,0x76,0x76,\n     0x76,0x77,0x77,0x77,0x77,0x77,0x77,0x77,\n     0x77,0x74,0x74,0x74,0x74,0x74,0x74,0x74,\n     0x74,0x75,0x75,0x75,0x75,0x75,0x75,0x75,\n     0x75,0x4A,0x4A,0x4A,0x4A,0x4B,0x4B,0x4B,\n     0x4B,0x48,0x48,0x48,0x48,0x49,0x49,0x49,\n     0x49,0x4E,0x4E,0x4E,0x4E,0x4F,0x4F,0x4F,\n     0x4F,0x4C,0x4C,0x4C,0x4C,0x4D,0x4D,0x4D,\n     0x4D,0x42,0x42,0x42,0x42,0x43,0x43,0x43,\n     0x43,0x40,0x40,0x40,0x40,0x41,0x41,0x41,\n     0x41,0x46,0x46,0x46,0x46,0x47,0x47,0x47,\n     0x47,0x44,0x44,0x44,0x44,0x45,0x45,0x45,\n     0x45,0x5A,0x5A,0x5A,0x5A,0x5B,0x5B,0x5B,\n     0x5B,0x58,0x58,0x58,0x58,0x59,0x59,0x59,\n     0x59,0x5E,0x5E,0x5E,0x5E,0x5F,0x5F,0x5F,\n     0x5F,0x5C,0x5C,0x5C,0x5C,0x5D,0x5D,0x5D,\n     0x5D,0x52,0x52,0x52,0x52,0x53,0x53,0x53,\n     0x53,0x50,0x50,0x50,0x50,0x51,0x51,0x51,\n     0x51,0x56,0x56,0x56,0x56,0x57,0x57,0x57,\n     0x57,0x54,0x54,0x54,0x54,0x55,0x55,0x55\n};\n\nconst pj_int16_t pjmedia_ulaw2linear_tab[256] = \n{\n   -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,\n   -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,\n   -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,\n   -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,\n    -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,\n    -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,\n    -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,\n    -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,\n    -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,\n    -1372, -1308, -1244, -1180, -1116, -1052,  -988,  -924,\n     -876,  -844,  -812,  -780,  -748,  -716,  -684,  -652,\n     -620,  -588,  -556,  -524,  -492,  -460,  -428,  -396,\n     -372,  -356,  -340,  -324,  -308,  -292,  -276,  -260,\n     -244,  -228,  -212,  -196,  -180,  -164,  -148,  -132,\n     -120,  -112,  -104,   -96,   -88,   -80,   -72,   -64,\n      -56,   -48,   -40,   -32,   -24,   -16,    -8,     0,\n    32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,\n    23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,\n    15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,\n    11900, 11388, 10876, 10364,  9852,  9340,  8828,  8316,\n     7932,  7676,  7420,  7164,  6908,  6652,  6396,  6140,\n     5884,  5628,  5372,  5116,  4860,  4604,  4348,  4092,\n     3900,  3772,  3644,  3516,  3388,  3260,  3132,  3004,\n     2876,  2748,  2620,  2492,  2364,  2236,  2108,  1980,\n     1884,  1820,  1756,  1692,  1628,  1564,  1500,  1436,\n     1372,  1308,  1244,  1180,  1116,  1052,   988,   924,\n      876,   844,   812,   780,   748,   716,   684,   652,\n      620,   588,   556,   524,   492,   460,   428,   396,\n      372,   356,   340,   324,   308,   292,   276,   260,\n      244,   228,   212,   196,   180,   164,   148,   132,\n      120,   112,   104,    96,    88,    80,    72,    64,\n       56,    48,    40,    32,    24,    16,     8,     0\n};\n\nconst pj_int16_t pjmedia_alaw2linear_tab[256] = \n{\n      -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,\n      -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,\n      -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,\n      -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,\n     -22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944,\n     -30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136,\n     -11008,-10496,-12032,-11520, -8960, -8448, -9984, -9472,\n     -15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568,\n       -344,  -328,  -376,  -360,  -280,  -264,  -312,  -296,\n       -472,  -456,  -504,  -488,  -408,  -392,  -440,  -424,\n\t-88,   -72,  -120,  -104,   -24,    -8,   -56,   -40,\n       -216,  -200,  -248,  -232,  -152,  -136,  -184,  -168,\n      -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,\n      -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,\n       -688,  -656,  -752,  -720,  -560,  -528,  -624,  -592,\n       -944,  -912, -1008,  -976,  -816,  -784,  -880,  -848,\n       5504,  5248,  6016,  5760,  4480,  4224,  4992,  4736,\n       7552,  7296,  8064,  7808,  6528,  6272,  7040,  6784,\n       2752,  2624,  3008,  2880,  2240,  2112,  2496,  2368,\n       3776,  3648,  4032,  3904,  3264,  3136,  3520,  3392,\n      22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,\n      30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,\n      11008, 10496, 12032, 11520,  8960,  8448,  9984,  9472,\n      15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,\n\t344,   328,   376,   360,   280,   264,   312,   296,\n\t472,   456,   504,   488,   408,   392,   440,   424,\n\t 88,    72,   120,   104,    24,     8,    56,    40,\n\t216,   200,   248,   232,   152,   136,   184,   168,\n       1376,  1312,  1504,  1440,  1120,  1056,  1248,  1184,\n       1888,  1824,  2016,  1952,  1632,  1568,  1760,  1696,\n\t688,   656,   752,   720,   560,   528,   624,   592,\n\t944,   912,  1008,   976,   816,   784,   880,   848\n};\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/avi_player.c",
    "content": "/* $Id: avi_player.c 4057 2012-04-17 06:54:50Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/**\n * Default file player/writer buffer size.\n */\n#include <pjmedia/avi_stream.h>\n#include <pjmedia/avi.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/wave.h>\n#include <pj/assert.h>\n#include <pj/file_access.h>\n#include <pj/file_io.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n\n#define THIS_FILE   \"avi_player.c\"\n\n#define AVIF_MUSTUSEINDEX       0x00000020\n#define AVIF_ISINTERLEAVED      0x00000100\n#define AVISF_DISABLED          0x00000001\n#define AVISF_VIDEO_PALCHANGES  0x00010000\n\n#define AVI_EOF 0xFFEEFFEE\n\n#define COMPARE_TAG(doc_tag, tag) (doc_tag == *((pj_uint32_t *)avi_tags[tag]))\n\n#define SIGNATURE\t    PJMEDIA_SIG_PORT_VID_AVI_PLAYER\n\n#define VIDEO_CLOCK_RATE\t90000\n\n#if 0\n#   define TRACE_(x)\tPJ_LOG(4,x)\n#else\n#   define TRACE_(x)\n#endif\n\n#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0\n    static void data_to_host(void *data, pj_uint8_t bits, unsigned count)\n    {\n\tunsigned i;\n\n        count /= (bits == 32? 4 : 2);\n\n\tif (bits == 32) {\n\t    pj_int32_t *data32 = (pj_int32_t *)data;\n\t    for (i=0; i<count; ++i)\n\t\tdata32[i] = pj_swap32(data32[i]);\n\t} else {\n\t    pj_int16_t *data16 = (pj_int16_t *)data;\n\t    for (i=0; i<count; ++i)\n\t\tdata16[i] = pj_swap16(data16[i]);\n\t}\n\n    }\n    static void data_to_host2(void *data, pj_uint8_t nsizes,\n                              pj_uint8_t *sizes)\n    {\n\tunsigned i;\n        pj_int8_t *datap = (pj_int8_t *)data;\n        for (i = 0; i < nsizes; i++) {\n            data_to_host(datap, 32, sizes[i]);\n            datap += sizes[i++];\n            if (i >= nsizes)\n                break;\n            data_to_host(datap, 16, sizes[i]);\n            datap += sizes[i];\n\t}\n    }\n#else\n#   define data_to_host(data, bits, count)\n#   define data_to_host2(data, nsizes, sizes)\n#endif\n\ntypedef struct avi_fmt_info\n{\n    pjmedia_format_id   fmt_id;\n    pjmedia_format_id   eff_fmt_id;\n} avi_fmt_info;\n\nstatic avi_fmt_info avi_fmts[] =\n{\n    {PJMEDIA_FORMAT_MJPEG}, {PJMEDIA_FORMAT_H264},\n    {PJMEDIA_FORMAT_UYVY}, {PJMEDIA_FORMAT_YUY2},\n    {PJMEDIA_FORMAT_IYUV}, {PJMEDIA_FORMAT_I420},\n    {PJMEDIA_FORMAT_DIB}, {PJMEDIA_FORMAT_RGB24},\n    {PJMEDIA_FORMAT_RGB32},\n    {PJMEDIA_FORMAT_PACK('X','V','I','D'), PJMEDIA_FORMAT_MPEG4},\n    {PJMEDIA_FORMAT_PACK('x','v','i','d'), PJMEDIA_FORMAT_MPEG4},\n    {PJMEDIA_FORMAT_PACK('D','I','V','X'), PJMEDIA_FORMAT_MPEG4},\n    {PJMEDIA_FORMAT_PACK('F','M','P','4'), PJMEDIA_FORMAT_MPEG4},\n    {PJMEDIA_FORMAT_PACK('D','X','5','0'), PJMEDIA_FORMAT_MPEG4}\n};\n\nstruct pjmedia_avi_streams\n{\n    unsigned        num_streams;\n    pjmedia_port  **streams;\n};\n\nstruct avi_reader_port\n{\n    pjmedia_port     base;\n    unsigned         stream_id;\n    unsigned\t     options;\n    pjmedia_format_id fmt_id;\n    unsigned         usec_per_frame;\n    pj_uint16_t\t     bits_per_sample;\n    pj_bool_t\t     eof;\n    pj_off_t\t     fsize;\n    pj_off_t\t     start_data;\n    pj_uint8_t       pad;\n    pj_oshandle_t    fd;\n    pj_ssize_t       size_left;\n    pj_timestamp     next_ts;\n\n    pj_status_t\t   (*cb)(pjmedia_port*, void*);\n};\n\n\nstatic pj_status_t avi_get_frame(pjmedia_port *this_port, \n\t\t\t         pjmedia_frame *frame);\nstatic pj_status_t avi_on_destroy(pjmedia_port *this_port);\n\nstatic struct avi_reader_port *create_avi_port(pj_pool_t *pool)\n{\n    const pj_str_t name = pj_str(\"file\");\n    struct avi_reader_port *port;\n\n    port = PJ_POOL_ZALLOC_T(pool, struct avi_reader_port);\n    if (!port)\n\treturn NULL;\n\n    /* Put in default values.\n     * These will be overriden once the file is read.\n     */\n    pjmedia_port_info_init(&port->base.info, &name, SIGNATURE, \n\t\t\t   8000, 1, 16, 80);\n\n    port->fd = (pj_oshandle_t)(pj_ssize_t)-1;\n    port->base.get_frame = &avi_get_frame;\n    port->base.on_destroy = &avi_on_destroy;\n\n    return port;\n}\n\n#define file_read(fd, data, size) file_read2(fd, data, size, 32)\n#define file_read2(fd, data, size, bits) file_read3(fd, data, size, bits, NULL)\n\nstatic pj_status_t file_read3(pj_oshandle_t fd, void *data, pj_ssize_t size,\n                              pj_uint16_t bits, pj_ssize_t *psz_read)\n{\n    pj_ssize_t size_read = size, size_to_read = size;\n    pj_status_t status = pj_file_read(fd, data, &size_read);\n    if (status != PJ_SUCCESS)\n        return status;\n\n    /* Normalize AVI header fields values from little-endian to host\n     * byte order.\n     */\n    if (bits > 0)\n        data_to_host(data, bits, size_read);\n\n    if (size_read != size_to_read) {\n        if (psz_read)\n            *psz_read = size_read;\n        return AVI_EOF;\n    }\n\n    return status;\n}\n\n/*\n * Create AVI player port.\n */\nPJ_DEF(pj_status_t)\npjmedia_avi_player_create_streams(pj_pool_t *pool,\n                                  const char *filename,\n\t\t\t\t  unsigned options,\n\t\t\t\t  pjmedia_avi_streams **p_streams)\n{\n    pjmedia_avi_hdr avi_hdr;\n    struct avi_reader_port *fport[PJMEDIA_AVI_MAX_NUM_STREAMS];\n    pj_off_t pos;\n    unsigned i, nstr = 0;\n    pj_status_t status = PJ_SUCCESS;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(pool && filename && p_streams, PJ_EINVAL);\n\n    /* Check the file really exists. */\n    if (!pj_file_exists(filename)) {\n\treturn PJ_ENOTFOUND;\n    }\n\n    /* Create fport instance. */\n    fport[0] = create_avi_port(pool);\n    if (!fport[0]) {\n\treturn PJ_ENOMEM;\n    }\n\n    /* Get the file size. */\n    fport[0]->fsize = pj_file_size(filename);\n\n    /* Size must be more than AVI header size */\n    if (fport[0]->fsize <= sizeof(riff_hdr_t) + sizeof(avih_hdr_t) + \n                           sizeof(strl_hdr_t))\n    {\n\treturn PJMEDIA_EINVALIMEDIATYPE;\n    }\n\n    /* Open file. */\n    status = pj_file_open(pool, filename, PJ_O_RDONLY, &fport[0]->fd);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Read the RIFF + AVIH header. */\n    status = file_read(fport[0]->fd, &avi_hdr,\n                       sizeof(riff_hdr_t) + sizeof(avih_hdr_t));\n    if (status != PJ_SUCCESS)\n        goto on_error;\n\n    /* Validate AVI file. */\n    if (!COMPARE_TAG(avi_hdr.riff_hdr.riff, PJMEDIA_AVI_RIFF_TAG) ||\n\t!COMPARE_TAG(avi_hdr.riff_hdr.avi, PJMEDIA_AVI_AVI_TAG) ||\n        !COMPARE_TAG(avi_hdr.avih_hdr.list_tag, PJMEDIA_AVI_LIST_TAG) ||\n        !COMPARE_TAG(avi_hdr.avih_hdr.hdrl_tag, PJMEDIA_AVI_HDRL_TAG) ||\n        !COMPARE_TAG(avi_hdr.avih_hdr.avih, PJMEDIA_AVI_AVIH_TAG))\n    {\n\tstatus = PJMEDIA_EINVALIMEDIATYPE;\n        goto on_error;\n    }\n\n    PJ_LOG(5, (THIS_FILE, \"The AVI file has %d streams.\",\n               avi_hdr.avih_hdr.num_streams));\n\n    /* Unsupported AVI format. */\n    if (avi_hdr.avih_hdr.num_streams > PJMEDIA_AVI_MAX_NUM_STREAMS) {\n        status = PJMEDIA_EAVIUNSUPP;\n        goto on_error;\n    }\n\n    /** \n     * TODO: Possibly unsupported AVI format.\n     * If you encounter this warning, verify whether the avi player\n     * is working properly.\n     */\n    if (avi_hdr.avih_hdr.flags & AVIF_MUSTUSEINDEX ||\n        avi_hdr.avih_hdr.pad > 1)\n    {\n        PJ_LOG(3, (THIS_FILE, \"Warning!!! Possibly unsupported AVI format: \"\n                   \"flags:%d, pad:%d\", avi_hdr.avih_hdr.flags, \n                   avi_hdr.avih_hdr.pad));\n    }\n\n    /* Read the headers of each stream. */\n    for (i = 0; i < avi_hdr.avih_hdr.num_streams; i++) {\n        pj_size_t elem = 0;\n        pj_ssize_t size_to_read;\n\n        /* Read strl header */\n        status = file_read(fport[0]->fd, &avi_hdr.strl_hdr[i],\n                           sizeof(strl_hdr_t));\n        if (status != PJ_SUCCESS)\n            goto on_error;\n        \n        elem = COMPARE_TAG(avi_hdr.strl_hdr[i].data_type, \n                           PJMEDIA_AVI_VIDS_TAG) ? \n               sizeof(strf_video_hdr_t) :\n               COMPARE_TAG(avi_hdr.strl_hdr[i].data_type, \n                           PJMEDIA_AVI_AUDS_TAG) ?\n               sizeof(strf_audio_hdr_t) : 0;\n\n        /* Read strf header */\n        status = file_read2(fport[0]->fd, &avi_hdr.strf_hdr[i],\n                            elem, 0);\n        if (status != PJ_SUCCESS)\n            goto on_error;\n\n        /* Normalize the endian */\n        if (elem == sizeof(strf_video_hdr_t))\n            data_to_host2(&avi_hdr.strf_hdr[i],\n                          sizeof(strf_video_hdr_sizes)/\n                          sizeof(strf_video_hdr_sizes[0]),\n                          strf_video_hdr_sizes);\n        else if (elem == sizeof(strf_audio_hdr_t))\n            data_to_host2(&avi_hdr.strf_hdr[i],\n                          sizeof(strf_audio_hdr_sizes)/\n                          sizeof(strf_audio_hdr_sizes[0]),\n                          strf_audio_hdr_sizes);\n\n        /* Skip the remainder of the header */\n        size_to_read = avi_hdr.strl_hdr[i].list_sz - (sizeof(strl_hdr_t) -\n                       8) - elem;\n\tstatus = pj_file_setpos(fport[0]->fd, size_to_read, PJ_SEEK_CUR);\n\tif (status != PJ_SUCCESS) {\n            goto on_error;\n\t}\n    }\n\n    /* Finish reading the AVIH header */\n    status = pj_file_setpos(fport[0]->fd, avi_hdr.avih_hdr.list_sz +\n                            sizeof(riff_hdr_t) + 8, PJ_SEEK_SET);\n    if (status != PJ_SUCCESS) {\n        goto on_error;\n    }\n\n    /* Skip any JUNK or LIST INFO until we get MOVI tag */\n    do {\n        pjmedia_avi_subchunk ch;\n        int read = 0;\n\n        status = file_read(fport[0]->fd, &ch, sizeof(pjmedia_avi_subchunk));\n        if (status != PJ_SUCCESS) {\n            goto on_error;\n        }\n\n        if (COMPARE_TAG(ch.id, PJMEDIA_AVI_LIST_TAG))\n        {\n            read = 4;\n            status = file_read(fport[0]->fd, &ch, read);\n            if (COMPARE_TAG(ch.id, PJMEDIA_AVI_MOVI_TAG))\n                break;\n        }\n\n        status = pj_file_setpos(fport[0]->fd, ch.len-read, PJ_SEEK_CUR);\n        if (status != PJ_SUCCESS) {\n            goto on_error;\n        }\n    } while(1);\n\n    status = pj_file_getpos(fport[0]->fd, &pos);\n    if (status != PJ_SUCCESS)\n        goto on_error;\n\n    for (i = 0, nstr = 0; i < avi_hdr.avih_hdr.num_streams; i++) {\n\tpjmedia_format_id fmt_id;\n\n        /* Skip non-audio, non-video, or disabled streams) */\n        if ((!COMPARE_TAG(avi_hdr.strl_hdr[i].data_type, \n                          PJMEDIA_AVI_VIDS_TAG) &&\n             !COMPARE_TAG(avi_hdr.strl_hdr[i].data_type, \n                          PJMEDIA_AVI_AUDS_TAG)) ||\n            avi_hdr.strl_hdr[i].flags & AVISF_DISABLED)\n        {\n            continue;\n        }\n\n        if (COMPARE_TAG(avi_hdr.strl_hdr[i].data_type, \n                        PJMEDIA_AVI_VIDS_TAG))\n        {\n            int j;\n\n            if (avi_hdr.strl_hdr[i].flags & AVISF_VIDEO_PALCHANGES) {\n                PJ_LOG(4, (THIS_FILE, \"Unsupported video stream\"));\n                continue;\n            }\n\n            fmt_id = avi_hdr.strl_hdr[i].codec;\n            for (j = sizeof(avi_fmts)/sizeof(avi_fmts[0])-1; j >= 0; j--) {\n                /* Check supported video formats here */\n                if (fmt_id == avi_fmts[j].fmt_id) {\n                    if (avi_fmts[j].eff_fmt_id)\n                        fmt_id = avi_fmts[j].eff_fmt_id;\n                    break;\n                }\n            }\n            \n            if (j < 0) {\n                PJ_LOG(4, (THIS_FILE, \"Unsupported video stream\"));\n                continue;\n            }\n        } else {\n            /* Check supported audio formats here */\n            if ((avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_PCM &&\n                 avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_ALAW &&\n                 avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_ULAW &&\n                 avi_hdr.strl_hdr[i].codec != PJMEDIA_WAVE_FMT_TAG_PCM) ||\n                avi_hdr.strf_hdr[i].strf_audio_hdr.bits_per_sample != 16)\n            {\n                PJ_LOG(4, (THIS_FILE, \"Unsupported audio stream\"));\n                continue;\n            }\n            /* Normalize format ID */\n            fmt_id = avi_hdr.strl_hdr[i].codec;\n            if (avi_hdr.strl_hdr[i].codec == PJMEDIA_WAVE_FMT_TAG_PCM)\n        \tfmt_id = PJMEDIA_FORMAT_PCM;\n        }\n\n        if (nstr > 0) {\n            /* Create fport instance. */\n            fport[nstr] = create_avi_port(pool);\n            if (!fport[nstr]) {\n\t        status = PJ_ENOMEM;\n                goto on_error;\n            }\n\n            /* Open file. */\n            status = pj_file_open(pool, filename, PJ_O_RDONLY,\n                                  &fport[nstr]->fd);\n            if (status != PJ_SUCCESS)\n                goto on_error;\n\n            /* Set the file position */\n            status = pj_file_setpos(fport[nstr]->fd, pos, PJ_SEEK_SET);\n            if (status != PJ_SUCCESS) {\n                goto on_error;\n            }\n        }\n\n        fport[nstr]->stream_id = i;\n        fport[nstr]->fmt_id = fmt_id;\n\n        nstr++;\n    }\n\n    if (nstr == 0) {\n        status = PJMEDIA_EAVIUNSUPP;\n        goto on_error;\n    }\n\n    for (i = 0; i < nstr; i++) {\n        strl_hdr_t *strl_hdr = &avi_hdr.strl_hdr[fport[i]->stream_id];\n\n        /* Initialize */\n        fport[i]->options = options;\n        fport[i]->fsize = fport[0]->fsize;\n        /* Current file position now points to start of data */\n        fport[i]->start_data = pos;\n        \n        if (COMPARE_TAG(strl_hdr->data_type, PJMEDIA_AVI_VIDS_TAG)) {\n            strf_video_hdr_t *strf_hdr =\n                &avi_hdr.strf_hdr[fport[i]->stream_id].strf_video_hdr;\n            const pjmedia_video_format_info *vfi;\n\n            vfi = pjmedia_get_video_format_info(\n                pjmedia_video_format_mgr_instance(),\n                strl_hdr->codec);\n\n            fport[i]->bits_per_sample = (vfi ? vfi->bpp : 0);\n            fport[i]->usec_per_frame = avi_hdr.avih_hdr.usec_per_frame;\n            pjmedia_format_init_video(&fport[i]->base.info.fmt,\n                                      fport[i]->fmt_id,\n                                      strf_hdr->biWidth,\n                                      strf_hdr->biHeight,\n                                      strl_hdr->rate,\n                                      strl_hdr->scale);\n#if 0\n            /* The calculation below is wrong. strf_hdr->biSizeImage shows\n             * uncompressed size. Looks like we need to go the ugly way to\n             * get the bitrage:\n             *    http://www.virtualdub.org/blog/pivot/entry.php?id=159\n             */\n            bps = strf_hdr->biSizeImage * 8 * strl_hdr->rate / strl_hdr->scale;\n            if (bps==0) {\n        \t/* strf_hdr->biSizeImage may be zero for uncompressed RGB */\n        \tbps = strf_hdr->biWidth * strf_hdr->biHeight *\n        \t\tstrf_hdr->biBitCount *\n        \t\tstrl_hdr->rate / strl_hdr->scale;\n            }\n            fport[i]->base.info.fmt.det.vid.avg_bps = bps;\n            fport[i]->base.info.fmt.det.vid.max_bps = bps;\n#endif\n        } else {\n            strf_audio_hdr_t *strf_hdr =\n                &avi_hdr.strf_hdr[fport[i]->stream_id].strf_audio_hdr;\n\n            fport[i]->bits_per_sample = strf_hdr->bits_per_sample;\n            fport[i]->usec_per_frame = avi_hdr.avih_hdr.usec_per_frame;\n            pjmedia_format_init_audio(&fport[i]->base.info.fmt,\n                                      fport[i]->fmt_id,\n                                      strf_hdr->sample_rate,\n                                      strf_hdr->nchannels,\n                                      strf_hdr->bits_per_sample,\n                                      20000 /* fport[i]->usec_per_frame */,\n                                      strf_hdr->bytes_per_sec * 8,\n                                      strf_hdr->bytes_per_sec * 8);\n        }\n\n        pj_strdup2(pool, &fport[i]->base.info.name, filename);\n    }\n\n    /* Done. */\n    *p_streams = pj_pool_alloc(pool, sizeof(pjmedia_avi_streams));\n    (*p_streams)->num_streams = nstr;\n    (*p_streams)->streams = pj_pool_calloc(pool, (*p_streams)->num_streams,\n                                           sizeof(pjmedia_port *));\n    for (i = 0; i < nstr; i++)\n        (*p_streams)->streams[i] = &fport[i]->base;\n\n    PJ_LOG(4,(THIS_FILE, \n\t      \"AVI file player '%.*s' created with \"\n\t      \"%d media ports\",\n\t      (int)fport[0]->base.info.name.slen,\n\t      fport[0]->base.info.name.ptr,\n              (*p_streams)->num_streams));\n\n    return PJ_SUCCESS;\n\non_error:\n    fport[0]->base.on_destroy(&fport[0]->base);\n    for (i = 1; i < nstr; i++)\n        fport[i]->base.on_destroy(&fport[i]->base);\n    if (status == AVI_EOF)\n        return PJMEDIA_EINVALIMEDIATYPE;\n    return status;\n}\n\nPJ_DEF(unsigned)\npjmedia_avi_streams_get_num_streams(pjmedia_avi_streams *streams)\n{\n    pj_assert(streams);\n    return streams->num_streams;\n}\n\nPJ_DEF(pjmedia_avi_stream *)\npjmedia_avi_streams_get_stream(pjmedia_avi_streams *streams,\n                               unsigned idx)\n{\n    pj_assert(streams);\n    return (idx < streams->num_streams ? streams->streams[idx] : NULL);\n}\n\nPJ_DEF(pjmedia_avi_stream *)\npjmedia_avi_streams_get_stream_by_media(pjmedia_avi_streams *streams,\n                                        unsigned start_idx,\n                                        pjmedia_type media_type)\n{\n    unsigned i;\n\n    pj_assert(streams);\n    for (i = start_idx; i < streams->num_streams; i++)\n        if (streams->streams[i]->info.fmt.type == media_type)\n            return streams->streams[i];\n    return NULL;\n}\n\n\n/*\n * Get the data length, in bytes.\n */\nPJ_DEF(pj_ssize_t) pjmedia_avi_stream_get_len(pjmedia_avi_stream *stream)\n{\n    struct avi_reader_port *fport;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(stream, -PJ_EINVAL);\n\n    /* Check that this is really a player port */\n    PJ_ASSERT_RETURN(stream->info.signature == SIGNATURE, -PJ_EINVALIDOP);\n\n    fport = (struct avi_reader_port*) stream;\n\n    return (pj_ssize_t)(fport->fsize - fport->start_data);\n}\n\n\n/*\n * Register a callback to be called when the file reading has reached the\n * end of file.\n */\nPJ_DEF(pj_status_t)\npjmedia_avi_stream_set_eof_cb( pjmedia_avi_stream *stream,\n\t\t\t       void *user_data,\n\t\t\t       pj_status_t (*cb)(pjmedia_avi_stream *stream,\n\t\t\t\t\t\t void *usr_data))\n{\n    struct avi_reader_port *fport;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(stream, -PJ_EINVAL);\n\n    /* Check that this is really a player port */\n    PJ_ASSERT_RETURN(stream->info.signature == SIGNATURE, -PJ_EINVALIDOP);\n\n    fport = (struct avi_reader_port*) stream;\n\n    fport->base.port_data.pdata = user_data;\n    fport->cb = cb;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get frame from file.\n */\nstatic pj_status_t avi_get_frame(pjmedia_port *this_port, \n\t\t\t         pjmedia_frame *frame)\n{\n    struct avi_reader_port *fport = (struct avi_reader_port*)this_port;\n    pj_status_t status;\n    pj_ssize_t size_read = 0, size_to_read = 0;\n\n    pj_assert(fport->base.info.signature == SIGNATURE);\n\n    /* We encountered end of file */\n    if (fport->eof) {\n\tpj_status_t status = PJ_SUCCESS;\n\n\tPJ_LOG(5,(THIS_FILE, \"File port %.*s EOF\",\n\t\t  (int)fport->base.info.name.slen,\n\t\t  fport->base.info.name.ptr));\n\n\t/* Call callback, if any */\n\tif (fport->cb)\n\t    status = (*fport->cb)(this_port, fport->base.port_data.pdata);\n\n\t/* If callback returns non PJ_SUCCESS or 'no loop' is specified,\n\t * return immediately (and don't try to access player port since\n\t * it might have been destroyed by the callback).\n\t */\n\tif ((status != PJ_SUCCESS) ||\n            (fport->options & PJMEDIA_AVI_FILE_NO_LOOP)) \n        {\n\t    frame->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    frame->size = 0;\n\t    return PJ_EEOF;\n\t}\n\n        /* Rewind file */\n\tPJ_LOG(5,(THIS_FILE, \"File port %.*s rewinding..\",\n\t\t  (int)fport->base.info.name.slen,\n\t\t  fport->base.info.name.ptr));\n\tfport->eof = PJ_FALSE;\n        pj_file_setpos(fport->fd, fport->start_data, PJ_SEEK_SET);\n    }\n\n    /* Fill frame buffer. */\n    size_to_read = frame->size;\n    do {\n        pjmedia_avi_subchunk ch = {0, 0};\n        char *cid;\n        unsigned stream_id;\n\n        /* We need to read data from the file past the chunk boundary */\n        if (fport->size_left > 0 && fport->size_left < size_to_read) {\n            status = file_read3(fport->fd, frame->buf, fport->size_left,\n                                fport->bits_per_sample, &size_read);\n            if (status != PJ_SUCCESS)\n                goto on_error2;\n            size_to_read -= fport->size_left;\n            fport->size_left = 0;\n        }\n\n        /* Read new chunk data */\n        if (fport->size_left == 0) {\n            pj_off_t pos;\n            pj_file_getpos(fport->fd, &pos);\n\n            /* Data is padded to the nearest WORD boundary */\n            if (fport->pad) {\n                status = pj_file_setpos(fport->fd, fport->pad, PJ_SEEK_CUR);\n                fport->pad = 0;\n            }\n\n            status = file_read(fport->fd, &ch, sizeof(pjmedia_avi_subchunk));\n            if (status != PJ_SUCCESS) {\n                size_read = 0;\n                goto on_error2;\n            }\n\n            cid = (char *)&ch.id;\n            if (cid[0] >= '0' && cid[0] <= '9' &&\n                cid[1] >= '0' && cid[1] <= '9') \n            {\n                stream_id = (cid[0] - '0') * 10 + (cid[1] - '0');\n            } else\n                stream_id = 100;\n            fport->pad = (pj_uint8_t)ch.len & 1;\n\n            TRACE_((THIS_FILE, \"Reading movi data at pos %u (%x), id: %.*s, \"\n                               \"length: %u\", (unsigned long)pos,\n                               (unsigned long)pos, 4, cid, ch.len));\n\n            /* We are only interested in data with our stream id */\n            if (stream_id != fport->stream_id) {\n                if (COMPARE_TAG(ch.id, PJMEDIA_AVI_LIST_TAG))\n                    PJ_LOG(5, (THIS_FILE, \"Unsupported LIST tag found in \"\n                                          \"the movi data.\"));\n                else if (COMPARE_TAG(ch.id, PJMEDIA_AVI_RIFF_TAG)) {\n                    PJ_LOG(3, (THIS_FILE, \"Unsupported format: multiple \"\n                           \"AVIs in a single file.\"));\n                    status = AVI_EOF;\n                    goto on_error2;\n                }\n\n                status = pj_file_setpos(fport->fd, ch.len,\n                                        PJ_SEEK_CUR);\n                continue;\n            }\n            fport->size_left = ch.len;\n        }\n\n        frame->type = (fport->base.info.fmt.type == PJMEDIA_TYPE_VIDEO ?\n                       PJMEDIA_FRAME_TYPE_VIDEO : PJMEDIA_FRAME_TYPE_AUDIO);\n\n        if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) {\n            if (size_to_read > fport->size_left)\n                size_to_read = fport->size_left;\n            status = file_read3(fport->fd, (char *)frame->buf + frame->size -\n                                size_to_read, size_to_read,\n                                fport->bits_per_sample, &size_read);\n            if (status != PJ_SUCCESS)\n                goto on_error2;\n            fport->size_left -= size_to_read;\n        } else {\n            pj_assert(frame->size >= ch.len);\n            status = file_read3(fport->fd, frame->buf, ch.len,\n                                0, &size_read);\n            if (status != PJ_SUCCESS)\n                goto on_error2;\n            frame->size = ch.len;\n            fport->size_left = 0;\n        }\n\n        break;\n\n    } while(1);\n\n    frame->timestamp.u64 = fport->next_ts.u64;\n    if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) {\n\tif (fport->usec_per_frame) {\n\t    fport->next_ts.u64 += (fport->usec_per_frame *\n\t\t\t\t   fport->base.info.fmt.det.aud.clock_rate /\n\t\t\t\t   1000000);\n\t} else {\n\t    fport->next_ts.u64 += (frame->size *\n\t\t\t\t   fport->base.info.fmt.det.aud.clock_rate /\n\t\t\t\t   (fport->base.info.fmt.det.aud.avg_bps / 8));\n\t}\n    } else {\n\tif (fport->usec_per_frame) {\n\t    fport->next_ts.u64 += (fport->usec_per_frame * VIDEO_CLOCK_RATE /\n\t\t\t\t   1000000);\n\t} else {\n\t    fport->next_ts.u64 += (frame->size * VIDEO_CLOCK_RATE /\n\t\t\t\t   (fport->base.info.fmt.det.vid.avg_bps / 8));\n\t}\n    }\n\n    return PJ_SUCCESS;\n\non_error2:\n    if (status == AVI_EOF) {\n        size_to_read -= size_read;\n        pj_bzero((char *)frame->buf + frame->size - size_to_read,\n                 size_to_read);\n        fport->eof = PJ_TRUE;\n\n        return PJ_SUCCESS;\n    }\n\n    return status;\n}\n\n/*\n * Destroy port.\n */\nstatic pj_status_t avi_on_destroy(pjmedia_port *this_port)\n{\n    struct avi_reader_port *fport = (struct avi_reader_port*) this_port;\n\n    pj_assert(this_port->info.signature == SIGNATURE);\n\n    if (fport->fd != (pj_oshandle_t) (pj_ssize_t)-1)\n        pj_file_close(fport->fd);\n    return PJ_SUCCESS;\n}\n\n\n#endif /* PJMEDIA_HAS_VIDEO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/bidirectional.c",
    "content": "/* $Id: bidirectional.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/bidirectional.h>\n#include <pj/pool.h>\n\n\n#define THIS_FILE   \"bidirectional.c\"\n#define SIGNATURE   PJMEDIA_SIG_PORT_BIDIR\n\nstruct bidir_port\n{\n    pjmedia_port     base;\n    pjmedia_port    *get_port;\n    pjmedia_port    *put_port;\n};\n\n\nstatic pj_status_t put_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame)\n{\n    struct bidir_port *p = (struct bidir_port*)this_port;\n    return pjmedia_port_put_frame(p->put_port, frame);\n}\n\n\nstatic pj_status_t get_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame)\n{\n    struct bidir_port *p = (struct bidir_port*)this_port;\n    return pjmedia_port_get_frame(p->get_port, frame);\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_bidirectional_port_create( pj_pool_t *pool,\n\t\t\t\t\t\t       pjmedia_port *get_port,\n\t\t\t\t\t\t       pjmedia_port *put_port,\n\t\t\t\t\t\t       pjmedia_port **p_port )\n{\n    struct bidir_port *port;\n    const pjmedia_audio_format_detail *gafd;\n\n    port = PJ_POOL_ZALLOC_T(pool, struct bidir_port);\n    gafd = pjmedia_format_get_audio_format_detail(&get_port->info.fmt, 1);\n\n    pjmedia_port_info_init(&port->base.info, &get_port->info.name, SIGNATURE,\n\t\t\t   gafd->clock_rate,\n\t\t\t   gafd->channel_count,\n\t\t\t   gafd->bits_per_sample,\n\t\t\t   PJMEDIA_AFD_SPF(gafd));\n\n    port->get_port = get_port;\n    port->put_port = put_port;\n\n    port->base.get_frame = &get_frame;\n    port->base.put_frame = &put_frame;\n\n    *p_port = &port->base;\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/clock_thread.c",
    "content": "/* $Id: clock_thread.c 4160 2012-06-07 04:10:22Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/clock.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/lock.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/compat/high_precision.h>\n\n/* API: Init clock source */\nPJ_DEF(pj_status_t) pjmedia_clock_src_init( pjmedia_clock_src *clocksrc,\n                                            pjmedia_type media_type,\n                                            unsigned clock_rate,\n                                            unsigned ptime_usec )\n{\n    PJ_ASSERT_RETURN(clocksrc, PJ_EINVAL);\n\n    clocksrc->media_type = media_type;\n    clocksrc->clock_rate = clock_rate;\n    clocksrc->ptime_usec = ptime_usec;\n    pj_set_timestamp32(&clocksrc->timestamp, 0, 0);\n    pj_get_timestamp(&clocksrc->last_update);\n\n    return PJ_SUCCESS;\n}\n\n/* API: Update clock source */\nPJ_DECL(pj_status_t) pjmedia_clock_src_update( pjmedia_clock_src *clocksrc,\n                                               const pj_timestamp *timestamp )\n{\n    PJ_ASSERT_RETURN(clocksrc, PJ_EINVAL);\n\n    if (timestamp)\n        pj_memcpy(&clocksrc->timestamp, timestamp, sizeof(pj_timestamp));\n    pj_get_timestamp(&clocksrc->last_update);\n\n    return PJ_SUCCESS;\n}\n\n/* API: Get clock source's current timestamp */\nPJ_DEF(pj_status_t)\npjmedia_clock_src_get_current_timestamp( const pjmedia_clock_src *clocksrc,\n                                         pj_timestamp *timestamp)\n{\n    pj_timestamp now;\n    unsigned elapsed_ms;\n    \n    PJ_ASSERT_RETURN(clocksrc && timestamp, PJ_EINVAL);\n\n    pj_get_timestamp(&now);\n    elapsed_ms = pj_elapsed_msec(&clocksrc->last_update, &now);\n    pj_memcpy(timestamp, &clocksrc->timestamp, sizeof(pj_timestamp));\n    pj_add_timestamp32(timestamp, elapsed_ms * clocksrc->clock_rate / 1000);\n\n    return PJ_SUCCESS;\n}\n\n/* API: Get clock source's time (in ms) */\nPJ_DEF(pj_uint32_t)\npjmedia_clock_src_get_time_msec( const pjmedia_clock_src *clocksrc )\n{\n    pj_timestamp ts;\n\n    pjmedia_clock_src_get_current_timestamp(clocksrc, &ts);\n\n#if PJ_HAS_INT64\n    if (ts.u64 > PJ_UINT64(0x3FFFFFFFFFFFFF))\n        return (pj_uint32_t)(ts.u64 / clocksrc->clock_rate * 1000);\n    else\n        return (pj_uint32_t)(ts.u64 * 1000 / clocksrc->clock_rate);\n#elif PJ_HAS_FLOATING_POINT\n    return (pj_uint32_t)((1.0 * ts.u32.hi * 0xFFFFFFFFUL + ts.u32.lo)\n                         * 1000.0 / clocksrc->clock_rate);\n#else\n    if (ts.u32.lo > 0x3FFFFFUL)\n        return (pj_uint32_t)(0xFFFFFFFFUL / clocksrc->clock_rate * ts.u32.hi \n                             * 1000UL + ts.u32.lo / clocksrc->clock_rate *\n                             1000UL);\n    else\n        return (pj_uint32_t)(0xFFFFFFFFUL / clocksrc->clock_rate * ts.u32.hi \n                             * 1000UL + ts.u32.lo * 1000UL /\n                             clocksrc->clock_rate);\n#endif\n}\n\n\n/*\n * Implementation of media clock with OS thread.\n */\n\nstruct pjmedia_clock\n{\n    pj_pool_t\t\t    *pool;\n    pj_timestamp\t     freq;\n    pj_timestamp\t     interval;\n    pj_timestamp\t     next_tick;\n    pj_timestamp\t     timestamp;\n    unsigned\t\t     timestamp_inc;\n    unsigned\t\t     options;\n    pj_uint64_t\t\t     max_jump;\n    pjmedia_clock_callback  *cb;\n    void\t\t    *user_data;\n    pj_thread_t\t\t    *thread;\n    pj_bool_t\t\t     running;\n    pj_bool_t\t\t     quitting;\n    pj_lock_t\t\t    *lock;\n};\n\n\nstatic int clock_thread(void *arg);\n\n#define MAX_JUMP_MSEC\t500\n#define USEC_IN_SEC\t(pj_uint64_t)1000000\n\n/*\n * Create media clock.\n */\nPJ_DEF(pj_status_t) pjmedia_clock_create( pj_pool_t *pool,\n\t\t\t\t\t  unsigned clock_rate,\n\t\t\t\t\t  unsigned channel_count,\n\t\t\t\t\t  unsigned samples_per_frame,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t\t  pjmedia_clock_callback *cb,\n\t\t\t\t\t  void *user_data,\n\t\t\t\t\t  pjmedia_clock **p_clock)\n{\n    pjmedia_clock_param param;\n\n    param.usec_interval = (unsigned)(samples_per_frame * USEC_IN_SEC /\n\t\t\t             channel_count / clock_rate);\n    param.clock_rate = clock_rate;\n    return pjmedia_clock_create2(pool, &param, options, cb,\n                                 user_data, p_clock);\n}\n\nPJ_DEF(pj_status_t) pjmedia_clock_create2(pj_pool_t *pool,\n                                          const pjmedia_clock_param *param,\n\t\t\t\t          unsigned options,\n\t\t\t\t          pjmedia_clock_callback *cb,\n\t\t\t\t          void *user_data,\n\t\t\t\t          pjmedia_clock **p_clock)\n{\n    pjmedia_clock *clock;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && param->usec_interval && param->clock_rate &&\n                     p_clock, PJ_EINVAL);\n\n    clock = PJ_POOL_ALLOC_T(pool, pjmedia_clock);\n    clock->pool = pj_pool_create(pool->factory, \"clock%p\", 512, 512, NULL);\n\n    status = pj_get_timestamp_freq(&clock->freq);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    clock->interval.u64 = param->usec_interval * clock->freq.u64 /\n                          USEC_IN_SEC;\n    clock->next_tick.u64 = 0;\n    clock->timestamp.u64 = 0;\n    clock->max_jump = MAX_JUMP_MSEC * clock->freq.u64 / 1000;\n    clock->timestamp_inc = (unsigned)(param->usec_interval *\n                                      param->clock_rate /\n\t\t\t\t      USEC_IN_SEC);\n    clock->options = options;\n    clock->cb = cb;\n    clock->user_data = user_data;\n    clock->thread = NULL;\n    clock->running = PJ_FALSE;\n    clock->quitting = PJ_FALSE;\n    \n    /* I don't think we need a mutex, so we'll use null. */\n    status = pj_lock_create_null_mutex(pool, \"clock\", &clock->lock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    *p_clock = clock;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Start the clock. \n */\nPJ_DEF(pj_status_t) pjmedia_clock_start(pjmedia_clock *clock)\n{\n    pj_timestamp now;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(clock != NULL, PJ_EINVAL);\n\n    if (clock->running)\n\treturn PJ_SUCCESS;\n\n    status = pj_get_timestamp(&now);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    clock->next_tick.u64 = now.u64 + clock->interval.u64;\n    clock->running = PJ_TRUE;\n    clock->quitting = PJ_FALSE;\n\n    if ((clock->options & PJMEDIA_CLOCK_NO_ASYNC) == 0 && !clock->thread) {\n\tstatus = pj_thread_create(clock->pool, \"clock\", &clock_thread, clock,\n\t\t\t\t  0, 0, &clock->thread);\n\tif (status != PJ_SUCCESS) {\n\t    clock->running = PJ_FALSE;\n\t    return status;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Stop the clock. \n */\nPJ_DEF(pj_status_t) pjmedia_clock_stop(pjmedia_clock *clock)\n{\n    PJ_ASSERT_RETURN(clock != NULL, PJ_EINVAL);\n\n    clock->running = PJ_FALSE;\n    clock->quitting = PJ_TRUE;\n\n    if (clock->thread) {\n\tif (pj_thread_join(clock->thread) == PJ_SUCCESS) {\n\t    pj_thread_destroy(clock->thread);\n\t    clock->thread = NULL;\n\t    pj_pool_reset(clock->pool);\n\t} else {\n\t    clock->quitting = PJ_FALSE;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Update the clock. \n */\nPJ_DEF(pj_status_t) pjmedia_clock_modify(pjmedia_clock *clock,\n                                         const pjmedia_clock_param *param)\n{\n    clock->interval.u64 = param->usec_interval * clock->freq.u64 /\n                          USEC_IN_SEC;\n    clock->timestamp_inc = (unsigned)(param->usec_interval *\n                                      param->clock_rate /\n\t\t\t\t      USEC_IN_SEC);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Calculate next tick */\nPJ_INLINE(void) clock_calc_next_tick(pjmedia_clock *clock,\n\t\t\t\t     pj_timestamp *now)\n{\n    if (clock->next_tick.u64+clock->max_jump < now->u64) {\n\t/* Timestamp has made large jump, adjust next_tick */\n\tclock->next_tick.u64 = now->u64;\n    }\n    clock->next_tick.u64 += clock->interval.u64;\n\n}\n\n/*\n * Poll the clock. \n */\nPJ_DEF(pj_bool_t) pjmedia_clock_wait( pjmedia_clock *clock,\n\t\t\t\t      pj_bool_t wait,\n\t\t\t\t      pj_timestamp *ts)\n{\n    pj_timestamp now;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(clock != NULL, PJ_FALSE);\n    PJ_ASSERT_RETURN((clock->options & PJMEDIA_CLOCK_NO_ASYNC) != 0,\n\t\t     PJ_FALSE);\n    PJ_ASSERT_RETURN(clock->running, PJ_FALSE);\n\n    status = pj_get_timestamp(&now);\n    if (status != PJ_SUCCESS)\n\treturn PJ_FALSE;\n\n    /* Wait for the next tick to happen */\n    if (now.u64 < clock->next_tick.u64) {\n\tunsigned msec;\n\n\tif (!wait)\n\t    return PJ_FALSE;\n\n\tmsec = pj_elapsed_msec(&now, &clock->next_tick);\n\tpj_thread_sleep(msec);\n    }\n\n    /* Call callback, if any */\n    if (clock->cb)\n\t(*clock->cb)(&clock->timestamp, clock->user_data);\n\n    /* Report timestamp to caller */\n    if (ts)\n\tts->u64 = clock->timestamp.u64;\n\n    /* Increment timestamp */\n    clock->timestamp.u64 += clock->timestamp_inc;\n\n    /* Calculate next tick */\n    clock_calc_next_tick(clock, &now);\n\n    /* Done */\n    return PJ_TRUE;\n}\n\n\n/*\n * Clock thread\n */\nstatic int clock_thread(void *arg)\n{\n    pj_timestamp now;\n    pjmedia_clock *clock = (pjmedia_clock*) arg;\n\n    /* Set thread priority to maximum unless not wanted. */\n    if ((clock->options & PJMEDIA_CLOCK_NO_HIGHEST_PRIO) == 0) {\n\tint max = pj_thread_get_prio_max(pj_thread_this());\n\tif (max > 0)\n\t    pj_thread_set_prio(pj_thread_this(), max);\n    }\n\n    /* Get the first tick */\n    pj_get_timestamp(&clock->next_tick);\n    clock->next_tick.u64 += clock->interval.u64;\n\n\n    while (!clock->quitting) {\n\n\tpj_get_timestamp(&now);\n\n\t/* Wait for the next tick to happen */\n\tif (now.u64 < clock->next_tick.u64) {\n\t    unsigned msec;\n\t    msec = pj_elapsed_msec(&now, &clock->next_tick);\n\t    pj_thread_sleep(msec);\n\t}\n\n\t/* Skip if not running */\n\tif (!clock->running) {\n\t    /* Calculate next tick */\n\t    clock_calc_next_tick(clock, &now);\n\t    continue;\n\t}\n\n\tpj_lock_acquire(clock->lock);\n\n\t/* Call callback, if any */\n\tif (clock->cb)\n\t    (*clock->cb)(&clock->timestamp, clock->user_data);\n\n\t/* Best effort way to detect if we've been destroyed in the callback */\n\tif (clock->quitting)\n\t    break;\n\n\t/* Increment timestamp */\n\tclock->timestamp.u64 += clock->timestamp_inc;\n\n\t/* Calculate next tick */\n\tclock_calc_next_tick(clock, &now);\n\n\tpj_lock_release(clock->lock);\n    }\n\n    return 0;\n}\n\n\n/*\n * Destroy the clock. \n */\nPJ_DEF(pj_status_t) pjmedia_clock_destroy(pjmedia_clock *clock)\n{\n    PJ_ASSERT_RETURN(clock != NULL, PJ_EINVAL);\n\n    clock->running = PJ_FALSE;\n    clock->quitting = PJ_TRUE;\n\n    if (clock->thread) {\n\tpj_thread_join(clock->thread);\n\tpj_thread_destroy(clock->thread);\n\tclock->thread = NULL;\n    }\n\n    if (clock->lock) {\n\tpj_lock_destroy(clock->lock);\n\tclock->lock = NULL;\n    }\n\n    if (clock->pool) {\n\tpj_pool_t *pool = clock->pool;\n\tclock->pool = NULL;\n\tpj_pool_release(pool);\n    }\n    return PJ_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/codec.c",
    "content": "/* $Id: codec.c 4254 2012-09-14 04:06:29Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/codec.h>\n#include <pjmedia/errno.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/string.h>\n\n#define THIS_FILE   \"codec.c\"\n\n\n\n/* Definition of default codecs parameters */\nstruct pjmedia_codec_default_param\n{\n    pj_pool_t\t\t*pool;\n    pjmedia_codec_param\t*param;\n};\n\n\n/* Sort codecs in codec manager based on priorities */\nstatic void sort_codecs(pjmedia_codec_mgr *mgr);\n\n\n/*\n * Duplicate codec parameter.\n */\nPJ_DEF(pjmedia_codec_param*) pjmedia_codec_param_clone(\n\t\t\t\t\tpj_pool_t *pool, \n\t\t\t\t\tconst pjmedia_codec_param *src)\n{\n    pjmedia_codec_param *p;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(pool && src, NULL);\n\n    p = PJ_POOL_ZALLOC_T(pool, pjmedia_codec_param);\n\n    /* Update codec param */\n    pj_memcpy(p, src, sizeof(pjmedia_codec_param));\n    for (i = 0; i < src->setting.dec_fmtp.cnt; ++i) {\n\tpj_strdup(pool, &p->setting.dec_fmtp.param[i].name, \n\t\t  &src->setting.dec_fmtp.param[i].name);\n\tpj_strdup(pool, &p->setting.dec_fmtp.param[i].val, \n\t\t  &src->setting.dec_fmtp.param[i].val);\n    }\n    for (i = 0; i < src->setting.enc_fmtp.cnt; ++i) {\n\tpj_strdup(pool, &p->setting.enc_fmtp.param[i].name, \n\t\t  &src->setting.enc_fmtp.param[i].name);\n\tpj_strdup(pool, &p->setting.enc_fmtp.param[i].val, \n\t\t  &src->setting.enc_fmtp.param[i].val);\n    }\n\n    return p;\n}\n\n\n/*\n * Initialize codec manager.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_mgr_init (pjmedia_codec_mgr *mgr,\n\t\t\t\t\t    pj_pool_factory *pf)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(mgr && pf, PJ_EINVAL);\n\n    /* Init codec manager */\n    pj_bzero(mgr, sizeof(pjmedia_codec_mgr));\n    mgr->pf = pf;\n    pj_list_init (&mgr->factory_list);\n    mgr->codec_cnt = 0;\n\n    /* Create pool */\n    mgr->pool = pj_pool_create(mgr->pf, \"codec-mgr\", 256, 256, NULL);\n\n    /* Create mutex */\n    status = pj_mutex_create_recursive(mgr->pool, \"codec-mgr\", &mgr->mutex);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Initialize codec manager.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_mgr_destroy (pjmedia_codec_mgr *mgr)\n{\n    pjmedia_codec_factory *factory;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    /* Destroy all factories in the list */\n    factory = mgr->factory_list.next;\n    while (factory != &mgr->factory_list) {\n\tpjmedia_codec_factory *next = factory->next;\n\t(*factory->op->destroy)();\n\tfactory = next;\n    }\n\n    /* Cleanup all pools of all codec default params */\n    for (i=0; i<mgr->codec_cnt; ++i) {\n\tif (mgr->codec_desc[i].param) {\n\t    pj_assert(mgr->codec_desc[i].param->pool);\n\t    pj_pool_release(mgr->codec_desc[i].param->pool);\n\t}\n    }\n\n    /* Destroy mutex */\n    if (mgr->mutex)\n\tpj_mutex_destroy(mgr->mutex);\n\n    /* Release pool */\n    if (mgr->pool)\n\tpj_pool_release(mgr->pool);\n\n    /* Just for safety, set codec manager states to zero */\n    pj_bzero(mgr, sizeof(pjmedia_codec_mgr));\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Register a codec factory.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_mgr_register_factory( pjmedia_codec_mgr *mgr,\n\t\t\t\t    pjmedia_codec_factory *factory)\n{\n    pjmedia_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS];\n    unsigned i, count;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(mgr && factory, PJ_EINVAL);\n\n    /* Since 2.0 we require codec factory to implement \"destroy\" op. Please\n     * see: https://trac.pjsip.org/repos/ticket/1294\n     *\n     * Really! Please do see it.\n     */\n    PJ_ASSERT_RETURN(factory->op->destroy != NULL, PJ_ENOTSUP);\n\n    /* Enum codecs */\n    count = PJ_ARRAY_SIZE(info);\n    status = factory->op->enum_info(factory, &count, info);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_mutex_lock(mgr->mutex);\n\n    /* Check codec count */\n    if (count + mgr->codec_cnt > PJ_ARRAY_SIZE(mgr->codec_desc)) {\n\tpj_mutex_unlock(mgr->mutex);\n\treturn PJ_ETOOMANY;\n    }\n\n\n    /* Save the codecs */\n    for (i=0; i<count; ++i) {\n\tpj_memcpy( &mgr->codec_desc[mgr->codec_cnt+i],\n\t\t   &info[i], sizeof(pjmedia_codec_info));\n\tmgr->codec_desc[mgr->codec_cnt+i].prio = PJMEDIA_CODEC_PRIO_NORMAL;\n\tmgr->codec_desc[mgr->codec_cnt+i].factory = factory;\n\tpjmedia_codec_info_to_id( &info[i],\n\t\t\t\t  mgr->codec_desc[mgr->codec_cnt+i].id,\n\t\t\t\t  sizeof(pjmedia_codec_id));\n    }\n\n    /* Update count */\n    mgr->codec_cnt += count;\n\n    /* Re-sort codec based on priorities */\n    sort_codecs(mgr);\n\n    /* Add factory to the list */\n    pj_list_push_back(&mgr->factory_list, factory);\n\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Unregister a codec factory.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_mgr_unregister_factory(\n\t\t\t\tpjmedia_codec_mgr *mgr, \n\t\t\t\tpjmedia_codec_factory *factory)\n{\n    unsigned i;\n    PJ_ASSERT_RETURN(mgr && factory, PJ_EINVAL);\n\n    pj_mutex_lock(mgr->mutex);\n\n    /* Factory must be registered. */\n    if (pj_list_find_node(&mgr->factory_list, factory) != factory) {\n\tpj_mutex_unlock(mgr->mutex);\n\treturn PJ_ENOTFOUND;\n    }\n\n    /* Erase factory from the factory list */\n    pj_list_erase(factory);\n\n\n    /* Remove all supported codecs from the codec manager that were created \n     * by the specified factory.\n     */\n    for (i=0; i<mgr->codec_cnt; ) {\n\n\tif (mgr->codec_desc[i].factory == factory) {\n\t    /* Release pool of codec default param */\n\t    if (mgr->codec_desc[i].param) {\n\t\tpj_assert(mgr->codec_desc[i].param->pool);\n\t\tpj_pool_release(mgr->codec_desc[i].param->pool);\n\t    }\n\n\t    /* Remove the codec from array of codec descriptions */\n\t    pj_array_erase(mgr->codec_desc, sizeof(mgr->codec_desc[0]), \n\t\t\t   mgr->codec_cnt, i);\n\t    --mgr->codec_cnt;\n\n\t} else {\n\t    ++i;\n\t}\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Enum all codecs.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_mgr_enum_codecs(pjmedia_codec_mgr *mgr, \n\t\t\t      unsigned *count, \n\t\t\t      pjmedia_codec_info codecs[],\n\t\t\t      unsigned *prio)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(mgr && count && codecs, PJ_EINVAL);\n\n    pj_mutex_lock(mgr->mutex);\n\n    if (*count > mgr->codec_cnt)\n\t*count = mgr->codec_cnt;\n    \n    for (i=0; i<*count; ++i) {\n\tpj_memcpy(&codecs[i], \n\t\t  &mgr->codec_desc[i].info, \n\t\t  sizeof(pjmedia_codec_info));\n    }\n\n    if (prio) {\n\tfor (i=0; i < *count; ++i)\n\t    prio[i] = mgr->codec_desc[i].prio;\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get codec info for static payload type.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_mgr_get_codec_info( pjmedia_codec_mgr *mgr,\n\t\t\t\t  unsigned pt,\n\t\t\t\t  const pjmedia_codec_info **p_info)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(mgr && p_info && pt>=0 && pt < 96, PJ_EINVAL);\n\n    pj_mutex_lock(mgr->mutex);\n\n    for (i=0; i<mgr->codec_cnt; ++i) {\n\tif (mgr->codec_desc[i].info.pt == pt) {\n\t    *p_info = &mgr->codec_desc[i].info;\n\n\t    pj_mutex_unlock(mgr->mutex);\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJMEDIA_CODEC_EUNSUP;\n}\n\n\n/*\n * Convert codec info struct into a unique codec identifier.\n * A codec identifier looks something like \"L16/44100/2\".\n */\nPJ_DEF(char*) pjmedia_codec_info_to_id( const pjmedia_codec_info *info,\n\t\t\t\t        char *id, unsigned max_len )\n{\n    int len;\n\n    PJ_ASSERT_RETURN(info && id && max_len, NULL);\n\n    len = pj_ansi_snprintf(id, max_len, \"%.*s/%u/%u\", \n\t\t\t   (int)info->encoding_name.slen,\n\t\t\t   info->encoding_name.ptr,\n\t\t\t   info->clock_rate,\n\t\t\t   info->channel_cnt);\n\n    if (len < 1 || len >= (int)max_len) {\n\tid[0] = '\\0';\n\treturn NULL;\n    }\n\n    return id;\n}\n\n\n/*\n * Find codecs by the unique codec identifier. This function will find\n * all codecs that match the codec identifier prefix. For example, if\n * \"L16\" is specified, then it will find \"L16/8000/1\", \"L16/16000/1\",\n * and so on, up to the maximum count specified in the argument.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_mgr_find_codecs_by_id( pjmedia_codec_mgr *mgr,\n\t\t\t\t     const pj_str_t *codec_id,\n\t\t\t\t     unsigned *count,\n\t\t\t\t     const pjmedia_codec_info *p_info[],\n\t\t\t\t     unsigned prio[])\n{\n    unsigned i, found = 0;\n\n    PJ_ASSERT_RETURN(mgr && codec_id && count && *count, PJ_EINVAL);\n\n    pj_mutex_lock(mgr->mutex);\n\n    for (i=0; i<mgr->codec_cnt; ++i) {\n\n\tif (codec_id->slen == 0 ||\n\t    pj_strnicmp2(codec_id, mgr->codec_desc[i].id, \n\t\t\t codec_id->slen) == 0) \n\t{\n\n\t    if (p_info)\n\t\tp_info[found] = &mgr->codec_desc[i].info;\n\t    if (prio)\n\t\tprio[found] = mgr->codec_desc[i].prio;\n\n\t    ++found;\n\n\t    if (found >= *count)\n\t\tbreak;\n\t}\n\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n    *count = found;\n\n    return found ? PJ_SUCCESS : PJ_ENOTFOUND;\n}\n\n\n/* Swap two codecs positions in codec manager */\nstatic void swap_codec(pjmedia_codec_mgr *mgr, unsigned i, unsigned j)\n{\n    struct pjmedia_codec_desc tmp;\n\n    pj_memcpy(&tmp, &mgr->codec_desc[i], sizeof(struct pjmedia_codec_desc));\n\n    pj_memcpy(&mgr->codec_desc[i], &mgr->codec_desc[j], \n\t       sizeof(struct pjmedia_codec_desc));\n\n    pj_memcpy(&mgr->codec_desc[j], &tmp, sizeof(struct pjmedia_codec_desc));\n}\n\n\n/* Sort codecs in codec manager based on priorities */\nstatic void sort_codecs(pjmedia_codec_mgr *mgr)\n{\n    unsigned i;\n\n   /* Re-sort */\n    for (i=0; i<mgr->codec_cnt; ++i) {\n\tunsigned j, max;\n\n\tfor (max=i, j=i+1; j<mgr->codec_cnt; ++j) {\n\t    if (mgr->codec_desc[j].prio > mgr->codec_desc[max].prio)\n\t\tmax = j;\n\t}\n\n\tif (max != i)\n\t    swap_codec(mgr, i, max);\n    }\n\n    /* Change PJMEDIA_CODEC_PRIO_HIGHEST codecs to NEXT_HIGHER */\n    for (i=0; i<mgr->codec_cnt; ++i) {\n\tif (mgr->codec_desc[i].prio == PJMEDIA_CODEC_PRIO_HIGHEST)\n\t    mgr->codec_desc[i].prio = PJMEDIA_CODEC_PRIO_NEXT_HIGHER;\n\telse\n\t    break;\n    }\n}\n\n\n/**\n * Set codec priority. The codec priority determines the order of\n * the codec in the SDP created by the endpoint. If more than one codecs\n * are found with the same codec_id prefix, then the function sets the\n * priorities of all those codecs.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_mgr_set_codec_priority(\n\t\t\t\tpjmedia_codec_mgr *mgr, \n\t\t\t\tconst pj_str_t *codec_id,\n\t\t\t\tpj_uint8_t prio)\n{\n    unsigned i, found = 0;\n\n    PJ_ASSERT_RETURN(mgr && codec_id, PJ_EINVAL);\n\n    pj_mutex_lock(mgr->mutex);\n\n    /* Update the priorities of affected codecs */\n    for (i=0; i<mgr->codec_cnt; ++i) \n    {\n\tif (codec_id->slen == 0 ||\n\t    pj_strnicmp2(codec_id, mgr->codec_desc[i].id, \n\t\t\t codec_id->slen) == 0) \n\t{\n\t    mgr->codec_desc[i].prio = (pjmedia_codec_priority) prio;\n\t    ++found;\n\t}\n    }\n\n    if (!found) {\n\tpj_mutex_unlock(mgr->mutex);\n\treturn PJ_ENOTFOUND;\n    }\n\n    /* Re-sort codecs */\n    sort_codecs(mgr);\n\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Allocate one codec.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_mgr_alloc_codec(pjmedia_codec_mgr *mgr, \n\t\t\t\t\t\t  const pjmedia_codec_info *info,\n\t\t\t\t\t\t  pjmedia_codec **p_codec)\n{\n    pjmedia_codec_factory *factory;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(mgr && info && p_codec, PJ_EINVAL);\n\n    *p_codec = NULL;\n\n    pj_mutex_lock(mgr->mutex);\n\n    factory = mgr->factory_list.next;\n    while (factory != &mgr->factory_list) {\n\n\tif ( (*factory->op->test_alloc)(factory, info) == PJ_SUCCESS ) {\n\n\t    status = (*factory->op->alloc_codec)(factory, info, p_codec);\n\t    if (status == PJ_SUCCESS) {\n\t\tpj_mutex_unlock(mgr->mutex);\n\t\treturn PJ_SUCCESS;\n\t    }\n\n\t}\n\n\tfactory = factory->next;\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJMEDIA_CODEC_EUNSUP;\n}\n\n\n/*\n * Get default codec parameter.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_mgr_get_default_param( pjmedia_codec_mgr *mgr,\n\t\t\t\t\t\t\tconst pjmedia_codec_info *info,\n\t\t\t\t\t\t\tpjmedia_codec_param *param )\n{\n    pjmedia_codec_factory *factory;\n    pj_status_t status;\n    pjmedia_codec_id codec_id;\n    struct pjmedia_codec_desc *codec_desc = NULL;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(mgr && info && param, PJ_EINVAL);\n\n    if (!pjmedia_codec_info_to_id(info, (char*)&codec_id, sizeof(codec_id)))\n\treturn PJ_EINVAL;\n\n    pj_mutex_lock(mgr->mutex);\n\n    /* First, lookup default param in codec desc */\n    for (i=0; i < mgr->codec_cnt; ++i) {\n\tif (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) {\n\t    codec_desc = &mgr->codec_desc[i];\n\t    break;\n\t}\n    }\n\n    /* If we found the codec and its default param is set, return it */\n    if (codec_desc && codec_desc->param) {\n\tpj_assert(codec_desc->param->param);\n\tpj_memcpy(param, codec_desc->param->param, \n\t\t  sizeof(pjmedia_codec_param));\n\n\tpj_mutex_unlock(mgr->mutex);\n\treturn PJ_SUCCESS;\n    }\n\n    /* Otherwise query the default param from codec factory */\n    factory = mgr->factory_list.next;\n    while (factory != &mgr->factory_list) {\n\n\tif ( (*factory->op->test_alloc)(factory, info) == PJ_SUCCESS ) {\n\n\t    status = (*factory->op->default_attr)(factory, info, param);\n\t    if (status == PJ_SUCCESS) {\n\t\t/* Check for invalid max_bps. */\n\t\tif (param->info.max_bps < param->info.avg_bps)\n\t\t    param->info.max_bps = param->info.avg_bps;\n\n\t\tpj_mutex_unlock(mgr->mutex);\n\t\treturn PJ_SUCCESS;\n\t    }\n\n\t}\n\n\tfactory = factory->next;\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n\n    return PJMEDIA_CODEC_EUNSUP;\n}\n\n\n/*\n * Set default codec parameter.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_mgr_set_default_param( \n\t\t\t\t\t    pjmedia_codec_mgr *mgr,\n\t\t\t\t\t    const pjmedia_codec_info *info,\n\t\t\t\t\t    const pjmedia_codec_param *param )\n{\n    unsigned i;\n    pjmedia_codec_id codec_id;\n    pj_pool_t *pool, *old_pool = NULL;\n    struct pjmedia_codec_desc *codec_desc = NULL;\n    pjmedia_codec_default_param *p;\n\n    PJ_ASSERT_RETURN(mgr && info, PJ_EINVAL);\n\n    if (!pjmedia_codec_info_to_id(info, (char*)&codec_id, sizeof(codec_id)))\n\treturn PJ_EINVAL;\n\n    pj_mutex_lock(mgr->mutex);\n\n    /* Lookup codec desc */\n    for (i=0; i < mgr->codec_cnt; ++i) {\n\tif (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) {\n\t    codec_desc = &mgr->codec_desc[i];\n\t    break;\n\t}\n    }\n\n    /* Codec not found */\n    if (!codec_desc) {\n\tpj_mutex_unlock(mgr->mutex);\n\treturn PJMEDIA_CODEC_EUNSUP;\n    }\n\n    /* If codec param is previously set, reset the codec param but release\n     * the codec param pool later after the new param is set (ticket #1171).\n     */\n    if (codec_desc->param) {\n\tpj_assert(codec_desc->param->pool);\n        old_pool = codec_desc->param->pool;\n\tcodec_desc->param = NULL;\n    }\n\n    /* When param is set to NULL, i.e: setting default codec param to library\n     * default setting, just return PJ_SUCCESS.\n     */\n    if (NULL == param) {\n\tpj_mutex_unlock(mgr->mutex);\n        if (old_pool)\n\t    pj_pool_release(old_pool);\n\treturn PJ_SUCCESS;\n    }\n\n    /* Instantiate and initialize codec param */\n    pool = pj_pool_create(mgr->pf, (char*)codec_id, 256, 256, NULL);\n    codec_desc->param = PJ_POOL_ZALLOC_T(pool, pjmedia_codec_default_param);\n    p = codec_desc->param;\n    p->pool = pool;\n\n    /* Update codec param */\n    p->param = pjmedia_codec_param_clone(pool, param);\n    if (!p->param) {\n\tpj_mutex_unlock(mgr->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n    if (old_pool)\n\tpj_pool_release(old_pool);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Dealloc codec.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_mgr_dealloc_codec(pjmedia_codec_mgr *mgr, \n\t\t\t\t\t\t    pjmedia_codec *codec)\n{\n    PJ_ASSERT_RETURN(mgr && codec, PJ_EINVAL);\n\n    return (*codec->factory->op->dealloc_codec)(codec->factory, codec);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/conf_switch.c",
    "content": "/* $Id: conf_switch.c 4443 2013-03-20 06:56:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/conference.h>\n#include <pjmedia/alaw_ulaw.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/port.h>\n#include <pjmedia/silencedet.h>\n#include <pjmedia/sound_port.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/math.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#if defined(PJMEDIA_CONF_USE_SWITCH_BOARD) && PJMEDIA_CONF_USE_SWITCH_BOARD!=0\n\n/* CONF_DEBUG enables detailed operation of the conference bridge.\n * Beware that it prints large amounts of logs (several lines per frame).\n */\n//#define CONF_DEBUG\n#ifdef CONF_DEBUG\n#   include <stdio.h>\n#   define TRACE_(x)   PJ_LOG(5,x)\n#else\n#   define TRACE_(x)\n#endif\n\n#define THIS_FILE\t    \"conf_switch.c\"\n\n#define SIGNATURE\t    PJMEDIA_CONF_SWITCH_SIGNATURE\n#define SIGNATURE_PORT\t    PJMEDIA_PORT_SIGNATURE('S', 'W', 'T', 'P')\n#define NORMAL_LEVEL\t    128\n#define SLOT_TYPE\t    unsigned\n#define INVALID_SLOT\t    ((SLOT_TYPE)-1)\n#define BUFFER_SIZE\t    PJMEDIA_CONF_SWITCH_BOARD_BUF_SIZE\n#define MAX_LEVEL\t    (32767)\n#define MIN_LEVEL\t    (-32768)\n\n/*\n * DON'T GET CONFUSED WITH TX/RX!!\n *\n * TX and RX directions are always viewed from the conference bridge's point\n * of view, and NOT from the port's point of view. So TX means the bridge\n * is transmitting to the port, RX means the bridge is receiving from the\n * port.\n */\n\n\n/**\n * This is a port connected to conference bridge.\n */\nstruct conf_port\n{\n    SLOT_TYPE\t\t slot;\t\t/**< Array of listeners.\t    */\n    pj_str_t\t\t name;\t\t/**< Port name.\t\t\t    */\n    pjmedia_port\t*port;\t\t/**< get_frame() and put_frame()    */\n    pjmedia_port_op\t rx_setting;\t/**< Can we receive from this port  */\n    pjmedia_port_op\t tx_setting;\t/**< Can we transmit to this port   */\n    unsigned\t\t listener_cnt;\t/**< Number of listeners.\t    */\n    SLOT_TYPE\t\t*listener_slots;/**< Array of listeners.\t    */\n    unsigned\t\t transmitter_cnt;/**<Number of transmitters.\t    */\n\n    /* Shortcut for port info. */\n    pjmedia_port_info\t*info;\n    unsigned\t\t samples_per_frame;\n\n    /* Calculated signal levels: */\n    unsigned\t\t tx_level;\t/**< Last tx level to this port.    */\n    unsigned\t\t rx_level;\t/**< Last rx level from this port.  */\n\n    /* The normalized signal level adjustment.\n     * A value of 128 (NORMAL_LEVEL) means there's no adjustment.\n     */\n    unsigned\t\t tx_adj_level;\t/**< Adjustment for TX.\t\t    */\n    unsigned\t\t rx_adj_level;\t/**< Adjustment for RX.\t\t    */\n\n    pj_timestamp\t ts_clock;\n    pj_timestamp\t ts_rx;\n    pj_timestamp\t ts_tx;\n\n    /* Tx buffer is a temporary buffer to be used when there's mismatch \n     * between port's ptime with conference's ptime. This buffer is used as \n     * the source to buffer the samples until there are enough samples to \n     * fulfill a complete frame to be transmitted to the port.\n     */\n    pj_uint8_t\t\t tx_buf[BUFFER_SIZE]; /**< Tx buffer.\t\t    */\n};\n\n\n/*\n * Conference bridge.\n */\nstruct pjmedia_conf\n{\n    unsigned\t\t  options;\t/**< Bitmask options.\t\t    */\n    unsigned\t\t  max_ports;\t/**< Maximum ports.\t\t    */\n    unsigned\t\t  port_cnt;\t/**< Current number of ports.\t    */\n    unsigned\t\t  connect_cnt;\t/**< Total number of connections    */\n    pjmedia_port\t *master_port;\t/**< Port zero's port.\t\t    */\n    char\t\t  master_name_buf[80]; /**< Port0 name buffer.\t    */\n    pj_mutex_t\t\t *mutex;\t/**< Conference mutex.\t\t    */\n    struct conf_port\t**ports;\t/**< Array of ports.\t\t    */\n    pj_uint8_t\t\t  buf[BUFFER_SIZE];\t/**< Common buffer.\t    */\n};\n\n\n/* Prototypes */\nstatic pj_status_t put_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame);\nstatic pj_status_t get_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame);\nstatic pj_status_t destroy_port(pjmedia_port *this_port);\n\n\n/*\n * Create port.\n */\nstatic pj_status_t create_conf_port( pj_pool_t *pool,\n\t\t\t\t     pjmedia_conf *conf,\n\t\t\t\t     pjmedia_port *port,\n\t\t\t\t     const pj_str_t *name,\n\t\t\t\t     struct conf_port **p_conf_port)\n{\n    struct conf_port *conf_port;\n    pjmedia_frame *f;\n\n    PJ_ASSERT_RETURN(pool && conf && port && name && p_conf_port, PJ_EINVAL);\n\n    /* Check port's buffer size */\n    if (port->info.fmt.id == PJMEDIA_FORMAT_PCM &&\n\tPJMEDIA_PIA_SPF(&port->info)*2 > BUFFER_SIZE - sizeof(pjmedia_frame))\n    {\n\tpj_assert(!\"Too small buffer size for audio switchboard. \"\n\t\t   \"Try increase PJMEDIA_CONF_SWITCH_BOARD_BUF_SIZE\");\n\treturn PJ_ETOOSMALL;\n    }\n\n    /* Create port. */\n    conf_port = PJ_POOL_ZALLOC_T(pool, struct conf_port);\n\n    /* Set name */\n    pj_strdup_with_null(pool, &conf_port->name, name);\n\n    /* Default has tx and rx enabled. */\n    conf_port->rx_setting = PJMEDIA_PORT_ENABLE;\n    conf_port->tx_setting = PJMEDIA_PORT_ENABLE;\n\n    /* Default level adjustment is 128 (which means no adjustment) */\n    conf_port->tx_adj_level = NORMAL_LEVEL;\n    conf_port->rx_adj_level = NORMAL_LEVEL;\n\n    /* Create transmit flag array */\n    conf_port->listener_slots = (SLOT_TYPE*)\n\t\t\t\tpj_pool_zalloc(pool, \n\t\t\t\t\t  conf->max_ports * sizeof(SLOT_TYPE));\n    PJ_ASSERT_RETURN(conf_port->listener_slots, PJ_ENOMEM);\n\n    /* Save some port's infos, for convenience. */\n    conf_port->port = port;\n    conf_port->info = &port->info;\n    conf_port->samples_per_frame = PJMEDIA_PIA_SPF(&port->info);\n\n    /* Init pjmedia_frame structure in the TX buffer. */\n    f = (pjmedia_frame*)conf_port->tx_buf;\n    f->buf = conf_port->tx_buf + sizeof(pjmedia_frame);\n\n    /* Done */\n    *p_conf_port = conf_port;\n    return PJ_SUCCESS;\n}\n\n/*\n * Create port zero for the sound device.\n */\nstatic pj_status_t create_sound_port( pj_pool_t *pool,\n\t\t\t\t      pjmedia_conf *conf )\n{\n    struct conf_port *conf_port;\n    pj_str_t name = { \"Master/sound\", 12 };\n    pj_status_t status;\n\n    status = create_conf_port(pool, conf, conf->master_port, &name, &conf_port);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n     /* Add the port to the bridge */\n    conf_port->slot = 0;\n    conf->ports[0] = conf_port;\n    conf->port_cnt++;\n\n    PJ_LOG(5,(THIS_FILE, \"Sound device successfully created for port 0\"));\n    return PJ_SUCCESS;\n}\n\n/*\n * Create conference bridge.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_create( pj_pool_t *pool,\n\t\t\t\t\t unsigned max_ports,\n\t\t\t\t\t unsigned clock_rate,\n\t\t\t\t\t unsigned channel_count,\n\t\t\t\t\t unsigned samples_per_frame,\n\t\t\t\t\t unsigned bits_per_sample,\n\t\t\t\t\t unsigned options,\n\t\t\t\t\t pjmedia_conf **p_conf )\n{\n    pjmedia_conf *conf;\n    const pj_str_t name = { \"Conf\", 4 };\n    pj_status_t status;\n\n    /* Can only accept 16bits per sample, for now.. */\n    PJ_ASSERT_RETURN(bits_per_sample == 16, PJ_EINVAL);\n\n    PJ_LOG(5,(THIS_FILE, \"Creating conference bridge with %d ports\",\n\t      max_ports));\n\n    /* Create and init conf structure. */\n    conf = PJ_POOL_ZALLOC_T(pool, pjmedia_conf);\n    PJ_ASSERT_RETURN(conf, PJ_ENOMEM);\n\n    conf->ports = (struct conf_port**) \n\t\t  pj_pool_zalloc(pool, max_ports*sizeof(void*));\n    PJ_ASSERT_RETURN(conf->ports, PJ_ENOMEM);\n\n    conf->options = options;\n    conf->max_ports = max_ports;\n    \n    /* Create and initialize the master port interface. */\n    conf->master_port = PJ_POOL_ZALLOC_T(pool, pjmedia_port);\n    PJ_ASSERT_RETURN(conf->master_port, PJ_ENOMEM);\n    \n    pjmedia_port_info_init(&conf->master_port->info, &name, SIGNATURE,\n\t\t\t   clock_rate, channel_count, bits_per_sample,\n\t\t\t   samples_per_frame);\n\n    conf->master_port->port_data.pdata = conf;\n    conf->master_port->port_data.ldata = 0;\n\n    conf->master_port->get_frame = &get_frame;\n    conf->master_port->put_frame = &put_frame;\n    conf->master_port->on_destroy = &destroy_port;\n\n\n    /* Create port zero for sound device. */\n    status = create_sound_port(pool, conf);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Create mutex. */\n    status = pj_mutex_create_recursive(pool, \"conf\", &conf->mutex);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Done */\n\n    *p_conf = conf;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Pause sound device.\n */\nstatic pj_status_t pause_sound( pjmedia_conf *conf )\n{\n    /* Do nothing. */\n    PJ_UNUSED_ARG(conf);\n    return PJ_SUCCESS;\n}\n\n/*\n * Resume sound device.\n */\nstatic pj_status_t resume_sound( pjmedia_conf *conf )\n{\n    /* Do nothing. */\n    PJ_UNUSED_ARG(conf);\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Destroy conference bridge.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_destroy( pjmedia_conf *conf )\n{\n    PJ_ASSERT_RETURN(conf != NULL, PJ_EINVAL);\n\n    /* Destroy mutex */\n    pj_mutex_destroy(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy the master port (will destroy the conference)\n */\nstatic pj_status_t destroy_port(pjmedia_port *this_port)\n{\n    pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;\n    return pjmedia_conf_destroy(conf);\n}\n\n/*\n * Get port zero interface.\n */\nPJ_DEF(pjmedia_port*) pjmedia_conf_get_master_port(pjmedia_conf *conf)\n{\n    /* Sanity check. */\n    PJ_ASSERT_RETURN(conf != NULL, NULL);\n\n    /* Can only return port interface when PJMEDIA_CONF_NO_DEVICE was\n     * present in the option.\n     */\n    PJ_ASSERT_RETURN((conf->options & PJMEDIA_CONF_NO_DEVICE) != 0, NULL);\n    \n    return conf->master_port;\n}\n\n\n/*\n * Set master port name.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_set_port0_name(pjmedia_conf *conf,\n\t\t\t\t\t\tconst pj_str_t *name)\n{\n    unsigned len;\n\n    /* Sanity check. */\n    PJ_ASSERT_RETURN(conf != NULL && name != NULL, PJ_EINVAL);\n\n    len = name->slen;\n    if (len > sizeof(conf->master_name_buf))\n\tlen = sizeof(conf->master_name_buf);\n    \n    if (len > 0) pj_memcpy(conf->master_name_buf, name->ptr, len);\n\n    conf->ports[0]->name.ptr = conf->master_name_buf;\n    conf->ports[0]->name.slen = len;\n\n    conf->master_port->info.name = conf->ports[0]->name;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Add stream port to the conference bridge.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_add_port( pjmedia_conf *conf,\n\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t   pjmedia_port *strm_port,\n\t\t\t\t\t   const pj_str_t *port_name,\n\t\t\t\t\t   unsigned *p_port )\n{\n    struct conf_port *conf_port;\n    unsigned index;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(conf && pool && strm_port, PJ_EINVAL);\n    /*\n    PJ_ASSERT_RETURN(conf->clock_rate == strm_port->info.clock_rate, \n\t\t     PJMEDIA_ENCCLOCKRATE);\n    PJ_ASSERT_RETURN(conf->channel_count == strm_port->info.channel_count, \n\t\t     PJMEDIA_ENCCHANNEL);\n    PJ_ASSERT_RETURN(conf->bits_per_sample == strm_port->info.bits_per_sample,\n\t\t     PJMEDIA_ENCBITS);\n    */\n\n    /* Port's samples per frame should be equal to or multiplication of \n     * conference's samples per frame.\n     */\n    /*\n    Not sure if this is needed!\n    PJ_ASSERT_RETURN((conf->samples_per_frame %\n\t\t     strm_port->info.samples_per_frame==0) ||\n\t\t     (strm_port->info.samples_per_frame %\n\t\t     conf->samples_per_frame==0),\n\t\t     PJMEDIA_ENCSAMPLESPFRAME);\n    */\n\n    /* If port_name is not specified, use the port's name */\n    if (!port_name)\n\tport_name = &strm_port->info.name;\n\n    pj_mutex_lock(conf->mutex);\n\n    if (conf->port_cnt >= conf->max_ports) {\n\tpj_assert(!\"Too many ports\");\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_ETOOMANY;\n    }\n\n    /* Find empty port in the conference bridge. */\n    for (index=0; index < conf->max_ports; ++index) {\n\tif (conf->ports[index] == NULL)\n\t    break;\n    }\n\n    pj_assert(index != conf->max_ports);\n\n    /* Create conf port structure. */\n    status = create_conf_port(pool, conf, strm_port, port_name, &conf_port);\n    if (status != PJ_SUCCESS) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn status;\n    }\n\n    /* Put the port. */\n    conf_port->slot = index;\n    conf->ports[index] = conf_port;\n    conf->port_cnt++;\n\n    /* Done. */\n    if (p_port) {\n\t*p_port = index;\n    }\n\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Add passive port.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_add_passive_port( pjmedia_conf *conf,\n\t\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t\t   const pj_str_t *name,\n\t\t\t\t\t\t   unsigned clock_rate,\n\t\t\t\t\t\t   unsigned channel_count,\n\t\t\t\t\t\t   unsigned samples_per_frame,\n\t\t\t\t\t\t   unsigned bits_per_sample,\n\t\t\t\t\t\t   unsigned options,\n\t\t\t\t\t\t   unsigned *p_slot,\n\t\t\t\t\t\t   pjmedia_port **p_port )\n{\n    PJ_UNUSED_ARG(conf);\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(name);\n    PJ_UNUSED_ARG(clock_rate);\n    PJ_UNUSED_ARG(channel_count);\n    PJ_UNUSED_ARG(samples_per_frame);\n    PJ_UNUSED_ARG(bits_per_sample);\n    PJ_UNUSED_ARG(options);\n    PJ_UNUSED_ARG(p_slot);\n    PJ_UNUSED_ARG(p_port);\n\n    return PJ_ENOTSUP;\n}\n\n\n\n/*\n * Change TX and RX settings for the port.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_configure_port( pjmedia_conf *conf,\n\t\t\t\t\t\t  unsigned slot,\n\t\t\t\t\t\t  pjmedia_port_op tx,\n\t\t\t\t\t\t  pjmedia_port_op rx)\n{\n    struct conf_port *conf_port;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);\n\n    pj_mutex_lock(conf->mutex);\n\n    /* Port must be valid. */\n    conf_port = conf->ports[slot];\n    if (conf_port == NULL) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    if (tx != PJMEDIA_PORT_NO_CHANGE)\n\tconf_port->tx_setting = tx;\n\n    if (rx != PJMEDIA_PORT_NO_CHANGE)\n\tconf_port->rx_setting = rx;\n\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Connect port.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_connect_port( pjmedia_conf *conf,\n\t\t\t\t\t       unsigned src_slot,\n\t\t\t\t\t       unsigned sink_slot,\n\t\t\t\t\t       int level )\n{\n    struct conf_port *src_port, *dst_port;\n    pj_bool_t start_sound = PJ_FALSE;\n    pjmedia_audio_format_detail *src_afd, *dst_afd;\n    unsigned i;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && src_slot<conf->max_ports && \n\t\t     sink_slot<conf->max_ports, PJ_EINVAL);\n\n    /* For now, level MUST be zero. */\n    PJ_ASSERT_RETURN(level == 0, PJ_EINVAL);\n\n    pj_mutex_lock(conf->mutex);\n\n    /* Ports must be valid. */\n    src_port = conf->ports[src_slot];\n    dst_port = conf->ports[sink_slot];\n    if (!src_port || !dst_port) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    src_afd = pjmedia_format_get_audio_format_detail(&src_port->info->fmt, 1);\n    dst_afd = pjmedia_format_get_audio_format_detail(&dst_port->info->fmt, 1);\n\n    /* Format must match. */\n    if (src_port->info->fmt.id != dst_port->info->fmt.id ||\n\tsrc_afd->avg_bps != dst_afd->avg_bps)\n    {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJMEDIA_ENOTCOMPATIBLE;\n    }\n\n    /* Clock rate must match. */\n    if (src_afd->clock_rate != dst_afd->clock_rate) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJMEDIA_ENCCLOCKRATE;\n    }\n\n    /* Channel count must match. */\n    if (src_afd->channel_count != dst_afd->channel_count) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJMEDIA_ENCCHANNEL;\n    }\n\n    /* Source and sink ptime must be equal or a multiplication factor. */\n    if ((src_afd->frame_time_usec % dst_afd->frame_time_usec != 0) &&\n        (dst_afd->frame_time_usec % src_afd->frame_time_usec != 0))\n    {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJMEDIA_ENCSAMPLESPFRAME;\n    }\n    \n    /* If sink is currently listening to other ports, it needs to be released\n     * first before the new connection made.\n     */ \n    if (dst_port->transmitter_cnt > 0) {\n\tunsigned j;\n\tpj_bool_t transmitter_found = PJ_FALSE;\n\n\tpj_assert(dst_port->transmitter_cnt == 1);\n\tfor (j=0; j<conf->max_ports && !transmitter_found; ++j) {\n\t    if (conf->ports[j]) {\n\t\tunsigned k;\n\n\t\tfor (k=0; k < conf->ports[j]->listener_cnt; ++k) {\n\t\t    if (conf->ports[j]->listener_slots[k] == sink_slot) {\n\t\t\tPJ_LOG(2,(THIS_FILE, \"Connection [%d->%d] is \"\n\t\t\t\t  \"disconnected for new connection [%d->%d]\",\n\t\t\t\t  j, sink_slot, src_slot, sink_slot));\n\t\t\tpjmedia_conf_disconnect_port(conf, j, sink_slot);\n\t\t\ttransmitter_found = PJ_TRUE;\n\t\t\tbreak;\n\t\t    }\n\t\t}\n\t    }\n\t}\n\tpj_assert(dst_port->transmitter_cnt == 0);\n    }\n\n    /* Check if connection has been made */\n    for (i=0; i<src_port->listener_cnt; ++i) {\n\tif (src_port->listener_slots[i] == sink_slot)\n\t    break;\n    }\n\n    /* Update master port info shortcut, note that application may update\n     * the master port info when the audio device needs to be reopened with\n     * a new format to match to ports connection format.\n     */\n    conf->ports[0]->samples_per_frame = PJMEDIA_PIA_SPF(conf->ports[0]->info);\n\n    if (i == src_port->listener_cnt) {\n\tsrc_port->listener_slots[src_port->listener_cnt] = sink_slot;\n\t++conf->connect_cnt;\n\t++src_port->listener_cnt;\n\t++dst_port->transmitter_cnt;\n\n\tif (conf->connect_cnt == 1)\n\t    start_sound = 1;\n\n\tPJ_LOG(4,(THIS_FILE,\"Port %d (%.*s) transmitting to port %d (%.*s)\",\n\t\t  src_slot,\n\t\t  (int)src_port->name.slen,\n\t\t  src_port->name.ptr,\n\t\t  sink_slot,\n\t\t  (int)dst_port->name.slen,\n\t\t  dst_port->name.ptr));\n    }\n\n    pj_mutex_unlock(conf->mutex);\n\n    /* Sound device must be started without mutex, otherwise the\n     * sound thread will deadlock (?)\n     */\n    if (start_sound)\n\tresume_sound(conf);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Disconnect port\n */\nPJ_DEF(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf,\n\t\t\t\t\t\t  unsigned src_slot,\n\t\t\t\t\t\t  unsigned sink_slot )\n{\n    struct conf_port *src_port, *dst_port;\n    unsigned i;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && src_slot<conf->max_ports && \n\t\t     sink_slot<conf->max_ports, PJ_EINVAL);\n\n    pj_mutex_lock(conf->mutex);\n\n    /* Ports must be valid. */\n    src_port = conf->ports[src_slot];\n    dst_port = conf->ports[sink_slot];\n    if (!src_port || !dst_port) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    /* Check if connection has been made */\n    for (i=0; i<src_port->listener_cnt; ++i) {\n\tif (src_port->listener_slots[i] == sink_slot)\n\t    break;\n    }\n\n    if (i != src_port->listener_cnt) {\n\tpjmedia_frame_ext *f;\n\n\tpj_assert(src_port->listener_cnt > 0 && \n\t\t  src_port->listener_cnt < conf->max_ports);\n\tpj_assert(dst_port->transmitter_cnt > 0 && \n\t\t  dst_port->transmitter_cnt < conf->max_ports);\n\tpj_array_erase(src_port->listener_slots, sizeof(SLOT_TYPE), \n\t\t       src_port->listener_cnt, i);\n\t--conf->connect_cnt;\n\t--src_port->listener_cnt;\n\t--dst_port->transmitter_cnt;\n\t\n\t/* Cleanup listener TX buffer. */\n\tf = (pjmedia_frame_ext*)dst_port->tx_buf;\n\tf->base.type = PJMEDIA_FRAME_TYPE_NONE;\n\tf->base.size = 0;\n\tf->samples_cnt = 0;\n\tf->subframe_cnt = 0;\n\n\tPJ_LOG(4,(THIS_FILE,\n\t\t  \"Port %d (%.*s) stop transmitting to port %d (%.*s)\",\n\t\t  src_slot,\n\t\t  (int)src_port->name.slen,\n\t\t  src_port->name.ptr,\n\t\t  sink_slot,\n\t\t  (int)dst_port->name.slen,\n\t\t  dst_port->name.ptr));\n    }\n\n    pj_mutex_unlock(conf->mutex);\n\n    if (conf->connect_cnt == 0) {\n\tpause_sound(conf);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get number of ports currently registered to the conference bridge.\n */\nPJ_DEF(unsigned) pjmedia_conf_get_port_count(pjmedia_conf *conf)\n{\n    return conf->port_cnt;\n}\n\n/*\n * Get total number of ports connections currently set up in the bridge.\n */\nPJ_DEF(unsigned) pjmedia_conf_get_connect_count(pjmedia_conf *conf)\n{\n    return conf->connect_cnt;\n}\n\n\n/*\n * Remove the specified port.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf,\n\t\t\t\t\t      unsigned port )\n{\n    struct conf_port *conf_port;\n    unsigned i;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && port < conf->max_ports, PJ_EINVAL);\n\n    /* Suspend the sound devices.\n     * Don't want to remove port while port is being accessed by sound\n     * device's threads!\n     */\n\n    pj_mutex_lock(conf->mutex);\n\n    /* Port must be valid. */\n    conf_port = conf->ports[port];\n    if (conf_port == NULL) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    conf_port->tx_setting = PJMEDIA_PORT_DISABLE;\n    conf_port->rx_setting = PJMEDIA_PORT_DISABLE;\n\n    /* Remove this port from transmit array of other ports. */\n    for (i=0; i<conf->max_ports; ++i) {\n\tunsigned j;\n\tstruct conf_port *src_port;\n\n\tsrc_port = conf->ports[i];\n\n\tif (!src_port)\n\t    continue;\n\n\tif (src_port->listener_cnt == 0)\n\t    continue;\n\n\tfor (j=0; j<src_port->listener_cnt; ++j) {\n\t    if (src_port->listener_slots[j] == port) {\n\t\tpj_array_erase(src_port->listener_slots, sizeof(SLOT_TYPE),\n\t\t\t       src_port->listener_cnt, j);\n\t\tpj_assert(conf->connect_cnt > 0);\n\t\t--conf->connect_cnt;\n\t\t--src_port->listener_cnt;\n\t\tbreak;\n\t    }\n\t}\n    }\n\n    /* Update transmitter_cnt of ports we're transmitting to */\n    while (conf_port->listener_cnt) {\n\tunsigned dst_slot;\n\tstruct conf_port *dst_port;\n\tpjmedia_frame_ext *f;\n\n\tdst_slot = conf_port->listener_slots[conf_port->listener_cnt-1];\n\tdst_port = conf->ports[dst_slot];\n\t--dst_port->transmitter_cnt;\n\t--conf_port->listener_cnt;\n\tpj_assert(conf->connect_cnt > 0);\n\t--conf->connect_cnt;\n\n\t/* Cleanup & reinit listener TX buffer. */\n\tf = (pjmedia_frame_ext*)dst_port->tx_buf;\n\tf->base.type = PJMEDIA_FRAME_TYPE_NONE;\n\tf->base.size = 0;\n\tf->samples_cnt = 0;\n\tf->subframe_cnt = 0;\n    }\n\n    /* Remove the port. */\n    conf->ports[port] = NULL;\n    --conf->port_cnt;\n\n    pj_mutex_unlock(conf->mutex);\n\n\n    /* Stop sound if there's no connection. */\n    if (conf->connect_cnt == 0) {\n\tpause_sound(conf);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Enum ports.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_enum_ports( pjmedia_conf *conf,\n\t\t\t\t\t     unsigned ports[],\n\t\t\t\t\t     unsigned *p_count )\n{\n    unsigned i, count=0;\n\n    PJ_ASSERT_RETURN(conf && p_count && ports, PJ_EINVAL);\n\n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    for (i=0; i<conf->max_ports && count<*p_count; ++i) {\n\tif (!conf->ports[i])\n\t    continue;\n\n\tports[count++] = i;\n    }\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    *p_count = count;\n    return PJ_SUCCESS;\n}\n\n/*\n * Get port info\n */\nPJ_DEF(pj_status_t) pjmedia_conf_get_port_info( pjmedia_conf *conf,\n\t\t\t\t\t\tunsigned slot,\n\t\t\t\t\t\tpjmedia_conf_port_info *info)\n{\n    struct conf_port *conf_port;\n    const pjmedia_audio_format_detail *afd;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);\n\n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    /* Port must be valid. */\n    conf_port = conf->ports[slot];\n    if (conf_port == NULL) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    afd = pjmedia_format_get_audio_format_detail(&conf_port->info->fmt, 1);\n\n    pj_bzero(info, sizeof(pjmedia_conf_port_info));\n\n    info->slot = slot;\n    info->name = conf_port->name;\n    info->tx_setting = conf_port->tx_setting;\n    info->rx_setting = conf_port->rx_setting;\n    info->listener_cnt = conf_port->listener_cnt;\n    info->listener_slots = conf_port->listener_slots;\n    info->transmitter_cnt = conf_port->transmitter_cnt;\n    info->clock_rate = afd->clock_rate;\n    info->channel_count = afd->channel_count;\n    info->samples_per_frame = conf_port->samples_per_frame;\n    info->bits_per_sample = afd->bits_per_sample;\n    info->format = conf_port->port->info.fmt;\n    info->tx_adj_level = conf_port->tx_adj_level - NORMAL_LEVEL;\n    info->rx_adj_level = conf_port->rx_adj_level - NORMAL_LEVEL;\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_conf_get_ports_info(pjmedia_conf *conf,\n\t\t\t\t\t\tunsigned *size,\n\t\t\t\t\t\tpjmedia_conf_port_info info[])\n{\n    unsigned i, count=0;\n\n    PJ_ASSERT_RETURN(conf && size && info, PJ_EINVAL);\n\n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    for (i=0; i<conf->max_ports && count<*size; ++i) {\n\tif (!conf->ports[i])\n\t    continue;\n\n\tpjmedia_conf_get_port_info(conf, i, &info[count]);\n\t++count;\n    }\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    *size = count;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get signal level.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_get_signal_level( pjmedia_conf *conf,\n\t\t\t\t\t\t   unsigned slot,\n\t\t\t\t\t\t   unsigned *tx_level,\n\t\t\t\t\t\t   unsigned *rx_level)\n{\n    struct conf_port *conf_port;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);\n\n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    /* Port must be valid. */\n    conf_port = conf->ports[slot];\n    if (conf_port == NULL) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    if (tx_level != NULL) {\n\t*tx_level = conf_port->tx_level;\n    }\n\n    if (rx_level != NULL) \n\t*rx_level = conf_port->rx_level;\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Adjust RX level of individual port.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_adjust_rx_level( pjmedia_conf *conf,\n\t\t\t\t\t\t  unsigned slot,\n\t\t\t\t\t\t  int adj_level )\n{\n    struct conf_port *conf_port;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);\n\n    /* Value must be from -128 to +127 */\n    /* Disabled, you can put more than +127, at your own risk: \n     PJ_ASSERT_RETURN(adj_level >= -128 && adj_level <= 127, PJ_EINVAL);\n     */\n    PJ_ASSERT_RETURN(adj_level >= -128, PJ_EINVAL);\n\n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    /* Port must be valid. */\n    conf_port = conf->ports[slot];\n    if (conf_port == NULL) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    /* Level adjustment is applicable only for ports that work with raw PCM. */\n    PJ_ASSERT_RETURN(conf_port->info->fmt.id == PJMEDIA_FORMAT_L16,\n\t\t     PJ_EIGNORED);\n\n    /* Set normalized adjustment level. */\n    conf_port->rx_adj_level = adj_level + NORMAL_LEVEL;\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Adjust TX level of individual port.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_adjust_tx_level( pjmedia_conf *conf,\n\t\t\t\t\t\t  unsigned slot,\n\t\t\t\t\t\t  int adj_level )\n{\n    struct conf_port *conf_port;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);\n\n    /* Value must be from -128 to +127 */\n    /* Disabled, you can put more than +127,, at your own risk:\n     PJ_ASSERT_RETURN(adj_level >= -128 && adj_level <= 127, PJ_EINVAL);\n     */\n    PJ_ASSERT_RETURN(adj_level >= -128, PJ_EINVAL);\n\n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    /* Port must be valid. */\n    conf_port = conf->ports[slot];\n    if (conf_port == NULL) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    /* Level adjustment is applicable only for ports that work with raw PCM. */\n    PJ_ASSERT_RETURN(conf_port->info->fmt.id == PJMEDIA_FORMAT_L16,\n\t\t     PJ_EIGNORED);\n\n    /* Set normalized adjustment level. */\n    conf_port->tx_adj_level = adj_level + NORMAL_LEVEL;\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n/* Deliver frm_src to a listener port, eventually call  port's put_frame() \n * when samples count in the frm_dst are equal to port's samples_per_frame.\n */\nstatic pj_status_t write_frame(struct conf_port *cport_dst,\n\t\t\t       const pjmedia_frame *frm_src)\n{\n    pjmedia_frame *frm_dst = (pjmedia_frame*)cport_dst->tx_buf;\n    \n    PJ_TODO(MAKE_SURE_DEST_FRAME_HAS_ENOUGH_SPACE);\n\n    frm_dst->type = frm_src->type;\n    frm_dst->timestamp = cport_dst->ts_tx;\n\n    if (frm_src->type == PJMEDIA_FRAME_TYPE_EXTENDED) {\n\n\tpjmedia_frame_ext *f_src = (pjmedia_frame_ext*)frm_src;\n\tpjmedia_frame_ext *f_dst = (pjmedia_frame_ext*)frm_dst;\n\tunsigned i;\n\n\tfor (i = 0; i < f_src->subframe_cnt; ++i) {\n\t    pjmedia_frame_ext_subframe *sf;\n\t    \n\t    /* Copy frame to listener's TX buffer. */\n\t    sf = pjmedia_frame_ext_get_subframe(f_src, i);\n\t    pjmedia_frame_ext_append_subframe(f_dst, sf->data, sf->bitlen, \n\t\t\t\t\t      f_src->samples_cnt / \n\t\t\t\t\t      f_src->subframe_cnt);\n\n\t    /* Check if it's time to deliver the TX buffer to listener, \n\t     * i.e: samples count in TX buffer equal to listener's\n\t     * samples per frame.\n\t     */\n\t    if (f_dst->samples_cnt >= cport_dst->samples_per_frame)\n\t    {\n\t\tif (cport_dst->slot) {\n\t\t    pjmedia_port_put_frame(cport_dst->port, \n\t\t\t\t\t   (pjmedia_frame*)f_dst);\n\n\t\t    /* Reset TX buffer. */\n\t\t    f_dst->subframe_cnt = 0;\n\t\t    f_dst->samples_cnt = 0;\n\t\t}\n\n\t\t/* Update TX timestamp. */\n\t\tpj_add_timestamp32(&cport_dst->ts_tx,\n\t\t\t\t   cport_dst->samples_per_frame);\n\t    }\n\t}\n\n    } else if (frm_src->type == PJMEDIA_FRAME_TYPE_AUDIO) {\n\n\tpj_int16_t *f_start, *f_end;\n\n\tf_start = (pj_int16_t*)frm_src->buf;\n\tf_end   = f_start + (frm_src->size >> 1);\n\n\twhile (f_start < f_end) {\n\t    unsigned nsamples_to_copy, nsamples_req;\n\n\t    /* Copy frame to listener's TX buffer.\n\t     * Note that if the destination is port 0, just copy the whole\n\t     * available samples.\n\t     */\n\t    nsamples_to_copy = f_end - f_start;\n\t    nsamples_req = cport_dst->samples_per_frame -\n\t\t\t  (frm_dst->size>>1);\n\t    if (cport_dst->slot && nsamples_to_copy > nsamples_req)\n\t\tnsamples_to_copy = nsamples_req;\n\n\t    /* Adjust TX level. */\n\t    if (cport_dst->tx_adj_level != NORMAL_LEVEL) {\n\t\tpj_int16_t *p, *p_end;\n\n\t\tp = f_start;\n\t\tp_end = p + nsamples_to_copy;\n\t\twhile (p < p_end) {\n\t\t    pj_int32_t itemp = *p;\n\n\t\t    /* Adjust the level */\n\t\t    itemp = (itemp * cport_dst->tx_adj_level) >> 7;\n\n\t\t    /* Clip the signal if it's too loud */\n\t\t    if (itemp > MAX_LEVEL) itemp = MAX_LEVEL;\n\t\t    else if (itemp < MIN_LEVEL) itemp = MIN_LEVEL;\n\n\t\t    /* Put back in the buffer. */\n\t\t    *p = (pj_int16_t)itemp;\n\t\t    ++p;\n\t\t}\n\t    }\n\n\t    pjmedia_copy_samples((pj_int16_t*)frm_dst->buf + (frm_dst->size>>1),\n\t\t\t\t f_start, \n\t\t\t\t nsamples_to_copy);\n\t    frm_dst->size += nsamples_to_copy << 1;\n\t    f_start += nsamples_to_copy;\n\n\t    /* Check if it's time to deliver the TX buffer to listener, \n\t     * i.e: samples count in TX buffer equal to listener's\n\t     * samples per frame. Note that for destination port 0 this\n\t     * function will just populate all samples in the TX buffer.\n\t     */\n\t    if (cport_dst->slot == 0) {\n\t\t/* Update TX timestamp. */\n\t\tpj_add_timestamp32(&cport_dst->ts_tx, nsamples_to_copy);\n\t    } else if ((frm_dst->size >> 1) == \n\t\t       cport_dst->samples_per_frame)\n\t    {\n\t\tpjmedia_port_put_frame(cport_dst->port, frm_dst);\n\n\t\t/* Reset TX buffer. */\n\t\tfrm_dst->size = 0;\n\n\t\t/* Update TX timestamp. */\n\t\tpj_add_timestamp32(&cport_dst->ts_tx, \n\t\t\t\t   cport_dst->samples_per_frame);\n\t    }\n\t}\n\n    } else if (frm_src->type == PJMEDIA_FRAME_TYPE_NONE) {\n\n\t/* Check port format. */\n\tif (cport_dst->port &&\n\t    cport_dst->port->info.fmt.id == PJMEDIA_FORMAT_L16)\n\t{\n\t    /* When there is already some samples in listener's TX buffer, \n\t     * pad the buffer with \"zero samples\".\n\t     */\n\t    if (frm_dst->size != 0) {\n\t\tpjmedia_zero_samples((pj_int16_t*)frm_dst->buf,\n\t\t\t\t     cport_dst->samples_per_frame -\n\t\t\t\t     (frm_dst->size>>1));\n\n\t\tfrm_dst->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\t\tfrm_dst->size = cport_dst->samples_per_frame << 1;\n\t\tif (cport_dst->slot) {\n\t\t    pjmedia_port_put_frame(cport_dst->port, frm_dst);\n\n\t\t    /* Reset TX buffer. */\n\t\t    frm_dst->size = 0;\n\t\t}\n\n\t\t/* Update TX timestamp. */\n\t\tpj_add_timestamp32(&cport_dst->ts_tx, \n\t\t\t\t   cport_dst->samples_per_frame);\n\t    }\n\t} else {\n\t    pjmedia_frame_ext *f_dst = (pjmedia_frame_ext*)frm_dst;\n\n\t    if (f_dst->samples_cnt != 0) {\n\t\tfrm_dst->type = PJMEDIA_FRAME_TYPE_EXTENDED;\n\t\tpjmedia_frame_ext_append_subframe(f_dst, NULL, 0, (pj_uint16_t)\n\t\t    (cport_dst->samples_per_frame - f_dst->samples_cnt));\n\t\tif (cport_dst->slot) {\n\t\t    pjmedia_port_put_frame(cport_dst->port, frm_dst);\n\n\t\t    /* Reset TX buffer. */\n\t\t    f_dst->subframe_cnt = 0;\n\t\t    f_dst->samples_cnt = 0;\n\t\t}\n\n\t\t/* Update TX timestamp. */\n\t\tpj_add_timestamp32(&cport_dst->ts_tx, \n\t\t\t\t   cport_dst->samples_per_frame);\n\t    }\n\t}\n\n\t/* Synchronize clock. */\n\twhile (pj_cmp_timestamp(&cport_dst->ts_clock, \n\t\t\t\t&cport_dst->ts_tx) > 0)\n\t{\n\t    frm_dst->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    frm_dst->timestamp = cport_dst->ts_tx;\n\t    if (cport_dst->slot)\n\t\tpjmedia_port_put_frame(cport_dst->port, frm_dst);\n\n\t    /* Update TX timestamp. */\n\t    pj_add_timestamp32(&cport_dst->ts_tx, cport_dst->samples_per_frame);\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Player callback.\n */\nstatic pj_status_t get_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame)\n{\n    pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;\n    unsigned ci, i;\n    \n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    /* Call get_frame() from all ports (except port 0) that has \n     * receiver and distribute the frame (put the frame to the destination \n     * port's buffer to accommodate different ptime, and ultimately call \n     * put_frame() of that port) to ports that are receiving from this port.\n     */\n    for (i=1, ci=1; i<conf->max_ports && ci<conf->port_cnt; ++i) {\n\tstruct conf_port *cport = conf->ports[i];\n\tunsigned master_samples_per_frame;\n\n\t/* Skip empty port. */\n\tif (!cport)\n\t    continue;\n\n\t/* Var \"ci\" is to count how many ports have been visited so far. */\n\t++ci;\n\n\tmaster_samples_per_frame = PJMEDIA_PIA_SPF(&conf->master_port->info);\n\n\t/* Update clock of the port. */\n\tpj_add_timestamp32(&cport->ts_clock, master_samples_per_frame);\n\n\t/* Skip if we're not allowed to receive from this port or \n\t * the port doesn't have listeners.\n\t */\n\tif (cport->rx_setting == PJMEDIA_PORT_DISABLE || \n\t    cport->listener_cnt == 0)\n\t{\n\t    cport->rx_level = 0;\n\t    pj_add_timestamp32(&cport->ts_rx, master_samples_per_frame);\n\t    continue;\n\t}\n\n\t/* Get frame from each port, put it to the listener TX buffer,\n\t * and eventually call put_frame() of the listener. This loop \n\t * will also make sure the ptime between conf & port synchronized.\n\t */\n\twhile (pj_cmp_timestamp(&cport->ts_clock, &cport->ts_rx) > 0) {\n\t    pjmedia_frame *f = (pjmedia_frame*)conf->buf;\n\t    pj_status_t status;\n\t    unsigned j;\n\t    pj_int32_t level = 0;\n\n\t    pj_add_timestamp32(&cport->ts_rx, cport->samples_per_frame);\n\t    \n\t    f->buf = &conf->buf[sizeof(pjmedia_frame)];\n\t    f->size = cport->samples_per_frame<<1;\n\n\t    /* Get frame from port. */\n\t    status = pjmedia_port_get_frame(cport->port, f);\n\t    if (status != PJ_SUCCESS)\n\t\tcontinue;\n\n\t    /* Calculate & adjust RX level. */\n\t    if (f->type == PJMEDIA_FRAME_TYPE_AUDIO) {\n\t\tif (cport->rx_adj_level != NORMAL_LEVEL) {\n\t\t    pj_int16_t *p = (pj_int16_t*)f->buf;\n\t\t    pj_int16_t *end;\n\n\t\t    end = p + (f->size >> 1);\n\t\t    while (p < end) {\n\t\t\tpj_int32_t itemp = *p;\n\n\t\t\t/* Adjust the level */\n\t\t\titemp = (itemp * cport->rx_adj_level) >> 7;\n\n\t\t\t/* Clip the signal if it's too loud */\n\t\t\tif (itemp > MAX_LEVEL) itemp = MAX_LEVEL;\n\t\t\telse if (itemp < MIN_LEVEL) itemp = MIN_LEVEL;\n\n\t\t\tlevel += PJ_ABS(itemp);\n\n\t\t\t/* Put back in the buffer. */\n\t\t\t*p = (pj_int16_t)itemp;\n\t\t\t++p;\n\t\t    }\n\t\t    level /= (f->size >> 1);\n\t\t} else {\n\t\t    level = pjmedia_calc_avg_signal((const pj_int16_t*)f->buf,\n\t\t\t\t\t\t    f->size >> 1);\n\t\t}\n\t    } else if (f->type == PJMEDIA_FRAME_TYPE_EXTENDED) {\n\t\t/* For extended frame, level is unknown, so we just set \n\t\t * it to NORMAL_LEVEL. \n\t\t */\n\t\tlevel = NORMAL_LEVEL;\n\t    }\n\n\t    cport->rx_level = pjmedia_linear2ulaw(level) ^ 0xff;\n\n\t    /* Put the frame to all listeners. */\n\t    for (j=0; j < cport->listener_cnt; ++j) \n\t    {\n\t\tstruct conf_port *listener;\n\n\t\tlistener = conf->ports[cport->listener_slots[j]];\n\n\t\t/* Skip if this listener doesn't want to receive audio */\n\t\tif (listener->tx_setting == PJMEDIA_PORT_DISABLE) {\n\t\t    pj_add_timestamp32(&listener->ts_tx, \n\t\t\t\t       listener->samples_per_frame);\n\t\t    listener->tx_level = 0;\n\t\t    continue;\n\t\t}\n    \t    \n\t\tstatus = write_frame(listener, f);\n\t\tif (status != PJ_SUCCESS) {\n\t\t    listener->tx_level = 0;\n\t\t    continue;\n\t\t}\n\n\t\t/* Set listener TX level based on transmitter RX level & \n\t\t * listener TX level.\n\t\t */\n\t\tlistener->tx_level = (cport->rx_level * listener->tx_adj_level)\n\t\t\t\t     >> 8;\n\t    }\n\t}\n    }\n\n    /* Keep alive. Update TX timestamp and send frame type NONE to all \n     * underflow ports at their own clock.\n     */\n    for (i=1, ci=1; i<conf->max_ports && ci<conf->port_cnt; ++i) {\n\tstruct conf_port *cport = conf->ports[i];\n\n\t/* Skip empty port. */\n\tif (!cport)\n\t    continue;\n\n\t/* Var \"ci\" is to count how many ports have been visited so far. */\n\t++ci;\n\n\tif (cport->tx_setting==PJMEDIA_PORT_MUTE || cport->transmitter_cnt==0)\n\t{\n\t    pjmedia_frame_ext *f;\n\t    \n\t    /* Clear left-over samples in tx_buffer, if any, so that it won't\n\t     * be transmitted next time we have audio signal.\n\t     */\n\t    f = (pjmedia_frame_ext*)cport->tx_buf;\n\t    f->base.type = PJMEDIA_FRAME_TYPE_NONE;\n\t    f->base.size = 0;\n\t    f->samples_cnt = 0;\n\t    f->subframe_cnt = 0;\n\t    \n\t    cport->tx_level = 0;\n\n\t    while (pj_cmp_timestamp(&cport->ts_clock, &cport->ts_tx) > 0)\n\t    {\n\t\tif (cport->tx_setting == PJMEDIA_PORT_ENABLE) {\n\t\t    pjmedia_frame tmp_f;\n\n\t\t    tmp_f.timestamp = cport->ts_tx;\n\t\t    tmp_f.type = PJMEDIA_FRAME_TYPE_NONE;\n\t\t    tmp_f.buf = NULL;\n\t\t    tmp_f.size = 0;\n\n\t\t    pjmedia_port_put_frame(cport->port, &tmp_f);\n\t\t    pj_add_timestamp32(&cport->ts_tx, cport->samples_per_frame);\n\t\t}\n\t    }\n\t}\n    }\n\n    /* Return sound playback frame. */\n    do {\n\tstruct conf_port *this_cport = conf->ports[this_port->port_data.ldata];\n\tpjmedia_frame *f_src = (pjmedia_frame*) this_cport->tx_buf;\n\n\tframe->type = f_src->type;\n\n\tif (f_src->type == PJMEDIA_FRAME_TYPE_EXTENDED) {\n\t    pjmedia_frame_ext *f_src_ = (pjmedia_frame_ext*)f_src;\n\t    pjmedia_frame_ext *f_dst = (pjmedia_frame_ext*)frame;\n\t    pjmedia_frame_ext_subframe *sf;\n\t    unsigned samples_per_subframe;\n\t    \n\t    if (f_src_->samples_cnt < this_cport->samples_per_frame) {\n\t\tf_dst->base.type = PJMEDIA_FRAME_TYPE_NONE;\n\t\tf_dst->samples_cnt = 0;\n\t\tf_dst->subframe_cnt = 0;\n\t\tbreak;\n\t    }\n\n\t    f_dst->samples_cnt = 0;\n\t    f_dst->subframe_cnt = 0;\n\t    i = 0;\n\t    samples_per_subframe = f_src_->samples_cnt / f_src_->subframe_cnt;\n\n\n\t    while (f_dst->samples_cnt < this_cport->samples_per_frame) {\n\t\tsf = pjmedia_frame_ext_get_subframe(f_src_, i++);\n\t\tpj_assert(sf);\n\t\tpjmedia_frame_ext_append_subframe(f_dst, sf->data, sf->bitlen,\n\t\t\t\t\t\t  samples_per_subframe);\n\t    }\n\n\t    /* Shift left TX buffer. */\n\t    pjmedia_frame_ext_pop_subframes(f_src_, i);\n\n\t} else if (f_src->type == PJMEDIA_FRAME_TYPE_AUDIO) {\n\t    if ((f_src->size>>1) < this_cport->samples_per_frame) {\n\t\tframe->type = PJMEDIA_FRAME_TYPE_NONE;\n\t\tframe->size = 0;\n\t\tbreak;\n\t    }\n\n\t    pjmedia_copy_samples((pj_int16_t*)frame->buf, \n\t\t\t\t (pj_int16_t*)f_src->buf, \n\t\t\t\t this_cport->samples_per_frame);\n\t    frame->size = this_cport->samples_per_frame << 1;\n\n\t    /* Shift left TX buffer. */\n\t    f_src->size -= frame->size;\n\t    if (f_src->size)\n\t\tpjmedia_move_samples((pj_int16_t*)f_src->buf,\n\t\t\t\t     (pj_int16_t*)f_src->buf + \n\t\t\t\t     this_cport->samples_per_frame,\n\t\t\t\t     f_src->size >> 1);\n\t} else { /* PJMEDIA_FRAME_TYPE_NONE */\n\t    pjmedia_frame_ext *f_src_ = (pjmedia_frame_ext*)f_src;\n\n\t    /* Reset source/TX buffer */\n\t    f_src_->base.size = 0;\n\t    f_src_->samples_cnt = 0;\n\t    f_src_->subframe_cnt = 0;\n\t}\n    } while (0);\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Recorder callback.\n */\nstatic pj_status_t put_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *f)\n{\n    pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;\n    struct conf_port *cport;\n    unsigned j;\n    pj_int32_t level = 0;\n\n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    /* Get conf port of this port */\n    cport = conf->ports[this_port->port_data.ldata];\n    if (cport == NULL) {\n\t/* Unlock mutex */\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_SUCCESS;\n    }\n\n    pj_add_timestamp32(&cport->ts_rx, cport->samples_per_frame);\n    \n    /* Skip if this port is muted/disabled. */\n    if (cport->rx_setting == PJMEDIA_PORT_DISABLE) {\n\tcport->rx_level = 0;\n\t/* Unlock mutex */\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_SUCCESS;\n    }\n\n    /* Skip if no port is listening to the microphone */\n    if (cport->listener_cnt == 0) {\n\tcport->rx_level = 0;\n\t/* Unlock mutex */\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_SUCCESS;\n    }\n\n    /* Calculate & adjust RX level. */\n    if (f->type == PJMEDIA_FRAME_TYPE_AUDIO) {\n\tif (cport->rx_adj_level != NORMAL_LEVEL) {\n\t    pj_int16_t *p = (pj_int16_t*)f->buf;\n\t    pj_int16_t *end;\n\n\t    end = p + (f->size >> 1);\n\t    while (p < end) {\n\t\tpj_int32_t itemp = *p;\n\n\t\t/* Adjust the level */\n\t\titemp = (itemp * cport->rx_adj_level) >> 7;\n\n\t\t/* Clip the signal if it's too loud */\n\t\tif (itemp > MAX_LEVEL) itemp = MAX_LEVEL;\n\t\telse if (itemp < MIN_LEVEL) itemp = MIN_LEVEL;\n\n\t\tlevel += PJ_ABS(itemp);\n\n\t\t/* Put back in the buffer. */\n\t\t*p = (pj_int16_t)itemp;\n\t\t++p;\n\t    }\n\t    level /= (f->size >> 1);\n\t} else {\n\t    level = pjmedia_calc_avg_signal((const pj_int16_t*)f->buf,\n\t\t\t\t\t    f->size >> 1);\n\t}\n    } else if (f->type == PJMEDIA_FRAME_TYPE_EXTENDED) {\n\t/* For extended frame, level is unknown, so we just set \n\t * it to NORMAL_LEVEL. \n\t */\n\tlevel = NORMAL_LEVEL;\n    }\n\n    cport->rx_level = pjmedia_linear2ulaw(level) ^ 0xff;\n\n    /* Put the frame to all listeners. */\n    for (j=0; j < cport->listener_cnt; ++j) \n    {\n\tstruct conf_port *listener;\n\tpj_status_t status;\n\n\tlistener = conf->ports[cport->listener_slots[j]];\n\n\t/* Skip if this listener doesn't want to receive audio */\n\tif (listener->tx_setting == PJMEDIA_PORT_DISABLE) {\n\t    pj_add_timestamp32(&listener->ts_tx, \n\t\t\t       listener->samples_per_frame);\n\t    listener->tx_level = 0;\n\t    continue;\n\t}\n\n\t/* Skip loopback for now. */\n\tif (listener == cport) {\n\t    pj_add_timestamp32(&listener->ts_tx, \n\t\t\t       listener->samples_per_frame);\n\t    listener->tx_level = 0;\n\t    continue;\n\t}\n\t    \n\tstatus = write_frame(listener, f);\n\tif (status != PJ_SUCCESS) {\n\t    listener->tx_level = 0;\n\t    continue;\n\t}\n\n\t/* Set listener TX level based on transmitter RX level & listener\n\t * TX level.\n\t */\n\tlistener->tx_level = (cport->rx_level * listener->tx_adj_level) >> 8;\n    }\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/conference.c",
    "content": "/* $Id: conference.c 4198 2012-07-05 10:25:46Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/conference.h>\n#include <pjmedia/alaw_ulaw.h>\n#include <pjmedia/delaybuf.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/port.h>\n#include <pjmedia/resample.h>\n#include <pjmedia/silencedet.h>\n#include <pjmedia/sound_port.h>\n#include <pjmedia/stereo.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#if !defined(PJMEDIA_CONF_USE_SWITCH_BOARD) || PJMEDIA_CONF_USE_SWITCH_BOARD==0\n\n/* CONF_DEBUG enables detailed operation of the conference bridge.\n * Beware that it prints large amounts of logs (several lines per frame).\n */\n//#define CONF_DEBUG\n#ifdef CONF_DEBUG\n#   include <stdio.h>\n#   define TRACE_(x)   PJ_LOG(5,x)\n#else\n#   define TRACE_(x)\n#endif\n\n\n/* REC_FILE macro enables recording of the samples written to the sound\n * device. The file contains RAW PCM data with no header, and has the\n * same settings (clock rate etc) as the conference bridge.\n * This should only be enabled when debugging audio quality *only*.\n */\n//#define REC_FILE    \"confrec.pcm\"\n#ifdef REC_FILE\nstatic FILE *fhnd_rec;\n#endif\n\n\n#define THIS_FILE\t\"conference.c\"\n\n#define RX_BUF_COUNT\t    PJMEDIA_SOUND_BUFFER_COUNT\n\n#define BYTES_PER_SAMPLE    2\n\n#define SIGNATURE\t    PJMEDIA_CONF_BRIDGE_SIGNATURE\n#define SIGNATURE_PORT\t    PJMEDIA_SIG_PORT_CONF_PASV\n/* Normal level is hardcodec to 128 in all over places */\n#define NORMAL_LEVEL\t    128\n#define SLOT_TYPE\t    unsigned\n#define INVALID_SLOT\t    ((SLOT_TYPE)-1)\n\n\n/* These are settings to control the adaptivity of changes in the\n * signal level of the ports, so that sudden change in signal level\n * in the port does not cause misaligned signal (which causes noise).\n */\n#define ATTACK_A    (conf->clock_rate / conf->samples_per_frame)\n#define ATTACK_B    1\n#define DECAY_A\t    0\n#define DECAY_B\t    1\n\n#define SIMPLE_AGC(last, target) \\\n    if (target >= last) \\\n\ttarget = (ATTACK_A*(last+1)+ATTACK_B*target)/(ATTACK_A+ATTACK_B); \\\n    else \\\n\ttarget = (DECAY_A*last+DECAY_B*target)/(DECAY_A+DECAY_B)\n\n#define MAX_LEVEL   (32767)\n#define MIN_LEVEL   (-32768)\n\n#define IS_OVERFLOW(s) ((s > MAX_LEVEL) || (s < MIN_LEVEL))\n\n\n/*\n * DON'T GET CONFUSED WITH TX/RX!!\n *\n * TX and RX directions are always viewed from the conference bridge's point\n * of view, and NOT from the port's point of view. So TX means the bridge\n * is transmitting to the port, RX means the bridge is receiving from the\n * port.\n */\n\n\n/**\n * This is a port connected to conference bridge.\n */\nstruct conf_port\n{\n    pj_str_t\t\t name;\t\t/**< Port name.\t\t\t    */\n    pjmedia_port\t*port;\t\t/**< get_frame() and put_frame()    */\n    pjmedia_port_op\t rx_setting;\t/**< Can we receive from this port  */\n    pjmedia_port_op\t tx_setting;\t/**< Can we transmit to this port   */\n    unsigned\t\t listener_cnt;\t/**< Number of listeners.\t    */\n    SLOT_TYPE\t\t*listener_slots;/**< Array of listeners.\t    */\n    unsigned\t\t transmitter_cnt;/**<Number of transmitters.\t    */\n\n    /* Shortcut for port info. */\n    unsigned\t\t clock_rate;\t/**< Port's clock rate.\t\t    */\n    unsigned\t\t samples_per_frame; /**< Port's samples per frame.  */\n    unsigned\t\t channel_count;\t/**< Port's channel count.\t    */\n\n    /* Calculated signal levels: */\n    unsigned\t\t tx_level;\t/**< Last tx level to this port.    */\n    unsigned\t\t rx_level;\t/**< Last rx level from this port.  */\n\n    /* The normalized signal level adjustment.\n     * A value of 128 (NORMAL_LEVEL) means there's no adjustment.\n     */\n    unsigned\t\t tx_adj_level;\t/**< Adjustment for TX.\t\t    */\n    unsigned\t\t rx_adj_level;\t/**< Adjustment for RX.\t\t    */\n\n    /* Resample, for converting clock rate, if they're different. */\n    pjmedia_resample\t*rx_resample;\n    pjmedia_resample\t*tx_resample;\n\n    /* RX buffer is temporary buffer to be used when there is mismatch\n     * between port's sample rate or ptime with conference's sample rate\n     * or ptime. The buffer is used for sampling rate conversion AND/OR to\n     * buffer the samples until there are enough samples to fulfill a \n     * complete frame to be processed by the bridge.\n     *\n     * When both sample rate AND ptime of the port match the conference \n     * settings, this buffer will not be created.\n     * \n     * This buffer contains samples at port's clock rate.\n     * The size of this buffer is the sum between port's samples per frame\n     * and bridge's samples per frame.\n     */\n    pj_int16_t\t\t*rx_buf;\t/**< The RX buffer.\t\t    */\n    unsigned\t\t rx_buf_cap;\t/**< Max size, in samples\t    */\n    unsigned\t\t rx_buf_count;\t/**< # of samples in the buf.\t    */\n\n    /* Mix buf is a temporary buffer used to mix all signal received\n     * by this port from all other ports. The mixed signal will be \n     * automatically adjusted to the appropriate level whenever\n     * there is possibility of clipping.\n     *\n     * This buffer contains samples at bridge's clock rate.\n     * The size of this buffer is equal to samples per frame of the bridge.\n     */\n\n    int\t\t\t mix_adj;\t/**< Adjustment level for mix_buf.  */\n    int\t\t\t last_mix_adj;\t/**< Last adjustment level.\t    */\n    pj_int32_t\t\t*mix_buf;\t/**< Total sum of signal.\t    */\n\n    /* Tx buffer is a temporary buffer to be used when there's mismatch \n     * between port's clock rate or ptime with conference's sample rate\n     * or ptime. This buffer is used as the source of the sampling rate\n     * conversion AND/OR to buffer the samples until there are enough\n     * samples to fulfill a complete frame to be transmitted to the port.\n     *\n     * When both sample rate and ptime of the port match the bridge's \n     * settings, this buffer will not be created.\n     * \n     * This buffer contains samples at port's clock rate.\n     * The size of this buffer is the sum between port's samples per frame\n     * and bridge's samples per frame.\n     */\n    pj_int16_t\t\t*tx_buf;\t/**< Tx buffer.\t\t\t    */\n    unsigned\t\t tx_buf_cap;\t/**< Max size, in samples.\t    */\n    unsigned\t\t tx_buf_count;\t/**< # of samples in the buffer.    */\n\n    /* When the port is not receiving signal from any other ports (e.g. when\n     * no other ports is transmitting to this port), the bridge periodically\n     * transmit NULL frame to the port to keep the port \"alive\" (for example,\n     * a stream port needs this heart-beat to periodically transmit silence\n     * frame to keep NAT binding alive).\n     *\n     * This NULL frame should be sent to the port at the port's ptime rate.\n     * So if the port's ptime is greater than the bridge's ptime, the bridge\n     * needs to delay the NULL frame until it's the right time to do so.\n     *\n     * This variable keeps track of how many pending NULL samples are being\n     * \"held\" for this port. Once this value reaches samples_per_frame\n     * value of the port, a NULL frame is sent. The samples value on this\n     * variable is clocked at the port's clock rate.\n     */\n    unsigned\t\t tx_heart_beat;\n\n    /* Delay buffer is a special buffer for sound device port (port 0, master\n     * port) and other passive ports (sound device port is also passive port).\n     *\n     * We need the delay buffer because we can not expect the mic and speaker \n     * thread to run equally after one another. In most systems, each thread \n     * will run multiple times before the other thread gains execution time. \n     * For example, in my system, mic thread is called three times, then \n     * speaker thread is called three times, and so on. This we call burst.\n     *\n     * There is also possibility of drift, unbalanced rate between put_frame\n     * and get_frame operation, in passive ports. If drift happens, snd_buf\n     * needs to be expanded or shrinked. \n     *\n     * Burst and drift are handled by delay buffer.\n     */\n    pjmedia_delay_buf\t*delay_buf;\n};\n\n\n/*\n * Conference bridge.\n */\nstruct pjmedia_conf\n{\n    unsigned\t\t  options;\t/**< Bitmask options.\t\t    */\n    unsigned\t\t  max_ports;\t/**< Maximum ports.\t\t    */\n    unsigned\t\t  port_cnt;\t/**< Current number of ports.\t    */\n    unsigned\t\t  connect_cnt;\t/**< Total number of connections    */\n    pjmedia_snd_port\t *snd_dev_port;\t/**< Sound device port.\t\t    */\n    pjmedia_port\t *master_port;\t/**< Port zero's port.\t\t    */\n    char\t\t  master_name_buf[80]; /**< Port0 name buffer.\t    */\n    pj_mutex_t\t\t *mutex;\t/**< Conference mutex.\t\t    */\n    struct conf_port\t**ports;\t/**< Array of ports.\t\t    */\n    unsigned\t\t  clock_rate;\t/**< Sampling rate.\t\t    */\n    unsigned\t\t  channel_count;/**< Number of channels (1=mono).   */\n    unsigned\t\t  samples_per_frame;\t/**< Samples per frame.\t    */\n    unsigned\t\t  bits_per_sample;\t/**< Bits per sample.\t    */\n};\n\n\n/* Prototypes */\nstatic pj_status_t put_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame);\nstatic pj_status_t get_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame);\nstatic pj_status_t get_frame_pasv(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame);\nstatic pj_status_t destroy_port(pjmedia_port *this_port);\nstatic pj_status_t destroy_port_pasv(pjmedia_port *this_port);\n\n\n/*\n * Create port.\n */\nstatic pj_status_t create_conf_port( pj_pool_t *pool,\n\t\t\t\t     pjmedia_conf *conf,\n\t\t\t\t     pjmedia_port *port,\n\t\t\t\t     const pj_str_t *name,\n\t\t\t\t     struct conf_port **p_conf_port)\n{\n    struct conf_port *conf_port;\n    pj_status_t status;\n\n    /* Create port. */\n    conf_port = PJ_POOL_ZALLOC_T(pool, struct conf_port);\n    PJ_ASSERT_RETURN(conf_port, PJ_ENOMEM);\n\n    /* Set name */\n    pj_strdup_with_null(pool, &conf_port->name, name);\n\n    /* Default has tx and rx enabled. */\n    conf_port->rx_setting = PJMEDIA_PORT_ENABLE;\n    conf_port->tx_setting = PJMEDIA_PORT_ENABLE;\n\n    /* Default level adjustment is 128 (which means no adjustment) */\n    conf_port->tx_adj_level = NORMAL_LEVEL;\n    conf_port->rx_adj_level = NORMAL_LEVEL;\n\n    /* Create transmit flag array */\n    conf_port->listener_slots = (SLOT_TYPE*)\n\t\t\t\tpj_pool_zalloc(pool, \n\t\t\t\t\t  conf->max_ports * sizeof(SLOT_TYPE));\n    PJ_ASSERT_RETURN(conf_port->listener_slots, PJ_ENOMEM);\n\n    /* Save some port's infos, for convenience. */\n    if (port) {\n\tpjmedia_audio_format_detail *afd;\n\n\tafd = pjmedia_format_get_audio_format_detail(&port->info.fmt, 1);\n\tconf_port->port = port;\n\tconf_port->clock_rate = afd->clock_rate;\n\tconf_port->samples_per_frame = PJMEDIA_AFD_SPF(afd);\n\tconf_port->channel_count = afd->channel_count;\n    } else {\n\tconf_port->port = NULL;\n\tconf_port->clock_rate = conf->clock_rate;\n\tconf_port->samples_per_frame = conf->samples_per_frame;\n\tconf_port->channel_count = conf->channel_count;\n    }\n\n    /* If port's clock rate is different than conference's clock rate,\n     * create a resample sessions.\n     */\n    if (conf_port->clock_rate != conf->clock_rate) {\n\n\tpj_bool_t high_quality;\n\tpj_bool_t large_filter;\n\n\thigh_quality = ((conf->options & PJMEDIA_CONF_USE_LINEAR)==0);\n\tlarge_filter = ((conf->options & PJMEDIA_CONF_SMALL_FILTER)==0);\n\n\t/* Create resample for rx buffer. */\n\tstatus = pjmedia_resample_create( pool, \n\t\t\t\t\t  high_quality,\n\t\t\t\t\t  large_filter,\n\t\t\t\t\t  conf->channel_count,\n\t\t\t\t\t  conf_port->clock_rate,/* Rate in */\n\t\t\t\t\t  conf->clock_rate, /* Rate out */\n\t\t\t\t\t  conf->samples_per_frame * \n\t\t\t\t\t    conf_port->clock_rate /\n\t\t\t\t\t    conf->clock_rate,\n\t\t\t\t\t  &conf_port->rx_resample);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\n\t/* Create resample for tx buffer. */\n\tstatus = pjmedia_resample_create(pool,\n\t\t\t\t\t high_quality,\n\t\t\t\t\t large_filter,\n\t\t\t\t\t conf->channel_count,\n\t\t\t\t\t conf->clock_rate,  /* Rate in */\n\t\t\t\t\t conf_port->clock_rate, /* Rate out */\n\t\t\t\t\t conf->samples_per_frame,\n\t\t\t\t\t &conf_port->tx_resample);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    /*\n     * Initialize rx and tx buffer, only when port's samples per frame or \n     * port's clock rate or channel number is different then the conference\n     * bridge settings.\n     */\n    if (conf_port->clock_rate != conf->clock_rate ||\n\tconf_port->channel_count != conf->channel_count ||\n\tconf_port->samples_per_frame != conf->samples_per_frame)\n    {\n\tunsigned port_ptime, conf_ptime, buff_ptime;\n\n\tport_ptime = conf_port->samples_per_frame / conf_port->channel_count *\n\t    1000 / conf_port->clock_rate;\n\tconf_ptime = conf->samples_per_frame / conf->channel_count *\n\t    1000 / conf->clock_rate;\n\n\t/* Calculate the size (in ptime) for the port buffer according to\n\t * this formula:\n\t *   - if either ptime is an exact multiple of the other, then use\n\t *     the larger ptime (e.g. 20ms and 40ms, use 40ms).\n\t *   - if not, then the ptime is sum of both ptimes (e.g. 20ms\n\t *     and 30ms, use 50ms)\n\t */\n\tif (port_ptime > conf_ptime) {\n\t    buff_ptime = port_ptime;\n\t    if (port_ptime % conf_ptime)\n\t\tbuff_ptime += conf_ptime;\n\t} else {\n\t    buff_ptime = conf_ptime;\n\t    if (conf_ptime % port_ptime)\n\t\tbuff_ptime += port_ptime;\n\t}\n\n\t/* Create RX buffer. */\n\t//conf_port->rx_buf_cap = (unsigned)(conf_port->samples_per_frame +\n\t//\t\t\t\t   conf->samples_per_frame * \n\t//\t\t\t\t   conf_port->clock_rate * 1.0 /\n\t//\t\t\t\t   conf->clock_rate + 0.5);\n\tconf_port->rx_buf_cap = conf_port->clock_rate * buff_ptime / 1000;\n\tif (conf_port->channel_count > conf->channel_count)\n\t    conf_port->rx_buf_cap *= conf_port->channel_count;\n\telse\n\t    conf_port->rx_buf_cap *= conf->channel_count;\n\n\tconf_port->rx_buf_count = 0;\n\tconf_port->rx_buf = (pj_int16_t*)\n\t\t\t    pj_pool_alloc(pool, conf_port->rx_buf_cap *\n\t\t\t\t\t\tsizeof(conf_port->rx_buf[0]));\n\tPJ_ASSERT_RETURN(conf_port->rx_buf, PJ_ENOMEM);\n\n\t/* Create TX buffer. */\n\tconf_port->tx_buf_cap = conf_port->rx_buf_cap;\n\tconf_port->tx_buf_count = 0;\n\tconf_port->tx_buf = (pj_int16_t*)\n\t\t\t    pj_pool_alloc(pool, conf_port->tx_buf_cap *\n\t\t\t\t\t\tsizeof(conf_port->tx_buf[0]));\n\tPJ_ASSERT_RETURN(conf_port->tx_buf, PJ_ENOMEM);\n    }\n\n\n    /* Create mix buffer. */\n    conf_port->mix_buf = (pj_int32_t*)\n\t\t\t pj_pool_zalloc(pool, conf->samples_per_frame *\n\t\t\t\t\t      sizeof(conf_port->mix_buf[0]));\n    PJ_ASSERT_RETURN(conf_port->mix_buf, PJ_ENOMEM);\n    conf_port->last_mix_adj = NORMAL_LEVEL;\n\n\n    /* Done */\n    *p_conf_port = conf_port;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Add passive port.\n */\nstatic pj_status_t create_pasv_port( pjmedia_conf *conf,\n\t\t\t\t     pj_pool_t *pool,\n\t\t\t\t     const pj_str_t *name,\n\t\t\t\t     pjmedia_port *port,\n\t\t\t\t     struct conf_port **p_conf_port)\n{\n    struct conf_port *conf_port;\n    pj_status_t status;\n    unsigned ptime;\n\n    /* Create port */\n    status = create_conf_port(pool, conf, port, name, &conf_port);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Passive port has delay buf. */\n    ptime = conf->samples_per_frame * 1000 / conf->clock_rate / \n\t    conf->channel_count;\n    status = pjmedia_delay_buf_create(pool, name->ptr, \n\t\t\t\t      conf->clock_rate,\n\t\t\t\t      conf->samples_per_frame,\n\t\t\t\t      conf->channel_count,\n\t\t\t\t      RX_BUF_COUNT * ptime, /* max delay */\n\t\t\t\t      0, /* options */\n\t\t\t\t      &conf_port->delay_buf);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    *p_conf_port = conf_port;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create port zero for the sound device.\n */\nstatic pj_status_t create_sound_port( pj_pool_t *pool,\n\t\t\t\t      pjmedia_conf *conf )\n{\n    struct conf_port *conf_port;\n    pj_str_t name = { \"Master/sound\", 12 };\n    pj_status_t status;\n\n\n    status = create_pasv_port(conf, pool, &name, NULL, &conf_port);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n\n    /* Create sound device port: */\n\n    if ((conf->options & PJMEDIA_CONF_NO_DEVICE) == 0) {\n\tpjmedia_aud_stream *strm;\n\tpjmedia_aud_param param;\n\n\t/*\n\t * If capture is disabled then create player only port.\n\t * Otherwise create bidirectional sound device port.\n\t */\n\tif (conf->options & PJMEDIA_CONF_NO_MIC)  {\n\t    status = pjmedia_snd_port_create_player(pool, -1, conf->clock_rate,\n\t\t\t\t\t\t    conf->channel_count,\n\t\t\t\t\t\t    conf->samples_per_frame,\n\t\t\t\t\t\t    conf->bits_per_sample, \n\t\t\t\t\t\t    0,\t/* options */\n\t\t\t\t\t\t    &conf->snd_dev_port);\n\n\t} else {\n\t    status = pjmedia_snd_port_create( pool, -1, -1, conf->clock_rate, \n\t\t\t\t\t      conf->channel_count, \n\t\t\t\t\t      conf->samples_per_frame,\n\t\t\t\t\t      conf->bits_per_sample,\n\t\t\t\t\t      0,    /* Options */\n\t\t\t\t\t      &conf->snd_dev_port);\n\n\t}\n\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tstrm = pjmedia_snd_port_get_snd_stream(conf->snd_dev_port);\n\tstatus = pjmedia_aud_stream_get_param(strm, &param);\n\tif (status == PJ_SUCCESS) {\n\t    pjmedia_aud_dev_info snd_dev_info;\n\t    if (conf->options & PJMEDIA_CONF_NO_MIC)\n\t\tpjmedia_aud_dev_get_info(param.play_id, &snd_dev_info);\n\t    else\n\t\tpjmedia_aud_dev_get_info(param.rec_id, &snd_dev_info);\n\t    pj_strdup2_with_null(pool, &conf_port->name, snd_dev_info.name);\n\t}\n\n\tPJ_LOG(5,(THIS_FILE, \"Sound device successfully created for port 0\"));\n    }\n\n\n     /* Add the port to the bridge */\n    conf->ports[0] = conf_port;\n    conf->port_cnt++;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Create conference bridge.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_create( pj_pool_t *pool,\n\t\t\t\t\t unsigned max_ports,\n\t\t\t\t\t unsigned clock_rate,\n\t\t\t\t\t unsigned channel_count,\n\t\t\t\t\t unsigned samples_per_frame,\n\t\t\t\t\t unsigned bits_per_sample,\n\t\t\t\t\t unsigned options,\n\t\t\t\t\t pjmedia_conf **p_conf )\n{\n    pjmedia_conf *conf;\n    const pj_str_t name = { \"Conf\", 4 };\n    pj_status_t status;\n\n    /* Can only accept 16bits per sample, for now.. */\n    PJ_ASSERT_RETURN(bits_per_sample == 16, PJ_EINVAL);\n\n    PJ_LOG(5,(THIS_FILE, \"Creating conference bridge with %d ports\",\n\t      max_ports));\n\n    /* Create and init conf structure. */\n    conf = PJ_POOL_ZALLOC_T(pool, pjmedia_conf);\n    PJ_ASSERT_RETURN(conf, PJ_ENOMEM);\n\n    conf->ports = (struct conf_port**) \n\t\t  pj_pool_zalloc(pool, max_ports*sizeof(void*));\n    PJ_ASSERT_RETURN(conf->ports, PJ_ENOMEM);\n\n    conf->options = options;\n    conf->max_ports = max_ports;\n    conf->clock_rate = clock_rate;\n    conf->channel_count = channel_count;\n    conf->samples_per_frame = samples_per_frame;\n    conf->bits_per_sample = bits_per_sample;\n\n    \n    /* Create and initialize the master port interface. */\n    conf->master_port = PJ_POOL_ZALLOC_T(pool, pjmedia_port);\n    PJ_ASSERT_RETURN(conf->master_port, PJ_ENOMEM);\n    \n    pjmedia_port_info_init(&conf->master_port->info, &name, SIGNATURE,\n\t\t\t   clock_rate, channel_count, bits_per_sample,\n\t\t\t   samples_per_frame);\n\n    conf->master_port->port_data.pdata = conf;\n    conf->master_port->port_data.ldata = 0;\n\n    conf->master_port->get_frame = &get_frame;\n    conf->master_port->put_frame = &put_frame;\n    conf->master_port->on_destroy = &destroy_port;\n\n\n    /* Create port zero for sound device. */\n    status = create_sound_port(pool, conf);\n    if (status != PJ_SUCCESS) {\n\tpjmedia_conf_destroy(conf);\n\treturn status;\n    }\n\n    /* Create mutex. */\n    status = pj_mutex_create_recursive(pool, \"conf\", &conf->mutex);\n    if (status != PJ_SUCCESS) {\n\tpjmedia_conf_destroy(conf);\n\treturn status;\n    }\n\n    /* If sound device was created, connect sound device to the\n     * master port.\n     */\n    if (conf->snd_dev_port) {\n\tstatus = pjmedia_snd_port_connect( conf->snd_dev_port, \n\t\t\t\t\t   conf->master_port );\n\tif (status != PJ_SUCCESS) {\n\t    pjmedia_conf_destroy(conf);\n\t    return status;\n\t}\n    }\n\n\n    /* Done */\n\n    *p_conf = conf;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Pause sound device.\n */\nstatic pj_status_t pause_sound( pjmedia_conf *conf )\n{\n    /* Do nothing. */\n    PJ_UNUSED_ARG(conf);\n    return PJ_SUCCESS;\n}\n\n/*\n * Resume sound device.\n */\nstatic pj_status_t resume_sound( pjmedia_conf *conf )\n{\n    /* Do nothing. */\n    PJ_UNUSED_ARG(conf);\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Destroy conference bridge.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_destroy( pjmedia_conf *conf )\n{\n    unsigned i, ci;\n\n    PJ_ASSERT_RETURN(conf != NULL, PJ_EINVAL);\n\n    /* Destroy sound device port. */\n    if (conf->snd_dev_port) {\n\tpjmedia_snd_port_destroy(conf->snd_dev_port);\n\tconf->snd_dev_port = NULL;\n    }\n\n    /* Destroy delay buf of all (passive) ports. */\n    for (i=0, ci=0; i<conf->max_ports && ci<conf->port_cnt; ++i) {\n\tstruct conf_port *cport;\n\n\tcport = conf->ports[i];\n\tif (!cport)\n\t    continue;\n\t\n\t++ci;\n\tif (cport->delay_buf) {\n\t    pjmedia_delay_buf_destroy(cport->delay_buf);\n\t    cport->delay_buf = NULL;\n\t}\n    }\n\n    /* Destroy mutex */\n    if (conf->mutex)\n\tpj_mutex_destroy(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy the master port (will destroy the conference)\n */\nstatic pj_status_t destroy_port(pjmedia_port *this_port)\n{\n    pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;\n    return pjmedia_conf_destroy(conf);\n}\n\nstatic pj_status_t destroy_port_pasv(pjmedia_port *this_port) {\n    pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;\n    struct conf_port *port = conf->ports[this_port->port_data.ldata];\n    pj_status_t status;\n\n    status = pjmedia_delay_buf_destroy(port->delay_buf);\n    if (status == PJ_SUCCESS)\n\tport->delay_buf = NULL;\n\n    return status;\n}\n\n/*\n * Get port zero interface.\n */\nPJ_DEF(pjmedia_port*) pjmedia_conf_get_master_port(pjmedia_conf *conf)\n{\n    /* Sanity check. */\n    PJ_ASSERT_RETURN(conf != NULL, NULL);\n\n    /* Can only return port interface when PJMEDIA_CONF_NO_DEVICE was\n     * present in the option.\n     */\n    PJ_ASSERT_RETURN((conf->options & PJMEDIA_CONF_NO_DEVICE) != 0, NULL);\n    \n    return conf->master_port;\n}\n\n\n/*\n * Set master port name.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_set_port0_name(pjmedia_conf *conf,\n\t\t\t\t\t\tconst pj_str_t *name)\n{\n    pj_size_t len;\n\n    /* Sanity check. */\n    PJ_ASSERT_RETURN(conf != NULL && name != NULL, PJ_EINVAL);\n\n    len = name->slen;\n    if (len > sizeof(conf->master_name_buf))\n\tlen = sizeof(conf->master_name_buf);\n    \n    if (len > 0) pj_memcpy(conf->master_name_buf, name->ptr, len);\n\n    conf->ports[0]->name.ptr = conf->master_name_buf;\n    conf->ports[0]->name.slen = len;\n\n    if (conf->master_port)\n\tconf->master_port->info.name = conf->ports[0]->name;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Add stream port to the conference bridge.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_add_port( pjmedia_conf *conf,\n\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t   pjmedia_port *strm_port,\n\t\t\t\t\t   const pj_str_t *port_name,\n\t\t\t\t\t   unsigned *p_port )\n{\n    struct conf_port *conf_port;\n    unsigned index;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(conf && pool && strm_port, PJ_EINVAL);\n\n    /* If port_name is not specified, use the port's name */\n    if (!port_name)\n\tport_name = &strm_port->info.name;\n\n    /* For this version of PJMEDIA, channel(s) number MUST be:\n     * - same between port & conference bridge.\n     * - monochannel on port or conference bridge.\n     */\n    if (PJMEDIA_PIA_CCNT(&strm_port->info) != conf->channel_count &&\n\t(PJMEDIA_PIA_CCNT(&strm_port->info) != 1 &&\n\t conf->channel_count != 1))\n    {\n\tpj_assert(!\"Number of channels mismatch\");\n\treturn PJMEDIA_ENCCHANNEL;\n    }\n\n    pj_mutex_lock(conf->mutex);\n\n    if (conf->port_cnt >= conf->max_ports) {\n\tpj_assert(!\"Too many ports\");\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_ETOOMANY;\n    }\n\n    /* Find empty port in the conference bridge. */\n    for (index=0; index < conf->max_ports; ++index) {\n\tif (conf->ports[index] == NULL)\n\t    break;\n    }\n\n    pj_assert(index != conf->max_ports);\n\n    /* Create conf port structure. */\n    status = create_conf_port(pool, conf, strm_port, port_name, &conf_port);\n    if (status != PJ_SUCCESS) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn status;\n    }\n\n    /* Put the port. */\n    conf->ports[index] = conf_port;\n    conf->port_cnt++;\n\n    /* Done. */\n    if (p_port) {\n\t*p_port = index;\n    }\n\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Add passive port.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_add_passive_port( pjmedia_conf *conf,\n\t\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t\t   const pj_str_t *name,\n\t\t\t\t\t\t   unsigned clock_rate,\n\t\t\t\t\t\t   unsigned channel_count,\n\t\t\t\t\t\t   unsigned samples_per_frame,\n\t\t\t\t\t\t   unsigned bits_per_sample,\n\t\t\t\t\t\t   unsigned options,\n\t\t\t\t\t\t   unsigned *p_slot,\n\t\t\t\t\t\t   pjmedia_port **p_port )\n{\n    struct conf_port *conf_port;\n    pjmedia_port *port;\n    unsigned index;\n    pj_str_t tmp;\n    pj_status_t status;\n\n    PJ_LOG(1, (THIS_FILE, \"This API has been deprecated since 1.3 and will \"\n\t\t\t  \"be removed in the future release!\"));\n\n    PJ_ASSERT_RETURN(conf && pool, PJ_EINVAL);\n\n    /* For this version of PJMEDIA, channel(s) number MUST be:\n     * - same between port & conference bridge.\n     * - monochannel on port or conference bridge.\n     */\n    if (channel_count != conf->channel_count && \n\t(channel_count != 1 && conf->channel_count != 1)) \n    {\n\tpj_assert(!\"Number of channels mismatch\");\n\treturn PJMEDIA_ENCCHANNEL;\n    }\n\n    /* For this version, options must be zero */\n    PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);\n    PJ_UNUSED_ARG(options);\n\n    pj_mutex_lock(conf->mutex);\n\n    if (conf->port_cnt >= conf->max_ports) {\n\tpj_assert(!\"Too many ports\");\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_ETOOMANY;\n    }\n\n    /* Find empty port in the conference bridge. */\n    for (index=0; index < conf->max_ports; ++index) {\n\tif (conf->ports[index] == NULL)\n\t    break;\n    }\n\n    pj_assert(index != conf->max_ports);\n\n    if (name == NULL) {\n\tname = &tmp;\n\n\ttmp.ptr = (char*) pj_pool_alloc(pool, 32);\n\ttmp.slen = pj_ansi_snprintf(tmp.ptr, 32, \"ConfPort#%d\", index);\n    }\n\n    /* Create and initialize the media port structure. */\n    port = PJ_POOL_ZALLOC_T(pool, pjmedia_port);\n    PJ_ASSERT_RETURN(port, PJ_ENOMEM);\n    \n    pjmedia_port_info_init(&port->info, name, SIGNATURE_PORT,\n\t\t\t   clock_rate, channel_count, bits_per_sample,\n\t\t\t   samples_per_frame);\n\n    port->port_data.pdata = conf;\n    port->port_data.ldata = index;\n\n    port->get_frame = &get_frame_pasv;\n    port->put_frame = &put_frame;\n    port->on_destroy = &destroy_port_pasv;\n\n    \n    /* Create conf port structure. */\n    status = create_pasv_port(conf, pool, name, port, &conf_port);\n    if (status != PJ_SUCCESS) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn status;\n    }\n\n\n    /* Put the port. */\n    conf->ports[index] = conf_port;\n    conf->port_cnt++;\n\n    /* Done. */\n    if (p_slot)\n\t*p_slot = index;\n    if (p_port)\n\t*p_port = port;\n\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Change TX and RX settings for the port.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_configure_port( pjmedia_conf *conf,\n\t\t\t\t\t\t  unsigned slot,\n\t\t\t\t\t\t  pjmedia_port_op tx,\n\t\t\t\t\t\t  pjmedia_port_op rx)\n{\n    struct conf_port *conf_port;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);\n\n    pj_mutex_lock(conf->mutex);\n\n    /* Port must be valid. */\n    conf_port = conf->ports[slot];\n    if (conf_port == NULL) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    conf_port = conf->ports[slot];\n\n    if (tx != PJMEDIA_PORT_NO_CHANGE)\n\tconf_port->tx_setting = tx;\n\n    if (rx != PJMEDIA_PORT_NO_CHANGE)\n\tconf_port->rx_setting = rx;\n\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Connect port.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_connect_port( pjmedia_conf *conf,\n\t\t\t\t\t       unsigned src_slot,\n\t\t\t\t\t       unsigned sink_slot,\n\t\t\t\t\t       int level )\n{\n    struct conf_port *src_port, *dst_port;\n    pj_bool_t start_sound = PJ_FALSE;\n    unsigned i;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && src_slot<conf->max_ports && \n\t\t     sink_slot<conf->max_ports, PJ_EINVAL);\n\n    /* For now, level MUST be zero. */\n    PJ_ASSERT_RETURN(level == 0, PJ_EINVAL);\n\n    pj_mutex_lock(conf->mutex);\n\n    /* Ports must be valid. */\n    src_port = conf->ports[src_slot];\n    dst_port = conf->ports[sink_slot];\n    if (!src_port || !dst_port) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    /* Check if connection has been made */\n    for (i=0; i<src_port->listener_cnt; ++i) {\n\tif (src_port->listener_slots[i] == sink_slot)\n\t    break;\n    }\n\n    if (i == src_port->listener_cnt) {\n\tsrc_port->listener_slots[src_port->listener_cnt] = sink_slot;\n\t++conf->connect_cnt;\n\t++src_port->listener_cnt;\n\t++dst_port->transmitter_cnt;\n\n\tif (conf->connect_cnt == 1)\n\t    start_sound = 1;\n\n\tPJ_LOG(4,(THIS_FILE,\"Port %d (%.*s) transmitting to port %d (%.*s)\",\n\t\t  src_slot,\n\t\t  (int)src_port->name.slen,\n\t\t  src_port->name.ptr,\n\t\t  sink_slot,\n\t\t  (int)dst_port->name.slen,\n\t\t  dst_port->name.ptr));\n    }\n\n    pj_mutex_unlock(conf->mutex);\n\n    /* Sound device must be started without mutex, otherwise the\n     * sound thread will deadlock (?)\n     */\n    if (start_sound)\n\tresume_sound(conf);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Disconnect port\n */\nPJ_DEF(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf,\n\t\t\t\t\t\t  unsigned src_slot,\n\t\t\t\t\t\t  unsigned sink_slot )\n{\n    struct conf_port *src_port, *dst_port;\n    unsigned i;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && src_slot<conf->max_ports && \n\t\t     sink_slot<conf->max_ports, PJ_EINVAL);\n\n    pj_mutex_lock(conf->mutex);\n\n    /* Ports must be valid. */\n    src_port = conf->ports[src_slot];\n    dst_port = conf->ports[sink_slot];\n    if (!src_port || !dst_port) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    /* Check if connection has been made */\n    for (i=0; i<src_port->listener_cnt; ++i) {\n\tif (src_port->listener_slots[i] == sink_slot)\n\t    break;\n    }\n\n    if (i != src_port->listener_cnt) {\n\tpj_assert(src_port->listener_cnt > 0 && \n\t\t  src_port->listener_cnt < conf->max_ports);\n\tpj_assert(dst_port->transmitter_cnt > 0 && \n\t\t  dst_port->transmitter_cnt < conf->max_ports);\n\tpj_array_erase(src_port->listener_slots, sizeof(SLOT_TYPE), \n\t\t       src_port->listener_cnt, i);\n\t--conf->connect_cnt;\n\t--src_port->listener_cnt;\n\t--dst_port->transmitter_cnt;\n\n\tPJ_LOG(4,(THIS_FILE,\n\t\t  \"Port %d (%.*s) stop transmitting to port %d (%.*s)\",\n\t\t  src_slot,\n\t\t  (int)src_port->name.slen,\n\t\t  src_port->name.ptr,\n\t\t  sink_slot,\n\t\t  (int)dst_port->name.slen,\n\t\t  dst_port->name.ptr));\n\n\t/* if source port is passive port and has no listener, reset delaybuf */\n\tif (src_port->delay_buf && src_port->listener_cnt == 0)\n\t    pjmedia_delay_buf_reset(src_port->delay_buf);\n    }\n\n    pj_mutex_unlock(conf->mutex);\n\n    if (conf->connect_cnt == 0) {\n\tpause_sound(conf);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get number of ports currently registered to the conference bridge.\n */\nPJ_DEF(unsigned) pjmedia_conf_get_port_count(pjmedia_conf *conf)\n{\n    return conf->port_cnt;\n}\n\n/*\n * Get total number of ports connections currently set up in the bridge.\n */\nPJ_DEF(unsigned) pjmedia_conf_get_connect_count(pjmedia_conf *conf)\n{\n    return conf->connect_cnt;\n}\n\n\n/*\n * Remove the specified port.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf,\n\t\t\t\t\t      unsigned port )\n{\n    struct conf_port *conf_port;\n    unsigned i;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && port < conf->max_ports, PJ_EINVAL);\n\n    /* Suspend the sound devices.\n     * Don't want to remove port while port is being accessed by sound\n     * device's threads!\n     */\n\n    pj_mutex_lock(conf->mutex);\n\n    /* Port must be valid. */\n    conf_port = conf->ports[port];\n    if (conf_port == NULL) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    conf_port->tx_setting = PJMEDIA_PORT_DISABLE;\n    conf_port->rx_setting = PJMEDIA_PORT_DISABLE;\n\n    /* Remove this port from transmit array of other ports. */\n    for (i=0; i<conf->max_ports; ++i) {\n\tunsigned j;\n\tstruct conf_port *src_port;\n\n\tsrc_port = conf->ports[i];\n\n\tif (!src_port)\n\t    continue;\n\n\tif (src_port->listener_cnt == 0)\n\t    continue;\n\n\tfor (j=0; j<src_port->listener_cnt; ++j) {\n\t    if (src_port->listener_slots[j] == port) {\n\t\tpj_array_erase(src_port->listener_slots, sizeof(SLOT_TYPE),\n\t\t\t       src_port->listener_cnt, j);\n\t\tpj_assert(conf->connect_cnt > 0);\n\t\t--conf->connect_cnt;\n\t\t--src_port->listener_cnt;\n\t\tbreak;\n\t    }\n\t}\n    }\n\n    /* Update transmitter_cnt of ports we're transmitting to */\n    while (conf_port->listener_cnt) {\n\tunsigned dst_slot;\n\tstruct conf_port *dst_port;\n\n\tdst_slot = conf_port->listener_slots[conf_port->listener_cnt-1];\n\tdst_port = conf->ports[dst_slot];\n\t--dst_port->transmitter_cnt;\n\t--conf_port->listener_cnt;\n\tpj_assert(conf->connect_cnt > 0);\n\t--conf->connect_cnt;\n    }\n\n    /* Destroy pjmedia port if this conf port is passive port,\n     * i.e: has delay buf.\n     */\n    if (conf_port->delay_buf) {\n\tpjmedia_port_destroy(conf_port->port);\n\tconf_port->port = NULL;\n    }\n\n    /* Remove the port. */\n    conf->ports[port] = NULL;\n    --conf->port_cnt;\n\n    pj_mutex_unlock(conf->mutex);\n\n\n    /* Stop sound if there's no connection. */\n    if (conf->connect_cnt == 0) {\n\tpause_sound(conf);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Enum ports.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_enum_ports( pjmedia_conf *conf,\n\t\t\t\t\t     unsigned ports[],\n\t\t\t\t\t     unsigned *p_count )\n{\n    unsigned i, count=0;\n\n    PJ_ASSERT_RETURN(conf && p_count && ports, PJ_EINVAL);\n\n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    for (i=0; i<conf->max_ports && count<*p_count; ++i) {\n\tif (!conf->ports[i])\n\t    continue;\n\n\tports[count++] = i;\n    }\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    *p_count = count;\n    return PJ_SUCCESS;\n}\n\n/*\n * Get port info\n */\nPJ_DEF(pj_status_t) pjmedia_conf_get_port_info( pjmedia_conf *conf,\n\t\t\t\t\t\tunsigned slot,\n\t\t\t\t\t\tpjmedia_conf_port_info *info)\n{\n    struct conf_port *conf_port;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);\n\n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    /* Port must be valid. */\n    conf_port = conf->ports[slot];\n    if (conf_port == NULL) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    info->slot = slot;\n    info->name = conf_port->name;\n    info->tx_setting = conf_port->tx_setting;\n    info->rx_setting = conf_port->rx_setting;\n    info->listener_cnt = conf_port->listener_cnt;\n    info->listener_slots = conf_port->listener_slots;\n    info->transmitter_cnt = conf_port->transmitter_cnt;\n    info->clock_rate = conf_port->clock_rate;\n    info->channel_count = conf_port->channel_count;\n    info->samples_per_frame = conf_port->samples_per_frame;\n    info->bits_per_sample = conf->bits_per_sample;\n    info->tx_adj_level = conf_port->tx_adj_level - NORMAL_LEVEL;\n    info->rx_adj_level = conf_port->rx_adj_level - NORMAL_LEVEL;\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_conf_get_ports_info(pjmedia_conf *conf,\n\t\t\t\t\t\tunsigned *size,\n\t\t\t\t\t\tpjmedia_conf_port_info info[])\n{\n    unsigned i, count=0;\n\n    PJ_ASSERT_RETURN(conf && size && info, PJ_EINVAL);\n\n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    for (i=0; i<conf->max_ports && count<*size; ++i) {\n\tif (!conf->ports[i])\n\t    continue;\n\n\tpjmedia_conf_get_port_info(conf, i, &info[count]);\n\t++count;\n    }\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    *size = count;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get signal level.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_get_signal_level( pjmedia_conf *conf,\n\t\t\t\t\t\t   unsigned slot,\n\t\t\t\t\t\t   unsigned *tx_level,\n\t\t\t\t\t\t   unsigned *rx_level)\n{\n    struct conf_port *conf_port;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);\n\n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    /* Port must be valid. */\n    conf_port = conf->ports[slot];\n    if (conf_port == NULL) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    if (tx_level != NULL) {\n\t*tx_level = conf_port->tx_level;\n    }\n\n    if (rx_level != NULL) \n\t*rx_level = conf_port->rx_level;\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Adjust RX level of individual port.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_adjust_rx_level( pjmedia_conf *conf,\n\t\t\t\t\t\t  unsigned slot,\n\t\t\t\t\t\t  int adj_level )\n{\n    struct conf_port *conf_port;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);\n\n    /* Value must be from -128 to +127 */\n    /* Disabled, you can put more than +127, at your own risk: \n     PJ_ASSERT_RETURN(adj_level >= -128 && adj_level <= 127, PJ_EINVAL);\n     */\n    PJ_ASSERT_RETURN(adj_level >= -128, PJ_EINVAL);\n\n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    /* Port must be valid. */\n    conf_port = conf->ports[slot];\n    if (conf_port == NULL) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    /* Set normalized adjustment level. */\n    conf_port->rx_adj_level = adj_level + NORMAL_LEVEL;\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Adjust TX level of individual port.\n */\nPJ_DEF(pj_status_t) pjmedia_conf_adjust_tx_level( pjmedia_conf *conf,\n\t\t\t\t\t\t  unsigned slot,\n\t\t\t\t\t\t  int adj_level )\n{\n    struct conf_port *conf_port;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);\n\n    /* Value must be from -128 to +127 */\n    /* Disabled, you can put more than +127,, at your own risk:\n     PJ_ASSERT_RETURN(adj_level >= -128 && adj_level <= 127, PJ_EINVAL);\n     */\n    PJ_ASSERT_RETURN(adj_level >= -128, PJ_EINVAL);\n\n    /* Lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    /* Port must be valid. */\n    conf_port = conf->ports[slot];\n    if (conf_port == NULL) {\n\tpj_mutex_unlock(conf->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    /* Set normalized adjustment level. */\n    conf_port->tx_adj_level = adj_level + NORMAL_LEVEL;\n\n    /* Unlock mutex */\n    pj_mutex_unlock(conf->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Read from port.\n */\nstatic pj_status_t read_port( pjmedia_conf *conf,\n\t\t\t      struct conf_port *cport, pj_int16_t *frame,\n\t\t\t      pj_size_t count, pjmedia_frame_type *type )\n{\n\n    pj_assert(count == conf->samples_per_frame);\n\n    TRACE_((THIS_FILE, \"read_port %.*s: count=%d\", \n\t\t       (int)cport->name.slen, cport->name.ptr,\n\t\t       count));\n\n    /* \n     * If port's samples per frame and sampling rate and channel count\n     * matche conference bridge's settings, get the frame directly from\n     * the port.\n     */\n    if (cport->rx_buf_cap == 0) {\n\tpjmedia_frame f;\n\tpj_status_t status;\n\n\tf.buf = frame;\n\tf.size = count * BYTES_PER_SAMPLE;\n\n\tTRACE_((THIS_FILE, \"  get_frame %.*s: count=%d\", \n\t\t   (int)cport->name.slen, cport->name.ptr,\n\t\t   count));\n\n\tstatus = pjmedia_port_get_frame(cport->port, &f);\n\n\t*type = f.type;\n\n\treturn status;\n\n    } else {\n\tunsigned samples_req;\n\n\t/* Initialize frame type */\n\tif (cport->rx_buf_count == 0) {\n\t    *type = PJMEDIA_FRAME_TYPE_NONE;\n\t} else {\n\t    /* we got some samples in the buffer */\n\t    *type = PJMEDIA_FRAME_TYPE_AUDIO;\n\t}\n\n\t/*\n\t * If we don't have enough samples in rx_buf, read from the port \n\t * first. Remember that rx_buf may be in different clock rate and\n\t * channel count!\n\t */\n\n\tsamples_req = (unsigned) (count * 1.0 * \n\t\t      cport->clock_rate / conf->clock_rate + 0.5);\n\n\twhile (cport->rx_buf_count < samples_req) {\n\n\t    pjmedia_frame f;\n\t    pj_status_t status;\n\n\t    f.buf = cport->rx_buf + cport->rx_buf_count;\n\t    f.size = cport->samples_per_frame * BYTES_PER_SAMPLE;\n\n\t    TRACE_((THIS_FILE, \"  get_frame, count=%d\", \n\t\t       cport->samples_per_frame));\n\n\t    status = pjmedia_port_get_frame(cport->port, &f);\n\n\t    if (status != PJ_SUCCESS) {\n\t\t/* Fatal error! */\n\t\treturn status;\n\t    }\n\n\t    if (f.type != PJMEDIA_FRAME_TYPE_AUDIO) {\n\t\tTRACE_((THIS_FILE, \"  get_frame returned non-audio\"));\n\t\tpjmedia_zero_samples( cport->rx_buf + cport->rx_buf_count,\n\t\t\t\t      cport->samples_per_frame);\n\t    } else {\n\t\t/* We've got at least one frame */\n\t\t*type = PJMEDIA_FRAME_TYPE_AUDIO;\n\t    }\n\n\t    /* Adjust channels */\n\t    if (cport->channel_count != conf->channel_count) {\n\t\tif (cport->channel_count == 1) {\n\t\t    pjmedia_convert_channel_1ton((pj_int16_t*)f.buf, \n\t\t\t\t\t\t (const pj_int16_t*)f.buf,\n\t\t\t\t\t\t conf->channel_count, \n\t\t\t\t\t\t cport->samples_per_frame,\n\t\t\t\t\t\t 0);\n\t\t    cport->rx_buf_count += (cport->samples_per_frame * \n\t\t\t\t\t    conf->channel_count);\n\t\t} else { /* conf->channel_count == 1 */\n\t\t    pjmedia_convert_channel_nto1((pj_int16_t*)f.buf, \n\t\t\t\t\t\t (const pj_int16_t*)f.buf,\n\t\t\t\t\t\t cport->channel_count, \n\t\t\t\t\t\t cport->samples_per_frame, \n\t\t\t\t\t\t PJMEDIA_STEREO_MIX, 0);\n\t\t    cport->rx_buf_count += (cport->samples_per_frame / \n\t\t\t\t\t    cport->channel_count);\n\t\t}\n\t    } else {\n\t\tcport->rx_buf_count += cport->samples_per_frame;\n\t    }\n\n\t    TRACE_((THIS_FILE, \"  rx buffer size is now %d\",\n\t\t    cport->rx_buf_count));\n\n\t    pj_assert(cport->rx_buf_count <= cport->rx_buf_cap);\n\t}\n\n\t/*\n\t * If port's clock_rate is different, resample.\n\t * Otherwise just copy.\n\t */\n\tif (cport->clock_rate != conf->clock_rate) {\n\t    \n\t    unsigned src_count;\n\n\t    TRACE_((THIS_FILE, \"  resample, input count=%d\", \n\t\t    pjmedia_resample_get_input_size(cport->rx_resample)));\n\n\t    pjmedia_resample_run( cport->rx_resample,cport->rx_buf, frame);\n\n\t    src_count = (unsigned)(count * 1.0 * cport->clock_rate / \n\t\t\t\t   conf->clock_rate + 0.5);\n\t    cport->rx_buf_count -= src_count;\n\t    if (cport->rx_buf_count) {\n\t\tpjmedia_move_samples(cport->rx_buf, cport->rx_buf+src_count,\n\t\t\t\t     cport->rx_buf_count);\n\t    }\n\n\t    TRACE_((THIS_FILE, \"  rx buffer size is now %d\",\n\t\t    cport->rx_buf_count));\n\n\t} else {\n\n\t    pjmedia_copy_samples(frame, cport->rx_buf, (unsigned)count);\n\t    cport->rx_buf_count -= (unsigned)count;\n\t    if (cport->rx_buf_count) {\n\t\tpjmedia_move_samples(cport->rx_buf, cport->rx_buf+count,\n\t\t\t\t     cport->rx_buf_count);\n\t    }\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Write the mixed signal to the port.\n */\nstatic pj_status_t write_port(pjmedia_conf *conf, struct conf_port *cport,\n\t\t\t      const pj_timestamp *timestamp, \n\t\t\t      pjmedia_frame_type *frm_type)\n{\n    pj_int16_t *buf;\n    unsigned j, ts;\n    pj_status_t status;\n    pj_int32_t adj_level;\n    pj_int32_t tx_level;\n    unsigned dst_count;\n\n    *frm_type = PJMEDIA_FRAME_TYPE_AUDIO;\n\n    /* If port is muted or nobody is transmitting to this port, \n     * transmit NULL frame. \n     */\n    if (cport->tx_setting == PJMEDIA_PORT_MUTE || cport->transmitter_cnt==0) {\n\n\tpjmedia_frame frame;\n\n\t/* Clear left-over samples in tx_buffer, if any, so that it won't\n\t * be transmitted next time we have audio signal.\n\t */\n\tcport->tx_buf_count = 0;\n\n\t/* Add sample counts to heart-beat samples */\n\tcport->tx_heart_beat += conf->samples_per_frame * cport->clock_rate /\n\t\t\t\tconf->clock_rate * \n\t\t\t\tcport->channel_count / conf->channel_count;\n\n\t/* Set frame timestamp */\n\tframe.timestamp.u64 = timestamp->u64 * cport->clock_rate /\n\t\t\t\tconf->clock_rate;\n\tframe.type = PJMEDIA_FRAME_TYPE_NONE;\n\tframe.buf = NULL;\n\tframe.size = 0;\n\n\t/* Transmit heart-beat frames (may transmit more than one NULL frame\n\t * if port's ptime is less than bridge's ptime.\n\t */\n\tif (cport->port && cport->port->put_frame) {\n\t    while (cport->tx_heart_beat >= cport->samples_per_frame) {\n\n\t\tpjmedia_port_put_frame(cport->port, &frame);\n\n\t\tcport->tx_heart_beat -= cport->samples_per_frame;\n\t\tframe.timestamp.u64 += cport->samples_per_frame;\n\t    }\n\t}\n\n\tcport->tx_level = 0;\n\t*frm_type = PJMEDIA_FRAME_TYPE_NONE;\n\treturn PJ_SUCCESS;\n\n    } else if (cport->tx_setting != PJMEDIA_PORT_ENABLE) {\n\tcport->tx_level = 0;\n\t*frm_type = PJMEDIA_FRAME_TYPE_NONE;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Reset heart-beat sample count */\n    cport->tx_heart_beat = 0;\n\n    buf = (pj_int16_t*) cport->mix_buf;\n\n    /* If there are sources in the mix buffer, convert the mixed samples\n     * from 32bit to 16bit in the mixed samples itself. This is possible \n     * because mixed sample is 32bit.\n     *\n     * In addition to this process, if we need to change the level of\n     * TX signal, we adjust is here too.\n     */\n\n    /* Calculate signal level and adjust the signal when needed. \n     * Two adjustments performed at once: \n     * 1. user setting adjustment (tx_adj_level). \n     * 2. automatic adjustment of overflowed mixed buffer (mix_adj).\n     */\n\n    /* Apply simple AGC to the mix_adj, the automatic adjust, to avoid \n     * dramatic change in the level thus causing noise because the signal \n     * is now not aligned with the signal from the previous frame.\n     */\n    SIMPLE_AGC(cport->last_mix_adj, cport->mix_adj);\n    cport->last_mix_adj = cport->mix_adj;\n\n    /* adj_level = cport->tx_adj_level * cport->mix_adj / NORMAL_LEVEL;*/\n    adj_level = cport->tx_adj_level * cport->mix_adj;\n    adj_level >>= 7;\n\n    tx_level = 0;\n\n    if (adj_level != NORMAL_LEVEL) {\n\tfor (j=0; j<conf->samples_per_frame; ++j) {\n\t    pj_int32_t itemp = cport->mix_buf[j];\n\n\t    /* Adjust the level */\n\t    /*itemp = itemp * adj_level / NORMAL_LEVEL;*/\n\t    itemp = (itemp * adj_level) >> 7;\n\n\t    /* Clip the signal if it's too loud */\n\t    if (itemp > MAX_LEVEL) itemp = MAX_LEVEL;\n\t    else if (itemp < MIN_LEVEL) itemp = MIN_LEVEL;\n\n\t    /* Put back in the buffer. */\n\t    buf[j] = (pj_int16_t) itemp;\n\n\t    tx_level += (buf[j]>=0? buf[j] : -buf[j]);\n\t}\n    } else {\n\tfor (j=0; j<conf->samples_per_frame; ++j) {\n\t    buf[j] = (pj_int16_t) cport->mix_buf[j];\n\t    tx_level += (buf[j]>=0? buf[j] : -buf[j]);\n\t}\n    }\n\n    tx_level /= conf->samples_per_frame;\n\n    /* Convert level to 8bit complement ulaw */\n    tx_level = pjmedia_linear2ulaw(tx_level) ^ 0xff;\n\n    cport->tx_level = tx_level;\n\n    /* If port has the same clock_rate and samples_per_frame and \n     * number of channels as the conference bridge, transmit the \n     * frame as is.\n     */\n    if (cport->clock_rate == conf->clock_rate &&\n\tcport->samples_per_frame == conf->samples_per_frame &&\n\tcport->channel_count == conf->channel_count)\n    {\n\tif (cport->port != NULL) {\n\t    pjmedia_frame frame;\n\n\t    frame.type = PJMEDIA_FRAME_TYPE_AUDIO;\n\t    frame.buf = buf;\n\t    frame.size = conf->samples_per_frame * BYTES_PER_SAMPLE;\n\t    /* No need to adjust timestamp, port has the same\n\t     * clock rate as conference bridge \n\t     */\n\t    frame.timestamp = *timestamp;\n\n\t    TRACE_((THIS_FILE, \"put_frame %.*s, count=%d\", \n\t\t\t       (int)cport->name.slen, cport->name.ptr,\n\t\t\t       frame.size / BYTES_PER_SAMPLE));\n\n\t    return pjmedia_port_put_frame(cport->port, &frame);\n\t} else\n\t    return PJ_SUCCESS;\n    }\n\n    /* If it has different clock_rate, must resample. */\n    if (cport->clock_rate != conf->clock_rate) {\n\tpjmedia_resample_run( cport->tx_resample, buf, \n\t\t\t      cport->tx_buf + cport->tx_buf_count );\n\tdst_count = (unsigned)(conf->samples_per_frame * 1.0 *\n\t\t\t       cport->clock_rate / conf->clock_rate + 0.5);\n    } else {\n\t/* Same clock rate.\n\t * Just copy the samples to tx_buffer.\n\t */\n\tpjmedia_copy_samples( cport->tx_buf + cport->tx_buf_count,\n\t\t\t      buf, conf->samples_per_frame );\n\tdst_count = conf->samples_per_frame;\n    }\n\n    /* Adjust channels */\n    if (cport->channel_count != conf->channel_count) {\n\tpj_int16_t *tx_buf = cport->tx_buf + cport->tx_buf_count;\n\tif (conf->channel_count == 1) {\n\t    pjmedia_convert_channel_1ton(tx_buf, tx_buf,\n\t\t\t\t\t cport->channel_count, \n\t\t\t\t\t dst_count, 0);\n\t    dst_count *= cport->channel_count;\n\t} else { /* cport->channel_count == 1 */\n\t    pjmedia_convert_channel_nto1(tx_buf, tx_buf,\n\t\t\t\t\t conf->channel_count, \n\t\t\t\t\t dst_count, PJMEDIA_STEREO_MIX, 0);\n\t    dst_count /= conf->channel_count;\n\t}\n    }\n\n    cport->tx_buf_count += dst_count;\n\n    pj_assert(cport->tx_buf_count <= cport->tx_buf_cap);\n\n    /* Transmit while we have enough frame in the tx_buf. */\n    status = PJ_SUCCESS;\n    ts = 0;\n    while (cport->tx_buf_count >= cport->samples_per_frame &&\n\t   status == PJ_SUCCESS) \n    {\n\t\n\tTRACE_((THIS_FILE, \"write_port %.*s: count=%d\", \n\t\t\t   (int)cport->name.slen, cport->name.ptr,\n\t\t\t   cport->samples_per_frame));\n\n\tif (cport->port) {\n\t    pjmedia_frame frame;\n\n\t    frame.type = PJMEDIA_FRAME_TYPE_AUDIO;\n\t    frame.buf = cport->tx_buf;\n\t    frame.size = cport->samples_per_frame * BYTES_PER_SAMPLE;\n\t    /* Adjust timestamp as port may have different clock rate\n\t     * than the bridge.\n\t     */\n\t    frame.timestamp.u64 = timestamp->u64 * cport->clock_rate /\n\t\t\t\t  conf->clock_rate;\n\n\t    /* Add timestamp for individual frame */\n\t    frame.timestamp.u64 += ts;\n\t    ts += cport->samples_per_frame;\n\n\t    TRACE_((THIS_FILE, \"put_frame %.*s, count=%d\", \n\t\t\t       (int)cport->name.slen, cport->name.ptr,\n\t\t\t       frame.size / BYTES_PER_SAMPLE));\n\n\t    status = pjmedia_port_put_frame(cport->port, &frame);\n\n\t} else\n\t    status = PJ_SUCCESS;\n\n\tcport->tx_buf_count -= cport->samples_per_frame;\n\tif (cport->tx_buf_count) {\n\t    pjmedia_move_samples(cport->tx_buf, \n\t\t\t\t cport->tx_buf + cport->samples_per_frame,\n\t\t\t\t cport->tx_buf_count);\n\t}\n\n\tTRACE_((THIS_FILE, \" tx_buf count now is %d\", \n\t\t\t   cport->tx_buf_count));\n    }\n\n    return status;\n}\n\n\n/*\n * Player callback.\n */\nstatic pj_status_t get_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame)\n{\n    pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;\n    pjmedia_frame_type speaker_frame_type = PJMEDIA_FRAME_TYPE_NONE;\n    unsigned ci, cj, i, j;\n    pj_int16_t *p_in;\n    \n    TRACE_((THIS_FILE, \"- clock -\"));\n\n    /* Check that correct size is specified. */\n    pj_assert(frame->size == conf->samples_per_frame *\n\t\t\t     conf->bits_per_sample / 8);\n\n    /* Must lock mutex */\n    pj_mutex_lock(conf->mutex);\n\n    /* Reset port source count. We will only reset port's mix\n     * buffer when we have someone transmitting to it.\n     */\n    for (i=0, ci=0; i<conf->max_ports && ci < conf->port_cnt; ++i) {\n\tstruct conf_port *conf_port = conf->ports[i];\n\n\t/* Skip empty port. */\n\tif (!conf_port)\n\t    continue;\n\n\t/* Var \"ci\" is to count how many ports have been visited so far. */\n\t++ci;\n\n\t/* Reset buffer (only necessary if the port has transmitter) and\n\t * reset auto adjustment level for mixed signal.\n\t */\n\tconf_port->mix_adj = NORMAL_LEVEL;\n\tif (conf_port->transmitter_cnt) {\n\t    pj_bzero(conf_port->mix_buf,\n\t\t     conf->samples_per_frame*sizeof(conf_port->mix_buf[0]));\n\t}\n    }\n\n    /* Get frames from all ports, and \"mix\" the signal \n     * to mix_buf of all listeners of the port.\n     */\n    for (i=0, ci=0; i < conf->max_ports && ci < conf->port_cnt; ++i) {\n\tstruct conf_port *conf_port = conf->ports[i];\n\tpj_int32_t level = 0;\n\n\t/* Skip empty port. */\n\tif (!conf_port)\n\t    continue;\n\n\t/* Var \"ci\" is to count how many ports have been visited so far. */\n\t++ci;\n\n\t/* Skip if we're not allowed to receive from this port. */\n\tif (conf_port->rx_setting == PJMEDIA_PORT_DISABLE) {\n\t    conf_port->rx_level = 0;\n\t    continue;\n\t}\n\n\t/* Also skip if this port doesn't have listeners. */\n\tif (conf_port->listener_cnt == 0) {\n\t    conf_port->rx_level = 0;\n\t    continue;\n\t}\n\n\t/* Get frame from this port.\n\t * For passive ports, get the frame from the delay_buf.\n\t * For other ports, get the frame from the port. \n\t */\n\tif (conf_port->delay_buf != NULL) {\n\t    pj_status_t status;\n\t\n\t    status = pjmedia_delay_buf_get(conf_port->delay_buf,\n\t\t\t\t  (pj_int16_t*)frame->buf);\n\t    if (status != PJ_SUCCESS)\n\t\tcontinue;\n\n\t} else {\n\n\t    pj_status_t status;\n\t    pjmedia_frame_type frame_type;\n\n\t    status = read_port(conf, conf_port, (pj_int16_t*)frame->buf, \n\t\t\t       conf->samples_per_frame, &frame_type);\n\t    \n\t    if (status != PJ_SUCCESS) {\n\t\t/* bennylp: why do we need this????\n\t\t * Also see comments on similar issue with write_port().\n\t\tPJ_LOG(4,(THIS_FILE, \"Port %.*s get_frame() returned %d. \"\n\t\t\t\t     \"Port is now disabled\",\n\t\t\t\t     (int)conf_port->name.slen,\n\t\t\t\t     conf_port->name.ptr,\n\t\t\t\t     status));\n\t\tconf_port->rx_setting = PJMEDIA_PORT_DISABLE;\n\t\t */\n\t\tcontinue;\n\t    }\n\n\t    /* Check that the port is not removed when we call get_frame() */\n\t    if (conf->ports[i] == NULL)\n\t\tcontinue;\n\n\t    /* Ignore if we didn't get any frame */\n\t    if (frame_type != PJMEDIA_FRAME_TYPE_AUDIO)\n\t\tcontinue;\n\t}\n\n\tp_in = (pj_int16_t*) frame->buf;\n\n\t/* Adjust the RX level from this port\n\t * and calculate the average level at the same time.\n\t */\n\tif (conf_port->rx_adj_level != NORMAL_LEVEL) {\n\t    for (j=0; j<conf->samples_per_frame; ++j) {\n\t\t/* For the level adjustment, we need to store the sample to\n\t\t * a temporary 32bit integer value to avoid overflowing the\n\t\t * 16bit sample storage.\n\t\t */\n\t\tpj_int32_t itemp;\n\n\t\titemp = p_in[j];\n\t\t/*itemp = itemp * adj / NORMAL_LEVEL;*/\n\t\t/* bad code (signed/unsigned badness):\n\t\t *  itemp = (itemp * conf_port->rx_adj_level) >> 7;\n\t\t */\n\t\titemp *= conf_port->rx_adj_level;\n\t\titemp >>= 7;\n\n\t\t/* Clip the signal if it's too loud */\n\t\tif (itemp > MAX_LEVEL) itemp = MAX_LEVEL;\n\t\telse if (itemp < MIN_LEVEL) itemp = MIN_LEVEL;\n\n\t\tp_in[j] = (pj_int16_t) itemp;\n\t\tlevel += (p_in[j]>=0? p_in[j] : -p_in[j]);\n\t    }\n\t} else {\n\t    for (j=0; j<conf->samples_per_frame; ++j) {\n\t\tlevel += (p_in[j]>=0? p_in[j] : -p_in[j]);\n\t    }\n\t}\n\n\tlevel /= conf->samples_per_frame;\n\n\t/* Convert level to 8bit complement ulaw */\n\tlevel = pjmedia_linear2ulaw(level) ^ 0xff;\n\n\t/* Put this level to port's last RX level. */\n\tconf_port->rx_level = level;\n\n\t// Ticket #671: Skipping very low audio signal may cause noise \n\t// to be generated in the remote end by some hardphones.\n\t/* Skip processing frame if level is zero */\n\t//if (level == 0)\n\t//    continue;\n\n\t/* Add the signal to all listeners. */\n\tfor (cj=0; cj < conf_port->listener_cnt; ++cj) \n\t{\n\t    struct conf_port *listener;\n\t    pj_int32_t *mix_buf;\n\t    unsigned k;\n\n\t    listener = conf->ports[conf_port->listener_slots[cj]];\n\n\t    /* Skip if this listener doesn't want to receive audio */\n\t    if (listener->tx_setting != PJMEDIA_PORT_ENABLE)\n\t\tcontinue;\n\n\t    mix_buf = listener->mix_buf;\n\n\t    if (listener->transmitter_cnt > 1) {\n\t\t/* Mixing signals,\n\t\t * and calculate appropriate level adjustment if there is\n\t\t * any overflowed level in the mixed signal.\n\t\t */\n\t\tfor (k=0; k < conf->samples_per_frame; ++k) {\n\t\t    mix_buf[k] += p_in[k];\n\t\t    /* Check if normalization adjustment needed. */\n\t\t    if (IS_OVERFLOW(mix_buf[k])) {\n\t\t\t/* NORMAL_LEVEL * MAX_LEVEL / mix_buf[k]; */\n\t\t\tint tmp_adj = (MAX_LEVEL<<7) / mix_buf[k];\n\t\t\tif (tmp_adj<0) tmp_adj = -tmp_adj;\n\n\t\t\tif (tmp_adj<listener->mix_adj)\n\t\t\t    listener->mix_adj = tmp_adj;\n\n\t\t    } /* if any overflow in the mixed signals */\n\t\t} /* loop mixing signals */\n\t    } else {\n\t\t/* Only 1 transmitter:\n\t\t * just copy the samples to the mix buffer\n\t\t * no mixing and level adjustment needed\n\t\t */\n\t\tfor (k=0; k<conf->samples_per_frame; ++k) {\n\t\t    mix_buf[k] = p_in[k];\n\t\t}\n\t    }\n\t} /* loop the listeners of conf port */\n    } /* loop of all conf ports */\n\n    /* Time for all ports to transmit whetever they have in their\n     * buffer. \n     */\n    for (i=0, ci=0; i<conf->max_ports && ci<conf->port_cnt; ++i) {\n\tstruct conf_port *conf_port = conf->ports[i];\n\tpjmedia_frame_type frm_type;\n\tpj_status_t status;\n\n\tif (!conf_port)\n\t    continue;\n\n\t/* Var \"ci\" is to count how many ports have been visited. */\n\t++ci;\n\n\tstatus = write_port( conf, conf_port, &frame->timestamp,\n\t\t\t     &frm_type);\n\tif (status != PJ_SUCCESS) {\n\t    /* bennylp: why do we need this????\n\t       One thing for sure, put_frame()/write_port() may return\n\t       non-successfull status on Win32 if there's temporary glitch\n\t       on network interface, so disabling the port here does not\n\t       sound like a good idea.\n\n\t    PJ_LOG(4,(THIS_FILE, \"Port %.*s put_frame() returned %d. \"\n\t\t\t\t \"Port is now disabled\",\n\t\t\t\t (int)conf_port->name.slen,\n\t\t\t\t conf_port->name.ptr,\n\t\t\t\t status));\n\t    conf_port->tx_setting = PJMEDIA_PORT_DISABLE;\n\t    */\n\t    continue;\n\t}\n\n\t/* Set the type of frame to be returned to sound playback\n\t * device.\n\t */\n\tif (i == 0)\n\t    speaker_frame_type = frm_type;\n    }\n\n    /* Return sound playback frame. */\n    if (conf->ports[0]->tx_level) {\n\tTRACE_((THIS_FILE, \"write to audio, count=%d\", \n\t\t\t   conf->samples_per_frame));\n\tpjmedia_copy_samples( (pj_int16_t*)frame->buf, \n\t\t\t      (const pj_int16_t*)conf->ports[0]->mix_buf, \n\t\t\t      conf->samples_per_frame);\n    } else {\n\t/* Force frame type NONE */\n\tspeaker_frame_type = PJMEDIA_FRAME_TYPE_NONE;\n    }\n\n    /* MUST set frame type */\n    frame->type = speaker_frame_type;\n\n    pj_mutex_unlock(conf->mutex);\n\n#ifdef REC_FILE\n    if (fhnd_rec == NULL)\n\tfhnd_rec = fopen(REC_FILE, \"wb\");\n    if (fhnd_rec)\n\tfwrite(frame->buf, frame->size, 1, fhnd_rec);\n#endif\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * get_frame() for passive port\n */\nstatic pj_status_t get_frame_pasv(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame)\n{\n    pj_assert(0);\n    PJ_UNUSED_ARG(this_port);\n    PJ_UNUSED_ARG(frame);\n    return -1;\n}\n\n\n/*\n * Recorder (or passive port) callback.\n */\nstatic pj_status_t put_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame)\n{\n    pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;\n    struct conf_port *port = conf->ports[this_port->port_data.ldata];\n    pj_status_t status;\n\n    /* Check for correct size. */\n    PJ_ASSERT_RETURN( frame->size == conf->samples_per_frame *\n\t\t\t\t     conf->bits_per_sample / 8,\n\t\t      PJMEDIA_ENCSAMPLESPFRAME);\n\n    /* Check existance of delay_buf instance */\n    PJ_ASSERT_RETURN( port->delay_buf, PJ_EBUG );\n\n    /* Skip if this port is muted/disabled. */\n    if (port->rx_setting != PJMEDIA_PORT_ENABLE) {\n\treturn PJ_SUCCESS;\n    }\n\n    /* Skip if no port is listening to the microphone */\n    if (port->listener_cnt == 0) {\n\treturn PJ_SUCCESS;\n    }\n\n    status = pjmedia_delay_buf_put(port->delay_buf, (pj_int16_t*)frame->buf);\n\n    return status;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/converter.c",
    "content": "/* $Id: converter.c 4412 2013-03-05 03:12:32Z riza $ */\n/*\n * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia/converter.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/log.h>\n\n#define THIS_FILE\t\"converter.c\"\n\nstruct pjmedia_converter_mgr\n{\n    pjmedia_converter_factory  factory_list;\n};\n\nstatic pjmedia_converter_mgr *converter_manager_instance;\n\n#if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL\nPJ_DECL(pj_status_t)\npjmedia_libswscale_converter_init(pjmedia_converter_mgr *mgr);\n#endif\n\n#if defined(PJMEDIA_HAS_LIBYUV) && PJMEDIA_HAS_LIBYUV != 0\nPJ_DECL(pj_status_t)\npjmedia_libyuv_converter_init(pjmedia_converter_mgr *mgr);\n#endif\n\nPJ_DEF(pj_status_t) pjmedia_converter_mgr_create(pj_pool_t *pool,\n\t\t\t\t\t         pjmedia_converter_mgr **p_mgr)\n{\n    pjmedia_converter_mgr *mgr;\n    pj_status_t status = PJ_SUCCESS;\n\n    mgr = PJ_POOL_ALLOC_T(pool, pjmedia_converter_mgr);\n    pj_list_init(&mgr->factory_list);\n\n    if (!converter_manager_instance)\n\tconverter_manager_instance = mgr;\n\n#if defined(PJMEDIA_HAS_LIBYUV) && PJMEDIA_HAS_LIBYUV != 0\n    status = pjmedia_libyuv_converter_init(mgr);\n    if (status != PJ_SUCCESS) {\n\tPJ_PERROR(4,(THIS_FILE, status,\n\t\t     \"Error initializing libyuv converter\"));\n    }\n#endif\n\n#if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL\n    status = pjmedia_libswscale_converter_init(mgr);\n    if (status != PJ_SUCCESS) {\n\tPJ_PERROR(4,(THIS_FILE, status,\n\t\t     \"Error initializing libswscale converter\"));\n    }\n#endif\n\n    if (p_mgr)\n\t*p_mgr = mgr;\n\n    return status;\n}\n\nPJ_DEF(pjmedia_converter_mgr*) pjmedia_converter_mgr_instance(void)\n{\n    pj_assert(converter_manager_instance != NULL);\n    return converter_manager_instance;\n}\n\nPJ_DEF(void) pjmedia_converter_mgr_set_instance(pjmedia_converter_mgr *mgr)\n{\n    converter_manager_instance = mgr;\n}\n\nPJ_DEF(void) pjmedia_converter_mgr_destroy(pjmedia_converter_mgr *mgr)\n{\n    pjmedia_converter_factory *f;\n\n    if (!mgr) mgr = pjmedia_converter_mgr_instance();\n\n    PJ_ASSERT_ON_FAIL(mgr != NULL, return);\n\n    f = mgr->factory_list.next;\n    while (f != &mgr->factory_list) {\n\tpjmedia_converter_factory *next = f->next;\n\tpj_list_erase(f);\n\t(*f->op->destroy_factory)(f);\n\tf = next;\n    }\n\n    if (converter_manager_instance == mgr)\n\tconverter_manager_instance = NULL;\n}\n\nPJ_DEF(pj_status_t)\npjmedia_converter_mgr_register_factory(pjmedia_converter_mgr *mgr,\n\t\t\t\t       pjmedia_converter_factory *factory)\n{\n    pjmedia_converter_factory *pf;\n\n    if (!mgr) mgr = pjmedia_converter_mgr_instance();\n\n    PJ_ASSERT_RETURN(mgr != NULL, PJ_EINVAL);\n\n    PJ_ASSERT_RETURN(!pj_list_find_node(&mgr->factory_list, factory),\n\t\t     PJ_EEXISTS);\n\n    pf = mgr->factory_list.next;\n    while (pf != &mgr->factory_list) {\n\tif (pf->priority < factory->priority)\n\t    break;\n\tpf = pf->next;\n    }\n    pj_list_insert_before(pf, factory);\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t)\npjmedia_converter_mgr_unregister_factory(pjmedia_converter_mgr *mgr,\n\t\t\t\t         pjmedia_converter_factory *f,\n\t\t\t\t         pj_bool_t destroy)\n{\n    if (!mgr) mgr = pjmedia_converter_mgr_instance();\n\n    PJ_ASSERT_RETURN(mgr != NULL, PJ_EINVAL);\n\n    PJ_ASSERT_RETURN(pj_list_find_node(&mgr->factory_list, f), PJ_ENOTFOUND);\n    pj_list_erase(f);\n    if (destroy)\n\t(*f->op->destroy_factory)(f);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_converter_create(pjmedia_converter_mgr *mgr,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      pjmedia_conversion_param *param,\n\t\t\t\t\t      pjmedia_converter **p_cv)\n{\n    pjmedia_converter_factory *f;\n    pjmedia_converter *cv = NULL;\n    pj_status_t status = PJ_ENOTFOUND;\n\n    if (!mgr) mgr = pjmedia_converter_mgr_instance();\n\n    PJ_ASSERT_RETURN(mgr != NULL, PJ_EINVAL);\n\n    *p_cv = NULL;\n\n    f = mgr->factory_list.next;\n    while (f != &mgr->factory_list) {\n\tstatus = (*f->op->create_converter)(f, pool, param, &cv);\n\tif (status == PJ_SUCCESS)\n\t    break;\n\tf = f->next;\n    }\n\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (param->src.type == PJMEDIA_TYPE_VIDEO) {\n        char src_fourcc_name[5];\n        char dst_fourcc_name[5];\n        PJ_LOG(4, (THIS_FILE, \"Converter %p (%s) created for video: %dx%d %s -> %dx%d %s\",\n                              cv,\n                              f->name,\n                              param->src.det.vid.size.w,\n                              param->src.det.vid.size.h,\n                              pjmedia_fourcc_name(param->src.id, src_fourcc_name),\n                              param->dst.det.vid.size.w,\n                              param->dst.det.vid.size.h,\n                              pjmedia_fourcc_name(param->dst.id, dst_fourcc_name)));\n    } else if (param->src.type == PJMEDIA_TYPE_AUDIO) {\n        PJ_LOG(4, (THIS_FILE, \"Converter %p created for audio\", cv));\n    } else {\n        PJ_LOG(4, (THIS_FILE, \"Converter %p created for unknown\", cv));\n    }\n\n    *p_cv = cv;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_converter_convert(pjmedia_converter *cv,\n\t\t\t\t\t       pjmedia_frame *src_frame,\n\t\t\t\t\t       pjmedia_frame *dst_frame)\n{\n    return (*cv->op->convert)(cv, src_frame, dst_frame);\n}\n\nPJ_DEF(void) pjmedia_converter_destroy(pjmedia_converter *cv)\n{\n    PJ_LOG(4, (THIS_FILE, \"Converter %p destroyed\", cv));\n    (*cv->op->destroy)(cv);\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/converter_libswscale.c",
    "content": "/* $Id: converter_libswscale.c 4076 2012-04-24 09:40:35Z bennylp $ */\n/*\n * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia/converter.h>\n#include <pj/errno.h>\n\n#if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL\n\n#include \"ffmpeg_util.h\"\n#include <libswscale/swscale.h>\n\nstatic pj_status_t factory_create_converter(pjmedia_converter_factory *cf,\n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    const pjmedia_conversion_param*prm,\n\t\t\t\t\t    pjmedia_converter **p_cv);\nstatic void factory_destroy_factory(pjmedia_converter_factory *cf);\nstatic pj_status_t libswscale_conv_convert(pjmedia_converter *converter,\n\t\t\t\t\t   pjmedia_frame *src_frame,\n\t\t\t\t\t   pjmedia_frame *dst_frame);\nstatic void libswscale_conv_destroy(pjmedia_converter *converter);\n\n\nstruct fmt_info\n{\n    const pjmedia_video_format_info \t*fmt_info;\n    pjmedia_video_apply_fmt_param \t apply_param;\n};\n\nstruct ffmpeg_converter\n{\n    pjmedia_converter \t\t\t base;\n    struct SwsContext \t\t\t*sws_ctx;\n    struct fmt_info\t\t\t src,\n\t\t\t\t\t dst;\n};\n\nstatic pjmedia_converter_factory_op libswscale_factory_op =\n{\n    &factory_create_converter,\n    &factory_destroy_factory\n};\n\nstatic pjmedia_converter_op liswscale_converter_op =\n{\n    &libswscale_conv_convert,\n    &libswscale_conv_destroy\n};\n\nstatic pj_status_t factory_create_converter(pjmedia_converter_factory *cf,\n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    const pjmedia_conversion_param *prm,\n\t\t\t\t\t    pjmedia_converter **p_cv)\n{\n    enum AVPixelFormat srcFormat, dstFormat;\n    const pjmedia_video_format_detail *src_detail, *dst_detail;\n    const pjmedia_video_format_info *src_fmt_info, *dst_fmt_info;\n    struct SwsContext *sws_ctx;\n    struct ffmpeg_converter *fcv;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(cf);\n\n    /* Only supports video */\n    if (prm->src.type != PJMEDIA_TYPE_VIDEO ||\n\tprm->dst.type != prm->src.type ||\n\tprm->src.detail_type != PJMEDIA_FORMAT_DETAIL_VIDEO ||\n\tprm->dst.detail_type != prm->src.detail_type)\n    {\n\treturn PJ_ENOTSUP;\n    }\n\n    /* lookup source format info */\n    src_fmt_info = pjmedia_get_video_format_info(\n\t\t      pjmedia_video_format_mgr_instance(),\n\t\t      prm->src.id);\n    if (!src_fmt_info)\n\treturn PJ_ENOTSUP;\n\n    /* lookup destination format info */\n    dst_fmt_info = pjmedia_get_video_format_info(\n\t\t      pjmedia_video_format_mgr_instance(),\n\t\t      prm->dst.id);\n    if (!dst_fmt_info)\n\treturn PJ_ENOTSUP;\n\n    src_detail = pjmedia_format_get_video_format_detail(&prm->src, PJ_TRUE);\n    dst_detail = pjmedia_format_get_video_format_detail(&prm->dst, PJ_TRUE);\n\n    status = pjmedia_format_id_to_PixelFormat(prm->src.id, &srcFormat);\n    if (status != PJ_SUCCESS)\n\treturn PJ_ENOTSUP;\n\n    status = pjmedia_format_id_to_PixelFormat(prm->dst.id, &dstFormat);\n    if (status != PJ_SUCCESS)\n\treturn PJ_ENOTSUP;\n\n    sws_ctx = sws_getContext(src_detail->size.w, src_detail->size.h, srcFormat,\n\t\t             dst_detail->size.w, dst_detail->size.h, dstFormat,\n\t\t\t     SWS_BICUBIC,\n\t\t\t     NULL, NULL, NULL);\n    if (sws_ctx == NULL)\n\treturn PJ_ENOTSUP;\n\n    fcv = PJ_POOL_ZALLOC_T(pool, struct ffmpeg_converter);\n    fcv->base.op = &liswscale_converter_op;\n    fcv->sws_ctx = sws_ctx;\n    fcv->src.apply_param.size = src_detail->size;\n    fcv->src.fmt_info = src_fmt_info;\n    fcv->dst.apply_param.size = dst_detail->size;\n    fcv->dst.fmt_info = dst_fmt_info;\n\n    *p_cv = &fcv->base;\n\n    return PJ_SUCCESS;\n}\n\nstatic void factory_destroy_factory(pjmedia_converter_factory *cf)\n{\n    PJ_UNUSED_ARG(cf);\n}\n\nstatic pj_status_t libswscale_conv_convert(pjmedia_converter *converter,\n\t\t\t\t\t   pjmedia_frame *src_frame,\n\t\t\t\t\t   pjmedia_frame *dst_frame)\n{\n    struct ffmpeg_converter *fcv = (struct ffmpeg_converter*)converter;\n    struct fmt_info *src = &fcv->src,\n\t            *dst = &fcv->dst;\n    int h;\n\n    src->apply_param.buffer = src_frame->buf;\n    (*src->fmt_info->apply_fmt)(src->fmt_info, &src->apply_param);\n\n    dst->apply_param.buffer = dst_frame->buf;\n    (*dst->fmt_info->apply_fmt)(dst->fmt_info, &dst->apply_param);\n\n    h = sws_scale(fcv->sws_ctx,\n\t          (const uint8_t* const *)src->apply_param.planes,\n\t          src->apply_param.strides,\n\t\t  0, src->apply_param.size.h,\n\t\t  dst->apply_param.planes, dst->apply_param.strides);\n\n    //sws_scale() return value can't be trusted? There are cases when\n    //sws_scale() returns zero but conversion seems to work okay.\n    //return h==(int)dst->apply_param.size.h ? PJ_SUCCESS : PJ_EUNKNOWN;\n    PJ_UNUSED_ARG(h);\n\n    return PJ_SUCCESS;\n}\n\nstatic void libswscale_conv_destroy(pjmedia_converter *converter)\n{\n    struct ffmpeg_converter *fcv = (struct ffmpeg_converter*)converter;\n    if (fcv->sws_ctx) {\n\tstruct SwsContext *tmp = fcv->sws_ctx;\n\tfcv->sws_ctx = NULL;\n\tsws_freeContext(tmp);\n    }\n}\n\nstatic pjmedia_converter_factory libswscale_factory =\n{\n    NULL, NULL,\t\t\t\t\t/* list */\n    \"libswscale\",\t\t\t\t/* name */\n    PJMEDIA_CONVERTER_PRIORITY_NORMAL+1,\t/* priority */\n    NULL\t\t\t\t\t/* op will be init-ed later  */\n};\n\nPJ_DEF(pj_status_t)\npjmedia_libswscale_converter_init(pjmedia_converter_mgr *mgr)\n{\n    libswscale_factory.op = &libswscale_factory_op;\n    pjmedia_ffmpeg_add_ref();\n    return pjmedia_converter_mgr_register_factory(mgr, &libswscale_factory);\n}\n\n\nPJ_DEF(pj_status_t)\npjmedia_libswscale_converter_shutdown(pjmedia_converter_mgr *mgr,\n\t\t\t\t      pj_pool_t *pool)\n{\n    PJ_UNUSED_ARG(pool);\n    pjmedia_ffmpeg_dec_ref();\n    return pjmedia_converter_mgr_unregister_factory(mgr, &libswscale_factory,\n\t\t\t\t\t\t    PJ_TRUE);\n}\n\n#ifdef _MSC_VER\n#   pragma comment( lib, \"avutil.lib\")\n#   pragma comment( lib, \"swscale.lib\")\n#endif\n\n#endif /* #if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/converter_libyuv.c",
    "content": "/* $Id$ */\n/*\n * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\n#include <pjmedia/converter.h>\n#include <pj/errno.h>\n\n#if defined(PJMEDIA_HAS_LIBYUV) && PJMEDIA_HAS_LIBYUV != 0\n\n#include  <libyuv.h>\n\nstatic pj_status_t factory_create_converter(pjmedia_converter_factory *cf,\n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    const pjmedia_conversion_param*prm,\n\t\t\t\t\t    pjmedia_converter **p_cv);\n\nstatic void factory_destroy_factory(pjmedia_converter_factory *cf);\n\nstatic pj_status_t libyuv_conv_convert(pjmedia_converter *converter,\n\t\t\t\t       pjmedia_frame *src_frame,\n\t\t\t\t       pjmedia_frame *dst_frame);\n\nstatic void libyuv_conv_destroy(pjmedia_converter *converter);\n\nstatic pjmedia_converter_factory_op libyuv_factory_op =\n{\n    &factory_create_converter,\n    &factory_destroy_factory\n};\n\nstatic pjmedia_converter_op libyuv_converter_op =\n{\n    &libyuv_conv_convert,\n    &libyuv_conv_destroy\n};\n\ntypedef struct fmt_info\n{\n    const pjmedia_video_format_info \t*vid_fmt_info;\n    pjmedia_video_apply_fmt_param \t apply_param;\n} fmt_info;\n\ntypedef enum conv_func_type\n{\n    CONV_PACK_TO_PACK,\n    CONV_PACK_TO_PLANAR,\n    CONV_PLANAR_TO_PACK,\n    CONV_PLANAR_TO_PLANAR,\n    SCALE_PACK,\n    SCALE_PLANAR\n} conv_func_type;\n\ntypedef void (*gen_conv_func)();\n\ntypedef int (*conv_pack_to_pack_method)(const uint8* src, int src_stride,\n\t\t\t\t\tuint8* dst, int dst_stride,\n\t\t\t\t\tint width, int height);\t\n\ntypedef int (*conv_pack_to_planar_method)(const uint8* src, int src_stride,\n\t\t\t\t\t  uint8* dst1, int dst_stride1,\n\t\t\t\t\t  uint8* dst2, int dst_stride2,\n\t\t\t\t\t  uint8* dst3, int dst_stride3,\n\t\t\t\t\t  int width, int height);\n\ntypedef int (*conv_planar_to_pack_method)(const uint8* src1, int src_stride1,\n\t\t\t\t\t  const uint8* src2, int src_stride2,\n\t\t\t\t\t  const uint8* src3, int src_stride3,\n\t\t\t\t\t  uint8* dst, int dst_stride,\n\t\t\t\t\t  int width, int height);\n\ntypedef int (*conv_planar_to_planar_method)(const uint8* src1, int src_stride1,\n\t\t\t\t\t    const uint8* src2, int src_stride2,\n\t\t\t\t\t    const uint8* src3, int src_stride3,\n\t\t\t\t\t    uint8* dst1, int dst_stride1,\n\t\t\t\t\t    uint8* dst2, int dst_stride2,\n\t\t\t\t\t    uint8* dst3, int dst_stride3,\n\t\t\t\t\t    int width, int height);\n\ntypedef int  (*scale_pack_method)\n\t     (const uint8* src_argb, int src_stride_argb,\n              int src_width, int src_height,\n              uint8* dst_argb, int dst_stride_argb,\n              int dst_width, int dst_height,\n              enum FilterMode filtering);\n\ntypedef int (*scale_planar_method)\t\n\t    (const uint8* src_y, int src_stride_y,\n             const uint8* src_u, int src_stride_u,\n             const uint8* src_v, int src_stride_v,\n             int src_width, int src_height,\n             uint8* dst_y, int dst_stride_y,\n             uint8* dst_u, int dst_stride_u,\n             uint8* dst_v, int dst_stride_v,\n             int dst_width, int dst_height,\n             enum FilterMode filtering);\n\ntypedef union act_method\n{\n    conv_pack_to_pack_method\t    conv_pack_to_pack;\n    conv_pack_to_planar_method\t    conv_pack_to_planar;\n    conv_planar_to_pack_method\t    conv_planar_to_pack;\n    conv_planar_to_planar_method    conv_planar_to_planar;\n    scale_pack_method\t\t    scale_pack;\n    scale_planar_method\t\t    scale_planar;    \n} act_method;\n\ntypedef struct fmt_convert_map {\n    pj_uint32_t\t\t\t    src_id;\n    pj_uint32_t\t\t\t    dst_id;\n    conv_func_type\t\t    func_type;\n    gen_conv_func\t\t    conv_func;\n} fmt_convert_map;\n\n/* Maximum number of steps/act needed for the conversion/scale process. */\n#define MAXIMUM_ACT 3\n\n/* Define the filter mode for libyuv:\n * 0 : None (fastest)\n * 1 : Linear\n * 2 : Biinear\n * 3 : Filter Box (best quality)\n */\n#if !defined(LIBYUV_FILTER_MODE) \n#   define LIBYUV_FILTER_MODE 3\n#endif\n\n#define METHOD_IS_SCALE(mtd) mtd>CONV_PLANAR_TO_PLANAR\n\n/* Macro to help define format conversion table. */\n#define GET_PJ_FORMAT(fmt) PJMEDIA_FORMAT_##fmt\n\n#define MAP_CONV_PACK_TO_PACK(src,dst,method) GET_PJ_FORMAT(src),\\\n        GET_PJ_FORMAT(dst),CONV_PACK_TO_PACK,(gen_conv_func)&method\n#define MAP_CONV_PACK_TO_PLANAR(src,dst,method) GET_PJ_FORMAT(src),\\\n        GET_PJ_FORMAT(dst),CONV_PACK_TO_PLANAR,(gen_conv_func)&method\n#define MAP_CONV_PLANAR_TO_PACK(src,dst,method) GET_PJ_FORMAT(src),\\\n        GET_PJ_FORMAT(dst),CONV_PLANAR_TO_PACK,(gen_conv_func)&method\n#define MAP_CONV_PLANAR_TO_PLANAR(src,dst,method) GET_PJ_FORMAT(src),\\\n        GET_PJ_FORMAT(dst),CONV_PLANAR_TO_PLANAR,(gen_conv_func)&method\n#define MAP_SCALE_PACK(fmt,method) GET_PJ_FORMAT(fmt),\\\n        GET_PJ_FORMAT(fmt),SCALE_PACK,(gen_conv_func)&method\n#define MAP_SCALE_PLANAR(fmt,method) GET_PJ_FORMAT(fmt),\\\n        GET_PJ_FORMAT(fmt),SCALE_PLANAR,(gen_conv_func)&method\n\nstatic fmt_convert_map conv_to_i420[] = \n{\n    {MAP_CONV_PACK_TO_PLANAR(RGB24,I420,RGB24ToI420)},\n    {MAP_CONV_PACK_TO_PLANAR(RGBA,I420,ABGRToI420)},\n    {MAP_CONV_PACK_TO_PLANAR(BGRA,I420,ARGBToI420)},\n    {MAP_CONV_PACK_TO_PLANAR(YUY2,I420,YUY2ToI420)},\n    {MAP_CONV_PACK_TO_PLANAR(UYVY,I420,UYVYToI420)},\n    {MAP_CONV_PLANAR_TO_PLANAR(I422,I420,I422ToI420)}    \n};\n\nstatic fmt_convert_map conv_from_i420[] = \n{\n    {MAP_CONV_PLANAR_TO_PACK(I420,RGB24,I420ToRGB24)},\n    {MAP_CONV_PLANAR_TO_PACK(I420,RGBA,I420ToABGR)},\n    {MAP_CONV_PLANAR_TO_PACK(I420,BGRA,I420ToARGB)},\n    {MAP_CONV_PLANAR_TO_PACK(I420,YUY2,I420ToYUY2)},\n    {MAP_CONV_PLANAR_TO_PACK(I420,UYVY,I420ToUYVY)},\n    {MAP_CONV_PLANAR_TO_PLANAR(I420,I422,I420ToI422)},\n    {MAP_SCALE_PLANAR(I420,I420Scale)}\n};\n\nstatic fmt_convert_map conv_to_bgra[] = \n{\n    {MAP_CONV_PACK_TO_PACK(RGB24,BGRA,RGB24ToARGB)},\n    {MAP_CONV_PACK_TO_PACK(RGBA,BGRA,ABGRToARGB)},    \n    {MAP_CONV_PACK_TO_PACK(YUY2,BGRA,YUY2ToARGB)},\n    {MAP_CONV_PACK_TO_PACK(UYVY,BGRA,UYVYToARGB)},\n    {MAP_CONV_PLANAR_TO_PACK(I422,BGRA,I422ToARGB)},\n    {MAP_CONV_PLANAR_TO_PACK(I420,BGRA,I420ToARGB)}\n};\n\nstatic fmt_convert_map conv_from_bgra[] = \n{\n    {MAP_CONV_PACK_TO_PACK(BGRA,RGB24,ARGBToRGB24)},\n    {MAP_CONV_PACK_TO_PACK(BGRA,RGBA,ARGBToABGR)},\n    {MAP_CONV_PACK_TO_PACK(BGRA,YUY2,ARGBToYUY2)},\n    {MAP_CONV_PACK_TO_PACK(BGRA,UYVY,ARGBToUYVY)},\n    {MAP_CONV_PACK_TO_PLANAR(BGRA,I422,ARGBToI422)},\n    {MAP_CONV_PACK_TO_PLANAR(BGRA,I420,ARGBToI420)},\n    {MAP_SCALE_PACK(BGRA,ARGBScale)}\n};\n\ntypedef struct converter_act \n{\n    conv_func_type\t    act_type;\n    struct fmt_info\t    src_fmt_info;\n    struct fmt_info\t    dst_fmt_info;\n    act_method\t\t    method;\n} converter_act;\n\nstruct libyuv_converter\n{\n    pjmedia_converter \t\t\t base;      \n    int\t\t\t\t\t act_num;\n    converter_act\t\t\t act[MAXIMUM_ACT];\n};\n\n/* Find the matched format conversion map. */ \nstatic pj_status_t get_converter_map(pj_uint32_t src_id, \n\t\t \t\t     pj_uint32_t dst_id,\n\t\t\t\t     const pjmedia_rect_size *src_size, \n\t\t\t\t     const pjmedia_rect_size *dst_size,\n\t\t\t\t     int act_num,\n\t\t\t\t     converter_act *act)\n{\n    fmt_convert_map *map = NULL;\n    unsigned cnt = 0, i = 0;\n    unsigned act_idx = act_num - 1;\n\n#   define GET_MAP(src) \\\n    do { \\\n\tmap=src; \\\n\tcnt=PJ_ARRAY_SIZE(src); \\\n    }while(0)\n\n    if (src_id == PJMEDIA_FORMAT_I420) {\n\tGET_MAP(conv_from_i420);\n    } else if (src_id == PJMEDIA_FORMAT_BGRA) {\n\tGET_MAP(conv_from_bgra);\n    }\n\n    if (!map) {\n\tif (dst_id == PJMEDIA_FORMAT_I420) {\n\t    GET_MAP(conv_to_i420);\n\t} else if (dst_id == PJMEDIA_FORMAT_BGRA) {\n\t    GET_MAP(conv_to_bgra);\n\t}\n    }\n\n    if (!map)\n\treturn PJ_ENOTSUP;\n\n    for (;i<cnt;++i) {\n\tif ((map[i].src_id == src_id) && (map[i].dst_id == dst_id))\n\t    break;\n    }\n\n    if (i == cnt)\n\treturn PJ_ENOTSUP;\n\n    act[act_idx].act_type = map[i].func_type;\n\n    switch (act[act_idx].act_type) {\n    case CONV_PACK_TO_PACK:\n\tact[act_idx].method.conv_pack_to_pack = \n\t\t\t\t     (conv_pack_to_pack_method)map[i].conv_func;\n\tbreak;\n    case CONV_PACK_TO_PLANAR:\n\tact[act_idx].method.conv_pack_to_planar = \n\t\t\t\t   (conv_pack_to_planar_method)map[i].conv_func;\n\tbreak;\n    case CONV_PLANAR_TO_PACK:\n\tact[act_idx].method.conv_planar_to_pack = \n\t\t\t\t   (conv_planar_to_pack_method)map[i].conv_func;\n\tbreak;\n    case CONV_PLANAR_TO_PLANAR:\n\tact[act_idx].method.conv_planar_to_planar = \n\t\t\t\t (conv_planar_to_planar_method)map[i].conv_func;\n\tbreak;\n    case SCALE_PACK:\n\tact[act_idx].method.scale_pack = (scale_pack_method)map[i].conv_func;\n\tbreak;\n    case SCALE_PLANAR:\n\tact[act_idx].method.scale_planar = \n\t\t\t\t\t  (scale_planar_method)map[i].conv_func;\n\tbreak;\n    }    \n\n    act[act_idx].src_fmt_info.vid_fmt_info = pjmedia_get_video_format_info(\n\t\t\t\t\t    pjmedia_video_format_mgr_instance(),\n\t\t\t\t\t    src_id);\n    \n    act[act_idx].dst_fmt_info.vid_fmt_info = \n\t      pjmedia_get_video_format_info(pjmedia_video_format_mgr_instance(),\n\t\t\t\t\t    dst_id);\n\n    /* Source buffer size is always the same as the previous destination buffer \n       size, except for the first act. */\n    act[act_idx].src_fmt_info.apply_param.size = (!act_idx)?*src_size:\n\t\t\t\t   act[act_idx-1].dst_fmt_info.apply_param.size;\n\n    /* Destination buffer size is not the same as source buffer size \n       when scaling. */\n    act[act_idx].dst_fmt_info.apply_param.size = \n\t\t\t\t     (METHOD_IS_SCALE(act[act_idx].act_type))?\n\t\t\t\t     *dst_size:\n\t\t\t\t     act[act_idx].src_fmt_info.apply_param.size;\n    \n    return PJ_SUCCESS;\n}\n\n/* This method will return the prefered conversion format based \n * on the color model. \n */\nstatic pjmedia_format_id get_next_conv_fmt(pj_uint32_t src_id) {\n    const pjmedia_video_format_info *vid_info = pjmedia_get_video_format_info(\n\t\t\t\t\t    pjmedia_video_format_mgr_instance(),\n\t\t\t\t\t    src_id);\n\n    if (!vid_info)\n\treturn PJMEDIA_FORMAT_BGRA;\n\n    if (vid_info->color_model == PJMEDIA_COLOR_MODEL_YUV) {\n\treturn PJMEDIA_FORMAT_I420;\n    } else {\n\treturn PJMEDIA_FORMAT_BGRA;\n    }\n}\n\n/* This method will find and set all the steps needed for conversion/scale. \n * More than one step might be needed, since not all format is provided with \n * a direct conversion/scale method.\n * e.g : Scale YUY2 (240*320) to YUY2 (320*720)\n *\t - Step 1: Convert YUY2(240*320) to I420 (240*320)\n *\t - Step 2: Scale I420 (320*760)\n *\t - Step 3: Convert I420 (320*760) to YUY2 (320*760)\n */\nstatic int set_converter_act(pj_uint32_t src_id, \n\t\t\t     pj_uint32_t dst_id,\n\t\t\t     const pjmedia_rect_size *src_size, \n\t\t\t     const pjmedia_rect_size *dst_size,\n\t\t\t     converter_act *act)\n{\n    unsigned act_num = 0;\n    pj_uint32_t current_id = src_id;\n    pj_bool_t need_scale = PJ_FALSE;\n\n    /* Convert to I420 or BGRA if needed. */\n    if ((src_id != PJMEDIA_FORMAT_I420) || (src_id != PJMEDIA_FORMAT_BGRA)) {\n\tpj_uint32_t next_id = get_next_conv_fmt(src_id);\n        if (get_converter_map(src_id, next_id, src_size, dst_size, ++act_num, \n                              act) != PJ_SUCCESS)\n        {\n            return 0;\t\t\t\n        }\t\t\t\t\t\t   \n        \t\n\tcurrent_id = next_id;\n    }\n\n    /* Scale if needed */\n    need_scale = ((src_size->w != dst_size->w) ||\n\t\t  (src_size->h != dst_size->h));\n\n    if (need_scale) {\n\tif (get_converter_map(current_id, current_id, src_size, dst_size, \n\t\t\t      ++act_num, act) != PJ_SUCCESS)\n        {\n            return 0;                        \n        }                              \n    }\n\n    /* Convert if needed */\n    if (current_id != dst_id) {\n\tif (get_converter_map(current_id, dst_id, src_size, dst_size, ++act_num,\n                              act) != PJ_SUCCESS)\n        {\n            return 0;\n        }                              \n    }\n\n    return act_num; \n}\n\n/* Additional buffer might be needed for formats without direct conversion/scale\n * method. This method will allocate and set the destination buffer needed by\n * the conversion/scaling process.\n */\nstatic pj_status_t set_destination_buffer(pj_pool_t *pool, \n\t\t\t\t\t  struct libyuv_converter *lconv)\n{\n    int i = 0;\n\n    for (;i<lconv->act_num-1;++i) {\n\tpj_size_t buffer_size = 0;\t\n\tfmt_info *info = &lconv->act[i].dst_fmt_info;\n\n\t/* Get destination buffer size. */\n\t(*info->vid_fmt_info->apply_fmt)(info->vid_fmt_info, \n\t\t\t\t\t &info->apply_param);\n\n\tbuffer_size = info->apply_param.framebytes;\n\n\t/* Allocate buffer. */\n\tlconv->act[i].dst_fmt_info.apply_param.buffer = \n\t\t\t\t  (pj_uint8_t*)pj_pool_alloc(pool, buffer_size);\n\n\tif (!lconv->act[i].dst_fmt_info.apply_param.buffer)\n\t    return PJ_ENOMEM;\n    }\n    return PJ_SUCCESS;\n}\n\n/* Check the act input/output format matched the conversion/scale format. */\nstatic pj_bool_t check_converter_act(const converter_act *act, \n\t\t\t\t     int act_num, \n\t\t\t\t     pj_uint32_t src_id,\n\t\t\t\t     const pjmedia_rect_size *src_size,\n\t\t\t\t     pj_uint32_t dst_id, \n\t\t\t\t     const pjmedia_rect_size *dst_size)\n{\n    if (act_num) {\n\tconst struct fmt_info *first_fmt = &act[0].src_fmt_info;\n\tconst struct fmt_info *last_fmt = &act[act_num-1].dst_fmt_info;\t\n\n\tif ((first_fmt->vid_fmt_info->id == src_id) &&\n\t    (first_fmt->apply_param.size.h == src_size->h) &&\n\t    (first_fmt->apply_param.size.w == src_size->w) &&\n\t    (last_fmt->vid_fmt_info->id == dst_id) && \n\t    (last_fmt->apply_param.size.h == dst_size->h) &&\n\t    (last_fmt->apply_param.size.w == dst_size->w))\n\t{\n\t    return PJ_TRUE;\n\t}\n    } \n    return PJ_FALSE;\n}\n\nstatic pj_status_t factory_create_converter(pjmedia_converter_factory *cf,\n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    const pjmedia_conversion_param *prm,\n\t\t\t\t\t    pjmedia_converter **p_cv)\n{\n    const pjmedia_video_format_detail *src_detail, *dst_detail;\n    const pjmedia_video_format_info *src_fmt_info, *dst_fmt_info;\n    struct libyuv_converter *lconv = NULL;\n    pj_status_t status = PJ_ENOTSUP;\n\n    PJ_UNUSED_ARG(cf);\n\n    /* Only supports video */\n    if (prm->src.type != PJMEDIA_TYPE_VIDEO ||\n\tprm->dst.type != prm->src.type ||\n\tprm->src.detail_type != PJMEDIA_FORMAT_DETAIL_VIDEO ||\n\tprm->dst.detail_type != prm->src.detail_type)\n    {\n\treturn status;\n    }\n\n    /* lookup source format info */\n    src_fmt_info = pjmedia_get_video_format_info(\n\t\t\t\t\t    pjmedia_video_format_mgr_instance(),\n\t\t\t\t\t    prm->src.id);\n\n    if (!src_fmt_info)\n\treturn status;\n\n    /* lookup destination format info */\n    dst_fmt_info = pjmedia_get_video_format_info(\n\t\t\t\t\t    pjmedia_video_format_mgr_instance(),\n\t\t\t\t\t    prm->dst.id);\n\n    if (!dst_fmt_info)\n\treturn status;\n\n    src_detail = pjmedia_format_get_video_format_detail(&prm->src, PJ_TRUE);\n    dst_detail = pjmedia_format_get_video_format_detail(&prm->dst, PJ_TRUE);\n    \n    lconv = PJ_POOL_ZALLOC_T(pool, struct libyuv_converter);\n    lconv->base.op = &libyuv_converter_op;\n\n    lconv->act_num = set_converter_act(src_fmt_info->id, dst_fmt_info->id, \n\t\t\t\t       &src_detail->size, &dst_detail->size,\n\t\t\t\t       lconv->act);\n\n    if (!lconv->act_num) {\n\treturn status;\n    }\n\n    if (!check_converter_act(lconv->act, lconv->act_num, \n\t\t\t     src_fmt_info->id, &src_detail->size,\n\t\t\t     dst_fmt_info->id, &dst_detail->size)) \n    {\n\treturn status;\n    }\n\n    status = set_destination_buffer(pool, lconv);\n\n    *p_cv = &lconv->base;\n\n    return status;\n}\n\nstatic void factory_destroy_factory(pjmedia_converter_factory *cf)\n{\n    PJ_UNUSED_ARG(cf);\n}\n\nstatic pj_status_t libyuv_conv_convert(pjmedia_converter *converter,\n\t\t\t\t       pjmedia_frame *src_frame,\n\t\t\t\t       pjmedia_frame *dst_frame)\n{\n    struct libyuv_converter *lconv = (struct libyuv_converter*)converter;\n    int i = 0;\n\n    /* Set the first act buffer from src frame. */\n    lconv->act[0].src_fmt_info.apply_param.buffer = src_frame->buf;\n\n    /* Set the last act buffer from dst frame. */\n    lconv->act[lconv->act_num-1].dst_fmt_info.apply_param.buffer = \n\t\t\t\t\t\t\t\t dst_frame->buf;\n\n    for (;i<lconv->act_num;++i) {\t\n\t/* Use destination info as the source info for the next act. */\n\tstruct fmt_info *src_fmt_info = (i==0)?&lconv->act[i].src_fmt_info: \n\t\t\t\t\t&lconv->act[i-1].dst_fmt_info;\n\n\tstruct fmt_info *dst_fmt_info = &lconv->act[i].dst_fmt_info;\t\n\t\n\t(*src_fmt_info->vid_fmt_info->apply_fmt)(src_fmt_info->vid_fmt_info, \n\t\t\t\t\t\t &src_fmt_info->apply_param);\n\n\t(*dst_fmt_info->vid_fmt_info->apply_fmt)(dst_fmt_info->vid_fmt_info, \n\t\t\t\t\t\t &dst_fmt_info->apply_param);\n\n\tswitch (lconv->act[i].act_type) {\n\tcase CONV_PACK_TO_PACK:\n\t    (*lconv->act[i].method.conv_pack_to_pack)(\n\t\t\t      (const uint8*)src_fmt_info->apply_param.planes[0],\n\t\t\t      src_fmt_info->apply_param.strides[0],\n\t\t\t      dst_fmt_info->apply_param.planes[0], \n\t\t\t      dst_fmt_info->apply_param.strides[0],\n\t\t\t      dst_fmt_info->apply_param.size.w, \n\t\t\t      dst_fmt_info->apply_param.size.h);\n\t    break;\n\tcase CONV_PACK_TO_PLANAR:\n\t    (*lconv->act[i].method.conv_pack_to_planar)(\n\t\t\t      (const uint8*)src_fmt_info->apply_param.planes[0],\n\t\t\t      src_fmt_info->apply_param.strides[0],\n\t\t\t      dst_fmt_info->apply_param.planes[0], \n\t\t\t      dst_fmt_info->apply_param.strides[0],\n\t\t\t      dst_fmt_info->apply_param.planes[1], \n\t\t\t      dst_fmt_info->apply_param.strides[1],\n\t\t\t      dst_fmt_info->apply_param.planes[2], \n\t\t\t      dst_fmt_info->apply_param.strides[2],\n\t\t\t      dst_fmt_info->apply_param.size.w, \n\t\t\t      dst_fmt_info->apply_param.size.h);\n\t    break;\n\tcase CONV_PLANAR_TO_PACK:\n\t    (*lconv->act[i].method.conv_planar_to_pack)(\n\t\t\t      (const uint8*)src_fmt_info->apply_param.planes[0],\n\t\t\t      src_fmt_info->apply_param.strides[0],\n\t\t\t      (const uint8*)src_fmt_info->apply_param.planes[1],\n\t\t\t      src_fmt_info->apply_param.strides[1],\n\t\t\t      (const uint8*)src_fmt_info->apply_param.planes[2],\n\t\t\t      src_fmt_info->apply_param.strides[2],\n\t\t\t      dst_fmt_info->apply_param.planes[0], \n\t\t\t      dst_fmt_info->apply_param.strides[0],\n\t\t\t      dst_fmt_info->apply_param.size.w, \n\t\t\t      dst_fmt_info->apply_param.size.h);\n\t    break;\n\tcase CONV_PLANAR_TO_PLANAR:\n\t    (*lconv->act[i].method.conv_planar_to_planar)(\n\t\t\t      (const uint8*)src_fmt_info->apply_param.planes[0],\n\t\t\t      src_fmt_info->apply_param.strides[0],\n\t\t\t      (const uint8*)src_fmt_info->apply_param.planes[1],\n\t\t\t      src_fmt_info->apply_param.strides[1],\n\t\t\t      (const uint8*)src_fmt_info->apply_param.planes[2],\n\t\t\t      src_fmt_info->apply_param.strides[2],\n\t\t\t      dst_fmt_info->apply_param.planes[0], \n\t\t\t      dst_fmt_info->apply_param.strides[0],\n\t\t\t      dst_fmt_info->apply_param.planes[1], \n\t\t\t      dst_fmt_info->apply_param.strides[1],\n\t\t\t      dst_fmt_info->apply_param.planes[2], \n\t\t\t      dst_fmt_info->apply_param.strides[2],\n\t\t\t      dst_fmt_info->apply_param.size.w, \n\t\t\t      dst_fmt_info->apply_param.size.h);\n\t    break;\n\tcase SCALE_PACK:\n\t    (*lconv->act[i].method.scale_pack)(\n\t\t\t      (const uint8*)src_fmt_info->apply_param.planes[0],\n\t\t\t      src_fmt_info->apply_param.strides[0],\n\t\t\t      src_fmt_info->apply_param.size.w,\n\t\t\t      src_fmt_info->apply_param.size.h,\n\t\t\t      (uint8*)dst_fmt_info->apply_param.planes[0],\n\t\t\t      dst_fmt_info->apply_param.strides[0],\n\t\t\t      dst_fmt_info->apply_param.size.w,\n\t\t\t      dst_fmt_info->apply_param.size.h,\n\t\t\t      LIBYUV_FILTER_MODE);\n\t    break;\t\n\tcase SCALE_PLANAR:\n\t    (*lconv->act[i].method.scale_planar)(\n\t\t\t      (const uint8*)src_fmt_info->apply_param.planes[0],\n\t\t\t      src_fmt_info->apply_param.strides[0],\n\t\t\t      (const uint8*)src_fmt_info->apply_param.planes[1],\n\t\t\t      src_fmt_info->apply_param.strides[1],\n\t\t\t      (const uint8*)src_fmt_info->apply_param.planes[2],\n\t\t\t      src_fmt_info->apply_param.strides[2],\n\t\t\t      src_fmt_info->apply_param.size.w,\n\t\t\t      src_fmt_info->apply_param.size.h,\n\t\t\t      (uint8*)dst_fmt_info->apply_param.planes[0],\n\t\t\t      dst_fmt_info->apply_param.strides[0],\n\t\t\t      (uint8*)dst_fmt_info->apply_param.planes[1],\n\t\t\t      dst_fmt_info->apply_param.strides[1],\n\t\t\t      (uint8*)dst_fmt_info->apply_param.planes[2],\n\t\t\t      dst_fmt_info->apply_param.strides[2],\n\t\t\t      dst_fmt_info->apply_param.size.w,\n\t\t\t      dst_fmt_info->apply_param.size.h,\n\t\t\t      LIBYUV_FILTER_MODE);\n\t    break;\t\n\t};\t\n    }    \n    return PJ_SUCCESS;\n}\n\nstatic void libyuv_conv_destroy(pjmedia_converter *converter)\n{\n    PJ_UNUSED_ARG(converter);\n}\n\nstatic pjmedia_converter_factory libyuv_factory =\n{\n    NULL, NULL,\t\t\t\t\t/* list */\n    \"libyuv\",\t\t\t\t\t/* name */\n    PJMEDIA_CONVERTER_PRIORITY_NORMAL,\t\t/* priority */\n    NULL\t\t\t\t\t/* op will be init-ed later  */\n};\n\nPJ_DEF(pj_status_t)\npjmedia_libyuv_converter_init(pjmedia_converter_mgr *mgr)\n{\n    libyuv_factory.op = &libyuv_factory_op;\n    return pjmedia_converter_mgr_register_factory(mgr, &libyuv_factory);\n}\n\n\nPJ_DEF(pj_status_t)\npjmedia_libyuv_converter_shutdown(pjmedia_converter_mgr *mgr,\n\t\t\t\t  pj_pool_t *pool)\n{\n    PJ_UNUSED_ARG(pool);\n    return pjmedia_converter_mgr_unregister_factory(mgr, &libyuv_factory,\n\t\t\t\t\t\t    PJ_TRUE);\n}\n\n#ifdef _MSC_VER\n#   pragma comment(lib, \"libyuv.lib\")\n#endif\n\n#endif //#if defined(PJMEDIA_HAS_LIBYUV) && PJMEDIA_HAS_LIBYUV != 0\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/delaybuf.c",
    "content": "/* $Id: delaybuf.c 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pjmedia/delaybuf.h>\n#include <pjmedia/circbuf.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/frame.h>\n#include <pjmedia/wsola.h>\n#include <pj/assert.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/math.h>\n#include <pj/pool.h>\n\n\n#if 0\n#   define TRACE__(x) PJ_LOG(3,x)\n#else\n#   define TRACE__(x)\n#endif\n\n/* Operation types of delay buffer */\nenum OP\n{\n    OP_PUT,\n    OP_GET\n};\n\n/* Specify time for delaybuf to recalculate effective delay, in ms.\n */\n#define RECALC_TIME\t    2000\n\n/* Default value of maximum delay, in ms, this value is used when \n * maximum delay requested is less than ptime (one frame length).\n */\n#define DEFAULT_MAX_DELAY   400\n\n/* Number of frames to add to learnt level for additional stability.\n */\n#define SAFE_MARGIN\t    0\n\n/* This structure describes internal delaybuf settings and states.\n */\nstruct pjmedia_delay_buf\n{\n    /* Properties and configuration */\n    char\t     obj_name[PJ_MAX_OBJ_NAME];\n    pj_lock_t\t    *lock;\t\t/**< Lock object.\t\t     */\n    unsigned\t     samples_per_frame; /**< Number of samples in one frame  */\n    unsigned\t     ptime;\t\t/**< Frame time, in ms\t\t     */\n    unsigned\t     channel_count;\t/**< Channel count, in ms\t     */\n    pjmedia_circ_buf *circ_buf;\t\t/**< Circular buffer to store audio\n\t\t\t\t\t     samples\t\t\t     */\n    unsigned\t     max_cnt;\t\t/**< Maximum samples to be buffered  */\n    unsigned\t     eff_cnt;\t\t/**< Effective count of buffered \n\t\t\t\t\t     samples to keep the optimum\n\t\t\t\t\t     balance between delay and \n\t\t\t\t\t     stability. This is calculated \n\t\t\t\t\t     based on burst level.\t     */\n\n    /* Learning vars */\n    unsigned\t     level;\t\t/**< Burst level counter\t     */\n    enum OP\t     last_op;\t\t/**< Last op (GET or PUT) of learning*/\n    int\t\t     recalc_timer;\t/**< Timer for recalculating max_level*/\n    unsigned\t     max_level;\t\t/**< Current max burst level\t     */\n\n    /* Drift handler */\n    pjmedia_wsola   *wsola;\t\t/**< Drift handler\t\t     */\n};\n\n\nPJ_DEF(pj_status_t) pjmedia_delay_buf_create( pj_pool_t *pool,\n\t\t\t\t\t      const char *name,\n\t\t\t\t\t      unsigned clock_rate,\n\t\t\t\t\t      unsigned samples_per_frame,\n\t\t\t\t\t      unsigned channel_count,\n\t\t\t\t\t      unsigned max_delay,\n\t\t\t\t\t      unsigned options,\n\t\t\t\t\t      pjmedia_delay_buf **p_b)\n{\n    pjmedia_delay_buf *b;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && samples_per_frame && clock_rate && channel_count &&\n\t\t     p_b, PJ_EINVAL);\n\n    if (!name) {\n\tname = \"delaybuf\";\n    }\n\n    b = PJ_POOL_ZALLOC_T(pool, pjmedia_delay_buf);\n\n    pj_ansi_strncpy(b->obj_name, name, PJ_MAX_OBJ_NAME-1);\n\n    b->samples_per_frame = samples_per_frame;\n    b->channel_count = channel_count;\n    b->ptime = samples_per_frame * 1000 / clock_rate / channel_count;\n    if (max_delay < b->ptime)\n\tmax_delay = PJ_MAX(DEFAULT_MAX_DELAY, b->ptime);\n\n    b->max_cnt = samples_per_frame * max_delay / b->ptime;\n    b->eff_cnt = b->max_cnt >> 1;\n    b->recalc_timer = RECALC_TIME;\n\n    /* Create circular buffer */\n    status = pjmedia_circ_buf_create(pool, b->max_cnt, &b->circ_buf);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (!(options & PJMEDIA_DELAY_BUF_SIMPLE_FIFO)) {\n        /* Create WSOLA */\n        status = pjmedia_wsola_create(pool, clock_rate, samples_per_frame, 1,\n\t\t\t\t      PJMEDIA_WSOLA_NO_FADING, &b->wsola);\n        if (status != PJ_SUCCESS)\n\t    return status;\n        PJ_LOG(5, (b->obj_name, \"Using delay buffer with WSOLA.\"));\n    } else {\n        PJ_LOG(5, (b->obj_name, \"Using simple FIFO delay buffer.\"));\n    }\n\n    /* Finally, create mutex */\n    status = pj_lock_create_recursive_mutex(pool, b->obj_name, \n\t\t\t\t\t    &b->lock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    *p_b = b;\n\n    TRACE__((b->obj_name,\"Delay buffer created\"));\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_delay_buf_destroy(pjmedia_delay_buf *b)\n{\n    pj_status_t status = PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(b, PJ_EINVAL);\n\n    pj_lock_acquire(b->lock);\n\n    if (b->wsola) {\n        status = pjmedia_wsola_destroy(b->wsola);\n        if (status == PJ_SUCCESS)\n\t    b->wsola = NULL;\n    }\n\n    pj_lock_release(b->lock);\n\n    pj_lock_destroy(b->lock);\n    b->lock = NULL;\n\n    return status;\n}\n\n/* This function will erase samples from delay buffer.\n * The number of erased samples is guaranteed to be >= erase_cnt.\n */\nstatic void shrink_buffer(pjmedia_delay_buf *b, unsigned erase_cnt)\n{\n    pj_int16_t *buf1, *buf2;\n    unsigned buf1len;\n    unsigned buf2len;\n    pj_status_t status;\n\n    pj_assert(b && erase_cnt && pjmedia_circ_buf_get_len(b->circ_buf));\n\n    pjmedia_circ_buf_get_read_regions(b->circ_buf, &buf1, &buf1len, \n\t\t\t\t      &buf2, &buf2len);\n    status = pjmedia_wsola_discard(b->wsola, buf1, buf1len, buf2, buf2len,\n\t\t\t\t   &erase_cnt);\n\n    if ((status == PJ_SUCCESS) && (erase_cnt > 0)) {\n\t/* WSOLA discard will manage the first buffer to be full, unless \n\t * erase_cnt is greater than second buffer length. So it is safe\n\t * to just set the circular buffer length.\n\t */\n\n\tpjmedia_circ_buf_set_len(b->circ_buf, \n\t\t\t\t pjmedia_circ_buf_get_len(b->circ_buf) - \n\t\t\t\t erase_cnt);\n\n\tPJ_LOG(5,(b->obj_name,\"%d samples reduced, buf_cnt=%d\", \n\t       erase_cnt, pjmedia_circ_buf_get_len(b->circ_buf)));\n    }\n}\n\n/* Fast increase, slow decrease */\n#define AGC_UP(cur, target) cur = (cur + target*3) >> 2\n#define AGC_DOWN(cur, target) cur = (cur*3 + target) >> 2\n#define AGC(cur, target) \\\n    if (cur < target) AGC_UP(cur, target); \\\n    else AGC_DOWN(cur, target)\n\nstatic void update(pjmedia_delay_buf *b, enum OP op)\n{\n    /* Sequential operation */\n    if (op == b->last_op) {\n\t++b->level;\n\treturn;\n    } \n\n    /* Switching operation */\n    if (b->level > b->max_level)\n\tb->max_level = b->level;\n\n    b->recalc_timer -= (b->level * b->ptime) >> 1;\n\n    b->last_op = op;\n    b->level = 1;\n\n    /* Recalculate effective count based on max_level */\n    if (b->recalc_timer <= 0) {\n\tunsigned new_eff_cnt = (b->max_level+SAFE_MARGIN)*b->samples_per_frame;\n\n\t/* Smoothening effective count transition */\n\tAGC(b->eff_cnt, new_eff_cnt);\n\t\n\t/* Make sure the new effective count is multiplication of \n\t * channel_count, so let's round it up.\n\t */\n\tif (b->eff_cnt % b->channel_count)\n\t    b->eff_cnt += b->channel_count - (b->eff_cnt % b->channel_count);\n\n\tTRACE__((b->obj_name,\"Cur eff_cnt=%d\", b->eff_cnt));\n\t\n\tb->max_level = 0;\n\tb->recalc_timer = RECALC_TIME;\n    }\n\n    /* See if we need to shrink the buffer to reduce delay */\n    if (op == OP_PUT && pjmedia_circ_buf_get_len(b->circ_buf) > \n\tb->samples_per_frame + b->eff_cnt)\n    {\n\tunsigned erase_cnt = b->samples_per_frame >> 1;\n\tunsigned old_buf_cnt = pjmedia_circ_buf_get_len(b->circ_buf);\n\n\tshrink_buffer(b, erase_cnt);\n\tPJ_LOG(4,(b->obj_name,\"Buffer size adjusted from %d to %d (eff_cnt=%d)\",\n\t          old_buf_cnt,\n\t\t  pjmedia_circ_buf_get_len(b->circ_buf),\n\t\t  b->eff_cnt));\n    }\n}\n\nPJ_DEF(pj_status_t) pjmedia_delay_buf_put(pjmedia_delay_buf *b,\n\t\t\t\t\t   pj_int16_t frame[])\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(b && frame, PJ_EINVAL);\n\n    pj_lock_acquire(b->lock);\n\n    if (b->wsola) {\n        update(b, OP_PUT);\n    \n        status = pjmedia_wsola_save(b->wsola, frame, PJ_FALSE);\n        if (status != PJ_SUCCESS) {\n\t    pj_lock_release(b->lock);\n\t    return status;\n        }\n    }\n\n    /* Overflow checking */\n    if (pjmedia_circ_buf_get_len(b->circ_buf) + b->samples_per_frame > \n\tb->max_cnt)\n    {\n\tunsigned erase_cnt;\n\n        if (b->wsola) {\n\t    /* shrink one frame or just the diff? */\n\t    //erase_cnt = b->samples_per_frame;\n\t    erase_cnt = pjmedia_circ_buf_get_len(b->circ_buf) + \n\t\t        b->samples_per_frame - b->max_cnt;\n\n\t    shrink_buffer(b, erase_cnt);\n        }\n\n\t/* Check if shrinking failed or erased count is less than requested,\n\t * delaybuf needs to drop eldest samples, this is bad since the voice\n\t * samples get rough transition which may produce tick noise.\n\t */\n\tif (pjmedia_circ_buf_get_len(b->circ_buf) + b->samples_per_frame > \n\t    b->max_cnt) \n\t{\n\t    erase_cnt = pjmedia_circ_buf_get_len(b->circ_buf) + \n\t\t\tb->samples_per_frame - b->max_cnt;\n\n\t    pjmedia_circ_buf_adv_read_ptr(b->circ_buf, erase_cnt);\n\n\t    PJ_LOG(4,(b->obj_name,\"%sDropping %d eldest samples, buf_cnt=%d\",\n                      (b->wsola? \"Shrinking failed or insufficient. \": \"\"),\n                      erase_cnt, pjmedia_circ_buf_get_len(b->circ_buf)));\n\t}\n    }\n\n    pjmedia_circ_buf_write(b->circ_buf, frame, b->samples_per_frame);\n\n    pj_lock_release(b->lock);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_delay_buf_get( pjmedia_delay_buf *b,\n\t\t\t\t\t   pj_int16_t frame[])\n{\n    pj_status_t status = PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(b && frame, PJ_EINVAL);\n\n    pj_lock_acquire(b->lock);\n\n    if (b->wsola)\n        update(b, OP_GET);\n\n    /* Starvation checking */\n    if (pjmedia_circ_buf_get_len(b->circ_buf) < b->samples_per_frame) {\n\n\tPJ_LOG(4,(b->obj_name,\"Underflow, buf_cnt=%d, will generate 1 frame\",\n\t\t  pjmedia_circ_buf_get_len(b->circ_buf)));\n\n        if (b->wsola) {\n            status = pjmedia_wsola_generate(b->wsola, frame);\n\n\t    if (status == PJ_SUCCESS) {\n\t        TRACE__((b->obj_name,\"Successfully generate 1 frame\"));\n\t        if (pjmedia_circ_buf_get_len(b->circ_buf) == 0) {\n\t\t    pj_lock_release(b->lock);\n\t\t    return PJ_SUCCESS;\n\t        }\n\n\t        /* Put generated frame into buffer */\n\t        pjmedia_circ_buf_write(b->circ_buf, frame,\n                                       b->samples_per_frame);\n            }\n        }\n\n\tif (!b->wsola || status != PJ_SUCCESS) {\n\t    unsigned buf_len = pjmedia_circ_buf_get_len(b->circ_buf);\n\t    \n\t    /* Give all what delay buffer has, then pad with zeroes */\n            if (b->wsola)\n\t        PJ_LOG(4,(b->obj_name,\"Error generating frame, status=%d\", \n\t\t          status));\n\n\t    pjmedia_circ_buf_read(b->circ_buf, frame, buf_len);\n\t    pjmedia_zero_samples(&frame[buf_len], \n\t\t\t\t b->samples_per_frame - buf_len);\n\n\t    /* The buffer is empty now, reset it */\n\t    pjmedia_circ_buf_reset(b->circ_buf);\n\n\t    pj_lock_release(b->lock);\n\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    pjmedia_circ_buf_read(b->circ_buf, frame, b->samples_per_frame);\n\n    pj_lock_release(b->lock);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_delay_buf_reset(pjmedia_delay_buf *b)\n{\n    PJ_ASSERT_RETURN(b, PJ_EINVAL);\n\n    pj_lock_acquire(b->lock);\n\n    b->recalc_timer = RECALC_TIME;\n\n    /* Reset buffer */\n    pjmedia_circ_buf_reset(b->circ_buf);\n\n    /* Reset WSOLA */\n    if (b->wsola)\n        pjmedia_wsola_reset(b->wsola, 0);\n\n    pj_lock_release(b->lock);\n\n    PJ_LOG(5,(b->obj_name,\"Delay buffer is reset\"));\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/dummy.c",
    "content": "/* $Id: dummy.c 3715 2011-08-19 09:35:25Z nanang $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\n#include <pjmedia/frame.h>\n#include <pjmedia/port.h>\n#include <pjmedia/types.h>\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/echo_common.c",
    "content": "/* $Id: echo_common.c 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pjmedia/echo.h>\n#include <pjmedia/delaybuf.h>\n#include <pjmedia/frame.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/list.h>\n#include <pj/log.h>\n#include <pj/math.h>\n#include <pj/pool.h>\n#include \"echo_internal.h\"\n\n#define THIS_FILE   \"echo_common.c\"\n\ntypedef struct ec_operations ec_operations;\n\nstruct frame\n{\n    PJ_DECL_LIST_MEMBER(struct frame);\n    short   buf[1];\n};\n\nstruct pjmedia_echo_state\n{\n    pj_pool_t\t    *pool;\n    char\t    *obj_name;\n    unsigned\t     samples_per_frame;\n    void\t    *state;\n    ec_operations   *op;\n\n    pj_bool_t\t     lat_ready;\t    /* lat_buf has been filled in.\t    */\n    struct frame     lat_buf;\t    /* Frame queue for delayed playback\t    */\n    struct frame     lat_free;\t    /* Free frame list.\t\t\t    */\n\n    pjmedia_delay_buf\t*delay_buf;\n    pj_int16_t\t    *frm_buf;\n};\n\n\nstruct ec_operations\n{\n    const char *name;\n\n    pj_status_t (*ec_create)(pj_pool_t *pool,\n\t\t\t     unsigned clock_rate,\n\t\t\t     unsigned channel_count,\n\t\t\t     unsigned samples_per_frame,\n\t\t\t     unsigned tail_ms,\n\t\t\t     unsigned options,\n\t\t\t     void **p_state );\n    pj_status_t (*ec_destroy)(void *state );\n    void        (*ec_reset)(void *state );\n    pj_status_t (*ec_cancel)(void *state,\n\t\t\t     pj_int16_t *rec_frm,\n\t\t\t     const pj_int16_t *play_frm,\n\t\t\t     unsigned options,\n\t\t\t     void *reserved );\n    pj_status_t (*ec_playback)(void *state,\n\t\t\t     pj_int16_t *play_frm );\n    pj_status_t (*ec_capture)(void *state,\n\t\t\t     pj_int16_t *rec_frm,\n\t\t\t     unsigned options );\n};\n\n\nstatic struct ec_operations echo_supp_op = \n{\n    \"Echo suppressor\",\n    &echo_supp_create,\n    &echo_supp_destroy,\n    &echo_supp_reset,\n    &echo_supp_cancel_echo\n};\n\n\n\n/*\n * Speex AEC prototypes\n */\n#if defined(PJMEDIA_HAS_SPEEX_AEC) && PJMEDIA_HAS_SPEEX_AEC!=0\nstatic struct ec_operations speex_aec_op = \n{\n    \"AEC\",\n    &speex_aec_create,\n    &speex_aec_destroy,\n    &speex_aec_reset,\n    &speex_aec_cancel_echo,\n    &speex_aec_playback,\n    &speex_aec_capture\n};\n#endif\n\n\n/*\n * IPP AEC prototypes\n */\n#if defined(PJMEDIA_HAS_INTEL_IPP_AEC) && PJMEDIA_HAS_INTEL_IPP_AEC!=0\nstatic struct ec_operations ipp_aec_op = \n{\n    \"IPP AEC\",\n    &ipp_aec_create,\n    &ipp_aec_destroy,\n    &ipp_aec_reset,\n    &ipp_aec_cancel_echo\n};\n#endif\n\n\n/*\n * WebRTC prototypes\n */\n#if defined(PJMEDIA_HAS_WEBRTC_AEC) && PJMEDIA_HAS_WEBRTC_AEC!=0\nstatic struct ec_operations webrtc_aec_op =\n{\n    \"WEBRTC AEC\",\n    &webrtc_aec_create,\n    &webrtc_aec_destroy,\n    &webrtc_aec_reset,\n    &webrtc_aec_cancel_echo\n};\n#endif\n\n\n/*\n * Create the echo canceller. \n */\nPJ_DEF(pj_status_t) pjmedia_echo_create( pj_pool_t *pool,\n\t\t\t\t\t unsigned clock_rate,\n\t\t\t\t\t unsigned samples_per_frame,\n\t\t\t\t\t unsigned tail_ms,\n\t\t\t\t\t unsigned latency_ms,\n\t\t\t\t\t unsigned options,\n\t\t\t\t\t pjmedia_echo_state **p_echo )\n{\n    return pjmedia_echo_create2(pool, clock_rate, 1, samples_per_frame,\n\t\t\t\ttail_ms, latency_ms, options, p_echo);\n}\n\n/*\n * Create the echo canceller. \n */\nPJ_DEF(pj_status_t) pjmedia_echo_create2(pj_pool_t *pool,\n\t\t\t\t\t unsigned clock_rate,\n\t\t\t\t\t unsigned channel_count,\n\t\t\t\t\t unsigned samples_per_frame,\n\t\t\t\t\t unsigned tail_ms,\n\t\t\t\t\t unsigned latency_ms,\n\t\t\t\t\t unsigned options,\n\t\t\t\t\t pjmedia_echo_state **p_echo )\n{\n    unsigned ptime, lat_cnt;\n    unsigned delay_buf_opt = 0;\n    pjmedia_echo_state *ec;\n    pj_status_t status;\n\n    /* Create new pool and instantiate and init the EC */\n    pool = pj_pool_create(pool->factory, \"ec%p\", 256, 256, NULL);\n    ec = PJ_POOL_ZALLOC_T(pool, struct pjmedia_echo_state);\n    ec->pool = pool;\n    ec->obj_name = pool->obj_name;\n    ec->samples_per_frame = samples_per_frame;\n    ec->frm_buf = (pj_int16_t*)pj_pool_alloc(pool, samples_per_frame<<1);\n    pj_list_init(&ec->lat_buf);\n    pj_list_init(&ec->lat_free);\n\n    /* Select the backend algorithm */\n    if (0) {\n\t/* Dummy */\n\t;\n#if defined(PJMEDIA_HAS_SPEEX_AEC) && PJMEDIA_HAS_SPEEX_AEC!=0\n    } else if ((options & PJMEDIA_ECHO_ALGO_MASK) == PJMEDIA_ECHO_SPEEX ||\n\t       (options & PJMEDIA_ECHO_ALGO_MASK) == PJMEDIA_ECHO_DEFAULT) \n    {\n\tec->op = &speex_aec_op;\n#endif\n\n#if defined(PJMEDIA_HAS_WEBRTC_AEC) && PJMEDIA_HAS_WEBRTC_AEC!=0\n    } else if ((options & PJMEDIA_ECHO_ALGO_MASK) == PJMEDIA_ECHO_WEBRTC ||\n\t       (options & PJMEDIA_ECHO_ALGO_MASK) == PJMEDIA_ECHO_DEFAULT) \n    {\n\tec->op = &webrtc_aec_op;\n#endif\n\n#if defined(PJMEDIA_HAS_INTEL_IPP_AEC) && PJMEDIA_HAS_INTEL_IPP_AEC!=0\n    } else if ((options & PJMEDIA_ECHO_ALGO_MASK) == PJMEDIA_ECHO_IPP ||\n\t       (options & PJMEDIA_ECHO_ALGO_MASK) == PJMEDIA_ECHO_DEFAULT)\n    {\n\tec->op = &ipp_aec_op;\n\n#endif\n\n    } else {\n\tec->op = &echo_supp_op;\n    }\n\n    /* Completeness check for EC operation playback and capture, they must\n     * be implemented both or none.\n     */\n    pj_assert(!ec->op->ec_capture == !ec->op->ec_playback);\n\n    PJ_LOG(5,(ec->obj_name, \"Creating %s\", ec->op->name));\n\n    /* Instantiate EC object */\n    status = (*ec->op->ec_create)(pool, clock_rate, channel_count, \n\t\t\t\t  samples_per_frame, tail_ms, \n\t\t\t\t  options, &ec->state);\n    if (status != PJ_SUCCESS) {\n\tpj_pool_release(pool);\n\treturn status;\n    }\n\n    /* If EC algo does not have playback and capture callbakcs,\n     * create latency buffer and delay buffer to handle drift.\n     */\n    if (ec->op->ec_playback && ec->op->ec_capture) {\n\tlatency_ms = 0;\n    } else {\n\t/* Create latency buffers */\n\tptime = samples_per_frame * 1000 / clock_rate;\n\tif (latency_ms > ptime) {\n\t    /* Normalize latency with delaybuf/WSOLA latency */\n\t    latency_ms -= PJ_MIN(ptime, PJMEDIA_WSOLA_DELAY_MSEC);\n\t}\n\tif (latency_ms < ptime) {\n\t    /* Give at least one frame delay to simplify programming */\n\t    latency_ms = ptime;\n\t}\n\tlat_cnt = latency_ms / ptime;\n\twhile (lat_cnt--)  {\n\t    struct frame *frm;\n\n\t    frm = (struct frame*) pj_pool_alloc(pool, (samples_per_frame<<1) +\n\t\t\t\t\t\t      sizeof(struct frame));\n\t    pj_list_push_back(&ec->lat_free, frm);\n\t}\n\n\t/* Create delay buffer to compensate drifts */\n\tif (options & PJMEDIA_ECHO_USE_SIMPLE_FIFO)\n\t    delay_buf_opt |= PJMEDIA_DELAY_BUF_SIMPLE_FIFO;\n\tstatus = pjmedia_delay_buf_create(ec->pool, ec->obj_name, clock_rate, \n\t\t\t\t\t  samples_per_frame, channel_count,\n\t\t\t\t\t  (PJMEDIA_SOUND_BUFFER_COUNT+1) * ptime,\n\t\t\t\t\t  delay_buf_opt, &ec->delay_buf);\n\tif (status != PJ_SUCCESS) {\n\t    pj_pool_release(pool);\n\t    return status;\n\t}\n    }\n\n    PJ_LOG(4,(ec->obj_name, \n\t      \"%s created, clock_rate=%d, channel=%d, \"\n\t      \"samples per frame=%d, tail length=%d ms, \"\n\t      \"latency=%d ms\", \n\t      ec->op->name, clock_rate, channel_count, samples_per_frame,\n\t      tail_ms, latency_ms));\n\n    /* Done */\n    *p_echo = ec;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy the Echo Canceller. \n */\nPJ_DEF(pj_status_t) pjmedia_echo_destroy(pjmedia_echo_state *echo )\n{\n    (*echo->op->ec_destroy)(echo->state);\n\n    if (echo->delay_buf) {\n\tpjmedia_delay_buf_destroy(echo->delay_buf);\n\techo->delay_buf = NULL;\n    }\n\n    pj_pool_release(echo->pool);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Reset the echo canceller.\n */\nPJ_DEF(pj_status_t) pjmedia_echo_reset(pjmedia_echo_state *echo )\n{\n    while (!pj_list_empty(&echo->lat_buf)) {\n\tstruct frame *frm;\n\tfrm = echo->lat_buf.next;\n\tpj_list_erase(frm);\n\tpj_list_push_back(&echo->lat_free, frm);\n    }\n    echo->lat_ready = PJ_FALSE;\n    if (echo->delay_buf)\n\tpjmedia_delay_buf_reset(echo->delay_buf);\n    echo->op->ec_reset(echo->state);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Let the Echo Canceller know that a frame has been played to the speaker.\n */\nPJ_DEF(pj_status_t) pjmedia_echo_playback( pjmedia_echo_state *echo,\n\t\t\t\t\t   pj_int16_t *play_frm )\n{\n    /* If EC algo has playback handler, just pass the frame. */\n    if (echo->op->ec_playback) {\n\treturn (*echo->op->ec_playback)(echo->state, play_frm);\n    }\n\n    /* Playing frame should be stored, as it will be used by echo_capture() \n     * as reference frame, delay buffer is used for storing the playing frames\n     * as in case there was clock drift between mic & speaker.\n     *\n     * Ticket #830:\n     * Note that pjmedia_delay_buf_put() may modify the input frame and those\n     * modified frames may not be smooth, i.e: if there were two or more\n     * consecutive pjmedia_delay_buf_get() before next pjmedia_delay_buf_put(),\n     * so we'll just feed the delay buffer with the copy of playing frame,\n     * instead of the original playing frame. However this will cause the EC \n     * uses slight 'different' frames (for reference) than actually played \n     * by the speaker.\n     */\n    pjmedia_copy_samples(echo->frm_buf, play_frm, \n\t\t\t echo->samples_per_frame);\n    pjmedia_delay_buf_put(echo->delay_buf, echo->frm_buf);\n\n    if (!echo->lat_ready) {\n\t/* We've not built enough latency in the buffer, so put this frame\n\t * in the latency buffer list.\n\t */\n\tstruct frame *frm;\n\n\tif (pj_list_empty(&echo->lat_free)) {\n\t    echo->lat_ready = PJ_TRUE;\n\t    PJ_LOG(5,(echo->obj_name, \"Latency bufferring complete\"));\n\t    return PJ_SUCCESS;\n\t}\n\t    \n\tfrm = echo->lat_free.prev;\n\tpj_list_erase(frm);\n\n\t/* Move one frame from delay buffer to the latency buffer. */\n\tpjmedia_delay_buf_get(echo->delay_buf, echo->frm_buf);\n\tpjmedia_copy_samples(frm->buf, echo->frm_buf, echo->samples_per_frame);\n\tpj_list_push_back(&echo->lat_buf, frm);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Let the Echo Canceller knows that a frame has been captured from \n * the microphone.\n */\nPJ_DEF(pj_status_t) pjmedia_echo_capture( pjmedia_echo_state *echo,\n\t\t\t\t\t  pj_int16_t *rec_frm,\n\t\t\t\t\t  unsigned options )\n{\n    struct frame *oldest_frm;\n    pj_status_t status, rc;\n\n    /* If EC algo has capture handler, just pass the frame. */\n    if (echo->op->ec_capture) {\n\treturn (*echo->op->ec_capture)(echo->state, rec_frm, options);\n    }\n\n    if (!echo->lat_ready) {\n\t/* Prefetching to fill in the desired latency */\n\tPJ_LOG(5,(echo->obj_name, \"Prefetching..\"));\n\treturn PJ_SUCCESS;\n    }\n\n    /* Retrieve oldest frame from the latency buffer */\n    oldest_frm = echo->lat_buf.next;\n    pj_list_erase(oldest_frm);\n\n    /* Cancel echo using this reference frame */\n    status = pjmedia_echo_cancel(echo, rec_frm, oldest_frm->buf, \n\t\t\t\t options, NULL);\n\n    /* Move one frame from delay buffer to the latency buffer. */\n    rc = pjmedia_delay_buf_get(echo->delay_buf, oldest_frm->buf);\n    if (rc != PJ_SUCCESS) {\n\t/* Ooops.. no frame! */\n\tPJ_LOG(5,(echo->obj_name, \n\t\t  \"No frame from delay buffer. This will upset EC later\"));\n\tpjmedia_zero_samples(oldest_frm->buf, echo->samples_per_frame);\n    }\n    pj_list_push_back(&echo->lat_buf, oldest_frm);\n    \n    return status;\n}\n\n\n/*\n * Perform echo cancellation.\n */\nPJ_DEF(pj_status_t) pjmedia_echo_cancel( pjmedia_echo_state *echo,\n\t\t\t\t\t pj_int16_t *rec_frm,\n\t\t\t\t\t const pj_int16_t *play_frm,\n\t\t\t\t\t unsigned options,\n\t\t\t\t\t void *reserved )\n{\n    return (*echo->op->ec_cancel)( echo->state, rec_frm, play_frm, options, \n\t\t\t\t   reserved);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/echo_internal.h",
    "content": "/* $Id: echo_internal.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJMEDIA_ECHO_INTERNAL_H__\n#define __PJMEDIA_ECHO_INTERNAL_H__\n\n#include <pjmedia/types.h>\n\nPJ_BEGIN_DECL\n\n/*\n * Simple echo suppressor\n */\nPJ_DECL(pj_status_t) echo_supp_create(pj_pool_t *pool,\n\t\t\t\t      unsigned clock_rate,\n\t\t\t\t      unsigned channel_count,\n\t\t\t\t      unsigned samples_per_frame,\n\t\t\t\t      unsigned tail_ms,\n\t\t\t\t      unsigned options,\n\t\t\t\t      void **p_state );\nPJ_DECL(pj_status_t) echo_supp_destroy(void *state);\nPJ_DECL(void) echo_supp_reset(void *state);\nPJ_DECL(pj_status_t) echo_supp_cancel_echo(void *state,\n\t\t\t\t\t   pj_int16_t *rec_frm,\n\t\t\t\t\t   const pj_int16_t *play_frm,\n\t\t\t\t\t   unsigned options,\n\t\t\t\t\t   void *reserved );\n\nPJ_DECL(pj_status_t) speex_aec_create(pj_pool_t *pool,\n\t\t\t\t      unsigned clock_rate,\n\t\t\t\t      unsigned channel_count,\n\t\t\t\t      unsigned samples_per_frame,\n\t\t\t\t      unsigned tail_ms,\n\t\t\t\t      unsigned options,\n\t\t\t\t      void **p_state );\nPJ_DECL(pj_status_t) speex_aec_destroy(void *state );\nPJ_DECL(void) speex_aec_reset(void *state );\nPJ_DECL(pj_status_t) speex_aec_cancel_echo(void *state,\n\t\t\t\t\t   pj_int16_t *rec_frm,\n\t\t\t\t\t   const pj_int16_t *play_frm,\n\t\t\t\t\t   unsigned options,\n\t\t\t\t\t   void *reserved );\nPJ_DECL(pj_status_t) speex_aec_playback(void *state,\n\t\t\t\t\tpj_int16_t *play_frm );\nPJ_DECL(pj_status_t) speex_aec_capture(void *state,\n\t\t\t\t       pj_int16_t *rec_frm,\n\t\t\t\t       unsigned options );\n\nPJ_DECL(pj_status_t) ipp_aec_create(pj_pool_t *pool,\n\t\t\t\t    unsigned clock_rate,\n\t\t\t\t    unsigned channel_count,\n\t\t\t\t    unsigned samples_per_frame,\n\t\t\t\t    unsigned tail_ms,\n\t\t\t\t    unsigned options,\n\t\t\t\t    void **p_echo );\nPJ_DECL(pj_status_t) ipp_aec_destroy(void *state );\nPJ_DECL(void) ipp_aec_reset(void *state );\nPJ_DECL(pj_status_t) ipp_aec_cancel_echo(void *state,\n\t\t\t\t\t pj_int16_t *rec_frm,\n\t\t\t\t\t const pj_int16_t *play_frm,\n\t\t\t\t\t unsigned options,\n\t\t\t\t\t void *reserved );\n\nPJ_DECL(pj_status_t) webrtc_aec_create(pj_pool_t *pool,\n\t\t\t               unsigned clock_rate,\n\t\t\t               unsigned channel_count,\n\t\t\t               unsigned samples_per_frame,\n\t\t\t               unsigned tail_ms,\n\t\t\t               unsigned options,\n\t\t\t               void **p_echo );\nPJ_DECL(pj_status_t) webrtc_aec_destroy(void *state );\nPJ_DECL(void) webrtc_aec_reset(void *state );\nPJ_DECL(pj_status_t) webrtc_aec_cancel_echo(void *state,\n\t\t\t\t\t    pj_int16_t *rec_frm,\n\t\t\t\t\t    const pj_int16_t *play_frm,\n\t\t\t\t\t    unsigned options,\n\t\t\t\t\t    void *reserved );\n\nPJ_END_DECL\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/echo_port.c",
    "content": "/* $Id: echo_port.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/echo_port.h>\n#include <pjmedia/echo.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n\n\n#define THIS_FILE   \"ec_port.c\"\n#define SIGNATURE   PJMEDIA_SIG_PORT_ECHO\n#define BUF_COUNT   32\n\nstruct ec\n{\n    pjmedia_port\t base;\n    pjmedia_port\t*dn_port;\n    pjmedia_echo_state\t*ec;\n};\n\n\nstatic pj_status_t ec_put_frame(pjmedia_port *this_port, \n\t\t\t\tpjmedia_frame *frame);\nstatic pj_status_t ec_get_frame(pjmedia_port *this_port, \n\t\t\t\tpjmedia_frame *frame);\nstatic pj_status_t ec_on_destroy(pjmedia_port *this_port);\n\n\nPJ_DEF(pj_status_t) pjmedia_echo_port_create(pj_pool_t *pool,\n\t\t\t\t\t     pjmedia_port *dn_port,\n\t\t\t\t\t     unsigned tail_ms,\n\t\t\t\t\t     unsigned latency_ms,\n\t\t\t\t\t     unsigned options,\n\t\t\t\t\t     pjmedia_port **p_port )\n{\n    const pj_str_t AEC = { \"EC\", 2 };\n    pjmedia_audio_format_detail *afd;\n    struct ec *ec;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && dn_port && p_port, PJ_EINVAL);\n\n    afd = pjmedia_format_get_audio_format_detail(&dn_port->info.fmt, PJ_TRUE);\n\n    PJ_ASSERT_RETURN(afd->bits_per_sample==16 && tail_ms,\n\t\t     PJ_EINVAL);\n\n    /* Create the port and the AEC itself */\n    ec = PJ_POOL_ZALLOC_T(pool, struct ec);\n    \n    pjmedia_port_info_init(&ec->base.info, &AEC, SIGNATURE,\n\t\t\t   afd->clock_rate,\n\t\t\t   afd->channel_count,\n\t\t\t   afd->bits_per_sample,\n\t\t\t   PJMEDIA_AFD_SPF(afd));\n\n    status = pjmedia_echo_create2(pool, afd->clock_rate,\n\t\t\t\t  afd->channel_count,\n\t\t\t\t  PJMEDIA_AFD_SPF(afd),\n\t\t\t\t  tail_ms, latency_ms, options, &ec->ec);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* More init */\n    ec->dn_port = dn_port;\n    ec->base.get_frame = &ec_get_frame;\n    ec->base.put_frame = &ec_put_frame;\n    ec->base.on_destroy = &ec_on_destroy;\n\n    /* Done */\n    *p_port = &ec->base;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t ec_put_frame( pjmedia_port *this_port, \n\t\t\t\t pjmedia_frame *frame)\n{\n    struct ec *ec = (struct ec*)this_port;\n\n    PJ_ASSERT_RETURN(this_port->info.signature == SIGNATURE, PJ_EINVAL);\n\n    if (frame->type == PJMEDIA_FRAME_TYPE_NONE ) {\n\treturn pjmedia_port_put_frame(ec->dn_port, frame);\n    }\n\n    PJ_ASSERT_RETURN(frame->size == PJMEDIA_PIA_AVG_FSZ(&this_port->info),\n\t\t     PJ_EINVAL);\n\n    pjmedia_echo_capture(ec->ec, (pj_int16_t*)frame->buf, 0);\n\n    return pjmedia_port_put_frame(ec->dn_port, frame);\n}\n\n\nstatic pj_status_t ec_get_frame( pjmedia_port *this_port, \n\t\t\t\t pjmedia_frame *frame)\n{\n    struct ec *ec = (struct ec*)this_port;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(this_port->info.signature == SIGNATURE, PJ_EINVAL);\n\n    status = pjmedia_port_get_frame(ec->dn_port, frame);\n    if (status!=PJ_SUCCESS || frame->type!=PJMEDIA_FRAME_TYPE_AUDIO) {\n\tpjmedia_zero_samples((pj_int16_t*)frame->buf, \n\t\t\t      PJMEDIA_PIA_SPF(&this_port->info));\n    }\n\n    pjmedia_echo_playback(ec->ec, (pj_int16_t*)frame->buf);\n\n    return status;\n}\n\n\nstatic pj_status_t ec_on_destroy(pjmedia_port *this_port)\n{\n    struct ec *ec = (struct ec*)this_port;\n\n    PJ_ASSERT_RETURN(this_port->info.signature == SIGNATURE, PJ_EINVAL);\n\n    pjmedia_echo_destroy(ec->ec);\n\n    return PJ_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/echo_speex.c",
    "content": "/* $Id: echo_speex.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pjmedia/echo.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/frame.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n\n#if defined(PJMEDIA_HAS_SPEEX_AEC) && PJMEDIA_HAS_SPEEX_AEC != 0\n\n#include <speex/speex_echo.h>\n#include <speex/speex_preprocess.h>\n\n#include \"echo_internal.h\"\n\ntypedef struct speex_ec\n{\n    SpeexEchoState\t *state;\n    SpeexPreprocessState *preprocess;\n\n    unsigned\t\t  samples_per_frame;\n    unsigned\t\t  prefetch;\n    unsigned\t\t  options;\n    pj_int16_t\t\t *tmp_frame;\n} speex_ec;\n\n\n\n/*\n * Create the AEC. \n */\nPJ_DEF(pj_status_t) speex_aec_create(pj_pool_t *pool,\n\t\t\t\t     unsigned clock_rate,\n\t\t\t\t     unsigned channel_count,\n\t\t\t\t     unsigned samples_per_frame,\n\t\t\t\t     unsigned tail_ms,\n\t\t\t\t     unsigned options,\n\t\t\t\t     void **p_echo )\n{\n    speex_ec *echo;\n    int sampling_rate;\n\n    *p_echo = NULL;\n\n    echo = PJ_POOL_ZALLOC_T(pool, speex_ec);\n    PJ_ASSERT_RETURN(echo != NULL, PJ_ENOMEM);\n\n    echo->samples_per_frame = samples_per_frame;\n    echo->options = options;\n\n#if 0\n    echo->state = speex_echo_state_init_mc(echo->samples_per_frame,\n\t\t\t\t\t   clock_rate * tail_ms / 1000,\n\t\t\t\t\t   channel_count, channel_count);\n#else\n    if (channel_count != 1) {\n\tPJ_LOG(2,(\"echo_speex.c\", \"Multichannel EC is not supported by this \"\n\t\t\t\t  \"echo canceller. It may not work.\"));\n    }\n    echo->state = speex_echo_state_init(echo->samples_per_frame,\n    \t\t\t\t\tclock_rate * tail_ms / 1000);\n#endif\n    if (echo->state == NULL) {\n\treturn PJ_ENOMEM;\n    }\n\n    /* Set sampling rate */\n    sampling_rate = clock_rate;\n    speex_echo_ctl(echo->state, SPEEX_ECHO_SET_SAMPLING_RATE, \n\t\t   &sampling_rate);\n\n    echo->preprocess = speex_preprocess_state_init(echo->samples_per_frame,\n\t\t\t\t\t\t   clock_rate);\n    if (echo->preprocess == NULL) {\n\tspeex_echo_state_destroy(echo->state);\n\treturn PJ_ENOMEM;\n    }\n\n    /* Disable all preprocessing, we only want echo cancellation */\n#if 0\n    disabled = 0;\n    enabled = 1;\n    speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_DENOISE, \n\t\t\t &enabled);\n    speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_AGC, \n\t\t\t &disabled);\n    speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_VAD, \n\t\t\t &disabled);\n    speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_DEREVERB, \n\t\t\t &enabled);\n#endif\n\n    /* Enable/disable AGC & denoise */\n    {\n\tspx_int32_t enabled;\n\n\tenabled = PJMEDIA_SPEEX_AEC_USE_AGC;\n\tspeex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_AGC, \n\t\t\t     &enabled);\n\n\tenabled = PJMEDIA_SPEEX_AEC_USE_DENOISE;\n\tspeex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_DENOISE, \n\t\t\t     &enabled);\n    }\n\n    /* Control echo cancellation in the preprocessor */\n   speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, \n\t\t\techo->state);\n\n\n    /* Create temporary frame for echo cancellation */\n    echo->tmp_frame = (pj_int16_t*) pj_pool_zalloc(pool, 2*samples_per_frame);\n    PJ_ASSERT_RETURN(echo->tmp_frame != NULL, PJ_ENOMEM);\n\n    /* Done */\n    *p_echo = echo;\n    return PJ_SUCCESS;\n\n}\n\n\n/*\n * Destroy AEC\n */\nPJ_DEF(pj_status_t) speex_aec_destroy(void *state )\n{\n    speex_ec *echo = (speex_ec*) state;\n\n    PJ_ASSERT_RETURN(echo && echo->state, PJ_EINVAL);\n\n    if (echo->state) {\n\tspeex_echo_state_destroy(echo->state);\n\techo->state = NULL;\n    }\n\n    if (echo->preprocess) {\n\tspeex_preprocess_state_destroy(echo->preprocess);\n\techo->preprocess = NULL;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Reset AEC\n */\nPJ_DEF(void) speex_aec_reset(void *state )\n{\n    speex_ec *echo = (speex_ec*) state;\n    speex_echo_state_reset(echo->state);\n}\n\n\n/*\n * Perform echo cancellation.\n */\nPJ_DEF(pj_status_t) speex_aec_cancel_echo( void *state,\n\t\t\t\t\t   pj_int16_t *rec_frm,\n\t\t\t\t\t   const pj_int16_t *play_frm,\n\t\t\t\t\t   unsigned options,\n\t\t\t\t\t   void *reserved )\n{\n    speex_ec *echo = (speex_ec*) state;\n\n    /* Sanity checks */\n    PJ_ASSERT_RETURN(echo && rec_frm && play_frm && options==0 &&\n\t\t     reserved==NULL, PJ_EINVAL);\n\n    /* Cancel echo, put output in temporary buffer */\n    speex_echo_cancellation(echo->state, (const spx_int16_t*)rec_frm,\n\t\t\t    (const spx_int16_t*)play_frm,\n\t\t\t    (spx_int16_t*)echo->tmp_frame);\n\n\n    /* Preprocess output */\n    speex_preprocess_run(echo->preprocess, (spx_int16_t*)echo->tmp_frame);\n\n    /* Copy temporary buffer back to original rec_frm */\n    pjmedia_copy_samples(rec_frm, echo->tmp_frame, echo->samples_per_frame);\n\n    return PJ_SUCCESS;\n\n}\n\n/*\n * Let AEC know that a frame was queued to be played.\n */\nPJ_DEF(pj_status_t) speex_aec_playback( void *state,\n\t\t\t\t\tpj_int16_t *play_frm )\n{\n    speex_ec *echo = (speex_ec*) state;\n\n    /* Sanity checks */\n    PJ_ASSERT_RETURN(echo && play_frm, PJ_EINVAL);\n\n    speex_echo_playback(echo->state, (spx_int16_t*)play_frm);\n\n    return PJ_SUCCESS;\n\n}\n\n/*\n * Perform echo cancellation to captured frame.\n */\nPJ_DEF(pj_status_t) speex_aec_capture( void *state,\n\t\t\t\t       pj_int16_t *rec_frm,\n\t\t\t\t       unsigned options )\n{\n    speex_ec *echo = (speex_ec*) state;\n\n    /* Sanity checks */\n    PJ_ASSERT_RETURN(echo && rec_frm, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(options);\n\n    /* Cancel echo */\n    pjmedia_copy_samples(echo->tmp_frame, rec_frm, echo->samples_per_frame);\n    speex_echo_capture(echo->state,\n\t\t       (spx_int16_t*)echo->tmp_frame,\n\t\t       (spx_int16_t*)rec_frm);\n\n    /* Apply preprocessing */\n    speex_preprocess_run(echo->preprocess, (spx_int16_t*)rec_frm);\n\n    return PJ_SUCCESS;\n}\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/echo_suppress.c",
    "content": "/* $Id: echo_suppress.c 3664 2011-07-19 03:42:28Z nanang $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia/types.h>\n#include <pjmedia/alaw_ulaw.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/frame.h>\n#include <pjmedia/silencedet.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n\n#include \"echo_internal.h\"\n\n#define THIS_FILE\t\t\t    \"echo_suppress.c\"\n\n/* Maximum float constant */\n#define MAX_FLOAT\t\t(float)1.701411e38\n\n/* The effective learn duration (in seconds) before we declare that learning\n * is complete. The actual learning duration itself may be longer depending\n * on the conversation pattern (e.g. we can't detect echo if speaker is only\n * playing silence).\n */\n#define MAX_CALC_DURATION_SEC\t3\n\n/* The internal audio segment length, in milliseconds. 10ms shold be good\n * and no need to change it.\n */\n#define SEGMENT_PTIME\t\t10\n\n/* The length of the template signal in milliseconds. The longer the template,\n * the better correlation will be found, at the expense of more processing\n * and longer learning time.\n */\n#define TEMPLATE_PTIME\t\t200\n\n/* How long to look back in the past to see if either mic or speaker is\n * active.\n */\n#define SIGNAL_LOOKUP_MSEC\t200\n\n/* The minimum level value to be considered as talking, in uLaw complement\n * (0-255).\n */\n#define MIN_SIGNAL_ULAW\t\t35\n\n/* The period (in seconds) on which the ES will analize it's effectiveness,\n * and it may trigger soft-reset to force recalculation.\n */\n#define CHECK_PERIOD\t\t30\n\n/* Maximum signal level of average echo residue (in uLaw complement). When\n * the residue value exceeds this value, we force the ES to re-learn.\n */\n#define MAX_RESIDUE\t\t2.5\n\n\n#if 0\n#   define TRACE_(expr)\tPJ_LOG(5,expr)\n\nstatic const char *state_names[] =\n{\n    \"Null\",\n    \"local talking\",\n    \"remote silent\",\n    \"doubletalk\",\n    \"remote talking\"\n};\n\n#else\n#   define TRACE_(expr)\n#endif\n\nPJ_INLINE(float) FABS(float val)\n{\n    if (val < 0)\n\treturn -val;\n    else\n\treturn val;\n}\n\n\n#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0\n    typedef float pj_ufloat_t;\n#   define pj_ufloat_from_float(f)\t(f)\n#   define pj_ufloat_mul_u(val1, f)\t((val1) * (f))\n#   define pj_ufloat_mul_i(val1, f)\t((val1) * (f))\n#else\n    typedef pj_uint32_t pj_ufloat_t;\n\n    pj_ufloat_t pj_ufloat_from_float(float f)\n    {\n\treturn (pj_ufloat_t)(f * 65536);\n    }\n\n    unsigned pj_ufloat_mul_u(unsigned val1, pj_ufloat_t val2)\n    {\n\treturn (val1 * val2) >> 16;\n    }\n\n    int pj_ufloat_mul_i(int val1, pj_ufloat_t val2)\n    {\n\treturn (val1 * (pj_int32_t)val2) >> 16;\n    }\n#endif\n\n\n/* Conversation state */\ntypedef enum talk_state\n{\n    ST_NULL,\n    ST_LOCAL_TALK,\n    ST_REM_SILENT,\n    ST_DOUBLETALK,\n    ST_REM_TALK\n} talk_state_t;\n\n\n/* Description:\n\n   The echo suppressor tries to find the position of echoed signal by looking\n   at the correlation between signal played to the speaker (played signal)\n   and the signal captured from the microphone (recorded signal).\n\n   To do this, it first divides the frames (from mic and speaker) into\n   segments, calculate the audio level of the segment, and save the level\n   information in the playback and record history (play_hist and rec_hist\n   respectively).\n\n   In the history, the newest element (depicted as \"t0\" in the diagram belo)\n   is put in the last position of the array.\n\n   The record history size is as large as the template size (tmpl_cnt), since\n   we will use the record history as the template to find the best matching\n   position in the playback history.\n\n   Here is the record history buffer:\n\n       <--templ_cnt-->\n       +-------------+\n       |   rec_hist  |\n       +-------------+\n    t-templ_cnt......t0\n\n   As you can see, the newest frame (\"t0\") is put as the last element in the\n   array.\n\n   The playback history size is larger than record history, since we need to\n   find the matching pattern in the past. The playback history size is\n   \"templ_cnt + tail_cnt\", where \"tail_cnt\" is the number of segments equal\n   to the maximum tail length. The maximum tail length is set when the ES\n   is created.\n\n   Here is the playback history buffer:\n\n       <-----tail_cnt-----> <--templ_cnt-->\n       +-------------------+--------------+\n       |             play_hist            |\n       +-------------------+--------------+\n   t-play_hist_cnt...t-templ_cnt.......t0\n\n\n\n   Learning:\n\n   During the processing, the ES calculates the following values:\n    - the correlation value, that is how similar the playback signal compared\n      to the mic signal. The lower the correlation value the better (i.e. more\n      similar) the signal is. The correlation value is done over the template\n      duration.\n    - the gain scaling factor, that is the ratio between mic signal and\n      speaker signal. The ES calculates both the minimum and average ratios.\n\n   The ES calculates both the values above for every tail position in the\n   playback history. The values are saved in arrays below:\n\n     <-----tail_cnt----->\n     +-------------------+\n     |      corr_sum     |\n     +-------------------+\n     |     min_factor    |\n     +-------------------+\n     |     avg_factor    |\n     +-------------------+\n\n   At the end of processing, the ES iterates through the correlation array and\n   picks the tail index with the lowest corr_sum value. This is the position\n   where echo is most likely to be found.\n\n\n   Processing:\n\n   Once learning is done, the ES will change the level of the mic signal\n   depending on the state of the conversation and according to the ratio that\n   has been found in the learning phase above.\n\n */\n\n/*\n * The simple echo suppresor state\n */\ntypedef struct echo_supp\n{\n    unsigned\t clock_rate;\t    /* Clock rate.\t\t\t    */\n    pj_uint16_t\t samples_per_frame; /* Frame length in samples\t\t    */\n    pj_uint16_t  samples_per_segment;/* Segment length in samples\t    */\n    pj_uint16_t  tail_ms;\t    /* Tail length in milliseconds\t    */\n    pj_uint16_t  tail_samples;\t    /* Tail length in samples.\t\t    */\n\n    pj_bool_t\t learning;\t    /* Are we still learning yet?\t    */\n    talk_state_t talk_state;\t    /* Current talking state\t\t    */\n    int\t\t tail_index;\t    /* Echo location, -1 if not found\t    */\n\n    unsigned\t max_calc;\t    /* # of calc before learning complete.\n                                       (see MAX_CALC_DURATION_SEC)\t    */\n    unsigned\t calc_cnt;\t    /* Number of calculations so far\t    */\n\n    unsigned\t update_cnt;\t    /* # of updates\t\t\t    */\n    unsigned\t templ_cnt;\t    /* Template length, in # of segments    */\n    unsigned\t tail_cnt;\t    /* Tail length, in # of segments\t    */\n    unsigned\t play_hist_cnt;\t    /* # of segments in play_hist\t    */\n    pj_uint16_t *play_hist;\t    /* Array of playback levels\t\t    */\n    pj_uint16_t *rec_hist;\t    /* Array of rec levels\t\t    */\n\n    float\t*corr_sum;\t    /* Array of corr for each tail pos.\t    */\n    float\t*tmp_corr;\t    /* Temporary corr array calculation\t    */\n    float\t best_corr;\t    /* Best correlation so far.\t\t    */\n\n    unsigned\t sum_rec_level;\t    /* Running sum of level in rec_hist\t    */\n    float\t rec_corr;\t    /* Running corr in rec_hist.\t    */\n\n    unsigned\t sum_play_level0;   /* Running sum of level for first pos   */\n    float\t play_corr0;\t    /* Running corr for first pos .\t    */\n\n    float\t*min_factor;\t    /* Array of minimum scaling factor\t    */\n    float\t*avg_factor;\t    /* Array of average scaling factor\t    */\n    float\t*tmp_factor;\t    /* Array to store provisional result    */\n\n    unsigned\t running_cnt;\t    /* Running duration in # of frames\t    */\n    float\t residue;\t    /* Accummulated echo residue.\t    */\n    float\t last_factor;\t    /* Last factor applied to mic signal    */\n} echo_supp;\n\n\n\n/*\n * Create.\n */\nPJ_DEF(pj_status_t) echo_supp_create( pj_pool_t *pool,\n\t\t\t\t      unsigned clock_rate,\n\t\t\t\t      unsigned channel_count,\n\t\t\t\t      unsigned samples_per_frame,\n\t\t\t\t      unsigned tail_ms,\n\t\t\t\t      unsigned options,\n\t\t\t\t      void **p_state )\n{\n    echo_supp *ec;\n\n    PJ_UNUSED_ARG(channel_count);\n    PJ_UNUSED_ARG(options);\n\n    PJ_ASSERT_RETURN(samples_per_frame >= SEGMENT_PTIME * clock_rate / 1000,\n\t\t     PJ_ENOTSUP);\n\n    ec = PJ_POOL_ZALLOC_T(pool, struct echo_supp);\n    ec->clock_rate = clock_rate;\n    ec->samples_per_frame = (pj_uint16_t)samples_per_frame;\n    ec->samples_per_segment = (pj_uint16_t)(SEGMENT_PTIME * clock_rate / 1000);\n    ec->tail_ms = (pj_uint16_t)tail_ms;\n    ec->tail_samples = (pj_uint16_t)(tail_ms * clock_rate / 1000);\n\n    ec->templ_cnt = TEMPLATE_PTIME / SEGMENT_PTIME;\n    ec->tail_cnt = (pj_uint16_t)(tail_ms / SEGMENT_PTIME);\n    ec->play_hist_cnt = (pj_uint16_t)(ec->tail_cnt+ec->templ_cnt);\n\n    ec->max_calc = (pj_uint16_t)(MAX_CALC_DURATION_SEC * clock_rate /\n\t\t\t\t ec->samples_per_segment);\n\n    ec->rec_hist = (pj_uint16_t*)\n\t\t    pj_pool_alloc(pool, ec->templ_cnt *\n\t\t\t\t\tsizeof(ec->rec_hist[0]));\n\n    /* Note: play history has twice number of elements */\n    ec->play_hist = (pj_uint16_t*)\n\t\t     pj_pool_alloc(pool, ec->play_hist_cnt *\n\t\t\t\t\t sizeof(ec->play_hist[0]));\n\n    ec->corr_sum = (float*)\n\t\t   pj_pool_alloc(pool, ec->tail_cnt *\n\t\t\t\t       sizeof(ec->corr_sum[0]));\n    ec->tmp_corr = (float*)\n\t\t   pj_pool_alloc(pool, ec->tail_cnt *\n\t\t\t\t       sizeof(ec->tmp_corr[0]));\n    ec->min_factor = (float*)\n\t\t     pj_pool_alloc(pool, ec->tail_cnt *\n\t\t\t\t         sizeof(ec->min_factor[0]));\n    ec->avg_factor = (float*)\n\t\t     pj_pool_alloc(pool, ec->tail_cnt *\n\t\t\t\t         sizeof(ec->avg_factor[0]));\n    ec->tmp_factor = (float*)\n\t\t     pj_pool_alloc(pool, ec->tail_cnt *\n\t\t\t\t         sizeof(ec->tmp_factor[0]));\n    echo_supp_reset(ec);\n\n    *p_state = ec;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy.\n */\nPJ_DEF(pj_status_t) echo_supp_destroy(void *state)\n{\n    PJ_UNUSED_ARG(state);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Hard reset\n */\nPJ_DEF(void) echo_supp_reset(void *state)\n{\n    unsigned i;\n    echo_supp *ec = (echo_supp*) state;\n\n    pj_bzero(ec->rec_hist, ec->templ_cnt * sizeof(ec->rec_hist[0]));\n    pj_bzero(ec->play_hist, ec->play_hist_cnt * sizeof(ec->play_hist[0]));\n\n    for (i=0; i<ec->tail_cnt; ++i) {\n\tec->corr_sum[i] = ec->avg_factor[i] = 0;\n\tec->min_factor[i] = MAX_FLOAT;\n    }\n\n    ec->update_cnt = 0;\n    ec->calc_cnt = 0;\n    ec->learning = PJ_TRUE;\n    ec->tail_index = -1;\n    ec->best_corr = MAX_FLOAT;\n    ec->talk_state = ST_NULL;\n    ec->last_factor = 1.0;\n    ec->residue = 0;\n    ec->running_cnt = 0;\n    ec->sum_rec_level = ec->sum_play_level0 = 0;\n    ec->rec_corr = ec->play_corr0 = 0;\n}\n\n/*\n * Soft reset to force the EC to re-learn without having to discard all\n * rec and playback history.\n */\nPJ_DEF(void) echo_supp_soft_reset(void *state)\n{\n    unsigned i;\n\n    echo_supp *ec = (echo_supp*) state;\n\n    for (i=0; i<ec->tail_cnt; ++i) {\n\tec->corr_sum[i] = 0;\n    }\n\n    ec->update_cnt = 0;\n    ec->calc_cnt = 0;\n    ec->learning = PJ_TRUE;\n    ec->best_corr = MAX_FLOAT;\n    ec->residue = 0;\n    ec->running_cnt = 0;\n    ec->sum_rec_level = ec->sum_play_level0 = 0;\n    ec->rec_corr = ec->play_corr0 = 0;\n\n    PJ_LOG(4,(THIS_FILE, \"Echo suppressor soft reset. Re-learning..\"));\n}\n\n\n/* Set state */\nstatic void echo_supp_set_state(echo_supp *ec, talk_state_t state,\n\t\t\t\tunsigned level)\n{\n    PJ_UNUSED_ARG(level);\n\n    if (state != ec->talk_state) {\n\tTRACE_((THIS_FILE, \"[%03d.%03d] %s --> %s, level=%u\",\n\t\t\t   (ec->update_cnt * SEGMENT_PTIME / 1000),\n\t\t\t   ((ec->update_cnt * SEGMENT_PTIME) % 1000),\n\t\t\t   state_names[ec->talk_state],\n\t\t\t   state_names[state], level));\n\tec->talk_state = state;\n    }\n}\n\n/*\n * Update EC state\n */\nstatic void echo_supp_update(echo_supp *ec, pj_int16_t *rec_frm,\n\t\t\t     const pj_int16_t *play_frm)\n{\n    int prev_index;\n    unsigned i, j, frm_level, sum_play_level, ulaw;\n    pj_uint16_t old_rec_frm_level, old_play_frm_level;\n    float play_corr;\n\n    ++ec->update_cnt;\n    if (ec->update_cnt > 0x7FFFFFFF)\n\tec->update_cnt = 0x7FFFFFFF; /* Detect overflow */\n\n    /* Calculate current play frame level */\n    frm_level = pjmedia_calc_avg_signal(play_frm, ec->samples_per_segment);\n    ++frm_level; /* to avoid division by zero */\n\n    /* Save the oldest frame level for later */\n    old_play_frm_level = ec->play_hist[0];\n\n    /* Push current frame level to the back of the play history */\n    pj_array_erase(ec->play_hist, sizeof(pj_uint16_t), ec->play_hist_cnt, 0);\n    ec->play_hist[ec->play_hist_cnt-1] = (pj_uint16_t) frm_level;\n\n    /* Calculate level of current mic frame */\n    frm_level = pjmedia_calc_avg_signal(rec_frm, ec->samples_per_segment);\n    ++frm_level; /* to avoid division by zero */\n\n    /* Save the oldest frame level for later */\n    old_rec_frm_level = ec->rec_hist[0];\n\n    /* Push to the back of the rec history */\n    pj_array_erase(ec->rec_hist, sizeof(pj_uint16_t), ec->templ_cnt, 0);\n    ec->rec_hist[ec->templ_cnt-1] = (pj_uint16_t) frm_level;\n\n\n    /* Can't do the calc until the play history is full. */\n    if (ec->update_cnt < ec->play_hist_cnt)\n\treturn;\n\n    /* Skip if learning is done */\n    if (!ec->learning)\n\treturn;\n\n\n    /* Calculate rec signal pattern */\n    if (ec->sum_rec_level == 0) {\n\t/* Buffer has just been filled up, do full calculation */\n\tec->rec_corr = 0;\n\tec->sum_rec_level = 0;\n\tfor (i=0; i < ec->templ_cnt-1; ++i) {\n\t    float corr;\n\t    corr = (float)ec->rec_hist[i+1] / ec->rec_hist[i];\n\t    ec->rec_corr += corr;\n\t    ec->sum_rec_level += ec->rec_hist[i];\n\t}\n\tec->sum_rec_level += ec->rec_hist[i];\n    } else {\n\t/* Update from previous calculation */\n\tec->sum_rec_level = ec->sum_rec_level - old_rec_frm_level +\n\t\t\t    ec->rec_hist[ec->templ_cnt-1];\n\tec->rec_corr = ec->rec_corr - ((float)ec->rec_hist[0] /\n\t\t\t\t\t      old_rec_frm_level) +\n\t\t       ((float)ec->rec_hist[ec->templ_cnt-1] /\n\t\t\t       ec->rec_hist[ec->templ_cnt-2]);\n    }\n\n    /* Iterate through the play history and calculate the signal correlation\n     * for every tail position in the play_hist. Save the result in temporary\n     * array since we may bail out early if the conversation state is not good\n     * to detect echo.\n     */\n    /*\n     * First phase: do full calculation for the first position\n     */\n    if (ec->sum_play_level0 == 0) {\n\t/* Buffer has just been filled up, do full calculation */\n\tsum_play_level = 0;\n\tplay_corr = 0;\n\tfor (j=0; j<ec->templ_cnt-1; ++j) {\n\t    float corr;\n\t    corr = (float)ec->play_hist[j+1] / ec->play_hist[j];\n\t    play_corr += corr;\n\t    sum_play_level += ec->play_hist[j];\n\t}\n\tsum_play_level += ec->play_hist[j];\n\tec->sum_play_level0 = sum_play_level;\n\tec->play_corr0 = play_corr;\n    } else {\n\t/* Update from previous calculation */\n\tec->sum_play_level0 = ec->sum_play_level0 - old_play_frm_level +\n\t\t\t      ec->play_hist[ec->templ_cnt-1];\n\tec->play_corr0 = ec->play_corr0 - ((float)ec->play_hist[0] /\n\t\t\t\t\t          old_play_frm_level) +\n\t\t         ((float)ec->play_hist[ec->templ_cnt-1] /\n\t\t\t         ec->play_hist[ec->templ_cnt-2]);\n\tsum_play_level = ec->sum_play_level0;\n\tplay_corr = ec->play_corr0;\n    }\n    ec->tmp_corr[0] = FABS(play_corr - ec->rec_corr);\n    ec->tmp_factor[0] = (float)ec->sum_rec_level / sum_play_level;\n\n    /* Bail out if remote isn't talking */\n    ulaw = pjmedia_linear2ulaw(sum_play_level/ec->templ_cnt) ^ 0xFF;\n    if (ulaw < MIN_SIGNAL_ULAW) {\n\techo_supp_set_state(ec, ST_REM_SILENT, ulaw);\n\treturn;\n    }\n    /* Bail out if local user is talking */\n    if (ec->sum_rec_level >= sum_play_level) {\n\techo_supp_set_state(ec, ST_LOCAL_TALK, ulaw);\n\treturn;\n    }\n\n    /*\n     * Second phase: do incremental calculation for the rest of positions\n     */\n    for (i=1; i < ec->tail_cnt; ++i) {\n\tunsigned end;\n\n\tend = i + ec->templ_cnt;\n\n\tsum_play_level = sum_play_level - ec->play_hist[i-1] +\n\t\t\t ec->play_hist[end-1];\n\tplay_corr = play_corr - ((float)ec->play_hist[i]/ec->play_hist[i-1]) +\n\t\t    ((float)ec->play_hist[end-1]/ec->play_hist[end-2]);\n\n\t/* Bail out if remote isn't talking */\n\tulaw = pjmedia_linear2ulaw(sum_play_level/ec->templ_cnt) ^ 0xFF;\n\tif (ulaw < MIN_SIGNAL_ULAW) {\n\t    echo_supp_set_state(ec, ST_REM_SILENT, ulaw);\n\t    return;\n\t}\n\n\t/* Bail out if local user is talking */\n\tif (ec->sum_rec_level >= sum_play_level) {\n\t    echo_supp_set_state(ec, ST_LOCAL_TALK, ulaw);\n\t    return;\n\t}\n\n#if 0\n\t// disabled: not a good idea if mic throws out loud echo\n\t/* Also bail out if we suspect there's a doubletalk */\n\tulaw = pjmedia_linear2ulaw(ec->sum_rec_level/ec->templ_cnt) ^ 0xFF;\n\tif (ulaw > MIN_SIGNAL_ULAW) {\n\t    echo_supp_set_state(ec, ST_DOUBLETALK, ulaw);\n\t    return;\n\t}\n#endif\n\n\t/* Calculate correlation and save to temporary array */\n\tec->tmp_corr[i] = FABS(play_corr - ec->rec_corr);\n\n\t/* Also calculate the gain factor between mic and speaker level */\n\tec->tmp_factor[i] = (float)ec->sum_rec_level / sum_play_level;\n\tpj_assert(ec->tmp_factor[i] < 1);\n    }\n\n    /* We seem to have good signal, we can update the EC state */\n    echo_supp_set_state(ec, ST_REM_TALK, MIN_SIGNAL_ULAW);\n\n    /* Accummulate the correlation value to the history and at the same\n     * time find the tail index of the best correlation.\n     */\n    prev_index = ec->tail_index;\n    for (i=1; i<ec->tail_cnt-1; ++i) {\n\tfloat *p = &ec->corr_sum[i], sum;\n\n\t/* Accummulate correlation value  for this tail position */\n\tec->corr_sum[i] += ec->tmp_corr[i];\n\n\t/* Update the min and avg gain factor for this tail position */\n\tif (ec->tmp_factor[i] < ec->min_factor[i])\n\t    ec->min_factor[i] = ec->tmp_factor[i];\n\tec->avg_factor[i] = ((ec->avg_factor[i] * ec->tail_cnt) +\n\t\t\t\t    ec->tmp_factor[i]) /\n\t\t\t    (ec->tail_cnt + 1);\n\n\t/* To get the best correlation, also include the correlation\n\t * value of the neighbouring tail locations.\n\t */\n\tsum = *(p-1) + (*p)*2 + *(p+1);\n\t//sum = *p;\n\n\t/* See if we have better correlation value */\n\tif (sum < ec->best_corr) {\n\t    ec->tail_index = i;\n\t    ec->best_corr = sum;\n\t}\n    }\n\n    if (ec->tail_index != prev_index) {\n\tunsigned duration;\n\tint imin, iavg;\n\n\tduration = ec->update_cnt * SEGMENT_PTIME;\n\timin = (int)(ec->min_factor[ec->tail_index] * 1000);\n\tiavg = (int)(ec->avg_factor[ec->tail_index] * 1000);\n\n\tPJ_LOG(4,(THIS_FILE,\n\t\t  \"Echo suppressor updated at t=%03d.%03ds, echo tail=%d msec\"\n\t\t  \", factor min/avg=%d.%03d/%d.%03d\",\n\t\t  (duration/1000), (duration%1000),\n\t\t  (ec->tail_cnt-ec->tail_index) * SEGMENT_PTIME,\n\t\t  imin/1000, imin%1000,\n\t\t  iavg/1000, iavg%1000));\n\n    }\n\n    ++ec->calc_cnt;\n\n    if (ec->calc_cnt > ec->max_calc) {\n\tunsigned duration;\n\tint imin, iavg;\n\n\n\tec->learning = PJ_FALSE;\n\tec->running_cnt = 0;\n\n\tduration = ec->update_cnt * SEGMENT_PTIME;\n\timin = (int)(ec->min_factor[ec->tail_index] * 1000);\n\tiavg = (int)(ec->avg_factor[ec->tail_index] * 1000);\n\n\tPJ_LOG(4,(THIS_FILE,\n\t          \"Echo suppressor learning done at t=%03d.%03ds, tail=%d ms\"\n\t\t  \", factor min/avg=%d.%03d/%d.%03d\",\n\t\t  (duration/1000), (duration%1000),\n\t\t  (ec->tail_cnt-ec->tail_index) * SEGMENT_PTIME,\n\t\t  imin/1000, imin%1000,\n\t\t  iavg/1000, iavg%1000));\n    }\n\n}\n\n\n/* Amplify frame */\nstatic void amplify_frame(pj_int16_t *frm, unsigned length,\n\t\t\t  pj_ufloat_t factor)\n{\n    unsigned i;\n\n    for (i=0; i<length; ++i) {\n\tfrm[i] = (pj_int16_t)pj_ufloat_mul_i(frm[i], factor);\n    }\n}\n\n/*\n * Perform echo cancellation.\n */\nPJ_DEF(pj_status_t) echo_supp_cancel_echo( void *state,\n\t\t\t\t\t   pj_int16_t *rec_frm,\n\t\t\t\t\t   const pj_int16_t *play_frm,\n\t\t\t\t\t   unsigned options,\n\t\t\t\t\t   void *reserved )\n{\n    unsigned i, N;\n    echo_supp *ec = (echo_supp*) state;\n\n    PJ_UNUSED_ARG(options);\n    PJ_UNUSED_ARG(reserved);\n\n    /* Calculate number of segments. This should be okay even if\n     * samples_per_frame is not a multiply of samples_per_segment, since\n     * we only calculate level.\n     */\n    N = ec->samples_per_frame / ec->samples_per_segment;\n    pj_assert(N>0);\n    for (i=0; i<N; ++i) {\n\tunsigned pos = i * ec->samples_per_segment;\n\techo_supp_update(ec, rec_frm+pos, play_frm+pos);\n    }\n\n    if (ec->tail_index < 0) {\n\t/* Not ready */\n    } else {\n\tunsigned lookup_cnt, rec_level=0, play_level=0;\n\tunsigned tail_cnt;\n\tfloat factor;\n\n\t/* How many previous segments to lookup */\n\tlookup_cnt = SIGNAL_LOOKUP_MSEC / SEGMENT_PTIME;\n\tif (lookup_cnt > ec->templ_cnt)\n\t    lookup_cnt = ec->templ_cnt;\n\n\t/* Lookup in recording history to get maximum mic level, to see\n\t * if local user is currently talking\n\t */\n\tfor (i=ec->templ_cnt - lookup_cnt; i < ec->templ_cnt; ++i) {\n\t    if (ec->rec_hist[i] > rec_level)\n\t\trec_level = ec->rec_hist[i];\n\t}\n\trec_level = pjmedia_linear2ulaw(rec_level) ^ 0xFF;\n\n\t/* Calculate the detected tail length, in # of segments */\n\ttail_cnt = (ec->tail_cnt - ec->tail_index);\n\n\t/* Lookup in playback history to get max speaker level, to see\n\t * if remote user is currently talking\n\t */\n\tfor (i=ec->play_hist_cnt -lookup_cnt -tail_cnt;\n\t     i<ec->play_hist_cnt-tail_cnt; ++i)\n\t{\n\t    if (ec->play_hist[i] > play_level)\n\t\tplay_level = ec->play_hist[i];\n\t}\n\tplay_level = pjmedia_linear2ulaw(play_level) ^ 0xFF;\n\n\tif (rec_level >= MIN_SIGNAL_ULAW) {\n\t    if (play_level < MIN_SIGNAL_ULAW) {\n\t\t/* Mic is talking, speaker is idle. Let mic signal pass as is.\n\t\t */\n\t\tfactor = 1.0;\n\t\techo_supp_set_state(ec, ST_LOCAL_TALK, rec_level);\n\t    } else if (rec_level > play_level) {\n\t\t/* Seems that both are talking. Scale the mic signal\n\t\t * down a little bit to reduce echo, while allowing both\n\t\t * parties to talk at the same time.\n\t\t */\n\t\tfactor = (float)(ec->avg_factor[ec->tail_index] * 2);\n\t\techo_supp_set_state(ec, ST_DOUBLETALK, rec_level);\n\t    } else {\n\t\t/* Speaker is active, but we've picked up large signal in\n\t\t * the microphone. Assume that this is an echo, so bring\n\t\t * the level down to minimum too.\n\t\t */\n\t\tfactor = ec->min_factor[ec->tail_index] / 2;\n\t\techo_supp_set_state(ec, ST_REM_TALK, play_level);\n\t    }\n\t} else {\n\t    if (play_level < MIN_SIGNAL_ULAW) {\n\t\t/* Both mic and speaker seems to be idle. Also scale the\n\t\t * mic signal down with average factor to reduce low power\n\t\t * echo.\n\t\t */\n\t\tfactor = ec->avg_factor[ec->tail_index] * 3 / 2;\n\t\techo_supp_set_state(ec, ST_REM_SILENT, rec_level);\n\t    } else {\n\t\t/* Mic is idle, but there's something playing in speaker.\n\t\t * Scale the mic down to minimum\n\t\t */\n\t\tfactor = ec->min_factor[ec->tail_index] / 2;\n\t\techo_supp_set_state(ec, ST_REM_TALK, play_level);\n\t    }\n\t}\n\n\t/* Smoothen the transition */\n\tif (factor >= ec->last_factor)\n\t    factor = (factor + ec->last_factor) / 2;\n\telse\n\t    factor = (factor + ec->last_factor*19) / 20;\n\n\t/* Amplify frame */\n\tamplify_frame(rec_frm, ec->samples_per_frame,\n\t\t      pj_ufloat_from_float(factor));\n\tec->last_factor = factor;\n\n\tif (ec->talk_state == ST_REM_TALK) {\n\t    unsigned level, recalc_cnt;\n\n\t    /* Get the adjusted frame signal level */\n\t    level = pjmedia_calc_avg_signal(rec_frm, ec->samples_per_frame);\n\t    level = pjmedia_linear2ulaw(level) ^ 0xFF;\n\n\t    /* Accumulate average echo residue to see the ES effectiveness */\n\t    ec->residue = ((ec->residue * ec->running_cnt) + level) /\n\t\t\t  (ec->running_cnt + 1);\n\n\t    ++ec->running_cnt;\n\n\t    /* Check if we need to re-learn */\n\t    recalc_cnt = CHECK_PERIOD * ec->clock_rate / ec->samples_per_frame;\n\t    if (ec->running_cnt > recalc_cnt) {\n\t\tint iresidue;\n\n\t\tiresidue = (int)(ec->residue*1000);\n\n\t\tPJ_LOG(5,(THIS_FILE, \"Echo suppressor residue = %d.%03d\",\n\t\t\t  iresidue/1000, iresidue%1000));\n\n\t\tif (ec->residue > MAX_RESIDUE && !ec->learning) {\n\t\t    echo_supp_soft_reset(ec);\n\t\t    ec->residue = 0;\n\t\t} else {\n\t\t    ec->running_cnt = 0;\n\t\t    ec->residue = 0;\n\t\t}\n\t    }\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/echo_webrtc_aec.c",
    "content": "/**\n * Copyright (C) 2011-2013 AG Projects\n * Copyright (C) 2010 Regis Montoya (aka r3gis - www.r3gis.fr)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n#include <pjmedia/echo.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/frame.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n\n\n#if defined(PJMEDIA_HAS_WEBRTC_AEC) && PJMEDIA_HAS_WEBRTC_AEC != 0\n\n/* 0: conservative, 1: moderate, 2: aggresive */\n#ifndef PJMEDIA_WEBRTC_AEC_AGGRESSIVENESS\n    #define PJMEDIA_WEBRTC_AEC_AGGRESSIVENESS 2\n#endif\n\n/* 0: mild, 1: mediumn, 2: aggressive */\n#ifndef PJMEDIA_WEBRTC_NS_POLICY\n    #define PJMEDIA_WEBRTC_NS_POLICY 0\n#endif\n\n#define THIS_FILE    \"echo_webrtc_aec.c\"\n\n#include <third_party/webrtc/src/common_audio/signal_processing_library/main/interface/signal_processing_library.h>\n#include <third_party/webrtc/src/modules/audio_processing/aec/main/interface/echo_cancellation.h>\n#include <third_party/webrtc/src/modules/audio_processing/agc/main/interface/gain_control.h>\n#include <third_party/webrtc/src/modules/audio_processing/ns/main/interface/noise_suppression.h>\n\n#include \"echo_internal.h\"\n\n\n/*\n * This file contains the implementation of an echo canceller and noise suppressor for PJSIP which uses components\n * from the WebRTC project. Things to take into account:\n *\n * - The WebRTC engine works with 10ms frames, while in PJSIP we use 20ms frames mostly, all data fed to WebRTC elements needs\n *   to be chunked in 10ms chunks.\n * - When a 32kHz sampling rate is used, the WebRTC engine needs frames to be passed split into low and high frequencies. PJSIP\n *   will give us a frame with all frequencies, so the signal processing library in WebRTC must be used to split frames into low\n *   and high frequencies, and combine them later.\n */\n\n\ntypedef struct AudioBuffer\n{\n    int samples_per_channel;\n    pj_bool_t is_split;\n\n    WebRtc_Word16* data;\n    WebRtc_Word16 low_pass_data[160];\n    WebRtc_Word16 high_pass_data[160];\n\n    WebRtc_Word32 analysis_filter_state1[6];\n    WebRtc_Word32 analysis_filter_state2[6];\n    WebRtc_Word32 synthesis_filter_state1[6];\n    WebRtc_Word32 synthesis_filter_state2[6];\n} AudioBuffer;\n\nstatic WebRtc_Word16* AudioBuffer_GetData(AudioBuffer *ab);\nstatic WebRtc_Word16* AudioBuffer_GetLowPassData(AudioBuffer *ab);\nstatic WebRtc_Word16* AudioBuffer_GetHighPassData(AudioBuffer *ab);\nstatic void AudioBuffer_SetData(AudioBuffer *ab, WebRtc_Word16 *data);\nstatic void AudioBuffer_Initialize(AudioBuffer *ab, int sample_rate);\nstatic int AudioBuffer_SamplesPerChannel(AudioBuffer *ab);\n\n\nstatic WebRtc_Word16* AudioBuffer_GetData(AudioBuffer *ab)\n{\n    pj_assert(ab->data);\n\n    if (ab->is_split) {\n        WebRtcSpl_SynthesisQMF(ab->low_pass_data,\n                               ab->high_pass_data,\n                               ab->data,\n                               ab->synthesis_filter_state1,\n                               ab->synthesis_filter_state2);\n    }\n    return ab->data;\n}\n\n\nstatic WebRtc_Word16* AudioBuffer_GetLowPassData(AudioBuffer *ab)\n{\n    if (!ab->is_split) {\n        return ab->data;\n    } else {\n        return ab->low_pass_data;\n    }\n}\n\n\nstatic WebRtc_Word16* AudioBuffer_GetHighPassData(AudioBuffer *ab)\n{\n    if (!ab->is_split) {\n        return ab->data;\n    } else {\n        return ab->high_pass_data;\n    }\n}\n\n\nstatic void AudioBuffer_Initialize(AudioBuffer *ab, int sample_rate)\n{\n    pj_bzero(ab, sizeof(AudioBuffer));\n    if (sample_rate == 32000) {\n        ab->is_split = PJ_TRUE;\n        ab->samples_per_channel = 160;\n    } else {\n        ab->is_split = PJ_FALSE;\n        ab->samples_per_channel = sample_rate / 100;\n    }\n}\n\n\nstatic void AudioBuffer_SetData(AudioBuffer *ab, WebRtc_Word16 *data)\n{\n    ab->data = data;\n    if (ab->is_split) {\n        /* split data into low and high bands */\n        WebRtcSpl_AnalysisQMF(ab->data,                      /* input data */\n                              ab->low_pass_data,             /* pointer to low pass data storage*/\n                              ab->high_pass_data,            /* pointer to high pass data storage*/\n                              ab->analysis_filter_state1,\n                              ab->analysis_filter_state2);\n    }\n}\n\n\nstatic int AudioBuffer_SamplesPerChannel(AudioBuffer *ab)\n{\n    return ab->samples_per_channel;\n}\n\n\nconst WebRtc_Word16 kFilterCoefficients8kHz[5] =\n    {3798, -7596, 3798, 7807, -3733};\n\nconst WebRtc_Word16 kFilterCoefficients[5] =\n    {4012, -8024, 4012, 8002, -3913};\n\ntypedef struct {\n  WebRtc_Word16 y[4];\n  WebRtc_Word16 x[2];\n  const WebRtc_Word16* ba;\n} HighPassFilterState;\n\n\nstatic int HighPassFilter_Initialize(HighPassFilterState* hpf, int sample_rate) {\n  assert(hpf != NULL);\n\n  if (sample_rate == 8000) {\n    hpf->ba = kFilterCoefficients8kHz;\n  } else {\n    hpf->ba = kFilterCoefficients;\n  }\n\n  WebRtcSpl_MemSetW16(hpf->x, 0, 2);\n  WebRtcSpl_MemSetW16(hpf->y, 0, 4);\n\n  return 0;\n}\n\n\nstatic int HighPassFilter_Process(HighPassFilterState* hpf, WebRtc_Word16* data, int length) {\n  assert(hpf != NULL);\n\n  int i;\n  WebRtc_Word32 tmp_int32 = 0;\n  WebRtc_Word16* y = hpf->y;\n  WebRtc_Word16* x = hpf->x;\n  const WebRtc_Word16* ba = hpf->ba;\n\n  for (i = 0; i < length; i++) {\n    //  y[i] = b[0] * x[i] + b[1] * x[i-1] + b[2] * x[i-2]\n    //         + -a[1] * y[i-1] + -a[2] * y[i-2];\n\n    tmp_int32 = WEBRTC_SPL_MUL_16_16(y[1], ba[3]); // -a[1] * y[i-1] (low part)\n    tmp_int32 += WEBRTC_SPL_MUL_16_16(y[3], ba[4]); // -a[2] * y[i-2] (low part)\n    tmp_int32 = (tmp_int32 >> 15);\n    tmp_int32 += WEBRTC_SPL_MUL_16_16(y[0], ba[3]); // -a[1] * y[i-1] (high part)\n    tmp_int32 += WEBRTC_SPL_MUL_16_16(y[2], ba[4]); // -a[2] * y[i-2] (high part)\n    tmp_int32 = (tmp_int32 << 1);\n\n    tmp_int32 += WEBRTC_SPL_MUL_16_16(data[i], ba[0]); // b[0]*x[0]\n    tmp_int32 += WEBRTC_SPL_MUL_16_16(x[0], ba[1]);    // b[1]*x[i-1]\n    tmp_int32 += WEBRTC_SPL_MUL_16_16(x[1], ba[2]);    // b[2]*x[i-2]\n\n    // Update state (input part)\n    x[1] = x[0];\n    x[0] = data[i];\n\n    // Update state (filtered part)\n    y[2] = y[0];\n    y[3] = y[1];\n    y[0] = (WebRtc_Word16)(tmp_int32 >> 13);\n    y[1] = (WebRtc_Word16)((tmp_int32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)(y[0]), 13)) << 2);\n\n    // Rounding in Q12, i.e. add 2^11\n    tmp_int32 += 2048;\n\n    // Saturate (to 2^27) so that the HP filtered signal does not overflow\n    tmp_int32 = WEBRTC_SPL_SAT((WebRtc_Word32)(134217727), tmp_int32, (WebRtc_Word32)(-134217728));\n\n    // Convert back to Q0 and use rounding\n    data[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp_int32, 12);\n\n  }\n\n  return 0;\n}\n\n\ntypedef struct webrtc_ec\n{\n    void        *AEC_inst;\n    void        *AGC_inst;\n    NsHandle    *NS_inst;\n\n    pj_bool_t   needs_reset;\n    unsigned    skip_frames;\n    unsigned    silence_frames;\n\n    unsigned    clock_rate;\n    unsigned    echo_tail;\n    unsigned    samples_per_frame;\n    unsigned    samples_per_10ms_frame;\n\n    WebRtc_Word32   mic_capture_level;\n    WebRtc_Word16   has_echo;\n    WebRtc_UWord8   is_saturated;\n\n    HighPassFilterState  hpf;\n    AudioBuffer capture_audio_buffer;\n    AudioBuffer playback_audio_buffer;\n\n    pj_int16_t  *tmp_frame;\n    pj_int16_t  *empty_frame;\n} webrtc_ec;\n\n\n#define WEBRTC_AEC_ERROR(aec_inst, tag)                                   \\\n    do {                                                                  \\\n        unsigned status = WebRtcAec_get_error_code(aec_inst);             \\\n        PJ_LOG(4, (THIS_FILE, \"WebRTC AEC ERROR (%s) %d\", tag, status));  \\\n    } while (0)                                                           \\\n\n\n#define WEBRTC_AGC_ERROR(ns_inst, text)                                   \\\n    do {                                                                  \\\n        PJ_LOG(4, (THIS_FILE, \"WebRTC AGC ERROR (%s)\", text));            \\\n    } while (0)                                                           \\\n\n\n#define WEBRTC_NS_ERROR(ns_inst, text)                                    \\\n    do {                                                                  \\\n        PJ_LOG(4, (THIS_FILE, \"WebRTC NS ERROR (%s)\", text));             \\\n    } while (0)                                                           \\\n\n\nPJ_DEF(pj_status_t) webrtc_aec_create(pj_pool_t *pool,\n\t\t\t\t      unsigned clock_rate,\n\t\t\t\t      unsigned channel_count,\n\t\t\t\t      unsigned samples_per_frame,\n\t\t\t\t      unsigned tail_ms,\n\t\t\t\t      unsigned options,\n\t\t\t\t      void **p_echo )\n{\n    webrtc_ec *echo;\n    int status;\n\n    *p_echo = NULL;\n\n    if (clock_rate != 16000 && clock_rate != 32000) {\n        PJ_LOG(4, (THIS_FILE, \"Unsupported sample rate: %d\", clock_rate));\n        return PJ_EINVAL;\n    }\n\n    echo = PJ_POOL_ZALLOC_T(pool, webrtc_ec);\n    PJ_ASSERT_RETURN(echo != NULL, PJ_ENOMEM);\n\n    status = WebRtcAec_Create(&echo->AEC_inst);\n    if(status != 0) {\n        PJ_LOG(4, (THIS_FILE, \"Couldn't allocate memory for WebRTC AEC\"));\n    \tgoto error;\n    }\n\n    status = WebRtcAec_Init(echo->AEC_inst, clock_rate, clock_rate);\n    if(status != 0) {\n        WEBRTC_AEC_ERROR(echo->AEC_inst, \"initialization\");\n    \tgoto error;\n    }\n\n    AecConfig aec_config;\n    aec_config.nlpMode = PJMEDIA_WEBRTC_AEC_AGGRESSIVENESS;\n    aec_config.skewMode = kAecFalse;\n    aec_config.metricsMode = kAecFalse;\n\n    status = WebRtcAec_set_config(echo->AEC_inst, aec_config);\n    if(status != 0) {\n        WEBRTC_AEC_ERROR(echo->AEC_inst, \"config initialization\");\n    \tgoto error;\n    }\n\n    status = WebRtcAgc_Create(&echo->AGC_inst);\n    if(status != 0) {\n        PJ_LOG(4, (THIS_FILE, \"Couldn't allocate memory for WebRTC AGC\"));\n    \tgoto error;\n    }\n\n    status = WebRtcAgc_Init(echo->AGC_inst, 0, 255, kAgcModeAdaptiveAnalog, clock_rate);\n    if(status != 0) {\n        WEBRTC_AGC_ERROR(echo->AGC_inst, \"initialization\");\n    \tgoto error;\n    }\n\n    WebRtcAgc_config_t agc_config;\n    agc_config.targetLevelDbfs = 7;\n    agc_config.compressionGaindB = 0;\n    agc_config.limiterEnable = kAgcFalse;\n\n    status = WebRtcAgc_set_config(echo->AGC_inst, agc_config);\n    if(status != 0) {\n        WEBRTC_AGC_ERROR(echo->AGC_inst, \"config initialization\");\n    \tgoto error;\n    }\n\n    status = WebRtcNs_Create(&echo->NS_inst);\n    if(status != 0) {\n        PJ_LOG(4, (THIS_FILE, \"Couldn't allocate memory for WebRTC NS\"));\n    \tgoto error;\n    }\n\n    status = WebRtcNs_Init(echo->NS_inst, clock_rate);\n    if(status != 0) {\n        WEBRTC_NS_ERROR(echo->NS_inst, \"initialization\");\n        goto error;\n    }\n\n    status = WebRtcNs_set_policy(echo->NS_inst, PJMEDIA_WEBRTC_NS_POLICY);\n    if (status != 0) {\n        WEBRTC_NS_ERROR(echo->NS_inst, \"failed to set policy\");\n    }\n\n    echo->clock_rate = clock_rate;\n    echo->samples_per_frame = samples_per_frame;\n    echo->samples_per_10ms_frame = clock_rate / 100;    /* the WebRTC engine works with 10ms frames */\n    echo->echo_tail = tail_ms;\n    echo->needs_reset = PJ_TRUE;\n    echo->skip_frames = 0;\n    echo->silence_frames = 0;\n    echo->mic_capture_level = 255;    /* initial mic capture level, maximum */\n\n    /* Allocate temporary frames for echo cancellation */\n    echo->tmp_frame = (pj_int16_t*) pj_pool_zalloc(pool, sizeof(pj_int16_t)*samples_per_frame);\n    PJ_ASSERT_RETURN(echo->tmp_frame, PJ_ENOMEM);\n\n    echo->empty_frame = (pj_int16_t*) pj_pool_zalloc(pool, sizeof(pj_int16_t)*samples_per_frame);\n    PJ_ASSERT_RETURN(echo->empty_frame, PJ_ENOMEM);\n\n    /* Initialize audio buffers */\n    AudioBuffer_Initialize(&echo->capture_audio_buffer, clock_rate);\n    AudioBuffer_Initialize(&echo->playback_audio_buffer, clock_rate);\n\n    /* Initialize high pass filter */\n    HighPassFilter_Initialize(&echo->hpf, clock_rate);\n\n    PJ_LOG(4, (THIS_FILE, \"WebRTC AEC and NS initialized\"));\n    *p_echo = echo;\n    return PJ_SUCCESS;\n\nerror:\n    if (echo->AEC_inst)\n        WebRtcAec_Free(echo->AEC_inst);\n    if (echo->AGC_inst)\n        WebRtcAgc_Free(echo->AGC_inst);\n    if (echo->NS_inst)\n        WebRtcNs_Free(echo->NS_inst);\n    return PJ_EBUG;\n}\n\n\nPJ_DEF(pj_status_t) webrtc_aec_destroy(void *state )\n{\n    webrtc_ec *echo = (webrtc_ec*) state;\n    PJ_ASSERT_RETURN(echo, PJ_EINVAL);\n\n    if (echo->AEC_inst) {\n    \tWebRtcAec_Free(echo->AEC_inst);\n    \techo->AEC_inst = NULL;\n    }\n    if (echo->AGC_inst) {\n    \tWebRtcAgc_Free(echo->AGC_inst);\n    \techo->AGC_inst = NULL;\n    }\n    if (echo->NS_inst) {\n        WebRtcNs_Free(echo->NS_inst);\n        echo->NS_inst = NULL;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(void) webrtc_aec_reset(void *state)\n{\n    /* Synchronously reset later, before processing the next frame, to avoid race conditions */\n    ((webrtc_ec*)state)->needs_reset = PJ_TRUE;\n}\n\n\nstatic void aec_reset(webrtc_ec *echo)\n{\n    PJ_ASSERT_ON_FAIL(echo && echo->AEC_inst && echo->AGC_inst && echo->NS_inst, {return;});\n\n    int status = 0;\n\n    /* re-initialize the AEC */\n    status = WebRtcAec_Init(echo->AEC_inst, echo->clock_rate, echo->clock_rate);\n    if(status != 0) {\n        WEBRTC_AEC_ERROR(echo->AEC_inst, \"re-initialization\");\n        return;\n    }\n\n    AecConfig aec_config;\n    aec_config.nlpMode = PJMEDIA_WEBRTC_AEC_AGGRESSIVENESS;\n    aec_config.skewMode = kAecFalse;\n    aec_config.metricsMode = kAecFalse;\n\n    status = WebRtcAec_set_config(echo->AEC_inst, aec_config);\n    if(status != 0) {\n        WEBRTC_AEC_ERROR(echo->AEC_inst, \"configuration re-initialization\");\n        return;\n    }\n\n    /* re-initialize the AGC */\n    status = WebRtcAgc_Init(echo->AGC_inst, 0, 255, kAgcModeAdaptiveAnalog, echo->clock_rate);\n    if(status != 0) {\n        WEBRTC_AGC_ERROR(echo->AGC_inst, \"initialization\");\n    \treturn;\n    }\n\n    WebRtcAgc_config_t agc_config;\n    agc_config.targetLevelDbfs = 7;\n    agc_config.compressionGaindB = 0;\n    agc_config.limiterEnable = kAgcFalse;\n\n    status = WebRtcAgc_set_config(echo->AGC_inst, agc_config);\n    if(status != 0) {\n        WEBRTC_AGC_ERROR(echo->AGC_inst, \"config initialization\");\n    \treturn;\n    }\n\n    /* re-initialize the NS */\n    status = WebRtcNs_Init(echo->NS_inst, echo->clock_rate);\n    if(status != 0) {\n        WEBRTC_NS_ERROR(echo->NS_inst, \"re-initialization\");\n    \treturn;\n    }\n\n    status = WebRtcNs_set_policy(echo->NS_inst, PJMEDIA_WEBRTC_NS_POLICY);\n    if (status != 0) {\n        WEBRTC_NS_ERROR(echo->NS_inst, \"configuration re-initialization\");\n        return;\n    }\n\n    /* re-initialize audio buffers */\n    AudioBuffer_Initialize(&echo->capture_audio_buffer, echo->clock_rate);\n    AudioBuffer_Initialize(&echo->playback_audio_buffer, echo->clock_rate);\n\n    /* re-initialize high pass filter state */\n    HighPassFilter_Initialize(&echo->hpf, echo->clock_rate);\n\n    /* re-initialize mic level */\n    echo->mic_capture_level = 255;\n\n    PJ_LOG(4, (THIS_FILE, \"WebRTC AEC reset succeeded\"));\n}\n\n\n/*\n * Perform echo cancellation.\n */\nPJ_DEF(pj_status_t) webrtc_aec_cancel_echo(void *state,\n\t\t\t\t\t    pj_int16_t *rec_frm,\n\t\t\t\t\t    const pj_int16_t *play_frm,\n\t\t\t\t\t    unsigned options,\n\t\t\t\t\t    void *reserved)\n{\n    webrtc_ec *echo = (webrtc_ec*) state;\n    pj_int16_t *capture_frame, *result_frame;\n    int i, status;\n\n    /* Sanity checks */\n    PJ_ASSERT_RETURN(echo && echo->AEC_inst && echo->AGC_inst && echo->NS_inst, PJ_EINVAL);\n    PJ_ASSERT_RETURN(rec_frm && play_frm && options==0 && reserved==NULL, PJ_EINVAL);\n\n    /* Check if a reset is needed */\n    if (echo->needs_reset) {\n        aec_reset(echo);\n        echo->needs_reset = PJ_FALSE;\n        echo->skip_frames = 15;\n        echo->silence_frames = 10;\n    }\n\n    if (echo->skip_frames) {\n        echo->skip_frames--;\n        capture_frame = echo->empty_frame;\n        result_frame = echo->empty_frame;\n    } else if (echo->silence_frames) {\n        echo->silence_frames--;\n        capture_frame = rec_frm;\n        result_frame = echo->empty_frame;\n    } else {\n        capture_frame = rec_frm;\n        result_frame = echo->tmp_frame;\n    }\n\n    /* Copy record frame to a temporary buffer, in case things go wrong audio will be returned unchanged  */\n    pjmedia_copy_samples(echo->tmp_frame, capture_frame, echo->samples_per_frame);\n\n    for(i=0; i < echo->samples_per_frame; i+= echo->samples_per_10ms_frame) {\n        /* feed a 10ms frame into the audio buffers */\n        AudioBuffer_SetData(&echo->capture_audio_buffer, (WebRtc_Word16 *) (&echo->tmp_frame[i]));\n        AudioBuffer_SetData(&echo->playback_audio_buffer, (WebRtc_Word16 *) (&play_frm[i]));\n\n        /* Apply high pass filer */\n        HighPassFilter_Process(&echo->hpf,\n                               AudioBuffer_GetLowPassData(&echo->capture_audio_buffer),\n                               AudioBuffer_SamplesPerChannel(&echo->capture_audio_buffer));\n\n        /* Analyze capture data gain\n         * NOTE: if we used kAgcModeAdaptiveDigital we'd use WebRtcAgc_VirtualMic instead\n         */\n        status = WebRtcAgc_AddMic(echo->AGC_inst,\n                                  AudioBuffer_GetLowPassData(&echo->capture_audio_buffer),\n                                  AudioBuffer_GetHighPassData(&echo->capture_audio_buffer),\n                                  AudioBuffer_SamplesPerChannel(&echo->capture_audio_buffer));\n        if(status != 0) {\n            WEBRTC_AGC_ERROR(echo->AGC_inst, \"gain analysis\");\n            return PJ_EBUG;\n        }\n\n        /* Feed farend buffer to AGC */\n        status = WebRtcAgc_AddFarend(echo->AGC_inst,\n                                     AudioBuffer_GetLowPassData(&echo->playback_audio_buffer),\n                                     AudioBuffer_SamplesPerChannel(&echo->playback_audio_buffer));\n        if(status != 0) {\n            WEBRTC_AGC_ERROR(echo->AGC_inst, \"farend buffering\");\n            return PJ_EBUG;\n        }\n\n        /* Feed farend buffer to AEC  */\n        status = WebRtcAec_BufferFarend(echo->AEC_inst,\n                                        AudioBuffer_GetLowPassData(&echo->playback_audio_buffer),\n                                        AudioBuffer_SamplesPerChannel(&echo->playback_audio_buffer));\n        if(status != 0) {\n            WEBRTC_AEC_ERROR(echo->AEC_inst, \"farend buffering\");\n            return PJ_EBUG;\n        }\n\n        /* Noise suppression */\n        status = WebRtcNs_Process(echo->NS_inst,\n                                  AudioBuffer_GetLowPassData(&echo->capture_audio_buffer),\n                                  AudioBuffer_GetHighPassData(&echo->capture_audio_buffer),\n                                  AudioBuffer_GetLowPassData(&echo->capture_audio_buffer),\n                                  AudioBuffer_GetHighPassData(&echo->capture_audio_buffer));\n        if (status != 0) {\n            WEBRTC_NS_ERROR(echo->NS_inst, \"ns processing\");\n            return PJ_EBUG;\n        }\n\n        /* Process echo cancellation */\n        status = WebRtcAec_Process(echo->AEC_inst,\n                                   AudioBuffer_GetLowPassData(&echo->capture_audio_buffer),\n                                   AudioBuffer_GetHighPassData(&echo->capture_audio_buffer),\n                                   AudioBuffer_GetLowPassData(&echo->capture_audio_buffer),\n                                   AudioBuffer_GetHighPassData(&echo->capture_audio_buffer),\n                                   AudioBuffer_SamplesPerChannel(&echo->capture_audio_buffer),\n                                   echo->echo_tail,\n                                   0);\n        if(status != 0) {\n            WEBRTC_AEC_ERROR(echo->AEC_inst, \"echo processing\");\n            return PJ_EBUG;\n        }\n\n        WebRtcAec_get_echo_status(echo->AEC_inst, &echo->has_echo);\n#if 0\n        if (echo->has_echo) {\n            PJ_LOG(4, (THIS_FILE, \"Sound might have echo\"));\n        }\n#endif\n\n        /* Process gain control */\n        status = WebRtcAgc_Process(echo->AGC_inst,\n                                   AudioBuffer_GetLowPassData(&echo->capture_audio_buffer),\n                                   AudioBuffer_GetHighPassData(&echo->capture_audio_buffer),\n                                   AudioBuffer_SamplesPerChannel(&echo->capture_audio_buffer),\n                                   AudioBuffer_GetLowPassData(&echo->capture_audio_buffer),\n                                   AudioBuffer_GetHighPassData(&echo->capture_audio_buffer),\n                                   echo->mic_capture_level,\n                                   &echo->mic_capture_level,\n                                   echo->has_echo,\n                                   &echo->is_saturated);\n        if (status != 0) {\n            WEBRTC_AGC_ERROR(echo->AGC_inst, \"agc processing\");\n            return PJ_EBUG;\n        }\n#if 0\n        if (echo->is_saturated) {\n            PJ_LOG(4, (THIS_FILE, \"Sound might be saturated\"));\n        }\n#endif\n\n        /* finish frame processing, in case we are working at 32kHz low and high bands will be combined */\n        AudioBuffer_GetData(&echo->capture_audio_buffer);\n    }\n\n    /* Copy temporary buffer back to original rec_frm */\n    pjmedia_copy_samples(rec_frm, result_frame, echo->samples_per_frame);\n\n    return PJ_SUCCESS;\n\n}\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/endpoint.c",
    "content": "/* $Id: endpoint.c 4474 2013-04-16 09:12:59Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/endpoint.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/sdp.h>\n#include <pjmedia/vid_codec.h>\n#include <pjmedia-audiodev/audiodev.h>\n#include <pj/assert.h>\n#include <pj/ioqueue.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/sock.h>\n#include <pj/string.h>\n\n\n#define THIS_FILE   \"endpoint.c\"\n\nstatic const pj_str_t STR_IN = { \"IN\", 2 };\nstatic const pj_str_t STR_IP4 = { \"IP4\", 3};\nstatic const pj_str_t STR_IP6 = { \"IP6\", 3};\nstatic const pj_str_t STR_RTP_AVP = { \"RTP/AVP\", 7 };\nstatic const pj_str_t STR_SDP_NAME = { \"pjmedia\", 7 };\nstatic const pj_str_t STR_SENDRECV = { \"sendrecv\", 8 };\n\n\n\n/* Config to control rtpmap inclusion for static payload types */\npj_bool_t pjmedia_add_rtpmap_for_static_pt = \n\t    PJMEDIA_ADD_RTPMAP_FOR_STATIC_PT;\n\n/* Config to control use of RFC3890 TIAS */\npj_bool_t pjmedia_add_bandwidth_tias_in_sdp =\n            PJMEDIA_ADD_BANDWIDTH_TIAS_IN_SDP;\n\n\n\n/* Worker thread proc. */\nstatic int PJ_THREAD_FUNC worker_proc(void*);\n\n\n#define MAX_THREADS\t16\n\n\n/* List of media endpoint exit callback. */\ntypedef struct exit_cb\n{\n    PJ_DECL_LIST_MEMBER\t\t    (struct exit_cb);\n    pjmedia_endpt_exit_callback\t    func;\n} exit_cb;\n\n\n/** Concrete declaration of media endpoint. */\nstruct pjmedia_endpt\n{\n    /** Pool. */\n    pj_pool_t\t\t *pool;\n\n    /** Pool factory. */\n    pj_pool_factory\t *pf;\n\n    /** Codec manager. */\n    pjmedia_codec_mgr\t  codec_mgr;\n\n    /** IOqueue instance. */\n    pj_ioqueue_t \t *ioqueue;\n\n    /** Do we own the ioqueue? */\n    pj_bool_t\t\t  own_ioqueue;\n\n    /** Number of threads. */\n    unsigned\t\t  thread_cnt;\n\n    /** IOqueue polling thread, if any. */\n    pj_thread_t\t\t *thread[MAX_THREADS];\n\n    /** To signal polling thread to quit. */\n    pj_bool_t\t\t  quit_flag;\n\n    /** Is telephone-event enable */\n    pj_bool_t\t\t  has_telephone_event;\n\n    /** List of exit callback. */\n    exit_cb\t\t  exit_cb_list;\n};\n\n/**\n * Initialize and get the instance of media endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_endpt_create(pj_pool_factory *pf,\n\t\t\t\t\t pj_ioqueue_t *ioqueue,\n\t\t\t\t\t unsigned worker_cnt,\n\t\t\t\t\t pjmedia_endpt **p_endpt)\n{\n    pj_pool_t *pool;\n    pjmedia_endpt *endpt;\n    unsigned i;\n    pj_status_t status;\n\n    status = pj_register_strerror(PJMEDIA_ERRNO_START, PJ_ERRNO_SPACE_SIZE,\n\t\t\t\t  &pjmedia_strerror);\n    pj_assert(status == PJ_SUCCESS);\n\n    PJ_ASSERT_RETURN(pf && p_endpt, PJ_EINVAL);\n    PJ_ASSERT_RETURN(worker_cnt <= MAX_THREADS, PJ_EINVAL);\n\n    pool = pj_pool_create(pf, \"med-ept\", 512, 512, NULL);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    endpt = PJ_POOL_ZALLOC_T(pool, struct pjmedia_endpt);\n    endpt->pool = pool;\n    endpt->pf = pf;\n    endpt->ioqueue = ioqueue;\n    endpt->thread_cnt = worker_cnt;\n    endpt->has_telephone_event = PJ_TRUE;\n\n    /* Sound */\n    status = pjmedia_aud_subsys_init(pf);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Init codec manager. */\n    status = pjmedia_codec_mgr_init(&endpt->codec_mgr, endpt->pf);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Initialize exit callback list. */\n    pj_list_init(&endpt->exit_cb_list);\n\n    /* Create ioqueue if none is specified. */\n    if (endpt->ioqueue == NULL) {\n\t\n\tendpt->own_ioqueue = PJ_TRUE;\n\n\tstatus = pj_ioqueue_create( endpt->pool, PJ_IOQUEUE_MAX_HANDLES,\n\t\t\t\t    &endpt->ioqueue);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n\tif (worker_cnt == 0) {\n\t    PJ_LOG(4,(THIS_FILE, \"Warning: no worker thread is created in\"  \n\t\t\t\t \"media endpoint for internal ioqueue\"));\n\t}\n    }\n\n    /* Create worker threads if asked. */\n    for (i=0; i<worker_cnt; ++i) {\n\tstatus = pj_thread_create( endpt->pool, \"media\", &worker_proc,\n\t\t\t\t   endpt, 0, 0, &endpt->thread[i]);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n    }\n\n\n    *p_endpt = endpt;\n    return PJ_SUCCESS;\n\non_error:\n\n    /* Destroy threads */\n    for (i=0; i<endpt->thread_cnt; ++i) {\n\tif (endpt->thread[i]) {\n\t    pj_thread_destroy(endpt->thread[i]);\n\t}\n    }\n\n    /* Destroy internal ioqueue */\n    if (endpt->ioqueue && endpt->own_ioqueue)\n\tpj_ioqueue_destroy(endpt->ioqueue);\n\n    pjmedia_codec_mgr_destroy(&endpt->codec_mgr);\n    pjmedia_aud_subsys_shutdown();\n    pj_pool_release(pool);\n    return status;\n}\n\n/**\n * Get the codec manager instance.\n */\nPJ_DEF(pjmedia_codec_mgr*) pjmedia_endpt_get_codec_mgr(pjmedia_endpt *endpt)\n{\n    return &endpt->codec_mgr;\n}\n\n/**\n * Deinitialize media endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_endpt_destroy (pjmedia_endpt *endpt)\n{\n    exit_cb *ecb;\n\n    pjmedia_endpt_stop_threads(endpt);\n\n    /* Destroy internal ioqueue */\n    if (endpt->ioqueue && endpt->own_ioqueue) {\n\tpj_ioqueue_destroy(endpt->ioqueue);\n\tendpt->ioqueue = NULL;\n    }\n\n    endpt->pf = NULL;\n\n    pjmedia_codec_mgr_destroy(&endpt->codec_mgr);\n    pjmedia_aud_subsys_shutdown();\n\n    /* Call all registered exit callbacks */\n    ecb = endpt->exit_cb_list.next;\n    while (ecb != &endpt->exit_cb_list) {\n\t(*ecb->func)(endpt);\n\tecb = ecb->next;\n    }\n\n    pj_pool_release (endpt->pool);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_endpt_set_flag( pjmedia_endpt *endpt,\n\t\t\t\t\t    pjmedia_endpt_flag flag,\n\t\t\t\t\t    const void *value)\n{\n    PJ_ASSERT_RETURN(endpt, PJ_EINVAL);\n\n    switch (flag) {\n    case PJMEDIA_ENDPT_HAS_TELEPHONE_EVENT_FLAG:\n\tendpt->has_telephone_event = *(pj_bool_t*)value;\n\tbreak;\n    default:\n\treturn PJ_EINVAL;\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_endpt_get_flag( pjmedia_endpt *endpt,\n\t\t\t\t\t    pjmedia_endpt_flag flag,\n\t\t\t\t\t    void *value)\n{\n    PJ_ASSERT_RETURN(endpt, PJ_EINVAL);\n\n    switch (flag) {\n    case PJMEDIA_ENDPT_HAS_TELEPHONE_EVENT_FLAG:\n\t*(pj_bool_t*)value = endpt->has_telephone_event;\n\tbreak;\n    default:\n\treturn PJ_EINVAL;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/**\n * Get the ioqueue instance of the media endpoint.\n */\nPJ_DEF(pj_ioqueue_t*) pjmedia_endpt_get_ioqueue(pjmedia_endpt *endpt)\n{\n    PJ_ASSERT_RETURN(endpt, NULL);\n    return endpt->ioqueue;\n}\n\n/**\n * Get the number of worker threads in media endpoint.\n */\nPJ_DEF(unsigned) pjmedia_endpt_get_thread_count(pjmedia_endpt *endpt)\n{\n    PJ_ASSERT_RETURN(endpt, 0);\n    return endpt->thread_cnt;\n}\n\n/**\n * Get a reference to one of the worker threads of the media endpoint \n */\nPJ_DEF(pj_thread_t*) pjmedia_endpt_get_thread(pjmedia_endpt *endpt, \n\t\t\t\t\t      unsigned index)\n{\n    PJ_ASSERT_RETURN(endpt, NULL);\n    PJ_ASSERT_RETURN(index < endpt->thread_cnt, NULL);\n\n    /* here should be an assert on index >= 0 < endpt->thread_cnt */\n\n    return endpt->thread[index];\n}\n\n/**\n * Stop and destroy the worker threads of the media endpoint\n */\nPJ_DEF(pj_status_t) pjmedia_endpt_stop_threads(pjmedia_endpt *endpt)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(endpt, PJ_EINVAL);\n\n    endpt->quit_flag = 1;\n\n    /* Destroy threads */\n    for (i=0; i<endpt->thread_cnt; ++i) {\n\tif (endpt->thread[i]) {\n\t    pj_thread_join(endpt->thread[i]);\n\t    pj_thread_destroy(endpt->thread[i]);\n\t    endpt->thread[i] = NULL;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n/**\n * Worker thread proc.\n */\nstatic int PJ_THREAD_FUNC worker_proc(void *arg)\n{\n    pjmedia_endpt *endpt = (pjmedia_endpt*) arg;\n\n    while (!endpt->quit_flag) {\n\tpj_time_val timeout = { 0, 500 };\n\tpj_ioqueue_poll(endpt->ioqueue, &timeout);\n    }\n\n    return 0;\n}\n\n/**\n * Create pool.\n */\nPJ_DEF(pj_pool_t*) pjmedia_endpt_create_pool( pjmedia_endpt *endpt,\n\t\t\t\t\t      const char *name,\n\t\t\t\t\t      pj_size_t initial,\n\t\t\t\t\t      pj_size_t increment)\n{\n    pj_assert(endpt != NULL);\n\n    return pj_pool_create(endpt->pf, name, initial, increment, NULL);\n}\n\n/* Common initialization for both audio and video SDP media line */\nstatic pj_status_t init_sdp_media(pjmedia_sdp_media *m,\n                                  pj_pool_t *pool,\n                                  const pj_str_t *media_type,\n\t\t\t\t  const pjmedia_sock_info *sock_info)\n{\n    char tmp_addr[PJ_INET6_ADDRSTRLEN];\n    pjmedia_sdp_attr *attr;\n    const pj_sockaddr *addr;\n\n    pj_strdup(pool, &m->desc.media, media_type);\n\n    addr = &sock_info->rtp_addr_name;\n\n    /* Validate address family */\n    PJ_ASSERT_RETURN(addr->addr.sa_family == pj_AF_INET() ||\n                     addr->addr.sa_family == pj_AF_INET6(),\n                     PJ_EAFNOTSUP);\n\n    /* SDP connection line */\n    m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);\n    m->conn->net_type = STR_IN;\n    m->conn->addr_type = (addr->addr.sa_family==pj_AF_INET())? STR_IP4:STR_IP6;\n    pj_sockaddr_print(addr, tmp_addr, sizeof(tmp_addr), 0);\n    pj_strdup2(pool, &m->conn->addr, tmp_addr);\n\n    /* Port and transport in media description */\n    m->desc.port = pj_sockaddr_get_port(addr);\n    m->desc.port_count = 1;\n    pj_strdup (pool, &m->desc.transport, &STR_RTP_AVP);\n\n    /* Add \"rtcp\" attribute */\n#if defined(PJMEDIA_HAS_RTCP_IN_SDP) && PJMEDIA_HAS_RTCP_IN_SDP!=0\n    if (sock_info->rtcp_addr_name.addr.sa_family != 0) {\n\tattr = pjmedia_sdp_attr_create_rtcp(pool, &sock_info->rtcp_addr_name);\n\tif (attr)\n\t    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);\n    }\n#endif\n\n    /* Add sendrecv attribute. */\n    attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);\n    attr->name = STR_SENDRECV;\n    m->attr[m->attr_count++] = attr;\n\n    return PJ_SUCCESS;\n}\n\n/* Create m=audio SDP media line */\nPJ_DEF(pj_status_t) pjmedia_endpt_create_audio_sdp(pjmedia_endpt *endpt,\n                                                   pj_pool_t *pool,\n                                                   const pjmedia_sock_info *si,\n                                                   unsigned options,\n                                                   pjmedia_sdp_media **p_m)\n{\n    const pj_str_t STR_AUDIO = { \"audio\", 5 };\n    pjmedia_sdp_media *m;\n    pjmedia_sdp_attr *attr;\n    unsigned i;\n    unsigned max_bitrate = 0;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(options);\n\n    /* Check that there are not too many codecs */\n    PJ_ASSERT_RETURN(endpt->codec_mgr.codec_cnt <= PJMEDIA_MAX_SDP_FMT,\n\t\t     PJ_ETOOMANY);\n\n    /* Create and init basic SDP media */\n    m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media);\n    status = init_sdp_media(m, pool, &STR_AUDIO, si);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Add format, rtpmap, and fmtp (when applicable) for each codec */\n    for (i=0; i<endpt->codec_mgr.codec_cnt; ++i) {\n\n\tpjmedia_codec_info *codec_info;\n\tpjmedia_sdp_rtpmap rtpmap;\n\tchar tmp_param[3];\n\tpjmedia_codec_param codec_param;\n\tpj_str_t *fmt;\n\n\tif (endpt->codec_mgr.codec_desc[i].prio == PJMEDIA_CODEC_PRIO_DISABLED)\n\t    break;\n\n\tcodec_info = &endpt->codec_mgr.codec_desc[i].info;\n\tpjmedia_codec_mgr_get_default_param(&endpt->codec_mgr, codec_info,\n\t\t\t\t\t    &codec_param);\n\tfmt = &m->desc.fmt[m->desc.fmt_count++];\n\n\tfmt->ptr = (char*) pj_pool_alloc(pool, 8);\n\tfmt->slen = pj_utoa(codec_info->pt, fmt->ptr);\n\n\trtpmap.pt = *fmt;\n\trtpmap.enc_name = codec_info->encoding_name;\n\n#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG != 0)\n\tif (codec_info->pt == PJMEDIA_RTP_PT_G722)\n\t    rtpmap.clock_rate = 8000;\n\telse\n\t    rtpmap.clock_rate = codec_info->clock_rate;\n#else\n\trtpmap.clock_rate = codec_info->clock_rate;\n#endif\n\n\t/* For audio codecs, rtpmap parameters denotes the number\n\t * of channels, which can be omited if the value is 1.\n\t */\n\tif (codec_info->type == PJMEDIA_TYPE_AUDIO &&\n\t    codec_info->channel_cnt > 1)\n\t{\n\t    /* Can only support one digit channel count */\n\t    pj_assert(codec_info->channel_cnt < 10);\n\n\t    tmp_param[0] = (char)('0' + codec_info->channel_cnt);\n\n\t    rtpmap.param.ptr = tmp_param;\n\t    rtpmap.param.slen = 1;\n\n\t} else {\n\t    rtpmap.param.ptr = \"\";\n\t    rtpmap.param.slen = 0;\n\t}\n\n\tif (codec_info->pt >= 96 || pjmedia_add_rtpmap_for_static_pt) {\n\t    pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);\n\t    m->attr[m->attr_count++] = attr;\n\t}\n\n\t/* Add fmtp params */\n\tif (codec_param.setting.dec_fmtp.cnt > 0) {\n\t    enum { MAX_FMTP_STR_LEN = 160 };\n\t    char buf[MAX_FMTP_STR_LEN];\n\t    unsigned buf_len = 0, ii;\n\t    pjmedia_codec_fmtp *dec_fmtp = &codec_param.setting.dec_fmtp;\n\n\t    /* Print codec PT */\n\t    buf_len += pj_ansi_snprintf(buf,\n\t\t\t\t\tMAX_FMTP_STR_LEN - buf_len,\n\t\t\t\t\t\"%d\",\n\t\t\t\t\tcodec_info->pt);\n\n\t    for (ii = 0; ii < dec_fmtp->cnt; ++ii) {\n\t\tpj_size_t test_len = 2;\n\n\t\t/* Check if buf still available */\n\t\ttest_len = dec_fmtp->param[ii].val.slen + \n\t\t\t   dec_fmtp->param[ii].name.slen + 2;\n\t\tif (test_len + buf_len >= MAX_FMTP_STR_LEN)\n\t\t    return PJ_ETOOBIG;\n\n\t\t/* Print delimiter */\n\t\tbuf_len += pj_ansi_snprintf(&buf[buf_len], \n\t\t\t\t\t    MAX_FMTP_STR_LEN - buf_len,\n\t\t\t\t\t    (ii == 0?\" \":\";\"));\n\n\t\t/* Print an fmtp param */\n\t\tif (dec_fmtp->param[ii].name.slen)\n\t\t    buf_len += pj_ansi_snprintf(\n\t\t\t\t\t    &buf[buf_len],\n\t\t\t\t\t    MAX_FMTP_STR_LEN - buf_len,\n\t\t\t\t\t    \"%.*s=%.*s\",\n\t\t\t\t\t    (int)dec_fmtp->param[ii].name.slen,\n\t\t\t\t\t    dec_fmtp->param[ii].name.ptr,\n\t\t\t\t\t    (int)dec_fmtp->param[ii].val.slen,\n\t\t\t\t\t    dec_fmtp->param[ii].val.ptr);\n\t\telse\n\t\t    buf_len += pj_ansi_snprintf(&buf[buf_len], \n\t\t\t\t\t    MAX_FMTP_STR_LEN - buf_len,\n\t\t\t\t\t    \"%.*s\", \n\t\t\t\t\t    (int)dec_fmtp->param[ii].val.slen,\n\t\t\t\t\t    dec_fmtp->param[ii].val.ptr);\n\t    }\n\n\t    attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);\n\n\t    attr->name = pj_str(\"fmtp\");\n\t    attr->value = pj_strdup3(pool, buf);\n\t    m->attr[m->attr_count++] = attr;\n\t}\n\n\t/* Find maximum bitrate in this media */\n\tif (max_bitrate < codec_param.info.max_bps)\n\t    max_bitrate = codec_param.info.max_bps;\n    }\n\n#if defined(PJMEDIA_RTP_PT_TELEPHONE_EVENTS) && \\\n    PJMEDIA_RTP_PT_TELEPHONE_EVENTS != 0\n    /*\n     * Add support telephony event\n     */\n    if (endpt->has_telephone_event) {\n\tm->desc.fmt[m->desc.fmt_count++] =\n\t    pj_str(PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR);\n\n\t/* Add rtpmap. */\n\tattr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);\n\tattr->name = pj_str(\"rtpmap\");\n\tattr->value = pj_str(PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR\n\t\t\t     \" telephone-event/8000\");\n\tm->attr[m->attr_count++] = attr;\n\n\t/* Add fmtp */\n\tattr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);\n\tattr->name = pj_str(\"fmtp\");\n#if defined(PJMEDIA_HAS_DTMF_FLASH) && PJMEDIA_HAS_DTMF_FLASH!= 0\n\tattr->value = pj_str(PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR \" 0-16\");\n#else\n\tattr->value = pj_str(PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR \" 0-15\");\n#endif\n\tm->attr[m->attr_count++] = attr;\n    }\n#endif\n\n    /* Put bandwidth info in media level using bandwidth modifier \"TIAS\"\n     * (RFC3890).\n     */\n#if 0\n    if (max_bitrate && pjmedia_add_bandwidth_tias_in_sdp) {\n\tconst pj_str_t STR_BANDW_MODIFIER = { \"TIAS\", 4 };\n\tpjmedia_sdp_bandw *b;\n\t    \n\tb = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_bandw);\n\tb->modifier = STR_BANDW_MODIFIER;\n\tb->value = max_bitrate;\n\tm->bandw[m->bandw_count++] = b;\n    }\n#endif\n\n    *p_m = m;\n    return PJ_SUCCESS;\n}\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n/* Create m=video SDP media line */\nPJ_DEF(pj_status_t) pjmedia_endpt_create_video_sdp(pjmedia_endpt *endpt,\n                                                   pj_pool_t *pool,\n                                                   const pjmedia_sock_info *si,\n                                                   unsigned options,\n                                                   pjmedia_sdp_media **p_m)\n{\n\n\n    const pj_str_t STR_VIDEO = { \"video\", 5 };\n    pjmedia_sdp_media *m;\n    pjmedia_vid_codec_info codec_info[PJMEDIA_VID_CODEC_MGR_MAX_CODECS];\n    unsigned codec_prio[PJMEDIA_VID_CODEC_MGR_MAX_CODECS];\n    pjmedia_sdp_attr *attr;\n    unsigned cnt, i;\n    unsigned max_bitrate = 0;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(options);\n\n    /* Make sure video codec manager is instantiated */\n    if (!pjmedia_vid_codec_mgr_instance())\n\tpjmedia_vid_codec_mgr_create(endpt->pool, NULL);\n\n    /* Create and init basic SDP media */\n    m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media);\n    status = init_sdp_media(m, pool, &STR_VIDEO, si);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    cnt = PJ_ARRAY_SIZE(codec_info);\n    status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &cnt, \n\t\t\t\t\t       codec_info, codec_prio);\n\n    /* Check that there are not too many codecs */\n    PJ_ASSERT_RETURN(0 <= PJMEDIA_MAX_SDP_FMT,\n\t\t     PJ_ETOOMANY);\n\n    /* Add format, rtpmap, and fmtp (when applicable) for each codec */\n    for (i=0; i<cnt; ++i) {\n\tpjmedia_sdp_rtpmap rtpmap;\n\tpjmedia_vid_codec_param codec_param;\n\tpj_str_t *fmt;\n\tpjmedia_video_format_detail *vfd;\n\n\tpj_bzero(&rtpmap, sizeof(rtpmap));\n\n\tif (codec_prio[i] == PJMEDIA_CODEC_PRIO_DISABLED)\n\t    break;\n\n\tif (i > PJMEDIA_MAX_SDP_FMT) {\n\t    /* Too many codecs, perhaps it is better to tell application by\n\t     * returning appropriate status code.\n\t     */\n\t    PJ_PERROR(3,(THIS_FILE, PJ_ETOOMANY,\n\t\t\t\"Skipping some video codecs\"));\n\t    break;\n\t}\n\n\t/* Must support RTP packetization and bidirectional */\n\tif ((codec_info[i].packings & PJMEDIA_VID_PACKING_PACKETS) == 0 ||\n\t    codec_info[i].dir != PJMEDIA_DIR_ENCODING_DECODING)\n\t{\n\t    continue;\n\t}\n\n\tpjmedia_vid_codec_mgr_get_default_param(NULL, &codec_info[i],\n\t\t\t\t\t\t&codec_param);\n\n\tfmt = &m->desc.fmt[m->desc.fmt_count++];\n\tfmt->ptr = (char*) pj_pool_alloc(pool, 8);\n\tfmt->slen = pj_utoa(codec_info[i].pt, fmt->ptr);\n\trtpmap.pt = *fmt;\n\n\t/* Encoding name */\n\trtpmap.enc_name = codec_info[i].encoding_name;\n\n\t/* Clock rate */\n\trtpmap.clock_rate = codec_info[i].clock_rate;\n\n\tif (codec_info[i].pt >= 96 || pjmedia_add_rtpmap_for_static_pt) {\n\t    pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);\n\t    m->attr[m->attr_count++] = attr;\n\t}\n\n\t/* Add fmtp params */\n\tif (codec_param.dec_fmtp.cnt > 0) {\n\t    enum { MAX_FMTP_STR_LEN = 160 };\n\t    char buf[MAX_FMTP_STR_LEN];\n\t    unsigned buf_len = 0, j;\n\t    pjmedia_codec_fmtp *dec_fmtp = &codec_param.dec_fmtp;\n\n\t    /* Print codec PT */\n\t    buf_len += pj_ansi_snprintf(buf, \n\t\t\t\t\tMAX_FMTP_STR_LEN - buf_len, \n\t\t\t\t\t\"%d\", \n\t\t\t\t\tcodec_info[i].pt);\n\n\t    for (j = 0; j < dec_fmtp->cnt; ++j) {\n\t\tpj_size_t test_len = 2;\n\n\t\t/* Check if buf still available */\n\t\ttest_len = dec_fmtp->param[j].val.slen + \n\t\t\t   dec_fmtp->param[j].name.slen + 2;\n\t\tif (test_len + buf_len >= MAX_FMTP_STR_LEN)\n\t\t    return PJ_ETOOBIG;\n\n\t\t/* Print delimiter */\n\t\tbuf_len += pj_ansi_snprintf(&buf[buf_len], \n\t\t\t\t\t    MAX_FMTP_STR_LEN - buf_len,\n\t\t\t\t\t    (j == 0?\" \":\";\"));\n\n\t\t/* Print an fmtp param */\n\t\tif (dec_fmtp->param[j].name.slen)\n\t\t    buf_len += pj_ansi_snprintf(\n\t\t\t\t\t    &buf[buf_len],\n\t\t\t\t\t    MAX_FMTP_STR_LEN - buf_len,\n\t\t\t\t\t    \"%.*s=%.*s\",\n\t\t\t\t\t    (int)dec_fmtp->param[j].name.slen,\n\t\t\t\t\t    dec_fmtp->param[j].name.ptr,\n\t\t\t\t\t    (int)dec_fmtp->param[j].val.slen,\n\t\t\t\t\t    dec_fmtp->param[j].val.ptr);\n\t\telse\n\t\t    buf_len += pj_ansi_snprintf(&buf[buf_len], \n\t\t\t\t\t    MAX_FMTP_STR_LEN - buf_len,\n\t\t\t\t\t    \"%.*s\", \n\t\t\t\t\t    (int)dec_fmtp->param[j].val.slen,\n\t\t\t\t\t    dec_fmtp->param[j].val.ptr);\n\t    }\n\n\t    attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);\n\n\t    attr->name = pj_str(\"fmtp\");\n\t    attr->value = pj_strdup3(pool, buf);\n\t    m->attr[m->attr_count++] = attr;\n\t}\n    \n\t/* Find maximum bitrate in this media */\n\tvfd = pjmedia_format_get_video_format_detail(&codec_param.enc_fmt,\n\t\t\t\t\t\t     PJ_TRUE);\n\tif (vfd && max_bitrate < vfd->max_bps)\n\t    max_bitrate = vfd->max_bps;\n    }\n\n    /* Put bandwidth info in media level using bandwidth modifier \"TIAS\"\n     * (RFC3890).\n     */\n    if (max_bitrate && pjmedia_add_bandwidth_tias_in_sdp) {\n\tconst pj_str_t STR_BANDW_MODIFIER = { \"TIAS\", 4 };\n\tpjmedia_sdp_bandw *b;\n\t    \n\tb = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_bandw);\n\tb->modifier = STR_BANDW_MODIFIER;\n\tb->value = max_bitrate;\n\tm->bandw[m->bandw_count++] = b;\n    }\n\n    *p_m = m;\n    return PJ_SUCCESS;\n}\n\n#endif /* PJMEDIA_HAS_VIDEO */\n\n\n/**\n * Create a \"blank\" SDP session description. The SDP will contain basic SDP\n * fields such as origin, time, and name, but without any media lines.\n */\nPJ_DEF(pj_status_t) pjmedia_endpt_create_base_sdp( pjmedia_endpt *endpt,\n\t\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t\t   const pj_str_t *sess_name,\n\t\t\t\t\t\t   const pj_sockaddr *origin,\n\t\t\t\t\t\t   pjmedia_sdp_session **p_sdp)\n{\n    pj_time_val tv;\n    pjmedia_sdp_session *sdp;\n\n    /* Sanity check arguments */\n    PJ_ASSERT_RETURN(endpt && pool && p_sdp, PJ_EINVAL);\n\n    sdp = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_session);\n\n    pj_gettimeofday(&tv);\n    sdp->origin.user = pj_str(\"-\");\n    sdp->origin.version = sdp->origin.id = tv.sec + 2208988800UL;\n    sdp->origin.net_type = STR_IN;\n\n    if (origin->addr.sa_family == pj_AF_INET()) {\n \tsdp->origin.addr_type = STR_IP4;\n \tpj_strdup2(pool, &sdp->origin.addr,\n \t\t   pj_inet_ntoa(origin->ipv4.sin_addr));\n    } else if (origin->addr.sa_family == pj_AF_INET6()) {\n \tchar tmp_addr[PJ_INET6_ADDRSTRLEN];\n\n \tsdp->origin.addr_type = STR_IP6;\n \tpj_strdup2(pool, &sdp->origin.addr,\n \t\t   pj_sockaddr_print(origin, tmp_addr, sizeof(tmp_addr), 0));\n\n    } else {\n \tpj_assert(!\"Invalid address family\");\n \treturn PJ_EAFNOTSUP;\n    }\n\n    if (sess_name)\n\tpj_strdup(pool, &sdp->name, sess_name);\n    else\n\tsdp->name = STR_SDP_NAME;\n\n    /* SDP time and attributes. */\n    sdp->time.start = sdp->time.stop = 0;\n    sdp->attr_count = 0;\n\n    /* Done */\n    *p_sdp = sdp;\n\n    return PJ_SUCCESS;\n}\n\n/**\n * Create a SDP session description that describes the endpoint\n * capability.\n */\nPJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      unsigned stream_cnt,\n\t\t\t\t\t      const pjmedia_sock_info sock_info[],\n\t\t\t\t\t      pjmedia_sdp_session **p_sdp )\n{\n    const pj_sockaddr *addr0;\n    pjmedia_sdp_session *sdp;\n    pjmedia_sdp_media *m;\n    pj_status_t status;\n\n    /* Sanity check arguments */\n    PJ_ASSERT_RETURN(endpt && pool && p_sdp && stream_cnt, PJ_EINVAL);\n    PJ_ASSERT_RETURN(stream_cnt < PJMEDIA_MAX_SDP_MEDIA, PJ_ETOOMANY);\n\n    addr0 = &sock_info[0].rtp_addr_name;\n\n    /* Create and initialize basic SDP session */\n    status = pjmedia_endpt_create_base_sdp(endpt, pool, NULL, addr0, &sdp);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Audio is first, by convention */\n    status = pjmedia_endpt_create_audio_sdp(endpt, pool,\n                                            &sock_info[0], 0, &m);\n    if (status != PJ_SUCCESS)\n\treturn status;\n    sdp->media[sdp->media_count++] = m;\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n    {\n\tunsigned i;\n\n\t/* The remaining stream, if any, are videos (by convention as well) */\n\tfor (i=1; i<stream_cnt; ++i) {\n\t    status = pjmedia_endpt_create_video_sdp(endpt, pool,\n\t\t\t\t\t\t    &sock_info[i], 0, &m);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\t    sdp->media[sdp->media_count++] = m;\n\t}\n    }\n#endif\n\n    /* Done */\n    *p_sdp = sdp;\n\n    return PJ_SUCCESS;\n}\n\n\n\n#if PJ_LOG_MAX_LEVEL >= 3\nstatic const char *good_number(char *buf, pj_int32_t val)\n{\n    if (val < 1000) {\n\tpj_ansi_sprintf(buf, \"%d\", val);\n    } else if (val < 1000000) {\n\tpj_ansi_sprintf(buf, \"%d.%dK\", \n\t\t\tval / 1000,\n\t\t\t(val % 1000) / 100);\n    } else {\n\tpj_ansi_sprintf(buf, \"%d.%02dM\", \n\t\t\tval / 1000000,\n\t\t\t(val % 1000000) / 10000);\n    }\n\n    return buf;\n}\n#endif\n\nPJ_DEF(pj_status_t) pjmedia_endpt_dump(pjmedia_endpt *endpt)\n{\n\n#if PJ_LOG_MAX_LEVEL >= 3\n    unsigned i, count;\n    pjmedia_codec_info codec_info[32];\n    unsigned prio[32];\n\n    PJ_LOG(3,(THIS_FILE, \"Dumping PJMEDIA capabilities:\"));\n\n    count = PJ_ARRAY_SIZE(codec_info);\n    if (pjmedia_codec_mgr_enum_codecs(&endpt->codec_mgr, \n\t\t\t\t      &count, codec_info, prio) != PJ_SUCCESS)\n    {\n\tPJ_LOG(3,(THIS_FILE, \" -error: failed to enum codecs\"));\n\treturn PJ_SUCCESS;\n    }\n\n    PJ_LOG(3,(THIS_FILE, \"  Total number of installed codecs: %d\", count));\n    for (i=0; i<count; ++i) {\n\tconst char *type;\n\tpjmedia_codec_param param;\n\tchar bps[32];\n\n\tswitch (codec_info[i].type) {\n\tcase PJMEDIA_TYPE_AUDIO:\n\t    type = \"Audio\"; break;\n\tcase PJMEDIA_TYPE_VIDEO:\n\t    type = \"Video\"; break;\n\tdefault:\n\t    type = \"Unknown type\"; break;\n\t}\n\n\tif (pjmedia_codec_mgr_get_default_param(&endpt->codec_mgr,\n\t\t\t\t\t\t&codec_info[i],\n\t\t\t\t\t\t&param) != PJ_SUCCESS)\n\t{\n\t    pj_bzero(&param, sizeof(pjmedia_codec_param));\n\t}\n\n\tPJ_LOG(3,(THIS_FILE, \n\t\t  \"   %s codec #%2d: pt=%d (%.*s @%dKHz/%d, %sbps, %dms%s%s%s%s%s)\",\n\t\t  type, i, codec_info[i].pt,\n\t\t  (int)codec_info[i].encoding_name.slen,\n\t\t  codec_info[i].encoding_name.ptr,\n\t\t  codec_info[i].clock_rate/1000,\n\t\t  codec_info[i].channel_cnt,\n\t\t  good_number(bps, param.info.avg_bps), \n\t\t  param.info.frm_ptime * param.setting.frm_per_pkt,\n\t\t  (param.setting.vad ? \" vad\" : \"\"),\n\t\t  (param.setting.cng ? \" cng\" : \"\"),\n\t\t  (param.setting.plc ? \" plc\" : \"\"),\n\t\t  (param.setting.penh ? \" penh\" : \"\"),\n\t\t  (prio[i]==PJMEDIA_CODEC_PRIO_DISABLED?\" disabled\":\"\")));\n    }\n#endif\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_endpt_atexit( pjmedia_endpt *endpt,\n\t\t\t\t\t  pjmedia_endpt_exit_callback func)\n{\n    exit_cb *new_cb;\n\n    PJ_ASSERT_RETURN(endpt && func, PJ_EINVAL);\n\n    if (endpt->quit_flag)\n\treturn PJ_EINVALIDOP;\n\n    new_cb = PJ_POOL_ZALLOC_T(endpt->pool, exit_cb);\n    new_cb->func = func;\n\n    pj_enter_critical_section();\n    pj_list_push_back(&endpt->exit_cb_list, new_cb);\n    pj_leave_critical_section();\n\n    return PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/errno.c",
    "content": "/* $Id: errno.c 3945 2012-01-27 09:12:59Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/errno.h>\n#include <pjmedia/types.h>\n#include <pj/string.h>\n\n#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)\nPJ_BEGIN_DECL\n    const char* get_libsrtp_errstr(int err);\nPJ_END_DECL\n#endif\n\n\n/* PJMEDIA's own error codes/messages \n * MUST KEEP THIS ARRAY SORTED!!\n * Message must be limited to 64 chars!\n */\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n\nstatic const struct \n{\n    int code;\n    const char *msg;\n} err_str[] = \n{\n    /* Generic PJMEDIA errors, shouldn't be used! */\n    PJ_BUILD_ERR( PJMEDIA_ERROR,\t    \"Unspecified PJMEDIA error\" ),\n\n    /* SDP error. */\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINSDP,\t    \"Invalid SDP descriptor\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINVER,\t    \"Invalid SDP version line\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINORIGIN,    \"Invalid SDP origin line\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINTIME,\t    \"Invalid SDP time line\"),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINNAME,\t    \"SDP name/subject line is empty\"),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINCONN,\t    \"Invalid SDP connection line\"),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EMISSINGCONN, \"Missing SDP connection info line\"),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINATTR,\t    \"Invalid SDP attributes\"),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINRTPMAP,    \"Invalid SDP rtpmap attribute\"),\n    PJ_BUILD_ERR( PJMEDIA_SDP_ERTPMAPTOOLONG,\"SDP rtpmap attribute too long\"),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EMISSINGRTPMAP,\"Missing SDP rtpmap for dynamic payload type\"),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINMEDIA,\t    \"Invalid SDP media line\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_ENOFMT,\t    \"No SDP payload format in the media line\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINPT,\t    \"Invalid SDP payload type in media line\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINFMTP,\t    \"Invalid SDP fmtp attribute\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINRTCP,\t    \"Invalid SDP rtcp attribyte\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINPROTO,\t    \"Invalid SDP media transport protocol\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EINBANDW,\t    \"Invalid SDP bandwidth info line\" ),\n\n    /* SDP negotiator errors. */\n    PJ_BUILD_ERR( PJMEDIA_SDPNEG_EINSTATE,\t\"Invalid SDP negotiator state for operation\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDPNEG_ENOINITIAL,\t\"No initial local SDP in SDP negotiator\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDPNEG_ENOACTIVE,\t\"No active SDP in SDP negotiator\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDPNEG_ENONEG,\t\"No current local/remote offer/answer\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDPNEG_EMISMEDIA,\t\"SDP media count mismatch in offer/answer\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDPNEG_EINVANSMEDIA,\t\"SDP media type mismatch in offer/answer\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDPNEG_EINVANSTP,\t\"SDP media transport type mismatch in offer/answer\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDPNEG_EANSNOMEDIA,\t\"No common SDP media payload in answer\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDPNEG_ENOMEDIA,\t\"No active media stream after negotiation\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDPNEG_NOANSCODEC,\t\"No suitable codec for remote offer\"),\n    PJ_BUILD_ERR( PJMEDIA_SDPNEG_NOANSTELEVENT,\t\"No suitable telephone-event for remote offer\"),\n    PJ_BUILD_ERR( PJMEDIA_SDPNEG_NOANSUNKNOWN,\t\"No suitable answer for unknown remote offer\"),\n\n    /* SDP comparison results */\n    PJ_BUILD_ERR( PJMEDIA_SDP_EMEDIANOTEQUAL,   \"SDP media descriptor not equal\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EPORTNOTEQUAL,    \"Port in SDP media descriptor not equal\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_ETPORTNOTEQUAL,   \"Transport in SDP media descriptor not equal\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EFORMATNOTEQUAL,  \"Format in SDP media descriptor not equal\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_ECONNNOTEQUAL,    \"SDP connection line not equal\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EATTRNOTEQUAL,    \"SDP attributes not equal\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EDIRNOTEQUAL,     \"SDP media direction not equal\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EFMTPNOTEQUAL,    \"SDP fmtp attribute not equal\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_ERTPMAPNOTEQUAL,  \"SDP rtpmap attribute not equal\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_ESESSNOTEQUAL,    \"SDP session descriptor not equal\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_EORIGINNOTEQUAL,  \"SDP origin line not equal\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_ENAMENOTEQUAL,    \"SDP name/subject line not equal\" ),\n    PJ_BUILD_ERR( PJMEDIA_SDP_ETIMENOTEQUAL,    \"SDP time line not equal\" ),\n\n    /* Codec errors. */\n    PJ_BUILD_ERR( PJMEDIA_CODEC_EUNSUP,\t\t\"Unsupported media codec\" ),\n    PJ_BUILD_ERR( PJMEDIA_CODEC_EFAILED,\t\"Codec internal creation error\" ),\n    PJ_BUILD_ERR( PJMEDIA_CODEC_EFRMTOOSHORT,   \"Codec frame is too short\" ),\n    PJ_BUILD_ERR( PJMEDIA_CODEC_EPCMTOOSHORT,   \"PCM frame is too short\" ),\n    PJ_BUILD_ERR( PJMEDIA_CODEC_EFRMINLEN,      \"Invalid codec frame length\" ),\n    PJ_BUILD_ERR( PJMEDIA_CODEC_EPCMFRMINLEN,   \"Invalid PCM frame length\" ),\n    PJ_BUILD_ERR( PJMEDIA_CODEC_EINMODE,\t\"Invalid codec mode (no fmtp?)\" ),\n    PJ_BUILD_ERR( PJMEDIA_CODEC_EBADBITSTREAM,\t\"Bad or corrupted bitstream\" ),\n\n    /* Media errors. */\n    PJ_BUILD_ERR( PJMEDIA_EINVALIDIP,\t    \"Invalid remote media (IP) address\" ),\n    PJ_BUILD_ERR( PJMEDIA_EASYMCODEC,\t    \"Asymetric media codec is not supported\" ),\n    PJ_BUILD_ERR( PJMEDIA_EINVALIDPT,\t    \"Invalid media payload type\" ),\n    PJ_BUILD_ERR( PJMEDIA_EMISSINGRTPMAP,   \"Missing rtpmap in media description\" ),\n    PJ_BUILD_ERR( PJMEDIA_EINVALIMEDIATYPE, \"Invalid media type\" ),\n    PJ_BUILD_ERR( PJMEDIA_EREMOTENODTMF,    \"Remote does not support DTMF\" ),\n    PJ_BUILD_ERR( PJMEDIA_RTP_EINDTMF,\t    \"Invalid DTMF digit\" ),\n    PJ_BUILD_ERR( PJMEDIA_RTP_EREMNORFC2833,\"Remote does not support RFC 2833\" ),\n    PJ_BUILD_ERR( PJMEDIA_EBADFMT,\t    \"Bad format\"),\n\n    /* RTP session errors. */\n    PJ_BUILD_ERR( PJMEDIA_RTP_EINPKT,\t    \"Invalid RTP packet\" ),\n    PJ_BUILD_ERR( PJMEDIA_RTP_EINPACK,\t    \"Invalid RTP packing (internal error)\" ),\n    PJ_BUILD_ERR( PJMEDIA_RTP_EINVER,\t    \"Invalid RTP version\" ),\n    PJ_BUILD_ERR( PJMEDIA_RTP_EINSSRC,\t    \"RTP packet SSRC id mismatch\" ),\n    PJ_BUILD_ERR( PJMEDIA_RTP_EINPT,\t    \"RTP packet payload type mismatch\" ),\n    PJ_BUILD_ERR( PJMEDIA_RTP_EINLEN,\t    \"Invalid RTP packet length\" ),\n    PJ_BUILD_ERR( PJMEDIA_RTP_ESESSRESTART,    \"RTP session restarted\" ),\n    PJ_BUILD_ERR( PJMEDIA_RTP_ESESSPROBATION,  \"RTP session in probation\" ),\n    PJ_BUILD_ERR( PJMEDIA_RTP_EBADSEQ,\t    \"Bad sequence number in RTP packet\" ),\n    PJ_BUILD_ERR( PJMEDIA_RTP_EBADDEST,\t    \"RTP media port destination is not configured\" ),\n    PJ_BUILD_ERR( PJMEDIA_RTP_ENOCONFIG,    \"RTP is not configured\" ),\n    \n    /* Media port errors: */\n    PJ_BUILD_ERR( PJMEDIA_ENOTCOMPATIBLE,   \"Media ports are not compatible\" ),\n    PJ_BUILD_ERR( PJMEDIA_ENCCLOCKRATE,\t    \"Media ports have incompatible clock rate\" ),\n    PJ_BUILD_ERR( PJMEDIA_ENCSAMPLESPFRAME, \"Media ports have incompatible samples per frame\" ),\n    PJ_BUILD_ERR( PJMEDIA_ENCTYPE,\t    \"Media ports have incompatible media type\" ),\n    PJ_BUILD_ERR( PJMEDIA_ENCBITS,\t    \"Media ports have incompatible bits per sample\" ),\n    PJ_BUILD_ERR( PJMEDIA_ENCBYTES,\t    \"Media ports have incompatible bytes per frame\" ),\n    PJ_BUILD_ERR( PJMEDIA_ENCCHANNEL,\t    \"Media ports have incompatible number of channels\" ),\n\n    /* Media file errors: */\n    PJ_BUILD_ERR( PJMEDIA_ENOTVALIDWAVE,    \"Not a valid WAVE file\" ),\n    PJ_BUILD_ERR( PJMEDIA_EWAVEUNSUPP,\t    \"Unsupported WAVE file format\" ),\n    PJ_BUILD_ERR( PJMEDIA_EWAVETOOSHORT,    \"WAVE file too short\" ),\n    PJ_BUILD_ERR( PJMEDIA_EFRMFILETOOBIG,   \"Sound frame too large for file buffer\"),\n    PJ_BUILD_ERR( PJMEDIA_EAVIUNSUPP,\t    \"Unsupported AVI file\"),\n\n    /* Sound device errors: */\n    PJ_BUILD_ERR( PJMEDIA_ENOSNDREC,\t    \"No suitable sound capture device\" ),\n    PJ_BUILD_ERR( PJMEDIA_ENOSNDPLAY,\t    \"No suitable sound playback device\" ),\n    PJ_BUILD_ERR( PJMEDIA_ESNDINDEVID,\t    \"Invalid sound device ID\" ),\n    PJ_BUILD_ERR( PJMEDIA_ESNDINSAMPLEFMT,  \"Invalid sample format for sound device\" ),\n\n#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)\n    /* SRTP transport errors: */\n    PJ_BUILD_ERR( PJMEDIA_SRTP_ECRYPTONOTMATCH, \"SRTP crypto-suite name not match the offerer tag\" ),\n    PJ_BUILD_ERR( PJMEDIA_SRTP_EINKEYLEN,\t\"Invalid SRTP key length for specific crypto\" ),\n    PJ_BUILD_ERR( PJMEDIA_SRTP_ENOTSUPCRYPTO,   \"Unsupported SRTP crypto-suite\" ),\n    PJ_BUILD_ERR( PJMEDIA_SRTP_ESDPAMBIGUEANS,  \"SRTP SDP contains ambigue answer\" ),\n    PJ_BUILD_ERR( PJMEDIA_SRTP_ESDPDUPCRYPTOTAG,\"Duplicated SRTP crypto tag\" ),\n    PJ_BUILD_ERR( PJMEDIA_SRTP_ESDPINCRYPTO,    \"Invalid SRTP crypto attribute\" ),\n    PJ_BUILD_ERR( PJMEDIA_SRTP_ESDPINCRYPTOTAG, \"Invalid SRTP crypto tag\" ),\n    PJ_BUILD_ERR( PJMEDIA_SRTP_ESDPINTRANSPORT, \"Invalid SDP media transport for SRTP\" ),\n    PJ_BUILD_ERR( PJMEDIA_SRTP_ESDPREQCRYPTO,   \"SRTP crypto attribute required\" ),\n    PJ_BUILD_ERR( PJMEDIA_SRTP_ESDPREQSECTP,    \"Secure transport required in SDP media descriptor\" )\n#endif\n\n};\n\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n\n\n/*\n * pjmedia_strerror()\n */\nPJ_DEF(pj_str_t) pjmedia_strerror( pj_status_t statcode, \n\t\t\t\t   char *buf, pj_size_t bufsize )\n{\n    pj_str_t errstr;\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n\n#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)\n    /* LIBSRTP error */\n    if (statcode >= PJMEDIA_LIBSRTP_ERRNO_START &&\n\tstatcode <  PJMEDIA_LIBSRTP_ERRNO_END)\n    {\n\tint err = statcode - PJMEDIA_LIBSRTP_ERRNO_START;\n\tpj_str_t msg;\n\t\n\tmsg = pj_str((char*)get_libsrtp_errstr(err));\n\n\terrstr.ptr = buf;\n\tpj_strncpy_with_null(&errstr, &msg, bufsize);\n\treturn errstr;\n    \n    } else\n#endif\n    \n    /* PJMEDIA error */\n    if (statcode >= PJMEDIA_ERRNO_START && \n\t       statcode < PJMEDIA_ERRNO_END)\n    {\n\t/* Find the error in the table.\n\t * Use binary search!\n\t */\n\tint first = 0;\n\tint n = PJ_ARRAY_SIZE(err_str);\n\n\twhile (n > 0) {\n\t    int half = n/2;\n\t    int mid = first + half;\n\n\t    if (err_str[mid].code < statcode) {\n\t\tfirst = mid+1;\n\t\tn -= (half+1);\n\t    } else if (err_str[mid].code > statcode) {\n\t\tn = half;\n\t    } else {\n\t\tfirst = mid;\n\t\tbreak;\n\t    }\n\t}\n\n\n\tif (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {\n\t    pj_str_t msg;\n\t    \n\t    msg.ptr = (char*)err_str[first].msg;\n\t    msg.slen = pj_ansi_strlen(err_str[first].msg);\n\n\t    errstr.ptr = buf;\n\t    pj_strncpy_with_null(&errstr, &msg, bufsize);\n\t    return errstr;\n\n\t} \n    } \n#endif\t/* PJ_HAS_ERROR_STRING */\n\n    /* Error not found. */\n    errstr.ptr = buf;\n    errstr.slen = pj_ansi_snprintf(buf, bufsize, \n\t\t\t\t   \"Unknown pjmedia error %d\",\n\t\t\t\t   statcode);\n    if (errstr.slen < 1 || errstr.slen >= (pj_ssize_t)bufsize)\n\terrstr.slen = bufsize - 1;\n    return errstr;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/event.c",
    "content": "/* $Id: event.c 3905 2011-12-09 05:15:39Z ming $ */\n/* \n * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/event.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/list.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#define THIS_FILE\t\"event.c\"\n\n#define MAX_EVENTS 16\n\ntypedef struct esub esub;\n\nstruct esub\n{\n    PJ_DECL_LIST_MEMBER(esub);\n\n    pjmedia_event_cb    *cb;\n    void                *user_data;\n    void                *epub;\n};\n\ntypedef struct event_queue\n{\n    pjmedia_event   events[MAX_EVENTS]; /**< array of events.           */\n    int             head, tail;\n    pj_bool_t       is_full;\n} event_queue;\n\nstruct pjmedia_event_mgr\n{\n    pj_pool_t      *pool;\n    pj_thread_t    *thread;             /**< worker thread.             */\n    pj_bool_t       is_quitting;\n    pj_sem_t       *sem;\n    pj_mutex_t     *mutex;\n    event_queue     ev_queue;\n    event_queue    *pub_ev_queue;       /**< publish() event queue.     */\n    esub            esub_list;          /**< list of subscribers.       */\n    esub            free_esub_list;     /**< list of subscribers.       */\n    esub           *th_next_sub,        /**< worker thread's next sub.  */\n                   *pub_next_sub;       /**< publish() next sub.        */\n};\n\nstatic pjmedia_event_mgr *event_manager_instance;\n\nstatic pj_status_t event_queue_add_event(event_queue* ev_queue,\n                                         pjmedia_event *event)\n{\n    if (ev_queue->is_full) {\n        char ev_name[5];\n\n        /* This event will be ignored. */\n        PJ_LOG(4, (THIS_FILE, \"Lost event %s from publisher [0x%p] \"\n                              \"due to full queue.\",\n                              pjmedia_fourcc_name(event->type, ev_name),\n                              event->epub));\n\n        return PJ_ETOOMANY;\n    }\n\n    pj_memcpy(&ev_queue->events[ev_queue->tail], event, sizeof(*event));\n    ev_queue->tail = (ev_queue->tail + 1) % MAX_EVENTS;\n    if (ev_queue->tail == ev_queue->head)\n        ev_queue->is_full = PJ_TRUE;\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t event_mgr_distribute_events(pjmedia_event_mgr *mgr,\n                                               event_queue *ev_queue,\n                                               esub **next_sub,\n                                               pj_bool_t rls_lock)\n{\n    pj_status_t err = PJ_SUCCESS;\n    esub * sub = mgr->esub_list.next;\n    pjmedia_event *ev = &ev_queue->events[ev_queue->head];\n\n    while (sub != &mgr->esub_list) {\n        *next_sub = sub->next;\n\n        /* Check if the subscriber is interested in \n         * receiving the event from the publisher.\n         */\n        if (sub->epub == ev->epub || !sub->epub) {\n            pjmedia_event_cb *cb = sub->cb;\n            void *user_data = sub->user_data;\n            pj_status_t status;\n            \n            if (rls_lock)\n                pj_mutex_unlock(mgr->mutex);\n\n            status = (*cb)(ev, user_data);\n            if (status != PJ_SUCCESS && err == PJ_SUCCESS)\n\t        err = status;\n\n            if (rls_lock)\n                pj_mutex_lock(mgr->mutex);\n        }\n\tsub = *next_sub;\n    }\n    *next_sub = NULL;\n\n    ev_queue->head = (ev_queue->head + 1) % MAX_EVENTS;\n    ev_queue->is_full = PJ_FALSE;\n\n    return err;\n}\n\n/* Event worker thread function. */\nstatic int event_worker_thread(void *arg)\n{\n    pjmedia_event_mgr *mgr = (pjmedia_event_mgr *)arg;\n\n    while (1) {\n\t/* Wait until there is an event. */\n        pj_sem_wait(mgr->sem);\n\n        if (mgr->is_quitting)\n            break;\n\n        pj_mutex_lock(mgr->mutex);\n        event_mgr_distribute_events(mgr, &mgr->ev_queue,\n                                    &mgr->th_next_sub, PJ_TRUE);\n        pj_mutex_unlock(mgr->mutex);\n    }\n\n    return 0;\n}\n\nPJ_DEF(pj_status_t) pjmedia_event_mgr_create(pj_pool_t *pool,\n                                             unsigned options,\n\t\t\t\t             pjmedia_event_mgr **p_mgr)\n{\n    pjmedia_event_mgr *mgr;\n    pj_status_t status;\n\n    mgr = PJ_POOL_ZALLOC_T(pool, pjmedia_event_mgr);\n    mgr->pool = pj_pool_create(pool->factory, \"evt mgr\", 500, 500, NULL);\n    pj_list_init(&mgr->esub_list);\n    pj_list_init(&mgr->free_esub_list);\n\n    if (!(options & PJMEDIA_EVENT_MGR_NO_THREAD)) {\n        status = pj_sem_create(mgr->pool, \"ev_sem\", 0, MAX_EVENTS + 1,\n                               &mgr->sem);\n        if (status != PJ_SUCCESS)\n            return status;\n\n        status = pj_thread_create(mgr->pool, \"ev_thread\",\n                                  &event_worker_thread,\n                                  mgr, 0, 0, &mgr->thread);\n        if (status != PJ_SUCCESS) {\n            pjmedia_event_mgr_destroy(mgr);\n            return status;\n        }\n    }\n\n    status = pj_mutex_create_recursive(mgr->pool, \"ev_mutex\", &mgr->mutex);\n    if (status != PJ_SUCCESS) {\n        pjmedia_event_mgr_destroy(mgr);\n        return status;\n    }\n\n    if (!event_manager_instance)\n\tevent_manager_instance = mgr;\n\n    if (p_mgr)\n\t*p_mgr = mgr;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pjmedia_event_mgr*) pjmedia_event_mgr_instance(void)\n{\n    return event_manager_instance;\n}\n\nPJ_DEF(void) pjmedia_event_mgr_set_instance(pjmedia_event_mgr *mgr)\n{\n    event_manager_instance = mgr;\n}\n\nPJ_DEF(void) pjmedia_event_mgr_destroy(pjmedia_event_mgr *mgr)\n{\n    if (!mgr) mgr = pjmedia_event_mgr_instance();\n    PJ_ASSERT_ON_FAIL(mgr != NULL, return);\n\n    if (mgr->thread) {\n        mgr->is_quitting = PJ_TRUE;\n        pj_sem_post(mgr->sem);\n        pj_thread_join(mgr->thread);\n    }\n\n    if (mgr->sem) {\n        pj_sem_destroy(mgr->sem);\n        mgr->sem = NULL;\n    }\n\n    if (mgr->mutex) {\n        pj_mutex_destroy(mgr->mutex);\n        mgr->mutex = NULL;\n    }\n\n    if (mgr->pool)\n        pj_pool_release(mgr->pool);\n\n    if (event_manager_instance == mgr)\n\tevent_manager_instance = NULL;\n}\n\nPJ_DEF(void) pjmedia_event_init( pjmedia_event *event,\n                                 pjmedia_event_type type,\n                                 const pj_timestamp *ts,\n                                 const void *src)\n{\n    pj_bzero(event, sizeof(*event));\n    event->type = type;\n    if (ts)\n\tevent->timestamp.u64 = ts->u64;\n    event->epub = event->src = src;\n}\n\nPJ_DEF(pj_status_t) pjmedia_event_subscribe( pjmedia_event_mgr *mgr,\n                                             pjmedia_event_cb *cb,\n                                             void *user_data,\n                                             void *epub)\n{\n    esub *sub;\n\n    PJ_ASSERT_RETURN(cb, PJ_EINVAL);\n\n    if (!mgr) mgr = pjmedia_event_mgr_instance();\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    pj_mutex_lock(mgr->mutex);\n    /* Check whether callback function with the same user data is already\n     * subscribed to the publisher. This is to prevent the callback function\n     * receiving the same event from the same publisher more than once.\n     */\n    sub = mgr->esub_list.next;\n    while (sub != &mgr->esub_list) {\n\tesub *next = sub->next;\n        if (sub->cb == cb && sub->user_data == user_data &&\n            sub->epub == epub)\n        {\n            pj_mutex_unlock(mgr->mutex);\n            return PJ_SUCCESS;\n        }\n\tsub = next;\n    }\n\n    if (mgr->free_esub_list.next != &mgr->free_esub_list) {\n        sub = mgr->free_esub_list.next;\n        pj_list_erase(sub);\n    } else\n        sub = PJ_POOL_ZALLOC_T(mgr->pool, esub);\n    sub->cb = cb;\n    sub->user_data = user_data;\n    sub->epub = epub;\n    pj_list_push_back(&mgr->esub_list, sub);\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t)\npjmedia_event_unsubscribe(pjmedia_event_mgr *mgr,\n                          pjmedia_event_cb *cb,\n                          void *user_data,\n                          void *epub)\n{\n    esub *sub;\n\n    PJ_ASSERT_RETURN(cb, PJ_EINVAL);\n\n    if (!mgr) mgr = pjmedia_event_mgr_instance();\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    pj_mutex_lock(mgr->mutex);\n    sub = mgr->esub_list.next;\n    while (sub != &mgr->esub_list) {\n\tesub *next = sub->next;\n        if (sub->cb == cb && (sub->user_data == user_data || !user_data) &&\n            (sub->epub == epub || !epub))\n        {\n            /* If the worker thread or pjmedia_event_publish() API is\n             * in the process of distributing events, make sure that\n             * its pointer to the next subscriber stays valid.\n             */\n            if (mgr->th_next_sub == sub)\n                mgr->th_next_sub = sub->next;\n            if (mgr->pub_next_sub == sub)\n                mgr->pub_next_sub = sub->next;\n            pj_list_erase(sub);\n            pj_list_push_back(&mgr->free_esub_list, sub);\n            if (user_data && epub)\n                break;\n        }\n\tsub = next;\n    }\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_event_publish( pjmedia_event_mgr *mgr,\n                                           void *epub,\n                                           pjmedia_event *event,\n                                           pjmedia_event_publish_flag flag)\n{\n    pj_status_t err = PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(epub && event, PJ_EINVAL);\n\n    if (!mgr) mgr = pjmedia_event_mgr_instance();\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    event->epub = epub;\n\n    pj_mutex_lock(mgr->mutex);\n    if (flag & PJMEDIA_EVENT_PUBLISH_POST_EVENT) {\n        if (event_queue_add_event(&mgr->ev_queue, event) == PJ_SUCCESS)\n            pj_sem_post(mgr->sem);\n    } else {\n        /* For nested pjmedia_event_publish() calls, i.e. calling publish()\n         * inside the subscriber's callback, the function will only add\n         * the event to the event queue of the first publish() call. It\n         * is the first publish() call that will be responsible to\n         * distribute the events.\n         */\n        if (mgr->pub_ev_queue) {\n            event_queue_add_event(mgr->pub_ev_queue, event);\n        } else {\n            static event_queue ev_queue;\n            pj_status_t status;\n\n            ev_queue.head = ev_queue.tail = 0;\n            ev_queue.is_full = PJ_FALSE;\n            mgr->pub_ev_queue = &ev_queue;\n\n            event_queue_add_event(mgr->pub_ev_queue, event);\n\n            do {\n                status = event_mgr_distribute_events(mgr, mgr->pub_ev_queue,\n                                                     &mgr->pub_next_sub,\n                                                     PJ_FALSE);\n                if (status != PJ_SUCCESS && err == PJ_SUCCESS)\n\t            err = status;\n            } while(ev_queue.head != ev_queue.tail || ev_queue.is_full);\n\n            mgr->pub_ev_queue = NULL;\n        }\n    }\n    pj_mutex_unlock(mgr->mutex);\n\n    return err;\n}\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/ffmpeg_util.c",
    "content": "/* $Id: ffmpeg_util.c 4158 2012-06-06 09:56:14Z nanang $ */\n/*\n * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia/types.h>\n#include <pj/errno.h>\n#include <pj/log.h>\n#include <pj/string.h>\n\n#if PJMEDIA_HAS_LIBAVFORMAT && PJMEDIA_HAS_LIBAVUTIL\n\n#include \"ffmpeg_util.h\"\n#include <libavformat/avformat.h>\n\n\n/* Conversion table between pjmedia_format_id and AVPixelFormat */\nstatic const struct ffmpeg_fmt_table_t\n{\n    pjmedia_format_id\tid;\n    enum AVPixelFormat\tpf;\n} ffmpeg_fmt_table[] =\n{\n    { PJMEDIA_FORMAT_ARGB, AV_PIX_FMT_ARGB},\n    { PJMEDIA_FORMAT_RGBA, AV_PIX_FMT_RGBA},\n    { PJMEDIA_FORMAT_RGB24,AV_PIX_FMT_BGR24},\n    { PJMEDIA_FORMAT_BGRA, AV_PIX_FMT_BGRA},\n    { PJMEDIA_FORMAT_GBRP, AV_PIX_FMT_GBR24P},\n\n    { PJMEDIA_FORMAT_AYUV, AV_PIX_FMT_NONE},\n    { PJMEDIA_FORMAT_YUY2, AV_PIX_FMT_YUYV422},\n    { PJMEDIA_FORMAT_UYVY, AV_PIX_FMT_UYVY422},\n    { PJMEDIA_FORMAT_I420, AV_PIX_FMT_YUV420P},\n    //{ PJMEDIA_FORMAT_YV12, AV_PIX_FMT_YUV420P},\n    { PJMEDIA_FORMAT_I422, AV_PIX_FMT_YUV422P},\n    { PJMEDIA_FORMAT_I420JPEG, AV_PIX_FMT_YUVJ420P},\n    { PJMEDIA_FORMAT_I422JPEG, AV_PIX_FMT_YUVJ422P},\n};\n\n/* Conversion table between pjmedia_format_id and CodecID */\nstatic const struct ffmpeg_codec_table_t\n{\n    pjmedia_format_id\tid;\n    unsigned\t\tcodec_id;\n} ffmpeg_codec_table[] =\n{\n    {PJMEDIA_FORMAT_H261,\tAV_CODEC_ID_H261},\n    {PJMEDIA_FORMAT_H263,\tAV_CODEC_ID_H263},\n    {PJMEDIA_FORMAT_H263P,\tAV_CODEC_ID_H263P},\n    {PJMEDIA_FORMAT_H264,\tAV_CODEC_ID_H264},\n    {PJMEDIA_FORMAT_MPEG1VIDEO,\tAV_CODEC_ID_MPEG1VIDEO},\n    {PJMEDIA_FORMAT_MPEG2VIDEO, AV_CODEC_ID_MPEG2VIDEO},\n    {PJMEDIA_FORMAT_MPEG4,\tAV_CODEC_ID_MPEG4},\n    {PJMEDIA_FORMAT_MJPEG,\tAV_CODEC_ID_MJPEG}\n};\n\nstatic int pjmedia_ffmpeg_ref_cnt;\n\nstatic void ffmpeg_log_cb(void* ptr, int level, const char* fmt, va_list vl);\n\nvoid pjmedia_ffmpeg_add_ref()\n{\n    if (pjmedia_ffmpeg_ref_cnt++ == 0) {\n\tav_log_set_level(AV_LOG_ERROR);\n\tav_log_set_callback(&ffmpeg_log_cb);\n\tav_register_all();\n    }\n}\n\nvoid pjmedia_ffmpeg_dec_ref()\n{\n    if (pjmedia_ffmpeg_ref_cnt-- == 1) {\n\t/* How to shutdown ffmpeg? */\n    }\n\n    if (pjmedia_ffmpeg_ref_cnt < 0) pjmedia_ffmpeg_ref_cnt = 0;\n}\n\n\nstatic void ffmpeg_log_cb(void* ptr, int level, const char* fmt, va_list vl)\n{\n    const char *LOG_SENDER = \"ffmpeg\";\n    enum { LOG_LEVEL = 5 };\n    char buf[100];\n    pj_size_t bufsize = sizeof(buf), len;\n    pj_str_t fmt_st;\n\n    /* Custom callback needs to filter log level by itself */\n    if (level > av_log_get_level())\n\treturn;\n    \n    /* Add original ffmpeg sender to log format */\n    if (ptr) {\n\tAVClass* avc = *(AVClass**)ptr;\n\tlen = pj_ansi_snprintf(buf, bufsize, \"%s: \", avc->item_name(ptr));\n\tif (len < 1 || len >= bufsize)\n\t    len = bufsize - 1;\n\tbufsize -= len;\n    }\n\n    /* Copy original log format */\n    len = pj_ansi_strlen(fmt);\n    if (len > bufsize-1)\n\tlen = bufsize-1;\n    pj_memcpy(buf+sizeof(buf)-bufsize, fmt, len);\n    bufsize -= len;\n\n    /* Trim log format */\n    pj_strset(&fmt_st, buf, sizeof(buf)-bufsize);\n    pj_strrtrim(&fmt_st);\n    buf[fmt_st.slen] = '\\0';\n\n    pj_log(LOG_SENDER, LOG_LEVEL, buf, vl);\n}\n\n\npj_status_t pjmedia_format_id_to_PixelFormat(pjmedia_format_id fmt_id,\n\t\t\t\t\t     enum AVPixelFormat *pixel_format)\n{\n    unsigned i;\n    for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_fmt_table); ++i) {\n\tconst struct ffmpeg_fmt_table_t *t = &ffmpeg_fmt_table[i];\n\tif (t->id==fmt_id && t->pf != AV_PIX_FMT_NONE) {\n\t    *pixel_format = t->pf;\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    *pixel_format = AV_PIX_FMT_NONE;\n    return PJ_ENOTFOUND;\n}\n\npj_status_t PixelFormat_to_pjmedia_format_id(enum AVPixelFormat pf,\n\t\t\t\t\t     pjmedia_format_id *fmt_id)\n{\n    unsigned i;\n    for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_fmt_table); ++i) {\n\tconst struct ffmpeg_fmt_table_t *t = &ffmpeg_fmt_table[i];\n\tif (t->pf == pf) {\n\t    if (fmt_id) *fmt_id = t->id;\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    return PJ_ENOTFOUND;\n}\n\npj_status_t pjmedia_format_id_to_CodecID(pjmedia_format_id fmt_id,\n\t\t\t\t\t unsigned *codec_id)\n{\n    unsigned i;\n    for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_codec_table); ++i) {\n\tconst struct ffmpeg_codec_table_t *t = &ffmpeg_codec_table[i];\n\tif (t->id==fmt_id && t->codec_id != AV_PIX_FMT_NONE) {\n\t    *codec_id = t->codec_id;\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    *codec_id = (unsigned)AV_PIX_FMT_NONE;\n    return PJ_ENOTFOUND;\n}\n\npj_status_t CodecID_to_pjmedia_format_id(unsigned codec_id,\n\t\t\t\t\t pjmedia_format_id *fmt_id)\n{\n    unsigned i;\n    for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_codec_table); ++i) {\n\tconst struct ffmpeg_codec_table_t *t = &ffmpeg_codec_table[i];\n\tif ((unsigned)t->codec_id == codec_id) {\n\t    if (fmt_id) *fmt_id = t->id;\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    return PJ_ENOTFOUND;\n}\n\n\n#ifdef _MSC_VER\n#   pragma comment( lib, \"avformat.lib\")\n#   pragma comment( lib, \"avutil.lib\")\n#endif\n\n#endif\t/* #if PJMEDIA_HAS_LIBAVFORMAT && PJMEDIA_HAS_LIBAVUTIL */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/ffmpeg_util.h",
    "content": "/* $Id: ffmpeg_util.h 3664 2011-07-19 03:42:28Z nanang $ */\n/*\n * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\n/*\n * This file contains common utilities that are useful for pjmedia components\n * that use ffmpeg. This is not a public API.\n */\n\n#ifndef __PJMEDIA_FFMPEG_UTIL_H__\n#define __PJMEDIA_FFMPEG_UTIL_H__\n\n#include <pjmedia/format.h>\n\n#ifdef _MSC_VER\n#   ifndef __cplusplus\n#\tdefine inline _inline\n#   endif\n#   pragma warning(disable:4244) /* possible loss of data */\n#endif\n\n#include <libavutil/avutil.h>\n#include <libavcodec/avcodec.h>\n\nvoid pjmedia_ffmpeg_add_ref();\nvoid pjmedia_ffmpeg_dec_ref();\n\npj_status_t pjmedia_format_id_to_PixelFormat(pjmedia_format_id fmt_id,\n\t\t\t\t\t     enum AVPixelFormat *pixel_format);\n\npj_status_t PixelFormat_to_pjmedia_format_id(enum AVPixelFormat pf,\n\t\t\t\t\t     pjmedia_format_id *fmt_id);\n\npj_status_t pjmedia_format_id_to_CodecID(pjmedia_format_id fmt_id,\n\t\t\t\t\t unsigned *codec_id);\n\npj_status_t CodecID_to_pjmedia_format_id(unsigned codec_id,\n\t\t\t\t\t pjmedia_format_id *fmt_id);\n\n#endif /* __PJMEDIA_FFMPEG_UTIL_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/format.c",
    "content": "/* $Id: format.c 4158 2012-06-06 09:56:14Z nanang $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia/format.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\nPJ_DEF(pjmedia_audio_format_detail*)\npjmedia_format_get_audio_format_detail(const pjmedia_format *fmt,\n\t\t\t\t       pj_bool_t assert_valid)\n{\n    if (fmt->detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO) {\n\treturn (pjmedia_audio_format_detail*) &fmt->det.aud;\n    } else {\n        /* Get rid of unused var compiler warning if pj_assert()\n         * macro does not do anything\n         */\n        PJ_UNUSED_ARG(assert_valid);\n\tpj_assert(!assert_valid || !\"Invalid audio format detail\");\n\treturn NULL;\n    }\n}\n\n\nPJ_DEF(pjmedia_format*) pjmedia_format_copy(pjmedia_format *dst,\n\t\t\t\t\t    const pjmedia_format *src)\n{\n    return (pjmedia_format*)pj_memcpy(dst, src, sizeof(*src));\n}\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n\nstatic pj_status_t apply_packed_fmt(const pjmedia_video_format_info *fi,\n\t                            pjmedia_video_apply_fmt_param *aparam);\n\nstatic pj_status_t apply_planar_420(const pjmedia_video_format_info *fi,\n\t                            pjmedia_video_apply_fmt_param *aparam);\n\nstatic pj_status_t apply_planar_422(const pjmedia_video_format_info *fi,\n\t                            pjmedia_video_apply_fmt_param *aparam);\n\nstatic pj_status_t apply_planar_444(const pjmedia_video_format_info *fi,\n\t                            pjmedia_video_apply_fmt_param *aparam);\n\nstruct pjmedia_video_format_mgr\n{\n    unsigned\t\t\tmax_info;\n    unsigned\t\t\tinfo_cnt;\n    pjmedia_video_format_info **infos;\n};\n\nstatic pjmedia_video_format_mgr *video_format_mgr_instance;\nstatic pjmedia_video_format_info built_in_vid_fmt_info[] =\n{\n    {PJMEDIA_FORMAT_RGB24, \"RGB24\", PJMEDIA_COLOR_MODEL_RGB, 24, 1, &apply_packed_fmt},\n    {PJMEDIA_FORMAT_ARGB,  \"ARGB\", PJMEDIA_COLOR_MODEL_RGB, 32, 1, &apply_packed_fmt},\n    {PJMEDIA_FORMAT_RGBA,  \"RGBA\", PJMEDIA_COLOR_MODEL_RGB, 32, 1, &apply_packed_fmt},\n    {PJMEDIA_FORMAT_BGRA,  \"BGRA\", PJMEDIA_COLOR_MODEL_RGB, 32, 1, &apply_packed_fmt},\n    {PJMEDIA_FORMAT_DIB ,  \"DIB \", PJMEDIA_COLOR_MODEL_RGB, 24, 1, &apply_packed_fmt},\n    {PJMEDIA_FORMAT_GBRP,  \"GBRP\", PJMEDIA_COLOR_MODEL_RGB, 24, 3, &apply_planar_444},\n    {PJMEDIA_FORMAT_AYUV,  \"AYUV\", PJMEDIA_COLOR_MODEL_YUV, 32, 1, &apply_packed_fmt},\n    {PJMEDIA_FORMAT_YUY2,  \"YUY2\", PJMEDIA_COLOR_MODEL_YUV, 16, 1, &apply_packed_fmt},\n    {PJMEDIA_FORMAT_UYVY,  \"UYVY\", PJMEDIA_COLOR_MODEL_YUV, 16, 1, &apply_packed_fmt},\n    {PJMEDIA_FORMAT_YVYU,  \"YVYU\", PJMEDIA_COLOR_MODEL_YUV, 16, 1, &apply_packed_fmt},\n    {PJMEDIA_FORMAT_I420,  \"I420\", PJMEDIA_COLOR_MODEL_YUV, 12, 3, &apply_planar_420},\n    {PJMEDIA_FORMAT_YV12,  \"YV12\", PJMEDIA_COLOR_MODEL_YUV, 12, 3, &apply_planar_420},\n    {PJMEDIA_FORMAT_I422,  \"I422\", PJMEDIA_COLOR_MODEL_YUV, 16, 3, &apply_planar_422},\n    {PJMEDIA_FORMAT_I420JPEG, \"I420JPG\", PJMEDIA_COLOR_MODEL_YUV, 12, 3, &apply_planar_420},\n    {PJMEDIA_FORMAT_I422JPEG, \"I422JPG\", PJMEDIA_COLOR_MODEL_YUV, 16, 3, &apply_planar_422},\n};\n\nPJ_DEF(void) pjmedia_format_init_video( pjmedia_format *fmt,\n\t\t\t\t\tpj_uint32_t fmt_id,\n\t\t\t\t\tunsigned width,\n\t\t\t\t\tunsigned height,\n\t\t\t\t\tunsigned fps_num,\n\t\t\t\t\tunsigned fps_denum)\n{\n    pj_assert(fps_denum);\n    fmt->id = fmt_id;\n    fmt->type = PJMEDIA_TYPE_VIDEO;\n    fmt->detail_type = PJMEDIA_FORMAT_DETAIL_VIDEO;\n\n    fmt->det.vid.size.w = width;\n    fmt->det.vid.size.h = height;\n    fmt->det.vid.fps.num = fps_num;\n    fmt->det.vid.fps.denum = fps_denum;\n    fmt->det.vid.avg_bps = fmt->det.vid.max_bps = 0;\n\n    if (pjmedia_video_format_mgr_instance()) {\n\tconst pjmedia_video_format_info *vfi;\n\tpjmedia_video_apply_fmt_param vafp;\n\tpj_uint32_t bps;\n\n\tvfi = pjmedia_get_video_format_info(NULL, fmt->id);\n        if (vfi) {\n\t    pj_bzero(&vafp, sizeof(vafp));\n\t    vafp.size = fmt->det.vid.size;\n\t    vfi->apply_fmt(vfi, &vafp);\n\n\t    bps = (pj_uint32_t)vafp.framebytes * fps_num * (pj_size_t)8 / fps_denum;\n\t    fmt->det.vid.avg_bps = fmt->det.vid.max_bps = bps;\n        }\n    }\n}\n\nPJ_DEF(pjmedia_video_format_detail*)\npjmedia_format_get_video_format_detail(const pjmedia_format *fmt,\n\t\t\t\t       pj_bool_t assert_valid)\n{\n    if (fmt->detail_type==PJMEDIA_FORMAT_DETAIL_VIDEO) {\n\treturn (pjmedia_video_format_detail*)&fmt->det.vid;\n    } else {\n\tpj_assert(!assert_valid || !\"Invalid video format detail\");\n\treturn NULL;\n    }\n}\n\n\nstatic pj_status_t apply_packed_fmt(const pjmedia_video_format_info *fi,\n\t                            pjmedia_video_apply_fmt_param *aparam)\n{\n    unsigned i;\n    pj_size_t stride;\n\n    stride = (pj_size_t)((aparam->size.w*fi->bpp) >> 3);\n\n    /* Calculate memsize */\n    aparam->framebytes = stride * aparam->size.h;\n\n    /* Packed formats only use 1 plane */\n    aparam->planes[0] = aparam->buffer;\n    aparam->strides[0] = (int)stride;\n    aparam->plane_bytes[0] = aparam->framebytes;\n\n    /* Zero unused planes */\n    for (i=1; i<PJMEDIA_MAX_VIDEO_PLANES; ++i) {\n\taparam->strides[i] = 0;\n\taparam->planes[i] = NULL;\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t apply_planar_420(const pjmedia_video_format_info *fi,\n\t                             pjmedia_video_apply_fmt_param *aparam)\n{\n    unsigned i;\n    pj_size_t Y_bytes;\n\n    PJ_UNUSED_ARG(fi);\n\n    /* Calculate memsize */\n    Y_bytes = (pj_size_t)(aparam->size.w * aparam->size.h);\n    aparam->framebytes = Y_bytes + (Y_bytes>>1);\n\n    /* Planar formats use 3 plane */\n    aparam->strides[0] = aparam->size.w;\n    aparam->strides[1] = aparam->strides[2] = (aparam->size.w>>1);\n\n    aparam->planes[0] = aparam->buffer;\n    aparam->planes[1] = aparam->planes[0] + Y_bytes;\n    aparam->planes[2] = aparam->planes[1] + (Y_bytes>>2);\n\n    aparam->plane_bytes[0] = Y_bytes;\n    aparam->plane_bytes[1] = aparam->plane_bytes[2] = (Y_bytes>>2);\n\n    /* Zero unused planes */\n    for (i=3; i<PJMEDIA_MAX_VIDEO_PLANES; ++i) {\n\taparam->strides[i] = 0;\n\taparam->planes[i] = NULL;\n        aparam->plane_bytes[i] = 0;\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t apply_planar_422(const pjmedia_video_format_info *fi,\n\t                             pjmedia_video_apply_fmt_param *aparam)\n{\n    unsigned i;\n    pj_size_t Y_bytes;\n\n    PJ_UNUSED_ARG(fi);\n\n    /* Calculate memsize */\n    Y_bytes = (pj_size_t)(aparam->size.w * aparam->size.h);\n    aparam->framebytes = (Y_bytes << 1);\n\n    /* Planar formats use 3 plane */\n    aparam->strides[0] = aparam->size.w;\n    aparam->strides[1] = aparam->strides[2] = (aparam->size.w>>1);\n\n    aparam->planes[0] = aparam->buffer;\n    aparam->planes[1] = aparam->planes[0] + Y_bytes;\n    aparam->planes[2] = aparam->planes[1] + (Y_bytes>>1);\n\n    aparam->plane_bytes[0] = Y_bytes;\n    aparam->plane_bytes[1] = aparam->plane_bytes[2] = (Y_bytes>>1);\n\n    /* Zero unused planes */\n    for (i=3; i<PJMEDIA_MAX_VIDEO_PLANES; ++i) {\n\taparam->strides[i] = 0;\n\taparam->planes[i] = NULL;\n        aparam->plane_bytes[i] = 0;\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t apply_planar_444(const pjmedia_video_format_info *fi,\n\t                            pjmedia_video_apply_fmt_param *aparam)\n{\n    unsigned i;\n    pj_size_t Y_bytes;\n\n    PJ_UNUSED_ARG(fi);\n\n    /* Calculate memsize */\n    Y_bytes = (pj_size_t)(aparam->size.w * aparam->size.h);\n    aparam->framebytes = (Y_bytes * 3);\n\n    /* Planar formats use 3 plane */\n    aparam->strides[0] = aparam->strides[1] = \n\t\t\t aparam->strides[2] = aparam->size.w;\n\n    aparam->planes[0] = aparam->buffer;\n    aparam->planes[1] = aparam->planes[0] + Y_bytes;\n    aparam->planes[2] = aparam->planes[1] + Y_bytes;\n\n    aparam->plane_bytes[0] = aparam->plane_bytes[1] =\n\t\t\t     aparam->plane_bytes[2] = Y_bytes;\n\n    /* Zero unused planes */\n    for (i=3; i<PJMEDIA_MAX_VIDEO_PLANES; ++i) {\n\taparam->strides[i] = 0;\n\taparam->planes[i] = NULL;\n        aparam->plane_bytes[i] = 0;\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t)\npjmedia_video_format_mgr_create(pj_pool_t *pool,\n\t\t\t\tunsigned max_fmt,\n\t\t\t\tunsigned options,\n\t\t\t\tpjmedia_video_format_mgr **p_mgr)\n{\n    pjmedia_video_format_mgr *mgr;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(pool && options==0, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(options);\n\n    mgr = PJ_POOL_ALLOC_T(pool, pjmedia_video_format_mgr);\n    mgr->max_info = max_fmt;\n    mgr->info_cnt = 0;\n    mgr->infos = pj_pool_calloc(pool, max_fmt, sizeof(pjmedia_video_format_info *));\n\n    if (video_format_mgr_instance == NULL)\n\tvideo_format_mgr_instance = mgr;\n\n    for (i=0; i<PJ_ARRAY_SIZE(built_in_vid_fmt_info); ++i) {\n\tpjmedia_register_video_format_info(mgr,\n\t\t\t\t\t   &built_in_vid_fmt_info[i]);\n    }\n\n    if (p_mgr)\n\t*p_mgr = mgr;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(const pjmedia_video_format_info*)\npjmedia_get_video_format_info(pjmedia_video_format_mgr *mgr,\n\t\t\t      pj_uint32_t id)\n{\n    pjmedia_video_format_info **first;\n    unsigned\t n;\n\n    if (!mgr)\n\tmgr = pjmedia_video_format_mgr_instance();\n\n    PJ_ASSERT_RETURN(mgr != NULL, NULL);\n\n    /* Binary search for the appropriate format id */\n    first = &mgr->infos[0];\n    n = mgr->info_cnt;\n    for (; n > 0; ) {\n\tunsigned half = n / 2;\n\tpjmedia_video_format_info **mid = first + half;\n\n\tif ((*mid)->id < id) {\n\t    first = ++mid;\n\t    n -= half + 1;\n\t} else if ((*mid)->id==id) {\n\t    return *mid;\n\t} else {\n\t    n = half;\n\t}\n    }\n\n    return NULL;\n}\n\n\nPJ_DEF(pj_status_t)\npjmedia_register_video_format_info(pjmedia_video_format_mgr *mgr,\n\t\t\t\t   pjmedia_video_format_info *info)\n{\n    unsigned i;\n\n    if (!mgr)\n\tmgr = pjmedia_video_format_mgr_instance();\n\n    PJ_ASSERT_RETURN(mgr != NULL, PJ_EINVALIDOP);\n\n    if (mgr->info_cnt >= mgr->max_info)\n\treturn PJ_ETOOMANY;\n\n    /* Insert to the array, sorted */\n    for (i=0; i<mgr->info_cnt; ++i) {\n\tif (mgr->infos[i]->id >= info->id)\n\t    break;\n    }\n\n    if (i < mgr->info_cnt) {\n\tif (mgr->infos[i]->id == info->id) {\n\t    /* just overwrite */\n\t    mgr->infos[i] = info;\n\t    return PJ_SUCCESS;\n\t}\n\n\tpj_memmove(&mgr->infos[i+1], &mgr->infos[i],\n\t\t   (mgr->info_cnt - i) * sizeof(pjmedia_video_format_info*));\n    }\n\n    mgr->infos[i] = info;\n    mgr->info_cnt++;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pjmedia_video_format_mgr*) pjmedia_video_format_mgr_instance(void)\n{\n    pj_assert(video_format_mgr_instance != NULL);\n    return video_format_mgr_instance;\n}\n\nPJ_DEF(void)\npjmedia_video_format_mgr_set_instance(pjmedia_video_format_mgr *mgr)\n{\n    video_format_mgr_instance = mgr;\n}\n\n\nPJ_DEF(void) pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr *mgr)\n{\n    if (!mgr)\n\tmgr = pjmedia_video_format_mgr_instance();\n\n    PJ_ASSERT_ON_FAIL(mgr != NULL, return);\n\n    mgr->info_cnt = 0;\n    if (video_format_mgr_instance == mgr)\n\tvideo_format_mgr_instance = NULL;\n}\n\n#endif /* PJMEDIA_HAS_VIDEO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/g711.c",
    "content": "/* $Id: g711.c 4266 2012-09-26 05:55:18Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n/* This file contains file from Sun Microsystems, Inc, with the complete \n * notice in the second half of this file.\n */\n#include <pjmedia/g711.h>\n#include <pjmedia/codec.h>\n#include <pjmedia/alaw_ulaw.h>\n#include <pjmedia/endpoint.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/port.h>\n#include <pjmedia/plc.h>\n#include <pjmedia/silencedet.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/assert.h>\n\n#if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC!=0\n\n/* We removed PLC in 0.6 (and re-enabled it again in 0.9!) */\n#define PLC_DISABLED\t0\n\n\n#define G711_BPS\t    64000\n#define G711_CODEC_CNT\t    0\t/* number of codec to preallocate in memory */\n#define PTIME\t\t    10\t/* basic frame size is 10 msec\t    */\n#define FRAME_SIZE\t    (8000 * PTIME / 1000)   /* 80 bytes\t    */\n#define SAMPLES_PER_FRAME   (8000 * PTIME / 1000)   /* 80 samples   */\n\n/* Prototypes for G711 factory */\nstatic pj_status_t g711_test_alloc( pjmedia_codec_factory *factory, \n\t\t\t\t    const pjmedia_codec_info *id );\nstatic pj_status_t g711_default_attr( pjmedia_codec_factory *factory, \n\t\t\t\t      const pjmedia_codec_info *id, \n\t\t\t\t      pjmedia_codec_param *attr );\nstatic pj_status_t g711_enum_codecs (pjmedia_codec_factory *factory, \n\t\t\t\t     unsigned *count, \n\t\t\t\t     pjmedia_codec_info codecs[]);\nstatic pj_status_t g711_alloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t     const pjmedia_codec_info *id, \n\t\t\t\t     pjmedia_codec **p_codec);\nstatic pj_status_t g711_dealloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t       pjmedia_codec *codec );\n\n/* Prototypes for G711 implementation. */\nstatic pj_status_t  g711_init( pjmedia_codec *codec, \n\t\t\t       pj_pool_t *pool );\nstatic pj_status_t  g711_open( pjmedia_codec *codec, \n\t\t\t       pjmedia_codec_param *attr );\nstatic pj_status_t  g711_close( pjmedia_codec *codec );\nstatic pj_status_t  g711_modify(pjmedia_codec *codec, \n\t\t\t        const pjmedia_codec_param *attr );\nstatic pj_status_t  g711_parse(pjmedia_codec *codec,\n\t\t\t       void *pkt,\n\t\t\t       pj_size_t pkt_size,\n\t\t\t       const pj_timestamp *timestamp,\n\t\t\t       unsigned *frame_cnt,\n\t\t\t       pjmedia_frame frames[]);\nstatic pj_status_t  g711_encode( pjmedia_codec *codec, \n\t\t\t\t const struct pjmedia_frame *input,\n\t\t\t\t unsigned output_buf_len, \n\t\t\t\t struct pjmedia_frame *output);\nstatic pj_status_t  g711_decode( pjmedia_codec *codec, \n\t\t\t\t const struct pjmedia_frame *input,\n\t\t\t\t unsigned output_buf_len, \n\t\t\t\t struct pjmedia_frame *output);\n#if !PLC_DISABLED\nstatic pj_status_t  g711_recover( pjmedia_codec *codec,\n\t\t\t\t  unsigned output_buf_len,\n\t\t\t\t  struct pjmedia_frame *output);\n#endif\n\n/* Definition for G711 codec operations. */\nstatic pjmedia_codec_op g711_op = \n{\n    &g711_init,\n    &g711_open,\n    &g711_close,\n    &g711_modify,\n    &g711_parse,\n    &g711_encode,\n    &g711_decode,\n#if !PLC_DISABLED\n    &g711_recover\n#else\n    NULL\n#endif\n};\n\n/* Definition for G711 codec factory operations. */\nstatic pjmedia_codec_factory_op g711_factory_op =\n{\n    &g711_test_alloc,\n    &g711_default_attr,\n    &g711_enum_codecs,\n    &g711_alloc_codec,\n    &g711_dealloc_codec,\n    &pjmedia_codec_g711_deinit\n};\n\n/* G711 factory private data */\nstatic struct g711_factory\n{\n    pjmedia_codec_factory\tbase;\n    pjmedia_endpt\t       *endpt;\n    pj_pool_t\t\t       *pool;\n    pj_mutex_t\t\t       *mutex;\n    pjmedia_codec\t\tcodec_list;\n} g711_factory;\n\n/* G711 codec private data. */\nstruct g711_private\n{\n    unsigned\t\t pt;\n#if !PLC_DISABLED\n    pj_bool_t\t\t plc_enabled;\n    pjmedia_plc\t\t*plc;\n#endif\n    pj_bool_t\t\t vad_enabled;\n    pjmedia_silence_det *vad;\n    pj_timestamp\t last_tx;\n};\n\n\nPJ_DEF(pj_status_t) pjmedia_codec_g711_init(pjmedia_endpt *endpt)\n{\n    pjmedia_codec_mgr *codec_mgr;\n    pj_status_t status;\n\n    if (g711_factory.endpt != NULL) {\n\t/* Already initialized. */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Init factory */\n    g711_factory.base.op = &g711_factory_op;\n    g711_factory.base.factory_data = NULL;\n    g711_factory.endpt = endpt;\n\n    pj_list_init(&g711_factory.codec_list);\n\n    /* Create pool */\n    g711_factory.pool = pjmedia_endpt_create_pool(endpt, \"g711\", 4000, 4000);\n    if (!g711_factory.pool)\n\treturn PJ_ENOMEM;\n\n    /* Create mutex. */\n    status = pj_mutex_create_simple(g711_factory.pool, \"g611\", \n\t\t\t\t    &g711_factory.mutex);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);\n    if (!codec_mgr) {\n\treturn PJ_EINVALIDOP;\n    }\n\n    /* Register codec factory to endpoint. */\n    status = pjmedia_codec_mgr_register_factory(codec_mgr, \n\t\t\t\t\t\t&g711_factory.base);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n\n    return PJ_SUCCESS;\n\non_error:\n    if (g711_factory.mutex) {\n\tpj_mutex_destroy(g711_factory.mutex);\n\tg711_factory.mutex = NULL;\n    }\n    if (g711_factory.pool) {\n\tpj_pool_release(g711_factory.pool);\n\tg711_factory.pool = NULL;\n    }\n    return status;\n}\n\nPJ_DEF(pj_status_t) pjmedia_codec_g711_deinit(void)\n{\n    pjmedia_codec_mgr *codec_mgr;\n    pj_status_t status;\n\n    if (g711_factory.endpt == NULL) {\n\t/* Not registered. */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Lock mutex. */\n    pj_mutex_lock(g711_factory.mutex);\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(g711_factory.endpt);\n    if (!codec_mgr) {\n\tg711_factory.endpt = NULL;\n\tpj_mutex_unlock(g711_factory.mutex);\n\treturn PJ_EINVALIDOP;\n    }\n\n    /* Unregister G711 codec factory. */\n    status = pjmedia_codec_mgr_unregister_factory(codec_mgr,\n\t\t\t\t\t\t  &g711_factory.base);\n    g711_factory.endpt = NULL;\n\n    /* Destroy mutex. */\n    pj_mutex_unlock(g711_factory.mutex);\n    pj_mutex_destroy(g711_factory.mutex);\n    g711_factory.mutex = NULL;\n\n\n    /* Release pool. */\n    pj_pool_release(g711_factory.pool);\n    g711_factory.pool = NULL;\n\n\n    return status;\n}\n\nstatic pj_status_t g711_test_alloc(pjmedia_codec_factory *factory, \n\t\t\t\t   const pjmedia_codec_info *id )\n{\n    PJ_UNUSED_ARG(factory);\n\n    /* It's sufficient to check payload type only. */\n    return (id->pt==PJMEDIA_RTP_PT_PCMU || id->pt==PJMEDIA_RTP_PT_PCMA)? 0:-1;\n}\n\nstatic pj_status_t g711_default_attr (pjmedia_codec_factory *factory, \n\t\t\t\t      const pjmedia_codec_info *id, \n\t\t\t\t      pjmedia_codec_param *attr )\n{\n    PJ_UNUSED_ARG(factory);\n\n    pj_bzero(attr, sizeof(pjmedia_codec_param));\n    attr->info.clock_rate = 8000;\n    attr->info.channel_cnt = 1;\n    attr->info.avg_bps = G711_BPS;\n    attr->info.max_bps = G711_BPS;\n    attr->info.pcm_bits_per_sample = 16;\n    attr->info.frm_ptime = PTIME;\n    attr->info.pt = (pj_uint8_t)id->pt;\n\n    /* Set default frames per packet to 2 (or 20ms) */\n    attr->setting.frm_per_pkt = 2;\n\n#if !PLC_DISABLED\n    /* Enable plc by default. */\n    attr->setting.plc = 1;\n#endif\n\n    /* Enable VAD by default. */\n    attr->setting.vad = 1;\n\n    /* Default all other flag bits disabled. */\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t g711_enum_codecs(pjmedia_codec_factory *factory, \n\t\t\t\t    unsigned *max_count, \n\t\t\t\t    pjmedia_codec_info codecs[])\n{\n    unsigned count = 0;\n\n    PJ_UNUSED_ARG(factory);\n\n    if (count < *max_count) {\n\tcodecs[count].type = PJMEDIA_TYPE_AUDIO;\n\tcodecs[count].pt = PJMEDIA_RTP_PT_PCMU;\n\tcodecs[count].encoding_name = pj_str(\"PCMU\");\n\tcodecs[count].clock_rate = 8000;\n\tcodecs[count].channel_cnt = 1;\n\t++count;\n    }\n    if (count < *max_count) {\n\tcodecs[count].type = PJMEDIA_TYPE_AUDIO;\n\tcodecs[count].pt = PJMEDIA_RTP_PT_PCMA;\n\tcodecs[count].encoding_name = pj_str(\"PCMA\");\n\tcodecs[count].clock_rate = 8000;\n\tcodecs[count].channel_cnt = 1;\n\t++count;\n    }\n\n    *max_count = count;\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t g711_alloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t     const pjmedia_codec_info *id,\n\t\t\t\t     pjmedia_codec **p_codec)\n{\n    pjmedia_codec *codec = NULL;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(factory==&g711_factory.base, PJ_EINVAL);\n\n    /* Lock mutex. */\n    pj_mutex_lock(g711_factory.mutex);\n\n    /* Allocate new codec if no more is available */\n    if (pj_list_empty(&g711_factory.codec_list)) {\n\tstruct g711_private *codec_priv;\n\n\tcodec = PJ_POOL_ALLOC_T(g711_factory.pool, pjmedia_codec);\n\tcodec_priv = PJ_POOL_ZALLOC_T(g711_factory.pool, struct g711_private);\n\tif (!codec || !codec_priv) {\n\t    pj_mutex_unlock(g711_factory.mutex);\n\t    return PJ_ENOMEM;\n\t}\n\n\t/* Set the payload type */\n\tcodec_priv->pt = id->pt;\n\n#if !PLC_DISABLED\n\t/* Create PLC, always with 10ms ptime */\n\tstatus = pjmedia_plc_create(g711_factory.pool, 8000,\n\t\t\t\t    SAMPLES_PER_FRAME,\n\t\t\t\t    0, &codec_priv->plc);\n\tif (status != PJ_SUCCESS) {\n\t    pj_mutex_unlock(g711_factory.mutex);\n\t    return status;\n\t}\n#endif\n\n\t/* Create VAD */\n\tstatus = pjmedia_silence_det_create(g711_factory.pool,\n\t\t\t\t\t    8000, SAMPLES_PER_FRAME,\n\t\t\t\t\t    &codec_priv->vad);\n\tif (status != PJ_SUCCESS) {\n\t    pj_mutex_unlock(g711_factory.mutex);\n\t    return status;\n\t}\n\n\tcodec->factory = factory;\n\tcodec->op = &g711_op;\n\tcodec->codec_data = codec_priv;\n    } else {\n\tcodec = g711_factory.codec_list.next;\n\tpj_list_erase(codec);\n    }\n\n    /* Zero the list, for error detection in g711_dealloc_codec */\n    codec->next = codec->prev = NULL;\n\n    *p_codec = codec;\n\n    /* Unlock mutex. */\n    pj_mutex_unlock(g711_factory.mutex);\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t g711_dealloc_codec(pjmedia_codec_factory *factory, \n\t\t\t\t      pjmedia_codec *codec )\n{\n    struct g711_private *priv = (struct g711_private*) codec->codec_data;\n    int i = 0;\n\n    PJ_ASSERT_RETURN(factory==&g711_factory.base, PJ_EINVAL);\n\n    /* Check that this node has not been deallocated before */\n    pj_assert (codec->next==NULL && codec->prev==NULL);\n    if (codec->next!=NULL || codec->prev!=NULL) {\n\treturn PJ_EINVALIDOP;\n    }\n\n#if !PLC_DISABLED\n    /* Clear left samples in the PLC, since codec+plc will be reused\n     * next time.\n     */\n    for (i=0; i<2; ++i) {\n\tpj_int16_t frame[SAMPLES_PER_FRAME];\n\tpjmedia_zero_samples(frame, PJ_ARRAY_SIZE(frame));\n\tpjmedia_plc_save(priv->plc, frame);\n    }\n#else\n    PJ_UNUSED_ARG(i);\n    PJ_UNUSED_ARG(priv);\n#endif\n\n    /* Lock mutex. */\n    pj_mutex_lock(g711_factory.mutex);\n\n    /* Insert at the back of the list */\n    pj_list_insert_before(&g711_factory.codec_list, codec);\n\n    /* Unlock mutex. */\n    pj_mutex_unlock(g711_factory.mutex);\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t g711_init( pjmedia_codec *codec, pj_pool_t *pool )\n{\n    /* There's nothing to do here really */\n    PJ_UNUSED_ARG(codec);\n    PJ_UNUSED_ARG(pool);\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t g711_open(pjmedia_codec *codec, \n\t\t\t     pjmedia_codec_param *attr )\n{\n    struct g711_private *priv = (struct g711_private*) codec->codec_data;\n    priv->pt = attr->info.pt;\n#if !PLC_DISABLED\n    priv->plc_enabled = (attr->setting.plc != 0);\n#endif\n    priv->vad_enabled = (attr->setting.vad != 0);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t g711_close( pjmedia_codec *codec )\n{\n    PJ_UNUSED_ARG(codec);\n    /* Nothing to do */\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t  g711_modify(pjmedia_codec *codec, \n\t\t\t        const pjmedia_codec_param *attr )\n{\n    struct g711_private *priv = (struct g711_private*) codec->codec_data;\n\n    if (attr->info.pt != priv->pt)\n\treturn PJMEDIA_EINVALIDPT;\n\n#if !PLC_DISABLED\n    priv->plc_enabled = (attr->setting.plc != 0);\n#endif\n    priv->vad_enabled = (attr->setting.vad != 0);\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t  g711_parse( pjmedia_codec *codec,\n\t\t\t\tvoid *pkt,\n\t\t\t\tpj_size_t pkt_size,\n\t\t\t\tconst pj_timestamp *ts,\n\t\t\t\tunsigned *frame_cnt,\n\t\t\t\tpjmedia_frame frames[])\n{\n    unsigned count = 0;\n\n    PJ_UNUSED_ARG(codec);\n\n    PJ_ASSERT_RETURN(ts && frame_cnt && frames, PJ_EINVAL);\n\n    while (pkt_size >= FRAME_SIZE && count < *frame_cnt) {\n\tframes[count].type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframes[count].buf = pkt;\n\tframes[count].size = FRAME_SIZE;\n\tframes[count].timestamp.u64 = ts->u64 + SAMPLES_PER_FRAME * count;\n\n\tpkt = ((char*)pkt) + FRAME_SIZE;\n\tpkt_size -= FRAME_SIZE;\n\n\t++count;\n    }\n\n    *frame_cnt = count;\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t  g711_encode(pjmedia_codec *codec, \n\t\t\t\tconst struct pjmedia_frame *input,\n\t\t\t\tunsigned output_buf_len, \n\t\t\t\tstruct pjmedia_frame *output)\n{\n    pj_int16_t *samples = (pj_int16_t*) input->buf;\n    struct g711_private *priv = (struct g711_private*) codec->codec_data;\n\n    /* Check output buffer length */\n    if (output_buf_len < (input->size >> 1))\n\treturn PJMEDIA_CODEC_EFRMTOOSHORT;\n\n    /* Detect silence if VAD is enabled */\n    if (priv->vad_enabled) {\n\tpj_bool_t is_silence;\n\tpj_int32_t silence_period;\n\n\tsilence_period = pj_timestamp_diff32(&priv->last_tx,\n\t\t\t\t\t     &input->timestamp);\n\n\tis_silence = pjmedia_silence_det_detect(priv->vad, \n\t\t\t\t\t\t(const pj_int16_t*) input->buf, \n\t\t\t\t\t\t(input->size >> 1), NULL);\n\tif (is_silence && \n\t    (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||\n\t     silence_period < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000))\n\t{\n\t    output->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    output->buf = NULL;\n\t    output->size = 0;\n\t    output->timestamp = input->timestamp;\n\t    return PJ_SUCCESS;\n\t} else {\n\t    priv->last_tx = input->timestamp;\n\t}\n    }\n\n    /* Encode */\n    if (priv->pt == PJMEDIA_RTP_PT_PCMA) {\n\tunsigned i, n;\n\tpj_uint8_t *dst = (pj_uint8_t*) output->buf;\n\n\tn = ((unsigned)input->size >> 1);\n\tfor (i=0; i!=n; ++i, ++dst) {\n\t    *dst = pjmedia_linear2alaw(samples[i]);\n\t}\n    } else if (priv->pt == PJMEDIA_RTP_PT_PCMU) {\n\tunsigned i, n;\n\tpj_uint8_t *dst = (pj_uint8_t*) output->buf;\n\n\tn = ((unsigned)input->size >> 1);\n\tfor (i=0; i!=n; ++i, ++dst) {\n\t    *dst = pjmedia_linear2ulaw(samples[i]);\n\t}\n\n    } else {\n\treturn PJMEDIA_EINVALIDPT;\n    }\n\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    output->size = (input->size >> 1);\n    output->timestamp = input->timestamp;\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t  g711_decode(pjmedia_codec *codec, \n\t\t\t\tconst struct pjmedia_frame *input,\n\t\t\t\tunsigned output_buf_len, \n\t\t\t\tstruct pjmedia_frame *output)\n{\n    struct g711_private *priv = (struct g711_private*) codec->codec_data;\n\n    /* Check output buffer length */\n    PJ_ASSERT_RETURN(output_buf_len >= (input->size << 1),\n\t\t     PJMEDIA_CODEC_EPCMTOOSHORT);\n\n    /* Input buffer MUST have exactly 80 bytes long */\n    PJ_ASSERT_RETURN(input->size == FRAME_SIZE, \n\t\t     PJMEDIA_CODEC_EFRMINLEN);\n\n    /* Decode */\n    if (priv->pt == PJMEDIA_RTP_PT_PCMA) {\n\tunsigned i;\n\tpj_uint8_t *src = (pj_uint8_t*) input->buf;\n\tpj_uint16_t *dst = (pj_uint16_t*) output->buf;\n\n\tfor (i=0; i!=input->size; ++i) {\n\t    *dst++ = (pj_uint16_t) pjmedia_alaw2linear(*src++);\n\t}\n    } else if (priv->pt == PJMEDIA_RTP_PT_PCMU) {\n\tunsigned i;\n\tpj_uint8_t *src = (pj_uint8_t*) input->buf;\n\tpj_uint16_t *dst = (pj_uint16_t*) output->buf;\n\n\tfor (i=0; i!=input->size; ++i) {\n\t    *dst++ = (pj_uint16_t) pjmedia_ulaw2linear(*src++);\n\t}\n\n    } else {\n\treturn PJMEDIA_EINVALIDPT;\n    }\n\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    output->size = (input->size << 1);\n    output->timestamp = input->timestamp;\n\n#if !PLC_DISABLED\n    if (priv->plc_enabled)\n\tpjmedia_plc_save( priv->plc, (pj_int16_t*)output->buf);\n#endif\n\n    return PJ_SUCCESS;\n}\n\n#if !PLC_DISABLED\nstatic pj_status_t  g711_recover( pjmedia_codec *codec,\n\t\t\t\t  unsigned output_buf_len,\n\t\t\t\t  struct pjmedia_frame *output)\n{\n    struct g711_private *priv = (struct g711_private*) codec->codec_data;\n\n    if (!priv->plc_enabled)\n\treturn PJ_EINVALIDOP;\n\n    PJ_ASSERT_RETURN(output_buf_len >= SAMPLES_PER_FRAME * 2, \n\t\t     PJMEDIA_CODEC_EPCMTOOSHORT);\n\n    pjmedia_plc_generate(priv->plc, (pj_int16_t*)output->buf);\n    output->size = SAMPLES_PER_FRAME * 2;\n\n    return PJ_SUCCESS;\n}\n#endif\n\n#endif\t/* PJMEDIA_HAS_G711_CODEC */\n\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/jbuf.c",
    "content": "/* $Id: jbuf.c 4369 2013-02-21 21:55:54Z bennylp $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n/*\n * Based on implementation kindly contributed by Switchlab, Ltd.\n */\n#include <pjmedia/jbuf.h>\n#include <pjmedia/errno.h>\n#include <pj/pool.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/math.h>\n#include <pj/string.h>\n\n\n#define THIS_FILE   \"jbuf.c\"\n\n\n/* Invalid sequence number, used as the initial value. */\n#define INVALID_OFFSET\t\t-9999\n\n/* Maximum burst length, whenever an operation is bursting longer than\n * this value, JB will assume that the opposite operation was idle.\n */\n#define MAX_BURST_MSEC\t\t1000\n\n/* Number of OP switches to be performed in JB_STATUS_INITIALIZING, before\n * JB can switch its states to JB_STATUS_PROCESSING.\n */\n#define INIT_CYCLE\t\t10\n\n\n/* Minimal difference between JB size and 2*burst-level to perform\n * JB shrinking in static discard algorithm.\n */\n#define STA_DISC_SAFE_SHRINKING_DIFF\t1\n\n\n/* Struct of JB internal buffer, represented in a circular buffer containing\n * frame content, frame type, frame length, and frame bit info.\n */\ntypedef struct jb_framelist_t\n{\n    /* Settings */\n    unsigned\t     frame_size;\t/**< maximum size of frame\t    */\n    unsigned\t     max_count;\t\t/**< maximum number of frames\t    */\n\n    /* Buffers */\n    char\t    *content;\t\t/**< frame content array\t    */\n    int\t\t    *frame_type;\t/**< frame type array\t\t    */\n    pj_size_t\t    *content_len;\t/**< frame length array\t\t    */\n    pj_uint32_t\t    *bit_info;\t\t/**< frame bit info array\t    */\n    pj_uint32_t\t    *ts;\t\t/**< timestamp array\t\t    */\n\n    /* States */\n    unsigned\t     head;\t\t/**< index of head, pointed frame\n\t\t\t\t\t     will be returned by next GET   */\n    unsigned\t     size;\t\t/**< current size of framelist,\n\t\t\t\t\t     including discarded frames.    */\n    unsigned\t     discarded_num;\t/**< current number of discarded\n\t\t\t\t\t     frames.\t\t\t    */\n    int\t\t     origin;\t\t/**< original index of flist_head   */\n\n} jb_framelist_t;\n\n\ntypedef void (*discard_algo)(pjmedia_jbuf *jb);\nstatic void jbuf_discard_static(pjmedia_jbuf *jb);\nstatic void jbuf_discard_progressive(pjmedia_jbuf *jb);\n\n\nstruct pjmedia_jbuf\n{\n    /* Settings (consts) */\n    pj_str_t\t    jb_name;\t\t/**< jitter buffer name\t\t    */\n    pj_size_t\t    jb_frame_size;\t/**< frame size\t\t\t    */\n    unsigned\t    jb_frame_ptime;\t/**< frame duration.\t\t    */\n    pj_size_t\t    jb_max_count;\t/**< capacity of jitter buffer,\n\t\t\t\t\t     in frames\t\t\t    */\n    int\t\t    jb_init_prefetch;\t/**< Initial prefetch\t\t    */\n    int\t\t    jb_min_prefetch;\t/**< Minimum allowable prefetch\t    */\n    int\t\t    jb_max_prefetch;\t/**< Maximum allowable prefetch\t    */\n    int\t\t    jb_max_burst;\t/**< maximum possible burst, whenever\n\t\t\t\t\t     burst exceeds this value, it\n\t\t\t\t\t     won't be included in level\n\t\t\t\t\t     calculation\t\t    */\n    int\t\t    jb_min_shrink_gap;\t/**< How often can we shrink\t    */\n    discard_algo    jb_discard_algo;\t/**< Discard algorithm\t\t    */\n\n    /* Buffer */\n    jb_framelist_t  jb_framelist;\t/**< the buffer\t\t\t    */\n\n    /* States */\n    int\t\t    jb_level;\t\t/**< delay between source &\n\t\t\t\t\t     destination (calculated according\n\t\t\t\t\t     of the number of burst get/put\n\t\t\t\t\t     operations)\t\t    */\n    int\t\t    jb_max_hist_level;  /**< max level during the last level\n\t\t\t\t\t     calculations\t\t    */\n    int\t\t    jb_stable_hist;\t/**< num of times the delay has\tbeen\n\t\t\t\t\t     lower then the prefetch num    */\n    int\t\t    jb_last_op;\t\t/**< last operation executed\n\t\t\t\t\t     (put/get)\t\t\t    */\n    int\t\t    jb_eff_level;\t/**< effective burst level\t    */\n    int\t\t    jb_prefetch;\t/**< no. of frame to insert before\n\t\t\t\t\t     removing some (at the beginning\n\t\t\t\t\t     of the framelist->content\n\t\t\t\t\t     operation), the value may be\n\t\t\t\t\t     continuously updated based on\n\t\t\t\t\t     current frame burst level.\t    */\n    pj_bool_t\t    jb_prefetching;\t/**< flag if jbuf is prefetching.   */\n    int\t\t    jb_status;\t\t/**< status is 'init' until the\tfirst\n\t\t\t\t\t     'put' operation\t\t    */\n    int\t\t    jb_init_cycle_cnt;\t/**< status is 'init' until the\tfirst\n\t\t\t\t\t     'put' operation\t\t    */\n\n    int\t\t    jb_discard_ref;\t/**< Seq # of last frame deleted or\n\t\t\t\t\t     discarded\t\t\t    */\n    unsigned\t    jb_discard_dist;\t/**< Distance from jb_discard_ref\n\t\t\t\t\t     to perform discard (in frm)    */\n\n    /* Statistics */\n    pj_math_stat    jb_delay;\t\t/**< Delay statistics of jitter buffer\n\t\t\t\t\t     (in ms)\t\t\t    */\n    pj_math_stat    jb_burst;\t\t/**< Burst statistics (in frames)   */\n    unsigned\t    jb_lost;\t\t/**< Number of lost frames.\t    */\n    unsigned\t    jb_discard;\t\t/**< Number of discarded frames.    */\n    unsigned\t    jb_empty;\t\t/**< Number of empty/prefetching frame\n\t\t\t\t\t     returned by GET. */\n};\n\n\n#define JB_STATUS_INITIALIZING\t0\n#define JB_STATUS_PROCESSING\t1\n\n\n\n/* Progressive discard algorithm introduced to reduce JB latency\n * by discarding incoming frames with adaptive aggressiveness based on\n * actual burst level.\n */\n#define PROGRESSIVE_DISCARD 1\n\n/* Internal JB frame flag, discarded frame will not be returned by JB to\n * application, it's just simply discarded.\n */\n#define PJMEDIA_JB_DISCARDED_FRAME 1024\n\n\n\n/* Enabling this would log the jitter buffer state about once per\n * second.\n */\n#if 0\n#  define TRACE__(args)\t    PJ_LOG(5,args)\n#else\n#  define TRACE__(args)\n#endif\n\nstatic pj_status_t jb_framelist_reset(jb_framelist_t *framelist);\nstatic unsigned jb_framelist_remove_head(jb_framelist_t *framelist,\n\t\t\t\t\t unsigned count);\n\nstatic pj_status_t jb_framelist_init( pj_pool_t *pool,\n\t\t\t\t      jb_framelist_t *framelist,\n\t\t\t\t      unsigned frame_size,\n\t\t\t\t      unsigned max_count)\n{\n    PJ_ASSERT_RETURN(pool && framelist, PJ_EINVAL);\n\n    pj_bzero(framelist, sizeof(jb_framelist_t));\n\n    framelist->frame_size   = frame_size;\n    framelist->max_count    = max_count;\n    framelist->content\t    = (char*)\n\t\t\t      pj_pool_alloc(pool,\n\t\t\t\t\t    framelist->frame_size*\n\t\t\t\t\t    framelist->max_count);\n    framelist->frame_type   = (int*)\n\t\t\t      pj_pool_alloc(pool,\n\t\t\t\t\t    sizeof(framelist->frame_type[0])*\n\t\t\t\t\t    framelist->max_count);\n    framelist->content_len  = (pj_size_t*)\n\t\t\t      pj_pool_alloc(pool,\n\t\t\t\t\t    sizeof(framelist->content_len[0])*\n\t\t\t\t\t    framelist->max_count);\n    framelist->bit_info\t    = (pj_uint32_t*)\n\t\t\t      pj_pool_alloc(pool,\n\t\t\t\t\t    sizeof(framelist->bit_info[0])*\n\t\t\t\t\t    framelist->max_count);\n    framelist->ts\t    = (pj_uint32_t*)\n\t\t\t      pj_pool_alloc(pool,\n\t\t\t\t\t    sizeof(framelist->ts[0])*\n\t\t\t\t\t    framelist->max_count);\n\n    return jb_framelist_reset(framelist);\n\n}\n\nstatic pj_status_t jb_framelist_destroy(jb_framelist_t *framelist)\n{\n    PJ_UNUSED_ARG(framelist);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t jb_framelist_reset(jb_framelist_t *framelist)\n{\n    framelist->head = 0;\n    framelist->origin = INVALID_OFFSET;\n    framelist->size = 0;\n    framelist->discarded_num = 0;\n\n\n    //pj_bzero(framelist->content,\n    //\t     framelist->frame_size *\n    //\t     framelist->max_count);\n\n    pj_memset(framelist->frame_type,\n\t      PJMEDIA_JB_MISSING_FRAME,\n\t      sizeof(framelist->frame_type[0]) *\n\t      framelist->max_count);\n\n    pj_bzero(framelist->content_len,\n\t     sizeof(framelist->content_len[0]) *\n\t     framelist->max_count);\n\n    //pj_bzero(framelist->bit_info,\n    //\t     sizeof(framelist->bit_info[0]) *\n    //\t     framelist->max_count);\n\n    return PJ_SUCCESS;\n}\n\n\nstatic unsigned jb_framelist_size(const jb_framelist_t *framelist)\n{\n    return framelist->size;\n}\n\n\nstatic unsigned jb_framelist_eff_size(const jb_framelist_t *framelist)\n{\n    return (framelist->size - framelist->discarded_num);\n}\n\nstatic int jb_framelist_origin(const jb_framelist_t *framelist)\n{\n    return framelist->origin;\n}\n\n\nstatic pj_bool_t jb_framelist_get(jb_framelist_t *framelist,\n\t\t\t\t  void *frame, pj_size_t *size,\n\t\t\t\t  pjmedia_jb_frame_type *p_type,\n\t\t\t\t  pj_uint32_t *bit_info,\n\t\t\t\t  pj_uint32_t *ts,\n\t\t\t\t  int *seq)\n{\n    if (framelist->size) {\n\tpj_bool_t prev_discarded = PJ_FALSE;\n\n\t/* Skip discarded frames */\n\twhile (framelist->frame_type[framelist->head] ==\n\t       PJMEDIA_JB_DISCARDED_FRAME)\n\t{\n\t    jb_framelist_remove_head(framelist, 1);\n\t    prev_discarded = PJ_TRUE;\n\t}\n\n\t/* Return the head frame if any */\n\tif (framelist->size) {\n\t    if (prev_discarded) {\n\t\t/* Ticket #1188: when previous frame(s) was discarded, return\n\t\t * 'missing' frame to trigger PLC to get smoother signal.\n\t\t */\n\t\t*p_type = PJMEDIA_JB_MISSING_FRAME;\n\t\tif (size)\n\t\t    *size = 0;\n\t\tif (bit_info)\n\t\t    *bit_info = 0;\n\t    } else {\n\t\tpj_memcpy(frame,\n\t\t\t  framelist->content +\n\t\t\t  framelist->head * framelist->frame_size,\n\t\t\t  framelist->frame_size);\n\t\t*p_type = (pjmedia_jb_frame_type)\n\t\t\t  framelist->frame_type[framelist->head];\n\t\tif (size)\n\t\t    *size   = framelist->content_len[framelist->head];\n\t\tif (bit_info)\n\t\t    *bit_info = framelist->bit_info[framelist->head];\n\t    }\n\t    if (ts)\n\t\t*ts = framelist->ts[framelist->head];\n\t    if (seq)\n\t\t*seq = framelist->origin;\n\n\t    //pj_bzero(framelist->content +\n\t    //\t framelist->head * framelist->frame_size,\n\t    //\t framelist->frame_size);\n\t    framelist->frame_type[framelist->head] = PJMEDIA_JB_MISSING_FRAME;\n\t    framelist->content_len[framelist->head] = 0;\n\t    framelist->bit_info[framelist->head] = 0;\n\t    framelist->ts[framelist->head] = 0;\n\n\t    framelist->origin++;\n\t    framelist->head = (framelist->head + 1) % framelist->max_count;\n\t    framelist->size--;\n\n\t    return PJ_TRUE;\n\t}\n    }\n\n    /* No frame available */\n    pj_bzero(frame, framelist->frame_size);\n\n    return PJ_FALSE;\n}\n\n\nstatic pj_bool_t jb_framelist_peek(jb_framelist_t *framelist,\n\t\t\t\t   unsigned offset,\n\t\t\t\t   const void **frame,\n\t\t\t\t   pj_size_t *size,\n\t\t\t\t   pjmedia_jb_frame_type *type,\n\t\t\t\t   pj_uint32_t *bit_info,\n\t\t\t\t   pj_uint32_t *ts,\n\t\t\t\t   int *seq)\n{\n    unsigned pos, idx;\n\n    if (offset >= jb_framelist_eff_size(framelist))\n\treturn PJ_FALSE;\n\n    pos = framelist->head;\n    idx = offset;\n\n    /* Find actual peek position, note there may be discarded frames */\n    while (1) {\n\tif (framelist->frame_type[pos] != PJMEDIA_JB_DISCARDED_FRAME) {\n\t    if (idx == 0)\n\t\tbreak;\n\t    else\n\t\t--idx;\n\t}\n\tpos = (pos + 1) % framelist->max_count;\n    }\n\n    /* Return the frame pointer */\n    if (frame)\n\t*frame = framelist->content + pos*framelist->frame_size;\n    if (type)\n\t*type = (pjmedia_jb_frame_type)\n\t\tframelist->frame_type[pos];\n    if (size)\n\t*size = framelist->content_len[pos];\n    if (bit_info)\n\t*bit_info = framelist->bit_info[pos];\n    if (ts)\n\t*ts = framelist->ts[pos];\n    if (seq)\n\t*seq = framelist->origin + offset;\n\n    return PJ_TRUE;\n}\n\n\n/* Remove oldest frames as many as param 'count' */\nstatic unsigned jb_framelist_remove_head(jb_framelist_t *framelist,\n\t\t\t\t\t unsigned count)\n{\n    if (count > framelist->size)\n\tcount = framelist->size;\n\n    if (count) {\n\t/* may be done in two steps if overlapping */\n\tunsigned step1,step2;\n\tunsigned tmp = framelist->head+count;\n\tunsigned i;\n\n\tif (tmp > framelist->max_count) {\n\t    step1 = framelist->max_count - framelist->head;\n\t    step2 = count-step1;\n\t} else {\n\t    step1 = count;\n\t    step2 = 0;\n\t}\n\n\tfor (i = framelist->head; i < (framelist->head + step1); ++i) {\n\t    if (framelist->frame_type[i] == PJMEDIA_JB_DISCARDED_FRAME) {\n\t\tpj_assert(framelist->discarded_num > 0);\n\t\tframelist->discarded_num--;\n\t    }\n\t}\n\n\t//pj_bzero(framelist->content +\n\t//\t    framelist->head * framelist->frame_size,\n\t//          step1*framelist->frame_size);\n\tpj_memset(framelist->frame_type+framelist->head,\n\t\t  PJMEDIA_JB_MISSING_FRAME,\n\t\t  step1*sizeof(framelist->frame_type[0]));\n\tpj_bzero(framelist->content_len+framelist->head,\n\t\t step1*sizeof(framelist->content_len[0]));\n\n\tif (step2) {\n\t    for (i = 0; i < step2; ++i) {\n\t\tif (framelist->frame_type[i] == PJMEDIA_JB_DISCARDED_FRAME) {\n\t\t    pj_assert(framelist->discarded_num > 0);\n\t\t    framelist->discarded_num--;\n\t\t}\n\t    }\n\t    //pj_bzero( framelist->content,\n\t    //\t      step2*framelist->frame_size);\n\t    pj_memset(framelist->frame_type,\n\t\t      PJMEDIA_JB_MISSING_FRAME,\n\t\t      step2*sizeof(framelist->frame_type[0]));\n\t    pj_bzero (framelist->content_len,\n\t\t      step2*sizeof(framelist->content_len[0]));\n\t}\n\n\t/* update states */\n\tframelist->origin += count;\n\tframelist->head = (framelist->head + count) % framelist->max_count;\n\tframelist->size -= count;\n    }\n\n    return count;\n}\n\n\nstatic pj_status_t jb_framelist_put_at(jb_framelist_t *framelist,\n\t\t\t\t       int index,\n\t\t\t\t       const void *frame,\n\t\t\t\t       unsigned frame_size,\n\t\t\t\t       pj_uint32_t bit_info,\n\t\t\t\t       pj_uint32_t ts,\n\t\t\t\t       unsigned frame_type)\n{\n    int distance;\n    unsigned pos;\n    enum { MAX_MISORDER = 100 };\n    enum { MAX_DROPOUT = 3000 };\n\n    PJ_ASSERT_RETURN(frame_size <= framelist->frame_size, PJ_EINVAL);\n\n    /* too late or sequence restart */\n    if (index < framelist->origin) {\n\tif (framelist->origin - index < MAX_MISORDER) {\n\t    /* too late */\n\t    return PJ_ETOOSMALL;\n\t} else {\n\t    /* sequence restart */\n\t    framelist->origin = index - framelist->size;\n\t}\n    }\n\n    /* if jbuf is empty, just reset the origin */\n    if (framelist->size == 0) {\n\tpj_assert(framelist->discarded_num == 0);\n\tframelist->origin = index;\n    }\n\n    /* get distance of this frame to the first frame in the buffer */\n    distance = index - framelist->origin;\n\n    /* far jump, the distance is greater than buffer capacity */\n    if (distance >= (int)framelist->max_count) {\n\tif (distance > MAX_DROPOUT) {\n\t    /* jump too far, reset the buffer */\n\t    jb_framelist_reset(framelist);\n\t    framelist->origin = index;\n\t    distance = 0;\n\t} else {\n\t    /* otherwise, reject the frame */\n\t    return PJ_ETOOMANY;\n\t}\n    }\n\n    /* get the slot position */\n    pos = (framelist->head + distance) % framelist->max_count;\n\n    /* if the slot is occupied, it must be duplicated frame, ignore it. */\n    if (framelist->frame_type[pos] != PJMEDIA_JB_MISSING_FRAME)\n\treturn PJ_EEXISTS;\n\n    /* put the frame into the slot */\n    framelist->frame_type[pos] = frame_type;\n    framelist->content_len[pos] = frame_size;\n    framelist->bit_info[pos] = bit_info;\n    framelist->ts[pos] = ts;\n\n    /* update framelist size */\n    if (framelist->origin + (int)framelist->size <= index)\n\tframelist->size = distance + 1;\n\n    if(PJMEDIA_JB_NORMAL_FRAME == frame_type) {\n\t/* copy frame content */\n\tpj_memcpy(framelist->content + pos * framelist->frame_size,\n\t\t  frame, frame_size);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t jb_framelist_discard(jb_framelist_t *framelist,\n\t\t\t\t        int index)\n{\n    unsigned pos;\n\n    PJ_ASSERT_RETURN(index >= framelist->origin &&\n\t\t     index <  framelist->origin + (int)framelist->size,\n\t\t     PJ_EINVAL);\n\n    /* Get the slot position */\n    pos = (framelist->head + (index - framelist->origin)) %\n\t  framelist->max_count;\n\n    /* Discard the frame */\n    framelist->frame_type[pos] = PJMEDIA_JB_DISCARDED_FRAME;\n    framelist->discarded_num++;\n\n    return PJ_SUCCESS;\n}\n\n\nenum pjmedia_jb_op\n{\n    JB_OP_INIT  = -1,\n    JB_OP_PUT   = 1,\n    JB_OP_GET   = 2\n};\n\n\nPJ_DEF(pj_status_t) pjmedia_jbuf_create(pj_pool_t *pool,\n\t\t\t\t\tconst pj_str_t *name,\n\t\t\t\t\tunsigned frame_size,\n\t\t\t\t\tunsigned ptime,\n\t\t\t\t\tunsigned max_count,\n\t\t\t\t\tpjmedia_jbuf **p_jb)\n{\n    pjmedia_jbuf *jb;\n    pj_status_t status;\n\n    jb = PJ_POOL_ZALLOC_T(pool, pjmedia_jbuf);\n\n    status = jb_framelist_init(pool, &jb->jb_framelist, frame_size, max_count);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_strdup_with_null(pool, &jb->jb_name, name);\n    jb->jb_frame_size\t = frame_size;\n    jb->jb_frame_ptime   = ptime;\n    jb->jb_prefetch\t = PJ_MIN(PJMEDIA_JB_DEFAULT_INIT_DELAY,max_count*4/5);\n    jb->jb_min_prefetch  = 0;\n    jb->jb_max_prefetch  = max_count*4/5;\n    jb->jb_max_count\t = max_count;\n    jb->jb_min_shrink_gap= PJMEDIA_JBUF_DISC_MIN_GAP / ptime;\n    jb->jb_max_burst\t = PJ_MAX(MAX_BURST_MSEC / ptime, max_count*3/4);\n\n    pj_math_stat_init(&jb->jb_delay);\n    pj_math_stat_init(&jb->jb_burst);\n\n    pjmedia_jbuf_set_discard(jb, PJMEDIA_JB_DISCARD_PROGRESSIVE);\n    pjmedia_jbuf_reset(jb);\n\n    *p_jb = jb;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Set the jitter buffer to fixed delay mode. The default behavior\n * is to adapt the delay with actual packet delay.\n *\n */\nPJ_DEF(pj_status_t) pjmedia_jbuf_set_fixed( pjmedia_jbuf *jb,\n\t\t\t\t\t    unsigned prefetch)\n{\n    PJ_ASSERT_RETURN(jb, PJ_EINVAL);\n    PJ_ASSERT_RETURN(prefetch <= jb->jb_max_count, PJ_EINVAL);\n\n    jb->jb_min_prefetch = jb->jb_max_prefetch =\n\tjb->jb_prefetch = jb->jb_init_prefetch = prefetch;\n\n    pjmedia_jbuf_set_discard(jb, PJMEDIA_JB_DISCARD_NONE);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Set the jitter buffer to adaptive mode.\n */\nPJ_DEF(pj_status_t) pjmedia_jbuf_set_adaptive( pjmedia_jbuf *jb,\n\t\t\t\t\t       unsigned prefetch,\n\t\t\t\t\t       unsigned min_prefetch,\n\t\t\t\t\t       unsigned max_prefetch)\n{\n    PJ_ASSERT_RETURN(jb, PJ_EINVAL);\n    PJ_ASSERT_RETURN(min_prefetch <= max_prefetch &&\n\t\t     prefetch <= max_prefetch &&\n\t\t     max_prefetch <= jb->jb_max_count,\n\t\t     PJ_EINVAL);\n\n    jb->jb_prefetch = jb->jb_init_prefetch = prefetch;\n    jb->jb_min_prefetch = min_prefetch;\n    jb->jb_max_prefetch = max_prefetch;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_jbuf_set_discard( pjmedia_jbuf *jb,\n\t\t\t\t\t      pjmedia_jb_discard_algo algo)\n{\n    PJ_ASSERT_RETURN(jb, PJ_EINVAL);\n    PJ_ASSERT_RETURN(algo >= PJMEDIA_JB_DISCARD_NONE &&\n\t\t     algo <= PJMEDIA_JB_DISCARD_PROGRESSIVE,\n\t\t     PJ_EINVAL);\n\n    switch(algo) {\n    case PJMEDIA_JB_DISCARD_PROGRESSIVE:\n\tjb->jb_discard_algo = &jbuf_discard_progressive;\n\tbreak;\n    case PJMEDIA_JB_DISCARD_STATIC:\n\tjb->jb_discard_algo = &jbuf_discard_static;\n\tbreak;\n    default:\n\tjb->jb_discard_algo = NULL;\n\tbreak;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_jbuf_reset(pjmedia_jbuf *jb)\n{\n    jb->jb_level\t = 0;\n    jb->jb_last_op\t = JB_OP_INIT;\n    jb->jb_stable_hist\t = 0;\n    jb->jb_status\t = JB_STATUS_INITIALIZING;\n    jb->jb_init_cycle_cnt= 0;\n    jb->jb_max_hist_level= 0;\n    jb->jb_prefetching   = (jb->jb_prefetch != 0);\n    jb->jb_discard_dist  = 0;\n\n    jb_framelist_reset(&jb->jb_framelist);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_jbuf_destroy(pjmedia_jbuf *jb)\n{\n    PJ_LOG(5, (jb->jb_name.ptr, \"\"\n\t       \"JB summary:\\n\"\n\t       \"  size=%d/eff=%d prefetch=%d level=%d\\n\"\n\t       \"  delay (min/max/avg/dev)=%d/%d/%d/%d ms\\n\"\n\t       \"  burst (min/max/avg/dev)=%d/%d/%d/%d frames\\n\"\n\t       \"  lost=%d discard=%d empty=%d\",\n\t       jb_framelist_size(&jb->jb_framelist),\n\t       jb_framelist_eff_size(&jb->jb_framelist),\n\t       jb->jb_prefetch, jb->jb_eff_level,\n\t       jb->jb_delay.min, jb->jb_delay.max, jb->jb_delay.mean,\n\t       pj_math_stat_get_stddev(&jb->jb_delay),\n\t       jb->jb_burst.min, jb->jb_burst.max, jb->jb_burst.mean,\n\t       pj_math_stat_get_stddev(&jb->jb_burst),\n\t       jb->jb_lost, jb->jb_discard, jb->jb_empty));\n\n    return jb_framelist_destroy(&jb->jb_framelist);\n}\n\nPJ_DEF(pj_bool_t) pjmedia_jbuf_is_full(const pjmedia_jbuf *jb)\n{\n    return jb->jb_framelist.size == jb->jb_framelist.max_count;\n}\n\nstatic void jbuf_calculate_jitter(pjmedia_jbuf *jb)\n{\n    int diff, cur_size;\n\n    cur_size = jb_framelist_eff_size(&jb->jb_framelist);\n    pj_math_stat_update(&jb->jb_burst, jb->jb_level);\n    jb->jb_max_hist_level = PJ_MAX(jb->jb_max_hist_level, jb->jb_level);\n\n    /* Burst level is decreasing */\n    if (jb->jb_level < jb->jb_eff_level) {\n\n\tenum { STABLE_HISTORY_LIMIT = 20 };\n\n\tjb->jb_stable_hist++;\n\n\t/* Only update the effective level (and prefetch) if 'stable'\n\t * condition is reached (not just short time impulse)\n\t */\n\tif (jb->jb_stable_hist > STABLE_HISTORY_LIMIT) {\n\n\t    diff = (jb->jb_eff_level - jb->jb_max_hist_level) / 3;\n\n\t    if (diff < 1)\n\t\tdiff = 1;\n\n\t    /* Update effective burst level */\n\t    jb->jb_eff_level -= diff;\n\n\t    /* Update prefetch based on level */\n\t    if (jb->jb_init_prefetch) {\n\t\tjb->jb_prefetch = jb->jb_eff_level;\n\t\tif (jb->jb_prefetch < jb->jb_min_prefetch)\n\t\t    jb->jb_prefetch = jb->jb_min_prefetch;\n\t\tif (jb->jb_prefetch > jb->jb_max_prefetch)\n\t\t    jb->jb_prefetch = jb->jb_max_prefetch;\n\t    }\n\n\t    /* Reset history */\n\t    jb->jb_max_hist_level = 0;\n\t    jb->jb_stable_hist = 0;\n\n\t    TRACE__((jb->jb_name.ptr,\"jb updated(1), lvl=%d pre=%d, size=%d\",\n\t\t     jb->jb_eff_level, jb->jb_prefetch, cur_size));\n\t    PJ_UNUSED_ARG(cur_size); /* Warning about unused var */\n\t}\n    }\n\n    /* Burst level is increasing */\n    else if (jb->jb_level > jb->jb_eff_level) {\n\n\t/* Instaneous set effective burst level to recent maximum level */\n\tjb->jb_eff_level = PJ_MIN(jb->jb_max_hist_level,\n\t\t\t\t  (int)(jb->jb_max_count*4/5));\n\n\t/* Update prefetch based on level */\n\tif (jb->jb_init_prefetch) {\n\t    jb->jb_prefetch = jb->jb_eff_level;\n\t    if (jb->jb_prefetch > jb->jb_max_prefetch)\n\t\tjb->jb_prefetch = jb->jb_max_prefetch;\n\t    if (jb->jb_prefetch < jb->jb_min_prefetch)\n\t\tjb->jb_prefetch = jb->jb_min_prefetch;\n\t}\n\n\tjb->jb_stable_hist = 0;\n\t/* Do not reset max_hist_level. */\n\t//jb->jb_max_hist_level = 0;\n\n\tTRACE__((jb->jb_name.ptr,\"jb updated(2), lvl=%d pre=%d, size=%d\",\n\t\t jb->jb_eff_level, jb->jb_prefetch, cur_size));\n    }\n\n    /* Level is unchanged */\n    else {\n\tjb->jb_stable_hist = 0;\n    }\n}\n\n\nstatic void jbuf_discard_static(pjmedia_jbuf *jb)\n{\n    /* These code is used for shortening the delay in the jitter buffer.\n     * It needs shrink only when there is possibility of drift. Drift\n     * detection is performed by inspecting the jitter buffer size, if\n     * its size is twice of current burst level, there can be drift.\n     *\n     * Moreover, normally drift level is quite low, so JB shouldn't need\n     * to shrink aggresively, it will shrink maximum one frame per\n     * PJMEDIA_JBUF_DISC_MIN_GAP ms. Theoritically, JB may handle drift level\n     * as much as = FRAME_PTIME/PJMEDIA_JBUF_DISC_MIN_GAP * 100%\n     *\n     * Whenever there is drift, where PUT > GET, this method will keep\n     * the latency (JB size) as much as twice of burst level.\n     */\n\n    /* Shrinking due of drift will be implicitly done by progressive discard,\n     * so just disable it when progressive discard is active.\n     */\n    int diff, burst_level;\n\n    burst_level = PJ_MAX(jb->jb_eff_level, jb->jb_level);\n    diff = jb_framelist_eff_size(&jb->jb_framelist) - burst_level*2;\n\n    if (diff >= STA_DISC_SAFE_SHRINKING_DIFF) {\n\tint seq_origin;\n\n\t/* Check and adjust jb_discard_ref, in case there was\n\t * seq restart\n\t */\n\tseq_origin = jb_framelist_origin(&jb->jb_framelist);\n\tif (seq_origin < jb->jb_discard_ref)\n\t    jb->jb_discard_ref = seq_origin;\n\n\tif (seq_origin - jb->jb_discard_ref >= jb->jb_min_shrink_gap)\n\t{\n\t    /* Shrink slowly, one frame per cycle */\n\t    diff = 1;\n\n\t    /* Drop frame(s)! */\n\t    diff = jb_framelist_remove_head(&jb->jb_framelist, diff);\n\t    jb->jb_discard_ref = jb_framelist_origin(&jb->jb_framelist);\n\t    jb->jb_discard += diff;\n\n\t    TRACE__((jb->jb_name.ptr,\n\t\t     \"JB shrinking %d frame(s), cur size=%d\", diff,\n\t\t     jb_framelist_eff_size(&jb->jb_framelist)));\n\t}\n    }\n}\n\n\nstatic void jbuf_discard_progressive(pjmedia_jbuf *jb)\n{\n    unsigned cur_size, burst_level, overflow, T, discard_dist;\n    int last_seq;\n\n    /* Should be done in PUT operation */\n    if (jb->jb_last_op != JB_OP_PUT)\n\treturn;\n\n    /* Check if latency is longer than burst */\n    cur_size = jb_framelist_eff_size(&jb->jb_framelist);\n    burst_level = PJ_MAX(jb->jb_eff_level, jb->jb_level);\n    if (cur_size <= burst_level) {\n\t/* Reset any scheduled discard */\n\tjb->jb_discard_dist = 0;\n\treturn;\n    }\n\n    /* Estimate discard duration needed for adjusting latency */\n    if (burst_level <= PJMEDIA_JBUF_PRO_DISC_MIN_BURST)\n\tT = PJMEDIA_JBUF_PRO_DISC_T1;\n    else if (burst_level >= PJMEDIA_JBUF_PRO_DISC_MAX_BURST)\n\tT = PJMEDIA_JBUF_PRO_DISC_T2;\n    else\n\tT = PJMEDIA_JBUF_PRO_DISC_T1 +\n\t    (PJMEDIA_JBUF_PRO_DISC_T2 - PJMEDIA_JBUF_PRO_DISC_T1) *\n\t    (burst_level - PJMEDIA_JBUF_PRO_DISC_MIN_BURST) /\n\t    (PJMEDIA_JBUF_PRO_DISC_MAX_BURST-PJMEDIA_JBUF_PRO_DISC_MIN_BURST);\n\n    /* Calculate current discard distance */\n    overflow = cur_size - burst_level;\n    discard_dist = T / overflow / jb->jb_frame_ptime;\n\n    /* Get last seq number in the JB */\n    last_seq = jb_framelist_origin(&jb->jb_framelist) +\n\t       jb_framelist_size(&jb->jb_framelist) - 1;\n\n    /* Setup new discard schedule if none, otherwise, update the existing\n     * discard schedule (can be delayed or accelerated).\n     */\n    if (jb->jb_discard_dist == 0) {\n\t/* Setup new discard schedule */\n\tjb->jb_discard_ref = last_seq;\n    } else if (last_seq < jb->jb_discard_ref) {\n\t/* Seq restarted, update discard reference */\n    \tjb->jb_discard_ref = last_seq;\n    }\n    jb->jb_discard_dist = PJ_MAX(jb->jb_min_shrink_gap, (int)discard_dist);\n\n    /* Check if we need to discard now */\n    if (last_seq >= (jb->jb_discard_ref + (int)jb->jb_discard_dist)) {\n\tint discard_seq;\n\n\tdiscard_seq = jb->jb_discard_ref + jb->jb_discard_dist;\n\tif (discard_seq < jb_framelist_origin(&jb->jb_framelist))\n\t    discard_seq = jb_framelist_origin(&jb->jb_framelist);\n\n\tjb_framelist_discard(&jb->jb_framelist, discard_seq);\n\n\tTRACE__((jb->jb_name.ptr,\n\t\t\"Discard #%d: ref=#%d dist=%d orig=%d size=%d/%d \"\n\t\t\"burst=%d/%d\",\n\t\tdiscard_seq,\n\t\tjb->jb_discard_ref,\n\t\tjb->jb_discard_dist,\n\t\tjb_framelist_origin(&jb->jb_framelist),\n\t\tcur_size,\n\t\tjb_framelist_size(&jb->jb_framelist),\n\t\tjb->jb_eff_level,\n\t\tburst_level));\n\n\t/* Update discard reference */\n\tjb->jb_discard_ref = discard_seq;\n    }\n}\n\n\nPJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper)\n{\n    if(jb->jb_last_op != oper) {\n\tjb->jb_last_op = oper;\n\n\tif (jb->jb_status == JB_STATUS_INITIALIZING) {\n\t    /* Switch status 'initializing' -> 'processing' after some OP\n\t     * switch cycles and current OP is GET (burst level is calculated\n\t     * based on PUT burst), so burst calculation is guaranted to be\n\t     * performed right after the status switching.\n\t     */\n\t    if (++jb->jb_init_cycle_cnt >= INIT_CYCLE && oper == JB_OP_GET) {\n\t\tjb->jb_status = JB_STATUS_PROCESSING;\n\t\t/* To make sure the burst calculation will be done right after\n\t\t * this, adjust burst level if it exceeds max burst level.\n\t\t */\n\t\tjb->jb_level = PJ_MIN(jb->jb_level, jb->jb_max_burst);\n\t    } else {\n\t\tjb->jb_level = 0;\n\t\treturn;\n\t    }\n\t}\n\n\t/* Perform jitter calculation based on PUT burst-level only, since\n\t * GET burst-level may not be accurate, e.g: when VAD is active.\n\t * Note that when burst-level is too big, i.e: exceeds jb_max_burst,\n\t * the GET op may be idle, in this case, we better skip the jitter\n\t * calculation.\n\t */\n\tif (oper == JB_OP_GET && jb->jb_level <= jb->jb_max_burst)\n\t    jbuf_calculate_jitter(jb);\n\n\tjb->jb_level = 0;\n    }\n\n    /* Call discard algorithm */\n    if (jb->jb_status == JB_STATUS_PROCESSING && jb->jb_discard_algo) {\n\t(*jb->jb_discard_algo)(jb);\n    }\n}\n\nPJ_DEF(void) pjmedia_jbuf_put_frame( pjmedia_jbuf *jb,\n\t\t\t\t     const void *frame,\n\t\t\t\t     pj_size_t frame_size,\n\t\t\t\t     int frame_seq)\n{\n    pjmedia_jbuf_put_frame3(jb, frame, frame_size, 0, frame_seq, 0, NULL);\n}\n\nPJ_DEF(void) pjmedia_jbuf_put_frame2(pjmedia_jbuf *jb,\n\t\t\t\t     const void *frame,\n\t\t\t\t     pj_size_t frame_size,\n\t\t\t\t     pj_uint32_t bit_info,\n\t\t\t\t     int frame_seq,\n\t\t\t\t     pj_bool_t *discarded)\n{\n    pjmedia_jbuf_put_frame3(jb, frame, frame_size, bit_info, frame_seq, 0,\n\t\t\t    discarded);\n}\n\nPJ_DEF(void) pjmedia_jbuf_put_frame3(pjmedia_jbuf *jb,\n\t\t\t\t     const void *frame,\n\t\t\t\t     pj_size_t frame_size,\n\t\t\t\t     pj_uint32_t bit_info,\n\t\t\t\t     int frame_seq,\n\t\t\t\t     pj_uint32_t ts,\n\t\t\t\t     pj_bool_t *discarded)\n{\n    pj_size_t min_frame_size;\n    int new_size, cur_size;\n    pj_status_t status;\n\n    cur_size = jb_framelist_eff_size(&jb->jb_framelist);\n\n    /* Attempt to store the frame */\n    min_frame_size = PJ_MIN(frame_size, jb->jb_frame_size);\n    status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame,\n\t\t\t\t (unsigned)min_frame_size, bit_info, ts,\n\t\t\t\t PJMEDIA_JB_NORMAL_FRAME);\n\n    /* Jitter buffer is full, remove some older frames */\n    while (status == PJ_ETOOMANY) {\n\tint distance;\n\tunsigned removed;\n\n\t/* Remove as few as possible just to make this frame in. Note that\n\t * the cases of seq-jump, out-of-order, and seq restart should have\n\t * been handled/normalized by previous call of jb_framelist_put_at().\n\t * So we're confident about 'distance' value here.\n\t */\n\tdistance = (frame_seq - jb_framelist_origin(&jb->jb_framelist)) -\n\t\t   (int)jb->jb_max_count + 1;\n\tpj_assert(distance > 0);\n\n\tremoved = jb_framelist_remove_head(&jb->jb_framelist, distance);\n\tstatus = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame,\n\t\t\t\t     (unsigned)min_frame_size, bit_info, ts,\n\t\t\t\t     PJMEDIA_JB_NORMAL_FRAME);\n\n\tjb->jb_discard += removed;\n    }\n\n    /* Get new JB size after PUT */\n    new_size = jb_framelist_eff_size(&jb->jb_framelist);\n\n    /* Return the flag if this frame is discarded */\n    if (discarded)\n\t*discarded = (status != PJ_SUCCESS);\n\n    if (status == PJ_SUCCESS) {\n\tif (jb->jb_prefetching) {\n\t    TRACE__((jb->jb_name.ptr, \"PUT prefetch_cnt=%d/%d\",\n\t\t     new_size, jb->jb_prefetch));\n\t    if (new_size >= jb->jb_prefetch)\n\t\tjb->jb_prefetching = PJ_FALSE;\n\t}\n\tjb->jb_level += (new_size > cur_size ? new_size-cur_size : 1);\n\tjbuf_update(jb, JB_OP_PUT);\n    } else\n\tjb->jb_discard++;\n}\n\n/*\n * Get frame from jitter buffer.\n */\nPJ_DEF(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb,\n\t\t\t\t     void *frame,\n\t\t\t\t     char *p_frame_type)\n{\n    pjmedia_jbuf_get_frame3(jb, frame, NULL, p_frame_type, NULL,\n\t\t\t    NULL, NULL);\n}\n\n/*\n * Get frame from jitter buffer.\n */\nPJ_DEF(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb,\n\t\t\t\t     void *frame,\n\t\t\t\t     pj_size_t *size,\n\t\t\t\t     char *p_frame_type,\n\t\t\t\t     pj_uint32_t *bit_info)\n{\n    pjmedia_jbuf_get_frame3(jb, frame, size, p_frame_type, bit_info,\n\t\t\t    NULL, NULL);\n}\n\n/*\n * Get frame from jitter buffer.\n */\nPJ_DEF(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb,\n\t\t\t\t     void *frame,\n\t\t\t\t     pj_size_t *size,\n\t\t\t\t     char *p_frame_type,\n\t\t\t\t     pj_uint32_t *bit_info,\n\t\t\t\t     pj_uint32_t *ts,\n\t\t\t\t     int *seq)\n{\n    if (jb->jb_prefetching) {\n\n\t/* Can't return frame because jitter buffer is filling up\n\t * minimum prefetch.\n\t */\n\n\t//pj_bzero(frame, jb->jb_frame_size);\n\t*p_frame_type = PJMEDIA_JB_ZERO_PREFETCH_FRAME;\n\tif (size)\n\t    *size = 0;\n\n\tTRACE__((jb->jb_name.ptr, \"GET prefetch_cnt=%d/%d\",\n\t\t jb_framelist_eff_size(&jb->jb_framelist), jb->jb_prefetch));\n\n\tjb->jb_empty++;\n\n    } else {\n\n\tpjmedia_jb_frame_type ftype = PJMEDIA_JB_NORMAL_FRAME;\n\tpj_bool_t res;\n\n\t/* Try to retrieve a frame from frame list */\n\tres = jb_framelist_get(&jb->jb_framelist, frame, size, &ftype,\n\t\t\t       bit_info, ts, seq);\n\tif (res) {\n\t    /* We've successfully retrieved a frame from the frame list, but\n\t     * the frame could be a blank frame!\n\t     */\n\t    if (ftype == PJMEDIA_JB_NORMAL_FRAME) {\n\t\t*p_frame_type = PJMEDIA_JB_NORMAL_FRAME;\n\t    } else {\n\t\t*p_frame_type = PJMEDIA_JB_MISSING_FRAME;\n\t\tjb->jb_lost++;\n\t    }\n\n\t    /* Store delay history at the first GET */\n\t    if (jb->jb_last_op == JB_OP_PUT) {\n\t\tunsigned cur_size;\n\n\t\t/* We've just retrieved one frame, so add one to cur_size */\n\t\tcur_size = jb_framelist_eff_size(&jb->jb_framelist) + 1;\n\t\tpj_math_stat_update(&jb->jb_delay,\n\t\t\t\t    cur_size*jb->jb_frame_ptime);\n\t    }\n\t} else {\n\t    /* Jitter buffer is empty */\n\t    if (jb->jb_prefetch)\n\t\tjb->jb_prefetching = PJ_TRUE;\n\n\t    //pj_bzero(frame, jb->jb_frame_size);\n\t    *p_frame_type = PJMEDIA_JB_ZERO_EMPTY_FRAME;\n\t    if (size)\n\t\t*size = 0;\n\n\t    jb->jb_empty++;\n\t}\n    }\n\n    jb->jb_level++;\n    jbuf_update(jb, JB_OP_GET);\n}\n\n/*\n * Get jitter buffer state.\n */\nPJ_DEF(pj_status_t) pjmedia_jbuf_get_state( const pjmedia_jbuf *jb,\n\t\t\t\t\t    pjmedia_jb_state *state )\n{\n    PJ_ASSERT_RETURN(jb && state, PJ_EINVAL);\n\n    state->frame_size = (unsigned)jb->jb_frame_size;\n    state->min_prefetch = jb->jb_min_prefetch;\n    state->max_prefetch = jb->jb_max_prefetch;\n\n    state->burst = jb->jb_eff_level;\n    state->prefetch = jb->jb_prefetch;\n    state->size = jb_framelist_eff_size(&jb->jb_framelist);\n\n    state->avg_delay = jb->jb_delay.mean;\n    state->min_delay = jb->jb_delay.min;\n    state->max_delay = jb->jb_delay.max;\n    state->dev_delay = pj_math_stat_get_stddev(&jb->jb_delay);\n\n    state->avg_burst = jb->jb_burst.mean;\n    state->empty = jb->jb_empty;\n    state->discard = jb->jb_discard;\n    state->lost = jb->jb_lost;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(void) pjmedia_jbuf_peek_frame( pjmedia_jbuf *jb,\n\t\t\t\t      unsigned offset,\n\t\t\t\t      const void **frame,\n\t\t\t\t      pj_size_t *size,\n\t\t\t\t      char *p_frm_type,\n\t\t\t\t      pj_uint32_t *bit_info,\n\t\t\t\t      pj_uint32_t *ts,\n\t\t\t\t      int *seq)\n{\n    pjmedia_jb_frame_type ftype;\n    pj_bool_t res;\n\n    res = jb_framelist_peek(&jb->jb_framelist, offset, frame, size, &ftype,\n\t\t\t    bit_info, ts, seq);\n    if (!res)\n\t*p_frm_type = PJMEDIA_JB_ZERO_EMPTY_FRAME;\n    else if (ftype == PJMEDIA_JB_NORMAL_FRAME)\n\t*p_frm_type = PJMEDIA_JB_NORMAL_FRAME;\n    else\n\t*p_frm_type = PJMEDIA_JB_MISSING_FRAME;\n}\n\n\nPJ_DEF(unsigned) pjmedia_jbuf_remove_frame(pjmedia_jbuf *jb,\n\t\t\t\t\t   unsigned frame_cnt)\n{\n    unsigned count, last_discard_num;\n\n    last_discard_num = jb->jb_framelist.discarded_num;\n    count = jb_framelist_remove_head(&jb->jb_framelist, frame_cnt);\n\n    /* Remove some more when there were discarded frames included */\n    while (jb->jb_framelist.discarded_num < last_discard_num) {\n\t/* Calculate frames count to be removed next */\n\tframe_cnt = last_discard_num - jb->jb_framelist.discarded_num;\n\n\t/* Normalize non-discarded frames count just been removed */\n\tcount -= frame_cnt;\n\n\t/* Remove more frames */\n\tlast_discard_num = jb->jb_framelist.discarded_num;\n\tcount += jb_framelist_remove_head(&jb->jb_framelist, frame_cnt);\n    }\n\n    return count;\n}\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/master_port.c",
    "content": "/* $Id: master_port.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/master_port.h>\n#include <pjmedia/clock.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/lock.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\nstruct pjmedia_master_port\n{\n    unsigned\t     options;\n    pjmedia_clock   *clock;\n    pjmedia_port    *u_port;\n    pjmedia_port    *d_port;\n    unsigned\t     buff_size;\n    void\t    *buff;\n    pj_lock_t\t    *lock;\n};\n\n\nstatic void clock_callback(const pj_timestamp *ts, void *user_data);\n\n\n/*\n * Create a master port.\n *\n */\nPJ_DEF(pj_status_t) pjmedia_master_port_create( pj_pool_t *pool,\n\t\t\t\t\t\tpjmedia_port *u_port,\n\t\t\t\t\t\tpjmedia_port *d_port,\n\t\t\t\t\t\tunsigned options,\n\t\t\t\t\t\tpjmedia_master_port **p_m)\n{\n    pjmedia_master_port *m;\n    unsigned clock_rate;\n    unsigned channel_count;\n    unsigned samples_per_frame;\n    unsigned bytes_per_frame;\n    pjmedia_audio_format_detail *u_afd, *d_afd;\n    pj_status_t status;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(pool && u_port && d_port && p_m, PJ_EINVAL);\n\n    u_afd = pjmedia_format_get_audio_format_detail(&u_port->info.fmt, PJ_TRUE);\n    d_afd = pjmedia_format_get_audio_format_detail(&d_port->info.fmt, PJ_TRUE);\n\n    /* Both ports MUST have equal clock rate */\n    PJ_ASSERT_RETURN(u_afd->clock_rate == d_afd->clock_rate,\n\t\t     PJMEDIA_ENCCLOCKRATE);\n\n    /* Both ports MUST have equal samples per frame */\n    PJ_ASSERT_RETURN(PJMEDIA_PIA_SPF(&u_port->info)==\n\t\t\tPJMEDIA_PIA_SPF(&d_port->info),\n\t\t     PJMEDIA_ENCSAMPLESPFRAME);\n\n    /* Both ports MUST have equal channel count */\n    PJ_ASSERT_RETURN(u_afd->channel_count == d_afd->channel_count,\n\t\t     PJMEDIA_ENCCHANNEL);\n\n\n    /* Get clock_rate and samples_per_frame from one of the port. */\n    clock_rate = u_afd->clock_rate;\n    samples_per_frame = PJMEDIA_PIA_SPF(&u_port->info);\n    channel_count = u_afd->channel_count;\n\n\n    /* Get the bytes_per_frame value, to determine the size of the\n     * buffer. We take the larger size of the two ports.\n     */\n    bytes_per_frame = PJMEDIA_AFD_AVG_FSZ(u_afd);\n    if (PJMEDIA_AFD_AVG_FSZ(d_afd) > bytes_per_frame)\n\tbytes_per_frame = PJMEDIA_AFD_AVG_FSZ(d_afd);\n\n\n    /* Create the master port instance */\n    m = PJ_POOL_ZALLOC_T(pool, pjmedia_master_port);\n    m->options = options;\n    m->u_port = u_port;\n    m->d_port = d_port;\n\n    \n    /* Create buffer */\n    m->buff_size = bytes_per_frame;\n    m->buff = pj_pool_alloc(pool, m->buff_size);\n    if (!m->buff)\n\treturn PJ_ENOMEM;\n\n    /* Create lock object */\n    status = pj_lock_create_simple_mutex(pool, \"mport\", &m->lock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Create media clock */\n    status = pjmedia_clock_create(pool, clock_rate, channel_count, \n\t\t\t\t  samples_per_frame, options, &clock_callback,\n\t\t\t\t  m, &m->clock);\n    if (status != PJ_SUCCESS) {\n\tpj_lock_destroy(m->lock);\n\treturn status;\n    }\n\n    /* Done */\n    *p_m = m;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Start the media flow.\n */\nPJ_DEF(pj_status_t) pjmedia_master_port_start(pjmedia_master_port *m)\n{\n    PJ_ASSERT_RETURN(m && m->clock, PJ_EINVAL);\n    PJ_ASSERT_RETURN(m->u_port && m->d_port, PJ_EINVALIDOP);\n\n    return pjmedia_clock_start(m->clock);\n}\n\n\n/*\n * Stop the media flow.\n */\nPJ_DEF(pj_status_t) pjmedia_master_port_stop(pjmedia_master_port *m)\n{\n    PJ_ASSERT_RETURN(m && m->clock, PJ_EINVAL);\n    \n    return pjmedia_clock_stop(m->clock);\n}\n\n\n/* Poll the master port clock */\nPJ_DEF(pj_bool_t) pjmedia_master_port_wait( pjmedia_master_port *m,\n\t\t\t\t\t    pj_bool_t wait,\n\t\t\t\t\t    pj_timestamp *ts)\n{\n    PJ_ASSERT_RETURN(m && m->clock, PJ_FALSE);\n\n    return pjmedia_clock_wait(m->clock, wait, ts);\n}\n\n/*\n * Callback to be called for each clock ticks.\n */\nstatic void clock_callback(const pj_timestamp *ts, void *user_data)\n{\n    pjmedia_master_port *m = (pjmedia_master_port*) user_data;\n    pjmedia_frame frame;\n    pj_status_t status;\n\n    \n    /* Lock access to ports. */\n    pj_lock_acquire(m->lock);\n\n    /* Get frame from upstream port and pass it to downstream port */\n    pj_bzero(&frame, sizeof(frame));\n    frame.buf = m->buff;\n    frame.size = m->buff_size;\n    frame.timestamp.u64 = ts->u64;\n\n    status = pjmedia_port_get_frame(m->u_port, &frame);\n    if (status != PJ_SUCCESS)\n\tframe.type = PJMEDIA_FRAME_TYPE_NONE;\n\n    status = pjmedia_port_put_frame(m->d_port, &frame);\n\n    /* Get frame from downstream port and pass it to upstream port */\n    pj_bzero(&frame, sizeof(frame));\n    frame.buf = m->buff;\n    frame.size = m->buff_size;\n    frame.timestamp.u64 = ts->u64;\n\n    status = pjmedia_port_get_frame(m->d_port, &frame);\n    if (status != PJ_SUCCESS)\n\tframe.type = PJMEDIA_FRAME_TYPE_NONE;\n\n    status = pjmedia_port_put_frame(m->u_port, &frame);\n\n    /* Release lock */\n    pj_lock_release(m->lock);\n}\n\n\n/*\n * Change the upstream port.\n */\nPJ_DEF(pj_status_t) pjmedia_master_port_set_uport(pjmedia_master_port *m,\n\t\t\t\t\t\t     pjmedia_port *port)\n{\n    PJ_ASSERT_RETURN(m && port, PJ_EINVAL);\n\n    /* Only supports audio for now */\n    PJ_ASSERT_RETURN(port->info.fmt.type==PJMEDIA_TYPE_AUDIO, PJ_ENOTSUP);\n\n    /* If we have downstream port, make sure they have matching samples per\n     * frame.\n     */\n    if (m->d_port) {\n\tPJ_ASSERT_RETURN(\n\t    PJMEDIA_PIA_PTIME(&port->info) ==\n\t\tPJMEDIA_PIA_PTIME(&m->d_port->info),\n\t    PJMEDIA_ENCSAMPLESPFRAME\n\t);\n    }\n\n    pj_lock_acquire(m->lock);\n\n    m->u_port = port;\n\n    pj_lock_release(m->lock);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the upstream port.\n */\nPJ_DEF(pjmedia_port*) pjmedia_master_port_get_uport(pjmedia_master_port*m)\n{\n    PJ_ASSERT_RETURN(m, NULL);\n    return m->u_port;\n}\n\n\n/*\n * Change the downstream port.\n */\nPJ_DEF(pj_status_t) pjmedia_master_port_set_dport(pjmedia_master_port *m,\n\t\t\t\t\t\t  pjmedia_port *port)\n{\n    PJ_ASSERT_RETURN(m && port, PJ_EINVAL);\n\n    /* Only supports audio for now */\n    PJ_ASSERT_RETURN(port->info.fmt.type==PJMEDIA_TYPE_AUDIO, PJ_ENOTSUP);\n\n    /* If we have upstream port, make sure they have matching samples per\n     * frame.\n     */\n    if (m->u_port) {\n\tPJ_ASSERT_RETURN(\n\t    PJMEDIA_PIA_PTIME(&port->info) ==\n\t\t    PJMEDIA_PIA_PTIME(&m->u_port->info),\n\t    PJMEDIA_ENCSAMPLESPFRAME\n\t);\n    }\n\n    pj_lock_acquire(m->lock);\n\n    m->d_port = port;\n\n    pj_lock_release(m->lock);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the downstream port.\n */\nPJ_DEF(pjmedia_port*) pjmedia_master_port_get_dport(pjmedia_master_port*m)\n{\n    PJ_ASSERT_RETURN(m, NULL);\n    return m->d_port;\n}\n\n\n/*\n * Destroy the master port, and optionally destroy the u_port and \n * d_port ports.\n */\nPJ_DEF(pj_status_t) pjmedia_master_port_destroy(pjmedia_master_port *m,\n\t\t\t\t\t\tpj_bool_t destroy_ports)\n{\n    PJ_ASSERT_RETURN(m, PJ_EINVAL);\n\n    if (m->clock) {\n\tpjmedia_clock_destroy(m->clock);\n\tm->clock = NULL;\n    }\n\n    if (m->u_port && destroy_ports) {\n\tpjmedia_port_destroy(m->u_port);\n\tm->u_port = NULL;\n    }\n\n    if (m->d_port && destroy_ports) {\n\tpjmedia_port_destroy(m->d_port);\n\tm->d_port = NULL;\n    }\n\n    if (m->lock) {\n\tpj_lock_destroy(m->lock);\n\tm->lock = NULL;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/mem_capture.c",
    "content": "/* $Id: mem_capture.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/mem_port.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/pool.h>\n\n\n#define THIS_FILE\t    \"mem_capture.c\"\n\n#define SIGNATURE\t    PJMEDIA_SIG_PORT_MEM_CAPTURE\n#define BYTES_PER_SAMPLE    2\n\nstruct mem_rec\n{\n    pjmedia_port     base;\n\n    unsigned\t     options;\n\n    char\t    *buffer;\n    pj_size_t\t     buf_size;\n    char\t    *write_pos;\n\n    pj_bool_t        eof;\n    void\t    *user_data;\n    pj_status_t    (*cb)(pjmedia_port *port,\n\t\t\t void *user_data);\n};\n\n\nstatic pj_status_t rec_put_frame(pjmedia_port *this_port, \n\t\t\t\t pjmedia_frame *frame);\nstatic pj_status_t rec_get_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame);\nstatic pj_status_t rec_on_destroy(pjmedia_port *this_port);\n\n\nPJ_DEF(pj_status_t) pjmedia_mem_capture_create( pj_pool_t *pool,\n\t\t\t\t\t\tvoid *buffer,\n\t\t\t\t\t\tpj_size_t size,\n\t\t\t\t\t\tunsigned clock_rate,\n\t\t\t\t\t\tunsigned channel_count,\n\t\t\t\t\t\tunsigned samples_per_frame,\n\t\t\t\t\t\tunsigned bits_per_sample,\n\t\t\t\t\t\tunsigned options,\n\t\t\t\t\t\tpjmedia_port **p_port)\n{\n    struct mem_rec *rec;\n    const pj_str_t name = { \"memrec\", 6 };\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(pool && buffer && size && clock_rate && channel_count &&\n\t\t     samples_per_frame && bits_per_sample && p_port,\n\t\t     PJ_EINVAL);\n\n    /* Can only support 16bit PCM */\n    PJ_ASSERT_RETURN(bits_per_sample == 16, PJ_EINVAL);\n\n\n    rec = PJ_POOL_ZALLOC_T(pool, struct mem_rec);\n    PJ_ASSERT_RETURN(rec != NULL, PJ_ENOMEM);\n\n    /* Create the rec */\n    pjmedia_port_info_init(&rec->base.info, &name, SIGNATURE,\n\t\t\t   clock_rate, channel_count, bits_per_sample, \n\t\t\t   samples_per_frame);\n\n\n    rec->base.put_frame = &rec_put_frame;\n    rec->base.get_frame = &rec_get_frame;\n    rec->base.on_destroy = &rec_on_destroy;\n\n\n    /* Save the buffer */\n    rec->buffer = rec->write_pos = (char*)buffer;\n    rec->buf_size = size;\n\n    /* Options */\n    rec->options = options;\n\n    *p_port = &rec->base;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Register a callback to be called when the file reading has reached the\n * end of buffer.\n */\nPJ_DEF(pj_status_t) pjmedia_mem_capture_set_eof_cb( pjmedia_port *port,\n\t\t\t\tvoid *user_data,\n\t\t\t\tpj_status_t (*cb)(pjmedia_port *port,\n\t\t\t\t\t\t  void *usr_data))\n{\n    struct mem_rec *rec;\n\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE,\n\t\t     PJ_EINVALIDOP);\n\n    rec = (struct mem_rec*) port;\n    rec->user_data = user_data;\n    rec->cb = cb;\n\n    return PJ_SUCCESS;\n} \n\n\n/* Get current buffer size */\nPJ_DEF(pj_size_t) pjmedia_mem_capture_get_size(pjmedia_port *port)\n{\n    struct mem_rec *rec;\n\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE,\n                     0);\n\n    rec = (struct mem_rec*) port;\n    if (rec->eof){\n        return rec->buf_size;\n    }\n    return rec->write_pos - rec->buffer;\n}\n\n\nstatic pj_status_t rec_put_frame( pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame)\n{\n    struct mem_rec *rec;\n    char *endpos;\n    pj_size_t size_written;\n\n    PJ_ASSERT_RETURN(this_port->info.signature == SIGNATURE,\n\t\t     PJ_EINVALIDOP);\n\n    rec = (struct mem_rec*) this_port;\n\n    if (rec->eof) {\n\treturn PJ_EEOF;\n    }\n \n    size_written = 0;\n    endpos = rec->buffer + rec->buf_size;\n\n    while (size_written < frame->size) {\n\tpj_size_t max;\n\t\n\tmax = frame->size - size_written;\n\tif ((endpos - rec->write_pos) < (int)max)\n\t    max = endpos - rec->write_pos;\n\t\n\tpj_memcpy(rec->write_pos, ((char*)frame->buf)+size_written, max);\n\tsize_written += max;\n\trec->write_pos += max;\n\t\n\tpj_assert(rec->write_pos <= endpos);\n\t\n        if (rec->write_pos == endpos) {\n\t    \n\t    /* Rewind */\n\t    rec->write_pos = rec->buffer;\n\t    \n\t    /* Call callback, if any */\n            if (rec->cb) {\n\t\tpj_status_t status;\n\t\t\n\t\trec->eof = PJ_TRUE;\n\t\tstatus = (*rec->cb)(this_port, rec->user_data);\n\t\tif (status != PJ_SUCCESS) {\n\t\t    /* Must not access recorder from here on. It may be\n\t\t     * destroyed by application.\n\t\t     */\n                    return status;\n\t\t}\n\t\trec->eof = PJ_FALSE;\n\t    }\n        } \n    }\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t rec_get_frame( pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame)\n{\n    PJ_ASSERT_RETURN(this_port->info.signature == SIGNATURE,\n\t\t     PJ_EINVALIDOP);\n\n    PJ_UNUSED_ARG(this_port);\n\n    frame->size = 0;\n    frame->type = PJMEDIA_FRAME_TYPE_NONE;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t rec_on_destroy(pjmedia_port *this_port)\n{\n    /* Call callback if data was captured\n     * and we're not in the callback already.\n     */\n    struct mem_rec *rec;\n\n    PJ_ASSERT_RETURN(this_port->info.signature == SIGNATURE,\n                     PJ_EINVALIDOP);\n\n    rec = (struct mem_rec*) this_port;\n\n    if(rec->cb && PJ_FALSE == rec->eof) {\n\trec->eof = PJ_TRUE;\n        (*rec->cb)(this_port, rec->user_data);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/mem_player.c",
    "content": "/* $Id: mem_player.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/mem_port.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/pool.h>\n\n\n#define THIS_FILE\t    \"mem_player.c\"\n\n#define SIGNATURE\t    PJMEDIA_SIG_PORT_MEM_PLAYER\n#define BYTES_PER_SAMPLE    2\n\nstruct mem_player\n{\n    pjmedia_port     base;\n\n    unsigned\t     options;\n    pj_timestamp     timestamp;\n\n    char\t    *buffer;\n    pj_size_t\t     buf_size;\n    char\t    *read_pos;\n\n    pj_bool_t\t     eof;\n    void\t    *user_data;\n    pj_status_t    (*cb)(pjmedia_port *port,\n\t\t\t void *user_data);\n\n};\n\n\nstatic pj_status_t mem_put_frame(pjmedia_port *this_port, \n\t\t\t\t pjmedia_frame *frame);\nstatic pj_status_t mem_get_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame);\nstatic pj_status_t mem_on_destroy(pjmedia_port *this_port);\n\n\nPJ_DEF(pj_status_t) pjmedia_mem_player_create( pj_pool_t *pool,\n\t\t\t\t\t       const void *buffer,\n\t\t\t\t\t       pj_size_t size,\n\t\t\t\t\t       unsigned clock_rate,\n\t\t\t\t\t       unsigned channel_count,\n\t\t\t\t\t       unsigned samples_per_frame,\n\t\t\t\t\t       unsigned bits_per_sample,\n\t\t\t\t\t       unsigned options,\n\t\t\t\t\t       pjmedia_port **p_port )\n{\n    struct mem_player *port;\n    pj_str_t name = pj_str(\"memplayer\");\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(pool && buffer && size && clock_rate && channel_count &&\n\t\t     samples_per_frame && bits_per_sample && p_port,\n\t\t     PJ_EINVAL);\n\n    /* Can only support 16bit PCM */\n    PJ_ASSERT_RETURN(bits_per_sample == 16, PJ_EINVAL);\n\n\n    port = PJ_POOL_ZALLOC_T(pool, struct mem_player);\n    PJ_ASSERT_RETURN(port != NULL, PJ_ENOMEM);\n\n    /* Create the port */\n    pjmedia_port_info_init(&port->base.info, &name, SIGNATURE, clock_rate,\n\t\t\t   channel_count, bits_per_sample, samples_per_frame);\n\n    port->base.put_frame = &mem_put_frame;\n    port->base.get_frame = &mem_get_frame;\n    port->base.on_destroy = &mem_on_destroy;\n\n\n    /* Save the buffer */\n    port->buffer = port->read_pos = (char*)buffer;\n    port->buf_size = size;\n\n    /* Options */\n    port->options = options;\n\n    *p_port = &port->base;\n\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Register a callback to be called when the file reading has reached the\n * end of buffer.\n */\nPJ_DEF(pj_status_t) pjmedia_mem_player_set_eof_cb( pjmedia_port *port,\n\t\t\t       void *user_data,\n\t\t\t       pj_status_t (*cb)(pjmedia_port *port,\n\t\t\t\t\t\t void *usr_data))\n{\n    struct mem_player *player;\n\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE,\n\t\t     PJ_EINVALIDOP);\n\n    player = (struct mem_player*) port;\n    player->user_data = user_data;\n    player->cb = cb;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t mem_put_frame( pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame)\n{\n    PJ_UNUSED_ARG(this_port);\n    PJ_UNUSED_ARG(frame);\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t mem_get_frame( pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame)\n{\n    struct mem_player *player;\n    char *endpos;\n    pj_size_t size_needed, size_written;\n\n    PJ_ASSERT_RETURN(this_port->info.signature == SIGNATURE,\n\t\t     PJ_EINVALIDOP);\n\n    player = (struct mem_player*) this_port;\n\n    if (player->eof) {\n\tpj_status_t status = PJ_SUCCESS;\n\n\t/* Call callback, if any */\n\tif (player->cb)\n\t    status = (*player->cb)(this_port, player->user_data);\n\n\t/* If callback returns non PJ_SUCCESS or 'no loop' is specified\n\t * return immediately (and don't try to access player port since\n\t * it might have been destroyed by the callback).\n\t */\n\tif ((status != PJ_SUCCESS) || (player->options & PJMEDIA_MEM_NO_LOOP)) {\n\t    frame->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    return PJ_EEOF;\n\t}\n\t\n\tplayer->eof = PJ_FALSE;\n    }\n\n    size_needed = PJMEDIA_PIA_AVG_FSZ(&this_port->info);\n    size_written = 0;\n    endpos = player->buffer + player->buf_size;\n\n    while (size_written < size_needed) {\n\tchar *dst = ((char*)frame->buf) + size_written;\n\tpj_size_t max;\n\t\n\tmax = size_needed - size_written;\n\tif (endpos - player->read_pos < (int)max)\n\t    max = endpos - player->read_pos;\n\n\tpj_memcpy(dst, player->read_pos, max);\n\tsize_written += max;\n\tplayer->read_pos += max;\n\n\tpj_assert(player->read_pos <= endpos);\n\n\tif (player->read_pos == endpos) {\n\t    /* Set EOF flag */\n\t    player->eof = PJ_TRUE;\n\t    /* Reset read pointer */\n\t    player->read_pos = player->buffer;\n\n\t    /* Pad with zeroes then return for no looped play */\n\t    if (player->options & PJMEDIA_MEM_NO_LOOP) {\n\t\tpj_size_t null_len;\n\n    \t\tnull_len = size_needed - size_written;\n\t\tpj_bzero(dst + max, null_len);\n\t\tbreak;\n\t    }\n\t}\n    }\n\n    frame->size = PJMEDIA_PIA_AVG_FSZ(&this_port->info);\n    frame->timestamp.u64 = player->timestamp.u64;\n    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\n    player->timestamp.u64 += PJMEDIA_PIA_SPF(&this_port->info);\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t mem_on_destroy(pjmedia_port *this_port)\n{\n    PJ_ASSERT_RETURN(this_port->info.signature == SIGNATURE,\n\t\t     PJ_EINVALIDOP);\n\n    /* Destroy signature */\n    this_port->info.signature = 0;\n\n    return PJ_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/mixer_port.c",
    "content": "/*\n * Copyright (C) 2010 AG Projects\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <string.h>\n\n#include <pjmedia/mixer_port.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n#define SIGNATURE   PJMEDIA_SIG_PORT_MIXER\n#define MIN(a, b)   ((a)>(b)?(b):(a))\n\nstruct mixer_port\n{\n    pjmedia_port        base;\n    pjmedia_frame_type  last_frame_type;\n    pj_size_t           last_frame_size;\n    pj_timestamp        last_frame_timestamp;\n    pj_int16_t*         buffer;\n    pj_size_t           buffer_size;\n};\n\nstatic pj_status_t mixer_get_frame(pjmedia_port *port, pjmedia_frame *frame);\nstatic pj_status_t mixer_put_frame(pjmedia_port *port, pjmedia_frame *frame);\nstatic pj_status_t mixer_on_destroy(pjmedia_port *port);\n\n\nPJ_DEF(pj_status_t) pjmedia_mixer_port_create(pj_pool_t *pool,\n                                              unsigned sampling_rate,\n                                              unsigned channel_count,\n                                              unsigned samples_per_frame,\n                                              unsigned bits_per_sample,\n                                              pjmedia_port **p_port)\n{\n    struct mixer_port *port;\n    const pj_str_t name = pj_str(\"mixer-port\");\n\n    PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL);\n\n    port = PJ_POOL_ZALLOC_T(pool, struct mixer_port);\n    PJ_ASSERT_RETURN(port != NULL, PJ_ENOMEM);\n\n    pjmedia_port_info_init(&port->base.info, &name, SIGNATURE, sampling_rate,\n                           channel_count, bits_per_sample, samples_per_frame);\n\n    port->base.get_frame = &mixer_get_frame;\n    port->base.put_frame = &mixer_put_frame;\n    port->base.on_destroy = &mixer_on_destroy;\n    port->last_frame_type = PJMEDIA_FRAME_TYPE_NONE;\n    port->last_frame_size = 0;\n    port->last_frame_timestamp.u64 = 0;\n    port->buffer = (pj_int16_t*) pj_pool_calloc(pool, samples_per_frame, sizeof(pj_int16_t));\n    port->buffer_size = sizeof(pj_int16_t) * samples_per_frame;\n\n    *p_port = &port->base;\n\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Put frame to file.\n */\nstatic pj_status_t mixer_put_frame(pjmedia_port *this_port, pjmedia_frame *frame)\n{\n    struct mixer_port* port = (struct mixer_port*) this_port;\n\n    if (!frame->size || frame->type != PJMEDIA_FRAME_TYPE_AUDIO) {\n        port->last_frame_type = PJMEDIA_FRAME_TYPE_NONE;\n        port->last_frame_size = 0;\n        port->last_frame_timestamp.u64 = 0;\n        return PJ_SUCCESS;\n    }\n\n    PJ_ASSERT_RETURN(frame->size <= port->buffer_size, PJ_EINVAL);\n\n    port->last_frame_type = frame->type;\n    pj_get_timestamp(&port->last_frame_timestamp);\n    port->last_frame_size = MIN(port->buffer_size, frame->size);\n    memcpy(port->buffer, frame->buf, port->last_frame_size);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get frame from file.\n */\nstatic pj_status_t mixer_get_frame(pjmedia_port *this_port, pjmedia_frame *frame)\n{\n    struct mixer_port* port = (struct mixer_port*) this_port;\n    pj_timestamp now;\n    pj_uint32_t frame_age;\n\n    pj_get_timestamp(&now);\n    frame_age = pj_elapsed_usec(&port->last_frame_timestamp, &now);\n\n    if (port->last_frame_timestamp.u64 != 0 && frame_age <= 100000) {\n        frame->type = port->last_frame_type;\n        frame->size = port->last_frame_size;\n        frame->timestamp.u64 = 0;\n        if (port->last_frame_size > 0) {\n            memcpy(frame->buf, port->buffer, port->last_frame_size);\n        }\n    } else {\n        frame->type = PJMEDIA_FRAME_TYPE_NONE;\n        frame->size = 0;\n        frame->timestamp.u64 = 0;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy port.\n */\nstatic pj_status_t mixer_on_destroy(pjmedia_port *this_port)\n{\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/null_port.c",
    "content": "/* $Id: null_port.c 4423 2013-03-06 06:06:17Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/null_port.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n#define SIGNATURE   PJMEDIA_SIG_PORT_NULL\n\nstatic pj_status_t null_get_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame);\nstatic pj_status_t null_put_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame);\nstatic pj_status_t null_on_destroy(pjmedia_port *this_port);\n\n\nPJ_DEF(pj_status_t) pjmedia_null_port_create( pj_pool_t *pool,\n\t\t\t\t\t      unsigned sampling_rate,\n\t\t\t\t\t      unsigned channel_count,\n\t\t\t\t\t      unsigned samples_per_frame,\n\t\t\t\t\t      unsigned bits_per_sample,\n\t\t\t\t\t      pjmedia_port **p_port )\n{\n    pjmedia_port *port;\n    const pj_str_t name = pj_str(\"null-port\");\n\n    PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL);\n\n    port = PJ_POOL_ZALLOC_T(pool, pjmedia_port);\n    PJ_ASSERT_RETURN(port != NULL, PJ_ENOMEM);\n\n    pjmedia_port_info_init(&port->info, &name, SIGNATURE, sampling_rate,\n\t\t\t   channel_count, bits_per_sample, samples_per_frame);\n\n    port->get_frame = &null_get_frame;\n    port->put_frame = &null_put_frame;\n    port->on_destroy = &null_on_destroy;\n\n\n    *p_port = port;\n    \n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Put frame to file.\n */\nstatic pj_status_t null_put_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame)\n{\n    PJ_UNUSED_ARG(this_port);\n    PJ_UNUSED_ARG(frame);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get frame from file.\n */\nstatic pj_status_t null_get_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame)\n{\n    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    frame->size = PJMEDIA_PIA_AVG_FSZ(&this_port->info);\n    frame->timestamp.u32.lo += PJMEDIA_PIA_SPF(&this_port->info);\n    pjmedia_zero_samples((pj_int16_t*)frame->buf, \n\t\t\t  PJMEDIA_PIA_SPF(&this_port->info));\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy port.\n */\nstatic pj_status_t null_on_destroy(pjmedia_port *this_port)\n{\n    PJ_UNUSED_ARG(this_port);\n    return PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/plc_common.c",
    "content": "/* $Id: plc_common.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/plc.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/wsola.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\nstatic void* plc_wsola_create(pj_pool_t*, unsigned c, unsigned f);\nstatic void  plc_wsola_save(void*, pj_int16_t*);\nstatic void  plc_wsola_generate(void*, pj_int16_t*);\n\n/**\n * This struct is used internally to represent a PLC backend.\n */\nstruct plc_alg\n{\n    void* (*plc_create)(pj_pool_t*, unsigned c, unsigned f);\n    void  (*plc_save)(void*, pj_int16_t*);\n    void  (*plc_generate)(void*, pj_int16_t*);\n};\n\n\nstatic struct plc_alg plc_wsola =\n{\n    &plc_wsola_create,\n    &plc_wsola_save,\n    &plc_wsola_generate\n};\n\n\nstruct pjmedia_plc\n{\n    void\t    *obj;\n    struct plc_alg  *op;\n};\n\n\n/*\n * Create PLC session. This function will select the PLC algorithm to\n * use based on the arguments.\n */\nPJ_DEF(pj_status_t) pjmedia_plc_create( pj_pool_t *pool,\n\t\t\t\t\tunsigned clock_rate,\n\t\t\t\t\tunsigned samples_per_frame,\n\t\t\t\t\tunsigned options,\n\t\t\t\t\tpjmedia_plc **p_plc)\n{\n    pjmedia_plc *plc;\n\n    PJ_ASSERT_RETURN(pool && clock_rate && samples_per_frame && p_plc,\n\t\t     PJ_EINVAL);\n    PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(options);\n\n    plc = PJ_POOL_ZALLOC_T(pool, pjmedia_plc);\n\n    plc->op = &plc_wsola;\n    plc->obj = plc->op->plc_create(pool, clock_rate, samples_per_frame);\n\n    *p_plc = plc;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Save a good frame to PLC.\n */\nPJ_DEF(pj_status_t) pjmedia_plc_save( pjmedia_plc *plc,\n\t\t\t\t      pj_int16_t *frame )\n{\n    PJ_ASSERT_RETURN(plc && frame, PJ_EINVAL);\n \n    plc->op->plc_save(plc->obj, frame);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Generate a replacement for lost frame.\n */\nPJ_DEF(pj_status_t) pjmedia_plc_generate( pjmedia_plc *plc,\n\t\t\t\t\t  pj_int16_t *frame )\n{\n    PJ_ASSERT_RETURN(plc && frame, PJ_EINVAL);\n    \n    plc->op->plc_generate(plc->obj, frame);\n    return PJ_SUCCESS;\n}\n\n\n//////////////////////////////////////////////////////////////////////////////\n/*\n * Packet loss concealment based on WSOLA\n */\nstruct wsola_plc\n{\n    pjmedia_wsola   *wsola;\n    pj_bool_t\t     prev_lost;\n};\n\n\nstatic void* plc_wsola_create(pj_pool_t *pool, unsigned clock_rate, \n\t\t\t      unsigned samples_per_frame)\n{\n    struct wsola_plc *o;\n    unsigned flag;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(clock_rate);\n\n    o = PJ_POOL_ZALLOC_T(pool, struct wsola_plc);\n    o->prev_lost = PJ_FALSE;\n\n    flag = PJMEDIA_WSOLA_NO_DISCARD;\n    if (PJMEDIA_WSOLA_PLC_NO_FADING)\n\tflag |= PJMEDIA_WSOLA_NO_FADING;\n\n    status = pjmedia_wsola_create(pool, clock_rate, samples_per_frame, 1,\n\t\t\t\t  flag, &o->wsola);\n    if (status != PJ_SUCCESS)\n\treturn NULL;\n\n    return o;\n}\n\nstatic void plc_wsola_save(void *plc, pj_int16_t *frame)\n{\n    struct wsola_plc *o = (struct wsola_plc*) plc;\n\n    pjmedia_wsola_save(o->wsola, frame, o->prev_lost);\n    o->prev_lost = PJ_FALSE;\n}\n\nstatic void plc_wsola_generate(void *plc, pj_int16_t *frame)\n{\n    struct wsola_plc *o = (struct wsola_plc*) plc;\n    \n    pjmedia_wsola_generate(o->wsola, frame);\n    o->prev_lost = PJ_TRUE;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/port.c",
    "content": "/* $Id: port.c 3893 2011-12-01 10:49:07Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/port.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n\n#define THIS_FILE\t\"port.c\"\n\n\n/**\n * This is an auxiliary function to initialize port info for\n * ports which deal with PCM audio.\n */\nPJ_DEF(pj_status_t) pjmedia_port_info_init( pjmedia_port_info *info,\n\t\t\t\t\t    const pj_str_t *name,\n\t\t\t\t\t    unsigned signature,\n\t\t\t\t\t    unsigned clock_rate,\n\t\t\t\t\t    unsigned channel_count,\n\t\t\t\t\t    unsigned bits_per_sample,\n\t\t\t\t\t    unsigned samples_per_frame)\n{\n#define USEC_IN_SEC (pj_uint64_t)1000000\n    unsigned frame_time_usec, avg_bps;\n\n    pj_bzero(info, sizeof(*info));\n\n    info->signature = signature;\n    info->dir = PJMEDIA_DIR_ENCODING_DECODING;\n    info->name = *name;\n\n    frame_time_usec = (unsigned)(samples_per_frame * USEC_IN_SEC /\n\t\t\t\t channel_count / clock_rate);\n    avg_bps = clock_rate * channel_count * bits_per_sample;\n\n    pjmedia_format_init_audio(&info->fmt, PJMEDIA_FORMAT_L16, clock_rate,\n\t\t\t      channel_count, bits_per_sample, frame_time_usec,\n\t\t\t      avg_bps, avg_bps);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_port_info_init2( pjmedia_port_info *info,\n\t\t\t\t\t     const pj_str_t *name,\n\t\t\t\t\t     unsigned signature,\n\t\t\t\t\t     pjmedia_dir dir,\n\t\t\t\t\t     const pjmedia_format *fmt)\n{\n    pj_bzero(info, sizeof(*info));\n    info->signature = signature;\n    info->dir = dir;\n    info->name = *name;\n\n    pjmedia_format_copy(&info->fmt, fmt);\n\n    return PJ_SUCCESS;\n}\n\n/**\n * Get a clock source from the port.\n */\nPJ_DEF(pjmedia_clock_src *) pjmedia_port_get_clock_src( pjmedia_port *port,\n                                                        pjmedia_dir dir )\n{\n    if (port && port->get_clock_src)\n\treturn port->get_clock_src(port, dir);\n    else\n\treturn NULL;\n}\n\n/**\n * Get a frame from the port (and subsequent downstream ports).\n */\nPJ_DEF(pj_status_t) pjmedia_port_get_frame( pjmedia_port *port,\n\t\t\t\t\t    pjmedia_frame *frame )\n{\n    PJ_ASSERT_RETURN(port && frame, PJ_EINVAL);\n\n    if (port->get_frame)\n\treturn port->get_frame(port, frame);\n    else {\n\tframe->type = PJMEDIA_FRAME_TYPE_NONE;\n\treturn PJ_EINVALIDOP;\n    }\n}\n\n\n/**\n * Put a frame to the port (and subsequent downstream ports).\n */\nPJ_DEF(pj_status_t) pjmedia_port_put_frame( pjmedia_port *port,\n\t\t\t\t\t    pjmedia_frame *frame )\n{\n    PJ_ASSERT_RETURN(port && frame, PJ_EINVAL);\n\n    if (port->put_frame)\n\treturn port->put_frame(port, frame);\n    else\n\treturn PJ_EINVALIDOP;\n}\n\n/**\n * Destroy port (and subsequent downstream ports)\n */\nPJ_DEF(pj_status_t) pjmedia_port_destroy( pjmedia_port *port )\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(port, PJ_EINVAL);\n\n    if (port->on_destroy)\n\tstatus = port->on_destroy(port);\n    else\n\tstatus = PJ_SUCCESS;\n\n    return status;\n}\n\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/resample_libsamplerate.c",
    "content": "/* $Id: resample_libsamplerate.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/resample.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n\n/*\n * HOW TO ACTIVATE LIBSAMPLERATE (a.k.a SRC/Secret Rabbit Code) AS\n * PJMEDIA'S SAMPLE RATE CONVERSION BACKEND\n *\n * See README.txt in third_party/samplerate directory.\n */\n\n\n#if PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_LIBSAMPLERATE\n\n#include \"../../third_party/libsamplerate/src/samplerate.h\"\n\n#define THIS_FILE   \"resample_libsamplerate.c\"\n\n#if defined(_MSC_VER)\n#   ifdef _DEBUG\n#\tpragma comment( lib, \"../../third_party/lib/libsamplerate-i386-win32-vc-debug.lib\")\n#   else\n#\tpragma comment( lib, \"../../third_party/lib/libsamplerate-i386-win32-vc-release.lib\")\n#   endif\n#endif\n\n\nstruct pjmedia_resample\n{\n    SRC_STATE\t*state;\n    unsigned\t in_samples;\n    unsigned\t out_samples;\n    float\t*frame_in, *frame_out;\n    unsigned\t in_extra, out_extra;\n    double\t ratio;\n};\n\n\nPJ_DEF(pj_status_t) pjmedia_resample_create( pj_pool_t *pool,\n\t\t\t\t\t     pj_bool_t high_quality,\n\t\t\t\t\t     pj_bool_t large_filter,\n\t\t\t\t\t     unsigned channel_count,\n\t\t\t\t\t     unsigned rate_in,\n\t\t\t\t\t     unsigned rate_out,\n\t\t\t\t\t     unsigned samples_per_frame,\n\t\t\t\t\t     pjmedia_resample **p_resample)\n{\n    pjmedia_resample *resample;\n    int type, err;\n\n    PJ_ASSERT_RETURN(pool && p_resample && rate_in &&\n\t\t     rate_out && samples_per_frame, PJ_EINVAL);\n\n    resample = PJ_POOL_ZALLOC_T(pool, pjmedia_resample);\n    PJ_ASSERT_RETURN(resample, PJ_ENOMEM);\n\n    /* Select conversion type */\n    if (high_quality) {\n\ttype = large_filter ? SRC_SINC_BEST_QUALITY : SRC_SINC_MEDIUM_QUALITY;\n    } else {\n\ttype = large_filter ? SRC_SINC_FASTEST : SRC_LINEAR;\n    }\n\n    /* Create converter */\n    resample->state = src_new(type, channel_count, &err);\n    if (resample->state == NULL) {\n\tPJ_LOG(4,(THIS_FILE, \"Error creating resample: %s\", \n\t\t  src_strerror(err)));\n\treturn PJMEDIA_ERROR;\n    }\n\n    /* Calculate ratio */\n    resample->ratio = rate_out * 1.0 / rate_in;\n\n    /* Calculate number of samples for input and output */\n    resample->in_samples = samples_per_frame;\n    resample->out_samples = rate_out / (rate_in / samples_per_frame);\n\n    resample->frame_in = (float*) \n\t\t\t pj_pool_calloc(pool, \n\t\t\t\t\tresample->in_samples + 8, \n\t\t\t\t\tsizeof(float));\n\n    resample->frame_out = (float*) \n\t\t\t  pj_pool_calloc(pool, \n\t\t\t\t\t resample->out_samples + 8, \n\t\t\t\t\t sizeof(float));\n\n    /* Set the converter ratio */\n    err = src_set_ratio(resample->state, resample->ratio);\n    if (err != 0) {\n\tPJ_LOG(4,(THIS_FILE, \"Error creating resample: %s\", \n\t\t  src_strerror(err)));\n\treturn PJMEDIA_ERROR;\n    }\n\n    /* Done */\n\n    PJ_LOG(5,(THIS_FILE, \n\t      \"Resample using libsamplerate %s, type=%s (%s), \"\n\t      \"ch=%d, in/out rate=%d/%d\", \n\t      src_get_version(),\n\t      src_get_name(type), src_get_description(type),\n\t      channel_count, rate_in, rate_out));\n\n    *p_resample = resample;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(void) pjmedia_resample_run( pjmedia_resample *resample,\n\t\t\t\t   const pj_int16_t *input,\n\t\t\t\t   pj_int16_t *output )\n{\n    SRC_DATA src_data;\n\n    /* Convert samples to float */\n    src_short_to_float_array(input, resample->frame_in, \n\t\t\t     resample->in_samples);\n\n    if (resample->in_extra) {\n\tunsigned i;\n\n\tfor (i=0; i<resample->in_extra; ++i)\n\t    resample->frame_in[resample->in_samples+i] =\n\t\tresample->frame_in[resample->in_samples-1];\n    }\n\n    /* Prepare SRC_DATA */\n    pj_bzero(&src_data, sizeof(src_data));\n    src_data.data_in = resample->frame_in;\n    src_data.data_out = resample->frame_out;\n    src_data.input_frames = resample->in_samples + resample->in_extra;\n    src_data.output_frames = resample->out_samples + resample->out_extra;\n    src_data.src_ratio = resample->ratio;\n\n    /* Process! */\n    src_process(resample->state, &src_data);\n\n    /* Convert output back to short */\n    src_float_to_short_array(resample->frame_out, output,\n\t\t\t     src_data.output_frames_gen);\n\n    /* Replay last sample if conversion couldn't fill up the whole \n     * frame. This could happen for example with 22050 to 16000 conversion.\n     */\n    if (src_data.output_frames_gen < (int)resample->out_samples) {\n\tunsigned i;\n\n\tif (resample->in_extra < 4)\n\t    resample->in_extra++;\n\n\tfor (i=src_data.output_frames_gen; \n\t     i<resample->out_samples; ++i)\n\t{\n\t    output[i] = output[src_data.output_frames_gen-1];\n\t}\n    }\n}\n\n\nPJ_DEF(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample)\n{\n    PJ_ASSERT_RETURN(resample != NULL, 0);\n    return resample->in_samples;\n}\n\n\nPJ_DEF(void) pjmedia_resample_destroy(pjmedia_resample *resample)\n{\n    PJ_ASSERT_ON_FAIL(resample, return);\n    if (resample->state) {\n\tsrc_delete(resample->state);\n\tresample->state = NULL;\n\n\tPJ_LOG(5,(THIS_FILE, \"Resample destroyed\"));\n    }\n}\n\n#else /* PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_LIBSAMPLERATE */\n\nint pjmedia_libsamplerate_excluded;\n\n#endif\t/* PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_LIBSAMPLERATE */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/resample_port.c",
    "content": "/* $Id: resample_port.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/resample.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n#define BYTES_PER_SAMPLE\t2\n#define SIGNATURE\t\tPJMEDIA_SIG_PORT_RESAMPLE\n\n\nstruct resample_port\n{\n    pjmedia_port\t base;\n    pjmedia_port\t*dn_port;\n    unsigned\t\t options;\n    pjmedia_resample\t*resample_get;\n    pjmedia_resample\t*resample_put;\n    pj_int16_t\t\t*get_buf;\n    pj_int16_t\t\t*put_buf;\n};\n\n\n\nstatic pj_status_t resample_put_frame(pjmedia_port *this_port,\n\t\t\t\t      pjmedia_frame *frame);\nstatic pj_status_t resample_get_frame(pjmedia_port *this_port, \n\t\t\t\t      pjmedia_frame *frame);\nstatic pj_status_t resample_destroy(pjmedia_port *this_port);\n\n\n\nPJ_DEF(pj_status_t) pjmedia_resample_port_create( pj_pool_t *pool,\n\t\t\t\t\t\t  pjmedia_port *dn_port,\n\t\t\t\t\t\t  unsigned clock_rate,\n\t\t\t\t\t\t  unsigned opt,\n\t\t\t\t\t\t  pjmedia_port **p_port  )\n{\n    const pj_str_t name = pj_str(\"resample\");\n    struct resample_port *rport;\n    pjmedia_audio_format_detail *d_afd, *r_afd;\n    pj_status_t status;\n\n    /* Validate arguments. */\n    PJ_ASSERT_RETURN(pool && dn_port && clock_rate && p_port, PJ_EINVAL);\n\n    /* Only supports 16bit samples per frame */\n    PJ_ASSERT_RETURN(PJMEDIA_PIA_BITS(&dn_port->info) == 16, PJMEDIA_ENCBITS);\n\n    d_afd = pjmedia_format_get_audio_format_detail(&dn_port->info.fmt, 1);\n\n    /* Create and initialize port. */\n    rport = PJ_POOL_ZALLOC_T(pool, struct resample_port);\n    PJ_ASSERT_RETURN(rport != NULL, PJ_ENOMEM);\n\n    pjmedia_port_info_init(&rport->base.info, &name, SIGNATURE, clock_rate,\n\t\t           d_afd->channel_count, BYTES_PER_SAMPLE * 8,\n\t\t\t   clock_rate * d_afd->frame_time_usec / 1000000);\n\n    rport->dn_port = dn_port;\n    rport->options = opt;\n\n    r_afd = pjmedia_format_get_audio_format_detail(&rport->base.info.fmt, 1);\n\n    /* Create buffers. \n     * We need separate buffer for get_frame() and put_frame() since\n     * both functions may run simultaneously.\n     */\n    rport->get_buf = (pj_int16_t*)\n\t\t     pj_pool_alloc(pool, PJMEDIA_PIA_AVG_FSZ(&dn_port->info));\n    PJ_ASSERT_RETURN(rport->get_buf != NULL, PJ_ENOMEM);\n\n    rport->put_buf = (pj_int16_t*)\n\t\t     pj_pool_alloc(pool, PJMEDIA_PIA_AVG_FSZ(&dn_port->info));\n    PJ_ASSERT_RETURN(rport->put_buf != NULL, PJ_ENOMEM);\n\n\n    /* Create \"get_frame\" resample */\n    status = pjmedia_resample_create(pool, \n\t\t\t\t     (opt&PJMEDIA_RESAMPLE_USE_LINEAR)==0,\n\t\t\t\t     (opt&PJMEDIA_RESAMPLE_USE_SMALL_FILTER)==0,\n\t\t\t\t     d_afd->channel_count,\n\t\t\t\t     d_afd->clock_rate,\n\t\t\t\t     r_afd->clock_rate,\n\t\t\t\t     PJMEDIA_PIA_SPF(&dn_port->info),\n\t\t\t\t     &rport->resample_get);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Create \"put_frame\" resample */\n    status = pjmedia_resample_create(pool, \n\t\t\t\t     (opt&PJMEDIA_RESAMPLE_USE_LINEAR)==0, \n\t\t\t\t     (opt&PJMEDIA_RESAMPLE_USE_SMALL_FILTER)==0,\n\t\t\t\t     d_afd->channel_count,\n\t\t\t\t     r_afd->clock_rate,\n\t\t\t\t     d_afd->clock_rate,\n\t\t\t\t     PJMEDIA_PIA_SPF(&rport->base.info),\n\t\t\t\t     &rport->resample_put);\n\n    /* Media port interface */\n    rport->base.get_frame = &resample_get_frame;\n    rport->base.put_frame = &resample_put_frame;\n    rport->base.on_destroy = &resample_destroy;\n\n\n    /* Done */\n    *p_port = &rport->base;\n\n    return PJ_SUCCESS;\n}\n\n\n\nstatic pj_status_t resample_put_frame(pjmedia_port *this_port,\n\t\t\t\t      pjmedia_frame *frame)\n{\n    struct resample_port *rport = (struct resample_port*) this_port;\n    pjmedia_frame downstream_frame;\n\n    /* Return if we don't have downstream port. */\n    if (rport->dn_port == NULL) {\n\treturn PJ_SUCCESS;\n    }\n\n    if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) {\n\tpjmedia_resample_run( rport->resample_put, \n\t\t\t      (const pj_int16_t*) frame->buf, \n\t\t\t      rport->put_buf);\n\n\tdownstream_frame.buf = rport->put_buf;\n\tdownstream_frame.size = PJMEDIA_PIA_AVG_FSZ(&rport->dn_port->info);\n    } else {\n\tdownstream_frame.buf = frame->buf;\n\tdownstream_frame.size = frame->size;\n    }\n\n    downstream_frame.type = frame->type;\n    downstream_frame.timestamp.u64 = frame->timestamp.u64;\n\n    return pjmedia_port_put_frame( rport->dn_port, &downstream_frame );\n}\n\n\n\nstatic pj_status_t resample_get_frame(pjmedia_port *this_port, \n\t\t\t\t      pjmedia_frame *frame)\n{\n    struct resample_port *rport = (struct resample_port*) this_port;\n    pjmedia_frame tmp_frame;\n    pj_status_t status;\n\n    /* Return silence if we don't have downstream port */\n    if (rport->dn_port == NULL) {\n\tpj_bzero(frame->buf, frame->size);\n\treturn PJ_SUCCESS;\n    }\n\n    tmp_frame.buf = rport->get_buf;\n    tmp_frame.size = PJMEDIA_PIA_AVG_FSZ(&rport->dn_port->info);\n    tmp_frame.timestamp.u64 = frame->timestamp.u64;\n    tmp_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;\n\n    status = pjmedia_port_get_frame( rport->dn_port, &tmp_frame);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (tmp_frame.type != PJMEDIA_FRAME_TYPE_AUDIO) {\n\tframe->type = tmp_frame.type;\n\tframe->timestamp = tmp_frame.timestamp;\n\t/* Copy whatever returned as long as the buffer size is enough */\n\tframe->size = tmp_frame.size < PJMEDIA_PIA_AVG_FSZ(&rport->base.info) ?\n\t\t      tmp_frame.size : PJMEDIA_PIA_AVG_FSZ(&rport->base.info);\n\tif (tmp_frame.size) {\n\t    pjmedia_copy_samples((pj_int16_t*)frame->buf, \n\t\t\t\t (const pj_int16_t*)tmp_frame.buf, \n\t\t\t\t (unsigned)frame->size >> 1);\n\t}\n\treturn PJ_SUCCESS;\n    }\n\n    pjmedia_resample_run( rport->resample_get, \n\t\t\t  (const pj_int16_t*) tmp_frame.buf, \n\t\t\t  (pj_int16_t*) frame->buf);\n\n    frame->size = PJMEDIA_PIA_AVG_FSZ(&rport->base.info);\n    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t resample_destroy(pjmedia_port *this_port)\n{\n    struct resample_port *rport = (struct resample_port*) this_port;\n\n    if ((rport->options & PJMEDIA_RESAMPLE_DONT_DESTROY_DN)==0) {\n\tpjmedia_port_destroy(rport->dn_port);\n\trport->dn_port = NULL;\n    }\n\n    if (rport->resample_get) {\n\tpjmedia_resample_destroy(rport->resample_get);\n\trport->resample_get = NULL;\n    }\n\n    if (rport->resample_put) {\n\tpjmedia_resample_destroy(rport->resample_put);\n\trport->resample_put = NULL;\n    }\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/resample_resample.c",
    "content": "/* $Id: resample_resample.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pjmedia/resample.h>\n\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n\n\n#if PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_LIBRESAMPLE\n\n#include <third_party/resample/include/resamplesubs.h>\n\n#define THIS_FILE   \"resample.c\"\n\n\n\nstruct pjmedia_resample\n{\n    double\t factor;\t/* Conversion factor = rate_out / rate_in.  */\n    pj_bool_t\t large_filter;\t/* Large filter?\t\t\t    */\n    pj_bool_t\t high_quality;\t/* Not fast?\t\t\t\t    */\n    unsigned\t xoff;\t\t/* History and lookahead size, in samples   */\n    unsigned\t frame_size;\t/* Samples per frame.\t\t\t    */\n    unsigned\t channel_cnt;\t/* Channel count.\t\t\t    */\n\n    /* Buffer for monochannel */\n    pj_int16_t\t*buffer;\t/* Input buffer.\t\t\t    */\n\n    /* Buffer for multichannel */\n    pj_int16_t **in_buffer;\t/* Array of input buffer for each channel.  */\n    pj_int16_t  *tmp_buffer;\t/* Temporary output buffer for processing.  */\n};\n\n\nPJ_DEF(pj_status_t) pjmedia_resample_create( pj_pool_t *pool,\n\t\t\t\t\t     pj_bool_t high_quality,\n\t\t\t\t\t     pj_bool_t large_filter,\n\t\t\t\t\t     unsigned channel_count,\n\t\t\t\t\t     unsigned rate_in,\n\t\t\t\t\t     unsigned rate_out,\n\t\t\t\t\t     unsigned samples_per_frame,\n\t\t\t\t\t     pjmedia_resample **p_resample)\n{\n    pjmedia_resample *resample;\n\n    PJ_ASSERT_RETURN(pool && p_resample && rate_in &&\n\t\t     rate_out && samples_per_frame, PJ_EINVAL);\n\n    resample = PJ_POOL_ZALLOC_T(pool, pjmedia_resample);\n    PJ_ASSERT_RETURN(resample, PJ_ENOMEM);\n\n    /*\n     * If we're downsampling, always use the fast algorithm since it seems\n     * to yield the same quality.\n     */\n    if (rate_out < rate_in) {\n\t//no this is not a good idea. It sounds pretty good with speech,\n\t//but very poor with background noise etc.\n\t//high_quality = 0;\n    }\n\n    resample->factor = rate_out * 1.0 / rate_in;\n    resample->large_filter = large_filter;\n    resample->high_quality = high_quality;\n    resample->channel_cnt = channel_count;\n    resample->frame_size = samples_per_frame;\n\n    if (high_quality) {\n\t/* This is a bug in xoff calculation, thanks Stephane Lussier\n\t * of Macadamian dot com.\n\t *   resample->xoff = large_filter ? 32 : 6;\n\t */\n\tresample->xoff = res_GetXOFF(resample->factor, (char)large_filter);\n    } else {\n\tresample->xoff = 1;\n    }\n\n    if (channel_count == 1) {\n\tunsigned size;\n\n\t/* Allocate input buffer */\n\tsize = (samples_per_frame + 2*resample->xoff) * sizeof(pj_int16_t);\n\tresample->buffer = (pj_int16_t*) pj_pool_alloc(pool, size);\n\tPJ_ASSERT_RETURN(resample->buffer, PJ_ENOMEM);\n\n\tpjmedia_zero_samples(resample->buffer, resample->xoff*2);\n\n    } else if (channel_count > 1) {\n\tunsigned i, size;\n\n\t/* Allocate input buffer table */\n\tsize = channel_count * sizeof(pj_int16_t*);\n\tresample->in_buffer = (pj_int16_t**)pj_pool_alloc(pool, size);\n\n\t/* Allocate input buffer */\n\tsize = (samples_per_frame/channel_count + 2*resample->xoff) * \n\t       sizeof(pj_int16_t);\n\tfor (i = 0; i < channel_count; ++i) {\n\t    resample->in_buffer[i] = (pj_int16_t*)pj_pool_alloc(pool, size);\n\t    PJ_ASSERT_RETURN(resample->in_buffer, PJ_ENOMEM);\n\t    pjmedia_zero_samples(resample->in_buffer[i], resample->xoff*2);\n\t}\n\n\t/* Allocate temporary output buffer */\n\tsize = (unsigned) (resample->frame_size * sizeof(pj_int16_t) * \n\t\t\t   resample->factor / channel_count + 0.5);\n\tresample->tmp_buffer = (pj_int16_t*) pj_pool_alloc(pool, size);\n\tPJ_ASSERT_RETURN(resample->tmp_buffer, PJ_ENOMEM);\n    }\n\n    *p_resample = resample;\n\n    PJ_LOG(5,(THIS_FILE, \"resample created: %s qualiy, %s filter, in/out \"\n\t\t\t  \"rate=%d/%d\", \n\t\t\t  (high_quality?\"high\":\"low\"),\n\t\t\t  (large_filter?\"large\":\"small\"),\n\t\t\t  rate_in, rate_out));\n    return PJ_SUCCESS;\n}\n\n\n\nPJ_DEF(void) pjmedia_resample_run( pjmedia_resample *resample,\n\t\t\t\t   const pj_int16_t *input,\n\t\t\t\t   pj_int16_t *output )\n{\n    PJ_ASSERT_ON_FAIL(resample, return);\n\n    /* Okay chaps, here's how we do resampling.\n     *\n     * The original resample algorithm requires xoff samples *before* the\n     * input buffer as history, and another xoff samples *after* the\n     * end of the input buffer as lookahead. Since application can only\n     * supply framesize buffer on each run, PJMEDIA needs to arrange the\n     * buffer to meet these requirements.\n     *\n     * So here comes the trick.\n     *\n     * First of all, because of the history and lookahead requirement, \n     * resample->buffer need to accomodate framesize+2*xoff samples in its\n     * buffer. This is done when the buffer is created.\n     *\n     * On the first run, the input frame (supplied by application) is\n     * copied to resample->buffer at 2*xoff position. The first 2*xoff\n     * samples are initially zeroed (in the initialization). The resample\n     * algorithm then invoked at resample->buffer+xoff ONLY, thus giving\n     * it one xoff at the beginning as zero, and one xoff at the end\n     * as the end of the original input. The resample algorithm will see\n     * that the first xoff samples in the input as zero.\n     *\n     * So here's the layout of resample->buffer on the first run.\n     *\n     * run 0 \n     *     +------+------+--------------+\n     *     | 0000 | 0000 |  frame0...   |\n     *     +------+------+--------------+\n     *     ^      ^      ^              ^\n\t *     0    xoff  2*xoff       size+2*xoff \n\t *\n     * (Note again: resample algorithm is called at resample->buffer+xoff)\n     *\n     * At the end of the run, 2*xoff samples from the end of \n     * resample->buffer are copied to the beginning of resample->buffer.\n     * The first xoff part of this will be used as history for the next\n     * run, and the second xoff part of this is actually the start of\n     * resampling for the next run.\n     *\n     * And the first run completes, the function returns.\n     *\n     * \n     * On the next run, the input frame supplied by application is again\n     * copied at 2*xoff position in the resample->buffer, and the \n     * resample algorithm is again invoked at resample->buffer+xoff \n     * position. So effectively, the resample algorithm will start its\n     * operation on the last xoff from the previous frame, and gets the\n     * history from the last 2*xoff of the previous frame, and the look-\n     * ahead from the last xoff of current frame.\n     *\n     * So on this run, the buffer layout is:\n     *\n     * run 1\n     *     +------+------+--------------+\n     *     | frm0 | frm0 |  frame1...   |\n     *     +------+------+--------------+\n     *     ^      ^      ^              ^\n\t *     0    xoff  2*xoff       size+2*xoff \n     *\n     * As you can see from above diagram, the resampling algorithm is\n     * actually called from the last xoff part of previous frame (frm0).\n     *\n     * And so on the process continues for the next frame, and the next,\n     * and the next, ...\n     *\n     */\n    if (resample->channel_cnt == 1) {\n\tpj_int16_t *dst_buf;\n\tconst pj_int16_t *src_buf;\n\n\t/* Prepare input frame */\n\tdst_buf = resample->buffer + resample->xoff*2;\n\tpjmedia_copy_samples(dst_buf, input, resample->frame_size);\n\n\t/* Resample */\n\tif (resample->high_quality) {\n\t    res_Resample(resample->buffer + resample->xoff, output,\n\t\t\t resample->factor, (pj_uint16_t)resample->frame_size,\n\t\t\t (char)resample->large_filter, (char)PJ_TRUE);\n\t} else {\n\t    res_SrcLinear(resample->buffer + resample->xoff, output, \n\t\t\t  resample->factor, (pj_uint16_t)resample->frame_size);\n\t}\n\n\t/* Update history */\n\tdst_buf = resample->buffer;\n\tsrc_buf = input + resample->frame_size - resample->xoff*2;\n\tpjmedia_copy_samples(dst_buf, src_buf, resample->xoff * 2);\n\n    } else { /* Multichannel */\n\tunsigned i, j;\n\n\tfor (i = 0; i < resample->channel_cnt; ++i) {\n\t    pj_int16_t *dst_buf;\n\t    const pj_int16_t *src_buf;\n\t    unsigned mono_frm_sz_in;\n\t    unsigned mono_frm_sz_out;\n    \t\n\t    mono_frm_sz_in  = resample->frame_size / resample->channel_cnt;\n\t    mono_frm_sz_out = (unsigned)(mono_frm_sz_in * resample->factor + 0.5);\n\n\t    /* Deinterleave input */\n\t    dst_buf = resample->in_buffer[i] + resample->xoff*2;\n\t    src_buf = input + i;\n\t    for (j = 0; j < mono_frm_sz_in; ++j) {\n\t\t*dst_buf++ = *src_buf;\n\t\tsrc_buf += resample->channel_cnt;\n\t    }\n\n\t    /* Resample this channel */\n\t    if (resample->high_quality) {\n\t\tres_Resample(resample->in_buffer[i] + resample->xoff,\n\t\t\t     resample->tmp_buffer, resample->factor,\n\t\t\t     (pj_uint16_t)mono_frm_sz_in,\n\t\t\t     (char)resample->large_filter, (char)PJ_TRUE);\n\t    } else {\n\t\tres_SrcLinear( resample->in_buffer[i],\n\t\t\t       resample->tmp_buffer, \n\t\t\t       resample->factor, \n\t\t\t       (pj_uint16_t)mono_frm_sz_in);\n\t    }\n\n\t    /* Update history */\n\t    dst_buf = resample->in_buffer[i];\n\t    src_buf = resample->in_buffer[i] + mono_frm_sz_in;\n\t    pjmedia_copy_samples(dst_buf, src_buf, resample->xoff * 2);\n\n\t    /* Reinterleave output */\n\t    dst_buf = output + i;\n\t    src_buf = resample->tmp_buffer;\n\t    for (j = 0; j < mono_frm_sz_out; ++j) {\n\t\t*dst_buf = *src_buf++;\n\t\tdst_buf += resample->channel_cnt;\n\t    }\n\t}\n    }\n}\n\nPJ_DEF(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample)\n{\n    PJ_ASSERT_RETURN(resample != NULL, 0);\n    return resample->frame_size;\n}\n\nPJ_DEF(void) pjmedia_resample_destroy(pjmedia_resample *resample)\n{\n    PJ_UNUSED_ARG(resample);\n}\n\n\n#elif PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_NONE\n\n/*\n * This is the configuration when sample rate conversion is disabled.\n */\nPJ_DEF(pj_status_t) pjmedia_resample_create( pj_pool_t *pool,\n\t\t\t\t\t     pj_bool_t high_quality,\n\t\t\t\t\t     pj_bool_t large_filter,\n\t\t\t\t\t     unsigned channel_count,\n\t\t\t\t\t     unsigned rate_in,\n\t\t\t\t\t     unsigned rate_out,\n\t\t\t\t\t     unsigned samples_per_frame,\n\t\t\t\t\t     pjmedia_resample **p_resample) \n{\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(high_quality);\n    PJ_UNUSED_ARG(large_filter);\n    PJ_UNUSED_ARG(channel_count);\n    PJ_UNUSED_ARG(rate_in);\n    PJ_UNUSED_ARG(rate_out);\n    PJ_UNUSED_ARG(samples_per_frame);\n    PJ_UNUSED_ARG(p_resample);\n\n    return PJ_EINVALIDOP;\n}\n\nPJ_DEF(void) pjmedia_resample_run( pjmedia_resample *resample,\n\t\t\t\t   const pj_int16_t *input,\n\t\t\t\t   pj_int16_t *output ) \n{\n    PJ_UNUSED_ARG(resample);\n    PJ_UNUSED_ARG(input);\n    PJ_UNUSED_ARG(output);\n}\n\nPJ_DEF(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample) \n{\n    PJ_UNUSED_ARG(resample);\n    return 0;\n}\n\nPJ_DEF(void) pjmedia_resample_destroy(pjmedia_resample *resample) \n{\n    PJ_UNUSED_ARG(resample);\n}\n\n#endif\t/* PJMEDIA_RESAMPLE_IMP */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/resample_speex.c",
    "content": "/* $Id: resample_speex.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/resample.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n\n#if PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_SPEEX\n\n#include <speex/speex_resampler.h>\n\n#define THIS_FILE   \"resample_speex.c\"\n\n\nstruct pjmedia_resample\n{\n    SpeexResamplerState *state;\n    unsigned\t\t in_samples_per_frame;\n    unsigned\t\t out_samples_per_frame;\n};\n\n\nPJ_DEF(pj_status_t) pjmedia_resample_create( pj_pool_t *pool,\n\t\t\t\t\t     pj_bool_t high_quality,\n\t\t\t\t\t     pj_bool_t large_filter,\n\t\t\t\t\t     unsigned channel_count,\n\t\t\t\t\t     unsigned rate_in,\n\t\t\t\t\t     unsigned rate_out,\n\t\t\t\t\t     unsigned samples_per_frame,\n\t\t\t\t\t     pjmedia_resample **p_resample)\n{\n    pjmedia_resample *resample;\n    int quality;\n    int err;\n\n    PJ_ASSERT_RETURN(pool && p_resample && rate_in &&\n\t\t     rate_out && samples_per_frame, PJ_EINVAL);\n\n    resample = PJ_POOL_ZALLOC_T(pool, pjmedia_resample);\n    PJ_ASSERT_RETURN(resample, PJ_ENOMEM);\n\n    if (high_quality) {\n\tif (large_filter)\n\t    quality = 10;\n\telse\n\t    quality = 7;\n    } else {\n\tquality = 3;\n    }\n\n    resample->in_samples_per_frame = samples_per_frame;\n    resample->out_samples_per_frame = rate_out / (rate_in / samples_per_frame);\n    resample->state = speex_resampler_init(channel_count,  rate_in, rate_out, \n                                           quality, &err);\n    if (resample->state == NULL || err != RESAMPLER_ERR_SUCCESS)\n\treturn PJ_ENOMEM;\n\n\n    *p_resample = resample;\n\n    PJ_LOG(5,(THIS_FILE, \n\t      \"resample created: quality=%d, ch=%d, in/out rate=%d/%d\", \n\t      quality, channel_count, rate_in, rate_out));\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(void) pjmedia_resample_run( pjmedia_resample *resample,\n\t\t\t\t   const pj_int16_t *input,\n\t\t\t\t   pj_int16_t *output )\n{\n    spx_uint32_t in_length, out_length;\n\n    PJ_ASSERT_ON_FAIL(resample, return);\n\n    in_length = resample->in_samples_per_frame;\n    out_length = resample->out_samples_per_frame;\n\n    speex_resampler_process_interleaved_int(resample->state,\n\t\t\t\t\t    (const __int16 *)input, &in_length,\n\t\t\t\t\t    (__int16 *)output, &out_length);\n\n    pj_assert(in_length == resample->in_samples_per_frame);\n    pj_assert(out_length == resample->out_samples_per_frame);\n}\n\n\nPJ_DEF(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample)\n{\n    PJ_ASSERT_RETURN(resample != NULL, 0);\n    return resample->in_samples_per_frame;\n}\n\n\nPJ_DEF(void) pjmedia_resample_destroy(pjmedia_resample *resample)\n{\n    PJ_ASSERT_ON_FAIL(resample, return);\n    if (resample->state) {\n\tspeex_resampler_destroy(resample->state);\n\tresample->state = NULL;\n    }\n}\n\n#else /* PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_SPEEX */\n\nint pjmedia_resample_speex_excluded;\n\n#endif\t/* PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_SPEEX */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/rtcp.c",
    "content": "/* $Id: rtcp.c 4283 2012-10-12 06:19:32Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/rtcp.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/sock.h>\n#include <pj/string.h>\n\n#define THIS_FILE \"rtcp.c\"\n\n#define RTCP_SR   200\n#define RTCP_RR   201\n#define RTCP_SDES 202\n#define RTCP_BYE  203\n#define RTCP_PSFB 206    /* Payload-specific FB message (RFC 4585) */\n#define RTCP_XR   207\n\nenum {\n    RTCP_SDES_NULL  = 0,\n    RTCP_SDES_CNAME = 1,\n    RTCP_SDES_NAME  = 2,\n    RTCP_SDES_EMAIL = 3,\n    RTCP_SDES_PHONE = 4,\n    RTCP_SDES_LOC   = 5,\n    RTCP_SDES_TOOL  = 6,\n    RTCP_SDES_NOTE  = 7\n};\n\n#if PJ_HAS_HIGH_RES_TIMER==0\n#   error \"High resolution timer needs to be enabled\"\n#endif\n\n\n\n#if 0\n#   define TRACE_(x)\tPJ_LOG(3,x)\n#else\n#   define TRACE_(x)\t;\n#endif\n\n\n/*\n * Get NTP time.\n */\nPJ_DEF(pj_status_t) pjmedia_rtcp_get_ntp_time(const pjmedia_rtcp_session *sess,\n\t\t\t\t\t      pjmedia_rtcp_ntp_rec *ntp)\n{\n/* Seconds between 1900-01-01 to 1970-01-01 */\n#define JAN_1970  (2208988800UL)\n    pj_timestamp ts;\n    pj_status_t status;\n\n    status = pj_get_timestamp(&ts);\n\n    /* Fill up the high 32bit part */\n    ntp->hi = (pj_uint32_t)((ts.u64 - sess->ts_base.u64) / sess->ts_freq.u64)\n\t      + sess->tv_base.sec + JAN_1970;\n\n    /* Calculate seconds fractions */\n    ts.u64 = (ts.u64 - sess->ts_base.u64) % sess->ts_freq.u64;\n    pj_assert(ts.u64 < sess->ts_freq.u64);\n    ts.u64 = (ts.u64 << 32) / sess->ts_freq.u64;\n\n    /* Fill up the low 32bit part */\n    ntp->lo = ts.u32.lo;\n\n\n#if (defined(PJ_WIN32) && PJ_WIN32!=0) || \\\n    (defined(PJ_WIN64) && PJ_WIN64!=0) || \\\n    (defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0)\n\n    /* On Win32, since we use QueryPerformanceCounter() as the backend\n     * timestamp API, we need to protect against this bug:\n     *   Performance counter value may unexpectedly leap forward\n     *   http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323\n     */\n    {\n\t/*\n\t * Compare elapsed time reported by timestamp with actual elapsed \n\t * time. If the difference is too excessive, then we use system\n\t * time instead.\n\t */\n\n\t/* MIN_DIFF needs to be large enough so that \"normal\" diff caused\n\t * by system activity or context switch doesn't trigger the time\n\t * correction.\n\t */\n\tenum { MIN_DIFF = 400 };\n\n\tpj_time_val ts_time, elapsed, diff;\n\n\tpj_gettimeofday(&elapsed);\n\n\tts_time.sec = ntp->hi - sess->tv_base.sec - JAN_1970;\n\tts_time.msec = (long)(ntp->lo * 1000.0 / 0xFFFFFFFF);\n\n\tPJ_TIME_VAL_SUB(elapsed, sess->tv_base);\n\n\tif (PJ_TIME_VAL_LT(ts_time, elapsed)) {\n\t    diff = elapsed;\n\t    PJ_TIME_VAL_SUB(diff, ts_time);\n\t} else {\n\t    diff = ts_time;\n\t    PJ_TIME_VAL_SUB(diff, elapsed);\n\t}\n\n\tif (PJ_TIME_VAL_MSEC(diff) >= MIN_DIFF) {\n\n\t    TRACE_((sess->name, \"RTCP NTP timestamp corrected by %d ms\",\n\t\t    PJ_TIME_VAL_MSEC(diff)));\n\n\n\t    ntp->hi = elapsed.sec + sess->tv_base.sec + JAN_1970;\n\t    ntp->lo = (elapsed.msec * 65536 / 1000) << 16;\n\t}\n\n    }\n#endif\n\n    return status;\n}\n\n\n/*\n * Initialize RTCP session setting.\n */\nPJ_DEF(void) pjmedia_rtcp_session_setting_default(\n\t\t\t\t    pjmedia_rtcp_session_setting *settings)\n{\n    pj_bzero(settings, sizeof(*settings));\n}\n\n\n/*\n * Initialize bidirectional RTCP statistics.\n *\n */\nPJ_DEF(void) pjmedia_rtcp_init_stat(pjmedia_rtcp_stat *stat)\n{\n    pj_time_val now;\n\n    pj_assert(stat);\n\n    pj_bzero(stat, sizeof(pjmedia_rtcp_stat));\n\n    pj_math_stat_init(&stat->rtt);\n    pj_math_stat_init(&stat->rx.loss_period);\n    pj_math_stat_init(&stat->rx.jitter);\n    pj_math_stat_init(&stat->tx.loss_period);\n    pj_math_stat_init(&stat->tx.jitter);\n\n#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0\n    pj_math_stat_init(&stat->rx_ipdv);\n#endif\n\n#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0\n    pj_math_stat_init(&stat->rx_raw_jitter);\n#endif\n\n    pj_gettimeofday(&now);\n    stat->start = now;\n}\n\n\n/*\n * Initialize RTCP session.\n */\nPJ_DEF(void) pjmedia_rtcp_init(pjmedia_rtcp_session *sess, \n\t\t\t       char *name,\n\t\t\t       unsigned clock_rate,\n\t\t\t       unsigned samples_per_frame,\n\t\t\t       pj_uint32_t ssrc)\n{\n    pjmedia_rtcp_session_setting settings;\n\n    pjmedia_rtcp_session_setting_default(&settings);\n    settings.name = name;\n    settings.clock_rate = clock_rate;\n    settings.samples_per_frame = samples_per_frame;\n    settings.ssrc = ssrc;\n\n    pjmedia_rtcp_init2(sess, &settings);\n}\n\n\n/*\n * Initialize RTCP session.\n */\nPJ_DEF(void) pjmedia_rtcp_init2( pjmedia_rtcp_session *sess,\n\t\t\t\t const pjmedia_rtcp_session_setting *settings)\n{\n    pjmedia_rtcp_sr_pkt *sr_pkt = &sess->rtcp_sr_pkt;\n    pj_time_val now;\n    \n    /* Memset everything */\n    pj_bzero(sess, sizeof(pjmedia_rtcp_session));\n\n    /* Last RX timestamp in RTP packet */\n    sess->rtp_last_ts = (unsigned)-1;\n\n    /* Name */\n    sess->name = settings->name ? settings->name : (char*)THIS_FILE;\n\n    /* Set clock rate */\n    sess->clock_rate = settings->clock_rate;\n    sess->pkt_size = settings->samples_per_frame;\n\n    /* Init common RTCP SR header */\n    sr_pkt->common.version = 2;\n    sr_pkt->common.count = 1;\n    sr_pkt->common.pt = RTCP_SR;\n    sr_pkt->common.length = pj_htons(12);\n    sr_pkt->common.ssrc = pj_htonl(settings->ssrc);\n    \n    /* Copy to RTCP RR header */\n    pj_memcpy(&sess->rtcp_rr_pkt.common, &sr_pkt->common, \n\t      sizeof(pjmedia_rtcp_common));\n    sess->rtcp_rr_pkt.common.pt = RTCP_RR;\n    sess->rtcp_rr_pkt.common.length = pj_htons(7);\n\n    /* Get time and timestamp base and frequency */\n    pj_gettimeofday(&now);\n    sess->tv_base = now;\n    pj_get_timestamp(&sess->ts_base);\n    pj_get_timestamp_freq(&sess->ts_freq);\n    sess->rtp_ts_base = settings->rtp_ts_base;\n\n    /* Initialize statistics states */\n    pjmedia_rtcp_init_stat(&sess->stat);\n\n    /* RR will be initialized on receipt of the first RTP packet. */\n}\n\n\nPJ_DEF(void) pjmedia_rtcp_fini(pjmedia_rtcp_session *sess)\n{\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n    pjmedia_rtcp_xr_fini(&sess->xr_session);\n#else\n    /* Nothing to do. */\n    PJ_UNUSED_ARG(sess);\n#endif\n}\n\nstatic void rtcp_init_seq(pjmedia_rtcp_session *sess)\n{\n    sess->received = 0;\n    sess->exp_prior = 0;\n    sess->rx_prior = 0;\n    sess->transit = 0;\n    sess->jitter = 0;\n}\n\nPJ_DEF(void) pjmedia_rtcp_rx_rtp( pjmedia_rtcp_session *sess, \n\t\t\t\t  unsigned seq, \n\t\t\t\t  unsigned rtp_ts,\n\t\t\t\t  unsigned payload)\n{\n    pjmedia_rtcp_rx_rtp2(sess, seq, rtp_ts, payload, PJ_FALSE);\n}\n\nPJ_DEF(void) pjmedia_rtcp_rx_rtp2(pjmedia_rtcp_session *sess, \n\t\t\t\t  unsigned seq, \n\t\t\t\t  unsigned rtp_ts,\n\t\t\t\t  unsigned payload,\n\t\t\t\t  pj_bool_t discarded)\n{   \n    pj_timestamp ts;\n    pj_uint32_t arrival;\n    pj_int32_t transit;\n    pjmedia_rtp_status seq_st;\n\n#if !defined(PJMEDIA_HAS_RTCP_XR) || (PJMEDIA_HAS_RTCP_XR == 0)\n    PJ_UNUSED_ARG(discarded);\n#endif\n\n    if (sess->stat.rx.pkt == 0) {\n\t/* Init sequence for the first time. */\n\tpjmedia_rtp_seq_init(&sess->seq_ctrl, (pj_uint16_t)seq);\n    } \n\n    sess->stat.rx.pkt++;\n    sess->stat.rx.bytes += payload;\n\n    /* Process the RTP packet. */\n    pjmedia_rtp_seq_update(&sess->seq_ctrl, (pj_uint16_t)seq, &seq_st);\n\n    if (seq_st.status.flag.restart) {\n\trtcp_init_seq(sess);\n    }\n    \n    if (seq_st.status.flag.dup) {\n\tsess->stat.rx.dup++;\n\tTRACE_((sess->name, \"Duplicate packet detected\"));\n    }\n\n    if (seq_st.status.flag.outorder && !seq_st.status.flag.probation) {\n\tsess->stat.rx.reorder++;\n\tTRACE_((sess->name, \"Out-of-order packet detected\"));\n    }\n\n    if (seq_st.status.flag.bad) {\n\tsess->stat.rx.discard++;\n\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n\tpjmedia_rtcp_xr_rx_rtp(&sess->xr_session, seq, \n\t\t\t       -1,\t\t\t\t /* lost    */\n\t\t\t       (seq_st.status.flag.dup? 1:0),\t /* dup     */\n\t\t\t       (!seq_st.status.flag.dup? 1:-1),  /* discard */\n\t\t\t       -1,\t\t\t\t /* jitter  */\n\t\t\t       -1, 0);\t\t\t\t /* toh\t    */\n#endif\n\n\tTRACE_((sess->name, \"Bad packet discarded\"));\n\treturn;\n    }\n\n    /* Only mark \"good\" packets */\n    ++sess->received;\n\n    /* Calculate loss periods. */\n    if (seq_st.diff > 1) {\n\tunsigned count = seq_st.diff - 1;\n\tunsigned period;\n\n\tperiod = count * sess->pkt_size * 1000 / sess->clock_rate;\n\tperiod *= 1000;\n\n\t/* Update packet lost. \n\t * The packet lost number will also be updated when we're sending\n\t * outbound RTCP RR.\n\t */\n\tsess->stat.rx.loss += (seq_st.diff - 1);\n\tTRACE_((sess->name, \"%d packet(s) lost\", seq_st.diff - 1));\n\n\t/* Update loss period stat */\n\tpj_math_stat_update(&sess->stat.rx.loss_period, period);\n    }\n\n\n    /*\n     * Calculate jitter only when sequence is good (see RFC 3550 section A.8),\n     * AND only when the timestamp is different than the last packet\n     * (see RTP FAQ).\n     */\n    if (seq_st.diff == 1 && rtp_ts != sess->rtp_last_ts) {\n\t/* Get arrival time and convert timestamp to samples */\n\tpj_get_timestamp(&ts);\n\tts.u64 = ts.u64 * sess->clock_rate / sess->ts_freq.u64;\n\tarrival = ts.u32.lo;\n\n\ttransit = arrival - rtp_ts;\n    \n\t/* Ignore the first N packets as they normally have bad jitter\n\t * due to other threads working to establish the call\n\t */\n\tif (sess->transit == 0 || \n\t    sess->received < PJMEDIA_RTCP_IGNORE_FIRST_PACKETS) \n\t{\n\t    sess->transit = transit;\n\t    sess->stat.rx.jitter.min = (unsigned)-1;\n\t} else {\n\t    pj_int32_t d;\n\t    pj_uint32_t jitter;\n\n\t    d = transit - sess->transit;\n\t    if (d < 0) \n\t\td = -d;\n\t    \n\t    sess->jitter += d - ((sess->jitter + 8) >> 4);\n\n\t    /* Update jitter stat */\n\t    jitter = sess->jitter >> 4;\n\t    \n\t    /* Convert jitter unit from samples to usec */\n\t    if (jitter < 4294)\n\t\tjitter = jitter * 1000000 / sess->clock_rate;\n\t    else {\n\t\tjitter = jitter * 1000 / sess->clock_rate;\n\t\tjitter *= 1000;\n\t    }\n\t    pj_math_stat_update(&sess->stat.rx.jitter, jitter);\n\n\n#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0\n\t    {\n\t\tpj_uint32_t raw_jitter;\n\n\t\t/* Convert raw jitter unit from samples to usec */\n\t\tif (d < 4294)\n\t\t    raw_jitter = d * 1000000 / sess->clock_rate;\n\t\telse {\n\t\t    raw_jitter = d * 1000 / sess->clock_rate;\n\t\t    raw_jitter *= 1000;\n\t\t}\n\t\t\n\t\t/* Update jitter stat */\n\t\tpj_math_stat_update(&sess->stat.rx_raw_jitter, raw_jitter);\n\t    }\n#endif\n\n\n#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0\n\t    {\n\t\tpj_int32_t ipdv;\n\n\t\tipdv = transit - sess->transit;\n\t\t/* Convert IPDV unit from samples to usec */\n\t\tif (ipdv > -2147 && ipdv < 2147)\n\t\t    ipdv = ipdv * 1000000 / (int)sess->clock_rate;\n\t\telse {\n\t\t    ipdv = ipdv * 1000 / (int)sess->clock_rate;\n\t\t    ipdv *= 1000;\n\t\t}\n\t\t\n\t\t/* Update jitter stat */\n\t\tpj_math_stat_update(&sess->stat.rx_ipdv, ipdv);\n\t    }\n#endif\n\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n\t    pjmedia_rtcp_xr_rx_rtp(&sess->xr_session, seq, \n\t\t\t\t   0,\t\t\t    /* lost    */\n\t\t\t\t   0,\t\t\t    /* dup     */\n\t\t\t\t   discarded,\t\t    /* discard */\n\t\t\t\t   (sess->jitter >> 4),\t    /* jitter  */\n\t\t\t\t   -1, 0);\t\t    /* toh     */\n#endif\n\n\t    /* Update session transit */\n\t    sess->transit = transit;\n\t}\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n    } else if (seq_st.diff > 1) {\n\tint i;\n\n\t/* Report RTCP XR about packet losses */\n\tfor (i=seq_st.diff-1; i>0; --i) {\n\t    pjmedia_rtcp_xr_rx_rtp(&sess->xr_session, seq - i, \n\t\t\t\t   1,\t\t\t    /* lost    */\n\t\t\t\t   0,\t\t\t    /* dup     */\n\t\t\t\t   0,\t\t\t    /* discard */\n\t\t\t\t   -1,\t\t\t    /* jitter  */\n\t\t\t\t   -1, 0);\t\t    /* toh     */\n\t}\n\n\t/* Report RTCP XR this packet */\n\tpjmedia_rtcp_xr_rx_rtp(&sess->xr_session, seq, \n\t\t\t       0,\t\t\t    /* lost    */\n\t\t\t       0,\t\t\t    /* dup     */\n\t\t\t       discarded,\t\t    /* discard */\n\t\t\t       -1,\t\t\t    /* jitter  */\n\t\t\t       -1, 0);\t\t\t    /* toh     */\n#endif\n    }\n\n    /* Update timestamp of last RX RTP packet */\n    sess->rtp_last_ts = rtp_ts;\n}\n\nPJ_DEF(void) pjmedia_rtcp_tx_rtp(pjmedia_rtcp_session *sess, \n\t\t\t\t unsigned bytes_payload_size)\n{\n    /* Update statistics */\n    sess->stat.tx.pkt++;\n    sess->stat.tx.bytes += bytes_payload_size;\n}\n\n\nstatic void parse_rtcp_report( pjmedia_rtcp_session *sess,\n\t\t\t       const void *pkt,\n\t\t\t       pj_size_t size)\n{\n    pjmedia_rtcp_common *common = (pjmedia_rtcp_common*) pkt;\n    const pjmedia_rtcp_rr *rr = NULL;\n    const pjmedia_rtcp_sr *sr = NULL;\n    pj_uint32_t last_loss, jitter_samp, jitter;\n\n    /* Parse RTCP */\n    if (common->pt == RTCP_SR) {\n\tsr = (pjmedia_rtcp_sr*) (((char*)pkt) + sizeof(pjmedia_rtcp_common));\n\tif (common->count > 0 && size >= (sizeof(pjmedia_rtcp_sr_pkt))) {\n\t    rr = (pjmedia_rtcp_rr*)(((char*)pkt) + (sizeof(pjmedia_rtcp_common)\n\t\t\t\t    + sizeof(pjmedia_rtcp_sr)));\n\t}\n    } else if (common->pt == RTCP_RR && common->count > 0) {\n\trr = (pjmedia_rtcp_rr*)(((char*)pkt) + sizeof(pjmedia_rtcp_common));\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n    } else if (common->pt == RTCP_XR) {\n\tif (sess->xr_enabled)\n\t    pjmedia_rtcp_xr_rx_rtcp_xr(&sess->xr_session, pkt, size);\n\n\treturn;\n#endif\n    }\n\n\n    if (sr) {\n\t/* Save LSR from NTP timestamp of RTCP packet */\n\tsess->rx_lsr = ((pj_ntohl(sr->ntp_sec) & 0x0000FFFF) << 16) | \n\t\t       ((pj_ntohl(sr->ntp_frac) >> 16) & 0xFFFF);\n\n\t/* Calculate SR arrival time for DLSR */\n\tpj_get_timestamp(&sess->rx_lsr_time);\n\n\tTRACE_((sess->name, \"Rx RTCP SR: ntp_ts=%p\", \n\t\tsess->rx_lsr,\n\t\t(pj_uint32_t)(sess->rx_lsr_time.u64*65536/sess->ts_freq.u64)));\n    }\n\n\n    /* Nothing more to do if there's no RR packet */\n    if (rr == NULL)\n\treturn;\n\n\n    last_loss = sess->stat.tx.loss;\n\n    /* Get packet loss */\n    sess->stat.tx.loss = (rr->total_lost_2 << 16) +\n\t\t\t (rr->total_lost_1 << 8) +\n\t\t\t  rr->total_lost_0;\n\n    TRACE_((sess->name, \"Rx RTCP RR: total_lost_2=%x, 1=%x, 0=%x, lost=%d\", \n\t    (int)rr->total_lost_2,\n\t    (int)rr->total_lost_1,\n\t    (int)rr->total_lost_0,\n\t    sess->stat.tx.loss));\n    \n    /* We can't calculate the exact loss period for TX, so just give the\n     * best estimation.\n     */\n    if (sess->stat.tx.loss > last_loss) {\n\tunsigned period;\n\n\t/* Loss period in msec */\n\tperiod = (sess->stat.tx.loss - last_loss) * sess->pkt_size *\n\t\t 1000 / sess->clock_rate;\n\n\t/* Loss period in usec */\n\tperiod *= 1000;\n\n\t/* Update loss period stat */\n\tpj_math_stat_update(&sess->stat.tx.loss_period, period);\n    }\n\n    /* Get jitter value in usec */\n    jitter_samp = pj_ntohl(rr->jitter);\n    /* Calculate jitter in usec, avoiding overflows */\n    if (jitter_samp <= 4294)\n\tjitter = jitter_samp * 1000000 / sess->clock_rate;\n    else {\n\tjitter = jitter_samp * 1000 / sess->clock_rate;\n\tjitter *= 1000;\n    }\n\n    /* Update jitter statistics */\n    pj_math_stat_update(&sess->stat.tx.jitter, jitter);\n\n    /* Can only calculate if LSR and DLSR is present in RR */\n    if (rr->lsr && rr->dlsr) {\n\tpj_uint32_t lsr, now, dlsr;\n\tpj_uint64_t eedelay;\n\tpjmedia_rtcp_ntp_rec ntp;\n\n\t/* LSR is the middle 32bit of NTP. It has 1/65536 second \n\t * resolution \n\t */\n\tlsr = pj_ntohl(rr->lsr);\n\n\t/* DLSR is delay since LSR, also in 1/65536 resolution */\n\tdlsr = pj_ntohl(rr->dlsr);\n\n\t/* Get current time, and convert to 1/65536 resolution */\n\tpjmedia_rtcp_get_ntp_time(sess, &ntp);\n\tnow = ((ntp.hi & 0xFFFF) << 16) + (ntp.lo >> 16);\n\n\t/* End-to-end delay is (now-lsr-dlsr) */\n\teedelay = now - lsr - dlsr;\n\n\t/* Convert end to end delay to usec (keeping the calculation in\n         * 64bit space)::\n\t *   sess->ee_delay = (eedelay * 1000) / 65536;\n\t */\n\tif (eedelay < 4294) {\n\t    eedelay = (eedelay * 1000000) >> 16;\n\t} else {\n\t    eedelay = (eedelay * 1000) >> 16;\n\t    eedelay *= 1000;\n\t}\n\n\tTRACE_((sess->name, \"Rx RTCP RR: lsr=%p, dlsr=%p (%d:%03dms), \"\n\t\t\t   \"now=%p, rtt=%p\",\n\t\tlsr, dlsr, dlsr/65536, (dlsr%65536)*1000/65536,\n\t\tnow, (pj_uint32_t)eedelay));\n\t\n\t/* Only save calculation if \"now\" is greater than lsr, or\n\t * otherwise rtt will be invalid \n\t */\n\tif (now-dlsr >= lsr) {\n\t    unsigned rtt = (pj_uint32_t)eedelay;\n\t    \n\t    /* Check that eedelay value really makes sense. \n\t     * We allow up to 30 seconds RTT!\n\t     */\n\t    if (eedelay > 30 * 1000 * 1000UL) {\n\n\t\tTRACE_((sess->name, \"RTT not making any sense, ignored..\"));\n\t\tgoto end_rtt_calc;\n\t    }\n\n#if defined(PJMEDIA_RTCP_NORMALIZE_FACTOR) && PJMEDIA_RTCP_NORMALIZE_FACTOR!=0\n\t    /* \"Normalize\" rtt value that is exceptionally high. For such\n\t     * values, \"normalize\" the rtt to be PJMEDIA_RTCP_NORMALIZE_FACTOR\n\t     * times the average value.\n\t     */\n\t    if (rtt > ((unsigned)sess->stat.rtt.mean *\n\t\t       PJMEDIA_RTCP_NORMALIZE_FACTOR) && sess->stat.rtt.n!=0)\n\t    {\n\t\tunsigned orig_rtt = rtt;\n\t\trtt = sess->stat.rtt.mean * PJMEDIA_RTCP_NORMALIZE_FACTOR;\n\t\tPJ_LOG(5,(sess->name,\n\t\t\t  \"RTT value %d usec is normalized to %d usec\",\n\t\t\t  orig_rtt, rtt));\n\t    }\n#endif\n\t    TRACE_((sess->name, \"RTCP RTT is set to %d usec\", rtt));\n\n\t    /* Update RTT stat */\n\t    pj_math_stat_update(&sess->stat.rtt, rtt);\n\n\t} else {\n\t    PJ_LOG(5, (sess->name, \"Internal RTCP NTP clock skew detected: \"\n\t\t\t\t   \"lsr=%p, now=%p, dlsr=%p (%d:%03dms), \"\n\t\t\t\t   \"diff=%d\",\n\t\t\t\t   lsr, now, dlsr, dlsr/65536,\n\t\t\t\t   (dlsr%65536)*1000/65536,\n\t\t\t\t   dlsr-(now-lsr)));\n\t}\n    }\n\nend_rtt_calc:\n\n    pj_gettimeofday(&sess->stat.tx.update);\n    sess->stat.tx.update_cnt++;\n}\n\n\nstatic void parse_rtcp_sdes(pjmedia_rtcp_session *sess,\n\t\t\t    const void *pkt,\n\t\t\t    pj_size_t size)\n{\n    pjmedia_rtcp_sdes *sdes = &sess->stat.peer_sdes;\n    char *p, *p_end;\n    char *b, *b_end;\n\n    p = (char*)pkt + 8;\n    p_end = (char*)pkt + size;\n\n    pj_bzero(sdes, sizeof(*sdes));\n    b = sess->stat.peer_sdes_buf_;\n    b_end = b + sizeof(sess->stat.peer_sdes_buf_);\n\n    while (p < p_end) {\n\tpj_uint8_t sdes_type, sdes_len;\n\tpj_str_t sdes_value = {NULL, 0};\n\n\tsdes_type = *p++;\n\n\t/* Check for end of SDES item list */\n\tif (sdes_type == RTCP_SDES_NULL || p == p_end)\n\t    break;\n\n\tsdes_len = *p++;\n\n\t/* Check for corrupted SDES packet */\n\tif (p + sdes_len > p_end)\n\t    break;\n\n\t/* Get SDES item */\n\tif (b + sdes_len < b_end) {\n\t    pj_memcpy(b, p, sdes_len);\n\t    sdes_value.ptr = b;\n\t    sdes_value.slen = sdes_len;\n\t    b += sdes_len;\n\t} else {\n\t    /* Insufficient SDES buffer */\n\t    PJ_LOG(5, (sess->name,\n\t\t    \"Unsufficient buffer to save RTCP SDES type %d:%.*s\",\n\t\t    sdes_type, sdes_len, p));\n\t    p += sdes_len;\n\t    continue;\n\t}\n\n\tswitch (sdes_type) {\n\tcase RTCP_SDES_CNAME:\n\t    sdes->cname = sdes_value;\n\t    break;\n\tcase RTCP_SDES_NAME:\n\t    sdes->name = sdes_value;\n\t    break;\n\tcase RTCP_SDES_EMAIL:\n\t    sdes->email = sdes_value;\n\t    break;\n\tcase RTCP_SDES_PHONE:\n\t    sdes->phone = sdes_value;\n\t    break;\n\tcase RTCP_SDES_LOC:\n\t    sdes->loc = sdes_value;\n\t    break;\n\tcase RTCP_SDES_TOOL:\n\t    sdes->tool = sdes_value;\n\t    break;\n\tcase RTCP_SDES_NOTE:\n\t    sdes->note = sdes_value;\n\t    break;\n\tdefault:\n\t    TRACE_((sess->name, \"Received unknown RTCP SDES type %d:%.*s\",\n\t\t    sdes_type, sdes_value.slen, sdes_value.ptr));\n\t    break;\n\t}\n\n\tp += sdes_len;\n    }\n}\n\n\nstatic void parse_rtcp_bye(pjmedia_rtcp_session *sess,\n\t\t\t   const void *pkt,\n\t\t\t   pj_size_t size)\n{\n    pj_str_t reason = {\"-\", 1};\n\n    /* Check and get BYE reason */\n    if (size > 8) {\n\treason.slen = PJ_MIN(sizeof(sess->stat.peer_sdes_buf_),\n                             *((pj_uint8_t*)pkt+8));\n\tpj_memcpy(sess->stat.peer_sdes_buf_, ((pj_uint8_t*)pkt+9),\n\t\t  reason.slen);\n\treason.ptr = sess->stat.peer_sdes_buf_;\n    }\n\n    /* Just print RTCP BYE log */\n    PJ_LOG(5, (sess->name, \"Received RTCP BYE, reason: %.*s\",\n\t       reason.slen, reason.ptr));\n}\n\n\nstatic void parse_rtcp_psfb(pjmedia_rtcp_session *sess,\n\t\t\t    const void *pkt,\n\t\t\t    pj_size_t size)\n{\n    pjmedia_rtcp_common *common = (pjmedia_rtcp_common*)pkt;\n    pj_assert(common->pt == RTCP_PSFB);\n\n    if (common->count == 1) {\n        /* It's a PLI */\n        PJ_LOG(5, (sess->name, \"Received RTCP PLI\"));\n        sess->keyframe_requested = PJ_TRUE;\n    }\n}\n\n\nPJ_DEF(void) pjmedia_rtcp_rx_rtcp( pjmedia_rtcp_session *sess,\n\t\t\t\t   const void *pkt,\n\t\t\t\t   pj_size_t size)\n{\n    pj_uint8_t *p, *p_end;\n\n    sess->keyframe_requested = PJ_FALSE;\n\n    p = (pj_uint8_t*)pkt;\n    p_end = p + size;\n    while (p < p_end) {\n\tpjmedia_rtcp_common *common = (pjmedia_rtcp_common*)p;\n\tunsigned len;\n\n\tlen = (pj_ntohs((pj_uint16_t)common->length)+1) * 4;\n\tswitch(common->pt) {\n\tcase RTCP_SR:\n\tcase RTCP_RR:\n\tcase RTCP_XR:\n\t    parse_rtcp_report(sess, p, len);\n\t    break;\n\tcase RTCP_SDES:\n\t    parse_rtcp_sdes(sess, p, len);\n\t    break;\n\tcase RTCP_BYE:\n\t    parse_rtcp_bye(sess, p, len);\n\t    break;\n\tcase RTCP_PSFB:\n\t    parse_rtcp_psfb(sess, p, len);\n\t    break;\n\tdefault:\n\t    /* Ignore unknown RTCP */\n\t    TRACE_((sess->name, \"Received unknown RTCP packet type=%d\",\n\t\t    common->pt));\n\t    break;\n\t}\n\n\tp += len;\n    }\n}\n\n\nPJ_DEF(void) pjmedia_rtcp_build_rtcp(pjmedia_rtcp_session *sess, \n\t\t\t\t     void **ret_p_pkt, int *len)\n{\n    pj_uint32_t expected, expected_interval, received_interval, lost_interval;\n    pjmedia_rtcp_sr *sr;\n    pjmedia_rtcp_rr *rr;\n    pj_timestamp ts_now;\n    pjmedia_rtcp_ntp_rec ntp;\n\n    /* Get current NTP time. */\n    pj_get_timestamp(&ts_now);\n    pjmedia_rtcp_get_ntp_time(sess, &ntp);\n\n\n    /* See if we have transmitted RTP packets since last time we\n     * sent RTCP SR.\n     */\n    if (sess->stat.tx.pkt != pj_ntohl(sess->rtcp_sr_pkt.sr.sender_pcount)) {\n\tpj_time_val ts_time;\n\tpj_uint32_t rtp_ts;\n\n\t/* So we should send RTCP SR */\n\t*ret_p_pkt = (void*) &sess->rtcp_sr_pkt;\n\t*len = sizeof(pjmedia_rtcp_sr_pkt);\n\trr = &sess->rtcp_sr_pkt.rr;\n\tsr = &sess->rtcp_sr_pkt.sr;\n\n\t/* Update packet count */\n\tsr->sender_pcount = pj_htonl(sess->stat.tx.pkt);\n\n\t/* Update octets count */\n\tsr->sender_bcount = pj_htonl(sess->stat.tx.bytes);\n\n\t/* Fill in NTP timestamp in SR. */\n\tsr->ntp_sec = pj_htonl(ntp.hi);\n\tsr->ntp_frac = pj_htonl(ntp.lo);\n\n\t/* Fill in RTP timestamp (corresponds to NTP timestamp) in SR. */\n\tts_time.sec = ntp.hi - sess->tv_base.sec - JAN_1970;\n\tts_time.msec = (long)(ntp.lo * 1000.0 / 0xFFFFFFFF);\n\trtp_ts = sess->rtp_ts_base +\n\t\t (pj_uint32_t)(sess->clock_rate*ts_time.sec) +\n\t\t (pj_uint32_t)(sess->clock_rate*ts_time.msec/1000);\n\tsr->rtp_ts = pj_htonl(rtp_ts);\n\n\tTRACE_((sess->name, \"TX RTCP SR: ntp_ts=%p\", \n\t\t\t   ((ntp.hi & 0xFFFF) << 16) + ((ntp.lo & 0xFFFF0000) \n\t\t\t\t>> 16)));\n\n\n    } else {\n\t/* We should send RTCP RR then */\n\t*ret_p_pkt = (void*) &sess->rtcp_rr_pkt;\n\t*len = sizeof(pjmedia_rtcp_rr_pkt);\n\trr = &sess->rtcp_rr_pkt.rr;\n\tsr = NULL;\n    }\n    \n    /* SSRC and last_seq */\n    rr->ssrc = pj_htonl(sess->peer_ssrc);\n    rr->last_seq = (sess->seq_ctrl.cycles & 0xFFFF0000L);\n    /* Since this is an \"+=\" operation, make sure we update last_seq on\n     * both RR and SR.\n     */\n    sess->rtcp_sr_pkt.rr.last_seq += sess->seq_ctrl.max_seq;\n    sess->rtcp_rr_pkt.rr.last_seq += sess->seq_ctrl.max_seq;\n    rr->last_seq = pj_htonl(rr->last_seq);\n\n\n    /* Jitter */\n    rr->jitter = pj_htonl(sess->jitter >> 4);\n    \n    \n    /* Total lost. */\n    expected = pj_ntohl(rr->last_seq) - sess->seq_ctrl.base_seq;\n\n    /* This is bug: total lost already calculated on each incoming RTP!\n    if (expected >= sess->received)\n\tsess->stat.rx.loss = expected - sess->received;\n    else\n\tsess->stat.rx.loss = 0;\n    */\n\n    rr->total_lost_2 = (sess->stat.rx.loss >> 16) & 0xFF;\n    rr->total_lost_1 = (sess->stat.rx.loss >> 8) & 0xFF;\n    rr->total_lost_0 = (sess->stat.rx.loss & 0xFF);\n\n    /* Fraction lost calculation */\n    expected_interval = expected - sess->exp_prior;\n    sess->exp_prior = expected;\n    \n    received_interval = sess->received - sess->rx_prior;\n    sess->rx_prior = sess->received;\n    \n    if (expected_interval >= received_interval)\n\tlost_interval = expected_interval - received_interval;\n    else\n\tlost_interval = 0;\n    \n    if (expected_interval==0 || lost_interval == 0) {\n\trr->fract_lost = 0;\n    } else {\n\trr->fract_lost = (lost_interval << 8) / expected_interval;\n    }\n    \n    if (sess->rx_lsr_time.u64 == 0 || sess->rx_lsr == 0) {\n\trr->lsr = 0;\n\trr->dlsr = 0;\n    } else {\n\tpj_timestamp ts;\n\tpj_uint32_t lsr = sess->rx_lsr;\n\tpj_uint64_t lsr_time = sess->rx_lsr_time.u64;\n\tpj_uint32_t dlsr;\n\t\n\t/* Convert LSR time to 1/65536 seconds resolution */\n\tlsr_time = (lsr_time << 16) / sess->ts_freq.u64;\n\n\t/* Fill in LSR.\n\t   LSR is the middle 32bit of the last SR NTP time received.\n\t */\n\trr->lsr = pj_htonl(lsr);\n\t\n\t/* Fill in DLSR.\n\t   DLSR is Delay since Last SR, in 1/65536 seconds.\n\t */\n\tts.u64 = ts_now.u64;\n\n\t/* Convert interval to 1/65536 seconds value */\n\tts.u64 = (ts.u64 << 16) / sess->ts_freq.u64;\n\n\t/* Get DLSR */\n\tdlsr = (pj_uint32_t)(ts.u64 - lsr_time);\n\trr->dlsr = pj_htonl(dlsr);\n\n\tTRACE_((sess->name,\"Tx RTCP RR: lsr=%p, lsr_time=%p, now=%p, dlsr=%p\"\n\t\t\t   \"(%ds:%03dms)\",\n\t\t\t   lsr, \n\t\t\t   (pj_uint32_t)lsr_time,\n\t\t\t   (pj_uint32_t)ts.u64, \n\t\t\t   dlsr,\n\t\t\t   dlsr/65536,\n\t\t\t   (dlsr%65536)*1000/65536 ));\n    }\n    \n    /* Update counter */\n    pj_gettimeofday(&sess->stat.rx.update);\n    sess->stat.rx.update_cnt++;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_rtcp_build_rtcp_sdes(\n\t\t\t\t\t    pjmedia_rtcp_session *session, \n\t\t\t\t\t    void *buf,\n\t\t\t\t\t    pj_size_t *length,\n\t\t\t\t\t    const pjmedia_rtcp_sdes *sdes)\n{\n    pjmedia_rtcp_common *hdr;\n    pj_uint8_t *p;\n    pj_size_t len;\n\n    PJ_ASSERT_RETURN(session && buf && length && sdes, PJ_EINVAL);\n\n    /* Verify SDES item length */\n    if (sdes->cname.slen > 255 || sdes->name.slen  > 255 ||\n\tsdes->email.slen > 255 || sdes->phone.slen > 255 ||\n\tsdes->loc.slen   > 255 || sdes->tool.slen  > 255 ||\n\tsdes->note.slen  > 255)\n    {\n\treturn PJ_EINVAL;\n    }\n\n    /* Verify buffer length */\n    len = sizeof(*hdr);\n    if (sdes->cname.slen) len += sdes->cname.slen + 2;\n    if (sdes->name.slen)  len += sdes->name.slen  + 2;\n    if (sdes->email.slen) len += sdes->email.slen + 2;\n    if (sdes->phone.slen) len += sdes->phone.slen + 2;\n    if (sdes->loc.slen)   len += sdes->loc.slen   + 2;\n    if (sdes->tool.slen)  len += sdes->tool.slen  + 2;\n    if (sdes->note.slen)  len += sdes->note.slen  + 2;\n    len++; /* null termination */\n    len = ((len+3)/4) * 4;\n    if (len > *length)\n\treturn PJ_ETOOSMALL;\n\n    /* Build RTCP SDES header */\n    hdr = (pjmedia_rtcp_common*)buf;\n    pj_memcpy(hdr, &session->rtcp_sr_pkt.common,  sizeof(*hdr));\n    hdr->pt = RTCP_SDES;\n    hdr->length = pj_htons((pj_uint16_t)(len/4 - 1));\n\n    /* Build RTCP SDES items */\n    p = (pj_uint8_t*)hdr + sizeof(*hdr);\n#define BUILD_SDES_ITEM(SDES_NAME, SDES_TYPE) \\\n    if (sdes->SDES_NAME.slen) { \\\n\t*p++ = SDES_TYPE; \\\n\t*p++ = (pj_uint8_t)sdes->SDES_NAME.slen; \\\n\tpj_memcpy(p, sdes->SDES_NAME.ptr, sdes->SDES_NAME.slen); \\\n\tp += sdes->SDES_NAME.slen; \\\n    }\n    BUILD_SDES_ITEM(cname, RTCP_SDES_CNAME);\n    BUILD_SDES_ITEM(name,  RTCP_SDES_NAME);\n    BUILD_SDES_ITEM(email, RTCP_SDES_EMAIL);\n    BUILD_SDES_ITEM(phone, RTCP_SDES_PHONE);\n    BUILD_SDES_ITEM(loc,   RTCP_SDES_LOC);\n    BUILD_SDES_ITEM(tool,  RTCP_SDES_TOOL);\n    BUILD_SDES_ITEM(note,  RTCP_SDES_NOTE);\n#undef BUILD_SDES_ITEM\n\n    /* Null termination */\n    *p++ = 0;\n\n    /* Pad to 32bit */\n    while ((p-(pj_uint8_t*)buf) % 4)\n\t*p++ = 0;\n\n    /* Finally */\n    pj_assert((int)len == p-(pj_uint8_t*)buf);\n    *length = len;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_rtcp_build_rtcp_bye(pjmedia_rtcp_session *session,\n\t\t\t\t\t\tvoid *buf,\n\t\t\t\t\t\tpj_size_t *length,\n\t\t\t\t\t\tconst pj_str_t *reason)\n{\n    pjmedia_rtcp_common *hdr;\n    pj_uint8_t *p;\n    pj_size_t len;\n\n    PJ_ASSERT_RETURN(session && buf && length, PJ_EINVAL);\n\n    /* Verify BYE reason length */\n    if (reason && reason->slen > 255)\n\treturn PJ_EINVAL;\n\n    /* Verify buffer length */\n    len = sizeof(*hdr);\n    if (reason && reason->slen) len += reason->slen + 1;\n    len = ((len+3)/4) * 4;\n    if (len > *length)\n\treturn PJ_ETOOSMALL;\n\n    /* Build RTCP BYE header */\n    hdr = (pjmedia_rtcp_common*)buf;\n    pj_memcpy(hdr, &session->rtcp_sr_pkt.common,  sizeof(*hdr));\n    hdr->pt = RTCP_BYE;\n    hdr->length = pj_htons((pj_uint16_t)(len/4 - 1));\n\n    /* Write RTCP BYE reason */\n    p = (pj_uint8_t*)hdr + sizeof(*hdr);\n    if (reason && reason->slen) {\n\t*p++ = (pj_uint8_t)reason->slen;\n\tpj_memcpy(p, reason->ptr, reason->slen);\n\tp += reason->slen;\n    }\n\n    /* Pad to 32bit */\n    while ((p-(pj_uint8_t*)buf) % 4)\n\t*p++ = 0;\n\n    pj_assert((int)len == p-(pj_uint8_t*)buf);\n    *length = len;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_rtcp_build_rtcp_pli(pjmedia_rtcp_session *session,\n\t\t\t\t\t\tvoid *buf,\n\t\t\t\t\t\tpj_size_t *length)\n{\n    pjmedia_rtcp_common *hdr;\n    pj_uint8_t *p;\n    pj_size_t len = 12;    /* pjmedia_rtcp_common + media SSRC (uint32_t) */\n\n    PJ_ASSERT_RETURN(session && buf && length, PJ_EINVAL);\n\n    /* Verify buffer length */\n    if (len > *length)\n\treturn PJ_ETOOSMALL;\n\n    /* Build RTCP PLI */\n    hdr = (pjmedia_rtcp_common*)buf;\n    pj_memcpy(hdr, &session->rtcp_sr_pkt.common,  sizeof(*hdr));\n    hdr->pt = RTCP_PSFB;\n    hdr->count = 1;    /* FMT: 1 == Picture Loss Indication (PLI) */\n    hdr->length = pj_htons((pj_uint16_t)(len/4 - 1));\n\n    p = (pj_uint8_t*)hdr + sizeof(*hdr);\n    pj_memset(p, 0, (pj_uint8_t*)hdr + len - p);\n    *length = len;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_rtcp_enable_xr( pjmedia_rtcp_session *sess, \n\t\t\t\t\t    pj_bool_t enable)\n{\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n\n    /* Check if request won't change anything */\n    if (!(enable ^ sess->xr_enabled))\n\treturn PJ_SUCCESS;\n\n    if (!enable) {\n\tsess->xr_enabled = PJ_FALSE;\n\treturn PJ_SUCCESS;\n    }\n\n    pjmedia_rtcp_xr_init(&sess->xr_session, sess, 0, 1);\n    sess->xr_enabled = PJ_TRUE;\n\n    return PJ_SUCCESS;\n\n#else\n\n    PJ_UNUSED_ARG(sess);\n    PJ_UNUSED_ARG(enable);\n    return PJ_ENOTSUP;\n\n#endif\n}\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/rtcp_xr.c",
    "content": "/* $Id: rtcp_xr.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pjmedia/rtcp_xr.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/rtcp.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/sock.h>\n#include <pj/string.h>\n\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n\n#define THIS_FILE \"rtcp_xr.c\"\n\n\n#if PJ_HAS_HIGH_RES_TIMER==0\n#   error \"High resolution timer needs to be enabled\"\n#endif\n\n\n/* RTCP XR payload type */\n#define RTCP_XR\t\t    207\n\n/* RTCP XR block types */\n#define BT_LOSS_RLE\t    1\n#define BT_DUP_RLE\t    2\n#define BT_RCPT_TIMES\t    3\n#define BT_RR_TIME\t    4\n#define BT_DLRR\t\t    5\n#define BT_STATS\t    6\n#define BT_VOIP_METRICS\t    7\n\n\n#define DEFAULT_GMIN\t    16\n\n\n#if 0\n#   define TRACE_(x)\tPJ_LOG(3,x)\n#else\n#   define TRACE_(x)\t;\n#endif\n\nvoid pjmedia_rtcp_xr_init( pjmedia_rtcp_xr_session *session, \n\t\t\t   struct pjmedia_rtcp_session *parent_session,\n\t\t\t   pj_uint8_t gmin,\n\t\t\t   unsigned frames_per_packet)\n{\n    pj_bzero(session, sizeof(pjmedia_rtcp_xr_session));\n\n    session->name = parent_session->name;\n    session->rtcp_session = parent_session;\n    pj_memcpy(&session->pkt.common, &session->rtcp_session->rtcp_sr_pkt.common,\n\t      sizeof(pjmedia_rtcp_common));\n    session->pkt.common.pt = RTCP_XR;\n\n    /* Init config */\n    session->stat.rx.voip_mtc.gmin = (pj_uint8_t)(gmin? gmin : DEFAULT_GMIN);\n    session->ptime = session->rtcp_session->pkt_size * 1000 / \n\t\t     session->rtcp_session->clock_rate;\n    session->frames_per_packet = frames_per_packet;\n\n    /* Init Statistics Summary fields which have non-zero default */\n    session->stat.rx.stat_sum.jitter.min = (unsigned) -1;\n    session->stat.rx.stat_sum.toh.min = (unsigned) -1;\n\n    /* Init VoIP Metrics fields which have non-zero default */\n    session->stat.rx.voip_mtc.signal_lvl = 127;\n    session->stat.rx.voip_mtc.noise_lvl = 127;\n    session->stat.rx.voip_mtc.rerl = 127;\n    session->stat.rx.voip_mtc.r_factor = 127;\n    session->stat.rx.voip_mtc.ext_r_factor = 127;\n    session->stat.rx.voip_mtc.mos_lq = 127;\n    session->stat.rx.voip_mtc.mos_cq = 127;\n\n    session->stat.tx.voip_mtc.signal_lvl = 127;\n    session->stat.tx.voip_mtc.noise_lvl = 127;\n    session->stat.tx.voip_mtc.rerl = 127;\n    session->stat.tx.voip_mtc.r_factor = 127;\n    session->stat.tx.voip_mtc.ext_r_factor = 127;\n    session->stat.tx.voip_mtc.mos_lq = 127;\n    session->stat.tx.voip_mtc.mos_cq = 127;\n}\n\nvoid pjmedia_rtcp_xr_fini(pjmedia_rtcp_xr_session *session)\n{\n    PJ_UNUSED_ARG(session);\n}\n\nPJ_DEF(void) pjmedia_rtcp_build_rtcp_xr( pjmedia_rtcp_xr_session *sess, \n\t\t\t\t\t unsigned rpt_types,\n\t\t\t\t\t void **rtcp_pkt, int *len)\n{\n    pj_uint16_t size = 0;\n\n    /* Receiver Reference Time Report Block */\n    /* Build this block if we have received packets since last build */\n    if ((rpt_types == 0 || (rpt_types & PJMEDIA_RTCP_XR_RR_TIME)) &&\n\tsess->rx_last_rr != sess->rtcp_session->stat.rx.pkt)\n    {\n\tpjmedia_rtcp_xr_rb_rr_time *r;\n\tpjmedia_rtcp_ntp_rec ntp;\n\n\tr = (pjmedia_rtcp_xr_rb_rr_time*) &sess->pkt.buf[size];\n\tpj_bzero(r, sizeof(pjmedia_rtcp_xr_rb_rr_time));\n\n\t/* Init block header */\n\tr->header.bt = BT_RR_TIME;\n\tr->header.specific = 0;\n\tr->header.length = pj_htons(2);\n\n\t/* Generate block contents */\n\tpjmedia_rtcp_get_ntp_time(sess->rtcp_session, &ntp);\n\tr->ntp_sec = pj_htonl(ntp.hi);\n\tr->ntp_frac = pj_htonl(ntp.lo);\n\n\t/* Finally */\n\tsize += sizeof(pjmedia_rtcp_xr_rb_rr_time);\n\tsess->rx_last_rr = sess->rtcp_session->stat.rx.pkt;\n    }\n\n    /* DLRR Report Block */\n    /* Build this block if we have received RR NTP (rx_lrr) before */\n    if ((rpt_types == 0 || (rpt_types & PJMEDIA_RTCP_XR_DLRR)) && \n\tsess->rx_lrr)\n    {\n\tpjmedia_rtcp_xr_rb_dlrr *r;\n\tpjmedia_rtcp_xr_rb_dlrr_item *dlrr_item;\n\tpj_timestamp ts;\n\n\tr = (pjmedia_rtcp_xr_rb_dlrr*) &sess->pkt.buf[size];\n\tpj_bzero(r, sizeof(pjmedia_rtcp_xr_rb_dlrr));\n\n\t/* Init block header */\n\tr->header.bt = BT_DLRR;\n\tr->header.specific = 0;\n\tr->header.length = pj_htons(sizeof(pjmedia_rtcp_xr_rb_dlrr)/4 - 1);\n\n\t/* Generate block contents */\n\tdlrr_item = &r->item;\n\tdlrr_item->ssrc = pj_htonl(sess->rtcp_session->peer_ssrc);\n\tdlrr_item->lrr = pj_htonl(sess->rx_lrr);\n\n\t/* Calculate DLRR */\n\tif (sess->rx_lrr != 0) {\n\t    pj_get_timestamp(&ts);\n\t    ts.u64 -= sess->rx_lrr_time.u64;\n\t\n\t    /* Convert DLRR time to 1/65536 seconds resolution */\n\t    ts.u64 = (ts.u64 << 16) / sess->rtcp_session->ts_freq.u64;\n\t    dlrr_item->dlrr = pj_htonl(ts.u32.lo);\n\t} else {\n\t    dlrr_item->dlrr = 0;\n\t}\n\n\t/* Finally */\n\tsize += sizeof(pjmedia_rtcp_xr_rb_dlrr);\n    }\n\n    /* Statistics Summary Block */\n    /* Build this block if we have received packets since last build */\n    if ((rpt_types == 0 || (rpt_types & PJMEDIA_RTCP_XR_STATS)) &&\n\tsess->stat.rx.stat_sum.count > 0)\n    {\n\tpjmedia_rtcp_xr_rb_stats *r;\n\tpj_uint8_t specific = 0;\n\n\tr = (pjmedia_rtcp_xr_rb_stats*) &sess->pkt.buf[size];\n\tpj_bzero(r, sizeof(pjmedia_rtcp_xr_rb_stats));\n\n\t/* Init block header */\n\tspecific |= sess->stat.rx.stat_sum.l ? (1 << 7) : 0;\n\tspecific |= sess->stat.rx.stat_sum.d ? (1 << 6) : 0;\n\tspecific |= sess->stat.rx.stat_sum.j ? (1 << 5) : 0;\n\tspecific |= (sess->stat.rx.stat_sum.t & 3) << 3;\n\tr->header.bt = BT_STATS;\n\tr->header.specific = specific;\n\tr->header.length = pj_htons(9);\n\n\t/* Generate block contents */\n\tr->ssrc = pj_htonl(sess->rtcp_session->peer_ssrc);\n\tr->begin_seq = pj_htons((pj_uint16_t)\n\t\t\t\t(sess->stat.rx.stat_sum.begin_seq & 0xFFFF));\n\tr->end_seq = pj_htons((pj_uint16_t)\n\t\t\t      (sess->stat.rx.stat_sum.end_seq & 0xFFFF));\n\tif (sess->stat.rx.stat_sum.l) {\n\t    r->lost = pj_htonl(sess->stat.rx.stat_sum.lost);\n\t}\n\tif (sess->stat.rx.stat_sum.d) {\n\t    r->dup = pj_htonl(sess->stat.rx.stat_sum.dup);\n\t}\n\tif (sess->stat.rx.stat_sum.j) {\n\t    r->jitter_min = pj_htonl(sess->stat.rx.stat_sum.jitter.min);\n\t    r->jitter_max = pj_htonl(sess->stat.rx.stat_sum.jitter.max);\n\t    r->jitter_mean = \n\t\tpj_htonl((unsigned)sess->stat.rx.stat_sum.jitter.mean);\n\t    r->jitter_dev = \n\t\tpj_htonl(pj_math_stat_get_stddev(&sess->stat.rx.stat_sum.jitter));\n\t}\n\tif (sess->stat.rx.stat_sum.t) {\n\t    r->toh_min = sess->stat.rx.stat_sum.toh.min;\n\t    r->toh_max = sess->stat.rx.stat_sum.toh.max;\n\t    r->toh_mean = (unsigned) sess->stat.rx.stat_sum.toh.mean;\n\t    r->toh_dev = pj_math_stat_get_stddev(&sess->stat.rx.stat_sum.toh);\n\t}\n\n\t/* Reset TX statistics summary each time built */\n\tpj_bzero(&sess->stat.rx.stat_sum, sizeof(sess->stat.rx.stat_sum));\n\tsess->stat.rx.stat_sum.jitter.min = (unsigned) -1;\n\tsess->stat.rx.stat_sum.toh.min = (unsigned) -1;\n\n\t/* Finally */\n\tsize += sizeof(pjmedia_rtcp_xr_rb_stats);\n\tpj_gettimeofday(&sess->stat.rx.stat_sum.update);\n    }\n\n    /* Voip Metrics Block */\n    /* Build this block if we have received packets */\n    if ((rpt_types == 0 || (rpt_types & PJMEDIA_RTCP_XR_VOIP_METRICS)) &&\n\tsess->rtcp_session->stat.rx.pkt)\n    {\n\tpjmedia_rtcp_xr_rb_voip_mtc *r;\n\tpj_uint32_t c11;\n\tpj_uint32_t c13;\n\tpj_uint32_t c14;\n\tpj_uint32_t c22;\n\tpj_uint32_t c23;\n\tpj_uint32_t c31;\n\tpj_uint32_t c32;\n\tpj_uint32_t c33;\n\tpj_uint32_t ctotal, m;\n\tunsigned est_extra_delay;\n\n\tr = (pjmedia_rtcp_xr_rb_voip_mtc*) &sess->pkt.buf[size];\n\tpj_bzero(r, sizeof(pjmedia_rtcp_xr_rb_voip_mtc));\n\n\t/* Init block header */\n\tr->header.bt = BT_VOIP_METRICS;\n\tr->header.specific = 0;\n\tr->header.length = pj_htons(8);\n\n\t/* Use temp vars for easiness. */\n\tc11 = sess->voip_mtc_stat.c11;\n\tc13 = sess->voip_mtc_stat.c13;\n\tc14 = sess->voip_mtc_stat.c14;\n\tc22 = sess->voip_mtc_stat.c22;\n\tc23 = sess->voip_mtc_stat.c23;\n\tc33 = sess->voip_mtc_stat.c33;\n\tm = sess->ptime * sess->frames_per_packet;\n\n\t/* Calculate additional transition counts. */\n\tc31 = c13;\n\tc32 = c23;\n\tctotal = c11 + c14 + c13 + c22 + c23 + c31 + c32 + c33;\n\n\tif (ctotal) {\n\t    pj_uint32_t p32, p23;\n\n\t    //original version:\n\t    //p32 = c32 / (c31 + c32 + c33);\n\t    if (c31 + c32 + c33 == 0)\n\t\tp32 = 0;\n\t    else\n\t\tp32 = (c32 << 16) / (c31 + c32 + c33);\n\n\t    //original version:\n\t    //if ((c22 + c23) < 1) {\n\t    //    p23 = 1;\n\t    //} else {\n\t    //    p23 = 1 - c22 / (c22 + c23);\n\t    //}\n\t    if (c23 == 0) {\n\t        p23 = 0;\n\t    } else {\n\t        p23 = (c23 << 16) / (c22 + c23);\n\t    }\n\n\t    /* Calculate loss/discard densities, scaled of 0-256 */\n\t    if (c11 == 0)\n\t\tsess->stat.rx.voip_mtc.gap_den = 0;\n\t    else\n\t\tsess->stat.rx.voip_mtc.gap_den = (pj_uint8_t)\n\t\t\t\t\t\t ((c14 << 8) / (c11 + c14));\n\t    if (p23 == 0)\n\t\tsess->stat.rx.voip_mtc.burst_den = 0;\n\t    else\n\t\tsess->stat.rx.voip_mtc.burst_den = (pj_uint8_t)\n\t\t\t\t\t\t   ((p23 << 8) / (p23 + p32));\n\n\t    /* Calculate (average) durations, in ms */\n\t    if (c13 == 0) {\n\t\tc13 = 1;\n\t\tctotal += 1;\n\t    }\n\t    sess->stat.rx.voip_mtc.gap_dur = (pj_uint16_t)\n\t\t\t\t\t    ((c11+c14+c13) * m / c13);\n\t    sess->stat.rx.voip_mtc.burst_dur = (pj_uint16_t)\n\t\t\t\t\t    ((ctotal - (c11+c14+c13)) * m / c13);\n\n\t    /* Callculate loss/discard rates, scaled 0-256 */\n\t    sess->stat.rx.voip_mtc.loss_rate = (pj_uint8_t)\n\t\t\t((sess->voip_mtc_stat.loss_count << 8) / ctotal);\n\t    sess->stat.rx.voip_mtc.discard_rate = (pj_uint8_t)\n\t\t\t((sess->voip_mtc_stat.discard_count << 8) / ctotal);\n\t} else {\n\t    /* No lost/discarded packet yet. */\n\t    sess->stat.rx.voip_mtc.gap_den = 0;\n\t    sess->stat.rx.voip_mtc.burst_den = 0;\n\t    sess->stat.rx.voip_mtc.gap_dur = 0;\n\t    sess->stat.rx.voip_mtc.burst_dur = 0;\n\t    sess->stat.rx.voip_mtc.loss_rate = 0;\n\t    sess->stat.rx.voip_mtc.discard_rate = 0;\n\t}\n\n\t/* Set round trip delay (in ms) to RTT calculated after receiving\n\t * DLRR or DLSR.\n\t */\n\tif (sess->stat.rtt.last)\n\t    sess->stat.rx.voip_mtc.rnd_trip_delay = (pj_uint16_t)\n\t\t\t\t    (sess->stat.rtt.last / 1000);\n\telse if (sess->rtcp_session->stat.rtt.last)\n\t    sess->stat.rx.voip_mtc.rnd_trip_delay = (pj_uint16_t)\n\t\t\t\t    (sess->rtcp_session->stat.rtt.last / 1000);\n\t\n\t/* End system delay = RTT/2 + current jitter buffer size + \n\t *                    EXTRA (estimated extra delay)\n\t * EXTRA will cover additional delay introduced by other components of\n\t * audio engine, e.g: sound device, codec, AEC, PLC, WSOLA.\n\t * Since it is difficult to get the exact value of EXTRA, estimation\n\t * is taken to be totally around 30ms + sound device latency.\n\t */\n\test_extra_delay = 30;\n\n#if PJMEDIA_SOUND_IMPLEMENTATION!=PJMEDIA_SOUND_NULL_SOUND\n\test_extra_delay += PJMEDIA_SND_DEFAULT_REC_LATENCY + \n\t\t\t   PJMEDIA_SND_DEFAULT_PLAY_LATENCY;\n#endif\n\n\tsess->stat.rx.voip_mtc.end_sys_delay = (pj_uint16_t)\n\t\t\t\t (sess->stat.rx.voip_mtc.rnd_trip_delay / 2 +\n\t\t\t\t sess->stat.rx.voip_mtc.jb_nom + \n\t\t\t\t est_extra_delay);\n\n\t/* Generate block contents */\n\tr->ssrc\t\t    = pj_htonl(sess->rtcp_session->peer_ssrc);\n\tr->loss_rate\t    = sess->stat.rx.voip_mtc.loss_rate;\n\tr->discard_rate\t    = sess->stat.rx.voip_mtc.discard_rate;\n\tr->burst_den\t    = sess->stat.rx.voip_mtc.burst_den;\n\tr->gap_den\t    = sess->stat.rx.voip_mtc.gap_den;\n\tr->burst_dur\t    = pj_htons(sess->stat.rx.voip_mtc.burst_dur);\n\tr->gap_dur\t    = pj_htons(sess->stat.rx.voip_mtc.gap_dur);\n\tr->rnd_trip_delay   = pj_htons(sess->stat.rx.voip_mtc.rnd_trip_delay);\n\tr->end_sys_delay    = pj_htons(sess->stat.rx.voip_mtc.end_sys_delay);\n\t/* signal & noise level encoded in two's complement form */\n\tr->signal_lvl\t    = (pj_uint8_t) \n\t\t\t      ((sess->stat.rx.voip_mtc.signal_lvl >= 0)?\n\t\t\t       sess->stat.rx.voip_mtc.signal_lvl :\n\t\t\t       (sess->stat.rx.voip_mtc.signal_lvl + 256));\n\tr->noise_lvl\t    = (pj_uint8_t)\n\t\t\t      ((sess->stat.rx.voip_mtc.noise_lvl >= 0)?\n\t\t\t       sess->stat.rx.voip_mtc.noise_lvl :\n\t\t\t       (sess->stat.rx.voip_mtc.noise_lvl + 256));\n\tr->rerl\t\t    = sess->stat.rx.voip_mtc.rerl;\n\tr->gmin\t\t    = sess->stat.rx.voip_mtc.gmin;\n\tr->r_factor\t    = sess->stat.rx.voip_mtc.r_factor;\n\tr->ext_r_factor\t    = sess->stat.rx.voip_mtc.ext_r_factor;\n\tr->mos_lq\t    = sess->stat.rx.voip_mtc.mos_lq;\n\tr->mos_cq\t    = sess->stat.rx.voip_mtc.mos_cq;\n\tr->rx_config\t    = sess->stat.rx.voip_mtc.rx_config;\n\tr->jb_nom\t    = pj_htons(sess->stat.rx.voip_mtc.jb_nom);\n\tr->jb_max\t    = pj_htons(sess->stat.rx.voip_mtc.jb_max);\n\tr->jb_abs_max\t    = pj_htons(sess->stat.rx.voip_mtc.jb_abs_max);\n\n\t/* Finally */\n\tsize += sizeof(pjmedia_rtcp_xr_rb_voip_mtc);\n\tpj_gettimeofday(&sess->stat.rx.voip_mtc.update);\n    }\n\n    /* Add RTCP XR header size */\n    size += sizeof(sess->pkt.common);\n\n    /* Set RTCP XR header 'length' to packet size in 32-bit unit minus one */\n    sess->pkt.common.length = pj_htons((pj_uint16_t)(size/4 - 1));\n\n    /* Set the return values */\n    *rtcp_pkt = (void*) &sess->pkt;\n    *len = size;\n}\n\n\nvoid pjmedia_rtcp_xr_rx_rtcp_xr( pjmedia_rtcp_xr_session *sess,\n\t\t\t\t const void *pkt,\n\t\t\t\t pj_size_t size)\n{\n    const pjmedia_rtcp_xr_pkt\t      *rtcp_xr = (pjmedia_rtcp_xr_pkt*) pkt;\n    const pjmedia_rtcp_xr_rb_rr_time  *rb_rr_time = NULL;\n    const pjmedia_rtcp_xr_rb_dlrr     *rb_dlrr = NULL;\n    const pjmedia_rtcp_xr_rb_stats    *rb_stats = NULL;\n    const pjmedia_rtcp_xr_rb_voip_mtc *rb_voip_mtc = NULL;\n    const pjmedia_rtcp_xr_rb_header   *rb_hdr = (pjmedia_rtcp_xr_rb_header*) \n\t\t\t\t\t\trtcp_xr->buf;\n    unsigned pkt_len, rb_len;\n\n    if (rtcp_xr->common.pt != RTCP_XR)\n\treturn;\n\n    pkt_len = pj_ntohs((pj_uint16_t)rtcp_xr->common.length);\n\n    if ((pkt_len + 1) > (size / 4))\n\treturn;\n\n    /* Parse report rpt_types */\n    while ((pj_int32_t*)rb_hdr < (pj_int32_t*)pkt + pkt_len)\n    {\t\n\trb_len = pj_ntohs((pj_uint16_t)rb_hdr->length);\n\n\t/* Just skip any block with length == 0 (no report content) */\n\tif (rb_len) {\n\t    switch (rb_hdr->bt) {\n\t\tcase BT_RR_TIME:\n\t\t    rb_rr_time = (pjmedia_rtcp_xr_rb_rr_time*) rb_hdr;\n\t\t    break;\n\t\tcase BT_DLRR:\n\t\t    rb_dlrr = (pjmedia_rtcp_xr_rb_dlrr*) rb_hdr;\n\t\t    break;\n\t\tcase BT_STATS:\n\t\t    rb_stats = (pjmedia_rtcp_xr_rb_stats*) rb_hdr;\n\t\t    break;\n\t\tcase BT_VOIP_METRICS:\n\t\t    rb_voip_mtc = (pjmedia_rtcp_xr_rb_voip_mtc*) rb_hdr;\n\t\t    break;\n\t\tdefault:\n\t\t    break;\n\t    }\n\t}\n\trb_hdr = (pjmedia_rtcp_xr_rb_header*)\n\t\t ((pj_int32_t*)rb_hdr + rb_len + 1);\n    }\n\n    /* Receiving RR Time */\n    if (rb_rr_time) {\n\t/* Save LRR from NTP timestamp of the RR time block report */\n\tsess->rx_lrr = ((pj_ntohl(rb_rr_time->ntp_sec) & 0x0000FFFF) << 16) | \n\t\t       ((pj_ntohl(rb_rr_time->ntp_frac) >> 16) & 0xFFFF);\n\n\t/* Calculate RR arrival time for DLRR */\n\tpj_get_timestamp(&sess->rx_lrr_time);\n\n\tTRACE_((sess->name, \"Rx RTCP SR: ntp_ts=%p\", sess->rx_lrr,\n\t       (pj_uint32_t)(sess->rx_lrr_time.u64*65536/\n\t\t\t     sess->rtcp_session->ts_freq.u64)));\n    }\n\n    /* Receiving DLRR */\n    if (rb_dlrr) {\n\tpj_uint32_t lrr, now, dlrr;\n\tpj_uint64_t eedelay;\n\tpjmedia_rtcp_ntp_rec ntp;\n\n\t/* LRR is the middle 32bit of NTP. It has 1/65536 second \n\t * resolution \n\t */\n\tlrr = pj_ntohl(rb_dlrr->item.lrr);\n\n\t/* DLRR is delay since LRR, also in 1/65536 resolution */\n\tdlrr = pj_ntohl(rb_dlrr->item.dlrr);\n\n\t/* Get current time, and convert to 1/65536 resolution */\n\tpjmedia_rtcp_get_ntp_time(sess->rtcp_session, &ntp);\n\tnow = ((ntp.hi & 0xFFFF) << 16) + (ntp.lo >> 16);\n\n\t/* End-to-end delay is (now-lrr-dlrr) */\n\teedelay = now - lrr - dlrr;\n\n\t/* Convert end to end delay to usec (keeping the calculation in\n         * 64bit space)::\n\t *   sess->ee_delay = (eedelay * 1000) / 65536;\n\t */\n\tif (eedelay < 4294) {\n\t    eedelay = (eedelay * 1000000) >> 16;\n\t} else {\n\t    eedelay = (eedelay * 1000) >> 16;\n\t    eedelay *= 1000;\n\t}\n\n\tTRACE_((sess->name, \"Rx RTCP XR DLRR: lrr=%p, dlrr=%p (%d:%03dms), \"\n\t\t\t   \"now=%p, rtt=%p\",\n\t\tlrr, dlrr, dlrr/65536, (dlrr%65536)*1000/65536,\n\t\tnow, (pj_uint32_t)eedelay));\n\t\n\t/* Only save calculation if \"now\" is greater than lrr, or\n\t * otherwise rtt will be invalid \n\t */\n\tif (now-dlrr >= lrr) {\n\t    unsigned rtt = (pj_uint32_t)eedelay;\n\t    \n\t    /* Check that eedelay value really makes sense. \n\t     * We allow up to 30 seconds RTT!\n\t     */\n\t    if (eedelay <= 30 * 1000 * 1000UL) {\n\t\t/* \"Normalize\" rtt value that is exceptionally high.\n\t\t * For such values, \"normalize\" the rtt to be three times\n\t\t * the average value.\n\t\t */\n\t\tif (rtt>((unsigned)sess->stat.rtt.mean*3) && sess->stat.rtt.n!=0)\n\t\t{\n\t\t    unsigned orig_rtt = rtt;\n\t\t    rtt = (unsigned)sess->stat.rtt.mean*3;\n\t\t    PJ_LOG(5,(sess->name, \n\t\t\t      \"RTT value %d usec is normalized to %d usec\",\n\t\t\t      orig_rtt, rtt));\n\t\t}\n    \t\n\t\tTRACE_((sess->name, \"RTCP RTT is set to %d usec\", rtt));\n\t\tpj_math_stat_update(&sess->stat.rtt, rtt);\n\t    }\n\t} else {\n\t    PJ_LOG(5, (sess->name, \"Internal RTCP NTP clock skew detected: \"\n\t\t\t\t   \"lrr=%p, now=%p, dlrr=%p (%d:%03dms), \"\n\t\t\t\t   \"diff=%d\",\n\t\t\t\t   lrr, now, dlrr, dlrr/65536,\n\t\t\t\t   (dlrr%65536)*1000/65536,\n\t\t\t\t   dlrr-(now-lrr)));\n\t}\n    }\n\n    /* Receiving Statistics Summary */\n    if (rb_stats) {\n\tpj_uint8_t flags = rb_stats->header.specific;\n\n\tpj_bzero(&sess->stat.tx.stat_sum, sizeof(sess->stat.tx.stat_sum));\n\n\t/* Range of packets sequence reported in this blocks */\n\tsess->stat.tx.stat_sum.begin_seq = pj_ntohs(rb_stats->begin_seq);\n\tsess->stat.tx.stat_sum.end_seq   = pj_ntohs(rb_stats->end_seq);\n\n\t/* Get flags of valid fields */\n\tsess->stat.tx.stat_sum.l = (flags & (1 << 7)) != 0;\n\tsess->stat.tx.stat_sum.d = (flags & (1 << 6)) != 0;\n\tsess->stat.tx.stat_sum.j = (flags & (1 << 5)) != 0;\n\tsess->stat.tx.stat_sum.t = (flags & (3 << 3)) != 0;\n\n\t/* Fetch the reports info */\n\tif (sess->stat.tx.stat_sum.l) {\n\t    sess->stat.tx.stat_sum.lost = pj_ntohl(rb_stats->lost);\n\t}\n\n\tif (sess->stat.tx.stat_sum.d) {\n\t    sess->stat.tx.stat_sum.dup = pj_ntohl(rb_stats->dup);\n\t}\n\n\tif (sess->stat.tx.stat_sum.j) {\n\t    sess->stat.tx.stat_sum.jitter.min = pj_ntohl(rb_stats->jitter_min);\n\t    sess->stat.tx.stat_sum.jitter.max = pj_ntohl(rb_stats->jitter_max);\n\t    sess->stat.tx.stat_sum.jitter.mean= pj_ntohl(rb_stats->jitter_mean);\n\t    pj_math_stat_set_stddev(&sess->stat.tx.stat_sum.jitter, \n\t\t\t\t    pj_ntohl(rb_stats->jitter_dev));\n\t}\n\n\tif (sess->stat.tx.stat_sum.t) {\n\t    sess->stat.tx.stat_sum.toh.min = rb_stats->toh_min;\n\t    sess->stat.tx.stat_sum.toh.max = rb_stats->toh_max;\n\t    sess->stat.tx.stat_sum.toh.mean= rb_stats->toh_mean;\n\t    pj_math_stat_set_stddev(&sess->stat.tx.stat_sum.toh, \n\t\t\t\t    pj_ntohl(rb_stats->toh_dev));\n\t}\n\n\tpj_gettimeofday(&sess->stat.tx.stat_sum.update);\n    }\n\n    /* Receiving VoIP Metrics */\n    if (rb_voip_mtc) {\n\tsess->stat.tx.voip_mtc.loss_rate = rb_voip_mtc->loss_rate;\n\tsess->stat.tx.voip_mtc.discard_rate = rb_voip_mtc->discard_rate;\n\tsess->stat.tx.voip_mtc.burst_den = rb_voip_mtc->burst_den;\n\tsess->stat.tx.voip_mtc.gap_den = rb_voip_mtc->gap_den;\n\tsess->stat.tx.voip_mtc.burst_dur = pj_ntohs(rb_voip_mtc->burst_dur);\n\tsess->stat.tx.voip_mtc.gap_dur = pj_ntohs(rb_voip_mtc->gap_dur);\n\tsess->stat.tx.voip_mtc.rnd_trip_delay = \n\t\t\t\t\tpj_ntohs(rb_voip_mtc->rnd_trip_delay);\n\tsess->stat.tx.voip_mtc.end_sys_delay = \n\t\t\t\t\tpj_ntohs(rb_voip_mtc->end_sys_delay);\n\t/* signal & noise level encoded in two's complement form */\n\tsess->stat.tx.voip_mtc.signal_lvl = (pj_int8_t)\n\t\t\t\t    ((rb_voip_mtc->signal_lvl > 127)?\n\t\t\t\t     ((int)rb_voip_mtc->signal_lvl - 256) : \n\t\t\t\t     rb_voip_mtc->signal_lvl);\n\tsess->stat.tx.voip_mtc.noise_lvl  = (pj_int8_t)\n\t\t\t\t    ((rb_voip_mtc->noise_lvl > 127)?\n\t\t\t\t     ((int)rb_voip_mtc->noise_lvl - 256) : \n\t\t\t\t     rb_voip_mtc->noise_lvl);\n\tsess->stat.tx.voip_mtc.rerl = rb_voip_mtc->rerl;\n\tsess->stat.tx.voip_mtc.gmin = rb_voip_mtc->gmin;\n\tsess->stat.tx.voip_mtc.r_factor = rb_voip_mtc->r_factor;\n\tsess->stat.tx.voip_mtc.ext_r_factor = rb_voip_mtc->ext_r_factor;\n\tsess->stat.tx.voip_mtc.mos_lq = rb_voip_mtc->mos_lq;\n\tsess->stat.tx.voip_mtc.mos_cq = rb_voip_mtc->mos_cq;\n\tsess->stat.tx.voip_mtc.rx_config = rb_voip_mtc->rx_config;\n\tsess->stat.tx.voip_mtc.jb_nom = pj_ntohs(rb_voip_mtc->jb_nom);\n\tsess->stat.tx.voip_mtc.jb_max = pj_ntohs(rb_voip_mtc->jb_max);\n\tsess->stat.tx.voip_mtc.jb_abs_max = pj_ntohs(rb_voip_mtc->jb_abs_max);\n\n\tpj_gettimeofday(&sess->stat.tx.voip_mtc.update);\n    }\n}\n\n/* Place seq into a 32-bit sequence number space based upon a\n * heuristic for its most likely location.\n */\nstatic pj_uint32_t extend_seq(pjmedia_rtcp_xr_session *sess,\n\t\t\t      const pj_uint16_t seq)\n{\n\n    pj_uint32_t extended_seq, seq_a, seq_b, diff_a, diff_b;\n    if(sess->uninitialized_src_ref_seq) {\n\t/* This is the first sequence number received.  Place\n\t * it in the middle of the extended sequence number\n\t * space.\n\t */\n\tsess->src_ref_seq = seq | 0x80000000u;\n\tsess->uninitialized_src_ref_seq = PJ_FALSE;\n\textended_seq = sess->src_ref_seq;\n    } else {\n\t/* Prior sequence numbers have been received.\n\t * Propose two candidates for the extended sequence\n\t * number: seq_a is without wraparound, seq_b with\n\t * wraparound.\n\t */\n\tseq_a = seq | (sess->src_ref_seq & 0xFFFF0000u);\n\tif(sess->src_ref_seq < seq_a) {\n\t    seq_b  = seq_a - 0x00010000u;\n\t    diff_a = seq_a - sess->src_ref_seq;\n\t    diff_b = sess->src_ref_seq - seq_b;\n\t} else {\n\t    seq_b  = seq_a + 0x00010000u;\n\t    diff_a = sess->src_ref_seq - seq_a;\n\t    diff_b = seq_b - sess->src_ref_seq;\n\t}\n\n\t/* Choose the closer candidate.  If they are equally\n\t * close, the choice is somewhat arbitrary: we choose\n\t * the candidate for which no rollover is necessary.\n\t */\n\tif(diff_a < diff_b) {\n\t    extended_seq = seq_a;\n\t} else {\n\t    extended_seq = seq_b;\n\t}\n\n\t/* Set the reference sequence number to be this most\n\t * recently-received sequence number.\n\t */\n\tsess->src_ref_seq = extended_seq;\n    }\n\n    /* Return our best guess for a 32-bit sequence number that\n     * corresponds to the 16-bit number we were given.\n     */\n    return extended_seq;\n}\n\nvoid pjmedia_rtcp_xr_rx_rtp( pjmedia_rtcp_xr_session *sess,\n\t\t\t     unsigned seq, \n\t\t\t     int lost,\n\t\t\t     int dup,\n\t\t\t     int discarded,\n\t\t\t     int jitter,\n\t\t\t     int toh, pj_bool_t toh_ipv4)\n{\n    pj_uint32_t ext_seq;\n\n    /* Get 32 bit version of sequence */\n    ext_seq = extend_seq(sess, (pj_uint16_t)seq);\n\n    /* Update statistics summary */\n    sess->stat.rx.stat_sum.count++;\n\n    if (sess->stat.rx.stat_sum.begin_seq == 0 || \n\tsess->stat.rx.stat_sum.begin_seq > ext_seq)\n    {\n\tsess->stat.rx.stat_sum.begin_seq = ext_seq;\n    }\n\n    if (sess->stat.rx.stat_sum.end_seq == 0 || \n\tsess->stat.rx.stat_sum.end_seq < ext_seq)\n    {\n\tsess->stat.rx.stat_sum.end_seq = ext_seq;\n    }\n\n    if (lost >= 0) {\n\tsess->stat.rx.stat_sum.l = PJ_TRUE;\n\tif (lost > 0)\n\t    sess->stat.rx.stat_sum.lost++;\n    }\n\n    if (dup >= 0) {\n\tsess->stat.rx.stat_sum.d = PJ_TRUE;\n\tif (dup > 0)\n\t    sess->stat.rx.stat_sum.dup++;\n    }\n\n    if (jitter >= 0) {\n\tsess->stat.rx.stat_sum.j = PJ_TRUE;\n\tpj_math_stat_update(&sess->stat.rx.stat_sum.jitter, jitter);\n    }\n\n    if (toh >= 0) {\n\tsess->stat.rx.stat_sum.t = toh_ipv4? 1 : 2;\n\tpj_math_stat_update(&sess->stat.rx.stat_sum.toh, toh);\n    }\n\n    /* Update burst metrics.\n     * There are two terms introduced in the RFC 3611: gap & burst.\n     * Gap represents good stream condition, lost+discard rate <= 1/Gmin.\n     * Burst represents the opposite, lost+discard rate > 1/Gmin.\n     */\n    if (lost >= 0 && discarded >= 0) {\n\tif(lost > 0) {\n\t    sess->voip_mtc_stat.loss_count++;\n\t}\n\tif(discarded > 0) {\n\t    sess->voip_mtc_stat.discard_count++;\n\t}\n\tif(!lost && !discarded) {\n\t    /* Number of good packets since last lost/discarded */\n\t    sess->voip_mtc_stat.pkt++;\n\t}\n\telse {\n\t    if(sess->voip_mtc_stat.pkt >= sess->stat.rx.voip_mtc.gmin) {\n\t\t/* Gap condition */\n\t\tif(sess->voip_mtc_stat.lost == 1) {\n\t\t    /* Gap -> Gap */\n\t\t    sess->voip_mtc_stat.c14++;\n\t\t}\n\t\telse {\n\t\t    /* Burst -> Gap */\n\t\t    sess->voip_mtc_stat.c13++;\n\t\t}\n\t\tsess->voip_mtc_stat.lost = 1;\n\t\tsess->voip_mtc_stat.c11 += sess->voip_mtc_stat.pkt;\n\t    }\n\t    else {\n\t\t/* Burst condition */\n\t\tsess->voip_mtc_stat.lost++;\n\t\tif(sess->voip_mtc_stat.pkt == 0) {\n\t\t    /* Consecutive losts */\n\t\t    sess->voip_mtc_stat.c33++;\n\t\t}\n\t\telse {\n\t\t    /* Any good packets, but still bursting */\n\t\t    sess->voip_mtc_stat.c23++;\n\t\t    sess->voip_mtc_stat.c22 += (sess->voip_mtc_stat.pkt - 1);\n\t\t}\n\t    }\n\n\t    sess->voip_mtc_stat.pkt = 0;\n\t}\n    }\n}\n\nvoid pjmedia_rtcp_xr_tx_rtp( pjmedia_rtcp_xr_session *session, \n\t\t\t     unsigned ptsize )\n{\n    PJ_UNUSED_ARG(session);\n    PJ_UNUSED_ARG(ptsize);\n}\n\nPJ_DEF(pj_status_t) pjmedia_rtcp_xr_update_info( \n\t\t\t\t\t pjmedia_rtcp_xr_session *sess,\n\t\t\t\t\t unsigned info,\n\t\t\t\t\t pj_int32_t val)\n{\n    int v = val;\n\n    switch(info) {\n\tcase PJMEDIA_RTCP_XR_INFO_SIGNAL_LVL:\n\t    sess->stat.rx.voip_mtc.signal_lvl = (pj_int8_t) v;\n\t    break;\n\n\tcase PJMEDIA_RTCP_XR_INFO_NOISE_LVL:\n\t    sess->stat.rx.voip_mtc.noise_lvl = (pj_int8_t) v;\n\t    break;\n\n\tcase PJMEDIA_RTCP_XR_INFO_RERL:\n\t    sess->stat.rx.voip_mtc.rerl = (pj_uint8_t) v;\n\t    break;\n\n\tcase PJMEDIA_RTCP_XR_INFO_R_FACTOR:\n\t    sess->stat.rx.voip_mtc.ext_r_factor = (pj_uint8_t) v;\n\t    break;\n\n\tcase PJMEDIA_RTCP_XR_INFO_MOS_LQ:\n\t    sess->stat.rx.voip_mtc.mos_lq = (pj_uint8_t) v;\n\t    break;\n\n\tcase PJMEDIA_RTCP_XR_INFO_MOS_CQ:\n\t    sess->stat.rx.voip_mtc.mos_cq = (pj_uint8_t) v;\n\t    break;\n\n\tcase PJMEDIA_RTCP_XR_INFO_CONF_PLC:\n\t    if (v >= 0 && v <= 3) {\n\t\tsess->stat.rx.voip_mtc.rx_config &= 0x3F;\n\t\tsess->stat.rx.voip_mtc.rx_config |= (pj_uint8_t) (v << 6);\n\t    }\n\t    break;\n\n\tcase PJMEDIA_RTCP_XR_INFO_CONF_JBA:\n\t    if (v >= 0 && v <= 3) {\n\t\tsess->stat.rx.voip_mtc.rx_config &= 0xCF;\n\t\tsess->stat.rx.voip_mtc.rx_config |= (pj_uint8_t) (v << 4);\n\t    }\n\t    break;\n\n\tcase PJMEDIA_RTCP_XR_INFO_CONF_JBR:\n\t    if (v >= 0 && v <= 15) {\n\t\tsess->stat.rx.voip_mtc.rx_config &= 0xF0;\n\t\tsess->stat.rx.voip_mtc.rx_config |= (pj_uint8_t) v;\n\t    }\n\t    break;\n\n\tcase PJMEDIA_RTCP_XR_INFO_JB_NOM:\n\t    sess->stat.rx.voip_mtc.jb_nom = (pj_uint16_t) v;\n\t    break;\n\n\tcase PJMEDIA_RTCP_XR_INFO_JB_MAX:\n\t    sess->stat.rx.voip_mtc.jb_max = (pj_uint16_t) v;\n\t    break;\n\n\tcase PJMEDIA_RTCP_XR_INFO_JB_ABS_MAX:\n\t    sess->stat.rx.voip_mtc.jb_abs_max = (pj_uint16_t) v;\n\t    break;\n\n\tdefault:\n\t    return PJ_EINVAL;\n    }\n\n    return PJ_SUCCESS;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/rtp.c",
    "content": "/* $Id: rtp.c 4235 2012-08-24 03:15:42Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/rtp.h>\n#include <pjmedia/errno.h>\n#include <pj/log.h>\n#include <pj/sock.h>\t/* pj_htonx, pj_htonx */\n#include <pj/assert.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n\n\n#define THIS_FILE   \"rtp.c\"\n\n#define RTP_VERSION\t2\n\n#define RTP_SEQ_MOD\t(1 << 16)\n#define MAX_DROPOUT \t((pj_int16_t)3000)\n#define MAX_MISORDER \t((pj_int16_t)100)\n#define MIN_SEQUENTIAL  ((pj_int16_t)2)\n\nstatic void pjmedia_rtp_seq_restart(pjmedia_rtp_seq_session *seq_ctrl, \n\t\t\t\t    pj_uint16_t seq);\n\n\nPJ_DEF(pj_status_t) pjmedia_rtp_session_init( pjmedia_rtp_session *ses,\n\t\t\t\t\t      int default_pt, \n\t\t\t\t\t      pj_uint32_t sender_ssrc )\n{\n    PJ_LOG(5, (THIS_FILE, \n\t       \"pjmedia_rtp_session_init: ses=%p, default_pt=%d, ssrc=0x%x\",\n\t       ses, default_pt, sender_ssrc));\n\n    /* Check RTP header packing. */\n    if (sizeof(struct pjmedia_rtp_hdr) != 12) {\n\tpj_assert(!\"Wrong RTP header packing!\");\n\treturn PJMEDIA_RTP_EINPACK;\n    }\n\n    /* If sender_ssrc is not specified, create from random value. */\n    if (sender_ssrc == 0 || sender_ssrc == (pj_uint32_t)-1) {\n\tsender_ssrc = pj_htonl(pj_rand());\n    } else {\n\tsender_ssrc = pj_htonl(sender_ssrc);\n    }\n\n    /* Initialize session. */\n    pj_bzero(ses, sizeof(*ses));\n\n    /* Initial sequence number SHOULD be random, according to RFC 3550. */\n    /* According to RFC 3711, it should be random within 2^15 bit */\n    ses->out_extseq = pj_rand() & 0x7FFF;\n    ses->peer_ssrc = 0;\n    \n    /* Build default header for outgoing RTP packet. */\n    ses->out_hdr.v = RTP_VERSION;\n    ses->out_hdr.p = 0;\n    ses->out_hdr.x = 0;\n    ses->out_hdr.cc = 0;\n    ses->out_hdr.m = 0;\n    ses->out_hdr.pt = (pj_uint8_t) default_pt;\n    ses->out_hdr.seq = (pj_uint16_t) pj_htons( (pj_uint16_t)ses->out_extseq );\n    ses->out_hdr.ts = 0;\n    ses->out_hdr.ssrc = sender_ssrc;\n\n    /* Keep some arguments as session defaults. */\n    ses->out_pt = (pj_uint16_t) default_pt;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_rtp_session_init2( \n\t\t\t\t    pjmedia_rtp_session *ses,\n\t\t\t\t    pjmedia_rtp_session_setting settings)\n{\n    pj_status_t status;\n    int\t\t pt = 0;\n    pj_uint32_t\t sender_ssrc = 0;\n\n    if (settings.flags & 1)\n\tpt = settings.default_pt;\n    if (settings.flags & 2)\n\tsender_ssrc = settings.sender_ssrc;\n\n    status = pjmedia_rtp_session_init(ses, pt, sender_ssrc);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (settings.flags & 4) {\n\tses->out_extseq = settings.seq;\n\tses->out_hdr.seq = pj_htons((pj_uint16_t)ses->out_extseq);\n    }\n    if (settings.flags & 8)\n\tses->out_hdr.ts = pj_htonl(settings.ts);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_rtp_encode_rtp( pjmedia_rtp_session *ses, \n\t\t\t\t\t    int pt, int m,\n\t\t\t\t\t    int payload_len, int ts_len,\n\t\t\t\t\t    const void **rtphdr, int *hdrlen )\n{\n    /* Update timestamp */\n    ses->out_hdr.ts = pj_htonl(pj_ntohl(ses->out_hdr.ts)+ts_len);\n\n    /* If payload_len is zero, bail out.\n     * This is a clock frame; we're not really transmitting anything.\n     */\n    if (payload_len == 0)\n\treturn PJ_SUCCESS;\n\n    /* Update session. */\n    ses->out_extseq++;\n\n    /* Create outgoing header. */\n    ses->out_hdr.pt = (pj_uint8_t) ((pt == -1) ? ses->out_pt : pt);\n    ses->out_hdr.m = (pj_uint16_t) m;\n    ses->out_hdr.seq = pj_htons( (pj_uint16_t) ses->out_extseq);\n\n    /* Return values */\n    *rtphdr = &ses->out_hdr;\n    *hdrlen = sizeof(pjmedia_rtp_hdr);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_rtp_decode_rtp( pjmedia_rtp_session *ses, \n\t\t\t\t\t    const void *pkt, int pkt_len,\n\t\t\t\t\t    const pjmedia_rtp_hdr **hdr,\n\t\t\t\t\t    const void **payload,\n\t\t\t\t\t    unsigned *payloadlen)\n{\n    int offset;\n\n    PJ_UNUSED_ARG(ses);\n\n    /* Assume RTP header at the start of packet. We'll verify this later. */\n    *hdr = (pjmedia_rtp_hdr*)pkt;\n\n    /* Check RTP header sanity. */\n    if ((*hdr)->v != RTP_VERSION) {\n\treturn PJMEDIA_RTP_EINVER;\n    }\n\n    /* Payload is located right after header plus CSRC */\n    offset = sizeof(pjmedia_rtp_hdr) + ((*hdr)->cc * sizeof(pj_uint32_t));\n\n    /* Adjust offset if RTP extension is used. */\n    if ((*hdr)->x) {\n\tpjmedia_rtp_ext_hdr *ext = (pjmedia_rtp_ext_hdr*) \n\t\t\t\t    (((pj_uint8_t*)pkt) + offset);\n\toffset += ((pj_ntohs(ext->length)+1) * sizeof(pj_uint32_t));\n    }\n\n    /* Check that offset is less than packet size */\n    if (offset > pkt_len)\n\treturn PJMEDIA_RTP_EINLEN;\n\n    /* Find and set payload. */\n    *payload = ((pj_uint8_t*)pkt) + offset;\n    *payloadlen = pkt_len - offset;\n \n    /* Remove payload padding if any */\n    if ((*hdr)->p && *payloadlen > 0) {\n\tpj_uint8_t pad_len;\n\n\tpad_len = ((pj_uint8_t*)(*payload))[*payloadlen - 1];\n\tif (pad_len <= *payloadlen)\n\t    *payloadlen -= pad_len;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(void) pjmedia_rtp_session_update( pjmedia_rtp_session *ses, \n\t\t\t\t\t const pjmedia_rtp_hdr *hdr,\n\t\t\t\t\t pjmedia_rtp_status *p_seq_st)\n{\n    pjmedia_rtp_session_update2(ses, hdr, p_seq_st, PJ_TRUE);\n}\n\nPJ_DEF(void) pjmedia_rtp_session_update2( pjmedia_rtp_session *ses, \n\t\t\t\t\t  const pjmedia_rtp_hdr *hdr,\n\t\t\t\t\t  pjmedia_rtp_status *p_seq_st,\n\t\t\t\t\t  pj_bool_t check_pt)\n{\n    pjmedia_rtp_status seq_st;\n\n    /* for now check_pt MUST be either PJ_TRUE or PJ_FALSE.\n     * In the future we might change check_pt from boolean to \n     * unsigned integer to accommodate more flags.\n     */\n    pj_assert(check_pt==PJ_TRUE || check_pt==PJ_FALSE);\n\n    /* Init status */\n    seq_st.status.value = 0;\n    seq_st.diff = 0;\n\n    /* Check SSRC. */\n    if (ses->peer_ssrc == 0) ses->peer_ssrc = pj_ntohl(hdr->ssrc);\n\n    if (pj_ntohl(hdr->ssrc) != ses->peer_ssrc) {\n\tseq_st.status.flag.badssrc = 1;\n\tses->peer_ssrc = pj_ntohl(hdr->ssrc);\n    }\n\n    /* Check payload type. */\n    if (check_pt && hdr->pt != ses->out_pt) {\n\tif (p_seq_st) {\n\t    p_seq_st->status.value = seq_st.status.value;\n\t    p_seq_st->status.flag.bad = 1;\n\t    p_seq_st->status.flag.badpt = 1;\n\t}\n\treturn;\n    }\n\n    /* Initialize sequence number on first packet received. */\n    if (ses->received == 0)\n\tpjmedia_rtp_seq_init( &ses->seq_ctrl, pj_ntohs(hdr->seq) );\n\n    /* Check sequence number to see if remote session has been restarted. */\n    pjmedia_rtp_seq_update( &ses->seq_ctrl, pj_ntohs(hdr->seq), &seq_st);\n    if (seq_st.status.flag.restart) {\n\t++ses->received;\n\n    } else if (!seq_st.status.flag.bad) {\n\t++ses->received;\n    }\n\n    if (p_seq_st) {\n\tp_seq_st->status.value = seq_st.status.value;\n\tp_seq_st->diff = seq_st.diff;\n    }\n}\n\n\n\nvoid pjmedia_rtp_seq_restart(pjmedia_rtp_seq_session *sess, pj_uint16_t seq)\n{\n    sess->base_seq = seq;\n    sess->max_seq = seq;\n    sess->bad_seq = RTP_SEQ_MOD + 1;\n    sess->cycles = 0;\n}\n\n\nvoid pjmedia_rtp_seq_init(pjmedia_rtp_seq_session *sess, pj_uint16_t seq)\n{\n    pjmedia_rtp_seq_restart(sess, seq);\n\n    sess->max_seq = (pj_uint16_t) (seq - 1);\n    sess->probation = MIN_SEQUENTIAL;\n}\n\n\nvoid pjmedia_rtp_seq_update( pjmedia_rtp_seq_session *sess, \n\t\t\t     pj_uint16_t seq,\n\t\t\t     pjmedia_rtp_status *seq_status)\n{\n    pj_uint16_t udelta = (pj_uint16_t) (seq - sess->max_seq);\n    pjmedia_rtp_status st;\n    \n    /* Init status */\n    st.status.value = 0;\n    st.diff = 0;\n\n    /*\n     * Source is not valid until MIN_SEQUENTIAL packets with\n     * sequential sequence numbers have been received.\n     */\n    if (sess->probation) {\n\n\tst.status.flag.probation = 1;\n\t\n        if (seq == sess->max_seq+ 1) {\n\t    /* packet is in sequence */\n\t    st.diff = 1;\n\t    sess->probation--;\n            sess->max_seq = seq;\n            if (sess->probation == 0) {\n\t\tst.status.flag.probation = 0;\n            }\n\t} else {\n\n\t    st.diff = 0;\n\n\t    st.status.flag.bad = 1;\n\t    if (seq == sess->max_seq)\n\t\tst.status.flag.dup = 1;\n\t    else\n\t\tst.status.flag.outorder = 1;\n\n\t    sess->probation = MIN_SEQUENTIAL - 1;\n\t    sess->max_seq = seq;\n        }\n\n\n    } else if (udelta == 0) {\n\n\tst.status.flag.dup = 1;\n\n    } else if (udelta < MAX_DROPOUT) {\n\t/* in order, with permissible gap */\n\tif (seq < sess->max_seq) {\n\t    /* Sequence number wrapped - count another 64K cycle. */\n\t    sess->cycles += RTP_SEQ_MOD;\n        }\n        sess->max_seq = seq;\n\n\tst.diff = udelta;\n\n    } else if (udelta <= (RTP_SEQ_MOD - MAX_MISORDER)) {\n\t/* the sequence number made a very large jump */\n        if (seq == sess->bad_seq) {\n\t    /*\n\t     * Two sequential packets -- assume that the other side\n\t     * restarted without telling us so just re-sync\n\t     * (i.e., pretend this was the first packet).\n\t     */\n\t    pjmedia_rtp_seq_restart(sess, seq);\n\t    st.status.flag.restart = 1;\n\t    st.status.flag.probation = 1;\n\t    st.diff = 1;\n\t}\n        else {\n\t    sess->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1);\n            st.status.flag.bad = 1;\n\t    st.status.flag.outorder = 1;\n        }\n    } else {\n\t/* old duplicate or reordered packet.\n\t * Not necessarily bad packet (?)\n\t */\n\tst.status.flag.outorder = 1;\n    }\n    \n\n    if (seq_status) {\n\tseq_status->diff = st.diff;\n\tseq_status->status.value = st.status.value;\n    }\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/sdp.c",
    "content": "/* $Id: sdp.c 4367 2013-02-21 20:49:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/sdp.h>\n#include <pjmedia/errno.h>\n#include <pjlib-util/scanner.h>\n#include <pj/array.h>\n#include <pj/except.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/string.h>\n#include <pj/pool.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n\n\nenum {\n    SKIP_WS = 0,\n    SYNTAX_ERROR = 1,\n};\n// New token definition from RFC 4566 (SDP)\n#define TOKEN\t\t\"!#$%&'*+-.^_`{|}~\"\n//#define TOKEN\t\t\"-.!%*_=`'~\"\n//#define TOKEN\t\t\"'`-./:?\\\"#$&*;=@[]^_`{|}+~!\"\n#define NTP_OFFSET\t((pj_uint32_t)2208988800)\n#define THIS_FILE\t\"sdp.c\"\n\ntypedef struct parse_context\n{ \n    pj_status_t last_error;\n} parse_context;\n\n\n/*\n * Prototypes for line parser.\n */\nstatic void parse_version(pj_scanner *scanner, parse_context *ctx);\nstatic void parse_origin(pj_scanner *scanner, pjmedia_sdp_session *ses,\n\t\t\t parse_context *ctx);\nstatic void parse_time(pj_scanner *scanner, pjmedia_sdp_session *ses,\n\t\t       parse_context *ctx);\nstatic void parse_generic_line(pj_scanner *scanner, pj_str_t *str,\n\t\t\t       parse_context *ctx);\nstatic void parse_connection_info(pj_scanner *scanner, pjmedia_sdp_conn *conn,\n\t\t\t\t  parse_context *ctx);\nstatic void parse_bandwidth_info(pj_scanner *scanner, pjmedia_sdp_bandw *bandw,\n\t\t\t\t  parse_context *ctx);\nstatic pjmedia_sdp_attr *parse_attr(pj_pool_t *pool, pj_scanner *scanner,\n\t\t\t\t    parse_context *ctx);\nstatic void parse_media(pj_scanner *scanner, pjmedia_sdp_media *med,\n\t\t\tparse_context *ctx);\nstatic void on_scanner_error(pj_scanner *scanner);\n\n/*\n * Scanner character specification.\n */\nstatic int is_initialized;\nstatic pj_cis_buf_t cis_buf;\nstatic pj_cis_t cs_digit, cs_token;\n\nstatic void init_sdp_parser(void)\n{\n    if (is_initialized != 0)\n\treturn;\n\n    pj_enter_critical_section();\n\n    if (is_initialized != 0) {\n\tpj_leave_critical_section();\n\treturn;\n    }\n    \n    pj_cis_buf_init(&cis_buf);\n\n    pj_cis_init(&cis_buf, &cs_token);\n    pj_cis_add_alpha(&cs_token);\n    pj_cis_add_num(&cs_token);\n    pj_cis_add_str(&cs_token, TOKEN);\n\n    pj_cis_init(&cis_buf, &cs_digit);\n    pj_cis_add_num(&cs_digit);\n\n    is_initialized = 1;\n    pj_leave_critical_section();\n}\n\nPJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_attr_create( pj_pool_t *pool,\n\t\t\t\t\t\t   const char *name,\n\t\t\t\t\t\t   const pj_str_t *value)\n{\n    pjmedia_sdp_attr *attr;\n\n    PJ_ASSERT_RETURN(pool && name, NULL);\n\n    attr = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_attr);\n    pj_strdup2(pool, &attr->name, name);\n\n    if (value)\n\tpj_strdup_with_null(pool, &attr->value, value);\n    else {\n\tattr->value.ptr = NULL;\n\tattr->value.slen = 0;\n    }\n\n    return attr;\n}\n\nPJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_attr_clone(pj_pool_t *pool, \n\t\t\t\t\t\t const pjmedia_sdp_attr *rhs)\n{\n    pjmedia_sdp_attr *attr;\n    \n    PJ_ASSERT_RETURN(pool && rhs, NULL);\n\n    attr = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_attr);\n\n    pj_strdup(pool, &attr->name, &rhs->name);\n    pj_strdup_with_null(pool, &attr->value, &rhs->value);\n\n    return attr;\n}\n\nPJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_attr_find (unsigned count, \n\t\t\t\t       pjmedia_sdp_attr *const attr_array[],\n\t\t\t\t       const pj_str_t *name,\n\t\t\t\t       const pj_str_t *c_fmt)\n{\n    unsigned i;\n    unsigned c_pt = 0xFFFF;\n\n    PJ_ASSERT_RETURN(count <= PJMEDIA_MAX_SDP_ATTR, NULL);\n\n    if (c_fmt)\n\tc_pt = pj_strtoul(c_fmt);\n\n    for (i=0; i<count; ++i) {\n\tif (pj_strcmp(&attr_array[i]->name, name) == 0) {\n\t    const pjmedia_sdp_attr *a = attr_array[i];\n\t    if (c_fmt) {\n\t\tunsigned pt = (unsigned) pj_strtoul2(&a->value, NULL, 10);\n\t\tif (pt == c_pt) {\n\t\t    return (pjmedia_sdp_attr*)a;\n\t\t}\n\t    } else \n\t\treturn (pjmedia_sdp_attr*)a;\n\t}\n    }\n    return NULL;\n}\n\nPJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_attr_find2(unsigned count, \n\t\t\t\t       pjmedia_sdp_attr *const attr_array[],\n\t\t\t\t       const char *c_name,\n\t\t\t\t       const pj_str_t *c_fmt)\n{\n    pj_str_t name;\n\n    name.ptr = (char*)c_name;\n    name.slen = pj_ansi_strlen(c_name);\n\n    return pjmedia_sdp_attr_find(count, attr_array, &name, c_fmt);\n}\n\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_attr_add(unsigned *count,\n\t\t\t\t\t pjmedia_sdp_attr *attr_array[],\n\t\t\t\t\t pjmedia_sdp_attr *attr)\n{\n    PJ_ASSERT_RETURN(count && attr_array && attr, PJ_EINVAL);\n    PJ_ASSERT_RETURN(*count < PJMEDIA_MAX_SDP_ATTR, PJ_ETOOMANY);\n\n    attr_array[*count] = attr;\n    (*count)++;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(unsigned) pjmedia_sdp_attr_remove_all(unsigned *count,\n\t\t\t\t\t     pjmedia_sdp_attr *attr_array[],\n\t\t\t\t\t     const char *name)\n{\n    unsigned i, removed = 0;\n    pj_str_t attr_name;\n\n    PJ_ASSERT_RETURN(count && attr_array && name, PJ_EINVAL);\n    PJ_ASSERT_RETURN(*count <= PJMEDIA_MAX_SDP_ATTR, PJ_ETOOMANY);\n\n    attr_name.ptr = (char*)name;\n    attr_name.slen = pj_ansi_strlen(name);\n\n    for (i=0; i<*count; ) {\n\tif (pj_strcmp(&attr_array[i]->name, &attr_name)==0) {\n\t    pj_array_erase(attr_array, sizeof(pjmedia_sdp_attr*),\n\t\t\t   *count, i);\n\t    --(*count);\n\t    ++removed;\n\t} else {\n\t    ++i;\n\t}   \n    }\n\n    return removed;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_attr_remove( unsigned *count,\n\t\t\t\t\t     pjmedia_sdp_attr *attr_array[],\n\t\t\t\t\t     pjmedia_sdp_attr *attr )\n{\n    unsigned i, removed=0;\n\n    PJ_ASSERT_RETURN(count && attr_array && attr, PJ_EINVAL);\n    PJ_ASSERT_RETURN(*count <= PJMEDIA_MAX_SDP_ATTR, PJ_ETOOMANY);\n\n    for (i=0; i<*count; ) {\n\tif (attr_array[i] == attr) {\n\t    pj_array_erase(attr_array, sizeof(pjmedia_sdp_attr*),\n\t\t\t   *count, i);\n\t    --(*count);\n\t    ++removed;\n\t} else {\n\t    ++i;\n\t}\n    }\n\n    return removed ? PJ_SUCCESS : PJ_ENOTFOUND;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_attr_get_rtpmap( const pjmedia_sdp_attr *attr,\n\t\t\t\t\t\t pjmedia_sdp_rtpmap *rtpmap)\n{\n    pj_scanner scanner;\n    pj_str_t token;\n    pj_status_t status = -1;\n    char term = 0;\n    PJ_USE_EXCEPTION;\n\n    PJ_ASSERT_RETURN(pj_strcmp2(&attr->name, \"rtpmap\")==0, PJ_EINVALIDOP);\n\n    PJ_ASSERT_RETURN(attr->value.slen != 0, PJMEDIA_SDP_EINATTR);\n\n    init_sdp_parser();\n\n    /* Check if input is null terminated, and null terminate if\n     * necessary. Unfortunately this may crash the application if\n     * attribute was allocated from a read-only memory location.\n     * But this shouldn't happen as attribute's value normally is\n     * null terminated.\n     */\n    if (attr->value.ptr[attr->value.slen] != 0 &&\n\tattr->value.ptr[attr->value.slen] != '\\r' &&\n\tattr->value.ptr[attr->value.slen] != '\\n')\n    {\n\tpj_assert(!\"Shouldn't happen\");\n\tterm = attr->value.ptr[attr->value.slen];\n\tattr->value.ptr[attr->value.slen] = '\\0';\n    }\n\n    pj_scan_init(&scanner, (char*)attr->value.ptr, attr->value.slen,\n\t\t PJ_SCAN_AUTOSKIP_WS, &on_scanner_error);\n\n    /* rtpmap sample:\n     *\ta=rtpmap:98 L16/16000/2.\n     */\n\n    /* Init */\n    rtpmap->pt.slen = rtpmap->param.slen = rtpmap->enc_name.slen = 0;\n    rtpmap->clock_rate = 0;\n\n    /* Parse */\n    PJ_TRY {\n\n\t/* Get payload type. */\n\tpj_scan_get(&scanner, &cs_token, &rtpmap->pt);\n\n\n\t/* Get encoding name. */\n\tpj_scan_get(&scanner, &cs_token, &rtpmap->enc_name);\n\n\t/* Expecting '/' after encoding name. */\n\tif (pj_scan_get_char(&scanner) != '/') {\n\t    status = PJMEDIA_SDP_EINRTPMAP;\n\t    goto on_return;\n\t}\n\n\n\t/* Get the clock rate. */\n\tpj_scan_get(&scanner, &cs_digit, &token);\n\trtpmap->clock_rate = pj_strtoul(&token);\n\n\t/* Expecting either '/' or EOF */\n\tif (*scanner.curptr == '/') {\n\t    pj_scan_get_char(&scanner);\n\t    rtpmap->param.ptr = scanner.curptr;\n\t    rtpmap->param.slen = scanner.end - scanner.curptr;\n\t} else {\n\t    rtpmap->param.slen = 0;\n\t}\n\n\tstatus = PJ_SUCCESS;\n    }\n    PJ_CATCH_ANY {\n\tstatus = PJMEDIA_SDP_EINRTPMAP;\n    }\n    PJ_END;\n\n\non_return:\n    pj_scan_fini(&scanner);\n    if (term) {\n\tattr->value.ptr[attr->value.slen] = term;\n    }\n    return status;\n}\n\nPJ_DEF(pj_status_t) pjmedia_sdp_attr_get_fmtp( const pjmedia_sdp_attr *attr,\n\t\t\t\t\t       pjmedia_sdp_fmtp *fmtp)\n{\n    const char *p = attr->value.ptr;\n    const char *end = attr->value.ptr + attr->value.slen;\n    pj_str_t token;\n\n    PJ_ASSERT_RETURN(pj_strcmp2(&attr->name, \"fmtp\")==0, PJ_EINVALIDOP);\n\n    /* fmtp BNF:\n     *\ta=fmtp:<format> <format specific parameter>\n     */\n\n    /* Get format. */\n    token.ptr = (char*)p;\n    while (pj_isdigit(*p) && p!=end)\n\t++p;\n    token.slen = p - token.ptr;\n    if (token.slen == 0)\n\treturn PJMEDIA_SDP_EINFMTP;\n\n    fmtp->fmt = token;\n\n    /* Expecting space after format. */\n    if (*p != ' ') return PJMEDIA_SDP_EINFMTP;\n\n    /* Get space. */\n    ++p;\n\n    /* Set the remaining string as fmtp format parameter. */\n    fmtp->fmt_param.ptr = (char*)p;\n    fmtp->fmt_param.slen = end - p;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_attr_get_rtcp(const pjmedia_sdp_attr *attr,\n\t\t\t\t\t      pjmedia_sdp_rtcp_attr *rtcp)\n{\n    pj_scanner scanner;\n    pj_str_t token;\n    pj_status_t status = -1;\n    PJ_USE_EXCEPTION;\n\n    PJ_ASSERT_RETURN(pj_strcmp2(&attr->name, \"rtcp\")==0, PJ_EINVALIDOP);\n\n    init_sdp_parser();\n\n    /* fmtp BNF:\n     *\ta=rtcp:<port> [nettype addrtype address]\n     */\n\n    pj_scan_init(&scanner, (char*)attr->value.ptr, attr->value.slen,\n\t\t PJ_SCAN_AUTOSKIP_WS, &on_scanner_error);\n\n    /* Init */\n    rtcp->net_type.slen = rtcp->addr_type.slen = rtcp->addr.slen = 0;\n\n    /* Parse */\n    PJ_TRY {\n\n\t/* Get the port */\n\tpj_scan_get(&scanner, &cs_token, &token);\n\trtcp->port = pj_strtoul(&token);\n\n\t/* Have address? */\n\tif (!pj_scan_is_eof(&scanner)) {\n\n\t    /* Get network type */\n\t    pj_scan_get(&scanner, &cs_token, &rtcp->net_type);\n\n\t    /* Get address type */\n\t    pj_scan_get(&scanner, &cs_token, &rtcp->addr_type);\n\n\t    /* Get the address */\n\t    pj_scan_get(&scanner, &cs_token, &rtcp->addr);\n\n\t}\n\n\tstatus = PJ_SUCCESS;\n\n    }\n    PJ_CATCH_ANY {\n\tstatus = PJMEDIA_SDP_EINRTCP;\n    }\n    PJ_END;\n\n    pj_scan_fini(&scanner);\n    return status;\n}\n\n\nPJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_attr_create_rtcp(pj_pool_t *pool,\n\t\t\t\t\t\t       const pj_sockaddr *a)\n{\n    enum {\n\tATTR_LEN = PJ_INET6_ADDRSTRLEN+16\n    };\n    pjmedia_sdp_attr *attr;\n\n    attr = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_attr);\n    attr->name = pj_str(\"rtcp\");\n    attr->value.ptr = (char*) pj_pool_alloc(pool, ATTR_LEN);\n    if (a->addr.sa_family == pj_AF_INET()) {\n\tattr->value.slen = \n\t    pj_ansi_snprintf(attr->value.ptr, ATTR_LEN,\n\t\t\t    \"%u IN IP4 %s\",\n\t\t\t    pj_ntohs(a->ipv4.sin_port),\n\t\t\t    pj_inet_ntoa(a->ipv4.sin_addr));\n    } else if (a->addr.sa_family == pj_AF_INET6()) {\n\tchar tmp_addr[PJ_INET6_ADDRSTRLEN];\n\tattr->value.slen = \n\t    pj_ansi_snprintf(attr->value.ptr, ATTR_LEN,\n\t\t\t    \"%u IN IP6 %s\",\n\t\t\t    pj_sockaddr_get_port(a),\n\t\t\t    pj_sockaddr_print(a, tmp_addr, \n\t\t\t\t\t      sizeof(tmp_addr), 0));\n\n    } else {\n\tpj_assert(!\"Unsupported address family\");\n\treturn NULL;\n    }\n\n    return attr;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_attr_to_rtpmap(pj_pool_t *pool,\n\t\t\t\t\t       const pjmedia_sdp_attr *attr,\n\t\t\t\t\t       pjmedia_sdp_rtpmap **p_rtpmap)\n{\n    PJ_ASSERT_RETURN(pool && attr && p_rtpmap, PJ_EINVAL);\n\n    *p_rtpmap = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_rtpmap);\n    PJ_ASSERT_RETURN(*p_rtpmap, PJ_ENOMEM);\n\n    return pjmedia_sdp_attr_get_rtpmap(attr, *p_rtpmap);\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_rtpmap_to_attr(pj_pool_t *pool,\n\t\t\t\t\t       const pjmedia_sdp_rtpmap *rtpmap,\n\t\t\t\t\t       pjmedia_sdp_attr **p_attr)\n{\n    pjmedia_sdp_attr *attr;\n    char tempbuf[128];\n    int len;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(pool && rtpmap && p_attr, PJ_EINVAL);\n\n    /* Check that mandatory attributes are specified. */\n    PJ_ASSERT_RETURN(rtpmap->enc_name.slen && rtpmap->clock_rate,\n\t\t     PJMEDIA_SDP_EINRTPMAP);\n\n\n    attr = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_attr);\n    PJ_ASSERT_RETURN(attr != NULL, PJ_ENOMEM);\n\n    attr->name.ptr = \"rtpmap\";\n    attr->name.slen = 6;\n\n    /* Format: \":pt enc_name/clock_rate[/param]\" */\n    len = pj_ansi_snprintf(tempbuf, sizeof(tempbuf), \n\t\t\t   \"%.*s %.*s/%u%s%.*s\",\n\t\t\t   (int)rtpmap->pt.slen,\n\t\t\t   rtpmap->pt.ptr,\n\t\t\t   (int)rtpmap->enc_name.slen,\n\t\t\t   rtpmap->enc_name.ptr,\n\t\t\t   rtpmap->clock_rate,\n\t\t\t   (rtpmap->param.slen ? \"/\" : \"\"),\n\t\t\t   (int)rtpmap->param.slen,\n\t\t\t   rtpmap->param.ptr);\n\n    if (len < 1 || len >= (int)sizeof(tempbuf))\n\treturn PJMEDIA_SDP_ERTPMAPTOOLONG;\n\n    attr->value.slen = len;\n    attr->value.ptr = (char*) pj_pool_alloc(pool, attr->value.slen+1);\n    pj_memcpy(attr->value.ptr, tempbuf, attr->value.slen+1);\n\n    *p_attr = attr;\n    return PJ_SUCCESS;\n}\n\n\nstatic int print_connection_info( pjmedia_sdp_conn *c, char *buf, int len)\n{\n    int printed;\n\n    printed = pj_ansi_snprintf(buf, len, \"c=%.*s %.*s %.*s\\r\\n\",\n\t\t\t       (int)c->net_type.slen,\n\t\t\t       c->net_type.ptr,\n\t\t\t       (int)c->addr_type.slen,\n\t\t\t       c->addr_type.ptr,\n\t\t\t       (int)c->addr.slen,\n\t\t\t       c->addr.ptr);\n    if (printed < 1 || printed >= len)\n\treturn -1;\n\n    return printed;\n}\n\n\nPJ_DEF(pjmedia_sdp_conn*) pjmedia_sdp_conn_clone (pj_pool_t *pool, \n\t\t\t\t\t\t  const pjmedia_sdp_conn *rhs)\n{\n    pjmedia_sdp_conn *c = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_conn);\n    if (!c) return NULL;\n\n    if (!pj_strdup (pool, &c->net_type, &rhs->net_type)) return NULL;\n    if (!pj_strdup (pool, &c->addr_type, &rhs->addr_type)) return NULL;\n    if (!pj_strdup (pool, &c->addr, &rhs->addr)) return NULL;\n\n    return c;\n}\n\nPJ_DEF(pjmedia_sdp_bandw*)\npjmedia_sdp_bandw_clone (pj_pool_t *pool, \n\t\t\t const pjmedia_sdp_bandw *rhs)\n{\n    pjmedia_sdp_bandw *b = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_bandw);\n    if (!b) return NULL;\n\n    if (!pj_strdup (pool, &b->modifier, &rhs->modifier)) return NULL;\n    b->value = rhs->value;\n\n    return b;\n}\n\nstatic pj_ssize_t print_bandw(const pjmedia_sdp_bandw *bandw,\n\t\t\t      char *buf, pj_size_t len)\n{\n    char *p = buf;\n\n    if ((int)len < bandw->modifier.slen + 10 + 5)\n\treturn -1;\n\n    *p++ = 'b';\n    *p++ = '=';\n    pj_memcpy(p, bandw->modifier.ptr, bandw->modifier.slen);\n    p += bandw->modifier.slen;\n    *p++ = ':';\n    p += pj_utoa(bandw->value, p);\n\n    *p++ = '\\r';\n    *p++ = '\\n';\n    return p-buf;\n}\n\nstatic pj_ssize_t print_attr(const pjmedia_sdp_attr *attr, \n\t\t\t     char *buf, pj_size_t len)\n{\n    char *p = buf;\n\n    if ((int)len < attr->name.slen + attr->value.slen + 10)\n\treturn -1;\n\n    *p++ = 'a';\n    *p++ = '=';\n    pj_memcpy(p, attr->name.ptr, attr->name.slen);\n    p += attr->name.slen;\n    \n\n    if (attr->value.slen) {\n\t*p++ = ':';\n\tpj_memcpy(p, attr->value.ptr, attr->value.slen);\n\tp += attr->value.slen;\n    }\n\n    *p++ = '\\r';\n    *p++ = '\\n';\n    return p-buf;\n}\n\nstatic int print_media_desc( pjmedia_sdp_media *m, char *buf, int len)\n{\n    char *p = buf;\n    char *end = buf+len;\n    unsigned i;\n    int printed;\n\n    /* check length for the \"m=\" line. */\n    if (len < m->desc.media.slen+m->desc.transport.slen+12+24) {\n\treturn -1;\n    }\n    *p++ = 'm';\t    /* m= */\n    *p++ = '=';\n    pj_memcpy(p, m->desc.media.ptr, m->desc.media.slen);\n    p += m->desc.media.slen;\n    *p++ = ' ';\n    printed = pj_utoa(m->desc.port, p);\n    p += printed;\n    if (m->desc.port_count > 1) {\n\t*p++ = '/';\n\tprinted = pj_utoa(m->desc.port_count, p);\n\tp += printed;\n    }\n    *p++ = ' ';\n    pj_memcpy(p, m->desc.transport.ptr, m->desc.transport.slen);\n    p += m->desc.transport.slen;\n    for (i=0; i<m->desc.fmt_count; ++i) {\n\t*p++ = ' ';\n\tpj_memcpy(p, m->desc.fmt[i].ptr, m->desc.fmt[i].slen);\n\tp += m->desc.fmt[i].slen;\n    }\n    *p++ = '\\r';\n    *p++ = '\\n';\n\n    /* print connection info, if present. */\n    if (m->conn) {\n\tprinted = print_connection_info(m->conn, p, (int)(end-p));\n\tif (printed < 0) {\n\t    return -1;\n\t}\n\tp += printed;\n    }\n    \n    /* print optional bandwidth info. */\n    for (i=0; i<m->bandw_count; ++i) {\n\tprinted = (int)print_bandw(m->bandw[i], p, end-p);\n\tif (printed < 0) {\n\t    return -1;\n\t}\n\tp += printed;\n    }\n\n    /* print attributes. */\n    for (i=0; i<m->attr_count; ++i) {\n\tprinted = (int)print_attr(m->attr[i], p, end-p);\n\tif (printed < 0) {\n\t    return -1;\n\t}\n\tp += printed;\n    }\n\n    return (int)(p-buf);\n}\n\nPJ_DEF(pjmedia_sdp_media*) pjmedia_sdp_media_clone(\n\t\t\t\t\t\t pj_pool_t *pool, \n\t\t\t\t\t\t const pjmedia_sdp_media *rhs)\n{\n    unsigned int i;\n    pjmedia_sdp_media *m = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_media);\n    PJ_ASSERT_RETURN(m != NULL, NULL);\n\n    pj_strdup (pool, &m->desc.media, &rhs->desc.media);\n    m->desc.port = rhs->desc.port;\n    m->desc.port_count = rhs->desc.port_count;\n    pj_strdup (pool, &m->desc.transport, &rhs->desc.transport);\n    m->desc.fmt_count = rhs->desc.fmt_count;\n    for (i=0; i<rhs->desc.fmt_count; ++i)\n\tpj_strdup(pool, &m->desc.fmt[i], &rhs->desc.fmt[i]);\n\n    if (rhs->conn) {\n\tm->conn = pjmedia_sdp_conn_clone (pool, rhs->conn);\n\tPJ_ASSERT_RETURN(m->conn != NULL, NULL);\n    } else {\n\tm->conn = NULL;\n    }\n\n    m->bandw_count = rhs->bandw_count;\n    for (i=0; i < rhs->bandw_count; ++i) {\n\tm->bandw[i] = pjmedia_sdp_bandw_clone (pool, rhs->bandw[i]);\n\tPJ_ASSERT_RETURN(m->bandw[i] != NULL, NULL);\n    }\n\n    m->attr_count = rhs->attr_count;\n    for (i=0; i < rhs->attr_count; ++i) {\n\tm->attr[i] = pjmedia_sdp_attr_clone (pool, rhs->attr[i]);\n\tPJ_ASSERT_RETURN(m->attr[i] != NULL, NULL);\n    }\n\n    return m;\n}\n\nPJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_media_find_attr(\n\t\t\t\tconst pjmedia_sdp_media *m,\n\t\t\t\tconst pj_str_t *name, const pj_str_t *fmt)\n{\n    PJ_ASSERT_RETURN(m && name, NULL);\n    return pjmedia_sdp_attr_find(m->attr_count, m->attr, name, fmt);\n}\n\n\n\nPJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_media_find_attr2(\n\t\t\t\tconst pjmedia_sdp_media *m,\n\t\t\t\tconst char *name, const pj_str_t *fmt)\n{\n    PJ_ASSERT_RETURN(m && name, NULL);\n    return pjmedia_sdp_attr_find2(m->attr_count, m->attr, name, fmt);\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_media_add_attr( pjmedia_sdp_media *m,\n\t\t\t\t\t\tpjmedia_sdp_attr *attr)\n{\n    return pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);\n}\n\nPJ_DEF(pj_status_t) pjmedia_sdp_session_add_attr(pjmedia_sdp_session *s,\n\t\t\t\t\t\t pjmedia_sdp_attr *attr)\n{\n    return pjmedia_sdp_attr_add(&s->attr_count, s->attr, attr);\n}\n\nPJ_DEF(unsigned) pjmedia_sdp_media_remove_all_attr(pjmedia_sdp_media *m,\n\t\t\t\t\t\t   const char *name)\n{\n    return pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, name);\n}\n\nPJ_DEF(pj_status_t) pjmedia_sdp_media_remove_attr(pjmedia_sdp_media *m,\n\t\t\t      \t\t\t  pjmedia_sdp_attr *attr)\n{\n    return pjmedia_sdp_attr_remove(&m->attr_count, m->attr, attr);\n}\n\nstatic int print_session(const pjmedia_sdp_session *ses, \n\t\t\t char *buf, pj_ssize_t len)\n{\n    char *p = buf;\n    char *end = buf+len;\n    unsigned i;\n    int printed;\n\n    /* Check length for v= and o= lines. */\n    if (len < 5+ \n\t      2+ses->origin.user.slen+18+\n\t      ses->origin.net_type.slen+ses->origin.addr.slen + 2)\n    {\n\treturn -1;\n    }\n\n    /* SDP version (v= line) */\n    pj_memcpy(p, \"v=0\\r\\n\", 5);\n    p += 5;\n\n    /* Owner (o=) line. */\n    *p++ = 'o';\n    *p++ = '=';\n    pj_memcpy(p, ses->origin.user.ptr, ses->origin.user.slen);\n    p += ses->origin.user.slen;\n    *p++ = ' ';\n    printed = pj_utoa(ses->origin.id, p);\n    p += printed;\n    *p++ = ' ';\n    printed = pj_utoa(ses->origin.version, p);\n    p += printed;\n    *p++ = ' ';\n    pj_memcpy(p, ses->origin.net_type.ptr, ses->origin.net_type.slen);\n    p += ses->origin.net_type.slen;\n    *p++ = ' ';\n    pj_memcpy(p, ses->origin.addr_type.ptr, ses->origin.addr_type.slen);\n    p += ses->origin.addr_type.slen;\n    *p++ = ' ';\n    pj_memcpy(p, ses->origin.addr.ptr, ses->origin.addr.slen);\n    p += ses->origin.addr.slen;\n    *p++ = '\\r';\n    *p++ = '\\n';\n\n    /* Session name (s=) line. */\n    if ((end-p)  < 8+ses->name.slen) {\n\treturn -1;\n    }\n    *p++ = 's';\n    *p++ = '=';\n    pj_memcpy(p, ses->name.ptr, ses->name.slen);\n    p += ses->name.slen;\n    *p++ = '\\r';\n    *p++ = '\\n';\n\n    /* Connection line (c=) if exist. */\n    if (ses->conn) {\n\tprinted = print_connection_info(ses->conn, p, (int)(end-p));\n\tif (printed < 1) {\n\t    return -1;\n\t}\n\tp += printed;\n    }\n\n    /* print optional bandwidth info. */\n    for (i=0; i<ses->bandw_count; ++i) {\n\tprinted = (int)print_bandw(ses->bandw[i], p, end-p);\n\tif (printed < 1) {\n\t    return -1;\n\t}\n\tp += printed;\n    }\n\n    /* Time */\n    if ((end-p) < 24) {\n\treturn -1;\n    }\n    *p++ = 't';\n    *p++ = '=';\n    printed = pj_utoa(ses->time.start, p);\n    p += printed;\n    *p++ = ' ';\n    printed = pj_utoa(ses->time.stop, p);\n    p += printed;\n    *p++ = '\\r';\n    *p++ = '\\n';\n\n    /* Print all attribute (a=) lines. */\n    for (i=0; i<ses->attr_count; ++i) {\n\tprinted = (int)print_attr(ses->attr[i], p, end-p);\n\tif (printed < 0) {\n\t    return -1;\n\t}\n\tp += printed;\n    }\n\n    /* Print media (m=) lines. */\n    for (i=0; i<ses->media_count; ++i) {\n\tprinted = print_media_desc(ses->media[i], p, (int)(end-p));\n\tif (printed < 0) {\n\t    return -1;\n\t}\n\tp += printed;\n    }\n\n    return (int)(p-buf);\n}\n\n/******************************************************************************\n * PARSERS\n */\n\nstatic void parse_version(pj_scanner *scanner, parse_context *ctx)\n{\n    ctx->last_error = PJMEDIA_SDP_EINVER;\n\n    /* check equal sign */\n    if (*(scanner->curptr+1) != '=') {\n\ton_scanner_error(scanner);\n\treturn;\n    }\n\n    /* check version is 0 */\n    if (*(scanner->curptr+2) != '0') {\n\ton_scanner_error(scanner);\n\treturn;\n    }\n\n    /* We've got what we're looking for, skip anything until newline */\n    pj_scan_skip_line(scanner);\n}\n\nstatic void parse_origin(pj_scanner *scanner, pjmedia_sdp_session *ses,\n\t\t\t parse_context *ctx)\n{\n    pj_str_t str;\n\n    ctx->last_error = PJMEDIA_SDP_EINORIGIN;\n\n    /* check equal sign */\n    if (*(scanner->curptr+1) != '=') {\n\ton_scanner_error(scanner);\n\treturn;\n    }\n\n    /* o= */\n    pj_scan_advance_n(scanner, 2, SKIP_WS);\n\n    /* username. */\n    pj_scan_get_until_ch(scanner, ' ', &ses->origin.user);\n    pj_scan_get_char(scanner);\n\n    /* id */\n    pj_scan_get_until_ch(scanner, ' ', &str);\n    ses->origin.id = pj_strtoul(&str);\n    pj_scan_get_char(scanner);\n\n    /* version */\n    pj_scan_get_until_ch(scanner, ' ', &str);\n    ses->origin.version = pj_strtoul(&str);\n    pj_scan_get_char(scanner);\n\n    /* network-type */\n    pj_scan_get_until_ch(scanner, ' ', &ses->origin.net_type);\n    pj_scan_get_char(scanner);\n\n    /* addr-type */\n    pj_scan_get_until_ch(scanner, ' ', &ses->origin.addr_type);\n    pj_scan_get_char(scanner);\n\n    /* address */\n    pj_scan_get_until_chr(scanner, \" \\t\\r\\n\", &ses->origin.addr);\n\n    /* We've got what we're looking for, skip anything until newline */\n    pj_scan_skip_line(scanner);\n\n}\n\nstatic void parse_time(pj_scanner *scanner, pjmedia_sdp_session *ses,\n\t\t       parse_context *ctx)\n{\n    pj_str_t str;\n\n    ctx->last_error = PJMEDIA_SDP_EINTIME;\n\n    /* check equal sign */\n    if (*(scanner->curptr+1) != '=') {\n\ton_scanner_error(scanner);\n\treturn;\n    }\n\n    /* t= */\n    pj_scan_advance_n(scanner, 2, SKIP_WS);\n\n    /* start time */\n    pj_scan_get_until_ch(scanner, ' ', &str);\n    ses->time.start = pj_strtoul(&str);\n\n    pj_scan_get_char(scanner);\n\n    /* stop time */\n    pj_scan_get_until_chr(scanner, \" \\t\\r\\n\", &str);\n    ses->time.stop = pj_strtoul(&str);\n\n    /* We've got what we're looking for, skip anything until newline */\n    pj_scan_skip_line(scanner);\n}\n\nstatic void parse_generic_line(pj_scanner *scanner, pj_str_t *str,\n\t\t\t       parse_context *ctx)\n{\n    ctx->last_error = PJMEDIA_SDP_EINSDP;\n\n    /* check equal sign */\n    if (*(scanner->curptr+1) != '=') {\n\ton_scanner_error(scanner);\n\treturn;\n    }\n\n    /* x= */\n    pj_scan_advance_n(scanner, 2, SKIP_WS);\n\n    /* get anything until newline (including whitespaces). */\n    pj_scan_get_until_chr(scanner, \"\\r\\n\", str);\n\n    /* newline. */\n    pj_scan_get_newline(scanner);\n}\n\nstatic void parse_connection_info(pj_scanner *scanner, pjmedia_sdp_conn *conn,\n\t\t\t\t  parse_context *ctx)\n{\n    ctx->last_error = PJMEDIA_SDP_EINCONN;\n\n    /* c= */\n    pj_scan_advance_n(scanner, 2, SKIP_WS);\n\n    /* network-type */\n    pj_scan_get_until_ch(scanner, ' ', &conn->net_type);\n    pj_scan_get_char(scanner);\n\n    /* addr-type */\n    pj_scan_get_until_ch(scanner, ' ', &conn->addr_type);\n    pj_scan_get_char(scanner);\n\n    /* address. */\n    pj_scan_get_until_chr(scanner, \"/ \\t\\r\\n\", &conn->addr);\n    PJ_TODO(PARSE_SDP_CONN_ADDRESS_SUBFIELDS);\n\n    /* We've got what we're looking for, skip anything until newline */\n    pj_scan_skip_line(scanner);\n}\n\nstatic void parse_bandwidth_info(pj_scanner *scanner, pjmedia_sdp_bandw *bandw,\n\t\t\t\t  parse_context *ctx)\n{\n    pj_str_t str;\n\n    ctx->last_error = PJMEDIA_SDP_EINBANDW;\n\n    /* b= */\n    pj_scan_advance_n(scanner, 2, SKIP_WS);\n\n    /* modifier */\n    pj_scan_get_until_ch(scanner, ':', &bandw->modifier);\n    pj_scan_get_char(scanner);\n\n    /* value */\n    pj_scan_get_until_chr(scanner, \" \\t\\r\\n\", &str);\n    bandw->value = pj_strtoul(&str);\n\n    /* We've got what we're looking for, skip anything until newline */\n    pj_scan_skip_line(scanner);\n}\n\nstatic void parse_media(pj_scanner *scanner, pjmedia_sdp_media *med,\n\t\t\tparse_context *ctx)\n{\n    pj_str_t str;\n\n    ctx->last_error = PJMEDIA_SDP_EINMEDIA;\n\n    /* check the equal sign */\n    if (*(scanner->curptr+1) != '=') {\n\ton_scanner_error(scanner);\n\treturn;\n    }\n\n    /* m= */\n    pj_scan_advance_n(scanner, 2, SKIP_WS);\n\n    /* type */\n    pj_scan_get_until_ch(scanner, ' ', &med->desc.media);\n    pj_scan_get_char(scanner);\n\n    /* port */\n    pj_scan_get(scanner, &cs_token, &str);\n    med->desc.port = (unsigned short)pj_strtoul(&str);\n    if (*scanner->curptr == '/') {\n\t/* port count */\n\tpj_scan_get_char(scanner);\n\tpj_scan_get(scanner, &cs_token, &str);\n\tmed->desc.port_count = pj_strtoul(&str);\n\n    } else {\n\tmed->desc.port_count = 0;\n    }\n\n    if (pj_scan_get_char(scanner) != ' ') {\n\tPJ_THROW(SYNTAX_ERROR);\n    }\n\n    /* transport */\n    pj_scan_get_until_chr(scanner, \" \\t\\r\\n\", &med->desc.transport);\n\n    /* format list */\n    med->desc.fmt_count = 0;\n    while (*scanner->curptr == ' ') {\n\tpj_str_t fmt;\n\n\tpj_scan_get_char(scanner);\n\n\t/* Check again for the end of the line */\n\tif ((*scanner->curptr == '\\r') || (*scanner->curptr == '\\n'))\n\t\tbreak;\n\n\tpj_scan_get(scanner, &cs_token, &fmt);\n\tif (med->desc.fmt_count < PJMEDIA_MAX_SDP_FMT)\n\t    med->desc.fmt[med->desc.fmt_count++] = fmt;\n\telse\n\t    PJ_PERROR(2,(THIS_FILE, PJ_ETOOMANY, \n\t\t         \"Error adding SDP media format %.*s, \"\n\t\t\t \"format is ignored\",\n\t\t\t (int)fmt.slen, fmt.ptr));\n    }\n\n    /* We've got what we're looking for, skip anything until newline */\n    pj_scan_skip_line(scanner);\n}\n\nstatic void on_scanner_error(pj_scanner *scanner)\n{\n    PJ_UNUSED_ARG(scanner);\n\n    PJ_THROW(SYNTAX_ERROR);\n}\n\nstatic pjmedia_sdp_attr *parse_attr( pj_pool_t *pool, pj_scanner *scanner,\n\t\t\t\t    parse_context *ctx)\n{\n    pjmedia_sdp_attr *attr;\n\n    ctx->last_error = PJMEDIA_SDP_EINATTR;\n\n    attr = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_attr);\n\n    /* check equal sign */\n    if (*(scanner->curptr+1) != '=') {\n\ton_scanner_error(scanner);\n\treturn NULL;\n    }\n\n    /* skip a= */\n    pj_scan_advance_n(scanner, 2, SKIP_WS);\n    \n    /* get attr name. */\n    pj_scan_get(scanner, &cs_token, &attr->name);\n\n    if (*scanner->curptr && *scanner->curptr != '\\r' && \n\t*scanner->curptr != '\\n') \n    {\n\t/* skip ':' if present. */\n\tif (*scanner->curptr == ':')\n\t    pj_scan_get_char(scanner);\n\n\t/* get value */\n\tif (*scanner->curptr != '\\r' && *scanner->curptr != '\\n') {\n\t    pj_scan_get_until_chr(scanner, \"\\r\\n\", &attr->value);\n\t} else {\n\t    attr->value.ptr = NULL;\n\t    attr->value.slen = 0;\n\t}\n\n    } else {\n\tattr->value.ptr = NULL;\n\tattr->value.slen = 0;\n    }\n\n    /* We've got what we're looking for, skip anything until newline */\n    pj_scan_skip_line(scanner);\n\n    return attr;\n}\n\n\n/*\n * Apply direction attribute in session to all media.\n */\nstatic void apply_media_direction(pjmedia_sdp_session *sdp)\n{\n    pjmedia_sdp_attr *dir_attr = NULL;\n    unsigned i;\n\n    const pj_str_t inactive = { \"inactive\", 8 };\n    const pj_str_t sendonly = { \"sendonly\", 8 };\n    const pj_str_t recvonly = { \"recvonly\", 8 };\n    const pj_str_t sendrecv = { \"sendrecv\", 8 };\n\n    /* Find direction attribute in session, don't need to find default \n     * direction \"sendrecv\".\n     */\n    for (i = 0; i < sdp->attr_count && !dir_attr; ++i) {\n\tif (!pj_strcmp(&sdp->attr[i]->name, &sendonly) ||\n\t    !pj_strcmp(&sdp->attr[i]->name, &recvonly) ||\n\t    !pj_strcmp(&sdp->attr[i]->name, &inactive)) \n\t{\n\t    dir_attr = sdp->attr[i];\n\t}\n    }\n\n    /* Found the direction attribute */\n    if (dir_attr) {\n\t/* Remove the direction attribute in session */\n\tpjmedia_sdp_attr_remove(&sdp->attr_count, sdp->attr, dir_attr);\n\n\t/* Apply the direction attribute to all media, but not overriding it\n\t * if media already has direction attribute.\n\t */\n\tfor (i = 0; i < sdp->media_count; ++i) {\n\t    pjmedia_sdp_media *m;\n\t    unsigned j;\n\n\t    /* Find direction attribute in this media */\n\t    m = sdp->media[i];\n\t    for (j = 0; j < m->attr_count; ++j) {\n\t\tif (!pj_strcmp(&m->attr[j]->name, &sendrecv) ||\n\t\t    !pj_strcmp(&m->attr[j]->name, &sendonly) ||\n\t\t    !pj_strcmp(&m->attr[j]->name, &recvonly) ||\n\t\t    !pj_strcmp(&m->attr[j]->name, &inactive)) \n\t\t{\n\t\t    break;\n\t\t}\n\t    }\n\n\t    /* Not found, apply direction attribute from session */\n\t    if (j == m->attr_count)\n\t\tpjmedia_sdp_media_add_attr(m, dir_attr);\n\t}\n    }\n}\n\n\n/*\n * Parse SDP message.\n */\nPJ_DEF(pj_status_t) pjmedia_sdp_parse( pj_pool_t *pool,\n\t\t\t\t       char *buf, pj_size_t len, \n\t\t\t\t       pjmedia_sdp_session **p_sdp)\n{\n    pj_scanner scanner;\n    pjmedia_sdp_session *session;\n    pjmedia_sdp_media *media = NULL;\n    pjmedia_sdp_attr *attr;\n    pjmedia_sdp_conn *conn;\n    pjmedia_sdp_bandw *bandw;\n    pj_str_t dummy;\n    int cur_name = 254;\n    parse_context ctx;\n    PJ_USE_EXCEPTION;\n\n    ctx.last_error = PJ_SUCCESS;\n\n    init_sdp_parser();\n\n    pj_scan_init(&scanner, buf, len, 0, &on_scanner_error);\n    session = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_session);\n    PJ_ASSERT_RETURN(session != NULL, PJ_ENOMEM);\n\n    /* Ignore leading newlines */\n    while (*scanner.curptr=='\\r' || *scanner.curptr=='\\n')\n\tpj_scan_get_char(&scanner);\n\n    PJ_TRY {\n\twhile (!pj_scan_is_eof(&scanner)) {\n\t\tcur_name = *scanner.curptr;\n\t\tswitch (cur_name) {\n\t\tcase 'a':\n\t\t    attr = parse_attr(pool, &scanner, &ctx);\n\t\t    if (attr) {\n\t\t\tif (media) {\n\t\t\t    if (media->attr_count < PJMEDIA_MAX_SDP_ATTR)\n\t\t\t\tpjmedia_sdp_media_add_attr(media, attr);\n\t\t\t    else\n\t\t\t\tPJ_PERROR(2, (THIS_FILE, PJ_ETOOMANY,\n\t\t\t\t\t      \"Error adding media attribute, \"\n\t\t\t\t\t      \"attribute is ignored\"));\n\t\t\t} else {\n\t\t\t    if (session->attr_count < PJMEDIA_MAX_SDP_ATTR)\n\t\t\t\tpjmedia_sdp_session_add_attr(session, attr);\n\t\t\t    else\n\t\t\t\tPJ_PERROR(2, (THIS_FILE, PJ_ETOOMANY,\n\t\t\t\t\t      \"Error adding session attribute\"\n\t\t\t\t\t      \", attribute is ignored\"));\n\t\t\t}\n\t\t    }\n\t\t    break;\n\t\tcase 'o':\n\t\t    parse_origin(&scanner, session, &ctx);\n\t\t    break;\n\t\tcase 's':\n\t\t    parse_generic_line(&scanner, &session->name, &ctx);\n\t\t    break;\n\t\tcase 'c':\n\t\t    conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);\n\t\t    parse_connection_info(&scanner, conn, &ctx);\n\t\t    if (media) {\n\t\t\tmedia->conn = conn;\n\t\t    } else {\n\t\t\tsession->conn = conn;\n\t\t    }\n\t\t    break;\n\t\tcase 't':\n\t\t    parse_time(&scanner, session, &ctx);\n\t\t    break;\n\t\tcase 'm':\n\t\t    media = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media);\n\t\t    parse_media(&scanner, media, &ctx);\n\t\t    if (session->media_count < PJMEDIA_MAX_SDP_MEDIA)\n\t\t\tsession->media[ session->media_count++ ] = media;\n\t\t    else\n\t\t\tPJ_PERROR(2,(THIS_FILE, PJ_ETOOMANY,\n\t\t\t\t     \"Error adding media, media is ignored\"));\n\t\t    break;\n\t\tcase 'v':\n\t\t    parse_version(&scanner, &ctx);\n\t\t    break;\n\t\tcase 13:\n\t\tcase 10:\n\t\t    pj_scan_get_char(&scanner);\n\t\t    /* Allow empty newlines at the end of the message */\n\t\t    while (!pj_scan_is_eof(&scanner)) {\n\t\t\tif (*scanner.curptr != 13 && *scanner.curptr != 10) {\n\t\t\t    ctx.last_error = PJMEDIA_SDP_EINSDP;\n\t\t\t    on_scanner_error(&scanner);\n\t\t\t}\n\t\t\tpj_scan_get_char(&scanner);\n\t\t    }\n\t\t    break;\n\t\tcase 'b':\n\t\t    bandw = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_bandw);\n\t\t    parse_bandwidth_info(&scanner, bandw, &ctx);\n\t\t    if (media) {\n\t\t\tif (media->bandw_count < PJMEDIA_MAX_SDP_BANDW)\n\t\t\t    media->bandw[media->bandw_count++] = bandw;\n\t\t\telse\n\t\t\t    PJ_PERROR(2, (THIS_FILE, PJ_ETOOMANY,\n\t\t\t\t\t  \"Error adding media bandwidth \"\n\t\t\t\t\t  \"info, info is ignored\"));\n\t\t    } else {\n\t\t\tif (session->bandw_count < PJMEDIA_MAX_SDP_BANDW)\n\t\t\t    session->bandw[session->bandw_count++] = bandw;\n\t\t\telse\n\t\t\t    PJ_PERROR(2, (THIS_FILE, PJ_ETOOMANY,\n\t\t\t\t\t  \"Error adding session bandwidth \"\n\t\t\t\t\t  \"info, info is ignored\"));\n\t\t    }\n\t\t    break;\n\t\tdefault:\n\t\t    if (cur_name >= 'a' && cur_name <= 'z')\n\t\t\tparse_generic_line(&scanner, &dummy, &ctx);\n\t\t    else  {\n\t\t\tctx.last_error = PJMEDIA_SDP_EINSDP;\n\t\t\ton_scanner_error(&scanner);\n\t\t    }\n\t\t    break;\n\t\t}\n\t}\n\n\tctx.last_error = PJ_SUCCESS;\n\n    }\n    PJ_CATCH_ANY {\n\t\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\tpj_strerror(ctx.last_error, errmsg, sizeof(errmsg));\n\n\tPJ_LOG(4, (THIS_FILE, \"Error parsing SDP in line %d col %d: %s\",\n\t\t   scanner.line, pj_scan_get_col(&scanner),\n\t\t   errmsg));\n\n\tsession = NULL;\n\n\tpj_assert(ctx.last_error != PJ_SUCCESS);\n    }\n    PJ_END;\n\n    pj_scan_fini(&scanner);\n\n    if (session)\n\tapply_media_direction(session);\n\n    *p_sdp = session;\n    return ctx.last_error;\n}\n\n/*\n * Print SDP description.\n */\nPJ_DEF(int) pjmedia_sdp_print( const pjmedia_sdp_session *desc, \n\t\t\t       char *buf, pj_size_t size)\n{\n    return print_session(desc, buf, size);\n}\n\n\n/*\n * Clone session\n */\nPJ_DEF(pjmedia_sdp_session*) pjmedia_sdp_session_clone( pj_pool_t *pool,\n\t\t\t   \t\t\tconst pjmedia_sdp_session *rhs)\n{\n    pjmedia_sdp_session *sess;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(pool && rhs, NULL);\n\n    sess = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_session);\n    PJ_ASSERT_RETURN(sess != NULL, NULL);\n\n    /* Clone origin line. */\n    pj_strdup(pool, &sess->origin.user, &rhs->origin.user);\n    sess->origin.id = rhs->origin.id;\n    sess->origin.version = rhs->origin.version;\n    pj_strdup(pool, &sess->origin.net_type, &rhs->origin.net_type);\n    pj_strdup(pool, &sess->origin.addr_type, &rhs->origin.addr_type);\n    pj_strdup(pool, &sess->origin.addr, &rhs->origin.addr);\n\n    /* Clone subject line. */\n    pj_strdup(pool, &sess->name, &rhs->name);\n\n    /* Clone connection line */\n    if (rhs->conn) {\n\tsess->conn = pjmedia_sdp_conn_clone(pool, rhs->conn);\n\tPJ_ASSERT_RETURN(sess->conn != NULL, NULL);\n    }\n\n    /* Duplicate bandwidth info */\n    sess->bandw_count = rhs->bandw_count;\n    for (i=0; i<rhs->bandw_count; ++i) {\n\tsess->bandw[i] = pjmedia_sdp_bandw_clone(pool, rhs->bandw[i]);\n    }\n\n    /* Clone time line. */\n    sess->time.start = rhs->time.start;\n    sess->time.stop = rhs->time.stop;\n\n    /* Duplicate session attributes. */\n    sess->attr_count = rhs->attr_count;\n    for (i=0; i<rhs->attr_count; ++i) {\n\tsess->attr[i] = pjmedia_sdp_attr_clone(pool, rhs->attr[i]);\n    }\n\n    /* Duplicate media descriptors. */\n    sess->media_count = rhs->media_count;\n    for (i=0; i<rhs->media_count; ++i) {\n\tsess->media[i] = pjmedia_sdp_media_clone(pool, rhs->media[i]);\n    }\n\n    return sess;\n}\n\n\n#define CHECK(exp,ret)\tdo {\t\t\t\\\n\t\t\t    /*pj_assert(exp);*/\t\\\n\t\t\t    if (!(exp))\t\t\\\n\t\t\t\treturn ret;\t\\\n\t\t\t} while (0)\n\n/* Validate SDP connetion info. */\nstatic pj_status_t validate_sdp_conn(const pjmedia_sdp_conn *c)\n{\n    CHECK( c, PJ_EINVAL);\n    CHECK( pj_strcmp2(&c->net_type, \"IN\")==0, PJMEDIA_SDP_EINCONN);\n    CHECK( pj_strcmp2(&c->addr_type, \"IP4\")==0 ||\n\t   pj_strcmp2(&c->addr_type, \"IP6\")==0, \n\t   PJMEDIA_SDP_EINCONN);\n    CHECK( c->addr.slen != 0, PJMEDIA_SDP_EINCONN);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Validate SDP session descriptor. */\nPJ_DEF(pj_status_t) pjmedia_sdp_validate(const pjmedia_sdp_session *sdp)\n{\n    return pjmedia_sdp_validate2(sdp, PJ_TRUE);\n}\n\n\n/* Validate SDP session descriptor. */\nPJ_DEF(pj_status_t) pjmedia_sdp_validate2(const pjmedia_sdp_session *sdp,\n\t\t\t\t\t  pj_bool_t strict)\n{\n    unsigned i;\n    const pj_str_t STR_RTPMAP = { \"rtpmap\", 6 };\n\n    CHECK( sdp != NULL, PJ_EINVAL);\n\n    /* Validate origin line. */\n    CHECK( sdp->origin.user.slen != 0, PJMEDIA_SDP_EINORIGIN);\n    CHECK( pj_strcmp2(&sdp->origin.net_type, \"IN\")==0, \n\t   PJMEDIA_SDP_EINORIGIN);\n    CHECK( pj_strcmp2(&sdp->origin.addr_type, \"IP4\")==0 ||\n\t   pj_strcmp2(&sdp->origin.addr_type, \"IP6\")==0, \n\t   PJMEDIA_SDP_EINORIGIN);\n    CHECK( sdp->origin.addr.slen != 0, PJMEDIA_SDP_EINORIGIN);\n\n    /* Validate subject line. */\n    CHECK( sdp->name.slen != 0, PJMEDIA_SDP_EINNAME);\n\n    /* Ignore start and stop time. */\n\n    /* If session level connection info is present, validate it. */\n    if (sdp->conn) {\n\tpj_status_t status = validate_sdp_conn(sdp->conn);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    /* Validate each media. */\n    for (i=0; i<sdp->media_count; ++i) {\n\tconst pjmedia_sdp_media *m = sdp->media[i];\n\tunsigned j;\n\n\t/* Validate the m= line. */\n\tCHECK( m->desc.media.slen != 0, PJMEDIA_SDP_EINMEDIA);\n\tCHECK( m->desc.transport.slen != 0, PJMEDIA_SDP_EINMEDIA);\n\tCHECK( m->desc.fmt_count != 0 || m->desc.port==0, PJMEDIA_SDP_ENOFMT);\n\n\t/* If media level connection info is present, validate it. */\n\tif (m->conn) {\n\t    pj_status_t status = validate_sdp_conn(m->conn);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\t}\n\n\t/* If media doesn't have connection info, then connection info\n\t * must be present in the session.\n\t */\n\tif (m->conn == NULL) {\n\t    if (sdp->conn == NULL)\n\t\tif (strict || m->desc.port != 0)\n\t\t    return PJMEDIA_SDP_EMISSINGCONN;\n\t}\n\n\t/* Verify payload type. */\n\tfor (j=0; j<m->desc.fmt_count; ++j) {\n\n\t    /* Arrgh noo!! Payload type can be non-numeric!!\n\t     * RTC based programs sends \"null\" for instant messaging!\n\t     */\n\t    if (pj_isdigit(*m->desc.fmt[j].ptr)) {\n\t\tunsigned pt = pj_strtoul(&m->desc.fmt[j]);\n\n\t\t/* Payload type is between 0 and 127. \n\t\t */\n\t\tCHECK( pt <= 127, PJMEDIA_SDP_EINPT);\n\n\t\t/* If port is not zero, then for each dynamic payload type, an\n\t\t * rtpmap attribute must be specified.\n\t\t */\n\t\tif (m->desc.port != 0 && pt >= 96) {\n\t\t    const pjmedia_sdp_attr *a;\n\n\t\t    a = pjmedia_sdp_media_find_attr(m, &STR_RTPMAP, \n\t\t\t\t\t\t    &m->desc.fmt[j]);\n\t\t    CHECK( a != NULL, PJMEDIA_SDP_EMISSINGRTPMAP);\n\t\t}\n\t    }\n\t}\n    }\n\n    /* Looks good. */\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_transport_cmp( const pj_str_t *t1,\n\t\t\t\t\t       const pj_str_t *t2)\n{\n    static const pj_str_t ID_RTP_AVP  = { \"RTP/AVP\", 7 };\n    static const pj_str_t ID_RTP_SAVP = { \"RTP/SAVP\", 8 };\n\n    /* Exactly equal? */\n    if (pj_stricmp(t1, t2) == 0)\n\treturn PJ_SUCCESS;\n\n    /* Compatible? */\n    if ((!pj_stricmp(t1, &ID_RTP_AVP) || !pj_stricmp(t1, &ID_RTP_SAVP)) &&\n        (!pj_stricmp(t2, &ID_RTP_AVP) || !pj_stricmp(t2, &ID_RTP_SAVP)))\n\treturn PJ_SUCCESS;\n\n    return PJMEDIA_SDP_ETPORTNOTEQUAL;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_media_deactivate(pj_pool_t *pool,\n\t\t\t\t\t\t pjmedia_sdp_media *m)\n{\n    PJ_ASSERT_RETURN(m, PJ_EINVAL);\n    PJ_UNUSED_ARG(pool);\n\n    /* Set port to zero */\n    m->desc.port = 0;\n\n    /* And remove attributes */\n    m->attr_count = 0;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pjmedia_sdp_media*) pjmedia_sdp_media_clone_deactivate(\n\t\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\t\tconst pjmedia_sdp_media *rhs)\n{\n    unsigned int i;\n    pjmedia_sdp_media *m;\n\n    PJ_ASSERT_RETURN(pool && rhs, NULL);\n\n    m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media);\n    pj_memcpy(m, rhs, sizeof(*m));\n\n    /* Clone the media line only */\n    pj_strdup (pool, &m->desc.media, &rhs->desc.media);\n    pj_strdup (pool, &m->desc.transport, &rhs->desc.transport);\n    for (i=0; i<rhs->desc.fmt_count; ++i)\n\tpj_strdup(pool, &m->desc.fmt[i], &rhs->desc.fmt[i]);\n\n    if (rhs->conn) {\n\tm->conn = pjmedia_sdp_conn_clone (pool, rhs->conn);\n\tPJ_ASSERT_RETURN(m->conn != NULL, NULL);\n    }\n\n    m->bandw_count = rhs->bandw_count;\n    for (i=0; i < rhs->bandw_count; ++i) {\n\tm->bandw[i] = pjmedia_sdp_bandw_clone (pool, rhs->bandw[i]);\n\tPJ_ASSERT_RETURN(m->bandw[i] != NULL, NULL);\n    }\n\n    /* And deactivate it */\n    pjmedia_sdp_media_deactivate(pool, m);\n\n    return m;\n}\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/sdp_cmp.c",
    "content": "/* $Id: sdp_cmp.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/sdp.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/string.h>\n\n\n/* Compare connection line. */\nstatic pj_status_t compare_conn(const pjmedia_sdp_conn *c1,\n\t\t\t\tconst pjmedia_sdp_conn *c2)\n{\n    /* Compare network type. */\n    if (pj_strcmp(&c1->net_type, &c2->net_type) != 0)\n\treturn PJMEDIA_SDP_ECONNNOTEQUAL;\n\n    /* Compare address type. */\n    if (pj_strcmp(&c1->addr_type, &c2->addr_type) != 0)\n\treturn PJMEDIA_SDP_ECONNNOTEQUAL;\n\n    /* Compare address. */\n    if (pj_strcmp(&c1->addr, &c2->addr) != 0)\n\treturn PJMEDIA_SDP_ECONNNOTEQUAL;\n\n    return PJ_SUCCESS;\n}\n\n/* Compare attributes array. */\nstatic pj_status_t compare_attr_imp(unsigned count1,\n\t\t\t\t    pjmedia_sdp_attr *const attr1[],\n\t\t\t\t    unsigned count2,\n\t\t\t\t    pjmedia_sdp_attr *const attr2[])\n{\n    pj_status_t status;\n    unsigned i;\n    const pj_str_t inactive = { \"inactive\", 8 };\n    const pj_str_t sendrecv = { \"sendrecv\", 8 };\n    const pj_str_t sendonly = { \"sendonly\", 8 };\n    const pj_str_t recvonly = { \"recvonly\", 8 };\n    const pj_str_t fmtp = { \"fmtp\", 4 };\n    const pj_str_t rtpmap = { \"rtpmap\", 6 };\n\n    /* For simplicity, we only compare the following attributes, and ignore\n     * the others:\n     *\t- direction, eg. inactive, sendonly, recvonly, sendrecv\n     *\t- fmtp for each payload.\n     *\t- rtpmap for each payload.\n     */\n    for (i=0; i<count1; ++i) {\n\tconst pjmedia_sdp_attr *a1 = attr1[i];\n\n\tif (pj_strcmp(&a1->name, &inactive) == 0 || \n\t    pj_strcmp(&a1->name, &sendrecv) == 0 ||\n\t    pj_strcmp(&a1->name, &sendonly) == 0 ||\n\t    pj_strcmp(&a1->name, &recvonly) == 0)\n\t{\n\t    /* For inactive, sendrecv, sendonly, and recvonly attributes,\n\t     * the same attribute must be present on the other SDP.\n\t     */\n\t    const pjmedia_sdp_attr *a2;\n\t    a2 = pjmedia_sdp_attr_find(count2, attr2, &a1->name, NULL);\n\t    if (!a2)\n\t\treturn PJMEDIA_SDP_EDIRNOTEQUAL;\n\n\t} else if (pj_strcmp(&a1->name, &fmtp) == 0) {\n\t    /* For fmtp attribute, find the fmtp attribute in the other SDP\n\t     * for the same payload type, and compare the fmtp param/value.\n\t     */\n\t    pjmedia_sdp_fmtp fmtp1, fmtp2;\n\t    const pjmedia_sdp_attr *a2;\n\n\t    status = pjmedia_sdp_attr_get_fmtp(a1, &fmtp1);\n\t    if (status != PJ_SUCCESS)\n\t\treturn PJMEDIA_SDP_EFMTPNOTEQUAL;\n\n\t    a2 = pjmedia_sdp_attr_find(count2, attr2, &a1->name, &fmtp1.fmt);\n\t    if (!a2)\n\t\treturn PJMEDIA_SDP_EFMTPNOTEQUAL;\n\n\t    status = pjmedia_sdp_attr_get_fmtp(a2, &fmtp2);\n\t    if (status != PJ_SUCCESS)\n\t\treturn PJMEDIA_SDP_EFMTPNOTEQUAL;\n\n\t    if (pj_strcmp(&fmtp1.fmt_param, &fmtp2.fmt_param) != 0)\n\t\treturn PJMEDIA_SDP_EFMTPNOTEQUAL;\n\n\t} else if (pj_strcmp(&a1->name, &rtpmap) == 0) {\n\t    /* For rtpmap attribute, find rtpmap attribute on the other SDP\n\t     * for the same payload type, and compare both rtpmap atribute\n\t     * values.\n\t     */\n\t    pjmedia_sdp_rtpmap r1, r2;\n\t    const pjmedia_sdp_attr *a2;\n\n\t    status = pjmedia_sdp_attr_get_rtpmap(a1, &r1);\n\t    if (status != PJ_SUCCESS)\n\t\treturn PJMEDIA_SDP_ERTPMAPNOTEQUAL;\n\n\t    a2 = pjmedia_sdp_attr_find(count2, attr2, &a1->name, &r1.pt);\n\t    if (!a2)\n\t\treturn PJMEDIA_SDP_ERTPMAPNOTEQUAL;\n\n\t    status = pjmedia_sdp_attr_get_rtpmap(a2, &r2);\n\t    if (status != PJ_SUCCESS)\n\t\treturn PJMEDIA_SDP_ERTPMAPNOTEQUAL;\n\n\t    if (pj_strcmp(&r1.pt, &r2.pt) != 0)\n\t\treturn PJMEDIA_SDP_ERTPMAPNOTEQUAL;\n\t    if (pj_strcmp(&r1.enc_name, &r2.enc_name) != 0)\n\t\treturn PJMEDIA_SDP_ERTPMAPNOTEQUAL;\n\t    if (r1.clock_rate != r2.clock_rate)\n\t\treturn PJMEDIA_SDP_ERTPMAPNOTEQUAL;\n\t    if (pj_strcmp(&r1.param, &r2.param) != 0)\n\t\treturn PJMEDIA_SDP_ERTPMAPNOTEQUAL;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* Compare attributes array. */\nstatic pj_status_t compare_attr(unsigned count1,\n\t\t\t\tpjmedia_sdp_attr *const attr1[],\n\t\t\t\tunsigned count2,\n\t\t\t\tpjmedia_sdp_attr *const attr2[])\n{\n    pj_status_t status;\n\n    status = compare_attr_imp(count1, attr1, count2, attr2);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    status = compare_attr_imp(count2, attr2, count1, attr1);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return PJ_SUCCESS;\n}\n\n/* Compare media descriptor */\nPJ_DEF(pj_status_t) pjmedia_sdp_media_cmp( const pjmedia_sdp_media *sd1,\n\t\t\t\t\t   const pjmedia_sdp_media *sd2,\n\t\t\t\t\t   unsigned option)\n{\n    unsigned i;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sd1 && sd2 && option==0, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(option);\n\n    /* Compare media type. */\n    if (pj_strcmp(&sd1->desc.media, &sd2->desc.media) != 0)\n\treturn PJMEDIA_SDP_EMEDIANOTEQUAL;\n\n    /* Compare port number. */\n    if (sd1->desc.port != sd2->desc.port)\n\treturn PJMEDIA_SDP_EPORTNOTEQUAL;\n\n    /* Compare port count. */\n    if (sd1->desc.port_count != sd2->desc.port_count)\n\treturn PJMEDIA_SDP_EPORTNOTEQUAL;\n\n    /* Compare transports. */\n    if (pj_strcmp(&sd1->desc.transport, &sd2->desc.transport) != 0)\n\treturn PJMEDIA_SDP_ETPORTNOTEQUAL;\n\n    /* For zeroed port media, stop comparing here */\n    if (sd1->desc.port == 0)\n\treturn PJ_SUCCESS;\n\n    /* Compare number of formats. */\n    if (sd1->desc.fmt_count != sd2->desc.fmt_count)\n\treturn PJMEDIA_SDP_EFORMATNOTEQUAL;\n\n    /* Compare formats, in order. */\n    for (i=0; i<sd1->desc.fmt_count; ++i) {\n\tif (pj_strcmp(&sd1->desc.fmt[i], &sd2->desc.fmt[i]) != 0)\n\t    return PJMEDIA_SDP_EFORMATNOTEQUAL;\n    }\n\n    /* Compare connection line, if they exist. */\n    if (sd1->conn) {\n\tif (!sd2->conn)\n\t    return PJMEDIA_SDP_EMEDIANOTEQUAL;\n\tstatus = compare_conn(sd1->conn, sd2->conn);\n    } else {\n\tif (sd2->conn)\n\t    return PJMEDIA_SDP_EMEDIANOTEQUAL;\n    }\n\n    /* Compare attributes. */\n    status = compare_attr(sd1->attr_count, sd1->attr, \n\t\t\t  sd2->attr_count, sd2->attr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Looks equal */\n    return PJ_SUCCESS;\n}\n\n/*\n * Compare two SDP session for equality.\n */\nPJ_DEF(pj_status_t) pjmedia_sdp_session_cmp( const pjmedia_sdp_session *sd1,\n\t\t\t\t\t     const pjmedia_sdp_session *sd2,\n\t\t\t\t\t     unsigned option)\n{\n    unsigned i;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sd1 && sd2 && option==0, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(option);\n\n    /* Compare the origin line. */\n    if (pj_strcmp(&sd1->origin.user, &sd2->origin.user) != 0)\n\treturn PJMEDIA_SDP_EORIGINNOTEQUAL;\n\n    if (sd1->origin.id != sd2->origin.id)\n\treturn PJMEDIA_SDP_EORIGINNOTEQUAL;\n\n    if (sd1->origin.version != sd2->origin.version)\n\treturn PJMEDIA_SDP_EORIGINNOTEQUAL;\n\n    if (pj_strcmp(&sd1->origin.net_type, &sd2->origin.net_type) != 0)\n\treturn PJMEDIA_SDP_EORIGINNOTEQUAL;\n\n    if (pj_strcmp(&sd1->origin.addr_type, &sd2->origin.addr_type) != 0)\n\treturn PJMEDIA_SDP_EORIGINNOTEQUAL;\n\n    if (pj_strcmp(&sd1->origin.addr, &sd2->origin.addr) != 0)\n\treturn PJMEDIA_SDP_EORIGINNOTEQUAL;\n\n    \n    /* Compare the subject line. */\n    if (pj_strcmp(&sd1->name, &sd2->name) != 0)\n\treturn PJMEDIA_SDP_ENAMENOTEQUAL;\n\n    /* Compare connection line, when they exist */\n    if (sd1->conn) {\n\tif (!sd2->conn)\n\t    return PJMEDIA_SDP_ECONNNOTEQUAL;\n\tstatus = compare_conn(sd1->conn, sd2->conn);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    } else {\n\tif (sd2->conn)\n\t    return PJMEDIA_SDP_ECONNNOTEQUAL;\n    }\n\n    /* Compare time line. */\n    if (sd1->time.start != sd2->time.start)\n\treturn PJMEDIA_SDP_ETIMENOTEQUAL;\n\n    if (sd1->time.stop != sd2->time.stop)\n\treturn PJMEDIA_SDP_ETIMENOTEQUAL;\n\n    /* Compare attributes. */\n    status = compare_attr(sd1->attr_count, sd1->attr, \n\t\t\t  sd2->attr_count, sd2->attr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Compare media lines. */\n    if (sd1->media_count != sd2->media_count)\n\treturn PJMEDIA_SDP_EMEDIANOTEQUAL;\n\n    for (i=0; i<sd1->media_count; ++i) {\n\tstatus = pjmedia_sdp_media_cmp(sd1->media[i], sd2->media[i], 0);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    /* Looks equal. */\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_conn_cmp(const pjmedia_sdp_conn *conn1, \n\t\t\t\t\t const pjmedia_sdp_conn *conn2,\n\t\t\t\t\t unsigned option)\n{\n    PJ_UNUSED_ARG(option);\n    return compare_conn(conn1, conn2);\n}\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/sdp_neg.c",
    "content": "/* $Id: sdp_neg.c 4498 2013-04-24 09:52:25Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/sdp_neg.h>\n#include <pjmedia/sdp.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/ctype.h>\n#include <pj/array.h>\n\n/**\n * This structure describes SDP media negotiator.\n */\nstruct pjmedia_sdp_neg\n{\n    pjmedia_sdp_neg_state state;\t    /**< Negotiator state.\t     */\n    pj_bool_t\t\t  prefer_remote_codec_order;\n    pj_bool_t             answer_with_multiple_codecs;\n    pj_bool_t\t\t  has_remote_answer;\n    pj_bool_t\t\t  answer_was_remote;\n\n    pjmedia_sdp_session\t*initial_sdp,\t    /**< Initial local SDP\t     */\n\t\t\t*initial_sdp_tmp,   /**< Temporary initial local SDP */\n\t\t\t*active_local_sdp,  /**< Currently active local SDP. */\n\t\t\t*active_remote_sdp, /**< Currently active remote's.  */\n\t\t\t*neg_local_sdp,\t    /**< Temporary local SDP.\t     */\n\t\t\t*neg_remote_sdp;    /**< Temporary remote SDP.\t     */\n};\n\nstatic const char *state_str[] = \n{\n    \"STATE_NULL\",\n    \"STATE_LOCAL_OFFER\",\n    \"STATE_REMOTE_OFFER\",\n    \"STATE_WAIT_NEGO\",\n    \"STATE_DONE\",\n};\n\n/* Definition of customized SDP format negotiation callback */\nstruct fmt_match_cb_t\n{\n    pj_str_t\t\t\t    fmt_name;\n    pjmedia_sdp_neg_fmt_match_cb    cb;\n};\n\n/* Number of registered customized SDP format negotiation callbacks */\nstatic unsigned fmt_match_cb_cnt;\n\n/* The registered customized SDP format negotiation callbacks */\nstatic struct fmt_match_cb_t \n\t      fmt_match_cb[PJMEDIA_SDP_NEG_MAX_CUSTOM_FMT_NEG_CB];\n\n/* Redefining a very long identifier name, just for convenience */\n#define ALLOW_MODIFY_ANSWER PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER\n\nstatic pj_status_t custom_fmt_match( pj_pool_t *pool,\n\t\t\t\t   const pj_str_t *fmt_name,\n\t\t\t\t   pjmedia_sdp_media *offer,\n\t\t\t\t   unsigned o_fmt_idx,\n\t\t\t\t   pjmedia_sdp_media *answer,\n\t\t\t\t   unsigned a_fmt_idx,\n\t\t\t\t   unsigned option);\n\n\n/*\n * Get string representation of negotiator state.\n */\nPJ_DEF(const char*) pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_state state)\n{\n    if ((int)state >=0 && state < (pjmedia_sdp_neg_state)PJ_ARRAY_SIZE(state_str))\n\treturn state_str[state];\n\n    return \"<?UNKNOWN?>\";\n}\n\n\n/*\n * Create with local offer.\n */\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_create_w_local_offer( pj_pool_t *pool,\n\t\t\t\t      const pjmedia_sdp_session *local,\n\t\t\t\t      pjmedia_sdp_neg **p_neg)\n{\n    pjmedia_sdp_neg *neg;\n    pj_status_t status;\n\n    /* Check arguments are valid. */\n    PJ_ASSERT_RETURN(pool && local && p_neg, PJ_EINVAL);\n\n    *p_neg = NULL;\n\n    /* Validate local offer. */\n    PJ_ASSERT_RETURN((status=pjmedia_sdp_validate(local))==PJ_SUCCESS, status);\n\n    /* Create and initialize negotiator. */\n    neg = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_neg);\n    PJ_ASSERT_RETURN(neg != NULL, PJ_ENOMEM);\n\n    neg->state = PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER;\n    neg->prefer_remote_codec_order = PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER;\n    neg->answer_with_multiple_codecs = PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS;\n    neg->initial_sdp = pjmedia_sdp_session_clone(pool, local);\n    neg->neg_local_sdp = pjmedia_sdp_session_clone(pool, local);\n\n    *p_neg = neg;\n    return PJ_SUCCESS;\n}\n\n/*\n * Create with remote offer and initial local offer/answer.\n */\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_create_w_remote_offer(pj_pool_t *pool,\n\t\t\t\t      const pjmedia_sdp_session *initial,\n\t\t\t\t      const pjmedia_sdp_session *remote,\n\t\t\t\t      pjmedia_sdp_neg **p_neg)\n{\n    pjmedia_sdp_neg *neg;\n    pj_status_t status;\n\n    /* Check arguments are valid. */\n    PJ_ASSERT_RETURN(pool && remote && p_neg, PJ_EINVAL);\n\n    *p_neg = NULL;\n\n    /* Validate remote offer and initial answer */\n    status = pjmedia_sdp_validate2(remote, PJ_FALSE);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Create and initialize negotiator. */\n    neg = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_neg);\n    PJ_ASSERT_RETURN(neg != NULL, PJ_ENOMEM);\n\n    neg->prefer_remote_codec_order = PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER;\n    neg->neg_remote_sdp = pjmedia_sdp_session_clone(pool, remote);\n\n    if (initial) {\n\tPJ_ASSERT_RETURN((status=pjmedia_sdp_validate(initial))==PJ_SUCCESS, \n\t\t\t status);\n\n\tneg->initial_sdp = pjmedia_sdp_session_clone(pool, initial);\n\tneg->neg_local_sdp = pjmedia_sdp_session_clone(pool, initial);\n\n\tneg->state = PJMEDIA_SDP_NEG_STATE_WAIT_NEGO;\n\n    } else {\n\t\n\tneg->state = PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER;\n\n    }\n\n    *p_neg = neg;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Set codec order preference.\n */\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_set_prefer_remote_codec_order(\n\t\t\t\t\t\tpjmedia_sdp_neg *neg,\n\t\t\t\t\t\tpj_bool_t prefer_remote)\n{\n    PJ_ASSERT_RETURN(neg, PJ_EINVAL);\n    neg->prefer_remote_codec_order = prefer_remote;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Set multiple codec answering.\n */\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_set_answer_multiple_codecs(\n                        pjmedia_sdp_neg *neg,\n                        pj_bool_t answer_multiple)\n{\n    PJ_ASSERT_RETURN(neg, PJ_EINVAL);\n    neg->answer_with_multiple_codecs = answer_multiple;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get SDP negotiator state.\n */\nPJ_DEF(pjmedia_sdp_neg_state) pjmedia_sdp_neg_get_state( pjmedia_sdp_neg *neg )\n{\n    /* Check arguments are valid. */\n    PJ_ASSERT_RETURN(neg != NULL, PJMEDIA_SDP_NEG_STATE_NULL);\n    return neg->state;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_get_active_local( pjmedia_sdp_neg *neg,\n\t\t\t\t\tconst pjmedia_sdp_session **local)\n{\n    PJ_ASSERT_RETURN(neg && local, PJ_EINVAL);\n    PJ_ASSERT_RETURN(neg->active_local_sdp, PJMEDIA_SDPNEG_ENOACTIVE);\n\n    *local = neg->active_local_sdp;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_get_active_remote( pjmedia_sdp_neg *neg,\n\t\t\t\t   const pjmedia_sdp_session **remote)\n{\n    PJ_ASSERT_RETURN(neg && remote, PJ_EINVAL);\n    PJ_ASSERT_RETURN(neg->active_remote_sdp, PJMEDIA_SDPNEG_ENOACTIVE);\n\n    *remote = neg->active_remote_sdp;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_bool_t) pjmedia_sdp_neg_was_answer_remote(pjmedia_sdp_neg *neg)\n{\n    PJ_ASSERT_RETURN(neg, PJ_FALSE);\n\n    return neg->answer_was_remote;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_get_neg_remote( pjmedia_sdp_neg *neg,\n\t\t\t\tconst pjmedia_sdp_session **remote)\n{\n    PJ_ASSERT_RETURN(neg && remote, PJ_EINVAL);\n    PJ_ASSERT_RETURN(neg->neg_remote_sdp, PJMEDIA_SDPNEG_ENONEG);\n\n    *remote = neg->neg_remote_sdp;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_get_neg_local( pjmedia_sdp_neg *neg,\n\t\t\t       const pjmedia_sdp_session **local)\n{\n    PJ_ASSERT_RETURN(neg && local, PJ_EINVAL);\n    PJ_ASSERT_RETURN(neg->neg_local_sdp, PJMEDIA_SDPNEG_ENONEG);\n\n    *local = neg->neg_local_sdp;\n    return PJ_SUCCESS;\n}\n\nstatic pjmedia_sdp_media *sdp_media_clone_deactivate(\n\t\t\t\t    pj_pool_t *pool,\n                                    const pjmedia_sdp_media *rem_med,\n                                    const pjmedia_sdp_media *local_med,\n                                    const pjmedia_sdp_session *local_sess)\n{\n    pjmedia_sdp_media *res;\n\n    res = pjmedia_sdp_media_clone_deactivate(pool, rem_med);\n    if (!res)\n\treturn NULL;\n\n    if (!res->conn && (!local_sess || !local_sess->conn)) {\n\tif (local_med && local_med->conn)\n\t    res->conn = pjmedia_sdp_conn_clone(pool, local_med->conn);\n\telse {\n\t    res->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);\n\t    res->conn->net_type = pj_str(\"IN\");\n\t    res->conn->addr_type = pj_str(\"IP4\");\n\t    res->conn->addr = pj_str(\"127.0.0.1\");\n\t}\n    }\n\n    return res;\n}\n\n/*\n * Modify local SDP and wait for remote answer.\n */\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer( pj_pool_t *pool,\n\t\t\t\t    pjmedia_sdp_neg *neg,\n\t\t\t\t    const pjmedia_sdp_session *local)\n{\n    return pjmedia_sdp_neg_modify_local_offer2(pool, neg, 0, local);\n}\n\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2(\n                                    pj_pool_t *pool,\n\t\t\t\t    pjmedia_sdp_neg *neg,\n                                    unsigned flags,\n\t\t\t\t    const pjmedia_sdp_session *local)\n{\n    pjmedia_sdp_session *new_offer;\n    pjmedia_sdp_session *old_offer;\n    char media_used[PJMEDIA_MAX_SDP_MEDIA];\n    unsigned oi; /* old offer media index */\n    pj_status_t status;\n\n    /* Check arguments are valid. */\n    PJ_ASSERT_RETURN(pool && neg && local, PJ_EINVAL);\n\n    /* Can only do this in STATE_DONE. */\n    PJ_ASSERT_RETURN(neg->state == PJMEDIA_SDP_NEG_STATE_DONE, \n\t\t     PJMEDIA_SDPNEG_EINSTATE);\n\n    /* Validate the new offer */\n    status = pjmedia_sdp_validate(local);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Change state to STATE_LOCAL_OFFER */\n    neg->state = PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER;\n\n    /* Init vars */\n    pj_bzero(media_used, sizeof(media_used));\n    old_offer = neg->active_local_sdp;\n    new_offer = pjmedia_sdp_session_clone(pool, local);\n\n    /* RFC 3264 Section 8: When issuing an offer that modifies the session,\n     * the \"o=\" line of the new SDP MUST be identical to that in the\n     * previous SDP, except that the version in the origin field MUST\n     * increment by one from the previous SDP.\n     */\n    pj_strdup(pool, &new_offer->origin.user, &old_offer->origin.user);\n    new_offer->origin.id = old_offer->origin.id;\n    new_offer->origin.version = old_offer->origin.version + 1;\n    pj_strdup(pool, &new_offer->origin.net_type, &old_offer->origin.net_type);\n    pj_strdup(pool, &new_offer->origin.addr_type,&old_offer->origin.addr_type);\n    pj_strdup(pool, &new_offer->origin.addr, &old_offer->origin.addr);\n\n    if ((flags & PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE) == 0) {\n       /* Generating the new offer, in the case media lines doesn't match the\n        * active SDP (e.g. current/active SDP's have m=audio and m=video lines,\n        * and the new offer only has m=audio line), the negotiator will fix \n        * the new offer by reordering and adding the missing media line with \n        * port number set to zero.\n        */\n        for (oi = 0; oi < old_offer->media_count; ++oi) {\n\t    pjmedia_sdp_media *om;\n\t    pjmedia_sdp_media *nm;\n\t    unsigned ni; /* new offer media index */\n\t    pj_bool_t found = PJ_FALSE;\n\n\t    om = old_offer->media[oi];\n\t    for (ni = oi; ni < new_offer->media_count; ++ni) {\n\t        nm = new_offer->media[ni];\n\t        if (pj_strcmp(&nm->desc.media, &om->desc.media) == 0) {\n\t\t    if (ni != oi) {\n\t\t        /* The same media found but the position unmatched to\n                         * the old offer, so let's put this media in the right\n                         * place, and keep the order of the rest.\n\t\t         */\n\t\t        pj_array_insert(\n                            new_offer->media,\t\t /* array    */\n\t\t\t    sizeof(new_offer->media[0]), /* elmt size*/\n\t\t\t    ni,\t\t\t\t /* count    */\n\t\t            oi,\t\t\t\t /* pos      */\n\t\t\t    &nm);\t\t\t /* new elmt */\n\t\t    }\n\t\t    found = PJ_TRUE;\n\t\t    break;\n\t        }\n\t    }\n\t    if (!found) {\n\t        pjmedia_sdp_media *m;\n\n\t        m = sdp_media_clone_deactivate(pool, om, om, local);\n\n\t        pj_array_insert(new_offer->media, sizeof(new_offer->media[0]),\n\t\t\t        new_offer->media_count++, oi, &m);\n\t    }\n        }\n    } else {\n        /* If media type change is allowed, the negotiator only needs to fix \n         * the new offer by adding the missing media line(s) with port number\n         * set to zero.\n         */\n        for (oi = new_offer->media_count; oi < old_offer->media_count; ++oi) {\n            pjmedia_sdp_media *m;\n\n\t    m = sdp_media_clone_deactivate(pool, old_offer->media[oi],\n                                           old_offer->media[oi], local);\n\n\t    pj_array_insert(new_offer->media, sizeof(new_offer->media[0]),\n\t                    new_offer->media_count++, oi, &m);\n\n        }\n    }\n\n    /* New_offer fixed */\n    neg->initial_sdp_tmp = neg->initial_sdp;\n    neg->initial_sdp = new_offer;\n    neg->neg_local_sdp = pjmedia_sdp_session_clone(pool, new_offer);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_send_local_offer( pj_pool_t *pool,\n\t\t\t\t  pjmedia_sdp_neg *neg,\n\t\t\t\t  const pjmedia_sdp_session **offer)\n{\n    /* Check arguments are valid. */\n    PJ_ASSERT_RETURN(neg && offer, PJ_EINVAL);\n\n    *offer = NULL;\n\n    /* Can only do this in STATE_DONE or STATE_LOCAL_OFFER. */\n    PJ_ASSERT_RETURN(neg->state == PJMEDIA_SDP_NEG_STATE_DONE ||\n\t\t     neg->state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, \n\t\t     PJMEDIA_SDPNEG_EINSTATE);\n\n    if (neg->state == PJMEDIA_SDP_NEG_STATE_DONE) {\n\t/* If in STATE_DONE, set the active SDP as the offer. */\n\tPJ_ASSERT_RETURN(neg->active_local_sdp, PJMEDIA_SDPNEG_ENOACTIVE);\n\n\t/* Retain initial SDP */\n\tif (neg->initial_sdp) {\n\t    neg->initial_sdp_tmp = neg->initial_sdp;\n    \t    neg->initial_sdp = pjmedia_sdp_session_clone(pool,\n\t\t\t\t\t\t\t neg->initial_sdp);\n\t}\n\n\tneg->state = PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER;\n\tneg->neg_local_sdp = pjmedia_sdp_session_clone(pool, \n\t\t\t\t\t\t       neg->active_local_sdp);\n\t*offer = neg->active_local_sdp;\n\n    } else {\n\t/* We assume that we're in STATE_LOCAL_OFFER.\n\t * In this case set the neg_local_sdp as the offer.\n\t */\n\t*offer = neg->neg_local_sdp;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_set_remote_answer( pj_pool_t *pool,\n\t\t\t\t   pjmedia_sdp_neg *neg,\n\t\t\t\t   const pjmedia_sdp_session *remote)\n{\n    /* Check arguments are valid. */\n    PJ_ASSERT_RETURN(pool && neg && remote, PJ_EINVAL);\n\n    /* Can only do this in STATE_LOCAL_OFFER.\n     * If we haven't provided local offer, then rx_remote_offer() should\n     * be called instead of this function.\n     */\n    PJ_ASSERT_RETURN(neg->state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, \n\t\t     PJMEDIA_SDPNEG_EINSTATE);\n\n    /* We're ready to negotiate. */\n    neg->state = PJMEDIA_SDP_NEG_STATE_WAIT_NEGO;\n    neg->has_remote_answer = PJ_TRUE;\n    neg->neg_remote_sdp = pjmedia_sdp_session_clone(pool, remote);\n \n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_set_remote_offer( pj_pool_t *pool,\n\t\t\t\t  pjmedia_sdp_neg *neg,\n\t\t\t\t  const pjmedia_sdp_session *remote)\n{\n    /* Check arguments are valid. */\n    PJ_ASSERT_RETURN(pool && neg && remote, PJ_EINVAL);\n\n    /* Can only do this in STATE_DONE.\n     * If we already provide local offer, then rx_remote_answer() should\n     * be called instead of this function.\n     */\n    PJ_ASSERT_RETURN(neg->state == PJMEDIA_SDP_NEG_STATE_DONE, \n\t\t     PJMEDIA_SDPNEG_EINSTATE);\n\n    /* State now is STATE_REMOTE_OFFER. */\n    neg->state = PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER;\n    neg->neg_remote_sdp = pjmedia_sdp_session_clone(pool, remote);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_set_local_answer( pj_pool_t *pool,\n\t\t\t\t  pjmedia_sdp_neg *neg,\n\t\t\t\t  const pjmedia_sdp_session *local)\n{\n    /* Check arguments are valid. */\n    PJ_ASSERT_RETURN(pool && neg && local, PJ_EINVAL);\n\n    /* Can only do this in STATE_REMOTE_OFFER.\n     * If we already provide local offer, then rx_remote_answer() should\n     * be called instead of this function.\n     */\n    PJ_ASSERT_RETURN(neg->state == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER, \n\t\t     PJMEDIA_SDPNEG_EINSTATE);\n\n    /* State now is STATE_WAIT_NEGO. */\n    neg->state = PJMEDIA_SDP_NEG_STATE_WAIT_NEGO;\n    if (local) {\n\tneg->neg_local_sdp = pjmedia_sdp_session_clone(pool, local);\n\tif (neg->initial_sdp) {\n\t    /* Retain initial_sdp value. */\n\t    neg->initial_sdp_tmp = neg->initial_sdp;\n\t    neg->initial_sdp = pjmedia_sdp_session_clone(pool,\n\t\t\t\t\t\t\t neg->initial_sdp);\n        \n\t    /* I don't think there is anything in RFC 3264 that mandates\n\t     * answerer to place the same origin (and increment version)\n\t     * in the answer, but probably it won't hurt either.\n\t     * Note that the version will be incremented in \n\t     * pjmedia_sdp_neg_negotiate()\n\t     */\n\t    neg->neg_local_sdp->origin.id = neg->initial_sdp->origin.id;\n\t} else {\n\t    neg->initial_sdp = pjmedia_sdp_session_clone(pool, local);\n\t}\n    } else {\n\tPJ_ASSERT_RETURN(neg->initial_sdp, PJMEDIA_SDPNEG_ENOINITIAL);\n\tneg->initial_sdp_tmp = neg->initial_sdp;\n\tneg->initial_sdp = pjmedia_sdp_session_clone(pool, neg->initial_sdp);\n\tneg->neg_local_sdp = pjmedia_sdp_session_clone(pool, neg->initial_sdp);\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_bool_t) pjmedia_sdp_neg_has_local_answer(pjmedia_sdp_neg *neg)\n{\n    pj_assert(neg && neg->state==PJMEDIA_SDP_NEG_STATE_WAIT_NEGO);\n    return !neg->has_remote_answer;\n}\n\n\n/* Swap string. */\nstatic void str_swap(pj_str_t *str1, pj_str_t *str2)\n{\n    pj_str_t tmp = *str1;\n    *str1 = *str2;\n    *str2 = tmp;\n}\n\nstatic void remove_all_media_directions(pjmedia_sdp_media *m)\n{\n    pjmedia_sdp_media_remove_all_attr(m, \"inactive\");\n    pjmedia_sdp_media_remove_all_attr(m, \"sendrecv\");\n    pjmedia_sdp_media_remove_all_attr(m, \"sendonly\");\n    pjmedia_sdp_media_remove_all_attr(m, \"recvonly\");\n}\n\n/* Update media direction based on peer's media direction */\nstatic void update_media_direction(pj_pool_t *pool,\n\t\t\t\t   const pjmedia_sdp_media *remote,\n\t\t\t\t   pjmedia_sdp_media *local)\n{\n    pjmedia_dir old_dir = PJMEDIA_DIR_ENCODING_DECODING,\n\t        new_dir;\n\n    /* Get the media direction of local SDP */\n    if (pjmedia_sdp_media_find_attr2(local, \"sendonly\", NULL))\n\told_dir = PJMEDIA_DIR_ENCODING;\n    else if (pjmedia_sdp_media_find_attr2(local, \"recvonly\", NULL))\n\told_dir = PJMEDIA_DIR_DECODING;\n    else if (pjmedia_sdp_media_find_attr2(local, \"inactive\", NULL))\n\told_dir = PJMEDIA_DIR_NONE;\n\n    new_dir = old_dir;\n\n    /* Adjust local media direction based on remote media direction */\n    if (pjmedia_sdp_media_find_attr2(remote, \"inactive\", NULL) != NULL) {\n\t/* If remote has \"a=inactive\", then local is inactive too */\n\n\tnew_dir = PJMEDIA_DIR_NONE;\n\n    } else if(pjmedia_sdp_media_find_attr2(remote, \"sendonly\", NULL) != NULL) {\n\t/* If remote has \"a=sendonly\", then set local to \"recvonly\" if\n\t * it is currently \"sendrecv\". Otherwise if local is NOT \"recvonly\",\n\t * then set local direction to \"inactive\".\n\t */\n\tswitch (old_dir) {\n\tcase PJMEDIA_DIR_ENCODING_DECODING:\n\t    new_dir = PJMEDIA_DIR_DECODING;\n\t    break;\n\tcase PJMEDIA_DIR_DECODING:\n\t    /* No change */\n\t    break;\n\tdefault:\n\t    new_dir = PJMEDIA_DIR_NONE;\n\t    break;\n\t}\n\n    } else if(pjmedia_sdp_media_find_attr2(remote, \"recvonly\", NULL) != NULL) {\n\t/* If remote has \"a=recvonly\", then set local to \"sendonly\" if\n\t * it is currently \"sendrecv\". Otherwise if local is NOT \"sendonly\",\n\t * then set local direction to \"inactive\"\n\t */\n    \n\tswitch (old_dir) {\n\tcase PJMEDIA_DIR_ENCODING_DECODING:\n\t    new_dir = PJMEDIA_DIR_ENCODING;\n\t    break;\n\tcase PJMEDIA_DIR_ENCODING:\n\t    /* No change */\n\t    break;\n\tdefault:\n\t    new_dir = PJMEDIA_DIR_NONE;\n\t    break;\n\t}\n\n    } else {\n\t/* Remote indicates \"sendrecv\" capability. No change to local \n\t * direction \n\t */\n    }\n\n    if (new_dir != old_dir) {\n\tpjmedia_sdp_attr *a = NULL;\n\n\tremove_all_media_directions(local);\n\n\tswitch (new_dir) {\n\tcase PJMEDIA_DIR_NONE:\n\t    a = pjmedia_sdp_attr_create(pool, \"inactive\", NULL);\n\t    break;\n\tcase PJMEDIA_DIR_ENCODING:\n\t    a = pjmedia_sdp_attr_create(pool, \"sendonly\", NULL);\n\t    break;\n\tcase PJMEDIA_DIR_DECODING:\n\t    a = pjmedia_sdp_attr_create(pool, \"recvonly\", NULL);\n\t    break;\n\tdefault:\n\t    /* sendrecv */\n\t    break;\n\t}\n\t\n\tif (a) {\n\t    pjmedia_sdp_media_add_attr(local, a);\n\t}\n    }\n}\n\n\n/* Update single local media description to after receiving answer\n * from remote.\n */\nstatic pj_status_t process_m_answer( pj_pool_t *pool,\n\t\t\t\t     pjmedia_sdp_media *offer,\n\t\t\t\t     pjmedia_sdp_media *answer,\n\t\t\t\t     pj_bool_t allow_asym)\n{\n    unsigned i;\n\n    /* Check that the media type match our offer. */\n\n    if (pj_strcmp(&answer->desc.media, &offer->desc.media)!=0) {\n\t/* The media type in the answer is different than the offer! */\n\treturn PJMEDIA_SDPNEG_EINVANSMEDIA;\n    }\n\n\n    /* Check that transport in the answer match our offer. */\n\n    /* At this point, transport type must be compatible, \n     * the transport instance will do more validation later.\n     */\n    if (pjmedia_sdp_transport_cmp(&answer->desc.transport, \n\t\t\t\t  &offer->desc.transport) \n\t!= PJ_SUCCESS)\n    {\n\treturn PJMEDIA_SDPNEG_EINVANSTP;\n    }\n\n\n    /* Check if remote has rejected our offer */\n    if (answer->desc.port == 0) {\n\t\n\t/* Remote has rejected our offer. \n\t * Deactivate our media too.\n\t */\n\tpjmedia_sdp_media_deactivate(pool, offer);\n\n\t/* Don't need to proceed */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Ticket #1148: check if remote answer does not set port to zero when\n     * offered with port zero. Let's just tolerate it.\n     */\n    if (offer->desc.port == 0) {\n\t/* Don't need to proceed */\n\treturn PJ_SUCCESS;\n    }\n\n    /* No need to update the direction when processing an answer */\n\n    /* If asymetric media is allowed, then just check that remote answer has \n     * codecs that are within the offer. \n     *\n     * Otherwise if asymetric media is not allowed, then we will choose only\n     * one codec in our initial offer to match the answer.\n     */\n    if (allow_asym) {\n\tfor (i=0; i<answer->desc.fmt_count; ++i) {\n\t    unsigned j;\n\t    pj_str_t *rem_fmt = &answer->desc.fmt[i];\n\n\t    for (j=0; j<offer->desc.fmt_count; ++j) {\n\t\tif (pj_strcmp(rem_fmt, &answer->desc.fmt[j])==0)\n\t\t    break;\n\t    }\n\n\t    if (j != offer->desc.fmt_count) {\n\t\t/* Found at least one common codec. */\n\t\tbreak;\n\t    }\n\t}\n\n\tif (i == answer->desc.fmt_count) {\n\t    /* No common codec in the answer! */\n\t    return PJMEDIA_SDPNEG_EANSNOMEDIA;\n\t}\n\n\tPJ_TODO(CHECK_SDP_NEGOTIATION_WHEN_ASYMETRIC_MEDIA_IS_ALLOWED);\n\n    } else {\n\t/* Offer format priority based on answer format index/priority */\n\tunsigned offer_fmt_prior[PJMEDIA_MAX_SDP_FMT];\n\n\t/* Remove all format in the offer that has no matching answer */\n\tfor (i=0; i<offer->desc.fmt_count;) {\n\t    unsigned pt;\n\t    pj_uint32_t j;\n\t    pj_str_t *fmt = &offer->desc.fmt[i];\n\t    \n\n\t    /* Find matching answer */\n\t    pt = pj_strtoul(fmt);\n\n\t    if (pt < 96) {\n\t\tfor (j=0; j<answer->desc.fmt_count; ++j) {\n\t\t    if (pj_strcmp(fmt, &answer->desc.fmt[j])==0)\n\t\t\tbreak;\n\t\t}\n\t    } else {\n\t\t/* This is dynamic payload type.\n\t\t * For dynamic payload type, we must look the rtpmap and\n\t\t * compare the encoding name.\n\t\t */\n\t\tconst pjmedia_sdp_attr *a;\n\t\tpjmedia_sdp_rtpmap or_;\n\n\t\t/* Get the rtpmap for the payload type in the offer. */\n\t\ta = pjmedia_sdp_media_find_attr2(offer, \"rtpmap\", fmt);\n\t\tif (!a) {\n\t\t    pj_assert(!\"Bug! Offer should have been validated\");\n\t\t    return PJ_EBUG;\n\t\t}\n\t\tpjmedia_sdp_attr_get_rtpmap(a, &or_);\n\n\t\t/* Find paylaod in answer SDP with matching \n\t\t * encoding name and clock rate.\n\t\t */\n\t\tfor (j=0; j<answer->desc.fmt_count; ++j) {\n\t\t    a = pjmedia_sdp_media_find_attr2(answer, \"rtpmap\", \n\t\t\t\t\t\t     &answer->desc.fmt[j]);\n\t\t    if (a) {\n\t\t\tpjmedia_sdp_rtpmap ar;\n\t\t\tpjmedia_sdp_attr_get_rtpmap(a, &ar);\n\n\t\t\t/* See if encoding name, clock rate, and channel\n\t\t\t * count match \n\t\t\t */\n\t\t\tif (!pj_stricmp(&or_.enc_name, &ar.enc_name) &&\n\t\t\t    or_.clock_rate == ar.clock_rate &&\n\t\t\t    (pj_stricmp(&or_.param, &ar.param)==0 ||\n\t\t\t     (ar.param.slen==1 && *ar.param.ptr=='1')))\n\t\t\t{\n\t\t\t    /* Call custom format matching callbacks */\n\t\t\t    if (custom_fmt_match(pool, &or_.enc_name,\n\t\t\t\t\t\t offer, i, answer, j, 0) ==\n\t\t\t\tPJ_SUCCESS)\n\t\t\t    {\n\t\t\t\t/* Match! */\n\t\t\t\tbreak;\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\n\t    if (j == answer->desc.fmt_count) {\n\t\t/* This format has no matching answer.\n\t\t * Remove it from our offer.\n\t\t */\n\t\tpjmedia_sdp_attr *a;\n\n\t\t/* Remove rtpmap associated with this format */\n\t\ta = pjmedia_sdp_media_find_attr2(offer, \"rtpmap\", fmt);\n\t\tif (a)\n\t\t    pjmedia_sdp_media_remove_attr(offer, a);\n\n\t\t/* Remove fmtp associated with this format */\n\t\ta = pjmedia_sdp_media_find_attr2(offer, \"fmtp\", fmt);\n\t\tif (a)\n\t\t    pjmedia_sdp_media_remove_attr(offer, a);\n\n\t\t/* Remove this format from offer's array */\n\t\tpj_array_erase(offer->desc.fmt, sizeof(offer->desc.fmt[0]),\n\t\t\t       offer->desc.fmt_count, i);\n\t\t--offer->desc.fmt_count;\n\n\t    } else {\n\t\toffer_fmt_prior[i] = j;\n\t\t++i;\n\t    }\n\t}\n\n\tif (0 == offer->desc.fmt_count) {\n\t    /* No common codec in the answer! */\n\t    return PJMEDIA_SDPNEG_EANSNOMEDIA;\n\t}\n\n\t/* Post process:\n\t * - Resort offer formats so the order match to the answer.\n\t * - Remove answer formats that unmatches to the offer.\n\t */\n\t\n\t/* Resort offer formats */\n\tfor (i=0; i<offer->desc.fmt_count; ++i) {\n\t    unsigned j;\n\t    for (j=i+1; j<offer->desc.fmt_count; ++j) {\n\t\tif (offer_fmt_prior[i] > offer_fmt_prior[j]) {\n\t\t    unsigned tmp = offer_fmt_prior[i];\n\t\t    offer_fmt_prior[i] = offer_fmt_prior[j];\n\t\t    offer_fmt_prior[j] = tmp;\n\t\t    str_swap(&offer->desc.fmt[i], &offer->desc.fmt[j]);\n\t\t}\n\t    }\n\t}\n\n\t/* Remove unmatched answer formats */\n\t{\n\t    unsigned del_cnt = 0;\n\t    for (i=0; i<answer->desc.fmt_count;) {\n\t\t/* The offer is ordered now, also the offer_fmt_prior */\n\t\tif (i >= offer->desc.fmt_count || \n\t\t    offer_fmt_prior[i]-del_cnt != i)\n\t\t{\n\t\t    pj_str_t *fmt = &answer->desc.fmt[i];\n\t\t    pjmedia_sdp_attr *a;\n\n\t\t    /* Remove rtpmap associated with this format */\n\t\t    a = pjmedia_sdp_media_find_attr2(answer, \"rtpmap\", fmt);\n\t\t    if (a)\n\t\t\tpjmedia_sdp_media_remove_attr(answer, a);\n\n\t\t    /* Remove fmtp associated with this format */\n\t\t    a = pjmedia_sdp_media_find_attr2(answer, \"fmtp\", fmt);\n\t\t    if (a)\n\t\t\tpjmedia_sdp_media_remove_attr(answer, a);\n\n\t\t    /* Remove this format from answer's array */\n\t\t    pj_array_erase(answer->desc.fmt, \n\t\t\t\t   sizeof(answer->desc.fmt[0]),\n\t\t\t\t   answer->desc.fmt_count, i);\n\t\t    --answer->desc.fmt_count;\n\n\t\t    ++del_cnt;\n\t\t} else {\n\t\t    ++i;\n\t\t}\n\t    }\n\t}\n    }\n\n    /* Looks okay */\n    return PJ_SUCCESS;\n}\n\n\n/* Update local media session (offer) to create active local session\n * after receiving remote answer.\n */\nstatic pj_status_t process_answer(pj_pool_t *pool,\n\t\t\t\t  pjmedia_sdp_session *offer,\n\t\t\t\t  pjmedia_sdp_session *answer,\n\t\t\t\t  pj_bool_t allow_asym,\n\t\t\t\t  pjmedia_sdp_session **p_active)\n{\n    unsigned omi = 0; /* Offer media index */\n    unsigned ami = 0; /* Answer media index */\n    pj_bool_t has_active = PJ_FALSE;\n    pj_status_t status;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(pool && offer && answer && p_active, PJ_EINVAL);\n\n    /* Check that media count match between offer and answer */\n    // Ticket #527, different media count is allowed for more interoperability,\n    // however, the media order must be same between offer and answer.\n    // if (offer->media_count != answer->media_count)\n    //\t   return PJMEDIA_SDPNEG_EMISMEDIA;\n\n    /* Now update each media line in the offer with the answer. */\n    for (; omi<offer->media_count; ++omi) {\n\tif (ami == answer->media_count) {\n\t    /* The answer has less media than the offer */\n\t    pjmedia_sdp_media *am;\n\n\t    /* Generate matching-but-disabled-media for the answer */\n\t    am = sdp_media_clone_deactivate(pool, offer->media[omi],\n\t                                    offer->media[omi], offer);\n\t    answer->media[answer->media_count++] = am;\n\t    ++ami;\n\n\t    /* Deactivate our media offer too */\n\t    pjmedia_sdp_media_deactivate(pool, offer->media[omi]);\n\n\t    /* No answer media to be negotiated */\n\t    continue;\n\t}\n\n\tstatus = process_m_answer(pool, offer->media[omi], answer->media[ami],\n\t\t\t\t  allow_asym);\n\n\t/* If media type is mismatched, just disable the media. */\n\tif (status == PJMEDIA_SDPNEG_EINVANSMEDIA) {\n\t    pjmedia_sdp_media_deactivate(pool, offer->media[omi]);\n\t    continue;\n\t}\n\t/* No common format in the answer media. */\n\telse if (status == PJMEDIA_SDPNEG_EANSNOMEDIA) {\n\t    pjmedia_sdp_media_deactivate(pool, offer->media[omi]);\n\t    pjmedia_sdp_media_deactivate(pool, answer->media[ami]);\n\t} \n\t/* Return the error code, for other errors. */\n\telse if (status != PJ_SUCCESS) {\n\t    return status;\n\t}\n\n\tif (offer->media[omi]->desc.port != 0)\n\t    has_active = PJ_TRUE;\n\n\t++ami;\n    }\n\n    *p_active = offer;\n\n    return has_active ? PJ_SUCCESS : PJMEDIA_SDPNEG_ENOMEDIA;\n}\n\n\n/* Internal function to rewrite the format string in SDP attribute rtpmap\n * and fmtp.\n */\nPJ_INLINE(void) rewrite_pt(pj_pool_t *pool, pj_str_t *attr_val,\n\t\t\t   const pj_str_t *old_pt, const pj_str_t *new_pt)\n{\n    int len_diff = (int)(new_pt->slen - old_pt->slen);\n\n    /* Note that attribute value should be null-terminated. */\n    if (len_diff > 0) {\n\tpj_str_t new_val;\n\tnew_val.ptr = (char*)pj_pool_alloc(pool, attr_val->slen+len_diff+1);\n\tnew_val.slen = attr_val->slen + len_diff;\n\tpj_memcpy(new_val.ptr + len_diff, attr_val->ptr, attr_val->slen + 1);\n\t*attr_val = new_val;\n    } else if (len_diff < 0) {\n\tattr_val->slen += len_diff;\n\tpj_memmove(attr_val->ptr, attr_val->ptr - len_diff,\n\t\t   attr_val->slen + 1);\n    }\n    pj_memcpy(attr_val->ptr, new_pt->ptr, new_pt->slen);\n}\n\n\n/* Internal function to apply symmetric PT for the local answer. */\nstatic void apply_answer_symmetric_pt(pj_pool_t *pool,\n\t\t\t\t      pjmedia_sdp_media *answer,\n\t\t\t\t      unsigned pt_cnt,\n\t\t\t\t      const pj_str_t pt_offer[],\n\t\t\t\t      const pj_str_t pt_answer[])\n{\n    pjmedia_sdp_attr *a_tmp[PJMEDIA_MAX_SDP_ATTR];\n    unsigned i, a_tmp_cnt = 0;\n\n    /* Rewrite the payload types in the answer if different to\n     * the ones in the offer.\n     */\n    for (i = 0; i < pt_cnt; ++i) {\n\tpjmedia_sdp_attr *a;\n\n\t/* Skip if the PTs are the same already, e.g: static PT. */\n\tif (pj_strcmp(&pt_answer[i], &pt_offer[i]) == 0)\n\t    continue;\n\n\t/* Rewrite payload type in the answer to match to the offer */\n\tpj_strdup(pool, &answer->desc.fmt[i], &pt_offer[i]);\n\n\t/* Also update payload type in rtpmap */\n\ta = pjmedia_sdp_media_find_attr2(answer, \"rtpmap\", &pt_answer[i]);\n\tif (a) {\n\t    rewrite_pt(pool, &a->value, &pt_answer[i], &pt_offer[i]);\n\t    /* Temporarily remove the attribute in case the new payload\n\t     * type is being used by another format in the media.\n\t     */\n\t    pjmedia_sdp_media_remove_attr(answer, a);\n\t    a_tmp[a_tmp_cnt++] = a;\n\t}\n\n\t/* Also update payload type in fmtp */\n\ta = pjmedia_sdp_media_find_attr2(answer, \"fmtp\", &pt_answer[i]);\n\tif (a) {\n\t    rewrite_pt(pool, &a->value, &pt_answer[i], &pt_offer[i]);\n\t    /* Temporarily remove the attribute in case the new payload\n\t     * type is being used by another format in the media.\n\t     */\n\t    pjmedia_sdp_media_remove_attr(answer, a);\n\t    a_tmp[a_tmp_cnt++] = a;\n\t}\n    }\n\n    /* Return back 'rtpmap' and 'fmtp' attributes */\n    for (i = 0; i < a_tmp_cnt; ++i)\n\tpjmedia_sdp_media_add_attr(answer, a_tmp[i]);\n}\n\n\n/* Try to match offer with answer. */\nstatic pj_status_t match_offer(pj_pool_t *pool,\n\t\t\t       pj_bool_t prefer_remote_codec_order,\n                               pj_bool_t answer_with_multiple_codecs,\n\t\t\t       const pjmedia_sdp_media *offer,\n\t\t\t       const pjmedia_sdp_media *preanswer,\n\t\t\t       const pjmedia_sdp_session *preanswer_sdp,\n\t\t\t       pjmedia_sdp_media **p_answer)\n{\n    unsigned i;\n    pj_bool_t master_has_codec = 0,\n\t      master_has_other = 0,\n\t      found_matching_codec = 0,\n\t      found_matching_telephone_event = 0,\n\t      found_matching_other = 0;\n    unsigned pt_answer_count = 0;\n    pj_str_t pt_answer[PJMEDIA_MAX_SDP_FMT];\n    pj_str_t pt_offer[PJMEDIA_MAX_SDP_FMT];\n    pjmedia_sdp_media *answer;\n    const pjmedia_sdp_media *master, *slave;\n\n    /* If offer has zero port, just clone the offer */\n    if (offer->desc.port == 0) {\n\tanswer = sdp_media_clone_deactivate(pool, offer, preanswer,\n\t\t\t\t\t    preanswer_sdp);\n\t*p_answer = answer;\n\treturn PJ_SUCCESS;\n    }\n\n    /* If the preanswer define zero port, this media is being rejected,\n     * just clone the preanswer.\n     */\n    if (preanswer->desc.port == 0) {\n\tanswer = pjmedia_sdp_media_clone(pool, preanswer);\n\t*p_answer = answer;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Set master/slave negotiator based on prefer_remote_codec_order. */\n    if (prefer_remote_codec_order) {\n\tmaster = offer;\n\tslave  = preanswer;\n    } else {\n\tmaster = preanswer;\n\tslave  = offer;\n    }\n    \n    /* With the addition of telephone-event and dodgy MS RTC SDP, \n     * the answer generation algorithm looks really shitty...\n     */\n    for (i=0; i<master->desc.fmt_count; ++i) {\n\tunsigned j;\n\t\n\tif (pj_isdigit(*master->desc.fmt[i].ptr)) {\n\t    /* This is normal/standard payload type, where it's identified\n\t     * by payload number.\n\t     */\n\t    unsigned pt;\n\n\t    pt = pj_strtoul(&master->desc.fmt[i]);\n\t    \n\t    if (pt < 96) {\n\t\t/* For static payload type, it's enough to compare just\n\t\t * the payload number.\n\t\t */\n\n\t\tmaster_has_codec = 1;\n\n\t\t/* We just need to select one codec if not allowing multiple.\n\t\t * Continue if we have selected matching codec for previous \n\t\t * payload.\n\t\t */\n\t\tif (!answer_with_multiple_codecs && found_matching_codec)\n\t\t    continue;\n\n\t\t/* Find matching codec in local descriptor. */\n\t\tfor (j=0; j<slave->desc.fmt_count; ++j) {\n\t\t    unsigned p;\n\t\t    p = pj_strtoul(&slave->desc.fmt[j]);\n\t\t    if (p == pt && pj_isdigit(*slave->desc.fmt[j].ptr)) {\n\t\t\tfound_matching_codec = 1;\n\t\t\tpt_offer[pt_answer_count] = slave->desc.fmt[j];\n\t\t\tpt_answer[pt_answer_count++] = slave->desc.fmt[j];\n\t\t\tbreak;\n\t\t    }\n\t\t}\n\n\t    } else {\n\t\t/* This is dynamic payload type.\n\t\t * For dynamic payload type, we must look the rtpmap and\n\t\t * compare the encoding name.\n\t\t */\n\t\tconst pjmedia_sdp_attr *a;\n\t\tpjmedia_sdp_rtpmap or_;\n\t\tpj_bool_t is_codec;\n\n\t\t/* Get the rtpmap for the payload type in the master. */\n\t\ta = pjmedia_sdp_media_find_attr2(master, \"rtpmap\", \n\t\t\t\t\t\t &master->desc.fmt[i]);\n\t\tif (!a) {\n\t\t    pj_assert(!\"Bug! Offer should have been validated\");\n\t\t    return PJMEDIA_SDP_EMISSINGRTPMAP;\n\t\t}\n\t\tpjmedia_sdp_attr_get_rtpmap(a, &or_);\n\n\t\tif (!pj_stricmp2(&or_.enc_name, \"telephone-event\")) {\n\t\t    if (found_matching_telephone_event)\n\t\t\tcontinue;\n\t\t    is_codec = 0;\n\t\t} else {\n\t\t    master_has_codec = 1;\n\t\t    if (!answer_with_multiple_codecs && found_matching_codec)\n\t\t\tcontinue;\n\t\t    is_codec = 1;\n\t\t}\n\t\t\n\t\t/* Find paylaod in our initial SDP with matching \n\t\t * encoding name and clock rate.\n\t\t */\n\t\tfor (j=0; j<slave->desc.fmt_count; ++j) {\n\t\t    a = pjmedia_sdp_media_find_attr2(slave, \"rtpmap\", \n\t\t\t\t\t\t     &slave->desc.fmt[j]);\n\t\t    if (a) {\n\t\t\tpjmedia_sdp_rtpmap lr;\n\t\t\tpjmedia_sdp_attr_get_rtpmap(a, &lr);\n\n\t\t\t/* See if encoding name, clock rate, and\n\t\t\t * channel count  match \n\t\t\t */\n\t\t\tif (!pj_stricmp(&or_.enc_name, &lr.enc_name) &&\n\t\t\t    or_.clock_rate == lr.clock_rate &&\n\t\t\t    (pj_stricmp(&or_.param, &lr.param)==0 ||\n\t\t\t     (lr.param.slen==0 && or_.param.slen==1 && \n\t\t\t\t\t\t *or_.param.ptr=='1') || \n\t\t\t     (or_.param.slen==0 && lr.param.slen==1 && \n\t\t\t\t\t\t  *lr.param.ptr=='1'))) \n\t\t\t{\n\t\t\t    /* Match! */\n\t\t\t    if (is_codec) {\n\t\t\t\tpjmedia_sdp_media *o_med, *a_med;\n\t\t\t\tunsigned o_fmt_idx, a_fmt_idx;\n\n\t\t\t\to_med = (pjmedia_sdp_media*)offer;\n\t\t\t\ta_med = (pjmedia_sdp_media*)preanswer;\n\t\t\t\to_fmt_idx = prefer_remote_codec_order? i:j;\n\t\t\t\ta_fmt_idx = prefer_remote_codec_order? j:i;\n\n\t\t\t\t/* Call custom format matching callbacks */\n\t\t\t\tif (custom_fmt_match(pool, &or_.enc_name,\n\t\t\t\t\t\t     o_med, o_fmt_idx,\n\t\t\t\t\t\t     a_med, a_fmt_idx,\n\t\t\t\t\t\t     ALLOW_MODIFY_ANSWER) !=\n\t\t\t\t    PJ_SUCCESS)\n\t\t\t\t{\n\t\t\t\t    continue;\n\t\t\t\t}\n\t\t\t\tfound_matching_codec = 1;\n\t\t\t    } else {\n\t\t\t\tfound_matching_telephone_event = 1;\n\t\t\t    }\n\n\t\t\t    pt_offer[pt_answer_count] = \n\t\t\t\t\t\tprefer_remote_codec_order?\n\t\t\t\t\t\toffer->desc.fmt[i]:\n\t\t\t\t\t\toffer->desc.fmt[j];\n\t\t\t    pt_answer[pt_answer_count++] = \n\t\t\t\t\t\tprefer_remote_codec_order? \n\t\t\t\t\t\tpreanswer->desc.fmt[j]:\n\t\t\t\t\t\tpreanswer->desc.fmt[i];\n\t\t\t    break;\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\n\t} else {\n\t    /* This is a non-standard, brain damaged SDP where the payload\n\t     * type is non-numeric. It exists e.g. in Microsoft RTC based\n\t     * UA, to indicate instant messaging capability.\n\t     * Example:\n\t     *\t- m=x-ms-message 5060 sip null\n\t     */\n\t    master_has_other = 1;\n\t    if (found_matching_other)\n\t\tcontinue;\n\n\t    for (j=0; j<slave->desc.fmt_count; ++j) {\n\t\tif (!pj_strcmp(&master->desc.fmt[i], &slave->desc.fmt[j])) {\n\t\t    /* Match */\n\t\t    found_matching_other = 1;\n\t\t    pt_offer[pt_answer_count] = prefer_remote_codec_order?\n\t\t\t\t\t\toffer->desc.fmt[i]:\n\t\t\t\t\t\toffer->desc.fmt[j];\n\t\t    pt_answer[pt_answer_count++] = prefer_remote_codec_order? \n\t\t\t\t\t\t   preanswer->desc.fmt[j]:\n\t\t\t\t\t\t   preanswer->desc.fmt[i];\n\t\t    break;\n\t\t}\n\t    }\n\t}\n    }\n\n    /* See if all types of master can be matched. */\n    if (master_has_codec && !found_matching_codec) {\n\treturn PJMEDIA_SDPNEG_NOANSCODEC;\n    }\n\n    /* If this comment is removed, negotiation will fail if remote has offered\n       telephone-event and local is not configured with telephone-event\n\n    if (offer_has_telephone_event && !found_matching_telephone_event) {\n\treturn PJMEDIA_SDPNEG_NOANSTELEVENT;\n    }\n    */\n\n    if (master_has_other && !found_matching_other) {\n\treturn PJMEDIA_SDPNEG_NOANSUNKNOWN;\n    }\n\n    /* Seems like everything is in order.\n     * Build the answer by cloning from preanswer, but rearrange the payload\n     * to suit the offer.\n     */\n    answer = pjmedia_sdp_media_clone(pool, preanswer);\n    for (i=0; i<pt_answer_count; ++i) {\n\tunsigned j;\n\tfor (j=i; j<answer->desc.fmt_count; ++j) {\n\t    if (!pj_strcmp(&answer->desc.fmt[j], &pt_answer[i]))\n\t\tbreak;\n\t}\n\tpj_assert(j != answer->desc.fmt_count);\n\tstr_swap(&answer->desc.fmt[i], &answer->desc.fmt[j]);\n    }\n    \n    /* Remove unwanted local formats. */\n    for (i=pt_answer_count; i<answer->desc.fmt_count; ++i) {\n\tpjmedia_sdp_attr *a;\n\n\t/* Remove rtpmap for this format */\n\ta = pjmedia_sdp_media_find_attr2(answer, \"rtpmap\", \n\t\t\t\t\t &answer->desc.fmt[i]);\n\tif (a) {\n\t    pjmedia_sdp_media_remove_attr(answer, a);\n\t}\n\n\t/* Remove fmtp for this format */\n\ta = pjmedia_sdp_media_find_attr2(answer, \"fmtp\", \n\t\t\t\t\t &answer->desc.fmt[i]);\n\tif (a) {\n\t    pjmedia_sdp_media_remove_attr(answer, a);\n\t}\n    }\n    answer->desc.fmt_count = pt_answer_count;\n\n#if PJMEDIA_SDP_NEG_ANSWER_SYMMETRIC_PT\n    apply_answer_symmetric_pt(pool, answer, pt_answer_count,\n\t\t\t      pt_offer, pt_answer);\n#endif\n\n    /* Update media direction. */\n    update_media_direction(pool, offer, answer);\n\n    *p_answer = answer;\n    return PJ_SUCCESS;\n}\n\n/* Create complete answer for remote's offer. */\nstatic pj_status_t create_answer( pj_pool_t *pool,\n\t\t\t\t  pj_bool_t prefer_remote_codec_order,\n                                  pj_bool_t answer_with_multiple_codecs,\n\t\t\t\t  const pjmedia_sdp_session *initial,\n\t\t\t\t  const pjmedia_sdp_session *offer,\n\t\t\t\t  pjmedia_sdp_session **p_answer)\n{\n    pj_status_t status = PJMEDIA_SDPNEG_ENOMEDIA;\n    pj_bool_t has_active = PJ_FALSE;\n    pjmedia_sdp_session *answer;\n    char media_used[PJMEDIA_MAX_SDP_MEDIA];\n    unsigned i;\n\n    /* Validate remote offer. \n     * This should have been validated before.\n     */\n    PJ_ASSERT_RETURN((status=pjmedia_sdp_validate(offer))==PJ_SUCCESS, status);\n\n    /* Create initial answer by duplicating initial SDP,\n     * but clear all media lines. The media lines will be filled up later.\n     */\n    answer = pjmedia_sdp_session_clone(pool, initial);\n    PJ_ASSERT_RETURN(answer != NULL, PJ_ENOMEM);\n\n    answer->media_count = 0;\n\n    pj_bzero(media_used, sizeof(media_used));\n\n    /* For each media line, create our answer based on our initial\n     * capability.\n     */\n    for (i=0; i<offer->media_count; ++i) {\n\tconst pjmedia_sdp_media *om;\t/* offer */\n\tconst pjmedia_sdp_media *im;\t/* initial media */\n\tpjmedia_sdp_media *am = NULL;\t/* answer/result */\n\tunsigned j;\n\n\tom = offer->media[i];\n\n\t/* Find media description in our initial capability that matches\n\t * the media type and transport type of offer's media, has\n\t * matching codec, and has not been used to answer other offer.\n\t */\n\tfor (im=NULL, j=0; j<initial->media_count; ++j) {\n\t    im = initial->media[j];\n\t    if (pj_strcmp(&om->desc.media, &im->desc.media)==0 &&\n\t\tpj_strcmp(&om->desc.transport, &im->desc.transport)==0 &&\n\t\tmedia_used[j] == 0)\n\t    {\n                pj_status_t status2;\n\n\t\t/* See if it has matching codec. */\n\t\tstatus2 = match_offer(pool, prefer_remote_codec_order,\n                                      answer_with_multiple_codecs,\n\t\t\t\t      om, im, initial, &am);\n\t\tif (status2 == PJ_SUCCESS) {\n\t\t    /* Mark media as used. */\n\t\t    media_used[j] = 1;\n\t\t    break;\n                } else {\n                    status = status2;\n                }\n\t    }\n\t}\n\n\tif (j==initial->media_count) {\n\t    /* No matching media.\n\t     * Reject the offer by setting the port to zero in the answer.\n\t     */\n\t    /* For simplicity in the construction of the answer, we'll\n\t     * just clone the media from the offer. Anyway receiver will\n\t     * ignore anything in the media once it sees that the port\n\t     * number is zero.\n\t     */\n\t    am = sdp_media_clone_deactivate(pool, om, om, answer);\n\t} else {\n\t    /* The answer is in am */\n\t    pj_assert(am != NULL);\n\t}\n\n\t/* Add the media answer */\n\tanswer->media[answer->media_count++] = am;\n\n\t/* Check if this media is active.*/\n\tif (am->desc.port != 0)\n\t    has_active = PJ_TRUE;\n    }\n\n    *p_answer = answer;\n\n    return has_active ? PJ_SUCCESS : status;\n}\n\n/* Cancel offer */\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_cancel_offer(pjmedia_sdp_neg *neg)\n{\n    PJ_ASSERT_RETURN(neg, PJ_EINVAL);\n\n    /* Must be in LOCAL_OFFER state. */\n    PJ_ASSERT_RETURN(neg->state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER ||\n\t\t     neg->state == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER,\n\t\t     PJMEDIA_SDPNEG_EINSTATE);\n\n    if (neg->state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER &&\n\tneg->active_local_sdp) \n    {\n\t/* Increment next version number. This happens if for example\n\t * the reinvite offer is rejected by 488. If we don't increment\n\t * the version here, the next offer will have the same version.\n\t */\n\tneg->active_local_sdp->origin.version++;\n    }\n\n    /* Revert back initial SDP */\n    if (neg->state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER)\n\tneg->initial_sdp = neg->initial_sdp_tmp;\n\n    /* Clear temporary SDP */\n    neg->initial_sdp_tmp = NULL;\n    neg->neg_local_sdp = neg->neg_remote_sdp = NULL;\n    neg->has_remote_answer = PJ_FALSE;\n\n    /* Reset state to done */\n    neg->state = PJMEDIA_SDP_NEG_STATE_DONE;\n\n    return PJ_SUCCESS;\n}\n\n\n/* The best bit: SDP negotiation function! */\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool,\n\t\t\t\t\t       pjmedia_sdp_neg *neg,\n\t\t\t\t\t       pj_bool_t allow_asym)\n{\n    pj_status_t status;\n\n    /* Check arguments are valid. */\n    PJ_ASSERT_RETURN(pool && neg, PJ_EINVAL);\n\n    /* Must be in STATE_WAIT_NEGO state. */\n    PJ_ASSERT_RETURN(neg->state == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, \n\t\t     PJMEDIA_SDPNEG_EINSTATE);\n\n    /* Must have remote offer. */\n    PJ_ASSERT_RETURN(neg->neg_remote_sdp, PJ_EBUG);\n\n    if (neg->has_remote_answer) {\n\tpjmedia_sdp_session *active;\n\tstatus = process_answer(pool, neg->neg_local_sdp, neg->neg_remote_sdp,\n\t\t\t        allow_asym, &active);\n\tif (status == PJ_SUCCESS) {\n\t    /* Only update active SDPs when negotiation is successfull */\n\t    neg->active_local_sdp = active;\n\t    neg->active_remote_sdp = neg->neg_remote_sdp;\n\t}\n    } else {\n\tpjmedia_sdp_session *answer = NULL;\n\n\tstatus = create_answer(pool, neg->prefer_remote_codec_order,\n                               neg->answer_with_multiple_codecs,\n\t\t\t       neg->neg_local_sdp, neg->neg_remote_sdp,\n\t\t\t       &answer);\n\tif (status == PJ_SUCCESS) {\n\t    pj_uint32_t active_ver;\n\n\t    if (neg->active_local_sdp)\n\t\tactive_ver = neg->active_local_sdp->origin.version;\n\t    else\n\t\tactive_ver = neg->initial_sdp->origin.version;\n\n\t    /* Only update active SDPs when negotiation is successfull */\n\t    neg->active_local_sdp = answer;\n\t    neg->active_remote_sdp = neg->neg_remote_sdp;\n\n\t    /* Increment SDP version */\n\t    neg->active_local_sdp->origin.version = ++active_ver;\n\t}\n    }\n\n    /* State is DONE regardless */\n    neg->state = PJMEDIA_SDP_NEG_STATE_DONE;\n\n    /* Save state */\n    neg->answer_was_remote = neg->has_remote_answer;\n\n    /* Revert back initial SDP if nego fails */\n    if (status != PJ_SUCCESS)\n\tneg->initial_sdp = neg->initial_sdp_tmp;\n\n    /* Clear temporary SDP */\n    neg->initial_sdp_tmp = NULL;\n    neg->neg_local_sdp = neg->neg_remote_sdp = NULL;\n    neg->has_remote_answer = PJ_FALSE;\n\n    return status;\n}\n\n\nstatic pj_status_t custom_fmt_match(pj_pool_t *pool,\n\t\t\t\t    const pj_str_t *fmt_name,\n\t\t\t\t    pjmedia_sdp_media *offer,\n\t\t\t\t    unsigned o_fmt_idx,\n\t\t\t\t    pjmedia_sdp_media *answer,\n\t\t\t\t    unsigned a_fmt_idx,\n\t\t\t\t    unsigned option)\n{\n    unsigned i;\n\n    for (i = 0; i < fmt_match_cb_cnt; ++i) {\n\tif (pj_stricmp(fmt_name, &fmt_match_cb[i].fmt_name) == 0) {\n\t    pj_assert(fmt_match_cb[i].cb);\n\t    return (*fmt_match_cb[i].cb)(pool, offer, o_fmt_idx,\n\t\t\t\t\t answer, a_fmt_idx,\n\t\t\t\t\t option);\n\t}\n    }\n\n    /* Not customized format matching found, should be matched */\n    return PJ_SUCCESS;\n}\n\n/* Register customized SDP format negotiation callback function. */\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_register_fmt_match_cb(\n\t\t\t\t\tconst pj_str_t *fmt_name,\n\t\t\t\t\tpjmedia_sdp_neg_fmt_match_cb cb)\n{\n    struct fmt_match_cb_t *f = NULL;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(fmt_name, PJ_EINVAL);\n\n    /* Check if the callback for the format name has been registered */\n    for (i = 0; i < fmt_match_cb_cnt; ++i) {\n\tif (pj_stricmp(fmt_name, &fmt_match_cb[i].fmt_name) == 0)\n\t    break;\n    }\n\n    /* Unregistration */\n    \n    if (cb == NULL) {\n\tif (i == fmt_match_cb_cnt)\n\t    return PJ_ENOTFOUND;\n\n\tpj_array_erase(fmt_match_cb, sizeof(fmt_match_cb[0]),\n\t\t       fmt_match_cb_cnt, i);\n\tfmt_match_cb_cnt--;\n\n\treturn PJ_SUCCESS;\n    }\n\n    /* Registration */\n\n    if (i < fmt_match_cb_cnt) {\n\t/* The same format name has been registered before */\n\tif (cb != fmt_match_cb[i].cb)\n\t    return PJ_EEXISTS;\n\telse\n\t    return PJ_SUCCESS;\n    }\n\n    if (fmt_match_cb_cnt >= PJ_ARRAY_SIZE(fmt_match_cb))\n\treturn PJ_ETOOMANY;\n\n    f = &fmt_match_cb[fmt_match_cb_cnt++];\n    f->fmt_name = *fmt_name;\n    f->cb = cb;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Match format in the SDP media offer and answer. */\nPJ_DEF(pj_status_t) pjmedia_sdp_neg_fmt_match(pj_pool_t *pool,\n\t\t\t\t\t      pjmedia_sdp_media *offer,\n\t\t\t\t\t      unsigned o_fmt_idx,\n\t\t\t\t\t      pjmedia_sdp_media *answer,\n\t\t\t\t\t      unsigned a_fmt_idx,\n\t\t\t\t\t      unsigned option)\n{\n    const pjmedia_sdp_attr *attr;\n    pjmedia_sdp_rtpmap o_rtpmap, a_rtpmap;\n    unsigned o_pt;\n    unsigned a_pt;\n\n    o_pt = pj_strtoul(&offer->desc.fmt[o_fmt_idx]);\n    a_pt = pj_strtoul(&answer->desc.fmt[a_fmt_idx]);\n\n    if (o_pt < 96 || a_pt < 96) {\n\tif (o_pt == a_pt)\n\t    return PJ_SUCCESS;\n\telse\n\t    return PJMEDIA_SDP_EFORMATNOTEQUAL;\n    }\n\n    /* Get the format rtpmap from the offer. */\n    attr = pjmedia_sdp_media_find_attr2(offer, \"rtpmap\", \n\t\t\t\t\t&offer->desc.fmt[o_fmt_idx]);\n    if (!attr) {\n\tpj_assert(!\"Bug! Offer haven't been validated\");\n\treturn PJ_EBUG;\n    }\n    pjmedia_sdp_attr_get_rtpmap(attr, &o_rtpmap);\n\n    /* Get the format rtpmap from the answer. */\n    attr = pjmedia_sdp_media_find_attr2(answer, \"rtpmap\", \n\t\t\t\t\t&answer->desc.fmt[a_fmt_idx]);\n    if (!attr) {\n\tpj_assert(!\"Bug! Answer haven't been validated\");\n\treturn PJ_EBUG;\n    }\n    pjmedia_sdp_attr_get_rtpmap(attr, &a_rtpmap);\n\n    if (pj_stricmp(&o_rtpmap.enc_name, &a_rtpmap.enc_name) != 0 ||\n\t(o_rtpmap.clock_rate != a_rtpmap.clock_rate) ||\n\t(!(pj_stricmp(&o_rtpmap.param, &a_rtpmap.param) == 0 ||\n\t   (a_rtpmap.param.slen == 0 && o_rtpmap.param.slen == 1 &&\n\t    *o_rtpmap.param.ptr == '1') ||\n\t   (o_rtpmap.param.slen == 0 && a_rtpmap.param.slen == 1 &&\n\t    *a_rtpmap.param.ptr=='1'))))\n    {\n\treturn PJMEDIA_SDP_EFORMATNOTEQUAL;\n    }\n\n    return custom_fmt_match(pool, &o_rtpmap.enc_name,\n\t\t\t    offer, o_fmt_idx, answer, a_fmt_idx, option);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/sdp_wrap.cpp",
    "content": "/* $Id: sdp_wrap.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * This file is a C++ wrapper, see ticket #886 for details.\n */\n\n#include \"sdp.c\"\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/session.c",
    "content": "/* $Id: session.c 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/session.h>\n#include <pjmedia/errno.h>\n#include <pj/log.h>\n#include <pj/os.h> \n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n#include <pj/rand.h>\n\n\nstruct pjmedia_session\n{\n    pj_pool_t\t\t   *pool;\n    pjmedia_endpt\t   *endpt;\n    unsigned\t\t    stream_cnt;\n    pjmedia_stream_info\t    stream_info[PJMEDIA_MAX_SDP_MEDIA];\n    pjmedia_stream\t   *stream[PJMEDIA_MAX_SDP_MEDIA];\n    void\t\t   *user_data;\n};\n\n#define THIS_FILE\t\t\"session.c\"\n\n#ifndef PJMEDIA_SESSION_SIZE\n#   define PJMEDIA_SESSION_SIZE\t(10*1024)\n#endif\n\n#ifndef PJMEDIA_SESSION_INC\n#   define PJMEDIA_SESSION_INC\t1024\n#endif\n\n/*\n * Initialize session info from SDP session descriptors.\n */\nPJ_DEF(pj_status_t) pjmedia_session_info_from_sdp( pj_pool_t *pool,\n\t\t\t       pjmedia_endpt *endpt,\n\t\t\t       unsigned max_streams,\n\t\t\t       pjmedia_session_info *si,\n\t\t\t       const pjmedia_sdp_session *local,\n\t\t\t       const pjmedia_sdp_session *remote)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(pool && endpt && si && local && remote, PJ_EINVAL);\n\n    si->stream_cnt = max_streams;\n    if (si->stream_cnt > local->media_count)\n\tsi->stream_cnt = local->media_count;\n\n    for (i=0; i<si->stream_cnt; ++i) {\n\tpj_status_t status;\n\n\tstatus = pjmedia_stream_info_from_sdp( &si->stream_info[i], pool,\n\t\t\t\t\t       endpt, \n\t\t\t\t\t       local, remote, i);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Create new session.\n */\nPJ_DEF(pj_status_t) pjmedia_session_create( pjmedia_endpt *endpt, \n\t\t\t\t\t    const pjmedia_session_info *si,\n\t\t\t\t\t    pjmedia_transport *transports[],\n\t\t\t\t\t    void *user_data,\n\t\t\t\t\t    pjmedia_session **p_session )\n{\n    pj_pool_t *pool;\n    pjmedia_session *session;\n    int i; /* Must be signed */\n    pj_status_t status;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(endpt && si && p_session, PJ_EINVAL);\n\n    /* Create pool for the session. */\n    pool = pjmedia_endpt_create_pool( endpt, \"session\", \n\t\t\t\t      PJMEDIA_SESSION_SIZE, \n\t\t\t\t      PJMEDIA_SESSION_INC);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    session = PJ_POOL_ZALLOC_T(pool, pjmedia_session);\n    session->pool = pool;\n    session->endpt = endpt;\n    session->stream_cnt = si->stream_cnt;\n    session->user_data = user_data;\n\n    /* Copy stream info (this simple memcpy may break sometime) */\n    pj_memcpy(session->stream_info, si->stream_info,\n\t      si->stream_cnt * sizeof(pjmedia_stream_info));\n\n    /*\n     * Now create and start the stream!\n     */\n    for (i=0; i<(int)si->stream_cnt; ++i) {\n\n\t/* Create the stream */\n\tstatus = pjmedia_stream_create(endpt, session->pool,\n\t\t\t\t       &session->stream_info[i],\n\t\t\t\t       (transports?transports[i]:NULL),\n\t\t\t\t       session,\n\t\t\t\t       &session->stream[i]);\n\tif (status == PJ_SUCCESS)\n\t    status = pjmedia_stream_start(session->stream[i]);\n\n\tif (status != PJ_SUCCESS) {\n\n\t    for ( --i; i>=0; --i) {\n\t\tpjmedia_stream_destroy(session->stream[i]);\n\t    }\n\n\t    pj_pool_release(session->pool);\n\t    return status;\n\t}\n    }\n\n\n    /* Done. */\n\n    *p_session = session;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get session info.\n */\nPJ_DEF(pj_status_t) pjmedia_session_get_info( pjmedia_session *session,\n\t\t\t\t\t      pjmedia_session_info *info )\n{\n    PJ_ASSERT_RETURN(session && info, PJ_EINVAL);\n\n    info->stream_cnt = session->stream_cnt;\n    pj_memcpy(info->stream_info, session->stream_info,\n\t      session->stream_cnt * sizeof(pjmedia_stream_info));\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get user data.\n */\nPJ_DEF(void*) pjmedia_session_get_user_data( pjmedia_session *session)\n{\n    return (session? session->user_data : NULL);\n}\n\n/**\n * Destroy media session.\n */\nPJ_DEF(pj_status_t) pjmedia_session_destroy (pjmedia_session *session)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(session, PJ_EINVAL);\n\n    for (i=0; i<session->stream_cnt; ++i) {\n\t\n\tpjmedia_stream_destroy(session->stream[i]);\n\n    }\n\n    pj_pool_release (session->pool);\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Activate all stream in media session.\n *\n */\nPJ_DEF(pj_status_t) pjmedia_session_resume(pjmedia_session *session,\n\t\t\t\t\t   pjmedia_dir dir)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(session, PJ_EINVAL);\n\n    for (i=0; i<session->stream_cnt; ++i) {\n\tpjmedia_session_resume_stream(session, i, dir);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Suspend receipt and transmission of all stream in media session.\n *\n */\nPJ_DEF(pj_status_t) pjmedia_session_pause(pjmedia_session *session,\n\t\t\t\t\t  pjmedia_dir dir)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(session, PJ_EINVAL);\n\n    for (i=0; i<session->stream_cnt; ++i) {\n\tpjmedia_session_pause_stream(session, i, dir);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Suspend receipt and transmission of individual stream in media session.\n */\nPJ_DEF(pj_status_t) pjmedia_session_pause_stream( pjmedia_session *session,\n\t\t\t\t\t\t  unsigned index,\n\t\t\t\t\t\t  pjmedia_dir dir)\n{\n    PJ_ASSERT_RETURN(session && index < session->stream_cnt, PJ_EINVAL);\n\n    return pjmedia_stream_pause(session->stream[index], dir);\n}\n\n\n/**\n * Activate individual stream in media session.\n *\n */\nPJ_DEF(pj_status_t) pjmedia_session_resume_stream( pjmedia_session *session,\n\t\t\t\t\t\t   unsigned index,\n\t\t\t\t\t\t   pjmedia_dir dir)\n{\n    PJ_ASSERT_RETURN(session && index < session->stream_cnt, PJ_EINVAL);\n\n    return pjmedia_stream_resume(session->stream[index], dir);\n}\n\n/**\n * Send RTCP SDES for the session.\n */\nPJ_DEF(pj_status_t) \npjmedia_session_send_rtcp_sdes( const pjmedia_session *session )\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(session, PJ_EINVAL);\n\n    for (i=0; i<session->stream_cnt; ++i) {\n\tpjmedia_stream_send_rtcp_sdes(session->stream[i]);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/**\n * Send RTCP BYE for the session.\n */\nPJ_DEF(pj_status_t) \npjmedia_session_send_rtcp_bye( const pjmedia_session *session )\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(session, PJ_EINVAL);\n\n    for (i=0; i<session->stream_cnt; ++i) {\n\tpjmedia_stream_send_rtcp_bye(session->stream[i]);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/**\n * Enumerate media stream in the session.\n */\nPJ_DEF(pj_status_t) pjmedia_session_enum_streams(const pjmedia_session *session,\n\t\t\t\t\t\t unsigned *count, \n\t\t\t\t\t\t pjmedia_stream_info info[])\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(session && count && *count && info, PJ_EINVAL);\n\n    if (*count > session->stream_cnt)\n\t*count = session->stream_cnt;\n\n    for (i=0; i<*count; ++i) {\n\tpj_memcpy(&info[i], &session->stream_info[i], \n                  sizeof(pjmedia_stream_info));\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the port interface.\n */\nPJ_DEF(pj_status_t) pjmedia_session_get_port(  pjmedia_session *session,\n\t\t\t\t\t       unsigned index,\n\t\t\t\t\t       pjmedia_port **p_port)\n{\n    return pjmedia_stream_get_port( session->stream[index], p_port);\n}\n\n/*\n * Get statistics\n */\nPJ_DEF(pj_status_t) pjmedia_session_get_stream_stat( pjmedia_session *session,\n\t\t\t\t\t\t     unsigned index,\n\t\t\t\t\t\t     pjmedia_rtcp_stat *stat)\n{\n    PJ_ASSERT_RETURN(session && stat && index < session->stream_cnt, \n\t\t     PJ_EINVAL);\n\n    return pjmedia_stream_get_stat(session->stream[index], stat);\n}\n\n\n/**\n * Reset session statistics.\n */\nPJ_DEF(pj_status_t) pjmedia_session_reset_stream_stat( pjmedia_session *session,\n\t\t\t\t\t\t       unsigned index)\n{\n    PJ_ASSERT_RETURN(session && index < session->stream_cnt, PJ_EINVAL);\n\n    return pjmedia_stream_reset_stat(session->stream[index]);\n}\n\n\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n/*\n * Get extended statistics\n */\nPJ_DEF(pj_status_t) pjmedia_session_get_stream_stat_xr(\n\t\t\t\t\t     pjmedia_session *session,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_rtcp_xr_stat *stat_xr)\n{\n    PJ_ASSERT_RETURN(session && stat_xr && index < session->stream_cnt, \n\t\t     PJ_EINVAL);\n\n    return pjmedia_stream_get_stat_xr(session->stream[index], stat_xr);\n}\n#endif\n\nPJ_DEF(pj_status_t) pjmedia_session_get_stream_stat_jbuf(\n\t\t\t\t\t    pjmedia_session *session,\n\t\t\t\t\t    unsigned index,\n\t\t\t\t\t    pjmedia_jb_state *state)\n{\n    PJ_ASSERT_RETURN(session && state && index < session->stream_cnt, \n\t\t     PJ_EINVAL);\n\n    return pjmedia_stream_get_stat_jbuf(session->stream[index], state);\n}\n\n/*\n * Dial DTMF digit to the stream, using RFC 2833 mechanism.\n */\nPJ_DEF(pj_status_t) pjmedia_session_dial_dtmf( pjmedia_session *session,\n\t\t\t\t\t       unsigned index,\n\t\t\t\t\t       const pj_str_t *ascii_digits )\n{\n    PJ_ASSERT_RETURN(session && ascii_digits, PJ_EINVAL);\n    return pjmedia_stream_dial_dtmf(session->stream[index], ascii_digits);\n}\n\n/*\n * Check if the specified stream has received DTMF digits.\n */\nPJ_DEF(pj_status_t) pjmedia_session_check_dtmf( pjmedia_session *session,\n\t\t\t\t\t        unsigned index )\n{\n    PJ_ASSERT_RETURN(session, PJ_EINVAL);\n    return pjmedia_stream_check_dtmf(session->stream[index]);\n}\n\n\n/*\n * Retrieve DTMF digits from the specified stream.\n */\nPJ_DEF(pj_status_t) pjmedia_session_get_dtmf( pjmedia_session *session,\n\t\t\t\t\t      unsigned index,\n\t\t\t\t\t      char *ascii_digits,\n\t\t\t\t\t      unsigned *size )\n{\n    PJ_ASSERT_RETURN(session && ascii_digits && size, PJ_EINVAL);\n    return pjmedia_stream_get_dtmf(session->stream[index], ascii_digits,\n\t\t\t\t   size);\n}\n\n/*\n * Install DTMF callback.\n */\nPJ_DEF(pj_status_t) pjmedia_session_set_dtmf_callback(pjmedia_session *session,\n\t\t\t\t  unsigned index,\n\t\t\t\t  void (*cb)(pjmedia_stream*, \n\t\t\t\t \t     void *user_data, \n\t\t\t\t\t     int digit), \n\t\t\t\t  void *user_data)\n{\n    PJ_ASSERT_RETURN(session && index < session->stream_cnt, PJ_EINVAL);\n    return pjmedia_stream_set_dtmf_callback(session->stream[index], cb,\n\t\t\t\t\t    user_data);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/silencedet.c",
    "content": "/* $Id: silencedet.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/silencedet.h>\n#include <pjmedia/alaw_ulaw.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#define THIS_FILE   \"silencedet.c\"\n\n#if 1\n#   define TRACE_(x)\tPJ_LOG(5,x)\n#else\n#   define TRACE_(x)\n#endif\n\n/**\n * This enumeration specifies operation mode of silence detector \n */\ntypedef enum pjmedia_silence_det_mode {\n    VAD_MODE_NONE,\n    VAD_MODE_FIXED,\n    VAD_MODE_ADAPTIVE\n} pjmedia_silence_det_mode;\n\n/**\n * Default settings\n */\n#define DEF_RECALC_ON_VOICED\t    4000 /* Time to recalculate threshold\n\t\t\t\t\t    in voiced condition, in ms\t  */\n#define DEF_RECALC_ON_SILENCE\t    2000 /* Time to recalculate threshold\n\t\t\t\t\t    in silence condition, in ms.  */\n#define DEF_BEFORE_SILENCE\t    400\t /* Silence time before really changing\n\t\t\t\t\t    state into SILENCE, in ms.\t  */\n#define DEF_THRESHOLD\t\t    1000 /* Default threshold.\t\t  */\n\n/**\n * This enumeration specifies the states of the silence detector.\n */\nenum pjmedia_silence_det_state {\n    STATE_SILENCE,\n    STATE_START_SILENCE,\n    STATE_VOICED\n};\n\n/**\n * This structure holds the silence detector state.\n */\nstruct pjmedia_silence_det\n{\n    char      objname[PJ_MAX_OBJ_NAME]; /**< VAD name.\t\t\t    */\n\n    int\t      mode;\t\t\t/**< VAD mode.\t\t\t    */\n    unsigned  ptime;\t\t\t/**< Frame time, in msec.\t    */\n\n    unsigned  threshold;\t\t/**< Current threshold level.\t    */\n    unsigned  sum_level;\t\t/**< Total sum of recent level.\t    */\n    unsigned  sum_cnt;\t\t\t/**< Number of level summed.\t    */\n    unsigned  silence_timer;\t\t/**< Silence condition timer.\t    */\n    unsigned  voiced_timer;\t\t/**< Voiced condition timer.\t    */\n    \n    enum pjmedia_silence_det_state state;/**< Silence detector state.\t    */\n    unsigned  recalc_on_voiced;\t\t/**< Setting of time to recalc \n\t\t\t\t\t     threshold in voiced condition. */\n    unsigned  recalc_on_silence;\t/**< Setting of time to recalc \n\t\t\t\t\t     threshold in silence condition.*/\n    unsigned  before_silence;\t\t/**< Setting of silence time before \n\t\t\t\t\t     really changing state into SILENCE,\n\t\t\t\t\t     in ms.\t\t\t    */\n};\n\n\n\nPJ_DEF(pj_status_t) pjmedia_silence_det_create( pj_pool_t *pool,\n\t\t\t\t\t\tunsigned clock_rate,\n\t\t\t\t\t\tunsigned samples_per_frame,\n\t\t\t\t\t\tpjmedia_silence_det **p_sd)\n{\n    pjmedia_silence_det *sd;\n\n    PJ_ASSERT_RETURN(pool && p_sd, PJ_EINVAL);\n\n    sd = PJ_POOL_ZALLOC_T(pool, pjmedia_silence_det);\n\n    pj_ansi_snprintf(sd->objname, PJ_MAX_OBJ_NAME, \"sd%p\", sd);\n    sd->objname[PJ_MAX_OBJ_NAME-1] = '\\0';\n\n    sd->ptime = samples_per_frame * 1000 / clock_rate;\n     \n    /* Default settings */\n    pjmedia_silence_det_set_params(sd, -1, -1, -1);\n\n    /* Restart in adaptive, silent mode */\n    pjmedia_silence_det_set_adaptive( sd, -1 );\n\n    *p_sd = sd;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_silence_det_set_name( pjmedia_silence_det *sd,\n\t\t\t\t\t\t  const char *name)\n{\n    PJ_ASSERT_RETURN(sd && name, PJ_EINVAL);\n\n    pj_ansi_snprintf(sd->objname, PJ_MAX_OBJ_NAME, name, sd);\n    sd->objname[PJ_MAX_OBJ_NAME-1] = '\\0';\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_silence_det_set_adaptive(pjmedia_silence_det *sd,\n\t\t\t\t\t\t     int threshold)\n{\n    PJ_ASSERT_RETURN(sd, PJ_EINVAL);\n\n    if (threshold < 0)\n\tthreshold = DEF_THRESHOLD;\n\n    sd->mode = VAD_MODE_ADAPTIVE;\n    sd->threshold = threshold;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_silence_det_set_fixed( pjmedia_silence_det *sd,\n\t\t\t\t\t\t   int threshold )\n{\n    PJ_ASSERT_RETURN(sd, PJ_EINVAL);\n\n    if (threshold < 0)\n\tthreshold = DEF_THRESHOLD;\n\n    sd->mode = VAD_MODE_FIXED;\n    sd->threshold = threshold;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_silence_det_set_params( pjmedia_silence_det *sd,\n\t\t\t\t\t\t    int before_silence,\n\t\t\t\t\t\t    int recalc_time1,\n\t\t\t\t\t\t    int recalc_time2)\n{\n    PJ_ASSERT_RETURN(sd, PJ_EINVAL);\n\n    if (recalc_time1 < 0)\n\trecalc_time1 = DEF_RECALC_ON_VOICED;\n    if (recalc_time2 < 0)\n\trecalc_time2 = DEF_RECALC_ON_SILENCE;\n    if (before_silence < 0)\n\tbefore_silence = DEF_BEFORE_SILENCE;\n\n    sd->recalc_on_voiced = recalc_time1;\n    sd->recalc_on_silence = recalc_time2;\n    sd->before_silence  = before_silence;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_silence_det_disable( pjmedia_silence_det *sd )\n{\n    PJ_ASSERT_RETURN(sd, PJ_EINVAL);\n\n    sd->mode = VAD_MODE_NONE;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_int32_t) pjmedia_calc_avg_signal( const pj_int16_t samples[],\n\t\t\t\t\t    pj_size_t count)\n{\n    pj_uint32_t sum = 0;\n    \n    const pj_int16_t * pcm = samples;\n    const pj_int16_t * end = samples + count;\n\n    if (count==0)\n\treturn 0;\n\n    while (pcm != end) {\n\tif (*pcm < 0)\n\t    sum -= *pcm++;\n\telse\n\t    sum += *pcm++;\n    }\n    \n    return (pj_int32_t)(sum / count);\n}\n\nPJ_DEF(pj_bool_t) pjmedia_silence_det_apply( pjmedia_silence_det *sd,\n\t\t\t\t\t     pj_uint32_t level)\n{\n    int avg_recent_level;\n\n    if (sd->mode == VAD_MODE_NONE)\n\treturn PJ_FALSE;\n\n    if (sd->mode == VAD_MODE_FIXED)\n\treturn (level < sd->threshold);\n\n    /* Calculating recent level */\n    sd->sum_level += level;\n    ++sd->sum_cnt;\n    avg_recent_level = (sd->sum_level / sd->sum_cnt);\n\n    if (level > sd->threshold || \n\tlevel >= PJMEDIA_SILENCE_DET_MAX_THRESHOLD)\n    {\n\tsd->silence_timer = 0;\n\tsd->voiced_timer += sd->ptime;\n\n\tswitch(sd->state) {\n\t    case STATE_VOICED:\n\t\tif (sd->voiced_timer > sd->recalc_on_voiced) {\n\t\t    /* Voiced for long time (>recalc_on_voiced), current \n\t\t     * threshold seems to be too low.\n\t\t     */\n\t\t    sd->threshold = (avg_recent_level + sd->threshold) >> 1;\n\t\t    TRACE_((THIS_FILE,\"Re-adjust threshold (in talk burst)\"\n\t\t\t    \"to %d\", sd->threshold));\n\n\t\t    sd->voiced_timer = 0;\n\n\t\t    /* Reset sig_level */\n\t\t    sd->sum_level = avg_recent_level;\n\t\t    sd->sum_cnt = 1;\n\t\t}\n\t\tbreak;\n\n\t    case STATE_SILENCE:\n\t\tTRACE_((THIS_FILE,\"Starting talk burst (level=%d threshold=%d)\",\n\t\t\tlevel, sd->threshold));\n\n\t    case STATE_START_SILENCE:\n\t\tsd->state = STATE_VOICED;\n\n\t\t/* Reset sig_level */\n\t\tsd->sum_level = level;\n\t\tsd->sum_cnt = 1;\n\n\t\tbreak;\n\n\t    default:\n\t\tpj_assert(0);\n\t\tbreak;\n\t}\n    } else {\n\tsd->voiced_timer = 0;\n\tsd->silence_timer += sd->ptime;\n\n\tswitch(sd->state) {\n\t    case STATE_SILENCE:\n\t\tif (sd->silence_timer >= sd->recalc_on_silence) {\n\t\t    sd->threshold = avg_recent_level << 1;\n\t\t    TRACE_((THIS_FILE,\"Re-adjust threshold (in silence)\"\n\t\t\t    \"to %d\", sd->threshold));\n\n\t\t    sd->silence_timer = 0;\n\n\t\t    /* Reset sig_level */\n\t\t    sd->sum_level = avg_recent_level;\n\t\t    sd->sum_cnt = 1;\n\t\t}\n\t\tbreak;\n\n\t    case STATE_VOICED:\n\t\tsd->state = STATE_START_SILENCE;\n\n\t\t/* Reset sig_level */\n\t\tsd->sum_level = level;\n\t\tsd->sum_cnt = 1;\n\n\t    case STATE_START_SILENCE:\n\t\tif (sd->silence_timer >= sd->before_silence) {\n\t\t    sd->state = STATE_SILENCE;\n\t\t    sd->threshold = avg_recent_level << 1;\n\t\t    TRACE_((THIS_FILE,\"Starting silence (level=%d \"\n\t\t\t    \"threshold=%d)\", level, sd->threshold));\n\n\t\t    /* Reset sig_level */\n\t\t    sd->sum_level = avg_recent_level;\n\t\t    sd->sum_cnt = 1;\n\t\t}\n\t\tbreak;\n\n\t    default:\n\t\tpj_assert(0);\n\t\tbreak;\n\t}\n    }\n\n    return (sd->state == STATE_SILENCE);\n}\n\n\nPJ_DEF(pj_bool_t) pjmedia_silence_det_detect( pjmedia_silence_det *sd,\n\t\t\t\t\t      const pj_int16_t samples[],\n\t\t\t\t\t      pj_size_t count,\n\t\t\t\t\t      pj_int32_t *p_level)\n{\n    pj_uint32_t level;\n    \n    /* Calculate average signal level. */\n    level = pjmedia_calc_avg_signal(samples, count);\n    \n    /* Report to caller, if required. */\n    if (p_level)\n\t*p_level = level;\n\n    return pjmedia_silence_det_apply(sd, level);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/sound_legacy.c",
    "content": "/* $Id: sound_legacy.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * This is implementation of legacy sound device API, for applications\n * that still use the old/deprecated sound device API. This implementation\n * uses the new Audio Device API.\n *\n * Please see http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more\n * information.\n */\n\n#include <pjmedia/sound.h>\n#include <pjmedia-audiodev/errno.h>\n#include <pj/assert.h>\n\n#if PJMEDIA_HAS_LEGACY_SOUND_API\n\nstatic struct legacy_subsys\n{\n    pjmedia_snd_dev_info     info[4];\n    unsigned\t\t     info_counter;\n    unsigned\t\t     user_rec_latency;\n    unsigned\t\t     user_play_latency;\n} g_sys;\n\nstruct pjmedia_snd_stream\n{\n    pj_pool_t\t\t*pool;\n    pjmedia_aud_stream\t*aud_strm;\n    pjmedia_snd_rec_cb\t user_rec_cb;\n    pjmedia_snd_play_cb  user_play_cb;\n    void\t\t*user_user_data;\n};\n\nPJ_DEF(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory)\n{\n    return pjmedia_aud_subsys_init(factory);\n}\n\nPJ_DEF(pj_status_t) pjmedia_snd_deinit(void)\n{\n    return pjmedia_aud_subsys_shutdown();\n}\n\nPJ_DEF(int) pjmedia_snd_get_dev_count(void)\n{\n    return pjmedia_aud_dev_count();\n}\n\nPJ_DEF(const pjmedia_snd_dev_info*) pjmedia_snd_get_dev_info(unsigned index)\n{\n    pjmedia_snd_dev_info *oi = &g_sys.info[g_sys.info_counter];\n    pjmedia_aud_dev_info di;\n\n    g_sys.info_counter = (g_sys.info_counter+1) % PJ_ARRAY_SIZE(g_sys.info);\n\n    if (pjmedia_aud_dev_get_info(index, &di) != PJ_SUCCESS)\n\treturn NULL;\n\n    pj_bzero(oi, sizeof(*oi));\n    pj_ansi_strncpy(oi->name, di.name, sizeof(oi->name));\n    oi->name[sizeof(oi->name)-1] = '\\0';\n    oi->input_count = di.input_count;\n    oi->output_count = di.output_count;\n    oi->default_samples_per_sec = di.default_samples_per_sec;\n\n    return oi;\n}\n\n\nstatic pj_status_t snd_play_cb(void *user_data,\n\t\t\t       pjmedia_frame *frame)\n{\n    pjmedia_snd_stream *strm = (pjmedia_snd_stream*)user_data;\n\n    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    return strm->user_play_cb(strm->user_user_data, \n\t\t\t      frame->timestamp.u32.lo,\n\t\t\t      frame->buf,\n\t\t\t      (unsigned)frame->size);\n}\n\nstatic pj_status_t snd_rec_cb(void *user_data,\n\t\t\t      pjmedia_frame *frame)\n{\n    pjmedia_snd_stream *strm = (pjmedia_snd_stream*)user_data;\n    return strm->user_rec_cb(strm->user_user_data, \n\t\t\t     frame->timestamp.u32.lo,\n\t\t\t     frame->buf,\n\t\t\t     (unsigned)frame->size);\n}\n\nstatic pj_status_t open_stream( pjmedia_dir dir,\n\t\t\t        int rec_id,\n\t\t\t\tint play_id,\n\t\t\t\tunsigned clock_rate,\n\t\t\t\tunsigned channel_count,\n\t\t\t\tunsigned samples_per_frame,\n\t\t\t\tunsigned bits_per_sample,\n\t\t\t\tpjmedia_snd_rec_cb rec_cb,\n\t\t\t\tpjmedia_snd_play_cb play_cb,\n\t\t\t\tvoid *user_data,\n\t\t\t\tpjmedia_snd_stream **p_snd_strm)\n{\n    pj_pool_t *pool;\n    pjmedia_snd_stream *snd_strm;\n    pjmedia_aud_param param;\n    pj_status_t status;\n\n    /* Initialize parameters */\n    if (dir & PJMEDIA_DIR_CAPTURE) {\n\tstatus = pjmedia_aud_dev_default_param(rec_id, &param);\n    } else {\n\tstatus = pjmedia_aud_dev_default_param(play_id, &param);\n    }\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    param.dir = dir;\n    param.rec_id = rec_id;\n    param.play_id = play_id;\n    param.clock_rate = clock_rate;\n    param.channel_count = channel_count;\n    param.samples_per_frame = samples_per_frame;\n    param.bits_per_sample = bits_per_sample;\n\n    /* Latencies setting */\n    if ((dir & PJMEDIA_DIR_CAPTURE) && g_sys.user_rec_latency) {\n\tparam.flags |= PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY;\n\tparam.input_latency_ms = g_sys.user_rec_latency;\n    }\n    if ((dir & PJMEDIA_DIR_PLAYBACK) && g_sys.user_play_latency) {\n\tparam.flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;\n\tparam.output_latency_ms = g_sys.user_play_latency;\n    }\n\n    /* Create sound wrapper */\n    pool = pj_pool_create(pjmedia_aud_subsys_get_pool_factory(),\n\t\t\t  \"legacy-snd\", 512, 512, NULL);\n    snd_strm = PJ_POOL_ZALLOC_T(pool, pjmedia_snd_stream);\n    snd_strm->pool = pool;\n    snd_strm->user_rec_cb = rec_cb;\n    snd_strm->user_play_cb = play_cb;\n    snd_strm->user_user_data = user_data;\n\n    /* Create the stream */\n    status = pjmedia_aud_stream_create(&param, &snd_rec_cb, \n\t\t\t\t       &snd_play_cb, snd_strm,\n\t\t\t\t       &snd_strm->aud_strm);\n    if (status != PJ_SUCCESS) {\n\tpj_pool_release(pool);\n\treturn status;\n    }\n\n    *p_snd_strm = snd_strm;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_snd_open_rec( int index,\n\t\t\t\t\t  unsigned clock_rate,\n\t\t\t\t\t  unsigned channel_count,\n\t\t\t\t\t  unsigned samples_per_frame,\n\t\t\t\t\t  unsigned bits_per_sample,\n\t\t\t\t\t  pjmedia_snd_rec_cb rec_cb,\n\t\t\t\t\t  void *user_data,\n\t\t\t\t\t  pjmedia_snd_stream **p_snd_strm)\n{\n    return open_stream(PJMEDIA_DIR_CAPTURE, index, PJMEDIA_AUD_INVALID_DEV,\n\t\t       clock_rate, channel_count, samples_per_frame,\n\t\t       bits_per_sample, rec_cb, NULL,\n\t\t       user_data, p_snd_strm);\n}\n\nPJ_DEF(pj_status_t) pjmedia_snd_open_player( int index,\n\t\t\t\t\tunsigned clock_rate,\n\t\t\t\t\tunsigned channel_count,\n\t\t\t\t\tunsigned samples_per_frame,\n\t\t\t\t\tunsigned bits_per_sample,\n\t\t\t\t\tpjmedia_snd_play_cb play_cb,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tpjmedia_snd_stream **p_snd_strm )\n{\n    return open_stream(PJMEDIA_DIR_PLAYBACK, PJMEDIA_AUD_INVALID_DEV, index, \n\t\t       clock_rate, channel_count, samples_per_frame,\n\t\t       bits_per_sample, NULL, play_cb,\n\t\t       user_data, p_snd_strm);\n}\n\nPJ_DEF(pj_status_t) pjmedia_snd_open( int rec_id,\n\t\t\t\t      int play_id,\n\t\t\t\t      unsigned clock_rate,\n\t\t\t\t      unsigned channel_count,\n\t\t\t\t      unsigned samples_per_frame,\n\t\t\t\t      unsigned bits_per_sample,\n\t\t\t\t      pjmedia_snd_rec_cb rec_cb,\n\t\t\t\t      pjmedia_snd_play_cb play_cb,\n\t\t\t\t      void *user_data,\n\t\t\t\t      pjmedia_snd_stream **p_snd_strm)\n{\n    return open_stream(PJMEDIA_DIR_CAPTURE_PLAYBACK, rec_id, play_id,\n\t\t       clock_rate, channel_count, samples_per_frame,\n\t\t       bits_per_sample, rec_cb, play_cb, \n\t\t       user_data, p_snd_strm);\n}\n\nPJ_DEF(pj_status_t) pjmedia_snd_stream_start(pjmedia_snd_stream *stream)\n{\n    return pjmedia_aud_stream_start(stream->aud_strm);\n}\n\nPJ_DEF(pj_status_t) pjmedia_snd_stream_stop(pjmedia_snd_stream *stream)\n{\n    return pjmedia_aud_stream_stop(stream->aud_strm);\n}\n\nPJ_DEF(pj_status_t) pjmedia_snd_stream_get_info(pjmedia_snd_stream *strm,\n\t\t\t\t\t\tpjmedia_snd_stream_info *pi)\n{\n    pjmedia_aud_param param;\n    pj_status_t status;\n\n    status = pjmedia_aud_stream_get_param(strm->aud_strm, &param);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_bzero(pi, sizeof(*pi));\n    pi->dir = param.dir;\n    pi->play_id = param.play_id;\n    pi->rec_id = param.rec_id;\n    pi->clock_rate = param.clock_rate;\n    pi->channel_count = param.channel_count;\n    pi->samples_per_frame = param.samples_per_frame;\n    pi->bits_per_sample = param.bits_per_sample;\n\n    if (param.flags & PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY) {\n\tpi->rec_latency = param.input_latency_ms;\n    }\n    if (param.flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY) {\n\tpi->play_latency = param.output_latency_ms;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_snd_stream_close(pjmedia_snd_stream *stream)\n{\n    pj_status_t status;\n\n    status = pjmedia_aud_stream_destroy(stream->aud_strm);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_pool_release(stream->pool);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_snd_set_latency(unsigned input_latency, \n\t\t\t\t\t    unsigned output_latency)\n{\n    g_sys.user_rec_latency = input_latency;\n    g_sys.user_play_latency = output_latency;\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_HAS_LEGACY_SOUND_API */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/sound_port.c",
    "content": "/* $Id: sound_port.c 4487 2013-04-23 05:37:41Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/sound_port.h>\n#include <pjmedia/alaw_ulaw.h>\n#include <pjmedia/delaybuf.h>\n#include <pjmedia/echo.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/rand.h>\n#include <pj/string.h>\t    /* pj_memset() */\n\n#define AEC_TAIL\t    128\t    /* default AEC length in ms */\n#define AEC_SUSPEND_LIMIT   5\t    /* seconds of no activity\t*/\n\n#define THIS_FILE\t    \"sound_port.c\"\n\n//#define TEST_OVERFLOW_UNDERFLOW\n\nstruct pjmedia_snd_port\n{\n    int\t\t\t rec_id;\n    int\t\t\t play_id;\n    pj_uint32_t\t\t aud_caps;\n    pjmedia_aud_param\t aud_param;\n    pjmedia_aud_stream\t*aud_stream;\n    pjmedia_dir\t\t dir;\n    pjmedia_port\t*port;\n\n    pjmedia_clock_src    cap_clocksrc,\n                         play_clocksrc;\n\n    unsigned\t\t clock_rate;\n    unsigned\t\t channel_count;\n    unsigned\t\t samples_per_frame;\n    unsigned\t\t bits_per_sample;\n    unsigned\t\t options;\n    unsigned\t\t prm_ec_options;\n\n    /* software ec */\n    pjmedia_echo_state\t*ec_state;\n    unsigned\t\t ec_options;\n    unsigned\t\t ec_tail_len;\n    pj_bool_t\t\t ec_suspended;\n    unsigned\t\t ec_suspend_count;\n    unsigned\t\t ec_suspend_limit;\n\n    /* audio frame preview callbacks */\n    void\t\t*user_data;\n    pjmedia_aud_play_cb  on_play_frame;\n    pjmedia_aud_rec_cb   on_rec_frame;\n};\n\n/*\n * The callback called by sound player when it needs more samples to be\n * played.\n */\nstatic pj_status_t play_cb(void *user_data, pjmedia_frame *frame)\n{\n    pjmedia_snd_port *snd_port = (pjmedia_snd_port*) user_data;\n    pjmedia_port *port;\n    const unsigned required_size = (unsigned)frame->size;\n    pj_status_t status;\n\n    pjmedia_clock_src_update(&snd_port->play_clocksrc, &frame->timestamp);\n\n    port = snd_port->port;\n    if (port == NULL)\n\tgoto no_frame;\n\n    status = pjmedia_port_get_frame(port, frame);\n    if (status != PJ_SUCCESS)\n\tgoto no_frame;\n\n    if (frame->type != PJMEDIA_FRAME_TYPE_AUDIO)\n\tgoto no_frame;\n\n    /* Must supply the required samples */\n    pj_assert(frame->size == required_size);\n\n    if (snd_port->ec_state) {\n\tif (snd_port->ec_suspended) {\n\t    snd_port->ec_suspended = PJ_FALSE;\n\t    pjmedia_echo_reset(snd_port->ec_state);\n\t    PJ_LOG(4,(THIS_FILE, \"EC activated\"));\n\t}\n\tsnd_port->ec_suspend_count = 0;\n\tpjmedia_echo_playback(snd_port->ec_state, (pj_int16_t*)frame->buf);\n    }\n\n    /* Invoke preview callback */\n    if (snd_port->on_play_frame)\n\t(*snd_port->on_play_frame)(snd_port->user_data, frame);\n\n    return PJ_SUCCESS;\n\nno_frame:\n    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    frame->size = required_size;\n    pj_bzero(frame->buf, frame->size);\n\n    if (snd_port->ec_state && !snd_port->ec_suspended) {\n\t++snd_port->ec_suspend_count;\n\tif (snd_port->ec_suspend_count > snd_port->ec_suspend_limit) {\n\t    snd_port->ec_suspended = PJ_TRUE;\n\t    PJ_LOG(4,(THIS_FILE, \"EC suspended because of inactivity\"));\n\t}\n\tif (snd_port->ec_state) {\n\t    /* To maintain correct delay in EC */\n\t    pjmedia_echo_playback(snd_port->ec_state, (pj_int16_t*)frame->buf);\n\t}\n    }\n\n    /* Invoke preview callback */\n    if (snd_port->on_play_frame)\n\t(*snd_port->on_play_frame)(snd_port->user_data, frame);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * The callback called by sound recorder when it has finished capturing a\n * frame.\n */\nstatic pj_status_t rec_cb(void *user_data, pjmedia_frame *frame)\n{\n    pjmedia_snd_port *snd_port = (pjmedia_snd_port*) user_data;\n    pjmedia_port *port;\n\n    pjmedia_clock_src_update(&snd_port->cap_clocksrc, &frame->timestamp);\n\n    /* Invoke preview callback */\n    if (snd_port->on_rec_frame)\n\t(*snd_port->on_rec_frame)(snd_port->user_data, frame);\n\n    port = snd_port->port;\n    if (port == NULL)\n\treturn PJ_SUCCESS;\n\n    /* Cancel echo */\n    if (snd_port->ec_state && !snd_port->ec_suspended) {\n\tpjmedia_echo_capture(snd_port->ec_state, (pj_int16_t*) frame->buf, 0);\n    }\n\n    pjmedia_port_put_frame(port, frame);\n\n\n    return PJ_SUCCESS;\n}\n\n/*\n * The callback called by sound player when it needs more samples to be\n * played. This version is for non-PCM data.\n */\nstatic pj_status_t play_cb_ext(void *user_data, pjmedia_frame *frame)\n{\n    pjmedia_snd_port *snd_port = (pjmedia_snd_port*) user_data;\n    pjmedia_port *port = snd_port->port;\n\n    if (port == NULL) {\n\tframe->type = PJMEDIA_FRAME_TYPE_NONE;\n\treturn PJ_SUCCESS;\n    }\n\n    pjmedia_port_get_frame(port, frame);\n\n    /* Invoke preview callback */\n    if (snd_port->on_play_frame)\n\t(*snd_port->on_play_frame)(snd_port->user_data, frame);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * The callback called by sound recorder when it has finished capturing a\n * frame. This version is for non-PCM data.\n */\nstatic pj_status_t rec_cb_ext(void *user_data, pjmedia_frame *frame)\n{\n    pjmedia_snd_port *snd_port = (pjmedia_snd_port*) user_data;\n    pjmedia_port *port;\n\n    /* Invoke preview callback */\n    if (snd_port->on_rec_frame)\n\t(*snd_port->on_rec_frame)(snd_port->user_data, frame);\n\n    port = snd_port->port;\n    if (port == NULL)\n\treturn PJ_SUCCESS;\n\n    pjmedia_port_put_frame(port, frame);\n\n    return PJ_SUCCESS;\n}\n\n/* Initialize with default values (zero) */\nPJ_DEF(void) pjmedia_snd_port_param_default(pjmedia_snd_port_param *prm)\n{\n    pj_bzero(prm, sizeof(*prm));\n}\n\n/*\n * Start the sound stream.\n * This may be called even when the sound stream has already been started.\n */\nstatic pj_status_t start_sound_device( pj_pool_t *pool,\n\t\t\t\t       pjmedia_snd_port *snd_port )\n{\n    pjmedia_aud_rec_cb snd_rec_cb;\n    pjmedia_aud_play_cb snd_play_cb;\n    pjmedia_aud_param param_copy;\n    pj_status_t status;\n\n    /* Check if sound has been started. */\n    if (snd_port->aud_stream != NULL)\n\treturn PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(snd_port->dir == PJMEDIA_DIR_CAPTURE ||\n\t\t     snd_port->dir == PJMEDIA_DIR_PLAYBACK ||\n\t\t     snd_port->dir == PJMEDIA_DIR_CAPTURE_PLAYBACK,\n\t\t     PJ_EBUG);\n\n    /* Get device caps */\n    if (snd_port->aud_param.dir & PJMEDIA_DIR_CAPTURE) {\n\tpjmedia_aud_dev_info dev_info;\n\n\tstatus = pjmedia_aud_dev_get_info(snd_port->aud_param.rec_id, \n\t\t\t\t\t  &dev_info);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tsnd_port->aud_caps = dev_info.caps;\n    } else {\n\tsnd_port->aud_caps = 0;\n    }\n\n    /* Process EC settings */\n    pj_memcpy(&param_copy, &snd_port->aud_param, sizeof(param_copy));\n    if (param_copy.flags & PJMEDIA_AUD_DEV_CAP_EC) {\n\t/* EC is wanted */\n\tif ((snd_port->prm_ec_options & PJMEDIA_ECHO_USE_SW_ECHO) == 0 &&\n            (snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC))\n        {\n\t    /* Device supports EC */\n\t    /* Nothing to do */\n\t} else {\n\t    /* Application wants to use software EC or device\n             * doesn't support EC, remove EC settings from\n\t     * device parameters\n\t     */\n\t    param_copy.flags &= ~(PJMEDIA_AUD_DEV_CAP_EC |\n\t\t\t\t  PJMEDIA_AUD_DEV_CAP_EC_TAIL);\n\t}\n    }\n\n    /* Use different callback if format is not PCM */\n    if (snd_port->aud_param.ext_fmt.id == PJMEDIA_FORMAT_L16) {\n\tsnd_rec_cb = &rec_cb;\n\tsnd_play_cb = &play_cb;\n    } else {\n\tsnd_rec_cb = &rec_cb_ext;\n\tsnd_play_cb = &play_cb_ext;\n    }\n\n    /* Open the device */\n    status = pjmedia_aud_stream_create(&param_copy,\n\t\t\t\t       snd_rec_cb,\n\t\t\t\t       snd_play_cb,\n\t\t\t\t       snd_port,\n\t\t\t\t       &snd_port->aud_stream);\n\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Inactivity limit before EC is suspended. */\n    snd_port->ec_suspend_limit = AEC_SUSPEND_LIMIT *\n\t\t\t\t (snd_port->clock_rate / \n\t\t\t\t  snd_port->samples_per_frame);\n\n    /* Create software EC if parameter specifies EC and\n     * (app specifically requests software EC or device\n     * doesn't support EC). Only do this if the format is PCM!\n     */\n    if ((snd_port->aud_param.flags & PJMEDIA_AUD_DEV_CAP_EC) &&\n\t((snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC)==0 ||\n         (snd_port->prm_ec_options & PJMEDIA_ECHO_USE_SW_ECHO) != 0) &&\n\tparam_copy.ext_fmt.id == PJMEDIA_FORMAT_PCM)\n    {\n\tif ((snd_port->aud_param.flags & PJMEDIA_AUD_DEV_CAP_EC_TAIL)==0) {\n\t    snd_port->aud_param.flags |= PJMEDIA_AUD_DEV_CAP_EC_TAIL;\n\t    snd_port->aud_param.ec_tail_ms = AEC_TAIL;\n\t    PJ_LOG(4,(THIS_FILE, \"AEC tail is set to default %u ms\",\n\t\t\t\t snd_port->aud_param.ec_tail_ms));\n\t}\n\n\tpjmedia_snd_port_set_ec(snd_port, pool,\n\t\t\t\tsnd_port->aud_param.ec_tail_ms,\n\t\t\t\tsnd_port->prm_ec_options);\n    }\n\n    /* Start sound stream. */\n    if (!(snd_port->options & PJMEDIA_SND_PORT_NO_AUTO_START)) {\n\tstatus = pjmedia_aud_stream_start(snd_port->aud_stream);\n    }\n    if (status != PJ_SUCCESS) {\n\tpjmedia_aud_stream_destroy(snd_port->aud_stream);\n\tsnd_port->aud_stream = NULL;\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Stop the sound device.\n * This may be called even when there's no sound device in the port.\n */\nstatic pj_status_t stop_sound_device( pjmedia_snd_port *snd_port )\n{\n    /* Check if we have sound stream device. */\n    if (snd_port->aud_stream) {\n\tpjmedia_aud_stream_stop(snd_port->aud_stream);\n\tpjmedia_aud_stream_destroy(snd_port->aud_stream);\n\tsnd_port->aud_stream = NULL;\n    }\n\n    /* Destroy AEC */\n    if (snd_port->ec_state) {\n\tpjmedia_echo_destroy(snd_port->ec_state);\n\tsnd_port->ec_state = NULL;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create bidirectional port.\n */\nPJ_DEF(pj_status_t) pjmedia_snd_port_create( pj_pool_t *pool,\n\t\t\t\t\t     int rec_id,\n\t\t\t\t\t     int play_id,\n\t\t\t\t\t     unsigned clock_rate,\n\t\t\t\t\t     unsigned channel_count,\n\t\t\t\t\t     unsigned samples_per_frame,\n\t\t\t\t\t     unsigned bits_per_sample,\n\t\t\t\t\t     unsigned options,\n\t\t\t\t\t     pjmedia_snd_port **p_port)\n{\n    pjmedia_snd_port_param param;\n    pj_status_t status;\n\n    pjmedia_snd_port_param_default(&param);\n\n    /* Normalize rec_id & play_id */\n    if (rec_id < 0)\n\trec_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;\n    if (play_id < 0)\n\tplay_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;\n\n    status = pjmedia_aud_dev_default_param(rec_id, &param.base);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    param.base.dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;\n    param.base.rec_id = rec_id;\n    param.base.play_id = play_id;\n    param.base.clock_rate = clock_rate;\n    param.base.channel_count = channel_count;\n    param.base.samples_per_frame = samples_per_frame;\n    param.base.bits_per_sample = bits_per_sample;\n    param.options = options;\n    param.ec_options = 0;\n\n    return pjmedia_snd_port_create2(pool, &param, p_port);\n}\n\n/*\n * Create sound recorder AEC.\n */\nPJ_DEF(pj_status_t) pjmedia_snd_port_create_rec( pj_pool_t *pool,\n\t\t\t\t\t\t int dev_id,\n\t\t\t\t\t\t unsigned clock_rate,\n\t\t\t\t\t\t unsigned channel_count,\n\t\t\t\t\t\t unsigned samples_per_frame,\n\t\t\t\t\t\t unsigned bits_per_sample,\n\t\t\t\t\t\t unsigned options,\n\t\t\t\t\t\t pjmedia_snd_port **p_port)\n{\n    pjmedia_snd_port_param param;\n    pj_status_t status;\n\n    pjmedia_snd_port_param_default(&param);\n\n    /* Normalize dev_id */\n    if (dev_id < 0)\n\tdev_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;\n\n    status = pjmedia_aud_dev_default_param(dev_id, &param.base);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    param.base.dir = PJMEDIA_DIR_CAPTURE;\n    param.base.rec_id = dev_id;\n    param.base.clock_rate = clock_rate;\n    param.base.channel_count = channel_count;\n    param.base.samples_per_frame = samples_per_frame;\n    param.base.bits_per_sample = bits_per_sample;\n    param.options = options;\n    param.ec_options = 0;\n\n    return pjmedia_snd_port_create2(pool, &param, p_port);\n}\n\n\n/*\n * Create sound player port.\n */\nPJ_DEF(pj_status_t) pjmedia_snd_port_create_player( pj_pool_t *pool,\n\t\t\t\t\t\t    int dev_id,\n\t\t\t\t\t\t    unsigned clock_rate,\n\t\t\t\t\t\t    unsigned channel_count,\n\t\t\t\t\t\t    unsigned samples_per_frame,\n\t\t\t\t\t\t    unsigned bits_per_sample,\n\t\t\t\t\t\t    unsigned options,\n\t\t\t\t\t\t    pjmedia_snd_port **p_port)\n{\n    pjmedia_snd_port_param param;\n    pj_status_t status;\n\n    pjmedia_snd_port_param_default(&param);\n\n    /* Normalize dev_id */\n    if (dev_id < 0)\n\tdev_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;\n\n    status = pjmedia_aud_dev_default_param(dev_id, &param.base);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    param.base.dir = PJMEDIA_DIR_PLAYBACK;\n    param.base.play_id = dev_id;\n    param.base.clock_rate = clock_rate;\n    param.base.channel_count = channel_count;\n    param.base.samples_per_frame = samples_per_frame;\n    param.base.bits_per_sample = bits_per_sample;\n    param.options = options;\n    param.ec_options = 0;\n\n    return pjmedia_snd_port_create2(pool, &param, p_port);\n}\n\n\n/*\n * Create sound port.\n */\nPJ_DEF(pj_status_t) pjmedia_snd_port_create2(pj_pool_t *pool,\n\t\t\t\t\t     const pjmedia_snd_port_param *prm,\n\t\t\t\t\t     pjmedia_snd_port **p_port)\n{\n    pjmedia_snd_port *snd_port;\n    pj_status_t status;\n    unsigned ptime_usec;\n\n    PJ_ASSERT_RETURN(pool && prm && p_port, PJ_EINVAL);\n\n    snd_port = PJ_POOL_ZALLOC_T(pool, pjmedia_snd_port);\n    PJ_ASSERT_RETURN(snd_port, PJ_ENOMEM);\n\n    snd_port->dir = prm->base.dir;\n    snd_port->rec_id = prm->base.rec_id;\n    snd_port->play_id = prm->base.play_id;\n    snd_port->clock_rate = prm->base.clock_rate;\n    snd_port->channel_count = prm->base.channel_count;\n    snd_port->samples_per_frame = prm->base.samples_per_frame;\n    snd_port->bits_per_sample = prm->base.bits_per_sample;\n    pj_memcpy(&snd_port->aud_param, &prm->base, sizeof(snd_port->aud_param));\n    snd_port->options = prm->options;\n    snd_port->prm_ec_options = prm->ec_options;\n    snd_port->user_data = prm->user_data;\n    snd_port->on_play_frame = prm->on_play_frame;\n    snd_port->on_rec_frame = prm->on_rec_frame;\n\n    ptime_usec = prm->base.samples_per_frame * 1000 / prm->base.channel_count /\n                 prm->base.clock_rate * 1000;\n    pjmedia_clock_src_init(&snd_port->cap_clocksrc, PJMEDIA_TYPE_AUDIO,\n                           snd_port->clock_rate, ptime_usec);\n    pjmedia_clock_src_init(&snd_port->play_clocksrc, PJMEDIA_TYPE_AUDIO,\n                           snd_port->clock_rate, ptime_usec);\n    \n    /* Start sound device immediately.\n     * If there's no port connected, the sound callback will return\n     * empty signal.\n     */\n    status = start_sound_device( pool, snd_port );\n    if (status != PJ_SUCCESS) {\n\tpjmedia_snd_port_destroy(snd_port);\n\treturn status;\n    }\n\n    *p_port = snd_port;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy port (also destroys the sound device).\n */\nPJ_DEF(pj_status_t) pjmedia_snd_port_destroy(pjmedia_snd_port *snd_port)\n{\n    PJ_ASSERT_RETURN(snd_port, PJ_EINVAL);\n\n    return stop_sound_device(snd_port);\n}\n\n\n/*\n * Retrieve the sound stream associated by this sound device port.\n */\nPJ_DEF(pjmedia_aud_stream*) pjmedia_snd_port_get_snd_stream(\n\t\t\t\t\t\tpjmedia_snd_port *snd_port)\n{\n    PJ_ASSERT_RETURN(snd_port, NULL);\n    return snd_port->aud_stream;\n}\n\n\n/* Reset EC state */\nPJ_DEF(pj_status_t) pjmedia_snd_port_reset_ec_state( pjmedia_snd_port *snd_port )\n{\n    PJ_ASSERT_RETURN(snd_port, PJ_EINVAL);\n    if (snd_port->ec_state) {\n\tpjmedia_echo_reset(snd_port->ec_state);\n\tPJ_LOG(4,(THIS_FILE, \"EC reset\"));\n    }\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Change EC settings.\n */\nPJ_DEF(pj_status_t) pjmedia_snd_port_set_ec( pjmedia_snd_port *snd_port,\n\t\t\t\t\t     pj_pool_t *pool,\n\t\t\t\t\t     unsigned tail_ms,\n\t\t\t\t\t     unsigned options)\n{\n    pjmedia_aud_param prm;\n    pj_status_t status;\n\n    /* Sound must be opened in full-duplex mode */\n    PJ_ASSERT_RETURN(snd_port && \n\t\t     snd_port->dir == PJMEDIA_DIR_CAPTURE_PLAYBACK,\n\t\t     PJ_EINVALIDOP);\n\n    /* Determine whether we use device or software EC */\n    if ((snd_port->prm_ec_options & PJMEDIA_ECHO_USE_SW_ECHO) == 0 &&\n        (snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC))\n    {\n\t/* We use device EC */\n\tpj_bool_t ec_enabled;\n\n\t/* Query EC status */\n\tstatus = pjmedia_aud_stream_get_cap(snd_port->aud_stream,\n\t\t\t\t\t    PJMEDIA_AUD_DEV_CAP_EC,\n\t\t\t\t\t    &ec_enabled);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tif (tail_ms != 0) {\n\t    /* Change EC setting */\n\n\t    if (!ec_enabled) {\n\t\t/* Enable EC first */\n\t\tpj_bool_t value = PJ_TRUE;\n\t\tstatus = pjmedia_aud_stream_set_cap(snd_port->aud_stream, \n\t\t\t\t\t\t    PJMEDIA_AUD_DEV_CAP_EC,\n\t\t\t\t\t\t    &value);\n\t\tif (status != PJ_SUCCESS)\n\t\t    return status;\n\t    }\n\n\t    if ((snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC_TAIL)==0) {\n\t\t/* Device does not support setting EC tail */\n\t\treturn PJMEDIA_EAUD_INVCAP;\n\t    }\n\n\t    return pjmedia_aud_stream_set_cap(snd_port->aud_stream,\n\t\t\t\t\t      PJMEDIA_AUD_DEV_CAP_EC_TAIL,\n\t\t\t\t\t      &tail_ms);\n\n\t} else if (ec_enabled) {\n\t    /* Disable EC */\n\t    pj_bool_t value = PJ_FALSE;\n\t    return pjmedia_aud_stream_set_cap(snd_port->aud_stream, \n\t\t\t\t\t      PJMEDIA_AUD_DEV_CAP_EC,\n\t\t\t\t\t      &value);\n\t} else {\n\t    /* Request to disable EC but EC has been disabled */\n\t    /* Do nothing */\n\t    return PJ_SUCCESS;\n\t}\n\n    } else {\n\t/* We use software EC */\n\n\t/* Check if there is change in parameters */\n\tif (tail_ms==snd_port->ec_tail_len && options==snd_port->ec_options) {\n\t    PJ_LOG(5,(THIS_FILE, \"pjmedia_snd_port_set_ec() ignored, no \"\n\t\t\t\t \"change in settings\"));\n\t    return PJ_SUCCESS;\n\t}\n\n\tstatus = pjmedia_aud_stream_get_param(snd_port->aud_stream, &prm);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Audio stream must be in PCM format */\n\tPJ_ASSERT_RETURN(prm.ext_fmt.id == PJMEDIA_FORMAT_PCM,\n\t\t\t PJ_EINVALIDOP);\n\n\t/* Destroy AEC */\n\tif (snd_port->ec_state) {\n\t    pjmedia_echo_destroy(snd_port->ec_state);\n\t    snd_port->ec_state = NULL;\n\t}\n\n\tif (tail_ms != 0) {\n\t    unsigned delay_ms;\n\n\t    //No need to add input latency in the latency calculation,\n\t    //since actual input latency should be zero.\n\t    //delay_ms = (si.rec_latency + si.play_latency) * 1000 /\n\t    //\t   snd_port->clock_rate;\n\t    /* Set EC latency to 3/4 of output latency to reduce the\n\t     * possibility of missing/late reference frame.\n\t     */\n\t    delay_ms = prm.output_latency_ms * 3/4;\n\t    status = pjmedia_echo_create2(pool, snd_port->clock_rate, \n\t\t\t\t\t  snd_port->channel_count,\n\t\t\t\t\t  snd_port->samples_per_frame, \n\t\t\t\t\t  tail_ms, delay_ms,\n\t\t\t\t\t  options, &snd_port->ec_state);\n\t    if (status != PJ_SUCCESS)\n\t\tsnd_port->ec_state = NULL;\n\t    else\n\t\tsnd_port->ec_suspended = PJ_FALSE;\n\t} else {\n\t    PJ_LOG(4,(THIS_FILE, \"Echo canceller is now disabled in the \"\n\t\t\t\t \"sound port\"));\n\t    status = PJ_SUCCESS;\n\t}\n\n\tsnd_port->ec_options = options;\n\tsnd_port->ec_tail_len = tail_ms;\n    }\n\n    return status;\n}\n\n\n/* Get AEC tail length */\nPJ_DEF(pj_status_t) pjmedia_snd_port_get_ec_tail( pjmedia_snd_port *snd_port,\n\t\t\t\t\t\t  unsigned *p_length)\n{\n    PJ_ASSERT_RETURN(snd_port && p_length, PJ_EINVAL);\n\n    /* Determine whether we use device or software EC */\n    if (snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC) {\n\t/* We use device EC */\n\tpj_bool_t ec_enabled;\n\tpj_status_t status;\n\n\t/* Query EC status */\n\tstatus = pjmedia_aud_stream_get_cap(snd_port->aud_stream,\n\t\t\t\t\t    PJMEDIA_AUD_DEV_CAP_EC,\n\t\t\t\t\t    &ec_enabled);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tif (!ec_enabled) {\n\t    *p_length = 0;\n\t} else if (snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC_TAIL) {\n\t    /* Get device EC tail */\n\t    status = pjmedia_aud_stream_get_cap(snd_port->aud_stream,\n\t\t\t\t\t\tPJMEDIA_AUD_DEV_CAP_EC_TAIL,\n\t\t\t\t\t\tp_length);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\t} else {\n\t    /* Just use default */\n\t    *p_length = AEC_TAIL;\n\t}\n\n    } else {\n\t/* We use software EC */\n\t*p_length =  snd_port->ec_state ? snd_port->ec_tail_len : 0;\n    }\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get clock source.\n */\nPJ_DEF(pjmedia_clock_src *)\npjmedia_snd_port_get_clock_src( pjmedia_snd_port *snd_port,\n                                pjmedia_dir dir )\n{\n    return (dir == PJMEDIA_DIR_CAPTURE? &snd_port->cap_clocksrc:\n            &snd_port->play_clocksrc);\n}\n\n\n/*\n * Connect a port.\n */\nPJ_DEF(pj_status_t) pjmedia_snd_port_connect( pjmedia_snd_port *snd_port,\n\t\t\t\t\t      pjmedia_port *port)\n{\n    pjmedia_audio_format_detail *afd;\n\n    PJ_ASSERT_RETURN(snd_port && port, PJ_EINVAL);\n\n    afd = pjmedia_format_get_audio_format_detail(&port->info.fmt, PJ_TRUE);\n\n    /* Check that port has the same configuration as the sound device\n     * port.\n     */\n    if (afd->clock_rate != snd_port->clock_rate)\n\treturn PJMEDIA_ENCCLOCKRATE;\n\n    if (PJMEDIA_AFD_SPF(afd) != snd_port->samples_per_frame)\n\treturn PJMEDIA_ENCSAMPLESPFRAME;\n\n    if (afd->channel_count != snd_port->channel_count)\n\treturn PJMEDIA_ENCCHANNEL;\n\n    if (afd->bits_per_sample != snd_port->bits_per_sample)\n\treturn PJMEDIA_ENCBITS;\n\n    /* Port is okay. */\n    snd_port->port = port;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the connected port.\n */\nPJ_DEF(pjmedia_port*) pjmedia_snd_port_get_port(pjmedia_snd_port *snd_port)\n{\n    PJ_ASSERT_RETURN(snd_port, NULL);\n    return snd_port->port;\n}\n\n\n/*\n * Disconnect port.\n */\nPJ_DEF(pj_status_t) pjmedia_snd_port_disconnect(pjmedia_snd_port *snd_port)\n{\n    PJ_ASSERT_RETURN(snd_port, PJ_EINVAL);\n\n    snd_port->port = NULL;\n\n    return PJ_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/splitcomb.c",
    "content": "/* $Id: splitcomb.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/splitcomb.h>\n#include <pjmedia/delaybuf.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n\n\n#define SIGNATURE\t    PJMEDIA_SIG_PORT_SPLIT_COMB\n#define SIGNATURE_PORT\t    PJMEDIA_SIG_PORT_SPLIT_COMB_P\n#define THIS_FILE\t    \"splitcomb.c\"\n#define TMP_SAMP_TYPE\t    pj_int16_t\n\n/* Maximum number of channels. */\n#define MAX_CHANNELS\t    16\n\n/* Maximum number of buffers to be accommodated by delaybuf */\n#define MAX_BUF_CNT\t    PJMEDIA_SOUND_BUFFER_COUNT\n\n/* Maximum number of burst before we pause the media flow */\n#define MAX_BURST\t    (buf_cnt + 6)\n\n/* Maximum number of NULL frames received before we pause the\n * media flow.\n */\n#define MAX_NULL_FRAMES\t    (rport->max_burst)\n\n\n/* Operations */\n#define OP_PUT\t\t    (1)\n#define OP_GET\t\t    (-1)\n\n\n/* \n * Media flow directions:\n *\n *             put_frame() +-----+\n *  UPSTREAM  ------------>|split|<--> DOWNSTREAM\n *            <------------|comb |\n *             get_frame() +-----+\n *\n */\nenum sc_dir\n{\n    /* This is the media direction from the splitcomb to the \n     * downstream port(s), which happens when:\n     *  - put_frame() is called to the splitcomb\n     *  - get_frame() is called to the reverse channel port.\n     */\n    DIR_DOWNSTREAM,\n\n    /* This is the media direction from the downstream port to \n     * the splitcomb, which happens when:\n     *  - get_frame() is called to the splitcomb\n     *  - put_frame() is called to the reverse channel port.\n     */\n    DIR_UPSTREAM\n};\n\n\n\n/*\n * This structure describes the splitter/combiner.\n */\nstruct splitcomb\n{\n    pjmedia_port      base;\n\n    unsigned\t      options;\n\n    /* Array of ports, one for each channel */\n    struct {\n\tpjmedia_port *port;\n\tpj_bool_t     reversed;\n    } port_desc[MAX_CHANNELS];\n\n    /* Temporary buffers needed to extract mono frame from\n     * multichannel frame. We could use stack for this, but this\n     * way it should be safer for devices with small stack size.\n     */\n    TMP_SAMP_TYPE    *get_buf;\n    TMP_SAMP_TYPE    *put_buf;\n};\n\n\n/*\n * This structure describes reverse port.\n */\nstruct reverse_port\n{\n    pjmedia_port     base;\n    struct splitcomb*parent;\n    unsigned\t     ch_num;\n\n    /* Maximum burst before media flow is suspended.\n     * With reverse port, it's possible that either end of the \n     * port doesn't actually process the media flow (meaning, it\n     * stops calling get_frame()/put_frame()). When this happens,\n     * the other end will encounter excessive underflow or overflow,\n     * depending on which direction is not actively processed by\n     * the stopping end.\n     *\n     * To avoid excessive underflow/overflow, the media flow will\n     * be suspended once underflow/overflow goes over this max_burst\n     * limit.\n     */\n    int\t\t     max_burst;\n\n    /* When the media interface port of the splitcomb or the reverse\n     * channel port is registered to conference bridge, the bridge\n     * will transmit NULL frames to the media port when the media\n     * port is not receiving any audio from other slots (for example,\n     * when no other slots are connected to the media port).\n     *\n     * When this happens, we will generate zero frame to our buffer,\n     * to avoid underflow/overflow. But after too many NULL frames\n     * are received, we will pause the media flow instead, to save\n     * some processing.\n     *\n     * This value controls how many NULL frames can be received\n     * before we suspend media flow for a particular direction.\n     */\n    unsigned\t     max_null_frames;\n\n    /* A reverse port need a temporary buffer to store frames\n     * (because of the different phase, see splitcomb.h for details). \n     * Since we can not expect get_frame() and put_frame() to be\n     * called evenly one after another, we use delay buffers to\n     * accomodate the burst.\n     *\n     * We maintain state for each direction, hence the array. The\n     * array is indexed by direction (sc_dir).\n     */\n    struct {\n\n\t/* The delay buffer where frames will be stored */\n\tpjmedia_delay_buf   *dbuf;\n\n\t/* Flag to indicate that audio flow on this direction\n\t * is currently being suspended (perhaps because nothing\n\t * is processing the frame on the other end).\n\t */\n\tpj_bool_t\tpaused;\n\n\t/* Operation level. When the level exceeds a maximum value,\n\t * the media flow on this direction will be paused.\n\t */\n\tint\t\tlevel;\n\n\t/* Timestamp. */\n\tpj_timestamp\tts;\n\n\t/* Number of NULL frames transmitted to this port so far.\n\t * NULL frame indicate that nothing is transmitted, and \n\t * once we get too many of this, we should pause the media\n\t * flow to reduce processing.\n\t */\n\tunsigned\tnull_cnt;\n\n    } buf[2];\n\n    /* Must have temporary put buffer for the delay buf,\n     * unfortunately.\n     */\n    pj_int16_t\t      *tmp_up_buf;\n};\n\n\n/*\n * Prototypes.\n */\nstatic pj_status_t put_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame);\nstatic pj_status_t get_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame);\nstatic pj_status_t on_destroy(pjmedia_port *this_port);\n\nstatic pj_status_t rport_put_frame(pjmedia_port *this_port, \n\t\t\t\t   pjmedia_frame *frame);\nstatic pj_status_t rport_get_frame(pjmedia_port *this_port, \n\t\t\t\t   pjmedia_frame *frame);\nstatic pj_status_t rport_on_destroy(pjmedia_port *this_port);\n\n\n/*\n * Create the splitter/combiner.\n */\nPJ_DEF(pj_status_t) pjmedia_splitcomb_create( pj_pool_t *pool,\n\t\t\t\t\t      unsigned clock_rate,\n\t\t\t\t\t      unsigned channel_count,\n\t\t\t\t\t      unsigned samples_per_frame,\n\t\t\t\t\t      unsigned bits_per_sample,\n\t\t\t\t\t      unsigned options,\n\t\t\t\t\t      pjmedia_port **p_splitcomb)\n{\n    const pj_str_t name = pj_str(\"splitcomb\");\n    struct splitcomb *sc;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(pool && clock_rate && channel_count &&\n\t\t     samples_per_frame && bits_per_sample &&\n\t\t     p_splitcomb, PJ_EINVAL);\n\n    /* Only supports 16 bits per sample */\n    PJ_ASSERT_RETURN(bits_per_sample == 16, PJ_EINVAL);\n\n    *p_splitcomb = NULL;\n\n    /* Create the splitter/combiner structure */\n    sc = PJ_POOL_ZALLOC_T(pool, struct splitcomb);\n    PJ_ASSERT_RETURN(sc != NULL, PJ_ENOMEM);\n\n    /* Create temporary buffers */\n    sc->get_buf = (TMP_SAMP_TYPE*)\n\t\t  pj_pool_alloc(pool, samples_per_frame * \n\t\t\t\t      sizeof(TMP_SAMP_TYPE) /\n\t\t\t\t      channel_count);\n    PJ_ASSERT_RETURN(sc->get_buf, PJ_ENOMEM);\n\n    sc->put_buf = (TMP_SAMP_TYPE*)\n\t\t  pj_pool_alloc(pool, samples_per_frame * \n\t\t\t\t      sizeof(TMP_SAMP_TYPE) /\n\t\t\t\t      channel_count);\n    PJ_ASSERT_RETURN(sc->put_buf, PJ_ENOMEM);\n\n\n    /* Save options */\n    sc->options = options;\n\n    /* Initialize port */\n    pjmedia_port_info_init(&sc->base.info, &name, SIGNATURE, clock_rate,\n\t\t\t   channel_count, bits_per_sample, samples_per_frame);\n\n    sc->base.put_frame = &put_frame;\n    sc->base.get_frame = &get_frame;\n    sc->base.on_destroy = &on_destroy;\n\n    /* Init ports array */\n    /*\n    sc->port_desc = pj_pool_zalloc(pool, channel_count*sizeof(*sc->port_desc));\n    */\n    pj_bzero(sc->port_desc, sizeof(sc->port_desc));\n\n    /* Done for now */\n    *p_splitcomb = &sc->base;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Attach media port with the same phase as the splitter/combiner.\n */\nPJ_DEF(pj_status_t) pjmedia_splitcomb_set_channel( pjmedia_port *splitcomb,\n\t\t\t\t\t\t   unsigned ch_num,\n\t\t\t\t\t\t   unsigned options,\n\t\t\t\t\t\t   pjmedia_port *port)\n{\n    struct splitcomb *sc = (struct splitcomb*) splitcomb;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(splitcomb && port, PJ_EINVAL);\n\n    /* Make sure this is really a splitcomb port */\n    PJ_ASSERT_RETURN(sc->base.info.signature == SIGNATURE, PJ_EINVAL);\n\n    /* Check the channel number */\n    PJ_ASSERT_RETURN(ch_num < PJMEDIA_PIA_CCNT(&sc->base.info), PJ_EINVAL);\n\n    /* options is unused for now */\n    PJ_UNUSED_ARG(options);\n\n    sc->port_desc[ch_num].port = port;\n    sc->port_desc[ch_num].reversed = PJ_FALSE;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create reverse phase port for the specified channel.\n */\nPJ_DEF(pj_status_t) pjmedia_splitcomb_create_rev_channel( pj_pool_t *pool,\n\t\t\t\t      pjmedia_port *splitcomb,\n\t\t\t\t      unsigned ch_num,\n\t\t\t\t      unsigned options,\n\t\t\t\t      pjmedia_port **p_chport)\n{\n    const pj_str_t name = pj_str(\"scomb-rev\");\n    struct splitcomb *sc = (struct splitcomb*) splitcomb;\n    struct reverse_port *rport;\n    unsigned buf_cnt;\n    const pjmedia_audio_format_detail *sc_afd, *p_afd;\n    pjmedia_port *port;\n    pj_status_t status;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(pool && splitcomb, PJ_EINVAL);\n\n    /* Make sure this is really a splitcomb port */\n    PJ_ASSERT_RETURN(sc->base.info.signature == SIGNATURE, PJ_EINVAL);\n\n    /* Check the channel number */\n    PJ_ASSERT_RETURN(ch_num < PJMEDIA_PIA_CCNT(&sc->base.info), PJ_EINVAL);\n\n    /* options is unused for now */\n    PJ_UNUSED_ARG(options);\n\n    sc_afd = pjmedia_format_get_audio_format_detail(&splitcomb->info.fmt, 1);\n\n    /* Create the port */\n    rport = PJ_POOL_ZALLOC_T(pool, struct reverse_port);\n    rport->parent = sc;\n    rport->ch_num = ch_num;\n\n    /* Initialize port info... */\n    port = &rport->base;\n    pjmedia_port_info_init(&port->info, &name, SIGNATURE_PORT, \n\t\t\t   sc_afd->clock_rate, 1,\n\t\t\t   sc_afd->bits_per_sample,\n\t\t\t   PJMEDIA_PIA_SPF(&splitcomb->info) /\n\t\t\t\t   sc_afd->channel_count);\n\n    p_afd = pjmedia_format_get_audio_format_detail(&port->info.fmt, 1);\n\n    /* ... and the callbacks */\n    port->put_frame = &rport_put_frame;\n    port->get_frame = &rport_get_frame;\n    port->on_destroy = &rport_on_destroy;\n\n    /* Buffer settings */\n    buf_cnt = options & 0xFF;\n    if (buf_cnt == 0)\n\tbuf_cnt = MAX_BUF_CNT;\n\n    rport->max_burst = MAX_BURST;\n    rport->max_null_frames = MAX_NULL_FRAMES;\n\n    /* Create downstream/put buffers */\n    status = pjmedia_delay_buf_create(pool, \"scombdb-dn\",\n\t\t\t\t      p_afd->clock_rate,\n\t\t\t\t      PJMEDIA_PIA_SPF(&port->info),\n\t\t\t\t      p_afd->channel_count,\n\t\t\t\t      buf_cnt * p_afd->frame_time_usec / 1000,\n\t\t\t\t      0, &rport->buf[DIR_DOWNSTREAM].dbuf);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    /* Create upstream/get buffers */\n    status = pjmedia_delay_buf_create(pool, \"scombdb-up\",\n\t\t\t\t      p_afd->clock_rate,\n\t\t\t\t      PJMEDIA_PIA_SPF(&port->info),\n\t\t\t\t      p_afd->channel_count,\n\t\t\t\t      buf_cnt * p_afd->frame_time_usec / 1000,\n\t\t\t\t      0, &rport->buf[DIR_UPSTREAM].dbuf);\n    if (status != PJ_SUCCESS) {\n\tpjmedia_delay_buf_destroy(rport->buf[DIR_DOWNSTREAM].dbuf);\n\treturn status;\n    }\n\n    /* And temporary upstream/get buffer */\n    rport->tmp_up_buf = (pj_int16_t*)\n\t                pj_pool_alloc(pool,\n\t\t\t\t      PJMEDIA_PIA_AVG_FSZ(&port->info));\n\n    /* Save port in the splitcomb */\n    sc->port_desc[ch_num].port = &rport->base;\n    sc->port_desc[ch_num].reversed = PJ_TRUE;\n\n\n    /* Done */\n    *p_chport = port;\n    return status;\n}\n\n\n/* \n * Extract one mono frame from a multichannel frame. \n */\nstatic void extract_mono_frame( const pj_int16_t *in,\n\t\t\t        pj_int16_t *out,\n\t\t\t\tunsigned ch,\n\t\t\t\tunsigned ch_cnt,\n\t\t\t\tunsigned samples_count)\n{\n    unsigned i;\n\n    in += ch;\n    for (i=0; i<samples_count; ++i) {\n\t*out++ = *in;\n\tin += ch_cnt;\n    }\n}\n\n\n/* \n * Put one mono frame into a multichannel frame \n */\nstatic void store_mono_frame( const pj_int16_t *in,\n\t\t\t      pj_int16_t *out,\n\t\t\t      unsigned ch,\n\t\t\t      unsigned ch_cnt,\n\t\t\t      unsigned samples_count)\n{\n    unsigned i;\n\n    out += ch;\n    for (i=0; i<samples_count; ++i) {\n\t*out = *in++;\n\tout += ch_cnt;\n    }\n}\n\n/* Update operation on the specified direction  */\nstatic void op_update(struct reverse_port *rport, int dir, int op)\n{\n    char *dir_name[2] = {\"downstream\", \"upstream\"};\n\n    rport->buf[dir].level += op;\n\n    if (op == OP_PUT) {\n\trport->buf[dir].ts.u64 += PJMEDIA_PIA_SPF(&rport->base.info);\n    }\n\n    if (rport->buf[dir].paused) {\n\tif (rport->buf[dir].level < -rport->max_burst) {\n\t    /* Prevent the level from overflowing and resets back to zero */\n\t    rport->buf[dir].level = -rport->max_burst;\n\t} else if (rport->buf[dir].level > rport->max_burst) {\n\t    /* Prevent the level from overflowing and resets back to zero */\n\t    rport->buf[dir].level = rport->max_burst;\n\t} else {\n\t    /* Level has fallen below max level, we can resume\n\t     * media flow.\n\t     */\n\t    PJ_LOG(5,(rport->base.info.name.ptr, \n\t\t      \"Resuming media flow on %s direction (level=%d)\", \n\t\t      dir_name[dir], rport->buf[dir].level));\n\t    rport->buf[dir].level = 0;\n\t    rport->buf[dir].paused = PJ_FALSE;\n\n\t    //This will cause disruption in audio, and it seems to be\n\t    //working fine without this anyway, so we disable it for now.\n\t    //pjmedia_delay_buf_learn(rport->buf[dir].dbuf);\n\n\t}\n    } else {\n\tif (rport->buf[dir].level >= rport->max_burst ||\n\t    rport->buf[dir].level <= -rport->max_burst) \n\t{\n\t    /* Level has reached maximum level, the other side of\n\t     * rport is not sending/retrieving frames. Pause the\n\t     * rport on this direction.\n\t     */\n\t    PJ_LOG(5,(rport->base.info.name.ptr, \n\t\t      \"Pausing media flow on %s direction (level=%d)\", \n\t\t      dir_name[dir], rport->buf[dir].level));\n\t    rport->buf[dir].paused = PJ_TRUE;\n\t}\n    }\n}\n\n\n/*\n * \"Write\" a multichannel frame downstream. This would split \n * the multichannel frame into individual mono channel, and write \n * it to the appropriate port.\n */\nstatic pj_status_t put_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame)\n{\n    struct splitcomb *sc = (struct splitcomb*) this_port;\n    unsigned ch;\n\n    /* Handle null frame */\n    if (frame->type == PJMEDIA_FRAME_TYPE_NONE) {\n\tfor (ch=0; ch < PJMEDIA_PIA_CCNT(&this_port->info); ++ch) {\n\t    pjmedia_port *port = sc->port_desc[ch].port;\n\n\t    if (!port) continue;\n\n\t    if (!sc->port_desc[ch].reversed) {\n\t\tpjmedia_port_put_frame(port, frame);\n\t    } else {\n\t\tstruct reverse_port *rport = (struct reverse_port*)port;\n\n\t\t/* Update the number of NULL frames received. Once we have too\n\t\t * many of this, we'll stop calling op_update() to let the\n\t\t * media be suspended.\n\t\t */\n\n\t\tif (++rport->buf[DIR_DOWNSTREAM].null_cnt > \n\t\t\trport->max_null_frames) \n\t\t{\n\t\t    /* Prevent the counter from overflowing and resetting\n\t\t     * back to zero\n\t\t     */\n\t\t    rport->buf[DIR_DOWNSTREAM].null_cnt = \n\t\t\trport->max_null_frames + 1;\n\t\t    continue;\n\t\t}\n\n\t\t/* Write zero port to delaybuf so that it doesn't underflow. \n\t\t * If we don't do this, get_frame() on this direction will\n\t\t * cause delaybuf to generate missing frame and the last\n\t\t * frame transmitted to delaybuf will be replayed multiple\n\t\t * times, which doesn't sound good.\n\t\t */\n\n\t\t/* Update rport state. */\n\t\top_update(rport, DIR_DOWNSTREAM, OP_PUT);\n\n\t\t/* Discard frame if rport is paused on this direction */\n\t\tif (rport->buf[DIR_DOWNSTREAM].paused)\n\t\t    continue;\n\n\t\t/* Generate zero frame. */\n\t\tpjmedia_zero_samples(sc->put_buf, \n\t\t\t\t     PJMEDIA_PIA_SPF(&port->info));\n\n\t\t/* Put frame to delay buffer */\n\t\tpjmedia_delay_buf_put(rport->buf[DIR_DOWNSTREAM].dbuf,\n\t\t\t\t      sc->put_buf);\n\n\t    }\n\t}\n\treturn PJ_SUCCESS;\n    }\n\n    /* Not sure how we would handle partial frame, so better reject\n     * it for now.\n     */\n    PJ_ASSERT_RETURN(frame->size == PJMEDIA_PIA_AVG_FSZ(&this_port->info),\n\t\t     PJ_EINVAL);\n\n    /* \n     * Write mono frame into each channels \n     */\n    for (ch=0; ch < PJMEDIA_PIA_CCNT(&this_port->info); ++ch) {\n\tpjmedia_port *port = sc->port_desc[ch].port;\n\n\tif (!port)\n\t    continue;\n\n\t/* Extract the mono frame to temporary buffer */\n\textract_mono_frame((const pj_int16_t*)frame->buf, sc->put_buf, ch, \n\t\t\t   PJMEDIA_PIA_CCNT(&this_port->info),\n\t\t\t   (unsigned)frame->size * 8 / \n\t\t\t     PJMEDIA_PIA_BITS(&this_port->info) /\n\t\t\t     PJMEDIA_PIA_CCNT(&this_port->info));\n\n\tif (!sc->port_desc[ch].reversed) {\n\t    /* Write to normal port */\n\t    pjmedia_frame mono_frame;\n\n\t    mono_frame.buf = sc->put_buf;\n\t    mono_frame.size = frame->size / PJMEDIA_PIA_CCNT(&this_port->info);\n\t    mono_frame.type = frame->type;\n\t    mono_frame.timestamp.u64 = frame->timestamp.u64;\n\n\t    /* Write */\n\t    pjmedia_port_put_frame(port, &mono_frame);\n\n\t} else {\n\t    /* Write to reversed phase port */\n\t    struct reverse_port *rport = (struct reverse_port*)port;\n\n\t    /* Reset NULL frame counter */\n\t    rport->buf[DIR_DOWNSTREAM].null_cnt = 0;\n\n\t    /* Update rport state. */\n\t    op_update(rport, DIR_DOWNSTREAM, OP_PUT);\n\n\t    if (!rport->buf[DIR_DOWNSTREAM].paused) {\n\t\tpjmedia_delay_buf_put(rport->buf[DIR_DOWNSTREAM].dbuf, \n\t\t\t\t      sc->put_buf);\n\t    }\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get a multichannel frame upstream.\n * This will get mono channel frame from each port and put the\n * mono frame into the multichannel frame.\n */\nstatic pj_status_t get_frame(pjmedia_port *this_port, \n\t\t\t     pjmedia_frame *frame)\n{\n    struct splitcomb *sc = (struct splitcomb*) this_port;\n    unsigned ch;\n    pj_bool_t has_frame = PJ_FALSE;\n\n    /* Read frame from each port */\n    for (ch=0; ch < PJMEDIA_PIA_CCNT(&this_port->info); ++ch) {\n\tpjmedia_port *port = sc->port_desc[ch].port;\n\tpjmedia_frame mono_frame;\n\tpj_status_t status;\n\n\tif (!port) {\n\t    pjmedia_zero_samples(sc->get_buf, \n\t\t\t\t PJMEDIA_PIA_SPF(&this_port->info) /\n\t\t\t\t  PJMEDIA_PIA_CCNT(&this_port->info));\n\n\t} else if (sc->port_desc[ch].reversed == PJ_FALSE) {\n\t    /* Read from normal port */\n\t    mono_frame.buf = sc->get_buf;\n\t    mono_frame.size = PJMEDIA_PIA_AVG_FSZ(&port->info);\n\t    mono_frame.timestamp.u64 = frame->timestamp.u64;\n\n\t    status = pjmedia_port_get_frame(port, &mono_frame);\n\t    if (status != PJ_SUCCESS || \n\t\tmono_frame.type != PJMEDIA_FRAME_TYPE_AUDIO)\n\t    {\n\t\tpjmedia_zero_samples(sc->get_buf, \n\t\t\t\t     PJMEDIA_PIA_SPF(&port->info));\n\t    }\n\n\t    frame->timestamp.u64 = mono_frame.timestamp.u64;\n\n\t} else {\n\t    /* Read from temporary buffer for reverse port */\n\t    struct reverse_port *rport = (struct reverse_port*)port;\n\n\t    /* Update rport state. */\n\t    op_update(rport, DIR_UPSTREAM, OP_GET);\n\n\t    if (!rport->buf[DIR_UPSTREAM].paused) {\n\t\tpjmedia_delay_buf_get(rport->buf[DIR_UPSTREAM].dbuf, \n\t\t\t\t      sc->get_buf);\n\n\t    } else {\n\t\tpjmedia_zero_samples(sc->get_buf, \n\t\t\t\t     PJMEDIA_PIA_SPF(&port->info));\n\t    }\n\n\t    frame->timestamp.u64 = rport->buf[DIR_UPSTREAM].ts.u64;\n\t}\n\n\t/* Combine the mono frame into multichannel frame */\n\tstore_mono_frame(sc->get_buf, \n\t\t\t (pj_int16_t*)frame->buf, ch,\n\t\t\t PJMEDIA_PIA_CCNT(&this_port->info),\n\t\t\t PJMEDIA_PIA_SPF(&this_port->info) /\n\t\t\t  PJMEDIA_PIA_CCNT(&this_port->info));\n\n\thas_frame = PJ_TRUE;\n    }\n\n    /* Return NO_FRAME is we don't get any frames from downstream ports */\n    if (has_frame) {\n\tframe->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframe->size = PJMEDIA_PIA_AVG_FSZ(&this_port->info);\n    } else\n\tframe->type = PJMEDIA_FRAME_TYPE_NONE;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t on_destroy(pjmedia_port *this_port)\n{\n    /* Nothing to do for the splitcomb\n     * Reverse ports must be destroyed separately.\n     */\n    PJ_UNUSED_ARG(this_port);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Put a frame in the reverse port (upstream direction). This frame\n * will be picked up by get_frame() above.\n */\nstatic pj_status_t rport_put_frame(pjmedia_port *this_port, \n\t\t\t\t   pjmedia_frame *frame)\n{\n    struct reverse_port *rport = (struct reverse_port*) this_port;\n\n    pj_assert(frame->size <= PJMEDIA_PIA_AVG_FSZ(&rport->base.info));\n\n    /* Handle NULL frame */\n    if (frame->type != PJMEDIA_FRAME_TYPE_AUDIO) {\n\t/* Update the number of NULL frames received. Once we have too\n\t * many of this, we'll stop calling op_update() to let the\n\t * media be suspended.\n\t */\n\tif (++rport->buf[DIR_UPSTREAM].null_cnt > rport->max_null_frames) {\n\t    /* Prevent the counter from overflowing and resetting back \n\t     * to zero\n\t     */\n\t    rport->buf[DIR_UPSTREAM].null_cnt = rport->max_null_frames + 1;\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* Write zero port to delaybuf so that it doesn't underflow. \n\t * If we don't do this, get_frame() on this direction will\n\t * cause delaybuf to generate missing frame and the last\n\t * frame transmitted to delaybuf will be replayed multiple\n\t * times, which doesn't sound good.\n\t */\n\n\t/* Update rport state. */\n\top_update(rport, DIR_UPSTREAM, OP_PUT);\n\n\t/* Discard frame if rport is paused on this direction */\n\tif (rport->buf[DIR_UPSTREAM].paused)\n\t    return PJ_SUCCESS;\n\n\t/* Generate zero frame. */\n\tpjmedia_zero_samples(rport->tmp_up_buf, \n\t\t\t     PJMEDIA_PIA_SPF(&this_port->info));\n\n\t/* Put frame to delay buffer */\n\treturn pjmedia_delay_buf_put(rport->buf[DIR_UPSTREAM].dbuf, \n\t\t\t\t     rport->tmp_up_buf);\n    }\n\n    /* Not sure how to handle partial frame, so better reject for now */\n    PJ_ASSERT_RETURN(frame->size == PJMEDIA_PIA_AVG_FSZ(&this_port->info),\n\t\t     PJ_EINVAL);\n\n    /* Reset NULL frame counter */\n    rport->buf[DIR_UPSTREAM].null_cnt = 0;\n\n    /* Update rport state. */\n    op_update(rport, DIR_UPSTREAM, OP_PUT);\n\n    /* Discard frame if rport is paused on this direction */\n    if (rport->buf[DIR_UPSTREAM].paused)\n\treturn PJ_SUCCESS;\n\n    /* Unfortunately must copy to temporary buffer since delay buf\n     * modifies the frame content.\n     */\n    pjmedia_copy_samples(rport->tmp_up_buf, (const pj_int16_t*)frame->buf,\n\t\t         PJMEDIA_PIA_SPF(&this_port->info));\n\n    /* Put frame to delay buffer */\n    return pjmedia_delay_buf_put(rport->buf[DIR_UPSTREAM].dbuf, \n\t\t\t\t rport->tmp_up_buf);\n}\n\n\n/* Get a mono frame from a reversed phase channel (downstream direction).\n * The frame is put by put_frame() call to the splitcomb.\n */\nstatic pj_status_t rport_get_frame(pjmedia_port *this_port, \n\t\t\t\t   pjmedia_frame *frame)\n{\n    struct reverse_port *rport = (struct reverse_port*) this_port;\n\n    /* Update state */\n    op_update(rport, DIR_DOWNSTREAM, OP_GET);\n\n    /* Return no frame if media flow on this direction is being\n     * paused.\n     */\n    if (rport->buf[DIR_DOWNSTREAM].paused) {\n\tframe->type = PJMEDIA_FRAME_TYPE_NONE;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Get frame from delay buffer */\n    frame->size = PJMEDIA_PIA_AVG_FSZ(&this_port->info);\n    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    frame->timestamp.u64 = rport->buf[DIR_DOWNSTREAM].ts.u64;\n\n    return pjmedia_delay_buf_get(rport->buf[DIR_DOWNSTREAM].dbuf, \n\t\t\t\t (short*)frame->buf);\n}\n\n\nstatic pj_status_t rport_on_destroy(pjmedia_port *this_port)\n{\n    struct reverse_port *rport = (struct reverse_port*) this_port;\n\n    pjmedia_delay_buf_destroy(rport->buf[DIR_DOWNSTREAM].dbuf);\n    pjmedia_delay_buf_destroy(rport->buf[DIR_UPSTREAM].dbuf);\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/stereo_port.c",
    "content": "/* $Id: stereo_port.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pjmedia/stereo.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n#define SIGNATURE\t\tPJMEDIA_SIG_PORT_STEREO\n\n\nstruct stereo_port\n{\n    pjmedia_port\t base;\n    pjmedia_port\t*dn_port;\n    unsigned\t\t options;\n    pj_int16_t\t\t*put_buf;\n    pj_int16_t\t\t*get_buf;\n};\n\n\n\nstatic pj_status_t stereo_put_frame(pjmedia_port *this_port,\n\t\t\t\t    pjmedia_frame *frame);\nstatic pj_status_t stereo_get_frame(pjmedia_port *this_port, \n\t\t\t\t    pjmedia_frame *frame);\nstatic pj_status_t stereo_destroy(pjmedia_port *this_port);\n\n\n\nPJ_DEF(pj_status_t) pjmedia_stereo_port_create( pj_pool_t *pool,\n\t\t\t\t\t\tpjmedia_port *dn_port,\n\t\t\t\t\t\tunsigned channel_count,\n\t\t\t\t\t\tunsigned options,\n\t\t\t\t\t\tpjmedia_port **p_port )\n{\n    const pj_str_t name = pj_str(\"stereo\");\n    struct stereo_port *sport;\n    unsigned samples_per_frame;\n\n    /* Validate arguments. */\n    PJ_ASSERT_RETURN(pool && dn_port && channel_count && p_port, PJ_EINVAL);\n\n    /* Only supports 16bit samples per frame */\n    PJ_ASSERT_RETURN(PJMEDIA_PIA_BITS(&dn_port->info) == 16,\n\t\t     PJMEDIA_ENCBITS);\n\n    /* Validate channel counts */\n    PJ_ASSERT_RETURN(((PJMEDIA_PIA_CCNT(&dn_port->info)>1 &&\n\t\t\t      channel_count==1) ||\n\t\t      (PJMEDIA_PIA_CCNT(&dn_port->info)==1 &&\n\t\t\t      channel_count>1)),\n\t\t      PJ_EINVAL);\n\n    /* Create and initialize port. */\n    sport = PJ_POOL_ZALLOC_T(pool, struct stereo_port);\n    PJ_ASSERT_RETURN(sport != NULL, PJ_ENOMEM);\n\n    samples_per_frame = PJMEDIA_PIA_SPF(&dn_port->info) * channel_count /\n\t                  PJMEDIA_PIA_CCNT(&dn_port->info);\n\n    pjmedia_port_info_init(&sport->base.info, &name, SIGNATURE, \n\t                   PJMEDIA_PIA_SRATE(&dn_port->info),\n\t\t\t   channel_count, \n\t\t\t   PJMEDIA_PIA_BITS(&dn_port->info),\n\t\t\t   samples_per_frame);\n\n    sport->dn_port = dn_port;\n    sport->options = options;\n\n    /* We always need buffer for put_frame */\n    sport->put_buf = (pj_int16_t*)\n\t\t     pj_pool_alloc(pool,\n\t\t\t\t   PJMEDIA_PIA_AVG_FSZ(&dn_port->info));\n\n    /* See if we need buffer for get_frame */\n    if (PJMEDIA_PIA_CCNT(&dn_port->info) > channel_count) {\n\tsport->get_buf = (pj_int16_t*)\n\t\t\t pj_pool_alloc(pool,\n\t\t\t\t       PJMEDIA_PIA_AVG_FSZ(&dn_port->info));\n    }\n\n    /* Media port interface */\n    sport->base.get_frame = &stereo_get_frame;\n    sport->base.put_frame = &stereo_put_frame;\n    sport->base.on_destroy = &stereo_destroy;\n\n\n    /* Done */\n    *p_port = &sport->base;\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t stereo_put_frame(pjmedia_port *this_port,\n\t\t\t\t    pjmedia_frame *frame)\n{\n    struct stereo_port *sport = (struct stereo_port*) this_port;\n    const pjmedia_audio_format_detail *s_afd, *dn_afd;\n    pjmedia_frame tmp_frame;\n\n    /* Return if we don't have downstream port. */\n    if (sport->dn_port == NULL) {\n\treturn PJ_SUCCESS;\n    }\n\n    s_afd = pjmedia_format_get_audio_format_detail(&this_port->info.fmt, 1);\n    dn_afd = pjmedia_format_get_audio_format_detail(&sport->dn_port->info.fmt,\n\t\t\t\t\t\t    1);\n\n    if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) {\n\ttmp_frame.buf = sport->put_buf;\n\tif (dn_afd->channel_count == 1) {\n\t    pjmedia_convert_channel_nto1((pj_int16_t*)tmp_frame.buf, \n\t\t\t\t\t (const pj_int16_t*)frame->buf,\n\t\t\t\t\t s_afd->channel_count,\n\t\t\t\t\t PJMEDIA_AFD_SPF(s_afd),\n\t\t\t\t\t (sport->options & PJMEDIA_STEREO_MIX),\n\t\t\t\t\t 0);\n\t} else {\n\t    pjmedia_convert_channel_1ton((pj_int16_t*)tmp_frame.buf, \n\t\t\t\t\t (const pj_int16_t*)frame->buf,\n\t\t\t\t\t dn_afd->channel_count,\n\t\t\t\t\t PJMEDIA_AFD_SPF(s_afd),\n\t\t\t\t\t sport->options);\n\t}\n\ttmp_frame.size = PJMEDIA_AFD_AVG_FSZ(dn_afd);\n    } else {\n\ttmp_frame.buf = frame->buf;\n\ttmp_frame.size = frame->size;\n    }\n\n    tmp_frame.type = frame->type;\n    tmp_frame.timestamp.u64 = frame->timestamp.u64;\n\n    return pjmedia_port_put_frame( sport->dn_port, &tmp_frame );\n}\n\n\n\nstatic pj_status_t stereo_get_frame(pjmedia_port *this_port, \n\t\t\t\t    pjmedia_frame *frame)\n{\n    struct stereo_port *sport = (struct stereo_port*) this_port;\n    const pjmedia_audio_format_detail *s_afd, *dn_afd;\n    pjmedia_frame tmp_frame;\n    pj_status_t status;\n\n    /* Return silence if we don't have downstream port */\n    if (sport->dn_port == NULL) {\n\tpj_bzero(frame->buf, frame->size);\n\treturn PJ_SUCCESS;\n    }\n\n    s_afd = pjmedia_format_get_audio_format_detail(&this_port->info.fmt, 1);\n    dn_afd = pjmedia_format_get_audio_format_detail(&sport->dn_port->info.fmt,\n\t\t\t\t\t\t    1);\n\n    tmp_frame.buf = sport->get_buf? sport->get_buf : frame->buf;\n    tmp_frame.size = PJMEDIA_PIA_AVG_FSZ(&sport->dn_port->info);\n    tmp_frame.timestamp.u64 = frame->timestamp.u64;\n    tmp_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;\n\n    status = pjmedia_port_get_frame( sport->dn_port, &tmp_frame);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (tmp_frame.type != PJMEDIA_FRAME_TYPE_AUDIO) {\n\tframe->type = tmp_frame.type;\n\tframe->timestamp = tmp_frame.timestamp;\n\tframe->size = tmp_frame.size;\n\tif (tmp_frame.size && tmp_frame.buf == sport->get_buf)\n\t    pj_memcpy(frame->buf, tmp_frame.buf, tmp_frame.size);\n\treturn PJ_SUCCESS;\n    }\n\n    if (s_afd->channel_count == 1) {\n\tpjmedia_convert_channel_nto1((pj_int16_t*)frame->buf, \n\t\t\t\t     (const pj_int16_t*)tmp_frame.buf,\n\t\t\t\t     dn_afd->channel_count,\n\t\t\t\t     PJMEDIA_AFD_SPF(s_afd),\n\t\t\t\t     (sport->options & PJMEDIA_STEREO_MIX), 0);\n    } else {\n\tpjmedia_convert_channel_1ton((pj_int16_t*)frame->buf, \n\t\t\t\t     (const pj_int16_t*)tmp_frame.buf,\n\t\t\t\t     s_afd->channel_count,\n\t\t\t\t     PJMEDIA_AFD_SPF(dn_afd),\n\t\t\t\t     sport->options);\n    }\n\n    frame->size = PJMEDIA_AFD_AVG_FSZ(s_afd);\n    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t stereo_destroy(pjmedia_port *this_port)\n{\n    struct stereo_port *sport = (struct stereo_port*) this_port;\n\n    if ((sport->options & PJMEDIA_STEREO_DONT_DESTROY_DN)==0) {\n\tpjmedia_port_destroy(sport->dn_port);\n\tsport->dn_port = NULL;\n    }\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/stream.c",
    "content": "/* $Id: stream.c 4336 2013-01-29 08:15:02Z ming $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia/stream.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/rtp.h>\n#include <pjmedia/rtcp.h>\n#include <pjmedia/jbuf.h>\n#include <pjmedia/stream_common.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n#include <pj/compat/socket.h>\n#include <pj/errno.h>\n#include <pj/ioqueue.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/sock_select.h>\n#include <pj/string.h>\t    /* memcpy() */\n\n\n#define THIS_FILE\t\t\t\"stream.c\"\n#define ERRLEVEL\t\t\t1\n#define LOGERR_(expr)\t\t\tstream_perror expr\n#define TRC_(expr)\t\t\tPJ_LOG(5,expr)\n\n#define BYTES_PER_SAMPLE\t\t2\n\n/* Limit the number of synthetic audio samples that are generated by PLC.\n * Normally PLC should have it's own means to limit the number of\n * synthetic frames, so we need to set this to a reasonably large value\n * just as precaution\n */\n#define MAX_PLC_MSEC\t\t\tPJMEDIA_MAX_PLC_DURATION_MSEC\n\n\n/* Tracing jitter buffer operations in a stream session to a CSV file.\n * The trace will contain JB operation timestamp, frame info, RTP info, and\n * the JB state right after the operation.\n */\n#define TRACE_JB\t\t\t0\t/* Enable/disable trace.    */\n#define TRACE_JB_PATH_PREFIX\t\t\"\"\t/* Optional path/prefix\n\t\t\t\t\t\t   for the CSV filename.    */\n#if TRACE_JB\n#   include <pj/file_io.h>\n#   define TRACE_JB_INVALID_FD\t\t((pj_oshandle_t)-1)\n#   define TRACE_JB_OPENED(s)\t\t(s->trace_jb_fd != TRACE_JB_INVALID_FD)\n#endif\n\n#ifndef PJMEDIA_STREAM_SIZE\n#   define PJMEDIA_STREAM_SIZE\t1000\n#endif\n\n#ifndef PJMEDIA_STREAM_INC\n#   define PJMEDIA_STREAM_INC\t1000\n#endif\n\n/* Number of DTMF E bit transmissions */\n#define DTMF_EBIT_RETRANSMIT_CNT\t3\n\n/**\n * Media channel.\n */\nstruct pjmedia_channel\n{\n    pjmedia_stream\t   *stream;\t    /**< Parent stream.\t\t    */\n    pjmedia_dir\t\t    dir;\t    /**< Channel direction.\t    */\n    unsigned\t\t    pt;\t\t    /**< Payload type.\t\t    */\n    pj_bool_t\t\t    paused;\t    /**< Paused?.\t\t    */\n    unsigned\t\t    out_pkt_size;   /**< Size of output buffer.\t    */\n    void\t\t   *out_pkt;\t    /**< Output buffer.\t\t    */\n    unsigned                out_pkt_len;    /**< Length of data in buffer.  */\n    pjmedia_rtp_session\t    rtp;\t    /**< RTP session.\t\t    */\n};\n\n\nstruct dtmf\n{\n    int\t\t    event;\n    pj_uint32_t\t    duration;\n    int\t\t    ebit_cnt;\t\t    /**< # of E bit transmissions   */\n};\n\n/**\n * This structure describes media stream.\n * A media stream is bidirectional media transmission between two endpoints.\n * It consists of two channels, i.e. encoding and decoding channels.\n * A media stream corresponds to a single \"m=\" line in a SDP session\n * description.\n */\nstruct pjmedia_stream\n{\n    pjmedia_endpt\t    *endpt;\t    /**< Media endpoint.\t    */\n    pjmedia_codec_mgr\t    *codec_mgr;\t    /**< Codec manager instance.    */\n    pjmedia_stream_info\t     si;\t    /**< Creation parameter.        */\n    pjmedia_port\t     port;\t    /**< Port interface.\t    */\n    pjmedia_channel\t    *enc;\t    /**< Encoding channel.\t    */\n    pjmedia_channel\t    *dec;\t    /**< Decoding channel.\t    */\n\n    pj_pool_t\t\t    *own_pool;\t    /**< Only created if not given  */\n\n    pjmedia_dir\t\t     dir;\t    /**< Stream direction.\t    */\n    void\t\t    *user_data;\t    /**< User data.\t\t    */\n    pj_str_t\t\t     cname;\t    /**< SDES CNAME\t\t    */\n\n    pjmedia_transport\t    *transport;\t    /**< Stream transport.\t    */\n\n    pjmedia_codec\t    *codec;\t    /**< Codec instance being used. */\n    pjmedia_codec_param\t     codec_param;   /**< Codec param.\t\t    */\n    pj_int16_t\t\t    *enc_buf;\t    /**< Encoding buffer, when enc's\n\t\t\t\t\t\t ptime is different than dec.\n\t\t\t\t\t\t Otherwise it's NULL.\t    */\n\n    unsigned\t\t     enc_samples_per_pkt;\n    unsigned\t\t     enc_buf_size;  /**< Encoding buffer size, in\n\t\t\t\t\t\t samples.\t\t    */\n    unsigned\t\t     enc_buf_pos;   /**< First position in buf.\t    */\n    unsigned\t\t     enc_buf_count; /**< Number of samples in the\n\t\t\t\t\t\t encoding buffer.\t    */\n\n    unsigned\t\t     plc_cnt;\t    /**< # of consecutive PLC frames*/\n    unsigned\t\t     max_plc_cnt;   /**< Max # of PLC frames\t    */\n\n    unsigned\t\t     vad_enabled;   /**< VAD enabled in param.\t    */\n    unsigned\t\t     frame_size;    /**< Size of encoded base frame.*/\n    pj_bool_t\t\t     is_streaming;  /**< Currently streaming?. This\n\t\t\t\t\t\t is used to put RTP marker\n\t\t\t\t\t\t bit.\t\t\t    */\n    pj_uint32_t\t\t     ts_vad_disabled;/**< TS when VAD was disabled. */\n    pj_uint32_t\t\t     tx_duration;   /**< TX duration in timestamp.  */\n\n    pj_mutex_t\t\t    *jb_mutex;\n    pjmedia_jbuf\t    *jb;\t    /**< Jitter buffer.\t\t    */\n    char\t\t     jb_last_frm;   /**< Last frame type from jb    */\n    unsigned\t\t     jb_last_frm_cnt;/**< Last JB frame type counter*/\n\n    pjmedia_rtcp_session     rtcp;\t    /**< RTCP for incoming RTP.\t    */\n\n    pj_uint32_t\t\t     rtcp_last_tx;  /**< RTCP tx time in timestamp  */\n    pj_uint32_t\t\t     rtcp_interval; /**< Interval, in timestamp.    */\n    pj_bool_t\t\t     initial_rr;    /**< Initial RTCP RR sent\t    */\n    pj_bool_t                rtcp_sdes_bye_disabled;/**< Send RTCP SDES/BYE?*/\n    void\t\t    *out_rtcp_pkt;  /**< Outgoing RTCP packet.\t    */\n    unsigned\t\t     out_rtcp_pkt_size;\n\t\t\t\t\t    /**< Outgoing RTCP packet size. */\n\n    /* RFC 2833 DTMF transmission queue: */\n    int\t\t\t     tx_event_pt;   /**< Outgoing pt for dtmf.\t    */\n    int\t\t\t     tx_dtmf_count; /**< # of digits in tx dtmf buf.*/\n    struct dtmf\t\t     tx_dtmf_buf[32];/**< Outgoing dtmf queue.\t    */\n\n    /* Incoming DTMF: */\n    int\t\t\t     rx_event_pt;   /**< Incoming pt for dtmf.\t    */\n    int\t\t\t     last_dtmf;\t    /**< Current digit, or -1.\t    */\n    pj_uint32_t\t\t     last_dtmf_dur; /**< Start ts for cur digit.    */\n    unsigned\t\t     rx_dtmf_count; /**< # of digits in dtmf rx buf.*/\n    char\t\t     rx_dtmf_buf[32];/**< Incoming DTMF buffer.\t    */\n\n    /* DTMF callback */\n    void\t\t    (*dtmf_cb)(pjmedia_stream*, void*, int);\n    void\t\t     *dtmf_cb_user_data;\n\n#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)\n    /* Enable support to handle codecs with inconsistent clock rate\n     * between clock rate in SDP/RTP & the clock rate that is actually used.\n     * This happens for example with G.722 and MPEG audio codecs.\n     */\n    pj_bool_t\t\t     has_g722_mpeg_bug;\n\t\t\t\t\t    /**< Flag to specify whether\n\t\t\t\t\t\t normalization process\n\t\t\t\t\t\t is needed\t\t    */\n    unsigned\t\t     rtp_tx_ts_len_per_pkt;\n\t\t\t\t\t    /**< Normalized ts length per packet\n\t\t\t\t\t\t transmitted according to\n\t\t\t\t\t\t 'erroneous' definition\t    */\n    unsigned\t\t     rtp_rx_ts_len_per_frame;\n\t\t\t\t\t    /**< Normalized ts length per frame\n\t\t\t\t\t\t received according to\n\t\t\t\t\t\t 'erroneous' definition\t    */\n    unsigned\t\t     rtp_rx_last_cnt;/**< Nb of frames in last pkt  */\n    unsigned\t\t     rtp_rx_check_cnt;\n\t\t\t\t\t    /**< Counter of remote timestamp\n\t\t\t\t\t\t checking */\n#endif\n\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n    pj_uint32_t\t\t     rtcp_xr_last_tx;  /**< RTCP XR tx time\n\t\t\t\t\t            in timestamp.           */\n    pj_uint32_t\t\t     rtcp_xr_interval; /**< Interval, in timestamp. */\n    pj_sockaddr\t\t     rtcp_xr_dest;     /**< Additional remote RTCP XR\n\t\t\t\t\t\t    dest. If sin_family is\n\t\t\t\t\t\t    zero, it will be ignored*/\n    unsigned\t\t     rtcp_xr_dest_len; /**< Length of RTCP XR dest\n\t\t\t\t\t            address\t\t    */\n#endif\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0\n    pj_bool_t\t\t     use_ka;\t       /**< Stream keep-alive with non-\n\t\t\t\t\t\t    codec-VAD mechanism is\n\t\t\t\t\t\t    enabled?\t\t    */\n    pj_timestamp\t     last_frm_ts_sent; /**< Timestamp of last sending\n\t\t\t\t\t            packet\t\t    */\n#endif\n\n#if TRACE_JB\n    pj_oshandle_t\t    trace_jb_fd;\t    /**< Jitter tracing file handle.*/\n    char\t\t   *trace_jb_buf;\t    /**< Jitter tracing buffer.\t    */\n#endif\n\n    pj_uint32_t\t\t     rtp_rx_last_ts;        /**< Last received RTP timestamp*/\n    pj_status_t\t\t     rtp_rx_last_err;       /**< Last RTP recv() error */\n};\n\n\n/* RFC 2833 digit */\nstatic const char digitmap[17] = { '0', '1', '2', '3',\n\t\t\t\t   '4', '5', '6', '7',\n\t\t\t\t   '8', '9', '*', '#',\n\t\t\t\t   'A', 'B', 'C', 'D', \n\t\t\t\t   'R'};\n\n/* Zero audio frame samples */\nstatic pj_int16_t zero_frame[2 * 30 * 16000 / 1000];\n\n/*\n * Print error.\n */\nstatic void stream_perror(const char *sender, const char *title,\n\t\t\t  pj_status_t status)\n{\n    char errmsg[PJ_ERR_MSG_SIZE];\n\n    pj_strerror(status, errmsg, sizeof(errmsg));\n    PJ_LOG(4,(sender, \"%s: %s [err:%d]\", title, errmsg, status));\n}\n\n\nstatic pj_status_t send_rtcp(pjmedia_stream *stream,\n\t\t\t     pj_bool_t with_sdes,\n\t\t\t     pj_bool_t with_bye,\n\t\t\t     pj_bool_t with_xr);\n\n\n#if TRACE_JB\n\nPJ_INLINE(int) trace_jb_print_timestamp(char **buf, pj_ssize_t len)\n{\n    pj_time_val now;\n    pj_parsed_time ptime;\n    char *p = *buf;\n\n    if (len < 14)\n\treturn -1;\n\n    pj_gettimeofday(&now);\n    pj_time_decode(&now, &ptime);\n    p += pj_utoa_pad(ptime.hour, p, 2, '0');\n    *p++ = ':';\n    p += pj_utoa_pad(ptime.min, p, 2, '0');\n    *p++ = ':';\n    p += pj_utoa_pad(ptime.sec, p, 2, '0');\n    *p++ = '.';\n    p += pj_utoa_pad(ptime.msec, p, 3, '0');\n    *p++ = ',';\n\n    *buf = p;\n\n    return 0;\n}\n\nPJ_INLINE(int) trace_jb_print_state(pjmedia_stream *stream,\n\t\t\t\t    char **buf, pj_ssize_t len)\n{\n    char *p = *buf;\n    char *endp = *buf + len;\n    pjmedia_jb_state state;\n\n    pjmedia_jbuf_get_state(stream->jb, &state);\n\n    len = pj_ansi_snprintf(p, endp-p, \"%d, %d, %d\",\n\t\t\t   state.size, state.burst, state.prefetch);\n    if ((len < 0) || (len >= endp-p))\n\treturn -1;\n\n    p += len;\n    *buf = p;\n    return 0;\n}\n\nstatic void trace_jb_get(pjmedia_stream *stream, pjmedia_jb_frame_type ft,\n\t\t\t pj_size_t fsize)\n{\n    char *p = stream->trace_jb_buf;\n    char *endp = stream->trace_jb_buf + PJ_LOG_MAX_SIZE;\n    pj_ssize_t len = 0;\n    const char* ft_st;\n\n    if (!TRACE_JB_OPENED(stream))\n\treturn;\n\n    /* Print timestamp. */\n    if (trace_jb_print_timestamp(&p, endp-p))\n\tgoto on_insuff_buffer;\n\n    /* Print frame type and size */\n    switch(ft) {\n\tcase PJMEDIA_JB_MISSING_FRAME:\n\t    ft_st = \"missing\";\n\t    break;\n\tcase PJMEDIA_JB_NORMAL_FRAME:\n\t    ft_st = \"normal\";\n\t    break;\n\tcase PJMEDIA_JB_ZERO_PREFETCH_FRAME:\n\t    ft_st = \"prefetch\";\n\t    break;\n\tcase PJMEDIA_JB_ZERO_EMPTY_FRAME:\n\t    ft_st = \"empty\";\n\t    break;\n\tdefault:\n\t    ft_st = \"unknown\";\n\t    break;\n    }\n\n    /* Print operation, size, frame count, frame type */\n    len = pj_ansi_snprintf(p, endp-p, \"GET,%d,1,%s,,,,\", fsize, ft_st);\n    if ((len < 0) || (len >= endp-p))\n\tgoto on_insuff_buffer;\n    p += len;\n\n    /* Print JB state */\n    if (trace_jb_print_state(stream, &p, endp-p))\n\tgoto on_insuff_buffer;\n\n    /* Print end of line */\n    if (endp-p < 2)\n\tgoto on_insuff_buffer;\n    *p++ = '\\n';\n\n    /* Write and flush */\n    len = p - stream->trace_jb_buf;\n    pj_file_write(stream->trace_jb_fd, stream->trace_jb_buf, &len);\n    pj_file_flush(stream->trace_jb_fd);\n    return;\n\non_insuff_buffer:\n    pj_assert(!\"Trace buffer too small, check PJ_LOG_MAX_SIZE!\");\n}\n\nstatic void trace_jb_put(pjmedia_stream *stream, const pjmedia_rtp_hdr *hdr,\n\t\t\t unsigned payloadlen, unsigned frame_cnt)\n{\n    char *p = stream->trace_jb_buf;\n    char *endp = stream->trace_jb_buf + PJ_LOG_MAX_SIZE;\n    pj_ssize_t len = 0;\n\n    if (!TRACE_JB_OPENED(stream))\n\treturn;\n\n    /* Print timestamp. */\n    if (trace_jb_print_timestamp(&p, endp-p))\n\tgoto on_insuff_buffer;\n\n    /* Print operation, size, frame count, RTP info */\n    len = pj_ansi_snprintf(p, endp-p,\n\t\t\t   \"PUT,%d,%d,,%d,%d,%d,\",\n\t\t\t   payloadlen, frame_cnt,\n\t\t\t   pj_ntohs(hdr->seq), pj_ntohl(hdr->ts), hdr->m);\n    if ((len < 0) || (len >= endp-p))\n\tgoto on_insuff_buffer;\n    p += len;\n\n    /* Print JB state */\n    if (trace_jb_print_state(stream, &p, endp-p))\n\tgoto on_insuff_buffer;\n\n    /* Print end of line */\n    if (endp-p < 2)\n\tgoto on_insuff_buffer;\n    *p++ = '\\n';\n\n    /* Write and flush */\n    len = p - stream->trace_jb_buf;\n    pj_file_write(stream->trace_jb_fd, stream->trace_jb_buf, &len);\n    pj_file_flush(stream->trace_jb_fd);\n    return;\n\non_insuff_buffer:\n    pj_assert(!\"Trace buffer too small, check PJ_LOG_MAX_SIZE!\");\n}\n\n#endif /* TRACE_JB */\n\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0\n/*\n * Send keep-alive packet using non-codec frame.\n */\nstatic void send_keep_alive_packet(pjmedia_stream *stream)\n{\n#if PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_EMPTY_RTP\n\n    /* Keep-alive packet is empty RTP */\n    pj_status_t status;\n    void *pkt;\n    int pkt_len;\n\n    TRC_((stream->port.info.name.ptr,\n\t  \"Sending keep-alive (RTCP and empty RTP)\"));\n\n    /* Send RTP */\n    status = pjmedia_rtp_encode_rtp( &stream->enc->rtp,\n\t\t\t\t     stream->enc->pt, 0,\n\t\t\t\t     1,\n\t\t\t\t     0,\n\t\t\t\t     (const void**)&pkt,\n\t\t\t\t     &pkt_len);\n    pj_assert(status == PJ_SUCCESS);\n\n    pj_memcpy(stream->enc->out_pkt, pkt, pkt_len);\n    pjmedia_transport_send_rtp(stream->transport, stream->enc->out_pkt,\n\t\t\t       pkt_len);\n\n    /* Send RTCP */\n    send_rtcp(stream, PJ_TRUE, PJ_FALSE, PJ_FALSE);\n\n#elif PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER\n\n    /* Keep-alive packet is defined in PJMEDIA_STREAM_KA_USER_PKT */\n    int pkt_len;\n    const pj_str_t str_ka = PJMEDIA_STREAM_KA_USER_PKT;\n\n    TRC_((stream->port.info.name.ptr,\n\t  \"Sending keep-alive (custom RTP/RTCP packets)\"));\n\n    /* Send to RTP port */\n    pj_memcpy(stream->enc->out_pkt, str_ka.ptr, str_ka.slen);\n    pkt_len = str_ka.slen;\n    pjmedia_transport_send_rtp(stream->transport, stream->enc->out_pkt,\n\t\t\t       pkt_len);\n\n    /* Send to RTCP port */\n    pjmedia_transport_send_rtcp(stream->transport, stream->enc->out_pkt,\n\t\t\t        pkt_len);\n\n#else\n\n    PJ_UNUSED_ARG(stream);\n\n#endif\n}\n#endif\t/* defined(PJMEDIA_STREAM_ENABLE_KA) */\n\n/*\n * play_callback()\n *\n * This callback is called by sound device's player thread when it\n * needs to feed the player with some frames.\n */\nstatic pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)\n{\n    pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;\n    pjmedia_channel *channel = stream->dec;\n    unsigned samples_count, samples_per_frame, samples_required;\n    pj_int16_t *p_out_samp;\n    pj_status_t status;\n\n\n    /* Return no frame is channel is paused */\n    if (channel->paused) {\n\tframe->type = PJMEDIA_FRAME_TYPE_NONE;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Repeat get frame from the jitter buffer and decode the frame\n     * until we have enough frames according to codec's ptime.\n     */\n\n    /* Lock jitter buffer mutex first */\n    pj_mutex_lock( stream->jb_mutex );\n\n    samples_required = PJMEDIA_PIA_SPF(&stream->port.info);\n    samples_per_frame = stream->codec_param.info.frm_ptime *\n\t\t\tstream->codec_param.info.clock_rate *\n\t\t\tstream->codec_param.info.channel_cnt /\n\t\t\t1000;\n    p_out_samp = (pj_int16_t*) frame->buf;\n\n    for (samples_count=0; samples_count < samples_required;\n\t samples_count += samples_per_frame)\n    {\n\tchar frame_type;\n\tpj_size_t frame_size;\n\tpj_uint32_t bit_info;\n\n\t/* Get frame from jitter buffer. */\n\tpjmedia_jbuf_get_frame2(stream->jb, channel->out_pkt, &frame_size,\n\t\t\t        &frame_type, &bit_info);\n\n#if TRACE_JB\n\ttrace_jb_get(stream, frame_type, frame_size);\n#endif\n\n\tif (frame_type == PJMEDIA_JB_MISSING_FRAME) {\n\n\t    /* Activate PLC */\n\t    if (stream->codec->op->recover &&\n\t\tstream->codec_param.setting.plc &&\n\t\tstream->plc_cnt < stream->max_plc_cnt)\n\t    {\n\t\tpjmedia_frame frame_out;\n\n\t\tframe_out.buf = p_out_samp + samples_count;\n\t\tframe_out.size = frame->size - samples_count*2;\n\t\tstatus = pjmedia_codec_recover(stream->codec,\n\t\t\t\t\t       (unsigned)frame_out.size,\n\t\t\t\t\t       &frame_out);\n\n\t\t++stream->plc_cnt;\n\n\t    } else {\n\t\tstatus = -1;\n\t    }\n\n\t    if (status != PJ_SUCCESS) {\n\t\t/* Either PLC failed or PLC not supported/enabled */\n\t\tpjmedia_zero_samples(p_out_samp + samples_count,\n\t\t\t\t     samples_required - samples_count);\n\t    }\n\n\t    if (frame_type != stream->jb_last_frm) {\n\t\t/* Report changing frame type event */\n\t\tPJ_LOG(5,(stream->port.info.name.ptr, \"Frame lost%s!\",\n\t\t          (status == PJ_SUCCESS? \", recovered\":\"\")));\n\n\t\tstream->jb_last_frm = frame_type;\n\t\tstream->jb_last_frm_cnt = 1;\n\t    } else {\n\t\tstream->jb_last_frm_cnt++;\n\t    }\n\n\t} else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) {\n\n\t    const char *with_plc = \"\";\n\n\t    /* Jitter buffer is empty. If this is the first \"empty\" state,\n\t     * activate PLC to smoothen the fade-out, otherwise zero\n\t     * the frame.\n\t     */\n\t    //Using this \"if\" will only invoke PLC for the first packet\n\t    //lost and not the subsequent ones.\n\t    //if (frame_type != stream->jb_last_frm) {\n\t    if (1) {\n\t\t/* Activate PLC to smoothen the missing frame */\n\t\tif (stream->codec->op->recover &&\n\t\t    stream->codec_param.setting.plc &&\n\t\t    stream->plc_cnt < stream->max_plc_cnt)\n\t\t{\n\t\t    pjmedia_frame frame_out;\n\n\t\t    do {\n\t\t\tframe_out.buf = p_out_samp + samples_count;\n\t\t\tframe_out.size = frame->size - samples_count*2;\n\t\t\tstatus = pjmedia_codec_recover(stream->codec,\n\t\t\t\t\t\t       (unsigned)frame_out.size,\n\t\t\t\t\t\t       &frame_out);\n\t\t\tif (status != PJ_SUCCESS)\n\t\t\t    break;\n\n\t\t\tsamples_count += samples_per_frame;\n\t\t\t++stream->plc_cnt;\n\n\t\t    } while (samples_count < samples_required &&\n\t\t\t     stream->plc_cnt < stream->max_plc_cnt);\n\n\t\t    with_plc = \", plc invoked\";\n\t\t}\n\t    }\n\n\t    if (samples_count < samples_required) {\n\t\tpjmedia_zero_samples(p_out_samp + samples_count,\n\t\t\t\t     samples_required - samples_count);\n\t\tsamples_count = samples_required;\n\t    }\n\n\t    if (stream->jb_last_frm != frame_type) {\n\t\tpjmedia_jb_state jb_state;\n\n\t\t/* Report changing frame type event */\n\t\tpjmedia_jbuf_get_state(stream->jb, &jb_state);\n\t\tPJ_LOG(5,(stream->port.info.name.ptr,\n\t\t\t  \"Jitter buffer empty (prefetch=%d)%s\",\n\t\t\t  jb_state.prefetch, with_plc));\n\n\t\tstream->jb_last_frm = frame_type;\n\t\tstream->jb_last_frm_cnt = 1;\n\t    } else {\n\t\tstream->jb_last_frm_cnt++;\n\t    }\n\t    break;\n\n\t} else if (frame_type != PJMEDIA_JB_NORMAL_FRAME) {\n\n\t    const char *with_plc = \"\";\n\n\t    /* It can only be PJMEDIA_JB_ZERO_PREFETCH frame */\n\t    pj_assert(frame_type == PJMEDIA_JB_ZERO_PREFETCH_FRAME);\n\n\t    /* Always activate PLC when it's available.. */\n\t    if (stream->codec->op->recover &&\n\t\tstream->codec_param.setting.plc &&\n\t\tstream->plc_cnt < stream->max_plc_cnt)\n\t    {\n\t\tpjmedia_frame frame_out;\n\n\t\tdo {\n\t\t    frame_out.buf = p_out_samp + samples_count;\n\t\t    frame_out.size = frame->size - samples_count*2;\n\t\t    status = pjmedia_codec_recover(stream->codec,\n\t\t\t\t\t\t   (unsigned)frame_out.size,\n\t\t\t\t\t\t   &frame_out);\n\t\t    if (status != PJ_SUCCESS)\n\t\t\tbreak;\n\t\t    samples_count += samples_per_frame;\n\n\t\t    ++stream->plc_cnt;\n\n\t\t} while (samples_count < samples_required &&\n\t\t\t stream->plc_cnt < stream->max_plc_cnt);\n\n\t\twith_plc = \", plc invoked\";\n\t    }\n\n\t    if (samples_count < samples_required) {\n\t\tpjmedia_zero_samples(p_out_samp + samples_count,\n\t\t\t\t     samples_required - samples_count);\n\t\tsamples_count = samples_required;\n\t    }\n\n\t    if (stream->jb_last_frm != frame_type) {\n\t\tpjmedia_jb_state jb_state;\n\n\t\t/* Report changing frame type event */\n\t\tpjmedia_jbuf_get_state(stream->jb, &jb_state);\n\t\tPJ_LOG(5,(stream->port.info.name.ptr,\n\t\t\t  \"Jitter buffer is bufferring (prefetch=%d)%s\",\n\t\t\t  jb_state.prefetch, with_plc));\n\n\t\tstream->jb_last_frm = frame_type;\n\t\tstream->jb_last_frm_cnt = 1;\n\t    } else {\n\t\tstream->jb_last_frm_cnt++;\n\t    }\n\t    break;\n\n\t} else {\n\t    /* Got \"NORMAL\" frame from jitter buffer */\n\t    pjmedia_frame frame_in, frame_out;\n\n\t    stream->plc_cnt = 0;\n\n\t    /* Decode */\n\t    frame_in.buf = channel->out_pkt;\n\t    frame_in.size = frame_size;\n\t    frame_in.bit_info = bit_info;\n\t    frame_in.type = PJMEDIA_FRAME_TYPE_AUDIO;  /* ignored */\n\n\t    frame_out.buf = p_out_samp + samples_count;\n\t    frame_out.size = frame->size - samples_count*BYTES_PER_SAMPLE;\n\t    status = pjmedia_codec_decode( stream->codec, &frame_in,\n\t\t\t\t\t   (unsigned)frame_out.size,\n\t\t\t\t\t   &frame_out);\n\t    if (status != 0) {\n\t\tLOGERR_((port->info.name.ptr, \"codec decode() error\",\n\t\t\t status));\n\n\t\tpjmedia_zero_samples(p_out_samp + samples_count,\n\t\t\t\t     samples_per_frame);\n\t    }\n\n\t    if (stream->jb_last_frm != frame_type) {\n\t\t/* Report changing frame type event */\n\t\tPJ_LOG(5,(stream->port.info.name.ptr,\n\t\t\t  \"Jitter buffer starts returning normal frames \"\n\t\t\t  \"(after %d empty/lost)\",\n\t\t\t  stream->jb_last_frm_cnt, stream->jb_last_frm));\n\n\t\tstream->jb_last_frm = frame_type;\n\t\tstream->jb_last_frm_cnt = 1;\n\t    } else {\n\t\tstream->jb_last_frm_cnt++;\n\t    }\n\t}\n    }\n\n\n    /* Unlock jitter buffer mutex. */\n    pj_mutex_unlock( stream->jb_mutex );\n\n    /* Return PJMEDIA_FRAME_TYPE_NONE if we have no frames at all\n     * (it can happen when jitter buffer returns PJMEDIA_JB_ZERO_EMPTY_FRAME).\n     */\n    if (samples_count == 0) {\n\tframe->type = PJMEDIA_FRAME_TYPE_NONE;\n\tframe->size = 0;\n    } else {\n\tframe->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframe->size = samples_count * BYTES_PER_SAMPLE;\n\tframe->timestamp.u64 = 0;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* The other version of get_frame callback used when stream port format\n * is non linear PCM.\n */\nstatic pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)\n{\n    pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;\n    pjmedia_channel *channel = stream->dec;\n    pjmedia_frame_ext *f = (pjmedia_frame_ext*)frame;\n    unsigned samples_per_frame, samples_required;\n    pj_status_t status;\n\n    /* Return no frame if channel is paused */\n    if (channel->paused) {\n\tframe->type = PJMEDIA_FRAME_TYPE_NONE;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Repeat get frame from the jitter buffer and decode the frame\n     * until we have enough frames according to codec's ptime.\n     */\n\n    samples_required = PJMEDIA_PIA_SPF(&stream->port.info);\n    samples_per_frame = stream->codec_param.info.frm_ptime *\n\t\t\tstream->codec_param.info.clock_rate *\n\t\t\tstream->codec_param.info.channel_cnt /\n\t\t\t1000;\n\n    pj_bzero(f, sizeof(pjmedia_frame_ext));\n    f->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;\n\n    while (f->samples_cnt < samples_required) {\n\tchar frame_type;\n\tpj_size_t frame_size;\n\tpj_uint32_t bit_info;\n\n\t/* Lock jitter buffer mutex first */\n\tpj_mutex_lock( stream->jb_mutex );\n\n\t/* Get frame from jitter buffer. */\n\tpjmedia_jbuf_get_frame2(stream->jb, channel->out_pkt, &frame_size,\n\t\t\t        &frame_type, &bit_info);\n\n#if TRACE_JB\n\ttrace_jb_get(stream, frame_type, frame_size);\n#endif\n\n\t/* Unlock jitter buffer mutex. */\n\tpj_mutex_unlock( stream->jb_mutex );\n\n\tif (frame_type == PJMEDIA_JB_NORMAL_FRAME) {\n\t    /* Got \"NORMAL\" frame from jitter buffer */\n\t    pjmedia_frame frame_in;\n\n\t    /* Decode */\n\t    frame_in.buf = channel->out_pkt;\n\t    frame_in.size = frame_size;\n\t    frame_in.bit_info = bit_info;\n\t    frame_in.type = PJMEDIA_FRAME_TYPE_AUDIO;\n\n\t    status = pjmedia_codec_decode( stream->codec, &frame_in,\n\t\t\t\t\t   0, frame);\n\t    if (status != PJ_SUCCESS) {\n\t\tLOGERR_((port->info.name.ptr, \"codec decode() error\",\n\t\t\t status));\n\t\tpjmedia_frame_ext_append_subframe(f, NULL, 0,\n\t\t\t\t\t    (pj_uint16_t)samples_per_frame);\n\t    }\n\n\t    if (stream->jb_last_frm != frame_type) {\n\t\t/* Report changing frame type event */\n\t\tPJ_LOG(5,(stream->port.info.name.ptr,\n\t\t\t  \"Jitter buffer starts returning normal frames \"\n\t\t\t  \"(after %d empty/lost)\",\n\t\t\t  stream->jb_last_frm_cnt, stream->jb_last_frm));\n\n\t\tstream->jb_last_frm = frame_type;\n\t\tstream->jb_last_frm_cnt = 1;\n\t    } else {\n\t\tstream->jb_last_frm_cnt++;\n\t    }\n\n\t} else {\n\n\t    /* Try to generate frame by invoking PLC (when any) */\n\t    status = PJ_SUCCESS;\n\t    if (stream->codec->op->recover) {\n\t\tstatus = pjmedia_codec_recover(stream->codec, 0, frame);\n\t    }\n\n\t    /* No PLC or PLC failed */\n\t    if (!stream->codec->op->recover || status != PJ_SUCCESS) {\n\t\tpjmedia_frame_ext_append_subframe(f, NULL, 0,\n\t\t\t\t\t    (pj_uint16_t)samples_per_frame);\n\t    }\n\n\t    if (frame_type == PJMEDIA_JB_MISSING_FRAME) {\n\t\tif (frame_type != stream->jb_last_frm) {\n\t\t    /* Report changing frame type event */\n\t\t    PJ_LOG(5,(stream->port.info.name.ptr, \"Frame lost!\"));\n\n\t\t    stream->jb_last_frm = frame_type;\n\t\t    stream->jb_last_frm_cnt = 1;\n\t\t} else {\n\t\t    stream->jb_last_frm_cnt++;\n\t\t}\n\t    } else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) {\n\t\tif (frame_type != stream->jb_last_frm) {\n\t\t    pjmedia_jb_state jb_state;\n\n\t\t    /* Report changing frame type event */\n\t\t    pjmedia_jbuf_get_state(stream->jb, &jb_state);\n\t\t    PJ_LOG(5,(stream->port.info.name.ptr,\n\t\t\t      \"Jitter buffer empty (prefetch=%d)\",\n\t\t\t      jb_state.prefetch));\n\n\t\t    stream->jb_last_frm = frame_type;\n\t\t    stream->jb_last_frm_cnt = 1;\n\t\t} else {\n\t\t    stream->jb_last_frm_cnt++;\n\t\t}\n\t    } else {\n\n\t\t/* It can only be PJMEDIA_JB_ZERO_PREFETCH frame */\n\t\tpj_assert(frame_type == PJMEDIA_JB_ZERO_PREFETCH_FRAME);\n\n\t\tif (stream->jb_last_frm != frame_type) {\n\t\t    pjmedia_jb_state jb_state;\n\n\t\t    /* Report changing frame type event */\n\t\t    pjmedia_jbuf_get_state(stream->jb, &jb_state);\n\t\t    PJ_LOG(5,(stream->port.info.name.ptr,\n\t\t\t      \"Jitter buffer is bufferring (prefetch=%d)\",\n\t\t\t      jb_state.prefetch));\n\n\t\t    stream->jb_last_frm = frame_type;\n\t\t    stream->jb_last_frm_cnt = 1;\n\t\t} else {\n\t\t    stream->jb_last_frm_cnt++;\n\t\t}\n\t    }\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Transmit DTMF\n */\nstatic void create_dtmf_payload(pjmedia_stream *stream,\n\t\t\t        struct pjmedia_frame *frame_out,\n\t\t\t        int forced_last, int *first, int *last)\n{\n    pjmedia_rtp_dtmf_event *event;\n    struct dtmf *digit = &stream->tx_dtmf_buf[0];\n\n    pj_assert(sizeof(pjmedia_rtp_dtmf_event) == 4);\n\n    *first = *last = 0;\n\n    event = (pjmedia_rtp_dtmf_event*) frame_out->buf;\n\n    if (digit->duration == 0) {\n\tPJ_LOG(5,(stream->port.info.name.ptr, \"Sending DTMF digit id %c\",\n\t\t  digitmap[digit->event]));\n\t*first = 1;\n    }\n\n    digit->duration += PJMEDIA_PIA_SPF(&stream->port.info);\n    if (digit->duration >= PJMEDIA_DTMF_DURATION)\n\tdigit->duration = PJMEDIA_DTMF_DURATION;\n\n    event->event = (pj_uint8_t)digit->event;\n    event->e_vol = 10;\n    event->duration = pj_htons((pj_uint16_t)digit->duration);\n\n    if (forced_last) {\n\tdigit->duration = PJMEDIA_DTMF_DURATION;\n    }\n\n    if (digit->duration >= PJMEDIA_DTMF_DURATION) {\n\n\tevent->e_vol |= 0x80;\n\n\tif (++digit->ebit_cnt >= DTMF_EBIT_RETRANSMIT_CNT) {\n\t    *last = 1;\n\n\t    /* Prepare next digit. */\n\t    pj_mutex_lock(stream->jb_mutex);\n\n\t    pj_array_erase(stream->tx_dtmf_buf, sizeof(stream->tx_dtmf_buf[0]),\n\t\t\t   stream->tx_dtmf_count, 0);\n\t    --stream->tx_dtmf_count;\n\n\t    pj_mutex_unlock(stream->jb_mutex);\n\t}\n    }\n\n    frame_out->size = 4;\n}\n\n\nstatic pj_status_t send_rtcp(pjmedia_stream *stream,\n\t\t\t     pj_bool_t with_sdes,\n\t\t\t     pj_bool_t with_bye,\n\t\t\t     pj_bool_t with_xr)\n{\n    void *sr_rr_pkt;\n    pj_uint8_t *pkt;\n    int len, max_len;\n    pj_status_t status;\n\n    /* Build RTCP RR/SR packet */\n    pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len);\n\n#if !defined(PJMEDIA_HAS_RTCP_XR) || (PJMEDIA_HAS_RTCP_XR == 0)\n    with_xr = PJ_FALSE;\n#endif\n\n    if (with_sdes || with_bye || with_xr) {\n\tpkt = (pj_uint8_t*) stream->out_rtcp_pkt;\n\tpj_memcpy(pkt, sr_rr_pkt, len);\n\tmax_len = stream->out_rtcp_pkt_size;\n    } else {\n\tpkt = (pj_uint8_t*)sr_rr_pkt;\n\tmax_len = len;\n    }\n\n    /* Build RTCP SDES packet */\n    if (with_sdes) {\n\tpjmedia_rtcp_sdes sdes;\n\tpj_size_t sdes_len;\n\n\tpj_bzero(&sdes, sizeof(sdes));\n\tsdes.cname = stream->cname;\n\tsdes_len = max_len - len;\n\tstatus = pjmedia_rtcp_build_rtcp_sdes(&stream->rtcp, pkt+len,\n\t\t\t\t\t      &sdes_len, &sdes);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(stream->port.info.name.ptr, status,\n        \t\t\t     \"Error generating RTCP SDES\"));\n\t} else {\n\t    len += (int)sdes_len;\n\t}\n    }\n\n    /* Build RTCP XR packet */\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n    if (with_xr) {\n\tint i;\n\tpjmedia_jb_state jb_state;\n\tvoid *xr_pkt;\n\tint xr_len;\n\n\t/* Update RTCP XR with current JB states */\n\tpjmedia_jbuf_get_state(stream->jb, &jb_state);\n\n\ti = jb_state.avg_delay;\n\tstatus = pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,\n\t\t\t\t\t     PJMEDIA_RTCP_XR_INFO_JB_NOM, i);\n\tpj_assert(status == PJ_SUCCESS);\n\n\ti = jb_state.max_delay;\n\tstatus = pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,\n\t\t\t\t\t     PJMEDIA_RTCP_XR_INFO_JB_MAX, i);\n\tpj_assert(status == PJ_SUCCESS);\n\n\tpjmedia_rtcp_build_rtcp_xr(&stream->rtcp.xr_session, 0,\n\t\t\t\t   &xr_pkt, &xr_len);\n\n\tif (xr_len + len <= max_len) {\n\t    pj_memcpy(pkt+len, xr_pkt, xr_len);\n\t    len += xr_len;\n\n\t    /* Send the RTCP XR to third-party destination if specified */\n\t    if (stream->rtcp_xr_dest_len) {\n\t\tpjmedia_transport_send_rtcp2(stream->transport,\n\t\t\t\t\t     &stream->rtcp_xr_dest,\n\t\t\t\t\t     stream->rtcp_xr_dest_len,\n\t\t\t\t\t     xr_pkt, xr_len);\n\t    }\n\n\t} else {\n\t    PJ_PERROR(4,(stream->port.info.name.ptr, PJ_ETOOBIG,\n        \t\t \"Error generating RTCP-XR\"));\n\t}\n    }\n#endif\n\n    /* Build RTCP BYE packet */\n    if (with_bye) {\n\tpj_size_t bye_len;\n\n\tbye_len = max_len - len;\n\tstatus = pjmedia_rtcp_build_rtcp_bye(&stream->rtcp, pkt+len,\n\t\t\t\t\t     &bye_len, NULL);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(stream->port.info.name.ptr, status,\n        \t\t\t     \"Error generating RTCP BYE\"));\n\t} else {\n\t    len += (int)bye_len;\n\t}\n    }\n\n    /* Send! */\n    status = pjmedia_transport_send_rtcp(stream->transport, pkt, len);\n\n    return status;\n}\n\n/**\n * check_tx_rtcp()\n *\n * This function is can be called by either put_frame() or get_frame(),\n * to transmit periodic RTCP SR/RR report.\n */\nstatic void check_tx_rtcp(pjmedia_stream *stream, pj_uint32_t timestamp)\n{\n    /* Note that timestamp may represent local or remote timestamp,\n     * depending on whether this function is called from put_frame()\n     * or get_frame().\n     */\n\n    if (stream->rtcp_last_tx == 0) {\n\n\tstream->rtcp_last_tx = timestamp;\n\n    } else if (timestamp - stream->rtcp_last_tx >= stream->rtcp_interval) {\n\tpj_bool_t with_xr = PJ_FALSE;\n\tpj_status_t status;\n\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n\tif (stream->rtcp.xr_enabled) {\n\t    if (stream->rtcp_xr_last_tx == 0) {\n\t\tstream->rtcp_xr_last_tx = timestamp;\n\t    } else if (timestamp - stream->rtcp_xr_last_tx >=\n\t\t       stream->rtcp_xr_interval)\n\t    {\n\t\twith_xr = PJ_TRUE;\n\n\t\t/* Update last tx RTCP XR */\n\t\tstream->rtcp_xr_last_tx = timestamp;\n\t    }\n\t}\n#endif\n\n\tstatus = send_rtcp(stream, !stream->rtcp_sdes_bye_disabled, PJ_FALSE,\n\t\t\t   with_xr);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(stream->port.info.name.ptr, status,\n        \t\t \"Error sending RTCP\"));\n\t}\n\n\tstream->rtcp_last_tx = timestamp;\n    }\n}\n\n\n/**\n * Rebuffer the frame when encoder and decoder has different ptime\n * (such as when different iLBC modes are used by local and remote)\n */\nstatic void rebuffer(pjmedia_stream *stream,\n\t\t     pjmedia_frame *frame)\n{\n    /* How many samples are needed */\n    unsigned count;\n\n    /* Normalize frame */\n    if (frame->type != PJMEDIA_FRAME_TYPE_AUDIO)\n\tframe->size = 0;\n\n    /* Remove used frame from the buffer. */\n    if (stream->enc_buf_pos) {\n\tif (stream->enc_buf_count) {\n\t    pj_memmove(stream->enc_buf,\n\t\t       stream->enc_buf + stream->enc_buf_pos,\n\t\t       (stream->enc_buf_count << 1));\n\t}\n\tstream->enc_buf_pos = 0;\n    }\n\n    /* Make sure we have space to store the new frame */\n    pj_assert(stream->enc_buf_count + (frame->size >> 1) <\n\t\tstream->enc_buf_size);\n\n    /* Append new frame to the buffer */\n    if (frame->size) {\n\t/* Handle case when there is no port transmitting to this port */\n\tif (frame->buf) {\n\t    pj_memcpy(stream->enc_buf + stream->enc_buf_count,\n\t\t      frame->buf, frame->size);\n\t} else {\n\t    pj_bzero(stream->enc_buf + stream->enc_buf_count, frame->size);\n\t}\n\tstream->enc_buf_count += ((unsigned)frame->size >> 1);\n    }\n\n    /* How many samples are needed */\n    count = stream->codec_param.info.enc_ptime *\n\t    PJMEDIA_PIA_SRATE(&stream->port.info) / 1000;\n\n    /* See if we have enough samples */\n    if (stream->enc_buf_count >= count) {\n\n\tframe->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframe->buf = stream->enc_buf;\n\tframe->size = (count << 1);\n\n\tstream->enc_buf_pos = count;\n\tstream->enc_buf_count -= count;\n\n    } else {\n\t/* We don't have enough samples */\n\tframe->type = PJMEDIA_FRAME_TYPE_NONE;\n    }\n}\n\n\n/**\n * put_frame_imp()\n */\nstatic pj_status_t put_frame_imp( pjmedia_port *port,\n\t\t\t\t  pjmedia_frame *frame )\n{\n    pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;\n    pjmedia_channel *channel = stream->enc;\n    pj_status_t status = 0;\n    pjmedia_frame frame_out;\n    unsigned ts_len, rtp_ts_len, samples_per_frame;\n    void *rtphdr;\n    int rtphdrlen;\n    int inc_timestamp = 0;\n\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0\n    /* If the interval since last sending packet is greater than\n     * PJMEDIA_STREAM_KA_INTERVAL, send keep-alive packet.\n     */\n    if (stream->use_ka)\n    {\n\tpj_uint32_t dtx_duration;\n\n\tdtx_duration = pj_timestamp_diff32(&stream->last_frm_ts_sent,\n\t\t\t\t\t   &frame->timestamp);\n\tif (dtx_duration >\n\t    PJMEDIA_STREAM_KA_INTERVAL * PJMEDIA_PIA_SRATE(&stream->port.info))\n\t{\n\t    send_keep_alive_packet(stream);\n\t    stream->last_frm_ts_sent = frame->timestamp;\n\t}\n    }\n#endif\n\n    /* Don't do anything if stream is paused */\n    if (channel->paused) {\n\tstream->enc_buf_pos = stream->enc_buf_count = 0;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Number of samples in the frame */\n    if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO)\n\tts_len = ((unsigned)frame->size >> 1) /\n\t\t stream->codec_param.info.channel_cnt;\n    else if (frame->type == PJMEDIA_FRAME_TYPE_EXTENDED)\n\tts_len = PJMEDIA_PIA_SPF(&stream->port.info) /\n\t\t PJMEDIA_PIA_CCNT(&stream->port.info);\n    else\n\tts_len = 0;\n\n    /* Increment transmit duration */\n    stream->tx_duration += ts_len;\n\n#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)\n    /* Handle special case for audio codec with RTP timestamp inconsistence\n     * e.g: G722, MPEG audio.\n     */\n    if (stream->has_g722_mpeg_bug)\n\trtp_ts_len = stream->rtp_tx_ts_len_per_pkt;\n    else\n\trtp_ts_len = ts_len;\n#else\n    rtp_ts_len = ts_len;\n#endif\n\n    /* Init frame_out buffer. */\n    frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr);\n    frame_out.size = 0;\n\n    /* Calculate number of samples per frame */\n    samples_per_frame = stream->enc_samples_per_pkt;\n\n\n    /* If we have DTMF digits in the queue, transmit the digits.\n     * Otherwise encode the PCM buffer.\n     */\n    if (stream->tx_dtmf_count) {\n\tint first=0, last=0;\n\n\tcreate_dtmf_payload(stream, &frame_out, 0, &first, &last);\n\n\t/* Encapsulate into RTP packet. Note that:\n         *  - RTP marker should be set on the beginning of a new event\n\t *  - RTP timestamp is constant for the same packet.\n         */\n\tstatus = pjmedia_rtp_encode_rtp( &channel->rtp,\n\t\t\t\t\t stream->tx_event_pt, first,\n\t\t\t\t\t (int)frame_out.size,\n\t\t\t\t\t (first ? rtp_ts_len : 0),\n\t\t\t\t\t (const void**)&rtphdr,\n\t\t\t\t\t &rtphdrlen);\n\n\tif (last) {\n\t    /* This is the last packet for the event.\n\t     * Increment the RTP timestamp of the RTP session, for next\n\t     * RTP packets.\n\t     */\n\t    inc_timestamp = PJMEDIA_DTMF_DURATION +\n\t\t            ((DTMF_EBIT_RETRANSMIT_CNT-1) * samples_per_frame)\n\t\t            - rtp_ts_len;\n\t}\n\n\n    /*\n     * Special treatment for FRAME_TYPE_AUDIO but with frame->buf==NULL.\n     * This happens when stream input is disconnected from the bridge.\n     * In this case we periodically transmit RTP frame to keep NAT binding\n     * open, by giving zero PCM frame to the codec.\n     *\n     * This was originally done in http://trac.pjsip.org/repos/ticket/56,\n     * but then disabled in http://trac.pjsip.org/repos/ticket/439, but\n     * now it's enabled again.\n     */\n    } else if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO &&\n\t       frame->buf == NULL &&\n\t       stream->port.info.fmt.id == PJMEDIA_FORMAT_L16 &&\n\t       (stream->dir & PJMEDIA_DIR_ENCODING) &&\n\t       stream->enc_samples_per_pkt < PJ_ARRAY_SIZE(zero_frame))\n    {\n\tpjmedia_frame silence_frame;\n\n\tpj_bzero(&silence_frame, sizeof(silence_frame));\n\tsilence_frame.buf = zero_frame;\n\tsilence_frame.size = stream->enc_samples_per_pkt * 2;\n\tsilence_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tsilence_frame.timestamp.u32.lo = pj_ntohl(stream->enc->rtp.out_hdr.ts);\n\n\t/* Encode! */\n\tstatus = pjmedia_codec_encode( stream->codec, &silence_frame,\n\t\t\t\t       channel->out_pkt_size -\n\t\t\t\t       sizeof(pjmedia_rtp_hdr),\n\t\t\t\t       &frame_out);\n\tif (status != PJ_SUCCESS) {\n\t    LOGERR_((stream->port.info.name.ptr,\n\t\t    \"Codec encode() error\", status));\n\t    return status;\n\t}\n\n\t/* Encapsulate. */\n\tstatus = pjmedia_rtp_encode_rtp( &channel->rtp,\n\t\t\t\t\t channel->pt, 0,\n\t\t\t\t\t (int)frame_out.size, rtp_ts_len,\n\t\t\t\t\t (const void**)&rtphdr,\n\t\t\t\t\t &rtphdrlen);\n\n\n    /* Encode audio frame */\n    } else if ((frame->type == PJMEDIA_FRAME_TYPE_AUDIO &&\n\t        frame->buf != NULL) ||\n\t       (frame->type == PJMEDIA_FRAME_TYPE_EXTENDED))\n    {\n\t/* Encode! */\n\tstatus = pjmedia_codec_encode( stream->codec, frame,\n\t\t\t\t       channel->out_pkt_size -\n\t\t\t\t       sizeof(pjmedia_rtp_hdr),\n\t\t\t\t       &frame_out);\n\tif (status != PJ_SUCCESS) {\n\t    LOGERR_((stream->port.info.name.ptr,\n\t\t    \"Codec encode() error\", status));\n\t    return status;\n\t}\n\n\t/* Encapsulate. */\n\tstatus = pjmedia_rtp_encode_rtp( &channel->rtp,\n\t\t\t\t\t channel->pt, 0,\n\t\t\t\t\t (int)frame_out.size, rtp_ts_len,\n\t\t\t\t\t (const void**)&rtphdr,\n\t\t\t\t\t &rtphdrlen);\n\n    } else {\n\n\t/* Just update RTP session's timestamp. */\n\tstatus = pjmedia_rtp_encode_rtp( &channel->rtp,\n\t\t\t\t\t 0, 0,\n\t\t\t\t\t 0, rtp_ts_len,\n\t\t\t\t\t (const void**)&rtphdr,\n\t\t\t\t\t &rtphdrlen);\n\n    }\n\n    if (status != PJ_SUCCESS) {\n\tLOGERR_((stream->port.info.name.ptr,\n\t\t\"RTP encode_rtp() error\", status));\n\treturn status;\n    }\n\n    /* Check if now is the time to transmit RTCP SR/RR report.\n     * We only do this when stream direction is not \"decoding only\", because\n     * when it is, check_tx_rtcp() will be handled by get_frame().\n     */\n    if (stream->dir != PJMEDIA_DIR_DECODING) {\n\tcheck_tx_rtcp(stream, pj_ntohl(channel->rtp.out_hdr.ts));\n    }\n\n    /* Do nothing if we have nothing to transmit */\n    if (frame_out.size == 0) {\n\tif (stream->is_streaming) {\n\t    PJ_LOG(5,(stream->port.info.name.ptr,\"Starting silence\"));\n\t    stream->is_streaming = PJ_FALSE;\n\t}\n\n\treturn PJ_SUCCESS;\n    }\n\n\n    /* Copy RTP header to the beginning of packet */\n    pj_memcpy(channel->out_pkt, rtphdr, sizeof(pjmedia_rtp_hdr));\n\n    /* Special case for DTMF: timestamp remains constant for\n     * the same event, and is only updated after a complete event\n     * has been transmitted.\n     */\n    if (inc_timestamp) {\n\tpjmedia_rtp_encode_rtp( &channel->rtp, stream->tx_event_pt, 0,\n\t\t\t\t0, inc_timestamp, NULL, NULL);\n    }\n\n    /* Set RTP marker bit if currently not streaming */\n    if (stream->is_streaming == PJ_FALSE) {\n\tpjmedia_rtp_hdr *rtp = (pjmedia_rtp_hdr*) channel->out_pkt;\n\n\trtp->m = 1;\n\tPJ_LOG(5,(stream->port.info.name.ptr,\"Start talksprut..\"));\n    }\n\n    stream->is_streaming = PJ_TRUE;\n\n    /* Send the RTP packet to the transport. */\n    status = pjmedia_transport_send_rtp(stream->transport, channel->out_pkt,\n                                        frame_out.size +\n\t\t\t\t\t    sizeof(pjmedia_rtp_hdr));\n    if (status != PJ_SUCCESS) {\n\tPJ_PERROR(4,(stream->port.info.name.ptr, status,\n\t\t     \"Error sending RTP\"));\n\treturn PJ_SUCCESS;\n    }\n\n    /* Update stat */\n    pjmedia_rtcp_tx_rtp(&stream->rtcp, (unsigned)frame_out.size);\n    stream->rtcp.stat.rtp_tx_last_ts = pj_ntohl(stream->enc->rtp.out_hdr.ts);\n    stream->rtcp.stat.rtp_tx_last_seq = pj_ntohs(stream->enc->rtp.out_hdr.seq);\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0\n    /* Update timestamp of last sending packet. */\n    stream->last_frm_ts_sent = frame->timestamp;\n#endif\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * put_frame()\n *\n * This callback is called by upstream component when it has PCM frame\n * to transmit. This function encodes the PCM frame, pack it into\n * RTP packet, and transmit to peer.\n */\nstatic pj_status_t put_frame( pjmedia_port *port,\n\t\t\t      pjmedia_frame *frame )\n{\n    pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;\n    pjmedia_frame tmp_zero_frame;\n    unsigned samples_per_frame;\n\n    samples_per_frame = stream->enc_samples_per_pkt;\n\n    /* http://www.pjsip.org/trac/ticket/56:\n     *  when input is PJMEDIA_FRAME_TYPE_NONE, feed zero PCM frame\n     *  instead so that encoder can decide whether or not to transmit\n     *  silence frame.\n     */\n    if (frame->type == PJMEDIA_FRAME_TYPE_NONE) {\n\tpj_memcpy(&tmp_zero_frame, frame, sizeof(pjmedia_frame));\n\tframe = &tmp_zero_frame;\n\n\ttmp_zero_frame.buf = NULL;\n\ttmp_zero_frame.size = samples_per_frame * 2;\n\ttmp_zero_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;\n    }\n\n#if 0\n    // This is no longer needed because each TYPE_NONE frame will\n    // be converted into zero frame above\n\n    /* If VAD is temporarily disabled during creation, feed zero PCM frame\n     * to the codec.\n     */\n    if (stream->vad_enabled != stream->codec_param.setting.vad &&\n\tstream->vad_enabled != 0 &&\n\tframe->type == PJMEDIA_FRAME_TYPE_NONE &&\n\tsamples_per_frame <= ZERO_PCM_MAX_SIZE)\n    {\n\tpj_memcpy(&tmp_in_frame, frame, sizeof(pjmedia_frame));\n\tframe = &tmp_in_frame;\n\n\ttmp_in_frame.buf = NULL;\n\ttmp_in_frame.size = samples_per_frame * 2;\n\ttmp_in_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;\n    }\n#endif\n\n    /* If VAD is temporarily disabled during creation, enable it\n     * after transmitting for VAD_SUSPEND_SEC seconds.\n     */\n    if (stream->vad_enabled != stream->codec_param.setting.vad &&\n\t(stream->tx_duration - stream->ts_vad_disabled) >\n           PJMEDIA_PIA_SRATE(&stream->port.info) *\n\t  PJMEDIA_STREAM_VAD_SUSPEND_MSEC / 1000)\n    {\n\tstream->codec_param.setting.vad = stream->vad_enabled;\n\tpjmedia_codec_modify(stream->codec, &stream->codec_param);\n\tPJ_LOG(4,(stream->port.info.name.ptr,\"VAD re-enabled\"));\n    }\n\n\n    /* If encoder has different ptime than decoder, then the frame must\n     * be passed through the encoding buffer via rebuffer() function.\n     */\n    if (stream->enc_buf != NULL) {\n\tpjmedia_frame tmp_rebuffer_frame;\n\tpj_status_t status = PJ_SUCCESS;\n\n\t/* Copy original frame to temporary frame since we need\n\t * to modify it.\n\t */\n\tpj_memcpy(&tmp_rebuffer_frame, frame, sizeof(pjmedia_frame));\n\n\t/* Loop while we have full frame in enc_buffer */\n\tfor (;;) {\n\t    pj_status_t st;\n\n\t    /* Run rebuffer() */\n\t    rebuffer(stream, &tmp_rebuffer_frame);\n\n\t    /* Process this frame */\n\t    st = put_frame_imp(port, &tmp_rebuffer_frame);\n\t    if (st != PJ_SUCCESS)\n\t\tstatus = st;\n\n\t    /* If we still have full frame in the buffer, re-run\n\t     * rebuffer() with NULL frame.\n\t     */\n\t    if (stream->enc_buf_count >= stream->enc_samples_per_pkt) {\n\n\t\ttmp_rebuffer_frame.type = PJMEDIA_FRAME_TYPE_NONE;\n\n\t    } else {\n\n\t\t/* Otherwise break */\n\t\tbreak;\n\t    }\n\t}\n\n\treturn status;\n\n    } else {\n\treturn put_frame_imp(port, frame);\n    }\n}\n\n\n#if 0\nstatic void dump_bin(const char *buf, unsigned len)\n{\n    unsigned i;\n\n    PJ_LOG(3,(THIS_FILE, \"begin dump\"));\n    for (i=0; i<len; ++i) {\n\tint j;\n\tchar bits[9];\n\tunsigned val = buf[i] & 0xFF;\n\n\tbits[8] = '\\0';\n\tfor (j=0; j<8; ++j) {\n\t    if (val & (1 << (7-j)))\n\t\tbits[j] = '1';\n\t    else\n\t\tbits[j] = '0';\n\t}\n\n\tPJ_LOG(3,(THIS_FILE, \"%2d %s [%d]\", i, bits, val));\n    }\n    PJ_LOG(3,(THIS_FILE, \"end dump\"));\n}\n#endif\n\n/*\n * Handle incoming DTMF digits.\n */\nstatic void handle_incoming_dtmf( pjmedia_stream *stream,\n\t\t\t\t  const void *payload, unsigned payloadlen)\n{\n    pjmedia_rtp_dtmf_event *event = (pjmedia_rtp_dtmf_event*) payload;\n\n    /* Check compiler packing. */\n    pj_assert(sizeof(pjmedia_rtp_dtmf_event)==4);\n\n    /* Must have sufficient length before we proceed. */\n    if (payloadlen < sizeof(pjmedia_rtp_dtmf_event))\n\treturn;\n\n    //dump_bin(payload, payloadlen);\n\n    /* Check if this is the same/current digit of the last packet. */\n    if (stream->last_dtmf != -1 &&\n\tevent->event == stream->last_dtmf &&\n\tpj_ntohs(event->duration) >= stream->last_dtmf_dur)\n    {\n\t/* Yes, this is the same event. */\n\tstream->last_dtmf_dur = pj_ntohs(event->duration);\n\treturn;\n    }\n\n    /* Ignore unknown event. */\n#if defined(PJMEDIA_HAS_DTMF_FLASH) && PJMEDIA_HAS_DTMF_FLASH!= 0\n    if (event->event > 16) {\n#else\n    if (event->event > 15) {\n#endif    \n\tPJ_LOG(5,(stream->port.info.name.ptr,\n\t\t  \"Ignored RTP pkt with bad DTMF event %d\",\n    \t\t  event->event));\n\treturn;\n    }\n\n    /* New event! */\n    PJ_LOG(5,(stream->port.info.name.ptr, \"Received DTMF digit %c, vol=%d\",\n    \t      digitmap[event->event],\n    \t      (event->e_vol & 0x3F)));\n\n    stream->last_dtmf = event->event;\n    stream->last_dtmf_dur = pj_ntohs(event->duration);\n\n    /* If DTMF callback is installed, call the callback, otherwise keep\n     * the DTMF digits in the buffer.\n     */\n    if (stream->dtmf_cb) {\n\n\tstream->dtmf_cb(stream, stream->dtmf_cb_user_data,\n\t\t\tdigitmap[event->event]);\n\n    } else {\n\t/* By convention, we use jitter buffer's mutex to access shared\n\t * DTMF variables.\n\t */\n\tpj_mutex_lock(stream->jb_mutex);\n\tif (stream->rx_dtmf_count >= PJ_ARRAY_SIZE(stream->rx_dtmf_buf)) {\n\t    /* DTMF digits overflow.  Discard the oldest digit. */\n\t    pj_array_erase(stream->rx_dtmf_buf,\n\t\t\t   sizeof(stream->rx_dtmf_buf[0]),\n\t\t\t   stream->rx_dtmf_count, 0);\n\t    --stream->rx_dtmf_count;\n\t}\n\tstream->rx_dtmf_buf[stream->rx_dtmf_count++] = digitmap[event->event];\n\tpj_mutex_unlock(stream->jb_mutex);\n    }\n}\n\n\n/*\n * This callback is called by stream transport on receipt of packets\n * in the RTP socket.\n */\nstatic void on_rx_rtp( void *data,\n\t\t       void *pkt,\n                       pj_ssize_t bytes_read)\n\n{\n    pjmedia_stream *stream = (pjmedia_stream*) data;\n    pjmedia_channel *channel = stream->dec;\n    const pjmedia_rtp_hdr *hdr;\n    const void *payload;\n    unsigned payloadlen;\n    pjmedia_rtp_status seq_st;\n    pj_status_t status;\n    pj_bool_t pkt_discarded = PJ_FALSE;\n\n    /* Check for errors */\n    if (bytes_read < 0) {\n\tstatus = (pj_status_t)-bytes_read;\n\tif (status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) {\n\t    return;\n\t}\n\tif (stream->rtp_rx_last_err != status) {\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\t    pj_strerror(status, errmsg, sizeof(errmsg));\n\t    PJ_LOG(4,(stream->port.info.name.ptr,\n\t\t      \"Unable to receive RTP packet, recv() returned %d: %s\",\n\t\t      status, errmsg));\n\t    stream->rtp_rx_last_err = status;\n\t}\n\treturn;\n    } else {\n\tstream->rtp_rx_last_err = PJ_SUCCESS;\n    }\n\n    /* Ignore keep-alive packets */\n    if (bytes_read < (pj_ssize_t) sizeof(pjmedia_rtp_hdr))\n\treturn;\n\n    /* Update RTP and RTCP session. */\n    status = pjmedia_rtp_decode_rtp(&channel->rtp, pkt, (int)bytes_read,\n\t\t\t\t    &hdr, &payload, &payloadlen);\n    if (status != PJ_SUCCESS) {\n\tLOGERR_((stream->port.info.name.ptr, \"RTP decode error\", status));\n\tstream->rtcp.stat.rx.discard++;\n\treturn;\n    }\n\n    /* Ignore the packet if decoder is paused */\n    if (channel->paused)\n\tgoto on_return;\n\n    /* Update RTP session (also checks if RTP session can accept\n     * the incoming packet.\n     */\n    pjmedia_rtp_session_update2(&channel->rtp, hdr, &seq_st,\n\t\t\t        hdr->pt != stream->rx_event_pt);\n    if (seq_st.status.value) {\n\tTRC_  ((stream->port.info.name.ptr,\n\t\t\"RTP status: badpt=%d, badssrc=%d, dup=%d, \"\n\t\t\"outorder=%d, probation=%d, restart=%d\",\n\t\tseq_st.status.flag.badpt,\n\t\tseq_st.status.flag.badssrc,\n\t\tseq_st.status.flag.dup,\n\t\tseq_st.status.flag.outorder,\n\t\tseq_st.status.flag.probation,\n\t\tseq_st.status.flag.restart));\n\n\tif (seq_st.status.flag.badpt) {\n\t    PJ_LOG(4,(stream->port.info.name.ptr,\n\t\t      \"Bad RTP pt %d (expecting %d)\",\n\t\t      hdr->pt, channel->rtp.out_pt));\n\t}\n\n\tif (seq_st.status.flag.badssrc) {\n\t    PJ_LOG(4,(stream->port.info.name.ptr,\n\t\t      \"Changed RTP peer SSRC %d (previously %d)\",\n\t\t      channel->rtp.peer_ssrc, stream->rtcp.peer_ssrc));\n\t    stream->rtcp.peer_ssrc = channel->rtp.peer_ssrc;\n\t}\n\n\n    }\n\n    /* Skip bad RTP packet */\n    if (seq_st.status.flag.bad) {\n\tpkt_discarded = PJ_TRUE;\n\tgoto on_return;\n    }\n\n    /* Ignore if payloadlen is zero */\n    if (payloadlen == 0) {\n\tpkt_discarded = PJ_TRUE;\n\tgoto on_return;\n    }\n\n    /* Handle incoming DTMF. */\n    if (hdr->pt == stream->rx_event_pt) {\n\t/* Ignore out-of-order packet as it will be detected as new\n\t * digit. Also ignore duplicate packet as it serves no use.\n\t */\n\tif (seq_st.status.flag.outorder || seq_st.status.flag.dup) {\n\t    goto on_return;\n\t}\n\n\thandle_incoming_dtmf(stream, payload, payloadlen);\n\tgoto on_return;\n    }\n\n    /* Put \"good\" packet to jitter buffer, or reset the jitter buffer\n     * when RTP session is restarted.\n     */\n    pj_mutex_lock( stream->jb_mutex );\n    if (seq_st.status.flag.restart) {\n\tstatus = pjmedia_jbuf_reset(stream->jb);\n\tPJ_LOG(4,(stream->port.info.name.ptr, \"Jitter buffer reset\"));\n    } else {\n\t/*\n\t * Packets may contain more than one frames, while the jitter\n\t * buffer can only take one frame per \"put\" operation. So we need\n\t * to ask the codec to \"parse\" the payload into multiple frames.\n\t */\n\tenum { MAX = 16 };\n\tpj_timestamp ts;\n\tunsigned i, count = MAX;\n\tunsigned ts_span;\n\tpjmedia_frame frames[MAX];\n\n\t/* Get the timestamp of the first sample */\n\tts.u64 = pj_ntohl(hdr->ts);\n\n\t/* Parse the payload. */\n\tstatus = pjmedia_codec_parse(stream->codec, (void*)payload,\n\t\t\t\t     payloadlen, &ts, &count, frames);\n\tif (status != PJ_SUCCESS) {\n\t    LOGERR_((stream->port.info.name.ptr,\n\t\t     \"Codec parse() error\",\n\t\t     status));\n\t    count = 0;\n\t}\n\n#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)\n\t/* This code is used to learn the samples per frame value that is put\n\t * by remote endpoint, for codecs with inconsistent clock rate such\n\t * as G.722 or MPEG audio. We need to learn the samples per frame\n\t * value as it is used as divider when inserting frames into the\n\t * jitter buffer.\n\t */\n\tif (stream->has_g722_mpeg_bug) {\n\t    if (stream->rtp_rx_check_cnt) {\n\t\t/* Make sure the detection performed only on two consecutive\n\t\t * packets with valid RTP sequence and no wrapped timestamp.\n\t\t */\n\t\tif (seq_st.diff == 1 && stream->rtp_rx_last_ts &&\n\t\t    ts.u64 > stream->rtp_rx_last_ts &&\n\t\t    stream->rtp_rx_last_cnt > 0)\n\t\t{\n\t\t    unsigned peer_frm_ts_diff;\n\t\t    unsigned frm_ts_span;\n\n\t\t    /* Calculate actual frame timestamp span */\n\t\t    frm_ts_span = PJMEDIA_PIA_SPF(&stream->port.info) /\n\t\t\t\t  stream->codec_param.setting.frm_per_pkt/\n\t\t\t\t  PJMEDIA_PIA_CCNT(&stream->port.info);\n\n\t\t    /* Get remote frame timestamp span */\n\t\t    peer_frm_ts_diff =\n\t\t\t((pj_uint32_t)ts.u64-stream->rtp_rx_last_ts) /\n\t\t\tstream->rtp_rx_last_cnt;\n\n\t\t    /* Possibilities remote's samples per frame for G.722\n\t\t     * are only (frm_ts_span) and (frm_ts_span/2), this\n\t\t     * validation is needed to avoid wrong decision because\n\t\t     * of silence frames.\n\t\t     */\n\t\t    if (stream->codec_param.info.pt == PJMEDIA_RTP_PT_G722 &&\n\t\t\t(peer_frm_ts_diff == frm_ts_span ||\n\t\t\t peer_frm_ts_diff == (frm_ts_span>>1)))\n\t\t    {\n\t\t\tif (peer_frm_ts_diff < stream->rtp_rx_ts_len_per_frame)\n\t\t\t{\n\t\t\t    stream->rtp_rx_ts_len_per_frame = peer_frm_ts_diff;\n\t\t\t    /* Done, stop the check immediately */\n\t\t\t    stream->rtp_rx_check_cnt = 1;\n\t\t\t}\n\n\t\t\tif (--stream->rtp_rx_check_cnt == 0) {\n    \t\t\t    PJ_LOG(4, (THIS_FILE, \"G722 codec used, remote\"\n\t\t\t\t       \" samples per frame detected = %d\",\n\t\t\t\t       stream->rtp_rx_ts_len_per_frame));\n\n\t\t\t    /* Reset jitter buffer once detection done */\n\t\t\t    pjmedia_jbuf_reset(stream->jb);\n\t\t\t}\n\t\t    }\n\t\t}\n\n\t\tstream->rtp_rx_last_ts = (pj_uint32_t)ts.u64;\n\t\tstream->rtp_rx_last_cnt = count;\n\t    }\n\n\t    ts_span = stream->rtp_rx_ts_len_per_frame;\n\n\t    /* Adjust the timestamp of the parsed frames */\n\t    for (i=0; i<count; ++i) {\n\t\tframes[i].timestamp.u64 = ts.u64 + ts_span * i;\n\t    }\n\n\t} else {\n\t    ts_span = stream->codec_param.info.frm_ptime *\n\t\t      stream->codec_param.info.clock_rate /\n\t\t      1000;\n\t}\n#else\n\tts_span = stream->codec_param.info.frm_ptime *\n\t\t  stream->codec_param.info.clock_rate /\n\t\t  1000;\n#endif\n\n\t/* Put each frame to jitter buffer. */\n\tfor (i=0; i<count; ++i) {\n\t    unsigned ext_seq;\n\t    pj_bool_t discarded;\n\n\t    ext_seq = (unsigned)(frames[i].timestamp.u64 / ts_span);\n\t    pjmedia_jbuf_put_frame2(stream->jb, frames[i].buf, frames[i].size,\n\t\t\t\t    frames[i].bit_info, ext_seq, &discarded);\n\t    if (discarded)\n\t\tpkt_discarded = PJ_TRUE;\n\t}\n\n#if TRACE_JB\n\ttrace_jb_put(stream, hdr, payloadlen, count);\n#endif\n\n    }\n    pj_mutex_unlock( stream->jb_mutex );\n\n\n    /* Check if now is the time to transmit RTCP SR/RR report.\n     * We only do this when stream direction is \"decoding only\",\n     * because otherwise check_tx_rtcp() will be handled by put_frame()\n     */\n    if (stream->dir == PJMEDIA_DIR_DECODING) {\n\tcheck_tx_rtcp(stream, pj_ntohl(hdr->ts));\n    }\n\n    if (status != 0) {\n\tLOGERR_((stream->port.info.name.ptr, \"Jitter buffer put() error\",\n\t\tstatus));\n\tpkt_discarded = PJ_TRUE;\n\tgoto on_return;\n    }\n\non_return:\n    /* Update RTCP session */\n    if (stream->rtcp.peer_ssrc == 0)\n\tstream->rtcp.peer_ssrc = channel->rtp.peer_ssrc;\n\n    pjmedia_rtcp_rx_rtp2(&stream->rtcp, pj_ntohs(hdr->seq),\n\t\t\t pj_ntohl(hdr->ts), payloadlen, pkt_discarded);\n\n    /* Send RTCP RR and SDES after we receive some RTP packets */\n    if (stream->rtcp.received >= 10 && !stream->initial_rr) {\n\tstatus = send_rtcp(stream, !stream->rtcp_sdes_bye_disabled,\n\t\t\t   PJ_FALSE, PJ_FALSE);\n        if (status != PJ_SUCCESS) {\n            PJ_PERROR(4,(stream->port.info.name.ptr, status,\n            \t     \"Error sending initial RTCP RR\"));\n\t} else {\n\t    stream->initial_rr = PJ_TRUE;\n\t}\n    }\n}\n\n\n/*\n * This callback is called by stream transport on receipt of packets\n * in the RTCP socket.\n */\nstatic void on_rx_rtcp( void *data,\n                        void *pkt,\n                        pj_ssize_t bytes_read)\n{\n    pjmedia_stream *stream = (pjmedia_stream*) data;\n\n    /* Check for errors */\n    if (bytes_read < 0) {\n\tif (bytes_read != -PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) {\n\t    LOGERR_((stream->port.info.name.ptr, \"RTCP recv() error\",\n\t\t    (pj_status_t)-bytes_read));\n\t}\n\treturn;\n    }\n\n    pjmedia_rtcp_rx_rtcp(&stream->rtcp, pkt, bytes_read);\n}\n\n\n/*\n * Create media channel.\n */\nstatic pj_status_t create_channel( pj_pool_t *pool,\n\t\t\t\t   pjmedia_stream *stream,\n\t\t\t\t   pjmedia_dir dir,\n\t\t\t\t   unsigned pt,\n\t\t\t\t   const pjmedia_stream_info *param,\n\t\t\t\t   pjmedia_channel **p_channel)\n{\n    pjmedia_channel *channel;\n    pj_status_t status;\n\n    /* Allocate memory for channel descriptor */\n\n    channel = PJ_POOL_ZALLOC_T(pool, pjmedia_channel);\n    PJ_ASSERT_RETURN(channel != NULL, PJ_ENOMEM);\n\n    /* Init channel info. */\n\n    channel->stream = stream;\n    channel->dir = dir;\n    channel->paused = 1;\n    channel->pt = pt;\n\n\n    /* Allocate buffer for outgoing packet. */\n\n    if (param->type == PJMEDIA_TYPE_AUDIO) {\n        channel->out_pkt_size = sizeof(pjmedia_rtp_hdr) +\n\t\t\t        stream->codec_param.info.max_bps *\n\t\t\t        PJMEDIA_MAX_FRAME_DURATION_MS /\n\t\t\t        8 / 1000;\n        if (channel->out_pkt_size > PJMEDIA_MAX_MTU -\n\t\t\t\t    PJMEDIA_STREAM_RESV_PAYLOAD_LEN)\n\t{\n\t    channel->out_pkt_size = PJMEDIA_MAX_MTU -\n\t\t\t\t    PJMEDIA_STREAM_RESV_PAYLOAD_LEN;\n\t}\n    } else {\n        return PJ_ENOTSUP;\n    }\n\n    channel->out_pkt = pj_pool_alloc(pool, channel->out_pkt_size);\n    PJ_ASSERT_RETURN(channel->out_pkt != NULL, PJ_ENOMEM);\n\n\n\n    /* Create RTP and RTCP sessions: */\n\n    if (param->rtp_seq_ts_set == 0) {\n\tstatus = pjmedia_rtp_session_init(&channel->rtp, pt, param->ssrc);\n    } else {\n\tpjmedia_rtp_session_setting settings;\n\n\tsettings.flags = (pj_uint8_t)((param->rtp_seq_ts_set << 2) | 3);\n\tsettings.default_pt = pt;\n\tsettings.sender_ssrc = param->ssrc;\n\tsettings.seq = param->rtp_seq;\n\tsettings.ts = param->rtp_ts;\n\tstatus = pjmedia_rtp_session_init2(&channel->rtp, settings);\n    }\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Done. */\n    *p_channel = channel;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create media stream.\n */\nPJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,\n\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t   const pjmedia_stream_info *info,\n\t\t\t\t\t   pjmedia_transport *tp,\n\t\t\t\t\t   void *user_data,\n\t\t\t\t\t   pjmedia_stream **p_stream)\n\n{\n    enum { M = 32 };\n    pjmedia_stream *stream;\n    pj_str_t name;\n    unsigned jb_init, jb_max, jb_min_pre, jb_max_pre;\n    pjmedia_audio_format_detail *afd;\n    pj_pool_t *own_pool = NULL;\n    char *p;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(endpt && info && p_stream, PJ_EINVAL);\n\n    if (pool == NULL) {\n\town_pool = pjmedia_endpt_create_pool( endpt, \"strm%p\",\n\t\t\t\t\t      PJMEDIA_STREAM_SIZE,\n\t\t\t\t\t      PJMEDIA_STREAM_INC);\n\tPJ_ASSERT_RETURN(own_pool != NULL, PJ_ENOMEM);\n\tpool = own_pool;\n    }\n\n    /* Allocate the media stream: */\n\n    stream = PJ_POOL_ZALLOC_T(pool, pjmedia_stream);\n    PJ_ASSERT_RETURN(stream != NULL, PJ_ENOMEM);\n    stream->own_pool = own_pool;\n    pj_memcpy(&stream->si, info, sizeof(*info));\n    pj_strdup(pool, &stream->si.fmt.encoding_name, &info->fmt.encoding_name);\n    if (info->param)\n\tstream->si.param = pjmedia_codec_param_clone(pool, info->param);\n\n    /* Init stream/port name */\n    name.ptr = (char*) pj_pool_alloc(pool, M);\n    name.slen = pj_ansi_snprintf(name.ptr, M, \"strm%p\", stream);\n\n    /* Init some port-info. Some parts of the info will be set later\n     * once we have more info about the codec.\n     */\n    pjmedia_port_info_init(&stream->port.info, &name,\n                           PJMEDIA_SIG_PORT_STREAM,\n\t\t\t   info->fmt.clock_rate, info->fmt.channel_cnt,\n\t\t\t   16, 80);\n    afd = pjmedia_format_get_audio_format_detail(&stream->port.info.fmt, 1);\n\n    /* Init port. */\n\n    //No longer there in 2.0\n    //pj_strdup(pool, &stream->port.info.encoding_name, &info->fmt.encoding_name);\n    afd->clock_rate = info->fmt.clock_rate;\n    afd->channel_count = info->fmt.channel_cnt;\n    stream->port.port_data.pdata = stream;\n\n    /* Init stream: */\n    stream->endpt = endpt;\n    stream->codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);\n    stream->dir = info->dir;\n    stream->user_data = user_data;\n    stream->rtcp_interval = (PJMEDIA_RTCP_INTERVAL-500 + (pj_rand()%1000)) *\n\t\t\t    info->fmt.clock_rate / 1000;\n    stream->rtcp_sdes_bye_disabled = info->rtcp_sdes_bye_disabled;\n\n    stream->tx_event_pt = info->tx_event_pt ? info->tx_event_pt : -1;\n    stream->rx_event_pt = info->rx_event_pt ? info->rx_event_pt : -1;\n    stream->last_dtmf = -1;\n    stream->jb_last_frm = PJMEDIA_JB_NORMAL_FRAME;\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0\n    stream->use_ka = info->use_ka;\n#endif\n\n    /* Build random RTCP CNAME. CNAME has user@host format */\n    stream->cname.ptr = p = (char*) pj_pool_alloc(pool, 20);\n    pj_create_random_string(p, 5);\n    p += 5;\n    *p++ = '@'; *p++ = 'p'; *p++ = 'j';\n    pj_create_random_string(p, 6);\n    p += 6;\n    *p++ = '.'; *p++ = 'o'; *p++ = 'r'; *p++ = 'g';\n    stream->cname.slen = p - stream->cname.ptr;\n\n\n    /* Create mutex to protect jitter buffer: */\n\n    status = pj_mutex_create_simple(pool, NULL, &stream->jb_mutex);\n    if (status != PJ_SUCCESS)\n\tgoto err_cleanup;\n\n\n    /* Create and initialize codec: */\n\n    status = pjmedia_codec_mgr_alloc_codec( stream->codec_mgr,\n\t\t\t\t\t    &info->fmt, &stream->codec);\n    if (status != PJ_SUCCESS)\n\tgoto err_cleanup;\n\n\n    /* Get codec param: */\n    if (info->param)\n\tstream->codec_param = *stream->si.param;\n    else {\n\tstatus = pjmedia_codec_mgr_get_default_param(stream->codec_mgr,\n\t\t\t\t\t\t     &info->fmt,\n\t\t\t\t\t\t     &stream->codec_param);\n\tif (status != PJ_SUCCESS)\n\t    goto err_cleanup;\n    }\n\n    /* Check for invalid max_bps. */\n    if (stream->codec_param.info.max_bps < stream->codec_param.info.avg_bps)\n\tstream->codec_param.info.max_bps = stream->codec_param.info.avg_bps;\n\n    /* Check for invalid frame per packet. */\n    if (stream->codec_param.setting.frm_per_pkt < 1)\n\tstream->codec_param.setting.frm_per_pkt = 1;\n\n    /* Init the codec. */\n    status = pjmedia_codec_init(stream->codec, pool);\n    if (status != PJ_SUCCESS)\n\tgoto err_cleanup;\n\n    /* Open the codec. */\n\n    /* The clock rate for Opus codec is not static,\n     * it's negotiated in the SDP.\n     */\n    if (!pj_stricmp2(&info->fmt.encoding_name, \"opus\")) {\n\tstream->codec_param.info.clock_rate = info->fmt.clock_rate;\n\tstream->codec_param.info.channel_cnt = info->fmt.channel_cnt;\n    }\n\n    status = pjmedia_codec_open(stream->codec, &stream->codec_param);\n    if (status != PJ_SUCCESS)\n\tgoto err_cleanup;\n\n    /* Set additional info and callbacks. */\n    afd->bits_per_sample = 16;\n    afd->frame_time_usec = stream->codec_param.info.frm_ptime *\n\t\t           stream->codec_param.setting.frm_per_pkt * 1000;\n    stream->port.info.fmt.id = stream->codec_param.info.fmt_id;\n    if (stream->codec_param.info.fmt_id == PJMEDIA_FORMAT_L16) {\n\t/* Raw format */\n\tafd->avg_bps = afd->max_bps = afd->clock_rate * afd->channel_count *\n\t\t\t\t      afd->bits_per_sample;\n\n\tstream->port.put_frame = &put_frame;\n\tstream->port.get_frame = &get_frame;\n    } else {\n\t/* Encoded format */\n\tafd->avg_bps = stream->codec_param.info.avg_bps;\n\tafd->max_bps = stream->codec_param.info.max_bps;\n\n\t/* Not applicable for 2.0\n\tif ((stream->codec_param.info.max_bps *\n\t     stream->codec_param.info.frm_ptime *\n\t     stream->codec_param.setting.frm_per_pkt) % 8000 != 0)\n\t{\n\t    ++stream->port.info.bytes_per_frame;\n\t}\n\tstream->port.info.format.bitrate = stream->codec_param.info.avg_bps;\n\tstream->port.info.format.vad = (stream->codec_param.setting.vad != 0);\n\t*/\n\n\tstream->port.put_frame = &put_frame;\n\tstream->port.get_frame = &get_frame_ext;\n    }\n\n    /* If encoder and decoder's ptime are asymmetric, then we need to\n     * create buffer on the encoder side. This could happen for example\n     * with iLBC\n     */\n    if (stream->codec_param.info.enc_ptime!=0 &&\n\tstream->codec_param.info.enc_ptime!=stream->codec_param.info.frm_ptime)\n    {\n\tunsigned ptime;\n\n\tstream->enc_samples_per_pkt = stream->codec_param.info.enc_ptime *\n\t\t\t\t      stream->codec_param.info.channel_cnt *\n\t\t\t\t      afd->clock_rate / 1000;\n\n\t/* Set buffer size as twice the largest ptime value between\n\t * stream's ptime, encoder ptime, or decoder ptime.\n\t */\n\n\tptime = afd->frame_time_usec / 1000;\n\n\tif (stream->codec_param.info.enc_ptime > ptime)\n\t    ptime = stream->codec_param.info.enc_ptime;\n\n\tif (stream->codec_param.info.frm_ptime > ptime)\n\t    ptime = stream->codec_param.info.frm_ptime;\n\n\tptime <<= 1;\n\n\t/* Allocate buffer */\n\tstream->enc_buf_size = afd->clock_rate * ptime / 1000;\n\tstream->enc_buf = (pj_int16_t*)\n\t\t\t  pj_pool_alloc(pool, stream->enc_buf_size * 2);\n\n    } else {\n\tstream->enc_samples_per_pkt = PJMEDIA_AFD_SPF(afd);\n    }\n\n\n    /* Initially disable the VAD in the stream, to help traverse NAT better */\n    stream->vad_enabled = stream->codec_param.setting.vad;\n    if (PJMEDIA_STREAM_VAD_SUSPEND_MSEC > 0 && stream->vad_enabled) {\n\tstream->codec_param.setting.vad = 0;\n\tstream->ts_vad_disabled = 0;\n\tpjmedia_codec_modify(stream->codec, &stream->codec_param);\n\tPJ_LOG(4,(stream->port.info.name.ptr,\"VAD temporarily disabled\"));\n    }\n\n    /* Get the frame size */\n    if (stream->codec_param.info.max_rx_frame_size > 0) {\n        stream->frame_size = stream->codec_param.info.max_rx_frame_size;\n    } else {\n        stream->frame_size = stream->codec_param.info.max_bps *\n\t\t\t     stream->codec_param.info.frm_ptime / 8 / 1000;\n        if ((stream->codec_param.info.max_bps *\n             stream->codec_param.info.frm_ptime) % 8000 != 0)\n        {\n\t    ++stream->frame_size;\n        }\n    }\n\n    /* How many consecutive PLC frames can be generated */\n    stream->max_plc_cnt = (MAX_PLC_MSEC+stream->codec_param.info.frm_ptime-1)/\n\t\t\t    stream->codec_param.info.frm_ptime;\n\n#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)\n    stream->rtp_rx_check_cnt = 50;\n    stream->has_g722_mpeg_bug = PJ_FALSE;\n    stream->rtp_rx_last_ts = 0;\n    stream->rtp_rx_last_cnt = 0;\n    stream->rtp_tx_ts_len_per_pkt = stream->enc_samples_per_pkt /\n\t\t\t\t     stream->codec_param.info.channel_cnt;\n    stream->rtp_rx_ts_len_per_frame = PJMEDIA_AFD_SPF(afd) /\n\t\t\t\t      stream->codec_param.setting.frm_per_pkt /\n\t\t\t\t      stream->codec_param.info.channel_cnt;\n\n    if (info->fmt.pt == PJMEDIA_RTP_PT_G722) {\n\tstream->has_g722_mpeg_bug = PJ_TRUE;\n\t/* RTP clock rate = 1/2 real clock rate */\n\tstream->rtp_tx_ts_len_per_pkt >>= 1;\n    } else if (!pj_stricmp2(&info->fmt.encoding_name, \"opus\")) {\n\tunsigned opus_ts_modifier = 48000 / afd->clock_rate;\n\tstream->rtp_rx_check_cnt = 0;\n\tstream->has_g722_mpeg_bug = PJ_TRUE;\n\tstream->rtp_tx_ts_len_per_pkt *= opus_ts_modifier;\n\tstream->rtp_rx_ts_len_per_frame *= opus_ts_modifier;\n    }\n#endif\n\n    /* Init jitter buffer parameters: */\n    if (info->jb_max >= stream->codec_param.info.frm_ptime)\n\tjb_max = (info->jb_max + stream->codec_param.info.frm_ptime - 1) /\n\t\t stream->codec_param.info.frm_ptime;\n    else\n\tjb_max = 500 / stream->codec_param.info.frm_ptime;\n\n    if (info->jb_min_pre >= stream->codec_param.info.frm_ptime)\n\tjb_min_pre = info->jb_min_pre / stream->codec_param.info.frm_ptime;\n    else\n\t//jb_min_pre = 60 / stream->codec_param.info.frm_ptime;\n\tjb_min_pre = 1;\n\n    if (info->jb_max_pre >= stream->codec_param.info.frm_ptime)\n\tjb_max_pre = info->jb_max_pre / stream->codec_param.info.frm_ptime;\n    else\n\t//jb_max_pre = 240 / stream->codec_param.info.frm_ptime;\n\tjb_max_pre = jb_max * 4 / 5;\n\n    if (info->jb_init >= stream->codec_param.info.frm_ptime)\n\tjb_init = info->jb_init / stream->codec_param.info.frm_ptime;\n    else\n\t//jb_init = (jb_min_pre + jb_max_pre) / 2;\n\tjb_init = 0;\n\n    /* Create jitter buffer */\n    status = pjmedia_jbuf_create(pool, &stream->port.info.name,\n\t\t\t\t stream->frame_size,\n\t\t\t\t stream->codec_param.info.frm_ptime,\n\t\t\t\t jb_max, &stream->jb);\n    if (status != PJ_SUCCESS)\n\tgoto err_cleanup;\n\n\n    /* Set up jitter buffer */\n    pjmedia_jbuf_set_adaptive( stream->jb, jb_init, jb_min_pre, jb_max_pre);\n\n    /* Create decoder channel: */\n\n    status = create_channel( pool, stream, PJMEDIA_DIR_DECODING,\n\t\t\t     info->rx_pt, info, &stream->dec);\n    if (status != PJ_SUCCESS)\n\tgoto err_cleanup;\n\n\n    /* Create encoder channel: */\n\n    status = create_channel( pool, stream, PJMEDIA_DIR_ENCODING,\n\t\t\t     info->tx_pt, info, &stream->enc);\n    if (status != PJ_SUCCESS)\n\tgoto err_cleanup;\n\n\n    /* Init RTCP session: */\n\n    {\n\tpjmedia_rtcp_session_setting rtcp_setting;\n\n\tpjmedia_rtcp_session_setting_default(&rtcp_setting);\n\trtcp_setting.name = stream->port.info.name.ptr;\n\trtcp_setting.ssrc = info->ssrc;\n\trtcp_setting.rtp_ts_base = pj_ntohl(stream->enc->rtp.out_hdr.ts);\n\trtcp_setting.clock_rate = info->fmt.clock_rate;\n\trtcp_setting.samples_per_frame = PJMEDIA_AFD_SPF(afd);\n\n#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)\n\t/* Special case for G.722 */\n\tif (info->fmt.pt == PJMEDIA_RTP_PT_G722) {\n\t    rtcp_setting.clock_rate = 8000;\n\t    rtcp_setting.samples_per_frame = 160;\n\t}\n#endif\n\n\tpjmedia_rtcp_init2(&stream->rtcp, &rtcp_setting);\n\n\tif (info->rtp_seq_ts_set) {\n\t    stream->rtcp.stat.rtp_tx_last_seq = info->rtp_seq;\n\t    stream->rtcp.stat.rtp_tx_last_ts = info->rtp_ts;\n\t}\n    }\n\n    /* Allocate outgoing RTCP buffer, should be enough to hold SR/RR, SDES,\n     * BYE, and XR.\n     */\n    stream->out_rtcp_pkt_size =  sizeof(pjmedia_rtcp_sr_pkt) +\n\t\t\t\t sizeof(pjmedia_rtcp_common) +\n\t\t\t\t (4 + (unsigned)stream->cname.slen) +\n\t\t\t\t 32;\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n    if (info->rtcp_xr_enabled) {\n\tstream->out_rtcp_pkt_size += sizeof(pjmedia_rtcp_xr_pkt);\n    }\n#endif\n\n    if (stream->out_rtcp_pkt_size > PJMEDIA_MAX_MTU)\n\tstream->out_rtcp_pkt_size = PJMEDIA_MAX_MTU;\n\n    stream->out_rtcp_pkt = pj_pool_alloc(pool, stream->out_rtcp_pkt_size);\n\n    /* Only attach transport when stream is ready. */\n    status = pjmedia_transport_attach(tp, stream, &info->rem_addr,\n\t\t\t\t      &info->rem_rtcp,\n\t\t\t\t      pj_sockaddr_get_len(&info->rem_addr),\n                                      &on_rx_rtp, &on_rx_rtcp);\n    if (status != PJ_SUCCESS)\n\tgoto err_cleanup;\n\n    stream->transport = tp;\n\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n    /* Enable RTCP XR and update stream info/config to RTCP XR */\n    if (info->rtcp_xr_enabled) {\n\tint i;\n\n\tpjmedia_rtcp_enable_xr(&stream->rtcp, PJ_TRUE);\n\n\t/* Set RTCP XR TX interval */\n\tif (info->rtcp_xr_interval != 0)\n\t    stream->rtcp_xr_interval = info->rtcp_xr_interval;\n\telse\n\t    stream->rtcp_xr_interval = (PJMEDIA_RTCP_INTERVAL +\n\t\t\t\t       (pj_rand() % 8000)) *\n\t\t\t\t       info->fmt.clock_rate / 1000;\n\n\t/* Additional third-party RTCP XR destination */\n\tif (info->rtcp_xr_dest.addr.sa_family != 0) {\n\t    stream->rtcp_xr_dest_len = pj_sockaddr_get_len(&info->rtcp_xr_dest);\n\t    pj_memcpy(&stream->rtcp_xr_dest, &info->rtcp_xr_dest,\n\t\t      stream->rtcp_xr_dest_len);\n\t}\n\n\t/* jitter buffer adaptive info */\n\ti = PJMEDIA_RTCP_XR_JB_ADAPTIVE;\n\tpjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,\n\t\t\t\t    PJMEDIA_RTCP_XR_INFO_CONF_JBA,\n\t\t\t\t    i);\n\n\t/* Jitter buffer aggressiveness info (estimated) */\n\ti = 7;\n\tpjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,\n\t\t\t\t    PJMEDIA_RTCP_XR_INFO_CONF_JBR,\n\t\t\t\t    i);\n\n\t/* Jitter buffer absolute maximum delay */\n\ti = jb_max * stream->codec_param.info.frm_ptime;\n\tpjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,\n\t\t\t\t    PJMEDIA_RTCP_XR_INFO_JB_ABS_MAX,\n\t\t\t\t    i);\n\n\t/* PLC info */\n\tif (stream->codec_param.setting.plc == 0)\n\t    i = PJMEDIA_RTCP_XR_PLC_DIS;\n\telse\n#if PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA\n\t    i = PJMEDIA_RTCP_XR_PLC_ENH;\n#else\n\t    i = PJMEDIA_RTCP_XR_PLC_DIS;\n#endif\n\tpjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,\n\t\t\t\t    PJMEDIA_RTCP_XR_INFO_CONF_PLC,\n\t\t\t\t    i);\n    }\n#endif\n\n    /* Update the stream info's codec param */\n    stream->si.param = &stream->codec_param;\n\n    /* Send RTCP SDES */\n    if (!stream->rtcp_sdes_bye_disabled) {\n        pjmedia_stream_send_rtcp_sdes(stream);\n    }\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0\n    /* NAT hole punching by sending KA packet via RTP transport. */\n    if (stream->use_ka)\n\tsend_keep_alive_packet(stream);\n#endif\n\n#if TRACE_JB\n    {\n\tchar trace_name[PJ_MAXPATH];\n\tpj_ssize_t len;\n\n\tpj_ansi_snprintf(trace_name, sizeof(trace_name),\n\t\t\t TRACE_JB_PATH_PREFIX \"%s.csv\",\n\t\t\t stream->port.info.name.ptr);\n\tstatus = pj_file_open(pool, trace_name, PJ_O_WRONLY, &stream->trace_jb_fd);\n\tif (status != PJ_SUCCESS) {\n\t    stream->trace_jb_fd = TRACE_JB_INVALID_FD;\n\t    PJ_LOG(3,(THIS_FILE, \"Failed creating RTP trace file '%s'\",\n\t\t      trace_name));\n\t} else {\n\t    stream->trace_jb_buf = (char*)pj_pool_alloc(pool, PJ_LOG_MAX_SIZE);\n\n\t    /* Print column header */\n\t    len = pj_ansi_snprintf(stream->trace_jb_buf, PJ_LOG_MAX_SIZE,\n\t\t\t\t   \"Time, Operation, Size, Frame Count, \"\n\t\t\t\t   \"Frame type, RTP Seq, RTP TS, RTP M, \"\n\t\t\t\t   \"JB size, JB burst level, JB prefetch\\n\");\n\t    if (len < 1 || len >= PJ_LOG_MAX_SIZE)\n\t\tlen = PJ_LOG_MAX_SIZE-1;\n\t    pj_file_write(stream->trace_jb_fd, stream->trace_jb_buf, &len);\n\t    pj_file_flush(stream->trace_jb_fd);\n\t}\n    }\n#endif\n\n    /* Success! */\n    *p_stream = stream;\n\n    PJ_LOG(5,(THIS_FILE, \"Stream %s created\", stream->port.info.name.ptr));\n\n    return PJ_SUCCESS;\n\n\nerr_cleanup:\n    pjmedia_stream_destroy(stream);\n    return status;\n}\n\n\n/*\n * Destroy stream.\n */\nPJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream )\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n\n    /* Send RTCP BYE (also SDES & XR) */\n    if (!stream->rtcp_sdes_bye_disabled) {\n\tsend_rtcp(stream, PJ_TRUE, PJ_TRUE, PJ_TRUE);\n    }\n\n    /* If we're in the middle of transmitting DTMF digit, send one last\n     * RFC 2833 RTP packet with 'End' flag set.\n     */\n    if (stream->tx_dtmf_count && stream->tx_dtmf_buf[0].duration != 0) {\n\tpjmedia_frame frame_out;\n\tpjmedia_channel *channel = stream->enc;\n\tint first=0, last=0;\n\tvoid *rtphdr;\n\tint rtphdrlen;\n\n\tpj_bzero(&frame_out, sizeof(frame_out));\n\tframe_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr);\n\tframe_out.size = 0;\n\n\tcreate_dtmf_payload(stream, &frame_out, 1, &first, &last);\n\n\t/* Encapsulate into RTP packet. Note that:\n         *  - RTP marker should be set on the beginning of a new event\n\t *  - RTP timestamp is constant for the same packet.\n         */\n\tstatus = pjmedia_rtp_encode_rtp( &channel->rtp,\n\t\t\t\t\t stream->tx_event_pt, first,\n\t\t\t\t\t (int)frame_out.size, 0,\n\t\t\t\t\t (const void**)&rtphdr,\n\t\t\t\t\t &rtphdrlen);\n\tif (status == PJ_SUCCESS) {\n\t    /* Copy RTP header to the beginning of packet */\n\t    pj_memcpy(channel->out_pkt, rtphdr, sizeof(pjmedia_rtp_hdr));\n\n\t    /* Send the RTP packet to the transport. */\n\t    status = pjmedia_transport_send_rtp(stream->transport,\n\t\t\t\t\t\tchannel->out_pkt,\n\t\t\t\t\t\tframe_out.size +\n\t\t\t\t\t\t    sizeof(pjmedia_rtp_hdr));\n\t}\n\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(stream->port.info.name.ptr, status,\n\t\t\t \"Error sending RTP/DTMF end packet\"));\n\t}\n    }\n\n    /* Detach from transport\n     * MUST NOT hold stream mutex while detaching from transport, as\n     * it may cause deadlock. See ticket #460 for the details.\n     */\n    if (stream->transport) {\n\tpjmedia_transport_detach(stream->transport, stream);\n\tstream->transport = NULL;\n    }\n\n    /* This function may be called when stream is partly initialized. */\n    if (stream->jb_mutex)\n\tpj_mutex_lock(stream->jb_mutex);\n\n\n    /* Free codec. */\n\n    if (stream->codec) {\n\tpjmedia_codec_close(stream->codec);\n\tpjmedia_codec_mgr_dealloc_codec(stream->codec_mgr, stream->codec);\n\tstream->codec = NULL;\n    }\n\n    /* Free mutex */\n\n    if (stream->jb_mutex) {\n        pj_mutex_unlock(stream->jb_mutex);\n\tpj_mutex_destroy(stream->jb_mutex);\n\tstream->jb_mutex = NULL;\n    }\n\n    /* Destroy jitter buffer */\n    if (stream->jb)\n\tpjmedia_jbuf_destroy(stream->jb);\n\n#if TRACE_JB\n    if (TRACE_JB_OPENED(stream)) {\n\tpj_file_close(stream->trace_jb_fd);\n\tstream->trace_jb_fd = TRACE_JB_INVALID_FD;\n    }\n#endif\n\n    if (stream->own_pool) {\n\tpj_pool_t *pool = stream->own_pool;\n\tstream->own_pool = NULL;\n\tpj_pool_release(pool);\n    }\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the last frame frame type retreived from the jitter buffer.\n */\nPJ_DEF(char) pjmedia_stream_get_last_jb_frame_type(pjmedia_stream *stream)\n{\n    return stream->jb_last_frm;\n}\n\n\n/*\n * Get the port interface.\n */\nPJ_DEF(pj_status_t) pjmedia_stream_get_port( pjmedia_stream *stream,\n\t\t\t\t\t     pjmedia_port **p_port )\n{\n    *p_port = &stream->port;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the transport object\n */\nPJ_DEF(pjmedia_transport*) pjmedia_stream_get_transport(pjmedia_stream *st)\n{\n    return st->transport;\n}\n\n\n/*\n * Start stream.\n */\nPJ_DEF(pj_status_t) pjmedia_stream_start(pjmedia_stream *stream)\n{\n\n    PJ_ASSERT_RETURN(stream && stream->enc && stream->dec, PJ_EINVALIDOP);\n\n    if (stream->enc && (stream->dir & PJMEDIA_DIR_ENCODING)) {\n\tstream->enc->paused = 0;\n\t//pjmedia_snd_stream_start(stream->enc->snd_stream);\n\tPJ_LOG(4,(stream->port.info.name.ptr, \"Encoder stream started\"));\n    } else {\n\tPJ_LOG(4,(stream->port.info.name.ptr, \"Encoder stream paused\"));\n    }\n\n    if (stream->dec && (stream->dir & PJMEDIA_DIR_DECODING)) {\n\tstream->dec->paused = 0;\n\t//pjmedia_snd_stream_start(stream->dec->snd_stream);\n\tPJ_LOG(4,(stream->port.info.name.ptr, \"Decoder stream started\"));\n    } else {\n\tPJ_LOG(4,(stream->port.info.name.ptr, \"Decoder stream paused\"));\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_stream_get_info( const pjmedia_stream *stream,\n\t\t\t\t\t     pjmedia_stream_info *info)\n{\n    PJ_ASSERT_RETURN(stream && info, PJ_EINVAL);\n\n    pj_memcpy(info, &stream->si, sizeof(pjmedia_stream_info));\n    return PJ_SUCCESS;\n}\n\n/*\n * Get stream statistics.\n */\nPJ_DEF(pj_status_t) pjmedia_stream_get_stat( const pjmedia_stream *stream,\n\t\t\t\t\t     pjmedia_rtcp_stat *stat)\n{\n    PJ_ASSERT_RETURN(stream && stat, PJ_EINVAL);\n\n    pj_memcpy(stat, &stream->rtcp.stat, sizeof(pjmedia_rtcp_stat));\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Reset the stream statistics in the middle of a stream session.\n */\nPJ_DEF(pj_status_t) pjmedia_stream_reset_stat(pjmedia_stream *stream)\n{\n    PJ_ASSERT_RETURN(stream, PJ_EINVAL);\n\n    pjmedia_rtcp_init_stat(&stream->rtcp.stat);\n\n    return PJ_SUCCESS;\n}\n\n\n#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)\n/*\n * Get stream extended statistics.\n */\nPJ_DEF(pj_status_t) pjmedia_stream_get_stat_xr( const pjmedia_stream *stream,\n\t\t\t\t\t        pjmedia_rtcp_xr_stat *stat)\n{\n    PJ_ASSERT_RETURN(stream && stat, PJ_EINVAL);\n\n    if (stream->rtcp.xr_enabled) {\n\tpj_memcpy(stat, &stream->rtcp.xr_session.stat, sizeof(pjmedia_rtcp_xr_stat));\n\treturn PJ_SUCCESS;\n    }\n    return PJ_ENOTFOUND;\n}\n#endif\n\n/*\n * Get jitter buffer state.\n */\nPJ_DEF(pj_status_t) pjmedia_stream_get_stat_jbuf(const pjmedia_stream *stream,\n\t\t\t\t\t\t pjmedia_jb_state *state)\n{\n    PJ_ASSERT_RETURN(stream && state, PJ_EINVAL);\n    return pjmedia_jbuf_get_state(stream->jb, state);\n}\n\n/*\n * Pause stream.\n */\nPJ_DEF(pj_status_t) pjmedia_stream_pause( pjmedia_stream *stream,\n\t\t\t\t\t  pjmedia_dir dir)\n{\n    PJ_ASSERT_RETURN(stream, PJ_EINVAL);\n\n    if ((dir & PJMEDIA_DIR_ENCODING) && stream->enc) {\n\tstream->enc->paused = 1;\n\tPJ_LOG(4,(stream->port.info.name.ptr, \"Encoder stream paused\"));\n    }\n\n    if ((dir & PJMEDIA_DIR_DECODING) && stream->dec) {\n\tstream->dec->paused = 1;\n\n\t/* Also reset jitter buffer */\n\tpj_mutex_lock( stream->jb_mutex );\n\tpjmedia_jbuf_reset(stream->jb);\n\tpj_mutex_unlock( stream->jb_mutex );\n\n\tPJ_LOG(4,(stream->port.info.name.ptr, \"Decoder stream paused\"));\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Resume stream\n */\nPJ_DEF(pj_status_t) pjmedia_stream_resume( pjmedia_stream *stream,\n\t\t\t\t\t   pjmedia_dir dir)\n{\n    PJ_ASSERT_RETURN(stream, PJ_EINVAL);\n\n    if ((dir & PJMEDIA_DIR_ENCODING) && stream->enc) {\n\tstream->enc->paused = 0;\n\tPJ_LOG(4,(stream->port.info.name.ptr, \"Encoder stream resumed\"));\n    }\n\n    if ((dir & PJMEDIA_DIR_DECODING) && stream->dec) {\n\tstream->dec->paused = 0;\n\tPJ_LOG(4,(stream->port.info.name.ptr, \"Decoder stream resumed\"));\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Dial DTMF\n */\nPJ_DEF(pj_status_t) pjmedia_stream_dial_dtmf( pjmedia_stream *stream,\n\t\t\t\t\t      const pj_str_t *digit_char)\n{\n    pj_status_t status = PJ_SUCCESS;\n\n    /* By convention we use jitter buffer mutex to access DTMF\n     * queue.\n     */\n    PJ_ASSERT_RETURN(stream && digit_char, PJ_EINVAL);\n\n    /* Check that remote can receive DTMF events. */\n    if (stream->tx_event_pt < 0) {\n\treturn PJMEDIA_RTP_EREMNORFC2833;\n    }\n\n    pj_mutex_lock(stream->jb_mutex);\n\n    if (stream->tx_dtmf_count+digit_char->slen >=\n\t(long)PJ_ARRAY_SIZE(stream->tx_dtmf_buf))\n    {\n\tstatus = PJ_ETOOMANY;\n    } else {\n\tint i;\n\n\t/* convert ASCII digits into payload type first, to make sure\n\t * that all digits are valid.\n\t */\n\tfor (i=0; i<digit_char->slen; ++i) {\n\t    unsigned pt;\n\t    int dig = pj_tolower(digit_char->ptr[i]);\n\n\t    if (dig >= '0' && dig <= '9')\n\t    {\n\t\tpt = dig - '0';\n\t    }\n\t    else if (dig >= 'a' && dig <= 'd')\n\t    {\n\t\tpt = dig - 'a' + 12;\n\t    }\n\t    else if (dig == '*')\n\t    {\n\t\tpt = 10;\n\t    }\n\t    else if (dig == '#')\n\t    {\n\t\tpt = 11;\n\t    }\n#if defined(PJMEDIA_HAS_DTMF_FLASH) && PJMEDIA_HAS_DTMF_FLASH!= 0\t    \n\t    else if (dig == 'r')\n\t    {\n\t\tpt = 16;\n\t    }\n#endif\n\t    else\n\t    {\n\t\tstatus = PJMEDIA_RTP_EINDTMF;\n\t\tbreak;\n\t    }\n\n\t    stream->tx_dtmf_buf[stream->tx_dtmf_count+i].event = pt;\n\t    stream->tx_dtmf_buf[stream->tx_dtmf_count+i].duration = 0;\n\t    stream->tx_dtmf_buf[stream->tx_dtmf_count+i].ebit_cnt = 0;\n\t}\n\n\tif (status != PJ_SUCCESS)\n\t    goto on_return;\n\n\t/* Increment digit count only if all digits are valid. */\n\tstream->tx_dtmf_count += (int)digit_char->slen;\n    }\n\non_return:\n    pj_mutex_unlock(stream->jb_mutex);\n\n    return status;\n}\n\n\n/*\n * See if we have DTMF digits in the rx buffer.\n */\nPJ_DEF(pj_bool_t) pjmedia_stream_check_dtmf(pjmedia_stream *stream)\n{\n    return stream->rx_dtmf_count != 0;\n}\n\n\n/*\n * Retrieve incoming DTMF digits from the stream's DTMF buffer.\n */\nPJ_DEF(pj_status_t) pjmedia_stream_get_dtmf( pjmedia_stream *stream,\n\t\t\t\t\t     char *digits,\n\t\t\t\t\t     unsigned *size)\n{\n    PJ_ASSERT_RETURN(stream && digits && size, PJ_EINVAL);\n\n    pj_assert(sizeof(stream->rx_dtmf_buf[0]) == 0);\n\n    /* By convention, we use jitter buffer's mutex to access DTMF\n     * digits resources.\n     */\n    pj_mutex_lock(stream->jb_mutex);\n\n    if (stream->rx_dtmf_count < *size)\n\t*size = stream->rx_dtmf_count;\n\n    if (*size) {\n\tpj_memcpy(digits, stream->rx_dtmf_buf, *size);\n\tstream->rx_dtmf_count -= *size;\n\tif (stream->rx_dtmf_count) {\n\t    pj_memmove(stream->rx_dtmf_buf,\n\t\t       &stream->rx_dtmf_buf[*size],\n\t\t       stream->rx_dtmf_count);\n\t}\n    }\n\n    pj_mutex_unlock(stream->jb_mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Set callback to be called upon receiving DTMF digits.\n */\nPJ_DEF(pj_status_t) pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream,\n\t\t\t\t void (*cb)(pjmedia_stream*,\n\t\t\t\t\t    void *user_data,\n\t\t\t\t\t    int digit),\n\t\t\t\t void *user_data)\n{\n    PJ_ASSERT_RETURN(stream, PJ_EINVAL);\n\n    /* By convention, we use jitter buffer's mutex to access DTMF\n     * digits resources.\n     */\n    pj_mutex_lock(stream->jb_mutex);\n\n    stream->dtmf_cb = cb;\n    stream->dtmf_cb_user_data = user_data;\n\n    pj_mutex_unlock(stream->jb_mutex);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Send RTCP SDES.\n */\nPJ_DEF(pj_status_t)\npjmedia_stream_send_rtcp_sdes( pjmedia_stream *stream )\n{\n    PJ_ASSERT_RETURN(stream, PJ_EINVAL);\n\n    return send_rtcp(stream, PJ_TRUE, PJ_FALSE, PJ_FALSE);\n}\n\n/*\n * Send RTCP BYE.\n */\nPJ_DEF(pj_status_t)\npjmedia_stream_send_rtcp_bye( pjmedia_stream *stream )\n{\n    PJ_ASSERT_RETURN(stream, PJ_EINVAL);\n\n    if (stream->enc && stream->transport) {\n\treturn send_rtcp(stream, PJ_TRUE, PJ_TRUE, PJ_FALSE);\n    }\n\n    return PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/stream_common.c",
    "content": "/* $Id: stream_common.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/stream_common.h>\n#include <pj/log.h>\n\n#define THIS_FILE\t\"stream_common.c\"\n\n/*\n * Parse fmtp for specified format/payload type.\n */\nPJ_DEF(pj_status_t) pjmedia_stream_info_parse_fmtp( pj_pool_t *pool,\n\t\t\t\t\t\t    const pjmedia_sdp_media *m,\n\t\t\t\t\t\t    unsigned pt,\n\t\t\t\t\t\t    pjmedia_codec_fmtp *fmtp)\n{\n    const pjmedia_sdp_attr *attr;\n    pjmedia_sdp_fmtp sdp_fmtp;\n    char *p, *p_end, fmt_buf[8];\n    pj_str_t fmt;\n    pj_status_t status;\n\n    pj_assert(m && fmtp);\n\n    pj_bzero(fmtp, sizeof(pjmedia_codec_fmtp));\n\n    /* Get \"fmtp\" attribute for the format */\n    pj_ansi_sprintf(fmt_buf, \"%d\", pt);\n    fmt = pj_str(fmt_buf);\n    attr = pjmedia_sdp_media_find_attr2(m, \"fmtp\", &fmt);\n    if (attr == NULL)\n\treturn PJ_SUCCESS;\n\n    /* Parse \"fmtp\" attribute */\n    status = pjmedia_sdp_attr_get_fmtp(attr, &sdp_fmtp);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Prepare parsing */\n    p = sdp_fmtp.fmt_param.ptr;\n    p_end = p + sdp_fmtp.fmt_param.slen;\n\n    /* Parse */\n    while (p < p_end) {\n\tchar *token, *start, *end;\n\n\tif (fmtp->cnt >= PJMEDIA_CODEC_MAX_FMTP_CNT) {\n\t    PJ_LOG(4,(THIS_FILE,\n\t\t      \"Warning: fmtp parameter count exceeds \"\n\t\t      \"PJMEDIA_CODEC_MAX_FMTP_CNT\"));\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* Skip whitespaces */\n\twhile (p < p_end && (*p == ' ' || *p == '\\t')) ++p;\n\tif (p == p_end)\n\t    break;\n\n\t/* Get token */\n\tstart = p;\n\twhile (p < p_end && *p != ';' && *p != '=') ++p;\n\tend = p - 1;\n\n\t/* Right trim */\n\twhile (end >= start && (*end == ' '  || *end == '\\t' || \n\t\t\t\t*end == '\\r' || *end == '\\n' ))\n\t    --end;\n\n\t/* Forward a char after trimming */\n\t++end;\n\n\t/* Store token */\n\tif (end > start) {\n\t    if (pool) {\n\t\ttoken = (char*)pj_pool_alloc(pool, end - start);\n\t\tpj_ansi_strncpy(token, start, end - start);\n\t    } else {\n\t\ttoken = start;\n\t    }\n\t    if (*p == '=')\n\t\t/* Got param name */\n\t\tpj_strset(&fmtp->param[fmtp->cnt].name, token, end - start);\n\t    else\n\t\t/* Got param value */\n\t\tpj_strset(&fmtp->param[fmtp->cnt++].val, token, end - start);\n\t} else if (*p != '=') {\n\t    ++fmtp->cnt;\n\t}\n\n\t/* Next */\n\t++p;\n    }\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/stream_info.c",
    "content": "/* $Id: stream_info.c 3982 2012-03-22 09:56:52Z bennylp $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia/stream.h>\n#include <pjmedia/sdp_neg.h>\n#include <pjmedia/stream_common.h>\n#include <pj/ctype.h>\n#include <pj/rand.h>\n\nstatic const pj_str_t ID_AUDIO = { \"audio\", 5};\nstatic const pj_str_t ID_IN = { \"IN\", 2 };\nstatic const pj_str_t ID_IP4 = { \"IP4\", 3};\nstatic const pj_str_t ID_IP6 = { \"IP6\", 3};\nstatic const pj_str_t ID_RTP_AVP = { \"RTP/AVP\", 7 };\nstatic const pj_str_t ID_RTP_SAVP = { \"RTP/SAVP\", 8 };\n//static const pj_str_t ID_SDP_NAME = { \"pjmedia\", 7 };\nstatic const pj_str_t ID_RTPMAP = { \"rtpmap\", 6 };\nstatic const pj_str_t ID_TELEPHONE_EVENT = { \"telephone-event\", 15 };\n\n/*\n * Internal function for collecting codec info and param from the SDP media.\n */\nstatic pj_status_t get_audio_codec_info_param(pjmedia_stream_info *si,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      pjmedia_codec_mgr *mgr,\n\t\t\t\t\t      const pjmedia_sdp_media *local_m,\n\t\t\t\t\t      const pjmedia_sdp_media *rem_m)\n{\n    const pjmedia_sdp_attr *attr;\n    pjmedia_sdp_rtpmap *rtpmap;\n    unsigned i, fmti, pt = 0;\n    pj_status_t status;\n\n    /* Find the first codec which is not telephone-event */\n    for ( fmti = 0; fmti < local_m->desc.fmt_count; ++fmti ) {\n\tpjmedia_sdp_rtpmap r;\n\n\tif ( !pj_isdigit(*local_m->desc.fmt[fmti].ptr) )\n\t    return PJMEDIA_EINVALIDPT;\n\tpt = pj_strtoul(&local_m->desc.fmt[fmti]);\n\n\tif (pt < 96) {\n\t    /* This is known static PT. Skip rtpmap checking because it is\n\t     * optional. */\n\t    break;\n\t}\n\n\tattr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP,\n\t\t\t\t\t   &local_m->desc.fmt[fmti]);\n\tif (attr == NULL)\n\t    continue;\n\n\tstatus = pjmedia_sdp_attr_get_rtpmap(attr, &r);\n\tif (status != PJ_SUCCESS)\n\t    continue;\n\n\tif (pj_strcmp(&r.enc_name, &ID_TELEPHONE_EVENT) != 0)\n\t    break;\n    }\n    if ( fmti >= local_m->desc.fmt_count )\n\treturn PJMEDIA_EINVALIDPT;\n\n    /* Get payload type for receiving direction */\n    si->rx_pt = pt;\n\n    /* Get codec info.\n     * For static payload types, get the info from codec manager.\n     * For dynamic payload types, MUST get the rtpmap.\n     */\n    if (pt < 96) {\n\tpj_bool_t has_rtpmap;\n\n\trtpmap = NULL;\n\thas_rtpmap = PJ_TRUE;\n\n\tattr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP,\n\t\t\t\t\t   &local_m->desc.fmt[fmti]);\n\tif (attr == NULL) {\n\t    has_rtpmap = PJ_FALSE;\n\t}\n\tif (attr != NULL) {\n\t    status = pjmedia_sdp_attr_to_rtpmap(pool, attr, &rtpmap);\n\t    if (status != PJ_SUCCESS)\n\t\thas_rtpmap = PJ_FALSE;\n\t}\n\n\t/* Build codec format info: */\n\tif (has_rtpmap) {\n\t    si->fmt.type = si->type;\n\t    si->fmt.pt = pj_strtoul(&local_m->desc.fmt[fmti]);\n\t    pj_strdup(pool, &si->fmt.encoding_name, &rtpmap->enc_name);\n\t    si->fmt.clock_rate = rtpmap->clock_rate;\n\n#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG != 0)\n\t    /* The session info should have the actual clock rate, because\n\t     * this info is used for calculationg buffer size, etc in stream\n\t     */\n\t    if (si->fmt.pt == PJMEDIA_RTP_PT_G722)\n\t\tsi->fmt.clock_rate = 16000;\n#endif\n\n\t    /* For audio codecs, rtpmap parameters denotes the number of\n\t     * channels.\n\t     */\n\t    if (si->type == PJMEDIA_TYPE_AUDIO && rtpmap->param.slen) {\n\t\tsi->fmt.channel_cnt = (unsigned) pj_strtoul(&rtpmap->param);\n\t    } else {\n\t\tsi->fmt.channel_cnt = 1;\n\t    }\n\n\t} else {\n\t    const pjmedia_codec_info *p_info;\n\n\t    status = pjmedia_codec_mgr_get_codec_info( mgr, pt, &p_info);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    pj_memcpy(&si->fmt, p_info, sizeof(pjmedia_codec_info));\n\t}\n\n\t/* For static payload type, pt's are symetric */\n\tsi->tx_pt = pt;\n\n    } else {\n\tpjmedia_codec_id codec_id;\n\tpj_str_t codec_id_st;\n\tconst pjmedia_codec_info *p_info;\n\n\tattr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP,\n\t\t\t\t\t   &local_m->desc.fmt[fmti]);\n\tif (attr == NULL)\n\t    return PJMEDIA_EMISSINGRTPMAP;\n\n\tstatus = pjmedia_sdp_attr_to_rtpmap(pool, attr, &rtpmap);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Build codec format info: */\n\n\tsi->fmt.type = si->type;\n\tsi->fmt.pt = pj_strtoul(&local_m->desc.fmt[fmti]);\n\tsi->fmt.encoding_name = rtpmap->enc_name;\n\tsi->fmt.clock_rate = rtpmap->clock_rate;\n\n\t/* For audio codecs, rtpmap parameters denotes the number of\n\t * channels.\n\t */\n\tif (si->type == PJMEDIA_TYPE_AUDIO && rtpmap->param.slen) {\n\t    si->fmt.channel_cnt = (unsigned) pj_strtoul(&rtpmap->param);\n\t} else {\n\t    si->fmt.channel_cnt = 1;\n\t}\n\n\t/* Normalize the codec info from codec manager. Note that the\n\t * payload type will be resetted to its default (it might have\n\t * been rewritten by the SDP negotiator to match to the remote\n\t * offer), this is intentional as currently some components may\n\t * prefer (or even require) the default PT in codec info.\n\t */\n\tpjmedia_codec_info_to_id(&si->fmt, codec_id, sizeof(codec_id));\n\n\ti = 1;\n\tcodec_id_st = pj_str(codec_id);\n\tstatus = pjmedia_codec_mgr_find_codecs_by_id(mgr, &codec_id_st,\n\t\t\t\t\t\t     &i, &p_info, NULL);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tpj_memcpy(&si->fmt, p_info, sizeof(pjmedia_codec_info));\n\n\t/* Determine payload type for outgoing channel, by finding\n\t * dynamic payload type in remote SDP that matches the answer.\n\t */\n\tsi->tx_pt = 0xFFFF;\n\tfor (i=0; i<rem_m->desc.fmt_count; ++i) {\n\t    if (pjmedia_sdp_neg_fmt_match(pool,\n\t\t\t\t\t  (pjmedia_sdp_media*)local_m, fmti,\n\t\t\t\t\t  (pjmedia_sdp_media*)rem_m, i, 0) ==\n\t\tPJ_SUCCESS)\n\t    {\n\t\t/* Found matched codec. */\n\t\tsi->tx_pt = pj_strtoul(&rem_m->desc.fmt[i]);\n\t\tbreak;\n\t    }\n\t}\n\n\tif (si->tx_pt == 0xFFFF)\n\t    return PJMEDIA_EMISSINGRTPMAP;\n    }\n\n\n    /* Now that we have codec info, get the codec param. */\n    si->param = PJ_POOL_ALLOC_T(pool, pjmedia_codec_param);\n    status = pjmedia_codec_mgr_get_default_param(mgr, &si->fmt,\n\t\t\t\t\t         si->param);\n\n    /* Get remote fmtp for our encoder. */\n    pjmedia_stream_info_parse_fmtp(pool, rem_m, si->tx_pt,\n\t\t\t\t   &si->param->setting.enc_fmtp);\n\n    /* Get local fmtp for our decoder. */\n    pjmedia_stream_info_parse_fmtp(pool, local_m, si->rx_pt,\n\t\t\t\t   &si->param->setting.dec_fmtp);\n\n    /* Get the remote ptime for our encoder. */\n    attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr,\n\t\t\t\t  \"ptime\", NULL);\n    if (attr) {\n\tpj_str_t tmp_val = attr->value;\n\tunsigned frm_per_pkt;\n\n\tpj_strltrim(&tmp_val);\n\n\t/* Round up ptime when the specified is not multiple of frm_ptime */\n\tfrm_per_pkt = (pj_strtoul(&tmp_val) +\n\t\t      si->param->info.frm_ptime/2) /\n\t\t      si->param->info.frm_ptime;\n\tif (frm_per_pkt != 0) {\n            si->param->setting.frm_per_pkt = (pj_uint8_t)frm_per_pkt;\n        }\n    }\n\n    /* Get remote maxptime for our encoder. */\n    attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr,\n\t\t\t\t  \"maxptime\", NULL);\n    if (attr) {\n\tpj_str_t tmp_val = attr->value;\n\n\tpj_strltrim(&tmp_val);\n\tsi->tx_maxptime = pj_strtoul(&tmp_val);\n    }\n\n    /* When direction is NONE (it means SDP negotiation has failed) we don't\n     * need to return a failure here, as returning failure will cause\n     * the whole SDP to be rejected. See ticket #:\n     *\thttp://\n     *\n     * Thanks Alain Totouom\n     */\n    if (status != PJ_SUCCESS && si->dir != PJMEDIA_DIR_NONE)\n\treturn status;\n\n\n    /* Get incomming payload type for telephone-events */\n    si->rx_event_pt = -1;\n    for (i=0; i<local_m->attr_count; ++i) {\n\tpjmedia_sdp_rtpmap r;\n\n\tattr = local_m->attr[i];\n\tif (pj_strcmp(&attr->name, &ID_RTPMAP) != 0)\n\t    continue;\n\tif (pjmedia_sdp_attr_get_rtpmap(attr, &r) != PJ_SUCCESS)\n\t    continue;\n\tif (pj_strcmp(&r.enc_name, &ID_TELEPHONE_EVENT) == 0) {\n\t    si->rx_event_pt = pj_strtoul(&r.pt);\n\t    break;\n\t}\n    }\n\n    /* Get outgoing payload type for telephone-events */\n    si->tx_event_pt = -1;\n    for (i=0; i<rem_m->attr_count; ++i) {\n\tpjmedia_sdp_rtpmap r;\n\n\tattr = rem_m->attr[i];\n\tif (pj_strcmp(&attr->name, &ID_RTPMAP) != 0)\n\t    continue;\n\tif (pjmedia_sdp_attr_get_rtpmap(attr, &r) != PJ_SUCCESS)\n\t    continue;\n\tif (pj_strcmp(&r.enc_name, &ID_TELEPHONE_EVENT) == 0) {\n\t    si->tx_event_pt = pj_strtoul(&r.pt);\n\t    break;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Create stream info from SDP media line.\n */\nPJ_DEF(pj_status_t) pjmedia_stream_info_from_sdp(\n\t\t\t\t\t   pjmedia_stream_info *si,\n\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t   pjmedia_endpt *endpt,\n\t\t\t\t\t   const pjmedia_sdp_session *local,\n\t\t\t\t\t   const pjmedia_sdp_session *remote,\n\t\t\t\t\t   unsigned stream_idx)\n{\n    const pj_str_t STR_INACTIVE = { \"inactive\", 8 };\n    const pj_str_t STR_SENDONLY = { \"sendonly\", 8 };\n    const pj_str_t STR_RECVONLY = { \"recvonly\", 8 };\n\n    pjmedia_codec_mgr *mgr;\n    const pjmedia_sdp_attr *attr;\n    const pjmedia_sdp_media *local_m;\n    const pjmedia_sdp_media *rem_m;\n    const pjmedia_sdp_conn *local_conn;\n    const pjmedia_sdp_conn *rem_conn;\n    int rem_af, local_af;\n    pj_sockaddr local_addr;\n    pj_status_t status;\n\n\n    /* Validate arguments: */\n    PJ_ASSERT_RETURN(pool && si && local && remote, PJ_EINVAL);\n    PJ_ASSERT_RETURN(stream_idx < local->media_count, PJ_EINVAL);\n    PJ_ASSERT_RETURN(stream_idx < remote->media_count, PJ_EINVAL);\n\n    /* Keep SDP shortcuts */\n    local_m = local->media[stream_idx];\n    rem_m = remote->media[stream_idx];\n\n    local_conn = local_m->conn ? local_m->conn : local->conn;\n    if (local_conn == NULL)\n\treturn PJMEDIA_SDP_EMISSINGCONN;\n\n    rem_conn = rem_m->conn ? rem_m->conn : remote->conn;\n    if (rem_conn == NULL)\n\treturn PJMEDIA_SDP_EMISSINGCONN;\n\n    /* Media type must be audio */\n    if (pj_stricmp(&local_m->desc.media, &ID_AUDIO) != 0)\n\treturn PJMEDIA_EINVALIMEDIATYPE;\n\n    /* Get codec manager. */\n    mgr = pjmedia_endpt_get_codec_mgr(endpt);\n\n    /* Reset: */\n\n    pj_bzero(si, sizeof(*si));\n\n#if PJMEDIA_HAS_RTCP_XR && PJMEDIA_STREAM_ENABLE_XR\n    /* Set default RTCP XR enabled/disabled */\n    si->rtcp_xr_enabled = PJ_TRUE;\n#endif\n\n    /* Media type: */\n    si->type = PJMEDIA_TYPE_AUDIO;\n\n    /* Transport protocol */\n\n    /* At this point, transport type must be compatible,\n     * the transport instance will do more validation later.\n     */\n    status = pjmedia_sdp_transport_cmp(&rem_m->desc.transport,\n\t\t\t\t       &local_m->desc.transport);\n    if (status != PJ_SUCCESS)\n\treturn PJMEDIA_SDPNEG_EINVANSTP;\n\n    if (pj_stricmp(&local_m->desc.transport, &ID_RTP_AVP) == 0) {\n\n\tsi->proto = PJMEDIA_TP_PROTO_RTP_AVP;\n\n    } else if (pj_stricmp(&local_m->desc.transport, &ID_RTP_SAVP) == 0) {\n\n\tsi->proto = PJMEDIA_TP_PROTO_RTP_SAVP;\n\n    } else {\n\n\tsi->proto = PJMEDIA_TP_PROTO_UNKNOWN;\n\treturn PJ_SUCCESS;\n    }\n\n\n    /* Check address family in remote SDP */\n    rem_af = pj_AF_UNSPEC();\n    if (pj_stricmp(&rem_conn->net_type, &ID_IN)==0) {\n\tif (pj_stricmp(&rem_conn->addr_type, &ID_IP4)==0) {\n\t    rem_af = pj_AF_INET();\n\t} else if (pj_stricmp(&rem_conn->addr_type, &ID_IP6)==0) {\n\t    rem_af = pj_AF_INET6();\n\t}\n    }\n\n    if (rem_af==pj_AF_UNSPEC()) {\n\t/* Unsupported address family */\n\treturn PJ_EAFNOTSUP;\n    }\n\n    /* Set remote address: */\n    status = pj_sockaddr_init(rem_af, &si->rem_addr, &rem_conn->addr,\n\t\t\t      rem_m->desc.port);\n    if (status != PJ_SUCCESS) {\n\t/* Invalid IP address. */\n\treturn PJMEDIA_EINVALIDIP;\n    }\n\n    /* Check address family of local info */\n    local_af = pj_AF_UNSPEC();\n    if (pj_stricmp(&local_conn->net_type, &ID_IN)==0) {\n\tif (pj_stricmp(&local_conn->addr_type, &ID_IP4)==0) {\n\t    local_af = pj_AF_INET();\n\t} else if (pj_stricmp(&local_conn->addr_type, &ID_IP6)==0) {\n\t    local_af = pj_AF_INET6();\n\t}\n    }\n\n    if (local_af==pj_AF_UNSPEC()) {\n\t/* Unsupported address family */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Set remote address: */\n    status = pj_sockaddr_init(local_af, &local_addr, &local_conn->addr,\n\t\t\t      local_m->desc.port);\n    if (status != PJ_SUCCESS) {\n\t/* Invalid IP address. */\n\treturn PJMEDIA_EINVALIDIP;\n    }\n\n    /* Local and remote address family must match */\n    if (local_af != rem_af)\n\treturn PJ_EAFNOTSUP;\n\n    /* Media direction: */\n\n    if (local_m->desc.port == 0 ||\n\tpj_sockaddr_has_addr(&local_addr)==PJ_FALSE ||\n\tpj_sockaddr_has_addr(&si->rem_addr)==PJ_FALSE ||\n\tpjmedia_sdp_media_find_attr(local_m, &STR_INACTIVE, NULL)!=NULL)\n    {\n\t/* Inactive stream. */\n\n\tsi->dir = PJMEDIA_DIR_NONE;\n\n    } else if (pjmedia_sdp_media_find_attr(local_m, &STR_SENDONLY, NULL)!=NULL) {\n\n\t/* Send only stream. */\n\n\tsi->dir = PJMEDIA_DIR_ENCODING;\n\n    } else if (pjmedia_sdp_media_find_attr(local_m, &STR_RECVONLY, NULL)!=NULL) {\n\n\t/* Recv only stream. */\n\n\tsi->dir = PJMEDIA_DIR_DECODING;\n\n    } else {\n\n\t/* Send and receive stream. */\n\n\tsi->dir = PJMEDIA_DIR_ENCODING_DECODING;\n\n    }\n\n    /* No need to do anything else if stream is rejected */\n    if (local_m->desc.port == 0) {\n\treturn PJ_SUCCESS;\n    }\n\n    /* If \"rtcp\" attribute is present in the SDP, set the RTCP address\n     * from that attribute. Otherwise, calculate from RTP address.\n     */\n    attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr,\n\t\t\t\t  \"rtcp\", NULL);\n    if (attr) {\n\tpjmedia_sdp_rtcp_attr rtcp;\n\tstatus = pjmedia_sdp_attr_get_rtcp(attr, &rtcp);\n\tif (status == PJ_SUCCESS) {\n\t    if (rtcp.addr.slen) {\n\t\tstatus = pj_sockaddr_init(rem_af, &si->rem_rtcp, &rtcp.addr,\n\t\t\t\t\t  (pj_uint16_t)rtcp.port);\n\t    } else {\n\t\tpj_sockaddr_init(rem_af, &si->rem_rtcp, NULL,\n\t\t\t\t (pj_uint16_t)rtcp.port);\n\t\tpj_memcpy(pj_sockaddr_get_addr(&si->rem_rtcp),\n\t\t          pj_sockaddr_get_addr(&si->rem_addr),\n\t\t\t  pj_sockaddr_get_addr_len(&si->rem_addr));\n\t    }\n\t}\n    }\n\n    if (!pj_sockaddr_has_addr(&si->rem_rtcp)) {\n\tint rtcp_port;\n\n\tpj_memcpy(&si->rem_rtcp, &si->rem_addr, sizeof(pj_sockaddr));\n\trtcp_port = pj_sockaddr_get_port(&si->rem_addr) + 1;\n\tpj_sockaddr_set_port(&si->rem_rtcp, (pj_uint16_t)rtcp_port);\n    }\n\n\n    /* Get the payload number for receive channel. */\n    /*\n       Previously we used to rely on fmt[0] being the selected codec,\n       but some UA sends telephone-event as fmt[0] and this would\n       cause assert failure below.\n\n       Thanks Chris Hamilton <chamilton .at. cs.dal.ca> for this patch.\n\n    // And codec must be numeric!\n    if (!pj_isdigit(*local_m->desc.fmt[0].ptr) ||\n\t!pj_isdigit(*rem_m->desc.fmt[0].ptr))\n    {\n\treturn PJMEDIA_EINVALIDPT;\n    }\n\n    pt = pj_strtoul(&local_m->desc.fmt[0]);\n    pj_assert(PJMEDIA_RTP_PT_TELEPHONE_EVENTS==0 ||\n\t      pt != PJMEDIA_RTP_PT_TELEPHONE_EVENTS);\n    */\n\n    /* Get codec info and param */\n    status = get_audio_codec_info_param(si, pool, mgr, local_m, rem_m);\n\n    /* Leave SSRC to random. */\n    si->ssrc = pj_rand();\n\n    /* Set default jitter buffer parameter. */\n    si->jb_init = si->jb_max = si->jb_min_pre = si->jb_max_pre = -1;\n\n    return status;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/tonegen.c",
    "content": "/* $Id: tonegen.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/tonegen.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/silencedet.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n\n/* amplitude */\n#define AMP\tPJMEDIA_TONEGEN_VOLUME\n\n#ifndef M_PI\n#   define M_PI  ((DATA)3.141592653589793238462643383279)\n#endif\n\n#if PJMEDIA_TONEGEN_ALG==PJMEDIA_TONEGEN_SINE\n    #include <math.h>\n    #define DATA\tdouble\n\n    /*\n     * This is the good old tone generator using sin().\n     * Speed = 1347 usec to generate 1 second, 8KHz dual-tones (2.66GHz P4).\n     *         approx. 10.91 MIPS\n     *\n     *         506,535 usec/100.29 MIPS on ARM926EJ-S.\n     */\n    struct gen\n    {\n\tDATA add;\n\tDATA c;\n\tDATA vol;\n    };\n\n    #define GEN_INIT(var,R,F,A) var.add = ((DATA)F)/R, var.c=0, var.vol=A\n    #define GEN_SAMP(val,var)   val = (short)(sin(var.c * 2 * M_PI) * \\\n\t\t\t\t\t      var.vol); \\\n\t\t\t        var.c += var.add\n\n#elif PJMEDIA_TONEGEN_ALG==PJMEDIA_TONEGEN_FLOATING_POINT\n    #include <math.h>\n    #define DATA\tfloat\n\n    /*\n     * Default floating-point based tone generation using sine wave \n     * generation from:\n     *   http://www.musicdsp.org/showone.php?id=10.\n     * This produces good quality tone in relatively faster time than\n     * the normal sin() generator.\n     * Speed = 350 usec to generate 1 second, 8KHz dual-tones (2.66GHz P4).\n     *         approx. 2.84 MIPS\n     *\n     *         18,037 usec/3.57 MIPS on ARM926EJ-S.\n     */\n    struct gen\n    {\n\tDATA a, s0, s1;\n    };\n\n    #define GEN_INIT(var,R,F,A) var.a = (DATA) (2.0 * sin(M_PI * F / R)); \\\n\t\t\t        var.s0 = 0; \\\n\t\t\t        var.s1 = (DATA)(0 - (int)A)\n    #define GEN_SAMP(val,var)   var.s0 = var.s0 - var.a * var.s1; \\\n\t\t\t        var.s1 = var.s1 + var.a * var.s0; \\\n\t\t\t        val = (short) var.s0\n\n#elif PJMEDIA_TONEGEN_ALG==PJMEDIA_TONEGEN_FIXED_POINT_CORDIC\n    /* Cordic algorithm with 28 bit size, from:\n     * http://www.dcs.gla.ac.uk/~jhw/cordic/\n     * Speed = 742 usec to generate 1 second, 8KHz dual-tones (2.66GHz P4).\n     *         (PJMEDIA_TONEGEN_FIXED_POINT_CORDIC_LOOP=7)\n     *         approx. 6.01 MIPS\n     *\n     *         ARM926EJ-S results:\n     *\t        loop=7:   8,943 usec/1.77 MIPS\n     *\t\tloop=8:   9,872 usec/1.95 MIPS\n     *          loop=10: 11,662 usec/2.31 MIPS\n     *          loop=12: 13,561 usec/2.69 MIPS\n     */\n    #define CORDIC_1K\t\t0x026DD3B6\n    #define CORDIC_HALF_PI\t0x06487ED5\n    #define CORDIC_PI\t\t(CORDIC_HALF_PI * 2)\n    #define CORDIC_MUL_BITS\t26\n    #define CORDIC_MUL\t\t(1 << CORDIC_MUL_BITS)\n    #define CORDIC_NTAB\t\t28\n    #define CORDIC_LOOP\t\tPJMEDIA_TONEGEN_FIXED_POINT_CORDIC_LOOP\n\n    static int cordic_ctab [] = \n    {\n\t0x03243F6A, 0x01DAC670, 0x00FADBAF, 0x007F56EA, 0x003FEAB7, \n\t0x001FFD55, 0x000FFFAA, 0x0007FFF5, 0x0003FFFE, 0x0001FFFF, \n\t0x0000FFFF, 0x00007FFF, 0x00003FFF, 0x00001FFF, 0x00000FFF, \n\t0x000007FF, 0x000003FF, 0x000001FF, 0x000000FF, 0x0000007F, \n\t0x0000003F, 0x0000001F, 0x0000000F, 0x00000007, 0x00000003, \n\t0x00000001, 0x00000000, 0x00000000 \n    };\n\n    static pj_int32_t cordic(pj_int32_t theta, unsigned n)\n    {\n\tunsigned k;\n\tint d;\n\tpj_int32_t tx;\n\tpj_int32_t x = CORDIC_1K, y = 0, z = theta;\n\n\tfor (k=0; k<n; ++k) {\n\t    #if 0\n\t    d = (z>=0) ? 0 : -1;\n\t    #else\n\t    /* Only slightly (~2.5%) faster, but not portable? */\n\t     d = z>>27;\n\t    #endif\n\t    tx = x - (((y>>k) ^ d) - d);\n\t    y = y + (((x>>k) ^ d) - d);\n\t    z = z - ((cordic_ctab[k] ^ d) - d);\n\t    x = tx;\n\t}  \n\treturn y;\n    }\n\n    /* Note: theta must be uint32 here */\n    static pj_int32_t cordic_sin(pj_uint32_t theta, unsigned n)\n    {\n\tif (theta < CORDIC_HALF_PI)\n\t    return cordic(theta, n);\n\telse if (theta < CORDIC_PI)\n\t    return cordic(CORDIC_HALF_PI-(theta-CORDIC_HALF_PI), n);\n\telse if (theta < CORDIC_PI + CORDIC_HALF_PI)\n\t    return -cordic(theta - CORDIC_PI, n);\n\telse if (theta < 2 * CORDIC_PI)\n\t    return -cordic(CORDIC_HALF_PI-(theta-3*CORDIC_HALF_PI), n);\n\telse {\n\t    pj_assert(!\"Invalid cordic_sin() value\");\n\t    return 0;\n\t}\n    }\n\n    struct gen\n    {\n\tunsigned    add;\n\tpj_uint32_t c;\n\tunsigned    vol;\n    };\n\n    #define VOL(var,v)\t\t(((v) * var.vol) >> 15)\n    #define GEN_INIT(var,R,F,A)\tgen_init(&var, R, F, A)\n    #define GEN_SAMP(val,var)\tval = gen_samp(&var)\n\n    static void gen_init(struct gen *var, unsigned R, unsigned F, unsigned A)\n    {\n\tvar->add = 2*CORDIC_PI/R * F;\n\tvar->c = 0;\n\tvar->vol = A;\n    }\n\n    PJ_INLINE(short) gen_samp(struct gen *var)\n    {\n\tpj_int32_t val;\n\tval = cordic_sin(var->c, CORDIC_LOOP);\n\t/*val = (val * 32767) / CORDIC_MUL;\n\t *val = VOL((*var), val);\n\t */\n\tval = ((val >> 10) * var->vol) >> 16;\n\tvar->c += var->add;\n\tif (var->c > 2*CORDIC_PI)\n\t    var->c -= (2 * CORDIC_PI);\n\treturn (short) val;\n    }\n\n#elif PJMEDIA_TONEGEN_ALG==PJMEDIA_TONEGEN_FAST_FIXED_POINT\n\n    /* \n     * Fallback algorithm when floating point is disabled.\n     * This is a very fast fixed point tone generation using sine wave\n     * approximation from\n     *    http://www.audiomulch.com/~rossb/code/sinusoids/ \n     * Quality wise not so good, but it's blazing fast!\n     * Speed = 117 usec to generate 1 second, 8KHz dual-tones (2.66GHz P4).\n     *         approx. 0.95 MIPS\n     *\n     *         1,449 usec/0.29 MIPS on ARM926EJ-S.\n     */\n    PJ_INLINE(int) approximate_sin3(unsigned x)\n    {\t\n\t    unsigned s=-(int)(x>>31);\n\t    x+=x;\n\t    x=x>>16;\n\t    x*=x^0xffff;            // x=x*(2-x)\n\t    x+=x;                   // optional\n\t    return x^s;\n    }\n    struct gen\n    {\n\tunsigned add;\n\tunsigned c;\n\tunsigned vol;\n    };\n\n    #define MAXI\t\t((unsigned)0xFFFFFFFF)\n    #define SIN\t\t\tapproximate_sin3\n    #define VOL(var,v)\t\t(((v) * var.vol) >> 15)\n    #define GEN_INIT(var,R,F,A)\tvar.add = MAXI/R * F, var.c=0, var.vol=A\n    #define GEN_SAMP(val,var)\tval = (short) VOL(var,SIN(var.c)>>16); \\\n\t\t\t\tvar.c += var.add\n\n#else\n    #error \"PJMEDIA_TONEGEN_ALG is not set correctly\"\n#endif\n\nstruct gen_state\n{\n    struct gen tone1;\n    struct gen tone2;\n    pj_bool_t  has_tone2;\n};\n\n\nstatic void init_generate_single_tone(struct gen_state *state,\n\t\t\t\t      unsigned clock_rate, \n\t\t\t\t      unsigned freq,\n\t\t\t\t      unsigned vol)\n{\n    GEN_INIT(state->tone1,clock_rate,freq,vol);\n    state->has_tone2 = PJ_FALSE;\n}\n\nstatic void generate_single_tone(struct gen_state *state,\n\t\t\t\t unsigned channel_count,\n\t\t\t\t unsigned samples,\n\t\t\t\t short buf[]) \n{\n    short *end = buf + samples;\n\n    if (channel_count==1) {\n\n\twhile (buf < end) {\n\t    GEN_SAMP(*buf++, state->tone1);\n\t}\n\n    } else if (channel_count == 2) {\n\n\twhile (buf < end) {\n\t    GEN_SAMP(*buf, state->tone1);\n\t    *(buf+1) = *buf;\n\t    buf += 2;\n\t}\n    }\n}\n\n\nstatic void init_generate_dual_tone(struct gen_state *state,\n\t\t\t\t    unsigned clock_rate, \n\t\t\t\t    unsigned freq1,\n\t\t\t\t    unsigned freq2,\n\t\t\t\t    unsigned vol)\n{\n    GEN_INIT(state->tone1,clock_rate,freq1,vol);\n    GEN_INIT(state->tone2,clock_rate,freq2,vol);\n    state->has_tone2 = PJ_TRUE;\n}\n\n\nstatic void generate_dual_tone(struct gen_state *state,\n\t\t\t       unsigned channel_count,\n\t\t\t       unsigned samples,\n\t\t\t       short buf[]) \n{\n    short *end = buf + samples;\n\n    if (channel_count==1) {\n\tint val, val2;\n\twhile (buf < end) {\n\t    GEN_SAMP(val, state->tone1);\n\t    GEN_SAMP(val2, state->tone2);\n\t    *buf++ = (short)((val+val2) >> 1);\n\t}\n    } else if (channel_count == 2) {\n\tint val, val2;\n\twhile (buf < end) {\n\n\t    GEN_SAMP(val, state->tone1);\n\t    GEN_SAMP(val2, state->tone2);\n\t    val = (val + val2) >> 1;\n\n\t    *buf++ = (short)val;\n\t    *buf++ = (short)val;\n\t}\n    }\n}\n\n\nstatic void init_generate_tone(struct gen_state *state,\n\t\t\t       unsigned clock_rate, \n\t\t\t       unsigned freq1,\n\t\t\t       unsigned freq2,\n\t\t\t       unsigned vol)\n{\n    if (freq2)\n\tinit_generate_dual_tone(state, clock_rate, freq1, freq2 ,vol);\n    else\n\tinit_generate_single_tone(state, clock_rate, freq1,vol);\n}\n\n\nstatic void generate_tone(struct gen_state *state,\n\t\t\t  unsigned channel_count,\n\t\t\t  unsigned samples,\n\t\t\t  short buf[])\n{\n    if (!state->has_tone2)\n\tgenerate_single_tone(state, channel_count, samples, buf);\n    else\n\tgenerate_dual_tone(state, channel_count, samples, buf);\n}\n\n\n/****************************************************************************/\n\n#define SIGNATURE   PJMEDIA_SIG_PORT_TONEGEN\n#define THIS_FILE   \"tonegen.c\"\n\n#if 0\n#   define TRACE_(expr)\tPJ_LOG(4,expr)\n#else\n#   define TRACE_(expr)\n#endif\n\nenum flags\n{\n    PJMEDIA_TONE_INITIALIZED\t= 1,\n    PJMEDIA_TONE_ENABLE_FADE\t= 2\n};\n\nstruct tonegen\n{\n    pjmedia_port\tbase;\n\n    /* options */\n    unsigned\t\toptions;\n    unsigned\t\tplayback_options;\n    unsigned\t\tfade_in_len;\t/* fade in for this # of samples */\n    unsigned\t\tfade_out_len;\t/* fade out for this # of samples*/\n\n    /* lock */\n    pj_lock_t\t       *lock;\n\n    /* Digit map */\n    pjmedia_tone_digit_map  *digit_map;\n\n    /* Tone generation state */\n    struct gen_state\tstate;\n\n    /* Currently played digits: */\n    unsigned\t\tcount;\t\t    /* # of digits\t\t*/\n    unsigned\t\tcur_digit;\t    /* currently played\t\t*/\n    unsigned\t\tdig_samples;\t    /* sample pos in cur digit\t*/\n    pjmedia_tone_desc\tdigits[PJMEDIA_TONEGEN_MAX_DIGITS];/* array of digits*/\n};\n\n\n/* Default digit map is DTMF */\nstatic pjmedia_tone_digit_map digit_map = \n{\n    16,\n    {\n\t{ '0', 941,  1336 },\n\t{ '1', 697,  1209 },\n\t{ '2', 697,  1336 },\n\t{ '3', 697,  1477 },\n\t{ '4', 770,  1209 },\n\t{ '5', 770,  1336 },\n\t{ '6', 770,  1477 },\n\t{ '7', 852,  1209 },\n\t{ '8', 852,  1336 },\n\t{ '9', 852,  1477 },\n\t{ 'a', 697,  1633 },\n\t{ 'b', 770,  1633 },\n\t{ 'c', 852,  1633 },\n\t{ 'd', 941,  1633 },\n\t{ '*', 941,  1209 },\n\t{ '#', 941,  1477 },\n    }\n};\n\n\nstatic pj_status_t tonegen_get_frame(pjmedia_port *this_port, \n\t\t\t\t     pjmedia_frame *frame);\nstatic pj_status_t tonegen_destroy(pjmedia_port *this_port);\n\n/*\n * Create an instance of tone generator with the specified parameters.\n * When the tone generator is first created, it will be loaded with the\n * default digit map.\n */\nPJ_DEF(pj_status_t) pjmedia_tonegen_create2(pj_pool_t *pool,\n\t\t\t\t\t    const pj_str_t *name,\n\t\t\t\t\t    unsigned clock_rate,\n\t\t\t\t\t    unsigned channel_count,\n\t\t\t\t\t    unsigned samples_per_frame,\n\t\t\t\t\t    unsigned bits_per_sample,\n\t\t\t\t\t    unsigned options,\n\t\t\t\t\t    pjmedia_port **p_port)\n{\n    const pj_str_t STR_TONE_GEN = pj_str(\"tonegen\");\n    struct tonegen  *tonegen;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && clock_rate && channel_count && \n\t\t     samples_per_frame && bits_per_sample == 16 && \n\t\t     p_port != NULL, PJ_EINVAL);\n\n    /* Only support mono and stereo */\n    PJ_ASSERT_RETURN(channel_count==1 || channel_count==2, PJ_EINVAL);\n\n    /* Create and initialize port */\n    tonegen = PJ_POOL_ZALLOC_T(pool, struct tonegen);\n    if (name == NULL || name->slen == 0) name = &STR_TONE_GEN;\n    status = pjmedia_port_info_init(&tonegen->base.info, name, \n\t\t\t\t    SIGNATURE, clock_rate, channel_count, \n\t\t\t\t    bits_per_sample, samples_per_frame);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    tonegen->options = options;\n    tonegen->base.get_frame = &tonegen_get_frame;\n    tonegen->base.on_destroy = &tonegen_destroy;\n    tonegen->digit_map = &digit_map;\n\n    tonegen->fade_in_len = PJMEDIA_TONEGEN_FADE_IN_TIME * clock_rate / 1000;\n    tonegen->fade_out_len = PJMEDIA_TONEGEN_FADE_OUT_TIME * clock_rate / 1000;\n\n    /* Lock */\n    if (options & PJMEDIA_TONEGEN_NO_LOCK) {\n\tstatus = pj_lock_create_null_mutex(pool, \"tonegen\", &tonegen->lock);\n    } else {\n\tstatus = pj_lock_create_simple_mutex(pool, \"tonegen\", &tonegen->lock);\n    }\n\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    TRACE_((THIS_FILE, \"Tonegen created: %u/%u/%u/%u\", clock_rate, \n\t    channel_count, samples_per_frame, bits_per_sample));\n\n    /* Done */\n    *p_port = &tonegen->base;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_tonegen_create( pj_pool_t *pool,\n\t\t\t\t\t    unsigned clock_rate,\n\t\t\t\t\t    unsigned channel_count,\n\t\t\t\t\t    unsigned samples_per_frame,\n\t\t\t\t\t    unsigned bits_per_sample,\n\t\t\t\t\t    unsigned options,\n\t\t\t\t\t    pjmedia_port **p_port)\n{\n    return pjmedia_tonegen_create2(pool, NULL, clock_rate, channel_count,\n\t\t\t\t   samples_per_frame, bits_per_sample, \n\t\t\t\t   options, p_port);\n}\n\n\n/*\n * Check if the tone generator is still busy producing some tones.\n */\nPJ_DEF(pj_bool_t) pjmedia_tonegen_is_busy(pjmedia_port *port)\n{\n    struct tonegen *tonegen = (struct tonegen*) port;\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_TRUE);\n    return tonegen->count != 0;\n}\n\n\n/*\n * Instruct the tone generator to stop current processing.\n */\nPJ_DEF(pj_status_t) pjmedia_tonegen_stop(pjmedia_port *port)\n{\n    struct tonegen *tonegen = (struct tonegen*) port;\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVAL);\n\n    TRACE_((THIS_FILE, \"tonegen_stop()\"));\n\n    pj_lock_acquire(tonegen->lock);\n    tonegen->count = 0;\n    tonegen->cur_digit = 0;\n    tonegen->dig_samples = 0;\n    pj_lock_release(tonegen->lock);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Instruct the tone generator to stop current processing.\n */\nPJ_DEF(pj_status_t) pjmedia_tonegen_rewind(pjmedia_port *port)\n{\n    struct tonegen *tonegen = (struct tonegen*) port;\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVAL);\n\n    TRACE_((THIS_FILE, \"tonegen_rewind()\"));\n\n    /* Reset back to the first tone */\n    pj_lock_acquire(tonegen->lock);\n    tonegen->cur_digit = 0;\n    tonegen->dig_samples = 0;\n    pj_lock_release(tonegen->lock);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Callback to destroy tonegen\n */\nstatic pj_status_t tonegen_destroy(pjmedia_port *port)\n{\n    struct tonegen *tonegen = (struct tonegen*) port;\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVAL);\n\n    TRACE_((THIS_FILE, \"tonegen_destroy()\"));\n\n    pj_lock_acquire(tonegen->lock);\n    pj_lock_release(tonegen->lock);\n\n    pj_lock_destroy(tonegen->lock);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Fill a frame with tones.\n */\nstatic pj_status_t tonegen_get_frame(pjmedia_port *port, \n\t\t\t\t     pjmedia_frame *frame)\n{\n    struct tonegen *tonegen = (struct tonegen*) port;\n    short *dst, *end;\n    unsigned clock_rate = PJMEDIA_PIA_SRATE(&tonegen->base.info);\n\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVAL);\n\n    pj_lock_acquire(tonegen->lock);\n\n    if (tonegen->count == 0) {\n\t/* We don't have digits to play */\n\tframe->type = PJMEDIA_FRAME_TYPE_NONE;\n\tgoto on_return;\n    }\n\n    if (tonegen->cur_digit > tonegen->count) {\n\t/* We have played all the digits */\n\tif ((tonegen->options|tonegen->playback_options)&PJMEDIA_TONEGEN_LOOP)\n\t{\n\t    /* Reset back to the first tone */\n\t    tonegen->cur_digit = 0;\n\t    tonegen->dig_samples = 0;\n\n\t    TRACE_((THIS_FILE, \"tonegen_get_frame(): rewind\"));\n\n\t} else {\n\t    tonegen->count = 0;\n\t    tonegen->cur_digit = 0;\n\t    frame->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    TRACE_((THIS_FILE, \"tonegen_get_frame(): no more digit\"));\n\t    goto on_return;\n\t}\n    }\n\n    if (tonegen->dig_samples>=(tonegen->digits[tonegen->cur_digit].on_msec+\n\t\t\t       tonegen->digits[tonegen->cur_digit].off_msec)*\n\t\t\t       clock_rate / 1000)\n    {\n\t/* We have finished with current digit */\n\ttonegen->cur_digit++;\n\ttonegen->dig_samples = 0;\n\n\tTRACE_((THIS_FILE, \"tonegen_get_frame(): next digit\"));\n    }\n\n    if (tonegen->cur_digit >= tonegen->count) {\n\t/* After we're finished with the last digit, we have played all \n\t * the digits \n\t */\n\tif ((tonegen->options|tonegen->playback_options)&PJMEDIA_TONEGEN_LOOP)\n\t{\n\t    /* Reset back to the first tone */\n\t    tonegen->cur_digit = 0;\n\t    tonegen->dig_samples = 0;\n\n\t    TRACE_((THIS_FILE, \"tonegen_get_frame(): rewind\"));\n\n\t} else {\n\t    tonegen->count = 0;\n\t    tonegen->cur_digit = 0;\n\t    frame->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    TRACE_((THIS_FILE, \"tonegen_get_frame(): no more digit\"));\n\t    goto on_return;\n\t}\n    }\n    \n    dst = (short*) frame->buf;\n    end = dst + PJMEDIA_PIA_SPF(&port->info);\n\n    while (dst < end) {\n\tpjmedia_tone_desc *dig = &tonegen->digits[tonegen->cur_digit];\n\tunsigned required, cnt, on_samp, off_samp;\n\n\trequired = (unsigned)(end - dst);\n\ton_samp = dig->on_msec * clock_rate / 1000;\n\toff_samp = dig->off_msec * clock_rate / 1000;\n\n\t/* Init tonegen */\n\tif (tonegen->dig_samples == 0 && \n\t    (tonegen->count!=1 || !(dig->flags & PJMEDIA_TONE_INITIALIZED)))\n\t{\n\t    init_generate_tone(&tonegen->state,\n\t\t               PJMEDIA_PIA_SRATE(&port->info),\n\t\t\t       dig->freq1, dig->freq2, dig->volume);\n\t    dig->flags |= PJMEDIA_TONE_INITIALIZED;\n\t    if (tonegen->cur_digit > 0) {\n\t\t/* Clear initialized flag of previous digit */\n\t\ttonegen->digits[tonegen->cur_digit-1].flags &= \n\t\t\t\t\t\t(~PJMEDIA_TONE_INITIALIZED);\n\t    }\n\t}\n\n\t/* Add tone signal */\n\tif (tonegen->dig_samples < on_samp) {\n\t    cnt = on_samp - tonegen->dig_samples;\n\t    if (cnt > required)\n\t\tcnt = required;\n\t    generate_tone(&tonegen->state,\n\t\t\t  PJMEDIA_PIA_CCNT(&port->info),\n\t\t\t  cnt, dst);\n\n\t    dst += cnt;\n\t    tonegen->dig_samples += cnt;\n\t    required -= cnt;\n\n\t    if ((dig->flags & PJMEDIA_TONE_ENABLE_FADE) && \n\t\ttonegen->dig_samples == cnt) \n\t    {\n\t\t/* Fade in */\n\t\tshort *samp = (dst - cnt);\n\t\tshort *samp_end;\n\n\t\tif (cnt > tonegen->fade_in_len)\n\t\t    cnt = tonegen->fade_in_len;\n\t\tsamp_end = samp + cnt;\n\t\tif (cnt) {\n\t\t    const unsigned step = 0xFFFF / cnt;\n\t\t    unsigned scale = 0;\n\n\t\t    for (; samp < samp_end; ++samp) {\n\t\t\t(*samp) = (short)(((*samp) * scale) >> 16);\n\t\t\tscale += step;\n\t\t    }\n\t\t}\n\t    } else if ((dig->flags & PJMEDIA_TONE_ENABLE_FADE) &&\n\t\t\ttonegen->dig_samples==on_samp) \n\t    {\n\t\t/* Fade out */\n\t\tif (cnt > tonegen->fade_out_len)\n\t\t    cnt = tonegen->fade_out_len;\n\t\tif (cnt) {\n\t\t    short *samp = (dst - cnt);\n\t\t    const unsigned step = 0xFFFF / cnt;\n\t\t    unsigned scale = 0xFFFF - step;\n\n\t\t    for (; samp < dst; ++samp) {\n\t\t\t(*samp) = (short)(((*samp) * scale) >> 16);\n\t\t\tscale -= step;\n\t\t    }\n\t\t}\n\t    }\n\n\t    if (dst == end)\n\t\tbreak;\n\t}\n\n\t/* Add silence signal */\n\tcnt = off_samp + on_samp - tonegen->dig_samples;\n\tif (cnt > required)\n\t    cnt = required;\n\tpjmedia_zero_samples(dst, cnt);\n\tdst += cnt;\n\ttonegen->dig_samples += cnt;\n\n\t/* Move to next digit if we're finished with this tone */\n\tif (tonegen->dig_samples >= on_samp + off_samp) {\n\t    tonegen->cur_digit++;\n\t    tonegen->dig_samples = 0;\n\n\t    if (tonegen->cur_digit >= tonegen->count) {\n\t\t/* All digits have been played */\n\t\tif ((tonegen->options & PJMEDIA_TONEGEN_LOOP) ||\n\t\t    (tonegen->playback_options & PJMEDIA_TONEGEN_LOOP))\n\t\t{\n\t\t    tonegen->cur_digit = 0;\n\t\t} else {\n\t\t    break;\n\t\t}\n\t    }\n\t}\n    }\n\n    if (dst < end)\n\tpjmedia_zero_samples(dst, (unsigned)(end-dst));\n\n    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    frame->size = PJMEDIA_PIA_AVG_FSZ(&port->info);\n\n    TRACE_((THIS_FILE, \"tonegen_get_frame(): frame created, level=%u\",\n\t    pjmedia_calc_avg_signal((pj_int16_t*)frame->buf, frame->size/2)));\n\n    if (tonegen->cur_digit >= tonegen->count) {\n\tif ((tonegen->options|tonegen->playback_options)&PJMEDIA_TONEGEN_LOOP)\n\t{\n\t    /* Reset back to the first tone */\n\t    tonegen->cur_digit = 0;\n\t    tonegen->dig_samples = 0;\n\n\t    TRACE_((THIS_FILE, \"tonegen_get_frame(): rewind\"));\n\n\t} else {\n\t    tonegen->count = 0;\n\t    tonegen->cur_digit = 0;\n\n\t    TRACE_((THIS_FILE, \"tonegen_get_frame(): no more digit\"));\n\t}\n    }\n\non_return:\n    pj_lock_release(tonegen->lock);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Play tones.\n */\nPJ_DEF(pj_status_t) pjmedia_tonegen_play( pjmedia_port *port,\n\t\t\t\t\t  unsigned count,\n\t\t\t\t\t  const pjmedia_tone_desc tones[],\n\t\t\t\t\t  unsigned options)\n{\n    struct tonegen *tonegen = (struct tonegen*) port;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(port && port->info.signature == SIGNATURE &&\n\t\t     count && tones, PJ_EINVAL);\n\n    /* Don't put more than available buffer */\n    PJ_ASSERT_RETURN(count+tonegen->count <= PJMEDIA_TONEGEN_MAX_DIGITS,\n\t\t     PJ_ETOOMANY);\n\n    pj_lock_acquire(tonegen->lock);\n\n    /* Set playback options */\n    tonegen->playback_options = options;\n    \n    /* Copy digits */\n    pj_memcpy(tonegen->digits + tonegen->count,\n\t      tones, count * sizeof(pjmedia_tone_desc));\n    \n    /* Normalize volume, and check if we need to disable fading.\n     * Disable fading if tone off time is zero. Application probably\n     * wants to play this tone continuously (e.g. dial tone).\n     */\n    for (i=0; i<count; ++i) {\n\tpjmedia_tone_desc *t = &tonegen->digits[i+tonegen->count];\n\tif (t->volume == 0)\n\t    t->volume = AMP;\n\telse if (t->volume < 0)\n\t    t->volume = (short) -t->volume;\n\t/* Reset flags */\n\tt->flags = 0;\n\tif (t->off_msec != 0)\n\t    t->flags |= PJMEDIA_TONE_ENABLE_FADE;\n    }\n\n    tonegen->count += count;\n\n    pj_lock_release(tonegen->lock);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Play digits.\n */\nPJ_DEF(pj_status_t) pjmedia_tonegen_play_digits( pjmedia_port *port,\n\t\t\t\t\t\t unsigned count,\n\t\t\t\t\t\t const pjmedia_tone_digit digits[],\n\t\t\t\t\t\t unsigned options)\n{\n    struct tonegen *tonegen = (struct tonegen*) port;\n    pjmedia_tone_desc tones[PJMEDIA_TONEGEN_MAX_DIGITS];\n    const pjmedia_tone_digit_map *map;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(port && port->info.signature == SIGNATURE &&\n\t\t     count && digits, PJ_EINVAL);\n    PJ_ASSERT_RETURN(count < PJMEDIA_TONEGEN_MAX_DIGITS, PJ_ETOOMANY);\n\n    pj_lock_acquire(tonegen->lock);\n\n    map = tonegen->digit_map;\n\n    for (i=0; i<count; ++i) {\n\tint d = pj_tolower(digits[i].digit);\n\tunsigned j;\n\n\t/* Translate ASCII digits with digitmap */\n\tfor (j=0; j<map->count; ++j) {\n\t    if (d == map->digits[j].digit)\n\t\tbreak;\n\t}\n\tif (j == map->count) {\n\t    pj_lock_release(tonegen->lock);\n\t    return PJMEDIA_RTP_EINDTMF;\n\t}\n\n\ttones[i].freq1 = map->digits[j].freq1;\n\ttones[i].freq2 = map->digits[j].freq2;\n\ttones[i].on_msec = digits[i].on_msec;\n\ttones[i].off_msec = digits[i].off_msec;\n\ttones[i].volume = digits[i].volume;\n    }\n\n    pj_lock_release(tonegen->lock);\n\n    return pjmedia_tonegen_play(port, count, tones, options);\n}\n\n\n/*\n * Get the digit-map currently used by this tone generator.\n */\nPJ_DEF(pj_status_t) pjmedia_tonegen_get_digit_map(pjmedia_port *port,\n\t\t\t\t\t\t  const pjmedia_tone_digit_map **m)\n{\n    struct tonegen *tonegen = (struct tonegen*) port;\n    \n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVAL);\n    PJ_ASSERT_RETURN(m != NULL, PJ_EINVAL);\n\n    *m = tonegen->digit_map;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Set digit map to be used by the tone generator.\n */\nPJ_DEF(pj_status_t) pjmedia_tonegen_set_digit_map(pjmedia_port *port,\n\t\t\t\t\t\t  pjmedia_tone_digit_map *m)\n{\n    struct tonegen *tonegen = (struct tonegen*) port;\n    \n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVAL);\n    PJ_ASSERT_RETURN(m != NULL, PJ_EINVAL);\n\n    pj_lock_acquire(tonegen->lock);\n\n    tonegen->digit_map = m;\n\n    pj_lock_release(tonegen->lock);\n\n    return PJ_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/transport_adapter_sample.c",
    "content": "/* $Id: transport_adapter_sample.c 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/transport_adapter_sample.h>\n#include <pjmedia/endpoint.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n\n\n/* Transport functions prototypes */\nstatic pj_status_t transport_get_info (pjmedia_transport *tp,\n\t\t\t\t       pjmedia_transport_info *info);\nstatic pj_status_t transport_attach   (pjmedia_transport *tp,\n\t\t\t\t       void *user_data,\n\t\t\t\t       const pj_sockaddr_t *rem_addr,\n\t\t\t\t       const pj_sockaddr_t *rem_rtcp,\n\t\t\t\t       unsigned addr_len,\n\t\t\t\t       void (*rtp_cb)(void*,\n\t\t\t\t\t\t      void*,\n\t\t\t\t\t\t      pj_ssize_t),\n\t\t\t\t       void (*rtcp_cb)(void*,\n\t\t\t\t\t\t       void*,\n\t\t\t\t\t\t       pj_ssize_t));\nstatic void\t   transport_detach   (pjmedia_transport *tp,\n\t\t\t\t       void *strm);\nstatic pj_status_t transport_send_rtp( pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_send_rtcp(pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_send_rtcp2(pjmedia_transport *tp,\n\t\t\t\t       const pj_sockaddr_t *addr,\n\t\t\t\t       unsigned addr_len,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_media_create(pjmedia_transport *tp,\n\t\t\t\t       pj_pool_t *sdp_pool,\n\t\t\t\t       unsigned options,\n\t\t\t\t       const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t       unsigned media_index);\nstatic pj_status_t transport_encode_sdp(pjmedia_transport *tp,\n\t\t\t\t       pj_pool_t *sdp_pool,\n\t\t\t\t       pjmedia_sdp_session *local_sdp,\n\t\t\t\t       const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t       unsigned media_index);\nstatic pj_status_t transport_media_start (pjmedia_transport *tp,\n\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t       const pjmedia_sdp_session *local_sdp,\n\t\t\t\t       const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t       unsigned media_index);\nstatic pj_status_t transport_media_stop(pjmedia_transport *tp);\nstatic pj_status_t transport_simulate_lost(pjmedia_transport *tp,\n\t\t\t\t       pjmedia_dir dir,\n\t\t\t\t       unsigned pct_lost);\nstatic pj_status_t transport_destroy  (pjmedia_transport *tp);\n\n\n/* The transport operations */\nstatic struct pjmedia_transport_op tp_adapter_op = \n{\n    &transport_get_info,\n    &transport_attach,\n    &transport_detach,\n    &transport_send_rtp,\n    &transport_send_rtcp,\n    &transport_send_rtcp2,\n    &transport_media_create,\n    &transport_encode_sdp,\n    &transport_media_start,\n    &transport_media_stop,\n    &transport_simulate_lost,\n    &transport_destroy\n};\n\n\n/* The transport adapter instance */\nstruct tp_adapter\n{\n    pjmedia_transport\t base;\n    pj_bool_t\t\t del_base;\n\n    pj_pool_t\t\t*pool;\n\n    /* Stream information. */\n    void\t\t*stream_user_data;\n    void\t       (*stream_rtp_cb)(void *user_data,\n\t\t\t\t\tvoid *pkt,\n\t\t\t\t\tpj_ssize_t);\n    void\t       (*stream_rtcp_cb)(void *user_data,\n\t\t\t\t\t void *pkt,\n\t\t\t\t\t pj_ssize_t);\n\n\n    /* Add your own member here.. */\n    pjmedia_transport\t*slave_tp;\n};\n\n\n/*\n * Create the adapter.\n */\nPJ_DEF(pj_status_t) pjmedia_tp_adapter_create( pjmedia_endpt *endpt,\n\t\t\t\t\t       const char *name,\n\t\t\t\t\t       pjmedia_transport *transport,\n\t\t\t\t\t       pj_bool_t del_base,\n\t\t\t\t\t       pjmedia_transport **p_tp)\n{\n    pj_pool_t *pool;\n    struct tp_adapter *adapter;\n\n    if (name == NULL)\n\tname = \"tpad%p\";\n\n    /* Create the pool and initialize the adapter structure */\n    pool = pjmedia_endpt_create_pool(endpt, name, 512, 512);\n    adapter = PJ_POOL_ZALLOC_T(pool, struct tp_adapter);\n    adapter->pool = pool;\n    pj_ansi_strncpy(adapter->base.name, pool->obj_name, \n\t\t    sizeof(adapter->base.name));\n    adapter->base.type = (pjmedia_transport_type)\n\t\t\t (PJMEDIA_TRANSPORT_TYPE_USER + 1);\n    adapter->base.op = &tp_adapter_op;\n\n    /* Save the transport as the slave transport */\n    adapter->slave_tp = transport;\n    adapter->del_base = del_base;\n\n    /* Done */\n    *p_tp = &adapter->base;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * get_info() is called to get the transport addresses to be put\n * in SDP c= line and a=rtcp line.\n */\nstatic pj_status_t transport_get_info(pjmedia_transport *tp,\n\t\t\t\t      pjmedia_transport_info *info)\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)tp;\n\n    /* Since we don't have our own connection here, we just pass\n     * this function to the slave transport.\n     */\n    return pjmedia_transport_get_info(adapter->slave_tp, info);\n}\n\n\n/* This is our RTP callback, that is called by the slave transport when it\n * receives RTP packet.\n */\nstatic void transport_rtp_cb(void *user_data, void *pkt, pj_ssize_t size)\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)user_data;\n\n    pj_assert(adapter->stream_rtp_cb != NULL);\n\n    /* Call stream's callback */\n    adapter->stream_rtp_cb(adapter->stream_user_data, pkt, size);\n}\n\n/* This is our RTCP callback, that is called by the slave transport when it\n * receives RTCP packet.\n */\nstatic void transport_rtcp_cb(void *user_data, void *pkt, pj_ssize_t size)\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)user_data;\n\n    pj_assert(adapter->stream_rtcp_cb != NULL);\n\n    /* Call stream's callback */\n    adapter->stream_rtcp_cb(adapter->stream_user_data, pkt, size);\n}\n\n\n/*\n * attach() is called by stream to register callbacks that we should\n * call on receipt of RTP and RTCP packets.\n */\nstatic pj_status_t transport_attach(pjmedia_transport *tp,\n\t\t\t\t    void *user_data,\n\t\t\t\t    const pj_sockaddr_t *rem_addr,\n\t\t\t\t    const pj_sockaddr_t *rem_rtcp,\n\t\t\t\t    unsigned addr_len,\n\t\t\t\t    void (*rtp_cb)(void*,\n\t\t\t\t\t\t   void*,\n\t\t\t\t\t\t   pj_ssize_t),\n\t\t\t\t    void (*rtcp_cb)(void*,\n\t\t\t\t\t\t    void*,\n\t\t\t\t\t\t    pj_ssize_t))\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)tp;\n    pj_status_t status;\n\n    /* In this example, we will save the stream information and callbacks\n     * to our structure, and we will register different RTP/RTCP callbacks\n     * instead.\n     */\n    pj_assert(adapter->stream_user_data == NULL);\n    adapter->stream_user_data = user_data;\n    adapter->stream_rtp_cb = rtp_cb;\n    adapter->stream_rtcp_cb = rtcp_cb;\n\n    status = pjmedia_transport_attach(adapter->slave_tp, adapter, rem_addr,\n\t\t\t\t      rem_rtcp, addr_len, &transport_rtp_cb,\n\t\t\t\t      &transport_rtcp_cb);\n    if (status != PJ_SUCCESS) {\n\tadapter->stream_user_data = NULL;\n\tadapter->stream_rtp_cb = NULL;\n\tadapter->stream_rtcp_cb = NULL;\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* \n * detach() is called when the media is terminated, and the stream is \n * to be disconnected from us.\n */\nstatic void transport_detach(pjmedia_transport *tp, void *strm)\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)tp;\n    \n    PJ_UNUSED_ARG(strm);\n\n    if (adapter->stream_user_data != NULL) {\n\tpjmedia_transport_detach(adapter->slave_tp, adapter);\n\tadapter->stream_user_data = NULL;\n\tadapter->stream_rtp_cb = NULL;\n\tadapter->stream_rtcp_cb = NULL;\n    }\n}\n\n\n/*\n * send_rtp() is called to send RTP packet. The \"pkt\" and \"size\" argument \n * contain both the RTP header and the payload.\n */\nstatic pj_status_t transport_send_rtp( pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size)\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)tp;\n\n    /* You may do some processing to the RTP packet here if you want. */\n\n    /* Send the packet using the slave transport */\n    return pjmedia_transport_send_rtp(adapter->slave_tp, pkt, size);\n}\n\n\n/*\n * send_rtcp() is called to send RTCP packet. The \"pkt\" and \"size\" argument\n * contain the RTCP packet.\n */\nstatic pj_status_t transport_send_rtcp(pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size)\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)tp;\n\n    /* You may do some processing to the RTCP packet here if you want. */\n\n    /* Send the packet using the slave transport */\n    return pjmedia_transport_send_rtcp(adapter->slave_tp, pkt, size);\n}\n\n\n/*\n * This is another variant of send_rtcp(), with the alternate destination\n * address in the argument.\n */\nstatic pj_status_t transport_send_rtcp2(pjmedia_transport *tp,\n\t\t\t\t        const pj_sockaddr_t *addr,\n\t\t\t\t        unsigned addr_len,\n\t\t\t\t        const void *pkt,\n\t\t\t\t        pj_size_t size)\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)tp;\n    return pjmedia_transport_send_rtcp2(adapter->slave_tp, addr, addr_len, \n\t\t\t\t\tpkt, size);\n}\n\n/*\n * The media_create() is called when the transport is about to be used for\n * a new call.\n */\nstatic pj_status_t transport_media_create(pjmedia_transport *tp,\n\t\t\t\t          pj_pool_t *sdp_pool,\n\t\t\t\t          unsigned options,\n\t\t\t\t          const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t          unsigned media_index)\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)tp;\n\n    /* if \"rem_sdp\" is not NULL, it means we are UAS. You may do some\n     * inspections on the incoming SDP to verify that the SDP is acceptable\n     * for us. If the SDP is not acceptable, we can reject the SDP by \n     * returning non-PJ_SUCCESS.\n     */\n    if (rem_sdp) {\n\t/* Do your stuff.. */\n    }\n\n    /* Once we're done with our initialization, pass the call to the\n     * slave transports to let it do it's own initialization too.\n     */\n    return pjmedia_transport_media_create(adapter->slave_tp, sdp_pool, options,\n\t\t\t\t\t   rem_sdp, media_index);\n}\n\n/*\n * The encode_sdp() is called when we're about to send SDP to remote party,\n * either as SDP offer or as SDP answer.\n */\nstatic pj_status_t transport_encode_sdp(pjmedia_transport *tp,\n\t\t\t\t        pj_pool_t *sdp_pool,\n\t\t\t\t        pjmedia_sdp_session *local_sdp,\n\t\t\t\t        const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t        unsigned media_index)\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)tp;\n\n    /* If \"rem_sdp\" is not NULL, it means we're encoding SDP answer. You may\n     * do some more checking on the SDP's once again to make sure that\n     * everything is okay before we send SDP.\n     */\n    if (rem_sdp) {\n\t/* Do checking stuffs here.. */\n    }\n\n    /* You may do anything to the local_sdp, e.g. adding new attributes, or\n     * even modifying the SDP if you want.\n     */\n    if (1) {\n\t/* Say we add a proprietary attribute here.. */\n\tpjmedia_sdp_attr *my_attr;\n\n\tmy_attr = PJ_POOL_ALLOC_T(sdp_pool, pjmedia_sdp_attr);\n\tpj_strdup2(sdp_pool, &my_attr->name, \"X-adapter\");\n\tpj_strdup2(sdp_pool, &my_attr->value, \"some value\");\n\n\tpjmedia_sdp_attr_add(&local_sdp->media[media_index]->attr_count,\n\t\t\t     local_sdp->media[media_index]->attr,\n\t\t\t     my_attr);\n    }\n\n    /* And then pass the call to slave transport to let it encode its \n     * information in the SDP. You may choose to call encode_sdp() to slave\n     * first before adding your custom attributes if you want.\n     */\n    return pjmedia_transport_encode_sdp(adapter->slave_tp, sdp_pool, local_sdp,\n\t\t\t\t\trem_sdp, media_index);\n}\n\n/*\n * The media_start() is called once both local and remote SDP have been\n * negotiated successfully, and the media is ready to start. Here we can start\n * committing our processing.\n */\nstatic pj_status_t transport_media_start(pjmedia_transport *tp,\n\t\t\t\t         pj_pool_t *pool,\n\t\t\t\t         const pjmedia_sdp_session *local_sdp,\n\t\t\t\t         const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t         unsigned media_index)\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)tp;\n\n    /* Do something.. */\n\n    /* And pass the call to the slave transport */\n    return pjmedia_transport_media_start(adapter->slave_tp, pool, local_sdp,\n\t\t\t\t\t rem_sdp, media_index);\n}\n\n/*\n * The media_stop() is called when media has been stopped.\n */\nstatic pj_status_t transport_media_stop(pjmedia_transport *tp)\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)tp;\n\n    /* Do something.. */\n\n    /* And pass the call to the slave transport */\n    return pjmedia_transport_media_stop(adapter->slave_tp);\n}\n\n/*\n * simulate_lost() is called to simulate packet lost\n */\nstatic pj_status_t transport_simulate_lost(pjmedia_transport *tp,\n\t\t\t\t           pjmedia_dir dir,\n\t\t\t\t           unsigned pct_lost)\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)tp;\n    return pjmedia_transport_simulate_lost(adapter->slave_tp, dir, pct_lost);\n}\n\n/*\n * destroy() is called when the transport is no longer needed.\n */\nstatic pj_status_t transport_destroy  (pjmedia_transport *tp)\n{\n    struct tp_adapter *adapter = (struct tp_adapter*)tp;\n\n    /* Close the slave transport */\n    if (adapter->del_base) {\n\tpjmedia_transport_close(adapter->slave_tp);\n    }\n\n    /* Self destruct.. */\n    pj_pool_release(adapter->pool);\n\n    return PJ_SUCCESS;\n}\n\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/transport_ice.c",
    "content": "/* $Id: transport_ice.c 4350 2013-02-15 03:57:31Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/transport_ice.h>\n#include <pjnath/errno.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n\n#define THIS_FILE   \"transport_ice.c\"\n#if 0\n#   define TRACE__(expr)    PJ_LOG(5,expr)\n#else\n#   define TRACE__(expr)\n#endif\n\nenum oa_role\n{\n    ROLE_NONE,\n    ROLE_OFFERER,\n    ROLE_ANSWERER\n};\n\nstruct sdp_state\n{\n    unsigned\t\tmatch_comp_cnt;\t/* Matching number of components    */\n    pj_bool_t\t\tice_mismatch;\t/* Address doesn't match candidates */\n    pj_bool_t\t\tice_restart;\t/* Offer to restart ICE\t\t    */\n    pj_ice_sess_role\tlocal_role;\t/* Our role\t\t\t    */\n};\n\nstruct transport_ice\n{\n    pjmedia_transport\t base;\n    pj_pool_t\t\t*pool;\n    int\t\t\t af;\n    unsigned\t\t options;\t/**< Transport options.\t\t    */\n\n    unsigned\t\t comp_cnt;\n    pj_ice_strans\t*ice_st;\n\n    pjmedia_ice_cb\t cb;\n    unsigned\t\t media_option;\n\n    pj_bool_t\t\t initial_sdp;\n    enum oa_role\t oa_role;\t/**< Last role in SDP offer/answer  */\n    struct sdp_state\t rem_offer_state;/**< Describes the remote offer    */\n\n    void\t\t*stream;\n    pj_sockaddr\t\t remote_rtp;\n    pj_sockaddr\t\t remote_rtcp;\n    unsigned\t\t addr_len;\t/**< Length of addresses.\t    */\n\n    pj_bool_t\t\t use_ice;\n    pj_sockaddr\t\t rtp_src_addr;\t/**< Actual source RTP address.\t    */\n    pj_sockaddr\t\t rtcp_src_addr;\t/**< Actual source RTCP address.    */\n    unsigned\t\t rtp_src_cnt;\t/**< How many pkt from this addr.   */\n    unsigned\t\t rtcp_src_cnt;  /**< How many pkt from this addr.   */\n\n    unsigned\t\t tx_drop_pct;\t/**< Percent of tx pkts to drop.    */\n    unsigned\t\t rx_drop_pct;\t/**< Percent of rx pkts to drop.    */\n\n    void\t       (*rtp_cb)(void*,\n\t\t\t         void*,\n\t\t\t\t pj_ssize_t);\n    void\t       (*rtcp_cb)(void*,\n\t\t\t\t  void*,\n\t\t\t\t  pj_ssize_t);\n};\n\n\n/*\n * These are media transport operations.\n */\nstatic pj_status_t transport_get_info (pjmedia_transport *tp,\n\t\t\t\t       pjmedia_transport_info *info);\nstatic pj_status_t transport_attach   (pjmedia_transport *tp,\n\t\t\t\t       void *user_data,\n\t\t\t\t       const pj_sockaddr_t *rem_addr,\n\t\t\t\t       const pj_sockaddr_t *rem_rtcp,\n\t\t\t\t       unsigned addr_len,\n\t\t\t\t       void (*rtp_cb)(void*,\n\t\t\t\t\t\t      void*,\n\t\t\t\t\t\t      pj_ssize_t),\n\t\t\t\t       void (*rtcp_cb)(void*,\n\t\t\t\t\t\t       void*,\n\t\t\t\t\t\t       pj_ssize_t));\nstatic void\t   transport_detach   (pjmedia_transport *tp,\n\t\t\t\t       void *strm);\nstatic pj_status_t transport_send_rtp( pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_send_rtcp(pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_send_rtcp2(pjmedia_transport *tp,\n\t\t\t\t       const pj_sockaddr_t *addr,\n\t\t\t\t       unsigned addr_len,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_media_create(pjmedia_transport *tp,\n\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t       unsigned options,\n\t\t\t\t       const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t       unsigned media_index);\nstatic pj_status_t transport_encode_sdp(pjmedia_transport *tp,\n\t\t\t\t        pj_pool_t *tmp_pool,\n\t\t\t\t        pjmedia_sdp_session *sdp_local,\n\t\t\t\t        const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t        unsigned media_index);\nstatic pj_status_t transport_media_start(pjmedia_transport *tp,\n\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t       const pjmedia_sdp_session *sdp_local,\n\t\t\t\t       const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t       unsigned media_index);\nstatic pj_status_t transport_media_stop(pjmedia_transport *tp);\nstatic pj_status_t transport_simulate_lost(pjmedia_transport *tp,\n\t\t\t\t       pjmedia_dir dir,\n\t\t\t\t       unsigned pct_lost);\nstatic pj_status_t transport_destroy  (pjmedia_transport *tp);\n\n/*\n * And these are ICE callbacks.\n */\nstatic void ice_on_rx_data(pj_ice_strans *ice_st, \n\t\t\t   unsigned comp_id, \n\t\t\t   void *pkt, pj_size_t size,\n\t\t\t   const pj_sockaddr_t *src_addr,\n\t\t\t   unsigned src_addr_len);\nstatic void ice_on_ice_complete(pj_ice_strans *ice_st, \n\t\t\t\tpj_ice_strans_op op,\n\t\t\t        pj_status_t status);\nstatic void ice_on_ice_state(pj_ice_strans *ice_st,\n\t\t\t     pj_ice_strans_state prev,\n\t\t\t     pj_ice_strans_state curr);\n\n\nstatic pjmedia_transport_op transport_ice_op = \n{\n    &transport_get_info,\n    &transport_attach,\n    &transport_detach,\n    &transport_send_rtp,\n    &transport_send_rtcp,\n    &transport_send_rtcp2,\n    &transport_media_create,\n    &transport_encode_sdp,\n    &transport_media_start,\n    &transport_media_stop,\n    &transport_simulate_lost,\n    &transport_destroy\n};\n\nstatic const pj_str_t STR_RTP_AVP\t= { \"RTP/AVP\", 7 };\nstatic const pj_str_t STR_CANDIDATE\t= { \"candidate\", 9};\nstatic const pj_str_t STR_REM_CAND\t= { \"remote-candidates\", 17 };\nstatic const pj_str_t STR_ICE_LITE\t= { \"ice-lite\", 8};\nstatic const pj_str_t STR_ICE_MISMATCH\t= { \"ice-mismatch\", 12};\nstatic const pj_str_t STR_ICE_UFRAG\t= { \"ice-ufrag\", 9 };\nstatic const pj_str_t STR_ICE_PWD\t= { \"ice-pwd\", 7 };\nstatic const pj_str_t STR_IP4\t\t= { \"IP4\", 3 };\nstatic const pj_str_t STR_IP6\t\t= { \"IP6\", 3 };\nstatic const pj_str_t STR_RTCP\t\t= { \"rtcp\", 4 };\nstatic const pj_str_t STR_BANDW_RR\t= { \"RR\", 2 };\nstatic const pj_str_t STR_BANDW_RS\t= { \"RS\", 2 };\n\nenum {\n    COMP_RTP = 1,\n    COMP_RTCP = 2\n};\n\n/*\n * Create ICE media transport.\n */\nPJ_DEF(pj_status_t) pjmedia_ice_create(pjmedia_endpt *endpt,\n\t\t\t\t       const char *name,\n\t\t\t\t       unsigned comp_cnt,\n\t\t\t\t       const pj_ice_strans_cfg *cfg,\n\t\t\t\t       const pjmedia_ice_cb *cb,\n\t    \t\t\t       pjmedia_transport **p_tp)\n{\n    return pjmedia_ice_create2(endpt, name, comp_cnt, cfg, cb, 0, p_tp);\n}\n\n/*\n * Create ICE media transport.\n */\nPJ_DEF(pj_status_t) pjmedia_ice_create2(pjmedia_endpt *endpt,\n\t\t\t\t        const char *name,\n\t\t\t\t        unsigned comp_cnt,\n\t\t\t\t        const pj_ice_strans_cfg *cfg,\n\t\t\t\t        const pjmedia_ice_cb *cb,\n\t\t\t\t\tunsigned options,\n\t    \t\t\t        pjmedia_transport **p_tp)\n{\n    return pjmedia_ice_create3(endpt, name, comp_cnt, cfg, cb,\n                               options, NULL, p_tp);\n}\n\n/*\n * Create ICE media transport.\n */\nPJ_DEF(pj_status_t) pjmedia_ice_create3(pjmedia_endpt *endpt,\n\t\t\t\t        const char *name,\n\t\t\t\t        unsigned comp_cnt,\n\t\t\t\t        const pj_ice_strans_cfg *cfg,\n\t\t\t\t        const pjmedia_ice_cb *cb,\n\t\t\t\t\tunsigned options,\n\t\t\t\t\tvoid *user_data,\n\t    \t\t\t        pjmedia_transport **p_tp)\n{\n    pj_pool_t *pool;\n    pj_ice_strans_cb ice_st_cb;\n    pj_ice_strans_cfg ice_st_cfg;\n    struct transport_ice *tp_ice;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(endpt && comp_cnt && cfg && p_tp, PJ_EINVAL);\n\n    /* Create transport instance */\n    pool = pjmedia_endpt_create_pool(endpt, name, 512, 512);\n    tp_ice = PJ_POOL_ZALLOC_T(pool, struct transport_ice);\n    tp_ice->pool = pool;\n    tp_ice->af = cfg->af;\n    tp_ice->options = options;\n    tp_ice->comp_cnt = comp_cnt;\n    pj_ansi_strcpy(tp_ice->base.name, pool->obj_name);\n    tp_ice->base.op = &transport_ice_op;\n    tp_ice->base.type = PJMEDIA_TRANSPORT_TYPE_ICE;\n    tp_ice->base.user_data = user_data;\n    tp_ice->initial_sdp = PJ_TRUE;\n    tp_ice->oa_role = ROLE_NONE;\n    tp_ice->use_ice = PJ_FALSE;\n\n    pj_memcpy(&ice_st_cfg, cfg, sizeof(pj_ice_strans_cfg));\n    if (cb)\n\tpj_memcpy(&tp_ice->cb, cb, sizeof(pjmedia_ice_cb));\n\n    /* Assign return value first because ICE might call callback\n     * in create()\n     */\n    *p_tp = &tp_ice->base;\n\n    /* Configure ICE callbacks */\n    pj_bzero(&ice_st_cb, sizeof(ice_st_cb));\n    ice_st_cb.on_ice_complete = &ice_on_ice_complete;\n    ice_st_cb.on_ice_state = &ice_on_ice_state;\n    ice_st_cb.on_rx_data = &ice_on_rx_data;\n\n    /* Configure RTP socket buffer settings, if not set */\n    if (ice_st_cfg.comp[COMP_RTP-1].so_rcvbuf_size == 0) {\n\tice_st_cfg.comp[COMP_RTP-1].so_rcvbuf_size = \n\t\t\t    PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE;\n    }\n    if (ice_st_cfg.comp[COMP_RTP-1].so_sndbuf_size == 0) {\n\tice_st_cfg.comp[COMP_RTP-1].so_sndbuf_size = \n\t\t\t    PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE;\n    }\n\n    /* Create ICE */\n    status = pj_ice_strans_create(name, &ice_st_cfg, comp_cnt, tp_ice, \n\t\t\t\t  &ice_st_cb, &tp_ice->ice_st);\n    if (status != PJ_SUCCESS) {\n\tpj_pool_release(pool);\n\t*p_tp = NULL;\n\treturn status;\n    }\n\n    /* Done */\n    return PJ_SUCCESS;\n}\n\n/*\n * Get the ICE stream transport associated with this media transport.\n */\nPJ_DEF(pj_ice_strans*) pjmedia_ice_get_strans(pjmedia_transport *tp)\n{\n    struct transport_ice *tp_ice;\n\n    tp_ice = (struct transport_ice*) tp;\n    return tp_ice->ice_st;\n}\n\nPJ_DEF(pj_grp_lock_t *) pjmedia_ice_get_grp_lock(pjmedia_transport *tp)\n{\n    PJ_ASSERT_RETURN(tp, NULL);\n    return pj_ice_strans_get_grp_lock(((struct transport_ice *)tp)->ice_st);\n}\n\n/* Disable ICE when SDP from remote doesn't contain a=candidate line */\nstatic void set_no_ice(struct transport_ice *tp_ice, const char *reason,\n\t\t       pj_status_t err)\n{\n    if (err != PJ_SUCCESS) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\tpj_strerror(err, errmsg, sizeof(errmsg));\n\tPJ_LOG(4,(tp_ice->base.name, \n\t\t  \"Stopping ICE, reason=%s:%s\", reason, errmsg));\n    } else {\n\tPJ_LOG(4,(tp_ice->base.name, \n\t\t  \"Stopping ICE, reason=%s\", reason));\n    }\n\n    /* Notify application about ICE stop */\n    if (tp_ice->cb.on_ice_stop)\n        (*tp_ice->cb.on_ice_stop)(&tp_ice->base, (char *)reason, err);\n\n    if (tp_ice->ice_st) {\n\tpj_ice_strans_stop_ice(tp_ice->ice_st);\n    }\n\n    tp_ice->use_ice = PJ_FALSE;\n}\n\n\n/* Create SDP candidate attribute */\nstatic int print_sdp_cand_attr(char *buffer, int max_len,\n\t\t\t       const pj_ice_sess_cand *cand)\n{\n    char ipaddr[PJ_INET6_ADDRSTRLEN+2];\n    int len, len2;\n\n    len = pj_ansi_snprintf( buffer, max_len,\n\t\t\t    \"%.*s %u UDP %u %s %u typ \",\n\t\t\t    (int)cand->foundation.slen,\n\t\t\t    cand->foundation.ptr,\n\t\t\t    (unsigned)cand->comp_id,\n\t\t\t    cand->prio,\n\t\t\t    pj_sockaddr_print(&cand->addr, ipaddr, \n\t\t\t\t\t      sizeof(ipaddr), 0),\n\t\t\t    (unsigned)pj_sockaddr_get_port(&cand->addr));\n    if (len < 1 || len >= max_len)\n\treturn -1;\n\n    switch (cand->type) {\n    case PJ_ICE_CAND_TYPE_HOST:\n\tlen2 = pj_ansi_snprintf(buffer+len, max_len-len, \"host\");\n\tbreak;\n    case PJ_ICE_CAND_TYPE_SRFLX:\n    case PJ_ICE_CAND_TYPE_RELAYED:\n    case PJ_ICE_CAND_TYPE_PRFLX:\n\tlen2 = pj_ansi_snprintf(buffer+len, max_len-len,\n\t\t\t        \"%s raddr %s rport %d\",\n\t\t\t\tpj_ice_get_cand_type_name(cand->type),\n\t\t\t\tpj_sockaddr_print(&cand->rel_addr, ipaddr,\n\t\t\t\t\t\t  sizeof(ipaddr), 0),\n\t\t\t\t(int)pj_sockaddr_get_port(&cand->rel_addr));\n\tbreak;\n    default:\n\tpj_assert(!\"Invalid candidate type\");\n\tlen2 = -1;\n\tbreak;\n    }\n    if (len2 < 1 || len2 >= max_len-len)\n\treturn -1;\n\n    return len+len2;\n}\n\n\n/* Get ice-ufrag and ice-pwd attribute */\nstatic void get_ice_attr(const pjmedia_sdp_session *rem_sdp,\n\t\t\t const pjmedia_sdp_media *rem_m,\n\t\t\t const pjmedia_sdp_attr **p_ice_ufrag,\n\t\t\t const pjmedia_sdp_attr **p_ice_pwd)\n{\n    pjmedia_sdp_attr *attr;\n\n    /* Find ice-ufrag attribute in media descriptor */\n    attr = pjmedia_sdp_attr_find(rem_m->attr_count, rem_m->attr,\n\t\t\t\t &STR_ICE_UFRAG, NULL);\n    if (attr == NULL) {\n\t/* Find ice-ufrag attribute in session descriptor */\n\tattr = pjmedia_sdp_attr_find(rem_sdp->attr_count, rem_sdp->attr,\n\t\t\t\t     &STR_ICE_UFRAG, NULL);\n    }\n    *p_ice_ufrag = attr;\n\n    /* Find ice-pwd attribute in media descriptor */\n    attr = pjmedia_sdp_attr_find(rem_m->attr_count, rem_m->attr,\n\t\t\t\t &STR_ICE_PWD, NULL);\n    if (attr == NULL) {\n\t/* Find ice-pwd attribute in session descriptor */\n\tattr = pjmedia_sdp_attr_find(rem_sdp->attr_count, rem_sdp->attr,\n\t\t\t\t     &STR_ICE_PWD, NULL);\n    }\n    *p_ice_pwd = attr;\n}\n\n\n/* Encode and add \"a=ice-mismatch\" attribute in the SDP */\nstatic void encode_ice_mismatch(pj_pool_t *sdp_pool,\n\t\t\t\tpjmedia_sdp_session *sdp_local,\n\t\t\t\tunsigned media_index)\n{\n    pjmedia_sdp_attr *attr;\n    pjmedia_sdp_media *m = sdp_local->media[media_index];\n\n    attr = PJ_POOL_ALLOC_T(sdp_pool, pjmedia_sdp_attr);\n    attr->name = STR_ICE_MISMATCH;\n    attr->value.slen = 0;\n    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);\n}\n\n\n/* Encode ICE information in SDP */\nstatic pj_status_t encode_session_in_sdp(struct transport_ice *tp_ice,\n\t\t\t\t\t pj_pool_t *sdp_pool,\n\t\t\t\t\t pjmedia_sdp_session *sdp_local,\n\t\t\t\t\t unsigned media_index,\n\t\t\t\t\t unsigned comp_cnt,\n\t\t\t\t\t pj_bool_t restart_session)\n{\n    enum { \n\tATTR_BUF_LEN = 160,\t/* Max len of a=candidate attr */\n\tRATTR_BUF_LEN= 160\t/* Max len of a=remote-candidates attr */\n    };\n    pjmedia_sdp_media *m = sdp_local->media[media_index];\n    pj_str_t local_ufrag, local_pwd;\n    pjmedia_sdp_attr *attr;\n    pj_status_t status;\n\n    /* Must have a session */\n    PJ_ASSERT_RETURN(pj_ice_strans_has_sess(tp_ice->ice_st), PJ_EBUG);\n\n    /* Get ufrag and pwd from current session */\n    pj_ice_strans_get_ufrag_pwd(tp_ice->ice_st, &local_ufrag, &local_pwd,\n\t\t\t\tNULL, NULL);\n\n    /* The listing of candidates depends on whether ICE has completed\n     * or not. When ICE has completed:\n     *\n     * 9.1.2.2: Existing Media Streams with ICE Completed\n     *   The agent MUST include a candidate attributes for candidates\n     *   matching the default destination for each component of the \n     *   media stream, and MUST NOT include any other candidates.\n     *\n     * When ICE has not completed, we shall include all candidates.\n     *\n     * Except when we have detected that remote is offering to restart\n     * the session, in this case we will answer with full ICE SDP and\n     * new ufrag/pwd pair.\n     */\n    if (!restart_session && pj_ice_strans_sess_is_complete(tp_ice->ice_st) &&\n\tpj_ice_strans_get_state(tp_ice->ice_st) != PJ_ICE_STRANS_STATE_FAILED)\n    {\n\tconst pj_ice_sess_check *check;\n\tchar *attr_buf;\n\tpjmedia_sdp_conn *conn;\n\tpjmedia_sdp_attr *a_rtcp;\n\tpj_str_t rem_cand;\n\tunsigned comp;\n\n\t/* Encode ice-ufrag attribute */\n\tattr = pjmedia_sdp_attr_create(sdp_pool, STR_ICE_UFRAG.ptr,\n\t\t\t\t       &local_ufrag);\n\tpjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);\n\n\t/* Encode ice-pwd attribute */\n\tattr = pjmedia_sdp_attr_create(sdp_pool, STR_ICE_PWD.ptr, \n\t\t\t\t       &local_pwd);\n\tpjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);\n\n\t/* Prepare buffer */\n\tattr_buf = (char*) pj_pool_alloc(sdp_pool, ATTR_BUF_LEN);\n\trem_cand.ptr = (char*) pj_pool_alloc(sdp_pool, RATTR_BUF_LEN);\n\trem_cand.slen = 0;\n\n\t/* 9.1.2.2: Existing Media Streams with ICE Completed\n\t *   The default destination for media (i.e., the values of \n\t *   the IP addresses and ports in the m and c line used for\n\t *   that media stream) MUST be the local candidate from the\n\t *   highest priority nominated pair in the valid list for each\n\t *   component.\n\t */\n\tcheck = pj_ice_strans_get_valid_pair(tp_ice->ice_st, 1);\n\tif (check == NULL) {\n\t    pj_assert(!\"Shouldn't happen\");\n\t    return PJ_EBUG;\n\t}\n\n\t/* Override connection line address and media port number */\n\tconn = m->conn;\n\tif (conn == NULL)\n\t    conn = sdp_local->conn;\n\n\tconn->addr.ptr = (char*) pj_pool_alloc(sdp_pool, \n\t\t\t\t\t       PJ_INET6_ADDRSTRLEN);\n\tpj_sockaddr_print(&check->lcand->addr, conn->addr.ptr, \n\t\t\t  PJ_INET6_ADDRSTRLEN, 0);\n\tconn->addr.slen = pj_ansi_strlen(conn->addr.ptr);\n\tm->desc.port = pj_sockaddr_get_port(&check->lcand->addr);\n\n\t/* Override address RTCP attribute if it's present */\n\tif (comp_cnt == 2 &&\n\t    (check = pj_ice_strans_get_valid_pair(tp_ice->ice_st, \n\t\t\t\t\t\t  COMP_RTCP)) != NULL &&\n\t    (a_rtcp = pjmedia_sdp_attr_find(m->attr_count, m->attr, \n\t\t\t\t\t    &STR_RTCP, 0)) != NULL) \n\t{\n\t    pjmedia_sdp_attr_remove(&m->attr_count, m->attr, a_rtcp);\n\n\t    a_rtcp = pjmedia_sdp_attr_create_rtcp(sdp_pool, \n\t\t\t\t\t\t  &check->lcand->addr);\n\t    if (a_rtcp)\n\t\tpjmedia_sdp_attr_add(&m->attr_count, m->attr, a_rtcp);\n\t}\n\n\t/* Encode only candidates matching the default destination \n\t * for each component \n\t */\n\tfor (comp=0; comp < comp_cnt; ++comp) {\n\t    int len;\n\t    pj_str_t value;\n\n\t    /* Get valid pair for this component */\n\t    check = pj_ice_strans_get_valid_pair(tp_ice->ice_st, comp+1);\n\t    if (check == NULL)\n\t\tcontinue;\n\n\t    /* Print and add local candidate in the pair */\n\t    value.ptr = attr_buf;\n\t    value.slen = print_sdp_cand_attr(attr_buf, ATTR_BUF_LEN, \n\t\t\t\t\t     check->lcand);\n\t    if (value.slen < 0) {\n\t\tpj_assert(!\"Not enough attr_buf to print candidate\");\n\t\treturn PJ_EBUG;\n\t    }\n\n\t    attr = pjmedia_sdp_attr_create(sdp_pool, STR_CANDIDATE.ptr,\n\t\t\t\t\t   &value);\n\t    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);\n\n\t    /* Append to a=remote-candidates attribute */\n\t    if (pj_ice_strans_get_role(tp_ice->ice_st) == \n\t\t\t\t    PJ_ICE_SESS_ROLE_CONTROLLING) \n\t    {\n\t\tchar rem_addr[PJ_INET6_ADDRSTRLEN];\n\n\t\tpj_sockaddr_print(&check->rcand->addr, rem_addr, \n\t\t\t\t  sizeof(rem_addr), 0);\n\t\tlen = pj_ansi_snprintf(\n\t\t\t   rem_cand.ptr + rem_cand.slen,\n\t\t\t   RATTR_BUF_LEN - rem_cand.slen,\n\t\t\t   \"%s%u %s %u\", \n\t\t\t   (rem_cand.slen==0? \"\" : \" \"),\n\t\t\t   comp+1, rem_addr,\n\t\t\t   pj_sockaddr_get_port(&check->rcand->addr)\n\t\t\t   );\n\t\tif (len < 1 || len >= RATTR_BUF_LEN - rem_cand.slen) {\n\t\t    pj_assert(!\"Not enough buffer to print \"\n\t\t\t       \"remote-candidates\");\n\t\t    return PJ_EBUG;\n\t\t}\n\n\t\trem_cand.slen += len;\n\t    }\n\t}\n\n\t/* 9.1.2.2: Existing Media Streams with ICE Completed\n\t *   In addition, if the agent is controlling, it MUST include\n\t *   the a=remote-candidates attribute for each media stream \n\t *   whose check list is in the Completed state.  The attribute\n\t *   contains the remote candidates from the highest priority \n\t *   nominated pair in the valid list for each component of that\n\t *   media stream.\n\t */\n\tif (pj_ice_strans_get_role(tp_ice->ice_st) == \n\t\t\t\t    PJ_ICE_SESS_ROLE_CONTROLLING) \n\t{\n\t    attr = pjmedia_sdp_attr_create(sdp_pool, STR_REM_CAND.ptr, \n\t\t\t\t\t   &rem_cand);\n\t    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);\n\t}\n\n    } else if (pj_ice_strans_has_sess(tp_ice->ice_st) &&\n\t       (restart_session || pj_ice_strans_get_state(tp_ice->ice_st) !=\n\t\tPJ_ICE_STRANS_STATE_FAILED))\n    {\n\t/* Encode all candidates to SDP media */\n\tchar *attr_buf;\n\tunsigned comp;\n\n\t/* If ICE is not restarted, encode current ICE ufrag/pwd.\n\t * Otherwise generate new one.\n\t */\n\tif (!restart_session) {\n\t    attr = pjmedia_sdp_attr_create(sdp_pool, STR_ICE_UFRAG.ptr,\n\t\t\t\t\t   &local_ufrag);\n\t    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);\n\n\t    attr = pjmedia_sdp_attr_create(sdp_pool, STR_ICE_PWD.ptr, \n\t\t\t\t\t   &local_pwd);\n\t    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);\n\n\t} else {\n\t    pj_str_t str;\n\n\t    str.slen = PJ_ICE_UFRAG_LEN;\n\t    str.ptr = (char*) pj_pool_alloc(sdp_pool, str.slen);\n\t    pj_create_random_string(str.ptr, str.slen);\n\t    attr = pjmedia_sdp_attr_create(sdp_pool, STR_ICE_UFRAG.ptr, &str);\n\t    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);\n\n\t    str.ptr = (char*) pj_pool_alloc(sdp_pool, str.slen);\n\t    pj_create_random_string(str.ptr, str.slen);\n\t    attr = pjmedia_sdp_attr_create(sdp_pool, STR_ICE_PWD.ptr, &str);\n\t    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);\n\t}\n\n\t/* Create buffer to encode candidates as SDP attribute */\n\tattr_buf = (char*) pj_pool_alloc(sdp_pool, ATTR_BUF_LEN);\n\n\tfor (comp=0; comp < comp_cnt; ++comp) {\n\t    unsigned cand_cnt;\n\t    pj_ice_sess_cand cand[PJ_ICE_ST_MAX_CAND];\n\t    unsigned i;\n\n\t    cand_cnt = PJ_ARRAY_SIZE(cand);\n\t    status = pj_ice_strans_enum_cands(tp_ice->ice_st, comp+1,\n\t\t\t\t\t      &cand_cnt, cand);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    for (i=0; i<cand_cnt; ++i) {\n\t\tpj_str_t value;\n\n\t\tvalue.slen = print_sdp_cand_attr(attr_buf, ATTR_BUF_LEN, \n\t\t\t\t\t\t &cand[i]);\n\t\tif (value.slen < 0) {\n\t\t    pj_assert(!\"Not enough attr_buf to print candidate\");\n\t\t    return PJ_EBUG;\n\t\t}\n\n\t\tvalue.ptr = attr_buf;\n\t\tattr = pjmedia_sdp_attr_create(sdp_pool, \n\t\t\t\t\t       STR_CANDIDATE.ptr,\n\t\t\t\t\t       &value);\n\t\tpjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);\n\t    }\n\t}\n    } else {\n\t/* ICE has failed, application should have terminated this call */\n    }\n\n    /* Removing a=rtcp line when there is only one component. */\n    if (comp_cnt == 1) {\n\tattr = pjmedia_sdp_attr_find(m->attr_count, m->attr, &STR_RTCP, NULL);\n\tif (attr)\n\t    pjmedia_sdp_attr_remove(&m->attr_count, m->attr, attr);\n        /* If RTCP is not in use, we MUST send b=RS:0 and b=RR:0. */\n        pj_assert(m->bandw_count + 2 <= PJ_ARRAY_SIZE(m->bandw));\n        if (m->bandw_count + 2 <= PJ_ARRAY_SIZE(m->bandw)) {\n            m->bandw[m->bandw_count] = PJ_POOL_ZALLOC_T(sdp_pool,\n                                                        pjmedia_sdp_bandw);\n            pj_memcpy(&m->bandw[m->bandw_count]->modifier, &STR_BANDW_RS,\n                      sizeof(pj_str_t));\n            m->bandw_count++;\n            m->bandw[m->bandw_count] = PJ_POOL_ZALLOC_T(sdp_pool,\n                                                        pjmedia_sdp_bandw);\n            pj_memcpy(&m->bandw[m->bandw_count]->modifier, &STR_BANDW_RR,\n                      sizeof(pj_str_t));\n            m->bandw_count++;\n        }\n    }\n    \n\n    return PJ_SUCCESS;\n}\n\n\n/* Parse a=candidate line */\nstatic pj_status_t parse_cand(const char *obj_name,\n\t\t\t      pj_pool_t *pool,\n\t\t\t      const pj_str_t *orig_input,\n\t\t\t      pj_ice_sess_cand *cand)\n{\n    pj_str_t input;\n    char *token, *host;\n    int af;\n    pj_str_t s;\n    pj_status_t status = PJNATH_EICEINCANDSDP;\n\n    pj_bzero(cand, sizeof(*cand));\n    pj_strdup_with_null(pool, &input, orig_input);\n\n    PJ_UNUSED_ARG(obj_name);\n\n    /* Foundation */\n    token = strtok(input.ptr, \" \");\n    if (!token) {\n\tTRACE__((obj_name, \"Expecting ICE foundation in candidate\"));\n\tgoto on_return;\n    }\n    pj_strdup2(pool, &cand->foundation, token);\n\n    /* Component ID */\n    token = strtok(NULL, \" \");\n    if (!token) {\n\tTRACE__((obj_name, \"Expecting ICE component ID in candidate\"));\n\tgoto on_return;\n    }\n    cand->comp_id = (pj_uint8_t) atoi(token);\n\n    /* Transport */\n    token = strtok(NULL, \" \");\n    if (!token) {\n\tTRACE__((obj_name, \"Expecting ICE transport in candidate\"));\n\tgoto on_return;\n    }\n    if (pj_ansi_stricmp(token, \"UDP\") != 0) {\n\tTRACE__((obj_name, \n\t\t \"Expecting ICE UDP transport only in candidate\"));\n\tgoto on_return;\n    }\n\n    /* Priority */\n    token = strtok(NULL, \" \");\n    if (!token) {\n\tTRACE__((obj_name, \"Expecting ICE priority in candidate\"));\n\tgoto on_return;\n    }\n    cand->prio = atoi(token);\n\n    /* Host */\n    host = strtok(NULL, \" \");\n    if (!host) {\n\tTRACE__((obj_name, \"Expecting ICE host in candidate\"));\n\tgoto on_return;\n    }\n    /* Detect address family */\n    if (pj_ansi_strchr(host, ':'))\n\taf = pj_AF_INET6();\n    else\n\taf = pj_AF_INET();\n    /* Assign address */\n    if (pj_sockaddr_init(af, &cand->addr, pj_cstr(&s, host), 0)) {\n\tTRACE__((obj_name, \"Invalid ICE candidate address\"));\n\tgoto on_return;\n    }\n\n    /* Port */\n    token = strtok(NULL, \" \");\n    if (!token) {\n\tTRACE__((obj_name, \"Expecting ICE port number in candidate\"));\n\tgoto on_return;\n    }\n    pj_sockaddr_set_port(&cand->addr, (pj_uint16_t)atoi(token));\n\n    /* typ */\n    token = strtok(NULL, \" \");\n    if (!token) {\n\tTRACE__((obj_name, \"Expecting ICE \\\"typ\\\" in candidate\"));\n\tgoto on_return;\n    }\n    if (pj_ansi_stricmp(token, \"typ\") != 0) {\n\tTRACE__((obj_name, \"Expecting ICE \\\"typ\\\" in candidate\"));\n\tgoto on_return;\n    }\n\n    /* candidate type */\n    token = strtok(NULL, \" \");\n    if (!token) {\n\tTRACE__((obj_name, \"Expecting ICE candidate type in candidate\"));\n\tgoto on_return;\n    }\n\n    if (pj_ansi_stricmp(token, \"host\") == 0) {\n\tcand->type = PJ_ICE_CAND_TYPE_HOST;\n\n    } else if (pj_ansi_stricmp(token, \"srflx\") == 0) {\n\tcand->type = PJ_ICE_CAND_TYPE_SRFLX;\n\n    } else if (pj_ansi_stricmp(token, \"relay\") == 0) {\n\tcand->type = PJ_ICE_CAND_TYPE_RELAYED;\n\n    } else if (pj_ansi_stricmp(token, \"prflx\") == 0) {\n\tcand->type = PJ_ICE_CAND_TYPE_PRFLX;\n\n    } else {\n\tPJ_LOG(5,(obj_name, \"Invalid ICE candidate type %s in candidate\", \n\t\t  token));\n\tgoto on_return;\n    }\n\n    status = PJ_SUCCESS;\n\non_return:\n    return status;\n}\n\n\n/* Create initial SDP offer */\nstatic pj_status_t create_initial_offer(struct transport_ice *tp_ice,\n\t\t\t\t\tpj_pool_t *sdp_pool,\n\t\t\t\t\tpjmedia_sdp_session *loc_sdp,\n\t\t\t\t\tunsigned media_index)\n{\n    pj_status_t status;\n\n    /* Encode ICE in SDP */\n    status = encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index, \n\t\t\t\t   tp_ice->comp_cnt, PJ_FALSE);\n    if (status != PJ_SUCCESS) {\n\tset_no_ice(tp_ice, \"Error encoding SDP answer\", status);\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* Verify incoming offer */\nstatic pj_status_t verify_ice_sdp(struct transport_ice *tp_ice,\n\t\t\t\t  pj_pool_t *tmp_pool,\n\t\t\t\t  const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t  unsigned media_index,\n\t\t\t\t  pj_ice_sess_role current_ice_role,\n\t\t\t\t  struct sdp_state *sdp_state)\n{\n    const pjmedia_sdp_media *rem_m;\n    const pjmedia_sdp_attr *ufrag_attr, *pwd_attr;\n    const pjmedia_sdp_conn *rem_conn;\n    pj_bool_t comp1_found=PJ_FALSE, comp2_found=PJ_FALSE, has_rtcp=PJ_FALSE;\n    pj_sockaddr rem_conn_addr, rtcp_addr;\n    unsigned i;\n    pj_status_t status;\n\n    rem_m = rem_sdp->media[media_index];\n\n    /* Get the \"ice-ufrag\" and \"ice-pwd\" attributes */\n    get_ice_attr(rem_sdp, rem_m, &ufrag_attr, &pwd_attr);\n\n    /* If \"ice-ufrag\" or \"ice-pwd\" are not found, disable ICE */\n    if (ufrag_attr==NULL || pwd_attr==NULL) {\n\tsdp_state->match_comp_cnt = 0;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Verify that default target for each component matches one of the \n     * candidate for the component. Otherwise stop ICE with ICE ice_mismatch \n     * error.\n     */\n\n    /* Component 1 is the c= line */\n    rem_conn = rem_m->conn;\n    if (rem_conn == NULL)\n\trem_conn = rem_sdp->conn;\n    if (!rem_conn)\n\treturn PJMEDIA_SDP_EMISSINGCONN;\n\n    /* Verify address family matches */\n    if ((tp_ice->af==pj_AF_INET() && \n\t pj_strcmp(&rem_conn->addr_type, &STR_IP4)!=0) ||\n\t(tp_ice->af==pj_AF_INET6() && \n\t pj_strcmp(&rem_conn->addr_type, &STR_IP6)!=0))\n    {\n\treturn PJMEDIA_SDP_ETPORTNOTEQUAL;\n    }\n\n    /* Assign remote connection address */\n    status = pj_sockaddr_init(tp_ice->af, &rem_conn_addr, &rem_conn->addr,\n\t\t\t      (pj_uint16_t)rem_m->desc.port);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (tp_ice->comp_cnt > 1) {\n\tconst pjmedia_sdp_attr *attr;\n\n\t/* Get default RTCP candidate from a=rtcp line, if present, otherwise\n\t * calculate default RTCP candidate from default RTP target.\n\t */\n\tattr = pjmedia_sdp_attr_find(rem_m->attr_count, rem_m->attr, \n\t\t\t\t     &STR_RTCP, NULL);\n\thas_rtcp = (attr != NULL);\n\n\tif (attr) {\n\t    pjmedia_sdp_rtcp_attr rtcp_attr;\n\n\t    status = pjmedia_sdp_attr_get_rtcp(attr, &rtcp_attr);\n\t    if (status != PJ_SUCCESS) {\n\t\t/* Error parsing a=rtcp attribute */\n\t\treturn status;\n\t    }\n    \t\n\t    if (rtcp_attr.addr.slen) {\n\t\t/* Verify address family matches */\n\t\tif ((tp_ice->af==pj_AF_INET() && \n\t\t     pj_strcmp(&rtcp_attr.addr_type, &STR_IP4)!=0) ||\n\t\t    (tp_ice->af==pj_AF_INET6() && \n\t\t     pj_strcmp(&rtcp_attr.addr_type, &STR_IP6)!=0))\n\t\t{\n\t\t    return PJMEDIA_SDP_ETPORTNOTEQUAL;\n\t\t}\n\n\t\t/* Assign RTCP address */\n\t\tstatus = pj_sockaddr_init(tp_ice->af, &rtcp_addr,\n\t\t\t\t\t  &rtcp_attr.addr,\n\t\t\t\t\t  (pj_uint16_t)rtcp_attr.port);\n\t\tif (status != PJ_SUCCESS) {\n\t\t    return PJMEDIA_SDP_EINRTCP;\n\t\t}\n\t    } else {\n\t\t/* Assign RTCP address */\n\t\tstatus = pj_sockaddr_init(tp_ice->af, &rtcp_addr, \n\t\t\t\t\t  NULL, \n\t\t\t\t\t  (pj_uint16_t)rtcp_attr.port);\n\t\tif (status != PJ_SUCCESS) {\n\t\t    return PJMEDIA_SDP_EINRTCP;\n\t\t}\n\t\tpj_sockaddr_copy_addr(&rtcp_addr, &rem_conn_addr);\n\t    }\n\t} else {\n\t    unsigned rtcp_port;\n    \t\n\t    rtcp_port = pj_sockaddr_get_port(&rem_conn_addr) + 1;\n\t    pj_sockaddr_cp(&rtcp_addr, &rem_conn_addr);\n\t    pj_sockaddr_set_port(&rtcp_addr, (pj_uint16_t)rtcp_port);\n\t}\n    }\n\n    /* Find the default addresses in a=candidate attributes. \n     */\n    for (i=0; i<rem_m->attr_count; ++i) {\n\tpj_ice_sess_cand cand;\n\n\tif (pj_strcmp(&rem_m->attr[i]->name, &STR_CANDIDATE)!=0)\n\t    continue;\n\n\tstatus = parse_cand(tp_ice->base.name, tmp_pool, \n\t\t\t    &rem_m->attr[i]->value, &cand);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_LOG(4,(tp_ice->base.name, \n\t\t      \"Error in parsing SDP candidate attribute '%.*s', \"\n\t\t      \"candidate is ignored\",\n\t\t      (int)rem_m->attr[i]->value.slen, \n\t\t      rem_m->attr[i]->value.ptr));\n\t    continue;\n\t}\n\n\tif (!comp1_found && cand.comp_id==COMP_RTP &&\n\t    pj_sockaddr_cmp(&rem_conn_addr, &cand.addr)==0) \n\t{\n\t    comp1_found = PJ_TRUE;\n\t} else if (!comp2_found && cand.comp_id==COMP_RTCP &&\n\t\t    pj_sockaddr_cmp(&rtcp_addr, &cand.addr)==0) \n\t{\n\t    comp2_found = PJ_TRUE;\n\t}\n\n\tif (cand.comp_id == COMP_RTCP)\n\t    has_rtcp = PJ_TRUE;\n\n\tif (comp1_found && (comp2_found || tp_ice->comp_cnt==1))\n\t    break;\n    }\n\n    /* Check matched component count and ice_mismatch */\n    if (comp1_found && (tp_ice->comp_cnt==1 || !has_rtcp)) {\n\tsdp_state->match_comp_cnt = 1;\n\tsdp_state->ice_mismatch = PJ_FALSE;\n    } else if (comp1_found && comp2_found) {\n\tsdp_state->match_comp_cnt = 2;\n\tsdp_state->ice_mismatch = PJ_FALSE;\n    } else {\n\tsdp_state->match_comp_cnt = (tp_ice->comp_cnt > 1 && has_rtcp)? 2 : 1;\n\tsdp_state->ice_mismatch = PJ_TRUE;\n    }\n\n\n    /* Detect remote restarting session */\n    if (pj_ice_strans_has_sess(tp_ice->ice_st) &&\n\t(pj_ice_strans_sess_is_running(tp_ice->ice_st) ||\n\t pj_ice_strans_sess_is_complete(tp_ice->ice_st))) \n    {\n\tpj_str_t rem_run_ufrag, rem_run_pwd;\n\tpj_ice_strans_get_ufrag_pwd(tp_ice->ice_st, NULL, NULL,\n\t\t\t\t    &rem_run_ufrag, &rem_run_pwd);\n\tif (pj_strcmp(&ufrag_attr->value, &rem_run_ufrag) ||\n\t    pj_strcmp(&pwd_attr->value, &rem_run_pwd))\n\t{\n\t    /* Remote offers to restart ICE */\n\t    sdp_state->ice_restart = PJ_TRUE;\n\t} else {\n\t    sdp_state->ice_restart = PJ_FALSE;\n\t}\n    } else {\n\tsdp_state->ice_restart = PJ_FALSE;\n    }\n\n    /* Detect our role */\n    if (current_ice_role==PJ_ICE_SESS_ROLE_CONTROLLING) {\n\tsdp_state->local_role = PJ_ICE_SESS_ROLE_CONTROLLING;\n    } else {\n\tif (pjmedia_sdp_attr_find(rem_sdp->attr_count, rem_sdp->attr,\n\t\t\t\t  &STR_ICE_LITE, NULL) != NULL)\n\t{\n\t    /* Remote is ICE Lite */\n\t    sdp_state->local_role = PJ_ICE_SESS_ROLE_CONTROLLING;\n\t} else {\n\t    sdp_state->local_role = PJ_ICE_SESS_ROLE_CONTROLLED;\n\t}\n    }\n\n    PJ_LOG(4,(tp_ice->base.name, \n\t      \"Processing SDP: support ICE=%u, common comp_cnt=%u, \"\n\t      \"ice_mismatch=%u, ice_restart=%u, local_role=%s\",\n\t      (sdp_state->match_comp_cnt != 0), \n\t      sdp_state->match_comp_cnt, \n\t      sdp_state->ice_mismatch, \n\t      sdp_state->ice_restart,\n\t      pj_ice_sess_role_name(sdp_state->local_role)));\n\n    return PJ_SUCCESS;\n\n}\n\n\n/* Verify incoming offer and create initial answer */\nstatic pj_status_t create_initial_answer(struct transport_ice *tp_ice,\n\t\t\t\t\t pj_pool_t *sdp_pool,\n\t\t\t\t\t pjmedia_sdp_session *loc_sdp,\n\t\t\t\t\t const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t\t unsigned media_index)\n{\n    const pjmedia_sdp_media *rem_m = rem_sdp->media[media_index];\n    pj_status_t status;\n\n    /* Check if media is removed (just in case) */\n    if (rem_m->desc.port == 0) {\n\treturn PJ_SUCCESS;\n    }\n\n    /* Verify the offer */\n    status = verify_ice_sdp(tp_ice, sdp_pool, rem_sdp, media_index, \n\t\t\t    PJ_ICE_SESS_ROLE_CONTROLLED, \n\t\t\t    &tp_ice->rem_offer_state);\n    if (status != PJ_SUCCESS) {\n\tset_no_ice(tp_ice, \"Invalid SDP offer\", status);\n\treturn status;\n    }\n\n    /* Does remote support ICE? */\n    if (tp_ice->rem_offer_state.match_comp_cnt==0) {\n\tset_no_ice(tp_ice, \"No ICE found in SDP offer\", PJ_SUCCESS);\n\treturn PJ_SUCCESS;\n    }\n\n    /* ICE ice_mismatch? */\n    if (tp_ice->rem_offer_state.ice_mismatch) {\n\tset_no_ice(tp_ice, \"ICE ice_mismatch in remote offer\", PJ_SUCCESS);\n\tencode_ice_mismatch(sdp_pool, loc_sdp, media_index);\n\treturn PJ_SUCCESS;\n    }\n\n    /* Encode ICE in SDP */\n    status = encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index, \n\t\t\t\t   tp_ice->rem_offer_state.match_comp_cnt,\n\t\t\t\t   PJ_FALSE);\n    if (status != PJ_SUCCESS) {\n\tset_no_ice(tp_ice, \"Error encoding SDP answer\", status);\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* Create subsequent SDP offer */\nstatic pj_status_t create_subsequent_offer(struct transport_ice *tp_ice,\n\t\t\t\t\t   pj_pool_t *sdp_pool,\n\t\t\t\t\t   pjmedia_sdp_session *loc_sdp,\n\t\t\t\t\t   unsigned media_index)\n{\n    unsigned comp_cnt;\n\n    if (pj_ice_strans_has_sess(tp_ice->ice_st) == PJ_FALSE) {\n\t/* We don't have ICE */\n\treturn PJ_SUCCESS;\n    }\n\n    comp_cnt = pj_ice_strans_get_running_comp_cnt(tp_ice->ice_st);\n    return encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index,\n\t\t\t\t comp_cnt, PJ_FALSE);\n}\n\n\n/* Create subsequent SDP answer */\nstatic pj_status_t create_subsequent_answer(struct transport_ice *tp_ice,\n\t\t\t\t\t    pj_pool_t *sdp_pool,\n\t\t\t\t\t    pjmedia_sdp_session *loc_sdp,\n\t\t\t\t\t    const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t\t    unsigned media_index)\n{\n    pj_status_t status;\n\n    /* We have a session */\n    status = verify_ice_sdp(tp_ice, sdp_pool, rem_sdp, media_index, \n\t\t\t    PJ_ICE_SESS_ROLE_CONTROLLED, \n\t\t\t    &tp_ice->rem_offer_state);\n    if (status != PJ_SUCCESS) {\n\t/* Something wrong with the offer */\n\treturn status;\n    }\n\n    if (pj_ice_strans_has_sess(tp_ice->ice_st)) {\n\t/*\n\t * Received subsequent offer while we have ICE active.\n\t */\n\n\tif (tp_ice->rem_offer_state.match_comp_cnt == 0) {\n\t    /* Remote no longer offers ICE */\n\t    return PJ_SUCCESS;\n\t}\n\n\tif (tp_ice->rem_offer_state.ice_mismatch) {\n\t    encode_ice_mismatch(sdp_pool, loc_sdp, media_index);\n\t    return PJ_SUCCESS;\n\t}\n\n\tstatus = encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index,\n\t\t\t\t       tp_ice->rem_offer_state.match_comp_cnt,\n\t\t\t\t       tp_ice->rem_offer_state.ice_restart);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Done */\n\n    } else {\n\t/*\n\t * Received subsequent offer while we DON'T have ICE active.\n\t */\n\n\tif (tp_ice->rem_offer_state.match_comp_cnt == 0) {\n\t    /* Remote does not support ICE */\n\t    return PJ_SUCCESS;\n\t}\n\n\tif (tp_ice->rem_offer_state.ice_mismatch) {\n\t    encode_ice_mismatch(sdp_pool, loc_sdp, media_index);\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* Looks like now remote is offering ICE, so we need to create\n\t * ICE session now.\n\t */\n\tstatus = pj_ice_strans_init_ice(tp_ice->ice_st, \n\t\t\t\t\tPJ_ICE_SESS_ROLE_CONTROLLED,\n\t\t\t\t\tNULL, NULL);\n\tif (status != PJ_SUCCESS) {\n\t    /* Fail to create new ICE session */\n\t    return status;\n\t}\n\n\tstatus = encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index,\n\t\t\t\t       tp_ice->rem_offer_state.match_comp_cnt,\n\t\t\t\t       tp_ice->rem_offer_state.ice_restart);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Done */\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * For both UAC and UAS, pass in the SDP before sending it to remote.\n * This will add ICE attributes to the SDP.\n */\nstatic pj_status_t transport_media_create(pjmedia_transport *tp,\n\t\t\t\t          pj_pool_t *sdp_pool,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t\t  const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t\t  unsigned media_index)\n{\n    struct transport_ice *tp_ice = (struct transport_ice*)tp;\n    pj_ice_sess_role ice_role;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(media_index);\n    PJ_UNUSED_ARG(sdp_pool);\n\n    tp_ice->media_option = options;\n    tp_ice->oa_role = ROLE_NONE;\n    tp_ice->initial_sdp = PJ_TRUE;\n\n    /* Init ICE, the initial role is set now based on availability of\n     * rem_sdp, but it will be checked again later.\n     */\n    ice_role = (rem_sdp==NULL ? PJ_ICE_SESS_ROLE_CONTROLLING : \n\t\t\t\tPJ_ICE_SESS_ROLE_CONTROLLED);\n    status = pj_ice_strans_init_ice(tp_ice->ice_st, ice_role, NULL, NULL);\n\n    /* Done */\n    return status;\n}\n\n\nstatic pj_status_t transport_encode_sdp(pjmedia_transport *tp,\n\t\t\t\t        pj_pool_t *sdp_pool,\n\t\t\t\t        pjmedia_sdp_session *sdp_local,\n\t\t\t\t        const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t        unsigned media_index)\n{\n    struct transport_ice *tp_ice = (struct transport_ice*)tp;\n    pj_status_t status;\n\n    /* Validate media transport */\n    /* This transport only support RTP/AVP transport, unless if\n     * transport checking is disabled\n     */\n    if ((tp_ice->media_option & PJMEDIA_TPMED_NO_TRANSPORT_CHECKING) == 0) {\n\tpjmedia_sdp_media *loc_m, *rem_m;\n\n\trem_m = rem_sdp? rem_sdp->media[media_index] : NULL;\n\tloc_m = sdp_local->media[media_index];\n\n\tif (pj_stricmp(&loc_m->desc.transport, &STR_RTP_AVP) ||\n\t   (rem_m && pj_stricmp(&rem_m->desc.transport, &STR_RTP_AVP)))\n\t{\n\t    pjmedia_sdp_media_deactivate(sdp_pool, loc_m);\n\t    return PJMEDIA_SDP_EINPROTO;\n\t}\n    }\n\n    if (tp_ice->initial_sdp) {\n\tif (rem_sdp) {\n\t    status = create_initial_answer(tp_ice, sdp_pool, sdp_local, \n\t\t\t\t\t   rem_sdp, media_index);\n\t} else {\n\t    status = create_initial_offer(tp_ice, sdp_pool, sdp_local,\n\t\t\t\t\t  media_index);\n\t}\n    } else {\n\tif (rem_sdp) {\n\t    status = create_subsequent_answer(tp_ice, sdp_pool, sdp_local,\n\t\t\t\t\t      rem_sdp, media_index);\n\t} else {\n\t    status = create_subsequent_offer(tp_ice, sdp_pool, sdp_local,\n\t\t\t\t\t     media_index);\n\t}\n    }\n\n    if (status==PJ_SUCCESS) {\n\tif (rem_sdp)\n\t    tp_ice->oa_role = ROLE_ANSWERER;\n\telse\n\t    tp_ice->oa_role = ROLE_OFFERER;\n    }\n\n    return status;\n}\n\n\n/* Start ICE session with the specified remote SDP */\nstatic pj_status_t start_ice(struct transport_ice *tp_ice,\n\t\t\t     pj_pool_t *tmp_pool,\n\t\t\t     const pjmedia_sdp_session *rem_sdp,\n\t\t\t     unsigned media_index)\n{\n    pjmedia_sdp_media *rem_m = rem_sdp->media[media_index];\n    const pjmedia_sdp_attr *ufrag_attr, *pwd_attr;\n    pj_ice_sess_cand *cand;\n    unsigned i, cand_cnt;\n    pj_status_t status;\n\n    get_ice_attr(rem_sdp, rem_m, &ufrag_attr, &pwd_attr);\n\n    /* Allocate candidate array */\n    cand = (pj_ice_sess_cand*)\n\t   pj_pool_calloc(tmp_pool, PJ_ICE_MAX_CAND, \n\t\t\t  sizeof(pj_ice_sess_cand));\n\n    /* Get all candidates in the media */\n    cand_cnt = 0;\n    for (i=0; i<rem_m->attr_count && cand_cnt < PJ_ICE_MAX_CAND; ++i) {\n\tpjmedia_sdp_attr *attr;\n\n\tattr = rem_m->attr[i];\n\n\tif (pj_strcmp(&attr->name, &STR_CANDIDATE)!=0)\n\t    continue;\n\n\t/* Parse candidate */\n\tstatus = parse_cand(tp_ice->base.name, tmp_pool, &attr->value, \n\t\t\t    &cand[cand_cnt]);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_LOG(4,(tp_ice->base.name, \n\t\t      \"Error in parsing SDP candidate attribute '%.*s', \"\n\t\t      \"candidate is ignored\",\n\t\t      (int)attr->value.slen, attr->value.ptr));\n\t    continue;\n\t}\n\n\tcand_cnt++;\n    }\n\n    /* Start ICE */\n    return pj_ice_strans_start_ice(tp_ice->ice_st, &ufrag_attr->value, \n\t\t\t\t   &pwd_attr->value, cand_cnt, cand);\n}\n\n\n/*\n * Start ICE checks when both offer and answer have been negotiated\n * by SDP negotiator.\n */\nstatic pj_status_t transport_media_start(pjmedia_transport *tp,\n\t\t\t\t         pj_pool_t *tmp_pool,\n\t\t\t\t         const pjmedia_sdp_session *sdp_local,\n\t\t\t\t         const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t         unsigned media_index)\n{\n    struct transport_ice *tp_ice = (struct transport_ice*)tp;\n    pjmedia_sdp_media *rem_m;\n    enum oa_role current_oa_role;\n    pj_bool_t initial_oa;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(tp && tmp_pool && rem_sdp, PJ_EINVAL);\n    PJ_ASSERT_RETURN(media_index < rem_sdp->media_count, PJ_EINVAL);\n\n    rem_m = rem_sdp->media[media_index];\n\n    initial_oa = tp_ice->initial_sdp;\n    current_oa_role = tp_ice->oa_role;\n\n    /* SDP has been negotiated */\n    tp_ice->initial_sdp = PJ_FALSE;\n    tp_ice->oa_role = ROLE_NONE;\n\n    /* Nothing to do if we don't have ICE session */\n    if (pj_ice_strans_has_sess(tp_ice->ice_st) == PJ_FALSE) {\n\treturn PJ_SUCCESS;\n    }\n\n    /* Special case for Session Timer. The re-INVITE for session refresh\n     * doesn't call transport_encode_sdp(), causing current_oa_role to\n     * be set to ROLE_NONE. This is a workaround.\n     */\n    if (current_oa_role == ROLE_NONE) {\n\tcurrent_oa_role = ROLE_OFFERER;\n    }\n\n    /* Processing depends on the offer/answer role */\n    if (current_oa_role == ROLE_OFFERER) {\n\t/*\n\t * We are offerer. So this will be the first time we see the\n\t * remote's SDP.\n\t */\n\tstruct sdp_state answer_state;\n\n\t/* Verify the answer */\n\tstatus = verify_ice_sdp(tp_ice, tmp_pool, rem_sdp, media_index, \n\t\t\t\tPJ_ICE_SESS_ROLE_CONTROLLING, &answer_state);\n\tif (status != PJ_SUCCESS) {\n\t    /* Something wrong in the SDP answer */\n\t    set_no_ice(tp_ice, \"Invalid remote SDP answer\", status);\n\t    return status;\n\t}\n\n\t/* Does it have ICE? */\n\tif (answer_state.match_comp_cnt == 0) {\n\t    /* Remote doesn't support ICE */\n\t    set_no_ice(tp_ice, \"Remote answer doesn't support ICE\", \n\t\t       PJ_SUCCESS);\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* Check if remote has reported ice-mismatch */\n\tif (pjmedia_sdp_attr_find(rem_m->attr_count, rem_m->attr, \n\t\t\t\t  &STR_ICE_MISMATCH, NULL) != NULL)\n\t{\n\t    /* Remote has reported ice-mismatch */\n\t    set_no_ice(tp_ice, \n\t\t       \"Remote answer contains 'ice-mismatch' attribute\", \n\t\t       PJ_SUCCESS);\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* Check if remote has indicated a restart */\n\tif (answer_state.ice_restart) {\n\t    PJ_LOG(2,(tp_ice->base.name, \n\t\t      \"Warning: remote has signalled ICE restart in SDP \"\n\t\t      \"answer which is disallowed. Remote ICE negotiation\"\n\t\t      \" may fail.\"));\n\t}\n\n\t/* Check if the answer itself is mismatched */\n\tif (answer_state.ice_mismatch) {\n\t    /* This happens either when a B2BUA modified remote answer but\n\t     * strangely didn't modify our offer, or remote is not capable\n\t     * of detecting mismatch in our offer (it didn't put \n\t     * 'ice-mismatch' attribute in the answer).\n\t     */\n\t    PJ_LOG(2,(tp_ice->base.name, \n\t\t      \"Warning: remote answer mismatch, but it does not \"\n\t\t      \"reject our offer with 'ice-mismatch'. ICE negotiation \"\n\t\t      \"may fail\"));\n\t}\n\n\t/* Do nothing if ICE is complete or running */\n\tif (pj_ice_strans_sess_is_running(tp_ice->ice_st)) {\n\t    PJ_LOG(4,(tp_ice->base.name,\n\t\t      \"Ignored offer/answer because ICE is running\"));\n\t    return PJ_SUCCESS;\n\t}\n\n\tif (pj_ice_strans_sess_is_complete(tp_ice->ice_st)) {\n\t    PJ_LOG(4,(tp_ice->base.name, \"ICE session unchanged\"));\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* Start ICE */\n\n    } else {\n\t/*\n\t * We are answerer. We've seen and negotiated remote's SDP\n\t * before, and the result is in \"rem_offer_state\".\n\t */\n\tconst pjmedia_sdp_attr *ufrag_attr, *pwd_attr;\n\n\t/* Check for ICE in remote offer */\n\tif (tp_ice->rem_offer_state.match_comp_cnt == 0) {\n\t    /* No ICE attribute present */\n\t    set_no_ice(tp_ice, \"Remote no longer offers ICE\",\n\t\t       PJ_SUCCESS);\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* Check for ICE ice_mismatch condition in the offer */\n\tif (tp_ice->rem_offer_state.ice_mismatch) {\n\t    set_no_ice(tp_ice, \"Remote offer mismatch: \", \n\t\t       PJNATH_EICEMISMATCH);\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* If ICE is complete and remote doesn't request restart,\n\t * then leave the session as is.\n\t */\n\tif (!initial_oa && tp_ice->rem_offer_state.ice_restart == PJ_FALSE) {\n\t    /* Remote has not requested ICE restart, so session is\n\t     * unchanged.\n\t     */\n\t    PJ_LOG(4,(tp_ice->base.name, \"ICE session unchanged\"));\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* Either remote has requested ICE restart or this is our\n\t * first answer. \n\t */\n\n\t/* Stop ICE */\n\tif (!initial_oa) {\n\t    set_no_ice(tp_ice, \"restarting by remote request..\", PJ_SUCCESS);\n\n\t    /* We have put new ICE ufrag and pwd in the answer. Now\n\t     * create a new ICE session with that ufrag/pwd pair.\n\t     */\n\t    get_ice_attr(sdp_local, sdp_local->media[media_index], \n\t\t\t &ufrag_attr, &pwd_attr);\n\t    status = pj_ice_strans_init_ice(tp_ice->ice_st, \n\t\t\t\t\t    tp_ice->rem_offer_state.local_role,\n\t\t\t\t\t    &ufrag_attr->value, \n\t\t\t\t\t    &pwd_attr->value);\n\t    if (status != PJ_SUCCESS) {\n\t\tPJ_LOG(1,(tp_ice->base.name, \n\t\t\t  \"ICE re-initialization failed (status=%d)!\",\n\t\t\t  status));\n\t\treturn status;\n\t    }\n\t}\n\n\t/* Ticket #977: Update role if turns out we're supposed to be the \n\t * Controlling agent (e.g. when talking to ice-lite peer). \n\t */\n\tif (tp_ice->rem_offer_state.local_role==PJ_ICE_SESS_ROLE_CONTROLLING &&\n\t    pj_ice_strans_has_sess(tp_ice->ice_st)) \n\t{\n\t    pj_ice_strans_change_role(tp_ice->ice_st, \n\t\t\t\t      PJ_ICE_SESS_ROLE_CONTROLLING);\n\t}\n\n\n\t/* start ICE */\n    }\n\n    /* Now start ICE */\n    status = start_ice(tp_ice, tmp_pool, rem_sdp, media_index);\n    if (status != PJ_SUCCESS) {\n\tPJ_LOG(1,(tp_ice->base.name, \n\t\t  \"ICE restart failed (status=%d)!\",\n\t\t  status));\n\treturn status;\n    }\n\n    /* Done */\n    tp_ice->use_ice = PJ_TRUE;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t transport_media_stop(pjmedia_transport *tp)\n{\n    struct transport_ice *tp_ice = (struct transport_ice*)tp;\n    \n    set_no_ice(tp_ice, \"media stop requested\", PJ_SUCCESS);\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t transport_get_info(pjmedia_transport *tp,\n\t\t\t\t      pjmedia_transport_info *info)\n{\n    struct transport_ice *tp_ice = (struct transport_ice*)tp;\n    pj_ice_sess_cand cand;\n    pj_status_t status;\n\n    pj_bzero(&info->sock_info, sizeof(info->sock_info));\n    info->sock_info.rtp_sock = info->sock_info.rtcp_sock = PJ_INVALID_SOCKET;\n\n    /* Get RTP default address */\n    status = pj_ice_strans_get_def_cand(tp_ice->ice_st, 1, &cand);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_sockaddr_cp(&info->sock_info.rtp_addr_name, &cand.base_addr);\n\n    /* Get RTCP default address */\n    if (tp_ice->comp_cnt > 1) {\n\tstatus = pj_ice_strans_get_def_cand(tp_ice->ice_st, 2, &cand);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tpj_sockaddr_cp(&info->sock_info.rtcp_addr_name, &cand.base_addr);\n    }\n\n    /* Set remote address originating RTP & RTCP if this transport has \n     * ICE activated or received any packets.\n     */\n    if (tp_ice->use_ice || tp_ice->rtp_src_cnt) {\n\tinfo->src_rtp_name  = tp_ice->rtp_src_addr;\n    }\n    if (tp_ice->use_ice || tp_ice->rtcp_src_cnt) {\n\tinfo->src_rtcp_name = tp_ice->rtcp_src_addr;\n    }\n\n    /* Fill up transport specific info */\n    if (info->specific_info_cnt < PJ_ARRAY_SIZE(info->spc_info)) {\n\tpjmedia_transport_specific_info *tsi;\n\tpjmedia_ice_transport_info *ii;\n\tunsigned i;\n\n\tpj_assert(sizeof(*ii) <= sizeof(tsi->buffer));\n\ttsi = &info->spc_info[info->specific_info_cnt++];\n\ttsi->type = PJMEDIA_TRANSPORT_TYPE_ICE;\n\ttsi->cbsize = sizeof(*ii);\n\n\tii = (pjmedia_ice_transport_info*) tsi->buffer;\n\tpj_bzero(ii, sizeof(*ii));\n\n\tii->active = tp_ice->use_ice;\n\n\tif (pj_ice_strans_has_sess(tp_ice->ice_st))\n\t    ii->role = pj_ice_strans_get_role(tp_ice->ice_st);\n\telse\n\t    ii->role = PJ_ICE_SESS_ROLE_UNKNOWN;\n\tii->sess_state = pj_ice_strans_get_state(tp_ice->ice_st);\n\tii->comp_cnt = pj_ice_strans_get_running_comp_cnt(tp_ice->ice_st);\n\t\n\tfor (i=1; i<=ii->comp_cnt && i<=PJ_ARRAY_SIZE(ii->comp); ++i) {\n\t    const pj_ice_sess_check *chk;\n\n\t    chk = pj_ice_strans_get_valid_pair(tp_ice->ice_st, i);\n\t    if (chk) {\n\t\tii->comp[i-1].lcand_type = chk->lcand->type;\n\t\tpj_sockaddr_cp(&ii->comp[i-1].lcand_addr,\n\t\t               &chk->lcand->addr);\n\t\tii->comp[i-1].rcand_type = chk->rcand->type;\n\t\tpj_sockaddr_cp(&ii->comp[i-1].rcand_addr,\n\t\t               &chk->rcand->addr);\n\t    }\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t transport_attach  (pjmedia_transport *tp,\n\t\t\t\t      void *stream,\n\t\t\t\t      const pj_sockaddr_t *rem_addr,\n\t\t\t\t      const pj_sockaddr_t *rem_rtcp,\n\t\t\t\t      unsigned addr_len,\n\t\t\t\t      void (*rtp_cb)(void*,\n\t\t\t\t\t\t     void*,\n\t\t\t\t\t\t     pj_ssize_t),\n\t\t\t\t      void (*rtcp_cb)(void*,\n\t\t\t\t\t\t      void*,\n\t\t\t\t\t\t      pj_ssize_t))\n{\n    struct transport_ice *tp_ice = (struct transport_ice*)tp;\n\n    tp_ice->stream = stream;\n    tp_ice->rtp_cb = rtp_cb;\n    tp_ice->rtcp_cb = rtcp_cb;\n\n    pj_memcpy(&tp_ice->remote_rtp, rem_addr, addr_len);\n    pj_memcpy(&tp_ice->remote_rtcp, rem_rtcp, addr_len);\n    tp_ice->addr_len = addr_len;\n\n    /* Init source RTP & RTCP addresses and counter */\n    tp_ice->rtp_src_addr = tp_ice->remote_rtp;\n    tp_ice->rtcp_src_addr = tp_ice->remote_rtcp;\n    tp_ice->rtp_src_cnt = 0;\n    tp_ice->rtcp_src_cnt = 0;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void transport_detach(pjmedia_transport *tp,\n\t\t\t     void *strm)\n{\n    struct transport_ice *tp_ice = (struct transport_ice*)tp;\n\n    /* TODO: need to solve ticket #460 here */\n\n    tp_ice->rtp_cb = NULL;\n    tp_ice->rtcp_cb = NULL;\n    tp_ice->stream = NULL;\n\n    PJ_UNUSED_ARG(strm);\n}\n\n\nstatic pj_status_t transport_send_rtp(pjmedia_transport *tp,\n\t\t\t\t      const void *pkt,\n\t\t\t\t      pj_size_t size)\n{\n    struct transport_ice *tp_ice = (struct transport_ice*)tp;\n\n    /* Simulate packet lost on TX direction */\n    if (tp_ice->tx_drop_pct) {\n\tif ((pj_rand() % 100) <= (int)tp_ice->tx_drop_pct) {\n\t    PJ_LOG(5,(tp_ice->base.name, \n\t\t      \"TX RTP packet dropped because of pkt lost \"\n\t\t      \"simulation\"));\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    return pj_ice_strans_sendto(tp_ice->ice_st, 1, \n\t\t\t        pkt, size, &tp_ice->remote_rtp,\n\t\t\t\ttp_ice->addr_len);\n}\n\n\nstatic pj_status_t transport_send_rtcp(pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size)\n{\n    return transport_send_rtcp2(tp, NULL, 0, pkt, size);\n}\n\nstatic pj_status_t transport_send_rtcp2(pjmedia_transport *tp,\n\t\t\t\t        const pj_sockaddr_t *addr,\n\t\t\t\t        unsigned addr_len,\n\t\t\t\t        const void *pkt,\n\t\t\t\t        pj_size_t size)\n{\n    struct transport_ice *tp_ice = (struct transport_ice*)tp;\n    if (tp_ice->comp_cnt > 1) {\n\tif (addr == NULL) {\n\t    addr = &tp_ice->remote_rtcp;\n\t    addr_len = pj_sockaddr_get_len(addr);\n\t}\n\treturn pj_ice_strans_sendto(tp_ice->ice_st, 2, pkt, size, \n\t\t\t\t    addr, addr_len);\n    } else {\n\treturn PJ_SUCCESS;\n    }\n}\n\n\nstatic void ice_on_rx_data(pj_ice_strans *ice_st, unsigned comp_id, \n\t\t\t   void *pkt, pj_size_t size,\n\t\t\t   const pj_sockaddr_t *src_addr,\n\t\t\t   unsigned src_addr_len)\n{\n    struct transport_ice *tp_ice;\n    pj_bool_t discard = PJ_FALSE;\n\n    tp_ice = (struct transport_ice*) pj_ice_strans_get_user_data(ice_st);\n\n    if (comp_id==1 && tp_ice->rtp_cb) {\n\n\t/* Simulate packet lost on RX direction */\n\tif (tp_ice->rx_drop_pct) {\n\t    if ((pj_rand() % 100) <= (int)tp_ice->rx_drop_pct) {\n\t\tPJ_LOG(5,(tp_ice->base.name, \n\t\t\t  \"RX RTP packet dropped because of pkt lost \"\n\t\t\t  \"simulation\"));\n\t\treturn;\n\t    }\n\t}\n\n\t/* See if source address of RTP packet is different than the \n\t * configured address, and switch RTP remote address to \n\t * source packet address after several consecutive packets\n\t * have been received.\n\t */\n\tif (!tp_ice->use_ice) {\n\t    pj_bool_t enable_switch =\n\t\t    ((tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0);\n\n\t    if (!enable_switch ||\n\t\tpj_sockaddr_cmp(&tp_ice->remote_rtp, src_addr) == 0)\n\t    {\n\t\t/* Don't switch while we're receiving from remote_rtp */\n\t\ttp_ice->rtp_src_cnt = 0;\n\t    } else {\n\n\t\t++tp_ice->rtp_src_cnt;\n\n\t\t/* Check if the source address is recognized. */\n\t\tif (pj_sockaddr_cmp(src_addr, &tp_ice->rtp_src_addr) != 0) {\n\t\t    /* Remember the new source address. */\n\t\t    pj_sockaddr_cp(&tp_ice->rtp_src_addr, src_addr);\n\t\t    /* Reset counter */\n\t\t    tp_ice->rtp_src_cnt = 0;\n\t\t    discard = PJ_TRUE;\n\t\t}\n\n\t\tif (tp_ice->rtp_src_cnt < PJMEDIA_RTP_NAT_PROBATION_CNT) {\n\t\t    discard = PJ_TRUE;\n\t\t} else {\n\t\t    char addr_text[80];\n\n\t\t    /* Set remote RTP address to source address */\n\t\t    pj_sockaddr_cp(&tp_ice->remote_rtp, &tp_ice->rtp_src_addr);\n\t\t    tp_ice->addr_len = pj_sockaddr_get_len(&tp_ice->remote_rtp);\n\n\t\t    /* Reset counter */\n\t\t    tp_ice->rtp_src_cnt = 0;\n\n\t\t    PJ_LOG(4,(tp_ice->base.name,\n\t\t\t      \"Remote RTP address switched to %s\",\n\t\t\t      pj_sockaddr_print(&tp_ice->remote_rtp, addr_text,\n\t\t\t\t\t\tsizeof(addr_text), 3)));\n\n\t\t    /* Also update remote RTCP address if actual RTCP source\n\t\t     * address is not heard yet.\n\t\t     */\n\t\t    if (!pj_sockaddr_has_addr(&tp_ice->rtcp_src_addr)) {\n\t\t\tpj_uint16_t port;\n\n\t\t\tpj_sockaddr_cp(&tp_ice->remote_rtcp, \n\t\t\t\t       &tp_ice->remote_rtp);\n\n\t\t\tport = (pj_uint16_t)\n\t\t\t       (pj_sockaddr_get_port(&tp_ice->remote_rtp)+1);\n\t\t\tpj_sockaddr_set_port(&tp_ice->remote_rtcp, port);\n\n\t\t\tPJ_LOG(4,(tp_ice->base.name,\n\t\t\t\t  \"Remote RTCP address switched to predicted \"\n\t\t\t\t  \"address %s\",\n\t\t\t\t  pj_sockaddr_print(&tp_ice->remote_rtcp, \n\t\t\t\t\t\t    addr_text,\n\t\t\t\t\t\t    sizeof(addr_text), 3)));\n\t\t    }\n\t\t}\n\t    }\n\t}\n\n\tif (!discard)\n\t    (*tp_ice->rtp_cb)(tp_ice->stream, pkt, size);\n\n    } else if (comp_id==2 && tp_ice->rtcp_cb) {\n\n\t/* Check if RTCP source address is the same as the configured\n\t * remote address, and switch the address when they are\n\t * different.\n\t */\n\tif (!tp_ice->use_ice &&\n\t    (tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0)\n\t{\n\t    if (pj_sockaddr_cmp(&tp_ice->remote_rtcp, src_addr) == 0) {\n\t\ttp_ice->rtcp_src_cnt = 0;\n\t    } else {\n\t\tchar addr_text[80];\n\n\t\t++tp_ice->rtcp_src_cnt;\n\t\tif (tp_ice->rtcp_src_cnt < PJMEDIA_RTCP_NAT_PROBATION_CNT) {\n\t\t    discard = PJ_TRUE;\n\t\t} else {\n\t\t    tp_ice->rtcp_src_cnt = 0;\n\t\t    pj_sockaddr_cp(&tp_ice->rtcp_src_addr, src_addr);\n\t\t    pj_sockaddr_cp(&tp_ice->remote_rtcp, src_addr);\n\n\t\t    pj_assert(tp_ice->addr_len==pj_sockaddr_get_len(src_addr));\n\n\t\t    PJ_LOG(4,(tp_ice->base.name,\n\t\t\t      \"Remote RTCP address switched to %s\",\n\t\t\t      pj_sockaddr_print(&tp_ice->remote_rtcp,\n\t\t\t                        addr_text, sizeof(addr_text),\n\t\t\t                        3)));\n\t\t}\n\t    }\n\t}\n\n\tif (!discard)\n\t    (*tp_ice->rtcp_cb)(tp_ice->stream, pkt, size);\n    }\n\n    PJ_UNUSED_ARG(src_addr_len);\n}\n\n\nstatic void ice_on_ice_complete(pj_ice_strans *ice_st, \n\t\t\t\tpj_ice_strans_op op,\n\t\t\t        pj_status_t result)\n{\n    struct transport_ice *tp_ice;\n\n    tp_ice = (struct transport_ice*) pj_ice_strans_get_user_data(ice_st);\n\n    /* Notify application */\n    if (tp_ice->cb.on_ice_complete)\n\t(*tp_ice->cb.on_ice_complete)(&tp_ice->base, op, result);\n}\n\n\nstatic void ice_on_ice_state(pj_ice_strans *ice_st,\n\t\t\t     pj_ice_strans_state prev,\n\t\t\t     pj_ice_strans_state curr)\n{\n    struct transport_ice *tp_ice;\n\n    tp_ice = (struct transport_ice*) pj_ice_strans_get_user_data(ice_st);\n\n    /* Notify application */\n    if (tp_ice->cb.on_ice_state)\n\t(*tp_ice->cb.on_ice_state)(&tp_ice->base, prev, curr);\n}\n\n\n/* Simulate lost */\nstatic pj_status_t transport_simulate_lost(pjmedia_transport *tp,\n\t\t\t\t\t   pjmedia_dir dir,\n\t\t\t\t\t   unsigned pct_lost)\n{\n    struct transport_ice *ice = (struct transport_ice*) tp;\n\n    PJ_ASSERT_RETURN(tp && pct_lost <= 100, PJ_EINVAL);\n\n    if (dir & PJMEDIA_DIR_ENCODING)\n\tice->tx_drop_pct = pct_lost;\n\n    if (dir & PJMEDIA_DIR_DECODING)\n\tice->rx_drop_pct = pct_lost;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy ICE media transport.\n */\nstatic pj_status_t transport_destroy(pjmedia_transport *tp)\n{\n    struct transport_ice *tp_ice = (struct transport_ice*)tp;\n\n    if (tp_ice->ice_st) {\n\tpj_ice_strans_destroy(tp_ice->ice_st);\n\ttp_ice->ice_st = NULL;\n    }\n\n    if (tp_ice->pool) {\n\tpj_pool_t *pool = tp_ice->pool;\n\ttp_ice->pool = NULL;\n\tpj_pool_release(pool);\n    }\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/transport_loop.c",
    "content": "/* $Id: transport_loop.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/transport_loop.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/ioqueue.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n\n\nstruct user\n{\n    pj_bool_t\t\trx_disabled;\t/**< Doesn't want to receive pkt?   */\n    void\t       *user_data;\t/**< Only valid when attached\t    */\n    void  (*rtp_cb)(\tvoid*,\t\t/**< To report incoming RTP.\t    */\n\t\t\tvoid*,\n\t\t\tpj_ssize_t);\n    void  (*rtcp_cb)(\tvoid*,\t\t/**< To report incoming RTCP.\t    */\n\t\t\tvoid*,\n\t\t\tpj_ssize_t);\n};\n\nstruct transport_loop\n{\n    pjmedia_transport\tbase;\t\t/**< Base transport.\t\t    */\n\n    pj_pool_t\t       *pool;\t\t/**< Memory pool\t\t    */\n    unsigned\t\tuser_cnt;\t/**< Number of attachments\t    */\n    struct user\t\tusers[4];\t/**< Array of users.\t\t    */\n\n    unsigned\t\ttx_drop_pct;\t/**< Percent of tx pkts to drop.    */\n    unsigned\t\trx_drop_pct;\t/**< Percent of rx pkts to drop.    */\n\n};\n\n\n\n/*\n * These are media transport operations.\n */\nstatic pj_status_t transport_get_info (pjmedia_transport *tp,\n\t\t\t\t       pjmedia_transport_info *info);\nstatic pj_status_t transport_attach   (pjmedia_transport *tp,\n\t\t\t\t       void *user_data,\n\t\t\t\t       const pj_sockaddr_t *rem_addr,\n\t\t\t\t       const pj_sockaddr_t *rem_rtcp,\n\t\t\t\t       unsigned addr_len,\n\t\t\t\t       void (*rtp_cb)(void*,\n\t\t\t\t\t\t      void*,\n\t\t\t\t\t\t      pj_ssize_t),\n\t\t\t\t       void (*rtcp_cb)(void*,\n\t\t\t\t\t\t       void*,\n\t\t\t\t\t\t       pj_ssize_t));\nstatic void\t   transport_detach   (pjmedia_transport *tp,\n\t\t\t\t       void *strm);\nstatic pj_status_t transport_send_rtp( pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_send_rtcp(pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_send_rtcp2(pjmedia_transport *tp,\n\t\t\t\t       const pj_sockaddr_t *addr,\n\t\t\t\t       unsigned addr_len,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_media_create(pjmedia_transport *tp,\n\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t       unsigned options,\n\t\t\t\t       const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t       unsigned media_index);\nstatic pj_status_t transport_encode_sdp(pjmedia_transport *tp,\n\t\t\t\t        pj_pool_t *pool,\n\t\t\t\t        pjmedia_sdp_session *sdp_local,\n\t\t\t\t        const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t        unsigned media_index);\nstatic pj_status_t transport_media_start (pjmedia_transport *tp,\n\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t       const pjmedia_sdp_session *sdp_local,\n\t\t\t\t       const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t       unsigned media_index);\nstatic pj_status_t transport_media_stop(pjmedia_transport *tp);\nstatic pj_status_t transport_simulate_lost(pjmedia_transport *tp,\n\t\t\t\t       pjmedia_dir dir,\n\t\t\t\t       unsigned pct_lost);\nstatic pj_status_t transport_destroy  (pjmedia_transport *tp);\n\n\nstatic pjmedia_transport_op transport_udp_op = \n{\n    &transport_get_info,\n    &transport_attach,\n    &transport_detach,\n    &transport_send_rtp,\n    &transport_send_rtcp,\n    &transport_send_rtcp2,\n    &transport_media_create,\n    &transport_encode_sdp,\n    &transport_media_start,\n    &transport_media_stop,\n    &transport_simulate_lost,\n    &transport_destroy\n};\n\n\n/**\n * Create loopback transport.\n */\nPJ_DEF(pj_status_t) pjmedia_transport_loop_create(pjmedia_endpt *endpt,\n\t\t\t\t\t\t  pjmedia_transport **p_tp)\n{\n    struct transport_loop *tp;\n    pj_pool_t *pool;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(endpt && p_tp, PJ_EINVAL);\n\n    /* Create transport structure */\n    pool = pjmedia_endpt_create_pool(endpt, \"tploop\", 512, 512);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    tp = PJ_POOL_ZALLOC_T(pool, struct transport_loop);\n    tp->pool = pool;\n    pj_ansi_strncpy(tp->base.name, tp->pool->obj_name, PJ_MAX_OBJ_NAME-1);\n    tp->base.op = &transport_udp_op;\n    tp->base.type = PJMEDIA_TRANSPORT_TYPE_UDP;\n\n    /* Done */\n    *p_tp = &tp->base;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_transport_loop_disable_rx( pjmedia_transport *tp,\n\t\t\t\t\t\t       void *user,\n\t\t\t\t\t\t       pj_bool_t disabled)\n{\n    struct transport_loop *loop = (struct transport_loop*) tp;\n    unsigned i;\n\n    for (i=0; i<loop->user_cnt; ++i) {\n\tif (loop->users[i].user_data == user) {\n\t    loop->users[i].rx_disabled = disabled;\n\t    return PJ_SUCCESS;\n\t}\n    }\n    pj_assert(!\"Invalid stream user\");\n    return PJ_ENOTFOUND;\n}\n\n/**\n * Close loopback transport.\n */\nstatic pj_status_t transport_destroy(pjmedia_transport *tp)\n{\n    struct transport_loop *loop = (struct transport_loop*) tp;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    pj_pool_release(loop->pool);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Called to get the transport info */\nstatic pj_status_t transport_get_info(pjmedia_transport *tp,\n\t\t\t\t      pjmedia_transport_info *info)\n{\n    PJ_ASSERT_RETURN(tp && info, PJ_EINVAL);\n\n    info->sock_info.rtp_sock = 1;\n    pj_sockaddr_in_init(&info->sock_info.rtp_addr_name.ipv4, 0, 0);\n    info->sock_info.rtcp_sock = 2;\n    pj_sockaddr_in_init(&info->sock_info.rtcp_addr_name.ipv4, 0, 0);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Called by application to initialize the transport */\nstatic pj_status_t transport_attach(   pjmedia_transport *tp,\n\t\t\t\t       void *user_data,\n\t\t\t\t       const pj_sockaddr_t *rem_addr,\n\t\t\t\t       const pj_sockaddr_t *rem_rtcp,\n\t\t\t\t       unsigned addr_len,\n\t\t\t\t       void (*rtp_cb)(void*,\n\t\t\t\t\t\t      void*,\n\t\t\t\t\t\t      pj_ssize_t),\n\t\t\t\t       void (*rtcp_cb)(void*,\n\t\t\t\t\t\t       void*,\n\t\t\t\t\t\t       pj_ssize_t))\n{\n    struct transport_loop *loop = (struct transport_loop*) tp;\n    unsigned i;\n    const pj_sockaddr *rtcp_addr;\n\n    /* Validate arguments */\n    PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL);\n\n    /* Must not be \"attached\" to same user */\n    for (i=0; i<loop->user_cnt; ++i) {\n\tPJ_ASSERT_RETURN(loop->users[i].user_data != user_data,\n\t\t\t PJ_EINVALIDOP);\n    }\n    PJ_ASSERT_RETURN(loop->user_cnt != PJ_ARRAY_SIZE(loop->users), \n\t\t     PJ_ETOOMANY);\n\n    PJ_UNUSED_ARG(rem_rtcp);\n    PJ_UNUSED_ARG(rtcp_addr);\n\n    /* \"Attach\" the application: */\n\n    /* Save the new user */\n    loop->users[loop->user_cnt].rtp_cb = rtp_cb;\n    loop->users[loop->user_cnt].rtcp_cb = rtcp_cb;\n    loop->users[loop->user_cnt].user_data = user_data;\n    ++loop->user_cnt;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Called by application when it no longer needs the transport */\nstatic void transport_detach( pjmedia_transport *tp,\n\t\t\t      void *user_data)\n{\n    struct transport_loop *loop = (struct transport_loop*) tp;\n    unsigned i;\n\n    pj_assert(tp);\n\n    for (i=0; i<loop->user_cnt; ++i) {\n\tif (loop->users[i].user_data == user_data)\n\t    break;\n    }\n\n    /* Remove this user */\n    if (i != loop->user_cnt) {\n\tpj_array_erase(loop->users, sizeof(loop->users[0]),\n\t\t       loop->user_cnt, i);\n\t--loop->user_cnt;\n    }\n}\n\n\n/* Called by application to send RTP packet */\nstatic pj_status_t transport_send_rtp( pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size)\n{\n    struct transport_loop *loop = (struct transport_loop*)tp;\n    unsigned i;\n\n    /* Simulate packet lost on TX direction */\n    if (loop->tx_drop_pct) {\n\tif ((pj_rand() % 100) <= (int)loop->tx_drop_pct) {\n\t    PJ_LOG(5,(loop->base.name, \n\t\t      \"TX RTP packet dropped because of pkt lost \"\n\t\t      \"simulation\"));\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    /* Simulate packet lost on RX direction */\n    if (loop->rx_drop_pct) {\n\tif ((pj_rand() % 100) <= (int)loop->rx_drop_pct) {\n\t    PJ_LOG(5,(loop->base.name, \n\t\t      \"RX RTP packet dropped because of pkt lost \"\n\t\t      \"simulation\"));\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    /* Distribute to users */\n    for (i=0; i<loop->user_cnt; ++i) {\n\tif (!loop->users[i].rx_disabled && loop->users[i].rtp_cb)\n\t    (*loop->users[i].rtp_cb)(loop->users[i].user_data, (void*)pkt, \n\t\t\t\t     size);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* Called by application to send RTCP packet */\nstatic pj_status_t transport_send_rtcp(pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size)\n{\n    return transport_send_rtcp2(tp, NULL, 0, pkt, size);\n}\n\n\n/* Called by application to send RTCP packet */\nstatic pj_status_t transport_send_rtcp2(pjmedia_transport *tp,\n\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\tunsigned addr_len,\n\t\t\t\t        const void *pkt,\n\t\t\t\t        pj_size_t size)\n{\n    struct transport_loop *loop = (struct transport_loop*)tp;\n    unsigned i;\n\n    PJ_UNUSED_ARG(addr_len);\n    PJ_UNUSED_ARG(addr);\n\n    /* Distribute to users */\n    for (i=0; i<loop->user_cnt; ++i) {\n\tif (!loop->users[i].rx_disabled && loop->users[i].rtcp_cb)\n\t    (*loop->users[i].rtcp_cb)(loop->users[i].user_data, (void*)pkt,\n\t\t\t\t      size);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t transport_media_create(pjmedia_transport *tp,\n\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t  unsigned options,\n\t\t\t\t  const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t  unsigned media_index)\n{\n    PJ_UNUSED_ARG(tp);\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(options);\n    PJ_UNUSED_ARG(sdp_remote);\n    PJ_UNUSED_ARG(media_index);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t transport_encode_sdp(pjmedia_transport *tp,\n\t\t\t\t        pj_pool_t *pool,\n\t\t\t\t        pjmedia_sdp_session *sdp_local,\n\t\t\t\t        const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t        unsigned media_index)\n{\n    PJ_UNUSED_ARG(tp);\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(sdp_local);\n    PJ_UNUSED_ARG(rem_sdp);\n    PJ_UNUSED_ARG(media_index);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t transport_media_start(pjmedia_transport *tp,\n\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t  const pjmedia_sdp_session *sdp_local,\n\t\t\t\t  const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t  unsigned media_index)\n{\n    PJ_UNUSED_ARG(tp);\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(sdp_local);\n    PJ_UNUSED_ARG(sdp_remote);\n    PJ_UNUSED_ARG(media_index);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t transport_media_stop(pjmedia_transport *tp)\n{\n    PJ_UNUSED_ARG(tp);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t transport_simulate_lost(pjmedia_transport *tp,\n\t\t\t\t\t   pjmedia_dir dir,\n\t\t\t\t\t   unsigned pct_lost)\n{\n    struct transport_loop *loop = (struct transport_loop*)tp;\n\n    PJ_ASSERT_RETURN(tp && pct_lost <= 100, PJ_EINVAL);\n\n    if (dir & PJMEDIA_DIR_ENCODING)\n\tloop->tx_drop_pct = pct_lost;\n    \n    if (dir & PJMEDIA_DIR_DECODING)\n\tloop->rx_drop_pct = pct_lost;\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/transport_srtp.c",
    "content": "/* $Id: transport_srtp.c 4366 2013-02-21 20:41:31Z ming $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\n */\n\n#include <pjmedia/transport_srtp.h>\n#include <pjmedia/endpoint.h>\n#include <pjlib-util/base64.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n\n#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)\n\n#if defined(PJ_HAS_SSL_SOCK) && (PJ_HAS_SSL_SOCK != 0)\n#  include <openssl/rand.h>\n\n/* Suppress compile warning of OpenSSL deprecation (OpenSSL is deprecated\n * since MacOSX 10.7).\n */\n#if defined(PJ_DARWINOS) && PJ_DARWINOS==1\n#  pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n#endif\n\n#endif\n\n#if defined(PJMEDIA_EXTERNAL_SRTP) && (PJMEDIA_EXTERNAL_SRTP != 0)\n#  include <srtp/srtp.h>\n#  include <srtp/crypto_kernel.h>\n#else\n#  include <srtp.h>\n#endif\n\n#define THIS_FILE   \"transport_srtp.c\"\n\n/* Maximum size of outgoing packet */\n#define MAX_RTP_BUFFER_LEN\t    PJMEDIA_MAX_MTU\n#define MAX_RTCP_BUFFER_LEN\t    PJMEDIA_MAX_MTU\n\n/* Maximum SRTP crypto key length */\n#define MAX_KEY_LEN\t\t    128\n\n/* Initial value of probation counter. When probation counter > 0,\n * it means SRTP is in probation state, and it may restart when\n * srtp_unprotect() returns err_status_replay_*\n */\n#define PROBATION_CNT_INIT\t    100\n\n#define DEACTIVATE_MEDIA(pool, m)   pjmedia_sdp_media_deactivate(pool, m)\n\nstatic const pj_str_t ID_RTP_AVP  = { \"RTP/AVP\", 7 };\nstatic const pj_str_t ID_RTP_SAVP = { \"RTP/SAVP\", 8 };\nstatic const pj_str_t ID_INACTIVE = { \"inactive\", 8 };\nstatic const pj_str_t ID_CRYPTO   = { \"crypto\", 6 };\n\ntypedef struct crypto_suite\n{\n    char\t\t*name;\n    cipher_type_id_t\t cipher_type;\n    unsigned\t\t cipher_key_len;\n    auth_type_id_t\t auth_type;\n    unsigned\t\t auth_key_len;\n    unsigned\t\t srtp_auth_tag_len;\n    unsigned\t\t srtcp_auth_tag_len;\n    sec_serv_t\t\t service;\n} crypto_suite;\n\n/* Crypto suites as defined on RFC 4568 */\nstatic crypto_suite crypto_suites[] = {\n    /* plain RTP/RTCP (no cipher & no auth) */\n    {\"NULL\", NULL_CIPHER, 0, NULL_AUTH, 0, 0, 0, sec_serv_none},\n\n    /* cipher AES_CM, auth HMAC_SHA1, auth tag len = 10 octets */\n    {\"AES_CM_128_HMAC_SHA1_80\", AES_128_ICM, 30, HMAC_SHA1, 20, 10, 10,\n\tsec_serv_conf_and_auth},\n\n    /* cipher AES_CM, auth HMAC_SHA1, auth tag len = 4 octets */\n    {\"AES_CM_128_HMAC_SHA1_32\", AES_128_ICM, 30, HMAC_SHA1, 20, 4, 10,\n\tsec_serv_conf_and_auth},\n\n    /*\n     * F8_128_HMAC_SHA1_8 not supported by libsrtp?\n     * {\"F8_128_HMAC_SHA1_8\", NULL_CIPHER, 0, NULL_AUTH, 0, 0, 0, sec_serv_none}\n     */\n};\n\ntypedef struct transport_srtp\n{\n    pjmedia_transport\t base;\t\t    /**< Base transport interface.  */\n    pj_pool_t\t\t*pool;\t\t    /**< Pool for transport SRTP.   */\n    pj_lock_t\t\t*mutex;\t\t    /**< Mutex for libsrtp contexts.*/\n    char\t\t rtp_tx_buffer[MAX_RTP_BUFFER_LEN];\n    char\t\t rtcp_tx_buffer[MAX_RTCP_BUFFER_LEN];\n    pjmedia_srtp_setting setting;\n    unsigned\t\t media_option;\n\n    /* SRTP policy */\n    pj_bool_t\t\t session_inited;\n    pj_bool_t\t\t offerer_side;\n    pj_bool_t\t\t bypass_srtp;\n    char\t\t tx_key[MAX_KEY_LEN];\n    char\t\t rx_key[MAX_KEY_LEN];\n    pjmedia_srtp_crypto  tx_policy;\n    pjmedia_srtp_crypto  rx_policy;\n\n    /* Temporary policy for negotiation */\n    pjmedia_srtp_crypto  tx_policy_neg;\n    pjmedia_srtp_crypto  rx_policy_neg;\n\n    /* libSRTP contexts */\n    srtp_t\t\t srtp_tx_ctx;\n    srtp_t\t\t srtp_rx_ctx;\n\n    /* Stream information */\n    void\t\t*user_data;\n    void\t\t(*rtp_cb)( void *user_data,\n\t\t\t\t   void *pkt,\n\t\t\t\t   pj_ssize_t size);\n    void\t\t(*rtcp_cb)(void *user_data,\n\t\t\t\t   void *pkt,\n\t\t\t\t   pj_ssize_t size);\n\n    /* Transport information */\n    pjmedia_transport\t*member_tp; /**< Underlying transport.       */\n\n    /* SRTP usage policy of peer. This field is updated when media is starting.\n     * This is useful when SRTP is in optional mode and peer is using mandatory\n     * mode, so when local is about to reinvite/update, it should offer\n     * RTP/SAVP instead of offering RTP/AVP.\n     */\n    pjmedia_srtp_use\t peer_use;\n\n    /* When probation counter > 0, it means SRTP is in probation state,\n     * and it may restart when srtp_unprotect() returns err_status_replay_*\n     */\n    unsigned\t\t probation_cnt;\n} transport_srtp;\n\n\n/*\n * This callback is called by transport when incoming rtp is received\n */\nstatic void srtp_rtp_cb( void *user_data, void *pkt, pj_ssize_t size);\n\n/*\n * This callback is called by transport when incoming rtcp is received\n */\nstatic void srtp_rtcp_cb( void *user_data, void *pkt, pj_ssize_t size);\n\n\n/*\n * These are media transport operations.\n */\nstatic pj_status_t transport_get_info (pjmedia_transport *tp,\n\t\t\t\t       pjmedia_transport_info *info);\nstatic pj_status_t transport_attach   (pjmedia_transport *tp,\n\t\t\t\t       void *user_data,\n\t\t\t\t       const pj_sockaddr_t *rem_addr,\n\t\t\t\t       const pj_sockaddr_t *rem_rtcp,\n\t\t\t\t       unsigned addr_len,\n\t\t\t\t       void (*rtp_cb)(void*,\n\t\t\t\t\t\t      void*,\n\t\t\t\t\t\t      pj_ssize_t),\n\t\t\t\t       void (*rtcp_cb)(void*,\n\t\t\t\t\t\t       void*,\n\t\t\t\t\t\t       pj_ssize_t));\nstatic void\t   transport_detach   (pjmedia_transport *tp,\n\t\t\t\t       void *strm);\nstatic pj_status_t transport_send_rtp( pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_send_rtcp(pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_send_rtcp2(pjmedia_transport *tp,\n\t\t\t\t       const pj_sockaddr_t *addr,\n\t\t\t\t       unsigned addr_len,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_media_create(pjmedia_transport *tp,\n\t\t\t\t       pj_pool_t *sdp_pool,\n\t\t\t\t       unsigned options,\n\t\t\t\t       const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t       unsigned media_index);\nstatic pj_status_t transport_encode_sdp(pjmedia_transport *tp,\n\t\t\t\t       pj_pool_t *sdp_pool,\n\t\t\t\t       pjmedia_sdp_session *sdp_local,\n\t\t\t\t       const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t       unsigned media_index);\nstatic pj_status_t transport_media_start (pjmedia_transport *tp,\n\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t       const pjmedia_sdp_session *sdp_local,\n\t\t\t\t       const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t       unsigned media_index);\nstatic pj_status_t transport_media_stop(pjmedia_transport *tp);\nstatic pj_status_t transport_simulate_lost(pjmedia_transport *tp,\n\t\t\t\t       pjmedia_dir dir,\n\t\t\t\t       unsigned pct_lost);\nstatic pj_status_t transport_destroy  (pjmedia_transport *tp);\n\n\n\nstatic pjmedia_transport_op transport_srtp_op =\n{\n    &transport_get_info,\n    &transport_attach,\n    &transport_detach,\n    &transport_send_rtp,\n    &transport_send_rtcp,\n    &transport_send_rtcp2,\n    &transport_media_create,\n    &transport_encode_sdp,\n    &transport_media_start,\n    &transport_media_stop,\n    &transport_simulate_lost,\n    &transport_destroy\n};\n\n/* This function may also be used by other module, e.g: pjmedia/errno.c,\n * it should have C compatible declaration.\n */\nPJ_BEGIN_DECL\n    const char* get_libsrtp_errstr(int err);\nPJ_END_DECL\n\nconst char* get_libsrtp_errstr(int err)\n{\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n    static char *liberr[] = {\n\t\"ok\",\t\t\t\t    /* err_status_ok            = 0  */\n\t\"unspecified failure\",\t\t    /* err_status_fail          = 1  */\n\t\"unsupported parameter\",\t    /* err_status_bad_param     = 2  */\n\t\"couldn't allocate memory\",\t    /* err_status_alloc_fail    = 3  */\n\t\"couldn't deallocate properly\",\t    /* err_status_dealloc_fail  = 4  */\n\t\"couldn't initialize\",\t\t    /* err_status_init_fail     = 5  */\n\t\"can't process as much data as requested\",\n\t\t\t\t\t    /* err_status_terminus      = 6  */\n\t\"authentication failure\",\t    /* err_status_auth_fail     = 7  */\n\t\"cipher failure\",\t\t    /* err_status_cipher_fail   = 8  */\n\t\"replay check failed (bad index)\",  /* err_status_replay_fail   = 9  */\n\t\"replay check failed (index too old)\",\n\t\t\t\t\t    /* err_status_replay_old    = 10 */\n\t\"algorithm failed test routine\",    /* err_status_algo_fail     = 11 */\n\t\"unsupported operation\",\t    /* err_status_no_such_op    = 12 */\n\t\"no appropriate context found\",\t    /* err_status_no_ctx        = 13 */\n\t\"unable to perform desired validation\",\n\t\t\t\t\t    /* err_status_cant_check    = 14 */\n\t\"can't use key any more\",\t    /* err_status_key_expired   = 15 */\n\t\"error in use of socket\",\t    /* err_status_socket_err    = 16 */\n\t\"error in use POSIX signals\",\t    /* err_status_signal_err    = 17 */\n\t\"nonce check failed\",\t\t    /* err_status_nonce_bad     = 18 */\n\t\"couldn't read data\",\t\t    /* err_status_read_fail     = 19 */\n\t\"couldn't write data\",\t\t    /* err_status_write_fail    = 20 */\n\t\"error pasring data\",\t\t    /* err_status_parse_err     = 21 */\n\t\"error encoding data\",\t\t    /* err_status_encode_err    = 22 */\n\t\"error while using semaphores\",\t    /* err_status_semaphore_err = 23 */\n\t\"error while using pfkey\"\t    /* err_status_pfkey_err     = 24 */\n    };\n    if (err >= 0 && err < (int)PJ_ARRAY_SIZE(liberr)) {\n\treturn liberr[err];\n    } else {\n\tstatic char msg[32];\n\tpj_ansi_snprintf(msg, sizeof(msg), \"Unknown libsrtp error %d\", err);\n\treturn msg;\n    }\n#else\n    static char msg[32];\n    pj_ansi_snprintf(msg, sizeof(msg), \"libsrtp error %d\", err);\n    return msg;\n#endif\n}\n\nstatic pj_bool_t libsrtp_initialized;\nstatic void pjmedia_srtp_deinit_lib(pjmedia_endpt *endpt);\n\nPJ_DEF(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt)\n{\n#if PJMEDIA_LIBSRTP_AUTO_INIT_DEINIT\n    if (libsrtp_initialized == PJ_FALSE) {\n\terr_status_t err;\n\n\terr = srtp_init();\n\tif (err != err_status_ok) {\n\t    PJ_LOG(4, (THIS_FILE, \"Failed to initialize libsrtp: %s\",\n\t\t       get_libsrtp_errstr(err)));\n\t    return PJMEDIA_ERRNO_FROM_LIBSRTP(err);\n\t}\n\n\tif (pjmedia_endpt_atexit(endpt, pjmedia_srtp_deinit_lib) != PJ_SUCCESS)\n\t{\n\t    /* There will be memory leak when it fails to schedule libsrtp\n\t     * deinitialization, however the memory leak could be harmless,\n\t     * since in modern OS's memory used by an application is released\n\t     * when the application terminates.\n\t     */\n\t    PJ_LOG(4, (THIS_FILE, \"Failed to register libsrtp deinit.\"));\n\t}\n\n\tlibsrtp_initialized = PJ_TRUE;\n    }\n#else\n    PJ_UNUSED_ARG(endpt);\n#endif\n\n    return PJ_SUCCESS;\n}\n\nstatic void pjmedia_srtp_deinit_lib(pjmedia_endpt *endpt)\n{\n    err_status_t err;\n\n    /* Note that currently this SRTP init/deinit is not equipped with\n     * reference counter, it should be safe as normally there is only\n     * one single instance of media endpoint and even if it isn't, the\n     * pjmedia_transport_srtp_create() will invoke SRTP init (the only\n     * drawback should be the delay described by #788).\n     */\n\n    PJ_UNUSED_ARG(endpt);\n\n#if defined(PJMEDIA_EXTERNAL_SRTP) && (PJMEDIA_EXTERNAL_SRTP != 0)\n\n# if defined(PJMEDIA_SRTP_HAS_DEINIT) && PJMEDIA_SRTP_HAS_DEINIT!=0\n    err = srtp_deinit();\n# elif defined(PJMEDIA_SRTP_HAS_SHUTDOWN) && PJMEDIA_SRTP_HAS_SHUTDOWN!=0\n    err = srtp_shutdown();\n# else\n    err = err_status_ok;\n# endif\n\n#else\n    err = srtp_deinit();\n#endif\n    if (err != err_status_ok) {\n\tPJ_LOG(4, (THIS_FILE, \"Failed to deinitialize libsrtp: %s\",\n\t\t   get_libsrtp_errstr(err)));\n    }\n\n    libsrtp_initialized = PJ_FALSE;\n}\n\n\nstatic int get_crypto_idx(const pj_str_t* crypto_name)\n{\n    int i;\n    int cs_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]);\n\n    /* treat unspecified crypto_name as crypto 'NULL' */\n    if (crypto_name->slen == 0)\n\treturn 0;\n\n    for (i=0; i<cs_cnt; ++i) {\n\tif (!pj_stricmp2(crypto_name, crypto_suites[i].name))\n\t    return i;\n    }\n\n    return -1;\n}\n\n\nstatic int srtp_crypto_cmp(const pjmedia_srtp_crypto* c1,\n\t\t\t   const pjmedia_srtp_crypto* c2)\n{\n    int r;\n\n    r = pj_strcmp(&c1->key, &c2->key);\n    if (r != 0)\n\treturn r;\n\n    r = pj_stricmp(&c1->name, &c2->name);\n    if (r != 0)\n\treturn r;\n\n    return (c1->flags != c2->flags);\n}\n\n\nstatic pj_bool_t srtp_crypto_empty(const pjmedia_srtp_crypto* c)\n{\n    return (c->name.slen==0 || c->key.slen==0);\n}\n\n\nPJ_DEF(void) pjmedia_srtp_setting_default(pjmedia_srtp_setting *opt)\n{\n    unsigned i;\n\n    pj_assert(opt);\n\n    pj_bzero(opt, sizeof(pjmedia_srtp_setting));\n    opt->close_member_tp = PJ_TRUE;\n    opt->use = PJMEDIA_SRTP_OPTIONAL;\n\n    /* Copy default crypto-suites, but skip crypto 'NULL' */\n    opt->crypto_count = sizeof(crypto_suites)/sizeof(crypto_suites[0]) - 1;\n    for (i=0; i<opt->crypto_count; ++i)\n\topt->crypto[i].name = pj_str(crypto_suites[i+1].name);\n}\n\n\n/*\n * Create an SRTP media transport.\n */\nPJ_DEF(pj_status_t) pjmedia_transport_srtp_create(\n\t\t\t\t       pjmedia_endpt *endpt,\n\t\t\t\t       pjmedia_transport *tp,\n\t\t\t\t       const pjmedia_srtp_setting *opt,\n\t\t\t\t       pjmedia_transport **p_tp)\n{\n    pj_pool_t *pool;\n    transport_srtp *srtp;\n    pj_status_t status;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(endpt && tp && p_tp, PJ_EINVAL);\n\n    /* Check crypto availability */\n    if (opt && opt->crypto_count == 0 &&\n\topt->use == PJMEDIA_SRTP_MANDATORY)\n\treturn PJMEDIA_SRTP_ESDPREQCRYPTO;\n\n    /* Check crypto */\n    if (opt && opt->use != PJMEDIA_SRTP_DISABLED) {\n\tfor (i=0; i < opt->crypto_count; ++i) {\n\t    int cs_idx = get_crypto_idx(&opt->crypto[i].name);\n\n\t    /* check crypto name */\n\t    if (cs_idx == -1)\n\t\treturn PJMEDIA_SRTP_ENOTSUPCRYPTO;\n\n\t    /* check key length */\n\t    if (opt->crypto[i].key.slen &&\n\t\topt->crypto[i].key.slen <\n\t\t(pj_ssize_t)crypto_suites[cs_idx].cipher_key_len)\n\t\treturn PJMEDIA_SRTP_EINKEYLEN;\n\t}\n    }\n\n    /* Init libsrtp. */\n    status = pjmedia_srtp_init_lib(endpt);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pool = pjmedia_endpt_create_pool(endpt, \"srtp%p\", 1000, 1000);\n    srtp = PJ_POOL_ZALLOC_T(pool, transport_srtp);\n\n    srtp->pool = pool;\n    srtp->session_inited = PJ_FALSE;\n    srtp->bypass_srtp = PJ_FALSE;\n    srtp->probation_cnt = PROBATION_CNT_INIT;\n\n    if (opt) {\n\tsrtp->setting = *opt;\n\tif (opt->use == PJMEDIA_SRTP_DISABLED)\n\t    srtp->setting.crypto_count = 0;\n\n\tfor (i=0; i < srtp->setting.crypto_count; ++i) {\n\t    int cs_idx = get_crypto_idx(&opt->crypto[i].name);\n\t    pj_str_t tmp_key = opt->crypto[i].key;\n\n\t    /* re-set crypto */\n\t    srtp->setting.crypto[i].name = pj_str(crypto_suites[cs_idx].name);\n\t    /* cut key length */\n\t    if (tmp_key.slen)\n\t\ttmp_key.slen = crypto_suites[cs_idx].cipher_key_len;\n\t    pj_strdup(pool, &srtp->setting.crypto[i].key, &tmp_key);\n\t}\n    } else {\n\tpjmedia_srtp_setting_default(&srtp->setting);\n    }\n\n    status = pj_lock_create_recursive_mutex(pool, pool->obj_name, &srtp->mutex);\n    if (status != PJ_SUCCESS) {\n\tpj_pool_release(pool);\n\treturn status;\n    }\n\n    /* Initialize base pjmedia_transport */\n    pj_memcpy(srtp->base.name, pool->obj_name, PJ_MAX_OBJ_NAME);\n    if (tp)\n\tsrtp->base.type = tp->type;\n    else\n\tsrtp->base.type = PJMEDIA_TRANSPORT_TYPE_UDP;\n    srtp->base.op = &transport_srtp_op;\n\n    /* Set underlying transport */\n    srtp->member_tp = tp;\n\n    /* Initialize peer's SRTP usage mode. */\n    srtp->peer_use = srtp->setting.use;\n\n    /* Done */\n    *p_tp = &srtp->base;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Initialize and start SRTP session with the given parameters.\n */\nPJ_DEF(pj_status_t) pjmedia_transport_srtp_start(\n\t\t\t   pjmedia_transport *tp,\n\t\t\t   const pjmedia_srtp_crypto *tx,\n\t\t\t   const pjmedia_srtp_crypto *rx)\n{\n    transport_srtp  *srtp = (transport_srtp*) tp;\n    srtp_policy_t    tx_;\n    srtp_policy_t    rx_;\n    err_status_t     err;\n    int\t\t     cr_tx_idx = 0;\n    int\t\t     au_tx_idx = 0;\n    int\t\t     cr_rx_idx = 0;\n    int\t\t     au_rx_idx = 0;\n    pj_status_t\t     status = PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(tp && tx && rx, PJ_EINVAL);\n\n    pj_lock_acquire(srtp->mutex);\n\n    if (srtp->session_inited) {\n\tpjmedia_transport_srtp_stop(tp);\n    }\n\n    /* Get encryption and authentication method */\n    cr_tx_idx = au_tx_idx = get_crypto_idx(&tx->name);\n    if (tx->flags & PJMEDIA_SRTP_NO_ENCRYPTION)\n\tcr_tx_idx = 0;\n    if (tx->flags & PJMEDIA_SRTP_NO_AUTHENTICATION)\n\tau_tx_idx = 0;\n\n    cr_rx_idx = au_rx_idx = get_crypto_idx(&rx->name);\n    if (rx->flags & PJMEDIA_SRTP_NO_ENCRYPTION)\n\tcr_rx_idx = 0;\n    if (rx->flags & PJMEDIA_SRTP_NO_AUTHENTICATION)\n\tau_rx_idx = 0;\n\n    /* Check whether the crypto-suite requested is supported */\n    if (cr_tx_idx == -1 || cr_rx_idx == -1 || au_tx_idx == -1 ||\n\tau_rx_idx == -1)\n    {\n\tstatus = PJMEDIA_SRTP_ENOTSUPCRYPTO;\n\tgoto on_return;\n    }\n\n    /* If all options points to 'NULL' method, just bypass SRTP */\n    if (cr_tx_idx == 0 && cr_rx_idx == 0 && au_tx_idx == 0 && au_rx_idx == 0) {\n\tsrtp->bypass_srtp = PJ_TRUE;\n\tgoto on_return;\n    }\n\n    /* Check key length */\n    if (tx->key.slen != (pj_ssize_t)crypto_suites[cr_tx_idx].cipher_key_len ||\n        rx->key.slen != (pj_ssize_t)crypto_suites[cr_rx_idx].cipher_key_len)\n    {\n\tstatus = PJMEDIA_SRTP_EINKEYLEN;\n\tgoto on_return;\n    }\n\n    /* Init transmit direction */\n    pj_bzero(&tx_, sizeof(srtp_policy_t));\n    pj_memmove(srtp->tx_key, tx->key.ptr, tx->key.slen);\n    if (cr_tx_idx && au_tx_idx)\n\ttx_.rtp.sec_serv    = sec_serv_conf_and_auth;\n    else if (cr_tx_idx)\n\ttx_.rtp.sec_serv    = sec_serv_conf;\n    else if (au_tx_idx)\n\ttx_.rtp.sec_serv    = sec_serv_auth;\n    else\n\ttx_.rtp.sec_serv    = sec_serv_none;\n    tx_.key\t\t    = (uint8_t*)srtp->tx_key;\n    tx_.ssrc.type\t    = ssrc_any_outbound;\n    tx_.ssrc.value\t    = 0;\n    tx_.rtp.cipher_type\t    = crypto_suites[cr_tx_idx].cipher_type;\n    tx_.rtp.cipher_key_len  = crypto_suites[cr_tx_idx].cipher_key_len;\n    tx_.rtp.auth_type\t    = crypto_suites[au_tx_idx].auth_type;\n    tx_.rtp.auth_key_len    = crypto_suites[au_tx_idx].auth_key_len;\n    tx_.rtp.auth_tag_len    = crypto_suites[au_tx_idx].srtp_auth_tag_len;\n    tx_.rtcp\t\t    = tx_.rtp;\n    tx_.rtcp.auth_tag_len   = crypto_suites[au_tx_idx].srtcp_auth_tag_len;\n    tx_.next\t\t    = NULL;\n    err = srtp_create(&srtp->srtp_tx_ctx, &tx_);\n    if (err != err_status_ok) {\n\tstatus = PJMEDIA_ERRNO_FROM_LIBSRTP(err);\n\tgoto on_return;\n    }\n    srtp->tx_policy = *tx;\n    pj_strset(&srtp->tx_policy.key,  srtp->tx_key, tx->key.slen);\n    srtp->tx_policy.name=pj_str(crypto_suites[get_crypto_idx(&tx->name)].name);\n\n\n    /* Init receive direction */\n    pj_bzero(&rx_, sizeof(srtp_policy_t));\n    pj_memmove(srtp->rx_key, rx->key.ptr, rx->key.slen);\n    if (cr_rx_idx && au_rx_idx)\n\trx_.rtp.sec_serv    = sec_serv_conf_and_auth;\n    else if (cr_rx_idx)\n\trx_.rtp.sec_serv    = sec_serv_conf;\n    else if (au_rx_idx)\n\trx_.rtp.sec_serv    = sec_serv_auth;\n    else\n\trx_.rtp.sec_serv    = sec_serv_none;\n    rx_.key\t\t    = (uint8_t*)srtp->rx_key;\n    rx_.ssrc.type\t    = ssrc_any_inbound;\n    rx_.ssrc.value\t    = 0;\n    rx_.rtp.sec_serv\t    = crypto_suites[cr_rx_idx].service;\n    rx_.rtp.cipher_type\t    = crypto_suites[cr_rx_idx].cipher_type;\n    rx_.rtp.cipher_key_len  = crypto_suites[cr_rx_idx].cipher_key_len;\n    rx_.rtp.auth_type\t    = crypto_suites[au_rx_idx].auth_type;\n    rx_.rtp.auth_key_len    = crypto_suites[au_rx_idx].auth_key_len;\n    rx_.rtp.auth_tag_len    = crypto_suites[au_rx_idx].srtp_auth_tag_len;\n    rx_.rtcp\t\t    = rx_.rtp;\n    rx_.rtcp.auth_tag_len   = crypto_suites[au_rx_idx].srtcp_auth_tag_len;\n    rx_.next\t\t    = NULL;\n    err = srtp_create(&srtp->srtp_rx_ctx, &rx_);\n    if (err != err_status_ok) {\n\tsrtp_dealloc(srtp->srtp_tx_ctx);\n\tstatus = PJMEDIA_ERRNO_FROM_LIBSRTP(err);\n\tgoto on_return;\n    }\n    srtp->rx_policy = *rx;\n    pj_strset(&srtp->rx_policy.key,  srtp->rx_key, rx->key.slen);\n    srtp->rx_policy.name=pj_str(crypto_suites[get_crypto_idx(&rx->name)].name);\n\n    /* Declare SRTP session initialized */\n    srtp->session_inited = PJ_TRUE;\n\n    /* Logging stuffs */\n#if PJ_LOG_MAX_LEVEL >= 5\n    {\n\tchar b64[PJ_BASE256_TO_BASE64_LEN(MAX_KEY_LEN)];\n\tint b64_len;\n\n\t/* TX crypto and key */\n\tb64_len = sizeof(b64);\n\tstatus = pj_base64_encode((pj_uint8_t*)tx->key.ptr, tx->key.slen,\n\t\t\t\t  b64, &b64_len);\n\tif (status != PJ_SUCCESS)\n\t    b64_len = pj_ansi_sprintf(b64, \"--key too long--\");\n\telse\n\t    b64[b64_len] = '\\0';\n\n\tPJ_LOG(5, (srtp->pool->obj_name, \"TX: %s key=%s\",\n\t\t   srtp->tx_policy.name.ptr, b64));\n\tif (srtp->tx_policy.flags) {\n\t    PJ_LOG(5,(srtp->pool->obj_name, \"TX: disable%s%s\",\n\t\t      (cr_tx_idx?\"\":\" enc\"),\n\t\t      (au_tx_idx?\"\":\" auth\")));\n\t}\n\n\t/* RX crypto and key */\n\tb64_len = sizeof(b64);\n\tstatus = pj_base64_encode((pj_uint8_t*)rx->key.ptr, rx->key.slen,\n\t\t\t\t  b64, &b64_len);\n\tif (status != PJ_SUCCESS)\n\t    b64_len = pj_ansi_sprintf(b64, \"--key too long--\");\n\telse\n\t    b64[b64_len] = '\\0';\n\n\tPJ_LOG(5, (srtp->pool->obj_name, \"RX: %s key=%s\",\n\t\t   srtp->rx_policy.name.ptr, b64));\n\tif (srtp->rx_policy.flags) {\n\t    PJ_LOG(5,(srtp->pool->obj_name,\"RX: disable%s%s\",\n\t\t      (cr_rx_idx?\"\":\" enc\"),\n\t\t      (au_rx_idx?\"\":\" auth\")));\n\t}\n    }\n#endif\n\non_return:\n    pj_lock_release(srtp->mutex);\n    return status;\n}\n\n/*\n * Stop SRTP session.\n */\nPJ_DEF(pj_status_t) pjmedia_transport_srtp_stop(pjmedia_transport *srtp)\n{\n    transport_srtp *p_srtp = (transport_srtp*) srtp;\n    err_status_t err;\n\n    PJ_ASSERT_RETURN(srtp, PJ_EINVAL);\n\n    pj_lock_acquire(p_srtp->mutex);\n\n    if (!p_srtp->session_inited) {\n\tpj_lock_release(p_srtp->mutex);\n\treturn PJ_SUCCESS;\n    }\n\n    err = srtp_dealloc(p_srtp->srtp_rx_ctx);\n    if (err != err_status_ok) {\n\tPJ_LOG(4, (p_srtp->pool->obj_name,\n\t\t   \"Failed to dealloc RX SRTP context: %s\",\n\t\t   get_libsrtp_errstr(err)));\n    }\n    err = srtp_dealloc(p_srtp->srtp_tx_ctx);\n    if (err != err_status_ok) {\n\tPJ_LOG(4, (p_srtp->pool->obj_name,\n\t\t   \"Failed to dealloc TX SRTP context: %s\",\n\t\t   get_libsrtp_errstr(err)));\n    }\n\n    p_srtp->session_inited = PJ_FALSE;\n    pj_bzero(&p_srtp->rx_policy, sizeof(p_srtp->rx_policy));\n    pj_bzero(&p_srtp->tx_policy, sizeof(p_srtp->tx_policy));\n\n    pj_lock_release(p_srtp->mutex);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pjmedia_transport *) pjmedia_transport_srtp_get_member(\n\t\t\t\t\t\tpjmedia_transport *tp)\n{\n    transport_srtp *srtp = (transport_srtp*) tp;\n\n    PJ_ASSERT_RETURN(tp, NULL);\n\n    return srtp->member_tp;\n}\n\n\nstatic pj_status_t transport_get_info(pjmedia_transport *tp,\n\t\t\t\t      pjmedia_transport_info *info)\n{\n    transport_srtp *srtp = (transport_srtp*) tp;\n    pjmedia_srtp_info srtp_info;\n    int spc_info_idx;\n\n    PJ_ASSERT_RETURN(tp && info, PJ_EINVAL);\n    PJ_ASSERT_RETURN(info->specific_info_cnt <\n\t\t     PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT, PJ_ETOOMANY);\n    PJ_ASSERT_RETURN(sizeof(pjmedia_srtp_info) <=\n\t\t     PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE, PJ_ENOMEM);\n\n    srtp_info.active = srtp->session_inited;\n    srtp_info.rx_policy = srtp->rx_policy;\n    srtp_info.tx_policy = srtp->tx_policy;\n    srtp_info.use = srtp->setting.use;\n    srtp_info.peer_use = srtp->peer_use;\n\n    spc_info_idx = info->specific_info_cnt++;\n    info->spc_info[spc_info_idx].type = PJMEDIA_TRANSPORT_TYPE_SRTP;\n    info->spc_info[spc_info_idx].cbsize = sizeof(srtp_info);\n    pj_memcpy(&info->spc_info[spc_info_idx].buffer, &srtp_info,\n\t      sizeof(srtp_info));\n\n    return pjmedia_transport_get_info(srtp->member_tp, info);\n}\n\nstatic pj_status_t transport_attach(pjmedia_transport *tp,\n\t\t\t\t    void *user_data,\n\t\t\t\t    const pj_sockaddr_t *rem_addr,\n\t\t\t\t    const pj_sockaddr_t *rem_rtcp,\n\t\t\t\t    unsigned addr_len,\n\t\t\t\t    void (*rtp_cb) (void*, void*,\n\t\t\t\t\t\t    pj_ssize_t),\n\t\t\t\t    void (*rtcp_cb)(void*, void*,\n\t\t\t\t\t\t    pj_ssize_t))\n{\n    transport_srtp *srtp = (transport_srtp*) tp;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL);\n\n    /* Save the callbacks */\n    pj_lock_acquire(srtp->mutex);\n    srtp->rtp_cb = rtp_cb;\n    srtp->rtcp_cb = rtcp_cb;\n    srtp->user_data = user_data;\n    pj_lock_release(srtp->mutex);\n\n    /* Attach itself to transport */\n    status = pjmedia_transport_attach(srtp->member_tp, srtp, rem_addr,\n\t\t\t\t      rem_rtcp, addr_len, &srtp_rtp_cb,\n\t\t\t\t      &srtp_rtcp_cb);\n    if (status != PJ_SUCCESS) {\n\tpj_lock_acquire(srtp->mutex);\n\tsrtp->rtp_cb = NULL;\n\tsrtp->rtcp_cb = NULL;\n\tsrtp->user_data = NULL;\n\tpj_lock_release(srtp->mutex);\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic void transport_detach(pjmedia_transport *tp, void *strm)\n{\n    transport_srtp *srtp = (transport_srtp*) tp;\n\n    PJ_UNUSED_ARG(strm);\n    PJ_ASSERT_ON_FAIL(tp, return);\n\n    if (srtp->member_tp) {\n\tpjmedia_transport_detach(srtp->member_tp, srtp);\n    }\n\n    /* Clear up application infos from transport */\n    pj_lock_acquire(srtp->mutex);\n    srtp->rtp_cb = NULL;\n    srtp->rtcp_cb = NULL;\n    srtp->user_data = NULL;\n    pj_lock_release(srtp->mutex);\n}\n\nstatic pj_status_t transport_send_rtp( pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size)\n{\n    pj_status_t status;\n    transport_srtp *srtp = (transport_srtp*) tp;\n    int len = (int)size;\n    err_status_t err;\n\n    if (srtp->bypass_srtp)\n\treturn pjmedia_transport_send_rtp(srtp->member_tp, pkt, size);\n\n    if (size > sizeof(srtp->rtp_tx_buffer) - 10)\n\treturn PJ_ETOOBIG;\n\n    pj_memcpy(srtp->rtp_tx_buffer, pkt, size);\n\n    pj_lock_acquire(srtp->mutex);\n    if (!srtp->session_inited) {\n\tpj_lock_release(srtp->mutex);\n\treturn PJ_EINVALIDOP;\n    }\n    err = srtp_protect(srtp->srtp_tx_ctx, srtp->rtp_tx_buffer, &len);\n    pj_lock_release(srtp->mutex);\n\n    if (err == err_status_ok) {\n\tstatus = pjmedia_transport_send_rtp(srtp->member_tp,\n\t\t\t\t\t    srtp->rtp_tx_buffer, len);\n    } else {\n\tstatus = PJMEDIA_ERRNO_FROM_LIBSRTP(err);\n    }\n\n    return status;\n}\n\nstatic pj_status_t transport_send_rtcp(pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size)\n{\n    return transport_send_rtcp2(tp, NULL, 0, pkt, size);\n}\n\nstatic pj_status_t transport_send_rtcp2(pjmedia_transport *tp,\n\t\t\t\t        const pj_sockaddr_t *addr,\n\t\t\t\t        unsigned addr_len,\n\t\t\t\t        const void *pkt,\n\t\t\t\t        pj_size_t size)\n{\n    pj_status_t status;\n    transport_srtp *srtp = (transport_srtp*) tp;\n    int len = (int)size;\n    err_status_t err;\n\n    if (srtp->bypass_srtp) {\n\treturn pjmedia_transport_send_rtcp2(srtp->member_tp, addr, addr_len,\n\t                                    pkt, size);\n    }\n\n    if (size > sizeof(srtp->rtcp_tx_buffer) - 10)\n\treturn PJ_ETOOBIG;\n\n    pj_memcpy(srtp->rtcp_tx_buffer, pkt, size);\n\n    pj_lock_acquire(srtp->mutex);\n    if (!srtp->session_inited) {\n\tpj_lock_release(srtp->mutex);\n\treturn PJ_EINVALIDOP;\n    }\n    err = srtp_protect_rtcp(srtp->srtp_tx_ctx, srtp->rtcp_tx_buffer, &len);\n    pj_lock_release(srtp->mutex);\n\n    if (err == err_status_ok) {\n\tstatus = pjmedia_transport_send_rtcp2(srtp->member_tp, addr, addr_len,\n\t\t\t\t\t      srtp->rtcp_tx_buffer, len);\n    } else {\n\tstatus = PJMEDIA_ERRNO_FROM_LIBSRTP(err);\n    }\n\n    return status;\n}\n\n\nstatic pj_status_t transport_simulate_lost(pjmedia_transport *tp,\n\t\t\t\t\t   pjmedia_dir dir,\n\t\t\t\t\t   unsigned pct_lost)\n{\n    transport_srtp *srtp = (transport_srtp *) tp;\n\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    return pjmedia_transport_simulate_lost(srtp->member_tp, dir, pct_lost);\n}\n\nstatic pj_status_t transport_destroy  (pjmedia_transport *tp)\n{\n    transport_srtp *srtp = (transport_srtp *) tp;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    if (srtp->setting.close_member_tp && srtp->member_tp) {\n\tpjmedia_transport_close(srtp->member_tp);\n    }\n\n    status = pjmedia_transport_srtp_stop(tp);\n\n    /* In case mutex is being acquired by other thread */\n    pj_lock_acquire(srtp->mutex);\n    pj_lock_release(srtp->mutex);\n\n    pj_lock_destroy(srtp->mutex);\n    pj_pool_release(srtp->pool);\n\n    return status;\n}\n\n/*\n * This callback is called by transport when incoming rtp is received\n */\nstatic void srtp_rtp_cb( void *user_data, void *pkt, pj_ssize_t size)\n{\n    transport_srtp *srtp = (transport_srtp *) user_data;\n    int len = size;\n    err_status_t err;\n    void (*cb)(void*, void*, pj_ssize_t) = NULL;\n    void *cb_data = NULL;\n\n    if (srtp->bypass_srtp) {\n\tsrtp->rtp_cb(srtp->user_data, pkt, size);\n\treturn;\n    }\n\n    if (size < 0) {\n\treturn;\n    }\n\n    /* Make sure buffer is 32bit aligned */\n    PJ_ASSERT_ON_FAIL( (((pj_ssize_t)pkt) & 0x03)==0, return );\n\n    if (srtp->probation_cnt > 0)\n\t--srtp->probation_cnt;\n\n    pj_lock_acquire(srtp->mutex);\n\n    if (!srtp->session_inited) {\n\tpj_lock_release(srtp->mutex);\n\treturn;\n    }\n    err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);\n    if (srtp->probation_cnt > 0 &&\n\t(err == err_status_replay_old || err == err_status_replay_fail))\n    {\n\t/* Handle such condition that stream is updated (RTP seq is reinited\n\t * & SRTP is restarted), but some old packets are still coming\n\t * so SRTP is learning wrong RTP seq. While the newly inited RTP seq\n\t * comes, SRTP thinks the RTP seq is replayed, so srtp_unprotect()\n\t * will return err_status_replay_*. Restarting SRTP can resolve this.\n\t */\n\tpjmedia_srtp_crypto tx, rx;\n\tpj_status_t status;\n\n\ttx = srtp->tx_policy;\n\trx = srtp->rx_policy;\n\tstatus = pjmedia_transport_srtp_start((pjmedia_transport*)srtp,\n\t\t\t\t\t      &tx, &rx);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_LOG(5,(srtp->pool->obj_name, \"Failed to restart SRTP, err=%s\",\n\t\t      get_libsrtp_errstr(err)));\n\t} else if (!srtp->bypass_srtp) {\n\t    err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);\n\t}\n    }\n\n    if (err != err_status_ok) {\n\tPJ_LOG(5,(srtp->pool->obj_name,\n\t\t  \"Failed to unprotect SRTP, pkt size=%d, err=%s\",\n\t\t  size, get_libsrtp_errstr(err)));\n    } else {\n\tcb = srtp->rtp_cb;\n\tcb_data = srtp->user_data;\n    }\n\n    pj_lock_release(srtp->mutex);\n\n    if (cb) {\n\t(*cb)(cb_data, pkt, len);\n    }\n}\n\n/*\n * This callback is called by transport when incoming rtcp is received\n */\nstatic void srtp_rtcp_cb( void *user_data, void *pkt, pj_ssize_t size)\n{\n    transport_srtp *srtp = (transport_srtp *) user_data;\n    int len = size;\n    err_status_t err;\n    void (*cb)(void*, void*, pj_ssize_t) = NULL;\n    void *cb_data = NULL;\n\n    if (srtp->bypass_srtp) {\n\tsrtp->rtcp_cb(srtp->user_data, pkt, size);\n\treturn;\n    }\n\n    if (size < 0) {\n\treturn;\n    }\n\n    /* Make sure buffer is 32bit aligned */\n    PJ_ASSERT_ON_FAIL( (((pj_ssize_t)pkt) & 0x03)==0, return );\n\n    pj_lock_acquire(srtp->mutex);\n\n    if (!srtp->session_inited) {\n\tpj_lock_release(srtp->mutex);\n\treturn;\n    }\n    err = srtp_unprotect_rtcp(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);\n    if (err != err_status_ok) {\n\tPJ_LOG(5,(srtp->pool->obj_name,\n\t\t  \"Failed to unprotect SRTCP, pkt size=%d, err=%s\",\n\t\t  size, get_libsrtp_errstr(err)));\n    } else {\n\tcb = srtp->rtcp_cb;\n\tcb_data = srtp->user_data;\n    }\n\n    pj_lock_release(srtp->mutex);\n\n    if (cb) {\n\t(*cb)(cb_data, pkt, len);\n    }\n}\n\n/* Generate crypto attribute, including crypto key.\n * If crypto-suite chosen is crypto NULL, just return PJ_SUCCESS,\n * and set buffer_len = 0.\n */\nstatic pj_status_t generate_crypto_attr_value(pj_pool_t *pool,\n\t\t\t\t\t      char *buffer, int *buffer_len,\n\t\t\t\t\t      pjmedia_srtp_crypto *crypto,\n\t\t\t\t\t      int tag)\n{\n    pj_status_t status;\n    int cs_idx = get_crypto_idx(&crypto->name);\n    char b64_key[PJ_BASE256_TO_BASE64_LEN(MAX_KEY_LEN)+1];\n    int b64_key_len = sizeof(b64_key);\n    int print_len;\n\n    if (cs_idx == -1)\n\treturn PJMEDIA_SRTP_ENOTSUPCRYPTO;\n\n    /* Crypto-suite NULL. */\n    if (cs_idx == 0) {\n\t*buffer_len = 0;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Generate key if not specified. */\n    if (crypto->key.slen == 0) {\n\tpj_bool_t key_ok;\n\tchar key[MAX_KEY_LEN];\n\terr_status_t err;\n\tunsigned i;\n\n\tPJ_ASSERT_RETURN(MAX_KEY_LEN >= crypto_suites[cs_idx].cipher_key_len,\n\t\t\t PJ_ETOOSMALL);\n\n\tdo {\n\t    key_ok = PJ_TRUE;\n\n\n#if defined(PJ_HAS_SSL_SOCK) && (PJ_HAS_SSL_SOCK != 0)\n\n/* Include OpenSSL libraries for MSVC */\n#  ifdef _MSC_VER\n#    pragma comment( lib, \"libeay32\")\n#    pragma comment( lib, \"ssleay32\")\n#  endif\n\n\t    err = RAND_bytes((unsigned char*)key,\n\t\t\t     crypto_suites[cs_idx].cipher_key_len);\n\t    if (err != 1) {\n\t\tPJ_LOG(5,(THIS_FILE, \"Failed generating random key\"));\n\t\treturn PJMEDIA_ERRNO_FROM_LIBSRTP(1);\n\t    }\n#else\t    \n\t    err = crypto_get_random((unsigned char*)key,\n\t\t\t\t     crypto_suites[cs_idx].cipher_key_len);\n\t    if (err != err_status_ok) {\n\t\tPJ_LOG(5,(THIS_FILE, \"Failed generating random key: %s\",\n\t\t\t  get_libsrtp_errstr(err)));\n\t\treturn PJMEDIA_ERRNO_FROM_LIBSRTP(err);\n\t    }\n#endif\n\t    for (i=0; i<crypto_suites[cs_idx].cipher_key_len && key_ok; ++i)\n\t\tif (key[i] == 0) key_ok = PJ_FALSE;\n\n\t} while (!key_ok);\n\tcrypto->key.ptr = (char*)\n\t\t\t  pj_pool_zalloc(pool,\n\t\t\t\t\t crypto_suites[cs_idx].cipher_key_len);\n\tpj_memcpy(crypto->key.ptr, key, crypto_suites[cs_idx].cipher_key_len);\n\tcrypto->key.slen = crypto_suites[cs_idx].cipher_key_len;\n    }\n\n    if (crypto->key.slen != (pj_ssize_t)crypto_suites[cs_idx].cipher_key_len)\n\treturn PJMEDIA_SRTP_EINKEYLEN;\n\n    /* Key transmitted via SDP should be base64 encoded. */\n    status = pj_base64_encode((pj_uint8_t*)crypto->key.ptr, crypto->key.slen,\n\t\t\t      b64_key, &b64_key_len);\n    if (status != PJ_SUCCESS) {\n\tPJ_LOG(5,(THIS_FILE, \"Failed encoding plain key to base64\"));\n\treturn status;\n    }\n\n    b64_key[b64_key_len] = '\\0';\n\n    PJ_ASSERT_RETURN(*buffer_len >= (crypto->name.slen + \\\n\t\t     b64_key_len + 16), PJ_ETOOSMALL);\n\n    /* Print the crypto attribute value. */\n    print_len = pj_ansi_snprintf(buffer, *buffer_len, \"%d %s inline:%s\",\n\t\t\t\t   tag,\n\t\t\t\t   crypto_suites[cs_idx].name,\n\t\t\t\t   b64_key);\n    if (print_len < 1 || print_len >= *buffer_len)\n\treturn PJ_ETOOSMALL;\n\n    *buffer_len = print_len;\n\n    return PJ_SUCCESS;\n}\n\n/* Parse crypto attribute line */\nstatic pj_status_t parse_attr_crypto(pj_pool_t *pool,\n\t\t\t\t     const pjmedia_sdp_attr *attr,\n\t\t\t\t     pjmedia_srtp_crypto *crypto,\n\t\t\t\t     int *tag)\n{\n    pj_str_t input;\n    char *token;\n    pj_size_t token_len;\n    pj_str_t tmp;\n    pj_status_t status;\n    int itmp;\n\n    pj_bzero(crypto, sizeof(*crypto));\n    pj_strdup_with_null(pool, &input, &attr->value);\n\n    /* Tag */\n    token = strtok(input.ptr, \" \");\n    if (!token) {\n\tPJ_LOG(4,(THIS_FILE, \"Attribute crypto expecting tag\"));\n\treturn PJMEDIA_SDP_EINATTR;\n    }\n    token_len = pj_ansi_strlen(token);\n\n    /* Tag must not use leading zeroes. */\n    if (token_len > 1 && *token == '0')\n\treturn PJMEDIA_SDP_EINATTR;\n\n    /* Tag must be decimal, i.e: contains only digit '0'-'9'. */\n    for (itmp = 0; itmp < token_len; ++itmp)\n\tif (!pj_isdigit(token[itmp]))\n\t    return PJMEDIA_SDP_EINATTR;\n\n    /* Get tag value. */\n    *tag = atoi(token);\n\n    /* Crypto-suite */\n    token = strtok(NULL, \" \");\n    if (!token) {\n\tPJ_LOG(4,(THIS_FILE, \"Attribute crypto expecting crypto suite\"));\n\treturn PJMEDIA_SDP_EINATTR;\n    }\n    crypto->name = pj_str(token);\n\n    /* Key method */\n    token = strtok(NULL, \":\");\n    if (!token) {\n\tPJ_LOG(4,(THIS_FILE, \"Attribute crypto expecting key method\"));\n\treturn PJMEDIA_SDP_EINATTR;\n    }\n    if (pj_ansi_stricmp(token, \"inline\")) {\n\tPJ_LOG(4,(THIS_FILE, \"Attribute crypto key method '%s' not supported!\",\n\t          token));\n\treturn PJMEDIA_SDP_EINATTR;\n    }\n\n    /* Key */\n    token = strtok(NULL, \"| \");\n    if (!token) {\n\tPJ_LOG(4,(THIS_FILE, \"Attribute crypto expecting key\"));\n\treturn PJMEDIA_SDP_EINATTR;\n    }\n    tmp = pj_str(token);\n    if (PJ_BASE64_TO_BASE256_LEN(tmp.slen) > MAX_KEY_LEN) {\n\tPJ_LOG(4,(THIS_FILE, \"Key too long\"));\n\treturn PJMEDIA_SRTP_EINKEYLEN;\n    }\n\n    /* Decode key */\n    crypto->key.ptr = (char*) pj_pool_zalloc(pool, MAX_KEY_LEN);\n    itmp = MAX_KEY_LEN;\n    status = pj_base64_decode(&tmp, (pj_uint8_t*)crypto->key.ptr,\n\t\t\t      &itmp);\n    if (status != PJ_SUCCESS) {\n\tPJ_LOG(4,(THIS_FILE, \"Failed decoding crypto key from base64\"));\n\treturn status;\n    }\n    crypto->key.slen = itmp;\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t transport_media_create(pjmedia_transport *tp,\n\t\t\t\t          pj_pool_t *sdp_pool,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t          const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t\t  unsigned media_index)\n{\n    struct transport_srtp *srtp = (struct transport_srtp*) tp;\n    unsigned member_tp_option;\n\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    pj_bzero(&srtp->rx_policy_neg, sizeof(srtp->rx_policy_neg));\n    pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg));\n\n    srtp->media_option = options;\n    member_tp_option = options | PJMEDIA_TPMED_NO_TRANSPORT_CHECKING;\n\n    srtp->offerer_side = sdp_remote == NULL;\n\n    /* Validations */\n    if (srtp->offerer_side) {\n\n\tif (srtp->setting.use == PJMEDIA_SRTP_DISABLED)\n\t    goto BYPASS_SRTP;\n\n    } else {\n\n\tpjmedia_sdp_media *m_rem;\n\n\tm_rem = sdp_remote->media[media_index];\n\n\t/* Nothing to do on inactive media stream */\n\tif (pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL))\n\t    goto BYPASS_SRTP;\n\n\t/* Validate remote media transport based on SRTP usage option.\n\t */\n\tswitch (srtp->setting.use) {\n\t    case PJMEDIA_SRTP_DISABLED:\n\t\tif (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0)\n\t\t    return PJMEDIA_SRTP_ESDPINTRANSPORT;\n\t\tgoto BYPASS_SRTP;\n\t    case PJMEDIA_SRTP_OPTIONAL:\n\t\tbreak;\n\t    case PJMEDIA_SRTP_MANDATORY:\n\t\tif (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0)\n\t\t    return PJMEDIA_SRTP_ESDPINTRANSPORT;\n\t\tbreak;\n\t}\n\n    }\n    goto PROPAGATE_MEDIA_CREATE;\n\nBYPASS_SRTP:\n    srtp->bypass_srtp = PJ_TRUE;\n    member_tp_option &= ~PJMEDIA_TPMED_NO_TRANSPORT_CHECKING;\n\nPROPAGATE_MEDIA_CREATE:\n    return pjmedia_transport_media_create(srtp->member_tp, sdp_pool,\n\t\t\t\t\t  member_tp_option, sdp_remote,\n\t\t\t\t\t  media_index);\n}\n\nstatic pj_status_t transport_encode_sdp(pjmedia_transport *tp,\n\t\t\t\t\tpj_pool_t *sdp_pool,\n\t\t\t\t\tpjmedia_sdp_session *sdp_local,\n\t\t\t\t\tconst pjmedia_sdp_session *sdp_remote,\n\t\t\t\t\tunsigned media_index)\n{\n    struct transport_srtp *srtp = (struct transport_srtp*) tp;\n    pjmedia_sdp_media *m_rem, *m_loc;\n    enum { MAXLEN = 512 };\n    char buffer[MAXLEN];\n    int buffer_len;\n    pj_status_t status;\n    pjmedia_sdp_attr *attr;\n    pj_str_t attr_value;\n    unsigned i, j;\n\n    PJ_ASSERT_RETURN(tp && sdp_pool && sdp_local, PJ_EINVAL);\n\n    pj_bzero(&srtp->rx_policy_neg, sizeof(srtp->rx_policy_neg));\n    pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg));\n\n    srtp->offerer_side = sdp_remote == NULL;\n\n    m_rem = sdp_remote ? sdp_remote->media[media_index] : NULL;\n    m_loc = sdp_local->media[media_index];\n\n    /* Bypass if media transport is not RTP/AVP or RTP/SAVP */\n    if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP)  != 0 &&\n\tpj_stricmp(&m_loc->desc.transport, &ID_RTP_SAVP) != 0)\n\tgoto BYPASS_SRTP;\n\n    /* Do nothing if we are in bypass */\n    if (srtp->bypass_srtp)\n        goto BYPASS_SRTP;\n\n    /* If the media is inactive, do nothing. */\n    /* No, we still need to process SRTP offer/answer even if the media is\n     * marked as inactive, because the transport is still alive in this\n     * case (e.g. for keep-alive). See:\n     *   http://trac.pjsip.org/repos/ticket/1079\n     */\n    /*\n    if (pjmedia_sdp_media_find_attr(m_loc, &ID_INACTIVE, NULL) ||\n\t(m_rem && pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL)))\n\tgoto BYPASS_SRTP;\n    */\n\n    /* Check remote media transport & set local media transport\n     * based on SRTP usage option.\n     */\n    if (srtp->offerer_side) {\n\n\t/* Generate transport */\n\tswitch (srtp->setting.use) {\n\t    case PJMEDIA_SRTP_DISABLED:\n\t\tgoto BYPASS_SRTP;\n\t    case PJMEDIA_SRTP_OPTIONAL:\n\t\tm_loc->desc.transport =\n\t\t\t\t(srtp->peer_use == PJMEDIA_SRTP_MANDATORY)?\n\t\t\t\tID_RTP_SAVP : ID_RTP_AVP;\n\t\tbreak;\n\t    case PJMEDIA_SRTP_MANDATORY:\n\t\tm_loc->desc.transport = ID_RTP_SAVP;\n\t\tbreak;\n\t}\n\n\t/* Generate crypto attribute if not yet */\n\tif (pjmedia_sdp_media_find_attr(m_loc, &ID_CRYPTO, NULL) == NULL) {\n\t    /* Offer only current active crypto if any, otherwise offer all\n\t     * crypto-suites in the setting.\n\t     */\n\t    for (i=0; i<srtp->setting.crypto_count; ++i) {\n\t\tif (srtp->tx_policy.name.slen &&\n\t\t    pj_stricmp(&srtp->tx_policy.name,\n\t\t\t       &srtp->setting.crypto[i].name) != 0)\n\t\t{\n\t\t    continue;\n\t\t}\n\n\t\tbuffer_len = MAXLEN;\n\t\tstatus = generate_crypto_attr_value(srtp->pool, buffer, &buffer_len,\n\t\t\t\t\t\t    &srtp->setting.crypto[i],\n\t\t\t\t\t\t    i+1);\n\t\tif (status != PJ_SUCCESS)\n\t\t    return status;\n\n\t\t/* If buffer_len==0, just skip the crypto attribute. */\n\t\tif (buffer_len) {\n\t\t    pj_strset(&attr_value, buffer, buffer_len);\n\t\t    attr = pjmedia_sdp_attr_create(srtp->pool, ID_CRYPTO.ptr,\n\t\t\t\t\t\t   &attr_value);\n\t\t    m_loc->attr[m_loc->attr_count++] = attr;\n\t\t}\n\t    }\n\t}\n\n    } else {\n\t/* Answerer side */\n\n\tpj_assert(sdp_remote && m_rem);\n\n\t/* Generate transport */\n\tswitch (srtp->setting.use) {\n\t    case PJMEDIA_SRTP_DISABLED:\n\t\tif (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0)\n\t\t    return PJMEDIA_SRTP_ESDPINTRANSPORT;\n\t\tgoto BYPASS_SRTP;\n\t    case PJMEDIA_SRTP_OPTIONAL:\n\t\tm_loc->desc.transport = m_rem->desc.transport;\n\t\tbreak;\n\t    case PJMEDIA_SRTP_MANDATORY:\n\t\tif (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0)\n\t\t    return PJMEDIA_SRTP_ESDPINTRANSPORT;\n\t\tm_loc->desc.transport = ID_RTP_SAVP;\n\t\tbreak;\n\t}\n\n\t/* Generate crypto attribute if not yet */\n\tif (pjmedia_sdp_media_find_attr(m_loc, &ID_CRYPTO, NULL) == NULL) {\n\n\t    pjmedia_srtp_crypto tmp_rx_crypto;\n\t    pj_bool_t has_crypto_attr = PJ_FALSE;\n\t    int matched_idx = -1;\n\t    int chosen_tag = 0;\n\t    int tags[64]; /* assume no more than 64 crypto attrs in a media */\n\t    unsigned cr_attr_count = 0;\n\n\t    /* Find supported crypto-suite, get the tag, and assign policy_local */\n\t    for (i=0; i<m_rem->attr_count; ++i) {\n\t\tif (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0)\n\t\t    continue;\n\n\t\thas_crypto_attr = PJ_TRUE;\n\n\t\tstatus = parse_attr_crypto(srtp->pool, m_rem->attr[i],\n\t\t\t\t\t   &tmp_rx_crypto, &tags[cr_attr_count]);\n\t\tif (status != PJ_SUCCESS)\n\t\t    return status;\n\n\t\t/* Check duplicated tag */\n\t\tfor (j=0; j<cr_attr_count; ++j) {\n\t\t    if (tags[j] == tags[cr_attr_count]) {\n\t\t\tDEACTIVATE_MEDIA(sdp_pool, m_loc);\n\t\t\treturn PJMEDIA_SRTP_ESDPDUPCRYPTOTAG;\n\t\t    }\n\t\t}\n\n\t\tif (matched_idx == -1) {\n\t\t    /* lets see if the crypto-suite offered is supported */\n\t\t    for (j=0; j<srtp->setting.crypto_count; ++j)\n\t\t\tif (pj_stricmp(&tmp_rx_crypto.name,\n\t\t\t\t       &srtp->setting.crypto[j].name) == 0)\n\t\t\t{\n\t\t\t    int cs_idx = get_crypto_idx(&tmp_rx_crypto.name);\n\t\t\t    \n\t    \t\t    if (cs_idx == -1)\n\t    \t\t        return PJMEDIA_SRTP_ENOTSUPCRYPTO;\n\n\t\t\t    /* Force to use test key */\n\t\t\t    /* bad keys for snom: */\n\t\t\t    //char *hex_test_key = \"58b29c5c8f42308120ce857e439f2d\"\n\t\t\t    //\t\t     \"7810a8b10ad0b1446be5470faea496\";\n\t\t\t    //char *hex_test_key = \"20a26aac7ba062d356ff52b61e3993\"\n\t\t\t    //\t\t     \"ccb78078f12c64db94b9c294927fd0\";\n\t\t\t    //pj_str_t *test_key = &srtp->setting.crypto[j].key;\n\t\t\t    //char  *raw_test_key = pj_pool_zalloc(srtp->pool, 64);\n\t\t\t    //hex_string_to_octet_string(\n\t\t\t    //\t\traw_test_key,\n\t\t\t    //\t\thex_test_key,\n\t\t\t    //\t\tstrlen(hex_test_key));\n\t\t\t    //pj_strset(test_key, raw_test_key,\n\t\t\t    //\t  crypto_suites[cs_idx].cipher_key_len);\n\t\t\t    /* EO Force to use test key */\n\n\t\t\t    if (tmp_rx_crypto.key.slen !=\n\t\t\t\t(int)crypto_suites[cs_idx].cipher_key_len)\n\t\t\t\treturn PJMEDIA_SRTP_EINKEYLEN;\n\n\t\t\t    srtp->rx_policy_neg = tmp_rx_crypto;\n\t\t\t    chosen_tag = tags[cr_attr_count];\n\t\t\t    matched_idx = j;\n    \t\t\t    break;\n\t\t\t}\n\t\t}\n\t\tcr_attr_count++;\n\t    }\n\n\t    /* Check crypto negotiation result */\n\t    switch (srtp->setting.use) {\n\t\tcase PJMEDIA_SRTP_DISABLED:\n\t\t    pj_assert(!\"Should never reach here\");\n\t\t    break;\n\n\t\tcase PJMEDIA_SRTP_OPTIONAL:\n\t\t    /* bypass SRTP when no crypto-attr and remote uses RTP/AVP */\n\t\t    if (!has_crypto_attr &&\n\t\t\tpj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0)\n\t\t\tgoto BYPASS_SRTP;\n\t\t    /* bypass SRTP when nothing match and remote uses RTP/AVP */\n\t\t    else if (matched_idx == -1 &&\n\t\t\tpj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0)\n\t\t\tgoto BYPASS_SRTP;\n\t\t    break;\n\n\t\tcase PJMEDIA_SRTP_MANDATORY:\n\t\t    /* Do nothing, intentional */\n\t\t    break;\n\t    }\n\n\t    /* No crypto attr */\n\t    if (!has_crypto_attr) {\n\t\tDEACTIVATE_MEDIA(sdp_pool, m_loc);\n\t\treturn PJMEDIA_SRTP_ESDPREQCRYPTO;\n\t    }\n\n\t    /* No crypto match */\n\t    if (matched_idx == -1) {\n\t\tDEACTIVATE_MEDIA(sdp_pool, m_loc);\n\t\treturn PJMEDIA_SRTP_ENOTSUPCRYPTO;\n\t    }\n\n\t    /* we have to generate crypto answer,\n\t     * with srtp->tx_policy_neg matched the offer\n\t     * and rem_tag contains matched offer tag.\n\t     */\n\t    buffer_len = MAXLEN;\n\t    status = generate_crypto_attr_value(srtp->pool, buffer, &buffer_len,\n\t\t\t\t\t\t&srtp->setting.crypto[matched_idx],\n\t\t\t\t\t\tchosen_tag);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    srtp->tx_policy_neg = srtp->setting.crypto[matched_idx];\n\n\t    /* If buffer_len==0, just skip the crypto attribute. */\n\t    if (buffer_len) {\n\t\tpj_strset(&attr_value, buffer, buffer_len);\n\t\tattr = pjmedia_sdp_attr_create(sdp_pool, ID_CRYPTO.ptr,\n\t\t\t\t\t       &attr_value);\n\t\tm_loc->attr[m_loc->attr_count++] = attr;\n\t    }\n\n\t    /* At this point, we get valid rx_policy_neg & tx_policy_neg. */\n\t}\n\n    }\n    goto PROPAGATE_MEDIA_CREATE;\n\nBYPASS_SRTP:\n    /* Do not update this flag here as actually the media session hasn't been\n     * updated.\n     */\n    //srtp->bypass_srtp = PJ_TRUE;\n\nPROPAGATE_MEDIA_CREATE:\n    return pjmedia_transport_encode_sdp(srtp->member_tp, sdp_pool,\n\t\t\t\t\tsdp_local, sdp_remote, media_index);\n}\n\n\n\nstatic pj_status_t transport_media_start(pjmedia_transport *tp,\n\t\t\t\t         pj_pool_t *pool,\n\t\t\t\t         const pjmedia_sdp_session *sdp_local,\n\t\t\t\t         const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t         unsigned media_index)\n{\n    struct transport_srtp *srtp = (struct transport_srtp*) tp;\n    pjmedia_sdp_media *m_rem, *m_loc;\n    pj_status_t status;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(tp && pool && sdp_local && sdp_remote, PJ_EINVAL);\n\n    m_rem = sdp_remote->media[media_index];\n    m_loc = sdp_local->media[media_index];\n\n    if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0)\n\tsrtp->peer_use = PJMEDIA_SRTP_MANDATORY;\n    else\n\tsrtp->peer_use = PJMEDIA_SRTP_OPTIONAL;\n\n    /* For answerer side, this function will just have to start SRTP */\n\n    /* Check remote media transport & set local media transport\n     * based on SRTP usage option.\n     */\n    if (srtp->offerer_side) {\n\tif (srtp->setting.use == PJMEDIA_SRTP_DISABLED) {\n\t    if (pjmedia_sdp_media_find_attr(m_rem, &ID_CRYPTO, NULL)) {\n\t\tDEACTIVATE_MEDIA(pool, m_loc);\n\t\treturn PJMEDIA_SRTP_ESDPINCRYPTO;\n\t    }\n\t    goto BYPASS_SRTP;\n\t} else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) {\n\t    // Regardless the answer's transport type (RTP/AVP or RTP/SAVP),\n\t    // the answer must be processed through in optional mode.\n\t    // Please note that at this point transport type is ensured to be\n\t    // RTP/AVP or RTP/SAVP, see transport_media_create()\n\t    //if (pj_stricmp(&m_rem->desc.transport, &m_loc->desc.transport)) {\n\t\t//DEACTIVATE_MEDIA(pool, m_loc);\n\t\t//return PJMEDIA_SDP_EINPROTO;\n\t    //}\n\t} else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) {\n\t    if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP)) {\n\t\tDEACTIVATE_MEDIA(pool, m_loc);\n\t\treturn PJMEDIA_SDP_EINPROTO;\n\t    }\n\t}\n    }\n\n    if (srtp->offerer_side) {\n\t/* find supported crypto-suite, get the tag, and assign policy_local */\n\tpjmedia_srtp_crypto tmp_tx_crypto;\n\tpj_bool_t has_crypto_attr = PJ_FALSE;\n\tint rem_tag;\n\n\tfor (i=0; i<m_rem->attr_count; ++i) {\n\t    if (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0)\n\t\tcontinue;\n\n\t    /* more than one crypto attribute in media answer */\n\t    if (has_crypto_attr) {\n\t\tDEACTIVATE_MEDIA(pool, m_loc);\n\t\treturn PJMEDIA_SRTP_ESDPAMBIGUEANS;\n\t    }\n\n\t    has_crypto_attr = PJ_TRUE;\n\n\t    status = parse_attr_crypto(srtp->pool, m_rem->attr[i],\n\t\t\t\t       &tmp_tx_crypto, &rem_tag);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\n\t    /* our offer tag is always ordered by setting */\n\t    if (rem_tag < 1 || rem_tag > (int)srtp->setting.crypto_count) {\n\t\tDEACTIVATE_MEDIA(pool, m_loc);\n\t\treturn PJMEDIA_SRTP_ESDPINCRYPTOTAG;\n\t    }\n\n\t    /* match the crypto name */\n\t    if (pj_stricmp(&tmp_tx_crypto.name,\n\t\t&srtp->setting.crypto[rem_tag-1].name) != 0)\n\t    {\n\t\tDEACTIVATE_MEDIA(pool, m_loc);\n\t\treturn PJMEDIA_SRTP_ECRYPTONOTMATCH;\n\t    }\n\n\t    srtp->tx_policy_neg = srtp->setting.crypto[rem_tag-1];\n\t    srtp->rx_policy_neg = tmp_tx_crypto;\n\t}\n\n\tif (srtp->setting.use == PJMEDIA_SRTP_DISABLED) {\n\t    /* should never reach here */\n\t    goto BYPASS_SRTP;\n\t} else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) {\n\t    if (!has_crypto_attr)\n\t\tgoto BYPASS_SRTP;\n\t} else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) {\n\t    if (!has_crypto_attr) {\n\t\tDEACTIVATE_MEDIA(pool, m_loc);\n\t\treturn PJMEDIA_SRTP_ESDPREQCRYPTO;\n\t    }\n\t}\n\n\t/* At this point, we get valid rx_policy_neg & tx_policy_neg. */\n    }\n\n    /* Make sure we have the SRTP policies */\n    if (srtp_crypto_empty(&srtp->tx_policy_neg) ||\n\tsrtp_crypto_empty(&srtp->rx_policy_neg))\n    {\n\tgoto BYPASS_SRTP;\n    }\n\n    /* Reset probation counts */\n    srtp->probation_cnt = PROBATION_CNT_INIT;\n\n    /* Got policy_local & policy_remote, let's initalize the SRTP */\n\n    /* Ticket #1075: media_start() is called whenever media description\n     * gets updated, e.g: call hold, however we should restart SRTP only\n     * when the SRTP policy settings are updated.\n     */\n    if (srtp_crypto_cmp(&srtp->tx_policy_neg, &srtp->tx_policy) ||\n\tsrtp_crypto_cmp(&srtp->rx_policy_neg, &srtp->rx_policy))\n    {\n\tstatus = pjmedia_transport_srtp_start(tp,\n\t\t\t\t\t      &srtp->tx_policy_neg,\n\t\t\t\t\t      &srtp->rx_policy_neg);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    srtp->bypass_srtp = PJ_FALSE;\n\n    goto PROPAGATE_MEDIA_START;\n\nBYPASS_SRTP:\n    srtp->bypass_srtp = PJ_TRUE;\n    srtp->peer_use = PJMEDIA_SRTP_DISABLED;\n    if (srtp->session_inited) {\n\tpjmedia_transport_srtp_stop(tp);\n    }\n\nPROPAGATE_MEDIA_START:\n    return pjmedia_transport_media_start(srtp->member_tp, pool,\n\t\t\t\t\t sdp_local, sdp_remote,\n\t\t\t\t         media_index);\n}\n\nstatic pj_status_t transport_media_stop(pjmedia_transport *tp)\n{\n    struct transport_srtp *srtp = (struct transport_srtp*) tp;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    status = pjmedia_transport_media_stop(srtp->member_tp);\n    if (status != PJ_SUCCESS)\n\tPJ_LOG(4, (srtp->pool->obj_name,\n\t\t   \"SRTP failed stop underlying media transport.\"));\n\n    return pjmedia_transport_srtp_stop(tp);\n}\n\n/* Utility */\nPJ_DEF(pj_status_t) pjmedia_transport_srtp_decrypt_pkt(pjmedia_transport *tp,\n\t\t\t\t\t\t       pj_bool_t is_rtp,\n\t\t\t\t\t\t       void *pkt,\n\t\t\t\t\t\t       int *pkt_len)\n{\n    transport_srtp *srtp = (transport_srtp *)tp;\n    err_status_t err;\n\n    if (srtp->bypass_srtp)\n\treturn PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(tp && pkt && (*pkt_len>0), PJ_EINVAL);\n    PJ_ASSERT_RETURN(srtp->session_inited, PJ_EINVALIDOP);\n\n    /* Make sure buffer is 32bit aligned */\n    PJ_ASSERT_ON_FAIL( (((pj_ssize_t)pkt) & 0x03)==0, return PJ_EINVAL);\n\n    pj_lock_acquire(srtp->mutex);\n\n    if (!srtp->session_inited) {\n\tpj_lock_release(srtp->mutex);\n\treturn PJ_EINVALIDOP;\n    }\n\n    if (is_rtp)\n\terr = srtp_unprotect(srtp->srtp_rx_ctx, pkt, pkt_len);\n    else\n\terr = srtp_unprotect_rtcp(srtp->srtp_rx_ctx, pkt, pkt_len);\n\n    if (err != err_status_ok) {\n\tPJ_LOG(5,(srtp->pool->obj_name,\n\t\t  \"Failed to unprotect SRTP, pkt size=%d, err=%s\",\n\t\t  *pkt_len, get_libsrtp_errstr(err)));\n    }\n\n    pj_lock_release(srtp->mutex);\n\n    return (err==err_status_ok) ? PJ_SUCCESS : PJMEDIA_ERRNO_FROM_LIBSRTP(err);\n}\n\n#endif\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/transport_udp.c",
    "content": "/* $Id: transport_udp.c 4197 2012-07-05 07:26:29Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/transport_udp.h>\n#include <pj/addr_resolv.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/ioqueue.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n\n\n/* Maximum size of incoming RTP packet */\n#define RTP_LEN\t    PJMEDIA_MAX_MRU\n\n/* Maximum size of incoming RTCP packet */\n#define RTCP_LEN    600\n\n/* Maximum pending write operations */\n#define MAX_PENDING 4\n\nstatic const pj_str_t ID_RTP_AVP  = { \"RTP/AVP\", 7 };\n\n/* Pending write buffer */\ntypedef struct pending_write\n{\n    char\t\tbuffer[PJMEDIA_MAX_MTU];\n    pj_ioqueue_op_key_t\top_key;\n} pending_write;\n\n\nstruct transport_udp\n{\n    pjmedia_transport\tbase;\t\t/**< Base transport.\t\t    */\n\n    pj_pool_t\t       *pool;\t\t/**< Memory pool\t\t    */\n    unsigned\t\toptions;\t/**< Transport options.\t\t    */\n    unsigned\t\tmedia_options;\t/**< Transport media options.\t    */\n    void\t       *user_data;\t/**< Only valid when attached\t    */\n    pj_bool_t\t\tattached;\t/**< Has attachment?\t\t    */\n    pj_sockaddr\t\trem_rtp_addr;\t/**< Remote RTP address\t\t    */\n    pj_sockaddr\t\trem_rtcp_addr;\t/**< Remote RTCP address\t    */\n    int\t\t\taddr_len;\t/**< Length of addresses.\t    */\n    void  (*rtp_cb)(\tvoid*,\t\t/**< To report incoming RTP.\t    */\n\t\t\tvoid*,\n\t\t\tpj_ssize_t);\n    void  (*rtcp_cb)(\tvoid*,\t\t/**< To report incoming RTCP.\t    */\n\t\t\tvoid*,\n\t\t\tpj_ssize_t);\n\n    unsigned\t\ttx_drop_pct;\t/**< Percent of tx pkts to drop.    */\n    unsigned\t\trx_drop_pct;\t/**< Percent of rx pkts to drop.    */\n\n    pj_sock_t\t        rtp_sock;\t/**< RTP socket\t\t\t    */\n    pj_sockaddr\t\trtp_addr_name;\t/**< Published RTP address.\t    */\n    pj_ioqueue_key_t   *rtp_key;\t/**< RTP socket key in ioqueue\t    */\n    pj_ioqueue_op_key_t\trtp_read_op;\t/**< Pending read operation\t    */\n    unsigned\t\trtp_write_op_id;/**< Next write_op to use\t    */\n    pending_write\trtp_pending_write[MAX_PENDING];  /**< Pending write */\n    pj_sockaddr\t\trtp_src_addr;\t/**< Actual packet src addr.\t    */\n    unsigned\t\trtp_src_cnt;\t/**< How many pkt from this addr.   */\n    int\t\t\trtp_addrlen;\t/**< Address length.\t\t    */\n    char\t\trtp_pkt[RTP_LEN];/**< Incoming RTP packet buffer    */\n\n    pj_sock_t\t\trtcp_sock;\t/**< RTCP socket\t\t    */\n    pj_sockaddr\t\trtcp_addr_name;\t/**< Published RTCP address.\t    */\n    pj_sockaddr\t\trtcp_src_addr;\t/**< Actual source RTCP address.    */\n    unsigned\t\trtcp_src_cnt;\t/**< How many pkt from this addr.   */\n    int\t\t\trtcp_addr_len;\t/**< Length of RTCP src address.    */\n    pj_ioqueue_key_t   *rtcp_key;\t/**< RTCP socket key in ioqueue\t    */\n    pj_ioqueue_op_key_t rtcp_read_op;\t/**< Pending read operation\t    */\n    pj_ioqueue_op_key_t rtcp_write_op;\t/**< Pending write operation\t    */\n    char\t\trtcp_pkt[RTCP_LEN];/**< Incoming RTCP packet buffer */\n};\n\n\n\nstatic void on_rx_rtp( pj_ioqueue_key_t *key, \n                       pj_ioqueue_op_key_t *op_key, \n                       pj_ssize_t bytes_read);\nstatic void on_rx_rtcp(pj_ioqueue_key_t *key, \n                       pj_ioqueue_op_key_t *op_key, \n                       pj_ssize_t bytes_read);\n\n/*\n * These are media transport operations.\n */\nstatic pj_status_t transport_get_info (pjmedia_transport *tp,\n\t\t\t\t       pjmedia_transport_info *info);\nstatic pj_status_t transport_attach   (pjmedia_transport *tp,\n\t\t\t\t       void *user_data,\n\t\t\t\t       const pj_sockaddr_t *rem_addr,\n\t\t\t\t       const pj_sockaddr_t *rem_rtcp,\n\t\t\t\t       unsigned addr_len,\n\t\t\t\t       void (*rtp_cb)(void*,\n\t\t\t\t\t\t      void*,\n\t\t\t\t\t\t      pj_ssize_t),\n\t\t\t\t       void (*rtcp_cb)(void*,\n\t\t\t\t\t\t       void*,\n\t\t\t\t\t\t       pj_ssize_t));\nstatic void\t   transport_detach   (pjmedia_transport *tp,\n\t\t\t\t       void *strm);\nstatic pj_status_t transport_send_rtp( pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_send_rtcp(pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_send_rtcp2(pjmedia_transport *tp,\n\t\t\t\t       const pj_sockaddr_t *addr,\n\t\t\t\t       unsigned addr_len,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size);\nstatic pj_status_t transport_media_create(pjmedia_transport *tp,\n\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t       unsigned options,\n\t\t\t\t       const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t       unsigned media_index);\nstatic pj_status_t transport_encode_sdp(pjmedia_transport *tp,\n\t\t\t\t        pj_pool_t *pool,\n\t\t\t\t        pjmedia_sdp_session *sdp_local,\n\t\t\t\t        const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t        unsigned media_index);\nstatic pj_status_t transport_media_start (pjmedia_transport *tp,\n\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t       const pjmedia_sdp_session *sdp_local,\n\t\t\t\t       const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t       unsigned media_index);\nstatic pj_status_t transport_media_stop(pjmedia_transport *tp);\nstatic pj_status_t transport_simulate_lost(pjmedia_transport *tp,\n\t\t\t\t       pjmedia_dir dir,\n\t\t\t\t       unsigned pct_lost);\nstatic pj_status_t transport_destroy  (pjmedia_transport *tp);\n\n\nstatic pjmedia_transport_op transport_udp_op = \n{\n    &transport_get_info,\n    &transport_attach,\n    &transport_detach,\n    &transport_send_rtp,\n    &transport_send_rtcp,\n    &transport_send_rtcp2,\n    &transport_media_create,\n    &transport_encode_sdp,\n    &transport_media_start,\n    &transport_media_stop,\n    &transport_simulate_lost,\n    &transport_destroy\n};\n\n\n/**\n * Create UDP stream transport.\n */\nPJ_DEF(pj_status_t) pjmedia_transport_udp_create( pjmedia_endpt *endpt,\n\t\t\t\t\t\t  const char *name,\n\t\t\t\t\t\t  int port,\n\t\t\t\t\t\t  unsigned options,\n\t\t\t\t\t\t  pjmedia_transport **p_tp)\n{\n    return pjmedia_transport_udp_create2(endpt, name, NULL, port, options, \n\t\t\t\t\tp_tp);\n}\n\n/**\n * Create UDP stream transport.\n */\nPJ_DEF(pj_status_t) pjmedia_transport_udp_create2(pjmedia_endpt *endpt,\n\t\t\t\t\t\t  const char *name,\n\t\t\t\t\t\t  const pj_str_t *addr,\n\t\t\t\t\t\t  int port,\n\t\t\t\t\t\t  unsigned options,\n\t\t\t\t\t\t  pjmedia_transport **p_tp)\n{\n    return pjmedia_transport_udp_create3(endpt, pj_AF_INET(), name,\n\t\t\t\t\t addr, port, options, p_tp);\n}\n\n/**\n * Create UDP stream transport.\n */\nPJ_DEF(pj_status_t) pjmedia_transport_udp_create3(pjmedia_endpt *endpt,\n\t\t\t\t\t\t  int af,\n\t\t\t\t\t\t  const char *name,\n\t\t\t\t\t\t  const pj_str_t *addr,\n\t\t\t\t\t\t  int port,\n\t\t\t\t\t\t  unsigned options,\n\t\t\t\t\t\t  pjmedia_transport **p_tp)\n{\n    pjmedia_sock_info si;\n    pj_status_t status;\n\n    \n    /* Sanity check */\n    PJ_ASSERT_RETURN(endpt && port && p_tp, PJ_EINVAL);\n\n\n    pj_bzero(&si, sizeof(pjmedia_sock_info));\n    si.rtp_sock = si.rtcp_sock = PJ_INVALID_SOCKET;\n\n    /* Create RTP socket */\n    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &si.rtp_sock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Bind RTP socket */\n    status = pj_sockaddr_init(af, &si.rtp_addr_name, addr, (pj_uint16_t)port);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    status = pj_sock_bind(si.rtp_sock, &si.rtp_addr_name, \n\t\t\t  pj_sockaddr_get_len(&si.rtp_addr_name));\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n\n    /* Create RTCP socket */\n    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &si.rtcp_sock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Bind RTCP socket */\n    status = pj_sockaddr_init(af, &si.rtcp_addr_name, addr, \n\t\t\t      (pj_uint16_t)(port+1));\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    status = pj_sock_bind(si.rtcp_sock, &si.rtcp_addr_name,\n\t\t\t  pj_sockaddr_get_len(&si.rtcp_addr_name));\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    \n    /* Create UDP transport by attaching socket info */\n    return pjmedia_transport_udp_attach( endpt, name, &si, options, p_tp);\n\n\non_error:\n    if (si.rtp_sock != PJ_INVALID_SOCKET)\n\tpj_sock_close(si.rtp_sock);\n    if (si.rtcp_sock != PJ_INVALID_SOCKET)\n\tpj_sock_close(si.rtcp_sock);\n    return status;\n}\n\n\n/**\n * Create UDP stream transport from existing socket info.\n */\nPJ_DEF(pj_status_t) pjmedia_transport_udp_attach( pjmedia_endpt *endpt,\n\t\t\t\t\t\t  const char *name,\n\t\t\t\t\t\t  const pjmedia_sock_info *si,\n\t\t\t\t\t\t  unsigned options,\n\t\t\t\t\t\t  pjmedia_transport **p_tp)\n{\n    struct transport_udp *tp;\n    pj_pool_t *pool;\n    pj_ioqueue_t *ioqueue;\n    pj_ioqueue_callback rtp_cb, rtcp_cb;\n    pj_ssize_t size;\n    unsigned i;\n    pj_status_t status;\n\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(endpt && si && p_tp, PJ_EINVAL);\n\n    /* Get ioqueue instance */\n    ioqueue = pjmedia_endpt_get_ioqueue(endpt);\n\n    if (name==NULL)\n\tname = \"udp%p\";\n\n    /* Create transport structure */\n    pool = pjmedia_endpt_create_pool(endpt, name, 512, 512);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    tp = PJ_POOL_ZALLOC_T(pool, struct transport_udp);\n    tp->pool = pool;\n    tp->options = options;\n    pj_memcpy(tp->base.name, pool->obj_name, PJ_MAX_OBJ_NAME);\n    tp->base.op = &transport_udp_op;\n    tp->base.type = PJMEDIA_TRANSPORT_TYPE_UDP;\n\n    /* Copy socket infos */\n    tp->rtp_sock = si->rtp_sock;\n    tp->rtp_addr_name = si->rtp_addr_name;\n    tp->rtcp_sock = si->rtcp_sock;\n    tp->rtcp_addr_name = si->rtcp_addr_name;\n\n    /* If address is 0.0.0.0, use host's IP address */\n    if (!pj_sockaddr_has_addr(&tp->rtp_addr_name)) {\n\tpj_sockaddr hostip;\n\n\tstatus = pj_gethostip(tp->rtp_addr_name.addr.sa_family, &hostip);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n\tpj_memcpy(pj_sockaddr_get_addr(&tp->rtp_addr_name), \n\t\t  pj_sockaddr_get_addr(&hostip),\n\t\t  pj_sockaddr_get_addr_len(&hostip));\n    }\n\n    /* Same with RTCP */\n    if (!pj_sockaddr_has_addr(&tp->rtcp_addr_name)) {\n\tpj_memcpy(pj_sockaddr_get_addr(&tp->rtcp_addr_name),\n\t\t  pj_sockaddr_get_addr(&tp->rtp_addr_name),\n\t\t  pj_sockaddr_get_addr_len(&tp->rtp_addr_name));\n    }\n\n    /* Setup RTP socket with the ioqueue */\n    pj_bzero(&rtp_cb, sizeof(rtp_cb));\n    rtp_cb.on_read_complete = &on_rx_rtp;\n\n    status = pj_ioqueue_register_sock(pool, ioqueue, tp->rtp_sock, tp,\n\t\t\t\t      &rtp_cb, &tp->rtp_key);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n    \n    /* Disallow concurrency so that detach() and destroy() are\n     * synchronized with the callback.\n     */\n    status = pj_ioqueue_set_concurrency(tp->rtp_key, PJ_FALSE);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    pj_ioqueue_op_key_init(&tp->rtp_read_op, sizeof(tp->rtp_read_op));\n    for (i=0; i<PJ_ARRAY_SIZE(tp->rtp_pending_write); ++i)\n\tpj_ioqueue_op_key_init(&tp->rtp_pending_write[i].op_key, \n\t\t\t       sizeof(tp->rtp_pending_write[i].op_key));\n\n    /* Kick of pending RTP read from the ioqueue */\n    tp->rtp_addrlen = sizeof(tp->rtp_src_addr);\n    size = sizeof(tp->rtp_pkt);\n    status = pj_ioqueue_recvfrom(tp->rtp_key, &tp->rtp_read_op,\n\t\t\t         tp->rtp_pkt, &size, PJ_IOQUEUE_ALWAYS_ASYNC,\n\t\t\t\t &tp->rtp_src_addr, &tp->rtp_addrlen);\n    if (status != PJ_EPENDING)\n\tgoto on_error;\n\n\n    /* Setup RTCP socket with ioqueue */\n    pj_bzero(&rtcp_cb, sizeof(rtcp_cb));\n    rtcp_cb.on_read_complete = &on_rx_rtcp;\n\n    status = pj_ioqueue_register_sock(pool, ioqueue, tp->rtcp_sock, tp,\n\t\t\t\t      &rtcp_cb, &tp->rtcp_key);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    status = pj_ioqueue_set_concurrency(tp->rtcp_key, PJ_FALSE);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    pj_ioqueue_op_key_init(&tp->rtcp_read_op, sizeof(tp->rtcp_read_op));\n    pj_ioqueue_op_key_init(&tp->rtcp_write_op, sizeof(tp->rtcp_write_op));\n\n\n    /* Kick of pending RTCP read from the ioqueue */\n    size = sizeof(tp->rtcp_pkt);\n    tp->rtcp_addr_len = sizeof(tp->rtcp_src_addr);\n    status = pj_ioqueue_recvfrom( tp->rtcp_key, &tp->rtcp_read_op,\n\t\t\t\t  tp->rtcp_pkt, &size, PJ_IOQUEUE_ALWAYS_ASYNC,\n\t\t\t\t  &tp->rtcp_src_addr, &tp->rtcp_addr_len);\n    if (status != PJ_EPENDING)\n\tgoto on_error;\n\n\n    /* Done */\n    *p_tp = &tp->base;\n    return PJ_SUCCESS;\n\n\non_error:\n    transport_destroy(&tp->base);\n    return status;\n}\n\n\n/**\n * Close UDP transport.\n */\nstatic pj_status_t transport_destroy(pjmedia_transport *tp)\n{\n    struct transport_udp *udp = (struct transport_udp*) tp;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    /* Must not close while application is using this */\n    //PJ_ASSERT_RETURN(!udp->attached, PJ_EINVALIDOP);\n    \n\n    if (udp->rtp_key) {\n\t/* This will block the execution if callback is still\n\t * being called.\n\t */\n\tpj_ioqueue_unregister(udp->rtp_key);\n\tudp->rtp_key = NULL;\n\tudp->rtp_sock = PJ_INVALID_SOCKET;\n    } else if (udp->rtp_sock != PJ_INVALID_SOCKET) {\n\tpj_sock_close(udp->rtp_sock);\n\tudp->rtp_sock = PJ_INVALID_SOCKET;\n    }\n\n    if (udp->rtcp_key) {\n\tpj_ioqueue_unregister(udp->rtcp_key);\n\tudp->rtcp_key = NULL;\n\tudp->rtcp_sock = PJ_INVALID_SOCKET;\n    } else if (udp->rtcp_sock != PJ_INVALID_SOCKET) {\n\tpj_sock_close(udp->rtcp_sock);\n\tudp->rtcp_sock = PJ_INVALID_SOCKET;\n    }\n\n    pj_pool_release(udp->pool);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Notification from ioqueue about incoming RTP packet */\nstatic void on_rx_rtp( pj_ioqueue_key_t *key, \n                       pj_ioqueue_op_key_t *op_key, \n                       pj_ssize_t bytes_read)\n{\n    struct transport_udp *udp;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(op_key);\n\n    udp = (struct transport_udp*) pj_ioqueue_get_user_data(key);\n\n    do {\n\tvoid (*cb)(void*,void*,pj_ssize_t);\n\tvoid *user_data;\n\tpj_bool_t discard = PJ_FALSE;\n\n\tcb = udp->rtp_cb;\n\tuser_data = udp->user_data;\n\n\t/* Simulate packet lost on RX direction */\n\tif (udp->rx_drop_pct) {\n\t    if ((pj_rand() % 100) <= (int)udp->rx_drop_pct) {\n\t\tPJ_LOG(5,(udp->base.name, \n\t\t\t  \"RX RTP packet dropped because of pkt lost \"\n\t\t\t  \"simulation\"));\n\t\tdiscard = PJ_TRUE;\n\t    }\n\t}\n\n\t/* See if source address of RTP packet is different than the \n\t * configured address, and switch RTP remote address to \n\t * source packet address after several consecutive packets\n\t * have been received.\n\t */\n\tif (bytes_read>0 && \n\t    (udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0) \n\t{\n\t    if (pj_sockaddr_cmp(&udp->rem_rtp_addr, &udp->rtp_src_addr) == 0) {\n\t\t/* We're still receiving from rem_rtp_addr. Don't switch. */\n\t\tudp->rtp_src_cnt = 0;\n\t    } else {\n\t\tudp->rtp_src_cnt++;\n\n\t\tif (udp->rtp_src_cnt < PJMEDIA_RTP_NAT_PROBATION_CNT) {\n\t\t    discard = PJ_TRUE;\n\t\t} else {\n\t\t\n\t\t    char addr_text[80];\n\n\t\t    /* Set remote RTP address to source address */\n\t\t    pj_memcpy(&udp->rem_rtp_addr, &udp->rtp_src_addr,\n\t\t\t      sizeof(pj_sockaddr));\n\n\t\t    /* Reset counter */\n\t\t    udp->rtp_src_cnt = 0;\n\n\t\t    PJ_LOG(4,(udp->base.name,\n\t\t\t      \"Remote RTP address switched to %s\",\n\t\t\t      pj_sockaddr_print(&udp->rtp_src_addr, addr_text,\n\t\t\t\t\t\tsizeof(addr_text), 3)));\n\n\t\t    /* Also update remote RTCP address if actual RTCP source\n\t\t     * address is not heard yet.\n\t\t     */\n\t\t    if (!pj_sockaddr_has_addr(&udp->rtcp_src_addr)) {\n\t\t\tpj_uint16_t port;\n\n\t\t\tpj_memcpy(&udp->rem_rtcp_addr, &udp->rem_rtp_addr, \n\t\t\t\t  sizeof(pj_sockaddr));\n\t\t\tpj_sockaddr_copy_addr(&udp->rem_rtcp_addr,\n\t\t\t\t\t      &udp->rem_rtp_addr);\n\t\t\tport = (pj_uint16_t)\n\t\t\t       (pj_sockaddr_get_port(&udp->rem_rtp_addr)+1);\n\t\t\tpj_sockaddr_set_port(&udp->rem_rtcp_addr, port);\n\n\t\t\tpj_memcpy(&udp->rtcp_src_addr, &udp->rem_rtcp_addr, \n\t\t\t\t  sizeof(pj_sockaddr));\n\n\t\t\tPJ_LOG(4,(udp->base.name,\n\t\t\t\t  \"Remote RTCP address switched to predicted\"\n\t\t\t\t  \" address %s\",\n\t\t\t\t  pj_sockaddr_print(&udp->rtcp_src_addr, \n\t\t\t\t\t\t    addr_text,\n\t\t\t\t\t\t    sizeof(addr_text), 3)));\n\n\t\t    }\n\t\t}\n\t    }\n\t}\n\n\tif (!discard && udp->attached && cb)\n\t    (*cb)(user_data, udp->rtp_pkt, bytes_read);\n\n\tbytes_read = sizeof(udp->rtp_pkt);\n\tudp->rtp_addrlen = sizeof(udp->rtp_src_addr);\n\tstatus = pj_ioqueue_recvfrom(udp->rtp_key, &udp->rtp_read_op,\n\t\t\t\t     udp->rtp_pkt, &bytes_read, 0,\n\t\t\t\t     &udp->rtp_src_addr, \n\t\t\t\t     &udp->rtp_addrlen);\n\n\tif (status != PJ_EPENDING && status != PJ_SUCCESS)\n\t    bytes_read = -status;\n\n    } while (status != PJ_EPENDING && status != PJ_ECANCELLED);\n}\n\n\n/* Notification from ioqueue about incoming RTCP packet */\nstatic void on_rx_rtcp(pj_ioqueue_key_t *key, \n                       pj_ioqueue_op_key_t *op_key, \n                       pj_ssize_t bytes_read)\n{\n    struct transport_udp *udp;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(op_key);\n\n    udp = (struct transport_udp*) pj_ioqueue_get_user_data(key);\n\n    do {\n\tvoid (*cb)(void*,void*,pj_ssize_t);\n\tvoid *user_data;\n\n\tcb = udp->rtcp_cb;\n\tuser_data = udp->user_data;\n\n\tif (udp->attached && cb)\n\t    (*cb)(user_data, udp->rtcp_pkt, bytes_read);\n\n\t/* Check if RTCP source address is the same as the configured\n\t * remote address, and switch the address when they are\n\t * different.\n\t */\n\tif (bytes_read>0 &&\n\t    (udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0)\n\t{\n\t    if (pj_sockaddr_cmp(&udp->rem_rtcp_addr, &udp->rtcp_src_addr) == 0) {\n\t\t/* Still receiving from rem_rtcp_addr, don't switch */\n\t\tudp->rtcp_src_cnt = 0;\n\t    } else {\n\t\t++udp->rtcp_src_cnt;\n\n\t\tif (udp->rtcp_src_cnt >= PJMEDIA_RTCP_NAT_PROBATION_CNT\t) {\n\t\t    char addr_text[80];\n\n\t\t    udp->rtcp_src_cnt = 0;\n\t\t    pj_memcpy(&udp->rem_rtcp_addr, &udp->rtcp_src_addr,\n\t\t\t      sizeof(pj_sockaddr));\n\n\t\t    PJ_LOG(4,(udp->base.name,\n\t\t\t      \"Remote RTCP address switched to %s\",\n\t\t\t      pj_sockaddr_print(&udp->rtcp_src_addr, addr_text,\n\t\t\t\t\t\tsizeof(addr_text), 3)));\n\t\t}\n\t    }\n\t}\n\n\tbytes_read = sizeof(udp->rtcp_pkt);\n\tudp->rtcp_addr_len = sizeof(udp->rtcp_src_addr);\n\tstatus = pj_ioqueue_recvfrom(udp->rtcp_key, &udp->rtcp_read_op,\n\t\t\t\t     udp->rtcp_pkt, &bytes_read, 0,\n\t\t\t\t     &udp->rtcp_src_addr, \n\t\t\t\t     &udp->rtcp_addr_len);\n\tif (status != PJ_EPENDING && status != PJ_SUCCESS)\n\t    bytes_read = -status;\n\n    } while (status != PJ_EPENDING && status != PJ_ECANCELLED);\n}\n\n\n/* Called to get the transport info */\nstatic pj_status_t transport_get_info(pjmedia_transport *tp,\n\t\t\t\t      pjmedia_transport_info *info)\n{\n    struct transport_udp *udp = (struct transport_udp*)tp;\n    PJ_ASSERT_RETURN(tp && info, PJ_EINVAL);\n\n    info->sock_info.rtp_sock = udp->rtp_sock;\n    info->sock_info.rtp_addr_name = udp->rtp_addr_name;\n    info->sock_info.rtcp_sock = udp->rtcp_sock;\n    info->sock_info.rtcp_addr_name = udp->rtcp_addr_name;\n\n    /* Get remote address originating RTP & RTCP. */\n    info->src_rtp_name  = udp->rtp_src_addr;\n    info->src_rtcp_name = udp->rtcp_src_addr;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Called by application to initialize the transport */\nstatic pj_status_t transport_attach(   pjmedia_transport *tp,\n\t\t\t\t       void *user_data,\n\t\t\t\t       const pj_sockaddr_t *rem_addr,\n\t\t\t\t       const pj_sockaddr_t *rem_rtcp,\n\t\t\t\t       unsigned addr_len,\n\t\t\t\t       void (*rtp_cb)(void*,\n\t\t\t\t\t\t      void*,\n\t\t\t\t\t\t      pj_ssize_t),\n\t\t\t\t       void (*rtcp_cb)(void*,\n\t\t\t\t\t\t       void*,\n\t\t\t\t\t\t       pj_ssize_t))\n{\n    struct transport_udp *udp = (struct transport_udp*) tp;\n    const pj_sockaddr *rtcp_addr;\n\n    /* Validate arguments */\n    PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL);\n\n    /* Must not be \"attached\" to existing application */\n    PJ_ASSERT_RETURN(!udp->attached, PJ_EINVALIDOP);\n\n    /* Lock the ioqueue keys to make sure that callbacks are\n     * not executed. See ticket #844 for details.\n     */\n    pj_ioqueue_lock_key(udp->rtp_key);\n    pj_ioqueue_lock_key(udp->rtcp_key);\n\n    /* \"Attach\" the application: */\n\n    /* Copy remote RTP address */\n    pj_memcpy(&udp->rem_rtp_addr, rem_addr, addr_len);\n\n    /* Copy remote RTP address, if one is specified. */\n    rtcp_addr = (const pj_sockaddr*) rem_rtcp;\n    if (rtcp_addr && pj_sockaddr_has_addr(rtcp_addr)) {\n\tpj_memcpy(&udp->rem_rtcp_addr, rem_rtcp, addr_len);\n\n    } else {\n\tunsigned rtcp_port;\n\n\t/* Otherwise guess the RTCP address from the RTP address */\n\tpj_memcpy(&udp->rem_rtcp_addr, rem_addr, addr_len);\n\trtcp_port = pj_sockaddr_get_port(&udp->rem_rtp_addr) + 1;\n\tpj_sockaddr_set_port(&udp->rem_rtcp_addr, (pj_uint16_t)rtcp_port);\n    }\n\n    /* Save the callbacks */\n    udp->rtp_cb = rtp_cb;\n    udp->rtcp_cb = rtcp_cb;\n    udp->user_data = user_data;\n\n    /* Save address length */\n    udp->addr_len = addr_len;\n\n    /* Last, mark transport as attached */\n    udp->attached = PJ_TRUE;\n\n    /* Reset source RTP & RTCP addresses and counter */\n    pj_bzero(&udp->rtp_src_addr, sizeof(udp->rtp_src_addr));\n    pj_bzero(&udp->rtcp_src_addr, sizeof(udp->rtcp_src_addr));\n    udp->rtp_src_cnt = 0;\n    udp->rtcp_src_cnt = 0;\n\n    /* Set buffer size for RTP socket */\n#if PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE\n    {\n\tunsigned sobuf_size = PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE;\n\tpj_status_t status;\n\tstatus = pj_sock_setsockopt_sobuf(udp->rtp_sock, pj_SO_RCVBUF(),\n\t\t\t\t\t  PJ_TRUE, &sobuf_size);\n\tif (status != PJ_SUCCESS) {\n\t    pj_perror(3, tp->name, status, \"Failed setting SO_RCVBUF\");\n\t} else {\n\t    if (sobuf_size < PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE) {\n\t\tPJ_LOG(4, (tp->name, \n\t\t\t   \"Warning! Cannot set SO_RCVBUF as configured, \"\n\t\t\t   \"now=%d, configured=%d\",\n\t\t\t   sobuf_size, PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE));\n\t    } else {\n\t\tPJ_LOG(5, (tp->name, \"SO_RCVBUF set to %d\", sobuf_size));\n\t    }\n\t}\n    }\n#endif\n#if PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE\n    {\n\tunsigned sobuf_size = PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE;\n\tpj_status_t status;\n\tstatus = pj_sock_setsockopt_sobuf(udp->rtp_sock, pj_SO_SNDBUF(),\n\t\t\t\t\t  PJ_TRUE, &sobuf_size);\n\tif (status != PJ_SUCCESS) {\n\t    pj_perror(3, tp->name, status, \"Failed setting SO_SNDBUF\");\n\t} else {\n\t    if (sobuf_size < PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE) {\n\t\tPJ_LOG(4, (tp->name, \n\t\t\t   \"Warning! Cannot set SO_SNDBUF as configured, \"\n\t\t\t   \"now=%d, configured=%d\",\n\t\t\t   sobuf_size, PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE));\n\t    } else {\n\t\tPJ_LOG(5, (tp->name, \"SO_SNDBUF set to %d\", sobuf_size));\n\t    }\n\t}\n    }\n#endif\n\n    /* Unlock keys */\n    pj_ioqueue_unlock_key(udp->rtcp_key);\n    pj_ioqueue_unlock_key(udp->rtp_key);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Called by application when it no longer needs the transport */\nstatic void transport_detach( pjmedia_transport *tp,\n\t\t\t      void *user_data)\n{\n    struct transport_udp *udp = (struct transport_udp*) tp;\n\n    pj_assert(tp);\n\n    if (udp->attached) {\n\t/* Lock the ioqueue keys to make sure that callbacks are\n\t * not executed. See ticket #460 for details.\n\t */\n\tpj_ioqueue_lock_key(udp->rtp_key);\n\tpj_ioqueue_lock_key(udp->rtcp_key);\n\n\t/* User data is unreferenced on Release build */\n\tPJ_UNUSED_ARG(user_data);\n\n\t/* As additional checking, check if the same user data is specified */\n\tpj_assert(user_data == udp->user_data);\n\n\t/* First, mark transport as unattached */\n\tudp->attached = PJ_FALSE;\n\n\t/* Clear up application infos from transport */\n\tudp->rtp_cb = NULL;\n\tudp->rtcp_cb = NULL;\n\tudp->user_data = NULL;\n\n\t/* Unlock keys */\n\tpj_ioqueue_unlock_key(udp->rtcp_key);\n\tpj_ioqueue_unlock_key(udp->rtp_key);\n    }\n}\n\n\n/* Called by application to send RTP packet */\nstatic pj_status_t transport_send_rtp( pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size)\n{\n    struct transport_udp *udp = (struct transport_udp*)tp;\n    pj_ssize_t sent;\n    unsigned id;\n    struct pending_write *pw;\n    pj_status_t status;\n\n    /* Must be attached */\n    PJ_ASSERT_RETURN(udp->attached, PJ_EINVALIDOP);\n\n    /* Check that the size is supported */\n    PJ_ASSERT_RETURN(size <= PJMEDIA_MAX_MTU, PJ_ETOOBIG);\n\n    /* Simulate packet lost on TX direction */\n    if (udp->tx_drop_pct) {\n\tif ((pj_rand() % 100) <= (int)udp->tx_drop_pct) {\n\t    PJ_LOG(5,(udp->base.name, \n\t\t      \"TX RTP packet dropped because of pkt lost \"\n\t\t      \"simulation\"));\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n\n    id = udp->rtp_write_op_id;\n    pw = &udp->rtp_pending_write[id];\n\n    /* We need to copy packet to our buffer because when the\n     * operation is pending, caller might write something else\n     * to the original buffer.\n     */\n    pj_memcpy(pw->buffer, pkt, size);\n\n    sent = size;\n    status = pj_ioqueue_sendto( udp->rtp_key, \n\t\t\t\t&udp->rtp_pending_write[id].op_key,\n\t\t\t\tpw->buffer, &sent, 0,\n\t\t\t\t&udp->rem_rtp_addr, \n\t\t\t\tudp->addr_len);\n\n    udp->rtp_write_op_id = (udp->rtp_write_op_id + 1) %\n\t\t\t   PJ_ARRAY_SIZE(udp->rtp_pending_write);\n\n    if (status==PJ_SUCCESS || status==PJ_EPENDING)\n\treturn PJ_SUCCESS;\n\n    return status;\n}\n\n/* Called by application to send RTCP packet */\nstatic pj_status_t transport_send_rtcp(pjmedia_transport *tp,\n\t\t\t\t       const void *pkt,\n\t\t\t\t       pj_size_t size)\n{\n    return transport_send_rtcp2(tp, NULL, 0, pkt, size);\n}\n\n\n/* Called by application to send RTCP packet */\nstatic pj_status_t transport_send_rtcp2(pjmedia_transport *tp,\n\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\tunsigned addr_len,\n\t\t\t\t        const void *pkt,\n\t\t\t\t        pj_size_t size)\n{\n    struct transport_udp *udp = (struct transport_udp*)tp;\n    pj_ssize_t sent;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(udp->attached, PJ_EINVALIDOP);\n\n    if (addr == NULL) {\n\taddr = &udp->rem_rtcp_addr;\n\taddr_len = udp->addr_len;\n    }\n\n    sent = size;\n    status = pj_ioqueue_sendto( udp->rtcp_key, &udp->rtcp_write_op,\n\t\t\t\tpkt, &sent, 0, addr, addr_len);\n\n    if (status==PJ_SUCCESS || status==PJ_EPENDING)\n\treturn PJ_SUCCESS;\n\n    return status;\n}\n\n\nstatic pj_status_t transport_media_create(pjmedia_transport *tp,\n\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t  unsigned options,\n\t\t\t\t  const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t  unsigned media_index)\n{\n    struct transport_udp *udp = (struct transport_udp*)tp;\n\n    PJ_ASSERT_RETURN(tp && pool, PJ_EINVAL);\n    udp->media_options = options;\n\n    PJ_UNUSED_ARG(sdp_remote);\n    PJ_UNUSED_ARG(media_index);\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t transport_encode_sdp(pjmedia_transport *tp,\n\t\t\t\t        pj_pool_t *pool,\n\t\t\t\t        pjmedia_sdp_session *sdp_local,\n\t\t\t\t        const pjmedia_sdp_session *rem_sdp,\n\t\t\t\t        unsigned media_index)\n{\n    struct transport_udp *udp = (struct transport_udp*)tp;\n\n    /* Validate media transport */\n    /* By now, this transport only support RTP/AVP transport */\n    if ((udp->media_options & PJMEDIA_TPMED_NO_TRANSPORT_CHECKING) == 0) {\n\tpjmedia_sdp_media *m_rem, *m_loc;\n\n\tm_rem = rem_sdp? rem_sdp->media[media_index] : NULL;\n\tm_loc = sdp_local->media[media_index];\n\n\tif (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP) ||\n\t   (m_rem && pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP)))\n\t{\n\t    pjmedia_sdp_media_deactivate(pool, m_loc);\n\t    return PJMEDIA_SDP_EINPROTO;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t transport_media_start(pjmedia_transport *tp,\n\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t  const pjmedia_sdp_session *sdp_local,\n\t\t\t\t  const pjmedia_sdp_session *sdp_remote,\n\t\t\t\t  unsigned media_index)\n{\n    PJ_ASSERT_RETURN(tp && pool && sdp_local, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(tp);\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(sdp_local);\n    PJ_UNUSED_ARG(sdp_remote);\n    PJ_UNUSED_ARG(media_index);\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t transport_media_stop(pjmedia_transport *tp)\n{\n    PJ_UNUSED_ARG(tp);\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t transport_simulate_lost(pjmedia_transport *tp,\n\t\t\t\t\t   pjmedia_dir dir,\n\t\t\t\t\t   unsigned pct_lost)\n{\n    struct transport_udp *udp = (struct transport_udp*)tp;\n\n    PJ_ASSERT_RETURN(tp && pct_lost <= 100, PJ_EINVAL);\n\n    if (dir & PJMEDIA_DIR_ENCODING)\n\tudp->tx_drop_pct = pct_lost;\n    \n    if (dir & PJMEDIA_DIR_DECODING)\n\tudp->rx_drop_pct = pct_lost;\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/transport_zrtp.c",
    "content": "/* $Id$ */\n/*\n * Copyright (C) 2010 Werner Dittmann\n * This is the pjmedia ZRTP transport module.\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\n#include <pjmedia/transport_zrtp.h>\n#include <pjmedia/endpoint.h>\n#include <pjlib.h>\n#include <pjlib-util.h>\n\n#include \"../../third_party/zsrtp/include/ZsrtpCWrapper.h\"\n\n#define THIS_FILE \"transport_zrtp.c\"\n\n#define MAX_RTP_BUFFER_LEN\t    PJMEDIA_MAX_MTU\n#define MAX_RTCP_BUFFER_LEN\t    PJMEDIA_MAX_MTU\n\n\n/* Transport functions prototypes */\nstatic pj_status_t transport_get_info(pjmedia_transport *tp,\n                                      pjmedia_transport_info *info);\nstatic pj_status_t transport_attach(pjmedia_transport *tp,\n                                    void *user_data,\n                                    const pj_sockaddr_t *rem_addr,\n                                    const pj_sockaddr_t *rem_rtcp,\n                                    unsigned addr_len,\n                                    void (*rtp_cb)(void*,\n                                                   void*,\n                                                   pj_ssize_t),\n                                    void (*rtcp_cb)(void*,\n                                                    void*,\n                                                    pj_ssize_t));\nstatic void    transport_detach(pjmedia_transport *tp,\n                                void *strm);\nstatic pj_status_t transport_send_rtp(pjmedia_transport *tp,\n                                      const void *pkt,\n                                      pj_size_t size);\nstatic pj_status_t transport_send_rtcp(pjmedia_transport *tp,\n                                       const void *pkt,\n                                       pj_size_t size);\nstatic pj_status_t transport_send_rtcp2(pjmedia_transport *tp,\n                                        const pj_sockaddr_t *addr,\n                                        unsigned addr_len,\n                                        const void *pkt,\n                                        pj_size_t size);\nstatic pj_status_t transport_media_create(pjmedia_transport *tp,\n        pj_pool_t *sdp_pool,\n        unsigned options,\n        const pjmedia_sdp_session *rem_sdp,\n        unsigned media_index);\nstatic pj_status_t transport_encode_sdp(pjmedia_transport *tp,\n                                        pj_pool_t *sdp_pool,\n                                        pjmedia_sdp_session *local_sdp,\n                                        const pjmedia_sdp_session *rem_sdp,\n                                        unsigned media_index);\nstatic pj_status_t transport_media_start(pjmedia_transport *tp,\n        pj_pool_t *pool,\n        const pjmedia_sdp_session *local_sdp,\n        const pjmedia_sdp_session *rem_sdp,\n        unsigned media_index);\nstatic pj_status_t transport_media_stop(pjmedia_transport *tp);\nstatic pj_status_t transport_simulate_lost(pjmedia_transport *tp,\n        pjmedia_dir dir,\n        unsigned pct_lost);\nstatic pj_status_t transport_destroy(pjmedia_transport *tp);\n\n\n/* The transport operations */\nstatic struct pjmedia_transport_op tp_zrtp_op =\n{\n    &transport_get_info,\n    &transport_attach,\n    &transport_detach,\n    &transport_send_rtp,\n    &transport_send_rtcp,\n    &transport_send_rtcp2,\n    &transport_media_create,\n    &transport_encode_sdp,\n    &transport_media_start,\n    &transport_media_stop,\n    &transport_simulate_lost,\n    &transport_destroy\n};\n\n/* The transport zrtp instance */\nstruct tp_zrtp\n{\n    pjmedia_transport base;\n    pj_pool_t       *pool;\n\n    /* Stream information. */\n    void        *stream_user_data;\n    void (*stream_rtp_cb)(void *user_data,\n                          void *pkt,\n                          pj_ssize_t);\n    void (*stream_rtcp_cb)(void *user_data,\n                           void *pkt,\n                           pj_ssize_t);\n\n    /* Add your own member here.. */\n    uint64_t protect;\n    uint64_t unprotect;\n    int32_t  unprotect_err;\n    int32_t refcount;\n    pj_timer_heap_t* timer_heap;\n    pj_timer_entry timeoutEntry;\n    pj_mutex_t* zrtpMutex;\n    ZsrtpContext* srtpReceive;\n    ZsrtpContext* srtpSend;\n    ZsrtpContextCtrl* srtcpReceive;\n    ZsrtpContextCtrl* srtcpSend;\n    void* sendBuffer;\n    void* sendBufferCtrl;\n    pj_uint8_t* zrtpBuffer;\n//    pj_int32_t sendBufferLen;\n    pj_uint32_t peerSSRC;       /* stored in host order */\n    pj_uint32_t localSSRC;      /* stored in host order */\n    char* clientIdString;\n    pjmedia_transport   *slave_tp;\n    pjmedia_zrtp_cb cb;\n    ZrtpContext* zrtpCtx;\n    pj_uint16_t zrtpSeq;\n    pj_bool_t enableZrtp;\n    pj_bool_t started;\n    pj_bool_t close_slave;\n    pj_bool_t mitmMode;\n    char cipher[128];\n};\n\n/* Forward declaration of thethe ZRTP specific callback functions that this\n  adapter must implement */\nstatic int32_t zrtp_sendDataZRTP(ZrtpContext* ctx, const uint8_t* data, int32_t length) ;\nstatic int32_t zrtp_activateTimer(ZrtpContext* ctx, int32_t time) ;\nstatic int32_t zrtp_cancelTimer(ZrtpContext* ctx) ;\nstatic void zrtp_sendInfo(ZrtpContext* ctx, int32_t severity, int32_t subCode) ;\nstatic int32_t zrtp_srtpSecretsReady(ZrtpContext* ctx, C_SrtpSecret_t* secrets, int32_t part) ;\nstatic void zrtp_srtpSecretsOff(ZrtpContext* ctx, int32_t part) ;\nstatic void zrtp_srtpSecretsOn(ZrtpContext* ctx, char* c, char* s, int32_t verified) ;\nstatic void zrtp_handleGoClear(ZrtpContext* ctx) ;\nstatic void zrtp_zrtpNegotiationFailed(ZrtpContext* ctx, int32_t severity, int32_t subCode) ;\nstatic void zrtp_zrtpNotSuppOther(ZrtpContext* ctx) ;\nstatic void zrtp_synchEnter(ZrtpContext* ctx) ;\nstatic void zrtp_synchLeave(ZrtpContext* ctx) ;\nstatic void zrtp_zrtpAskEnrollment(ZrtpContext* ctx, int32_t info) ;\nstatic void zrtp_zrtpInformEnrollment(ZrtpContext* ctx, int32_t info) ;\nstatic void zrtp_signSAS(ZrtpContext* ctx, uint8_t* sasHash) ;\nstatic int32_t zrtp_checkSASSignature(ZrtpContext* ctx, uint8_t* sasHash) ;\n\n/* The callback function structure for ZRTP */\nstatic zrtp_Callbacks c_callbacks =\n{\n    &zrtp_sendDataZRTP,\n    &zrtp_activateTimer,\n    &zrtp_cancelTimer,\n    &zrtp_sendInfo,\n    &zrtp_srtpSecretsReady,\n    &zrtp_srtpSecretsOff,\n    &zrtp_srtpSecretsOn,\n    &zrtp_handleGoClear,\n    &zrtp_zrtpNegotiationFailed,\n    &zrtp_zrtpNotSuppOther,\n    &zrtp_synchEnter,\n    &zrtp_synchLeave,\n    &zrtp_zrtpAskEnrollment,\n    &zrtp_zrtpInformEnrollment,\n    &zrtp_signSAS,\n    &zrtp_checkSASSignature\n};\n\nstatic void timer_callback(pj_timer_heap_t *ht, pj_timer_entry *e);\n\nstatic char clientId[] =    \"SIP SIMPLE Client SDK\";\n\n/*\n * Create the ZRTP transport.\n */\nPJ_DEF(pj_status_t) pjmedia_transport_zrtp_create(pjmedia_endpt *endpt,\n                                                  pj_timer_heap_t *timer_heap,\n                                                  pjmedia_transport *tp,\n                                                  pjmedia_transport **p_tp,\n                                                  pj_bool_t close_slave)\n{\n    pj_pool_t *pool;\n    struct tp_zrtp *zrtp;\n\n    PJ_ASSERT_RETURN(endpt && tp && p_tp, PJ_EINVAL);\n\n    /* Create the pool and initialize the adapter structure */\n    pool = pjmedia_endpt_create_pool(endpt, \"zrtp%p\", 5*1024, 512);\n    zrtp = PJ_POOL_ZALLOC_T(pool, struct tp_zrtp);\n    zrtp->pool = pool;\n\n    /* Initialize base pjmedia_transport */\n    pj_memcpy(zrtp->base.name, pool->obj_name, PJ_MAX_OBJ_NAME);\n    zrtp->base.type = tp->type;\n    zrtp->base.op = &tp_zrtp_op;\n\n    /* Set the timer heap to be used for timers */\n    zrtp->timer_heap = timer_heap;\n\n    /* Create the empty wrapper */\n    zrtp->zrtpCtx = zrtp_CreateWrapper();\n\n    /* Initialize standard values */\n    zrtp->clientIdString = clientId;    /* Set standard name */\n    zrtp->zrtpSeq = 1;                  /* TODO: randomize */\n    pj_mutex_create_simple(zrtp->pool, \"zrtp\", &zrtp->zrtpMutex);\n    zrtp->zrtpBuffer = pj_pool_zalloc(pool, MAX_ZRTP_SIZE);\n    zrtp->sendBuffer = pj_pool_zalloc(pool, MAX_RTP_BUFFER_LEN);\n    zrtp->sendBufferCtrl = pj_pool_zalloc(pool, MAX_RTCP_BUFFER_LEN);\n\n    zrtp->slave_tp = tp;\n    zrtp->close_slave = close_slave;\n    zrtp->mitmMode = PJ_FALSE;\n\n    /* Done */\n    zrtp->refcount++;\n    *p_tp = &zrtp->base;\n    return PJ_SUCCESS;\n}\n\nPJ_DECL(pj_status_t) pjmedia_transport_zrtp_initialize(pjmedia_transport *tp,\n                                                       const char *zidFilename,\n                                                       pj_bool_t autoEnable,\n                                                       pjmedia_zrtp_cb *cb)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    zrtp_initializeZrtpEngine(zrtp->zrtpCtx, &c_callbacks, zrtp->clientIdString,\n                              zidFilename, zrtp, zrtp->mitmMode);\n    zrtp->enableZrtp = autoEnable;\n    if (cb)\n\tpj_memcpy(&zrtp->cb, cb, sizeof(pjmedia_zrtp_cb));\n    return PJ_SUCCESS;\n}\n\nstatic void timer_callback(pj_timer_heap_t *ht, pj_timer_entry *e)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)e->user_data;\n\n    zrtp_processTimeout(zrtp->zrtpCtx);\n    PJ_UNUSED_ARG(ht);\n}\n\n/*\n * Here start with callback functions that support the ZRTP core\n */\nstatic int32_t zrtp_sendDataZRTP(ZrtpContext* ctx, const uint8_t* data, int32_t length)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n    pj_uint16_t totalLen = length + 12;     /* Fixed number of bytes of ZRTP header */\n    pj_uint32_t crc;\n    pj_uint8_t* buffer = zrtp->zrtpBuffer;\n    pj_uint16_t* pus;\n    pj_uint32_t* pui;\n\n    if ((totalLen) > MAX_ZRTP_SIZE)\n        return 0;\n\n    /* Get some handy pointers */\n    pus = (pj_uint16_t*)buffer;\n    pui = (pj_uint32_t*)buffer;\n\n    /* set up fixed ZRTP header */\n    *buffer = 0x10;     /* invalid RTP version - refer to ZRTP spec chap 5 */\n    *(buffer + 1) = 0;\n    pus[1] = pj_htons(zrtp->zrtpSeq++);\n    pui[1] = pj_htonl(ZRTP_MAGIC);\n    pui[2] = pj_htonl(zrtp->localSSRC);   /* stored in host order */\n\n    /* Copy ZRTP message data behind the header data */\n    pj_memcpy(buffer+12, data, length);\n\n    /* Setup and compute ZRTP CRC */\n    crc = zrtp_GenerateCksum(buffer, totalLen-CRC_SIZE);\n\n    /* convert and store CRC in ZRTP packet.*/\n    crc = zrtp_EndCksum(crc);\n    *(uint32_t*)(buffer+totalLen-CRC_SIZE) = pj_htonl(crc);\n\n    /* Send the ZRTP packet using the slave transport */\n    return (pjmedia_transport_send_rtp(zrtp->slave_tp, buffer, totalLen) == PJ_SUCCESS) ? 1 : 0;\n}\n\nstatic int32_t zrtp_activateTimer(ZrtpContext* ctx, int32_t time)\n{\n    pj_time_val timeout;\n    pj_status_t status;\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n\n    timeout.sec = time / 1000;\n    timeout.msec = time % 1000;\n\n    pj_timer_entry_init(&zrtp->timeoutEntry, 0, zrtp, &timer_callback);\n    status = pj_timer_heap_schedule(zrtp->timer_heap, &zrtp->timeoutEntry, &timeout);\n    if (status == PJ_SUCCESS)\n        return 1;\n    else\n        return 0;\n}\n\nstatic int32_t zrtp_cancelTimer(ZrtpContext* ctx)\n{\n    pj_status_t status;\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n\n    status = pj_timer_heap_cancel(zrtp->timer_heap, &zrtp->timeoutEntry);\n    if (status == PJ_SUCCESS)\n        return 1;\n    else\n        return 0;\n}\n\nstatic void zrtp_sendInfo(ZrtpContext* ctx, int32_t severity, int32_t subCode)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n\n    if (zrtp->cb.show_message)\n        zrtp->cb.show_message(&zrtp->base, severity, subCode);\n\n}\n\nstatic int32_t zrtp_srtpSecretsReady(ZrtpContext* ctx, C_SrtpSecret_t* secrets, int32_t part)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n    \n    ZsrtpContext* recvCrypto;\n    ZsrtpContext* senderCrypto;\n    ZsrtpContextCtrl* recvCryptoCtrl;\n    ZsrtpContextCtrl* senderCryptoCtrl;\n    int cipher;\n    int authn;\n    int authKeyLen;\n    //    int srtcpAuthTagLen;\n    \n    if (secrets->authAlgorithm == zrtp_Sha1) {\n        authn = SrtpAuthenticationSha1Hmac;\n        authKeyLen = 20;\n        //        srtcpAuthTagLen = 80;   // Always 80 bit for SRTCP / SHA1\n    }\n    \n    if (secrets->authAlgorithm == zrtp_Skein) {\n        authn = SrtpAuthenticationSkeinHmac;\n        authKeyLen = 32;\n        //        srtcpAuthTagLen = 64;   // Always 64 bit for SRTCP / Skein\n    }\n    \n    if (secrets->symEncAlgorithm == zrtp_Aes)\n        cipher = SrtpEncryptionAESCM;\n    \n    if (secrets->symEncAlgorithm == zrtp_TwoFish)\n        cipher = SrtpEncryptionTWOCM;\n    \n    if (part == ForSender) {\n        // To encrypt packets: intiator uses initiator keys,\n        // responder uses responder keys\n        // Create a \"half baked\" crypto context first and store it. This is\n        // the main crypto context for the sending part of the connection.\n        if (secrets->role == Initiator) {\n            senderCrypto = zsrtp_CreateWrapper(zrtp->localSSRC,\n                                               0,\n                                               0L,                                      // keyderivation << 48,\n                                               cipher,                                  // encryption algo\n                                               authn,                                   // authtentication algo\n                                               (unsigned char*)secrets->keyInitiator,   // Master Key\n                                               secrets->initKeyLen / 8,                 // Master Key length\n                                               (unsigned char*)secrets->saltInitiator,  // Master Salt\n                                               secrets->initSaltLen / 8,                // Master Salt length\n                                               secrets->initKeyLen / 8,                 // encryption keyl\n                                               authKeyLen,                              // authentication key len\n                                               secrets->initSaltLen / 8,                // session salt len\n                                               secrets->srtpAuthTagLen / 8);            // authentication tag lenA\n            \n            senderCryptoCtrl = zsrtp_CreateWrapperCtrl(zrtp->localSSRC,\n                                                       cipher,                                    // encryption algo\n                                                       authn,                                     // authtication algo\n                                                       (unsigned char*)secrets->keyInitiator,     // Master Key\n                                                       secrets->initKeyLen / 8,                   // Master Key length\n                                                       (unsigned char*)secrets->saltInitiator,    // Master Salt\n                                                       secrets->initSaltLen / 8,                  // Master Salt length\n                                                       secrets->initKeyLen / 8,                   // encryption keyl\n                                                       authKeyLen,                                // authentication key len\n                                                       secrets->initSaltLen / 8,                  // session salt len\n                                                       secrets->srtpAuthTagLen / 8);              // authentication tag len\n            //                                                              srtcpAuthTagLen / 8);                      // authentication tag len\n        }\n        else {\n            senderCrypto = zsrtp_CreateWrapper(zrtp->localSSRC,\n                                               0,\n                                               0L,                                      // keyderivation << 48,\n                                               cipher,                                  // encryption algo\n                                               authn,                                   // authtentication algo\n                                               (unsigned char*)secrets->keyResponder,   // Master Key\n                                               secrets->respKeyLen / 8,                 // Master Key length\n                                               (unsigned char*)secrets->saltResponder,  // Master Salt\n                                               secrets->respSaltLen / 8,                // Master Salt length\n                                               secrets->respKeyLen / 8,                 // encryption keyl\n                                               authKeyLen,                              // authentication key len\n                                               secrets->respSaltLen / 8,                // session salt len\n                                               secrets->srtpAuthTagLen / 8);            // authentication tag len\n            \n            senderCryptoCtrl = zsrtp_CreateWrapperCtrl(zrtp->localSSRC,\n                                                       cipher,                                    // encryption algo\n                                                       authn,                                     // authtication algo\n                                                       (unsigned char*)secrets->keyResponder,     // Master Key\n                                                       secrets->respKeyLen / 8,                   // Master Key length\n                                                       (unsigned char*)secrets->saltResponder,    // Master Salt\n                                                       secrets->respSaltLen / 8,                  // Master Salt length\n                                                       secrets->respKeyLen / 8,                   // encryption keyl\n                                                       authKeyLen,                                // authentication key len\n                                                       secrets->respSaltLen / 8,                  // session salt len\n                                                       secrets->srtpAuthTagLen / 8);              // authentication tag len\n            //                                                              srtcpAuthTagLen / 8);                      // authentication tag len\n        }\n        if (senderCrypto == NULL) {\n            return 0;\n        }\n        // Create a SRTP crypto context for real SSRC sender stream.\n        // Note: key derivation can be done at this time only if the\n        // key derivation rate is 0 (disabled). For ZRTP this is the\n        // case: the key derivation is defined as 2^48\n        // which is effectively 0.\n        zsrtp_deriveSrtpKeys(senderCrypto, 0L);\n        zrtp->srtpSend = senderCrypto;\n        \n        zsrtp_deriveSrtpKeysCtrl(senderCryptoCtrl);\n        zrtp->srtcpSend = senderCryptoCtrl;\n    }\n    if (part == ForReceiver) {\n        // To decrypt packets: intiator uses responder keys,\n        // responder initiator keys\n        // See comment above.\n        if (secrets->role == Initiator) {\n            recvCrypto = zsrtp_CreateWrapper(zrtp->peerSSRC,\n                                             0,\n                                             0L,                                      // keyderivation << 48,\n                                             cipher,                                  // encryption algo\n                                             authn,                                   // authtentication algo\n                                             (unsigned char*)secrets->keyResponder,   // Master Key\n                                             secrets->respKeyLen / 8,                 // Master Key length\n                                             (unsigned char*)secrets->saltResponder,  // Master Salt\n                                             secrets->respSaltLen / 8,                // Master Salt length\n                                             secrets->respKeyLen / 8,                 // encryption keyl\n                                             authKeyLen,                              // authentication key len\n                                             secrets->respSaltLen / 8,                // session salt len\n                                             secrets->srtpAuthTagLen / 8);            // authentication tag len\n            \n            recvCryptoCtrl = zsrtp_CreateWrapperCtrl(zrtp->peerSSRC,\n                                                     cipher,                                    // encryption algo\n                                                     authn,                                     // authtication algo\n                                                     (unsigned char*)secrets->keyResponder,     // Master Key\n                                                     secrets->respKeyLen / 8,                   // Master Key length\n                                                     (unsigned char*)secrets->saltResponder,    // Master Salt\n                                                     secrets->respSaltLen / 8,                  // Master Salt length\n                                                     secrets->respKeyLen / 8,                   // encryption keyl\n                                                     authKeyLen,                                // authentication key len\n                                                     secrets->respSaltLen / 8,                  // session salt len\n                                                     secrets->srtpAuthTagLen / 8);              // authentication tag len\n            //                                                            srtcpAuthTagLen / 8);                      // authentication tag len\n        }\n        else {\n            recvCrypto = zsrtp_CreateWrapper(zrtp->peerSSRC,\n                                             0,\n                                             0L,                                      // keyderivation << 48,\n                                             cipher,                                  // encryption algo\n                                             authn,                                   // authtentication algo\n                                             (unsigned char*)secrets->keyInitiator,   // Master Key\n                                             secrets->initKeyLen / 8,                 // Master Key length\n                                             (unsigned char*)secrets->saltInitiator,  // Master Salt\n                                             secrets->initSaltLen / 8,                // Master Salt length\n                                             secrets->initKeyLen / 8,                 // encryption keyl\n                                             authKeyLen,                              // authentication key len\n                                             secrets->initSaltLen / 8,                // session salt len\n                                             secrets->srtpAuthTagLen / 8);            // authentication tag len\n            \n            recvCryptoCtrl = zsrtp_CreateWrapperCtrl(zrtp->peerSSRC,\n                                                     cipher,                                    // encryption algo\n                                                     authn,                                     // authtication algo\n                                                     (unsigned char*)secrets->keyInitiator,     // Master Key\n                                                     secrets->initKeyLen / 8,                   // Master Key length\n                                                     (unsigned char*)secrets->saltInitiator,    // Master Salt\n                                                     secrets->initSaltLen / 8,                  // Master Salt length\n                                                     secrets->initKeyLen / 8,                   // encryption keyl\n                                                     authKeyLen,                                // authentication key len\n                                                     secrets->initSaltLen / 8,                  // session salt len\n                                                     secrets->srtpAuthTagLen / 8);              // authentication tag len\n            //                                                            srtcpAuthTagLen / 8);                      // authentication tag len\n        }\n        if (recvCrypto == NULL) {\n            return 0;\n        }\n        // Create a SRTP crypto context for real SSRC input stream.\n        // If the sender didn't provide a SSRC just insert the template\n        // into the queue. After we received the first packet the real\n        // crypto context will be created.\n        //\n        // Note: key derivation can be done at this time only if the\n        // key derivation rate is 0 (disabled). For ZRTP this is the\n        // case: the key derivation is defined as 2^48\n        // which is effectively 0.\n        zsrtp_deriveSrtpKeys(recvCrypto, 0L);\n        zrtp->srtpReceive = recvCrypto;\n        \n        zsrtp_deriveSrtpKeysCtrl(recvCryptoCtrl);\n        zrtp->srtcpReceive = recvCryptoCtrl;\n    }\n    return 1;\n}\n\nstatic void zrtp_srtpSecretsOff(ZrtpContext* ctx, int32_t part)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n\n    if (part == ForSender)\n    {\n        zsrtp_DestroyWrapper(zrtp->srtpSend);\n        zsrtp_DestroyWrapperCtrl(zrtp->srtcpSend);\n        zrtp->srtpSend = NULL;\n        zrtp->srtcpSend = NULL;\n    }\n    if (part == ForReceiver)\n    {\n        zsrtp_DestroyWrapper(zrtp->srtpReceive);\n        zsrtp_DestroyWrapperCtrl(zrtp->srtcpReceive);\n        zrtp->srtpReceive = NULL;\n        zrtp->srtcpReceive = NULL;\n    }\n\n    if (zrtp->cb.secure_off)\n        zrtp->cb.secure_off(&zrtp->base);\n}\n\nstatic void zrtp_srtpSecretsOn(ZrtpContext* ctx, char* c, char* s, int32_t verified)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n    int len;\n\n    len = strlen(c);\n    if (len > sizeof(zrtp->cipher) - 1)\n        len = sizeof(zrtp->cipher) - 1;\n    memcpy(zrtp->cipher, c, len);\n    zrtp->cipher[len] = '\\0';\n\n    if (zrtp->cb.secure_on)\n        zrtp->cb.secure_on(&zrtp->base, c);\n\n    if (s && strlen(s) > 0 && zrtp->cb.show_sas)\n        zrtp->cb.show_sas(&zrtp->base, s, verified);\n}\n\nstatic void zrtp_handleGoClear(ZrtpContext* ctx)\n{\n    /* TODO: implement */\n}\n\nstatic void zrtp_zrtpNegotiationFailed(ZrtpContext* ctx, int32_t severity, int32_t subCode)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n\n    if (zrtp->cb.negotiation_failed)\n        zrtp->cb.negotiation_failed(&zrtp->base, severity, subCode);\n}\n\nstatic void zrtp_zrtpNotSuppOther(ZrtpContext* ctx)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n\n    if (zrtp->cb.not_supported_by_other)\n        zrtp->cb.not_supported_by_other(&zrtp->base);\n}\n\nstatic void zrtp_synchEnter(ZrtpContext* ctx)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n    pj_mutex_lock(zrtp->zrtpMutex);\n}\n\nstatic void zrtp_synchLeave(ZrtpContext* ctx)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n    pj_mutex_unlock(zrtp->zrtpMutex);\n}\n\nstatic void zrtp_zrtpAskEnrollment(ZrtpContext* ctx, int32_t info)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n\n    if (zrtp->cb.ask_enrollment)\n        zrtp->cb.ask_enrollment(&zrtp->base, info);\n}\n\nstatic void zrtp_zrtpInformEnrollment(ZrtpContext* ctx, int32_t info)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n\n    if (zrtp->cb.inform_enrollment)\n        zrtp->cb.inform_enrollment(&zrtp->base, info);\n}\n\nstatic void zrtp_signSAS(ZrtpContext* ctx, uint8_t* sasHash)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n\n    if (zrtp->cb.sign_sas)\n        zrtp->cb.sign_sas(&zrtp->base, sasHash);\n}\n\nstatic int32_t zrtp_checkSASSignature(ZrtpContext* ctx, uint8_t* sasHash)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData;\n\n    if (zrtp->cb.check_sas_signature)\n        return zrtp->cb.check_sas_signature(&zrtp->base, sasHash);\n    return 0;\n}\n\n/*\n * Implement the specific ZRTP transport functions\n */\nPJ_DEF(void) pjmedia_transport_zrtp_setEnableZrtp(pjmedia_transport *tp, pj_bool_t onOff)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_assert(tp);\n\n    zrtp->enableZrtp = onOff;\n}\n\nPJ_DEF(pj_bool_t) pjmedia_transport_zrtp_isEnableZrtp(pjmedia_transport *tp)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    PJ_ASSERT_RETURN(tp, PJ_FALSE);\n\n    return zrtp->enableZrtp;\n\n}\n\nPJ_DEF(void) pjmedia_transport_zrtp_startZrtp(pjmedia_transport *tp)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_assert(tp && zrtp->zrtpCtx);\n\n    zrtp_startZrtpEngine(zrtp->zrtpCtx);\n    zrtp->started = 1;\n}\n\nPJ_DEF(void) pjmedia_transport_zrtp_stopZrtp(pjmedia_transport *tp)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_assert(tp && zrtp->zrtpCtx);\n\n    zrtp_stopZrtpEngine(zrtp->zrtpCtx);\n    zrtp->started = 0;\n}\n\nPJ_DEF(void) pjmedia_transport_zrtp_setLocalSSRC(pjmedia_transport *tp, uint32_t ssrc)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_assert(tp);\n\n    zrtp->localSSRC = ssrc;\n}\n\nPJ_DEF(pj_bool_t) pjmedia_transport_zrtp_isMitmMode(pjmedia_transport *tp)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_assert(tp);\n\n    return zrtp->mitmMode;\n}\n\nPJ_DEF(void) pjmedia_transport_zrtp_setMitmMode(pjmedia_transport *tp, pj_bool_t mitmMode)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_assert(tp);\n\n    zrtp->mitmMode = mitmMode;\n}\n\nPJ_DEF(ZrtpContext*) pjmedia_transport_zrtp_getZrtpContext(pjmedia_transport *tp)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    PJ_ASSERT_RETURN(tp, NULL);\n\n    return zrtp->zrtpCtx;\n}\n\nPJ_DEF(void) pjmedia_transport_zrtp_setSASVerified(pjmedia_transport *tp, pj_bool_t verified)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_assert(tp);\n\n    if (verified)\n        zrtp_SASVerified(zrtp->zrtpCtx);\n    else\n        zrtp_resetSASVerified(zrtp->zrtpCtx);\n}\n\nPJ_DEF(int) pjmedia_transport_zrtp_getPeerZid(pjmedia_transport *tp, unsigned char* data)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_assert(tp);\n\n    return zrtp_getPeerZid(zrtp->zrtpCtx, data);\n}\n\nPJ_DEF(char*) pjmedia_transport_zrtp_getPeerName(pjmedia_transport *tp)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_assert(tp);\n\n    return zrtp_getPeerName(zrtp->zrtpCtx);\n}\n\nPJ_DEF(void) pjmedia_transport_zrtp_putPeerName(pjmedia_transport *tp, const char *name)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_assert(tp);\n\n    zrtp_putPeerName(zrtp->zrtpCtx, name);\n}\n\nPJ_DEF(char*) pjmedia_transport_zrtp_getMultiStreamParameters(pjmedia_transport *tp, pj_int32_t *length)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_assert(tp);\n\n    return zrtp_getMultiStrParams(zrtp->zrtpCtx, length);\n}\n\nPJ_DEF(void) pjmedia_transport_zrtp_setMultiStreamParameters(pjmedia_transport *tp, const char *parameters, pj_int32_t length, pjmedia_transport *master_tp)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    struct tp_zrtp *master_zrtp = (struct tp_zrtp*)master_tp;\n    pj_assert(tp);\n    pj_assert(master_tp);\n\n    zrtp_setMultiStrParams(zrtp->zrtpCtx, (char*) parameters, length, master_zrtp->zrtpCtx);\n}\n\n/*\n * get_info() is called to get the transport addresses to be put\n * in SDP c= line and a=rtcp line.\n */\nstatic pj_status_t transport_get_info(pjmedia_transport *tp,\n                                      pjmedia_transport_info *info)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pjmedia_zrtp_info zrtp_info;\n    int spc_info_idx;\n\n    PJ_ASSERT_RETURN(tp && info, PJ_EINVAL);\n    PJ_ASSERT_RETURN(info->specific_info_cnt <\n                     PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT, PJ_ETOOMANY);\n\n    zrtp_info.active = zrtp_inState(zrtp->zrtpCtx, SecureState) ? PJ_TRUE : PJ_FALSE;\n    if (zrtp_info.active)\n        memcpy(zrtp_info.cipher, zrtp->cipher, sizeof(zrtp->cipher));\n    else\n        zrtp_info.cipher[0] = '\\0';\n\n    spc_info_idx = info->specific_info_cnt++;\n    info->spc_info[spc_info_idx].type = PJMEDIA_TRANSPORT_TYPE_ZRTP;\n\n    pj_memcpy(&info->spc_info[spc_info_idx].buffer, &zrtp_info,\n              sizeof(zrtp_info));\n\n    return pjmedia_transport_get_info(zrtp->slave_tp, info);\n}\n\n/* This is our RTP callback, that is called by the slave transport when it\n * receives RTP packet.\n */\nstatic void transport_rtp_cb(void *user_data, void *pkt, pj_ssize_t size)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)user_data;\n\n    pj_uint8_t* buffer = (pj_uint8_t*)pkt;\n    int32_t newLen = 0;\n    pj_status_t rc = PJ_SUCCESS;\n\n    pj_assert(zrtp && zrtp->stream_rtcp_cb && pkt);\n\n    // check if this could be a real RTP/SRTP packet.\n    if ((*buffer & 0xf0) != 0x10)\n    {\n        //  Could be real RTP, check if we are in secure mode\n        if (zrtp->srtpReceive == NULL || size < 0)\n        {\n            zrtp->stream_rtp_cb(zrtp->stream_user_data, pkt, size);\n        }\n        else\n        {\n            rc = zsrtp_unprotect(zrtp->srtpReceive, pkt, size, &newLen);\n            if (rc == 1)\n            {\n                zrtp->unprotect++;\n                zrtp->stream_rtp_cb(zrtp->stream_user_data, pkt,\n                                    newLen);\n                zrtp->unprotect_err = 0;\n            }\n            else\n            {\n                if (zrtp->cb.show_message)\n                {\n                    if (rc == -1)\n                        zrtp->cb.show_message(&zrtp->base, zrtp_Warning, zrtp_WarningSRTPauthError);\n                    else\n                        zrtp->cb.show_message(&zrtp->base, zrtp_Warning, zrtp_WarningSRTPreplayError);\n                }\n                zrtp->unprotect_err = rc;\n                /* We failed to decrypt the packet, but forward it regardless to the slave\n                 * transport, it might not have been encrypted after all */\n                zrtp->stream_rtp_cb(zrtp->stream_user_data, pkt, size);\n            }\n        }\n        if (!zrtp->started && zrtp->enableZrtp)\n            pjmedia_transport_zrtp_startZrtp((pjmedia_transport *)zrtp);\n\n        return;\n    }\n\n    // We assume all other packets are ZRTP packets here. Process\n    // if ZRTP processing is enabled. Because valid RTP packets are\n    // already handled we delete any packets here after processing.\n    if (zrtp->enableZrtp && zrtp->zrtpCtx != NULL)\n    {\n        // Get CRC value into crc (see above how to compute the offset)\n        pj_uint16_t temp = size - CRC_SIZE;\n        pj_uint32_t crc = *(uint32_t*)(buffer + temp);\n        crc = pj_ntohl(crc);\n\n        if (!zrtp_CheckCksum(buffer, temp, crc))\n        {\n            if (zrtp->cb.show_message)\n                zrtp->cb.show_message(&zrtp->base, zrtp_Warning, zrtp_WarningCRCmismatch);\n            return;\n        }\n\n        pj_uint32_t magic = *(pj_uint32_t*)(buffer + 4);\n        magic = pj_ntohl(magic);\n\n        // Check if it is really a ZRTP packet, return, no further processing\n        if (magic != ZRTP_MAGIC)\n            return;\n\n        // cover the case if the other party sends _only_ ZRTP packets at the\n        // beginning of a session. Start ZRTP in this case as well.\n        if (!zrtp->started)\n        {\n            pjmedia_transport_zrtp_startZrtp((pjmedia_transport *)zrtp);\n        }\n        // this now points beyond the undefined and length field.\n        // We need them, thus adjust\n        unsigned char* zrtpMsg = (buffer + 12);\n\n        // store peer's SSRC in host order, used when creating the CryptoContext\n        zrtp->peerSSRC = *(pj_uint32_t*)(buffer + 8);\n        zrtp->peerSSRC = pj_ntohl(zrtp->peerSSRC);\n        zrtp_processZrtpMessage(zrtp->zrtpCtx, zrtpMsg, zrtp->peerSSRC, size);\n    }\n}\n\n\n/* This is our RTCP callback, that is called by the slave transport when it\n * receives RTCP packet.\n */\nstatic void transport_rtcp_cb(void *user_data, void *pkt, pj_ssize_t size)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)user_data;\n    int32_t newLen = 0;\n    pj_status_t rc = PJ_SUCCESS;\n    \n    pj_assert(zrtp && zrtp->stream_rtcp_cb);\n    \n    if (zrtp->srtcpReceive == NULL || size < 0)\n    {\n        zrtp->stream_rtcp_cb(zrtp->stream_user_data, pkt, size);\n    }\n    else\n    {\n        rc = zsrtp_unprotectCtrl(zrtp->srtcpReceive, pkt, size, &newLen);\n\n        if (rc == 1)\n        {\n            /* Call stream's callback */\n            zrtp->stream_rtcp_cb(zrtp->stream_user_data, pkt, newLen);\n        }\n        else\n        {\n            // Testing: print some error output\n        }\n    }\n}\n\n\n/*\n * attach() is called by stream to register callbacks that we should\n * call on receipt of RTP and RTCP packets.\n */\nstatic pj_status_t transport_attach(pjmedia_transport *tp,\n                                    void *user_data,\n                                    const pj_sockaddr_t *rem_addr,\n                                    const pj_sockaddr_t *rem_rtcp,\n                                    unsigned addr_len,\n                                    void (*rtp_cb)(void*,\n                                                   void*,\n                                                   pj_ssize_t),\n                                    void (*rtcp_cb)(void*,\n                                                    void*,\n                                                    pj_ssize_t))\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL);\n\n    /* In this example, we will save the stream information and callbacks\n     * to our structure, and we will register different RTP/RTCP callbacks\n     * instead.\n     */\n    pj_assert(zrtp->stream_user_data == NULL);\n    zrtp->stream_user_data = user_data;\n    zrtp->stream_rtp_cb = rtp_cb;\n    zrtp->stream_rtcp_cb = rtcp_cb;\n\n    status = pjmedia_transport_attach(zrtp->slave_tp, zrtp, rem_addr,\n                                      rem_rtcp, addr_len, &transport_rtp_cb,\n                                      &transport_rtcp_cb);\n    if (status != PJ_SUCCESS)\n    {\n        zrtp->stream_user_data = NULL;\n        zrtp->stream_rtp_cb = NULL;\n        zrtp->stream_rtcp_cb = NULL;\n        return status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * detach() is called when the media is terminated, and the stream is\n * to be disconnected from us.\n */\nstatic void transport_detach(pjmedia_transport *tp, void *strm)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n\n    PJ_UNUSED_ARG(strm);\n    PJ_ASSERT_ON_FAIL(tp, return);\n\n    if (zrtp->stream_user_data != NULL)\n    {\n        pjmedia_transport_detach(zrtp->slave_tp, zrtp);\n        zrtp->stream_user_data = NULL;\n        zrtp->stream_rtp_cb = NULL;\n        zrtp->stream_rtcp_cb = NULL;\n    }\n}\n\n\n/*\n * send_rtp() is called to send RTP packet. The \"pkt\" and \"size\" argument\n * contain both the RTP header and the payload.\n */\nstatic pj_status_t transport_send_rtp(pjmedia_transport *tp,\n                                      const void *pkt,\n                                      pj_size_t size)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_uint32_t* pui = (pj_uint32_t*)pkt;\n    int32_t newLen = 0;\n    pj_status_t rc = PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(tp && pkt, PJ_EINVAL);\n\n\n    if (!zrtp->started && zrtp->enableZrtp)\n    {\n        if (zrtp->localSSRC == 0)\n            zrtp->localSSRC = pj_ntohl(pui[2]);   /* Learn own SSRC before starting ZRTP */\n\n        pjmedia_transport_zrtp_startZrtp((pjmedia_transport *)zrtp);\n    }\n\n    if (zrtp->srtpSend == NULL)\n    {\n        return pjmedia_transport_send_rtp(zrtp->slave_tp, pkt, size);\n    }\n    else\n    {\n        if (size+80 > MAX_RTP_BUFFER_LEN)\n            return PJ_ETOOBIG;\n\n        pj_memcpy(zrtp->sendBuffer, pkt, size);\n        rc = zsrtp_protect(zrtp->srtpSend, zrtp->sendBuffer, size, &newLen);\n        zrtp->protect++;\n\n        if (rc == 1)\n            return pjmedia_transport_send_rtp(zrtp->slave_tp, zrtp->sendBuffer, newLen);\n        else\n            return PJ_EIGNORED;\n    }\n}\n\n\n/*\n * send_rtcp() is called to send RTCP packet. The \"pkt\" and \"size\" argument\n * contain the RTCP packet.\n */\nstatic pj_status_t transport_send_rtcp(pjmedia_transport *tp,\n                                       const void *pkt,\n                                       pj_size_t size)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    pj_status_t rc = PJ_SUCCESS;\n    int32_t newLen = 0;\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    /* You may do some processing to the RTCP packet here if you want. */\n    if (zrtp->srtcpSend == NULL)\n    {\n        return pjmedia_transport_send_rtcp(zrtp->slave_tp, pkt, size);\n    }\n    else\n    {\n        if (size+80 > MAX_RTCP_BUFFER_LEN)\n            return PJ_ETOOBIG;\n\n        pj_memcpy(zrtp->sendBufferCtrl, pkt, size);\n        rc = zsrtp_protectCtrl(zrtp->srtcpSend, zrtp->sendBufferCtrl, size, &newLen);\n\n        if (rc == 1)\n            return pjmedia_transport_send_rtcp(zrtp->slave_tp, zrtp->sendBufferCtrl, newLen);\n        else\n            return PJ_EIGNORED;\n    }\n\n    /* Send the packet using the slave transport */\n//    return pjmedia_transport_send_rtcp(zrtp->slave_tp, pkt, size);\n}\n\n\n/*\n * This is another variant of send_rtcp(), with the alternate destination\n * address in the argument.\n */\nstatic pj_status_t transport_send_rtcp2(pjmedia_transport *tp,\n                                        const pj_sockaddr_t *addr,\n                                        unsigned addr_len,\n                                        const void *pkt,\n                                        pj_size_t size)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    return pjmedia_transport_send_rtcp2(zrtp->slave_tp, addr, addr_len,\n                                        pkt, size);\n}\n\n/*\n * The media_create() is called when the transport is about to be used for\n * a new call.\n */\nstatic pj_status_t transport_media_create(pjmedia_transport *tp,\n        pj_pool_t *sdp_pool,\n        unsigned options,\n        const pjmedia_sdp_session *rem_sdp,\n        unsigned media_index)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    /* if \"rem_sdp\" is not NULL, it means we are UAS. You may do some\n     * inspections on the incoming SDP to verify that the SDP is acceptable\n     * for us. If the SDP is not acceptable, we can reject the SDP by\n     * returning non-PJ_SUCCESS.\n     */\n    if (rem_sdp)\n    {\n        /* Do your stuff.. */\n    }\n\n    /* Once we're done with our initialization, pass the call to the\n     * slave transports to let it do it's own initialization too.\n     */\n    return pjmedia_transport_media_create(zrtp->slave_tp, sdp_pool, options,\n                                          rem_sdp, media_index);\n}\n\n/*\n * The encode_sdp() is called when we're about to send SDP to remote party,\n * either as SDP offer or as SDP answer.\n */\nstatic pj_status_t transport_encode_sdp(pjmedia_transport *tp,\n                                        pj_pool_t *sdp_pool,\n                                        pjmedia_sdp_session *local_sdp,\n                                        const pjmedia_sdp_session *rem_sdp,\n                                        unsigned media_index)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    int32_t numVersions, i;\n    \n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n    \n    /* If \"rem_sdp\" is not NULL, it means we're encoding SDP answer. You may\n     * do some more checking on the SDP's once again to make sure that\n     * everything is okay before we send SDP.\n     */\n    if (rem_sdp)\n    {\n        /* Do checking stuffs here.. */\n    }\n\n    /* Add zrtp-hash attributes to both INVITE and 200 OK. */\n    numVersions = zrtp_getNumberSupportedVersions(zrtp->zrtpCtx);\n    for (i = 0; i < numVersions; i++) {\n        char *zrtp_hello_hash = zrtp_getHelloHash(zrtp->zrtpCtx, i);\n        if (zrtp_hello_hash && *zrtp_hello_hash) {\n            int zrtp_hello_hash_len = strlen(zrtp_hello_hash);\n            pj_str_t *zrtp_hash_str = PJ_POOL_ALLOC_T(sdp_pool, pj_str_t);\n            pjmedia_sdp_attr *zrtp_hash = NULL;\n\n            zrtp_hash_str->ptr = zrtp_hello_hash;\n            zrtp_hash_str->slen = zrtp_hello_hash_len;\n\n            zrtp_hash = pjmedia_sdp_attr_create(sdp_pool, \"zrtp-hash\", zrtp_hash_str);\n            if (zrtp_hash && \n                pjmedia_sdp_attr_add(&local_sdp->media[media_index]->attr_count, local_sdp->media[media_index]->attr, zrtp_hash) == PJ_SUCCESS) {\n                PJ_LOG(4, (THIS_FILE, \"attribute added: a=zrtp-hash:%s\", zrtp_hello_hash));\n            }\n            else {\n                PJ_LOG(4, (THIS_FILE, \"error adding attribute: a=zrtp-hash:%s\", zrtp_hello_hash));\n            }\n        }\n    }\n\n    /* You may do anything to the local_sdp, e.g. adding new attributes, or\n     * even modifying the SDP if you want.\n     */\n    if (0)\n    {\n        /* Say we add a proprietary attribute here.. */\n        pjmedia_sdp_attr *my_attr;\n\n        my_attr = PJ_POOL_ALLOC_T(sdp_pool, pjmedia_sdp_attr);\n        pj_strdup2(sdp_pool, &my_attr->name, \"X-zrtp\");\n        pj_strdup2(sdp_pool, &my_attr->value, \"some value\");\n\n        pjmedia_sdp_attr_add(&local_sdp->media[media_index]->attr_count,\n                             local_sdp->media[media_index]->attr,\n                             my_attr);\n    }\n\n    /* And then pass the call to slave transport to let it encode its\n     * information in the SDP. You may choose to call encode_sdp() to slave\n     * first before adding your custom attributes if you want.\n     */\n    return pjmedia_transport_encode_sdp(zrtp->slave_tp, sdp_pool, local_sdp, rem_sdp, media_index);\n}\n\n/*\n * The media_start() is called once both local and remote SDP have been\n * negotiated successfully, and the media is ready to start. Here we can start\n * committing our processing.\n */\nstatic pj_status_t transport_media_start(pjmedia_transport *tp,\n        pj_pool_t *pool,\n        const pjmedia_sdp_session *local_sdp,\n        const pjmedia_sdp_session *rem_sdp,\n        unsigned media_index)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    /* Do something.. */\n\n    /* And pass the call to the slave transport */\n    return pjmedia_transport_media_start(zrtp->slave_tp, pool, local_sdp,\n                                         rem_sdp, media_index);\n}\n\n/*\n * The media_stop() is called when media has been stopped.\n */\nstatic pj_status_t transport_media_stop(pjmedia_transport *tp)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    /* Do something.. */\n    PJ_LOG(4, (THIS_FILE, \"Media stop - encrypted packets: %ld, decrypted packets: %ld\",\n               zrtp->protect, zrtp->unprotect));\n\n    /* And pass the call to the slave transport */\n    return pjmedia_transport_media_stop(zrtp->slave_tp);\n}\n\n/*\n * simulate_lost() is called to simulate packet lost\n */\nstatic pj_status_t transport_simulate_lost(pjmedia_transport *tp,\n        pjmedia_dir dir,\n        unsigned pct_lost)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    return pjmedia_transport_simulate_lost(zrtp->slave_tp, dir, pct_lost);\n}\n\n/*\n * destroy() is called when the transport is no longer needed.\n */\nstatic pj_status_t transport_destroy(pjmedia_transport *tp)\n{\n    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;\n\n    PJ_ASSERT_RETURN(tp, PJ_EINVAL);\n\n    PJ_LOG(4, (THIS_FILE, \"Destroy - encrypted packets: %ld, decrypted packets: %ld\",\n               zrtp->protect, zrtp->unprotect));\n\n    /* close the slave transport in case */\n    if (zrtp->close_slave && zrtp->slave_tp)\n        pjmedia_transport_close(zrtp->slave_tp);\n\n    /* Self destruct.. */\n    zrtp_stopZrtpEngine(zrtp->zrtpCtx);\n    zrtp_DestroyWrapper(zrtp->zrtpCtx);\n    zrtp->zrtpCtx = NULL;\n\n    /* In case mutex is being acquired by other thread */\n    pj_mutex_lock(zrtp->zrtpMutex);\n    pj_mutex_unlock(zrtp->zrtpMutex);\n    pj_mutex_destroy(zrtp->zrtpMutex);\n\n    pj_pool_release(zrtp->pool);\n\n    return PJ_SUCCESS;\n}\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/types.c",
    "content": "/* $Id: types.c 4411 2013-03-04 04:34:38Z nanang $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia/types.h>\n#include <pj/assert.h>\n\n/**\n * Utility function to return the string name for a pjmedia_type.\n *\n * @param t\t\tThe media type.\n *\n * @return\t\tString.\n */\nPJ_DEF(const char*) pjmedia_type_name(pjmedia_type t)\n{\n    const char *type_names[] = {\n\t\"none\",\n\t\"audio\",\n\t\"video\",\n\t\"application\",\n\t\"unknown\"\n    };\n\n    pj_assert(t < (int)PJ_ARRAY_SIZE(type_names));\n    pj_assert(PJMEDIA_TYPE_UNKNOWN == 4);\n\n    if (t < (int)PJ_ARRAY_SIZE(type_names))\n\treturn type_names[t];\n    else\n\treturn \"??\";\n}\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/vid_codec.c",
    "content": "/* $Id: vid_codec.c 4008 2012-04-03 04:03:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/vid_codec.h>\n#include <pjmedia/errno.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/string.h>\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n\n#define THIS_FILE   \"vid_codec.c\"\n\nstatic pjmedia_vid_codec_mgr *def_vid_codec_mgr;\n\n\n/* Definition of default codecs parameters */\ntypedef struct pjmedia_vid_codec_default_param\n{\n    pj_pool_t\t\t\t*pool;\n    pjmedia_vid_codec_param\t*param;\n} pjmedia_vid_codec_default_param;\n\n\n/*\n * Codec manager maintains array of these structs for each supported\n * codec.\n */\ntypedef struct pjmedia_vid_codec_desc\n{\n    pjmedia_vid_codec_info\t     info;\t/**< Codec info.\t    */\n    pjmedia_codec_id\t             id;        /**< Fully qualified name   */\n    pjmedia_codec_priority           prio;      /**< Priority.\t\t    */\n    pjmedia_vid_codec_factory       *factory;\t/**< The factory.\t    */\n    pjmedia_vid_codec_default_param *def_param; /**< Default codecs \n\t\t\t\t\t             parameters.\t    */\n} pjmedia_vid_codec_desc;\n\n\n/* The declaration of video codec manager */\nstruct pjmedia_vid_codec_mgr\n{\n    /** Pool factory instance. */\n    pj_pool_factory\t\t*pf;\n\n    /** Codec manager mutex. */\n    pj_mutex_t\t\t\t*mutex;\n\n    /** List of codec factories registered to codec manager. */\n    pjmedia_vid_codec_factory\t factory_list;\n\n    /** Number of supported codecs. */\n    unsigned\t\t\t codec_cnt;\n\n    /** Array of codec descriptor. */\n    pjmedia_vid_codec_desc\t codec_desc[PJMEDIA_CODEC_MGR_MAX_CODECS];\n\n};\n\n\n\n/* Sort codecs in codec manager based on priorities */\nstatic void sort_codecs(pjmedia_vid_codec_mgr *mgr);\n\n\n/*\n * Duplicate video codec parameter.\n */\nPJ_DEF(pjmedia_vid_codec_param*) pjmedia_vid_codec_param_clone(\n\t\t\t\t\tpj_pool_t *pool, \n\t\t\t\t\tconst pjmedia_vid_codec_param *src)\n{\n    pjmedia_vid_codec_param *p;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(pool && src, NULL);\n\n    p = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_codec_param);\n\n    /* Update codec param */\n    pj_memcpy(p, src, sizeof(pjmedia_vid_codec_param));\n    for (i = 0; i < src->dec_fmtp.cnt; ++i) {\n\tpj_strdup(pool, &p->dec_fmtp.param[i].name, \n\t\t  &src->dec_fmtp.param[i].name);\n\tpj_strdup(pool, &p->dec_fmtp.param[i].val, \n\t\t  &src->dec_fmtp.param[i].val);\n    }\n    for (i = 0; i < src->enc_fmtp.cnt; ++i) {\n\tpj_strdup(pool, &p->enc_fmtp.param[i].name, \n\t\t  &src->enc_fmtp.param[i].name);\n\tpj_strdup(pool, &p->enc_fmtp.param[i].val, \n\t\t  &src->enc_fmtp.param[i].val);\n    }\n\n    return p;\n}\n\n/*\n * Initialize codec manager.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_create(\n                                            pj_pool_t *pool,\n                                            pjmedia_vid_codec_mgr **p_mgr)\n{\n    pjmedia_vid_codec_mgr *mgr;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool, PJ_EINVAL);\n\n    mgr = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_codec_mgr);\n    mgr->pf = pool->factory;\n    pj_list_init (&mgr->factory_list);\n    mgr->codec_cnt = 0;\n\n    /* Create mutex */\n    status = pj_mutex_create_recursive(pool, \"vid-codec-mgr\", &mgr->mutex);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (!def_vid_codec_mgr)\n        def_vid_codec_mgr = mgr;\n\n    if (p_mgr)\n        *p_mgr = mgr;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Initialize codec manager.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_destroy (pjmedia_vid_codec_mgr *mgr)\n{\n    if (!mgr) mgr = def_vid_codec_mgr;\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    /* Destroy mutex */\n    if (mgr->mutex)\n\tpj_mutex_destroy(mgr->mutex);\n\n    /* Just for safety, set codec manager states to zero */\n    pj_bzero(mgr, sizeof(pjmedia_vid_codec_mgr));\n\n    if (mgr == def_vid_codec_mgr)\n        def_vid_codec_mgr = NULL;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pjmedia_vid_codec_mgr*) pjmedia_vid_codec_mgr_instance(void)\n{\n    //pj_assert(def_vid_codec_mgr);\n    return def_vid_codec_mgr;\n}\n\nPJ_DEF(void) pjmedia_vid_codec_mgr_set_instance(pjmedia_vid_codec_mgr* mgr)\n{\n    def_vid_codec_mgr = mgr;\n}\n\n\n/*\n * Register a codec factory.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_register_factory(\n                                    pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t    pjmedia_vid_codec_factory *factory)\n{\n    pjmedia_vid_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS];\n    unsigned i, count;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(factory, PJ_EINVAL);\n\n    if (!mgr) mgr = def_vid_codec_mgr;\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    /* Enum codecs */\n    count = PJ_ARRAY_SIZE(info);\n    status = factory->op->enum_info(factory, &count, info);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_mutex_lock(mgr->mutex);\n\n    /* Check codec count */\n    if (count + mgr->codec_cnt > PJ_ARRAY_SIZE(mgr->codec_desc)) {\n\tpj_mutex_unlock(mgr->mutex);\n\treturn PJ_ETOOMANY;\n    }\n\n\n    /* Save the codecs */\n    for (i=0; i<count; ++i) {\n\tpj_memcpy( &mgr->codec_desc[mgr->codec_cnt+i],\n\t\t   &info[i], sizeof(pjmedia_vid_codec_info));\n\tmgr->codec_desc[mgr->codec_cnt+i].prio = PJMEDIA_CODEC_PRIO_NORMAL;\n\tmgr->codec_desc[mgr->codec_cnt+i].factory = factory;\n\tpjmedia_vid_codec_info_to_id( &info[i],\n\t\t\t\t  mgr->codec_desc[mgr->codec_cnt+i].id,\n\t\t\t\t  sizeof(pjmedia_codec_id));\n    }\n\n    /* Update count */\n    mgr->codec_cnt += count;\n\n    /* Re-sort codec based on priorities */\n    sort_codecs(mgr);\n\n    /* Add factory to the list */\n    pj_list_push_back(&mgr->factory_list, factory);\n\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Unregister a codec factory.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_unregister_factory(\n\t\t\t\tpjmedia_vid_codec_mgr *mgr, \n\t\t\t\tpjmedia_vid_codec_factory *factory)\n{\n    unsigned i;\n    PJ_ASSERT_RETURN(factory, PJ_EINVAL);\n\n    if (!mgr) mgr = def_vid_codec_mgr;\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    pj_mutex_lock(mgr->mutex);\n\n    /* Factory must be registered. */\n    if (pj_list_find_node(&mgr->factory_list, factory) != factory) {\n\tpj_mutex_unlock(mgr->mutex);\n\treturn PJ_ENOTFOUND;\n    }\n\n    /* Erase factory from the factory list */\n    pj_list_erase(factory);\n\n\n    /* Remove all supported codecs from the codec manager that were created \n     * by the specified factory.\n     */\n    for (i=0; i<mgr->codec_cnt; ) {\n\n\tif (mgr->codec_desc[i].factory == factory) {\n\t    /* Remove the codec from array of codec descriptions */\n\t    pj_array_erase(mgr->codec_desc, sizeof(mgr->codec_desc[0]), \n\t\t\t   mgr->codec_cnt, i);\n\t    --mgr->codec_cnt;\n\n\t} else {\n\t    ++i;\n\t}\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Enum all codecs.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_enum_codecs(\n                                pjmedia_vid_codec_mgr *mgr, \n\t\t\t        unsigned *count, \n\t\t\t        pjmedia_vid_codec_info codecs[],\n\t\t\t        unsigned *prio)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(count && codecs, PJ_EINVAL);\n\n    if (!mgr) mgr = def_vid_codec_mgr;\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    pj_mutex_lock(mgr->mutex);\n\n    if (*count > mgr->codec_cnt)\n\t*count = mgr->codec_cnt;\n    \n    for (i=0; i<*count; ++i) {\n\tpj_memcpy(&codecs[i], \n\t\t  &mgr->codec_desc[i].info, \n\t\t  sizeof(pjmedia_vid_codec_info));\n    }\n\n    if (prio) {\n\tfor (i=0; i < *count; ++i)\n\t    prio[i] = mgr->codec_desc[i].prio;\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get codec info for the specified payload type.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_get_codec_info(\n                                    pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t    unsigned pt,\n\t\t\t\t    const pjmedia_vid_codec_info **p_info)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(p_info, PJ_EINVAL);\n\n    if (!mgr) mgr = def_vid_codec_mgr;\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    pj_mutex_lock(mgr->mutex);\n\n    for (i=0; i<mgr->codec_cnt; ++i) {\n\tif (mgr->codec_desc[i].info.pt == pt) {\n\t    *p_info = &mgr->codec_desc[i].info;\n\n\t    pj_mutex_unlock(mgr->mutex);\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJMEDIA_CODEC_EUNSUP;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_get_codec_info2(\n\t\t\t\t    pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t    pjmedia_format_id fmt_id,\n\t\t\t\t    const pjmedia_vid_codec_info **p_info)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(p_info, PJ_EINVAL);\n\n    if (!mgr) mgr = def_vid_codec_mgr;\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    pj_mutex_lock(mgr->mutex);\n\n    for (i=0; i<mgr->codec_cnt; ++i) {\n\tif (mgr->codec_desc[i].info.fmt_id == fmt_id) {\n\t    *p_info = &mgr->codec_desc[i].info;\n\n\t    pj_mutex_unlock(mgr->mutex);\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJMEDIA_CODEC_EUNSUP;\n}\n\n\n/*\n * Convert codec info struct into a unique codec identifier.\n * A codec identifier looks something like \"H263/34\".\n */\nPJ_DEF(char*) pjmedia_vid_codec_info_to_id(\n                                        const pjmedia_vid_codec_info *info,\n\t\t\t\t        char *id, unsigned max_len )\n{\n    int len;\n\n    PJ_ASSERT_RETURN(info && id && max_len, NULL);\n\n    len = pj_ansi_snprintf(id, max_len, \"%.*s/%u\",\n\t\t\t   (int)info->encoding_name.slen,\n\t\t\t   info->encoding_name.ptr,\n\t\t\t   info->pt);\n\n    if (len < 1 || len >= (int)max_len) {\n\tid[0] = '\\0';\n\treturn NULL;\n    }\n\n    return id;\n}\n\n\n/*\n * Find codecs by the unique codec identifier. This function will find\n * all codecs that match the codec identifier prefix. For example, if\n * \"L16\" is specified, then it will find \"L16/8000/1\", \"L16/16000/1\",\n * and so on, up to the maximum count specified in the argument.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_find_codecs_by_id(\n                                     pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t     const pj_str_t *codec_id,\n\t\t\t\t     unsigned *count,\n\t\t\t\t     const pjmedia_vid_codec_info *p_info[],\n\t\t\t\t     unsigned prio[])\n{\n    unsigned i, found = 0;\n\n    PJ_ASSERT_RETURN(codec_id && count && *count, PJ_EINVAL);\n\n    if (!mgr) mgr = def_vid_codec_mgr;\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    pj_mutex_lock(mgr->mutex);\n\n    for (i=0; i<mgr->codec_cnt; ++i) {\n\n\tif (codec_id->slen == 0 ||\n\t    pj_strnicmp2(codec_id, mgr->codec_desc[i].id, \n\t\t\t codec_id->slen) == 0) \n\t{\n\n\t    if (p_info)\n\t\tp_info[found] = &mgr->codec_desc[i].info;\n\t    if (prio)\n\t\tprio[found] = mgr->codec_desc[i].prio;\n\n\t    ++found;\n\n\t    if (found >= *count)\n\t\tbreak;\n\t}\n\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n    *count = found;\n\n    return found ? PJ_SUCCESS : PJ_ENOTFOUND;\n}\n\n\n/* Swap two codecs positions in codec manager */\nstatic void swap_codec(pjmedia_vid_codec_mgr *mgr, unsigned i, unsigned j)\n{\n    pjmedia_vid_codec_desc tmp;\n\n    pj_memcpy(&tmp, &mgr->codec_desc[i], sizeof(pjmedia_vid_codec_desc));\n\n    pj_memcpy(&mgr->codec_desc[i], &mgr->codec_desc[j], \n\t       sizeof(pjmedia_vid_codec_desc));\n\n    pj_memcpy(&mgr->codec_desc[j], &tmp, sizeof(pjmedia_vid_codec_desc));\n}\n\n\n/* Sort codecs in codec manager based on priorities */\nstatic void sort_codecs(pjmedia_vid_codec_mgr *mgr)\n{\n    unsigned i;\n\n   /* Re-sort */\n    for (i=0; i<mgr->codec_cnt; ++i) {\n\tunsigned j, max;\n\n\tfor (max=i, j=i+1; j<mgr->codec_cnt; ++j) {\n\t    if (mgr->codec_desc[j].prio > mgr->codec_desc[max].prio)\n\t\tmax = j;\n\t}\n\n\tif (max != i)\n\t    swap_codec(mgr, i, max);\n    }\n\n    /* Change PJMEDIA_CODEC_PRIO_HIGHEST codecs to NEXT_HIGHER */\n    for (i=0; i<mgr->codec_cnt; ++i) {\n\tif (mgr->codec_desc[i].prio == PJMEDIA_CODEC_PRIO_HIGHEST)\n\t    mgr->codec_desc[i].prio = PJMEDIA_CODEC_PRIO_NEXT_HIGHER;\n\telse\n\t    break;\n    }\n}\n\n\n/**\n * Set codec priority. The codec priority determines the order of\n * the codec in the SDP created by the endpoint. If more than one codecs\n * are found with the same codec_id prefix, then the function sets the\n * priorities of all those codecs.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_set_codec_priority(\n\t\t\t\tpjmedia_vid_codec_mgr *mgr, \n\t\t\t\tconst pj_str_t *codec_id,\n\t\t\t\tpj_uint8_t prio)\n{\n    unsigned i, found = 0;\n\n    PJ_ASSERT_RETURN(codec_id, PJ_EINVAL);\n\n    if (!mgr) mgr = def_vid_codec_mgr;\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    pj_mutex_lock(mgr->mutex);\n\n    /* Update the priorities of affected codecs */\n    for (i=0; i<mgr->codec_cnt; ++i) \n    {\n\tif (codec_id->slen == 0 ||\n\t    pj_strnicmp2(codec_id, mgr->codec_desc[i].id, \n\t\t\t codec_id->slen) == 0) \n\t{\n\t    mgr->codec_desc[i].prio = (pjmedia_codec_priority) prio;\n\t    ++found;\n\t}\n    }\n\n    if (!found) {\n\tpj_mutex_unlock(mgr->mutex);\n\treturn PJ_ENOTFOUND;\n    }\n\n    /* Re-sort codecs */\n    sort_codecs(mgr);\n\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Allocate one codec.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_alloc_codec(\n                                        pjmedia_vid_codec_mgr *mgr, \n\t\t\t\t\tconst pjmedia_vid_codec_info *info,\n\t\t\t\t\tpjmedia_vid_codec **p_codec)\n{\n    pjmedia_vid_codec_factory *factory;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(info && p_codec, PJ_EINVAL);\n\n    if (!mgr) mgr = def_vid_codec_mgr;\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    *p_codec = NULL;\n\n    pj_mutex_lock(mgr->mutex);\n\n    factory = mgr->factory_list.next;\n    while (factory != &mgr->factory_list) {\n\n\tif ( (*factory->op->test_alloc)(factory, info) == PJ_SUCCESS ) {\n\n\t    status = (*factory->op->alloc_codec)(factory, info, p_codec);\n\t    if (status == PJ_SUCCESS) {\n\t\tpj_mutex_unlock(mgr->mutex);\n\t\treturn PJ_SUCCESS;\n\t    }\n\n\t}\n\n\tfactory = factory->next;\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n    return PJMEDIA_CODEC_EUNSUP;\n}\n\n\n/*\n * Get default codec parameter.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_get_default_param(\n                                        pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t\tconst pjmedia_vid_codec_info *info,\n\t\t\t\t\tpjmedia_vid_codec_param *param )\n{\n    pjmedia_vid_codec_factory *factory;\n    pj_status_t status;\n    pjmedia_codec_id codec_id;\n    pjmedia_vid_codec_desc *codec_desc = NULL;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(info && param, PJ_EINVAL);\n\n    if (!mgr) mgr = def_vid_codec_mgr;\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    if (!pjmedia_vid_codec_info_to_id(info, (char*)&codec_id, \n                                      sizeof(codec_id)))\n\treturn PJ_EINVAL;\n\n    pj_mutex_lock(mgr->mutex);\n\n    /* First, lookup default param in codec desc */\n    for (i=0; i < mgr->codec_cnt; ++i) {\n\tif (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) {\n\t    codec_desc = &mgr->codec_desc[i];\n\t    break;\n\t}\n    }\n\n    /* If we found the codec and its default param is set, return it */\n    if (codec_desc && codec_desc->def_param) {\n\tpj_memcpy(param, codec_desc->def_param->param, \n\t\t  sizeof(pjmedia_vid_codec_param));\n\n\tpj_mutex_unlock(mgr->mutex);\n\treturn PJ_SUCCESS;\n    }\n\n    /* Otherwise query the default param from codec factory */\n    factory = mgr->factory_list.next;\n    while (factory != &mgr->factory_list) {\n\n\tif ( (*factory->op->test_alloc)(factory, info) == PJ_SUCCESS ) {\n\n\t    status = (*factory->op->default_attr)(factory, info, param);\n\t    if (status == PJ_SUCCESS) {\n\t\t/* Check for invalid max_bps. */\n\t\t//if (param->info.max_bps < param->info.avg_bps)\n\t\t//    param->info.max_bps = param->info.avg_bps;\n\n\t\tpj_mutex_unlock(mgr->mutex);\n\t\treturn PJ_SUCCESS;\n\t    }\n\n\t}\n\n\tfactory = factory->next;\n    }\n\n    pj_mutex_unlock(mgr->mutex);\n\n\n    return PJMEDIA_CODEC_EUNSUP;\n}\n\n\n/*\n * Set default codec parameter.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_set_default_param( \n\t\t\t\t\t    pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t\t    const pjmedia_vid_codec_info *info,\n\t\t\t\t\t    const pjmedia_vid_codec_param *param )\n{\n    unsigned i;\n    pjmedia_codec_id codec_id;\n    pjmedia_vid_codec_desc *codec_desc = NULL;\n    pj_pool_t *pool, *old_pool = NULL;\n    pjmedia_vid_codec_default_param *p;\n\n    PJ_ASSERT_RETURN(info, PJ_EINVAL);\n\n    if (!mgr) mgr = def_vid_codec_mgr;\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    if (!pjmedia_vid_codec_info_to_id(info, (char*)&codec_id, sizeof(codec_id)))\n\treturn PJ_EINVAL;\n\n    pj_mutex_lock(mgr->mutex);\n\n    /* Lookup codec desc */\n    for (i=0; i < mgr->codec_cnt; ++i) {\n\tif (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) {\n\t    codec_desc = &mgr->codec_desc[i];\n\t    break;\n\t}\n    }\n\n    /* Codec not found */\n    if (!codec_desc) {\n\tpj_mutex_unlock(mgr->mutex);\n\treturn PJMEDIA_CODEC_EUNSUP;\n    }\n\n    /* If codec param is previously set */\n    if (codec_desc->def_param) {\n\tpj_assert(codec_desc->def_param->pool);\n        old_pool = codec_desc->def_param->pool;\n\tcodec_desc->def_param = NULL;\n    }\n\n    /* When param is set to NULL, i.e: setting default codec param to library\n     * default setting, just return PJ_SUCCESS.\n     */\n    if (NULL == param) {\n\tpj_mutex_unlock(mgr->mutex);\n        if (old_pool)\n\t    pj_pool_release(old_pool);\n\treturn PJ_SUCCESS;\n    }\n\n    /* Create new default codec param instance */\n    pool = pj_pool_create(mgr->pf, (char*)codec_id, 256, 256, NULL);\n    codec_desc->def_param = PJ_POOL_ZALLOC_T(pool,\n\t\t\t\t\t     pjmedia_vid_codec_default_param);\n    p = codec_desc->def_param;\n    p->pool = pool;\n\n    /* Update codec default param */\n    p->param = pjmedia_vid_codec_param_clone(pool, param);\n    if (!p->param) {\n\tpj_mutex_unlock(mgr->mutex);\n\treturn PJ_EINVAL;\n    }\n\n    codec_desc->def_param = p;\n\n    pj_mutex_unlock(mgr->mutex);\n\n    /* Release old pool at the very end, as application tends to apply changes\n     * to the existing/old codec param fetched using\n     * pjmedia_vid_codec_mgr_get_default_param() which doesn't do deep clone.\n     */\n    if (old_pool)\n\tpj_pool_release(old_pool);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Dealloc codec.\n */\nPJ_DEF(pj_status_t)\npjmedia_vid_codec_mgr_dealloc_codec(pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t    pjmedia_vid_codec *codec)\n{\n    PJ_ASSERT_RETURN(codec, PJ_EINVAL);\n\n    if (!mgr) mgr = def_vid_codec_mgr;\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    return (*codec->factory->op->dealloc_codec)(codec->factory, codec);\n}\n\n\n#endif /* PJMEDIA_HAS_VIDEO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/vid_codec_util.c",
    "content": "/* $Id: vid_codec_util.c 4362 2013-02-21 14:51:56Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/vid_codec_util.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/stream_common.h>\n#include <pjlib-util/base64.h>\n#include <pj/ctype.h>\n#include <pj/math.h>\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n\n#define THIS_FILE   \"vid_codec_util.c\"\n\n/* If this is set to non-zero, H.264 custom negotiation will require\n * \"profile-level-id\" and \"packetization-mode\" to be exact match to\n * get a successful negotiation. Note that flexible answer (updating\n * SDP answer to match remote offer) is always active regardless the\n * value of this macro.\n */\n#define H264_STRICT_SDP_NEGO\t    0\n\n/* Default frame rate, if not specified */\n#define DEFAULT_H264_FPS_NUM\t    10\n#define DEFAULT_H264_FPS_DENUM\t    1\n\n/* Default aspect ratio, if not specified */\n#define DEFAULT_H264_RATIO_NUM\t    4\n#define DEFAULT_H264_RATIO_DENUM    3\n\n\n/* ITU resolution definition */\nstruct mpi_resolution_t\n{\n    pj_str_t\t\tname;    \n    pjmedia_rect_size\tsize;\n}\nmpi_resolutions [] =\n{\n    {{\"CIF\",3},     {352,288}},\n    {{\"QCIF\",4},    {176,144}},\n    {{\"SQCIF\",5},   {88,72}},\n    {{\"CIF4\",4},    {704,576}},\n    {{\"CIF16\",5},   {1408,1142}},\n};\n\n\n#define CALC_H264_MB_NUM(size) (((size.w+15)/16)*((size.h+15)/16))\n#define CALC_H264_MBPS(size,fps) CALC_H264_MB_NUM(size)*fps.num/fps.denum\n\n\n/* Parse fmtp value for custom resolution, e.g: \"CUSTOM=800,600,2\" */\nstatic pj_status_t parse_custom_res_fmtp(const pj_str_t *fmtp_val,\n\t\t\t\t\t pjmedia_rect_size *size,\n\t\t\t\t\t unsigned *mpi)\n{\n    const char *p, *p_end;\n    pj_str_t token;\n    unsigned long val[3] = {0};\n    unsigned i = 0;\n\n    p = token.ptr = fmtp_val->ptr;\n    p_end = p + fmtp_val->slen;\n\n    while (p<=p_end && i<PJ_ARRAY_SIZE(val)) {\n\tif (*p==',' || p==p_end) {\n\t    token.slen = (char*)p - token.ptr;\n\t    val[i++] = pj_strtoul(&token);\n\t    token.ptr = (char*)p+1;\n\t}\n\t++p;\n    }\n\n    if (!val[0] || !val[1])\n\treturn PJ_ETOOSMALL;\n\n    if (val[2]<1 || val[2]>32)\n\treturn PJ_EINVAL;\n\n    size->w = val[0];\n    size->h = val[1];\n    *mpi = val[2];\n    return PJ_SUCCESS;\n}\n\n\n/* H263 fmtp parser */\nPJ_DEF(pj_status_t) pjmedia_vid_codec_parse_h263_fmtp(\n\t\t\t\t    const pjmedia_codec_fmtp *fmtp,\n\t\t\t\t    pjmedia_vid_codec_h263_fmtp *h263_fmtp)\n{\n    const pj_str_t CUSTOM = {\"CUSTOM\", 6};\n    unsigned i;\n\n    pj_bzero(h263_fmtp, sizeof(*h263_fmtp));\n\n    for (i=0; i<fmtp->cnt; ++i) {\n\tunsigned j;\n\tpj_bool_t parsed = PJ_FALSE;\n\n\tif (h263_fmtp->mpi_cnt >= PJ_ARRAY_SIZE(h263_fmtp->mpi)) {\n\t    pj_assert(!\"Too small MPI array in H263 fmtp\");\n\t    continue;\n\t}\n\n\t/* Standard size MPIs */\n\tfor (j=0; j<PJ_ARRAY_SIZE(mpi_resolutions) && !parsed; ++j) {\n\t    if (pj_stricmp(&fmtp->param[i].name, &mpi_resolutions[j].name)==0)\n\t    {\n\t\tunsigned mpi;\n\n\t\tmpi = pj_strtoul(&fmtp->param[i].val);\n\t\tif (mpi<1 || mpi>32)\n\t\t    return PJMEDIA_SDP_EINFMTP;\n\n\t\th263_fmtp->mpi[h263_fmtp->mpi_cnt].size = \n\t\t\t\t\t\t    mpi_resolutions[j].size;\n\t\th263_fmtp->mpi[h263_fmtp->mpi_cnt].val = mpi;\n\t\t++h263_fmtp->mpi_cnt;\n\t\tparsed = PJ_TRUE;\n\t    }\n\t}\n\tif (parsed)\n\t    continue;\n\n\t/* Custom size MPIs */\n\tif (pj_stricmp(&fmtp->param[i].name, &CUSTOM)==0) {\n\t    pjmedia_rect_size size;\n\t    unsigned mpi;\n\t    pj_status_t status;\n\n\t    status = parse_custom_res_fmtp(&fmtp->param[i].val, &size, &mpi);\n\t    if (status != PJ_SUCCESS)\n\t\treturn PJMEDIA_SDP_EINFMTP;\n\n\t    h263_fmtp->mpi[h263_fmtp->mpi_cnt].size = size;\n\t    h263_fmtp->mpi[h263_fmtp->mpi_cnt].val = mpi;\n\t    ++h263_fmtp->mpi_cnt;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nstatic unsigned fps_to_mpi(const pjmedia_ratio *fps) \n{\n    unsigned mpi;\n\n    /* Original formula = (fps->denum * 30000) / (fps->num * 1001) */\n    mpi = (fps->denum*30000 + fps->num*1001/2) / (fps->num*1001);\n    \n    /* Normalize, should be in the range of 1-32 */\n    if (mpi > 32) mpi = 32;\n    if (mpi < 1) mpi = 1;\n\n    return mpi;\n};\n\nPJ_DEF(pj_status_t) pjmedia_vid_codec_h263_apply_fmtp(\n\t\t\t\tpjmedia_vid_codec_param *param)\n{\n    if (param->dir & PJMEDIA_DIR_ENCODING) {\n\tpjmedia_vid_codec_h263_fmtp fmtp_loc, fmtp_rem;\n\tpjmedia_rect_size size = {0};\n\tunsigned mpi = 0;\n\tpjmedia_video_format_detail *vfd;\n\tpj_status_t status;\n\n\tvfd = pjmedia_format_get_video_format_detail(&param->enc_fmt,\n\t\t\t\t\t\t     PJ_TRUE);\n\n\t/* Get local param */\n\t// Local param should be fetched from \"param->enc_fmt\" instead of\n\t// \"param->dec_fmtp\".\n\t//status = pjmedia_vid_codec_parse_h263_fmtp(&param->dec_fmtp,\n\t//\t\t\t\t\t   &fmtp_loc);\n\t//if (status != PJ_SUCCESS)\n\t//    return status;\n\tfmtp_loc.mpi_cnt = 1;\n\tfmtp_loc.mpi[0].size = vfd->size;\n\tfmtp_loc.mpi[0].val  = fps_to_mpi(&vfd->fps);\n\n\t/* Get remote param */\n\tstatus = pjmedia_vid_codec_parse_h263_fmtp(&param->enc_fmtp,\n\t\t\t\t\t\t   &fmtp_rem);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Negotiate size & MPI setting */\n\tif (fmtp_rem.mpi_cnt == 0) {\n\t    /* Remote doesn't specify MPI setting, send QCIF=1 */\n\t    size.w = 176;\n\t    size.h = 144;\n\t    mpi\t   = 1;\n\t//} else if (fmtp_loc.mpi_cnt == 0) {\n\t//    /* Local MPI setting not set, just use remote preference. */\n\t//    size = fmtp_rem.mpi[0].size;\n\t//    mpi  = fmtp_rem.mpi[0].val;\n\t} else {\n\t    /* Both have preferences, let's try to match them */\n\t    unsigned i, j;\n\t    pj_bool_t matched = PJ_FALSE;\n\t    pj_uint32_t min_diff = 0xFFFFFFFF;\n\t    pj_uint32_t loc_sq, rem_sq, diff;\n\n\t    /* Find the exact size match or the closest size, then choose\n\t     * the highest MPI among the match/closest pair.\n\t     */\n\t    for (i = 0; i < fmtp_rem.mpi_cnt && !matched; ++i) {\n\t\trem_sq = fmtp_rem.mpi[i].size.w * fmtp_rem.mpi[i].size.h;\n\t\tfor (j = 0; j < fmtp_loc.mpi_cnt; ++j) {\n\t\t    /* See if we got exact match */\n\t\t    if (fmtp_rem.mpi[i].size.w == fmtp_loc.mpi[j].size.w &&\n\t\t\tfmtp_rem.mpi[i].size.h == fmtp_loc.mpi[j].size.h)\n\t\t    {\n\t\t\tsize = fmtp_rem.mpi[i].size;\n\t\t\tmpi  = PJ_MAX(fmtp_rem.mpi[i].val,\n\t\t\t\t      fmtp_loc.mpi[j].val);\n\t\t\tmatched = PJ_TRUE;\n\t\t\tbreak;\n\t\t    }\n\n\t\t    /* Otherwise keep looking for the closest match */\n\t\t    loc_sq = fmtp_loc.mpi[j].size.w * fmtp_loc.mpi[j].size.h;\n\t\t    diff = loc_sq>rem_sq? (loc_sq-rem_sq):(rem_sq-loc_sq);\n\t\t    if (diff < min_diff) {\n\t\t\tsize = rem_sq<loc_sq? fmtp_rem.mpi[i].size :\n\t\t\t\t\t      fmtp_loc.mpi[j].size;\n\t\t\tmpi  = PJ_MAX(fmtp_rem.mpi[i].val,\n\t\t\t\t      fmtp_loc.mpi[j].val);\n\t\t    }\n\t\t}\n\t    }\n\t}\n\n\t/* Apply the negotiation result */\n\tvfd->size = size;\n\tvfd->fps.num = 30000;\n\tvfd->fps.denum = 1001 * mpi;\n    }\n\n    if (param->dir & PJMEDIA_DIR_DECODING) {\n\t/* Here we just want to find the highest resolution and the lowest MPI\n\t * we support and set it as the decoder param.\n\t */\n\tpjmedia_vid_codec_h263_fmtp fmtp;\n\tpjmedia_video_format_detail *vfd;\n\tpj_status_t status;\n\t\n\tstatus = pjmedia_vid_codec_parse_h263_fmtp(&param->dec_fmtp,\n\t\t\t\t\t\t   &fmtp);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tvfd = pjmedia_format_get_video_format_detail(&param->dec_fmt,\n\t\t\t\t\t\t     PJ_TRUE);\n\n\tif (fmtp.mpi_cnt == 0) {\n\t    /* No resolution specified, lets just assume 4CIF=1! */\n\t    vfd->size.w = 704;\n\t    vfd->size.h = 576;\n\t    vfd->fps.num = 30000;\n\t    vfd->fps.denum = 1001;\n\t} else {\n\t    unsigned i, max_size = 0, max_size_idx = 0, min_mpi = 32;\n\t    \n\t    /* Get the largest size and the lowest MPI */\n\t    for (i = 0; i < fmtp.mpi_cnt; ++i) {\n\t\tif (fmtp.mpi[i].size.w * fmtp.mpi[i].size.h > max_size) {\n\t\t    max_size = fmtp.mpi[i].size.w * fmtp.mpi[i].size.h;\n\t\t    max_size_idx = i;\n\t\t}\n\t\tif (fmtp.mpi[i].val < min_mpi)\n\t\t    min_mpi = fmtp.mpi[i].val;\n\t    }\n\n\t    vfd->size = fmtp.mpi[max_size_idx].size;\n\t    vfd->fps.num = 30000;\n\t    vfd->fps.denum = 1001 * min_mpi;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* Declaration of H.264 level info */\ntypedef struct h264_level_info_t\n{\n    unsigned id;\t    /* Level id.\t\t\t*/\n    unsigned max_mbps;\t    /* Max macroblocks per second.\t*/\n    unsigned max_mb;\t    /* Max macroblocks.\t\t\t*/\n    unsigned max_br;\t    /* Max bitrate (kbps).\t\t*/\n} h264_level_info_t;\n\n\n/* Init H264 parameters based on profile-level-id */\nstatic pj_status_t init_h264_profile(const pj_str_t *profile,\n\t\t\t\t     pjmedia_vid_codec_h264_fmtp *fmtp)\n{\n    const h264_level_info_t level_info[] =\n    {\n\t{ 10,   1485,    99,     64 },\n\t{ 9,    1485,    99,    128 }, /*< level 1b */\n\t{ 11,   3000,   396,    192 },\n\t{ 12,   6000,   396,    384 },\n\t{ 13,  11880,   396,    768 },\n\t{ 20,  11880,   396,   2000 },\n\t{ 21,  19800,   792,   4000 },\n\t{ 22,  20250,  1620,   4000 },\n\t{ 30,  40500,  1620,  10000 },\n\t{ 31, 108000,  3600,  14000 },\n\t{ 32, 216000,  5120,  20000 },\n\t{ 40, 245760,  8192,  20000 },\n\t{ 41, 245760,  8192,  50000 },\n\t{ 42, 522240,  8704,  50000 },\n\t{ 50, 589824, 22080, 135000 },\n\t{ 51, 983040, 36864, 240000 },\n    };\n    unsigned i, tmp;\n    pj_str_t endst;\n    const h264_level_info_t *li = NULL;\n\n    if (profile->slen != 6)\n\treturn PJMEDIA_SDP_EINFMTP;\n\n    tmp = pj_strtoul2(profile, &endst, 16);\n    if (endst.slen)\n\treturn PJMEDIA_SDP_EINFMTP;\n\n    fmtp->profile_idc = (pj_uint8_t)((tmp >> 16) & 0xFF);\n    fmtp->profile_iop = (pj_uint8_t)((tmp >> 8) & 0xFF);\n    fmtp->level = (pj_uint8_t)(tmp & 0xFF);\n\n    for (i = 0; i < PJ_ARRAY_SIZE(level_info); ++i) {\n\tif (level_info[i].id == fmtp->level) {\n\t    li = &level_info[i];\n\t    break;\n\t}\n    }\n    if (li == NULL)\n\treturn PJMEDIA_SDP_EINFMTP;\n\n    /* Init profile level spec */\n    if (fmtp->max_br == 0)\n\tfmtp->max_br = li->max_br;\n    if (fmtp->max_mbps == 0)\n\tfmtp->max_mbps = li->max_mbps;\n    if (fmtp->max_fs == 0)\n\tfmtp->max_fs = li->max_mb;\n\n    return PJ_SUCCESS;\n}\n\n\n/* H264 fmtp parser */\nPJ_DEF(pj_status_t) pjmedia_vid_codec_h264_parse_fmtp(\n\t\t\t\t    const pjmedia_codec_fmtp *fmtp,\n\t\t\t\t    pjmedia_vid_codec_h264_fmtp *h264_fmtp)\n{\n    const pj_str_t PROFILE_LEVEL_ID\t= {\"profile-level-id\", 16};\n    const pj_str_t MAX_MBPS\t\t= {\"max-mbps\", 8};\n    const pj_str_t MAX_FS\t\t= {\"max-fs\", 6};\n    const pj_str_t MAX_CPB\t\t= {\"max-cpb\", 7};\n    const pj_str_t MAX_DPB\t    \t= {\"max-dpb\", 7};\n    const pj_str_t MAX_BR\t\t= {\"max-br\", 6};\n    const pj_str_t PACKETIZATION_MODE\t= {\"packetization-mode\", 18};\n    const pj_str_t SPROP_PARAMETER_SETS = {\"sprop-parameter-sets\", 20};\n    unsigned i;\n    pj_status_t status;\n\n    pj_bzero(h264_fmtp, sizeof(*h264_fmtp));\n\n    for (i=0; i<fmtp->cnt; ++i) {\n\tunsigned tmp;\n\tif (pj_stricmp(&fmtp->param[i].name, &PROFILE_LEVEL_ID)==0) {\n\t    /* Init H264 parameters based on level, if not set yet */\n\t    status = init_h264_profile(&fmtp->param[i].val, h264_fmtp);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\t} else if (pj_stricmp(&fmtp->param[i].name, &PACKETIZATION_MODE)==0) {\n\t    tmp = pj_strtoul(&fmtp->param[i].val);\n\t    if (tmp <= 2) \n\t\th264_fmtp->packetization_mode = (pj_uint8_t)tmp;\n\t    else\n\t\treturn PJMEDIA_SDP_EINFMTP;\n\t} else if (pj_stricmp(&fmtp->param[i].name, &MAX_MBPS)==0) {\n\t    tmp = pj_strtoul(&fmtp->param[i].val);\n\t    h264_fmtp->max_mbps = PJ_MAX(tmp, h264_fmtp->max_mbps);\n\t} else if (pj_stricmp(&fmtp->param[i].name, &MAX_FS)==0) {\n\t    tmp = pj_strtoul(&fmtp->param[i].val);\n\t    h264_fmtp->max_fs = PJ_MAX(tmp, h264_fmtp->max_fs);\n\t} else if (pj_stricmp(&fmtp->param[i].name, &MAX_CPB)==0) {\n\t    tmp = pj_strtoul(&fmtp->param[i].val);\n\t    h264_fmtp->max_cpb = PJ_MAX(tmp, h264_fmtp->max_cpb);\n\t} else if (pj_stricmp(&fmtp->param[i].name, &MAX_DPB)==0) {\n\t    tmp = pj_strtoul(&fmtp->param[i].val);\n\t    h264_fmtp->max_dpb = PJ_MAX(tmp, h264_fmtp->max_dpb);\n\t} else if (pj_stricmp(&fmtp->param[i].name, &MAX_BR)==0) {\n\t    tmp = pj_strtoul(&fmtp->param[i].val);\n\t    h264_fmtp->max_br = PJ_MAX(tmp, h264_fmtp->max_br);\n\t} else if (pj_stricmp(&fmtp->param[i].name, &SPROP_PARAMETER_SETS)==0)\n\t{\n\t    pj_str_t sps_st;\n\n\t    sps_st = fmtp->param[i].val;\n\t    while (sps_st.slen) {\n\t\tpj_str_t tmp_st;\n\t\tint tmp_len;\n\t\tconst pj_uint8_t start_code[3] = {0, 0, 1};\n\t\tchar *p;\n\t\tpj_uint8_t *nal;\n\t\tpj_status_t status;\n\n\t\t/* Find field separator ',' */\n\t\ttmp_st = sps_st;\n\t\tp = pj_strchr(&sps_st, ',');\n\t\tif (p) {\n\t\t    tmp_st.slen = p - sps_st.ptr;\n\t\t    sps_st.ptr  = p+1;\n\t\t    sps_st.slen -= (tmp_st.slen+1);\n\t\t} else {\n\t\t    sps_st.slen = 0;\n\t\t}\n\n\t\t/* Decode field and build NAL unit for this param */\n\t\tnal = &h264_fmtp->sprop_param_sets[\n\t\t\t\t\t  h264_fmtp->sprop_param_sets_len];\n\t\ttmp_len = PJ_ARRAY_SIZE(h264_fmtp->sprop_param_sets) -\n\t\t\t  (int)h264_fmtp->sprop_param_sets_len -\n\t\t\t  PJ_ARRAY_SIZE(start_code);\n\t\tstatus = pj_base64_decode(&tmp_st,\n\t\t\t\t\t  nal + PJ_ARRAY_SIZE(start_code),\n\t\t\t\t\t  &tmp_len);\n\t\tif (status != PJ_SUCCESS)\n\t\t    return PJMEDIA_SDP_EINFMTP;\n\n\t\ttmp_len += PJ_ARRAY_SIZE(start_code);\n\t\tpj_memcpy(nal, start_code, PJ_ARRAY_SIZE(start_code));\n\t\th264_fmtp->sprop_param_sets_len += tmp_len;\n\t    }\n\t}\n    }\n\n    /* When profile-level-id is not specified, use default value \"42000A\" */\n    if (h264_fmtp->profile_idc == 0) {\n\tconst pj_str_t DEF_PROFILE = {\"42000A\", 6};\n\n\tstatus = init_h264_profile(&DEF_PROFILE, h264_fmtp);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_vid_codec_h264_match_sdp(pj_pool_t *pool,\n\t\t\t\t\t\t     pjmedia_sdp_media *offer,\n\t\t\t\t\t\t     unsigned o_fmt_idx,\n\t\t\t\t\t\t     pjmedia_sdp_media *answer,\n\t\t\t\t\t\t     unsigned a_fmt_idx,\n\t\t\t\t\t\t     unsigned option)\n{\n    const pj_str_t PROFILE_LEVEL_ID\t= {\"profile-level-id\", 16};\n    const pj_str_t PACKETIZATION_MODE\t= {\"packetization-mode\", 18};\n    pjmedia_codec_fmtp o_fmtp_raw, a_fmtp_raw;\n    pjmedia_vid_codec_h264_fmtp o_fmtp, a_fmtp;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(pool);\n\n    /* Parse offer */\n    status = pjmedia_stream_info_parse_fmtp(\n\t\t\t\t    NULL, offer, \n\t\t\t\t    pj_strtoul(&offer->desc.fmt[o_fmt_idx]),\n\t\t\t\t    &o_fmtp_raw);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    status = pjmedia_vid_codec_h264_parse_fmtp(&o_fmtp_raw, &o_fmtp);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Parse answer */\n    status = pjmedia_stream_info_parse_fmtp(\n\t\t\t\t    NULL, answer, \n\t\t\t\t    pj_strtoul(&answer->desc.fmt[a_fmt_idx]),\n\t\t\t\t    &a_fmtp_raw);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    status = pjmedia_vid_codec_h264_parse_fmtp(&a_fmtp_raw, &a_fmtp);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (option & PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER) {\n\tunsigned i;\n\n\t/* Flexible negotiation, adjust our answer to the offer.\n\t * Apply Postel's Principle (TM) in it's full glory.\n\t */\n\tif (a_fmtp.profile_idc != o_fmtp.profile_idc)\n\t    a_fmtp.profile_idc = o_fmtp.profile_idc;\n\tif (a_fmtp.profile_iop != o_fmtp.profile_iop)\n\t    a_fmtp.profile_iop = o_fmtp.profile_iop;\n\tif (a_fmtp.packetization_mode >= o_fmtp.packetization_mode)\n\t    a_fmtp.packetization_mode = o_fmtp.packetization_mode;\n\n\t/* Match them now */\n#if H264_STRICT_SDP_NEGO\n\tif (a_fmtp.profile_idc != o_fmtp.profile_idc ||\n\t    a_fmtp.profile_iop != o_fmtp.profile_iop ||\n\t    a_fmtp.packetization_mode != o_fmtp.packetization_mode)\n\t{\n\t    return PJMEDIA_SDP_EFORMATNOTEQUAL;\n\t}\n#else\n\tif (a_fmtp.profile_idc != o_fmtp.profile_idc)\n\t{\n\t    return PJMEDIA_SDP_EFORMATNOTEQUAL;\n\t}\n#endif\n\n\t/* Update the answer */\n\tfor (i = 0; i < a_fmtp_raw.cnt; ++i) {\n\t    if (pj_stricmp(&a_fmtp_raw.param[i].name, &PROFILE_LEVEL_ID) == 0)\n\t    {\n\t\tchar *p = a_fmtp_raw.param[i].val.ptr;\n\t\tpj_val_to_hex_digit(a_fmtp.profile_idc, p);\n\t\tp += 2;\n\t\tpj_val_to_hex_digit(a_fmtp.profile_iop, p);\n\t    }\n\t    else if (pj_stricmp(&a_fmtp_raw.param[i].name, &PACKETIZATION_MODE) == 0)\n\t    {\n\t\tchar *p = a_fmtp_raw.param[i].val.ptr;\n\t\t*p = '0' + a_fmtp.packetization_mode;\n\t    }\n\t}\n    } else {\n#if H264_STRICT_SDP_NEGO\n\t/* Strict negotiation */\n\tif (a_fmtp.profile_idc != o_fmtp.profile_idc ||\n\t    a_fmtp.profile_iop != o_fmtp.profile_iop ||\n\t    a_fmtp.packetization_mode != o_fmtp.packetization_mode)\n\t{\n\t    return PJMEDIA_SDP_EFORMATNOTEQUAL;\n\t}\n#else\n\t/* Permissive negotiation */\n\tif (a_fmtp.profile_idc != o_fmtp.profile_idc)\n\t{\n\t    return PJMEDIA_SDP_EFORMATNOTEQUAL;\n\t}\n#endif\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* Find greatest common divisor (GCD) */\nstatic unsigned gcd (unsigned a, unsigned b) {\n    unsigned c;\n    while (b) {\n\tc = a % b;\n\ta = b;\n\tb = c;\n    }\n    return a;\n}\n\n/* Find highest resolution possible for the specified H264 fmtp and\n * aspect ratio.\n */\nstatic pj_status_t find_highest_res(pjmedia_vid_codec_h264_fmtp *fmtp,\n\t\t\t\t    const pjmedia_ratio *fps,\n\t\t\t\t    const pjmedia_ratio *ratio,\n\t\t\t\t    pjmedia_rect_size *size,\n\t\t\t\t    pj_bool_t is_decoding)\n{\n    pjmedia_ratio def_ratio = { DEFAULT_H264_RATIO_NUM,\n\t\t\t        DEFAULT_H264_RATIO_DENUM };\n    pjmedia_ratio def_fps   = { DEFAULT_H264_FPS_NUM,\n\t\t\t        DEFAULT_H264_FPS_DENUM };\n    pjmedia_ratio asp_ratio, the_fps;\n    unsigned max_fs, g, scale;\n\n    pj_assert(size);\n\n    /* Get the ratio, or just use default if not provided. */\n    if (ratio && ratio->num && ratio->denum) {\n\tasp_ratio = *ratio;\n    } else {\n\tasp_ratio = def_ratio;\n    }\n\n    /* Normalize the aspect ratio */\n    g = gcd(asp_ratio.num, asp_ratio.denum);\n    asp_ratio.num /= g;\n    asp_ratio.denum /= g;\n\n    /* Get the frame rate, or just use default if not provided. */\n    if (fps && fps->num && fps->denum) {\n\tthe_fps = *fps;\n    } else {\n\tthe_fps = def_fps;\n    }\n\n    /* Calculate maximum size (in macroblocks) */\n    max_fs = fmtp->max_mbps * the_fps.denum / the_fps.num;\n    max_fs = PJ_MIN(max_fs, fmtp->max_fs);\n\n    /* Check if the specified ratio is using big numbers\n     * (not normalizable), override it!\n     */\n    if ((int)max_fs < asp_ratio.num * asp_ratio.denum) {\n        if ((int)max_fs >= def_ratio.num * def_ratio.denum)\n\t    asp_ratio = def_ratio;\n\telse\n\t    asp_ratio.num = asp_ratio.denum = 1;\n    }\n\n    /* Calculate the scale factor for size */\n    scale = pj_isqrt(max_fs / asp_ratio.denum / asp_ratio.num);\n\n    /* Calculate the size, note that the frame size is in macroblock units */\n    size->w = asp_ratio.num   * scale * 16;\n    size->h = asp_ratio.denum * scale * 16;\n\n    /* #1769: for decoding, size is usually used for allocating buffer,\n     * so we need to make sure that frame size is not less than max_fs.\n     */\n    if (is_decoding && ((size->w * size->h) >> 8) < max_fs) {\n\t/* Size is less than max_fs, recalculate using ratio 1:1 and\n\t * round up the scale.\n\t */\n\tscale = pj_isqrt(max_fs) + 1;\n\tsize->w = size->h = scale * 16;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_vid_codec_h264_apply_fmtp(\n\t\t\t\tpjmedia_vid_codec_param *param)\n{\n    if (param->dir & PJMEDIA_DIR_ENCODING) {\n\tpjmedia_vid_codec_h264_fmtp fmtp;\n\tpjmedia_video_format_detail *vfd;\n\tpj_status_t status;\n\n\t/* Get remote param */\n\tstatus = pjmedia_vid_codec_h264_parse_fmtp(&param->enc_fmtp,\n\t\t\t\t\t\t   &fmtp);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Adjust fps, size, and bitrate to conform to H.264 level\n\t * specified by remote SDP fmtp.\n\t */\n\tvfd = pjmedia_format_get_video_format_detail(&param->enc_fmt,\n\t\t\t\t\t\t     PJ_TRUE);\n\n\tif (vfd->fps.num == 0 || vfd->fps.denum == 0) {\n\t    vfd->fps.num   = DEFAULT_H264_FPS_NUM;\n\t    vfd->fps.denum = DEFAULT_H264_FPS_DENUM;\n\t}\n\n\tif (vfd->size.w && vfd->size.h) {\n\t    unsigned mb, mbps;\n\t    \n\t    /* Scale down the resolution if it exceeds profile spec */\n\t    mb = CALC_H264_MB_NUM(vfd->size);\n\t    mbps = CALC_H264_MBPS(vfd->size, vfd->fps);\n\t    if (mb > fmtp.max_fs || mbps > fmtp.max_mbps) {\n\t\tpjmedia_ratio r;\n\t\tr.num = vfd->size.w;\n\t\tr.denum = vfd->size.h;\n\t\tfind_highest_res(&fmtp, &vfd->fps, &r, &vfd->size, PJ_FALSE);\n\t    }\n\t} else {\n\t    /* When not specified, just use the highest res possible*/\n\t    pjmedia_ratio r;\n\t    r.num = vfd->size.w;\n\t    r.denum = vfd->size.h;\n\t    find_highest_res(&fmtp, &vfd->fps, &r, &vfd->size, PJ_FALSE);\n\t}\n\n\t/* Encoding bitrate must not be higher than H264 level spec */\n\tif (vfd->avg_bps > fmtp.max_br * 1000)\n\t    vfd->avg_bps = fmtp.max_br * 1000;\n\tif (vfd->max_bps > fmtp.max_br * 1000)\n\t    vfd->max_bps = fmtp.max_br * 1000;\n    }\n\n    if (param->dir & PJMEDIA_DIR_DECODING) {\n\t/* Here we just want to find the highest resolution possible from the\n\t * fmtp and set it as the decoder param.\n\t */\n\tpjmedia_vid_codec_h264_fmtp fmtp;\n\tpjmedia_video_format_detail *vfd;\n\tpjmedia_ratio r;\n\tpjmedia_rect_size highest_size;\n\tpj_status_t status;\n\t\n\tstatus = pjmedia_vid_codec_h264_parse_fmtp(&param->dec_fmtp,\n\t\t\t\t\t\t   &fmtp);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tvfd = pjmedia_format_get_video_format_detail(&param->dec_fmt,\n\t\t\t\t\t\t     PJ_TRUE);\n\n\tif (vfd->fps.num == 0 || vfd->fps.denum == 0) {\n\t    vfd->fps.num   = DEFAULT_H264_FPS_NUM;\n\t    vfd->fps.denum = DEFAULT_H264_FPS_DENUM;\n\t}\n\n\t/* Normalize decoding resolution, i.e: it must not be lower than\n\t * the H264 profile level setting used, as this may be used by\n\t * app to allocate buffer.\n\t */\n\tr.num = vfd->size.w;\n\tr.denum = vfd->size.h;\n\tfind_highest_res(&fmtp, &vfd->fps, &r, &highest_size, PJ_TRUE);\n\tif (vfd->size.w * vfd->size.h < highest_size.w * highest_size.h)\n\t    vfd->size = highest_size;\n\n\t/* Normalize decoding bitrate based on H264 level spec */\n\tif (vfd->avg_bps < fmtp.max_br * 1000)\n\t    vfd->avg_bps = fmtp.max_br * 1000;\n\tif (vfd->max_bps < fmtp.max_br * 1000)\n\t    vfd->max_bps = fmtp.max_br * 1000;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n#endif /* PJMEDIA_HAS_VIDEO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/vid_port.c",
    "content": "/* $Id: vid_port.c 4290 2012-11-01 03:06:33Z ming $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia/vid_port.h>\n#include <pjmedia/clock.h>\n#include <pjmedia/converter.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/event.h>\n#include <pjmedia/vid_codec.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n\n#define SIGNATURE\tPJMEDIA_SIG_VID_PORT\n#define THIS_FILE\t\"vid_port.c\"\n\n\n/* Enable/disable test of finding closest format algo */\n#define ENABLE_TEST_FIND_FMT 0\n\n\n/**\n * Enable this to trace the format matching process.\n */\n#if 0\n#  define TRACE_FIND_FMT(args)\t    PJ_LOG(5,args)\n#else\n#  define TRACE_FIND_FMT(args)\n#endif\n\n/**\n * We use nearest width and aspect ratio to find match between the requested \n * format and the supported format. Specify this to determine the array size \n * of the supported formats with the nearest width. From this array, we will \n * find the one with lowest diff_ratio. Setting this to 1 will thus skip \n * the aspect ratio calculation. \n */\n#ifndef PJMEDIA_VID_PORT_MATCH_WIDTH_ARRAY_SIZE\n#   define PJMEDIA_VID_PORT_MATCH_WIDTH_ARRAY_SIZE 3\n#endif\n\ntypedef struct vid_pasv_port vid_pasv_port;\n\nenum role\n{\n    ROLE_NONE,\n    ROLE_ACTIVE,\n    ROLE_PASSIVE\n};\n\nenum fmt_match\n{\n    FMT_MATCH,\n    FMT_SAME_COLOR_SPACE,\n    FMT_DIFF_COLOR_SPACE\n};\n\nstruct pjmedia_vid_port\n{\n    pj_pool_t               *pool;\n    pj_str_t                 dev_name;\n    pjmedia_dir              dir;\n//    pjmedia_rect_size        cap_size;\n    pjmedia_vid_dev_stream  *strm;\n    pjmedia_vid_dev_cb       strm_cb;\n    void                    *strm_cb_data;\n    enum role                role,\n                             stream_role;\n    vid_pasv_port           *pasv_port;\n    pjmedia_port            *client_port;\n    pj_bool_t                destroy_client_port;\n\n    struct {\n        pjmedia_converter\t*conv;\n        void\t\t        *conv_buf;\n        pj_size_t\t\t conv_buf_size;\n        pjmedia_conversion_param conv_param;\n        unsigned                 usec_ctr;\n        unsigned                 usec_src, usec_dst;\n    } conv;\n\n    pjmedia_clock           *clock;\n    pjmedia_clock_src        clocksrc;\n\n    struct sync_clock_src_t\n    {\n        pjmedia_clock_src   *sync_clocksrc;\n        pj_int32_t           sync_delta;\n        unsigned             max_sync_ticks;\n        unsigned             nsync_frame;\n        unsigned             nsync_progress;\n    } sync_clocksrc;\n\n    pjmedia_frame           *frm_buf;\n    pj_size_t                frm_buf_size;\n    pj_mutex_t              *frm_mutex;\n};\n\nstruct vid_pasv_port\n{\n    pjmedia_port\t base;\n    pjmedia_vid_port\t*vp;\n};\n\nstruct fmt_prop \n{\n    pj_uint32_t id;\n    pjmedia_rect_size size;\n    pjmedia_ratio fps;\n};\n\nstatic pj_status_t vidstream_cap_cb(pjmedia_vid_dev_stream *stream,\n\t\t\t\t    void *user_data,\n\t\t\t\t    pjmedia_frame *frame);\nstatic pj_status_t vidstream_render_cb(pjmedia_vid_dev_stream *stream,\n\t\t\t\t       void *user_data,\n\t\t\t\t       pjmedia_frame *frame);\nstatic pj_status_t vidstream_event_cb(pjmedia_event *event,\n                                      void *user_data);\nstatic pj_status_t client_port_event_cb(pjmedia_event *event,\n                                        void *user_data);\n\nstatic void enc_clock_cb(const pj_timestamp *ts, void *user_data);\nstatic void dec_clock_cb(const pj_timestamp *ts, void *user_data);\n\nstatic pj_status_t vid_pasv_port_put_frame(struct pjmedia_port *this_port,\n\t\t\t\t\t   pjmedia_frame *frame);\n\nstatic pj_status_t vid_pasv_port_get_frame(struct pjmedia_port *this_port,\n\t\t\t\t\t   pjmedia_frame *frame);\n\n\nPJ_DEF(void) pjmedia_vid_port_param_default(pjmedia_vid_port_param *prm)\n{\n    pj_bzero(prm, sizeof(*prm));\n    prm->active = PJ_TRUE;\n}\n\nstatic const char *vid_dir_name(pjmedia_dir dir)\n{\n    switch (dir) {\n    case PJMEDIA_DIR_CAPTURE:\n\treturn \"capture\";\n    case PJMEDIA_DIR_RENDER:\n\treturn \"render\";\n    default:\n\treturn \"??\";\n    }\n}\n\nstatic pj_status_t create_converter(pjmedia_vid_port *vp)\n{\n    if (vp->conv.conv) {\n        pjmedia_converter_destroy(vp->conv.conv);\n\tvp->conv.conv = NULL;\n    }\n\n    /* Instantiate converter if necessary */\n    if (vp->conv.conv_param.src.id != vp->conv.conv_param.dst.id ||\n\t(vp->conv.conv_param.src.det.vid.size.w !=\n         vp->conv.conv_param.dst.det.vid.size.w) ||\n\t(vp->conv.conv_param.src.det.vid.size.h !=\n         vp->conv.conv_param.dst.det.vid.size.h))\n    {\n\tpj_status_t status;\n\n\t/* Yes, we need converter */\n\tstatus = pjmedia_converter_create(NULL, vp->pool, &vp->conv.conv_param,\n\t\t\t\t\t  &vp->conv.conv);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(THIS_FILE, status, \"Error creating converter\"));\n\t    return status;\n\t}\n    }\n\n    if (vp->conv.conv ||\n        (vp->role==ROLE_ACTIVE && (vp->dir & PJMEDIA_DIR_ENCODING)))\n    {\n\tpj_status_t status;\n\tconst pjmedia_video_format_info *vfi;\n\tpjmedia_video_apply_fmt_param vafp;\n\n\t/* Allocate buffer for conversion */\n\tvfi = pjmedia_get_video_format_info(NULL, vp->conv.conv_param.dst.id);\n\tif (!vfi)\n\t    return PJMEDIA_EBADFMT;\n\n\tpj_bzero(&vafp, sizeof(vafp));\n\tvafp.size = vp->conv.conv_param.dst.det.vid.size;\n\tstatus = vfi->apply_fmt(vfi, &vafp);\n\tif (status != PJ_SUCCESS)\n\t    return PJMEDIA_EBADFMT;\n\n\tif (vafp.framebytes > vp->conv.conv_buf_size) {\n\t    vp->conv.conv_buf = pj_pool_alloc(vp->pool, vafp.framebytes);\n\t    vp->conv.conv_buf_size = vafp.framebytes;\n\t}\n    }\n\n    vp->conv.usec_ctr = 0;\n    vp->conv.usec_src = PJMEDIA_PTIME(&vp->conv.conv_param.src.det.vid.fps);\n    vp->conv.usec_dst = PJMEDIA_PTIME(&vp->conv.conv_param.dst.det.vid.fps);\n\n    return PJ_SUCCESS;\n}\t  \n\nstatic pj_uint32_t match_format_id(pj_uint32_t req_id,\n\t\t\t\t   pj_uint32_t sup_id)\n{\n    const pjmedia_video_format_info *req_fmt_info, *sup_fmt_info;\n\n    if (req_id == sup_id)\n\treturn FMT_MATCH;\n\n    req_fmt_info = pjmedia_get_video_format_info( \n\t\t\t\t\tpjmedia_video_format_mgr_instance(),\n\t\t\t\t\treq_id);\n\n    sup_fmt_info = pjmedia_get_video_format_info( \n\t\t\t\t\tpjmedia_video_format_mgr_instance(),\n\t\t\t\t\tsup_id);\n\n    if ((req_fmt_info == NULL) || (sup_fmt_info == NULL)) {\n\treturn FMT_DIFF_COLOR_SPACE;\n    }\n\n    if (req_fmt_info->color_model == sup_fmt_info->color_model) {\n\treturn FMT_SAME_COLOR_SPACE;\n    }\n\n    return FMT_DIFF_COLOR_SPACE;\n}\n\nstatic pj_uint32_t get_match_format_id(pj_uint32_t req_fmt_id,\n\t\t\t\t       pjmedia_vid_dev_info *di)\n{\n    unsigned i, match_idx = 0, match_fmt = FMT_DIFF_COLOR_SPACE+1;\n\n    /* Find the matching format. If no exact match is found, find \n     * the supported format with the same color space. If no match is found,\n     * use the first supported format on the list.\n     */\n    for (i = 0; i < di->fmt_cnt; ++i) {\n\tunsigned tmp_fmt = match_format_id(req_fmt_id, di->fmt[i].id);\n\n\tif (match_fmt == FMT_MATCH)\n\t    return req_fmt_id;\n\n\tif (tmp_fmt < match_fmt) {\n\t    match_idx = i;\n\t    match_fmt = tmp_fmt;\n\t}\n    }\n    return di->fmt[match_idx].id;\n}\n\n/**\n * Find the closest supported format from the specific requested format.\n * The algo is to find a supported size with the matching format id, width and\n * lowest diff_ratio.\n * ---\n * For format id matching, the priority is:\n * 1. Find exact match\n * 2. Find format with the same color space\n * 3. Use the first supported format. \n * ---\n * For ratio matching:\n * Find the lowest difference of the aspect ratio between the requested and\n * the supported format.\n */\nstatic struct fmt_prop find_closest_fmt(pj_uint32_t req_fmt_id,\n\t\t\t\t\tpjmedia_rect_size *req_fmt_size,\n\t\t\t\t\tpjmedia_ratio *req_fmt_fps,\n\t\t\t\t\tpjmedia_vid_dev_info *di)\n{\n    unsigned i, match_idx = 0;\n    pj_uint32_t match_fmt_id;     \n    float req_ratio, min_diff_ratio = 0.0;    \n    struct fmt_prop ret_prop;\n    pj_bool_t found_exact_match = PJ_FALSE;\n\n    #define\tGET_DIFF(x, y)\t((x) > (y)? (x-y) : (y-x))\n    \n    /* This will contain the supported format with lowest width difference */\n    pjmedia_rect_size nearest_width[PJMEDIA_VID_PORT_MATCH_WIDTH_ARRAY_SIZE];\n\n    /* Initialize the list. */\n    for (i=0;i<PJMEDIA_VID_PORT_MATCH_WIDTH_ARRAY_SIZE;++i) {\n\tnearest_width[i].w = 0xFFFFFFFF;\n\tnearest_width[i].h = 0;\n    }\n\n    /* Get the matching format id. We assume each format will support all \n     * image size. \n     */\n    match_fmt_id = get_match_format_id(req_fmt_id, di);\n    \n    /* Search from the supported format, the smallest diff width. Stop the \n     * search if exact match is found.\n     */\n    for (i=0;i<di->fmt_cnt;++i) {\n\tpjmedia_video_format_detail *vfd;\n\tunsigned diff_width1, diff_width2;\n\n\t/* Ignore supported format with different format id. */\n\tif (di->fmt[i].id != match_fmt_id)\n\t    continue;\n\n\tvfd = pjmedia_format_get_video_format_detail(&di->fmt[i], PJ_TRUE);\n\n\t/* Exact match found. */\n\tif ((vfd->size.w == req_fmt_size->w) && \n\t    (vfd->size.h == req_fmt_size->h)) \n\t{\n\t    nearest_width[0] = vfd->size;\n\t    found_exact_match = PJ_TRUE;\n\t    break;\n\t}\n\n\tdiff_width1 =  GET_DIFF(vfd->size.w, req_fmt_size->w);\n\tdiff_width2 =  GET_DIFF(nearest_width[0].w, req_fmt_size->w);\n\n\t/* Fill the nearest width list. */\n\tif (diff_width1 <= diff_width2) {\n\t    int k = 1;\n\t    pjmedia_rect_size tmp_size = vfd->size;\t    \n\n\t    while(((GET_DIFF(tmp_size.w, req_fmt_size->w) <\n\t\t   (GET_DIFF(nearest_width[k].w, req_fmt_size->w))) && \n\t\t  (k < PJ_ARRAY_SIZE(nearest_width))))    \t\n\t    {\n\t\tnearest_width[k-1] = nearest_width[k];\n\t\t++k;\n\t    }\n\t    nearest_width[k-1] = tmp_size;\n\t}\t\t\n    }\n    /* No need to calculate ratio if exact match is found. */\n    if (!found_exact_match) {\n\tpj_bool_t found_match = PJ_FALSE;\n\n\t/* We have the list of supported format with nearest width. Now get the \n\t * best ratio.\n\t */\n\treq_ratio = (float)req_fmt_size->w / (float)req_fmt_size->h;\n\tfor (i=0;i<PJ_ARRAY_SIZE(nearest_width);++i) {\n\t    float sup_ratio, diff_ratio;\n\n\t    if (nearest_width[i].w == 0xFFFFFFFF)\n\t\tcontinue;\n\n\t    sup_ratio = (float)nearest_width[i].w / (float)nearest_width[i].h;\n\n\t    diff_ratio = GET_DIFF(sup_ratio, req_ratio);\n\n\t    if ((!found_match) || (diff_ratio <= min_diff_ratio)) {\n\t\tfound_match = PJ_TRUE;\n\t\tmatch_idx = i;\n\t\tmin_diff_ratio = diff_ratio;\n\t    }\n\t}\n    }\n    ret_prop.id = match_fmt_id;\n    ret_prop.size = nearest_width[match_idx];\n    ret_prop.fps = *req_fmt_fps;\n    return ret_prop;\n}\n\n#if ENABLE_TEST_FIND_FMT\n/**\n * This is to test the algo to find the closest fmt\n */\nstatic void test_find_closest_fmt(pjmedia_vid_dev_info *di)\n{  \n    unsigned i, j, k;\n    char fmt_name[5];\n\n    pjmedia_rect_size find_size[] = {\n\t{720, 480},\n\t{352, 288},\n\t{400, 300},\n\t{1600, 900},\n\t{255, 352},\n\t{500, 500},\n    };\n\n    pjmedia_ratio find_fps[] = {\n\t{1, 1},\n\t{10, 1},\n\t{15, 1},\n\t{30, 1},\n    };\n\n    pj_uint32_t find_id[] = {\n\tPJMEDIA_FORMAT_RGB24,\n\tPJMEDIA_FORMAT_RGBA,\n\tPJMEDIA_FORMAT_AYUV,\n\tPJMEDIA_FORMAT_YUY2,\n\tPJMEDIA_FORMAT_I420\n    };\n\n    TRACE_FIND_FMT((THIS_FILE, \"Supported format = \"));\n    for (i = 0; i < di->fmt_cnt; i++) {\n\t//pjmedia_video_format_detail *vid_fd = \n\t//    pjmedia_format_get_video_format_detail(&di->fmt[i], PJ_TRUE);\n\n\tpjmedia_fourcc_name(di->fmt[i].id, fmt_name);\n\n\tTRACE_FIND_FMT((THIS_FILE, \"id:%s size:%d*%d fps:%d/%d\", \n\t\t\tfmt_name,\n\t\t\tvid_fd->size.w,\n\t\t\tvid_fd->size.h,\n\t\t\tvid_fd->fps.num,\n\t\t\tvid_fd->fps.denum));\n    }\n    \n    for (i = 0; i < PJ_ARRAY_SIZE(find_id); i++) {\n\n\tfor (j = 0; j < PJ_ARRAY_SIZE(find_fps); j++) {\n\t\n\t    for (k = 0; k < PJ_ARRAY_SIZE(find_size); k++) {\n\t\tstruct fmt_prop match_prop;\n\n\t\tpjmedia_fourcc_name(find_id[i], fmt_name);\n\n\t\tTRACE_FIND_FMT((THIS_FILE, \"Trying to find closest match \"\n\t\t\t\t           \"id:%s size:%dx%d fps:%d/%d\", \n\t\t\t        fmt_name,\n\t\t\t        find_size[k].w,\n\t\t\t        find_size[k].h,\n\t\t\t        find_fps[j].num,\n\t\t\t        find_fps[j].denum));\n\t\t\n\t\tmatch_prop = find_closest_fmt(find_id[i],\n\t\t\t\t\t      &find_size[k],\n\t\t\t\t\t      &find_fps[j],\n\t\t\t\t\t      di);\n\n\t\tif ((match_prop.id == find_id[i]) && \n\t\t    (match_prop.size.w == find_size[k].w) &&\n\t\t    (match_prop.size.h == find_size[k].h) &&\n\t\t    (match_prop.fps.num / match_prop.fps.denum == \n\t\t     find_fps[j].num * find_fps[j].denum)) \n\t\t{\n\t\t    TRACE_FIND_FMT((THIS_FILE, \"Exact Match found!!\"));\n\t\t} else {\n\t\t    pjmedia_fourcc_name(match_prop.id, fmt_name);\n\t\t    TRACE_FIND_FMT((THIS_FILE, \"Closest format = \"\\\n\t\t\t\t\t        \"id:%s size:%dx%d fps:%d/%d\", \n\t\t\t\t    fmt_name,\n\t\t\t\t    match_prop.size.w,\n\t\t\t\t    match_prop.size.h, \n\t\t\t\t    match_prop.fps.num,\n\t\t\t\t    match_prop.fps.denum));\t\t    \n\t\t}\n\t    }\n\t}\n    }\n}\n#endif\n\nPJ_DEF(pj_status_t) pjmedia_vid_port_create( pj_pool_t *pool,\n\t\t\t\t\t     const pjmedia_vid_port_param *prm,\n\t\t\t\t\t     pjmedia_vid_port **p_vid_port)\n{\n    pjmedia_vid_port *vp;\n    pjmedia_video_format_detail *vfd;\n    char dev_name[64];\n    char fmt_name[5];\n    pjmedia_vid_dev_cb vid_cb;\n    pj_bool_t need_frame_buf = PJ_FALSE;\n    pj_status_t status;\n    unsigned ptime_usec;\n    pjmedia_vid_dev_param vparam;\n    pjmedia_vid_dev_info di;\n\n    PJ_ASSERT_RETURN(pool && prm && p_vid_port, PJ_EINVAL);\n    PJ_ASSERT_RETURN(prm->vidparam.fmt.type == PJMEDIA_TYPE_VIDEO &&\n                     prm->vidparam.dir != PJMEDIA_DIR_NONE &&\n                     prm->vidparam.dir != PJMEDIA_DIR_CAPTURE_RENDER,\n\t\t     PJ_EINVAL);\n\n    /* Retrieve the video format detail */\n    vfd = pjmedia_format_get_video_format_detail(&prm->vidparam.fmt, PJ_TRUE);\n    if (!vfd)\n\treturn PJ_EINVAL;\n\n    PJ_ASSERT_RETURN(vfd->fps.num, PJ_EINVAL);\n\n    /* Allocate videoport */\n    vp = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_port);\n    vp->pool = pj_pool_create(pool->factory, \"video port\", 500, 500, NULL);\n    vp->role = prm->active ? ROLE_ACTIVE : ROLE_PASSIVE;\n    vp->dir = prm->vidparam.dir;\n//    vp->cap_size = vfd->size;\n\n    vparam = prm->vidparam;\n    dev_name[0] = '\\0';\n\n    /* Get device info */\n    if (vp->dir & PJMEDIA_DIR_CAPTURE)\n        status = pjmedia_vid_dev_get_info(prm->vidparam.cap_id, &di);\n    else\n        status = pjmedia_vid_dev_get_info(prm->vidparam.rend_id, &di);\n    if (status != PJ_SUCCESS)\n        return status;\n\n    pj_ansi_snprintf(dev_name, sizeof(dev_name), \"%s [%s]\",\n                     di.name, di.driver);\n    pjmedia_fourcc_name(vparam.fmt.id, fmt_name);\n    PJ_LOG(4,(THIS_FILE,\n\t      \"Opening device %s for %s: format=%s, size=%dx%d @%d:%d fps\",\n\t      dev_name,\n\t      vid_dir_name(prm->vidparam.dir), fmt_name,\n\t      vfd->size.w, vfd->size.h,\n\t      vfd->fps.num, vfd->fps.denum));\n\n    if (di.dir == PJMEDIA_DIR_RENDER) {\n\t/* Find the matching format. If no exact match is found, find \n\t * the supported format with the same color space. If no match is found,\n\t * use the first supported format on the list.\n\t */\n\tpj_assert(di.fmt_cnt != 0);\n\tvparam.fmt.id = get_match_format_id(prm->vidparam.fmt.id, &di);\n    } else {\n\tstruct fmt_prop match_prop;\n\n\tif (di.fmt_cnt == 0) {\n\t    status = PJMEDIA_EVID_SYSERR;\n\t    PJ_PERROR(4,(THIS_FILE, status, \"Device has no supported format\"));\n\t    return status;\n\t}\n\n#if ENABLE_TEST_FIND_FMT\n\ttest_find_closest_fmt(&di);\n#endif\n\n\tmatch_prop = find_closest_fmt(prm->vidparam.fmt.id, \n\t\t\t\t      &vfd->size,\t\t\t     \n\t\t\t\t      &vfd->fps, \n\t\t\t\t      &di);\n\n\tif ((match_prop.id != prm->vidparam.fmt.id) || \n\t    (match_prop.size.w != vfd->size.w) ||\n\t    (match_prop.size.h != vfd->size.h))\n\t{\n\t    vparam.fmt.id = match_prop.id;\n\t    vparam.fmt.det.vid.size = match_prop.size;\n\t}\n    }\n\n    pj_strdup2_with_null(pool, &vp->dev_name, di.name);\n    vp->stream_role = di.has_callback ? ROLE_ACTIVE : ROLE_PASSIVE;\n\n    ptime_usec = PJMEDIA_PTIME(&vfd->fps);\n    pjmedia_clock_src_init(&vp->clocksrc, PJMEDIA_TYPE_VIDEO,\n                           prm->vidparam.clock_rate, ptime_usec);\n    vp->sync_clocksrc.max_sync_ticks = \n        PJMEDIA_CLOCK_SYNC_MAX_RESYNC_DURATION *\n        1000 / vp->clocksrc.ptime_usec;\n\n    /* Create the video stream */\n    pj_bzero(&vid_cb, sizeof(vid_cb));\n    vid_cb.capture_cb = &vidstream_cap_cb;\n    vid_cb.render_cb = &vidstream_render_cb;\n\n    status = pjmedia_vid_dev_stream_create(&vparam, &vid_cb, vp,\n\t\t\t\t           &vp->strm);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    PJ_LOG(4,(THIS_FILE,\n\t      \"Device %s opened: format=%s, size=%dx%d @%d:%d fps\",\n\t      dev_name, fmt_name,\n\t      vparam.fmt.det.vid.size.w, vparam.fmt.det.vid.size.h,\n\t      vparam.fmt.det.vid.fps.num, vparam.fmt.det.vid.fps.denum));\n\n    /* Subscribe to device's events */\n    pjmedia_event_subscribe(NULL, &vidstream_event_cb,\n                            vp, vp->strm);\n\n    if (vp->dir & PJMEDIA_DIR_CAPTURE) {\n\tpjmedia_format_copy(&vp->conv.conv_param.src, &vparam.fmt);\n\tpjmedia_format_copy(&vp->conv.conv_param.dst, &prm->vidparam.fmt);\n    } else {\n\tpjmedia_format_copy(&vp->conv.conv_param.src, &prm->vidparam.fmt);\n\tpjmedia_format_copy(&vp->conv.conv_param.dst, &vparam.fmt);\n    }\n\n    status = create_converter(vp);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    if (vp->role==ROLE_ACTIVE &&\n        ((vp->dir & PJMEDIA_DIR_ENCODING) || vp->stream_role==ROLE_PASSIVE))\n    {\n        pjmedia_clock_param param;\n\n\t/* Active role is wanted, but our device is passive, so create\n\t * master clocks to run the media flow. For encoding direction,\n         * we also want to create our own clock since the device's clock\n         * may run at a different rate.\n\t */\n\tneed_frame_buf = PJ_TRUE;\n            \n        param.usec_interval = PJMEDIA_PTIME(&vfd->fps);\n        param.clock_rate = prm->vidparam.clock_rate;\n        status = pjmedia_clock_create2(pool, &param,\n                                       PJMEDIA_CLOCK_NO_HIGHEST_PRIO,\n                                       (vp->dir & PJMEDIA_DIR_ENCODING) ?\n                                       &enc_clock_cb: &dec_clock_cb,\n                                       vp, &vp->clock);\n        if (status != PJ_SUCCESS)\n            goto on_error;\n\n    } else if (vp->role==ROLE_PASSIVE) {\n\tvid_pasv_port *pp;\n\n\t/* Always need to create media port for passive role */\n\tvp->pasv_port = pp = PJ_POOL_ZALLOC_T(pool, vid_pasv_port);\n\tpp->vp = vp;\n\tpp->base.get_frame = &vid_pasv_port_get_frame;\n\tpp->base.put_frame = &vid_pasv_port_put_frame;\n\tpjmedia_port_info_init2(&pp->base.info, &vp->dev_name,\n\t                        PJMEDIA_SIG_VID_PORT,\n\t\t\t        prm->vidparam.dir, &prm->vidparam.fmt);\n\n        need_frame_buf = PJ_TRUE;\n    }\n\n    if (need_frame_buf) {\n\tconst pjmedia_video_format_info *vfi;\n\tpjmedia_video_apply_fmt_param vafp;\n\n\tvfi = pjmedia_get_video_format_info(NULL, vparam.fmt.id);\n\tif (!vfi) {\n\t    status = PJ_ENOTFOUND;\n\t    goto on_error;\n\t}\n\n\tpj_bzero(&vafp, sizeof(vafp));\n\tvafp.size = vparam.fmt.det.vid.size;\n\tstatus = vfi->apply_fmt(vfi, &vafp);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n        vp->frm_buf = PJ_POOL_ZALLOC_T(pool, pjmedia_frame);\n        vp->frm_buf_size = vafp.framebytes;\n        vp->frm_buf->buf = pj_pool_alloc(pool, vafp.framebytes);\n        vp->frm_buf->size = vp->frm_buf_size;\n        vp->frm_buf->type = PJMEDIA_FRAME_TYPE_NONE;\n\n        status = pj_mutex_create_simple(pool, vp->dev_name.ptr,\n                                        &vp->frm_mutex);\n        if (status != PJ_SUCCESS)\n            goto on_error;\n    }\n\n    *p_vid_port = vp;\n\n    return PJ_SUCCESS;\n\non_error:\n    pjmedia_vid_port_destroy(vp);\n    return status;\n}\n\nPJ_DEF(void) pjmedia_vid_port_set_cb(pjmedia_vid_port *vid_port,\n\t\t\t\t     const pjmedia_vid_dev_cb *cb,\n                                     void *user_data)\n{\n    pj_assert(vid_port && cb);\n    pj_memcpy(&vid_port->strm_cb, cb, sizeof(*cb));\n    vid_port->strm_cb_data = user_data;\n}\n\nPJ_DEF(pjmedia_vid_dev_stream*)\npjmedia_vid_port_get_stream(pjmedia_vid_port *vp)\n{\n    PJ_ASSERT_RETURN(vp, NULL);\n    return vp->strm;\n}\n\n\nPJ_DEF(pjmedia_port*)\npjmedia_vid_port_get_passive_port(pjmedia_vid_port *vp)\n{\n    PJ_ASSERT_RETURN(vp && vp->role==ROLE_PASSIVE, NULL);\n    return &vp->pasv_port->base;\n}\n\n\nPJ_DEF(pjmedia_clock_src *)\npjmedia_vid_port_get_clock_src( pjmedia_vid_port *vid_port )\n{\n    PJ_ASSERT_RETURN(vid_port, NULL);\n    return &vid_port->clocksrc;\n}\n\nPJ_DECL(pj_status_t)\npjmedia_vid_port_set_clock_src( pjmedia_vid_port *vid_port,\n                                pjmedia_clock_src *clocksrc)\n{\n    PJ_ASSERT_RETURN(vid_port && clocksrc, PJ_EINVAL);\n\n    vid_port->sync_clocksrc.sync_clocksrc = clocksrc;\n    vid_port->sync_clocksrc.sync_delta =\n        pjmedia_clock_src_get_time_msec(&vid_port->clocksrc) -\n        pjmedia_clock_src_get_time_msec(clocksrc);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_vid_port_connect(pjmedia_vid_port *vp,\n\t\t\t\t\t      pjmedia_port *port,\n\t\t\t\t\t      pj_bool_t destroy)\n{\n    PJ_ASSERT_RETURN(vp && vp->role==ROLE_ACTIVE, PJ_EINVAL);\n    vp->destroy_client_port = destroy;\n    vp->client_port = port;\n\n    /* Subscribe to client port's events */\n    pjmedia_event_subscribe(NULL, &client_port_event_cb, vp,\n                            vp->client_port);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_vid_port_disconnect(pjmedia_vid_port *vp)\n{\n    PJ_ASSERT_RETURN(vp && vp->role==ROLE_ACTIVE, PJ_EINVAL);\n\n    pjmedia_event_unsubscribe(NULL, &client_port_event_cb, vp,\n                              vp->client_port);\n    vp->client_port = NULL;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pjmedia_port*)\npjmedia_vid_port_get_connected_port(pjmedia_vid_port *vp)\n{\n    PJ_ASSERT_RETURN(vp && vp->role==ROLE_ACTIVE, NULL);\n    return vp->client_port;\n}\n\nPJ_DEF(pj_status_t) pjmedia_vid_port_start(pjmedia_vid_port *vp)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(vp, PJ_EINVAL);\n\n    status = pjmedia_vid_dev_stream_start(vp->strm);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    if (vp->clock) {\n\tstatus = pjmedia_clock_start(vp->clock);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n    }\n\n    return PJ_SUCCESS;\n\non_error:\n    pjmedia_vid_port_stop(vp);\n    return status;\n}\n\nPJ_DEF(pj_bool_t) pjmedia_vid_port_is_running(pjmedia_vid_port *vp)\n{\n    return pjmedia_vid_dev_stream_is_running(vp->strm);\n}\n\nPJ_DEF(pj_status_t) pjmedia_vid_port_stop(pjmedia_vid_port *vp)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(vp, PJ_EINVAL);\n\n    if (vp->clock) {\n\tstatus = pjmedia_clock_stop(vp->clock);\n    }\n\n    status = pjmedia_vid_dev_stream_stop(vp->strm);\n\n    return status;\n}\n\nPJ_DEF(void) pjmedia_vid_port_destroy(pjmedia_vid_port *vp)\n{\n    PJ_ASSERT_ON_FAIL(vp, return);\n\n    PJ_LOG(4,(THIS_FILE, \"Closing %s..\", vp->dev_name.ptr));\n\n    if (vp->clock) {\n\tpjmedia_clock_destroy(vp->clock);\n\tvp->clock = NULL;\n    }\n    if (vp->strm) {\n        pjmedia_event_unsubscribe(NULL, &vidstream_event_cb, vp, vp->strm);\n\tpjmedia_vid_dev_stream_destroy(vp->strm);\n\tvp->strm = NULL;\n    }\n    if (vp->client_port) {\n        pjmedia_event_unsubscribe(NULL, &client_port_event_cb, vp,\n                                  vp->client_port);\n\tif (vp->destroy_client_port)\n\t    pjmedia_port_destroy(vp->client_port);\n\tvp->client_port = NULL;\n    }\n    if (vp->frm_mutex) {\n\tpj_mutex_destroy(vp->frm_mutex);\n\tvp->frm_mutex = NULL;\n    }\n    if (vp->conv.conv) {\n        pjmedia_converter_destroy(vp->conv.conv);\n        vp->conv.conv = NULL;\n    }\n    pj_pool_release(vp->pool);\n}\n\n/*\nstatic void save_rgb_frame(int width, int height, const pjmedia_frame *frm)\n{\n    static int counter;\n    FILE *pFile;\n    char szFilename[32];\n    const pj_uint8_t *pFrame = (const pj_uint8_t*)frm->buf;\n    int  y;\n\n    if (counter > 10)\n\treturn;\n\n    // Open file\n    sprintf(szFilename, \"frame%02d.ppm\", counter++);\n    pFile=fopen(szFilename, \"wb\");\n    if(pFile==NULL)\n      return;\n\n    // Write header\n    fprintf(pFile, \"P6\\n%d %d\\n255\\n\", width, height);\n\n    // Write pixel data\n    for(y=0; y<height; y++)\n      fwrite(pFrame+y*width*3, 1, width*3, pFile);\n\n    // Close file\n    fclose(pFile);\n}\n*/\n\n/* Handle event from vidstream */\nstatic pj_status_t vidstream_event_cb(pjmedia_event *event,\n                                      void *user_data)\n{\n    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;\n    \n    /* Just republish the event to our client */\n    return pjmedia_event_publish(NULL, vp, event, 0);\n}\n\nstatic pj_status_t client_port_event_cb(pjmedia_event *event,\n                                        void *user_data)\n{\n    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;\n\n    if (event->type == PJMEDIA_EVENT_FMT_CHANGED) {\n        const pjmedia_video_format_detail *vfd;\n        const pjmedia_video_format_detail *vfd_cur;\n        pjmedia_vid_dev_param vid_param;\n        pj_status_t status;\n        \n        /* Retrieve the current video format detail */\n        pjmedia_vid_dev_stream_get_param(vp->strm, &vid_param);\n        vfd_cur = pjmedia_format_get_video_format_detail(\n\t\t  &vid_param.fmt, PJ_TRUE);\n        if (!vfd_cur)\n            return PJMEDIA_EVID_BADFORMAT;\n\n        /* Retrieve the new video format detail */\n        vfd = pjmedia_format_get_video_format_detail(\n                  &event->data.fmt_changed.new_fmt, PJ_TRUE);\n        if (!vfd || !vfd->fps.num || !vfd->fps.denum)\n            return PJMEDIA_EVID_BADFORMAT;\n\n\t/* Ticket #1876: if this is a passive renderer and only frame rate is\n\t * changing, simply modify the clock.\n\t */\n\tif (vp->dir == PJMEDIA_DIR_RENDER &&\n\t    vp->stream_role == ROLE_PASSIVE && vp->role == ROLE_ACTIVE)\n\t{\n\t    pj_bool_t fps_only;\n\t    pjmedia_video_format_detail tmp_vfd;\n\t    \n\t    tmp_vfd = *vfd_cur;\n\t    tmp_vfd.fps = vfd->fps;\n\t    fps_only = pj_memcmp(vfd, &tmp_vfd, sizeof(*vfd)) == 0;\n\t    if (fps_only) {\n\t\tpjmedia_clock_param clock_param;\n\t\tclock_param.usec_interval = PJMEDIA_PTIME(&vfd->fps);\n\t\tclock_param.clock_rate = vid_param.clock_rate;\n\t\tpjmedia_clock_modify(vp->clock, &clock_param);\n\n\t\treturn pjmedia_event_publish(NULL, vp, event,\n\t\t\t\t\t     PJMEDIA_EVENT_PUBLISH_POST_EVENT);\n\t    }\n\t}\n\n\t/* Ticket #1827:\n\t * Stopping video port should not be necessary here because\n\t * it will also try to stop the clock, from inside the clock's\n\t * own thread, so it may get stuck. We just stop the video device\n\t * stream instead.\n\t * pjmedia_vid_port_stop(vp);\n\t */\n\tpjmedia_vid_dev_stream_stop(vp->strm);\n        \n\t/* Change the destination format to the new format */\n\tpjmedia_format_copy(&vp->conv.conv_param.src,\n\t\t\t    &event->data.fmt_changed.new_fmt);\n\t/* Only copy the size here */\n\tvp->conv.conv_param.dst.det.vid.size =\n\t    event->data.fmt_changed.new_fmt.det.vid.size;\n\n\tstatus = create_converter(vp);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(THIS_FILE, status, \"Error recreating converter\"));\n\t    return status;\n\t}\n\n        if (vid_param.fmt.id != vp->conv.conv_param.dst.id ||\n            (vid_param.fmt.det.vid.size.h !=\n             vp->conv.conv_param.dst.det.vid.size.h) ||\n            (vid_param.fmt.det.vid.size.w !=\n             vp->conv.conv_param.dst.det.vid.size.w))\n        {\n            status = pjmedia_vid_dev_stream_set_cap(vp->strm,\n                                                    PJMEDIA_VID_DEV_CAP_FORMAT,\n                                                    &vp->conv.conv_param.dst);\n            if (status != PJ_SUCCESS) {\n                PJ_LOG(3, (THIS_FILE, \"failure in changing the format of the \"\n                                      \"video device\"));\n                PJ_LOG(3, (THIS_FILE, \"reverting to its original format: %s\",\n                                      status != PJMEDIA_EVID_ERR ? \"success\" :\n                                      \"failure\"));\n\t        pjmedia_vid_port_start(vp);\n                return status;\n            }\n        }\n        \n        if (vp->stream_role == ROLE_PASSIVE) {\n            pjmedia_clock_param clock_param;\n            \n            /**\n             * Initially, frm_buf was allocated the biggest\n             * supported size, so we do not need to re-allocate\n             * the buffer here.\n             */\n            /* Adjust the clock */\n            clock_param.usec_interval = PJMEDIA_PTIME(&vfd->fps);\n            clock_param.clock_rate = vid_param.clock_rate;\n            pjmedia_clock_modify(vp->clock, &clock_param);\n        }\n        \n\t/* pjmedia_vid_port_start(vp); */\n\tpjmedia_vid_dev_stream_start(vp->strm);\n    }\n    \n    /* Republish the event, post the event to the event manager\n     * to avoid deadlock if vidport is trying to stop the clock.\n     */\n    return pjmedia_event_publish(NULL, vp, event,\n                                 PJMEDIA_EVENT_PUBLISH_POST_EVENT);\n}\n\nstatic pj_status_t convert_frame(pjmedia_vid_port *vp,\n                                 pjmedia_frame *src_frame,\n                                 pjmedia_frame *dst_frame)\n{\n    pj_status_t status = PJ_SUCCESS;\n\n    if (vp->conv.conv) {\n        if (!dst_frame->buf || dst_frame->size < vp->conv.conv_buf_size) {\n            dst_frame->buf  = vp->conv.conv_buf;\n\t    dst_frame->size = vp->conv.conv_buf_size;\n        }\n\tstatus = pjmedia_converter_convert(vp->conv.conv,\n\t\t\t\t\t   src_frame, dst_frame);\n    }\n    \n    return status;\n}\n\n/* Copy frame to buffer. */\nstatic void copy_frame_to_buffer(pjmedia_vid_port *vp,\n                                 pjmedia_frame *frame)\n{\n    pj_mutex_lock(vp->frm_mutex);\n    pjmedia_frame_copy(vp->frm_buf, frame);\n    pj_mutex_unlock(vp->frm_mutex);\n}\n\n/* Get frame from buffer and convert it if necessary. */\nstatic pj_status_t get_frame_from_buffer(pjmedia_vid_port *vp,\n                                         pjmedia_frame *frame)\n{\n    pj_status_t status = PJ_SUCCESS;\n\n    pj_mutex_lock(vp->frm_mutex);\n    if (vp->conv.conv)\n        status = convert_frame(vp, vp->frm_buf, frame);\n    else\n        pjmedia_frame_copy(frame, vp->frm_buf);\n    pj_mutex_unlock(vp->frm_mutex);\n    \n    return status;\n}\n\nstatic void enc_clock_cb(const pj_timestamp *ts, void *user_data)\n{\n    /* We are here because user wants us to be active but the stream is\n     * passive. So get a frame from the stream and push it to user.\n     */\n    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;\n    pjmedia_frame frame_;\n    pj_status_t status = PJ_SUCCESS;\n\n    pj_assert(vp->role==ROLE_ACTIVE);\n\n    PJ_UNUSED_ARG(ts);\n\n    if (!vp->client_port)\n\treturn;\n\n    if (vp->stream_role == ROLE_PASSIVE) {\n        while (vp->conv.usec_ctr < vp->conv.usec_dst) {\n            vp->frm_buf->size = vp->frm_buf_size;\n            status = pjmedia_vid_dev_stream_get_frame(vp->strm, vp->frm_buf);\n            vp->conv.usec_ctr += vp->conv.usec_src;\n        }\n        vp->conv.usec_ctr -= vp->conv.usec_dst;\n        if (status != PJ_SUCCESS)\n\t    return;\n    }\n\n    //save_rgb_frame(vp->cap_size.w, vp->cap_size.h, vp->frm_buf);\n\n    frame_.buf = vp->conv.conv_buf;\n    frame_.size = vp->conv.conv_buf_size;\n    status = get_frame_from_buffer(vp, &frame_);\n    if (status != PJ_SUCCESS)\n        return;\n\n    status = pjmedia_port_put_frame(vp->client_port, &frame_);\n    if (status != PJ_SUCCESS)\n        return;\n}\n\nstatic void dec_clock_cb(const pj_timestamp *ts, void *user_data)\n{\n    /* We are here because user wants us to be active but the stream is\n     * passive. So get a frame from the stream and push it to user.\n     */\n    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;\n    pj_status_t status;\n    pjmedia_frame frame;\n\n    pj_assert(vp->role==ROLE_ACTIVE && vp->stream_role==ROLE_PASSIVE);\n\n    PJ_UNUSED_ARG(ts);\n\n    if (!vp->client_port)\n\treturn;\n\n    status = vidstream_render_cb(vp->strm, vp, &frame);\n    if (status != PJ_SUCCESS)\n        return;\n    \n    if (frame.size > 0)\n\tstatus = pjmedia_vid_dev_stream_put_frame(vp->strm, &frame);\n}\n\nstatic pj_status_t vidstream_cap_cb(pjmedia_vid_dev_stream *stream,\n\t\t\t\t    void *user_data,\n\t\t\t\t    pjmedia_frame *frame)\n{\n    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;\n\n    /* We just store the frame in the buffer. For active role, we let\n     * video port's clock to push the frame buffer to the user.\n     * The decoding counterpart for passive role and active stream is\n     * located in vid_pasv_port_put_frame()\n     */\n    copy_frame_to_buffer(vp, frame);\n\n    /* This is tricky since the frame is still in its original unconverted\n     * format, which may not be what the application expects.\n     */\n    if (vp->strm_cb.capture_cb)\n        return (*vp->strm_cb.capture_cb)(stream, vp->strm_cb_data, frame);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t vidstream_render_cb(pjmedia_vid_dev_stream *stream,\n\t\t\t\t       void *user_data,\n\t\t\t\t       pjmedia_frame *frame)\n{\n    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;\n    pj_status_t status = PJ_SUCCESS;\n    \n    pj_bzero(frame, sizeof(pjmedia_frame));\n    if (vp->role==ROLE_ACTIVE) {\n        unsigned frame_ts = vp->clocksrc.clock_rate / 1000 *\n                            vp->clocksrc.ptime_usec / 1000;\n\n        if (!vp->client_port)\n            return status;\n        \n        if (vp->sync_clocksrc.sync_clocksrc) {\n            pjmedia_clock_src *src = vp->sync_clocksrc.sync_clocksrc;\n            pj_int32_t diff;\n            unsigned nsync_frame;\n            \n            /* Synchronization */\n            /* Calculate the time difference (in ms) with the sync source */\n            diff = pjmedia_clock_src_get_time_msec(&vp->clocksrc) -\n                   pjmedia_clock_src_get_time_msec(src) -\n                   vp->sync_clocksrc.sync_delta;\n            \n            /* Check whether sync source made a large jump */\n            if (diff < 0 && -diff > PJMEDIA_CLOCK_SYNC_MAX_SYNC_MSEC) {\n                pjmedia_clock_src_update(&vp->clocksrc, NULL);\n                vp->sync_clocksrc.sync_delta = \n                    pjmedia_clock_src_get_time_msec(src) -\n                    pjmedia_clock_src_get_time_msec(&vp->clocksrc);\n                vp->sync_clocksrc.nsync_frame = 0;\n                return status;\n            }\n            \n            /* Calculate the difference (in frames) with the sync source */\n            nsync_frame = abs(diff) * 1000 / vp->clocksrc.ptime_usec;\n            if (nsync_frame == 0) {\n                /* Nothing to sync */\n                vp->sync_clocksrc.nsync_frame = 0;\n            } else {\n                pj_int32_t init_sync_frame = nsync_frame;\n                \n                /* Check whether it's a new sync or whether we need to reset\n                 * the sync\n                 */\n                if (vp->sync_clocksrc.nsync_frame == 0 ||\n                    (vp->sync_clocksrc.nsync_frame > 0 &&\n                     nsync_frame > vp->sync_clocksrc.nsync_frame))\n                {\n                    vp->sync_clocksrc.nsync_frame = nsync_frame;\n                    vp->sync_clocksrc.nsync_progress = 0;\n                } else {\n                    init_sync_frame = vp->sync_clocksrc.nsync_frame;\n                }\n                \n                if (diff >= 0) {\n                    unsigned skip_mod;\n                    \n                    /* We are too fast */\n                    if (vp->sync_clocksrc.max_sync_ticks > 0) {\n                        skip_mod = init_sync_frame / \n                        vp->sync_clocksrc.max_sync_ticks + 2;\n                    } else\n                        skip_mod = init_sync_frame + 2;\n                    \n                    PJ_LOG(5, (THIS_FILE, \"synchronization: early by %d ms\",\n                               diff));\n                    /* We'll play a frame every skip_mod-th tick instead of\n                     * a complete pause\n                     */\n                    if (++vp->sync_clocksrc.nsync_progress % skip_mod > 0) {\n                        pjmedia_clock_src_update(&vp->clocksrc, NULL);\n                        return status;\n                    }\n                } else {\n                    unsigned i, ndrop = init_sync_frame;\n                    \n                    /* We are too late, drop the frame */\n                    if (vp->sync_clocksrc.max_sync_ticks > 0) {\n                        ndrop /= vp->sync_clocksrc.max_sync_ticks;\n                        ndrop++;\n                    }\n                    PJ_LOG(5, (THIS_FILE, \"synchronization: late, \"\n                               \"dropping %d frame(s)\", ndrop));\n                    \n                    if (ndrop >= nsync_frame) {\n                        vp->sync_clocksrc.nsync_frame = 0;\n                        ndrop = nsync_frame;\n                    } else\n                        vp->sync_clocksrc.nsync_progress += ndrop;\n                    \n                    for (i = 0; i < ndrop; i++) {\n                        vp->frm_buf->size = vp->frm_buf_size;\n                        status = pjmedia_port_get_frame(vp->client_port,\n                                                        vp->frm_buf);\n                        if (status != PJ_SUCCESS) {\n                            pjmedia_clock_src_update(&vp->clocksrc, NULL);\n                            return status;\n                        }\n                        \n                        pj_add_timestamp32(&vp->clocksrc.timestamp,\n                                           frame_ts);\n                    }\n                }\n            }\n        }\n        \n        vp->frm_buf->size = vp->frm_buf_size;\n        status = pjmedia_port_get_frame(vp->client_port, vp->frm_buf);\n        if (status != PJ_SUCCESS) {\n            pjmedia_clock_src_update(&vp->clocksrc, NULL);\n            return status;\n        }\n        pj_add_timestamp32(&vp->clocksrc.timestamp, frame_ts);\n        pjmedia_clock_src_update(&vp->clocksrc, NULL);\n\n        status = convert_frame(vp, vp->frm_buf, frame);\n\tif (status != PJ_SUCCESS)\n            return status;\n\n\tif (!vp->conv.conv)\n\t    pj_memcpy(frame, vp->frm_buf, sizeof(*frame));\n    } else {\n        /* The stream is active while we are passive so we need to get the\n         * frame from the buffer.\n         * The encoding counterpart is located in vid_pasv_port_get_frame()\n         */\n        get_frame_from_buffer(vp, frame);\n    }\n    if (vp->strm_cb.render_cb)\n        return (*vp->strm_cb.render_cb)(stream, vp->strm_cb_data, frame);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t vid_pasv_port_put_frame(struct pjmedia_port *this_port,\n\t\t\t\t\t   pjmedia_frame *frame)\n{\n    struct vid_pasv_port *vpp = (struct vid_pasv_port*)this_port;\n    pjmedia_vid_port *vp = vpp->vp;\n\n    if (vp->stream_role==ROLE_PASSIVE) {\n        /* We are passive and the stream is passive.\n         * The encoding counterpart is in vid_pasv_port_get_frame().\n         */\n        pj_status_t status;\n        pjmedia_frame frame_;\n        \n        pj_bzero(&frame_, sizeof(frame_));\n        status = convert_frame(vp, frame, &frame_);\n        if (status != PJ_SUCCESS)\n            return status;\n\n\treturn pjmedia_vid_dev_stream_put_frame(vp->strm, (vp->conv.conv?\n                                                           &frame_: frame));\n    } else {\n        /* We are passive while the stream is active so we just store the\n         * frame in the buffer.\n         * The encoding counterpart is located in vidstream_cap_cb()\n         */\n        copy_frame_to_buffer(vp, frame);\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t vid_pasv_port_get_frame(struct pjmedia_port *this_port,\n\t\t\t\t\t   pjmedia_frame *frame)\n{\n    struct vid_pasv_port *vpp = (struct vid_pasv_port*)this_port;\n    pjmedia_vid_port *vp = vpp->vp;\n    pj_status_t status = PJ_SUCCESS;\n\n    if (vp->stream_role==ROLE_PASSIVE) {\n        /* We are passive and the stream is passive.\n         * The decoding counterpart is in vid_pasv_port_put_frame().\n         */\n\tstatus = pjmedia_vid_dev_stream_get_frame(vp->strm, (vp->conv.conv?\n                                                  vp->frm_buf: frame));\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n        status = convert_frame(vp, vp->frm_buf, frame);\n    } else {\n        /* The stream is active while we are passive so we need to get the\n         * frame from the buffer.\n         * The decoding counterpart is located in vidstream_rend_cb()\n         */\n        get_frame_from_buffer(vp, frame);\n    }\n\n    return status;\n}\n\n\n#endif /* PJMEDIA_HAS_VIDEO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/vid_stream.c",
    "content": "/* $Id: vid_stream.c 4197 2012-07-05 07:26:29Z nanang $ */\n/* \n * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/vid_stream.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/event.h>\n#include <pjmedia/rtp.h>\n#include <pjmedia/rtcp.h>\n#include <pjmedia/jbuf.h>\n#include <pjmedia/stream_common.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/compat/socket.h>\n#include <pj/errno.h>\n#include <pj/ioqueue.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/sock_select.h>\n#include <pj/string.h>\t    /* memcpy() */\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n\n#define THIS_FILE\t\t\t\"vid_stream.c\"\n#define ERRLEVEL\t\t\t1\n#define LOGERR_(expr)\t\t\tstream_perror expr\n#define TRC_(expr)\t\t\tPJ_LOG(5,expr)\n#define SIGNATURE\t\t\tPJMEDIA_SIG_PORT_VID_STREAM\n\n#define TRACE_RC\t\t\t0\n\n/* Tracing jitter buffer operations in a stream session to a CSV file.\n * The trace will contain JB operation timestamp, frame info, RTP info, and\n * the JB state right after the operation.\n */\n#define TRACE_JB\t\t\t0\t/* Enable/disable trace.    */\n#define TRACE_JB_PATH_PREFIX\t\t\"\"\t/* Optional path/prefix\n\t\t\t\t\t\t   for the CSV filename.    */\n#if TRACE_JB\n#   include <pj/file_io.h>\n#   define TRACE_JB_INVALID_FD\t\t((pj_oshandle_t)-1)\n#   define TRACE_JB_OPENED(s)\t\t(s->trace_jb_fd != TRACE_JB_INVALID_FD)\n#endif\n\n#ifndef PJMEDIA_VSTREAM_SIZE\n#   define PJMEDIA_VSTREAM_SIZE\t1000\n#endif\n\n#ifndef PJMEDIA_VSTREAM_INC\n#   define PJMEDIA_VSTREAM_INC\t1000\n#endif\n\n/* Due to network MTU limitation, a picture bitstream may be splitted into\n * several chunks for RTP delivery. The chunk number may vary depend on the\n * picture resolution and MTU. This constant specifies the minimum chunk\n * number to be allocated to store a picture bitstream in decoding direction.\n */\n#define MIN_CHUNKS_PER_FRM\t30\n\n/* Video stream keep-alive feature is currently disabled. */\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0\n#   undef PJMEDIA_STREAM_ENABLE_KA\n#   define PJMEDIA_STREAM_ENABLE_KA 0\n#endif\n\n\n/**\n * Media channel.\n */\ntypedef struct pjmedia_vid_channel\n{\n    pjmedia_vid_stream\t   *stream;\t    /**< Parent stream.\t\t    */\n    pjmedia_dir\t\t    dir;\t    /**< Channel direction.\t    */\n    pjmedia_port\t    port;\t    /**< Port interface.\t    */\n    unsigned\t\t    pt;\t\t    /**< Payload type.\t\t    */\n    pj_bool_t\t\t    paused;\t    /**< Paused?.\t\t    */\n    void\t\t   *buf;\t    /**< Output buffer.\t\t    */\n    unsigned\t\t    buf_size;\t    /**< Size of output buffer.\t    */\n    pjmedia_rtp_session\t    rtp;\t    /**< RTP session.\t\t    */\n} pjmedia_vid_channel;\n\n\n/**\n * This structure describes media stream.\n * A media stream is bidirectional media transmission between two endpoints.\n * It consists of two channels, i.e. encoding and decoding channels.\n * A media stream corresponds to a single \"m=\" line in a SDP session\n * description.\n */\nstruct pjmedia_vid_stream\n{\n    pj_pool_t\t\t    *own_pool;      /**< Internal pool.\t\t    */\n    pjmedia_endpt\t    *endpt;\t    /**< Media endpoint.\t    */\n    pjmedia_vid_codec_mgr   *codec_mgr;\t    /**< Codec manager.\t\t    */\n    pjmedia_vid_stream_info  info;\t    /**< Stream info.\t\t    */\n\n    pjmedia_vid_channel\t    *enc;\t    /**< Encoding channel.\t    */\n    pjmedia_vid_channel\t    *dec;\t    /**< Decoding channel.\t    */\n\n    pjmedia_dir\t\t     dir;\t    /**< Stream direction.\t    */\n    void\t\t    *user_data;\t    /**< User data.\t\t    */\n    pj_str_t\t\t     name;\t    /**< Stream name\t\t    */\n    pj_str_t\t\t     cname;\t    /**< SDES CNAME\t\t    */\n\n    pjmedia_transport\t    *transport;\t    /**< Stream transport.\t    */\n    unsigned\t\t     send_err_cnt;  /**< Send error count.          */\n\n    pj_mutex_t\t\t    *jb_mutex;\n    pjmedia_jbuf\t    *jb;\t    /**< Jitter buffer.\t\t    */\n    char\t\t     jb_last_frm;   /**< Last frame type from jb    */\n    unsigned\t\t     jb_last_frm_cnt;/**< Last JB frame type counter*/\n\n    pjmedia_rtcp_session     rtcp;\t    /**< RTCP for incoming RTP.\t    */\n    pj_uint32_t\t\t     rtcp_last_tx;  /**< RTCP tx time in timestamp  */\n    pj_uint32_t\t\t     rtcp_interval; /**< Interval, in timestamp.    */\n    pj_bool_t\t\t     initial_rr;    /**< Initial RTCP RR sent\t    */\n    pj_bool_t                rtcp_sdes_bye_disabled;/**< Send RTCP SDES/BYE?*/\n    void\t\t    *out_rtcp_pkt;  /**< Outgoing RTCP packet.\t    */\n    unsigned\t\t     out_rtcp_pkt_size;\n\t\t\t\t\t    /**< Outgoing RTCP packet size. */\n\n    unsigned\t\t     dec_max_size;  /**< Size of decoded/raw picture*/\n    pjmedia_ratio\t     dec_max_fps;   /**< Max fps of decoding dir.   */\n    pjmedia_frame            dec_frame;\t    /**< Current decoded frame.     */\n    pjmedia_event            fmt_event;\t    /**< Buffered fmt_changed event\n                                                 to avoid deadlock\t    */\n    pjmedia_event            found_keyframe_event; \n\t\t\t\t\t    /**< Buffered found keyframe\n                                                 event for delayed republish*/\n\n    pjmedia_event            miss_keyframe_event; \n\t\t\t\t\t    /**< Buffered missing keyframe\n                                                 event for delayed republish*/\n\n    pjmedia_event            keyframe_req_event; \n\t\t\t\t\t    /**< Buffered keyframe request\n                                                 event for delayed republish*/\n\n    unsigned\t\t     frame_size;    /**< Size of encoded base frame.*/\n    unsigned\t\t     frame_ts_len;  /**< Frame length in timestamp. */\n\n    unsigned\t\t     rx_frame_cnt;  /**< # of array in rx_frames    */\n    pjmedia_frame\t    *rx_frames;\t    /**< Temp. buffer for incoming\n\t\t\t\t\t         frame assembly.\t    */\n\n    pj_bool_t\t\t     force_keyframe;/**< Forced to encode keyframe? */\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0\n    pj_bool_t\t\t     use_ka;\t       /**< Stream keep-alive with non-\n\t\t\t\t\t\t    codec-VAD mechanism is\n\t\t\t\t\t\t    enabled?\t\t    */\n    pj_timestamp\t     last_frm_ts_sent; /**< Timestamp of last sending\n\t\t\t\t\t            packet\t\t    */\n#endif\n\n#if TRACE_JB\n    pj_oshandle_t\t     trace_jb_fd;   /**< Jitter tracing file handle.*/\n    char\t\t    *trace_jb_buf;  /**< Jitter tracing buffer.\t    */\n#endif\n\n    pjmedia_vid_codec\t    *codec;\t    /**< Codec instance being used. */\n    pj_uint32_t\t\t     last_dec_ts;   /**< Last decoded timestamp.    */\n    int\t\t\t     last_dec_seq;  /**< Last decoded sequence.     */\n    pj_status_t\t\t     rtp_rx_last_err; /**< Last RTP recv() error.   */\n\n    pj_timestamp\t     ts_freq;\t    /**< Timestamp frequency.\t    */\n\n#if TRACE_RC\n    unsigned\t\t     rc_total_sleep;\n    unsigned\t\t     rc_total_pkt;\n    unsigned\t\t     rc_total_img;\n    pj_timestamp\t     tx_start;\n    pj_timestamp\t     tx_end;\n#endif\n};\n\n/* Prototypes */\nstatic pj_status_t decode_frame(pjmedia_vid_stream *stream,\n                                pjmedia_frame *frame);\n\n/*\n * Print error.\n */\nstatic void stream_perror(const char *sender, const char *title,\n\t\t\t  pj_status_t status)\n{\n    char errmsg[PJ_ERR_MSG_SIZE];\n\n    pj_strerror(status, errmsg, sizeof(errmsg));\n    PJ_LOG(4,(sender, \"%s: %s [err:%d]\", title, errmsg, status));\n}\n\n\nstatic pj_status_t send_rtcp(pjmedia_vid_stream *stream,\n\t\t\t     pj_bool_t with_sdes,\n\t\t\t     pj_bool_t with_bye);\n\n\n#if TRACE_JB\n\nPJ_INLINE(int) trace_jb_print_timestamp(char **buf, pj_ssize_t len)\n{\n    pj_time_val now;\n    pj_parsed_time ptime;\n    char *p = *buf;\n\n    if (len < 14)\n\treturn -1;\n\n    pj_gettimeofday(&now);\n    pj_time_decode(&now, &ptime);\n    p += pj_utoa_pad(ptime.hour, p, 2, '0');\n    *p++ = ':';\n    p += pj_utoa_pad(ptime.min, p, 2, '0');\n    *p++ = ':';\n    p += pj_utoa_pad(ptime.sec, p, 2, '0');\n    *p++ = '.';\n    p += pj_utoa_pad(ptime.msec, p, 3, '0');\n    *p++ = ',';\n\n    *buf = p;\n\n    return 0;\n}\n\nPJ_INLINE(int) trace_jb_print_state(pjmedia_vid_stream *stream, \n\t\t\t\t    char **buf, pj_ssize_t len)\n{\n    char *p = *buf;\n    char *endp = *buf + len;\n    pjmedia_jb_state state;\n\n    pjmedia_jbuf_get_state(stream->jb, &state);\n\n    len = pj_ansi_snprintf(p, endp-p, \"%d, %d, %d\",\n\t\t\t   state.size, state.burst, state.prefetch);\n    if ((len < 0) || (len >= endp-p))\n\treturn -1;\n\n    p += len;\n    *buf = p;\n    return 0;\n}\n\nstatic void trace_jb_get(pjmedia_vid_stream *stream, pjmedia_jb_frame_type ft,\n\t\t\t pj_size_t fsize)\n{\n    char *p = stream->trace_jb_buf;\n    char *endp = stream->trace_jb_buf + PJ_LOG_MAX_SIZE;\n    pj_ssize_t len = 0;\n    const char* ft_st;\n\n    if (!TRACE_JB_OPENED(stream))\n\treturn;\n\n    /* Print timestamp. */\n    if (trace_jb_print_timestamp(&p, endp-p))\n\tgoto on_insuff_buffer;\n\n    /* Print frame type and size */\n    switch(ft) {\n\tcase PJMEDIA_JB_MISSING_FRAME:\n\t    ft_st = \"missing\";\n\t    break;\n\tcase PJMEDIA_JB_NORMAL_FRAME:\n\t    ft_st = \"normal\";\n\t    break;\n\tcase PJMEDIA_JB_ZERO_PREFETCH_FRAME:\n\t    ft_st = \"prefetch\";\n\t    break;\n\tcase PJMEDIA_JB_ZERO_EMPTY_FRAME:\n\t    ft_st = \"empty\";\n\t    break;\n\tdefault:\n\t    ft_st = \"unknown\";\n\t    break;\n    }\n\n    /* Print operation, size, frame count, frame type */\n    len = pj_ansi_snprintf(p, endp-p, \"GET,%d,1,%s,,,,\", fsize, ft_st);\n    if ((len < 0) || (len >= endp-p))\n\tgoto on_insuff_buffer;\n    p += len;\n\n    /* Print JB state */\n    if (trace_jb_print_state(stream, &p, endp-p))\n\tgoto on_insuff_buffer;\n\n    /* Print end of line */\n    if (endp-p < 2)\n\tgoto on_insuff_buffer;\n    *p++ = '\\n';\n\n    /* Write and flush */\n    len = p - stream->trace_jb_buf;\n    pj_file_write(stream->trace_jb_fd, stream->trace_jb_buf, &len);\n    pj_file_flush(stream->trace_jb_fd);\n    return;\n\non_insuff_buffer:\n    pj_assert(!\"Trace buffer too small, check PJ_LOG_MAX_SIZE!\");\n}\n\nstatic void trace_jb_put(pjmedia_vid_stream *stream,\n\t\t\t const pjmedia_rtp_hdr *hdr,\n\t\t\t unsigned payloadlen, unsigned frame_cnt)\n{\n    char *p = stream->trace_jb_buf;\n    char *endp = stream->trace_jb_buf + PJ_LOG_MAX_SIZE;\n    pj_ssize_t len = 0;\n\n    if (!TRACE_JB_OPENED(stream))\n\treturn;\n\n    /* Print timestamp. */\n    if (trace_jb_print_timestamp(&p, endp-p))\n\tgoto on_insuff_buffer;\n\n    /* Print operation, size, frame count, RTP info */\n    len = pj_ansi_snprintf(p, endp-p,\n\t\t\t   \"PUT,%d,%d,,%d,%d,%d,\",\n\t\t\t   payloadlen, frame_cnt,\n\t\t\t   pj_ntohs(hdr->seq), pj_ntohl(hdr->ts), hdr->m);\n    if ((len < 0) || (len >= endp-p))\n\tgoto on_insuff_buffer;\n    p += len;\n\n    /* Print JB state */\n    if (trace_jb_print_state(stream, &p, endp-p))\n\tgoto on_insuff_buffer;\n\n    /* Print end of line */\n    if (endp-p < 2)\n\tgoto on_insuff_buffer;\n    *p++ = '\\n';\n\n    /* Write and flush */\n    len = p - stream->trace_jb_buf;\n    pj_file_write(stream->trace_jb_fd, stream->trace_jb_buf, &len);\n    pj_file_flush(stream->trace_jb_fd);\n    return;\n\non_insuff_buffer:\n    pj_assert(!\"Trace buffer too small, check PJ_LOG_MAX_SIZE!\");\n}\n\n#endif /* TRACE_JB */\n\nstatic void dump_port_info(const pjmedia_vid_channel *chan,\n                           const char *event_name)\n{\n    const pjmedia_port_info *pi = &chan->port.info;\n    char fourcc_name[5];\n\n    PJ_LOG(4, (pi->name.ptr,\n\t       \" %s format %s: %dx%d %s%s %d/%d(~%d)fps\",\n\t       (chan->dir==PJMEDIA_DIR_DECODING? \"Decoding\":\"Encoding\"),\n\t       event_name,\n\t       pi->fmt.det.vid.size.w, pi->fmt.det.vid.size.h,\n\t       pjmedia_fourcc_name(pi->fmt.id, fourcc_name),\n\t       (chan->dir==PJMEDIA_DIR_ENCODING?\"->\":\"<-\"),\n\t       pi->fmt.det.vid.fps.num, pi->fmt.det.vid.fps.denum,\n\t       pi->fmt.det.vid.fps.num/pi->fmt.det.vid.fps.denum));\n}\n\n/*\n * Handle events from stream components.\n */\nstatic pj_status_t stream_event_cb(pjmedia_event *event,\n                                   void *user_data)\n{\n    pjmedia_vid_stream *stream = (pjmedia_vid_stream*)user_data;\n\n    if (event->epub == stream->codec) {\n\t/* This is codec event */\n\tswitch (event->type) {\n\tcase PJMEDIA_EVENT_FMT_CHANGED:\n\t    /* Copy the event to avoid deadlock if we publish the event\n\t     * now. This happens because fmt_event may trigger restart\n\t     * while we're still holding the jb_mutex.\n\t     */\n\t    pj_memcpy(&stream->fmt_event, event, sizeof(*event));\n\t    return PJ_SUCCESS;\n\n\tcase PJMEDIA_EVENT_KEYFRAME_FOUND:\n\t    /* Republish this event later from get_frame(). */\n\t    pj_memcpy(&stream->found_keyframe_event, event, sizeof(*event));\n\t    return PJ_SUCCESS;\n\n\tcase PJMEDIA_EVENT_KEYFRAME_MISSING:\n\t    /* Republish this event later from get_frame(). */\n\t    pj_memcpy(&stream->miss_keyframe_event, event, sizeof(*event));\n\t    return PJ_SUCCESS;\n\n\tdefault:\n\t    break;\n\t}\n    }\n\n    return pjmedia_event_publish(NULL, stream, event, 0);\n}\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0\n/*\n * Send keep-alive packet using non-codec frame.\n */\nstatic void send_keep_alive_packet(pjmedia_vid_stream *stream)\n{\n#if PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_EMPTY_RTP\n\n    /* Keep-alive packet is empty RTP */\n    pjmedia_vid_channel *channel = stream->enc;\n    pj_status_t status;\n    void *pkt;\n    int pkt_len;\n\n    TRC_((channel->port.info.name.ptr,\n\t  \"Sending keep-alive (RTCP and empty RTP)\"));\n\n    /* Send RTP */\n    status = pjmedia_rtp_encode_rtp( &stream->enc->rtp,\n\t\t\t\t     stream->enc->pt, 0,\n\t\t\t\t     1,\n\t\t\t\t     0,\n\t\t\t\t     (const void**)&pkt,\n\t\t\t\t     &pkt_len);\n    pj_assert(status == PJ_SUCCESS);\n\n    pj_memcpy(stream->enc->buf, pkt, pkt_len);\n    pjmedia_transport_send_rtp(stream->transport, stream->enc->buf,\n\t\t\t       pkt_len);\n\n    /* Send RTCP */\n    send_rtcp(stream, PJ_TRUE, PJ_FALSE);\n\n#elif PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER\n\n    /* Keep-alive packet is defined in PJMEDIA_STREAM_KA_USER_PKT */\n    pjmedia_vid_channel *channel = stream->enc;\n    int pkt_len;\n    const pj_str_t str_ka = PJMEDIA_STREAM_KA_USER_PKT;\n\n    TRC_((channel->port.info.name.ptr,\n\t  \"Sending keep-alive (custom RTP/RTCP packets)\"));\n\n    /* Send to RTP port */\n    pj_memcpy(stream->enc->buf, str_ka.ptr, str_ka.slen);\n    pkt_len = str_ka.slen;\n    pjmedia_transport_send_rtp(stream->transport, stream->enc->buf,\n\t\t\t       pkt_len);\n\n    /* Send to RTCP port */\n    pjmedia_transport_send_rtcp(stream->transport, stream->enc->buf,\n\t\t\t        pkt_len);\n\n#else\n    \n    PJ_UNUSED_ARG(stream);\n\n#endif\n}\n#endif\t/* defined(PJMEDIA_STREAM_ENABLE_KA) */\n\n\nstatic pj_status_t send_rtcp(pjmedia_vid_stream *stream,\n\t\t\t     pj_bool_t with_sdes,\n\t\t\t     pj_bool_t with_bye)\n{\n    void *sr_rr_pkt;\n    pj_uint8_t *pkt;\n    int len, max_len;\n    pj_status_t status;\n\n    /* Build RTCP RR/SR packet */\n    pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len);\n\n    if (with_sdes || with_bye) {\n\tpkt = (pj_uint8_t*) stream->out_rtcp_pkt;\n\tpj_memcpy(pkt, sr_rr_pkt, len);\n\tmax_len = stream->out_rtcp_pkt_size;\n    } else {\n\tpkt = (pj_uint8_t*)sr_rr_pkt;\n\tmax_len = len;\n    }\n\n    /* Build RTCP SDES packet */\n    if (with_sdes) {\n\tpjmedia_rtcp_sdes sdes;\n\tpj_size_t sdes_len;\n\n\tpj_bzero(&sdes, sizeof(sdes));\n\tsdes.cname = stream->cname;\n\tsdes_len = max_len - len;\n\tstatus = pjmedia_rtcp_build_rtcp_sdes(&stream->rtcp, pkt+len,\n\t\t\t\t\t      &sdes_len, &sdes);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(stream->name.ptr, status,\n        \t\t\t     \"Error generating RTCP SDES\"));\n\t} else {\n\t    len += (int)sdes_len;\n\t}\n    }\n\n    /* Build RTCP BYE packet */\n    if (with_bye) {\n\tpj_size_t bye_len;\n\n\tbye_len = max_len - len;\n\tstatus = pjmedia_rtcp_build_rtcp_bye(&stream->rtcp, pkt+len,\n\t\t\t\t\t     &bye_len, NULL);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(stream->name.ptr, status,\n        \t\t\t     \"Error generating RTCP BYE\"));\n\t} else {\n\t    len += (int)bye_len;\n\t}\n    }\n\n    /* Send! */\n    status = pjmedia_transport_send_rtcp(stream->transport, pkt, len);\n\n    return status;\n}\n\n\n/**\n * check_tx_rtcp()\n *\n * This function is can be called by either put_frame() or get_frame(),\n * to transmit periodic RTCP SR/RR report.\n */\nstatic void check_tx_rtcp(pjmedia_vid_stream *stream, pj_uint32_t timestamp)\n{\n    /* Note that timestamp may represent local or remote timestamp, \n     * depending on whether this function is called from put_frame()\n     * or get_frame().\n     */\n\n\n    if (stream->rtcp_last_tx == 0) {\n\t\n\tstream->rtcp_last_tx = timestamp;\n\n    } else if (timestamp - stream->rtcp_last_tx >= stream->rtcp_interval) {\n\tpj_status_t status;\n\t\n\tstatus = send_rtcp(stream, !stream->rtcp_sdes_bye_disabled, PJ_FALSE);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(stream->name.ptr, status,\n        \t\t \"Error sending RTCP\"));\n\t}\n\n\tstream->rtcp_last_tx = timestamp;\n    }\n}\n\n\n#if 0\nstatic void dump_bin(const char *buf, unsigned len)\n{\n    unsigned i;\n\n    PJ_LOG(3,(THIS_FILE, \"begin dump\"));\n    for (i=0; i<len; ++i) {\n\tint j;\n\tchar bits[9];\n\tunsigned val = buf[i] & 0xFF;\n\n\tbits[8] = '\\0';\n\tfor (j=0; j<8; ++j) {\n\t    if (val & (1 << (7-j)))\n\t\tbits[j] = '1';\n\t    else\n\t\tbits[j] = '0';\n\t}\n\n\tPJ_LOG(3,(THIS_FILE, \"%2d %s [%d]\", i, bits, val));\n    }\n    PJ_LOG(3,(THIS_FILE, \"end dump\"));\n}\n#endif\n\n\n/*\n * This callback is called by stream transport on receipt of packets\n * in the RTP socket. \n */\nstatic void on_rx_rtp( void *data, \n\t\t       void *pkt,\n                       pj_ssize_t bytes_read)\n\n{\n    pjmedia_vid_stream *stream = (pjmedia_vid_stream*) data;\n    pjmedia_vid_channel *channel = stream->dec;\n    const pjmedia_rtp_hdr *hdr;\n    const void *payload;\n    unsigned payloadlen;\n    pjmedia_rtp_status seq_st;\n    pj_status_t status;\n    pj_bool_t pkt_discarded = PJ_FALSE;\n\n    /* Check for errors */\n    if (bytes_read < 0) {\n\tstatus = (pj_status_t)-bytes_read;\n\tif (status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) {\n\t    return;\n\t}\n\tif (stream->rtp_rx_last_err != status) {\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\t    pj_strerror(status, errmsg, sizeof(errmsg));\n\t    PJ_LOG(4,(channel->port.info.name.ptr,\n\t\t      \"Unable to receive RTP packet, recv() returned %d: %s\",\n\t\t      status, errmsg));\n\t    stream->rtp_rx_last_err = status;\n\t}\n\treturn;\n    } else {\n\tstream->rtp_rx_last_err = PJ_SUCCESS;\n    }\n\n    /* Ignore keep-alive packets */\n    if (bytes_read < (pj_ssize_t) sizeof(pjmedia_rtp_hdr))\n\treturn;\n\n    /* Update RTP and RTCP session. */\n    status = pjmedia_rtp_decode_rtp(&channel->rtp, pkt, (int)bytes_read,\n\t\t\t\t    &hdr, &payload, &payloadlen);\n    if (status != PJ_SUCCESS) {\n\tLOGERR_((channel->port.info.name.ptr, \"RTP decode error\", status));\n\tstream->rtcp.stat.rx.discard++;\n\treturn;\n    }\n\n    /* Ignore the packet if decoder is paused */\n    if (channel->paused)\n\tgoto on_return;\n\n    /* Update RTP session (also checks if RTP session can accept\n     * the incoming packet.\n     */\n    pjmedia_rtp_session_update2(&channel->rtp, hdr, &seq_st, PJ_TRUE);\n    if (seq_st.status.value) {\n\tTRC_  ((channel->port.info.name.ptr, \n\t\t\"RTP status: badpt=%d, badssrc=%d, dup=%d, \"\n\t\t\"outorder=%d, probation=%d, restart=%d\", \n\t\tseq_st.status.flag.badpt,\n\t\tseq_st.status.flag.badssrc,\n\t\tseq_st.status.flag.dup,\n\t\tseq_st.status.flag.outorder,\n\t\tseq_st.status.flag.probation,\n\t\tseq_st.status.flag.restart));\n\n\tif (seq_st.status.flag.badpt) {\n\t    PJ_LOG(4,(channel->port.info.name.ptr,\n\t\t      \"Bad RTP pt %d (expecting %d)\",\n\t\t      hdr->pt, channel->rtp.out_pt));\n\t}\n\n\tif (seq_st.status.flag.badssrc) {\n\t    PJ_LOG(4,(channel->port.info.name.ptr,\n\t\t      \"Changed RTP peer SSRC %d (previously %d)\",\n\t\t      channel->rtp.peer_ssrc, stream->rtcp.peer_ssrc));\n\t    stream->rtcp.peer_ssrc = channel->rtp.peer_ssrc;\n\t}\n\n\n    }\n\n    /* Skip bad RTP packet */\n    if (seq_st.status.flag.bad) {\n\tpkt_discarded = PJ_TRUE;\n\tgoto on_return;\n    }\n\n    /* Ignore if payloadlen is zero */\n    if (payloadlen == 0) {\n\tpkt_discarded = PJ_TRUE;\n\tgoto on_return;\n    }\n\n    pj_mutex_lock( stream->jb_mutex );\n\n    /* Quickly see if there may be a full picture in the jitter buffer, and\n     * decode them if so. More thorough check will be done in decode_frame().\n     */\n    if ((pj_ntohl(hdr->ts) != stream->dec_frame.timestamp.u32.lo) || hdr->m) {\n\tif (PJMEDIA_VID_STREAM_SKIP_PACKETS_TO_REDUCE_LATENCY) {\n\t    /* Always decode whenever we have picture in jb and\n\t     * overwrite already decoded picture if necessary\n\t     */\n\t    pj_size_t old_size = stream->dec_frame.size;\n\n\t    stream->dec_frame.size = stream->dec_max_size;\n\t    if (decode_frame(stream, &stream->dec_frame) != PJ_SUCCESS) {\n\t\tstream->dec_frame.size = old_size;\n\t    }\n\t} else {\n\t    /* Only decode if we don't already have decoded one,\n\t     * unless the jb is full.\n\t     */\n\t    pj_bool_t can_decode = PJ_FALSE;\n\n\t    if (pjmedia_jbuf_is_full(stream->jb)) {\n\t\tcan_decode = PJ_TRUE;\n\t    }\n\t    else if (stream->dec_frame.size == 0) {\n\t\tcan_decode = PJ_TRUE;\n\t    }\n\n\t    if (can_decode) {\n\t\tstream->dec_frame.size = stream->dec_max_size;\n\t\tif (decode_frame(stream, &stream->dec_frame) != PJ_SUCCESS) {\n\t\t    stream->dec_frame.size = 0;\n\t\t}\n\t    }\n\t}\n    }\n\n    /* Put \"good\" packet to jitter buffer, or reset the jitter buffer\n     * when RTP session is restarted.\n     */\n    if (seq_st.status.flag.restart) {\n\tstatus = pjmedia_jbuf_reset(stream->jb);\n\tPJ_LOG(4,(channel->port.info.name.ptr, \"Jitter buffer reset\"));\n    } else {\n\t/* Just put the payload into jitter buffer */\n\tpjmedia_jbuf_put_frame3(stream->jb, payload, payloadlen, 0, \n\t\t\t\tpj_ntohs(hdr->seq), pj_ntohl(hdr->ts), NULL);\n\n#if TRACE_JB\n\ttrace_jb_put(stream, hdr, payloadlen, count);\n#endif\n\n    }\n    pj_mutex_unlock( stream->jb_mutex );\n\n\n    /* Check if now is the time to transmit RTCP SR/RR report.\n     * We only do this when stream direction is \"decoding only\", \n     * because otherwise check_tx_rtcp() will be handled by put_frame()\n     */\n    if (stream->dir == PJMEDIA_DIR_DECODING) {\n\tcheck_tx_rtcp(stream, pj_ntohl(hdr->ts));\n    }\n\n    if (status != 0) {\n\tLOGERR_((channel->port.info.name.ptr, \"Jitter buffer put() error\", \n\t\tstatus));\n\tpkt_discarded = PJ_TRUE;\n\tgoto on_return;\n    }\n\non_return:\n    /* Update RTCP session */\n    if (stream->rtcp.peer_ssrc == 0)\n\tstream->rtcp.peer_ssrc = channel->rtp.peer_ssrc;\n\n    pjmedia_rtcp_rx_rtp2(&stream->rtcp, pj_ntohs(hdr->seq),\n\t\t\t pj_ntohl(hdr->ts), payloadlen, pkt_discarded);\n\n    /* Send RTCP RR and SDES after we receive some RTP packets */\n    if (stream->rtcp.received >= 10 && !stream->initial_rr) {\n\tstatus = send_rtcp(stream, !stream->rtcp_sdes_bye_disabled,\n\t\t\t   PJ_FALSE);\n        if (status != PJ_SUCCESS) {\n            PJ_PERROR(4,(stream->name.ptr, status,\n            \t     \"Error sending initial RTCP RR\"));\n\t} else {\n\t    stream->initial_rr = PJ_TRUE;\n\t}\n    }\n}\n\n\n/*\n * This callback is called by stream transport on receipt of packets\n * in the RTCP socket. \n */\nstatic void on_rx_rtcp( void *data,\n                        void *pkt, \n                        pj_ssize_t bytes_read)\n{\n    pjmedia_vid_stream *stream = (pjmedia_vid_stream*) data;\n\n    /* Check for errors */\n    if (bytes_read < 0) {\n\tif (bytes_read != -PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) {\n\t    LOGERR_((stream->cname.ptr, \"RTCP recv() error\",\n\t\t    (pj_status_t)-bytes_read));\n\t}\n\treturn;\n    }\n\n    pjmedia_rtcp_rx_rtcp(&stream->rtcp, pkt, bytes_read);\n\n    /* XXX: posting some event from the RTCP session might be a better option */\n    if (stream->rtcp.keyframe_requested) {\n        pjmedia_event event;\n        pjmedia_event_init(&event, PJMEDIA_EVENT_KEYFRAME_REQUESTED, NULL, stream);\n\tpj_memcpy(&stream->keyframe_req_event, &event, sizeof(event));\n    }\n}\n\nstatic pj_status_t put_frame(pjmedia_port *port,\n                             pjmedia_frame *frame)\n{\n    pjmedia_vid_stream *stream = (pjmedia_vid_stream*) port->port_data.pdata;\n    pjmedia_vid_channel *channel = stream->enc;\n    pj_status_t status = 0;\n    pjmedia_frame frame_out;\n    unsigned rtp_ts_len;\n    void *rtphdr;\n    int rtphdrlen;\n    pj_bool_t has_more_data = PJ_FALSE;\n    pj_size_t total_sent = 0;\n    pjmedia_vid_encode_opt enc_opt;\n    unsigned pkt_cnt = 0;\n    pj_timestamp initial_time;\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0\n    /* If the interval since last sending packet is greater than\n     * PJMEDIA_STREAM_KA_INTERVAL, send keep-alive packet.\n     */\n    if (stream->use_ka)\n    {\n\tpj_uint32_t dtx_duration;\n\n\tdtx_duration = pj_timestamp_diff32(&stream->last_frm_ts_sent, \n\t\t\t\t\t   &frame->timestamp);\n        /* Video stream keep-alive feature is currently disabled. */\n        /*\n        if (dtx_duration >\n\t    PJMEDIA_STREAM_KA_INTERVAL *\n            PJMEDIA_PIA_SRATE(&channel->port.info))\n\t{\n\t    send_keep_alive_packet(stream);\n\t    stream->last_frm_ts_sent = frame->timestamp;\n\t}\n        */\n    }\n#endif\n\n    /* Don't do anything if stream is paused */\n    if (channel->paused) {\n\treturn PJ_SUCCESS;\n    }\n\n    /* Get frame length in timestamp unit */\n    rtp_ts_len = stream->frame_ts_len;\n\n    /* Init frame_out buffer. */\n    frame_out.buf = ((char*)channel->buf) + sizeof(pjmedia_rtp_hdr);\n    frame_out.size = 0;\n\n    /* Init encoding option */\n    pj_bzero(&enc_opt, sizeof(enc_opt));\n    if (stream->force_keyframe) {\n\t/* Force encoder to generate keyframe */\n\tenc_opt.force_keyframe = PJ_TRUE;\n\tstream->force_keyframe = PJ_FALSE;\n\tTRC_((channel->port.info.name.ptr,\n\t      \"Forcing encoder to generate keyframe\"));\n    }\n\n    /* Encode! */\n    status = pjmedia_vid_codec_encode_begin(stream->codec, &enc_opt, frame,\n                                            channel->buf_size -\n                                               sizeof(pjmedia_rtp_hdr),\n                                            &frame_out,\n                                            &has_more_data);\n    if (status != PJ_SUCCESS) {\n\tLOGERR_((channel->port.info.name.ptr,\n\t\t\"Codec encode_begin() error\", status));\n\n\t/* Update RTP timestamp */\n\tpjmedia_rtp_encode_rtp(&channel->rtp, channel->pt, 1, 0,\n\t\t\t       rtp_ts_len,  (const void**)&rtphdr,\n\t\t\t       &rtphdrlen);\n\treturn status;\n    }\n    \n    pj_get_timestamp(&initial_time);\n\n    /* Loop while we have frame to send */\n    for (;;) {\n\tstatus = pjmedia_rtp_encode_rtp(&channel->rtp,\n\t                                channel->pt,\n\t                                (has_more_data == PJ_FALSE ? 1 : 0),\n\t                                (int)frame_out.size,\n\t                                rtp_ts_len,\n\t                                (const void**)&rtphdr,\n\t                                &rtphdrlen);\n\tif (status != PJ_SUCCESS) {\n\t    LOGERR_((channel->port.info.name.ptr,\n\t\t    \"RTP encode_rtp() error\", status));\n\t    return status;\n\t}\n\n\t/* When the payload length is zero, we should not send anything,\n\t * but proceed the rest normally.\n\t */\n\tif (frame_out.size != 0) {\n\t    /* Copy RTP header to the beginning of packet */\n\t    pj_memcpy(channel->buf, rtphdr, sizeof(pjmedia_rtp_hdr));\n\n\t    /* Send the RTP packet to the transport. */\n\t    status = pjmedia_transport_send_rtp(stream->transport,\n\t\t\t\t\t\t(char*)channel->buf,\n\t\t\t\t\t\tframe_out.size +\n\t\t\t\t\t\t    sizeof(pjmedia_rtp_hdr));\n\t    if (status != PJ_SUCCESS) {\n\t\tenum { COUNT_TO_REPORT = 20 };\n\t\tif (stream->send_err_cnt++ == 0) {\n\t\t    LOGERR_((channel->port.info.name.ptr,\n\t\t\t     \"Transport send_rtp() error\",\n\t\t\t     status));\n\t\t}\n\t\tif (stream->send_err_cnt > COUNT_TO_REPORT)\n\t\t    stream->send_err_cnt = 0;\n\t\t/* Ignore this error */\n\t    }\n\n\t    pjmedia_rtcp_tx_rtp(&stream->rtcp, (unsigned)frame_out.size);\n\t    total_sent += frame_out.size;\n\t    pkt_cnt++;\n\t}\n\n\tif (!has_more_data)\n\t    break;\n\n\t/* Next packets use same timestamp */\n\trtp_ts_len = 0;\n\n\tframe_out.size = 0;\n\n\t/* Encode more! */\n\tstatus = pjmedia_vid_codec_encode_more(stream->codec,\n\t                                       channel->buf_size -\n\t\t\t\t\t\t   sizeof(pjmedia_rtp_hdr),\n\t\t\t\t               &frame_out,\n\t\t\t\t\t       &has_more_data);\n\tif (status != PJ_SUCCESS) {\n\t    LOGERR_((channel->port.info.name.ptr,\n\t\t     \"Codec encode_more() error\", status));\n\t    /* Ignore this error (?) */\n\t    break;\n\t}\n\n\t/* Send rate control */\n\tif (stream->info.rc_cfg.method==PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING)\n\t{\n\t    pj_timestamp now, next_send_ts, total_send_ts;\n\n\t    total_send_ts.u64 = total_sent * stream->ts_freq.u64 * 8 /\n\t\t\t\tstream->info.rc_cfg.bandwidth;\n\t    next_send_ts = initial_time;\n\t    pj_add_timestamp(&next_send_ts, &total_send_ts);\n\n\t    pj_get_timestamp(&now);\n\t    if (pj_cmp_timestamp(&now, &next_send_ts) < 0) {\n\t\tunsigned ms_sleep;\n\t\tms_sleep = pj_elapsed_msec(&now, &next_send_ts);\n\n\t\tif (ms_sleep > 10)\n\t\t    ms_sleep = 10;\n\n\t\tpj_thread_sleep(ms_sleep);\n\t    }\n\t}\n    }\n\n#if TRACE_RC\n    /* Trace log for rate control */\n    {\n\tpj_timestamp end_time;\n\tunsigned total_sleep;\n\n\tpj_get_timestamp(&end_time);\n\ttotal_sleep = pj_elapsed_msec(&initial_time, &end_time);\n\tPJ_LOG(5, (stream->name.ptr, \"total pkt=%d size=%d sleep=%d\",\n\t\t   pkt_cnt, total_sent, total_sleep));\n\n\tif (stream->tx_start.u64 == 0)\n\t    stream->tx_start = initial_time;\n\tstream->tx_end = end_time;\n\tstream->rc_total_pkt += pkt_cnt;\n\tstream->rc_total_sleep += total_sleep;\n\tstream->rc_total_img++;\n    }\n#endif\n\n    /* Check if now is the time to transmit RTCP SR/RR report. \n     * We only do this when stream direction is not \"decoding only\", because\n     * when it is, check_tx_rtcp() will be handled by get_frame().\n     */\n    if (stream->dir != PJMEDIA_DIR_DECODING) {\n\tcheck_tx_rtcp(stream, pj_ntohl(channel->rtp.out_hdr.ts));\n    }\n\n    /* Do nothing if we have nothing to transmit */\n    if (total_sent == 0) {\n\treturn PJ_SUCCESS;\n    }\n\n    /* Update stat */\n    if (pkt_cnt) {\n\tstream->rtcp.stat.rtp_tx_last_ts =\n\t\tpj_ntohl(stream->enc->rtp.out_hdr.ts);\n\tstream->rtcp.stat.rtp_tx_last_seq =\n\t\tpj_ntohs(stream->enc->rtp.out_hdr.seq);\n    }\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0\n    /* Update timestamp of last sending packet. */\n    stream->last_frm_ts_sent = frame->timestamp;\n#endif\n\n    return PJ_SUCCESS;\n}\n\n/* Decode one image from jitter buffer */\nstatic pj_status_t decode_frame(pjmedia_vid_stream *stream,\n                                pjmedia_frame *frame)\n{\n    pjmedia_vid_channel *channel = stream->dec;\n    pj_uint32_t last_ts = 0;\n    int frm_first_seq = 0, frm_last_seq = 0;\n    pj_bool_t got_frame = PJ_FALSE;\n    unsigned cnt;\n    pj_status_t status;\n\n    /* Repeat get payload from the jitter buffer until all payloads with same\n     * timestamp are collected.\n     */\n\n    /* Check if we got a decodable frame */\n    for (cnt=0; ; ++cnt) {\n\tchar ptype;\n\tpj_uint32_t ts;\n\tint seq;\n\n\t/* Peek frame from jitter buffer. */\n\tpjmedia_jbuf_peek_frame(stream->jb, cnt, NULL, NULL,\n\t\t\t\t&ptype, NULL, &ts, &seq);\n\tif (ptype == PJMEDIA_JB_NORMAL_FRAME) {\n\t    if (last_ts == 0) {\n\t\tlast_ts = ts;\n\t\tfrm_first_seq = seq;\n\t    }\n\t    if (ts != last_ts) {\n\t\tgot_frame = PJ_TRUE;\n\t\tbreak;\n\t    }\n\t    frm_last_seq = seq;\n\t} else if (ptype == PJMEDIA_JB_ZERO_EMPTY_FRAME) {\n\t    /* No more packet in the jitter buffer */\n\t    break;\n\t}\n    }\n\n    if (got_frame) {\n\tunsigned i;\n\n\t/* Generate frame bitstream from the payload */\n\tif (cnt > stream->rx_frame_cnt) {\n\t    PJ_LOG(1,(channel->port.info.name.ptr,\n\t\t      \"Discarding %u frames because array is full!\",\n\t\t      cnt - stream->rx_frame_cnt));\n\t    pjmedia_jbuf_remove_frame(stream->jb, cnt - stream->rx_frame_cnt);\n\t    cnt = stream->rx_frame_cnt;\n\t}\n\n\tfor (i = 0; i < cnt; ++i) {\n\t    char ptype;\n\n\t    stream->rx_frames[i].type = PJMEDIA_FRAME_TYPE_VIDEO;\n\t    stream->rx_frames[i].timestamp.u64 = last_ts;\n\t    stream->rx_frames[i].bit_info = 0;\n\n\t    /* We use jbuf_peek_frame() as it will returns the pointer of\n\t     * the payload (no buffer and memcpy needed), just as we need.\n\t     */\n\t    pjmedia_jbuf_peek_frame(stream->jb, i,\n\t\t\t\t    (const void**)&stream->rx_frames[i].buf,\n\t\t\t\t    &stream->rx_frames[i].size, &ptype,\n\t\t\t\t    NULL, NULL, NULL);\n\n\t    if (ptype != PJMEDIA_JB_NORMAL_FRAME) {\n\t\t/* Packet lost, must set payload to NULL and keep going */\n\t\tstream->rx_frames[i].buf = NULL;\n\t\tstream->rx_frames[i].size = 0;\n\t\tstream->rx_frames[i].type = PJMEDIA_FRAME_TYPE_NONE;\n\t\tcontinue;\n\t    }\n\t}\n\n\t/* Decode */\n\tstatus = pjmedia_vid_codec_decode(stream->codec, cnt,\n\t                                  stream->rx_frames,\n\t                                  (unsigned)frame->size, frame);\n\tif (status != PJ_SUCCESS) {\n\t    LOGERR_((channel->port.info.name.ptr, \"codec decode() error\",\n\t\t     status));\n\t    frame->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    frame->size = 0;\n\t}\n\n\tpjmedia_jbuf_remove_frame(stream->jb, cnt);\n    }\n\n    /* Learn remote frame rate after successful decoding */\n    if (frame->type == PJMEDIA_FRAME_TYPE_VIDEO && frame->size)\n    {\n\t/* Only check remote frame rate when timestamp is not wrapping and\n\t * sequence is increased by 1.\n\t */\n\tif (last_ts > stream->last_dec_ts &&\n\t    frm_first_seq - stream->last_dec_seq == 1)\n\t{\n\t    pj_uint32_t ts_diff;\n\t    pjmedia_video_format_detail *vfd;\n\n\t    ts_diff = last_ts - stream->last_dec_ts;\n\t    vfd = pjmedia_format_get_video_format_detail(\n\t\t\t\t    &channel->port.info.fmt, PJ_TRUE);\n\t    if (stream->info.codec_info.clock_rate * vfd->fps.denum !=\n\t\tvfd->fps.num * ts_diff)\n\t    {\n\t\t/* Frame rate changed, update decoding port info */\n\t\tif (stream->info.codec_info.clock_rate % ts_diff == 0) {\n\t\t    vfd->fps.num = stream->info.codec_info.clock_rate/ts_diff;\n\t\t    vfd->fps.denum = 1;\n\t\t} else {\n\t\t    vfd->fps.num = stream->info.codec_info.clock_rate;\n\t\t    vfd->fps.denum = ts_diff;\n\t\t}\n\n\t\t/* Update stream info */\n\t\tstream->info.codec_param->dec_fmt.det.vid.fps = vfd->fps;\n\n\t\t/* Publish PJMEDIA_EVENT_FMT_CHANGED event if frame rate\n\t\t * increased and not exceeding 60fps.\n\t\t */\n\t\tif (vfd->fps.num/vfd->fps.denum <= 60.0 &&\n\t\t    vfd->fps.num * stream->dec_max_fps.denum >\n\t\t    stream->dec_max_fps.num * vfd->fps.denum)\n\t\t{\n\t\t    /*printf(\"FPS CHANGED: %d/%d -> %d/%d\\n\", stream->dec_max_fps.num, stream->dec_max_fps.denum, vfd->fps.num, vfd->fps.denum);*/\n\t\t    pjmedia_event *event = &stream->fmt_event;\n\n\t\t    /* Update max fps of decoding dir */\n\t\t    stream->dec_max_fps = vfd->fps;\n\n\t\t    /* Use the buffered format changed event:\n\t\t     * - just update the framerate if there is pending event,\n\t\t     * - otherwise, init the whole event.\n\t\t     */\n\t\t    if (stream->fmt_event.type != PJMEDIA_EVENT_NONE) {\n\t\t\tevent->data.fmt_changed.new_fmt.det.vid.fps = vfd->fps;\n\t\t    } else {\n\t\t\tpjmedia_event_init(event, PJMEDIA_EVENT_FMT_CHANGED,\n\t\t\t\t\t   &frame->timestamp, stream);\n\t\t\tevent->data.fmt_changed.dir = PJMEDIA_DIR_DECODING;\n\t\t\tpj_memcpy(&event->data.fmt_changed.new_fmt,\n\t\t\t\t  &stream->info.codec_param->dec_fmt,\n\t\t\t\t  sizeof(pjmedia_format));\n\t\t    }\n\t\t}\n\t    }\n\t}\n\n\t/* Update last frame seq and timestamp */\n\tstream->last_dec_seq = frm_last_seq;\n\tstream->last_dec_ts = last_ts;\n    }\n\n    return got_frame ? PJ_SUCCESS : PJ_ENOTFOUND;\n}\n\n\nstatic pj_status_t get_frame(pjmedia_port *port,\n                             pjmedia_frame *frame)\n{\n    pjmedia_vid_stream *stream = (pjmedia_vid_stream*) port->port_data.pdata;\n    pjmedia_vid_channel *channel = stream->dec;\n\n    /* Return no frame is channel is paused */\n    if (channel->paused) {\n\tframe->type = PJMEDIA_FRAME_TYPE_NONE;\n\tframe->size = 0;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Report pending events. Do not publish the event while holding the\n     * jb_mutex as that would lead to deadlock. It should be safe to\n     * operate on fmt_event without the mutex because format change normally\n     * would only occur once during the start of the media.\n     */\n    if (stream->fmt_event.type != PJMEDIA_EVENT_NONE) {\n\tpjmedia_event_fmt_changed_data *fmt_chg_data;\n\n\tfmt_chg_data = &stream->fmt_event.data.fmt_changed;\n\n\t/* Update stream info and decoding channel port info */\n\tif (fmt_chg_data->dir == PJMEDIA_DIR_DECODING) {\n\t    pjmedia_format_copy(&stream->info.codec_param->dec_fmt,\n\t\t\t\t&fmt_chg_data->new_fmt);\n\t    pjmedia_format_copy(&stream->dec->port.info.fmt,\n\t\t\t\t&fmt_chg_data->new_fmt);\n\n\t    /* Override the framerate to be 1.5x higher in the event\n\t     * for the renderer.\n\t     */\n#if 0\n\t    fmt_chg_data->new_fmt.det.vid.fps.num *= 3;\n\t    fmt_chg_data->new_fmt.det.vid.fps.num /= 2;\n#endif\n\t} else {\n\t    pjmedia_format_copy(&stream->info.codec_param->enc_fmt,\n\t\t\t\t&fmt_chg_data->new_fmt);\n\t    pjmedia_format_copy(&stream->enc->port.info.fmt,\n\t\t\t\t&fmt_chg_data->new_fmt);\n\t}\n\n\tdump_port_info(fmt_chg_data->dir==PJMEDIA_DIR_DECODING ?\n\t\t\tstream->dec : stream->enc,\n\t\t       \"changed\");\n\n\tpjmedia_event_publish(NULL, port, &stream->fmt_event, 0);\n\n\tstream->fmt_event.type = PJMEDIA_EVENT_NONE;\n    }\n\n    if (stream->found_keyframe_event.type != PJMEDIA_EVENT_NONE) {\n\tpjmedia_event_publish(NULL, port, &stream->found_keyframe_event,\n\t\t\t      PJMEDIA_EVENT_PUBLISH_POST_EVENT);\n\tstream->found_keyframe_event.type = PJMEDIA_EVENT_NONE;\n    }\n\n    if (stream->miss_keyframe_event.type != PJMEDIA_EVENT_NONE) {\n\tpjmedia_event_publish(NULL, port, &stream->miss_keyframe_event,\n\t\t\t      PJMEDIA_EVENT_PUBLISH_POST_EVENT);\n\tstream->miss_keyframe_event.type = PJMEDIA_EVENT_NONE;\n    }\n\n    if (stream->keyframe_req_event.type != PJMEDIA_EVENT_NONE) {\n\tpjmedia_event_publish(NULL, port, &stream->keyframe_req_event,\n\t\t\t      PJMEDIA_EVENT_PUBLISH_POST_EVENT);\n\tstream->keyframe_req_event.type = PJMEDIA_EVENT_NONE;\n    }\n\n    pj_mutex_lock( stream->jb_mutex );\n\n    if (stream->dec_frame.size == 0) {\n\t/* Don't have frame in buffer, try to decode one */\n\tif (decode_frame(stream, frame) != PJ_SUCCESS) {\n\t    frame->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    frame->size = 0;\n\t}\n    } else {\n\tif (frame->size < stream->dec_frame.size) {\n\t    PJ_LOG(4,(stream->dec->port.info.name.ptr,\n\t\t      \"Error: not enough buffer for decoded frame \"\n\t\t      \"(supplied=%d, required=%d)\",\n\t\t      (int)frame->size, (int)stream->dec_frame.size));\n\t    frame->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    frame->size = 0;\n\t} else {\n\t    frame->type = stream->dec_frame.type;\n\t    frame->timestamp = stream->dec_frame.timestamp;\n\t    frame->size = stream->dec_frame.size;\n\t    pj_memcpy(frame->buf, stream->dec_frame.buf, frame->size);\n\t}\n\n\tstream->dec_frame.size = 0;\n    }\n\n    pj_mutex_unlock( stream->jb_mutex );\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Create media channel.\n */\nstatic pj_status_t create_channel( pj_pool_t *pool,\n\t\t\t\t   pjmedia_vid_stream *stream,\n\t\t\t\t   pjmedia_dir dir,\n\t\t\t\t   unsigned pt,\n\t\t\t\t   const pjmedia_vid_stream_info *info,\n\t\t\t\t   pjmedia_vid_channel **p_channel)\n{\n    enum { M = 32 };\n    pjmedia_vid_channel *channel;\n    pj_status_t status;\n    unsigned min_out_pkt_size;\n    pj_str_t name;\n    const char *type_name;\n    pjmedia_format *fmt;\n    char fourcc_name[5];\n    pjmedia_port_info *pi;\n    \n    pj_assert(info->type == PJMEDIA_TYPE_VIDEO);\n    pj_assert(dir == PJMEDIA_DIR_DECODING || dir == PJMEDIA_DIR_ENCODING);\n\n    /* Allocate memory for channel descriptor */\n    channel = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_channel);\n    PJ_ASSERT_RETURN(channel != NULL, PJ_ENOMEM);\n\n    /* Init vars */\n    if (dir==PJMEDIA_DIR_DECODING) {\n\ttype_name = \"vstdec\";\n\tfmt = &info->codec_param->dec_fmt;\n    } else {\n\ttype_name = \"vstenc\";\n\tfmt = &info->codec_param->enc_fmt;\n    }\n    name.ptr = (char*) pj_pool_alloc(pool, M);\n    name.slen = pj_ansi_snprintf(name.ptr, M, \"%s%p\", type_name, stream);\n    pi = &channel->port.info;\n\n    /* Init channel info. */\n    channel->stream = stream;\n    channel->dir = dir;\n    channel->paused = 1;\n    channel->pt = pt;\n    \n    /* Allocate buffer for outgoing packet. */\n    if (dir == PJMEDIA_DIR_ENCODING) {\n\tchannel->buf_size = sizeof(pjmedia_rtp_hdr) + stream->frame_size;\n\n\t/* It should big enough to hold (minimally) RTCP SR with an SDES. */\n\tmin_out_pkt_size =  sizeof(pjmedia_rtcp_sr_pkt) +\n\t\t\t    sizeof(pjmedia_rtcp_common) +\n\t\t\t    (4 + (unsigned)stream->cname.slen) +\n\t\t\t    32;\n\n\tif (channel->buf_size < min_out_pkt_size)\n\t    channel->buf_size = min_out_pkt_size;\n\n\tchannel->buf = pj_pool_alloc(pool, channel->buf_size);\n\tPJ_ASSERT_RETURN(channel->buf != NULL, PJ_ENOMEM);\n    }\n\n    /* Create RTP and RTCP sessions: */\n    if (info->rtp_seq_ts_set == 0) {\n\tstatus = pjmedia_rtp_session_init(&channel->rtp, pt, info->ssrc);\n    } else {\n\tpjmedia_rtp_session_setting settings;\n\n\tsettings.flags = (pj_uint8_t)((info->rtp_seq_ts_set << 2) | 3);\n\tsettings.default_pt = pt;\n\tsettings.sender_ssrc = info->ssrc;\n\tsettings.seq = info->rtp_seq;\n\tsettings.ts = info->rtp_ts;\n\tstatus = pjmedia_rtp_session_init2(&channel->rtp, settings);\n    }\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Init port. */\n    pjmedia_port_info_init2(pi, &name, SIGNATURE, dir, fmt);\n    if (dir == PJMEDIA_DIR_DECODING) {\n\tchannel->port.get_frame = &get_frame;\n    } else {\n\tpi->fmt.id = info->codec_param->dec_fmt.id;\n\tchannel->port.put_frame = &put_frame;\n    }\n\n    /* Init port. */\n    channel->port.port_data.pdata = stream;\n\n    PJ_LOG(5, (name.ptr,\n\t       \"%s channel created %dx%d %s%s%.*s %d/%d(~%d)fps\",\n\t       (dir==PJMEDIA_DIR_ENCODING?\"Encoding\":\"Decoding\"),\n\t       pi->fmt.det.vid.size.w, pi->fmt.det.vid.size.h,\n\t       pjmedia_fourcc_name(pi->fmt.id, fourcc_name),\n\t       (dir==PJMEDIA_DIR_ENCODING?\"->\":\"<-\"),\n\t       info->codec_info.encoding_name.slen,\n\t       info->codec_info.encoding_name.ptr,\n\t       pi->fmt.det.vid.fps.num, pi->fmt.det.vid.fps.denum,\n\t       pi->fmt.det.vid.fps.num/pi->fmt.det.vid.fps.denum));\n\n    /* Done. */\n    *p_channel = channel;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create stream.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_create(\n\t\t\t\t\tpjmedia_endpt *endpt,\n\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\tpjmedia_vid_stream_info *info,\n\t\t\t\t\tpjmedia_transport *tp,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tpjmedia_vid_stream **p_stream)\n{\n    enum { M = 32 };\n    pj_pool_t *own_pool = NULL;\n    pjmedia_vid_stream *stream;\n    unsigned jb_init, jb_max, jb_min_pre, jb_max_pre;\n    int frm_ptime, chunks_per_frm;\n    pjmedia_video_format_detail *vfd_enc, *vfd_dec;\n    char *p;\n    pj_status_t status;\n\n    if (!pool) {\n\town_pool = pjmedia_endpt_create_pool( endpt, \"vstrm%p\",\n\t                                      PJMEDIA_VSTREAM_SIZE,\n\t                                      PJMEDIA_VSTREAM_INC);\n\tPJ_ASSERT_RETURN(own_pool != NULL, PJ_ENOMEM);\n\tpool = own_pool;\n    }\n\n    /* Allocate stream */\n    stream = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_stream);\n    PJ_ASSERT_RETURN(stream != NULL, PJ_ENOMEM);\n    stream->own_pool = own_pool;\n\n    /* Get codec manager */\n    stream->codec_mgr = pjmedia_vid_codec_mgr_instance();\n    PJ_ASSERT_RETURN(stream->codec_mgr, PJMEDIA_CODEC_EFAILED);\n\n    /* Init stream/port name */\n    stream->name.ptr = (char*) pj_pool_alloc(pool, M);\n    stream->name.slen = pj_ansi_snprintf(stream->name.ptr, M, \n\t\t\t\t\t \"vstrm%p\", stream);\n\n    /* Create and initialize codec: */\n    status = pjmedia_vid_codec_mgr_alloc_codec(stream->codec_mgr, \n\t\t\t\t\t       &info->codec_info,\n\t\t\t\t\t       &stream->codec);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Get codec param: */\n    if (!info->codec_param) {\n\tpjmedia_vid_codec_param def_param;\n\n\tstatus = pjmedia_vid_codec_mgr_get_default_param(stream->codec_mgr, \n\t\t\t\t\t\t         &info->codec_info,\n\t\t\t\t\t\t         &def_param);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tinfo->codec_param = pjmedia_vid_codec_param_clone(pool, &def_param);\n\tpj_assert(info->codec_param);\n    }\n\n    /* Init codec param and adjust MTU */\n    info->codec_param->dir = info->dir;\n    info->codec_param->enc_mtu -= (sizeof(pjmedia_rtp_hdr) +\n\t\t\t\t   PJMEDIA_STREAM_RESV_PAYLOAD_LEN);\n    if (info->codec_param->enc_mtu > PJMEDIA_MAX_MTU)\n\tinfo->codec_param->enc_mtu = PJMEDIA_MAX_MTU;\n\n    /* Packet size estimation for decoding direction */\n    vfd_enc = pjmedia_format_get_video_format_detail(\n\t\t\t\t\t&info->codec_param->enc_fmt, PJ_TRUE);\n    vfd_dec = pjmedia_format_get_video_format_detail(\n\t\t\t\t\t&info->codec_param->dec_fmt, PJ_TRUE);\n\n    /* Init stream: */\n    stream->endpt = endpt;\n    stream->dir = info->dir;\n    stream->user_data = user_data;\n    stream->rtcp_interval = (PJMEDIA_RTCP_INTERVAL-500 + (pj_rand()%1000)) *\n\t\t\t    info->codec_info.clock_rate / 1000;\n    stream->rtcp_sdes_bye_disabled = info->rtcp_sdes_bye_disabled;\n\n    stream->jb_last_frm = PJMEDIA_JB_NORMAL_FRAME;\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0\n    stream->use_ka = info->use_ka;\n#endif\n\n    /* Build random RTCP CNAME. CNAME has user@host format */\n    stream->cname.ptr = p = (char*) pj_pool_alloc(pool, 20);\n    pj_create_random_string(p, 5);\n    p += 5;\n    *p++ = '@'; *p++ = 'p'; *p++ = 'j';\n    pj_create_random_string(p, 6);\n    p += 6;\n    *p++ = '.'; *p++ = 'o'; *p++ = 'r'; *p++ = 'g';\n    stream->cname.slen = p - stream->cname.ptr;\n\n\n    /* Create mutex to protect jitter buffer: */\n\n    status = pj_mutex_create_simple(pool, NULL, &stream->jb_mutex);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Init and open the codec. */\n    status = pjmedia_vid_codec_init(stream->codec, pool);\n    if (status != PJ_SUCCESS)\n\treturn status;\n    status = pjmedia_vid_codec_open(stream->codec, info->codec_param);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Subscribe to codec events */\n    pjmedia_event_subscribe(NULL, &stream_event_cb, stream,\n                            stream->codec);\n\n    /* Estimate the maximum frame size */\n    stream->frame_size = vfd_enc->size.w * vfd_enc->size.h * 4;\n\n#if 0\n    stream->frame_size = vfd_enc->max_bps/8 * vfd_enc->fps.denum /\n\t\t\t vfd_enc->fps.num;\n    \n    /* As the maximum frame_size is not represented directly by maximum bps\n     * (which includes intra and predicted frames), let's increase the\n     * frame size value for safety.\n     */\n    stream->frame_size <<= 4;\n#endif\n\n    /* Validate the frame size */\n    if (stream->frame_size == 0 || \n\tstream->frame_size > PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE)\n    {\n\tstream->frame_size = PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE;\n    }\n\n    /* Get frame length in timestamp unit */\n    stream->frame_ts_len = info->codec_info.clock_rate *\n                           vfd_enc->fps.denum / vfd_enc->fps.num;\n\n    /* Initialize send rate states */\n    pj_get_timestamp_freq(&stream->ts_freq);\n    if (info->rc_cfg.bandwidth == 0)\n\tinfo->rc_cfg.bandwidth = vfd_enc->max_bps;\n\n    /* For simple blocking, need to have bandwidth large enough, otherwise\n     * we can slow down the transmission too much\n     */\n    if (info->rc_cfg.method==PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING &&\n\tinfo->rc_cfg.bandwidth < vfd_enc->avg_bps * 3)\n    {\n\tinfo->rc_cfg.bandwidth = vfd_enc->avg_bps * 3;\n    }\n\n    /* Override the initial framerate in the decoding direction. This initial\n     * value will be used by the renderer to configure its clock, and setting\n     * it to a bit higher value can avoid the possibility of high latency\n     * caused by clock drift (remote encoder clock runs slightly faster than\n     * local renderer clock) or video setup lag. Note that the actual framerate\n     * will be continuously calculated based on the incoming RTP timestamps.\n     */\n#if 0\n    vfd_dec->fps.num = vfd_dec->fps.num * 3 / 2;\n#endif\n    stream->dec_max_fps = vfd_dec->fps;\n\n    /* Create decoder channel */\n    status = create_channel( pool, stream, PJMEDIA_DIR_DECODING, \n\t\t\t     info->rx_pt, info, &stream->dec);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Create encoder channel */\n    status = create_channel( pool, stream, PJMEDIA_DIR_ENCODING, \n\t\t\t     info->tx_pt, info, &stream->enc);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Create temporary buffer for immediate decoding */\n    stream->dec_max_size = vfd_dec->size.w * vfd_dec->size.h * 4;\n    stream->dec_frame.buf = pj_pool_alloc(pool, stream->dec_max_size);\n\n    /* Init jitter buffer parameters: */\n    frm_ptime\t    = 1000 * vfd_enc->fps.denum / vfd_enc->fps.num;\n    chunks_per_frm  = stream->frame_size / PJMEDIA_MAX_MRU;\n    if (chunks_per_frm < MIN_CHUNKS_PER_FRM)\n\tchunks_per_frm = MIN_CHUNKS_PER_FRM;\n\n    /* JB max count, default 500ms */\n    if (info->jb_max >= frm_ptime)\n\tjb_max\t    = info->jb_max * chunks_per_frm / frm_ptime;\n    else\n\tjb_max\t    = 500 * chunks_per_frm / frm_ptime;\n\n    /* JB min prefetch, default 1 frame */\n    if (info->jb_min_pre >= frm_ptime)\n\tjb_min_pre  = info->jb_min_pre * chunks_per_frm / frm_ptime;\n    else\n\tjb_min_pre  = 1;\n\n    /* JB max prefetch, default 4/5 JB max count */\n    if (info->jb_max_pre >= frm_ptime)\n\tjb_max_pre  = info->jb_max_pre * chunks_per_frm / frm_ptime;\n    else\n\tjb_max_pre  = jb_max * 4 / 5;\n\n    /* JB init prefetch, default 0 */\n    if (info->jb_init >= frm_ptime)\n\tjb_init  = info->jb_init * chunks_per_frm / frm_ptime;\n    else\n\tjb_init  = 0;\n\n    /* Allocate array for temporary storage for assembly of incoming\n     * frames. Add more just in case.\n     */\n    stream->rx_frame_cnt = chunks_per_frm * 2;\n    stream->rx_frames = pj_pool_calloc(pool, stream->rx_frame_cnt,\n                                       sizeof(stream->rx_frames[0]));\n\n    /* Create jitter buffer */\n    status = pjmedia_jbuf_create(pool, &stream->dec->port.info.name,\n                                 PJMEDIA_MAX_MRU,\n\t\t\t\t 1000 * vfd_enc->fps.denum / vfd_enc->fps.num,\n\t\t\t\t jb_max, &stream->jb);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n\n    /* Set up jitter buffer */\n    pjmedia_jbuf_set_adaptive(stream->jb, jb_init, jb_min_pre, jb_max_pre);\n    pjmedia_jbuf_set_discard(stream->jb, PJMEDIA_JB_DISCARD_NONE);\n\n    /* Init RTCP session: */\n    {\n\tpjmedia_rtcp_session_setting rtcp_setting;\n\n\tpjmedia_rtcp_session_setting_default(&rtcp_setting);\n\trtcp_setting.name = stream->name.ptr;\n\trtcp_setting.ssrc = info->ssrc;\n\trtcp_setting.rtp_ts_base = pj_ntohl(stream->enc->rtp.out_hdr.ts);\n\trtcp_setting.clock_rate = info->codec_info.clock_rate;\n\trtcp_setting.samples_per_frame = 1;\n\n\tpjmedia_rtcp_init2(&stream->rtcp, &rtcp_setting);\n    }\n\n    /* Allocate outgoing RTCP buffer, should be enough to hold SR/RR, SDES,\n     * BYE, and XR.\n     */\n    stream->out_rtcp_pkt_size =  sizeof(pjmedia_rtcp_sr_pkt) +\n\t\t\t\t sizeof(pjmedia_rtcp_common) +\n\t\t\t\t (4 + (unsigned)stream->cname.slen) +\n\t\t\t\t 32;\n    if (stream->out_rtcp_pkt_size > PJMEDIA_MAX_MTU)\n\tstream->out_rtcp_pkt_size = PJMEDIA_MAX_MTU;\n\n    stream->out_rtcp_pkt = pj_pool_alloc(pool, stream->out_rtcp_pkt_size);\n\n    /* Only attach transport when stream is ready. */\n    status = pjmedia_transport_attach(tp, stream, &info->rem_addr, \n\t\t\t\t      &info->rem_rtcp, \n\t\t\t\t      pj_sockaddr_get_len(&info->rem_addr), \n                                      &on_rx_rtp, &on_rx_rtcp);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    stream->transport = tp;\n\n    /* Send RTCP SDES */\n    if (!stream->rtcp_sdes_bye_disabled) {\n        pjmedia_vid_stream_send_rtcp_sdes(stream);\n    }\n\n#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0\n    /* NAT hole punching by sending KA packet via RTP transport. */\n    if (stream->use_ka)\n\tsend_keep_alive_packet(stream);\n#endif\n\n#if TRACE_JB\n    {\n\tchar trace_name[PJ_MAXPATH];\n\tpj_ssize_t len;\n\n\tpj_ansi_snprintf(trace_name, sizeof(trace_name), \n\t\t\t TRACE_JB_PATH_PREFIX \"%s.csv\",\n\t\t\t channel->port.info.name.ptr);\n\tstatus = pj_file_open(pool, trace_name, PJ_O_RDWR,\n\t\t\t      &stream->trace_jb_fd);\n\tif (status != PJ_SUCCESS) {\n\t    stream->trace_jb_fd = TRACE_JB_INVALID_FD;\n\t    PJ_LOG(3,(THIS_FILE, \"Failed creating RTP trace file '%s'\", \n\t\t      trace_name));\n\t} else {\n\t    stream->trace_jb_buf = (char*)pj_pool_alloc(pool, PJ_LOG_MAX_SIZE);\n\n\t    /* Print column header */\n\t    len = pj_ansi_snprintf(stream->trace_jb_buf, PJ_LOG_MAX_SIZE,\n\t\t\t\t   \"Time, Operation, Size, Frame Count, \"\n\t\t\t\t   \"Frame type, RTP Seq, RTP TS, RTP M, \"\n\t\t\t\t   \"JB size, JB burst level, JB prefetch\\n\");\n\t    if (len < 1 || len >= PJ_LOG_MAX_SIZE)\n\t\tlen = PJ_LOG_MAX_SIZE - 1;\n\t    pj_file_write(stream->trace_jb_fd, stream->trace_jb_buf, &len);\n\t    pj_file_flush(stream->trace_jb_fd);\n\t}\n    }\n#endif\n\n    /* Save the stream info */\n    pj_memcpy(&stream->info, info, sizeof(*info));\n    stream->info.codec_param = pjmedia_vid_codec_param_clone(\n\t\t\t\t\t\tpool, info->codec_param);\n\n    /* Success! */\n    *p_stream = stream;\n\n    PJ_LOG(5,(THIS_FILE, \"Video stream %s created\", stream->name.ptr));\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy stream.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_destroy( pjmedia_vid_stream *stream )\n{\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n\n#if TRACE_RC\n    {\n\tunsigned total_time;\n\n\ttotal_time = pj_elapsed_msec(&stream->tx_start, &stream->tx_end);\n\tPJ_LOG(5, (stream->name.ptr, \n\t\t   \"RC stat: pkt_cnt=%.2f/image, sleep=%.2fms/s, fps=%.2f\",\n\t\t   stream->rc_total_pkt*1.0/stream->rc_total_img,\n\t\t   stream->rc_total_sleep*1000.0/total_time,\n\t\t   stream->rc_total_img*1000.0/total_time));\n    }\n#endif\n\n    /* Send RTCP BYE (also SDES) */\n    if (!stream->rtcp_sdes_bye_disabled) {\n\tsend_rtcp(stream, PJ_TRUE, PJ_TRUE);\n    }\n\n    /* Detach from transport \n     * MUST NOT hold stream mutex while detaching from transport, as\n     * it may cause deadlock. See ticket #460 for the details.\n     */\n    if (stream->transport) {\n\tpjmedia_transport_detach(stream->transport, stream);\n\tstream->transport = NULL;\n    }\n\n    /* This function may be called when stream is partly initialized. */\n    if (stream->jb_mutex)\n\tpj_mutex_lock(stream->jb_mutex);\n\n\n    /* Free codec. */\n    if (stream->codec) {\n        pjmedia_event_unsubscribe(NULL, &stream_event_cb, stream,\n                                  stream->codec);\n\tpjmedia_vid_codec_close(stream->codec);\n\tpjmedia_vid_codec_mgr_dealloc_codec(stream->codec_mgr, stream->codec);\n\tstream->codec = NULL;\n    }\n\n    /* Free mutex */\n    \n    if (stream->jb_mutex) {\n\tpj_mutex_destroy(stream->jb_mutex);\n\tstream->jb_mutex = NULL;\n    }\n\n    /* Destroy jitter buffer */\n    if (stream->jb) {\n\tpjmedia_jbuf_destroy(stream->jb);\n\tstream->jb = NULL;\n    }\n\n#if TRACE_JB\n    if (TRACE_JB_OPENED(stream)) {\n\tpj_file_close(stream->trace_jb_fd);\n\tstream->trace_jb_fd = TRACE_JB_INVALID_FD;\n    }\n#endif\n\n    if (stream->own_pool) {\n\tpj_pool_t *pool = stream->own_pool;\n\tstream->own_pool = NULL;\n\tpj_pool_release(pool);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the port interface.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_get_port(pjmedia_vid_stream *stream,\n\t\t\t\t\t\tpjmedia_dir dir,\n\t\t\t\t\t\tpjmedia_port **p_port )\n{\n    PJ_ASSERT_RETURN(dir==PJMEDIA_DIR_ENCODING || dir==PJMEDIA_DIR_DECODING,\n\t\t     PJ_EINVAL);\n\n    if (dir == PJMEDIA_DIR_ENCODING)\n\t*p_port = &stream->enc->port;\n    else\n\t*p_port = &stream->dec->port;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the transport object\n */\nPJ_DEF(pjmedia_transport*) pjmedia_vid_stream_get_transport(\n\t\t\t\t\t\t    pjmedia_vid_stream *st)\n{\n    return st->transport;\n}\n\n\n/*\n * Get stream statistics.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_get_stat(\n\t\t\t\t\t    const pjmedia_vid_stream *stream,\n\t\t\t\t\t    pjmedia_rtcp_stat *stat)\n{\n    PJ_ASSERT_RETURN(stream && stat, PJ_EINVAL);\n\n    pj_memcpy(stat, &stream->rtcp.stat, sizeof(pjmedia_rtcp_stat));\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Reset the stream statistics in the middle of a stream session.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_reset_stat(pjmedia_vid_stream *stream)\n{\n    PJ_ASSERT_RETURN(stream, PJ_EINVAL);\n\n    pjmedia_rtcp_init_stat(&stream->rtcp.stat);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get jitter buffer state.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_get_stat_jbuf(\n\t\t\t\t\t    const pjmedia_vid_stream *stream,\n\t\t\t\t\t    pjmedia_jb_state *state)\n{\n    PJ_ASSERT_RETURN(stream && state, PJ_EINVAL);\n    return pjmedia_jbuf_get_state(stream->jb, state);\n}\n\n\n/*\n * Get the stream info.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_get_info(\n\t\t\t\t\t    const pjmedia_vid_stream *stream,\n\t\t\t\t\t    pjmedia_vid_stream_info *info)\n{\n    PJ_ASSERT_RETURN(stream && info, PJ_EINVAL);\n    pj_memcpy(info, &stream->info, sizeof(*info));\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Start stream.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_start(pjmedia_vid_stream *stream)\n{\n\n    PJ_ASSERT_RETURN(stream && stream->enc && stream->dec, PJ_EINVALIDOP);\n\n    if (stream->enc && (stream->dir & PJMEDIA_DIR_ENCODING)) {\n\tstream->enc->paused = 0;\n\t//pjmedia_snd_stream_start(stream->enc->snd_stream);\n\tPJ_LOG(4,(stream->enc->port.info.name.ptr, \"Encoder stream started\"));\n    } else {\n\tPJ_LOG(4,(stream->enc->port.info.name.ptr, \"Encoder stream paused\"));\n    }\n\n    if (stream->dec && (stream->dir & PJMEDIA_DIR_DECODING)) {\n\tstream->dec->paused = 0;\n\t//pjmedia_snd_stream_start(stream->dec->snd_stream);\n\tPJ_LOG(4,(stream->dec->port.info.name.ptr, \"Decoder stream started\"));\n    } else {\n\tPJ_LOG(4,(stream->dec->port.info.name.ptr, \"Decoder stream paused\"));\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Check status.\n */\nPJ_DEF(pj_bool_t) pjmedia_vid_stream_is_running(pjmedia_vid_stream *stream,\n                                                pjmedia_dir dir)\n{\n    pj_bool_t is_running = PJ_TRUE;\n\n    PJ_ASSERT_RETURN(stream, PJ_FALSE);\n\n    if (dir & PJMEDIA_DIR_ENCODING) {\n\tis_running &= (stream->enc && !stream->enc->paused);\n    }\n\n    if (dir & PJMEDIA_DIR_DECODING) {\n\tis_running &= (stream->dec && !stream->dec->paused);\n    }\n\n    return is_running;\n}\n\n/*\n * Pause stream.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_pause(pjmedia_vid_stream *stream,\n\t\t\t\t\t     pjmedia_dir dir)\n{\n    PJ_ASSERT_RETURN(stream, PJ_EINVAL);\n\n    if ((dir & PJMEDIA_DIR_ENCODING) && stream->enc) {\n\tstream->enc->paused = 1;\n\tPJ_LOG(4,(stream->enc->port.info.name.ptr, \"Encoder stream paused\"));\n    }\n\n    if ((dir & PJMEDIA_DIR_DECODING) && stream->dec) {\n\tstream->dec->paused = 1;\n\n\t/* Also reset jitter buffer */\n\tpj_mutex_lock( stream->jb_mutex );\n\tpjmedia_jbuf_reset(stream->jb);\n\tpj_mutex_unlock( stream->jb_mutex );\n\n\tPJ_LOG(4,(stream->dec->port.info.name.ptr, \"Decoder stream paused\"));\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Resume stream\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_resume(pjmedia_vid_stream *stream,\n\t\t\t\t\t      pjmedia_dir dir)\n{\n    PJ_ASSERT_RETURN(stream, PJ_EINVAL);\n\n    if ((dir & PJMEDIA_DIR_ENCODING) && stream->enc) {\n\tstream->enc->paused = 0;\n\tPJ_LOG(4,(stream->enc->port.info.name.ptr, \"Encoder stream resumed\"));\n    }\n\n    if ((dir & PJMEDIA_DIR_DECODING) && stream->dec) {\n\tstream->dec->paused = 0;\n\tPJ_LOG(4,(stream->dec->port.info.name.ptr, \"Decoder stream resumed\"));\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Force stream to send video keyframe.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_send_keyframe(\n\t\t\t\t\t\tpjmedia_vid_stream *stream)\n{\n    PJ_ASSERT_RETURN(stream, PJ_EINVAL);\n\n    if (!pjmedia_vid_stream_is_running(stream, PJMEDIA_DIR_ENCODING))\n\treturn PJ_EINVALIDOP;\n\n    stream->force_keyframe = PJ_TRUE;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Send RTCP SDES.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_send_rtcp_sdes(\n\t\t\t\t\t\tpjmedia_vid_stream *stream)\n{\n    PJ_ASSERT_RETURN(stream, PJ_EINVAL);\n\n    return send_rtcp(stream, PJ_TRUE, PJ_FALSE);\n}\n\n\n/*\n * Send RTCP BYE.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_send_rtcp_bye(\n\t\t\t\t\t\tpjmedia_vid_stream *stream)\n{\n    PJ_ASSERT_RETURN(stream, PJ_EINVAL);\n\n    if (stream->enc && stream->transport) {\n\treturn send_rtcp(stream, PJ_TRUE, PJ_TRUE);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Send RTCP PLI.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_send_rtcp_pli(\n\t\t\t\t\t\tpjmedia_vid_stream *stream)\n{\n    PJ_ASSERT_RETURN(stream, PJ_EINVAL);\n\n    if (stream->enc && stream->transport) {\n        void *sr_rr_pkt;\n        pj_uint8_t *pkt;\n        int len, max_len;\n        pj_status_t status;\n        pj_size_t pli_len;\n\n        /* Build RTCP RR/SR packet */\n        pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len);\n\n        pkt = (pj_uint8_t*) stream->out_rtcp_pkt;\n        pj_memcpy(pkt, sr_rr_pkt, len);\n        max_len = stream->out_rtcp_pkt_size;\n\n        /* Build RTCP PLI packet */\n        pli_len = max_len - len;\n        status = pjmedia_rtcp_build_rtcp_pli(&stream->rtcp, pkt+len, &pli_len);\n        if (status != PJ_SUCCESS) {\n            PJ_PERROR(4,(stream->name.ptr, status, \"Error generating RTCP PLI\"));\n        } else {\n            len += (int)pli_len;\n        }\n\n        /* Send! */\n        status = pjmedia_transport_send_rtcp(stream->transport, pkt, len);\n\n        return status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Initialize the video stream rate control with default settings.\n */\nPJ_DEF(void)\npjmedia_vid_stream_rc_config_default(pjmedia_vid_stream_rc_config *cfg)\n{\n    pj_bzero(cfg, sizeof(*cfg));\n    cfg->method = PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING;\n}\n\n\n#endif /* PJMEDIA_HAS_VIDEO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/vid_stream_info.c",
    "content": "/* $Id: vid_stream_info.c 4257 2012-09-17 03:11:44Z ming $ */\n/*\n * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia/vid_stream.h>\n#include <pjmedia/sdp_neg.h>\n#include <pjmedia/stream_common.h>\n#include <pj/ctype.h>\n#include <pj/rand.h>\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\nstatic const pj_str_t ID_VIDEO = { \"video\", 5};\nstatic const pj_str_t ID_IN = { \"IN\", 2 };\nstatic const pj_str_t ID_IP4 = { \"IP4\", 3};\nstatic const pj_str_t ID_IP6 = { \"IP6\", 3};\nstatic const pj_str_t ID_RTP_AVP = { \"RTP/AVP\", 7 };\nstatic const pj_str_t ID_RTP_SAVP = { \"RTP/SAVP\", 8 };\n//static const pj_str_t ID_SDP_NAME = { \"pjmedia\", 7 };\nstatic const pj_str_t ID_RTPMAP = { \"rtpmap\", 6 };\n\n/*\n * Internal function for collecting codec info and param from the SDP media.\n */\nstatic pj_status_t get_video_codec_info_param(pjmedia_vid_stream_info *si,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      pjmedia_vid_codec_mgr *mgr,\n\t\t\t\t\t      const pjmedia_sdp_media *local_m,\n\t\t\t\t\t      const pjmedia_sdp_media *rem_m)\n{\n    unsigned pt = 0;\n    const pjmedia_vid_codec_info *p_info;\n    pj_status_t status;\n\n    pt = pj_strtoul(&local_m->desc.fmt[0]);\n\n    /* Get payload type for receiving direction */\n    si->rx_pt = pt;\n\n    /* Get codec info and payload type for transmitting direction. */\n    if (pt < 96) {\n\t/* For static payload types, get the codec info from codec manager. */\n\tstatus = pjmedia_vid_codec_mgr_get_codec_info(mgr, pt, &p_info);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tsi->codec_info = *p_info;\n\n\t/* Get payload type for transmitting direction.\n\t * For static payload type, pt's are symetric.\n\t */\n\tsi->tx_pt = pt;\n    } else {\n\tconst pjmedia_sdp_attr *attr;\n\tpjmedia_sdp_rtpmap *rtpmap;\n\tpjmedia_codec_id codec_id;\n\tpj_str_t codec_id_st;\n\tunsigned i;\n\n\t/* Determine payload type for outgoing channel, by finding\n\t * dynamic payload type in remote SDP that matches the answer.\n\t */\n\tsi->tx_pt = 0xFFFF;\n\tfor (i=0; i<rem_m->desc.fmt_count; ++i) {\n\t    if (pjmedia_sdp_neg_fmt_match(NULL,\n\t\t\t\t\t  (pjmedia_sdp_media*)local_m, 0,\n\t\t\t\t\t  (pjmedia_sdp_media*)rem_m, i, 0) ==\n\t\tPJ_SUCCESS)\n\t    {\n\t\t/* Found matched codec. */\n\t\tsi->tx_pt = pj_strtoul(&rem_m->desc.fmt[i]);\n\t\tbreak;\n\t    }\n\t}\n\n\tif (si->tx_pt == 0xFFFF)\n\t    return PJMEDIA_EMISSINGRTPMAP;\n\n\t/* For dynamic payload types, get codec name from the rtpmap */\n\tattr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP,\n\t\t\t\t\t   &local_m->desc.fmt[0]);\n\tif (attr == NULL)\n\t    return PJMEDIA_EMISSINGRTPMAP;\n\n\tstatus = pjmedia_sdp_attr_to_rtpmap(pool, attr, &rtpmap);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Then get the codec info from the codec manager */\n\tpj_ansi_snprintf(codec_id, sizeof(codec_id), \"%.*s/\",\n\t\t\t (int)rtpmap->enc_name.slen, rtpmap->enc_name.ptr);\n\tcodec_id_st = pj_str(codec_id);\n\ti = 1;\n\tstatus = pjmedia_vid_codec_mgr_find_codecs_by_id(mgr, &codec_id_st,\n\t\t\t\t\t\t\t &i, &p_info, NULL);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tsi->codec_info = *p_info;\n    }\n\n\n    /* Request for codec with the correct packing for streaming */\n    si->codec_info.packings = PJMEDIA_VID_PACKING_PACKETS;\n\n    /* Now that we have codec info, get the codec param. */\n    si->codec_param = PJ_POOL_ALLOC_T(pool, pjmedia_vid_codec_param);\n    status = pjmedia_vid_codec_mgr_get_default_param(mgr,\n\t\t\t\t\t\t     &si->codec_info,\n\t\t\t\t\t\t     si->codec_param);\n\n    /* Adjust encoding bitrate, if higher than remote preference. The remote\n     * bitrate preference is read from SDP \"b=TIAS\" line in media level.\n     */\n    if ((si->dir & PJMEDIA_DIR_ENCODING) && rem_m->bandw_count) {\n\tunsigned i, bandw = 0;\n\n\tfor (i = 0; i < rem_m->bandw_count; ++i) {\n\t    const pj_str_t STR_BANDW_MODIFIER_TIAS = { \"TIAS\", 4 };\n\t    if (!pj_stricmp(&rem_m->bandw[i]->modifier,\n\t\t&STR_BANDW_MODIFIER_TIAS))\n\t    {\n\t\tbandw = rem_m->bandw[i]->value;\n\t\tbreak;\n\t    }\n\t}\n\n\tif (bandw) {\n\t    pjmedia_video_format_detail *enc_vfd;\n\t    enc_vfd = pjmedia_format_get_video_format_detail(\n\t\t\t\t\t&si->codec_param->enc_fmt, PJ_TRUE);\n\t    if (!enc_vfd->avg_bps || enc_vfd->avg_bps > bandw)\n\t\tenc_vfd->avg_bps = bandw * 3 / 4;\n\t    if (!enc_vfd->max_bps || enc_vfd->max_bps > bandw)\n\t\tenc_vfd->max_bps = bandw;\n\t}\n    }\n\n    /* Get remote fmtp for our encoder. */\n    pjmedia_stream_info_parse_fmtp(pool, rem_m, si->tx_pt,\n\t\t\t\t   &si->codec_param->enc_fmtp);\n\n    /* Get local fmtp for our decoder. */\n    pjmedia_stream_info_parse_fmtp(pool, local_m, si->rx_pt,\n\t\t\t\t   &si->codec_param->dec_fmtp);\n\n    /* When direction is NONE (it means SDP negotiation has failed) we don't\n     * need to return a failure here, as returning failure will cause\n     * the whole SDP to be rejected. See ticket #:\n     *\thttp://\n     *\n     * Thanks Alain Totouom\n     */\n    if (status != PJ_SUCCESS && si->dir != PJMEDIA_DIR_NONE)\n\treturn status;\n\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Create stream info from SDP media line.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_stream_info_from_sdp(\n\t\t\t\t\t   pjmedia_vid_stream_info *si,\n\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t   pjmedia_endpt *endpt,\n\t\t\t\t\t   const pjmedia_sdp_session *local,\n\t\t\t\t\t   const pjmedia_sdp_session *remote,\n\t\t\t\t\t   unsigned stream_idx)\n{\n    const pj_str_t STR_INACTIVE = { \"inactive\", 8 };\n    const pj_str_t STR_SENDONLY = { \"sendonly\", 8 };\n    const pj_str_t STR_RECVONLY = { \"recvonly\", 8 };\n\n    const pjmedia_sdp_attr *attr;\n    const pjmedia_sdp_media *local_m;\n    const pjmedia_sdp_media *rem_m;\n    const pjmedia_sdp_conn *local_conn;\n    const pjmedia_sdp_conn *rem_conn;\n    int rem_af, local_af;\n    pj_sockaddr local_addr;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(endpt);\n\n    /* Validate arguments: */\n    PJ_ASSERT_RETURN(pool && si && local && remote, PJ_EINVAL);\n    PJ_ASSERT_RETURN(stream_idx < local->media_count, PJ_EINVAL);\n    PJ_ASSERT_RETURN(stream_idx < remote->media_count, PJ_EINVAL);\n\n    /* Keep SDP shortcuts */\n    local_m = local->media[stream_idx];\n    rem_m = remote->media[stream_idx];\n\n    local_conn = local_m->conn ? local_m->conn : local->conn;\n    if (local_conn == NULL)\n\treturn PJMEDIA_SDP_EMISSINGCONN;\n\n    rem_conn = rem_m->conn ? rem_m->conn : remote->conn;\n    if (rem_conn == NULL)\n\treturn PJMEDIA_SDP_EMISSINGCONN;\n\n    /* Media type must be video */\n    if (pj_stricmp(&local_m->desc.media, &ID_VIDEO) != 0)\n\treturn PJMEDIA_EINVALIMEDIATYPE;\n\n\n    /* Reset: */\n\n    pj_bzero(si, sizeof(*si));\n\n    /* Media type: */\n    si->type = PJMEDIA_TYPE_VIDEO;\n\n    /* Transport protocol */\n\n    /* At this point, transport type must be compatible,\n     * the transport instance will do more validation later.\n     */\n    status = pjmedia_sdp_transport_cmp(&rem_m->desc.transport,\n\t\t\t\t       &local_m->desc.transport);\n    if (status != PJ_SUCCESS)\n\treturn PJMEDIA_SDPNEG_EINVANSTP;\n\n    if (pj_stricmp(&local_m->desc.transport, &ID_RTP_AVP) == 0) {\n\n\tsi->proto = PJMEDIA_TP_PROTO_RTP_AVP;\n\n    } else if (pj_stricmp(&local_m->desc.transport, &ID_RTP_SAVP) == 0) {\n\n\tsi->proto = PJMEDIA_TP_PROTO_RTP_SAVP;\n\n    } else {\n\n\tsi->proto = PJMEDIA_TP_PROTO_UNKNOWN;\n\treturn PJ_SUCCESS;\n    }\n\n\n    /* Check address family in remote SDP */\n    rem_af = pj_AF_UNSPEC();\n    if (pj_stricmp(&rem_conn->net_type, &ID_IN)==0) {\n\tif (pj_stricmp(&rem_conn->addr_type, &ID_IP4)==0) {\n\t    rem_af = pj_AF_INET();\n\t} else if (pj_stricmp(&rem_conn->addr_type, &ID_IP6)==0) {\n\t    rem_af = pj_AF_INET6();\n\t}\n    }\n\n    if (rem_af==pj_AF_UNSPEC()) {\n\t/* Unsupported address family */\n\treturn PJ_EAFNOTSUP;\n    }\n\n    /* Set remote address: */\n    status = pj_sockaddr_init(rem_af, &si->rem_addr, &rem_conn->addr,\n\t\t\t      rem_m->desc.port);\n    if (status != PJ_SUCCESS) {\n\t/* Invalid IP address. */\n\treturn PJMEDIA_EINVALIDIP;\n    }\n\n    /* Check address family of local info */\n    local_af = pj_AF_UNSPEC();\n    if (pj_stricmp(&local_conn->net_type, &ID_IN)==0) {\n\tif (pj_stricmp(&local_conn->addr_type, &ID_IP4)==0) {\n\t    local_af = pj_AF_INET();\n\t} else if (pj_stricmp(&local_conn->addr_type, &ID_IP6)==0) {\n\t    local_af = pj_AF_INET6();\n\t}\n    }\n\n    if (local_af==pj_AF_UNSPEC()) {\n\t/* Unsupported address family */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Set remote address: */\n    status = pj_sockaddr_init(local_af, &local_addr, &local_conn->addr,\n\t\t\t      local_m->desc.port);\n    if (status != PJ_SUCCESS) {\n\t/* Invalid IP address. */\n\treturn PJMEDIA_EINVALIDIP;\n    }\n\n    /* Local and remote address family must match */\n    if (local_af != rem_af)\n\treturn PJ_EAFNOTSUP;\n\n    /* Media direction: */\n\n    if (local_m->desc.port == 0 ||\n\tpj_sockaddr_has_addr(&local_addr)==PJ_FALSE ||\n\tpj_sockaddr_has_addr(&si->rem_addr)==PJ_FALSE ||\n\tpjmedia_sdp_media_find_attr(local_m, &STR_INACTIVE, NULL)!=NULL)\n    {\n\t/* Inactive stream. */\n\n\tsi->dir = PJMEDIA_DIR_NONE;\n\n    } else if (pjmedia_sdp_media_find_attr(local_m, &STR_SENDONLY, NULL)!=NULL) {\n\n\t/* Send only stream. */\n\n\tsi->dir = PJMEDIA_DIR_ENCODING;\n\n    } else if (pjmedia_sdp_media_find_attr(local_m, &STR_RECVONLY, NULL)!=NULL) {\n\n\t/* Recv only stream. */\n\n\tsi->dir = PJMEDIA_DIR_DECODING;\n\n    } else {\n\n\t/* Send and receive stream. */\n\n\tsi->dir = PJMEDIA_DIR_ENCODING_DECODING;\n\n    }\n\n    /* No need to do anything else if stream is rejected */\n    if (local_m->desc.port == 0) {\n\treturn PJ_SUCCESS;\n    }\n\n    /* If \"rtcp\" attribute is present in the SDP, set the RTCP address\n     * from that attribute. Otherwise, calculate from RTP address.\n     */\n    attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr,\n\t\t\t\t  \"rtcp\", NULL);\n    if (attr) {\n\tpjmedia_sdp_rtcp_attr rtcp;\n\tstatus = pjmedia_sdp_attr_get_rtcp(attr, &rtcp);\n\tif (status == PJ_SUCCESS) {\n\t    if (rtcp.addr.slen) {\n\t\tstatus = pj_sockaddr_init(rem_af, &si->rem_rtcp, &rtcp.addr,\n\t\t\t\t\t  (pj_uint16_t)rtcp.port);\n\t    } else {\n\t\tpj_sockaddr_init(rem_af, &si->rem_rtcp, NULL,\n\t\t\t\t (pj_uint16_t)rtcp.port);\n\t\tpj_memcpy(pj_sockaddr_get_addr(&si->rem_rtcp),\n\t\t          pj_sockaddr_get_addr(&si->rem_addr),\n\t\t\t  pj_sockaddr_get_addr_len(&si->rem_addr));\n\t    }\n\t}\n    }\n\n    if (!pj_sockaddr_has_addr(&si->rem_rtcp)) {\n\tint rtcp_port;\n\n\tpj_memcpy(&si->rem_rtcp, &si->rem_addr, sizeof(pj_sockaddr));\n\trtcp_port = pj_sockaddr_get_port(&si->rem_addr) + 1;\n\tpj_sockaddr_set_port(&si->rem_rtcp, (pj_uint16_t)rtcp_port);\n    }\n\n    /* Get codec info and param */\n    status = get_video_codec_info_param(si, pool, NULL, local_m, rem_m);\n\n    /* Leave SSRC to random. */\n    si->ssrc = pj_rand();\n\n    /* Set default jitter buffer parameter. */\n    si->jb_init = si->jb_max = si->jb_min_pre = si->jb_max_pre = -1;\n\n    return status;\n}\n\n#endif /* PJMEDIA_HAS_VIDEO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/vid_tee.c",
    "content": "/* $Id: vid_tee.c 3773 2011-09-23 04:06:01Z nanang $ */\n/* \n * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/vid_tee.h>\n#include <pjmedia/converter.h>\n#include <pjmedia/errno.h>\n#include <pj/array.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n\n#define TEE_PORT_NAME\t\"vid_tee\"\n#define TEE_PORT_SIGN\tPJMEDIA_SIG_PORT_VID_TEE\n\n#define THIS_FILE\t\"vid_tee.c\"\n\ntypedef struct vid_tee_dst_port\n{\n    pjmedia_port\t*dst;\n    unsigned\t\t option;\n} vid_tee_dst_port;\n\n\ntypedef struct vid_tee_port\n{\n    pjmedia_port\t base;\n    pj_pool_t           *pool;\n    pj_pool_factory     *pf;\n    pj_pool_t           *buf_pool;\n    void\t\t*buf[2];\n    unsigned             buf_cnt;\n    pj_size_t\t\t buf_size;\n    unsigned\t\t dst_port_maxcnt;\n    unsigned\t\t dst_port_cnt;\n    vid_tee_dst_port\t*dst_ports;\n    pj_uint8_t\t\t*put_frm_flag;\n    pj_mutex_t          *lock;\n    \n    struct vid_tee_conv_t {\n        pjmedia_converter   *conv;\n        pj_size_t            conv_buf_size;        \n    } *tee_conv;\n} vid_tee_port;\n\n\nstatic pj_status_t tee_put_frame(pjmedia_port *port, pjmedia_frame *frame);\nstatic pj_status_t tee_get_frame(pjmedia_port *port, pjmedia_frame *frame);\nstatic pj_status_t tee_destroy(pjmedia_port *port);\n\n/*\n * Create a video tee port with the specified source media port.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_tee_create( pj_pool_t *pool,\n\t\t\t\t\t    const pjmedia_format *fmt,\n\t\t\t\t\t    unsigned max_dst_cnt,\n\t\t\t\t\t    pjmedia_port **p_vid_tee)\n{\n    vid_tee_port *tee;\n    pj_str_t name_st;\n    const pjmedia_video_format_info *vfi;\n    pjmedia_video_apply_fmt_param vafp;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && fmt && p_vid_tee, PJ_EINVAL);\n    PJ_ASSERT_RETURN(fmt->type == PJMEDIA_TYPE_VIDEO, PJ_EINVAL);\n\n    /* Allocate video tee structure */\n    tee = PJ_POOL_ZALLOC_T(pool, vid_tee_port);\n    tee->pf = pool->factory;\n    tee->pool = pj_pool_create(tee->pf, \"video tee\", 500, 500, NULL);\n\n    /* Create lock */\n    status = pj_mutex_create_simple(pool, \"vid-tee-mutex\", &tee->lock);\n    if (status != PJ_SUCCESS)\n        return status;\n\n    /* Initialize video tee structure */\n    tee->dst_port_maxcnt = max_dst_cnt;\n    tee->dst_ports = (vid_tee_dst_port*)\n                     pj_pool_calloc(pool, max_dst_cnt,\n                                    sizeof(vid_tee_dst_port));\n    tee->tee_conv = (struct vid_tee_conv_t *)\n                    pj_pool_calloc(pool, max_dst_cnt,\n                                   sizeof(struct vid_tee_conv_t));\n    tee->put_frm_flag = (pj_uint8_t*)\n\t\t\tpj_pool_calloc(pool, max_dst_cnt,\n\t\t\t\t       sizeof(tee->put_frm_flag[0]));\n\n    /* Initialize video tee buffer, its size is one frame */\n    vfi = pjmedia_get_video_format_info(NULL, fmt->id);\n    if (vfi == NULL) {\n\tstatus = PJMEDIA_EBADFMT;\n\tgoto on_error;\n    }\n\n    pj_bzero(&vafp, sizeof(vafp));\n    vafp.size = fmt->det.vid.size;\n    status = vfi->apply_fmt(vfi, &vafp);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    tee->buf_size = vafp.framebytes;\n\n    /* Initialize video tee port */\n    status = pjmedia_port_info_init2(&tee->base.info,\n\t\t\t\t     pj_strset2(&name_st, (char*)TEE_PORT_NAME),\n\t\t\t\t     TEE_PORT_SIGN,\n\t\t\t\t     PJMEDIA_DIR_ENCODING,\n\t\t\t\t     fmt);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    tee->base.get_frame = &tee_get_frame;\n    tee->base.put_frame = &tee_put_frame;\n    tee->base.on_destroy = &tee_destroy;\n\n    /* Done */\n    *p_vid_tee = &tee->base;\n\n    return PJ_SUCCESS;\n\non_error:\n    pj_mutex_destroy(tee->lock);\n    tee->lock = NULL;\n    return status;\n}\n\nstatic void realloc_buf(vid_tee_port *vid_tee,\n                        unsigned buf_cnt, pj_size_t buf_size)\n{\n    unsigned i;\n    \n    if (buf_cnt > vid_tee->buf_cnt)\n        vid_tee->buf_cnt = buf_cnt;\n    \n    if (buf_size > vid_tee->buf_size) {\n        /* We need a larger buffer here. */\n        vid_tee->buf_size = buf_size;\n        if (vid_tee->buf_pool) {\n            pj_pool_release(vid_tee->buf_pool);\n            vid_tee->buf_pool = NULL;\n        }\n        vid_tee->buf[0] = vid_tee->buf[1] = NULL;\n    }\n    \n    if (!vid_tee->buf_pool) {\n        vid_tee->buf_pool = pj_pool_create(vid_tee->pf, \"video tee buffer\",\n                                           1000, 1000, NULL);\n    }\n \n    for (i = 0; i < vid_tee->buf_cnt; i++) {\n        if (!vid_tee->buf[i])\n            vid_tee->buf[i] = pj_pool_alloc(vid_tee->buf_pool,\n                                            vid_tee->buf_size);\n    }\n}\n\n/*\n * Add a destination media port to the video tee.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_tee_add_dst_port(pjmedia_port *vid_tee,\n\t\t\t\t\t\t unsigned option,\n\t\t\t\t\t\t pjmedia_port *port)\n{\n    vid_tee_port *tee = (vid_tee_port*)vid_tee;\n    pjmedia_video_format_detail *vfd;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(vid_tee && vid_tee->info.signature==TEE_PORT_SIGN,\n\t\t     PJ_EINVAL);\n\n    pj_mutex_lock(tee->lock);\n\n    if (tee->dst_port_cnt >= tee->dst_port_maxcnt) {\n\tstatus = PJ_ETOOMANY;\n\tgoto end;\n    }\n\n    if (vid_tee->info.fmt.id != port->info.fmt.id) {\n\tstatus = PJMEDIA_EBADFMT;\n\tgoto end;\n    }\n\n    vfd = pjmedia_format_get_video_format_detail(&port->info.fmt, PJ_TRUE);\n    if (vfd->size.w != vid_tee->info.fmt.det.vid.size.w ||\n\tvfd->size.h != vid_tee->info.fmt.det.vid.size.h)\n    {\n        status = PJMEDIA_EBADFMT;\n        goto end;\n    }\n\n    realloc_buf(tee, (option & PJMEDIA_VID_TEE_DST_DO_IN_PLACE_PROC)?\n                1: 0, tee->buf_size);\n\n    pj_bzero(&tee->tee_conv[tee->dst_port_cnt], sizeof(tee->tee_conv[0]));\n    tee->dst_ports[tee->dst_port_cnt].dst = port;\n    tee->dst_ports[tee->dst_port_cnt].option = option;\n    ++tee->dst_port_cnt;\n\n    status = PJ_SUCCESS;\n\nend:\n    pj_mutex_unlock(tee->lock);\n    return status;\n}\n\n\n/*\n * Add a destination media port to the video tee. Create a converter if\n * necessary.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_tee_add_dst_port2(pjmedia_port *vid_tee,\n\t\t\t\t\t\t  unsigned option,\n\t\t\t\t\t\t  pjmedia_port *port)\n{\n    vid_tee_port *tee = (vid_tee_port*)vid_tee;\n    pjmedia_video_format_detail *vfd;\n    pj_status_t status;\n    \n    PJ_ASSERT_RETURN(vid_tee && vid_tee->info.signature==TEE_PORT_SIGN,\n\t\t     PJ_EINVAL);\n    \n    pj_mutex_lock(tee->lock);\n\n    if (tee->dst_port_cnt >= tee->dst_port_maxcnt) {\n\tstatus = PJ_ETOOMANY;\n\tgoto end;\n    }\n    \n    pj_bzero(&tee->tee_conv[tee->dst_port_cnt], sizeof(tee->tee_conv[0]));\n    \n    /* Check if we need to create a converter. */\n    vfd = pjmedia_format_get_video_format_detail(&port->info.fmt, PJ_TRUE);\n    if (vid_tee->info.fmt.id != port->info.fmt.id ||\n        vfd->size.w != vid_tee->info.fmt.det.vid.size.w ||\n\tvfd->size.h != vid_tee->info.fmt.det.vid.size.h)\n    {\n        const pjmedia_video_format_info *vfi;\n        pjmedia_video_apply_fmt_param vafp;\n        pjmedia_conversion_param conv_param;\n\n        vfi = pjmedia_get_video_format_info(NULL, port->info.fmt.id);\n        if (vfi == NULL) {\n            status = PJMEDIA_EBADFMT;\n            goto end;\n        }\n\n        pj_bzero(&vafp, sizeof(vafp));\n        vafp.size = port->info.fmt.det.vid.size;\n        status = vfi->apply_fmt(vfi, &vafp);\n        if (status != PJ_SUCCESS)\n            goto end;\n        \n        realloc_buf(tee, (option & PJMEDIA_VID_TEE_DST_DO_IN_PLACE_PROC)?\n                    2: 1, vafp.framebytes);\n        \n        pjmedia_format_copy(&conv_param.src, &vid_tee->info.fmt);\n\tpjmedia_format_copy(&conv_param.dst, &port->info.fmt);\n        \n        status = pjmedia_converter_create(\n                     NULL, tee->pool, &conv_param,\n                     &tee->tee_conv[tee->dst_port_cnt].conv);\n        if (status != PJ_SUCCESS)\n            goto end;\n        \n        tee->tee_conv[tee->dst_port_cnt].conv_buf_size = vafp.framebytes;\n    } else {\n        realloc_buf(tee, (option & PJMEDIA_VID_TEE_DST_DO_IN_PLACE_PROC)?\n                    1: 0, tee->buf_size);        \n    }\n    \n    tee->dst_ports[tee->dst_port_cnt].dst = port;\n    tee->dst_ports[tee->dst_port_cnt].option = option;\n    ++tee->dst_port_cnt;\n\n    status = PJ_SUCCESS;\n\nend:\n    pj_mutex_unlock(tee->lock);\n    return status;\n}\n\n\n/*\n * Remove a destination media port from the video tee.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_tee_remove_dst_port(pjmedia_port *vid_tee,\n\t\t\t\t\t\t    pjmedia_port *port)\n{\n    vid_tee_port *tee = (vid_tee_port*)vid_tee;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(vid_tee && vid_tee->info.signature==TEE_PORT_SIGN,\n\t\t     PJ_EINVAL);\n\n    pj_mutex_lock(tee->lock);\n\n    for (i = 0; i < tee->dst_port_cnt; ++i) {\n\tif (tee->dst_ports[i].dst == port) {\n            if (tee->tee_conv[i].conv)\n                pjmedia_converter_destroy(tee->tee_conv[i].conv);\n            \n\t    pj_array_erase(tee->dst_ports, sizeof(tee->dst_ports[0]),\n\t\t\t   tee->dst_port_cnt, i);\n            pj_array_erase(tee->tee_conv, sizeof(tee->tee_conv[0]),\n\t\t\t   tee->dst_port_cnt, i);\n\t    --tee->dst_port_cnt;\n\n\t    pj_mutex_unlock(tee->lock);\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    pj_mutex_unlock(tee->lock);\n    return PJ_ENOTFOUND;\n}\n\n\nstatic pj_status_t tee_put_frame(pjmedia_port *port, pjmedia_frame *frame)\n{\n    vid_tee_port *tee = (vid_tee_port*)port;\n    unsigned i, j;\n    const pj_uint8_t PUT_FRM_DONE = 1;\n\n    if (pj_mutex_trylock(tee->lock) != PJ_SUCCESS) {\n        /* we are busy adding / removing consumers */\n        return PJ_SUCCESS;\n    }\n\n    pj_bzero(tee->put_frm_flag, tee->dst_port_cnt *\n\t\t\t\tsizeof(tee->put_frm_flag[0]));\n\n    for (i = 0; i < tee->dst_port_cnt; ++i) {\n\tpjmedia_frame frame_ = *frame;\n\n        if (tee->put_frm_flag[i])\n            continue;\n        \n        if (tee->tee_conv[i].conv) {\n            pj_status_t status;\n            \n            frame_.buf  = tee->buf[0];\n            frame_.size = tee->tee_conv[i].conv_buf_size;\n            status = pjmedia_converter_convert(tee->tee_conv[i].conv,\n                                               frame, &frame_);\n            if (status != PJ_SUCCESS) {\n                PJ_LOG(3, (THIS_FILE,\n\t\t\t       \"Failed to convert frame for destination\"\n                               \" port %d (%.*s)\", i,\n                               tee->dst_ports[i].dst->info.name.slen,\n                               tee->dst_ports[i].dst->info.name.ptr));\n                continue;\n            }\n        }\n        \n        /* Find other destination ports which has the same format so\n         * we don't need to do the same conversion twice.\n         */\n        for (j = i; j < tee->dst_port_cnt; ++j) {\n            pjmedia_frame framep;\n            \n            if (tee->put_frm_flag[j] ||\n                (tee->dst_ports[j].dst->info.fmt.id != \n                 tee->dst_ports[i].dst->info.fmt.id) ||\n                (tee->dst_ports[j].dst->info.fmt.det.vid.size.w != \n                 tee->dst_ports[i].dst->info.fmt.det.vid.size.w) ||\n                (tee->dst_ports[j].dst->info.fmt.det.vid.size.h != \n                 tee->dst_ports[i].dst->info.fmt.det.vid.size.h))\n            {\n                continue;\n            }\n            \n            framep = frame_;\n            /* For dst_ports that do in-place processing, we need to duplicate\n             * the data source first.\n             */\n            if (tee->dst_ports[j].option & PJMEDIA_VID_TEE_DST_DO_IN_PLACE_PROC)\n            {\n                PJ_ASSERT_RETURN(tee->buf_size <= frame_.size, PJ_ETOOBIG);\n                framep.buf = tee->buf[tee->buf_cnt-1];\n                framep.size = frame_.size;\n                pj_memcpy(framep.buf, frame_.buf, frame_.size);\n            }\n\n            /* Deliver the data */\n            pjmedia_port_put_frame(tee->dst_ports[j].dst, &framep);\n            tee->put_frm_flag[j] = PUT_FRM_DONE;\n            \n            if (!tee->tee_conv[i].conv)\n                break;\n        }\n    }\n\n    pj_mutex_unlock(tee->lock);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t tee_get_frame(pjmedia_port *port, pjmedia_frame *frame)\n{\n    PJ_UNUSED_ARG(port);\n    PJ_UNUSED_ARG(frame);\n\n    pj_assert(!\"Bug! Tee port get_frame() shouldn't be called.\");\n\n    return PJ_EBUG;\n}\n\nstatic pj_status_t tee_destroy(pjmedia_port *port)\n{\n    vid_tee_port *tee = (vid_tee_port*)port;\n\n    PJ_ASSERT_RETURN(port && port->info.signature==TEE_PORT_SIGN, PJ_EINVAL);\n\n    if (tee->lock) {\n        pj_mutex_destroy(tee->lock);\n        tee->lock = NULL;\n    }\n\n    pj_pool_release(tee->pool);\n    if (tee->buf_pool)\n        pj_pool_release(tee->buf_pool);\n                    \n    pj_bzero(tee, sizeof(*tee));\n\n    return PJ_SUCCESS;\n}\n\n\n#endif /* PJMEDIA_HAS_VIDEO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/wav_player.c",
    "content": "/* $Id: wav_player.c 4122 2012-05-14 11:04:46Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/wav_port.h>\n#include <pjmedia/alaw_ulaw.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/wave.h>\n#include <pj/assert.h>\n#include <pj/file_access.h>\n#include <pj/file_io.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n#define THIS_FILE   \"wav_player.c\"\n\n\n#define SIGNATURE\t    PJMEDIA_SIG_PORT_WAV_PLAYER\n#define BITS_PER_SAMPLE\t    16\n\n#if 1\n#   define TRACE_(x)\tPJ_LOG(4,x)\n#else\n#   define TRACE_(x)\n#endif\n\n#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0\n    static void samples_to_host(pj_int16_t *samples, unsigned count)\n    {\n\tunsigned i;\n\tfor (i=0; i<count; ++i) {\n\t    samples[i] = pj_swap16(samples[i]);\n\t}\n    }\n#else\n#   define samples_to_host(samples,count)\n#endif\n\nstruct file_reader_port\n{\n    pjmedia_port     base;\n    unsigned\t     options;\n    pjmedia_wave_fmt_tag fmt_tag;\n    pj_uint16_t\t     bytes_per_sample;\n    pj_bool_t\t     eof;\n    pj_uint32_t\t     bufsize;\n    char\t    *buf;\n    char\t    *readpos;\n    char\t    *eofpos;\n\n    pj_off_t\t     fsize;\n    unsigned\t     start_data;\n    unsigned         data_len;\n    unsigned         data_left;\n    pj_off_t\t     fpos;\n    pj_oshandle_t    fd;\n\n    pj_status_t\t   (*cb)(pjmedia_port*, void*);\n};\n\n\nstatic pj_status_t file_get_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame);\nstatic pj_status_t file_on_destroy(pjmedia_port *this_port);\n\nstatic struct file_reader_port *create_file_port(pj_pool_t *pool)\n{\n    const pj_str_t name = pj_str(\"file\");\n    struct file_reader_port *port;\n\n    port = PJ_POOL_ZALLOC_T(pool, struct file_reader_port);\n    if (!port)\n\treturn NULL;\n\n    /* Put in default values.\n     * These will be overriden once the file is read.\n     */\n    pjmedia_port_info_init(&port->base.info, &name, SIGNATURE, \n\t\t\t   8000, 1, 16, 80);\n\n    port->base.get_frame = &file_get_frame;\n    port->base.on_destroy = &file_on_destroy;\n\n\n    return port;\n}\n\n/*\n * Fill buffer.\n */\nstatic pj_status_t fill_buffer(struct file_reader_port *fport)\n{\n    pj_uint32_t size_left = fport->bufsize;\n    unsigned size_to_read;\n    pj_ssize_t size;\n    pj_status_t status;\n\n    fport->eofpos = NULL;\n    \n    while (size_left > 0) {\n\n\t/* Calculate how many bytes to read in this run. */\n\tsize = size_to_read = size_left;\n\tstatus = pj_file_read(fport->fd, \n\t\t\t      &fport->buf[fport->bufsize-size_left], \n\t\t\t      &size);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\tif (size < 0) {\n\t    /* Should return more appropriate error code here.. */\n\t    return PJ_ECANCELLED;\n\t}\n\n        if (size > (pj_ssize_t)fport->data_left) {\n            /* We passed the end of the data chunk,\n             * only count the portion read from the data chunk.\n             */\n            size = (pj_ssize_t)fport->data_left;\n        }\n\n\tsize_left -= (pj_uint32_t)size;\n        fport->data_left -= (pj_uint32_t)size;\n\tfport->fpos += size;\n\n\t/* If size is less than size_to_read, it indicates that we've\n\t * encountered EOF. Rewind the file.\n\t */\n        if (size < (pj_ssize_t)size_to_read) {\n            fport->eof = PJ_TRUE;\n            fport->eofpos = fport->buf + fport->bufsize - size_left;\n\n            if (fport->options & PJMEDIA_FILE_NO_LOOP) {\n                /* Zero remaining buffer */\n                if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_PCM) {\n                    pj_bzero(fport->eofpos, size_left);\n                } else if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ULAW) {\n                    int val = pjmedia_linear2ulaw(0);\n                    pj_memset(fport->eofpos, val, size_left);\n                } else if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ALAW) {\n                    int val = pjmedia_linear2alaw(0);\n                    pj_memset(fport->eofpos, val, size_left);\n                }\n\t\tsize_left = 0;\n            }\n\n\t    /* Rewind file */\n\t    fport->fpos = fport->start_data;\n\t    pj_file_setpos( fport->fd, fport->fpos, PJ_SEEK_SET);\n            fport->data_left = fport->data_len;\n\t}\n    }\n\n    /* Convert samples to host rep */\n    samples_to_host((pj_int16_t*)fport->buf, \n\t\t    fport->bufsize/fport->bytes_per_sample);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create WAVE player port.\n */\nPJ_DEF(pj_status_t) pjmedia_wav_player_port_create( pj_pool_t *pool,\n\t\t\t\t\t\t     const char *filename,\n\t\t\t\t\t\t     unsigned ptime,\n\t\t\t\t\t\t     unsigned options,\n\t\t\t\t\t\t     pj_ssize_t buff_size,\n\t\t\t\t\t\t     pjmedia_port **p_port )\n{\n    pjmedia_wave_hdr wave_hdr;\n    pj_ssize_t size_to_read, size_read;\n    struct file_reader_port *fport;\n    pjmedia_audio_format_detail *ad;\n    pj_off_t pos;\n    pj_str_t name;\n    unsigned samples_per_frame;\n    pj_status_t status = PJ_SUCCESS;\n\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(pool && filename && p_port, PJ_EINVAL);\n\n    /* Check the file really exists. */\n    if (!pj_file_exists(filename)) {\n\treturn PJ_ENOTFOUND;\n    }\n\n    /* Normalize ptime */\n    if (ptime == 0)\n\tptime = 20;\n\n    /* Normalize buff_size */\n    if (buff_size < 1) buff_size = PJMEDIA_FILE_PORT_BUFSIZE;\n\n\n    /* Create fport instance. */\n    fport = create_file_port(pool);\n    if (!fport) {\n\treturn PJ_ENOMEM;\n    }\n\n\n    /* Get the file size. */\n    fport->fsize = pj_file_size(filename);\n\n    /* Size must be more than WAVE header size */\n    if (fport->fsize <= sizeof(pjmedia_wave_hdr)) {\n\treturn PJMEDIA_ENOTVALIDWAVE;\n    }\n\n    /* Open file. */\n    status = pj_file_open( pool, filename, PJ_O_RDONLY, &fport->fd);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Read the file header plus fmt header only. */\n    size_read = size_to_read = sizeof(wave_hdr) - 8;\n    status = pj_file_read( fport->fd, &wave_hdr, &size_read);\n    if (status != PJ_SUCCESS) {\n\tpj_file_close(fport->fd);\n\treturn status;\n    }\n    if (size_read != size_to_read) {\n\tpj_file_close(fport->fd);\n\treturn PJMEDIA_ENOTVALIDWAVE;\n    }\n\n    /* Normalize WAVE header fields values from little-endian to host\n     * byte order.\n     */\n    pjmedia_wave_hdr_file_to_host(&wave_hdr);\n    \n    /* Validate WAVE file. */\n    if (wave_hdr.riff_hdr.riff != PJMEDIA_RIFF_TAG ||\n\twave_hdr.riff_hdr.wave != PJMEDIA_WAVE_TAG ||\n\twave_hdr.fmt_hdr.fmt != PJMEDIA_FMT_TAG)\n    {\n\tpj_file_close(fport->fd);\n\tTRACE_((THIS_FILE, \n\t\t\"actual value|expected riff=%x|%x, wave=%x|%x fmt=%x|%x\",\n\t\twave_hdr.riff_hdr.riff, PJMEDIA_RIFF_TAG,\n\t\twave_hdr.riff_hdr.wave, PJMEDIA_WAVE_TAG,\n\t\twave_hdr.fmt_hdr.fmt, PJMEDIA_FMT_TAG));\n\treturn PJMEDIA_ENOTVALIDWAVE;\n    }\n\n    /* Validate format and its attributes (i.e: bits per sample, block align) */\n    switch (wave_hdr.fmt_hdr.fmt_tag) {\n    case PJMEDIA_WAVE_FMT_TAG_PCM:\n\tif (wave_hdr.fmt_hdr.bits_per_sample != 16 || \n\t    wave_hdr.fmt_hdr.block_align != 2 * wave_hdr.fmt_hdr.nchan)\n\t    status = PJMEDIA_EWAVEUNSUPP;\n\tbreak;\n\n    case PJMEDIA_WAVE_FMT_TAG_ALAW:\n    case PJMEDIA_WAVE_FMT_TAG_ULAW:\n\tif (wave_hdr.fmt_hdr.bits_per_sample != 8 ||\n\t    wave_hdr.fmt_hdr.block_align != wave_hdr.fmt_hdr.nchan)\n\t    status = PJMEDIA_ENOTVALIDWAVE;\n\tbreak;\n\n    default:\n\tstatus = PJMEDIA_EWAVEUNSUPP;\n\tbreak;\n    }\n\n    if (status != PJ_SUCCESS) {\n\tpj_file_close(fport->fd);\n\treturn status;\n    }\n\n    fport->fmt_tag = (pjmedia_wave_fmt_tag)wave_hdr.fmt_hdr.fmt_tag;\n    fport->bytes_per_sample = (pj_uint16_t) \n\t\t\t      (wave_hdr.fmt_hdr.bits_per_sample / 8);\n\n    /* If length of fmt_header is greater than 16, skip the remaining\n     * fmt header data.\n     */\n    if (wave_hdr.fmt_hdr.len > 16) {\n\tsize_to_read = wave_hdr.fmt_hdr.len - 16;\n\tstatus = pj_file_setpos(fport->fd, size_to_read, PJ_SEEK_CUR);\n\tif (status != PJ_SUCCESS) {\n\t    pj_file_close(fport->fd);\n\t    return status;\n\t}\n    }\n\n    /* Repeat reading the WAVE file until we have 'data' chunk */\n    for (;;) {\n\tpjmedia_wave_subchunk subchunk;\n\tsize_read = 8;\n\tstatus = pj_file_read(fport->fd, &subchunk, &size_read);\n\tif (status != PJ_SUCCESS || size_read != 8) {\n\t    pj_file_close(fport->fd);\n\t    return PJMEDIA_EWAVETOOSHORT;\n\t}\n\n\t/* Normalize endianness */\n\tPJMEDIA_WAVE_NORMALIZE_SUBCHUNK(&subchunk);\n\n\t/* Break if this is \"data\" chunk */\n\tif (subchunk.id == PJMEDIA_DATA_TAG) {\n\t    wave_hdr.data_hdr.data = PJMEDIA_DATA_TAG;\n\t    wave_hdr.data_hdr.len = subchunk.len;\n\t    break;\n\t}\n\n\t/* Otherwise skip the chunk contents */\n\tsize_to_read = subchunk.len;\n\tstatus = pj_file_setpos(fport->fd, size_to_read, PJ_SEEK_CUR);\n\tif (status != PJ_SUCCESS) {\n\t    pj_file_close(fport->fd);\n\t    return status;\n\t}\n    }\n\n    /* Current file position now points to start of data */\n    status = pj_file_getpos(fport->fd, &pos);\n    fport->start_data = (unsigned)pos;\n    fport->data_len = wave_hdr.data_hdr.len;\n    fport->data_left = wave_hdr.data_hdr.len;\n\n    /* Validate length. */\n    if (wave_hdr.data_hdr.len > fport->fsize - fport->start_data) {\n\tpj_file_close(fport->fd);\n\treturn PJMEDIA_EWAVEUNSUPP;\n    }\n    if (wave_hdr.data_hdr.len < ptime * wave_hdr.fmt_hdr.sample_rate *\n\t\t\t\twave_hdr.fmt_hdr.nchan / 1000)\n    {\n\tpj_file_close(fport->fd);\n\treturn PJMEDIA_EWAVETOOSHORT;\n    }\n\n    /* It seems like we have a valid WAVE file. */\n\n    /* Initialize */\n    fport->options = options;\n\n    /* Update port info. */\n    ad = pjmedia_format_get_audio_format_detail(&fport->base.info.fmt, 1);\n    pj_strdup2(pool, &name, filename);\n    samples_per_frame = ptime * wave_hdr.fmt_hdr.sample_rate *\n\t\t        wave_hdr.fmt_hdr.nchan / 1000;\n    pjmedia_port_info_init(&fport->base.info, &name, SIGNATURE,\n\t\t\t   wave_hdr.fmt_hdr.sample_rate,\n\t\t\t   wave_hdr.fmt_hdr.nchan,\n\t\t\t   BITS_PER_SAMPLE,\n\t\t\t   samples_per_frame);\n\n    /* If file is shorter than buffer size, adjust buffer size to file\n     * size. Otherwise EOF callback will be called multiple times when\n     * fill_buffer() is called.\n     */\n    if (wave_hdr.data_hdr.len < (unsigned)buff_size)\n\tbuff_size = wave_hdr.data_hdr.len;\n\n    /* Create file buffer.\n     */\n    fport->bufsize = (pj_uint32_t)buff_size;\n\n\n    /* samples_per_frame must be smaller than bufsize (because get_frame()\n     * doesn't handle this case).\n     */\n    if (samples_per_frame * fport->bytes_per_sample >= fport->bufsize) {\n\tpj_file_close(fport->fd);\n\treturn PJ_EINVAL;\n    }\n\n    /* Create buffer. */\n    fport->buf = (char*) pj_pool_alloc(pool, fport->bufsize);\n    if (!fport->buf) {\n\tpj_file_close(fport->fd);\n\treturn PJ_ENOMEM;\n    }\n \n    fport->readpos = fport->buf;\n\n    /* Set initial position of the file. */\n    fport->fpos = fport->start_data;\n\n    /* Fill up the buffer. */\n    status = fill_buffer(fport);\n    if (status != PJ_SUCCESS) {\n\tpj_file_close(fport->fd);\n\treturn status;\n    }\n\n    /* Done. */\n\n    *p_port = &fport->base;\n\n\n    PJ_LOG(4,(THIS_FILE, \n\t      \"File player '%.*s' created: samp.rate=%d, ch=%d, bufsize=%uKB, \"\n\t      \"filesize=%luKB\",\n\t      (int)fport->base.info.name.slen,\n\t      fport->base.info.name.ptr,\n\t      ad->clock_rate,\n\t      ad->channel_count,\n\t      fport->bufsize / 1000,\n\t      (unsigned long)(fport->fsize / 1000)));\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get additional info about the file player.\n */\nPJ_DEF(pj_status_t) pjmedia_wav_player_get_info(\n\t\t\t\t\tpjmedia_port *port,\n\t\t\t\t\tpjmedia_wav_player_info *info)\n{\n    struct file_reader_port *fport;\n    PJ_ASSERT_RETURN(port && info, PJ_EINVAL);\n\n    pj_bzero(info, sizeof(*info));\n\n    /* Check that this is really a player port */\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVALIDOP);\n\n    fport = (struct file_reader_port*) port;\n\n    if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_PCM) {\n\tinfo->fmt_id = PJMEDIA_FORMAT_PCM;\n\tinfo->payload_bits_per_sample = 16;\n    } else if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ULAW) {\n\tinfo->fmt_id = PJMEDIA_FORMAT_ULAW;\n\tinfo->payload_bits_per_sample = 8;\n    } else if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ALAW) {\n\tinfo->fmt_id = PJMEDIA_FORMAT_ALAW;\n\tinfo->payload_bits_per_sample = 8;\n    } else {\n\tpj_assert(!\"Unsupported format\");\n\treturn PJ_ENOTSUP;\n    }\n\n    info->size_bytes = pjmedia_wav_player_get_len(port);\n    info->size_samples = info->size_bytes /\n\t\t\t (info->payload_bits_per_sample / 8);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get the data length, in bytes.\n */\nPJ_DEF(pj_ssize_t) pjmedia_wav_player_get_len(pjmedia_port *port)\n{\n    struct file_reader_port *fport;\n    pj_ssize_t size;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(port, -PJ_EINVAL);\n\n    /* Check that this is really a player port */\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, -PJ_EINVALIDOP);\n\n    fport = (struct file_reader_port*) port;\n\n    size = (pj_ssize_t) fport->fsize;\n    return size - fport->start_data;\n}\n\n\n/*\n * Set position.\n */\nPJ_DEF(pj_status_t) pjmedia_wav_player_port_set_pos(pjmedia_port *port,\n\t\t\t\t\t\t    pj_uint32_t bytes )\n{\n    struct file_reader_port *fport;\n    pj_status_t status;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(port, PJ_EINVAL);\n\n    /* Check that this is really a player port */\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVALIDOP);\n\n\n    fport = (struct file_reader_port*) port;\n\n    /* Check that this offset does not pass the audio-data (in case of\n     * extra chunk after audio data chunk\n     */\n    PJ_ASSERT_RETURN(bytes < fport->data_len, PJ_EINVAL);\n\n    fport->fpos = fport->start_data + bytes;\n    fport->data_left = fport->data_len - bytes;\n    pj_file_setpos( fport->fd, fport->fpos, PJ_SEEK_SET);\n\n    fport->eof = PJ_FALSE;\n    status = fill_buffer(fport);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    fport->readpos = fport->buf;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the file play position of WAV player (in bytes).\n */\nPJ_DEF(pj_ssize_t) pjmedia_wav_player_port_get_pos( pjmedia_port *port )\n{\n    struct file_reader_port *fport;\n    pj_size_t payload_pos;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(port, -PJ_EINVAL);\n\n    /* Check that this is really a player port */\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, -PJ_EINVALIDOP);\n\n    fport = (struct file_reader_port*) port;\n\n    payload_pos = (pj_size_t)(fport->fpos - fport->start_data);\n    if (payload_pos >= fport->bufsize)\n\treturn payload_pos - fport->bufsize + (fport->readpos - fport->buf);\n    else\n\treturn (fport->readpos - fport->buf) % payload_pos;\n}\n\n\n\n/*\n * Register a callback to be called when the file reading has reached the\n * end of file.\n */\nPJ_DEF(pj_status_t) pjmedia_wav_player_set_eof_cb( pjmedia_port *port,\n\t\t\t       void *user_data,\n\t\t\t       pj_status_t (*cb)(pjmedia_port *port,\n\t\t\t\t\t\t void *usr_data))\n{\n    struct file_reader_port *fport;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(port, -PJ_EINVAL);\n\n    /* Check that this is really a player port */\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, -PJ_EINVALIDOP);\n\n    fport = (struct file_reader_port*) port;\n\n    fport->base.port_data.pdata = user_data;\n    fport->cb = cb;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get frame from file.\n */\nstatic pj_status_t file_get_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame)\n{\n    struct file_reader_port *fport = (struct file_reader_port*)this_port;\n    pj_size_t frame_size;\n    pj_status_t status = PJ_SUCCESS;\n\n    pj_assert(fport->base.info.signature == SIGNATURE);\n    pj_assert(frame->size <= fport->bufsize);\n\n    /* EOF is set and readpos already passed the eofpos */\n    if (fport->eof && fport->readpos >= fport->eofpos) {\n\tPJ_LOG(5,(THIS_FILE, \"File port %.*s EOF\",\n\t\t  (int)fport->base.info.name.slen,\n\t\t  fport->base.info.name.ptr));\n\n\t/* Call callback, if any */\n\tif (fport->cb)\n\t    status = (*fport->cb)(this_port, fport->base.port_data.pdata);\n\n\t/* If callback returns non PJ_SUCCESS or 'no loop' is specified,\n\t * return immediately (and don't try to access player port since\n\t * it might have been destroyed by the callback).\n\t */\n\tif ((status != PJ_SUCCESS) || (fport->options & PJMEDIA_FILE_NO_LOOP)) {\n\t    frame->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    frame->size = 0;\n\t    return PJ_EEOF;\n\t}\n    \t\n\tPJ_LOG(5,(THIS_FILE, \"File port %.*s rewinding..\",\n\t\t  (int)fport->base.info.name.slen,\n\t\t  fport->base.info.name.ptr));\n\t\n\tfport->eof = PJ_FALSE;\n    }\n\n    //pj_assert(frame->size == fport->base.info.bytes_per_frame);\n    if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_PCM) {\n\tframe_size = frame->size;\n\t//frame->size = frame_size;\n    } else {\n\t/* Must be ULAW or ALAW */\n\tpj_assert(fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ULAW || \n\t\t  fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ALAW);\n\n\tframe_size = frame->size >> 1;\n\tframe->size = frame_size << 1;\n    }\n\n    /* Copy frame from buffer. */\n    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    frame->timestamp.u64 = 0;\n\n    if ((fport->readpos + frame_size) <= (fport->buf + fport->bufsize))\n    {\n\t/* Read contiguous buffer. */\n\tpj_memcpy(frame->buf, fport->readpos, frame_size);\n\n\t/* Fill up the buffer if all has been read. */\n\tfport->readpos += frame_size;\n\tif (fport->readpos == fport->buf + fport->bufsize) {\n\t    fport->readpos = fport->buf;\n\n\t    status = fill_buffer(fport);\n\t    if (status != PJ_SUCCESS) {\n\t\tframe->type = PJMEDIA_FRAME_TYPE_NONE;\n\t\tframe->size = 0;\n\t\tfport->readpos = fport->buf + fport->bufsize;\n\t\treturn status;\n\t    }\n\t}\n    } else {\n\tunsigned endread;\n\n\t/* Split read.\n\t * First stage: read until end of buffer. \n\t */\n\tendread = (unsigned)((fport->buf+fport->bufsize) - fport->readpos);\n\tpj_memcpy(frame->buf, fport->readpos, endread);\n\n\t/* End Of Buffer and EOF and NO LOOP */\n\tif (fport->eof && (fport->options & PJMEDIA_FILE_NO_LOOP)) {\n\t    fport->readpos += endread;\n\n            if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_PCM) {\n                pj_bzero((char*)frame->buf + endread, frame_size - endread);\n            } else if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ULAW) {\n                int val = pjmedia_linear2ulaw(0);\n                pj_memset((char*)frame->buf + endread, val,\n                          frame_size - endread);\n            } else if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ALAW) {\n                int val = pjmedia_linear2alaw(0);\n                pj_memset((char*)frame->buf + endread, val,\n                          frame_size - endread);\n            }\n\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* Second stage: fill up buffer, and read from the start of buffer. */\n\tstatus = fill_buffer(fport);\n\tif (status != PJ_SUCCESS) {\n\t    frame->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    frame->size = 0;\n\t    fport->readpos = fport->buf + fport->bufsize;\n\t    return status;\n\t}\n\n\tpj_memcpy(((char*)frame->buf)+endread, fport->buf, frame_size-endread);\n\tfport->readpos = fport->buf + (frame_size - endread);\n    }\n\n    if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ULAW ||\n\tfport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ALAW)\n    {\n\tunsigned i;\n\tpj_uint16_t *dst;\n\tpj_uint8_t *src;\n\n\tdst = (pj_uint16_t*)frame->buf + frame_size - 1;\n\tsrc = (pj_uint8_t*)frame->buf + frame_size - 1;\n\n\tif (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ULAW) {\n\t    for (i = 0; i < frame_size; ++i) {\n\t\t*dst-- = (pj_uint16_t) pjmedia_ulaw2linear(*src--);\n\t    }\n\t} else {\n\t    for (i = 0; i < frame_size; ++i) {\n\t\t*dst-- = (pj_uint16_t) pjmedia_alaw2linear(*src--);\n\t    }\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Destroy port.\n */\nstatic pj_status_t file_on_destroy(pjmedia_port *this_port)\n{\n    struct file_reader_port *fport = (struct file_reader_port*) this_port;\n\n    pj_assert(this_port->info.signature == SIGNATURE);\n\n    pj_file_close(fport->fd);\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/wav_playlist.c",
    "content": "/* $Id: wav_playlist.c 3917 2011-12-20 10:01:35Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * Original author:\n *  David Clark <vdc1048 @ tx.rr.com>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/wav_playlist.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/wave.h>\n#include <pj/assert.h>\n#include <pj/file_access.h>\n#include <pj/file_io.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#define THIS_FILE\t    \"wav_playlist.c\"\n\n#define SIGNATURE\t    PJMEDIA_SIG_PORT_WAV_PLAYLIST\n#define BYTES_PER_SAMPLE    2\n\n\n#if 1\n#   define TRACE_(x)\tPJ_LOG(4,x)\n#else\n#   define TRACE_(x)\n#endif\n\n#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0\n    static void samples_to_host(pj_int16_t *samples, unsigned count)\n    {\n\tunsigned i;\n\tfor (i=0; i<count; ++i) {\n\t    samples[i] = pj_swap16(samples[i]);\n\t}\n    }\n#else\n#   define samples_to_host(samples,count)\n#endif\n\n\nstruct playlist_port\n{\n    pjmedia_port     base;\n    unsigned\t     options;\n    pj_bool_t\t     eof;\n    pj_uint32_t\t     bufsize;\n    char\t    *buf;\n    char\t    *readpos;\n\n    pj_off_t        *fsize_list;\n    unsigned        *start_data_list;\n    pj_off_t        *fpos_list;\n    pj_oshandle_t   *fd_list;\t    /* list of file descriptors\t*/\n    int              current_file;  /* index of current file.\t*/\n    int              max_file;\t    /* how many files.\t\t*/\n\n    pj_status_t\t   (*cb)(pjmedia_port*, void*);\n};\n\n\nstatic pj_status_t file_list_get_frame(pjmedia_port *this_port,\n\t\t\t\t       pjmedia_frame *frame);\nstatic pj_status_t file_list_on_destroy(pjmedia_port *this_port);\n\n\nstatic struct playlist_port *create_file_list_port(pj_pool_t *pool,\n\t\t\t\t\t\t   const pj_str_t *name)\n{\n    struct playlist_port *port;\n\n    port = PJ_POOL_ZALLOC_T(pool, struct playlist_port);\n    if (!port)\n\treturn NULL;\n\n    /* Put in default values.\n     * These will be overriden once the file is read.\n     */\n    pjmedia_port_info_init(&port->base.info, name, SIGNATURE,\n\t\t\t   8000, 1, 16, 80);\n\n    port->base.get_frame = &file_list_get_frame;\n    port->base.on_destroy = &file_list_on_destroy;\n\n    return port;\n}\n\n\n/*\n * Fill buffer for file_list operations.\n */\nstatic pj_status_t file_fill_buffer(struct playlist_port *fport)\n{\n    pj_uint32_t size_left = fport->bufsize;\n    pj_uint32_t size_to_read;\n    pj_ssize_t size;\n    pj_status_t status;\n    int current_file = fport->current_file;\n\n    /* Can't read file if EOF and loop flag is disabled */\n    if (fport->eof)\n\treturn PJ_EEOF;\n\n    while (size_left > 0)\n    {\n\t/* Calculate how many bytes to read in this run. */\n\tsize = size_to_read = size_left;\n\tstatus = pj_file_read(fport->fd_list[current_file],\n\t\t\t      &fport->buf[fport->bufsize-size_left],\n\t\t\t      &size);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\t\n\tif (size < 0)\n\t{\n\t    /* Should return more appropriate error code here.. */\n\t    return PJ_ECANCELLED;\n\t}\n\t\n\tsize_left -= (pj_uint32_t)size;\n\tfport->fpos_list[current_file] += size;\n\t\n\t/* If size is less than size_to_read, it indicates that we've\n\t * encountered EOF. Rewind the file.\n\t */\n\tif (size < (pj_ssize_t)size_to_read)\n\t{\n\t    /* Rewind the file for the next iteration */\n\t    fport->fpos_list[current_file] = \n\t\tfport->start_data_list[current_file];\n\t    pj_file_setpos(fport->fd_list[current_file], \n\t\t\t   fport->fpos_list[current_file], PJ_SEEK_SET);\n\n\t    /* Move to next file */\n\t    current_file++;\n\t    fport->current_file = current_file;\n\n\t    if (fport->current_file == fport->max_file)\n\t    {\n\t\t/* Clear the remaining part of the buffer first, to prevent\n\t\t * old samples from being played. If the playback restarts,\n\t\t * this will be overwritten by new reading.\n\t\t */\n\t\tif (size_left > 0) {\n\t\t    pj_bzero(&fport->buf[fport->bufsize-size_left], \n\t\t\t     size_left);\n\t\t}\n\n\t\t/* All files have been played. Call callback, if any. */\n\t\tif (fport->cb)\n\t\t{\n\t\t    PJ_LOG(5,(THIS_FILE,\n\t\t\t      \"File port %.*s EOF, calling callback\",\n\t\t\t      (int)fport->base.info.name.slen,\n\t\t\t      fport->base.info.name.ptr));\n\t\t    \n\t\t    fport->eof = PJ_TRUE;\n\n\t\t    status = (*fport->cb)(&fport->base,\n\t\t\t\t\t  fport->base.port_data.pdata);\n\n\t\t    if (status != PJ_SUCCESS)\n\t\t    {\n\t\t\t/* This will crash if file port is destroyed in the\n\t\t\t * callback, that's why we set the eof flag before\n\t\t\t * calling the callback:\n\t\t\t fport->eof = PJ_TRUE;\n\t\t\t */\n\t\t\treturn status;\n\t\t    }\n\n\t\t    fport->eof = PJ_FALSE;\n\t\t}\n\n\n\t\tif (fport->options & PJMEDIA_FILE_NO_LOOP)\n\t\t{\n\t\t    PJ_LOG(5,(THIS_FILE, \"File port %.*s EOF, stopping..\",\n\t\t\t      (int)fport->base.info.name.slen,\n\t\t\t      fport->base.info.name.ptr));\n\t\t    fport->eof = PJ_TRUE;\n\t\t    return PJ_EEOF;\n\t\t}\n\t\telse\n\t\t{\n\t\t    PJ_LOG(5,(THIS_FILE, \"File port %.*s EOF, rewinding..\",\n\t\t\t      (int)fport->base.info.name.slen,\n\t\t\t      fport->base.info.name.ptr));\n\t\t    \n\t\t    /* start with first file again. */\n\t\t    fport->current_file = current_file = 0;\n\t\t    fport->fpos_list[0] = fport->start_data_list[0];\n\t\t    pj_file_setpos(fport->fd_list[0], fport->fpos_list[0],\n\t\t\t\t   PJ_SEEK_SET);\n\t\t}\t\t\n\t\t\n\t    } /* if current_file == max_file */\n\n\t} /* size < size_to_read */\n\n    } /* while () */\n    \n    /* Convert samples to host rep */\n    samples_to_host((pj_int16_t*)fport->buf, fport->bufsize/BYTES_PER_SAMPLE);\n    \n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create wave list player.\n */\nPJ_DEF(pj_status_t) pjmedia_wav_playlist_create(pj_pool_t *pool,\n\t\t\t\t\t\tconst pj_str_t *port_label,\n\t\t\t\t\t\tconst pj_str_t file_list[],\n\t\t\t\t\t\tint file_count,\n\t\t\t\t\t\tunsigned ptime,\n\t\t\t\t\t\tunsigned options,\n\t\t\t\t\t\tpj_ssize_t buff_size,\n\t\t\t\t\t\tpjmedia_port **p_port)\n{\n    struct playlist_port *fport;\n    pjmedia_audio_format_detail *afd;\n    pj_off_t pos;\n    pj_status_t status;\n    int index;\n    pj_bool_t has_wave_info = PJ_FALSE;\n    pj_str_t tmp_port_label;\n    char filename[PJ_MAXPATH];\t/* filename for open operations.    */\n\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(pool && file_list && file_count && p_port, PJ_EINVAL);\n\n    /* Normalize port_label */\n    if (port_label == NULL || port_label->slen == 0) {\n\ttmp_port_label = pj_str(\"WAV playlist\");\n\tport_label = &tmp_port_label;\n    }\n\n    /* Be sure all files exist\t*/\n    for (index=0; index<file_count; index++) {\n\n\tPJ_ASSERT_RETURN(file_list[index].slen < PJ_MAXPATH, PJ_ENAMETOOLONG);\n\n\tpj_memcpy(filename, file_list[index].ptr, file_list[index].slen);\n\tfilename[file_list[index].slen] = '\\0';\n\n    \t/* Check the file really exists. */\n    \tif (!pj_file_exists(filename)) {\n\t    PJ_LOG(4,(THIS_FILE,\n\t\t      \"WAV playlist error: file '%s' not found\",\n\t      \t      filename));\n\t    return PJ_ENOTFOUND;\n    \t}\n    }\n\n    /* Normalize ptime */\n    if (ptime == 0)\n\tptime = 20;\n\n    /* Create fport instance. */\n    fport = create_file_list_port(pool, port_label);\n    if (!fport) {\n\treturn PJ_ENOMEM;\n    }\n\n    afd = pjmedia_format_get_audio_format_detail(&fport->base.info.fmt, 1);\n\n    /* start with the first file. */\n    fport->current_file = 0;\n    fport->max_file = file_count;\n\n    /* Create file descriptor list */\n    fport->fd_list = (pj_oshandle_t*)\n\t\t     pj_pool_zalloc(pool, sizeof(pj_oshandle_t)*file_count);\n    if (!fport->fd_list) {\n\treturn PJ_ENOMEM;\n    }\n\n    /* Create file size list */\n    fport->fsize_list = (pj_off_t*)\n\t\t\tpj_pool_alloc(pool, sizeof(pj_off_t)*file_count);\n    if (!fport->fsize_list) {\n\treturn PJ_ENOMEM;\n    }\n\n    /* Create start of WAVE data list */\n    fport->start_data_list = (unsigned*)\n\t\t\t     pj_pool_alloc(pool, sizeof(unsigned)*file_count);\n    if (!fport->start_data_list) {\n\treturn PJ_ENOMEM;\n    }\n\n    /* Create file position list */\n    fport->fpos_list = (pj_off_t*)\n\t\t       pj_pool_alloc(pool, sizeof(pj_off_t)*file_count);\n    if (!fport->fpos_list) {\n\treturn PJ_ENOMEM;\n    }\n\n    /* Create file buffer once for this operation.\n     */\n    if (buff_size < 1) buff_size = PJMEDIA_FILE_PORT_BUFSIZE;\n    fport->bufsize = (pj_uint32_t)buff_size;\n\n\n    /* Create buffer. */\n    fport->buf = (char*) pj_pool_alloc(pool, fport->bufsize);\n    if (!fport->buf) {\n\treturn PJ_ENOMEM;\n    }\n\n    /* Initialize port */\n    fport->options = options;\n    fport->readpos = fport->buf;\n\n\n    /* ok run this for all files to be sure all are good for playback. */\n    for (index=file_count-1; index>=0; index--) {\n\n\tpjmedia_wave_hdr wavehdr;\n\tpj_ssize_t size_to_read, size_read;\n\n\t/* we end with the last one so we are good to go if still in function*/\n\tpj_memcpy(filename, file_list[index].ptr, file_list[index].slen);\n\tfilename[file_list[index].slen] = '\\0';\n\n\t/* Get the file size. */\n\tfport->current_file = index;\n\tfport->fsize_list[index] = pj_file_size(filename);\n\t\n\t/* Size must be more than WAVE header size */\n\tif (fport->fsize_list[index] <= sizeof(pjmedia_wave_hdr)) {\n\t    status = PJMEDIA_ENOTVALIDWAVE;\n\t    goto on_error;\n\t}\n\t\n\t/* Open file. */\n\tstatus = pj_file_open( pool, filename, PJ_O_RDONLY, \n\t\t\t       &fport->fd_list[index]);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\t\n\t/* Read the file header plus fmt header only. */\n\tsize_read = size_to_read = sizeof(wavehdr) - 8;\n\tstatus = pj_file_read( fport->fd_list[index], &wavehdr, &size_read);\n\tif (status != PJ_SUCCESS) {\n\t    goto on_error;\n\t}\n\n\tif (size_read != size_to_read) {\n\t    status = PJMEDIA_ENOTVALIDWAVE;\n\t    goto on_error;\n\t}\n\t\n\t/* Normalize WAVE header fields values from little-endian to host\n\t * byte order.\n\t */\n\tpjmedia_wave_hdr_file_to_host(&wavehdr);\n\t\n\t/* Validate WAVE file. */\n\tif (wavehdr.riff_hdr.riff != PJMEDIA_RIFF_TAG ||\n\t    wavehdr.riff_hdr.wave != PJMEDIA_WAVE_TAG ||\n\t    wavehdr.fmt_hdr.fmt != PJMEDIA_FMT_TAG)\n\t{\n\t    TRACE_((THIS_FILE,\n\t\t\"actual value|expected riff=%x|%x, wave=%x|%x fmt=%x|%x\",\n\t\twavehdr.riff_hdr.riff, PJMEDIA_RIFF_TAG,\n\t\twavehdr.riff_hdr.wave, PJMEDIA_WAVE_TAG,\n\t\twavehdr.fmt_hdr.fmt, PJMEDIA_FMT_TAG));\n\t    status = PJMEDIA_ENOTVALIDWAVE;\n\t    goto on_error;\n\t}\n\t\n\t/* Must be PCM with 16bits per sample */\n\tif (wavehdr.fmt_hdr.fmt_tag != 1 ||\n\t    wavehdr.fmt_hdr.bits_per_sample != 16)\n\t{\n\t    status = PJMEDIA_EWAVEUNSUPP;\n\t    goto on_error;\n\t}\n\t\n\t/* Block align must be 2*nchannels */\n\tif (wavehdr.fmt_hdr.block_align != \n\t\twavehdr.fmt_hdr.nchan * BYTES_PER_SAMPLE)\n\t{\n\t    status = PJMEDIA_EWAVEUNSUPP;\n\t    goto on_error;\n\t}\n\t\n\t/* If length of fmt_header is greater than 16, skip the remaining\n\t * fmt header data.\n\t */\n\tif (wavehdr.fmt_hdr.len > 16) {\n\t    size_to_read = wavehdr.fmt_hdr.len - 16;\n\t    status = pj_file_setpos(fport->fd_list[index], size_to_read, \n\t\t\t\t    PJ_SEEK_CUR);\n\t    if (status != PJ_SUCCESS) {\n\t\tgoto on_error;\n\t    }\n\t}\n\t\n\t/* Repeat reading the WAVE file until we have 'data' chunk */\n\tfor (;;) {\n\t    pjmedia_wave_subchunk subchunk;\n\t    size_read = 8;\n\t    status = pj_file_read(fport->fd_list[index], &subchunk, \n\t\t\t\t  &size_read);\n\t    if (status != PJ_SUCCESS || size_read != 8) {\n\t\tstatus = PJMEDIA_EWAVETOOSHORT;\n\t\tgoto on_error;\n\t    }\n\t    \n\t    /* Normalize endianness */\n\t    PJMEDIA_WAVE_NORMALIZE_SUBCHUNK(&subchunk);\n\t    \n\t    /* Break if this is \"data\" chunk */\n\t    if (subchunk.id == PJMEDIA_DATA_TAG) {\n\t\twavehdr.data_hdr.data = PJMEDIA_DATA_TAG;\n\t\twavehdr.data_hdr.len = subchunk.len;\n\t\tbreak;\n\t    }\n\t    \n\t    /* Otherwise skip the chunk contents */\n\t    size_to_read = subchunk.len;\n\t    status = pj_file_setpos(fport->fd_list[index], size_to_read, \n\t\t\t\t    PJ_SEEK_CUR);\n\t    if (status != PJ_SUCCESS) {\n\t\tgoto on_error;\n\t    }\n\t}\n\t\n\t/* Current file position now points to start of data */\n\tstatus = pj_file_getpos(fport->fd_list[index], &pos);\n\tfport->start_data_list[index] = (unsigned)pos;\n\t\n\t/* Validate length. */\n\tif (wavehdr.data_hdr.len != fport->fsize_list[index] - \n\t\t\t\t       fport->start_data_list[index]) \n\t{\n\t    status = PJMEDIA_EWAVEUNSUPP;\n\t    goto on_error;\n\t}\n\tif (wavehdr.data_hdr.len < 400) {\n\t    status = PJMEDIA_EWAVETOOSHORT;\n\t    goto on_error;\n\t}\n\t\n\t/* It seems like we have a valid WAVE file. */\n\t\n\t/* Update port info if we don't have one, otherwise check\n\t * that the WAV file has the same attributes as previous files. \n\t */\n\tif (!has_wave_info) {\n\t    afd->channel_count = wavehdr.fmt_hdr.nchan;\n\t    afd->clock_rate = wavehdr.fmt_hdr.sample_rate;\n\t    afd->bits_per_sample = wavehdr.fmt_hdr.bits_per_sample;\n\t    afd->frame_time_usec = ptime * 1000;\n\t    afd->avg_bps = afd->max_bps = afd->clock_rate *\n\t\t\t\t\t  afd->channel_count *\n\t\t\t\t\t  afd->bits_per_sample;\n\n\t    has_wave_info = PJ_TRUE;\n\n\t} else {\n\n\t    /* Check that this file has the same characteristics as the other\n\t     * files.\n\t     */\n\t    if (wavehdr.fmt_hdr.nchan != afd->channel_count ||\n\t\twavehdr.fmt_hdr.sample_rate != afd->clock_rate ||\n\t\twavehdr.fmt_hdr.bits_per_sample != afd->bits_per_sample)\n\t    {\n\t\t/* This file has different characteristics than the other \n\t\t * files. \n\t\t */\n\t\tPJ_LOG(4,(THIS_FILE,\n\t\t          \"WAV playlist error: file '%s' has differrent number\"\n\t\t\t  \" of channels, sample rate, or bits per sample\",\n\t      \t\t  filename));\n\t\tstatus = PJMEDIA_EWAVEUNSUPP;\n\t\tgoto on_error;\n\t    }\n\n\t}\n\t\n\t\n\t/* Set initial position of the file. */\n\tfport->fpos_list[index] = fport->start_data_list[index];\n    }\n\n    /* Fill up the buffer. */\n    status = file_fill_buffer(fport);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n    \n    /* Done. */\n    \n    *p_port = &fport->base;\n    \n    PJ_LOG(4,(THIS_FILE,\n\t     \"WAV playlist '%.*s' created: samp.rate=%d, ch=%d, bufsize=%uKB\",\n\t     (int)port_label->slen,\n\t     port_label->ptr,\n\t     afd->clock_rate,\n\t     afd->channel_count,\n\t     fport->bufsize / 1000));\n    \n    return PJ_SUCCESS;\n\non_error:\n    for (index=0; index<file_count; ++index) {\n\tif (fport->fd_list[index] != 0)\n\t    pj_file_close(fport->fd_list[index]);\n    }\n\n    return status;\n}\n\n\n/*\n * Register a callback to be called when the file reading has reached the\n * end of the last file.\n */\nPJ_DEF(pj_status_t) pjmedia_wav_playlist_set_eof_cb(pjmedia_port *port,\n\t\t\t        void *user_data,\n\t\t\t        pj_status_t (*cb)(pjmedia_port *port,\n\t\t\t\t\t\t  void *usr_data))\n{\n    struct playlist_port *fport;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(port, PJ_EINVAL);\n\n    /* Check that this is really a playlist port */\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVALIDOP);\n\n    fport = (struct playlist_port*) port;\n\n    fport->base.port_data.pdata = user_data;\n    fport->cb = cb;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get frame from file for file_list operation\n */\nstatic pj_status_t file_list_get_frame(pjmedia_port *this_port,\n\t\t\t\t       pjmedia_frame *frame)\n{\n    struct playlist_port *fport = (struct playlist_port*)this_port;\n    pj_size_t frame_size;\n    pj_status_t status;\n\n    pj_assert(fport->base.info.signature == SIGNATURE);\n\n    //frame_size = fport->base.info.bytes_per_frame;\n    //pj_assert(frame->size == frame_size);\n    frame_size = frame->size;\n\n    /* Copy frame from buffer. */\n    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    frame->size = frame_size;\n    frame->timestamp.u64 = 0;\n\n    if (fport->readpos + frame_size <= fport->buf + fport->bufsize) {\n\n\t/* Read contiguous buffer. */\n\tpj_memcpy(frame->buf, fport->readpos, frame_size);\n\n\t/* Fill up the buffer if all has been read. */\n\tfport->readpos += frame_size;\n\tif (fport->readpos == fport->buf + fport->bufsize) {\n\t    fport->readpos = fport->buf;\n\n\t    status = file_fill_buffer(fport);\n\t    if (status != PJ_SUCCESS) {\n\t\tframe->type = PJMEDIA_FRAME_TYPE_NONE;\n\t\tframe->size = 0;\n\t\treturn status;\n\t    }\n\t}\n    } else {\n\tunsigned endread;\n\n\t/* Split read.\n\t * First stage: read until end of buffer.\n\t */\n\tendread = (unsigned)((fport->buf+fport->bufsize) - fport->readpos);\n\tpj_memcpy(frame->buf, fport->readpos, endread);\n\n\t/* Second stage: fill up buffer, and read from the start of buffer. */\n\tstatus = file_fill_buffer(fport);\n\tif (status != PJ_SUCCESS) {\n\t    pj_bzero(((char*)frame->buf)+endread, frame_size-endread);\n\t    return status;\n\t}\n\n\tpj_memcpy(((char*)frame->buf)+endread, fport->buf, frame_size-endread);\n\tfport->readpos = fport->buf + (frame_size - endread);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy port.\n */\nstatic pj_status_t file_list_on_destroy(pjmedia_port *this_port)\n{\n    struct playlist_port *fport = (struct playlist_port*) this_port;\n    int index;\n\n    pj_assert(this_port->info.signature == SIGNATURE);\n\n    for (index=0; index<fport->max_file; index++)\n\tpj_file_close(fport->fd_list[index]);\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/wav_writer.c",
    "content": "/* $Id: wav_writer.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/wav_port.h>\n#include <pjmedia/alaw_ulaw.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/wave.h>\n#include <pj/assert.h>\n#include <pj/file_access.h>\n#include <pj/file_io.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n#define THIS_FILE\t    \"wav_writer.c\"\n#define SIGNATURE\t    PJMEDIA_SIG_PORT_WAV_WRITER\n\n\nstruct file_port\n{\n    pjmedia_port     base;\n    pjmedia_wave_fmt_tag fmt_tag;\n    pj_uint16_t\t     bytes_per_sample;\n\n    pj_size_t\t     bufsize;\n    char\t    *buf;\n    char\t    *writepos;\n    pj_size_t\t     total;\n\n    pj_oshandle_t    fd;\n\n    pj_size_t\t     cb_size;\n    pj_status_t\t   (*cb)(pjmedia_port*, void*);\n};\n\nstatic pj_status_t file_put_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame);\nstatic pj_status_t file_get_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame);\nstatic pj_status_t file_on_destroy(pjmedia_port *this_port);\n\n\n/*\n * Create file writer port.\n */\nPJ_DEF(pj_status_t) pjmedia_wav_writer_port_create( pj_pool_t *pool,\n\t\t\t\t\t\t     const char *filename,\n\t\t\t\t\t\t     unsigned sampling_rate,\n\t\t\t\t\t\t     unsigned channel_count,\n\t\t\t\t\t\t     unsigned samples_per_frame,\n\t\t\t\t\t\t     unsigned bits_per_sample,\n\t\t\t\t\t\t     unsigned flags,\n\t\t\t\t\t\t     pj_ssize_t buff_size,\n\t\t\t\t\t\t     pjmedia_port **p_port )\n{\n    struct file_port *fport;\n    pjmedia_wave_hdr wave_hdr;\n    pj_ssize_t size;\n    pj_str_t name;\n    pj_status_t status;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(pool && filename && p_port, PJ_EINVAL);\n\n    /* Only supports 16bits per sample for now.\n     * See flush_buffer().\n     */\n    PJ_ASSERT_RETURN(bits_per_sample == 16, PJ_EINVAL);\n\n    /* Create file port instance. */\n    fport = PJ_POOL_ZALLOC_T(pool, struct file_port);\n    PJ_ASSERT_RETURN(fport != NULL, PJ_ENOMEM);\n\n    /* Initialize port info. */\n    pj_strdup2(pool, &name, filename);\n    pjmedia_port_info_init(&fport->base.info, &name, SIGNATURE,\n\t\t\t   sampling_rate, channel_count, bits_per_sample,\n\t\t\t   samples_per_frame);\n\n    fport->base.get_frame = &file_get_frame;\n    fport->base.put_frame = &file_put_frame;\n    fport->base.on_destroy = &file_on_destroy;\n\n    if (flags == PJMEDIA_FILE_WRITE_ALAW) {\n\tfport->fmt_tag = PJMEDIA_WAVE_FMT_TAG_ALAW;\n\tfport->bytes_per_sample = 1;\n    } else if (flags == PJMEDIA_FILE_WRITE_ULAW) {\n\tfport->fmt_tag = PJMEDIA_WAVE_FMT_TAG_ULAW;\n\tfport->bytes_per_sample = 1;\n    } else {\n\tfport->fmt_tag = PJMEDIA_WAVE_FMT_TAG_PCM;\n\tfport->bytes_per_sample = 2;\n    }\n\n    /* Open file in write and read mode.\n     * We need the read mode because we'll modify the WAVE header once\n     * the recording has completed.\n     */\n    status = pj_file_open(pool, filename, PJ_O_WRONLY, &fport->fd);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Initialize WAVE header */\n    pj_bzero(&wave_hdr, sizeof(pjmedia_wave_hdr));\n    wave_hdr.riff_hdr.riff = PJMEDIA_RIFF_TAG;\n    wave_hdr.riff_hdr.file_len = 0; /* will be filled later */\n    wave_hdr.riff_hdr.wave = PJMEDIA_WAVE_TAG;\n\n    wave_hdr.fmt_hdr.fmt = PJMEDIA_FMT_TAG;\n    wave_hdr.fmt_hdr.len = 16;\n    wave_hdr.fmt_hdr.fmt_tag = (pj_uint16_t)fport->fmt_tag;\n    wave_hdr.fmt_hdr.nchan = (pj_int16_t)channel_count;\n    wave_hdr.fmt_hdr.sample_rate = sampling_rate;\n    wave_hdr.fmt_hdr.bytes_per_sec = sampling_rate * channel_count * \n\t\t\t\t     fport->bytes_per_sample;\n    wave_hdr.fmt_hdr.block_align = (pj_uint16_t)\n\t\t\t\t   (fport->bytes_per_sample * channel_count);\n    wave_hdr.fmt_hdr.bits_per_sample = (pj_uint16_t)\n\t\t\t\t       (fport->bytes_per_sample * 8);\n\n    wave_hdr.data_hdr.data = PJMEDIA_DATA_TAG;\n    wave_hdr.data_hdr.len = 0;\t    /* will be filled later */\n\n\n    /* Convert WAVE header from host byte order to little endian\n     * before writing the header.\n     */\n    pjmedia_wave_hdr_host_to_file(&wave_hdr);\n\n\n    /* Write WAVE header */\n    if (fport->fmt_tag != PJMEDIA_WAVE_FMT_TAG_PCM) {\n\tpjmedia_wave_subchunk fact_chunk;\n\tpj_uint32_t tmp = 0;\n\n\tfact_chunk.id = PJMEDIA_FACT_TAG;\n\tfact_chunk.len = 4;\n\n\tPJMEDIA_WAVE_NORMALIZE_SUBCHUNK(&fact_chunk);\n\n\t/* Write WAVE header without DATA chunk header */\n\tsize = sizeof(pjmedia_wave_hdr) - sizeof(wave_hdr.data_hdr);\n\tstatus = pj_file_write(fport->fd, &wave_hdr, &size);\n\tif (status != PJ_SUCCESS) {\n\t    pj_file_close(fport->fd);\n\t    return status;\n\t}\n\n\t/* Write FACT chunk if it stores compressed data */\n\tsize = sizeof(fact_chunk);\n\tstatus = pj_file_write(fport->fd, &fact_chunk, &size);\n\tif (status != PJ_SUCCESS) {\n\t    pj_file_close(fport->fd);\n\t    return status;\n\t}\n\tsize = 4;\n\tstatus = pj_file_write(fport->fd, &tmp, &size);\n\tif (status != PJ_SUCCESS) {\n\t    pj_file_close(fport->fd);\n\t    return status;\n\t}\n\n\t/* Write DATA chunk header */\n\tsize = sizeof(wave_hdr.data_hdr);\n\tstatus = pj_file_write(fport->fd, &wave_hdr.data_hdr, &size);\n\tif (status != PJ_SUCCESS) {\n\t    pj_file_close(fport->fd);\n\t    return status;\n\t}\n    } else {\n\tsize = sizeof(pjmedia_wave_hdr);\n\tstatus = pj_file_write(fport->fd, &wave_hdr, &size);\n\tif (status != PJ_SUCCESS) {\n\t    pj_file_close(fport->fd);\n\t    return status;\n\t}\n    }\n\n    /* Set buffer size. */\n    if (buff_size < 1) buff_size = PJMEDIA_FILE_PORT_BUFSIZE;\n    fport->bufsize = buff_size;\n\n    /* Check that buffer size is greater than bytes per frame */\n    pj_assert(fport->bufsize >= PJMEDIA_PIA_AVG_FSZ(&fport->base.info));\n\n\n    /* Allocate buffer and set initial write position */\n    fport->buf = (char*) pj_pool_alloc(pool, fport->bufsize);\n    if (fport->buf == NULL) {\n\tpj_file_close(fport->fd);\n\treturn PJ_ENOMEM;\n    }\n    fport->writepos = fport->buf;\n\n    /* Done. */\n    *p_port = &fport->base;\n\n    PJ_LOG(4,(THIS_FILE, \n\t      \"File writer '%.*s' created: samp.rate=%d, bufsize=%uKB\",\n\t      (int)fport->base.info.name.slen,\n\t      fport->base.info.name.ptr,\n\t      PJMEDIA_PIA_SRATE(&fport->base.info),\n\t      fport->bufsize / 1000));\n\n\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Get current writing position. \n */\nPJ_DEF(pj_ssize_t) pjmedia_wav_writer_port_get_pos( pjmedia_port *port )\n{\n    struct file_port *fport;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(port, -PJ_EINVAL);\n\n    /* Check that this is really a writer port */\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, -PJ_EINVALIDOP);\n\n    fport = (struct file_port*) port;\n\n    return fport->total;\n}\n\n\n/*\n * Register callback.\n */\nPJ_DEF(pj_status_t) pjmedia_wav_writer_port_set_cb( pjmedia_port *port,\n\t\t\t\tpj_size_t pos,\n\t\t\t\tvoid *user_data,\n\t\t\t        pj_status_t (*cb)(pjmedia_port *port,\n\t\t\t\t\t\t  void *usr_data))\n{\n    struct file_port *fport;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(port && cb, PJ_EINVAL);\n\n    /* Check that this is really a writer port */\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVALIDOP);\n\n    fport = (struct file_port*) port;\n\n    fport->cb_size = pos;\n    fport->base.port_data.pdata = user_data;\n    fport->cb = cb;\n\n    return PJ_SUCCESS;\n}\n\n\n#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0\n    static void swap_samples(pj_int16_t *samples, unsigned count)\n    {\n\tunsigned i;\n\tfor (i=0; i<count; ++i) {\n\t    samples[i] = pj_swap16(samples[i]);\n\t}\n    }\n#else\n#   define swap_samples(samples,count)\n#endif\n\n/*\n * Flush the contents of the buffer to the file.\n */\nstatic pj_status_t flush_buffer(struct file_port *fport)\n{\n    pj_ssize_t bytes = fport->writepos - fport->buf;\n    pj_status_t status;\n\n    /* Convert samples to little endian */\n    swap_samples((pj_int16_t*)fport->buf, bytes/fport->bytes_per_sample);\n\n    /* Write to file. */\n    status = pj_file_write(fport->fd, fport->buf, &bytes);\n\n    /* Reset writepos */\n    fport->writepos = fport->buf;\n\n    return status;\n}\n\n/*\n * Put a frame into the buffer. When the buffer is full, flush the buffer\n * to the file.\n */\nstatic pj_status_t file_put_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame)\n{\n    struct file_port *fport = (struct file_port *)this_port;\n    pj_size_t frame_size;\n\n    if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_PCM)\n\tframe_size = frame->size;\n    else\n\tframe_size = frame->size >> 1;\n\n    /* Flush buffer if we don't have enough room for the frame. */\n    if (fport->writepos + frame_size > fport->buf + fport->bufsize) {\n\tpj_status_t status;\n\tstatus = flush_buffer(fport);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    /* Check if frame is not too large. */\n    PJ_ASSERT_RETURN(fport->writepos+frame_size <= fport->buf+fport->bufsize,\n\t\t     PJMEDIA_EFRMFILETOOBIG);\n\n    /* Copy frame to buffer. */\n    if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_PCM) {\n\tpj_memcpy(fport->writepos, frame->buf, frame->size);\n    } else {\n\tunsigned i;\n\tpj_int16_t *src = (pj_int16_t*)frame->buf;\n\tpj_uint8_t *dst = (pj_uint8_t*)fport->writepos;\n\n\tif (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ULAW) {\n\t    for (i = 0; i < frame_size; ++i) {\n\t\t*dst++ = pjmedia_linear2ulaw(*src++);\n\t    }\n\t} else {\n\t    for (i = 0; i < frame_size; ++i) {\n\t\t*dst++ = pjmedia_linear2alaw(*src++);\n\t    }\n\t}\n\n    }\n    fport->writepos += frame_size;\n\n    /* Increment total written, and check if we need to call callback */\n    fport->total += frame_size;\n    if (fport->cb && fport->total >= fport->cb_size) {\n\tpj_status_t (*cb)(pjmedia_port*, void*);\n\tpj_status_t status;\n\n\tcb = fport->cb;\n\tfport->cb = NULL;\n\n\tstatus = (*cb)(this_port, this_port->port_data.pdata);\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get frame, basicy is a no-op operation.\n */\nstatic pj_status_t file_get_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame)\n{\n    PJ_UNUSED_ARG(this_port);\n    PJ_UNUSED_ARG(frame);\n    return PJ_EINVALIDOP;\n}\n\n/*\n * Close the port, modify file header with updated file length.\n */\nstatic pj_status_t file_on_destroy(pjmedia_port *this_port)\n{\n    enum { FILE_LEN_POS = 4, DATA_LEN_POS = 40 };\n    struct file_port *fport = (struct file_port *)this_port;\n    pj_off_t file_size;\n    pj_ssize_t bytes;\n    pj_uint32_t wave_file_len;\n    pj_uint32_t wave_data_len;\n    pj_status_t status;\n    pj_uint32_t data_len_pos = DATA_LEN_POS;\n\n    /* Flush remaining buffers. */\n    if (fport->writepos != fport->buf) \n\tflush_buffer(fport);\n\n    /* Get file size. */\n    status = pj_file_getpos(fport->fd, &file_size);\n    if (status != PJ_SUCCESS) {\n        pj_file_close(fport->fd);\n\treturn status;\n    }\n\n    /* Calculate wave fields */\n    wave_file_len = (pj_uint32_t)(file_size - 8);\n    wave_data_len = (pj_uint32_t)(file_size - sizeof(pjmedia_wave_hdr));\n\n#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0\n    wave_file_len = pj_swap32(wave_file_len);\n    wave_data_len = pj_swap32(wave_data_len);\n#endif\n\n    /* Seek to the file_len field. */\n    status = pj_file_setpos(fport->fd, FILE_LEN_POS, PJ_SEEK_SET);\n    if (status != PJ_SUCCESS) {\n        pj_file_close(fport->fd);\n\treturn status;\n    }\n\n    /* Write file_len */\n    bytes = sizeof(wave_file_len);\n    status = pj_file_write(fport->fd, &wave_file_len, &bytes);\n    if (status != PJ_SUCCESS) {\n        pj_file_close(fport->fd);\n\treturn status;\n    }\n\n    /* Write samples_len in FACT chunk */\n    if (fport->fmt_tag != PJMEDIA_WAVE_FMT_TAG_PCM) {\n\tenum { SAMPLES_LEN_POS = 44};\n\tpj_uint32_t wav_samples_len;\n\n\t/* Adjust wave_data_len & data_len_pos since there is FACT chunk */\n\twave_data_len -= 12;\n\tdata_len_pos += 12;\n\twav_samples_len = wave_data_len;\n\n\t/* Seek to samples_len field. */\n\tstatus = pj_file_setpos(fport->fd, SAMPLES_LEN_POS, PJ_SEEK_SET);\n        if (status != PJ_SUCCESS) {\n            pj_file_close(fport->fd);\n\t    return status;\n        }\n\n\t/* Write samples_len */\n\tbytes = sizeof(wav_samples_len);\n\tstatus = pj_file_write(fport->fd, &wav_samples_len, &bytes);\n\tif (status != PJ_SUCCESS) {\n            pj_file_close(fport->fd);\n\t    return status;\n        }\n    }\n\n    /* Seek to data_len field. */\n    status = pj_file_setpos(fport->fd, data_len_pos, PJ_SEEK_SET);\n    if (status != PJ_SUCCESS) {\n        pj_file_close(fport->fd);\n\treturn status;\n    }\n\n    /* Write file_len */\n    bytes = sizeof(wave_data_len);\n    status = pj_file_write(fport->fd, &wave_data_len, &bytes);\n    if (status != PJ_SUCCESS) {\n        pj_file_close(fport->fd);\n\treturn status;\n    }\n\n    /* Close file */\n    status = pj_file_close(fport->fd);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Done. */\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/wave.c",
    "content": "/* $Id: wave.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/wave.h>\n\n/*\n * Change the endianness of WAVE header fields.\n */\nstatic void wave_hdr_swap_bytes( pjmedia_wave_hdr *hdr )\n{\n#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0\n    hdr->riff_hdr.riff\t\t    = pj_swap32(hdr->riff_hdr.riff);\n    hdr->riff_hdr.file_len\t    = pj_swap32(hdr->riff_hdr.file_len);\n    hdr->riff_hdr.wave\t\t    = pj_swap32(hdr->riff_hdr.wave);\n    \n    hdr->fmt_hdr.fmt\t\t    = pj_swap32(hdr->fmt_hdr.fmt);\n    hdr->fmt_hdr.len\t\t    = pj_swap32(hdr->fmt_hdr.len);\n    hdr->fmt_hdr.fmt_tag\t    = pj_swap16(hdr->fmt_hdr.fmt_tag);\n    hdr->fmt_hdr.nchan\t\t    = pj_swap16(hdr->fmt_hdr.nchan);\n    hdr->fmt_hdr.sample_rate\t    = pj_swap32(hdr->fmt_hdr.sample_rate);\n    hdr->fmt_hdr.bytes_per_sec\t    = pj_swap32(hdr->fmt_hdr.bytes_per_sec);\n    hdr->fmt_hdr.block_align\t    = pj_swap16(hdr->fmt_hdr.block_align);\n    hdr->fmt_hdr.bits_per_sample    = pj_swap16(hdr->fmt_hdr.bits_per_sample);\n    \n    hdr->data_hdr.data\t\t    = pj_swap32(hdr->data_hdr.data);\n    hdr->data_hdr.len\t\t    = pj_swap32(hdr->data_hdr.len);\n#else\n    PJ_UNUSED_ARG(hdr);\n#endif\n}\n\n\nPJ_DEF(void) pjmedia_wave_hdr_file_to_host( pjmedia_wave_hdr *hdr )\n{\n    wave_hdr_swap_bytes(hdr);\n}\n\nPJ_DEF(void) pjmedia_wave_hdr_host_to_file( pjmedia_wave_hdr *hdr )\n{\n    wave_hdr_swap_bytes(hdr);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia/wsola.c",
    "content": "/* $Id: wsola.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia/wsola.h>\n#include <pjmedia/circbuf.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/math.h>\n#include <pj/pool.h>\n\n/*\n * This file contains implementation of WSOLA using PJMEDIA_WSOLA_IMP_WSOLA\n * or PJMEDIA_WSOLA_IMP_NULL\n */\n#define THIS_FILE   \"wsola.c\"\n\n/*\n * http://trac.pjsip.org/repos/ticket/683:\n *  Workaround for segfault problem in the fixed point version of create_win()\n *  on ARM9 platform, possibly due to gcc optimization bug.\n *\n *  For now, we will use linear window when floating point is disabled.\n */\n#ifndef PJMEDIA_WSOLA_LINEAR_WIN\n#   define PJMEDIA_WSOLA_LINEAR_WIN    (!PJ_HAS_FLOATING_POINT)\n#endif\n\n\n#if 0\n#   define TRACE_(x)\tPJ_LOG(4,x)\n#else\n#   define TRACE_(x)\n#endif\n\n#if 0\n#   define CHECK_(x)\tpj_assert(x)\n#else\n#   define CHECK_(x)\n#endif\n\n\n#if (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA) || \\\n    (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA_LITE)\n\n/*\n * WSOLA implementation using WSOLA\n */\n\n/* Buffer size including history, in frames */\n#define FRAME_CNT\t6\n\n/* Number of history frames in buffer */\n#define HIST_CNT\t1.5\n\n/* Template size, in msec */\n#define TEMPLATE_PTIME\tPJMEDIA_WSOLA_TEMPLATE_LENGTH_MSEC\n\n/* Hanning window size, in msec */\n#define HANNING_PTIME\tPJMEDIA_WSOLA_DELAY_MSEC\n\n/* Number of frames in erase buffer */\n#define ERASE_CNT\t((unsigned)3)\n\n/* Minimum distance from template for find_pitch() of expansion, in frames */\n#define EXP_MIN_DIST\t0.5\n\n/* Maximum distance from template for find_pitch() of expansion, in frames */\n#define EXP_MAX_DIST\tHIST_CNT\n\n/* Duration of a continuous synthetic frames after which the volume \n * of the synthetic frame will be set to zero with fading-out effect.\n */\n#define MAX_EXPAND_MSEC\tPJMEDIA_WSOLA_MAX_EXPAND_MSEC\n\n\n/* Buffer content:\n *\n *  +---------+-----------+--------------------+\n *  | history | min_extra | more extra / empty |\n *  +---------+-----------+--------------------+\n *  ^         ^           ^                    ^\n * buf    hist_size   min_extra            buf_size\n * \n * History size (hist_size) is a constant value, initialized upon creation.\n *\n * min_extra size is equal to HANNING_PTIME, this samples is useful for \n * smoothening samples transition between generated frame & history \n * (when PLC is invoked), or between generated samples & normal frame \n * (after lost/PLC). Since min_extra samples need to be available at \n * any time, this will introduce delay of HANNING_PTIME ms.\n *\n * More extra is excess samples produced by PLC (PLC frame generation may \n * produce more than exact one frame).\n *\n * At any particular time, the buffer will contain at least (hist_size + \n * min_extra) samples.\n *\n * A \"save\" operation will append the new frame to the end of the buffer,\n * return the frame from samples right after history and shift the buffer\n * by one frame.\n *\n */\n\n/* WSOLA structure */\nstruct pjmedia_wsola\n{\n    unsigned\t\t clock_rate;\t    /* Sampling rate.\t\t    */\n    pj_uint16_t\t\t samples_per_frame; /* Samples per frame (const)    */\n    pj_uint16_t\t\t channel_count;\t    /* Channel countt (const)\t    */\n    pj_uint16_t\t\t options;\t    /* Options.\t\t\t    */\n\n    pjmedia_circ_buf\t*buf;\t\t    /* The buffer.\t\t    */\n    pj_int16_t\t\t*erase_buf;\t    /* Temporary erase buffer.\t    */\n    pj_int16_t\t\t*merge_buf;\t    /* Temporary merge buffer.\t    */\n\n    pj_uint16_t\t\t buf_size;\t    /* Total buffer size (const)    */\n    pj_uint16_t\t\t hanning_size;\t    /* Hanning window size (const)  */\n    pj_uint16_t\t\t templ_size;\t    /* Template size (const)\t    */\n    pj_uint16_t\t\t hist_size;\t    /* History size (const)\t    */\n\n    pj_uint16_t\t\t min_extra;\t    /* Minimum extra (const)\t    */\n    unsigned\t\t max_expand_cnt;    /* Max # of synthetic samples   */\n    unsigned\t\t fade_out_pos;\t    /* Last fade-out position\t    */\n    pj_uint16_t\t\t expand_sr_min_dist;/* Minimum distance from template \n\t\t\t\t\t       for find_pitch() on expansion\n\t\t\t\t\t       (const)\t\t\t    */\n    pj_uint16_t\t\t expand_sr_max_dist;/* Maximum distance from template \n\t\t\t\t\t       for find_pitch() on expansion\n\t\t\t\t\t       (const)\t\t\t    */\n\n#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0\n    float\t\t*hanning;\t    /* Hanning window.\t\t    */\n#else\n    pj_uint16_t\t\t*hanning;\t    /* Hanning window.\t\t    */\n#endif\n\n    pj_timestamp\t ts;\t\t    /* Running timestamp.\t    */\n\n};\n\n#if (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA_LITE)\n\n/* In this implementation, waveform similarity comparison is done by calculating\n * the difference of total level between template frame and the target buffer \n * for each template_cnt samples. The smallest difference value assumed to be \n * the most similar block. This seems to be naive, however some tests show\n * acceptable results and the processing speed is amazing.\n *\n * diff level = (template[1]+..+template[n]) - (target[1]+..+target[n])\n */\nstatic pj_int16_t *find_pitch(pj_int16_t *frm, pj_int16_t *beg, pj_int16_t *end, \n\t\t\t unsigned template_cnt, int first)\n{\n    pj_int16_t *sr, *best=beg;\n    int best_corr = 0x7FFFFFFF;\n    int frm_sum = 0;\n    unsigned i;\n\n    for (i = 0; i<template_cnt; ++i)\n\tfrm_sum += frm[i];\n\n    for (sr=beg; sr!=end; ++sr) {\n\tint corr = frm_sum;\n\tint abs_corr = 0;\n\n\t/* Do calculation on 8 samples at once */\n\tfor (i = 0; i<template_cnt-8; i+=8) {\n\t    corr -= (int)sr[i+0] +\n\t\t    (int)sr[i+1] +\n\t\t    (int)sr[i+2] +\n\t\t    (int)sr[i+3] +\n\t\t    (int)sr[i+4] +\n\t\t    (int)sr[i+5] +\n\t\t    (int)sr[i+6] +\n\t\t    (int)sr[i+7];\n\t}\n\n\t/* Process remaining samples */\n\tfor (; i<template_cnt; ++i)\n\t    corr -= (int)sr[i];\n\n\tabs_corr = corr > 0? corr : -corr;\n\n\tif (first) {\n\t    if (abs_corr < best_corr) {\n\t\tbest_corr = abs_corr;\n\t\tbest = sr;\n\t    }\n\t} else {\n\t    if (abs_corr <= best_corr) {\n\t\tbest_corr = abs_corr;\n\t\tbest = sr;\n\t    }\n\t}\n    }\n\n    /*TRACE_((THIS_FILE, \"found pitch at %u\", best-beg));*/\n    return best;\n}\n\n#endif\n\n#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0\n/*\n * Floating point version.\n */\n\n#if (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA)\n\nstatic pj_int16_t *find_pitch(pj_int16_t *frm, pj_int16_t *beg, pj_int16_t *end, \n\t\t\t unsigned template_cnt, int first)\n{\n    pj_int16_t *sr, *best=beg;\n    double best_corr = 0;\n\n    for (sr=beg; sr!=end; ++sr) {\n\tdouble corr = 0;\n\tunsigned i;\n\n\t/* Do calculation on 8 samples at once */\n\tfor (i=0; i<template_cnt-8; i += 8) {\n\t    corr += ((float)frm[i+0]) * ((float)sr[i+0]) + \n\t\t    ((float)frm[i+1]) * ((float)sr[i+1]) + \n\t\t    ((float)frm[i+2]) * ((float)sr[i+2]) + \n\t\t    ((float)frm[i+3]) * ((float)sr[i+3]) + \n\t\t    ((float)frm[i+4]) * ((float)sr[i+4]) + \n\t\t    ((float)frm[i+5]) * ((float)sr[i+5]) + \n\t\t    ((float)frm[i+6]) * ((float)sr[i+6]) + \n\t\t    ((float)frm[i+7]) * ((float)sr[i+7]);\n\t}\n\n\t/* Process remaining samples. */\n\tfor (; i<template_cnt; ++i) {\n\t    corr += ((float)frm[i]) * ((float)sr[i]);\n\t}\n\n\tif (first) {\n\t    if (corr > best_corr) {\n\t\tbest_corr = corr;\n\t\tbest = sr;\n\t    }\n\t} else {\n\t    if (corr >= best_corr) {\n\t\tbest_corr = corr;\n\t\tbest = sr;\n\t    }\n\t}\n    }\n\n    /*TRACE_((THIS_FILE, \"found pitch at %u\", best-beg));*/\n    return best;\n}\n\n#endif\n\nstatic void overlapp_add(pj_int16_t dst[], unsigned count,\n\t\t\t pj_int16_t l[], pj_int16_t r[],\n\t\t\t float w[])\n{\n    unsigned i;\n\n    for (i=0; i<count; ++i) {\n\tdst[i] = (pj_int16_t)(l[i] * w[count-1-i] + r[i] * w[i]);\n    }\n}\n\nstatic void overlapp_add_simple(pj_int16_t dst[], unsigned count,\n\t\t\t\tpj_int16_t l[], pj_int16_t r[])\n{\n    float step = (float)(1.0 / count), stepdown = 1.0;\n    unsigned i;\n\n    for (i=0; i<count; ++i) {\n\tdst[i] = (pj_int16_t)(l[i] * stepdown + r[i] * (1-stepdown));\n\tstepdown -= step;\n    }\n}\n\nstatic void create_win(pj_pool_t *pool, float **pw, unsigned count)\n{\n    unsigned i;\n    float *w = (float*)pj_pool_calloc(pool, count, sizeof(float));\n\n    *pw = w;\n\n    for (i=0;i<count; i++) {\n\tw[i] = (float)(0.5 - 0.5 * cos(2.0 * PJ_PI * i / (count*2-1)) );\n    }\n}\n\n#else\t/* PJ_HAS_FLOATING_POINT */\n/*\n * Fixed point version.\n */\n#define WINDOW_BITS\t15\nenum { WINDOW_MAX_VAL = (1 << WINDOW_BITS)-1 };\n\n#if (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA)\n\nstatic pj_int16_t *find_pitch(pj_int16_t *frm, pj_int16_t *beg, pj_int16_t *end, \n\t\t\t unsigned template_cnt, int first)\n{\n    pj_int16_t *sr, *best=beg;\n    pj_int64_t best_corr = 0;\n\n    \n    for (sr=beg; sr!=end; ++sr) {\n\tpj_int64_t corr = 0;\n\tunsigned i;\n\n\t/* Do calculation on 8 samples at once */\n\tfor (i=0; i<template_cnt-8; i+=8) {\n\t    corr += ((int)frm[i+0]) * ((int)sr[i+0]) + \n\t\t    ((int)frm[i+1]) * ((int)sr[i+1]) + \n\t\t    ((int)frm[i+2]) * ((int)sr[i+2]) +\n\t\t    ((int)frm[i+3]) * ((int)sr[i+3]) +\n\t\t    ((int)frm[i+4]) * ((int)sr[i+4]) +\n\t\t    ((int)frm[i+5]) * ((int)sr[i+5]) +\n\t\t    ((int)frm[i+6]) * ((int)sr[i+6]) +\n\t\t    ((int)frm[i+7]) * ((int)sr[i+7]);\n\t}\n\n\t/* Process remaining samples. */\n\tfor (; i<template_cnt; ++i) {\n\t    corr += ((int)frm[i]) * ((int)sr[i]);\n\t}\n\n\tif (first) {\n\t    if (corr > best_corr) {\n\t\tbest_corr = corr;\n\t\tbest = sr;\n\t    }\n\t} else {\n\t    if (corr >= best_corr) {\n\t\tbest_corr = corr;\n\t\tbest = sr;\n\t    }\n\t}\n    }\n\n    /*TRACE_((THIS_FILE, \"found pitch at %u\", best-beg));*/\n    return best;\n}\n\n#endif\n\n\nstatic void overlapp_add(pj_int16_t dst[], unsigned count,\n\t\t\t pj_int16_t l[], pj_int16_t r[],\n\t\t\t pj_uint16_t w[])\n{\n    unsigned i;\n\n    for (i=0; i<count; ++i) {\n\tdst[i] = (pj_int16_t)(((int)(l[i]) * (int)(w[count-1-i]) + \n\t                  (int)(r[i]) * (int)(w[i])) >> WINDOW_BITS);\n    }\n}\n\nstatic void overlapp_add_simple(pj_int16_t dst[], unsigned count,\n\t\t\t\tpj_int16_t l[], pj_int16_t r[])\n{\n    int step = ((WINDOW_MAX_VAL+1) / count), \n\tstepdown = WINDOW_MAX_VAL;\n    unsigned i;\n\n    for (i=0; i<count; ++i) {\n\tdst[i]=(pj_int16_t)((l[i] * stepdown + r[i] * (1-stepdown)) >> WINDOW_BITS);\n\tstepdown -= step;\n    }\n}\n\n#if PJ_HAS_INT64 && !PJMEDIA_WSOLA_LINEAR_WIN\n/* approx_cos():\n *   see: http://www.audiomulch.com/~rossb/code/sinusoids/ \n */\nstatic pj_uint32_t approx_cos( pj_uint32_t x )\n{\n    pj_uint32_t i,j,k;\n\n    if( x == 0 )\n\treturn 0xFFFFFFFF;\n\n    i = x << 1;\n    k = ((x + 0xBFFFFFFD) & 0x80000000) >> 30;\n    j = i - i * ((i & 0x80000000)>>30);\n    j = j >> 15;\n    j = (j * j + j) >> 1;\n    j = j - j * k;\n\n    return j;\n}\n#endif\t/* PJ_HAS_INT64 && .. */\n\nstatic void create_win(pj_pool_t *pool, pj_uint16_t **pw, unsigned count)\n{\n    \n    unsigned i;\n    pj_uint16_t *w = (pj_uint16_t*)pj_pool_calloc(pool, count, \n\t\t\t\t\t\t  sizeof(pj_uint16_t));\n\n    *pw = w;\n\n    for (i=0; i<count; i++) {\n#if PJ_HAS_INT64 && !PJMEDIA_WSOLA_LINEAR_WIN\n\tpj_uint32_t phase;\n\tpj_uint64_t cos_val;\n\n\t/* w[i] = (float)(0.5 - 0.5 * cos(2.0 * PJ_PI * i / (count*2-1)) ); */\n\n\tphase = (pj_uint32_t)(PJ_INT64(0xFFFFFFFF) * i / (count*2-1));\n\tcos_val = approx_cos(phase);\n\n\tw[i] = (pj_uint16_t)(WINDOW_MAX_VAL - \n\t\t\t      (WINDOW_MAX_VAL * cos_val) / 0xFFFFFFFF);\n#else\n\t/* Revert to linear */\n\tw[i] = (pj_uint16_t)(i * WINDOW_MAX_VAL / count);\n#endif\n    }\n}\n\n#endif\t/* PJ_HAS_FLOATING_POINT */\n\n/* Apply fade-in to the buffer.\n *  - fade_cnt is the number of samples on which the volume\n *       will go from zero to 100%\n *  - fade_pos is current sample position within fade_cnt range.\n *       It is zero for the first sample, so the first sample will\n *\t have zero volume. This value is increasing.\n */\nstatic void fade_in(pj_int16_t buf[], int count,\n\t\t    int fade_in_pos, int fade_cnt)\n{\n#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0\n    float fade_pos = (float)fade_in_pos;\n#else\n    int fade_pos = fade_in_pos;\n#endif\n\n    if (fade_cnt - fade_pos < count) {\n\tfor (; fade_pos < fade_cnt; ++fade_pos, ++buf) {\n\t    *buf = (pj_int16_t)(*buf * fade_pos / fade_cnt);\n\t}\n\t/* Leave the remaining samples as is */\n    } else {\n\tpj_int16_t *end = buf + count;\n\tfor (; buf != end; ++fade_pos, ++buf) {\n\t    *buf = (pj_int16_t)(*buf * fade_pos / fade_cnt);\n\t}\n    }\n}\n\n/* Apply fade-out to the buffer. */\nstatic void wsola_fade_out(pjmedia_wsola *wsola, \n\t\t\t   pj_int16_t buf[], int count)\n{\n    pj_int16_t *end = buf + count;\n    int fade_cnt = wsola->max_expand_cnt;\n#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0\n    float fade_pos = (float)wsola->fade_out_pos;\n#else\n    int fade_pos = wsola->fade_out_pos;\n#endif\n\n    if (wsola->fade_out_pos == 0) {\n\tpjmedia_zero_samples(buf, count);\n    } else if (fade_pos < count) {\n\tfor (; fade_pos; --fade_pos, ++buf) {\n\t    *buf = (pj_int16_t)(*buf * fade_pos / fade_cnt);\n\t}\n\tif (buf != end)\n\t    pjmedia_zero_samples(buf, (unsigned)(end - buf));\n\twsola->fade_out_pos = 0;\n    } else {\n\tfor (; buf != end; --fade_pos, ++buf) {\n\t    *buf = (pj_int16_t)(*buf * fade_pos / fade_cnt);\n\t}\n\twsola->fade_out_pos -= count;\n    }\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_wsola_create( pj_pool_t *pool, \n\t\t\t\t\t  unsigned clock_rate,\n\t\t\t\t\t  unsigned samples_per_frame,\n\t\t\t\t\t  unsigned channel_count,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t\t  pjmedia_wsola **p_wsola)\n{\n    pjmedia_wsola *wsola;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && clock_rate && samples_per_frame && p_wsola,\n\t\t     PJ_EINVAL);\n    PJ_ASSERT_RETURN(clock_rate <= 65535, PJ_EINVAL);\n    PJ_ASSERT_RETURN(samples_per_frame < clock_rate, PJ_EINVAL);\n    PJ_ASSERT_RETURN(channel_count > 0, PJ_EINVAL);\n\n    /* Allocate wsola and initialize vars */\n    wsola = PJ_POOL_ZALLOC_T(pool, pjmedia_wsola);\n    wsola->clock_rate= (pj_uint16_t) clock_rate;\n    wsola->samples_per_frame = (pj_uint16_t) samples_per_frame;\n    wsola->channel_count = (pj_uint16_t) channel_count;\n    wsola->options = (pj_uint16_t) options;\n    wsola->max_expand_cnt = clock_rate * MAX_EXPAND_MSEC / 1000;\n    wsola->fade_out_pos = wsola->max_expand_cnt;\n\n    /* Create circular buffer */\n    wsola->buf_size = (pj_uint16_t) (samples_per_frame * FRAME_CNT);\n    status = pjmedia_circ_buf_create(pool, wsola->buf_size, &wsola->buf);\n    if (status != PJ_SUCCESS) {\n\tPJ_LOG(3, (THIS_FILE, \"Failed to create circular buf\"));\n\treturn status;\n    }\n\n    /* Calculate history size */\n    wsola->hist_size = (pj_uint16_t)(HIST_CNT * samples_per_frame);\n\n    /* Calculate template size */\n    wsola->templ_size = (pj_uint16_t)(TEMPLATE_PTIME * clock_rate * \n\t\t\t\t      channel_count / 1000);\n    if (wsola->templ_size > samples_per_frame)\n\twsola->templ_size = wsola->samples_per_frame;\n\n    /* Calculate hanning window size */\n    wsola->hanning_size = (pj_uint16_t)(HANNING_PTIME * clock_rate * \n\t\t\t\t        channel_count / 1000);\n    if (wsola->hanning_size > wsola->samples_per_frame)\n\twsola->hanning_size = wsola->samples_per_frame;\n\n    pj_assert(wsola->templ_size <= wsola->hanning_size);\n\n    /* Create merge buffer */\n    wsola->merge_buf = (pj_int16_t*) pj_pool_calloc(pool, \n\t\t\t\t\t\t    wsola->hanning_size,\n\t\t\t\t\t\t    sizeof(pj_int16_t));\n\n    /* Setup with PLC */\n    if ((options & PJMEDIA_WSOLA_NO_PLC) == 0) {\n\twsola->min_extra = wsola->hanning_size;\n\twsola->expand_sr_min_dist = (pj_uint16_t)\n\t\t\t\t    (EXP_MIN_DIST * wsola->samples_per_frame);\n\twsola->expand_sr_max_dist = (pj_uint16_t)\n\t\t\t\t    (EXP_MAX_DIST * wsola->samples_per_frame);\n    }\n\n    /* Setup with hanning */\n    if ((options & PJMEDIA_WSOLA_NO_HANNING) == 0) {\n\tcreate_win(pool, &wsola->hanning, wsola->hanning_size);\n    }\n\n    /* Setup with discard */\n    if ((options & PJMEDIA_WSOLA_NO_DISCARD) == 0) {\n\twsola->erase_buf = (pj_int16_t*)pj_pool_calloc(pool, samples_per_frame *\n\t\t\t\t\t\t       ERASE_CNT,\n\t\t\t\t\t\t       sizeof(pj_int16_t));\n    }\n\n    /* Generate dummy extra */\n    pjmedia_circ_buf_set_len(wsola->buf, wsola->hist_size + wsola->min_extra);\n\n    *p_wsola = wsola;\n    return PJ_SUCCESS;\n\n}\n\nPJ_DEF(pj_status_t) pjmedia_wsola_destroy(pjmedia_wsola *wsola)\n{\n    /* Nothing to do */\n    PJ_UNUSED_ARG(wsola);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_wsola_set_max_expand(pjmedia_wsola *wsola,\n\t\t\t\t\t\t  unsigned msec)\n{\n    PJ_ASSERT_RETURN(wsola, PJ_EINVAL);\n    wsola->max_expand_cnt = msec * wsola->clock_rate / 1000;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjmedia_wsola_reset( pjmedia_wsola *wsola,\n\t\t\t\t\t unsigned options)\n{\n    PJ_ASSERT_RETURN(wsola && options==0, PJ_EINVAL);\n    PJ_UNUSED_ARG(options);\n\n    pjmedia_circ_buf_reset(wsola->buf);\n    pjmedia_circ_buf_set_len(wsola->buf, wsola->hist_size + wsola->min_extra);\n    pjmedia_zero_samples(wsola->buf->start, wsola->buf->len); \n    wsola->fade_out_pos = wsola->max_expand_cnt;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void expand(pjmedia_wsola *wsola, unsigned needed)\n{\n    unsigned generated = 0;\n    unsigned rep;\n\n    pj_int16_t *reg1, *reg2;\n    unsigned reg1_len, reg2_len;\n\n    pjmedia_circ_buf_pack_buffer(wsola->buf);\n    pjmedia_circ_buf_get_read_regions(wsola->buf, &reg1, &reg1_len, \n\t\t\t\t      &reg2, &reg2_len);\n    CHECK_(reg2_len == 0);\n\n    for (rep=1;; ++rep) {\n\tpj_int16_t *start, *templ;\n\tunsigned dist;\n\n\ttempl = reg1 + reg1_len - wsola->hanning_size;\n\tCHECK_(templ - reg1 >= wsola->hist_size);\n\n\tstart = find_pitch(templ, \n\t\t\t   templ - wsola->expand_sr_max_dist, \n\t\t\t   templ - wsola->expand_sr_min_dist,\n\t\t\t   wsola->templ_size, \n\t\t\t   1);\n\n\t/* Should we make sure that \"start\" is really aligned to\n\t * channel #0, in case of stereo? Probably not necessary, as\n\t * find_pitch() should have found the best match anyway.\n\t */\n\n\tif (wsola->options & PJMEDIA_WSOLA_NO_HANNING) {\n\t    overlapp_add_simple(wsola->merge_buf, wsola->hanning_size, \n\t\t\t        templ, start);\n\t} else {\n\t    /* Check if pointers are in the valid range */\n\t    CHECK_(templ >= wsola->buf->buf &&\n\t\t   templ + wsola->hanning_size <= \n\t\t   wsola->buf->buf + wsola->buf->capacity);\n\t    CHECK_(start >= wsola->buf->buf &&\n\t\t   start + wsola->hanning_size <= \n\t\t   wsola->buf->buf + wsola->buf->capacity);\n\n\t    overlapp_add(wsola->merge_buf, wsola->hanning_size, templ, \n\t\t\t start, wsola->hanning);\n\t}\n\n\t/* How many new samples do we have */\n\tdist = (unsigned)(templ - start);\n\n\t/* Not enough buffer to hold the result */\n\tif (reg1_len + dist > wsola->buf_size) {\n\t    pj_assert(!\"WSOLA buffer size may be to small!\");\n\t    break;\n\t}\n\n\t/* Copy the \"tail\" (excess frame) to the end */\n\tpjmedia_move_samples(templ + wsola->hanning_size, \n\t\t\t     start + wsola->hanning_size,\n\t\t\t     dist);\n\n\t/* Copy the merged frame */\n\tpjmedia_copy_samples(templ, wsola->merge_buf, wsola->hanning_size);\n\n\t/* We have new samples */\n\treg1_len += dist;\n\tpjmedia_circ_buf_set_len(wsola->buf, reg1_len);\n\n\tgenerated += dist;\n\n\tif (generated >= needed) {\n\t    TRACE_((THIS_FILE, \"WSOLA frame expanded after %d iterations\", \n\t\t    rep));\n\t    break;\n\t}\n    }\n}\n\n\nstatic unsigned compress(pjmedia_wsola *wsola, pj_int16_t *buf, unsigned count,\n\t\t\t unsigned del_cnt)\n{\n    unsigned samples_del = 0, rep;\n\n    for (rep=1; ; ++rep) {\n\tpj_int16_t *start, *end;\n\tunsigned dist;\n\n\tif (count <= wsola->hanning_size + del_cnt) {\n\t    TRACE_((THIS_FILE, \"Not enough samples to compress!\"));\n\t    return samples_del;\n\t}\n\n\t// Make start distance to del_cnt, so discard will be performed in\n\t// only one iteration.\n\t//start = buf + (frmsz >> 1);\n\tstart = buf + del_cnt - samples_del;\n\tend = start + wsola->samples_per_frame;\n\n\tif (end + wsola->hanning_size > buf + count) {\n\t    end = buf+count-wsola->hanning_size;\n\t}\n\n\tCHECK_(start < end);\n\n\tstart = find_pitch(buf, start, end, wsola->templ_size, 0);\n\tdist = (unsigned)(start - buf);\n\n\tif (wsola->options & PJMEDIA_WSOLA_NO_HANNING) {\n\t    overlapp_add_simple(buf, wsola->hanning_size, buf, start);\n\t} else {\n\t    overlapp_add(buf, wsola->hanning_size, buf, start, wsola->hanning);\n\t}\n\n\tpjmedia_move_samples(buf + wsola->hanning_size, \n\t\t\t     buf + wsola->hanning_size + dist,\n\t\t\t     count - wsola->hanning_size - dist);\n\n\tcount -= dist;\n\tsamples_del += dist;\n\n\tif (samples_del >= del_cnt) {\n\t    TRACE_((THIS_FILE, \n\t\t    \"Erased %d of %d requested after %d iteration(s)\",\n\t\t    samples_del, del_cnt, rep));\n\t    break;\n\t}\n    }\n\n    return samples_del;\n}\n\n\n\nPJ_DEF(pj_status_t) pjmedia_wsola_save( pjmedia_wsola *wsola, \n\t\t\t\t\tpj_int16_t frm[], \n\t\t\t\t\tpj_bool_t prev_lost)\n{\n    unsigned buf_len;\n    pj_status_t status;\n\n    buf_len = pjmedia_circ_buf_get_len(wsola->buf);\n\n    /* Update vars */\n    wsola->ts.u64 += wsola->samples_per_frame;\n\n    /* If previous frame was lost, smoothen this frame with the generated one */\n    if (prev_lost) {\n\tpj_int16_t *reg1, *reg2;\n\tunsigned reg1_len, reg2_len;\n\tpj_int16_t *ola_left;\n\n\t/* Trim excessive len */\n\tif ((int)buf_len > wsola->hist_size + (wsola->min_extra<<1)) {\n\t    buf_len = wsola->hist_size + (wsola->min_extra<<1);\n\t    pjmedia_circ_buf_set_len(wsola->buf, buf_len);\n\t}\n\n\tpjmedia_circ_buf_get_read_regions(wsola->buf, &reg1, &reg1_len, \n\t\t\t\t\t  &reg2, &reg2_len);\n\n\tCHECK_(pjmedia_circ_buf_get_len(wsola->buf) >= \n\t       (unsigned)(wsola->hist_size + (wsola->min_extra<<1)));\n\n\t/* Continue applying fade out to the extra samples */\n\tif ((wsola->options & PJMEDIA_WSOLA_NO_FADING)==0) {\n\t    if (reg2_len == 0) {\n\t\twsola_fade_out(wsola, reg1 + reg1_len - (wsola->min_extra<<1),\n\t\t\t       (wsola->min_extra<<1));\n\t    } else if ((int)reg2_len >= (wsola->min_extra<<1)) {\n\t\twsola_fade_out(wsola, reg2 + reg2_len - (wsola->min_extra<<1),\n\t\t\t       (wsola->min_extra<<1));\n\t    } else {\n\t\tunsigned tmp = (wsola->min_extra<<1) - reg2_len;\n\t\twsola_fade_out(wsola, reg1 + reg1_len - tmp, tmp);\n\t\twsola_fade_out(wsola, reg2, reg2_len);\n\t    }\n\t}\n\n\t/* Get the region in buffer to be merged with the frame */\n\tif (reg2_len == 0) {\n\t    ola_left = reg1 + reg1_len - wsola->min_extra;\n\t} else if (reg2_len >= wsola->min_extra) {\n\t    ola_left = reg2 + reg2_len - wsola->min_extra;\n\t} else {\n\t    unsigned tmp;\n\n\t    tmp = wsola->min_extra - reg2_len;\n\t    pjmedia_copy_samples(wsola->merge_buf, reg1 + reg1_len - tmp, tmp);\n\t    pjmedia_copy_samples(wsola->merge_buf + tmp, reg2, reg2_len);\n\t    ola_left = wsola->merge_buf;\n\t}\n\n\t/* Apply fade-in to the frame before merging */\n\tif ((wsola->options & PJMEDIA_WSOLA_NO_FADING)==0) {\n\t    unsigned count = wsola->min_extra;\n\t    int fade_in_pos;\n\n\t    /* Scale fade_in position based on last fade-out */\n\t    fade_in_pos = wsola->fade_out_pos * count /\n\t\t\t  wsola->max_expand_cnt;\n\n\t    /* Fade-in it */\n\t    fade_in(frm, wsola->samples_per_frame,\n\t\t    fade_in_pos, count);\n\t}\n\n\t/* Merge it */\n\toverlapp_add_simple(frm, wsola->min_extra, ola_left, frm);\n\n\t/* Trim len */\n\tbuf_len -= wsola->min_extra;\n\tpjmedia_circ_buf_set_len(wsola->buf, buf_len);\n\n    } else if ((wsola->options & PJMEDIA_WSOLA_NO_FADING)==0 &&\n\t       wsola->fade_out_pos != wsola->max_expand_cnt) \n    {\n\tunsigned count = wsola->min_extra;\n\tint fade_in_pos;\n\n\t/* Fade out the remaining synthetic samples */\n\tif (buf_len > wsola->hist_size) {\n\t    pj_int16_t *reg1, *reg2;\n\t    unsigned reg1_len, reg2_len;\n\n\t    /* Number of samples to fade out */\n\t    count = buf_len - wsola->hist_size;\n\n\t    pjmedia_circ_buf_get_read_regions(wsola->buf, &reg1, &reg1_len, \n\t\t\t\t\t      &reg2, &reg2_len);\n\n\t    CHECK_(pjmedia_circ_buf_get_len(wsola->buf) >= \n\t\t   (unsigned)(wsola->hist_size + (wsola->min_extra<<1)));\n\n\t    /* Continue applying fade out to the extra samples */\n\t    if (reg2_len == 0) {\n\t\twsola_fade_out(wsola, reg1 + reg1_len - count, count);\n\t    } else if (reg2_len >= count) {\n\t\twsola_fade_out(wsola, reg2 + reg2_len - count, count);\n\t    } else {\n\t\tunsigned tmp = count - reg2_len;\n\t\twsola_fade_out(wsola, reg1 + reg1_len - tmp, tmp);\n\t\twsola_fade_out(wsola, reg2, reg2_len);\n\t    }\n\t}\n\n\t/* Apply fade-in to the frame */\n\tcount = wsola->min_extra;\n\n\t/* Scale fade_in position based on last fade-out */\n\tfade_in_pos = wsola->fade_out_pos * count /\n\t\t      wsola->max_expand_cnt;\n\n\t/* Fade it in */\n\tfade_in(frm, wsola->samples_per_frame,\n\t\tfade_in_pos, count);\n\n    }\n\n    wsola->fade_out_pos = wsola->max_expand_cnt;\n\n    status = pjmedia_circ_buf_write(wsola->buf, frm, wsola->samples_per_frame);\n    if (status != PJ_SUCCESS) {\n\tTRACE_((THIS_FILE, \"Failed writing to circbuf [err=%d]\", status));\n\treturn status;\n    }\n\n    status = pjmedia_circ_buf_copy(wsola->buf, wsola->hist_size, frm, \n\t\t\t\t   wsola->samples_per_frame);\n    if (status != PJ_SUCCESS) {\n\tTRACE_((THIS_FILE, \"Failed copying from circbuf [err=%d]\", status));\n\treturn status;\n    }\n\n    return pjmedia_circ_buf_adv_read_ptr(wsola->buf, wsola->samples_per_frame);\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_wsola_generate( pjmedia_wsola *wsola, \n\t\t\t\t\t    pj_int16_t frm[])\n{\n    unsigned samples_len, samples_req;\n    pj_status_t status = PJ_SUCCESS;\n\n    CHECK_(pjmedia_circ_buf_get_len(wsola->buf) >= wsola->hist_size + \n\t   wsola->min_extra);\n\n    /* Calculate how many samples in the buffer */\n    samples_len = pjmedia_circ_buf_get_len(wsola->buf) - wsola->hist_size;\n\n    /* Calculate how many samples are required to be available in the buffer */\n    samples_req = wsola->samples_per_frame + (wsola->min_extra << 1);\n    \n    wsola->ts.u64 += wsola->samples_per_frame;\n\n    if (samples_len < samples_req) {\n\t/* Expand buffer */\n\texpand(wsola, samples_req - samples_len);\n\tTRACE_((THIS_FILE, \"Buf size after expanded = %d\", \n\t\tpjmedia_circ_buf_get_len(wsola->buf)));\n    }\n\n    status = pjmedia_circ_buf_copy(wsola->buf, wsola->hist_size, frm, \n\t\t\t\t   wsola->samples_per_frame);\n    if (status != PJ_SUCCESS) {\n\tTRACE_((THIS_FILE, \"Failed copying from circbuf [err=%d]\", status));\n\treturn status;\n    }\n\n    pjmedia_circ_buf_adv_read_ptr(wsola->buf, wsola->samples_per_frame);\n\n    /* Apply fade-out to the frame */\n    if ((wsola->options & PJMEDIA_WSOLA_NO_FADING)==0) {\n\twsola_fade_out(wsola, frm, wsola->samples_per_frame);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_wsola_discard( pjmedia_wsola *wsola, \n\t\t\t\t\t   pj_int16_t buf1[],\n\t\t\t\t\t   unsigned buf1_cnt, \n\t\t\t\t\t   pj_int16_t buf2[],\n\t\t\t\t\t   unsigned buf2_cnt,\n\t\t\t\t\t   unsigned *del_cnt)\n{\n    PJ_ASSERT_RETURN(wsola && buf1 && buf1_cnt && del_cnt, PJ_EINVAL);\n    PJ_ASSERT_RETURN(*del_cnt, PJ_EINVAL);\n\n    if (buf2_cnt == 0) {\n\t/* The whole buffer is contiguous space, straight away. */\n\t*del_cnt = compress(wsola, buf1, buf1_cnt, *del_cnt);\n    } else {\n\tPJ_ASSERT_RETURN(buf2, PJ_EINVAL);\n\n\tif (buf1_cnt < ERASE_CNT * wsola->samples_per_frame &&\n\t    buf2_cnt < ERASE_CNT * wsola->samples_per_frame &&\n\t    wsola->erase_buf == NULL)\n\t{\n\t    /* We need erase_buf but WSOLA was created with \n\t     * PJMEDIA_WSOLA_NO_DISCARD flag.\n\t     */\n\t    pj_assert(!\"WSOLA need erase buffer!\");\n\t    return PJ_EINVALIDOP;\n\t}\n\n\tif (buf2_cnt >= ERASE_CNT * wsola->samples_per_frame) {\n\t    /* Enough space to perform compress in the second buffer. */\n\t    *del_cnt = compress(wsola, buf2, buf2_cnt, *del_cnt);\n\t} else if (buf1_cnt >= ERASE_CNT * wsola->samples_per_frame) {\n\t    /* Enough space to perform compress in the first buffer, but then\n\t     * we need to re-arrange the buffers so there is no gap between \n\t     * buffers.\n\t     */\n\t    unsigned max;\n\n\t    *del_cnt = compress(wsola, buf1, buf1_cnt, *del_cnt);\n\n\t    max = *del_cnt;\n\t    if (max > buf2_cnt)\n\t\tmax = buf2_cnt;\n\n\t    pjmedia_move_samples(buf1 + buf1_cnt - (*del_cnt), buf2, max);\n\n\t    if (max < buf2_cnt) {\n\t\tpjmedia_move_samples(buf2, buf2+(*del_cnt), \n\t\t\t\t     buf2_cnt-max);\n\t    }\n\t} else {\n\t    /* Not enough samples in either buffers to perform compress. \n\t     * Need to combine the buffers in a contiguous space, the erase_buf.\n\t     */\n\t    unsigned buf_size = buf1_cnt + buf2_cnt;\n\t    pj_int16_t *rem;\t/* remainder */\n\t    unsigned rem_cnt;\n\n\t    if (buf_size > ERASE_CNT * wsola->samples_per_frame) {\n\t\tbuf_size = ERASE_CNT * wsola->samples_per_frame;\n\t\t\n\t\trem_cnt = buf1_cnt + buf2_cnt - buf_size;\n\t\trem = buf2 + buf2_cnt - rem_cnt;\n\t\t\n\t    } else {\n\t\trem = NULL;\n\t\trem_cnt = 0;\n\t    }\n\n\t    pjmedia_copy_samples(wsola->erase_buf, buf1, buf1_cnt);\n\t    pjmedia_copy_samples(wsola->erase_buf+buf1_cnt, buf2, \n\t\t\t\t buf_size-buf1_cnt);\n\n\t    *del_cnt = compress(wsola, wsola->erase_buf, buf_size, *del_cnt);\n\n\t    buf_size -= (*del_cnt);\n\n\t    /* Copy back to buffers */\n\t    if (buf_size == buf1_cnt) {\n\t\tpjmedia_copy_samples(buf1, wsola->erase_buf, buf_size);\n\t\tif (rem_cnt) {\n\t\t    pjmedia_move_samples(buf2, rem, rem_cnt);\n\t\t}\n\t    } else if (buf_size < buf1_cnt) {\n\t\tpjmedia_copy_samples(buf1, wsola->erase_buf, buf_size);\n\t\tif (rem_cnt) {\n\t\t    unsigned c = rem_cnt;\n\t\t    if (c > buf1_cnt-buf_size) {\n\t\t\tc = buf1_cnt-buf_size;\n\t\t    }\n\t\t    pjmedia_copy_samples(buf1+buf_size, rem, c);\n\t\t    rem += c;\n\t\t    rem_cnt -= c;\n\t\t    if (rem_cnt)\n\t\t\tpjmedia_move_samples(buf2, rem, rem_cnt);\n\t\t}\n\t    } else {\n\t\tpjmedia_copy_samples(buf1, wsola->erase_buf, buf1_cnt);\n\t\tpjmedia_copy_samples(buf2, wsola->erase_buf+buf1_cnt, \n\t\t\t\t     buf_size-buf1_cnt);\n\t\tif (rem_cnt) {\n\t\t    pjmedia_move_samples(buf2+buf_size-buf1_cnt, rem,\n\t\t\t\t         rem_cnt);\n\t\t}\n\t    }\n\t    \n\t}\n    }\n\n    return (*del_cnt) > 0 ? PJ_SUCCESS : PJ_ETOOSMALL;\n}\n\n\n#elif PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_NULL\n/*\n * WSOLA implementation using NULL\n */\n\nstruct pjmedia_wsola\n{\n    unsigned samples_per_frame;\n};\n\n\nPJ_DEF(pj_status_t) pjmedia_wsola_create( pj_pool_t *pool, \n\t\t\t\t\t  unsigned clock_rate,\n\t\t\t\t\t  unsigned samples_per_frame,\n\t\t\t\t\t  unsigned channel_count,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t\t  pjmedia_wsola **p_wsola)\n{\n    pjmedia_wsola *wsola;\n\n    wsola = PJ_POOL_ZALLOC_T(pool, struct pjmedia_wsola);\n    wsola->samples_per_frame = samples_per_frame;\n\n    PJ_UNUSED_ARG(clock_rate);\n    PJ_UNUSED_ARG(channel_count);\n    PJ_UNUSED_ARG(options);\n\n    *p_wsola = wsola;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_wsola_destroy(pjmedia_wsola *wsola)\n{\n    PJ_UNUSED_ARG(wsola);\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_wsola_reset( pjmedia_wsola *wsola,\n\t\t\t\t\t unsigned options)\n{\n    PJ_UNUSED_ARG(wsola);\n    PJ_UNUSED_ARG(options);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_wsola_save( pjmedia_wsola *wsola, \n\t\t\t\t\tpj_int16_t frm[], \n\t\t\t\t\tpj_bool_t prev_lost)\n{\n    PJ_UNUSED_ARG(wsola);\n    PJ_UNUSED_ARG(frm);\n    PJ_UNUSED_ARG(prev_lost);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_wsola_generate( pjmedia_wsola *wsola, \n\t\t\t\t\t    pj_int16_t frm[])\n{\n    pjmedia_zero_samples(frm, wsola->samples_per_frame);\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjmedia_wsola_discard( pjmedia_wsola *wsola, \n\t\t\t\t\t   pj_int16_t buf1[],\n\t\t\t\t\t   unsigned buf1_cnt, \n\t\t\t\t\t   pj_int16_t buf2[],\n\t\t\t\t\t   unsigned buf2_cnt,\n\t\t\t\t\t   unsigned *del_cnt)\n{\n    CHECK_(buf1_cnt + buf2_cnt >= wsola->samples_per_frame);\n\n    PJ_UNUSED_ARG(buf1);\n    PJ_UNUSED_ARG(buf1_cnt);\n    PJ_UNUSED_ARG(buf2);\n    PJ_UNUSED_ARG(buf2_cnt);\n\n    *del_cnt = wsola->samples_per_frame;\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* #if PJMEDIA_WSOLA_IMP.. */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-audiodev/alsa_dev.c",
    "content": "/* $Id: alsa_dev.c 4283 2012-10-12 06:19:32Z ming $ */\n/*\n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2007-2009 Keystream AB and Konftel AB, All rights reserved.\n *                         Author: <dan.aberg@keystream.se>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia_audiodev.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pjmedia/errno.h>\n\n#if defined(PJMEDIA_AUDIO_DEV_HAS_ALSA) && PJMEDIA_AUDIO_DEV_HAS_ALSA\n\n#include <sys/syscall.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <unistd.h>\n#include <sys/select.h>\n#include <pthread.h>\n#include <errno.h>\n#include <alsa/asoundlib.h>\n\n\n#define THIS_FILE \t\t\t\"alsa_dev.c\"\n#define MAX_DEVICES\t\t\t128\n\n/* Set to 1 to enable tracing */\n#if 0\n#\tdefine TRACE_(expr)\t\tPJ_LOG(5,expr)\n#else\n#\tdefine TRACE_(expr)\n#endif\n\n/*\n * Factory prototypes\n */\nstatic pj_status_t alsa_factory_init(pjmedia_aud_dev_factory *f);\nstatic pj_status_t alsa_factory_destroy(pjmedia_aud_dev_factory *f);\nstatic pj_status_t alsa_factory_refresh(pjmedia_aud_dev_factory *f);\nstatic unsigned    alsa_factory_get_dev_count(pjmedia_aud_dev_factory *f);\nstatic pj_status_t alsa_factory_get_dev_info(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_aud_dev_info *info);\nstatic pj_status_t alsa_factory_default_param(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t      unsigned index,\n\t\t\t\t\t      pjmedia_aud_param *param);\nstatic pj_status_t alsa_factory_create_stream(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t      const pjmedia_aud_param *param,\n\t\t\t\t\t      pjmedia_aud_rec_cb rec_cb,\n\t\t\t\t\t      pjmedia_aud_play_cb play_cb,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      pjmedia_aud_stream **p_strm);\nstatic void alsa_factory_set_observer(pjmedia_aud_dev_factory *f,\n                                      pjmedia_aud_dev_change_callback cb);\nstatic int alsa_factory_get_default_rec_dev(pjmedia_aud_dev_factory *f);\nstatic int alsa_factory_get_default_play_dev(pjmedia_aud_dev_factory *f);\n\n\n/*\n * Stream prototypes\n */\nstatic pj_status_t alsa_stream_get_param(pjmedia_aud_stream *strm,\n\t\t\t\t\t pjmedia_aud_param *param);\nstatic pj_status_t alsa_stream_get_cap(pjmedia_aud_stream *strm,\n\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t       void *value);\nstatic pj_status_t alsa_stream_set_cap(pjmedia_aud_stream *strm,\n\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t       const void *value);\nstatic pj_status_t alsa_stream_start(pjmedia_aud_stream *strm);\nstatic pj_status_t alsa_stream_stop(pjmedia_aud_stream *strm);\nstatic pj_status_t alsa_stream_destroy(pjmedia_aud_stream *strm);\n\n\n/* alsa device info */\nstruct alsa_dev_info\n{\n    pjmedia_aud_dev_info\t info;\n    char alsa_name[64];\n};\n\nstruct alsa_factory\n{\n    pjmedia_aud_dev_factory\t base;\n    pj_pool_factory\t\t*pf;\n    pj_pool_t\t\t\t*pool;\n    pj_pool_t\t\t\t*base_pool;\n\n    unsigned\t\t\t dev_cnt;\n    struct alsa_dev_info\t devs[MAX_DEVICES];\n};\n\nstruct alsa_stream\n{\n    pjmedia_aud_stream\t base;\n\n    /* Common */\n    pj_pool_t\t\t*pool;\n    struct alsa_factory *af;\n    void\t\t*user_data;\n    pjmedia_aud_param\t param;\t\t/* Running parameter \t\t*/\n    int                  rec_id;      \t/* Capture device id\t\t*/\n    int                  quit;\n\n    /* Playback */\n    snd_pcm_t\t\t*pb_pcm;\n    snd_pcm_uframes_t    pb_frames; \t/* samples_per_frame\t\t*/\n    pjmedia_aud_play_cb  pb_cb;\n    unsigned             pb_buf_size;\n    char\t\t*pb_buf;\n    pj_thread_t\t\t*pb_thread;\n\n    /* Capture */\n    snd_pcm_t\t\t*ca_pcm;\n    snd_pcm_uframes_t    ca_frames; \t/* samples_per_frame\t\t*/\n    pjmedia_aud_rec_cb   ca_cb;\n    unsigned             ca_buf_size;\n    char\t\t*ca_buf;\n    pj_thread_t\t\t*ca_thread;\n};\n\nstatic pjmedia_aud_dev_factory_op alsa_factory_op =\n{\n    &alsa_factory_init,\n    &alsa_factory_destroy,\n    &alsa_factory_get_dev_count,\n    &alsa_factory_get_dev_info,\n    &alsa_factory_default_param,\n    &alsa_factory_create_stream,\n    &alsa_factory_refresh,\n    &alsa_factory_set_observer,\n    &alsa_factory_get_default_rec_dev,\n    &alsa_factory_get_default_play_dev\n};\n\nstatic pjmedia_aud_stream_op alsa_stream_op =\n{\n    &alsa_stream_get_param,\n    &alsa_stream_get_cap,\n    &alsa_stream_set_cap,\n    &alsa_stream_start,\n    &alsa_stream_stop,\n    &alsa_stream_destroy\n};\n\nstatic void null_alsa_error_handler (const char *file,\n\t\t\t\tint line,\n\t\t\t\tconst char *function,\n\t\t\t\tint err,\n\t\t\t\tconst char *fmt,\n\t\t\t\t...)\n{\n    PJ_UNUSED_ARG(file);\n    PJ_UNUSED_ARG(line);\n    PJ_UNUSED_ARG(function);\n    PJ_UNUSED_ARG(err);\n    PJ_UNUSED_ARG(fmt);\n}\n\nstatic void alsa_error_handler (const char *file,\n\t\t\t\tint line,\n\t\t\t\tconst char *function,\n\t\t\t\tint err,\n\t\t\t\tconst char *fmt,\n\t\t\t\t...)\n{\n    char err_msg[128];\n    int index, len;\n    va_list arg;\n\n#ifndef NDEBUG\n    index = snprintf (err_msg, sizeof(err_msg), \"ALSA lib %s:%i:(%s) \",\n\t\t      file, line, function);\n#else\n    index = snprintf (err_msg, sizeof(err_msg), \"ALSA lib: \");\n#endif\n    if (index < 1 || index >= (int)sizeof(err_msg)) {\n\tindex = sizeof(err_msg)-1;\n\terr_msg[index] = '\\0';\n\tgoto print_msg;\n    }\n\n    va_start (arg, fmt);\n    if (index < sizeof(err_msg)-1) {\n\tlen = vsnprintf( err_msg+index, sizeof(err_msg)-index, fmt, arg);\n\tif (len < 1 || len >= (int)sizeof(err_msg)-index)\n\t    len = sizeof(err_msg)-index-1;\n\tindex += len;\n\terr_msg[index] = '\\0';\n    }\n    va_end(arg);\n    if (err && index < sizeof(err_msg)-1) {\n\tlen = snprintf( err_msg+index, sizeof(err_msg)-index, \": %s\",\n\t\t\tsnd_strerror(err));\n\tif (len < 1 || len >= (int)sizeof(err_msg)-index)\n\t    len = sizeof(err_msg)-index-1;\n\tindex += len;\n\terr_msg[index] = '\\0';\n    }\nprint_msg:\n    PJ_LOG (4,(THIS_FILE, \"%s\", err_msg));\n}\n\n\nstatic pj_status_t add_dev (struct alsa_factory *af, const char *dev_name, const char *dev_desc)\n{\n    struct alsa_dev_info *adi;\n    snd_pcm_t* pcm;\n    int pb_result, ca_result;\n\n    if (af->dev_cnt >= PJ_ARRAY_SIZE(af->devs))\n\treturn PJ_ETOOMANY;\n\n    adi = &af->devs[af->dev_cnt];\n\n    TRACE_((THIS_FILE, \"add_dev (%s): Enter\", dev_name));\n\n    /* Try to open the device in playback mode */\n    pb_result = snd_pcm_open (&pcm, dev_name, SND_PCM_STREAM_PLAYBACK, 0);\n    if (pb_result >= 0) {\n\tTRACE_((THIS_FILE, \"Try to open the device for playback - success\"));\n\tsnd_pcm_close (pcm);\n    } else {\n\tTRACE_((THIS_FILE, \"Try to open the device for playback - failure\"));\n    }\n\n    /* Try to open the device in capture mode */\n    ca_result = snd_pcm_open (&pcm, dev_name, SND_PCM_STREAM_CAPTURE, 0);\n    if (ca_result >= 0) {\n\tTRACE_((THIS_FILE, \"Try to open the device for capture - success\"));\n\tsnd_pcm_close (pcm);\n    } else {\n\tTRACE_((THIS_FILE, \"Try to open the device for capture - failure\"));\n    }\n\n    /* Check if the device could be opened in playback or capture mode */\n    if (pb_result<0 && ca_result<0) {\n\tTRACE_((THIS_FILE, \"Unable to open sound device %s\", dev_name));\n\treturn PJMEDIA_EAUD_NODEV;\n    }\n\n    /* Reset device info */\n    pj_bzero(adi, sizeof(*adi));\n\n    /* Set device name */\n    strncpy(adi->alsa_name, dev_name, sizeof(adi->alsa_name));\n\n    /* Set comprehensive device name */\n    int name_size = sizeof(adi->info.name);\n    if (dev_desc) {\n        pj_bool_t name_set = PJ_FALSE;\n\tif (strncmp(\"sysdefault\", dev_name, 10) == 0) {\n\t    /* Only use first line for default device*/\n\t    char *ptr = strstr(dev_desc, \"\\n\");\n\t    if (ptr) {\n\t        int len = ptr - dev_desc;\n                strncpy(adi->info.name, dev_desc, (len >= name_size-1)?name_size:len);\n                name_set = PJ_TRUE;\n            }\n        } else if (strncmp(\"iec958\", dev_name, 6) == 0) {\n            /* Mangle name for SPDIF devices*/\n\t    char *ptr = strstr(dev_desc, \",\");\n\t    if (ptr) {\n\t        int len = ptr - dev_desc;\n\t        if (len + 18 < name_size) {\n                    strncpy(adi->info.name, dev_desc, len);\n                    strncpy(adi->info.name+len, \", Digital (S/PDIF)\", 18);\n                    name_set = PJ_TRUE;\n                }\n            }\n        }\n\n        if (!name_set) {\n            /* Use the entire description for other device names */\n            int i = 0;\n            while (i < name_size-1 && dev_desc[i] != '\\0') {\n                if (dev_desc[i] == '\\n' || dev_desc[i] == '\\r')\n                    adi->info.name[i] = ' ';\n                else\n                    adi->info.name[i] = dev_desc[i];\n                i++;\n            }\n        }\n    } else {\n        strncpy(adi->info.name, dev_name, name_size);\n    }\n\n    /* Check the number of playback channels */\n    adi->info.output_count = (pb_result>=0) ? 1 : 0;\n\n    /* Check the number of capture channels */\n    adi->info.input_count = (ca_result>=0) ? 1 : 0;\n\n    /* Set the default sample rate */\n    adi->info.default_samples_per_sec = 8000;\n\n    /* Driver name */\n    strcpy(adi->info.driver, \"ALSA\");\n\n    ++af->dev_cnt;\n\n    PJ_LOG (5,(THIS_FILE, \"Added sound device %s\", adi->alsa_name));\n\n    return PJ_SUCCESS;\n}\n\n\n/* Create ALSA audio driver. */\npjmedia_aud_dev_factory* pjmedia_alsa_factory(pj_pool_factory *pf)\n{\n    struct alsa_factory *af;\n    pj_pool_t *pool;\n\n    pool = pj_pool_create(pf, \"alsa_aud_base\", 256, 256, NULL);\n    af = PJ_POOL_ZALLOC_T(pool, struct alsa_factory);\n    af->pf = pf;\n    af->base_pool = pool;\n    af->base.op = &alsa_factory_op;\n\n    return &af->base;\n}\n\n\n/* API: init factory */\nstatic pj_status_t alsa_factory_init(pjmedia_aud_dev_factory *f)\n{\n    pj_status_t status = alsa_factory_refresh(f);\n    if (PJ_SUCCESS != status)\n\treturn status;\n\n    PJ_LOG(4,(THIS_FILE, \"ALSA initialized\"));\n    return PJ_SUCCESS;\n}\n\n\n/* API: destroy factory */\nstatic pj_status_t alsa_factory_destroy(pjmedia_aud_dev_factory *f)\n{\n    struct alsa_factory *af = (struct alsa_factory*)f;\n\n    if (af->pool)\n\tpj_pool_release(af->pool);\n\n    if (af->base_pool) {\n\tpj_pool_t *pool = af->base_pool;\n\taf->base_pool = NULL;\n\tpj_pool_release(pool);\n    }\n\n    /* Restore handler */\n    snd_lib_error_set_handler(NULL);\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: refresh the device list */\nstatic pj_status_t alsa_factory_refresh(pjmedia_aud_dev_factory *f)\n{\n    struct alsa_factory *af = (struct alsa_factory*)f;\n    char **hints, **n;\n    int err;\n\n    TRACE_((THIS_FILE, \"pjmedia_snd_init: Enumerate sound devices\"));\n\n    if (af->pool != NULL) {\n\tpj_pool_release(af->pool);\n\taf->pool = NULL;\n    }\n\n    af->pool = pj_pool_create(af->pf, \"alsa_aud\", 256, 256, NULL);\n    af->dev_cnt = 0;\n\n    /* Enumerate sound devices */\n    err = snd_device_name_hint(-1, \"pcm\", (void***)&hints);\n    if (err != 0)\n\treturn PJMEDIA_EAUD_SYSERR;\n\n    /* Set a null error handler prior to enumeration to suppress errors */\n    snd_lib_error_set_handler(null_alsa_error_handler);\n\n    n = hints;\n    while (*n != NULL) {\n\tchar *name = snd_device_name_get_hint(*n, \"NAME\");\n\tchar *desc = snd_device_name_get_hint(*n, \"DESC\");\n\tif (name != NULL) {\n\t    if (strncmp(\"null\", name, 4) == 0 ||\n                strncmp(\"front\", name, 5) == 0 ||\n                strncmp(\"rear\", name, 4) == 0 ||\n                strncmp(\"side\", name, 4) == 0 ||\n                strncmp(\"dmix\", name, 4) == 0 ||\n                strncmp(\"dsnoop\", name, 6) == 0 ||\n                strncmp(\"hw\", name, 2) == 0 ||\n                strncmp(\"plughw\", name, 6) == 0 ||\n                strncmp(\"center_lfe\", name, 10) == 0 ||\n\t        strncmp(\"surround\", name, 8) == 0 ||\n\t        (strncmp(\"default\", name, 7) == 0 && strstr(name, \":CARD=\") != NULL)) {\n\t        /* skip these devices, 'sysdefault' always contains the relevant information */\n\t        ;\n\t    } else {\n\t        add_dev(af, name, desc);\n\t    }\n\t    free(name);\n\t    free(desc);\n\t}\n\tn++;\n    }\n\n    /* Install error handler after enumeration, otherwise we'll get many\n     * error messages about invalid card/device ID.\n     */\n    snd_lib_error_set_handler(alsa_error_handler);\n\n    err = snd_device_name_free_hint((void**)hints);\n\n    PJ_LOG(4,(THIS_FILE, \"ALSA driver found %d devices\", af->dev_cnt));\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: get device count */\nstatic unsigned  alsa_factory_get_dev_count(pjmedia_aud_dev_factory *f)\n{\n    struct alsa_factory *af = (struct alsa_factory*)f;\n    return af->dev_cnt;\n}\n\n\n/* API: get device info */\nstatic pj_status_t alsa_factory_get_dev_info(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_aud_dev_info *info)\n{\n    struct alsa_factory *af = (struct alsa_factory*)f;\n\n    PJ_ASSERT_RETURN(index>=0 && index<af->dev_cnt, PJ_EINVAL);\n\n    pj_memcpy(info, &af->devs[index].info, sizeof(*info));\n    info->caps = PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY |\n\t\t PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;\n    return PJ_SUCCESS;\n}\n\n/* API: create default parameter */\nstatic pj_status_t alsa_factory_default_param(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t      unsigned index,\n\t\t\t\t\t      pjmedia_aud_param *param)\n{\n    struct alsa_factory *af = (struct alsa_factory*)f;\n    struct alsa_dev_info *adi;\n\n    PJ_ASSERT_RETURN(index>=0 && index<af->dev_cnt, PJ_EINVAL);\n\n    adi = &af->devs[index];\n\n    pj_bzero(param, sizeof(*param));\n    if (adi->info.input_count && adi->info.output_count) {\n\tparam->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;\n\tparam->rec_id = index;\n\tparam->play_id = index;\n    } else if (adi->info.input_count) {\n\tparam->dir = PJMEDIA_DIR_CAPTURE;\n\tparam->rec_id = index;\n\tparam->play_id = PJMEDIA_AUD_INVALID_DEV;\n    } else if (adi->info.output_count) {\n\tparam->dir = PJMEDIA_DIR_PLAYBACK;\n\tparam->play_id = index;\n\tparam->rec_id = PJMEDIA_AUD_INVALID_DEV;\n    } else {\n\treturn PJMEDIA_EAUD_INVDEV;\n    }\n\n    param->clock_rate = adi->info.default_samples_per_sec;\n    param->channel_count = 1;\n    param->samples_per_frame = adi->info.default_samples_per_sec * 20 / 1000;\n    param->bits_per_sample = 16;\n    param->flags = adi->info.caps;\n    param->input_latency_ms = PJMEDIA_SND_DEFAULT_REC_LATENCY;\n    param->output_latency_ms = PJMEDIA_SND_DEFAULT_PLAY_LATENCY;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic int pb_thread_func (void *arg)\n{\n    struct alsa_stream* stream = (struct alsa_stream*) arg;\n    snd_pcm_t* pcm             = stream->pb_pcm;\n    int size                   = stream->pb_buf_size;\n    snd_pcm_uframes_t nframes  = stream->pb_frames;\n    void* user_data            = stream->user_data;\n    char* buf \t\t       = stream->pb_buf;\n    pj_timestamp tstamp;\n    int result;\n\n    pj_bzero (buf, size);\n    tstamp.u64 = 0;\n\n    TRACE_((THIS_FILE, \"pb_thread_func(%u): Started\",\n\t    (unsigned)syscall(SYS_gettid)));\n\n    snd_pcm_prepare (pcm);\n\n    while (!stream->quit) {\n\tpjmedia_frame frame;\n\n\tframe.type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframe.buf = buf;\n\tframe.size = size;\n\tframe.timestamp.u64 = tstamp.u64;\n\tframe.bit_info = 0;\n\n\tresult = stream->pb_cb (user_data, &frame);\n\tif (result != PJ_SUCCESS || stream->quit)\n\t    break;\n\n\tif (frame.type != PJMEDIA_FRAME_TYPE_AUDIO)\n\t    pj_bzero (buf, size);\n\n\tresult = snd_pcm_writei (pcm, buf, nframes);\n\tif (result == -EPIPE) {\n\t    PJ_LOG (4,(THIS_FILE, \"pb_thread_func: underrun!\"));\n\t    snd_pcm_prepare (pcm);\n\t} else if (result < 0) {\n\t    PJ_LOG (4,(THIS_FILE, \"pb_thread_func: error writing data!\"));\n\t}\n\n\ttstamp.u64 += nframes;\n    }\n\n    snd_pcm_drain (pcm);\n    TRACE_((THIS_FILE, \"pb_thread_func: Stopped\"));\n    return PJ_SUCCESS;\n}\n\n\n\nstatic int ca_thread_func (void *arg)\n{\n    struct alsa_stream* stream = (struct alsa_stream*) arg;\n    snd_pcm_t* pcm             = stream->ca_pcm;\n    int size                   = stream->ca_buf_size;\n    snd_pcm_uframes_t nframes  = stream->ca_frames;\n    void* user_data            = stream->user_data;\n    char* buf \t\t       = stream->ca_buf;\n    pj_timestamp tstamp;\n    int result;\n    struct sched_param param;\n    pthread_t* thid;\n\n    thid = (pthread_t*) pj_thread_get_os_handle (pj_thread_this());\n    param.sched_priority = sched_get_priority_max (SCHED_RR);\n    PJ_LOG (5,(THIS_FILE, \"ca_thread_func(%u): Set thread priority \"\n\t\t          \"for audio capture thread.\",\n\t\t          (unsigned)syscall(SYS_gettid)));\n    result = pthread_setschedparam (*thid, SCHED_RR, &param);\n    if (result) {\n\tif (result == EPERM)\n\t    PJ_LOG (5,(THIS_FILE, \"Unable to increase thread priority, \"\n\t\t\t\t  \"root access needed.\"));\n\telse\n\t    PJ_LOG (5,(THIS_FILE, \"Unable to increase thread priority, \"\n\t\t\t\t  \"error: %d\",\n\t\t\t\t  result));\n    }\n\n    pj_bzero (buf, size);\n    tstamp.u64 = 0;\n\n    TRACE_((THIS_FILE, \"ca_thread_func(%u): Started\",\n\t    (unsigned)syscall(SYS_gettid)));\n\n    snd_pcm_prepare (pcm);\n\n    while (!stream->quit) {\n\tpjmedia_frame frame;\n\n\tpj_bzero (buf, size);\n\tresult = snd_pcm_readi (pcm, buf, nframes);\n\tif (result == -EPIPE) {\n\t    PJ_LOG (4,(THIS_FILE, \"ca_thread_func: overrun!\"));\n\t    snd_pcm_prepare (pcm);\n\t    continue;\n\t} else if (result < 0) {\n\t    PJ_LOG (4,(THIS_FILE, \"ca_thread_func: error reading data!\"));\n\t}\n\tif (stream->quit)\n\t    break;\n\n\tframe.type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframe.buf = (void*) buf;\n\tframe.size = size;\n\tframe.timestamp.u64 = tstamp.u64;\n\tframe.bit_info = 0;\n\n\tresult = stream->ca_cb (user_data, &frame);\n\tif (result != PJ_SUCCESS || stream->quit)\n\t    break;\n\n\ttstamp.u64 += nframes;\n    }\n    snd_pcm_drop (pcm);\n    TRACE_((THIS_FILE, \"ca_thread_func: Stopped\"));\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t open_playback (struct alsa_stream* stream,\n\t\t\t          const pjmedia_aud_param *param)\n{\n    snd_pcm_hw_params_t* params;\n    snd_pcm_format_t format;\n    int result;\n    unsigned int rate;\n    snd_pcm_uframes_t tmp_buf_size;\n    snd_pcm_uframes_t tmp_period_size;\n\n    if (param->play_id < 0 || param->play_id >= stream->af->dev_cnt)\n\treturn PJMEDIA_EAUD_INVDEV;\n\n    /* Open PCM for playback */\n    PJ_LOG (5,(THIS_FILE, \"open_playback: Open playback device '%s'\",\n\t       stream->af->devs[param->play_id].alsa_name));\n    result = snd_pcm_open (&stream->pb_pcm,\n\t\t\t   stream->af->devs[param->play_id].alsa_name,\n\t\t\t   SND_PCM_STREAM_PLAYBACK,\n\t\t\t   0);\n    if (result < 0)\n\treturn PJMEDIA_EAUD_SYSERR;\n\n    /* Allocate a hardware parameters object. */\n    snd_pcm_hw_params_alloca (&params);\n\n    /* Fill it in with default values. */\n    snd_pcm_hw_params_any (stream->pb_pcm, params);\n\n    /* Set interleaved mode */\n    snd_pcm_hw_params_set_access (stream->pb_pcm, params,\n\t\t\t\t  SND_PCM_ACCESS_RW_INTERLEAVED);\n\n    /* Set format */\n    switch (param->bits_per_sample) {\n    case 8:\n\tTRACE_((THIS_FILE, \"open_playback: set format SND_PCM_FORMAT_S8\"));\n\tformat = SND_PCM_FORMAT_S8;\n\tbreak;\n    case 16:\n\tTRACE_((THIS_FILE, \"open_playback: set format SND_PCM_FORMAT_S16_LE\"));\n\tformat = SND_PCM_FORMAT_S16_LE;\n\tbreak;\n    case 24:\n\tTRACE_((THIS_FILE, \"open_playback: set format SND_PCM_FORMAT_S24_LE\"));\n\tformat = SND_PCM_FORMAT_S24_LE;\n\tbreak;\n    case 32:\n\tTRACE_((THIS_FILE, \"open_playback: set format SND_PCM_FORMAT_S32_LE\"));\n\tformat = SND_PCM_FORMAT_S32_LE;\n\tbreak;\n    default:\n\tTRACE_((THIS_FILE, \"open_playback: set format SND_PCM_FORMAT_S16_LE\"));\n\tformat = SND_PCM_FORMAT_S16_LE;\n\tbreak;\n    }\n    snd_pcm_hw_params_set_format (stream->pb_pcm, params, format);\n\n    /* Set number of channels */\n    TRACE_((THIS_FILE, \"open_playback: set channels: %d\",\n\t\t       param->channel_count));\n    snd_pcm_hw_params_set_channels (stream->pb_pcm, params,\n\t\t\t\t    param->channel_count);\n\n    /* Set clock rate */\n    rate = param->clock_rate;\n    TRACE_((THIS_FILE, \"open_playback: set clock rate: %d\", rate));\n    snd_pcm_hw_params_set_rate_near (stream->pb_pcm, params, &rate, NULL);\n    TRACE_((THIS_FILE, \"open_playback: clock rate set to: %d\", rate));\n\n    /* Set period size to samples_per_frame frames. */\n    stream->pb_frames = (snd_pcm_uframes_t) param->samples_per_frame /\n\t\t\t\t\t    param->channel_count;\n    TRACE_((THIS_FILE, \"open_playback: set period size: %d\",\n\t    stream->pb_frames));\n    tmp_period_size = stream->pb_frames;\n    snd_pcm_hw_params_set_period_size_near (stream->pb_pcm, params,\n\t\t\t\t\t    &tmp_period_size, NULL);\n    TRACE_((THIS_FILE, \"open_playback: period size set to: %d\",\n\t    tmp_period_size));\n\n    /* Set the sound device buffer size and latency */\n    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY)\n\ttmp_buf_size = (rate / 1000) * param->output_latency_ms;\n    else\n\ttmp_buf_size = (rate / 1000) * PJMEDIA_SND_DEFAULT_PLAY_LATENCY;\n    snd_pcm_hw_params_set_buffer_size_near (stream->pb_pcm, params,\n\t\t\t\t\t    &tmp_buf_size);\n    stream->param.output_latency_ms = tmp_buf_size / (rate / 1000);\n\n    /* Set our buffer */\n    stream->pb_buf_size = stream->pb_frames * param->channel_count *\n\t\t\t  (param->bits_per_sample/8);\n    stream->pb_buf = (char*) pj_pool_alloc(stream->pool, stream->pb_buf_size);\n\n    TRACE_((THIS_FILE, \"open_playback: buffer size set to: %d\",\n\t    (int)tmp_buf_size));\n    TRACE_((THIS_FILE, \"open_playback: playback_latency set to: %d ms\",\n\t    (int)stream->param.output_latency_ms));\n\n    /* Activate the parameters */\n    result = snd_pcm_hw_params (stream->pb_pcm, params);\n    if (result < 0) {\n\tsnd_pcm_close (stream->pb_pcm);\n\treturn PJMEDIA_EAUD_SYSERR;\n    }\n\n    PJ_LOG (5,(THIS_FILE, \"Opened device alsa(%s) for playing, sample rate=%d\"\n\t       \", ch=%d, bits=%d, period size=%d frames, latency=%d ms\",\n\t       stream->af->devs[param->play_id].alsa_name,\n\t       rate, param->channel_count,\n\t       param->bits_per_sample, stream->pb_frames,\n\t       (int)stream->param.output_latency_ms));\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t open_capture (struct alsa_stream* stream,\n\t\t\t         const pjmedia_aud_param *param)\n{\n    snd_pcm_hw_params_t* params;\n    snd_pcm_format_t format;\n    int result;\n    unsigned int rate;\n    snd_pcm_uframes_t tmp_buf_size;\n    snd_pcm_uframes_t tmp_period_size;\n\n    if (param->rec_id < 0 || param->rec_id >= stream->af->dev_cnt)\n\treturn PJMEDIA_EAUD_INVDEV;\n\n    /* Open PCM for capture */\n    PJ_LOG (5,(THIS_FILE, \"open_capture: Open capture device '%s'\",\n\t       stream->af->devs[param->rec_id].alsa_name));\n    result = snd_pcm_open (&stream->ca_pcm,\n\t\t            stream->af->devs[param->rec_id].alsa_name,\n\t\t\t   SND_PCM_STREAM_CAPTURE,\n\t\t\t   0);\n    if (result < 0)\n\treturn PJMEDIA_EAUD_SYSERR;\n\n    /* Allocate a hardware parameters object. */\n    snd_pcm_hw_params_alloca (&params);\n\n    /* Fill it in with default values. */\n    snd_pcm_hw_params_any (stream->ca_pcm, params);\n\n    /* Set interleaved mode */\n    snd_pcm_hw_params_set_access (stream->ca_pcm, params,\n\t\t\t\t  SND_PCM_ACCESS_RW_INTERLEAVED);\n\n    /* Set format */\n    switch (param->bits_per_sample) {\n    case 8:\n\tTRACE_((THIS_FILE, \"open_capture: set format SND_PCM_FORMAT_S8\"));\n\tformat = SND_PCM_FORMAT_S8;\n\tbreak;\n    case 16:\n\tTRACE_((THIS_FILE, \"open_capture: set format SND_PCM_FORMAT_S16_LE\"));\n\tformat = SND_PCM_FORMAT_S16_LE;\n\tbreak;\n    case 24:\n\tTRACE_((THIS_FILE, \"open_capture: set format SND_PCM_FORMAT_S24_LE\"));\n\tformat = SND_PCM_FORMAT_S24_LE;\n\tbreak;\n    case 32:\n\tTRACE_((THIS_FILE, \"open_capture: set format SND_PCM_FORMAT_S32_LE\"));\n\tformat = SND_PCM_FORMAT_S32_LE;\n\tbreak;\n    default:\n\tTRACE_((THIS_FILE, \"open_capture: set format SND_PCM_FORMAT_S16_LE\"));\n\tformat = SND_PCM_FORMAT_S16_LE;\n\tbreak;\n    }\n    snd_pcm_hw_params_set_format (stream->ca_pcm, params, format);\n\n    /* Set number of channels */\n    TRACE_((THIS_FILE, \"open_capture: set channels: %d\",\n\t    param->channel_count));\n    snd_pcm_hw_params_set_channels (stream->ca_pcm, params,\n\t\t\t\t    param->channel_count);\n\n    /* Set clock rate */\n    rate = param->clock_rate;\n    TRACE_((THIS_FILE, \"open_capture: set clock rate: %d\", rate));\n    snd_pcm_hw_params_set_rate_near (stream->ca_pcm, params, &rate, NULL);\n    TRACE_((THIS_FILE, \"open_capture: clock rate set to: %d\", rate));\n\n    /* Set period size to samples_per_frame frames. */\n    stream->ca_frames = (snd_pcm_uframes_t) param->samples_per_frame /\n\t\t\t\t\t    param->channel_count;\n    TRACE_((THIS_FILE, \"open_capture: set period size: %d\",\n\t    stream->ca_frames));\n    tmp_period_size = stream->ca_frames;\n    snd_pcm_hw_params_set_period_size_near (stream->ca_pcm, params,\n\t\t\t\t\t    &tmp_period_size, NULL);\n    TRACE_((THIS_FILE, \"open_capture: period size set to: %d\",\n\t    tmp_period_size));\n\n    /* Set the sound device buffer size and latency */\n    if (param->flags & PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY)\n\ttmp_buf_size = (rate / 1000) * param->input_latency_ms;\n    else\n\ttmp_buf_size = (rate / 1000) * PJMEDIA_SND_DEFAULT_REC_LATENCY;\n    snd_pcm_hw_params_set_buffer_size_near (stream->ca_pcm, params,\n\t\t\t\t\t    &tmp_buf_size);\n    stream->param.input_latency_ms = tmp_buf_size / (rate / 1000);\n\n    /* Set our buffer */\n    stream->ca_buf_size = stream->ca_frames * param->channel_count *\n\t\t\t  (param->bits_per_sample/8);\n    stream->ca_buf = (char*) pj_pool_alloc (stream->pool, stream->ca_buf_size);\n\n    TRACE_((THIS_FILE, \"open_capture: buffer size set to: %d\",\n\t    (int)tmp_buf_size));\n    TRACE_((THIS_FILE, \"open_capture: capture_latency set to: %d ms\",\n\t    (int)stream->param.input_latency_ms));\n\n    /* Activate the parameters */\n    result = snd_pcm_hw_params (stream->ca_pcm, params);\n    if (result < 0) {\n\tsnd_pcm_close (stream->ca_pcm);\n\treturn PJMEDIA_EAUD_SYSERR;\n    }\n\n    PJ_LOG (5,(THIS_FILE, \"Opened device alsa(%s) for capture, sample rate=%d\"\n\t       \", ch=%d, bits=%d, period size=%d frames, latency=%d ms\",\n\t       stream->af->devs[param->rec_id].alsa_name,\n\t       rate, param->channel_count,\n\t       param->bits_per_sample, stream->ca_frames,\n\t       (int)stream->param.input_latency_ms));\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: create stream */\nstatic pj_status_t alsa_factory_create_stream(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t      const pjmedia_aud_param *param,\n\t\t\t\t\t      pjmedia_aud_rec_cb rec_cb,\n\t\t\t\t\t      pjmedia_aud_play_cb play_cb,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      pjmedia_aud_stream **p_strm)\n{\n    struct alsa_factory *af = (struct alsa_factory*)f;\n    pj_status_t status;\n    pj_pool_t* pool;\n    struct alsa_stream* stream;\n\n    pool = pj_pool_create (af->pf, \"alsa%p\", 1024, 1024, NULL);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    /* Allocate and initialize comon stream data */\n    stream = PJ_POOL_ZALLOC_T (pool, struct alsa_stream);\n    stream->base.op = &alsa_stream_op;\n    stream->pool      = pool;\n    stream->af \t      = af;\n    stream->user_data = user_data;\n    stream->pb_cb     = play_cb;\n    stream->ca_cb     = rec_cb;\n    stream->quit      = 0;\n    pj_memcpy(&stream->param, param, sizeof(*param));\n\n    /* Init playback */\n    if (param->dir & PJMEDIA_DIR_PLAYBACK) {\n\tstatus = open_playback (stream, param);\n\tif (status != PJ_SUCCESS) {\n\t    pj_pool_release (pool);\n\t    return status;\n\t}\n    }\n\n    /* Init capture */\n    if (param->dir & PJMEDIA_DIR_CAPTURE) {\n\tstatus = open_capture (stream, param);\n\tif (status != PJ_SUCCESS) {\n\t    if (param->dir & PJMEDIA_DIR_PLAYBACK)\n\t\tsnd_pcm_close (stream->pb_pcm);\n\t    pj_pool_release (pool);\n\t    return status;\n\t}\n    }\n\n    *p_strm = &stream->base;\n    return PJ_SUCCESS;\n}\n\n\n/* API: set audio device change observer */\nstatic void alsa_factory_set_observer(pjmedia_aud_dev_factory *f,\n                                      pjmedia_aud_dev_change_callback cb)\n{\n    PJ_UNUSED_ARG(f);\n    PJ_UNUSED_ARG(cb);\n}\n\n/* API: get default recording device */\nstatic int alsa_factory_get_default_rec_dev(pjmedia_aud_dev_factory *f)\n{\n    PJ_UNUSED_ARG(f);\n    return -1;\n}\n\n/* API: get default playback device */\nstatic int alsa_factory_get_default_play_dev(pjmedia_aud_dev_factory *f)\n{\n    PJ_UNUSED_ARG(f);\n    return -1;\n}\n\n/* API: get running parameter */\nstatic pj_status_t alsa_stream_get_param(pjmedia_aud_stream *s,\n\t\t\t\t\t pjmedia_aud_param *pi)\n{\n    struct alsa_stream *stream = (struct alsa_stream*)s;\n\n    PJ_ASSERT_RETURN(s && pi, PJ_EINVAL);\n\n    pj_memcpy(pi, &stream->param, sizeof(*pi));\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: get capability */\nstatic pj_status_t alsa_stream_get_cap(pjmedia_aud_stream *s,\n\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t       void *pval)\n{\n    struct alsa_stream *stream = (struct alsa_stream*)s;\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    if (cap==PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY &&\n\t(stream->param.dir & PJMEDIA_DIR_CAPTURE))\n    {\n\t/* Recording latency */\n\t*(unsigned*)pval = stream->param.input_latency_ms;\n\treturn PJ_SUCCESS;\n    } else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY &&\n\t       (stream->param.dir & PJMEDIA_DIR_PLAYBACK))\n    {\n\t/* Playback latency */\n\t*(unsigned*)pval = stream->param.output_latency_ms;\n\treturn PJ_SUCCESS;\n    } else {\n\treturn PJMEDIA_EAUD_INVCAP;\n    }\n}\n\n\n/* API: set capability */\nstatic pj_status_t alsa_stream_set_cap(pjmedia_aud_stream *strm,\n\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t       const void *value)\n{\n    PJ_UNUSED_ARG(strm);\n    PJ_UNUSED_ARG(cap);\n    PJ_UNUSED_ARG(value);\n\n    return PJMEDIA_EAUD_INVCAP;\n}\n\n\n/* API: start stream */\nstatic pj_status_t alsa_stream_start (pjmedia_aud_stream *s)\n{\n    struct alsa_stream *stream = (struct alsa_stream*)s;\n    pj_status_t status = PJ_SUCCESS;\n\n    stream->quit = 0;\n    if (stream->param.dir & PJMEDIA_DIR_PLAYBACK) {\n\tstatus = pj_thread_create (stream->pool,\n\t\t\t\t   \"alsasound_playback\",\n\t\t\t\t   pb_thread_func,\n\t\t\t\t   stream,\n\t\t\t\t   0, //ZERO,\n\t\t\t\t   0,\n\t\t\t\t   &stream->pb_thread);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    if (stream->param.dir & PJMEDIA_DIR_CAPTURE) {\n\tstatus = pj_thread_create (stream->pool,\n\t\t\t\t   \"alsasound_playback\",\n\t\t\t\t   ca_thread_func,\n\t\t\t\t   stream,\n\t\t\t\t   0, //ZERO,\n\t\t\t\t   0,\n\t\t\t\t   &stream->ca_thread);\n\tif (status != PJ_SUCCESS) {\n\t    stream->quit = PJ_TRUE;\n\t    pj_thread_join(stream->pb_thread);\n\t    pj_thread_destroy(stream->pb_thread);\n\t    stream->pb_thread = NULL;\n\t}\n    }\n\n    return status;\n}\n\n\n/* API: stop stream */\nstatic pj_status_t alsa_stream_stop (pjmedia_aud_stream *s)\n{\n    struct alsa_stream *stream = (struct alsa_stream*)s;\n\n    stream->quit = 1;\n\n    if (stream->pb_thread) {\n\tTRACE_((THIS_FILE,\n\t\t   \"alsa_stream_stop(%u): Waiting for playback to stop.\",\n\t\t   (unsigned)syscall(SYS_gettid)));\n\tpj_thread_join (stream->pb_thread);\n\tTRACE_((THIS_FILE,\n\t\t   \"alsa_stream_stop(%u): playback stopped.\",\n\t\t   (unsigned)syscall(SYS_gettid)));\n\tpj_thread_destroy(stream->pb_thread);\n\tstream->pb_thread = NULL;\n    }\n\n    if (stream->ca_thread) {\n\tTRACE_((THIS_FILE,\n\t\t   \"alsa_stream_stop(%u): Waiting for capture to stop.\",\n\t\t   (unsigned)syscall(SYS_gettid)));\n\tpj_thread_join (stream->ca_thread);\n\tTRACE_((THIS_FILE,\n\t\t   \"alsa_stream_stop(%u): capture stopped.\",\n\t\t   (unsigned)syscall(SYS_gettid)));\n\tpj_thread_destroy(stream->ca_thread);\n\tstream->ca_thread = NULL;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n\nstatic pj_status_t alsa_stream_destroy (pjmedia_aud_stream *s)\n{\n    struct alsa_stream *stream = (struct alsa_stream*)s;\n\n    alsa_stream_stop (s);\n\n    if (stream->param.dir & PJMEDIA_DIR_PLAYBACK) {\n\tsnd_pcm_close (stream->pb_pcm);\n\tstream->pb_pcm = NULL;\n    }\n    if (stream->param.dir & PJMEDIA_DIR_CAPTURE) {\n\tsnd_pcm_close (stream->ca_pcm);\n\tstream->ca_pcm = NULL;\n    }\n\n    pj_pool_release (stream->pool);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_AUDIO_DEV_HAS_ALSA */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-audiodev/audiodev.c",
    "content": "/* $Id: audiodev.c 4435 2013-03-11 06:32:58Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-audiodev/audiodev_imp.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#define THIS_FILE   \"audiodev.c\"\n\n#define DEFINE_CAP(name, info)\t{name, info}\n\n/* Capability names */\nstatic struct cap_info\n{\n    const char *name;\n    const char *info;\n} cap_infos[] = \n{\n    DEFINE_CAP(\"ext-fmt\",     \"Extended/non-PCM format\"),\n    DEFINE_CAP(\"latency-in\",  \"Input latency/buffer size setting\"),\n    DEFINE_CAP(\"latency-out\", \"Output latency/buffer size setting\"),\n    DEFINE_CAP(\"vol-in\",      \"Input volume setting\"),\n    DEFINE_CAP(\"vol-out\",     \"Output volume setting\"),\n    DEFINE_CAP(\"meter-in\",    \"Input meter\"),\n    DEFINE_CAP(\"meter-out\",   \"Output meter\"),\n    DEFINE_CAP(\"route-in\",    \"Input routing\"),\n    DEFINE_CAP(\"route-out\",   \"Output routing\"),\n    DEFINE_CAP(\"aec\",\t      \"Accoustic echo cancellation\"),\n    DEFINE_CAP(\"aec-tail\",    \"Tail length setting for AEC\"),\n    DEFINE_CAP(\"vad\",\t      \"Voice activity detection\"),\n    DEFINE_CAP(\"cng\",\t      \"Comfort noise generation\"),\n    DEFINE_CAP(\"plg\",\t      \"Packet loss concealment\")\n};\n\n\n/*\n * The device index seen by application and driver is different. \n *\n * At application level, device index is index to global list of device.\n * At driver level, device index is index to device list on that particular\n * factory only.\n */\n#define MAKE_DEV_ID(f_id, index)   (((f_id & 0xFFFF) << 16) | (index & 0xFFFF))\n#define GET_INDEX(dev_id)\t   ((dev_id) & 0xFFFF)\n#define GET_FID(dev_id)\t\t   ((dev_id) >> 16)\n#define DEFAULT_DEV_ID\t\t    0\n\n\n#if PJMEDIA_AUDIO_DEV_HAS_COREAUDIO\npjmedia_aud_dev_factory* pjmedia_coreaudio_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_AUDIO_DEV_HAS_ALSA\npjmedia_aud_dev_factory* pjmedia_alsa_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_AUDIO_DEV_HAS_OPENSL\npjmedia_aud_dev_factory* pjmedia_opensl_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_AUDIO_DEV_HAS_ANDROID_JNI\npjmedia_aud_dev_factory* pjmedia_android_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_AUDIO_DEV_HAS_BB10\npjmedia_aud_dev_factory* pjmedia_bb10_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_AUDIO_DEV_HAS_WMME\npjmedia_aud_dev_factory* pjmedia_wmme_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_AUDIO_DEV_HAS_BDIMAD\npjmedia_aud_dev_factory* pjmedia_bdimad_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS\npjmedia_aud_dev_factory* pjmedia_symb_vas_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_AUDIO_DEV_HAS_SYMB_APS\npjmedia_aud_dev_factory* pjmedia_aps_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA\npjmedia_aud_dev_factory* pjmedia_symb_mda_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO\npjmedia_aud_dev_factory* pjmedia_null_audio_factory(pj_pool_factory *pf);\n#endif\n\n#define MAX_DRIVERS\t16\n#define MAX_DEVS\t64\n\n\n/* driver structure */\nstruct driver\n{\n    /* Creation function */\n    pjmedia_aud_dev_factory_create_func_ptr create;\n    /* Factory instance */\n    pjmedia_aud_dev_factory *f;\n    char\t\t     name[32];\t/* Driver name\t\t\t    */\n    unsigned\t\t     dev_cnt;\t/* Number of devices\t\t    */\n    unsigned\t\t     start_idx;\t/* Start index in global list\t    */\n    int\t\t\t     rec_dev_idx;/* Default capture device.\t    */\n    int\t\t\t     play_dev_idx;/* Default playback device\t    */\n};\n\n/* The audio subsystem */\nstatic struct aud_subsys\n{\n    unsigned\t     init_count;\t/* How many times init() is called  */\n    pj_pool_factory *pf;\t\t/* The pool factory.\t\t    */\n\n    unsigned\t     drv_cnt;\t\t/* Number of drivers.\t\t    */\n    struct driver    drv[MAX_DRIVERS];\t/* Array of drivers.\t\t    */\n\n    unsigned\t     dev_cnt;\t\t/* Total number of devices.\t    */\n    pj_uint32_t\t     dev_list[MAX_DEVS];/* Array of device IDs.\t\t    */\n\n    pjmedia_aud_dev_observer  dev_observer;\n\n} aud_subsys;\n\n/* callback for device change operations */\nstatic void process_aud_dev_change_event(pjmedia_aud_dev_change_event event)\n{\n    pj_status_t status;\n\n    if (!pj_thread_is_registered()) {\n        status = pj_thread_register(\"aud_dev_observer\", aud_subsys.dev_observer.thread_desc, &aud_subsys.dev_observer.thread);\n        if (status != PJ_SUCCESS) {\n            return;\n        }\n        PJ_LOG(5, (THIS_FILE, \"Audio device change thread registered\"));\n    }\n\n    status = pj_mutex_lock(aud_subsys.dev_observer.lock);\n    if (status != PJ_SUCCESS) {\n        PJ_LOG(5, (THIS_FILE, \"Could not acquire audio device change lock\"));\n        return;\n    }\n\n    if (!aud_subsys.dev_observer.cb) {\n        /* there is no registered callback to call */\n        goto end;\n    }\n\n    switch(event) {\n    case DEFAULT_INPUT_CHANGED:\n        PJ_LOG(5, (THIS_FILE, \"Default input device changed\"));\n        pjmedia_aud_dev_refresh();\n        (*aud_subsys.dev_observer.cb)(PJMEDIA_AUD_DEV_DEFAULT_INPUT_CHANGED);\n        break;\n    case DEFAULT_OUTPUT_CHANGED:\n        PJ_LOG(5, (THIS_FILE, \"Default output device changed\"));\n        pjmedia_aud_dev_refresh();\n        (*aud_subsys.dev_observer.cb)(PJMEDIA_AUD_DEV_DEFAULT_OUTPUT_CHANGED);\n        break;\n    case DEVICE_LIST_CHANGED:\n        PJ_LOG(5, (THIS_FILE, \"Device list changed\"));\n        (*aud_subsys.dev_observer.cb)(PJMEDIA_AUD_DEV_LIST_WILL_REFRESH);\n        pjmedia_aud_dev_refresh();\n        (*aud_subsys.dev_observer.cb)(PJMEDIA_AUD_DEV_LIST_DID_REFRESH);\n        break;\n    default:\n        PJ_LOG(5, (THIS_FILE, \"Unknown event: %d\", event));\n        break;\n    }\n\nend:\n    status = pj_mutex_unlock(aud_subsys.dev_observer.lock);\n    if (status != PJ_SUCCESS) {\n        PJ_LOG(5, (THIS_FILE, \"Could not release audio device change lock\"));\n    }\n\n}\n\n/* API: get capability name/info */\nPJ_DEF(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,\n\t\t\t\t\t     const char **p_desc)\n{\n    const char *desc;\n    unsigned i;\n\n    if (p_desc==NULL) p_desc = &desc;\n\n    for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) {\n\tif ((1 << i)==cap)\n\t    break;\n    }\n\n    if (i==PJ_ARRAY_SIZE(cap_infos)) {\n\t*p_desc = \"??\";\n\treturn \"??\";\n    }\n\n    *p_desc = cap_infos[i].info;\n    return cap_infos[i].name;\n}\n\nstatic pj_status_t get_cap_pointer(const pjmedia_aud_param *param,\n\t\t\t\t   pjmedia_aud_dev_cap cap,\n\t\t\t\t   void **ptr,\n\t\t\t\t   unsigned *size)\n{\n#define FIELD_INFO(name)    *ptr = (void*)&param->name; \\\n\t\t\t    *size = sizeof(param->name)\n\n    switch (cap) {\n    case PJMEDIA_AUD_DEV_CAP_EXT_FORMAT:\n\tFIELD_INFO(ext_fmt);\n\tbreak;\n    case PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY:\n\tFIELD_INFO(input_latency_ms);\n\tbreak;\n    case PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY:\n\tFIELD_INFO(output_latency_ms);\n\tbreak;\n    case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:\n\tFIELD_INFO(input_vol);\n\tbreak;\n    case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:\n\tFIELD_INFO(output_vol);\n\tbreak;\n    case PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE:\n\tFIELD_INFO(input_route);\n\tbreak;\n    case PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE:\n\tFIELD_INFO(output_route);\n\tbreak;\n    case PJMEDIA_AUD_DEV_CAP_EC:\n\tFIELD_INFO(ec_enabled);\n\tbreak;\n    case PJMEDIA_AUD_DEV_CAP_EC_TAIL:\n\tFIELD_INFO(ec_tail_ms);\n\tbreak;\n    /* vad is no longer in \"fmt\" in 2.0.\n    case PJMEDIA_AUD_DEV_CAP_VAD:\n\tFIELD_INFO(ext_fmt.vad);\n\tbreak;\n    */\n    case PJMEDIA_AUD_DEV_CAP_CNG:\n\tFIELD_INFO(cng_enabled);\n\tbreak;\n    case PJMEDIA_AUD_DEV_CAP_PLC:\n\tFIELD_INFO(plc_enabled);\n\tbreak;\n    default:\n\treturn PJMEDIA_EAUD_INVCAP;\n    }\n\n#undef FIELD_INFO\n\n    return PJ_SUCCESS;\n}\n\n/* API: set cap value to param */\nPJ_DEF(pj_status_t) pjmedia_aud_param_set_cap( pjmedia_aud_param *param,\n\t\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t\t       const void *pval)\n{\n    void *cap_ptr;\n    unsigned cap_size;\n    pj_status_t status;\n\n    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_memcpy(cap_ptr, pval, cap_size);\n    param->flags |= cap;\n\n    return PJ_SUCCESS;\n}\n\n/* API: get cap value from param */\nPJ_DEF(pj_status_t) pjmedia_aud_param_get_cap( const pjmedia_aud_param *param,\n\t\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t\t       void *pval)\n{\n    void *cap_ptr;\n    unsigned cap_size;\n    pj_status_t status;\n\n    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if ((param->flags & cap) == 0) {\n\tpj_bzero(cap_ptr, cap_size);\n\treturn PJMEDIA_EAUD_INVCAP;\n    }\n\n    pj_memcpy(pval, cap_ptr, cap_size);\n    return PJ_SUCCESS;\n}\n\n/* Internal: init driver */\nstatic pj_status_t init_driver(unsigned drv_idx, pj_bool_t refresh)\n{\n    struct driver *drv = &aud_subsys.drv[drv_idx];\n    pjmedia_aud_dev_factory *f;\n    unsigned i, dev_cnt;\n    pj_status_t status;\n\n    if (!refresh && drv->create) {\n\t/* Create the factory */\n\tf = (*drv->create)(aud_subsys.pf);\n\tif (!f)\n\t    return PJ_EUNKNOWN;\n\n\t/* Call factory->init() */\n\tstatus = f->op->init(f);\n\tif (status != PJ_SUCCESS) {\n\t    f->op->destroy(f);\n\t    return status;\n\t}\n    } else {\n\tf = drv->f;\n    }\n\n    /* Register device change observer */\n    if (!refresh) {\n        f->op->set_dev_change_cb(f, &process_aud_dev_change_event);\n    }\n\n    if (!f)\n\treturn PJ_EUNKNOWN;\n\n    /* Get number of devices */\n    dev_cnt = f->op->get_dev_count(f);\n    if (dev_cnt + aud_subsys.dev_cnt > MAX_DEVS) {\n\tPJ_LOG(4,(THIS_FILE, \"%d device(s) cannot be registered because\"\n\t\t\t      \" there are too many devices\",\n\t\t\t      aud_subsys.dev_cnt + dev_cnt - MAX_DEVS));\n\tdev_cnt = MAX_DEVS - aud_subsys.dev_cnt;\n    }\n\n    /* enabling this will cause pjsua-lib initialization to fail when there\n     * is no sound device installed in the system, even when pjsua has been\n     * run with --null-audio\n     *\n    if (dev_cnt == 0) {\n\tf->op->destroy(f);\n\treturn PJMEDIA_EAUD_NODEV;\n    }\n    */\n\n    /* Fill in default devices */\n    drv->rec_dev_idx = f->op->get_default_rec_dev(f);\n    drv->play_dev_idx = f->op->get_default_play_dev(f);\n    for (i=0; i<dev_cnt; ++i) {\n\tpjmedia_aud_dev_info info;\n\n\tstatus = f->op->get_dev_info(f, i, &info);\n\tif (status != PJ_SUCCESS) {\n\t    f->op->destroy(f);\n\t    return status;\n\t}\n\n\tif (drv->name[0]=='\\0') {\n\t    /* Set driver name */\n\t    pj_ansi_strncpy(drv->name, info.driver, sizeof(drv->name));\n\t    drv->name[sizeof(drv->name)-1] = '\\0';\n\t}\n\n\tif (drv->play_dev_idx < 0 && info.output_count) {\n\t    /* Set default playback device */\n\t    drv->play_dev_idx = i;\n\t}\n\tif (drv->rec_dev_idx < 0 && info.input_count) {\n\t    /* Set default capture device */\n\t    drv->rec_dev_idx = i;\n\t}\n\n\tif (drv->play_dev_idx >= 0 && drv->rec_dev_idx >= 0)\n\t{\n\t    /* Done. */\n\t    break;\n\t}\n    }\n\n    /* Register the factory */\n    drv->f = f;\n    drv->f->sys.drv_idx = drv_idx;\n    drv->start_idx = aud_subsys.dev_cnt;\n    drv->dev_cnt = dev_cnt;\n\n    /* Register devices to global list */\n    for (i=0; i<dev_cnt; ++i) {\n\taud_subsys.dev_list[aud_subsys.dev_cnt++] = MAKE_DEV_ID(drv_idx, i);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* Internal: deinit driver */\nstatic void deinit_driver(unsigned drv_idx)\n{\n    struct driver *drv = &aud_subsys.drv[drv_idx];\n\n    if (drv->f) {\n        drv->f->op->set_dev_change_cb(drv->f, NULL);\n\tdrv->f->op->destroy(drv->f);\n\tdrv->f = NULL;\n    }\n\n    pj_bzero(drv, sizeof(*drv));\n    drv->play_dev_idx = drv->rec_dev_idx = PJMEDIA_AUD_INVALID_DEV;\n}\n\n/* API: Initialize the audio subsystem. */\nPJ_DEF(pj_status_t) pjmedia_aud_subsys_init(pj_pool_factory *pf)\n{\n    unsigned i;\n    pj_status_t status;\n\n    /* Allow init() to be called multiple times as long as there is matching\n     * number of shutdown().\n     */\n    if (aud_subsys.init_count++ != 0) {\n\treturn PJ_SUCCESS;\n    }\n\n    /* Register error subsystem */\n    status = pj_register_strerror(PJMEDIA_AUDIODEV_ERRNO_START, \n\t\t\t\t  PJ_ERRNO_SPACE_SIZE, \n\t\t\t\t  &pjmedia_audiodev_strerror);\n    pj_assert(status == PJ_SUCCESS);\n\n    /* Init */\n    aud_subsys.pf = pf;\n    aud_subsys.drv_cnt = 0;\n    aud_subsys.dev_cnt = 0;\n\n    /* Register creation functions */\n#if PJMEDIA_AUDIO_DEV_HAS_OPENSL\n    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_opensl_factory;\n#endif\n#if PJMEDIA_AUDIO_DEV_HAS_ANDROID_JNI\n    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_android_factory;\n#endif\n#if PJMEDIA_AUDIO_DEV_HAS_BB10\n    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_bb10_factory;\n#endif\n#if PJMEDIA_AUDIO_DEV_HAS_ALSA\n    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_alsa_factory;\n#endif\n#if PJMEDIA_AUDIO_DEV_HAS_COREAUDIO\n    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_coreaudio_factory;\n#endif\n#if PJMEDIA_AUDIO_DEV_HAS_WMME\n    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_wmme_factory;\n#endif\n#if PJMEDIA_AUDIO_DEV_HAS_BDIMAD\n    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_bdimad_factory;\n#endif\n#if PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS\n    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_symb_vas_factory;\n#endif\n#if PJMEDIA_AUDIO_DEV_HAS_SYMB_APS\n    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_aps_factory;\n#endif\n#if PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA\n    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_symb_mda_factory;\n#endif\n#if PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO\n    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_null_audio_factory;\n#endif\n\n    /* Initialize audio device observer objects */\n    pj_status_t st;\n    aud_subsys.dev_observer.pool = pj_pool_create(pf, \"aud_dev_observer_pool\", 512, 512, NULL);\n    if (!aud_subsys.dev_observer.pool) {\n        return PJ_ENOMEM;\n    }\n    st = pj_mutex_create_simple(aud_subsys.dev_observer.pool, \"aud_dev_observer_lock\", &aud_subsys.dev_observer.lock);\n    if (st != PJ_SUCCESS) {\n        return st;\n    }\n    aud_subsys.dev_observer.cb = NULL;\n\n    /* Initialize each factory and build the device ID list */\n    for (i=0; i<aud_subsys.drv_cnt; ++i) {\n\tstatus = init_driver(i, PJ_FALSE);\n\tif (status != PJ_SUCCESS) {\n\t    deinit_driver(i);\n\t    continue;\n\t}\n    }\n\n    return aud_subsys.dev_cnt ? PJ_SUCCESS : status;\n}\n\n/* API: register an audio device factory to the audio subsystem. */\nPJ_DEF(pj_status_t)\npjmedia_aud_register_factory(pjmedia_aud_dev_factory_create_func_ptr adf)\n{\n    pj_status_t status;\n\n    if (aud_subsys.init_count == 0)\n\treturn PJMEDIA_EAUD_INIT;\n\n    aud_subsys.drv[aud_subsys.drv_cnt].create = adf;\n    status = init_driver(aud_subsys.drv_cnt, PJ_FALSE);\n    if (status == PJ_SUCCESS) {\n\taud_subsys.drv_cnt++;\n    } else {\n\tdeinit_driver(aud_subsys.drv_cnt);\n    }\n\n    return status;\n}\n\n/* API: unregister an audio device factory from the audio subsystem. */\nPJ_DEF(pj_status_t)\npjmedia_aud_unregister_factory(pjmedia_aud_dev_factory_create_func_ptr adf)\n{\n    unsigned i, j;\n\n    if (aud_subsys.init_count == 0)\n\treturn PJMEDIA_EAUD_INIT;\n\n    for (i=0; i<aud_subsys.drv_cnt; ++i) {\n\tstruct driver *drv = &aud_subsys.drv[i];\n\n\tif (drv->create == adf) {\n\t    for (j = drv->start_idx; j < drv->start_idx + drv->dev_cnt; j++)\n\t    {\n\t\taud_subsys.dev_list[j] = (pj_uint32_t)PJMEDIA_AUD_INVALID_DEV;\n\t    }\n\n\t    deinit_driver(i);\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    return PJMEDIA_EAUD_ERR;\n}\n\n/* API: get the pool factory registered to the audio subsystem. */\nPJ_DEF(pj_pool_factory*) pjmedia_aud_subsys_get_pool_factory(void)\n{\n    return aud_subsys.pf;\n}\n\n/* API: Shutdown the audio subsystem. */\nPJ_DEF(pj_status_t) pjmedia_aud_subsys_shutdown(void)\n{\n    unsigned i;\n\n    /* Allow shutdown() to be called multiple times as long as there is matching\n     * number of init().\n     */\n    if (aud_subsys.init_count == 0) {\n\treturn PJ_SUCCESS;\n    }\n    --aud_subsys.init_count;\n\n    if (aud_subsys.init_count == 0) {\n\tfor (i=0; i<aud_subsys.drv_cnt; ++i) {\n\t    deinit_driver(i);\n\t}\n\n        pj_mutex_destroy(aud_subsys.dev_observer.lock);\n        pj_pool_release(aud_subsys.dev_observer.pool);\n\n\taud_subsys.pf = NULL;\n    }\n    return PJ_SUCCESS;\n}\n\n/* API: Refresh the list of sound devices installed in the system. */\nPJ_DEF(pj_status_t) pjmedia_aud_dev_refresh(void)\n{\n    unsigned i;\n    \n    aud_subsys.dev_cnt = 0;\n    for (i=0; i<aud_subsys.drv_cnt; ++i) {\n\tstruct driver *drv = &aud_subsys.drv[i];\n\t\n\tif (drv->f && drv->f->op->refresh) {\n\t    pj_status_t status = drv->f->op->refresh(drv->f);\n\t    if (status != PJ_SUCCESS) {\n\t\tPJ_PERROR(4, (THIS_FILE, status, \"Unable to refresh device \"\n\t\t\t\t\t\t \"list for %s\", drv->name));\n\t    }\n\t}\n\tinit_driver(i, PJ_TRUE);\n    }\n    return PJ_SUCCESS;\n}\n\n/* API: Get the number of sound devices installed in the system. */\nPJ_DEF(unsigned) pjmedia_aud_dev_count(void)\n{\n    return aud_subsys.dev_cnt;\n}\n\n/* Internal: convert local index to global device index */\nstatic pj_status_t make_global_index(unsigned drv_idx, \n\t\t\t\t     pjmedia_aud_dev_index *id)\n{\n    if (*id < 0) {\n\treturn PJ_SUCCESS;\n    }\n\n    /* Check that factory still exists */\n    PJ_ASSERT_RETURN(aud_subsys.drv[drv_idx].f, PJ_EBUG);\n\n    /* Check that device index is valid */\n    PJ_ASSERT_RETURN(*id>=0 && *id<(int)aud_subsys.drv[drv_idx].dev_cnt, \n\t\t     PJ_EBUG);\n\n    *id += aud_subsys.drv[drv_idx].start_idx;\n    return PJ_SUCCESS;\n}\n\n/* Internal: lookup device id */\nstatic pj_status_t lookup_dev(pjmedia_aud_dev_index id,\n\t\t\t      pjmedia_aud_dev_factory **p_f,\n\t\t\t      unsigned *p_local_index)\n{\n    int f_id, index;\n\n    if (id < 0) {\n\tunsigned i;\n\n\tif (id == PJMEDIA_AUD_INVALID_DEV)\n\t    return PJMEDIA_EAUD_INVDEV;\n\n\tfor (i=0; i<aud_subsys.drv_cnt; ++i) {\n\t    struct driver *drv = &aud_subsys.drv[i];\n\t    if (id==PJMEDIA_AUD_DEFAULT_CAPTURE_DEV && \n\t\tdrv->rec_dev_idx >= 0) \n\t    {\n\t\tid = drv->rec_dev_idx;\n\t\tmake_global_index(i, &id);\n\t\tbreak;\n\t    } else if (id==PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV && \n\t\tdrv->play_dev_idx >= 0) \n\t    {\n\t\tid = drv->play_dev_idx;\n\t\tmake_global_index(i, &id);\n\t\tbreak;\n            }\n\t}\n\n\tif (id < 0) {\n\t    return PJMEDIA_EAUD_NODEFDEV;\n\t}\n    }\n\n    f_id = GET_FID(aud_subsys.dev_list[id]);\n    index = GET_INDEX(aud_subsys.dev_list[id]);\n\n    if (f_id < 0 || f_id >= (int)aud_subsys.drv_cnt)\n\treturn PJMEDIA_EAUD_INVDEV;\n\n    if (index < 0 || index >= (int)aud_subsys.drv[f_id].dev_cnt)\n\treturn PJMEDIA_EAUD_INVDEV;\n\n    *p_f = aud_subsys.drv[f_id].f;\n    *p_local_index = (unsigned)index;\n\n    return PJ_SUCCESS;\n\n}\n\n/* API: Get device information. */\nPJ_DEF(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_index id,\n\t\t\t\t\t     pjmedia_aud_dev_info *info)\n{\n    pjmedia_aud_dev_factory *f;\n    unsigned index;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(info && id!=PJMEDIA_AUD_INVALID_DEV, PJ_EINVAL);\n    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);\n\n    status = lookup_dev(id, &f, &index);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return f->op->get_dev_info(f, index, info);\n}\n\n/* API: find device */\nPJ_DEF(pj_status_t) pjmedia_aud_dev_lookup( const char *drv_name,\n\t\t\t\t\t    const char *dev_name,\n\t\t\t\t\t    pjmedia_aud_dev_index *id)\n{\n    pjmedia_aud_dev_factory *f = NULL;\n    unsigned drv_idx, dev_idx;\n\n    PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL);\n    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);\n\n    for (drv_idx=0; drv_idx<aud_subsys.drv_cnt; ++drv_idx) {\n\tif (!pj_ansi_stricmp(drv_name, aud_subsys.drv[drv_idx].name)) {\n\t    f = aud_subsys.drv[drv_idx].f;\n\t    break;\n\t}\n    }\n\n    if (!f)\n\treturn PJ_ENOTFOUND;\n\n    for (dev_idx=0; dev_idx<aud_subsys.drv[drv_idx].dev_cnt; ++dev_idx) {\n\tpjmedia_aud_dev_info info;\n\tpj_status_t status;\n\n\tstatus = f->op->get_dev_info(f, dev_idx, &info);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tif (!pj_ansi_stricmp(dev_name, info.name))\n\t    break;\n    }\n\n    if (dev_idx==aud_subsys.drv[drv_idx].dev_cnt)\n\treturn PJ_ENOTFOUND;\n\n    *id = dev_idx;\n    make_global_index(drv_idx, id);\n\n    return PJ_SUCCESS;\n}\n\n/* API: Initialize the audio device parameters with default values for the\n * specified device.\n */\nPJ_DEF(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_index id,\n\t\t\t\t\t\t  pjmedia_aud_param *param)\n{\n    pjmedia_aud_dev_factory *f;\n    unsigned index;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(param && id!=PJMEDIA_AUD_INVALID_DEV, PJ_EINVAL);\n    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);\n\n    status = lookup_dev(id, &f, &index);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    status = f->op->default_param(f, index, param);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Normalize device IDs */\n    make_global_index(f->sys.drv_idx, &param->rec_id);\n    make_global_index(f->sys.drv_idx, &param->play_id);\n\n    return PJ_SUCCESS;\n}\n\n/* API: Open audio stream object using the specified parameters. */\nPJ_DEF(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_param *prm,\n\t\t\t\t\t      pjmedia_aud_rec_cb rec_cb,\n\t\t\t\t\t      pjmedia_aud_play_cb play_cb,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      pjmedia_aud_stream **p_aud_strm)\n{\n    pjmedia_aud_dev_factory *rec_f=NULL, *play_f=NULL, *f=NULL;\n    pjmedia_aud_param param;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(prm && prm->dir && p_aud_strm, PJ_EINVAL);\n    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);\n    PJ_ASSERT_RETURN(prm->dir==PJMEDIA_DIR_CAPTURE ||\n\t\t     prm->dir==PJMEDIA_DIR_PLAYBACK ||\n\t\t     prm->dir==PJMEDIA_DIR_CAPTURE_PLAYBACK,\n\t\t     PJ_EINVAL);\n\n    /* Must make copy of param because we're changing device ID */\n    pj_memcpy(&param, prm, sizeof(param));\n\n    /* Normalize rec_id */\n    if (param.dir & PJMEDIA_DIR_CAPTURE) {\n\tunsigned index;\n\n\tif (param.rec_id < 0)\n\t    param.rec_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;\n\n\tstatus = lookup_dev(param.rec_id, &rec_f, &index);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tparam.rec_id = index;\n\tf = rec_f;\n    }\n\n    /* Normalize play_id */\n    if (param.dir & PJMEDIA_DIR_PLAYBACK) {\n\tunsigned index;\n\n\tif (param.play_id < 0)\n\t    param.play_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;\n\n\tstatus = lookup_dev(param.play_id, &play_f, &index);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tparam.play_id = index;\n\tf = play_f;\n    }\n\n    PJ_ASSERT_RETURN(f != NULL, PJ_EBUG);\n\n    /* For now, rec_id and play_id must belong to the same factory */\n    PJ_ASSERT_RETURN((param.dir != PJMEDIA_DIR_CAPTURE_PLAYBACK) || \n\t\t     (rec_f == play_f),\n\t\t     PJMEDIA_EAUD_INVDEV);\n\n    /* Create the stream */\n    status = f->op->create_stream(f, &param, rec_cb, play_cb,\n\t\t\t\t  user_data, p_aud_strm);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Assign factory id to the stream */\n    (*p_aud_strm)->sys.drv_idx = f->sys.drv_idx;\n    return PJ_SUCCESS;\n}\n\n/* API: Get the running parameters for the specified audio stream. */\nPJ_DEF(pj_status_t) pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm,\n\t\t\t\t\t\t pjmedia_aud_param *param)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(strm && param, PJ_EINVAL);\n    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);\n\n    status = strm->op->get_param(strm, param);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Normalize device id's */\n    make_global_index(strm->sys.drv_idx, &param->rec_id);\n    make_global_index(strm->sys.drv_idx, &param->play_id);\n\n    return PJ_SUCCESS;\n}\n\n/* API: Get the value of a specific capability of the audio stream. */\nPJ_DEF(pj_status_t) pjmedia_aud_stream_get_cap(pjmedia_aud_stream *strm,\n\t\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t\t       void *value)\n{\n    return strm->op->get_cap(strm, cap, value);\n}\n\n/* API: Set the value of a specific capability of the audio stream. */\nPJ_DEF(pj_status_t) pjmedia_aud_stream_set_cap(pjmedia_aud_stream *strm,\n\t\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t\t       const void *value)\n{\n    return strm->op->set_cap(strm, cap, value);\n}\n\n/* API: Start the stream. */\nPJ_DEF(pj_status_t) pjmedia_aud_stream_start(pjmedia_aud_stream *strm)\n{\n    return strm->op->start(strm);\n}\n\n/* API: Stop the stream. */\nPJ_DEF(pj_status_t) pjmedia_aud_stream_stop(pjmedia_aud_stream *strm)\n{\n    return strm->op->stop(strm);\n}\n\n/* API: Destroy the stream. */\nPJ_DEF(pj_status_t) pjmedia_aud_stream_destroy(pjmedia_aud_stream *strm)\n{\n    return strm->op->destroy(strm);\n}\n\n/* API: Register device change observer. */\nPJ_DEF(pj_status_t) pjmedia_aud_dev_set_observer_cb(pjmedia_aud_dev_observer_callback cb)\n{\n    pj_status_t status;\n\n    status = pj_mutex_lock(aud_subsys.dev_observer.lock);\n    if (status != PJ_SUCCESS) {\n        PJ_LOG(5, (THIS_FILE, \"Could not acquire audio device change lock\"));\n        return status;\n    }\n\n    aud_subsys.dev_observer.cb = cb;\n\n    status = pj_mutex_unlock(aud_subsys.dev_observer.lock);\n    if (status != PJ_SUCCESS) {\n        PJ_LOG(5, (THIS_FILE, \"Could not release audio device change lock\"));\n    }\n\n    return status;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-audiodev/coreaudio_dev.m",
    "content": "/* $Id$ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia-audiodev/audiodev_imp.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n\n#if PJMEDIA_AUDIO_DEV_HAS_COREAUDIO\n\n#include \"TargetConditionals.h\"\n#if TARGET_OS_IPHONE\n    #define COREAUDIO_MAC 0\n#else\n    #define COREAUDIO_MAC 1\n#endif\n\n#include <AudioUnit/AudioUnit.h>\n#include <AudioToolbox/AudioConverter.h>\n#if COREAUDIO_MAC\n    #include <CoreAudio/CoreAudio.h>\n#else\n    #include <AVFoundation/AVAudioSession.h>\n\n    #define AudioDeviceID unsigned\n\n    /**\n     * As in iOS SDK 4 or later, audio route change property listener is\n     * no longer necessary. Just make surethat your application can receive\n     * remote control events by adding the code:\n     *     [[UIApplication sharedApplication] \n     *      beginReceivingRemoteControlEvents];\n     * Otherwise audio route change (such as headset plug/unplug) will not be\n     * processed while your application is in the background mode.\n     */\n    #define USE_AUDIO_ROUTE_CHANGE_PROP_LISTENER 0\n\n    /* Starting iOS SDK 7, Audio Session API is deprecated. */\n    #define USE_AUDIO_SESSION_API 0\n#endif\n\n/* For Mac OS 10.5.x and earlier */\n#if AUDIO_UNIT_VERSION < 1060\n    #define AudioComponent Component\n    #define AudioComponentDescription ComponentDescription\n    #define AudioComponentInstance ComponentInstance\n    #define AudioComponentFindNext FindNextComponent\n    #define AudioComponentInstanceNew OpenAComponent\n    #define AudioComponentInstanceDispose CloseComponent\n#endif\n\n\n#define THIS_FILE\t\t\"coreaudio_dev.c\"\n\n/* coreaudio device info */\nstruct coreaudio_dev_info\n{\n    pjmedia_aud_dev_info\t info;\n    AudioDeviceID\t\t dev_id;\n};\n\n/* linked list of streams */\nstruct stream_list\n{\n    PJ_DECL_LIST_MEMBER(struct stream_list);\n    struct coreaudio_stream\t*stream;\n};\n\n/* coreaudio factory */\nstruct coreaudio_factory\n{\n    pjmedia_aud_dev_factory\t base;\n    pj_pool_t\t\t\t*base_pool;\n    pj_pool_t\t\t\t*pool;\n    pj_pool_factory\t\t*pf;\n    pj_mutex_t\t\t\t*mutex;\n\n    unsigned\t\t\t dev_count;\n    struct coreaudio_dev_info\t*dev_info;\n\n    AudioComponent\t\t io_comp;\n    struct stream_list\t\t streams;\n};\n\n/* Sound stream. */\nstruct coreaudio_stream\n{\n    pjmedia_aud_stream\t \t base;   \t /**< Base stream  \t  */\n    pjmedia_aud_param\t \t param;\t\t /**< Settings\t          */\n    pj_pool_t\t\t\t*pool;           /**< Memory pool.        */\n    struct coreaudio_factory\t*cf;\n    struct stream_list\t\t list_entry;\n\n    pjmedia_aud_rec_cb   \t rec_cb;         /**< Capture callback.   */\n    pjmedia_aud_play_cb  \t play_cb;        /**< Playback callback.  */\n    void                \t*user_data;      /**< Application data.   */\n\n    pj_timestamp\t \t play_timestamp;\n    pj_timestamp\t \t rec_timestamp;\n\n    pj_int16_t\t\t\t*rec_buf;\n    unsigned\t\t \t rec_buf_count;\n    pj_int16_t\t\t\t*play_buf;\n    unsigned\t\t \t play_buf_count;\n\n    pj_bool_t\t\t\t interrupted;\n    pj_bool_t\t\t \t quit_flag;\n    pj_bool_t\t\t\t running;\n\n    pj_bool_t\t\t \t rec_thread_initialized;\n    pj_thread_desc\t \t rec_thread_desc;\n    pj_thread_t\t\t\t*rec_thread;\n\n    pj_bool_t\t\t \t play_thread_initialized;\n    pj_thread_desc\t \t play_thread_desc;\n    pj_thread_t\t\t\t*play_thread;\n\n    AudioUnit\t\t \t io_units[2];\n    AudioStreamBasicDescription  streamFormat;\n    AudioBufferList\t\t*audio_buf;\n\n    AudioConverterRef            resample;\n    pj_int16_t\t\t\t*resample_buf;\n    void\t\t\t*resample_buf_ptr;\n    unsigned\t\t \t resample_buf_count;\n    unsigned\t\t \t resample_buf_size;\n    \n#if !COREAUDIO_MAC\n    AVAudioSession              *sess;\n#endif\n};\n\n/* Static variable */\nstatic struct coreaudio_factory *cf_instance = NULL;\n\n/* Prototypes */\nstatic pj_status_t ca_factory_init(pjmedia_aud_dev_factory *f);\nstatic pj_status_t ca_factory_destroy(pjmedia_aud_dev_factory *f);\nstatic pj_status_t ca_factory_refresh(pjmedia_aud_dev_factory *f);\nstatic unsigned    ca_factory_get_dev_count(pjmedia_aud_dev_factory *f);\nstatic pj_status_t ca_factory_get_dev_info(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t   unsigned index,\n\t\t\t\t\t   pjmedia_aud_dev_info *info);\nstatic pj_status_t ca_factory_default_param(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t    unsigned index,\n\t\t\t\t\t    pjmedia_aud_param *param);\nstatic pj_status_t ca_factory_create_stream(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t    const pjmedia_aud_param *param,\n\t\t\t\t\t    pjmedia_aud_rec_cb rec_cb,\n\t\t\t\t\t    pjmedia_aud_play_cb play_cb,\n\t\t\t\t\t    void *user_data,\n\t\t\t\t\t    pjmedia_aud_stream **p_aud_strm);\n\nstatic void ca_factory_set_observer(pjmedia_aud_dev_factory *f,\n                                    pjmedia_aud_dev_change_callback cb);\nstatic int ca_factory_get_default_rec_dev(pjmedia_aud_dev_factory *f);\nstatic int ca_factory_get_default_play_dev(pjmedia_aud_dev_factory *f);\n \nstatic pj_status_t ca_stream_get_param(pjmedia_aud_stream *strm,\n\t\t\t\t       pjmedia_aud_param *param);\nstatic pj_status_t ca_stream_get_cap(pjmedia_aud_stream *strm,\n\t\t\t\t     pjmedia_aud_dev_cap cap,\n\t\t\t\t     void *value);\nstatic pj_status_t ca_stream_set_cap(pjmedia_aud_stream *strm,\n\t\t\t\t     pjmedia_aud_dev_cap cap,\n\t\t\t\t     const void *value);\nstatic pj_status_t ca_stream_start(pjmedia_aud_stream *strm);\nstatic pj_status_t ca_stream_stop(pjmedia_aud_stream *strm);\nstatic pj_status_t ca_stream_destroy(pjmedia_aud_stream *strm);\nstatic pj_status_t create_audio_unit(AudioComponent io_comp,\n\t\t\t\t     AudioDeviceID dev_id,\n\t\t\t\t     pjmedia_dir dir,\n\t\t\t\t     struct coreaudio_stream *strm,\n\t\t\t\t     AudioUnit *io_unit);\n#if !COREAUDIO_MAC && USE_AUDIO_SESSION_API != 0\nstatic void interruptionListener(void *inClientData, UInt32 inInterruption);\nstatic void propListener(void *                 inClientData,\n                         AudioSessionPropertyID inID,\n                         UInt32                 inDataSize,\n                         const void *           inData);\n#endif\n\n/* Operations */\nstatic pjmedia_aud_dev_factory_op factory_op =\n{\n    &ca_factory_init,\n    &ca_factory_destroy,\n    &ca_factory_get_dev_count,\n    &ca_factory_get_dev_info,\n    &ca_factory_default_param,\n    &ca_factory_create_stream,\n    &ca_factory_refresh,\n    &ca_factory_set_observer,\n    &ca_factory_get_default_rec_dev,\n    &ca_factory_get_default_play_dev\n};\n\nstatic pjmedia_aud_stream_op stream_op =\n{\n    &ca_stream_get_param,\n    &ca_stream_get_cap,\n    &ca_stream_set_cap,\n    &ca_stream_start,\n    &ca_stream_stop,\n    &ca_stream_destroy\n};\n\n\n/****************************************************************************\n * Factory operations\n */\n/*\n * Init coreaudio audio driver.\n */\npjmedia_aud_dev_factory* pjmedia_coreaudio_factory(pj_pool_factory *pf)\n{\n    struct coreaudio_factory *f;\n    pj_pool_t *pool;\n\n    pool = pj_pool_create(pf, \"core audio base\", 1000, 1000, NULL);\n    f = PJ_POOL_ZALLOC_T(pool, struct coreaudio_factory);\n    f->pf = pf;\n    f->base_pool = pool;\n    f->base.op = &factory_op;\n\n    return &f->base;\n}\n\n\n/* API: init factory */\nstatic pj_status_t ca_factory_init(pjmedia_aud_dev_factory *f)\n{\n    struct coreaudio_factory *cf = (struct coreaudio_factory*)f;\n    AudioComponentDescription desc;\n    pj_status_t status;\n#if !COREAUDIO_MAC\n    unsigned i;\n#endif\n\n    pj_list_init(&cf->streams);\n    status = pj_mutex_create_recursive(cf->base_pool,\n\t\t\t\t       \"coreaudio\",\n\t\t\t\t       &cf->mutex);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    desc.componentType = kAudioUnitType_Output;\n#if COREAUDIO_MAC\n    desc.componentSubType = kAudioUnitSubType_HALOutput;\n#else\n    desc.componentSubType = kAudioUnitSubType_RemoteIO;\n#endif\n    desc.componentManufacturer = kAudioUnitManufacturer_Apple;\n    desc.componentFlags = 0;\n    desc.componentFlagsMask = 0;\n\n    cf->io_comp = AudioComponentFindNext(NULL, &desc);\n    if (cf->io_comp == NULL)\n\treturn PJMEDIA_EAUD_INIT; // cannot find IO unit;\n\n    status = ca_factory_refresh(f);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n#if !COREAUDIO_MAC\n    cf->pool = pj_pool_create(cf->pf, \"core audio\", 1000, 1000, NULL);\n    cf->dev_count = 1;\n    cf->dev_info = (struct coreaudio_dev_info*)\n   \t\t   pj_pool_calloc(cf->pool, cf->dev_count,\n   \t\t   sizeof(struct coreaudio_dev_info));\n    for (i = 0; i < cf->dev_count; i++) {\n \tstruct coreaudio_dev_info *cdi;\n\n \tcdi = &cf->dev_info[i];\n \tpj_bzero(cdi, sizeof(*cdi));\n \tcdi->dev_id = 0;\n \tstrcpy(cdi->info.name, \"iPhone IO device\");\n \tstrcpy(cdi->info.driver, \"apple\");\n \tcdi->info.input_count = 1;\n \tcdi->info.output_count = 1;\n \tcdi->info.default_samples_per_sec = 8000;\n\n\t/* Set the device capabilities here */\n \tcdi->info.caps = PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY |\n\t\t\t PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY |\n\t\t\t PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING |\n#if USE_AUDIO_SESSION_API != 0\n\t\t\t PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE |\n\t\t\t PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE |\n#endif\n\t\t\t PJMEDIA_AUD_DEV_CAP_EC;\n \tcdi->info.routes = PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER |\n\t\t\t   PJMEDIA_AUD_DEV_ROUTE_EARPIECE |\n\t\t\t   PJMEDIA_AUD_DEV_ROUTE_BLUETOOTH;\n\n\tPJ_LOG(4, (THIS_FILE, \" dev_id %d: %s  (in=%d, out=%d) %dHz\",\n\t\t   i,\n\t\t   cdi->info.name,\n\t\t   cdi->info.input_count,\n\t\t   cdi->info.output_count,\n\t\t   cdi->info.default_samples_per_sec));\n    }\n\n#if USE_AUDIO_SESSION_API != 0\n    {\n        OSStatus ostatus;\n\n        /* Initialize the Audio Session */\n        ostatus = AudioSessionInitialize(NULL, NULL, interruptionListener,\n                                         NULL);\n        if (ostatus != kAudioSessionNoError) {\n            PJ_LOG(4, (THIS_FILE,\n                       \"Warning: cannot initialize audio session services (%i)\",\n                       ostatus));\n        }\n\n        /* Listen for audio routing change notifications. */\n#if USE_AUDIO_ROUTE_CHANGE_PROP_LISTENER != 0\n        ostatus = AudioSessionAddPropertyListener(\n                      kAudioSessionProperty_AudioRouteChange,\n\t\t      propListener, cf);\n        if (ostatus != kAudioSessionNoError) {\n            PJ_LOG(4, (THIS_FILE,\n                       \"Warning: cannot listen for audio route change \"\n                       \"notifications (%i)\", ostatus));\n        }\n#endif\n    }\n#endif\n\n    /* Initialize audio session category and mode */\n    {\n\tAVAudioSession *sess = [AVAudioSession sharedInstance];\n\tpj_bool_t err;\n\n\tif ([sess respondsToSelector:@selector(setCategory:withOptions:error:)])\n\t{\n\t    err = [sess setCategory:AVAudioSessionCategoryPlayAndRecord\n\t\t        withOptions:AVAudioSessionCategoryOptionAllowBluetooth\n\t\t        error:nil] != YES;\n        } else {\n    \t    err = [sess setCategory:AVAudioSessionCategoryPlayAndRecord\n\t\t        error:nil] != YES;\n        }\n\tif (err) {\n            PJ_LOG(3, (THIS_FILE,\n   \t               \"Warning: failed settting audio session category\"));\n\t}\n\n\tif ([sess respondsToSelector:@selector(setMode:error:)] &&\n\t    [sess setMode:AVAudioSessionModeVoiceChat error:nil] != YES)\n\t{\n\t    PJ_LOG(3, (THIS_FILE, \"Warning: failed settting audio mode\"));\n\t}\n    }\n\n    cf_instance = cf;\n#endif\n\n    PJ_LOG(4, (THIS_FILE, \"core audio initialized\"));\n\n    return PJ_SUCCESS;\n}\n\n/* API: destroy factory */\nstatic pj_status_t ca_factory_destroy(pjmedia_aud_dev_factory *f)\n{\n    struct coreaudio_factory *cf = (struct coreaudio_factory*)f;\n    pj_pool_t *pool;\n\n    pj_assert(cf);\n    pj_assert(cf->base_pool);\n    pj_assert(pj_list_empty(&cf->streams));\n\n#if !COREAUDIO_MAC\n#if USE_AUDIO_SESSION_API != 0 && USE_AUDIO_ROUTE_CHANGE_PROP_LISTENER != 0\n    AudioSessionRemovePropertyListenerWithUserData(\n        kAudioSessionProperty_AudioRouteChange, propListener, cf);\n#endif\n#endif\n    \n    if (cf->pool) {\n\tpj_pool_release(cf->pool);\n\tcf->pool = NULL;\n    }\n\n    if (cf->mutex) {\n\tpj_mutex_lock(cf->mutex);\n\tcf_instance = NULL;\n\tpj_mutex_unlock(cf->mutex);\n\tpj_mutex_destroy(cf->mutex);\n\tcf->mutex = NULL;\n    }\n\n    pool = cf->base_pool;\n    cf->base_pool = NULL;\n    pj_pool_release(pool);\n\n    return PJ_SUCCESS;\n}\n\n/* API: refresh the device list */\nstatic pj_status_t ca_factory_refresh(pjmedia_aud_dev_factory *f)\n{\n#if !COREAUDIO_MAC\n    /* iPhone doesn't support refreshing the device list */\n    PJ_UNUSED_ARG(f);\n    return PJ_SUCCESS;\n#else\n    struct coreaudio_factory *cf = (struct coreaudio_factory*)f;\n    unsigned i;\n    unsigned dev_count;\n    AudioObjectPropertyAddress addr;\n    AudioDeviceID *dev_ids;\n    UInt32 buf_size, dev_size, size = sizeof(AudioDeviceID);\n    AudioBufferList *buf = NULL;\n    OSStatus ostatus;\n\n    if (cf->pool != NULL) {\n\tpj_pool_release(cf->pool);\n\tcf->pool = NULL;\n    }\n\n    cf->dev_count = 0;\n    cf->pool = pj_pool_create(cf->pf, \"core audio\", 1000, 1000, NULL);\n\n    /* Find out how many audio devices there are */\n    addr.mSelector = kAudioHardwarePropertyDevices;\n    addr.mScope = kAudioObjectPropertyScopeGlobal;\n    addr.mElement = kAudioObjectPropertyElementMaster;\n    ostatus = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr,\n                                             0, NULL, &dev_size);\n    if (ostatus != noErr) {\n\tdev_size = 0;\n    }\n\n    /* Calculate the number of audio devices available */\n    dev_count = dev_size / size;\n    if (dev_count==0) {\n  \tPJ_LOG(4,(THIS_FILE, \"core audio found no sound devices\"));\n  \t/* Enabling this will cause pjsua-lib initialization to fail when\n  \t * there is no sound device installed in the system, even when pjsua\n  \t * has been run with --null-audio. Moreover, it might be better to\n  \t * think that the core audio backend initialization is successful,\n  \t * regardless there is no audio device installed, as later application\n  \t * can check it using get_dev_count().\n  \treturn PJMEDIA_EAUD_NODEV;\n  \t */\n  \treturn PJ_SUCCESS;\n    }\n    PJ_LOG(4, (THIS_FILE, \"core audio detected %d devices\",\n\t       dev_count));\n\n    /* Get all the audio device IDs */\n    dev_ids = (AudioDeviceID *)pj_pool_calloc(cf->pool, dev_count, size);\n    if (!dev_ids)\n\treturn PJ_ENOMEM;\n    ostatus = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,\n\t\t\t\t\t 0, NULL,\n\t\t\t\t         &dev_size, (void *)dev_ids);\n    if (ostatus != noErr ) {\n\t/* This should not happen since we have successfully retrieved\n\t * the property data size before\n\t */\n\treturn PJMEDIA_EAUD_INIT;\n    }\n    \n    if (dev_size > 1) {\n\tAudioDeviceID dev_id = kAudioObjectUnknown;\n\tunsigned idx = 0;\n\t\n\t/* Find default audio input device */\n\taddr.mSelector = kAudioHardwarePropertyDefaultInputDevice;\n\taddr.mScope = kAudioObjectPropertyScopeGlobal;\n\taddr.mElement = kAudioObjectPropertyElementMaster;\n\tsize = sizeof(dev_id);\n\t\n\tostatus = AudioObjectGetPropertyData(kAudioObjectSystemObject,\n\t\t\t\t\t     &addr, 0, NULL,\n\t\t\t\t\t     &size, (void *)&dev_id);\n\tif (ostatus == noErr && dev_id != dev_ids[idx]) {\n\t    AudioDeviceID temp_id = dev_ids[idx];\n\t    \n\t    for (i = idx + 1; i < dev_count; i++) {\n\t\tif (dev_ids[i] == dev_id) {\n\t\t    dev_ids[idx++] = dev_id;\n\t\t    dev_ids[i] = temp_id;\n\t\t    break;\n\t\t}\n\t    }\n\t}\n\n\t/* Find default audio output device */\n\taddr.mSelector = kAudioHardwarePropertyDefaultOutputDevice;\t\n\tostatus = AudioObjectGetPropertyData(kAudioObjectSystemObject,\n\t\t\t\t\t     &addr, 0, NULL,\n\t\t\t\t\t     &size, (void *)&dev_id);\n\tif (ostatus == noErr && dev_id != dev_ids[idx]) {\n\t    AudioDeviceID temp_id = dev_ids[idx];\n\t    \n\t    for (i = idx + 1; i < dev_count; i++) {\n\t\tif (dev_ids[i] == dev_id) {\n\t\t    dev_ids[idx] = dev_id;\n\t\t    dev_ids[i] = temp_id;\n\t\t    break;\n\t\t}\n\t    }\n\t}\n    }\n\n    /* Build the devices' info */\n    cf->dev_info = (struct coreaudio_dev_info*)\n  \t\t   pj_pool_calloc(cf->pool, dev_count,\n  \t\t   sizeof(struct coreaudio_dev_info));\n    buf_size = 0;\n    for (i = 0; i < dev_count; i++) {\n\tstruct coreaudio_dev_info *cdi;\n\tFloat64 sampleRate;\n\n\tcdi = &cf->dev_info[i];\n\tpj_bzero(cdi, sizeof(*cdi));\n\tcdi->dev_id = dev_ids[i];\n\n\t/* Get device name */\n\taddr.mSelector = kAudioDevicePropertyDeviceName;\n\taddr.mScope = kAudioObjectPropertyScopeGlobal;\n\taddr.mElement = kAudioObjectPropertyElementMaster;\n\tsize = sizeof(cdi->info.name);\n\tAudioObjectGetPropertyData(cdi->dev_id, &addr,\n\t\t\t\t   0, NULL,\n\t\t\t           &size, (void *)cdi->info.name);\n\n\tstrcpy(cdi->info.driver, \"core audio\");\n\n        /* Get the number of input channels */\n\taddr.mSelector = kAudioDevicePropertyStreamConfiguration;\n\taddr.mScope = kAudioDevicePropertyScopeInput;\n\tsize = 0;\n\tostatus = AudioObjectGetPropertyDataSize(cdi->dev_id, &addr,\n\t                                         0, NULL, &size);\n\tif (ostatus == noErr && size > 0) {\n\n\t    if (size > buf_size) {\n\t\tbuf = pj_pool_alloc(cf->pool, size);\n\t\tbuf_size = size;\n\t    }\n\t    if (buf) {\n\t\tUInt32 idx;\n\n\t\t/* Get the input stream configuration */\n\t\tostatus = AudioObjectGetPropertyData(cdi->dev_id, &addr,\n\t\t\t\t\t\t     0, NULL,\n\t\t\t\t\t\t     &size, buf);\n\t\tif (ostatus == noErr) {\n\t\t    /* Count the total number of input channels in\n\t\t     * the stream\n\t\t     */\n\t\t    for (idx = 0; idx < buf->mNumberBuffers; idx++) {\n\t\t\tcdi->info.input_count +=\n\t\t\t    buf->mBuffers[idx].mNumberChannels;\n\t\t    }\n\t\t}\n\t    }\n\t}\n\n        /* Get the number of output channels */\n\taddr.mScope = kAudioDevicePropertyScopeOutput;\n\tsize = 0;\n\tostatus = AudioObjectGetPropertyDataSize(cdi->dev_id, &addr,\n\t                                         0, NULL, &size);\n\tif (ostatus == noErr && size > 0) {\n\n\t    if (size > buf_size) {\n\t\tbuf = pj_pool_alloc(cf->pool, size);\n\t\tbuf_size = size;\n\t    }\n\t    if (buf) {\n\t\tUInt32 idx;\n\n\t\t/* Get the output stream configuration */\n\t\tostatus = AudioObjectGetPropertyData(cdi->dev_id, &addr,\n\t\t\t\t\t\t     0, NULL,\n\t\t\t\t\t\t     &size, buf);\n\t\tif (ostatus == noErr) {\n\t\t    /* Count the total number of output channels in\n\t\t     * the stream\n\t\t     */\n\t\t    for (idx = 0; idx < buf->mNumberBuffers; idx++) {\n\t\t\tcdi->info.output_count +=\n\t\t\t    buf->mBuffers[idx].mNumberChannels;\n\t\t    }\n\t\t}\n\t    }\n\t}\n\n\t/* Get default sample rate */\n\taddr.mSelector = kAudioDevicePropertyNominalSampleRate;\n\taddr.mScope = kAudioObjectPropertyScopeGlobal;\n\tsize = sizeof(Float64);\n\tostatus = AudioObjectGetPropertyData (cdi->dev_id, &addr,\n\t\t                              0, NULL,\n\t\t                              &size, &sampleRate);\n\tcdi->info.default_samples_per_sec = (ostatus == noErr ?\n\t\t\t\t\t    sampleRate:\n\t\t\t\t\t    16000);\n\n\t/* Set device capabilities here */\n\tif (cdi->info.input_count > 0) {\n\t    cdi->info.caps |= PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY;\n\t}\n\tif (cdi->info.output_count > 0) {\n\t    cdi->info.caps |= PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;\n\t    addr.mSelector = kAudioDevicePropertyVolumeScalar;\n\t    addr.mScope = kAudioDevicePropertyScopeOutput;\n\t    if (AudioObjectHasProperty(cdi->dev_id, &addr)) {\n\t\tcdi->info.caps |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;\n\t    }\n\t}\n\n\tcf->dev_count++;\n\n\tPJ_LOG(4, (THIS_FILE, \" dev_id %d: %s  (in=%d, out=%d) %dHz\",\n\t       i,\n\t       cdi->info.name,\n\t       cdi->info.input_count,\n\t       cdi->info.output_count,\n\t       cdi->info.default_samples_per_sec));\n    }\n\n    return PJ_SUCCESS;\n#endif\n}\n\n/* API: get number of devices */\nstatic unsigned ca_factory_get_dev_count(pjmedia_aud_dev_factory *f)\n{\n    struct coreaudio_factory *cf = (struct coreaudio_factory*)f;\n    return cf->dev_count;\n}\n\n/* API: get device info */\nstatic pj_status_t ca_factory_get_dev_info(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t   unsigned index,\n\t\t\t\t\t   pjmedia_aud_dev_info *info)\n{\n    struct coreaudio_factory *cf = (struct coreaudio_factory*)f;\n\n    PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EAUD_INVDEV);\n\n    pj_memcpy(info, &cf->dev_info[index].info, sizeof(*info));\n\n    return PJ_SUCCESS;\n}\n\n/* API: create default device parameter */\nstatic pj_status_t ca_factory_default_param(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t    unsigned index,\n\t\t\t\t\t    pjmedia_aud_param *param)\n{\n    struct coreaudio_factory *cf = (struct coreaudio_factory*)f;\n    struct coreaudio_dev_info *di = &cf->dev_info[index];\n\n    PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EAUD_INVDEV);\n\n    pj_bzero(param, sizeof(*param));\n    if (di->info.input_count && di->info.output_count) {\n\tparam->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;\n\tparam->rec_id = index;\n\tparam->play_id = index;\n    } else if (di->info.input_count) {\n\tparam->dir = PJMEDIA_DIR_CAPTURE;\n\tparam->rec_id = index;\n\tparam->play_id = PJMEDIA_AUD_INVALID_DEV;\n    } else if (di->info.output_count) {\n\tparam->dir = PJMEDIA_DIR_PLAYBACK;\n\tparam->play_id = index;\n\tparam->rec_id = PJMEDIA_AUD_INVALID_DEV;\n    } else {\n\treturn PJMEDIA_EAUD_INVDEV;\n    }\n\n    /* Set the mandatory settings here */\n    param->clock_rate = di->info.default_samples_per_sec;\n    param->channel_count = 1;\n    param->samples_per_frame = di->info.default_samples_per_sec * 20 / 1000;\n    param->bits_per_sample = 16;\n\n    /* Set the param for device capabilities here */\n    param->flags = PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY |\n\t\t   PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;\n    param->input_latency_ms = PJMEDIA_SND_DEFAULT_REC_LATENCY;\n    param->output_latency_ms = PJMEDIA_SND_DEFAULT_PLAY_LATENCY;\n\n    return PJ_SUCCESS;\n}\n\nstatic OSStatus property_listener_proc(AudioObjectID objectID,\n                                       UInt32 numberAddresses,\n                                       const AudioObjectPropertyAddress inAddresses[],\n                                       void *clientData)\n{\n    pjmedia_aud_dev_change_callback cb = (pjmedia_aud_dev_change_callback)clientData;\n    pjmedia_aud_dev_change_event event;\n    UInt32 i;\n\n    for(i = 0; i < numberAddresses; i++) {\n        event = 0;\n        switch (inAddresses[i].mSelector) {\n        case kAudioHardwarePropertyDefaultInputDevice:\n            event = DEFAULT_INPUT_CHANGED;\n            break;\n        case kAudioHardwarePropertyDefaultOutputDevice:\n            event = DEFAULT_OUTPUT_CHANGED;\n            break;\n        case kAudioHardwarePropertyDevices:\n            event = DEVICE_LIST_CHANGED;\n            break;\n        default:\n            break;\n        }\n        if (event > 0) {\n            (cb)(event);\n        }\n    }\n\n    return noErr;\n}\n\n/* API: set audio device change observer */\nstatic void ca_factory_set_observer(pjmedia_aud_dev_factory *f,\n                                    pjmedia_aud_dev_change_callback cb)\n{\n    AudioObjectPropertyAddress addr;\n    OSStatus ostatus;\n\n    /* observer for devices list */\n    addr.mSelector = kAudioHardwarePropertyDevices;\n    addr.mScope = kAudioObjectPropertyScopeGlobal;\n    addr.mElement = kAudioObjectPropertyElementMaster;\n\n    if (cb) {\n        ostatus = AudioObjectAddPropertyListener(kAudioObjectSystemObject,\n                                                &addr,\n                                                property_listener_proc,\n                                                cb);\n    } else {\n        ostatus = AudioObjectRemovePropertyListener(kAudioObjectSystemObject,\n                                                    &addr,\n                                                    property_listener_proc,\n                                                    cb);\n    }\n    if (ostatus != noErr) {\n\tPJ_LOG(5,(THIS_FILE, \"Error %sregistering devices list observer\", cb==NULL ? \"un-\" : \"\"));\n    }\n\n    /* observer for default input device */\n    addr.mSelector = kAudioHardwarePropertyDefaultInputDevice;\n\n    if (cb) {\n        ostatus = AudioObjectAddPropertyListener(kAudioObjectSystemObject,\n                                                &addr,\n                                                property_listener_proc,\n                                                cb);\n    } else {\n        ostatus = AudioObjectRemovePropertyListener(kAudioObjectSystemObject,\n                                                    &addr,\n                                                    property_listener_proc,\n                                                    cb);\n    }\n    if (ostatus != noErr) {\n\tPJ_LOG(5,(THIS_FILE, \"Error %sregistering default input device observer\", cb==NULL ? \"un-\" : \"\"));\n    }\n\n    /* observer for default output device */\n    addr.mSelector = kAudioHardwarePropertyDefaultOutputDevice;\n\n    if (cb) {\n        ostatus = AudioObjectAddPropertyListener(kAudioObjectSystemObject,\n                                                &addr,\n                                                property_listener_proc,\n                                                cb);\n    } else {\n        ostatus = AudioObjectRemovePropertyListener(kAudioObjectSystemObject,\n                                                    &addr,\n                                                    property_listener_proc,\n                                                    cb);\n    }\n    if (ostatus != noErr) {\n\tPJ_LOG(5,(THIS_FILE, \"Error %sregistering default output device observer\", cb==NULL ? \"un-\" : \"\"));\n    }\n\n}\n\n/* API: get default recording device */\nstatic int ca_factory_get_default_rec_dev(pjmedia_aud_dev_factory *f)\n{\n    AudioDeviceID dev_id = kAudioObjectUnknown;\n    AudioObjectPropertyAddress addr;\n    UInt32 size;\n    OSStatus ostatus;\n    int i;\n    int idx = -1;\n    struct coreaudio_factory *cf = (struct coreaudio_factory*)f;\n\n    /* Find default audio input device */\n    addr.mSelector = kAudioHardwarePropertyDefaultInputDevice;\n    addr.mScope = kAudioObjectPropertyScopeGlobal;\n    addr.mElement = kAudioObjectPropertyElementMaster;\n    size = sizeof(dev_id);\n\n    ostatus = AudioObjectGetPropertyData(kAudioObjectSystemObject,\n                                         &addr, 0, NULL,\n                                         &size, (void *)&dev_id);\n    if (ostatus == noErr) {\n        for (i = 0; i < cf->dev_count; i++) {\n            struct coreaudio_dev_info *cdi;\n\t    cdi = &cf->dev_info[i];\n            if (cdi->dev_id == dev_id) {\n                idx = i;\n                break;\n            }\n        }\n    }\n    return idx;\n}\n\n/* API: get default playback device */\nstatic int ca_factory_get_default_play_dev(pjmedia_aud_dev_factory *f)\n{\n    AudioDeviceID dev_id = kAudioObjectUnknown;\n    AudioObjectPropertyAddress addr;\n    UInt32 size;\n    OSStatus ostatus;\n    int i;\n    int idx = -1;\n    struct coreaudio_factory *cf = (struct coreaudio_factory*)f;\n\n    /* Find default audio output device */\n    addr.mSelector = kAudioHardwarePropertyDefaultOutputDevice;\n    addr.mScope = kAudioObjectPropertyScopeGlobal;\n    addr.mElement = kAudioObjectPropertyElementMaster;\n    size = sizeof(dev_id);\n\n    ostatus = AudioObjectGetPropertyData(kAudioObjectSystemObject,\n                                         &addr, 0, NULL,\n                                         &size, (void *)&dev_id);\n    if (ostatus == noErr) {\n        for (i = 0; i < cf->dev_count; i++) {\n            struct coreaudio_dev_info *cdi;\n\t    cdi = &cf->dev_info[i];\n            if (cdi->dev_id == dev_id) {\n                idx = i;\n                break;\n            }\n        }\n    }\n    return idx;\n}\n\nOSStatus resampleProc(AudioConverterRef             inAudioConverter,\n\t\t      UInt32                        *ioNumberDataPackets,\n\t\t      AudioBufferList               *ioData,\n\t\t      AudioStreamPacketDescription  **outDataPacketDescription,\n\t\t      void                          *inUserData)\n{\n    struct coreaudio_stream *strm = (struct coreaudio_stream*)inUserData;\n\n    if (*ioNumberDataPackets > strm->resample_buf_size)\n\t*ioNumberDataPackets = strm->resample_buf_size;\n\n    ioData->mNumberBuffers = 1;\n    ioData->mBuffers[0].mNumberChannels = strm->streamFormat.mChannelsPerFrame;\n    ioData->mBuffers[0].mData = strm->resample_buf_ptr;\n    ioData->mBuffers[0].mDataByteSize = *ioNumberDataPackets *\n\t\t\t\t\tstrm->streamFormat.mChannelsPerFrame *\n\t\t\t\t\tstrm->param.bits_per_sample >> 3;\n\n    return noErr;\n}\n\nstatic OSStatus resample_callback(void                       *inRefCon,\n\t\t\t\t  AudioUnitRenderActionFlags *ioActionFlags,\n\t\t\t\t  const AudioTimeStamp       *inTimeStamp,\n\t\t\t\t  UInt32                      inBusNumber,\n\t\t\t\t  UInt32                      inNumberFrames,\n\t\t\t\t  AudioBufferList            *ioData)\n{\n    struct coreaudio_stream *strm = (struct coreaudio_stream*)inRefCon;\n    OSStatus ostatus;\n    pj_status_t status = 0;\n    unsigned nsamples;\n    AudioBufferList *buf = strm->audio_buf;\n    pj_int16_t *input;\n    UInt32 resampleSize;\n\n    pj_assert(!strm->quit_flag);\n\n    /* Known cases of callback's thread:\n     * - The thread may be changed in the middle of a session\n     *   it happens when plugging/unplugging headphone.\n     * - The same thread may be reused in consecutive sessions. The first\n     *   session will leave TLS set, but release the TLS data address,\n     *   so the second session must re-register the callback's thread.\n     */\n    if (strm->rec_thread_initialized == 0 || !pj_thread_is_registered())\n    {\n\tpj_bzero(strm->rec_thread_desc, sizeof(pj_thread_desc));\n\tstatus = pj_thread_register(\"ca_rec\", strm->rec_thread_desc,\n\t\t\t\t    &strm->rec_thread);\n\tstrm->rec_thread_initialized = 1;\n\tPJ_LOG(5,(THIS_FILE, \"Recorder thread started, (%i frames)\", \n\t\t  inNumberFrames));\n    }\n\n    buf->mBuffers[0].mData = NULL;\n    buf->mBuffers[0].mDataByteSize = inNumberFrames *\n\t\t\t\t     strm->streamFormat.mChannelsPerFrame;\n    /* Render the unit to get input data */\n    ostatus = AudioUnitRender(strm->io_units[0],\n\t\t\t      ioActionFlags,\n\t\t\t      inTimeStamp,\n\t\t\t      inBusNumber,\n\t\t\t      inNumberFrames,\n\t\t\t      buf);\n\n    if (ostatus != noErr) {\n\tPJ_LOG(5, (THIS_FILE, \"Core audio unit render error %i\", ostatus));\n\tgoto on_break;\n    }\n    input = (pj_int16_t *)buf->mBuffers[0].mData;\n\n    resampleSize = strm->resample_buf_size;\n    nsamples = inNumberFrames * strm->param.channel_count +\n\t       strm->resample_buf_count;\n\n    if (nsamples >= resampleSize) {\n\tpjmedia_frame frame;\n\tUInt32 resampleOutput = strm->param.samples_per_frame /\n\t\t\t\tstrm->streamFormat.mChannelsPerFrame;\n\tAudioBufferList ab;\n\n\tframe.type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframe.buf = (void*) strm->rec_buf;\n\tframe.size = strm->param.samples_per_frame *\n\t\t     strm->param.bits_per_sample >> 3;\n\tframe.bit_info = 0;\n\t\n\tab.mNumberBuffers = 1;\n\tab.mBuffers[0].mNumberChannels = strm->streamFormat.mChannelsPerFrame;\n\tab.mBuffers[0].mData = strm->rec_buf;\n\tab.mBuffers[0].mDataByteSize = frame.size;\n\n\t/* If buffer is not empty, combine the buffer with the just incoming\n\t * samples, then call put_frame.\n\t */\n\tif (strm->resample_buf_count) {\n\t    unsigned chunk_count = resampleSize - strm->resample_buf_count;\n\t    pjmedia_copy_samples(strm->resample_buf + strm->resample_buf_count,\n\t\t\t\t input, chunk_count);\n\n\t    /* Do the resample */\n\n\t    strm->resample_buf_ptr = strm->resample_buf;\n\t    ostatus = AudioConverterFillComplexBuffer(strm->resample,\n\t\t\t\t\t\t      resampleProc,\n\t\t\t\t\t\t      strm,\n\t\t\t\t\t\t      &resampleOutput,\n\t\t\t\t\t\t      &ab,\n\t\t\t\t\t\t      NULL);\n\t    if (ostatus != noErr) {\n\t\tgoto on_break;\n\t    }\n\t    frame.timestamp.u64 = strm->rec_timestamp.u64;\n\n\t    status = (*strm->rec_cb)(strm->user_data, &frame);\n\n\t    input = input + chunk_count;\n\t    nsamples -= resampleSize;\n\t    strm->resample_buf_count = 0;\n\t    strm->rec_timestamp.u64 += strm->param.samples_per_frame /\n\t\t\t\t       strm->param.channel_count;\n\t}\n\t\n\t\n \t/* Give all frames we have */\n \twhile (nsamples >= resampleSize && status == 0) {\n \t    frame.timestamp.u64 = strm->rec_timestamp.u64;\n\t    \n\t    /* Do the resample */\n\t    strm->resample_buf_ptr = input;\n\t    ab.mBuffers[0].mDataByteSize = frame.size;\n\t    resampleOutput = strm->param.samples_per_frame /\n\t\t\t     strm->streamFormat.mChannelsPerFrame;\n\t    ostatus = AudioConverterFillComplexBuffer(strm->resample,\n\t\t\t\t\t\t      resampleProc,\n\t\t\t\t\t\t      strm,\n\t\t\t\t\t\t      &resampleOutput,\n\t\t\t\t\t\t      &ab,\n\t\t\t\t\t\t      NULL);\n\t    if (ostatus != noErr) {\n\t\tgoto on_break;\n\t    }\t    \n\t    \n \t    status = (*strm->rec_cb)(strm->user_data, &frame);\n\t    \n \t    input = (pj_int16_t*) input + resampleSize;\n \t    nsamples -= resampleSize;\n \t    strm->rec_timestamp.u64 += strm->param.samples_per_frame /\n\t\t\t\t       strm->param.channel_count;\n \t}\n\n\t/* Store the remaining samples into the buffer */\n\tif (nsamples && status == 0) {\n\t    strm->resample_buf_count = nsamples;\n\t    pjmedia_copy_samples(strm->resample_buf, input,\n\t\t\t\t nsamples);\n\t}\n\n    } else {\n\t/* Not enough samples, let's just store them in the buffer */\n\tpjmedia_copy_samples(strm->resample_buf + strm->resample_buf_count,\n\t\t\t     input,\n\t\t\t     inNumberFrames * strm->param.channel_count);\n\tstrm->resample_buf_count += inNumberFrames *\n\t\t\t\t    strm->param.channel_count;\n    }\n\n    return noErr;\n\non_break:\n    return -1;\n}\n\nstatic OSStatus input_callback(void                       *inRefCon,\n                               AudioUnitRenderActionFlags *ioActionFlags,\n                               const AudioTimeStamp       *inTimeStamp,\n                               UInt32                      inBusNumber,\n                               UInt32                      inNumberFrames,\n                               AudioBufferList            *ioData)\n{\n    struct coreaudio_stream *strm = (struct coreaudio_stream*)inRefCon;\n    OSStatus ostatus;\n    pj_status_t status = 0;\n    unsigned nsamples;\n    AudioBufferList *buf = strm->audio_buf;\n    pj_int16_t *input;\n\n    pj_assert(!strm->quit_flag);\n\n    /* Known cases of callback's thread:\n     * - The thread may be changed in the middle of a session\n     *   it happens when plugging/unplugging headphone.\n     * - The same thread may be reused in consecutive sessions. The first\n     *   session will leave TLS set, but release the TLS data address,\n     *   so the second session must re-register the callback's thread.\n     */\n    if (strm->rec_thread_initialized == 0 || !pj_thread_is_registered())\n    {\n\tpj_bzero(strm->rec_thread_desc, sizeof(pj_thread_desc));\n\tstatus = pj_thread_register(\"ca_rec\", strm->rec_thread_desc,\n\t\t\t\t    &strm->rec_thread);\n\tstrm->rec_thread_initialized = 1;\n\tPJ_LOG(5,(THIS_FILE, \"Recorder thread started, (%i frames)\",\n\t\t  inNumberFrames));\n    }\n\n    buf->mBuffers[0].mData = NULL;\n    buf->mBuffers[0].mDataByteSize = inNumberFrames *\n\t\t\t\t     strm->streamFormat.mChannelsPerFrame;\n    /* Render the unit to get input data */\n    ostatus = AudioUnitRender(strm->io_units[0],\n\t\t\t      ioActionFlags,\n\t\t\t      inTimeStamp,\n\t\t\t      inBusNumber,\n\t\t\t      inNumberFrames,\n\t\t\t      buf);\n\n    if (ostatus != noErr) {\n\tPJ_LOG(5, (THIS_FILE, \"Core audio unit render error %i\", ostatus));\n\tgoto on_break;\n    }\n    input = (pj_int16_t *)buf->mBuffers[0].mData;\n\n    /* Calculate number of samples we've got */\n    nsamples = inNumberFrames * strm->param.channel_count +\n\t       strm->rec_buf_count;\n    if (nsamples >= strm->param.samples_per_frame) {\n\tpjmedia_frame frame;\n\n\tframe.type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframe.size = strm->param.samples_per_frame *\n\t\t     strm->param.bits_per_sample >> 3;\n\tframe.bit_info = 0;\n\n \t/* If buffer is not empty, combine the buffer with the just incoming\n \t * samples, then call put_frame.\n \t */\n \tif (strm->rec_buf_count) {\n \t    unsigned chunk_count = 0;\n\n \t    chunk_count = strm->param.samples_per_frame - strm->rec_buf_count;\n \t    pjmedia_copy_samples(strm->rec_buf + strm->rec_buf_count,\n \t\t\t\t input, chunk_count);\n\n \t    frame.buf = (void*) strm->rec_buf;\n \t    frame.timestamp.u64 = strm->rec_timestamp.u64;\n\n \t    status = (*strm->rec_cb)(strm->user_data, &frame);\n\n \t    input = input + chunk_count;\n \t    nsamples -= strm->param.samples_per_frame;\n \t    strm->rec_buf_count = 0;\n \t    strm->rec_timestamp.u64 += strm->param.samples_per_frame /\n\t\t\t\t       strm->param.channel_count;\n \t}\n\n \t/* Give all frames we have */\n \twhile (nsamples >= strm->param.samples_per_frame && status == 0) {\n \t    frame.buf = (void*) input;\n \t    frame.timestamp.u64 = strm->rec_timestamp.u64;\n\n \t    status = (*strm->rec_cb)(strm->user_data, &frame);\n\n \t    input = (pj_int16_t*) input + strm->param.samples_per_frame;\n \t    nsamples -= strm->param.samples_per_frame;\n \t    strm->rec_timestamp.u64 += strm->param.samples_per_frame /\n\t\t\t\t       strm->param.channel_count;\n \t}\n\n \t/* Store the remaining samples into the buffer */\n \tif (nsamples && status == 0) {\n \t    strm->rec_buf_count = nsamples;\n \t    pjmedia_copy_samples(strm->rec_buf, input,\n \t\t\t         nsamples);\n \t}\n\n     } else {\n \t/* Not enough samples, let's just store them in the buffer */\n \tpjmedia_copy_samples(strm->rec_buf + strm->rec_buf_count,\n \t\t\t     input,\n \t\t\t     inNumberFrames * strm->param.channel_count);\n \tstrm->rec_buf_count += inNumberFrames * strm->param.channel_count;\n     }\n\n    return noErr;\n\non_break:\n    return -1;\n}\n\nstatic OSStatus output_renderer(void                       *inRefCon,\n                                AudioUnitRenderActionFlags *ioActionFlags,\n                                const AudioTimeStamp       *inTimeStamp,\n                                UInt32                      inBusNumber,\n                                UInt32                      inNumberFrames,\n                                AudioBufferList            *ioData)\n{\n    struct coreaudio_stream *stream = (struct coreaudio_stream*)inRefCon;\n    pj_status_t status = 0;\n    unsigned nsamples_req = inNumberFrames * stream->param.channel_count;\n    pj_int16_t *output = ioData->mBuffers[0].mData;\n\n    pj_assert(!stream->quit_flag);\n\n    /* Known cases of callback's thread:\n     * - The thread may be changed in the middle of a session\n     *   it happens when plugging/unplugging headphone.\n     * - The same thread may be reused in consecutive sessions. The first\n     *   session will leave TLS set, but release the TLS data address,\n     *   so the second session must re-register the callback's thread.\n     */\n    if (stream->play_thread_initialized == 0 || !pj_thread_is_registered())\n    {\n\tpj_bzero(stream->play_thread_desc, sizeof(pj_thread_desc));\n\tstatus = pj_thread_register(\"coreaudio\", stream->play_thread_desc,\n\t\t\t\t    &stream->play_thread);\n\tstream->play_thread_initialized = 1;\n\tPJ_LOG(5,(THIS_FILE, \"Player thread started, (%i frames)\",\n\t\t  inNumberFrames));\n    }\n\n\n    /* Check if any buffered samples */\n    if (stream->play_buf_count) {\n\t/* samples buffered >= requested by sound device */\n\tif (stream->play_buf_count >= nsamples_req) {\n\t    pjmedia_copy_samples((pj_int16_t*)output, stream->play_buf,\n\t\t\t\t nsamples_req);\n\t    stream->play_buf_count -= nsamples_req;\n\t    pjmedia_move_samples(stream->play_buf,\n\t\t\t\t stream->play_buf + nsamples_req,\n\t\t\t\t stream->play_buf_count);\n\t    nsamples_req = 0;\n\n\t    return noErr;\n\t}\n\n\t/* samples buffered < requested by sound device */\n\tpjmedia_copy_samples((pj_int16_t*)output, stream->play_buf,\n\t\t\t     stream->play_buf_count);\n\tnsamples_req -= stream->play_buf_count;\n\toutput = (pj_int16_t*)output + stream->play_buf_count;\n\tstream->play_buf_count = 0;\n    }\n\n    /* Fill output buffer as requested */\n    while (nsamples_req && status == 0) {\n\tpjmedia_frame frame;\n\n\tframe.type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframe.size = stream->param.samples_per_frame *\n\t\t     stream->param.bits_per_sample >> 3;\n\tframe.timestamp.u64 = stream->play_timestamp.u64;\n\tframe.bit_info = 0;\n\n\tif (nsamples_req >= stream->param.samples_per_frame) {\n\t    frame.buf = output;\n\t    status = (*stream->play_cb)(stream->user_data, &frame);\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_break;\n\n\t    if (frame.type != PJMEDIA_FRAME_TYPE_AUDIO)\n\t\tpj_bzero(frame.buf, frame.size);\n\n\t    nsamples_req -= stream->param.samples_per_frame;\n\t    output = (pj_int16_t*)output + stream->param.samples_per_frame;\n\t} else {\n\t    frame.buf = stream->play_buf;\n\t    status = (*stream->play_cb)(stream->user_data, &frame);\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_break;\n\n\t    if (frame.type != PJMEDIA_FRAME_TYPE_AUDIO)\n\t\tpj_bzero(frame.buf, frame.size);\n\n\t    pjmedia_copy_samples((pj_int16_t*)output, stream->play_buf,\n\t\t\t\t nsamples_req);\n\t    stream->play_buf_count = stream->param.samples_per_frame -\n\t\t                     nsamples_req;\n\t    pjmedia_move_samples(stream->play_buf,\n\t\t\t\t stream->play_buf+nsamples_req,\n\t\t\t\t stream->play_buf_count);\n\t    nsamples_req = 0;\n\t}\n\n\tstream->play_timestamp.u64 += stream->param.samples_per_frame /\n\t\t\t\t      stream->param.channel_count;\n    }\n\n    return noErr;\n\non_break:\n    return -1;\n}\n\n#if !COREAUDIO_MAC && USE_AUDIO_SESSION_API != 0\nstatic void propListener(void \t\t\t*inClientData,\n\t\t\t AudioSessionPropertyID\tinID,\n\t\t\t UInt32                 inDataSize,\n\t\t\t const void *           inData)\n{\n    struct coreaudio_factory *cf = (struct coreaudio_factory*)inClientData;\n    struct stream_list *it, *itBegin;\n    CFDictionaryRef routeDictionary;\n    CFNumberRef reason;\n    SInt32 reasonVal;\n    pj_assert(cf);\n\n    if (inID != kAudioSessionProperty_AudioRouteChange)\n\treturn;\n\n    routeDictionary = (CFDictionaryRef)inData;\n    reason = (CFNumberRef)\n\t     CFDictionaryGetValue(\n\t         routeDictionary, \n\t\t CFSTR(kAudioSession_AudioRouteChangeKey_Reason));\n    CFNumberGetValue(reason, kCFNumberSInt32Type, &reasonVal);\n\n    if (reasonVal != kAudioSessionRouteChangeReason_OldDeviceUnavailable) {\n\tPJ_LOG(3, (THIS_FILE, \"ignoring audio route change...\"));\n\treturn;\n    }\n\n    PJ_LOG(3, (THIS_FILE, \"audio route changed\"));\n\n    pj_mutex_lock(cf->mutex);\n    itBegin = &cf->streams;\n    for (it = itBegin->next; it != itBegin; it = it->next) {\n\tif (it->stream->interrupted)\n\t    continue;\n\n\t/*\n\tstatus = ca_stream_stop((pjmedia_aud_stream *)it->stream);\n\tstatus = ca_stream_start((pjmedia_aud_stream *)it->stream);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_LOG(3, (THIS_FILE,\n\t\t       \"Error: failed to restart the audio unit (%i)\",\n\t\t       status));\n\t    continue;\n\t}\n\tPJ_LOG(3, (THIS_FILE, \"core audio unit successfully restarted\"));\n\t*/\n    }\n    pj_mutex_unlock(cf->mutex);\n}\n\nstatic void interruptionListener(void *inClientData, UInt32 inInterruption)\n{\n    struct stream_list *it, *itBegin;\n    pj_status_t status;\n    static pj_thread_desc thread_desc;\n    pj_thread_t *thread;\n    \n    /* Register the thread with PJLIB, this is must for any external threads\n     * which need to use the PJLIB framework.\n     */\n    if (!pj_thread_is_registered()) {\n\tpj_bzero(thread_desc, sizeof(pj_thread_desc));\n\tstatus = pj_thread_register(\"intListener\", thread_desc, &thread);\n    }\n    \n    PJ_LOG(3, (THIS_FILE, \"Session interrupted! --- %s ---\",\n\t   inInterruption == kAudioSessionBeginInterruption ?\n\t   \"Begin Interruption\" : \"End Interruption\"));\n\n    if (!cf_instance)\n\treturn;\n    \n    pj_mutex_lock(cf_instance->mutex);\n    itBegin = &cf_instance->streams;\n    for (it = itBegin->next; it != itBegin; it = it->next) {\n\tif (inInterruption == kAudioSessionEndInterruption &&\n\t    it->stream->interrupted == PJ_TRUE)\n\t{\n\t    UInt32 audioCategory;\n\t    OSStatus ostatus;\n\n\t    /* Make sure that your application can receive remote control\n\t     * events by adding the code:\n\t     *     [[UIApplication sharedApplication] \n\t     *      beginReceivingRemoteControlEvents];\n\t     * Otherwise audio unit will fail to restart while your\n\t     * application is in the background mode.\n\t     */\n\t    /* Make sure we set the correct audio category before restarting */\n\t    audioCategory = kAudioSessionCategory_PlayAndRecord;\n\t    ostatus = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,\n\t\t\t\t\t      sizeof(audioCategory),\n\t\t\t\t\t      &audioCategory);\n\t    if (ostatus != kAudioSessionNoError) {\n\t\tPJ_LOG(4, (THIS_FILE,\n\t\t\t   \"Warning: cannot set the audio session category (%i)\",\n\t\t\t   ostatus));\n\t    }\n\t    \n\t    /* Restart the stream */\n\t    status = ca_stream_start((pjmedia_aud_stream*)it->stream);\n\t    if (status != PJ_SUCCESS) {\n\t\tPJ_LOG(3, (THIS_FILE,\n\t\t\t   \"Error: failed to restart the audio unit (%i)\",\n\t\t\t   status));\n\t\tcontinue;\n\t    }\n\t    PJ_LOG(3, (THIS_FILE, \"core audio unit successfully resumed\"\n\t\t       \" after interruption\"));\n\t} else if (inInterruption == kAudioSessionBeginInterruption &&\n\t\t   it->stream->running == PJ_TRUE)\n\t{\n\t    status = ca_stream_stop((pjmedia_aud_stream*)it->stream);\n\t    it->stream->interrupted = PJ_TRUE;\n\t}\n    }\n    pj_mutex_unlock(cf_instance->mutex);\n}\n\n#endif\n\n#if COREAUDIO_MAC\n/* Internal: create audio converter for resampling the recorder device */\nstatic pj_status_t create_audio_resample(struct coreaudio_stream     *strm,\n\t\t\t\t\t AudioStreamBasicDescription *desc)\n{\n    OSStatus ostatus;\n\n    pj_assert(strm->streamFormat.mSampleRate != desc->mSampleRate);\n    pj_assert(NULL == strm->resample);\n    pj_assert(NULL == strm->resample_buf);\n\n    /* Create the audio converter */\n    ostatus = AudioConverterNew(desc, &strm->streamFormat, &strm->resample);\n    if (ostatus != noErr) {\n\treturn PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n    }\n    \n    /*\n     * Allocate the buffer required to hold enough input data\n     */\n    strm->resample_buf_size =  (unsigned)(desc->mSampleRate *\n\t\t\t\t\t  strm->param.samples_per_frame /\n\t\t\t\t\t  strm->param.clock_rate);\n    strm->resample_buf = (pj_int16_t*)\n\t\t\t pj_pool_alloc(strm->pool,\n\t\t\t\t       strm->resample_buf_size *\n\t\t\t\t       strm->param.bits_per_sample >> 3);\n    if (!strm->resample_buf)\n\treturn PJ_ENOMEM;\n    strm->resample_buf_count = 0;\n\n    return PJ_SUCCESS;\n}\n#endif\n\n/* Internal: create audio unit for recorder/playback device */\nstatic pj_status_t create_audio_unit(AudioComponent io_comp,\n\t\t\t\t     AudioDeviceID dev_id,\n\t\t\t\t     pjmedia_dir dir,\n\t\t\t\t     struct coreaudio_stream *strm,\n\t\t\t\t     AudioUnit *io_unit)\n{\n    OSStatus ostatus;\n\n#if !COREAUDIO_MAC\n    strm->sess = [AVAudioSession sharedInstance];\n#endif\n    \n    /* Create an audio unit to interface with the device */\n    ostatus = AudioComponentInstanceNew(io_comp, io_unit);\n    if (ostatus != noErr) {\n\treturn PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n    }\n\n    /* Set audio unit's properties for capture device */\n    if (dir & PJMEDIA_DIR_CAPTURE) {\n\tUInt32 enable = 1;\n\n\t/* Enable input */\n\tostatus = AudioUnitSetProperty(*io_unit,\n\t                               kAudioOutputUnitProperty_EnableIO,\n\t                               kAudioUnitScope_Input,\n\t                               1,\n\t                               &enable,\n\t                               sizeof(enable));\n\tif (ostatus != noErr) {\n\t    PJ_LOG(4, (THIS_FILE,\n\t\t   \"Warning: cannot enable IO of capture device %d\",\n\t\t   dev_id));\n\t}\n\n\t/* Disable output */\n\tif (!(dir & PJMEDIA_DIR_PLAYBACK)) {\n\t    enable = 0;\n\t    ostatus = AudioUnitSetProperty(*io_unit,\n\t\t\t\t\t   kAudioOutputUnitProperty_EnableIO,\n\t\t\t\t\t   kAudioUnitScope_Output,\n\t\t\t\t\t   0,\n\t\t\t\t\t   &enable,\n\t\t\t\t\t   sizeof(enable));\n\t    if (ostatus != noErr) {\n\t\tPJ_LOG(4, (THIS_FILE,\n\t\t       \"Warning: cannot disable IO of capture device %d\",\n\t\t       dev_id));\n\t    }\n\t}\n    }\n\n    /* Set audio unit's properties for playback device */\n    if (dir & PJMEDIA_DIR_PLAYBACK) {\n\tUInt32 enable = 1;\n\n\t/* Enable output */\n\tostatus = AudioUnitSetProperty(*io_unit,\n\t                               kAudioOutputUnitProperty_EnableIO,\n\t                               kAudioUnitScope_Output,\n\t                               0,\n\t                               &enable,\n\t                               sizeof(enable));\n\tif (ostatus != noErr) {\n\t    PJ_LOG(4, (THIS_FILE,\n\t\t   \"Warning: cannot enable IO of playback device %d\",\n\t\t   dev_id));\n\t}\n\n    }\n\n#if COREAUDIO_MAC\n    PJ_LOG(5, (THIS_FILE, \"Opening device %d\", dev_id));\n    ostatus = AudioUnitSetProperty(*io_unit,\n\t\t\t           kAudioOutputUnitProperty_CurrentDevice,\n\t\t\t           kAudioUnitScope_Global,\n\t\t\t           0,\n\t\t\t           &dev_id,\n\t\t\t           sizeof(dev_id));\n    if (ostatus != noErr) {\n\treturn PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n    }\n#endif\n\n    if (dir & PJMEDIA_DIR_CAPTURE) {\n#if COREAUDIO_MAC\n\tAudioStreamBasicDescription deviceFormat;\n\tUInt32 size;\n\n\t/*\n\t * Keep the sample rate from the device, otherwise we will confuse\n\t * AUHAL\n\t */\n\tsize = sizeof(AudioStreamBasicDescription);\n\tostatus = AudioUnitGetProperty(*io_unit,\n\t\t\t\t       kAudioUnitProperty_StreamFormat,\n\t\t\t\t       kAudioUnitScope_Input,\n\t\t\t\t       1,\n\t\t\t\t       &deviceFormat,\n\t\t\t\t       &size);\n\tif (ostatus != noErr) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n\tstrm->streamFormat.mSampleRate = deviceFormat.mSampleRate;\n#endif\n\n\t/* When setting the stream format, we have to make sure the sample\n\t * rate is supported. Setting an unsupported sample rate will cause\n\t * AudioUnitRender() to fail later.\n\t */\n\tostatus = AudioUnitSetProperty(*io_unit,\n\t\t\t\t       kAudioUnitProperty_StreamFormat,\n\t\t\t\t       kAudioUnitScope_Output,\n\t\t\t\t       1,\n\t\t\t\t       &strm->streamFormat,\n\t\t\t\t       sizeof(strm->streamFormat));\n\tif (ostatus != noErr) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n\n#if COREAUDIO_MAC\n\tstrm->streamFormat.mSampleRate = strm->param.clock_rate;\n\tsize = sizeof(AudioStreamBasicDescription);\n\tostatus = AudioUnitGetProperty (*io_unit,\n\t\t\t\t\tkAudioUnitProperty_StreamFormat,\n\t\t\t\t\tkAudioUnitScope_Output,\n\t\t\t\t\t1,\n\t\t\t\t\t&deviceFormat,\n\t\t\t\t\t&size);\n\tif (ostatus == noErr) {\n\t    if (strm->streamFormat.mSampleRate != deviceFormat.mSampleRate) {\n\t\tpj_status_t rc = create_audio_resample(strm, &deviceFormat);\n\t\tif (PJ_SUCCESS != rc)\n\t\t    return rc;\n\t    }\n\t} else {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n#endif\n    }\n\n    if (dir & PJMEDIA_DIR_PLAYBACK) {\n\tAURenderCallbackStruct output_cb;\n\n\t/* Set the stream format */\n\tostatus = AudioUnitSetProperty(*io_unit,\n\t                               kAudioUnitProperty_StreamFormat,\n\t                               kAudioUnitScope_Input,\n\t                               0,\n\t                               &strm->streamFormat,\n\t                               sizeof(strm->streamFormat));\n\tif (ostatus != noErr) {\n\t    PJ_LOG(4, (THIS_FILE,\n\t\t   \"Warning: cannot set playback stream format of dev %d\",\n\t\t   dev_id));\n\t}\n\n\t/* Set render callback */\n\toutput_cb.inputProc = output_renderer;\n\toutput_cb.inputProcRefCon = strm;\n\tostatus = AudioUnitSetProperty(*io_unit,\n\t\t\t\t       kAudioUnitProperty_SetRenderCallback,\n\t\t\t\t       kAudioUnitScope_Input,\n\t\t\t\t       0,\n\t\t\t\t       &output_cb,\n\t\t\t\t       sizeof(output_cb));\n\tif (ostatus != noErr) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n\n\t/* Allocate playback buffer */\n\tstrm->play_buf = (pj_int16_t*)pj_pool_alloc(strm->pool,\n\t\t\t strm->param.samples_per_frame *\n\t\t\t strm->param.bits_per_sample >> 3);\n\tif (!strm->play_buf)\n\t    return PJ_ENOMEM;\n\tstrm->play_buf_count = 0;\n    }\n\n    if (dir & PJMEDIA_DIR_CAPTURE) {\n\tAURenderCallbackStruct input_cb;\n#if COREAUDIO_MAC\n\tAudioBuffer *ab;\n\tUInt32 size, buf_size;\n#endif\n\n\t/* Set input callback */\n\tinput_cb.inputProc = strm->resample ? resample_callback :\n\t\t\t     input_callback;\n\tinput_cb.inputProcRefCon = strm;\n\tostatus = AudioUnitSetProperty(\n\t\t      *io_unit,\n\t\t      kAudioOutputUnitProperty_SetInputCallback,\n\t\t      kAudioUnitScope_Global,\n\t\t      0,\n\t\t      &input_cb,\n\t\t      sizeof(input_cb));\n\tif (ostatus != noErr) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n\n#if COREAUDIO_MAC\n\t/* Get device's buffer frame size */\n\tsize = sizeof(UInt32);\n\tostatus = AudioUnitGetProperty(*io_unit,\n\t\t                       kAudioDevicePropertyBufferFrameSize,\n\t\t                       kAudioUnitScope_Global,\n\t\t                       0,\n\t\t                       &buf_size,\n\t\t                       &size);\n\tif (ostatus != noErr)\n\t{\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n\n\t/* Allocate audio buffer */\n\tstrm->audio_buf = (AudioBufferList*)pj_pool_alloc(strm->pool,\n\t\t          sizeof(AudioBufferList) + sizeof(AudioBuffer));\n\tif (!strm->audio_buf)\n\t    return PJ_ENOMEM;\n\n\tstrm->audio_buf->mNumberBuffers = 1;\n\tab = &strm->audio_buf->mBuffers[0];\n\tab->mNumberChannels = strm->streamFormat.mChannelsPerFrame;\n\tab->mDataByteSize = buf_size * ab->mNumberChannels *\n\t\t\t    strm->param.bits_per_sample >> 3;\n\tab->mData = pj_pool_alloc(strm->pool,\n\t\t\t\t  ab->mDataByteSize);\n\tif (!ab->mData)\n\t    return PJ_ENOMEM;\n\n#else\n\t/* We will let AudioUnitRender() to allocate the buffer\n\t * for us later\n\t */\n\tstrm->audio_buf = (AudioBufferList*)pj_pool_alloc(strm->pool,\n\t\t          sizeof(AudioBufferList) + sizeof(AudioBuffer));\n\tif (!strm->audio_buf)\n\t    return PJ_ENOMEM;\n\n\tstrm->audio_buf->mNumberBuffers = 1;\n\tstrm->audio_buf->mBuffers[0].mNumberChannels =\n\t\tstrm->streamFormat.mChannelsPerFrame;\n\t\n#endif\n\n\t/* Allocate recording buffer */\n\tstrm->rec_buf = (pj_int16_t*)pj_pool_alloc(strm->pool,\n\t\t\tstrm->param.samples_per_frame *\n\t\t\tstrm->param.bits_per_sample >> 3);\n\tif (!strm->rec_buf)\n\t    return PJ_ENOMEM;\n\tstrm->rec_buf_count = 0;\n    }\n\n    /* Initialize the audio unit */\n    ostatus = AudioUnitInitialize(*io_unit);\n    if (ostatus != noErr) {\n \treturn PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: create stream */\nstatic pj_status_t ca_factory_create_stream(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t    const pjmedia_aud_param *param,\n\t\t\t\t\t    pjmedia_aud_rec_cb rec_cb,\n\t\t\t\t\t    pjmedia_aud_play_cb play_cb,\n\t\t\t\t\t    void *user_data,\n\t\t\t\t\t    pjmedia_aud_stream **p_aud_strm)\n{\n    struct coreaudio_factory *cf = (struct coreaudio_factory*)f;\n    pj_pool_t *pool;\n    struct coreaudio_stream *strm;\n    pj_status_t status;\n\n    /* Create and Initialize stream descriptor */\n    pool = pj_pool_create(cf->pf, \"coreaudio-dev\", 1000, 1000, NULL);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    strm = PJ_POOL_ZALLOC_T(pool, struct coreaudio_stream);\n    pj_list_init(&strm->list_entry);\n    strm->list_entry.stream = strm;\n    strm->cf = cf;\n    pj_memcpy(&strm->param, param, sizeof(*param));\n    strm->pool = pool;\n    strm->rec_cb = rec_cb;\n    strm->play_cb = play_cb;\n    strm->user_data = user_data;\n\n    /* Set the stream format */\n    strm->streamFormat.mSampleRate       = param->clock_rate;\n    strm->streamFormat.mFormatID         = kAudioFormatLinearPCM;\n    strm->streamFormat.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger\n  \t\t\t\t\t   | kLinearPCMFormatFlagIsPacked;\n    strm->streamFormat.mBitsPerChannel   = strm->param.bits_per_sample;\n    strm->streamFormat.mChannelsPerFrame = param->channel_count;\n    strm->streamFormat.mBytesPerFrame    = strm->streamFormat.mChannelsPerFrame\n\t                                   * strm->param.bits_per_sample >> 3;\n    strm->streamFormat.mFramesPerPacket  = 1;\n    strm->streamFormat.mBytesPerPacket   = strm->streamFormat.mBytesPerFrame *\n\t\t\t\t\t   strm->streamFormat.mFramesPerPacket;\n\n    /* Apply input/output routes settings before we create the audio units */\n    if (param->flags & PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE) {\n\tca_stream_set_cap(&strm->base,\n\t\t          PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE,\n\t\t          &param->input_route);\n    }\n    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE) {\n\tca_stream_set_cap(&strm->base,\n\t\t          PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE,\n\t\t          &param->output_route);\n    }\n    if (param->flags & PJMEDIA_AUD_DEV_CAP_EC) {\n\tca_stream_set_cap(&strm->base,\n\t\t          PJMEDIA_AUD_DEV_CAP_EC,\n\t\t          &param->ec_enabled);\n    } else {\n\tpj_bool_t ec = PJ_FALSE;\n\tca_stream_set_cap(&strm->base,\n\t\t          PJMEDIA_AUD_DEV_CAP_EC, &ec);\n    }\n\n    strm->io_units[0] = strm->io_units[1] = NULL;\n    if (param->dir == PJMEDIA_DIR_CAPTURE_PLAYBACK &&\n\tparam->rec_id == param->play_id)\n    {\n\t/* If both input and output are on the same device, only create\n\t * one audio unit to interface with the device.\n\t */\n\tstatus = create_audio_unit(cf->io_comp,\n\t\t                   cf->dev_info[param->rec_id].dev_id,\n\t\t                   param->dir, strm, &strm->io_units[0]);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n    } else {\n\tunsigned nunits = 0;\n\n\tif (param->dir & PJMEDIA_DIR_CAPTURE) {\n\t    status = create_audio_unit(cf->io_comp,\n\t\t\t\t       cf->dev_info[param->rec_id].dev_id,\n\t\t\t\t       PJMEDIA_DIR_CAPTURE,\n\t\t\t\t       strm, &strm->io_units[nunits++]);\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_error;\n\t}\n\tif (param->dir & PJMEDIA_DIR_PLAYBACK) {\n\n\t    status = create_audio_unit(cf->io_comp,\n\t\t\t\t       cf->dev_info[param->play_id].dev_id,\n\t\t\t\t       PJMEDIA_DIR_PLAYBACK,\n\t\t\t\t       strm, &strm->io_units[nunits++]);\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_error;\n\t}\n    }\n\n    /* Apply the remaining settings */\n    if (param->flags & PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY) {\n\tca_stream_get_cap(&strm->base,\n\t\t          PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY,\n\t\t          &strm->param.input_latency_ms);\n    }\n    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY) {\n\tca_stream_get_cap(&strm->base,\n\t\t          PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY,\n\t\t          &strm->param.output_latency_ms);\n    }\n    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING) {\n\tca_stream_set_cap(&strm->base,\n\t\t          PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,\n\t\t          &param->output_vol);\n    }\n\n    pj_mutex_lock(strm->cf->mutex);\n    pj_assert(pj_list_empty(&strm->list_entry));\n    pj_list_insert_after(&strm->cf->streams, &strm->list_entry);\n    pj_mutex_unlock(strm->cf->mutex);\n\n    /* Done */\n    strm->base.op = &stream_op;\n    *p_aud_strm = &strm->base;\n\n    return PJ_SUCCESS;\n\n on_error:\n    ca_stream_destroy((pjmedia_aud_stream *)strm);\n    return status;\n}\n\n/* API: Get stream info. */\nstatic pj_status_t ca_stream_get_param(pjmedia_aud_stream *s,\n\t\t\t\t       pjmedia_aud_param *pi)\n{\n    struct coreaudio_stream *strm = (struct coreaudio_stream*)s;\n\n    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);\n\n    pj_memcpy(pi, &strm->param, sizeof(*pi));\n\n    /* Update the device capabilities' values */\n    if (ca_stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY,\n\t\t          &pi->input_latency_ms) == PJ_SUCCESS)\n    {\n    \tpi->flags |= PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY;\n    }\n    if (ca_stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY,\n\t\t\t  &pi->output_latency_ms) == PJ_SUCCESS)\n    {\n\tpi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;\n    }\n    if (ca_stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,\n\t\t\t  &pi->output_vol) == PJ_SUCCESS)\n    {\n        pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;\n    }\n    if (ca_stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE,\n\t\t\t  &pi->input_route) == PJ_SUCCESS)\n    {\n        pi->flags |= PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE;\n    }\n    if (ca_stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE,\n\t\t\t  &pi->output_route) == PJ_SUCCESS)\n    {\n        pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE;\n    }\n    if (ca_stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_EC,\n\t\t\t  &pi->ec_enabled) == PJ_SUCCESS)\n    {\n        pi->flags |= PJMEDIA_AUD_DEV_CAP_EC;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: get capability */\nstatic pj_status_t ca_stream_get_cap(pjmedia_aud_stream *s,\n\t\t\t\t     pjmedia_aud_dev_cap cap,\n\t\t\t\t     void *pval)\n{\n    struct coreaudio_stream *strm = (struct coreaudio_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    if (cap==PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY &&\n\t(strm->param.dir & PJMEDIA_DIR_CAPTURE))\n    {\n#if COREAUDIO_MAC\n\tUInt32 latency, size = sizeof(UInt32);\n\n\t/* Recording latency */\n\tif (AudioUnitGetProperty (strm->io_units[0],\n\t\t\t\t  kAudioDevicePropertyLatency,\n\t\t\t\t  kAudioUnitScope_Input,\n\t\t\t\t  1,\n\t\t\t\t  &latency,\n\t\t\t\t  &size) == noErr)\n\t{\n\t    UInt32 latency2;\n\t    if (AudioUnitGetProperty (strm->io_units[0],\n\t\t\t\t      kAudioDevicePropertyBufferFrameSize,\n\t\t\t\t      kAudioUnitScope_Input,\n\t\t\t\t      1,\n\t\t\t\t      &latency2,\n\t\t\t\t      &size) == noErr)\n\t    {\n\t\tstrm->param.input_latency_ms = (latency + latency2) * 1000 /\n\t\t\t\t\t       strm->param.clock_rate;\n\t    }\n\t}\n#else\n        if ([strm->sess respondsToSelector:@selector(inputLatency)]) {\n\t    strm->param.input_latency_ms =\n                (unsigned)(([strm->sess inputLatency] +\n                            [strm->sess IOBufferDuration]) * 1000);\n\t} else\n            return PJMEDIA_EAUD_INVCAP;\n#endif\n\n\t*(unsigned*)pval = strm->param.input_latency_ms;\n\treturn PJ_SUCCESS;\n    } else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY  &&\n\t       (strm->param.dir & PJMEDIA_DIR_PLAYBACK))\n    {\n#if COREAUDIO_MAC\n\tUInt32 latency, size = sizeof(UInt32);\n\tAudioUnit *io_unit = strm->io_units[1] ? &strm->io_units[1] :\n\t\t\t     &strm->io_units[0];\n\n\t/* Playback latency */\n\tif (AudioUnitGetProperty (*io_unit,\n\t\t\t\t  kAudioDevicePropertyLatency,\n\t\t\t\t  kAudioUnitScope_Output,\n\t\t\t\t  0,\n\t\t\t\t  &latency,\n\t\t\t\t  &size) == noErr)\n\t{\n\t    UInt32 latency2;\n\t    if (AudioUnitGetProperty (*io_unit,\n\t\t\t\t      kAudioDevicePropertyBufferFrameSize,\n\t\t\t\t      kAudioUnitScope_Output,\n\t\t\t\t      0,\n\t\t\t\t      &latency2,\n\t\t\t\t      &size) == noErr)\n\t    {\n\t\tstrm->param.output_latency_ms = (latency + latency2) * 1000 /\n\t\t\t\t\t\tstrm->param.clock_rate;\n\t    }\n\t}\n#else\n        if ([strm->sess respondsToSelector:@selector(outputLatency)]) {\n\t    strm->param.output_latency_ms =\n            (unsigned)(([strm->sess outputLatency] +\n                        [strm->sess IOBufferDuration]) * 1000);\n\t} else\n            return PJMEDIA_EAUD_INVCAP;\n#endif\n\t*(unsigned*)pval = strm->param.output_latency_ms;\n\treturn PJ_SUCCESS;\n    } else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING &&\n\t       (strm->param.dir & PJMEDIA_DIR_PLAYBACK))\n    {\n#if COREAUDIO_MAC\n\tOSStatus ostatus;\n\tFloat32 volume;\n\tUInt32 size = sizeof(Float32);\n\n\t/* Output volume setting */\n\tostatus = AudioUnitGetProperty (strm->io_units[1] ? strm->io_units[1] :\n\t\t\t\t\tstrm->io_units[0],\n\t\t\t\t\tkAudioDevicePropertyVolumeScalar,\n\t                                kAudioUnitScope_Output,\n\t                                0,\n\t                                &volume,\n\t                                &size);\n\tif (ostatus != noErr)\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\n\t*(unsigned*)pval = (unsigned)(volume * 100);\n\treturn PJ_SUCCESS;\n#else\n        if ([strm->sess respondsToSelector:@selector(outputVolume)]) {\n            *(unsigned*)pval = (unsigned)([strm->sess outputVolume] * 100);\n            return PJ_SUCCESS;\n\t} else\n            return PJMEDIA_EAUD_INVCAP;\n#endif\n\n#if !COREAUDIO_MAC\n#if USE_AUDIO_SESSION_API != 0\n    } else if (cap==PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE &&\n\t       (strm->param.dir & PJMEDIA_DIR_CAPTURE))\n    {\n\tUInt32 btooth, size = sizeof(UInt32);\n\tOSStatus ostatus;\n\n\tostatus = AudioSessionGetProperty (\n\t    kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,\n\t    &size, &btooth);\n\tif (ostatus != kAudioSessionNoError) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n\n\t*(pjmedia_aud_dev_route*)pval = btooth?\n\t\t                        PJMEDIA_AUD_DEV_ROUTE_BLUETOOTH:\n\t\t\t\t\tPJMEDIA_AUD_DEV_ROUTE_DEFAULT;\n\treturn PJ_SUCCESS;\n    } else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE &&\n\t       (strm->param.dir & PJMEDIA_DIR_PLAYBACK))\n    {\n\tCFStringRef route;\n\tUInt32 size = sizeof(CFStringRef);\n\tOSStatus ostatus;\n\n\tostatus = AudioSessionGetProperty (kAudioSessionProperty_AudioRoute,\n\t\t\t\t\t   &size, &route);\n\tif (ostatus != kAudioSessionNoError) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n\n\tif (!route) {\n\t    *(pjmedia_aud_dev_route*)pval = PJMEDIA_AUD_DEV_ROUTE_DEFAULT;\n\t} else if (CFStringHasPrefix(route, CFSTR(\"Headset\"))) {\n\t    *(pjmedia_aud_dev_route*)pval = PJMEDIA_AUD_DEV_ROUTE_EARPIECE;\n\t} else {\n\t    *(pjmedia_aud_dev_route*)pval = PJMEDIA_AUD_DEV_ROUTE_DEFAULT;\n\t}\n\n\tCFRelease(route);\n\n\treturn PJ_SUCCESS;\n#endif\n    } else if (cap==PJMEDIA_AUD_DEV_CAP_EC) {\n\tAudioComponentDescription desc;\n\tOSStatus ostatus;\n\n\tostatus = AudioComponentGetDescription(strm->cf->io_comp, &desc);\n\tif (ostatus != noErr) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n\n\t*(pj_bool_t*)pval = (desc.componentSubType ==\n\t\t            kAudioUnitSubType_VoiceProcessingIO);\n\treturn PJ_SUCCESS;\n#endif\n    } else {\n\treturn PJMEDIA_EAUD_INVCAP;\n    }\n}\n\n/* API: set capability */\nstatic pj_status_t ca_stream_set_cap(pjmedia_aud_stream *s,\n\t\t\t\t     pjmedia_aud_dev_cap cap,\n\t\t\t\t     const void *pval)\n{\n    struct coreaudio_stream *strm = (struct coreaudio_stream*)s;\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n#if COREAUDIO_MAC\n    if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING &&\n\t(strm->param.dir & PJMEDIA_DIR_PLAYBACK))\n    {\n\tOSStatus ostatus;\n\tFloat32 volume = *(unsigned*)pval;\n\n\t/* Output volume setting */\n\tvolume /= 100.0;\n\tostatus = AudioUnitSetProperty (strm->io_units[1] ? strm->io_units[1] :\n\t\t\t\t\tstrm->io_units[0],\n\t\t\t\t\tkAudioDevicePropertyVolumeScalar,\n\t                                kAudioUnitScope_Output,\n\t                                0,\n\t                                &volume,\n\t                                sizeof(Float32));\n\tif (ostatus != noErr) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n\tstrm->param.output_vol = *(unsigned*)pval;\n\treturn PJ_SUCCESS;\n    }\n\n#else\n    if (cap==PJMEDIA_AUD_DEV_CAP_EC) {\n\tAudioComponentDescription desc;\n\tAudioComponent io_comp;\n        \n\tdesc.componentType = kAudioUnitType_Output;\n\tdesc.componentSubType = (*(pj_bool_t*)pval)?\n        kAudioUnitSubType_VoiceProcessingIO :\n        kAudioUnitSubType_RemoteIO;\n\tdesc.componentManufacturer = kAudioUnitManufacturer_Apple;\n\tdesc.componentFlags = 0;\n\tdesc.componentFlagsMask = 0;\n        \n\tio_comp = AudioComponentFindNext(NULL, &desc);\n\tif (io_comp == NULL)\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(-1);\n\tstrm->cf->io_comp = io_comp;\n\tstrm->param.ec_enabled = *(pj_bool_t*)pval;\n        \n        PJ_LOG(4, (THIS_FILE, \"Using %s audio unit\",\n                   (desc.componentSubType ==\n                    kAudioUnitSubType_RemoteIO? \"RemoteIO\":\n                    \"VoiceProcessingIO\")));\n        \n\treturn PJ_SUCCESS;\n    } else if ((cap==PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY &&\n\t (strm->param.dir & PJMEDIA_DIR_CAPTURE)) ||\n\t(cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY &&\n\t (strm->param.dir & PJMEDIA_DIR_PLAYBACK)))\n    {\n\tNSTimeInterval duration = *(unsigned *)pval;\n\tunsigned latency;\n\n\t/* For low-latency audio streaming, you can set this value to\n\t * as low as 5 ms (the default is 23ms). However, lowering the\n\t * latency may cause a decrease in audio quality.\n\t */\n\tduration /= 1000;\n\tif ([strm->sess setPreferredIOBufferDuration:duration error:nil]\n            != YES)\n        {\n\t    PJ_LOG(4, (THIS_FILE,\n\t\t       \"Error: cannot set the preferred buffer duration\"));\n\t    return PJMEDIA_EAUD_INVOP;\n\t}\n\t\n\tca_stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY, &latency);\n\tca_stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY, &latency);\n\t\n\treturn PJ_SUCCESS;\n    }\n\n#if USE_AUDIO_SESSION_API != 0\n\n    else if (cap==PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE &&\n\t       (strm->param.dir & PJMEDIA_DIR_CAPTURE))\n    {\n\tUInt32 btooth = *(pjmedia_aud_dev_route*)pval ==\n\t\t        PJMEDIA_AUD_DEV_ROUTE_BLUETOOTH ? 1 : 0;\n\tOSStatus ostatus;\n\n\tostatus = AudioSessionSetProperty (\n\t    kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,\n\t    sizeof(btooth), &btooth);\n\tif (ostatus != kAudioSessionNoError) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n\tstrm->param.input_route = *(pjmedia_aud_dev_route*)pval;\n\treturn PJ_SUCCESS;\n    } else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE &&\n\t       (strm->param.dir & PJMEDIA_DIR_PLAYBACK))\n    {\n\tOSStatus ostatus;\n\tUInt32 route = *(pjmedia_aud_dev_route*)pval ==\n\t\t       PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER ?\n\t\t       kAudioSessionOverrideAudioRoute_Speaker :\n\t\t       kAudioSessionOverrideAudioRoute_None;\n\n\tostatus = AudioSessionSetProperty (\n\t    kAudioSessionProperty_OverrideAudioRoute,\n\t    sizeof(route), &route);\n\tif (ostatus != kAudioSessionNoError) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n\tstrm->param.output_route = *(pjmedia_aud_dev_route*)pval;\n\treturn PJ_SUCCESS;\n    }\n#endif\n#endif\n\n    return PJMEDIA_EAUD_INVCAP;\n}\n\n/* API: Start stream. */\nstatic pj_status_t ca_stream_start(pjmedia_aud_stream *strm)\n{\n    struct coreaudio_stream *stream = (struct coreaudio_stream*)strm;\n    OSStatus ostatus;\n    UInt32 i;\n\n    if (stream->running)\n\treturn PJ_SUCCESS;\n\n    stream->quit_flag = 0;\n    stream->interrupted = PJ_FALSE;\n    stream->rec_buf_count = 0;\n    stream->play_buf_count = 0;\n    stream->resample_buf_count = 0;\n\n    if (stream->resample) {\n\tostatus = AudioConverterReset(stream->resample);\n\tif (ostatus != noErr)\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n    }\n\n#if !COREAUDIO_MAC\n    if ([stream->sess setActive:true error:nil] != YES) {\n\tPJ_LOG(4, (THIS_FILE, \"Warning: cannot activate audio session\"));\n    }\n#endif\n    \n    for (i = 0; i < 2; i++) {\n\tif (stream->io_units[i] == NULL) break;\n\tostatus = AudioOutputUnitStart(stream->io_units[i]);\n\tif (ostatus != noErr) {\n\t    if (i == 1)\n\t\tAudioOutputUnitStop(stream->io_units[0]);\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n    }\n\n    stream->running = PJ_TRUE;\n\n    PJ_LOG(4, (THIS_FILE, \"core audio stream started\"));\n\n    return PJ_SUCCESS;\n}\n\n/* API: Stop stream. */\nstatic pj_status_t ca_stream_stop(pjmedia_aud_stream *strm)\n{\n    struct coreaudio_stream *stream = (struct coreaudio_stream*)strm;\n    OSStatus ostatus;\n    unsigned i;\n    int should_deactivate;\n    struct stream_list *it, *itBegin;\n\n    if (!stream->running)\n\treturn PJ_SUCCESS;\n\n    for (i = 0; i < 2; i++) {\n\tif (stream->io_units[i] == NULL) break;\n\tostatus = AudioOutputUnitStop(stream->io_units[i]);\n\tif (ostatus != noErr) {\n\t    if (i == 0 && stream->io_units[1])\n\t\tAudioOutputUnitStop(stream->io_units[1]);\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(ostatus);\n\t}\n    }\n\n    /* Check whether we need to deactivate the audio session. */\n    pj_mutex_lock(stream->cf->mutex);\n    pj_assert(!pj_list_empty(&stream->cf->streams));\n    pj_assert(!pj_list_empty(&stream->list_entry));\n    stream->running = PJ_FALSE;\n    should_deactivate = PJ_TRUE;\n    itBegin = &stream->cf->streams;\n    for (it = itBegin->next; it != itBegin; it = it->next) {\n\tif (it->stream->running) {\n\t    should_deactivate = PJ_FALSE;\n\t    break;\n\t}\n    }\n    pj_mutex_unlock(stream->cf->mutex);\n\n#if !COREAUDIO_MAC\n    if (should_deactivate) {\n        if ([stream->sess \n             respondsToSelector:@selector(setActive:withOptions:error:)])\n        {\n  \t    [stream->sess setActive:NO\n  \t    withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation \n  \t    error:nil];\n\t} else {\n\t    if ([stream->sess setActive:NO error:nil] != YES) {\n            \tPJ_LOG(4, (THIS_FILE, \"Warning: cannot deactivate \"\n            \t\t\t      \"audio session\"));\n            }\n        }\n    }\n#endif\n\n    stream->quit_flag = 1;\n    stream->play_thread_initialized = 0;\n    stream->rec_thread_initialized = 0;\n    pj_bzero(stream->rec_thread_desc, sizeof(pj_thread_desc));\n    pj_bzero(stream->play_thread_desc, sizeof(pj_thread_desc));\n\n    PJ_LOG(4, (THIS_FILE, \"core audio stream stopped\"));\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: Destroy stream. */\nstatic pj_status_t ca_stream_destroy(pjmedia_aud_stream *strm)\n{\n    struct coreaudio_stream *stream = (struct coreaudio_stream*)strm;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n\n    ca_stream_stop(strm);\n\n    for (i = 0; i < 2; i++) {\n\tif (stream->io_units[i]) {\n\t    AudioUnitUninitialize(stream->io_units[i]);\n\t    AudioComponentInstanceDispose(stream->io_units[i]);\n\t    stream->io_units[i] = NULL;\n\t}\n    }\n\n    if (stream->resample)\n\tAudioConverterDispose(stream->resample);\n\n    pj_mutex_lock(stream->cf->mutex);\n    if (!pj_list_empty(&stream->list_entry))\n\tpj_list_erase(&stream->list_entry);\n    pj_mutex_unlock(stream->cf->mutex);\n\n    pj_pool_release(stream->pool);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_AUDIO_DEV_HAS_COREAUDIO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-audiodev/errno.c",
    "content": "/* $Id: errno.c 4432 2013-03-08 08:02:48Z riza $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-audiodev/errno.h>\n#include <pj/string.h>\n#include <pj/unicode.h>\n#if PJMEDIA_AUDIO_DEV_HAS_WMME\n#   ifdef _MSC_VER\n#\tpragma warning(push, 3)\n#   endif\n#   include <windows.h>\n#   include <mmsystem.h>\n#   ifdef _MSC_VER\n#\tpragma warning(pop)\n#   endif\n#endif\n\n/* PJMEDIA-Audiodev's own error codes/messages \n * MUST KEEP THIS ARRAY SORTED!!\n * Message must be limited to 64 chars!\n */\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n\nstatic const struct \n{\n    int code;\n    const char *msg;\n} err_str[] = \n{\n    PJ_BUILD_ERR( PJMEDIA_EAUD_ERR,\t    \"Unspecified audio device error\" ),\n    PJ_BUILD_ERR( PJMEDIA_EAUD_SYSERR,\t    \"Unknown error from audio driver\" ),\n    PJ_BUILD_ERR( PJMEDIA_EAUD_INIT,\t    \"Audio subsystem not initialized\" ),\n    PJ_BUILD_ERR( PJMEDIA_EAUD_INVDEV,\t    \"Invalid audio device\" ),\n    PJ_BUILD_ERR( PJMEDIA_EAUD_NODEV,\t    \"Found no audio devices\" ),\n    PJ_BUILD_ERR( PJMEDIA_EAUD_NODEFDEV,    \"Unable to find default audio device\" ),\n    PJ_BUILD_ERR( PJMEDIA_EAUD_NOTREADY,    \"Audio device not ready\" ),\n    PJ_BUILD_ERR( PJMEDIA_EAUD_INVCAP,\t    \"Invalid or unsupported audio capability\" ),\n    PJ_BUILD_ERR( PJMEDIA_EAUD_INVOP,\t    \"Invalid or unsupported audio device operation\" ),\n    PJ_BUILD_ERR( PJMEDIA_EAUD_BADFORMAT,   \"Bad or invalid audio device format\" ),\n    PJ_BUILD_ERR( PJMEDIA_EAUD_SAMPFORMAT,  \"Invalid audio device sample format\"),\n    PJ_BUILD_ERR( PJMEDIA_EAUD_BADLATENCY,  \"Bad audio latency setting\")\n\n};\n\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n\n\n/*\n * pjmedia_audiodev_strerror()\n */\nPJ_DEF(pj_str_t) pjmedia_audiodev_strerror(pj_status_t statcode, \n\t\t\t\t\t   char *buf, pj_size_t bufsize )\n{\n    pj_str_t errstr;\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n\n\n    /* See if the error comes from Core Audio. */\n#if PJMEDIA_AUDIO_DEV_HAS_COREAUDIO\n    if (statcode >= PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_START &&\n\tstatcode <= PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_END)\n    {\n\tint ca_err = PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_START - statcode;\n\n\tPJ_UNUSED_ARG(ca_err);\n\t// TODO: create more helpful error messages\n\terrstr.ptr = buf;\n\tpj_strcpy2(&errstr, \"Core audio error\");\n\treturn errstr;\n    } else\n#endif\n\n    /* See if the error comes from WMME */\n#if PJMEDIA_AUDIO_DEV_HAS_WMME\n    if ((statcode >= PJMEDIA_AUDIODEV_WMME_IN_ERROR_START &&\n\t statcode < PJMEDIA_AUDIODEV_WMME_IN_ERROR_END) ||\n\t(statcode >= PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START &&\n\t statcode < PJMEDIA_AUDIODEV_WMME_OUT_ERROR_END))\n    {\n\tMMRESULT native_err, mr;\n\tMMRESULT (WINAPI *waveGetErrText)(UINT mmrError, LPTSTR pszText, UINT cchText);\n\tPJ_DECL_UNICODE_TEMP_BUF(wbuf, 80)\n\n\tif (statcode >= PJMEDIA_AUDIODEV_WMME_IN_ERROR_START &&\n\t    statcode <= PJMEDIA_AUDIODEV_WMME_IN_ERROR_END)\n\t{\n\t    native_err = statcode - PJMEDIA_AUDIODEV_WMME_IN_ERROR_START;\n\t    waveGetErrText = &waveInGetErrorText;\n\t} else {\n\t    native_err = statcode - PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START;\n\t    waveGetErrText = &waveOutGetErrorText;\n\t}\n\n#if PJ_NATIVE_STRING_IS_UNICODE\n\tmr = (*waveGetErrText)(native_err, wbuf, PJ_ARRAY_SIZE(wbuf));\n\tif (mr == MMSYSERR_NOERROR) {\n\t    int len = wcslen(wbuf);\n\t    pj_unicode_to_ansi(wbuf, len, buf, bufsize);\n\t}\n#else\n\tmr = (*waveGetErrText)(native_err, buf, (UINT)bufsize);\n#endif\n\n\tif (mr==MMSYSERR_NOERROR) {\n\t    errstr.ptr = buf;\n\t    errstr.slen = pj_ansi_strlen(buf);\n\t    return errstr;\n\t} else {\n\t    pj_ansi_snprintf(buf, bufsize, \"MMSYSTEM native error %d\", \n\t\t\t     native_err);\n\t    return pj_str(buf);\n\t}\n\n    } else\n#endif\n\n/* See if the error comes from BDIMAD */\n#if PJMEDIA_AUDIO_DEV_HAS_BDIMAD\n\t\n\tif (statcode >= PJMEDIA_AUDIODEV_BDIMAD_ERROR_START &&\n\t    statcode <  PJMEDIA_AUDIODEV_BDIMAD_ERROR_END)\n\t{\n\t    pj_status_t native_err;\n\t    native_err = statcode - PJMEDIA_AUDIODEV_BDIMAD_ERROR_START;\n\n\t    pj_ansi_snprintf(buf, bufsize, \"BDIMAD native error %d\", native_err);\n\t    return pj_str(buf);\n\t} else\n#endif\n\n    /* Audiodev error */\n    if (statcode >= PJMEDIA_AUDIODEV_ERRNO_START && \n\tstatcode < PJMEDIA_AUDIODEV_ERRNO_END)\n    {\n\t/* Find the error in the table.\n\t * Use binary search!\n\t */\n\tint first = 0;\n\tint n = PJ_ARRAY_SIZE(err_str);\n\n\twhile (n > 0) {\n\t    int half = n/2;\n\t    int mid = first + half;\n\n\t    if (err_str[mid].code < statcode) {\n\t\tfirst = mid+1;\n\t\tn -= (half+1);\n\t    } else if (err_str[mid].code > statcode) {\n\t\tn = half;\n\t    } else {\n\t\tfirst = mid;\n\t\tbreak;\n\t    }\n\t}\n\n\n\tif (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {\n\t    pj_str_t msg;\n\t    \n\t    msg.ptr = (char*)err_str[first].msg;\n\t    msg.slen = pj_ansi_strlen(err_str[first].msg);\n\n\t    errstr.ptr = buf;\n\t    pj_strncpy_with_null(&errstr, &msg, bufsize);\n\t    return errstr;\n\n\t} \n    } \n#endif\t/* PJ_HAS_ERROR_STRING */\n\n    /* Error not found. */\n    errstr.ptr = buf;\n    errstr.slen = pj_ansi_snprintf(buf, bufsize, \n\t\t\t\t   \"Unknown pjmedia-audiodev error %d\",\n\t\t\t\t   statcode);\n    if (errstr.slen < 1 || errstr.slen >= (pj_ssize_t)bufsize)\n\terrstr.slen = bufsize - 1;\n    return errstr;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-audiodev/null_dev.c",
    "content": "/* $Id: null_dev.c 3553 2011-05-05 06:14:19Z nanang $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia-audiodev/audiodev_imp.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n\n#if PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO\n\n#define THIS_FILE\t\t\"null_dev.c\"\n\n/* null_audio device info */\nstruct null_audio_dev_info\n{\n    pjmedia_aud_dev_info\t info;\n    unsigned\t\t\t dev_id;\n};\n\n/* null_audio factory */\nstruct null_audio_factory\n{\n    pjmedia_aud_dev_factory\t base;\n    pj_pool_t\t\t\t*pool;\n    pj_pool_factory\t\t*pf;\n\n    unsigned\t\t\t dev_count;\n    struct null_audio_dev_info\t*dev_info;\n};\n\n/* Sound stream. */\nstruct null_audio_stream\n{\n    pjmedia_aud_stream\t base;\t\t    /**< Base stream\t       */\n    pjmedia_aud_param\t param;\t\t    /**< Settings\t       */\n    pj_pool_t           *pool;              /**< Memory pool.          */\n\n    pjmedia_aud_rec_cb   rec_cb;            /**< Capture callback.     */\n    pjmedia_aud_play_cb  play_cb;           /**< Playback callback.    */\n    void                *user_data;         /**< Application data.     */\n};\n\n\n/* Prototypes */\nstatic pj_status_t null_factory_init(pjmedia_aud_dev_factory *f);\nstatic pj_status_t null_factory_destroy(pjmedia_aud_dev_factory *f);\nstatic pj_status_t null_factory_refresh(pjmedia_aud_dev_factory *f);\nstatic unsigned    null_factory_get_dev_count(pjmedia_aud_dev_factory *f);\nstatic pj_status_t null_factory_get_dev_info(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_aud_dev_info *info);\nstatic pj_status_t null_factory_default_param(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t      unsigned index,\n\t\t\t\t\t      pjmedia_aud_param *param);\nstatic pj_status_t null_factory_create_stream(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t      const pjmedia_aud_param *param,\n\t\t\t\t\t      pjmedia_aud_rec_cb rec_cb,\n\t\t\t\t\t      pjmedia_aud_play_cb play_cb,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      pjmedia_aud_stream **p_aud_strm);\n\nstatic pj_status_t null_stream_get_param(pjmedia_aud_stream *strm,\n\t\t\t\t\t pjmedia_aud_param *param);\nstatic pj_status_t null_stream_get_cap(pjmedia_aud_stream *strm,\n\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t       void *value);\nstatic pj_status_t null_stream_set_cap(pjmedia_aud_stream *strm,\n\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t       const void *value);\nstatic pj_status_t null_stream_start(pjmedia_aud_stream *strm);\nstatic pj_status_t null_stream_stop(pjmedia_aud_stream *strm);\nstatic pj_status_t null_stream_destroy(pjmedia_aud_stream *strm);\n\n/* Operations */\nstatic pjmedia_aud_dev_factory_op factory_op =\n{\n    &null_factory_init,\n    &null_factory_destroy,\n    &null_factory_get_dev_count,\n    &null_factory_get_dev_info,\n    &null_factory_default_param,\n    &null_factory_create_stream,\n    &null_factory_refresh\n};\n\nstatic pjmedia_aud_stream_op stream_op =\n{\n    &null_stream_get_param,\n    &null_stream_get_cap,\n    &null_stream_set_cap,\n    &null_stream_start,\n    &null_stream_stop,\n    &null_stream_destroy\n};\n\n\n/****************************************************************************\n * Factory operations\n */\n/*\n * Init null_audio audio driver.\n */\npjmedia_aud_dev_factory* pjmedia_null_audio_factory(pj_pool_factory *pf)\n{\n    struct null_audio_factory *f;\n    pj_pool_t *pool;\n\n    pool = pj_pool_create(pf, \"null audio\", 1000, 1000, NULL);\n    f = PJ_POOL_ZALLOC_T(pool, struct null_audio_factory);\n    f->pf = pf;\n    f->pool = pool;\n    f->base.op = &factory_op;\n\n    return &f->base;\n}\n\n\n/* API: init factory */\nstatic pj_status_t null_factory_init(pjmedia_aud_dev_factory *f)\n{\n    struct null_audio_factory *nf = (struct null_audio_factory*)f;\n    struct null_audio_dev_info *ndi;\n\n    /* Initialize input and output devices here */\n    nf->dev_count = 1;\n    nf->dev_info = (struct null_audio_dev_info*)\n \t\t   pj_pool_calloc(nf->pool, nf->dev_count,\n \t\t\t\t  sizeof(struct null_audio_dev_info));\n    ndi = &nf->dev_info[0];\n    pj_bzero(ndi, sizeof(*ndi));\n    strcpy(ndi->info.name, \"null device\");\n    strcpy(ndi->info.driver, \"null\");\n    ndi->info.input_count = 1;\n    ndi->info.output_count = 1;\n    ndi->info.default_samples_per_sec = 16000;\n    /* Set the device capabilities here */\n    ndi->info.caps = 0;\n\n    PJ_LOG(4, (THIS_FILE, \"null audio initialized\"));\n\n    return PJ_SUCCESS;\n}\n\n/* API: destroy factory */\nstatic pj_status_t null_factory_destroy(pjmedia_aud_dev_factory *f)\n{\n    struct null_audio_factory *nf = (struct null_audio_factory*)f;\n    pj_pool_t *pool = nf->pool;\n\n    nf->pool = NULL;\n    pj_pool_release(pool);\n\n    return PJ_SUCCESS;\n}\n\n/* API: refresh the list of devices */\nstatic pj_status_t null_factory_refresh(pjmedia_aud_dev_factory *f)\n{\n    PJ_UNUSED_ARG(f);\n    return PJ_SUCCESS;\n}\n\n/* API: get number of devices */\nstatic unsigned null_factory_get_dev_count(pjmedia_aud_dev_factory *f)\n{\n    struct null_audio_factory *nf = (struct null_audio_factory*)f;\n    return nf->dev_count;\n}\n\n/* API: get device info */\nstatic pj_status_t null_factory_get_dev_info(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_aud_dev_info *info)\n{\n    struct null_audio_factory *nf = (struct null_audio_factory*)f;\n\n    PJ_ASSERT_RETURN(index < nf->dev_count, PJMEDIA_EAUD_INVDEV);\n\n    pj_memcpy(info, &nf->dev_info[index].info, sizeof(*info));\n\n    return PJ_SUCCESS;\n}\n\n/* API: create default device parameter */\nstatic pj_status_t null_factory_default_param(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t      unsigned index,\n\t\t\t\t\t      pjmedia_aud_param *param)\n{\n    struct null_audio_factory *nf = (struct null_audio_factory*)f;\n    struct null_audio_dev_info *di = &nf->dev_info[index];\n\n    PJ_ASSERT_RETURN(index < nf->dev_count, PJMEDIA_EAUD_INVDEV);\n\n    pj_bzero(param, sizeof(*param));\n    if (di->info.input_count && di->info.output_count) {\n\tparam->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;\n\tparam->rec_id = index;\n\tparam->play_id = index;\n    } else if (di->info.input_count) {\n\tparam->dir = PJMEDIA_DIR_CAPTURE;\n\tparam->rec_id = index;\n\tparam->play_id = PJMEDIA_AUD_INVALID_DEV;\n    } else if (di->info.output_count) {\n\tparam->dir = PJMEDIA_DIR_PLAYBACK;\n\tparam->play_id = index;\n\tparam->rec_id = PJMEDIA_AUD_INVALID_DEV;\n    } else {\n\treturn PJMEDIA_EAUD_INVDEV;\n    }\n\n    /* Set the mandatory settings here */\n    /* The values here are just some examples */\n    param->clock_rate = di->info.default_samples_per_sec;\n    param->channel_count = 1;\n    param->samples_per_frame = di->info.default_samples_per_sec * 20 / 1000;\n    param->bits_per_sample = 16;\n\n    /* Set the device capabilities here */\n    param->flags = 0;\n\n    return PJ_SUCCESS;\n}\n\n/* API: create stream */\nstatic pj_status_t null_factory_create_stream(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t      const pjmedia_aud_param *param,\n\t\t\t\t\t      pjmedia_aud_rec_cb rec_cb,\n\t\t\t\t\t      pjmedia_aud_play_cb play_cb,\n\t\t\t\t\t      void *user_data,\n\t\t\t\t\t      pjmedia_aud_stream **p_aud_strm)\n{\n    struct null_audio_factory *nf = (struct null_audio_factory*)f;\n    pj_pool_t *pool;\n    struct null_audio_stream *strm;\n\n    /* Create and Initialize stream descriptor */\n    pool = pj_pool_create(nf->pf, \"null_audio-dev\", 1000, 1000, NULL);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    strm = PJ_POOL_ZALLOC_T(pool, struct null_audio_stream);\n    pj_memcpy(&strm->param, param, sizeof(*param));\n    strm->pool = pool;\n    strm->rec_cb = rec_cb;\n    strm->play_cb = play_cb;\n    strm->user_data = user_data;\n\n    /* Create player stream here */\n    if (param->dir & PJMEDIA_DIR_PLAYBACK) {\n    }\n\n    /* Create capture stream here */\n    if (param->dir & PJMEDIA_DIR_CAPTURE) {\n    }\n\n    /* Apply the remaining settings */\n    /* Below is an example if you want to set the output volume */\n    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING) {\n\tnull_stream_set_cap(&strm->base,\n\t\t            PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,\n\t\t            &param->output_vol);\n    }\n\n    /* Done */\n    strm->base.op = &stream_op;\n    *p_aud_strm = &strm->base;\n\n    return PJ_SUCCESS;\n}\n\n/* API: Get stream info. */\nstatic pj_status_t null_stream_get_param(pjmedia_aud_stream *s,\n\t\t\t\t\t pjmedia_aud_param *pi)\n{\n    struct null_audio_stream *strm = (struct null_audio_stream*)s;\n\n    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);\n\n    pj_memcpy(pi, &strm->param, sizeof(*pi));\n\n    /* Example: Update the volume setting */\n    if (null_stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,\n\t\t\t    &pi->output_vol) == PJ_SUCCESS)\n    {\n        pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: get capability */\nstatic pj_status_t null_stream_get_cap(pjmedia_aud_stream *s,\n\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t       void *pval)\n{\n    struct null_audio_stream *strm = (struct null_audio_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    /* Example: Get the output's volume setting */\n    if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING)\n    {\n\t/* Output volume setting */\n\t*(unsigned*)pval = 0; // retrieve output device's volume here\n\treturn PJ_SUCCESS;\n    } else {\n\treturn PJMEDIA_EAUD_INVCAP;\n    }\n}\n\n/* API: set capability */\nstatic pj_status_t null_stream_set_cap(pjmedia_aud_stream *s,\n\t\t\t\t       pjmedia_aud_dev_cap cap,\n\t\t\t\t       const void *pval)\n{\n    struct null_audio_stream *strm = (struct null_audio_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    /* Example */\n    if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING)\n    {\n\t/* Output volume setting */\n\t// set output's volume level here\n\treturn PJ_SUCCESS;\n    }\n\n    return PJMEDIA_EAUD_INVCAP;\n}\n\n/* API: Start stream. */\nstatic pj_status_t null_stream_start(pjmedia_aud_stream *strm)\n{\n    struct null_audio_stream *stream = (struct null_audio_stream*)strm;\n\n    PJ_UNUSED_ARG(stream);\n\n    PJ_LOG(4, (THIS_FILE, \"Starting null audio stream\"));\n\n    return PJ_SUCCESS;\n}\n\n/* API: Stop stream. */\nstatic pj_status_t null_stream_stop(pjmedia_aud_stream *strm)\n{\n    struct null_audio_stream *stream = (struct null_audio_stream*)strm;\n\n    PJ_UNUSED_ARG(stream);\n\n    PJ_LOG(4, (THIS_FILE, \"Stopping null audio stream\"));\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: Destroy stream. */\nstatic pj_status_t null_stream_destroy(pjmedia_aud_stream *strm)\n{\n    struct null_audio_stream *stream = (struct null_audio_stream*)strm;\n\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n\n    null_stream_stop(strm);\n\n    pj_pool_release(stream->pool);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-audiodev/wmme_dev.c",
    "content": "/* $Id: wmme_dev.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-audiodev/audiodev_imp.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/string.h>\n#include <pj/unicode.h>\n\n#if PJMEDIA_AUDIO_DEV_HAS_WMME\n\n#ifdef _MSC_VER\n#   pragma warning(push, 3)\n#endif\n\n#include <windows.h>\n#include <dbt.h>\n#include <mmsystem.h>\n#include <mmreg.h>\n\n#ifdef _MSC_VER\n#   pragma warning(pop)\n#endif\n\n#ifndef PJMEDIA_WMME_DEV_USE_MMDEVICE_API\n#   if defined(_WIN32_WINNT) && (_WIN32_WINNT>=0x0600)\n#      define PJMEDIA_WMME_DEV_USE_MMDEVICE_API 1\n#   else\n#      define PJMEDIA_WMME_DEV_USE_MMDEVICE_API 0\n#   endif\n#endif\n\n#if PJMEDIA_WMME_DEV_USE_MMDEVICE_API != 0\n#   define DRV_QUERYFUNCTIONINSTANCEID     (DRV_RESERVED + 17)\n#   define DRV_QUERYFUNCTIONINSTANCEIDSIZE (DRV_RESERVED + 18)\n#endif\n\n/* mingw lacks WAVE_FORMAT_ALAW/MULAW */\n#ifndef WAVE_FORMAT_ALAW\n#   define  WAVE_FORMAT_ALAW       0x0006\n#endif\n#ifndef WAVE_FORMAT_MULAW\n#   define  WAVE_FORMAT_MULAW      0x0007\n#endif\n\n#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0\n#   pragma comment(lib, \"Coredll.lib\")\n#elif defined(_MSC_VER)\n#   pragma comment(lib, \"winmm.lib\")\n#endif\n\n\n#define THIS_FILE\t\t\t\"wmme_dev.c\"\n\n/* WMME device change observer */\nstruct wmme_dev_observer\n{\n    pj_thread_t                         *thread;\n    pj_pool_t                           *pool;\n    pjmedia_aud_dev_change_callback      cb;\n    HWND                                 hWnd;\n};\n\n/* WMME device info */\nstruct wmme_dev_info\n{\n    pjmedia_aud_dev_info\t info;\n    unsigned\t\t\t deviceId;\n    const wchar_t\t\t*endpointId;\n};\n\n/* WMME factory */\nstruct wmme_factory\n{\n    pjmedia_aud_dev_factory\t base;\n    pj_pool_t\t\t\t*base_pool;\n    pj_pool_t\t\t\t*pool;\n    pj_pool_factory\t\t*pf;\n\n    unsigned\t\t\t dev_count;\n    struct wmme_dev_info\t*dev_info;\n\n    struct wmme_dev_observer     dev_observer;\n};\n\n\n/* Individual WMME capture/playback stream descriptor */\nstruct wmme_channel\n{\n    union\n    {\n\tHWAVEIN   In;\n\tHWAVEOUT  Out;\n    } hWave;\n\n    WAVEHDR      *WaveHdr;\n    HANDLE        hEvent;\n    DWORD         dwBufIdx;\n    DWORD         dwMaxBufIdx;\n    pj_timestamp  timestamp;\n};\n\n\n/* Sound stream. */\nstruct wmme_stream\n{\n    pjmedia_aud_stream\t base;\t\t    /**< Base stream\t       */\n    pjmedia_aud_param\t param;\t\t    /**< Settings\t       */\n    pj_pool_t           *pool;              /**< Memory pool.          */\n\n    pjmedia_aud_rec_cb   rec_cb;            /**< Capture callback.     */\n    pjmedia_aud_play_cb  play_cb;           /**< Playback callback.    */\n    void                *user_data;         /**< Application data.     */\n\n    struct wmme_channel  play_strm;         /**< Playback stream.      */\n    struct wmme_channel  rec_strm;          /**< Capture stream.       */\n\n    void    \t\t*buffer;\t    /**< Temp. frame buffer.   */\n    pjmedia_format_id\t fmt_id;\t    /**< Frame format\t       */\n    pj_uint8_t\t\t silence_char;\t    /**< Silence pattern       */\n    unsigned\t\t bytes_per_frame;   /**< Bytes per frame       */\n\n    pjmedia_frame_ext\t*xfrm;\t\t    /**< Extended frame buffer */\n    unsigned\t\t xfrm_size;\t    /**< Total ext frm size    */\n\n    pj_thread_t         *thread;            /**< Thread handle.        */\n    HANDLE               thread_quit_event; /**< Quit signal to thread */\n};\n\n\n/* Prototypes */\nstatic pj_status_t factory_init(pjmedia_aud_dev_factory *f);\nstatic pj_status_t factory_destroy(pjmedia_aud_dev_factory *f);\nstatic pj_status_t factory_refresh(pjmedia_aud_dev_factory *f);\nstatic unsigned    factory_get_dev_count(pjmedia_aud_dev_factory *f);\nstatic pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f, \n\t\t\t\t\tunsigned index,\n\t\t\t\t\tpjmedia_aud_dev_info *info);\nstatic pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t unsigned index,\n\t\t\t\t\t pjmedia_aud_param *param);\nstatic pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t const pjmedia_aud_param *param,\n\t\t\t\t\t pjmedia_aud_rec_cb rec_cb,\n\t\t\t\t\t pjmedia_aud_play_cb play_cb,\n\t\t\t\t\t void *user_data,\n\t\t\t\t\t pjmedia_aud_stream **p_aud_strm);\nstatic void factory_set_observer(pjmedia_aud_dev_factory *f,\n                                 pjmedia_aud_dev_change_callback cb);\nstatic int factory_get_default_rec_dev(pjmedia_aud_dev_factory *f);\nstatic int factory_get_default_play_dev(pjmedia_aud_dev_factory *f);\n\n\nstatic pj_status_t stream_get_param(pjmedia_aud_stream *strm,\n\t\t\t\t    pjmedia_aud_param *param);\nstatic pj_status_t stream_get_cap(pjmedia_aud_stream *strm,\n\t\t\t\t  pjmedia_aud_dev_cap cap,\n\t\t\t\t  void *value);\nstatic pj_status_t stream_set_cap(pjmedia_aud_stream *strm,\n\t\t\t\t  pjmedia_aud_dev_cap cap,\n\t\t\t\t  const void *value);\nstatic pj_status_t stream_start(pjmedia_aud_stream *strm);\nstatic pj_status_t stream_stop(pjmedia_aud_stream *strm);\nstatic pj_status_t stream_destroy(pjmedia_aud_stream *strm);\n\n\n/* Operations */\nstatic pjmedia_aud_dev_factory_op factory_op =\n{\n    &factory_init,\n    &factory_destroy,\n    &factory_get_dev_count,\n    &factory_get_dev_info,\n    &factory_default_param,\n    &factory_create_stream,\n    &factory_refresh,\n    &factory_set_observer,\n    &factory_get_default_rec_dev,\n    &factory_get_default_play_dev\n};\n\nstatic pjmedia_aud_stream_op stream_op = \n{\n    &stream_get_param,\n    &stream_get_cap,\n    &stream_set_cap,\n    &stream_start,\n    &stream_stop,\n    &stream_destroy\n};\n\n\n/****************************************************************************\n * Factory operations\n */\n/*\n * Init WMME audio driver.\n */\npjmedia_aud_dev_factory* pjmedia_wmme_factory(pj_pool_factory *pf)\n{\n    struct wmme_factory *f;\n    pj_pool_t *pool;\n\n    pool = pj_pool_create(pf, \"WMME base\", 1000, 1000, NULL);\n    f = PJ_POOL_ZALLOC_T(pool, struct wmme_factory);\n    f->pf = pf;\n    f->base_pool = pool;\n    f->base.op = &factory_op;\n\n    return &f->base;\n}\n\n/* Internal: Windows Vista and Windows 7 have their device\n * names truncated when using the waveXXX api.  The names\n * should be acquired from the MMDevice APIs\n */\n#if PJMEDIA_WMME_DEV_USE_MMDEVICE_API != 0\n\n#define COBJMACROS\n#include <mmdeviceapi.h>\n#define INITGUID\n#include <Guiddef.h>\n#include <FunctionDiscoveryKeys_devpkey.h>\n\nDEFINE_GUID(CLSID_MMDeviceEnumerator, 0xBCDE0395, 0xE52F, 0x467C,\n\t    0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E);\nDEFINE_GUID(IID_IMMDeviceEnumerator, 0xA95664D2, 0x9614, 0x4F35,\n\t    0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6);\n\nstatic void get_dev_names(pjmedia_aud_dev_factory *f)\n{\n    struct wmme_factory *wf = (struct wmme_factory*)f;\n    HRESULT              coinit = S_OK;\n    HRESULT              hr = S_OK;\n    IMMDeviceEnumerator *pEnumerator = NULL;\n    IMMDeviceCollection *pDevices = NULL;\n    UINT                 cDevices = 0;\n    UINT                 nDevice = 0;\n\n    coinit = CoInitializeEx(NULL, COINIT_MULTITHREADED);\n    if (coinit == RPC_E_CHANGED_MODE)\n\tcoinit = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);\n    if (FAILED(coinit))\n\tgoto on_error;\n\n    hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,\n\t\t\t  CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator,\n\t\t\t  (void**)&pEnumerator);\n    if (FAILED(hr))\n\tgoto on_error;\n    hr = IMMDeviceEnumerator_EnumAudioEndpoints(pEnumerator, eAll,\n\t\t\t\t\t\tDEVICE_STATE_ACTIVE,\n\t\t\t\t\t\t&pDevices);\n    if (FAILED(hr))\n\tgoto on_error;\n    hr = IMMDeviceCollection_GetCount(pDevices, &cDevices);\n    if (FAILED(hr))\n\tgoto on_error;\n\n    for (nDevice = 0; nDevice < cDevices; ++nDevice) {\n\tIMMDevice      *pDevice = NULL;\n\tIPropertyStore *pProps = NULL;\n\tLPWSTR          pwszID = NULL;\n\tPROPVARIANT     varName;\n\tunsigned        i;\n\n\tPropVariantInit(&varName);\n\n\thr = IMMDeviceCollection_Item(pDevices, nDevice, &pDevice);\n\tif (FAILED(hr))\n\t    goto cleanup;\n\thr = IMMDevice_GetId(pDevice, &pwszID);\n\tif (FAILED(hr))\n\t    goto cleanup;\n\thr = IMMDevice_OpenPropertyStore(pDevice, STGM_READ, &pProps);\n\tif (FAILED(hr))\n\t    goto cleanup;\n\thr = IPropertyStore_GetValue(pProps, &PKEY_Device_FriendlyName,\n\t\t\t\t     &varName);\n\tif (FAILED(hr))\n\t    goto cleanup;\n\n\tfor (i = 0; i < wf->dev_count; ++i) {\n\t    if (0 == wcscmp(wf->dev_info[i].endpointId, pwszID)) {\n\t\tpj_unicode_to_ansi(varName.pwszVal, \n\t\t\t\t   wcslen(varName.pwszVal), \n\t\t\t\t   wf->dev_info[i].info.name, \n\t\t\t\t   sizeof(wf->dev_info[i].info.name));\n\n\t\tbreak;\n\t    }\n\t}\n\n\tPropVariantClear(&varName);\n\n    cleanup:\n\tif (pProps)\n\t    IPropertyStore_Release(pProps);\n\tif (pwszID)\n\t    CoTaskMemFree(pwszID);\n\tif (pDevice)\n\t    hr = IMMDevice_Release(pDevice);\n    }\n\non_error:\n    if (pDevices)\n\thr = IMMDeviceCollection_Release(pDevices);\n\n    if (pEnumerator)\n\thr = IMMDeviceEnumerator_Release(pEnumerator);\n\n    if (SUCCEEDED(coinit))\n\tCoUninitialize();\n}\n\n#else\n\nstatic void get_dev_names(pjmedia_aud_dev_factory *f)\n{\n    PJ_UNUSED_ARG(f);\n}\n\n#endif\n\n/* Internal: build device info from WAVEINCAPS/WAVEOUTCAPS */\nstatic void build_dev_info(UINT deviceId, struct wmme_dev_info *wdi, \n\t\t\t   const WAVEINCAPS *wic, const WAVEOUTCAPS *woc)\n{\n#define WIC_WOC(wic,woc,field)\t(wic? wic->field : woc->field)\n\n    pj_bzero(wdi, sizeof(*wdi));\n    wdi->deviceId = deviceId;\n\n    /* Device Name */\n    if (deviceId==WAVE_MAPPER) {\n\tstrncpy(wdi->info.name, \"Wave mapper\", sizeof(wdi->info.name));\n\twdi->info.name[sizeof(wdi->info.name)-1] = '\\0';\n    } else {\n\tconst pj_char_t *szPname = WIC_WOC(wic, woc, szPname);\n\tPJ_DECL_ANSI_TEMP_BUF(wTmp, sizeof(wdi->info.name));\n\t\n\tstrncpy(wdi->info.name, \n\t\tPJ_NATIVE_TO_STRING(szPname, wTmp, PJ_ARRAY_SIZE(wTmp)),\n\t\tsizeof(wdi->info.name));\n\twdi->info.name[sizeof(wdi->info.name)-1] = '\\0';\n    }\n\n    wdi->info.default_samples_per_sec = 16000;\n    strcpy(wdi->info.driver, \"WMME\");\n\n    if (wic) {\n\twdi->info.input_count = wic->wChannels;\n\twdi->info.caps |= PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY;\n\n\t/* Sometimes a device can return a rediculously large number of \n\t * channels. This happened with an SBLive card on a Windows ME box.\n\t * It also happens on Win XP!\n\t */\n\tif (wdi->info.input_count<1 || wdi->info.input_count>256) {\n\t    wdi->info.input_count = 2;\n\t}\n    }\n\n    if (woc) {\n\twdi->info.output_count = woc->wChannels;\n\twdi->info.caps |= PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;\n\t\n\tif (woc->dwSupport & WAVECAPS_VOLUME) {\n\t    wdi->info.caps |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;\n\t}\n\n\t/* Sometimes a device can return a rediculously large number of \n\t * channels. This happened with an SBLive card on a Windows ME box.\n\t * It also happens on Win XP!\n\t */\n\tif (wdi->info.output_count<1 || wdi->info.output_count>256) {\n\t    wdi->info.output_count = 2;\n\t}\n    }\n\n    /* Extended formats */\n    wdi->info.caps |= PJMEDIA_AUD_DEV_CAP_EXT_FORMAT;\n    wdi->info.ext_fmt_cnt = 2;\n    pjmedia_format_init_audio(&wdi->info.ext_fmt[0],\n\t\t\t      PJMEDIA_FORMAT_PCMU, 8000, 1, 8,\n\t\t\t      20000, 64000, 64000);\n    pjmedia_format_init_audio(&wdi->info.ext_fmt[0],\n\t\t\t      PJMEDIA_FORMAT_PCMA, 8000, 1, 8,\n\t\t\t      20000, 64000, 64000);\n}\n\n/* API: init factory */\nstatic pj_status_t factory_init(pjmedia_aud_dev_factory *f)\n{\n    pj_status_t ret = factory_refresh(f);\n    if (ret != PJ_SUCCESS)\n\treturn ret;\n\n    PJ_LOG(4, (THIS_FILE, \"WMME initialized\"));\n    return PJ_SUCCESS;\n}\n\n/* API: refresh the device list */\nstatic pj_status_t factory_refresh(pjmedia_aud_dev_factory *f)\n{\n    struct wmme_factory *wf = (struct wmme_factory*)f;\n    unsigned c;\n    int i;\n    int inputDeviceCount, outputDeviceCount, devCount=0;\n    pj_bool_t waveMapperAdded = PJ_FALSE;\n\n    if (wf->pool != NULL) {\n\tpj_pool_release(wf->pool);\n\twf->pool = NULL;\n    }\n\n    /* Enumerate sound devices */\n    wf->dev_count = 0;\n    wf->pool = pj_pool_create(wf->pf, \"WMME\", 1000, 1000, NULL);\n\n    inputDeviceCount = waveInGetNumDevs();\n    devCount += inputDeviceCount;\n\n    outputDeviceCount = waveOutGetNumDevs();\n    devCount += outputDeviceCount;\n\n    if (devCount) {\n\t/* Assume there is WAVE_MAPPER */\n\tdevCount += 2;\n    }\n\n    if (devCount==0) {\n\tPJ_LOG(4,(THIS_FILE, \"WMME found no sound devices\"));\n\t/* Enabling this will cause pjsua-lib initialization to fail when there\n\t * is no sound device installed in the system, even when pjsua has been\n\t * run with --null-audio. Moreover, it might be better to think that\n\t * the WMME backend initialization is successfull, regardless there is\n\t * no audio device installed, as later application can check it using \n\t * get_dev_count().\n\treturn PJMEDIA_EAUD_NODEV;\n\t */\n\treturn PJ_SUCCESS;\n    }\n\n    wf->dev_info = (struct wmme_dev_info*)\n\t\t   pj_pool_calloc(wf->pool, devCount, \n\t\t\t\t  sizeof(struct wmme_dev_info));\n\n    if (inputDeviceCount && outputDeviceCount) {\n\t/* Attempt to add WAVE_MAPPER as input and output device */\n\tWAVEINCAPS wic;\n\tMMRESULT mr;\n\n\tpj_bzero(&wic, sizeof(WAVEINCAPS));\n\tmr = waveInGetDevCaps(WAVE_MAPPER, &wic, sizeof(WAVEINCAPS));\n\n\tif (mr == MMSYSERR_NOERROR) {\n\t    WAVEOUTCAPS woc;\n\n\t    pj_bzero(&woc, sizeof(WAVEOUTCAPS));\n\t    mr = waveOutGetDevCaps(WAVE_MAPPER, &woc, sizeof(WAVEOUTCAPS));\n\t    if (mr == MMSYSERR_NOERROR) {\n\t\tbuild_dev_info(WAVE_MAPPER, &wf->dev_info[wf->dev_count], \n\t\t\t       &wic, &woc);\n\t\twf->dev_info[wf->dev_count].endpointId = L\"\";\n\t\t++wf->dev_count;\n\t\twaveMapperAdded = PJ_TRUE;\n\t    }\n\t}\n\n    }\n\n    if (inputDeviceCount > 0) {\n\t/* -1 is the WAVE_MAPPER */\n\tfor (i = (waveMapperAdded? 0 : -1); i < inputDeviceCount; ++i) {\n\t    UINT uDeviceID = (UINT)((i==-1) ? WAVE_MAPPER : i);\n\t    WAVEINCAPS wic;\n\t    MMRESULT mr;\n\t    DWORD cbEndpointId;\n\n\t    pj_bzero(&wic, sizeof(WAVEINCAPS));\n\n\t    mr = waveInGetDevCaps(uDeviceID, &wic, sizeof(WAVEINCAPS));\n\n\t    if (mr == MMSYSERR_NOMEM)\n\t\treturn PJ_ENOMEM;\n\n\t    if (mr != MMSYSERR_NOERROR)\n\t\tcontinue;\n\n\t    build_dev_info(uDeviceID, &wf->dev_info[wf->dev_count], \n\t\t\t   &wic, NULL);\n\n#if PJMEDIA_WMME_DEV_USE_MMDEVICE_API != 0\n\t    /* Try to get the endpoint id of the audio device */\n\t    wf->dev_info[wf->dev_count].endpointId = L\"\";\n\n\t    mr = waveInMessage((HWAVEIN)IntToPtr(uDeviceID),\n\t\t\t       DRV_QUERYFUNCTIONINSTANCEIDSIZE,\n\t\t\t       (DWORD_PTR)&cbEndpointId, (DWORD_PTR)NULL);\n\t    if (mr == MMSYSERR_NOERROR) {\n\t\tconst wchar_t **epid = &wf->dev_info[wf->dev_count].endpointId;\n\t\t*epid = (const wchar_t*) pj_pool_calloc(wf->pool,\n\t\t\t\t\t\t\tcbEndpointId, 1);\n\t\tmr = waveInMessage((HWAVEIN)IntToPtr(uDeviceID),\n\t\t\t\t   DRV_QUERYFUNCTIONINSTANCEID,\n\t\t\t\t   (DWORD_PTR)*epid,\n\t\t\t\t   cbEndpointId);\n\t    }\n#else\n\t    PJ_UNUSED_ARG(cbEndpointId);\n#endif\n\n\t    ++wf->dev_count;\n\t}\n    }\n\n    if( outputDeviceCount > 0 )\n    {\n\t/* -1 is the WAVE_MAPPER */\n\tfor (i = (waveMapperAdded? 0 : -1); i < outputDeviceCount; ++i) {\n\t    UINT uDeviceID = (UINT)((i==-1) ? WAVE_MAPPER : i);\n\t    WAVEOUTCAPS woc;\n\t    MMRESULT mr;\n\t    DWORD cbEndpointId;\n\n\t    pj_bzero(&woc, sizeof(WAVEOUTCAPS));\n\n\t    mr = waveOutGetDevCaps(uDeviceID, &woc, sizeof(WAVEOUTCAPS));\n\n\t    if (mr == MMSYSERR_NOMEM)\n\t\treturn PJ_ENOMEM;\n\n\t    if (mr != MMSYSERR_NOERROR)\n\t\tcontinue;\n\n\t    build_dev_info(uDeviceID, &wf->dev_info[wf->dev_count], \n\t\t\t   NULL, &woc);\n\n#if PJMEDIA_WMME_DEV_USE_MMDEVICE_API != 0\n\t    /* Try to get the endpoint id of the audio device */\n\t    wf->dev_info[wf->dev_count].endpointId = L\"\";\n\n\t    mr = waveOutMessage((HWAVEOUT)IntToPtr(uDeviceID),\n\t\t\t\tDRV_QUERYFUNCTIONINSTANCEIDSIZE,\n\t\t\t\t(DWORD_PTR)&cbEndpointId, (DWORD_PTR)NULL);\n\t    if (mr == MMSYSERR_NOERROR) {\n\t\tconst wchar_t **epid = &wf->dev_info[wf->dev_count].endpointId;\n\t\t*epid = (const wchar_t*)pj_pool_calloc(wf->pool,\n\t\t\t\t\t\t       cbEndpointId, 1);\n\t\tmr = waveOutMessage((HWAVEOUT)IntToPtr(uDeviceID),\n\t\t\t\t    DRV_QUERYFUNCTIONINSTANCEID,\n\t\t\t\t    (DWORD_PTR)*epid, cbEndpointId);\n\t    }\n#else\n\t    PJ_UNUSED_ARG(cbEndpointId);\n#endif\n\n\t    ++wf->dev_count;\n\t}\n    }\n\n    /* On Windows Vista and Windows 7 get the full device names */\n    get_dev_names(f);\n\n    PJ_LOG(4, (THIS_FILE, \"WMME found %d devices:\",\n\t       wf->dev_count));\n    for (c = 0; c < wf->dev_count; ++c) {\n\tPJ_LOG(4, (THIS_FILE, \" dev_id %d: %s  (in=%d, out=%d)\", \n\t    c,\n\t    wf->dev_info[c].info.name,\n\t    wf->dev_info[c].info.input_count,\n\t    wf->dev_info[c].info.output_count));\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: destroy factory */\nstatic pj_status_t factory_destroy(pjmedia_aud_dev_factory *f)\n{\n    struct wmme_factory *wf = (struct wmme_factory*)f;\n    pj_pool_t *pool = wf->base_pool;\n\n    pj_pool_release(wf->pool);\n    wf->base_pool = NULL;\n    pj_pool_release(pool);\n\n    return PJ_SUCCESS;\n}\n\n/* API: get number of devices */\nstatic unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f)\n{\n    struct wmme_factory *wf = (struct wmme_factory*)f;\n    return wf->dev_count;\n}\n\n/* API: get device info */\nstatic pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f, \n\t\t\t\t\tunsigned index,\n\t\t\t\t\tpjmedia_aud_dev_info *info)\n{\n    struct wmme_factory *wf = (struct wmme_factory*)f;\n\n    PJ_ASSERT_RETURN(index < wf->dev_count, PJMEDIA_EAUD_INVDEV);\n\n    pj_memcpy(info, &wf->dev_info[index].info, sizeof(*info));\n\n    return PJ_SUCCESS;\n}\n\n/* API: create default device parameter */\nstatic pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t unsigned index,\n\t\t\t\t\t pjmedia_aud_param *param)\n{\n    struct wmme_factory *wf = (struct wmme_factory*)f;\n    struct wmme_dev_info *di = &wf->dev_info[index];\n\n    PJ_ASSERT_RETURN(index < wf->dev_count, PJMEDIA_EAUD_INVDEV);\n\n    pj_bzero(param, sizeof(*param));\n    if (di->info.input_count && di->info.output_count) {\n\tparam->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;\n\tparam->rec_id = index;\n\tparam->play_id = index;\n    } else if (di->info.input_count) {\n\tparam->dir = PJMEDIA_DIR_CAPTURE;\n\tparam->rec_id = index;\n\tparam->play_id = PJMEDIA_AUD_INVALID_DEV;\n    } else if (di->info.output_count) {\n\tparam->dir = PJMEDIA_DIR_PLAYBACK;\n\tparam->play_id = index;\n\tparam->rec_id = PJMEDIA_AUD_INVALID_DEV;\n    } else {\n\treturn PJMEDIA_EAUD_INVDEV;\n    }\n\n    param->clock_rate = di->info.default_samples_per_sec;\n    param->channel_count = 1;\n    param->samples_per_frame = di->info.default_samples_per_sec * 20 / 1000;\n    param->bits_per_sample = 16;\n    param->flags = PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY |\n\t\t   PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;\n    param->input_latency_ms = PJMEDIA_SND_DEFAULT_REC_LATENCY;\n    param->output_latency_ms = PJMEDIA_SND_DEFAULT_PLAY_LATENCY;\n\n    return PJ_SUCCESS;\n}\n\n/* Internal: init WAVEFORMATEX */\nstatic pj_status_t init_waveformatex(LPWAVEFORMATEX wfx, \n\t\t\t\t     const pjmedia_aud_param *prm)\n{\n\n    pj_bzero(wfx, sizeof(WAVEFORMATEX));\n    if (prm->ext_fmt.id == PJMEDIA_FORMAT_L16) {\n\tenum { BYTES_PER_SAMPLE = 2 };\n\twfx->wFormatTag = WAVE_FORMAT_PCM; \n\twfx->nChannels = (pj_uint16_t)prm->channel_count;\n\twfx->nSamplesPerSec = prm->clock_rate;\n\twfx->nBlockAlign = (pj_uint16_t)(prm->channel_count * \n\t\t\t\t\t BYTES_PER_SAMPLE);\n\twfx->nAvgBytesPerSec = prm->clock_rate * prm->channel_count * \n\t\t\t       BYTES_PER_SAMPLE;\n\twfx->wBitsPerSample = 16;\n\n\treturn PJ_SUCCESS;\n\n    } else if ((prm->flags & PJMEDIA_AUD_DEV_CAP_EXT_FORMAT) &&\n\t       (prm->ext_fmt.id == PJMEDIA_FORMAT_PCMA ||\n\t        prm->ext_fmt.id == PJMEDIA_FORMAT_PCMU))\n    {\n\tunsigned ptime;\n\n\tptime = prm->samples_per_frame * 1000 / \n\t\t(prm->clock_rate * prm->channel_count);\n\twfx->wFormatTag = (pj_uint16_t)\n\t\t\t  ((prm->ext_fmt.id==PJMEDIA_FORMAT_PCMA) ?\n\t\t\t    WAVE_FORMAT_ALAW : WAVE_FORMAT_MULAW);  \n\twfx->nChannels = (pj_uint16_t)prm->channel_count;\n\twfx->nSamplesPerSec = prm->clock_rate;\n\twfx->nAvgBytesPerSec = prm->clock_rate * prm->channel_count;\n\twfx->nBlockAlign = (pj_uint16_t)(wfx->nAvgBytesPerSec * ptime /\n\t\t\t\t\t 1000);\n\twfx->wBitsPerSample = 8;\n\twfx->cbSize = 0;\n\n\treturn PJ_SUCCESS;\n\n    } else {\n\n\treturn PJMEDIA_EAUD_BADFORMAT;\n\n    }\n}\n\n/* Get format name */\nstatic const char *get_fmt_name(pj_uint32_t id)\n{\n    static char name[8];\n\n    if (id == PJMEDIA_FORMAT_L16)\n\treturn \"PCM\";\n    pj_memcpy(name, &id, 4);\n    name[4] = '\\0';\n    return name;\n}\n\n/* Internal: create WMME player device. */\nstatic pj_status_t init_player_stream(  struct wmme_factory *wf,\n\t\t\t\t        pj_pool_t *pool,\n\t\t\t\t\tstruct wmme_stream *parent,\n\t\t\t\t        struct wmme_channel *wmme_strm,\n\t\t\t\t\tconst pjmedia_aud_param *prm,\n\t\t\t\t\tunsigned buffer_count)\n{\n    MMRESULT mr;\n    WAVEFORMATEX wfx; \n    unsigned i, ptime;\n    DWORD flag;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(prm->play_id < (int)wf->dev_count, PJ_EINVAL);\n\n    /*\n     * Create a wait event.\n     */\n    wmme_strm->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\n    if (NULL == wmme_strm->hEvent)\n\treturn pj_get_os_error();\n\n    /*\n     * Set up wave format structure for opening the device.\n     */\n    status = init_waveformatex(&wfx, prm);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    ptime = prm->samples_per_frame * 1000 / \n\t    (prm->clock_rate * prm->channel_count);\n    parent->bytes_per_frame = wfx.nAvgBytesPerSec * ptime / 1000;\n\n    flag = CALLBACK_EVENT;\n    if (prm->ext_fmt.id == PJMEDIA_FORMAT_L16)\n\tflag |= WAVE_FORMAT_DIRECT;\n\n    /*\n     * Open wave device.\n     */\n    mr = waveOutOpen(&wmme_strm->hWave.Out, \n\t\t     wf->dev_info[prm->play_id].deviceId,\n\t\t     &wfx, (DWORD_PTR)wmme_strm->hEvent, 0, flag);\n    if (mr != MMSYSERR_NOERROR) {\n\treturn PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(mr);\n    }\n\n    /* Pause the wave out device */\n    mr = waveOutPause(wmme_strm->hWave.Out);\n    if (mr != MMSYSERR_NOERROR) {\n\treturn PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(mr);\n    }\n\n    /*\n     * Create the buffers. \n     */\n    wmme_strm->WaveHdr = (WAVEHDR*)\n\t\t\t pj_pool_zalloc(pool, sizeof(WAVEHDR) * buffer_count);\n    for (i = 0; i < buffer_count; ++i) {\n\twmme_strm->WaveHdr[i].lpData = pj_pool_zalloc(pool, \n\t\t\t\t\t\t      parent->bytes_per_frame);\n\twmme_strm->WaveHdr[i].dwBufferLength = parent->bytes_per_frame;\n\tmr = waveOutPrepareHeader(wmme_strm->hWave.Out, \n\t\t\t\t  &(wmme_strm->WaveHdr[i]),\n\t\t\t\t  sizeof(WAVEHDR));\n\tif (mr != MMSYSERR_NOERROR) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(mr); \n\t}\n\tmr = waveOutWrite(wmme_strm->hWave.Out, &(wmme_strm->WaveHdr[i]), \n\t\t\t  sizeof(WAVEHDR));\n\tif (mr != MMSYSERR_NOERROR) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(mr);\n\t}\n    }\n\n    wmme_strm->dwBufIdx = 0;\n    wmme_strm->dwMaxBufIdx = buffer_count;\n    wmme_strm->timestamp.u64 = 0;\n\n    /* Done setting up play device. */\n    PJ_LOG(4, (THIS_FILE, \n\t       \" WaveAPI Sound player \\\"%s\\\" initialized (\"\n\t       \"format=%s, clock_rate=%d, \"\n\t       \"channel_count=%d, samples_per_frame=%d (%dms))\",\n\t       wf->dev_info[prm->play_id].info.name,\n\t       get_fmt_name(prm->ext_fmt.id),\n\t       prm->clock_rate, prm->channel_count, prm->samples_per_frame,\n\t       prm->samples_per_frame * 1000 / prm->clock_rate));\n\n    return PJ_SUCCESS;\n}\n\n\n/* Internal: create Windows Multimedia recorder device */\nstatic pj_status_t init_capture_stream( struct wmme_factory *wf,\n\t\t\t\t        pj_pool_t *pool,\n\t\t\t\t\tstruct wmme_stream *parent,\n\t\t\t\t\tstruct wmme_channel *wmme_strm,\n\t\t\t\t\tconst pjmedia_aud_param *prm,\n\t\t\t\t\tunsigned buffer_count)\n{\n    MMRESULT mr;\n    WAVEFORMATEX wfx; \n    DWORD flag;\n    unsigned i, ptime;\n\n    PJ_ASSERT_RETURN(prm->rec_id < (int)wf->dev_count, PJ_EINVAL);\n\n    /*\n    * Create a wait event.\n    */\n    wmme_strm->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\n    if (NULL == wmme_strm->hEvent) {\n\treturn pj_get_os_error();\n    }\n\n    /*\n     * Set up wave format structure for opening the device.\n     */\n    init_waveformatex(&wfx, prm);\n    ptime = prm->samples_per_frame * 1000 / \n\t    (prm->clock_rate * prm->channel_count);\n    parent->bytes_per_frame = wfx.nAvgBytesPerSec * ptime / 1000;\n\n    flag = CALLBACK_EVENT;\n    if (prm->ext_fmt.id == PJMEDIA_FORMAT_L16)\n\tflag |= WAVE_FORMAT_DIRECT;\n\n    /*\n     * Open wave device.\n     */\n    mr = waveInOpen(&wmme_strm->hWave.In, \n\t\t    wf->dev_info[prm->rec_id].deviceId, \n\t\t    &wfx, (DWORD_PTR)wmme_strm->hEvent, 0, flag);\n    if (mr != MMSYSERR_NOERROR) {\n\treturn PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_IN(mr);\n    }\n\n    /*\n     * Create the buffers. \n     */\n    wmme_strm->WaveHdr = (WAVEHDR*)\n\t\t\t pj_pool_zalloc(pool, sizeof(WAVEHDR) * buffer_count);\n    for (i = 0; i < buffer_count; ++i) {\n\twmme_strm->WaveHdr[i].lpData = pj_pool_zalloc(pool, \n\t\t\t\t\t\t      parent->bytes_per_frame);\n\twmme_strm->WaveHdr[i].dwBufferLength = parent->bytes_per_frame;\n\tmr = waveInPrepareHeader(wmme_strm->hWave.In, \n\t\t\t\t &(wmme_strm->WaveHdr[i]),\n\t\t\t\t sizeof(WAVEHDR));\n\tif (mr != MMSYSERR_NOERROR) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_IN(mr);\n\t}\n\tmr = waveInAddBuffer(wmme_strm->hWave.In, &(wmme_strm->WaveHdr[i]), \n\t\t\t     sizeof(WAVEHDR));\n\tif (mr != MMSYSERR_NOERROR) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_IN(mr);\n\t}\n    }\n\n    wmme_strm->dwBufIdx = 0;\n    wmme_strm->dwMaxBufIdx = buffer_count;\n    wmme_strm->timestamp.u64 = 0;\n\n    /* Done setting up play device. */\n    PJ_LOG(4,(THIS_FILE, \n\t\" WaveAPI Sound recorder \\\"%s\\\" initialized \"\n\t\"(format=%s, clock_rate=%d, \"\n\t\"channel_count=%d, samples_per_frame=%d (%dms))\",\n\twf->dev_info[prm->rec_id].info.name,\n\tget_fmt_name(prm->ext_fmt.id),\n\tprm->clock_rate, prm->channel_count, prm->samples_per_frame,\n\tprm->samples_per_frame * 1000 / prm->clock_rate));\n\n    return PJ_SUCCESS;\n}\n\n\n/* WMME capture and playback thread. */\nstatic int PJ_THREAD_FUNC wmme_dev_thread(void *arg)\n{\n    struct wmme_stream *strm = (struct wmme_stream*)arg;\n    HANDLE events[3];\n    unsigned eventCount;\n    pj_status_t status = PJ_SUCCESS;\n    static unsigned rec_cnt, play_cnt;\n    enum { MAX_BURST = 1000 };\n\n    /* Suppress compile warning for unused debugging vars */\n    PJ_UNUSED_ARG(rec_cnt);\n    PJ_UNUSED_ARG(play_cnt);\n    rec_cnt = play_cnt = 0;\n\n    eventCount = 0;\n    events[eventCount++] = strm->thread_quit_event;\n    if (strm->param.dir & PJMEDIA_DIR_PLAYBACK)\n\tevents[eventCount++] = strm->play_strm.hEvent;\n    if (strm->param.dir & PJMEDIA_DIR_CAPTURE)\n\tevents[eventCount++] = strm->rec_strm.hEvent;\n\n\n    /* Raise self priority. We don't want the audio to be distorted by\n     * system activity.\n     */\n#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE != 0\n    if (strm->param.dir & PJMEDIA_DIR_PLAYBACK)\n\tCeSetThreadPriority(GetCurrentThread(), 153);\n    else\n\tCeSetThreadPriority(GetCurrentThread(), 247);\n#else\n    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);\n#endif\n\n    /*\n     * Loop while not signalled to quit, wait for event objects to be \n     * signalled by WMME capture and play buffer.\n     */\n    while (status == PJ_SUCCESS)\n    {\n\n\tDWORD rc;\n\tpjmedia_dir signalled_dir;\n\n\t/* Swap hWaveIn and hWaveOut to get equal opportunity for both */\n\tif (eventCount==3) {\n\t    HANDLE hTemp = events[2];\n\t    events[2] = events[1];\n\t    events[1] = hTemp;\n\t}\n\n\trc = WaitForMultipleObjects(eventCount, events, FALSE, INFINITE);\n\tif (rc < WAIT_OBJECT_0 || rc >= WAIT_OBJECT_0 + eventCount)\n\t    continue;\n\n\tif (rc == WAIT_OBJECT_0)\n\t    break;\n\n\tif (rc == (WAIT_OBJECT_0 + 1))\n\t{\n\t    if (events[1] == strm->play_strm.hEvent)\n\t\tsignalled_dir = PJMEDIA_DIR_PLAYBACK;\n\t    else\n\t\tsignalled_dir = PJMEDIA_DIR_CAPTURE;\n\t}\n\telse\n\t{\n\t    if (events[2] == strm->play_strm.hEvent)\n\t\tsignalled_dir = PJMEDIA_DIR_PLAYBACK;\n\t    else\n\t\tsignalled_dir = PJMEDIA_DIR_CAPTURE;\n\t}\n\n\n\tif (signalled_dir == PJMEDIA_DIR_PLAYBACK)\n\t{\n\t    struct wmme_channel *wmme_strm = &strm->play_strm;\n\t    unsigned burst;\n\n\t    status = PJ_SUCCESS;\n\n\t    /*\n\t     * Windows Multimedia has requested us to feed some frames to\n\t     * playback buffer.\n\t     */\n\n\t    for (burst=0; burst<MAX_BURST &&\n\t\t (wmme_strm->WaveHdr[wmme_strm->dwBufIdx].dwFlags & WHDR_DONE);\n\t         ++burst)\n\t    {\n\t\tvoid *buffer = wmme_strm->WaveHdr[wmme_strm->dwBufIdx].lpData;\n\t\tpjmedia_frame pcm_frame, *frame;\n\t\tMMRESULT mr = MMSYSERR_NOERROR;\n\n\t\t//PJ_LOG(5,(THIS_FILE, \"Finished writing buffer %d\", \n\t\t//\t  wmme_strm->dwBufIdx));\n\n\t\tif (strm->fmt_id == PJMEDIA_FORMAT_L16) {\n\t\t    /* PCM mode */\n\t\t    frame = &pcm_frame;\n\n\t\t    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\t\t    frame->size = strm->bytes_per_frame;\n\t\t    frame->buf = buffer;\n\t\t    frame->timestamp.u64 = wmme_strm->timestamp.u64;\n\t\t    frame->bit_info = 0;\n\t\t} else {\n\t\t    /* Codec mode */\n\t\t    frame = &strm->xfrm->base;\n\n\t\t    strm->xfrm->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;\n\t\t    strm->xfrm->base.size = strm->bytes_per_frame;\n\t\t    strm->xfrm->base.buf = NULL;\n\t\t    strm->xfrm->base.timestamp.u64 = wmme_strm->timestamp.u64;\n\t\t    strm->xfrm->base.bit_info = 0;\n\t\t}\n\n\t\t/* Get frame from application. */\n\t\t//PJ_LOG(5,(THIS_FILE, \"xxx %u play_cb\", play_cnt++));\n\t\tstatus = (*strm->play_cb)(strm->user_data, frame);\n\n\t\tif (status != PJ_SUCCESS)\n\t\t    break;\n\n\t\tif (strm->fmt_id == PJMEDIA_FORMAT_L16) {\n\t\t    /* PCM mode */\n\t\t    if (frame->type == PJMEDIA_FRAME_TYPE_NONE) {\n\t\t\tpj_bzero(buffer, strm->bytes_per_frame);\n\t\t    } else if (frame->type == PJMEDIA_FRAME_TYPE_EXTENDED) {\n\t\t\tpj_assert(!\"Frame type not supported\");\n\t\t    } else if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) {\n\t\t\t/* Nothing to do */\n\t\t    } else {\n\t\t\tpj_assert(!\"Frame type not supported\");\n\t\t    }\n\t\t} else {\n\t\t    /* Codec mode */\n\t\t    if (frame->type == PJMEDIA_FRAME_TYPE_NONE) {\n\t\t\tpj_memset(buffer, strm->silence_char, \n\t\t\t\t  strm->bytes_per_frame);\n\t\t    } else if (frame->type == PJMEDIA_FRAME_TYPE_EXTENDED) {\n\t\t\tunsigned sz;\n\t\t\tsz = pjmedia_frame_ext_copy_payload(strm->xfrm,\n\t\t\t\t\t\t\t    buffer,\n\t\t\t\t\t\t\t    strm->bytes_per_frame);\n\t\t\tif (sz < strm->bytes_per_frame) {\n\t\t\t    pj_memset((char*)buffer+sz,\n\t\t\t\t      strm->silence_char,\n\t\t\t\t      strm->bytes_per_frame - sz);\n\t\t\t}\n\t\t    } else {\n\t\t\tpj_assert(!\"Frame type not supported\");\n\t\t    }\n\t\t}\n\n\t\t/* Write to the device. */\n\t\tmr = waveOutWrite(wmme_strm->hWave.Out, \n\t\t\t\t  &(wmme_strm->WaveHdr[wmme_strm->dwBufIdx]),\n\t\t\t\t  sizeof(WAVEHDR));\n\t\tif (mr != MMSYSERR_NOERROR) {\n\t\t    status = PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(mr);\n\t\t    break;\n\t\t}\n\n\t\t/* Increment position. */\n\t\tif (++wmme_strm->dwBufIdx >= wmme_strm->dwMaxBufIdx)\n\t\t    wmme_strm->dwBufIdx = 0;\n\t\twmme_strm->timestamp.u64 += strm->param.samples_per_frame /\n\t\t\t\t\t    strm->param.channel_count;\n\t    } /* for */\n\t}\n\telse\n\t{\n\t    struct wmme_channel *wmme_strm = &strm->rec_strm;\n\t    unsigned burst;\n\t    MMRESULT mr = MMSYSERR_NOERROR;\n\t    status = PJ_SUCCESS;\n\n\t    /*\n\t    * Windows Multimedia has indicated that it has some frames ready\n\t    * in the capture buffer. Get as much frames as possible to\n\t    * prevent overflows.\n\t    */\n#if 0\n\t    {\n\t\tstatic DWORD tc = 0;\n\t\tDWORD now = GetTickCount();\n\t\tDWORD i = 0;\n\t\tDWORD bits = 0;\n\n\t\tif (tc == 0) tc = now;\n\n\t\tfor (i = 0; i < wmme_strm->dwMaxBufIdx; ++i)\n\t\t{\n\t\t    bits = bits << 4;\n\t\t    bits |= wmme_strm->WaveHdr[i].dwFlags & WHDR_DONE;\n\t\t}\n\t\tPJ_LOG(5,(THIS_FILE, \"Record Signal> Index: %d, Delta: %4.4d, \"\n\t\t\t  \"Flags: %6.6x\\n\",\n\t\t\t  wmme_strm->dwBufIdx,\n\t\t\t  now - tc,\n\t\t\t  bits));\n\t\ttc = now;\n\t    }\n#endif\n\n\t    for (burst=0; burst<MAX_BURST &&\n\t\t (wmme_strm->WaveHdr[wmme_strm->dwBufIdx].dwFlags & WHDR_DONE);\n\t         ++burst)\n\t    {\n\t\tchar* buffer = (char*)\n\t\t\t       wmme_strm->WaveHdr[wmme_strm->dwBufIdx].lpData;\n\t\tunsigned cap_len = \n\t\t\twmme_strm->WaveHdr[wmme_strm->dwBufIdx].dwBytesRecorded;\n\t\tpjmedia_frame pcm_frame, *frame;\n\n\t\t/*\n\t\tPJ_LOG(5,(THIS_FILE, \"Read %d bytes from buffer %d\", cap_len, \n\t\t\t  wmme_strm->dwBufIdx));\n\t\t*/\n\t    \n\t\tif (strm->fmt_id == PJMEDIA_FORMAT_L16) {\n\t\t    /* PCM mode */\n\t\t    if (cap_len < strm->bytes_per_frame)\n\t\t\tpj_bzero(buffer + cap_len, \n\t\t\t\t strm->bytes_per_frame - cap_len);\n\n\t\t    /* Copy the audio data out of the wave buffer. */\n\t\t    pj_memcpy(strm->buffer, buffer, strm->bytes_per_frame);\n\n\t\t    /* Prepare frame */\n\t\t    frame = &pcm_frame;\n\t\t    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\t\t    frame->buf = strm->buffer;\n\t\t    frame->size = strm->bytes_per_frame;\n\t\t    frame->timestamp.u64 = wmme_strm->timestamp.u64;\n\t\t    frame->bit_info = 0;\n\n\t\t} else {\n\t\t    /* Codec mode */\n\t\t    frame = &strm->xfrm->base;\n\n\t\t    frame->type = PJMEDIA_FRAME_TYPE_EXTENDED;\n\t\t    frame->buf = NULL;\n\t\t    frame->size = strm->bytes_per_frame;\n\t\t    frame->timestamp.u64 = wmme_strm->timestamp.u64;\n\t\t    frame->bit_info = 0;\n\n\t\t    strm->xfrm->samples_cnt = 0;\n\t\t    strm->xfrm->subframe_cnt = 0;\n\t\t    pjmedia_frame_ext_append_subframe(\n\t\t\tstrm->xfrm, buffer,\n\t\t\tstrm->bytes_per_frame *8,\n\t\t\tstrm->param.samples_per_frame\n\t\t    );\n\t\t}\n\n\t\t/* Re-add the buffer to the device. */\n\t\tmr = waveInAddBuffer(wmme_strm->hWave.In, \n\t\t\t\t     &(wmme_strm->WaveHdr[wmme_strm->dwBufIdx]), \n\t\t\t\t     sizeof(WAVEHDR));\n\t\tif (mr != MMSYSERR_NOERROR) {\n\t\t    status = PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_IN(mr);\n\t\t    break;\n\t\t}\n\n\n\t\t/* Call callback */\n\t\t//PJ_LOG(5,(THIS_FILE, \"xxx %u rec_cb\", rec_cnt++));\n\t\tstatus = (*strm->rec_cb)(strm->user_data, frame);\n\t\tif (status != PJ_SUCCESS)\n\t\t    break;\n\n\t\t/* Increment position. */\n\t\tif (++wmme_strm->dwBufIdx >= wmme_strm->dwMaxBufIdx)\n\t\t    wmme_strm->dwBufIdx = 0;\n\t\twmme_strm->timestamp.u64 += strm->param.samples_per_frame /\n\t\t\t\t\t    strm->param.channel_count;\n\t    } /* for */\n\t}\n    }\n\n    PJ_LOG(5,(THIS_FILE, \"WMME: thread stopping..\"));\n    return 0;\n}\n\n\n/* API: create stream */\nstatic pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,\n\t\t\t\t\t const pjmedia_aud_param *param,\n\t\t\t\t\t pjmedia_aud_rec_cb rec_cb,\n\t\t\t\t\t pjmedia_aud_play_cb play_cb,\n\t\t\t\t\t void *user_data,\n\t\t\t\t\t pjmedia_aud_stream **p_aud_strm)\n{\n    struct wmme_factory *wf = (struct wmme_factory*)f;\n    pj_pool_t *pool;\n    struct wmme_stream *strm;\n    pj_uint8_t silence_char;\n    pj_status_t status;\n\n    switch (param->ext_fmt.id) {\n    case PJMEDIA_FORMAT_L16:\n\tsilence_char = '\\0';\n\tbreak;\n    case PJMEDIA_FORMAT_ALAW:\n\tsilence_char = (pj_uint8_t)'\\xd5';\n\tbreak;\n    case PJMEDIA_FORMAT_ULAW:\n\tsilence_char = (pj_uint8_t)'\\xff';\n\tbreak;\n    default:\n\treturn PJMEDIA_EAUD_BADFORMAT;\n    }\n\n    /* Create and Initialize stream descriptor */\n    pool = pj_pool_create(wf->pf, \"wmme-dev\", 1000, 1000, NULL);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    strm = PJ_POOL_ZALLOC_T(pool, struct wmme_stream);\n    pj_memcpy(&strm->param, param, sizeof(*param));\n    strm->pool = pool;\n    strm->rec_cb = rec_cb;\n    strm->play_cb = play_cb;\n    strm->user_data = user_data;\n    strm->fmt_id = param->ext_fmt.id;\n    strm->silence_char = silence_char;\n\n    /* Create player stream */\n    if (param->dir & PJMEDIA_DIR_PLAYBACK) {\n\tunsigned buf_count;\n\n\tif ((param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY)==0) {\n\t    strm->param.flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;\n\t    strm->param.output_latency_ms = PJMEDIA_SND_DEFAULT_PLAY_LATENCY;\n\t}\n\n\tbuf_count = strm->param.output_latency_ms * param->clock_rate * \n\t\t    param->channel_count / param->samples_per_frame / 1000;\n\n\tstatus = init_player_stream(wf, strm->pool,\n\t\t\t\t    strm,\n\t\t\t\t    &strm->play_strm,\n\t\t\t\t    param,\n\t\t\t\t    buf_count);\n\n\tif (status != PJ_SUCCESS) {\n\t    stream_destroy(&strm->base);\n\t    return status;\n\t}\n    }\n\n    /* Create capture stream */\n    if (param->dir & PJMEDIA_DIR_CAPTURE) {\n\tunsigned buf_count;\n\n\tif ((param->flags & PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY)==0) {\n\t    strm->param.flags |= PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY;\n\t    strm->param.input_latency_ms = PJMEDIA_SND_DEFAULT_REC_LATENCY;\n\t}\n\n\tbuf_count = strm->param.input_latency_ms * param->clock_rate * \n\t\t    param->channel_count / param->samples_per_frame / 1000;\n\n\tstatus = init_capture_stream(wf, strm->pool,\n\t\t\t\t     strm,\n\t\t\t\t     &strm->rec_strm,\n\t\t\t\t     param,\n\t\t\t\t     buf_count);\n\n\tif (status != PJ_SUCCESS) {\n\t    stream_destroy(&strm->base);\n\t    return status;\n\t}\n    }\n\n    strm->buffer = pj_pool_alloc(pool, strm->bytes_per_frame);\n    if (!strm->buffer) {\n\tpj_pool_release(pool);\n\treturn PJ_ENOMEM;\n    }\n\n    /* If format is extended, must create buffer for the extended frame. */\n    if (strm->fmt_id != PJMEDIA_FORMAT_L16) {\n\tstrm->xfrm_size = sizeof(pjmedia_frame_ext) + \n\t\t\t  32 * sizeof(pjmedia_frame_ext_subframe) +\n\t\t\t  strm->bytes_per_frame + 4;\n\tstrm->xfrm = (pjmedia_frame_ext*)\n\t\t     pj_pool_alloc(pool, strm->xfrm_size);\n    }\n\n    /* Create the stop event */\n    strm->thread_quit_event = CreateEvent(NULL, FALSE, FALSE, NULL);\n    if (strm->thread_quit_event == NULL) {\n\tstatus = pj_get_os_error();\n\tstream_destroy(&strm->base);\n\treturn status;\n    }\n\n    /* Create and start the thread */\n    status = pj_thread_create(pool, \"wmme\", &wmme_dev_thread, strm, 0, 0, \n\t\t\t      &strm->thread);\n    if (status != PJ_SUCCESS) {\n\tstream_destroy(&strm->base);\n\treturn status;\n    }\n\n    /* Apply the remaining settings */\n    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING) {\n\tstream_set_cap(&strm->base, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,\n\t\t       &param->output_vol);\n    }\n\n\n    /* Done */\n    strm->base.op = &stream_op;\n    *p_aud_strm = &strm->base;\n\n    return PJ_SUCCESS;\n}\n\n/* Processes OS messages arriving at the hWnd window */\nINT_PTR WINAPI ProcessOSMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\n{\n    /* wf is used in order to query the number of audio devices currently handled */\n    static struct wmme_factory *wf = NULL;\n\n    switch( message )\n    {\n        case WM_CREATE:\n            /* Initialize wf pointer on the first run */\n            if (wf == NULL)\n            {\n                CREATESTRUCT *CrtStrPtr = (CREATESTRUCT *) lParam;\n                wf = (struct wmme_factory *)(CrtStrPtr->lpCreateParams);\n            }\n            break;\n        case WM_DEVICECHANGE:\n            /* Possible insertion or removal of device. There's some issues:\n\n                - Some devices/drivers does not trigger arrival nor\n                  removecomplete events, but only devnodes_changed events.\n                  Therefore, we process all of those type of events.\n\n                - Some hardware can send many devnodes_changed events at the\n                  same time (up to ~15 of such events). These batches are\n                  detected using temporal locality, using constMaxBatchPeriod_.\n                  Once the device is detected, the rest of redundant events\n                  are discarded. In order to know if there's a new device or not,\n                  actual audio devices count is compared to stored audio devices\n                  count (via wf->dev_count).\n\n                - Hardware takes some time to settle and be recognized by\n                  drivers. A small window of time is given in order to account\n                  for this (constMaxSettleTime_);\n\n                  Settle time should be slightly lower than batch period.\n            */\n            if (wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE || wParam == DBT_DEVNODES_CHANGED) {\n                const int constMaxBatchPeriod_ = 3; /* seconds */\n                const int constMaxSettleTime_ = (constMaxBatchPeriod_ * 1000) - 500; /* milliseconds */\n\n                /* Loop that allows hardware to settle */\n                int settleTimeLeft = constMaxSettleTime_;\n                while (settleTimeLeft > 0) {\n                    /* Check if actual devices lists (I/O) sizes have actually\n                       changed before notifying upper levels. Consider input\n                       devices, output devices and a WAVE MAPPER device for each.\n                    */\n                    if(waveInGetNumDevs() + waveOutGetNumDevs() + 2 != wf->dev_count) {\n                        /* Hardware changed */\n                        if (wf->dev_observer.cb) {\n                            wf->dev_observer.cb(DEVICE_LIST_CHANGED);\n                        }\n                        break;\n                    } else {\n                        /* Hardware is settling... */\n                        Sleep(250);\n                        settleTimeLeft -= 250;\n                    }\n                }\n            }\n            break;\n        case WM_CLOSE:\n            if (!DestroyWindow(hWnd)) {\n                PJ_LOG(4,(THIS_FILE, \"Couldn't destroy message window\"));\n            }\n            break;\n        case WM_DESTROY:\n            PostQuitMessage(0);\n            break;\n        default:\n            break;\n    }\n\n    return 1;\n}\n\nstatic pj_status_t create_os_messages_window(struct wmme_factory *wf)\n{\n    pj_status_t status = PJ_EBUG;\n    WNDCLASSEX wndClass;\n    HWND hWnd;\n\n    /* Set up and register window class */\n    ZeroMemory(&wndClass, sizeof(WNDCLASSEX));\n    wndClass.cbSize = sizeof(WNDCLASSEX);\n    wndClass.style = CS_OWNDC;\n    wndClass.lpfnWndProc = (WNDPROC)(ProcessOSMessage);\n    wndClass.hInstance = (HINSTANCE)(GetModuleHandle(0));\n    wndClass.lpszClassName = \"DeviceChangeMessageWindow\";\n\n    if (RegisterClassEx(&wndClass)) {\n        /* Create the window that will receive OS messages */\n        hWnd = CreateWindowEx( 0, \"DeviceChangeMessageWindow\", NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, (LPVOID)(wf));\n        if (hWnd != NULL) {\n            wf->dev_observer.hWnd = hWnd;\n            if (UpdateWindow(hWnd) != 0) {\n                status = PJ_SUCCESS;\n            }\n        } else {\n            PJ_LOG(4,(THIS_FILE, \"Error creating window to receive device change events\"));\n        }\n    }\n\n    return status;\n\n}\n\nstatic pj_status_t dispatch_os_messages(void)\n{\n    pj_status_t status = PJ_SUCCESS;\n    MSG msg;\n    int ret;\n\n    /* Process OS messages with low cpu-usage wait loop */\n    while((ret = GetMessage(&msg, NULL, 0, 0)) != 0) {\n        if (ret == -1) {\n            PJ_LOG(4,(THIS_FILE, \"Couldn't process OS message\"));\n            status = PJ_EBUG;\n            break;\n        } else {\n            TranslateMessage(&msg);\n            DispatchMessage(&msg);\n        }\n    }\n\n    return status;\n\n}\n\n/* WMME device observer thread thread. */\nstatic int PJ_THREAD_FUNC wmme_dev_observer_thread(void *arg)\n{\n    struct wmme_factory *wf = (struct wmme_factory*)arg;\n    pj_status_t status;\n\n    status = create_os_messages_window(wf);\n    if (status == PJ_SUCCESS) {\n        status = dispatch_os_messages();\n        if (status != PJ_SUCCESS) {\n            PJ_LOG(4,(THIS_FILE, \"Error dispatching device detection window events\"));\n        }\n    } else {\n        PJ_LOG(4,(THIS_FILE, \"Failed to create window for receiving device detection events\"));\n    }\n\n    return status;\n}\n\n/* API: set audio device change observer */\nstatic void factory_set_observer(pjmedia_aud_dev_factory *f,\n                                 pjmedia_aud_dev_change_callback cb)\n{\n    struct wmme_factory *wf = (struct wmme_factory*)f;\n    pj_pool_t *pool;\n    pj_status_t status;\n\n    if (cb) {\n        pool = pj_pool_create(wf->pf, \"wmme-dev-observer\", 1000, 1000, NULL);\n        PJ_ASSERT_ON_FAIL(pool != NULL, {return;});\n        status = pj_thread_create(pool, \"wmme_observer\", &wmme_dev_observer_thread, wf, 0, 0, &wf->dev_observer.thread);\n        if (status != PJ_SUCCESS) {\n\t    PJ_LOG(4,(THIS_FILE, \"Failed to create WMME device detection thread\"));\n            wf->dev_observer.thread = NULL;\n            return;\n        }\n        wf->dev_observer.cb = cb;\n    } else {\n        wf->dev_observer.cb = NULL;\n        if (wf->dev_observer.hWnd) {\n            CloseWindow(wf->dev_observer.hWnd);\n            wf->dev_observer.hWnd = NULL;\n        }\n\tpj_thread_join(wf->dev_observer.thread);\n\tpj_thread_destroy(wf->dev_observer.thread);\n        wf->dev_observer.thread = NULL;\n    }\n}\n\n/* API: get default recording device */\nstatic int factory_get_default_rec_dev(pjmedia_aud_dev_factory *f)\n{\n    PJ_UNUSED_ARG(f);\n    /* Let PJMEDIA pick the first one available */\n    return -1;\n}\n\n/* API: get default playback device */\nstatic int factory_get_default_play_dev(pjmedia_aud_dev_factory *f)\n{\n    PJ_UNUSED_ARG(f);\n    /* Let PJMEDIA pick the first one available */\n    return -1;\n}\n\n/* API: Get stream info. */\nstatic pj_status_t stream_get_param(pjmedia_aud_stream *s,\n\t\t\t\t    pjmedia_aud_param *pi)\n{\n    struct wmme_stream *strm = (struct wmme_stream*)s;\n\n    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);\n\n    pj_memcpy(pi, &strm->param, sizeof(*pi));\n    \n    /* Update the volume setting */\n    if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,\n\t\t      &pi->output_vol) == PJ_SUCCESS)\n    {\n\tpi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: get capability */\nstatic pj_status_t stream_get_cap(pjmedia_aud_stream *s,\n\t\t\t\t  pjmedia_aud_dev_cap cap,\n\t\t\t\t  void *pval)\n{\n    struct wmme_stream *strm = (struct wmme_stream*)s;\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    if (cap==PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY && \n\t(strm->param.dir & PJMEDIA_DIR_CAPTURE)) \n    {\n\t/* Recording latency */\n\t*(unsigned*)pval = strm->param.input_latency_ms;\n\treturn PJ_SUCCESS;\n    } else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY  && \n\t       (strm->param.dir & PJMEDIA_DIR_PLAYBACK))\n    {\n\t/* Playback latency */\n\t*(unsigned*)pval = strm->param.output_latency_ms;\n\treturn PJ_SUCCESS;\n    } else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING &&\n\t       strm->play_strm.hWave.Out)\n    {\n\t/* Output volume setting */\n\tDWORD waveVol;\n\tMMRESULT mr;\n\n\tmr = waveOutGetVolume(strm->play_strm.hWave.Out, &waveVol);\n\tif (mr != MMSYSERR_NOERROR) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(mr);\n\t}\n\n\twaveVol &= 0xFFFF;\n\t*(unsigned*)pval = (waveVol * 100) / 0xFFFF;\n\treturn PJ_SUCCESS;\n    } else {\n\treturn PJMEDIA_EAUD_INVCAP;\n    }\n}\n\n/* API: set capability */\nstatic pj_status_t stream_set_cap(pjmedia_aud_stream *s,\n\t\t\t\t  pjmedia_aud_dev_cap cap,\n\t\t\t\t  const void *pval)\n{\n    struct wmme_stream *strm = (struct wmme_stream*)s;\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING &&\n\tstrm->play_strm.hWave.Out)\n    {\n\t/* Output volume setting */\n\tunsigned vol = *(unsigned*)pval;\n\tDWORD waveVol;\n\tMMRESULT mr;\n\tpj_status_t status;\n\n\tif (vol > 100)\n\t    vol = 100;\n\n\twaveVol = (vol * 0xFFFF) / 100;\n\twaveVol |= (waveVol << 16);\n\n\tmr = waveOutSetVolume(strm->play_strm.hWave.Out, waveVol);\n\tstatus = (mr==MMSYSERR_NOERROR)? PJ_SUCCESS : \n\t\t\t\tPJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(mr);\n\tif (status == PJ_SUCCESS) {\n\t    strm->param.output_vol = *(unsigned*)pval;\n\t}\n\treturn status;\n    }\n\n    return PJMEDIA_EAUD_INVCAP;\n}\n\n/* API: Start stream. */\nstatic pj_status_t stream_start(pjmedia_aud_stream *strm)\n{\n    struct wmme_stream *stream = (struct wmme_stream*)strm;\n    MMRESULT mr;\n\n    if (stream->play_strm.hWave.Out != NULL)\n    {\n\tmr = waveOutRestart(stream->play_strm.hWave.Out);\n\tif (mr != MMSYSERR_NOERROR) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(mr);\n\t}\n\tPJ_LOG(4,(THIS_FILE, \"WMME playback stream started\"));\n    }\n\n    if (stream->rec_strm.hWave.In != NULL)\n    {\n\tmr = waveInStart(stream->rec_strm.hWave.In);\n\tif (mr != MMSYSERR_NOERROR) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_IN(mr);\n\t}\n\tPJ_LOG(4,(THIS_FILE, \"WMME capture stream started\"));\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: Stop stream. */\nstatic pj_status_t stream_stop(pjmedia_aud_stream *strm)\n{\n    struct wmme_stream *stream = (struct wmme_stream*)strm;\n    MMRESULT mr;\n\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n\n    if (stream->play_strm.hWave.Out != NULL)\n    {\n\tmr = waveOutPause(stream->play_strm.hWave.Out);\n\tif (mr != MMSYSERR_NOERROR) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(mr);\n\t}\n\tPJ_LOG(4,(THIS_FILE, \"Stopped WMME playback stream\"));\n    }\n\n    if (stream->rec_strm.hWave.In != NULL)\n    {\n\tmr = waveInStop(stream->rec_strm.hWave.In);\n\tif (mr != MMSYSERR_NOERROR) {\n\t    return PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_IN(mr);\n\t}\n\tPJ_LOG(4,(THIS_FILE, \"Stopped WMME capture stream\"));\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: Destroy stream. */\nstatic pj_status_t stream_destroy(pjmedia_aud_stream *strm)\n{\n    struct wmme_stream *stream = (struct wmme_stream*)strm;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n\n    stream_stop(strm);\n\n    /* Stop the stream thread */\n    if (stream->thread)\n    {\n\tSetEvent(stream->thread_quit_event);\n\tpj_thread_join(stream->thread);\n\tpj_thread_destroy(stream->thread);\n\tstream->thread = NULL;\n    }\n\n    /* Close the thread quit event */\n    if (stream->thread_quit_event)\n    {\n\tCloseHandle(stream->thread_quit_event);\n\tstream->thread_quit_event = NULL;\n    }\n\n    /* Unprepare the headers and close the play device */\n    if (stream->play_strm.hWave.Out)\n    {\n\twaveOutReset(stream->play_strm.hWave.Out);\n\tfor (i = 0; i < stream->play_strm.dwMaxBufIdx; ++i)\n\t    waveOutUnprepareHeader(stream->play_strm.hWave.Out, \n\t\t\t\t   &(stream->play_strm.WaveHdr[i]),\n\t\t\t\t   sizeof(WAVEHDR));\n\twaveOutClose(stream->play_strm.hWave.Out);\n\tstream->play_strm.hWave.Out = NULL;\n    }\n\n    /* Close the play event */\n    if (stream->play_strm.hEvent)\n    {\n\tCloseHandle(stream->play_strm.hEvent);\n\tstream->play_strm.hEvent = NULL;\n    }\n\n    /* Unprepare the headers and close the record device */\n    if (stream->rec_strm.hWave.In)\n    {\n\twaveInReset(stream->rec_strm.hWave.In);\n\tfor (i = 0; i < stream->play_strm.dwMaxBufIdx; ++i)\n\t    waveInUnprepareHeader(stream->rec_strm.hWave.In, \n\t\t\t\t  &(stream->rec_strm.WaveHdr[i]),\n\t\t\t\t  sizeof(WAVEHDR));\n\twaveInClose(stream->rec_strm.hWave.In);\n\tstream->rec_strm.hWave.In = NULL;\n    }\n\n    /* Close the record event */\n    if (stream->rec_strm.hEvent)\n    {\n\tCloseHandle(stream->rec_strm.hEvent);\n\tstream->rec_strm.hEvent = NULL;\n    }\n\n    pj_pool_release(stream->pool);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_AUDIO_DEV_HAS_WMME */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/audio_codecs.c",
    "content": "/* $Id: audio_codecs.c 4335 2013-01-29 08:09:15Z ming $ */\n/* \n * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-codec.h>\n#include <pjmedia/g711.h>\n\nPJ_DEF(void) pjmedia_audio_codec_config_default(pjmedia_audio_codec_config*cfg)\n{\n    pj_bzero(cfg, sizeof(*cfg));\n    cfg->speex.option = 0;\n    cfg->speex.quality = PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY;\n    cfg->speex.complexity = PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY;\n    cfg->ilbc.mode = 30;\n    cfg->passthrough.setting.ilbc_mode = cfg->ilbc.mode;\n}\n\nPJ_DEF(pj_status_t)\npjmedia_codec_register_audio_codecs(pjmedia_endpt *endpt,\n                                    const pjmedia_audio_codec_config *c)\n{\n    pjmedia_audio_codec_config default_cfg;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(endpt, PJ_EINVAL);\n    if (!c) {\n\tpjmedia_audio_codec_config_default(&default_cfg);\n\tc = &default_cfg;\n    }\n\n    PJ_ASSERT_RETURN(c->ilbc.mode==20 || c->ilbc.mode==30, PJ_EINVAL);\n\n#if PJMEDIA_HAS_PASSTHROUGH_CODECS\n    status = pjmedia_codec_passthrough_init2(endpt, &c->passthrough.setting);\n    if (status != PJ_SUCCESS)\n\treturn status;\n#endif\n\n#if PJMEDIA_HAS_SPEEX_CODEC\n    /* Register speex. */\n    status = pjmedia_codec_speex_init(endpt, c->speex.option,\n\t\t\t\t      c->speex.quality,\n\t\t\t\t      c->speex.complexity);\n    if (status != PJ_SUCCESS)\n\treturn status;\n#endif\n\n#if PJMEDIA_HAS_ILBC_CODEC\n    /* Register iLBC. */\n    status = pjmedia_codec_ilbc_init( endpt, c->ilbc.mode);\n    if (status != PJ_SUCCESS)\n\treturn status;\n#endif /* PJMEDIA_HAS_ILBC_CODEC */\n\n#if PJMEDIA_HAS_GSM_CODEC\n    /* Register GSM */\n    status = pjmedia_codec_gsm_init(endpt);\n    if (status != PJ_SUCCESS)\n\treturn status;\n#endif /* PJMEDIA_HAS_GSM_CODEC */\n\n#if PJMEDIA_HAS_G711_CODEC\n    /* Register PCMA and PCMU */\n    status = pjmedia_codec_g711_init(endpt);\n    if (status != PJ_SUCCESS)\n\treturn status;\n#endif\t/* PJMEDIA_HAS_G711_CODEC */\n\n#if PJMEDIA_HAS_G722_CODEC\n    status = pjmedia_codec_g722_init(endpt );\n    if (status != PJ_SUCCESS)\n\treturn status;\n#endif  /* PJMEDIA_HAS_G722_CODEC */\n\n#if PJMEDIA_HAS_G7221_CODEC\n    /* Register G722.1 codecs */\n    status = pjmedia_codec_g7221_init(endpt);\n    if (status != PJ_SUCCESS)\n\treturn status;\n#endif /* PJMEDIA_HAS_G7221_CODEC */\n\n#if PJMEDIA_HAS_OPUS_CODEC\n    /* Register opus codecs */\n    status = pjmedia_codec_opus_init(endpt);\n    if (status != PJ_SUCCESS)\n\treturn status;\n#endif /* PJMEDIA_HAS_OPUS_CODEC */\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/ffmpeg_vid_codecs.c",
    "content": "/* $Id: ffmpeg_vid_codecs.c 4311 2012-12-20 06:45:09Z nanang $ */\n/* \n * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-codec/ffmpeg_vid_codecs.h>\n#include <pjmedia-codec/h263_packetizer.h>\n#include <pjmedia-codec/h264_packetizer.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/vid_codec_util.h>\n#include <pj/assert.h>\n#include <pj/list.h>\n#include <pj/log.h>\n#include <pj/math.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/os.h>\n\n\n/*\n * Only build this file if PJMEDIA_HAS_FFMPEG_VID_CODEC != 0 and \n * PJMEDIA_HAS_VIDEO != 0\n */\n#if defined(PJMEDIA_HAS_FFMPEG_VID_CODEC) && \\\n            PJMEDIA_HAS_FFMPEG_VID_CODEC != 0 && \\\n    defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n#define THIS_FILE   \"ffmpeg_vid_codecs.c\"\n\n#define LIBAVCODEC_VER_AT_LEAST(major,minor)  (LIBAVCODEC_VERSION_MAJOR > major || \\\n     \t\t\t\t\t       (LIBAVCODEC_VERSION_MAJOR == major && \\\n\t\t\t\t\t        LIBAVCODEC_VERSION_MINOR >= minor))\n\n#include \"../pjmedia/ffmpeg_util.h\"\n#include <libavcodec/avcodec.h>\n#include <libavformat/avformat.h>\n#if LIBAVCODEC_VER_AT_LEAST(53,20)\n  /* Needed by 264 so far, on libavcodec 53.20 */\n# include <libavutil/opt.h>\n#endif\n\n\n/* Various compatibility */\n\n#if LIBAVCODEC_VER_AT_LEAST(53,20)\n#  define AVCODEC_OPEN(ctx,c)\t\tavcodec_open2(ctx,c,NULL)\n#else\n#  define AVCODEC_OPEN(ctx,c)\t\tavcodec_open(ctx,c)\n#endif\n\n#if LIBAVCODEC_VER_AT_LEAST(53,61)\n#  define AVCODEC_HAS_ENCODE(c)\t(c->encode2)\n#  define AV_OPT_SET(obj,name,val,opt)\t(av_opt_set(obj,name,val,opt)==0)\n#  define AV_OPT_SET_INT(obj,name,val)\t(av_opt_set_int(obj,name,val,0)==0)\n#else\n#  define AVCODEC_HAS_ENCODE(c)\t\t(c->encode)\n#  define AV_OPT_SET(obj,name,val,opt)\t(av_set_string3(obj,name,val,opt,NULL)==0)\n#  define AV_OPT_SET_INT(obj,name,val)\t(av_set_int(obj,name,val)!=NULL)\n#endif\n#define AVCODEC_HAS_DECODE(c)\t\t(c->decode)\n\n\n/* Prototypes for FFMPEG codecs factory */\nstatic pj_status_t ffmpeg_test_alloc( pjmedia_vid_codec_factory *factory, \n\t\t\t\t      const pjmedia_vid_codec_info *id );\nstatic pj_status_t ffmpeg_default_attr( pjmedia_vid_codec_factory *factory, \n\t\t\t\t        const pjmedia_vid_codec_info *info, \n\t\t\t\t        pjmedia_vid_codec_param *attr );\nstatic pj_status_t ffmpeg_enum_codecs( pjmedia_vid_codec_factory *factory, \n\t\t\t\t       unsigned *count, \n\t\t\t\t       pjmedia_vid_codec_info codecs[]);\nstatic pj_status_t ffmpeg_alloc_codec( pjmedia_vid_codec_factory *factory, \n\t\t\t\t       const pjmedia_vid_codec_info *info, \n\t\t\t\t       pjmedia_vid_codec **p_codec);\nstatic pj_status_t ffmpeg_dealloc_codec( pjmedia_vid_codec_factory *factory, \n\t\t\t\t         pjmedia_vid_codec *codec );\n\n/* Prototypes for FFMPEG codecs implementation. */\nstatic pj_status_t  ffmpeg_codec_init( pjmedia_vid_codec *codec, \n\t\t\t\t       pj_pool_t *pool );\nstatic pj_status_t  ffmpeg_codec_open( pjmedia_vid_codec *codec, \n\t\t\t\t       pjmedia_vid_codec_param *attr );\nstatic pj_status_t  ffmpeg_codec_close( pjmedia_vid_codec *codec );\nstatic pj_status_t  ffmpeg_codec_modify(pjmedia_vid_codec *codec, \n\t\t\t\t        const pjmedia_vid_codec_param *attr );\nstatic pj_status_t  ffmpeg_codec_get_param(pjmedia_vid_codec *codec,\n\t\t\t\t\t   pjmedia_vid_codec_param *param);\nstatic pj_status_t ffmpeg_codec_encode_begin(pjmedia_vid_codec *codec,\n\t\t\t\t\t     const pjmedia_vid_encode_opt *opt,\n                                             const pjmedia_frame *input,\n\t\t\t\t\t     unsigned out_size,\n\t\t\t\t\t     pjmedia_frame *output,\n\t\t\t\t\t     pj_bool_t *has_more);\nstatic pj_status_t ffmpeg_codec_encode_more(pjmedia_vid_codec *codec,\n\t\t\t\t\t    unsigned out_size,\n\t\t\t\t\t    pjmedia_frame *output,\n\t\t\t\t\t    pj_bool_t *has_more);\nstatic pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec,\n\t\t\t\t\tpj_size_t pkt_count,\n\t\t\t\t\tpjmedia_frame packets[],\n\t\t\t\t\tunsigned out_size,\n\t\t\t\t\tpjmedia_frame *output);\n\n/* Definition for FFMPEG codecs operations. */\nstatic pjmedia_vid_codec_op ffmpeg_op = \n{\n    &ffmpeg_codec_init,\n    &ffmpeg_codec_open,\n    &ffmpeg_codec_close,\n    &ffmpeg_codec_modify,\n    &ffmpeg_codec_get_param,\n    &ffmpeg_codec_encode_begin,\n    &ffmpeg_codec_encode_more,\n    &ffmpeg_codec_decode,\n    NULL\n};\n\n/* Definition for FFMPEG codecs factory operations. */\nstatic pjmedia_vid_codec_factory_op ffmpeg_factory_op =\n{\n    &ffmpeg_test_alloc,\n    &ffmpeg_default_attr,\n    &ffmpeg_enum_codecs,\n    &ffmpeg_alloc_codec,\n    &ffmpeg_dealloc_codec\n};\n\n\n/* FFMPEG codecs factory */\nstatic struct ffmpeg_factory {\n    pjmedia_vid_codec_factory    base;\n    pjmedia_vid_codec_mgr\t*mgr;\n    pj_pool_factory             *pf;\n    pj_pool_t\t\t        *pool;\n    pj_mutex_t\t\t        *mutex;\n} ffmpeg_factory;\n\n\ntypedef struct ffmpeg_codec_desc ffmpeg_codec_desc;\n\n\n/* FFMPEG codecs private data. */\ntypedef struct ffmpeg_private\n{\n    const ffmpeg_codec_desc\t    *desc;\n    pjmedia_vid_codec_param\t     param;\t/**< Codec param\t    */\n    pj_pool_t\t\t\t    *pool;\t/**< Pool for each instance */\n\n    /* Format info and apply format param */\n    const pjmedia_video_format_info *enc_vfi;\n    pjmedia_video_apply_fmt_param    enc_vafp;\n    const pjmedia_video_format_info *dec_vfi;\n    pjmedia_video_apply_fmt_param    dec_vafp;\n\n    /* Buffers, only needed for multi-packets */\n    pj_bool_t\t\t\t     whole;\n    void\t\t\t    *enc_buf;\n    unsigned\t\t\t     enc_buf_size;\n    pj_bool_t\t\t\t     enc_buf_is_keyframe;\n    unsigned\t\t\t     enc_frame_len;\n    unsigned     \t\t     enc_processed;\n    void\t\t\t    *dec_buf;\n    unsigned\t\t\t     dec_buf_size;\n    pj_timestamp\t\t     last_dec_keyframe_ts; \n\n    /* The ffmpeg codec states. */\n    AVCodec\t\t\t    *enc;\n    AVCodec\t\t\t    *dec;\n    AVCodecContext\t\t    *enc_ctx;\n    AVCodecContext\t\t    *dec_ctx;\n\n    /* The ffmpeg decoder cannot set the output format, so format conversion\n     * may be needed for post-decoding.\n     */\n    enum AVPixelFormat\t\t     expected_dec_fmt;\n\t\t\t\t\t\t/**< Expected output format of \n\t\t\t\t\t\t     ffmpeg decoder\t    */\n\n    void\t\t\t    *data;\t/**< Codec specific data    */\t\t    \n} ffmpeg_private;\n\n\n/* Shortcuts for packetize & unpacketize function declaration,\n * as it has long params and is reused many times!\n */\n#define FUNC_PACKETIZE(name) \\\n    pj_status_t(name)(ffmpeg_private *ff, pj_uint8_t *bits, \\\n\t\t      pj_size_t bits_len, unsigned *bits_pos, \\\n\t\t      const pj_uint8_t **payload, pj_size_t *payload_len)\n\n#define FUNC_UNPACKETIZE(name) \\\n    pj_status_t(name)(ffmpeg_private *ff, const pj_uint8_t *payload, \\\n\t\t      pj_size_t payload_len, pj_uint8_t *bits, \\\n\t\t      pj_size_t bits_len, unsigned *bits_pos)\n\n#define FUNC_FMT_MATCH(name) \\\n    pj_status_t(name)(pj_pool_t *pool, \\\n\t\t      pjmedia_sdp_media *offer, unsigned o_fmt_idx, \\\n\t\t      pjmedia_sdp_media *answer, unsigned a_fmt_idx, \\\n\t\t      unsigned option)\n\n\n/* Type definition of codec specific functions */\ntypedef FUNC_PACKETIZE(*func_packetize);\ntypedef FUNC_UNPACKETIZE(*func_unpacketize);\ntypedef pj_status_t (*func_preopen)\t(ffmpeg_private *ff);\ntypedef pj_status_t (*func_postopen)\t(ffmpeg_private *ff);\ntypedef FUNC_FMT_MATCH(*func_sdp_fmt_match);\n\n\n/* FFMPEG codec info */\nstruct ffmpeg_codec_desc\n{\n    /* Predefined info */\n    pjmedia_vid_codec_info       info;\n    pjmedia_format_id\t\t base_fmt_id;\t/**< Some codecs may be exactly\n\t\t\t\t\t\t     same or compatible with\n\t\t\t\t\t\t     another codec, base format\n\t\t\t\t\t\t     will tell the initializer\n\t\t\t\t\t\t     to copy this codec desc\n\t\t\t\t\t\t     from its base format   */\n    pjmedia_rect_size            size;\n    pjmedia_ratio                fps;\n    pj_uint32_t\t\t\t avg_bps;\n    pj_uint32_t\t\t\t max_bps;\n    func_packetize\t\t packetize;\n    func_unpacketize\t\t unpacketize;\n    func_preopen\t\t preopen;\n    func_preopen\t\t postopen;\n    func_sdp_fmt_match\t\t sdp_fmt_match;\n    pjmedia_codec_fmtp\t\t dec_fmtp;\n\n    /* Init time defined info */\n    pj_bool_t\t\t\t enabled;\n    AVCodec                     *enc;\n    AVCodec                     *dec;\n};\n\n\n#if PJMEDIA_HAS_FFMPEG_CODEC_H264 && !LIBAVCODEC_VER_AT_LEAST(53,20)\n#   error \"Must use libavcodec version 53.20 or later to enable FFMPEG H264\"\n#endif\n\n/* H264 constants */\n#define PROFILE_H264_BASELINE\t\t66\n#define PROFILE_H264_MAIN\t\t77\n#define PROFILE_H264_HIGH\t\t100\n\n/* Codec specific functions */\n#if PJMEDIA_HAS_FFMPEG_CODEC_H264\nstatic pj_status_t h264_preopen(ffmpeg_private *ff);\nstatic pj_status_t h264_postopen(ffmpeg_private *ff);\nstatic FUNC_PACKETIZE(h264_packetize);\nstatic FUNC_UNPACKETIZE(h264_unpacketize);\n#endif\n\nstatic pj_status_t h263_preopen(ffmpeg_private *ff);\nstatic FUNC_PACKETIZE(h263_packetize);\nstatic FUNC_UNPACKETIZE(h263_unpacketize);\n\n\n/* Internal codec info */\nstatic ffmpeg_codec_desc codec_desc[] =\n{\n#if PJMEDIA_HAS_FFMPEG_CODEC_H264\n    {\n\t{PJMEDIA_FORMAT_H264, PJMEDIA_RTP_PT_H264, {\"H264\",4},\n\t {\"Constrained Baseline (level=30, pack=1)\", 39}},\n\t0,\n\t{720, 480},\t{15, 1},\t256000, 256000,\n\t&h264_packetize, &h264_unpacketize, &h264_preopen, &h264_postopen,\n\t&pjmedia_vid_codec_h264_match_sdp,\n\t/* Leading space for better compatibility (strange indeed!) */\n\t{2, { {{\"profile-level-id\",16},    {\"42e01e\",6}}, \n\t      {{\" packetization-mode\",19},  {\"1\",1}}, } },\n    },\n#endif\n\n#if PJMEDIA_HAS_FFMPEG_CODEC_H263P\n    {\n\t{PJMEDIA_FORMAT_H263P, PJMEDIA_RTP_PT_H263P, {\"H263-1998\",9}},\n\tPJMEDIA_FORMAT_H263,\n\t{352, 288},\t{15, 1},\t256000, 256000,\n\t&h263_packetize, &h263_unpacketize, &h263_preopen, NULL, NULL,\n\t{2, { {{\"CIF\",3},   {\"1\",1}}, \n\t      {{\"QCIF\",4},  {\"1\",1}}, } },\n    },\n#endif\n\n    {\n\t{PJMEDIA_FORMAT_H263,\tPJMEDIA_RTP_PT_H263,\t{\"H263\",4}},\n    },\n    {\n\t{PJMEDIA_FORMAT_H261,\tPJMEDIA_RTP_PT_H261,\t{\"H261\",4}},\n    },\n    {\n\t{PJMEDIA_FORMAT_MJPEG,\tPJMEDIA_RTP_PT_JPEG,\t{\"JPEG\",4}},\n\tPJMEDIA_FORMAT_MJPEG, {640, 480}, {25, 1},\n    },\n    {\n\t{PJMEDIA_FORMAT_MPEG4,\t0,\t\t\t{\"MP4V\",4}},\n\tPJMEDIA_FORMAT_MPEG4, {640, 480}, {25, 1},\n    },\n};\n\n#if PJMEDIA_HAS_FFMPEG_CODEC_H264\n\ntypedef struct h264_data\n{\n    pjmedia_vid_codec_h264_fmtp\t fmtp;\n    pjmedia_h264_packetizer\t*pktz;\n} h264_data;\n\n\nstatic pj_status_t h264_preopen(ffmpeg_private *ff)\n{\n    h264_data *data;\n    pjmedia_h264_packetizer_cfg pktz_cfg;\n    pj_status_t status;\n\n    data = PJ_POOL_ZALLOC_T(ff->pool, h264_data);\n    ff->data = data;\n\n    /* Parse remote fmtp */\n    status = pjmedia_vid_codec_h264_parse_fmtp(&ff->param.enc_fmtp,\n\t\t\t\t\t       &data->fmtp);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Create packetizer */\n    pktz_cfg.mtu = ff->param.enc_mtu;\n#if 0\n    if (data->fmtp.packetization_mode == 0)\n\tpktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL;\n    else if (data->fmtp.packetization_mode == 1)\n\tpktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED;\n    else\n\treturn PJ_ENOTSUP;\n#else\n    if (data->fmtp.packetization_mode!=\n\t\t\t\tPJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL &&\n\tdata->fmtp.packetization_mode!=\n\t\t\t\tPJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED)\n    {\n\treturn PJ_ENOTSUP;\n    }\n    /* Better always send in single NAL mode for better compatibility */\n    pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL;\n#endif\n\n    status = pjmedia_h264_packetizer_create(ff->pool, &pktz_cfg, &data->pktz);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Apply SDP fmtp to format in codec param */\n    if (!ff->param.ignore_fmtp) {\n\tstatus = pjmedia_vid_codec_h264_apply_fmtp(&ff->param);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    if (ff->param.dir & PJMEDIA_DIR_ENCODING) {\n\tpjmedia_video_format_detail *vfd;\n\tAVCodecContext *ctx = ff->enc_ctx;\n\tconst char *profile = NULL;\n\n\tvfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt, \n\t\t\t\t\t\t     PJ_TRUE);\n\n\t/* Override generic params after applying SDP fmtp */\n\tctx->width = vfd->size.w;\n\tctx->height = vfd->size.h;\n\tctx->time_base.num = vfd->fps.denum;\n\tctx->time_base.den = vfd->fps.num;\n\n\t/* Apply profile. */\n\tctx->profile  = data->fmtp.profile_idc;\n\tswitch (ctx->profile) {\n\tcase PROFILE_H264_BASELINE:\n\t    profile = \"baseline\";\n\t    break;\n\tcase PROFILE_H264_MAIN:\n\t    profile = \"main\";\n\t    break;\n\tcase PROFILE_H264_HIGH:\n\t    profile = \"high\";\n\t    break;\n\tdefault:\n\t    break;\n\t}\n\tif (profile && !AV_OPT_SET(ctx->priv_data, \"profile\", profile, 0))\n\t{\n\t    PJ_LOG(3, (THIS_FILE, \"Failed to set H264 profile to '%s'\",\n\t\t       profile));\n\t}\n\n\t/* Apply profile constraint bits. */\n\t//PJ_TODO(set_h264_constraint_bits_properly_in_ffmpeg);\n\tif (data->fmtp.profile_iop) {\n#if defined(FF_PROFILE_H264_CONSTRAINED)\n\t    ctx->profile |= FF_PROFILE_H264_CONSTRAINED;\n#endif\n\t}\n\n\t/* Apply profile level. */\n\tctx->level    = data->fmtp.level;\n\n\t/* Limit NAL unit size as we prefer single NAL unit packetization */\n\tif (!AV_OPT_SET_INT(ctx->priv_data, \"slice-max-size\", ff->param.enc_mtu))\n\t{\n\t    PJ_LOG(3, (THIS_FILE, \"Failed to set H264 max NAL size to %d\",\n\t\t       ff->param.enc_mtu));\n\t}\n\n\t/* Apply intra-refresh */\n\tif (!AV_OPT_SET_INT(ctx->priv_data, \"intra-refresh\", 1))\n\t{\n\t    PJ_LOG(3, (THIS_FILE, \"Failed to set x264 intra-refresh\"));\n\t}\n\n\t/* Misc x264 settings (performance, quality, latency, etc).\n\t * Let's just use the x264 predefined preset & tune.\n\t */\n\tif (!AV_OPT_SET(ctx->priv_data, \"preset\", \"ultrafast\", 0)) {\n\t    PJ_LOG(3, (THIS_FILE, \"Failed to set x264 preset 'veryfast'\"));\n\t}\n\tif (!AV_OPT_SET(ctx->priv_data, \"tune\", \"fastdecode+zerolatency\", 0)) {\n\t    PJ_LOG(3, (THIS_FILE, \"Failed to set x264 tune 'fastdecode+zerolatency'\"));\n\t}\n    }\n\n    if (ff->param.dir & PJMEDIA_DIR_DECODING) {\n\tAVCodecContext *ctx = ff->dec_ctx;\n\n\t/* Apply the \"sprop-parameter-sets\" fmtp from remote SDP to\n\t * extradata of ffmpeg codec context.\n\t */\n\tif (data->fmtp.sprop_param_sets_len) {\n\t    ctx->extradata_size = (int)data->fmtp.sprop_param_sets_len;\n\t    ctx->extradata = data->fmtp.sprop_param_sets;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t h264_postopen(ffmpeg_private *ff)\n{\n    h264_data *data = (h264_data*)ff->data;\n    PJ_UNUSED_ARG(data);\n    return PJ_SUCCESS;\n}\n\nstatic FUNC_PACKETIZE(h264_packetize)\n{\n    h264_data *data = (h264_data*)ff->data;\n    return pjmedia_h264_packetize(data->pktz, bits, bits_len, bits_pos,\n\t\t\t\t  payload, payload_len);\n}\n\nstatic FUNC_UNPACKETIZE(h264_unpacketize)\n{\n    h264_data *data = (h264_data*)ff->data;\n    return pjmedia_h264_unpacketize(data->pktz, payload, payload_len,\n\t\t\t\t    bits, bits_len, bits_pos);\n}\n\n#endif /* PJMEDIA_HAS_FFMPEG_CODEC_H264 */\n\n\n#if PJMEDIA_HAS_FFMPEG_CODEC_H263P\n\ntypedef struct h263_data\n{\n    pjmedia_h263_packetizer\t*pktz;\n} h263_data;\n\n/* H263 pre-open */\nstatic pj_status_t h263_preopen(ffmpeg_private *ff)\n{\n    h263_data *data;\n    pjmedia_h263_packetizer_cfg pktz_cfg;\n    pj_status_t status;\n\n    data = PJ_POOL_ZALLOC_T(ff->pool, h263_data);\n    ff->data = data;\n\n    /* Create packetizer */\n    pktz_cfg.mtu = ff->param.enc_mtu;\n    pktz_cfg.mode = PJMEDIA_H263_PACKETIZER_MODE_RFC4629;\n    status = pjmedia_h263_packetizer_create(ff->pool, &pktz_cfg, &data->pktz);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Apply fmtp settings to codec param */\n    if (!ff->param.ignore_fmtp) {\n\tstatus = pjmedia_vid_codec_h263_apply_fmtp(&ff->param);\n    }\n\n    /* Override generic params after applying SDP fmtp */\n    if (ff->param.dir & PJMEDIA_DIR_ENCODING) {\n\tpjmedia_video_format_detail *vfd;\n\tAVCodecContext *ctx = ff->enc_ctx;\n\n\tvfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt, \n\t\t\t\t\t\t     PJ_TRUE);\n\n\t/* Override generic params after applying SDP fmtp */\n\tctx->width = vfd->size.w;\n\tctx->height = vfd->size.h;\n\tctx->time_base.num = vfd->fps.denum;\n\tctx->time_base.den = vfd->fps.num;\n    }\n\n    return status;\n}\n\nstatic FUNC_PACKETIZE(h263_packetize)\n{\n    h263_data *data = (h263_data*)ff->data;\n    return pjmedia_h263_packetize(data->pktz, bits, bits_len, bits_pos,\n\t\t\t\t  payload, payload_len);\n}\n\nstatic FUNC_UNPACKETIZE(h263_unpacketize)\n{\n    h263_data *data = (h263_data*)ff->data;\n    return pjmedia_h263_unpacketize(data->pktz, payload, payload_len,\n\t\t\t\t    bits, bits_len, bits_pos);\n}\n\n#endif /* PJMEDIA_HAS_FFMPEG_CODEC_H263P */\n\n\nstatic const ffmpeg_codec_desc* find_codec_desc_by_info(\n\t\t\tconst pjmedia_vid_codec_info *info)\n{\n    int i;\n\n    for (i=0; i<PJ_ARRAY_SIZE(codec_desc); ++i) {\n\tffmpeg_codec_desc *desc = &codec_desc[i];\n\n\tif (desc->enabled &&\n\t    (desc->info.fmt_id == info->fmt_id) &&\n            ((desc->info.dir & info->dir) == info->dir) &&\n\t    (desc->info.pt == info->pt) &&\n\t    (desc->info.packings & info->packings))\n        {\n            return desc;\n        }\n    }\n\n    return NULL;\n}\n\n\nstatic int find_codec_idx_by_fmt_id(pjmedia_format_id fmt_id)\n{\n    int i;\n    for (i=0; i<PJ_ARRAY_SIZE(codec_desc); ++i) {\n\tif (codec_desc[i].info.fmt_id == fmt_id)\n\t    return i;\n    }\n\n    return -1;\n}\n\n\n/*\n * Initialize and register FFMPEG codec factory to pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_ffmpeg_vid_init(pjmedia_vid_codec_mgr *mgr,\n                                                  pj_pool_factory *pf)\n{\n    pj_pool_t *pool;\n    AVCodec *c;\n    pj_status_t status;\n    unsigned i;\n\n    if (ffmpeg_factory.pool != NULL) {\n\t/* Already initialized. */\n\treturn PJ_SUCCESS;\n    }\n\n    if (!mgr) mgr = pjmedia_vid_codec_mgr_instance();\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    /* Create FFMPEG codec factory. */\n    ffmpeg_factory.base.op = &ffmpeg_factory_op;\n    ffmpeg_factory.base.factory_data = NULL;\n    ffmpeg_factory.mgr = mgr;\n    ffmpeg_factory.pf = pf;\n\n    pool = pj_pool_create(pf, \"ffmpeg codec factory\", 256, 256, NULL);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    /* Create mutex. */\n    status = pj_mutex_create_simple(pool, \"ffmpeg codec factory\", \n\t\t\t\t    &ffmpeg_factory.mutex);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    pjmedia_ffmpeg_add_ref();\n#if !LIBAVCODEC_VER_AT_LEAST(53,20)\n    /* avcodec_init() dissappeared between version 53.20 and 54.15, not sure\n     * exactly when \n     */\n    avcodec_init();\n#endif\n    avcodec_register_all();\n\n    /* Enum FFMPEG codecs */\n    for (c=av_codec_next(NULL); c; c=av_codec_next(c)) {\n        ffmpeg_codec_desc *desc;\n\tpjmedia_format_id fmt_id;\n\tint codec_info_idx;\n        \n#if LIBAVCODEC_VERSION_MAJOR <= 52\n#   define AVMEDIA_TYPE_VIDEO\tCODEC_TYPE_VIDEO\n#endif\n        if (c->type != AVMEDIA_TYPE_VIDEO)\n            continue;\n\n        /* Video encoder and decoder are usually implemented in separate\n         * AVCodec instances. While the codec attributes (e.g: raw formats,\n\t * supported fps) are in the encoder.\n         */\n\n\t//PJ_LOG(3, (THIS_FILE, \"%s\", c->name));\n\tstatus = CodecID_to_pjmedia_format_id(c->id, &fmt_id);\n\t/* Skip if format ID is unknown */\n\tif (status != PJ_SUCCESS)\n\t    continue;\n\n\tcodec_info_idx = find_codec_idx_by_fmt_id(fmt_id);\n\t/* Skip if codec is unwanted by this wrapper (not listed in \n\t * the codec info array)\n\t */\n\tif (codec_info_idx < 0)\n\t    continue;\n\n\tdesc = &codec_desc[codec_info_idx];\n\n\t/* Skip duplicated codec implementation */\n\tif ((AVCODEC_HAS_ENCODE(c) && (desc->info.dir & PJMEDIA_DIR_ENCODING))\n\t    ||\n\t    (AVCODEC_HAS_DECODE(c) && (desc->info.dir & PJMEDIA_DIR_DECODING)))\n\t{\n\t    continue;\n\t}\n\n\t/* Get raw/decoded format ids in the encoder */\n\tif (c->pix_fmts && AVCODEC_HAS_ENCODE(c)) {\n\t    pjmedia_format_id raw_fmt[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT];\n\t    unsigned raw_fmt_cnt = 0;\n\t    unsigned raw_fmt_cnt_should_be = 0;\n\t    const enum AVPixelFormat *p = c->pix_fmts;\n\n\t    for(;(p && *p != -1) &&\n\t\t (raw_fmt_cnt < PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT);\n\t\t ++p)\n\t    {\n\t\tpjmedia_format_id fmt_id;\n\n\t\traw_fmt_cnt_should_be++;\n\t\tstatus = PixelFormat_to_pjmedia_format_id(*p, &fmt_id);\n\t\tif (status != PJ_SUCCESS) {\n\t\t    PJ_LOG(6, (THIS_FILE, \"Unrecognized ffmpeg pixel \"\n\t\t\t       \"format %d\", *p));\n\t\t    continue;\n\t\t}\n\t\t\n\t\t//raw_fmt[raw_fmt_cnt++] = fmt_id;\n\t\t/* Disable some formats due to H.264 error:\n\t\t * x264 [error]: baseline profile doesn't support 4:4:4\n\t\t */\n\t\tif (desc->info.pt != PJMEDIA_RTP_PT_H264 ||\n\t\t    fmt_id != PJMEDIA_FORMAT_RGB24)\n\t\t{\n\t\t    raw_fmt[raw_fmt_cnt++] = fmt_id;\n\t\t}\n\t    }\n\n\t    if (raw_fmt_cnt == 0) {\n\t\tPJ_LOG(5, (THIS_FILE, \"No recognized raw format \"\n\t\t\t\t      \"for codec [%s/%s], codec ignored\",\n\t\t\t\t      c->name, c->long_name));\n\t\t/* Skip this encoder */\n\t\tcontinue;\n\t    }\n\n\t    if (raw_fmt_cnt < raw_fmt_cnt_should_be) {\n\t\tPJ_LOG(6, (THIS_FILE, \"Codec [%s/%s] have %d raw formats, \"\n\t\t\t\t      \"recognized only %d raw formats\",\n\t\t\t\t      c->name, c->long_name,\n\t\t\t\t      raw_fmt_cnt_should_be, raw_fmt_cnt));\n\t    }\n\n\t    desc->info.dec_fmt_id_cnt = raw_fmt_cnt;\n\t    pj_memcpy(desc->info.dec_fmt_id, raw_fmt, \n\t\t      sizeof(raw_fmt[0])*raw_fmt_cnt);\n\t}\n\n\t/* Get supported framerates */\n\tif (c->supported_framerates) {\n\t    const AVRational *fr = c->supported_framerates;\n\t    while ((fr->num != 0 || fr->den != 0) && \n\t\t   desc->info.fps_cnt < PJMEDIA_VID_CODEC_MAX_FPS_CNT)\n\t    {\n\t\tdesc->info.fps[desc->info.fps_cnt].num = fr->num;\n\t\tdesc->info.fps[desc->info.fps_cnt].denum = fr->den;\n\t\t++desc->info.fps_cnt;\n\t\t++fr;\n\t    }\n\t}\n\n\t/* Get ffmpeg encoder instance */\n\tif (AVCODEC_HAS_ENCODE(c) && !desc->enc) {\n            desc->info.dir |= PJMEDIA_DIR_ENCODING;\n            desc->enc = c;\n        }\n\t\n\t/* Get ffmpeg decoder instance */\n        if (AVCODEC_HAS_DECODE(c) && !desc->dec) {\n            desc->info.dir |= PJMEDIA_DIR_DECODING;\n            desc->dec = c;\n        }\n\n\t/* Enable this codec when any ffmpeg codec instance are recognized\n\t * and the supported raw formats info has been collected.\n\t */\n\tif ((desc->dec || desc->enc) && desc->info.dec_fmt_id_cnt)\n\t{\n\t    desc->enabled = PJ_TRUE;\n\t}\n\n\t/* Normalize default value of clock rate */\n\tif (desc->info.clock_rate == 0)\n\t    desc->info.clock_rate = 90000;\n\n\t/* Set supported packings */\n\tdesc->info.packings |= PJMEDIA_VID_PACKING_WHOLE;\n\tif (desc->packetize && desc->unpacketize)\n\t    desc->info.packings |= PJMEDIA_VID_PACKING_PACKETS;\n\n    }\n\n    /* Review all codecs for applying base format, registering format match for\n     * SDP negotiation, etc.\n     */\n    for (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) {\n\tffmpeg_codec_desc *desc = &codec_desc[i];\n\n\t/* Init encoder/decoder description from base format */\n\tif (desc->base_fmt_id && (!desc->dec || !desc->enc)) {\n\t    ffmpeg_codec_desc *base_desc = NULL;\n\t    int base_desc_idx;\n\t    pjmedia_dir copied_dir = PJMEDIA_DIR_NONE;\n\n\t    base_desc_idx = find_codec_idx_by_fmt_id(desc->base_fmt_id);\n\t    if (base_desc_idx != -1)\n\t\tbase_desc = &codec_desc[base_desc_idx];\n\t    if (!base_desc || !base_desc->enabled)\n\t\tcontinue;\n\n\t    /* Copy description from base codec */\n\t    if (!desc->info.dec_fmt_id_cnt) {\n\t\tdesc->info.dec_fmt_id_cnt = base_desc->info.dec_fmt_id_cnt;\n\t\tpj_memcpy(desc->info.dec_fmt_id, base_desc->info.dec_fmt_id, \n\t\t\t  sizeof(pjmedia_format_id)*desc->info.dec_fmt_id_cnt);\n\t    }\n\t    if (!desc->info.fps_cnt) {\n\t\tdesc->info.fps_cnt = base_desc->info.fps_cnt;\n\t\tpj_memcpy(desc->info.fps, base_desc->info.fps, \n\t\t\t  sizeof(desc->info.fps[0])*desc->info.fps_cnt);\n\t    }\n\t    if (!desc->info.clock_rate) {\n\t\tdesc->info.clock_rate = base_desc->info.clock_rate;\n\t    }\n\t    if (!desc->dec && base_desc->dec) {\n\t\tcopied_dir |= PJMEDIA_DIR_DECODING;\n\t\tdesc->dec = base_desc->dec;\n\t    }\n\t    if (!desc->enc && base_desc->enc) {\n\t\tcopied_dir |= PJMEDIA_DIR_ENCODING;\n\t\tdesc->enc = base_desc->enc;\n\t    }\n\n\t    desc->info.dir |= copied_dir;\n\t    desc->enabled = (desc->info.dir != PJMEDIA_DIR_NONE);\n\n\t    /* Set supported packings */\n\t    desc->info.packings |= PJMEDIA_VID_PACKING_WHOLE;\n\t    if (desc->packetize && desc->unpacketize)\n\t\tdesc->info.packings |= PJMEDIA_VID_PACKING_PACKETS;\n\n\t    if (copied_dir != PJMEDIA_DIR_NONE) {\n\t\tconst char *dir_name[] = {NULL, \"encoder\", \"decoder\", \"codec\"};\n\t\tPJ_LOG(5, (THIS_FILE, \"The %.*s %s is using base codec (%.*s)\",\n\t\t\t   desc->info.encoding_name.slen,\n\t\t\t   desc->info.encoding_name.ptr,\n\t\t\t   dir_name[copied_dir],\n\t\t\t   base_desc->info.encoding_name.slen,\n\t\t\t   base_desc->info.encoding_name.ptr));\n\t    }\n        }\n\n\t/* Registering format match for SDP negotiation */\n\tif (desc->sdp_fmt_match) {\n\t    status = pjmedia_sdp_neg_register_fmt_match_cb(\n\t\t\t\t\t\t&desc->info.encoding_name,\n\t\t\t\t\t\tdesc->sdp_fmt_match);\n\t    pj_assert(status == PJ_SUCCESS);\n\t}\n\n\t/* Print warning about missing encoder/decoder */\n\tif (!desc->enc) {\n\t    PJ_LOG(4, (THIS_FILE, \"Cannot find %.*s encoder in ffmpeg library\",\n\t\t       desc->info.encoding_name.slen,\n\t\t       desc->info.encoding_name.ptr));\n\t}\n\tif (!desc->dec) {\n\t    PJ_LOG(4, (THIS_FILE, \"Cannot find %.*s decoder in ffmpeg library\",\n\t\t       desc->info.encoding_name.slen,\n\t\t       desc->info.encoding_name.ptr));\n\t}\n    }\n\n    /* Register codec factory to codec manager. */\n    status = pjmedia_vid_codec_mgr_register_factory(mgr, \n\t\t\t\t\t\t    &ffmpeg_factory.base);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    ffmpeg_factory.pool = pool;\n\n    /* Done. */\n    return PJ_SUCCESS;\n\non_error:\n    pj_pool_release(pool);\n    return status;\n}\n\n/*\n * Unregister FFMPEG codecs factory from pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_ffmpeg_vid_deinit(void)\n{\n    pj_status_t status = PJ_SUCCESS;\n\n    if (ffmpeg_factory.pool == NULL) {\n\t/* Already deinitialized */\n\treturn PJ_SUCCESS;\n    }\n\n    pj_mutex_lock(ffmpeg_factory.mutex);\n\n    /* Unregister FFMPEG codecs factory. */\n    status = pjmedia_vid_codec_mgr_unregister_factory(ffmpeg_factory.mgr,\n\t\t\t\t\t\t      &ffmpeg_factory.base);\n\n    /* Destroy mutex. */\n    pj_mutex_unlock(ffmpeg_factory.mutex);\n    pj_mutex_destroy(ffmpeg_factory.mutex);\n    ffmpeg_factory.mutex = NULL;\n\n    /* Destroy pool. */\n    pj_pool_release(ffmpeg_factory.pool);\n    ffmpeg_factory.pool = NULL;\n\n    pjmedia_ffmpeg_dec_ref();\n\n    return status;\n}\n\n\n/* \n * Check if factory can allocate the specified codec. \n */\nstatic pj_status_t ffmpeg_test_alloc( pjmedia_vid_codec_factory *factory, \n\t\t\t\t      const pjmedia_vid_codec_info *info )\n{\n    const ffmpeg_codec_desc *desc;\n\n    PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL);\n    PJ_ASSERT_RETURN(info, PJ_EINVAL);\n\n    desc = find_codec_desc_by_info(info);\n    if (!desc) {\n        return PJMEDIA_CODEC_EUNSUP;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Generate default attribute.\n */\nstatic pj_status_t ffmpeg_default_attr( pjmedia_vid_codec_factory *factory, \n\t\t\t\t        const pjmedia_vid_codec_info *info, \n\t\t\t\t        pjmedia_vid_codec_param *attr )\n{\n    const ffmpeg_codec_desc *desc;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL);\n    PJ_ASSERT_RETURN(info && attr, PJ_EINVAL);\n\n    desc = find_codec_desc_by_info(info);\n    if (!desc) {\n        return PJMEDIA_CODEC_EUNSUP;\n    }\n\n    pj_bzero(attr, sizeof(pjmedia_vid_codec_param));\n\n    /* Scan the requested packings and use the lowest number */\n    attr->packing = 0;\n    for (i=0; i<15; ++i) {\n\tunsigned packing = (1 << i);\n\tif ((desc->info.packings & info->packings) & packing) {\n\t    attr->packing = (pjmedia_vid_packing)packing;\n\t    break;\n\t}\n    }\n    if (attr->packing == 0) {\n\t/* No supported packing in info */\n\treturn PJMEDIA_CODEC_EUNSUP;\n    }\n\n    /* Direction */\n    attr->dir = desc->info.dir;\n\n    /* Encoded format */\n    pjmedia_format_init_video(&attr->enc_fmt, desc->info.fmt_id,\n                              desc->size.w, desc->size.h,\n\t\t\t      desc->fps.num, desc->fps.denum);\n\n    /* Decoded format */\n    pjmedia_format_init_video(&attr->dec_fmt, desc->info.dec_fmt_id[0],\n                              desc->size.w, desc->size.h,\n\t\t\t      desc->fps.num, desc->fps.denum);\n\n    /* Decoding fmtp */\n    attr->dec_fmtp = desc->dec_fmtp;\n\n    /* Bitrate */\n    attr->enc_fmt.det.vid.avg_bps = desc->avg_bps;\n    attr->enc_fmt.det.vid.max_bps = desc->max_bps;\n\n    /* Encoding MTU */\n    attr->enc_mtu = PJMEDIA_MAX_VID_PAYLOAD_SIZE;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Enum codecs supported by this factory.\n */\nstatic pj_status_t ffmpeg_enum_codecs( pjmedia_vid_codec_factory *factory,\n\t\t\t\t       unsigned *count, \n\t\t\t\t       pjmedia_vid_codec_info codecs[])\n{\n    unsigned i, max_cnt;\n\n    PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL);\n\n    max_cnt = PJ_MIN(*count, PJ_ARRAY_SIZE(codec_desc));\n    *count = 0;\n\n    for (i=0; i<max_cnt; ++i) {\n\tif (codec_desc[i].enabled) {\n\t    pj_memcpy(&codecs[*count], &codec_desc[i].info, \n\t\t      sizeof(pjmedia_vid_codec_info));\n\t    (*count)++;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Allocate a new codec instance.\n */\nstatic pj_status_t ffmpeg_alloc_codec( pjmedia_vid_codec_factory *factory, \n\t\t\t\t       const pjmedia_vid_codec_info *info,\n\t\t\t\t       pjmedia_vid_codec **p_codec)\n{\n    ffmpeg_private *ff;\n    const ffmpeg_codec_desc *desc;\n    pjmedia_vid_codec *codec;\n    pj_pool_t *pool = NULL;\n    pj_status_t status = PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(factory && info && p_codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL);\n\n    desc = find_codec_desc_by_info(info);\n    if (!desc) {\n        return PJMEDIA_CODEC_EUNSUP;\n    }\n\n    /* Create pool for codec instance */\n    pool = pj_pool_create(ffmpeg_factory.pf, \"ffmpeg codec\", 512, 512, NULL);\n    codec = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_codec);\n    if (!codec) {\n        status = PJ_ENOMEM;\n        goto on_error;\n    }\n    codec->op = &ffmpeg_op;\n    codec->factory = factory;\n    ff = PJ_POOL_ZALLOC_T(pool, ffmpeg_private);\n    if (!ff) {\n        status = PJ_ENOMEM;\n        goto on_error;\n    }\n    codec->codec_data = ff;\n    ff->pool = pool;\n    ff->enc = desc->enc;\n    ff->dec = desc->dec;\n    ff->desc = desc;\n\n    *p_codec = codec;\n    return PJ_SUCCESS;\n\non_error:\n    if (pool)\n        pj_pool_release(pool);\n    return status;\n}\n\n/*\n * Free codec.\n */\nstatic pj_status_t ffmpeg_dealloc_codec( pjmedia_vid_codec_factory *factory, \n\t\t\t\t         pjmedia_vid_codec *codec )\n{\n    ffmpeg_private *ff;\n    pj_pool_t *pool;\n\n    PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL);\n\n    /* Close codec, if it's not closed. */\n    ff = (ffmpeg_private*) codec->codec_data;\n    pool = ff->pool;\n    codec->codec_data = NULL;\n    pj_pool_release(pool);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Init codec.\n */\nstatic pj_status_t ffmpeg_codec_init( pjmedia_vid_codec *codec, \n\t\t\t\t      pj_pool_t *pool )\n{\n    PJ_UNUSED_ARG(codec);\n    PJ_UNUSED_ARG(pool);\n    return PJ_SUCCESS;\n}\n\nstatic void print_ffmpeg_err(int err)\n{\n#if LIBAVCODEC_VER_AT_LEAST(52,72)\n    char errbuf[512];\n    if (av_strerror(err, errbuf, sizeof(errbuf)) >= 0)\n        PJ_LOG(5, (THIS_FILE, \"ffmpeg err %d: %s\", err, errbuf));\n#else\n    PJ_LOG(5, (THIS_FILE, \"ffmpeg err %d\", err));\n#endif\n\n}\n\nstatic pj_status_t open_ffmpeg_codec(ffmpeg_private *ff,\n                                     pj_mutex_t *ff_mutex)\n{\n    enum AVPixelFormat pix_fmt;\n    pjmedia_video_format_detail *vfd;\n    pj_bool_t enc_opened = PJ_FALSE, dec_opened = PJ_FALSE;\n    pj_status_t status;\n\n    /* Get decoded pixel format */\n    status = pjmedia_format_id_to_PixelFormat(ff->param.dec_fmt.id,\n                                              &pix_fmt);\n    if (status != PJ_SUCCESS)\n        return status;\n    ff->expected_dec_fmt = pix_fmt;\n\n    /* Get video format detail for shortcut access to encoded format */\n    vfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt, \n\t\t\t\t\t\t PJ_TRUE);\n\n    /* Allocate ffmpeg codec context */\n    if (ff->param.dir & PJMEDIA_DIR_ENCODING) {\n#if LIBAVCODEC_VER_AT_LEAST(53,20)\n\tff->enc_ctx = avcodec_alloc_context3(ff->enc);\n#else\n\tff->enc_ctx = avcodec_alloc_context();\n#endif\n\tif (ff->enc_ctx == NULL)\n\t    goto on_error;\n    }\n    if (ff->param.dir & PJMEDIA_DIR_DECODING) {\n#if LIBAVCODEC_VER_AT_LEAST(53,20)\n\tff->dec_ctx = avcodec_alloc_context3(ff->dec);\n#else\n\tff->dec_ctx = avcodec_alloc_context();\n#endif\n\tif (ff->dec_ctx == NULL)\n\t    goto on_error;\n    }\n\n    /* Init generic encoder params */\n    if (ff->param.dir & PJMEDIA_DIR_ENCODING) {\n        AVCodecContext *ctx = ff->enc_ctx;\n\n        ctx->pix_fmt = pix_fmt;\n\tctx->width = vfd->size.w;\n\tctx->height = vfd->size.h;\n\tctx->time_base.num = vfd->fps.denum;\n\tctx->time_base.den = vfd->fps.num;\n\tif (vfd->avg_bps) {\n\t    ctx->bit_rate = vfd->avg_bps;\n\t    if (vfd->max_bps > vfd->avg_bps)\n\t\tctx->bit_rate_tolerance = vfd->max_bps - vfd->avg_bps;\n\t}\n\tctx->strict_std_compliance = FF_COMPLIANCE_STRICT;\n        ctx->workaround_bugs = FF_BUG_AUTODETECT;\n        ctx->opaque = ff;\n\n\t/* Set no delay, note that this may cause some codec functionals\n\t * not working (e.g: rate control).\n\t */\n#if LIBAVCODEC_VER_AT_LEAST(52,113) && !LIBAVCODEC_VER_AT_LEAST(53,20)\n\tctx->rc_lookahead = 0;\n#endif\n    }\n\n    /* Init generic decoder params */\n    if (ff->param.dir & PJMEDIA_DIR_DECODING) {\n\tAVCodecContext *ctx = ff->dec_ctx;\n\n\t/* Width/height may be overriden by ffmpeg after first decoding. */\n\tctx->width  = ctx->coded_width  = ff->param.dec_fmt.det.vid.size.w;\n\tctx->height = ctx->coded_height = ff->param.dec_fmt.det.vid.size.h;\n\tctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;\n        ctx->workaround_bugs = FF_BUG_AUTODETECT;\n        ctx->opaque = ff;\n    }\n\n    /* Override generic params or apply specific params before opening\n     * the codec.\n     */\n    if (ff->desc->preopen) {\n\tstatus = (*ff->desc->preopen)(ff);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n    }\n\n    /* Open encoder */\n    if (ff->param.dir & PJMEDIA_DIR_ENCODING) {\n\tint err;\n\n\tpj_mutex_lock(ff_mutex);\n\terr = AVCODEC_OPEN(ff->enc_ctx, ff->enc);\n        pj_mutex_unlock(ff_mutex);\n        if (err < 0) {\n            print_ffmpeg_err(err);\n            status = PJMEDIA_CODEC_EFAILED;\n\t    goto on_error;\n        }\n\tenc_opened = PJ_TRUE;\n    }\n\n    /* Open decoder */\n    if (ff->param.dir & PJMEDIA_DIR_DECODING) {\n\tint err;\n\n\tpj_mutex_lock(ff_mutex);\n\terr = AVCODEC_OPEN(ff->dec_ctx, ff->dec);\n        pj_mutex_unlock(ff_mutex);\n        if (err < 0) {\n            print_ffmpeg_err(err);\n            status = PJMEDIA_CODEC_EFAILED;\n\t    goto on_error;\n        }\n\tdec_opened = PJ_TRUE;\n    }\n\n    /* Let the codec apply specific params after the codec opened */\n    if (ff->desc->postopen) {\n\tstatus = (*ff->desc->postopen)(ff);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n    }\n\n    return PJ_SUCCESS;\n\non_error:\n    if (ff->enc_ctx) {\n\tif (enc_opened)\n\t    avcodec_close(ff->enc_ctx);\n\tav_free(ff->enc_ctx);\n\tff->enc_ctx = NULL;\n    }\n    if (ff->dec_ctx) {\n\tif (dec_opened)\n\t    avcodec_close(ff->dec_ctx);\n\tav_free(ff->dec_ctx);\n\tff->dec_ctx = NULL;\n    }\n    return status;\n}\n\n/*\n * Open codec.\n */\nstatic pj_status_t ffmpeg_codec_open( pjmedia_vid_codec *codec, \n\t\t\t\t      pjmedia_vid_codec_param *attr )\n{\n    ffmpeg_private *ff;\n    pj_status_t status;\n    pj_mutex_t *ff_mutex;\n\n    PJ_ASSERT_RETURN(codec && attr, PJ_EINVAL);\n    ff = (ffmpeg_private*)codec->codec_data;\n\n    pj_memcpy(&ff->param, attr, sizeof(*attr));\n\n    /* Normalize encoding MTU in codec param */\n    if (attr->enc_mtu > PJMEDIA_MAX_VID_PAYLOAD_SIZE)\n\tattr->enc_mtu = PJMEDIA_MAX_VID_PAYLOAD_SIZE;\n\n    /* Open the codec */\n    ff_mutex = ((struct ffmpeg_factory*)codec->factory)->mutex;\n    status = open_ffmpeg_codec(ff, ff_mutex);\n    if (status != PJ_SUCCESS)\n        goto on_error;\n\n    /* Init format info and apply-param of decoder */\n    ff->dec_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id);\n    if (!ff->dec_vfi) {\n        status = PJ_EINVAL;\n        goto on_error;\n    }\n    pj_bzero(&ff->dec_vafp, sizeof(ff->dec_vafp));\n    ff->dec_vafp.size = ff->param.dec_fmt.det.vid.size;\n    ff->dec_vafp.buffer = NULL;\n    status = (*ff->dec_vfi->apply_fmt)(ff->dec_vfi, &ff->dec_vafp);\n    if (status != PJ_SUCCESS) {\n        goto on_error;\n    }\n\n    /* Init format info and apply-param of encoder */\n    ff->enc_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id);\n    if (!ff->enc_vfi) {\n        status = PJ_EINVAL;\n        goto on_error;\n    }\n    pj_bzero(&ff->enc_vafp, sizeof(ff->enc_vafp));\n    ff->enc_vafp.size = ff->param.enc_fmt.det.vid.size;\n    ff->enc_vafp.buffer = NULL;\n    status = (*ff->enc_vfi->apply_fmt)(ff->enc_vfi, &ff->enc_vafp);\n    if (status != PJ_SUCCESS) {\n        goto on_error;\n    }\n\n    /* Alloc buffers if needed */\n    ff->whole = (ff->param.packing == PJMEDIA_VID_PACKING_WHOLE);\n    if (!ff->whole) {\n\tff->enc_buf_size = (unsigned)ff->enc_vafp.framebytes;\n\tff->enc_buf = pj_pool_alloc(ff->pool, ff->enc_buf_size);\n\n\tff->dec_buf_size = (unsigned)ff->dec_vafp.framebytes;\n\tff->dec_buf = pj_pool_alloc(ff->pool, ff->dec_buf_size);\n    }\n\n    /* Update codec attributes, e.g: encoding format may be changed by\n     * SDP fmtp negotiation.\n     */\n    pj_memcpy(attr, &ff->param, sizeof(*attr));\n\n    return PJ_SUCCESS;\n\non_error:\n    ffmpeg_codec_close(codec);\n    return status;\n}\n\n/*\n * Close codec.\n */\nstatic pj_status_t ffmpeg_codec_close( pjmedia_vid_codec *codec )\n{\n    ffmpeg_private *ff;\n    pj_mutex_t *ff_mutex;\n\n    PJ_ASSERT_RETURN(codec, PJ_EINVAL);\n    ff = (ffmpeg_private*)codec->codec_data;\n    ff_mutex = ((struct ffmpeg_factory*)codec->factory)->mutex;\n\n    pj_mutex_lock(ff_mutex);\n    if (ff->enc_ctx) {\n        avcodec_close(ff->enc_ctx);\n        av_free(ff->enc_ctx);\n    }\n    if (ff->dec_ctx && ff->dec_ctx!=ff->enc_ctx) {\n        avcodec_close(ff->dec_ctx);\n        av_free(ff->dec_ctx);\n    }\n    ff->enc_ctx = NULL;\n    ff->dec_ctx = NULL;\n    pj_mutex_unlock(ff_mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Modify codec settings.\n */\nstatic pj_status_t  ffmpeg_codec_modify( pjmedia_vid_codec *codec, \n\t\t\t\t         const pjmedia_vid_codec_param *attr)\n{\n    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;\n\n    PJ_UNUSED_ARG(attr);\n    PJ_UNUSED_ARG(ff);\n\n    return PJ_ENOTSUP;\n}\n\nstatic pj_status_t  ffmpeg_codec_get_param(pjmedia_vid_codec *codec,\n\t\t\t\t\t   pjmedia_vid_codec_param *param)\n{\n    ffmpeg_private *ff;\n\n    PJ_ASSERT_RETURN(codec && param, PJ_EINVAL);\n\n    ff = (ffmpeg_private*)codec->codec_data;\n    pj_memcpy(param, &ff->param, sizeof(*param));\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t  ffmpeg_packetize ( pjmedia_vid_codec *codec,\n                                       pj_uint8_t *bits,\n                                       pj_size_t bits_len,\n                                       unsigned *bits_pos,\n                                       const pj_uint8_t **payload,\n                                       pj_size_t *payload_len)\n{\n    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;\n\n    if (ff->desc->packetize) {\n\treturn (*ff->desc->packetize)(ff, bits, bits_len, bits_pos,\n                                      payload, payload_len);\n    }\n\n    return PJ_ENOTSUP;\n}\n\nstatic pj_status_t  ffmpeg_unpacketize(pjmedia_vid_codec *codec,\n                                       const pj_uint8_t *payload,\n                                       pj_size_t   payload_len,\n                                       pj_uint8_t *bits,\n                                       pj_size_t   bits_len,\n\t\t\t\t       unsigned   *bits_pos)\n{\n    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;\n\n    if (ff->desc->unpacketize) {\n        return (*ff->desc->unpacketize)(ff, payload, payload_len,\n                                        bits, bits_len, bits_pos);\n    }\n    \n    return PJ_ENOTSUP;\n}\n\n\n/*\n * Encode frames.\n */\nstatic pj_status_t ffmpeg_codec_encode_whole(pjmedia_vid_codec *codec,\n\t\t\t\t\t     const pjmedia_vid_encode_opt *opt,\n\t\t\t\t\t     const pjmedia_frame *input,\n\t\t\t\t\t     unsigned output_buf_len,\n\t\t\t\t\t     pjmedia_frame *output)\n{\n    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;\n    pj_uint8_t *p = (pj_uint8_t*)input->buf;\n    AVFrame avframe;\n    AVPacket avpacket;\n    int err, got_packet;\n    //AVRational src_timebase;\n    /* For some reasons (e.g: SSE/MMX usage), the avcodec_encode_video() must\n     * have stack aligned to 16 bytes. Let's try to be safe by preparing the\n     * 16-bytes aligned stack here, in case it's not managed by the ffmpeg.\n     */\n    PJ_ALIGN_DATA(pj_uint32_t i[4], 16);\n\n    if ((long)(pj_ssize_t)i & 0xF) {\n\tPJ_LOG(2,(THIS_FILE, \"Stack alignment fails\"));\n    }\n\n    /* Check if encoder has been opened */\n    PJ_ASSERT_RETURN(ff->enc_ctx, PJ_EINVALIDOP);\n\n    pj_bzero(&avframe, sizeof(avframe));\n    av_frame_unref(&avframe);\n\n    // Let ffmpeg manage the timestamps\n    /*\n    src_timebase.num = 1;\n    src_timebase.den = ff->desc->info.clock_rate;\n    avframe.pts = av_rescale_q(input->timestamp.u64, src_timebase,\n\t\t\t       ff->enc_ctx->time_base);\n    */\n    \n    for (i[0] = 0; i[0] < ff->enc_vfi->plane_cnt; ++i[0]) {\n        avframe.data[i[0]] = p;\n        avframe.linesize[i[0]] = ff->enc_vafp.strides[i[0]];\n        p += ff->enc_vafp.plane_bytes[i[0]];\n    }\n\n    /* Force keyframe */\n    if (opt && opt->force_keyframe) {\n#if LIBAVCODEC_VER_AT_LEAST(53,20)\n\tavframe.pict_type = AV_PICTURE_TYPE_I;\n#else\n\tavframe.pict_type = FF_I_TYPE;\n#endif\n    }\n\n    av_init_packet(&avpacket);\n    avpacket.data = (pj_uint8_t*)output->buf;\n    avpacket.size = output_buf_len;\n\n#if LIBAVCODEC_VER_AT_LEAST(54,15)\n    err = avcodec_encode_video2(ff->enc_ctx, &avpacket, &avframe, &got_packet);\n    if (!err && got_packet)\n\terr = avpacket.size;\n#else\n    PJ_UNUSED_ARG(got_packet);\n    err = avcodec_encode_video(ff->enc_ctx, avpacket.data, avpacket.size, &avframe);\n#endif\n\n    if (err < 0) {\n        print_ffmpeg_err(err);\n        return PJMEDIA_CODEC_EFAILED;\n    } else {\n        output->size = err;\n\toutput->bit_info = 0;\n\tif (avpacket.flags & AV_PKT_FLAG_KEY)\n\t    output->bit_info |= PJMEDIA_VID_FRM_KEYFRAME;\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t ffmpeg_codec_encode_begin(pjmedia_vid_codec *codec,\n\t\t\t\t\t     const pjmedia_vid_encode_opt *opt,\n\t\t\t\t\t     const pjmedia_frame *input,\n\t\t\t\t\t     unsigned out_size,\n\t\t\t\t\t     pjmedia_frame *output,\n\t\t\t\t\t     pj_bool_t *has_more)\n{\n    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;\n    pj_status_t status;\n\n    *has_more = PJ_FALSE;\n\n    if (ff->whole) {\n\tstatus = ffmpeg_codec_encode_whole(codec, opt, input, out_size,\n\t\t\t\t\t   output);\n    } else {\n\tpjmedia_frame whole_frm;\n        const pj_uint8_t *payload;\n        pj_size_t payload_len;\n\n\tpj_bzero(&whole_frm, sizeof(whole_frm));\n\twhole_frm.buf = ff->enc_buf;\n\twhole_frm.size = ff->enc_buf_size;\n\tstatus = ffmpeg_codec_encode_whole(codec, opt, input,\n\t                                   (unsigned)whole_frm.size, \n\t\t\t\t\t   &whole_frm);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tff->enc_buf_is_keyframe = (whole_frm.bit_info & \n\t\t\t\t   PJMEDIA_VID_FRM_KEYFRAME);\n\tff->enc_frame_len = (unsigned)whole_frm.size;\n\tff->enc_processed = 0;\n        status = ffmpeg_packetize(codec, (pj_uint8_t*)whole_frm.buf,\n                                  whole_frm.size, &ff->enc_processed,\n\t\t\t\t  &payload, &payload_len);\n        if (status != PJ_SUCCESS)\n            return status;\n\n        if (out_size < payload_len)\n            return PJMEDIA_CODEC_EFRMTOOSHORT;\n\n        output->type = PJMEDIA_FRAME_TYPE_VIDEO;\n        pj_memcpy(output->buf, payload, payload_len);\n        output->size = payload_len;\n\n\tif (ff->enc_buf_is_keyframe)\n\t    output->bit_info |= PJMEDIA_VID_FRM_KEYFRAME;\n\n        *has_more = (ff->enc_processed < ff->enc_frame_len);\n    }\n\n    return status;\n}\n\nstatic pj_status_t ffmpeg_codec_encode_more(pjmedia_vid_codec *codec,\n\t\t\t\t\t    unsigned out_size,\n\t\t\t\t\t    pjmedia_frame *output,\n\t\t\t\t\t    pj_bool_t *has_more)\n{\n    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;\n    const pj_uint8_t *payload;\n    pj_size_t payload_len;\n    pj_status_t status;\n\n    *has_more = PJ_FALSE;\n\n    if (ff->enc_processed >= ff->enc_frame_len) {\n\t/* No more frame */\n\treturn PJ_EEOF;\n    }\n\n    status = ffmpeg_packetize(codec, (pj_uint8_t*)ff->enc_buf,\n                              ff->enc_frame_len, &ff->enc_processed,\n                              &payload, &payload_len);\n    if (status != PJ_SUCCESS)\n        return status;\n\n    if (out_size < payload_len)\n        return PJMEDIA_CODEC_EFRMTOOSHORT;\n\n    output->type = PJMEDIA_FRAME_TYPE_VIDEO;\n    pj_memcpy(output->buf, payload, payload_len);\n    output->size = payload_len;\n\n    if (ff->enc_buf_is_keyframe)\n\toutput->bit_info |= PJMEDIA_VID_FRM_KEYFRAME;\n\n    *has_more = (ff->enc_processed < ff->enc_frame_len);\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t check_decode_result(pjmedia_vid_codec *codec,\n\t\t\t\t       const pj_timestamp *ts,\n\t\t\t\t       pj_bool_t got_keyframe)\n{\n    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;\n    pjmedia_video_apply_fmt_param *vafp = &ff->dec_vafp;\n    pjmedia_event event;\n\n    /* Check for format change.\n     * Decoder output format is set by libavcodec, in case it is different\n     * to the configured param.\n     */\n    if (ff->dec_ctx->pix_fmt != ff->expected_dec_fmt ||\n\tff->dec_ctx->width != (int)vafp->size.w ||\n\tff->dec_ctx->height != (int)vafp->size.h)\n    {\n\tpjmedia_format_id new_fmt_id;\n\tpj_status_t status;\n\n\t/* Get current raw format id from ffmpeg decoder context */\n\tstatus = PixelFormat_to_pjmedia_format_id(ff->dec_ctx->pix_fmt, \n\t\t\t\t\t\t  &new_fmt_id);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Update decoder format in param */\n\t\tff->param.dec_fmt.id = new_fmt_id;\n\tff->param.dec_fmt.det.vid.size.w = ff->dec_ctx->width;\n\tff->param.dec_fmt.det.vid.size.h = ff->dec_ctx->height;\n\tff->expected_dec_fmt = ff->dec_ctx->pix_fmt;\n\n\t/* Re-init format info and apply-param of decoder */\n\tff->dec_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id);\n\tif (!ff->dec_vfi)\n\t    return PJ_ENOTSUP;\n\tpj_bzero(&ff->dec_vafp, sizeof(ff->dec_vafp));\n\tff->dec_vafp.size = ff->param.dec_fmt.det.vid.size;\n\tff->dec_vafp.buffer = NULL;\n\tstatus = (*ff->dec_vfi->apply_fmt)(ff->dec_vfi, &ff->dec_vafp);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Realloc buffer if necessary */\n\tif (ff->dec_vafp.framebytes > ff->dec_buf_size) {\n\t    PJ_LOG(5,(THIS_FILE, \"Reallocating decoding buffer %u --> %u\",\n\t\t       (unsigned)ff->dec_buf_size,\n\t\t       (unsigned)ff->dec_vafp.framebytes));\n\t    ff->dec_buf_size = (unsigned)ff->dec_vafp.framebytes;\n\t    ff->dec_buf = pj_pool_alloc(ff->pool, ff->dec_buf_size);\n\t}\n\n\t/* Broadcast format changed event */\n\tpjmedia_event_init(&event, PJMEDIA_EVENT_FMT_CHANGED, ts, codec);\n\tevent.data.fmt_changed.dir = PJMEDIA_DIR_DECODING;\n\tpj_memcpy(&event.data.fmt_changed.new_fmt, &ff->param.dec_fmt,\n\t\t  sizeof(ff->param.dec_fmt));\n\tpjmedia_event_publish(NULL, codec, &event, 0);\n    }\n\n    /* Check for missing/found keyframe */\n    if (got_keyframe) {\n\tpj_get_timestamp(&ff->last_dec_keyframe_ts);\n\n\t/* Broadcast keyframe event */\n        pjmedia_event_init(&event, PJMEDIA_EVENT_KEYFRAME_FOUND, ts, codec);\n        pjmedia_event_publish(NULL, codec, &event, 0);\n    } else if (ff->last_dec_keyframe_ts.u64 == 0) {\n\t/* Broadcast missing keyframe event */\n\tpjmedia_event_init(&event, PJMEDIA_EVENT_KEYFRAME_MISSING, ts, codec);\n\tpjmedia_event_publish(NULL, codec, &event, 0);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Decode frame.\n */\nstatic pj_status_t ffmpeg_codec_decode_whole(pjmedia_vid_codec *codec,\n\t\t\t\t\t     const pjmedia_frame *input,\n\t\t\t\t\t     unsigned output_buf_len,\n\t\t\t\t\t     pjmedia_frame *output)\n{\n    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;\n    AVFrame avframe;\n    AVPacket avpacket;\n    int err, got_picture;\n\n    /* Check if decoder has been opened */\n    PJ_ASSERT_RETURN(ff->dec_ctx, PJ_EINVALIDOP);\n\n    /* Reset output frame bit info */\n    output->bit_info = 0;\n\n    /* Validate output buffer size */\n    // Do this validation later after getting decoding result, where the real\n    // decoded size will be assured.\n    //if (ff->dec_vafp.framebytes > output_buf_len)\n\t//return PJ_ETOOSMALL;\n\n    /* Init frame to receive the decoded data, the ffmpeg codec context will\n     * automatically provide the decoded buffer (single buffer used for the\n     * whole decoding session, and seems to be freed when the codec context\n     * closed).\n     */\n    pj_bzero(&avframe, sizeof(avframe));\n    av_frame_unref(&avframe);\n\n    /* Init packet, the container of the encoded data */\n    av_init_packet(&avpacket);\n    avpacket.data = (pj_uint8_t*)input->buf;\n    avpacket.size = (int)input->size;\n\n    /* ffmpeg warns:\n     * - input buffer padding, at least AV_INPUT_BUFFER_PADDING_SIZE\n     * - null terminated\n     * Normally, encoded buffer is allocated more than needed, so lets just\n     * bzero the input buffer end/pad, hope it will be just fine.\n     */\n    pj_bzero(avpacket.data+avpacket.size, AV_INPUT_BUFFER_PADDING_SIZE);\n\n    output->bit_info = 0;\n    output->timestamp = input->timestamp;\n\n#if LIBAVCODEC_VER_AT_LEAST(52,72)\n    //avpacket.flags = AV_PKT_FLAG_KEY;\n#else\n    avpacket.flags = 0;\n#endif\n\n#if LIBAVCODEC_VER_AT_LEAST(52,72)\n    err = avcodec_decode_video2(ff->dec_ctx, &avframe, \n                                &got_picture, &avpacket);\n#else\n    err = avcodec_decode_video(ff->dec_ctx, &avframe,\n                               &got_picture, avpacket.data, avpacket.size);\n#endif\n    if (err < 0) {\n\tpjmedia_event event;\n\n\toutput->type = PJMEDIA_FRAME_TYPE_NONE;\n\toutput->size = 0;\n        print_ffmpeg_err(err);\n\n\t/* Broadcast missing keyframe event */\n\tpjmedia_event_init(&event, PJMEDIA_EVENT_KEYFRAME_MISSING,\n\t\t\t   &input->timestamp, codec);\n\tpjmedia_event_publish(NULL, codec, &event, 0);\n\n\treturn PJMEDIA_CODEC_EBADBITSTREAM;\n    } else if (got_picture) {\n        pjmedia_video_apply_fmt_param *vafp = &ff->dec_vafp;\n        pj_uint8_t *q = (pj_uint8_t*)output->buf;\n\tunsigned i;\n\tpj_status_t status;\n\n\t/* Check decoding result, e.g: see if the format got changed,\n\t * keyframe found/missing.\n\t */\n\tstatus = check_decode_result(codec, &input->timestamp,\n\t\t\t\t     avframe.key_frame);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Check provided buffer size */\n\tif (vafp->framebytes > output_buf_len)\n\t    return PJ_ETOOSMALL;\n\n\t/* Get the decoded data */\n\tfor (i = 0; i < ff->dec_vfi->plane_cnt; ++i) {\n\t    pj_uint8_t *p = avframe.data[i];\n\n\t    /* The decoded data may contain padding */\n\t    if (avframe.linesize[i]!=vafp->strides[i]) {\n\t\t/* Padding exists, copy line by line */\n\t\tpj_uint8_t *q_end;\n                    \n\t\tq_end = q+vafp->plane_bytes[i];\n\t\twhile(q < q_end) {\n\t\t    pj_memcpy(q, p, vafp->strides[i]);\n\t\t    q += vafp->strides[i];\n\t\t    p += avframe.linesize[i];\n\t\t}\n\t    } else {\n\t\t/* No padding, copy the whole plane */\n\t\tpj_memcpy(q, p, vafp->plane_bytes[i]);\n\t\tq += vafp->plane_bytes[i];\n\t    }\n\t}\n\n\toutput->type = PJMEDIA_FRAME_TYPE_VIDEO;\n        output->size = vafp->framebytes;\n    } else {\n\toutput->type = PJMEDIA_FRAME_TYPE_NONE;\n\toutput->size = 0;\n    }\n    \n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec,\n\t\t\t\t\tpj_size_t pkt_count,\n\t\t\t\t\tpjmedia_frame packets[],\n\t\t\t\t\tunsigned out_size,\n\t\t\t\t\tpjmedia_frame *output)\n{\n    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(codec && pkt_count > 0 && packets && output,\n                     PJ_EINVAL);\n\n    if (ff->whole) {\n\tpj_assert(pkt_count==1);\n\treturn ffmpeg_codec_decode_whole(codec, &packets[0], out_size, output);\n    } else {\n\tpjmedia_frame whole_frm;\n\tunsigned whole_len = 0;\n\tunsigned i;\n\n\tfor (i=0; i<pkt_count; ++i) {\n\t    if (whole_len + packets[i].size > ff->dec_buf_size) {\n\t\tPJ_LOG(5,(THIS_FILE, \"Decoding buffer overflow\"));\n\t\tbreak;\n\t    }\n\n\t    status = ffmpeg_unpacketize(codec, packets[i].buf, packets[i].size,\n\t                                ff->dec_buf, ff->dec_buf_size,\n\t                                &whole_len);\n\t    if (status != PJ_SUCCESS) {\n\t\tPJ_PERROR(5,(THIS_FILE, status, \"Unpacketize error\"));\n\t\tcontinue;\n\t    }\n\t}\n\n\twhole_frm.buf = ff->dec_buf;\n\twhole_frm.size = whole_len;\n\twhole_frm.timestamp = output->timestamp = packets[i].timestamp;\n\twhole_frm.bit_info = 0;\n\n\treturn ffmpeg_codec_decode_whole(codec, &whole_frm, out_size, output);\n    }\n}\n\n\n#ifdef _MSC_VER\n#   pragma comment( lib, \"avcodec.lib\")\n#endif\n\n#endif\t/* PJMEDIA_HAS_FFMPEG_VID_CODEC */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/g722/g722_dec.c",
    "content": "/* $Id: g722_dec.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n/*\n * Based on implementation found in Carnegie Mellon Speech Group Software\n * depository (ftp://ftp.cs.cmu.edu/project/fgdata/index.html). No copyright\n * was claimed in the original source codes.\n */\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n\n#include \"g722_dec.h\"\n\n#if defined(PJMEDIA_HAS_G722_CODEC) && (PJMEDIA_HAS_G722_CODEC != 0)\n\n#define MODE 1\n\n#define SATURATE(v, max, min) \\\n    if (v>max) v = max; \\\n    else if (v<min) v = min\n\nextern const int g722_qmf_coeff[24];\n\nstatic const int qm4[16] = \n{\n\t0, -20456, -12896, -8968,\n    -6288,  -4240,  -2584, -1200,\n    20456,  12896,   8968,  6288,\n     4240,   2584,   1200,     0\n};\nstatic const int ilb[32] = {\n    2048, 2093, 2139, 2186, 2233, 2282, 2332,\n    2383, 2435, 2489, 2543, 2599, 2656, 2714, \n    2774, 2834, 2896, 2960, 3025, 3091, 3158, \n    3228, 3298, 3371, 3444, 3520, 3597, 3676,\n    3756, 3838, 3922, 4008\n};\n\n\nstatic int block2l (int il, int detl)\n{\n    int dlt ;\n    int ril, wd2 ;\n\n    /* INVQAL */\n    ril = il >> 2 ;\n    wd2 = qm4[ril] ;\n    dlt = (detl * wd2) >> 15 ;\n\n    return (dlt) ;\n}\n\n\nstatic int block3l (g722_dec_t *dec, int il)\n{\n    int detl ;\n    int ril, il4, wd, wd1, wd2, wd3, nbpl, depl ;\n    static const int  wl[8] = {\n\t-60, -30, 58, 172, 334, 538, 1198, 3042\n    };\n    static const int rl42[16] = {\n\t0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0\n    };\n\n    /* LOGSCL */\n    ril = il >> 2 ;\n    il4 = rl42[ril] ;\n    wd = (dec->nbl * 32512) >> 15 ;\n    nbpl = wd + wl[il4] ;\n\n    if (nbpl <     0) nbpl = 0 ;\n    if (nbpl > 18432) nbpl = 18432 ;\n\n    /* SCALEL */\n    wd1 =  (nbpl >> 6) & 31 ;\n    wd2 = nbpl >> 11 ;\n    if ((8 - wd2) < 0)   wd3 = ilb[wd1] << (wd2 - 8) ;\n    else wd3 = ilb[wd1] >> (8 - wd2) ;\n    depl = wd3 << 2 ;\n\n    /* DELAYA */\n    dec->nbl = nbpl ;\n    /* DELAYL */\n    detl = depl ;\n\n    return (detl) ;\n}\n\n\nstatic int block4l (g722_dec_t *dec, int dl)\n{\n    int sl = dec->slow ;\n    int i ;\n    int wd, wd1, wd2, wd3, wd4, wd5/*, wd6 */;\n\n    dec->dlt[0] = dl;\n\n    /* RECONS */ \n    dec->rlt[0] = sl + dec->dlt[0] ;\n    SATURATE(dec->rlt[0], 32767, -32768);\n\n    /* PARREC */\n    dec->plt[0] = dec->dlt[0] + dec->szl ;\n    SATURATE(dec->plt[0], 32767, -32768);\n\n    /* UPPOL2 */\n    dec->sgl[0] = dec->plt[0] >> 15 ;\n    dec->sgl[1] = dec->plt[1] >> 15 ;\n    dec->sgl[2] = dec->plt[2] >> 15 ;\n\n    wd1 = dec->al[1] << 2;\n    SATURATE(wd1, 32767, -32768);\n\n    if ( dec->sgl[0] == dec->sgl[1] )  wd2 = - wd1 ;\n    else  wd2 = wd1 ;\n    if (wd2 > 32767) wd2 = 32767;\n    wd2 = wd2 >> 7 ;\n\n    if ( dec->sgl[0] == dec->sgl[2] )  wd3 = 128 ; \n    else  wd3 = - 128 ;\n\n    wd4 = wd2 + wd3 ;\n    wd5 = (dec->al[2] * 32512) >> 15 ;\n\n    dec->apl[2] = wd4 + wd5 ;\n    SATURATE(dec->apl[2], 12288, -12288);\n    \n    /* UPPOL1 */\n    dec->sgl[0] = dec->plt[0] >> 15 ;\n    dec->sgl[1] = dec->plt[1] >> 15 ;\n\n    if ( dec->sgl[0] == dec->sgl[1] )  wd1 = 192 ;\n    else  wd1 = - 192 ;\n\n    wd2 = (dec->al[1] * 32640) >> 15 ;\n\n    dec->apl[1] = wd1 + wd2 ;\n    SATURATE(dec->apl[1], 32767, -32768);\n\n    wd3 = (15360 - dec->apl[2]) ;\n    SATURATE(wd3, 32767, -32768);\n    if ( dec->apl[1] >  wd3)  dec->apl[1] =  wd3 ;\n    if ( dec->apl[1] < -wd3)  dec->apl[1] = -wd3 ;\n\n    /* UPZERO */\n    if ( dec->dlt[0] == 0 )  wd1 = 0 ;\n    else  wd1 = 128 ;\n\n    dec->sgl[0] = dec->dlt[0] >> 15 ;\n\n    for ( i = 1; i < 7; i++ ) {\n\tdec->sgl[i] = dec->dlt[i] >> 15 ;\n\tif ( dec->sgl[i] == dec->sgl[0] )  wd2 = wd1 ;\n\telse  wd2 = - wd1 ;\n\twd3 = (dec->bl[i] * 32640) >> 15 ;\n\tdec->bpl[i] = wd2 + wd3 ;\n\tSATURATE(dec->bpl[i], 32767, -32768);\n    }\n\n    /* DELAYA */\n    for ( i = 6; i > 0; i-- ) {\n\tdec->dlt[i] = dec->dlt[i-1] ;\n\tdec->bl[i]  = dec->bpl[i] ;\n    }\n\n    for ( i = 2; i > 0; i-- ) {\n\tdec->rlt[i] = dec->rlt[i-1] ;\n\tdec->plt[i] = dec->plt[i-1] ;\n\tdec->al[i]  = dec->apl[i] ;\n    }\n\n    /* FILTEP */\n    wd1 = dec->rlt[1] << 1;\n    SATURATE(wd1, 32767, -32768);\n    wd1 = ( dec->al[1] * wd1 ) >> 15 ;\n\n    wd2 = dec->rlt[2] << 1;\n    SATURATE(wd2, 32767, -32768);\n    wd2 = ( dec->al[2] * wd2 ) >> 15 ;\n\n    dec->spl = wd1 + wd2 ;\n    SATURATE(dec->spl, 32767, -32768);\n\n    /* FILTEZ */\n    dec->szl = 0 ;\n    for (i=6; i>0; i--) {\n\twd = dec->dlt[i] << 1;\n\tSATURATE(wd, 32767, -32768);\n\tdec->szl += (dec->bl[i] * wd) >> 15 ;\n\tSATURATE(dec->szl, 32767, -32768);\n    }\n\n    /* PREDIC */\n    sl = dec->spl + dec->szl ;\n    SATURATE(sl, 32767, -32768);\n\n    return (sl) ;\n}\n\nstatic int block5l (int ilr, int sl, int detl, int mode)\n{\n    int yl ;\n    int ril, dl, wd2 = 0;\n    static const int qm5[32] = {\n\t  -280,   -280, -23352, -17560,\n\t-14120, -11664,  -9752,  -8184,\n\t -6864,  -5712,  -4696,  -3784,\n\t -2960,  -2208,  -1520,   -880,\n\t 23352,  17560,  14120,  11664,\n\t  9752,   8184,   6864,   5712,\n\t  4696,   3784,   2960,   2208,\n\t  1520,    880,    280,   -280\n    };\n    static const int qm6[64] = {\n\t-136,\t-136,\t-136,\t-136,\n\t-24808,\t-21904,\t-19008,\t-16704,\n\t-14984,\t-13512,\t-12280,\t-11192,\n\t-10232,\t-9360,\t-8576,\t-7856,\n\t-7192,\t-6576,\t-6000,\t-5456,\n\t-4944,\t-4464,\t-4008,\t-3576,\n\t-3168,\t-2776,\t-2400,\t-2032,\n\t-1688,\t-1360,\t-1040,\t-728,\n\t24808,\t21904,\t19008,\t16704,\n\t14984,\t13512,\t12280,\t11192,\n\t10232,\t9360,\t8576,\t7856,\n\t7192,\t6576,\t6000,\t5456,\n\t4944,\t4464,\t4008,\t3576,\n\t3168,\t2776,\t2400,\t2032,\n\t1688,\t1360,\t1040,\t728,\n\t432,\t136,\t-432,\t-136\n    };\n    \n    /* INVQBL */\n    if (mode == 1) {\n\tril = ilr ;\n\twd2 = qm6[ril] ;\n    }\n\n    if (mode == 2) {\n\tril = ilr >> 1 ;\n\twd2 = qm5[ril] ;\n    }\n\n    if (mode == 3) {\n\tril = ilr >> 2 ;\n\twd2 = qm4[ril] ;\n    }\n\n    dl = (detl * wd2 ) >> 15 ;\n\n    /* RECONS */\n    yl = sl + dl ;\n    SATURATE(yl, 32767, -32768);\n\n    return (yl) ;\n}\n\nstatic int block6l (int yl)\n{\n    int rl ;\n\n    rl = yl ;\n    SATURATE(rl, 16383, -16384);\n\n    return (rl) ;\n}\n\nstatic int block2h (int ih, int deth)\n{\n    int dh ;\n    int wd2 ;\n    static const int qm2[4] = {-7408, -1616, 7408, 1616} ;\n    \n    /* INVQAH */\n    wd2 = qm2[ih] ;\n    dh = (deth * wd2) >> 15 ;\n\n    return (dh) ;\n}\n\nstatic int block3h (g722_dec_t *dec, int ih)\n{\n    int deth ;\n    int ih2, wd, wd1, wd2, wd3, nbph, deph ;\n    static const int wh[3] = {0, -214, 798} ;\n    static const int rh2[4] = {2, 1, 2, 1} ;\n    \n    /* LOGSCH */\n    ih2 = rh2[ih] ;\n    wd = (dec->nbh * 32512) >> 15 ;\n    nbph = wd + wh[ih2] ;\n\n    if (nbph <     0) nbph = 0 ;\n    if (nbph > 22528) nbph = 22528 ;\n\n\n    /* SCALEH */\n    wd1 =  (nbph >> 6) & 31 ;\n    wd2 = nbph >> 11 ;\n    if ((10 - wd2) < 0) wd3 = ilb[wd1] << (wd2 - 10) ;\n    else wd3 = ilb[wd1] >> (10 - wd2) ;\n    deph = wd3 << 2 ;\n\n    /* DELAYA */\n    dec->nbh = nbph ;\n    \n    /* DELAYH */\n    deth = deph ;\n\n    return (deth) ;\n}\n\nstatic int block4h (g722_dec_t *dec, int d)\n{\n    int sh = dec->shigh;\n    int i ;\n    int wd, wd1, wd2, wd3, wd4, wd5/*, wd6 */;\n\n    dec->dh[0] = d;\n\n    /* RECONS */ \n    dec->rh[0] = sh + dec->dh[0] ;\n    SATURATE(dec->rh[0], 32767, -32768);\n\n    /* PARREC */\n    dec->ph[0] = dec->dh[0] + dec->szh ;\n    SATURATE(dec->ph[0], 32767, -32768);\n\n    /* UPPOL2 */\n    dec->sgh[0] = dec->ph[0] >> 15 ;\n    dec->sgh[1] = dec->ph[1] >> 15 ;\n    dec->sgh[2] = dec->ph[2] >> 15 ;\n\n    wd1 = dec->ah[1] << 2;\n    SATURATE(wd1, 32767, -32768);\n\n    if ( dec->sgh[0] == dec->sgh[1] )  wd2 = - wd1 ;\n    else  wd2 = wd1 ;\n    if (wd2 > 32767) wd2 = 32767;\n\n    wd2 = wd2 >> 7 ;\n\n    if ( dec->sgh[0] == dec->sgh[2] )  wd3 = 128 ; \n    else  wd3 = - 128 ;\n\n    wd4 = wd2 + wd3 ;\n    wd5 = (dec->ah[2] * 32512) >> 15 ;\n\n    dec->aph[2] = wd4 + wd5 ;\n    SATURATE(dec->aph[2], 12288, -12288);\n    \n    /* UPPOL1 */\n    dec->sgh[0] = dec->ph[0] >> 15 ;\n    dec->sgh[1] = dec->ph[1] >> 15 ;\n\n    if ( dec->sgh[0] == dec->sgh[1] )  wd1 = 192 ;\n    else  wd1 = - 192 ;\n\n    wd2 = (dec->ah[1] * 32640) >> 15 ;\n\n    dec->aph[1] = wd1 + wd2 ;\n    SATURATE(dec->aph[1], 32767, -32768);\n    //dec->aph[2]?\n    //if (aph[2] > 32767) aph[2] = 32767;\n    //if (aph[2] < -32768) aph[2] = -32768;\n\n    wd3 = (15360 - dec->aph[2]) ;\n    SATURATE(wd3, 32767, -32768);\n    if ( dec->aph[1] >  wd3)  dec->aph[1] =  wd3 ;\n    if ( dec->aph[1] < -wd3)  dec->aph[1] = -wd3 ;\n\n    /* UPZERO */\n    if ( dec->dh[0] == 0 )  wd1 = 0 ;\n    if ( dec->dh[0] != 0 )  wd1 = 128 ;\n\n    dec->sgh[0] = dec->dh[0] >> 15 ;\n\n    for ( i = 1; i < 7; i++ ) {\n\tdec->sgh[i] = dec->dh[i] >> 15 ;\n\tif ( dec->sgh[i] == dec->sgh[0] )  wd2 = wd1 ;\n\telse wd2 = - wd1 ;\n\twd3 = (dec->bh[i] * 32640) >> 15 ;\n\tdec->bph[i] = wd2 + wd3 ;\n    }\n \n    /* DELAYA */\n    for ( i = 6; i > 0; i-- ) {\n\tdec->dh[i] = dec->dh[i-1] ;\n\tdec->bh[i] = dec->bph[i] ;\n    }\n\n    for ( i = 2; i > 0; i-- ) {\n\tdec->rh[i] = dec->rh[i-1] ;\n\tdec->ph[i] = dec->ph[i-1] ;\n\tdec->ah[i] = dec->aph[i] ;\n    }\n\n    /* FILTEP */\n    wd1 = dec->rh[1] << 1 ;\n    SATURATE(wd1, 32767, -32768);\n    wd1 = ( dec->ah[1] * wd1 ) >> 15 ;\n\n    wd2 = dec->rh[2] << 1;\n    SATURATE(wd2, 32767, -32768);\n    wd2 = ( dec->ah[2] * wd2 ) >> 15 ;\n\n    dec->sph = wd1 + wd2 ;\n    SATURATE(dec->sph, 32767, -32768);\n\n    /* FILTEZ */\n    dec->szh = 0 ;\n    for (i=6; i>0; i--) {\n\twd = dec->dh[i] << 1;\n\tSATURATE(wd, 32767, -32768);\n\tdec->szh += (dec->bh[i] * wd) >> 15 ;\n\tSATURATE(dec->szh, 32767, -32768);\n    }\n\n    /* PREDIC */\n    sh = dec->sph + dec->szh ;\n    SATURATE(sh, 32767, -32768);\n\n    return (sh) ;\n}\n\nstatic int block5h (int dh, int sh)\n{\n    int rh ;\n\n    rh = dh + sh;\n    SATURATE(rh, 16383, -16384);\n\n    return (rh) ;\n}\n\nstatic void rx_qmf(g722_dec_t *dec, int rl, int rh, int *xout1, int *xout2)\n{\n    int i;\n\n    pj_memmove(&dec->xd[1], dec->xd, 11*sizeof(dec->xd[0]));\n    pj_memmove(&dec->xs[1], dec->xs, 11*sizeof(dec->xs[0]));\n\n    /* RECA */\n    dec->xd[0] = rl - rh ;\n    if (dec->xd[0] > 16383) dec->xd[0] = 16383;\n    else if (dec->xd[0] < -16384) dec->xd[0] = -16384;\n    \n    /* RECB */\n    dec->xs[0] = rl + rh ;\n    if (dec->xs[0] > 16383) dec->xs[0] = 16383;\n    else if (dec->xs[0] < -16384) dec->xs[0] = -16384;\n    \n    /* ACCUMC */\n    *xout1 = 0;\n    for (i=0; i<12; ++i) *xout1 += dec->xd[i] * g722_qmf_coeff[2*i];\n    *xout1 = *xout1 >> 12 ;\n    if (*xout1 >  16383)  *xout1 =  16383 ;\n    else if (*xout1 < -16384)  *xout1 = -16384 ;\n    \n    /* ACCUMD */\n    *xout2 = 0;\n    for (i=0; i<12; ++i) *xout2 += dec->xs[i] * g722_qmf_coeff[2*i+1];\n    *xout2  = *xout2  >> 12 ;\n    if (*xout2  >  16383)  *xout2  =  16383 ;\n    else if (*xout2  < -16384)  *xout2  = -16384 ;\n}\n\n\nPJ_DEF(pj_status_t) g722_dec_init(g722_dec_t *dec)\n{\n    PJ_ASSERT_RETURN(dec, PJ_EINVAL);\n\n    pj_bzero(dec, sizeof(g722_dec_t));\n\n    dec->detlow = 32;\n    dec->dethigh = 8;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) g722_dec_decode( g722_dec_t *dec, \n\t\t\t\t    void *in, \n\t\t\t\t    pj_size_t in_size,\n\t\t\t\t    pj_int16_t out[],\n\t\t\t\t    pj_size_t *nsamples)\n{\n    unsigned i;\n    int ilowr, ylow, rlow, dlowt;\n    int ihigh, rhigh, dhigh;\n    int pcm1, pcm2;\n    pj_uint8_t *in_ = (pj_uint8_t*) in;\n\n    PJ_ASSERT_RETURN(dec && in && in_size && out && nsamples, PJ_EINVAL);\n    PJ_ASSERT_RETURN(*nsamples >= (in_size << 1), PJ_ETOOSMALL);\n\n    for(i = 0; i < in_size; ++i) {\n\tilowr = in_[i] & 63;\n\tihigh = (in_[i] >> 6) & 3;\n\n\t/* low band decoder */\n\tylow = block5l (ilowr, dec->slow, dec->detlow, MODE) ;\t\n\trlow = block6l (ylow) ;\n\tdlowt = block2l (ilowr, dec->detlow) ;\n\tdec->detlow = block3l (dec, ilowr) ;\n\tdec->slow = block4l (dec, dlowt) ;\n\t/* rlow <= output low band pcm */\n\n\t/* high band decoder */\n\tdhigh = block2h (ihigh, dec->dethigh) ;\n\trhigh = block5h (dhigh, dec->shigh) ;\n\tdec->dethigh = block3h (dec, ihigh) ;\n\tdec->shigh = block4h (dec, dhigh) ;\n\t/* rhigh <= output high band pcm */\n\n\trx_qmf(dec, rlow, rhigh, &pcm1, &pcm2);\n\tout[i*2]   = (pj_int16_t)pcm1;\n\tout[i*2+1] = (pj_int16_t)pcm2;\n    }\n\n    *nsamples = in_size << 1;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) g722_dec_deinit(g722_dec_t *dec)\n{\n    pj_bzero(dec, sizeof(g722_dec_t));\n\n    return PJ_SUCCESS;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/g722/g722_dec.h",
    "content": "/* $Id: g722_dec.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n/*\n * Based on implementation found in Carnegie Mellon Speech Group Software\n * depository (ftp://ftp.cs.cmu.edu/project/fgdata/index.html). No copyright\n * was claimed in the original source codes.\n */\n#ifndef __PJMEDIA_CODEC_G722_DEC_H__\n#define __PJMEDIA_CODEC_G722_DEC_H__\n\n#include <pjmedia-codec/types.h>\n\n/* Decoder state */\ntypedef struct g722_dec_t {\n    /* PCM low band */\n    int slow;\n    int detlow;\n    int spl;\n    int szl;\n    int rlt  [3];\n    int al   [3];\n    int apl  [3];\n    int plt  [3];\n    int dlt  [7];\n    int bl   [7];\n    int bpl  [7];\n    int sgl  [7];\n    int nbl;\n\n    /* PCM high band*/\n    int shigh;\n    int dethigh;\n    int sph;\n    int szh;\n    int rh   [3];\n    int ah   [3];\n    int aph  [3];\n    int ph   [3];\n    int dh   [7];\n    int bh   [7];\n    int bph  [7];\n    int sgh  [7];\n    int nbh;\n\n    /* QMF signal history */\n    int xd[12];\n    int xs[12];\n} g722_dec_t;\n\n\nPJ_DECL(pj_status_t) g722_dec_init(g722_dec_t *dec);\n\nPJ_DECL(pj_status_t) g722_dec_decode(g722_dec_t *dec, \n\t\t\t\t     void *in, \n\t\t\t\t     pj_size_t in_size,\n\t\t\t\t     pj_int16_t out[],\n\t\t\t\t     pj_size_t *nsamples);\n\nPJ_DECL(pj_status_t) g722_dec_deinit(g722_dec_t *dec);\n\n#endif /* __PJMEDIA_CODEC_G722_DEC_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/g722/g722_enc.c",
    "content": "/* $Id: g722_enc.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n/*\n * Based on implementation found in Carnegie Mellon Speech Group Software\n * depository (ftp://ftp.cs.cmu.edu/project/fgdata/index.html). No copyright\n * was claimed in the original source codes.\n */\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n\n#include \"g722_enc.h\"\n\n#if defined(PJMEDIA_HAS_G722_CODEC) && (PJMEDIA_HAS_G722_CODEC != 0)\n\n#define SATURATE(v, max, min) \\\n    if (v>max) v = max; \\\n    else if (v<min) v = min\n\n/* QMF tap coefficients */\nconst int g722_qmf_coeff[24] = {\n     3,\t    -11,    -11,    53,\t    12,\t    -156,\n    32,\t    362,    -210,   -805,   951,    3876,\n    3876,   951,    -805,   -210,   362,    32,\n    -156,   12,\t    53,\t    -11,    -11,    3\n};\n\n\nstatic int block1l (int xl, int sl, int detl)\n{\n    int il ;\n\n    int i, el, sil, mil, wd, wd1, hdu ;\n\n    static const int q6[32] = {\n\t0, 35, 72, 110, 150, 190, 233, 276, 323,\n\t370, 422, 473, 530, 587, 650, 714, 786,\n\t858, 940, 1023, 1121, 1219, 1339, 1458,\n\t1612, 1765, 1980, 2195, 2557, 2919, 0, 0\n    };\n\n    static const int iln[32] = {\n\t0, 63, 62, 31, 30, 29, 28, 27, 26, 25,\n\t24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14,\n\t13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 0 \n    };\n\n    static const int ilp[32] = {\n\t0, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52,\n\t51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41,\n\t40, 39, 38, 37, 36, 35, 34, 33, 32, 0 \n    };\n\n    /* SUBTRA */\n\n    el = xl - sl ;\n    SATURATE(el, 32767, -32768);\n\n    /* QUANTL */\n\n    sil = el >> 15 ;\n    if (sil == 0 )  wd = el ;\n    else wd = (32767 - el) & 32767 ;\n\n    mil = 1 ;\n\n    for (i = 1; i < 30; i++) {\n\thdu = (q6[i] << 3) * detl;\n\twd1 = (hdu >> 15) ;\n\tif (wd >= wd1)  mil = (i + 1) ;\n\telse break ;\n    }\n\n    if (sil == -1 ) il = iln[mil] ;\n    else il = ilp[mil] ;\n\n    return (il) ;\n}\n\nstatic int block2l (int il, int detl)\n{\n    int dlt;\n    int ril, wd2 ;\n    static const int qm4[16] = {\n\t0,\t-20456,\t-12896,\t-8968,\n\t-6288,\t-4240,\t-2584,\t-1200,\n\t20456,\t12896,\t8968,\t6288,\n\t4240,\t2584,\t1200,\t0\n    };\n\n    /* INVQAL */\n    ril = il >> 2 ;\n    wd2 = qm4[ril] ;\n    dlt = (detl * wd2) >> 15 ;\n\n    return (dlt) ;\n}\n\nstatic int block3l (g722_enc_t *enc, int il)\n{\n    int detl;\n    int ril, il4, wd, wd1, wd2, wd3, nbpl, depl ;\n    static int const wl[8] = {\n\t-60, -30, 58, 172, 334, 538, 1198, 3042\n    } ;\n    static int const rl42[16] = {\n\t0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0\n    };\n    static const int ilb[32] = {\n\t2048, 2093, 2139, 2186, 2233, 2282, 2332,\n\t2383, 2435, 2489, 2543, 2599, 2656, 2714,\n\t2774, 2834, 2896, 2960, 3025, 3091, 3158,\n\t3228, 3298, 3371, 3444, 3520, 3597, 3676,\n\t3756, 3838, 3922, 4008\n    };\n\n    /* LOGSCL */\n\n    ril = il >> 2 ;\n    il4 = rl42[ril] ;\n    \n    wd = (enc->nbl * 32512) >> 15 ;\n    nbpl = wd + wl[il4] ;\n\n    if (nbpl <     0) nbpl = 0 ;\n    if (nbpl > 18432) nbpl = 18432 ;\n\n    /* SCALEL */\n\n    wd1 =  (nbpl >> 6) & 31 ;\n    wd2 = nbpl >> 11 ;\n    if ((8 - wd2) < 0)    wd3 = ilb[wd1] << (wd2 - 8) ;\n    else   wd3 = ilb[wd1] >> (8 - wd2) ;\n    depl = wd3 << 2 ;\n\n    /* DELAYA */\n    enc->nbl = nbpl ;\n\n    /* DELAYL */\n    detl = depl ;\n\n#ifdef DEBUG_VERBOSE\n\tprintf (\"BLOCK3L il=%4d, ril=%4d, il4=%4d, nbl=%4d, wd=%4d, nbpl=%4d\\n\",\n\t\t il, ril, il4, enc->nbl, wd, nbpl) ;\n\tprintf (\"wd1=%4d, wd2=%4d, wd3=%4d, depl=%4d, detl=%4d\\n\",\n\t\twd1, wd2, wd3, depl, detl) ;\n#endif\n\n    return (detl) ;\n}\n\nstatic int block4l (g722_enc_t *enc, int dl)\n{\n    int sl = enc->slow;\n    int i ;\n    int wd, wd1, wd2, wd3, wd4, wd5 /*, wd6 */;\n\n    enc->dlt[0] = dl;\n    \n    /* RECONS */\n\n    enc->rlt[0] = sl + enc->dlt[0] ;\n    SATURATE(enc->rlt[0], 32767, -32768);\n\n    /* PARREC */\n\n    enc->plt[0] = enc->dlt[0] + enc->szl ;\n    SATURATE(enc->plt[0], 32767, -32768);\n\n    /* UPPOL2 */\n\n    enc->sgl[0] = enc->plt[0] >> 15 ;\n    enc->sgl[1] = enc->plt[1] >> 15 ;\n    enc->sgl[2] = enc->plt[2] >> 15 ;\n\n    wd1 = enc->al[1] << 2;\n    SATURATE(wd1, 32767, -32768);\n\n    if ( enc->sgl[0] == enc->sgl[1] )  wd2 = - wd1 ;\n    else  wd2 = wd1 ;\n    if ( wd2 > 32767 ) wd2 = 32767;\n\n    wd2 = wd2 >> 7 ;\n\n    if ( enc->sgl[0] == enc->sgl[2] )  wd3 = 128 ;\n    else  wd3 = - 128 ;\n\n    wd4 = wd2 + wd3 ;\n    wd5 = (enc->al[2] * 32512) >> 15 ;\n\n    enc->apl[2] = wd4 + wd5 ;\n    SATURATE(enc->apl[2], 12288, -12288);\n\n    /* UPPOL1 */\n\n    enc->sgl[0] = enc->plt[0] >> 15 ;\n    enc->sgl[1] = enc->plt[1] >> 15 ;\n\n    if ( enc->sgl[0] == enc->sgl[1] )  wd1 = 192 ;\n    else  wd1 = - 192 ;\n\n    wd2 = (enc->al[1] * 32640) >> 15 ;\n\n    enc->apl[1] = wd1 + wd2 ;\n    SATURATE(enc->apl[1], 32767, -32768);\n\n    wd3 = (15360 - enc->apl[2]) ;\n    SATURATE(wd3, 32767, -32768);\n\n    if ( enc->apl[1] >  wd3)  enc->apl[1] =  wd3 ;\n    if ( enc->apl[1] < -wd3)  enc->apl[1] = -wd3 ;\n\n    /* UPZERO */\n\n    if ( enc->dlt[0] == 0 )  wd1 = 0 ;\n    else wd1 = 128 ;\n\n    enc->sgl[0] = enc->dlt[0] >> 15 ;\n\n    for ( i = 1; i < 7; i++ ) {\n\tenc->sgl[i] = enc->dlt[i] >> 15 ;\n\tif ( enc->sgl[i] == enc->sgl[0] )  wd2 = wd1 ;\n\telse wd2 = - wd1 ;\n\twd3 = (enc->bl[i] * 32640) >> 15 ;\n\tenc->bpl[i] = wd2 + wd3 ;\n\tSATURATE(enc->bpl[i], 32767, -32768);\n    }\n\n    /* DELAYA */\n\n    for ( i = 6; i > 0; i-- ) {\n\tenc->dlt[i] = enc->dlt[i-1] ;\n\tenc->bl[i]  = enc->bpl[i] ;\n    }\n\n    for ( i = 2; i > 0; i-- ) {\n\tenc->rlt[i] = enc->rlt[i-1] ;\n\tenc->plt[i] = enc->plt[i-1] ;\n\tenc->al[i] = enc->apl[i] ;\n    }\n\n    /* FILTEP */\n\n    wd1 = enc->rlt[1] + enc->rlt[1];\n    SATURATE(wd1, 32767, -32768);\n    wd1 = ( enc->al[1] * wd1 ) >> 15 ;\n\n    wd2 = enc->rlt[2] + enc->rlt[2];\n    SATURATE(wd2, 32767, -32768);\n    wd2 = ( enc->al[2] * wd2 ) >> 15 ;\n\n    enc->spl = wd1 + wd2 ;\n    SATURATE(enc->spl, 32767, -32768);\n\n    /* FILTEZ */\n\n    enc->szl = 0 ;\n    for (i=6; i>0; i--) {\n\twd = enc->dlt[i] + enc->dlt[i];\n\tSATURATE(wd, 32767, -32768);\n\tenc->szl += (enc->bl[i] * wd) >> 15 ;\n\tSATURATE(enc->szl, 32767, -32768);\n    }\n\n    /* PREDIC */\n\n    sl = enc->spl + enc->szl ;\n    SATURATE(sl, 32767, -32768);\n\n    return (sl) ;\n}\n\nstatic int block1h (int xh, int sh, int deth)\n{\n    int ih ;\n\n    int eh, sih, mih, wd, wd1, hdu ;\n\n    static const int ihn[3] = { 0, 1, 0 } ;\n    static const int ihp[3] = { 0, 3, 2 } ;\n\n    /* SUBTRA */\n\n    eh = xh - sh ;\n    SATURATE(eh, 32767, -32768);\n\n    /* QUANTH */\n\n    sih = eh >> 15 ;\n    if (sih == 0 )  wd = eh ;\n    else wd = (32767 - eh) & 32767 ;\n\n    hdu = (564 << 3) * deth;\n    wd1 = (hdu >> 15) ;\n    if (wd >= wd1)  mih = 2 ;\n    else mih = 1 ;\n\n    if (sih == -1 ) ih = ihn[mih] ;\n    else ih = ihp[mih] ;\n\n    return (ih) ;\n}\n\nstatic int block2h (int ih, int deth)\n{\n    int dh ;\n    int wd2 ;\n    static const int qm2[4] = {-7408, -1616, 7408, 1616};\n    \n    /* INVQAH */\n\n    wd2 = qm2[ih] ;\n    dh = (deth * wd2) >> 15 ;\n\n    return (dh) ;\n}\n\nstatic int block3h (g722_enc_t *enc, int ih)\n{\n    int deth ;\n    int ih2, wd, wd1, wd2, wd3, nbph, deph ;\n    static const int wh[3] = {0, -214, 798} ;\n    static const int rh2[4] = {2, 1, 2, 1} ;\n    static const int ilb[32] = {\n\t2048, 2093, 2139, 2186, 2233, 2282, 2332,\n\t2383, 2435, 2489, 2543, 2599, 2656, 2714,\n\t2774, 2834, 2896, 2960, 3025, 3091, 3158,\n\t3228, 3298, 3371, 3444, 3520, 3597, 3676,\n\t3756, 3838, 3922, 4008\n    };\n\n    /* LOGSCH */\n\n    ih2 = rh2[ih] ;\n    wd = (enc->nbh * 32512) >> 15 ;\n    nbph = wd + wh[ih2] ;\n\n    if (nbph <     0) nbph = 0 ;\n    if (nbph > 22528) nbph = 22528 ;\n\n    /* SCALEH */\n\n    wd1 =  (nbph >> 6) & 31 ;\n    wd2 = nbph >> 11 ;\n    if ((10-wd2) < 0) wd3 = ilb[wd1] << (wd2-10) ;\n    else wd3 = ilb[wd1] >> (10-wd2) ;\n    deph = wd3 << 2 ;\n\n    /* DELAYA */\n    enc->nbh = nbph ;\n    /* DELAYH */\n    deth = deph ;\n\n    return (deth) ;\n}\n\nstatic int block4h (g722_enc_t *enc, int d)\n{\n    int sh = enc->shigh;\n    int i ;\n    int wd, wd1, wd2, wd3, wd4, wd5 /*, wd6 */;\n\n    enc->dh[0] = d;\n\n    /* RECONS */\n\n    enc->rh[0] = sh + enc->dh[0] ;\n    SATURATE(enc->rh[0], 32767, -32768);\n\n    /* PARREC */\n\n    enc->ph[0] = enc->dh[0] + enc->szh ;\n    SATURATE(enc->ph[0], 32767, -32768);\n\n    /* UPPOL2 */\n\n    enc->sgh[0] = enc->ph[0] >> 15 ;\n    enc->sgh[1] = enc->ph[1] >> 15 ;\n    enc->sgh[2] = enc->ph[2] >> 15 ;\n\n    wd1 = enc->ah[1] << 2;\n    SATURATE(wd1, 32767, -32768);\n\n    if ( enc->sgh[0] == enc->sgh[1] )  wd2 = - wd1 ;\n    else  wd2 = wd1 ;\n    if ( wd2 > 32767 ) wd2 = 32767;\n\n    wd2 = wd2 >> 7 ;\n\n    if ( enc->sgh[0] == enc->sgh[2] )  wd3 = 128 ;\n    else  wd3 = - 128 ;\n\n    wd4 = wd2 + wd3 ;\n    wd5 = (enc->ah[2] * 32512) >> 15 ;\n\n    enc->aph[2] = wd4 + wd5 ;\n    SATURATE(enc->aph[2], 12288, -12288);\n\n    /* UPPOL1 */\n\n    enc->sgh[0] = enc->ph[0] >> 15 ;\n    enc->sgh[1] = enc->ph[1] >> 15 ;\n\n    if ( enc->sgh[0] == enc->sgh[1] )  wd1 = 192 ;\n    else wd1 = - 192 ;\n\n    wd2 = (enc->ah[1] * 32640) >> 15 ;\n\n    enc->aph[1] = wd1 + wd2 ;\n    SATURATE(enc->aph[1], 32767, -32768);\n\n    wd3 = (15360 - enc->aph[2]) ;\n    SATURATE(wd3, 32767, -32768);\n\n    if ( enc->aph[1] >  wd3)  enc->aph[1] =  wd3 ;\n    else if ( enc->aph[1] < -wd3)  enc->aph[1] = -wd3 ;\n\n    /* UPZERO */\n\n    if ( enc->dh[0] == 0 )  wd1 = 0 ;\n    else wd1 = 128 ;\n\n    enc->sgh[0] = enc->dh[0] >> 15 ;\n\n    for ( i = 1; i < 7; i++ ) {\n\tenc->sgh[i] = enc->dh[i] >> 15 ;\n\tif ( enc->sgh[i] == enc->sgh[0] )  wd2 = wd1 ;\n\telse wd2 = - wd1 ;\n\twd3 = (enc->bh[i] * 32640) >> 15 ;\n\tenc->bph[i] = wd2 + wd3 ;\n\tSATURATE(enc->bph[i], 32767, -32768);\n    }\n\n    /* DELAYA */\n    for ( i = 6; i > 0; i-- ) {\n\tenc->dh[i] = enc->dh[i-1] ;\n\tenc->bh[i]  = enc->bph[i] ;\n    }\n\n    for ( i = 2; i > 0; i-- ) {\n\tenc->rh[i] = enc->rh[i-1] ;\n\tenc->ph[i] = enc->ph[i-1] ;\n\tenc->ah[i] = enc->aph[i] ;\n    }\n\n    /* FILTEP */\n\n    wd1 = enc->rh[1] + enc->rh[1];\n    SATURATE(wd1, 32767, -32768);\n    wd1 = ( enc->ah[1] * wd1 ) >> 15 ;\n\n    wd2 = enc->rh[2] + enc->rh[2];\n    SATURATE(wd2, 32767, -32768);\n    wd2 = ( enc->ah[2] * wd2 ) >> 15 ;\n\n    enc->sph = wd1 + wd2 ;\n    SATURATE(enc->sph, 32767, -32768);\n\n    /* FILTEZ */\n\n    enc->szh = 0 ;\n    for (i=6; i>0; i--) {\n\twd = enc->dh[i] + enc->dh[i];\n\tSATURATE(wd, 32767, -32768);\n\tenc->szh += (enc->bh[i] * wd) >> 15 ;\n\tSATURATE(enc->szh, 32767, -32768);\n    }\n\n    /* PREDIC */\n\n    sh = enc->sph + enc->szh ;\n    SATURATE(sh, 32767, -32768);\n\n    return (sh) ;\n}\n\n/* PROCESS PCM THROUGH THE QMF FILTER */\nstatic void tx_qmf(g722_enc_t *enc, int pcm1, int pcm2, int *lo, int *hi)\n{\n    int sumodd, sumeven;\n    int i;\n\n    pj_memmove(&enc->x[2], enc->x, 22 * sizeof(enc->x[0]));\n    enc->x[1] = pcm1; \n    enc->x[0] = pcm2;\n\n    sumodd = 0;\n    for (i=1; i<24; i+=2) sumodd += enc->x[i] * g722_qmf_coeff[i];\n\n    sumeven = 0;\n    for (i=0; i<24; i+=2) sumeven += enc->x[i] * g722_qmf_coeff[i];\n\n    *lo  = (sumeven + sumodd) >> 13  ;\n    *hi = (sumeven - sumodd) >> 13  ;\n\n    SATURATE(*lo, 16383, -16384);\n    SATURATE(*hi, 16383, -16383);\n}\n\n\nPJ_DEF(pj_status_t) g722_enc_init(g722_enc_t *enc)\n{\n    PJ_ASSERT_RETURN(enc, PJ_EINVAL);\n    \n    pj_bzero(enc, sizeof(g722_enc_t));\n\n    enc->detlow = 32;\n    enc->dethigh = 8;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) g722_enc_encode( g722_enc_t *enc, \n\t\t\t\t     pj_int16_t in[], \n\t\t\t\t     pj_size_t nsamples,\n\t\t\t\t     void *out,\n\t\t\t\t     pj_size_t *out_size)\n{\n    unsigned i;\n    int xlow, ilow, dlowt;\n    int xhigh, ihigh, dhigh;\n    pj_uint8_t *out_ = (pj_uint8_t*) out;\n\n    PJ_ASSERT_RETURN(enc && in && nsamples && out && out_size, PJ_EINVAL);\n    PJ_ASSERT_RETURN(nsamples % 2 == 0, PJ_EINVAL);\n    PJ_ASSERT_RETURN(*out_size >= (nsamples >> 1), PJ_ETOOSMALL);\n    \n    for(i = 0; i < nsamples; i += 2) {\n\ttx_qmf(enc, in[i], in[i+1], &xlow, &xhigh);\n\n\t/* low band encoder */\n\tilow = block1l (xlow, enc->slow, enc->detlow) ;\n\tdlowt = block2l (ilow, enc->detlow) ;\n\tenc->detlow = block3l (enc, ilow) ;\n\tenc->slow = block4l (enc, dlowt) ;\n\n\t/* high band encoder */\n\tihigh = block1h (xhigh, enc->shigh, enc->dethigh) ;\n\tdhigh = block2h (ihigh, enc->dethigh) ;\n\tenc->dethigh = block3h (enc, ihigh) ;\n\tenc->shigh = block4h (enc, dhigh) ;\n\n\t/* bits mix low & high adpcm */\n\tout_[i/2] = (pj_uint8_t)((ihigh << 6) | ilow);\n    }\n\n    *out_size = nsamples >> 1;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) g722_enc_deinit(g722_enc_t *enc)\n{\n    pj_bzero(enc, sizeof(g722_enc_t));\n\n    return PJ_SUCCESS;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/g722/g722_enc.h",
    "content": "/* $Id: g722_enc.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n/*\n * Based on implementation found in Carnegie Mellon Speech Group Software\n * depository (ftp://ftp.cs.cmu.edu/project/fgdata/index.html). No copyright\n * was claimed in the original source codes.\n */\n#ifndef __PJMEDIA_CODEC_G722_ENC_H__\n#define __PJMEDIA_CODEC_G722_ENC_H__\n\n#include <pjmedia-codec/types.h>\n\n/* Encoder state */\ntypedef struct g722_enc_t {\n    /* PCM low band */\n    int slow;\n    int detlow;\n    int spl;\n    int szl;\n    int rlt  [3];\n    int al   [3];\n    int apl  [3];\n    int plt  [3];\n    int dlt  [7];\n    int bl   [7];\n    int bpl  [7];\n    int sgl  [7];\n    int nbl;\n\n    /* PCM high band*/\n    int shigh;\n    int dethigh;\n    int sph;\n    int szh;\n    int rh   [3];\n    int ah   [3];\n    int aph  [3];\n    int ph   [3];\n    int dh   [7];\n    int bh   [7];\n    int bph  [7];\n    int sgh  [7];\n    int nbh;\n\n    /* QMF signal history */\n    int x[24];\n} g722_enc_t;\n\n\nPJ_DECL(pj_status_t) g722_enc_init(g722_enc_t *enc);\n\nPJ_DECL(pj_status_t) g722_enc_encode(g722_enc_t *enc, \n\t\t\t\t     pj_int16_t in[], \n\t\t\t\t     pj_size_t nsamples,\n\t\t\t\t     void *out,\n\t\t\t\t     pj_size_t *out_size);\n\nPJ_DECL(pj_status_t) g722_enc_deinit(g722_enc_t *enc);\n\n#endif /* __PJMEDIA_CODEC_G722_ENC_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/g722.c",
    "content": "/* $Id: g722.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-codec/g722.h>\n#include <pjmedia/codec.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/endpoint.h>\n#include <pjmedia/plc.h>\n#include <pjmedia/port.h>\n#include <pjmedia/silencedet.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/os.h>\n\n#if defined(PJMEDIA_HAS_G722_CODEC) && (PJMEDIA_HAS_G722_CODEC != 0)\n\n#include \"g722/g722_enc.h\"\n#include \"g722/g722_dec.h\"\n\n#define THIS_FILE   \"g722.c\"\n\n/* Defines */\n#define PTIME\t\t\t(10)\n#define SAMPLES_PER_FRAME\t(16000 * PTIME /1000)\n#define FRAME_LEN\t\t(80)\n#define PLC_DISABLED\t\t0\n\n/* Tracing */\n#ifndef PJ_TRACE\n#   define PJ_TRACE\t0\t\n#endif\n\n#if PJ_TRACE \n#   define TRACE_(expr)\tPJ_LOG(4,expr)\n#else\n#   define TRACE_(expr)\n#endif\n\n\n/* Prototypes for G722 factory */\nstatic pj_status_t g722_test_alloc(pjmedia_codec_factory *factory, \n\t\t\t\t   const pjmedia_codec_info *id );\nstatic pj_status_t g722_default_attr(pjmedia_codec_factory *factory, \n\t\t\t\t     const pjmedia_codec_info *id, \n\t\t\t\t     pjmedia_codec_param *attr );\nstatic pj_status_t g722_enum_codecs(pjmedia_codec_factory *factory, \n\t\t\t\t    unsigned *count, \n\t\t\t\t    pjmedia_codec_info codecs[]);\nstatic pj_status_t g722_alloc_codec(pjmedia_codec_factory *factory, \n\t\t\t\t    const pjmedia_codec_info *id, \n\t\t\t\t    pjmedia_codec **p_codec);\nstatic pj_status_t g722_dealloc_codec(pjmedia_codec_factory *factory, \n\t\t\t\t      pjmedia_codec *codec );\n\n/* Prototypes for G722 implementation. */\nstatic pj_status_t  g722_codec_init(pjmedia_codec *codec, \n\t\t\t\t    pj_pool_t *pool );\nstatic pj_status_t  g722_codec_open(pjmedia_codec *codec, \n\t\t\t\t    pjmedia_codec_param *attr );\nstatic pj_status_t  g722_codec_close(pjmedia_codec *codec );\nstatic pj_status_t  g722_codec_modify(pjmedia_codec *codec, \n\t\t\t\t      const pjmedia_codec_param *attr );\nstatic pj_status_t  g722_codec_parse(pjmedia_codec *codec,\n\t\t\t\t     void *pkt,\n\t\t\t\t     pj_size_t pkt_size,\n\t\t\t\t     const pj_timestamp *ts,\n\t\t\t\t     unsigned *frame_cnt,\n\t\t\t\t     pjmedia_frame frames[]);\nstatic pj_status_t  g722_codec_encode(pjmedia_codec *codec, \n\t\t\t\t      const struct pjmedia_frame *input,\n\t\t\t\t      unsigned output_buf_len, \n\t\t\t\t      struct pjmedia_frame *output);\nstatic pj_status_t  g722_codec_decode(pjmedia_codec *codec, \n\t\t\t\t      const struct pjmedia_frame *input,\n\t\t\t\t      unsigned output_buf_len, \n\t\t\t\t      struct pjmedia_frame *output);\n#if !PLC_DISABLED\nstatic pj_status_t  g722_codec_recover(pjmedia_codec *codec,\n\t\t\t\t      unsigned output_buf_len,\n\t\t\t\t      struct pjmedia_frame *output);\n#endif\n\n/* Definition for G722 codec operations. */\nstatic pjmedia_codec_op g722_op = \n{\n    &g722_codec_init,\n    &g722_codec_open,\n    &g722_codec_close,\n    &g722_codec_modify,\n    &g722_codec_parse,\n    &g722_codec_encode,\n    &g722_codec_decode,\n#if !PLC_DISABLED\n    &g722_codec_recover\n#else\n    NULL\n#endif\n};\n\n/* Definition for G722 codec factory operations. */\nstatic pjmedia_codec_factory_op g722_factory_op =\n{\n    &g722_test_alloc,\n    &g722_default_attr,\n    &g722_enum_codecs,\n    &g722_alloc_codec,\n    &g722_dealloc_codec,\n    &pjmedia_codec_g722_deinit\n};\n\n/* G722 factory */\nstatic struct g722_codec_factory\n{\n    pjmedia_codec_factory    base;\n    pjmedia_endpt\t    *endpt;\n    pj_pool_t\t\t    *pool;\n    pj_mutex_t\t\t    *mutex;\n    pjmedia_codec\t     codec_list;\n    unsigned\t\t     pcm_shift;\n} g722_codec_factory;\n\n\n/* G722 codec private data. */\nstruct g722_data\n{\n    g722_enc_t\t\t encoder;\n    g722_dec_t\t\t decoder;\n    unsigned\t\t pcm_shift;\n    pj_int16_t\t\t pcm_clip_mask;\n    pj_bool_t\t\t plc_enabled;\n    pj_bool_t\t\t vad_enabled;\n    pjmedia_silence_det\t*vad;\n    pj_timestamp\t last_tx;\n#if !PLC_DISABLED\n    pjmedia_plc\t\t*plc;\n#endif\n};\n\n\n\n/*\n * Initialize and register G722 codec factory to pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_g722_init( pjmedia_endpt *endpt )\n{\n    pjmedia_codec_mgr *codec_mgr;\n    pj_status_t status;\n\n    if (g722_codec_factory.pool != NULL)\n\treturn PJ_SUCCESS;\n\n    /* Create G722 codec factory. */\n    g722_codec_factory.base.op = &g722_factory_op;\n    g722_codec_factory.base.factory_data = NULL;\n    g722_codec_factory.endpt = endpt;\n    g722_codec_factory.pcm_shift = PJMEDIA_G722_DEFAULT_PCM_SHIFT;\n\n    g722_codec_factory.pool = pjmedia_endpt_create_pool(endpt, \"g722\", 1000, \n\t\t\t\t\t\t        1000);\n    if (!g722_codec_factory.pool)\n\treturn PJ_ENOMEM;\n\n    pj_list_init(&g722_codec_factory.codec_list);\n\n    /* Create mutex. */\n    status = pj_mutex_create_simple(g722_codec_factory.pool, \"g722\", \n\t\t\t\t    &g722_codec_factory.mutex);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);\n    if (!codec_mgr) {\n\tstatus = PJ_EINVALIDOP;\n\tgoto on_error;\n    }\n\n    /* Register codec factory to endpoint. */\n    status = pjmedia_codec_mgr_register_factory(codec_mgr, \n\t\t\t\t\t\t&g722_codec_factory.base);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    TRACE_((THIS_FILE, \"G722 codec factory initialized\"));\n    \n    /* Done. */\n    return PJ_SUCCESS;\n\non_error:\n    pj_pool_release(g722_codec_factory.pool);\n    g722_codec_factory.pool = NULL;\n    return status;\n}\n\n/*\n * Unregister G722 codec factory from pjmedia endpoint and deinitialize\n * the G722 codec library.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_g722_deinit(void)\n{\n    pjmedia_codec_mgr *codec_mgr;\n    pj_status_t status;\n\n    if (g722_codec_factory.pool == NULL)\n\treturn PJ_SUCCESS;\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(g722_codec_factory.endpt);\n    if (!codec_mgr) {\n\tpj_pool_release(g722_codec_factory.pool);\n\tg722_codec_factory.pool = NULL;\n\treturn PJ_EINVALIDOP;\n    }\n\n    /* Unregister G722 codec factory. */\n    status = pjmedia_codec_mgr_unregister_factory(codec_mgr,\n\t\t\t\t\t\t  &g722_codec_factory.base);\n    \n    /* Destroy mutex. */\n    pj_mutex_destroy(g722_codec_factory.mutex);\n\n    /* Destroy pool. */\n    pj_pool_release(g722_codec_factory.pool);\n    g722_codec_factory.pool = NULL;\n    \n    TRACE_((THIS_FILE, \"G722 codec factory shutdown\"));\n    return status;\n}\n\n\n/*\n * Set level adjustment.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_g722_set_pcm_shift(unsigned val)\n{\n    g722_codec_factory.pcm_shift = val;\n    return PJ_SUCCESS;\n}\n\n\n/* \n * Check if factory can allocate the specified codec. \n */\nstatic pj_status_t g722_test_alloc(pjmedia_codec_factory *factory, \n\t\t\t\t   const pjmedia_codec_info *info )\n{\n    PJ_UNUSED_ARG(factory);\n\n    /* Check payload type. */\n    if (info->pt != PJMEDIA_RTP_PT_G722)\n\treturn PJMEDIA_CODEC_EUNSUP;\n\n    /* Ignore the rest, since it's static payload type. */\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Generate default attribute.\n */\nstatic pj_status_t g722_default_attr( pjmedia_codec_factory *factory, \n\t\t\t\t      const pjmedia_codec_info *id, \n\t\t\t\t      pjmedia_codec_param *attr )\n{\n    PJ_UNUSED_ARG(factory);\n    PJ_UNUSED_ARG(id);\n\n    pj_bzero(attr, sizeof(pjmedia_codec_param));\n    attr->info.clock_rate = 16000;\n    attr->info.channel_cnt = 1;\n    attr->info.avg_bps = 64000;\n    attr->info.max_bps = 64000;\n    attr->info.pcm_bits_per_sample = 16;\n    attr->info.frm_ptime = PTIME;\n    attr->info.pt = PJMEDIA_RTP_PT_G722;\n\n    attr->setting.frm_per_pkt = 2;\n    attr->setting.vad = 1;\n    attr->setting.plc = 1;\n\n    /* Default all other flag bits disabled. */\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Enum codecs supported by this factory (i.e. only G722!).\n */\nstatic pj_status_t g722_enum_codecs(pjmedia_codec_factory *factory, \n\t\t\t\t    unsigned *count, \n\t\t\t\t    pjmedia_codec_info codecs[])\n{\n    PJ_UNUSED_ARG(factory);\n    PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);\n\n    pj_bzero(&codecs[0], sizeof(pjmedia_codec_info));\n    codecs[0].encoding_name = pj_str(\"G722\");\n    codecs[0].pt = PJMEDIA_RTP_PT_G722;\n    codecs[0].type = PJMEDIA_TYPE_AUDIO;\n    codecs[0].clock_rate = 16000;\n    codecs[0].channel_cnt = 1;\n\n    *count = 1;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Allocate a new G722 codec instance.\n */\nstatic pj_status_t g722_alloc_codec(pjmedia_codec_factory *factory, \n\t\t\t\t    const pjmedia_codec_info *id,\n\t\t\t\t    pjmedia_codec **p_codec)\n{\n    pjmedia_codec *codec;\n    struct g722_data *g722_data;\n\n    PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &g722_codec_factory.base, PJ_EINVAL);\n\n    pj_mutex_lock(g722_codec_factory.mutex);\n\n    /* Get free nodes, if any. */\n    if (!pj_list_empty(&g722_codec_factory.codec_list)) {\n\tcodec = g722_codec_factory.codec_list.next;\n\tpj_list_erase(codec);\n    } else {\n\tpj_status_t status;\n\n\tcodec = PJ_POOL_ZALLOC_T(g722_codec_factory.pool, pjmedia_codec);\n\tPJ_ASSERT_RETURN(codec != NULL, PJ_ENOMEM);\n\tcodec->op = &g722_op;\n\tcodec->factory = factory;\n\n\tg722_data = PJ_POOL_ZALLOC_T(g722_codec_factory.pool, struct g722_data);\n\tcodec->codec_data = g722_data;\n\n#if !PLC_DISABLED\n    \t/* Create PLC */\n    \tstatus = pjmedia_plc_create(g722_codec_factory.pool, 16000, \n\t\t\t            SAMPLES_PER_FRAME, 0, &g722_data->plc);\n\tif (status != PJ_SUCCESS) {\n\t    pj_mutex_unlock(g722_codec_factory.mutex);\n\t    return status;\n\t}\n#endif\n\n\t/* Create silence detector */\n\tstatus = pjmedia_silence_det_create(g722_codec_factory.pool,\n\t\t\t\t\t    16000, SAMPLES_PER_FRAME,\n\t\t\t\t\t    &g722_data->vad);\n\tif (status != PJ_SUCCESS) {\n\t    pj_mutex_unlock(g722_codec_factory.mutex);\n\t    TRACE_((THIS_FILE, \"Create silence detector failed (status = %d)\", \n                               status));\n\t    return status;\n\t}\n    }\n\n\n    pj_mutex_unlock(g722_codec_factory.mutex);\n\n    *p_codec = codec;\n    return PJ_SUCCESS;\n}\n\n/*\n * Free codec.\n */\nstatic pj_status_t g722_dealloc_codec(pjmedia_codec_factory *factory, \n\t\t\t\t      pjmedia_codec *codec )\n{\n    struct g722_data *g722_data;\n    int i;\n\n    PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &g722_codec_factory.base, PJ_EINVAL);\n\n    g722_data = (struct g722_data*) codec->codec_data;\n\n    /* Close codec, if it's not closed. */\n    g722_codec_close(codec);\n\n#if !PLC_DISABLED\n    /* Clear left samples in the PLC, since codec+plc will be reused\n     * next time.\n     */\n    for (i=0; i<2; ++i) {\n\tpj_int16_t frame[SAMPLES_PER_FRAME];\n\tpjmedia_zero_samples(frame, PJ_ARRAY_SIZE(frame));\n\tpjmedia_plc_save(g722_data->plc, frame);\n    }\n#else\n    PJ_UNUSED_ARG(i);\n#endif\n\n    /* Re-init silence_period */\n    pj_set_timestamp32(&g722_data->last_tx, 0, 0);\n\n    /* Put in the free list. */\n    pj_mutex_lock(g722_codec_factory.mutex);\n    pj_list_push_front(&g722_codec_factory.codec_list, codec);\n    pj_mutex_unlock(g722_codec_factory.mutex);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Init codec.\n */\nstatic pj_status_t g722_codec_init(pjmedia_codec *codec, \n\t\t\t\t   pj_pool_t *pool )\n{\n    PJ_UNUSED_ARG(codec);\n    PJ_UNUSED_ARG(pool);\n    return PJ_SUCCESS;\n}\n\n/*\n * Open codec.\n */\nstatic pj_status_t g722_codec_open(pjmedia_codec *codec, \n\t\t\t\t   pjmedia_codec_param *attr )\n{\n    struct g722_data *g722_data = (struct g722_data*) codec->codec_data;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(codec && attr, PJ_EINVAL);\n    PJ_ASSERT_RETURN(g722_data != NULL, PJ_EINVALIDOP);\n\n    status = g722_enc_init(&g722_data->encoder);\n    if (status != PJ_SUCCESS) {\n\tTRACE_((THIS_FILE, \"g722_enc_init() failed, status=%d\", status));\n\tpj_mutex_unlock(g722_codec_factory.mutex);\n\treturn PJMEDIA_CODEC_EFAILED;\n    }\n\n    status = g722_dec_init(&g722_data->decoder);\n    if (status != PJ_SUCCESS) {\n\tTRACE_((THIS_FILE, \"g722_dec_init() failed, status=%d\", status));\n\tpj_mutex_unlock(g722_codec_factory.mutex);\n\treturn PJMEDIA_CODEC_EFAILED;\n    }\n\n    g722_data->vad_enabled = (attr->setting.vad != 0);\n    g722_data->plc_enabled = (attr->setting.plc != 0);\n    g722_data->pcm_shift = g722_codec_factory.pcm_shift;\n    g722_data->pcm_clip_mask = (pj_int16_t)(1<<g722_codec_factory.pcm_shift)-1;\n    g722_data->pcm_clip_mask <<= (16-g722_codec_factory.pcm_shift);\n\n    TRACE_((THIS_FILE, \"G722 codec opened: vad=%d, plc=%d\",\n\t\t\tg722_data->vad_enabled, g722_data->plc_enabled));\n    return PJ_SUCCESS;\n}\n\n/*\n * Close codec.\n */\nstatic pj_status_t g722_codec_close( pjmedia_codec *codec )\n{\n    /* The codec, encoder, and decoder will be reused, so there's\n     * nothing to do here\n     */\n\n    PJ_UNUSED_ARG(codec);\n    \n    TRACE_((THIS_FILE, \"G722 codec closed\"));\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Modify codec settings.\n */\nstatic pj_status_t  g722_codec_modify(pjmedia_codec *codec, \n\t\t\t\t     const pjmedia_codec_param *attr )\n{\n    struct g722_data *g722_data = (struct g722_data*) codec->codec_data;\n\n    pj_assert(g722_data != NULL);\n\n    g722_data->vad_enabled = (attr->setting.vad != 0);\n    g722_data->plc_enabled = (attr->setting.plc != 0);\n\n    TRACE_((THIS_FILE, \"G722 codec modified: vad=%d, plc=%d\",\n\t\t\tg722_data->vad_enabled, g722_data->plc_enabled));\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get frames in the packet.\n */\nstatic pj_status_t  g722_codec_parse(pjmedia_codec *codec,\n\t\t\t\t     void *pkt,\n\t\t\t\t     pj_size_t pkt_size,\n\t\t\t\t     const pj_timestamp *ts,\n\t\t\t\t     unsigned *frame_cnt,\n\t\t\t\t     pjmedia_frame frames[])\n{\n    unsigned count = 0;\n\n    PJ_UNUSED_ARG(codec);\n\n    PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);\n\n    TRACE_((THIS_FILE, \"G722 parse(): input len=%d\", pkt_size));\n\n    while (pkt_size >= FRAME_LEN && count < *frame_cnt) {\n\tframes[count].type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframes[count].buf = pkt;\n\tframes[count].size = FRAME_LEN;\n\tframes[count].timestamp.u64 = ts->u64 + count * SAMPLES_PER_FRAME;\n\n\tpkt = ((char*)pkt) + FRAME_LEN;\n\tpkt_size -= FRAME_LEN;\n\n\t++count;\n    }\n\n    TRACE_((THIS_FILE, \"G722 parse(): got %d frames\", count));\n\n    *frame_cnt = count;\n    return PJ_SUCCESS;\n}\n\n/*\n * Encode frame.\n */\nstatic pj_status_t g722_codec_encode(pjmedia_codec *codec, \n\t\t\t\t     const struct pjmedia_frame *input,\n\t\t\t\t     unsigned output_buf_len, \n\t\t\t\t     struct pjmedia_frame *output)\n{\n    struct g722_data *g722_data = (struct g722_data*) codec->codec_data;\n    pj_status_t status;\n\n    pj_assert(g722_data && input && output);\n\n    PJ_ASSERT_RETURN((input->size >> 2) <= output_buf_len, \n                     PJMEDIA_CODEC_EFRMTOOSHORT);\n\n    /* Detect silence */\n    if (g722_data->vad_enabled) {\n\tpj_bool_t is_silence;\n\tpj_int32_t silence_duration;\n\n\tsilence_duration = pj_timestamp_diff32(&g722_data->last_tx, \n\t\t\t\t\t       &input->timestamp);\n\n\tis_silence = pjmedia_silence_det_detect(g722_data->vad, \n\t\t\t\t\t        (const pj_int16_t*) input->buf,\n\t\t\t\t\t\t(input->size >> 1),\n\t\t\t\t\t\tNULL);\n\tif (is_silence &&\n\t    (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||\n\t     silence_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*16000/1000))\n\t{\n\t    output->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    output->buf = NULL;\n\t    output->size = 0;\n\t    output->timestamp = input->timestamp;\n\t    return PJ_SUCCESS;\n\t} else {\n\t    g722_data->last_tx = input->timestamp;\n\t}\n    }\n\n    /* Adjust input signal level from 16-bit to 14-bit */\n    if (g722_data->pcm_shift) {\n\tpj_int16_t *p, *end;\n\n\tp = (pj_int16_t*)input->buf;\n\tend = p + input->size/2;\n\twhile (p < end) {\n\t    *p++ >>= g722_data->pcm_shift;\n\t}\n    }\n\n    /* Encode to temporary buffer */\n    output->size = output_buf_len;\n    status = g722_enc_encode(&g722_data->encoder, (pj_int16_t*)input->buf, \n\t\t\t     (input->size >> 1), output->buf, &output->size);\n    if (status != PJ_SUCCESS) {\n\toutput->size = 0;\n\toutput->buf = NULL;\n\toutput->type = PJMEDIA_FRAME_TYPE_NONE;\n\tTRACE_((THIS_FILE, \"G722 encode() status: %d\", status));\n\treturn PJMEDIA_CODEC_EFAILED;\n    }\n\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    output->timestamp = input->timestamp;\n    \n    TRACE_((THIS_FILE, \"G722 encode(): size=%d\", output->size));\n    return PJ_SUCCESS;\n}\n\n/*\n * Decode frame.\n */\nstatic pj_status_t g722_codec_decode(pjmedia_codec *codec, \n\t\t\t\t     const struct pjmedia_frame *input,\n\t\t\t\t     unsigned output_buf_len, \n\t\t\t\t     struct pjmedia_frame *output)\n{\n    struct g722_data *g722_data = (struct g722_data*) codec->codec_data;\n    pj_status_t status;\n\n    pj_assert(g722_data != NULL);\n    PJ_ASSERT_RETURN(input && output, PJ_EINVAL);\n\n    TRACE_((THIS_FILE, \"G722 decode(): inbuf=%p, insize=%d, outbuf=%p,\"\n\t\t       \"outsize=%d\",\n\t               input->buf, input->size, output->buf, output_buf_len));\n    \n    if (output_buf_len < SAMPLES_PER_FRAME * 2) {\n        TRACE_((THIS_FILE, \"G722 decode() ERROR: PJMEDIA_CODEC_EPCMTOOSHORT\"));\n\treturn PJMEDIA_CODEC_EPCMTOOSHORT;\n    }\n\n    if (input->size != FRAME_LEN) {\n        TRACE_((THIS_FILE, \"G722 decode() ERROR: PJMEDIA_CODEC_EFRMTOOSHORT\"));\n\treturn PJMEDIA_CODEC_EFRMTOOSHORT;\n    }\n\n\n    /* Decode */\n    output->size = SAMPLES_PER_FRAME;\n    status = g722_dec_decode(&g722_data->decoder, input->buf, input->size,\n\t\t\t     (pj_int16_t*)output->buf, &output->size);\n    if (status != PJ_SUCCESS) {\n\tTRACE_((THIS_FILE, \"G722 decode() status: %d\", status));\n\treturn PJMEDIA_CODEC_EFAILED;\n    }\n\n    pj_assert(output->size == SAMPLES_PER_FRAME);\n\n    /* Adjust input signal level from 14-bit to 16-bit */\n    if (g722_data->pcm_shift) {\n\tpj_int16_t *p, *end;\n\n\tp = (pj_int16_t*)output->buf;\n\tend = p + output->size;\n\twhile (p < end) {\n#if PJMEDIA_G722_STOP_PCM_SHIFT_ON_CLIPPING\n\t    /* If there is clipping, stop the PCM shifting */\n\t    if (*p & g722_data->pcm_clip_mask) {\n\t\tg722_data->pcm_shift = 0;\n\t\tbreak;\n\t    }\n#endif\n\t    *p++ <<= g722_data->pcm_shift;\n\t}\n    }\n\n    output->size = SAMPLES_PER_FRAME * 2;\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    output->timestamp = input->timestamp;\n\n#if !PLC_DISABLED\n    if (g722_data->plc_enabled)\n\tpjmedia_plc_save(g722_data->plc, (pj_int16_t*)output->buf);\n#endif\n\n    TRACE_((THIS_FILE, \"G722 decode done\"));\n    return PJ_SUCCESS;\n}\n\n\n#if !PLC_DISABLED\n/*\n * Recover lost frame.\n */\nstatic pj_status_t  g722_codec_recover(pjmedia_codec *codec,\n\t\t\t\t       unsigned output_buf_len,\n\t\t\t\t       struct pjmedia_frame *output)\n{\n    struct g722_data *g722_data = (struct g722_data*)codec->codec_data;\n\n    PJ_ASSERT_RETURN(g722_data->plc_enabled, PJ_EINVALIDOP);\n\n    PJ_ASSERT_RETURN(output_buf_len >= SAMPLES_PER_FRAME * 2, \n                     PJMEDIA_CODEC_EPCMTOOSHORT);\n\n    pjmedia_plc_generate(g722_data->plc, (pj_int16_t*)output->buf);\n\n    output->size = SAMPLES_PER_FRAME * 2;\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    \n    return PJ_SUCCESS;\n}\n#endif\n\n#endif // PJMEDIA_HAS_G722_CODEC\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/g7221.c",
    "content": "/* $Id: g7221.c 4001 2012-03-30 07:53:36Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-codec/g7221.h>\n#include <pjmedia-codec/g7221_sdp_match.h>\n#include <pjmedia/codec.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/endpoint.h>\n#include <pjmedia/port.h>\n#include <pjmedia/silencedet.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/math.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/os.h>\n\n/*\n * Only build this file if PJMEDIA_HAS_G7221_CODEC != 0\n */\n#if defined(PJMEDIA_HAS_G7221_CODEC) && PJMEDIA_HAS_G7221_CODEC!=0\n\n#include \"../../../third_party/g7221/common/defs.h\"\n\n#define THIS_FILE\t    \"g7221.c\"\n\n/* Codec tag, it is the SDP encoding name and also MIME subtype name */\n#define CODEC_TAG\t    \"G7221\"\n\n/* Sampling rates definition */\n#define WB_SAMPLE_RATE\t    16000\n#define UWB_SAMPLE_RATE\t    32000\n\n/* Maximum number of samples per frame. */\n#define MAX_SAMPLES_PER_FRAME (UWB_SAMPLE_RATE * 20 / 1000)\n\n/* Maximum number of codec params. */\n#define MAX_CODEC_MODES\t    8\n#define START_RSV_MODES_IDX 6\n\n\n/* Prototypes for G722.1 codec factory */\nstatic pj_status_t test_alloc( pjmedia_codec_factory *factory, \n\t\t\t       const pjmedia_codec_info *id );\nstatic pj_status_t default_attr( pjmedia_codec_factory *factory, \n\t\t\t\t const pjmedia_codec_info *id, \n\t\t\t\t pjmedia_codec_param *attr );\nstatic pj_status_t enum_codecs( pjmedia_codec_factory *factory, \n\t\t\t\tunsigned *count, \n\t\t\t\tpjmedia_codec_info codecs[]);\nstatic pj_status_t alloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\tconst pjmedia_codec_info *id, \n\t\t\t\tpjmedia_codec **p_codec);\nstatic pj_status_t dealloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t  pjmedia_codec *codec );\n\n/* Prototypes for G722.1 codec implementation. */\nstatic pj_status_t codec_init( pjmedia_codec *codec, \n\t\t\t       pj_pool_t *pool );\nstatic pj_status_t codec_open( pjmedia_codec *codec, \n\t\t\t       pjmedia_codec_param *attr );\nstatic pj_status_t codec_close( pjmedia_codec *codec );\nstatic pj_status_t codec_modify(pjmedia_codec *codec, \n\t\t\t        const pjmedia_codec_param *attr );\nstatic pj_status_t codec_parse( pjmedia_codec *codec,\n\t\t\t        void *pkt,\n\t\t\t\tpj_size_t pkt_size,\n\t\t\t\tconst pj_timestamp *ts,\n\t\t\t\tunsigned *frame_cnt,\n\t\t\t\tpjmedia_frame frames[]);\nstatic pj_status_t codec_encode( pjmedia_codec *codec, \n\t\t\t\t const struct pjmedia_frame *input,\n\t\t\t\t unsigned output_buf_len,\n\t\t\t\t struct pjmedia_frame *output);\nstatic pj_status_t codec_decode( pjmedia_codec *codec,\n\t\t\t\t const struct pjmedia_frame *input,\n\t\t\t\t unsigned output_buf_len, \n\t\t\t\t struct pjmedia_frame *output);\nstatic pj_status_t codec_recover( pjmedia_codec *codec, \n\t\t\t\t  unsigned output_buf_len, \n\t\t\t\t  struct pjmedia_frame *output);\n\n/* Definition for G722.1 codec operations. */\nstatic pjmedia_codec_op codec_op = \n{\n    &codec_init,\n    &codec_open,\n    &codec_close,\n    &codec_modify,\n    &codec_parse,\n    &codec_encode,\n    &codec_decode,\n    &codec_recover\n};\n\n/* Definition for G722.1 codec factory operations. */\nstatic pjmedia_codec_factory_op codec_factory_op =\n{\n    &test_alloc,\n    &default_attr,\n    &enum_codecs,\n    &alloc_codec,\n    &dealloc_codec,\n    &pjmedia_codec_g7221_deinit\n};\n\n\n/* Structure of G722.1 mode */\ntypedef struct codec_mode\n{\n    pj_bool_t\t     enabled;\t\t/* Is this mode enabled?\t    */\n    pj_uint8_t\t     pt;\t\t/* Payload type.\t\t    */\n    unsigned\t     sample_rate;\t/* Default sampling rate to be used.*/\n    unsigned\t     bitrate;\t\t/* Bitrate.\t\t\t    */\n    char\t     bitrate_str[8];\t/* Bitrate in string.\t\t    */\n} codec_mode;\n\n\n/* G722.1 codec factory */\nstatic struct codec_factory {\n    pjmedia_codec_factory    base;\t    /**< Base class.\t\t    */\n    pjmedia_endpt\t    *endpt;\t    /**< PJMEDIA endpoint instance. */\n    pj_pool_t\t\t    *pool;\t    /**< Codec factory pool.\t    */\n    pj_mutex_t\t\t    *mutex;\t    /**< Codec factory mutex.\t    */\n\n    int\t\t\t     pcm_shift;\t    /**< Level adjustment\t    */\n    unsigned\t\t     mode_count;    /**< Number of G722.1 modes.    */\n    codec_mode\t\t     modes[MAX_CODEC_MODES]; /**< The G722.1 modes. */\n    unsigned\t\t     mode_rsv_start;/**< Start index of G722.1 non-\n\t\t\t\t\t\t standard modes, currently\n\t\t\t\t\t\t there can only be up to two \n\t\t\t\t\t\t non-standard modes enabled\n\t\t\t\t\t\t at the same time.\t    */\n} codec_factory;\n\n/* G722.1 codec private data. */\ntypedef struct codec_private {\n    pj_pool_t\t\t*pool;\t\t    /**< Pool for each instance.    */\n    pj_bool_t\t\t plc_enabled;\t    /**< PLC enabled?\t\t    */\n    pj_bool_t\t\t vad_enabled;\t    /**< VAD enabled?\t\t    */\n    pjmedia_silence_det\t*vad;\t\t    /**< PJMEDIA VAD instance.\t    */\n    pj_timestamp\t last_tx;\t    /**< Timestamp of last transmit.*/\n\n    /* ITU ref implementation seems to leave the codec engine states to be\n     * managed by the application, so here we go.\n     */\n\n    /* Common engine state */\n    pj_uint16_t\t\t samples_per_frame; /**< Samples per frame.\t    */\n    pj_uint16_t\t\t bitrate;\t    /**< Coded stream bitrate.\t    */\n    pj_uint16_t\t\t frame_size;\t    /**< Coded frame size.\t    */\n    pj_uint16_t\t\t frame_size_bits;   /**< Coded frame size in bits.  */\n    pj_uint16_t\t\t number_of_regions; /**< Number of regions.\t    */\n    int\t\t\t pcm_shift;\t    /**< Adjustment for PCM in/out  */\n    \n    /* Encoder specific state */\n    Word16\t\t*enc_frame;\t    /**< 16bit to 14bit buffer\t    */\n    Word16\t\t*enc_old_frame;\n    \n    /* Decoder specific state */\n    Word16\t\t*dec_old_frame;\n    Rand_Obj\t\t dec_randobj;\n    Word16\t\t dec_old_mag_shift;\n    Word16\t\t*dec_old_mlt_coefs;\n} codec_private_t;\n\n/* \n * Helper function for looking up mode based on payload type.\n */\nstatic codec_mode* lookup_mode(unsigned pt)\n{\n    codec_mode* mode = NULL;\n    unsigned i;\n\n    for (i = 0; i < codec_factory.mode_count; ++i) {\n\tmode = &codec_factory.modes[i];\n\tif (mode->pt == pt)\n\t    break;\n    }\n\n    return mode;\n}\n\n/* \n * Helper function to validate G722.1 mode. Valid modes are defined as:\n * 1. sample rate must be 16kHz or 32kHz,\n * 2. bitrate:\n *    - for sampling rate 16kHz: 16000 to 32000 bps, it must be a multiple \n *      of 400 (to keep RTP payload octed-aligned)\n *    - for sampling rate 32kHz: 24000 to 48000 bps, it must be a multiple \n *      of 400 (to keep RTP payload octed-aligned)\n */\nstatic pj_bool_t validate_mode(unsigned sample_rate, unsigned bitrate)\n{\n    if (sample_rate == WB_SAMPLE_RATE) {\n\tif (bitrate < 16000 || bitrate > 32000 ||\n\t    ((bitrate-16000) % 400 != 0))\n\t{\n\t    return PJ_FALSE;\n\t}\n    } else if (sample_rate == UWB_SAMPLE_RATE) {\n\tif (bitrate < 24000 || bitrate > 48000 ||\n\t    ((bitrate-24000) % 400 != 0))\n\t{\n\t    return PJ_FALSE;\n\t}\n    } else {\n\treturn PJ_FALSE;\n    }\n\n    return PJ_TRUE;\n}\n\n#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0\nPJ_INLINE(void) swap_bytes(pj_uint16_t *buf, unsigned count)\n{\n    pj_uint16_t *end = buf + count;\n    while (buf != end) {\n\t*buf = (pj_uint16_t)((*buf << 8) | (*buf >> 8));\n\t++buf;\n    }\n}\n#else\n#define swap_bytes(buf, count)\n#endif\n\n/*\n * Initialize and register G722.1 codec factory to pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_g7221_init( pjmedia_endpt *endpt )\n{\n    pjmedia_codec_mgr *codec_mgr;\n    codec_mode *mode;\n    pj_str_t codec_name;\n    pj_status_t status;\n\n    if (codec_factory.pool != NULL) {\n\t/* Already initialized. */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Initialize codec modes, by default all standard bitrates are enabled */\n    codec_factory.mode_count = 0;\n    codec_factory.pcm_shift = PJMEDIA_G7221_DEFAULT_PCM_SHIFT;\n\n    mode = &codec_factory.modes[codec_factory.mode_count++];\n    mode->enabled = PJ_TRUE;\n    mode->pt = PJMEDIA_RTP_PT_G722_1_24;\n    mode->sample_rate = WB_SAMPLE_RATE;\n    mode->bitrate = 24000;\n    pj_utoa(mode->bitrate, mode->bitrate_str);\n\n    mode = &codec_factory.modes[codec_factory.mode_count++];\n    mode->enabled = PJ_TRUE;\n    mode->pt = PJMEDIA_RTP_PT_G722_1_32;\n    mode->sample_rate = WB_SAMPLE_RATE;\n    mode->bitrate = 32000;\n    pj_utoa(mode->bitrate, mode->bitrate_str);\n\n    mode = &codec_factory.modes[codec_factory.mode_count++];\n    mode->enabled = PJ_TRUE;\n    mode->pt = PJMEDIA_RTP_PT_G7221C_24;\n    mode->sample_rate = UWB_SAMPLE_RATE;\n    mode->bitrate = 24000;\n    pj_utoa(mode->bitrate, mode->bitrate_str);\n\n    mode = &codec_factory.modes[codec_factory.mode_count++];\n    mode->enabled = PJ_TRUE;\n    mode->pt = PJMEDIA_RTP_PT_G7221C_32;\n    mode->sample_rate = UWB_SAMPLE_RATE;\n    mode->bitrate = 32000;\n    pj_utoa(mode->bitrate, mode->bitrate_str);\n\n    mode = &codec_factory.modes[codec_factory.mode_count++];\n    mode->enabled = PJ_TRUE;\n    mode->pt = PJMEDIA_RTP_PT_G7221C_48;\n    mode->sample_rate = UWB_SAMPLE_RATE;\n    mode->bitrate = 48000;\n    pj_utoa(mode->bitrate, mode->bitrate_str);\n\n    /* Non-standard bitrates */\n\n    /* Bitrate 16kbps is non-standard but rather commonly used. */\n    mode = &codec_factory.modes[codec_factory.mode_count++];\n    mode->enabled = PJ_FALSE;\n    mode->pt = PJMEDIA_RTP_PT_G722_1_16;\n    mode->sample_rate = WB_SAMPLE_RATE;\n    mode->bitrate = 16000;\n    pj_utoa(mode->bitrate, mode->bitrate_str);\n\n    /* Reserved two modes for non-standard bitrates */\n    codec_factory.mode_rsv_start = codec_factory.mode_count;\n    mode = &codec_factory.modes[codec_factory.mode_count++];\n    mode->enabled = PJ_FALSE;\n    mode->pt = PJMEDIA_RTP_PT_G7221_RSV1;\n\n    mode = &codec_factory.modes[codec_factory.mode_count++];\n    mode->enabled = PJ_FALSE;\n    mode->pt = PJMEDIA_RTP_PT_G7221_RSV2;\n\n    pj_assert(codec_factory.mode_count <= MAX_CODEC_MODES);\n\n    /* Create G722.1 codec factory. */\n    codec_factory.base.op = &codec_factory_op;\n    codec_factory.base.factory_data = NULL;\n    codec_factory.endpt = endpt;\n\n    codec_factory.pool = pjmedia_endpt_create_pool(endpt, \"G722.1 codec\",\n\t\t\t\t\t\t   4000, 4000);\n    if (!codec_factory.pool)\n\treturn PJ_ENOMEM;\n\n    /* Create mutex. */\n    status = pj_mutex_create_simple(codec_factory.pool, \"G722.1 codec\",\n\t\t\t\t    &codec_factory.mutex);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);\n    if (!codec_mgr) {\n\tstatus = PJ_EINVALIDOP;\n\tgoto on_error;\n    }\n\n    /* Register format match callback. */\n    pj_cstr(&codec_name, CODEC_TAG);\n    status = pjmedia_sdp_neg_register_fmt_match_cb(\n\t\t\t\t\t&codec_name,\n\t\t\t\t\t&pjmedia_codec_g7221_match_sdp);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Register codec factory to endpoint. */\n    status = pjmedia_codec_mgr_register_factory(codec_mgr, \n\t\t\t\t\t\t&codec_factory.base);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Done. */\n    return PJ_SUCCESS;\n\non_error:\n    if (codec_factory.mutex) {\n\tpj_mutex_destroy(codec_factory.mutex);\n\tcodec_factory.mutex = NULL;\n    }\n\n    pj_pool_release(codec_factory.pool);\n    codec_factory.pool = NULL;\n    return status;\n}\n\n\n/**\n * Enable and disable G722.1 modes, including non-standard modes.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_g7221_set_mode(unsigned sample_rate, \n\t\t\t\t\t\t unsigned bitrate, \n\t\t\t\t\t\t pj_bool_t enabled)\n{\n    pjmedia_codec_mgr *codec_mgr;\n    unsigned i;\n\n    /* Validate mode */\n    if (!validate_mode(sample_rate, bitrate))\n\treturn PJMEDIA_CODEC_EINMODE;\n\n    /* Get codec manager */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(codec_factory.endpt);\n    if (!codec_mgr)\n\treturn PJMEDIA_CODEC_EFAILED;\n\n    /* Look up in factory modes table */\n    for (i = 0; i < codec_factory.mode_count; ++i) {\n\tif (codec_factory.modes[i].sample_rate == sample_rate &&\n\t    codec_factory.modes[i].bitrate == bitrate)\n\t{\n\t    codec_factory.modes[i].enabled = enabled;\n\n\t    /* Re-register G722.1 codec factory to update codec list */\n\t    pjmedia_codec_mgr_unregister_factory(codec_mgr,\n\t\t\t\t\t\t &codec_factory.base);\n\t    pjmedia_codec_mgr_register_factory(codec_mgr,\n\t\t\t\t\t       &codec_factory.base);\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    /* Mode not found in modes table, this may be a request to enable\n     * a non-standard G722.1 mode.\n     */\n\n    /* Non-standard mode need to be initialized first before user \n     * can disable it.\n     */\n    if (!enabled)\n\treturn PJ_ENOTFOUND;\n\n    /* Initialize a non-standard mode, look for available space. */\n    for (i = codec_factory.mode_rsv_start; \n\t i < codec_factory.mode_count; ++i) \n    {\n\tif (!codec_factory.modes[i].enabled)\n\t{\n\t    codec_mode *mode = &codec_factory.modes[i];\n\t    mode->enabled = PJ_TRUE;\n\t    mode->sample_rate = sample_rate;\n\t    mode->bitrate = bitrate;\n\t    pj_utoa(mode->bitrate, mode->bitrate_str);\n\n\t    /* Re-register G722.1 codec factory to update codec list */\n\t    pjmedia_codec_mgr_unregister_factory(codec_mgr,\n\t\t\t\t\t\t &codec_factory.base);\n\t    pjmedia_codec_mgr_register_factory(codec_mgr,\n\t\t\t\t\t       &codec_factory.base);\n\n\t    return PJ_SUCCESS;\n\t}\n    }\n    \n    /* No space for non-standard mode. */\n    return PJ_ETOOMANY;\n}\n\n\n/*\n * Set level adjustment.\n */\nPJ_DEF(pj_status_t)  pjmedia_codec_g7221_set_pcm_shift(int val)\n{\n    codec_factory.pcm_shift = val;\n    return PJ_SUCCESS;\n}\n\n/*\n * Unregister G722.1 codec factory from pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_g7221_deinit(void)\n{\n    pjmedia_codec_mgr *codec_mgr;\n    pj_status_t status;\n\n    if (codec_factory.pool == NULL) {\n\t/* Already deinitialized */\n\treturn PJ_SUCCESS;\n    }\n\n    pj_mutex_lock(codec_factory.mutex);\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(codec_factory.endpt);\n    if (!codec_mgr) {\n\tpj_pool_release(codec_factory.pool);\n\tcodec_factory.pool = NULL;\n\tpj_mutex_unlock(codec_factory.mutex);\n\treturn PJ_EINVALIDOP;\n    }\n\n    /* Unregister G722.1 codec factory. */\n    status = pjmedia_codec_mgr_unregister_factory(codec_mgr,\n\t\t\t\t\t\t  &codec_factory.base);\n    \n    /* Destroy mutex. */\n    pj_mutex_unlock(codec_factory.mutex);\n    pj_mutex_destroy(codec_factory.mutex);\n    codec_factory.mutex = NULL;\n\n    /* Destroy pool. */\n    pj_pool_release(codec_factory.pool);\n    codec_factory.pool = NULL;\n\n    return status;\n}\n\n/* \n * Check if factory can allocate the specified codec. \n */\nstatic pj_status_t test_alloc( pjmedia_codec_factory *factory, \n\t\t\t       const pjmedia_codec_info *info )\n{\n    PJ_UNUSED_ARG(factory);\n\n    /* Type MUST be audio. */\n    if (info->type != PJMEDIA_TYPE_AUDIO)\n\treturn PJMEDIA_CODEC_EUNSUP;\n\n    /* Check encoding name. */\n    if (pj_stricmp2(&info->encoding_name, CODEC_TAG) != 0)\n\treturn PJMEDIA_CODEC_EUNSUP;\n\n    /* Check clock-rate */\n    if (info->clock_rate != WB_SAMPLE_RATE && \n\tinfo->clock_rate != UWB_SAMPLE_RATE)\n    {\n\treturn PJMEDIA_CODEC_EUNSUP;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Generate default attribute.\n */\nstatic pj_status_t default_attr ( pjmedia_codec_factory *factory, \n\t\t\t\t  const pjmedia_codec_info *id, \n\t\t\t\t  pjmedia_codec_param *attr )\n{\n    codec_mode *mode;\n\n    PJ_ASSERT_RETURN(factory==&codec_factory.base, PJ_EINVAL);\n\n    pj_bzero(attr, sizeof(pjmedia_codec_param));\n\n    mode = lookup_mode(id->pt);\n    if (mode == NULL || !mode->enabled)\n\treturn PJMEDIA_CODEC_EUNSUP;\n\n    attr->info.pt = (pj_uint8_t)id->pt;\n    attr->info.channel_cnt = 1;\n    attr->info.clock_rate = mode->sample_rate;\n    attr->info.max_bps = mode->bitrate;\n    attr->info.avg_bps = mode->bitrate;\n    attr->info.pcm_bits_per_sample = 16;\n    attr->info.frm_ptime = 20;\n\n    /* Default flags. */\n    attr->setting.plc = 1;\n    attr->setting.vad = 0;\n    attr->setting.frm_per_pkt = 1;\n\n    /* Default FMTP setting */\n    attr->setting.dec_fmtp.cnt = 1;\n    attr->setting.dec_fmtp.param[0].name = pj_str(\"bitrate\");\n    attr->setting.dec_fmtp.param[0].val = pj_str(mode->bitrate_str);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Enum codecs supported by this factory.\n */\nstatic pj_status_t enum_codecs( pjmedia_codec_factory *factory, \n\t\t\t\tunsigned *count, \n\t\t\t\tpjmedia_codec_info codecs[])\n{\n    unsigned i, max_cnt;\n\n    PJ_ASSERT_RETURN(factory==&codec_factory.base, PJ_EINVAL);\n    PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);\n\n    max_cnt = *count;\n    *count = 0;\n    \n    for (i=0; (i < codec_factory.mode_count) && (*count < max_cnt); ++i)\n    {\n\tif (!codec_factory.modes[i].enabled)\n\t    continue;\n\n\tpj_bzero(&codecs[*count], sizeof(pjmedia_codec_info));\n\tcodecs[*count].encoding_name = pj_str((char*)CODEC_TAG);\n\tcodecs[*count].pt = codec_factory.modes[i].pt;\n\tcodecs[*count].type = PJMEDIA_TYPE_AUDIO;\n\tcodecs[*count].clock_rate = codec_factory.modes[i].sample_rate;\n\tcodecs[*count].channel_cnt = 1;\n\n\t++ *count;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Allocate a new codec instance.\n */\nstatic pj_status_t alloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\tconst pjmedia_codec_info *id,\n\t\t\t\tpjmedia_codec **p_codec)\n{\n    codec_private_t *codec_data;\n    pjmedia_codec *codec;\n    pj_pool_t *pool;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &codec_factory.base, PJ_EINVAL);\n\n    pj_mutex_lock(codec_factory.mutex);\n\n    /* Create pool for codec instance */\n    pool = pjmedia_endpt_create_pool(codec_factory.endpt, \"G7221\", 512, 512);\n    codec = PJ_POOL_ZALLOC_T(pool, pjmedia_codec);\n    codec->op = &codec_op;\n    codec->factory = factory;\n    codec->codec_data = PJ_POOL_ZALLOC_T(pool, codec_private_t);\n    codec_data = (codec_private_t*) codec->codec_data;\n    codec_data->pool = pool;\n\n    /* Create silence detector */\n    status = pjmedia_silence_det_create(pool, id->clock_rate, \n\t\t\t\t\tid->clock_rate * 20 / 1000,\n\t\t\t\t\t&codec_data->vad);\n    if (status != PJ_SUCCESS) {\n\tpj_mutex_unlock(codec_factory.mutex);\n\treturn status;\n    }\n\n    pj_mutex_unlock(codec_factory.mutex);\n\n    *p_codec = codec;\n    return PJ_SUCCESS;\n}\n\n/*\n * Free codec.\n */\nstatic pj_status_t dealloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t  pjmedia_codec *codec )\n{\n    codec_private_t *codec_data;\n    pj_pool_t *pool;\n\n    PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &codec_factory.base, PJ_EINVAL);\n\n    /* Close codec, if it's not closed. */\n    codec_data = (codec_private_t*) codec->codec_data;\n    pool = codec_data->pool;\n    codec_close(codec);\n\n    /* Release codec pool */\n    pj_pool_release(pool);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Init codec.\n */\nstatic pj_status_t codec_init( pjmedia_codec *codec, \n\t\t\t       pj_pool_t *pool )\n{\n    PJ_UNUSED_ARG(codec);\n    PJ_UNUSED_ARG(pool);\n    return PJ_SUCCESS;\n}\n\n/*\n * Open codec.\n */\nstatic pj_status_t codec_open( pjmedia_codec *codec, \n\t\t\t       pjmedia_codec_param *attr )\n{\n    codec_private_t *codec_data = (codec_private_t*) codec->codec_data;\n    pj_pool_t *pool;\n    pjmedia_codec_fmtp *fmtp = &attr->setting.dec_fmtp;\n    pj_uint16_t fmtp_bitrate = 0;\n    unsigned tmp;\n\n    for (tmp = 0; tmp < fmtp->cnt && !fmtp_bitrate; ++tmp) {\n\tif (!pj_strcmp2(&fmtp->param[tmp].name, \"bitrate\"))\n\t    fmtp_bitrate = (pj_uint16_t)pj_strtoul(&fmtp->param[tmp].val);\n    }\n\n    if (fmtp_bitrate == 0)\n\tfmtp_bitrate = (pj_uint16_t)attr->info.avg_bps;\n\n    /* Validate bitrate */\n    if (!fmtp_bitrate || !validate_mode(attr->info.clock_rate, fmtp_bitrate))\n\treturn PJMEDIA_CODEC_EINMODE;\n\n    pool = codec_data->pool;\n\n    /* Initialize common state */\n    codec_data->vad_enabled = (attr->setting.vad != 0);\n    codec_data->plc_enabled = (attr->setting.plc != 0);\n\n    codec_data->bitrate = fmtp_bitrate;\n    codec_data->frame_size_bits = fmtp_bitrate*20/1000;\n    codec_data->frame_size = (pj_uint16_t)(codec_data->frame_size_bits>>3);\n    codec_data->samples_per_frame = (pj_uint16_t)\n\t\t\t\t    (attr->info.clock_rate*20/1000);\n    codec_data->number_of_regions = (pj_uint16_t)\n\t\t\t\t    (attr->info.clock_rate <= WB_SAMPLE_RATE?\n\t\t\t\t     NUMBER_OF_REGIONS:MAX_NUMBER_OF_REGIONS);\n    codec_data->pcm_shift = codec_factory.pcm_shift;\n\n    /* Initialize encoder state */\n    tmp = codec_data->samples_per_frame << 1;\n    codec_data->enc_old_frame = (Word16*)pj_pool_zalloc(pool, tmp);\n    codec_data->enc_frame = (Word16*)pj_pool_alloc(pool, tmp);\n\n    /* Initialize decoder state */\n    tmp = codec_data->samples_per_frame;\n    codec_data->dec_old_frame = (Word16*)pj_pool_zalloc(pool, tmp);\n\n    tmp = codec_data->samples_per_frame << 1;\n    codec_data->dec_old_mlt_coefs = (Word16*)pj_pool_zalloc(pool, tmp);\n\n    codec_data->dec_randobj.seed0 = 1;\n    codec_data->dec_randobj.seed1 = 1;\n    codec_data->dec_randobj.seed2 = 1;\n    codec_data->dec_randobj.seed3 = 1;\n\n    /* Update codec param */\n    attr->info.avg_bps = attr->info.max_bps = fmtp_bitrate;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Close codec.\n */\nstatic pj_status_t codec_close( pjmedia_codec *codec )\n{\n    PJ_UNUSED_ARG(codec);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Modify codec settings.\n */\nstatic pj_status_t codec_modify( pjmedia_codec *codec, \n\t\t\t\t const pjmedia_codec_param *attr )\n{\n    codec_private_t *codec_data = (codec_private_t*) codec->codec_data;\n\n    codec_data->vad_enabled = (attr->setting.vad != 0);\n    codec_data->plc_enabled = (attr->setting.plc != 0);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get frames in the packet.\n */\nstatic pj_status_t codec_parse( pjmedia_codec *codec,\n\t\t\t\tvoid *pkt,\n\t\t\t\tpj_size_t pkt_size,\n\t\t\t\tconst pj_timestamp *ts,\n\t\t\t\tunsigned *frame_cnt,\n\t\t\t\tpjmedia_frame frames[])\n{\n    codec_private_t *codec_data = (codec_private_t*) codec->codec_data;\n    unsigned count = 0;\n\n    PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);\n\n    /* Parse based on fixed frame size. */\n    while (pkt_size >= codec_data->frame_size && count < *frame_cnt) {\n\tframes[count].type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframes[count].buf = pkt;\n\tframes[count].size = codec_data->frame_size;\n\tframes[count].timestamp.u64 = ts->u64 + \n\t\t\t\t      count * codec_data->samples_per_frame;\n\n\tpkt = (pj_uint8_t*)pkt + codec_data->frame_size;\n\tpkt_size -= codec_data->frame_size;\n\n\t++count;\n    }\n\n    pj_assert(pkt_size == 0);\n    *frame_cnt = count;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Encode frames.\n */\nstatic pj_status_t codec_encode( pjmedia_codec *codec, \n\t\t\t\t const struct pjmedia_frame *input,\n\t\t\t\t unsigned output_buf_len, \n\t\t\t\t struct pjmedia_frame *output)\n{\n    codec_private_t *codec_data = (codec_private_t*) codec->codec_data;\n    unsigned nsamples, processed;\n\n    /* Check frame in & out size */\n    nsamples = input->size >> 1;\n    PJ_ASSERT_RETURN(nsamples % codec_data->samples_per_frame == 0, \n\t\t     PJMEDIA_CODEC_EPCMFRMINLEN);\n    PJ_ASSERT_RETURN(output_buf_len >= codec_data->frame_size * nsamples /\n\t\t     codec_data->samples_per_frame,\n\t\t     PJMEDIA_CODEC_EFRMTOOSHORT);\n\n    /* Apply silence detection if VAD is enabled */\n    if (codec_data->vad_enabled) {\n\tpj_bool_t is_silence;\n\tpj_int32_t silence_duration;\n\n\tpj_assert(codec_data->vad);\n\n\tsilence_duration = pj_timestamp_diff32(&codec_data->last_tx, \n\t\t\t\t\t       &input->timestamp);\n\n\tis_silence = pjmedia_silence_det_detect(codec_data->vad, \n\t\t\t\t\t        (const pj_int16_t*) input->buf,\n\t\t\t\t\t\t(input->size >> 1),\n\t\t\t\t\t\tNULL);\n\tif (is_silence &&\n\t    (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||\n\t     silence_duration < (PJMEDIA_CODEC_MAX_SILENCE_PERIOD *\n\t\t\t         (int)codec_data->samples_per_frame / 20)))\n\t{\n\t    output->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    output->buf = NULL;\n\t    output->size = 0;\n\t    output->timestamp = input->timestamp;\n\t    return PJ_SUCCESS;\n\t} else {\n\t    codec_data->last_tx = input->timestamp;\n\t}\n    }\n\n    processed = 0;\n    output->size = 0;\n    while (processed < nsamples) {\n\tWord16 mlt_coefs[MAX_SAMPLES_PER_FRAME];\n\tWord16 mag_shift;\n\tconst Word16 *pcm_input;\n\tpj_int8_t *out_bits;\n\t\n\tpcm_input = (const Word16*)input->buf + processed;\n\tout_bits = (pj_int8_t*)output->buf + output->size;\n\n\t/* Encoder adjust the input signal level */\n\tif (codec_data->pcm_shift) {\n\t    unsigned i;\n\t    for (i=0; i<codec_data->samples_per_frame; ++i) {\n\t\tcodec_data->enc_frame[i] = \n\t\t\t(Word16)(pcm_input[i] >> codec_data->pcm_shift);\n\t    }\n\t    pcm_input = codec_data->enc_frame;\n\t}\n\n\t/* Convert input samples to rmlt coefs */\n\tmag_shift = samples_to_rmlt_coefs(pcm_input,\n\t\t\t\t\t  codec_data->enc_old_frame, \n\t\t\t\t\t  mlt_coefs, \n\t\t\t\t\t  codec_data->samples_per_frame);\n\n\t/* Encode the mlt coefs. Note that encoder output stream is\n\t * 16 bit array, so we need to take care about endianness.\n\t */\n\tencoder(codec_data->frame_size_bits,\n\t\tcodec_data->number_of_regions,\n\t\tmlt_coefs,\n\t\tmag_shift,\n\t\t(Word16*)out_bits);\n\n\t/* Encoder output are in native host byte order, while ITU says\n\t * it must be in network byte order (MSB first).\n\t */\n\tswap_bytes((pj_uint16_t*)out_bits, codec_data->frame_size/2);\n\n\tprocessed += codec_data->samples_per_frame;\n\toutput->size += codec_data->frame_size;\n    }\n\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    output->timestamp = input->timestamp;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Decode frame.\n */\nstatic pj_status_t codec_decode( pjmedia_codec *codec, \n\t\t\t\t const struct pjmedia_frame *input,\n\t\t\t\t unsigned output_buf_len, \n\t\t\t\t struct pjmedia_frame *output)\n{\n    codec_private_t *codec_data = (codec_private_t*) codec->codec_data;\n    Word16 mlt_coefs[MAX_SAMPLES_PER_FRAME];\n    Word16 mag_shift;\n    Bit_Obj bitobj;\n    Word16 frame_error_flag = 0;\n\n    /* Check frame out length size */\n    PJ_ASSERT_RETURN(output_buf_len >= \n\t\t    (unsigned)(codec_data->samples_per_frame<<1),\n\t\t     PJMEDIA_CODEC_EPCMTOOSHORT);\n\n    /* If input is NULL, perform PLC by settting frame_error_flag to 1 */\n    if (input) {\n\t/* Check frame in length size */\n\tPJ_ASSERT_RETURN((pj_uint16_t)input->size == codec_data->frame_size,\n\t\t\t PJMEDIA_CODEC_EFRMINLEN);\n\n\t/* Decoder requires input of 16-bits array in native host byte\n\t * order, while the frame received from the network are in\n\t * network byte order (MSB first).\n\t */\n\tswap_bytes((pj_uint16_t*)input->buf, codec_data->frame_size/2);\n\n\tbitobj.code_word_ptr = (Word16*)input->buf;\n\tbitobj.current_word =  *bitobj.code_word_ptr;\n\tbitobj.code_bit_count = 0;\n\tbitobj.number_of_bits_left = codec_data->frame_size_bits;\n\n\toutput->timestamp = input->timestamp;\n    } else {\n\tpj_bzero(&bitobj, sizeof(bitobj));\n\tframe_error_flag = 1;\n    }\n\n    /* Process the input frame to get mlt coefs */\n    decoder(&bitobj,\n\t    &codec_data->dec_randobj,\n            codec_data->number_of_regions,\n\t    mlt_coefs,\n            &mag_shift,\n\t    &codec_data->dec_old_mag_shift,\n            codec_data->dec_old_mlt_coefs,\n            frame_error_flag);\n\n    /* Convert the mlt_coefs to PCM samples */\n    rmlt_coefs_to_samples(mlt_coefs, \n\t\t\t  codec_data->dec_old_frame, \n\t\t\t  (Word16*)output->buf, \n\t\t\t  codec_data->samples_per_frame, \n\t\t\t  mag_shift);\n\n    /* Decoder adjust PCM signal */\n    if (codec_data->pcm_shift) {\n\tunsigned i;\n\tpj_int16_t *buf = (Word16*)output->buf;\n\n\tfor (i=0; i<codec_data->samples_per_frame; ++i) {\n\t    buf[i] <<= codec_data->pcm_shift;\n\t}\n    }\n\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    output->size = codec_data->samples_per_frame << 1;\n\n    return PJ_SUCCESS;\n}\n\n/* \n * Recover lost frame.\n */\nstatic pj_status_t codec_recover( pjmedia_codec *codec, \n\t\t\t\t  unsigned output_buf_len, \n\t\t\t\t  struct pjmedia_frame *output)\n{\n    codec_private_t *codec_data = (codec_private_t*) codec->codec_data;\n\n    /* Use native PLC when PLC is enabled. */\n    if (codec_data->plc_enabled)\n\treturn codec_decode(codec, NULL, output_buf_len, output);\n\n    /* Otherwise just return zero-fill frame. */\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    output->size = codec_data->samples_per_frame << 1;\n\n    pjmedia_zero_samples((pj_int16_t*)output->buf, \n\t\t\t codec_data->samples_per_frame);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_HAS_G7221_CODEC */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/g7221_sdp_match.c",
    "content": "/* $Id: g7221_sdp_match.c 3911 2011-12-15 06:45:23Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-codec/g7221_sdp_match.h>\n#include <pjmedia/errno.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n#define GET_FMTP_IVAL_BASE(ival, base, fmtp, param, default_val) \\\n    do { \\\n\tpj_str_t s; \\\n\tchar *p; \\\n\tp = pj_stristr(&fmtp.fmt_param, &param); \\\n\tif (!p) { \\\n\t    ival = default_val; \\\n\t    break; \\\n\t} \\\n\tpj_strset(&s, p + param.slen, fmtp.fmt_param.slen - \\\n\t\t  (p - fmtp.fmt_param.ptr) - param.slen); \\\n\tival = pj_strtoul2(&s, NULL, base); \\\n    } while (0)\n\n#define GET_FMTP_IVAL(ival, fmtp, param, default_val) \\\n\tGET_FMTP_IVAL_BASE(ival, 10, fmtp, param, default_val)\n\n\n\nPJ_DEF(pj_status_t) pjmedia_codec_g7221_match_sdp(pj_pool_t *pool,\n\t\t\t\t\t\t  pjmedia_sdp_media *offer,\n\t\t\t\t\t\t  unsigned o_fmt_idx,\n\t\t\t\t\t\t  pjmedia_sdp_media *answer,\n\t\t\t\t\t\t  unsigned a_fmt_idx,\n\t\t\t\t\t\t  unsigned option)\n{\n    const pjmedia_sdp_attr *attr_ans;\n    const pjmedia_sdp_attr *attr_ofr;\n    pjmedia_sdp_fmtp fmtp;\n    unsigned a_bitrate, o_bitrate;\n    const pj_str_t bitrate = {\"bitrate=\", 8};\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(option);\n\n    /* Parse offer */\n    attr_ofr = pjmedia_sdp_media_find_attr2(offer, \"fmtp\", \n\t\t\t\t\t    &offer->desc.fmt[o_fmt_idx]);\n    if (!attr_ofr)\n\treturn PJMEDIA_SDP_EINFMTP;\n\n    status = pjmedia_sdp_attr_get_fmtp(attr_ofr, &fmtp);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    GET_FMTP_IVAL(o_bitrate, fmtp, bitrate, 0);\n\n    /* Parse answer */\n    attr_ans = pjmedia_sdp_media_find_attr2(answer, \"fmtp\", \n\t\t\t\t\t    &answer->desc.fmt[a_fmt_idx]);\n    if (!attr_ans)\n\treturn PJMEDIA_SDP_EINFMTP;\n\n    status = pjmedia_sdp_attr_get_fmtp(attr_ans, &fmtp);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    GET_FMTP_IVAL(a_bitrate, fmtp, bitrate, 0);\n\n    /* Compare bitrate in answer and offer. */\n    if (a_bitrate != o_bitrate)\n\treturn PJMEDIA_SDP_EFORMATNOTEQUAL;\n\n    return PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/gsm.c",
    "content": "/* $Id: gsm.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-codec/gsm.h>\n#include <pjmedia/codec.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/endpoint.h>\n#include <pjmedia/plc.h>\n#include <pjmedia/port.h>\n#include <pjmedia/silencedet.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/os.h>\n\n/*\n * Only build this file if PJMEDIA_HAS_GSM_CODEC != 0\n */\n#if defined(PJMEDIA_HAS_GSM_CODEC) && PJMEDIA_HAS_GSM_CODEC != 0\n\n#if defined(PJMEDIA_EXTERNAL_GSM_CODEC) && PJMEDIA_EXTERNAL_GSM_CODEC\n# if PJMEDIA_EXTERNAL_GSM_GSM_H\n#   include <gsm/gsm.h>\n# elif PJMEDIA_EXTERNAL_GSM_H\n#   include <gsm.h>\n# else\n#   error Please set the location of gsm.h\n# endif\n#else\n#   include \"../../third_party/gsm/inc/gsm.h\"\n#endif\n\n/* We removed PLC in 0.6 (and re-enabled it again in 0.9!) */\n#define PLC_DISABLED\t0\n\n\n/* Prototypes for GSM factory */\nstatic pj_status_t gsm_test_alloc( pjmedia_codec_factory *factory, \n\t\t\t\t   const pjmedia_codec_info *id );\nstatic pj_status_t gsm_default_attr( pjmedia_codec_factory *factory, \n\t\t\t\t     const pjmedia_codec_info *id, \n\t\t\t\t     pjmedia_codec_param *attr );\nstatic pj_status_t gsm_enum_codecs( pjmedia_codec_factory *factory, \n\t\t\t\t    unsigned *count, \n\t\t\t\t    pjmedia_codec_info codecs[]);\nstatic pj_status_t gsm_alloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t    const pjmedia_codec_info *id, \n\t\t\t\t    pjmedia_codec **p_codec);\nstatic pj_status_t gsm_dealloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t      pjmedia_codec *codec );\n\n/* Prototypes for GSM implementation. */\nstatic pj_status_t  gsm_codec_init( pjmedia_codec *codec, \n\t\t\t\t    pj_pool_t *pool );\nstatic pj_status_t  gsm_codec_open( pjmedia_codec *codec, \n\t\t\t\t    pjmedia_codec_param *attr );\nstatic pj_status_t  gsm_codec_close( pjmedia_codec *codec );\nstatic pj_status_t  gsm_codec_modify(pjmedia_codec *codec, \n\t\t\t\t     const pjmedia_codec_param *attr );\nstatic pj_status_t  gsm_codec_parse( pjmedia_codec *codec,\n\t\t\t\t     void *pkt,\n\t\t\t\t     pj_size_t pkt_size,\n\t\t\t\t     const pj_timestamp *ts,\n\t\t\t\t     unsigned *frame_cnt,\n\t\t\t\t     pjmedia_frame frames[]);\nstatic pj_status_t  gsm_codec_encode( pjmedia_codec *codec, \n\t\t\t\t      const struct pjmedia_frame *input,\n\t\t\t\t      unsigned output_buf_len, \n\t\t\t\t      struct pjmedia_frame *output);\nstatic pj_status_t  gsm_codec_decode( pjmedia_codec *codec, \n\t\t\t\t      const struct pjmedia_frame *input,\n\t\t\t\t      unsigned output_buf_len, \n\t\t\t\t      struct pjmedia_frame *output);\n#if !PLC_DISABLED\nstatic pj_status_t  gsm_codec_recover(pjmedia_codec *codec,\n\t\t\t\t      unsigned output_buf_len,\n\t\t\t\t      struct pjmedia_frame *output);\n#endif\n\n/* Definition for GSM codec operations. */\nstatic pjmedia_codec_op gsm_op = \n{\n    &gsm_codec_init,\n    &gsm_codec_open,\n    &gsm_codec_close,\n    &gsm_codec_modify,\n    &gsm_codec_parse,\n    &gsm_codec_encode,\n    &gsm_codec_decode,\n#if !PLC_DISABLED\n    &gsm_codec_recover\n#else\n    NULL\n#endif\n};\n\n/* Definition for GSM codec factory operations. */\nstatic pjmedia_codec_factory_op gsm_factory_op =\n{\n    &gsm_test_alloc,\n    &gsm_default_attr,\n    &gsm_enum_codecs,\n    &gsm_alloc_codec,\n    &gsm_dealloc_codec,\n    &pjmedia_codec_gsm_deinit\n};\n\n/* GSM factory */\nstatic struct gsm_codec_factory\n{\n    pjmedia_codec_factory    base;\n    pjmedia_endpt\t    *endpt;\n    pj_pool_t\t\t    *pool;\n    pj_mutex_t\t\t    *mutex;\n    pjmedia_codec\t     codec_list;\n} gsm_codec_factory;\n\n\n/* GSM codec private data. */\nstruct gsm_data\n{\n    struct gsm_state\t*encoder;\n    struct gsm_state\t*decoder;\n    pj_bool_t\t\t plc_enabled;\n#if !PLC_DISABLED\n    pjmedia_plc\t\t*plc;\n#endif\n    pj_bool_t\t\t vad_enabled;\n    pjmedia_silence_det\t*vad;\n    pj_timestamp\t last_tx;\n};\n\n\n\n/*\n * Initialize and register GSM codec factory to pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_gsm_init( pjmedia_endpt *endpt )\n{\n    pjmedia_codec_mgr *codec_mgr;\n    pj_status_t status;\n\n    if (gsm_codec_factory.pool != NULL)\n\treturn PJ_SUCCESS;\n\n    /* Create GSM codec factory. */\n    gsm_codec_factory.base.op = &gsm_factory_op;\n    gsm_codec_factory.base.factory_data = NULL;\n    gsm_codec_factory.endpt = endpt;\n\n    gsm_codec_factory.pool = pjmedia_endpt_create_pool(endpt, \"gsm\", 4000, \n\t\t\t\t\t\t       4000);\n    if (!gsm_codec_factory.pool)\n\treturn PJ_ENOMEM;\n\n    pj_list_init(&gsm_codec_factory.codec_list);\n\n    /* Create mutex. */\n    status = pj_mutex_create_simple(gsm_codec_factory.pool, \"gsm\", \n\t\t\t\t    &gsm_codec_factory.mutex);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);\n    if (!codec_mgr) {\n\tstatus = PJ_EINVALIDOP;\n\tgoto on_error;\n    }\n\n    /* Register codec factory to endpoint. */\n    status = pjmedia_codec_mgr_register_factory(codec_mgr, \n\t\t\t\t\t\t&gsm_codec_factory.base);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Done. */\n    return PJ_SUCCESS;\n\non_error:\n    pj_pool_release(gsm_codec_factory.pool);\n    gsm_codec_factory.pool = NULL;\n    return status;\n}\n\n\n\n/*\n * Unregister GSM codec factory from pjmedia endpoint and deinitialize\n * the GSM codec library.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_gsm_deinit(void)\n{\n    pjmedia_codec_mgr *codec_mgr;\n    pj_status_t status;\n\n    if (gsm_codec_factory.pool == NULL)\n\treturn PJ_SUCCESS;\n\n    /* We don't want to deinit if there's outstanding codec. */\n    /* This is silly, as we'll always have codec in the list if\n       we ever allocate a codec! A better behavior maybe is to \n       deallocate all codecs in the list.\n    pj_mutex_lock(gsm_codec_factory.mutex);\n    if (!pj_list_empty(&gsm_codec_factory.codec_list)) {\n\tpj_mutex_unlock(gsm_codec_factory.mutex);\n\treturn PJ_EBUSY;\n    }\n    */\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(gsm_codec_factory.endpt);\n    if (!codec_mgr) {\n\tpj_pool_release(gsm_codec_factory.pool);\n\tgsm_codec_factory.pool = NULL;\n\treturn PJ_EINVALIDOP;\n    }\n\n    /* Unregister GSM codec factory. */\n    status = pjmedia_codec_mgr_unregister_factory(codec_mgr,\n\t\t\t\t\t\t  &gsm_codec_factory.base);\n    \n    /* Destroy mutex. */\n    pj_mutex_destroy(gsm_codec_factory.mutex);\n\n    /* Destroy pool. */\n    pj_pool_release(gsm_codec_factory.pool);\n    gsm_codec_factory.pool = NULL;\n\n    return status;\n}\n\n/* \n * Check if factory can allocate the specified codec. \n */\nstatic pj_status_t gsm_test_alloc( pjmedia_codec_factory *factory, \n\t\t\t\t   const pjmedia_codec_info *info )\n{\n    PJ_UNUSED_ARG(factory);\n\n    /* Check payload type. */\n    if (info->pt != PJMEDIA_RTP_PT_GSM)\n\treturn PJMEDIA_CODEC_EUNSUP;\n\n    /* Ignore the rest, since it's static payload type. */\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Generate default attribute.\n */\nstatic pj_status_t gsm_default_attr (pjmedia_codec_factory *factory, \n\t\t\t\t      const pjmedia_codec_info *id, \n\t\t\t\t      pjmedia_codec_param *attr )\n{\n    PJ_UNUSED_ARG(factory);\n    PJ_UNUSED_ARG(id);\n\n    pj_bzero(attr, sizeof(pjmedia_codec_param));\n    attr->info.clock_rate = 8000;\n    attr->info.channel_cnt = 1;\n    attr->info.avg_bps = 13200;\n    attr->info.max_bps = 13200;\n    attr->info.pcm_bits_per_sample = 16;\n    attr->info.frm_ptime = 20;\n    attr->info.pt = PJMEDIA_RTP_PT_GSM;\n\n    attr->setting.frm_per_pkt = 1;\n    attr->setting.vad = 1;\n#if !PLC_DISABLED\n    attr->setting.plc = 1;\n#endif\n\n    /* Default all other flag bits disabled. */\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Enum codecs supported by this factory (i.e. only GSM!).\n */\nstatic pj_status_t gsm_enum_codecs(pjmedia_codec_factory *factory, \n\t\t\t\t    unsigned *count, \n\t\t\t\t    pjmedia_codec_info codecs[])\n{\n    PJ_UNUSED_ARG(factory);\n    PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);\n\n    pj_bzero(&codecs[0], sizeof(pjmedia_codec_info));\n    codecs[0].encoding_name = pj_str(\"GSM\");\n    codecs[0].pt = PJMEDIA_RTP_PT_GSM;\n    codecs[0].type = PJMEDIA_TYPE_AUDIO;\n    codecs[0].clock_rate = 8000;\n    codecs[0].channel_cnt = 1;\n\n    *count = 1;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Allocate a new GSM codec instance.\n */\nstatic pj_status_t gsm_alloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t    const pjmedia_codec_info *id,\n\t\t\t\t    pjmedia_codec **p_codec)\n{\n    pjmedia_codec *codec;\n    struct gsm_data *gsm_data;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &gsm_codec_factory.base, PJ_EINVAL);\n\n\n    pj_mutex_lock(gsm_codec_factory.mutex);\n\n    /* Get free nodes, if any. */\n    if (!pj_list_empty(&gsm_codec_factory.codec_list)) {\n\tcodec = gsm_codec_factory.codec_list.next;\n\tpj_list_erase(codec);\n    } else {\n\tcodec = PJ_POOL_ZALLOC_T(gsm_codec_factory.pool, pjmedia_codec);\n\tPJ_ASSERT_RETURN(codec != NULL, PJ_ENOMEM);\n\tcodec->op = &gsm_op;\n\tcodec->factory = factory;\n\n\tgsm_data = PJ_POOL_ZALLOC_T(gsm_codec_factory.pool, struct gsm_data);\n\tcodec->codec_data = gsm_data;\n\n#if !PLC_DISABLED\n\t/* Create PLC */\n\tstatus = pjmedia_plc_create(gsm_codec_factory.pool, 8000, \n\t\t\t\t    160, 0, &gsm_data->plc);\n\tif (status != PJ_SUCCESS) {\n\t    pj_mutex_unlock(gsm_codec_factory.mutex);\n\t    return status;\n\t}\n#endif\n\n\t/* Create silence detector */\n\tstatus = pjmedia_silence_det_create(gsm_codec_factory.pool,\n\t\t\t\t\t    8000, 160,\n\t\t\t\t\t    &gsm_data->vad);\n\tif (status != PJ_SUCCESS) {\n\t    pj_mutex_unlock(gsm_codec_factory.mutex);\n\t    return status;\n\t}\n    }\n\n    pj_mutex_unlock(gsm_codec_factory.mutex);\n\n    *p_codec = codec;\n    return PJ_SUCCESS;\n}\n\n/*\n * Free codec.\n */\nstatic pj_status_t gsm_dealloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t      pjmedia_codec *codec )\n{\n    struct gsm_data *gsm_data;\n    int i;\n\n    PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &gsm_codec_factory.base, PJ_EINVAL);\n\n    gsm_data = (struct gsm_data*) codec->codec_data;\n\n    /* Close codec, if it's not closed. */\n    gsm_codec_close(codec);\n\n#if !PLC_DISABLED\n    /* Clear left samples in the PLC, since codec+plc will be reused\n     * next time.\n     */\n    for (i=0; i<2; ++i) {\n\tpj_int16_t frame[160];\n\tpjmedia_zero_samples(frame, PJ_ARRAY_SIZE(frame));\n\tpjmedia_plc_save(gsm_data->plc, frame);\n    }\n#else\n    PJ_UNUSED_ARG(i);\n#endif\n\n    /* Re-init silence_period */\n    pj_set_timestamp32(&gsm_data->last_tx, 0, 0);\n\n    /* Put in the free list. */\n    pj_mutex_lock(gsm_codec_factory.mutex);\n    pj_list_push_front(&gsm_codec_factory.codec_list, codec);\n    pj_mutex_unlock(gsm_codec_factory.mutex);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Init codec.\n */\nstatic pj_status_t gsm_codec_init( pjmedia_codec *codec, \n\t\t\t\t   pj_pool_t *pool )\n{\n    PJ_UNUSED_ARG(codec);\n    PJ_UNUSED_ARG(pool);\n    return PJ_SUCCESS;\n}\n\n/*\n * Open codec.\n */\nstatic pj_status_t gsm_codec_open( pjmedia_codec *codec, \n\t\t\t\t   pjmedia_codec_param *attr )\n{\n    struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data;\n\n    pj_assert(gsm_data != NULL);\n    pj_assert(gsm_data->encoder == NULL && gsm_data->decoder == NULL);\n\n    gsm_data->encoder = gsm_create();\n    if (!gsm_data->encoder)\n\treturn PJMEDIA_CODEC_EFAILED;\n\n    gsm_data->decoder = gsm_create();\n    if (!gsm_data->decoder)\n\treturn PJMEDIA_CODEC_EFAILED;\n\n    gsm_data->vad_enabled = (attr->setting.vad != 0);\n    gsm_data->plc_enabled = (attr->setting.plc != 0);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Close codec.\n */\nstatic pj_status_t gsm_codec_close( pjmedia_codec *codec )\n{\n    struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data;\n\n    pj_assert(gsm_data != NULL);\n\n    if (gsm_data->encoder) {\n\tgsm_destroy(gsm_data->encoder);\n\tgsm_data->encoder = NULL;\n    }\n    if (gsm_data->decoder) {\n\tgsm_destroy(gsm_data->decoder);\n\tgsm_data->decoder = NULL;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Modify codec settings.\n */\nstatic pj_status_t  gsm_codec_modify(pjmedia_codec *codec, \n\t\t\t\t     const pjmedia_codec_param *attr )\n{\n    struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data;\n\n    pj_assert(gsm_data != NULL);\n    pj_assert(gsm_data->encoder != NULL && gsm_data->decoder != NULL);\n\n    gsm_data->vad_enabled = (attr->setting.vad != 0);\n    gsm_data->plc_enabled = (attr->setting.plc != 0);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get frames in the packet.\n */\nstatic pj_status_t  gsm_codec_parse( pjmedia_codec *codec,\n\t\t\t\t     void *pkt,\n\t\t\t\t     pj_size_t pkt_size,\n\t\t\t\t     const pj_timestamp *ts,\n\t\t\t\t     unsigned *frame_cnt,\n\t\t\t\t     pjmedia_frame frames[])\n{\n    unsigned count = 0;\n\n    PJ_UNUSED_ARG(codec);\n\n    PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);\n\n    while (pkt_size >= 33 && count < *frame_cnt) {\n\tframes[count].type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframes[count].buf = pkt;\n\tframes[count].size = 33;\n\tframes[count].timestamp.u64 = ts->u64 + count * 160;\n\n\tpkt = ((char*)pkt) + 33;\n\tpkt_size -= 33;\n\n\t++count;\n    }\n\n    *frame_cnt = count;\n    return PJ_SUCCESS;\n}\n\n/*\n * Encode frame.\n */\nstatic pj_status_t gsm_codec_encode( pjmedia_codec *codec, \n\t\t\t\t     const struct pjmedia_frame *input,\n\t\t\t\t     unsigned output_buf_len, \n\t\t\t\t     struct pjmedia_frame *output)\n{\n    struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data;\n    pj_int16_t *pcm_in;\n    pj_size_t in_size;\n\n    pj_assert(gsm_data && input && output);\n    \n    pcm_in = (pj_int16_t*)input->buf;\n    in_size = input->size;\n\n    PJ_ASSERT_RETURN(in_size % 320 == 0, PJMEDIA_CODEC_EPCMFRMINLEN);\n    PJ_ASSERT_RETURN(output_buf_len >= 33 * in_size/320, \n\t\t     PJMEDIA_CODEC_EFRMTOOSHORT);\n\n    /* Detect silence */\n    if (gsm_data->vad_enabled) {\n\tpj_bool_t is_silence;\n\tpj_int32_t silence_duration;\n\n\tsilence_duration = pj_timestamp_diff32(&gsm_data->last_tx, \n\t\t\t\t\t       &input->timestamp);\n\n\tis_silence = pjmedia_silence_det_detect(gsm_data->vad, \n\t\t\t\t\t        (const pj_int16_t*) input->buf,\n\t\t\t\t\t\t(input->size >> 1),\n\t\t\t\t\t\tNULL);\n\tif (is_silence &&\n\t    (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||\n\t     silence_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000))\n\t{\n\t    output->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    output->buf = NULL;\n\t    output->size = 0;\n\t    output->timestamp = input->timestamp;\n\t    return PJ_SUCCESS;\n\t} else {\n\t    gsm_data->last_tx = input->timestamp;\n\t}\n    }\n\n    /* Encode */\n    output->size = 0;\n    while (in_size >= 320) {\n\tgsm_encode(gsm_data->encoder, pcm_in, \n\t\t   (unsigned char*)output->buf + output->size);\n\tpcm_in += 160;\n\toutput->size += 33;\n\tin_size -= 320;\n    }\n\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    output->timestamp = input->timestamp;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Decode frame.\n */\nstatic pj_status_t gsm_codec_decode( pjmedia_codec *codec, \n\t\t\t\t     const struct pjmedia_frame *input,\n\t\t\t\t     unsigned output_buf_len, \n\t\t\t\t     struct pjmedia_frame *output)\n{\n    struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data;\n\n    pj_assert(gsm_data != NULL);\n    PJ_ASSERT_RETURN(input && output, PJ_EINVAL);\n\n    if (output_buf_len < 320)\n\treturn PJMEDIA_CODEC_EPCMTOOSHORT;\n\n    if (input->size < 33)\n\treturn PJMEDIA_CODEC_EFRMTOOSHORT;\n\n    gsm_decode(gsm_data->decoder, \n\t       (unsigned char*)input->buf, \n\t       (short*)output->buf);\n\n    output->size = 320;\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    output->timestamp = input->timestamp;\n\n#if !PLC_DISABLED\n    if (gsm_data->plc_enabled)\n\tpjmedia_plc_save( gsm_data->plc, (pj_int16_t*)output->buf);\n#endif\n\n    return PJ_SUCCESS;\n}\n\n\n#if !PLC_DISABLED\n/*\n * Recover lost frame.\n */\nstatic pj_status_t  gsm_codec_recover(pjmedia_codec *codec,\n\t\t\t\t      unsigned output_buf_len,\n\t\t\t\t      struct pjmedia_frame *output)\n{\n    struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data;\n\n    PJ_ASSERT_RETURN(gsm_data->plc_enabled, PJ_EINVALIDOP);\n\n    PJ_ASSERT_RETURN(output_buf_len >= 320, PJMEDIA_CODEC_EPCMTOOSHORT);\n\n    pjmedia_plc_generate(gsm_data->plc, (pj_int16_t*)output->buf);\n    output->size = 320;\n\n    return PJ_SUCCESS;\n}\n#endif\n\n\n#endif\t/* PJMEDIA_HAS_GSM_CODEC */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/h263_packetizer.c",
    "content": "/* $Id: h263_packetizer.c 4006 2012-04-02 08:40:54Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-codec/h263_packetizer.h>\n#include <pjmedia/types.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/string.h>\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n\n#define THIS_FILE\t\"h263_packetizer.c\"\n\n\n/* H.263 packetizer definition */\nstruct pjmedia_h263_packetizer {\n    /* Current settings */\n    pjmedia_h263_packetizer_cfg cfg;\n    \n    /* Unpacketizer state */\n    unsigned\t    unpack_last_sync_pos;\n    pj_bool_t\t    unpack_prev_lost;\n};\n\n\n/*\n * Find synchronization point (PSC, slice, GSBC, EOS, EOSBS) in H.263 \n * bitstream.\n */\nstatic pj_uint8_t* find_sync_point(pj_uint8_t *data,\n\t\t\t\t   pj_size_t data_len)\n{\n    pj_uint8_t *p = data, *end = data+data_len-1;\n\n    while (p < end && (*p || *(p+1)))\n        ++p;\n\n    if (p == end)\n        return NULL;\n        \n    return p;\n}\n\n\n/*\n * Find synchronization point (PSC, slice, GSBC, EOS, EOSBS) in H.263 \n * bitstream, in reversed manner.\n */\nstatic pj_uint8_t* find_sync_point_rev(pj_uint8_t *data,\n                                       pj_size_t data_len)\n{\n    pj_uint8_t *p = data+data_len-2;\n\n    while (p >= data && (*p || *(p+1)))\n        --p;\n\n    if (p < data)\n        return (data + data_len);\n        \n    return p;\n}\n\n\n/*\n * Create H263 packetizer.\n */\nPJ_DEF(pj_status_t) pjmedia_h263_packetizer_create(\n\t\t\t\tpj_pool_t *pool,\n\t\t\t\tconst pjmedia_h263_packetizer_cfg *cfg,\n\t\t\t\tpjmedia_h263_packetizer **p)\n{\n    pjmedia_h263_packetizer *p_;\n\n    PJ_ASSERT_RETURN(pool && p, PJ_EINVAL);\n\n    if (cfg && cfg->mode != PJMEDIA_H263_PACKETIZER_MODE_RFC4629)\n\treturn PJ_ENOTSUP;\n\n    p_ = PJ_POOL_ZALLOC_T(pool, pjmedia_h263_packetizer);\n    if (cfg) {\n\tpj_memcpy(&p_->cfg, cfg, sizeof(*cfg));\n    } else {\n\tp_->cfg.mode = PJMEDIA_H263_PACKETIZER_MODE_RFC4629;\n\tp_->cfg.mtu = PJMEDIA_MAX_VID_PAYLOAD_SIZE;\n    }\n\n    *p = p_;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Generate an RTP payload from H.263 frame bitstream, in-place processing.\n */\nPJ_DEF(pj_status_t) pjmedia_h263_packetize(pjmedia_h263_packetizer *pktz,\n\t\t\t\t\t   pj_uint8_t *bits,\n                                           pj_size_t bits_len,\n                                           unsigned *pos,\n                                           const pj_uint8_t **payload,\n                                           pj_size_t *payload_len)\n{\n    pj_uint8_t *p, *end;\n\n    pj_assert(pktz && bits && pos && payload && payload_len);\n    pj_assert(*pos <= bits_len);\n\n    p = bits + *pos;\n    end = bits + bits_len;\n\n    /* Put two octets payload header */\n    if ((end-p > 2) && *p==0 && *(p+1)==0) {\n        /* The bitstream starts with synchronization point, just override\n         * the two zero octets (sync point mark) for payload header.\n         */\n        *p = 0x04;\n    } else {\n        /* Not started in synchronization point, we will use two octets\n         * preceeding the bitstream for payload header!\n         */\n\n\tif (*pos < 2) {\n\t    /* Invalid H263 bitstream, it's not started with PSC */\n\t    return PJ_EINVAL;\n\t}\n\n\tp -= 2;\n        *p = 0;\n    }\n    *(p+1) = 0;\n\n    /* When bitstream truncation needed because of payload length/MTU \n     * limitation, try to use sync point for the payload boundary.\n     */\n    if (end-p > pktz->cfg.mtu) {\n\tend = find_sync_point_rev(p+2, pktz->cfg.mtu-2);\n    }\n\n    *payload = p;\n    *payload_len = end-p;\n    *pos = (unsigned)(end - bits);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Append an RTP payload to a H.263 picture bitstream.\n */\nPJ_DEF(pj_status_t) pjmedia_h263_unpacketize (pjmedia_h263_packetizer *pktz,\n\t\t\t\t\t      const pj_uint8_t *payload,\n                                              pj_size_t payload_len,\n                                              pj_uint8_t *bits,\n                                              pj_size_t bits_size,\n\t\t\t\t\t      unsigned *pos)\n{\n    pj_uint8_t P, V, PLEN;\n    const pj_uint8_t *p = payload;\n    pj_uint8_t *q;\n\n    q = bits + *pos;\n\n    /* Check if this is a missing/lost packet */\n    if (payload == NULL) {\n\tpktz->unpack_prev_lost = PJ_TRUE;\n\treturn PJ_SUCCESS;\n    }\n\n    /* H263 payload header size is two octets */\n    if (payload_len < 2) {\n\t/* Invalid bitstream, discard this payload */\n\tpktz->unpack_prev_lost = PJ_TRUE;\n\treturn PJ_EINVAL;\n    }\n\n    /* Reset last sync point for every new picture bitstream */\n    if (*pos == 0)\n\tpktz->unpack_last_sync_pos = 0;\n\n    /* Get payload header info */\n    P = *p & 0x04;\n    V = *p & 0x02;\n    PLEN = ((*p & 0x01) << 5) + ((*(p+1) & 0xF8)>>3);\n\n    /* Get start bitstream pointer */\n    p += 2;\t    /* Skip payload header */\n    if (V)\n        p += 1;\t    /* Skip VRC data */\n    if (PLEN)\n        p += PLEN;  /* Skip extra picture header data */\n\n    /* Get bitstream length */\n    if (payload_len > (pj_size_t)(p - payload)) {\n\tpayload_len -= (p - payload);\n    } else {\n\t/* Invalid bitstream, discard this payload */\n\tpktz->unpack_prev_lost = PJ_TRUE;\n\treturn PJ_EINVAL;\n    }\n\n    /* Validate bitstream length */\n    if (bits_size < *pos + payload_len + 2) {\n\t/* Insufficient bistream buffer, discard this payload */\n\tpj_assert(!\"Insufficient H.263 bitstream buffer\");\n\tpktz->unpack_prev_lost = PJ_TRUE;\n\treturn PJ_ETOOSMALL;\n    }\n\n    /* Start writing bitstream */\n\n    /* No sync point flag */\n    if (!P) {\n\tif (*pos == 0) {\n\t    /* Previous packet must be lost */\n\t    pktz->unpack_prev_lost = PJ_TRUE;\n\n\t    /* If there is extra picture header, let's use it. */\n\t    if (PLEN) {\n\t\t/* Write two zero octets for PSC */\n\t\t*q++ = 0;\n\t\t*q++ = 0;\n\t\t/* Copy the picture header */\n\t\tp -= PLEN;\n\t\tpj_memcpy(q, p, PLEN);\n\t\tp += PLEN;\n\t\tq += PLEN;\n\t    }\n\t} else if (pktz->unpack_prev_lost) {\n\t    /* If prev packet was lost, revert the bitstream pointer to\n\t     * the last sync point.\n\t     */\n\t    pj_assert(pktz->unpack_last_sync_pos <= *pos);\n\t    q = bits + pktz->unpack_last_sync_pos;\n\t}\n\n\t/* There was packet lost, see if this payload contain sync point\n\t * (usable data).\n\t */\n\tif (pktz->unpack_prev_lost) {\n\t    pj_uint8_t *sync;\n\t    sync = find_sync_point((pj_uint8_t*)p, payload_len);\n\t    if (sync) {\n\t\t/* Got sync point, update P/sync-point flag */\n\t\tP = 1;\n\t\t/* Skip the two zero octets */\n\t\tsync += 2;\n\t\t/* Update payload length and start bitstream pointer */\n\t\tpayload_len -= (sync - p);\n\t\tp = sync;\n\t    } else {\n\t\t/* No sync point in it, just discard this payload */\n\t\treturn PJ_EIGNORED;\n\t    }\n\t}\n    }\n\n    /* Write two zero octets when payload flagged with sync point */\n    if (P) {\n\tpktz->unpack_last_sync_pos = (unsigned)(q - bits);\n        *q++ = 0;\n        *q++ = 0;\n    }\n\n    /* Write the payload to the bitstream */\n    pj_memcpy(q, p, payload_len);\n    q += payload_len;\n\n    /* Update the bitstream writing offset */\n    *pos = (unsigned)(q - bits);\n\n    pktz->unpack_prev_lost = PJ_FALSE;\n\n    return PJ_SUCCESS;\n}\n\n\n#endif /* PJMEDIA_HAS_VIDEO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/h264_packetizer.c",
    "content": "/* $Id: h264_packetizer.c 4006 2012-04-02 08:40:54Z nanang $ */\n/* \n * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-codec/h264_packetizer.h>\n#include <pjmedia/types.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n\n#define THIS_FILE\t\t\"h264_packetizer.c\"\n\n#define DBG_PACKETIZE\t\t0\n#define DBG_UNPACKETIZE\t\t0\n\n\n/* H.264 packetizer definition */\nstruct pjmedia_h264_packetizer\n{\n    /* Current settings */\n    pjmedia_h264_packetizer_cfg cfg;\n    \n    /* Unpacketizer state */\n    unsigned\t    unpack_last_sync_pos;\n    pj_bool_t\t    unpack_prev_lost;\n};\n\n\n/* Enumeration of H.264 NAL unit types */\nenum\n{\n    NAL_TYPE_SINGLE_NAL_MIN\t= 1,\n    NAL_TYPE_SINGLE_NAL_MAX\t= 23,\n    NAL_TYPE_STAP_A\t\t= 24,\n    NAL_TYPE_FU_A\t\t= 28,\n};\n\n\n/*\n * Find next NAL unit from the specified H.264 bitstream data.\n */\nstatic pj_uint8_t* find_next_nal_unit(pj_uint8_t *start,\n                                      pj_uint8_t *end)\n{\n    pj_uint8_t *p = start;\n\n    /* Simply lookup \"0x000001\" pattern */\n    while (p <= end-3 && (p[0] || p[1] || p[2]!=1))\n        ++p;\n\n    if (p > end-3)\n\t/* No more NAL unit in this bitstream */\n        return NULL;\n\n    /* Include 8 bits leading zero */\n    if (p>start && *(p-1)==0)\n\treturn (p-1);\n\n    return p;\n}\n\n\n/*\n * Create H264 packetizer.\n */\nPJ_DEF(pj_status_t) pjmedia_h264_packetizer_create(\n\t\t\t\tpj_pool_t *pool,\n\t\t\t\tconst pjmedia_h264_packetizer_cfg *cfg,\n\t\t\t\tpjmedia_h264_packetizer **p)\n{\n    pjmedia_h264_packetizer *p_;\n\n    PJ_ASSERT_RETURN(pool && p, PJ_EINVAL);\n\n    if (cfg &&\n\tcfg->mode != PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED &&\n\tcfg->mode != PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL)\n    {\n\treturn PJ_ENOTSUP;\n    }\n\n    p_ = PJ_POOL_ZALLOC_T(pool, pjmedia_h264_packetizer);\n    if (cfg) {\n\tpj_memcpy(&p_->cfg, cfg, sizeof(*cfg));\n    } else {\n\tp_->cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED;\n\tp_->cfg.mtu = PJMEDIA_MAX_VID_PAYLOAD_SIZE;\n    }\n\n    *p = p_;\n\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Generate an RTP payload from H.264 frame bitstream, in-place processing.\n */\nPJ_DEF(pj_status_t) pjmedia_h264_packetize(pjmedia_h264_packetizer *pktz,\n\t\t\t\t\t   pj_uint8_t *buf,\n                                           pj_size_t buf_len,\n                                           unsigned *pos,\n                                           const pj_uint8_t **payload,\n                                           pj_size_t *payload_len)\n{\n    pj_uint8_t *nal_start = NULL, *nal_end = NULL, *nal_octet = NULL;\n    pj_uint8_t *p, *end;\n    enum { \n\tHEADER_SIZE_FU_A\t     = 2,\n\tHEADER_SIZE_STAP_A\t     = 3,\n    };\n    enum { MAX_NALS_IN_AGGR = 32 };\n\n#if DBG_PACKETIZE\n    if (*pos == 0 && buf_len) {\n\tPJ_LOG(3, (\"h264pack\", \"<< Start packing new frame >>\"));\n    }\n#endif\n\n    p = buf + *pos;\n    end = buf + buf_len;\n\n    /* Find NAL unit startcode */\n    if (end-p >= 4)\n\tnal_start = find_next_nal_unit(p, p+4);\n    if (nal_start) {\n\t/* Get NAL unit octet pointer */\n\twhile (*nal_start++ == 0);\n\tnal_octet = nal_start;\n    } else {\n\t/* This NAL unit is being fragmented */\n\tnal_start = p;\n    }\n\n    /* Get end of NAL unit */\n    p = nal_start+pktz->cfg.mtu+1;\n    if (p > end || pktz->cfg.mode==PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL) \n\tp = end;\n    nal_end = find_next_nal_unit(nal_start, p); \n    if (!nal_end)\n\tnal_end = p;\n\n    /* Validate MTU vs NAL length on single NAL unit packetization */\n    if ((pktz->cfg.mode==PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL) &&\n\tnal_end - nal_start > pktz->cfg.mtu)\n    {\n\t//pj_assert(!\"MTU too small for H.264 single NAL packetization mode\");\n\tPJ_LOG(2,(\"h264_packetizer.c\",\n\t\t  \"MTU too small for H.264 (required=%u, MTU=%u)\",\n\t\t  nal_end - nal_start, pktz->cfg.mtu));\n\treturn PJ_ETOOSMALL;\n    }\n\n    /* Evaluate the proper payload format structure */\n\n    /* Fragmentation (FU-A) packet */\n    if ((pktz->cfg.mode != PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL) &&\n\t(!nal_octet || nal_end-nal_start > pktz->cfg.mtu))\n    {\n\tpj_uint8_t NRI, TYPE;\n\n\tif (nal_octet) {\n\t    /* We have NAL unit octet, so this is the first fragment */\n\t    NRI = (*nal_octet & 0x60) >> 5;\n\t    TYPE = *nal_octet & 0x1F;\n\n\t    /* Skip nal_octet in nal_start to be overriden by FU header */\n\t    ++nal_start;\n\t} else {\n\t    /* Not the first fragment, get NRI and NAL unit type\n\t     * from the previous fragment.\n\t     */\n\t    p = nal_start - pktz->cfg.mtu;\n\t    NRI = (*p & 0x60) >> 5;\n\t    TYPE = *(p+1) & 0x1F;\n\t}\n\n\t/* Init FU indicator (one octet: F+NRI+TYPE) */\n\tp = nal_start - HEADER_SIZE_FU_A;\n\t*p = (NRI << 5) | NAL_TYPE_FU_A;\n\t++p;\n\n\t/* Init FU header (one octed: S+E+R+TYPE) */\n\t*p = TYPE;\n\tif (nal_octet)\n\t    *p |= (1 << 7); /* S bit flag = start of fragmentation */\n\tif (nal_end-nal_start+HEADER_SIZE_FU_A <= pktz->cfg.mtu)\n\t    *p |= (1 << 6); /* E bit flag = end of fragmentation */\n\n\t/* Set payload, payload length */\n\t*payload = nal_start - HEADER_SIZE_FU_A;\n\tif (nal_end-nal_start+HEADER_SIZE_FU_A > pktz->cfg.mtu)\n\t    *payload_len = pktz->cfg.mtu;\n\telse\n\t    *payload_len = nal_end - nal_start + HEADER_SIZE_FU_A;\n\t*pos = (unsigned)(*payload + *payload_len - buf);\n\n#if DBG_PACKETIZE\n\tPJ_LOG(3, (\"h264pack\", \"Packetized fragmented H264 NAL unit \"\n\t\t   \"(pos=%d, type=%d, NRI=%d, S=%d, E=%d, len=%d/%d)\",\n\t\t   *payload-buf, TYPE, NRI, *p>>7, (*p>>6)&1, *payload_len,\n\t\t   buf_len));\n#endif\n\n\treturn PJ_SUCCESS;\n    }\n\n    /* Aggregation (STAP-A) packet */\n    if ((pktz->cfg.mode != PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL) &&\n\t(nal_end != end) &&\n\t(nal_end - nal_start + HEADER_SIZE_STAP_A) < pktz->cfg.mtu) \n    {\n\tint total_size;\n\tunsigned nal_cnt = 1;\n\tpj_uint8_t *nal[MAX_NALS_IN_AGGR];\n\tpj_size_t nal_size[MAX_NALS_IN_AGGR];\n\tpj_uint8_t NRI;\n\n\tpj_assert(nal_octet);\n\n\t/* Init the first NAL unit in the packet */\n\tnal[0] = nal_start;\n\tnal_size[0] = nal_end - nal_start;\n\ttotal_size = (int)nal_size[0] + HEADER_SIZE_STAP_A;\n\tNRI = (*nal_octet & 0x60) >> 5;\n\n\t/* Populate next NAL units */\n\twhile (nal_cnt < MAX_NALS_IN_AGGR) {\n\t    pj_uint8_t *tmp_end;\n\n\t    /* Find start address of the next NAL unit */\n\t    p = nal[nal_cnt-1] + nal_size[nal_cnt-1];\n\t    while (*p++ == 0);\n\t    nal[nal_cnt] = p;\n\n\t    /* Find end address of the next NAL unit */\n\t    tmp_end = p + (pktz->cfg.mtu - total_size);\n\t    if (tmp_end > end)\n\t\ttmp_end = end;\n\t    p = find_next_nal_unit(p+1, tmp_end);\n\t    if (p) {\n\t\tnal_size[nal_cnt] = p - nal[nal_cnt];\n\t    } else {\n\t\tbreak;\n\t    }\n\n\t    /* Update total payload size (2 octet NAL size + NAL) */\n\t    total_size += (2 + (int)nal_size[nal_cnt]);\n\t    if (total_size <= pktz->cfg.mtu) {\n\t\tpj_uint8_t tmp_nri;\n\n\t\t/* Get maximum NRI of the aggregated NAL units */\n\t\ttmp_nri = (*(nal[nal_cnt]-1) & 0x60) >> 5;\n\t\tif (tmp_nri > NRI)\n\t\t    NRI = tmp_nri;\n\t    } else {\n\t\tbreak;\n\t    }\n\n\t    ++nal_cnt;\n\t}\n\n\t/* Only use STAP-A when we found more than one NAL units */\n\tif (nal_cnt > 1) {\n\t    unsigned i;\n\n\t    /* Init STAP-A NAL header (F+NRI+TYPE) */\n\t    p = nal[0] - HEADER_SIZE_STAP_A;\n\t    *p++ = (NRI << 5) | NAL_TYPE_STAP_A;\n\n\t    /* Append all populated NAL units into payload (SIZE+NAL) */\n\t    for (i = 0; i < nal_cnt; ++i) {\n\t\t/* Put size (2 octets in network order) */\n\t\tpj_assert(nal_size[i] <= 0xFFFF);\n\t\t*p++ = (pj_uint8_t)(nal_size[i] >> 8);\n\t\t*p++ = (pj_uint8_t)(nal_size[i] & 0xFF);\n\t\t\n\t\t/* Append NAL unit, watchout memmove()-ing bitstream! */\n\t\tif (p != nal[i])\n\t\t    pj_memmove(p, nal[i], nal_size[i]);\n\t\tp += nal_size[i];\n\t    }\n\n\t    /* Set payload, payload length, and pos */\n\t    *payload = nal[0] - HEADER_SIZE_STAP_A;\n\t    pj_assert(*payload >= buf+*pos);\n\t    *payload_len = p - *payload;\n\t    *pos = (unsigned)(nal[nal_cnt-1] + nal_size[nal_cnt-1] - buf);\n\n#if DBG_PACKETIZE\n\t    PJ_LOG(3, (\"h264pack\", \"Packetized aggregation of \"\n\t\t       \"%d H264 NAL units (pos=%d, NRI=%d len=%d/%d)\",\n\t\t       nal_cnt, *payload-buf, NRI, *payload_len, buf_len));\n#endif\n\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    /* Single NAL unit packet */\n    *payload = nal_start;\n    *payload_len = nal_end - nal_start;\n    *pos = (unsigned)(nal_end - buf);\n\n#if DBG_PACKETIZE\n    PJ_LOG(3, (\"h264pack\", \"Packetized single H264 NAL unit \"\n\t       \"(pos=%d, type=%d, NRI=%d, len=%d/%d)\",\n\t       nal_start-buf, *nal_octet&0x1F, (*nal_octet&0x60)>>5,\n\t       *payload_len, buf_len));\n#endif\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Append RTP payload to a H.264 picture bitstream. Note that the only\n * payload format that cares about packet lost is the NAL unit\n * fragmentation format (FU-A/B), so we will only manage the \"prev_lost\"\n * state for the FU-A/B packets.\n */\nPJ_DEF(pj_status_t) pjmedia_h264_unpacketize(pjmedia_h264_packetizer *pktz,\n\t\t\t\t\t     const pj_uint8_t *payload,\n                                             pj_size_t   payload_len,\n                                             pj_uint8_t *bits,\n                                             pj_size_t   bits_len,\n\t\t\t\t\t     unsigned   *bits_pos)\n{\n    const pj_uint8_t nal_start_code[3] = {0, 0, 1};\n    enum { MIN_PAYLOAD_SIZE = 2 };\n    pj_uint8_t nal_type;\n\n    PJ_UNUSED_ARG(pktz);\n\n#if DBG_UNPACKETIZE\n    if (*bits_pos == 0 && payload_len) {\n\tPJ_LOG(3, (\"h264unpack\", \">> Start unpacking new frame <<\"));\n    }\n#endif\n\n    /* Check if this is a missing/lost packet */\n    if (payload == NULL) {\n\tpktz->unpack_prev_lost = PJ_TRUE;\n\treturn PJ_SUCCESS;\n    }\n\n    /* H264 payload size */\n    if (payload_len < MIN_PAYLOAD_SIZE) {\n\t/* Invalid bitstream, discard this payload */\n\tpktz->unpack_prev_lost = PJ_TRUE;\n\treturn PJ_EINVAL;\n    }\n\n    /* Reset last sync point for every new picture bitstream */\n    if (*bits_pos == 0)\n\tpktz->unpack_last_sync_pos = 0;\n\n    nal_type = *payload & 0x1F;\n    if (nal_type >= NAL_TYPE_SINGLE_NAL_MIN &&\n\tnal_type <= NAL_TYPE_SINGLE_NAL_MAX)\n    {\n\t/* Single NAL unit packet */\n\tpj_uint8_t *p = bits + *bits_pos;\n\n\t/* Validate bitstream length */\n\tif (bits_len-*bits_pos < payload_len+PJ_ARRAY_SIZE(nal_start_code)) {\n\t    /* Insufficient bistream buffer, discard this payload */\n\t    pj_assert(!\"Insufficient H.263 bitstream buffer\");\n\t    return PJ_ETOOSMALL;\n\t}\n\n\t/* Write NAL unit start code */\n\tpj_memcpy(p, &nal_start_code, PJ_ARRAY_SIZE(nal_start_code));\n\tp += PJ_ARRAY_SIZE(nal_start_code);\n\n\t/* Write NAL unit */\n\tpj_memcpy(p, payload, payload_len);\n\tp += payload_len;\n\n\t/* Update the bitstream writing offset */\n\t*bits_pos = (unsigned)(p - bits);\n\tpktz->unpack_last_sync_pos = *bits_pos;\n\n#if DBG_UNPACKETIZE\n\tPJ_LOG(3, (\"h264unpack\", \"Unpacked single H264 NAL unit \"\n\t\t   \"(type=%d, NRI=%d, len=%d)\",\n\t\t   nal_type, (*payload&0x60)>>5, payload_len));\n#endif\n\n    }\n    else if (nal_type == NAL_TYPE_STAP_A)\n    {\n\t/* Aggregation packet */\n\tpj_uint8_t *p, *p_end;\n\tconst pj_uint8_t *q, *q_end;\n\tunsigned cnt = 0;\n\n\t/* Validate bitstream length */\n\tif (bits_len - *bits_pos < payload_len + 32) {\n\t    /* Insufficient bistream buffer, discard this payload */\n\t    pj_assert(!\"Insufficient H.263 bitstream buffer\");\n\t    return PJ_ETOOSMALL;\n\t}\n\n\t/* Fill bitstream */\n\tp = bits + *bits_pos;\n\tp_end = bits + bits_len;\n\tq = payload + 1;\n\tq_end = payload + payload_len;\n\twhile (q < q_end && p < p_end) {\n\t    pj_uint16_t tmp_nal_size;\n\n\t    /* Write NAL unit start code */\n\t    pj_memcpy(p, &nal_start_code, PJ_ARRAY_SIZE(nal_start_code));\n\t    p += PJ_ARRAY_SIZE(nal_start_code);\n\n\t    /* Get NAL unit size */\n\t    tmp_nal_size = (*q << 8) | *(q+1);\n\t    q += 2;\n\t    if (q + tmp_nal_size > q_end) {\n\t\t/* Invalid bitstream, discard the rest of the payload */\n\t\treturn PJ_EINVAL;\n\t    }\n\n\t    /* Write NAL unit */\n\t    pj_memcpy(p, q, tmp_nal_size);\n\t    p += tmp_nal_size;\n\t    q += tmp_nal_size;\n\t    ++cnt;\n\n\t    /* Update the bitstream writing offset */\n\t    *bits_pos = (unsigned)(p - bits);\n\t    pktz->unpack_last_sync_pos = *bits_pos;\n\t}\n\n#if DBG_UNPACKETIZE\n\tPJ_LOG(3, (\"h264unpack\", \"Unpacked %d H264 NAL units (len=%d)\",\n\t\t   cnt, payload_len));\n#endif\n\n    }\n    else if (nal_type == NAL_TYPE_FU_A)\n    {\n\t/* Fragmentation packet */\n\tpj_uint8_t *p;\n\tconst pj_uint8_t *q = payload;\n\tpj_uint8_t NRI, TYPE, S, E;\n\n\tp = bits + *bits_pos;\n\n\t/* Validate bitstream length */\n\tif (bits_len-*bits_pos < payload_len+PJ_ARRAY_SIZE(nal_start_code)) {\n\t    /* Insufficient bistream buffer, drop this packet */\n\t    pj_assert(!\"Insufficient H.263 bitstream buffer\");\n\t    pktz->unpack_prev_lost = PJ_TRUE;\n\t    return PJ_ETOOSMALL;\n\t}\n\n\t/* Get info */\n\tS = *(q+1) & 0x80;    /* Start bit flag\t*/\n\tE = *(q+1) & 0x40;    /* End bit flag\t*/\n\tTYPE = *(q+1) & 0x1f;\n\tNRI = (*q & 0x60) >> 5;\n\n\t/* Fill bitstream */\n\tif (S) {\n\t    /* This is the first part, write NAL unit start code */\n\t    pj_memcpy(p, &nal_start_code, PJ_ARRAY_SIZE(nal_start_code));\n\t    p += PJ_ARRAY_SIZE(nal_start_code);\n\n\t    /* Write NAL unit octet */\n\t    *p++ = (NRI << 5) | TYPE;\n\t} else if (pktz->unpack_prev_lost) {\n\t    /* If prev packet was lost, revert the bitstream pointer to\n\t     * the last sync point.\n\t     */\n\t    pj_assert(pktz->unpack_last_sync_pos <= *bits_pos);\n\t    *bits_pos = pktz->unpack_last_sync_pos;\n\t    /* And discard this payload (and the following fragmentation\n\t     * payloads carrying this same NAL unit.\n\t     */\n\t    return PJ_EIGNORED;\n\t}\n\tq += 2;\n\n\t/* Write NAL unit */\n\tpj_memcpy(p, q, payload_len - 2);\n\tp += (payload_len - 2);\n\n\t/* Update the bitstream writing offset */\n\t*bits_pos = (unsigned)(p - bits);\n\tif (E) {\n\t    /* Update the sync pos only if the end bit flag is set */\n\t    pktz->unpack_last_sync_pos = *bits_pos;\n\t}\n\n#if DBG_UNPACKETIZE\n\tPJ_LOG(3, (\"h264unpack\", \"Unpacked fragmented H264 NAL unit \"\n\t\t   \"(type=%d, NRI=%d, len=%d)\",\n\t\t   TYPE, NRI, payload_len));\n#endif\n\n    } else {\n\t*bits_pos = 0;\n\treturn PJ_ENOTSUP;\n    }\n\n    pktz->unpack_prev_lost = PJ_FALSE;\n\n    return PJ_SUCCESS;\n}\n\n\n#endif /* PJMEDIA_HAS_VIDEO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/ilbc.c",
    "content": "/* $Id: ilbc.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-codec/ilbc.h>\n#include <pjmedia-codec/types.h>\n#include <pjmedia/codec.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/endpoint.h>\n#include <pjmedia/plc.h>\n#include <pjmedia/port.h>\n#include <pjmedia/silencedet.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/os.h>\n\n#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO\n    #include <AudioToolbox/AudioToolbox.h>\n    #define iLBC_Enc_Inst_t AudioConverterRef\n    #define iLBC_Dec_Inst_t AudioConverterRef\n    #define BLOCKL_MAX \t\t1\n#else\n    #include \"../../third_party/ilbc/iLBC_encode.h\"\n    #include \"../../third_party/ilbc/iLBC_decode.h\"\n#endif\n\n/*\n * Only build this file if PJMEDIA_HAS_ILBC_CODEC != 0\n */\n#if defined(PJMEDIA_HAS_ILBC_CODEC) && PJMEDIA_HAS_ILBC_CODEC != 0\n\n\n#define THIS_FILE\t\"ilbc.c\"\n#define CLOCK_RATE\t8000\n#define DEFAULT_MODE\t30\n\n\n/* Prototypes for iLBC factory */\nstatic pj_status_t ilbc_test_alloc(pjmedia_codec_factory *factory, \n\t\t\t\t   const pjmedia_codec_info *id );\nstatic pj_status_t ilbc_default_attr(pjmedia_codec_factory *factory, \n\t\t\t\t     const pjmedia_codec_info *id, \n\t\t\t\t     pjmedia_codec_param *attr );\nstatic pj_status_t ilbc_enum_codecs(pjmedia_codec_factory *factory, \n\t\t\t\t    unsigned *count, \n\t\t\t\t    pjmedia_codec_info codecs[]);\nstatic pj_status_t ilbc_alloc_codec(pjmedia_codec_factory *factory, \n\t\t\t\t    const pjmedia_codec_info *id, \n\t\t\t\t    pjmedia_codec **p_codec);\nstatic pj_status_t ilbc_dealloc_codec(pjmedia_codec_factory *factory, \n\t\t\t\t      pjmedia_codec *codec );\n\n/* Prototypes for iLBC implementation. */\nstatic pj_status_t  ilbc_codec_init(pjmedia_codec *codec, \n\t\t\t\t    pj_pool_t *pool );\nstatic pj_status_t  ilbc_codec_open(pjmedia_codec *codec, \n\t\t\t\t    pjmedia_codec_param *attr );\nstatic pj_status_t  ilbc_codec_close(pjmedia_codec *codec );\nstatic pj_status_t  ilbc_codec_modify(pjmedia_codec *codec, \n\t\t\t\t      const pjmedia_codec_param *attr );\nstatic pj_status_t  ilbc_codec_parse(pjmedia_codec *codec,\n\t\t\t\t     void *pkt,\n\t\t\t\t     pj_size_t pkt_size,\n\t\t\t\t     const pj_timestamp *ts,\n\t\t\t\t     unsigned *frame_cnt,\n\t\t\t\t     pjmedia_frame frames[]);\nstatic pj_status_t  ilbc_codec_encode(pjmedia_codec *codec, \n\t\t\t\t      const struct pjmedia_frame *input,\n\t\t\t\t      unsigned output_buf_len, \n\t\t\t\t      struct pjmedia_frame *output);\nstatic pj_status_t  ilbc_codec_decode(pjmedia_codec *codec, \n\t\t\t\t      const struct pjmedia_frame *input,\n\t\t\t\t      unsigned output_buf_len, \n\t\t\t\t      struct pjmedia_frame *output);\nstatic pj_status_t  ilbc_codec_recover(pjmedia_codec *codec,\n\t\t\t\t       unsigned output_buf_len,\n\t\t\t\t       struct pjmedia_frame *output);\n\n/* Definition for iLBC codec operations. */\nstatic pjmedia_codec_op ilbc_op = \n{\n    &ilbc_codec_init,\n    &ilbc_codec_open,\n    &ilbc_codec_close,\n    &ilbc_codec_modify,\n    &ilbc_codec_parse,\n    &ilbc_codec_encode,\n    &ilbc_codec_decode,\n    &ilbc_codec_recover\n};\n\n/* Definition for iLBC codec factory operations. */\nstatic pjmedia_codec_factory_op ilbc_factory_op =\n{\n    &ilbc_test_alloc,\n    &ilbc_default_attr,\n    &ilbc_enum_codecs,\n    &ilbc_alloc_codec,\n    &ilbc_dealloc_codec,\n    &pjmedia_codec_ilbc_deinit\n};\n\n/* iLBC factory */\nstatic struct ilbc_factory\n{\n    pjmedia_codec_factory    base;\n    pjmedia_endpt\t    *endpt;\n\n    int\t\t\t     mode;\n    int\t\t\t     bps;\n} ilbc_factory;\n\n\n/* iLBC codec private data. */\nstruct ilbc_codec\n{\n    pjmedia_codec\t base;\n    pj_pool_t\t\t*pool;\n    char\t\t obj_name[PJ_MAX_OBJ_NAME];\n    pjmedia_silence_det\t*vad;\n    pj_bool_t\t\t vad_enabled;\n    pj_bool_t\t\t plc_enabled;\n    pj_timestamp\t last_tx;\n\n\n    pj_bool_t\t\t enc_ready;\n    iLBC_Enc_Inst_t\t enc;\n    unsigned\t\t enc_frame_size;\n    unsigned\t\t enc_samples_per_frame;\n    float\t\t enc_block[BLOCKL_MAX];\n\n    pj_bool_t\t\t dec_ready;\n    iLBC_Dec_Inst_t\t dec;\n    unsigned\t\t dec_frame_size;\n    unsigned\t\t dec_samples_per_frame;\n    float\t\t dec_block[BLOCKL_MAX];\n\n#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO\n    unsigned\t\t enc_total_packets;\n    char\t\t *enc_buffer;\n    unsigned\t\t enc_buffer_offset;\n\n    unsigned\t\t dec_total_packets;\n    char\t\t *dec_buffer;\n    unsigned\t\t dec_buffer_offset;\n#endif\n};\n\nstatic pj_str_t STR_MODE = {\"mode\", 4};\n\n/*\n * Initialize and register iLBC codec factory to pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_ilbc_init( pjmedia_endpt *endpt,\n\t\t\t\t\t     int mode )\n{\n    pjmedia_codec_mgr *codec_mgr;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(endpt != NULL, PJ_EINVAL);\n    PJ_ASSERT_RETURN(mode==0 || mode==20 || mode==30, PJ_EINVAL);\n\n    /* Create iLBC codec factory. */\n    ilbc_factory.base.op = &ilbc_factory_op;\n    ilbc_factory.base.factory_data = NULL;\n    ilbc_factory.endpt = endpt;\n\n    if (mode == 0)\n\tmode = DEFAULT_MODE;\n\n    ilbc_factory.mode = mode;\n\n    if (mode == 20) {\n\tilbc_factory.bps = 15200;\t\n    } else {\n\tilbc_factory.bps = 13333;\n    }\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);\n    if (!codec_mgr)\n\treturn PJ_EINVALIDOP;\n\n    /* Register codec factory to endpoint. */\n    status = pjmedia_codec_mgr_register_factory(codec_mgr, \n\t\t\t\t\t\t&ilbc_factory.base);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n\n    /* Done. */\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Unregister iLBC codec factory from pjmedia endpoint and deinitialize\n * the iLBC codec library.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_ilbc_deinit(void)\n{\n    pjmedia_codec_mgr *codec_mgr;\n    pj_status_t status;\n\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(ilbc_factory.endpt);\n    if (!codec_mgr)\n\treturn PJ_EINVALIDOP;\n\n    /* Unregister iLBC codec factory. */\n    status = pjmedia_codec_mgr_unregister_factory(codec_mgr,\n\t\t\t\t\t\t  &ilbc_factory.base);\n    \n    return status;\n}\n\n/* \n * Check if factory can allocate the specified codec. \n */\nstatic pj_status_t ilbc_test_alloc( pjmedia_codec_factory *factory, \n\t\t\t\t   const pjmedia_codec_info *info )\n{\n    const pj_str_t ilbc_tag = { \"iLBC\", 4};\n\n    PJ_UNUSED_ARG(factory);\n    PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL);\n\n\n    /* Type MUST be audio. */\n    if (info->type != PJMEDIA_TYPE_AUDIO)\n\treturn PJMEDIA_CODEC_EUNSUP;\n\n    /* Check encoding name. */\n    if (pj_stricmp(&info->encoding_name, &ilbc_tag) != 0)\n\treturn PJMEDIA_CODEC_EUNSUP;\n\n    /* Check clock-rate */\n    if (info->clock_rate != CLOCK_RATE)\n\treturn PJMEDIA_CODEC_EUNSUP;\n    \n    /* Channel count must be one */\n    if (info->channel_cnt != 1)\n\treturn PJMEDIA_CODEC_EUNSUP;\n\n    /* Yes, this should be iLBC! */\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Generate default attribute.\n */\nstatic pj_status_t ilbc_default_attr (pjmedia_codec_factory *factory, \n\t\t\t\t      const pjmedia_codec_info *id, \n\t\t\t\t      pjmedia_codec_param *attr )\n{\n    PJ_UNUSED_ARG(factory);\n    PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(id);\n    PJ_ASSERT_RETURN(pj_stricmp2(&id->encoding_name, \"iLBC\")==0, PJ_EINVAL);\n\n    pj_bzero(attr, sizeof(pjmedia_codec_param));\n\n    attr->info.clock_rate = CLOCK_RATE;\n    attr->info.channel_cnt = 1;\n    attr->info.avg_bps = ilbc_factory.bps;\n    attr->info.max_bps = 15200;\n    attr->info.pcm_bits_per_sample = 16;\n    attr->info.frm_ptime = (short)ilbc_factory.mode;\n    attr->info.pt = PJMEDIA_RTP_PT_ILBC;\n\n    attr->setting.frm_per_pkt = 1;\n    attr->setting.vad = 1;\n    attr->setting.plc = 1;\n    attr->setting.penh = 1;\n    attr->setting.dec_fmtp.cnt = 1;\n    attr->setting.dec_fmtp.param[0].name = STR_MODE;\n    if (ilbc_factory.mode == 30)\n\tattr->setting.dec_fmtp.param[0].val = pj_str(\"30\");\n    else\n\tattr->setting.dec_fmtp.param[0].val = pj_str(\"20\");\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Enum codecs supported by this factory (i.e. only iLBC!).\n */\nstatic pj_status_t ilbc_enum_codecs(pjmedia_codec_factory *factory, \n\t\t\t\t    unsigned *count, \n\t\t\t\t    pjmedia_codec_info codecs[])\n{\n    PJ_UNUSED_ARG(factory);\n    PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL);\n\n    PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);\n\n    pj_bzero(&codecs[0], sizeof(pjmedia_codec_info));\n\n    codecs[0].encoding_name = pj_str(\"iLBC\");\n    codecs[0].pt = PJMEDIA_RTP_PT_ILBC;\n    codecs[0].type = PJMEDIA_TYPE_AUDIO;\n    codecs[0].clock_rate = 8000;\n    codecs[0].channel_cnt = 1;\n\n    *count = 1;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Allocate a new iLBC codec instance.\n */\nstatic pj_status_t ilbc_alloc_codec(pjmedia_codec_factory *factory, \n\t\t\t\t    const pjmedia_codec_info *id,\n\t\t\t\t    pjmedia_codec **p_codec)\n{\n    pj_pool_t *pool;\n    struct ilbc_codec *codec;\n\n    PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &ilbc_factory.base, PJ_EINVAL);\n\n    pool = pjmedia_endpt_create_pool(ilbc_factory.endpt, \"iLBC%p\",\n\t\t\t\t     2000, 2000);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    codec = PJ_POOL_ZALLOC_T(pool, struct ilbc_codec);\n    codec->base.op = &ilbc_op;\n    codec->base.factory = factory;\n    codec->pool = pool;\n\n    pj_ansi_snprintf(codec->obj_name,  sizeof(codec->obj_name),\n\t\t     \"ilbc%p\", codec);\n\n    *p_codec = &codec->base;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Free codec.\n */\nstatic pj_status_t ilbc_dealloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t      pjmedia_codec *codec )\n{\n    struct ilbc_codec *ilbc_codec;\n\n    PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);\n    PJ_UNUSED_ARG(factory);\n    PJ_ASSERT_RETURN(factory == &ilbc_factory.base, PJ_EINVAL);\n\n    ilbc_codec = (struct ilbc_codec*) codec;\n\n#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO\n    if (ilbc_codec->enc) {\n\tAudioConverterDispose(ilbc_codec->enc);\n\tilbc_codec->enc = NULL;\n    }\n    if (ilbc_codec->dec) {\n\tAudioConverterDispose(ilbc_codec->dec);\n\tilbc_codec->dec = NULL;\n    }\n#endif\n\n    pj_pool_release(ilbc_codec->pool);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Init codec.\n */\nstatic pj_status_t ilbc_codec_init(pjmedia_codec *codec, \n\t\t\t\t   pj_pool_t *pool )\n{\n    PJ_UNUSED_ARG(codec);\n    PJ_UNUSED_ARG(pool);\n    return PJ_SUCCESS;\n}\n\n/*\n * Open codec.\n */\nstatic pj_status_t ilbc_codec_open(pjmedia_codec *codec, \n\t\t\t\t   pjmedia_codec_param *attr )\n{\n    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;\n    pj_status_t status;\n    unsigned i;\n    pj_uint16_t dec_fmtp_mode = DEFAULT_MODE, \n\t\tenc_fmtp_mode = DEFAULT_MODE;\n\n#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO\n    AudioStreamBasicDescription srcFormat, dstFormat;\n    UInt32 size;\n\n    srcFormat.mSampleRate       = attr->info.clock_rate;\n    srcFormat.mFormatID         = kAudioFormatLinearPCM;\n    srcFormat.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger\n\t\t\t\t  | kLinearPCMFormatFlagIsPacked;\n    srcFormat.mBitsPerChannel   = attr->info.pcm_bits_per_sample;\n    srcFormat.mChannelsPerFrame = attr->info.channel_cnt;\n    srcFormat.mBytesPerFrame    = srcFormat.mChannelsPerFrame\n\t                          * srcFormat.mBitsPerChannel >> 3;\n    srcFormat.mFramesPerPacket  = 1;\n    srcFormat.mBytesPerPacket   = srcFormat.mBytesPerFrame *\n\t\t\t\t  srcFormat.mFramesPerPacket;\n\n    memset(&dstFormat, 0, sizeof(dstFormat));\n    dstFormat.mSampleRate \t= attr->info.clock_rate;\n    dstFormat.mFormatID \t= kAudioFormatiLBC;\n    dstFormat.mChannelsPerFrame = attr->info.channel_cnt;\n#endif\n\n    pj_assert(ilbc_codec != NULL);\n    pj_assert(ilbc_codec->enc_ready == PJ_FALSE && \n\t      ilbc_codec->dec_ready == PJ_FALSE);\n\n    /* Get decoder mode */\n    for (i = 0; i < attr->setting.dec_fmtp.cnt; ++i) {\n\tif (pj_stricmp(&attr->setting.dec_fmtp.param[i].name, &STR_MODE) == 0)\n\t{\n\t    dec_fmtp_mode = (pj_uint16_t)\n\t\t\t    pj_strtoul(&attr->setting.dec_fmtp.param[i].val);\n\t    break;\n\t}\n    }\n\n    /* Decoder mode must be set */\n    PJ_ASSERT_RETURN(dec_fmtp_mode == 20 || dec_fmtp_mode == 30, \n\t\t     PJMEDIA_CODEC_EINMODE);\n\n    /* Get encoder mode */\n    for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {\n\tif (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_MODE) == 0)\n\t{\n\t    enc_fmtp_mode = (pj_uint16_t)\n\t\t\t    pj_strtoul(&attr->setting.enc_fmtp.param[i].val);\n\t    break;\n\t}\n    }\n\n    PJ_ASSERT_RETURN(enc_fmtp_mode==20 || enc_fmtp_mode==30, \n\t\t     PJMEDIA_CODEC_EINMODE);\n\n    /* Both sides of a bi-directional session MUST use the same \"mode\" value.\n     * In this point, possible values are only 20 or 30, so when encoder and\n     * decoder modes are not same, just use the default mode, it is 30.\n     */\n    if (enc_fmtp_mode != dec_fmtp_mode) {\n\tenc_fmtp_mode = dec_fmtp_mode = DEFAULT_MODE;\n\tPJ_LOG(4,(ilbc_codec->obj_name, \n\t\t  \"Normalized iLBC encoder and decoder modes to %d\", \n\t\t  DEFAULT_MODE));\n    }\n\n    /* Update some attributes based on negotiated mode. */\n    attr->info.avg_bps = (dec_fmtp_mode == 30? 13333 : 15200);\n    attr->info.frm_ptime = dec_fmtp_mode;\n\n    /* Create encoder */\n#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO\n    dstFormat.mFramesPerPacket  = CLOCK_RATE * enc_fmtp_mode / 1000;\n    dstFormat.mBytesPerPacket   = (enc_fmtp_mode == 20? 38 : 50);\n\n    /* Use AudioFormat API to fill out the rest of the description */\n    size = sizeof(dstFormat);\n    AudioFormatGetProperty(kAudioFormatProperty_FormatInfo,\n \t                   0, NULL, &size, &dstFormat);\n\n    if (AudioConverterNew(&srcFormat, &dstFormat, &ilbc_codec->enc) != noErr)\n\treturn PJMEDIA_CODEC_EFAILED;\n    ilbc_codec->enc_frame_size = (enc_fmtp_mode == 20? 38 : 50);\n#else\n    ilbc_codec->enc_frame_size = initEncode(&ilbc_codec->enc, enc_fmtp_mode);\n#endif\n    ilbc_codec->enc_samples_per_frame = CLOCK_RATE * enc_fmtp_mode / 1000;\n    ilbc_codec->enc_ready = PJ_TRUE;\n\n    /* Create decoder */\n#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO\n    if (AudioConverterNew(&dstFormat, &srcFormat, &ilbc_codec->dec) != noErr)\n\treturn PJMEDIA_CODEC_EFAILED;\n    ilbc_codec->dec_samples_per_frame = CLOCK_RATE * dec_fmtp_mode / 1000;\n#else\n    ilbc_codec->dec_samples_per_frame = initDecode(&ilbc_codec->dec,\n\t\t\t\t\t\t   dec_fmtp_mode,\n\t\t\t\t\t\t   attr->setting.penh);\n#endif\n    ilbc_codec->dec_frame_size = (dec_fmtp_mode == 20? 38 : 50);\n    ilbc_codec->dec_ready = PJ_TRUE;\n\n    /* Save plc flags */\n    ilbc_codec->plc_enabled = (attr->setting.plc != 0);\n\n    /* Create silence detector. */\n    ilbc_codec->vad_enabled = (attr->setting.vad != 0);\n    status = pjmedia_silence_det_create(ilbc_codec->pool, CLOCK_RATE,\n\t\t\t\t\tilbc_codec->enc_samples_per_frame,\n\t\t\t\t\t&ilbc_codec->vad);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Init last_tx (not necessary because of zalloc, but better\n     * be safe in case someone remove zalloc later.\n     */\n    pj_set_timestamp32(&ilbc_codec->last_tx, 0, 0);\n\n    PJ_LOG(4,(ilbc_codec->obj_name, \n\t      \"iLBC codec opened, mode=%d\", dec_fmtp_mode));\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Close codec.\n */\nstatic pj_status_t ilbc_codec_close( pjmedia_codec *codec )\n{\n    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;\n\n    PJ_UNUSED_ARG(codec);\n\n    PJ_LOG(5,(ilbc_codec->obj_name, \"iLBC codec closed\"));\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Modify codec settings.\n */\nstatic pj_status_t  ilbc_codec_modify(pjmedia_codec *codec, \n\t\t\t\t      const pjmedia_codec_param *attr )\n{\n    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;\n\n    ilbc_codec->plc_enabled = (attr->setting.plc != 0);\n    ilbc_codec->vad_enabled = (attr->setting.vad != 0);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get frames in the packet.\n */\nstatic pj_status_t  ilbc_codec_parse( pjmedia_codec *codec,\n\t\t\t\t     void *pkt,\n\t\t\t\t     pj_size_t pkt_size,\n\t\t\t\t     const pj_timestamp *ts,\n\t\t\t\t     unsigned *frame_cnt,\n\t\t\t\t     pjmedia_frame frames[])\n{\n    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;\n    unsigned count;\n\n    PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);\n\n    count = 0;\n    while (pkt_size >= ilbc_codec->dec_frame_size && count < *frame_cnt) {\n\tframes[count].type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframes[count].buf = pkt;\n\tframes[count].size = ilbc_codec->dec_frame_size;\n\tframes[count].timestamp.u64 = ts->u64 + count * \n\t\t\t\t      ilbc_codec->dec_samples_per_frame;\n\n\tpkt = ((char*)pkt) + ilbc_codec->dec_frame_size;\n\tpkt_size -= ilbc_codec->dec_frame_size;\n\n\t++count;\n    }\n\n    *frame_cnt = count;\n    return PJ_SUCCESS;\n}\n\n#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO\nstatic OSStatus encodeDataProc (\n    AudioConverterRef             inAudioConverter,\n    UInt32                        *ioNumberDataPackets,\n    AudioBufferList               *ioData,\n    AudioStreamPacketDescription  **outDataPacketDescription,\n    void                          *inUserData\n)\n{\n    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)inUserData;\n\n    /* Initialize in case of failure */\n    ioData->mBuffers[0].mData = NULL;\n    ioData->mBuffers[0].mDataByteSize = 0;\n\n    if (ilbc_codec->enc_total_packets < *ioNumberDataPackets) {\n\t*ioNumberDataPackets = ilbc_codec->enc_total_packets;\n    }\n\n    if (*ioNumberDataPackets) {\n\tioData->mBuffers[0].mData = ilbc_codec->enc_buffer +\n\t\t\t\t    ilbc_codec->enc_buffer_offset;\n\tioData->mBuffers[0].mDataByteSize = *ioNumberDataPackets *\n\t\t\t\t\t    ilbc_codec->enc_samples_per_frame\n\t\t\t\t\t    << 1;\n\tilbc_codec->enc_buffer_offset += ioData->mBuffers[0].mDataByteSize;\n    }\n\n    ilbc_codec->enc_total_packets -= *ioNumberDataPackets;\n    return noErr;\n}\n\nstatic OSStatus decodeDataProc (\n    AudioConverterRef             inAudioConverter,\n    UInt32                        *ioNumberDataPackets,\n    AudioBufferList               *ioData,\n    AudioStreamPacketDescription  **outDataPacketDescription,\n    void                          *inUserData\n)\n{\n    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)inUserData;\n\n    /* Initialize in case of failure */\n    ioData->mBuffers[0].mData = NULL;\n    ioData->mBuffers[0].mDataByteSize = 0;\n\n    if (ilbc_codec->dec_total_packets < *ioNumberDataPackets) {\n\t*ioNumberDataPackets = ilbc_codec->dec_total_packets;\n    }\n\n    if (*ioNumberDataPackets) {\n\tioData->mBuffers[0].mData = ilbc_codec->dec_buffer +\n\t\t\t\t    ilbc_codec->dec_buffer_offset;\n\tioData->mBuffers[0].mDataByteSize = *ioNumberDataPackets *\n\t\t\t\t\t    ilbc_codec->dec_frame_size;\n\tilbc_codec->dec_buffer_offset += ioData->mBuffers[0].mDataByteSize;\n    }\n\n    ilbc_codec->dec_total_packets -= *ioNumberDataPackets;\n    return noErr;\n}\n#endif\n\n/*\n * Encode frame.\n */\nstatic pj_status_t ilbc_codec_encode(pjmedia_codec *codec, \n\t\t\t\t     const struct pjmedia_frame *input,\n\t\t\t\t     unsigned output_buf_len, \n\t\t\t\t     struct pjmedia_frame *output)\n{\n    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;\n    pj_int16_t *pcm_in;\n    pj_size_t nsamples;\n\n    pj_assert(ilbc_codec && input && output);\n\n    pcm_in = (pj_int16_t*)input->buf;\n    nsamples = input->size >> 1;\n\n    PJ_ASSERT_RETURN(nsamples % ilbc_codec->enc_samples_per_frame == 0, \n\t\t     PJMEDIA_CODEC_EPCMFRMINLEN);\n    PJ_ASSERT_RETURN(output_buf_len >= ilbc_codec->enc_frame_size * nsamples /\n\t\t     ilbc_codec->enc_samples_per_frame,\n\t\t     PJMEDIA_CODEC_EFRMTOOSHORT);\n\n    /* Detect silence */\n    if (ilbc_codec->vad_enabled) {\n\tpj_bool_t is_silence;\n\tpj_int32_t silence_period;\n\n\tsilence_period = pj_timestamp_diff32(&ilbc_codec->last_tx,\n\t\t\t\t\t      &input->timestamp);\n\n\tis_silence = pjmedia_silence_det_detect(ilbc_codec->vad, \n\t\t\t\t\t        (const pj_int16_t*)input->buf,\n\t\t\t\t\t\t(input->size >> 1),\n\t\t\t\t\t\tNULL);\n\tif (is_silence &&\n\t    (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||\n\t     silence_period < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000))\n\t{\n\t    output->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    output->buf = NULL;\n\t    output->size = 0;\n\t    output->timestamp = input->timestamp;\n\t    return PJ_SUCCESS;\n\t} else {\n\t    ilbc_codec->last_tx = input->timestamp;\n\t}\n    }\n\n    /* Encode */\n    output->size = 0;\n    while (nsamples >= ilbc_codec->enc_samples_per_frame) {\n#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO\n        OSStatus err;\n        AudioBufferList theABL;\n        UInt32 npackets = 1;\n        \n        theABL.mNumberBuffers = 1;\n        theABL.mBuffers[0].mNumberChannels = 1;\n        theABL.mBuffers[0].mDataByteSize = output_buf_len;\n        theABL.mBuffers[0].mData = output->buf + output->size;\n        \n        ilbc_codec->enc_total_packets = 1;\n        ilbc_codec->enc_buffer = (char *)input->buf;\n        ilbc_codec->enc_buffer_offset = input->size - (nsamples << 1);\n        \n        err = AudioConverterFillComplexBuffer(ilbc_codec->enc, encodeDataProc,\n                                              ilbc_codec, &npackets,\n                                              &theABL, NULL);\n        if (err == noErr && npackets) {\n            output->size += npackets * ilbc_codec->enc_frame_size;\n        }\n#else\n        unsigned i;\n        \n        /* Convert to float */\n        for (i=0; i<ilbc_codec->enc_samples_per_frame; ++i) {\n            ilbc_codec->enc_block[i] = (float) (*pcm_in++);\n        }\n        \n        iLBC_encode((unsigned char *)output->buf + output->size,\n                    ilbc_codec->enc_block,\n                    &ilbc_codec->enc);\n        \n        output->size += ilbc_codec->enc.no_of_bytes;\n#endif\n\n\tnsamples -= ilbc_codec->enc_samples_per_frame;\n    }\n\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    output->timestamp = input->timestamp;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Decode frame.\n */\nstatic pj_status_t ilbc_codec_decode(pjmedia_codec *codec, \n\t\t\t\t     const struct pjmedia_frame *input,\n\t\t\t\t     unsigned output_buf_len, \n\t\t\t\t     struct pjmedia_frame *output)\n{\n    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;\n#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO\n    UInt32 npackets;\n    OSStatus err;\n    AudioBufferList theABL;\n#else\n    unsigned i;\n#endif\n\n    pj_assert(ilbc_codec != NULL);\n    PJ_ASSERT_RETURN(input && output, PJ_EINVAL);\n\n    if (output_buf_len < (ilbc_codec->dec_samples_per_frame << 1))\n\treturn PJMEDIA_CODEC_EPCMTOOSHORT;\n\n    if (input->size != ilbc_codec->dec_frame_size)\n\treturn PJMEDIA_CODEC_EFRMINLEN;\n\n    /* Decode to temporary buffer */\n#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO\n    npackets = input->size / ilbc_codec->dec_frame_size *\n\t       ilbc_codec->dec_samples_per_frame;\n\n    theABL.mNumberBuffers = 1;\n    theABL.mBuffers[0].mNumberChannels = 1;\n    theABL.mBuffers[0].mDataByteSize = output_buf_len;\n    theABL.mBuffers[0].mData = output->buf;\n\n    ilbc_codec->dec_total_packets = npackets;\n    ilbc_codec->dec_buffer = (char *)input->buf;\n    ilbc_codec->dec_buffer_offset = 0;\n\n    err = AudioConverterFillComplexBuffer(ilbc_codec->dec, decodeDataProc,\n\t\t\t\t\t  ilbc_codec, &npackets,\n\t\t\t\t\t  &theABL, NULL);\n    if (err == noErr) {\n\toutput->size = npackets * (ilbc_codec->dec_samples_per_frame << 1);\n    }\n#else\n    iLBC_decode(ilbc_codec->dec_block, (unsigned char*) input->buf,\n\t\t&ilbc_codec->dec, 1);\n\n    /* Convert decodec samples from float to short */\n    for (i=0; i<ilbc_codec->dec_samples_per_frame; ++i) {\n\t((short*)output->buf)[i] = (short)ilbc_codec->dec_block[i];\n    }\n    output->size = (ilbc_codec->dec_samples_per_frame << 1);\n#endif\n\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    output->timestamp = input->timestamp;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Recover lost frame.\n */\nstatic pj_status_t  ilbc_codec_recover(pjmedia_codec *codec,\n\t\t\t\t      unsigned output_buf_len,\n\t\t\t\t      struct pjmedia_frame *output)\n{\n    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;\n#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO\n    UInt32 npackets;\n    OSStatus err;\n    AudioBufferList theABL;\n#else\n    unsigned i;\n#endif\n\n    pj_assert(ilbc_codec != NULL);\n    PJ_ASSERT_RETURN(output, PJ_EINVAL);\n\n    if (output_buf_len < (ilbc_codec->dec_samples_per_frame << 1))\n\treturn PJMEDIA_CODEC_EPCMTOOSHORT;\n\n    /* Decode to temporary buffer */\n#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO\n    npackets = 1;\n\n    theABL.mNumberBuffers = 1;\n    theABL.mBuffers[0].mNumberChannels = 1;\n    theABL.mBuffers[0].mDataByteSize = output_buf_len;\n    theABL.mBuffers[0].mData = output->buf;\n\n    ilbc_codec->dec_total_packets = npackets;\n    ilbc_codec->dec_buffer_offset = 0;\n    if (ilbc_codec->dec_buffer) {\n\terr = AudioConverterFillComplexBuffer(ilbc_codec->dec, decodeDataProc,\n\t\t\t\t\t      ilbc_codec, &npackets,\n\t\t\t\t\t      &theABL, NULL);\n\tif (err == noErr) {\n\t    output->size = npackets *\n\t\t           (ilbc_codec->dec_samples_per_frame << 1);\n\t}\n    } else {\n\toutput->size = npackets * (ilbc_codec->dec_samples_per_frame << 1);\n\tpj_bzero(output->buf, output->size);\n    }\n#else\n    iLBC_decode(ilbc_codec->dec_block, NULL, &ilbc_codec->dec, 0);\n\n    /* Convert decodec samples from float to short */\n    for (i=0; i<ilbc_codec->dec_samples_per_frame; ++i) {\n\t((short*)output->buf)[i] = (short)ilbc_codec->dec_block[i];\n    }\n    output->size = (ilbc_codec->dec_samples_per_frame << 1);\n#endif\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\n    return PJ_SUCCESS;\n}\n\n\n#endif\t/* PJMEDIA_HAS_ILBC_CODEC */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/openh264.cpp",
    "content": "/* $Id$ */\n/* \n * Copyright (C)2014 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-codec/openh264.h>\n#include <pjmedia-codec/h264_packetizer.h>\n#include <pjmedia/vid_codec_util.h>\n#include <pjmedia/errno.h>\n#include <pj/log.h>\n\n#if defined(PJMEDIA_HAS_OPENH264_CODEC) && \\\n            PJMEDIA_HAS_OPENH264_CODEC != 0 && \\\n    defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n#ifdef _MSC_VER\n#   include <stdint.h>\n#   pragma comment( lib, \"openh264.lib\")\n#endif\n\n/* OpenH264: */\n#include <wels/codec_api.h>\n#include <wels/codec_app_def.h>\n\n/*\n * Constants\n */\n#define THIS_FILE\t\t\"openh264.cpp\"\n\n#if (defined(PJ_DARWINOS) && PJ_DARWINOS != 0 && TARGET_OS_IPHONE) || \\\n     defined(__ANDROID__)\n#  define DEFAULT_WIDTH\t\t352\n#  define DEFAULT_HEIGHT\t288\n#else\n#  define DEFAULT_WIDTH\t\t720\n#  define DEFAULT_HEIGHT\t480\n#endif\n\n#define DEFAULT_FPS\t\t15\n#define DEFAULT_AVG_BITRATE\t256000\n#define DEFAULT_MAX_BITRATE\t256000\n\n#define MAX_RX_WIDTH\t\t1200\n#define MAX_RX_HEIGHT\t\t800\n\n\n/*\n * Factory operations.\n */\nstatic pj_status_t oh264_test_alloc(pjmedia_vid_codec_factory *factory,\n                                    const pjmedia_vid_codec_info *info );\nstatic pj_status_t oh264_default_attr(pjmedia_vid_codec_factory *factory,\n                                      const pjmedia_vid_codec_info *info,\n                                      pjmedia_vid_codec_param *attr );\nstatic pj_status_t oh264_enum_info(pjmedia_vid_codec_factory *factory,\n                                   unsigned *count,\n                                   pjmedia_vid_codec_info codecs[]);\nstatic pj_status_t oh264_alloc_codec(pjmedia_vid_codec_factory *factory,\n                                     const pjmedia_vid_codec_info *info,\n                                     pjmedia_vid_codec **p_codec);\nstatic pj_status_t oh264_dealloc_codec(pjmedia_vid_codec_factory *factory,\n                                       pjmedia_vid_codec *codec );\n\n\n/*\n * Codec operations\n */\nstatic pj_status_t oh264_codec_init(pjmedia_vid_codec *codec,\n                                    pj_pool_t *pool );\nstatic pj_status_t oh264_codec_open(pjmedia_vid_codec *codec,\n                                    pjmedia_vid_codec_param *param );\nstatic pj_status_t oh264_codec_close(pjmedia_vid_codec *codec);\nstatic pj_status_t oh264_codec_modify(pjmedia_vid_codec *codec,\n                                      const pjmedia_vid_codec_param *param);\nstatic pj_status_t oh264_codec_get_param(pjmedia_vid_codec *codec,\n                                         pjmedia_vid_codec_param *param);\nstatic pj_status_t oh264_codec_encode_begin(pjmedia_vid_codec *codec,\n                                            const pjmedia_vid_encode_opt *opt,\n                                            const pjmedia_frame *input,\n                                            unsigned out_size,\n                                            pjmedia_frame *output,\n                                            pj_bool_t *has_more);\nstatic pj_status_t oh264_codec_encode_more(pjmedia_vid_codec *codec,\n                                           unsigned out_size,\n                                           pjmedia_frame *output,\n                                           pj_bool_t *has_more);\nstatic pj_status_t oh264_codec_decode(pjmedia_vid_codec *codec,\n                                      pj_size_t count,\n                                      pjmedia_frame packets[],\n                                      unsigned out_size,\n                                      pjmedia_frame *output);\n\n/* Definition for OpenH264 codecs operations. */\nstatic pjmedia_vid_codec_op oh264_codec_op =\n{\n    &oh264_codec_init,\n    &oh264_codec_open,\n    &oh264_codec_close,\n    &oh264_codec_modify,\n    &oh264_codec_get_param,\n    &oh264_codec_encode_begin,\n    &oh264_codec_encode_more,\n    &oh264_codec_decode,\n    NULL\n};\n\n/* Definition for OpenH264 codecs factory operations. */\nstatic pjmedia_vid_codec_factory_op oh264_factory_op =\n{\n    &oh264_test_alloc,\n    &oh264_default_attr,\n    &oh264_enum_info,\n    &oh264_alloc_codec,\n    &oh264_dealloc_codec\n};\n\n\nstatic struct oh264_factory\n{\n    pjmedia_vid_codec_factory    base;\n    pjmedia_vid_codec_mgr\t*mgr;\n    pj_pool_factory             *pf;\n    pj_pool_t\t\t        *pool;\n} oh264_factory;\n\n\ntypedef struct oh264_codec_data\n{\n    pj_pool_t\t\t\t*pool;\n    pjmedia_vid_codec_param\t*prm;\n    pj_bool_t\t\t\t whole;\n    pjmedia_h264_packetizer\t*pktz;\n\n    /* Encoder state */\n    ISVCEncoder\t\t\t*enc;\n    SSourcePicture\t\t*esrc_pic;\n    unsigned\t\t \t enc_input_size;\n    pj_uint8_t\t\t\t*enc_frame_whole;\n    unsigned\t\t\t enc_frame_size;\n    unsigned\t\t\t enc_processed;\n    pj_timestamp\t\t ets;\n    SFrameBSInfo\t\t bsi;\n    int\t\t\t \t ilayer;\n\n    /* Decoder state */\n    ISVCDecoder\t\t\t*dec;\n    pj_uint8_t\t\t\t*dec_buf;\n    unsigned\t\t\t dec_buf_size;\n} oh264_codec_data;\n\nstruct SLayerPEncCtx\n{\n    pj_int32_t\t\t\tiDLayerQp;\n    SSliceArgument\t\tsSliceArgument;\n};\n\nPJ_DEF(pj_status_t) pjmedia_codec_openh264_vid_init(pjmedia_vid_codec_mgr *mgr,\n                                                    pj_pool_factory *pf)\n{\n    const pj_str_t h264_name = { (char*)\"H264\", 4};\n    pj_status_t status;\n\n    if (oh264_factory.pool != NULL) {\n\t/* Already initialized. */\n\treturn PJ_SUCCESS;\n    }\n\n    if (!mgr) mgr = pjmedia_vid_codec_mgr_instance();\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    /* Create OpenH264 codec factory. */\n    oh264_factory.base.op = &oh264_factory_op;\n    oh264_factory.base.factory_data = NULL;\n    oh264_factory.mgr = mgr;\n    oh264_factory.pf = pf;\n    oh264_factory.pool = pj_pool_create(pf, \"oh264factory\", 256, 256, NULL);\n    if (!oh264_factory.pool)\n\treturn PJ_ENOMEM;\n\n    /* Registering format match for SDP negotiation */\n    status = pjmedia_sdp_neg_register_fmt_match_cb(\n\t\t\t\t\t&h264_name,\n\t\t\t\t\t&pjmedia_vid_codec_h264_match_sdp);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Register codec factory to codec manager. */\n    status = pjmedia_vid_codec_mgr_register_factory(mgr,\n\t\t\t\t\t\t    &oh264_factory.base);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    PJ_LOG(4,(THIS_FILE, \"OpenH264 codec initialized\"));\n\n    /* Done. */\n    return PJ_SUCCESS;\n\non_error:\n    pj_pool_release(oh264_factory.pool);\n    oh264_factory.pool = NULL;\n    return status;\n}\n\n/*\n * Unregister OpenH264 codecs factory from pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_openh264_vid_deinit(void)\n{\n    pj_status_t status = PJ_SUCCESS;\n\n    if (oh264_factory.pool == NULL) {\n\t/* Already deinitialized */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Unregister OpenH264 codecs factory. */\n    status = pjmedia_vid_codec_mgr_unregister_factory(oh264_factory.mgr,\n\t\t\t\t\t\t      &oh264_factory.base);\n\n    /* Destroy pool. */\n    pj_pool_release(oh264_factory.pool);\n    oh264_factory.pool = NULL;\n\n    return status;\n}\n\nstatic pj_status_t oh264_test_alloc(pjmedia_vid_codec_factory *factory,\n                                    const pjmedia_vid_codec_info *info )\n{\n    PJ_ASSERT_RETURN(factory == &oh264_factory.base, PJ_EINVAL);\n\n    if (info->fmt_id == PJMEDIA_FORMAT_H264 &&\n\tinfo->pt != 0)\n    {\n\treturn PJ_SUCCESS;\n    }\n\n    return PJMEDIA_CODEC_EUNSUP;\n}\n\nstatic pj_status_t oh264_default_attr(pjmedia_vid_codec_factory *factory,\n                                      const pjmedia_vid_codec_info *info,\n                                      pjmedia_vid_codec_param *attr )\n{\n    PJ_ASSERT_RETURN(factory == &oh264_factory.base, PJ_EINVAL);\n    PJ_ASSERT_RETURN(info && attr, PJ_EINVAL);\n\n    pj_bzero(attr, sizeof(pjmedia_vid_codec_param));\n\n    attr->dir = PJMEDIA_DIR_ENCODING_DECODING;\n    attr->packing = PJMEDIA_VID_PACKING_PACKETS;\n\n    /* Encoded format */\n    pjmedia_format_init_video(&attr->enc_fmt, PJMEDIA_FORMAT_H264,\n                              DEFAULT_WIDTH, DEFAULT_HEIGHT,\n\t\t\t      DEFAULT_FPS, 1);\n\n    /* Decoded format */\n    pjmedia_format_init_video(&attr->dec_fmt, PJMEDIA_FORMAT_I420,\n                              DEFAULT_WIDTH, DEFAULT_HEIGHT,\n\t\t\t      DEFAULT_FPS, 1);\n\n    /* Decoding fmtp */\n    attr->dec_fmtp.cnt = 2;\n    attr->dec_fmtp.param[0].name = pj_str((char*)\"profile-level-id\");\n    attr->dec_fmtp.param[0].val = pj_str((char*)\"42e01e\");\n    attr->dec_fmtp.param[1].name = pj_str((char*)\" packetization-mode\");\n    attr->dec_fmtp.param[1].val = pj_str((char*)\"1\");\n\n    /* Bitrate */\n    attr->enc_fmt.det.vid.avg_bps = DEFAULT_AVG_BITRATE;\n    attr->enc_fmt.det.vid.max_bps = DEFAULT_MAX_BITRATE;\n\n    /* Encoding MTU */\n    attr->enc_mtu = PJMEDIA_MAX_VID_PAYLOAD_SIZE;\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t oh264_enum_info(pjmedia_vid_codec_factory *factory,\n                                   unsigned *count,\n                                   pjmedia_vid_codec_info info[])\n{\n    PJ_ASSERT_RETURN(info && *count > 0, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &oh264_factory.base, PJ_EINVAL);\n\n    *count = 1;\n    info->fmt_id = PJMEDIA_FORMAT_H264;\n    info->pt = PJMEDIA_RTP_PT_H264;\n    info->encoding_name = pj_str((char*)\"H264\");\n    info->encoding_desc = pj_str((char*)\"OpenH264 codec\");\n    info->clock_rate = 90000;\n    info->dir = PJMEDIA_DIR_ENCODING_DECODING;\n    info->dec_fmt_id_cnt = 1;\n    info->dec_fmt_id[0] = PJMEDIA_FORMAT_I420;\n    info->packings = PJMEDIA_VID_PACKING_PACKETS |\n\t\t     PJMEDIA_VID_PACKING_WHOLE;\n    info->fps_cnt = 3;\n    info->fps[0].num = 15;\n    info->fps[0].denum = 1;\n    info->fps[1].num = 25;\n    info->fps[1].denum = 1;\n    info->fps[2].num = 30;\n    info->fps[2].denum = 1;\n\n    return PJ_SUCCESS;\n\n}\n\nstatic pj_status_t oh264_alloc_codec(pjmedia_vid_codec_factory *factory,\n                                     const pjmedia_vid_codec_info *info,\n                                     pjmedia_vid_codec **p_codec)\n{\n    pj_pool_t *pool;\n    pjmedia_vid_codec *codec;\n    oh264_codec_data *oh264_data;\n    int rc;\n\n    PJ_ASSERT_RETURN(factory == &oh264_factory.base && info && p_codec,\n                     PJ_EINVAL);\n\n    *p_codec = NULL;\n\n    pool = pj_pool_create(oh264_factory.pf, \"oh264%p\", 512, 512, NULL);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    /* codec instance */\n    codec = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_codec);\n    codec->factory = factory;\n    codec->op = &oh264_codec_op;\n\n    /* codec data */\n    oh264_data = PJ_POOL_ZALLOC_T(pool, oh264_codec_data);\n    oh264_data->pool = pool;\n    codec->codec_data = oh264_data;\n\n    /* encoder allocation */\n    rc = WelsCreateSVCEncoder(&oh264_data->enc);\n    if (rc != 0)\n\tgoto on_error;\n\n    oh264_data->esrc_pic = PJ_POOL_ZALLOC_T(pool, SSourcePicture);\n\n    /* decoder allocation */\n    rc = WelsCreateDecoder(&oh264_data->dec);\n    if (rc != 0)\n\tgoto on_error;\n\n    *p_codec = codec;\n    return PJ_SUCCESS;\n\non_error:\n    oh264_dealloc_codec(factory, codec);\n    return PJMEDIA_CODEC_EFAILED;\n}\n\nstatic pj_status_t oh264_dealloc_codec(pjmedia_vid_codec_factory *factory,\n                                       pjmedia_vid_codec *codec )\n{\n    oh264_codec_data *oh264_data;\n\n    PJ_ASSERT_RETURN(codec, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(factory);\n\n    oh264_data = (oh264_codec_data*) codec->codec_data;\n    if (oh264_data->enc) {\n\tWelsDestroySVCEncoder(oh264_data->enc);\n\toh264_data->enc = NULL;\n    }\n    if (oh264_data->dec) {\n\toh264_data->dec->Uninitialize();\n    \tWelsDestroyDecoder(oh264_data->dec);\n    \toh264_data->dec = NULL;\n    }\n    pj_pool_release(oh264_data->pool);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t oh264_codec_init(pjmedia_vid_codec *codec,\n                                    pj_pool_t *pool )\n{\n    PJ_ASSERT_RETURN(codec && pool, PJ_EINVAL);\n    PJ_UNUSED_ARG(codec);\n    PJ_UNUSED_ARG(pool);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t oh264_codec_open(pjmedia_vid_codec *codec,\n                                    pjmedia_vid_codec_param *codec_param )\n{\n    oh264_codec_data \t*oh264_data;\n    pjmedia_vid_codec_param\t*param;\n    pjmedia_h264_packetizer_cfg  pktz_cfg;\n    pjmedia_vid_codec_h264_fmtp  h264_fmtp;\n    SEncParamExt\t eprm;\n    SSpatialLayerConfig *elayer = &eprm.sSpatialLayers[0];\n    SLayerPEncCtx\t elayer_ctx;\n    SDecodingParam\t sDecParam = {0};\n    int \t\t rc;\n    pj_status_t\t\t status;\n\n    PJ_ASSERT_RETURN(codec && codec_param, PJ_EINVAL);\n\n    PJ_LOG(5,(THIS_FILE, \"Opening codec..\"));\n\n    oh264_data = (oh264_codec_data*) codec->codec_data;\n    oh264_data->prm = pjmedia_vid_codec_param_clone( oh264_data->pool,\n                                                     codec_param);\n    param = oh264_data->prm;\n\n    /* Parse remote fmtp */\n    pj_bzero(&h264_fmtp, sizeof(h264_fmtp));\n    status = pjmedia_vid_codec_h264_parse_fmtp(&param->enc_fmtp, &h264_fmtp);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Apply SDP fmtp to format in codec param */\n    if (!param->ignore_fmtp) {\n\tstatus = pjmedia_vid_codec_h264_apply_fmtp(param);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    pj_bzero(&pktz_cfg, sizeof(pktz_cfg));\n    pktz_cfg.mtu = param->enc_mtu;\n    /* Packetization mode */\n#if 0\n    if (h264_fmtp.packetization_mode == 0)\n\tpktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL;\n    else if (h264_fmtp.packetization_mode == 1)\n\tpktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED;\n    else\n\treturn PJ_ENOTSUP;\n#else\n    if (h264_fmtp.packetization_mode!=\n\t\t\t\tPJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL &&\n\th264_fmtp.packetization_mode!=\n\t\t\t\tPJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED)\n    {\n\treturn PJ_ENOTSUP;\n    }\n    /* Better always send in single NAL mode for better compatibility */\n    pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL;\n#endif\n\n    status = pjmedia_h264_packetizer_create(oh264_data->pool, &pktz_cfg,\n                                            &oh264_data->pktz);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    oh264_data->whole = (param->packing == PJMEDIA_VID_PACKING_WHOLE);\n\n    /*\n     * Encoder\n     */\n\n    /* Init encoder parameters */\n    oh264_data->enc->GetDefaultParams (&eprm);\n    eprm.iComplexityMode    \t\t= MEDIUM_COMPLEXITY;\n    eprm.sSpatialLayers[0].uiProfileIdc\t= PRO_BASELINE;\n    eprm.iPicWidth\t\t\t= param->enc_fmt.det.vid.size.w;\n    eprm.iUsageType         \t\t= CAMERA_VIDEO_REAL_TIME;\n    eprm.iPicHeight\t\t\t= param->enc_fmt.det.vid.size.h;\n    eprm.fMaxFrameRate\t\t\t= (param->enc_fmt.det.vid.fps.num *\n\t\t\t\t\t   1.0f /\n\t\t\t\t\t   param->enc_fmt.det.vid.fps.denum);\n    eprm.iTemporalLayerNum\t\t= 1;\n    eprm.uiIntraPeriod\t\t\t= 0; /* I-Frame interval in frames */\n    eprm.eSpsPpsIdStrategy      \t= (oh264_data->whole ? CONSTANT_ID :\n        INCREASING_ID);\n    eprm.bEnableFrameCroppingFlag\t= true;\n    eprm.iLoopFilterDisableIdc\t\t= 0;\n    eprm.iLoopFilterAlphaC0Offset\t= 0;\n    eprm.iLoopFilterBetaOffset\t\t= 0;\n    eprm.iMultipleThreadIdc\t\t= 1;\n    //eprm.bEnableRc\t\t\t= 1;\n    eprm.iTargetBitrate\t\t\t= param->enc_fmt.det.vid.avg_bps;\n    eprm.bEnableFrameSkip\t\t= 1;\n    eprm.bEnableDenoise\t\t\t= 0;\n    eprm.bEnableSceneChangeDetect\t= 1;\n    eprm.bEnableBackgroundDetection\t= 1;\n    eprm.bEnableAdaptiveQuant\t\t= 1;\n    eprm.bEnableLongTermReference\t= 0;\n    eprm.iLtrMarkPeriod\t\t\t= 30;\n    eprm.bPrefixNalAddingCtrl\t\t= false;\n    eprm.iSpatialLayerNum\t\t= 1;\n    if (!oh264_data->whole) {\n\teprm.uiMaxNalSize\t\t\t= param->enc_mtu;\n    }\n\n    pj_bzero(&elayer_ctx, sizeof (SLayerPEncCtx));\n    elayer_ctx.iDLayerQp\t\t= 24;\n    elayer_ctx.sSliceArgument.uiSliceMode = (oh264_data->whole ?\n                                             SM_SINGLE_SLICE :\n                                             SM_SIZELIMITED_SLICE);\n    elayer_ctx.sSliceArgument.uiSliceSizeConstraint = param->enc_mtu;\n    elayer_ctx.sSliceArgument.uiSliceNum      = 1;\n    elayer_ctx.sSliceArgument.uiSliceMbNum[0] = 960;\n    elayer_ctx.sSliceArgument.uiSliceMbNum[1] = 0;\n    elayer_ctx.sSliceArgument.uiSliceMbNum[2] = 0;\n    elayer_ctx.sSliceArgument.uiSliceMbNum[3] = 0;\n    elayer_ctx.sSliceArgument.uiSliceMbNum[4] = 0;\n    elayer_ctx.sSliceArgument.uiSliceMbNum[5] = 0;\n    elayer_ctx.sSliceArgument.uiSliceMbNum[6] = 0;\n    elayer_ctx.sSliceArgument.uiSliceMbNum[7] = 0;\n\n    elayer->iVideoWidth\t\t\t= eprm.iPicWidth;\n    elayer->iVideoHeight\t\t= eprm.iPicHeight;\n    elayer->fFrameRate\t\t\t= eprm.fMaxFrameRate;\n    elayer->uiProfileIdc\t\t= eprm.sSpatialLayers[0].uiProfileIdc;\n    elayer->iSpatialBitrate\t\t= eprm.iTargetBitrate;\n    elayer->iDLayerQp\t\t\t= elayer_ctx.iDLayerQp;\n    elayer->sSliceArgument.uiSliceMode = elayer_ctx.sSliceArgument.uiSliceMode;\n\n    memcpy ( &elayer->sSliceArgument,\n             &elayer_ctx.sSliceArgument,\n             sizeof (SSliceArgument));\n    memcpy ( &elayer->sSliceArgument.uiSliceMbNum[0],\n             &elayer_ctx.sSliceArgument.uiSliceMbNum[0],\n             sizeof (elayer_ctx.sSliceArgument.uiSliceMbNum));\n\n    /* Init input picture */\n    oh264_data->esrc_pic->iColorFormat\t= videoFormatI420;\n    oh264_data->esrc_pic->uiTimeStamp\t= 0;\n    oh264_data->esrc_pic->iPicWidth\t= eprm.iPicWidth;\n    oh264_data->esrc_pic->iPicHeight\t= eprm.iPicHeight;\n    oh264_data->esrc_pic->iStride[0] \t= oh264_data->esrc_pic->iPicWidth;\n    oh264_data->esrc_pic->iStride[1]\t=\n\t    oh264_data->esrc_pic->iStride[2] =\n\t\t\t\t\t  oh264_data->esrc_pic->iStride[0]>>1;\n\n    oh264_data->enc_input_size = oh264_data->esrc_pic->iPicWidth *\n\t\t\t\t oh264_data->esrc_pic->iPicHeight * 3 >> 1;\n\n    /* Initialize encoder */\n    rc = oh264_data->enc->InitializeExt (&eprm);\n    if (rc != cmResultSuccess) {\n\tPJ_LOG(4,(THIS_FILE, \"SVC encoder Initialize failed, rc=%d\", rc));\n\treturn PJMEDIA_CODEC_EFAILED;\n    }\n\n    int videoFormat = videoFormatI420;\n    rc = oh264_data->enc->SetOption (ENCODER_OPTION_DATAFORMAT, &videoFormat);\n    if (rc != cmResultSuccess) {\n      PJ_LOG(4,(THIS_FILE, \"SVC encoder SetOption videoFormatI420 failed, \"\n            \"rc=%d\", rc));\n      return PJMEDIA_CODEC_EFAILED;\n    }\n\n    /*\n     * Decoder\n     */\n    sDecParam.sVideoProperty.size\t= sizeof (sDecParam.sVideoProperty);\n    sDecParam.uiTargetDqLayer\t\t= (pj_uint8_t) - 1;\n    sDecParam.eEcActiveIdc          \t= ERROR_CON_SLICE_COPY;\n    sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;\n\n    //TODO:\n    // Apply \"sprop-parameter-sets\" here\n\n    rc = WelsCreateDecoder(&oh264_data->dec);\n    if (rc) {\n\tPJ_LOG(4,(THIS_FILE, \"Unable to create OpenH264 decoder\"));\n\treturn PJMEDIA_CODEC_EFAILED;\n    }\n\n    rc = oh264_data->dec->Initialize (&sDecParam);\n    if (rc) {\n\tPJ_LOG(4,(THIS_FILE, \"Decoder initialization failed, rc=%d\", rc));\n\treturn PJMEDIA_CODEC_EFAILED;\n    }\n\n    oh264_data->dec_buf_size = (MAX_RX_WIDTH * MAX_RX_HEIGHT * 3 >> 1) +\n\t\t\t       (MAX_RX_WIDTH);\n    oh264_data->dec_buf = (pj_uint8_t*)pj_pool_alloc(oh264_data->pool,\n                                                     oh264_data->dec_buf_size);\n\n    /* Need to update param back after values are negotiated */\n    pj_memcpy(codec_param, param, sizeof(*codec_param));\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t oh264_codec_close(pjmedia_vid_codec *codec)\n{\n    PJ_ASSERT_RETURN(codec, PJ_EINVAL);\n    PJ_UNUSED_ARG(codec);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t oh264_codec_modify(pjmedia_vid_codec *codec,\n                                      const pjmedia_vid_codec_param *param)\n{\n    PJ_ASSERT_RETURN(codec && param, PJ_EINVAL);\n    PJ_UNUSED_ARG(codec);\n    PJ_UNUSED_ARG(param);\n    return PJ_EINVALIDOP;\n}\n\nstatic pj_status_t oh264_codec_get_param(pjmedia_vid_codec *codec,\n                                         pjmedia_vid_codec_param *param)\n{\n    struct oh264_codec_data *oh264_data;\n\n    PJ_ASSERT_RETURN(codec && param, PJ_EINVAL);\n\n    oh264_data = (oh264_codec_data*) codec->codec_data;\n    pj_memcpy(param, oh264_data->prm, sizeof(*param));\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t oh264_codec_encode_begin(pjmedia_vid_codec *codec,\n                                            const pjmedia_vid_encode_opt *opt,\n                                            const pjmedia_frame *input,\n                                            unsigned out_size,\n                                            pjmedia_frame *output,\n                                            pj_bool_t *has_more)\n{\n    struct oh264_codec_data *oh264_data;\n    int rc;\n\n    PJ_ASSERT_RETURN(codec && input && out_size && output && has_more,\n                     PJ_EINVAL);\n\n    oh264_data = (oh264_codec_data*) codec->codec_data;\n\n    PJ_ASSERT_RETURN(input->size == oh264_data->enc_input_size,\n                     PJMEDIA_CODEC_EFRMINLEN);\n\n    if (opt && opt->force_keyframe) {\n\toh264_data->enc->ForceIntraFrame(true);\n    }\n\n    oh264_data->esrc_pic->pData[0] = (pj_uint8_t*)input->buf;\n    oh264_data->esrc_pic->pData[1] = oh264_data->esrc_pic->pData[0] +\n\t\t\t\t\t(oh264_data->esrc_pic->iPicWidth *\n\t\t\t\t\t oh264_data->esrc_pic->iPicHeight);\n    oh264_data->esrc_pic->pData[2] = oh264_data->esrc_pic->pData[1] +\n\t\t\t\t\t(oh264_data->esrc_pic->iPicWidth *\n\t\t\t\t\t oh264_data->esrc_pic->iPicHeight >>2);\n\n    pj_memset (&oh264_data->bsi, 0, sizeof (SFrameBSInfo));\n    rc = oh264_data->enc->EncodeFrame( oh264_data->esrc_pic, &oh264_data->bsi);\n    if (rc != cmResultSuccess) {\n\tPJ_LOG(5,(THIS_FILE, \"EncodeFrame() error, ret: %d\", rc));\n\treturn PJMEDIA_CODEC_EFAILED;\n    }\n\n    if (oh264_data->bsi.eFrameType == videoFrameTypeSkip) {\n\toutput->size = 0;\n\toutput->type = PJMEDIA_FRAME_TYPE_NONE;\n\toutput->timestamp = input->timestamp;\n\treturn PJ_SUCCESS;\n    }\n\n    oh264_data->ets = input->timestamp;\n    oh264_data->ilayer = 0;\n    oh264_data->enc_frame_size = oh264_data->enc_processed = 0;\n\n    if (oh264_data->whole) {\n\tSLayerBSInfo* pLayerBsInfo;\n\tpj_uint8_t *payload;\n\tunsigned i, payload_size = 0;\n\n\t*has_more = PJ_FALSE;\n\n\t/* Find which layer with biggest payload */\n\toh264_data->ilayer = 0;\n        payload_size = oh264_data->bsi.sLayerInfo[0].pNalLengthInByte[0];\n\tfor (i=0; i < (unsigned)oh264_data->bsi.iLayerNum; ++i) {\n\t    unsigned j;\n\t    pLayerBsInfo = &oh264_data->bsi.sLayerInfo[i];\n\t    for (j=0; j < (unsigned)pLayerBsInfo->iNalCount; ++j) {\n\t\tif (pLayerBsInfo->pNalLengthInByte[j] > (int)payload_size) {\n                    payload_size = pLayerBsInfo->pNalLengthInByte[j];\n\t\t    oh264_data->ilayer = i;\n\t\t}\n\t    }\n\t}\n\n\tpLayerBsInfo = &oh264_data->bsi.sLayerInfo[oh264_data->ilayer];\n\tif (pLayerBsInfo == NULL) {\n\t    output->size = 0;\n\t    output->type = PJMEDIA_FRAME_TYPE_NONE;\n\t    return PJ_SUCCESS;\n\t}\n\n\tpayload = pLayerBsInfo->pBsBuf;\n\tpayload_size = 0;\n\tfor (int inal = pLayerBsInfo->iNalCount - 1; inal >= 0; --inal) {\n\t    payload_size += pLayerBsInfo->pNalLengthInByte[inal];\n\t}\n\n\tif (payload_size > out_size)\n\t    return PJMEDIA_CODEC_EFRMTOOSHORT;\n\n\toutput->type = PJMEDIA_FRAME_TYPE_VIDEO;\n\toutput->size = payload_size;\n\toutput->timestamp = input->timestamp;\n\tpj_memcpy(output->buf, payload, payload_size);\n\n\treturn PJ_SUCCESS;\n    }\n\n    return oh264_codec_encode_more(codec, out_size, output, has_more);\n}\n\n\nstatic pj_status_t oh264_codec_encode_more(pjmedia_vid_codec *codec,\n                                           unsigned out_size,\n                                           pjmedia_frame *output,\n                                           pj_bool_t *has_more)\n{\n    struct oh264_codec_data *oh264_data;\n    const pj_uint8_t *payload;\n    pj_size_t payload_len;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(codec && out_size && output && has_more,\n                     PJ_EINVAL);\n\n    oh264_data = (oh264_codec_data*) codec->codec_data;\n\n    if (oh264_data->enc_processed < oh264_data->enc_frame_size) {\n\t/* We have outstanding frame in packetizer */\n\tstatus = pjmedia_h264_packetize(oh264_data->pktz,\n\t                                oh264_data->enc_frame_whole,\n\t                                oh264_data->enc_frame_size,\n\t                                &oh264_data->enc_processed,\n\t                                &payload, &payload_len);\n\tif (status != PJ_SUCCESS) {\n\t    /* Reset */\n\t    oh264_data->enc_frame_size = oh264_data->enc_processed = 0;\n\t    *has_more = (oh264_data->enc_processed <\n\t\t\t    oh264_data->enc_frame_size) ||\n\t\t\t(oh264_data->ilayer < oh264_data->bsi.iLayerNum);\n\n\t    PJ_PERROR(3,(THIS_FILE, status, \"pjmedia_h264_packetize() error\"));\n\t    return status;\n\t}\n\n\tPJ_ASSERT_RETURN(payload_len <= out_size, PJMEDIA_CODEC_EFRMTOOSHORT);\n\n        output->type = PJMEDIA_FRAME_TYPE_VIDEO;\n        pj_memcpy(output->buf, payload, payload_len);\n        output->size = payload_len;\n\n        if (oh264_data->bsi.eFrameType == videoFrameTypeIDR) {\n\t    output->bit_info |= PJMEDIA_VID_FRM_KEYFRAME;\n        }\n\n        *has_more = (oh264_data->enc_processed < oh264_data->enc_frame_size) ||\n        \t    (oh264_data->ilayer < oh264_data->bsi.iLayerNum);\n        return PJ_SUCCESS;\n    }\n\n    if (oh264_data->ilayer >= oh264_data->bsi.iLayerNum) {\n\t/* No more unretrieved frame */\n\tgoto no_frame;\n    }\n\n    SLayerBSInfo* pLayerBsInfo;\n    pLayerBsInfo = &oh264_data->bsi.sLayerInfo[oh264_data->ilayer++];\n    if (pLayerBsInfo == NULL) {\n\tgoto no_frame;\n    }\n\n    oh264_data->enc_frame_size = 0;\n    for (int inal = pLayerBsInfo->iNalCount - 1; inal >= 0; --inal) {\n\toh264_data->enc_frame_size += pLayerBsInfo->pNalLengthInByte[inal];\n    }\n\n    oh264_data->enc_frame_whole = pLayerBsInfo->pBsBuf;\n    oh264_data->enc_processed = 0;\n\n\n    status = pjmedia_h264_packetize(oh264_data->pktz,\n\t\t\t\t    oh264_data->enc_frame_whole,\n\t\t\t\t    oh264_data->enc_frame_size,\n\t\t\t\t    &oh264_data->enc_processed,\n\t\t\t\t    &payload, &payload_len);\n    if (status != PJ_SUCCESS) {\n\t/* Reset */\n\toh264_data->enc_frame_size = oh264_data->enc_processed = 0;\n\t*has_more = (oh264_data->ilayer < oh264_data->bsi.iLayerNum);\n\n\tPJ_PERROR(3,(THIS_FILE, status, \"pjmedia_h264_packetize() error [2]\"));\n\treturn status;\n    }\n\n    PJ_ASSERT_RETURN(payload_len <= out_size, PJMEDIA_CODEC_EFRMTOOSHORT);\n\n    output->type = PJMEDIA_FRAME_TYPE_VIDEO;\n    pj_memcpy(output->buf, payload, payload_len);\n    output->size = payload_len;\n\n    if (oh264_data->bsi.eFrameType == videoFrameTypeIDR) {\n\toutput->bit_info |= PJMEDIA_VID_FRM_KEYFRAME;\n    }\n\n    *has_more = (oh264_data->enc_processed < oh264_data->enc_frame_size) ||\n    \t    (oh264_data->ilayer < oh264_data->bsi.iLayerNum);\n\n    return PJ_SUCCESS;\n\nno_frame:\n    *has_more = PJ_FALSE;\n    output->size = 0;\n    output->type = PJMEDIA_FRAME_TYPE_NONE;\n    return PJ_SUCCESS;\n}\n\nstatic int write_yuv(pj_uint8_t *buf,\n                     unsigned dst_len,\n                     unsigned char* pData[3],\n                     int iStride[2],\n                     int iWidth,\n                     int iHeight)\n{\n    unsigned req_size;\n    pj_uint8_t *dst = buf;\n    pj_uint8_t *max = dst + dst_len;\n    int   i;\n    unsigned char*  pPtr = NULL;\n\n    req_size = (iWidth * iHeight) + (iWidth / 2 * iHeight / 2) +\n\t       (iWidth / 2 * iHeight / 2);\n    if (dst_len < req_size)\n\treturn -1;\n\n    pPtr = pData[0];\n    for (i = 0; i < iHeight && (dst + iWidth < max); i++) {\n\tpj_memcpy(dst, pPtr, iWidth);\n\tpPtr += iStride[0];\n\tdst += iWidth;\n    }\n\n    if (i < iHeight)\n\treturn -1;\n\n    iHeight = iHeight / 2;\n    iWidth = iWidth / 2;\n    pPtr = pData[1];\n    for (i = 0; i < iHeight && (dst + iWidth <= max); i++) {\n\tpj_memcpy(dst, pPtr, iWidth);\n\tpPtr += iStride[1];\n\tdst += iWidth;\n    }\n\n    if (i < iHeight)\n\treturn -1;\n\n    pPtr = pData[2];\n    for (i = 0; i < iHeight && (dst + iWidth <= max); i++) {\n\tpj_memcpy(dst, pPtr, iWidth);\n\tpPtr += iStride[1];\n\tdst += iWidth;\n    }\n\n    if (i < iHeight)\n\treturn -1;\n\n    return dst - buf;\n}\n\nstatic pj_status_t oh264_got_decoded_frame(pjmedia_vid_codec *codec,\n\t\t\t\t\t   struct oh264_codec_data *oh264_data,\n\t\t\t\t\t   unsigned char *pData[3],\n\t\t\t\t\t   SBufferInfo *sDstBufInfo,\n\t\t\t\t\t   pj_timestamp *timestamp,\n\t\t\t\t\t   unsigned out_size,\n\t\t\t\t\t   pjmedia_frame *output)\n{\n    pj_uint8_t* pDst[3] = {NULL};\n\n    pDst[0] = (pj_uint8_t*)pData[0];\n    pDst[1] = (pj_uint8_t*)pData[1];\n    pDst[2] = (pj_uint8_t*)pData[2];\n\n    /* Do not reset size as it may already contain frame\n    output->size = 0;\n    */\n\n    if (!pDst[0] || !pDst[1] || !pDst[2]) {\n\treturn PJ_SUCCESS;\n    }\n\n    int iStride[2];\n    int iWidth = sDstBufInfo->UsrData.sSystemBuffer.iWidth;\n    int iHeight = sDstBufInfo->UsrData.sSystemBuffer.iHeight;\n\n    iStride[0] = sDstBufInfo->UsrData.sSystemBuffer.iStride[0];\n    iStride[1] = sDstBufInfo->UsrData.sSystemBuffer.iStride[1];\n\n    int len = write_yuv((pj_uint8_t *)output->buf, out_size,\n\t\t\tpDst, iStride, iWidth, iHeight);\n    if (len > 0) {\n\toutput->timestamp = *timestamp;\n\toutput->size = len;\n\toutput->type = PJMEDIA_FRAME_TYPE_VIDEO;\n    } else {\n\t/* buffer is damaged, reset size */\n\toutput->size = 0;\n\treturn PJMEDIA_CODEC_EFRMTOOSHORT;\n    }\n\n    /* Detect format change */\n    if (iWidth != (int)oh264_data->prm->dec_fmt.det.vid.size.w ||\n\tiHeight != (int)oh264_data->prm->dec_fmt.det.vid.size.h)\n    {\n\tpjmedia_event event;\n\n\tPJ_LOG(4,(THIS_FILE, \"Frame size changed: %dx%d --> %dx%d\",\n\t\t  oh264_data->prm->dec_fmt.det.vid.size.w,\n\t\t  oh264_data->prm->dec_fmt.det.vid.size.h,\n\t\t  iWidth, iHeight));\n\n\toh264_data->prm->dec_fmt.det.vid.size.w = iWidth;\n\toh264_data->prm->dec_fmt.det.vid.size.h = iHeight;\n\n\t/* Broadcast format changed event */\n\tpjmedia_event_init(&event, PJMEDIA_EVENT_FMT_CHANGED,\n\t                   timestamp, codec);\n\tevent.data.fmt_changed.dir = PJMEDIA_DIR_DECODING;\n\tpjmedia_format_copy(&event.data.fmt_changed.new_fmt,\n\t                    &oh264_data->prm->dec_fmt);\n\tpjmedia_event_publish(NULL, codec, &event,\n\t                      PJMEDIA_EVENT_PUBLISH_DEFAULT);\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t oh264_codec_decode(pjmedia_vid_codec *codec,\n                                      pj_size_t count,\n                                      pjmedia_frame packets[],\n                                      unsigned out_size,\n                                      pjmedia_frame *output)\n{\n    struct oh264_codec_data *oh264_data;\n    unsigned char* pData[3] = {NULL};\n    const pj_uint8_t nal_start[] = { 0, 0, 1 };\n    SBufferInfo sDstBufInfo;\n    pj_bool_t has_frame = PJ_FALSE;\n    unsigned buf_pos, whole_len = 0;\n    unsigned i, frm_cnt;\n    pj_status_t status = PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(codec && count && packets && out_size && output,\n                     PJ_EINVAL);\n    PJ_ASSERT_RETURN(output->buf, PJ_EINVAL);\n\n    oh264_data = (oh264_codec_data*) codec->codec_data;\n\n    /*\n     * Step 1: unpacketize the packets/frames\n     */\n    whole_len = 0;\n    if (oh264_data->whole) {\n\tfor (i=0; i<count; ++i) {\n\t    if (whole_len + packets[i].size > oh264_data->dec_buf_size) {\n\t\tPJ_LOG(4,(THIS_FILE, \"Decoding buffer overflow [1]\"));\n\t\treturn PJMEDIA_CODEC_EFRMTOOSHORT;\n\t    }\n\n\t    pj_memcpy( oh264_data->dec_buf + whole_len,\n\t               (pj_uint8_t*)packets[i].buf,\n\t               packets[i].size);\n\t    whole_len += packets[i].size;\n\t}\n\n    } else {\n\tfor (i=0; i<count; ++i) {\n\n\t    if (whole_len + packets[i].size + sizeof(nal_start) >\n\t\t\t\t\t\toh264_data->dec_buf_size)\n\t    {\n\t\tPJ_LOG(4,(THIS_FILE, \"Decoding buffer overflow [1]\"));\n\t\treturn PJMEDIA_CODEC_EFRMTOOSHORT;\n\t    }\n\n\t    status = pjmedia_h264_unpacketize( oh264_data->pktz,\n\t\t\t\t\t       (pj_uint8_t*)packets[i].buf,\n\t\t\t\t\t       packets[i].size,\n\t\t\t\t\t       oh264_data->dec_buf,\n\t\t\t\t\t       oh264_data->dec_buf_size,\n\t\t\t\t\t       &whole_len);\n\t    if (status != PJ_SUCCESS) {\n\t\tPJ_PERROR(4,(THIS_FILE, status, \"Unpacketize error\"));\n\t\tcontinue;\n\t    }\n\t}\n    }\n\n    if (whole_len + sizeof(nal_start) > oh264_data->dec_buf_size) {\n\tPJ_LOG(4,(THIS_FILE, \"Decoding buffer overflow [2]\"));\n\treturn PJMEDIA_CODEC_EFRMTOOSHORT;\n    }\n\n    /* Dummy NAL sentinel */\n    pj_memcpy( oh264_data->dec_buf + whole_len, nal_start, sizeof(nal_start));\n\n    /*\n     * Step 2: parse the individual NAL and give to decoder\n     */\n    buf_pos = 0;\n    for ( frm_cnt=0; ; ++frm_cnt) {\n\tunsigned frm_size;\n\tunsigned char *start;\n\n\tfor (i = 0; buf_pos + i < whole_len; i++) {\n\t    if (oh264_data->dec_buf[buf_pos + i] == 0 &&\n\t\toh264_data->dec_buf[buf_pos + i + 1] == 0 &&\n\t\toh264_data->dec_buf[buf_pos + i + 2] == 1 &&\n\t\ti > 1)\n\t    {\n\t\tbreak;\n\t    }\n\t}\n\tfrm_size = i;\n\n\tpj_bzero( pData, sizeof(pData));\n\tpj_bzero( &sDstBufInfo, sizeof (SBufferInfo));\n\n\tstart = oh264_data->dec_buf + buf_pos;\n\n\t/* Decode */\n\toh264_data->dec->DecodeFrame2( start, frm_size, pData, &sDstBufInfo);\n\n\tif (sDstBufInfo.iBufferStatus == 1) {\n\t    /* May overwrite existing frame but that's ok. */\n\t    status = oh264_got_decoded_frame(codec, oh264_data, pData,\n\t                                     &sDstBufInfo,\n\t                                     &packets[0].timestamp, out_size,\n\t                                     output);\n\t    has_frame = (status==PJ_SUCCESS && output->size != 0);\n\t}\n\n\tif (buf_pos + frm_size >= whole_len)\n\t    break;\n\n\tbuf_pos += frm_size;\n    }\n\n    /* Signal that we have no more frames */\n    pj_int32_t iEndOfStreamFlag = true;\n    oh264_data->dec->SetOption( DECODER_OPTION_END_OF_STREAM,\n                                (void*)&iEndOfStreamFlag);\n\n    /* Retrieve the decoded frame */\n    pj_bzero(pData, sizeof(pData));\n    pj_bzero(&sDstBufInfo, sizeof (SBufferInfo));\n    oh264_data->dec->DecodeFrame2 (NULL, 0, pData, &sDstBufInfo);\n\n    if (sDstBufInfo.iBufferStatus == 1) {\n\t/* Overwrite existing output frame and that's ok, because we assume\n\t * newer frame have better quality because it has more NALs\n\t */\n\tstatus = oh264_got_decoded_frame(codec, oh264_data, pData,\n\t                                 &sDstBufInfo, &packets[0].timestamp,\n\t                                 out_size, output);\n\thas_frame = (status==PJ_SUCCESS && output->size != 0);\n    }\n\n    if (!has_frame) {\n\tpjmedia_event event;\n\n\t/* Broadcast missing keyframe event */\n\tpjmedia_event_init(&event, PJMEDIA_EVENT_KEYFRAME_MISSING,\n\t                   &packets[0].timestamp, codec);\n\tpjmedia_event_publish(NULL, codec, &event,\n\t                      PJMEDIA_EVENT_PUBLISH_DEFAULT);\n\n\tPJ_LOG(5,(THIS_FILE, \"Decode couldn't produce picture, \"\n\t\t  \"input nframes=%d, concatenated size=%d bytes\",\n\t\t  count, whole_len));\n\n\toutput->type = PJMEDIA_FRAME_TYPE_NONE;\n\toutput->size = 0;\n\toutput->timestamp = packets[0].timestamp;\n    }\n\n    return status;\n}\n\n#endif\t/* PJMEDIA_HAS_OPENH264_CODEC */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/opus.c",
    "content": "/**\n * Copyright (C) 2010 Regis Montoya (aka r3gis - www.r3gis.fr)\n * This file is part of pjsip_android.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <pjmedia-codec/opus.h>\n#include <pjmedia-codec/types.h>\n#include <pjmedia/codec.h>\n#include <pjmedia/endpoint.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/port.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n\n#if defined(PJMEDIA_HAS_OPUS_CODEC) && (PJMEDIA_HAS_OPUS_CODEC!=0)\n\n#include \"../../third_party/opus/include/opus.h\"\n\n/* Opus can encode frames of 2.5, 5, 10, 20, 40, or 60 ms. */\n#define FRAME_LENGTH_MS\t\t20\n\n/* It can also combine multiple frames into packets of up to 120 ms */\n/* So at maximum 2.5ms * 48frames = 120ms*/\n#define OPUS_MAX_FRAMES_PER_PACKET 48\n\n#define OPUS_CLOCK_RATE 48000\n\n#define _TRACE_OPUS 0\n\n#define THIS_FILE       \"opus.c\"\n\n/* Prototypes for OPUS factory */\nstatic pj_status_t opus_test_alloc(pjmedia_codec_factory *factory,\n\t\t\t\t   const pjmedia_codec_info *id);\nstatic pj_status_t opus_default_attr(pjmedia_codec_factory *factory,\n\t\t\t\t     const pjmedia_codec_info *id,\n\t\t\t\t     pjmedia_codec_param *attr);\nstatic pj_status_t opus_enum_codecs(pjmedia_codec_factory *factory,\n\t\t\t\t    unsigned *count,\n\t\t\t\t    pjmedia_codec_info codecs[]);\nstatic pj_status_t opus_alloc_codec(pjmedia_codec_factory *factory,\n\t\t\t\t    const pjmedia_codec_info *id,\n\t\t\t\t    pjmedia_codec **p_codec);\nstatic pj_status_t opus_dealloc_codec(pjmedia_codec_factory *factory,\n\t\t\t\t      pjmedia_codec *codec);\n\n/* Prototypes for OPUS implementation. */\nstatic pj_status_t opus_codec_init(pjmedia_codec *codec,\n\t\t\t\t   pj_pool_t *pool);\nstatic pj_status_t opus_codec_open(pjmedia_codec *codec,\n\t\t\t\t   pjmedia_codec_param *attr);\nstatic pj_status_t opus_codec_close(pjmedia_codec *codec);\nstatic pj_status_t opus_codec_modify(pjmedia_codec *codec,\n\t\t\t\t     const pjmedia_codec_param *attr);\nstatic pj_status_t opus_codec_parse(pjmedia_codec *codec,\n\t\t\t\t    void *pkt,\n\t\t\t\t    pj_size_t pkt_size,\n\t\t\t\t    const pj_timestamp *timestamp,\n\t\t\t\t    unsigned *frame_cnt,\n\t\t\t\t    pjmedia_frame frames[]);\nstatic pj_status_t opus_codec_encode(pjmedia_codec *codec,\n\t\t\t\t     const struct pjmedia_frame *input,\n\t\t\t\t     unsigned output_buf_len,\n\t\t\t\t     struct pjmedia_frame *output);\nstatic pj_status_t opus_codec_decode(pjmedia_codec *codec,\n\t\t\t\t     const struct pjmedia_frame *input,\n\t\t\t\t     unsigned output_buf_len,\n\t\t\t\t     struct pjmedia_frame *output);\nstatic pj_status_t opus_codec_recover(pjmedia_codec *codec,\n\t\t\t\t      unsigned output_buf_len,\n\t\t\t\t      struct pjmedia_frame *output);\n\n/* Definition for OPUS codec operations. */\nstatic pjmedia_codec_op opus_op = {\n    &opus_codec_init,\n    &opus_codec_open,\n    &opus_codec_close,\n    &opus_codec_modify,\n    &opus_codec_parse,\n    &opus_codec_encode,\n    &opus_codec_decode,\n    &opus_codec_recover\n};\n\n/* Definition for OPUS codec factory operations. */\nstatic pjmedia_codec_factory_op opus_factory_op = {\n    &opus_test_alloc,\n    &opus_default_attr,\n    &opus_enum_codecs,\n    &opus_alloc_codec,\n    &opus_dealloc_codec,\n    &pjmedia_codec_opus_deinit\n};\n\n/* OPUS factory private data */\nstatic struct opus_factory {\n\tpjmedia_codec_factory base;\n\tpjmedia_endpt *endpt;\n\tpj_pool_t *pool;\n\tpj_mutex_t *mutex;\n\tpjmedia_codec codec_list;\n} opus_factory;\n\n/* OPUS codec private data. */\nstruct opus_private {\n    pj_pool_t *pool; /* Pool for each instance.    */\n    pj_uint8_t   pcm_bytes_per_sample;\n\n    int externalFs; /* Clock rate we would like to limit from outside */\n\n    pj_bool_t enc_ready;\n    OpusEncoder* psEnc;\n\n    pj_bool_t dec_ready;\n    OpusDecoder* psDec;\n\n    /* Buffer of 120ms to hold decoded frames. */\n    void        *dec_buf;\n    pj_size_t    dec_buf_size;\n    pj_size_t    dec_buf_max_size;\n    int          dec_buf_sample_per_frame;\n    pj_uint32_t  pkt_info;    /* Packet info for buffered frames.  */\n};\n\nint opus_to_pjsip_error_code(int opus_error) {\n\tswitch (opus_error) {\n\tcase OPUS_BAD_ARG:\n\t\t/* One or more invalid/out of range arguments */\n\t\treturn PJ_EINVAL;\n\tcase OPUS_BUFFER_TOO_SMALL:\n\t\t/* The mode struct passed is invalid */\n\t\treturn PJMEDIA_CODEC_EPCMTOOSHORT;\n\tcase OPUS_INTERNAL_ERROR:\n\t\t/* An internal error was detected */\n\t\treturn PJMEDIA_CODEC_EFAILED;\n\tcase OPUS_INVALID_PACKET:\n\t\t/* The compressed data passed is corrupted */\n\t\treturn PJMEDIA_CODEC_EBADBITSTREAM;\n\tcase OPUS_UNIMPLEMENTED:\n\t\t/* Invalid/unsupported request number */\n\t\treturn PJ_ENOTSUP;\n\tcase OPUS_INVALID_STATE:\n\t\t/* An encoder or decoder structure is invalid or already freed */\n\t\treturn PJ_EINVALIDOP;\n\tcase OPUS_ALLOC_FAIL:\n\t\t/* Memory allocation has failed */\n\t\treturn PJMEDIA_CODEC_EFAILED;\n\t}\n\treturn PJMEDIA_ERROR;\n}\n\n/*\n * Apply opus settings to dec_fmtp parameters\n */\nvoid apply_opus_codec_params(pj_pool_t* pool, pjmedia_codec_param *attr) {\n\tattr->setting.dec_fmtp.cnt = 0;\n\tattr->setting.dec_fmtp.param[attr->setting.dec_fmtp.cnt].name = pj_str(\"useinbandfec\");\n\tif (attr->setting.plc == 0) {\n\t    attr->setting.dec_fmtp.param[attr->setting.dec_fmtp.cnt].val = pj_str(\"0\");\n\t} else {\n\t    attr->setting.dec_fmtp.param[attr->setting.dec_fmtp.cnt].val = pj_str(\"1\");\n\t}\n\tattr->setting.dec_fmtp.cnt++;\n\tif (attr->setting.vad == 1) {\n\t\tattr->setting.dec_fmtp.param[attr->setting.dec_fmtp.cnt].name = pj_str(\"usedtx\");\n\t\tattr->setting.dec_fmtp.param[attr->setting.dec_fmtp.cnt].val = pj_str(\"1\");\n\t\tattr->setting.dec_fmtp.cnt++;\n\t}\n\tif (attr->info.channel_cnt == 2) {\n\t\tattr->setting.dec_fmtp.param[attr->setting.dec_fmtp.cnt].name = pj_str(\"stereo\");\n\t\tattr->setting.dec_fmtp.param[attr->setting.dec_fmtp.cnt].val = pj_str(\"1\");\n\t\tattr->setting.dec_fmtp.cnt++;\n\t}\n\tif (attr->info.clock_rate < 48000) {\n\t\tattr->setting.dec_fmtp.param[attr->setting.dec_fmtp.cnt].name = pj_str(\"maxcodedaudiobandwidth\");\n\t\tchar clock_rate_char[8];\n\t\tpj_utoa(attr->info.clock_rate, clock_rate_char);\n\t\tpj_strdup2(pool, &attr->setting.dec_fmtp.param[attr->setting.dec_fmtp.cnt].val, clock_rate_char);\n\t\tattr->setting.dec_fmtp.cnt++;\n\t}\n}\n\nPJ_DEF(pj_status_t) pjmedia_codec_opus_init(pjmedia_endpt *endpt) {\n\tpjmedia_codec_mgr *codec_mgr;\n\tpj_status_t status;\n\n\tif (opus_factory.endpt != NULL) {\n\t\t/* Already initialized. */\n\t\treturn PJ_SUCCESS;\n\t}\n\n\t/* Init factory */\n\topus_factory.base.op = &opus_factory_op;\n\topus_factory.base.factory_data = NULL;\n\topus_factory.endpt = endpt;\n\n\t/* Create pool */\n\topus_factory.pool = pjmedia_endpt_create_pool(endpt, \"opus codecs\", 4000, 4000);\n\tif (!opus_factory.pool)\n\t\treturn PJ_ENOMEM;\n\n\t/* Init list */\n\tpj_list_init(&opus_factory.codec_list);\n\n\t/* Create mutex. */\n\tstatus = pj_mutex_create_simple(opus_factory.pool, \"opus codecs\", &opus_factory.mutex);\n\tif (status != PJ_SUCCESS)\n\t\tgoto on_error;\n\n\tPJ_LOG(5, (THIS_FILE, \"Init opus\"));\n\n\t/* Get the codec manager. */\n\tcodec_mgr = pjmedia_endpt_get_codec_mgr(endpt);\n\tif (!codec_mgr)\n\t\treturn PJ_EINVALIDOP;\n\n\n\tPJ_LOG(5, (THIS_FILE, \"Init opus > DONE\"));\n\n\t/* Register codec factory to endpoint. */\n\tstatus = pjmedia_codec_mgr_register_factory(codec_mgr, &opus_factory.base);\n\tif (status != PJ_SUCCESS)\n\t\treturn status;\n\n\treturn PJ_SUCCESS;\n\non_error:\n\tif (opus_factory.mutex) {\n\t\tpj_mutex_destroy(opus_factory.mutex);\n\t\topus_factory.mutex = NULL;\n\t}\n\tif (opus_factory.pool) {\n\t\tpj_pool_release(opus_factory.pool);\n\t\topus_factory.pool = NULL;\n\t}\n\n\treturn status;\n}\n\n/*\n * Unregister OPUS codec factory from pjmedia endpoint and deinitialize\n * the OPUS codec library.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_opus_deinit(void) {\n\tpjmedia_codec_mgr *codec_mgr;\n\tpj_status_t status;\n\n\tif (opus_factory.endpt == NULL) {\n\t\t/* Not registered. */\n\t\treturn PJ_SUCCESS;\n\t}\n\n\t/* Lock mutex. */\n\tpj_mutex_lock(opus_factory.mutex);\n\n\t/* Get the codec manager. */\n\tcodec_mgr = pjmedia_endpt_get_codec_mgr(opus_factory.endpt);\n\tif (!codec_mgr) {\n\t\topus_factory.endpt = NULL;\n\t\tpj_mutex_unlock(opus_factory.mutex);\n\t\treturn PJ_EINVALIDOP;\n\t}\n\n\t/* Unregister opus codec factory. */\n\tstatus = pjmedia_codec_mgr_unregister_factory(codec_mgr, &opus_factory.base);\n\topus_factory.endpt = NULL;\n\n\t/* Destroy mutex. */\n        pj_mutex_unlock(opus_factory.mutex);\n\tpj_mutex_destroy(opus_factory.mutex);\n\topus_factory.mutex = NULL;\n\n\t/* Release pool. */\n\tpj_pool_release(opus_factory.pool);\n\topus_factory.pool = NULL;\n\n\treturn status;\n}\n\n/*\n * Check if factory can allocate the specified codec.\n */\nstatic pj_status_t opus_test_alloc(pjmedia_codec_factory *factory, const pjmedia_codec_info *info) {\n\tconst pj_str_t opus_tag = { \"opus\", 4 };\n\n\tPJ_UNUSED_ARG(factory);\n\tPJ_ASSERT_RETURN(factory==&opus_factory.base, PJ_EINVAL);\n\n\t/* Type MUST be audio. */\n\tif (info->type != PJMEDIA_TYPE_AUDIO)\n\t\treturn PJMEDIA_CODEC_EUNSUP;\n\n\t/* Check encoding name. */\n\tif (pj_stricmp(&info->encoding_name, &opus_tag) != 0)\n\t\treturn PJMEDIA_CODEC_EUNSUP;\n\n\t/* Check clock-rate */\n\tif (info->clock_rate == 8000 || info->clock_rate == 12000 ||\n\t    info->clock_rate == 16000 || info->clock_rate == 24000 || info->clock_rate == 48000) {\n\t\treturn PJ_SUCCESS;\n\t}\n\n\t/* Clock rate not supported */\n\treturn PJMEDIA_CODEC_EUNSUP;\n}\n\n/*\n * Generate default attribute.\n */\nstatic pj_status_t opus_default_attr(pjmedia_codec_factory *factory, const pjmedia_codec_info *id, pjmedia_codec_param *attr) {\n\tPJ_ASSERT_RETURN(factory == &opus_factory.base, PJ_EINVAL);\n\tpj_bzero(attr, sizeof(pjmedia_codec_param));\n\n\t/* Table from opus rfc\n\t +-------+---------+-----------+\n\t |  Mode | fs (Hz) | BR (kbps) |\n\t +-------+---------+-----------+\n\t | voice |   8000  |   6 - 20  |\n\t | voice |  12000  |   7 - 25  |\n\t | voice |  16000  |   8 - 30  |\n\t | voice |  24000  |  18 - 28  |\n\t | voice |  48000  |  24 - 32  |\n\t +-------+---------+-----------+\n\t */\n\n\tattr->info.channel_cnt = 1;\n\t/* SAGH: set to 2? */\n\t/*\n\t * TODO : would like to use 16kHz as internal clock rate in our case\n\t * pjmedia seems to have no support of different clock rate for RTP\n\t * and for associated port. Keeping 48kHz for RTP is needed (we just have\n\t * to transform timestamps) but to feed codec with 16kHz frames seems requires\n\t * some extra work in pjmedia.\n\t * For now we are obliged to use pjmedia resampler while would be\n\t * more efficient to use the Opus feature instead.\n\t * Using g722 hack was tried but seems useless.\n\t */\n\tattr->info.clock_rate = 48000;\n\tattr->info.avg_bps = 20000;\n\tattr->info.max_bps = 32000;\n\tattr->info.frm_ptime = FRAME_LENGTH_MS;\n\tattr->info.pcm_bits_per_sample = 16;\n\tattr->info.pt = (pj_uint8_t) id->pt;\n\n\t/* Inform the stream to prepare a larger buffer since we cannot parse\n\t* OPUS packets and split it into individual frames.\n\t* Max packet size of opus is 120ms audio\n\t*/\n\tattr->info.max_rx_frame_size = attr->info.max_bps * 120 / 8 / 1000;\n\tif ((attr->info.max_bps * attr->info.frm_ptime) % 8000 != 0)\n\t\t++attr->info.max_rx_frame_size;\n\n\n\tattr->setting.frm_per_pkt = 1;\n\t/* Default usedtx is 0 in opus */\n\tattr->setting.vad = 0;\n\t/* Default useinbandfec is 1 in opus */\n\tattr->setting.plc = 1;\n\n\t/* Apply these settings to relevant fmtp parameters */\n\tapply_opus_codec_params(opus_factory.pool, attr);\n\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Enum codecs supported by this factory.\n */\nstatic pj_status_t opus_enum_codecs(pjmedia_codec_factory *factory, unsigned *count, pjmedia_codec_info codecs[]) {\n\tPJ_UNUSED_ARG(factory);\n\tPJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);\n\n\tpj_bzero(&codecs[0], sizeof(pjmedia_codec_info));\n\tcodecs[0].encoding_name = pj_str(\"opus\");\n\tcodecs[0].pt = PJMEDIA_RTP_PT_OPUS;\n\tcodecs[0].type = PJMEDIA_TYPE_AUDIO;\n\tcodecs[0].clock_rate = 48000;\n\tcodecs[0].channel_cnt = 1; /* SAGHUL: set to 2? */\n\n\t*count = 1;\n\n\treturn PJ_SUCCESS;\n\n}\n\n/*\n * Allocate a new OPUS codec instance.\n */\nstatic pj_status_t opus_alloc_codec(pjmedia_codec_factory *factory, const pjmedia_codec_info *id, pjmedia_codec **p_codec) {\n\tpjmedia_codec *codec;\n\tstruct opus_private *opus;\n\n\tPJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);\n\tPJ_ASSERT_RETURN(factory == &opus_factory.base, PJ_EINVAL);\n\n\tpj_mutex_lock(opus_factory.mutex);\n\n\t/* Get free nodes, if any. */\n\tif (!pj_list_empty(&opus_factory.codec_list)) {\n\t\tcodec = opus_factory.codec_list.next;\n\t\tpj_list_erase(codec);\n\t} else {\n\t\tcodec = PJ_POOL_ZALLOC_T(opus_factory.pool, pjmedia_codec);\n\t\tPJ_ASSERT_RETURN(codec != NULL, PJ_ENOMEM);\n\t\tcodec->op = &opus_op;\n\t\tcodec->factory = factory;\n\t\tcodec->codec_data = pj_pool_alloc(opus_factory.pool, sizeof(struct opus_private));\n\t}\n\n\tpj_mutex_unlock(opus_factory.mutex);\n\n\topus = (struct opus_private*) codec->codec_data;\n\topus->enc_ready = PJ_FALSE;\n\topus->dec_ready = PJ_FALSE;\n\n\t/* Create pool for codec instance */\n\topus->pool = pjmedia_endpt_create_pool(opus_factory.endpt, \"opuscodec\", 512, 512);\n\n\t*p_codec = codec;\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Free codec.\n */\nstatic pj_status_t opus_dealloc_codec(pjmedia_codec_factory *factory, pjmedia_codec *codec) {\n\tstruct opus_private *opus;\n\n\tPJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);\n\tPJ_UNUSED_ARG(factory);\n\tPJ_ASSERT_RETURN(factory == &opus_factory.base, PJ_EINVAL);\n\n\topus = (struct opus_private*) codec->codec_data;\n\n\t/* Close codec, if it's not closed. */\n\tif (opus->enc_ready || opus->dec_ready)\n\t\topus_codec_close(codec);\n\n\t/* Put in the free list. */\n\tpj_mutex_lock(opus_factory.mutex);\n\tpj_list_push_front(&opus_factory.codec_list, codec);\n\tpj_mutex_unlock(opus_factory.mutex);\n\n\tpj_pool_release(opus->pool);\n\topus->pool = NULL;\n\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Init codec.\n */\nstatic pj_status_t opus_codec_init(pjmedia_codec *codec, pj_pool_t *pool) {\n\tPJ_UNUSED_ARG(codec);\n\tPJ_UNUSED_ARG(pool);\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Open codec.\n */\nstatic pj_status_t opus_codec_open(pjmedia_codec *codec, pjmedia_codec_param *attr) {\n\tconst pj_str_t STR_FMTP_USE_INBAND_FEC = { \"useinbandfec\", 12 };\n\tconst pj_str_t STR_FMTP_MAX_AVERAGE_BITRATE = { \"maxaveragebitrate\", 17 };\n\tconst pj_str_t STR_FMTP_MAX_CODED_AUDIO_BANDWIDTH = { \"maxcodedaudiobandwidth\", 22 };\n\tconst pj_str_t STR_FMTP_USE_DTX = { \"usedtx\", 6 };\n\n\tstruct opus_private *opus;\n\tint ret, tmpFmtpVal;\n\tunsigned i, structSizeBytes, max_nsamples;\n\n\topus = (struct opus_private*) codec->codec_data;\n\n\tPJ_ASSERT_RETURN(opus && !opus->enc_ready && !opus->dec_ready, PJ_EINVAL);\n\n\tPJ_LOG(4, (THIS_FILE, \"Clock rate is %d \", attr->info.clock_rate));\n        opus->externalFs = attr->info.clock_rate;\n\n\t/* Create Encoder */\n\tstructSizeBytes = opus_encoder_get_size(attr->info.channel_cnt);\n\topus->psEnc = pj_pool_zalloc(opus->pool, structSizeBytes);\n\tret = opus_encoder_init(opus->psEnc, opus->externalFs, attr->info.channel_cnt, OPUS_APPLICATION_AUDIO);\n\tif (ret) {\n\t\tPJ_LOG(1, (THIS_FILE, \"Unable to init encoder : %d\", ret));\n\t\treturn PJ_EINVAL;\n\t}\n\n\t/*\n\t * Set Encoder parameters\n\t * TODO : have it configurable\n\t */\n\topus_encoder_ctl(opus->psEnc, OPUS_SET_COMPLEXITY(10));\n\topus_encoder_ctl(opus->psEnc, OPUS_SET_INBAND_FEC(1)); /* on by default */\n\topus_encoder_ctl(opus->psEnc, OPUS_SET_PACKET_LOSS_PERC(5));\n\topus_encoder_ctl(opus->psEnc, OPUS_SET_SIGNAL(OPUS_AUTO));\n\n\t/* Apply fmtp params to Encoder */\n\tfor (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {\n\t\tif (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_FMTP_USE_INBAND_FEC) == 0) {\n\t\t\ttmpFmtpVal = (int)(pj_strtoul(&attr->setting.enc_fmtp.param[i].val));\n\t\t\topus_encoder_ctl(opus->psEnc, OPUS_SET_INBAND_FEC(tmpFmtpVal));\n\t\t\tbreak;\n\t\t} else if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_FMTP_MAX_AVERAGE_BITRATE) == 0) {\n\t\t\ttmpFmtpVal = (int)(pj_strtoul(&attr->setting.enc_fmtp.param[i].val));\n\t\t\tif (tmpFmtpVal >= 6000 && tmpFmtpVal <= 510000) {\n\t\t\t\topus_encoder_ctl(opus->psEnc, OPUS_SET_BITRATE(tmpFmtpVal));\n\t\t\t}\n\t\t} else if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_FMTP_MAX_CODED_AUDIO_BANDWIDTH) == 0) {\n\t\t\ttmpFmtpVal = (int)(pj_strtoul(&attr->setting.enc_fmtp.param[i].val));\n\t\t\tif (tmpFmtpVal <= 8000) {\n\t\t\t\topus_encoder_ctl(opus->psEnc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));\n\t\t\t} else if (tmpFmtpVal <= 12000) {\n\t\t\t\topus_encoder_ctl(opus->psEnc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_MEDIUMBAND));\n\t\t\t} else if (tmpFmtpVal <= 16000) {\n\t\t\t\topus_encoder_ctl(opus->psEnc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));\n\t\t\t} else if (tmpFmtpVal <= 24000) {\n\t\t\t\topus_encoder_ctl(opus->psEnc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));\n\t\t\t} else if (tmpFmtpVal <= 48000) {\n\t\t\t\topus_encoder_ctl(opus->psEnc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));\n\t\t\t}\n\t\t} else if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_FMTP_USE_DTX) == 0) {\n\t\t\ttmpFmtpVal = (int)(pj_strtoul(&attr->setting.enc_fmtp.param[i].val));\n\t\t\topus_encoder_ctl(opus->psEnc, OPUS_SET_DTX(tmpFmtpVal));\n\t\t}\n\t}\n\n\topus->enc_ready = PJ_TRUE;\n\n\t/* Decoder buffer */\n\topus->pcm_bytes_per_sample = attr->info.pcm_bits_per_sample / 8;\n\tmax_nsamples = 120 * OPUS_CLOCK_RATE / 1000; /* 120ms is max frame time */\n\topus->dec_buf_max_size = max_nsamples * opus->pcm_bytes_per_sample;\n\topus->dec_buf = pj_pool_alloc(opus->pool, opus->dec_buf_max_size);\n\n\t/* Create decoder */\n\tstructSizeBytes = opus_decoder_get_size(attr->info.channel_cnt);\n\topus->psDec = pj_pool_zalloc(opus->pool, structSizeBytes);\n\tret = opus_decoder_init(opus->psDec, opus->externalFs, attr->info.channel_cnt);\n\tif (ret) {\n\t\tPJ_LOG(1, (THIS_FILE, \"Unable to init decoder : %d\", ret));\n\t\treturn PJ_EINVAL;\n\t}\n\n\topus->dec_ready = PJ_TRUE;\n\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Close codec.\n */\nstatic pj_status_t opus_codec_close(pjmedia_codec *codec) {\n\tstruct opus_private *opus;\n\topus = (struct opus_private*) codec->codec_data;\n\n\topus->enc_ready = PJ_FALSE;\n\topus->dec_ready = PJ_FALSE;\n\n\tPJ_LOG(5, (THIS_FILE, \"OPUS codec closed\"));\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Modify codec settings.\n */\nstatic pj_status_t opus_codec_modify(pjmedia_codec *codec, const pjmedia_codec_param *attr) {\n    PJ_TODO(implement_opus_codec_modify);\n\n    PJ_UNUSED_ARG(codec);\n    PJ_UNUSED_ARG(attr);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Encode frame.\n */\nstatic pj_status_t opus_codec_encode(pjmedia_codec *codec, const struct pjmedia_frame *input, unsigned output_buf_len, struct pjmedia_frame *output) {\n\tstruct opus_private *opus;\n\topus_int32 ret;\n\tunsigned nsamples;\n\n\tPJ_ASSERT_RETURN(codec && input && output, PJ_EINVAL);\n\n\topus = (struct opus_private*) codec->codec_data;\n\n\t/* Check frame in size */\n\tnsamples = input->size / opus->pcm_bytes_per_sample;\n\t/* TODO: validate? */\n\n\t/* Encode */\n\toutput->size = 0;\n\n\tret = opus_encode(opus->psEnc, (opus_int16*) input->buf, nsamples, (unsigned char *) output->buf, output_buf_len);\n\tif (ret < 0) {\n\t\tPJ_LOG(1, (THIS_FILE, \"Impossible to encode packet %d\", ret));\n\t\treturn opus_to_pjsip_error_code(ret);\n\t} else {\n\t\toutput->size = (pj_size_t) ret;\n\t}\n\toutput->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\toutput->timestamp = input->timestamp;\n#if _TRACE_OPUS\n\tPJ_LOG(4, (THIS_FILE, \"Encoder packet size %d for input %d ouput max len %d @ %d\", output->size, input->size, output_buf_len, (unsigned) output->timestamp.u64));\n#endif\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Get frames in the packet.\n */\n\nstatic pj_status_t opus_codec_parse(pjmedia_codec *codec, void *pkt, pj_size_t pkt_size, const pj_timestamp *ts, unsigned *frame_cnt, pjmedia_frame frames[]) {\n\tstruct opus_private *opus;\n\tunsigned char toc;\n\tconst unsigned char *raw_frames[48];\n\tshort size[48];\n\tint err, payload_offset, samples_per_frame;\n\tunsigned i;\n\n\tPJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);\n\n\topus = (struct opus_private*) codec->codec_data;\n\n\terr = opus_packet_parse(pkt, pkt_size, &toc, raw_frames, size, &payload_offset);\n\tif (err <= 0) {\n            PJ_LOG(4, (THIS_FILE, \"Error parsing Opus packet: %s\", opus_strerror(err)));\n            *frame_cnt = 0;\n\t    return opus_to_pjsip_error_code(err);\n        }\n\n        *frame_cnt = (unsigned)err;\n\tsamples_per_frame = opus_packet_get_samples_per_frame(pkt, opus->externalFs);\n\n#if _TRACE_OPUS\n    PJ_LOG(4, (THIS_FILE, \"Pkt info : bw -> %d , spf -> %d\", opus_packet_get_bandwidth(pkt), samples_per_frame));\n#endif\n\n    for (i = 0; i < *frame_cnt; i++) {\n        frames[i].type = PJMEDIA_FRAME_TYPE_AUDIO;\n        frames[i].bit_info = (((unsigned)ts->u64 & 0xFFFF) << 16) | (((unsigned)pkt & 0xFF) << 8) | i;\n        frames[i].buf = pkt;\n        frames[i].size = pkt_size;\n        frames[i].timestamp.u64 = ts->u64 + i * samples_per_frame;\n#if _TRACE_OPUS\n    \tPJ_LOG(4, (THIS_FILE, \"parsed %d of %d\",frames[i].size, *frame_cnt));\n#endif\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t opus_codec_decode(pjmedia_codec *codec, const struct pjmedia_frame *input, unsigned output_buf_len, struct pjmedia_frame *output) {\n    struct opus_private *opus;\n    unsigned pkt_info, frm_info, frm_size;\n\n    PJ_ASSERT_RETURN(codec && input && output_buf_len && output, PJ_EINVAL);\n\n    opus = (struct opus_private*) codec->codec_data;\n\n    pkt_info = input->bit_info & 0xFFFFFF00;\n    frm_info = input->bit_info & 0xF;\n    if (opus->pkt_info != pkt_info || input->bit_info == 0) {\n\t\topus->pkt_info = pkt_info;\n\t\topus->dec_buf_sample_per_frame = opus_packet_get_samples_per_frame(input->buf, opus->externalFs);\n\t\t/* We need to decode all the frames in the packet. */\n\t\topus->dec_buf_size = opus_decode(opus->psDec,\n\t\t\t\t\t\t (const unsigned char *) input->buf,\n\t\t\t\t\t\t (opus_int32) input->size,\n\t\t\t\t\t\t opus->dec_buf,\n\t\t\t\t\t\t opus->dec_buf_max_size,\n\t\t\t\t\t\t 0 /* decode FEC */);\n\t\tif(opus->dec_buf_size <= 0){\n\t\t\tPJ_LOG(2, (THIS_FILE, \"Failed to decode frame (err=%d)\", opus->dec_buf_size));\n\t\t\topus->dec_buf_size = 0;\n\t\t} else {\n\t\t\topus->dec_buf_size = opus->dec_buf_size * opus->pcm_bytes_per_sample;\n\t\t}\n    }\n\n    /* We have this packet decoded now (either was previously in the buffer or was just added to buffer). */\n    if (opus->dec_buf_size == 0) {\n\t    /* The decoding was a failure. */\n\t    output->size = 0;\n    } else {\n\t    frm_size = opus->dec_buf_sample_per_frame * opus->pcm_bytes_per_sample;\n#if _TRACE_OPUS\n\t    PJ_LOG(4, (THIS_FILE, \"Decode : copy from big buffer %d to %d\", output_buf_len, frm_size));\n#endif\n\t    if(output_buf_len < frm_size){\n\t        return PJ_ETOOSMALL;\n\t    }\n\t    /* Copy the decoded frame from the buffer. */\n\t    pj_memcpy(output->buf, ((opus_int16*)opus->dec_buf) + (frm_info * frm_size), frm_size);\n\t    output->size = frm_size;\n\t}\n\n\tif (output->size == 0) {\n\t\toutput->type = PJMEDIA_FRAME_TYPE_NONE;\n\t\toutput->buf = NULL;\n\t\treturn PJMEDIA_CODEC_EFAILED;\n\t}\n\n\toutput->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\toutput->timestamp = input->timestamp;\n\n#if _TRACE_OPUS\n\tPJ_LOG(4, (THIS_FILE, \"Decoded %d to %d with max %d\", input->size, output->size, output_buf_len));\n#endif\n\treturn PJ_SUCCESS;\n}\n\n/*\n * Recover lost frame.\n */\nstatic pj_status_t opus_codec_recover(pjmedia_codec *codec, unsigned output_buf_len, struct pjmedia_frame *output) {\n\tstruct opus_private *opus;\n\tint ret = 0;\n\tint frame_size;\n\n\tPJ_ASSERT_RETURN(output, PJ_EINVAL);\n\topus = (struct opus_private*) codec->codec_data;\n\n\tframe_size = output_buf_len / opus->pcm_bytes_per_sample;\n\t/* Decode */\n\tret = opus_decode(opus->psDec, (const unsigned char *) NULL, 0, output->buf, frame_size, 0);\n\tif (ret < 0) {\n\t\tPJ_LOG(1, (THIS_FILE, \"Failed to recover opus frame %d\", ret));\n\t\treturn PJ_EINVAL;\n\t} else if (ret == 0) {\n#if _TRACE_OPUS\n\t\tPJ_LOG(4, (THIS_FILE, \"Empty frame recovered %d\", ret));\n#endif\n\t\toutput->type = PJMEDIA_FRAME_TYPE_NONE;\n\t\toutput->buf = NULL;\n\t\toutput->size = 0;\n\t} else {\n#if _TRACE_OPUS\n\t\tPJ_LOG(4, (THIS_FILE, \"Frame recovered %d\", ret));\n#endif\n\t\toutput->size = ret * opus->pcm_bytes_per_sample;\n\t\toutput->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\t}\n\n\treturn PJ_SUCCESS;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/passthrough.c",
    "content": "/* $Id: passthrough.c 4082 2012-04-24 13:09:14Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-codec/passthrough.h>\n#include <pjmedia-codec/amr_sdp_match.h>\n#include <pjmedia/codec.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/endpoint.h>\n#include <pjmedia/port.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/math.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/os.h>\n\n/*\n * Only build this file if PJMEDIA_HAS_PASSTHROUGH_CODECS != 0\n */\n#if defined(PJMEDIA_HAS_PASSTHROUGH_CODECS) && PJMEDIA_HAS_PASSTHROUGH_CODECS!=0\n\n#define THIS_FILE   \"passthrough.c\"\n\n\n/* Prototypes for passthrough codecs factory */\nstatic pj_status_t test_alloc( pjmedia_codec_factory *factory, \n\t\t\t       const pjmedia_codec_info *id );\nstatic pj_status_t default_attr( pjmedia_codec_factory *factory, \n\t\t\t\t const pjmedia_codec_info *id, \n\t\t\t\t pjmedia_codec_param *attr );\nstatic pj_status_t enum_codecs( pjmedia_codec_factory *factory, \n\t\t\t\tunsigned *count, \n\t\t\t\tpjmedia_codec_info codecs[]);\nstatic pj_status_t alloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\tconst pjmedia_codec_info *id, \n\t\t\t\tpjmedia_codec **p_codec);\nstatic pj_status_t dealloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t  pjmedia_codec *codec );\n\n/* Prototypes for passthrough codecs implementation. */\nstatic pj_status_t codec_init( pjmedia_codec *codec, \n\t\t\t       pj_pool_t *pool );\nstatic pj_status_t codec_open( pjmedia_codec *codec, \n\t\t\t       pjmedia_codec_param *attr );\nstatic pj_status_t codec_close( pjmedia_codec *codec );\nstatic pj_status_t codec_modify(pjmedia_codec *codec, \n\t\t\t        const pjmedia_codec_param *attr );\nstatic pj_status_t codec_parse( pjmedia_codec *codec,\n\t\t\t        void *pkt,\n\t\t\t\tpj_size_t pkt_size,\n\t\t\t\tconst pj_timestamp *ts,\n\t\t\t\tunsigned *frame_cnt,\n\t\t\t\tpjmedia_frame frames[]);\nstatic pj_status_t codec_encode( pjmedia_codec *codec, \n\t\t\t\t const struct pjmedia_frame *input,\n\t\t\t\t unsigned output_buf_len,\n\t\t\t\t struct pjmedia_frame *output);\nstatic pj_status_t codec_decode( pjmedia_codec *codec,\n\t\t\t\t const struct pjmedia_frame *input,\n\t\t\t\t unsigned output_buf_len, \n\t\t\t\t struct pjmedia_frame *output);\nstatic pj_status_t codec_recover( pjmedia_codec *codec, \n\t\t\t\t  unsigned output_buf_len, \n\t\t\t\t  struct pjmedia_frame *output);\n\n/* Definition for passthrough codecs operations. */\nstatic pjmedia_codec_op codec_op = \n{\n    &codec_init,\n    &codec_open,\n    &codec_close,\n    &codec_modify,\n    &codec_parse,\n    &codec_encode,\n    &codec_decode,\n    &codec_recover\n};\n\n/* Definition for passthrough codecs factory operations. */\nstatic pjmedia_codec_factory_op codec_factory_op =\n{\n    &test_alloc,\n    &default_attr,\n    &enum_codecs,\n    &alloc_codec,\n    &dealloc_codec,\n    &pjmedia_codec_passthrough_deinit\n};\n\n/* Passthrough codecs factory */\nstatic struct codec_factory {\n    pjmedia_codec_factory    base;\n    pjmedia_endpt\t    *endpt;\n    pj_pool_t\t\t    *pool;\n    pj_mutex_t\t\t    *mutex;\n} codec_factory;\n\n/* Passthrough codecs private data. */\ntypedef struct codec_private {\n    pj_pool_t\t\t*pool;\t\t    /**< Pool for each instance.    */\n    int\t\t\t codec_idx;\t    /**< Codec index.\t\t    */\n    void\t\t*codec_setting;\t    /**< Specific codec setting.    */\n    pj_uint16_t\t\t avg_frame_size;    /**< Average of frame size.\t    */\n    unsigned\t\t samples_per_frame; /**< Samples per frame, for iLBC\n\t\t\t\t\t\t this can be 240 or 160, can\n\t\t\t\t\t\t only be known after codec is\n\t\t\t\t\t\t opened.\t\t    */\n} codec_private_t;\n\n\n\n/* CUSTOM CALLBACKS */\n\n/* Parse frames from a packet. Default behaviour of frame parsing is \n * just separating frames based on calculating frame length derived \n * from bitrate. Implement this callback when the default behaviour is \n * unapplicable.\n */\ntypedef pj_status_t (*parse_cb)(codec_private_t *codec_data, void *pkt, \n\t\t\t\tpj_size_t pkt_size, const pj_timestamp *ts,\n\t\t\t\tunsigned *frame_cnt, pjmedia_frame frames[]);\n\n/* Pack frames into a packet. Default behaviour of packing frames is \n * just stacking the frames with octet aligned without adding any \n * payload header. Implement this callback when the default behaviour is\n * unapplicable.\n */\ntypedef pj_status_t (*pack_cb)(codec_private_t *codec_data, \n\t\t\t       const struct pjmedia_frame_ext *input,\n\t\t\t       unsigned output_buf_len, \n\t\t\t       struct pjmedia_frame *output);\n\n\n/* Custom callback implementations. */\nstatic pj_status_t parse_amr( codec_private_t *codec_data, void *pkt, \n\t\t\t      pj_size_t pkt_size, const pj_timestamp *ts,\n\t\t\t      unsigned *frame_cnt, pjmedia_frame frames[]);\nstatic pj_status_t pack_amr ( codec_private_t *codec_data,\n\t\t\t      const struct pjmedia_frame_ext *input,\n\t\t\t      unsigned output_buf_len, \n\t\t\t      struct pjmedia_frame *output);\n\n\n/* Passthrough codec implementation descriptions. */\nstatic struct codec_desc {\n    int\t\t     enabled;\t\t/* Is this codec enabled?\t    */\n    const char\t    *name;\t\t/* Codec name.\t\t\t    */\n    pj_uint8_t\t     pt;\t\t/* Payload type.\t\t    */\n    pjmedia_format_id fmt_id;\t\t/* Source format.\t\t    */\n    unsigned\t     clock_rate;\t/* Codec's clock rate.\t\t    */\n    unsigned\t     channel_count;\t/* Codec's channel count.\t    */\n    unsigned\t     samples_per_frame;\t/* Codec's samples count.\t    */\n    unsigned\t     def_bitrate;\t/* Default bitrate of this codec.   */\n    unsigned\t     max_bitrate;\t/* Maximum bitrate of this codec.   */\n    pj_uint8_t\t     frm_per_pkt;\t/* Default num of frames per packet.*/\n    pj_uint8_t\t     vad;\t\t/* VAD enabled/disabled.\t    */\n    pj_uint8_t\t     plc;\t\t/* PLC enabled/disabled.\t    */\n    parse_cb\t     parse;\t\t/* Callback to parse bitstream.\t    */\n    pack_cb\t     pack;\t\t/* Callback to pack bitstream.\t    */\n    pjmedia_codec_fmtp dec_fmtp;\t/* Decoder's fmtp params.\t    */\n}\n\ncodec_desc[] = \n{\n#   if PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR\n    {1, \"AMR\",\t    PJMEDIA_RTP_PT_AMR,       PJMEDIA_FORMAT_AMR,\n\t\t    8000, 1, 160, \n\t\t    7400, 12200, 2, 1, 1,\n\t\t    &parse_amr, &pack_amr\n\t\t    /*, {1, {{{\"octet-align\", 11}, {\"1\", 1}}} } */\n    },\n#   endif\n\n#   if PJMEDIA_HAS_PASSTHROUGH_CODEC_G729\n    {1, \"G729\",\t    PJMEDIA_RTP_PT_G729,      PJMEDIA_FORMAT_G729,\n\t\t    8000, 1,  80,\n\t\t    8000, 8000, 2, 1, 1\n    },\n#   endif\n\n#   if PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC\n    {1, \"iLBC\",\t    PJMEDIA_RTP_PT_ILBC,      PJMEDIA_FORMAT_ILBC,\n\t\t    8000, 1,  240,\n\t\t    13333, 15200, 1, 1, 1,\n\t\t    NULL, NULL,\n\t\t    {1, {{{\"mode\", 4}, {\"30\", 2}}} }\n    },\n#   endif\n\n#   if PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU\n    {1, \"PCMU\",\t    PJMEDIA_RTP_PT_PCMU,      PJMEDIA_FORMAT_PCMU,\n\t\t    8000, 1,  80,\n\t\t    64000, 64000, 2, 1, 1\n    },\n#   endif\n\n#   if PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA\n    {1, \"PCMA\",\t    PJMEDIA_RTP_PT_PCMA,      PJMEDIA_FORMAT_PCMA,\n\t\t    8000, 1,  80,\n\t\t    64000, 64000, 2, 1, 1\n    },\n#   endif\n};\n\n\n#if PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR\n\n#include <pjmedia-codec/amr_helper.h>\n\ntypedef struct amr_settings_t {\n    pjmedia_codec_amr_pack_setting enc_setting;\n    pjmedia_codec_amr_pack_setting dec_setting;\n    pj_int8_t enc_mode;\n} amr_settings_t;\n\n\n/* Pack AMR payload */\nstatic pj_status_t pack_amr ( codec_private_t *codec_data,\n\t\t\t      const struct pjmedia_frame_ext *input,\n\t\t\t      unsigned output_buf_len, \n\t\t\t      struct pjmedia_frame *output)\n{\n    enum {MAX_FRAMES_PER_PACKET = PJMEDIA_MAX_FRAME_DURATION_MS / 20};\n\n    pjmedia_frame frames[MAX_FRAMES_PER_PACKET];\n    amr_settings_t* setting = (amr_settings_t*)codec_data->codec_setting;\n    pjmedia_codec_amr_pack_setting *enc_setting = &setting->enc_setting;\n    pj_uint8_t SID_FT;\n    unsigned i;\n\n    pj_assert(input->subframe_cnt <= MAX_FRAMES_PER_PACKET);\n\n    SID_FT = (pj_uint8_t)(enc_setting->amr_nb? 8 : 9);\n\n    /* Get frames */\n    for (i = 0; i < input->subframe_cnt; ++i) {\n\tpjmedia_frame_ext_subframe *sf;\n\tpjmedia_codec_amr_bit_info *info;\n\tunsigned len;\n\t\n\tsf = pjmedia_frame_ext_get_subframe(input, i);\n\tlen = (sf->bitlen + 7) >> 3;\n\t\n\tinfo = (pjmedia_codec_amr_bit_info*) &frames[i].bit_info;\n\tpj_bzero(info, sizeof(*info));\n\t\n\tif (len == 0) {\n\t    /* DTX */\n\t    info->frame_type = 15;\n\t} else {\n\t    info->frame_type = pjmedia_codec_amr_get_mode2(enc_setting->amr_nb, \n\t\t\t\t\t\t\t   len);\n\t}\n\tinfo->good_quality = 1;\n\tinfo->mode = setting->enc_mode;\n\tif (info->frame_type == SID_FT)\n\t    info->STI = (sf->data[4] >> 4) & 1;\n\n\tframes[i].buf = sf->data;\n\tframes[i].size = len;\n    }\n\n    output->size = output_buf_len;\n\n    return pjmedia_codec_amr_pack(frames, input->subframe_cnt, enc_setting, \n\t\t\t\t  output->buf, &output->size);\n}\n\n\n/* Parse AMR payload into frames. */\nstatic pj_status_t parse_amr(codec_private_t *codec_data, void *pkt, \n\t\t\t     pj_size_t pkt_size, const pj_timestamp *ts,\n\t\t\t     unsigned *frame_cnt, pjmedia_frame frames[])\n{\n    amr_settings_t* s = (amr_settings_t*)codec_data->codec_setting;\n    pjmedia_codec_amr_pack_setting *setting;\n    pj_status_t status;\n    pj_uint8_t cmr;\n\n    setting = &s->dec_setting;\n\n    status = pjmedia_codec_amr_parse(pkt, pkt_size, ts, setting, frames, \n\t\t\t\t     frame_cnt, &cmr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    // CMR is not supported for now. \n    /* Check Change Mode Request. */\n    //if ((setting->amr_nb && cmr <= 7) || (!setting->amr_nb && cmr <= 8)) {\n    //\ts->enc_mode = cmr;\n    //}\n\n    return PJ_SUCCESS;\n}\n\n#endif /* PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR */\n\n\n/*\n * Initialize and register passthrough codec factory to pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_passthrough_init( pjmedia_endpt *endpt )\n{\n    pjmedia_codec_mgr *codec_mgr;\n    pj_str_t codec_name;\n    pj_status_t status;\n\n    if (codec_factory.pool != NULL) {\n\t/* Already initialized. */\n\treturn PJ_EEXISTS;\n    }\n\n    /* Create passthrough codec factory. */\n    codec_factory.base.op = &codec_factory_op;\n    codec_factory.base.factory_data = NULL;\n    codec_factory.endpt = endpt;\n\n    codec_factory.pool = pjmedia_endpt_create_pool(endpt, \"Passthrough codecs\",\n\t\t\t\t\t\t   4000, 4000);\n    if (!codec_factory.pool)\n\treturn PJ_ENOMEM;\n\n    /* Create mutex. */\n    status = pj_mutex_create_simple(codec_factory.pool, \"Passthrough codecs\",\n\t\t\t\t    &codec_factory.mutex);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);\n    if (!codec_mgr) {\n\tstatus = PJ_EINVALIDOP;\n\tgoto on_error;\n    }\n\n    /* Register format match callback. */\n#if PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR\n    pj_cstr(&codec_name, \"AMR\");\n    status = pjmedia_sdp_neg_register_fmt_match_cb(\n\t\t\t\t\t&codec_name,\n\t\t\t\t\t&pjmedia_codec_amr_match_sdp);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n#endif\n\n    /* Suppress compile warning */\n    PJ_UNUSED_ARG(codec_name);\n\n    /* Register codec factory to endpoint. */\n    status = pjmedia_codec_mgr_register_factory(codec_mgr, \n\t\t\t\t\t\t&codec_factory.base);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Done. */\n    return PJ_SUCCESS;\n\non_error:\n    pj_pool_release(codec_factory.pool);\n    codec_factory.pool = NULL;\n    return status;\n}\n\n/*\n * Initialize and register passthrough codec factory to pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_passthrough_init2( \n\t\t      pjmedia_endpt *endpt,\n\t\t      const pjmedia_codec_passthrough_setting *setting)\n{\n    if (codec_factory.pool != NULL) {\n\t/* Already initialized. */\n\treturn PJ_EEXISTS;\n    }\n\n    if (setting != NULL) {\n\tunsigned i;\n\n\t/* Enable/disable codecs based on the specified encoding formats */\n\tfor (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) {\n\t    pj_bool_t enabled = PJ_FALSE;\n\t    unsigned j;\n\n\t    for (j = 0; j < setting->fmt_cnt && !enabled; ++j) {\n\t\tif ((pj_uint32_t)codec_desc[i].fmt_id == setting->fmts[j].id)\n\t\t    enabled = PJ_TRUE;\n\t    }\n\n\t    codec_desc[i].enabled = enabled;\n\t}\n\n#if PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC\n\t/* Update iLBC codec description based on default mode setting. */\n\tfor (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) {\n\t    if (codec_desc[i].enabled && \n\t\tcodec_desc[i].fmt_id == PJMEDIA_FORMAT_ILBC)\n\t    {\n\t\tcodec_desc[i].samples_per_frame = \n\t\t\t\t(setting->ilbc_mode == 20? 160 : 240);\n\t\tcodec_desc[i].def_bitrate = \n\t\t\t\t(setting->ilbc_mode == 20? 15200 : 13333);\n\t\tpj_strset2(&codec_desc[i].dec_fmtp.param[0].val, \n\t\t\t\t(setting->ilbc_mode == 20? \"20\" : \"30\"));\n\t\tbreak;\n\t    }\n\t}\n#endif\n    }\n\n    return pjmedia_codec_passthrough_init(endpt);\n}\n\n/*\n * Unregister passthrough codecs factory from pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_passthrough_deinit(void)\n{\n    pjmedia_codec_mgr *codec_mgr;\n    unsigned i;\n    pj_status_t status;\n\n    if (codec_factory.pool == NULL) {\n\t/* Already deinitialized */\n\treturn PJ_SUCCESS;\n    }\n\n    pj_mutex_lock(codec_factory.mutex);\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(codec_factory.endpt);\n    if (!codec_mgr) {\n\tpj_pool_release(codec_factory.pool);\n\tcodec_factory.pool = NULL;\n\tpj_mutex_unlock(codec_factory.mutex);\n\treturn PJ_EINVALIDOP;\n    }\n\n    /* Unregister passthrough codecs factory. */\n    status = pjmedia_codec_mgr_unregister_factory(codec_mgr,\n\t\t\t\t\t\t  &codec_factory.base);\n    \n    /* Destroy mutex. */\n    pj_mutex_unlock(codec_factory.mutex);\n    pj_mutex_destroy(codec_factory.mutex);\n    codec_factory.mutex = NULL;\n\n    /* Destroy pool. */\n    pj_pool_release(codec_factory.pool);\n    codec_factory.pool = NULL;\n\n    /* Re-enable all codecs in the codec_desc. */\n    for (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) {\n\tcodec_desc[i].enabled = PJ_TRUE;\n    }\n\n    return status;\n}\n\n/* \n * Check if factory can allocate the specified codec. \n */\nstatic pj_status_t test_alloc( pjmedia_codec_factory *factory, \n\t\t\t       const pjmedia_codec_info *info )\n{\n    unsigned i;\n\n    PJ_UNUSED_ARG(factory);\n\n    /* Type MUST be audio. */\n    if (info->type != PJMEDIA_TYPE_AUDIO)\n\treturn PJMEDIA_CODEC_EUNSUP;\n\n    for (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) {\n\tpj_str_t name = pj_str((char*)codec_desc[i].name);\n\tif ((pj_stricmp(&info->encoding_name, &name) == 0) &&\n\t    (info->clock_rate == (unsigned)codec_desc[i].clock_rate) &&\n\t    (info->channel_cnt == (unsigned)codec_desc[i].channel_count) &&\n\t    (codec_desc[i].enabled))\n\t{\n\t    return PJ_SUCCESS;\n\t}\n    }\n    \n    /* Unsupported, or mode is disabled. */\n    return PJMEDIA_CODEC_EUNSUP;\n}\n\n/*\n * Generate default attribute.\n */\nstatic pj_status_t default_attr ( pjmedia_codec_factory *factory, \n\t\t\t\t  const pjmedia_codec_info *id, \n\t\t\t\t  pjmedia_codec_param *attr )\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(factory==&codec_factory.base, PJ_EINVAL);\n\n    pj_bzero(attr, sizeof(pjmedia_codec_param));\n\n    for (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) {\n\tpj_str_t name = pj_str((char*)codec_desc[i].name);\n\tif ((pj_stricmp(&id->encoding_name, &name) == 0) &&\n\t    (id->clock_rate == (unsigned)codec_desc[i].clock_rate) &&\n\t    (id->channel_cnt == (unsigned)codec_desc[i].channel_count) &&\n\t    (id->pt == (unsigned)codec_desc[i].pt))\n\t{\n\t    attr->info.pt = (pj_uint8_t)id->pt;\n\t    attr->info.channel_cnt = codec_desc[i].channel_count;\n\t    attr->info.clock_rate = codec_desc[i].clock_rate;\n\t    attr->info.avg_bps = codec_desc[i].def_bitrate;\n\t    attr->info.max_bps = codec_desc[i].max_bitrate;\n\t    attr->info.pcm_bits_per_sample = 16;\n\t    attr->info.frm_ptime =  (pj_uint16_t)\n\t\t\t\t    (codec_desc[i].samples_per_frame * 1000 / \n\t\t\t\t    codec_desc[i].channel_count / \n\t\t\t\t    codec_desc[i].clock_rate);\n\t    attr->info.fmt_id = codec_desc[i].fmt_id;\n\n\t    /* Default flags. */\n\t    attr->setting.frm_per_pkt = codec_desc[i].frm_per_pkt;\n\t    attr->setting.plc = codec_desc[i].plc;\n\t    attr->setting.penh= 0;\n\t    attr->setting.vad = codec_desc[i].vad;\n\t    attr->setting.cng = attr->setting.vad;\n\t    attr->setting.dec_fmtp = codec_desc[i].dec_fmtp;\n\n\t    if (attr->setting.vad == 0) {\n#if PJMEDIA_HAS_PASSTHROUGH_CODEC_G729\n\t\tif (id->pt == PJMEDIA_RTP_PT_G729) {\n\t\t    /* Signal G729 Annex B is being disabled */\n\t\t    attr->setting.dec_fmtp.cnt = 1;\n\t\t    pj_strset2(&attr->setting.dec_fmtp.param[0].name, \"annexb\");\n\t\t    pj_strset2(&attr->setting.dec_fmtp.param[0].val, \"no\");\n\t\t}\n#endif\n\t    }\n\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    return PJMEDIA_CODEC_EUNSUP;\n}\n\n/*\n * Enum codecs supported by this factory.\n */\nstatic pj_status_t enum_codecs( pjmedia_codec_factory *factory, \n\t\t\t\tunsigned *count, \n\t\t\t\tpjmedia_codec_info codecs[])\n{\n    unsigned max;\n    unsigned i;\n\n    PJ_UNUSED_ARG(factory);\n    PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);\n\n    max = *count;\n    \n    for (i = 0, *count = 0; i < PJ_ARRAY_SIZE(codec_desc) && *count < max; ++i) \n    {\n\tif (!codec_desc[i].enabled)\n\t    continue;\n\n\tpj_bzero(&codecs[*count], sizeof(pjmedia_codec_info));\n\tcodecs[*count].encoding_name = pj_str((char*)codec_desc[i].name);\n\tcodecs[*count].pt = codec_desc[i].pt;\n\tcodecs[*count].type = PJMEDIA_TYPE_AUDIO;\n\tcodecs[*count].clock_rate = codec_desc[i].clock_rate;\n\tcodecs[*count].channel_cnt = codec_desc[i].channel_count;\n\n\t++*count;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Allocate a new codec instance.\n */\nstatic pj_status_t alloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\tconst pjmedia_codec_info *id,\n\t\t\t\tpjmedia_codec **p_codec)\n{\n    codec_private_t *codec_data;\n    pjmedia_codec *codec;\n    int idx;\n    pj_pool_t *pool;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &codec_factory.base, PJ_EINVAL);\n\n    pj_mutex_lock(codec_factory.mutex);\n\n    /* Find codec's index */\n    idx = -1;\n    for (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) {\n\tpj_str_t name = pj_str((char*)codec_desc[i].name);\n\tif ((pj_stricmp(&id->encoding_name, &name) == 0) &&\n\t    (id->clock_rate == (unsigned)codec_desc[i].clock_rate) &&\n\t    (id->channel_cnt == (unsigned)codec_desc[i].channel_count) &&\n\t    (codec_desc[i].enabled))\n\t{\n\t    idx = i;\n\t    break;\n\t}\n    }\n    if (idx == -1) {\n\t*p_codec = NULL;\n\treturn PJMEDIA_CODEC_EUNSUP;\n    }\n\n    /* Create pool for codec instance */\n    pool = pjmedia_endpt_create_pool(codec_factory.endpt, \"passthroughcodec\",\n\t\t\t\t     512, 512);\n    codec = PJ_POOL_ZALLOC_T(pool, pjmedia_codec);\n    codec->op = &codec_op;\n    codec->factory = factory;\n    codec->codec_data = PJ_POOL_ZALLOC_T(pool, codec_private_t);\n    codec_data = (codec_private_t*) codec->codec_data;\n    codec_data->pool = pool;\n    codec_data->codec_idx = idx;\n\n    pj_mutex_unlock(codec_factory.mutex);\n\n    *p_codec = codec;\n    return PJ_SUCCESS;\n}\n\n/*\n * Free codec.\n */\nstatic pj_status_t dealloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t  pjmedia_codec *codec )\n{\n    codec_private_t *codec_data;\n\n    PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &codec_factory.base, PJ_EINVAL);\n\n    /* Close codec, if it's not closed. */\n    codec_data = (codec_private_t*) codec->codec_data;\n    codec_close(codec);\n\n    pj_pool_release(codec_data->pool);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Init codec.\n */\nstatic pj_status_t codec_init( pjmedia_codec *codec, \n\t\t\t       pj_pool_t *pool )\n{\n    PJ_UNUSED_ARG(codec);\n    PJ_UNUSED_ARG(pool);\n    return PJ_SUCCESS;\n}\n\n/*\n * Open codec.\n */\nstatic pj_status_t codec_open( pjmedia_codec *codec, \n\t\t\t       pjmedia_codec_param *attr )\n{\n    codec_private_t *codec_data = (codec_private_t*) codec->codec_data;\n    struct codec_desc *desc = &codec_desc[codec_data->codec_idx];\n    pj_pool_t *pool;\n    int i, j;\n\n    pool = codec_data->pool;\n\n    /* Cache samples per frame value */\n    codec_data->samples_per_frame = desc->samples_per_frame;\n\n    /* Calculate bitstream size */\n    i = attr->info.avg_bps * codec_data->samples_per_frame;\n    j = desc->clock_rate << 3;\n    codec_data->avg_frame_size = (pj_uint16_t)(i / j);\n    if (i % j) ++codec_data->avg_frame_size;\n\n#if PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR\n    /* Init AMR settings */\n    if (desc->pt == PJMEDIA_RTP_PT_AMR || desc->pt == PJMEDIA_RTP_PT_AMRWB) {\n\tamr_settings_t *s;\n\tpj_uint8_t octet_align = 0;\n\tpj_int8_t enc_mode;\n\t\n\tenc_mode = pjmedia_codec_amr_get_mode(attr->info.avg_bps);\n\tpj_assert(enc_mode >= 0 && enc_mode <= 8);\n\n\tfor (i = 0; i < attr->setting.dec_fmtp.cnt; ++i) {\n\t    const pj_str_t STR_FMTP_OCTET_ALIGN = {\"octet-align\", 11};\n\t    \n\t    /* Fetch octet-align setting. It should be fine to fetch only \n\t     * the decoder, since encoder & decoder must use the same setting \n\t     * (RFC 4867 section 8.3.1).\n\t     */\n\t    if (pj_stricmp(&attr->setting.dec_fmtp.param[i].name, \n\t\t\t   &STR_FMTP_OCTET_ALIGN) == 0)\n\t    {\n\t\toctet_align=(pj_uint8_t)\n\t\t\t    (pj_strtoul(&attr->setting.dec_fmtp.param[i].val));\n\t\tbreak;\n\t    }\n\t}\n\n\tfor (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {\n\t    const pj_str_t STR_FMTP_MODE_SET = {\"mode-set\", 8};\n\n\t    /* mode-set, encoding mode is chosen based on local default mode \n\t     * setting:\n\t     * - if local default mode is included in the mode-set, use it\n\t     * - otherwise, find the closest mode to local default mode;\n\t     *   if there are two closest modes, prefer to use the higher\n\t     *   one, e.g: local default mode is 4, the mode-set param\n\t     *   contains '2,3,5,6', then 5 will be chosen.\n\t     */\n\t    if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, \n\t\t\t   &STR_FMTP_MODE_SET) == 0)\n\t    {\n\t\tconst char *p;\n\t\tpj_size_t l;\n\t\tpj_int8_t diff = 99;\n\t\t\n\t\tp = pj_strbuf(&attr->setting.enc_fmtp.param[i].val);\n\t\tl = pj_strlen(&attr->setting.enc_fmtp.param[i].val);\n\n\t\twhile (l--) {\n\t\t    if ((desc->pt==PJMEDIA_RTP_PT_AMR && *p>='0' && *p<='7') ||\n\t\t        (desc->pt==PJMEDIA_RTP_PT_AMRWB && *p>='0' && *p<='8'))\n\t\t    {\n\t\t\tpj_int8_t tmp = (pj_int8_t)(*p - '0' - enc_mode);\n\n\t\t\tif (PJ_ABS(diff) > PJ_ABS(tmp) || \n\t\t\t    (PJ_ABS(diff) == PJ_ABS(tmp) && tmp > diff))\n\t\t\t{\n\t\t\t    diff = tmp;\n\t\t\t    if (diff == 0) break;\n\t\t\t}\n\t\t    }\n\t\t    ++p;\n\t\t}\n\n\t\tif (diff == 99)\n\t\t    return PJMEDIA_CODEC_EFAILED;\n\n\t\tenc_mode = (pj_int8_t)(enc_mode + diff);\n\n\t\tbreak;\n\t    }\n\t}\n\n\ts = PJ_POOL_ZALLOC_T(pool, amr_settings_t);\n\tcodec_data->codec_setting = s;\n\n\ts->enc_mode = enc_mode;\n\tif (s->enc_mode < 0)\n\t    return PJMEDIA_CODEC_EINMODE;\n\n\ts->enc_setting.amr_nb = (pj_uint8_t)(desc->pt == PJMEDIA_RTP_PT_AMR);\n\ts->enc_setting.octet_aligned = octet_align;\n\ts->enc_setting.reorder = PJ_FALSE; /* Note this! passthrough codec\n\t\t\t\t\t      doesn't do sensitivity bits \n\t\t\t\t\t      reordering */\n\ts->enc_setting.cmr = 15;\n\t\n\ts->dec_setting.amr_nb = (pj_uint8_t)(desc->pt == PJMEDIA_RTP_PT_AMR);\n\ts->dec_setting.octet_aligned = octet_align;\n\ts->dec_setting.reorder = PJ_FALSE; /* Note this! passthrough codec\n\t\t\t\t\t      doesn't do sensitivity bits \n\t\t\t\t\t      reordering */\n\t\n\t/* Return back bitrate info to application */\n\tattr->info.avg_bps = s->enc_setting.amr_nb?\n\t\t\t     pjmedia_codec_amrnb_bitrates[s->enc_mode]:\n\t\t\t     pjmedia_codec_amrwb_bitrates[s->enc_mode];\n    }\n#endif\n\n#if PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC\n    /* Init iLBC settings */\n    if (desc->pt == PJMEDIA_RTP_PT_ILBC)\n    {\n\tenum { DEFAULT_MODE = 30 };\n\tstatic pj_str_t STR_MODE = {\"mode\", 4};\n\tpj_uint16_t dec_fmtp_mode = DEFAULT_MODE, \n\t\t    enc_fmtp_mode = DEFAULT_MODE;\n\n\t/* Get decoder mode */\n\tfor (i = 0; i < attr->setting.dec_fmtp.cnt; ++i) {\n\t    if (pj_stricmp(&attr->setting.dec_fmtp.param[i].name, &STR_MODE) == 0)\n\t    {\n\t\tdec_fmtp_mode = (pj_uint16_t)\n\t\t\t\tpj_strtoul(&attr->setting.dec_fmtp.param[i].val);\n\t\tbreak;\n\t    }\n\t}\n\n\t/* Decoder mode must be set */\n\tPJ_ASSERT_RETURN(dec_fmtp_mode == 20 || dec_fmtp_mode == 30, \n\t\t\t PJMEDIA_CODEC_EINMODE);\n\n\t/* Get encoder mode */\n\tfor (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {\n\t    if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_MODE) == 0)\n\t    {\n\t\tenc_fmtp_mode = (pj_uint16_t)\n\t\t\t\tpj_strtoul(&attr->setting.enc_fmtp.param[i].val);\n\t\tbreak;\n\t    }\n\t}\n\n\tPJ_ASSERT_RETURN(enc_fmtp_mode==20 || enc_fmtp_mode==30, \n\t\t\t PJMEDIA_CODEC_EINMODE);\n\n\t/* Both sides of a bi-directional session MUST use the same \"mode\" value.\n\t * In this point, possible values are only 20 or 30, so when encoder and\n\t * decoder modes are not same, just use the default mode, it is 30.\n\t */\n\tif (enc_fmtp_mode != dec_fmtp_mode) {\n\t    enc_fmtp_mode = dec_fmtp_mode = DEFAULT_MODE;\n\t    PJ_LOG(4,(pool->obj_name, \n\t\t      \"Normalized iLBC encoder and decoder modes to %d\", \n\t\t      DEFAULT_MODE));\n\t}\n\n\t/* Update some attributes based on negotiated mode. */\n\tattr->info.avg_bps = (dec_fmtp_mode == 30? 13333 : 15200);\n\tattr->info.frm_ptime = dec_fmtp_mode;\n\n\t/* Override average frame size */\n\tcodec_data->avg_frame_size = (dec_fmtp_mode == 30? 50 : 38);\n\n\t/* Override samples per frame */\n\tcodec_data->samples_per_frame = (dec_fmtp_mode == 30? 240 : 160);\n    }\n#endif\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Close codec.\n */\nstatic pj_status_t codec_close( pjmedia_codec *codec )\n{\n    PJ_UNUSED_ARG(codec);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Modify codec settings.\n */\nstatic pj_status_t codec_modify( pjmedia_codec *codec, \n\t\t\t\t const pjmedia_codec_param *attr )\n{\n    /* Not supported yet. */\n    PJ_UNUSED_ARG(codec);\n    PJ_UNUSED_ARG(attr);\n\n    return PJ_ENOTSUP;\n}\n\n/*\n * Get frames in the packet.\n */\nstatic pj_status_t codec_parse( pjmedia_codec *codec,\n\t\t\t\tvoid *pkt,\n\t\t\t\tpj_size_t pkt_size,\n\t\t\t\tconst pj_timestamp *ts,\n\t\t\t\tunsigned *frame_cnt,\n\t\t\t\tpjmedia_frame frames[])\n{\n    codec_private_t *codec_data = (codec_private_t*) codec->codec_data;\n    struct codec_desc *desc = &codec_desc[codec_data->codec_idx];\n    unsigned count = 0;\n\n    PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);\n\n    if (desc->parse != NULL) {\n\treturn desc->parse(codec_data, pkt,  pkt_size, ts, frame_cnt, frames);\n    }\n\n    while (pkt_size >= codec_data->avg_frame_size && count < *frame_cnt) {\n\tframes[count].type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframes[count].buf = pkt;\n\tframes[count].size = codec_data->avg_frame_size;\n\tframes[count].timestamp.u64 = ts->u64 + \n\t\t\t\t      count * codec_data->samples_per_frame;\n\n\tpkt = (pj_uint8_t*)pkt + codec_data->avg_frame_size;\n\tpkt_size -= codec_data->avg_frame_size;\n\n\t++count;\n    }\n\n    if (pkt_size && count < *frame_cnt) {\n\tframes[count].type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframes[count].buf = pkt;\n\tframes[count].size = pkt_size;\n\tframes[count].timestamp.u64 = ts->u64 + \n\t\t\t\t       count * codec_data->samples_per_frame;\n\t++count;\n    }\n\n    *frame_cnt = count;\n    return PJ_SUCCESS;\n}\n\n/*\n * Encode frames.\n */\nstatic pj_status_t codec_encode( pjmedia_codec *codec, \n\t\t\t\t const struct pjmedia_frame *input,\n\t\t\t\t unsigned output_buf_len, \n\t\t\t\t struct pjmedia_frame *output)\n{\n    codec_private_t *codec_data = (codec_private_t*) codec->codec_data;\n    struct codec_desc *desc = &codec_desc[codec_data->codec_idx];\n    const pjmedia_frame_ext *input_ = (const pjmedia_frame_ext*) input;\n\n    pj_assert(input && input->type == PJMEDIA_FRAME_TYPE_EXTENDED);\n\n    if (desc->pack != NULL) {\n\tdesc->pack(codec_data, input_, output_buf_len, output);\n    } else {\n\tif (input_->subframe_cnt == 0) {\n\t    /* DTX */\n\t    output->buf = NULL;\n\t    output->size = 0;\n\t    output->type = PJMEDIA_FRAME_TYPE_NONE;\n\t} else {\n\t    unsigned i;\n\t    pj_uint8_t *p = output->buf;\n\n\t    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\t    output->size = 0;\n\t    \n\t    for (i = 0; i < input_->subframe_cnt; ++i) {\n\t\tpjmedia_frame_ext_subframe *sf;\n\t\tunsigned sf_len;\n\n\t\tsf = pjmedia_frame_ext_get_subframe(input_, i);\n\t\tpj_assert(sf);\n\n\t\tsf_len = (sf->bitlen + 7) >> 3;\n\n\t\tpj_memcpy(p, sf->data, sf_len);\n\t\tp += sf_len;\n\t\toutput->size += sf_len;\n\n\t\t/* If there is SID or DTX frame, break the loop. */\n\t\tif (desc->pt == PJMEDIA_RTP_PT_G729 && \n\t\t    sf_len < codec_data->avg_frame_size)\n\t\t{\n\t\t    break;\n\t\t}\n\t\t\n\t    }\n\t}\n    }\n\n    output->timestamp = input->timestamp;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Decode frame.\n */\nstatic pj_status_t codec_decode( pjmedia_codec *codec, \n\t\t\t\t const struct pjmedia_frame *input,\n\t\t\t\t unsigned output_buf_len, \n\t\t\t\t struct pjmedia_frame *output)\n{\n    codec_private_t *codec_data = (codec_private_t*) codec->codec_data;\n#if PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR\n    struct codec_desc *desc = &codec_desc[codec_data->codec_idx];\n#endif\n    pjmedia_frame_ext *output_ = (pjmedia_frame_ext*) output;\n\n    pj_assert(input);\n    PJ_UNUSED_ARG(output_buf_len);\n\n#if PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR\n    /* Need to rearrange the AMR bitstream, since the bitstream may not be \n     * started from bit 0 or may need to be reordered from sensitivity order \n     * into encoder bits order.\n     */\n    if (desc->pt == PJMEDIA_RTP_PT_AMR || desc->pt == PJMEDIA_RTP_PT_AMRWB) {\n\tpjmedia_frame input_;\n\tpjmedia_codec_amr_pack_setting *setting;\n\n\tsetting = &((amr_settings_t*)codec_data->codec_setting)->dec_setting;\n\n\tinput_ = *input;\n\tpjmedia_codec_amr_predecode(input, setting, &input_);\n\t\n\tpjmedia_frame_ext_append_subframe(output_, input_.buf, \n\t\t\t\t\t  (pj_uint16_t)(input_.size << 3),\n\t\t\t\t\t  (pj_uint16_t)codec_data->samples_per_frame);\n\toutput->timestamp = input->timestamp;\n\t\n\treturn PJ_SUCCESS;\n    }\n#endif\n    \n    pjmedia_frame_ext_append_subframe(output_, input->buf, \n\t\t\t\t      (pj_uint16_t)(input->size << 3),\n\t\t\t\t      (pj_uint16_t)codec_data->samples_per_frame);\n    output->timestamp = input->timestamp;\n\n    return PJ_SUCCESS;\n}\n\n/* \n * Recover lost frame.\n */\nstatic pj_status_t codec_recover( pjmedia_codec *codec, \n\t\t\t\t  unsigned output_buf_len, \n\t\t\t\t  struct pjmedia_frame *output)\n{\n    codec_private_t *codec_data = (codec_private_t*) codec->codec_data;\n    pjmedia_frame_ext *output_ = (pjmedia_frame_ext*) output;\n\n    PJ_UNUSED_ARG(output_buf_len);\n\n    pjmedia_frame_ext_append_subframe(output_, NULL, 0,\n\t\t\t\t      (pj_uint16_t)codec_data->samples_per_frame);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_HAS_PASSTHROUGH_CODECS */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/speex_codec.c",
    "content": "/* $Id: speex_codec.c 3664 2011-07-19 03:42:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pjmedia-codec/speex.h>\n#include <pjmedia/codec.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/endpoint.h>\n#include <pjmedia/port.h>\n#include <speex/speex.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/os.h>\n\n/*\n * Only build this file if PJMEDIA_HAS_SPEEX_CODEC != 0\n */\n#if defined(PJMEDIA_HAS_SPEEX_CODEC) && PJMEDIA_HAS_SPEEX_CODEC!=0\n\n\n#define THIS_FILE   \"speex_codec.c\"\n\n/* Prototypes for Speex factory */\nstatic pj_status_t spx_test_alloc( pjmedia_codec_factory *factory, \n\t\t\t\t   const pjmedia_codec_info *id );\nstatic pj_status_t spx_default_attr( pjmedia_codec_factory *factory, \n\t\t\t\t     const pjmedia_codec_info *id, \n\t\t\t\t     pjmedia_codec_param *attr );\nstatic pj_status_t spx_enum_codecs( pjmedia_codec_factory *factory, \n\t\t\t\t    unsigned *count, \n\t\t\t\t    pjmedia_codec_info codecs[]);\nstatic pj_status_t spx_alloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t    const pjmedia_codec_info *id, \n\t\t\t\t    pjmedia_codec **p_codec);\nstatic pj_status_t spx_dealloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t      pjmedia_codec *codec );\n\n/* Prototypes for Speex implementation. */\nstatic pj_status_t  spx_codec_init( pjmedia_codec *codec, \n\t\t\t\t    pj_pool_t *pool );\nstatic pj_status_t  spx_codec_open( pjmedia_codec *codec, \n\t\t\t\t    pjmedia_codec_param *attr );\nstatic pj_status_t  spx_codec_close( pjmedia_codec *codec );\nstatic pj_status_t  spx_codec_modify(pjmedia_codec *codec, \n\t\t\t\t     const pjmedia_codec_param *attr );\nstatic pj_status_t  spx_codec_parse( pjmedia_codec *codec,\n\t\t\t\t     void *pkt,\n\t\t\t\t     pj_size_t pkt_size,\n\t\t\t\t     const pj_timestamp *ts,\n\t\t\t\t     unsigned *frame_cnt,\n\t\t\t\t     pjmedia_frame frames[]);\nstatic pj_status_t  spx_codec_encode( pjmedia_codec *codec, \n\t\t\t\t      const struct pjmedia_frame *input,\n\t\t\t\t      unsigned output_buf_len, \n\t\t\t\t      struct pjmedia_frame *output);\nstatic pj_status_t  spx_codec_decode( pjmedia_codec *codec, \n\t\t\t\t      const struct pjmedia_frame *input,\n\t\t\t\t      unsigned output_buf_len, \n\t\t\t\t      struct pjmedia_frame *output);\nstatic pj_status_t  spx_codec_recover(pjmedia_codec *codec, \n\t\t\t\t      unsigned output_buf_len, \n\t\t\t\t      struct pjmedia_frame *output);\n\n/* Definition for Speex codec operations. */\nstatic pjmedia_codec_op spx_op = \n{\n    &spx_codec_init,\n    &spx_codec_open,\n    &spx_codec_close,\n    &spx_codec_modify,\n    &spx_codec_parse,\n    &spx_codec_encode,\n    &spx_codec_decode,\n    &spx_codec_recover\n};\n\n/* Definition for Speex codec factory operations. */\nstatic pjmedia_codec_factory_op spx_factory_op =\n{\n    &spx_test_alloc,\n    &spx_default_attr,\n    &spx_enum_codecs,\n    &spx_alloc_codec,\n    &spx_dealloc_codec,\n    &pjmedia_codec_speex_deinit\n};\n\n/* Index to Speex parameter. */\nenum\n{\n    PARAM_NB,\t/* Index for narrowband parameter.\t*/\n    PARAM_WB,\t/* Index for wideband parameter.\t*/\n    PARAM_UWB,\t/* Index for ultra-wideband parameter\t*/\n};\n\n/* Speex default parameter */\nstruct speex_param\n{\n    int\t\t     enabled;\t\t/* Is this mode enabled?\t    */\n    const SpeexMode *mode;\t\t/* Speex mode.\t\t\t    */\n    int\t\t     pt;\t\t/* Payload type.\t\t    */\n    unsigned\t     clock_rate;\t/* Default sampling rate to be used.*/\n    int\t\t     quality;\t\t/* Default encoder quality.\t    */\n    int\t\t     complexity;\t/* Default encoder complexity.\t    */\n    int\t\t     samples_per_frame;\t/* Samples per frame.\t\t    */\n    int\t\t     framesize;\t\t/* Frame size for current mode.\t    */\n    int\t\t     bitrate;\t\t/* Bit rate for current mode.\t    */\n    int\t\t     max_bitrate;\t/* Max bit rate for current mode.   */\n};\n\n/* Speex factory */\nstatic struct spx_factory\n{\n    pjmedia_codec_factory    base;\n    pjmedia_endpt\t    *endpt;\n    pj_pool_t\t\t    *pool;\n    pj_mutex_t\t\t    *mutex;\n    pjmedia_codec\t     codec_list;\n    struct speex_param\t     speex_param[3];\n\n} spx_factory;\n\n/* Speex codec private data. */\nstruct spx_private\n{\n    int\t\t\t param_id;\t    /**< Index to speex param.\t*/\n\n    void\t\t*enc;\t\t    /**< Encoder state.\t\t*/\n    SpeexBits\t\t enc_bits;\t    /**< Encoder bits.\t\t*/\n    void\t\t*dec;\t\t    /**< Decoder state.\t\t*/\n    SpeexBits\t\t dec_bits;\t    /**< Decoder bits.\t\t*/\n};\n\n\n/*\n * Get codec bitrate and frame size.\n */\nstatic pj_status_t get_speex_info( struct speex_param *p )\n{\n    void *state;\n    int tmp;\n\n    /* Create temporary encoder */\n    state = speex_encoder_init(p->mode);\n    if (!state)\n\treturn PJMEDIA_CODEC_EFAILED;\n\n    /* Set the quality */\n    if (p->quality != -1)\n\tspeex_encoder_ctl(state, SPEEX_SET_QUALITY, &p->quality);\n\n    /* Sampling rate. */\n    speex_encoder_ctl(state, SPEEX_SET_SAMPLING_RATE, &p->clock_rate);\n\n    /* VAD off to have max bitrate */\n    tmp = 0;\n    speex_encoder_ctl(state, SPEEX_SET_VAD, &tmp);\n\n    /* Complexity. */\n    if (p->complexity != -1)\n\tspeex_encoder_ctl(state, SPEEX_SET_COMPLEXITY, &p->complexity);\n\n    /* Now get the frame size */\n    speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &p->samples_per_frame);\n\n    /* Now get the average bitrate */\n    speex_encoder_ctl(state, SPEEX_GET_BITRATE, &p->bitrate);\n\n    /* Calculate framesize. */\n    p->framesize = p->bitrate * 20 / 1000;\n\n    /* Now get the maximum bitrate by using maximum quality (=10) */\n    tmp = 10;\n    speex_encoder_ctl(state, SPEEX_SET_QUALITY, &tmp);\n    speex_encoder_ctl(state, SPEEX_GET_BITRATE, &p->max_bitrate);\n\n    /* Destroy encoder. */\n    speex_encoder_destroy(state);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Initialize and register Speex codec factory to pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_speex_init( pjmedia_endpt *endpt,\n\t\t\t\t\t      unsigned options,\n\t\t\t\t\t      int quality,\n\t\t\t\t\t      int complexity )\n{\n    pjmedia_codec_mgr *codec_mgr;\n    unsigned i;\n    pj_status_t status;\n\n    if (spx_factory.pool != NULL) {\n\t/* Already initialized. */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Get defaults */\n    if (quality < 0) quality = PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY;\n    if (complexity < 0) complexity = PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY;\n\n    /* Validate quality & complexity */\n    PJ_ASSERT_RETURN(quality >= 0 && quality <= 10, PJ_EINVAL);\n    PJ_ASSERT_RETURN(complexity >= 1 && complexity <= 10, PJ_EINVAL);\n\n    /* Create Speex codec factory. */\n    spx_factory.base.op = &spx_factory_op;\n    spx_factory.base.factory_data = NULL;\n    spx_factory.endpt = endpt;\n\n    spx_factory.pool = pjmedia_endpt_create_pool(endpt, \"speex\", \n\t\t\t\t\t\t       4000, 4000);\n    if (!spx_factory.pool)\n\treturn PJ_ENOMEM;\n\n    pj_list_init(&spx_factory.codec_list);\n\n    /* Create mutex. */\n    status = pj_mutex_create_simple(spx_factory.pool, \"speex\", \n\t\t\t\t    &spx_factory.mutex);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Initialize default Speex parameter. */\n    spx_factory.speex_param[PARAM_NB].enabled = \n\t((options & PJMEDIA_SPEEX_NO_NB) == 0);\n    spx_factory.speex_param[PARAM_NB].pt = PJMEDIA_RTP_PT_SPEEX_NB;\n    spx_factory.speex_param[PARAM_NB].mode = speex_lib_get_mode(SPEEX_MODEID_NB);\n    spx_factory.speex_param[PARAM_NB].clock_rate = 8000;\n    spx_factory.speex_param[PARAM_NB].quality = quality;\n    spx_factory.speex_param[PARAM_NB].complexity = complexity;\n\n    spx_factory.speex_param[PARAM_WB].enabled = \n\t((options & PJMEDIA_SPEEX_NO_WB) == 0);\n    spx_factory.speex_param[PARAM_WB].pt = PJMEDIA_RTP_PT_SPEEX_WB;\n    spx_factory.speex_param[PARAM_WB].mode = speex_lib_get_mode(SPEEX_MODEID_WB);\n    spx_factory.speex_param[PARAM_WB].clock_rate = 16000;\n    spx_factory.speex_param[PARAM_WB].quality = quality;\n    spx_factory.speex_param[PARAM_WB].complexity = complexity;\n\n    spx_factory.speex_param[PARAM_UWB].enabled = \n\t((options & PJMEDIA_SPEEX_NO_UWB) == 0);\n    spx_factory.speex_param[PARAM_UWB].pt = PJMEDIA_RTP_PT_SPEEX_UWB;\n    spx_factory.speex_param[PARAM_UWB].mode = speex_lib_get_mode(SPEEX_MODEID_UWB);\n    spx_factory.speex_param[PARAM_UWB].clock_rate = 32000;\n    spx_factory.speex_param[PARAM_UWB].quality = quality;\n    spx_factory.speex_param[PARAM_UWB].complexity = complexity;\n\n    /* Somehow quality <=4 is broken in linux. */\n    if (quality <= 4 && quality >= 0) {\n\tPJ_LOG(5,(THIS_FILE, \"Adjusting quality to 5 for uwb\"));\n\tspx_factory.speex_param[PARAM_UWB].quality = 5;\n    }\n\n    /* Get codec framesize and avg bitrate for each mode. */\n    for (i=0; i<PJ_ARRAY_SIZE(spx_factory.speex_param); ++i) {\n\tstatus = get_speex_info(&spx_factory.speex_param[i]);\n    }\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);\n    if (!codec_mgr) {\n\tstatus = PJ_EINVALIDOP;\n\tgoto on_error;\n    }\n\n    /* Register codec factory to endpoint. */\n    status = pjmedia_codec_mgr_register_factory(codec_mgr, \n\t\t\t\t\t\t&spx_factory.base);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Done. */\n    return PJ_SUCCESS;\n\non_error:\n    pj_pool_release(spx_factory.pool);\n    spx_factory.pool = NULL;\n    return status;\n}\n\n\n/*\n * Initialize with default settings.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_speex_init_default(pjmedia_endpt *endpt)\n{\n    return pjmedia_codec_speex_init(endpt, 0, -1, -1);\n}\n\n/*\n * Change the settings of Speex codec.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_speex_set_param(unsigned clock_rate,\n\t\t\t\t\t\t  int quality,\n\t\t\t\t\t\t  int complexity)\n{\n    unsigned i;\n\n    /* Get defaults */\n    if (quality < 0) quality = PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY;\n    if (complexity < 0) complexity = PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY;\n\n    /* Validate quality & complexity */\n    PJ_ASSERT_RETURN(quality >= 0 && quality <= 10, PJ_EINVAL);\n    PJ_ASSERT_RETURN(complexity >= 1 && complexity <= 10, PJ_EINVAL);\n\n    /* Apply the settings */\n    for (i=0; i<PJ_ARRAY_SIZE(spx_factory.speex_param); ++i) {\n\tif (spx_factory.speex_param[i].clock_rate == clock_rate) {\n\t    pj_status_t status;\n\n\t    spx_factory.speex_param[i].quality = quality;\n\t    spx_factory.speex_param[i].complexity = complexity;\n\n\t    /* Somehow quality<=4 is broken in linux. */\n\t    if (i == PARAM_UWB && quality <= 4 && quality >= 0) {\n\t\tPJ_LOG(5,(THIS_FILE, \"Adjusting quality to 5 for uwb\"));\n\t\tspx_factory.speex_param[PARAM_UWB].quality = 5;\n\t    }\n\n\t    status = get_speex_info(&spx_factory.speex_param[i]);\n\n\t    return status;\n\t}\n    }\n\n    return PJ_EINVAL;\n}\n\n/*\n * Unregister Speex codec factory from pjmedia endpoint and deinitialize\n * the Speex codec library.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_speex_deinit(void)\n{\n    pjmedia_codec_mgr *codec_mgr;\n    pj_status_t status;\n\n    if (spx_factory.pool == NULL) {\n\t/* Already deinitialized */\n\treturn PJ_SUCCESS;\n    }\n\n    pj_mutex_lock(spx_factory.mutex);\n\n    /* We don't want to deinit if there's outstanding codec. */\n    /* This is silly, as we'll always have codec in the list if\n       we ever allocate a codec! A better behavior maybe is to \n       deallocate all codecs in the list.\n    if (!pj_list_empty(&spx_factory.codec_list)) {\n\tpj_mutex_unlock(spx_factory.mutex);\n\treturn PJ_EBUSY;\n    }\n    */\n\n    /* Get the codec manager. */\n    codec_mgr = pjmedia_endpt_get_codec_mgr(spx_factory.endpt);\n    if (!codec_mgr) {\n\tpj_pool_release(spx_factory.pool);\n\tspx_factory.pool = NULL;\n\treturn PJ_EINVALIDOP;\n    }\n\n    /* Unregister Speex codec factory. */\n    status = pjmedia_codec_mgr_unregister_factory(codec_mgr,\n\t\t\t\t\t\t  &spx_factory.base);\n    \n    /* Destroy mutex. */\n    pj_mutex_unlock(spx_factory.mutex);\n    pj_mutex_destroy(spx_factory.mutex);\n    spx_factory.mutex = NULL;\n\n    /* Destroy pool. */\n    pj_pool_release(spx_factory.pool);\n    spx_factory.pool = NULL;\n\n    return status;\n}\n\n/* \n * Check if factory can allocate the specified codec. \n */\nstatic pj_status_t spx_test_alloc( pjmedia_codec_factory *factory, \n\t\t\t\t   const pjmedia_codec_info *info )\n{\n    const pj_str_t speex_tag = { \"speex\", 5};\n    unsigned i;\n\n    PJ_UNUSED_ARG(factory);\n\n    /* Type MUST be audio. */\n    if (info->type != PJMEDIA_TYPE_AUDIO)\n\treturn PJMEDIA_CODEC_EUNSUP;\n\n    /* Check encoding name. */\n    if (pj_stricmp(&info->encoding_name, &speex_tag) != 0)\n\treturn PJMEDIA_CODEC_EUNSUP;\n\n    /* Check clock-rate */\n    for (i=0; i<PJ_ARRAY_SIZE(spx_factory.speex_param); ++i) {\n\tif (info->clock_rate == spx_factory.speex_param[i].clock_rate) {\n\t    /* Okay, let's Speex! */\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    \n    /* Unsupported, or mode is disabled. */\n    return PJMEDIA_CODEC_EUNSUP;\n}\n\n/*\n * Generate default attribute.\n */\nstatic pj_status_t spx_default_attr (pjmedia_codec_factory *factory, \n\t\t\t\t      const pjmedia_codec_info *id, \n\t\t\t\t      pjmedia_codec_param *attr )\n{\n\n    PJ_ASSERT_RETURN(factory==&spx_factory.base, PJ_EINVAL);\n\n    pj_bzero(attr, sizeof(pjmedia_codec_param));\n    attr->info.pt = (pj_uint8_t)id->pt;\n    attr->info.channel_cnt = 1;\n\n    if (id->clock_rate <= 8000) {\n\tattr->info.clock_rate = spx_factory.speex_param[PARAM_NB].clock_rate;\n\tattr->info.avg_bps = spx_factory.speex_param[PARAM_NB].bitrate;\n\tattr->info.max_bps = spx_factory.speex_param[PARAM_NB].max_bitrate;\n\n    } else if (id->clock_rate <= 16000) {\n\tattr->info.clock_rate = spx_factory.speex_param[PARAM_WB].clock_rate;\n\tattr->info.avg_bps = spx_factory.speex_param[PARAM_WB].bitrate;\n\tattr->info.max_bps = spx_factory.speex_param[PARAM_WB].max_bitrate;\n\n    } else {\n\t/* Wow.. somebody is doing ultra-wideband. Cool...! */\n\tattr->info.clock_rate = spx_factory.speex_param[PARAM_UWB].clock_rate;\n\tattr->info.avg_bps = spx_factory.speex_param[PARAM_UWB].bitrate;\n\tattr->info.max_bps = spx_factory.speex_param[PARAM_UWB].max_bitrate;\n    }\n\n    attr->info.pcm_bits_per_sample = 16;\n    attr->info.frm_ptime = 20;\n    attr->info.pt = (pj_uint8_t)id->pt;\n\n    attr->setting.frm_per_pkt = 1;\n\n    /* Default flags. */\n    attr->setting.cng = 1;\n    attr->setting.plc = 1;\n    attr->setting.penh =1 ;\n    attr->setting.vad = 1;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Enum codecs supported by this factory (i.e. only Speex!).\n */\nstatic pj_status_t spx_enum_codecs(pjmedia_codec_factory *factory, \n\t\t\t\t    unsigned *count, \n\t\t\t\t    pjmedia_codec_info codecs[])\n{\n    unsigned max;\n    int i;  /* Must be signed */\n\n    PJ_UNUSED_ARG(factory);\n    PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);\n\n    max = *count;\n    *count = 0;\n\n    /*\n     * We return three codecs here, and in this order:\n     *\t- ultra-wideband, wideband, and narrowband.\n     */\n    for (i=PJ_ARRAY_SIZE(spx_factory.speex_param)-1; i>=0 && *count<max; --i) {\n\n\tif (!spx_factory.speex_param[i].enabled)\n\t    continue;\n\n\tpj_bzero(&codecs[*count], sizeof(pjmedia_codec_info));\n\tcodecs[*count].encoding_name = pj_str(\"speex\");\n\tcodecs[*count].pt = spx_factory.speex_param[i].pt;\n\tcodecs[*count].type = PJMEDIA_TYPE_AUDIO;\n\tcodecs[*count].clock_rate = spx_factory.speex_param[i].clock_rate;\n\tcodecs[*count].channel_cnt = 1;\n\n\t++*count;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Allocate a new Speex codec instance.\n */\nstatic pj_status_t spx_alloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t    const pjmedia_codec_info *id,\n\t\t\t\t    pjmedia_codec **p_codec)\n{\n    pjmedia_codec *codec;\n    struct spx_private *spx;\n\n    PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &spx_factory.base, PJ_EINVAL);\n\n\n    pj_mutex_lock(spx_factory.mutex);\n\n    /* Get free nodes, if any. */\n    if (!pj_list_empty(&spx_factory.codec_list)) {\n\tcodec = spx_factory.codec_list.next;\n\tpj_list_erase(codec);\n    } else {\n\tcodec = PJ_POOL_ZALLOC_T(spx_factory.pool, pjmedia_codec);\n\tPJ_ASSERT_RETURN(codec != NULL, PJ_ENOMEM);\n\tcodec->op = &spx_op;\n\tcodec->factory = factory;\n\tcodec->codec_data = pj_pool_alloc(spx_factory.pool,\n\t\t\t\t\t  sizeof(struct spx_private));\n    }\n\n    pj_mutex_unlock(spx_factory.mutex);\n\n    spx = (struct spx_private*) codec->codec_data;\n    spx->enc = NULL;\n    spx->dec = NULL;\n\n    if (id->clock_rate <= 8000)\n\tspx->param_id = PARAM_NB;\n    else if (id->clock_rate <= 16000)\n\tspx->param_id = PARAM_WB;\n    else\n\tspx->param_id = PARAM_UWB;\n\n    *p_codec = codec;\n    return PJ_SUCCESS;\n}\n\n/*\n * Free codec.\n */\nstatic pj_status_t spx_dealloc_codec( pjmedia_codec_factory *factory, \n\t\t\t\t      pjmedia_codec *codec )\n{\n    struct spx_private *spx;\n\n    PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &spx_factory.base, PJ_EINVAL);\n\n    /* Close codec, if it's not closed. */\n    spx = (struct spx_private*) codec->codec_data;\n    if (spx->enc != NULL || spx->dec != NULL) {\n\tspx_codec_close(codec);\n    }\n\n    /* Put in the free list. */\n    pj_mutex_lock(spx_factory.mutex);\n    pj_list_push_front(&spx_factory.codec_list, codec);\n    pj_mutex_unlock(spx_factory.mutex);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Init codec.\n */\nstatic pj_status_t spx_codec_init( pjmedia_codec *codec, \n\t\t\t\t   pj_pool_t *pool )\n{\n    PJ_UNUSED_ARG(codec);\n    PJ_UNUSED_ARG(pool);\n    return PJ_SUCCESS;\n}\n\n/*\n * Open codec.\n */\nstatic pj_status_t spx_codec_open( pjmedia_codec *codec, \n\t\t\t\t   pjmedia_codec_param *attr )\n{\n    struct spx_private *spx;\n    int id, tmp;\n\n    spx = (struct spx_private*) codec->codec_data;\n    id = spx->param_id;\n\n    /* \n     * Create and initialize encoder. \n     */\n    spx->enc = speex_encoder_init(spx_factory.speex_param[id].mode);\n    if (!spx->enc)\n\treturn PJMEDIA_CODEC_EFAILED;\n    speex_bits_init(&spx->enc_bits);\n\n    /* Set the quality*/\n    if (spx_factory.speex_param[id].quality != -1) {\n\tspeex_encoder_ctl(spx->enc, SPEEX_SET_QUALITY, \n\t\t\t  &spx_factory.speex_param[id].quality);\n    }\n\n    /* Sampling rate. */\n    tmp = attr->info.clock_rate;\n    speex_encoder_ctl(spx->enc, SPEEX_SET_SAMPLING_RATE, \n\t\t      &spx_factory.speex_param[id].clock_rate);\n\n    /* VAD */\n    tmp = (attr->setting.vad != 0);\n    speex_encoder_ctl(spx->enc, SPEEX_SET_VAD, &tmp);\n    speex_encoder_ctl(spx->enc, SPEEX_SET_DTX, &tmp);\n\n    /* Complexity */\n    if (spx_factory.speex_param[id].complexity != -1) {\n\tspeex_encoder_ctl(spx->enc, SPEEX_SET_COMPLEXITY, \n\t\t\t  &spx_factory.speex_param[id].complexity);\n    }\n\n    /* \n     * Create and initialize decoder. \n     */\n    spx->dec = speex_decoder_init(spx_factory.speex_param[id].mode);\n    if (!spx->dec) {\n\tspx_codec_close(codec);\n\treturn PJMEDIA_CODEC_EFAILED;\n    }\n    speex_bits_init(&spx->dec_bits);\n\n    /* Sampling rate. */\n    speex_decoder_ctl(spx->dec, SPEEX_SET_SAMPLING_RATE, \n\t\t      &spx_factory.speex_param[id].clock_rate);\n\n    /* PENH */\n    tmp = attr->setting.penh;\n    speex_decoder_ctl(spx->dec, SPEEX_SET_ENH, &tmp);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Close codec.\n */\nstatic pj_status_t spx_codec_close( pjmedia_codec *codec )\n{\n    struct spx_private *spx;\n\n    spx = (struct spx_private*) codec->codec_data;\n\n    /* Destroy encoder*/\n    if (spx->enc) {\n\tspeex_encoder_destroy( spx->enc );\n\tspx->enc = NULL;\n\tspeex_bits_destroy( &spx->enc_bits );\n    }\n\n    /* Destroy decoder */\n    if (spx->dec) {\n\tspeex_decoder_destroy( spx->dec);\n\tspx->dec = NULL;\n\tspeex_bits_destroy( &spx->dec_bits );\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Modify codec settings.\n */\nstatic pj_status_t  spx_codec_modify(pjmedia_codec *codec, \n\t\t\t\t     const pjmedia_codec_param *attr )\n{\n    struct spx_private *spx;\n    int tmp;\n\n    spx = (struct spx_private*) codec->codec_data;\n\n    /* VAD */\n    tmp = (attr->setting.vad != 0);\n    speex_encoder_ctl(spx->enc, SPEEX_SET_VAD, &tmp);\n    speex_encoder_ctl(spx->enc, SPEEX_SET_DTX, &tmp);\n\n    /* PENH */\n    tmp = attr->setting.penh;\n    speex_decoder_ctl(spx->dec, SPEEX_SET_ENH, &tmp);\n\n    return PJ_SUCCESS;\n}\n\n#if 0\n#  define TRACE__(args)\t    PJ_LOG(5,args)\n#else\n#  define TRACE__(args)\n#endif\n\n#undef THIS_FUNC\n#define THIS_FUNC \"speex_get_next_frame\"\n\n#define NB_SUBMODES 16\n#define NB_SUBMODE_BITS 4\n\n#define SB_SUBMODES 8\n#define SB_SUBMODE_BITS 3\n\n/* This function will iterate frames & submodes in the Speex bits.\n * Returns 0 if a frame found, otherwise returns -1.\n */\nstatic int speex_get_next_frame(SpeexBits *bits)\n{\n    static const int inband_skip_table[NB_SUBMODES] =\n       {1, 1, 4, 4, 4, 4, 4, 4, 8, 8, 16, 16, 32, 32, 64, 64 };\n    static const int wb_skip_table[SB_SUBMODES] =\n       {SB_SUBMODE_BITS+1, 36, 112, 192, 352, -1, -1, -1};\n\n    unsigned submode;\n    unsigned nb_count = 0;\n\n    while (speex_bits_remaining(bits) >= 5) {\n\tunsigned wb_count = 0;\n\tunsigned bit_ptr = bits->bitPtr;\n\tunsigned char_ptr = bits->charPtr;\n\n\t/* WB frame */\n\twhile ((speex_bits_remaining(bits) >= 4)\n\t    && speex_bits_unpack_unsigned(bits, 1))\n\t{\n\t    int advance;\n\n\t    submode = speex_bits_unpack_unsigned(bits, 3);\n\t    advance = wb_skip_table[submode];\n\t    if (advance < 0) {\n\t\tTRACE__((THIS_FUNC, \"Invalid mode encountered. \"\n\t\t\t \"The stream is corrupted.\"));\n\t\treturn -1;\n\t    } \n\t    TRACE__((THIS_FUNC, \"WB layer skipped: %d bits\", advance));\n\t    advance -= (SB_SUBMODE_BITS+1);\n\t    speex_bits_advance(bits, advance);\n\n\t    bit_ptr = bits->bitPtr;\n\t    char_ptr = bits->charPtr;\n\n\t    /* Consecutive subband frames may not exceed 2 frames */\n\t    if (++wb_count > 2)\n\t\treturn -1;\n\t}\n\n\t/* End of bits, return the frame */\n\tif (speex_bits_remaining(bits) < 4) {\n\t    TRACE__((THIS_FUNC, \"End of stream\"));\n\t    return 0;\n\t}\n\n\t/* Stop iteration, return the frame */\n\tif (nb_count > 0) {\n\t    bits->bitPtr = bit_ptr;\n\t    bits->charPtr = char_ptr;\n\t    return 0;\n\t}\n\n\t/* Get control bits */\n\tsubmode = speex_bits_unpack_unsigned(bits, 4);\n\tTRACE__((THIS_FUNC, \"Control bits: %d at %d\", \n\t\t submode, bits->charPtr*8+bits->bitPtr));\n\n\tif (submode == 15) {\n\t    TRACE__((THIS_FUNC, \"Found submode: terminator\"));\n\t    return -1;\n\t} else if (submode == 14) {\n\t    /* in-band signal; next 4 bits contain signal id */\n\t    submode = speex_bits_unpack_unsigned(bits, 4);\n\t    TRACE__((THIS_FUNC, \"Found submode: in-band %d bits\", \n\t\t     inband_skip_table[submode]));\n\t    speex_bits_advance(bits, inband_skip_table[submode]);\n\t} else if (submode == 13) {\n\t    /* user in-band; next 5 bits contain msg len */\n\t    submode = speex_bits_unpack_unsigned(bits, 5);\n\t    TRACE__((THIS_FUNC, \"Found submode: user-band %d bytes\", submode));\n\t    speex_bits_advance(bits, submode * 8);\n\t} else if (submode > 8) {\n\t    TRACE__((THIS_FUNC, \"Unknown sub-mode %d\", submode));\n\t    return -1;\n\t} else {\n\t    /* NB frame */\n\t    int advance = submode;\n\t    speex_mode_query(&speex_nb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);\n\t    if (advance < 0) {\n\t\tTRACE__((THIS_FUNC, \"Invalid mode encountered. \"\n\t\t\t \"The stream is corrupted.\"));\n\t\treturn -1;\n\t    }\n\t    TRACE__((THIS_FUNC, \"Submode %d: %d bits\", submode, advance));\n\t    advance -= (NB_SUBMODE_BITS+1);\n\t    speex_bits_advance(bits, advance);\n\n\t    ++nb_count;\n\t}\n    }\n\n    return 0;\n}\n\n\n/*\n * Get frames in the packet.\n */\nstatic pj_status_t  spx_codec_parse( pjmedia_codec *codec,\n\t\t\t\t     void *pkt,\n\t\t\t\t     pj_size_t pkt_size,\n\t\t\t\t     const pj_timestamp *ts,\n\t\t\t\t     unsigned *frame_cnt,\n\t\t\t\t     pjmedia_frame frames[])\n{\n    struct spx_private *spx = (struct spx_private*) codec->codec_data;\n    unsigned samples_per_frame;\n    unsigned count = 0;\n    int char_ptr = 0;\n    int bit_ptr = 0;\n\n    samples_per_frame=spx_factory.speex_param[spx->param_id].samples_per_frame;\n\n    /* Copy the data into the speex bit-stream */\n    speex_bits_read_from(&spx->dec_bits, (char*)pkt, (int)pkt_size);\n\n    while (speex_get_next_frame(&spx->dec_bits) == 0 && \n\t   spx->dec_bits.charPtr != char_ptr)\n    {\n\tframes[count].buf = (char*)pkt + char_ptr;\n\t/* Bit info contains start bit offset of the frame */\n\tframes[count].bit_info = bit_ptr;\n\tframes[count].type = PJMEDIA_FRAME_TYPE_AUDIO;\n\tframes[count].timestamp.u64 = ts->u64 + count * samples_per_frame;\n\tframes[count].size = spx->dec_bits.charPtr - char_ptr;\n\tif (spx->dec_bits.bitPtr)\n\t    ++frames[count].size;\n\n\tbit_ptr = spx->dec_bits.bitPtr;\n\tchar_ptr = spx->dec_bits.charPtr;\n\n\t++count;\n    }\n\n    *frame_cnt = count;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Encode frames.\n */\nstatic pj_status_t spx_codec_encode( pjmedia_codec *codec, \n\t\t\t\t     const struct pjmedia_frame *input,\n\t\t\t\t     unsigned output_buf_len, \n\t\t\t\t     struct pjmedia_frame *output)\n{\n    struct spx_private *spx;\n    unsigned samples_per_frame;\n    int tx = 0;\n    spx_int16_t *pcm_in = (spx_int16_t*)input->buf;\n    pj_size_t nsamples;\n\n    spx = (struct spx_private*) codec->codec_data;\n\n    if (input->type != PJMEDIA_FRAME_TYPE_AUDIO) {\n\toutput->size = 0;\n\toutput->buf = NULL;\n\toutput->timestamp = input->timestamp;\n\toutput->type = input->type;\n\treturn PJ_SUCCESS;\n    }\n\n    nsamples = input->size >> 1;\n    samples_per_frame=spx_factory.speex_param[spx->param_id].samples_per_frame;\n\n    PJ_ASSERT_RETURN(nsamples % samples_per_frame == 0, \n\t\t     PJMEDIA_CODEC_EPCMFRMINLEN);\n\n    /* Flush all the bits in the struct so we can encode a new frame */\n    speex_bits_reset(&spx->enc_bits);\n\n    /* Encode the frames */\n    while (nsamples >= samples_per_frame) {\n\ttx += speex_encode_int(spx->enc, pcm_in, &spx->enc_bits);\n\tpcm_in += samples_per_frame;\n\tnsamples -= samples_per_frame;\n    }\n\n    /* Check if we need not to transmit the frame (DTX) */\n    if (tx == 0) {\n\toutput->buf = NULL;\n\toutput->size = 0;\n\toutput->timestamp.u64 = input->timestamp.u64;\n\toutput->type = PJMEDIA_FRAME_TYPE_NONE;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Check size. */\n    pj_assert(speex_bits_nbytes(&spx->enc_bits) <= (int)output_buf_len);\n\n    /* Copy the bits to an array of char that can be written */\n    output->size = speex_bits_write(&spx->enc_bits, \n\t\t\t\t    (char*)output->buf, output_buf_len);\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    output->timestamp = input->timestamp;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Decode frame.\n */\nstatic pj_status_t spx_codec_decode( pjmedia_codec *codec, \n\t\t\t\t     const struct pjmedia_frame *input,\n\t\t\t\t     unsigned output_buf_len, \n\t\t\t\t     struct pjmedia_frame *output)\n{\n    struct spx_private *spx;\n    unsigned samples_per_frame;\n\n    spx = (struct spx_private*) codec->codec_data;\n    samples_per_frame=spx_factory.speex_param[spx->param_id].samples_per_frame;\n\n    PJ_ASSERT_RETURN(output_buf_len >= samples_per_frame << 1,\n\t\t     PJMEDIA_CODEC_EPCMTOOSHORT);\n\n    if (input->type != PJMEDIA_FRAME_TYPE_AUDIO) {\n\tpjmedia_zero_samples((pj_int16_t*)output->buf, samples_per_frame);\n\toutput->size = samples_per_frame << 1;\n\toutput->timestamp.u64 = input->timestamp.u64;\n\toutput->type = PJMEDIA_FRAME_TYPE_AUDIO;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Copy the data into the bit-stream struct */\n    speex_bits_read_from(&spx->dec_bits, (char*)input->buf, (int)input->size);\n    \n    /* Set Speex dec_bits pointer to the start bit of the frame */\n    speex_bits_advance(&spx->dec_bits, input->bit_info);\n\n    /* Decode the data */\n    speex_decode_int(spx->dec, &spx->dec_bits, (spx_int16_t*)output->buf);\n\n    output->type = PJMEDIA_FRAME_TYPE_AUDIO;\n    output->size = samples_per_frame << 1;\n    output->timestamp.u64 = input->timestamp.u64;\n\n    return PJ_SUCCESS;\n}\n\n/* \n * Recover lost frame.\n */\nstatic pj_status_t  spx_codec_recover(pjmedia_codec *codec, \n\t\t\t\t      unsigned output_buf_len, \n\t\t\t\t      struct pjmedia_frame *output)\n{\n    struct spx_private *spx;\n    unsigned count;\n\n    /* output_buf_len is unreferenced when building in Release mode */\n    PJ_UNUSED_ARG(output_buf_len);\n\n    spx = (struct spx_private*) codec->codec_data;\n\n    count = spx_factory.speex_param[spx->param_id].clock_rate * 20 / 1000;\n    pj_assert(count <= output_buf_len/2);\n\n    /* Recover packet loss */\n    speex_decode_int(spx->dec, NULL, (spx_int16_t*) output->buf);\n\n    output->size = count * 2;\n\n    return PJ_SUCCESS;\n}\n\n\n#endif\t/* PJMEDIA_HAS_SPEEX_CODEC */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-codec/vpx.c",
    "content": "/**\n * Copyright (C) 2015 AG Projects\n * Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)\n * This file is part of pjsip_android.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <pjmedia-codec/vpx.h>\n#include <pjmedia/errno.h>\n#include <pjmedia/vid_codec_util.h>\n#include <pj/assert.h>\n#include <pj/list.h>\n#include <pj/log.h>\n#include <pj/math.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/os.h>\n\n#if defined(PJ_WIN32) && PJ_WIN32!=0\n# include <windows.h>\n#elif defined(PJ_DARWINOS) && PJ_DARWINOS!=0\n# include <sys/sysctl.h>\n# include <sys/types.h>\n#elif defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H!=0\n# include <unistd.h>\n#else\n# warning \"Cannot find a way to guess the number of cores on this platform.\"\n#endif\n\n#if defined(PJMEDIA_HAS_VPX_CODEC) && \\\n            PJMEDIA_HAS_VPX_CODEC != 0 && \\\n    defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n#define THIS_FILE   \"vpx.c\"\n\n#define DEFAULT_WIDTH\t640\n#define DEFAULT_HEIGHT\t480\n#define DEFAULT_FPS\t15\n\n#define DEFAULT_AVG_BITRATE\t256000\n#define DEFAULT_MAX_BITRATE\t256000\n\n#define VPX_CODEC_DISABLE_COMPAT 1\n#include <vpx/vpx_encoder.h>\n#include <vpx/vp8cx.h>\n#include <vpx/vpx_decoder.h>\n#include <vpx/vp8dx.h>\n\n#if 1\n#   define TRACE_(x)    PJ_LOG(4, x)\n#else\n#   define TRACE_(x)\n#endif\n\n/* Prototypes for LibVPX codecs factory */\nstatic pj_status_t pj_vpx_test_alloc(pjmedia_vid_codec_factory *factory,\n        const pjmedia_vid_codec_info *id);\nstatic pj_status_t pj_vpx_default_attr(pjmedia_vid_codec_factory *factory,\n        const pjmedia_vid_codec_info *info, pjmedia_vid_codec_param *attr);\nstatic pj_status_t pj_vpx_enum_codecs(pjmedia_vid_codec_factory *factory,\n        unsigned *count, pjmedia_vid_codec_info codecs[]);\nstatic pj_status_t pj_vpx_alloc_codec(pjmedia_vid_codec_factory *factory,\n        const pjmedia_vid_codec_info *info, pjmedia_vid_codec **p_codec);\nstatic pj_status_t pj_vpx_dealloc_codec(pjmedia_vid_codec_factory *factory,\n        pjmedia_vid_codec *codec);\n\n/* Prototypes for VPX codec implementation. */\nstatic pj_status_t pj_vpx_codec_init(pjmedia_vid_codec *codec, pj_pool_t *pool);\nstatic pj_status_t pj_vpx_codec_open(pjmedia_vid_codec *codec,\n        pjmedia_vid_codec_param *attr);\nstatic pj_status_t pj_vpx_codec_close(pjmedia_vid_codec *codec);\nstatic pj_status_t pj_vpx_codec_modify(pjmedia_vid_codec *codec,\n        const pjmedia_vid_codec_param *attr);\nstatic pj_status_t pj_vpx_codec_get_param(pjmedia_vid_codec *codec,\n        pjmedia_vid_codec_param *param);\nstatic pj_status_t pj_vpx_codec_encode_begin(pjmedia_vid_codec *codec,\n        const pjmedia_vid_encode_opt *opt, const pjmedia_frame *input,\n        unsigned out_size, pjmedia_frame *output, pj_bool_t *has_more);\nstatic pj_status_t pj_vpx_codec_encode_more(pjmedia_vid_codec *codec,\n        unsigned out_size, pjmedia_frame *output, pj_bool_t *has_more);\nstatic pj_status_t pj_vpx_codec_decode(pjmedia_vid_codec *codec,\n        pj_size_t pkt_count, pjmedia_frame packets[], unsigned out_size,\n        pjmedia_frame *output);\n\n/* Definition for VPX codec operations. */\nstatic pjmedia_vid_codec_op vpx_op = { &pj_vpx_codec_init,\n                                       &pj_vpx_codec_open,\n                                       &pj_vpx_codec_close,\n                                       &pj_vpx_codec_modify,\n                                       &pj_vpx_codec_get_param,\n                                       &pj_vpx_codec_encode_begin,\n                                       &pj_vpx_codec_encode_more,\n                                       &pj_vpx_codec_decode,\n                                       NULL };\n\n/* Definition for VPX factory operations. */\nstatic pjmedia_vid_codec_factory_op vpx_factory_op = { &pj_vpx_test_alloc,\n        &pj_vpx_default_attr, &pj_vpx_enum_codecs, &pj_vpx_alloc_codec,\n        &pj_vpx_dealloc_codec };\n\n/* VPX codec factory */\nstatic struct vpx_factory {\n    pjmedia_vid_codec_factory base;\n    pjmedia_vid_codec_mgr *mgr;\n    pj_pool_factory *pf;\n    pj_pool_t *pool;\n    pj_mutex_t *mutex;\n} vpx_factory;\n\ntypedef struct vpx_codec_desc vpx_codec_desc;\n\n/* VPX codec private data. */\ntypedef struct vpx_private {\n    const vpx_codec_desc *desc;\n    pjmedia_vid_codec_param param; /**< Codec param\t    */\n    pj_pool_t *pool; /**< Pool for each instance */\n\n    /* Format info and apply format param */\n    const pjmedia_video_format_info *enc_vfi;\n    pjmedia_video_apply_fmt_param enc_vafp;\n    const pjmedia_video_format_info *dec_vfi;\n    pjmedia_video_apply_fmt_param dec_vafp;\n\n    /* The vpx encoder. */\n    struct vpx_codec_ctx    encoder;\n    struct vpx_image        rawimg;\n    void                    *enc_buf;\n    unsigned                enc_buf_size;\n    pj_bool_t                enc_buf_is_keyframe;\n    unsigned                 enc_frame_len;\n    unsigned                 enc_processed;\n    vpx_codec_iter_t        enc_iter;\n    int                     rc_max_intra_target;\n\n    /* The vpx decoder */\n    struct vpx_codec_ctx    decoder;\n    void                    *dec_buf;\n    unsigned                dec_buf_size;\n    unsigned                dec_frame_len;\n    pj_bool_t               dec_stream_info_init;\n    pj_timestamp            last_dec_keyframe_ts;\n\n} vpx_private;\n\n\n/* Number of threads to use, depending on resolution and number of CPUS.\n * Borrowed from WebRTC.\n */\nunsigned int number_of_threads(int width, int height, int cpus) {\n#if 1\n    int c = width * height;\n    if (c >= 1920 * 1080 && cpus > 8)\n        return 8;\n    else if (c > 1280 * 960 && cpus >=6)\n        return 3;\n    else if (c > 640 * 480 && cpus >= 3)\n        return 2;\n    else\n        return 1;\n#else\n    return cpus - 1;\n#endif\n}\n\n\nunsigned int number_of_cores(void) {\n    static unsigned int ncores;\n\n    if (!ncores) {\n#if defined(PJ_WIN32) && PJ_WIN32!=0\n        SYSTEM_INFO si;\n        GetSystemInfo(&si);\n        ncores = si.dwNumberOfProcessors;\n#elif defined(PJ_DARWINOS) && PJ_DARWINOS!=0\n        int name[] = {CTL_HW, HW_AVAILCPU};\n        int ncpu;\n        size_t size = sizeof(ncpu);\n        if (0 == sysctl(name, 2, &ncpu, &size, NULL, 0)) {\n            ncores = ncpu;\n        } else {\n            PJ_LOG(4, (THIS_FILE, \"Failed to detect number of CPU cores\"));\n            ncores = 1;\n        }\n#elif defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H!=0\n        ncores = sysconf(_SC_NPROCESSORS_ONLN);\n#else\n        ncores = 1;\n#endif\n    }\n\n    return ncores;\n}\n\n\n/*\n * Initialize and register VPX codec factory to pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_vpx_init(pjmedia_vid_codec_mgr *mgr,\n        pj_pool_factory *pf) {\n    pj_pool_t *pool;\n    pj_status_t status;\n\n    TRACE_((THIS_FILE, \"Init vpx codec\"));\n\n    if (vpx_factory.pool != NULL ) {\n        /* Already initialized. */\n        return PJ_SUCCESS;\n    }\n\n    if (!mgr)\n        mgr = pjmedia_vid_codec_mgr_instance();\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    /* Create VPX codec factory. */\n    vpx_factory.base.op = &vpx_factory_op;\n    vpx_factory.base.factory_data = NULL;\n    vpx_factory.mgr = mgr;\n    vpx_factory.pf = pf;\n\n    pool = pj_pool_create(pf, \"vpx codec factory\", 256, 256, NULL );\n    if (!pool)\n        return PJ_ENOMEM;\n\n    /* Create mutex. */\n    status = pj_mutex_create_simple(pool, \"vpx codec factory\",\n            &vpx_factory.mutex);\n    if (status != PJ_SUCCESS)\n        goto on_error;\n\n    /* Register codec factory to codec manager. */\n    status = pjmedia_vid_codec_mgr_register_factory(mgr, &vpx_factory.base);\n    if (status != PJ_SUCCESS)\n        goto on_error;\n\n    vpx_factory.pool = pool;\n\n    /* Done. */\n    return PJ_SUCCESS;\n\n    on_error: pj_pool_release(pool);\n    return status;\n}\n\n/*\n * Unregister VPX factory from pjmedia endpoint.\n */\nPJ_DEF(pj_status_t) pjmedia_codec_vpx_deinit(void) {\n    pj_status_t status = PJ_SUCCESS;\n    TRACE_((THIS_FILE, \"Deinit vpx codec\"));\n\n    if (vpx_factory.pool == NULL ) {\n        /* Already deinitialized */\n        return PJ_SUCCESS;\n    }\n\n    pj_mutex_lock(vpx_factory.mutex);\n\n    /* Unregister VPX codecs factory. */\n    status = pjmedia_vid_codec_mgr_unregister_factory(vpx_factory.mgr,\n            &vpx_factory.base);\n\n    /* Destroy mutex. */\n    pj_mutex_destroy(vpx_factory.mutex);\n\n    /* Destroy pool. */\n    pj_pool_release(vpx_factory.pool);\n    vpx_factory.pool = NULL;\n\n    return status;\n}\n\n/*\n * Check if factory can allocate the specified codec.\n */\nstatic pj_status_t pj_vpx_test_alloc(pjmedia_vid_codec_factory *factory,\n        const pjmedia_vid_codec_info *info) {\n    const pj_str_t vpx_tag = { \"VP8\", 3};\n\n    PJ_ASSERT_RETURN(factory==&vpx_factory.base, PJ_EINVAL);\n    PJ_ASSERT_RETURN(info, PJ_EINVAL);\n\n    /* Check encoding name. */\n    if (pj_stricmp(&info->encoding_name, &vpx_tag) != 0)\n    return PJMEDIA_CODEC_EUNSUP;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Generate default attribute.\n */\nstatic pj_status_t pj_vpx_default_attr(pjmedia_vid_codec_factory *factory,\n        const pjmedia_vid_codec_info *info, pjmedia_vid_codec_param *attr) {\n\n    PJ_ASSERT_RETURN(factory==&vpx_factory.base, PJ_EINVAL);\n    PJ_ASSERT_RETURN(info && attr, PJ_EINVAL);\n\n    TRACE_((THIS_FILE, \"vpx default attr\"));\n\n\n    pj_bzero(attr, sizeof(pjmedia_vid_codec_param));\n\n    /* Scan the requested packings and use the lowest number */\n    attr->packing = 1;\n\n    /* Direction */\n    attr->dir = PJMEDIA_DIR_ENCODING_DECODING;\n\n    /* Encoded format */\n    pjmedia_format_init_video(&attr->enc_fmt, PJMEDIA_FORMAT_VP8,\n                              DEFAULT_WIDTH, DEFAULT_HEIGHT,\n                              DEFAULT_FPS, 1);\n\n    /* Decoded format */\n    pjmedia_format_init_video(&attr->dec_fmt, PJMEDIA_FORMAT_I420,\n                              DEFAULT_WIDTH, DEFAULT_HEIGHT,\n                              DEFAULT_FPS, 1);\n\n    /* Decoding fmtp */\n    attr->dec_fmtp.cnt = 0;\n\n    /* Bitrate */\n    attr->enc_fmt.det.vid.avg_bps = DEFAULT_AVG_BITRATE;\n    attr->enc_fmt.det.vid.max_bps = DEFAULT_MAX_BITRATE;\n\n    attr->enc_fmtp.cnt = 0;\n\n    /* Encoding MTU */\n    attr->enc_mtu = PJMEDIA_MAX_VID_PAYLOAD_SIZE;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Enum codecs supported by this factory.\n */\nstatic pj_status_t pj_vpx_enum_codecs(pjmedia_vid_codec_factory *factory,\n        unsigned *count, pjmedia_vid_codec_info info[]) {\n\n    PJ_ASSERT_RETURN(info && *count > 0, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &vpx_factory.base, PJ_EINVAL);\n    TRACE_((THIS_FILE, \"Enum codecs...\"));\n\n    *count = 1;\n    info->fmt_id = PJMEDIA_FORMAT_VP8;\n    info->pt = PJMEDIA_RTP_PT_VP8;\n    info->encoding_name = pj_str(\"VP8\");\n    info->encoding_desc = pj_str(\"WebM Project VP8 Encoder\");\n    info->dir = PJMEDIA_DIR_ENCODING_DECODING;\n    info->clock_rate = 90000;\n    info->dec_fmt_id_cnt = 1;\n    info->dec_fmt_id[0] = PJMEDIA_FORMAT_I420;\n    info->packings = PJMEDIA_VID_PACKING_PACKETS;\n    info->fps_cnt = 4;\n    info->fps[0].num = 15;\n    info->fps[0].denum = 1;\n    info->fps[1].num = 20;\n    info->fps[1].denum = 1;\n    info->fps[2].num = 25;\n    info->fps[2].denum = 1;\n    info->fps[3].num = 30;\n    info->fps[3].denum = 1;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Allocate a new codec instance.\n */\nstatic pj_status_t pj_vpx_alloc_codec(pjmedia_vid_codec_factory *factory,\n        const pjmedia_vid_codec_info *info, pjmedia_vid_codec **p_codec) {\n    vpx_private *vpx;\n    pjmedia_vid_codec *codec;\n    pj_pool_t *pool = NULL;\n    pj_status_t status = PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(factory && info && p_codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &vpx_factory.base, PJ_EINVAL);\n\n    TRACE_((THIS_FILE, \"vpx pj_vpx_alloc_codec\"));\n\n\n    if (info->pt != PJMEDIA_RTP_PT_VP8) {\n        return PJMEDIA_CODEC_EUNSUP;\n    }\n\n    /* Create pool for codec instance */\n    pool = pj_pool_create(vpx_factory.pf, \"vp8 codec\", 512, 512, NULL );\n    codec = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_codec);\n    if (!codec) {\n        status = PJ_ENOMEM;\n        goto on_error;\n    }\n    codec->op = &vpx_op;\n    codec->factory = factory;\n    vpx = PJ_POOL_ZALLOC_T(pool, vpx_private);\n    if (!vpx) {\n        status = PJ_ENOMEM;\n        goto on_error;\n    }\n    codec->codec_data = vpx;\n    vpx->pool = pool;\n\n    *p_codec = codec;\n    return PJ_SUCCESS;\n\n    on_error: if (pool)\n        pj_pool_release(pool);\n    return status;\n}\n\n/*\n * Free codec.\n */\nstatic pj_status_t pj_vpx_dealloc_codec(pjmedia_vid_codec_factory *factory,\n        pjmedia_vid_codec *codec) {\n    vpx_private *vpx;\n    pj_pool_t *pool;\n\n    PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);\n    PJ_ASSERT_RETURN(factory == &vpx_factory.base, PJ_EINVAL);\n    TRACE_((THIS_FILE, \"vpx pj_vpx_dealloc_codec\"));\n\n    /* Close codec, if it's not closed. */\n    vpx = (vpx_private*) codec->codec_data;\n    pool = vpx->pool;\n    codec->codec_data = NULL;\n    pj_pool_release(pool);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Init codec.\n */\nstatic pj_status_t pj_vpx_codec_init(pjmedia_vid_codec *codec, pj_pool_t *pool) {\n    PJ_UNUSED_ARG(codec);\n    PJ_UNUSED_ARG(pool);\n    TRACE_((THIS_FILE, \"vpx pj_vpx_codec_init\"));\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t pj_vpx_encoder_open(vpx_private *vpx) {\n    vpx_codec_flags_t flags = 0;\n    /* XXX: use VPX_CODEC_USE_OUTPUT_PARTITION ? */\n    const struct vpx_codec_iface *iface = &vpx_codec_vp8_cx_algo;\n    struct vpx_codec_enc_cfg enccfg;\n    int res;\n\n    TRACE_((THIS_FILE, \"vpx pj_vpx_encoder_open\"));\n\n    res = vpx_codec_enc_config_default(iface, &enccfg, 0);\n    if (res != VPX_CODEC_OK) {\n        PJ_LOG(1, (THIS_FILE, \"Failed to get vpx default config : %s\", vpx_codec_err_to_string(res)));\n        return PJMEDIA_CODEC_EFAILED;\n    }\n\n    enccfg.g_w = vpx->param.enc_fmt.det.vid.size.w;\n    enccfg.g_h = vpx->param.enc_fmt.det.vid.size.h;\n    enccfg.g_timebase.num = vpx->param.enc_fmt.det.vid.fps.num;\n    enccfg.g_timebase.den = vpx->param.enc_fmt.det.vid.fps.denum;\n    //provide dummy value to initialize wrapper, values will be updated each _encode()\n    vpx_img_wrap(&vpx->rawimg,\n                 VPX_IMG_FMT_I420,\n                 vpx->param.enc_fmt.det.vid.size.w,\n                 vpx->param.enc_fmt.det.vid.size.h,\n                 1,\n                 NULL);\n\n    enccfg.g_threads = number_of_threads(enccfg.g_w, enccfg.g_h, number_of_cores());\n    PJ_LOG(4, (THIS_FILE, \"Using %d threads for VPX encoding\", enccfg.g_threads));\n\n    enccfg.g_lag_in_frames = 0;\n    enccfg.g_pass = VPX_RC_ONE_PASS;\n    enccfg.rc_end_usage = VPX_CBR;\n    enccfg.rc_target_bitrate = vpx->param.enc_fmt.det.vid.avg_bps / 1000; // in kbit/s\n    enccfg.g_timebase.num = 1;\n    enccfg.g_timebase.den = 90000;\n    enccfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT;\n    enccfg.rc_resize_allowed = 1;\n    enccfg.rc_min_quantizer = 2;\n    enccfg.rc_max_quantizer = 56;\n    enccfg.rc_undershoot_pct = 100;\n    enccfg.rc_overshoot_pct = 15;\n    enccfg.rc_buf_initial_sz = 500;\n    enccfg.rc_buf_optimal_sz = 600;\n    enccfg.rc_buf_sz = 1000;\n    enccfg.kf_mode = VPX_KF_AUTO;\n    enccfg.kf_max_dist = 3000;\n\n    vpx->rc_max_intra_target = PJ_MAX(300, enccfg.rc_buf_sz * 0.5 * enccfg.g_timebase.num / 10);\n\n    res = vpx_codec_enc_init(&vpx->encoder, vpx_codec_vp8_cx(), &enccfg, flags);\n    if (res != VPX_CODEC_OK) {\n        PJ_LOG(1, (THIS_FILE, \"Failed to init vpx encoder : %s\", vpx_codec_err_to_string(res)));\n        return PJMEDIA_CODEC_EFAILED;\n    }\n\n    vpx_codec_control(&vpx->encoder, VP8E_SET_STATIC_THRESHOLD, 1);\n    vpx_codec_control(&vpx->encoder, VP8E_SET_CPUUSED, -6);   // XXX: test\n    vpx_codec_control(&vpx->encoder, VP8E_SET_TOKEN_PARTITIONS, VP8_ONE_TOKENPARTITION);\n    vpx_codec_control(&vpx->encoder, VP8E_SET_MAX_INTRA_BITRATE_PCT, vpx->rc_max_intra_target);\n#ifdef VP8E_SET_SCREEN_CONTENT_MODE\n    vpx_codec_control(&vpx->encoder, VP8E_SET_SCREEN_CONTENT_MODE, 0);\n#endif\n    vpx->enc_iter = NULL;\n\n    vpx->enc_buf_size = vpx->enc_vafp.framebytes;\n    vpx->enc_buf = pj_pool_alloc(vpx->pool, vpx->enc_buf_size);\n\n    vpx->dec_buf_size = vpx->dec_vafp.framebytes;\n    vpx->dec_buf = pj_pool_alloc(vpx->pool, vpx->dec_buf_size);\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t pj_vpx_decoder_open(vpx_private *vpx) {\n    vpx_codec_flags_t flags = 0;\n    vpx_codec_dec_cfg_t cfg;\n    int res;\n\n    cfg.threads = 1;\n    cfg.h = 0;\n    cfg.w = 0;\n\n    res = vpx_codec_dec_init(&vpx->decoder, vpx_codec_vp8_dx(), &cfg, flags);\n    if (res != VPX_CODEC_OK) {\n        PJ_LOG(1, (THIS_FILE, \"Failed to init vpx decoder : %s\", vpx_codec_err_to_string(res)));\n        return PJ_ENOMEM;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Open codec.\n */\nstatic pj_status_t pj_vpx_codec_open(pjmedia_vid_codec *codec, pjmedia_vid_codec_param *attr) {\n    vpx_private *vpx;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(codec && attr, PJ_EINVAL);\n    vpx = (vpx_private*) codec->codec_data;\n\n    pj_memcpy(&vpx->param, attr, sizeof(*attr));\n\n    /* Normalize encoding MTU in codec param */\n    if (attr->enc_mtu > PJMEDIA_MAX_VID_PAYLOAD_SIZE) {\n        attr->enc_mtu = PJMEDIA_MAX_VID_PAYLOAD_SIZE;\n    }\n\n    /* Init format info and apply-param of decoder */\n    vpx->dec_vfi = pjmedia_get_video_format_info(NULL, vpx->param.dec_fmt.id);\n    if (!vpx->dec_vfi) {\n        status = PJ_EINVAL;\n        goto on_error;\n    }\n    pj_bzero(&vpx->dec_vafp, sizeof(vpx->dec_vafp));\n    vpx->dec_vafp.size = vpx->param.dec_fmt.det.vid.size;\n    vpx->dec_vafp.buffer = NULL;\n    status = (*vpx->dec_vfi->apply_fmt)(vpx->dec_vfi, &vpx->dec_vafp);\n    if (status != PJ_SUCCESS) {\n        goto on_error;\n    }\n\n    /* Init format info and apply-param of encoder */\n    vpx->enc_vfi = pjmedia_get_video_format_info(NULL, vpx->param.dec_fmt.id);\n    if (!vpx->enc_vfi) {\n        status = PJ_EINVAL;\n        goto on_error;\n    }\n    pj_bzero(&vpx->enc_vafp, sizeof(vpx->enc_vafp));\n    vpx->enc_vafp.size = vpx->param.enc_fmt.det.vid.size;\n    vpx->enc_vafp.buffer = NULL;\n    status = (*vpx->enc_vfi->apply_fmt)(vpx->enc_vfi, &vpx->enc_vafp);\n    if (status != PJ_SUCCESS) {\n        goto on_error;\n    }\n\n    /* Open the encoder */\n    TRACE_((THIS_FILE, \"Open vpx version : %s build : %s\", vpx_codec_version_str(), vpx_codec_build_config()));\n\n    if (vpx->param.dir & PJMEDIA_DIR_ENCODING) {\n        status = pj_vpx_encoder_open(vpx);\n        if (status != PJ_SUCCESS) {\n            goto on_error;\n        }\n    }\n    if (vpx->param.dir & PJMEDIA_DIR_DECODING) {\n        status = pj_vpx_decoder_open(vpx);\n        if (status != PJ_SUCCESS) {\n            goto on_error;\n        }\n    }\n\n\n    /* Update codec attributes, e.g: encoding format may be changed by\n     * SDP fmtp negotiation.\n     */\n    pj_memcpy(attr, &vpx->param, sizeof(*attr));\n\n    return PJ_SUCCESS;\n\non_error:\n    pj_vpx_codec_close(codec);\n    return status;\n}\n\n/*\n * Close codec.\n */\nstatic pj_status_t pj_vpx_codec_close(pjmedia_vid_codec *codec) {\n    vpx_private *vpx;\n\n    PJ_ASSERT_RETURN(codec, PJ_EINVAL);\n    vpx = (vpx_private*) codec->codec_data;\n\n    vpx_codec_destroy(&vpx->decoder);\n    vpx_codec_destroy(&vpx->encoder);\n    vpx_img_free(&vpx->rawimg);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Modify codec settings.\n */\nstatic pj_status_t pj_vpx_codec_modify(pjmedia_vid_codec *codec,\n        const pjmedia_vid_codec_param *attr) {\n    vpx_private *vpx = (vpx_private*) codec->codec_data;\n\n    // TODO : add bitrate change support here\n    PJ_UNUSED_ARG(attr);\n    PJ_UNUSED_ARG(vpx);\n\n    return PJ_ENOTSUP;\n}\n\nstatic pj_status_t pj_vpx_codec_get_param(pjmedia_vid_codec *codec,\n        pjmedia_vid_codec_param *param) {\n    vpx_private *vpx;\n\n    PJ_ASSERT_RETURN(codec && param, PJ_EINVAL);\n\n    vpx = (vpx_private*) codec->codec_data;\n    pj_memcpy(param, &vpx->param, sizeof(*param));\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Encode frames.\n */\n\nstatic pj_status_t pj_vpx_codec_encode_begin(pjmedia_vid_codec *codec,\n        const pjmedia_vid_encode_opt *opt, const pjmedia_frame *input,\n        unsigned out_size, pjmedia_frame *output, pj_bool_t *has_more) {\n    vpx_private *vpx = (vpx_private*) codec->codec_data;\n    vpx_image_t *rawimg;\n    vpx_enc_frame_flags_t flags = 0;\n    pj_uint8_t *p;\n    int i, res;\n\n    PJ_ASSERT_RETURN(codec && input, PJ_EINVAL);\n\n    p = (pj_uint8_t*) input->buf;\n\n    *has_more = PJ_FALSE;\n\n    rawimg = &vpx->rawimg;\n    if(input->size < vpx->enc_vafp.framebytes){\n        PJ_LOG(1, (THIS_FILE, \"Frame provided is too small !\"));\n        return PJ_ETOOSMALL;\n    }\n\n    for (i = 0; i < vpx->enc_vfi->plane_cnt; ++i) {\n        rawimg->planes[i] = p;\n        rawimg->stride[i] = vpx->enc_vafp.strides[i];\n        p += vpx->enc_vafp.plane_bytes[i];\n    }\n\n    if (opt && opt->force_keyframe) {\n        flags |= VPX_EFLAG_FORCE_KF;\n        vpx_codec_control(&vpx->encoder, VP8E_SET_MAX_INTRA_BITRATE_PCT, vpx->rc_max_intra_target);\n    }\n\n    res = vpx_codec_encode(&vpx->encoder, rawimg, input->timestamp.u64, 1, flags, VPX_DL_REALTIME);\n    if (res != VPX_CODEC_OK) {\n        PJ_LOG(1, (THIS_FILE, \"Failed to encode : %s %s\", vpx_codec_err_to_string(res), vpx->encoder.err_detail));\n        return PJMEDIA_CODEC_EFAILED;\n    }\n\n    vpx->enc_iter = NULL;\n    vpx->enc_frame_len = 0;\n    vpx->enc_processed = 0;\n    return pj_vpx_codec_encode_more(codec, out_size, output, has_more);\n}\n\nstatic pj_status_t pj_vpx_codec_encode_more(pjmedia_vid_codec *codec,\n        unsigned out_size, pjmedia_frame *output, pj_bool_t *has_more) {\n    vpx_private *vpx = (vpx_private*) codec->codec_data;\n    const vpx_codec_cx_pkt_t *pkt;\n\n    /* Default return */\n    *has_more = PJ_FALSE;\n    output->size = 0;\n    output->type = PJMEDIA_FRAME_TYPE_NONE;\n\n    if (vpx->enc_frame_len == 0) {\n        /*\n         * For now we assume that we have only one cx data here\n         * Which is probably fine as we do not ask encoder to bufferize\n         */\n        //PJ_LOG(4, (THIS_FILE, \"Encode one frame at %p\", vpx->enc_iter));\n        pkt = vpx_codec_get_cx_data(&vpx->encoder, &vpx->enc_iter);\n        if (pkt == NULL ) {\n            if (!vpx->encoder.err) {\n                PJ_LOG(3, (THIS_FILE, \"Encoder packet dropped\"));\n                return PJ_SUCCESS;\n            } else {\n                PJ_LOG(1, (THIS_FILE, \"Failed to get cx datas : %s\", vpx_codec_err_to_string(vpx->encoder.err)));\n                return PJMEDIA_CODEC_EFAILED;\n            }\n        } else if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {\n            pj_memcpy(vpx->enc_buf, pkt->data.frame.buf, pkt->data.frame.sz);\n            vpx->enc_frame_len = pkt->data.frame.sz;\n            vpx->enc_processed = 0;\n            vpx->enc_buf_is_keyframe = !!(pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? PJ_TRUE : PJ_FALSE;\n\n            //PJ_LOG(4, (THIS_FILE, \"Encoded with 0 byte : %d\", ((pj_uint8_t*)(vpx->enc_buf))[0]));\n        } else {\n            PJ_LOG(6, (THIS_FILE, \"Vpx packet kind %d not taken into account\", pkt->kind));\n            return PJ_SUCCESS;\n        }\n    }\n    // TODO we should support if iter not over too\n\n    if(vpx->enc_frame_len > 0) {\n        //PJ_LOG(4, (THIS_FILE, \"We have an enc_frame : %d; max : %d\", vpx->enc_frame_len, vpx->param.enc_mtu));\n        /* Reserve 1 octet for vp8 packetization info */\n        unsigned max_size = vpx->param.enc_mtu - 1;\n        unsigned remaining_size = vpx->enc_frame_len - vpx->enc_processed;\n        /* TODO : we could equally distributed packets sizes */\n        unsigned payload_len = PJ_MIN(remaining_size, max_size);\n        pj_uint8_t* p = (pj_uint8_t*) output->buf;\n        pj_uint8_t* s = (pj_uint8_t*) vpx->enc_buf;\n        //PJ_LOG(4, (THIS_FILE, \"Payload : %d\", payload_len));\n\n        output->type = PJMEDIA_FRAME_TYPE_VIDEO;\n        output->bit_info = 0;\n        if (vpx->enc_buf_is_keyframe) {\n            output->bit_info |= PJMEDIA_VID_FRM_KEYFRAME;\n        }\n        /* Set vp8 packetization info */\n        p[0] = 0;\n        if(vpx->enc_processed == 0)\n            p[0] |= 0x10;\n        if(!vpx->enc_buf_is_keyframe)\n            p[0] |= 0x20;\n\n        pj_memcpy( (p + 1), (s + vpx->enc_processed), payload_len);\n        output->size = payload_len + 1;\n\n        vpx->enc_processed += payload_len;\n        *has_more = !(vpx->enc_processed == vpx->enc_frame_len);\n    }\n\n    //PJ_LOG(4, (THIS_FILE, \"Encoded size %d\", output->size));\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Decode frame.\n */\n\nstatic pj_status_t check_decode_result(pjmedia_vid_codec *codec,\n                                       const vpx_image_t *img,\n                                       const pj_timestamp *ts) {\n    vpx_private *vpx = (vpx_private*) codec->codec_data;\n    pjmedia_video_apply_fmt_param *vafp = &vpx->dec_vafp;\n    pjmedia_event event;\n    int res, reference_updates = 0;\n\n    /* Check for format change.\n     */\n    if (img->d_w != (int) vafp->size.w || img->d_h != (int) vafp->size.h) {\n        pj_status_t status;\n\n        /* Update decoder format in param */\n        vpx->param.dec_fmt.det.vid.size.w = img->d_w;\n        vpx->param.dec_fmt.det.vid.size.h = img->d_h;\n\n        /* Re-init format info and apply-param of decoder */\n        vpx->dec_vfi = pjmedia_get_video_format_info(NULL, vpx->param.dec_fmt.id);\n        if (!vpx->dec_vfi)\n            return PJ_ENOTSUP;\n        pj_bzero(&vpx->dec_vafp, sizeof(vpx->dec_vafp));\n        vpx->dec_vafp.size = vpx->param.dec_fmt.det.vid.size;\n        vpx->dec_vafp.buffer = NULL;\n        status = (*vpx->dec_vfi->apply_fmt)(vpx->dec_vfi, &vpx->dec_vafp);\n        if (status != PJ_SUCCESS)\n            return status;\n\n        /* Realloc buffer if necessary */\n\tif (vpx->dec_vafp.framebytes > vpx->dec_buf_size) {\n\t    PJ_LOG(5,(THIS_FILE, \"Reallocating decoding buffer %u --> %u\",\n\t\t       (unsigned)vpx->dec_buf_size,\n\t\t       (unsigned)vpx->dec_vafp.framebytes));\n\t    vpx->dec_buf_size = (unsigned)vpx->dec_vafp.framebytes;\n\t    vpx->dec_buf = pj_pool_alloc(vpx->pool, vpx->dec_buf_size);\n\t}\n\n        /* Broadcast format changed event */\n        pjmedia_event_init(&event, PJMEDIA_EVENT_FMT_CHANGED, ts, codec);\n        event.data.fmt_changed.dir = PJMEDIA_DIR_DECODING;\n        pj_memcpy(&event.data.fmt_changed.new_fmt, &vpx->param.dec_fmt, sizeof(vpx->param.dec_fmt));\n        pjmedia_event_publish(NULL, codec, &event, 0);\n    }\n\n    /* Check for found keyframe */\n    res = vpx_codec_control(&vpx->decoder, VP8D_GET_LAST_REF_UPDATES, &reference_updates);\n    if (res == VPX_CODEC_OK) {\n        pj_bool_t got_keyframe = (reference_updates & VP8_GOLD_FRAME);\n        if (got_keyframe) {\n            pj_get_timestamp(&vpx->last_dec_keyframe_ts);\n\n            /* Broadcast keyframe event */\n            pjmedia_event_init(&event, PJMEDIA_EVENT_KEYFRAME_FOUND, ts, codec);\n            pjmedia_event_publish(NULL, codec, &event, 0);\n        }\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t pj_vpx_codec_decode_whole(pjmedia_vid_codec *codec,\n                                             const vpx_image_t *img,\n                                             const pj_timestamp *ts,\n                                             unsigned output_buf_len,\n                                             pjmedia_frame *output) {\n    pj_status_t status;\n    int half_width = (img->d_w + 1) >> 1;\n    int half_height = (img->d_h + 1) >> 1;\n    uint8_t* buf;\n    uint32_t pos = 0;\n    uint32_t plane, y;\n    uint8_t* buffer = output->buf;\n    int buffer_size = img->d_w * img->d_h + half_width * half_height * 2;\n\n    output->type = PJMEDIA_FRAME_TYPE_NONE;\n    output->size = 0;\n\n    /* Check decoding result, e.g: see if the format got changed,\n     * keyframe found/missing.\n     */\n    status = check_decode_result(codec, img, ts);\n    if (status != PJ_SUCCESS)\n    \treturn status;\n\n    /* Reset output frame bit info */\n    output->bit_info = 0;\n    output->timestamp = *ts;\n\n    if (buffer_size <= output_buf_len) {\n        for (plane = 0; plane < 3; plane++) {\n            unsigned int width = (plane ? half_width : img->d_w);\n            unsigned int height = (plane ? half_height : img->d_h);\n            buf = img->planes[plane];\n            for (y = 0; y < height; y++) {\n                pj_memcpy(&buffer[pos], buf, width);\n                pos += width;\n                buf += img->stride[plane];\n            }\n        }\n        output->size = buffer_size;\n        output->type = PJMEDIA_FRAME_TYPE_VIDEO;\n        return PJ_SUCCESS;\n    } else {\n        PJ_LOG(1, (THIS_FILE, \"Frame ignored because of too small buffer\"));\n        return PJ_ETOOSMALL;\n    }\n}\n\nstatic pj_status_t pj_vpx_codec_decode(pjmedia_vid_codec *codec,\n                                       pj_size_t pkt_count,\n                                       pjmedia_frame packets[],\n                                       unsigned out_size,\n                                       pjmedia_frame *output) {\n    vpx_private *vpx = (vpx_private*) codec->codec_data;\n    vpx_image_t *img;\n    vpx_codec_iter_t iter;\n    int i, res;\n\n    PJ_ASSERT_RETURN(codec && pkt_count > 0 && packets && output, PJ_EINVAL);\n\n    vpx->dec_frame_len = 0;\n\n    /* TODO : packet parsing is absolutely incomplete here !!!!\n     * We should manage extensions, partitions etc\n     * */\n    for (i = 0; i < pkt_count; ++i) {\n        pj_uint8_t *data;\n        pj_uint8_t extended_bit, s_bit, partition_id;\n        unsigned extension_len = 0;\n        unsigned payload_size = packets[i].size;\n\n        if(payload_size == 0) {\n            continue;\n        }\n\n        data = packets[i].buf;\n        extended_bit = (*data) & 0x80;\n        s_bit = (*data) & 0x20;\n        partition_id = (*data) & 0x1F;\n\n        PJ_UNUSED_ARG(s_bit);\n        PJ_UNUSED_ARG(partition_id);\n\n        /* First octet is for */\n        /* |X|R|N|S|PartID | */\n        if(extended_bit) {\n            pj_uint8_t i_bit, l_bit, t_bit, k_bit;\n            (data)++;\n            extension_len++;\n            i_bit = (*data) & 0x80;\n            l_bit = (*data) & 0x40;\n            t_bit = (*data) & 0x20;\n            k_bit = (*data) & 0x10;\n            if(payload_size <= 1) {\n                PJ_LOG(4, (THIS_FILE, \"Error decoding VP8 extended attributes\"));\n                continue;\n            }\n            /* We have extension in octet 2 */\n            /* |I|L|T|K| RSV   | */\n            if (i_bit) {\n                data++;\n                if(payload_size <= 2){\n                    PJ_LOG(4, (THIS_FILE, \"Error decoding VP8 extended picture ID attribute\"));\n                    continue;\n                }\n                // I present check M flag for long picture ID\n                if ((*data) & 0x80) {\n                    data++;\n                }\n            }\n            if (l_bit) {\n                data++;\n            }\n            if (t_bit || k_bit) {\n                data++;\n            }\n        }\n\n        data++;\n        payload_size = packets[i].size - (data - (pj_uint8_t*)packets[i].buf);\n\n        //PJ_LOG(4, (THIS_FILE, \"Unpack RTP %d size %d, start %d\", i, packets[i].size, s[0] & 0x10));\n        if((vpx->dec_frame_len + payload_size) < vpx->dec_buf_size) {\n            pj_memcpy(vpx->dec_buf + vpx->dec_frame_len, data, payload_size);\n            vpx->dec_frame_len += payload_size;\n        } else {\n            PJ_LOG(1, (THIS_FILE, \"Buffer is too small\"));\n        }\n    }\n\n    if(vpx->dec_frame_len == 0){\n        PJ_LOG(1, (THIS_FILE, \"No content for these packets\"));\n        return PJ_SUCCESS;\n    }\n\n    res = vpx_codec_decode(&vpx->decoder, vpx->dec_buf, vpx->dec_frame_len, NULL, VPX_DL_REALTIME);\n    switch (res) {\n        case VPX_CODEC_UNSUP_BITSTREAM:\n        case VPX_CODEC_UNSUP_FEATURE:\n        case VPX_CODEC_CORRUPT_FRAME:\n            /* Fatal errors to the stream, request a keyframe to see if we can recover */\n            PJ_LOG(4, (THIS_FILE, \"Fatal error decoding stream: (%d) %s\", res, vpx_codec_err_to_string(res)));\n            pjmedia_event event;\n            pjmedia_event_init(&event, PJMEDIA_EVENT_KEYFRAME_MISSING, NULL, codec);\n            pjmedia_event_publish(NULL, codec, &event, 0);\n            return PJMEDIA_CODEC_EBADBITSTREAM;\n        case VPX_CODEC_OK:\n            break;\n        default:\n            PJ_LOG(4, (THIS_FILE, \"Failed to decode packets: (%d) %s\", res, vpx_codec_err_to_string(res)));\n            return PJMEDIA_ERROR;\n    }\n\n    iter = NULL;\n    for (;;) {\n        pj_status_t status;\n        img = vpx_codec_get_frame(&vpx->decoder, &iter);\n        if (img == NULL)\n            break;\n        status = pj_vpx_codec_decode_whole(codec, img, &packets[0].timestamp, out_size, output);\n        if (status != PJ_SUCCESS) {\n            PJ_LOG(4, (THIS_FILE, \"Failed to decode frame\"));\n            /* XXX stop processing and request keyframe? */\n        }\n    }\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_HAS_VPX_VID_CODEC */\n\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-videodev/avf_dev.m",
    "content": "/*\n * Copyright (C) 2014-present AG Projects (http://ag-projects.com)\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia-videodev/videodev_imp.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n\n#if defined(PJMEDIA_HAS_VIDEO) && PJMEDIA_HAS_VIDEO != 0 && \\\n    defined(PJMEDIA_VIDEO_DEV_HAS_AVF) && PJMEDIA_VIDEO_DEV_HAS_AVF != 0\n\n#include <Foundation/NSAutoreleasePool.h>\n#include <AVFoundation/AVFoundation.h>\n#include <QuartzCore/QuartzCore.h>\n#include <dispatch/dispatch.h>\n\n#define THIS_FILE\t\t\"avf_dev.c\"\n#define DEFAULT_CLOCK_RATE\t90000\n#define DEFAULT_WIDTH\t\t640\n#define DEFAULT_HEIGHT\t\t480\n#define DEFAULT_FPS\t\t15\n\n\ntypedef struct avf_fmt_info\n{\n    pjmedia_format_id   pjmedia_format;\n    unsigned\t\tavf_format;\n} avf_fmt_info;\n\nstatic avf_fmt_info avf_fmts[] =\n{\n    {PJMEDIA_FORMAT_BGRA, kCVPixelFormatType_32BGRA},\n    {PJMEDIA_FORMAT_YUY2, kCVPixelFormatType_422YpCbCr8_yuvs},\n    {PJMEDIA_FORMAT_UYVY, kCVPixelFormatType_422YpCbCr8},\n};\n\n/* avf device info */\nstruct avf_dev_info\n{\n    pjmedia_vid_dev_info\t info;\n    AVCaptureDevice              *dev;\n};\n\n/* avf factory */\nstruct avf_factory\n{\n    pjmedia_vid_dev_factory\t base;\n    pj_pool_t\t\t\t*pool;\n    pj_pool_t\t\t\t*dev_pool;\n    pj_pool_factory\t\t*pf;\n\n    unsigned\t\t\t dev_count;\n    struct avf_dev_info\t\t*dev_info;\n};\n\nstruct avf_stream;    /* forward declaration */\ntypedef void (*func_ptr)(struct avf_stream *strm);\n\n@interface AVFDelegate: NSObject <AVCaptureVideoDataOutputSampleBufferDelegate>\n{\n@public\n    struct avf_stream *stream;\n}\n@end\n\n\n/* Video stream. */\nstruct avf_stream\n{\n    pjmedia_vid_dev_stream  base;\t    /**< Base stream\t       */\n    pjmedia_vid_dev_param   param;\t    /**< Settings\t       */\n    pj_pool_t\t\t   *pool;           /**< Memory pool.          */\n\n    pj_timestamp\t    cap_frame_ts;   /**< Captured frame tstamp */\n    unsigned\t\t    cap_ts_inc;\t    /**< Increment\t       */\n\n    pjmedia_vid_dev_cb\t    vid_cb;         /**< Stream callback.      */\n    void\t\t   *user_data;      /**< Application data.     */\n\n    pjmedia_rect_size\t    size;\n\n    pj_bool_t\t\t    cap_thread_initialized;\n    pj_thread_desc\t    cap_thread_desc;\n    pj_thread_t\t\t   *cap_thread;\n    pj_bool_t               cap_exited;\n\n    struct avf_factory      *af;\n    pj_status_t             status;\n    pj_bool_t               is_running;\n\n    dispatch_queue_t                    video_ops_queue;\n\n    AVCaptureSession\t\t\t*cap_session;\n    AVCaptureDeviceInput\t\t*dev_input;\n    AVCaptureVideoDataOutput\t        *video_output;\n    AVFDelegate                         *delegate;\n};\n\n\n/* Prototypes */\nstatic pj_status_t avf_factory_init(pjmedia_vid_dev_factory *f);\nstatic pj_status_t avf_factory_destroy(pjmedia_vid_dev_factory *f);\nstatic pj_status_t avf_factory_refresh(pjmedia_vid_dev_factory *f);\nstatic unsigned    avf_factory_get_dev_count(pjmedia_vid_dev_factory *f);\nstatic pj_status_t avf_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t   unsigned index,\n\t\t\t\t\t   pjmedia_vid_dev_info *info);\nstatic pj_status_t avf_factory_default_param(pj_pool_t *pool,\n\t\t\t\t\t    pjmedia_vid_dev_factory *f,\n\t\t\t\t\t    unsigned index,\n\t\t\t\t\t    pjmedia_vid_dev_param *param);\nstatic pj_status_t avf_factory_create_stream(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t     pjmedia_vid_dev_param *param,\n\t\t\t\t\t     const pjmedia_vid_dev_cb *cb,\n\t\t\t\t\t     void *user_data,\n\t\t\t\t\t     pjmedia_vid_dev_stream **p_vid_strm);\n\nstatic pj_status_t avf_stream_get_param(pjmedia_vid_dev_stream *strm,\n\t\t\t\t        pjmedia_vid_dev_param *param);\nstatic pj_status_t avf_stream_get_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t      pjmedia_vid_dev_cap cap,\n\t\t\t\t      void *value);\nstatic pj_status_t avf_stream_set_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t      pjmedia_vid_dev_cap cap,\n\t\t\t\t      const void *value);\nstatic pj_status_t avf_stream_start(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t avf_stream_stop(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t avf_stream_destroy(pjmedia_vid_dev_stream *strm);\n\n/* Operations */\nstatic pjmedia_vid_dev_factory_op factory_op =\n{\n    &avf_factory_init,\n    &avf_factory_destroy,\n    &avf_factory_get_dev_count,\n    &avf_factory_get_dev_info,\n    &avf_factory_default_param,\n    &avf_factory_create_stream,\n    &avf_factory_refresh\n};\n\nstatic pjmedia_vid_dev_stream_op stream_op =\n{\n    &avf_stream_get_param,\n    &avf_stream_get_cap,\n    &avf_stream_set_cap,\n    &avf_stream_start,\n    NULL,\n    NULL,\n    &avf_stream_stop,\n    &avf_stream_destroy\n};\n\n\n/****************************************************************************\n * Factory operations\n */\n/*\n * Init avf video driver.\n */\npjmedia_vid_dev_factory* pjmedia_avf_factory(pj_pool_factory *pf)\n{\n    struct avf_factory *f;\n    pj_pool_t *pool;\n\n    pool = pj_pool_create(pf, \"avf video\", 4000, 4000, NULL);\n    f = PJ_POOL_ZALLOC_T(pool, struct avf_factory);\n    f->pf = pf;\n    f->pool = pool;\n    f->base.op = &factory_op;\n\n    return &f->base;\n}\n\n\n/* API: init factory */\nstatic pj_status_t avf_factory_init(pjmedia_vid_dev_factory *f)\n{\n    return avf_factory_refresh(f);\n}\n\n/* API: destroy factory */\nstatic pj_status_t avf_factory_destroy(pjmedia_vid_dev_factory *f)\n{\n    struct avf_factory *af = (struct avf_factory*)f;\n    pj_pool_t *pool = af->pool;\n\n    if (af->dev_pool)\n        pj_pool_release(af->dev_pool);\n    af->pool = NULL;\n    if (pool)\n        pj_pool_release(pool);\n\n    return PJ_SUCCESS;\n}\n\n/* API: refresh the list of devices */\nstatic pj_status_t avf_factory_refresh(pjmedia_vid_dev_factory *f)\n{\n    struct avf_factory *af = (struct avf_factory*)f;\n    struct avf_dev_info *di;\n    unsigned dev_count = 0;\n    NSAutoreleasePool *apool = [[NSAutoreleasePool alloc]init];\n    NSArray *dev_array;\n\n    if (af->dev_pool) {\n        pj_pool_release(af->dev_pool);\n        af->dev_pool = NULL;\n    }\n\n    dev_array = [AVCaptureDevice devices];\n    for (AVCaptureDevice *device in dev_array) {\n\tif ([device hasMediaType:AVMediaTypeVideo] && ![device isSuspended]) {\n\t    dev_count++;\n\t}\n    }\n\n    /* Initialize input and output devices here */\n    af->dev_count = 0;\n    af->dev_pool = pj_pool_create(af->pf, \"avf video\", 500, 500, NULL);\n\n    af->dev_info = (struct avf_dev_info*) pj_pool_calloc(af->dev_pool, dev_count, sizeof(struct avf_dev_info));\n    for (AVCaptureDevice *device in dev_array) {\n\tif (![device hasMediaType:AVMediaTypeVideo] || [device isSuspended]) {\n\t    continue;\n\t}\n\n        di = &af->dev_info[af->dev_count++];\n        pj_bzero(di, sizeof(*di));\n        di->dev = device;\n        pj_ansi_strncpy(di->info.name, [device.localizedName UTF8String], sizeof(di->info.name));\n        pj_ansi_strncpy(di->info.driver, \"AVF\", sizeof(di->info.driver));\n        di->info.dir = PJMEDIA_DIR_CAPTURE;\n        di->info.has_callback = PJ_TRUE;\n        di->info.fmt_cnt = 0;\n        di->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;\n\n        PJ_LOG(4, (THIS_FILE, \" dev: %s\", di->info.name));\n\n        for (AVCaptureDeviceFormat* f in [device formats]) {\n            unsigned i;\n            CMFormatDescriptionRef desc = [f formatDescription];\n            for (i = 0; i < PJ_ARRAY_SIZE(avf_fmts); i++) {\n                if (CMFormatDescriptionGetMediaSubType(desc) == avf_fmts[i].avf_format) {\n                    char fmt_name[5];\n                    CMVideoDimensions dim = CMVideoFormatDescriptionGetDimensions(desc);\n                    if (dim.width < 640)\n                        continue;\n                    pjmedia_fourcc_name(avf_fmts[i].pjmedia_format, fmt_name);\n                    PJ_LOG(4, (THIS_FILE, \"  detected resolution %dx%d (%s)\", dim.width, dim.height, fmt_name));\n                    pjmedia_format *fmt = &di->info.fmt[di->info.fmt_cnt++];\n                    pjmedia_format_init_video(fmt,\n                                              avf_fmts[i].pjmedia_format,\n                                              dim.width,\n                                              dim.height,\n                                              DEFAULT_FPS, 1);\n                }\n            }\n        }\n\n        if (di->info.fmt_cnt == 0) {\n            PJ_LOG(4, (THIS_FILE, \"  there are no compatible formats, using default\"));\n            pjmedia_format *fmt = &di->info.fmt[di->info.fmt_cnt++];\n            pjmedia_format_init_video(fmt,\n                                      avf_fmts[0].pjmedia_format,\n                                      DEFAULT_WIDTH,\n                                      DEFAULT_HEIGHT,\n                                      DEFAULT_FPS, 1);\n        }\n    }\n\n    [apool release];\n\n    PJ_LOG(4, (THIS_FILE, \"avf video has %d devices\", af->dev_count));\n\n    return PJ_SUCCESS;\n}\n\n/* API: get number of devices */\nstatic unsigned avf_factory_get_dev_count(pjmedia_vid_dev_factory *f)\n{\n    struct avf_factory *af = (struct avf_factory*)f;\n    return af->dev_count;\n}\n\n/* API: get device info */\nstatic pj_status_t avf_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t    unsigned index,\n\t\t\t\t\t    pjmedia_vid_dev_info *info)\n{\n    struct avf_factory *af = (struct avf_factory*)f;\n    PJ_ASSERT_RETURN(index < af->dev_count, PJMEDIA_EVID_INVDEV);\n\n    pj_memcpy(info, &af->dev_info[index].info, sizeof(*info));\n\n    return PJ_SUCCESS;\n}\n\n/* API: create default device parameter */\nstatic pj_status_t avf_factory_default_param(pj_pool_t *pool,\n\t\t\t\t\t     pjmedia_vid_dev_factory *f,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_vid_dev_param *param)\n{\n    struct avf_factory *af = (struct avf_factory*)f;\n    struct avf_dev_info *di = &af->dev_info[index];\n\n    PJ_ASSERT_RETURN(index < af->dev_count, PJMEDIA_EVID_INVDEV);\n    PJ_UNUSED_ARG(pool);\n\n    pj_bzero(param, sizeof(*param));\n    param->dir = PJMEDIA_DIR_CAPTURE;\n    param->cap_id = index;\n    param->rend_id = PJMEDIA_VID_INVALID_DEV;\n    param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;\n    param->clock_rate = DEFAULT_CLOCK_RATE;\n    pj_memcpy(&param->fmt, &di->info.fmt[0], sizeof(param->fmt));\n\n    return PJ_SUCCESS;\n}\n\nstatic avf_fmt_info* get_avf_format_info(pjmedia_format_id id)\n{\n    unsigned i;\n\n    for (i = 0; i < PJ_ARRAY_SIZE(avf_fmts); i++) {\n        if (avf_fmts[i].pjmedia_format == id)\n            return &avf_fmts[i];\n    }\n\n    return NULL;\n}\n\n\n@implementation AVFDelegate\n- (void)captureOutput:(AVCaptureOutput *)captureOutput\n\t\t      didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer\n\t\t      fromConnection:(AVCaptureConnection *)connection\n{\n    pjmedia_frame frame = {0};\n    CVImageBufferRef img;\n    CVReturn ret;\n    OSType type;\n    size_t width, height;\n\n    /* Register thread if needed */\n    if (stream->cap_thread_initialized == 0 || !pj_thread_is_registered()) {\n        pj_bzero(stream->cap_thread_desc, sizeof(pj_thread_desc));\n        pj_thread_register(\"avf_cap\", stream->cap_thread_desc, &stream->cap_thread);\n        stream->cap_thread_initialized = 1;\n    }\n\n    if (!sampleBuffer)\n\treturn;\n\n    /* Get a CMSampleBuffer's Core Video image buffer for the media data */\n    img = CMSampleBufferGetImageBuffer(sampleBuffer);\n    if (!img)\n        return;\n\n    /* Check for supported formats */\n    type = CVPixelBufferGetPixelFormatType(img);\n    switch(type) {\n        case kCVPixelFormatType_32BGRA:\n        case kCVPixelFormatType_422YpCbCr8_yuvs:\n        case kCVPixelFormatType_422YpCbCr8:\n            break;\n        default:\n            PJ_LOG(4, (THIS_FILE, \"Unsupported image format! %c%c%c%c\", type>>24, type>>16, type>>8, type>>0));\n            return;\n    }\n\n    /* Lock the base address of the pixel buffer */\n    ret = CVPixelBufferLockBaseAddress(img, kCVPixelBufferLock_ReadOnly);\n    if (ret != kCVReturnSuccess)\n        return;\n\n    width = CVPixelBufferGetWidth(img);\n    height = CVPixelBufferGetHeight(img);\n\n    /* Prepare frame */\n    frame.type = PJMEDIA_FRAME_TYPE_VIDEO;\n    frame.timestamp.u64 = stream->cap_frame_ts.u64;\n    frame.buf = CVPixelBufferGetBaseAddress(img);\n    frame.size = CVPixelBufferGetBytesPerRow(img) * height;\n\n    if (stream->size.w != width || stream->size.h != height) {\n        PJ_LOG(4, (THIS_FILE, \"AVF image size changed, before: %dx%d, after: %dx%d\", stream->size.w, stream->size.h, width, height));\n    }\n\n    if (stream->vid_cb.capture_cb) {\n        (*stream->vid_cb.capture_cb)(&stream->base, stream->user_data, &frame);\n    }\n\n    stream->cap_frame_ts.u64 += stream->cap_ts_inc;\n\n    /* Unlock the pixel buffer */\n    CVPixelBufferUnlockBaseAddress(img, kCVPixelBufferLock_ReadOnly);\n}\n@end\n\n\nstatic void init_avf_stream(struct avf_stream *strm)\n{\n    const pjmedia_video_format_info *vfi;\n    pjmedia_video_format_detail *vfd;\n    avf_fmt_info *fi = get_avf_format_info(strm->param.fmt.id);\n    NSError *error;\n    pj_status_t status;\n\n    if (!fi) {\n        strm->status = PJMEDIA_EVID_BADFORMAT;\n        return;\n    }\n\n    strm->cap_session = [[AVCaptureSession alloc] init];\n    if (!strm->cap_session) {\n        strm->status = PJ_ENOMEM;\n        return;\n    }\n\n    strm->cap_session.sessionPreset = AVCaptureSessionPresetHigh;\n    vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE);\n    pj_assert(vfd);\n    vfi = pjmedia_get_video_format_info(NULL, strm->param.fmt.id);\n    pj_assert(vfi);\n    vfd->size = strm->size;\n\n    PJ_LOG(4, (THIS_FILE, \"Opening video device at %dx%d resolution\", vfd->size.w, vfd->size.h));\n\n    /* Add the video device to the session as a device input */\n    AVCaptureDevice *videoDevice = strm->af->dev_info[strm->param.cap_id].dev;\n    strm->dev_input = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error: &error];\n    if (!strm->dev_input) {\n        status = PJMEDIA_EVID_SYSERR;\n        return;\n    }\n\n    [strm->cap_session addInput:strm->dev_input];\n\n    strm->video_output = [[AVCaptureVideoDataOutput alloc] init];\n    if (!strm->video_output) {\n        status = PJMEDIA_EVID_SYSERR;\n        return;\n    }\n    [strm->cap_session addOutput:strm->video_output];\n\n    /* Configure the video output */\n    strm->video_output.alwaysDiscardsLateVideoFrames = YES;\n    /* The Apple provided documentation says the only supported key is kCVPixelBufferPixelFormatTypeKey,\n     * but it turns out kCVPixelBufferWidthKey and kCVPixelBufferHeightKey are also required. Thanks\n     * Chromium, for figuring it out.*/\n    strm->video_output.videoSettings =\n        [NSDictionary dictionaryWithObjectsAndKeys: @(fi->avf_format),\n                                                    kCVPixelBufferPixelFormatTypeKey,\n                                                    @(vfd->size.w),\n                                                    kCVPixelBufferWidthKey,\n                                                    @(vfd->size.h),\n                                                    kCVPixelBufferHeightKey,\n                                                    nil];\n    strm->delegate = [[AVFDelegate alloc] init];\n    strm->delegate->stream = strm;\n    dispatch_queue_t queue = dispatch_queue_create(\"AVFQueue\", NULL);\n    [strm->video_output setSampleBufferDelegate:strm->delegate queue:queue];\n    dispatch_release(queue);\n}\n\nstatic void run_func_on_video_queue(struct avf_stream *strm, func_ptr func)\n{\n    dispatch_sync(strm->video_ops_queue, ^{\n        (*func)(strm);\n    });\n}\n\n/* API: create stream */\nstatic pj_status_t avf_factory_create_stream(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t     pjmedia_vid_dev_param *param,\n\t\t\t\t\t     const pjmedia_vid_dev_cb *cb,\n\t\t\t\t\t     void *user_data,\n\t\t\t\t\t     pjmedia_vid_dev_stream **p_vid_strm)\n{\n    struct avf_factory *af = (struct avf_factory*)f;\n    pj_pool_t *pool;\n    struct avf_stream *strm;\n    const pjmedia_video_format_info *vfi;\n    pjmedia_video_format_detail *vfd;\n    pj_status_t status = PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);\n    PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&\n\t\t     param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&\n                     param->dir == PJMEDIA_DIR_CAPTURE,\n\t\t     PJ_EINVAL);\n\n    vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);\n    if (!vfi)\n        return PJMEDIA_EVID_BADFORMAT;\n\n    /* Create and Initialize stream descriptor */\n    pool = pj_pool_create(af->pf, \"avf-dev\", 4000, 4000, NULL);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    strm = PJ_POOL_ZALLOC_T(pool, struct avf_stream);\n    pj_memcpy(&strm->param, param, sizeof(*param));\n    strm->pool = pool;\n    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));\n    strm->user_data = user_data;\n    strm->af = af;\n\n    vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE);\n    pj_memcpy(&strm->size, &vfd->size, sizeof(vfd->size));\n    pj_assert(vfd->fps.num);\n    strm->cap_ts_inc = PJMEDIA_SPF2(strm->param.clock_rate, &vfd->fps, 1);\n\n    /* Create dispatch queue */\n    strm->video_ops_queue = dispatch_queue_create(\"AVF Video Ops\", DISPATCH_QUEUE_SERIAL);\n\n    /* Create capture stream here */\n    strm->status = PJ_SUCCESS;\n    run_func_on_video_queue(strm, init_avf_stream);\n    status = strm->status;\n    if (status != PJ_SUCCESS) {\n        dispatch_release(strm->video_ops_queue);\n        avf_stream_destroy((pjmedia_vid_dev_stream *)strm);\n        return status;\n    }\n\n    /* Update param as output */\n    param->fmt = strm->param.fmt;\n\n    /* Done */\n    strm->base.op = &stream_op;\n    *p_vid_strm = &strm->base;\n\n    return PJ_SUCCESS;\n}\n\n/* API: Get stream info. */\nstatic pj_status_t avf_stream_get_param(pjmedia_vid_dev_stream *s,\n\t\t\t\t        pjmedia_vid_dev_param *pi)\n{\n    struct avf_stream *strm = (struct avf_stream*)s;\n    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);\n\n    pj_memcpy(pi, &strm->param, sizeof(*pi));\n\n    return PJ_SUCCESS;\n}\n\n/* API: get capability */\nstatic pj_status_t avf_stream_get_cap(pjmedia_vid_dev_stream *s,\n\t\t\t\t      pjmedia_vid_dev_cap cap,\n\t\t\t\t      void *pval)\n{\n    struct avf_stream *strm = (struct avf_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n    PJ_UNUSED_ARG(cap);\n    PJ_UNUSED_ARG(pval);\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    return PJMEDIA_EVID_INVCAP;\n}\n\n/* API: set capability */\nstatic pj_status_t avf_stream_set_cap(pjmedia_vid_dev_stream *s,\n\t\t\t\t     pjmedia_vid_dev_cap cap,\n\t\t\t\t     const void *pval)\n{\n    struct avf_stream *strm = (struct avf_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n    PJ_UNUSED_ARG(cap);\n    PJ_UNUSED_ARG(pval);\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    return PJMEDIA_EVID_INVCAP;\n}\n\nstatic void start_avf(struct avf_stream *strm)\n{\n    [strm->cap_session startRunning];\n}\n\nstatic void stop_avf(struct avf_stream *strm)\n{\n    [strm->cap_session stopRunning];\n}\n\n/* API: Start stream. */\nstatic pj_status_t avf_stream_start(pjmedia_vid_dev_stream *strm)\n{\n    struct avf_stream *stream = (struct avf_stream*)strm;\n\n    PJ_LOG(4, (THIS_FILE, \"Starting avf video stream\"));\n\n    if (stream->cap_session) {\n        run_func_on_video_queue(stream, start_avf);\n\tif (![stream->cap_session isRunning])\n\t    return PJMEDIA_EVID_NOTREADY;\n        stream->is_running = PJ_TRUE;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: Stop stream. */\nstatic pj_status_t avf_stream_stop(pjmedia_vid_dev_stream *strm)\n{\n    struct avf_stream *stream = (struct avf_stream*)strm;\n\n    PJ_LOG(4, (THIS_FILE, \"Stopping avf video stream\"));\n\n    if (stream->cap_session && [stream->cap_session isRunning]) {\n        int i;\n        stream->cap_exited = PJ_FALSE;\n        run_func_on_video_queue(stream, stop_avf);\n        stream->is_running = PJ_FALSE;\n        for (i = 50; i >= 0 && !stream->cap_exited; i--) {\n            pj_thread_sleep(10);\n        }\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic void destroy_avf(struct avf_stream *strm)\n{\n    if (strm->cap_session) {\n        [strm->cap_session removeInput:strm->dev_input];\n        [strm->cap_session removeOutput:strm->video_output];\n\t[strm->cap_session release];\n\tstrm->cap_session = NULL;\n    }\n\n    if (strm->delegate) {\n\t[strm->delegate release];\n\tstrm->delegate = NULL;\n    }\n\n    if (strm->dev_input) {\n\tstrm->dev_input = NULL;\n    }\n    if (strm->video_output) {\n\tstrm->video_output = NULL;\n    }\n}\n\n/* API: Destroy stream. */\nstatic pj_status_t avf_stream_destroy(pjmedia_vid_dev_stream *strm)\n{\n    struct avf_stream *stream = (struct avf_stream*)strm;\n\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n\n    avf_stream_stop(strm);\n    run_func_on_video_queue(stream, destroy_avf);\n\n    dispatch_release(stream->video_ops_queue);\n    pj_pool_release(stream->pool);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_VIDEO_DEV_HAS_AVF */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-videodev/avi_dev.c",
    "content": "/* $Id: avi_dev.c 4086 2012-04-26 02:44:41Z ming $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia-videodev/videodev_imp.h>\n#include <pjmedia-videodev/avi_dev.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/rand.h>\n#include <pjmedia/vid_codec.h>\n\n#if defined(PJMEDIA_VIDEO_DEV_HAS_AVI) && PJMEDIA_VIDEO_DEV_HAS_AVI != 0 && \\\n    defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n#define THIS_FILE\t\t\"avi_dev.c\"\n#define DRIVER_NAME\t\t\"AVIDev\"\n#define DEFAULT_CLOCK_RATE\t90000\n#define DEFAULT_WIDTH\t\t640\n#define DEFAULT_HEIGHT\t\t480\n#define DEFAULT_FPS\t\t25\n\ntypedef struct avi_dev_strm avi_dev_strm;\n\n/* avi_ device info */\nstruct avi_dev_info\n{\n    pjmedia_vid_dev_info\t info;\n\n    pj_pool_t\t\t\t*pool;\n    pj_str_t\t\t\t fpath;\n    pj_str_t\t\t\t title;\n    pjmedia_avi_streams\t\t*avi;\n    pjmedia_port                *vid;\n    avi_dev_strm\t\t*strm;\n    pjmedia_vid_codec           *codec;\n    pj_uint8_t                  *enc_buf;\n    pj_size_t                    enc_buf_size;\n};\n\n/* avi_ factory */\nstruct avi_factory\n{\n    pjmedia_vid_dev_factory\t base;\n    pj_pool_t\t\t\t*pool;\n    pj_pool_factory\t\t*pf;\n\n    unsigned\t\t\t dev_count;\n    struct avi_dev_info\t\t*dev_info;\n};\n\n/* Video stream. */\nstruct avi_dev_strm\n{\n    pjmedia_vid_dev_stream\t     base;\t    /**< Base stream\t    */\n    pjmedia_vid_dev_param\t     param;\t    /**< Settings\t    */\n    pj_pool_t\t\t\t    *pool;          /**< Memory pool.       */\n    struct avi_dev_info\t\t    *adi;\n\n    pjmedia_vid_dev_cb\t\t     vid_cb;\t    /**< Stream callback.   */\n    void\t\t\t    *user_data;\t    /**< Application data.  */\n};\n\n\n/* Prototypes */\nstatic pj_status_t avi_factory_init(pjmedia_vid_dev_factory *f);\nstatic pj_status_t avi_factory_destroy(pjmedia_vid_dev_factory *f);\nstatic pj_status_t avi_factory_refresh(pjmedia_vid_dev_factory *f);\nstatic unsigned    avi_factory_get_dev_count(pjmedia_vid_dev_factory *f);\nstatic pj_status_t avi_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_vid_dev_info *info);\nstatic pj_status_t avi_factory_default_param(pj_pool_t *pool,\n                                              pjmedia_vid_dev_factory *f,\n\t\t\t\t\t      unsigned index,\n\t\t\t\t\t      pjmedia_vid_dev_param *param);\nstatic pj_status_t avi_factory_create_stream(\n\t\t\t\t\tpjmedia_vid_dev_factory *f,\n\t\t\t\t\tpjmedia_vid_dev_param *param,\n\t\t\t\t\tconst pjmedia_vid_dev_cb *cb,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tpjmedia_vid_dev_stream **p_vid_strm);\n\nstatic pj_status_t avi_dev_strm_get_param(pjmedia_vid_dev_stream *strm,\n\t\t\t\t\t  pjmedia_vid_dev_param *param);\nstatic pj_status_t avi_dev_strm_get_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t        pjmedia_vid_dev_cap cap,\n\t\t\t\t        void *value);\nstatic pj_status_t avi_dev_strm_set_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t        pjmedia_vid_dev_cap cap,\n\t\t\t\t        const void *value);\nstatic pj_status_t avi_dev_strm_get_frame(pjmedia_vid_dev_stream *strm,\n                                          pjmedia_frame *frame);\nstatic pj_status_t avi_dev_strm_start(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t avi_dev_strm_stop(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t avi_dev_strm_destroy(pjmedia_vid_dev_stream *strm);\n\nstatic void reset_dev_info(struct avi_dev_info *adi);\n\n/* Operations */\nstatic pjmedia_vid_dev_factory_op factory_op =\n{\n    &avi_factory_init,\n    &avi_factory_destroy,\n    &avi_factory_get_dev_count,\n    &avi_factory_get_dev_info,\n    &avi_factory_default_param,\n    &avi_factory_create_stream,\n    &avi_factory_refresh\n};\n\nstatic pjmedia_vid_dev_stream_op stream_op =\n{\n    &avi_dev_strm_get_param,\n    &avi_dev_strm_get_cap,\n    &avi_dev_strm_set_cap,\n    &avi_dev_strm_start,\n    &avi_dev_strm_get_frame,\n    NULL,\n    &avi_dev_strm_stop,\n    &avi_dev_strm_destroy\n};\n\n\n/****************************************************************************\n * Factory operations\n */\n\n/* API */\nPJ_DEF(pj_status_t) pjmedia_avi_dev_create_factory(\n\t\t\t\t    pj_pool_factory *pf,\n\t\t\t\t    unsigned max_dev,\n\t\t\t\t    pjmedia_vid_dev_factory **p_ret)\n{\n    struct avi_factory *cf;\n    pj_pool_t *pool;\n    pj_status_t status;\n\n    pool = pj_pool_create(pf, \"avidevfc%p\", 512, 512, NULL);\n    cf = PJ_POOL_ZALLOC_T(pool, struct avi_factory);\n    cf->pf = pf;\n    cf->pool = pool;\n    cf->dev_count = max_dev;\n    cf->base.op = &factory_op;\n\n    cf->dev_info = (struct avi_dev_info*)\n \t\t   pj_pool_calloc(cf->pool, cf->dev_count,\n \t\t\t\t  sizeof(struct avi_dev_info));\n\n    if (p_ret) {\n\t*p_ret = &cf->base;\n    }\n\n    status = pjmedia_vid_register_factory(NULL, &cf->base);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    PJ_LOG(4, (THIS_FILE, \"AVI dev factory created with %d virtual device(s)\",\n\t       cf->dev_count));\n\n    return PJ_SUCCESS;\n}\n\n/* API: init factory */\nstatic pj_status_t avi_factory_init(pjmedia_vid_dev_factory *f)\n{\n    struct avi_factory *cf = (struct avi_factory*)f;\n    unsigned i;\n\n    for (i=0; i<cf->dev_count; ++i) {\n\treset_dev_info(&cf->dev_info[i]);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: destroy factory */\nstatic pj_status_t avi_factory_destroy(pjmedia_vid_dev_factory *f)\n{\n    struct avi_factory *cf = (struct avi_factory*)f;\n    pj_pool_t *pool = cf->pool;\n\n    cf->pool = NULL;\n    pj_pool_release(pool);\n\n    return PJ_SUCCESS;\n}\n\n/* API: refresh the list of devices */\nstatic pj_status_t avi_factory_refresh(pjmedia_vid_dev_factory *f)\n{\n    PJ_UNUSED_ARG(f);\n    return PJ_SUCCESS;\n}\n\n/* API: get number of devices */\nstatic unsigned avi_factory_get_dev_count(pjmedia_vid_dev_factory *f)\n{\n    struct avi_factory *cf = (struct avi_factory*)f;\n    return cf->dev_count;\n}\n\n/* API: get device info */\nstatic pj_status_t avi_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_vid_dev_info *info)\n{\n    struct avi_factory *cf = (struct avi_factory*)f;\n\n    PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);\n\n    pj_memcpy(info, &cf->dev_info[index].info, sizeof(*info));\n\n    return PJ_SUCCESS;\n}\n\n/* API: create default device parameter */\nstatic pj_status_t avi_factory_default_param(pj_pool_t *pool,\n                                              pjmedia_vid_dev_factory *f,\n\t\t\t\t\t      unsigned index,\n\t\t\t\t\t      pjmedia_vid_dev_param *param)\n{\n    struct avi_factory *cf = (struct avi_factory*)f;\n    struct avi_dev_info *di = &cf->dev_info[index];\n\n    PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);\n\n    PJ_UNUSED_ARG(pool);\n\n    pj_bzero(param, sizeof(*param));\n    param->dir = PJMEDIA_DIR_CAPTURE;\n    param->cap_id = index;\n    param->rend_id = PJMEDIA_VID_INVALID_DEV;\n    param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;\n    param->clock_rate = DEFAULT_CLOCK_RATE;\n    pj_memcpy(&param->fmt, &di->info.fmt[0], sizeof(param->fmt));\n\n    return PJ_SUCCESS;\n}\n\n/* reset dev info */\nstatic void reset_dev_info(struct avi_dev_info *adi)\n{\n    /* Close avi streams */\n    if (adi->avi) {\n\tunsigned i, cnt;\n\n\tcnt = pjmedia_avi_streams_get_num_streams(adi->avi);\n\tfor (i=0; i<cnt; ++i) {\n\t    pjmedia_avi_stream *as;\n\n\t    as = pjmedia_avi_streams_get_stream(adi->avi, i);\n\t    if (as) {\n\t\tpjmedia_port *port;\n\t\tport = pjmedia_avi_stream_get_port(as);\n\t\tpjmedia_port_destroy(port);\n\t    }\n\t}\n\tadi->avi = NULL;\n    }\n\n    if (adi->codec) {\n        pjmedia_vid_codec_close(adi->codec);\n        adi->codec = NULL;\n    }\n\n    if (adi->pool)\n\tpj_pool_release(adi->pool);\n\n    pj_bzero(adi, sizeof(*adi));\n\n    /* Fill up with *dummy\" device info */\n    pj_ansi_strncpy(adi->info.name, \"AVI Player\", sizeof(adi->info.name)-1);\n    pj_ansi_strncpy(adi->info.driver, DRIVER_NAME, sizeof(adi->info.driver)-1);\n    adi->info.dir = PJMEDIA_DIR_CAPTURE;\n    adi->info.has_callback = PJ_FALSE;\n}\n\n/* API: release resources */\nPJ_DEF(pj_status_t) pjmedia_avi_dev_free(pjmedia_vid_dev_index id)\n{\n    pjmedia_vid_dev_factory *f;\n    struct avi_factory *cf;\n    unsigned local_idx;\n    struct avi_dev_info *adi;\n    pj_status_t status;\n\n    /* Lookup the factory and local device index */\n    status = pjmedia_vid_dev_get_local_index(id, &f, &local_idx);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* The factory must be AVI factory */\n    PJ_ASSERT_RETURN(f->op->init == &avi_factory_init, PJMEDIA_EVID_INVDEV);\n    cf = (struct avi_factory*)f;\n\n    /* Device index should be valid */\n    PJ_ASSERT_RETURN(local_idx <= cf->dev_count, PJ_EBUG);\n    adi = &cf->dev_info[local_idx];\n\n    /* Cannot configure if stream is running */\n    if (adi->strm)\n\treturn PJ_EBUSY;\n\n    /* Reset */\n    reset_dev_info(adi);\n    return PJ_SUCCESS;\n}\n\n/* API: get param */\nPJ_DEF(pj_status_t) pjmedia_avi_dev_get_param(pjmedia_vid_dev_index id,\n                                              pjmedia_avi_dev_param *prm)\n{\n    pjmedia_vid_dev_factory *f;\n    struct avi_factory *cf;\n    unsigned local_idx;\n    struct avi_dev_info *adi;\n    pj_status_t status;\n\n    /* Lookup the factory and local device index */\n    status = pjmedia_vid_dev_get_local_index(id, &f, &local_idx);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* The factory must be factory */\n    PJ_ASSERT_RETURN(f->op->init == &avi_factory_init, PJMEDIA_EVID_INVDEV);\n    cf = (struct avi_factory*)f;\n\n    /* Device index should be valid */\n    PJ_ASSERT_RETURN(local_idx <= cf->dev_count, PJ_EBUG);\n    adi = &cf->dev_info[local_idx];\n\n    pj_bzero(prm, sizeof(*prm));\n    prm->path = adi->fpath;\n    prm->title = adi->title;\n    prm->avi_streams = adi->avi;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void) pjmedia_avi_dev_param_default(pjmedia_avi_dev_param *p)\n{\n    pj_bzero(p, sizeof(*p));\n}\n\n/* API: configure the AVI */\nPJ_DEF(pj_status_t) pjmedia_avi_dev_alloc( pjmedia_vid_dev_factory *f,\n                                           pjmedia_avi_dev_param *p,\n                                           pjmedia_vid_dev_index *p_id)\n{\n    pjmedia_vid_dev_index id;\n    struct avi_factory *cf = (struct avi_factory*)f;\n    unsigned local_idx;\n    struct avi_dev_info *adi = NULL;\n    pjmedia_format avi_fmt;\n    const pjmedia_video_format_info *vfi;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(f && p && p_id, PJ_EINVAL);\n\n    if (p_id)\n\t*p_id = PJMEDIA_VID_INVALID_DEV;\n\n    /* Get a free dev */\n    for (local_idx=0; local_idx<cf->dev_count; ++local_idx) {\n\tif (cf->dev_info[local_idx].avi == NULL) {\n\t    adi = &cf->dev_info[local_idx];\n\t    break;\n\t}\n    }\n\n    if (!adi)\n\treturn PJ_ETOOMANY;\n\n    /* Convert local ID to global id */\n    status = pjmedia_vid_dev_get_global_index(&cf->base, local_idx, &id);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Reset */\n    if (adi->pool) {\n\tpj_pool_release(adi->pool);\n    }\n    pj_bzero(adi, sizeof(*adi));\n\n    /* Reinit */\n    PJ_ASSERT_RETURN(p->path.slen, PJ_EINVAL);\n    adi->pool = pj_pool_create(cf->pf, \"avidi%p\", 512, 512, NULL);\n\n\n    /* Open the AVI */\n    pj_strdup_with_null(adi->pool, &adi->fpath, &p->path);\n    status = pjmedia_avi_player_create_streams(adi->pool, adi->fpath.ptr, 0,\n                                               &adi->avi);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    adi->vid = pjmedia_avi_streams_get_stream_by_media(adi->avi, 0,\n                                                       PJMEDIA_TYPE_VIDEO);\n    if (!adi->vid) {\n\tstatus = PJMEDIA_EVID_BADFORMAT;\n\tPJ_LOG(4,(THIS_FILE, \"Error: cannot find video in AVI %s\",\n\t\tadi->fpath.ptr));\n\tgoto on_error;\n    }\n\n    pjmedia_format_copy(&avi_fmt, &adi->vid->info.fmt);\n    vfi = pjmedia_get_video_format_info(NULL, avi_fmt.id);\n    /* Check whether the frame is encoded. */\n    if (!vfi || vfi->bpp == 0) {\n        /* Yes, prepare codec */\n        const pjmedia_vid_codec_info *codec_info;\n        pjmedia_vid_codec_param codec_param;\n\tpjmedia_video_apply_fmt_param vafp;\n\n        /* Lookup codec */\n        status = pjmedia_vid_codec_mgr_get_codec_info2(NULL,\n                                                       avi_fmt.id,\n                                                       &codec_info);\n        if (status != PJ_SUCCESS || !codec_info)\n            goto on_error;\n\n        status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info,\n                                                         &codec_param);\n        if (status != PJ_SUCCESS)\n            goto on_error;\n\n        /* Open codec */\n        status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info,\n                                                   &adi->codec);\n        if (status != PJ_SUCCESS)\n            goto on_error;\n\n        status = pjmedia_vid_codec_init(adi->codec, adi->pool);\n        if (status != PJ_SUCCESS)\n            goto on_error;\n\n        codec_param.dir = PJMEDIA_DIR_DECODING;\n        codec_param.packing = PJMEDIA_VID_PACKING_WHOLE;\n        status = pjmedia_vid_codec_open(adi->codec, &codec_param);\n        if (status != PJ_SUCCESS)\n            goto on_error;\n\n\t/* Allocate buffer */\n        avi_fmt.id = codec_info->dec_fmt_id[0];\n        vfi = pjmedia_get_video_format_info(NULL, avi_fmt.id);\n\tpj_bzero(&vafp, sizeof(vafp));\n\tvafp.size = avi_fmt.det.vid.size;\n\tstatus = vfi->apply_fmt(vfi, &vafp);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n\tadi->enc_buf = pj_pool_alloc(adi->pool, vafp.framebytes);\n\tadi->enc_buf_size = vafp.framebytes;\n    }\n\n    /* Calculate title */\n    if (p->title.slen) {\n\tpj_strdup_with_null(adi->pool, &adi->title, &p->title);\n    } else {\n\tchar *start = p->path.ptr + p->path.slen;\n\tpj_str_t tmp;\n\n\twhile (start >= p->path.ptr) {\n\t    if (*start == '/' || *start == '\\\\')\n\t\tbreak;\n\t    --start;\n\t}\n\ttmp.ptr = start + 1;\n\ttmp.slen = p->path.ptr + p->path.slen - tmp.ptr;\n\tpj_strdup_with_null(adi->pool, &adi->title, &tmp);\n    }\n\n    /* Init device info */\n    pj_ansi_strncpy(adi->info.name, adi->title.ptr, sizeof(adi->info.name)-1);\n    pj_ansi_strncpy(adi->info.driver, DRIVER_NAME, sizeof(adi->info.driver)-1);\n    adi->info.dir = PJMEDIA_DIR_CAPTURE;\n    adi->info.has_callback = PJ_FALSE;\n\n    adi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;\n    adi->info.fmt_cnt = 1;\n    pjmedia_format_copy(&adi->info.fmt[0], &avi_fmt);\n\n    /* Set out vars */\n    if (p_id)\n\t*p_id = id;\n    p->avi_streams = adi->avi;\n    if (p->title.slen == 0)\n\tp->title = adi->title;\n\n    return PJ_SUCCESS;\n\non_error:\n    if (adi->codec) {\n        pjmedia_vid_codec_close(adi->codec);\n        adi->codec = NULL;\n    }\n    if (adi->pool) {\n\tpj_pool_release(adi->pool);\n\tadi->pool = NULL;\n    }\n    pjmedia_avi_dev_free(id);\n    return status;\n}\n\n\n/* API: create stream */\nstatic pj_status_t avi_factory_create_stream(\n\t\t\t\t\tpjmedia_vid_dev_factory *f,\n\t\t\t\t\tpjmedia_vid_dev_param *param,\n\t\t\t\t\tconst pjmedia_vid_dev_cb *cb,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tpjmedia_vid_dev_stream **p_vid_strm)\n{\n    struct avi_factory *cf = (struct avi_factory*)f;\n    pj_pool_t *pool = NULL;\n    struct avi_dev_info *adi;\n    struct avi_dev_strm *strm;\n\n    PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);\n    PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&\n\t\t     param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&\n                     param->dir == PJMEDIA_DIR_CAPTURE,\n\t\t     PJ_EINVAL);\n\n    /* Device must have been configured with pjmedia_avi_dev_set_param() */\n    adi = &cf->dev_info[param->cap_id];\n    PJ_ASSERT_RETURN(adi->avi != NULL, PJ_EINVALIDOP);\n\n    /* Cannot create while stream is already active */\n    PJ_ASSERT_RETURN(adi->strm==NULL, PJ_EINVALIDOP);\n\n    /* Create and initialize basic stream descriptor */\n    pool = pj_pool_create(cf->pf, \"avidev%p\", 512, 512, NULL);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    strm = PJ_POOL_ZALLOC_T(pool, struct avi_dev_strm);\n    pj_memcpy(&strm->param, param, sizeof(*param));\n    strm->pool = pool;\n    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));\n    strm->user_data = user_data;\n    strm->adi = adi;\n\n    pjmedia_format_copy(&param->fmt, &adi->info.fmt[0]);\n\n    /* Done */\n    strm->base.op = &stream_op;\n    adi->strm = strm;\n    *p_vid_strm = &strm->base;\n\n    return PJ_SUCCESS;\n}\n\n/* API: Get stream info. */\nstatic pj_status_t avi_dev_strm_get_param(pjmedia_vid_dev_stream *s,\n\t\t\t\t\t pjmedia_vid_dev_param *pi)\n{\n    struct avi_dev_strm *strm = (struct avi_dev_strm*)s;\n\n    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);\n\n    pj_memcpy(pi, &strm->param, sizeof(*pi));\n\n    return PJ_SUCCESS;\n}\n\n/* API: get capability */\nstatic pj_status_t avi_dev_strm_get_cap(pjmedia_vid_dev_stream *s,\n\t\t\t\t       pjmedia_vid_dev_cap cap,\n\t\t\t\t       void *pval)\n{\n    struct avi_dev_strm *strm = (struct avi_dev_strm*)s;\n\n    PJ_UNUSED_ARG(strm);\n    PJ_UNUSED_ARG(cap);\n    PJ_UNUSED_ARG(pval);\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    return PJMEDIA_EVID_INVCAP;\n}\n\n/* API: set capability */\nstatic pj_status_t avi_dev_strm_set_cap(pjmedia_vid_dev_stream *s,\n\t\t\t\t       pjmedia_vid_dev_cap cap,\n\t\t\t\t       const void *pval)\n{\n    struct avi_dev_strm *strm = (struct avi_dev_strm*)s;\n\n    PJ_UNUSED_ARG(strm);\n    PJ_UNUSED_ARG(cap);\n    PJ_UNUSED_ARG(pval);\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    return PJMEDIA_EVID_INVCAP;\n}\n\n/* API: Get frame from stream */\nstatic pj_status_t avi_dev_strm_get_frame(pjmedia_vid_dev_stream *strm,\n                                         pjmedia_frame *frame)\n{\n    struct avi_dev_strm *stream = (struct avi_dev_strm*)strm;\n    \n    if (stream->adi->codec) {\n        pjmedia_frame enc_frame;\n        pj_status_t status;\n\n        enc_frame.buf = stream->adi->enc_buf;\n        enc_frame.size = stream->adi->enc_buf_size;\n        status = pjmedia_port_get_frame(stream->adi->vid, &enc_frame);\n        if (status != PJ_SUCCESS)\n            return status;\n\n        return pjmedia_vid_codec_decode(stream->adi->codec, 1, &enc_frame,\n                                        (unsigned)frame->size, frame);\n    } else {\n        return pjmedia_port_get_frame(stream->adi->vid, frame);\n    }\n}\n\n/* API: Start stream. */\nstatic pj_status_t avi_dev_strm_start(pjmedia_vid_dev_stream *strm)\n{\n    struct avi_dev_strm *stream = (struct avi_dev_strm*)strm;\n\n    PJ_UNUSED_ARG(stream);\n\n    PJ_LOG(4, (THIS_FILE, \"Starting avi video stream\"));\n\n    return PJ_SUCCESS;\n}\n\n/* API: Stop stream. */\nstatic pj_status_t avi_dev_strm_stop(pjmedia_vid_dev_stream *strm)\n{\n    struct avi_dev_strm *stream = (struct avi_dev_strm*)strm;\n\n    PJ_UNUSED_ARG(stream);\n\n    PJ_LOG(4, (THIS_FILE, \"Stopping avi video stream\"));\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: Destroy stream. */\nstatic pj_status_t avi_dev_strm_destroy(pjmedia_vid_dev_stream *strm)\n{\n    struct avi_dev_strm *stream = (struct avi_dev_strm*)strm;\n\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n\n    avi_dev_strm_stop(strm);\n\n    stream->adi->strm = NULL;\n    stream->adi = NULL;\n    pj_pool_release(stream->pool);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_VIDEO_DEV_HAS_AVI */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-videodev/colorbar_dev.c",
    "content": "/* $Id: colorbar_dev.c 4158 2012-06-06 09:56:14Z nanang $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia-videodev/videodev_imp.h>\n#include <pjmedia/clock.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/rand.h>\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && PJMEDIA_HAS_VIDEO != 0 && \\\n    defined(PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC) && \\\n    PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC != 0\n    \n\n#define THIS_FILE\t\t\"colorbar_dev.c\"\n#define DEFAULT_CLOCK_RATE\t90000\n#define DEFAULT_WIDTH\t\t352 //640\n#define DEFAULT_HEIGHT\t\t288 //480\n#define DEFAULT_FPS\t\t25\n\n\n/* cbar_ device info */\nstruct cbar_dev_info\n{\n    pjmedia_vid_dev_info\t info;\n};\n\n/* cbar_ factory */\nstruct cbar_factory\n{\n    pjmedia_vid_dev_factory\t base;\n    pj_pool_t\t\t\t*pool;\n    pj_pool_factory\t\t*pf;\n\n    unsigned\t\t\t dev_count;\n    struct cbar_dev_info\t*dev_info;\n};\n\nstruct cbar_fmt_info {\n    pjmedia_format_id            fmt_id;        /* Format ID                */\n\n    /* Info for packed formats. */\n    unsigned                     c_offset[3];   /* Color component offset, \n                                                   in bytes                 */\n    unsigned                     c_stride[3];   /* Color component stride,\n                                                   or distance between two \n                                                   consecutive same color\n                                                   components, in bytes     */\n};\n\n/* Colorbar video source supports */\nstatic struct cbar_fmt_info cbar_fmts[] =\n{\n    /* Packed formats */\n    { PJMEDIA_FORMAT_YUY2,      {0, 1, 3}, {2, 4, 4} },\n    { PJMEDIA_FORMAT_UYVY,      {1, 0, 2}, {2, 4, 4} },\n    { PJMEDIA_FORMAT_YVYU,      {0, 3, 1}, {2, 4, 4} },\n    { PJMEDIA_FORMAT_RGBA,      {0, 1, 2}, {4, 4, 4} },\n    { PJMEDIA_FORMAT_RGB24,     {0, 1, 2}, {3, 3, 3} },\n    { PJMEDIA_FORMAT_BGRA,      {2, 1, 0}, {4, 4, 4} },\n\n    /* Planar formats */\n    { PJMEDIA_FORMAT_YV12 },\n    { PJMEDIA_FORMAT_I420 },\n    { PJMEDIA_FORMAT_I422 },\n    { PJMEDIA_FORMAT_I420JPEG },\n    { PJMEDIA_FORMAT_I422JPEG },\n};\n\n/* Video stream. */\nstruct cbar_stream\n{\n    pjmedia_vid_dev_stream\t     base;\t    /**< Base stream\t    */\n    pjmedia_vid_dev_param\t     param;\t    /**< Settings\t    */\n    pj_pool_t\t\t\t    *pool;          /**< Memory pool.       */\n\n    pjmedia_vid_dev_cb\t\t     vid_cb;\t    /**< Stream callback.   */\n    void\t\t\t    *user_data;\t    /**< Application data.  */\n\n    const struct cbar_fmt_info      *cbfi;\n    const pjmedia_video_format_info *vfi;\n    pjmedia_video_apply_fmt_param    vafp;\n    pj_uint8_t                      *first_line[PJMEDIA_MAX_VIDEO_PLANES];\n    pj_timestamp\t\t     ts;\n    unsigned\t\t\t     ts_inc;\n\n    /* For active capturer only */\n    pjmedia_clock\t\t    *clock;\n    pj_uint8_t\t\t\t    *clock_buf;\n};\n\n\n/* Prototypes */\nstatic pj_status_t cbar_factory_init(pjmedia_vid_dev_factory *f);\nstatic pj_status_t cbar_factory_destroy(pjmedia_vid_dev_factory *f);\nstatic pj_status_t cbar_factory_refresh(pjmedia_vid_dev_factory *f); \nstatic unsigned    cbar_factory_get_dev_count(pjmedia_vid_dev_factory *f);\nstatic pj_status_t cbar_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_vid_dev_info *info);\nstatic pj_status_t cbar_factory_default_param(pj_pool_t *pool,\n                                              pjmedia_vid_dev_factory *f,\n\t\t\t\t\t      unsigned index,\n\t\t\t\t\t      pjmedia_vid_dev_param *param);\nstatic pj_status_t cbar_factory_create_stream(\n\t\t\t\t\tpjmedia_vid_dev_factory *f,\n\t\t\t\t\tpjmedia_vid_dev_param *param,\n\t\t\t\t\tconst pjmedia_vid_dev_cb *cb,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tpjmedia_vid_dev_stream **p_vid_strm);\n\nstatic pj_status_t cbar_stream_get_param(pjmedia_vid_dev_stream *strm,\n\t\t\t\t\t pjmedia_vid_dev_param *param);\nstatic pj_status_t cbar_stream_get_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t       pjmedia_vid_dev_cap cap,\n\t\t\t\t       void *value);\nstatic pj_status_t cbar_stream_set_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t       pjmedia_vid_dev_cap cap,\n\t\t\t\t       const void *value);\nstatic pj_status_t cbar_stream_get_frame(pjmedia_vid_dev_stream *strm,\n                                         pjmedia_frame *frame);\nstatic pj_status_t cbar_stream_start(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t cbar_stream_stop(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t cbar_stream_destroy(pjmedia_vid_dev_stream *strm);\n\n/* Operations */\nstatic pjmedia_vid_dev_factory_op factory_op =\n{\n    &cbar_factory_init,\n    &cbar_factory_destroy,\n    &cbar_factory_get_dev_count,\n    &cbar_factory_get_dev_info,\n    &cbar_factory_default_param,\n    &cbar_factory_create_stream,\n    &cbar_factory_refresh\n};\n\nstatic pjmedia_vid_dev_stream_op stream_op =\n{\n    &cbar_stream_get_param,\n    &cbar_stream_get_cap,\n    &cbar_stream_set_cap,\n    &cbar_stream_start,\n    &cbar_stream_get_frame,\n    NULL,\n    &cbar_stream_stop,\n    &cbar_stream_destroy\n};\n\n\n/****************************************************************************\n * Factory operations\n */\n/*\n * Init cbar_ video driver.\n */\npjmedia_vid_dev_factory* pjmedia_cbar_factory(pj_pool_factory *pf)\n{\n    struct cbar_factory *f;\n    pj_pool_t *pool;\n\n    pool = pj_pool_create(pf, \"cbar video\", 512, 512, NULL);\n    f = PJ_POOL_ZALLOC_T(pool, struct cbar_factory);\n    f->pf = pf;\n    f->pool = pool;\n    f->base.op = &factory_op;\n\n    return &f->base;\n}\n\n\n/* API: init factory */\nstatic pj_status_t cbar_factory_init(pjmedia_vid_dev_factory *f)\n{\n    struct cbar_factory *cf = (struct cbar_factory*)f;\n    struct cbar_dev_info *ddi;\n    unsigned i;\n\n    cf->dev_count = 2;\n\n    cf->dev_info = (struct cbar_dev_info*)\n \t\t   pj_pool_calloc(cf->pool, cf->dev_count,\n \t\t\t\t  sizeof(struct cbar_dev_info));\n\n    /* Passive capturer */\n    ddi = &cf->dev_info[0];\n    pj_bzero(ddi, sizeof(*ddi));\n    pj_ansi_strncpy(ddi->info.name, \"Colorbar generator\",\n\t\t    sizeof(ddi->info.name));\n    ddi->info.driver[sizeof(ddi->info.driver)-1] = '\\0';\n    pj_ansi_strncpy(ddi->info.driver, \"Colorbar\", sizeof(ddi->info.driver));\n    ddi->info.driver[sizeof(ddi->info.driver)-1] = '\\0';\n    ddi->info.dir = PJMEDIA_DIR_CAPTURE;\n    ddi->info.has_callback = PJ_FALSE;\n\n    ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;\n    ddi->info.fmt_cnt = sizeof(cbar_fmts)/sizeof(cbar_fmts[0]);\n    for (i = 0; i < ddi->info.fmt_cnt; i++) {\n        pjmedia_format *fmt = &ddi->info.fmt[i];\n        pjmedia_format_init_video(fmt, cbar_fmts[i].fmt_id,\n\t\t\t\t  DEFAULT_WIDTH, DEFAULT_HEIGHT,\n\t\t\t\t  DEFAULT_FPS, 1);\n    }\n\n    /* Active capturer */\n    ddi = &cf->dev_info[1];\n    pj_bzero(ddi, sizeof(*ddi));\n    pj_ansi_strncpy(ddi->info.name, \"Colorbar-active\",\n\t\t    sizeof(ddi->info.name));\n    ddi->info.driver[sizeof(ddi->info.driver)-1] = '\\0';\n    pj_ansi_strncpy(ddi->info.driver, \"Colorbar\", sizeof(ddi->info.driver));\n    ddi->info.driver[sizeof(ddi->info.driver)-1] = '\\0';\n    ddi->info.dir = PJMEDIA_DIR_CAPTURE;\n    ddi->info.has_callback = PJ_TRUE;\n\n    ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;\n    ddi->info.fmt_cnt = sizeof(cbar_fmts)/sizeof(cbar_fmts[0]);\n    for (i = 0; i < ddi->info.fmt_cnt; i++) {\n        pjmedia_format *fmt = &ddi->info.fmt[i];\n        pjmedia_format_init_video(fmt, cbar_fmts[i].fmt_id,\n\t\t\t\t  DEFAULT_WIDTH, DEFAULT_HEIGHT,\n\t\t\t\t  DEFAULT_FPS, 1);\n    }\n\n    PJ_LOG(4, (THIS_FILE, \"Colorbar video src initialized with %d device(s):\",\n\t       cf->dev_count));\n    for (i = 0; i < cf->dev_count; i++) {\n\tPJ_LOG(4, (THIS_FILE, \"%2d: %s\", i, cf->dev_info[i].info.name));\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: destroy factory */\nstatic pj_status_t cbar_factory_destroy(pjmedia_vid_dev_factory *f)\n{\n    struct cbar_factory *cf = (struct cbar_factory*)f;\n    pj_pool_t *pool = cf->pool;\n\n    cf->pool = NULL;\n    pj_pool_release(pool);\n\n    return PJ_SUCCESS;\n}\n\n/* API: refresh the list of devices */\nstatic pj_status_t cbar_factory_refresh(pjmedia_vid_dev_factory *f)\n{\n    PJ_UNUSED_ARG(f);\n    return PJ_SUCCESS;\n}\n\n/* API: get number of devices */\nstatic unsigned cbar_factory_get_dev_count(pjmedia_vid_dev_factory *f)\n{\n    struct cbar_factory *cf = (struct cbar_factory*)f;\n    return cf->dev_count;\n}\n\n/* API: get device info */\nstatic pj_status_t cbar_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_vid_dev_info *info)\n{\n    struct cbar_factory *cf = (struct cbar_factory*)f;\n\n    PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);\n\n    pj_memcpy(info, &cf->dev_info[index].info, sizeof(*info));\n\n    return PJ_SUCCESS;\n}\n\n/* API: create default device parameter */\nstatic pj_status_t cbar_factory_default_param(pj_pool_t *pool,\n                                              pjmedia_vid_dev_factory *f,\n\t\t\t\t\t      unsigned index,\n\t\t\t\t\t      pjmedia_vid_dev_param *param)\n{\n    struct cbar_factory *cf = (struct cbar_factory*)f;\n    struct cbar_dev_info *di = &cf->dev_info[index];\n\n    PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);\n\n    PJ_UNUSED_ARG(pool);\n\n    pj_bzero(param, sizeof(*param));\n    param->dir = PJMEDIA_DIR_CAPTURE;\n    param->cap_id = index;\n    param->rend_id = PJMEDIA_VID_INVALID_DEV;\n    param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;\n    param->clock_rate = DEFAULT_CLOCK_RATE;\n    pj_memcpy(&param->fmt, &di->info.fmt[0], sizeof(param->fmt));\n\n    return PJ_SUCCESS;\n}\n\nstatic const struct cbar_fmt_info* get_cbar_fmt_info(pjmedia_format_id id)\n{\n    unsigned i;\n\n    for (i = 0; i < sizeof(cbar_fmts)/sizeof(cbar_fmts[0]); i++) {\n        if (cbar_fmts[i].fmt_id == id)\n            return &cbar_fmts[i];\n    }\n\n    return NULL;\n}\n\nstatic void fill_first_line(pj_uint8_t *first_lines[], \n                            const struct cbar_fmt_info *cbfi,\n                            const pjmedia_video_format_info *vfi,\n                            const pjmedia_video_apply_fmt_param *vafp)\n{\n    typedef pj_uint8_t color_comp_t[3];\n    color_comp_t rgb_colors[] = \n    { \n        {255,255,255}, {255,255,0}, {0,255,255}, {0,255,0},\n        {255,0,255}, {255,0,0}, {0,0,255}, {0,0,0}\n    };\n    color_comp_t yuv_colors[] = \n    { \n        //{235,128,128}, {162,44,142}, {131,156,44}, {112,72,58},\n        //{84,184,198}, {65,100,212}, {35,212,114}, {16,128,128}\n        {235,128,128}, {210,16,146}, {170,166,16}, {145,54,34},\n        {106,202,222}, {81,90,240}, {41,240,110}, {16,128,128}\n    };\n\n    unsigned i, j, k;\n\n    if (vfi->plane_cnt == 1) {\n        /* Packed */\n\n        for (i = 0; i < 8; ++i) {\n            /* iterate bars */\n            for (j = 0; j < 3; ++j) {\n                /* iterate color components */\n                pj_uint8_t *p = NULL, c;\n                unsigned bar_width, inc_p;\n\n                if (vfi->color_model == PJMEDIA_COLOR_MODEL_RGB)\n                    c = rgb_colors[i][j];\n                else\n                    c = yuv_colors[i][j];\n\n                bar_width = vafp->size.w/8;\n                bar_width /= (cbfi->c_stride[j] * 8 / vfi->bpp);\n                inc_p = cbfi->c_stride[j];\n                p = first_lines[0] + bar_width*i*inc_p + cbfi->c_offset[j];\n\n                /* draw this color */\n                for (k = 0; k < bar_width; ++k) {\n                    *p = c;\n                    p += inc_p;\n                }\n            }\n        }\n\n    } else if (vfi->plane_cnt == 3) {\n\n        for (i = 0; i < 8; ++i) {\n            /* iterate bars */\n            for (j = 0; j < 3; ++j) {\n                /* iterate planes/color components */\n                pj_uint8_t *p = NULL, c;\n                unsigned bar_width;\n\n                if (vfi->color_model == PJMEDIA_COLOR_MODEL_RGB)\n                    c = rgb_colors[i][j];\n\t\telse {\n\t\t    if (vfi->id == PJMEDIA_FORMAT_YV12 && j > 0)\n\t\t\tc = yuv_colors[i][3-j];\n\t\t    else\n\t\t\tc = yuv_colors[i][j];\n\t\t}\n\n                bar_width = vafp->strides[j]/8;\n                p = first_lines[j] + bar_width*i;\n\n                /* draw this plane/color */\n                for (k = 0; k < bar_width; ++k)\n                    *p++ = c;\n            }\n        }\n    }\n}\n\n\nstatic void clock_cb(const pj_timestamp *ts, void *user_data)\n{\n    struct cbar_stream *stream = (struct cbar_stream*)user_data;\n    pjmedia_frame f;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(ts);\n\n    pj_bzero(&f, sizeof(f));\n    f.buf = stream->clock_buf;\n    f.size = stream->vafp.framebytes;\n    status = cbar_stream_get_frame(&stream->base, &f);\n    if (status == PJ_SUCCESS) {\n\t(*stream->vid_cb.capture_cb)(&stream->base, stream->user_data, &f);\n    }\n}\n\n\n/* API: create stream */\nstatic pj_status_t cbar_factory_create_stream(\n\t\t\t\t\tpjmedia_vid_dev_factory *f,\n\t\t\t\t\tpjmedia_vid_dev_param *param,\n\t\t\t\t\tconst pjmedia_vid_dev_cb *cb,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tpjmedia_vid_dev_stream **p_vid_strm)\n{\n    struct cbar_factory *cf = (struct cbar_factory*)f;\n    pj_pool_t *pool;\n    struct cbar_stream *strm;\n    const pjmedia_video_format_detail *vfd;\n    const pjmedia_video_format_info *vfi;\n    pjmedia_video_apply_fmt_param vafp;\n    const struct cbar_fmt_info *cbfi;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);\n    PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&\n\t\t     param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&\n                     param->dir == PJMEDIA_DIR_CAPTURE,\n\t\t     PJ_EINVAL);\n\n    pj_bzero(&vafp, sizeof(vafp));\n\n    vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);\n    vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);\n    cbfi = get_cbar_fmt_info(param->fmt.id);\n    if (!vfi || !cbfi)\n        return PJMEDIA_EVID_BADFORMAT;\n\n    vafp.size = param->fmt.det.vid.size;\n    if (vfi->apply_fmt(vfi, &vafp) != PJ_SUCCESS)\n        return PJMEDIA_EVID_BADFORMAT;\n\n    /* Create and Initialize stream descriptor */\n    pool = pj_pool_create(cf->pf, \"cbar-dev\", 512, 512, NULL);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    strm = PJ_POOL_ZALLOC_T(pool, struct cbar_stream);\n    pj_memcpy(&strm->param, param, sizeof(*param));\n    strm->pool = pool;\n    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));\n    strm->user_data = user_data;\n    strm->vfi = vfi;\n    strm->cbfi = cbfi;\n    pj_memcpy(&strm->vafp, &vafp, sizeof(vafp));\n    strm->ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);\n\n    for (i = 0; i < vfi->plane_cnt; ++i) {\n        strm->first_line[i] = pj_pool_alloc(pool, vafp.strides[i]);\n        pj_memset(strm->first_line[i], 255, vafp.strides[i]);\n    }\n\n    fill_first_line(strm->first_line, strm->cbfi, vfi, &strm->vafp);\n\n    /* Apply the remaining settings */\n/*    if (param->flags & PJMEDIA_VID_DEV_CAP_INPUT_SCALE) {\n\tcbar_stream_set_cap(&strm->base,\n\t\t            PJMEDIA_VID_DEV_CAP_INPUT_SCALE,\n                            &param->fmt);\n    }\n*/\n\n    /* Active role? */\n    if (param->cap_id == 1 && cb && cb->capture_cb) {\n        pjmedia_clock_param clock_param;\n\tpj_status_t status;\n\n\t/* Allocate buffer */\n\tstrm->clock_buf = pj_pool_alloc(pool, strm->vafp.framebytes);\n\n\t/* Create clock */\n\tpj_bzero(&clock_param, sizeof(clock_param));\n        clock_param.usec_interval = PJMEDIA_PTIME(&vfd->fps);\n        clock_param.clock_rate = param->clock_rate;\n        status = pjmedia_clock_create2(pool, &clock_param,\n                                       PJMEDIA_CLOCK_NO_HIGHEST_PRIO,\n                                       &clock_cb,\n                                       strm, &strm->clock);\n\tif (status != PJ_SUCCESS) {\n\t    pj_pool_release(pool);\n            return status;\n\t}\n    }\n\n    /* Done */\n    strm->base.op = &stream_op;\n    *p_vid_strm = &strm->base;\n\n    return PJ_SUCCESS;\n}\n\n/* API: Get stream info. */\nstatic pj_status_t cbar_stream_get_param(pjmedia_vid_dev_stream *s,\n\t\t\t\t\t pjmedia_vid_dev_param *pi)\n{\n    struct cbar_stream *strm = (struct cbar_stream*)s;\n\n    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);\n\n    pj_memcpy(pi, &strm->param, sizeof(*pi));\n\n/*    if (cbar_stream_get_cap(s, PJMEDIA_VID_DEV_CAP_INPUT_SCALE,\n                            &pi->fmt.info_size) == PJ_SUCCESS)\n    {\n        pi->flags |= PJMEDIA_VID_DEV_CAP_INPUT_SCALE;\n    }\n*/\n    return PJ_SUCCESS;\n}\n\n/* API: get capability */\nstatic pj_status_t cbar_stream_get_cap(pjmedia_vid_dev_stream *s,\n\t\t\t\t       pjmedia_vid_dev_cap cap,\n\t\t\t\t       void *pval)\n{\n    struct cbar_stream *strm = (struct cbar_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)\n    {\n        return PJMEDIA_EVID_INVCAP;\n//\treturn PJ_SUCCESS;\n    } else {\n\treturn PJMEDIA_EVID_INVCAP;\n    }\n}\n\n/* API: set capability */\nstatic pj_status_t cbar_stream_set_cap(pjmedia_vid_dev_stream *s,\n\t\t\t\t       pjmedia_vid_dev_cap cap,\n\t\t\t\t       const void *pval)\n{\n    struct cbar_stream *strm = (struct cbar_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)\n    {\n\treturn PJ_SUCCESS;\n    }\n\n    return PJMEDIA_EVID_INVCAP;\n}\n\nstatic pj_status_t spectrum_run(struct cbar_stream *d, pj_uint8_t *p,\n                                pj_size_t size)\n{\n    unsigned i;\n    pj_uint8_t *ptr = p;\n    pj_time_val tv;\n\n    PJ_UNUSED_ARG(size);\n\n    /* Subsequent lines */\n    for (i=0; i<d->vfi->plane_cnt; ++i) {\n        pj_uint8_t *plane_end;\n\n        plane_end = ptr + d->vafp.plane_bytes[i];\n        while (ptr < plane_end) {\n            pj_memcpy(ptr, d->first_line[i], d->vafp.strides[i]);\n            ptr += d->vafp.strides[i]; \n        }\n    }\n\n    /* blinking dot */\n    pj_gettimeofday(&tv);\n    if (tv.msec < 660) {\n\tenum { DOT_SIZE = 8 };\n        pj_uint8_t dot_clr_rgb[3] = {255, 255, 255};\n        pj_uint8_t dot_clr_yuv[3] = {235, 128, 128};\n\n        if (d->vfi->plane_cnt == 1) {\n            for (i = 0; i < 3; ++i) {\n                pj_uint8_t *ptr;\n                unsigned j, k, inc_ptr;\n                pj_size_t dot_size = DOT_SIZE;\n\n                dot_size /= (d->cbfi->c_stride[i] * 8 / d->vfi->bpp);\n                inc_ptr = d->cbfi->c_stride[i];\n                for (j = 0; j < dot_size; ++j) {\n                    ptr = p + d->vafp.strides[0]*(dot_size+j+1) - \n                          2*dot_size*inc_ptr + d->cbfi->c_offset[i];\n                    for (k = 0; k < dot_size; ++k) {\n                        if (d->vfi->color_model == PJMEDIA_COLOR_MODEL_RGB)\n                            *ptr = dot_clr_rgb[i];\n                        else\n                            *ptr = dot_clr_yuv[i];\n                        ptr += inc_ptr;\n                    }\n                }\n            }\n        } else {\n            pj_size_t offset_p = 0;\n\n            for (i = 0; i < 3; ++i) {\n                pj_uint8_t *ptr, c;\n                unsigned j;\n                pj_size_t dot_size = DOT_SIZE;\n\n                if (d->vfi->color_model == PJMEDIA_COLOR_MODEL_RGB)\n                    c = dot_clr_rgb[i];\n                else\n                    c = dot_clr_yuv[i];\n\n                dot_size /= (d->vafp.size.w / d->vafp.strides[i]);\n                ptr = p + offset_p + d->vafp.strides[i]*(dot_size+1) - \n                      2*dot_size;\n                for (j = 0; j < dot_size; ++j) {\n                    pj_memset(ptr, c, dot_size);\n                    ptr += d->vafp.strides[i];\n                }\n                offset_p += d->vafp.plane_bytes[i];\n            }\n        }\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: Get frame from stream */\nstatic pj_status_t cbar_stream_get_frame(pjmedia_vid_dev_stream *strm,\n                                         pjmedia_frame *frame)\n{\n    struct cbar_stream *stream = (struct cbar_stream*)strm;\n\n    frame->type = PJMEDIA_FRAME_TYPE_VIDEO;\n    frame->bit_info = 0;\n    frame->timestamp = stream->ts;\n    stream->ts.u64 += stream->ts_inc;\n    return spectrum_run(stream, frame->buf, frame->size);\n}\n\n/* API: Start stream. */\nstatic pj_status_t cbar_stream_start(pjmedia_vid_dev_stream *strm)\n{\n    struct cbar_stream *stream = (struct cbar_stream*)strm;\n\n    PJ_LOG(4, (THIS_FILE, \"Starting cbar video stream\"));\n\n    if (stream->clock)\n\treturn pjmedia_clock_start(stream->clock);\n\n    return PJ_SUCCESS;\n}\n\n/* API: Stop stream. */\nstatic pj_status_t cbar_stream_stop(pjmedia_vid_dev_stream *strm)\n{\n    struct cbar_stream *stream = (struct cbar_stream*)strm;\n\n    PJ_LOG(4, (THIS_FILE, \"Stopping cbar video stream\"));\n\n    if (stream->clock)\n\treturn pjmedia_clock_stop(stream->clock);\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: Destroy stream. */\nstatic pj_status_t cbar_stream_destroy(pjmedia_vid_dev_stream *strm)\n{\n    struct cbar_stream *stream = (struct cbar_stream*)strm;\n\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n\n    cbar_stream_stop(strm);\n\n    if (stream->clock)\n\tpjmedia_clock_destroy(stream->clock);\n    stream->clock = NULL;\n\n    pj_pool_release(stream->pool);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-videodev/dshow_dev.c",
    "content": "/* $Id: dshow_dev.c 4253 2012-09-13 08:35:24Z ming $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia-videodev/videodev_imp.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && PJMEDIA_HAS_VIDEO != 0 && \\\n    defined(PJMEDIA_VIDEO_DEV_HAS_DSHOW) && PJMEDIA_VIDEO_DEV_HAS_DSHOW != 0\n\n#include <windows.h>\n#define COBJMACROS\n#include <DShow.h>\n#include <wmsdkidl.h>\n#include <OleAuto.h>\n\n#ifndef DIBSIZE\n# define WIDTHBYTES(BTIS) ((DWORD)(((BTIS)+31) & (~31)) / 8)\n# define DIBWIDTHBYTES(BI) (DWORD)(BI).biBitCount) * (DWORD)WIDTHBYTES((DWORD)(BI).biWidth\n# define _DIBSIZE(BI) (DIBWIDTHBYTES(BI) * (DWORD)(BI).biHeight)\n# define DIBSIZE(BI) ((BI).biHeight < 0 ? (-1)*(_DIBSIZE(BI)) : _DIBSIZE(BI))\n#endif\n\n#define THIS_FILE\t\t\"dshow_dev.c\"\n#define DEFAULT_CLOCK_RATE\t90000\n#define DEFAULT_WIDTH\t\t640\n#define DEFAULT_HEIGHT\t\t480\n#define DEFAULT_FPS\t\t25\n\n/* Temporarily disable DirectShow renderer (VMR) */\n#define HAS_VMR\t\t\t0\n\ntypedef void (*input_callback)(void *user_data, IMediaSample *pMediaSample);\ntypedef struct NullRenderer NullRenderer;\nIBaseFilter* NullRenderer_Create(input_callback input_cb,\n                                 void *user_data);\n\ntypedef struct dshow_fmt_info\n{\n    pjmedia_format_id    pjmedia_format;\n    const GUID          *dshow_format;\n    pj_bool_t            enabled;\n} dshow_fmt_info;\n\nstatic dshow_fmt_info dshow_fmts[] =\n{\n    {PJMEDIA_FORMAT_YUY2, &MEDIASUBTYPE_YUY2, PJ_FALSE} ,\n    {PJMEDIA_FORMAT_RGB24, &MEDIASUBTYPE_RGB24, PJ_FALSE} ,\n    {PJMEDIA_FORMAT_RGB32, &MEDIASUBTYPE_RGB32, PJ_FALSE} ,\n    {PJMEDIA_FORMAT_IYUV, &MEDIASUBTYPE_IYUV, PJ_FALSE} ,\n    {PJMEDIA_FORMAT_I420, &WMMEDIASUBTYPE_I420, PJ_FALSE}\n};\n\n/* dshow_ device info */\nstruct dshow_dev_info\n{\n    pjmedia_vid_dev_info\t info;\n    unsigned\t\t\t dev_id;\n    WCHAR                        display_name[192];\n};\n\n/* dshow_ factory */\nstruct dshow_factory\n{\n    pjmedia_vid_dev_factory\t base;\n    pj_pool_t\t\t\t*pool;\n    pj_pool_t\t\t\t*dev_pool;\n    pj_pool_factory\t\t*pf;\n\n    unsigned\t\t\t dev_count;\n    struct dshow_dev_info\t*dev_info;\n};\n\n/* Video stream. */\nstruct dshow_stream\n{\n    pjmedia_vid_dev_stream   base;\t\t    /**< Base stream\t    */\n    pjmedia_vid_dev_param    param;\t\t    /**< Settings\t    */\n    pj_pool_t\t\t    *pool;\t\t    /**< Memory pool.\t    */\n\n    pjmedia_vid_dev_cb\t     vid_cb;\t\t    /**< Stream callback.   */\n    void\t\t    *user_data;\t\t    /**< Application data.  */\n\n    pj_bool_t\t\t     quit_flag;\n    pj_bool_t\t\t     rend_thread_exited;\n    pj_bool_t\t\t     cap_thread_exited;\n    pj_bool_t\t\t     cap_thread_initialized;\n    pj_thread_desc\t     cap_thread_desc;\n    pj_thread_t\t\t    *cap_thread;\n    void                    *frm_buf;\n    unsigned                 frm_buf_size;\n\n    struct dshow_graph\n    {\n        IFilterGraph        *filter_graph;\n        IMediaFilter        *media_filter;\n        IBaseFilter         *source_filter;\n        IBaseFilter         *rend_filter;\n        AM_MEDIA_TYPE       *mediatype;\n    } dgraph;\n\n    pj_timestamp\t     cap_ts;\n    unsigned\t\t     cap_ts_inc;\n};\n\n\n/* Prototypes */\nstatic pj_status_t dshow_factory_init(pjmedia_vid_dev_factory *f);\nstatic pj_status_t dshow_factory_destroy(pjmedia_vid_dev_factory *f);\nstatic pj_status_t dshow_factory_refresh(pjmedia_vid_dev_factory *f);\nstatic unsigned    dshow_factory_get_dev_count(pjmedia_vid_dev_factory *f);\nstatic pj_status_t dshow_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t      unsigned index,\n\t\t\t\t\t      pjmedia_vid_dev_info *info);\nstatic pj_status_t dshow_factory_default_param(pj_pool_t *pool,\n                                               pjmedia_vid_dev_factory *f,\n\t\t\t\t\t       unsigned index,\n\t\t\t\t\t       pjmedia_vid_dev_param *param);\nstatic pj_status_t dshow_factory_create_stream(\n\t\t\t\t\tpjmedia_vid_dev_factory *f,\n\t\t\t\t\tpjmedia_vid_dev_param *param,\n\t\t\t\t\tconst pjmedia_vid_dev_cb *cb,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tpjmedia_vid_dev_stream **p_vid_strm);\n\nstatic pj_status_t dshow_stream_get_param(pjmedia_vid_dev_stream *strm,\n\t\t\t\t\t  pjmedia_vid_dev_param *param);\nstatic pj_status_t dshow_stream_get_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t        pjmedia_vid_dev_cap cap,\n\t\t\t\t        void *value);\nstatic pj_status_t dshow_stream_set_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t        pjmedia_vid_dev_cap cap,\n\t\t\t\t        const void *value);\nstatic pj_status_t dshow_stream_start(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t dshow_stream_stop(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t dshow_stream_destroy(pjmedia_vid_dev_stream *strm);\n\n/* Operations */\nstatic pjmedia_vid_dev_factory_op factory_op =\n{\n    &dshow_factory_init,\n    &dshow_factory_destroy,\n    &dshow_factory_get_dev_count,\n    &dshow_factory_get_dev_info,\n    &dshow_factory_default_param,\n    &dshow_factory_create_stream,\n    &dshow_factory_refresh\n};\n\nstatic pjmedia_vid_dev_stream_op stream_op =\n{\n    &dshow_stream_get_param,\n    &dshow_stream_get_cap,\n    &dshow_stream_set_cap,\n    &dshow_stream_start,\n    NULL,\n    NULL,\n    &dshow_stream_stop,\n    &dshow_stream_destroy\n};\n\n\n/****************************************************************************\n * Factory operations\n */\n/*\n * Init dshow_ video driver.\n */\npjmedia_vid_dev_factory* pjmedia_dshow_factory(pj_pool_factory *pf)\n{\n    struct dshow_factory *f;\n    pj_pool_t *pool;\n\n    pool = pj_pool_create(pf, \"dshow video\", 1000, 1000, NULL);\n    f = PJ_POOL_ZALLOC_T(pool, struct dshow_factory);\n    f->pf = pf;\n    f->pool = pool;\n    f->base.op = &factory_op;\n\n    return &f->base;\n}\n\n/* API: init factory */\nstatic pj_status_t dshow_factory_init(pjmedia_vid_dev_factory *f)\n{\n    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);\n    if (hr == RPC_E_CHANGED_MODE) {\n        PJ_LOG(4,(THIS_FILE, \"Failed initializing DShow: \"\n                             \"COM library already initialized with \"\n                             \"incompatible concurrency model\"));\n        return PJMEDIA_EVID_INIT;\n    }\n\n    return dshow_factory_refresh(f);\n}\n\n/* API: destroy factory */\nstatic pj_status_t dshow_factory_destroy(pjmedia_vid_dev_factory *f)\n{\n    struct dshow_factory *df = (struct dshow_factory*)f;\n    pj_pool_t *pool = df->pool;\n\n    df->pool = NULL;\n    if (df->dev_pool)\n        pj_pool_release(df->dev_pool);\n    if (pool)\n        pj_pool_release(pool);\n\n    CoUninitialize();\n\n    return PJ_SUCCESS;\n}\n\nstatic HRESULT get_cap_device(struct dshow_factory *df,\n\t\t\t      unsigned id,\n\t\t\t      IBaseFilter **filter)\n{\n    IBindCtx *pbc;\n    HRESULT hr;\n\n    hr = CreateBindCtx(0, &pbc);\n    if (SUCCEEDED (hr)) {\n\tIMoniker *moniker;\n\tDWORD pchEaten;\n\n\thr = MkParseDisplayName(pbc, df->dev_info[id].display_name,\n\t\t\t\t&pchEaten, &moniker);\n\tif (SUCCEEDED(hr)) {\n\t    hr = IMoniker_BindToObject(moniker, pbc, NULL,\n\t\t\t\t       &IID_IBaseFilter,\n\t\t\t\t       (LPVOID *)filter);\n\t    IMoniker_Release(moniker);\n\t}\n\tIBindCtx_Release(pbc);\n    }\n\n    return hr;\n}\n\nstatic void enum_dev_cap(IBaseFilter *filter,\n\t\t\t pjmedia_dir dir,\n\t\t\t const GUID *dshow_fmt,\n\t\t\t AM_MEDIA_TYPE **pMediatype,\n                         int width,\n                         int height,\n\t\t\t IPin **pSrcpin,\n\t\t\t pjmedia_vid_dev_info *vdi)\n{\n    IEnumPins *pEnum;\n    AM_MEDIA_TYPE *mediatype = NULL;\n    pj_bool_t match_wh = PJ_FALSE;\n    HRESULT hr;\n\n    if (pSrcpin)\n\t*pSrcpin = NULL;\n    hr = IBaseFilter_EnumPins(filter, &pEnum);\n    if (SUCCEEDED(hr)) {\n        /* Loop through all the pins. */\n\tIPin *pPin = NULL;\n\n        while (IEnumPins_Next(pEnum, 1, &pPin, NULL) == S_OK) {\n            PIN_DIRECTION pindirtmp;\n\n            hr = IPin_QueryDirection(pPin, &pindirtmp);\n            if (hr != S_OK || pindirtmp != PINDIR_OUTPUT) {\n                if (SUCCEEDED(hr))\n                    IPin_Release(pPin);\n                continue;\n            }\n\n            if (dir == PJMEDIA_DIR_CAPTURE) {\n                IAMStreamConfig *streamcaps;\n\n                hr = IPin_QueryInterface(pPin, &IID_IAMStreamConfig,\n                                         (LPVOID *)&streamcaps);\n                if (SUCCEEDED(hr)) {\n                    VIDEO_STREAM_CONFIG_CAPS vscc;\n                    int i, isize, icount;\n\n                    IAMStreamConfig_GetNumberOfCapabilities(streamcaps,\n                                                            &icount, &isize);\n\n                    for (i = 0; i < icount; i++) {\n\t\t\tunsigned j, nformat;\n                        RPC_STATUS rpcstatus, rpcstatus2;\n\n                        hr = IAMStreamConfig_GetStreamCaps(streamcaps, i,\n                                                           &mediatype,\n                                                           (BYTE *)&vscc);\n                        if (FAILED (hr))\n                            continue;\n\n\t\t\tnformat = (dshow_fmt? 1:\n\t\t\t\t   sizeof(dshow_fmts)/sizeof(dshow_fmts[0]));\n\t\t\tfor (j = 0; j < nformat; j++) {\n\t\t\t    const GUID *dshow_format = dshow_fmt;\n                            \n\t\t\t    if (!dshow_format)\n\t\t\t\tdshow_format = dshow_fmts[j].dshow_format;\n\t\t\t    if (UuidCompare(&mediatype->subtype, \n\t\t\t\t\t    (UUID*)dshow_format,\n\t\t\t\t\t    &rpcstatus) == 0 && \n\t\t\t\trpcstatus == RPC_S_OK &&\n\t\t\t\tUuidCompare(&mediatype->formattype,\n\t\t\t\t\t    (UUID*)&FORMAT_VideoInfo,\n\t\t\t\t\t    &rpcstatus2) == 0 &&\n\t\t\t\trpcstatus2 == RPC_S_OK)\n\t\t\t    {\n                                VIDEOINFOHEADER *vi;\n\n                                vi = (VIDEOINFOHEADER *)mediatype->pbFormat;\n                                if (!dshow_fmt)\n                                    dshow_fmts[j].enabled = PJ_TRUE;\n\n\t\t\t\tif (vdi && vdi->fmt_cnt <\n                                    PJMEDIA_VID_DEV_INFO_FMT_CNT)\n                                {\n                                    unsigned fps_num=DEFAULT_FPS, fps_denum=1;\n                                    \n                                    if (vi->AvgTimePerFrame != 0) {\n                                        fps_num = 10000000;\n                                        fps_denum=(unsigned)vi->AvgTimePerFrame;\n                                    }\n                                        \n                                    pjmedia_format_init_video(\n                                        &vdi->fmt[vdi->fmt_cnt++],\n                                        dshow_fmts[j].pjmedia_format,\n                                        vi->bmiHeader.biWidth,\n                                        vi->bmiHeader.biHeight,\n                                        fps_num, fps_denum);\n                                }\n\t\t\t\t\n                                if (pSrcpin) {\n                                    if ((width == 0 && height == 0 ) ||\n                                        (vi->bmiHeader.biWidth == width &&\n                                         vi->bmiHeader.biHeight == height))\n                                    {\n                                        match_wh = PJ_TRUE;\n                                    }\n\t\t\t\t    *pSrcpin = pPin;\n\t\t\t\t    *pMediatype = mediatype;\n\t\t\t\t}\n\t\t\t    }\n\t\t\t}\n\t\t\tif (pSrcpin && *pSrcpin && match_wh)\n\t\t\t    break;\n                    }\n                    IAMStreamConfig_Release(streamcaps);\n                }\n            } else {\n                *pSrcpin = pPin;\n            }\n            if (pSrcpin && *pSrcpin)\n                break;\n            IPin_Release(pPin);\n\t}\n        IEnumPins_Release(pEnum);\n    }\n}\n\n/* API: refresh the list of devices */\nstatic pj_status_t dshow_factory_refresh(pjmedia_vid_dev_factory *f)\n{\n    struct dshow_factory *df = (struct dshow_factory*)f;\n    struct dshow_dev_info *ddi;\n    int dev_count = 0;\n    unsigned c;\n    ICreateDevEnum *dev_enum = NULL;\n    IEnumMoniker *enum_cat = NULL;\n    IMoniker *moniker = NULL;\n    HRESULT hr;\n    ULONG fetched;\n\n    if (df->dev_pool) {\n        pj_pool_release(df->dev_pool);\n        df->dev_pool = NULL;\n    }\n\n    for (c = 0; c < sizeof(dshow_fmts) / sizeof(dshow_fmts[0]); c++) {\n        dshow_fmts[c].enabled = PJ_FALSE;\n    }\n    \n    df->dev_count = 0;\n    df->dev_pool = pj_pool_create(df->pf, \"dshow video\", 500, 500, NULL);\n\n    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL,\n                          CLSCTX_INPROC_SERVER, &IID_ICreateDevEnum,\n                          (void**)&dev_enum);\n    if (FAILED(hr) ||\n        ICreateDevEnum_CreateClassEnumerator(dev_enum,\n            &CLSID_VideoInputDeviceCategory, &enum_cat, 0) != S_OK) \n    {\n\tPJ_LOG(4,(THIS_FILE, \"Windows found no video input devices\"));\n        if (dev_enum)\n            ICreateDevEnum_Release(dev_enum);\n\tdev_count = 0;\n    } else {\n        while (IEnumMoniker_Next(enum_cat, 1, &moniker, &fetched) == S_OK) {\n            dev_count++;\n        }\n    }\n\n    /* Add renderer device */\n    dev_count += 1;\n    df->dev_info = (struct dshow_dev_info*)\n \t\t   pj_pool_calloc(df->dev_pool, dev_count,\n \t\t\t\t  sizeof(struct dshow_dev_info));\n\n    if (dev_count > 1) {\n        IEnumMoniker_Reset(enum_cat);\n        while (IEnumMoniker_Next(enum_cat, 1, &moniker, &fetched) == S_OK) {\n            IPropertyBag *prop_bag;\n\n            hr = IMoniker_BindToStorage(moniker, 0, 0, &IID_IPropertyBag,\n                                        (void**)&prop_bag);\n            if (SUCCEEDED(hr)) {\n                VARIANT var_name;\n\n                VariantInit(&var_name);\n                hr = IPropertyBag_Read(prop_bag, L\"FriendlyName\",\n                                       &var_name, NULL);\n                if (SUCCEEDED(hr) && var_name.bstrVal) {\n                    WCHAR *wszDisplayName = NULL;\n\t\t    IBaseFilter *filter;\n                    pj_ssize_t len;\n\n                    ddi = &df->dev_info[df->dev_count++];\n                    pj_bzero(ddi, sizeof(*ddi));\n\n                    len = wcslen(var_name.bstrVal),\n                    len = WideCharToMultiByte(CP_ACP,\n                                              0,\n                                              var_name.bstrVal,\n                                              (int)len,\n                                              ddi->info.name,\n                                              sizeof(ddi->info.name), \n\t\t\t                      NULL,\n                                              NULL);\n\t            ddi->info.name[len] = '\\0';\n\n                    hr = IMoniker_GetDisplayName(moniker, NULL, NULL,\n                                                 &wszDisplayName);\n                    if (hr == S_OK && wszDisplayName) {\n                        pj_memcpy(ddi->display_name, wszDisplayName,\n                                  (wcslen(wszDisplayName)+1) * sizeof(WCHAR));\n                        CoTaskMemFree(wszDisplayName);\n                    }\n\n                    strncpy(ddi->info.driver, \"dshow\", \n                            sizeof(ddi->info.driver));\n                    ddi->info.driver[sizeof(ddi->info.driver)-1] = '\\0';\n                    ddi->info.dir = PJMEDIA_DIR_CAPTURE;\n                    ddi->info.has_callback = PJ_TRUE;\n\n                    /* Set the device capabilities here */\n                    ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;\n\n\t\t    hr = get_cap_device(df, df->dev_count-1, &filter);\n\t\t    if (SUCCEEDED(hr)) {\n\t\t\tddi->info.fmt_cnt = 0;\n\t\t\tenum_dev_cap(filter, ddi->info.dir, NULL, NULL,\n                                     0, 0, NULL, &ddi->info);\n\t\t    }\n                }\n                VariantClear(&var_name);\n\n                IPropertyBag_Release(prop_bag);\n            }\n            IMoniker_Release(moniker);\n        }\n\n        IEnumMoniker_Release(enum_cat);\n        ICreateDevEnum_Release(dev_enum);\n    }\n\n    PJ_LOG(4, (THIS_FILE, \"DShow has %d devices:\", \n\t       df->dev_count));\n    for (c = 0; c < df->dev_count; ++c) {\n\tPJ_LOG(4, (THIS_FILE, \" dev_id %d: %s (%s)\", \n\t       c,\n\t       df->dev_info[c].info.name,\n\t       df->dev_info[c].info.dir & PJMEDIA_DIR_CAPTURE ?\n               \"capture\" : \"render\"));\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: get number of devices */\nstatic unsigned dshow_factory_get_dev_count(pjmedia_vid_dev_factory *f)\n{\n    struct dshow_factory *df = (struct dshow_factory*)f;\n    return df->dev_count;\n}\n\n/* API: get device info */\nstatic pj_status_t dshow_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t      unsigned index,\n\t\t\t\t\t      pjmedia_vid_dev_info *info)\n{\n    struct dshow_factory *df = (struct dshow_factory*)f;\n\n    PJ_ASSERT_RETURN(index < df->dev_count, PJMEDIA_EVID_INVDEV);\n\n    pj_memcpy(info, &df->dev_info[index].info, sizeof(*info));\n\n    return PJ_SUCCESS;\n}\n\n/* API: create default device parameter */\nstatic pj_status_t dshow_factory_default_param(pj_pool_t *pool,\n                                               pjmedia_vid_dev_factory *f,\n\t\t\t\t\t       unsigned index,\n\t\t\t\t\t       pjmedia_vid_dev_param *param)\n{\n    struct dshow_factory *df = (struct dshow_factory*)f;\n    struct dshow_dev_info *di = &df->dev_info[index];\n\n    PJ_ASSERT_RETURN(index < df->dev_count, PJMEDIA_EVID_INVDEV);\n\n    PJ_UNUSED_ARG(pool);\n\n    pj_bzero(param, sizeof(*param));\n    if (di->info.dir & PJMEDIA_DIR_CAPTURE) {\n\tparam->dir = PJMEDIA_DIR_CAPTURE;\n\tparam->cap_id = index;\n\tparam->rend_id = PJMEDIA_VID_INVALID_DEV;\n    } else {\n\treturn PJMEDIA_EVID_INVDEV;\n    }\n\n    /* Set the device capabilities here */\n    param->clock_rate = DEFAULT_CLOCK_RATE;\n    param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;\n\n    pjmedia_format_copy(&param->fmt, &di->info.fmt[0]);\n\n    return PJ_SUCCESS;\n}\n\nstatic void input_cb(void *user_data, IMediaSample *pMediaSample)\n{\n    struct dshow_stream *strm = (struct dshow_stream*)user_data;\n    pjmedia_frame frame = {0};\n\n    if (strm->quit_flag) {\n        strm->cap_thread_exited = PJ_TRUE;\n        return;\n    }\n\n    if (strm->cap_thread_initialized == 0 || !pj_thread_is_registered())\n    {\n        pj_status_t status;\n\n\tstatus = pj_thread_register(\"ds_cap\", strm->cap_thread_desc, \n\t\t\t\t    &strm->cap_thread);\n        if (status != PJ_SUCCESS)\n            return;\n\tstrm->cap_thread_initialized = 1;\n\tPJ_LOG(5,(THIS_FILE, \"Capture thread started\"));\n    }\n\n    frame.type = PJMEDIA_FRAME_TYPE_VIDEO;\n    IMediaSample_GetPointer(pMediaSample, (BYTE **)&frame.buf);\n    frame.size = IMediaSample_GetActualDataLength(pMediaSample);\n    frame.bit_info = 0;\n    frame.timestamp = strm->cap_ts;\n    strm->cap_ts.u64 += strm->cap_ts_inc;\n\n    if (strm->frm_buf_size) {\n        unsigned i, stride;\n        BYTE *src_buf, *dst_buf;\n        pjmedia_video_format_detail *vfd;\n        \n        /* Image is bottom-up, convert it to top-down. */\n        src_buf = dst_buf = (BYTE *)frame.buf;\n        stride = strm->frm_buf_size;\n        vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt,\n                                                     PJ_TRUE);\n        src_buf += (vfd->size.h - 1) * stride;\n\n        for (i = vfd->size.h / 2; i > 0; i--) {\n            memcpy(strm->frm_buf, dst_buf, stride);\n            memcpy(dst_buf, src_buf, stride);\n            memcpy(src_buf, strm->frm_buf, stride);\n            dst_buf += stride;\n            src_buf -= stride;\n        }\n    }\n\n    if (strm->vid_cb.capture_cb)\n        (*strm->vid_cb.capture_cb)(&strm->base, strm->user_data, &frame);\n}\n\nstatic dshow_fmt_info* get_dshow_format_info(pjmedia_format_id id)\n{\n    unsigned i;\n\n    for (i = 0; i < sizeof(dshow_fmts)/sizeof(dshow_fmts[0]); i++) {\n        if (dshow_fmts[i].pjmedia_format == id && dshow_fmts[i].enabled)\n            return &dshow_fmts[i];\n    }\n\n    return NULL;\n}\n\nstatic pj_status_t create_filter_graph(pjmedia_dir dir,\n                                       unsigned id,\n                                       pj_bool_t use_def_size,\n                                       pj_bool_t use_def_fps,\n                                       struct dshow_factory *df,\n                                       struct dshow_stream *strm,\n                                       struct dshow_graph *graph)\n{\n    HRESULT hr;\n    IEnumPins *pEnum;\n    IPin *srcpin = NULL;\n    IPin *sinkpin = NULL;\n    AM_MEDIA_TYPE *mediatype = NULL;\n    VIDEOINFOHEADER *video_info, *vi = NULL;\n    pjmedia_video_format_detail *vfd;\n    const pjmedia_video_format_info *vfi;\n\n    PJ_ASSERT_RETURN(dir == PJMEDIA_DIR_CAPTURE, PJ_EINVAL);\n\n    vfi = pjmedia_get_video_format_info(pjmedia_video_format_mgr_instance(),\n                                        strm->param.fmt.id);\n    if (!vfi)\n        return PJMEDIA_EVID_BADFORMAT;\n\n    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);\n    if (FAILED(hr)) {\n\tPJ_LOG(4,(THIS_FILE, \"Error: CoInitializeEx\")); \n        goto on_error;\n    }\n\n    hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC,\n                          &IID_IFilterGraph, (LPVOID *)&graph->filter_graph);\n    if (FAILED(hr)) {\n        goto on_error;\n    }\n\n    hr = IFilterGraph_QueryInterface(graph->filter_graph, &IID_IMediaFilter,\n                                     (LPVOID *)&graph->media_filter);\n    if (FAILED(hr)) {\n        goto on_error;\n    }\n\n\thr = get_cap_device(df, id, &graph->source_filter);\n\tif (FAILED(hr)) {\n            goto on_error;\n        }\n\n    hr = IFilterGraph_AddFilter(graph->filter_graph, graph->source_filter,\n                                L\"capture\");\n    if (FAILED(hr)) {\n        goto on_error;\n    }\n\n    graph->rend_filter = NullRenderer_Create(input_cb, strm);\n\n    IBaseFilter_EnumPins(graph->rend_filter, &pEnum);\n    if (SUCCEEDED(hr)) {\n        // Loop through all the pins\n\tIPin *pPin = NULL;\n\n        while (IEnumPins_Next(pEnum, 1, &pPin, NULL) == S_OK) {\n            PIN_DIRECTION pindirtmp;\n\n            hr = IPin_QueryDirection(pPin, &pindirtmp);\n            if (hr == S_OK && pindirtmp == PINDIR_INPUT) {\n                sinkpin = pPin;\n                break;\n            }\n\t    IPin_Release(pPin);\n        }\n        IEnumPins_Release(pEnum);\n    }\n\n    vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE);\n\n    enum_dev_cap(graph->source_filter, dir,\n\t\t get_dshow_format_info(strm->param.fmt.id)->dshow_format,\n\t\t &mediatype, (use_def_size? 0: vfd->size.w),\n                 (use_def_size? 0: vfd->size.h), &srcpin, NULL);\n    graph->mediatype = mediatype;\n\n    if (!srcpin || !sinkpin || !mediatype) {\n        hr = VFW_E_TYPE_NOT_ACCEPTED;\n        goto on_error;\n    }\n    video_info = (VIDEOINFOHEADER *) mediatype->pbFormat;\n    if (!use_def_size) {\n        video_info->bmiHeader.biWidth = vfd->size.w;\n        video_info->bmiHeader.biHeight = vfd->size.h;\n    }\n    if (video_info->AvgTimePerFrame == 0 ||\n        (!use_def_fps && vfd->fps.num != 0))\n    {\n        video_info->AvgTimePerFrame = (LONGLONG) (10000000 * \n\t\t\t\t\t\t  (double)vfd->fps.denum /\n\t\t\t\t\t\t  vfd->fps.num);\n    }\n    video_info->bmiHeader.biSizeImage = DIBSIZE(video_info->bmiHeader);\n    mediatype->lSampleSize = DIBSIZE(video_info->bmiHeader);\n\n    hr = IFilterGraph_AddFilter(graph->filter_graph,\n                                (IBaseFilter *)graph->rend_filter,\n                                L\"renderer\");\n    if (FAILED(hr))\n        goto on_error;\n\n    hr = IFilterGraph_ConnectDirect(graph->filter_graph, srcpin, sinkpin,\n                                    mediatype);\n    if (SUCCEEDED(hr)) {\n        if (use_def_size || use_def_fps) {\n            pjmedia_format_init_video(&strm->param.fmt, strm->param.fmt.id,\n                                      video_info->bmiHeader.biWidth,\n                                      video_info->bmiHeader.biHeight,\n                                      10000000,\n                                      (unsigned)video_info->AvgTimePerFrame);\n        }\n\n        strm->frm_buf_size = 0;\n        if (dir == PJMEDIA_DIR_CAPTURE &&\n            video_info->bmiHeader.biCompression == BI_RGB &&\n            video_info->bmiHeader.biHeight > 0)\n        {\n            /* Allocate buffer to flip the captured image. */\n            strm->frm_buf_size = (video_info->bmiHeader.biBitCount >> 3) *\n                                 video_info->bmiHeader.biWidth;\n            strm->frm_buf = pj_pool_alloc(strm->pool, strm->frm_buf_size);\n        }\n    }\n\non_error:\n    if (srcpin)\n        IPin_Release(srcpin);\n    if (sinkpin)\n        IPin_Release(sinkpin);\n    if (vi)\n        CoTaskMemFree(vi);\n    if (FAILED(hr)) {\n\tchar msg[80];\n\tif (AMGetErrorText(hr, msg, sizeof(msg))) {\n\t    PJ_LOG(4,(THIS_FILE, \"Error creating filter graph: %s (hr=0x%x)\", \n\t\t      msg, hr));\n\t}\n        return PJ_EUNKNOWN;\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic void destroy_filter_graph(struct dshow_stream * stream)\n{\n    if (stream->dgraph.source_filter) {\n        IBaseFilter_Release(stream->dgraph.source_filter);\n        stream->dgraph.source_filter = NULL;\n    }\n    if (stream->dgraph.rend_filter) {\n        IBaseFilter_Release(stream->dgraph.rend_filter);\n        stream->dgraph.rend_filter = NULL;\n    }\n    if (stream->dgraph.media_filter) {\n        IMediaFilter_Release(stream->dgraph.media_filter);\n        stream->dgraph.media_filter = NULL;\n    }\n    if (stream->dgraph.filter_graph) {\n        IFilterGraph_Release(stream->dgraph.filter_graph);\n        stream->dgraph.filter_graph = NULL;\n    }\n}\n\n/* API: create stream */\nstatic pj_status_t dshow_factory_create_stream(\n\t\t\t\t\tpjmedia_vid_dev_factory *f,\n\t\t\t\t\tpjmedia_vid_dev_param *param,\n\t\t\t\t\tconst pjmedia_vid_dev_cb *cb,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tpjmedia_vid_dev_stream **p_vid_strm)\n{\n    struct dshow_factory *df = (struct dshow_factory*)f;\n    pj_pool_t *pool;\n    struct dshow_stream *strm;\n    pj_status_t status;\n    const pjmedia_video_format_detail *vfd;\n\n    PJ_ASSERT_RETURN(param->dir == PJMEDIA_DIR_CAPTURE, PJ_EINVAL);\n\n    if (!get_dshow_format_info(param->fmt.id))\n        return PJMEDIA_EVID_BADFORMAT;\n\n    /* Create and Initialize stream descriptor */\n    pool = pj_pool_create(df->pf, \"dshow-dev\", 1000, 1000, NULL);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    strm = PJ_POOL_ZALLOC_T(pool, struct dshow_stream);\n    pj_memcpy(&strm->param, param, sizeof(*param));\n    strm->pool = pool;\n    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));\n    strm->user_data = user_data;\n\n        /* Create capture stream here */\n        status = create_filter_graph(PJMEDIA_DIR_CAPTURE, param->cap_id,\n                                     PJ_FALSE, PJ_FALSE, df, strm,\n                                     &strm->dgraph);\n        if (status != PJ_SUCCESS) {\n            destroy_filter_graph(strm);\n            /* Try to use default fps */\n            PJ_LOG(4,(THIS_FILE, \"Trying to open dshow dev with default fps\"));\n            status = create_filter_graph(PJMEDIA_DIR_CAPTURE, param->cap_id,\n                                         PJ_FALSE, PJ_TRUE, df, strm,\n                                         &strm->dgraph);\n\n            if (status != PJ_SUCCESS) {\n                /* Still failed, now try to use default fps and size */\n                destroy_filter_graph(strm);\n                /* Try to use default fps */\n                PJ_LOG(4,(THIS_FILE, \"Trying to open dshow dev with default \"\n                                     \"size & fps\"));\n                status = create_filter_graph(PJMEDIA_DIR_CAPTURE,\n                                             param->cap_id,\n                                             PJ_TRUE, PJ_TRUE, df, strm,\n                                             &strm->dgraph);\n            }\n\n            if (status != PJ_SUCCESS)\n                goto on_error;\n            pj_memcpy(param, &strm->param, sizeof(*param));\n        }\n\t\n\tvfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);\n\tstrm->cap_ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);\n\n    /* Done */\n    strm->base.op = &stream_op;\n    *p_vid_strm = &strm->base;\n\n    return PJ_SUCCESS;\n \non_error:\n    dshow_stream_destroy((pjmedia_vid_dev_stream *)strm);\n    return status;\n}\n\n/* API: Get stream info. */\nstatic pj_status_t dshow_stream_get_param(pjmedia_vid_dev_stream *s,\n\t\t\t\t\t  pjmedia_vid_dev_param *pi)\n{\n    struct dshow_stream *strm = (struct dshow_stream*)s;\n\n    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);\n\n    pj_memcpy(pi, &strm->param, sizeof(*pi));\n\n    if (dshow_stream_get_cap(s, PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW,\n\t\t\t     &pi->window) == PJ_SUCCESS)\n    {\n        pi->flags |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: get capability */\nstatic pj_status_t dshow_stream_get_cap(pjmedia_vid_dev_stream *s,\n\t\t\t\t        pjmedia_vid_dev_cap cap,\n\t\t\t\t        void *pval)\n{\n    struct dshow_stream *strm = (struct dshow_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    if (cap==PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW)\n    {\n\t*(unsigned*)pval = 0;\n\treturn PJ_SUCCESS;\n    } else {\n\treturn PJMEDIA_EVID_INVCAP;\n    }\n}\n\n/* API: set capability */\nstatic pj_status_t dshow_stream_set_cap(pjmedia_vid_dev_stream *s,\n\t\t\t\t        pjmedia_vid_dev_cap cap,\n\t\t\t\t        const void *pval)\n{\n    struct dshow_stream *strm = (struct dshow_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    if (cap==PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW)\n    {\n\t// set renderer's window here\n\treturn PJ_SUCCESS;\n    }\n\n    return PJMEDIA_EVID_INVCAP;\n}\n\n/* API: Start stream. */\nstatic pj_status_t dshow_stream_start(pjmedia_vid_dev_stream *strm)\n{\n    struct dshow_stream *stream = (struct dshow_stream*)strm;\n    HRESULT hr;\n\n    stream->quit_flag = PJ_FALSE;\n    stream->cap_thread_exited = PJ_FALSE;\n    stream->rend_thread_exited = PJ_FALSE;\n\n    hr = IMediaFilter_Run(stream->dgraph.media_filter, 0);\n    if (FAILED(hr)) {\n        char msg[80];\n        if (AMGetErrorText(hr, msg, sizeof(msg))) {\n            PJ_LOG(4,(THIS_FILE, \"Error starting media: %s\", msg));\n        }\n        return PJ_EUNKNOWN;\n    }\n\n    PJ_LOG(4, (THIS_FILE, \"Starting dshow video stream\"));\n\n    return PJ_SUCCESS;\n}\n\n/* API: Stop stream. */\nstatic pj_status_t dshow_stream_stop(pjmedia_vid_dev_stream *strm)\n{\n    struct dshow_stream *stream = (struct dshow_stream*)strm;\n    unsigned i;\n\n    stream->quit_flag = PJ_TRUE;\n    if (stream->cap_thread) {\n        for (i=0; !stream->cap_thread_exited && i<100; ++i)\n\t    pj_thread_sleep(10);\n    }\n    for (i=0; !stream->rend_thread_exited && i<100; ++i)\n\tpj_thread_sleep(10);\n\n    if (stream->dgraph.media_filter)\n\tIMediaFilter_Stop(stream->dgraph.media_filter);\n\n    PJ_LOG(4, (THIS_FILE, \"Stopping dshow video stream\"));\n\n    return PJ_SUCCESS;\n}\n\n/* API: Destroy stream. */\nstatic pj_status_t dshow_stream_destroy(pjmedia_vid_dev_stream *strm)\n{\n    struct dshow_stream *stream = (struct dshow_stream*)strm;\n\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n\n    dshow_stream_stop(strm);\n    destroy_filter_graph(stream);\n\n    pj_pool_release(stream->pool);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_VIDEO_DEV_HAS_DSHOW */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-videodev/dshow_filter.cpp",
    "content": "/* $Id: dshowclasses.cpp 4062 2012-04-19 06:36:57Z ming $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\n#include <pjmedia-videodev/config.h>\n\n\n#if defined(PJMEDIA_VIDEO_DEV_HAS_DSHOW) && PJMEDIA_VIDEO_DEV_HAS_DSHOW != 0\n\n#include <DShow.h>\n#include <assert.h>\n#include <streams.h>\n\ntypedef void (*input_callback)(void *user_data, IMediaSample *pMediaSample);\n\nconst GUID CLSID_NullRenderer = {0xF9168C5E, 0xCEB2, 0x4FAA, {0xB6, 0xBF,\n                                 0x32, 0x9B, 0xF3, 0x9F, 0xA1, 0xE4}};\n\nclass NullRenderer: public CBaseRenderer\n{\npublic:\n    NullRenderer(HRESULT *pHr);\n    virtual ~NullRenderer();\n\n    virtual HRESULT CheckMediaType(const CMediaType *pmt);\n    virtual HRESULT DoRenderSample(IMediaSample *pMediaSample);\n\n    input_callback  input_cb;\n    void           *user_data;\n};\n\nNullRenderer::NullRenderer(HRESULT *pHr): CBaseRenderer(CLSID_NullRenderer,\n                                                        \"NullRenderer\",\n                                                        NULL, pHr)\n{\n    input_cb = NULL;\n}\n\nNullRenderer::~NullRenderer()\n{\n}\n\nHRESULT NullRenderer::CheckMediaType(const CMediaType *pmt)\n{\n    return S_OK;\n}\n\nHRESULT NullRenderer::DoRenderSample(IMediaSample *pMediaSample)\n{\n    if (input_cb)\n        input_cb(user_data, pMediaSample);\n\n    return S_OK;\n}\n\nextern \"C\" IBaseFilter* NullRenderer_Create(input_callback input_cb,\n                                             void *user_data)\n{\n    HRESULT hr;\n    NullRenderer *renderer = new NullRenderer(&hr);\n    renderer->AddRef();\n    renderer->input_cb = input_cb;\n    renderer->user_data = user_data;\n\n    return (CBaseFilter *)renderer;\n}\n\n#endif\t/* PJMEDIA_VIDEO_DEV_HAS_DSHOW */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-videodev/errno.c",
    "content": "/* $Id: errno.c 3715 2011-08-19 09:35:25Z nanang $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia-videodev/errno.h>\n#include <pj/string.h>\n#include <pj/unicode.h>\n\n/* PJMEDIA-videodev's own error codes/messages\n * MUST KEEP THIS ARRAY SORTED!!\n * Message must be limited to 64 chars!\n */\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n\nstatic const struct\n{\n    int code;\n    const char *msg;\n} err_str[] =\n{\n    PJ_BUILD_ERR( PJMEDIA_EVID_ERR,\t    \"Unspecified video device error\" ),\n    PJ_BUILD_ERR( PJMEDIA_EVID_SYSERR,\t    \"Unknown error from video driver\" ),\n    PJ_BUILD_ERR( PJMEDIA_EVID_INIT,\t    \"video subsystem not initialized\" ),\n    PJ_BUILD_ERR( PJMEDIA_EVID_INVDEV,\t    \"Invalid video device\" ),\n    PJ_BUILD_ERR( PJMEDIA_EVID_NODEV,\t    \"Found no video devices\" ),\n    PJ_BUILD_ERR( PJMEDIA_EVID_NODEFDEV,    \"Unable to find default video device\" ),\n    PJ_BUILD_ERR( PJMEDIA_EVID_NOTREADY,    \"video device not ready\" ),\n    PJ_BUILD_ERR( PJMEDIA_EVID_INVCAP,\t    \"Invalid or unsupported video capability\" ),\n    PJ_BUILD_ERR( PJMEDIA_EVID_INVOP,\t    \"Invalid or unsupported video device operation\" ),\n    PJ_BUILD_ERR( PJMEDIA_EVID_BADFORMAT,   \"Bad or invalid video device format\" ),\n    PJ_BUILD_ERR( PJMEDIA_EVID_SAMPFORMAT,  \"Invalid video device sample format\"),\n    PJ_BUILD_ERR( PJMEDIA_EVID_BADLATENCY,  \"Bad video latency setting\")\n\n};\n\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n\n\n/*\n * pjmedia_videodev_strerror()\n */\nPJ_DEF(pj_str_t) pjmedia_videodev_strerror(pj_status_t statcode,\n\t\t\t\t\t   char *buf, pj_size_t bufsize )\n{\n    pj_str_t errstr;\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n\n    /* videodev error */\n    if (statcode >= PJMEDIA_VIDEODEV_ERRNO_START &&\n\tstatcode < PJMEDIA_VIDEODEV_ERRNO_END)\n    {\n\t/* Find the error in the table.\n\t * Use binary search!\n\t */\n\tint first = 0;\n\tint n = PJ_ARRAY_SIZE(err_str);\n\n\twhile (n > 0) {\n\t    int half = n/2;\n\t    int mid = first + half;\n\n\t    if (err_str[mid].code < statcode) {\n\t\tfirst = mid+1;\n\t\tn -= (half+1);\n\t    } else if (err_str[mid].code > statcode) {\n\t\tn = half;\n\t    } else {\n\t\tfirst = mid;\n\t\tbreak;\n\t    }\n\t}\n\n\n\tif (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {\n\t    pj_str_t msg;\n\n\t    msg.ptr = (char*)err_str[first].msg;\n\t    msg.slen = pj_ansi_strlen(err_str[first].msg);\n\n\t    errstr.ptr = buf;\n\t    pj_strncpy_with_null(&errstr, &msg, bufsize);\n\t    return errstr;\n\n\t}\n    }\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n    /* Error not found. */\n    errstr.ptr = buf;\n    errstr.slen = pj_ansi_snprintf(buf, bufsize,\n\t\t\t\t   \"Unknown pjmedia-videodev error %d\",\n\t\t\t\t   statcode);\n    if (errstr.slen < 1 || errstr.slen >= (pj_ssize_t)bufsize)\n\terrstr.slen = bufsize - 1;\n    return errstr;\n}\n\n\n#endif /* PJMEDIA_HAS_VIDEO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-videodev/fb_dev.c",
    "content": "/*\n * Copyright (C) 2014-present AG Projects\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia-videodev/videodev_imp.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n\n#if defined(PJMEDIA_HAS_VIDEO) && PJMEDIA_HAS_VIDEO != 0 && \\\n    defined(PJMEDIA_VIDEO_DEV_HAS_FB) && PJMEDIA_VIDEO_DEV_HAS_FB != 0\n\n#include <pjmedia-videodev/fb_dev.h>\n\n#define THIS_FILE\t\t\"fb_dev.c\"\n#define DEFAULT_CLOCK_RATE\t90000\n#define DEFAULT_WIDTH\t\t640\n#define DEFAULT_HEIGHT\t\t480\n#define DEFAULT_FPS\t\t25\n\n\n/* Supported formats */\n#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0\nstatic pjmedia_format_id fb_fmts[] = {PJMEDIA_FORMAT_ARGB};\n#else\nstatic pjmedia_format_id fb_fmts[] = {PJMEDIA_FORMAT_BGRA};\n#endif\n\n\n/* fb device info */\nstruct fb_dev_info\n{\n    pjmedia_vid_dev_info\t info;\n};\n\n\n/* factory */\nstruct fb_factory\n{\n    pjmedia_vid_dev_factory\t base;\n    pj_pool_t\t\t\t*pool;\n    pj_pool_factory\t\t*pf;\n\n    unsigned\t\t\t dev_count;\n    struct fb_dev_info\t        *dev_info;\n};\n\n\n/* Video stream. */\nstruct fb_stream\n{\n    pjmedia_vid_dev_stream\t base;\t\t    /**< Base stream\t    */\n    pjmedia_vid_dev_param\t param;\t\t    /**< Settings\t    */\n    pj_pool_t\t\t\t*pool;              /**< Memory pool.       */\n\n    pjmedia_vid_dev_cb\t\t vid_cb;            /**< Stream callback.   */\n    void\t\t\t*user_data;         /**< Application data.  */\n\n    struct fb_factory           *ff;\n    pj_bool_t\t\t\t is_running;\n    pjmedia_rect_size            vid_size;\n\n    struct {\n        pjmedia_vid_dev_fb_frame_cb cb;\n        void *user_data;\n    } frame_handler;\n};\n\n\n/* Prototypes */\nstatic pj_status_t fb_factory_init(pjmedia_vid_dev_factory *f);\nstatic pj_status_t fb_factory_destroy(pjmedia_vid_dev_factory *f);\nstatic pj_status_t fb_factory_refresh(pjmedia_vid_dev_factory *f);\nstatic unsigned    fb_factory_get_dev_count(pjmedia_vid_dev_factory *f);\nstatic pj_status_t fb_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t   unsigned index,\n\t\t\t\t\t   pjmedia_vid_dev_info *info);\nstatic pj_status_t fb_factory_default_param(pj_pool_t *pool,\n                                            pjmedia_vid_dev_factory *f,\n\t\t\t\t\t    unsigned index,\n\t\t\t\t\t    pjmedia_vid_dev_param *param);\nstatic pj_status_t fb_factory_create_stream(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t    pjmedia_vid_dev_param *param,\n\t\t\t\t\t    const pjmedia_vid_dev_cb *cb,\n\t\t\t\t\t    void *user_data,\n\t\t\t\t\t    pjmedia_vid_dev_stream **p_vid_strm);\n\nstatic pj_status_t fb_stream_get_param(pjmedia_vid_dev_stream *strm,\n\t\t\t\t       pjmedia_vid_dev_param *param);\nstatic pj_status_t fb_stream_get_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t     pjmedia_vid_dev_cap cap,\n\t\t\t\t     void *value);\nstatic pj_status_t fb_stream_set_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t     pjmedia_vid_dev_cap cap,\n\t\t\t\t     const void *value);\nstatic pj_status_t fb_stream_put_frame(pjmedia_vid_dev_stream *strm,\n                                       const pjmedia_frame *frame);\nstatic pj_status_t fb_stream_start(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t fb_stream_stop(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t fb_stream_destroy(pjmedia_vid_dev_stream *strm);\n\n\n/* Operations */\nstatic pjmedia_vid_dev_factory_op factory_op =\n{\n    &fb_factory_init,\n    &fb_factory_destroy,\n    &fb_factory_get_dev_count,\n    &fb_factory_get_dev_info,\n    &fb_factory_default_param,\n    &fb_factory_create_stream,\n    &fb_factory_refresh\n};\n\nstatic pjmedia_vid_dev_stream_op stream_op =\n{\n    &fb_stream_get_param,\n    &fb_stream_get_cap,\n    &fb_stream_set_cap,\n    &fb_stream_start,\n    NULL,\n    &fb_stream_put_frame,\n    &fb_stream_stop,\n    &fb_stream_destroy\n};\n\n\n/****************************************************************************\n * Factory operations\n */\n/*\n * Init FB video driver.\n */\npjmedia_vid_dev_factory* pjmedia_fb_factory(pj_pool_factory *pf)\n{\n    struct fb_factory *f;\n    pj_pool_t *pool;\n\n    pool = pj_pool_create(pf, \"fb video\", 1000, 1000, NULL);\n    f = PJ_POOL_ZALLOC_T(pool, struct fb_factory);\n    f->pf = pf;\n    f->pool = pool;\n    f->base.op = &factory_op;\n\n    return &f->base;\n}\n\n\n/* API: init factory */\nstatic pj_status_t fb_factory_init(pjmedia_vid_dev_factory *f)\n{\n    struct fb_factory *ff = (struct fb_factory*)f;\n    struct fb_dev_info *di;\n    unsigned i, l;\n\n    /* Initialize input and output devices here */\n    ff->dev_info = (struct fb_dev_info*)\n    pj_pool_calloc(ff->pool, 1, sizeof(struct fb_dev_info));\n\n    ff->dev_count = 0;\n    di = &ff->dev_info[ff->dev_count++];\n    pj_bzero(di, sizeof(*di));\n    strcpy(di->info.name, \"FrameBuffer renderer\");\n    strcpy(di->info.driver, \"FrameBuffer\");\n    di->info.dir = PJMEDIA_DIR_RENDER;\n    di->info.has_callback = PJ_FALSE;\n    di->info.caps = 0;\n\n    for (i = 0; i < ff->dev_count; i++) {\n\tdi = &ff->dev_info[i];\n\tdi->info.fmt_cnt = PJ_ARRAY_SIZE(fb_fmts);\n\tdi->info.caps |= PJMEDIA_VID_DEV_CAP_FORMAT;\n\n\tfor (l = 0; l < PJ_ARRAY_SIZE(fb_fmts); l++) {\n\t    pjmedia_format *fmt = &di->info.fmt[l];\n\t    pjmedia_format_init_video(fmt,\n\t\t\t\t      fb_fmts[l],\n\t\t\t\t      DEFAULT_WIDTH,\n\t\t\t\t      DEFAULT_HEIGHT,\n\t\t\t\t      DEFAULT_FPS, 1);\n\t}\n    }\n\n    PJ_LOG(4, (THIS_FILE, \"FrameBuffer initialized\"));\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: destroy factory */\nstatic pj_status_t fb_factory_destroy(pjmedia_vid_dev_factory *f)\n{\n    struct fb_factory *ff = (struct fb_factory*)f;\n    pj_pool_t *pool = ff->pool;\n\n    ff->pool = NULL;\n    pj_pool_release(pool);\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: refresh the list of devices */\nstatic pj_status_t fb_factory_refresh(pjmedia_vid_dev_factory *f)\n{\n    PJ_UNUSED_ARG(f);\n    return PJ_SUCCESS;\n}\n\n\n/* API: get number of devices */\nstatic unsigned fb_factory_get_dev_count(pjmedia_vid_dev_factory *f)\n{\n    struct fb_factory *ff = (struct fb_factory*)f;\n    return ff->dev_count;\n}\n\n\n/* API: get device info */\nstatic pj_status_t fb_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t   unsigned index,\n\t\t\t\t\t   pjmedia_vid_dev_info *info)\n{\n    struct fb_factory *ff = (struct fb_factory*)f;\n\n    PJ_ASSERT_RETURN(index < ff->dev_count, PJMEDIA_EVID_INVDEV);\n    pj_memcpy(info, &ff->dev_info[index].info, sizeof(*info));\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: create default device parameter */\nstatic pj_status_t fb_factory_default_param(pj_pool_t *pool,\n                                            pjmedia_vid_dev_factory *f,\n\t\t\t\t\t    unsigned index,\n\t\t\t\t\t    pjmedia_vid_dev_param *param)\n{\n    struct fb_factory *ff = (struct fb_factory*)f;\n    struct fb_dev_info *di = &ff->dev_info[index];\n\n    PJ_ASSERT_RETURN(index < ff->dev_count, PJMEDIA_EVID_INVDEV);\n    PJ_UNUSED_ARG(pool);\n\n    pj_bzero(param, sizeof(*param));\n    param->dir = PJMEDIA_DIR_RENDER;\n    param->rend_id = index;\n    param->cap_id = PJMEDIA_VID_INVALID_DEV;\n\n    /* Set the device capabilities here */\n    param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;\n    param->clock_rate = DEFAULT_CLOCK_RATE;\n    pj_memcpy(&param->fmt, &di->info.fmt[0], sizeof(param->fmt));\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: Put frame from stream */\nstatic pj_status_t fb_stream_put_frame(pjmedia_vid_dev_stream *strm,\n                                       const pjmedia_frame *frame)\n{\n    struct fb_stream *stream = (struct fb_stream*)strm;\n\n    if (!stream->is_running)\n\treturn PJ_EINVALIDOP;\n\n    if (frame->size==0 || frame->buf==NULL)\n\treturn PJ_SUCCESS;\n\n    if (stream->frame_handler.cb)\n        stream->frame_handler.cb(frame, stream->vid_size, stream->frame_handler.user_data);\n\n    return PJ_SUCCESS;\n}\n\n/* API: create stream */\nstatic pj_status_t fb_factory_create_stream(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t    pjmedia_vid_dev_param *param,\n\t\t\t\t\t    const pjmedia_vid_dev_cb *cb,\n\t\t\t\t\t    void *user_data,\n\t\t\t\t\t    pjmedia_vid_dev_stream **p_vid_strm)\n{\n    struct fb_factory *ff = (struct fb_factory*)f;\n    pj_pool_t *pool;\n    pj_status_t status;\n    struct fb_stream *strm;\n    const pjmedia_video_format_info *vfi;\n\n    PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);\n    PJ_ASSERT_RETURN(param->dir == PJMEDIA_DIR_RENDER, PJ_EINVAL);\n    PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&\n\t\t     param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&\n                     param->dir == PJMEDIA_DIR_RENDER,\n\t\t     PJ_EINVAL);\n\n    vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);\n    if (!vfi)\n        return PJMEDIA_EVID_BADFORMAT;\n\n    /* Create and Initialize stream descriptor */\n    pool = pj_pool_create(ff->pf, \"fb-dev\", 1000, 1000, NULL);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    strm = PJ_POOL_ZALLOC_T(pool, struct fb_stream);\n    pj_memcpy(&strm->param, param, sizeof(*param));\n    strm->pool = pool;\n    strm->ff = ff;\n    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));\n    strm->user_data = user_data;\n\n    status = fb_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_FORMAT, &param->fmt);\n    if (status != PJ_SUCCESS) {\n        fb_stream_destroy((pjmedia_vid_dev_stream *)strm);\n        return status;\n    }\n\n    /* Done */\n    strm->base.op = &stream_op;\n    *p_vid_strm = &strm->base;\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: Get stream info. */\nstatic pj_status_t fb_stream_get_param(pjmedia_vid_dev_stream *s,\n\t\t\t               pjmedia_vid_dev_param *pi)\n{\n    struct fb_stream *strm = (struct fb_stream*)s;\n    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);\n\n    pj_memcpy(pi, &strm->param, sizeof(*pi));\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: get capability */\nstatic pj_status_t fb_stream_get_cap(pjmedia_vid_dev_stream *s,\n\t\t\t\t     pjmedia_vid_dev_cap cap,\n\t\t\t\t     void *pval)\n{\n    struct fb_stream *strm = (struct fb_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n    PJ_UNUSED_ARG(cap);\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    return PJMEDIA_EVID_INVCAP;\n}\n\n\n/* API: set capability */\nstatic pj_status_t fb_stream_set_cap(pjmedia_vid_dev_stream *s,\n\t\t\t\t     pjmedia_vid_dev_cap cap,\n\t\t\t\t     const void *pval)\n{\n    struct fb_stream *strm = (struct fb_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    if (cap == PJMEDIA_VID_DEV_CAP_FORMAT) {\n        const pjmedia_video_format_info *vfi;\n        pjmedia_video_format_detail *vfd;\n        pjmedia_format *fmt = (pjmedia_format *)pval;\n\n        vfi = pjmedia_get_video_format_info(pjmedia_video_format_mgr_instance(), fmt->id);\n        if (!vfi)\n            return PJMEDIA_EVID_BADFORMAT;\n\n        pjmedia_format_copy(&strm->param.fmt, fmt);\n\n        vfd = pjmedia_format_get_video_format_detail(fmt, PJ_TRUE);\n        pj_memcpy(&strm->vid_size, &vfd->size, sizeof(vfd->size));\n        if (strm->param.disp_size.w == 0 || strm->param.disp_size.h == 0)\n            pj_memcpy(&strm->param.disp_size, &vfd->size, sizeof(vfd->size));\n\n        return PJ_SUCCESS;\n    }\n\n    return PJMEDIA_EVID_INVCAP;\n}\n\n\n/* API: Start stream. */\nstatic pj_status_t fb_stream_start(pjmedia_vid_dev_stream *strm)\n{\n    struct fb_stream *stream = (struct fb_stream*)strm;\n    PJ_UNUSED_ARG(strm);\n\n    PJ_LOG(4, (THIS_FILE, \"Starting FB video stream\"));\n    stream->is_running = PJ_TRUE;\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: Stop stream. */\nstatic pj_status_t fb_stream_stop(pjmedia_vid_dev_stream *strm)\n{\n    struct fb_stream *stream = (struct fb_stream*)strm;\n    PJ_UNUSED_ARG(strm);\n\n    PJ_LOG(4, (THIS_FILE, \"Stopping FB video stream\"));\n    stream->is_running = PJ_FALSE;\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: Destroy stream. */\nstatic pj_status_t fb_stream_destroy(pjmedia_vid_dev_stream *strm)\n{\n    struct fb_stream *stream = (struct fb_stream*)strm;\n\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n\n    fb_stream_stop(strm);\n    pj_pool_release(stream->pool);\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: set callback for handling frames */\npj_status_t\npjmedia_vid_dev_fb_set_callback(pjmedia_vid_dev_stream *strm,\n                                pjmedia_vid_dev_fb_frame_cb cb,\n                                void *user_data)\n{\n    struct fb_stream *stream = (struct fb_stream*)strm;\n\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n    if (stream->is_running)\n        return PJ_EBUSY;\n\n    stream->frame_handler.cb = cb;\n    stream->frame_handler.user_data = user_data;\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_VIDEO_DEV_HAS_FB */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-videodev/null_dev.c",
    "content": "/* $Id: colorbar_dev.c 4158 2012-06-06 09:56:14Z nanang $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia-videodev/videodev_imp.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && PJMEDIA_HAS_VIDEO != 0 && \\\n    defined(PJMEDIA_VIDEO_DEV_HAS_NULL) && \\\n    PJMEDIA_VIDEO_DEV_HAS_NULL != 0\n\n\n#define THIS_FILE\t\t\"null_dev.c\"\n#define DEFAULT_CLOCK_RATE\t90000\n#define DEFAULT_WIDTH\t\t640\n#define DEFAULT_HEIGHT\t\t480\n#define DEFAULT_FPS\t\t5\n\n/* null_ device info */\nstruct null_dev_info\n{\n    pjmedia_vid_dev_info\t info;\n};\n\n/* null_ factory */\nstruct null_factory\n{\n    pjmedia_vid_dev_factory\t base;\n    pj_pool_t\t\t\t*pool;\n    pj_pool_factory\t\t*pf;\n\n    unsigned\t\t\t dev_count;\n    struct null_dev_info\t*dev_info;\n};\n\nstruct null_fmt_info {\n    pjmedia_format_id            fmt_id;        /* Format ID                */\n};\n\n/* Null video source supports */\nstatic struct null_fmt_info null_fmts[] =\n{\n    { PJMEDIA_FORMAT_BGRA },\n};\n\n/* Video stream. */\nstruct null_stream\n{\n    pjmedia_vid_dev_stream\t     base;\t    /**< Base stream\t    */\n    pjmedia_vid_dev_param\t     param;\t    /**< Settings\t    */\n    pj_pool_t\t\t\t    *pool;          /**< Memory pool.       */\n\n    pjmedia_vid_dev_cb\t\t     vid_cb;\t    /**< Stream callback.   */\n    void\t\t\t    *user_data;\t    /**< Application data.  */\n\n    const struct null_fmt_info      *cbfi;\n    const pjmedia_video_format_info *vfi;\n    pjmedia_video_apply_fmt_param    vafp;\n    pj_uint8_t                      *first_line[PJMEDIA_MAX_VIDEO_PLANES];\n    pj_timestamp\t\t     ts;\n    unsigned\t\t\t     ts_inc;\n};\n\n\n/* Prototypes */\nstatic pj_status_t null_factory_init(pjmedia_vid_dev_factory *f);\nstatic pj_status_t null_factory_destroy(pjmedia_vid_dev_factory *f);\nstatic pj_status_t null_factory_refresh(pjmedia_vid_dev_factory *f); \nstatic unsigned    null_factory_get_dev_count(pjmedia_vid_dev_factory *f);\nstatic pj_status_t null_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_vid_dev_info *info);\nstatic pj_status_t null_factory_default_param(pj_pool_t *pool,\n                                              pjmedia_vid_dev_factory *f,\n\t\t\t\t\t      unsigned index,\n\t\t\t\t\t      pjmedia_vid_dev_param *param);\nstatic pj_status_t null_factory_create_stream(\n\t\t\t\t\tpjmedia_vid_dev_factory *f,\n\t\t\t\t\tpjmedia_vid_dev_param *param,\n\t\t\t\t\tconst pjmedia_vid_dev_cb *cb,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tpjmedia_vid_dev_stream **p_vid_strm);\n\nstatic pj_status_t null_stream_get_param(pjmedia_vid_dev_stream *strm,\n\t\t\t\t\t pjmedia_vid_dev_param *param);\nstatic pj_status_t null_stream_get_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t       pjmedia_vid_dev_cap cap,\n\t\t\t\t       void *value);\nstatic pj_status_t null_stream_set_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t       pjmedia_vid_dev_cap cap,\n\t\t\t\t       const void *value);\nstatic pj_status_t null_stream_get_frame(pjmedia_vid_dev_stream *strm,\n                                         pjmedia_frame *frame);\nstatic pj_status_t null_stream_start(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t null_stream_stop(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t null_stream_destroy(pjmedia_vid_dev_stream *strm);\n\n/* Operations */\nstatic pjmedia_vid_dev_factory_op factory_op =\n{\n    &null_factory_init,\n    &null_factory_destroy,\n    &null_factory_get_dev_count,\n    &null_factory_get_dev_info,\n    &null_factory_default_param,\n    &null_factory_create_stream,\n    &null_factory_refresh\n};\n\nstatic pjmedia_vid_dev_stream_op stream_op =\n{\n    &null_stream_get_param,\n    &null_stream_get_cap,\n    &null_stream_set_cap,\n    &null_stream_start,\n    &null_stream_get_frame,\n    NULL,\n    &null_stream_stop,\n    &null_stream_destroy\n};\n\n\n/****************************************************************************\n * Factory operations\n */\n/*\n * Init null_ video driver.\n */\npjmedia_vid_dev_factory* pjmedia_null_factory(pj_pool_factory *pf)\n{\n    struct null_factory *f;\n    pj_pool_t *pool;\n\n    pool = pj_pool_create(pf, \"null video\", 512, 512, NULL);\n    f = PJ_POOL_ZALLOC_T(pool, struct null_factory);\n    f->pf = pf;\n    f->pool = pool;\n    f->base.op = &factory_op;\n\n    return &f->base;\n}\n\n\n/* API: init factory */\nstatic pj_status_t null_factory_init(pjmedia_vid_dev_factory *f)\n{\n    struct null_factory *cf = (struct null_factory*)f;\n    struct null_dev_info *ddi;\n    unsigned i;\n\n    cf->dev_count = 1;\n    cf->dev_info = (struct null_dev_info*)\n \t\t   pj_pool_calloc(cf->pool, cf->dev_count,\n \t\t\t\t  sizeof(struct null_dev_info));\n\n    ddi = &cf->dev_info[0];\n    pj_bzero(ddi, sizeof(*ddi));\n    pj_ansi_strncpy(ddi->info.name, \"Null video device\",\n\t\t    sizeof(ddi->info.name));\n    ddi->info.driver[sizeof(ddi->info.driver)-1] = '\\0';\n    pj_ansi_strncpy(ddi->info.driver, \"Null\", sizeof(ddi->info.driver));\n    ddi->info.driver[sizeof(ddi->info.driver)-1] = '\\0';\n    ddi->info.dir = PJMEDIA_DIR_CAPTURE;\n    ddi->info.has_callback = PJ_FALSE;\n\n    ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;\n    ddi->info.fmt_cnt = sizeof(null_fmts)/sizeof(null_fmts[0]);\n    for (i = 0; i < ddi->info.fmt_cnt; i++) {\n        pjmedia_format *fmt = &ddi->info.fmt[i];\n        pjmedia_format_init_video(fmt, null_fmts[i].fmt_id,\n\t\t\t\t  DEFAULT_WIDTH, DEFAULT_HEIGHT,\n\t\t\t\t  DEFAULT_FPS, 1);\n    }\n\n    PJ_LOG(4, (THIS_FILE, \"Null video src initialized with %d device(s):\", cf->dev_count));\n    for (i = 0; i < cf->dev_count; i++) {\n\tPJ_LOG(4, (THIS_FILE, \"%2d: %s\", i, cf->dev_info[i].info.name));\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: destroy factory */\nstatic pj_status_t null_factory_destroy(pjmedia_vid_dev_factory *f)\n{\n    struct null_factory *cf = (struct null_factory*)f;\n    pj_pool_t *pool = cf->pool;\n\n    cf->pool = NULL;\n    pj_pool_release(pool);\n\n    return PJ_SUCCESS;\n}\n\n/* API: refresh the list of devices */\nstatic pj_status_t null_factory_refresh(pjmedia_vid_dev_factory *f)\n{\n    PJ_UNUSED_ARG(f);\n    return PJ_SUCCESS;\n}\n\n/* API: get number of devices */\nstatic unsigned null_factory_get_dev_count(pjmedia_vid_dev_factory *f)\n{\n    struct null_factory *cf = (struct null_factory*)f;\n    return cf->dev_count;\n}\n\n/* API: get device info */\nstatic pj_status_t null_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_vid_dev_info *info)\n{\n    struct null_factory *cf = (struct null_factory*)f;\n\n    PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);\n\n    pj_memcpy(info, &cf->dev_info[index].info, sizeof(*info));\n\n    return PJ_SUCCESS;\n}\n\n/* API: create default device parameter */\nstatic pj_status_t null_factory_default_param(pj_pool_t *pool,\n                                              pjmedia_vid_dev_factory *f,\n\t\t\t\t\t      unsigned index,\n\t\t\t\t\t      pjmedia_vid_dev_param *param)\n{\n    struct null_factory *cf = (struct null_factory*)f;\n    struct null_dev_info *di = &cf->dev_info[index];\n\n    PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);\n\n    PJ_UNUSED_ARG(pool);\n\n    pj_bzero(param, sizeof(*param));\n    param->dir = PJMEDIA_DIR_CAPTURE;\n    param->cap_id = index;\n    param->rend_id = PJMEDIA_VID_INVALID_DEV;\n    param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;\n    param->clock_rate = DEFAULT_CLOCK_RATE;\n    pj_memcpy(&param->fmt, &di->info.fmt[0], sizeof(param->fmt));\n\n    return PJ_SUCCESS;\n}\n\nstatic const struct null_fmt_info* get_null_fmt_info(pjmedia_format_id id)\n{\n    unsigned i;\n\n    for (i = 0; i < sizeof(null_fmts)/sizeof(null_fmts[0]); i++) {\n        if (null_fmts[i].fmt_id == id)\n            return &null_fmts[i];\n    }\n\n    return NULL;\n}\n\n\n/* API: create stream */\nstatic pj_status_t null_factory_create_stream(\n\t\t\t\t\tpjmedia_vid_dev_factory *f,\n\t\t\t\t\tpjmedia_vid_dev_param *param,\n\t\t\t\t\tconst pjmedia_vid_dev_cb *cb,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tpjmedia_vid_dev_stream **p_vid_strm)\n{\n    struct null_factory *cf = (struct null_factory*)f;\n    pj_pool_t *pool;\n    struct null_stream *strm;\n    const pjmedia_video_format_detail *vfd;\n    const pjmedia_video_format_info *vfi;\n    pjmedia_video_apply_fmt_param vafp;\n    const struct null_fmt_info *cbfi;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);\n    PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&\n\t\t     param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&\n                     param->dir == PJMEDIA_DIR_CAPTURE,\n\t\t     PJ_EINVAL);\n\n    pj_bzero(&vafp, sizeof(vafp));\n\n    vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);\n    vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);\n    cbfi = get_null_fmt_info(param->fmt.id);\n    if (!vfi || !cbfi)\n        return PJMEDIA_EVID_BADFORMAT;\n\n    vafp.size = param->fmt.det.vid.size;\n    if (vfi->apply_fmt(vfi, &vafp) != PJ_SUCCESS)\n        return PJMEDIA_EVID_BADFORMAT;\n\n    /* Create and Initialize stream descriptor */\n    pool = pj_pool_create(cf->pf, \"null-dev\", 512, 512, NULL);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    strm = PJ_POOL_ZALLOC_T(pool, struct null_stream);\n    pj_memcpy(&strm->param, param, sizeof(*param));\n    strm->pool = pool;\n    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));\n    strm->user_data = user_data;\n    strm->vfi = vfi;\n    strm->cbfi = cbfi;\n    pj_memcpy(&strm->vafp, &vafp, sizeof(vafp));\n    strm->ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);\n\n    for (i = 0; i < vfi->plane_cnt; ++i) {\n        strm->first_line[i] = pj_pool_alloc(pool, vafp.strides[i]);\n        pj_memset(strm->first_line[i], 0, vafp.strides[i]);\n    }\n\n    /* Done */\n    strm->base.op = &stream_op;\n    *p_vid_strm = &strm->base;\n\n    return PJ_SUCCESS;\n}\n\n/* API: Get stream info. */\nstatic pj_status_t null_stream_get_param(pjmedia_vid_dev_stream *s,\n\t\t\t\t\t pjmedia_vid_dev_param *pi)\n{\n    struct null_stream *strm = (struct null_stream*)s;\n\n    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);\n\n    pj_memcpy(pi, &strm->param, sizeof(*pi));\n    return PJ_SUCCESS;\n}\n\n/* API: get capability */\nstatic pj_status_t null_stream_get_cap(pjmedia_vid_dev_stream *s,\n\t\t\t\t       pjmedia_vid_dev_cap cap,\n\t\t\t\t       void *pval)\n{\n    struct null_stream *strm = (struct null_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n    return PJMEDIA_EVID_INVCAP;\n}\n\n/* API: set capability */\nstatic pj_status_t null_stream_set_cap(pjmedia_vid_dev_stream *s,\n\t\t\t\t       pjmedia_vid_dev_cap cap,\n\t\t\t\t       const void *pval)\n{\n    struct null_stream *strm = (struct null_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n    return PJMEDIA_EVID_INVCAP;\n}\n\n\n/* API: Get frame from stream */\nstatic pj_status_t null_stream_get_frame(pjmedia_vid_dev_stream *strm,\n                                         pjmedia_frame *frame)\n{\n    struct null_stream *stream = (struct null_stream*)strm;\n    unsigned i;\n    pj_uint8_t *ptr = frame->buf;\n\n    frame->type = PJMEDIA_FRAME_TYPE_VIDEO;\n    frame->bit_info = 0;\n    frame->timestamp = stream->ts;\n    stream->ts.u64 += stream->ts_inc;\n\n    /* paint subsequent lines */\n    for (i=0; i<stream->vfi->plane_cnt; ++i) {\n        pj_uint8_t *plane_end;\n        plane_end = ptr + stream->vafp.plane_bytes[i];\n        while (ptr < plane_end) {\n            pj_memcpy(ptr, stream->first_line[i], stream->vafp.strides[i]);\n            ptr += stream->vafp.strides[i];\n        }\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: Start stream. */\nstatic pj_status_t null_stream_start(pjmedia_vid_dev_stream *strm)\n{\n    struct null_stream *stream = (struct null_stream*)strm;\n\n    PJ_UNUSED_ARG(stream);\n\n    PJ_LOG(4, (THIS_FILE, \"Starting null video stream\"));\n\n    return PJ_SUCCESS;\n}\n\n/* API: Stop stream. */\nstatic pj_status_t null_stream_stop(pjmedia_vid_dev_stream *strm)\n{\n    struct null_stream *stream = (struct null_stream*)strm;\n\n    PJ_UNUSED_ARG(stream);\n\n    PJ_LOG(4, (THIS_FILE, \"Stopping null video stream\"));\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: Destroy stream. */\nstatic pj_status_t null_stream_destroy(pjmedia_vid_dev_stream *strm)\n{\n    struct null_stream *stream = (struct null_stream*)strm;\n\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n\n    null_stream_stop(strm);\n\n    pj_pool_release(stream->pool);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_VIDEO_DEV_HAS_NULL */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-videodev/util.c",
    "content": "/* $Id$ */\n/*\n * Copyright (C) 2014-2015 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n \n#include \"util.h\"\n\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/log.h>\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n#if defined(PJMEDIA_HAS_LIBYUV) && PJMEDIA_HAS_LIBYUV != 0\n    #include  <libyuv.h>\n    #define HAS_ROTATION 1\n#else\n    #define HAS_ROTATION 0\n#endif\n\n#define THIS_FILE\t\t\"vid_util.c\"\n\npj_status_t\npjmedia_vid_dev_conv_create_converter(pjmedia_vid_dev_conv *conv,\n\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t      pjmedia_format *fmt,\n\t\t\t\t      pjmedia_rect_size src_size,\n\t\t\t\t      pjmedia_rect_size dst_size,\n\t\t\t\t      pj_bool_t handle_rotation,\n\t\t\t\t      pj_bool_t maintain_aspect_ratio)\n{\n    pj_status_t status;\n    pjmedia_conversion_param conv_param;\n    const pjmedia_video_format_info *vfi;\t\n\n    pj_assert((src_size.w == dst_size.w || src_size.h == dst_size.h) ||\n              (src_size.w == dst_size.h || src_size.h == dst_size.w));\n              \n    if (conv->conv)\n        return PJ_SUCCESS;\n        \n    if (fmt->id != PJMEDIA_FORMAT_I420 && fmt->id != PJMEDIA_FORMAT_BGRA)\n        return PJ_EINVAL;\n        \n    /* Currently, for BGRA format, device must handle the rotation. */\n    if (fmt->id == PJMEDIA_FORMAT_BGRA && handle_rotation)\n        return PJ_ENOTSUP;\n\n    if (handle_rotation) {\n#if !HAS_ROTATION\n\treturn PJ_ENOTSUP;\n#endif\n    }\n    \n    conv->src_size = src_size;\n    conv->dst_size = dst_size;\n    conv->handle_rotation = handle_rotation;\n    pjmedia_format_copy(&conv->fmt, fmt);\n    pjmedia_format_copy(&conv_param.src, fmt);\n    pjmedia_format_copy(&conv_param.dst, fmt);\n\n    /* If we do the rotation, the conversion's source size must be the same\n     * as the device's original size. Otherwise, frames that require conversion\n     * are the ones of which orientation differ by 90 or 270 degrees from the\n     * destination size.\n     */\n    if (handle_rotation) {\n        conv_param.src.det.vid.size = src_size;\n    } else {\n        conv_param.src.det.vid.size.w = dst_size.h;\n        conv_param.src.det.vid.size.h = dst_size.w;\n    }\n\n    /* Maintaining aspect ratio requires filling the left&right /\n     * top&bottom area with black color.\n     * Currently it is only supported for I420.\n     * TODO: support BGRA as well\n     */\n    if (fmt->id != PJMEDIA_FORMAT_I420)\n        maintain_aspect_ratio = PJ_FALSE;\n\n    /* Calculate the size after rotation.\n     * If aspect ratio doesn't need to be maintained, rot_size is simply equal\n     * to the destination size. Otherwise, we need to fit the rotated frame\n     * to height or to width.\n     */\n    conv->maintain_aspect_ratio = maintain_aspect_ratio;\n    if (maintain_aspect_ratio) {\n        conv->fit_to_h = (dst_size.w >= dst_size.h? PJ_TRUE: PJ_FALSE);\n\tif (conv->fit_to_h) {\t/* Fit to height */\n\t    conv->rot_size.h = dst_size.h;\n\t    conv->rot_size.w = dst_size.h * dst_size.h / dst_size.w;\n\t    /* Make sure the width difference is divisible by four\n\t     * so we can have equal padding left and right.\n\t     */\n\t    conv->rot_size.w += (dst_size.w - conv->rot_size.w) % 4;\n\t    conv->pad = (conv->dst_size.w - conv->rot_size.w) / 2;\n\t} else { \t\t\t/* Fit to width */\n\t    conv->rot_size.w = dst_size.w;\n\t    conv->rot_size.h = dst_size.w * dst_size.w / dst_size.h;\n\t    conv->rot_size.h += (dst_size.h - conv->rot_size.h) % 4;\n\t    conv->pad = (conv->dst_size.h - conv->rot_size.h) / 2;\n\t}\n    } else {\n        conv->rot_size = dst_size;\n    }\n    \n    /* Calculate the size after resizing. */\n    if (handle_rotation) {\n        /* If we do the rotation, conversion is done before rotation. */\n        if (maintain_aspect_ratio) {\n            /* Since aspect ratio is maintained, the long side after\n             * conversion must be the same as before conversion.\n             * For example: 352x288 will be converted to 288x236\n             */\n            pj_size_t long_s  = (conv->rot_size.h > conv->rot_size.w?\n            \t\t\t conv->rot_size.h: conv->rot_size.w);\n            pj_size_t short_s = (conv->rot_size.h > conv->rot_size.w?\n            \t\t\t conv->rot_size.w: conv->rot_size.h);\n            if (src_size.w > src_size.h) {\n                conv->res_size.w = long_s;\n                conv->res_size.h = short_s;\n             } else {\n                conv->res_size.w = short_s;\n                conv->res_size.h = long_s;\n             }\n        } else {\n            /* We don't need to maintain aspect ratio,\n             * so just swap the width and height.\n             * For example: 352x288 will be resized to 288x352\n             */\n            conv->res_size.w = src_size.h;\n            conv->res_size.h = src_size.w;\n        }\n        conv_param.dst.det.vid.size = conv->res_size;\n    } else {\n        conv->res_size = conv->rot_size;\n    \tconv_param.dst.det.vid.size = conv->rot_size;\n    }\n\n    status = pjmedia_converter_create(NULL, pool, &conv_param,\n\t\t\t\t      &conv->conv);\n    if (status != PJ_SUCCESS) {\n\tPJ_LOG(3, (THIS_FILE, \"Error creating converter\"));\n\treturn status;\n    }\n\n    vfi = pjmedia_get_video_format_info(NULL, fmt->id);\n    pj_assert(vfi);\n    \n    conv->wxh = conv->dst_size.w * conv->dst_size.h;\n    conv->src_frame_size = dst_size.w * dst_size.h * vfi->bpp / 8;\n    conv->conv_frame_size = conv->rot_size.w * conv->rot_size.h;\n    conv->conv_frame_size *= vfi->bpp / 8;\n    conv->conv_buf = pj_pool_alloc(pool, conv->src_frame_size);\n    \n    pjmedia_vid_dev_conv_set_rotation(conv, PJMEDIA_ORIENT_NATURAL);\n\n    PJ_LOG(4, (THIS_FILE, \"Orientation converter created: %dx%d to %dx%d, \"\n    \t\t\t  \"maintain aspect ratio=%s\",\n\t\t\t  conv_param.src.det.vid.size.w,\n\t\t\t  conv_param.src.det.vid.size.h,\n\t\t\t  conv_param.dst.det.vid.size.w,\n\t\t\t  conv_param.dst.det.vid.size.h,\n\t\t\t  maintain_aspect_ratio? \"yes\": \"no\"));\n\t\t\t  \n    return PJ_SUCCESS;\n}\n\nvoid pjmedia_vid_dev_conv_set_rotation(pjmedia_vid_dev_conv *conv,\n\t\t\t\t       pjmedia_orient rotation)\n{\n    pjmedia_rect_size new_size = conv->src_size;\n    \n    conv->rotation = rotation;\n    \n    if (rotation == PJMEDIA_ORIENT_ROTATE_90DEG ||\n\trotation == PJMEDIA_ORIENT_ROTATE_270DEG)\n    {\n        new_size.w = conv->src_size.h;\n        new_size.h = conv->src_size.w;\n    }\n    \n    /* Check whether new size (size after rotation) and destination\n     * are both portrait or both landscape. If yes, resize will not\n     * be required in pjmedia_vid_dev_conv_resize_and_rotate() below.\n     * For example, 352x288 frame rotated 270 degrees will fit into\n     * a destination frame of 288x352 (no resize needed).\n     */\n    if ((new_size.w > new_size.h && conv->dst_size.w > conv->dst_size.h) ||\n        (new_size.h > new_size.w && conv->dst_size.h > conv->dst_size.w))\n    {\n        conv->match_src_dst = PJ_TRUE;\n    } else {\n        conv->match_src_dst = PJ_FALSE;\n    }\n}\n\npj_status_t pjmedia_vid_dev_conv_resize_and_rotate(pjmedia_vid_dev_conv *conv,\n\t\t\t\t      \t\t   void *src_buf,\n\t\t\t\t      \t\t   void **result)\n{\n#define swap(a, b) {pj_uint8_t *c = a; a = b; b = c;}\n\n    pj_status_t status;\n    pjmedia_frame src_frame, dst_frame;\n    pjmedia_rect_size src_size = conv->src_size;\n    pj_uint8_t *src = src_buf;\n    pj_uint8_t *dst = conv->conv_buf;    \n\n    pj_assert(src_buf);\n    \n    if (!conv->conv) return PJ_EINVALIDOP;\n    \n    if (!conv->match_src_dst) {\n        /* We need to resize. */\n\tsrc_frame.buf = src;\n\tdst_frame.buf = dst;\n\tsrc_frame.size = conv->src_frame_size;\n\tdst_frame.size = conv->conv_frame_size;\n    \n\tstatus = pjmedia_converter_convert(conv->conv, &src_frame, &dst_frame);\n\tif (status != PJ_SUCCESS) {\n            PJ_LOG(3, (THIS_FILE, \"Failed to convert frame\"));\n            return status;\n        }\n        \n        src_size = conv->res_size;\n        \n        swap(src, dst);\n    }\n    \n    if (conv->handle_rotation && conv->rotation != PJMEDIA_ORIENT_NATURAL) {\n        /* We need to do rotation. */\n    \tif (conv->fmt.id == PJMEDIA_FORMAT_I420) {\n    \t    pjmedia_rect_size dst_size = src_size;\n    \t    pj_size_t p_len = src_size.w * src_size.h;\n    \t    \n\t    if (conv->rotation == PJMEDIA_ORIENT_ROTATE_90DEG ||\n\t\tconv->rotation == PJMEDIA_ORIENT_ROTATE_270DEG)\n\t    {\n\t\tdst_size.w = src_size.h;\n\t\tdst_size.h = src_size.w;\n\t    }\n    \t    \n#if defined(PJMEDIA_HAS_LIBYUV) && PJMEDIA_HAS_LIBYUV != 0\n\t    enum RotationMode mode;\n\t    \n\t    switch (conv->rotation) {\n\t        case PJMEDIA_ORIENT_ROTATE_90DEG:\n\t            mode = kRotate90;\n\t            break;\n\t        case PJMEDIA_ORIENT_ROTATE_180DEG:\n\t            mode = kRotate180;\n\t            break;\n\t        case PJMEDIA_ORIENT_ROTATE_270DEG:\n\t            mode = kRotate270;\n\t            break;\n\t        default:\n\t            mode = kRotate0;\n\t    }\n\n    \t    I420Rotate(src, src_size.w,\n    \t    \t       src+p_len, src_size.w/2,\n    \t    \t       src+p_len+p_len/4, src_size.w/2,\n    \t    \t       dst, dst_size.w,\n    \t    \t       dst+p_len, dst_size.w/2,\n    \t    \t       dst+p_len+p_len/4, dst_size.w/2,\n    \t    \t       src_size.w, src_size.h, mode);\n    \t    \n    \t    swap(src, dst);\n#else\n\t    PJ_UNUSED_ARG(p_len);\n\t    PJ_UNUSED_ARG(dst_size);\n#endif\n    \t}\n    }\n    \n    if (!conv->match_src_dst && conv->maintain_aspect_ratio) {\n\t/* Center the frame and fill the area with black color */    \n        if (conv->fmt.id == PJMEDIA_FORMAT_I420) {\n    \t    unsigned i = 0;\n    \t    pj_uint8_t *pdst = dst;\n    \t    pj_uint8_t *psrc = src;\n            pj_size_t p_len_src = 0, p_len_dst = conv->wxh;\n    \t    int pad = conv->pad;\n\n            pj_bzero(pdst, p_len_dst);\n\n            if (conv->fit_to_h) {\n                /* Fill the left and right with black */\n                for (; i < conv->dst_size.h; ++i) {\n                    pdst += pad;\n                    pj_memcpy(pdst, psrc, conv->rot_size.w);\n                    pdst += conv->rot_size.w;\n                    psrc += conv->rot_size.w;\n                    pdst += pad;\n                }\n            } else {\n                /* Fill the top and bottom with black */\n                p_len_src = conv->rot_size.w * conv->rot_size.h;\n                pj_memcpy(pdst + conv->rot_size.w * pad, psrc, p_len_src);\n                psrc += p_len_src;\n                pdst += p_len_dst;\n            }\n\n\t    /* Fill the U&V components with 0x80 to make it black.\n\t     * Bzero-ing will make the area look green instead.\n\t     */\n\t    pj_memset(pdst, 0x80, p_len_dst/2);\n\t    pad /= 2;\n            if (conv->fit_to_h) {\n\t    \tp_len_src = conv->rot_size.w / 2;\n                for (i = conv->dst_size.h; i > 0; --i) {\n                    pdst += pad;\n                    pj_memcpy(pdst, psrc, p_len_src);\n                    pdst += p_len_src;\n                    psrc += p_len_src;\n                    pdst += pad;\n                }\n            } else {\n                pj_uint8_t *U, *V;\n                pj_size_t gap = conv->rot_size.w * pad / 2;\n\n\t\tp_len_src /= 4;\n                U = pdst;\n                V = U + p_len_dst/4;\n\n                pj_memcpy(U + gap, psrc, p_len_src);\n                psrc += p_len_src;\n                pj_memcpy(V + gap, psrc, p_len_src);\n            }\n            \n            swap(src, dst);\n\t}\n    }\n    \n    *result = src;\n    \n    return PJ_SUCCESS;\n}\n\nvoid pjmedia_vid_dev_conv_destroy_converter(pjmedia_vid_dev_conv *conv)\n{\n    if (conv->conv) {\n        pjmedia_converter_destroy(conv->conv);\n        conv->conv = NULL;\n    }\n}\n\n#endif /* PJMEDIA_HAS_VIDEO */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-videodev/util.h",
    "content": "/* $Id$ */\n/*\n * Copyright (C) 2014-2015 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef __PJMEDIA_VIDEODEV_UTIL_H__\n#define __PJMEDIA_VIDEODEV_UTIL_H__\n\n#include <pjmedia/converter.h>\n#include <pjmedia/format.h>\n#include <pjmedia/types.h>\n\n/*\n * Video device utility functions to resize and rotate video frames.\n */\n\ntypedef struct pjmedia_vid_dev_conv\n{\n    pjmedia_converter\t   *conv;\n    pjmedia_format\t    fmt;\n    pjmedia_rect_size\t    src_size;\n    pjmedia_rect_size\t    dst_size;\n    pjmedia_rect_size\t    res_size;\t\t/* Size after resizing   */\n    pjmedia_orient\t    rotation;\n    pjmedia_rect_size\t    rot_size;\t\t/* Size after rotation   */ \n    \n    void\t\t   *conv_buf;\n    pj_size_t\t\t    src_frame_size;\n    pj_size_t\t\t    conv_frame_size;\n    \n    pj_bool_t\t\t    fit_to_h;\n    pj_bool_t\t\t    handle_rotation;\n    pj_bool_t\t\t    maintain_aspect_ratio;\n    pj_bool_t\t\t    match_src_dst;\n    pj_int32_t\t\t    pad;\n    pj_size_t\t\t    wxh;\n} pjmedia_vid_dev_conv;\n\n/**\n * Create converter.\n * The process: \n * frame --> resize -->        rotate       -->           center\n *                      (if handle_rotation      (if maintain_aspect_ratio\n *                          == PJ_TRUE)                 == PJ_TRUE)\n *\n * handle_rotation will specify whether the converter will need to do the\n * rotation as well. If PJ_FALSE, the video device will handle the rotation\n * and pass the already-rotated frame.\n *\n * maintain_aspect_ratio defines whether aspect ratio should be maintained\n * when rotating the image.\n * If PJ_TRUE, a frame of size w x h will be resized and rotated to\n * a new frame of size new_w x new_h (new_h and new_h have the same\n * aspect ratio as w x h). Then the new frame will be centered-fit into\n * the original frame with black area inserted to fill the gaps.\n * Disabling this setting will only resize the frame of size w x h to h x w,\n * and then rotate it to fit the original size of w x h. It will achieve\n * a slightly faster performance but the resulting image will be stretched.\n * The feature to maintain aspect ratio is only supported for certain formats\n * (currently, only if fmt.id equals to I420).\n */\npj_status_t\npjmedia_vid_dev_conv_create_converter(pjmedia_vid_dev_conv *conv,\n\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t      pjmedia_format *fmt,\n\t\t\t\t      pjmedia_rect_size src_size,\n\t\t\t\t      pjmedia_rect_size dst_size,\n\t\t\t\t      pj_bool_t handle_rotation,\n\t\t\t\t      pj_bool_t maintain_aspect_ratio);\n\n/* Set rotation */\nvoid pjmedia_vid_dev_conv_set_rotation(pjmedia_vid_dev_conv *conv,\n\t\t\t\t       pjmedia_orient rotation);\n\n/* Resize the buffer and rotate it, if necessary */\npj_status_t pjmedia_vid_dev_conv_resize_and_rotate(pjmedia_vid_dev_conv *conv,\n\t\t\t\t      \t\t    void *src_buf,\n\t\t\t\t      \t\t    void **result);\n\n/* Destroy converter */\nvoid pjmedia_vid_dev_conv_destroy_converter(pjmedia_vid_dev_conv *conv);\n\n#endif    /* __PJMEDIA_VIDEODEV_UTIL_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-videodev/v4l2_dev.c",
    "content": "/* $Id: v4l2_dev.c 4310 2012-12-19 05:38:28Z nanang $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjmedia-videodev/videodev_imp.h>\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/file_access.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/rand.h>\n\n#if defined(PJMEDIA_HAS_VIDEO) && PJMEDIA_HAS_VIDEO != 0 && \\\n    defined(PJMEDIA_VIDEO_DEV_HAS_V4L2) && PJMEDIA_VIDEO_DEV_HAS_V4L2 != 0\n\n#include <linux/videodev2.h>\n#include <libv4l2.h>\n#include <fcntl.h>\n#include <errno.h>\n#include <sys/mman.h>\n\n#define THIS_FILE\t\t\"v4l2_dev.c\"\n#define DRIVER_NAME\t\t\"v4l2\"\n#define V4L2_MAX_DEVS\t\t4\n#define DEFAULT_WIDTH\t\t640\n#define DEFAULT_HEIGHT\t\t480\n#define DEFAULT_FPS\t\t25\n#define DEFAULT_CLOCK_RATE\t90000\n#define INVALID_FD\t\t-1\n#define BUFFER_CNT\t\t2\n#define MAX_IOCTL_RETRY\t\t20\n\n\n/* mapping between pjmedia_fmt_id and v4l2 pixel format */\ntypedef struct vid4lin_fmt_map\n{\n    pj_uint32_t pjmedia_fmt_id;\n    pj_uint32_t\tv4l2_fmt_id;\n} vid4lin_fmt_map;\n\n/* I/O type being used */\nenum vid4lin_io_type\n{\n    IO_TYPE_NONE,\n    IO_TYPE_READ,\n    IO_TYPE_MMAP,\n    IO_TYPE_MMAP_USER\n};\n\n/* descriptor for each mmap-ed buffer */\ntypedef struct vid4lin_buffer\n{\n    void   *start;\n    size_t  length;\n} vid4lin_buffer;\n\n/* v4l2 device info */\ntypedef struct vid4lin_dev_info\n{\n    pjmedia_vid_dev_info\t info;\n    char\t\t\t dev_name[32];\n    struct v4l2_capability \t v4l2_cap;\n} vid4lin_dev_info;\n\n/* v4l2 factory */\ntypedef struct vid4lin_factory\n{\n    pjmedia_vid_dev_factory\t base;\n    pj_pool_t\t\t\t*pool;\n    pj_pool_t\t\t\t*dev_pool;\n    pj_pool_factory\t\t*pf;\n\n    unsigned\t\t\t dev_count;\n    vid4lin_dev_info\t\t*dev_info;\n} vid4lin_factory;\n\n/* Video stream. */\ntypedef struct vid4lin_stream\n{\n    pjmedia_vid_dev_stream\t base;\t\t/**< Base stream\t*/\n    pjmedia_vid_dev_param\t param;\t\t/**< Settings\t\t*/\n    pj_pool_t           \t*pool;\t\t/**< Memory pool.\t*/\n\n    int\t\t\t \t fd;\t\t/**< Video fd.\t\t*/\n    char\t\t\t name[64];\t/**< Name for log\t*/\n    enum vid4lin_io_type\t io_type;\t/**< I/O method.\t*/\n    unsigned\t\t\t buf_cnt;\t/**< MMap buf cnt.  \t*/\n    vid4lin_buffer\t\t*buffers;\t/**< MMap buffers.  \t*/\n    pj_time_val\t\t\t start_time;\t/**< Time when started\t*/\n\n    pjmedia_vid_dev_cb       \t vid_cb;\t/**< Stream callback  \t*/\n    void                \t*user_data;\t/**< Application data \t*/\n} vid4lin_stream;\n\n/* Use this to convert between pjmedia_format_id and V4L2 fourcc */\nstatic vid4lin_fmt_map v4l2_fmt_maps[] =\n{\n    { PJMEDIA_FORMAT_RGB24,\tV4L2_PIX_FMT_BGR24 },\n    { PJMEDIA_FORMAT_RGBA,\tV4L2_PIX_FMT_BGR32 },\n    { PJMEDIA_FORMAT_RGB32,\tV4L2_PIX_FMT_BGR32 },\n    { PJMEDIA_FORMAT_AYUV,\tV4L2_PIX_FMT_YUV32 },\n    { PJMEDIA_FORMAT_YUY2,\tV4L2_PIX_FMT_YUYV },\n    { PJMEDIA_FORMAT_UYVY,\tV4L2_PIX_FMT_UYVY }\n};\n\n/* Prototypes */\nstatic pj_status_t vid4lin_factory_init(pjmedia_vid_dev_factory *f);\nstatic pj_status_t vid4lin_factory_destroy(pjmedia_vid_dev_factory *f);\nstatic pj_status_t vid4lin_factory_refresh(pjmedia_vid_dev_factory *f);\nstatic unsigned    vid4lin_factory_get_dev_count(pjmedia_vid_dev_factory *f);\nstatic pj_status_t vid4lin_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t        unsigned index,\n\t\t\t\t\t        pjmedia_vid_dev_info *info);\nstatic pj_status_t vid4lin_factory_default_param(pj_pool_t *pool,\n                                                 pjmedia_vid_dev_factory *f,\n\t\t\t\t\t         unsigned index,\n\t\t\t\t\t         pjmedia_vid_dev_param *param);\nstatic pj_status_t vid4lin_factory_create_stream(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t\t pjmedia_vid_dev_param *prm,\n\t\t\t\t\t         const pjmedia_vid_dev_cb *cb,\n\t\t\t\t\t         void *user_data,\n\t\t\t\t\t         pjmedia_vid_dev_stream **p);\n\nstatic pj_status_t vid4lin_stream_get_param(pjmedia_vid_dev_stream *strm,\n\t\t\t\t\t    pjmedia_vid_dev_param *param);\nstatic pj_status_t vid4lin_stream_get_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t          pjmedia_vid_dev_cap cap,\n\t\t\t\t          void *value);\nstatic pj_status_t vid4lin_stream_set_cap(pjmedia_vid_dev_stream *strm,\n\t\t\t\t          pjmedia_vid_dev_cap cap,\n\t\t\t\t          const void *value);\nstatic pj_status_t vid4lin_stream_get_frame(pjmedia_vid_dev_stream *strm,\n                                            pjmedia_frame *frame);\nstatic pj_status_t vid4lin_stream_start(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t vid4lin_stream_stop(pjmedia_vid_dev_stream *strm);\nstatic pj_status_t vid4lin_stream_destroy(pjmedia_vid_dev_stream *strm);\n\n/* Operations */\nstatic pjmedia_vid_dev_factory_op factory_op =\n{\n    &vid4lin_factory_init,\n    &vid4lin_factory_destroy,\n    &vid4lin_factory_get_dev_count,\n    &vid4lin_factory_get_dev_info,\n    &vid4lin_factory_default_param,\n    &vid4lin_factory_create_stream,\n    &vid4lin_factory_refresh\n};\n\nstatic pjmedia_vid_dev_stream_op stream_op =\n{\n    &vid4lin_stream_get_param,\n    &vid4lin_stream_get_cap,\n    &vid4lin_stream_set_cap,\n    &vid4lin_stream_start,\n    &vid4lin_stream_get_frame,\n    NULL,\n    &vid4lin_stream_stop,\n    &vid4lin_stream_destroy\n};\n\n\n/****************************************************************************\n * Factory operations\n */\n/*\n * Factory creation function.\n */\npjmedia_vid_dev_factory* pjmedia_v4l2_factory(pj_pool_factory *pf)\n{\n    vid4lin_factory *f;\n    pj_pool_t *pool;\n\n    pool = pj_pool_create(pf, DRIVER_NAME, 512, 512, NULL);\n    f = PJ_POOL_ZALLOC_T(pool, vid4lin_factory);\n    f->pf = pf;\n    f->pool = pool;\n    f->base.op = &factory_op;\n\n    return &f->base;\n}\n\n/* util: ioctl that tries harder. */\nstatic pj_status_t xioctl(int fh, int request, void *arg)\n{\n    enum { RETRY = MAX_IOCTL_RETRY };\n    int r, c=0;\n\n    do {\n\tr = v4l2_ioctl(fh, request, arg);\n    } while (r==-1 && c++<RETRY && ((errno==EINTR) || (errno==EAGAIN)));\n\n    return (r == -1) ? pj_get_os_error() : PJ_SUCCESS;\n}\n\nstatic vid4lin_fmt_map* get_v4l2_format_info(pjmedia_format_id id)\n{\n    unsigned i;\n\n    for (i = 0; i < PJ_ARRAY_SIZE(v4l2_fmt_maps); i++) {\n        if (v4l2_fmt_maps[i].pjmedia_fmt_id == id)\n            return &v4l2_fmt_maps[i];\n    }\n\n    return NULL;\n}\n\n/* Get the supported size */\nstatic void v4l2_get_supported_size(int fd,\n\t\t\t\t    pj_uint32_t fmt_id,\n\t\t\t\t    pjmedia_vid_dev_info *info)\n{\n    int i=0;\n    pjmedia_rect_size v4l_sizes[] =\n    {\n\t /* Some webcam doesn't work well using size below 320x240 */\n         /*{ 128, 96 },  { 176, 144 },*/ { 320, 240 },   { 352, 240 },\n         { 352, 288 },   { 352, 480 },   { 352, 576 },   { 640, 480 },\n         { 704, 480 },   { 720, 480 },   { 704, 576 },   { 720, 576 },\n         { 800, 600 },   { 1024, 768 },  { 1280, 720 },  { 1280, 960 },\n         { 1280, 1024 }, { 1408, 960 },  { 1408, 1152 }, { 1600, 1200 },\n         { 1920, 1080 }/*, { 1920, 1088 }, { 2048, 1024 }, { 2048, 1080 },\n         { 2048, 1088 }, { 2048, 1536 }, { 2560, 1920 }, { 3616, 1536 },\n         { 3672, 1536 }, { 3680, 1536 }, { 3840, 2160 }, { 4096, 2048 },\n         { 4096, 2160 }, { 4096, 2304 }*/\n    };\n\n    const vid4lin_fmt_map *fmt_map = get_v4l2_format_info(fmt_id);\n    if (fmt_map == NULL)\n\treturn;\n\n    for (;i<PJ_ARRAY_SIZE(v4l_sizes) &&\n          info->fmt_cnt<PJMEDIA_VID_DEV_INFO_FMT_CNT;\n         i++)\n    {\n\tstruct v4l2_format v4l2_fmt;\n\tpj_status_t status;\n\n\tpj_bzero(&v4l2_fmt, sizeof(v4l2_fmt));\n\tv4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\n\tv4l2_fmt.fmt.pix.width       = v4l_sizes[i].w;\n\tv4l2_fmt.fmt.pix.height      = v4l_sizes[i].h;\n\tv4l2_fmt.fmt.pix.pixelformat = fmt_map->v4l2_fmt_id;\n\tv4l2_fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;\n\tstatus = xioctl(fd, VIDIOC_TRY_FMT, &v4l2_fmt);\n\tif (status != PJ_SUCCESS ||\n\t    v4l2_fmt.fmt.pix.pixelformat != fmt_map->v4l2_fmt_id ||\n\t    v4l2_fmt.fmt.pix.width != v4l_sizes[i].w ||\n\t    v4l2_fmt.fmt.pix.height != v4l_sizes[i].h)\n\t{\n\t    continue;\n\t}\n\n\tpjmedia_format_init_video(&info->fmt[info->fmt_cnt++],\n\t\t\t\t  fmt_id,\n\t\t\t\t  v4l_sizes[i].w,\n\t\t\t\t  v4l_sizes[i].h,\n\t\t\t\t  DEFAULT_FPS, 1);\n    }\n}\n\n/* Scan V4L2 devices */\nstatic pj_status_t v4l2_scan_devs(vid4lin_factory *f)\n{\n    vid4lin_dev_info vdi[V4L2_MAX_DEVS];\n    char dev_name[32];\n    unsigned i, old_count;\n    pj_status_t status;\n\n    if (f->dev_pool) {\n        pj_pool_release(f->dev_pool);\n        f->dev_pool = NULL;\n    }\n\n    pj_bzero(vdi, sizeof(vdi));\n    old_count = f->dev_count;\n    f->dev_count = 0;\n    f->dev_pool = pj_pool_create(f->pf, DRIVER_NAME, 500, 500, NULL);\n\n    for (i=0; i<V4L2_MAX_DEVS && f->dev_count < V4L2_MAX_DEVS; ++i) {\n\tint fd;\n\tvid4lin_dev_info *pdi;\n\tpj_uint32_t fmt_cap[8];\n\tint j, fmt_cnt=0;\n\n\tpdi = &vdi[f->dev_count];\n\n\tsnprintf(dev_name, sizeof(dev_name), \"/dev/video%d\", i);\n\tif (!pj_file_exists(dev_name))\n\t    continue;\n\n\tfd = v4l2_open(dev_name, O_RDWR, 0);\n\tif (fd == -1)\n\t    continue;\n\n\tstatus = xioctl(fd, VIDIOC_QUERYCAP, &pdi->v4l2_cap);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(THIS_FILE, status, \"Error querying %s\", dev_name));\n\t    v4l2_close(fd);\n\t    continue;\n\t}\n\n\tif ((pdi->v4l2_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {\n\t    v4l2_close(fd);\n\t    continue;\n\t}\n\n\tPJ_LOG(5,(THIS_FILE, \"Found capture device %s\", pdi->v4l2_cap.card));\n\tPJ_LOG(5,(THIS_FILE, \"  Enumerating formats:\"));\n\tfor (j=0; fmt_cnt<PJ_ARRAY_SIZE(fmt_cap); ++j) {\n\t    struct v4l2_fmtdesc fdesc;\n\t    unsigned k;\n\n\t    pj_bzero(&fdesc, sizeof(fdesc));\n\t    fdesc.index = j;\n\t    fdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\n\n\t    status = xioctl(fd, VIDIOC_ENUM_FMT, &fdesc);\n\t    if (status != PJ_SUCCESS)\n\t\tbreak;\n\n\t    for (k=0; k<PJ_ARRAY_SIZE(v4l2_fmt_maps); ++k) {\n\t\tif (v4l2_fmt_maps[k].v4l2_fmt_id == fdesc.pixelformat) {\n\t\t    fmt_cap[fmt_cnt++] = v4l2_fmt_maps[k].pjmedia_fmt_id;\n\t\t    PJ_LOG(5,(THIS_FILE, \"   Supported: %s\",\n\t\t\t      fdesc.description));\n\t\t    break;\n\t\t}\n\t    }\n\t    if (k==PJ_ARRAY_SIZE(v4l2_fmt_maps)) {\n\t\tPJ_LOG(5,(THIS_FILE, \"   Unsupported: %s\", fdesc.description));\n\t    }\n\t}\n\n\tif (fmt_cnt==0) {\n\t    PJ_LOG(5,(THIS_FILE, \"    Found no common format\"));\n\t    v4l2_close(fd);\n\t    continue;\n\t}\n\n\tstrncpy(pdi->dev_name, dev_name, sizeof(pdi->dev_name));\n\tpdi->dev_name[sizeof(pdi->dev_name)-1] = '\\0';\n\tstrncpy(pdi->info.name, (char*)pdi->v4l2_cap.card,\n\t\tsizeof(pdi->info.name));\n\tpdi->info.name[sizeof(pdi->info.name)-1] = '\\0';\n\tstrncpy(pdi->info.driver, DRIVER_NAME, sizeof(pdi->info.driver));\n\tpdi->info.driver[sizeof(pdi->info.driver)-1] = '\\0';\n\tpdi->info.dir = PJMEDIA_DIR_CAPTURE;\n\tpdi->info.has_callback = PJ_FALSE;\n\tpdi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;\n\n\tfor (j=0; j<fmt_cnt; ++j) {\n\t    v4l2_get_supported_size(fd, fmt_cap[j], &pdi->info);\n\t}\n\n\tv4l2_close(fd);\n\n\tif (j < fmt_cnt)\n\t    continue;\n\n\tf->dev_count++;\n    }\n\n    if (f->dev_count == 0)\n\treturn PJ_SUCCESS;\n\n    if (f->dev_count > old_count || f->dev_info == NULL) {\n\tf->dev_info = (vid4lin_dev_info*)\n\t\t      pj_pool_calloc(f->dev_pool,\n\t\t\t\t     f->dev_count,\n\t\t\t\t     sizeof(vid4lin_dev_info));\n    }\n    pj_memcpy(f->dev_info, vdi, f->dev_count * sizeof(vid4lin_dev_info));\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: init factory */\nstatic pj_status_t vid4lin_factory_init(pjmedia_vid_dev_factory *f)\n{\n    return vid4lin_factory_refresh(f);\n}\n\n/* API: destroy factory */\nstatic pj_status_t vid4lin_factory_destroy(pjmedia_vid_dev_factory *f)\n{\n    vid4lin_factory *cf = (vid4lin_factory*)f;\n    pj_pool_t *pool = cf->pool;\n\n    if (cf->dev_pool)\n        pj_pool_release(cf->dev_pool);\n    if (cf->pool) {\n\tcf->pool = NULL;\n\tpj_pool_release(pool);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* API: refresh the list of devices */\nstatic pj_status_t vid4lin_factory_refresh(pjmedia_vid_dev_factory *f)\n{\n    vid4lin_factory *cf = (vid4lin_factory*)f;\n    pj_status_t status;\n\n    status = v4l2_scan_devs(cf);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    PJ_LOG(4, (THIS_FILE, \"Video4Linux2 has %d devices\",\n\t       cf->dev_count));\n\n    return PJ_SUCCESS;\n}\n\n/* API: get number of devices */\nstatic unsigned vid4lin_factory_get_dev_count(pjmedia_vid_dev_factory *f)\n{\n    vid4lin_factory *cf = (vid4lin_factory*)f;\n    return cf->dev_count;\n}\n\n/* API: get device info */\nstatic pj_status_t vid4lin_factory_get_dev_info(pjmedia_vid_dev_factory *f,\n\t\t\t\t\t     unsigned index,\n\t\t\t\t\t     pjmedia_vid_dev_info *info)\n{\n    vid4lin_factory *cf = (vid4lin_factory*)f;\n\n    PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);\n\n    pj_memcpy(info, &cf->dev_info[index].info, sizeof(*info));\n\n    return PJ_SUCCESS;\n}\n\n/* API: create default device parameter */\nstatic pj_status_t vid4lin_factory_default_param(pj_pool_t *pool,\n                                                 pjmedia_vid_dev_factory *f,\n                                                 unsigned index,\n                                                 pjmedia_vid_dev_param *param)\n{\n    vid4lin_factory *cf = (vid4lin_factory*)f;\n\n    PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);\n\n    pj_bzero(param, sizeof(*param));\n    param->dir = PJMEDIA_DIR_CAPTURE;\n    param->cap_id = index;\n    param->rend_id = PJMEDIA_VID_INVALID_DEV;\n    param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;\n    param->clock_rate = DEFAULT_CLOCK_RATE;\n    pjmedia_format_copy(&param->fmt, &cf->dev_info[index].info.fmt[0]);\n\n    return PJ_SUCCESS;\n}\n\n/* util: setup format */\nstatic pj_status_t vid4lin_stream_init_fmt(vid4lin_stream *stream,\n\t\t\t\t\tconst pjmedia_vid_dev_param *param,\n\t\t\t\t\tpj_uint32_t pix_fmt)\n{\n    pjmedia_video_format_detail *vfd;\n    struct v4l2_format v4l2_fmt;\n    pj_status_t status;\n\n    vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);\n    if (vfd == NULL)\n\treturn PJMEDIA_EVID_BADFORMAT;\n\n    pj_bzero(&v4l2_fmt, sizeof(v4l2_fmt));\n    v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\n    v4l2_fmt.fmt.pix.width       = vfd->size.w;\n    v4l2_fmt.fmt.pix.height      = vfd->size.h;\n    v4l2_fmt.fmt.pix.pixelformat = pix_fmt;\n    v4l2_fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;\n    status = xioctl(stream->fd, VIDIOC_S_FMT, &v4l2_fmt);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (v4l2_fmt.fmt.pix.pixelformat != pix_fmt) {\n\tstatus = PJMEDIA_EVID_BADFORMAT;\n\treturn status;\n    }\n\n    if ((v4l2_fmt.fmt.pix.width != vfd->size.w) ||\n\t(v4l2_fmt.fmt.pix.height != vfd->size.h))\n    {\n\t/* Size has changed */\n\tvfd->size.w = v4l2_fmt.fmt.pix.width;\n\tvfd->size.h = v4l2_fmt.fmt.pix.height;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* Util: initiate v4l2 streaming via mmap */\nstatic pj_status_t vid4lin_stream_init_streaming(vid4lin_stream *stream)\n{\n    struct v4l2_requestbuffers req;\n    unsigned i;\n    pj_status_t status;\n\n    pj_bzero(&req, sizeof(req));\n    req.count = BUFFER_CNT;\n    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\n    req.memory = V4L2_MEMORY_MMAP;\n    status = xioctl(stream->fd, VIDIOC_REQBUFS, &req);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    stream->buffers = pj_pool_calloc(stream->pool, req.count,\n\t\t\t\t     sizeof(*stream->buffers));\n    stream->buf_cnt = 0;\n\n    for (i = 0; i < req.count; ++i) {\n\tstruct v4l2_buffer buf;\n\n\tpj_bzero(&buf, sizeof(buf));\n\n\tbuf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;\n\tbuf.memory      = V4L2_MEMORY_MMAP;\n\tbuf.index       = i;\n\n\tstatus = xioctl(stream->fd, VIDIOC_QUERYBUF, &buf);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n\tstream->buffers[i].length = buf.length;\n\tstream->buffers[i].start = v4l2_mmap(NULL, buf.length,\n\t\t\t\t\t     PROT_READ | PROT_WRITE,\n\t\t\t\t\t     MAP_SHARED, stream->fd,\n\t\t\t\t\t     buf.m.offset);\n\n\tif (MAP_FAILED == stream->buffers[i].start) {\n\t    status = pj_get_os_error();\n\t    goto on_error;\n\t}\n\n\tstream->buf_cnt++;\n    }\n\n    PJ_LOG(5,(THIS_FILE, \"  mmap streaming initialized\"));\n\n    stream->io_type = IO_TYPE_MMAP;\n    return PJ_SUCCESS;\n\non_error:\n    return status;\n}\n\n/* init streaming with user pointer */\nstatic pj_status_t vid4lin_stream_init_streaming_user(vid4lin_stream *stream)\n{\n    return PJ_ENOTSUP;\n}\n\n/* init streaming with read() */\nstatic pj_status_t vid4lin_stream_init_read_write(vid4lin_stream *stream)\n{\n    return PJ_ENOTSUP;\n}\n\n/* API: create stream */\nstatic pj_status_t vid4lin_factory_create_stream(pjmedia_vid_dev_factory *f,\n\t\t\t\t      pjmedia_vid_dev_param *param,\n\t\t\t\t      const pjmedia_vid_dev_cb *cb,\n\t\t\t\t      void *user_data,\n\t\t\t\t      pjmedia_vid_dev_stream **p_vid_strm)\n{\n    vid4lin_factory *cf = (vid4lin_factory*)f;\n    pj_pool_t *pool;\n    vid4lin_stream *stream;\n    vid4lin_dev_info *vdi;\n    const vid4lin_fmt_map *fmt_map;\n    const pjmedia_video_format_info *fmt_info;\n    pjmedia_video_format_detail *vfd;\n    pj_status_t status = PJ_SUCCESS;\n\n\n    PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);\n    PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&\n\t\t     param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&\n                     param->dir == PJMEDIA_DIR_CAPTURE,\n\t\t     PJ_EINVAL);\n    PJ_ASSERT_RETURN(param->cap_id >= 0 && param->cap_id < cf->dev_count,\n\t\t     PJMEDIA_EVID_INVDEV);\n\n    fmt_info = pjmedia_get_video_format_info(NULL, param->fmt.id);\n    if (!fmt_info || (fmt_map=get_v4l2_format_info(param->fmt.id))==NULL)\n        return PJMEDIA_EVID_BADFORMAT;\n\n    vdi = &cf->dev_info[param->cap_id];\n    vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);\n    PJ_UNUSED_ARG(vfd); /* Unused for now */\n\n    /* Create and Initialize stream descriptor */\n    pool = pj_pool_create(cf->pf, vdi->info.name, 512, 512, NULL);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    stream = PJ_POOL_ZALLOC_T(pool, vid4lin_stream);\n    pj_memcpy(&stream->param, param, sizeof(*param));\n    stream->pool = pool;\n    pj_memcpy(&stream->vid_cb, cb, sizeof(*cb));\n    strncpy(stream->name, vdi->info.name, sizeof(stream->name));\n    stream->name[sizeof(stream->name)-1] = '\\0';\n    stream->user_data = user_data;\n    stream->fd = INVALID_FD;\n\n    stream->fd = v4l2_open(vdi->dev_name, O_RDWR, 0);\n    if (stream->fd < 0)\n\tgoto on_error;\n\n    status = vid4lin_stream_init_fmt(stream, param, fmt_map->v4l2_fmt_id);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    if (vdi->v4l2_cap.capabilities & V4L2_CAP_STREAMING)\n\tstatus = vid4lin_stream_init_streaming(stream);\n\n    if (status!=PJ_SUCCESS && vdi->v4l2_cap.capabilities & V4L2_CAP_STREAMING)\n\tstatus = vid4lin_stream_init_streaming_user(stream);\n\n    if (status!=PJ_SUCCESS && vdi->v4l2_cap.capabilities & V4L2_CAP_READWRITE)\n\tstatus = vid4lin_stream_init_read_write(stream);\n\n    if (status != PJ_SUCCESS) {\n\tPJ_LOG(1,(THIS_FILE, \"Error: unable to initiate I/O on %s\",\n\t\t  stream->name));\n\tgoto on_error;\n    }\n\n    /* Done */\n    stream->base.op = &stream_op;\n    *p_vid_strm = &stream->base;\n\n    return PJ_SUCCESS;\n\non_error:\n    if (status == PJ_SUCCESS)\n\tstatus = PJ_RETURN_OS_ERROR(errno);\n\n    vid4lin_stream_destroy(&stream->base);\n    return status;\n}\n\n/* API: Get stream info. */\nstatic pj_status_t vid4lin_stream_get_param(pjmedia_vid_dev_stream *s,\n\t\t\t\t\t    pjmedia_vid_dev_param *pi)\n{\n    vid4lin_stream *strm = (vid4lin_stream*)s;\n\n    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);\n\n    pj_memcpy(pi, &strm->param, sizeof(*pi));\n\n    return PJ_SUCCESS;\n}\n\n/* API: get capability */\nstatic pj_status_t vid4lin_stream_get_cap(pjmedia_vid_dev_stream *s,\n                                          pjmedia_vid_dev_cap cap,\n                                          void *pval)\n{\n    vid4lin_stream *strm = (vid4lin_stream*)s;\n\n    PJ_UNUSED_ARG(strm);\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)\n    {\n        return PJMEDIA_EVID_INVCAP;\n//\treturn PJ_SUCCESS;\n    } else {\n\treturn PJMEDIA_EVID_INVCAP;\n    }\n}\n\n/* API: set capability */\nstatic pj_status_t vid4lin_stream_set_cap(pjmedia_vid_dev_stream *s,\n                                          pjmedia_vid_dev_cap cap,\n                                          const void *pval)\n{\n    vid4lin_stream *strm = (vid4lin_stream*)s;\n\n\n    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);\n\n    /*\n    if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)\n    {\n\treturn PJ_SUCCESS;\n    }\n    */\n    PJ_UNUSED_ARG(strm);\n    PJ_UNUSED_ARG(cap);\n    PJ_UNUSED_ARG(pval);\n\n    return PJMEDIA_EVID_INVCAP;\n}\n\n/* get frame from mmap */\nstatic pj_status_t vid4lin_stream_get_frame_mmap(vid4lin_stream *stream,\n                                                 pjmedia_frame *frame)\n{\n    struct v4l2_buffer buf;\n    pj_time_val time;\n    pj_status_t status = PJ_SUCCESS;\n    unsigned tmp_idx;\n\n    pj_bzero(&buf, sizeof(buf));\n    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\n    buf.memory = V4L2_MEMORY_MMAP;\n    status = xioctl(stream->fd, VIDIOC_DQBUF, &buf);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (frame->size < buf.bytesused) {\n\t/* supplied buffer is too small */\n\tpj_assert(!\"frame buffer is too small for v4l2\");\n\tstatus = PJ_ETOOSMALL;\n\tgoto on_return;\n    }\n\n    time.sec = buf.timestamp.tv_sec;\n    time.msec = buf.timestamp.tv_usec / 1000;\n    PJ_TIME_VAL_SUB(time, stream->start_time);\n\n    frame->type = PJMEDIA_FRAME_TYPE_VIDEO;\n    frame->bit_info = 0;\n    frame->size = buf.bytesused;\n    frame->timestamp.u64 = PJ_UINT64(1) * PJ_TIME_VAL_MSEC(time) *\n\t\t\t   stream->param.clock_rate / PJ_UINT64(1000);\n    pj_memcpy(frame->buf, stream->buffers[buf.index].start, buf.bytesused);\n\non_return:\n    tmp_idx = buf.index;\n    pj_bzero(&buf, sizeof(buf));\n    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\n    buf.memory = V4L2_MEMORY_MMAP;\n    buf.index = tmp_idx;\n    xioctl(stream->fd, VIDIOC_QBUF, &buf);\n\n    return status;\n}\n\n/* API: Get frame from stream */\nstatic pj_status_t vid4lin_stream_get_frame(pjmedia_vid_dev_stream *strm,\n                                            pjmedia_frame *frame)\n{\n    vid4lin_stream *stream = (vid4lin_stream*)strm;\n\n    if (stream->io_type == IO_TYPE_MMAP)\n\treturn vid4lin_stream_get_frame_mmap(stream, frame);\n    else {\n\tpj_assert(!\"Unsupported i/o type\");\n\treturn PJ_EINVALIDOP;\n    }\n}\n\n/* API: Start stream. */\nstatic pj_status_t vid4lin_stream_start(pjmedia_vid_dev_stream *strm)\n{\n    vid4lin_stream *stream = (vid4lin_stream*)strm;\n    struct v4l2_buffer buf;\n    enum v4l2_buf_type type;\n    unsigned i;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(stream->fd != -1, PJ_EINVALIDOP);\n\n    PJ_LOG(4, (THIS_FILE, \"Starting v4l2 video stream %s\", stream->name));\n\n    pj_gettimeofday(&stream->start_time);\n\n    for (i = 0; i < stream->buf_cnt; ++i) {\n\tpj_bzero(&buf, sizeof(buf));\n\tbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\n\tbuf.memory = V4L2_MEMORY_MMAP;\n\tbuf.index = i;\n\tstatus = xioctl(stream->fd, VIDIOC_QBUF, &buf);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n    }\n    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\n\n    status = xioctl(stream->fd, VIDIOC_STREAMON, &type);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    return PJ_SUCCESS;\n\non_error:\n    if (i > 0) {\n\t/* Dequeue already enqueued buffers. Can we do this while streaming\n\t * is not started?\n\t */\n\tunsigned n = i;\n\tfor (i=0; i<n; ++i) {\n\t    pj_bzero(&buf, sizeof(buf));\n\t    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\n\t    buf.memory = V4L2_MEMORY_MMAP;\n\t    xioctl(stream->fd, VIDIOC_DQBUF, &buf);\n\t}\n    }\n    return status;\n}\n\n/* API: Stop stream. */\nstatic pj_status_t vid4lin_stream_stop(pjmedia_vid_dev_stream *strm)\n{\n    vid4lin_stream *stream = (vid4lin_stream*)strm;\n    enum v4l2_buf_type type;\n    pj_status_t status;\n\n    if (stream->fd < 0)\n\treturn PJ_SUCCESS;\n\n    PJ_LOG(4, (THIS_FILE, \"Stopping v4l2 video stream %s\", stream->name));\n\n    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\n    status = xioctl(stream->fd, VIDIOC_STREAMOFF, &type);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return PJ_SUCCESS;\n}\n\n\n/* API: Destroy stream. */\nstatic pj_status_t vid4lin_stream_destroy(pjmedia_vid_dev_stream *strm)\n{\n    vid4lin_stream *stream = (vid4lin_stream*)strm;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);\n\n    vid4lin_stream_stop(strm);\n\n    PJ_LOG(4, (THIS_FILE, \"Destroying v4l2 video stream %s\", stream->name));\n\n    for (i=0; i<stream->buf_cnt; ++i) {\n\tif (stream->buffers[i].start != MAP_FAILED) {\n\t    v4l2_munmap(stream->buffers[i].start, stream->buffers[i].length);\n\t    stream->buffers[i].start = MAP_FAILED;\n\t}\n    }\n\n    if (stream->fd >= 0) {\n\tv4l2_close(stream->fd);\n\tstream->fd = -1;\n    }\n    pj_pool_release(stream->pool);\n\n    return PJ_SUCCESS;\n}\n\n#endif\t/* PJMEDIA_VIDEO_DEV_HAS_V4L2 */\n"
  },
  {
    "path": "deps/pjsip/pjmedia/src/pjmedia-videodev/videodev.c",
    "content": "/* $Id: videodev.c 4016 2012-04-04 05:05:50Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjmedia-videodev/videodev_imp.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)\n\n\n#define THIS_FILE   \"videodev.c\"\n\n#define DEFINE_CAP(name, info)\t{name, info}\n\n/* Capability names */\nstatic struct cap_info\n{\n    const char *name;\n    const char *info;\n} cap_infos[] = \n{\n    DEFINE_CAP(\"format\",        \"Video format\"),\n    DEFINE_CAP(\"scale\",         \"Input dimension\"),\n    DEFINE_CAP(\"window\",        \"Window handle\"),\n    DEFINE_CAP(\"resize\",        \"Renderer resize\"),\n    DEFINE_CAP(\"position\",      \"Renderer position\"),\n    DEFINE_CAP(\"hide\",          \"Renderer hide\"),\n    DEFINE_CAP(\"preview\",       \"Input preview\"),\n    DEFINE_CAP(\"orientation\",   \"Video orientation\"),\n    DEFINE_CAP(\"switch\",        \"Switch device\"),\n    DEFINE_CAP(\"wndflags\",      \"Window flags\")\n};\n\n\n/*\n * The device index seen by application and driver is different. \n *\n * At application level, device index is index to global list of device.\n * At driver level, device index is index to device list on that particular\n * factory only.\n */\n#define MAKE_DEV_ID(f_id, index)   (((f_id & 0xFFFF) << 16) | (index & 0xFFFF))\n#define GET_INDEX(dev_id)\t   ((dev_id) & 0xFFFF)\n#define GET_FID(dev_id)\t\t   ((dev_id) >> 16)\n#define DEFAULT_DEV_ID\t\t    0\n\n\n/* extern functions to create factories */\n#if PJMEDIA_VIDEO_DEV_HAS_NULL_VIDEO\npjmedia_vid_dev_factory* pjmedia_null_video_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_VIDEO_DEV_HAS_DSHOW\npjmedia_vid_dev_factory* pjmedia_dshow_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC\npjmedia_vid_dev_factory* pjmedia_cbar_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_VIDEO_DEV_HAS_V4L2\npjmedia_vid_dev_factory* pjmedia_v4l2_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_VIDEO_DEV_HAS_AVF\npjmedia_vid_dev_factory* pjmedia_avf_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_VIDEO_DEV_HAS_IOS\npjmedia_vid_dev_factory* pjmedia_ios_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_VIDEO_DEV_HAS_OPENGL\npjmedia_vid_dev_factory* pjmedia_opengl_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_VIDEO_DEV_HAS_FB\npjmedia_vid_dev_factory* pjmedia_fb_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_VIDEO_DEV_HAS_NULL\npjmedia_vid_dev_factory* pjmedia_null_factory(pj_pool_factory *pf);\n#endif\n\n#if PJMEDIA_VIDEO_DEV_HAS_ANDROID\npjmedia_vid_dev_factory* pjmedia_and_factory(pj_pool_factory *pf);\n#endif\n\n#define MAX_DRIVERS\tPJMEDIA_VID_DEV_MAX_DRIVERS\n#define MAX_DEVS\tPJMEDIA_VID_DEV_MAX_DEVS\n\n\n/* driver structure */\nstruct driver\n{\n    /* Creation function */\n    pjmedia_vid_dev_factory_create_func_ptr create;\n    /* Factory instance */\n    pjmedia_vid_dev_factory *f;\n    char\t\t     name[32];\t    /* Driver name\t\t    */\n    unsigned\t\t     dev_cnt;\t    /* Number of devices\t    */\n    unsigned\t\t     start_idx;\t    /* Start index in global list   */\n    int\t\t\t     cap_dev_idx;   /* Default capture device.\t    */\n    int\t\t\t     rend_dev_idx;  /* Default render device\t    */\n};\n\n/* The video device subsystem */\nstatic struct vid_subsys\n{\n    unsigned\t     init_count;\t/* How many times init() is called  */\n    pj_pool_factory *pf;\t\t/* The pool factory.\t\t    */\n\n    unsigned\t     drv_cnt;\t\t/* Number of drivers.\t\t    */\n    struct driver    drv[MAX_DRIVERS];\t/* Array of drivers.\t\t    */\n\n    unsigned\t     dev_cnt;\t\t/* Total number of devices.\t    */\n    pj_uint32_t\t     dev_list[MAX_DEVS];/* Array of device IDs.\t\t    */\n\n} vid_subsys;\n\n/* API: get capability name/info */\nPJ_DEF(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap,\n\t\t\t\t\t     const char **p_desc)\n{\n    const char *desc;\n    unsigned i;\n\n    if (p_desc==NULL) p_desc = &desc;\n\n    for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) {\n\tif ((1 << i)==cap)\n\t    break;\n    }\n\n    if (i==PJ_ARRAY_SIZE(cap_infos)) {\n\t*p_desc = \"??\";\n\treturn \"??\";\n    }\n\n    *p_desc = cap_infos[i].info;\n    return cap_infos[i].name;\n}\n\nstatic pj_status_t get_cap_pointer(const pjmedia_vid_dev_param *param,\n\t\t\t\t   pjmedia_vid_dev_cap cap,\n\t\t\t\t   void **ptr,\n\t\t\t\t   unsigned *size)\n{\n#define FIELD_INFO(name)    *ptr = (void*)&param->name; \\\n\t\t\t    *size = sizeof(param->name)\n\n    switch (cap) {\n    case PJMEDIA_VID_DEV_CAP_FORMAT:\n\tFIELD_INFO(fmt);\n\tbreak;\n    case PJMEDIA_VID_DEV_CAP_INPUT_SCALE:\n\tFIELD_INFO(disp_size);\n\tbreak;\n    case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW:\n\tFIELD_INFO(window);\n\tbreak;\n    case PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE:\n\tFIELD_INFO(disp_size);\n\tbreak;\n    case PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION:\n\tFIELD_INFO(window_pos);\n\tbreak;\n    case PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE:\n\tFIELD_INFO(window_hide);\n\tbreak;\n    case PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW:\n\tFIELD_INFO(native_preview);\n\tbreak;\n    case PJMEDIA_VID_DEV_CAP_ORIENTATION:\n\tFIELD_INFO(orient);\n\tbreak;\n    /* The PJMEDIA_VID_DEV_CAP_SWITCH does not have an entry in the\n     * param (it doesn't make sense to open a stream and tell it\n     * to switch immediately).\n     */\n    case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS:\n\tFIELD_INFO(window_flags);\n\tbreak;\n    default:\n\treturn PJMEDIA_EVID_INVCAP;\n    }\n\n#undef FIELD_INFO\n\n    return PJ_SUCCESS;\n}\n\n/* API: set cap value to param */\nPJ_DEF(pj_status_t)\npjmedia_vid_dev_param_set_cap( pjmedia_vid_dev_param *param,\n\t\t\t       pjmedia_vid_dev_cap cap,\n\t\t\t       const void *pval)\n{\n    void *cap_ptr;\n    unsigned cap_size;\n    pj_status_t status;\n\n    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_memcpy(cap_ptr, pval, cap_size);\n    param->flags |= cap;\n\n    return PJ_SUCCESS;\n}\n\n/* API: get cap value from param */\nPJ_DEF(pj_status_t)\npjmedia_vid_dev_param_get_cap( const pjmedia_vid_dev_param *param,\n\t\t\t       pjmedia_vid_dev_cap cap,\n\t\t\t       void *pval)\n{\n    void *cap_ptr;\n    unsigned cap_size;\n    pj_status_t status;\n\n    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if ((param->flags & cap) == 0) {\n\tpj_bzero(cap_ptr, cap_size);\n\treturn PJMEDIA_EVID_INVCAP;\n    }\n\n    pj_memcpy(pval, cap_ptr, cap_size);\n    return PJ_SUCCESS;\n}\n\n/* Internal: init driver */\nstatic pj_status_t init_driver(unsigned drv_idx, pj_bool_t refresh)\n{\n    struct driver *drv = &vid_subsys.drv[drv_idx];\n    pjmedia_vid_dev_factory *f;\n    unsigned i, dev_cnt;\n    pj_status_t status;\n\n    if (!refresh) {\n        /* Create the factory */\n        f = (*drv->create)(vid_subsys.pf);\n        if (!f)\n            return PJ_EUNKNOWN;\n\n        /* Call factory->init() */\n        status = f->op->init(f);\n        if (status != PJ_SUCCESS) {\n            f->op->destroy(f);\n            return status;\n        }\n    } else {\n\tf = drv->f;\n    }\n\n    /* Get number of devices */\n    dev_cnt = f->op->get_dev_count(f);\n    if (dev_cnt + vid_subsys.dev_cnt > MAX_DEVS) {\n\tPJ_LOG(4,(THIS_FILE, \"%d device(s) cannot be registered because\"\n\t\t\t      \" there are too many devices\",\n\t\t\t      vid_subsys.dev_cnt + dev_cnt - MAX_DEVS));\n\tdev_cnt = MAX_DEVS - vid_subsys.dev_cnt;\n    }\n\n    /* enabling this will cause pjsua-lib initialization to fail when there\n     * is no video device installed in the system, even when pjsua has been\n     * run with --null-video\n     *\n    if (dev_cnt == 0) {\n\tf->op->destroy(f);\n\treturn PJMEDIA_EVID_NODEV;\n    }\n    */\n\n    /* Fill in default devices */\n    drv->rend_dev_idx = drv->cap_dev_idx = -1;\n    for (i=0; i<dev_cnt; ++i) {\n\tpjmedia_vid_dev_info info;\n\n\tstatus = f->op->get_dev_info(f, i, &info);\n\tif (status != PJ_SUCCESS) {\n\t    f->op->destroy(f);\n\t    return status;\n\t}\n\n\tif (drv->name[0]=='\\0') {\n\t    /* Set driver name */\n\t    pj_ansi_strncpy(drv->name, info.driver, sizeof(drv->name));\n\t    drv->name[sizeof(drv->name)-1] = '\\0';\n\t}\n\n\tif (drv->rend_dev_idx < 0 && (info.dir & PJMEDIA_DIR_RENDER)) {\n\t    /* Set default render device */\n\t    drv->rend_dev_idx = i;\n\t}\n\tif (drv->cap_dev_idx < 0 && (info.dir & PJMEDIA_DIR_CAPTURE)) {\n\t    /* Set default capture device */\n\t    drv->cap_dev_idx = i;\n\t}\n\n        if (drv->rend_dev_idx >= 0 && drv->cap_dev_idx >= 0) {\n\t    /* Done. */\n\t    break;\n\t}\n    }\n\n    /* Register the factory */\n    drv->f = f;\n    drv->f->sys.drv_idx = drv_idx;\n    drv->start_idx = vid_subsys.dev_cnt;\n    drv->dev_cnt = dev_cnt;\n\n    /* Register devices to global list */\n    for (i=0; i<dev_cnt; ++i) {\n\tvid_subsys.dev_list[vid_subsys.dev_cnt++] = MAKE_DEV_ID(drv_idx, i);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* Internal: deinit driver */\nstatic void deinit_driver(unsigned drv_idx)\n{\n    struct driver *drv = &vid_subsys.drv[drv_idx];\n\n    if (drv->f) {\n\tdrv->f->op->destroy(drv->f);\n\tdrv->f = NULL;\n    }\n\n    drv->dev_cnt = 0;\n    drv->rend_dev_idx = drv->cap_dev_idx = -1;\n}\n\n/* API: Initialize the video device subsystem. */\nPJ_DEF(pj_status_t) pjmedia_vid_dev_subsys_init(pj_pool_factory *pf)\n{\n    unsigned i;\n    pj_status_t status = PJ_SUCCESS;\n\n    /* Allow init() to be called multiple times as long as there is matching\n     * number of shutdown().\n     */\n    if (vid_subsys.init_count++ != 0) {\n\treturn PJ_SUCCESS;\n    }\n\n    /* Register error subsystem */\n    pj_register_strerror(PJMEDIA_VIDEODEV_ERRNO_START, \n\t\t\t PJ_ERRNO_SPACE_SIZE, \n\t\t\t &pjmedia_videodev_strerror);\n\n    /* Init */\n    vid_subsys.pf = pf;\n    vid_subsys.drv_cnt = 0;\n    vid_subsys.dev_cnt = 0;\n\n    /* Register creation functions */\n#if PJMEDIA_VIDEO_DEV_HAS_V4L2\n    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_v4l2_factory;\n#endif\n#if PJMEDIA_VIDEO_DEV_HAS_AVF\n    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_avf_factory;\n#endif\n#if PJMEDIA_VIDEO_DEV_HAS_OPENGL\n    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_opengl_factory;\n#endif\n#if PJMEDIA_VIDEO_DEV_HAS_IOS\n    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_ios_factory;\n#endif\n#if PJMEDIA_VIDEO_DEV_HAS_DSHOW\n    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_dshow_factory;\n#endif\n#if PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC\n    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_cbar_factory;\n#endif\n#if PJMEDIA_VIDEO_DEV_HAS_FB\n    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_fb_factory;\n#endif\n#if PJMEDIA_VIDEO_DEV_HAS_NULL\n    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_null_factory;\n#endif\n\n    /* Initialize each factory and build the device ID list */\n    for (i=0; i<vid_subsys.drv_cnt; ++i) {\n\tstatus = init_driver(i, PJ_FALSE);\n\tif (status != PJ_SUCCESS) {\n\t    deinit_driver(i);\n\t    continue;\n\t}\n    }\n\n    return vid_subsys.dev_cnt ? PJ_SUCCESS : status;\n}\n\n/* API: register a video device factory to the video device subsystem. */\nPJ_DEF(pj_status_t)\npjmedia_vid_register_factory(pjmedia_vid_dev_factory_create_func_ptr adf,\n                             pjmedia_vid_dev_factory *factory)\n{\n    pj_bool_t refresh = PJ_FALSE;\n    pj_status_t status;\n\n    if (vid_subsys.init_count == 0)\n\treturn PJMEDIA_EVID_INIT;\n\n    vid_subsys.drv[vid_subsys.drv_cnt].create = adf;\n    vid_subsys.drv[vid_subsys.drv_cnt].f = factory;\n\n    if (factory) {\n        /* Call factory->init() */\n        status = factory->op->init(factory);\n        if (status != PJ_SUCCESS) {\n            factory->op->destroy(factory);\n            return status;\n        }\n        refresh = PJ_TRUE;\n    }\n\n    status = init_driver(vid_subsys.drv_cnt, refresh);\n    if (status == PJ_SUCCESS) {\n\tvid_subsys.drv_cnt++;\n    } else {\n\tdeinit_driver(vid_subsys.drv_cnt);\n    }\n\n    return status;\n}\n\n/* API: unregister a video device factory from the video device subsystem. */\nPJ_DEF(pj_status_t)\npjmedia_vid_unregister_factory(pjmedia_vid_dev_factory_create_func_ptr adf,\n                               pjmedia_vid_dev_factory *factory)\n{\n    unsigned i, j;\n\n    if (vid_subsys.init_count == 0)\n\treturn PJMEDIA_EVID_INIT;\n\n    for (i=0; i<vid_subsys.drv_cnt; ++i) {\n\tstruct driver *drv = &vid_subsys.drv[i];\n\n\tif ((factory && drv->f==factory) || (adf && drv->create == adf)) {\n\t    for (j = drv->start_idx; j < drv->start_idx + drv->dev_cnt; j++)\n\t    {\n\t\tvid_subsys.dev_list[j] = (pj_uint32_t)PJMEDIA_VID_INVALID_DEV;\n\t    }\n\n\t    deinit_driver(i);\n\t    pj_bzero(drv, sizeof(*drv));\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    return PJMEDIA_EVID_ERR;\n}\n\n/* API: get the pool factory registered to the video device subsystem. */\nPJ_DEF(pj_pool_factory*) pjmedia_vid_dev_subsys_get_pool_factory(void)\n{\n    return vid_subsys.pf;\n}\n\n/* API: Shutdown the video device subsystem. */\nPJ_DEF(pj_status_t) pjmedia_vid_dev_subsys_shutdown(void)\n{\n    unsigned i;\n\n    /* Allow shutdown() to be called multiple times as long as there is\n     * matching number of init().\n     */\n    if (vid_subsys.init_count == 0) {\n\treturn PJ_SUCCESS;\n    }\n    --vid_subsys.init_count;\n\n    if (vid_subsys.init_count == 0) {\n        for (i=0; i<vid_subsys.drv_cnt; ++i) {\n\t    deinit_driver(i);\n        }\n\n        vid_subsys.pf = NULL;\n    }\n    return PJ_SUCCESS;\n}\n\n/* API: Refresh the list of video devices installed in the system. */\nPJ_DEF(pj_status_t) pjmedia_vid_dev_refresh(void)\n{\n    unsigned i;\n    \n    vid_subsys.dev_cnt = 0;\n    for (i=0; i<vid_subsys.drv_cnt; ++i) {\n\tstruct driver *drv = &vid_subsys.drv[i];\n\t\n\tif (drv->f && drv->f->op->refresh) {\n\t    pj_status_t status = drv->f->op->refresh(drv->f);\n\t    if (status != PJ_SUCCESS) {\n\t\tPJ_PERROR(4, (THIS_FILE, status, \"Unable to refresh device \"\n\t\t\t\t\t\t \"list for %s\", drv->name));\n\t    }\n\t}\n\tinit_driver(i, PJ_TRUE);\n    }\n    return PJ_SUCCESS;\n}\n\n/* API: Get the number of video devices installed in the system. */\nPJ_DEF(unsigned) pjmedia_vid_dev_count(void)\n{\n    return vid_subsys.dev_cnt;\n}\n\n/* Internal: convert local index to global device index */\nstatic pj_status_t make_global_index(unsigned drv_idx, \n\t\t\t\t     pjmedia_vid_dev_index *id)\n{\n    if (*id < 0) {\n\treturn PJ_SUCCESS;\n    }\n\n    /* Check that factory still exists */\n    PJ_ASSERT_RETURN(vid_subsys.drv[drv_idx].f, PJ_EBUG);\n\n    /* Check that device index is valid */\n    PJ_ASSERT_RETURN(*id>=0 && *id<(int)vid_subsys.drv[drv_idx].dev_cnt, \n\t\t     PJ_EBUG);\n\n    *id += vid_subsys.drv[drv_idx].start_idx;\n    return PJ_SUCCESS;\n}\n\n/* Internal: lookup device id */\nstatic pj_status_t lookup_dev(pjmedia_vid_dev_index id,\n\t\t\t      pjmedia_vid_dev_factory **p_f,\n\t\t\t      unsigned *p_local_index)\n{\n    int f_id, index;\n\n    if (id < 0) {\n\tunsigned i;\n\n\tif (id <= PJMEDIA_VID_INVALID_DEV)\n\t    return PJMEDIA_EVID_INVDEV;\n\n\tfor (i=0; i<vid_subsys.drv_cnt; ++i) {\n\t    struct driver *drv = &vid_subsys.drv[i];\n\t    if (id==PJMEDIA_VID_DEFAULT_CAPTURE_DEV && \n\t\tdrv->cap_dev_idx >= 0) \n\t    {\n\t\tid = drv->cap_dev_idx;\n\t\tmake_global_index(i, &id);\n\t\tbreak;\n\t    } else if (id==PJMEDIA_VID_DEFAULT_RENDER_DEV && \n\t\tdrv->rend_dev_idx >= 0) \n\t    {\n\t\tid = drv->rend_dev_idx;\n\t\tmake_global_index(i, &id);\n\t\tbreak;\n\t    }\n\t}\n\n\tif (id < 0) {\n\t    return PJMEDIA_EVID_NODEFDEV;\n\t}\n    }\n\n    f_id = GET_FID(vid_subsys.dev_list[id]);\n    index = GET_INDEX(vid_subsys.dev_list[id]);\n\n    if (f_id < 0 || f_id >= (int)vid_subsys.drv_cnt)\n\treturn PJMEDIA_EVID_INVDEV;\n\n    if (index < 0 || index >= (int)vid_subsys.drv[f_id].dev_cnt)\n\treturn PJMEDIA_EVID_INVDEV;\n\n    *p_f = vid_subsys.drv[f_id].f;\n    *p_local_index = (unsigned)index;\n\n    return PJ_SUCCESS;\n\n}\n\n/* API: lookup device id */\nPJ_DEF(pj_status_t)\npjmedia_vid_dev_get_local_index(pjmedia_vid_dev_index id,\n                                pjmedia_vid_dev_factory **p_f,\n                                unsigned *p_local_index)\n{\n    return lookup_dev(id, p_f, p_local_index);\n}\n\n/* API: from factory and local index, get global index */\nPJ_DEF(pj_status_t)\npjmedia_vid_dev_get_global_index(const pjmedia_vid_dev_factory *f,\n                                 unsigned local_idx,\n                                 pjmedia_vid_dev_index *pid)\n{\n    PJ_ASSERT_RETURN(f->sys.drv_idx >= 0 && f->sys.drv_idx < MAX_DRIVERS,\n                     PJ_EINVALIDOP);\n    *pid = local_idx;\n    return make_global_index(f->sys.drv_idx, pid);\n}\n\n/* API: Get device information. */\nPJ_DEF(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id,\n\t\t\t\t\t     pjmedia_vid_dev_info *info)\n{\n    pjmedia_vid_dev_factory *f;\n    unsigned index;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(info, PJ_EINVAL);\n    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);\n\n    if (id <= PJMEDIA_VID_INVALID_DEV)\n\treturn PJMEDIA_EVID_INVDEV;\n\n    status = lookup_dev(id, &f, &index);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    status = f->op->get_dev_info(f, index, info);\n\n    /* Make sure device ID is the real ID (not PJMEDIA_VID_DEFAULT_*_DEV) */\n    info->id = index;\n    make_global_index(f->sys.drv_idx, &info->id);\n\n    return status;\n}\n\n/* API: find device */\nPJ_DEF(pj_status_t) pjmedia_vid_dev_lookup( const char *drv_name,\n\t\t\t\t\t    const char *dev_name,\n\t\t\t\t\t    pjmedia_vid_dev_index *id)\n{\n    pjmedia_vid_dev_factory *f = NULL;\n    unsigned drv_idx, dev_idx;\n\n    PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL);\n    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);\n\n    for (drv_idx=0; drv_idx<vid_subsys.drv_cnt; ++drv_idx) {\n\tif (!pj_ansi_stricmp(drv_name, vid_subsys.drv[drv_idx].name))\n\t{\n\t    f = vid_subsys.drv[drv_idx].f;\n\t    break;\n\t}\n    }\n\n    if (!f)\n\treturn PJ_ENOTFOUND;\n\n    for (dev_idx=0; dev_idx<vid_subsys.drv[drv_idx].dev_cnt; ++dev_idx)\n    {\n\tpjmedia_vid_dev_info info;\n\tpj_status_t status;\n\n\tstatus = f->op->get_dev_info(f, dev_idx, &info);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tif (!pj_ansi_stricmp(dev_name, info.name))\n\t    break;\n    }\n\n    if (dev_idx==vid_subsys.drv[drv_idx].dev_cnt)\n\treturn PJ_ENOTFOUND;\n\n    *id = dev_idx;\n    make_global_index(drv_idx, id);\n\n    return PJ_SUCCESS;\n}\n\n/* API: Initialize the video device parameters with default values for the\n * specified device.\n */\nPJ_DEF(pj_status_t) pjmedia_vid_dev_default_param(pj_pool_t *pool,\n                                                  pjmedia_vid_dev_index id,\n\t\t\t\t\t\t  pjmedia_vid_dev_param *param)\n{\n    pjmedia_vid_dev_factory *f;\n    unsigned index;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(param, PJ_EINVAL);\n    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);\n\n    if (id <= PJMEDIA_VID_INVALID_DEV)\n\treturn PJMEDIA_EVID_INVDEV;\n\n    status = lookup_dev(id, &f, &index);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    status = f->op->default_param(pool, f, index, param);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Normalize device IDs */\n    make_global_index(f->sys.drv_idx, &param->cap_id);\n    make_global_index(f->sys.drv_idx, &param->rend_id);\n\n    return PJ_SUCCESS;\n}\n\n/* API: Open video stream object using the specified parameters. */\nPJ_DEF(pj_status_t) pjmedia_vid_dev_stream_create(\n\t\t\t\t\tpjmedia_vid_dev_param *prm,\n\t\t\t\t\tconst pjmedia_vid_dev_cb *cb,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tpjmedia_vid_dev_stream **p_vid_strm)\n{\n    pjmedia_vid_dev_factory *cap_f=NULL, *rend_f=NULL, *f=NULL;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(prm && prm->dir && p_vid_strm, PJ_EINVAL);\n    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);\n    PJ_ASSERT_RETURN(prm->dir==PJMEDIA_DIR_CAPTURE ||\n\t\t     prm->dir==PJMEDIA_DIR_RENDER ||\n\t\t     prm->dir==PJMEDIA_DIR_CAPTURE_RENDER,\n\t\t     PJ_EINVAL);\n\n    /* Normalize cap_id */\n    if (prm->dir & PJMEDIA_DIR_CAPTURE) {\n\tunsigned index;\n\n\tif (prm->cap_id < 0)\n\t    prm->cap_id = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;\n\n\tstatus = lookup_dev(prm->cap_id, &cap_f, &index);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tprm->cap_id = index;\n\tf = cap_f;\n    }\n\n    /* Normalize rend_id */\n    if (prm->dir & PJMEDIA_DIR_RENDER) {\n\tunsigned index;\n\n\tif (prm->rend_id < 0)\n\t    prm->rend_id = PJMEDIA_VID_DEFAULT_RENDER_DEV;\n\n\tstatus = lookup_dev(prm->rend_id, &rend_f, &index);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tprm->rend_id = index;\n\tf = rend_f;\n    }\n\n    PJ_ASSERT_RETURN(f != NULL, PJ_EBUG);\n\n    /* For now, cap_id and rend_id must belong to the same factory */\n    PJ_ASSERT_RETURN((prm->dir != PJMEDIA_DIR_CAPTURE_RENDER) ||\n\t\t     (cap_f == rend_f),\n\t\t     PJMEDIA_EVID_INVDEV);\n\n    /* Create the stream */\n    status = f->op->create_stream(f, prm, cb,\n\t\t\t\t  user_data, p_vid_strm);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Assign factory id to the stream */\n    (*p_vid_strm)->sys.drv_idx = f->sys.drv_idx;\n    return PJ_SUCCESS;\n}\n\n/* API: Get the running parameters for the specified video stream. */\nPJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_param(\n\t\t\t\t\t    pjmedia_vid_dev_stream *strm,\n\t\t\t\t\t    pjmedia_vid_dev_param *param)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(strm && param, PJ_EINVAL);\n    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);\n\n    status = strm->op->get_param(strm, param);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Normalize device id's */\n    make_global_index(strm->sys.drv_idx, &param->cap_id);\n    make_global_index(strm->sys.drv_idx, &param->rend_id);\n\n    return PJ_SUCCESS;\n}\n\n/* API: Get the value of a specific capability of the video stream. */\nPJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_cap(\n\t\t\t\t\t    pjmedia_vid_dev_stream *strm,\n\t\t\t\t\t    pjmedia_vid_dev_cap cap,\n\t\t\t\t\t    void *value)\n{\n    return strm->op->get_cap(strm, cap, value);\n}\n\n/* API: Set the value of a specific capability of the video stream. */\nPJ_DEF(pj_status_t) pjmedia_vid_dev_stream_set_cap(\n\t\t\t\t\t    pjmedia_vid_dev_stream *strm,\n\t\t\t\t\t    pjmedia_vid_dev_cap cap,\n\t\t\t\t\t    const void *value)\n{\n    /* For fast switching, device global index needs to be converted to\n     * local index before forwarding the request to the device stream.\n     */\n    if (cap == PJMEDIA_VID_DEV_CAP_SWITCH) {\n\tpjmedia_vid_dev_factory *f;\n\tunsigned local_idx;\n\tpj_status_t status;\n\tpjmedia_vid_dev_switch_param p = *(pjmedia_vid_dev_switch_param*)value;\n\n\tstatus = lookup_dev(p.target_id, &f, &local_idx);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Make sure that current & target devices share the same factory */\n\tif (f->sys.drv_idx != strm->sys.drv_idx)\n\t    return PJMEDIA_EVID_INVDEV;\n\n\tp.target_id = local_idx;\n\treturn strm->op->set_cap(strm, cap, &p);\n    }\n\n    return strm->op->set_cap(strm, cap, value);\n}\n\n/* API: Start the stream. */\nPJ_DEF(pj_status_t) pjmedia_vid_dev_stream_start(pjmedia_vid_dev_stream *strm)\n{\n    pj_status_t status;\n\n    if (pjmedia_vid_dev_stream_is_running(strm))\n\treturn PJ_SUCCESS;\n\n    status = strm->op->start(strm);\n    if (status == PJ_SUCCESS)\n\tstrm->sys.is_running = PJ_TRUE;\n    return status;\n}\n\n/* API: has it been started? */\nPJ_DEF(pj_bool_t)\npjmedia_vid_dev_stream_is_running(pjmedia_vid_dev_stream *strm)\n{\n    return strm->sys.is_running;\n}\n\nPJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_frame(\n\t\t\t\t\t    pjmedia_vid_dev_stream *strm,\n\t\t\t\t\t    pjmedia_frame *frame)\n{\n    pj_assert(strm->op->get_frame);\n    return strm->op->get_frame(strm, frame);\n}\n\nPJ_DEF(pj_status_t) pjmedia_vid_dev_stream_put_frame(\n\t\t\t\t\t    pjmedia_vid_dev_stream *strm,\n                                            const pjmedia_frame *frame)\n{\n    pj_assert(strm->op->put_frame);\n    return strm->op->put_frame(strm, frame);\n}\n\n/* API: Stop the stream. */\nPJ_DEF(pj_status_t) pjmedia_vid_dev_stream_stop(pjmedia_vid_dev_stream *strm)\n{\n    strm->sys.is_running = PJ_FALSE;\n    return strm->op->stop(strm);\n}\n\n/* API: Destroy the stream. */\nPJ_DEF(pj_status_t) pjmedia_vid_dev_stream_destroy(\n\t\t\t\t\t\tpjmedia_vid_dev_stream *strm)\n{\n    strm->sys.is_running = PJ_FALSE;\n    return strm->op->destroy(strm);\n}\n\n\n#endif /* PJMEDIA_HAS_VIDEO */\n"
  },
  {
    "path": "deps/pjsip/pjnath/build/Makefile",
    "content": "# By default, the test application includes main.o.\n# OS make file may override this with os-specific files\nexport PJNATH_TEST_OBJS = main.o\n\ninclude ../../build.mak\ninclude ../../version.mak\ninclude $(PJDIR)/build/common.mak\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\nPJLIB_LIB:=../../pjlib/lib/libpj-$(TARGET_NAME)$(LIBEXT)\nPJLIB_UTIL_LIB:=../../pjlib-util/lib/libpjlib-util-$(TARGET_NAME)$(LIBEXT)\nexport PJNATH_LIB:=../lib/libpjnath-$(TARGET_NAME)$(LIBEXT)\n\n###############################################################################\n# Gather all flags.\n#\nexport _CFLAGS \t:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t\t   $(CFLAGS) $(CC_INC)../include $(CC_INC)../../pjlib/include \\\n\t\t   $(CC_INC)../../pjlib-util/include\nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\nexport _LDFLAGS := $(subst /,$(HOST_PSEP),$(PJNATH_LIB)) \\\n\t\t   $(subst /,$(HOST_PSEP),$(PJLIB_UTIL_LIB)) \\\n\t\t   $(subst /,$(HOST_PSEP),$(PJLIB_LIB)) \\\n\t\t   $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(LDFLAGS) \n\n###############################################################################\n# Defines for building PJNATH library\n#\nexport PJNATH_SRCDIR = ../src/pjnath\nexport PJNATH_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \\\n\t\terrno.o ice_session.o ice_strans.o nat_detect.o stun_auth.o \\\n\t\tstun_msg.o stun_msg_dump.o stun_session.o stun_sock.o \\\n\t\tstun_transaction.o turn_session.o turn_sock.o\nexport PJNATH_CFLAGS += $(_CFLAGS)\n\n###############################################################################\n# Defines for building test application\n#\nexport PJNATH_TEST_SRCDIR = ../src/pjnath-test\nexport PJNATH_TEST_OBJS += ice_test.o stun.o sess_auth.o server.o concur_test.o \\\n\t\t\t    stun_sock_test.o turn_sock_test.o test.o\nexport PJNATH_TEST_CFLAGS += $(_CFLAGS)\nexport PJNATH_TEST_LDFLAGS += $(_LDFLAGS)\nexport PJNATH_TEST_EXE:=../bin/pjnath-test-$(TARGET_NAME)$(HOST_EXE)\n\n\t\n###############################################################################\n# Defines for building TURN client application\n#\nexport PJTURN_CLIENT_SRCDIR = ../src/pjturn-client\nexport PJTURN_CLIENT_OBJS += client_main.o\nexport PJTURN_CLIENT_CFLAGS += $(_CFLAGS)\nexport PJTURN_CLIENT_LDFLAGS += $(_LDFLAGS)\nexport PJTURN_CLIENT_EXE:=../bin/pjturn-client-$(TARGET_NAME)$(HOST_EXE)\n\n###############################################################################\n# Defines for building TURN server application\n#\nexport PJTURN_SRV_SRCDIR = ../src/pjturn-srv\nexport PJTURN_SRV_OBJS += allocation.o auth.o listener_udp.o \\\n\t\t\t  listener_tcp.o server.o main.o\nexport PJTURN_SRV_CFLAGS += $(_CFLAGS)\nexport PJTURN_SRV_LDFLAGS += $(_LDFLAGS)\nexport PJTURN_SRV_EXE:=../bin/pjturn-srv-$(TARGET_NAME)$(HOST_EXE)\n\n\t\n\t\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT \n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\nTARGETS := pjnath pjturn-client pjturn-srv\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && rm -rf docs/$(PJ_VERSION) && doxygen docs/doxygen.cfg\n\t@if [ -n \"$(WWWDIR)\" ] && ! [ -d \"$(WWWDIR)/docs/$(PJ_VERSION)/pjnath/docs/html\" ] ; then \\\n\t\techo \"Creating docs/$(PJ_VERSION)/pjnath/docs/html\" ; \\\n\t\tmkdir -p $(WWWDIR)/docs/$(PJ_VERSION)/pjnath/docs/html ; \\\n\tfi \n\t@if [ -n \"$(WWWDIR)\" ] && [ -d \"$(WWWDIR)/docs/$(PJ_VERSION)/pjnath/docs/html\" ] ; then \\\n\t\techo \"Copying docs/$(PJ_VERSION) to $(WWWDIR)/docs/$(PJ_VERSION)/pjnath/docs/html..\" ; \\\n\t\tcp -v -a ../docs/$(PJ_VERSION)/html/* $(WWWDIR)/docs/$(PJ_VERSION)/pjnath/docs/html/ ; \\\n\tfi\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend pjlib pjlib-test clean realclean distclean\n\npjnath:\n\t$(MAKE) -f $(RULES_MAK) APP=PJNATH app=pjnath $(PJNATH_LIB)\n\n$$(PJNATH_LIB): pjnath\n\npjnath-test: $(PJLIB_LIB) $(PJLIB_UTIL_LIB) $(PJNATH_LIB)\n\t$(MAKE) -f $(RULES_MAK) APP=PJNATH_TEST app=pjnath-test $(PJNATH_TEST_EXE)\n\npjturn-client: $(PJLIB_LIB) $(PJLIB_UTIL_LIB) $(PJNATH_LIB)\n\t$(MAKE) -f $(RULES_MAK) APP=PJTURN_CLIENT app=pjturn-client $(PJTURN_CLIENT_EXE)\n\npjturn-srv: $(PJLIB_LIB) $(PJLIB_UTIL_LIB) $(PJNATH_LIB)\n\t$(MAKE) -f $(RULES_MAK) APP=PJTURN_SRV app=pjturn-srv $(PJTURN_SRV_EXE)\n\n.PHONY: ../lib/pjnath.ko\n../lib/pjnath.ko:\n\techo Making $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJNATH app=pjnath $@\n\n.PHONY: ../lib/pjnath-test.ko\n../lib/pjnath-test.ko:\n\t$(MAKE) -f $(RULES_MAK) APP=PJNATH_TEST app=pjnath-test $@\n\nclean:\n\t$(MAKE) -f $(RULES_MAK) APP=PJNATH app=pjnath $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJNATH_TEST app=pjnath-test $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJTURN_CLIENT app=pjturn-client $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJTURN_SRV app=pjturn-srv $@\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjnath-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjnath-test-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjturn-client-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjturn-srv-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(MAKE) -f $(RULES_MAK) APP=PJNATH app=pjnath $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJNATH_TEST app=pjnath-test $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJTURN_CLIENT app=pjturn-client $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJTURN_SRV app=pjturn-srv $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=PJNATH app=pjnath $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJNATH_TEST app=pjnath-test $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJTURN_CLIENT app=pjturn-client $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJTURN_SRV app=pjturn-srv $@\n\techo '$(PJNATH_TEST_EXE): $(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB)' >> .pjnath-test-$(TARGET_NAME).depend\n\techo '$(PJTURN_CLIENT_EXE): $(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB)' >> .pjturn-client-$(TARGET_NAME).depend\n\techo '$(PJTURN_SRV_EXE): $(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB)' >> .pjturn-srv-$(TARGET_NAME).depend\n\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/docs/doc_ice.h",
    "content": "/* $Id: doc_ice.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/**\n@defgroup PJNATH_ICE ICE: Interactive Connectivity Establishment\n@brief Interactive Connectivity Establishment (ICE)\n@ingroup PJNATH\n*/\n\n/**\n@defgroup PJNATH_ICE_STREAM_TRANSPORT ICE stream transport\n@brief Transport for media streams using ICE\n@ingroup PJNATH_ICE\n */\n\n/**\n@defgroup PJNATH_ICE_SESSION ICE Session\n@brief Transport Independent ICE Session\n@ingroup PJNATH_ICE\n */\n\n/**\n@addtogroup PJNATH_ICE\n\\section org Library organizations\n\nSee <b>Table of Contents</b> below.\n\n\\section ice_intro_sec Introduction to ICE\n\nInteractive Connectivity Establishment (ICE) is the ultimate \nweapon a client can have in its NAT traversal solution arsenals, \nas it promises that if there is indeed one path for two clients \nto communicate, then ICE will find this path. And if there are \nmore than one paths which the clients can communicate, ICE will \nuse the best/most efficient one.\n\nICE works by combining several protocols (such as STUN and TURN) \naltogether and offering several candidate paths for the communication,\nthereby maximising the chance of success, but at the same time also \nhas the capability to prioritize the candidates, so that the more \nexpensive alternative (namely relay) will only be used as the last\nresort when else fails. ICE negotiation process involves several \nstages:\n\n - candidate gathering, where the client finds out all the possible \n   addresses that it can use for the communication. It may find \n   three types of candidates: host candidate to represent its \n   physical NICs, server reflexive candidate for the address that \n   has been resolved from STUN, and relay candidate for the address \n   that the client has allocated from a TURN relay.\n - prioritizing these candidates. Typically the relay candidate will\n   have the lowest priority to use since it's the most expensive.\n - encoding these candidates, sending it to remote peer, and \n   negotiating it with offer-answer.\n - pairing the candidates, where it pairs every local candidates \n   with every remote candidates that it receives from the remote peer.\n - checking the connectivity for each candidate pairs.\n - concluding the result. Since every possible path combinations are \n   checked, if there is a path to communicate ICE will find it.\n\n\n\\section icestrans_sec Using ICE transport\n\nThe \\ref PJNATH_ICE_STREAM_TRANSPORT is a ready to use object which\nperforms the above ICE operations as well as provides application with\ninterface to send and receive data using the negotiated path.\n\nPlease see \\ref PJNATH_ICE_STREAM_TRANSPORT on how to use this object.\n\n\n\\section ice_owntransport_sec Creating custom ICE transport\n\nIf the \\ref PJNATH_ICE_STREAM_TRANSPORT is not suitable for use \nfor some reason, you will need to implement your own ICE transport,\nby combining the \\ref PJNATH_ICE_SESSION with your own means to\nsend and receive packets. The \\ref PJNATH_ICE_STREAM_TRANSPORT \nprovides the best example on how to do this.\n\n\n\\section ice_samples_sec Samples\n\nThe \\ref ice_demo_sample sample demonstrates how to use \n\\ref PJNATH_ICE_STREAM_TRANSPORT <b>without</b> using signaling \nprotocol such as <b>SIP</b>. It provides  interactive user interface\nto create and manage the ICE sessions as well as to exchange SDP \nwith another ice_demo instance.\n\nAlso see <b>\\ref samples_page</b> for other samples.\n */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/docs/doc_mainpage.h",
    "content": "/* $Id: doc_mainpage.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n\n/**\n\n@mainpage PJNATH - Open Source ICE, STUN, and TURN Library\n\nPJNATH (PJSIP NAT Helper) is an open source library providing NAT traversal \nfunctionalities by using standard based protocols such as STUN, TURN, and ICE.\n\n\n\\section background Background\n\n\nNetwork Address Translation (NAT) is commonly deployed everywhere primarily to\nalleviate the exhaustion of IPv4 address space by allowing multiple hosts to \nshare a public/Internet address. While NAT would work well for typical client \nserver communications (such as web and email), since it's always the client \nthat initiates the conversation and normally client doesn't need to maintain\nthe connection for a long time, installation of NAT would cause major problem\nfor peer-to-peer communication, such as (and especially) VoIP. \n\n<strong>\\ref nat_intro \"Read more..\"</strong>\n\n\n\\section intro Introduction to PJNATH\n\nPJSIP NAT Helper (PJNATH) is a library which contains the implementation of \nstandard based NAT traversal solutions. PJNATH can be used as a stand-alone \nlibrary for your software, or you may use PJSUA-LIB library, a very high level\n library integrating PJSIP, PJMEDIA, and PJNATH into simple to use APIs.\n\nPJNATH has the following features:\n\n - <strong>STUNbis</strong> implementation,\\n\n   providing both ready to use \n   STUN-aware socket and framework to implement higher level STUN based \n   protocols such as TURN and ICE. The implementation complies to \n   <A HREF=\"http://www.ietf.org/rfc/rfc5389.txt\">RFC 5389</A>\n   standard.\\n\\n\n\n - <strong>NAT type detection</strong>, \\n\n   performs detection of the NAT type in front of the endpoint, according\n   to <A HREF=\"http://www.ietf.org/rfc/rfc3489.txt\">RFC 3489</A>. \n   While the practice to detect the NAT type to assist NAT \n   traversal has been deprecated in favor of ICE, the information may still\n   be useful for troubleshooting purposes, hence the utility is provided.\\n\\n\n\n - <strong>Traversal Using Relays around NAT (TURN)</strong> implementation.\\n\n   TURN is a protocol for relaying communications by means of using relay, \n   and combined with ICE it provides efficient last effort alternative for \n   the communication path. The TURN implementation in PJNATH complies to \n   <A HREF=\"http://www.ietf.org/internet-drafts/draft-ietf-behave-turn-14.txt\">\n   draft-ietf-behave-turn-14</A> draft.\\n\\n\n\n - <strong>Interactive Connectivity Establishmen (ICE)</strong> implementation.\\n\n   ICE is a protocol for discovering communication path(s) between two \n   endpoints. The implementation in PJNATH complies to\n   <A HREF=\"http://www.ietf.org/internet-drafts/draft-ietf-mmusic-ice-19.txt\">\n   draft-ietf-mmusic-ice-19.txt</A> draft\n\nIn the future, more protocols will be implemented (such as UPnP IGD, and \nSOCKS5).\n\n\n\\section pjnath_organization_sec Library Organization\n\nThe library provides the following main component groups:\n\n - \\ref PJNATH_STUN\\n\\n\n - \\ref PJNATH_TURN\\n\\n\n - \\ref PJNATH_ICE\\n\\n\n - \\ref PJNATH_NAT_DETECT\\n\\n\n\nApart from the \\ref PJNATH_NAT_DETECT, each component group are further \ndivided into two functionalities:\n\n - <b>Transport objects</b>\\n\n   The transport objects (such as STUN transport, TURN transport, and ICE\n   stream transport) are the implementation of the session object\n   <strong>with</strong> particular transport/sockets. They are provided\n   as ready to use objects for applications.\\n\\n\n\n - <b>Transport independent/session layer</b>\\n\n   The session objects (such as STUN session, TURN session, and ICE session)\n   are the core object for maintaining the protocol session, and it is\n   independent of transport (i.e. it does not \"own\" a socket). This way\n   developers can reuse these session objects for any kind of transports,\n   such as UDP, TCP, or TLS, with or without using PJLIB socket API.\n   The session objects provide function and callback to send and receive\n   packets respectively.\n\nFor more information about each component groups, please click the component\nlink above.\n\n\n\\section pjnath_start_sec Getting Started with PJNATH\n\n\\subsection dependency Library Dependencies\n\nThe PJNATH library depends (and only depends) on PJLIB and PJLIB-UTIL\nlibraries. All these libraries should have been packaged together with\nthe main PJSIP distribution. You can download the PJSIP distribution\nfrom <A HREF=\"http://www.pjsip.org\">PJSIP website</A>\n\n\n\\subsection pjnath_using_sec Using the libraries\n\nPlease click on the appropriate component under \\ref pjnath_organization_sec\nsection above, which will take you to the documentation on how to use the \ncomponent.\n\n\n\\subsection samples_sec Samples\n\nWe attempt to provide simple samples to use each functionality of the PJNATH\nlibrary.\n\nPlease see <b>\\ref samples_page</b> page for the list of samples.\n\n\n*/\n\n\n\n/**\n@defgroup samples_page PJNATH Samples and screenshots\n@brief Sample applications and screenshots\n */\n\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/docs/doc_nat.h",
    "content": "/* $Id: doc_nat.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n\n/**\n\n@defgroup nat_intro Introduction to Network Address Translation (NAT) and NAT Traversal\n@brief This page describes NAT and the problems caused by it and the solutions\n\n\n\n\\section into Introduction to NAT\n\n\nNAT (Network Address Translation) is a mechanism where a device performs \nmodifications to the TCP/IP address/port number of a packet and maps the \nIP address from one realm to another (usually from private IP address to \npublic IP address and vice versa). This works by the NAT device allocating\na temporary port number on the public side of the NAT upon forwarding \noutbound packet from the internal host towards the Internet, maintaining\nthis mapping for some predefined time, and forwarding the inbound packets\nreceived from the Internet on this public port back to the internal host.\n\n\nNAT devices are installed primarily to alleviate the exhaustion of IPv4 \naddress space by allowing multiple hosts to share a public/Internet address.\nAlso due to its mapping nature (i.e. a mapping can only be created by \na transmission from an internal host), NAT device is preferred to be \ninstalled even when IPv4 address exhaustion is not a problem (for example\nwhen there is only one host at home), to provide some sort of security/shield\nfor the internal hosts against threats from the Internet.\n\n\nDespite the fact that NAT provides some shields for the internal network,\none must distinguish NAT solution from firewall solution. NAT is not \na firewall solution. A firewall is a security solution designed to enforce\nthe security policy of an organization, while NAT is a connectivity solution\nto allow multiple hosts to use a single public IP address. Understandably\nboth functionalities are difficult to separate at times, since many \n(typically consumer) products claims to do both with the same device and\nsimply label the device a NAT box. But we do want to make this distinction\nrather clear, as PJNATH is a NAT traversal helper and not a firewall bypass\nsolution (yet).\n\n\n\n\\section problems The NAT traversal problems\n\n\nWhile NAT would work well for typical client server communications (such as\nweb and email), since it's always the client that initiates the conversation\nand normally client doesn't need to maintain the connection for a long time,\ninstallation of NAT would cause major problem for peer-to-peer communication,\nsuch as (and especially) VoIP. These problems will be explained in more detail\nbelow.\n\n\n\\subsection peer_addr Peer address problem\n\n\nIn VoIP, normally we want the media (audio, and video) to flow directly\nbetween the clients, since relaying is costly (both in terms of bandwidth\ncost for service provider, and additional latency introduced by relaying).\nTo do this, each client informs its media transport address to the other\nclient , by sending it via the VoIP signaling path, and the other side would\nsend its media to this transport address.\n\n\nAnd there lies the problem. If the client software is not NAT aware, then\nit would send its private IP address to the other client, and the other\nclient would not be able to send media to this address.\n\n\nTraditionally this was solved by using STUN. With this mechanism, the client\nfirst finds out its public IP address/port by querying a STUN server, then\nsend sthis public address instead of its private address to the other \nclient. When both sides are using this mechanism, they can then send media \npackets to these addresses, thereby creating a mapping in the NAT (also \ncalled opening a \"hole\", hence this mechanism is also popularly called \n\"hole punching\") and both can then communicate with each other.\n\n\nBut this mechanism does not work in all cases, as will be explained below.\n\n\n\n\\subsection hairpin Hairpinning behavior\n\n\nHairpin is a behavior where a NAT device forwards packets from a host in\ninternal network (lets call it host A) back to some other host (host B) in\nthe same internal network, when it detects that the (public IP address)\ndestination of the packet is actually a mapped IP address that was created\nfor the internal host (host B). This is a desirable behavior of a NAT, \nbut unfortunately not all NAT devices support this.\n\n\nLacking this behavior, two (internal) hosts behind the same NAT will not\nbe able to communicate with each other if they exchange their public\naddresses (resolved by STUN above) to each other.\n\n\n\n\\subsection symmetric Symmetric behavior\n\n\nNAT devices don't behave uniformly and people have been trying to classify\ntheir behavior into different classes. Traditionally NAT devices are\nclassified into Full Cone, Restricted Cone, Port Restricted Cone, and \nSymmetric types, according to <A HREF=\"http://www.ietf.org/rfc/rfc3489.txt\">RFC 3489</A>\nsection 5. A more recent method of classification, as explained by \n<A HREF=\"http://www.ietf.org/rfc/rfc4787.txt\">RFC 4787</A>, divides \nthe NAT behavioral types into two attributes: the mapping behavior \nattribute and the filtering behavior attribute. Each attribute can be \none of three types: <i>Endpoint-Independent</i>, <i>Address-Dependent</i>,\nor <i>Address and Port-Dependent</i>. With this new classification method,\na Symmetric NAT actually is an Address and Port-Dependent mapping NAT.\n\n\nAmong these types, the Symmetric type is the hardest one to work with. \nThe problem is because the NAT allocates different mapping (of the same\ninternal host) for the communication to the STUN server and the \ncommunication to the other (external) hosts, so the IP address/port that\nis informed by one host to the other is meaningless for the recipient \nsince this is not the actual IP address/port mapping that the NAT device \ncreates. The result is when the recipient host tries to send a packet to \nthis address, the NAT device would drop the packet since it does not \nrecognize the sender of the packet as the \"authorized\" hosts to send \nto this address.\n\n\nThere are two solutions for this. The first, we could make the client \nsmarter by switching transmission of the media to the source address of \nthe media packets. This would work since normally clients uses a well \nknown trick called symmetric RTP, where they use one socket for both \ntransmitting and receiving RTP/media packets. We also use this \nmechanism in PJMEDIA media transport. But this solution only works \nif a client behind a symmetric NAT is not communicating with other \nclient behind either symmetric NAT or port-restricted NAT.\n\n\nThe second solution is to use media relay, but as have been mentioned \nabove, relaying is costly, both in terms of bandwidth cost for service\nprovider and additional latency introduced by relaying.\n\n\n\n\\subsection binding_timeout Binding timeout\n\nWhen a NAT device creates a binding (a public-private IP address \nmapping), it will associate a timer with it. The timer is used to \ndestroy the binding once there is no activity/traffic associated with \nthe binding. Because of this, a NAT aware application that wishes to \nkeep the binding open must periodically send outbound packets, \na mechanism known as keep-alive, or otherwise it will ultimately \nloose the binding and unable to receive incoming packets from Internet.\n\n\n\\section solutions The NAT traversal solutions\n\n\n\\subsection stun Old STUN (RFC 3489)\n\nThe original STUN (Simple Traversal of User Datagram Protocol (UDP) \nThrough Network Address Translators (NATs)) as defined by \n<A HREF=\"http://www.ietf.org/rfc/rfc3489.txt\">RFC 3489</A>\n(published in 2003, but the work was started as early as 2001) was \nmeant to be a standalone, standard-based solution for the NAT \nconnectivity problems above. It is equipped with NAT type detection \nalgoritm and methods to hole-punch the NAT in order to let traffic \nto get through and has been proven to be quite successful in \ntraversing many types of NATs, hence it has gained a lot of popularity\n as a simple and effective NAT traversal solution.\n\nBut since then the smart people at IETF has realized that STUN alone \nis not going to be enough. Besides its nature that STUN solution cannot \nsolve the symmetric-to-symmetric or port-restricted connection, \npeople have also discovered that NAT behavior can change for different \ntraffic (or for the same traffic overtime) hence it was concluded that \nNAT type detection could produce unreliable results hence one should not \nrely too much on it.\n\nBecause of this, STUN has since moved its efforts to different strategy. \nInstead of attempting to provide a standalone solution, it's now providing \na part solution and framework to build other (STUN based) protocols \non top of it, such as TURN and ICE.\n\n\n\\subsection stunbis STUN/STUNbis (RFC 5389)\n\nThe Session Traversal Utilities for NAT (STUN) is the further development \nof the old STUN. While it still provides a mechanism for a client to \nquery its public/mapped address to a STUN server, it has deprecated \nthe use of NAT type detection, and now it serves as a framework to build \nother protocols on top of it (such as TURN and ICE).\n\n\n\\subsection midcom_turn Old TURN (draft-rosenberg-midcom-turn)\n\nTraversal Using Relay NAT (TURN), a standard-based effort started as early\nas in November 2001, was meant to be the complementary method for the \n(old) STUN to complete the solution. The original idea was the host to use \nSTUN to detect the NAT type, and when it has found that the NAT type is \nsymmetric it would use TURN to relay the traffic. But as stated above, \nthis approach was deemed to be unreliable, and now the prefered way to use\nTURN (and it's a new TURN specification as well) is to combine it with ICE.\n\n\n\\subsection turn TURN (draft-ietf-behave-turn)\n\nTraversal Using Relays around NAT (TURN) is the latest development of TURN. \nWhile the protocol details have changed a lot, the objective is still \nthe same, that is to provide relaying control for the application. \nAs mentioned above, preferably TURN should be used with ICE since relaying \nis costly in terms of both bandwidth and latency, hence it should be used \nas the last resort.\n\n\n\\subsection b2bua B2BUA approach\n\nA SIP Back to Back User Agents (B2BUA) is a SIP entity that sits in the \nmiddle of SIP traffic and acts as SIP user agents on both call legs. \nThe primary motivations to have a B2BUA are to be able to provision \nthe call (e.g. billing, enforcing policy) and to help with NAT traversal \nfor the clients. Normally a B2BUA would be equipped with media relaying \nor otherwise it wouldn't be very useful.\n\nProducts that fall into this category include SIP Session Border \nControllers (SBC), and PBXs such as Asterisk are technically a B2BUA \nas well.\n\nThe benefit of B2BUA with regard to helping NAT traversal is it does not \nrequire any modifications to the client to make it go through NATs. \nAnd since basically it is a relay, it should be able to traverse \nsymmetric NAT successfully.\n\nHowever, since it is a relay, the usual relaying drawbacks apply, \nnamely the bandwidth and latency issue. More over, since a B2BUA acts \nas user agent in either call-legs (i.e. it terminates the SIP \nsignaling/call on one leg, albeit it creates another call on the other \nleg), it may also introduce serious issues with end-to-end SIP signaling.\n\n\n\\subsection alg ALG approach\n\nNowdays many NAT devices (such as consumer ADSL routers) are equipped \nwith intelligence to inspect and fix VoIP traffic in its effort to help \nit with the NAT traversal. This feature is called Application Layer \nGateway (ALG) intelligence. The idea is since the NAT device knows about \nthe mapping, it might as well try to fix the application traffic so that \nthe traffic could better traverse the NAT. Some tricks that are \nperformed include for example replacing the private IP addresses/ports \nin the SIP/SDP packet with the mapped public address/port of the host \nthat sends the packet.\n\nDespite many claims about its usefullness, in reality this has given us \nmore problems than the fix. Too many devices such as these break the \nSIP signaling, and in more advanced case, ICE negotiation. Some \nexamples of bad situations that we have encountered in the past:\n\n - NAT device alters the Via address/port fields in the SIP response \n   message, making the response fail to pass SIP response verification \n   as defined by SIP RFC.\n - In other case, the modifications in the Via headers of the SIP \n   response hides the important information from the SIP server, \n   nameny the actual IP address/port of the client as seen by the SIP \n   server.\n - Modifications in the Contact URI of REGISTER request/response makes \n   the client unable to detect it's registered binding.\n - Modifications in the IP addresses/ports in SDP causes ICE \n   negotiation to fail with ice-mismatch status.\n - The complexity of the ALG processing in itself seems to have caused \n   the device to behave erraticly with managing the address bindings \n   (e.g. it creates a new binding for the second packet sent by the \n   client, even when the previous packet was sent just second ago, or\n   it just sends inbound packet to the wrong host).\n\n\nMany man-months efforts have been spent just to troubleshoot issues \ncaused by these ALG (mal)functioning, and as it adds complexity to \nthe problem rather than solving it, in general we do not like this \napproach at all and would prefer it to go away.\n\n\n\\subsection upnp UPnP\n\nThe Universal Plug and Play (UPnP) is a set of protocol specifications \nto control network appliances and one of its specification is to \ncontrol NAT device. With this protocol, a client can instruct the \nNAT device to open a port in the NAT's public side and use this port \nfor its communication. UPnP has gained popularity due to its \nsimplicity, and one can expect it to be available on majority of \nNAT devices.\n\nThe drawback of UPnP is since it uses multicast in its communication,\nit will only allow client to control one NAT device that is in the \nsame multicast domain. While this normally is not a problem in \nhousehold installations (where people normally only have one NAT \nrouter), it will not work if the client is behind cascaded routers \ninstallation. More over uPnP has serious issues with security due to \nits lack of authentication, it's probably not the prefered solution \nfor organizations.\n\n\\subsection other Other solutions\n\nOther solutions to NAT traversal includes:\n\n - SOCKS, which supports UDP protocol since SOCKS5.\n\n\n\n\\section ice ICE Solution - The Protocol that Works Harder\n\nA new protocol is being standardized (it's in Work Group Last Call/WGLC \nstage at the time this article was written) by the IETF, called \nInteractive Connectivity Establishment (ICE). ICE is the ultimate \nweapon a client can have in its NAT traversal solution arsenals, \nas it promises that if there is indeed one path for two clients \nto communicate, then ICE will find this path. And if there are \nmore than one paths which the clients can communicate, ICE will \nuse the best/most efficient one.\n\nICE works by combining several protocols (such as STUN and TURN) \naltogether and offering several candidate paths for the communication, \nthereby maximising the chance of success, but at the same time also \nhas the capability to prioritize the candidates, so that the more \nexpensive alternative (namely relay) will only be used as the last\nresort when else fails. ICE negotiation process involves several \nstages:\n\n - candidate gathering, where the client finds out all the possible \n   addresses that it can use for the communication. It may find \n   three types of candidates: host candidate to represent its \n   physical NICs, server reflexive candidate for the address that \n   has been resolved from STUN, and relay candidate for the address \n   that the client has allocated from a TURN relay.\n - prioritizing these candidates. Typically the relay candidate will\n   have the lowest priority to use since it's the most expensive.\n - encoding these candidates, sending it to remote peer, and \n   negotiating it with offer-answer.\n - pairing the candidates, where it pairs every local candidates \n   with every remote candidates that it receives from the remote peer.\n - checking the connectivity for each candidate pairs.\n - concluding the result. Since every possible path combinations are \n   checked, if there is a path to communicate ICE will find it.\n\n\nThere are many benetifs of ICE:\n\n - it's standard based.\n - it works where STUN works (and more)\n - unlike standalone STUN solution, it solves the hairpinning issue, \n   since it also offers host candidates.\n - just as relaying solutions, it works with symmetric NATs. But unlike \n   plain relaying, relay is only used as the last resort, thereby \n   minimizing the bandwidth and latency issue of relaying.\n - it offers a generic framework for offering and checking address \n   candidates. While the ICE core standard only talks about using STUN \n   and TURN, implementors can add more types of candidates in the ICE \n   offer, for example UDP over TCP or HTTP relays, or even uPnP \n   candidates, and this could be done transparently for the remote \n   peer hence it's compatible and usable even when the remote peer \n   does not support these.\n - it also adds some kind of security particularly against DoS attacks, \n   since media address must be acknowledged before it can be used.\n\n\nHaving said that, ICE is a complex protocol to implement, making \ninteroperability an issue, and at this time of writing we don't see \nmany implementations of it yet. Fortunately, PJNATH has been one of \nthe first hence more mature ICE implementation, being first released\non mid-2007, and we have been testing our implementation at \n<A HREF=\"http://www.sipit.net\">SIP Interoperability Test (SIPit)</A>\nevents regularly, so hopefully we are one of the most stable as well.\n\n\n\\section pjnath PJNATH - The building blocks for effective NAT traversal solution\n\nPJSIP NAT Helper (PJNATH) is a library which contains the implementation \nof standard based NAT traversal solutions. PJNATH can be used as a \nstand-alone library for your software, or you may use PJSUA-LIB library, \na very high level library integrating PJSIP, PJMEDIA, and PJNATH into \nsimple to use APIs.\n\nPJNATH has the following features:\n\n - STUNbis implementation, providing both ready to use STUN-aware socket \n   and framework to implement higher level STUN based protocols such as \n   TURN and ICE.\n - NAT type detection, useful for troubleshooting purposes.\n - TURN implementation.\n - ICE implementation.\n\n\nMore protocols will be implemented in the future.\n\nGo back to \\ref index.\n\n */\n"
  },
  {
    "path": "deps/pjsip/pjnath/docs/doc_samples.h",
    "content": "/* $Id: doc_samples.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n\n/**\n@addtogroup samples_page\n\nSeveral samples that are included in the PJSIP distributions. The screenshots\nbelow were taken on a Windows machine, but the library is very portable and\nit is known to run on platforms such as Linux, MacOS X, Windows Mobile,\nSymbian, and so on.\n\n  - @ref ice_demo_sample\\n\n    This sample demonstrates how to use \\ref PJNATH_ICE_STREAM_TRANSPORT\n    <b>without</b> using signaling protocol such as <b>SIP</b>. It provides \n    interactive user interface to create and manage the ICE sessions as well\n    as to exchange SDP with another ice_demo instance.\\n\\n\n    \\image html ice_demo.jpg \"ice_demo on WinXP\"\n\n  - @ref turn_client_sample\\n\n    This sample demonstrates how to use \\ref PJNATH_TURN_SOCK\n    and also \\ref PJNATH_STUN_SOCK. It provides interactive \n    user interface to manage allocation, permissions, and\n    channel bindings.\\n\\n\n    \\image html pjturn_client.jpg \"pjturn_client on WinXP\"\n\n  - TURN server sample\\n\n    This is a simple sample TURN server application, which\n    we mainly use for testing (as back then there is no TURN\n    server available).\\n\n    The source code for this application are in <tt><b>pjnath/src/pjturn-srv</b></tt>\n    directory.\n\n */\n\n\n/**\n\\page turn_client_sample pjturn-client, a sample TURN client\n\nThis is a simple, interactive TURN client application, with the \nfollowing features:\n - DNS SRV resolution\n - TCP connection to TURN server\n - Optional fingerprint\n\nThis file is pjnath/src/pjturn-client/client_main.c.\n\nScreenshot on WinXP: \\image html pjturn_client.jpg \"pjturn_client on WinXP\"\n\n\\includelineno client_main.c.\n*/\n\n\n/**\n\\page ice_demo_sample ice_demo, an interactive ICE endpoint\n\nThis sample demonstrates how to use \\ref PJNATH_ICE_STREAM_TRANSPORT\n<b>without</b> using signaling protocol such as SIP. It provides\ninteractive user interface to create and manage the ICE sessions as well\nas to exchange SDP with another ice_demo instance.\n\nFeatures of the demo application:\n - supports host, STUN, and TURN candidates\n - disabling of host candidates\n - DNS SRV resolution for STUN and TURN servers\n - TCP connection to TURN server\n - Optional use of fingerprint for TURN\n - prints and parse SDP containing ICE infos\n - exchange SDP with copy/paste\n\nThis file is pjsip-apps/src/samples/icedemo.c\n\nScreenshot on WinXP: \\image html ice_demo.jpg \"ice_demo on WinXP\"\n\n\\includelineno icedemo.c.\n*/\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/docs/doc_stun.h",
    "content": "/* $Id: doc_stun.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n\n/**\n@defgroup PJNATH_STUN STUN: Session Traversal Utilities for NAT\n@ingroup PJNATH\n@brief Open source STUN library\n */\n\n/**\n@defgroup PJNATH_STUN_SOCK STUN-aware socket transport\n@brief STUN aware UDP socket transport\n@ingroup PJNATH_STUN\n */\n\n\n/**\n@defgroup PJNATH_STUN_SESSION STUN session\n@brief STUN client and server session\n@ingroup PJNATH_STUN\n */\n\n/**\n@defgroup PJNATH_STUN_BASE Base STUN objects\n@ingroup PJNATH_STUN\n@brief STUN data structures, objects, and configurations\n\nThese section contains STUN base data structures as well as\nconfigurations. Among other things it contains STUN message\nrepresentation and parsing, transactions, authentication\nframework, as well as compile-time and run-time configurations.\n*/\n\n\n/**\n@addtogroup PJNATH_STUN\n\nThis module contains implementation of STUN library in PJNATH -\nthe open source NAT helper containing STUN and ICE.\n\n\\section stun_org_sec Library organizations\n\nThe STUN part of PJNATH consists of the the following sections (see\n<b>Table of Contents</b> below).\n\n\n\\section stun_using_sec Using the STUN transport\n\nThe \\ref PJNATH_STUN_SOCK is a ready to use object which provides \nsend and receive interface for communicating UDP packets as well as\nmeans to communicate with the STUN server and manage the STUN mapped\naddress.\n\nSome features of the \\ref PJNATH_STUN_SOCK:\n - API to send and receive UDP packets,\n - interface to query the STUN mapped address info, \n - multiplex STUN and non-STUN incoming packets and distinguish between\n   STUN responses that belong to internal requests with application data\n   (the application data may be STUN packets as well),\n - resolution of the STUN server with DNS SRV query (if wanted), \n - maintaining STUN keep-alive, and \n - handle changes in STUN mapped address binding.\n\nPlease see \\ref PJNATH_STUN_SOCK for more information.\n\n\n\\section stun_advanced_sec Advanced use of the STUN components\n\nThe rest of the STUN part of the library provides lower level objects\nwhich can be used to build your own STUN based transport or\nprotocols (officially called STUN usages). These will be explained \nbriefly below.\n\n\n\\subsection stun_sess_sec The STUN session\n\nA STUN session is interactive information exchange between two STUN \nendpoints that lasts for some period of time. It is typically started by\nan outgoing or incoming request, and consists of several requests, \nresponses, and indications. All requests and responses within the session\ntypically share a same credential.\n\nThe \\ref PJNATH_STUN_SESSION is a transport-independent object to\nmanage a client or server STUN session. It is one of the core object in\nPJNATH, and it is used by several higher level objects including the \n\\ref PJNATH_STUN_SOCK, \\ref PJNATH_TURN_SESSION, and \\ref PJNATH_ICE_SESSION.\n\nThe \\ref PJNATH_STUN_SESSION has the following features:\n   - transport independent\n   - authentication management\n   - static or dynamic credential\n   - client transaction management\n   - server transaction management\n\nFor more information, including how to use it please see \n\\ref PJNATH_STUN_SESSION.\n\n\n\\subsection stun_extending_sec Extending STUN to support other usages\n\nAt present, the STUN subsystem in PJNATH supports STUN Binding, TURN, and\nICE usages. If other usages are to be supported, typically you would need\nto add new STUN methods (and the corresponding request and response message\ntypes), attributes, and error codes to \\ref PJNATH_STUN_MSG subsystem of\nPJNATH, as well as implementing the logic for the STUN usage.\n\n\n\\section stunsamples_sec STUN samples\n\nThe \\ref turn_client_sample sample application also contains sample\ncode to use \\ref PJNATH_STUN_SOCK. \n\nAlso see <b>\\ref samples_page</b> for other samples.\n\n\n */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/docs/doc_turn.h",
    "content": "/* $Id: doc_turn.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n\n/**\n@defgroup PJNATH_TURN TURN: Traversal Using Relays around NAT\n@brief TURN protocol implementation\n@ingroup PJNATH\n\n\\section turn_intro_sec Introduction to TURN\n\nWhen a direct communication path cannot be found, it is necessary to\nuse the services of an intermediate host that acts as a relay for the\npackets.  This relay typically sits in the public Internet and relays\npackets between two hosts that both sit behind NATs.\n\nTURN allows a host behind a NAT (called the TURN client) to request that \nanother host (called the TURN server) act as a relay.  The client can \narrange for the server to relay packets to and from certain other hosts\n(called peers) and can control aspects of how the relaying is done.\nThe client does this by obtaining an IP address and port on the\nserver, called the relayed-transport-address.  When a peer sends a\npacket to the relayed-transport-address, the server relays the packet\nto the client.  When the client sends a data packet to the server,\nthe server relays it to the appropriate peer using the relayed-\ntransport-address as the source.\n\n\n\\section turn_op_sec Overview of TURN operations\n\n<b>Discovering TURN server</b>.\\n\nClient learns the IP address of the TURN\nserver either through some privisioning or by querying DNS SRV records\nfor TURN service for the specified domain. Client may use UDP or TCP (or\nTLS) to connect to the TURN server.\n\n<b>Authentication</b>.\\n\nAll TURN operations requires the use of authentication\n(it uses STUN long term autentication method), hence client must be\nconfigured with the correct credential to use the service.\n\n<b>Allocation</b>.\\n\nClient creates one \"relay port\" (or called <b>relayed-transport-address</b>\nin TURN terminology) in the TURN server by sending TURN \\a Allocate request,\nhence this process is called creating allocation. Once the allocation is \nsuccessful, client will be given the IP address and port of the \"relay \nport\" in the Allocate response.\n\n<b>Sending data through the relay</b>.\\n\nOnce allocation has been created, client may send data to any remote \nendpoints (called peers in TURN terminology) via the \"relay port\". It does \nso by sending Send Indication to the TURN server, giving the peer address \nin the indication message. But note that at this point peers are not allowed\nto send data towards the client (via the \"relay port\") before permission is \ninstalled for that peer.\n\n<b>Creating permissions</b>.\\n\nPermission needs to be created in the TURN server so that a peer can send \ndata to the client via the relay port (a peer in this case is identified by\nits IP address). Without this, when the TURN server receives data from the\npeer in the \"relay port\", it will drop this data.\n\n<b>Receiving data from peers</b>.\\n\nOnce permission has been installed for the peer, any data received by the \nTURN server (from that peer) in the \"relay port\" will be relayed back to \nclient by using Data Indication.\n\n<b>Using ChannelData</b>.\\n\nTURN provides optimized framing to the data by using ChannelData \npacketization. The client activates this format by sending ChannelBind \nrequest to the TURN server, which provides (channel) binding which maps a \nparticular peer address with a channel number. Data sent or received to/for\nthis peer will then use ChannelData format instead of Send or Data \nIndications.\n\n<b>Refreshing the allocation, permissions, and channel bindings</b>.\\n\nAllocations, permissions, and channel bindings need to be refreshed\nperiodically by client, or otherwise they will expire.\n\n<b>Destroying the allocation</b>.\\n\nOnce the \"relay port\" is no longer needed, client destroys the allocation\nby sending Refresh request with LIFETIME attribute set to zero.\n\n\n\\section turn_org_sec Library organizations\n\nThe TURN functionalities in PJNATH primarily consist of \n\\ref PJNATH_TURN_SOCK and \\ref PJNATH_TURN_SESSION. Please see more\nbelow.\n\n\n\\section turn_using_sec Using TURN transport\n\nThe \\ref PJNATH_TURN_SOCK is a ready to use object for relaying\napplication data via a TURN server, by managing all the operations\nabove.\n\nAmong other things it provides the following features:\n - resolution of the TURN server with DNS SRV\n - interface to create allocation, permissions, and channel\n   bindings\n - interface to send and receive packets through the relay\n - provides callback to notify the application about incoming data\n - managing the allocation, permissions, and channel bindings\n\nPlease see \\ref PJNATH_TURN_SOCK for more documentation about and\non how to use this object.\n\n\n\\section turn_owntransport_sec Creating custom TURN transport\n\nThe \\ref PJNATH_TURN_SESSION is a transport-independent object to\nmanage a client TURN session. It contains the core logic for managing\nthe TURN client session as listed in TURN operations above, but\nin transport-independent manner (i.e. it doesn't have a socket), so\nthat developer can integrate TURN client functionality into existing\nframework that already has its own means to send and receive data,\nor to support new transport types to TURN, such as TLS.\n\nYou can create your own (custom) TURN transport by wrapping this\ninto your own object, and provide it with the means to send and\nreceive packets.\n\nPlease see \\ref PJNATH_TURN_SESSION for more information.\n\n\n\\section turn_samples_sec Samples\n\nThe \\ref turn_client_sample is a sample application to use the\n\\ref PJNATH_TURN_SOCK. Also there is a sample TURN server in\nthe distribution as well. \n\nAlso see <b>\\ref samples_page</b> for other samples.\n\n */\n\n\n/**\n * @defgroup PJNATH_TURN_SOCK TURN client transport\n * @brief Client transport utilizing TURN relay\n * @ingroup PJNATH_TURN\n */\n\n/**\n * @defgroup PJNATH_TURN_SESSION TURN client session\n * @brief Transport independent TURN client session\n * @ingroup PJNATH_TURN\n */\n"
  },
  {
    "path": "deps/pjsip/pjnath/docs/doxygen.cfg",
    "content": "# Doxyfile 1.3-rc3\r\n\r\n# This file describes the settings to be used by the documentation system\r\n# doxygen (www.doxygen.org) for a project\r\n#\r\n# All text after a hash (#) is considered a comment and will be ignored\r\n# The format is:\r\n#       TAG = value [value, ...]\r\n# For lists items can also be appended using:\r\n#       TAG += value [value, ...]\r\n# Values that contain spaces should be placed between quotes (\" \")\r\n\r\n#---------------------------------------------------------------------------\r\n# General configuration options\r\n#---------------------------------------------------------------------------\r\n\r\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded \r\n# by quotes) that should identify the project.\r\n\r\nPROJECT_NAME           =  \"PJNATH Reference\"\r\n\r\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. \r\n# This could be handy for archiving the generated documentation or \r\n# if some version control system is used.\r\n\r\nPROJECT_NUMBER         = $(PJ_VERSION)\r\n\r\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) \r\n# base path where the generated documentation will be put. \r\n# If a relative path is entered, it will be relative to the location \r\n# where doxygen was started. If left blank the current directory will be used.\r\n\r\nOUTPUT_DIRECTORY       = docs/$(PJ_VERSION)\r\n\r\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all \r\n# documentation generated by doxygen is written. Doxygen will use this \r\n# information to generate all constant output in the proper language. \r\n# The default language is English, other supported languages are: \r\n# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, \r\n# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en \r\n# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, \r\n# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian.\r\n\r\nOUTPUT_LANGUAGE        = English\r\n\r\n# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in \r\n# documentation are documented, even if no documentation was available. \r\n# Private class members and static file members will be hidden unless \r\n# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES\r\n\r\nEXTRACT_ALL            = NO\r\n\r\n# If the EXTRACT_PRIVATE tag is set to YES all private members of a class \r\n# will be included in the documentation.\r\n\r\nEXTRACT_PRIVATE        = NO\r\n\r\n# If the EXTRACT_STATIC tag is set to YES all static members of a file \r\n# will be included in the documentation.\r\n\r\nEXTRACT_STATIC         = NO\r\n\r\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) \r\n# defined locally in source files will be included in the documentation. \r\n# If set to NO only classes defined in header files are included.\r\n\r\nEXTRACT_LOCAL_CLASSES  = YES\r\n\r\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all \r\n# undocumented members of documented classes, files or namespaces. \r\n# If set to NO (the default) these members will be included in the \r\n# various overviews, but no documentation section is generated. \r\n# This option has no effect if EXTRACT_ALL is enabled.\r\n\r\nHIDE_UNDOC_MEMBERS     = NO\r\n\r\n# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all \r\n# undocumented classes that are normally visible in the class hierarchy. \r\n# If set to NO (the default) these class will be included in the various \r\n# overviews. This option has no effect if EXTRACT_ALL is enabled.\r\n\r\nHIDE_UNDOC_CLASSES     = NO\r\n\r\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all \r\n# friend (class|struct|union) declarations. \r\n# If set to NO (the default) these declarations will be included in the \r\n# documentation.\r\n\r\nHIDE_FRIEND_COMPOUNDS  = NO\r\n\r\n# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any \r\n# documentation blocks found inside the body of a function. \r\n# If set to NO (the default) these blocks will be appended to the \r\n# function's detailed documentation block.\r\n\r\nHIDE_IN_BODY_DOCS      = NO\r\n\r\n# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will \r\n# include brief member descriptions after the members that are listed in \r\n# the file and class documentation (similar to JavaDoc). \r\n# Set to NO to disable this.\r\n\r\nBRIEF_MEMBER_DESC      = YES\r\n\r\n# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend \r\n# the brief description of a member or function before the detailed description. \r\n# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the \r\n# brief descriptions will be completely suppressed.\r\n\r\nREPEAT_BRIEF           = NO\r\n\r\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then \r\n# Doxygen will generate a detailed section even if there is only a brief \r\n# description.\r\n\r\nALWAYS_DETAILED_SEC    = NO\r\n\r\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited \r\n# members of a class in the documentation of that class as if those members were \r\n# ordinary class members. Constructors, destructors and assignment operators of \r\n# the base classes will not be shown.\r\n\r\nINLINE_INHERITED_MEMB  = NO\r\n\r\n# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full \r\n# path before files name in the file list and in the header files. If set \r\n# to NO the shortest path that makes the file name unique will be used.\r\n\r\nFULL_PATH_NAMES        = NO\r\n\r\n# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag \r\n# can be used to strip a user defined part of the path. Stripping is \r\n# only done if one of the specified strings matches the left-hand part of \r\n# the path. It is allowed to use relative paths in the argument list.\r\n\r\nSTRIP_FROM_PATH        = \"c:\\project\\pjproject\"\r\n\r\n# The INTERNAL_DOCS tag determines if documentation \r\n# that is typed after a \\internal command is included. If the tag is set \r\n# to NO (the default) then the documentation will be excluded. \r\n# Set it to YES to include the internal documentation.\r\n\r\nINTERNAL_DOCS          = NO\r\n\r\n# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate \r\n# file names in lower case letters. If set to YES upper case letters are also \r\n# allowed. This is useful if you have classes or files whose names only differ \r\n# in case and if your file system supports case sensitive file names. Windows \r\n# users are adviced to set this option to NO.\r\n\r\nCASE_SENSE_NAMES       = YES\r\n\r\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter \r\n# (but less readable) file names. This can be useful is your file systems \r\n# doesn't support long names like on DOS, Mac, or CD-ROM.\r\n\r\nSHORT_NAMES            = NO\r\n\r\n# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen \r\n# will show members with their full class and namespace scopes in the \r\n# documentation. If set to YES the scope will be hidden.\r\n\r\nHIDE_SCOPE_NAMES       = NO\r\n\r\n# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen \r\n# will generate a verbatim copy of the header file for each class for \r\n# which an include is specified. Set to NO to disable this.\r\n\r\nVERBATIM_HEADERS       = YES\r\n\r\n# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen \r\n# will put list of the files that are included by a file in the documentation \r\n# of that file.\r\n\r\nSHOW_INCLUDE_FILES     = NO\r\n\r\n# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen \r\n# will interpret the first line (until the first dot) of a JavaDoc-style \r\n# comment as the brief description. If set to NO, the JavaDoc \r\n# comments  will behave just like the Qt-style comments (thus requiring an \r\n# explict @brief command for a brief description.\r\n\r\nJAVADOC_AUTOBRIEF      = NO\r\n\r\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen \r\n# treat a multi-line C++ special comment block (i.e. a block of //! or /// \r\n# comments) as a brief description. This used to be the default behaviour. \r\n# The new default is to treat a multi-line C++ comment block as a detailed \r\n# description. Set this tag to YES if you prefer the old behaviour instead.\r\n\r\nMULTILINE_CPP_IS_BRIEF = NO\r\n\r\n# If the DETAILS_AT_TOP tag is set to YES then Doxygen \r\n# will output the detailed description near the top, like JavaDoc.\r\n# If set to NO, the detailed description appears after the member \r\n# documentation.\r\n\r\nDETAILS_AT_TOP         = YES\r\n\r\n# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented \r\n# member inherits the documentation from any documented member that it \r\n# reimplements.\r\n\r\nINHERIT_DOCS           = YES\r\n\r\n# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] \r\n# is inserted in the documentation for inline members.\r\n\r\nINLINE_INFO            = YES\r\n\r\n# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen \r\n# will sort the (detailed) documentation of file and class members \r\n# alphabetically by member name. If set to NO the members will appear in \r\n# declaration order.\r\n\r\nSORT_MEMBER_DOCS       = YES\r\n\r\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC \r\n# tag is set to YES, then doxygen will reuse the documentation of the first \r\n# member in the group (if any) for the other members of the group. By default \r\n# all members of a group must be documented explicitly.\r\n\r\nDISTRIBUTE_GROUP_DOC   = NO\r\n\r\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. \r\n# Doxygen uses this value to replace tabs by spaces in code fragments.\r\n\r\nTAB_SIZE               = 8\r\n\r\n# The GENERATE_TODOLIST tag can be used to enable (YES) or \r\n# disable (NO) the todo list. This list is created by putting \\todo \r\n# commands in the documentation.\r\n\r\nGENERATE_TODOLIST      = YES\r\n\r\n# The GENERATE_TESTLIST tag can be used to enable (YES) or \r\n# disable (NO) the test list. This list is created by putting \\test \r\n# commands in the documentation.\r\n\r\nGENERATE_TESTLIST      = YES\r\n\r\n# The GENERATE_BUGLIST tag can be used to enable (YES) or \r\n# disable (NO) the bug list. This list is created by putting \\bug \r\n# commands in the documentation.\r\n\r\nGENERATE_BUGLIST       = YES\r\n\r\n# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or \r\n# disable (NO) the deprecated list. This list is created by putting \r\n# \\deprecated commands in the documentation.\r\n\r\nGENERATE_DEPRECATEDLIST= YES\r\n\r\n# This tag can be used to specify a number of aliases that acts \r\n# as commands in the documentation. An alias has the form \"name=value\". \r\n# For example adding \"sideeffect=\\par Side Effects:\\n\" will allow you to \r\n# put the command \\sideeffect (or @sideeffect) in the documentation, which \r\n# will result in a user defined paragraph with heading \"Side Effects:\". \r\n# You can put \\n's in the value part of an alias to insert newlines.\r\n\r\nALIASES                = \r\n\r\n# The ENABLED_SECTIONS tag can be used to enable conditional \r\n# documentation sections, marked by \\if sectionname ... \\endif.\r\n\r\nENABLED_SECTIONS       = \r\n\r\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines \r\n# the initial value of a variable or define consist of for it to appear in \r\n# the documentation. If the initializer consists of more lines than specified \r\n# here it will be hidden. Use a value of 0 to hide initializers completely. \r\n# The appearance of the initializer of individual variables and defines in the \r\n# documentation can be controlled using \\showinitializer or \\hideinitializer \r\n# command in the documentation regardless of this setting.\r\n\r\nMAX_INITIALIZER_LINES  = 30\r\n\r\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources \r\n# only. Doxygen will then generate output that is more tailored for C. \r\n# For instance some of the names that are used will be different. The list \r\n# of all members will be omitted, etc.\r\n\r\nOPTIMIZE_OUTPUT_FOR_C  = YES\r\n\r\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources \r\n# only. Doxygen will then generate output that is more tailored for Java. \r\n# For instance namespaces will be presented as packages, qualified scopes \r\n# will look different, etc.\r\n\r\nOPTIMIZE_OUTPUT_JAVA   = NO\r\n\r\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated \r\n# at the bottom of the documentation of classes and structs. If set to YES the \r\n# list will mention the files that were used to generate the documentation.\r\n\r\nSHOW_USED_FILES        = YES\r\nTYPEDEF_HIDES_STRUCT\t= YES\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to warning and progress messages\r\n#---------------------------------------------------------------------------\r\n\r\n# The QUIET tag can be used to turn on/off the messages that are generated \r\n# by doxygen. Possible values are YES and NO. If left blank NO is used.\r\n\r\nQUIET                  = NO\r\n\r\n# The WARNINGS tag can be used to turn on/off the warning messages that are \r\n# generated by doxygen. Possible values are YES and NO. If left blank \r\n# NO is used.\r\n\r\nWARNINGS               = YES\r\n\r\n# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings \r\n# for undocumented members. If EXTRACT_ALL is set to YES then this flag will \r\n# automatically be disabled.\r\n\r\nWARN_IF_UNDOCUMENTED   = YES\r\n\r\n# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for \r\n# potential errors in the documentation, such as not documenting some \r\n# parameters in a documented function, or documenting parameters that \r\n# don't exist or using markup commands wrongly.\r\n\r\nWARN_IF_DOC_ERROR      = YES\r\n\r\n# The WARN_FORMAT tag determines the format of the warning messages that \r\n# doxygen can produce. The string should contain the $file, $line, and $text \r\n# tags, which will be replaced by the file and line number from which the \r\n# warning originated and the warning text.\r\n\r\nWARN_FORMAT            = \"$file:$line: $text\"\r\n\r\n# The WARN_LOGFILE tag can be used to specify a file to which warning \r\n# and error messages should be written. If left blank the output is written \r\n# to stderr.\r\n\r\nWARN_LOGFILE           = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the input files\r\n#---------------------------------------------------------------------------\r\n\r\n# The INPUT tag can be used to specify the files and/or directories that contain \r\n# documented source files. You may enter file names like \"myfile.cpp\" or \r\n# directories like \"/usr/src/myproject\". Separate the files or directories \r\n# with spaces.\r\n\r\nINPUT                  =  docs include/pjnath\r\n\r\n# If the value of the INPUT tag contains directories, you can use the \r\n# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \r\n# and *.h) to filter out the source-files in the directories. If left \r\n# blank the following patterns are tested: \r\n# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp \r\n# *.h++ *.idl *.odl\r\n\r\nFILE_PATTERNS          = *.h *.c\r\n\r\n# The RECURSIVE tag can be used to turn specify whether or not subdirectories \r\n# should be searched for input files as well. Possible values are YES and NO. \r\n# If left blank NO is used.\r\n\r\nRECURSIVE              = YES\r\n\r\n# The EXCLUDE tag can be used to specify files and/or directories that should \r\n# excluded from the INPUT source files. This way you can easily exclude a \r\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\r\n\r\nEXCLUDE                = \r\n\r\n# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories \r\n# that are symbolic links (a Unix filesystem feature) are excluded from the input.\r\n\r\nEXCLUDE_SYMLINKS       = NO\r\n\r\n# If the value of the INPUT tag contains directories, you can use the \r\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude \r\n# certain files from those directories.\r\n\r\nEXCLUDE_PATTERNS       = \"*_i.h\" \"*/compat/*\"\r\n\r\n# The EXAMPLE_PATH tag can be used to specify one or more files or \r\n# directories that contain example code fragments that are included (see \r\n# the \\include command).\r\n\r\nEXAMPLE_PATH           = ../pjsip-apps/src/samples src/pjturn-client\r\n\r\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the \r\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \r\n# and *.h) to filter out the source-files in the directories. If left \r\n# blank all files are included.\r\n\r\nEXAMPLE_PATTERNS       = \r\n\r\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be \r\n# searched for input files to be used with the \\include or \\dontinclude \r\n# commands irrespective of the value of the RECURSIVE tag. \r\n# Possible values are YES and NO. If left blank NO is used.\r\n\r\nEXAMPLE_RECURSIVE      = YES\r\n\r\n# The IMAGE_PATH tag can be used to specify one or more files or \r\n# directories that contain image that are included in the documentation (see \r\n# the \\image command).\r\n\r\nIMAGE_PATH             =  docs\r\n\r\n# The INPUT_FILTER tag can be used to specify a program that doxygen should \r\n# invoke to filter for each input file. Doxygen will invoke the filter program \r\n# by executing (via popen()) the command <filter> <input-file>, where <filter> \r\n# is the value of the INPUT_FILTER tag, and <input-file> is the name of an \r\n# input file. Doxygen will then use the output that the filter program writes \r\n# to standard output.\r\n\r\nINPUT_FILTER           = \r\n\r\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using \r\n# INPUT_FILTER) will be used to filter the input files when producing source \r\n# files to browse (i.e. when SOURCE_BROWSER is set to YES).\r\n\r\nFILTER_SOURCE_FILES    = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to source browsing\r\n#---------------------------------------------------------------------------\r\n\r\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will \r\n# be generated. Documented entities will be cross-referenced with these sources.\r\n\r\nSOURCE_BROWSER         = NO\r\n\r\n# Setting the INLINE_SOURCES tag to YES will include the body \r\n# of functions and classes directly in the documentation.\r\n\r\nINLINE_SOURCES         = NO\r\n\r\n# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct \r\n# doxygen to hide any special comment blocks from generated source code \r\n# fragments. Normal C and C++ comments will always remain visible.\r\n\r\nSTRIP_CODE_COMMENTS    = YES\r\n\r\n# If the REFERENCED_BY_RELATION tag is set to YES (the default) \r\n# then for each documented function all documented \r\n# functions referencing it will be listed.\r\n\r\nREFERENCED_BY_RELATION = YES\r\n\r\n# If the REFERENCES_RELATION tag is set to YES (the default) \r\n# then for each documented function all documented entities \r\n# called/used by that function will be listed.\r\n\r\nREFERENCES_RELATION    = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the alphabetical class index\r\n#---------------------------------------------------------------------------\r\n\r\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index \r\n# of all compounds will be generated. Enable this if the project \r\n# contains a lot of classes, structs, unions or interfaces.\r\n\r\nALPHABETICAL_INDEX     = NO\r\n\r\n# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then \r\n# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns \r\n# in which this list will be split (can be a number in the range [1..20])\r\n\r\nCOLS_IN_ALPHA_INDEX    = 5\r\n\r\n# In case all classes in a project start with a common prefix, all \r\n# classes will be put under the same header in the alphabetical index. \r\n# The IGNORE_PREFIX tag can be used to specify one or more prefixes that \r\n# should be ignored while generating the index headers.\r\n\r\nIGNORE_PREFIX          = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the HTML output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_HTML tag is set to YES (the default) Doxygen will \r\n# generate HTML output.\r\n\r\nGENERATE_HTML          = YES\r\n\r\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `html' will be used as the default path.\r\n\r\nHTML_OUTPUT            = html\r\n\r\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for \r\n# each generated HTML page (for example: .htm,.php,.asp). If it is left blank \r\n# doxygen will generate files with .html extension.\r\n\r\nHTML_FILE_EXTENSION    = .htm\r\n\r\n# The HTML_HEADER tag can be used to specify a personal HTML header for \r\n# each generated HTML page. If it is left blank doxygen will generate a \r\n# standard header.\r\n\r\nHTML_HEADER            = docs/header.html\r\n\r\n# The HTML_FOOTER tag can be used to specify a personal HTML footer for \r\n# each generated HTML page. If it is left blank doxygen will generate a \r\n# standard footer.\r\n\r\nHTML_FOOTER            = docs/footer.html\r\n\r\n# The HTML_STYLESHEET tag can be used to specify a user defined cascading \r\n# style sheet that is used by each HTML page. It can be used to \r\n# fine-tune the look of the HTML output. If the tag is left blank doxygen \r\n# will generate a default style sheet\r\n\r\nHTML_STYLESHEET        = docs/doxygen.css\r\n\r\n# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, \r\n# files or namespaces will be aligned in HTML using tables. If set to \r\n# NO a bullet list will be used.\r\n\r\nHTML_ALIGN_MEMBERS     = YES\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, additional index files \r\n# will be generated that can be used as input for tools like the \r\n# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) \r\n# of the generated HTML documentation.\r\n\r\nGENERATE_HTMLHELP      = NO\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can \r\n# be used to specify the file name of the resulting .chm file. You \r\n# can add a path in front of the file if the result should not be \r\n# written to the html output dir.\r\n\r\nCHM_FILE               = \r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can \r\n# be used to specify the location (absolute path including file name) of \r\n# the HTML help compiler (hhc.exe). If non empty doxygen will try to run \r\n# the html help compiler on the generated index.hhp.\r\n\r\nHHC_LOCATION           = \r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag \r\n# controls if a separate .chi index file is generated (YES) or that \r\n# it should be included in the master .chm file (NO).\r\n\r\nGENERATE_CHI           = NO\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag \r\n# controls whether a binary table of contents is generated (YES) or a \r\n# normal table of contents (NO) in the .chm file.\r\n\r\nBINARY_TOC             = NO\r\n\r\n# The TOC_EXPAND flag can be set to YES to add extra items for group members \r\n# to the contents of the Html help documentation and to the tree view.\r\n\r\nTOC_EXPAND             = NO\r\n\r\n# The DISABLE_INDEX tag can be used to turn on/off the condensed index at \r\n# top of each HTML page. The value NO (the default) enables the index and \r\n# the value YES disables it.\r\n\r\nDISABLE_INDEX          = NO\r\n\r\n# This tag can be used to set the number of enum values (range [1..20]) \r\n# that doxygen will group on one line in the generated HTML documentation.\r\n\r\nENUM_VALUES_PER_LINE   = 1\r\n\r\n# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be\r\n# generated containing a tree-like index structure (just like the one that \r\n# is generated for HTML Help). For this to work a browser that supports \r\n# JavaScript, DHTML, CSS and frames is required (for instance Mozilla, \r\n# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are \r\n# probably better off using the HTML help feature.\r\n\r\nGENERATE_TREEVIEW      = NO\r\n\r\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be \r\n# used to set the initial width (in pixels) of the frame in which the tree \r\n# is shown.\r\n\r\nTREEVIEW_WIDTH         = 250\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the LaTeX output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will \r\n# generate Latex output.\r\n\r\nGENERATE_LATEX         = NO\r\n\r\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `latex' will be used as the default path.\r\n\r\nLATEX_OUTPUT           = latex\r\n\r\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be \r\n# invoked. If left blank `latex' will be used as the default command name.\r\n\r\nLATEX_CMD_NAME         = latex\r\n\r\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to \r\n# generate index for LaTeX. If left blank `makeindex' will be used as the \r\n# default command name.\r\n\r\nMAKEINDEX_CMD_NAME     = makeindex\r\n\r\n# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact \r\n# LaTeX documents. This may be useful for small projects and may help to \r\n# save some trees in general.\r\n\r\nCOMPACT_LATEX          = NO\r\n\r\n# The PAPER_TYPE tag can be used to set the paper type that is used \r\n# by the printer. Possible values are: a4, a4wide, letter, legal and \r\n# executive. If left blank a4wide will be used.\r\n\r\nPAPER_TYPE             = a4wide\r\n\r\n# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX \r\n# packages that should be included in the LaTeX output.\r\n\r\nEXTRA_PACKAGES         = \r\n\r\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for \r\n# the generated latex document. The header should contain everything until \r\n# the first chapter. If it is left blank doxygen will generate a \r\n# standard header. Notice: only use this tag if you know what you are doing!\r\n\r\nLATEX_HEADER           = \r\n\r\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated \r\n# is prepared for conversion to pdf (using ps2pdf). The pdf file will \r\n# contain links (just like the HTML output) instead of page references \r\n# This makes the output suitable for online browsing using a pdf viewer.\r\n\r\nPDF_HYPERLINKS         = YES\r\n\r\n# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of \r\n# plain latex in the generated Makefile. Set this option to YES to get a \r\n# higher quality PDF documentation.\r\n\r\nUSE_PDFLATEX           = YES\r\n\r\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\\\batchmode. \r\n# command to the generated LaTeX files. This will instruct LaTeX to keep \r\n# running if errors occur, instead of asking the user for help. \r\n# This option is also used when generating formulas in HTML.\r\n\r\nLATEX_BATCHMODE        = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the RTF output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output \r\n# The RTF output is optimised for Word 97 and may not look very pretty with \r\n# other RTF readers or editors.\r\n\r\nGENERATE_RTF           = NO\r\n\r\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `rtf' will be used as the default path.\r\n\r\nRTF_OUTPUT             = rtf\r\n\r\n# If the COMPACT_RTF tag is set to YES Doxygen generates more compact \r\n# RTF documents. This may be useful for small projects and may help to \r\n# save some trees in general.\r\n\r\nCOMPACT_RTF            = NO\r\n\r\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated \r\n# will contain hyperlink fields. The RTF file will \r\n# contain links (just like the HTML output) instead of page references. \r\n# This makes the output suitable for online browsing using WORD or other \r\n# programs which support those fields. \r\n# Note: wordpad (write) and others do not support links.\r\n\r\nRTF_HYPERLINKS         = NO\r\n\r\n# Load stylesheet definitions from file. Syntax is similar to doxygen's \r\n# config file, i.e. a series of assigments. You only have to provide \r\n# replacements, missing definitions are set to their default value.\r\n\r\nRTF_STYLESHEET_FILE    = \r\n\r\n# Set optional variables used in the generation of an rtf document. \r\n# Syntax is similar to doxygen's config file.\r\n\r\nRTF_EXTENSIONS_FILE    = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the man page output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_MAN tag is set to YES (the default) Doxygen will \r\n# generate man pages\r\n\r\nGENERATE_MAN           = NO\r\n\r\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `man' will be used as the default path.\r\n\r\nMAN_OUTPUT             = man\r\n\r\n# The MAN_EXTENSION tag determines the extension that is added to \r\n# the generated man pages (default is the subroutine's section .3)\r\n\r\nMAN_EXTENSION          = .3\r\n\r\n# If the MAN_LINKS tag is set to YES and Doxygen generates man output, \r\n# then it will generate one additional man file for each entity \r\n# documented in the real man page(s). These additional files \r\n# only source the real man page, but without them the man command \r\n# would be unable to find the correct page. The default is NO.\r\n\r\nMAN_LINKS              = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the XML output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_XML tag is set to YES Doxygen will \r\n# generate an XML file that captures the structure of \r\n# the code including all documentation. Note that this \r\n# feature is still experimental and incomplete at the \r\n# moment.\r\n\r\nGENERATE_XML           = NO\r\n\r\n# The XML_SCHEMA tag can be used to specify an XML schema, \r\n# which can be used by a validating XML parser to check the \r\n# syntax of the XML files.\r\n\r\nXML_SCHEMA             = \r\n\r\n# The XML_DTD tag can be used to specify an XML DTD, \r\n# which can be used by a validating XML parser to check the \r\n# syntax of the XML files.\r\n\r\nXML_DTD                = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options for the AutoGen Definitions output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will \r\n# generate an AutoGen Definitions (see autogen.sf.net) file \r\n# that captures the structure of the code including all \r\n# documentation. Note that this feature is still experimental \r\n# and incomplete at the moment.\r\n\r\nGENERATE_AUTOGEN_DEF   = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the Perl module output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_PERLMOD tag is set to YES Doxygen will \r\n# generate a Perl module file that captures the structure of \r\n# the code including all documentation. Note that this \r\n# feature is still experimental and incomplete at the \r\n# moment.\r\n\r\nGENERATE_PERLMOD       = NO\r\n\r\n# If the PERLMOD_LATEX tag is set to YES Doxygen will generate \r\n# the necessary Makefile rules, Perl scripts and LaTeX code to be able \r\n# to generate PDF and DVI output from the Perl module output.\r\n\r\nPERLMOD_LATEX          = NO\r\n\r\n# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be \r\n# nicely formatted so it can be parsed by a human reader.  This is useful \r\n# if you want to understand what is going on.  On the other hand, if this \r\n# tag is set to NO the size of the Perl module output will be much smaller \r\n# and Perl will parse it just the same.\r\n\r\nPERLMOD_PRETTY         = YES\r\n\r\n# The names of the make variables in the generated doxyrules.make file \r\n# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. \r\n# This is useful so different doxyrules.make files included by the same \r\n# Makefile don't overwrite each other's variables.\r\n\r\nPERLMOD_MAKEVAR_PREFIX = \r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration options related to the preprocessor   \r\n#---------------------------------------------------------------------------\r\n\r\n# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will \r\n# evaluate all C-preprocessor directives found in the sources and include \r\n# files.\r\n\r\nENABLE_PREPROCESSING   = YES\r\n\r\n# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro \r\n# names in the source code. If set to NO (the default) only conditional \r\n# compilation will be performed. Macro expansion can be done in a controlled \r\n# way by setting EXPAND_ONLY_PREDEF to YES.\r\n\r\nMACRO_EXPANSION        = YES\r\n\r\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES \r\n# then the macro expansion is limited to the macros specified with the \r\n# PREDEFINED and EXPAND_AS_PREDEFINED tags.\r\n\r\nEXPAND_ONLY_PREDEF     = NO\r\n\r\n# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files \r\n# in the INCLUDE_PATH (see below) will be search if a #include is found.\r\n\r\nSEARCH_INCLUDES        = YES\r\n\r\n# The INCLUDE_PATH tag can be used to specify one or more directories that \r\n# contain include files that are not input files but should be processed by \r\n# the preprocessor.\r\n\r\nINCLUDE_PATH           = \r\n\r\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard \r\n# patterns (like *.h and *.hpp) to filter out the header-files in the \r\n# directories. If left blank, the patterns specified with FILE_PATTERNS will \r\n# be used.\r\n\r\nINCLUDE_FILE_PATTERNS  = \r\n\r\n# The PREDEFINED tag can be used to specify one or more macro names that \r\n# are defined before the preprocessor is started (similar to the -D option of \r\n# gcc). The argument of the tag is a list of macros of the form: name \r\n# or name=definition (no spaces). If the definition and the = are \r\n# omitted =1 is assumed.\r\n\r\nPREDEFINED             = PJ_DECL(x)=x PJ_DEF(x)=x PJ_IDECL(x)=x \\\r\n\t\t\t PJ_IDEF(x)=x PJ_INLINE(x)=x \\\r\n\t\t\t PJ_DECL_NO_RETURN(x)=x \\\r\n\t\t\t PJ_HAS_HIGH_RES_TIMER=1 \\\r\n\t\t\t PJ_LOG_MAX_LEVEL=4 \\\r\n\t\t\t PJ_HAS_SEMAPHORE=1 \\\r\n\t\t\t PJ_HAS_EVENT_OBJ=1\r\n\r\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then \r\n# this tag can be used to specify a list of macro names that should be expanded. \r\n# The macro definition that is found in the sources will be used. \r\n# Use the PREDEFINED tag if you want to use a different macro definition.\r\n\r\nEXPAND_AS_DEFINED      = \r\n\r\n# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then \r\n# doxygen's preprocessor will remove all function-like macros that are alone \r\n# on a line, have an all uppercase name, and do not end with a semicolon. Such \r\n# function macros are typically used for boiler-plate code, and will confuse the \r\n# parser if not removed.\r\n\r\nSKIP_FUNCTION_MACROS   = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration::addtions related to external references   \r\n#---------------------------------------------------------------------------\r\n\r\n# The TAGFILES tag can be used to specify one or more tagfiles.\r\n\r\nTAGFILES               = ../pjlib/docs/pjlib.tag=../../../pjlib/docs/html ../pjlib-util/docs/pjlib-util.tag=../../../pjlib-util/docs/html ../pjsip/docs/pjsip.tag=../../../pjsip/docs/html ../pjmedia/docs/pjmedia.tag=../../../pjmedia/docs/html\r\n\r\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create \r\n# a tag file that is based on the input files it reads.\r\n\r\nGENERATE_TAGFILE       = ../pjnath/docs/pjnath.tag\r\n\r\n# If the ALLEXTERNALS tag is set to YES all external classes will be listed \r\n# in the class index. If set to NO only the inherited external classes \r\n# will be listed.\r\n\r\nALLEXTERNALS           = NO\r\n\r\n# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed \r\n# in the modules index. If set to NO, only the current project's groups will \r\n# be listed.\r\n\r\nEXTERNAL_GROUPS        = NO\r\n\r\n# The PERL_PATH should be the absolute path and name of the perl script \r\n# interpreter (i.e. the result of `which perl').\r\n\r\n#PERL_PATH              = /usr/bin/perl\r\nPERL_PATH              = /c/Perl/bin/perl\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration options related to the dot tool   \r\n#---------------------------------------------------------------------------\r\n\r\n# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will \r\n# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or \r\n# super classes. Setting the tag to NO turns the diagrams off. Note that this \r\n# option is superceded by the HAVE_DOT option below. This is only a fallback. It is \r\n# recommended to install and use dot, since it yield more powerful graphs.\r\n\r\nCLASS_DIAGRAMS         = NO\r\n\r\n# If set to YES, the inheritance and collaboration graphs will hide \r\n# inheritance and usage relations if the target is undocumented \r\n# or is not a class.\r\n\r\nHIDE_UNDOC_RELATIONS   = YES\r\n\r\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is \r\n# available from the path. This tool is part of Graphviz, a graph visualization \r\n# toolkit from AT&T and Lucent Bell Labs. The other options in this section \r\n# have no effect if this option is set to NO (the default)\r\n\r\nHAVE_DOT               = NO\r\n\r\n# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen \r\n# will generate a graph for each documented class showing the direct and \r\n# indirect inheritance relations. Setting this tag to YES will force the \r\n# the CLASS_DIAGRAMS tag to NO.\r\n\r\nCLASS_GRAPH            = YES\r\n\r\n# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen \r\n# will generate a graph for each documented class showing the direct and \r\n# indirect implementation dependencies (inheritance, containment, and \r\n# class references variables) of the class with other documented classes.\r\n\r\nCOLLABORATION_GRAPH    = YES\r\n\r\n# If set to YES, the inheritance and collaboration graphs will show the \r\n# relations between templates and their instances.\r\n\r\nTEMPLATE_RELATIONS     = YES\r\n\r\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT \r\n# tags are set to YES then doxygen will generate a graph for each documented \r\n# file showing the direct and indirect include dependencies of the file with \r\n# other documented files.\r\n\r\nINCLUDE_GRAPH          = YES\r\n\r\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and \r\n# HAVE_DOT tags are set to YES then doxygen will generate a graph for each \r\n# documented header file showing the documented files that directly or \r\n# indirectly include this file.\r\n\r\nINCLUDED_BY_GRAPH      = YES\r\n\r\n# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen \r\n# will graphical hierarchy of all classes instead of a textual one.\r\n\r\nGRAPHICAL_HIERARCHY    = YES\r\n\r\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images \r\n# generated by dot. Possible values are png, jpg, or gif\r\n# If left blank png will be used.\r\n\r\nDOT_IMAGE_FORMAT       = png\r\n\r\n# The tag DOT_PATH can be used to specify the path where the dot tool can be \r\n# found. If left blank, it is assumed the dot tool can be found on the path.\r\n\r\nDOT_PATH               = \r\n\r\n# The DOTFILE_DIRS tag can be used to specify one or more directories that \r\n# contain dot files that are included in the documentation (see the \r\n# \\dotfile command).\r\n\r\nDOTFILE_DIRS           = \r\n\r\n# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will \r\n# generate a legend page explaining the meaning of the various boxes and \r\n# arrows in the dot generated graphs.\r\n\r\nGENERATE_LEGEND        = YES\r\n\r\n# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will \r\n# remove the intermedate dot files that are used to generate \r\n# the various graphs.\r\n\r\nDOT_CLEANUP            = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration::addtions related to the search engine   \r\n#---------------------------------------------------------------------------\r\n\r\n# The SEARCHENGINE tag specifies whether or not a search engine should be \r\n# used. If set to NO the values of all tags below this one will be ignored.\r\n\r\nSEARCHENGINE           = NO\r\n\r\n# The CGI_NAME tag should be the name of the CGI script that \r\n# starts the search engine (doxysearch) with the correct parameters. \r\n# A script with this name will be generated by doxygen.\r\n\r\n#CGI_NAME               = search.cgi\r\n\r\n# The CGI_URL tag should be the absolute URL to the directory where the \r\n# cgi binaries are located. See the documentation of your http daemon for \r\n# details.\r\n\r\n#CGI_URL                = \r\n\r\n# The DOC_URL tag should be the absolute URL to the directory where the \r\n# documentation is located. If left blank the absolute path to the \r\n# documentation, with file:// prepended to it, will be used.\r\n\r\n#DOC_URL                = \r\n\r\n# The DOC_ABSPATH tag should be the absolute path to the directory where the \r\n# documentation is located. If left blank the directory on the local machine \r\n# will be used.\r\n\r\n#DOC_ABSPATH            = \r\n\r\n# The BIN_ABSPATH tag must point to the directory where the doxysearch binary \r\n# is installed.\r\n\r\n#BIN_ABSPATH            = /usr/local/bin/\r\n\r\n# The EXT_DOC_PATHS tag can be used to specify one or more paths to \r\n# documentation generated for other projects. This allows doxysearch to search \r\n# the documentation for these projects as well.\r\n\r\n#EXT_DOC_PATHS          = \r\n"
  },
  {
    "path": "deps/pjsip/pjnath/docs/doxygen.css",
    "content": "BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {\n\tfont-family: Geneva, Arial, Helvetica, sans-serif;\n}\nBODY,TD {\n       font-size: 80%;\n}\nCODE {\n\tfont-size: 120%;\n       font-family: monospace;\n}\n.fragment, pre {\n\tfont-size: 110%;\n       font-family: monospace;\n}\nH1 {\n\ttext-align: center;\n       font-size: 240%;\n}\nH2 {\n       \tfont-size: 200%;\n\tmargin-top     : 60px;\n}\nH3 {\n       font-size: 160%;\n}\nH4 {\n       font-size: 120%;\n}\nCAPTION { font-weight: bold }\nDIV.qindex {\n\twidth: 100%;\n\tbackground-color: #eeeeff;\n\tborder: 1px solid #b0b0b0;\n\ttext-align: center;\n\tmargin: 2px;\n\tpadding: 2px;\n\tline-height: 140%;\n}\nDIV.nav {\n\twidth: 100%;\n\tbackground-color: #eeeeff;\n\tborder: 1px solid #b0b0b0;\n\ttext-align: center;\n\tmargin: 2px;\n\tpadding: 2px;\n\tline-height: 140%;\n}\nA.qindex {\n       text-decoration: none;\n       font-size: 120%;\n       color: #1A419D;\n}\nA.qindex:visited {\n       text-decoration: none;\n       color: #1A419D\n}\nA.qindex:hover {\n\ttext-decoration: none;\n\tbackground-color: #ddddff;\n}\nA.qindexHL {\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tbackground-color: #6666cc;\n\tcolor: #ffffff;\n\tborder: 1px double #9295C2;\n}\nA.qindexHL:hover {\n\ttext-decoration: none;\n\tbackground-color: #6666cc;\n\tcolor: #ffffff;\n}\nA.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }\nA.el { text-decoration: none; font-weight: bold }\nA.elRef { font-weight: bold }\nA.code:link { text-decoration: none; font-weight: normal; color: #0000FF; }\nA.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}\nA.codeRef:link { font-weight: normal; color: #0000FF}\nA.codeRef:visited { font-weight: normal; color: #0000FF}\nA:hover { text-decoration: none; background-color: #f2f2ff }\nDL.el { margin-left: -1cm }\nPRE.fragment {\n\tborder: 1px solid #CCCCCC;\n\tbackground-color: #f5f5f5;\n\tmargin-top: 4px;\n\tmargin-bottom: 4px;\n\tmargin-left: 2px;\n\tmargin-right: 8px;\n\tpadding-left: 6px;\n\tpadding-right: 6px;\n\tpadding-top: 4px;\n\tpadding-bottom: 4px;\n}\nDIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }\nTD.md { background-color: #F4F4FB; font-weight: bold; }\nTD.mdPrefix {\n       background-color: #F4F4FB;\n       color: #606060;\n\tfont-size: 80%;\n}\nTD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; }\nTD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; }\nDIV.groupHeader {\n       margin-left: 16px;\n       margin-top: 12px;\n       margin-bottom: 6px;\n       font-weight: bold;\n}\nDIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }\nBODY {\n\tbackground: white;\n\tcolor: black;\n\tmargin-right: 20px;\n\tmargin-left: 20px;\n}\nTD.indexkey {\n\tbackground-color: #eeeeff;\n\tfont-weight: bold;\n\tpadding-right  : 10px;\n\tpadding-top    : 2px;\n\tpadding-left   : 10px;\n\tpadding-bottom : 2px;\n\tmargin-left    : 0px;\n\tmargin-right   : 0px;\n\tmargin-top     : 2px;\n\tmargin-bottom  : 2px;\n\tborder: 1px solid #CCCCCC;\n}\nTD.indexvalue {\n\tbackground-color: #eeeeff;\n\tfont-style: italic;\n\tpadding-right  : 10px;\n\tpadding-top    : 2px;\n\tpadding-left   : 10px;\n\tpadding-bottom : 2px;\n\tmargin-left    : 0px;\n\tmargin-right   : 0px;\n\tmargin-top     : 2px;\n\tmargin-bottom  : 2px;\n\tborder: 1px solid #CCCCCC;\n}\nTR.memlist {\n   background-color: #f0f0f0; \n}\nP.formulaDsp { text-align: center; }\nIMG.formulaDsp { }\nIMG.formulaInl { vertical-align: middle; }\nSPAN.keyword       { color: #008000 }\nSPAN.keywordtype   { color: #604020 }\nSPAN.keywordflow   { color: #e08000 }\nSPAN.comment       { color: #800000 }\nSPAN.preprocessor  { color: #806020 }\nSPAN.stringliteral { color: #002080 }\nSPAN.charliteral   { color: #008080 }\n.mdTable {\n\tborder: 1px solid #868686;\n\tbackground-color: #F4F4FB;\n}\n.mdRow {\n\tpadding: 8px 10px;\n}\n.mdescLeft {\n       padding: 0px 8px 4px 8px;\n\tfont-size: 80%;\n\tfont-style: italic;\n\tbackground-color: #FAFAFA;\n\tborder-top: 1px none #E0E0E0;\n\tborder-right: 1px none #E0E0E0;\n\tborder-bottom: 1px none #E0E0E0;\n\tborder-left: 1px none #E0E0E0;\n\tmargin: 0px;\n}\n.mdescRight {\n       padding: 0px 8px 4px 8px;\n\tfont-size: 80%;\n\tfont-style: italic;\n\tbackground-color: #FAFAFA;\n\tborder-top: 1px none #E0E0E0;\n\tborder-right: 1px none #E0E0E0;\n\tborder-bottom: 1px none #E0E0E0;\n\tborder-left: 1px none #E0E0E0;\n\tmargin: 0px;\n}\n.memItemLeft {\n\tpadding: 1px 0px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: solid;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.memItemRight {\n\tpadding: 1px 8px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: solid;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.memTemplItemLeft {\n\tpadding: 1px 0px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: none;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.memTemplItemRight {\n\tpadding: 1px 8px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: none;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.memTemplParams {\n\tpadding: 1px 0px 0px 8px;\n\tmargin: 4px;\n\tborder-top-width: 1px;\n\tborder-right-width: 1px;\n\tborder-bottom-width: 1px;\n\tborder-left-width: 1px;\n\tborder-top-color: #E0E0E0;\n\tborder-right-color: #E0E0E0;\n\tborder-bottom-color: #E0E0E0;\n\tborder-left-color: #E0E0E0;\n\tborder-top-style: solid;\n\tborder-right-style: none;\n\tborder-bottom-style: none;\n\tborder-left-style: none;\n       color: #606060;\n\tbackground-color: #FAFAFA;\n\tfont-size: 80%;\n}\n.search     { color: #003399;\n              font-weight: bold;\n}\nFORM.search {\n              margin-bottom: 0px;\n              margin-top: 0px;\n}\nINPUT.search { font-size: 75%;\n               color: #000080;\n               font-weight: normal;\n               background-color: #eeeeff;\n}\nTD.tiny      { font-size: 75%;\n}\na {\n\tcolor: #252E78;\n}\na:visited {\n\tcolor: #3D2185;\n}\n.dirtab { padding: 4px;\n          border-collapse: collapse;\n          border: 1px solid #b0b0b0;\n}\nTH.dirtab { background: #eeeeff;\n            font-weight: bold;\n}\nHR { height: 1px;\n     border: none;\n     border-top: 1px solid black;\n}\n"
  },
  {
    "path": "deps/pjsip/pjnath/docs/footer.html",
    "content": "\t</TD></TD></TABLE>\r\n<p>&nbsp;</p>\r\n<hr><center>\r\nPJNATH - Open Source NAT traversal helper library supporting STUN, TURN, and ICE<br>\r\nCopyright (C) 2006-2009 Teluu Inc.\r\n</center>\r\n\r\n\r\n<!--#include virtual=\"/footer.html\" -->\r\n\r\n</BODY>\r\n</HTML>\r\n"
  },
  {
    "path": "deps/pjsip/pjnath/docs/header.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=iso-8859-1\">\r\n<title>$title ($projectnumber)</title>\r\n<link href=\"/style/style.css\" rel=\"stylesheet\" type=\"text/css\">\r\n</head><body>\r\n\t<!--#include virtual=\"/header.html\" -->\r\n\t<TABLE border=0 width=\"90%\"><TR><TD>\r\n\t<p><A HREF=\"/\">Home</A> --&gt; <A HREF=\"/docs.htm\">Documentations</A> --&gt; <A HREF=\"/pjnath/docs/html/index.htm\">PJNATH Reference</A></p>\r\n\r\n\r\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/config.h",
    "content": "/* $Id: config.h 4199 2012-07-05 10:52:55Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_CONFIG_H__\n#define __PJNATH_CONFIG_H__\n\n\n/**\n * @file config.h\n * @brief Compile time settings\n */\n\n#include <pj/types.h>\n\n/**\n * @defgroup PJNATH_CONFIG Compile-time configurations\n * @brief Various compile time settings\n * @ingroup PJNATH_STUN_BASE\n * @{\n */\n\n\n/* **************************************************************************\n * GENERAL\n */\n\n/**\n * The log level for PJNATH error display.\n *\n * default 1\n */\n#ifndef PJNATH_ERROR_LEVEL\n#   define PJNATH_ERROR_LEVEL\t\t\t    1\n#endif\n\n\n/* **************************************************************************\n * STUN CONFIGURATION\n */\n\n/**\n * Maximum number of attributes in the STUN packet (for the new STUN\n * library).\n *\n * Default: 16\n */\n#ifndef PJ_STUN_MAX_ATTR\n#   define PJ_STUN_MAX_ATTR\t\t\t    16\n#endif\n\n/**\n * The default initial STUN round-trip time estimation (the RTO value\n * in RFC 3489-bis), in miliseconds. \n * This value is used to control the STUN request \n * retransmit time. The initial value of retransmission interval \n * would be set to this value, and will be doubled after each\n * retransmission.\n */\n#ifndef PJ_STUN_RTO_VALUE\n#   define PJ_STUN_RTO_VALUE\t\t\t    100\n#endif\n\n\n/**\n * The STUN transaction timeout value, in miliseconds.\n * After the last retransmission is sent and if no response is received \n * after this time, the STUN transaction will be considered to have failed.\n *\n * The default value is 16x RTO (as per RFC 3489-bis).\n */\n#ifndef PJ_STUN_TIMEOUT_VALUE\n#   define PJ_STUN_TIMEOUT_VALUE\t\t    (16 * PJ_STUN_RTO_VALUE)\n#endif\n\n\n/**\n * Maximum number of STUN transmission count.\n *\n * Default: 7 (as per RFC 3489-bis)\n */\n#ifndef PJ_STUN_MAX_TRANSMIT_COUNT\n#   define PJ_STUN_MAX_TRANSMIT_COUNT\t\t    7\n#endif\n\n\n/**\n * Duration to keep response in the cache, in msec.\n *\n * Default: 10000 (as per RFC 3489-bis)\n */\n#ifndef PJ_STUN_RES_CACHE_DURATION\n#   define PJ_STUN_RES_CACHE_DURATION\t\t    10000\n#endif\n\n\n/**\n * Maximum size of STUN message.\n */\n#ifndef PJ_STUN_MAX_PKT_LEN\n#   define PJ_STUN_MAX_PKT_LEN\t\t\t    800\n#endif\n\n\n/**\n * Default STUN port as defined by RFC 3489.\n */\n#define PJ_STUN_PORT\t\t\t\t    3478\n\n\n/**\n * Padding character for string attributes.\n *\n * Default: ASCII 0\n */\n#ifndef PJ_STUN_STRING_ATTR_PAD_CHR\n#   define PJ_STUN_STRING_ATTR_PAD_CHR\t\t    0\n#endif\n\n\n/**\n * Enable pre-RFC3489bis-07 style of STUN MESSAGE-INTEGRITY and FINGERPRINT\n * calculation. By default this should be disabled since the calculation is\n * not backward compatible with current STUN specification.\n */\n#ifndef PJ_STUN_OLD_STYLE_MI_FINGERPRINT\n#   define PJ_STUN_OLD_STYLE_MI_FINGERPRINT\t    0\n#endif\n\n\n/* **************************************************************************\n * STUN TRANSPORT CONFIGURATION\n */\n\n/**\n * The packet buffer size for the STUN transport.\n */\n#ifndef PJ_STUN_SOCK_PKT_LEN\n#   define PJ_STUN_SOCK_PKT_LEN\t\t\t    2000\n#endif\n\n\n/**\n * The duration of the STUN keep-alive period, in seconds.\n */\n#ifndef PJ_STUN_KEEP_ALIVE_SEC\n#   define PJ_STUN_KEEP_ALIVE_SEC\t\t    15\n#endif\n\n\n/* **************************************************************************\n * TURN CONFIGURATION\n */\n\n/**\n * Maximum DNS SRV entries to be processed in the DNS SRV response\n */\n#ifndef PJ_TURN_MAX_DNS_SRV_CNT\n#   define PJ_TURN_MAX_DNS_SRV_CNT\t\t    4\n#endif\n\n\n/**\n * Maximum TURN packet size to be supported.\n */\n#ifndef PJ_TURN_MAX_PKT_LEN\n#   define PJ_TURN_MAX_PKT_LEN\t\t\t    3000\n#endif\n\n\n/**\n * The TURN permission lifetime setting. This value should be taken from the\n * TURN protocol specification.\n */\n#ifndef PJ_TURN_PERM_TIMEOUT\n#   define PJ_TURN_PERM_TIMEOUT\t\t\t    300\n#endif\n\n\n/**\n * The TURN channel binding lifetime. This value should be taken from the\n * TURN protocol specification.\n */\n#ifndef PJ_TURN_CHANNEL_TIMEOUT\n#   define PJ_TURN_CHANNEL_TIMEOUT\t\t    600\n#endif\n\n\n/**\n * Number of seconds to refresh the permission/channel binding before the \n * permission/channel binding expires. This value should be greater than \n * PJ_TURN_PERM_TIMEOUT setting.\n */\n#ifndef PJ_TURN_REFRESH_SEC_BEFORE\n#   define PJ_TURN_REFRESH_SEC_BEFORE\t\t    60\n#endif\n\n\n/**\n * The TURN session timer heart beat interval. When this timer occurs, the \n * TURN session will scan all the permissions/channel bindings to see which\n * need to be refreshed.\n */\n#ifndef PJ_TURN_KEEP_ALIVE_SEC\n#   define PJ_TURN_KEEP_ALIVE_SEC\t\t    15\n#endif\n\n\n/* **************************************************************************\n * ICE CONFIGURATION\n */\n\n/**\n * Maximum number of ICE candidates.\n *\n * Default: 16\n */\n#ifndef PJ_ICE_MAX_CAND\n#   define PJ_ICE_MAX_CAND\t\t\t    16\n#endif\n\n\n/**\n * Maximum number of candidates for each ICE stream transport component.\n *\n * Default: 8\n */\n#ifndef PJ_ICE_ST_MAX_CAND\n#   define PJ_ICE_ST_MAX_CAND\t\t\t    8\n#endif\n\n\n/**\n * The number of bits to represent component IDs. This will affect\n * the maximum number of components (PJ_ICE_MAX_COMP) value.\n */\n#ifndef PJ_ICE_COMP_BITS\n#   define PJ_ICE_COMP_BITS\t\t\t    1\n#endif\n\n\n/**\n * Maximum number of ICE components.\n */\n#define PJ_ICE_MAX_COMP\t\t\t\t    (2<<PJ_ICE_COMP_BITS)\n\n/**\n * Use the priority value according to the ice-draft.\n */\n#ifndef PJNATH_ICE_PRIO_STD\n#   define PJNATH_ICE_PRIO_STD\t\t\t    1\n#endif\n\n\n/**\n * The number of bits to represent candidate type preference.\n */\n#ifndef PJ_ICE_CAND_TYPE_PREF_BITS\n#   if PJNATH_ICE_PRIO_STD\n#\tdefine PJ_ICE_CAND_TYPE_PREF_BITS\t    8\n#   else\n#\tdefine PJ_ICE_CAND_TYPE_PREF_BITS\t    2\n#   endif\n#endif\n\n\n/**\n * The number of bits to represent ICE candidate's local preference. The\n * local preference is used to specify preference among candidates with\n * the same type, and ICE draft suggests 65535 as the default local \n * preference, which means we need 16 bits to represent the value. But \n * since we don't have the facility to specify local preference, we'll\n * just disable this feature and let the preference sorted by the \n * type only.\n *\n * Default: 0\n */\n#ifndef PJ_ICE_LOCAL_PREF_BITS\n#   define PJ_ICE_LOCAL_PREF_BITS\t\t    0\n#endif\n\n\n/**\n * Maximum number of ICE checks.\n *\n * Default: 32\n */\n#ifndef PJ_ICE_MAX_CHECKS\n#   define PJ_ICE_MAX_CHECKS\t\t\t    32\n#endif\n\n\n/**\n * Default timer interval (in miliseconds) for starting ICE periodic checks.\n *\n * Default: 20\n */\n#ifndef PJ_ICE_TA_VAL\n#   define PJ_ICE_TA_VAL\t\t\t    20\n#endif\n\n\n/**\n * According to ICE Section 8.2. Updating States, if an In-Progress pair in \n * the check list is for the same component as a nominated pair, the agent \n * SHOULD cease retransmissions for its check if its pair priority is lower\n * than the lowest priority nominated pair for that component.\n *\n * If a higher priority check is In Progress, this rule would cause that\n * check to be performed even when it most likely will fail.\n *\n * The macro here controls if ICE session should cancel all In Progress \n * checks for the same component regardless of its priority.\n *\n * Default: 1 (yes, cancel all)\n */\n#ifndef PJ_ICE_CANCEL_ALL\n#   define PJ_ICE_CANCEL_ALL\t\t\t    1\n#endif\n\n\n/**\n * For a controlled agent, specify how long it wants to wait (in milliseconds)\n * for the controlling agent to complete sending connectivity check with\n * nominated flag set to true for all components after the controlled agent\n * has found that all connectivity checks in its checklist have been completed\n * and there is at least one successful (but not nominated) check for every\n * component.\n *\n * When selecting the value, bear in mind that the connectivity check from\n * controlling agent may be delayed because of delay in receiving SDP answer\n * from the controlled agent.\n *\n * Application may set this value to -1 to disable this timer.\n *\n * Default: 10000 (milliseconds)\n */\n#ifndef ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT\n#   define ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT\t10000\n#endif\n\n\n/**\n * For controlling agent if it uses regular nomination, specify the delay to\n * perform nominated check (connectivity check with USE-CANDIDATE attribute)\n * after all components have a valid pair.\n *\n * Default: 4*PJ_STUN_RTO_VALUE (milliseconds)\n */\n#ifndef PJ_ICE_NOMINATED_CHECK_DELAY\n#   define PJ_ICE_NOMINATED_CHECK_DELAY\t\t    (4*PJ_STUN_RTO_VALUE)\n#endif\n\n\n/**\n * Minimum interval value to be used for sending STUN keep-alive on the ICE\n * session, in seconds. This minimum interval, plus a random value\n * which maximum is PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND, specify the actual interval\n * of the STUN keep-alive.\n *\n * Default: 15 seconds\n *\n * @see PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND\n */\n#ifndef PJ_ICE_SESS_KEEP_ALIVE_MIN\n#   define PJ_ICE_SESS_KEEP_ALIVE_MIN\t\t    20\n#endif\n\n/* Warn about deprecated macro */\n#ifdef PJ_ICE_ST_KEEP_ALIVE_MIN\n#   error PJ_ICE_ST_KEEP_ALIVE_MIN is deprecated\n#endif\n\n/**\n * To prevent STUN keep-alives to be sent simultaneously, application should\n * add random interval to minimum interval (PJ_ICE_SESS_KEEP_ALIVE_MIN). This\n * setting specifies the maximum random value to be added to the minimum\n * interval, in seconds.\n *\n * Default: 5 seconds\n *\n * @see PJ_ICE_SESS_KEEP_ALIVE_MIN\n */\n#ifndef PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND\n#   define PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND\t    5\n#endif\n\n/* Warn about deprecated macro */\n#ifdef PJ_ICE_ST_KEEP_ALIVE_MAX_RAND\n#   error PJ_ICE_ST_KEEP_ALIVE_MAX_RAND is deprecated\n#endif\n\n\n/**\n * This constant specifies the length of random string generated for ICE\n * ufrag and password.\n *\n * Default: 8 (characters)\n */\n#ifndef PJ_ICE_UFRAG_LEN\n#   define PJ_ICE_UFRAG_LEN\t\t\t    8\n#endif\n\n\n/** ICE session pool initial size. */\n#ifndef PJNATH_POOL_LEN_ICE_SESS\n#   define PJNATH_POOL_LEN_ICE_SESS\t\t    512\n#endif\n\n/** ICE session pool increment size */\n#ifndef PJNATH_POOL_INC_ICE_SESS\n#   define PJNATH_POOL_INC_ICE_SESS\t\t    512\n#endif\n\n/** ICE stream transport pool initial size. */\n#ifndef PJNATH_POOL_LEN_ICE_STRANS\n#   define PJNATH_POOL_LEN_ICE_STRANS\t\t    1000\n#endif\n\n/** ICE stream transport pool increment size */\n#ifndef PJNATH_POOL_INC_ICE_STRANS\n#   define PJNATH_POOL_INC_ICE_STRANS\t\t    512\n#endif\n\n/** NAT detect pool initial size */\n#ifndef PJNATH_POOL_LEN_NATCK\n#   define PJNATH_POOL_LEN_NATCK\t\t    512\n#endif\n\n/** NAT detect pool increment size */\n#ifndef PJNATH_POOL_INC_NATCK\n#   define PJNATH_POOL_INC_NATCK\t\t    512\n#endif\n\n/** STUN session pool initial size */\n#ifndef PJNATH_POOL_LEN_STUN_SESS\n#   define PJNATH_POOL_LEN_STUN_SESS\t\t    1000\n#endif\n\n/** STUN session pool increment size */\n#ifndef PJNATH_POOL_INC_STUN_SESS\n#   define PJNATH_POOL_INC_STUN_SESS\t\t    1000\n#endif\n\n/** STUN session transmit data pool initial size */\n#ifndef PJNATH_POOL_LEN_STUN_TDATA\n#   define PJNATH_POOL_LEN_STUN_TDATA\t\t    1000\n#endif\n\n/** STUN session transmit data pool increment size */\n#ifndef PJNATH_POOL_INC_STUN_TDATA\n#   define PJNATH_POOL_INC_STUN_TDATA\t\t    1000\n#endif\n\n/** TURN session initial pool size */\n#ifndef PJNATH_POOL_LEN_TURN_SESS\n#   define PJNATH_POOL_LEN_TURN_SESS\t\t    1000\n#endif\n\n/** TURN session pool increment size */\n#ifndef PJNATH_POOL_INC_TURN_SESS\n#   define PJNATH_POOL_INC_TURN_SESS\t\t    1000\n#endif\n\n/** TURN socket initial pool size */\n#ifndef PJNATH_POOL_LEN_TURN_SOCK\n#   define PJNATH_POOL_LEN_TURN_SOCK\t\t    1000\n#endif\n\n/** TURN socket pool increment size */\n#ifndef PJNATH_POOL_INC_TURN_SOCK\n#   define PJNATH_POOL_INC_TURN_SOCK\t\t    1000\n#endif\n\n/** Default STUN software name */\n#ifndef PJNATH_STUN_SOFTWARE_NAME\n#   define PJNATH_MAKE_SW_NAME(a,b,c,d)     \"pjnath-\" #a \".\" #b \".\" #c d\n#   define PJNATH_MAKE_SW_NAME2(a,b,c,d)    PJNATH_MAKE_SW_NAME(a,b,c,d)\n#   define PJNATH_STUN_SOFTWARE_NAME        PJNATH_MAKE_SW_NAME2( \\\n\t\t\t\t\t\t    PJ_VERSION_NUM_MAJOR, \\\n\t\t\t\t\t\t    PJ_VERSION_NUM_MINOR, \\\n\t\t\t\t\t\t    PJ_VERSION_NUM_REV, \\\n\t\t\t\t\t\t    PJ_VERSION_NUM_EXTRA)\n#endif\n\n/**\n * @}\n */\n\n#endif\t/* __PJNATH_CONFIG_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/errno.h",
    "content": "/* $Id: errno.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_ERRNO_H__\n#define __PJNATH_ERRNO_H__\n\n/**\n * @file errno.h\n * @brief PJNATH specific error codes\n */\n\n#include <pj/errno.h>\n\n/**\n * @defgroup PJNATH_ERROR NAT Helper Library Error Codes\n * @brief PJNATH specific error code constants\n * @ingroup PJNATH_STUN_BASE\n * @{\n */\n\n/**\n * Start of error code relative to PJ_ERRNO_START_USER.\n * This value is 370000.\n */\n#define PJNATH_ERRNO_START    (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*4)\n\n\n/************************************************************\n * STUN MESSAGING ERRORS\n ***********************************************************/\n\n/**\n * Map STUN error code (300-699) into pj_status_t error space.\n */\n#define PJ_STATUS_FROM_STUN_CODE(code)\t(PJNATH_ERRNO_START+code)\n\n/**\n * @hideinitializer\n * Invalid STUN message\n */\n#define PJNATH_EINSTUNMSG\t    (PJNATH_ERRNO_START+1)  /* 370001 */\n/**\n * @hideinitializer\n * Invalid STUN message length.\n */\n#define PJNATH_EINSTUNMSGLEN\t    (PJNATH_ERRNO_START+2)  /* 370002 */\n/**\n * @hideinitializer\n * Invalid or unexpected STUN message type\n */\n#define\tPJNATH_EINSTUNMSGTYPE\t    (PJNATH_ERRNO_START+3)  /* 370003 */\n/**\n * @hideinitializer\n * STUN transaction has timed out\n */\n#define PJNATH_ESTUNTIMEDOUT\t    (PJNATH_ERRNO_START+4)  /* 370004 */\n\n\n/**\n * @hideinitializer\n * Too many STUN attributes.\n */\n#define PJNATH_ESTUNTOOMANYATTR\t    (PJNATH_ERRNO_START+21) /* 370021 */\n/**\n * @hideinitializer\n * Invalid STUN attribute length.\n */\n#define PJNATH_ESTUNINATTRLEN\t    (PJNATH_ERRNO_START+22) /* 370022 */\n/**\n * @hideinitializer\n * Found duplicate STUN attribute.\n */\n#define PJNATH_ESTUNDUPATTR\t    (PJNATH_ERRNO_START+23) /* 370023 */\n\n/**\n * @hideinitializer\n * STUN FINGERPRINT verification failed\n */\n#define PJNATH_ESTUNFINGERPRINT\t    (PJNATH_ERRNO_START+30) /* 370030 */\n/**\n * @hideinitializer\n * Invalid STUN attribute after MESSAGE-INTEGRITY.\n */\n#define PJNATH_ESTUNMSGINTPOS\t    (PJNATH_ERRNO_START+31) /* 370031 */\n/**\n * @hideinitializer\n * Invalid STUN attribute after FINGERPRINT.\n */\n#define PJNATH_ESTUNFINGERPOS\t    (PJNATH_ERRNO_START+33) /* 370033 */\n\n\n/**\n * @hideinitializer\n * STUN (XOR-)MAPPED-ADDRESS attribute not found\n */\n#define PJNATH_ESTUNNOMAPPEDADDR    (PJNATH_ERRNO_START+40) /* 370040 */\n/**\n * @hideinitializer\n * STUN IPv6 attribute not supported\n */\n#define PJNATH_ESTUNIPV6NOTSUPP\t    (PJNATH_ERRNO_START+41) /* 370041 */\n/**\n * @hideinitializer\n * Invalid address family value in STUN message.\n */\n#define PJNATH_EINVAF\t\t    (PJNATH_ERRNO_START+42) /* 370042 */\n\n/**\n * @hideinitializer\n * Invalid STUN server or server not configured.\n */\n#define PJNATH_ESTUNINSERVER\t    (PJNATH_ERRNO_START+50) /* 370050 */\n\n\n/************************************************************\n * STUN SESSION/TRANSPORT ERROR CODES\n ***********************************************************/\n/**\n * @hideinitializer\n * STUN object has been destoyed.\n */\n#define PJNATH_ESTUNDESTROYED\t    (PJNATH_ERRNO_START+60) /* 370060 */\n\n\n/************************************************************\n * ICE ERROR CODES\n ***********************************************************/\n\n/**\n * @hideinitializer\n * ICE session not available\n */\n#define PJNATH_ENOICE\t\t    (PJNATH_ERRNO_START+80) /* 370080 */\n/**\n * @hideinitializer\n * ICE check is in progress\n */\n#define PJNATH_EICEINPROGRESS\t    (PJNATH_ERRNO_START+81) /* 370081 */\n/**\n * @hideinitializer\n * This error indicates that ICE connectivity check has failed, because\n * there is at least one ICE component that does not have a valid check.\n * Normally this happens because the network topology had caused the\n * connectivity check to fail (e.g. no route between the two agents),\n * however other reasons may include software incompatibility between\n * the two agents, or incomplete candidates gathered by the agent(s).\n */\n#define PJNATH_EICEFAILED\t    (PJNATH_ERRNO_START+82) /* 370082 */\n/**\n * @hideinitializer\n * Default destination does not match any ICE candidates\n */\n#define PJNATH_EICEMISMATCH\t    (PJNATH_ERRNO_START+83) /* 370083 */\n/**\n * @hideinitializer\n * Invalid ICE component ID\n */\n#define PJNATH_EICEINCOMPID\t    (PJNATH_ERRNO_START+86) /* 370086 */\n/**\n * @hideinitializer\n * Invalid ICE candidate ID\n */\n#define PJNATH_EICEINCANDID\t    (PJNATH_ERRNO_START+87) /* 370087 */\n/**\n * @hideinitializer\n * Source address mismatch. This error occurs if the source address\n * of the response for ICE connectivity check is different than\n * the destination address of the request.\n */\n#define PJNATH_EICEINSRCADDR\t    (PJNATH_ERRNO_START+88) /* 370088 */\n/**\n * @hideinitializer\n * Missing ICE SDP attribute\n */\n#define PJNATH_EICEMISSINGSDP\t    (PJNATH_ERRNO_START+90) /* 370090 */\n/**\n * @hideinitializer\n * Invalid SDP \"candidate\" attribute\n */\n#define PJNATH_EICEINCANDSDP\t    (PJNATH_ERRNO_START+91) /* 370091 */\n/**\n * @hideinitializer\n * No host candidate associated with srflx. This error occurs when\n * a server reflexive candidate is added without the matching \n * host candidate.\n */\n#define PJNATH_EICENOHOSTCAND\t    (PJNATH_ERRNO_START+92) /* 370092 */\n/**\n * @hideinitializer\n * Controlled agent timed-out in waiting for the controlling agent to \n * send nominated check after all connectivity checks have completed.\n */\n#define PJNATH_EICENOMTIMEOUT\t    (PJNATH_ERRNO_START+93) /* 370093 */\n\n/************************************************************\n * TURN ERROR CODES\n ***********************************************************/\n/**\n * @hideinitializer\n * Invalid or unsupported TURN transport.\n */\n#define PJNATH_ETURNINTP\t    (PJNATH_ERRNO_START+120) /* 370120 */\n\n\n\n/**\n * @}\n */\n\n#endif\t/* __PJNATH_ERRNO_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/ice_session.h",
    "content": "/* $Id: ice_session.h 4360 2013-02-21 11:26:35Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_ICE_SESSION_H__\n#define __PJNATH_ICE_SESSION_H__\n\n/**\n * @file ice_session.h\n * @brief ICE session management\n */\n#include <pjnath/types.h>\n#include <pjnath/stun_session.h>\n#include <pjnath/errno.h>\n#include <pj/sock.h>\n#include <pj/timer.h>\n\nPJ_BEGIN_DECL\n\n\n/**\n * @addtogroup PJNATH_ICE_SESSION\n * @{\n *\n * This module describes #pj_ice_sess, a transport independent ICE session,\n * part of PJNATH - the Open Source NAT helper library.\n *\n * \\section pj_ice_sess_sec ICE Session\n *\n * An ICE session, represented by #pj_ice_sess structure, is the lowest \n * abstraction of ICE in PJNATH, and it is used to perform and manage\n * connectivity checks of transport address candidates <b>within a\n * single media stream</b> (note: this differs from what is described\n * in ICE draft, where an ICE session manages the whole media sessions\n * rather than just a single stream).\n *\n * The ICE session described here is independent from any transports,\n * meaning that the actual network I/O for this session would have to\n * be performed by the application, or higher layer abstraction. \n * Using this framework, application would give any incoming packets to\n * the ICE session, and it would provide the ICE session with a callback\n * to send outgoing message.\n *\n * For higher abstraction of ICE where transport is included, please \n * see \\ref PJNATH_ICE_STREAM_TRANSPORT.\n *\n * \\subsection pj_ice_sess_using_sec Using The ICE Session\n *\n * The steps below describe how to use ICE session. Alternatively application\n * can use the higher level ICE API, \\ref PJNATH_ICE_STREAM_TRANSPORT,\n * which has provided the integration of ICE with socket transport.\n *\n * The steps to use ICE session is similar for both offerer and\n * answerer:\n * - create ICE session with #pj_ice_sess_create(). Among other things,\n *   application needs to specify:\n *\t- STUN configuration (pj_stun_config), containing STUN settings\n *\t  such as timeout values and the instances of timer heap and\n *\t  ioqueue.\n *\t- Session name, useful for identifying this session in the log.\n *\t- Initial ICE role (#pj_ice_sess_role). The role can be changed\n *\t  at later time with #pj_ice_sess_change_role(), and ICE session\n *\t  can also change its role automatically when it detects role\n *\t  conflict.\n *\t- Number of components in the media session.\n *\t- Callback to receive ICE events (#pj_ice_sess_cb)\n *\t- Optional local ICE username and password. If these arguments\n *\t  are NULL, they will be generated randomly.\n * - Add local candidates for each component, with #pj_ice_sess_add_cand().\n *   A candidate is represented with #pj_ice_sess_cand structure.\n *   Each component must be provided with at least one candidate, and\n *   all components must have the same number of candidates. Failing\n *   to comply with this will cause failure during pairing process.\n * - Create offer to describe local ICE candidates. ICE session does not\n *   provide a function to create such offer, but application should be\n *   able to create one since it knows about all components and candidates.\n *   If application uses \\ref PJNATH_ICE_STREAM_TRANSPORT, it can\n *   enumerate local candidates by calling #pj_ice_strans_enum_cands().\n *   Application may use #pj_ice_sess_find_default_cand() to let ICE\n *   session chooses the default transport address to be used in SDP\n *   c= and m= lines.\n * - Send the offer to remote endpoint using signaling such as SIP.\n * - Once application has received the answer, it should parse this\n *   answer, build array of remote candidates, and create check lists by\n *   calling #pj_ice_sess_create_check_list(). This process is known as\n *   pairing the candidates, and will result in the creation of check lists.\n * - Once checklist has been created, application then can call\n *   #pj_ice_sess_start_check() to instruct ICE session to start\n *   performing connectivity checks. The ICE session performs the\n *   connectivity checks by processing each check in the checklists.\n * - Application will be notified about the result of ICE connectivity\n *   checks via the callback that was given in #pj_ice_sess_create()\n *   above.\n *\n * To send data, application calls #pj_ice_sess_send_data(). If ICE\n * negotiation has not completed, ICE session would simply drop the data,\n * and return error to caller. If ICE negotiation has completed\n * successfully, ICE session will in turn call the \\a on_tx_pkt\n * callback of #pj_ice_sess_cb instance that was previously registered\n * in #pj_ice_sess_create() above.\n *\n * When application receives any packets on the underlying sockets, it\n * must call #pj_ice_sess_on_rx_pkt(). The ICE session will inspect the\n * packet to decide whether to process it locally (if the packet is a\n * STUN message and is part of ICE session) or otherwise pass it back to\n * application via \\a on_rx_data callback.\n */\n\n/**\n * Forward declaration for checklist.\n */\ntypedef struct pj_ice_sess_checklist pj_ice_sess_checklist;\n\n/**\n * This enumeration describes the type of an ICE candidate.\n */\ntypedef enum pj_ice_cand_type\n{\n    /**\n     * ICE host candidate. A host candidate represents the actual local\n     * transport address in the host.\n     */\n    PJ_ICE_CAND_TYPE_HOST,\n\n    /**\n     * ICE server reflexive candidate, which represents the public mapped\n     * address of the local address, and is obtained by sending STUN\n     * Binding request from the host candidate to a STUN server.\n     */\n    PJ_ICE_CAND_TYPE_SRFLX,\n\n    /**\n     * ICE peer reflexive candidate, which is the address as seen by peer\n     * agent during connectivity check.\n     */\n    PJ_ICE_CAND_TYPE_PRFLX,\n\n    /**\n     * ICE relayed candidate, which represents the address allocated in\n     * TURN server.\n     */\n    PJ_ICE_CAND_TYPE_RELAYED,\n\n    /**\n     * Number of defined ICE candidate types.\n     */\n    PJ_ICE_CAND_TYPE_MAX\n\n} pj_ice_cand_type;\n\n\n/** Forward declaration for pj_ice_sess */\ntypedef struct pj_ice_sess pj_ice_sess;\n\n/** Forward declaration for pj_ice_sess_check */\ntypedef struct pj_ice_sess_check pj_ice_sess_check;\n\n\n/**\n * This structure describes ICE component. \n * A media stream may require multiple components, each of which has \n * to work for the media stream as a whole to work.  For media streams\n * based on RTP, there are two components per media stream - one for RTP,\n * and one for RTCP.\n */\ntypedef struct pj_ice_sess_comp\n{\n    /**\n     * Pointer to ICE check with highest priority which connectivity check\n     * has been successful. The value will be NULL if a no successful check\n     * has not been found for this component.\n     */\n    pj_ice_sess_check\t*valid_check;\n\n    /**\n     * Pointer to ICE check with highest priority which connectivity check\n     * has been successful and it has been nominated. The value may be NULL\n     * if there is no such check yet.\n     */\n    pj_ice_sess_check\t*nominated_check;\n\n    /**\n     * The STUN session to be used to send and receive STUN messages for this\n     * component.\n     */\n    pj_stun_session\t*stun_sess;\n\n} pj_ice_sess_comp;\n\n\n/**\n * Data structure to be attached to internal message processing.\n */\ntypedef struct pj_ice_msg_data\n{\n    /** Transport ID for this message */\n    unsigned\ttransport_id;\n\n    /** Flag to indicate whether data.req contains data */\n    pj_bool_t\thas_req_data;\n\n    /** The data */\n    union data {\n\t/** Request data */\n\tstruct request_data {\n\t    pj_ice_sess\t\t    *ice;   /**< ICE session\t*/\n\t    pj_ice_sess_checklist   *clist; /**< Checklist\t*/\n\t    unsigned\t\t     ckid;  /**< Check ID\t*/\n\t} req;\n    } data;\n\n} pj_ice_msg_data;\n\n\n/**\n * This structure describes an ICE candidate.\n * ICE candidate is a transport address that is to be tested by ICE\n * procedures in order to determine its suitability for usage for\n * receipt of media.  Candidates also have properties - their type\n * (server reflexive, relayed or host), priority, foundation, and\n * base.\n */\ntypedef struct pj_ice_sess_cand\n{\n    /**\n     * The candidate type, as described in #pj_ice_cand_type enumeration.\n     */\n    pj_ice_cand_type\t type;\n\n    /** \n     * Status of this candidate. The value will be PJ_SUCCESS if candidate\n     * address has been resolved successfully, PJ_EPENDING when the address\n     * resolution process is in progress, or other value when the address \n     * resolution has completed with failure.\n     */\n    pj_status_t\t\t status;\n\n    /**\n     * The component ID of this candidate. Note that component IDs starts\n     * with one for RTP and two for RTCP. In other words, it's not zero\n     * based.\n     */\n    pj_uint8_t\t\t comp_id;\n\n    /**\n     * Transport ID to be used to send packets for this candidate.\n     */\n    pj_uint8_t\t\t transport_id;\n\n    /**\n     * Local preference value, which typically is 65535.\n     */\n    pj_uint16_t\t\t local_pref;\n\n    /**\n     * The foundation string, which is an identifier which value will be\n     * equivalent for two candidates that are of the same type, share the \n     * same base, and come from the same STUN server. The foundation is \n     * used to optimize ICE performance in the Frozen algorithm.\n     */\n    pj_str_t\t\t foundation;\n\n    /**\n     * The candidate's priority, a 32-bit unsigned value which value will be\n     * calculated by the ICE session when a candidate is registered to the\n     * ICE session.\n     */\n    pj_uint32_t\t\t prio;\n\n    /**\n     * IP address of this candidate. For host candidates, this represents\n     * the local address of the socket. For reflexive candidates, the value\n     * will be the public address allocated in NAT router for the host\n     * candidate and as reported in MAPPED-ADDRESS or XOR-MAPPED-ADDRESS\n     * attribute of STUN Binding request. For relayed candidate, the value \n     * will be the address allocated in the TURN server by STUN Allocate\n     * request.\n     */\n    pj_sockaddr\t\t addr;\n\n    /**\n     * Base address of this candidate. \"Base\" refers to the address an agent \n     * sends from for a particular candidate.  For host candidates, the base\n     * is the same as the host candidate itself. For reflexive candidates, \n     * the base is the local IP address of the socket. For relayed candidates,\n     * the base address is the transport address allocated in the TURN server\n     * for this candidate.\n     */\n    pj_sockaddr\t\t base_addr;\n\n    /**\n     * Related address, which is used for informational only and is not used\n     * in any way by the ICE session.\n     */\n    pj_sockaddr\t\t rel_addr;\n\n} pj_ice_sess_cand;\n\n\n/**\n * This enumeration describes the state of ICE check.\n */\ntypedef enum pj_ice_sess_check_state\n{\n    /**\n     * A check for this pair hasn't been performed, and it can't\n     * yet be performed until some other check succeeds, allowing this\n     * pair to unfreeze and move into the Waiting state.\n     */\n    PJ_ICE_SESS_CHECK_STATE_FROZEN,\n\n    /**\n     * A check has not been performed for this pair, and can be\n     * performed as soon as it is the highest priority Waiting pair on\n     * the check list.\n     */\n    PJ_ICE_SESS_CHECK_STATE_WAITING,\n\n    /**\n     * A check has not been performed for this pair, and can be\n     * performed as soon as it is the highest priority Waiting pair on\n     * the check list.\n     */\n    PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS,\n\n    /**\n     * A check has not been performed for this pair, and can be\n     * performed as soon as it is the highest priority Waiting pair on\n     * the check list.\n     */\n    PJ_ICE_SESS_CHECK_STATE_SUCCEEDED,\n\n    /**\n     * A check for this pair was already done and failed, either\n     * never producing any response or producing an unrecoverable failure\n     * response.\n     */\n    PJ_ICE_SESS_CHECK_STATE_FAILED\n\n} pj_ice_sess_check_state;\n\n\n/**\n * This structure describes an ICE connectivity check. An ICE check\n * contains a candidate pair, and will involve sending STUN Binding \n * Request transaction for the purposes of verifying connectivity. \n * A check is sent from the local candidate to the remote candidate \n * of a candidate pair.\n */\nstruct pj_ice_sess_check\n{\n    /**\n     * Pointer to local candidate entry of this check.\n     */\n    pj_ice_sess_cand\t*lcand;\n\n    /**\n     * Pointer to remote candidate entry of this check.\n     */\n    pj_ice_sess_cand\t*rcand;\n\n    /**\n     * Check priority.\n     */\n    pj_timestamp\t prio;\n\n    /**\n     * Connectivity check state.\n     */\n    pj_ice_sess_check_state\t state;\n\n    /**\n     * STUN transmit data containing STUN Binding request that was sent \n     * as part of this check. The value will only be set when this check \n     * has a pending transaction, and is used to cancel the transaction\n     * when other check has succeeded.\n     */\n    pj_stun_tx_data\t*tdata;\n\n    /**\n     * Flag to indicate whether this check is nominated. A nominated check\n     * contains USE-CANDIDATE attribute in its STUN Binding request.\n     */\n    pj_bool_t\t\t nominated;\n\n    /**\n     * When the check failed, this will contain the failure status of the\n     * STUN transaction.\n     */\n    pj_status_t\t\t err_code;\n};\n\n\n/**\n * This enumeration describes ICE checklist state.\n */\ntypedef enum pj_ice_sess_checklist_state\n{\n    /**\n     * The checklist is not yet running.\n     */\n    PJ_ICE_SESS_CHECKLIST_ST_IDLE,\n\n    /**\n     * In this state, ICE checks are still in progress for this\n     * media stream.\n     */\n    PJ_ICE_SESS_CHECKLIST_ST_RUNNING,\n\n    /**\n     * In this state, ICE checks have completed for this media stream,\n     * either successfully or with failure.\n     */\n    PJ_ICE_SESS_CHECKLIST_ST_COMPLETED\n\n} pj_ice_sess_checklist_state;\n\n\n/**\n * This structure represents ICE check list, that is an ordered set of \n * candidate pairs that an agent will use to generate checks.\n */\nstruct pj_ice_sess_checklist\n{\n    /**\n     * The checklist state.\n     */\n    pj_ice_sess_checklist_state   state;\n\n    /**\n     * Number of candidate pairs (checks).\n     */\n    unsigned\t\t     count;\n\n    /**\n     * Array of candidate pairs (checks).\n     */\n    pj_ice_sess_check\t     checks[PJ_ICE_MAX_CHECKS];\n\n    /**\n     * A timer used to perform periodic check for this checklist.\n     */\n    pj_timer_entry\t     timer;\n\n};\n\n\n/**\n * This structure contains callbacks that will be called by the ICE\n * session.\n */\ntypedef struct pj_ice_sess_cb\n{\n    /**\n     * An optional callback that will be called by the ICE session when\n     * ICE negotiation has completed, successfully or with failure.\n     *\n     * @param ice\t    The ICE session.\n     * @param status\t    Will contain PJ_SUCCESS if ICE negotiation is\n     *\t\t\t    successful, or some error code.\n     */\n    void\t(*on_ice_complete)(pj_ice_sess *ice, pj_status_t status);\n\n    /**\n     * A mandatory callback which will be called by the ICE session when\n     * it needs to send outgoing STUN packet. \n     *\n     * @param ice\t    The ICE session.\n     * @param comp_id\t    ICE component ID.\n     * @param transport_id  Transport ID.\n     * @param pkt\t    The STUN packet.\n     * @param size\t    The size of the packet.\n     * @param dst_addr\t    Packet destination address.\n     * @param dst_addr_len  Length of destination address.\n     */\n    pj_status_t (*on_tx_pkt)(pj_ice_sess *ice, unsigned comp_id, \n\t\t\t     unsigned transport_id,\n\t\t\t     const void *pkt, pj_size_t size,\n\t\t\t     const pj_sockaddr_t *dst_addr,\n\t\t\t     unsigned dst_addr_len);\n\n    /**\n     * A mandatory callback which will be called by the ICE session when\n     * it receives packet which is not part of ICE negotiation.\n     *\n     * @param ice\t    The ICE session.\n     * @param comp_id\t    ICE component ID.\n     * @param transport_id  Transport ID.\n     * @param pkt\t    The whole packet.\n     * @param size\t    Size of the packet.\n     * @param src_addr\t    Source address where this packet was received \n     *\t\t\t    from.\n     * @param src_addr_len  The length of source address.\n     */\n    void\t(*on_rx_data)(pj_ice_sess *ice, unsigned comp_id,\n\t\t\t      unsigned transport_id, \n\t\t\t      void *pkt, pj_size_t size,\n\t\t\t      const pj_sockaddr_t *src_addr,\n\t\t\t      unsigned src_addr_len);\n} pj_ice_sess_cb;\n\n\n/**\n * This enumeration describes the role of the ICE agent.\n */\ntypedef enum pj_ice_sess_role\n{\n    /**\n     * The role is unknown.\n     */\n    PJ_ICE_SESS_ROLE_UNKNOWN,\n\n    /**\n     * The ICE agent is in controlled role.\n     */\n    PJ_ICE_SESS_ROLE_CONTROLLED,\n\n    /**\n     * The ICE agent is in controlling role.\n     */\n    PJ_ICE_SESS_ROLE_CONTROLLING\n\n} pj_ice_sess_role;\n\n\n/**\n * This structure represents an incoming check (an incoming Binding\n * request message), and is mainly used to keep early checks in the\n * list in the ICE session. An early check is a request received\n * from remote when we haven't received SDP answer yet, therefore we\n * can't perform triggered check. For such cases, keep the incoming\n * request in a list, and we'll do triggered checks (simultaneously)\n * as soon as we receive answer.\n */\ntypedef struct pj_ice_rx_check\n{\n    PJ_DECL_LIST_MEMBER(struct pj_ice_rx_check); /**< Standard list     */\n\n    unsigned\t\t comp_id;\t/**< Component ID.\t\t*/\n    unsigned\t\t transport_id;\t/**< Transport ID.\t\t*/\n\n    pj_sockaddr\t\t src_addr;\t/**< Source address of request\t*/\n    unsigned\t\t src_addr_len;\t/**< Length of src address.\t*/\n\n    pj_bool_t\t\t use_candidate;\t/**< USE-CANDIDATE is present?\t*/\n    pj_uint32_t\t\t priority;\t/**< PRIORITY value in the req.\t*/\n    pj_stun_uint64_attr *role_attr;\t/**< ICE-CONTROLLING/CONTROLLED\t*/\n\n} pj_ice_rx_check;\n\n\n/**\n * This structure describes various ICE session options. Application\n * configure the ICE session with these options by calling \n * #pj_ice_sess_set_options().\n */\ntypedef struct pj_ice_sess_options\n{\n    /**\n     * Specify whether to use aggressive nomination.\n     */\n    pj_bool_t\t\taggressive;\n\n    /**\n     * For controlling agent if it uses regular nomination, specify the delay\n     * to perform nominated check (connectivity check with USE-CANDIDATE \n     * attribute) after all components have a valid pair.\n     *\n     * Default value is PJ_ICE_NOMINATED_CHECK_DELAY.\n     */\n    unsigned\t\tnominated_check_delay;\n\n    /**\n     * For a controlled agent, specify how long it wants to wait (in \n     * milliseconds) for the controlling agent to complete sending \n     * connectivity check with nominated flag set to true for all components\n     * after the controlled agent has found that all connectivity checks in\n     * its checklist have been completed and there is at least one successful\n     * (but not nominated) check for every component.\n     *\n     * Default value for this option is \n     * ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT. Specify -1 to disable\n     * this timer.\n     */\n    int\t\t\tcontrolled_agent_want_nom_timeout;\n\n} pj_ice_sess_options;\n\n\n/**\n * This structure describes the ICE session. For this version of PJNATH,\n * an ICE session corresponds to a single media stream (unlike the ICE\n * session described in the ICE standard where an ICE session covers the\n * whole media and may consist of multiple media streams). The decision\n * to support only a single media session was chosen for simplicity,\n * while still allowing application to utilize multiple media streams by\n * creating multiple ICE sessions, one for each media stream.\n */\nstruct pj_ice_sess\n{\n    char\t\tobj_name[PJ_MAX_OBJ_NAME];  /**< Object name.\t    */\n\n    pj_pool_t\t\t*pool;\t\t\t    /**< Pool instance.\t    */\n    void\t\t*user_data;\t\t    /**< App. data.\t    */\n    pj_grp_lock_t\t*grp_lock;\t\t    /**< Group lock\t    */\n    pj_ice_sess_role\t role;\t\t\t    /**< ICE role.\t    */\n    pj_ice_sess_options\t opt;\t\t\t    /**< Options\t    */\n    pj_timestamp\t tie_breaker;\t\t    /**< Tie breaker value  */\n    pj_uint8_t\t\t*prefs;\t\t\t    /**< Type preference.   */\n    pj_bool_t\t\t is_nominating;\t\t    /**< Nominating stage   */\n    pj_bool_t\t\t is_complete;\t\t    /**< Complete?\t    */\n    pj_bool_t\t\t is_destroying;\t\t    /**< Destroy is called  */\n    pj_status_t\t\t ice_status;\t\t    /**< Error status.\t    */\n    pj_timer_entry\t timer;\t\t\t    /**< ICE timer.\t    */\n    pj_ice_sess_cb\t cb;\t\t\t    /**< Callback.\t    */\n\n    pj_stun_config\t stun_cfg;\t\t    /**< STUN settings.\t    */\n\n    /* STUN credentials */\n    pj_str_t\t\t tx_ufrag;\t\t    /**< Remote ufrag.\t    */\n    pj_str_t\t\t tx_uname;\t\t    /**< Uname for TX.\t    */\n    pj_str_t\t\t tx_pass;\t\t    /**< Remote password.   */\n    pj_str_t\t\t rx_ufrag;\t\t    /**< Local ufrag.\t    */\n    pj_str_t\t\t rx_uname;\t\t    /**< Uname for RX\t    */\n    pj_str_t\t\t rx_pass;\t\t    /**< Local password.    */\n\n    /* Components */\n    unsigned\t\t comp_cnt;\t\t    /**< # of components.   */\n    pj_ice_sess_comp\t comp[PJ_ICE_MAX_COMP];\t    /**< Component array    */\n    unsigned\t\t comp_ka;\t\t    /**< Next comp for KA   */\n\n    /* Local candidates */\n    unsigned\t\t lcand_cnt;\t\t    /**< # of local cand.   */\n    pj_ice_sess_cand\t lcand[PJ_ICE_MAX_CAND];    /**< Array of cand.\t    */\n\n    /* Remote candidates */\n    unsigned\t\t rcand_cnt;\t\t    /**< # of remote cand.  */\n    pj_ice_sess_cand\t rcand[PJ_ICE_MAX_CAND];    /**< Array of cand.\t    */\n\n    /** Array of transport datas */\n    pj_ice_msg_data\t tp_data[4];\n\n    /* List of eearly checks */\n    pj_ice_rx_check\t early_check;\t\t    /**< Early checks.\t    */\n\n    /* Checklist */\n    pj_ice_sess_checklist clist;\t\t    /**< Active checklist   */\n    \n    /* Valid list */\n    pj_ice_sess_checklist valid_list;\t\t    /**< Valid list.\t    */\n    \n    /** Temporary buffer for misc stuffs to avoid using stack too much */\n    union {\n    \tchar txt[128];\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n    } tmp;\n};\n\n\n/**\n * This is a utility function to retrieve the string name for the\n * particular candidate type.\n *\n * @param type\t\tCandidate type.\n *\n * @return\t\tThe string representation of the candidate type.\n */\nPJ_DECL(const char*) pj_ice_get_cand_type_name(pj_ice_cand_type type);\n\n\n/**\n * This is a utility function to retrieve the string name for the\n * particular role type.\n *\n * @param role\t\tRole type.\n *\n * @return\t\tThe string representation of the role.\n */\nPJ_DECL(const char*) pj_ice_sess_role_name(pj_ice_sess_role role);\n\n\n/**\n * This is a utility function to calculate the foundation identification\n * for a candidate.\n *\n * @param pool\t\tPool to allocate the foundation string.\n * @param foundation\tPointer to receive the foundation string.\n * @param type\t\tCandidate type.\n * @param base_addr\tBase address of the candidate.\n */\nPJ_DECL(void) pj_ice_calc_foundation(pj_pool_t *pool,\n\t\t\t\t     pj_str_t *foundation,\n\t\t\t\t     pj_ice_cand_type type,\n\t\t\t\t     const pj_sockaddr *base_addr);\n\n/**\n * Initialize ICE session options with library default values.\n *\n * @param opt\t\tICE session options.\n */\nPJ_DECL(void) pj_ice_sess_options_default(pj_ice_sess_options *opt);\n\n/**\n * Create ICE session with the specified role and number of components.\n * Application would typically need to create an ICE session before\n * sending an offer or upon receiving one. After the session is created,\n * application can register candidates to the ICE session by calling\n * #pj_ice_sess_add_cand() function.\n *\n * @param stun_cfg\tThe STUN configuration settings, containing among\n *\t\t\tother things the timer heap instance to be used\n *\t\t\tby the ICE session.\n * @param name\t\tOptional name to identify this ICE instance in\n *\t\t\tthe log file.\n * @param role\t\tICE role.\n * @param comp_cnt\tNumber of components.\n * @param cb\t\tICE callback.\n * @param local_ufrag\tOptional string to be used as local username to\n *\t\t\tauthenticate incoming STUN binding request. If\n *\t\t\tthe value is NULL, a random string will be \n *\t\t\tgenerated.\n * @param local_passwd\tOptional string to be used as local password.\n * @param grp_lock\tOptional group lock to be used by this session.\n * \t\t\tIf NULL, the session will create one itself.\n * @param p_ice\t\tPointer to receive the ICE session instance.\n *\n * @return\t\tPJ_SUCCESS if ICE session is created successfully.\n */\nPJ_DECL(pj_status_t) pj_ice_sess_create(pj_stun_config *stun_cfg,\n\t\t\t\t        const char *name,\n\t\t\t\t        pj_ice_sess_role role,\n\t\t\t\t        unsigned comp_cnt,\n\t\t\t\t        const pj_ice_sess_cb *cb,\n\t\t\t\t        const pj_str_t *local_ufrag,\n\t\t\t\t        const pj_str_t *local_passwd,\n\t\t\t\t        pj_grp_lock_t *grp_lock,\n\t\t\t\t        pj_ice_sess **p_ice);\n\n/**\n * Get the value of various options of the ICE session.\n *\n * @param ice\t\tThe ICE session.\n * @param opt\t\tThe options to be initialized with the values\n *\t\t\tfrom the ICE session.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error.\n */\nPJ_DECL(pj_status_t) pj_ice_sess_get_options(pj_ice_sess *ice,\n\t\t\t\t\t     pj_ice_sess_options *opt);\n\n/**\n * Specify various options for this ICE session. Application MUST only\n * call this function after the ICE session has been created but before\n * any connectivity check is started.\n *\n * Application should call #pj_ice_sess_get_options() to initialize the\n * options with their default values.\n *\n * @param ice\t\tThe ICE session.\n * @param opt\t\tOptions to be applied to the ICE session.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error.\n */\nPJ_DECL(pj_status_t) pj_ice_sess_set_options(pj_ice_sess *ice,\n\t\t\t\t\t     const pj_ice_sess_options *opt);\n\n/**\n * Destroy ICE session. This will cancel any connectivity checks currently\n * running, if any, and any other events scheduled by this session, as well\n * as all memory resources.\n *\n * @param ice\t\tICE session instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pj_ice_sess_destroy(pj_ice_sess *ice);\n\n\n/**\n * Change session role. This happens for example when ICE session was\n * created with controlled role when receiving an offer, but it turns out\n * that the offer contains \"a=ice-lite\" attribute when the SDP gets\n * inspected.\n *\n * @param ice\t\tThe ICE session.\n * @param new_role\tThe new role to be set.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error.\n */\nPJ_DECL(pj_status_t) pj_ice_sess_change_role(pj_ice_sess *ice,\n\t\t\t\t\t     pj_ice_sess_role new_role);\n\n\n/**\n * Assign a custom preference values for ICE candidate types. By assigning\n * custom preference value, application can control the order of candidates\n * to be checked first. The default preference settings is to use 126 for \n * host candidates, 100 for server reflexive candidates, 110 for peer \n * reflexive candidates, an 0 for relayed candidates.\n *\n * Note that this function must be called before any candidates are added\n * to the ICE session.\n *\n * @param ice\t\tThe ICE session.\n * @param prefs\t\tArray of candidate preference value. The values are\n *\t\t\tput in the array indexed by the candidate type as\n *\t\t\tspecified in pj_ice_cand_type.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ice_sess_set_prefs(pj_ice_sess *ice,\n\t\t\t\t\t   const pj_uint8_t prefs[4]);\n\n\n\n/**\n * Add a candidate to this ICE session. Application must add candidates for\n * each components ID before it can start pairing the candidates and \n * performing connectivity checks.\n *\n * @param ice\t\tICE session instance.\n * @param comp_id\tComponent ID of this candidate.\n * @param transport_id\tTransport ID to be used to send packets for this\n *\t\t\tcandidate.\n * @param type\t\tCandidate type.\n * @param local_pref\tLocal preference for this candidate, which\n *\t\t\tnormally should be set to 65535.\n * @param foundation\tFoundation identification.\n * @param addr\t\tThe candidate address.\n * @param base_addr\tThe candidate's base address.\n * @param rel_addr\tOptional related address.\n * @param addr_len\tLength of addresses.\n * @param p_cand_id\tOptional pointer to receive the candidate ID.\n *\n * @return\t\tPJ_SUCCESS if candidate is successfully added.\n */\nPJ_DECL(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice,\n\t\t\t\t\t  unsigned comp_id,\n\t\t\t\t\t  unsigned transport_id,\n\t\t\t\t\t  pj_ice_cand_type type,\n\t\t\t\t\t  pj_uint16_t local_pref,\n\t\t\t\t\t  const pj_str_t *foundation,\n\t\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t\t  const pj_sockaddr_t *base_addr,\n\t\t\t\t\t  const pj_sockaddr_t *rel_addr,\n\t\t\t\t\t  int addr_len,\n\t\t\t\t\t  unsigned *p_cand_id);\n\n/**\n * Find default candidate for the specified component ID, using this\n * rule:\n *  - if the component has a successful candidate pair, then the\n *    local candidate of this pair will be returned.\n *  - otherwise a relay, reflexive, or host candidate will be selected \n *    on that specified order.\n *\n * @param ice\t\tThe ICE session instance.\n * @param comp_id\tThe component ID.\n * @param p_cand_id\tPointer to receive the candidate ID.\n *\n * @return\t\tPJ_SUCCESS if a candidate has been selected.\n */\nPJ_DECL(pj_status_t) pj_ice_sess_find_default_cand(pj_ice_sess *ice,\n\t\t\t\t\t\t   unsigned comp_id,\n\t\t\t\t\t\t   int *p_cand_id);\n\n/**\n * Pair the local and remote candidates to create check list. Application\n * typically would call this function after receiving SDP containing ICE\n * candidates from the remote host (either upon receiving the initial\n * offer, for UAS, or upon receiving the answer, for UAC).\n *\n * Note that ICE connectivity check will not start until application calls\n * #pj_ice_sess_start_check().\n *\n * @param ice\t\tICE session instance.\n * @param rem_ufrag\tRemote ufrag, as seen in the SDP received from \n *\t\t\tthe remote agent.\n * @param rem_passwd\tRemote password, as seen in the SDP received from\n *\t\t\tthe remote agent.\n * @param rem_cand_cnt\tNumber of remote candidates.\n * @param rem_cand\tRemote candidate array. Remote candidates are\n *\t\t\tgathered from the SDP received from the remote \n *\t\t\tagent.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) \npj_ice_sess_create_check_list(pj_ice_sess *ice,\n\t\t\t      const pj_str_t *rem_ufrag,\n\t\t\t      const pj_str_t *rem_passwd,\n\t\t\t      unsigned rem_cand_cnt,\n\t\t\t      const pj_ice_sess_cand rem_cand[]);\n\n/**\n * Start ICE periodic check. This function will return immediately, and\n * application will be notified about the connectivity check status in\n * #pj_ice_sess_cb callback.\n *\n * @param ice\t\tThe ICE session instance.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ice_sess_start_check(pj_ice_sess *ice);\n\n\n/**\n * Send data using this ICE session. If ICE checks have not produced a\n * valid check for the specified component ID, this function will return\n * with failure. Otherwise ICE session will send the packet to remote\n * destination using the nominated local candidate for the specified\n * component.\n *\n * This function will in turn call \\a on_tx_pkt function in\n * #pj_ice_sess_cb callback to actually send the packet to the wire.\n *\n * @param ice\t\tThe ICE session.\n * @param comp_id\tComponent ID.\n * @param data\t\tThe data or packet to be sent.\n * @param data_len\tSize of data or packet, in bytes.\n *\n * @return\t\tPJ_SUCCESS if data is sent successfully.\n */\nPJ_DECL(pj_status_t) pj_ice_sess_send_data(pj_ice_sess *ice,\n\t\t\t\t\t   unsigned comp_id,\n\t\t\t\t\t   const void *data,\n\t\t\t\t\t   pj_size_t data_len);\n\n/**\n * Report the arrival of packet to the ICE session. Since ICE session\n * itself doesn't have any transports, it relies on application or\n * higher layer component to give incoming packets to the ICE session.\n * If the packet is not a STUN packet, this packet will be given back\n * to application via \\a on_rx_data() callback in #pj_ice_sess_cb.\n *\n * @param ice\t\tThe ICE session.\n * @param comp_id\tComponent ID.\n * @param transport_id\tNumber to identify where this packet was received\n *\t\t\tfrom. This parameter will be returned back to\n *\t\t\tapplication in \\a on_tx_pkt() callback.\n * @param pkt\t\tIncoming packet.\n * @param pkt_size\tSize of incoming packet.\n * @param src_addr\tSource address of the packet.\n * @param src_addr_len\tLength of the address.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice,\n\t\t\t\t\t   unsigned comp_id,\n\t\t\t\t\t   unsigned transport_id,\n\t\t\t\t\t   void *pkt,\n\t\t\t\t\t   pj_size_t pkt_size,\n\t\t\t\t\t   const pj_sockaddr_t *src_addr,\n\t\t\t\t\t   int src_addr_len);\n\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJNATH_ICE_SESSION_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/ice_strans.h",
    "content": "/* $Id: ice_strans.h 4133 2012-05-21 14:00:17Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_ICE_STRANS_H__\n#define __PJNATH_ICE_STRANS_H__\n\n\n/**\n * @file ice_strans.h\n * @brief ICE Stream Transport\n */\n#include <pjnath/ice_session.h>\n#include <pjnath/stun_sock.h>\n#include <pjnath/turn_sock.h>\n#include <pjlib-util/resolver.h>\n#include <pj/ioqueue.h>\n#include <pj/timer.h>\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * @addtogroup PJNATH_ICE_STREAM_TRANSPORT\n * @{\n *\n * This module describes ICE stream transport, as represented by #pj_ice_strans\n * structure, and is part of PJNATH - the Open Source NAT traversal helper\n * library.\n *\n * ICE stream transport, as represented by #pj_ice_strans structure, is an ICE\n * capable class for transporting media streams within a media session. \n * It consists of one or more transport sockets (typically two for RTP\n * based communication - one for RTP and one for RTCP), and an \n * \\ref PJNATH_ICE_SESSION for performing connectivity checks among the.\n * various candidates of the transport addresses.\n *\n *\n * \\section ice_strans_using_sec Using the ICE stream transport\n *\n * The steps below describe how to use ICE session:\n *\n *  - initialize a #pj_ice_strans_cfg structure. This contains various \n *    settings for the ICE stream transport, and among other things contains\n *    the STUN and TURN settings.\\n\\n\n *  - create the instance with #pj_ice_strans_create(). Among other things,\n *    the function needs the following arguments:\n *\t- the #pj_ice_strans_cfg structure for the main configurations\n *\t- number of components to be supported\n *\t- instance of #pj_ice_strans_cb structure to report callbacks to\n *\t  application.\\n\\n\n *  - while the #pj_ice_strans_create() call completes immediately, the\n *    initialization will be running in the background to gather the \n *    candidates (for example STUN and TURN candidates, if they are enabled\n *    in the #pj_ice_strans_cfg setting). Application will be notified when\n *    the initialization completes in the \\a on_ice_complete callback of\n *    the #pj_ice_strans_cb structure (the \\a op argument of this callback\n *    will be PJ_ICE_STRANS_OP_INIT).\\n\\n\n *  - when media stream is to be started (for example, a call is to be \n *    started), create an ICE session by calling #pj_ice_strans_init_ice().\\n\\n\n *  - the application now typically will need to communicate local ICE\n *    information to remote host. It can achieve this by using the following\n *    functions to query local ICE information:\n *\t- #pj_ice_strans_get_ufrag_pwd()\n *\t- #pj_ice_strans_enum_cands()\n *\t- #pj_ice_strans_get_def_cand()\\n\n *    The application may need to encode the above information as SDP.\\n\\n\n *  - when the application receives remote ICE information (for example, from\n *    the SDP received from remote), it can now start ICE negotiation, by\n *    calling #pj_ice_strans_start_ice(). This function requires some\n *    information about remote ICE agent such as remote ICE username fragment\n *    and password as well as array of remote candidates.\\n\\n\n *  - note that the PJNATH library does not work with SDP; application would\n *    need to encode and parse the SDP itself.\\n\\n\n *  - once ICE negotiation has been started, application will be notified\n *    about the completion in the \\a on_ice_complete() callback of the\n *    #pj_ice_strans_cb.\\n\\n\n *  - at any time, application may send or receive data. However the ICE\n *    stream transport may not be able to send it depending on its current\n *    state. Before ICE negotiation is started, the data will be sent using\n *    default candidate of the component. After negotiation is completed,\n *    data will be sent using the candidate from the successful/nominated\n *    pair. The ICE stream transport may not be able to send data while \n *    negotiation is in progress.\\n\\n\n *  - application sends data by using #pj_ice_strans_sendto(). Incoming\n *    data will be reported in \\a on_rx_data() callback of the\n *    #pj_ice_strans_cb.\\n\\n\n *  - once the media session has finished (e.g. user hangs up the call),\n *    destroy the ICE session with #pj_ice_strans_stop_ice().\\n\\n\n *  - at this point, application may destroy the ICE stream transport itself,\n *    or let it run so that it can be reused to create other ICE session.\n *    The benefit of letting the ICE stream transport alive (without any\n *    session active) is to avoid delay with the initialization, howerver\n *    keeping the transport alive means the transport needs to keep the\n *    STUN binding open by using keep-alive and also TURN allocation alive,\n *    and this will consume power which is an important issue for mobile\n *    applications.\\n\\n\n */\n\n/** Forward declaration for ICE stream transport. */\ntypedef struct pj_ice_strans pj_ice_strans;\n\n/** Transport operation types to be reported on \\a on_status() callback */\ntypedef enum pj_ice_strans_op\n{\n    /** Initialization (candidate gathering) */\n    PJ_ICE_STRANS_OP_INIT,\n\n    /** Negotiation */\n    PJ_ICE_STRANS_OP_NEGOTIATION,\n\n    /** This operatino is used to report failure in keep-alive operation.\n     *  Currently it is only used to report TURN Refresh failure.\n     */\n    PJ_ICE_STRANS_OP_KEEP_ALIVE\n\n} pj_ice_strans_op;\n\n\n/**\n * ICE stream transport's state.\n */\ntypedef enum pj_ice_strans_state\n{\n    /**\n     * ICE stream transport is not created.\n     */\n    PJ_ICE_STRANS_STATE_NULL,\n\n    /**\n     * ICE candidate gathering process is in progress.\n     */\n    PJ_ICE_STRANS_STATE_INIT,\n\n    /**\n     * ICE stream transport initialization/candidate gathering process is\n     * complete, ICE session may be created on this stream transport.\n     */\n    PJ_ICE_STRANS_STATE_READY,\n\n    /**\n     * New session has been created and the session is ready.\n     */\n    PJ_ICE_STRANS_STATE_SESS_READY,\n\n    /**\n     * ICE negotiation is in progress.\n     */\n    PJ_ICE_STRANS_STATE_NEGO,\n\n    /**\n     * ICE negotiation has completed successfully and media is ready\n     * to be used.\n     */\n    PJ_ICE_STRANS_STATE_RUNNING,\n\n    /**\n     * ICE negotiation has completed with failure.\n     */\n    PJ_ICE_STRANS_STATE_FAILED\n\n} pj_ice_strans_state;\n\n\n/** \n * This structure contains callbacks that will be called by the \n * ICE stream transport.\n */\ntypedef struct pj_ice_strans_cb\n{\n    /**\n     * This callback will be called when the ICE transport receives\n     * incoming packet from the sockets which is not related to ICE\n     * (for example, normal RTP/RTCP packet destined for application).\n     *\n     * @param ice_st\t    The ICE stream transport.\n     * @param comp_id\t    The component ID.\n     * @param pkt\t    The packet.\n     * @param size\t    Size of the packet.\n     * @param src_addr\t    Source address of the packet.\n     * @param src_addr_len  Length of the source address.\n     */\n    void    (*on_rx_data)(pj_ice_strans *ice_st,\n\t\t\t  unsigned comp_id, \n\t\t\t  void *pkt, pj_size_t size,\n\t\t\t  const pj_sockaddr_t *src_addr,\n\t\t\t  unsigned src_addr_len);\n\n    /**\n     * Callback to report status of various ICE operations.\n     * \n     * @param ice_st\t    The ICE stream transport.\n     * @param op\t    The operation which status is being reported.\n     * @param status\t    Operation status.\n     */\n    void    (*on_ice_complete)(pj_ice_strans *ice_st, \n\t\t\t       pj_ice_strans_op op,\n\t\t\t       pj_status_t status);\n\n    /**\n     * Callback to report ICE state changes.\n     *\n     * @param ice_st\t    The ICE stream transport.\n     * @param prev\t    Previous state.\n     * @param curr\t    Current state.\n     */\n    void    (*on_ice_state)(pj_ice_strans *ice_st,\n\t\t\t    pj_ice_strans_state prev,\n\t\t\t    pj_ice_strans_state curr);\n\n} pj_ice_strans_cb;\n\n\n/**\n * This structure describes ICE stream transport configuration. Application\n * should initialize the structure by calling #pj_ice_strans_cfg_default()\n * before changing the settings.\n */\ntypedef struct pj_ice_strans_cfg\n{\n    /**\n     * Address family, IPv4 or IPv6. Currently only pj_AF_INET() (IPv4)\n     * is supported, and this is the default value.\n     */\n    int\t\t\taf;\n\n    /**\n     * STUN configuration which contains the timer heap and\n     * ioqueue instance to be used, and STUN retransmission\n     * settings. This setting is mandatory.\n     *\n     * The default value is all zero. Application must initialize\n     * this setting with #pj_stun_config_init().\n     */\n    pj_stun_config\t stun_cfg;\n\n    /**\n     * DNS resolver to be used to resolve servers. If DNS SRV\n     * resolution is required, the resolver must be set.\n     *\n     * The default value is NULL.\n     */\n    pj_dns_resolver\t*resolver;\n\n    /**\n     * This contains various STUN session options. Once the ICE stream\n     * transport is created, application may also change the options\n     * with #pj_ice_strans_set_options().\n     */\n    pj_ice_sess_options\t opt;\n\n    /**\n     * STUN and local transport settings. This specifies the \n     * settings for local UDP socket, which will be resolved\n     * to get the STUN mapped address.\n     */\n    struct {\n\t/**\n\t * Optional configuration for STUN transport. The default\n\t * value will be initialized with #pj_stun_sock_cfg_default().\n\t */\n\tpj_stun_sock_cfg     cfg;\n\n\t/**\n\t * Maximum number of host candidates to be added. If the\n\t * value is zero, no host candidates will be added.\n\t *\n\t * Default: 64\n\t */\n\tunsigned\t     max_host_cands;\n\n\t/**\n\t * Include loopback addresses in the host candidates.\n\t *\n\t * Default: PJ_FALSE\n\t */\n\tpj_bool_t\t     loop_addr;\n\n\t/**\n\t * Specify the STUN server domain or hostname or IP address.\n\t * If DNS SRV resolution is required, application must fill\n\t * in this setting with the domain name of the STUN server \n\t * and set the resolver instance in the \\a resolver field.\n\t * Otherwise if the \\a resolver setting is not set, this\n\t * field will be resolved with hostname resolution and in\n\t * this case the \\a port field must be set.\n\t *\n\t * The \\a port field should also be set even when DNS SRV\n\t * resolution is used, in case the DNS SRV resolution fails.\n\t *\n\t * When this field is empty, STUN mapped address resolution\n\t * will not be performed. In this case only ICE host candidates\n\t * will be added to the ICE transport, unless if \\a no_host_cands\n\t * field is set. In this case, both host and srflx candidates \n\t * are disabled.\n\t *\n\t * The default value is empty.\n\t */\n\tpj_str_t\t     server;\n\n\t/**\n\t * The port number of the STUN server, when \\a server\n\t * field specifies a hostname rather than domain name. This\n\t * field should also be set even when the \\a server\n\t * specifies a domain name, to allow DNS SRV resolution\n\t * to fallback to DNS A/AAAA resolution when the DNS SRV\n\t * resolution fails.\n\t *\n\t * The default value is PJ_STUN_PORT.\n\t */\n\tpj_uint16_t\t     port;\n\n\t/**\n\t * Ignore STUN resolution error and proceed with just local\n\t * addresses.\n\t *\n\t * The default is PJ_FALSE\n\t */\n\tpj_bool_t\t     ignore_stun_error;\n\n    } stun;\n\n    /**\n     * TURN specific settings.\n     */\n    struct {\n\t/**\n\t * Optional TURN socket settings. The default values will be\n\t * initialized by #pj_turn_sock_cfg_default(). This contains\n\t * settings such as QoS.\n\t */\n\tpj_turn_sock_cfg     cfg;\n\n\t/**\n\t * Specify the TURN server domain or hostname or IP address.\n\t * If DNS SRV resolution is required, application must fill\n\t * in this setting with the domain name of the TURN server \n\t * and set the resolver instance in the \\a resolver field.\n\t * Otherwise if the \\a resolver setting is not set, this\n\t * field will be resolved with hostname resolution and in\n\t * this case the \\a port field must be set.\n\t *\n\t * The \\a port field should also be set even when DNS SRV\n\t * resolution is used, in case the DNS SRV resolution fails.\n\t *\n\t * When this field is empty, relay candidate will not be\n\t * created.\n\t *\n\t * The default value is empty.\n\t */\n\tpj_str_t\t     server;\n\n\t/**\n\t * The port number of the TURN server, when \\a server\n\t * field specifies a hostname rather than domain name. This\n\t * field should also be set even when the \\a server\n\t * specifies a domain name, to allow DNS SRV resolution\n\t * to fallback to DNS A/AAAA resolution when the DNS SRV\n\t * resolution fails.\n\t *\n\t * Default is zero.\n\t */\n\tpj_uint16_t\t     port;\n\n\t/**\n\t * Type of connection to the TURN server.\n\t *\n\t * Default is PJ_TURN_TP_UDP.\n\t */\n\tpj_turn_tp_type\t     conn_type;\n\n\t/**\n\t * Credential to be used for the TURN session. This setting\n\t * is mandatory.\n\t *\n\t * Default is to have no credential.\n\t */\n\tpj_stun_auth_cred    auth_cred;\n\n\t/**\n\t * Optional TURN Allocate parameter. The default value will be\n\t * initialized by #pj_turn_alloc_param_default().\n\t */\n\tpj_turn_alloc_param  alloc_param;\n\n    } turn;\n\n    /**\n     * Component specific settings, which will override the settings in\n     * the STUN and TURN settings above. For example, setting the QoS\n     * parameters here allows the application to have different QoS\n     * traffic type for RTP and RTCP component.\n     */\n    struct {\n\t/**\n\t * QoS traffic type to be set on this transport. When application\n\t * wants to apply QoS tagging to the transport, it's preferable to\n\t * set this field rather than \\a qos_param fields since this is \n\t * more portable.\n\t *\n\t * Default value is PJ_QOS_TYPE_BEST_EFFORT.\n\t */\n\tpj_qos_type qos_type;\n\n\t/**\n\t * Set the low level QoS parameters to the transport. This is a \n\t * lower level operation than setting the \\a qos_type field and\n\t * may not be supported on all platforms.\n\t *\n\t * By default all settings in this structure are disabled.\n\t */\n\tpj_qos_params qos_params;\n\n\t/**\n\t * Specify target value for socket receive buffer size. It will be\n\t * applied using setsockopt(). When it fails to set the specified\n\t * size, it will try with lower value until the highest possible is\n\t * successfully set.\n\t *\n\t * When this is set to zero, this component will apply socket receive\n\t * buffer size settings specified in STUN and TURN socket config\n\t * above, i.e: \\a stun::cfg::so_rcvbuf_size and\n\t * \\a turn::cfg::so_rcvbuf_size. Otherwise, this setting will be\n\t * applied to STUN and TURN sockets for this component, overriding\n\t * the setting specified in STUN/TURN socket config.\n\t *\n\t * Default: 0\n\t */\n\tunsigned so_rcvbuf_size;\n\n\t/**\n\t * Specify target value for socket send buffer size. It will be\n\t * applied using setsockopt(). When it fails to set the specified\n\t * size, it will try with lower value until the highest possible is\n\t * successfully set.\n\t *\n\t * When this is set to zero, this component will apply socket send\n\t * buffer size settings specified in STUN and TURN socket config\n\t * above, i.e: \\a stun::cfg::so_sndbuf_size and\n\t * \\a turn::cfg::so_sndbuf_size. Otherwise, this setting will be\n\t * applied to STUN and TURN sockets for this component, overriding\n\t * the setting specified in STUN/TURN socket config.\n\t *\n\t * Default: 0\n\t */\n\tunsigned so_sndbuf_size;\n\n    } comp[PJ_ICE_MAX_COMP];\n\n} pj_ice_strans_cfg;\n\n\n/** \n * Initialize ICE transport configuration with default values.\n *\n * @param cfg\t\tThe configuration to be initialized.\n */\nPJ_DECL(void) pj_ice_strans_cfg_default(pj_ice_strans_cfg *cfg);\n\n\n/**\n * Copy configuration.\n *\n * @param pool\t\tPool.\n * @param dst\t\tDestination.\n * @param src\t\tSource.\n */\nPJ_DECL(void) pj_ice_strans_cfg_copy(pj_pool_t *pool,\n\t\t\t\t     pj_ice_strans_cfg *dst,\n\t\t\t\t     const pj_ice_strans_cfg *src);\n\n\n/**\n * Create and initialize the ICE stream transport with the specified\n * parameters. \n *\n * @param name\t\tOptional name for logging identification.\n * @param cfg\t\tConfiguration.\n * @param comp_cnt\tNumber of components.\n * @param user_data\tArbitrary user data to be associated with this\n *\t\t\tICE stream transport.\n * @param cb\t\tCallback.\n * @param p_ice_st\tPointer to receive the ICE stream transport\n *\t\t\tinstance.\n *\n * @return\t\tPJ_SUCCESS if ICE stream transport is created\n *\t\t\tsuccessfully.\n */\nPJ_DECL(pj_status_t) pj_ice_strans_create(const char *name,\n\t\t\t\t\t  const pj_ice_strans_cfg *cfg,\n\t\t\t\t\t  unsigned comp_cnt,\n\t\t\t\t\t  void *user_data,\n\t\t\t\t\t  const pj_ice_strans_cb *cb,\n\t\t\t\t\t  pj_ice_strans **p_ice_st);\n\n/**\n * Get ICE session state.\n *\n * @param ice_st\tThe ICE stream transport.\n *\n * @return\t\tICE session state.\n */\nPJ_DECL(pj_ice_strans_state) pj_ice_strans_get_state(pj_ice_strans *ice_st);\n\n\n/**\n * Get string representation of ICE state.\n *\n * @param state\t\tICE stream transport state.\n *\n * @return\t\tString.\n */\nPJ_DECL(const char*) pj_ice_strans_state_name(pj_ice_strans_state state);\n\n\n/**\n * Destroy the ICE stream transport. This will destroy the ICE session\n * inside the ICE stream transport, close all sockets and release all\n * other resources.\n *\n * @param ice_st\tThe ICE stream transport.\n *\n * @return\t\tPJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ice_strans_destroy(pj_ice_strans *ice_st);\n\n\n/**\n * Get the user data associated with the ICE stream transport.\n *\n * @param ice_st\tThe ICE stream transport.\n *\n * @return\t\tThe user data.\n */\nPJ_DECL(void*) pj_ice_strans_get_user_data(pj_ice_strans *ice_st);\n\n\n/**\n * Get the value of various options of the ICE stream transport.\n *\n * @param ice_st\tThe ICE stream transport.\n * @param opt\t\tThe options to be initialized with the values\n *\t\t\tfrom the ICE stream transport.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error.\n */\nPJ_DECL(pj_status_t) pj_ice_strans_get_options(pj_ice_strans *ice_st,\n\t\t\t\t\t       pj_ice_sess_options *opt);\n\n/**\n * Specify various options for this ICE stream transport. Application \n * should call #pj_ice_strans_get_options() to initialize the options \n * with their default values.\n *\n * @param ice_st\tThe ICE stream transport.\n * @param opt\t\tOptions to be applied to this ICE stream transport.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error.\n */\nPJ_DECL(pj_status_t) pj_ice_strans_set_options(pj_ice_strans *ice_st,\n\t\t\t\t\t       const pj_ice_sess_options *opt);\n\n/**\n * Get the group lock for this ICE stream transport.\n *\n * @param ice_st\tThe ICE stream transport.\n *\n * @return\t\tThe group lock.\n */\nPJ_DECL(pj_grp_lock_t *) pj_ice_strans_get_grp_lock(pj_ice_strans *ice_st);\n\n/**\n * Initialize the ICE session in the ICE stream transport.\n * When application is about to send an offer containing ICE capability,\n * or when it receives an offer containing ICE capability, it must\n * call this function to initialize the internal ICE session. This would\n * register all transport address aliases for each component to the ICE\n * session as candidates. Then application can enumerate all local\n * candidates by calling #pj_ice_strans_enum_cands(), and encode these\n * candidates in the SDP to be sent to remote agent.\n *\n * @param ice_st\tThe ICE stream transport.\n * @param role\t\tICE role.\n * @param local_ufrag\tOptional local username fragment.\n * @param local_passwd\tOptional local password.\n *\n * @return\t\tPJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ice_strans_init_ice(pj_ice_strans *ice_st,\n\t\t\t\t\t    pj_ice_sess_role role,\n\t\t\t\t\t    const pj_str_t *local_ufrag,\n\t\t\t\t\t    const pj_str_t *local_passwd);\n\n/**\n * Check if the ICE stream transport has the ICE session created. The\n * ICE session is created with #pj_ice_strans_init_ice().\n *\n * @param ice_st\tThe ICE stream transport.\n *\n * @return\t\tPJ_TRUE if #pj_ice_strans_init_ice() has been\n *\t\t\tcalled.\n */\nPJ_DECL(pj_bool_t) pj_ice_strans_has_sess(pj_ice_strans *ice_st);\n\n\n/**\n * Check if ICE negotiation is still running.\n *\n * @param ice_st\tThe ICE stream transport.\n *\n * @return\t\tPJ_TRUE if ICE session has been created and ICE \n *\t\t\tnegotiation negotiation is in progress.\n */\nPJ_DECL(pj_bool_t) pj_ice_strans_sess_is_running(pj_ice_strans *ice_st);\n\n\n/**\n * Check if ICE negotiation has completed.\n *\n * @param ice_st\tThe ICE stream transport.\n *\n * @return\t\tPJ_TRUE if ICE session has been created and the\n *\t\t\tnegotiation is complete.\n */\nPJ_DECL(pj_bool_t) pj_ice_strans_sess_is_complete(pj_ice_strans *ice_st);\n\n\n/**\n * Get the current/running component count. If ICE negotiation has not\n * been started, the number of components will be equal to the number\n * when the ICE stream transport was created. Once negotiation been\n * started, the number of components will be the lowest number of \n * component between local and remote agents.\n *\n * @param ice_st\tThe ICE stream transport.\n *\n * @return\t\tThe running number of components.\n */\nPJ_DECL(unsigned) pj_ice_strans_get_running_comp_cnt(pj_ice_strans *ice_st);\n\n\n/**\n * Get the ICE username fragment and password of the ICE session. The\n * local username fragment and password can only be retrieved once ICE\n * session has been created with #pj_ice_strans_init_ice(). The remote\n * username fragment and password can only be retrieved once ICE session\n * has been started with #pj_ice_strans_start_ice().\n *\n * Note that the string returned by this function is only valid throughout\n * the duration of the ICE session, and the application must not modify\n * these strings. Once the ICE session has been stopped with\n * #pj_ice_strans_stop_ice(), the pointer in the string will no longer be\n * valid.\n *\n * @param ice_st\tThe ICE stream transport.\n * @param loc_ufrag\tOptional pointer to receive ICE username fragment\n *\t\t\tof local endpoint from the ICE session.\n * @param loc_pwd\tOptional pointer to receive ICE password of local\n *\t\t\tendpoint from the ICE session.\n * @param rem_ufrag\tOptional pointer to receive ICE username fragment\n *\t\t\tof remote endpoint from the ICE session.\n * @param rem_pwd\tOptional pointer to receive ICE password of remote\n *\t\t\tendpoint from the ICE session.\n *\n * @return\t\tPJ_SUCCESS if the strings have been retrieved\n *\t\t\tsuccessfully.\n */\nPJ_DECL(pj_status_t) pj_ice_strans_get_ufrag_pwd(pj_ice_strans *ice_st,\n\t\t\t\t\t\t pj_str_t *loc_ufrag,\n\t\t\t\t\t\t pj_str_t *loc_pwd,\n\t\t\t\t\t\t pj_str_t *rem_ufrag,\n\t\t\t\t\t\t pj_str_t *rem_pwd);\n\n\n/**\n * Get the number of local candidates for the specified component ID.\n *\n * @param ice_st\tThe ICE stream transport.\n * @param comp_id\tComponent ID.\n *\n * @return\t\tThe number of candidates.\n */\nPJ_DECL(unsigned) pj_ice_strans_get_cands_count(pj_ice_strans *ice_st,\n\t\t\t\t\t        unsigned comp_id);\n\n/**\n * Enumerate the local candidates for the specified component.\n *\n * @param ice_st\tThe ICE stream transport.\n * @param comp_id\tComponent ID.\n * @param count\t\tOn input, it specifies the maximum number of\n *\t\t\telements. On output, it will be filled with\n *\t\t\tthe number of candidates copied to the\n *\t\t\tarray.\n * @param cand\t\tArray of candidates.\n *\n * @return\t\tPJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ice_strans_enum_cands(pj_ice_strans *ice_st,\n\t\t\t\t\t      unsigned comp_id,\n\t\t\t\t\t      unsigned *count,\n\t\t\t\t\t      pj_ice_sess_cand cand[]);\n\n/**\n * Get the default candidate for the specified component. When this\n * function is called before ICE negotiation completes, the default\n * candidate is selected according to local preference criteria. When\n * this function is called after ICE negotiation completes, the\n * default candidate is the candidate that forms the valid pair.\n *\n * @param ice_st\tThe ICE stream transport.\n * @param comp_id\tComponent ID.\n * @param cand\t\tPointer to receive the default candidate\n *\t\t\tinformation.\n */\nPJ_DECL(pj_status_t) pj_ice_strans_get_def_cand(pj_ice_strans *ice_st,\n\t\t\t\t\t\tunsigned comp_id,\n\t\t\t\t\t\tpj_ice_sess_cand *cand);\n\n/**\n * Get the current ICE role. ICE session must have been initialized\n * before this function can be called.\n *\n * @param ice_st\tThe ICE stream transport.\n *\n * @return\t\tCurrent ICE role.\n */\nPJ_DECL(pj_ice_sess_role) pj_ice_strans_get_role(pj_ice_strans *ice_st);\n\n\n/**\n * Change session role. This happens for example when ICE session was\n * created with controlled role when receiving an offer, but it turns out\n * that the offer contains \"a=ice-lite\" attribute when the SDP gets\n * inspected. ICE session must have been initialized before this function\n * can be called.\n *\n * @param ice_st\tThe ICE stream transport.\n * @param new_role\tThe new role to be set.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error.\n */\nPJ_DECL(pj_status_t) pj_ice_strans_change_role(pj_ice_strans *ice_st,\n\t\t\t\t\t       pj_ice_sess_role new_role);\n\n\n/**\n * Start ICE connectivity checks. This function can only be called\n * after the ICE session has been created in the ICE stream transport\n * with #pj_ice_strans_init_ice().\n *\n * This function must be called once application has received remote\n * candidate list (typically from the remote SDP). This function pairs\n * local candidates with remote candidates, and starts ICE connectivity\n * checks. The ICE session/transport will then notify the application \n * via the callback when ICE connectivity checks completes, either \n * successfully or with failure.\n *\n * @param ice_st\tThe ICE stream transport.\n * @param rem_ufrag\tRemote ufrag, as seen in the SDP received from \n *\t\t\tthe remote agent.\n * @param rem_passwd\tRemote password, as seen in the SDP received from\n *\t\t\tthe remote agent.\n * @param rcand_cnt\tNumber of remote candidates in the array.\n * @param rcand\t\tRemote candidates array.\n *\n * @return\t\tPJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ice_strans_start_ice(pj_ice_strans *ice_st,\n\t\t\t\t\t     const pj_str_t *rem_ufrag,\n\t\t\t\t\t     const pj_str_t *rem_passwd,\n\t\t\t\t\t     unsigned rcand_cnt,\n\t\t\t\t\t     const pj_ice_sess_cand rcand[]);\n\n/**\n * Retrieve the candidate pair that has been nominated and successfully\n * checked for the specified component. If ICE negotiation is still in\n * progress or it has failed, this function will return NULL.\n *\n * @param ice_st\tThe ICE stream transport.\n * @param comp_id\tComponent ID.\n *\n * @return\t\tThe valid pair as ICE checklist structure if the\n *\t\t\tpair exist.\n */\nPJ_DECL(const pj_ice_sess_check*) \npj_ice_strans_get_valid_pair(const pj_ice_strans *ice_st,\n\t\t\t     unsigned comp_id);\n\n/**\n * Retrieve the ICE session associated with this transport\n *\n * @param ice_st\tThe ICE stream transport.\n *\n * @return\t\tThe ICE session associated with this transport\n */\nPJ_DECL(pj_ice_sess*)\npj_ice_strans_get_session(const pj_ice_strans *ice_st);\n\n/**\n * Retrieve the ICE start time\n *\n * @param ice_st\tThe ICE stream transport.\n *\n * @return\t\tThe ICE start time\n */\nPJ_DECL(pj_time_val)\npj_ice_strans_get_start_time(const pj_ice_strans *ice_st);\n\n/**\n * Stop and destroy the ICE session inside this media transport. Application\n * needs to call this function once the media session is over (the call has\n * been disconnected).\n *\n * Application MAY reuse this ICE stream transport for subsequent calls.\n * In this case, it must call #pj_ice_strans_stop_ice() when the call is\n * disconnected, and reinitialize the ICE stream transport for subsequent\n * call with #pj_ice_strans_init_ice()/#pj_ice_strans_start_ice(). In this\n * case, the ICE stream transport will maintain the internal sockets and\n * continue to send STUN keep-alive packets and TURN Refresh request to \n * keep the NAT binding/TURN allocation open and to detect change in STUN\n * mapped address.\n *\n * If application does not want to reuse the ICE stream transport for\n * subsequent calls, it must call #pj_ice_strans_destroy() to destroy the\n * ICE stream transport altogether.\n *\n * @param ice_st\tThe ICE stream transport.\n *\n * @return\t\tPJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_ice_strans_stop_ice(pj_ice_strans *ice_st);\n\n\n/**\n * Send outgoing packet using this transport. \n * Application can send data (normally RTP or RTCP packets) at any time\n * by calling this function. This function takes a destination\n * address as one of the arguments, and this destination address should\n * be taken from the default transport address of the component (that is\n * the address in SDP c= and m= lines, or in a=rtcp attribute). \n * If ICE negotiation is in progress, this function will send the data \n * to the destination address. Otherwise if ICE negotiation has completed\n * successfully, this function will send the data to the nominated remote \n * address, as negotiated by ICE.\n *\n * @param ice_st\tThe ICE stream transport.\n * @param comp_id\tComponent ID.\n * @param data\t\tThe data or packet to be sent.\n * @param data_len\tSize of data or packet, in bytes.\n * @param dst_addr\tThe destination address.\n * @param dst_addr_len\tLength of destination address.\n *\n * @return\t\tPJ_SUCCESS if data is sent successfully.\n */\nPJ_DECL(pj_status_t) pj_ice_strans_sendto(pj_ice_strans *ice_st,\n\t\t\t\t\t  unsigned comp_id,\n\t\t\t\t\t  const void *data,\n\t\t\t\t\t  pj_size_t data_len,\n\t\t\t\t\t  const pj_sockaddr_t *dst_addr,\n\t\t\t\t\t  int dst_addr_len);\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n\n#endif\t/* __PJNATH_ICE_STRANS_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/nat_detect.h",
    "content": "/* $Id: nat_detect.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_NAT_DETECT_H__\n#define __PJNATH_NAT_DETECT_H__\n\n/**\n * @file ice_session.h\n * @brief ICE session management\n */\n#include <pjnath/stun_session.h>\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJNATH_NAT_DETECT NAT Classification/Detection Tool\n * @brief NAT Classification/Detection Tool\n * @ingroup PJNATH\n * @{\n *\n * This module provides one function to perform NAT classification and\n * detection. NAT type detection is performed by calling\n * #pj_stun_detect_nat_type() function.\n */\n\n\n/**\n * This enumeration describes the NAT types, as specified by RFC 3489\n * Section 5, NAT Variations.\n */\ntypedef enum pj_stun_nat_type\n{\n    /**\n     * NAT type is unknown because the detection has not been performed.\n     */\n    PJ_STUN_NAT_TYPE_UNKNOWN,\n\n    /**\n     * NAT type is unknown because there is failure in the detection\n     * process, possibly because server does not support RFC 3489.\n     */\n    PJ_STUN_NAT_TYPE_ERR_UNKNOWN,\n\n    /**\n     * This specifies that the client has open access to Internet (or\n     * at least, its behind a firewall that behaves like a full-cone NAT,\n     * but without the translation)\n     */\n    PJ_STUN_NAT_TYPE_OPEN,\n\n    /**\n     * This specifies that communication with server has failed, probably\n     * because UDP packets are blocked.\n     */\n    PJ_STUN_NAT_TYPE_BLOCKED,\n\n    /**\n     * Firewall that allows UDP out, and responses have to come back to\n     * the source of the request (like a symmetric NAT, but no\n     * translation.\n     */\n    PJ_STUN_NAT_TYPE_SYMMETRIC_UDP,\n\n    /**\n     * A full cone NAT is one where all requests from the same internal \n     * IP address and port are mapped to the same external IP address and\n     * port.  Furthermore, any external host can send a packet to the \n     * internal host, by sending a packet to the mapped external address.\n     */\n    PJ_STUN_NAT_TYPE_FULL_CONE,\n\n    /**\n     * A symmetric NAT is one where all requests from the same internal \n     * IP address and port, to a specific destination IP address and port,\n     * are mapped to the same external IP address and port.  If the same \n     * host sends a packet with the same source address and port, but to \n     * a different destination, a different mapping is used.  Furthermore,\n     * only the external host that receives a packet can send a UDP packet\n     * back to the internal host.\n     */\n    PJ_STUN_NAT_TYPE_SYMMETRIC,\n\n    /**\n     * A restricted cone NAT is one where all requests from the same \n     * internal IP address and port are mapped to the same external IP \n     * address and port.  Unlike a full cone NAT, an external host (with \n     * IP address X) can send a packet to the internal host only if the \n     * internal host had previously sent a packet to IP address X.\n     */\n    PJ_STUN_NAT_TYPE_RESTRICTED,\n\n    /**\n     * A port restricted cone NAT is like a restricted cone NAT, but the \n     * restriction includes port numbers. Specifically, an external host \n     * can send a packet, with source IP address X and source port P, \n     * to the internal host only if the internal host had previously sent\n     * a packet to IP address X and port P.\n     */\n    PJ_STUN_NAT_TYPE_PORT_RESTRICTED\n\n} pj_stun_nat_type;\n\n\n/**\n * This structure contains the result of NAT classification function.\n */\ntypedef struct pj_stun_nat_detect_result\n{\n    /**\n     * Status of the detection process. If this value is not PJ_SUCCESS,\n     * the detection has failed and \\a nat_type field will contain\n     * PJ_STUN_NAT_TYPE_UNKNOWN.\n     */\n    pj_status_t\t\t status;\n\n    /**\n     * The text describing the status, if the status is not PJ_SUCCESS.\n     */\n    const char\t\t*status_text;\n\n    /**\n     * This contains the NAT type as detected by the detection procedure.\n     * This value is only valid when the \\a status is PJ_SUCCESS.\n     */\n    pj_stun_nat_type\t nat_type;\n\n    /**\n     * Text describing that NAT type.\n     */\n    const char\t\t*nat_type_name;\n\n} pj_stun_nat_detect_result;\n\n\n/**\n * Type of callback to be called when the NAT detection function has\n * completed.\n */\ntypedef void pj_stun_nat_detect_cb(void *user_data,\n\t\t\t\t   const pj_stun_nat_detect_result *res);\n\n\n/**\n * Get the NAT name from the specified NAT type.\n *\n * @param type\t\tNAT type.\n *\n * @return\t\tNAT name.\n */\nPJ_DECL(const char*) pj_stun_get_nat_name(pj_stun_nat_type type);\n\n\n/**\n * Perform NAT classification function according to the procedures\n * specified in RFC 3489. Once this function returns successfully,\n * the procedure will run in the \"background\" and will complete\n * asynchronously. Application can register a callback to be notified\n * when such detection has completed.\n *\n * @param server\tSTUN server address.\n * @param stun_cfg\tA structure containing various STUN configurations,\n *\t\t\tsuch as the ioqueue and timer heap instance used\n *\t\t\tto receive network I/O and timer events.\n * @param user_data\tApplication data, which will be returned back\n *\t\t\tin the callback.\n * @param cb\t\tCallback to be registered to receive notification\n *\t\t\tabout detection result.\n *\n * @return\t\tIf this function returns PJ_SUCCESS, the procedure\n *\t\t\twill complete asynchronously and callback will be\n *\t\t\tcalled when it completes. For other return\n *\t\t\tvalues, it means that an error has occured and\n *\t\t\tthe procedure did not start.\n */\nPJ_DECL(pj_status_t) pj_stun_detect_nat_type(const pj_sockaddr_in *server,\n\t\t\t\t\t     pj_stun_config *stun_cfg,\n\t\t\t\t\t     void *user_data,\n\t\t\t\t\t     pj_stun_nat_detect_cb *cb);\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJNATH_NAT_DETECT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/stun_auth.h",
    "content": "/* $Id: stun_auth.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_STUN_AUTH_H__\n#define __PJNATH_STUN_AUTH_H__\n\n/**\n * @file stun_auth.h\n * @brief STUN authentication.\n */\n\n#include <pjnath/stun_msg.h>\n\n\nPJ_BEGIN_DECL\n\n\n/* **************************************************************************/\n/**\n * @defgroup PJNATH_STUN_AUTH STUN Authentication\n * @brief STUN authentication helper\n * @ingroup PJNATH_STUN_BASE\n * @{\n */\n\n/**\n * Type of authentication.\n */\ntypedef enum pj_stun_auth_type\n{ \n    /**\n     * No authentication.\n     */\n    PJ_STUN_AUTH_NONE = 0,\n\n    /**\n     * Authentication using short term credential.\n     */\n    PJ_STUN_AUTH_SHORT_TERM = 1,\n\n    /**\n     * Authentication using long term credential.\n     */\n    PJ_STUN_AUTH_LONG_TERM = 2\n\n} pj_stun_auth_type;\n\n\n/**\n * Type of authentication data in the credential.\n */\ntypedef enum pj_stun_auth_cred_type\n{\n    /**\n     * The credential data contains a static credential to be matched \n     * against the credential in the message. A static credential can be \n     * used as both client side or server side authentication.\n     */\n    PJ_STUN_AUTH_CRED_STATIC,\n\n    /**\n     * The credential data contains callbacks to be called to verify the \n     * credential in the message. A dynamic credential is suitable when \n     * performing server side authentication where server does not know\n     * in advance the identity of the user requesting authentication.\n     */\n    PJ_STUN_AUTH_CRED_DYNAMIC\n\n} pj_stun_auth_cred_type;\n\n\n/**\n * Type of encoding applied to the password stored in the credential.\n */\ntypedef enum pj_stun_passwd_type\n{\n    /**\n     * Plain text password.\n     */\n    PJ_STUN_PASSWD_PLAIN    = 0,\n\n    /**\n     * Hashed password, valid for long term credential only. The hash value\n     * of the password is calculated as MD5(USERNAME \":\" REALM \":\" PASSWD)\n     * with all quotes removed from the username and realm values.\n     */\n    PJ_STUN_PASSWD_HASHED = 1\n\n} pj_stun_passwd_type;\n\n\n/**\n * This structure contains the descriptions needed to perform server side\n * authentication. Depending on the \\a type set in the structure, application\n * may specify a static username/password combination, or to have callbacks\n * called by the function to authenticate the credential dynamically.\n */\ntypedef struct pj_stun_auth_cred\n{\n    /**\n     * The type of authentication information in this structure.\n     */\n    pj_stun_auth_cred_type\ttype;\n\n    /**\n     * This union contains the authentication data.\n     */\n    union \n    {\n\t/**\n\t * This structure contains static data for performing authentication.\n\t * A non-empty realm indicates whether short term or long term\n\t * credential is used.\n\t */\n\tstruct\n\t{\n\t    /** \n\t     * If not-empty, it indicates that this is a long term credential.\n\t     */\n\t    pj_str_t\t\trealm;\n\n\t    /** \n\t     * The username of the credential.\n\t     */\n\t    pj_str_t\t\tusername;\n\n\t    /**\n\t     * Data type to indicate the type of password in the \\a data field.\n\t     */\n\t    pj_stun_passwd_type\tdata_type;\n\n\t    /** \n\t     * The data, which depends depends on the value of \\a data_type\n\t     * field. When \\a data_type is zero, this field will contain the\n\t     * plaintext password.\n\t     */\n\t    pj_str_t\t\tdata;\n\n\t    /** \n\t     * Optional NONCE.\n\t     */\n\t    pj_str_t\t\tnonce;\n\n\t} static_cred;\n\n\t/**\n\t * This structure contains callback to be called by the framework\n\t * to authenticate the incoming message.\n\t */\n\tstruct\n\t{\n\t    /**\n\t     * User data which will be passed back to callback functions.\n\t     */\n\t    void *user_data;\n\n\t    /**\n\t     * This callback is called by pj_stun_verify_credential() when\n\t     * server needs to challenge the request with 401 response.\n\t     *\n\t     * @param user_data\tThe user data as specified in the credential.\n\t     * @param pool\tPool to allocate memory.\n\t     * @param realm\tOn return, the function should fill in with\n\t     *\t\t\trealm if application wants to use long term\n\t     *\t\t\tcredential. Otherwise application should set\n\t     *\t\t\tempty string for the realm.\n\t     * @param nonce\tOn return, if application wants to use long\n\t     *\t\t\tterm credential, it MUST fill in the nonce\n\t     *\t\t\twith some value. Otherwise  if short term \n\t     *\t\t\tcredential is wanted, it MAY set this value.\n\t     *\t\t\tIf short term credential is wanted and the\n\t     *\t\t\tapplication doesn't want to include NONCE,\n\t     *\t\t\tthen it must set this to empty string.\n\t     *\n\t     * @return\t\tThe callback should return PJ_SUCCESS, or\n\t     *\t\t\totherwise response message will not be \n\t     *\t\t\tcreated.\n\t     */\n\t    pj_status_t (*get_auth)(void *user_data,\n\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t    pj_str_t *realm,\n\t\t\t\t    pj_str_t *nonce);\n\n\t    /**\n\t     * Get the credential to be put in outgoing request.\n\t     *\n\t     * @param msg\tThe outgoing message where the credential is\n\t     *\t\t\tto be applied.\n\t     * @param user_data\tThe user data as specified in the credential.\n\t     * @param pool\tPool where the callback can allocate memory\n\t     *\t\t\tto fill in the credential.\n\t     * @param realm\tOn return, the callback may specify the realm\n\t     *\t\t\tif long term credential is desired, otherwise\n\t     *\t\t\tthis string must be set to empty.\n\t     * @param username\tOn return, the callback must fill in with the\n\t     *\t\t\tusername.\n\t     * @param nonce\tOn return, the callback may optionally fill in\n\t     *\t\t\tthis argument with NONCE value if desired,\n\t     *\t\t\totherwise this argument must be set to empty.\n\t     * @param data_type\tOn return, the callback must set this argument\n\t     *\t\t\twith the type of password in the data argument.\n\t     * @param data\tOn return, the callback must set this with\n\t     *\t\t\tthe password, encoded according to data_type\n\t     *\t\t\targument.\n\t     *\n\t     * @return\t\tThe callback must return PJ_SUCCESS, otherwise\n\t     *\t\t\tthe message transmission will be cancelled.\n\t     */\n\t    pj_status_t (*get_cred)(const pj_stun_msg *msg,\n\t\t\t\t    void *user_data,\n\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t    pj_str_t *realm,\n\t\t\t\t    pj_str_t *username,\n\t\t\t\t    pj_str_t *nonce,\n\t\t\t\t    pj_stun_passwd_type *data_type,\n\t\t\t\t    pj_str_t *data);\n\n\t    /**\n\t     * Get the password for the specified username. This function \n\t     * is also used to check whether the username is valid.\n\t     *\n\t     * @param msg\tThe STUN message where the password will be\n\t     *\t\t\tapplied to.\n\t     * @param user_data\tThe user data as specified in the credential.\n\t     * @param realm\tThe realm as specified in the message.\n\t     * @param username\tThe username as specified in the message.\n\t     * @param pool\tPool to allocate memory when necessary.\n\t     * @param data_type On return, application should fill up this\n\t     *\t\t\targument with the type of data (which should\n\t     *\t\t\tbe zero if data is a plaintext password).\n\t     * @param data\tOn return, application should fill up this\n\t     *\t\t\targument with the password according to\n\t     *\t\t\tdata_type.\n\t     *\n\t     * @return\t\tThe callback should return PJ_SUCCESS if\n\t     *\t\t\tusername has been successfully verified\n\t     *\t\t\tand password was obtained. If non-PJ_SUCCESS\n\t     *\t\t\tis returned, it is assumed that the\n\t     *\t\t\tusername is not valid.\n\t     */\n\t    pj_status_t\t(*get_password)(const pj_stun_msg *msg,\n\t\t\t\t\tvoid *user_data, \n\t\t\t\t        const pj_str_t *realm,\n\t\t\t\t        const pj_str_t *username,\n\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\tpj_stun_passwd_type *data_type,\n\t\t\t\t\tpj_str_t *data);\n\n\t    /**\n\t     * This callback will be called to verify that the NONCE given\n\t     * in the message can be accepted. If this callback returns\n\t     * PJ_FALSE, 438 (Stale Nonce) response will be created.\n\t     *\n\t     * This callback is optional.\n\t     *\n\t     * @param msg\tThe STUN message where the nonce was received.\n\t     * @param user_data\tThe user data as specified in the credential.\n\t     * @param realm\tThe realm as specified in the message.\n\t     * @param username\tThe username as specified in the message.\n\t     * @param nonce\tThe nonce to be verified.\n\t     *\n\t     * @return\t\tThe callback MUST return non-zero if the \n\t     *\t\t\tNONCE can be accepted.\n\t     */\n\t    pj_bool_t\t(*verify_nonce)(const pj_stun_msg *msg,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tconst pj_str_t *realm,\n\t\t\t\t\tconst pj_str_t *username,\n\t\t\t\t\tconst pj_str_t *nonce);\n\n\t} dyn_cred;\n\n    } data;\n\n} pj_stun_auth_cred;\n\n\n/**\n * This structure contains the credential information that is found and\n * used to authenticate incoming requests. Application may use this\n * information when generating authentication for the outgoing response.\n */\ntypedef struct pj_stun_req_cred_info\n{\n    /**\n     * The REALM value found in the incoming request. If short term \n     * credential is used, the value will be empty.\n     */\n    pj_str_t\trealm;\n\n    /**\n     * The USERNAME value found in the incoming request.\n     */\n    pj_str_t\tusername;\n\n    /**\n     * Optional NONCE.\n     */\n    pj_str_t\tnonce;\n\n    /**\n     * Authentication key that was used to authenticate the incoming \n     * request. This key is created with #pj_stun_create_key(), and\n     * it can be used to encode the credential of the outgoing\n     * response.\n     */\n    pj_str_t\tauth_key;\n\n} pj_stun_req_cred_info;\n\n\n/**\n * Duplicate authentication credential.\n *\n * @param pool\t\tPool to be used to allocate memory.\n * @param dst\t\tDestination credential.\n * @param src\t\tSource credential.\n */\nPJ_DECL(void) pj_stun_auth_cred_dup(pj_pool_t *pool,\n\t\t\t\t      pj_stun_auth_cred *dst,\n\t\t\t\t      const pj_stun_auth_cred *src);\n\n/**\n * Duplicate request credential.\n *\n * @param pool\t\tPool to be used to allocate memory.\n * @param dst\t\tDestination credential.\n * @param src\t\tSource credential.\n */\nPJ_DECL(void) pj_stun_req_cred_info_dup(pj_pool_t *pool,\n\t\t\t\t\tpj_stun_req_cred_info *dst,\n\t\t\t\t\tconst pj_stun_req_cred_info *src);\n\n\n/**\n * Create authentication key to be used for encoding the message with\n * MESSAGE-INTEGRITY. If short term credential is used (i.e. the realm\n * argument is NULL or empty), the key will be copied from the password.\n * If long term credential is used, the key will be calculated from the\n * MD5 hash of the realm, username, and password.\n *\n * @param pool\t\tPool to allocate memory for the key.\n * @param key\t\tString to receive the key.\n * @param realm\t\tThe realm of the credential, if long term credential\n *\t\t\tis to be used. If short term credential is wanted,\n *\t\t\tapplication can put NULL or empty string here.\n * @param username\tThe username.\n * @param data_type\tPassword encoding.\n * @param data\t\tThe password.\n */\nPJ_DECL(void) pj_stun_create_key(pj_pool_t *pool,\n\t\t\t\t pj_str_t *key,\n\t\t\t\t const pj_str_t *realm,\n\t\t\t\t const pj_str_t *username,\n\t\t\t\t pj_stun_passwd_type data_type,\n\t\t\t\t const pj_str_t *data);\n\n/**\n * Verify credential in the STUN request. Note that before calling this\n * function, application must have checked that the message contains\n * PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute by calling pj_stun_msg_find_attr()\n * function, because this function will reject the message with 401 error\n * if it doesn't contain PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute.\n *\n * @param pkt\t\tThe original packet which has been parsed into\n *\t\t\tthe message. This packet MUST NOT have been modified\n *\t\t\tafter the parsing.\n * @param pkt_len\tThe length of the packet.\n * @param msg\t\tThe parsed message to be verified.\n * @param cred\t\tPointer to credential to be used to authenticate\n *\t\t\tthe message.\n * @param pool\t\tIf response is to be created, then memory will\n *\t\t\tbe allocated from this pool.\n * @param info\t\tOptional pointer to receive authentication information\n *\t\t\tfound in the request and the credential that is used\n *\t\t\tto authenticate the request.\n * @param p_response\tOptional pointer to receive the response message\n *\t\t\tthen the credential in the request fails to\n *\t\t\tauthenticate.\n *\n * @return\t\tPJ_SUCCESS if credential is verified successfully.\n *\t\t\tIf the verification fails and \\a p_response is not\n *\t\t\tNULL, an appropriate response will be returned in\n *\t\t\t\\a p_response.\n */\nPJ_DECL(pj_status_t) pj_stun_authenticate_request(const pj_uint8_t *pkt,\n\t\t\t\t\t          unsigned pkt_len,\n\t\t\t\t\t          const pj_stun_msg *msg,\n\t\t\t\t\t          pj_stun_auth_cred *cred,\n\t\t\t\t\t          pj_pool_t *pool,\n\t\t\t\t\t\t  pj_stun_req_cred_info *info,\n\t\t\t\t\t          pj_stun_msg **p_response);\n\n\n/**\n * Determine if STUN message can be authenticated. Some STUN error\n * responses cannot be authenticated since they cannot contain STUN\n * MESSAGE-INTEGRITY attribute. STUN Indication messages also cannot\n * be authenticated.\n *\n * @param msg\t\tThe STUN message.\n *\n * @return\t\tNon-zero if the STUN message can be authenticated.\n */\nPJ_DECL(pj_bool_t) pj_stun_auth_valid_for_msg(const pj_stun_msg *msg);\n\n\n/**\n * Verify credential in the STUN response. Note that before calling this\n * function, application must have checked that the message contains\n * PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute by calling pj_stun_msg_find_attr()\n * function, because otherwise this function will report authentication\n * failure.\n *\n * @param pkt\t\tThe original packet which has been parsed into\n *\t\t\tthe message. This packet MUST NOT have been modified\n *\t\t\tafter the parsing.\n * @param pkt_len\tThe length of the packet.\n * @param msg\t\tThe parsed message to be verified.\n * @param key\t\tAuthentication key to calculate MESSAGE-INTEGRITY\n *\t\t\tvalue. Application can create this key by using\n *\t\t\t#pj_stun_create_key() function.\n *\n * @return\t\tPJ_SUCCESS if credential is verified successfully.\n */\nPJ_DECL(pj_status_t) pj_stun_authenticate_response(const pj_uint8_t *pkt,\n\t\t\t\t\t           unsigned pkt_len,\n\t\t\t\t\t           const pj_stun_msg *msg,\n\t\t\t\t\t           const pj_str_t *key);\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJNATH_STUN_AUTH_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/stun_config.h",
    "content": "/* $Id: stun_config.h 4199 2012-07-05 10:52:55Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_STUN_CONFIG_H__\n#define __PJNATH_STUN_CONFIG_H__\n\n/**\n * @file stun_config.h\n * @brief STUN endpoint.\n */\n\n#include <pjnath/stun_msg.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/string.h>\n\n\nPJ_BEGIN_DECL\n\n\n/* **************************************************************************/\n/**\n * @defgroup PJNATH_STUN_CONFIG STUN Config\n * @brief STUN config\n * @ingroup PJNATH_STUN_BASE\n * @{\n */\n\n/**\n * STUN configuration.\n */\ntypedef struct pj_stun_config\n{\n    /**\n     * Pool factory to be used.\n     */\n    pj_pool_factory\t*pf;\n\n    /**\n     * Ioqueue.\n     */\n    pj_ioqueue_t\t*ioqueue;\n\n    /**\n     * Timer heap instance.\n     */\n    pj_timer_heap_t\t*timer_heap;\n\n    /**\n     * Options.\n     */\n    unsigned\t\t options;\n\n    /**\n     * The default initial STUN round-trip time estimation in msecs.\n     * The value normally is PJ_STUN_RTO_VALUE.\n     */\n    unsigned\t\t rto_msec;\n\n    /**\n     * The interval to cache outgoing  STUN response in the STUN session,\n     * in miliseconds. \n     *\n     * Default 10000 (10 seconds).\n     */\n    unsigned\t\t res_cache_msec;\n\n    /**\n     * Software name to be included in all STUN requests and responses.\n     *\n     * Default: PJNATH_STUN_SOFTWARE_NAME.\n     */\n    pj_str_t\t\t software_name;\n\n} pj_stun_config;\n\n\n\n/**\n * Initialize STUN config.\n */\nPJ_INLINE(void) pj_stun_config_init(pj_stun_config *cfg,\n\t\t\t\t    pj_pool_factory *factory,\n\t\t\t\t    unsigned options,\n\t\t\t\t    pj_ioqueue_t *ioqueue,\n\t\t\t\t    pj_timer_heap_t *timer_heap)\n{\n    pj_bzero(cfg, sizeof(*cfg));\n\n    cfg->pf = factory;\n    cfg->options = options;\n    cfg->ioqueue = ioqueue;\n    cfg->timer_heap = timer_heap;\n    cfg->rto_msec = PJ_STUN_RTO_VALUE;\n    cfg->res_cache_msec = PJ_STUN_RES_CACHE_DURATION;\n    cfg->software_name = pj_str((char*)PJNATH_STUN_SOFTWARE_NAME);\n}\n\n\n/**\n * Check that STUN config is valid.\n */\nPJ_INLINE(pj_status_t) pj_stun_config_check_valid(const pj_stun_config *cfg)\n{\n    PJ_ASSERT_RETURN(cfg->ioqueue && cfg->pf && cfg->timer_heap &&\n\t\t     cfg->rto_msec && cfg->res_cache_msec, PJ_EINVAL);\n    return PJ_SUCCESS;\n}\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJNATH_STUN_CONFIG_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/stun_msg.h",
    "content": "/* $Id: stun_msg.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_STUN_MSG_H__\n#define __PJNATH_STUN_MSG_H__\n\n/**\n * @file stun_msg.h\n * @brief STUN message components.\n */\n\n#include <pjnath/types.h>\n#include <pj/sock.h>\n\n\nPJ_BEGIN_DECL\n\n\n/* **************************************************************************/\n/**\n * @defgroup PJNATH_STUN_MSG STUN Message Representation and Parsing\n * @ingroup PJNATH_STUN_BASE\n * @brief Low-level representation and parsing of STUN messages.\n * @{\n */\n\n\n/**\n * STUN magic cookie.\n */\n#define PJ_STUN_MAGIC\t\t\t    0x2112A442\n\n\n/**\n * STUN method constants.\n */\nenum pj_stun_method_e\n{\n    /**\n     * STUN Binding method as defined by RFC 3489-bis.\n     */\n    PJ_STUN_BINDING_METHOD\t\t    = 1,\n\n    /**\n     * STUN Shared Secret method as defined by RFC 3489-bis.\n     */\n    PJ_STUN_SHARED_SECRET_METHOD\t    = 2,\n\n    /**\n     * STUN/TURN Allocate method as defined by draft-ietf-behave-turn\n     */\n    PJ_STUN_ALLOCATE_METHOD\t\t    = 3,\n\n    /**\n     * STUN/TURN Refresh method as defined by draft-ietf-behave-turn\n     */\n    PJ_STUN_REFRESH_METHOD\t\t    = 4,\n\n    /**\n     * STUN/TURN Send indication as defined by draft-ietf-behave-turn\n     */\n    PJ_STUN_SEND_METHOD\t\t\t    = 6,\n\n    /**\n     * STUN/TURN Data indication as defined by draft-ietf-behave-turn\n     */\n    PJ_STUN_DATA_METHOD\t\t\t    = 7,\n\n    /**\n     * STUN/TURN CreatePermission method as defined by draft-ietf-behave-turn\n     */\n    PJ_STUN_CREATE_PERM_METHOD\t\t    = 8,\n\n    /**\n     * STUN/TURN ChannelBind as defined by draft-ietf-behave-turn\n     */\n    PJ_STUN_CHANNEL_BIND_METHOD\t\t    = 9,\n\n    /**\n     * All known methods.\n     */\n    PJ_STUN_METHOD_MAX\n};\n\n\n/**\n * Retrieve the STUN method from the message-type field of the STUN\n * message.\n */\n#define PJ_STUN_GET_METHOD(msg_type)\t((msg_type) & 0xFEEF)\n\n\n/**\n * STUN message classes constants.\n */\nenum pj_stun_msg_class_e\n{\n    /**\n     * This specifies that the message type is a STUN request message.\n     */\n    PJ_STUN_REQUEST_CLASS\t    = 0,\n\n    /**\n     * This specifies that the message type is a STUN indication message.\n     */\n    PJ_STUN_INDICATION_CLASS\t    = 1,\n\n    /**\n     * This specifies that the message type is a STUN successful response.\n     */\n    PJ_STUN_SUCCESS_CLASS\t    = 2,\n\n    /**\n     * This specifies that the message type is a STUN error response.\n     */\n    PJ_STUN_ERROR_CLASS\t\t    = 3\n};\n\n\n/**\n * Determine if the message type is a request.\n */\n#define PJ_STUN_IS_REQUEST(msg_type)\t(((msg_type) & 0x0110) == 0x0000)\n\n\n/**\n * Determine if the message type is a successful response.\n */\n#define PJ_STUN_IS_SUCCESS_RESPONSE(msg_type) (((msg_type) & 0x0110) == 0x0100)\n\n/**\n * The response bit in the message type.\n */\n#define PJ_STUN_SUCCESS_RESPONSE_BIT\t(0x0100)\n\n\n/**\n * Determine if the message type is an error response.\n */\n#define PJ_STUN_IS_ERROR_RESPONSE(msg_type) (((msg_type) & 0x0110) == 0x0110)\n\n/**\n * The error response bit in the message type.\n */\n#define PJ_STUN_ERROR_RESPONSE_BIT\t(0x0110)\n\n/**\n * Determine if the message type is a response.\n */\n#define PJ_STUN_IS_RESPONSE(msg_type) (((msg_type) & 0x0100) == 0x0100)\n\n\n/**\n * Determine if the message type is an indication message.\n */\n#define PJ_STUN_IS_INDICATION(msg_type)\t(((msg_type) & 0x0110) == 0x0010)\n\n/**\n * The error response bit in the message type.\n */\n#define PJ_STUN_INDICATION_BIT\t\t(0x0010)\n\n\n/**\n * This enumeration describes STUN message types.\n */\ntypedef enum pj_stun_msg_type\n{\n    /**\n     * STUN BINDING request.\n     */\n    PJ_STUN_BINDING_REQUEST\t\t    = 0x0001,\n\n    /**\n     * Successful response to STUN BINDING-REQUEST.\n     */\n    PJ_STUN_BINDING_RESPONSE\t\t    = 0x0101,\n\n    /**\n     * Error response to STUN BINDING-REQUEST.\n     */\n    PJ_STUN_BINDING_ERROR_RESPONSE\t    = 0x0111,\n\n    /**\n     * Binding Indication (ICE)\n     */\n    PJ_STUN_BINDING_INDICATION\t\t    = 0x0011,\n\n    /**\n     * STUN SHARED-SECRET reqeust.\n     */\n    PJ_STUN_SHARED_SECRET_REQUEST\t    = 0x0002,\n\n    /**\n     * Successful response to STUN SHARED-SECRET reqeust.\n     */\n    PJ_STUN_SHARED_SECRET_RESPONSE\t    = 0x0102,\n\n    /**\n     * Error response to STUN SHARED-SECRET reqeust.\n     */\n    PJ_STUN_SHARED_SECRET_ERROR_RESPONSE    = 0x0112,\n\n\n    /**\n     * STUN/TURN Allocate Request\n     */\n    PJ_STUN_ALLOCATE_REQUEST\t\t    = 0x0003,\n\n    /**\n     * Successful response to STUN/TURN Allocate Request\n     */\n    PJ_STUN_ALLOCATE_RESPONSE\t\t    = 0x0103,\n\n    /**\n     * Failure response to STUN/TURN Allocate Request\n     */\n    PJ_STUN_ALLOCATE_ERROR_RESPONSE\t    = 0x0113,\n\n\n    /**\n     * STUN/TURN REFRESH Request\n     */\n    PJ_STUN_REFRESH_REQUEST\t\t    = 0x0004,\n\n    /**\n     * Successful response to STUN REFRESH request\n     */\n    PJ_STUN_REFRESH_RESPONSE\t\t    = 0x0104,\n\n    /**\n     * Error response to STUN REFRESH request.\n     */\n    PJ_STUN_REFRESH_ERROR_RESPONSE\t    = 0x0114,\n\n\n    /**\n     * TURN Send indication\n     */\n    PJ_STUN_SEND_INDICATION\t\t    = 0x0016,\n\n\n    /**\n     * TURN Data indication\n     */\n    PJ_STUN_DATA_INDICATION\t\t    = 0x0017,\n\n\n    /**\n     * TURN CreatePermission request\n     */\n    PJ_STUN_CREATE_PERM_REQUEST\t\t    = 0x0008,\n\n    /**\n     * TURN CreatePermission successful response.\n     */\n    PJ_STUN_CREATE_PERM_RESPONSE\t    = 0x0108,\n\n    /**\n     * TURN CreatePermission failure response\n     */\n    PJ_STUN_CREATE_PERM_ERROR_RESPONSE\t    = 0x0118,\n\n\n    /**\n     * STUN/TURN ChannelBind Request\n     */\n    PJ_STUN_CHANNEL_BIND_REQUEST\t    = 0x0009,\n\n    /**\n     * Successful response to STUN ChannelBind request\n     */\n    PJ_STUN_CHANNEL_BIND_RESPONSE\t    = 0x0109,\n\n    /**\n     * Error response to STUN ChannelBind request.\n     */\n    PJ_STUN_CHANNEL_BIND_ERROR_RESPONSE\t    = 0x0119\n\n} pj_stun_msg_type;\n\n\n\n/**\n * This enumeration describes STUN attribute types.\n */\ntypedef enum pj_stun_attr_type\n{\n    PJ_STUN_ATTR_MAPPED_ADDR\t    = 0x0001,/**< MAPPED-ADDRESS.\t    */\n    PJ_STUN_ATTR_RESPONSE_ADDR\t    = 0x0002,/**< RESPONSE-ADDRESS (deprcatd)*/\n    PJ_STUN_ATTR_CHANGE_REQUEST\t    = 0x0003,/**< CHANGE-REQUEST (deprecated)*/\n    PJ_STUN_ATTR_SOURCE_ADDR\t    = 0x0004,/**< SOURCE-ADDRESS (deprecated)*/\n    PJ_STUN_ATTR_CHANGED_ADDR\t    = 0x0005,/**< CHANGED-ADDRESS (deprecatd)*/\n    PJ_STUN_ATTR_USERNAME\t    = 0x0006,/**< USERNAME attribute.\t    */\n    PJ_STUN_ATTR_PASSWORD\t    = 0x0007,/**< was PASSWORD attribute.   */\n    PJ_STUN_ATTR_MESSAGE_INTEGRITY  = 0x0008,/**< MESSAGE-INTEGRITY.\t    */\n    PJ_STUN_ATTR_ERROR_CODE\t    = 0x0009,/**< ERROR-CODE.\t\t    */\n    PJ_STUN_ATTR_UNKNOWN_ATTRIBUTES = 0x000A,/**< UNKNOWN-ATTRIBUTES.\t    */\n    PJ_STUN_ATTR_REFLECTED_FROM\t    = 0x000B,/**< REFLECTED-FROM (deprecatd)*/\n    PJ_STUN_ATTR_CHANNEL_NUMBER\t    = 0x000C,/**< TURN CHANNEL-NUMBER\t    */\n    PJ_STUN_ATTR_LIFETIME\t    = 0x000D,/**< TURN LIFETIME attr.\t    */\n    PJ_STUN_ATTR_MAGIC_COOKIE\t    = 0x000F,/**< MAGIC-COOKIE attr (deprec)*/\n    PJ_STUN_ATTR_BANDWIDTH\t    = 0x0010,/**< TURN BANDWIDTH (deprec)   */\n    PJ_STUN_ATTR_XOR_PEER_ADDR\t    = 0x0012,/**< TURN XOR-PEER-ADDRESS\t    */\n    PJ_STUN_ATTR_DATA\t\t    = 0x0013,/**< DATA attribute.\t    */\n    PJ_STUN_ATTR_REALM\t\t    = 0x0014,/**< REALM attribute.\t    */\n    PJ_STUN_ATTR_NONCE\t\t    = 0x0015,/**< NONCE attribute.\t    */\n    PJ_STUN_ATTR_XOR_RELAYED_ADDR   = 0x0016,/**< TURN XOR-RELAYED-ADDRESS  */\n    PJ_STUN_ATTR_REQ_ADDR_TYPE\t    = 0x0017,/**< REQUESTED-ADDRESS-TYPE    */\n    PJ_STUN_ATTR_EVEN_PORT\t    = 0x0018,/**< TURN EVEN-PORT\t    */\n    PJ_STUN_ATTR_REQ_TRANSPORT\t    = 0x0019,/**< TURN REQUESTED-TRANSPORT  */\n    PJ_STUN_ATTR_DONT_FRAGMENT\t    = 0x001A,/**< TURN DONT-FRAGMENT\t    */\n    PJ_STUN_ATTR_XOR_MAPPED_ADDR    = 0x0020,/**< XOR-MAPPED-ADDRESS\t    */\n    PJ_STUN_ATTR_TIMER_VAL\t    = 0x0021,/**< TIMER-VAL attribute.\t    */\n    PJ_STUN_ATTR_RESERVATION_TOKEN  = 0x0022,/**< TURN RESERVATION-TOKEN    */\n    PJ_STUN_ATTR_XOR_REFLECTED_FROM = 0x0023,/**< XOR-REFLECTED-FROM\t    */\n    PJ_STUN_ATTR_PRIORITY\t    = 0x0024,/**< PRIORITY\t\t    */\n    PJ_STUN_ATTR_USE_CANDIDATE\t    = 0x0025,/**< USE-CANDIDATE\t\t    */\n    PJ_STUN_ATTR_ICMP\t\t    = 0x0030,/**< ICMP (TURN)\t\t    */\n\n    PJ_STUN_ATTR_END_MANDATORY_ATTR,\n\n    PJ_STUN_ATTR_START_EXTENDED_ATTR= 0x8021,\n\n    PJ_STUN_ATTR_SOFTWARE\t    = 0x8022,/**< SOFTWARE attribute.\t    */\n    PJ_STUN_ATTR_ALTERNATE_SERVER   = 0x8023,/**< ALTERNATE-SERVER.\t    */\n    PJ_STUN_ATTR_REFRESH_INTERVAL   = 0x8024,/**< REFRESH-INTERVAL.\t    */\n    PJ_STUN_ATTR_FINGERPRINT\t    = 0x8028,/**< FINGERPRINT attribute.    */\n    PJ_STUN_ATTR_ICE_CONTROLLED\t    = 0x8029,/**< ICE-CCONTROLLED attribute.*/\n    PJ_STUN_ATTR_ICE_CONTROLLING    = 0x802a,/**< ICE-CCONTROLLING attribute*/\n\n    PJ_STUN_ATTR_END_EXTENDED_ATTR\n\n} pj_stun_attr_type;\n\n\n/**\n * STUN error codes, which goes into STUN ERROR-CODE attribute.\n */\ntypedef enum pj_stun_status\n{\n    PJ_STUN_SC_TRY_ALTERNATE\t\t= 300,  /**< Try Alternate\t    */\n    PJ_STUN_SC_BAD_REQUEST\t\t= 400,  /**< Bad Request\t    */\n    PJ_STUN_SC_UNAUTHORIZED\t        = 401,  /**< Unauthorized\t    */\n    PJ_STUN_SC_FORBIDDEN\t\t= 403,\t/**< Forbidden (TURN)\t    */\n    PJ_STUN_SC_UNKNOWN_ATTRIBUTE        = 420,  /**< Unknown Attribute\t    */\n#if 0\n    /* These were obsolete in recent rfc3489bis */\n    //PJ_STUN_SC_STALE_CREDENTIALS      = 430,  /**< Stale Credentials\t    */\n    //PJ_STUN_SC_INTEGRITY_CHECK_FAILURE= 431,  /**< Integrity Chk Fail\t    */\n    //PJ_STUN_SC_MISSING_USERNAME\t= 432,  /**< Missing Username\t    */\n    //PJ_STUN_SC_USE_TLS\t\t= 433,  /**< Use TLS\t\t    */\n    //PJ_STUN_SC_MISSING_REALM\t\t= 434,  /**< Missing Realm\t    */\n    //PJ_STUN_SC_MISSING_NONCE\t\t= 435,  /**< Missing Nonce\t    */\n    //PJ_STUN_SC_UNKNOWN_USERNAME\t= 436,  /**< Unknown Username\t    */\n#endif\n    PJ_STUN_SC_ALLOCATION_MISMATCH      = 437,  /**< TURN Alloc Mismatch    */\n    PJ_STUN_SC_STALE_NONCE\t        = 438,  /**< Stale Nonce\t    */\n    PJ_STUN_SC_TRANSITIONING\t\t= 439,  /**< Transitioning.\t    */\n    PJ_STUN_SC_WRONG_CREDENTIALS\t= 441,\t/**< TURN Wrong Credentials */\n    PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO   = 442,  /**< Unsupported Transport or\n\t\t\t\t\t\t     Protocol (TURN) */\n    PJ_STUN_SC_OPER_TCP_ONLY\t\t= 445,  /**< Operation for TCP Only */\n    PJ_STUN_SC_CONNECTION_FAILURE       = 446,  /**< Connection Failure\t    */\n    PJ_STUN_SC_CONNECTION_TIMEOUT       = 447,  /**< Connection Timeout\t    */\n    PJ_STUN_SC_ALLOCATION_QUOTA_REACHED = 486,  /**< Allocation Quota Reached\n\t\t\t\t\t\t     (TURN) */\n    PJ_STUN_SC_ROLE_CONFLICT\t\t= 487,  /**< Role Conflict\t    */\n    PJ_STUN_SC_SERVER_ERROR\t        = 500,  /**< Server Error\t    */\n    PJ_STUN_SC_INSUFFICIENT_CAPACITY\t= 508,  /**< Insufficient Capacity \n\t\t\t\t\t\t     (TURN) */\n    PJ_STUN_SC_GLOBAL_FAILURE\t        = 600   /**< Global Failure\t    */\n} pj_stun_status;\n\n\n/**\n * This structure describes STUN message header. A STUN message has the \n * following format:\n *\n * \\verbatim\n\n        0                   1                   2                   3\n        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n       |0 0|     STUN Message Type     |         Message Length        |\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n       |                         Magic Cookie                          |\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n       |\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n                                Transaction ID\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n                                                                       |\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n   \\endverbatim\n */\ntypedef struct pj_stun_msg_hdr\n{\n    /**\n     * STUN message type, which the first two bits must be zeroes.\n     */\n    pj_uint16_t\t\ttype;\n\n    /**\n     * The message length is the size, in bytes, of the message not\n     * including the 20 byte STUN header.\n     */\n    pj_uint16_t\t\tlength;\n\n    /**\n     * The magic cookie is a fixed value, 0x2112A442 (PJ_STUN_MAGIC constant).\n     * In the previous version of this specification [15] this field was part \n     * of the transaction ID.\n     */\n    pj_uint32_t\t\tmagic;\n\n    /**\n     * The transaction ID is a 96 bit identifier.  STUN transactions are\n     * identified by their unique 96-bit transaction ID.  For request/\n     * response transactions, the transaction ID is chosen by the STUN\n     * client and MUST be unique for each new STUN transaction generated by\n     * that STUN client.  The transaction ID MUST be uniformly and randomly\n     * distributed between 0 and 2**96 - 1. \n     */\n    pj_uint8_t\t\ttsx_id[12];\n\n} pj_stun_msg_hdr;\n\n\n/**\n * This structre describes STUN attribute header. Each attribute is\n * TLV encoded, with a 16 bit type, 16 bit length, and variable value.\n * Each STUN attribute ends on a 32 bit boundary:\n *\n * \\verbatim\n\n        0                   1                   2                   3\n        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n       |         Type                  |            Length             |\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n   \\endverbatim\n */\ntypedef struct pj_stun_attr_hdr\n{\n    /**\n     * STUN attribute type.\n     */\n    pj_uint16_t\t\ttype;\n\n    /**\n     * The Length refers to the length of the actual useful content of the\n     * Value portion of the attribute, measured in bytes. The value\n     * in the Length field refers to the length of the Value part of the\n     * attribute prior to padding - i.e., the useful content.\n     */\n    pj_uint16_t\t\tlength;\n\n} pj_stun_attr_hdr;\n\n\n/**\n * This structure describes STUN generic IP address attribute, used for\n * example to represent STUN MAPPED-ADDRESS attribute.\n *\n * The generic IP address attribute indicates the transport address.\n * It consists of an eight bit address family, and a sixteen bit port,\n * followed by a fixed length value representing the IP address.  If the\n * address family is IPv4, the address is 32 bits, in network byte\n * order.  If the address family is IPv6, the address is 128 bits in\n * network byte order.\n *\n * The format of the generic IP address attribute is:\n *\n * \\verbatim\n\n        0                   1                   2                   3\n        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n       |x x x x x x x x|    Family     |           Port                |\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n       |                   Address  (variable)\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n   \\endverbatim\n */\ntypedef struct pj_stun_sockaddr_attr\n{\n    /**\n     * Standard STUN attribute header.\n     */\n    pj_stun_attr_hdr\thdr;\n\n    /**\n     * Flag to indicate whether this attribute should be sent in XOR-ed\n     * format, or has been received in XOR-ed format.\n     */\n    pj_bool_t\t\txor_ed;\n\n    /**\n     * The socket address\n     */\n    pj_sockaddr\t\tsockaddr;\n\n} pj_stun_sockaddr_attr;\n\n\n/**\n * This structure represents a generic STUN attributes with no payload,\n * and it is used for example by ICE USE-CANDIDATE attribute.\n */\ntypedef struct pj_stun_empty_attr\n{\n    /**\n     * Standard STUN attribute header.\n     */\n    pj_stun_attr_hdr\thdr;\n\n} pj_stun_empty_attr;\n\n\n/**\n * This structure represents generic STUN string attributes, such as STUN\n * USERNAME, PASSWORD, SOFTWARE, REALM, and NONCE attributes.\n */\ntypedef struct pj_stun_string_attr\n{\n    /**\n     * Standard STUN attribute header.\n     */\n    pj_stun_attr_hdr\thdr;\n\n    /**\n     * The string value.\n     */\n    pj_str_t\t\tvalue;\n\n} pj_stun_string_attr;\n\n\n/**\n * This structure represents a generic STUN attributes with 32bit (unsigned)\n * integer value, such as STUN FINGERPRINT and REFRESH-INTERVAL attributes.\n */\ntypedef struct pj_stun_uint_attr\n{\n    /**\n     * Standard STUN attribute header.\n     */\n    pj_stun_attr_hdr\thdr;\n    \n    /**\n     * The 32bit value, in host byte order.\n     */\n    pj_uint32_t\t\tvalue;\n\n} pj_stun_uint_attr;\n\n\n/**\n * This structure represents a generic STUN attributes with 64bit (unsigned)\n * integer value, such as ICE-CONTROLLED and ICE-CONTROLLING attributes.\n */\ntypedef struct pj_stun_uint64_attr\n{\n    /**\n     * Standard STUN attribute header.\n     */\n    pj_stun_attr_hdr\thdr;\n    \n    /**\n     * The 64bit value, in host byte order, represented with pj_timestamp.\n     */\n    pj_timestamp\tvalue;\n\n} pj_stun_uint64_attr;\n\n\n/**\n * This structure represents generic STUN attributes to hold a raw binary\n * data.\n */\ntypedef struct pj_stun_binary_attr\n{\n    /**\n     * Standard STUN attribute header.\n     */\n    pj_stun_attr_hdr\thdr;\n    \n    /**\n     * Special signature to indicate that this is a valid attribute even\n     * though we don't have meta-data to describe this attribute.\n     */\n    pj_uint32_t\t\tmagic;\n\n    /**\n     * Length of the data.\n     */\n    unsigned\t\tlength;\n\n    /**\n     * The raw data.\n     */\n    pj_uint8_t\t       *data;\n\n} pj_stun_binary_attr;\n\n\n/**\n * This structure describes STUN MESSAGE-INTEGRITY attribute.\n * The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [10] of the\n * STUN message.  The MESSAGE-INTEGRITY attribute can be present in any\n * STUN message type.  Since it uses the SHA1 hash, the HMAC will be 20\n * bytes.\n */\ntypedef struct pj_stun_msgint_attr\n{\n    /**\n     * Standard STUN attribute header.\n     */\n    pj_stun_attr_hdr\thdr;\n\n    /**\n     * The 20 bytes hmac value.\n     */\n    pj_uint8_t\t\thmac[20];\n\n} pj_stun_msgint_attr;\n\n\n/**\n * This structure describes STUN FINGERPRINT attribute. The FINGERPRINT \n * attribute can be present in all STUN messages.  It is computed as \n * the CRC-32 of the STUN message up to (but excluding) the FINGERPRINT \n * attribute itself, xor-d with the 32 bit value 0x5354554e\n */\ntypedef struct pj_stun_uint_attr pj_stun_fingerprint_attr;\n\n\n/**\n * This structure represents STUN ERROR-CODE attribute. The ERROR-CODE \n * attribute is present in the Binding Error Response and Shared Secret \n * Error Response.  It is a numeric value in the range of 100 to 699 \n * plus a textual reason phrase encoded in UTF-8\n *\n * \\verbatim\n\n        0                   1                   2                   3\n        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n       |                   0                     |Class|     Number    |\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n       |      Reason Phrase (variable)                                ..\n       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n \\endverbatim\n */\ntypedef struct pj_stun_errcode_attr\n{\n    /**\n     * Standard STUN attribute header.\n     */\n    pj_stun_attr_hdr\thdr;\n\n    /**\n     * STUN error code.\n     */\n    int\t\t\terr_code;\n\n    /**\n     * The reason phrase.\n     */\n    pj_str_t\t\treason;\n\n} pj_stun_errcode_attr;\n\n\n/**\n * This describes STUN REALM attribute.\n * The REALM attribute is present in requests and responses.  It\n * contains text which meets the grammar for \"realm\" as described in RFC\n * 3261 [11], and will thus contain a quoted string (including the\n * quotes).\n */\ntypedef struct pj_stun_string_attr pj_stun_realm_attr;\n\n\n/**\n * This describes STUN NONCE attribute. \n * The NONCE attribute is present in requests and in error responses.\n * It contains a sequence of qdtext or quoted-pair, which are defined in\n * RFC 3261 [11].  See RFC 2617 [7] for guidance on selection of nonce\n * values in a server.\n */\ntypedef struct pj_stun_string_attr pj_stun_nonce_attr;\n\n\n/**\n * This describes STUN UNKNOWN-ATTRIBUTES attribute.\n * The UNKNOWN-ATTRIBUTES attribute is present only in an error response\n * when the response code in the ERROR-CODE attribute is 420.\n * The attribute contains a list of 16 bit values, each of which\n * represents an attribute type that was not understood by the server.\n * If the number of unknown attributes is an odd number, one of the\n * attributes MUST be repeated in the list, so that the total length of\n * the list is a multiple of 4 bytes.\n */\ntypedef struct pj_stun_unknown_attr\n{\n    /**\n     * Standard STUN attribute header.\n     */\n    pj_stun_attr_hdr\thdr;\n\n    /**\n     * Number of unknown attributes in the array.\n     */\n    unsigned\t\tattr_count;\n\n    /**\n     * Array of unknown attribute IDs.\n     */\n    pj_uint16_t\t        attrs[PJ_STUN_MAX_ATTR];\n\n} pj_stun_unknown_attr;\n\n\n/**\n * This structure describes STUN MAPPED-ADDRESS attribute.\n * The MAPPED-ADDRESS attribute indicates the mapped transport address.\n */\ntypedef struct pj_stun_sockaddr_attr pj_stun_mapped_addr_attr;\n\n\n/**\n * This describes STUN XOR-MAPPED-ADDRESS attribute (which has the same\n * format as STUN MAPPED-ADDRESS attribute).\n * The XOR-MAPPED-ADDRESS attribute is present in responses.  It\n * provides the same information that would present in the MAPPED-\n * ADDRESS attribute but because the NAT's public IP address is\n * obfuscated through the XOR function, STUN messages are able to pass\n * through NATs which would otherwise interfere with STUN.\n */\ntypedef struct pj_stun_sockaddr_attr pj_stun_xor_mapped_addr_attr;\n\n\n/**\n * This describes STUN SOFTWARE attribute.\n * The SOFTWARE attribute contains a textual description of the software\n * being used by the agent sending the message.  It is used by clients\n * and servers.  Its value SHOULD include manufacturer and version\n * number. */\ntypedef struct pj_stun_string_attr pj_stun_software_attr;\n\n\n/**\n * This describes STUN ALTERNATE-SERVER attribute.\n * The alternate server represents an alternate transport address for a\n * different STUN server to try.  It is encoded in the same way as\n * MAPPED-ADDRESS.\n */\ntypedef struct pj_stun_sockaddr_attr pj_stun_alt_server_attr;\n\n\n/**\n * This describes STUN REFRESH-INTERVAL attribute.\n * The REFRESH-INTERVAL indicates the number of milliseconds that the\n * server suggests the client should use between refreshes of the NAT\n * bindings between the client and server.\n */\ntypedef struct pj_stun_uint_attr pj_stun_refresh_interval_attr;\n\n\n/**\n * This structure describes STUN RESPONSE-ADDRESS attribute.\n * The RESPONSE-ADDRESS attribute indicates where the response to a\n * Binding Request should be sent.  Its syntax is identical to MAPPED-\n * ADDRESS.\n *\n * Note that the usage of this attribute has been deprecated by the \n * RFC 3489-bis standard.\n */\ntypedef struct pj_stun_sockaddr_attr pj_stun_response_addr_attr;\n\n\n/**\n * This structure describes STUN CHANGED-ADDRESS attribute.\n * The CHANGED-ADDRESS attribute indicates the IP address and port where\n * responses would have been sent from if the \"change IP\" and \"change\n * port\" flags had been set in the CHANGE-REQUEST attribute of the\n * Binding Request.  The attribute is always present in a Binding\n * Response, independent of the value of the flags.  Its syntax is\n * identical to MAPPED-ADDRESS.\n *\n * Note that the usage of this attribute has been deprecated by the \n * RFC 3489-bis standard.\n */\ntypedef struct pj_stun_sockaddr_attr pj_stun_changed_addr_attr;\n\n\n/**\n * This structure describes STUN CHANGE-REQUEST attribute.\n * The CHANGE-REQUEST attribute is used by the client to request that\n * the server use a different address and/or port when sending the\n * response. \n *\n * Bit 29 of the value is the \"change IP\" flag.  If true, it requests \n * the server to send the Binding Response with a different IP address \n * than the one the Binding Request was received on.\n *\n * Bit 30 of the value is the \"change port\" flag.  If true, it requests \n * the server to send the Binding Response with a different port than \n * the one the Binding Request was received on.\n *\n * Note that the usage of this attribute has been deprecated by the \n * RFC 3489-bis standard.\n */\ntypedef struct pj_stun_uint_attr pj_stun_change_request_attr;\n\n/**\n * This structure describes STUN SOURCE-ADDRESS attribute.\n * The SOURCE-ADDRESS attribute is present in Binding Responses.  It\n * indicates the source IP address and port that the server is sending\n * the response from.  Its syntax is identical to that of MAPPED-\n * ADDRESS.\n *\n * Note that the usage of this attribute has been deprecated by the \n * RFC 3489-bis standard.\n */\ntypedef struct pj_stun_sockaddr_attr pj_stun_src_addr_attr;\n\n\n/**\n * This describes the STUN REFLECTED-FROM attribute.\n * The REFLECTED-FROM attribute is present only in Binding Responses,\n * when the Binding Request contained a RESPONSE-ADDRESS attribute.  The\n * attribute contains the identity (in terms of IP address) of the\n * source where the request came from.  Its purpose is to provide\n * traceability, so that a STUN server cannot be used as a reflector for\n * denial-of-service attacks.\n */\ntypedef struct pj_stun_sockaddr_attr pj_stun_reflected_from_attr;\n\n\n/**\n * This describes STUN USERNAME attribute.\n * The USERNAME attribute is used for message integrity.  It identifies\n * the shared secret used in the message integrity check.  Consequently,\n * the USERNAME MUST be included in any request that contains the\n * MESSAGE-INTEGRITY attribute.\n */\ntypedef struct pj_stun_string_attr pj_stun_username_attr;\n\n\n/**\n * This describes STUN PASSWORD attribute.\n * If the message type is Shared Secret Response it MUST include the\n * PASSWORD attribute.\n */\ntypedef struct pj_stun_string_attr pj_stun_password_attr;\n\n\n/**\n * This describes TURN CHANNEL-NUMBER attribute. In this library,\n * this attribute is represented with 32bit integer. Application may\n * use #PJ_STUN_GET_CH_NB() and #PJ_STUN_SET_CH_NB() to extract/set\n * channel number value from the 32bit integral value.\n *\n * The CHANNEL-NUMBER attribute contains the number of the channel.\n * It is a 16-bit unsigned integer, followed by a two-octet RFFU field\n * which MUST be set to 0 on transmission and ignored on reception.\n  \n \\verbatim\n    0                   1                   2                   3\n    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |        Channel Number         |         RFFU                  |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n \\endverbatim\n */\ntypedef struct pj_stun_uint_attr pj_stun_channel_number_attr;\n\n/**\n * Get 16bit channel number from 32bit integral value.\n * Note that uint32 attributes are always stored in host byte order\n * after they have been parsed from the PDU, so no need to do ntohs()\n * here.\n */\n#define PJ_STUN_GET_CH_NB(u32)\t    ((pj_uint16_t)(u32>>16))\n\n/**\n * Convert 16bit channel number into 32bit integral value.\n * Note that uint32 attributes will be converted to network byte order\n * when the attribute is written to packet, so no need to do htons()\n * here.\n */\n#define PJ_STUN_SET_CH_NB(chnum)    (((pj_uint32_t)chnum) << 16)\n\n\n/**\n * This describes STUN LIFETIME attribute.\n * The lifetime attribute represents the duration for which the server\n * will maintain an allocation in the absence of data traffic either\n * from or to the client.  It is a 32 bit value representing the number\n * of seconds remaining until expiration.\n */\ntypedef struct pj_stun_uint_attr pj_stun_lifetime_attr;\n\n\n/**\n * This describes STUN BANDWIDTH attribute.\n * The bandwidth attribute represents the peak bandwidth, measured in\n * kbits per second, that the client expects to use on the binding.  The\n * value represents the sum in the receive and send directions.\n */\ntypedef struct pj_stun_uint_attr pj_stun_bandwidth_attr;\n\n\n/**\n * This describes the STUN XOR-PEER-ADDRESS attribute.\n * The XOR-PEER-ADDRESS specifies the address and port of the peer as seen\n * from the TURN server.  It is encoded in the same way as XOR-MAPPED-\n * ADDRESS. \n */\ntypedef struct pj_stun_sockaddr_attr pj_stun_xor_peer_addr_attr;\n\n\n/**\n * This describes the STUN DATA attribute.\n * The DATA attribute is present in Send Indications and Data\n * Indications.  It contains raw payload data that is to be sent (in the\n * case of a Send Request) or was received (in the case of a Data\n * Indication)..\n */\ntypedef struct pj_stun_binary_attr pj_stun_data_attr;\n\n\n/**\n * This describes the STUN XOR-RELAYED-ADDRESS attribute. The \n * XOR-RELAYED-ADDRESS is present in Allocate responses.  It specifies the\n * address and port that the server allocated to the client.  It is\n * encoded in the same way as XOR-MAPPED-ADDRESS.\n */\ntypedef struct pj_stun_sockaddr_attr pj_stun_xor_relayed_addr_attr;\n\n\n/**\n * This describes the REQUESTED-ADDRESS-TYPE attribute.\n * The REQUESTED-ADDRESS-TYPE attribute is used by clients to request\n * the allocation of a specific address type from a server.  The\n * following is the format of the REQUESTED-ADDRESS-TYPE attribute.\n\n \\verbatim\n\n      0                   1                   2                   3\n      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |        Family                 |           Reserved            |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n \\endverbatim\n */\ntypedef struct pj_stun_uint_attr pj_stun_req_addr_type_attr;\n\n\n/**\n * This describes the TURN REQUESTED-TRANSPORT attribute, encoded in\n * STUN generic integer attribute.\n *\n * This attribute allows the client to request that the port in the\n * relayed-transport-address be even, and (optionally) that the server\n * reserve the next-higher port number.  The attribute is 8 bits long.\n * Its format is:\n\n\\verbatim\n      0\n      0 1 2 3 4 5 6 7\n     +-+-+-+-+-+-+-+-+\n     |R|    RFFU     |\n     +-+-+-+-+-+-+-+-+\n\n\\endverbatim\n\n * The attribute contains a single 1-bit flag:\n * \n * R: If 1, the server is requested to reserve the next higher port\n *    number (on the same IP address) for a subsequent allocation.  If\n *    0, no such reservation is requested.\n * \n * The other 7 bits of the attribute must be set to zero on transmission\n * and ignored on reception.\n */\ntypedef struct pj_stun_uint_attr pj_stun_even_port_attr;\n\n\n/**\n * This describes the TURN REQUESTED-TRANSPORT attribute, encoded in\n * STUN generic integer attribute.\n *\n * This attribute is used by the client to request a specific transport\n * protocol for the allocated transport address.  It has the following\n * format:\n\n \\verbatim\n\n      0                   1                   2                   3\n      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |    Protocol   |                    RFFU                       |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n\n \\endverbatim\n\n * The Protocol field specifies the desired protocol.  The codepoints\n * used in this field are taken from those allowed in the Protocol field\n * in the IPv4 header and the NextHeader field in the IPv6 header\n * [Protocol-Numbers].  This specification only allows the use of\n * codepoint 17 (User Datagram Protocol).\n * \n * The RFFU field is set to zero on transmission and ignored on\n * receiption.  It is reserved for future uses.\n */\ntypedef struct pj_stun_uint_attr pj_stun_req_transport_attr;\n\n/**\n * Get protocol value from 32bit TURN REQUESTED-TRANSPORT attribute.\n */\n#define PJ_STUN_GET_RT_PROTO(u32)   (u32 >> 24)\n\n/**\n * Convert protocol value to be placed in 32bit TURN REQUESTED-TRANSPORT\n * attribute.\n */\n#define PJ_STUN_SET_RT_PROTO(proto)   (((pj_uint32_t)(proto)) << 24)\n\n\n/**\n * This describes the TURN DONT-FRAGMENT attribute.\n *\n * This attribute is used by the client to request that the server set\n * the DF (Don't Fragment) bit in the IP header when relaying the\n * application data onward to the peer.  This attribute has no value\n * part and thus the attribute length field is 0.\n */\ntypedef struct pj_stun_empty_attr pj_stun_dont_fragment_attr;\n\n\n/**\n * This describes the TURN RESERVATION-TOKEN attribute.\n * The RESERVATION-TOKEN attribute contains a token that uniquely\n * identifies a relayed transport address being held in reserve by the\n * server.  The server includes this attribute in a success response to\n * tell the client about the token, and the client includes this\n * attribute in a subsequent Allocate request to request the server use\n * that relayed transport address for the allocation.\n * \n * The attribute value is a 64-bit-long field containing the token\n * value. \n */\ntypedef struct pj_stun_uint64_attr pj_stun_res_token_attr;\n\n/**\n * This describes the XOR-REFLECTED-FROM attribute, as described by\n * draft-macdonald-behave-nat-behavior-discovery-00.\n * The XOR-REFLECTED-FROM attribute is used in place of the REFLECTED-\n * FROM attribute.  It provides the same information, but because the\n * NAT's public address is obfuscated through the XOR function, It can\n * pass through a NAT that would otherwise attempt to translate it to\n * the private network address.  XOR-REFLECTED-FROM has identical syntax\n * to XOR-MAPPED-ADDRESS.\n */\ntypedef struct pj_stun_sockaddr_attr pj_stun_xor_reflected_from_attr;\n\n/**\n * This describes the PRIORITY attribute from draft-ietf-mmusic-ice-13.\n * The PRIORITY attribute indicates the priority that is to be\n * associated with a peer reflexive candidate, should one be discovered\n * by this check.  It is a 32 bit unsigned integer, and has an attribute\n * type of 0x0024.\n */\ntypedef struct pj_stun_uint_attr pj_stun_priority_attr;\n\n/**\n * This describes the USE-CANDIDATE attribute from draft-ietf-mmusic-ice-13.\n * The USE-CANDIDATE attribute indicates that the candidate pair\n * resulting from this check should be used for transmission of media.\n * The attribute has no content (the Length field of the attribute is\n * zero); it serves as a flag.\n */\ntypedef struct pj_stun_empty_attr pj_stun_use_candidate_attr;\n\n/**\n * This describes the STUN TIMER-VAL attribute.\n * The TIMER-VAL attribute is used only in conjunction with the Set\n * Active Destination response.  It conveys from the server, to the\n * client, the value of the timer used in the server state machine.\n */\ntypedef struct pj_stun_uint_attr pj_stun_timer_val_attr;\n\n/**\n * This describes ICE-CONTROLLING attribute.\n */\ntypedef struct pj_stun_uint64_attr pj_stun_ice_controlling_attr;\n\n/**\n * This describes ICE-CONTROLLED attribute.\n */\ntypedef struct pj_stun_uint64_attr pj_stun_ice_controlled_attr;\n\n/**\n * This describes TURN ICMP attribute\n */\ntypedef struct pj_stun_uint_attr pj_stun_icmp_attr;\n\n/**\n * This structure describes a parsed STUN message. All integral fields\n * in this structure (including IP addresses) will be in the host\n * byte order.\n */\ntypedef struct pj_stun_msg\n{\n    /**\n     * STUN message header.\n     */\n    pj_stun_msg_hdr     hdr;\n\n    /**\n     * Number of attributes in the STUN message.\n     */\n    unsigned\t\tattr_count;\n\n    /**\n     * Array of STUN attributes.\n     */\n    pj_stun_attr_hdr   *attr[PJ_STUN_MAX_ATTR];\n\n} pj_stun_msg;\n\n\n/** STUN decoding options */\nenum pj_stun_decode_options\n{\n    /** \n     * Tell the decoder that the message was received from datagram\n     * oriented transport (such as UDP).\n     */\n    PJ_STUN_IS_DATAGRAM\t    = 1,\n\n    /**\n     * Tell pj_stun_msg_decode() to check the validity of the STUN\n     * message by calling pj_stun_msg_check() before starting to\n     * decode the packet.\n     */\n    PJ_STUN_CHECK_PACKET    = 2,\n\n    /**\n     * This option current is only valid for #pj_stun_session_on_rx_pkt().\n     * When specified, it tells the session NOT to authenticate the\n     * message.\n     */\n    PJ_STUN_NO_AUTHENTICATE = 4,\n\n    /**\n     * Disable FINGERPRINT verification. This option can be used when calling\n     * #pj_stun_msg_check() and #pj_stun_msg_decode() to disable the \n     * verification of FINGERPRINT, for example when the STUN usage says when\n     * FINGERPRINT mechanism shall not be used.\n     */\n    PJ_STUN_NO_FINGERPRINT_CHECK = 8\n};\n\n\n/**\n * Get STUN message method name.\n *\n * @param msg_type\tThe STUN message type (in host byte order)\n *\n * @return\t\tThe STUN message method name string.\n */\nPJ_DECL(const char*) pj_stun_get_method_name(unsigned msg_type);\n\n\n/**\n * Get STUN message class name.\n *\n * @param msg_type\tThe STUN message type (in host byte order)\n *\n * @return\t\tThe STUN message class name string.\n */\nPJ_DECL(const char*) pj_stun_get_class_name(unsigned msg_type);\n\n\n/**\n * Get STUN attribute name.\n *\n * @return attr_type\tThe STUN attribute type (in host byte order).\n *\n * @return\t\tThe STUN attribute type name string.\n */\nPJ_DECL(const char*) pj_stun_get_attr_name(unsigned attr_type);\n\n\n/**\n * Get STUN standard reason phrase for the specified error code.\n *\n * @param err_code\tThe STUN error code.\n *\n * @return\t\tThe STUN error reason phrase.\n */\nPJ_DECL(pj_str_t) pj_stun_get_err_reason(int err_code);\n\n\n/**\n * Internal: set the padding character for string attribute.\n * The default padding character is PJ_STUN_STRING_ATTR_PAD_CHR.\n *\n * @return\t\tThe previous padding character.\n */\nPJ_DECL(int) pj_stun_set_padding_char(int chr);\n\n\n/**\n * Initialize a generic STUN message.\n *\n * @param msg\t\tThe message structure to be initialized.\n * @param msg_type\tThe 14bit message type (see pj_stun_msg_type \n *\t\t\tconstants).\n * @param magic\t\tMagic value to be put to the mesage; for requests,\n *\t\t\tthe value normally should be PJ_STUN_MAGIC.\n * @param tsx_id\tOptional transaction ID, or NULL to let the\n *\t\t\tfunction generates a random transaction ID.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_init(pj_stun_msg *msg,\n\t\t\t\t      unsigned msg_type,\n\t\t\t\t      pj_uint32_t magic,\n\t\t\t\t      const pj_uint8_t tsx_id[12]);\n\n/**\n * Create a generic STUN message.\n *\n * @param pool\t\tPool to create the STUN message.\n * @param msg_type\tThe 14bit message type.\n * @param magic\t\tMagic value to be put to the mesage; for requests,\n *\t\t\tthe value should be PJ_STUN_MAGIC.\n * @param tsx_id\tOptional transaction ID, or NULL to let the\n *\t\t\tfunction generates a random transaction ID.\n * @param p_msg\t\tPointer to receive the message.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_create(pj_pool_t *pool,\n\t\t\t\t\tunsigned msg_type,\n\t\t\t\t\tpj_uint32_t magic,\n\t\t\t\t\tconst pj_uint8_t tsx_id[12],\n\t\t\t\t\tpj_stun_msg **p_msg);\n\n/**\n * Clone a STUN message with all of its attributes.\n *\n * @param pool\t\tPool to allocate memory for the new message.\n * @param msg\t\tThe message to be cloned.\n *\n * @return\t\tThe duplicate message.\n */\nPJ_DECL(pj_stun_msg*) pj_stun_msg_clone(pj_pool_t *pool,\n\t\t\t\t\tconst pj_stun_msg *msg);\n\n/**\n * Create STUN response message. \n *\n * @param pool\t\tPool to create the mesage.\n * @param req_msg\tThe request message.\n * @param err_code\tSTUN error code. If this value is not zero,\n *\t\t\tthen error response will be created, otherwise\n *\t\t\tsuccessful response will be created.\n * @param err_msg\tOptional error message to explain err_code.\n *\t\t\tIf this value is NULL and err_code is not zero,\n *\t\t\tthe error string will be taken from the default\n *\t\t\tSTUN error message.\n * @param p_response\tPointer to receive the response.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_create_response(pj_pool_t *pool,\n\t\t\t\t\t\t const pj_stun_msg *req_msg,\n\t\t\t\t\t\t unsigned err_code,\n\t\t\t\t\t\t const pj_str_t *err_msg,\n\t\t\t\t\t\t pj_stun_msg **p_response);\n\n\n/**\n * Add STUN attribute to STUN message.\n *\n * @param msg\t\tThe STUN message.\n * @param attr\t\tThe STUN attribute to be added to the message.\n *\n * @return\t\tPJ_SUCCESS on success, or PJ_ETOOMANY if there are\n *\t\t\talready too many attributes in the message.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_add_attr(pj_stun_msg *msg,\n\t\t\t\t\t  pj_stun_attr_hdr *attr);\n\n\n/**\n * Print the STUN message structure to a packet buffer, ready to be \n * sent to remote destination. This function will take care about \n * calculating the MESSAGE-INTEGRITY digest as well as FINGERPRINT\n * value, if these attributes are present in the message.\n *\n * If application wants to apply credential to the message, it MUST\n * include a blank MESSAGE-INTEGRITY attribute in the message as the\n * last attribute or the attribute before FINGERPRINT. This function will\n * calculate the HMAC digest from the message using  the supplied key in\n * the parameter. The key should be set to the password if short term \n * credential is used, or calculated from the MD5 hash of the realm, \n * username, and password using #pj_stun_create_key() if long term \n * credential is used.\n *\n * If FINGERPRINT attribute is present, this function will calculate\n * the FINGERPRINT CRC attribute for the message. The FINGERPRINT MUST\n * be added as the last attribute of the message.\n *\n * @param msg\t\tThe STUN message to be printed. Upon return,\n *\t\t\tsome fields in the header (such as message\n *\t\t\tlength) will be updated.\n * @param pkt_buf\tThe buffer to be filled with the packet.\n * @param buf_size\tSize of the buffer.\n * @param options\tOptions, which currently must be zero.\n * @param key\t\tAuthentication key to calculate MESSAGE-INTEGRITY\n *\t\t\tvalue. Application can create this key by using\n *\t\t\t#pj_stun_create_key() function.\n * @param p_msg_len\tUpon return, it will be filed with the size of \n *\t\t\tthe packet in bytes, or negative value on error.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_encode(pj_stun_msg *msg,\n\t\t\t\t        pj_uint8_t *pkt_buf,\n\t\t\t\t        pj_size_t buf_size,\n\t\t\t\t        unsigned options,\n\t\t\t\t\tconst pj_str_t *key,\n\t\t\t\t        pj_size_t *p_msg_len);\n\n/**\n * Check that the PDU is potentially a valid STUN message. This function\n * is useful when application needs to multiplex STUN packets with other\n * application traffic. When this function returns PJ_SUCCESS, there is a\n * big chance that the packet is a STUN packet.\n *\n * Note that we cannot be sure that the PDU is a really valid STUN message \n * until we actually parse the PDU.\n *\n * @param pdu\t\tThe packet buffer.\n * @param pdu_len\tThe length of the packet buffer.\n * @param options\tAdditional options to be applied in the checking,\n *\t\t\twhich can be taken from pj_stun_decode_options. One \n *\t\t\tof the useful option is PJ_STUN_IS_DATAGRAM which \n *\t\t\tmeans that the pdu represents a whole STUN packet.\n *\n * @return\t\tPJ_SUCCESS if the PDU is a potentially valid STUN\n *\t\t\tmessage.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, \n\t\t\t\t       pj_size_t pdu_len, unsigned options);\n\n\n/**\n * Decode incoming packet into STUN message.\n *\n * @param pool\t\tPool to allocate the message.\n * @param pdu\t\tThe incoming packet to be parsed.\n * @param pdu_len\tThe length of the incoming packet.\n * @param options\tParsing flags, according to pj_stun_decode_options.\n * @param p_msg\t\tPointer to receive the parsed message.\n * @param p_parsed_len\tOptional pointer to receive how many bytes have\n *\t\t\tbeen parsed for the STUN message. This is useful\n *\t\t\twhen the packet is received over stream oriented\n *\t\t\ttransport.\n * @param p_response\tOptional pointer to receive an instance of response\n *\t\t\tmessage, if one can be created. If the packet being\n *\t\t\tdecoded is a request message, and it contains error,\n *\t\t\tand a response can be created, then the STUN \n *\t\t\tresponse message will be returned on this argument.\n *\n * @return\t\tPJ_SUCCESS if a STUN message has been successfully\n *\t\t\tdecoded.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,\n\t\t\t\t        const pj_uint8_t *pdu,\n\t\t\t\t        pj_size_t pdu_len,\n\t\t\t\t        unsigned options,\n\t\t\t\t        pj_stun_msg **p_msg,\n\t\t\t\t\tpj_size_t *p_parsed_len,\n\t\t\t\t        pj_stun_msg **p_response);\n\n/**\n * Dump STUN message to a printable string output.\n *\n * @param msg\t\tThe STUN message\n * @param buffer\tBuffer where the printable string output will\n *\t\t\tbe printed on.\n * @param length\tSpecify the maximum length of the buffer.\n * @param printed_len\tOptional pointer, which on output will be filled\n *\t\t\tup with the actual length of the output string.\n *\n * @return\t\tThe message string output.\n */\n#if PJ_LOG_MAX_LEVEL > 0\nPJ_DECL(char*) pj_stun_msg_dump(const pj_stun_msg *msg,\n\t\t\t        char *buffer,\n\t\t\t        unsigned length,\n\t\t\t\tunsigned *printed_len);\n#else\n#   define pj_stun_msg_dump(msg, buf, length, printed_len)  \"\"\n#endif\n\n\n/**\n * Find STUN attribute in the STUN message, starting from the specified\n * index.\n *\n * @param msg\t\tThe STUN message.\n * @param attr_type\tThe attribute type to be found, from pj_stun_attr_type.\n * @param start_index\tThe start index of the attribute in the message.\n *\t\t\tSpecify zero to start searching from the first\n *\t\t\tattribute.\n *\n * @return\t\tThe attribute instance, or NULL if it cannot be\n *\t\t\tfound.\n */\nPJ_DECL(pj_stun_attr_hdr*) pj_stun_msg_find_attr(const pj_stun_msg *msg,\n\t\t\t\t\t\t int attr_type,\n\t\t\t\t\t\t unsigned start_index);\n\n\n/**\n * Clone a STUN attribute.\n *\n * @param pool\t\tPool to allocate memory.\n * @param attr\t\tAttribute to clone.\n *\n * @return\t\tDuplicate attribute.\n */\nPJ_DECL(pj_stun_attr_hdr*) pj_stun_attr_clone(pj_pool_t *pool,\n\t\t\t\t\t      const pj_stun_attr_hdr *attr);\n\n\n/**\n * Initialize generic STUN IP address attribute. The \\a addr_len and\n * \\a addr parameters specify whether the address is IPv4 or IPv4\n * address.\n *\n * @param attr\t\tThe socket address attribute to initialize.\n * @param attr_type\tAttribute type, from #pj_stun_attr_type.\n * @param xor_ed\tIf non-zero, the port and address will be XOR-ed\n *\t\t\twith magic, to make the XOR-MAPPED-ADDRESS attribute.\n * @param addr\t\tA pj_sockaddr_in or pj_sockaddr_in6 structure.\n * @param addr_len\tLength of \\a addr parameter.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_sockaddr_attr_init(pj_stun_sockaddr_attr *attr,\n\t\t\t\t\t\tint attr_type, \n\t\t\t\t\t\tpj_bool_t xor_ed,\n\t\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\t\tunsigned addr_len);\n\n/**\n * Create a generic STUN IP address attribute. The \\a addr_len and\n * \\a addr parameters specify whether the address is IPv4 or IPv4\n * address.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param attr_type\tAttribute type, from #pj_stun_attr_type.\n * @param xor_ed\tIf non-zero, the port and address will be XOR-ed\n *\t\t\twith magic, to make the XOR-MAPPED-ADDRESS attribute.\n * @param addr\t\tA pj_sockaddr_in or pj_sockaddr_in6 structure.\n * @param addr_len\tLength of \\a addr parameter.\n * @param p_attr\tPointer to receive the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_sockaddr_attr_create(pj_pool_t *pool,\n\t\t\t\t\t\tint attr_type, \n\t\t\t\t\t\tpj_bool_t xor_ed,\n\t\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\t\tunsigned addr_len,\n\t\t\t\t\t\tpj_stun_sockaddr_attr **p_attr);\n\n\n/**\n * Create and add generic STUN IP address attribute to a STUN message.\n * The \\a addr_len and \\a addr parameters specify whether the address is \n * IPv4 or IPv4 address.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param msg\t\tThe STUN message.\n * @param attr_type\tAttribute type, from #pj_stun_attr_type.\n * @param xor_ed\tIf non-zero, the port and address will be XOR-ed\n *\t\t\twith magic, to make the XOR-MAPPED-ADDRESS attribute.\n * @param addr\t\tA pj_sockaddr_in or pj_sockaddr_in6 structure.\n * @param addr_len\tLength of \\a addr parameter.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_add_sockaddr_attr(pj_pool_t *pool,\n\t\t\t\t\t\t  pj_stun_msg *msg,\n\t\t\t\t\t\t  int attr_type, \n\t\t\t\t\t\t  pj_bool_t xor_ed,\n\t\t\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t\t\t  unsigned addr_len);\n\n/**\n * Initialize a STUN generic string attribute.\n *\n * @param attr\t\tThe string attribute to be initialized.\n * @param pool\t\tPool to duplicate the value into the attribute,\n *\t\t\tif value is not NULL or empty.\n * @param attr_type\tAttribute type, from #pj_stun_attr_type.\n * @param value\t\tThe string value to be assigned to the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_string_attr_init(pj_stun_string_attr *attr,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      int attr_type,\n\t\t\t\t\t      const pj_str_t *value);\n\n/**\n * Create a STUN generic string attribute.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param attr_type\tAttribute type, from #pj_stun_attr_type.\n * @param value\t\tThe string value to be assigned to the attribute.\n * @param p_attr\tPointer to receive the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_string_attr_create(pj_pool_t *pool,\n\t\t\t\t\t        int attr_type,\n\t\t\t\t\t        const pj_str_t *value,\n\t\t\t\t\t        pj_stun_string_attr **p_attr);\n\n/**\n * Create and add STUN generic string attribute to the message.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param msg\t\tThe STUN message.\n * @param attr_type\tAttribute type, from #pj_stun_attr_type.\n * @param value\t\tThe string value to be assigned to the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_add_string_attr(pj_pool_t *pool,\n\t\t\t\t\t\t pj_stun_msg *msg,\n\t\t\t\t\t\t int attr_type,\n\t\t\t\t\t\t const pj_str_t *value);\n\n/**\n * Create a STUN generic 32bit value attribute.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param attr_type\tAttribute type, from #pj_stun_attr_type.\n * @param value\t\tThe 32bit value to be assigned to the attribute.\n * @param p_attr\tPointer to receive the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_uint_attr_create(pj_pool_t *pool,\n\t\t\t\t\t      int attr_type,\n\t\t\t\t\t      pj_uint32_t value,\n\t\t\t\t\t      pj_stun_uint_attr **p_attr);\n\n/**\n * Create and add STUN generic 32bit value attribute to the message.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param msg\t\tThe STUN message\n * @param attr_type\tAttribute type, from #pj_stun_attr_type.\n * @param value\t\tThe 32bit value to be assigned to the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_add_uint_attr(pj_pool_t *pool,\n\t\t\t\t\t       pj_stun_msg *msg,\n\t\t\t\t\t       int attr_type,\n\t\t\t\t\t       pj_uint32_t value);\n\n\n/**\n * Create a STUN generic 64bit value attribute.\n *\n * @param pool\t\tPool to allocate memory from.\n * @param attr_type\tAttribute type, from #pj_stun_attr_type.\n * @param value\t\tOptional value to be assigned.\n * @param p_attr\tPointer to receive the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t)  pj_stun_uint64_attr_create(pj_pool_t *pool,\n\t\t\t\t\t        int attr_type,\n\t\t\t\t\t        const pj_timestamp *value,\n\t\t\t\t\t        pj_stun_uint64_attr **p_attr);\n\n\n/**\n *  Create and add STUN generic 64bit value attribute to the message. \n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param msg\t\tThe STUN message\n * @param attr_type\tAttribute type, from #pj_stun_attr_type.\n * @param value\t\tThe 64bit value to be assigned to the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t)  pj_stun_msg_add_uint64_attr(pj_pool_t *pool,\n\t\t\t\t\t          pj_stun_msg *msg,\n\t\t\t\t\t          int attr_type,\n\t\t\t\t\t          const pj_timestamp *value);\n\n/**\n * Create a STUN MESSAGE-INTEGRITY attribute.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param p_attr\tPointer to receive the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_msgint_attr_create(pj_pool_t *pool,\n\t\t\t\t\t\tpj_stun_msgint_attr **p_attr);\n\n/** \n * Create and add STUN MESSAGE-INTEGRITY attribute.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param msg\t\tThe STUN message\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_add_msgint_attr(pj_pool_t *pool,\n\t\t\t\t\t\t pj_stun_msg *msg);\n\n/**\n * Create a STUN ERROR-CODE attribute.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param err_code\tSTUN error code.\n * @param err_reason\tOptional STUN error reason. If NULL is given, the\n *\t\t\tstandard error reason will be given.\n * @param p_attr\tPointer to receive the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_errcode_attr_create(pj_pool_t *pool,\n\t\t\t\t\t\tint err_code,\n\t\t\t\t\t\tconst pj_str_t *err_reason,\n\t\t\t\t\t\tpj_stun_errcode_attr **p_attr);\n\n\n/**\n * Create and add STUN ERROR-CODE attribute to the message.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param msg\t\tThe STUN mesage.\n * @param err_code\tSTUN error code.\n * @param err_reason\tOptional STUN error reason. If NULL is given, the\n *\t\t\tstandard error reason will be given.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_add_errcode_attr(pj_pool_t *pool,\n\t\t\t\t\t\t  pj_stun_msg *msg,\n\t\t\t\t\t\t  int err_code,\n\t\t\t\t\t\t  const pj_str_t *err_reason);\n\n/**\n * Create instance of STUN UNKNOWN-ATTRIBUTES attribute and copy the\n * unknown attribute array to the attribute.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param attr_cnt\tNumber of attributes in the array (can be zero).\n * @param attr\t\tOptional array of attributes.\n * @param p_attr\tPointer to receive the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_unknown_attr_create(pj_pool_t *pool,\n\t\t\t\t\t\tunsigned attr_cnt,\n\t\t\t\t\t\tconst pj_uint16_t attr[],\n\t\t\t\t\t\tpj_stun_unknown_attr **p_attr);\n\n/**\n * Create and add STUN UNKNOWN-ATTRIBUTES attribute to the message.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param msg\t\tThe STUN message.\n * @param attr_cnt\tNumber of attributes in the array (can be zero).\n * @param attr\t\tOptional array of attribute types.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_add_unknown_attr(pj_pool_t *pool,\n\t\t\t\t\t\t  pj_stun_msg *msg,\n\t\t\t\t\t\t  unsigned attr_cnt,\n\t\t\t\t\t\t  const pj_uint16_t attr[]);\n\n/**\n * Initialize STUN binary attribute.\n *\n * @param attr\t\tThe attribute to be initialized.\n * @param pool\t\tPool to copy data, if the data and length are set.\n * @param attr_type\tThe attribute type, from #pj_stun_attr_type.\n * @param data\t\tData to be coped to the attribute, or NULL\n *\t\t\tif no data to be copied now.\n * @param length\tLength of data, or zero if no data is to be\n *\t\t\tcopied now.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_binary_attr_init(pj_stun_binary_attr *attr,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      int attr_type,\n\t\t\t\t\t      const pj_uint8_t *data,\n\t\t\t\t\t      unsigned length);\n\n/**\n * Create STUN binary attribute.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param attr_type\tThe attribute type, from #pj_stun_attr_type.\n * @param data\t\tData to be coped to the attribute, or NULL\n *\t\t\tif no data to be copied now.\n * @param length\tLength of data, or zero if no data is to be\n *\t\t\tcopied now.\n * @param p_attr\tPointer to receive the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_binary_attr_create(pj_pool_t *pool,\n\t\t\t\t\t        int attr_type,\n\t\t\t\t\t        const pj_uint8_t *data,\n\t\t\t\t\t        unsigned length,\n\t\t\t\t\t        pj_stun_binary_attr **p_attr);\n\n/**\n * Create STUN binary attribute and add the attribute to the message.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param msg\t\tThe STUN message.\n * @param attr_type\tThe attribute type, from #pj_stun_attr_type.\n * @param data\t\tData to be coped to the attribute, or NULL\n *\t\t\tif no data to be copied now.\n * @param length\tLength of data, or zero if no data is to be\n *\t\t\tcopied now.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_add_binary_attr(pj_pool_t *pool,\n\t\t\t\t\t\t pj_stun_msg *msg,\n\t\t\t\t\t\t int attr_type,\n\t\t\t\t\t\t const pj_uint8_t *data,\n\t\t\t\t\t\t unsigned length);\n\n/**\n * Create STUN empty attribute.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param attr_type\tThe attribute type, from #pj_stun_attr_type.\n * @param p_attr\tPointer to receive the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_empty_attr_create(pj_pool_t *pool,\n\t\t\t\t\t       int attr_type,\n\t\t\t\t\t       pj_stun_empty_attr **p_attr);\n\n/**\n * Create STUN empty attribute and add the attribute to the message.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param msg\t\tThe STUN message.\n * @param attr_type\tThe attribute type, from #pj_stun_attr_type.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_msg_add_empty_attr(pj_pool_t *pool,\n\t\t\t\t\t\tpj_stun_msg *msg,\n\t\t\t\t\t\tint attr_type);\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJNATH_STUN_MSG_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/stun_session.h",
    "content": "/* $Id: stun_session.h 4360 2013-02-21 11:26:35Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_STUN_SESSION_H__\n#define __PJNATH_STUN_SESSION_H__\n\n/**\n * @file stun_session.h\n * @brief STUN session management for client/server.\n */\n\n#include <pjnath/stun_msg.h>\n#include <pjnath/stun_auth.h>\n#include <pjnath/stun_config.h>\n#include <pjnath/stun_transaction.h>\n#include <pj/list.h>\n#include <pj/lock.h>\n#include <pj/timer.h>\n\nPJ_BEGIN_DECL\n\n\n/* **************************************************************************/\n/**\n * @addtogroup PJNATH_STUN_SESSION\n * @{\n *\n * This is is a transport-independent object to manage a client or server \n * STUN session. It has the following features:\n * \n *  - <b>transport independent</b>:\\n\n *    the object does not have it's own socket, but rather it provides\n *    functions and callbacks to send and receive packets. This way the\n *    object can be used by different transport types (e.g. UDP, TCP, \n *    TLS, etc.) as well as better integration to application which\n *    already has its own means to send and receive packets.\n * \n *  - <b>authentication management</b>:\\n\n *    the object manages STUN authentication throughout the lifetime of\n *    the session. For client sessions, once it's given a credential to\n *    authenticate itself with the server, the object will automatically\n *    add authentication info (the MESSAGE-INTEGRITY) to the request as\n *    well as authenticate the response. It will also handle long-term \n *    authentication challenges, including handling of nonce expiration,\n *    and retry the request automatically. For server sessions, it can \n *    be configured to authenticate incoming requests automatically.\n *  \n *  - <b>static or dynamic credential</b>:\\n\n *    application may specify static or dynamic credential to be used by\n *    the STUN session. Static credential means a static combination of\n *    username and password (and these cannot change during the session\n *    duration), while dynamic credential provides callback to ask the\n *    application about which username/password to use everytime\n *    authentication is about to be performed.\n *    \n *  - <b>client transaction management</b>:\\n\n *    outgoing requests may be sent with a STUN transaction for reliability,\n *    and the object will manage the transaction internally (including\n *    performing retransmissions). Application will be notified about the\n *    result of the request when the response arrives (or the transaction\n *    times out). When the request is challenged with authentication, the\n *    object will retry the request with new authentication info, and \n *    application will be notified about the final result of this request.\n * \n *  - <b>server transaction management</b>:\\n\n *    application may ask response to incoming requests to be cached by\n *    the object, and in this case the object will check for cached\n *    response everytime request is received. The cached response will be\n *    deleted once a timer expires.\n *\n * \\section using_stun_sess_sec Using the STUN session\n *\n * The following steps describes how to use the STUN session:\n *\n *  - <b>create the object configuration</b>:\\n\n *    The #pj_stun_config contains the configuration to create the STUN\n *    session, such as the timer heap to register internal timers and\n *    various STUN timeout values. You can initialize this structure by\n *    calling #pj_stun_config_init()\n *\n *  - <b>create the STUN session</b>:\\n\n *    by calling #pj_stun_session_create(). Among other things, this\n *    function requires the instance of #pj_stun_config and also \n *    #pj_stun_session_cb structure which stores callbacks to send\n *    outgoing packets as well as to notify application about incoming\n *    STUN requests, responses, and indicates and other events.\n *\n *  - <b>configure credential:</b>\\n\n *    if authentication is required for the session, configure the\n *    credential with #pj_stun_session_set_credential()\n *\n *  - <b>configuring other settings:</b>\\n\n *    several APIs are provided to configure the behavior of the STUN\n *    session (for example, to set the SOFTWARE attribute value, controls\n *    the logging behavior, fine tune the mutex locking, etc.). Please see\n *    the API reference for more info.\n *\n *  - <b>creating outgoing STUN requests or indications:</b>\\n\n *    create the STUN message by using #pj_stun_session_create_req() or\n *    #pj_stun_session_create_ind(). This will create a transmit data\n *    buffer containing a blank STUN request or indication. You will then\n *    typically need to add STUN attributes that are relevant to the\n *    request or indication, but note that some default attributes will\n *    be added by the session later when the message is sent (such as\n *    SOFTWARE attribute and attributes related to authentication).\n *    The message is now ready to be sent.\n *\n *  - <b>sending outgoing message:</b>\\n\n *    use #pj_stun_session_send_msg() to send outgoing STUN messages (this\n *    includes STUN requests, indications, and responses). The function has\n *    options whether to retransmit the request (for non reliable transports)\n *    or to cache the response if we're sending response. This function in \n *    turn will call the \\a on_send_msg() callback of #pj_stun_session_cb \n *    to request the application to send the packet.\n *\n *  - <b>handling incoming packet:</b>\\n\n *    call #pj_stun_session_on_rx_pkt() everytime the application receives\n *    a STUN packet. This function will decode the packet and process the\n *    packet according to the message, and normally this will cause one\n *    of the callback in the #pj_stun_session_cb to be called to notify\n *    the application about the event.\n *\n *  - <b>handling incoming requests:</b>\\n\n *    incoming requests are notified to application in the \\a on_rx_request\n *    callback of the #pj_stun_session_cb. If authentication is enabled in\n *    the session, the application will only receive this callback after\n *    the incoming request has been authenticated (if the authentication\n *    fails, the session would respond automatically with 401 error and\n *    the callback will not be called). Application now must create and\n *    send response for this request.\n *\n *  - <b>creating and sending response:</b>\\n\n *    create the STUN response with #pj_stun_session_create_res(). This will\n *    create a transmit data buffer containing a blank STUN response. You \n *    will then typically need to add STUN attributes that are relevant to\n *    the response, but note that some default attributes will\n *    be added by the session later when the message is sent (such as\n *    SOFTWARE attribute and attributes related to authentication).\n *    The message is now ready to be sent. Use #pj_stun_session_send_msg()\n *    (as explained above) to send the response.\n *\n *  - <b>convenient way to send response:</b>\\n\n *    the #pj_stun_session_respond() is provided as a convenient way to\n *    create and send simple STUN responses, such as error responses.\n *    \n *  - <b>destroying the session:</b>\\n\n *    once the session is done, use #pj_stun_session_destroy() to destroy\n *    the session.\n */\n\n\n/** Forward declaration for pj_stun_tx_data */\ntypedef struct pj_stun_tx_data pj_stun_tx_data;\n\n/** Forward declaration for pj_stun_rx_data */\ntypedef struct pj_stun_rx_data pj_stun_rx_data;\n\n/** Forward declaration for pj_stun_session */\ntypedef struct pj_stun_session pj_stun_session;\n\n\n/**\n * This is the callback to be registered to pj_stun_session, to send\n * outgoing message and to receive various notifications from the STUN\n * session.\n */\ntypedef struct pj_stun_session_cb\n{\n    /**\n     * Callback to be called by the STUN session to send outgoing message.\n     *\n     * @param sess\t    The STUN session.\n     * @param token\t    The token associated with this outgoing message\n     *\t\t\t    and was set by the application. This token was \n     *\t\t\t    set by application in pj_stun_session_send_msg()\n     *\t\t\t    for outgoing messages that are initiated by the\n     *\t\t\t    application, or in pj_stun_session_on_rx_pkt()\n     *\t\t\t    if this message is a response that was internally\n     *\t\t\t    generated by the STUN session (for example, an\n     *\t\t\t    401/Unauthorized response). Application may use\n     *\t\t\t    this facility for any purposes.\n     * @param pkt\t    Packet to be sent.\n     * @param pkt_size\t    Size of the packet to be sent.\n     * @param dst_addr\t    The destination address.\n     * @param addr_len\t    Length of destination address.\n     *\n     * @return\t\t    The callback should return the status of the\n     *\t\t\t    packet sending.\n     */\n    pj_status_t (*on_send_msg)(pj_stun_session *sess,\n\t\t\t       void *token,\n\t\t\t       const void *pkt,\n\t\t\t       pj_size_t pkt_size,\n\t\t\t       const pj_sockaddr_t *dst_addr,\n\t\t\t       unsigned addr_len);\n\n    /** \n     * Callback to be called on incoming STUN request message. This function\n     * is called when application calls pj_stun_session_on_rx_pkt() and when\n     * the STUN session has detected that the incoming STUN message is a\n     * STUN request message. In the \n     * callback processing, application MUST create a response by calling\n     * pj_stun_session_create_response() function and send the response\n     * with pj_stun_session_send_msg() function, before returning from\n     * the callback.\n     *\n     * @param sess\t    The STUN session.\n     * @param pkt\t    Pointer to the original STUN packet.\n     * @param pkt_len\t    Length of the STUN packet.\n     * @param rdata\t    Data containing incoming request message.\n     * @param token\t    The token that was set by the application when\n     *\t\t\t    calling pj_stun_session_on_rx_pkt() function.\n     * @param src_addr\t    Source address of the packet.\n     * @param src_addr_len  Length of the source address.\n     *\n     * @return\t\t    The return value of this callback will be\n     *\t\t\t    returned back to pj_stun_session_on_rx_pkt()\n     *\t\t\t    function.\n     */\n    pj_status_t (*on_rx_request)(pj_stun_session *sess,\n\t\t\t\t const pj_uint8_t *pkt,\n\t\t\t\t unsigned pkt_len,\n\t\t\t\t const pj_stun_rx_data *rdata,\n\t\t\t\t void *token,\n\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t unsigned src_addr_len);\n\n    /**\n     * Callback to be called when response is received or the transaction \n     * has timed out. This callback is called either when application calls\n     * pj_stun_session_on_rx_pkt() with the packet containing a STUN\n     * response for the client transaction, or when the internal timer of\n     * the STUN client transaction has timed-out before a STUN response is\n     * received.\n     *\n     * @param sess\t    The STUN session.\n     * @param status\t    Status of the request. If the value if not\n     *\t\t\t    PJ_SUCCESS, the transaction has timed-out\n     *\t\t\t    or other error has occurred, and the response\n     *\t\t\t    argument may be NULL.\n     *\t\t\t    Note that when the status is not success, the\n     *\t\t\t    response may contain non-NULL value if the \n     *\t\t\t    response contains STUN ERROR-CODE attribute.\n     * @param token\t    The token that was set by the application  when\n     *\t\t\t    calling pj_stun_session_send_msg() function.\n     *\t\t\t    Please not that this token IS NOT the token\n     *\t\t\t    that was given in pj_stun_session_on_rx_pkt().\n     * @param tdata\t    The original STUN request.\n     * @param response\t    The response message, on successful transaction,\n     *\t\t\t    or otherwise MAY BE NULL if status is not success.\n     *\t\t\t    Note that when the status is not success, this\n     *\t\t\t    argument may contain non-NULL value if the \n     *\t\t\t    response contains STUN ERROR-CODE attribute.\n     * @param src_addr\t    The source address where the response was \n     *\t\t\t    received, or NULL if the response is NULL.\n     * @param src_addr_len  The length of the source  address.\n     */\n    void (*on_request_complete)(pj_stun_session *sess,\n\t\t\t        pj_status_t status,\n\t\t\t\tvoid *token,\n\t\t\t        pj_stun_tx_data *tdata,\n\t\t\t        const pj_stun_msg *response,\n\t\t\t\tconst pj_sockaddr_t *src_addr,\n\t\t\t\tunsigned src_addr_len);\n\n\n    /**\n     * Callback to be called on incoming STUN request message. This function\n     * is called when application calls pj_stun_session_on_rx_pkt() and when\n     * the STUN session has detected that the incoming STUN message is a\n     * STUN indication message.\n     *\n     * @param sess\t    The STUN session.\n     * @param pkt\t    Pointer to the original STUN packet.\n     * @param pkt_len\t    Length of the STUN packet.\n     * @param msg\t    The parsed STUN indication.\n     * @param token\t    The token that was set by the application when\n     *\t\t\t    calling pj_stun_session_on_rx_pkt() function.\n     * @param src_addr\t    Source address of the packet.\n     * @param src_addr_len  Length of the source address.\n     *\n     * @return\t\t    The return value of this callback will be\n     *\t\t\t    returned back to pj_stun_session_on_rx_pkt()\n     *\t\t\t    function.\n     */\n    pj_status_t (*on_rx_indication)(pj_stun_session *sess,\n\t\t\t\t    const pj_uint8_t *pkt,\n\t\t\t\t    unsigned pkt_len,\n\t\t\t\t    const pj_stun_msg *msg,\n\t\t\t\t    void *token,\n\t\t\t\t    const pj_sockaddr_t *src_addr,\n\t\t\t\t    unsigned src_addr_len);\n\n} pj_stun_session_cb;\n\n\n/**\n * This structure describes incoming request message.\n */\nstruct pj_stun_rx_data\n{\n    /**\n     * The parsed request message.\n     */\n    pj_stun_msg\t\t    *msg;\n\n    /**\n     * Credential information that is found and used to authenticate \n     * incoming request. Application may use this information when \n     * generating  authentication for the outgoing response.\n     */\n    pj_stun_req_cred_info   info;\n};\n\n\n/**\n * This structure describe the outgoing STUN transmit data to carry the\n * message to be sent.\n */\nstruct pj_stun_tx_data\n{\n    /** PJLIB list interface */\n    PJ_DECL_LIST_MEMBER(struct pj_stun_tx_data);\n\n    pj_pool_t\t\t*pool;\t\t/**< Pool.\t\t\t    */\n    pj_stun_session\t*sess;\t\t/**< The STUN session.\t\t    */\n    pj_stun_msg\t\t*msg;\t\t/**< The STUN message.\t\t    */\n\n    void\t\t*token;\t\t/**< The token.\t\t\t    */\n\n    pj_stun_client_tsx\t*client_tsx;\t/**< Client STUN transaction.\t    */\n    pj_bool_t\t\t retransmit;\t/**< Retransmit request?\t    */\n    pj_uint32_t\t\t msg_magic;\t/**< Message magic.\t\t    */\n    pj_uint8_t\t\t msg_key[12];\t/**< Message/transaction key.\t    */\n\n    pj_stun_req_cred_info auth_info;\t/**< Credential info\t\t    */\n\n    void\t\t*pkt;\t\t/**< The STUN packet.\t\t    */\n    unsigned\t\t max_len;\t/**< Length of packet buffer.\t    */\n    pj_size_t\t\t pkt_size;\t/**< The actual length of STUN pkt. */\n\n    unsigned\t\t addr_len;\t/**< Length of destination address. */\n    const pj_sockaddr_t\t*dst_addr;\t/**< Destination address.\t    */\n\n    pj_timer_entry\t res_timer;\t/**< Response cache timer.\t    */\n};\n\n\n/**\n * These are the flags to control the message logging in the STUN session.\n */\ntypedef enum pj_stun_sess_msg_log_flag\n{\n    PJ_STUN_SESS_LOG_TX_REQ=1,\t/**< Log outgoing STUN requests.    */\n    PJ_STUN_SESS_LOG_TX_RES=2,\t/**< Log outgoing STUN responses.   */\n    PJ_STUN_SESS_LOG_TX_IND=4,\t/**< Log outgoing STUN indications. */\n\n    PJ_STUN_SESS_LOG_RX_REQ=8,\t/**< Log incoming STUN requests.    */\n    PJ_STUN_SESS_LOG_RX_RES=16,\t/**< Log incoming STUN responses    */\n    PJ_STUN_SESS_LOG_RX_IND=32\t/**< Log incoming STUN indications  */\n} pj_stun_sess_msg_log_flag;\n\n\n/**\n * Create a STUN session.\n *\n * @param cfg\t\tThe STUN endpoint, to be used to register timers etc.\n * @param name\t\tOptional name to be associated with this instance. The\n *\t\t\tname will be used for example for logging purpose.\n * @param cb\t\tSession callback.\n * @param fingerprint\tEnable message fingerprint for outgoing messages.\n * @param grp_lock\tOptional group lock to be used by this session.\n * \t\t\tIf NULL, the session will create one itself.\n * @param p_sess\tPointer to receive STUN session instance.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_session_create(pj_stun_config *cfg,\n\t\t\t\t\t    const char *name,\n\t\t\t\t\t    const pj_stun_session_cb *cb,\n\t\t\t\t\t    pj_bool_t fingerprint,\n\t\t\t\t\t    pj_grp_lock_t *grp_lock,\n\t\t\t\t\t    pj_stun_session **p_sess);\n\n/**\n * Destroy the STUN session and all objects created in the context of\n * this session.\n *\n * @param sess\t    The STUN session instance.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n *\t\t    This function will return PJ_EPENDING if the operation\n *\t\t    cannot be performed immediately because callbacks are\n *\t\t    being called; in this case the session will be destroyed\n *\t\t    as soon as the last callback returns.\n */\nPJ_DECL(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess);\n\n/**\n * Associated an arbitrary data with this STUN session. The user data may\n * be retrieved later with pj_stun_session_get_user_data() function.\n *\n * @param sess\t    The STUN session instance.\n * @param user_data The user data.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_session_set_user_data(pj_stun_session *sess,\n\t\t\t\t\t\t   void *user_data);\n\n/**\n * Retrieve the user data previously associated to this STUN session with\n * pj_stun_session_set_user_data().\n *\n * @param sess\t    The STUN session instance.\n *\n * @return\t    The user data associated with this STUN session.\n */\nPJ_DECL(void*) pj_stun_session_get_user_data(pj_stun_session *sess);\n\n/**\n * Get the group lock for this STUN session.\n *\n * @param sess\t    The STUN session instance.\n *\n * @return\t    The group lock.\n */\nPJ_DECL(pj_grp_lock_t *) pj_stun_session_get_grp_lock(pj_stun_session *sess);\n\n/**\n * Set SOFTWARE name to be included in all requests and responses.\n *\n * @param sess\t    The STUN session instance.\n * @param sw\t    Software name string. If this argument is NULL or\n *\t\t    empty, the session will not include SOFTWARE attribute\n *\t\t    in STUN requests and responses.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_session_set_software_name(pj_stun_session *sess,\n\t\t\t\t\t\t       const pj_str_t *sw);\n\n/**\n * Set credential to be used by this session. Once credential is set, all\n * outgoing messages will include MESSAGE-INTEGRITY, and all incoming\n * message will be authenticated against this credential.\n *\n * To disable authentication after it has been set, call this function\n * again with NULL as the argument.\n *\n * @param sess\t    The STUN session instance.\n * @param auth_type Type of authentication.\n * @param cred\t    The credential to be used by this session. If NULL\n *\t\t    is specified, authentication will be disabled.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_session_set_credential(pj_stun_session *sess,\n\t\t\t\t\t\tpj_stun_auth_type auth_type,\n\t\t\t\t\t\tconst pj_stun_auth_cred *cred);\n/**\n * Configure message logging. By default all flags are enabled.\n *\n * @param sess\t    The STUN session instance.\n * @param flags\t    Bitmask combination of #pj_stun_sess_msg_log_flag\n */\nPJ_DECL(void) pj_stun_session_set_log(pj_stun_session *sess,\n\t\t\t\t      unsigned flags);\n/**\n * Configure whether the STUN session should utilize FINGERPRINT in\n * outgoing messages.\n *\n * @param sess\t    The STUN session instance.\n * @param use\t    Boolean for the setting.\n *\n * @return\t    The previous configured value of FINGERPRINT\n *\t\t    utilization of the sessoin.\n */\nPJ_DECL(pj_bool_t) pj_stun_session_use_fingerprint(pj_stun_session *sess,\n\t\t\t\t\t\t   pj_bool_t use);\n\n/**\n * Create a STUN request message. After the message has been successfully\n * created, application can send the message by calling \n * pj_stun_session_send_msg().\n *\n * @param sess\t    The STUN session instance.\n * @param msg_type  The STUN request message type, from pj_stun_method_e or\n *\t\t    from pj_stun_msg_type.\n * @param magic\t    STUN magic, use PJ_STUN_MAGIC.\n * @param tsx_id    Optional transaction ID.\n * @param p_tdata   Pointer to receive STUN transmit data instance containing\n *\t\t    the request.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_session_create_req(pj_stun_session *sess,\n\t\t\t\t\t\tint msg_type,\n\t\t\t\t\t\tpj_uint32_t magic,\n\t\t\t\t\t\tconst pj_uint8_t tsx_id[12],\n\t\t\t\t\t\tpj_stun_tx_data **p_tdata);\n\n/**\n * Create a STUN Indication message. After the message  has been successfully\n * created, application can send the message by calling \n * pj_stun_session_send_msg().\n *\n * @param sess\t    The STUN session instance.\n * @param msg_type  The STUN request message type, from pj_stun_method_e or\n *\t\t    from pj_stun_msg_type. This function will add the\n *\t\t    indication bit as necessary.\n * @param p_tdata   Pointer to receive STUN transmit data instance containing\n *\t\t    the message.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_session_create_ind(pj_stun_session *sess,\n\t\t\t\t\t\tint msg_type,\n\t\t\t\t\t        pj_stun_tx_data **p_tdata);\n\n/**\n * Create a STUN response message. After the message has been \n * successfully created, application can send the message by calling \n * pj_stun_session_send_msg(). Alternatively application may use\n * pj_stun_session_respond() to create and send response in one function\n * call.\n *\n * @param sess\t    The STUN session instance.\n * @param rdata\t    The STUN request where the response is to be created.\n * @param err_code  Error code to be set in the response, if error response\n *\t\t    is to be created, according to pj_stun_status enumeration.\n *\t\t    This argument MUST be zero if successful response is\n *\t\t    to be created.\n * @param err_msg   Optional pointer for the error message string, when\n *\t\t    creating error response. If the value is NULL and the\n *\t\t    \\a err_code is non-zero, then default error message will\n *\t\t    be used.\n * @param p_tdata   Pointer to receive the response message created.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_session_create_res(pj_stun_session *sess,\n\t\t\t\t\t\tconst pj_stun_rx_data *rdata,\n\t\t\t\t\t\tunsigned err_code,\n\t\t\t\t\t\tconst pj_str_t *err_msg,\n\t\t\t\t\t\tpj_stun_tx_data **p_tdata);\n\n/**\n * Send STUN message to the specified destination. This function will encode\n * the pj_stun_msg instance to a packet buffer, and add credential or\n * fingerprint if necessary. If the message is a request, the session will\n * also create and manage a STUN client transaction to be used to manage the\n * retransmission of the request. After the message has been encoded and\n * transaction is setup, the \\a on_send_msg() callback of pj_stun_session_cb\n * (which is registered when the STUN session is created) will be called\n * to actually send the message to the wire.\n *\n * @param sess\t    The STUN session instance.\n * @param token\t    Optional token which will be given back to application in\n *\t\t    \\a on_send_msg() callback and \\a on_request_complete()\n *\t\t    callback, if the message is a STUN request message. \n *\t\t    Internally this function will put the token in the \n *\t\t    \\a token field of pj_stun_tx_data, hence it will\n *\t\t    overwrite any value that the application puts there.\n * @param cache_res If the message is a response message for an incoming\n *\t\t    request, specify PJ_TRUE to instruct the STUN session\n *\t\t    to cache this response for subsequent incoming request\n *\t\t    retransmission. Otherwise this parameter will be ignored\n *\t\t    for non-response message.\n * @param retransmit If the message is a request message, specify whether the\n *\t\t    request should be retransmitted. Normally application will\n *\t\t    specify TRUE if the underlying transport is UDP and FALSE\n *\t\t    if the underlying transport is TCP or TLS.\n * @param dst_addr  The destination socket address.\n * @param addr_len  Length of destination address.\n * @param tdata\t    The STUN transmit data containing the STUN message to\n *\t\t    be sent.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n *\t\t    This function will return PJNATH_ESTUNDESTROYED if \n *\t\t    application has destroyed the session in \n *\t\t    \\a on_send_msg() callback.\n */\nPJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess,\n\t\t\t\t\t      void *token,\n\t\t\t\t\t      pj_bool_t cache_res,\n\t\t\t\t\t      pj_bool_t retransmit,\n\t\t\t\t\t      const pj_sockaddr_t *dst_addr,\n\t\t\t\t\t      unsigned addr_len,\n\t\t\t\t\t      pj_stun_tx_data *tdata);\n\n/**\n * This is a utility function to create and send response for an incoming\n * STUN request. Internally this function calls pj_stun_session_create_res()\n * and pj_stun_session_send_msg(). It is provided here as a matter of\n * convenience.\n *\n * @param sess\t    The STUN session instance.\n * @param rdata\t    The STUN request message to be responded.\n * @param code\t    Error code to be set in the response, if error response\n *\t\t    is to be created, according to pj_stun_status enumeration.\n *\t\t    This argument MUST be zero if successful response is\n *\t\t    to be created.\n * @param err_msg   Optional pointer for the error message string, when\n *\t\t    creating error response. If the value is NULL and the\n *\t\t    \\a err_code is non-zero, then default error message will\n *\t\t    be used.\n * @param token\t    Optional token which will be given back to application in\n *\t\t    \\a on_send_msg() callback and \\a on_request_complete()\n *\t\t    callback, if the message is a STUN request message. \n *\t\t    Internally this function will put the token in the \n *\t\t    \\a token field of pj_stun_tx_data, hence it will\n *\t\t    overwrite any value that the application puts there.\n * @param cache\t    Specify whether session should cache this response for\n *\t\t    future request retransmission. If TRUE, subsequent request\n *\t\t    retransmission will be handled by the session and it \n *\t\t    will not call request callback.\n * @param dst_addr  Destination address of the response (or equal to the\n *\t\t    source address of the original request).\n * @param addr_len  Address length.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n *\t\t    This function will return PJNATH_ESTUNDESTROYED if \n *\t\t    application has destroyed the session in \n *\t\t    \\a on_send_msg() callback.\n */\nPJ_DECL(pj_status_t) pj_stun_session_respond(pj_stun_session *sess, \n\t\t\t\t\t     const pj_stun_rx_data *rdata,\n\t\t\t\t\t     unsigned code, \n\t\t\t\t\t     const char *err_msg,\n\t\t\t\t\t     void *token,\n\t\t\t\t\t     pj_bool_t cache, \n\t\t\t\t\t     const pj_sockaddr_t *dst_addr, \n\t\t\t\t\t     unsigned addr_len);\n\n/**\n * Cancel outgoing STUN transaction. This operation is only valid for outgoing\n * STUN request, to cease retransmission of the request and destroy the\n * STUN client transaction that is used to send the request.\n *\n * @param sess\t    The STUN session instance.\n * @param tdata\t    The request message previously sent.\n * @param notify    Specify whether \\a on_request_complete() callback should\n *\t\t    be called.\n * @param status    If \\a on_request_complete() callback is to be called,\n *\t\t    specify the error status to be given when calling the\n *\t\t    callback. This error status MUST NOT be PJ_SUCCESS.\n *\n * @return\t    PJ_SUCCESS if transaction is successfully cancelled.\n *\t\t    This function will return PJNATH_ESTUNDESTROYED if \n *\t\t    application has destroyed the session in \n *\t\t    \\a on_request_complete() callback.\n */\nPJ_DECL(pj_status_t) pj_stun_session_cancel_req(pj_stun_session *sess,\n\t\t\t\t\t\tpj_stun_tx_data *tdata,\n\t\t\t\t\t\tpj_bool_t notify,\n\t\t\t\t\t\tpj_status_t status);\n\n/**\n * Explicitly request retransmission of the request. Normally application\n * doesn't need to do this, but this functionality is needed by ICE to\n * speed up connectivity check completion.\n *\n * @param sess\t    The STUN session instance.\n * @param tdata\t    The request message previously sent.\n * @param mod_count Boolean flag to indicate whether transmission count\n *                  needs to be incremented.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error.\n *\t\t    This function will return PJNATH_ESTUNDESTROYED if \n *\t\t    application has destroyed the session in \\a on_send_msg()\n *\t\t    callback.\n */\nPJ_DECL(pj_status_t) pj_stun_session_retransmit_req(pj_stun_session *sess,\n\t\t\t\t\t\t    pj_stun_tx_data *tdata,\n                                                    pj_bool_t mod_count);\n\n\n/**\n * Application must call this function to notify the STUN session about\n * the arrival of STUN packet. The STUN packet MUST have been checked\n * first with #pj_stun_msg_check() to verify that this is indeed a valid\n * STUN packet.\n *\n * The STUN session will decode the packet into pj_stun_msg, and process\n * the message accordingly. If the message is a response, it will search\n * through the outstanding STUN client transactions for a matching\n * transaction ID and hand over the response to the transaction.\n *\n * On successful message processing, application will be notified about\n * the message via one of the pj_stun_session_cb callback.\n *\n * @param sess\t\tThe STUN session instance.\n * @param packet\tThe packet containing STUN message.\n * @param pkt_size\tSize of the packet.\n * @param options\tOptions, from #pj_stun_decode_options.\n * @param parsed_len\tOptional pointer to receive the size of the parsed\n *\t\t\tSTUN message (useful if packet is received via a\n *\t\t\tstream oriented protocol).\n * @param token\t\tOptional token which will be given back to application\n *\t\t\tin the \\a on_rx_request(), \\a on_rx_indication() and \n *\t\t\t\\a on_send_msg() callbacks. The token can be used to \n *\t\t\tassociate processing or incoming request or indication\n *\t\t\twith some context.\n * @param src_addr\tThe source address of the packet, which will also\n *\t\t\tbe given back to application callbacks, along with\n *\t\t\tsource address length.\n * @param src_addr_len\tLength of the source address.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n *\t\t\tThis function will return PJNATH_ESTUNDESTROYED if \n *\t\t\tapplication has destroyed the session in one of the\n *\t\t\tcallback.\n */\nPJ_DECL(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess,\n\t\t\t\t\t       const void *packet,\n\t\t\t\t\t       pj_size_t pkt_size,\n\t\t\t\t\t       unsigned options,\n\t\t\t\t\t       void *token,\n\t\t\t\t\t       pj_size_t *parsed_len,\n\t\t\t\t\t       const pj_sockaddr_t *src_addr,\n\t\t\t\t\t       unsigned src_addr_len);\n\n/**\n * Destroy the transmit data. Call this function only when tdata has been\n * created but application doesn't want to send the message (perhaps\n * because of other error).\n *\n * @param sess\t    The STUN session.\n * @param tdata\t    The transmit data.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(void) pj_stun_msg_destroy_tdata(pj_stun_session *sess,\n\t\t\t\t\tpj_stun_tx_data *tdata);\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n#endif\t/* __PJNATH_STUN_SESSION_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/stun_sock.h",
    "content": "/* $Id: stun_sock.h 4360 2013-02-21 11:26:35Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_STUN_SOCK_H__\n#define __PJNATH_STUN_SOCK_H__\n\n/**\n * @file stun_sock.h\n * @brief STUN aware socket transport\n */\n#include <pjnath/stun_config.h>\n#include <pjlib-util/resolver.h>\n#include <pj/ioqueue.h>\n#include <pj/lock.h>\n#include <pj/sock.h>\n#include <pj/sock_qos.h>\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * @addtogroup PJNATH_STUN_SOCK\n * @{\n *\n * The STUN transport provides asynchronous UDP like socket transport\n * with the additional STUN capability. It has the following features:\n *\n *  - API to send and receive UDP packets\n *\n *  - multiplex STUN and non-STUN incoming packets and distinguish between\n *    STUN responses that belong to internal requests with application data\n *    (the application data may be STUN packets as well)\n *\n *  - DNS SRV resolution to the STUN server (if wanted), along with fallback\n *    to DNS A resolution if SRV record is not found.\n *\n *  - STUN keep-alive maintenance, and handle changes to the mapped address\n *    (when the NAT binding changes)\n *\n */\n\n/**\n * Opaque type to represent a STUN transport.\n */\ntypedef struct pj_stun_sock pj_stun_sock;\n\n/**\n * Types of operation being reported in \\a on_status() callback of\n * pj_stun_sock_cb. Application may retrieve the string representation\n * of these constants with pj_stun_sock_op_name().\n */\ntypedef enum pj_stun_sock_op\n{\n    /**\n     * Asynchronous DNS resolution.\n     */\n    PJ_STUN_SOCK_DNS_OP\t\t= 1,\n\n    /**\n     * Initial STUN Binding request.\n     */\n    PJ_STUN_SOCK_BINDING_OP,\n\n    /**\n     * Subsequent STUN Binding request for keeping the binding\n     * alive.\n     */\n    PJ_STUN_SOCK_KEEP_ALIVE_OP,\n\n    /**\n     * IP address change notification from the keep-alive operation.\n     */\n    PJ_STUN_SOCK_MAPPED_ADDR_CHANGE\n\n\n} pj_stun_sock_op;\n\n\n/**\n * This structure contains callbacks that will be called by the STUN\n * transport to notify application about various events.\n */\ntypedef struct pj_stun_sock_cb\n{\n    /**\n     * Notification when incoming packet has been received.\n     *\n     * @param stun_sock\tThe STUN transport.\n     * @param data\tThe packet.\n     * @param data_len\tLength of the packet.\n     * @param src_addr\tThe source address of the packet.\n     * @param addr_len\tThe length of the source address.\n     *\n     * @return\t\tApplication should normally return PJ_TRUE to let\n     *\t\t\tthe STUN transport continue its operation. However\n     *\t\t\tit must return PJ_FALSE if it has destroyed the\n     *\t\t\tSTUN transport in this callback.\n     */\n    pj_bool_t (*on_rx_data)(pj_stun_sock *stun_sock,\n\t\t\t    void *pkt,\n\t\t\t    unsigned pkt_len,\n\t\t\t    const pj_sockaddr_t *src_addr,\n\t\t\t    unsigned addr_len);\n\n    /**\n     * Notifification when asynchronous send operation has completed.\n     *\n     * @param stun_sock\tThe STUN transport.\n     * @param send_key\tThe send operation key that was given in\n     *\t\t\t#pj_stun_sock_sendto().\n     * @param sent\tIf value is positive non-zero it indicates the\n     *\t\t\tnumber of data sent. When the value is negative,\n     *\t\t\tit contains the error code which can be retrieved\n     *\t\t\tby negating the value (i.e. status=-sent).\n     *\n     * @return\t\tApplication should normally return PJ_TRUE to let\n     *\t\t\tthe STUN transport continue its operation. However\n     *\t\t\tit must return PJ_FALSE if it has destroyed the\n     *\t\t\tSTUN transport in this callback.\n     */\n    pj_bool_t (*on_data_sent)(pj_stun_sock *stun_sock,\n\t\t\t      pj_ioqueue_op_key_t *send_key,\n\t\t\t      pj_ssize_t sent);\n\n    /**\n     * Notification when the status of the STUN transport has changed. This\n     * callback may be called for the following conditions:\n     *\t- the first time the publicly mapped address has been resolved from\n     *\t  the STUN server, this callback will be called with \\a op argument\n     *    set to PJ_STUN_SOCK_BINDING_OP \\a status  argument set to \n     *    PJ_SUCCESS.\n     *\t- anytime when the transport has detected that the publicly mapped\n     *    address has changed, this callback will be called with \\a op\n     *    argument set to PJ_STUN_SOCK_KEEP_ALIVE_OP and \\a status\n     *    argument set to PJ_SUCCESS. On this case and the case above,\n     *    application will get the resolved public address in the\n     *    #pj_stun_sock_info structure.\n     *\t- for any terminal error (such as STUN time-out, DNS resolution\n     *    failure, or keep-alive failure), this callback will be called \n     *\t  with the \\a status argument set to non-PJ_SUCCESS.\n     *\n     * @param stun_sock\tThe STUN transport.\n     * @param op\tThe operation that triggers the callback.\n     * @param status\tThe status.\n     *\n     * @return\t\tMust return PJ_FALSE if it has destroyed the\n     *\t\t\tSTUN transport in this callback. Application should\n     *\t\t\tnormally destroy the socket and return PJ_FALSE\n     *\t\t\tupon encountering terminal error, otherwise it\n     *\t\t\tshould return PJ_TRUE to let the STUN socket operation\n     *\t\t\tcontinues.\n     */\n    pj_bool_t\t(*on_status)(pj_stun_sock *stun_sock, \n\t\t\t     pj_stun_sock_op op,\n\t\t\t     pj_status_t status);\n\n} pj_stun_sock_cb;\n\n\n/**\n * This structure contains information about the STUN transport. Application\n * may query this information by calling #pj_stun_sock_get_info().\n */\ntypedef struct pj_stun_sock_info\n{\n    /**\n     * The bound address of the socket.\n     */\n    pj_sockaddr\t    bound_addr;\n\n    /**\n     * IP address of the STUN server.\n     */\n    pj_sockaddr\t    srv_addr;\n\n    /**\n     * The publicly mapped address. It may contain zero address when the\n     * mapped address has not been resolved. Application may query whether\n     * this field contains valid address with pj_sockaddr_has_addr().\n     */\n    pj_sockaddr\t    mapped_addr;\n\n    /**\n     * Number of interface address aliases. The interface address aliases\n     * are list of all interface addresses in this host.\n     */\n    unsigned\t    alias_cnt;\n\n    /**\n     * Array of interface address aliases.\n     */\n    pj_sockaddr\t    aliases[PJ_ICE_ST_MAX_CAND];\n\n} pj_stun_sock_info;\n\n\n/**\n * This describe the settings to be given to the STUN transport during its\n * creation. Application should initialize this structure by calling\n * #pj_stun_sock_cfg_default().\n */\ntypedef struct pj_stun_sock_cfg\n{\n    /**\n     * The group lock to be used by the STUN socket. If NULL, the STUN socket\n     * will create one internally.\n     *\n     * Default: NULL\n     */\n    pj_grp_lock_t *grp_lock;\n\n    /**\n     * Packet buffer size.\n     *\n     * Default value is PJ_STUN_SOCK_PKT_LEN.\n     */\n    unsigned max_pkt_size;\n\n    /**\n     * Specify the number of simultaneous asynchronous read operations to\n     * be invoked to the ioqueue. Having more than one read operations will\n     * increase performance on multiprocessor systems since the application\n     * will be able to process more than one incoming packets simultaneously.\n     * Default value is 1.\n     */\n    unsigned async_cnt;\n\n    /**\n     * Specify the interface where the socket should be bound to. If the\n     * address is zero, socket will be bound to INADDR_ANY. If the address\n     * is non-zero, socket will be bound to this address only, and the\n     * transport will have only one address alias (the \\a alias_cnt field\n     * in #pj_stun_sock_info structure. If the port is set to zero, the\n     * socket will bind at any port (chosen by the OS).\n     */\n    pj_sockaddr bound_addr;\n\n    /**\n     * Specify the port range for STUN socket binding, relative to the start\n     * port number specified in \\a bound_addr. Note that this setting is only\n     * applicable when the start port number is non zero.\n     *\n     * Default value is zero.\n     */\n    pj_uint16_t\tport_range;\n\n    /**\n     * Specify the STUN keep-alive duration, in seconds. The STUN transport\n     * does keep-alive by sending STUN Binding request to the STUN server. \n     * If this value is zero, the PJ_STUN_KEEP_ALIVE_SEC value will be used.\n     * If the value is negative, it will disable STUN keep-alive.\n     */\n    int ka_interval;\n\n    /**\n     * QoS traffic type to be set on this transport. When application wants\n     * to apply QoS tagging to the transport, it's preferable to set this\n     * field rather than \\a qos_param fields since this is more portable.\n     *\n     * Default value is PJ_QOS_TYPE_BEST_EFFORT.\n     */\n    pj_qos_type qos_type;\n\n    /**\n     * Set the low level QoS parameters to the transport. This is a lower\n     * level operation than setting the \\a qos_type field and may not be\n     * supported on all platforms.\n     *\n     * By default all settings in this structure are disabled.\n     */\n    pj_qos_params qos_params;\n\n    /**\n     * Specify if STUN socket should ignore any errors when setting the QoS\n     * traffic type/parameters.\n     *\n     * Default: PJ_TRUE\n     */\n    pj_bool_t qos_ignore_error;\n\n    /**\n     * Specify target value for socket receive buffer size. It will be\n     * applied using setsockopt(). When it fails to set the specified size,\n     * it will try with lower value until the highest possible is\n     * successfully set.\n     *\n     * Default: 0 (OS default)\n     */\n    unsigned so_rcvbuf_size;\n\n    /**\n     * Specify target value for socket send buffer size. It will be\n     * applied using setsockopt(). When it fails to set the specified size,\n     * it will try with lower value until the highest possible is\n     * successfully set.\n     *\n     * Default: 0 (OS default)\n     */\n    unsigned so_sndbuf_size;\n\n} pj_stun_sock_cfg;\n\n\n\n/**\n * Retrieve the name representing the specified operation.\n */\nPJ_DECL(const char*) pj_stun_sock_op_name(pj_stun_sock_op op);\n\n\n/**\n * Initialize the STUN transport setting with its default values.\n *\n * @param cfg\tThe STUN transport config.\n */\nPJ_DECL(void) pj_stun_sock_cfg_default(pj_stun_sock_cfg *cfg);\n\n\n/**\n * Create the STUN transport using the specified configuration. Once\n * the STUN transport has been create, application should call\n * #pj_stun_sock_start() to start the transport.\n *\n * @param stun_cfg\tThe STUN configuration which contains among other\n *\t\t\tthings the ioqueue and timer heap instance for\n *\t\t\tthe operation of this transport.\n * @param af\t\tAddress family of socket. Currently pj_AF_INET()\n *\t\t\tand pj_AF_INET6() are supported. \n * @param name\t\tOptional name to be given to this transport to\n *\t\t\tassist debugging.\n * @param cb\t\tCallback to receive events/data from the transport.\n * @param cfg\t\tOptional transport settings.\n * @param user_data\tArbitrary application data to be associated with\n *\t\t\tthis transport.\n * @param p_sock\tPointer to receive the created transport instance.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_stun_sock_create(pj_stun_config *stun_cfg,\n\t\t\t\t\t const char *name,\n\t\t\t\t\t int af,\n\t\t\t\t\t const pj_stun_sock_cb *cb,\n\t\t\t\t\t const pj_stun_sock_cfg *cfg,\n\t\t\t\t\t void *user_data,\n\t\t\t\t\t pj_stun_sock **p_sock);\n\n\n/**\n * Start the STUN transport. This will start the DNS SRV resolution for\n * the STUN server (if desired), and once the server is resolved, STUN\n * Binding request will be sent to resolve the publicly mapped address.\n * Once the initial STUN Binding response is received, the keep-alive\n * timer will be started.\n *\n * @param stun_sock\tThe STUN transport instance.\n * @param domain\tThe domain, hostname, or IP address of the TURN\n *\t\t\tserver. When this parameter contains domain name,\n *\t\t\tthe \\a resolver parameter must be set to activate\n *\t\t\tDNS SRV resolution.\n * @param default_port\tThe default STUN port number to use when DNS SRV\n *\t\t\tresolution is not used. If DNS SRV resolution is\n *\t\t\tused, the server port number will be set from the\n *\t\t\tDNS SRV records. The recommended value for this\n *\t\t\tparameter is PJ_STUN_PORT.\n * @param resolver\tIf this parameter is not NULL, then the \\a domain\n *\t\t\tparameter will be first resolved with DNS SRV and\n *\t\t\tthen fallback to using DNS A/AAAA resolution when\n *\t\t\tDNS SRV resolution fails. If this parameter is\n *\t\t\tNULL, the \\a domain parameter will be resolved as\n *\t\t\thostname.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successfully\n *\t\t\tqueued, or the appropriate error code on failure.\n *\t\t\tWhen this function returns PJ_SUCCESS, the final\n *\t\t\tresult of the allocation process will be notified\n *\t\t\tto application in \\a on_state() callback.\n */\nPJ_DECL(pj_status_t) pj_stun_sock_start(pj_stun_sock *stun_sock,\n\t\t\t\t        const pj_str_t *domain,\n\t\t\t\t        pj_uint16_t default_port,\n\t\t\t\t        pj_dns_resolver *resolver);\n\n/**\n * Destroy the STUN transport.\n *\n * @param sock\t\tThe STUN transport socket.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_stun_sock_destroy(pj_stun_sock *sock);\n\n\n/**\n * Associate a user data with this STUN transport. The user data may then\n * be retrieved later with #pj_stun_sock_get_user_data().\n *\n * @param stun_sock\tThe STUN transport instance.\n * @param user_data\tArbitrary data.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_stun_sock_set_user_data(pj_stun_sock *stun_sock,\n\t\t\t\t\t        void *user_data);\n\n/**\n * Retrieve the previously assigned user data associated with this STUN\n * transport.\n *\n * @param stun_sock\tThe STUN transport instance.\n *\n * @return\t\tThe user/application data.\n */\nPJ_DECL(void*) pj_stun_sock_get_user_data(pj_stun_sock *stun_sock);\n\n\n/**\n * Get the group lock for this STUN transport.\n *\n * @param stun_sock\tThe STUN transport instance.\n *\n * @return\t        The group lock.\n */\nPJ_DECL(pj_grp_lock_t *) pj_stun_sock_get_grp_lock(pj_stun_sock *stun_sock);\n\n\n/**\n * Get the STUN transport info. The transport info contains, among other\n * things, the allocated relay address.\n *\n * @param stun_sock\tThe STUN transport instance.\n * @param info\t\tPointer to be filled with STUN transport info.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_stun_sock_get_info(pj_stun_sock *stun_sock,\n\t\t\t\t\t   pj_stun_sock_info *info);\n\n\n/**\n * Send a data to the specified address. This function may complete\n * asynchronously and in this case \\a on_data_sent() will be called.\n *\n * @param stun_sock\tThe STUN transport instance.\n * @param send_key\tOptional send key for sending the packet down to\n *\t\t\tthe ioqueue. This value will be given back to\n *\t\t\t\\a on_data_sent() callback\n * @param pkt\t\tThe data/packet to be sent to peer.\n * @param pkt_len\tLength of the data.\n * @param flag\t\tpj_ioqueue_sendto() flag.\n * @param dst_addr\tThe remote address.\n * @param addr_len\tLength of the address.\n *\n * @return\t\tPJ_SUCCESS if data has been sent immediately, or\n *\t\t\tPJ_EPENDING if data cannot be sent immediately. In\n *\t\t\tthis case the \\a on_data_sent() callback will be\n *\t\t\tcalled when data is actually sent. Any other return\n *\t\t\tvalue indicates error condition.\n */ \nPJ_DECL(pj_status_t) pj_stun_sock_sendto(pj_stun_sock *stun_sock,\n\t\t\t\t\t pj_ioqueue_op_key_t *send_key,\n\t\t\t\t\t const void *pkt,\n\t\t\t\t\t unsigned pkt_len,\n\t\t\t\t\t unsigned flag,\n\t\t\t\t\t const pj_sockaddr_t *dst_addr,\n\t\t\t\t\t unsigned addr_len);\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJNATH_STUN_SOCK_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/stun_transaction.h",
    "content": "/* $Id: stun_transaction.h 4360 2013-02-21 11:26:35Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_STUN_TRANSACTION_H__\n#define __PJNATH_STUN_TRANSACTION_H__\n\n/**\n * @file stun_transaction.h\n * @brief STUN transaction\n */\n\n#include <pjnath/stun_msg.h>\n#include <pjnath/stun_config.h>\n#include <pj/lock.h>\n\n\nPJ_BEGIN_DECL\n\n\n/* **************************************************************************/\n/**\n * @defgroup PJNATH_STUN_TRANSACTION STUN Client Transaction\n * @brief STUN client transaction\n * @ingroup PJNATH_STUN_BASE\n * @{\n *\n The @ref PJNATH_STUN_TRANSACTION is used to manage outgoing STUN request,\n for example to retransmit the request and to notify application about the\n completion of the request.\n\n The @ref PJNATH_STUN_TRANSACTION does not use any networking operations,\n but instead application must supply the transaction with a callback to\n be used by the transaction to send outgoing requests. This way the STUN\n transaction is made more generic and can work with different types of\n networking codes in application.\n\n\n */\n\n/**\n * Opaque declaration of STUN client transaction.\n */\ntypedef struct pj_stun_client_tsx pj_stun_client_tsx;\n\n/**\n * STUN client transaction callback.\n */\ntypedef struct pj_stun_tsx_cb\n{\n    /**\n     * This callback is called when the STUN transaction completed.\n     *\n     * @param tsx\t    The STUN transaction.\n     * @param status\t    Status of the transaction. Status PJ_SUCCESS\n     *\t\t\t    means that the request has received a successful\n     *\t\t\t    response.\n     * @param response\t    The STUN response, which value may be NULL if\n     *\t\t\t    \\a status is not PJ_SUCCESS.\n     * @param src_addr\t    The source address of the response, if response \n     *\t\t\t    is not NULL.\n     * @param src_addr_len  The length of the source address.\n     */\n    void\t(*on_complete)(pj_stun_client_tsx *tsx,\n\t\t\t       pj_status_t status, \n\t\t\t       const pj_stun_msg *response,\n\t\t\t       const pj_sockaddr_t *src_addr,\n\t\t\t       unsigned src_addr_len);\n\n    /**\n     * This callback is called by the STUN transaction when it wants to send\n     * outgoing message.\n     *\n     * @param tsx\t    The STUN transaction instance.\n     * @param stun_pkt\t    The STUN packet to be sent.\n     * @param pkt_size\t    Size of the STUN packet.\n     *\n     * @return\t\t    If return value of the callback is not PJ_SUCCESS,\n     *\t\t\t    the transaction will fail. Application MUST return\n     *\t\t\t    PJNATH_ESTUNDESTROYED if it has destroyed the\n     *\t\t\t    transaction in this callback.\n     */\n    pj_status_t (*on_send_msg)(pj_stun_client_tsx *tsx,\n\t\t\t       const void *stun_pkt,\n\t\t\t       pj_size_t pkt_size);\n\n    /**\n     * This callback is called after the timer that was scheduled by\n     * #pj_stun_client_tsx_schedule_destroy() has elapsed. Application\n     * should call #pj_stun_client_tsx_destroy() upon receiving this\n     * callback.\n     *\n     * This callback is optional if application will not call \n     * #pj_stun_client_tsx_schedule_destroy().\n     *\n     * @param tsx\t    The STUN transaction instance.\n     */\n    void (*on_destroy)(pj_stun_client_tsx *tsx);\n\n} pj_stun_tsx_cb;\n\n\n\n/**\n * Create an instance of STUN client transaction. The STUN client \n * transaction is used to transmit outgoing STUN request and to \n * ensure the reliability of the request by periodically retransmitting\n * the request, if necessary.\n *\n * @param cfg\t\tThe STUN endpoint, which will be used to retrieve\n *\t\t\tvarious settings for the transaction.\n * @param pool\t\tPool to be used to allocate memory from.\n * @param grp_lock\tGroup lock to synchronize.\n * @param cb\t\tCallback structure, to be used by the transaction\n *\t\t\tto send message and to notify the application about\n *\t\t\tthe completion of the transaction.\n * @param p_tsx\t\tPointer to receive the transaction instance.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_client_tsx_create(\tpj_stun_config *cfg,\n\t\t\t\t\t        pj_pool_t *pool,\n\t\t\t\t\t        pj_grp_lock_t *grp_lock,\n\t\t\t\t\t\tconst pj_stun_tsx_cb *cb,\n\t\t\t\t\t\tpj_stun_client_tsx **p_tsx);\n\n/**\n * Schedule timer to destroy the transaction after the transaction is \n * complete. Application normally calls this function in the on_complete()\n * callback. When this timer elapsed, the on_destroy() callback will be \n * called.\n *\n * This is convenient to let the STUN transaction absorbs any response \n * for the previous request retransmissions. If application doesn't want\n * this, it can destroy the transaction immediately by calling \n * #pj_stun_client_tsx_destroy().\n *\n * @param tsx\t\tThe STUN transaction.\n * @param delay\t\tThe delay interval before on_destroy() callback\n *\t\t\tis called.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) \npj_stun_client_tsx_schedule_destroy(pj_stun_client_tsx *tsx,\n\t\t\t\t    const pj_time_val *delay);\n\n\n/**\n * Destroy the STUN transaction immediately after the transaction is complete.\n * Application normally calls this function in the on_complete() callback.\n *\n * @param tsx\t\tThe STUN transaction.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_client_tsx_destroy(pj_stun_client_tsx *tsx);\n\n\n/**\n * Stop the client transaction.\n *\n * @param tsx\t\tThe STUN transaction.\n *\n * @return\t\tPJ_SUCCESS on success or PJ_EINVAL if the parameter\n *\t\t\tis NULL.\n */\nPJ_DECL(pj_status_t) pj_stun_client_tsx_stop(pj_stun_client_tsx *tsx);\n\n\n/**\n * Check if transaction has completed.\n *\n * @param tsx\t\tThe STUN transaction.\n *\n * @return\t\tNon-zero if transaction has completed.\n */\nPJ_DECL(pj_bool_t) pj_stun_client_tsx_is_complete(pj_stun_client_tsx *tsx);\n\n\n/**\n * Associate an arbitrary data with the STUN transaction. This data\n * can be then retrieved later from the transaction, by using\n * pj_stun_client_tsx_get_data() function.\n *\n * @param tsx\t\tThe STUN client transaction.\n * @param data\t\tApplication data to be associated with the\n *\t\t\tSTUN transaction.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pj_stun_client_tsx_set_data(pj_stun_client_tsx *tsx,\n\t\t\t\t\t\t void *data);\n\n\n/**\n * Get the user data that was previously associated with the STUN \n * transaction.\n *\n * @param tsx\t\tThe STUN client transaction.\n *\n * @return\t\tThe user data.\n */\nPJ_DECL(void*) pj_stun_client_tsx_get_data(pj_stun_client_tsx *tsx);\n\n\n/**\n * Start the STUN client transaction by sending STUN request using\n * this transaction. If reliable transport such as TCP or TLS is used,\n * the retransmit flag should be set to PJ_FALSE because reliablity\n * will be assured by the transport layer.\n *\n * @param tsx\t\tThe STUN client transaction.\n * @param retransmit\tShould this message be retransmitted by the\n *\t\t\tSTUN transaction.\n * @param pkt\t\tThe STUN packet to send.\n * @param pkt_len\tLength of STUN packet.\n *\n * @return\t\tPJ_SUCCESS on success, or PJNATH_ESTUNDESTROYED \n *\t\t\twhen the user has destroyed the transaction in \n *\t\t\t\\a on_send_msg() callback, or any other error code\n *\t\t\tas returned by \\a on_send_msg() callback.\n */\nPJ_DECL(pj_status_t) pj_stun_client_tsx_send_msg(pj_stun_client_tsx *tsx,\n\t\t\t\t\t\t pj_bool_t retransmit,\n\t\t\t\t\t\t void *pkt,\n\t\t\t\t\t\t unsigned pkt_len);\n\n/**\n * Request to retransmit the request. Normally application should not need\n * to call this function since retransmission would be handled internally,\n * but this functionality is needed by ICE.\n *\n * @param tsx\t\tThe STUN client transaction instance.\n * @param mod_count     Boolean flag to indicate whether transmission count\n *                      needs to be incremented.\n *\n * @return\t\tPJ_SUCCESS on success, or PJNATH_ESTUNDESTROYED \n *\t\t\twhen the user has destroyed the transaction in \n *\t\t\t\\a on_send_msg() callback, or any other error code\n *\t\t\tas returned by \\a on_send_msg() callback.\n */\nPJ_DECL(pj_status_t) pj_stun_client_tsx_retransmit(pj_stun_client_tsx *tsx,\n                                                   pj_bool_t mod_count);\n\n\n/**\n * Notify the STUN transaction about the arrival of STUN response.\n * If the STUN response contains a final error (300 and greater), the\n * transaction will be terminated and callback will be called. If the\n * STUN response contains response code 100-299, retransmission\n * will  cease, but application must still call this function again\n * with a final response later to allow the transaction to complete.\n *\n * @param tsx\t\tThe STUN client transaction instance.\n * @param msg\t\tThe incoming STUN message.\n * @param src_addr\tThe source address of the packet.\n * @param src_addr_len\tThe length of the source address.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_stun_client_tsx_on_rx_msg(pj_stun_client_tsx *tsx,\n\t\t\t\t\t\t  const pj_stun_msg *msg,\n\t\t\t\t\t\t  const pj_sockaddr_t*src_addr,\n\t\t\t\t\t\t  unsigned src_addr_len);\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJNATH_STUN_TRANSACTION_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/turn_session.h",
    "content": "/* $Id: turn_session.h 4360 2013-02-21 11:26:35Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_TURN_SESSION_H__\n#define __PJNATH_TURN_SESSION_H__\n\n/**\n * @file turn_session.h\n * @brief Transport independent TURN client session.\n */\n#include <pjnath/stun_session.h>\n#include <pjlib-util/resolver.h>\n\n\nPJ_BEGIN_DECL\n\n\n/* **************************************************************************/\n/**\n@addtogroup PJNATH_TURN_SESSION\n@{\n\nThe \\ref PJNATH_TURN_SESSION is a transport-independent object to\nmanage a client TURN session. It contains the core logic for manage\nthe TURN client session as listed in \\ref turn_op_sec, but\nin transport-independent manner (i.e. it doesn't have a socket), so\nthat developer can integrate TURN client functionality into existing\nframework that already has its own means to send and receive data,\nor to support new transport types to TURN, such as TLS.\n\n\n\\section turn_sess_using_sec Using the TURN session\n\nThese steps describes how to use the TURN session:\n\n - <b>Creating the session</b>:\\n\n   use #pj_turn_session_create() to create the session. \n\n - <b>Configuring credential</b>:\\n\n   all TURN operations requires the use of authentication (it uses STUN \n   long term autentication method). Use #pj_turn_session_set_credential()\n   to configure the TURN credential to be used by the session.\n\n - <b>Configuring server</b>:\\n\n   application must call #pj_turn_session_set_server() before it can send\n   Allocate request (with pj_turn_session_alloc()). This function will\n   resolve the TURN server using DNS SRV resolution if the \\a resolver\n   is set. The server resolution process will complete asynchronously,\n   and application will be notified in \\a on_state() callback of the \n   #pj_turn_session_cb structurewith the session state set to \n   PJ_TURN_STATE_RESOLVED.\n\n - <b>Creating allocation</b>:\\n\n   create one \"relay port\" (or called <b>relayed-transport-address</b>\n   in TURN terminology) in the TURN server by using #pj_turn_session_alloc().\n   This will send Allocate request to the server. This function will complete\n   immediately, and application will be notified about the allocation\n   result in the \\a on_state() callback of the #pj_turn_session_cb structure.\n\n - <b>Getting the allocation result</b>:\\n\n   if allocation is successful, the session state will progress to\n   \\a PJ_TURN_STATE_READY, otherwise the state will be \n   \\a PJ_TURN_STATE_DEALLOCATED or higher. Session state progression is\n   reported in the \\a on_state() callback of the #pj_turn_session_cb \n   structure. On successful allocation, application may retrieve the\n   allocation info by calling #pj_turn_session_get_info().\n\n - <b>Sending data through the relay</b>.\\n\n   Once allocation has been created, client may send data to any remote \n   endpoints (called peers in TURN terminology) via the \"relay port\". It does\n   so by calling #pj_turn_session_sendto(), giving the peer address \n   in the function argument. But note that at this point peers are not allowed\n   to send data towards the client (via the \"relay port\") before permission is\n   installed for that peer.\n\n - <b>Creating permissions</b>.\\n\n   Permission needs to be created in the TURN server so that a peer can send \n   data to the client via the relay port (a peer in this case is identified by\n   its IP address). Without this, when the TURN server receives data from the\n   peer in the \"relay port\", it will drop this data. Create the permission by\n   calling #pj_turn_session_set_perm(), specifying the peer IP address in the\n   argument (the port part of the address is ignored). More than one IP \n   addresses may be specified.\n\n - <b>Receiving data from peers</b>.\\n\n   Once permission has been installed for the peer, any data received by the \n   TURN server (from that peer) in the \"relay port\" will be relayed back to \n   client by the server, and application will be notified via \\a on_rx_data\n   callback of the #pj_turn_session_cb.\n\n - <b>Using ChannelData</b>.\\n\n   TURN provides optimized framing to the data by using ChannelData \n   packetization. The client activates this format for the specified peer by\n   calling #pj_turn_session_bind_channel(). Data sent or received to/for\n   this peer will then use ChannelData format instead of Send or Data \n   Indications.\n\n - <b>Refreshing the allocation, permissions, and channel bindings</b>.\\n\n   Allocations, permissions, and channel bindings will be refreshed by the\n   session automatically when they about to expire.\n\n - <b>Destroying the allocation</b>.\\n\n   Once the \"relay port\" is no longer needed, client destroys the allocation\n   by calling #pj_turn_session_shutdown(). This function will return\n   immediately, and application will be notified about the deallocation\n   result in the \\a on_state() callback of the #pj_turn_session_cb structure.\n   Once the state has reached PJ_TURN_STATE_DESTROYING, application must\n   assume that the session will be destroyed shortly after.\n\n */\n\n/** \n * Opaque declaration for TURN client session.\n */\ntypedef struct pj_turn_session pj_turn_session;\n\n\n/** \n * TURN transport types, which will be used both to specify the connection \n * type for reaching TURN server and the type of allocation transport to be \n * requested to server (the REQUESTED-TRANSPORT attribute).\n */\ntypedef enum pj_turn_tp_type\n{\n    /**\n     * UDP transport, which value corresponds to IANA protocol number.\n     */\n    PJ_TURN_TP_UDP = 17,\n\n    /**\n     * TCP transport, which value corresponds to IANA protocol number.\n     */\n    PJ_TURN_TP_TCP = 6,\n\n    /**\n     * TLS transport. The TLS transport will only be used as the connection\n     * type to reach the server and never as the allocation transport type.\n     */\n    PJ_TURN_TP_TLS = 255\n\n} pj_turn_tp_type;\n\n\n/** TURN session state */\ntypedef enum pj_turn_state_t\n{\n    /**\n     * TURN session has just been created.\n     */\n    PJ_TURN_STATE_NULL,\n\n    /**\n     * TURN server has been configured and now is being resolved via\n     * DNS SRV resolution.\n     */\n    PJ_TURN_STATE_RESOLVING,\n\n    /**\n     * TURN server has been resolved. If there is pending allocation to\n     * be done, it will be invoked immediately.\n     */\n    PJ_TURN_STATE_RESOLVED,\n\n    /**\n     * TURN session has issued ALLOCATE request and is waiting for response\n     * from the TURN server.\n     */\n    PJ_TURN_STATE_ALLOCATING,\n\n    /**\n     * TURN session has successfully allocated relay resoruce and now is\n     * ready to be used.\n     */\n    PJ_TURN_STATE_READY,\n\n    /**\n     * TURN session has issued deallocate request and is waiting for a\n     * response from the TURN server.\n     */\n    PJ_TURN_STATE_DEALLOCATING,\n\n    /**\n     * Deallocate response has been received. Normally the session will\n     * proceed to DESTROYING state immediately.\n     */\n    PJ_TURN_STATE_DEALLOCATED,\n\n    /**\n     * TURN session is being destroyed.\n     */\n    PJ_TURN_STATE_DESTROYING\n\n} pj_turn_state_t;\n\n\n#pragma pack(1)\n\n/**\n * This structure ChannelData header. All the fields are in network byte\n * order when it's on the wire.\n */\ntypedef struct pj_turn_channel_data\n{\n    pj_uint16_t ch_number;\t/**< Channel number.    */\n    pj_uint16_t length;\t\t/**< Payload length.\t*/\n} pj_turn_channel_data;\n\n\n#pragma pack()\n\n\n/**\n * Callback to receive events from TURN session.\n */\ntypedef struct pj_turn_session_cb\n{\n    /**\n     * This callback will be called by the TURN session whenever it\n     * needs to send outgoing message. Since the TURN session doesn't\n     * have a socket on its own, this callback must be implemented.\n     *\n     * @param sess\tThe TURN session.\n     * @param pkt\tThe packet/data to be sent.\n     * @param pkt_len\tLength of the packet/data.\n     * @param dst_addr\tDestination address of the packet.\n     * @param addr_len\tLength of the destination address.\n     *\n     * @return\t\tThe callback should return the status of the\n     *\t\t\tsend operation. \n     */\n    pj_status_t (*on_send_pkt)(pj_turn_session *sess,\n\t\t\t       const pj_uint8_t *pkt,\n\t\t\t       unsigned pkt_len,\n\t\t\t       const pj_sockaddr_t *dst_addr,\n\t\t\t       unsigned addr_len);\n\n    /**\n     * Notification when peer address has been bound successfully to \n     * a channel number.\n     *\n     * This callback is optional since the nature of this callback is\n     * for information only.\n     *\n     * @param sess\tThe TURN session.\n     * @param peer_addr\tThe peer address.\n     * @param addr_len\tLength of the peer address.\n     * @param ch_num\tThe channel number associated with this peer address.\n     */\n    void (*on_channel_bound)(pj_turn_session *sess,\n\t\t\t     const pj_sockaddr_t *peer_addr,\n\t\t\t     unsigned addr_len,\n\t\t\t     unsigned ch_num);\n\n    /**\n     * Notification when incoming data has been received, either through\n     * Data indication or ChannelData message from the TURN server.\n     *\n     * @param sess\tThe TURN session.\n     * @param pkt\tThe data/payload of the Data Indication or ChannelData\n     *\t\t\tpacket.\n     * @param pkt_len\tLength of the data/payload.\n     * @param peer_addr\tPeer address where this payload was received by\n     *\t\t\tthe TURN server.\n     * @param addr_len\tLength of the peer address.\n     */\n    void (*on_rx_data)(pj_turn_session *sess,\n\t\t       void *pkt,\n\t\t       unsigned pkt_len,\n\t\t       const pj_sockaddr_t *peer_addr,\n\t\t       unsigned addr_len);\n\n    /**\n     * Notification when TURN session state has changed. Application should\n     * implement this callback at least to know that the TURN session is\n     * going to be destroyed.\n     *\n     * @param sess\tThe TURN session.\n     * @param old_state\tThe previous state of the session.\n     * @param new_state\tThe current state of the session.\n     */\n    void (*on_state)(pj_turn_session *sess, \n\t\t     pj_turn_state_t old_state,\n\t\t     pj_turn_state_t new_state);\n\n} pj_turn_session_cb;\n\n\n/**\n * Allocation parameter, which can be given when application calls \n * pj_turn_session_alloc() to allocate relay address in the TURN server.\n * Application should call pj_turn_alloc_param_default() to initialize\n * this structure with the default values.\n */\ntypedef struct pj_turn_alloc_param\n{\n    /**\n     * The requested BANDWIDTH. Default is zero to not request any\n     * specific bandwidth. Note that this attribute has been deprecated\n     * after TURN-08 draft, hence application should only use this\n     * attribute when talking to TURN-07 or older version.\n     */\n    int\t    bandwidth;\n\n    /**\n     * The requested LIFETIME. Default is zero to not request any\n     * explicit allocation lifetime.\n     */\n    int\t    lifetime;\n\n    /**\n     * If set to non-zero, the TURN session will periodically send blank\n     * Send Indication every PJ_TURN_KEEP_ALIVE_SEC to refresh local\n     * NAT bindings. Default is zero.\n     */\n    int\t    ka_interval;\n\n} pj_turn_alloc_param;\n\n\n/**\n * This structure describes TURN session info.\n */\ntypedef struct pj_turn_session_info\n{\n    /**\n     * Session state.\n     */\n    pj_turn_state_t state;\n\n    /**\n     * Last error (if session was terminated because of error)\n     */\n    pj_status_t\t    last_status;\n\n    /**\n     * Type of connection to the TURN server.\n     */\n    pj_turn_tp_type conn_type;\n\n    /**\n     * The selected TURN server address.\n     */\n    pj_sockaddr\t    server;\n\n    /**\n     * Mapped address, as reported by the TURN server.\n     */\n    pj_sockaddr\t    mapped_addr;\n\n    /**\n     * The relay address\n     */\n    pj_sockaddr\t    relay_addr;\n\n    /**\n     * Current seconds before allocation expires.\n     */\n    int\t\t    lifetime;\n\n} pj_turn_session_info;\n\n\n/**\n * Initialize pj_turn_alloc_param with the default values.\n *\n * @param prm\tThe TURN allocation parameter to be initialized.\n */\nPJ_DECL(void) pj_turn_alloc_param_default(pj_turn_alloc_param *prm);\n\n\n/**\n * Duplicate pj_turn_alloc_param.\n *\n * @param pool\tPool to allocate memory (currently not used)\n * @param dst\tDestination parameter.\n * @param src\tSource parameter.\n */\nPJ_DECL(void) pj_turn_alloc_param_copy(pj_pool_t *pool, \n\t\t\t\t       pj_turn_alloc_param *dst,\n\t\t\t\t       const pj_turn_alloc_param *src);\n\n/**\n * Get string representation for the given TURN state.\n *\n * @param state\tThe TURN session state.\n *\n * @return\tThe state name as NULL terminated string.\n */\nPJ_DECL(const char*) pj_turn_state_name(pj_turn_state_t state);\n\n\n/**\n * Create a TURN session instance with the specified address family and\n * connection type. Once TURN session instance is created, application\n * must call pj_turn_session_alloc() to allocate a relay address in the TURN\n * server.\n *\n * @param cfg\t\tThe STUN configuration which contains among other\n *\t\t\tthings the ioqueue and timer heap instance for\n *\t\t\tthe operation of this session.\n * @param name\t\tOptional name to identify this session in the log.\n * @param af\t\tAddress family of the client connection. Currently\n *\t\t\tpj_AF_INET() and pj_AF_INET6() are supported.\n * @param conn_type\tConnection type to the TURN server.\n * @param grp_lock\tOptional group lock object to be used by this session.\n * \t\t\tIf this value is NULL, the session will create\n * \t\t\ta group lock internally.\n * @param cb\t\tCallback to receive events from the TURN session.\n * @param options\tOption flags, currently this value must be zero.\n * @param user_data\tArbitrary application data to be associated with\n *\t\t\tthis transport.\n * @param p_sess\tPointer to receive the created instance of the\n *\t\t\tTURN session.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_session_create(const pj_stun_config *cfg,\n\t\t\t\t\t    const char *name,\n\t\t\t\t\t    int af,\n\t\t\t\t\t    pj_turn_tp_type conn_type,\n\t\t\t\t\t    pj_grp_lock_t *grp_lock,\n\t\t\t\t\t    const pj_turn_session_cb *cb,\n\t\t\t\t\t    unsigned options,\n\t\t\t\t\t    void *user_data,\n\t\t\t\t\t    pj_turn_session **p_sess);\n\n/**\n * Shutdown TURN client session. This will gracefully deallocate and\n * destroy the client session.\n *\n * @param sess\t\tThe TURN client session.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_session_shutdown(pj_turn_session *sess);\n\n\n/**\n * Forcefully destroy the TURN session. This will destroy the session\n * immediately. If there is an active allocation, the server will not\n * be notified about the client destruction.\n *\n * @param sess\t\tThe TURN client session.\n * @param last_err\tOptional error code to be set to the session,\n *\t\t\twhich would be returned back in the \\a info\n *\t\t\tparameter of #pj_turn_session_get_info(). If\n *\t\t\tthis argument value is PJ_SUCCESS, the error\n *\t\t\tcode will not be set. If the session already\n *\t\t\thas an error code set, this function will not\n *\t\t\toverwrite that error code either.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_session_destroy(pj_turn_session *sess,\n\t\t\t\t\t     pj_status_t last_err);\n\n\n/**\n * Get the information about this TURN session and the allocation, if\n * any.\n *\n * @param sess\t\tThe TURN client session.\n * @param info\t\tThe structure to be initialized with the TURN\n *\t\t\tsession info.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_session_get_info(pj_turn_session *sess,\n\t\t\t\t\t      pj_turn_session_info *info);\n\n/**\n * Associate a user data with this TURN session. The user data may then\n * be retrieved later with pj_turn_session_get_user_data().\n *\n * @param sess\t\tThe TURN client session.\n * @param user_data\tArbitrary data.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_session_set_user_data(pj_turn_session *sess,\n\t\t\t\t\t\t   void *user_data);\n\n/**\n * Retrieve the previously assigned user data associated with this TURN\n * session.\n *\n * @param sess\t\tThe TURN client session.\n *\n * @return\t\tThe user/application data.\n */\nPJ_DECL(void*) pj_turn_session_get_user_data(pj_turn_session *sess);\n\n\n/**\n * Get the group lock for this TURN session.\n *\n * @param sess\t\tThe TURN client session.\n *\n * @return\t        The group lock.\n */\nPJ_DECL(pj_grp_lock_t *) pj_turn_session_get_grp_lock(pj_turn_session *sess);\n\n\n/**\n * Configure message logging. By default all flags are enabled.\n *\n * @param sess\t\tThe TURN client session.\n * @param flags\t\tBitmask combination of #pj_stun_sess_msg_log_flag\n */\nPJ_DECL(void) pj_turn_session_set_log(pj_turn_session *sess,\n\t\t\t\t      unsigned flags);\n\n\n/**\n * Configure the SOFTWARE name to be sent in all STUN requests by the\n * TURN session.\n *\n * @param sess\t    The TURN client session.\n * @param sw\t    Software name string. If this argument is NULL or\n *\t\t    empty, the session will not include SOFTWARE attribute\n *\t\t    in STUN requests and responses.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_turn_session_set_software_name(pj_turn_session *sess,\n\t\t\t\t\t\t       const pj_str_t *sw);\n\n\n/**\n * Set the server or domain name of the server. Before the application\n * can send Allocate request (with pj_turn_session_alloc()), it must first\n * resolve the server address(es) using this function. This function will\n * resolve the TURN server using DNS SRV resolution if the \\a resolver\n * is set. The server resolution process will complete asynchronously,\n * and application will be notified in \\a on_state() callback with the\n * session state set to PJ_TURN_STATE_RESOLVED.\n *\n * Application may call with pj_turn_session_alloc() before the server\n * resolution completes. In this case, the operation will be queued by\n * the session, and it will be sent once the server resolution completes.\n *\n * @param sess\t\tThe TURN client session.\n * @param domain\tThe domain, hostname, or IP address of the TURN\n *\t\t\tserver. When this parameter contains domain name,\n *\t\t\tthe \\a resolver parameter must be set to activate\n *\t\t\tDNS SRV resolution.\n * @param default_port\tThe default TURN port number to use when DNS SRV\n *\t\t\tresolution is not used. If DNS SRV resolution is\n *\t\t\tused, the server port number will be set from the\n *\t\t\tDNS SRV records.\n * @param resolver\tIf this parameter is not NULL, then the \\a domain\n *\t\t\tparameter will be first resolved with DNS SRV and\n *\t\t\tthen fallback to using DNS A/AAAA resolution when\n *\t\t\tDNS SRV resolution fails. If this parameter is\n *\t\t\tNULL, the \\a domain parameter will be resolved as\n *\t\t\thostname.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successfully\n *\t\t\tqueued, or the appropriate error code on failure.\n *\t\t\tWhen this function returns PJ_SUCCESS, the final\n *\t\t\tresult of the resolution process will be notified\n *\t\t\tto application in \\a on_state() callback.\n */\nPJ_DECL(pj_status_t) pj_turn_session_set_server(pj_turn_session *sess,\n\t\t\t\t\t        const pj_str_t *domain,\n\t\t\t\t\t\tint default_port,\n\t\t\t\t\t\tpj_dns_resolver *resolver);\n\n\n/**\n * Set credential to be used to authenticate against TURN server. \n * Application must call this function before sending Allocate request\n * with pj_turn_session_alloc().\n *\n * @param sess\t\tThe TURN client session\n * @param cred\t\tSTUN credential to be used.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_session_set_credential(pj_turn_session *sess,\n\t\t\t\t\t      const pj_stun_auth_cred *cred);\n\n\n/**\n * Allocate a relay address/resource in the TURN server by sending TURN\n * Allocate request. Application must first initiate the server resolution\n * process with pj_turn_session_set_server() and set the credential to be\n * used with pj_turn_session_set_credential() before calling this function.\n *\n * This function will complete asynchronously, and the application will be\n * notified about the allocation result in \\a on_state() callback. The \n * TURN session state will move to PJ_TURN_STATE_READY if allocation is\n * successful, and PJ_TURN_STATE_DEALLOCATING or greater state if allocation\n * has failed.\n *\n * Once allocation has been successful, the TURN session will keep this\n * allocation alive until the session is destroyed, by sending periodic\n * allocation refresh to the TURN server.\n *\n * @param sess\t\tThe TURN client session.\n * @param param\t\tOptional TURN allocation parameter.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successfully\n *\t\t\tinitiated or the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_session_alloc(pj_turn_session *sess,\n\t\t\t\t\t   const pj_turn_alloc_param *param);\n\n\n/**\n * Create or renew permission in the TURN server for the specified peer IP\n * addresses. Application must install permission for a particular (peer)\n * IP address before it sends any data to that IP address, or otherwise\n * the TURN server will drop the data.\n *\n * @param sess\t\tThe TURN client session.\n * @param addr_cnt\tNumber of IP addresses.\n * @param addr\t\tArray of peer IP addresses. Only the address family\n *\t\t\tand IP address portion of the socket address matter.\n * @param options\tSpecify 1 to let the TURN client session automatically\n *\t\t\trenew the permission later when they are about to\n *\t\t\texpire.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successfully\n *\t\t\tissued, or the appropriate error code. Note that\n *\t\t\tthe operation itself will complete asynchronously.\n */\nPJ_DECL(pj_status_t) pj_turn_session_set_perm(pj_turn_session *sess,\n\t\t\t\t\t      unsigned addr_cnt,\n\t\t\t\t\t      const pj_sockaddr addr[],\n\t\t\t\t\t      unsigned options);\n\n\n/**\n * Send a data to the specified peer address via the TURN relay. This \n * function will encapsulate the data as STUN Send Indication or TURN\n * ChannelData packet and send the message to the TURN server. The TURN\n * server then will send the data to the peer.\n *\n * The allocation (pj_turn_session_alloc()) must have been successfully\n * created before application can relay any data.\n *\n * Since TURN session is transport independent, this function will\n * ultimately call \\a on_send_pkt() callback to request the application \n * to actually send the packet containing the data to the TURN server.\n *\n * @param sess\t\tThe TURN client session.\n * @param pkt\t\tThe data/packet to be sent to peer.\n * @param pkt_len\tLength of the data.\n * @param peer_addr\tThe remote peer address (the ultimate destination\n *\t\t\tof the data, and not the TURN server address).\n * @param addr_len\tLength of the address.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_session_sendto(pj_turn_session *sess,\n\t\t\t\t\t    const pj_uint8_t *pkt,\n\t\t\t\t\t    unsigned pkt_len,\n\t\t\t\t\t    const pj_sockaddr_t *peer_addr,\n\t\t\t\t\t    unsigned addr_len);\n\n/**\n * Optionally establish channel binding for the specified a peer address.\n * This function will assign a unique channel number for the peer address\n * and request channel binding to the TURN server for this address. When\n * a channel has been bound to a peer, the TURN client and TURN server\n * will exchange data using ChannelData encapsulation format, which has\n * lower bandwidth overhead than Send Indication (the default format used\n * when peer address is not bound to a channel).\n *\n * This function will complete asynchronously, and application will be\n * notified about the result in \\a on_channel_bound() callback.\n *\n * @param sess\t\tThe TURN client session.\n * @param peer\t\tThe remote peer address.\n * @param addr_len\tLength of the address.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successfully\n *\t\t\tinitiated, or the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_session_bind_channel(pj_turn_session *sess,\n\t\t\t\t\t\t  const pj_sockaddr_t *peer,\n\t\t\t\t\t\t  unsigned addr_len);\n\n/**\n * Notify TURN client session upon receiving a packet from server. Since\n * the TURN session is transport independent, it does not read packet from\n * any sockets, and rather relies on application giving it packets that\n * are received from the TURN server. The session then processes this packet\n * and decides whether it is part of TURN protocol exchange or if it is a\n * data to be reported back to user, which in this case it will call the\n * \\a on_rx_data() callback.\n *\n * @param sess\t\tThe TURN client session.\n * @param pkt\t\tThe packet as received from the TURN server. This\n *\t\t\tshould contain either STUN encapsulated message or\n *\t\t\ta ChannelData packet.\n * @param pkt_len\tThe length of the packet.\n * @param parsed_len\tOptional argument to receive the number of parsed\n *\t\t\tor processed data from the packet.\n *\n * @return\t\tThe function may return non-PJ_SUCCESS if it receives\n *\t\t\tnon-STUN and non-ChannelData packet, or if the\n *\t\t\t\\a on_rx_data() returns non-PJ_SUCCESS;\n */\nPJ_DECL(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess,\n\t\t\t\t\t       void *pkt,\n\t\t\t\t\t       pj_size_t pkt_len,\n\t\t\t\t\t       pj_size_t *parsed_len);\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJNATH_TURN_SESSION_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/turn_sock.h",
    "content": "/* $Id: turn_sock.h 4360 2013-02-21 11:26:35Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_TURN_SOCK_H__\n#define __PJNATH_TURN_SOCK_H__\n\n/**\n * @file turn_sock.h\n * @brief TURN relay using UDP client as transport protocol\n */\n#include <pjnath/turn_session.h>\n#include <pj/sock_qos.h>\n\n\nPJ_BEGIN_DECL\n\n\n/* **************************************************************************/\n/**\n@addtogroup PJNATH_TURN_SOCK\n@{\n\nThis is a ready to use object for relaying application data via a TURN server,\nby managing all the operations in \\ref turn_op_sec.\n\n\\section turnsock_using_sec Using TURN transport\n\nThis object provides a thin wrapper to the \\ref PJNATH_TURN_SESSION, hence the\nAPI is very much the same (apart from the obvious difference in the names).\nPlease see \\ref PJNATH_TURN_SESSION for the documentation on how to use the\nsession.\n\n\\section turnsock_samples_sec Samples\n\nThe \\ref turn_client_sample is a sample application to use the\n\\ref PJNATH_TURN_SOCK.\n\nAlso see <b>\\ref samples_page</b> for other samples.\n\n */\n\n\n/** \n * Opaque declaration for TURN client.\n */\ntypedef struct pj_turn_sock pj_turn_sock;\n\n/**\n * This structure contains callbacks that will be called by the TURN\n * transport.\n */\ntypedef struct pj_turn_sock_cb\n{\n    /**\n     * Notification when incoming data has been received from the remote\n     * peer via the TURN server. The data reported in this callback will\n     * be the exact data as sent by the peer (e.g. the TURN encapsulation\n     * such as Data Indication or ChannelData will be removed before this\n     * function is called).\n     *\n     * @param turn_sock\t    The TURN client transport.\n     * @param data\t    The data as received from the peer.    \n     * @param data_len\t    Length of the data.\n     * @param peer_addr\t    The peer address.\n     * @param addr_len\t    The length of the peer address.\n     */\n    void (*on_rx_data)(pj_turn_sock *turn_sock,\n\t\t       void *pkt,\n\t\t       unsigned pkt_len,\n\t\t       const pj_sockaddr_t *peer_addr,\n\t\t       unsigned addr_len);\n\n    /**\n     * Notification when TURN session state has changed. Application should\n     * implement this callback to monitor the progress of the TURN session.\n     *\n     * @param turn_sock\t    The TURN client transport.\n     * @param old_state\t    Previous state.\n     * @param new_state\t    Current state.\n     */\n    void (*on_state)(pj_turn_sock *turn_sock, \n\t\t     pj_turn_state_t old_state,\n\t\t     pj_turn_state_t new_state);\n\n} pj_turn_sock_cb;\n\n\n/**\n * This structure describes options that can be specified when creating\n * the TURN socket. Application should call #pj_turn_sock_cfg_default()\n * to initialize this structure with its default values before using it.\n */\ntypedef struct pj_turn_sock_cfg\n{\n    /**\n     * The group lock to be used by the STUN socket. If NULL, the STUN socket\n     * will create one internally.\n     *\n     * Default: NULL\n     */\n    pj_grp_lock_t *grp_lock;\n\n    /**\n     * Packet buffer size.\n     *\n     * Default value is PJ_TURN_MAX_PKT_LEN.\n     */\n    unsigned max_pkt_size;\n\n    /**\n     * QoS traffic type to be set on this transport. When application wants\n     * to apply QoS tagging to the transport, it's preferable to set this\n     * field rather than \\a qos_param fields since this is more portable.\n     *\n     * Default value is PJ_QOS_TYPE_BEST_EFFORT.\n     */\n    pj_qos_type qos_type;\n\n    /**\n     * Set the low level QoS parameters to the transport. This is a lower\n     * level operation than setting the \\a qos_type field and may not be\n     * supported on all platforms.\n     *\n     * By default all settings in this structure are not set.\n     */\n    pj_qos_params qos_params;\n\n    /**\n     * Specify if STUN socket should ignore any errors when setting the QoS\n     * traffic type/parameters.\n     *\n     * Default: PJ_TRUE\n     */\n    pj_bool_t qos_ignore_error;\n\n    /**\n     * Specify the interface where the socket should be bound to. If the\n     * address is zero, socket will be bound to INADDR_ANY. If the address\n     * is non-zero, socket will be bound to this address only. If the port is\n     * set to zero, the socket will bind at any port (chosen by the OS).\n     */\n    pj_sockaddr bound_addr;\n\n    /**\n     * Specify the port range for TURN socket binding, relative to the start\n     * port number specified in \\a bound_addr. Note that this setting is only\n     * applicable when the start port number is non zero.\n     *\n     * Default value is zero.\n     */\n    pj_uint16_t\tport_range;\n\n    /**\n     * Specify target value for socket receive buffer size. It will be\n     * applied using setsockopt(). When it fails to set the specified size,\n     * it will try with lower value until the highest possible has been\n     * successfully set.\n     *\n     * Default: 0 (OS default)\n     */\n    unsigned so_rcvbuf_size;\n\n    /**\n     * Specify target value for socket send buffer size. It will be\n     * applied using setsockopt(). When it fails to set the specified size,\n     * it will try with lower value until the highest possible has been\n     * successfully set.\n     *\n     * Default: 0 (OS default)\n     */\n    unsigned so_sndbuf_size;\n\n} pj_turn_sock_cfg;\n\n\n/**\n * Initialize pj_turn_sock_cfg structure with default values.\n */\nPJ_DECL(void) pj_turn_sock_cfg_default(pj_turn_sock_cfg *cfg);\n\n\n/**\n * Create a TURN transport instance with the specified address family and\n * connection type. Once TURN transport instance is created, application\n * must call pj_turn_sock_alloc() to allocate a relay address in the TURN\n * server.\n *\n * @param cfg\t\tThe STUN configuration which contains among other\n *\t\t\tthings the ioqueue and timer heap instance for\n *\t\t\tthe operation of this transport.\n * @param af\t\tAddress family of the client connection. Currently\n *\t\t\tpj_AF_INET() and pj_AF_INET6() are supported.\n * @param conn_type\tConnection type to the TURN server. Both TCP and\n *\t\t\tUDP are supported.\n * @param cb\t\tCallback to receive events from the TURN transport.\n * @param setting\tOptional settings to be specified to the transport.\n *\t\t\tIf this parameter is NULL, default values will be\n *\t\t\tused.\n * @param user_data\tArbitrary application data to be associated with\n *\t\t\tthis transport.\n * @param p_turn_sock\tPointer to receive the created instance of the\n *\t\t\tTURN transport.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_sock_create(pj_stun_config *cfg,\n\t\t\t\t\t int af,\n\t\t\t\t\t pj_turn_tp_type conn_type,\n\t\t\t\t\t const pj_turn_sock_cb *cb,\n\t\t\t\t\t const pj_turn_sock_cfg *setting,\n\t\t\t\t\t void *user_data,\n\t\t\t\t\t pj_turn_sock **p_turn_sock);\n\n/**\n * Destroy the TURN transport instance. This will gracefully close the\n * connection between the client and the TURN server. Although this\n * function will return immediately, the TURN socket deletion may continue\n * in the background and the application may still get state changes\n * notifications from this transport.\n *\n * @param turn_sock\tThe TURN transport instance.\n */\nPJ_DECL(void) pj_turn_sock_destroy(pj_turn_sock *turn_sock);\n\n\n/**\n * Associate a user data with this TURN transport. The user data may then\n * be retrieved later with #pj_turn_sock_get_user_data().\n *\n * @param turn_sock\tThe TURN transport instance.\n * @param user_data\tArbitrary data.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_sock_set_user_data(pj_turn_sock *turn_sock,\n\t\t\t\t\t        void *user_data);\n\n/**\n * Retrieve the previously assigned user data associated with this TURN\n * transport.\n *\n * @param turn_sock\tThe TURN transport instance.\n *\n * @return\t\tThe user/application data.\n */\nPJ_DECL(void*) pj_turn_sock_get_user_data(pj_turn_sock *turn_sock);\n\n\n/**\n * Get the group lock for this TURN transport.\n *\n * @param turn_sock\tThe TURN transport instance.\n *\n * @return\t        The group lock.\n */\nPJ_DECL(pj_grp_lock_t *) pj_turn_sock_get_grp_lock(pj_turn_sock *turn_sock);\n\n\n/**\n * Get the TURN transport info. The transport info contains, among other\n * things, the allocated relay address.\n *\n * @param turn_sock\tThe TURN transport instance.\n * @param info\t\tPointer to be filled with TURN transport info.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_sock_get_info(pj_turn_sock *turn_sock,\n\t\t\t\t\t   pj_turn_session_info *info);\n\n/**\n * Acquire the internal mutex of the TURN transport. Application may need\n * to call this function to synchronize access to other objects alongside \n * the TURN transport, to avoid deadlock.\n *\n * @param turn_sock\tThe TURN transport instance.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_sock_lock(pj_turn_sock *turn_sock);\n\n\n/**\n * Release the internal mutex previously held with pj_turn_sock_lock().\n *\n * @param turn_sock\tThe TURN transport instance.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_sock_unlock(pj_turn_sock *turn_sock);\n\n\n/**\n * Set STUN message logging for this TURN session. \n * See #pj_stun_session_set_log().\n *\n * @param turn_sock\tThe TURN transport instance.\n * @param flags\t\tBitmask combination of #pj_stun_sess_msg_log_flag\n */\nPJ_DECL(void) pj_turn_sock_set_log(pj_turn_sock *turn_sock,\n\t\t\t\t   unsigned flags);\n\n/**\n * Configure the SOFTWARE name to be sent in all STUN requests by the\n * TURN session.\n *\n * @param turn_sock\tThe TURN transport instance.\n * @param sw\t    Software name string. If this argument is NULL or\n *\t\t    empty, the session will not include SOFTWARE attribute\n *\t\t    in STUN requests and responses.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pj_turn_sock_set_software_name(pj_turn_sock *turn_sock,\n\t\t\t\t\t\t    const pj_str_t *sw);\n\n\n/**\n * Allocate a relay address/resource in the TURN server. This function\n * will resolve the TURN server using DNS SRV (if desired) and send TURN\n * \\a Allocate request using the specified credential to allocate a relay\n * address in the server. This function completes asynchronously, and\n * application will be notified when the allocation process has been\n * successful in the \\a on_state() callback when the state is set to\n * PJ_TURN_STATE_READY. If the allocation fails, the state will be set\n * to PJ_TURN_STATE_DEALLOCATING or greater.\n *\n * @param turn_sock\tThe TURN transport instance.\n * @param domain\tThe domain, hostname, or IP address of the TURN\n *\t\t\tserver. When this parameter contains domain name,\n *\t\t\tthe \\a resolver parameter must be set to activate\n *\t\t\tDNS SRV resolution.\n * @param default_port\tThe default TURN port number to use when DNS SRV\n *\t\t\tresolution is not used. If DNS SRV resolution is\n *\t\t\tused, the server port number will be set from the\n *\t\t\tDNS SRV records.\n * @param resolver\tIf this parameter is not NULL, then the \\a domain\n *\t\t\tparameter will be first resolved with DNS SRV and\n *\t\t\tthen fallback to using DNS A/AAAA resolution when\n *\t\t\tDNS SRV resolution fails. If this parameter is\n *\t\t\tNULL, the \\a domain parameter will be resolved as\n *\t\t\thostname.\n * @param cred\t\tThe STUN credential to be used for the TURN server.\n * @param param\t\tOptional TURN allocation parameter.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successfully\n *\t\t\tqueued, or the appropriate error code on failure.\n *\t\t\tWhen this function returns PJ_SUCCESS, the final\n *\t\t\tresult of the allocation process will be notified\n *\t\t\tto application in \\a on_state() callback.\n *\t\t\t\n */\nPJ_DECL(pj_status_t) pj_turn_sock_alloc(pj_turn_sock *turn_sock,\n\t\t\t\t        const pj_str_t *domain,\n\t\t\t\t        int default_port,\n\t\t\t\t        pj_dns_resolver *resolver,\n\t\t\t\t        const pj_stun_auth_cred *cred,\n\t\t\t\t        const pj_turn_alloc_param *param);\n\n/**\n * Create or renew permission in the TURN server for the specified peer IP\n * addresses. Application must install permission for a particular (peer)\n * IP address before it sends any data to that IP address, or otherwise\n * the TURN server will drop the data.\n *\n * @param turn_sock\tThe TURN transport instance.\n * @param addr_cnt\tNumber of IP addresses.\n * @param addr\t\tArray of peer IP addresses. Only the address family\n *\t\t\tand IP address portion of the socket address matter.\n * @param options\tSpecify 1 to let the TURN client session automatically\n *\t\t\trenew the permission later when they are about to\n *\t\t\texpire.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successfully\n *\t\t\tissued, or the appropriate error code. Note that\n *\t\t\tthe operation itself will complete asynchronously.\n */\nPJ_DECL(pj_status_t) pj_turn_sock_set_perm(pj_turn_sock *turn_sock,\n\t\t\t\t\t   unsigned addr_cnt,\n\t\t\t\t\t   const pj_sockaddr addr[],\n\t\t\t\t\t   unsigned options);\n\n/**\n * Send a data to the specified peer address via the TURN relay. This \n * function will encapsulate the data as STUN Send Indication or TURN\n * ChannelData packet and send the message to the TURN server. The TURN\n * server then will send the data to the peer.\n *\n * The allocation (pj_turn_sock_alloc()) must have been successfully\n * created before application can relay any data.\n *\n * @param turn_sock\tThe TURN transport instance.\n * @param pkt\t\tThe data/packet to be sent to peer.\n * @param pkt_len\tLength of the data.\n * @param peer_addr\tThe remote peer address (the ultimate destination\n *\t\t\tof the data, and not the TURN server address).\n * @param addr_len\tLength of the address.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */ \nPJ_DECL(pj_status_t) pj_turn_sock_sendto(pj_turn_sock *turn_sock,\n\t\t\t\t\tconst pj_uint8_t *pkt,\n\t\t\t\t\tunsigned pkt_len,\n\t\t\t\t\tconst pj_sockaddr_t *peer_addr,\n\t\t\t\t\tunsigned addr_len);\n\n/**\n * Optionally establish channel binding for the specified a peer address.\n * This function will assign a unique channel number for the peer address\n * and request channel binding to the TURN server for this address. When\n * a channel has been bound to a peer, the TURN transport and TURN server\n * will exchange data using ChannelData encapsulation format, which has\n * lower bandwidth overhead than Send Indication (the default format used\n * when peer address is not bound to a channel).\n *\n * @param turn_sock\tThe TURN transport instance.\n * @param peer\t\tThe remote peer address.\n * @param addr_len\tLength of the address.\n *\n * @return\t\tPJ_SUCCESS if the operation has been successful,\n *\t\t\tor the appropriate error code on failure.\n */\nPJ_DECL(pj_status_t) pj_turn_sock_bind_channel(pj_turn_sock *turn_sock,\n\t\t\t\t\t       const pj_sockaddr_t *peer,\n\t\t\t\t\t       unsigned addr_len);\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJNATH_TURN_SOCK_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath/types.h",
    "content": "/* $Id: types.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJNATH_TYPES_H__\n#define __PJNATH_TYPES_H__\n\n/**\n * @file types.h\n * @brief PJNATH types.\n */\n\n#include <pj/types.h>\n#include <pjnath/config.h>\n\n/**\n * @defgroup PJNATH NAT Traversal Helper Library\n * @{\n */\n\nPJ_BEGIN_DECL\n\n/**\n * This constant describes a number to be used to identify an invalid TURN\n * channel number.\n */\n#define PJ_TURN_INVALID_CHANNEL\t    0xFFFF\n\n\n/**\n * Initialize pjnath library.\n *\n * @return\t    Initialization status.\n */\nPJ_DECL(pj_status_t) pjnath_init(void);\n\n\n/**\n * Display error to the log. \n *\n * @param sender    The sender name.\n * @param title\t    Title message.\n * @param status    The error status.\n */\n#if PJNATH_ERROR_LEVEL <= PJ_LOG_MAX_LEVEL\nPJ_DECL(void) pjnath_perror(const char *sender, const char *title,\n\t\t\t    pj_status_t status);\n#else\n# define pjnath_perror(sender, title, status)\n#endif\n\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJNATH_TYPES_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/include/pjnath.h",
    "content": "/* $Id: pjnath.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#ifndef __PJNATH_H__\n#define __PJNATH_H__\n\n/**\n * @file pjnath.h\n * @brief PJNATH main header file.\n */\n#include <pjnath/config.h>\n#include <pjnath/errno.h>\n#include <pjnath/ice_session.h>\n#include <pjnath/ice_strans.h>\n#include <pjnath/nat_detect.h>\n#include <pjnath/stun_auth.h>\n#include <pjnath/stun_config.h>\n#include <pjnath/stun_msg.h>\n#include <pjnath/stun_session.h>\n#include <pjnath/stun_sock.h>\n#include <pjnath/stun_transaction.h>\n#include <pjnath/turn_session.h>\n#include <pjnath/turn_sock.h>\n#include <pjnath/types.h>\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjnath/errno.c",
    "content": "/* $Id: errno.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjnath/errno.h>\n#include <pjnath/stun_msg.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/string.h>\n\n\n\n/* PJNATH's own error codes/messages \n * MUST KEEP THIS ARRAY SORTED!!\n * Message must be limited to 64 chars!\n */\n#if defined(PJ_HAS_ERROR_STRING) && PJ_HAS_ERROR_STRING!=0\nstatic const struct \n{\n    int code;\n    const char *msg;\n} err_str[] = \n{\n    /* STUN related error codes */\n    PJ_BUILD_ERR( PJNATH_EINSTUNMSG,\t    \"Invalid STUN message\"),\n    PJ_BUILD_ERR( PJNATH_EINSTUNMSGLEN,\t    \"Invalid STUN message length\"),\n    PJ_BUILD_ERR( PJNATH_EINSTUNMSGTYPE,    \"Invalid or unexpected STUN message type\"),\n    PJ_BUILD_ERR( PJNATH_ESTUNTIMEDOUT,\t    \"STUN transaction has timed out\"),\n\n    PJ_BUILD_ERR( PJNATH_ESTUNTOOMANYATTR,  \"Too many STUN attributes\"),\n    PJ_BUILD_ERR( PJNATH_ESTUNINATTRLEN,    \"Invalid STUN attribute length\"),\n    PJ_BUILD_ERR( PJNATH_ESTUNDUPATTR,\t    \"Found duplicate STUN attribute\"),\n\n    PJ_BUILD_ERR( PJNATH_ESTUNFINGERPRINT,  \"STUN FINGERPRINT verification failed\"),\n    PJ_BUILD_ERR( PJNATH_ESTUNMSGINTPOS,    \"Invalid STUN attribute after MESSAGE-INTEGRITY\"),\n    PJ_BUILD_ERR( PJNATH_ESTUNFINGERPOS,    \"Invalid STUN attribute after FINGERPRINT\"),\n\n    PJ_BUILD_ERR( PJNATH_ESTUNNOMAPPEDADDR, \"STUN (XOR-)MAPPED-ADDRESS attribute not found\"),\n    PJ_BUILD_ERR( PJNATH_ESTUNIPV6NOTSUPP,  \"STUN IPv6 attribute not supported\"),\n    PJ_BUILD_ERR( PJNATH_EINVAF,\t    \"Invalid STUN address family value\"),\n    PJ_BUILD_ERR( PJNATH_ESTUNINSERVER,\t    \"Invalid STUN server or server not configured\"),\n\n    PJ_BUILD_ERR( PJNATH_ESTUNDESTROYED,    \"STUN object has been destoyed\"),\n\n    /* ICE related errors */\n    PJ_BUILD_ERR( PJNATH_ENOICE,\t    \"ICE session not available\"),\n    PJ_BUILD_ERR( PJNATH_EICEINPROGRESS,    \"ICE check is in progress\"),\n    PJ_BUILD_ERR( PJNATH_EICEFAILED,\t    \"All ICE checklists failed\"),\n    PJ_BUILD_ERR( PJNATH_EICEMISMATCH,\t    \"Default target doesn't match any ICE candidates\"),\n    PJ_BUILD_ERR( PJNATH_EICEINCOMPID,\t    \"Invalid ICE component ID\"),\n    PJ_BUILD_ERR( PJNATH_EICEINCANDID,\t    \"Invalid ICE candidate ID\"),\n    PJ_BUILD_ERR( PJNATH_EICEINSRCADDR,\t    \"Source address mismatch\"),\n    PJ_BUILD_ERR( PJNATH_EICEMISSINGSDP,    \"Missing ICE SDP attribute\"),\n    PJ_BUILD_ERR( PJNATH_EICEINCANDSDP,\t    \"Invalid SDP \\\"candidate\\\" attribute\"),\n    PJ_BUILD_ERR( PJNATH_EICENOHOSTCAND,    \"No host candidate associated with srflx\"),\n    PJ_BUILD_ERR( PJNATH_EICENOMTIMEOUT,    \"Controlled agent timed out waiting for nomination\"),\n\n    /* TURN related errors */\n    PJ_BUILD_ERR( PJNATH_ETURNINTP,\t    \"Invalid/unsupported transport\"),\n\n};\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n\n/*\n * pjnath_strerror()\n */\nstatic pj_str_t pjnath_strerror(pj_status_t statcode, \n\t\t\t\tchar *buf, pj_size_t bufsize )\n{\n    pj_str_t errstr;\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n\n    if (statcode >= PJNATH_ERRNO_START && \n\tstatcode < PJNATH_ERRNO_START + PJ_ERRNO_SPACE_SIZE)\n    {\n\t/* Find the error in the table.\n\t * Use binary search!\n\t */\n\tint first = 0;\n\tint n = PJ_ARRAY_SIZE(err_str);\n\n\twhile (n > 0) {\n\t    int half = n/2;\n\t    int mid = first + half;\n\n\t    if (err_str[mid].code < statcode) {\n\t\tfirst = mid+1;\n\t\tn -= (half+1);\n\t    } else if (err_str[mid].code > statcode) {\n\t\tn = half;\n\t    } else {\n\t\tfirst = mid;\n\t\tbreak;\n\t    }\n\t}\n\n\n\tif (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {\n\t    pj_str_t msg;\n\t    \n\t    msg.ptr = (char*)err_str[first].msg;\n\t    msg.slen = pj_ansi_strlen(err_str[first].msg);\n\n\t    errstr.ptr = buf;\n\t    pj_strncpy_with_null(&errstr, &msg, bufsize);\n\t    return errstr;\n\n\t} \n    }\n\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n\n    /* Error not found. */\n    errstr.ptr = buf;\n    errstr.slen = pj_ansi_snprintf(buf, bufsize, \n\t\t\t\t   \"Unknown pjnath error %d\",\n\t\t\t\t   statcode);\n    if (errstr.slen < 1 || errstr.slen >= (int)bufsize)\n\terrstr.slen = bufsize-1;\n\n    return errstr;\n}\n\n\nstatic pj_str_t pjnath_strerror2(pj_status_t statcode, \n\t\t\t\t char *buf, pj_size_t bufsize )\n{\n    int stun_code = statcode - PJ_STATUS_FROM_STUN_CODE(0);\n    const pj_str_t cmsg = pj_stun_get_err_reason(stun_code);\n    pj_str_t errstr;\n\n    buf[bufsize-1] = '\\0';\n\n    if (cmsg.slen == 0) {\n\t/* Not found */\n\terrstr.ptr = buf;\n\terrstr.slen = pj_ansi_snprintf(buf, bufsize, \n\t\t\t\t       \"Unknown STUN err-code %d\",\n\t\t\t\t       stun_code);\n    } else {\n\terrstr.ptr = buf;\n\tpj_strncpy(&errstr, &cmsg, bufsize);\n\tif (errstr.slen < (int)bufsize)\n\t    buf[errstr.slen] = '\\0';\n\telse\n\t    buf[bufsize-1] = '\\0';\n    }\n\n    if (errstr.slen < 1 || errstr.slen >= (int)bufsize)\n\terrstr.slen = bufsize-1;\n\n    return errstr;\n}\n\n\nPJ_DEF(pj_status_t) pjnath_init(void)\n{\n    pj_status_t status;\n\n    status = pj_register_strerror(PJNATH_ERRNO_START, 299, \n\t\t\t\t  &pjnath_strerror);\n    pj_assert(status == PJ_SUCCESS);\n\n    status = pj_register_strerror(PJ_STATUS_FROM_STUN_CODE(300), \n\t\t\t\t  699 - 300, \n\t\t\t\t  &pjnath_strerror2);\n    pj_assert(status == PJ_SUCCESS);\n\n    return PJ_SUCCESS;\n}\n\n\n#if PJNATH_ERROR_LEVEL <= PJ_LOG_MAX_LEVEL\n\nPJ_DEF(void) pjnath_perror(const char *sender, const char *title,\n\t\t\t   pj_status_t status)\n{\n    char errmsg[PJ_ERR_MSG_SIZE];\n\n    pj_strerror(status, errmsg, sizeof(errmsg));\n\n#if PJNATH_ERROR_LEVEL==1\n    PJ_LOG(1,(sender, \"%s: %s\", title, errmsg));\n#elif PJNATH_ERROR_LEVEL==2\n    PJ_LOG(2,(sender, \"%s: %s\", title, errmsg));\n#elif PJNATH_ERROR_LEVEL==3\n    PJ_LOG(3,(sender, \"%s: %s\", title, errmsg));\n#elif PJNATH_ERROR_LEVEL==4\n    PJ_LOG(4,(sender, \"%s: %s\", title, errmsg));\n#elif PJNATH_ERROR_LEVEL==5\n    PJ_LOG(5,(sender, \"%s: %s\", title, errmsg));\n#else\n# error Invalid PJNATH_ERROR_LEVEL value\n#endif\n}\n\n#endif\t/* PJNATH_ERROR_LEVEL <= PJ_LOG_MAX_LEVEL */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjnath/ice_session.c",
    "content": "/* $Id: ice_session.c 4365 2013-02-21 18:06:51Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjnath/ice_session.h>\n#include <pj/addr_resolv.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/guid.h>\n#include <pj/hash.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n\n/* String names for candidate types */\nstatic const char *cand_type_names[] =\n{\n    \"host\",\n    \"srflx\",\n    \"prflx\",\n    \"relay\"\n\n};\n\n/* String names for pj_ice_sess_check_state */\n#if PJ_LOG_MAX_LEVEL >= 4\nstatic const char *check_state_name[] = \n{\n    \"Frozen\",\n    \"Waiting\",\n    \"In Progress\",\n    \"Succeeded\",\n    \"Failed\"\n};\n\nstatic const char *clist_state_name[] =\n{\n    \"Idle\",\n    \"Running\",\n    \"Completed\"\n};\n#endif\t/* PJ_LOG_MAX_LEVEL >= 4 */\n\nstatic const char *role_names[] = \n{\n    \"Unknown\",\n    \"Controlled\",\n    \"Controlling\"\n};\n\nenum timer_type\n{\n    TIMER_NONE,\t\t\t/**< Timer not active\t\t\t*/\n    TIMER_COMPLETION_CALLBACK,\t/**< Call on_ice_complete() callback    */\n    TIMER_CONTROLLED_WAIT_NOM,\t/**< Controlled agent is waiting for \n\t\t\t\t     controlling agent to send connectivity\n\t\t\t\t     check with nominated flag after it has\n\t\t\t\t     valid check for every components.\t*/\n    TIMER_START_NOMINATED_CHECK,/**< Controlling agent start connectivity\n\t\t\t\t     checks with USE-CANDIDATE flag.\t*/\n    TIMER_KEEP_ALIVE\t\t/**< ICE keep-alive timer.\t\t*/\n\n};\n\n/* Candidate type preference */\nstatic pj_uint8_t cand_type_prefs[PJ_ICE_CAND_TYPE_MAX] =\n{\n#if PJ_ICE_CAND_TYPE_PREF_BITS < 8\n    /* Keep it to 2 bits */\n    3,\t    /**< PJ_ICE_HOST_PREF\t*/\n    1,\t    /**< PJ_ICE_SRFLX_PREF.\t*/\n    2,\t    /**< PJ_ICE_PRFLX_PREF\t*/\n    0\t    /**< PJ_ICE_RELAYED_PREF\t*/\n#else\n    /* Default ICE session preferences, according to draft-ice */\n    126,    /**< PJ_ICE_HOST_PREF\t*/\n    100,    /**< PJ_ICE_SRFLX_PREF.\t*/\n    110,    /**< PJ_ICE_PRFLX_PREF\t*/\n    0\t    /**< PJ_ICE_RELAYED_PREF\t*/\n#endif\n};\n\n#define THIS_FILE\t\t\"ice_session.c\"\n#define CHECK_NAME_LEN\t\t128\n#define LOG4(expr)\t\tPJ_LOG(4,expr)\n#define LOG5(expr)\t\tPJ_LOG(4,expr)\n#define GET_LCAND_ID(cand)\t(unsigned)(cand - ice->lcand)\n#define GET_CHECK_ID(cl, chk)\t(chk - (cl)->checks)\n\n\n/* The data that will be attached to the STUN session on each\n * component.\n */\ntypedef struct stun_data\n{\n    pj_ice_sess\t\t*ice;\n    unsigned\t\t comp_id;\n    pj_ice_sess_comp\t*comp;\n} stun_data;\n\n\n/* The data that will be attached to the timer to perform\n * periodic check.\n */\ntypedef struct timer_data\n{\n    pj_ice_sess\t\t    *ice;\n    pj_ice_sess_checklist   *clist;\n} timer_data;\n\n\n/* This is the data that will be attached as token to outgoing\n * STUN messages.\n */\n\n\n/* Forward declarations */\nstatic void on_timer(pj_timer_heap_t *th, pj_timer_entry *te);\nstatic void on_ice_complete(pj_ice_sess *ice, pj_status_t status);\nstatic void ice_keep_alive(pj_ice_sess *ice, pj_bool_t send_now);\nstatic void ice_on_destroy(void *obj);\nstatic void destroy_ice(pj_ice_sess *ice,\n\t\t\tpj_status_t reason);\nstatic pj_status_t start_periodic_check(pj_timer_heap_t *th, \n\t\t\t\t\tpj_timer_entry *te);\nstatic void start_nominated_check(pj_ice_sess *ice);\nstatic void periodic_timer(pj_timer_heap_t *th, \n\t\t\t  pj_timer_entry *te);\nstatic void handle_incoming_check(pj_ice_sess *ice,\n\t\t\t\t  const pj_ice_rx_check *rcheck);\n\n/* These are the callbacks registered to the STUN sessions */\nstatic pj_status_t on_stun_send_msg(pj_stun_session *sess,\n\t\t\t\t    void *token,\n\t\t\t\t    const void *pkt,\n\t\t\t\t    pj_size_t pkt_size,\n\t\t\t\t    const pj_sockaddr_t *dst_addr,\n\t\t\t\t    unsigned addr_len);\nstatic pj_status_t on_stun_rx_request(pj_stun_session *sess,\n\t\t\t\t      const pj_uint8_t *pkt,\n\t\t\t\t      unsigned pkt_len,\n\t\t\t\t      const pj_stun_rx_data *rdata,\n\t\t\t\t      void *token,\n\t\t\t\t      const pj_sockaddr_t *src_addr,\n\t\t\t\t      unsigned src_addr_len);\nstatic void on_stun_request_complete(pj_stun_session *stun_sess,\n\t\t\t\t     pj_status_t status,\n\t\t\t\t     void *token,\n\t\t\t\t     pj_stun_tx_data *tdata,\n\t\t\t\t     const pj_stun_msg *response,\n\t\t\t\t     const pj_sockaddr_t *src_addr,\n\t\t\t\t     unsigned src_addr_len);\nstatic pj_status_t on_stun_rx_indication(pj_stun_session *sess,\n\t\t\t\t\t const pj_uint8_t *pkt,\n\t\t\t\t\t unsigned pkt_len,\n\t\t\t\t\t const pj_stun_msg *msg,\n\t\t\t\t\t void *token,\n\t\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t\t unsigned src_addr_len);\n\n/* These are the callbacks for performing STUN authentication */\nstatic pj_status_t stun_auth_get_auth(void *user_data,\n\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t      pj_str_t *realm,\n\t\t\t\t      pj_str_t *nonce);\nstatic pj_status_t stun_auth_get_cred(const pj_stun_msg *msg,\n\t\t\t\t      void *user_data,\n\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t      pj_str_t *realm,\n\t\t\t\t      pj_str_t *username,\n\t\t\t\t      pj_str_t *nonce,\n\t\t\t\t      pj_stun_passwd_type *data_type,\n\t\t\t\t      pj_str_t *data);\nstatic pj_status_t stun_auth_get_password(const pj_stun_msg *msg,\n\t\t\t\t\t  void *user_data, \n\t\t\t\t\t  const pj_str_t *realm,\n\t\t\t\t\t  const pj_str_t *username,\n\t\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t\t  pj_stun_passwd_type *data_type,\n\t\t\t\t\t  pj_str_t *data);\n\n\nPJ_DEF(const char*) pj_ice_get_cand_type_name(pj_ice_cand_type type)\n{\n    PJ_ASSERT_RETURN(type <= PJ_ICE_CAND_TYPE_RELAYED, \"???\");\n    return cand_type_names[type];\n}\n\n\nPJ_DEF(const char*) pj_ice_sess_role_name(pj_ice_sess_role role)\n{\n    switch (role) {\n    case PJ_ICE_SESS_ROLE_UNKNOWN:\n\treturn \"Unknown\";\n    case PJ_ICE_SESS_ROLE_CONTROLLED:\n\treturn \"Controlled\";\n    case PJ_ICE_SESS_ROLE_CONTROLLING:\n\treturn \"Controlling\";\n    default:\n\treturn \"??\";\n    }\n}\n\n\n/* Get the prefix for the foundation */\nstatic int get_type_prefix(pj_ice_cand_type type)\n{\n    switch (type) {\n    case PJ_ICE_CAND_TYPE_HOST:\t    return 'H';\n    case PJ_ICE_CAND_TYPE_SRFLX:    return 'S';\n    case PJ_ICE_CAND_TYPE_PRFLX:    return 'P';\n    case PJ_ICE_CAND_TYPE_RELAYED:  return 'R';\n    default:\n\tpj_assert(!\"Invalid type\");\n\treturn 'U';\n    }\n}\n\n/* Calculate foundation:\n * Two candidates have the same foundation when they are \"similar\" - of\n * the same type and obtained from the same host candidate and STUN\n * server using the same protocol.  Otherwise, their foundation is\n * different.\n */\nPJ_DEF(void) pj_ice_calc_foundation(pj_pool_t *pool,\n\t\t\t\t    pj_str_t *foundation,\n\t\t\t\t    pj_ice_cand_type type,\n\t\t\t\t    const pj_sockaddr *base_addr)\n{\n#if PJNATH_ICE_PRIO_STD\n    char buf[64];\n    pj_uint32_t val;\n\n    if (base_addr->addr.sa_family == pj_AF_INET()) {\n\tval = pj_ntohl(base_addr->ipv4.sin_addr.s_addr);\n    } else {\n\tval = pj_hash_calc(0, pj_sockaddr_get_addr(base_addr),\n\t\t\t   pj_sockaddr_get_addr_len(base_addr));\n    }\n    pj_ansi_snprintf(buf, sizeof(buf), \"%c%x\",\n\t\t     get_type_prefix(type), val);\n    pj_strdup2(pool, foundation, buf);\n#else\n    /* Much shorter version, valid for candidates added by\n     * pj_ice_strans.\n     */\n    foundation->ptr = (char*) pj_pool_alloc(pool, 1);\n    *foundation->ptr = (char)get_type_prefix(type);\n    foundation->slen = 1;\n\n    PJ_UNUSED_ARG(base_addr);\n#endif\n}\n\n\n/* Init component */\nstatic pj_status_t init_comp(pj_ice_sess *ice,\n\t\t\t     unsigned comp_id,\n\t\t\t     pj_ice_sess_comp *comp)\n{\n    pj_stun_session_cb sess_cb;\n    pj_stun_auth_cred auth_cred;\n    stun_data *sd;\n    pj_status_t status;\n\n    /* Init STUN callbacks */\n    pj_bzero(&sess_cb, sizeof(sess_cb));\n    sess_cb.on_request_complete = &on_stun_request_complete;\n    sess_cb.on_rx_indication = &on_stun_rx_indication;\n    sess_cb.on_rx_request = &on_stun_rx_request;\n    sess_cb.on_send_msg = &on_stun_send_msg;\n\n    /* Create STUN session for this candidate */\n    status = pj_stun_session_create(&ice->stun_cfg, NULL, \n\t\t\t            &sess_cb, PJ_TRUE,\n\t\t\t            ice->grp_lock,\n\t\t\t\t    &comp->stun_sess);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Associate data with this STUN session */\n    sd = PJ_POOL_ZALLOC_T(ice->pool, struct stun_data);\n    sd->ice = ice;\n    sd->comp_id = comp_id;\n    sd->comp = comp;\n    pj_stun_session_set_user_data(comp->stun_sess, sd);\n\n    /* Init STUN authentication credential */\n    pj_bzero(&auth_cred, sizeof(auth_cred));\n    auth_cred.type = PJ_STUN_AUTH_CRED_DYNAMIC;\n    auth_cred.data.dyn_cred.get_auth = &stun_auth_get_auth;\n    auth_cred.data.dyn_cred.get_cred = &stun_auth_get_cred;\n    auth_cred.data.dyn_cred.get_password = &stun_auth_get_password;\n    auth_cred.data.dyn_cred.user_data = comp->stun_sess;\n    pj_stun_session_set_credential(comp->stun_sess, PJ_STUN_AUTH_SHORT_TERM,\n\t\t\t\t   &auth_cred);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Init options with default values */\nPJ_DEF(void) pj_ice_sess_options_default(pj_ice_sess_options *opt)\n{\n    opt->aggressive = PJ_TRUE;\n    opt->nominated_check_delay = PJ_ICE_NOMINATED_CHECK_DELAY;\n    opt->controlled_agent_want_nom_timeout = \n\tICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT;\n}\n\n/*\n * Create ICE session.\n */\nPJ_DEF(pj_status_t) pj_ice_sess_create(pj_stun_config *stun_cfg,\n\t\t\t\t       const char *name,\n\t\t\t\t       pj_ice_sess_role role,\n\t\t\t\t       unsigned comp_cnt,\n\t\t\t\t       const pj_ice_sess_cb *cb,\n\t\t\t\t       const pj_str_t *local_ufrag,\n\t\t\t\t       const pj_str_t *local_passwd,\n\t\t\t\t       pj_grp_lock_t *grp_lock,\n\t\t\t\t       pj_ice_sess **p_ice)\n{\n    pj_pool_t *pool;\n    pj_ice_sess *ice;\n    unsigned i;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(stun_cfg && cb && p_ice, PJ_EINVAL);\n\n    if (name == NULL)\n\tname = \"icess%p\";\n\n    pool = pj_pool_create(stun_cfg->pf, name, PJNATH_POOL_LEN_ICE_SESS, \n\t\t\t  PJNATH_POOL_INC_ICE_SESS, NULL);\n    ice = PJ_POOL_ZALLOC_T(pool, pj_ice_sess);\n    ice->pool = pool;\n    ice->role = role;\n    ice->tie_breaker.u32.hi = pj_rand();\n    ice->tie_breaker.u32.lo = pj_rand();\n    ice->prefs = cand_type_prefs;\n    pj_ice_sess_options_default(&ice->opt);\n\n    pj_timer_entry_init(&ice->timer, TIMER_NONE, (void*)ice, &on_timer);\n\n    pj_ansi_snprintf(ice->obj_name, sizeof(ice->obj_name),\n\t\t     name, ice);\n\n    if (grp_lock) {\n\tice->grp_lock = grp_lock;\n    } else {\n\tstatus = pj_grp_lock_create(pool, NULL, &ice->grp_lock);\n\tif (status != PJ_SUCCESS) {\n\t    pj_pool_release(pool);\n\t    return status;\n\t}\n    }\n\n    pj_grp_lock_add_ref(ice->grp_lock);\n    pj_grp_lock_add_handler(ice->grp_lock, pool, ice,\n                            &ice_on_destroy);\n\n    pj_memcpy(&ice->cb, cb, sizeof(*cb));\n    pj_memcpy(&ice->stun_cfg, stun_cfg, sizeof(*stun_cfg));\n\n    ice->comp_cnt = comp_cnt;\n    for (i=0; i<comp_cnt; ++i) {\n\tpj_ice_sess_comp *comp;\n\tcomp = &ice->comp[i];\n\tcomp->valid_check = NULL;\n\tcomp->nominated_check = NULL;\n\n\tstatus = init_comp(ice, i+1, comp);\n\tif (status != PJ_SUCCESS) {\n\t    destroy_ice(ice, status);\n\t    return status;\n\t}\n    }\n\n    /* Initialize transport datas */\n    for (i=0; i<PJ_ARRAY_SIZE(ice->tp_data); ++i) {\n\tice->tp_data[i].transport_id = i;\n\tice->tp_data[i].has_req_data = PJ_FALSE;\n    }\n\n    if (local_ufrag == NULL) {\n\tice->rx_ufrag.ptr = (char*) pj_pool_alloc(ice->pool, PJ_ICE_UFRAG_LEN);\n\tpj_create_random_string(ice->rx_ufrag.ptr, PJ_ICE_UFRAG_LEN);\n\tice->rx_ufrag.slen = PJ_ICE_UFRAG_LEN;\n    } else {\n\tpj_strdup(ice->pool, &ice->rx_ufrag, local_ufrag);\n    }\n\n    if (local_passwd == NULL) {\n\tice->rx_pass.ptr = (char*) pj_pool_alloc(ice->pool, PJ_ICE_UFRAG_LEN);\n\tpj_create_random_string(ice->rx_pass.ptr, PJ_ICE_UFRAG_LEN);\n\tice->rx_pass.slen = PJ_ICE_UFRAG_LEN;\n    } else {\n\tpj_strdup(ice->pool, &ice->rx_pass, local_passwd);\n    }\n\n    pj_list_init(&ice->early_check);\n\n    /* Done */\n    *p_ice = ice;\n\n    LOG4((ice->obj_name, \n\t \"ICE session created, comp_cnt=%d, role is %s agent\",\n\t comp_cnt, role_names[ice->role]));\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the value of various options of the ICE session.\n */\nPJ_DEF(pj_status_t) pj_ice_sess_get_options(pj_ice_sess *ice,\n\t\t\t\t\t    pj_ice_sess_options *opt)\n{\n    PJ_ASSERT_RETURN(ice, PJ_EINVAL);\n    pj_memcpy(opt, &ice->opt, sizeof(*opt));\n    return PJ_SUCCESS;\n}\n\n/*\n * Specify various options for this ICE session.\n */\nPJ_DEF(pj_status_t) pj_ice_sess_set_options(pj_ice_sess *ice,\n\t\t\t\t\t    const pj_ice_sess_options *opt)\n{\n    PJ_ASSERT_RETURN(ice && opt, PJ_EINVAL);\n    pj_memcpy(&ice->opt, opt, sizeof(*opt));\n    LOG5((ice->obj_name, \"ICE nomination type set to %s\",\n\t  (ice->opt.aggressive ? \"aggressive\" : \"regular\")));\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Callback to really destroy the session\n */\nstatic void ice_on_destroy(void *obj)\n{\n    pj_ice_sess *ice = (pj_ice_sess*) obj;\n\n    if (ice->pool) {\n\tpj_pool_t *pool = ice->pool;\n\tice->pool = NULL;\n\tpj_pool_release(pool);\n    }\n    LOG4((THIS_FILE, \"ICE session %p destroyed\", ice));\n}\n\n/*\n * Destroy\n */\nstatic void destroy_ice(pj_ice_sess *ice,\n\t\t\tpj_status_t reason)\n{\n    unsigned i;\n\n    if (reason == PJ_SUCCESS) {\n\tLOG4((ice->obj_name, \"Destroying ICE session %p\", ice));\n    }\n\n    pj_grp_lock_acquire(ice->grp_lock);\n\n    if (ice->is_destroying) {\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn;\n    }\n\n    ice->is_destroying = PJ_TRUE;\n\n    pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap,\n                                   &ice->timer, PJ_FALSE);\n\n    for (i=0; i<ice->comp_cnt; ++i) {\n\tif (ice->comp[i].stun_sess) {\n\t    pj_stun_session_destroy(ice->comp[i].stun_sess);\n\t    ice->comp[i].stun_sess = NULL;\n\t}\n    }\n\n    pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap,\n                                   &ice->clist.timer,\n                                   PJ_FALSE);\n\n    pj_grp_lock_dec_ref(ice->grp_lock);\n    pj_grp_lock_release(ice->grp_lock);\n}\n\n\n/*\n * Destroy\n */\nPJ_DEF(pj_status_t) pj_ice_sess_destroy(pj_ice_sess *ice)\n{\n    PJ_ASSERT_RETURN(ice, PJ_EINVAL);\n    destroy_ice(ice, PJ_SUCCESS);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Change session role. \n */\nPJ_DEF(pj_status_t) pj_ice_sess_change_role(pj_ice_sess *ice,\n\t\t\t\t\t    pj_ice_sess_role new_role)\n{\n    PJ_ASSERT_RETURN(ice, PJ_EINVAL);\n\n    if (new_role != ice->role) {\n\tice->role = new_role;\n\tLOG4((ice->obj_name, \"Role changed to %s\", role_names[new_role]));\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Change type preference\n */\nPJ_DEF(pj_status_t) pj_ice_sess_set_prefs(pj_ice_sess *ice,\n\t\t\t\t\t  const pj_uint8_t prefs[4])\n{\n    unsigned i;\n    PJ_ASSERT_RETURN(ice && prefs, PJ_EINVAL);\n    ice->prefs = (pj_uint8_t*) pj_pool_calloc(ice->pool, PJ_ICE_CAND_TYPE_MAX,\n\t\t\t\t\t      sizeof(pj_uint8_t));\n    for (i=0; i<PJ_ICE_CAND_TYPE_MAX; ++i) {\n#if PJ_ICE_CAND_TYPE_PREF_BITS < 8\n\tpj_assert(prefs[i] < (2 << PJ_ICE_CAND_TYPE_PREF_BITS));\n#endif\n\tice->prefs[i] = prefs[i];\n    }\n    return PJ_SUCCESS;\n}\n\n\n/* Find component by ID */\nstatic pj_ice_sess_comp *find_comp(const pj_ice_sess *ice, unsigned comp_id)\n{\n    /* Ticket #1844: possible wrong assertion when remote has less ICE comp */\n    //pj_assert(comp_id > 0 && comp_id <= ice->comp_cnt);\n    if (comp_id > ice->comp_cnt)\n\treturn NULL;\n\n    return (pj_ice_sess_comp*) &ice->comp[comp_id-1];\n}\n\n\n/* Callback by STUN authentication when it needs to send 401 */\nstatic pj_status_t stun_auth_get_auth(void *user_data,\n\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t      pj_str_t *realm,\n\t\t\t\t      pj_str_t *nonce)\n{\n    PJ_UNUSED_ARG(user_data);\n    PJ_UNUSED_ARG(pool);\n\n    realm->slen = 0;\n    nonce->slen = 0;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Get credential to be sent with outgoing message */\nstatic pj_status_t stun_auth_get_cred(const pj_stun_msg *msg,\n\t\t\t\t      void *user_data,\n\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t      pj_str_t *realm,\n\t\t\t\t      pj_str_t *username,\n\t\t\t\t      pj_str_t *nonce,\n\t\t\t\t      pj_stun_passwd_type *data_type,\n\t\t\t\t      pj_str_t *data)\n{\n    pj_stun_session *sess = (pj_stun_session *)user_data;\n    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess);\n    pj_ice_sess *ice = sd->ice;\n\n    PJ_UNUSED_ARG(pool);\n    realm->slen = nonce->slen = 0;\n\n    if (PJ_STUN_IS_RESPONSE(msg->hdr.type)) {\n\t/* Outgoing responses need to have the same credential as\n\t * incoming requests.\n\t */\n\t*username = ice->rx_uname;\n\t*data_type = PJ_STUN_PASSWD_PLAIN;\n\t*data = ice->rx_pass;\n    }\n    else {\n\t*username = ice->tx_uname;\n\t*data_type = PJ_STUN_PASSWD_PLAIN;\n\t*data = ice->tx_pass;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* Get password to be used to authenticate incoming message */\nstatic pj_status_t stun_auth_get_password(const pj_stun_msg *msg,\n\t\t\t\t\t  void *user_data, \n\t\t\t\t\t  const pj_str_t *realm,\n\t\t\t\t\t  const pj_str_t *username,\n\t\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t\t  pj_stun_passwd_type *data_type,\n\t\t\t\t\t  pj_str_t *data)\n{\n    pj_stun_session *sess = (pj_stun_session *)user_data;\n    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess);\n    pj_ice_sess *ice = sd->ice;\n\n    PJ_UNUSED_ARG(realm);\n    PJ_UNUSED_ARG(pool);\n\n    if (PJ_STUN_IS_SUCCESS_RESPONSE(msg->hdr.type) ||\n\tPJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type))\n    {\n\t/* Incoming response is authenticated with TX credential */\n\t/* Verify username */\n\tif (pj_strcmp(username, &ice->tx_uname) != 0)\n\t    return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNAUTHORIZED);\n\t*data_type = PJ_STUN_PASSWD_PLAIN;\n\t*data = ice->tx_pass;\n\n    } else {\n\t/* Incoming request is authenticated with RX credential */\n\t/* The agent MUST accept a credential if the username consists\n\t * of two values separated by a colon, where the first value is\n\t * equal to the username fragment generated by the agent in an offer\n\t * or answer for a session in-progress, and the MESSAGE-INTEGRITY \n\t * is the output of a hash of the password and the STUN packet's \n\t * contents.\n\t */\n\tconst char *pos;\n\tpj_str_t ufrag;\n\n\tpos = (const char*)pj_memchr(username->ptr, ':', username->slen);\n\tif (pos == NULL)\n\t    return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNAUTHORIZED);\n\n\tufrag.ptr = (char*)username->ptr;\n\tufrag.slen = (pos - username->ptr);\n\n\tif (pj_strcmp(&ufrag, &ice->rx_ufrag) != 0)\n\t    return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNAUTHORIZED);\n\n\t*data_type = PJ_STUN_PASSWD_PLAIN;\n\t*data = ice->rx_pass;\n\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_uint32_t CALC_CAND_PRIO(pj_ice_sess *ice,\n\t\t\t\t  pj_ice_cand_type type,\n\t\t\t\t  pj_uint32_t local_pref,\n\t\t\t\t  pj_uint32_t comp_id)\n{\n#if PJNATH_ICE_PRIO_STD\n    return ((ice->prefs[type] & 0xFF) << 24) + \n\t   ((local_pref & 0xFFFF)    << 8) +\n\t   (((256 - comp_id) & 0xFF) << 0);\n#else\n    enum {\n\ttype_mask   = ((2 << PJ_ICE_CAND_TYPE_PREF_BITS) - 1),\n\tlocal_mask  = ((2 << PJ_ICE_LOCAL_PREF_BITS) - 1),\n\tcomp_mask   = ((2 << PJ_ICE_COMP_BITS) - 1),\n\n\tcomp_shift  = 0,\n\tlocal_shift = (PJ_ICE_COMP_BITS),\n\ttype_shift  = (comp_shift + local_shift),\n\n\tmax_comp    = (2<<PJ_ICE_COMP_BITS),\n    };\n\n    return ((ice->prefs[type] & type_mask) << type_shift) + \n\t   ((local_pref & local_mask) << local_shift) +\n\t   (((max_comp - comp_id) & comp_mask) << comp_shift);\n#endif\n}\n\n\n/*\n * Add ICE candidate\n */\nPJ_DEF(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice,\n\t\t\t\t\t unsigned comp_id,\n\t\t\t\t\t unsigned transport_id,\n\t\t\t\t\t pj_ice_cand_type type,\n\t\t\t\t\t pj_uint16_t local_pref,\n\t\t\t\t\t const pj_str_t *foundation,\n\t\t\t\t\t const pj_sockaddr_t *addr,\n\t\t\t\t\t const pj_sockaddr_t *base_addr,\n\t\t\t\t\t const pj_sockaddr_t *rel_addr,\n\t\t\t\t\t int addr_len,\n\t\t\t\t\t unsigned *p_cand_id)\n{\n    pj_ice_sess_cand *lcand;\n    pj_status_t status = PJ_SUCCESS;\n    char address[PJ_INET6_ADDRSTRLEN];\n\n    PJ_ASSERT_RETURN(ice && comp_id && \n\t\t     foundation && addr && base_addr && addr_len,\n\t\t     PJ_EINVAL);\n    PJ_ASSERT_RETURN(comp_id <= ice->comp_cnt, PJ_EINVAL);\n\n    pj_grp_lock_acquire(ice->grp_lock);\n\n    if (ice->lcand_cnt >= PJ_ARRAY_SIZE(ice->lcand)) {\n\tstatus = PJ_ETOOMANY;\n\tgoto on_error;\n    }\n\n    lcand = &ice->lcand[ice->lcand_cnt];\n    lcand->comp_id = (pj_uint8_t)comp_id;\n    lcand->transport_id = (pj_uint8_t)transport_id;\n    lcand->type = type;\n    pj_strdup(ice->pool, &lcand->foundation, foundation);\n    lcand->prio = CALC_CAND_PRIO(ice, type, local_pref, lcand->comp_id);\n    pj_sockaddr_cp(&lcand->addr, addr);\n    pj_sockaddr_cp(&lcand->base_addr, base_addr);\n    if (rel_addr == NULL)\n\trel_addr = base_addr;\n    pj_memcpy(&lcand->rel_addr, rel_addr, addr_len);\n\n    pj_ansi_strcpy(ice->tmp.txt, pj_sockaddr_print(&lcand->addr, address,\n                                                   sizeof(address), 0));\n    LOG4((ice->obj_name, \n\t \"Candidate %d added: comp_id=%d, type=%s, foundation=%.*s, \"\n\t \"addr=%s:%d, base=%s:%d, prio=0x%x (%u)\",\n\t ice->lcand_cnt, \n\t lcand->comp_id, \n\t cand_type_names[lcand->type],\n\t (int)lcand->foundation.slen,\n\t lcand->foundation.ptr,\n\t ice->tmp.txt, \n\t  pj_sockaddr_get_port(&lcand->addr),\n\t  pj_sockaddr_print(&lcand->base_addr, address, sizeof(address), 0),\n\t  pj_sockaddr_get_port(&lcand->base_addr),\n\t lcand->prio, lcand->prio));\n\n    if (p_cand_id)\n\t*p_cand_id = ice->lcand_cnt;\n\n    ++ice->lcand_cnt;\n\non_error:\n    pj_grp_lock_release(ice->grp_lock);\n    return status;\n}\n\n\n/* Find default candidate ID for the component */\nPJ_DEF(pj_status_t) pj_ice_sess_find_default_cand(pj_ice_sess *ice,\n\t\t\t\t\t\t  unsigned comp_id,\n\t\t\t\t\t\t  int *cand_id)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(ice && comp_id && cand_id, PJ_EINVAL);\n    PJ_ASSERT_RETURN(comp_id <= ice->comp_cnt, PJ_EINVAL);\n\n    *cand_id = -1;\n\n    pj_grp_lock_acquire(ice->grp_lock);\n\n    /* First find in valid list if we have nominated pair */\n    for (i=0; i<ice->valid_list.count; ++i) {\n\tpj_ice_sess_check *check = &ice->valid_list.checks[i];\n\t\n\tif (check->lcand->comp_id == comp_id) {\n\t    *cand_id = GET_LCAND_ID(check->lcand);\n\t    pj_grp_lock_release(ice->grp_lock);\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    /* If there's no nominated pair, find relayed candidate */\n    for (i=0; i<ice->lcand_cnt; ++i) {\n\tpj_ice_sess_cand *lcand = &ice->lcand[i];\n\tif (lcand->comp_id==comp_id &&\n\t    lcand->type == PJ_ICE_CAND_TYPE_RELAYED) \n\t{\n\t    *cand_id = GET_LCAND_ID(lcand);\n\t    pj_grp_lock_release(ice->grp_lock);\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    /* If there's no relayed candidate, find reflexive candidate */\n    for (i=0; i<ice->lcand_cnt; ++i) {\n\tpj_ice_sess_cand *lcand = &ice->lcand[i];\n\tif (lcand->comp_id==comp_id &&\n\t    (lcand->type == PJ_ICE_CAND_TYPE_SRFLX ||\n\t     lcand->type == PJ_ICE_CAND_TYPE_PRFLX)) \n\t{\n\t    *cand_id = GET_LCAND_ID(lcand);\n\t    pj_grp_lock_release(ice->grp_lock);\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    /* Otherwise return host candidate */\n    for (i=0; i<ice->lcand_cnt; ++i) {\n\tpj_ice_sess_cand *lcand = &ice->lcand[i];\n\tif (lcand->comp_id==comp_id &&\n\t    lcand->type == PJ_ICE_CAND_TYPE_HOST) \n\t{\n\t    *cand_id = GET_LCAND_ID(lcand);\n\t    pj_grp_lock_release(ice->grp_lock);\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    /* Still no candidate is found! :( */\n    pj_grp_lock_release(ice->grp_lock);\n\n    pj_assert(!\"Should have a candidate by now\");\n    return PJ_EBUG;\n}\n\n\n#ifndef MIN\n#   define MIN(a,b) (a < b ? a : b)\n#endif\n\n#ifndef MAX\n#   define MAX(a,b) (a > b ? a : b)\n#endif\n\nstatic pj_timestamp CALC_CHECK_PRIO(const pj_ice_sess *ice, \n\t\t\t\t    const pj_ice_sess_cand *lcand,\n\t\t\t\t    const pj_ice_sess_cand *rcand)\n{\n    pj_uint32_t O, A;\n    pj_timestamp prio;\n\n    /* Original formula:\n     *   pair priority = 2^32*MIN(O,A) + 2*MAX(O,A) + (O>A?1:0)\n     */\n\n    if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLING) {\n\tO = lcand->prio; \n\tA = rcand->prio;\n    } else {\n\tO = rcand->prio;\n\tA = lcand->prio;\n    }\n\n    /*\n    return ((pj_uint64_t)1 << 32) * MIN(O, A) +\n\t   (pj_uint64_t)2 * MAX(O, A) + (O>A ? 1 : 0);\n    */\n\n    prio.u32.hi = MIN(O,A);\n    prio.u32.lo = (MAX(O, A) << 1) + (O>A ? 1 : 0);\n\n    return prio;\n}\n\n\nPJ_INLINE(int) CMP_CHECK_PRIO(const pj_ice_sess_check *c1,\n\t\t\t      const pj_ice_sess_check *c2)\n{\n    return pj_cmp_timestamp(&c1->prio, &c2->prio);\n}\n\n\n#if PJ_LOG_MAX_LEVEL >= 4\nstatic const char *dump_check(char *buffer, unsigned bufsize,\n\t\t\t      const pj_ice_sess_checklist *clist,\n\t\t\t      const pj_ice_sess_check *check)\n{\n    const pj_ice_sess_cand *lcand = check->lcand;\n    const pj_ice_sess_cand *rcand = check->rcand;\n    char laddr[PJ_INET6_ADDRSTRLEN], raddr[PJ_INET6_ADDRSTRLEN];\n    int len;\n\n    PJ_CHECK_STACK();\n\n    len = pj_ansi_snprintf(buffer, bufsize,\n\t\t\t   \"%d: [%d] %s:%d-->%s:%d\",\n\t\t\t   (int)GET_CHECK_ID(clist, check),\n\t\t\t   check->lcand->comp_id,\n\t\t\t   pj_sockaddr_print(&lcand->addr, laddr,\n\t\t\t                     sizeof(laddr), 0),\n\t\t\t   pj_sockaddr_get_port(&lcand->addr),\n\t\t\t   pj_sockaddr_print(&rcand->addr, raddr,\n\t\t\t                     sizeof(raddr), 0),\n\t\t\t   pj_sockaddr_get_port(&rcand->addr));\n\n    if (len < 0)\n\tlen = 0;\n    else if (len >= (int)bufsize)\n\tlen = bufsize - 1;\n\n    buffer[len] = '\\0';\n    return buffer;\n}\n\nstatic void dump_checklist(const char *title, pj_ice_sess *ice, \n\t\t\t   const pj_ice_sess_checklist *clist)\n{\n    unsigned i;\n\n    LOG4((ice->obj_name, \"%s\", title));\n    for (i=0; i<clist->count; ++i) {\n\tconst pj_ice_sess_check *c = &clist->checks[i];\n\tLOG4((ice->obj_name, \" %s (%s, state=%s)\",\n\t     dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), clist, c),\n\t     (c->nominated ? \"nominated\" : \"not nominated\"), \n\t     check_state_name[c->state]));\n    }\n}\n\n#else\n#define dump_checklist(title, ice, clist)\n#endif\n\nstatic void check_set_state(pj_ice_sess *ice, pj_ice_sess_check *check,\n\t\t\t    pj_ice_sess_check_state st, \n\t\t\t    pj_status_t err_code)\n{\n    pj_assert(check->state < PJ_ICE_SESS_CHECK_STATE_SUCCEEDED);\n\n    LOG5((ice->obj_name, \"Check %s: state changed from %s to %s\",\n\t dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), &ice->clist, check),\n\t check_state_name[check->state],\n\t check_state_name[st]));\n    check->state = st;\n    check->err_code = err_code;\n}\n\nstatic void clist_set_state(pj_ice_sess *ice, pj_ice_sess_checklist *clist,\n\t\t\t    pj_ice_sess_checklist_state st)\n{\n    if (clist->state != st) {\n\tLOG5((ice->obj_name, \"Checklist: state changed from %s to %s\",\n\t     clist_state_name[clist->state],\n\t     clist_state_name[st]));\n\tclist->state = st;\n    }\n}\n\n/* Sort checklist based on priority */\nstatic void sort_checklist(pj_ice_sess *ice, pj_ice_sess_checklist *clist)\n{\n    unsigned i;\n    pj_ice_sess_check **check_ptr[PJ_ICE_MAX_COMP*2];\n    unsigned check_ptr_cnt = 0;\n\n    for (i=0; i<ice->comp_cnt; ++i) {\n\tif (ice->comp[i].valid_check) {\n\t    check_ptr[check_ptr_cnt++] = &ice->comp[i].valid_check;\n\t}\n\tif (ice->comp[i].nominated_check) {\n\t    check_ptr[check_ptr_cnt++] = &ice->comp[i].nominated_check;\n\t}\n    }\n\n    pj_assert(clist->count > 0);\n    for (i=0; i<clist->count-1; ++i) {\n\tunsigned j, highest = i;\n\n\tfor (j=i+1; j<clist->count; ++j) {\n\t    if (CMP_CHECK_PRIO(&clist->checks[j], &clist->checks[highest]) > 0) {\n\t\thighest = j;\n\t    }\n\t}\n\n\tif (highest != i) {\n\t    pj_ice_sess_check tmp;\n\t    unsigned k;\n\n\t    pj_memcpy(&tmp, &clist->checks[i], sizeof(pj_ice_sess_check));\n\t    pj_memcpy(&clist->checks[i], &clist->checks[highest], \n\t\t      sizeof(pj_ice_sess_check));\n\t    pj_memcpy(&clist->checks[highest], &tmp, \n\t\t      sizeof(pj_ice_sess_check));\n\n\t    /* Update valid and nominated check pointers, since we're moving\n\t     * around checks\n\t     */\n\t    for (k=0; k<check_ptr_cnt; ++k) {\n\t\tif (*check_ptr[k] == &clist->checks[highest])\n\t\t    *check_ptr[k] = &clist->checks[i];\n\t\telse if (*check_ptr[k] == &clist->checks[i])\n\t\t    *check_ptr[k] = &clist->checks[highest];\n\t    }\n\t}\n    }\n}\n\n/* Prune checklist, this must have been done after the checklist\n * is sorted.\n */\nstatic pj_status_t prune_checklist(pj_ice_sess *ice, \n\t\t\t\t   pj_ice_sess_checklist *clist)\n{\n    unsigned i;\n\n    /* Since an agent cannot send requests directly from a reflexive\n     * candidate, but only from its base, the agent next goes through the\n     * sorted list of candidate pairs.  For each pair where the local\n     * candidate is server reflexive, the server reflexive candidate MUST be\n     * replaced by its base.  Once this has been done, the agent MUST prune\n     * the list.  This is done by removing a pair if its local and remote\n     * candidates are identical to the local and remote candidates of a pair\n     * higher up on the priority list.  The result is a sequence of ordered\n     * candidate pairs, called the check list for that media stream.    \n     */\n    /* First replace SRFLX candidates with their base */\n    for (i=0; i<clist->count; ++i) {\n\tpj_ice_sess_cand *srflx = clist->checks[i].lcand;\n\n\tif (clist->checks[i].lcand->type == PJ_ICE_CAND_TYPE_SRFLX) {\n\t    /* Find the base for this candidate */\n\t    unsigned j;\n\t    for (j=0; j<ice->lcand_cnt; ++j) {\n\t\tpj_ice_sess_cand *host = &ice->lcand[j];\n\n\t\tif (host->type != PJ_ICE_CAND_TYPE_HOST)\n\t\t    continue;\n\n\t\tif (pj_sockaddr_cmp(&srflx->base_addr, &host->addr) == 0) {\n\t\t    /* Replace this SRFLX with its BASE */\n\t\t    clist->checks[i].lcand = host;\n\t\t    break;\n\t\t}\n\t    }\n\n\t    if (j==ice->lcand_cnt) {\n\t\tchar baddr[PJ_INET6_ADDRSTRLEN];\n\t\t/* Host candidate not found this this srflx! */\n\t\tLOG4((ice->obj_name, \n\t\t      \"Base candidate %s:%d not found for srflx candidate %d\",\n\t\t      pj_sockaddr_print(&srflx->base_addr, baddr,\n\t\t                        sizeof(baddr), 0),\n\t\t      pj_sockaddr_get_port(&srflx->base_addr),\n\t\t      GET_LCAND_ID(clist->checks[i].lcand)));\n\t\treturn PJNATH_EICENOHOSTCAND;\n\t    }\n\t}\n    }\n\n    /* Next remove a pair if its local and remote candidates are identical\n     * to the local and remote candidates of a pair higher up on the priority\n     * list\n     */\n    /*\n     * Not in ICE!\n     * Remove host candidates if their base are the the same!\n     */\n    for (i=0; i<clist->count; ++i) {\n\tpj_ice_sess_cand *licand = clist->checks[i].lcand;\n\tpj_ice_sess_cand *ricand = clist->checks[i].rcand;\n\tunsigned j;\n\n\tfor (j=i+1; j<clist->count;) {\n\t    pj_ice_sess_cand *ljcand = clist->checks[j].lcand;\n\t    pj_ice_sess_cand *rjcand = clist->checks[j].rcand;\n\t    const char *reason = NULL;\n\n\t    if ((licand == ljcand) && (ricand == rjcand)) {\n\t\treason = \"duplicate found\";\n\t    } else if ((rjcand == ricand) &&\n\t\t       (pj_sockaddr_cmp(&ljcand->base_addr, \n\t\t\t\t     &licand->base_addr)==0)) \n\t    {\n\t\treason = \"equal base\";\n\t    }\n\n\t    if (reason != NULL) {\n\t\t/* Found duplicate, remove it */\n\t\tLOG5((ice->obj_name, \"Check %s pruned (%s)\",\n\t\t      dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), \n\t\t\t\t &ice->clist, &clist->checks[j]),\n\t\t      reason));\n\n\t\tpj_array_erase(clist->checks, sizeof(clist->checks[0]),\n\t\t\t       clist->count, j);\n\t\t--clist->count;\n\n\t    } else {\n\t\t++j;\n\t    }\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* Timer callback */\nstatic void on_timer(pj_timer_heap_t *th, pj_timer_entry *te)\n{\n    pj_ice_sess *ice = (pj_ice_sess*) te->user_data;\n    enum timer_type type = (enum timer_type)te->id;\n\n    PJ_UNUSED_ARG(th);\n\n    pj_grp_lock_acquire(ice->grp_lock);\n\n    te->id = TIMER_NONE;\n\n    if (ice->is_destroying) {\n\t/* Stray timer, could happen when destroy is invoked while callback\n\t * is pending. */\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn;\n    }\n\n    switch (type) {\n    case TIMER_CONTROLLED_WAIT_NOM:\n\tLOG4((ice->obj_name, \n\t      \"Controlled agent timed-out in waiting for the controlling \"\n\t      \"agent to send nominated check. Setting state to fail now..\"));\n\ton_ice_complete(ice, PJNATH_EICENOMTIMEOUT);\n\tbreak;\n    case TIMER_COMPLETION_CALLBACK:\n\t{\n\t    void (*on_ice_complete)(pj_ice_sess *ice, pj_status_t status);\n\t    pj_status_t ice_status;\n\n\t    /* Start keep-alive timer but don't send any packets yet.\n\t     * Need to do it here just in case app destroy the session\n\t     * in the callback.\n\t     */\n\t    if (ice->ice_status == PJ_SUCCESS)\n\t\tice_keep_alive(ice, PJ_FALSE);\n\n\t    /* Release mutex in case app destroy us in the callback */\n\t    ice_status = ice->ice_status;\n\t    on_ice_complete = ice->cb.on_ice_complete;\n\n\t    /* Notify app about ICE completion*/\n\t    if (on_ice_complete)\n\t\t(*on_ice_complete)(ice, ice_status);\n\t}\n\tbreak;\n    case TIMER_START_NOMINATED_CHECK:\n\tstart_nominated_check(ice);\n\tbreak;\n    case TIMER_KEEP_ALIVE:\n\tice_keep_alive(ice, PJ_TRUE);\n\tbreak;\n    case TIMER_NONE:\n\t/* Nothing to do, just to get rid of gcc warning */\n\tbreak;\n    }\n\n    pj_grp_lock_release(ice->grp_lock);\n}\n\n/* Send keep-alive */\nstatic void ice_keep_alive(pj_ice_sess *ice, pj_bool_t send_now)\n{\n    if (send_now) {\n\t/* Send Binding Indication for the component */\n\tpj_ice_sess_comp *comp = &ice->comp[ice->comp_ka];\n\tpj_stun_tx_data *tdata;\n\tpj_ice_sess_check *the_check;\n\tpj_ice_msg_data *msg_data;\n\tint addr_len;\n\tpj_bool_t saved;\n\tpj_status_t status;\n\n\t/* Must have nominated check by now */\n\tpj_assert(comp->nominated_check != NULL);\n\tthe_check = comp->nominated_check;\n\n\t/* Create the Binding Indication */\n\tstatus = pj_stun_session_create_ind(comp->stun_sess, \n\t\t\t\t\t    PJ_STUN_BINDING_INDICATION,\n\t\t\t\t\t    &tdata);\n\tif (status != PJ_SUCCESS)\n\t    goto done;\n\n\t/* Need the transport_id */\n\tmsg_data = PJ_POOL_ZALLOC_T(tdata->pool, pj_ice_msg_data);\n\tmsg_data->transport_id = the_check->lcand->transport_id;\n\n\t/* Temporarily disable FINGERPRINT. The Binding Indication \n\t * SHOULD NOT contain any attributes.\n\t */\n\tsaved = pj_stun_session_use_fingerprint(comp->stun_sess, PJ_FALSE);\n\n\t/* Send to session */\n\taddr_len = pj_sockaddr_get_len(&the_check->rcand->addr);\n\tstatus = pj_stun_session_send_msg(comp->stun_sess, msg_data,\n\t\t\t\t\t  PJ_FALSE, PJ_FALSE, \n\t\t\t\t\t  &the_check->rcand->addr, \n\t\t\t\t\t  addr_len, tdata);\n\n\t/* Restore FINGERPRINT usage */\n\tpj_stun_session_use_fingerprint(comp->stun_sess, saved);\n\ndone:\n\tice->comp_ka = (ice->comp_ka + 1) % ice->comp_cnt;\n    }\n\n    if (ice->timer.id == TIMER_NONE) {\n\tpj_time_val delay = { 0, 0 };\n\n\tdelay.msec = (PJ_ICE_SESS_KEEP_ALIVE_MIN + \n\t\t      (pj_rand() % PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND)) * 1000 / \n\t\t     ice->comp_cnt;\n\tpj_time_val_normalize(&delay);\n\n\tpj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,\n\t                                  &ice->timer, &delay,\n\t                                  TIMER_KEEP_ALIVE,\n\t                                  ice->grp_lock);\n\n    } else {\n\tpj_assert(!\"Not expected any timer active\");\n    }\n}\n\n/* This function is called when ICE processing completes */\nstatic void on_ice_complete(pj_ice_sess *ice, pj_status_t status)\n{\n    if (!ice->is_complete) {\n\tice->is_complete = PJ_TRUE;\n\tice->ice_status = status;\n    \n\tpj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap, &ice->timer,\n\t                               TIMER_NONE);\n\n\t/* Log message */\n\tLOG4((ice->obj_name, \"ICE process complete, status=%s\", \n\t     pj_strerror(status, ice->tmp.errmsg, \n\t\t\t sizeof(ice->tmp.errmsg)).ptr));\n\n\tdump_checklist(\"Valid list\", ice, &ice->valid_list);\n\n\t/* Call callback */\n\tif (ice->cb.on_ice_complete) {\n\t    pj_time_val delay = {0, 0};\n\n\t    pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,\n\t                                      &ice->timer, &delay,\n\t                                      TIMER_COMPLETION_CALLBACK,\n\t                                      ice->grp_lock);\n\t}\n    }\n}\n\n/* Update valid check and nominated check for the candidate */\nstatic void update_comp_check(pj_ice_sess *ice, unsigned comp_id, \n\t\t\t      pj_ice_sess_check *check)\n{\n    pj_ice_sess_comp *comp;\n\n    comp = find_comp(ice, comp_id);\n    if (comp->valid_check == NULL) {\n\tcomp->valid_check = check;\n    } else {\n\tif (CMP_CHECK_PRIO(comp->valid_check, check) < 0)\n\t    comp->valid_check = check;\n    }\n\n    if (check->nominated) {\n\t/* Update the nominated check for the component */\n\tif (comp->nominated_check == NULL) {\n\t    comp->nominated_check = check;\n\t} else {\n\t    if (CMP_CHECK_PRIO(comp->nominated_check, check) < 0)\n\t\tcomp->nominated_check = check;\n\t}\n    }\n}\n\n/* This function is called when one check completes */\nstatic pj_bool_t on_check_complete(pj_ice_sess *ice,\n\t\t\t\t   pj_ice_sess_check *check)\n{\n    pj_ice_sess_comp *comp;\n    unsigned i;\n\n    pj_assert(check->state >= PJ_ICE_SESS_CHECK_STATE_SUCCEEDED);\n\n    comp = find_comp(ice, check->lcand->comp_id);\n\n    /* 7.1.2.2.2.  Updating Pair States\n     * \n     * The agent sets the state of the pair that generated the check to\n     * Succeeded.  The success of this check might also cause the state of\n     * other checks to change as well.  The agent MUST perform the following\n     * two steps:\n     * \n     * 1.  The agent changes the states for all other Frozen pairs for the\n     *     same media stream and same foundation to Waiting.  Typically\n     *     these other pairs will have different component IDs but not\n     *     always.\n     */\n    if (check->err_code==PJ_SUCCESS) {\n\n\tfor (i=0; i<ice->clist.count; ++i) {\n\t    pj_ice_sess_check *c = &ice->clist.checks[i];\n\t    if (pj_strcmp(&c->lcand->foundation, &check->lcand->foundation)==0\n\t\t && c->state == PJ_ICE_SESS_CHECK_STATE_FROZEN)\n\t    {\n\t\tcheck_set_state(ice, c, PJ_ICE_SESS_CHECK_STATE_WAITING, 0);\n\t    }\n\t}\n\n\tLOG5((ice->obj_name, \"Check %d is successful%s\",\n\t     GET_CHECK_ID(&ice->clist, check),\n\t     (check->nominated ? \"  and nominated\" : \"\")));\n\n    }\n\n    /* 8.2.  Updating States\n     * \n     * For both controlling and controlled agents, the state of ICE\n     * processing depends on the presence of nominated candidate pairs in\n     * the valid list and on the state of the check list:\n     *\n     * o  If there are no nominated pairs in the valid list for a media\n     *    stream and the state of the check list is Running, ICE processing\n     *    continues.\n     *\n     * o  If there is at least one nominated pair in the valid list:\n     *\n     *    - The agent MUST remove all Waiting and Frozen pairs in the check\n     *      list for the same component as the nominated pairs for that\n     *      media stream\n     *\n     *    - If an In-Progress pair in the check list is for the same\n     *      component as a nominated pair, the agent SHOULD cease\n     *      retransmissions for its check if its pair priority is lower\n     *      than the lowest priority nominated pair for that component\n     */\n    if (check->err_code==PJ_SUCCESS && check->nominated) {\n\n\tfor (i=0; i<ice->clist.count; ++i) {\n\n\t    pj_ice_sess_check *c = &ice->clist.checks[i];\n\n\t    if (c->lcand->comp_id == check->lcand->comp_id) {\n\n\t\tif (c->state < PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS) {\n\n\t\t    /* Just fail Frozen/Waiting check */\n\t\t    LOG5((ice->obj_name, \n\t\t\t \"Check %s to be failed because state is %s\",\n\t\t\t dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), \n\t\t\t\t    &ice->clist, c), \n\t\t\t check_state_name[c->state]));\n\t\t    check_set_state(ice, c, PJ_ICE_SESS_CHECK_STATE_FAILED,\n\t\t\t\t    PJ_ECANCELLED);\n\n\t\t} else if (c->state == PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS\n\t\t\t   && (PJ_ICE_CANCEL_ALL ||\n\t\t\t        CMP_CHECK_PRIO(c, check) < 0)) {\n\n\t\t    /* State is IN_PROGRESS, cancel transaction */\n\t\t    if (c->tdata) {\n\t\t\tLOG5((ice->obj_name, \n\t\t\t     \"Cancelling check %s (In Progress)\",\n\t\t\t     dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), \n\t\t\t\t\t&ice->clist, c)));\n\t\t\tpj_stun_session_cancel_req(comp->stun_sess, \n\t\t\t\t\t\t   c->tdata, PJ_FALSE, 0);\n\t\t\tc->tdata = NULL;\n\t\t\tcheck_set_state(ice, c, PJ_ICE_SESS_CHECK_STATE_FAILED,\n\t\t\t\t\tPJ_ECANCELLED);\n\t\t    }\n\t\t}\n\t    }\n\t}\n    }\n\n\n    /* Still in 8.2.  Updating States\n     * \n     * o  Once there is at least one nominated pair in the valid list for\n     *    every component of at least one media stream and the state of the\n     *    check list is Running:\n     *    \n     *    *  The agent MUST change the state of processing for its check\n     *       list for that media stream to Completed.\n     *    \n     *    *  The agent MUST continue to respond to any checks it may still\n     *       receive for that media stream, and MUST perform triggered\n     *       checks if required by the processing of Section 7.2.\n     *    \n     *    *  The agent MAY begin transmitting media for this media stream as\n     *       described in Section 11.1\n     */\n\n    /* See if all components have nominated pair. If they do, then mark\n     * ICE processing as success, otherwise wait.\n     */\n    for (i=0; i<ice->comp_cnt; ++i) {\n\tif (ice->comp[i].nominated_check == NULL)\n\t    break;\n    }\n    if (i == ice->comp_cnt) {\n\t/* All components have nominated pair */\n\ton_ice_complete(ice, PJ_SUCCESS);\n\treturn PJ_TRUE;\n    }\n\n    /* Note: this is the stuffs that we don't do in 7.1.2.2.2, since our\n     *       ICE session only supports one media stream for now:\n     * \n     * 7.1.2.2.2.  Updating Pair States\n     *\n     * 2.  If there is a pair in the valid list for every component of this\n     *     media stream (where this is the actual number of components being\n     *     used, in cases where the number of components signaled in the SDP\n     *     differs from offerer to answerer), the success of this check may\n     *     unfreeze checks for other media streams. \n     */\n\n    /* 7.1.2.3.  Check List and Timer State Updates\n     * Regardless of whether the check was successful or failed, the\n     * completion of the transaction may require updating of check list and\n     * timer states.\n     * \n     * If all of the pairs in the check list are now either in the Failed or\n     * Succeeded state, and there is not a pair in the valid list for each\n     * component of the media stream, the state of the check list is set to\n     * Failed.  \n     */\n\n    /* \n     * See if all checks in the checklist have completed. If we do,\n     * then mark ICE processing as failed.\n     */\n    for (i=0; i<ice->clist.count; ++i) {\n\tpj_ice_sess_check *c = &ice->clist.checks[i];\n\tif (c->state < PJ_ICE_SESS_CHECK_STATE_SUCCEEDED) {\n\t    break;\n\t}\n    }\n\n    if (i == ice->clist.count) {\n\t/* All checks have completed, but we don't have nominated pair.\n\t * If agent's role is controlled, check if all components have\n\t * valid pair. If it does, this means the controlled agent has\n\t * finished the check list and it's waiting for controlling\n\t * agent to send checks with USE-CANDIDATE flag set.\n\t */\n\tif (ice->role == PJ_ICE_SESS_ROLE_CONTROLLED) {\n\t    for (i=0; i < ice->comp_cnt; ++i) {\n\t\tif (ice->comp[i].valid_check == NULL)\n\t\t    break;\n\t    }\n\n\t    if (i < ice->comp_cnt) {\n\t\t/* This component ID doesn't have valid pair.\n\t\t * Mark ICE as failed. \n\t\t */\n\t\ton_ice_complete(ice, PJNATH_EICEFAILED);\n\t\treturn PJ_TRUE;\n\t    } else {\n\t\t/* All components have a valid pair.\n\t\t * We should wait until we receive nominated checks.\n\t\t */\n\t\tif (ice->timer.id == TIMER_NONE &&\n\t\t    ice->opt.controlled_agent_want_nom_timeout >= 0) \n\t\t{\n\t\t    pj_time_val delay;\n\n\t\t    delay.sec = 0;\n\t\t    delay.msec = ice->opt.controlled_agent_want_nom_timeout;\n\t\t    pj_time_val_normalize(&delay);\n\n\t\t    pj_timer_heap_schedule_w_grp_lock(\n\t\t\t\t\tice->stun_cfg.timer_heap,\n\t\t                        &ice->timer, &delay,\n\t\t                        TIMER_CONTROLLED_WAIT_NOM,\n\t\t                        ice->grp_lock);\n\n\t\t    LOG5((ice->obj_name, \n\t\t\t  \"All checks have completed. Controlled agent now \"\n\t\t\t  \"waits for nomination from controlling agent \"\n\t\t\t  \"(timeout=%d msec)\",\n\t\t\t  ice->opt.controlled_agent_want_nom_timeout));\n\t\t}\n\t\treturn PJ_FALSE;\n\t    }\n\n\t    /* Unreached */\n\n\t} else if (ice->is_nominating) {\n\t    /* We are controlling agent and all checks have completed but\n\t     * there's at least one component without nominated pair (or\n\t     * more likely we don't have any nominated pairs at all).\n\t     */\n\t    on_ice_complete(ice, PJNATH_EICEFAILED);\n\t    return PJ_TRUE;\n\n\t} else {\n\t    /* We are controlling agent and all checks have completed. If\n\t     * we have valid list for every component, then move on to\n\t     * sending nominated check, otherwise we have failed.\n\t     */\n\t    for (i=0; i<ice->comp_cnt; ++i) {\n\t\tif (ice->comp[i].valid_check == NULL)\n\t\t    break;\n\t    }\n\n\t    if (i < ice->comp_cnt) {\n\t\t/* At least one component doesn't have a valid check. Mark\n\t\t * ICE as failed.\n\t\t */\n\t\ton_ice_complete(ice, PJNATH_EICEFAILED);\n\t\treturn PJ_TRUE;\n\t    }\n\n\t    /* Now it's time to send connectivity check with nomination \n\t     * flag set.\n\t     */\n\t    LOG4((ice->obj_name, \n\t\t  \"All checks have completed, starting nominated checks now\"));\n\t    start_nominated_check(ice);\n\t    return PJ_FALSE;\n\t}\n    }\n\n    /* If this connectivity check has been successful, scan all components\n     * and see if they have a valid pair, if we are controlling and we haven't\n     * started our nominated check yet.\n     */\n    if (check->err_code == PJ_SUCCESS && \n\tice->role==PJ_ICE_SESS_ROLE_CONTROLLING &&\n\t!ice->is_nominating &&\n\tice->timer.id == TIMER_NONE) \n    {\n\tpj_time_val delay;\n\n\tfor (i=0; i<ice->comp_cnt; ++i) {\n\t    if (ice->comp[i].valid_check == NULL)\n\t\tbreak;\n\t}\n\n\tif (i < ice->comp_cnt) {\n\t    /* Some components still don't have valid pair, continue\n\t     * processing.\n\t     */\n\t    return PJ_FALSE;\n\t}\n\n\tLOG4((ice->obj_name, \n\t      \"Scheduling nominated check in %d ms\",\n\t      ice->opt.nominated_check_delay));\n\n\tpj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap, &ice->timer,\n\t                               TIMER_NONE);\n\n\t/* All components have valid pair. Let connectivity checks run for\n\t * a little bit more time, then start our nominated check.\n\t */\n\tdelay.sec = 0;\n\tdelay.msec = ice->opt.nominated_check_delay;\n\tpj_time_val_normalize(&delay);\n\n\tpj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,\n\t                                  &ice->timer, &delay,\n\t                                  TIMER_START_NOMINATED_CHECK,\n\t                                  ice->grp_lock);\n\treturn PJ_FALSE;\n    }\n\n    /* We still have checks to perform */\n    return PJ_FALSE;\n}\n\n\n/* Create checklist by pairing local candidates with remote candidates */\nPJ_DEF(pj_status_t) pj_ice_sess_create_check_list(\n\t\t\t      pj_ice_sess *ice,\n\t\t\t      const pj_str_t *rem_ufrag,\n\t\t\t      const pj_str_t *rem_passwd,\n\t\t\t      unsigned rem_cand_cnt,\n\t\t\t      const pj_ice_sess_cand rem_cand[])\n{\n    pj_ice_sess_checklist *clist;\n    char buf[128];\n    pj_str_t username;\n    timer_data *td;\n    unsigned i, j;\n    unsigned highest_comp = 0;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(ice && rem_ufrag && rem_passwd && rem_cand_cnt &&\n\t\t     rem_cand, PJ_EINVAL);\n    PJ_ASSERT_RETURN(rem_cand_cnt + ice->rcand_cnt <= PJ_ICE_MAX_CAND,\n\t\t     PJ_ETOOMANY);\n\n    pj_grp_lock_acquire(ice->grp_lock);\n\n    /* Save credentials */\n    username.ptr = buf;\n\n    pj_strcpy(&username, rem_ufrag);\n    pj_strcat2(&username, \":\");\n    pj_strcat(&username, &ice->rx_ufrag);\n\n    pj_strdup(ice->pool, &ice->tx_uname, &username);\n    pj_strdup(ice->pool, &ice->tx_ufrag, rem_ufrag);\n    pj_strdup(ice->pool, &ice->tx_pass, rem_passwd);\n\n    pj_strcpy(&username, &ice->rx_ufrag);\n    pj_strcat2(&username, \":\");\n    pj_strcat(&username, rem_ufrag);\n\n    pj_strdup(ice->pool, &ice->rx_uname, &username);\n\n\n    /* Save remote candidates */\n    ice->rcand_cnt = 0;\n    for (i=0; i<rem_cand_cnt; ++i) {\n\tpj_ice_sess_cand *cn = &ice->rcand[ice->rcand_cnt];\n\n\t/* Ignore candidate which has no matching component ID */\n\tif (rem_cand[i].comp_id==0 || rem_cand[i].comp_id > ice->comp_cnt) {\n\t    continue;\n\t}\n\n\tif (rem_cand[i].comp_id > highest_comp)\n\t    highest_comp = rem_cand[i].comp_id;\n\n\tpj_memcpy(cn, &rem_cand[i], sizeof(pj_ice_sess_cand));\n\tpj_strdup(ice->pool, &cn->foundation, &rem_cand[i].foundation);\n\tice->rcand_cnt++;\n    }\n\n    /* Generate checklist */\n    clist = &ice->clist;\n    for (i=0; i<ice->lcand_cnt; ++i) {\n\tfor (j=0; j<ice->rcand_cnt; ++j) {\n\n\t    pj_ice_sess_cand *lcand = &ice->lcand[i];\n\t    pj_ice_sess_cand *rcand = &ice->rcand[j];\n\t    pj_ice_sess_check *chk = NULL;\n\n\t    if (clist->count >= PJ_ICE_MAX_CHECKS) {\n\t\tpj_grp_lock_release(ice->grp_lock);\n\t\treturn PJ_ETOOMANY;\n\t    } \n\n           chk = &clist->checks[clist->count];\n\n\t    /* A local candidate is paired with a remote candidate if\n\t     * and only if the two candidates have the same component ID \n\t     * and have the same IP address version. \n\t     */\n\t    if ((lcand->comp_id != rcand->comp_id) ||\n\t\t(lcand->addr.addr.sa_family != rcand->addr.addr.sa_family))\n\t    {\n\t\tcontinue;\n\t    }\n\n\n\t    chk->lcand = lcand;\n\t    chk->rcand = rcand;\n\t    chk->state = PJ_ICE_SESS_CHECK_STATE_FROZEN;\n\n\t    chk->prio = CALC_CHECK_PRIO(ice, lcand, rcand);\n\n\t    clist->count++;\n\t}\n    }\n\n    /* This could happen if candidates have no matching address families */\n    if (clist->count == 0) {\n\tLOG4((ice->obj_name,  \"Error: no checklist can be created\"));\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn PJ_ENOTFOUND;\n    }\n\n    /* Sort checklist based on priority */\n    sort_checklist(ice, clist);\n\n    /* Prune the checklist */\n    status = prune_checklist(ice, clist);\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn status;\n    }\n\n    /* Disable our components which don't have matching component */\n    for (i=highest_comp; i<ice->comp_cnt; ++i) {\n\tif (ice->comp[i].stun_sess) {\n\t    pj_stun_session_destroy(ice->comp[i].stun_sess);\n\t    pj_bzero(&ice->comp[i], sizeof(ice->comp[i]));\n\t}\n    }\n    ice->comp_cnt = highest_comp;\n\n    /* Init timer entry in the checklist. Initially the timer ID is FALSE\n     * because timer is not running.\n     */\n    clist->timer.id = PJ_FALSE;\n    td = PJ_POOL_ZALLOC_T(ice->pool, timer_data);\n    td->ice = ice;\n    td->clist = clist;\n    clist->timer.user_data = (void*)td;\n    clist->timer.cb = &periodic_timer;\n\n\n    /* Log checklist */\n    dump_checklist(\"Checklist created:\", ice, clist);\n\n    pj_grp_lock_release(ice->grp_lock);\n\n    return PJ_SUCCESS;\n}\n\n/* Perform check on the specified candidate pair. */\nstatic pj_status_t perform_check(pj_ice_sess *ice, \n\t\t\t\t pj_ice_sess_checklist *clist,\n\t\t\t\t unsigned check_id,\n\t\t\t\t pj_bool_t nominate)\n{\n    pj_ice_sess_comp *comp;\n    pj_ice_msg_data *msg_data;\n    pj_ice_sess_check *check;\n    const pj_ice_sess_cand *lcand;\n    const pj_ice_sess_cand *rcand;\n    pj_uint32_t prio;\n    pj_status_t status;\n\n    check = &clist->checks[check_id];\n    lcand = check->lcand;\n    rcand = check->rcand;\n    comp = find_comp(ice, lcand->comp_id);\n\n    LOG5((ice->obj_name, \n\t \"Sending connectivity check for check %s\", \n\t dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), clist, check)));\n    pj_log_push_indent();\n\n    /* Create request */\n    status = pj_stun_session_create_req(comp->stun_sess, \n\t\t\t\t\tPJ_STUN_BINDING_REQUEST, PJ_STUN_MAGIC,\n\t\t\t\t\tNULL, &check->tdata);\n    if (status != PJ_SUCCESS) {\n\tpjnath_perror(ice->obj_name, \"Error creating STUN request\", status);\n\tpj_log_pop_indent();\n\treturn status;\n    }\n\n    /* Attach data to be retrieved later when STUN request transaction\n     * completes and on_stun_request_complete() callback is called.\n     */\n    msg_data = PJ_POOL_ZALLOC_T(check->tdata->pool, pj_ice_msg_data);\n    msg_data->transport_id = lcand->transport_id;\n    msg_data->has_req_data = PJ_TRUE;\n    msg_data->data.req.ice = ice;\n    msg_data->data.req.clist = clist;\n    msg_data->data.req.ckid = check_id;\n\n    /* Add PRIORITY */\n#if PJNATH_ICE_PRIO_STD\n    prio = CALC_CAND_PRIO(ice, PJ_ICE_CAND_TYPE_PRFLX, 65535, \n\t\t\t  lcand->comp_id);\n#else\n    prio = CALC_CAND_PRIO(ice, PJ_ICE_CAND_TYPE_PRFLX, 0, \n\t\t\t  lcand->comp_id);\n#endif\n    pj_stun_msg_add_uint_attr(check->tdata->pool, check->tdata->msg, \n\t\t\t      PJ_STUN_ATTR_PRIORITY, prio);\n\n    /* Add USE-CANDIDATE and set this check to nominated.\n     * Also add ICE-CONTROLLING or ICE-CONTROLLED\n     */\n    if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLING) {\n\tif (nominate) {\n\t    pj_stun_msg_add_empty_attr(check->tdata->pool, check->tdata->msg,\n\t\t\t\t       PJ_STUN_ATTR_USE_CANDIDATE);\n\t    check->nominated = PJ_TRUE;\n\t}\n\n\tpj_stun_msg_add_uint64_attr(check->tdata->pool, check->tdata->msg, \n\t\t\t\t    PJ_STUN_ATTR_ICE_CONTROLLING,\n\t\t\t\t    &ice->tie_breaker);\n\n    } else {\n\tpj_stun_msg_add_uint64_attr(check->tdata->pool, check->tdata->msg, \n\t\t\t\t    PJ_STUN_ATTR_ICE_CONTROLLED,\n\t\t\t\t    &ice->tie_breaker);\n    }\n\n\n    /* Note that USERNAME and MESSAGE-INTEGRITY will be added by the \n     * STUN session.\n     */\n\n    /* Initiate STUN transaction to send the request */\n    status = pj_stun_session_send_msg(comp->stun_sess, msg_data, PJ_FALSE, \n\t\t\t\t      PJ_TRUE, &rcand->addr, \n\t\t\t\t      pj_sockaddr_get_len(&rcand->addr),\n\t\t\t\t      check->tdata);\n    if (status != PJ_SUCCESS) {\n\tcheck->tdata = NULL;\n\tpjnath_perror(ice->obj_name, \"Error sending STUN request\", status);\n\tpj_log_pop_indent();\n\treturn status;\n    }\n\n    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS, \n\t            PJ_SUCCESS);\n    pj_log_pop_indent();\n    return PJ_SUCCESS;\n}\n\n\n/* Start periodic check for the specified checklist.\n * This callback is called by timer on every Ta (20msec by default)\n */\nstatic pj_status_t start_periodic_check(pj_timer_heap_t *th, \n\t\t\t\t\tpj_timer_entry *te)\n{\n    timer_data *td;\n    pj_ice_sess *ice;\n    pj_ice_sess_checklist *clist;\n    unsigned i, start_count=0;\n    pj_status_t status;\n\n    td = (struct timer_data*) te->user_data;\n    ice = td->ice;\n    clist = td->clist;\n\n    pj_grp_lock_acquire(ice->grp_lock);\n\n    if (ice->is_destroying) {\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn PJ_SUCCESS;\n    }\n\n    /* Set timer ID to FALSE first */\n    te->id = PJ_FALSE;\n\n    /* Set checklist state to Running */\n    clist_set_state(ice, clist, PJ_ICE_SESS_CHECKLIST_ST_RUNNING);\n\n    LOG5((ice->obj_name, \"Starting checklist periodic check\"));\n    pj_log_push_indent();\n\n    /* Send STUN Binding request for check with highest priority on\n     * Waiting state.\n     */\n    for (i=0; i<clist->count; ++i) {\n\tpj_ice_sess_check *check = &clist->checks[i];\n\n\tif (check->state == PJ_ICE_SESS_CHECK_STATE_WAITING) {\n\t    status = perform_check(ice, clist, i, ice->is_nominating);\n\t    if (status != PJ_SUCCESS) {\n\t\tpj_grp_lock_release(ice->grp_lock);\n\t\tpj_log_pop_indent();\n\t\treturn status;\n\t    }\n\n\t    ++start_count;\n\t    break;\n\t}\n    }\n\n    /* If we don't have anything in Waiting state, perform check to\n     * highest priority pair that is in Frozen state.\n     */\n    if (start_count==0) {\n\tfor (i=0; i<clist->count; ++i) {\n\t    pj_ice_sess_check *check = &clist->checks[i];\n\n\t    if (check->state == PJ_ICE_SESS_CHECK_STATE_FROZEN) {\n\t\tstatus = perform_check(ice, clist, i, ice->is_nominating);\n\t\tif (status != PJ_SUCCESS) {\n\t\t    pj_grp_lock_release(ice->grp_lock);\n\t\t    pj_log_pop_indent();\n\t\t    return status;\n\t\t}\n\n\t\t++start_count;\n\t\tbreak;\n\t    }\n\t}\n    }\n\n    /* Cannot start check because there's no suitable candidate pair.\n     */\n    if (start_count!=0) {\n\t/* Schedule for next timer */\n\tpj_time_val timeout = {0, PJ_ICE_TA_VAL};\n\n\tpj_time_val_normalize(&timeout);\n\tpj_timer_heap_schedule_w_grp_lock(th, te, &timeout, PJ_TRUE,\n\t                                  ice->grp_lock);\n    }\n\n    pj_grp_lock_release(ice->grp_lock);\n    pj_log_pop_indent();\n    return PJ_SUCCESS;\n}\n\n\n/* Start sending connectivity check with USE-CANDIDATE */\nstatic void start_nominated_check(pj_ice_sess *ice)\n{\n    pj_time_val delay;\n    unsigned i;\n    pj_status_t status;\n\n    LOG4((ice->obj_name, \"Starting nominated check..\"));\n    pj_log_push_indent();\n\n    pj_assert(ice->is_nominating == PJ_FALSE);\n\n    /* Stop our timer if it's active */\n    if (ice->timer.id == TIMER_START_NOMINATED_CHECK) {\n\tpj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap, &ice->timer,\n\t                               TIMER_NONE);\n    }\n\n    /* For each component, set the check state of valid check with\n     * highest priority to Waiting (it should have Success state now).\n     */\n    for (i=0; i<ice->comp_cnt; ++i) {\n\tunsigned j;\n\tconst pj_ice_sess_check *vc = ice->comp[i].valid_check;\n\n\tpj_assert(ice->comp[i].nominated_check == NULL);\n\tpj_assert(vc->err_code == PJ_SUCCESS);\n\n\tfor (j=0; j<ice->clist.count; ++j) {\n\t    pj_ice_sess_check *c = &ice->clist.checks[j];\n\t    if (c->lcand->transport_id == vc->lcand->transport_id &&\n\t\tc->rcand == vc->rcand)\n\t    {\n\t\tpj_assert(c->err_code == PJ_SUCCESS);\n\t\tc->state = PJ_ICE_SESS_CHECK_STATE_FROZEN;\n\t\tcheck_set_state(ice, c, PJ_ICE_SESS_CHECK_STATE_WAITING, \n\t\t\t        PJ_SUCCESS);\n\t\tbreak;\n\t    }\n\t}\n    }\n\n    /* And (re)start the periodic check */\n    pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap,\n                                   &ice->clist.timer, PJ_FALSE);\n\n    delay.sec = delay.msec = 0;\n    status = pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,\n                                               &ice->clist.timer, &delay,\n                                               PJ_TRUE,\n                                               ice->grp_lock);\n    if (status == PJ_SUCCESS) {\n\tLOG5((ice->obj_name, \"Periodic timer rescheduled..\"));\n    }\n\n    ice->is_nominating = PJ_TRUE;\n    pj_log_pop_indent();\n}\n\n/* Timer callback to perform periodic check */\nstatic void periodic_timer(pj_timer_heap_t *th, \n\t\t\t   pj_timer_entry *te)\n{\n    start_periodic_check(th, te);\n}\n\n\n/* Utility: find string in string array */\nstatic const pj_str_t *find_str(const pj_str_t *strlist[], unsigned count,\n\t\t\t\tconst pj_str_t *str)\n{\n    unsigned i;\n    for (i=0; i<count; ++i) {\n\tif (pj_strcmp(strlist[i], str)==0)\n\t    return strlist[i];\n    }\n    return NULL;\n}\n\n\n/*\n * Start ICE periodic check. This function will return immediately, and\n * application will be notified about the connectivity check status in\n * #pj_ice_sess_cb callback.\n */\nPJ_DEF(pj_status_t) pj_ice_sess_start_check(pj_ice_sess *ice)\n{\n    pj_ice_sess_checklist *clist;\n    const pj_ice_sess_cand *cand0;\n    const pj_str_t *flist[PJ_ICE_MAX_CAND]; // XXX\n    pj_ice_rx_check *rcheck;\n    unsigned i, flist_cnt = 0;\n    pj_time_val delay;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(ice, PJ_EINVAL);\n\n    /* Checklist must have been created */\n    PJ_ASSERT_RETURN(ice->clist.count > 0, PJ_EINVALIDOP);\n\n    /* Lock session */\n    pj_grp_lock_acquire(ice->grp_lock);\n\n    LOG4((ice->obj_name, \"Starting ICE check..\"));\n    pj_log_push_indent();\n\n    /* If we are using aggressive nomination, set the is_nominating state */\n    if (ice->opt.aggressive)\n\tice->is_nominating = PJ_TRUE;\n\n    /* The agent examines the check list for the first media stream (a\n     * media stream is the first media stream when it is described by\n     * the first m-line in the SDP offer and answer).  For that media\n     * stream, it:\n     * \n     * -  Groups together all of the pairs with the same foundation,\n     * \n     * -  For each group, sets the state of the pair with the lowest\n     *    component ID to Waiting.  If there is more than one such pair,\n     *    the one with the highest priority is used.\n     */\n\n    clist = &ice->clist;\n\n    /* Pickup the first pair for component 1. */\n    for (i=0; i<clist->count; ++i) {\n\tif (clist->checks[i].lcand->comp_id == 1)\n\t    break;\n    }\n    if (i == clist->count) {\n\tpj_assert(!\"Unable to find checklist for component 1\");\n\tpj_grp_lock_release(ice->grp_lock);\n\tpj_log_pop_indent();\n\treturn PJNATH_EICEINCOMPID;\n    }\n\n    /* Set this check to WAITING only if state is frozen. It may be possible\n     * that this check has already been started by a trigger check\n     */\n    if (clist->checks[i].state == PJ_ICE_SESS_CHECK_STATE_FROZEN) {\n\tcheck_set_state(ice, &clist->checks[i], \n\t\t\tPJ_ICE_SESS_CHECK_STATE_WAITING, PJ_SUCCESS);\n    }\n\n    cand0 = clist->checks[i].lcand;\n    flist[flist_cnt++] = &clist->checks[i].lcand->foundation;\n\n    /* Find all of the other pairs in that check list with the same\n     * component ID, but different foundations, and sets all of their\n     * states to Waiting as well.\n     */\n    for (++i; i<clist->count; ++i) {\n\tconst pj_ice_sess_cand *cand1;\n\n\tcand1 = clist->checks[i].lcand;\n\n\tif (cand1->comp_id==cand0->comp_id &&\n\t    find_str(flist, flist_cnt, &cand1->foundation)==NULL)\n\t{\n\t    if (clist->checks[i].state == PJ_ICE_SESS_CHECK_STATE_FROZEN) {\n\t\tcheck_set_state(ice, &clist->checks[i], \n\t\t\t\tPJ_ICE_SESS_CHECK_STATE_WAITING, PJ_SUCCESS);\n\t    }\n\t    flist[flist_cnt++] = &cand1->foundation;\n\t}\n    }\n\n    /* First, perform all pending triggered checks, simultaneously. */\n    rcheck = ice->early_check.next;\n    while (rcheck != &ice->early_check) {\n\tLOG4((ice->obj_name, \n\t      \"Performing delayed triggerred check for component %d\",\n\t      rcheck->comp_id));\n\tpj_log_push_indent();\n\thandle_incoming_check(ice, rcheck);\n\trcheck = rcheck->next;\n\tpj_log_pop_indent();\n    }\n    pj_list_init(&ice->early_check);\n\n    /* Start periodic check */\n    /* We could start it immediately like below, but lets schedule timer \n     * instead to reduce stack usage:\n     * return start_periodic_check(ice->stun_cfg.timer_heap, &clist->timer);\n     */\n    delay.sec = delay.msec = 0;\n    status = pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,\n                                               &clist->timer, &delay,\n                                               PJ_TRUE, ice->grp_lock);\n    if (status != PJ_SUCCESS) {\n\tclist->timer.id = PJ_FALSE;\n    }\n\n    pj_grp_lock_release(ice->grp_lock);\n    pj_log_pop_indent();\n    return status;\n}\n\n\n//////////////////////////////////////////////////////////////////////////////\n\n/* Callback called by STUN session to send the STUN message.\n * STUN session also doesn't have a transport, remember?!\n */\nstatic pj_status_t on_stun_send_msg(pj_stun_session *sess,\n\t\t\t\t    void *token,\n\t\t\t\t    const void *pkt,\n\t\t\t\t    pj_size_t pkt_size,\n\t\t\t\t    const pj_sockaddr_t *dst_addr,\n\t\t\t\t    unsigned addr_len)\n{\n    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess);\n    pj_ice_sess *ice = sd->ice;\n    pj_ice_msg_data *msg_data = (pj_ice_msg_data*) token;\n    pj_status_t status;\n    \n    pj_grp_lock_acquire(ice->grp_lock);\n\n    if (ice->is_destroying) {\n\t/* Stray retransmit timer that could happen while\n\t * we're being destroyed */\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    status = (*ice->cb.on_tx_pkt)(ice, sd->comp_id, msg_data->transport_id,\n\t\t\t\t  pkt, pkt_size, dst_addr, addr_len);\n\n    pj_grp_lock_release(ice->grp_lock);\n    return status;\n}\n\n\n/* This callback is called when outgoing STUN request completed */\nstatic void on_stun_request_complete(pj_stun_session *stun_sess,\n\t\t\t\t     pj_status_t status,\n\t\t\t\t     void *token,\n\t\t\t\t     pj_stun_tx_data *tdata,\n\t\t\t\t     const pj_stun_msg *response,\n\t\t\t\t     const pj_sockaddr_t *src_addr,\n\t\t\t\t     unsigned src_addr_len)\n{\n    pj_ice_msg_data *msg_data = (pj_ice_msg_data*) token;\n    pj_ice_sess *ice;\n    pj_ice_sess_check *check, *new_check;\n    pj_ice_sess_cand *lcand;\n    pj_ice_sess_checklist *clist;\n    pj_stun_xor_mapped_addr_attr *xaddr;\n    unsigned i;\n\n    PJ_UNUSED_ARG(stun_sess);\n    PJ_UNUSED_ARG(src_addr_len);\n\n    pj_assert(msg_data->has_req_data);\n\n    ice = msg_data->data.req.ice;\n    clist = msg_data->data.req.clist;\n    check = &clist->checks[msg_data->data.req.ckid];\n    \n\n    /* Mark STUN transaction as complete */\n    pj_assert(tdata == check->tdata);\n    check->tdata = NULL;\n\n    pj_grp_lock_acquire(ice->grp_lock);\n\n    if (ice->is_destroying) {\n\t/* Not sure if this is possible but just in case */\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn;\n    }\n\n    /* Init lcand to NULL. lcand will be found from the mapped address\n     * found in the response.\n     */\n    lcand = NULL;\n\n    if (status != PJ_SUCCESS) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\n\tif (status==PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_ROLE_CONFLICT)) {\n\n\t    /* Role conclict response.\n\t     *\n\t     * 7.1.2.1.  Failure Cases:\n\t     *\n\t     * If the request had contained the ICE-CONTROLLED attribute, \n\t     * the agent MUST switch to the controlling role if it has not\n\t     * already done so.  If the request had contained the \n\t     * ICE-CONTROLLING attribute, the agent MUST switch to the \n\t     * controlled role if it has not already done so.  Once it has\n\t     * switched, the agent MUST immediately retry the request with\n\t     * the ICE-CONTROLLING or ICE-CONTROLLED attribute reflecting \n\t     * its new role.\n\t     */\n\t    pj_ice_sess_role new_role = PJ_ICE_SESS_ROLE_UNKNOWN;\n\t    pj_stun_msg *req = tdata->msg;\n\n\t    if (pj_stun_msg_find_attr(req, PJ_STUN_ATTR_ICE_CONTROLLING, 0)) {\n\t\tnew_role = PJ_ICE_SESS_ROLE_CONTROLLED;\n\t    } else if (pj_stun_msg_find_attr(req, PJ_STUN_ATTR_ICE_CONTROLLED, \n\t\t\t\t\t     0)) {\n\t\tnew_role = PJ_ICE_SESS_ROLE_CONTROLLING;\n\t    } else {\n\t\tpj_assert(!\"We should have put CONTROLLING/CONTROLLED attr!\");\n\t\tnew_role = PJ_ICE_SESS_ROLE_CONTROLLED;\n\t    }\n\n\t    if (new_role != ice->role) {\n\t\tLOG4((ice->obj_name, \n\t\t      \"Changing role because of role conflict response\"));\n\t\tpj_ice_sess_change_role(ice, new_role);\n\t    }\n\n\t    /* Resend request */\n\t    LOG4((ice->obj_name, \"Resending check because of role conflict\"));\n\t    pj_log_push_indent();\n\t    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_WAITING, 0);\n\t    perform_check(ice, clist, msg_data->data.req.ckid, \n\t\t\t  check->nominated || ice->is_nominating);\n\t    pj_log_pop_indent();\n\t    pj_grp_lock_release(ice->grp_lock);\n\t    return;\n\t}\n\n\tpj_strerror(status, errmsg, sizeof(errmsg));\n\tLOG4((ice->obj_name, \n\t     \"Check %s%s: connectivity check FAILED: %s\",\n\t     dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), \n\t\t\t&ice->clist, check),\n\t     (check->nominated ? \" (nominated)\" : \" (not nominated)\"),\n\t     errmsg));\n\tpj_log_push_indent();\n\tcheck_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, status);\n\ton_check_complete(ice, check);\n\tpj_log_pop_indent();\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn;\n    }\n\n\n    /* 7.1.2.1.  Failure Cases\n     *\n     * The agent MUST check that the source IP address and port of the\n     * response equals the destination IP address and port that the Binding\n     * Request was sent to, and that the destination IP address and port of\n     * the response match the source IP address and port that the Binding\n     * Request was sent from.\n     */\n    if (pj_sockaddr_cmp(&check->rcand->addr, (const pj_sockaddr*)src_addr)!=0)\n    {\n\tstatus = PJNATH_EICEINSRCADDR;\n\tLOG4((ice->obj_name, \n\t     \"Check %s%s: connectivity check FAILED: source address mismatch\",\n\t     dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), \n\t\t\t&ice->clist, check),\n\t     (check->nominated ? \" (nominated)\" : \" (not nominated)\")));\n\tpj_log_push_indent();\n\tcheck_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, status);\n\ton_check_complete(ice, check);\n\tpj_log_pop_indent();\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn;\n    }\n\n    /* 7.1.2.2.  Success Cases\n     * \n     * A check is considered to be a success if all of the following are\n     * true:\n     * \n     * o  the STUN transaction generated a success response\n     * \n     * o  the source IP address and port of the response equals the\n     *    destination IP address and port that the Binding Request was sent\n     *    to\n     * \n     * o  the destination IP address and port of the response match the\n     *    source IP address and port that the Binding Request was sent from\n     */\n\n\n    LOG4((ice->obj_name, \n\t \"Check %s%s: connectivity check SUCCESS\",\n\t dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), \n\t\t    &ice->clist, check),\n\t (check->nominated ? \" (nominated)\" : \" (not nominated)\")));\n\n    /* Get the STUN XOR-MAPPED-ADDRESS attribute. */\n    xaddr = (pj_stun_xor_mapped_addr_attr*)\n\t    pj_stun_msg_find_attr(response, PJ_STUN_ATTR_XOR_MAPPED_ADDR,0);\n    if (!xaddr) {\n\tcheck_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, \n\t\t\tPJNATH_ESTUNNOMAPPEDADDR);\n\ton_check_complete(ice, check);\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn;\n    }\n\n    /* Find local candidate that matches the XOR-MAPPED-ADDRESS */\n    pj_assert(lcand == NULL);\n    for (i=0; i<ice->lcand_cnt; ++i) {\n\t/* Ticket #1891: apply additional check as there may be a shared\n\t * mapped address for different base/local addresses.\n\t */\n\tif (pj_sockaddr_cmp(&xaddr->sockaddr, &ice->lcand[i].addr) == 0 &&\n\t    pj_sockaddr_cmp(&check->lcand->base_addr,\n\t\t\t    &ice->lcand[i].base_addr) == 0)\n\t{\n\t    /* Match */\n\t    lcand = &ice->lcand[i];\n\t    break;\n\t}\n    }\n\n    /* 7.1.2.2.1.  Discovering Peer Reflexive Candidates\n     * If the transport address returned in XOR-MAPPED-ADDRESS does not match\n     * any of the local candidates that the agent knows about, the mapped \n     * address represents a new candidate - a peer reflexive candidate.\n     */\n    if (lcand == NULL) {\n\tunsigned cand_id;\n\tpj_str_t foundation;\n\n\tpj_ice_calc_foundation(ice->pool, &foundation, PJ_ICE_CAND_TYPE_PRFLX,\n\t\t\t       &check->lcand->base_addr);\n\n\t/* Still in 7.1.2.2.1.  Discovering Peer Reflexive Candidates\n\t * Its priority is set equal to the value of the PRIORITY attribute\n         * in the Binding Request.\n\t *\n\t * I think the priority calculated by add_cand() should be the same\n\t * as the one calculated in perform_check(), so there's no need to\n\t * get the priority from the PRIORITY attribute.\n\t */\n\n\t/* Add new peer reflexive candidate */\n\tstatus = pj_ice_sess_add_cand(ice, check->lcand->comp_id, \n\t\t\t\t      msg_data->transport_id,\n\t\t\t\t      PJ_ICE_CAND_TYPE_PRFLX,\n\t\t\t\t      65535, &foundation,\n\t\t\t\t      &xaddr->sockaddr, \n\t\t\t\t      &check->lcand->base_addr, \n\t\t\t\t      &check->lcand->base_addr,\n\t\t\t\t      pj_sockaddr_get_len(&xaddr->sockaddr),\n\t\t\t\t      &cand_id);\n\tif (status != PJ_SUCCESS) {\n\t    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, \n\t\t\t    status);\n\t    on_check_complete(ice, check);\n\t    pj_grp_lock_release(ice->grp_lock);\n\t    return;\n\t}\n\n\t/* Update local candidate */\n\tlcand = &ice->lcand[cand_id];\n\n    }\n\n    /* 7.1.2.2.3.  Constructing a Valid Pair\n     * Next, the agent constructs a candidate pair whose local candidate\n     * equals the mapped address of the response, and whose remote candidate\n     * equals the destination address to which the request was sent.    \n     */\n\n    /* Add pair to valid list, if it's not there, otherwise just update\n     * nominated flag\n     */\n    for (i=0; i<ice->valid_list.count; ++i) {\n\tif (ice->valid_list.checks[i].lcand == lcand &&\n\t    ice->valid_list.checks[i].rcand == check->rcand)\n\t    break;\n    }\n\n    if (i==ice->valid_list.count) {\n\tpj_assert(ice->valid_list.count < PJ_ICE_MAX_CHECKS);\n\tnew_check = &ice->valid_list.checks[ice->valid_list.count++];\n\tnew_check->lcand = lcand;\n\tnew_check->rcand = check->rcand;\n\tnew_check->prio = CALC_CHECK_PRIO(ice, lcand, check->rcand);\n\tnew_check->state = PJ_ICE_SESS_CHECK_STATE_SUCCEEDED;\n\tnew_check->nominated = check->nominated;\n\tnew_check->err_code = PJ_SUCCESS;\n    } else {\n\tnew_check = &ice->valid_list.checks[i];\n\tice->valid_list.checks[i].nominated = check->nominated;\n    }\n\n    /* Update valid check and nominated check for the component */\n    update_comp_check(ice, new_check->lcand->comp_id, new_check);\n\n    /* Sort valid_list (must do so after update_comp_check(), otherwise\n     * new_check will point to something else (#953)\n     */\n    sort_checklist(ice, &ice->valid_list);\n\n    /* 7.1.2.2.2.  Updating Pair States\n     * \n     * The agent sets the state of the pair that generated the check to\n     * Succeeded.  The success of this check might also cause the state of\n     * other checks to change as well.\n     */\n    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_SUCCEEDED, \n\t\t    PJ_SUCCESS);\n\n    /* Perform 7.1.2.2.2.  Updating Pair States.\n     * This may terminate ICE processing.\n     */\n    if (on_check_complete(ice, check)) {\n\t/* ICE complete! */\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn;\n    }\n\n    pj_grp_lock_release(ice->grp_lock);\n}\n\n\n/* This callback is called by the STUN session associated with a candidate\n * when it receives incoming request.\n */\nstatic pj_status_t on_stun_rx_request(pj_stun_session *sess,\n\t\t\t\t      const pj_uint8_t *pkt,\n\t\t\t\t      unsigned pkt_len,\n\t\t\t\t      const pj_stun_rx_data *rdata,\n\t\t\t\t      void *token,\n\t\t\t\t      const pj_sockaddr_t *src_addr,\n\t\t\t\t      unsigned src_addr_len)\n{\n    stun_data *sd;\n    const pj_stun_msg *msg = rdata->msg;\n    pj_ice_msg_data *msg_data;\n    pj_ice_sess *ice;\n    pj_stun_priority_attr *prio_attr;\n    pj_stun_use_candidate_attr *uc_attr;\n    pj_stun_uint64_attr *role_attr;\n    pj_stun_tx_data *tdata;\n    pj_ice_rx_check *rcheck, tmp_rcheck;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(pkt);\n    PJ_UNUSED_ARG(pkt_len);\n    \n    /* Reject any requests except Binding request */\n    if (msg->hdr.type != PJ_STUN_BINDING_REQUEST) {\n\tpj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST, \n\t\t\t\tNULL, token, PJ_TRUE, \n\t\t\t\tsrc_addr, src_addr_len);\n\treturn PJ_SUCCESS;\n    }\n\n\n    sd = (stun_data*) pj_stun_session_get_user_data(sess);\n    ice = sd->ice;\n\n    pj_grp_lock_acquire(ice->grp_lock);\n\n    if (ice->is_destroying) {\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    /*\n     * Note:\n     *  Be aware that when STUN request is received, we might not get\n     *  SDP answer yet, so we might not have remote candidates and\n     *  checklist yet. This case will be handled after we send\n     *  a response.\n     */\n\n    /* Get PRIORITY attribute */\n    prio_attr = (pj_stun_priority_attr*)\n\t        pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_PRIORITY, 0);\n    if (prio_attr == NULL) {\n\tLOG5((ice->obj_name, \"Received Binding request with no PRIORITY\"));\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn PJ_SUCCESS;\n    }\n\n    /* Get USE-CANDIDATE attribute */\n    uc_attr = (pj_stun_use_candidate_attr*)\n\t      pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_USE_CANDIDATE, 0);\n\n\n    /* Get ICE-CONTROLLING or ICE-CONTROLLED */\n    role_attr = (pj_stun_uint64_attr*)\n\t        pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ICE_CONTROLLING, 0);\n    if (role_attr == NULL) {\n\trole_attr = (pj_stun_uint64_attr*)\n\t            pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ICE_CONTROLLED, 0);\n    }\n\n    /* Handle the case when request comes before answer is received.\n     * We need to put credential in the response, and since we haven't\n     * got the response, copy the username from the request.\n     */\n    if (ice->rcand_cnt == 0) {\n\tpj_stun_string_attr *uname_attr;\n\n\tuname_attr = (pj_stun_string_attr*)\n\t\t     pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_USERNAME, 0);\n\tpj_assert(uname_attr != NULL);\n\tpj_strdup(ice->pool, &ice->rx_uname, &uname_attr->value);\n    }\n\n    /* 7.2.1.1.  Detecting and Repairing Role Conflicts\n     */\n    if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLING &&\n\trole_attr && role_attr->hdr.type == PJ_STUN_ATTR_ICE_CONTROLLING)\n    {\n\tif (pj_cmp_timestamp(&ice->tie_breaker, &role_attr->value) < 0) {\n\t    /* Switch role to controlled */\n\t    LOG4((ice->obj_name, \n\t\t  \"Changing role because of ICE-CONTROLLING attribute\"));\n\t    pj_ice_sess_change_role(ice, PJ_ICE_SESS_ROLE_CONTROLLED);\n\t} else {\n\t    /* Generate 487 response */\n\t    pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT, \n\t\t\t\t    NULL, token, PJ_TRUE, \n\t\t\t\t    src_addr, src_addr_len);\n\t    pj_grp_lock_release(ice->grp_lock);\n\t    return PJ_SUCCESS;\n\t}\n\n    } else if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLED &&\n\t       role_attr && role_attr->hdr.type == PJ_STUN_ATTR_ICE_CONTROLLED)\n    {\n\tif (pj_cmp_timestamp(&ice->tie_breaker, &role_attr->value) < 0) {\n\t    /* Generate 487 response */\n\t    pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT, \n\t\t\t\t    NULL, token, PJ_TRUE, \n\t\t\t\t    src_addr, src_addr_len);\n\t    pj_grp_lock_release(ice->grp_lock);\n\t    return PJ_SUCCESS;\n\t} else {\n\t    /* Switch role to controlled */\n\t    LOG4((ice->obj_name, \n\t\t  \"Changing role because of ICE-CONTROLLED attribute\"));\n\t    pj_ice_sess_change_role(ice, PJ_ICE_SESS_ROLE_CONTROLLING);\n\t}\n    }\n\n    /* \n     * First send response to this request \n     */\n    status = pj_stun_session_create_res(sess, rdata, 0, NULL, &tdata);\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn status;\n    }\n\n    /* Add XOR-MAPPED-ADDRESS attribute */\n    status = pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, \n\t\t\t\t\t   PJ_STUN_ATTR_XOR_MAPPED_ADDR,\n\t\t\t\t\t   PJ_TRUE, src_addr, src_addr_len);\n\n    /* Create a msg_data to be associated with this response */\n    msg_data = PJ_POOL_ZALLOC_T(tdata->pool, pj_ice_msg_data);\n    msg_data->transport_id = ((pj_ice_msg_data*)token)->transport_id;\n    msg_data->has_req_data = PJ_FALSE;\n\n    /* Send the response */\n    status = pj_stun_session_send_msg(sess, msg_data, PJ_TRUE, PJ_TRUE,\n\t\t\t\t      src_addr, src_addr_len, tdata);\n\n\n    /* \n     * Handling early check.\n     *\n     * It's possible that we receive this request before we receive SDP\n     * answer. In this case, we can't perform trigger check since we\n     * don't have checklist yet, so just save this check in a pending\n     * triggered check array to be acted upon later.\n     */\n    if (ice->rcand_cnt == 0) {\n\trcheck = PJ_POOL_ZALLOC_T(ice->pool, pj_ice_rx_check);\n    } else {\n\trcheck = &tmp_rcheck;\n    }\n\n    /* Init rcheck */\n    rcheck->comp_id = sd->comp_id;\n    rcheck->transport_id = ((pj_ice_msg_data*)token)->transport_id;\n    rcheck->src_addr_len = src_addr_len;\n    pj_sockaddr_cp(&rcheck->src_addr, src_addr);\n    rcheck->use_candidate = (uc_attr != NULL);\n    rcheck->priority = prio_attr->value;\n    rcheck->role_attr = role_attr;\n\n    if (ice->rcand_cnt == 0) {\n\t/* We don't have answer yet, so keep this request for later */\n\tLOG4((ice->obj_name, \"Received an early check for comp %d\",\n\t      rcheck->comp_id));\n\tpj_list_push_back(&ice->early_check, rcheck);\n    } else {\n\t/* Handle this check */\n\thandle_incoming_check(ice, rcheck);\n    }\n\n    pj_grp_lock_release(ice->grp_lock);\n    return PJ_SUCCESS;\n}\n\n\n/* Handle incoming Binding request and perform triggered check.\n * This function may be called by on_stun_rx_request(), or when\n * SDP answer is received and we have received early checks.\n */\nstatic void handle_incoming_check(pj_ice_sess *ice,\n\t\t\t\t  const pj_ice_rx_check *rcheck)\n{\n    pj_ice_sess_comp *comp;\n    pj_ice_sess_cand *lcand = NULL;\n    pj_ice_sess_cand *rcand;\n    unsigned i;\n\n    comp = find_comp(ice, rcheck->comp_id);\n\n    /* Find remote candidate based on the source transport address of \n     * the request.\n     */\n    for (i=0; i<ice->rcand_cnt; ++i) {\n\tif (pj_sockaddr_cmp(&rcheck->src_addr, &ice->rcand[i].addr)==0)\n\t    break;\n    }\n\n    /* 7.2.1.3.  Learning Peer Reflexive Candidates\n     * If the source transport address of the request does not match any\n     * existing remote candidates, it represents a new peer reflexive remote\n     * candidate.\n     */\n    if (i == ice->rcand_cnt) {\n\tchar raddr[PJ_INET6_ADDRSTRLEN];\n\tif (ice->rcand_cnt >= PJ_ICE_MAX_CAND) {\n\t    LOG4((ice->obj_name, \n\t          \"Unable to add new peer reflexive candidate: too many \"\n\t\t  \"candidates already (%d)\", PJ_ICE_MAX_CAND));\n\t    return;\n\t}\n\n\trcand = &ice->rcand[ice->rcand_cnt++];\n\trcand->comp_id = (pj_uint8_t)rcheck->comp_id;\n\trcand->type = PJ_ICE_CAND_TYPE_PRFLX;\n\trcand->prio = rcheck->priority;\n\tpj_sockaddr_cp(&rcand->addr, &rcheck->src_addr);\n\n\t/* Foundation is random, unique from other foundation */\n\trcand->foundation.ptr = (char*) pj_pool_alloc(ice->pool, 36);\n\trcand->foundation.slen = pj_ansi_snprintf(rcand->foundation.ptr, 36,\n\t\t\t\t\t\t  \"f%p\", \n\t\t\t\t\t\t  rcand->foundation.ptr);\n\n\tLOG4((ice->obj_name, \n\t      \"Added new remote candidate from the request: %s:%d\",\n\t      pj_sockaddr_print(&rcand->addr, raddr, sizeof(raddr), 0),\n\t      pj_sockaddr_get_port(&rcand->addr)));\n\n    } else {\n\t/* Remote candidate found */\n\trcand = &ice->rcand[i];\n    }\n\n#if 0\n    /* Find again the local candidate by matching the base address\n     * with the local candidates in the checklist. Checks may have\n     * been pruned before, so it's possible that if we use the lcand\n     * as it is, we wouldn't be able to find the check in the checklist\n     * and we will end up creating a new check unnecessarily.\n     */\n    for (i=0; i<ice->clist.count; ++i) {\n\tpj_ice_sess_check *c = &ice->clist.checks[i];\n\tif (/*c->lcand == lcand ||*/\n\t    pj_sockaddr_cmp(&c->lcand->base_addr, &lcand->base_addr)==0)\n\t{\n\t    lcand = c->lcand;\n\t    break;\n\t}\n    }\n#else\n    /* Just get candidate with the highest priority and same transport ID\n     * for the specified  component ID in the checklist.\n     */\n    for (i=0; i<ice->clist.count; ++i) {\n\tpj_ice_sess_check *c = &ice->clist.checks[i];\n\tif (c->lcand->comp_id == rcheck->comp_id &&\n\t    c->lcand->transport_id == rcheck->transport_id) \n\t{\n\t    lcand = c->lcand;\n\t    break;\n\t}\n    }\n    if (lcand == NULL) {\n\t/* Should not happen, but just in case remote is sending a\n\t * Binding request for a component which it doesn't have.\n\t */\n\tLOG4((ice->obj_name, \n\t     \"Received Binding request but no local candidate is found!\"));\n\treturn;\n    }\n#endif\n\n    /* \n     * Create candidate pair for this request. \n     */\n\n    /* \n     * 7.2.1.4.  Triggered Checks\n     *\n     * Now that we have local and remote candidate, check if we already\n     * have this pair in our checklist.\n     */\n    for (i=0; i<ice->clist.count; ++i) {\n\tpj_ice_sess_check *c = &ice->clist.checks[i];\n\tif (c->lcand == lcand && c->rcand == rcand)\n\t    break;\n    }\n\n    /* If the pair is already on the check list:\n     * - If the state of that pair is Waiting or Frozen, its state is\n     *   changed to In-Progress and a check for that pair is performed\n     *   immediately.  This is called a triggered check.\n     *\n     * - If the state of that pair is In-Progress, the agent SHOULD\n     *   generate an immediate retransmit of the Binding Request for the\n     *   check in progress.  This is to facilitate rapid completion of\n     *   ICE when both agents are behind NAT.\n     * \n     * - If the state of that pair is Failed or Succeeded, no triggered\n     *   check is sent.\n     */\n    if (i != ice->clist.count) {\n\tpj_ice_sess_check *c = &ice->clist.checks[i];\n\n\t/* If USE-CANDIDATE is present, set nominated flag \n\t * Note: DO NOT overwrite nominated flag if one is already set.\n\t */\n\tc->nominated = ((rcheck->use_candidate) || c->nominated);\n\n\tif (c->state == PJ_ICE_SESS_CHECK_STATE_FROZEN ||\n\t    c->state == PJ_ICE_SESS_CHECK_STATE_WAITING)\n\t{\n\t    /* See if we shall nominate this check */\n\t    pj_bool_t nominate = (c->nominated || ice->is_nominating);\n\n\t    LOG5((ice->obj_name, \"Performing triggered check for check %d\",i));\n\t    pj_log_push_indent();\n\t    perform_check(ice, &ice->clist, i, nominate);\n\t    pj_log_pop_indent();\n\n\t} else if (c->state == PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS) {\n\t    /* Should retransmit immediately\n\t     */\n\t    LOG5((ice->obj_name, \"Triggered check for check %d not performed \"\n\t\t  \"because it's in progress. Retransmitting\", i));\n\t    pj_log_push_indent();\n\t    pj_stun_session_retransmit_req(comp->stun_sess, c->tdata, PJ_FALSE);\n\t    pj_log_pop_indent();\n\n\t} else if (c->state == PJ_ICE_SESS_CHECK_STATE_SUCCEEDED) {\n\t    /* Check complete for this component.\n\t     * Note this may end ICE process.\n\t     */\n\t    pj_bool_t complete;\n\t    unsigned j;\n\n\t    /* If this check is nominated, scan the valid_list for the\n\t     * same check and update the nominated flag. A controlled \n\t     * agent might have finished the check earlier.\n\t     */\n\t    if (rcheck->use_candidate) {\n\t\tfor (j=0; j<ice->valid_list.count; ++j) {\n\t\t    pj_ice_sess_check *vc = &ice->valid_list.checks[j];\n\t\t    if (vc->lcand->transport_id == c->lcand->transport_id && \n\t\t\tvc->rcand == c->rcand) \n\t\t    {\n\t\t\t/* Set nominated flag */\n\t\t\tvc->nominated = PJ_TRUE;\n\n\t\t\t/* Update valid check and nominated check for the component */\n\t\t\tupdate_comp_check(ice, vc->lcand->comp_id, vc);\n\n\t\t\tLOG5((ice->obj_name, \"Valid check %s is nominated\", \n\t\t\t      dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), \n\t\t\t\t\t &ice->valid_list, vc)));\n\t\t    }\n\t\t}\n\t    }\n\n\t    LOG5((ice->obj_name, \"Triggered check for check %d not performed \"\n\t\t\t\t\"because it's completed\", i));\n\t    pj_log_push_indent();\n\t    complete = on_check_complete(ice, c);\n\t    pj_log_pop_indent();\n\t    if (complete) {\n\t\treturn;\n\t    }\n\t}\n\n    }\n    /* If the pair is not already on the check list:\n     * - The pair is inserted into the check list based on its priority.\n     * - Its state is set to In-Progress\n     * - A triggered check for that pair is performed immediately.\n     */\n    /* Note: only do this if we don't have too many checks in checklist */\n    else if (ice->clist.count < PJ_ICE_MAX_CHECKS) {\n\n\tpj_ice_sess_check *c = &ice->clist.checks[ice->clist.count];\n\tpj_bool_t nominate;\n\n\tc->lcand = lcand;\n\tc->rcand = rcand;\n\tc->prio = CALC_CHECK_PRIO(ice, lcand, rcand);\n\tc->state = PJ_ICE_SESS_CHECK_STATE_WAITING;\n\tc->nominated = rcheck->use_candidate;\n\tc->err_code = PJ_SUCCESS;\n\n\tnominate = (c->nominated || ice->is_nominating);\n\n\tLOG4((ice->obj_name, \"New triggered check added: %d\", \n\t     ice->clist.count));\n\tpj_log_push_indent();\n\tperform_check(ice, &ice->clist, ice->clist.count++, nominate);\n\tpj_log_pop_indent();\n\n    } else {\n\tLOG4((ice->obj_name, \"Error: unable to perform triggered check: \"\n\t     \"TOO MANY CHECKS IN CHECKLIST!\"));\n    }\n}\n\n\nstatic pj_status_t on_stun_rx_indication(pj_stun_session *sess,\n\t\t\t\t\t const pj_uint8_t *pkt,\n\t\t\t\t\t unsigned pkt_len,\n\t\t\t\t\t const pj_stun_msg *msg,\n\t\t\t\t\t void *token,\n\t\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t\t unsigned src_addr_len)\n{\n    struct stun_data *sd;\n\n    PJ_UNUSED_ARG(sess);\n    PJ_UNUSED_ARG(pkt);\n    PJ_UNUSED_ARG(pkt_len);\n    PJ_UNUSED_ARG(msg);\n    PJ_UNUSED_ARG(token);\n    PJ_UNUSED_ARG(src_addr);\n    PJ_UNUSED_ARG(src_addr_len);\n\n    sd = (struct stun_data*) pj_stun_session_get_user_data(sess);\n\n    pj_log_push_indent();\n\n    if (msg->hdr.type == PJ_STUN_BINDING_INDICATION) {\n\tLOG5((sd->ice->obj_name, \"Received Binding Indication keep-alive \"\n\t      \"for component %d\", sd->comp_id));\n    } else {\n\tLOG4((sd->ice->obj_name, \"Received unexpected %s indication \"\n\t      \"for component %d\", pj_stun_get_method_name(msg->hdr.type), \n\t      sd->comp_id));\n    }\n\n    pj_log_pop_indent();\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_ice_sess_send_data(pj_ice_sess *ice,\n\t\t\t\t\t  unsigned comp_id,\n\t\t\t\t\t  const void *data,\n\t\t\t\t\t  pj_size_t data_len)\n{\n    pj_status_t status = PJ_SUCCESS;\n    pj_ice_sess_comp *comp;\n    pj_ice_sess_cand *cand;\n    pj_uint8_t transport_id;\n    pj_sockaddr addr;\n\n    PJ_ASSERT_RETURN(ice && comp_id, PJ_EINVAL);\n    \n    /* It is possible that comp_cnt is less than comp_id, when remote\n     * doesn't support all the components that we have.\n     */\n    if (comp_id > ice->comp_cnt) {\n\treturn PJNATH_EICEINCOMPID;\n    }\n\n    pj_grp_lock_acquire(ice->grp_lock);\n\n    if (ice->is_destroying) {\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    comp = find_comp(ice, comp_id);\n    if (comp == NULL) {\n\tstatus = PJNATH_EICEINCOMPID;\n\tpj_grp_lock_release(ice->grp_lock);\n\tgoto on_return;\n    }\n\n    if (comp->valid_check == NULL) {\n\tstatus = PJNATH_EICEINPROGRESS;\n\tpj_grp_lock_release(ice->grp_lock);\n\tgoto on_return;\n    }\n\n    cand = comp->valid_check->lcand;\n    transport_id = cand->transport_id;\n    pj_sockaddr_cp(&addr, &comp->valid_check->rcand->addr);\n\n    /* Release the mutex now to avoid deadlock (see ticket #1451). */\n    pj_grp_lock_release(ice->grp_lock);\n\n    PJ_RACE_ME(5);\n\n    status = (*ice->cb.on_tx_pkt)(ice, comp_id, transport_id, \n\t\t\t\t  data, data_len, \n\t\t\t\t  &addr, \n\t\t\t\t  pj_sockaddr_get_len(&addr));\n\non_return:\n    return status;\n}\n\n\nPJ_DEF(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice,\n\t\t\t\t\t  unsigned comp_id,\n\t\t\t\t\t  unsigned transport_id,\n\t\t\t\t\t  void *pkt,\n\t\t\t\t\t  pj_size_t pkt_size,\n\t\t\t\t\t  const pj_sockaddr_t *src_addr,\n\t\t\t\t\t  int src_addr_len)\n{\n    pj_status_t status = PJ_SUCCESS;\n    pj_ice_sess_comp *comp;\n    pj_ice_msg_data *msg_data = NULL;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(ice, PJ_EINVAL);\n\n    pj_grp_lock_acquire(ice->grp_lock);\n\n    if (ice->is_destroying) {\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    comp = find_comp(ice, comp_id);\n    if (comp == NULL) {\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn PJNATH_EICEINCOMPID;\n    }\n\n    /* Find transport */\n    for (i=0; i<PJ_ARRAY_SIZE(ice->tp_data); ++i) {\n\tif (ice->tp_data[i].transport_id == transport_id) {\n\t    msg_data = &ice->tp_data[i];\n\t    break;\n\t}\n    }\n    if (msg_data == NULL) {\n\tpj_assert(!\"Invalid transport ID\");\n\tpj_grp_lock_release(ice->grp_lock);\n\treturn PJ_EINVAL;\n    }\n\n    /* Don't check fingerprint. We only need to distinguish STUN and non-STUN\n     * packets. We don't need to verify the STUN packet too rigorously, that\n     * will be done by the user.\n     */\n    status = pj_stun_msg_check((const pj_uint8_t*)pkt, pkt_size, \n    \t\t\t       PJ_STUN_IS_DATAGRAM |\n    \t\t\t         PJ_STUN_NO_FINGERPRINT_CHECK);\n    if (status == PJ_SUCCESS) {\n\tstatus = pj_stun_session_on_rx_pkt(comp->stun_sess, pkt, pkt_size,\n\t\t\t\t\t   PJ_STUN_IS_DATAGRAM, msg_data,\n\t\t\t\t\t   NULL, src_addr, src_addr_len);\n\tif (status != PJ_SUCCESS) {\n\t    pj_strerror(status, ice->tmp.errmsg, sizeof(ice->tmp.errmsg));\n\t    LOG4((ice->obj_name, \"Error processing incoming message: %s\",\n\t\t  ice->tmp.errmsg));\n\t}\n\tpj_grp_lock_release(ice->grp_lock);\n    } else {\n\t/* Not a STUN packet. Call application's callback instead, but release\n\t * the mutex now or otherwise we may get deadlock.\n\t */\n\tpj_grp_lock_release(ice->grp_lock);\n\n\tPJ_RACE_ME(5);\n\n\t(*ice->cb.on_rx_data)(ice, comp_id, transport_id, pkt, pkt_size, \n\t\t\t      src_addr, src_addr_len);\n\tstatus = PJ_SUCCESS;\n    }\n\n    return status;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjnath/ice_strans.c",
    "content": "/* $Id: ice_strans.c 4412 2013-03-05 03:12:32Z riza $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjnath/ice_strans.h>\n#include <pjnath/errno.h>\n#include <pj/addr_resolv.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/ip_helper.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n#include <pj/compat/socket.h>\n\n#define ENABLE_TRACE 0\n\n#if defined(ENABLE_TRACE) && (ENABLE_TRACE != 0)\n#  define TRACE_PKT(expr)\t    PJ_LOG(5,expr)\n#else\n#  define TRACE_PKT(expr)\n#endif\n\n\n/* Transport IDs */\nenum tp_type\n{\n    TP_NONE,\n    TP_STUN,\n    TP_TURN\n};\n\n/* Candidate's local preference values. This is mostly used to\n * specify preference among candidates with the same type. Since\n * we don't have the facility to specify that, we'll just set it\n * all to the same value.\n */\n#if PJNATH_ICE_PRIO_STD\n#   define SRFLX_PREF  65535\n#   define HOST_PREF   65535\n#   define RELAY_PREF  65535\n#else\n#   define SRFLX_PREF  0\n#   define HOST_PREF   0\n#   define RELAY_PREF  0\n#endif\n\n\n/* The candidate type preference when STUN candidate is used */\nstatic pj_uint8_t srflx_pref_table[PJ_ICE_CAND_TYPE_MAX] =\n{\n#if PJNATH_ICE_PRIO_STD\n    100,    /**< PJ_ICE_HOST_PREF\t    */\n    110,    /**< PJ_ICE_SRFLX_PREF\t    */\n    126,    /**< PJ_ICE_PRFLX_PREF\t    */\n    0\t    /**< PJ_ICE_RELAYED_PREF    */\n#else\n    /* Keep it to 2 bits */\n    1,\t/**< PJ_ICE_HOST_PREF\t    */\n    2,\t/**< PJ_ICE_SRFLX_PREF\t    */\n    3,\t/**< PJ_ICE_PRFLX_PREF\t    */\n    0\t/**< PJ_ICE_RELAYED_PREF    */\n#endif\n};\n\n\n/* ICE callbacks */\nstatic void\t   on_ice_complete(pj_ice_sess *ice, pj_status_t status);\nstatic pj_status_t ice_tx_pkt(pj_ice_sess *ice,\n\t\t\t      unsigned comp_id,\n\t\t\t      unsigned transport_id,\n\t\t\t      const void *pkt, pj_size_t size,\n\t\t\t      const pj_sockaddr_t *dst_addr,\n\t\t\t      unsigned dst_addr_len);\nstatic void\t   ice_rx_data(pj_ice_sess *ice,\n\t\t\t       unsigned comp_id,\n\t\t\t       unsigned transport_id,\n\t\t\t       void *pkt, pj_size_t size,\n\t\t\t       const pj_sockaddr_t *src_addr,\n\t\t\t       unsigned src_addr_len);\n\n\n/* STUN socket callbacks */\n/* Notification when incoming packet has been received. */\nstatic pj_bool_t stun_on_rx_data(pj_stun_sock *stun_sock,\n\t\t\t\t void *pkt,\n\t\t\t\t unsigned pkt_len,\n\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t unsigned addr_len);\n/* Notifification when asynchronous send operation has completed. */\nstatic pj_bool_t stun_on_data_sent(pj_stun_sock *stun_sock,\n\t\t\t\t   pj_ioqueue_op_key_t *send_key,\n\t\t\t\t   pj_ssize_t sent);\n/* Notification when the status of the STUN transport has changed. */\nstatic pj_bool_t stun_on_status(pj_stun_sock *stun_sock,\n\t\t\t\tpj_stun_sock_op op,\n\t\t\t\tpj_status_t status);\n\n\n/* TURN callbacks */\nstatic void turn_on_rx_data(pj_turn_sock *turn_sock,\n\t\t\t    void *pkt,\n\t\t\t    unsigned pkt_len,\n\t\t\t    const pj_sockaddr_t *peer_addr,\n\t\t\t    unsigned addr_len);\nstatic void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state,\n\t\t\t  pj_turn_state_t new_state);\n\n\n\n/* Forward decls */\nstatic void ice_st_on_destroy(void *obj);\nstatic void destroy_ice_st(pj_ice_strans *ice_st);\n#define ice_st_perror(ice_st,msg,rc) pjnath_perror(ice_st->obj_name,msg,rc)\nstatic void sess_init_update(pj_ice_strans *ice_st);\n\n/**\n * This structure describes an ICE stream transport component. A component\n * in ICE stream transport typically corresponds to a single socket created\n * for this component, and bound to a specific transport address. This\n * component may have multiple alias addresses, for example one alias\n * address for each interfaces in multi-homed host, another for server\n * reflexive alias, and another for relayed alias. For each transport\n * address alias, an ICE stream transport candidate (#pj_ice_sess_cand) will\n * be created, and these candidates will eventually registered to the ICE\n * session.\n */\ntypedef struct pj_ice_strans_comp\n{\n    pj_ice_strans\t*ice_st;\t/**< ICE stream transport.\t*/\n    unsigned\t\t comp_id;\t/**< Component ID.\t\t*/\n\n    pj_stun_sock\t*stun_sock;\t/**< STUN transport.\t\t*/\n    pj_turn_sock\t*turn_sock;\t/**< TURN relay transport.\t*/\n    pj_bool_t\t\t turn_log_off;\t/**< TURN loggin off?\t\t*/\n    unsigned\t\t turn_err_cnt;\t/**< TURN disconnected count.\t*/\n\n    unsigned\t\t cand_cnt;\t/**< # of candidates/aliaes.\t*/\n    pj_ice_sess_cand\t cand_list[PJ_ICE_ST_MAX_CAND];\t/**< Cand array\t*/\n\n    unsigned\t\t default_cand;\t/**< Default candidate.\t\t*/\n\n} pj_ice_strans_comp;\n\n\n/**\n * This structure represents the ICE stream transport.\n */\nstruct pj_ice_strans\n{\n    char\t\t    *obj_name;\t/**< Log ID.\t\t\t*/\n    pj_pool_t\t\t    *pool;\t/**< Pool used by this object.\t*/\n    void\t\t    *user_data;\t/**< Application data.\t\t*/\n    pj_ice_strans_cfg\t     cfg;\t/**< Configuration.\t\t*/\n    pj_ice_strans_cb\t     cb;\t/**< Application callback.\t*/\n    pj_grp_lock_t\t    *grp_lock;  /**< Group lock.\t\t*/\n\n    pj_ice_strans_state\t     state;\t/**< Session state.\t\t*/\n    pj_ice_sess\t\t    *ice;\t/**< ICE session.\t\t*/\n    pj_time_val\t\t     start_time;/**< Time when ICE was started\t*/\n\n    unsigned\t\t     comp_cnt;\t/**< Number of components.\t*/\n    pj_ice_strans_comp\t   **comp;\t/**< Components array.\t\t*/\n\n    pj_timer_entry\t     ka_timer;\t/**< STUN keep-alive timer.\t*/\n\n    pj_bool_t\t\t     destroy_req;/**< Destroy has been called?\t*/\n    pj_bool_t\t\t     cb_called;\t/**< Init error callback called?*/\n};\n\n\n/* Set ICE state*/\nstatic void set_ice_state(pj_ice_strans *ice_st, pj_ice_strans_state state)\n{\n    pj_ice_strans_state prev = ice_st->state;\n\n    if (prev != state) {\n        ice_st->state = state;\n        if (ice_st->cb.on_ice_state)\n            (*ice_st->cb.on_ice_state)(ice_st, prev, state);\n    }\n}\n\n\n/* Validate configuration */\nstatic pj_status_t pj_ice_strans_cfg_check_valid(const pj_ice_strans_cfg *cfg)\n{\n    pj_status_t status;\n\n    status = pj_stun_config_check_valid(&cfg->stun_cfg);\n    if (!status)\n\treturn status;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Initialize ICE transport configuration with default values.\n */\nPJ_DEF(void) pj_ice_strans_cfg_default(pj_ice_strans_cfg *cfg)\n{\n    pj_bzero(cfg, sizeof(*cfg));\n\n    pj_stun_config_init(&cfg->stun_cfg, NULL, 0, NULL, NULL);\n    pj_stun_sock_cfg_default(&cfg->stun.cfg);\n    pj_turn_alloc_param_default(&cfg->turn.alloc_param);\n    pj_turn_sock_cfg_default(&cfg->turn.cfg);\n\n    pj_ice_sess_options_default(&cfg->opt);\n\n    cfg->af = pj_AF_INET();\n    cfg->stun.port = PJ_STUN_PORT;\n    cfg->turn.conn_type = PJ_TURN_TP_UDP;\n\n    cfg->stun.max_host_cands = 64;\n    cfg->stun.ignore_stun_error = PJ_FALSE;\n}\n\n\n/*\n * Copy configuration.\n */\nPJ_DEF(void) pj_ice_strans_cfg_copy( pj_pool_t *pool,\n\t\t\t\t     pj_ice_strans_cfg *dst,\n\t\t\t\t     const pj_ice_strans_cfg *src)\n{\n    pj_memcpy(dst, src, sizeof(*src));\n\n    if (src->stun.server.slen)\n\tpj_strdup(pool, &dst->stun.server, &src->stun.server);\n    if (src->turn.server.slen)\n\tpj_strdup(pool, &dst->turn.server, &src->turn.server);\n    pj_stun_auth_cred_dup(pool, &dst->turn.auth_cred,\n\t\t\t  &src->turn.auth_cred);\n}\n\n\n/*\n * Add or update TURN candidate.\n */\nstatic pj_status_t add_update_turn(pj_ice_strans *ice_st,\n\t\t\t\t   pj_ice_strans_comp *comp)\n{\n    pj_turn_sock_cb turn_sock_cb;\n    pj_ice_sess_cand *cand = NULL;\n    unsigned i;\n    pj_status_t status;\n\n    /* Find relayed candidate in the component */\n    for (i=0; i<comp->cand_cnt; ++i) {\n\tif (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED) {\n\t    cand = &comp->cand_list[i];\n\t    break;\n\t}\n    }\n\n    /* If candidate is found, invalidate it first */\n    if (cand) {\n\tcand->status = PJ_EPENDING;\n\n\t/* Also if this component's default candidate is set to relay,\n\t * move it temporarily to something else.\n\t */\n\tif ((int)comp->default_cand == cand - comp->cand_list) {\n\t    /* Init to something */\n\t    comp->default_cand = 0;\n\t    /* Use srflx candidate as the default, if any */\n\t    for (i=0; i<comp->cand_cnt; ++i) {\n\t\tif (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_SRFLX) {\n\t\t    comp->default_cand = i;\n\t\t    break;\n\t\t}\n\t    }\n\t}\n    }\n\n    /* Init TURN socket */\n    pj_bzero(&turn_sock_cb, sizeof(turn_sock_cb));\n    turn_sock_cb.on_rx_data = &turn_on_rx_data;\n    turn_sock_cb.on_state = &turn_on_state;\n\n    /* Override with component specific QoS settings, if any */\n    if (ice_st->cfg.comp[comp->comp_id-1].qos_type) {\n\tice_st->cfg.turn.cfg.qos_type =\n\t    ice_st->cfg.comp[comp->comp_id-1].qos_type;\n    }\n    if (ice_st->cfg.comp[comp->comp_id-1].qos_params.flags) {\n\tpj_memcpy(&ice_st->cfg.turn.cfg.qos_params,\n\t\t  &ice_st->cfg.comp[comp->comp_id-1].qos_params,\n\t\t  sizeof(ice_st->cfg.turn.cfg.qos_params));\n    }\n\n    /* Override with component specific socket buffer size settings, if any */\n    if (ice_st->cfg.comp[comp->comp_id-1].so_rcvbuf_size > 0) {\n\tice_st->cfg.turn.cfg.so_rcvbuf_size =\n\t    ice_st->cfg.comp[comp->comp_id-1].so_rcvbuf_size;\n    }\n    if (ice_st->cfg.comp[comp->comp_id-1].so_sndbuf_size > 0) {\n\tice_st->cfg.turn.cfg.so_sndbuf_size =\n\t    ice_st->cfg.comp[comp->comp_id-1].so_sndbuf_size;\n    }\n\n    /* Create the TURN transport */\n    status = pj_turn_sock_create(&ice_st->cfg.stun_cfg, ice_st->cfg.af,\n\t\t\t\t ice_st->cfg.turn.conn_type,\n\t\t\t\t &turn_sock_cb, &ice_st->cfg.turn.cfg,\n\t\t\t\t comp, &comp->turn_sock);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    /* Add pending job */\n    ///sess_add_ref(ice_st);\n\n    /* Start allocation */\n    status=pj_turn_sock_alloc(comp->turn_sock,\n\t\t\t      &ice_st->cfg.turn.server,\n\t\t\t      ice_st->cfg.turn.port,\n\t\t\t      ice_st->cfg.resolver,\n\t\t\t      &ice_st->cfg.turn.auth_cred,\n\t\t\t      &ice_st->cfg.turn.alloc_param);\n    if (status != PJ_SUCCESS) {\n\t///sess_dec_ref(ice_st);\n\treturn status;\n    }\n\n    /* Add relayed candidate with pending status if there's no existing one */\n    if (cand == NULL) {\n\tcand = &comp->cand_list[comp->cand_cnt++];\n\tcand->type = PJ_ICE_CAND_TYPE_RELAYED;\n\tcand->status = PJ_EPENDING;\n\tcand->local_pref = RELAY_PREF;\n\tcand->transport_id = TP_TURN;\n\tcand->comp_id = (pj_uint8_t) comp->comp_id;\n    }\n\n    PJ_LOG(4,(ice_st->obj_name,\n\t\t  \"Comp %d: TURN relay candidate waiting for allocation\",\n\t\t  comp->comp_id));\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_bool_t ice_cand_equals(pj_ice_sess_cand *lcand, \n\t\t    \t         pj_ice_sess_cand *rcand)\n{\n    if (lcand == NULL && rcand == NULL){\n        return PJ_TRUE;\n    }\n    if (lcand == NULL || rcand == NULL){\n        return PJ_FALSE;\n    }\n    \n    if (lcand->type != rcand->type\n        || lcand->status != rcand->status\n        || lcand->comp_id != rcand->comp_id\n        || lcand->transport_id != rcand->transport_id\n        || lcand->local_pref != rcand->local_pref\n        || lcand->prio != rcand->prio\n        || pj_sockaddr_cmp(&lcand->addr, &rcand->addr) != 0\n        || pj_sockaddr_cmp(&lcand->base_addr, &rcand->base_addr) != 0)\n    {\n        return PJ_FALSE;\n    }\n    \n    return PJ_TRUE;\n}\n\n/*\n * Create the component.\n */\nstatic pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)\n{\n    pj_ice_strans_comp *comp = NULL;\n    pj_status_t status;\n\n    /* Verify arguments */\n    PJ_ASSERT_RETURN(ice_st && comp_id, PJ_EINVAL);\n\n    /* Check that component ID present */\n    PJ_ASSERT_RETURN(comp_id <= ice_st->comp_cnt, PJNATH_EICEINCOMPID);\n\n    /* Create component */\n    comp = PJ_POOL_ZALLOC_T(ice_st->pool, pj_ice_strans_comp);\n    comp->ice_st = ice_st;\n    comp->comp_id = comp_id;\n\n    ice_st->comp[comp_id-1] = comp;\n\n    /* Initialize default candidate */\n    comp->default_cand = 0;\n\n    /* Create STUN transport if configured */\n    if (ice_st->cfg.stun.server.slen || ice_st->cfg.stun.max_host_cands) {\n\tpj_stun_sock_cb stun_sock_cb;\n\tpj_ice_sess_cand *cand;\n\n\tpj_bzero(&stun_sock_cb, sizeof(stun_sock_cb));\n\tstun_sock_cb.on_rx_data = &stun_on_rx_data;\n\tstun_sock_cb.on_status = &stun_on_status;\n\tstun_sock_cb.on_data_sent = &stun_on_data_sent;\n\n\t/* Override component specific QoS settings, if any */\n\tif (ice_st->cfg.comp[comp_id-1].qos_type) {\n\t    ice_st->cfg.stun.cfg.qos_type =\n\t\tice_st->cfg.comp[comp_id-1].qos_type;\n\t}\n\tif (ice_st->cfg.comp[comp_id-1].qos_params.flags) {\n\t    pj_memcpy(&ice_st->cfg.stun.cfg.qos_params,\n\t\t      &ice_st->cfg.comp[comp_id-1].qos_params,\n\t\t      sizeof(ice_st->cfg.stun.cfg.qos_params));\n\t}\n\n\t/* Override component specific socket buffer size settings, if any */\n\tif (ice_st->cfg.comp[comp_id-1].so_rcvbuf_size > 0) {\n\t    ice_st->cfg.stun.cfg.so_rcvbuf_size =\n\t\tice_st->cfg.comp[comp_id-1].so_rcvbuf_size;\n\t}\n\tif (ice_st->cfg.comp[comp_id-1].so_sndbuf_size > 0) {\n\t    ice_st->cfg.stun.cfg.so_sndbuf_size =\n\t\tice_st->cfg.comp[comp_id-1].so_sndbuf_size;\n\t}\n\n\t/* Create the STUN transport */\n\tstatus = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL,\n\t\t\t\t     ice_st->cfg.af, &stun_sock_cb,\n\t\t\t\t     &ice_st->cfg.stun.cfg,\n\t\t\t\t     comp, &comp->stun_sock);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Start STUN Binding resolution and add srflx candidate\n\t * only if server is set\n\t */\n\tif (ice_st->cfg.stun.server.slen) {\n\t    pj_stun_sock_info stun_sock_info;\n\n\t    /* Add pending job */\n\t    ///sess_add_ref(ice_st);\n\n\t    PJ_LOG(4,(ice_st->obj_name,\n\t\t      \"Comp %d: srflx candidate starts Binding discovery\",\n\t\t      comp_id));\n\n\t    pj_log_push_indent();\n\n\t    /* Start Binding resolution */\n\t    status = pj_stun_sock_start(comp->stun_sock,\n\t\t\t\t\t&ice_st->cfg.stun.server,\n\t\t\t\t\tice_st->cfg.stun.port,\n\t\t\t\t\tice_st->cfg.resolver);\n\t    if (status != PJ_SUCCESS) {\n\t\t///sess_dec_ref(ice_st);\n\t\tpj_log_pop_indent();\n\t\treturn status;\n\t    }\n\n\t    /* Enumerate addresses */\n\t    status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info);\n\t    if (status != PJ_SUCCESS) {\n\t\t///sess_dec_ref(ice_st);\n\t\tpj_log_pop_indent();\n\t\treturn status;\n\t    }\n\n\t    /* Add srflx candidate with pending status. */\n\t    cand = &comp->cand_list[comp->cand_cnt++];\n\t    cand->type = PJ_ICE_CAND_TYPE_SRFLX;\n\t    cand->status = PJ_EPENDING;\n\t    cand->local_pref = SRFLX_PREF;\n\t    cand->transport_id = TP_STUN;\n\t    cand->comp_id = (pj_uint8_t) comp_id;\n\t    pj_sockaddr_cp(&cand->base_addr, &stun_sock_info.aliases[0]);\n\t    pj_sockaddr_cp(&cand->rel_addr, &cand->base_addr);\n\t    pj_ice_calc_foundation(ice_st->pool, &cand->foundation,\n\t\t\t\t   cand->type, &cand->base_addr);\n\n\t    /* Set default candidate to srflx */\n\t    comp->default_cand = (unsigned)(cand - comp->cand_list);\n\n\t    pj_log_pop_indent();\n\t}\n\n\t/* Add local addresses to host candidates, unless max_host_cands\n\t * is set to zero.\n\t */\n\tif (ice_st->cfg.stun.max_host_cands) {\n\t    pj_stun_sock_info stun_sock_info;\n\t    unsigned i;\n\n\t    /* Enumerate addresses */\n\t    status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    for (i=0; i<stun_sock_info.alias_cnt &&\n\t\t      i<ice_st->cfg.stun.max_host_cands; ++i)\n\t    {\n\t\tunsigned j;\n\t\tpj_bool_t cand_duplicate = PJ_FALSE;\n\t\tchar addrinfo[PJ_INET6_ADDRSTRLEN+10];\n\t\tconst pj_sockaddr *addr = &stun_sock_info.aliases[i];\n\n\t\t/* Leave one candidate for relay */\n\t\tif (comp->cand_cnt >= PJ_ICE_ST_MAX_CAND-1) {\n\t\t    PJ_LOG(4,(ice_st->obj_name, \"Too many host candidates\"));\n\t\t    break;\n\t\t}\n\n\t\t/* Ignore loopback addresses unless cfg->stun.loop_addr\n\t\t * is set\n\t\t */\n\t\tif ((pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127) {\n\t\t    if (ice_st->cfg.stun.loop_addr==PJ_FALSE)\n\t\t\tcontinue;\n\t\t}\n\n\t\tcand = &comp->cand_list[comp->cand_cnt];\n\n\t\tcand->type = PJ_ICE_CAND_TYPE_HOST;\n\t\tcand->status = PJ_SUCCESS;\n\t\tcand->local_pref = HOST_PREF;\n\t\tcand->transport_id = TP_STUN;\n\t\tcand->comp_id = (pj_uint8_t) comp_id;\n\t\tpj_sockaddr_cp(&cand->addr, addr);\n\t\tpj_sockaddr_cp(&cand->base_addr, addr);\n\t\tpj_bzero(&cand->rel_addr, sizeof(cand->rel_addr));\n            \n\t\t/* Check if not already in list */\n\t\tfor (j=0; j<comp->cand_cnt; j++) {\n\t\t    if (ice_cand_equals(cand, &comp->cand_list[j])) {\n\t\t\tcand_duplicate = PJ_TRUE;\n\t\t\tbreak;\n\t\t    }\n\t\t}\n\n\t\tif (cand_duplicate) {\n\t\t    PJ_LOG(4, (ice_st->obj_name,\n\t\t\t   \"Comp %d: host candidate %s is a duplicate\",\n\t\t\t   comp_id, pj_sockaddr_print(&cand->addr, addrinfo,\n\t\t\t   sizeof(addrinfo), 3)));\n\n\t\t    pj_bzero(&cand->addr, sizeof(cand->addr));\n\t\t    pj_bzero(&cand->base_addr, sizeof(cand->base_addr));\n\t\t    continue;\n\t\t} else {\n\t\t    comp->cand_cnt+=1;\n\t\t}\n            \n\t\tpj_ice_calc_foundation(ice_st->pool, &cand->foundation,\n\t\t\t\t       cand->type, &cand->base_addr);\n\n\t\tPJ_LOG(4,(ice_st->obj_name,\n\t\t\t  \"Comp %d: host candidate %s added\",\n\t\t\t  comp_id, pj_sockaddr_print(&cand->addr, addrinfo,\n\t\t\t\t\t\t     sizeof(addrinfo), 3)));\n\t    }\n\t}\n    }\n\n    /* Create TURN relay if configured. */\n    if (ice_st->cfg.turn.server.slen) {\n\tadd_update_turn(ice_st, comp);\n    }\n\n    /* It's possible that we end up without any candidates */\n    if (comp->cand_cnt == 0) {\n\tPJ_LOG(4,(ice_st->obj_name,\n\t\t  \"Error: no candidate is created due to settings\"));\n\treturn PJ_EINVAL;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create ICE stream transport\n */\nPJ_DEF(pj_status_t) pj_ice_strans_create( const char *name,\n\t\t\t\t\t  const pj_ice_strans_cfg *cfg,\n\t\t\t\t\t  unsigned comp_cnt,\n\t\t\t\t\t  void *user_data,\n\t\t\t\t\t  const pj_ice_strans_cb *cb,\n\t\t\t\t\t  pj_ice_strans **p_ice_st)\n{\n    pj_pool_t *pool;\n    pj_ice_strans *ice_st;\n    unsigned i;\n    pj_status_t status;\n\n    status = pj_ice_strans_cfg_check_valid(cfg);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    PJ_ASSERT_RETURN(comp_cnt && cb && p_ice_st &&\n\t\t     comp_cnt <= PJ_ICE_MAX_COMP , PJ_EINVAL);\n\n    if (name == NULL)\n\tname = \"ice%p\";\n\n    pool = pj_pool_create(cfg->stun_cfg.pf, name, PJNATH_POOL_LEN_ICE_STRANS,\n\t\t\t  PJNATH_POOL_INC_ICE_STRANS, NULL);\n    ice_st = PJ_POOL_ZALLOC_T(pool, pj_ice_strans);\n    ice_st->pool = pool;\n    ice_st->obj_name = pool->obj_name;\n    ice_st->user_data = user_data;\n\n    PJ_LOG(4,(ice_st->obj_name,\n\t      \"Creating ICE stream transport with %d component(s)\",\n\t      comp_cnt));\n    pj_log_push_indent();\n\n    status = pj_grp_lock_create(pool, NULL, &ice_st->grp_lock);\n    if (status != PJ_SUCCESS) {\n\tpj_pool_release(pool);\n\tpj_log_pop_indent();\n\treturn status;\n    }\n\n    pj_grp_lock_add_ref(ice_st->grp_lock);\n    pj_grp_lock_add_handler(ice_st->grp_lock, pool, ice_st,\n\t\t\t    &ice_st_on_destroy);\n\n    pj_ice_strans_cfg_copy(pool, &ice_st->cfg, cfg);\n    ice_st->cfg.stun.cfg.grp_lock = ice_st->grp_lock;\n    ice_st->cfg.turn.cfg.grp_lock = ice_st->grp_lock;\n    pj_memcpy(&ice_st->cb, cb, sizeof(*cb));\n\n    ice_st->comp_cnt = comp_cnt;\n    ice_st->comp = (pj_ice_strans_comp**)\n\t\t   pj_pool_calloc(pool, comp_cnt, sizeof(pj_ice_strans_comp*));\n\n    /* Move state to candidate gathering */\n    set_ice_state(ice_st, PJ_ICE_STRANS_STATE_INIT);\n\n    /* Acquire initialization mutex to prevent callback to be\n     * called before we finish initialization.\n     */\n    pj_grp_lock_acquire(ice_st->grp_lock);\n\n    for (i=0; i<comp_cnt; ++i) {\n\tstatus = create_comp(ice_st, i+1);\n\tif (status != PJ_SUCCESS) {\n\t    pj_grp_lock_release(ice_st->grp_lock);\n\t    destroy_ice_st(ice_st);\n\t    pj_log_pop_indent();\n\t    return status;\n\t}\n    }\n\n    /* Done with initialization */\n    pj_grp_lock_release(ice_st->grp_lock);\n\n    PJ_LOG(4,(ice_st->obj_name, \"ICE stream transport %p created\", ice_st));\n\n    *p_ice_st = ice_st;\n\n    /* Check if all candidates are ready (this may call callback) */\n    sess_init_update(ice_st);\n\n    pj_log_pop_indent();\n\n    return PJ_SUCCESS;\n}\n\n/* REALLY destroy ICE */\nstatic void ice_st_on_destroy(void *obj)\n{\n    pj_ice_strans *ice_st = (pj_ice_strans*)obj;\n\n    PJ_LOG(4,(ice_st->obj_name, \"ICE stream transport %p destroyed\", obj));\n\n    /* Done */\n    pj_pool_release(ice_st->pool);\n}\n\n/* Destroy ICE */\nstatic void destroy_ice_st(pj_ice_strans *ice_st)\n{\n    unsigned i;\n\n    PJ_LOG(5,(ice_st->obj_name, \"ICE stream transport %p destroy request..\",\n\t      ice_st));\n    pj_log_push_indent();\n\n    pj_grp_lock_acquire(ice_st->grp_lock);\n\n    if (ice_st->destroy_req) {\n\tpj_grp_lock_release(ice_st->grp_lock);\n\treturn;\n    }\n\n    ice_st->destroy_req = PJ_TRUE;\n\n    /* Destroy ICE if we have ICE */\n    if (ice_st->ice) {\n\tpj_ice_sess_destroy(ice_st->ice);\n\tice_st->ice = NULL;\n    }\n\n    /* Destroy all components */\n    for (i=0; i<ice_st->comp_cnt; ++i) {\n\tif (ice_st->comp[i]) {\n\t    if (ice_st->comp[i]->stun_sock) {\n\t\tpj_stun_sock_destroy(ice_st->comp[i]->stun_sock);\n\t\tice_st->comp[i]->stun_sock = NULL;\n\t    }\n\t    if (ice_st->comp[i]->turn_sock) {\n\t\tpj_turn_sock_destroy(ice_st->comp[i]->turn_sock);\n\t\tice_st->comp[i]->turn_sock = NULL;\n\t    }\n\t}\n    }\n\n    pj_grp_lock_dec_ref(ice_st->grp_lock);\n    pj_grp_lock_release(ice_st->grp_lock);\n\n    pj_log_pop_indent();\n}\n\n/* Get ICE session state. */\nPJ_DEF(pj_ice_strans_state) pj_ice_strans_get_state(pj_ice_strans *ice_st)\n{\n    return ice_st->state;\n}\n\n/* State string */\nPJ_DEF(const char*) pj_ice_strans_state_name(pj_ice_strans_state state)\n{\n    const char *names[] = {\n\t\"Null\",\n\t\"Candidate Gathering\",\n\t\"Candidate Gathering Complete\",\n\t\"Session Initialized\",\n\t\"Negotiation In Progress\",\n\t\"Negotiation Success\",\n\t\"Negotiation Failed\"\n    };\n\n    PJ_ASSERT_RETURN(state <= PJ_ICE_STRANS_STATE_FAILED, \"???\");\n    return names[state];\n}\n\n/* Notification about failure */\nstatic void sess_fail(pj_ice_strans *ice_st, pj_ice_strans_op op,\n\t\t      const char *title, pj_status_t status)\n{\n    char errmsg[PJ_ERR_MSG_SIZE];\n\n    pj_strerror(status, errmsg, sizeof(errmsg));\n    PJ_LOG(4,(ice_st->obj_name, \"%s: %s\", title, errmsg));\n    pj_log_push_indent();\n\n    if (op==PJ_ICE_STRANS_OP_INIT && ice_st->cb_called) {\n\tpj_log_pop_indent();\n\treturn;\n    }\n\n    ice_st->cb_called = PJ_TRUE;\n\n    if (ice_st->cb.on_ice_complete)\n\t(*ice_st->cb.on_ice_complete)(ice_st, op, status);\n\n    pj_log_pop_indent();\n}\n\n/* Update initialization status */\nstatic void sess_init_update(pj_ice_strans *ice_st)\n{\n    unsigned i;\n\n    /* Ignore if init callback has been called */\n    if (ice_st->cb_called)\n\treturn;\n\n    /* Notify application when all candidates have been gathered */\n    for (i=0; i<ice_st->comp_cnt; ++i) {\n\tunsigned j;\n\tpj_ice_strans_comp *comp = ice_st->comp[i];\n\n\tfor (j=0; j<comp->cand_cnt; ++j) {\n\t    pj_ice_sess_cand *cand = &comp->cand_list[j];\n\n\t    if (cand->status == PJ_EPENDING)\n\t\treturn;\n\t}\n    }\n\n    /* All candidates have been gathered */\n    ice_st->cb_called = PJ_TRUE;\n    set_ice_state(ice_st, PJ_ICE_STRANS_STATE_READY);\n    if (ice_st->cb.on_ice_complete)\n\t(*ice_st->cb.on_ice_complete)(ice_st, PJ_ICE_STRANS_OP_INIT,\n\t\t\t\t      PJ_SUCCESS);\n}\n\n/*\n * Destroy ICE stream transport.\n */\nPJ_DEF(pj_status_t) pj_ice_strans_destroy(pj_ice_strans *ice_st)\n{\n    destroy_ice_st(ice_st);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get user data\n */\nPJ_DEF(void*) pj_ice_strans_get_user_data(pj_ice_strans *ice_st)\n{\n    PJ_ASSERT_RETURN(ice_st, NULL);\n    return ice_st->user_data;\n}\n\n\n/*\n * Get the value of various options of the ICE stream transport.\n */\nPJ_DEF(pj_status_t) pj_ice_strans_get_options( pj_ice_strans *ice_st,\n\t\t\t\t\t       pj_ice_sess_options *opt)\n{\n    PJ_ASSERT_RETURN(ice_st && opt, PJ_EINVAL);\n    pj_memcpy(opt, &ice_st->cfg.opt, sizeof(*opt));\n    return PJ_SUCCESS;\n}\n\n/*\n * Specify various options for this ICE stream transport.\n */\nPJ_DEF(pj_status_t) pj_ice_strans_set_options(pj_ice_strans *ice_st,\n\t\t\t\t\t      const pj_ice_sess_options *opt)\n{\n    PJ_ASSERT_RETURN(ice_st && opt, PJ_EINVAL);\n    pj_memcpy(&ice_st->cfg.opt, opt, sizeof(*opt));\n    if (ice_st->ice)\n\tpj_ice_sess_set_options(ice_st->ice, &ice_st->cfg.opt);\n    return PJ_SUCCESS;\n}\n\n/**\n * Get the group lock for this ICE stream transport.\n */\nPJ_DEF(pj_grp_lock_t *) pj_ice_strans_get_grp_lock(pj_ice_strans *ice_st)\n{\n    PJ_ASSERT_RETURN(ice_st, NULL);\n    return ice_st->grp_lock;\n}\n\n/*\n * Create ICE!\n */\nPJ_DEF(pj_status_t) pj_ice_strans_init_ice(pj_ice_strans *ice_st,\n\t\t\t\t\t   pj_ice_sess_role role,\n\t\t\t\t\t   const pj_str_t *local_ufrag,\n\t\t\t\t\t   const pj_str_t *local_passwd)\n{\n    pj_status_t status;\n    unsigned i;\n    pj_ice_sess_cb ice_cb;\n    //const pj_uint8_t srflx_prio[4] = { 100, 126, 110, 0 };\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(ice_st, PJ_EINVAL);\n    /* Must not have ICE */\n    PJ_ASSERT_RETURN(ice_st->ice == NULL, PJ_EINVALIDOP);\n    /* Components must have been created */\n    PJ_ASSERT_RETURN(ice_st->comp[0] != NULL, PJ_EINVALIDOP);\n\n    /* Init callback */\n    pj_bzero(&ice_cb, sizeof(ice_cb));\n    ice_cb.on_ice_complete = &on_ice_complete;\n    ice_cb.on_rx_data = &ice_rx_data;\n    ice_cb.on_tx_pkt = &ice_tx_pkt;\n\n    /* Create! */\n    status = pj_ice_sess_create(&ice_st->cfg.stun_cfg, ice_st->obj_name, role,\n\t\t\t        ice_st->comp_cnt, &ice_cb,\n\t\t\t        local_ufrag, local_passwd,\n\t\t\t        ice_st->grp_lock,\n\t\t\t        &ice_st->ice);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Associate user data */\n    ice_st->ice->user_data = (void*)ice_st;\n\n    /* Set options */\n    pj_ice_sess_set_options(ice_st->ice, &ice_st->cfg.opt);\n\n    /* If default candidate for components are SRFLX one, upload a custom\n     * type priority to ICE session so that SRFLX candidates will get\n     * checked first.\n     */\n    if (ice_st->comp[0]->cand_list[ice_st->comp[0]->default_cand].type\n\t    == PJ_ICE_CAND_TYPE_SRFLX)\n    {\n\tpj_ice_sess_set_prefs(ice_st->ice, srflx_pref_table);\n    }\n\n    /* Add components/candidates */\n    for (i=0; i<ice_st->comp_cnt; ++i) {\n\tunsigned j;\n\tpj_ice_strans_comp *comp = ice_st->comp[i];\n\n\t/* Re-enable logging for Send/Data indications */\n\tif (comp->turn_sock) {\n\t    PJ_LOG(5,(ice_st->obj_name,\n\t\t      \"Disabling STUN Indication logging for \"\n\t\t      \"component %d\", i+1));\n\t    pj_turn_sock_set_log(comp->turn_sock, 0xFFFF);\n\t    comp->turn_log_off = PJ_FALSE;\n\t}\n\n\tfor (j=0; j<comp->cand_cnt; ++j) {\n\t    pj_ice_sess_cand *cand = &comp->cand_list[j];\n\t    unsigned ice_cand_id;\n\n\t    /* Skip if candidate is not ready */\n\t    if (cand->status != PJ_SUCCESS) {\n\t\tPJ_LOG(5,(ice_st->obj_name,\n\t\t\t  \"Candidate %d of comp %d is not added (pending)\",\n\t\t\t  j, i));\n\t\tcontinue;\n\t    }\n\n\t    /* Must have address */\n\t    pj_assert(pj_sockaddr_has_addr(&cand->addr));\n\n\t    /* Add the candidate */\n\t    status = pj_ice_sess_add_cand(ice_st->ice, comp->comp_id,\n\t\t\t\t\t  cand->transport_id, cand->type,\n\t\t\t\t\t  cand->local_pref,\n\t\t\t\t\t  &cand->foundation, &cand->addr,\n\t\t\t\t\t  &cand->base_addr,  &cand->rel_addr,\n\t\t\t\t\t  pj_sockaddr_get_len(&cand->addr),\n\t\t\t\t\t  (unsigned*)&ice_cand_id);\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_error;\n\t}\n    }\n\n    /* ICE session is ready for negotiation */\n    set_ice_state(ice_st, PJ_ICE_STRANS_STATE_SESS_READY);\n\n    return PJ_SUCCESS;\n\non_error:\n    pj_ice_strans_stop_ice(ice_st);\n    return status;\n}\n\n/*\n * Check if the ICE stream transport has the ICE session created.\n */\nPJ_DEF(pj_bool_t) pj_ice_strans_has_sess(pj_ice_strans *ice_st)\n{\n    PJ_ASSERT_RETURN(ice_st, PJ_FALSE);\n    return ice_st->ice != NULL;\n}\n\n/*\n * Check if ICE negotiation is still running.\n */\nPJ_DEF(pj_bool_t) pj_ice_strans_sess_is_running(pj_ice_strans *ice_st)\n{\n    return ice_st && ice_st->ice && ice_st->ice->rcand_cnt &&\n\t   !pj_ice_strans_sess_is_complete(ice_st);\n}\n\n\n/*\n * Check if ICE negotiation has completed.\n */\nPJ_DEF(pj_bool_t) pj_ice_strans_sess_is_complete(pj_ice_strans *ice_st)\n{\n    return ice_st && ice_st->ice && ice_st->ice->is_complete;\n}\n\n\n/*\n * Get the current/running component count.\n */\nPJ_DEF(unsigned) pj_ice_strans_get_running_comp_cnt(pj_ice_strans *ice_st)\n{\n    PJ_ASSERT_RETURN(ice_st, PJ_EINVAL);\n\n    if (ice_st->ice && ice_st->ice->rcand_cnt) {\n\treturn ice_st->ice->comp_cnt;\n    } else {\n\treturn ice_st->comp_cnt;\n    }\n}\n\n\n/*\n * Get the ICE username fragment and password of the ICE session.\n */\nPJ_DEF(pj_status_t) pj_ice_strans_get_ufrag_pwd( pj_ice_strans *ice_st,\n\t\t\t\t\t\t pj_str_t *loc_ufrag,\n\t\t\t\t\t\t pj_str_t *loc_pwd,\n\t\t\t\t\t\t pj_str_t *rem_ufrag,\n\t\t\t\t\t\t pj_str_t *rem_pwd)\n{\n    PJ_ASSERT_RETURN(ice_st && ice_st->ice, PJ_EINVALIDOP);\n\n    if (loc_ufrag) *loc_ufrag = ice_st->ice->rx_ufrag;\n    if (loc_pwd) *loc_pwd = ice_st->ice->rx_pass;\n\n    if (rem_ufrag || rem_pwd) {\n\tPJ_ASSERT_RETURN(ice_st->ice->rcand_cnt != 0, PJ_EINVALIDOP);\n\tif (rem_ufrag) *rem_ufrag = ice_st->ice->tx_ufrag;\n\tif (rem_pwd) *rem_pwd = ice_st->ice->tx_pass;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get number of candidates\n */\nPJ_DEF(unsigned) pj_ice_strans_get_cands_count(pj_ice_strans *ice_st,\n\t\t\t\t\t       unsigned comp_id)\n{\n    unsigned i, cnt;\n\n    PJ_ASSERT_RETURN(ice_st && ice_st->ice && comp_id &&\n\t\t     comp_id <= ice_st->comp_cnt, 0);\n\n    cnt = 0;\n    for (i=0; i<ice_st->ice->lcand_cnt; ++i) {\n\tif (ice_st->ice->lcand[i].comp_id != comp_id)\n\t    continue;\n\t++cnt;\n    }\n\n    return cnt;\n}\n\n/*\n * Enum candidates\n */\nPJ_DEF(pj_status_t) pj_ice_strans_enum_cands(pj_ice_strans *ice_st,\n\t\t\t\t\t     unsigned comp_id,\n\t\t\t\t\t     unsigned *count,\n\t\t\t\t\t     pj_ice_sess_cand cand[])\n{\n    unsigned i, cnt;\n\n    PJ_ASSERT_RETURN(ice_st && ice_st->ice && comp_id &&\n\t\t     comp_id <= ice_st->comp_cnt && count && cand, PJ_EINVAL);\n\n    cnt = 0;\n    for (i=0; i<ice_st->ice->lcand_cnt && cnt<*count; ++i) {\n\tif (ice_st->ice->lcand[i].comp_id != comp_id)\n\t    continue;\n\tpj_memcpy(&cand[cnt], &ice_st->ice->lcand[i],\n\t\t  sizeof(pj_ice_sess_cand));\n\t++cnt;\n    }\n\n    *count = cnt;\n    return PJ_SUCCESS;\n}\n\n/*\n * Get default candidate.\n */\nPJ_DEF(pj_status_t) pj_ice_strans_get_def_cand( pj_ice_strans *ice_st,\n\t\t\t\t\t\tunsigned comp_id,\n\t\t\t\t\t\tpj_ice_sess_cand *cand)\n{\n    const pj_ice_sess_check *valid_pair;\n\n    PJ_ASSERT_RETURN(ice_st && comp_id && comp_id <= ice_st->comp_cnt &&\n\t\t      cand, PJ_EINVAL);\n\n    valid_pair = pj_ice_strans_get_valid_pair(ice_st, comp_id);\n    if (valid_pair) {\n\tpj_memcpy(cand, valid_pair->lcand, sizeof(pj_ice_sess_cand));\n    } else {\n\tpj_ice_strans_comp *comp = ice_st->comp[comp_id - 1];\n\tpj_assert(comp->default_cand<comp->cand_cnt);\n\tpj_memcpy(cand, &comp->cand_list[comp->default_cand],\n\t\t  sizeof(pj_ice_sess_cand));\n    }\n    return PJ_SUCCESS;\n}\n\n/*\n * Get the current ICE role.\n */\nPJ_DEF(pj_ice_sess_role) pj_ice_strans_get_role(pj_ice_strans *ice_st)\n{\n    PJ_ASSERT_RETURN(ice_st && ice_st->ice, PJ_ICE_SESS_ROLE_UNKNOWN);\n    return ice_st->ice->role;\n}\n\n/*\n * Change session role.\n */\nPJ_DEF(pj_status_t) pj_ice_strans_change_role( pj_ice_strans *ice_st,\n\t\t\t\t\t       pj_ice_sess_role new_role)\n{\n    PJ_ASSERT_RETURN(ice_st && ice_st->ice, PJ_EINVALIDOP);\n    return pj_ice_sess_change_role(ice_st->ice, new_role);\n}\n\n/*\n * Start ICE processing !\n */\nPJ_DEF(pj_status_t) pj_ice_strans_start_ice( pj_ice_strans *ice_st,\n\t\t\t\t\t     const pj_str_t *rem_ufrag,\n\t\t\t\t\t     const pj_str_t *rem_passwd,\n\t\t\t\t\t     unsigned rem_cand_cnt,\n\t\t\t\t\t     const pj_ice_sess_cand rem_cand[])\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(ice_st && rem_ufrag && rem_passwd &&\n\t\t     rem_cand_cnt && rem_cand, PJ_EINVAL);\n\n    /* Mark start time */\n    pj_gettimeofday(&ice_st->start_time);\n\n    /* Build check list */\n    status = pj_ice_sess_create_check_list(ice_st->ice, rem_ufrag, rem_passwd,\n\t\t\t\t\t   rem_cand_cnt, rem_cand);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* If we have TURN candidate, now is the time to create the permissions */\n    if (ice_st->comp[0]->turn_sock) {\n\tunsigned i;\n\n\tfor (i=0; i<ice_st->comp_cnt; ++i) {\n\t    pj_ice_strans_comp *comp = ice_st->comp[i];\n\t    pj_sockaddr addrs[PJ_ICE_ST_MAX_CAND];\n\t    unsigned j, count=0;\n\n\t    /* Gather remote addresses for this component */\n\t    for (j=0; j<rem_cand_cnt && count<PJ_ARRAY_SIZE(addrs); ++j) {\n\t\tif (rem_cand[j].comp_id==i+1) {\n\t\t    pj_memcpy(&addrs[count++], &rem_cand[j].addr,\n\t\t\t      pj_sockaddr_get_len(&rem_cand[j].addr));\n\t\t}\n\t    }\n\n\t    if (count) {\n\t\tstatus = pj_turn_sock_set_perm(comp->turn_sock, count,\n\t\t\t\t\t       addrs, 0);\n\t\tif (status != PJ_SUCCESS) {\n\t\t    pj_ice_strans_stop_ice(ice_st);\n\t\t    return status;\n\t\t}\n\t    }\n\t}\n    }\n\n    /* Start ICE negotiation! */\n    status = pj_ice_sess_start_check(ice_st->ice);\n    if (status != PJ_SUCCESS) {\n\tpj_ice_strans_stop_ice(ice_st);\n\treturn status;\n    }\n\n    set_ice_state(ice_st, PJ_ICE_STRANS_STATE_NEGO);\n    return status;\n}\n\n/*\n * Get valid pair.\n */\nPJ_DEF(const pj_ice_sess_check*)\npj_ice_strans_get_valid_pair(const pj_ice_strans *ice_st,\n\t\t\t     unsigned comp_id)\n{\n    PJ_ASSERT_RETURN(ice_st && comp_id && comp_id <= ice_st->comp_cnt,\n\t\t     NULL);\n\n    if (ice_st->ice == NULL)\n\treturn NULL;\n\n    return ice_st->ice->comp[comp_id-1].valid_check;\n}\n\n/*\n * Get ICE session.\n */\nPJ_DEF(pj_ice_sess*)\npj_ice_strans_get_session(const pj_ice_strans *ice_st)\n{\n    return ice_st->ice;\n}\n\n/*\n * Get ICE start time.\n */\nPJ_DEF(pj_time_val)\npj_ice_strans_get_start_time(const pj_ice_strans *ice_st)\n{\n\n    return ice_st->start_time;\n}\n\n/*\n * Stop ICE!\n */\nPJ_DEF(pj_status_t) pj_ice_strans_stop_ice(pj_ice_strans *ice_st)\n{\n    PJ_ASSERT_RETURN(ice_st, PJ_EINVAL);\n    \n    /* Protect with group lock, since this may cause race condition with\n     * pj_ice_strans_sendto().\n     * See ticket #1877.\n     */\n    pj_grp_lock_acquire(ice_st->grp_lock);\n\n    if (ice_st->ice) {\n\tpj_ice_sess_destroy(ice_st->ice);\n\tice_st->ice = NULL;\n    }\n\n    set_ice_state(ice_st, PJ_ICE_STRANS_STATE_INIT);\n\n    pj_grp_lock_release(ice_st->grp_lock);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Application wants to send outgoing packet.\n */\nPJ_DEF(pj_status_t) pj_ice_strans_sendto( pj_ice_strans *ice_st,\n\t\t\t\t\t  unsigned comp_id,\n\t\t\t\t\t  const void *data,\n\t\t\t\t\t  pj_size_t data_len,\n\t\t\t\t\t  const pj_sockaddr_t *dst_addr,\n\t\t\t\t\t  int dst_addr_len)\n{\n    pj_ice_strans_comp *comp;\n    unsigned def_cand;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(ice_st && comp_id && comp_id <= ice_st->comp_cnt &&\n\t\t     dst_addr && dst_addr_len, PJ_EINVAL);\n\n    comp = ice_st->comp[comp_id-1];\n\n    /* Check that default candidate for the component exists */\n    def_cand = comp->default_cand;\n    if (def_cand >= comp->cand_cnt)\n\treturn PJ_EINVALIDOP;\n\n    /* Protect with group lock, since this may cause race condition with\n     * pj_ice_strans_stop_ice().\n     * See ticket #1877.\n     */\n    pj_grp_lock_acquire(ice_st->grp_lock);\n\n    /* If ICE is available, send data with ICE, otherwise send with the\n     * default candidate selected during initialization.\n     *\n     * https://trac.pjsip.org/repos/ticket/1416:\n     * Once ICE has failed, also send data with the default candidate.\n     */\n    if (ice_st->ice && ice_st->state == PJ_ICE_STRANS_STATE_RUNNING) {\n\tstatus = pj_ice_sess_send_data(ice_st->ice, comp_id, data, data_len);\n\t\n\tpj_grp_lock_release(ice_st->grp_lock);\n\t\n\treturn status;\n    } \n    \n    pj_grp_lock_release(ice_st->grp_lock);\n    \n    if (comp->cand_list[def_cand].status == PJ_SUCCESS) {\n\n\tif (comp->cand_list[def_cand].type == PJ_ICE_CAND_TYPE_RELAYED) {\n\n\t    enum {\n\t\tmsg_disable_ind = 0xFFFF &\n\t\t\t\t  ~(PJ_STUN_SESS_LOG_TX_IND|\n\t\t\t\t    PJ_STUN_SESS_LOG_RX_IND)\n\t    };\n\n\t    /* https://trac.pjsip.org/repos/ticket/1316 */\n\t    if (comp->turn_sock == NULL) {\n\t\t/* TURN socket error */\n\t\treturn PJ_EINVALIDOP;\n\t    }\n\n\t    if (!comp->turn_log_off) {\n\t\t/* Disable logging for Send/Data indications */\n\t\tPJ_LOG(5,(ice_st->obj_name,\n\t\t\t  \"Disabling STUN Indication logging for \"\n\t\t\t  \"component %d\", comp->comp_id));\n\t\tpj_turn_sock_set_log(comp->turn_sock, msg_disable_ind);\n\t\tcomp->turn_log_off = PJ_TRUE;\n\t    }\n\n\t    status = pj_turn_sock_sendto(comp->turn_sock,\n\t\t\t\t\t (const pj_uint8_t*)data,\n\t\t\t\t\t (unsigned)data_len,\n\t\t\t\t\t dst_addr, dst_addr_len);\n\t    return (status==PJ_SUCCESS||status==PJ_EPENDING) ?\n\t\t    PJ_SUCCESS : status;\n\t} else {\n\t    status = pj_stun_sock_sendto(comp->stun_sock, NULL, data,\n\t\t\t\t\t (unsigned)data_len, 0, dst_addr,\n\t\t\t\t\t dst_addr_len);\n\t    return (status==PJ_SUCCESS||status==PJ_EPENDING) ?\n\t\t    PJ_SUCCESS : status;\n\t}\n\n    } else\n\treturn PJ_EINVALIDOP;\n}\n\n/*\n * Callback called by ICE session when ICE processing is complete, either\n * successfully or with failure.\n */\nstatic void on_ice_complete(pj_ice_sess *ice, pj_status_t status)\n{\n    pj_ice_strans *ice_st = (pj_ice_strans*)ice->user_data;\n    pj_time_val t;\n    unsigned msec;\n\n    pj_grp_lock_add_ref(ice_st->grp_lock);\n\n    pj_gettimeofday(&t);\n    PJ_TIME_VAL_SUB(t, ice_st->start_time);\n    msec = PJ_TIME_VAL_MSEC(t);\n\n    if (ice_st->cb.on_ice_complete) {\n\tif (status != PJ_SUCCESS) {\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\t    pj_strerror(status, errmsg, sizeof(errmsg));\n\t    PJ_LOG(4,(ice_st->obj_name,\n\t\t      \"ICE negotiation failed after %ds:%03d: %s\",\n\t\t      msec/1000, msec%1000, errmsg));\n\t} else {\n\t    unsigned i;\n\t    enum {\n\t\tmsg_disable_ind = 0xFFFF &\n\t\t\t\t  ~(PJ_STUN_SESS_LOG_TX_IND|\n\t\t\t\t    PJ_STUN_SESS_LOG_RX_IND)\n\t    };\n\n\t    PJ_LOG(4,(ice_st->obj_name,\n\t\t      \"ICE negotiation success after %ds:%03d\",\n\t\t      msec/1000, msec%1000));\n\n\t    for (i=0; i<ice_st->comp_cnt; ++i) {\n\t\tconst pj_ice_sess_check *check;\n\n\t\tcheck = pj_ice_strans_get_valid_pair(ice_st, i+1);\n\t\tif (check) {\n\t\t    char lip[PJ_INET6_ADDRSTRLEN+10];\n\t\t    char rip[PJ_INET6_ADDRSTRLEN+10];\n\n\t\t    pj_sockaddr_print(&check->lcand->addr, lip,\n\t\t\t\t      sizeof(lip), 3);\n\t\t    pj_sockaddr_print(&check->rcand->addr, rip,\n\t\t\t\t      sizeof(rip), 3);\n\n\t\t    if (check->lcand->transport_id == TP_TURN) {\n\t\t\t/* Activate channel binding for the remote address\n\t\t\t * for more efficient data transfer using TURN.\n\t\t\t */\n\t\t\tstatus = pj_turn_sock_bind_channel(\n\t\t\t\t\tice_st->comp[i]->turn_sock,\n\t\t\t\t\t&check->rcand->addr,\n\t\t\t\t\tsizeof(check->rcand->addr));\n\n\t\t\t/* Disable logging for Send/Data indications */\n\t\t\tPJ_LOG(5,(ice_st->obj_name,\n\t\t\t\t  \"Disabling STUN Indication logging for \"\n\t\t\t\t  \"component %d\", i+1));\n\t\t\tpj_turn_sock_set_log(ice_st->comp[i]->turn_sock,\n\t\t\t\t\t     msg_disable_ind);\n\t\t\tice_st->comp[i]->turn_log_off = PJ_TRUE;\n\t\t    }\n\n\t\t    PJ_LOG(4,(ice_st->obj_name, \" Comp %d: \"\n\t\t\t      \"sending from %s candidate %s to \"\n\t\t\t      \"%s candidate %s\",\n\t\t\t      i+1,\n\t\t\t      pj_ice_get_cand_type_name(check->lcand->type),\n\t\t\t      lip,\n\t\t\t      pj_ice_get_cand_type_name(check->rcand->type),\n\t\t\t      rip));\n\n\t\t} else {\n\t\t    PJ_LOG(4,(ice_st->obj_name,\n\t\t\t      \"Comp %d: disabled\", i+1));\n\t\t}\n\t    }\n\t}\n\n\tset_ice_state(ice_st, (status==PJ_SUCCESS) ? PJ_ICE_STRANS_STATE_RUNNING :\n\t\t\t\t\t             PJ_ICE_STRANS_STATE_FAILED);\n\n\tpj_log_push_indent();\n\t(*ice_st->cb.on_ice_complete)(ice_st, PJ_ICE_STRANS_OP_NEGOTIATION,\n\t\t\t\t      status);\n\tpj_log_pop_indent();\n\n    }\n\n    pj_grp_lock_dec_ref(ice_st->grp_lock);\n}\n\n/*\n * Callback called by ICE session when it wants to send outgoing packet.\n */\nstatic pj_status_t ice_tx_pkt(pj_ice_sess *ice,\n\t\t\t      unsigned comp_id,\n\t\t\t      unsigned transport_id,\n\t\t\t      const void *pkt, pj_size_t size,\n\t\t\t      const pj_sockaddr_t *dst_addr,\n\t\t\t      unsigned dst_addr_len)\n{\n    pj_ice_strans *ice_st = (pj_ice_strans*)ice->user_data;\n    pj_ice_strans_comp *comp;\n    pj_status_t status;\n#if defined(ENABLE_TRACE) && (ENABLE_TRACE != 0)\n    char daddr[PJ_INET6_ADDRSTRLEN];\n#endif\n\n    PJ_ASSERT_RETURN(comp_id && comp_id <= ice_st->comp_cnt, PJ_EINVAL);\n\n    comp = ice_st->comp[comp_id-1];\n\n    TRACE_PKT((comp->ice_st->obj_name,\n\t       \"Component %d TX packet to %s:%d with transport %d\",\n\t       comp_id,\n\t       pj_sockaddr_print(dst_addr, daddr, sizeof(addr), 0),\n\t       pj_sockaddr_get_port(dst_addr),\n\t       transport_id));\n\n    if (transport_id == TP_TURN) {\n\tif (comp->turn_sock) {\n\t    status = pj_turn_sock_sendto(comp->turn_sock,\n\t\t\t\t\t (const pj_uint8_t*)pkt,\n\t\t\t\t\t (unsigned)size,\n\t\t\t\t\t dst_addr, dst_addr_len);\n\t} else {\n\t    status = PJ_EINVALIDOP;\n\t}\n    } else if (transport_id == TP_STUN) {\n\tstatus = pj_stun_sock_sendto(comp->stun_sock, NULL,\n\t\t\t\t     pkt, (unsigned)size, 0,\n\t\t\t\t     dst_addr, dst_addr_len);\n    } else {\n\tpj_assert(!\"Invalid transport ID\");\n\tstatus = PJ_EINVALIDOP;\n    }\n\n    return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status;\n}\n\n/*\n * Callback called by ICE session when it receives application data.\n */\nstatic void ice_rx_data(pj_ice_sess *ice,\n\t\t        unsigned comp_id,\n\t\t\tunsigned transport_id,\n\t\t        void *pkt, pj_size_t size,\n\t\t        const pj_sockaddr_t *src_addr,\n\t\t        unsigned src_addr_len)\n{\n    pj_ice_strans *ice_st = (pj_ice_strans*)ice->user_data;\n\n    PJ_UNUSED_ARG(transport_id);\n\n    if (ice_st->cb.on_rx_data) {\n\t(*ice_st->cb.on_rx_data)(ice_st, comp_id, pkt, size,\n\t\t\t\t src_addr, src_addr_len);\n    }\n}\n\n/* Notification when incoming packet has been received from\n * the STUN socket.\n */\nstatic pj_bool_t stun_on_rx_data(pj_stun_sock *stun_sock,\n\t\t\t\t void *pkt,\n\t\t\t\t unsigned pkt_len,\n\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t unsigned addr_len)\n{\n    pj_ice_strans_comp *comp;\n    pj_ice_strans *ice_st;\n    pj_status_t status;\n\n    comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock);\n    if (comp == NULL) {\n\t/* We have disassociated ourselves from the STUN socket */\n\treturn PJ_FALSE;\n    }\n\n    ice_st = comp->ice_st;\n\n    pj_grp_lock_add_ref(ice_st->grp_lock);\n\n    if (ice_st->ice == NULL) {\n\t/* The ICE session is gone, but we're still receiving packets.\n\t * This could also happen if remote doesn't do ICE. So just\n\t * report this to application.\n\t */\n\tif (ice_st->cb.on_rx_data) {\n\t    (*ice_st->cb.on_rx_data)(ice_st, comp->comp_id, pkt, pkt_len,\n\t\t\t\t     src_addr, addr_len);\n\t}\n\n    } else {\n\n\t/* Hand over the packet to ICE session */\n\tstatus = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id,\n\t\t\t\t       TP_STUN, pkt, pkt_len,\n\t\t\t\t       src_addr, addr_len);\n\n\tif (status != PJ_SUCCESS) {\n\t    ice_st_perror(comp->ice_st, \"Error processing packet\",\n\t\t\t  status);\n\t}\n    }\n\n    return pj_grp_lock_dec_ref(ice_st->grp_lock) ? PJ_FALSE : PJ_TRUE;\n}\n\n/* Notifification when asynchronous send operation to the STUN socket\n * has completed.\n */\nstatic pj_bool_t stun_on_data_sent(pj_stun_sock *stun_sock,\n\t\t\t\t   pj_ioqueue_op_key_t *send_key,\n\t\t\t\t   pj_ssize_t sent)\n{\n    PJ_UNUSED_ARG(stun_sock);\n    PJ_UNUSED_ARG(send_key);\n    PJ_UNUSED_ARG(sent);\n    return PJ_TRUE;\n}\n\n/* Notification when the status of the STUN transport has changed. */\nstatic pj_bool_t stun_on_status(pj_stun_sock *stun_sock,\n\t\t\t\tpj_stun_sock_op op,\n\t\t\t\tpj_status_t status)\n{\n    pj_ice_strans_comp *comp;\n    pj_ice_strans *ice_st;\n    pj_ice_sess_cand *cand = NULL;\n    unsigned i;\n\n    pj_assert(status != PJ_EPENDING);\n\n    comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock);\n    ice_st = comp->ice_st;\n\n    pj_grp_lock_add_ref(ice_st->grp_lock);\n\n    /* Wait until initialization completes */\n    pj_grp_lock_acquire(ice_st->grp_lock);\n\n    /* Find the srflx cancidate */\n    for (i=0; i<comp->cand_cnt; ++i) {\n\tif (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_SRFLX) {\n\t    cand = &comp->cand_list[i];\n\t    break;\n\t}\n    }\n\n    pj_grp_lock_release(ice_st->grp_lock);\n\n    /* It is possible that we don't have srflx candidate even though this\n     * callback is called. This could happen when we cancel adding srflx\n     * candidate due to initialization error.\n     */\n    if (cand == NULL) {\n\treturn pj_grp_lock_dec_ref(ice_st->grp_lock) ? PJ_FALSE : PJ_TRUE;\n    }\n\n    switch (op) {\n    case PJ_STUN_SOCK_DNS_OP:\n\tif (status != PJ_SUCCESS) {\n\t    /* May not have cand, e.g. when error during init */\n\t    if (cand)\n\t\tcand->status = status;\n\t    if (!ice_st->cfg.stun.ignore_stun_error) {\n\t\tsess_fail(ice_st, PJ_ICE_STRANS_OP_INIT,\n\t\t          \"DNS resolution failed\", status);\n\t    } else {\n\t\tPJ_LOG(4,(ice_st->obj_name,\n\t\t\t  \"STUN error is ignored for comp %d\",\n\t\t\t  comp->comp_id));\n\t    }\n\t}\n\tbreak;\n    case PJ_STUN_SOCK_BINDING_OP:\n    case PJ_STUN_SOCK_MAPPED_ADDR_CHANGE:\n\tif (status == PJ_SUCCESS) {\n\t    pj_stun_sock_info info;\n\n\t    status = pj_stun_sock_get_info(stun_sock, &info);\n\t    if (status == PJ_SUCCESS) {\n\t\tchar ipaddr[PJ_INET6_ADDRSTRLEN+10];\n\t\tconst char *op_name = (op==PJ_STUN_SOCK_BINDING_OP) ?\n\t\t\t\t    \"Binding discovery complete\" :\n\t\t\t\t    \"srflx address changed\";\n\t\tpj_bool_t dup = PJ_FALSE;\n\n\t\t/* Eliminate the srflx candidate if the address is\n\t\t * equal to other (host) candidates.\n\t\t */\n\t\tfor (i=0; i<comp->cand_cnt; ++i) {\n\t\t    if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_HOST &&\n\t\t\tpj_sockaddr_cmp(&comp->cand_list[i].addr,\n\t\t\t\t\t&info.mapped_addr) == 0)\n\t\t    {\n\t\t\tdup = PJ_TRUE;\n\t\t\tbreak;\n\t\t    }\n\t\t}\n\n\t\tif (dup) {\n\t\t    /* Duplicate found, remove the srflx candidate */\n\t\t    unsigned idx = (unsigned)(cand - comp->cand_list);\n\n\t\t    /* Update default candidate index */\n\t\t    if (comp->default_cand > idx) {\n\t\t\t--comp->default_cand;\n\t\t    } else if (comp->default_cand == idx) {\n\t\t\tcomp->default_cand = 0;\n\t\t    }\n\n\t\t    /* Remove srflx candidate */\n\t\t    pj_array_erase(comp->cand_list, sizeof(comp->cand_list[0]),\n\t\t\t\t   comp->cand_cnt, idx);\n\t\t    --comp->cand_cnt;\n\t\t} else {\n\t\t    /* Otherwise update the address */\n\t\t    pj_sockaddr_cp(&cand->addr, &info.mapped_addr);\n\t\t    cand->status = PJ_SUCCESS;\n\t\t}\n\n\t\tPJ_LOG(4,(comp->ice_st->obj_name,\n\t\t\t  \"Comp %d: %s, \"\n\t\t\t  \"srflx address is %s\",\n\t\t\t  comp->comp_id, op_name,\n\t\t\t  pj_sockaddr_print(&info.mapped_addr, ipaddr,\n\t\t\t\t\t     sizeof(ipaddr), 3)));\n\n\t\tsess_init_update(ice_st);\n\t    }\n\t}\n\n\tif (status != PJ_SUCCESS) {\n\t    /* May not have cand, e.g. when error during init */\n\t    if (cand)\n\t\tcand->status = status;\n\t    if (!ice_st->cfg.stun.ignore_stun_error || comp->cand_cnt==1) {\n\t\tsess_fail(ice_st, PJ_ICE_STRANS_OP_INIT,\n\t\t\t  \"STUN binding request failed\", status);\n\t    } else {\n\t\tPJ_LOG(4,(ice_st->obj_name,\n\t\t\t  \"STUN error is ignored for comp %d\",\n\t\t\t  comp->comp_id));\n\n\t\tif (cand) {\n\t\t    unsigned idx = (unsigned)(cand - comp->cand_list);\n\n\t\t    /* Update default candidate index */\n\t\t    if (comp->default_cand == idx) {\n\t\t\tcomp->default_cand = !idx;\n\t\t    }\n\t\t}\n\n\t\tsess_init_update(ice_st);\n\t    }\n\t}\n\tbreak;\n    case PJ_STUN_SOCK_KEEP_ALIVE_OP:\n\tif (status != PJ_SUCCESS) {\n\t    pj_assert(cand != NULL);\n\t    cand->status = status;\n\t    if (!ice_st->cfg.stun.ignore_stun_error) {\n\t\tsess_fail(ice_st, PJ_ICE_STRANS_OP_INIT,\n\t\t\t  \"STUN keep-alive failed\", status);\n\t    } else {\n\t\tPJ_LOG(4,(ice_st->obj_name, \"STUN error is ignored\"));\n\t    }\n\t}\n\tbreak;\n    }\n\n    return pj_grp_lock_dec_ref(ice_st->grp_lock)? PJ_FALSE : PJ_TRUE;\n}\n\n/* Callback when TURN socket has received a packet */\nstatic void turn_on_rx_data(pj_turn_sock *turn_sock,\n\t\t\t    void *pkt,\n\t\t\t    unsigned pkt_len,\n\t\t\t    const pj_sockaddr_t *peer_addr,\n\t\t\t    unsigned addr_len)\n{\n    pj_ice_strans_comp *comp;\n    pj_status_t status;\n\n    comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock);\n    if (comp == NULL) {\n\t/* We have disassociated ourselves from the TURN socket */\n\treturn;\n    }\n\n    pj_grp_lock_add_ref(comp->ice_st->grp_lock);\n\n    if (comp->ice_st->ice == NULL) {\n\t/* The ICE session is gone, but we're still receiving packets.\n\t * This could also happen if remote doesn't do ICE and application\n\t * specifies TURN as the default address in SDP.\n\t * So in this case just give the packet to application.\n\t */\n\tif (comp->ice_st->cb.on_rx_data) {\n\t    (*comp->ice_st->cb.on_rx_data)(comp->ice_st, comp->comp_id, pkt,\n\t\t\t\t\t   pkt_len, peer_addr, addr_len);\n\t}\n\n    } else {\n\n\t/* Hand over the packet to ICE */\n\tstatus = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id,\n\t\t\t\t       TP_TURN, pkt, pkt_len,\n\t\t\t\t       peer_addr, addr_len);\n\n\tif (status != PJ_SUCCESS) {\n\t    ice_st_perror(comp->ice_st,\n\t\t\t  \"Error processing packet from TURN relay\",\n\t\t\t  status);\n\t}\n    }\n\n    pj_grp_lock_dec_ref(comp->ice_st->grp_lock);\n}\n\n\n/* Callback when TURN client state has changed */\nstatic void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state,\n\t\t\t  pj_turn_state_t new_state)\n{\n    pj_ice_strans_comp *comp;\n\n    comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock);\n    if (comp == NULL) {\n\t/* Not interested in further state notification once the relay is\n\t * disconnecting.\n\t */\n\treturn;\n    }\n\n    PJ_LOG(5,(comp->ice_st->obj_name, \"TURN client state changed %s --> %s\",\n\t      pj_turn_state_name(old_state), pj_turn_state_name(new_state)));\n    pj_log_push_indent();\n\n    pj_grp_lock_add_ref(comp->ice_st->grp_lock);\n\n    if (new_state == PJ_TURN_STATE_READY) {\n\tpj_turn_session_info rel_info;\n\tchar ipaddr[PJ_INET6_ADDRSTRLEN+8];\n\tpj_ice_sess_cand *cand = NULL;\n\tunsigned i;\n\n\tcomp->turn_err_cnt = 0;\n\n\t/* Get allocation info */\n\tpj_turn_sock_get_info(turn_sock, &rel_info);\n\n\t/* Wait until initialization completes */\n\tpj_grp_lock_acquire(comp->ice_st->grp_lock);\n\n\t/* Find relayed candidate in the component */\n\tfor (i=0; i<comp->cand_cnt; ++i) {\n\t    if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED) {\n\t\tcand = &comp->cand_list[i];\n\t\tbreak;\n\t    }\n\t}\n\tpj_assert(cand != NULL);\n\n\tpj_grp_lock_release(comp->ice_st->grp_lock);\n\n\t/* Update candidate */\n\tpj_sockaddr_cp(&cand->addr, &rel_info.relay_addr);\n\tpj_sockaddr_cp(&cand->base_addr, &rel_info.relay_addr);\n\tpj_sockaddr_cp(&cand->rel_addr, &rel_info.mapped_addr);\n\tpj_ice_calc_foundation(comp->ice_st->pool, &cand->foundation,\n\t\t\t       PJ_ICE_CAND_TYPE_RELAYED,\n\t\t\t       &rel_info.relay_addr);\n\tcand->status = PJ_SUCCESS;\n\n\t/* Set default candidate to relay */\n\tcomp->default_cand = (unsigned)(cand - comp->cand_list);\n\n\tPJ_LOG(4,(comp->ice_st->obj_name,\n\t\t  \"Comp %d: TURN allocation complete, relay address is %s\",\n\t\t  comp->comp_id,\n\t\t  pj_sockaddr_print(&rel_info.relay_addr, ipaddr,\n\t\t\t\t     sizeof(ipaddr), 3)));\n\n\tsess_init_update(comp->ice_st);\n\n    } else if (new_state >= PJ_TURN_STATE_DEALLOCATING) {\n\tpj_turn_session_info info;\n\n\t++comp->turn_err_cnt;\n\n\tpj_turn_sock_get_info(turn_sock, &info);\n\n\t/* Unregister ourself from the TURN relay */\n\tpj_turn_sock_set_user_data(turn_sock, NULL);\n\tcomp->turn_sock = NULL;\n\n\t/* Set session to fail on error. last_status PJ_SUCCESS means normal\n\t * deallocation, which should not trigger sess_fail as it may have\n\t * been initiated by ICE destroy\n\t */\n\tif (info.last_status != PJ_SUCCESS) {\n\t    if (comp->ice_st->state < PJ_ICE_STRANS_STATE_READY) {\n\t\tsess_fail(comp->ice_st, PJ_ICE_STRANS_OP_INIT,\n\t\t\t  \"TURN allocation failed\", info.last_status);\n\t    } else if (comp->turn_err_cnt > 1) {\n\t\tsess_fail(comp->ice_st, PJ_ICE_STRANS_OP_KEEP_ALIVE,\n\t\t\t  \"TURN refresh failed\", info.last_status);\n\t    } else {\n\t\tPJ_PERROR(4,(comp->ice_st->obj_name, info.last_status,\n\t\t\t  \"Comp %d: TURN allocation failed, retrying\",\n\t\t\t  comp->comp_id));\n\t\tadd_update_turn(comp->ice_st, comp);\n\t    }\n\t}\n    }\n\n    pj_grp_lock_dec_ref(comp->ice_st->grp_lock);\n\n    pj_log_pop_indent();\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjnath/nat_detect.c",
    "content": "/* $Id: nat_detect.c 4360 2013-02-21 11:26:35Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjnath/nat_detect.h>\n#include <pjnath/errno.h>\n#include <pj/assert.h>\n#include <pj/ioqueue.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n#include <pj/timer.h>\n#include <pj/compat/socket.h>\n\n\nstatic const char *nat_type_names[] =\n{\n    \"Unknown\",\n    \"ErrUnknown\",\n    \"Open\",\n    \"Blocked\",\n    \"Symmetric UDP\",\n    \"Full Cone\",\n    \"Symmetric\",\n    \"Restricted\",\n    \"Port Restricted\"\n};\n\n\n#define CHANGE_IP_FLAG\t\t4\n#define CHANGE_PORT_FLAG\t2\n#define CHANGE_IP_PORT_FLAG\t(CHANGE_IP_FLAG | CHANGE_PORT_FLAG)\n#define TEST_INTERVAL\t\t50\n\nenum test_type\n{\n    ST_TEST_1,\n    ST_TEST_2,\n    ST_TEST_3,\n    ST_TEST_1B,\n    ST_MAX\n};\n\nstatic const char *test_names[] =\n{\n    \"Test I: Binding request\",\n    \"Test II: Binding request with change address and port request\",\n    \"Test III: Binding request with change port request\",\n    \"Test IB: Binding request to alternate address\"\n};\n\nenum timer_type\n{\n    TIMER_TEST\t    = 1,\n    TIMER_DESTROY   = 2\n};\n\ntypedef struct nat_detect_session\n{\n    pj_pool_t\t\t    *pool;\n    pj_grp_lock_t\t    *grp_lock;\n\n    pj_timer_heap_t\t    *timer_heap;\n    pj_timer_entry\t     timer;\n    unsigned\t\t     timer_executed;\n\n    void\t\t    *user_data;\n    pj_stun_nat_detect_cb   *cb;\n    pj_sock_t\t\t     sock;\n    pj_sockaddr_in\t     local_addr;\n    pj_ioqueue_key_t\t    *key;\n    pj_sockaddr_in\t     server;\n    pj_sockaddr_in\t    *cur_server;\n    pj_stun_session\t    *stun_sess;\n\n    pj_ioqueue_op_key_t\t     read_op, write_op;\n    pj_uint8_t\t\t     rx_pkt[PJ_STUN_MAX_PKT_LEN];\n    pj_ssize_t\t\t     rx_pkt_len;\n    pj_sockaddr_in\t     src_addr;\n    int\t\t\t     src_addr_len;\n\n    struct result\n    {\n\tpj_bool_t\texecuted;\n\tpj_bool_t\tcomplete;\n\tpj_status_t\tstatus;\n\tpj_sockaddr_in\tma;\n\tpj_sockaddr_in\tca;\n\tpj_stun_tx_data\t*tdata;\n    } result[ST_MAX];\n\n} nat_detect_session;\n\n\nstatic void on_read_complete(pj_ioqueue_key_t *key, \n                             pj_ioqueue_op_key_t *op_key, \n                             pj_ssize_t bytes_read);\nstatic void on_request_complete(pj_stun_session *sess,\n\t\t\t        pj_status_t status,\n\t\t\t\tvoid *token,\n\t\t\t        pj_stun_tx_data *tdata,\n\t\t\t        const pj_stun_msg *response,\n\t\t\t\tconst pj_sockaddr_t *src_addr,\n\t\t\t\tunsigned src_addr_len);\nstatic pj_status_t on_send_msg(pj_stun_session *sess,\n\t\t\t       void *token,\n\t\t\t       const void *pkt,\n\t\t\t       pj_size_t pkt_size,\n\t\t\t       const pj_sockaddr_t *dst_addr,\n\t\t\t       unsigned addr_len);\n\nstatic pj_status_t send_test(nat_detect_session *sess,\n\t\t\t     enum test_type test_id,\n\t\t\t     const pj_sockaddr_in *alt_addr,\n\t\t\t     pj_uint32_t change_flag);\nstatic void on_sess_timer(pj_timer_heap_t *th,\n\t\t\t     pj_timer_entry *te);\nstatic void sess_destroy(nat_detect_session *sess);\nstatic void sess_on_destroy(void *member);\n\n/*\n * Get the NAT name from the specified NAT type.\n */\nPJ_DEF(const char*) pj_stun_get_nat_name(pj_stun_nat_type type)\n{\n    PJ_ASSERT_RETURN(type >= 0 && type <= PJ_STUN_NAT_TYPE_PORT_RESTRICTED,\n\t\t     \"*Invalid*\");\n\n    return nat_type_names[type];\n}\n\nstatic int test_executed(nat_detect_session *sess)\n{\n    unsigned i, count;\n    for (i=0, count=0; i<PJ_ARRAY_SIZE(sess->result); ++i) {\n\tif (sess->result[i].executed)\n\t    ++count;\n    }\n    return count;\n}\n\nstatic int test_completed(nat_detect_session *sess)\n{\n    unsigned i, count;\n    for (i=0, count=0; i<PJ_ARRAY_SIZE(sess->result); ++i) {\n\tif (sess->result[i].complete)\n\t    ++count;\n    }\n    return count;\n}\n\nstatic pj_status_t get_local_interface(const pj_sockaddr_in *server,\n\t\t\t\t       pj_in_addr *local_addr)\n{\n    pj_sock_t sock;\n    pj_sockaddr_in tmp;\n    int addr_len;\n    pj_status_t status;\n\n    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    status = pj_sock_bind_in(sock, 0, 0);\n    if (status != PJ_SUCCESS) {\n\tpj_sock_close(sock);\n\treturn status;\n    }\n\n    status = pj_sock_connect(sock, server, sizeof(pj_sockaddr_in));\n    if (status != PJ_SUCCESS) {\n\tpj_sock_close(sock);\n\treturn status;\n    }\n\n    addr_len = sizeof(pj_sockaddr_in);\n    status = pj_sock_getsockname(sock, &tmp, &addr_len);\n    if (status != PJ_SUCCESS) {\n\tpj_sock_close(sock);\n\treturn status;\n    }\n\n    local_addr->s_addr = tmp.sin_addr.s_addr;\n    \n    pj_sock_close(sock);\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_stun_detect_nat_type(const pj_sockaddr_in *server,\n\t\t\t\t\t    pj_stun_config *stun_cfg,\n\t\t\t\t\t    void *user_data,\n\t\t\t\t\t    pj_stun_nat_detect_cb *cb)\n{\n    pj_pool_t *pool;\n    nat_detect_session *sess;\n    pj_stun_session_cb sess_cb;\n    pj_ioqueue_callback ioqueue_cb;\n    int addr_len;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(server && stun_cfg, PJ_EINVAL);\n    PJ_ASSERT_RETURN(stun_cfg->pf && stun_cfg->ioqueue && stun_cfg->timer_heap,\n\t\t     PJ_EINVAL);\n\n    /*\n     * Init NAT detection session.\n     */\n    pool = pj_pool_create(stun_cfg->pf, \"natck%p\", PJNATH_POOL_LEN_NATCK, \n\t\t\t  PJNATH_POOL_INC_NATCK, NULL);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    sess = PJ_POOL_ZALLOC_T(pool, nat_detect_session);\n    sess->pool = pool;\n    sess->user_data = user_data;\n    sess->cb = cb;\n\n    status = pj_grp_lock_create(pool, NULL, &sess->grp_lock);\n    if (status != PJ_SUCCESS) {\n\t/* Group lock not created yet, just destroy pool and return */\n\tpj_pool_release(pool);\n\treturn status;\n    }\n\n    pj_grp_lock_add_ref(sess->grp_lock);\n    pj_grp_lock_add_handler(sess->grp_lock, pool, sess, &sess_on_destroy);\n\n    pj_memcpy(&sess->server, server, sizeof(pj_sockaddr_in));\n\n    /*\n     * Init timer to self-destroy.\n     */\n    sess->timer_heap = stun_cfg->timer_heap;\n    sess->timer.cb = &on_sess_timer;\n    sess->timer.user_data = sess;\n\n\n    /*\n     * Initialize socket.\n     */\n    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sess->sock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /*\n     * Bind to any.\n     */\n    pj_bzero(&sess->local_addr, sizeof(pj_sockaddr_in));\n    sess->local_addr.sin_family = pj_AF_INET();\n    status = pj_sock_bind(sess->sock, &sess->local_addr, \n\t\t\t  sizeof(pj_sockaddr_in));\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /*\n     * Get local/bound address.\n     */\n    addr_len = sizeof(sess->local_addr);\n    status = pj_sock_getsockname(sess->sock, &sess->local_addr, &addr_len);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /*\n     * Find out which interface is used to send to the server.\n     */\n    status = get_local_interface(server, &sess->local_addr.sin_addr);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    PJ_LOG(5,(sess->pool->obj_name, \"Local address is %s:%d\",\n\t      pj_inet_ntoa(sess->local_addr.sin_addr), \n\t      pj_ntohs(sess->local_addr.sin_port)));\n\n    PJ_LOG(5,(sess->pool->obj_name, \"Server set to %s:%d\",\n\t      pj_inet_ntoa(server->sin_addr), \n\t      pj_ntohs(server->sin_port)));\n\n    /*\n     * Register socket to ioqueue to receive asynchronous input\n     * notification.\n     */\n    pj_bzero(&ioqueue_cb, sizeof(ioqueue_cb));\n    ioqueue_cb.on_read_complete = &on_read_complete;\n\n    status = pj_ioqueue_register_sock2(sess->pool, stun_cfg->ioqueue, \n\t\t\t\t       sess->sock, sess->grp_lock, sess,\n\t\t\t\t       &ioqueue_cb, &sess->key);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /*\n     * Create STUN session.\n     */\n    pj_bzero(&sess_cb, sizeof(sess_cb));\n    sess_cb.on_request_complete = &on_request_complete;\n    sess_cb.on_send_msg = &on_send_msg;\n    status = pj_stun_session_create(stun_cfg, pool->obj_name, &sess_cb,\n\t\t\t\t    PJ_FALSE, sess->grp_lock, &sess->stun_sess);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    pj_stun_session_set_user_data(sess->stun_sess, sess);\n\n    /*\n     * Kick-off ioqueue reading.\n     */\n    pj_ioqueue_op_key_init(&sess->read_op, sizeof(sess->read_op));\n    pj_ioqueue_op_key_init(&sess->write_op, sizeof(sess->write_op));\n    on_read_complete(sess->key, &sess->read_op, 0);\n\n    /*\n     * Start TEST_1\n     */\n    sess->timer.id = TIMER_TEST;\n    on_sess_timer(stun_cfg->timer_heap, &sess->timer);\n\n    return PJ_SUCCESS;\n\non_error:\n    sess_destroy(sess);\n    return status;\n}\n\n\nstatic void sess_destroy(nat_detect_session *sess)\n{\n    if (sess->stun_sess) { \n\tpj_stun_session_destroy(sess->stun_sess);\n\tsess->stun_sess = NULL;\n    }\n\n    if (sess->key) {\n\tpj_ioqueue_unregister(sess->key);\n\tsess->key = NULL;\n\tsess->sock = PJ_INVALID_SOCKET;\n    } else if (sess->sock && sess->sock != PJ_INVALID_SOCKET) {\n\tpj_sock_close(sess->sock);\n\tsess->sock = PJ_INVALID_SOCKET;\n    }\n\n    if (sess->grp_lock) {\n\tpj_grp_lock_dec_ref(sess->grp_lock);\n    }\n}\n\nstatic void sess_on_destroy(void *member)\n{\n    nat_detect_session *sess = (nat_detect_session*)member;\n    if (sess->pool) {\n\tpj_pool_release(sess->pool);\n    }\n}\n\nstatic void end_session(nat_detect_session *sess,\n\t\t\tpj_status_t status,\n\t\t\tpj_stun_nat_type nat_type)\n{\n    pj_stun_nat_detect_result result;\n    char errmsg[PJ_ERR_MSG_SIZE];\n    pj_time_val delay;\n\n    if (sess->timer.id != 0) {\n\tpj_timer_heap_cancel(sess->timer_heap, &sess->timer);\n\tsess->timer.id = 0;\n    }\n\n    pj_bzero(&result, sizeof(result));\n    errmsg[0] = '\\0';\n    result.status_text = errmsg;\n\n    result.status = status;\n    pj_strerror(status, errmsg, sizeof(errmsg));\n    result.nat_type = nat_type;\n    result.nat_type_name = nat_type_names[result.nat_type];\n\n    if (sess->cb)\n\t(*sess->cb)(sess->user_data, &result);\n\n    delay.sec = 0;\n    delay.msec = 0;\n\n    sess->timer.id = TIMER_DESTROY;\n    pj_timer_heap_schedule(sess->timer_heap, &sess->timer, &delay);\n}\n\n\n/*\n * Callback upon receiving packet from network.\n */\nstatic void on_read_complete(pj_ioqueue_key_t *key, \n                             pj_ioqueue_op_key_t *op_key, \n                             pj_ssize_t bytes_read)\n{\n    nat_detect_session *sess;\n    pj_status_t status;\n\n    sess = (nat_detect_session *) pj_ioqueue_get_user_data(key);\n    pj_assert(sess != NULL);\n\n    pj_grp_lock_acquire(sess->grp_lock);\n\n    /* Ignore packet when STUN session has been destroyed */\n    if (!sess->stun_sess)\n\tgoto on_return;\n\n    if (bytes_read < 0) {\n\tif (-bytes_read != PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK) &&\n\t    -bytes_read != PJ_STATUS_FROM_OS(OSERR_EINPROGRESS) && \n\t    -bytes_read != PJ_STATUS_FROM_OS(OSERR_ECONNRESET)) \n\t{\n\t    /* Permanent error */\n\t    end_session(sess, (pj_status_t)-bytes_read, \n\t\t\tPJ_STUN_NAT_TYPE_ERR_UNKNOWN);\n\t    goto on_return;\n\t}\n\n    } else if (bytes_read > 0) {\n\tpj_stun_session_on_rx_pkt(sess->stun_sess, sess->rx_pkt, bytes_read,\n\t\t\t\t  PJ_STUN_IS_DATAGRAM|PJ_STUN_CHECK_PACKET, \n\t\t\t\t  NULL, NULL, \n\t\t\t\t  &sess->src_addr, sess->src_addr_len);\n    }\n\n\n    sess->rx_pkt_len = sizeof(sess->rx_pkt);\n    sess->src_addr_len = sizeof(sess->src_addr);\n    status = pj_ioqueue_recvfrom(key, op_key, sess->rx_pkt, &sess->rx_pkt_len,\n\t\t\t\t PJ_IOQUEUE_ALWAYS_ASYNC, \n\t\t\t\t &sess->src_addr, &sess->src_addr_len);\n\n    if (status != PJ_EPENDING) {\n\tpj_assert(status != PJ_SUCCESS);\n\tend_session(sess, status, PJ_STUN_NAT_TYPE_ERR_UNKNOWN);\n    }\n\non_return:\n    pj_grp_lock_release(sess->grp_lock);\n}\n\n\n/*\n * Callback to send outgoing packet from STUN session.\n */\nstatic pj_status_t on_send_msg(pj_stun_session *stun_sess,\n\t\t\t       void *token,\n\t\t\t       const void *pkt,\n\t\t\t       pj_size_t pkt_size,\n\t\t\t       const pj_sockaddr_t *dst_addr,\n\t\t\t       unsigned addr_len)\n{\n    nat_detect_session *sess;\n    pj_ssize_t pkt_len;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(token);\n\n    sess = (nat_detect_session*) pj_stun_session_get_user_data(stun_sess);\n\n    pkt_len = pkt_size;\n    status = pj_ioqueue_sendto(sess->key, &sess->write_op, pkt, &pkt_len, 0,\n\t\t\t       dst_addr, addr_len);\n\n    return status;\n\n}\n\n/*\n * Callback upon request completion.\n */\nstatic void on_request_complete(pj_stun_session *stun_sess,\n\t\t\t        pj_status_t status,\n\t\t\t\tvoid *token,\n\t\t\t        pj_stun_tx_data *tdata,\n\t\t\t        const pj_stun_msg *response,\n\t\t\t\tconst pj_sockaddr_t *src_addr,\n\t\t\t\tunsigned src_addr_len)\n{\n    nat_detect_session *sess;\n    pj_stun_sockaddr_attr *mattr = NULL;\n    pj_stun_changed_addr_attr *ca = NULL;\n    pj_uint32_t *tsx_id;\n    int cmp;\n    unsigned test_id;\n\n    PJ_UNUSED_ARG(token);\n    PJ_UNUSED_ARG(tdata);\n    PJ_UNUSED_ARG(src_addr);\n    PJ_UNUSED_ARG(src_addr_len);\n\n    sess = (nat_detect_session*) pj_stun_session_get_user_data(stun_sess);\n\n    pj_grp_lock_acquire(sess->grp_lock);\n\n    /* Find errors in the response */\n    if (status == PJ_SUCCESS) {\n\n\t/* Check error message */\n\tif (PJ_STUN_IS_ERROR_RESPONSE(response->hdr.type)) {\n\t    pj_stun_errcode_attr *eattr;\n\t    int err_code;\n\n\t    eattr = (pj_stun_errcode_attr*)\n\t\t    pj_stun_msg_find_attr(response, PJ_STUN_ATTR_ERROR_CODE, 0);\n\n\t    if (eattr != NULL)\n\t\terr_code = eattr->err_code;\n\t    else\n\t\terr_code = PJ_STUN_SC_SERVER_ERROR;\n\n\t    status = PJ_STATUS_FROM_STUN_CODE(err_code);\n\n\n\t} else {\n\n\t    /* Get MAPPED-ADDRESS or XOR-MAPPED-ADDRESS */\n\t    mattr = (pj_stun_sockaddr_attr*)\n\t\t    pj_stun_msg_find_attr(response, PJ_STUN_ATTR_XOR_MAPPED_ADDR, 0);\n\t    if (mattr == NULL) {\n\t\tmattr = (pj_stun_sockaddr_attr*)\n\t\t\tpj_stun_msg_find_attr(response, PJ_STUN_ATTR_MAPPED_ADDR, 0);\n\t    }\n\n\t    if (mattr == NULL) {\n\t\tstatus = PJNATH_ESTUNNOMAPPEDADDR;\n\t    }\n\n\t    /* Get CHANGED-ADDRESS attribute */\n\t    ca = (pj_stun_changed_addr_attr*)\n\t\t pj_stun_msg_find_attr(response, PJ_STUN_ATTR_CHANGED_ADDR, 0);\n\n\t    if (ca == NULL) {\n\t\tstatus = PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_SERVER_ERROR);\n\t    }\n\n\t}\n    }\n\n    /* Save the result */\n    tsx_id = (pj_uint32_t*) tdata->msg->hdr.tsx_id;\n    test_id = tsx_id[2];\n\n    if (test_id >= ST_MAX) {\n\tPJ_LOG(4,(sess->pool->obj_name, \"Invalid transaction ID %u in response\",\n\t\t  test_id));\n\tend_session(sess, PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_SERVER_ERROR),\n\t\t    PJ_STUN_NAT_TYPE_ERR_UNKNOWN);\n\tgoto on_return;\n    }\n\n    PJ_LOG(5,(sess->pool->obj_name, \"Completed %s, status=%d\",\n\t      test_names[test_id], status));\n\n    sess->result[test_id].complete = PJ_TRUE;\n    sess->result[test_id].status = status;\n    if (status == PJ_SUCCESS) {\n\tpj_memcpy(&sess->result[test_id].ma, &mattr->sockaddr.ipv4,\n\t\t  sizeof(pj_sockaddr_in));\n\tpj_memcpy(&sess->result[test_id].ca, &ca->sockaddr.ipv4,\n\t\t  sizeof(pj_sockaddr_in));\n    }\n\n    /* Send Test 1B only when Test 2 completes. Must not send Test 1B\n     * before Test 2 completes to avoid creating mapping on the NAT.\n     */\n    if (!sess->result[ST_TEST_1B].executed && \n\tsess->result[ST_TEST_2].complete &&\n\tsess->result[ST_TEST_2].status != PJ_SUCCESS &&\n\tsess->result[ST_TEST_1].complete &&\n\tsess->result[ST_TEST_1].status == PJ_SUCCESS) \n    {\n\tcmp = pj_memcmp(&sess->local_addr, &sess->result[ST_TEST_1].ma,\n\t\t\tsizeof(pj_sockaddr_in));\n\tif (cmp != 0)\n\t    send_test(sess, ST_TEST_1B, &sess->result[ST_TEST_1].ca, 0);\n    }\n\n    if (test_completed(sess)<3 || test_completed(sess)!=test_executed(sess))\n\tgoto on_return;\n\n    /* Handle the test result according to RFC 3489 page 22:\n\n\n                        +--------+\n                        |  Test  |\n                        |   1    |\n                        +--------+\n                             |\n                             |\n                             V\n                            /\\              /\\\n                         N /  \\ Y          /  \\ Y             +--------+\n          UDP     <-------/Resp\\--------->/ IP \\------------->|  Test  |\n          Blocked         \\ ?  /          \\Same/              |   2    |\n                           \\  /            \\? /               +--------+\n                            \\/              \\/                    |\n                                             | N                  |\n                                             |                    V\n                                             V                    /\\\n                                         +--------+  Sym.      N /  \\\n                                         |  Test  |  UDP    <---/Resp\\\n                                         |   2    |  Firewall   \\ ?  /\n                                         +--------+              \\  /\n                                             |                    \\/\n                                             V                     |Y\n                  /\\                         /\\                    |\n   Symmetric  N  /  \\       +--------+   N  /  \\                   V\n      NAT  <--- / IP \\<-----|  Test  |<--- /Resp\\               Open\n                \\Same/      |   1B   |     \\ ?  /               Internet\n                 \\? /       +--------+      \\  /\n                  \\/                         \\/\n                  |                           |Y\n                  |                           |\n                  |                           V\n                  |                           Full\n                  |                           Cone\n                  V              /\\\n              +--------+        /  \\ Y\n              |  Test  |------>/Resp\\---->Restricted\n              |   3    |       \\ ?  /\n              +--------+        \\  /\n                                 \\/\n                                  |N\n                                  |       Port\n                                  +------>Restricted\n\n                 Figure 2: Flow for type discovery process\n     */\n\n    switch (sess->result[ST_TEST_1].status) {\n    case PJNATH_ESTUNTIMEDOUT:\n\t/*\n\t * Test 1 has timed-out. Conclude with NAT_TYPE_BLOCKED. \n\t */\n\tend_session(sess, PJ_SUCCESS, PJ_STUN_NAT_TYPE_BLOCKED);\n\tbreak;\n    case PJ_SUCCESS:\n\t/*\n\t * Test 1 is successful. Further tests are needed to detect\n\t * NAT type. Compare the MAPPED-ADDRESS with the local address.\n\t */\n\tcmp = pj_memcmp(&sess->local_addr, &sess->result[ST_TEST_1].ma,\n\t\t\tsizeof(pj_sockaddr_in));\n\tif (cmp==0) {\n\t    /*\n\t     * MAPPED-ADDRESS and local address is equal. Need one more\n\t     * test to determine NAT type.\n\t     */\n\t    switch (sess->result[ST_TEST_2].status) {\n\t    case PJ_SUCCESS:\n\t\t/*\n\t\t * Test 2 is also successful. We're in the open.\n\t\t */\n\t\tend_session(sess, PJ_SUCCESS, PJ_STUN_NAT_TYPE_OPEN);\n\t\tbreak;\n\t    case PJNATH_ESTUNTIMEDOUT:\n\t\t/*\n\t\t * Test 2 has timed out. We're behind somekind of UDP\n\t\t * firewall.\n\t\t */\n\t\tend_session(sess, PJ_SUCCESS, PJ_STUN_NAT_TYPE_SYMMETRIC_UDP);\n\t\tbreak;\n\t    default:\n\t\t/*\n\t\t * We've got other error with Test 2.\n\t\t */\n\t\tend_session(sess, sess->result[ST_TEST_2].status, \n\t\t\t    PJ_STUN_NAT_TYPE_ERR_UNKNOWN);\n\t\tbreak;\n\t    }\n\t} else {\n\t    /*\n\t     * MAPPED-ADDRESS is different than local address.\n\t     * We're behind NAT.\n\t     */\n\t    switch (sess->result[ST_TEST_2].status) {\n\t    case PJ_SUCCESS:\n\t\t/*\n\t\t * Test 2 is successful. We're behind a full-cone NAT.\n\t\t */\n\t\tend_session(sess, PJ_SUCCESS, PJ_STUN_NAT_TYPE_FULL_CONE);\n\t\tbreak;\n\t    case PJNATH_ESTUNTIMEDOUT:\n\t\t/*\n\t\t * Test 2 has timed-out Check result of test 1B..\n\t\t */\n\t\tswitch (sess->result[ST_TEST_1B].status) {\n\t\tcase PJ_SUCCESS:\n\t\t    /*\n\t\t     * Compare the MAPPED-ADDRESS of test 1B with the\n\t\t     * MAPPED-ADDRESS returned in test 1..\n\t\t     */\n\t\t    cmp = pj_memcmp(&sess->result[ST_TEST_1].ma,\n\t\t\t\t    &sess->result[ST_TEST_1B].ma,\n\t\t\t\t    sizeof(pj_sockaddr_in));\n\t\t    if (cmp != 0) {\n\t\t\t/*\n\t\t\t * MAPPED-ADDRESS is different, we're behind a\n\t\t\t * symmetric NAT.\n\t\t\t */\n\t\t\tend_session(sess, PJ_SUCCESS,\n\t\t\t\t    PJ_STUN_NAT_TYPE_SYMMETRIC);\n\t\t    } else {\n\t\t\t/*\n\t\t\t * MAPPED-ADDRESS is equal. We're behind a restricted\n\t\t\t * or port-restricted NAT, depending on the result of\n\t\t\t * test 3.\n\t\t\t */\n\t\t\tswitch (sess->result[ST_TEST_3].status) {\n\t\t\tcase PJ_SUCCESS:\n\t\t\t    /*\n\t\t\t     * Test 3 is successful, we're behind a restricted\n\t\t\t     * NAT.\n\t\t\t     */\n\t\t\t    end_session(sess, PJ_SUCCESS,\n\t\t\t\t\tPJ_STUN_NAT_TYPE_RESTRICTED);\n\t\t\t    break;\n\t\t\tcase PJNATH_ESTUNTIMEDOUT:\n\t\t\t    /*\n\t\t\t     * Test 3 failed, we're behind a port restricted\n\t\t\t     * NAT.\n\t\t\t     */\n\t\t\t    end_session(sess, PJ_SUCCESS,\n\t\t\t\t\tPJ_STUN_NAT_TYPE_PORT_RESTRICTED);\n\t\t\t    break;\n\t\t\tdefault:\n\t\t\t    /*\n\t\t\t     * Got other error with test 3.\n\t\t\t     */\n\t\t\t    end_session(sess, sess->result[ST_TEST_3].status,\n\t\t\t\t\tPJ_STUN_NAT_TYPE_ERR_UNKNOWN);\n\t\t\t    break;\n\t\t\t}\n\t\t    }\n\t\t    break;\n\t\tcase PJNATH_ESTUNTIMEDOUT:\n\t\t    /*\n\t\t     * Strangely test 1B has failed. Maybe connectivity was\n\t\t     * lost? Or perhaps port 3489 (the usual port number in\n\t\t     * CHANGED-ADDRESS) is blocked?\n\t\t     */\n\t\t    switch (sess->result[ST_TEST_3].status) {\n\t\t    case PJ_SUCCESS:\n\t\t\t/* Although test 1B failed, test 3 was successful.\n\t\t\t * It could be that port 3489 is blocked, while the\n\t\t\t * NAT itself looks to be a Restricted one.\n\t\t\t */\n\t\t\tend_session(sess, PJ_SUCCESS, \n\t\t\t\t    PJ_STUN_NAT_TYPE_RESTRICTED);\n\t\t\tbreak;\n\t\t    default:\n\t\t\t/* Can't distinguish between Symmetric and Port\n\t\t\t * Restricted, so set the type to Unknown\n\t\t\t */\n\t\t\tend_session(sess, PJ_SUCCESS, \n\t\t\t\t    PJ_STUN_NAT_TYPE_ERR_UNKNOWN);\n\t\t\tbreak;\n\t\t    }\n\t\t    break;\n\t\tdefault:\n\t\t    /*\n\t\t     * Got other error with test 1B.\n\t\t     */\n\t\t    end_session(sess, sess->result[ST_TEST_1B].status,\n\t\t\t\tPJ_STUN_NAT_TYPE_ERR_UNKNOWN);\n\t\t    break;\n\t\t}\n\t\tbreak;\n\t    default:\n\t\t/*\n\t\t * We've got other error with Test 2.\n\t\t */\n\t\tend_session(sess, sess->result[ST_TEST_2].status, \n\t\t\t    PJ_STUN_NAT_TYPE_ERR_UNKNOWN);\n\t\tbreak;\n\t    }\n\t}\n\tbreak;\n    default:\n\t/*\n\t * We've got other error with Test 1.\n\t */\n\tend_session(sess, sess->result[ST_TEST_1].status, \n\t\t    PJ_STUN_NAT_TYPE_ERR_UNKNOWN);\n\tbreak;\n    }\n\non_return:\n    pj_grp_lock_release(sess->grp_lock);\n}\n\n\n/* Perform test */\nstatic pj_status_t send_test(nat_detect_session *sess,\n\t\t\t     enum test_type test_id,\n\t\t\t     const pj_sockaddr_in *alt_addr,\n\t\t\t     pj_uint32_t change_flag)\n{\n    pj_uint32_t magic, tsx_id[3];\n    pj_status_t status;\n\n    sess->result[test_id].executed = PJ_TRUE;\n\n    /* Randomize tsx id */\n    do {\n\tmagic = pj_rand();\n    } while (magic == PJ_STUN_MAGIC);\n\n    tsx_id[0] = pj_rand();\n    tsx_id[1] = pj_rand();\n    tsx_id[2] = test_id;\n\n    /* Create BIND request */\n    status = pj_stun_session_create_req(sess->stun_sess, \n\t\t\t\t\tPJ_STUN_BINDING_REQUEST, magic,\n\t\t\t\t\t(pj_uint8_t*)tsx_id, \n\t\t\t\t\t&sess->result[test_id].tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Add CHANGE-REQUEST attribute */\n    status = pj_stun_msg_add_uint_attr(sess->pool, \n\t\t\t\t       sess->result[test_id].tdata->msg,\n\t\t\t\t       PJ_STUN_ATTR_CHANGE_REQUEST,\n\t\t\t\t       change_flag);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Configure alternate address */\n    if (alt_addr)\n\tsess->cur_server = (pj_sockaddr_in*) alt_addr;\n    else\n\tsess->cur_server = &sess->server;\n\n    PJ_LOG(5,(sess->pool->obj_name, \n              \"Performing %s to %s:%d\", \n\t      test_names[test_id],\n\t      pj_inet_ntoa(sess->cur_server->sin_addr),\n\t      pj_ntohs(sess->cur_server->sin_port)));\n\n    /* Send the request */\n    status = pj_stun_session_send_msg(sess->stun_sess, NULL, PJ_TRUE,\n\t\t\t\t      PJ_TRUE, sess->cur_server, \n\t\t\t\t      sizeof(pj_sockaddr_in),\n\t\t\t\t      sess->result[test_id].tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    return PJ_SUCCESS;\n\non_error:\n    sess->result[test_id].complete = PJ_TRUE;\n    sess->result[test_id].status = status;\n\n    return status;\n}\n\n\n/* Timer callback */\nstatic void on_sess_timer(pj_timer_heap_t *th,\n\t\t\t     pj_timer_entry *te)\n{\n    nat_detect_session *sess;\n\n    sess = (nat_detect_session*) te->user_data;\n\n    if (te->id == TIMER_DESTROY) {\n\tpj_grp_lock_acquire(sess->grp_lock);\n\tpj_ioqueue_unregister(sess->key);\n\tsess->key = NULL;\n\tsess->sock = PJ_INVALID_SOCKET;\n\tte->id = 0;\n\tpj_grp_lock_release(sess->grp_lock);\n\n\tsess_destroy(sess);\n\n    } else if (te->id == TIMER_TEST) {\n\n\tpj_bool_t next_timer;\n\n\tpj_grp_lock_acquire(sess->grp_lock);\n\n\tnext_timer = PJ_FALSE;\n\n\tif (sess->timer_executed == 0) {\n\t    send_test(sess, ST_TEST_1, NULL, 0);\n\t    next_timer = PJ_TRUE;\n\t} else if (sess->timer_executed == 1) {\n\t    send_test(sess, ST_TEST_2, NULL, CHANGE_IP_PORT_FLAG);\n\t    next_timer = PJ_TRUE;\n\t} else if (sess->timer_executed == 2) {\n\t    send_test(sess, ST_TEST_3, NULL, CHANGE_PORT_FLAG);\n\t} else {\n\t    pj_assert(!\"Shouldn't have timer at this state\");\n\t}\n\n\t++sess->timer_executed;\n\n\tif (next_timer) {\n\t    pj_time_val delay = {0, TEST_INTERVAL};\n\t    pj_timer_heap_schedule(th, te, &delay);\n\t} else {\n\t    te->id = 0;\n\t}\n\n\tpj_grp_lock_release(sess->grp_lock);\n\n    } else {\n\tpj_assert(!\"Invalid timer ID\");\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjnath/stun_auth.c",
    "content": "/* $Id: stun_auth.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjnath/stun_auth.h>\n#include <pjnath/errno.h>\n#include <pjlib-util/hmac_sha1.h>\n#include <pjlib-util/md5.h>\n#include <pjlib-util/sha1.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#define THIS_FILE   \"stun_auth.c\"\n\n/* Duplicate credential */\nPJ_DEF(void) pj_stun_auth_cred_dup( pj_pool_t *pool,\n\t\t\t\t      pj_stun_auth_cred *dst,\n\t\t\t\t      const pj_stun_auth_cred *src)\n{\n    dst->type = src->type;\n\n    switch (src->type) {\n    case PJ_STUN_AUTH_CRED_STATIC:\n\tpj_strdup(pool, &dst->data.static_cred.realm,\n\t\t\t&src->data.static_cred.realm);\n\tpj_strdup(pool, &dst->data.static_cred.username,\n\t\t\t&src->data.static_cred.username);\n\tdst->data.static_cred.data_type = src->data.static_cred.data_type;\n\tpj_strdup(pool, &dst->data.static_cred.data,\n\t\t\t&src->data.static_cred.data);\n\tpj_strdup(pool, &dst->data.static_cred.nonce,\n\t\t\t&src->data.static_cred.nonce);\n\tbreak;\n    case PJ_STUN_AUTH_CRED_DYNAMIC:\n\tpj_memcpy(&dst->data.dyn_cred, &src->data.dyn_cred, \n\t\t  sizeof(src->data.dyn_cred));\n\tbreak;\n    }\n}\n\n\n/*\n * Duplicate request credential.\n */\nPJ_DEF(void) pj_stun_req_cred_info_dup( pj_pool_t *pool,\n\t\t\t\t\tpj_stun_req_cred_info *dst,\n\t\t\t\t\tconst pj_stun_req_cred_info *src)\n{\n    pj_strdup(pool, &dst->realm, &src->realm);\n    pj_strdup(pool, &dst->username, &src->username);\n    pj_strdup(pool, &dst->nonce, &src->nonce);\n    pj_strdup(pool, &dst->auth_key, &src->auth_key);\n}\n\n\n/* Calculate HMAC-SHA1 key for long term credential, by getting\n * MD5 digest of username, realm, and password. \n */\nstatic void calc_md5_key(pj_uint8_t digest[16],\n\t\t\t const pj_str_t *realm,\n\t\t\t const pj_str_t *username,\n\t\t\t const pj_str_t *passwd)\n{\n    /* The 16-byte key for MESSAGE-INTEGRITY HMAC is formed by taking\n     * the MD5 hash of the result of concatenating the following five\n     * fields: (1) The username, with any quotes and trailing nulls\n     * removed, (2) A single colon, (3) The realm, with any quotes and\n     * trailing nulls removed, (4) A single colon, and (5) The \n     * password, with any trailing nulls removed.\n     */\n    pj_md5_context ctx;\n    pj_str_t s;\n\n    pj_md5_init(&ctx);\n\n#define REMOVE_QUOTE(s)\tif (s.slen && *s.ptr=='\"') \\\n\t\t\t    s.ptr++, s.slen--; \\\n\t\t\tif (s.slen && s.ptr[s.slen-1]=='\"') \\\n\t\t\t    s.slen--;\n\n    /* Add username */\n    s = *username;\n    REMOVE_QUOTE(s);\n    pj_md5_update(&ctx, (pj_uint8_t*)s.ptr, (unsigned)s.slen);\n\n    /* Add single colon */\n    pj_md5_update(&ctx, (pj_uint8_t*)\":\", 1);\n\n    /* Add realm */\n    s = *realm;\n    REMOVE_QUOTE(s);\n    pj_md5_update(&ctx, (pj_uint8_t*)s.ptr, (unsigned)s.slen);\n\n#undef REMOVE_QUOTE\n\n    /* Another colon */\n    pj_md5_update(&ctx, (pj_uint8_t*)\":\", 1);\n\n    /* Add password */\n    pj_md5_update(&ctx, (pj_uint8_t*)passwd->ptr, (unsigned)passwd->slen);\n\n    /* Done */\n    pj_md5_final(&ctx, digest);\n}\n\n\n/*\n * Create authentication key to be used for encoding the message with\n * MESSAGE-INTEGRITY. \n */\nPJ_DEF(void) pj_stun_create_key(pj_pool_t *pool,\n\t\t\t\tpj_str_t *key,\n\t\t\t\tconst pj_str_t *realm,\n\t\t\t\tconst pj_str_t *username,\n\t\t\t\tpj_stun_passwd_type data_type,\n\t\t\t\tconst pj_str_t *data)\n{\n    PJ_ASSERT_ON_FAIL(pool && key && username && data, return);\n\n    if (realm && realm->slen) {\n\tif (data_type == PJ_STUN_PASSWD_PLAIN) {\n\t    key->ptr = (char*) pj_pool_alloc(pool, 16);\n\t    calc_md5_key((pj_uint8_t*)key->ptr, realm, username, data);\n\t    key->slen = 16;\n\t} else {\n\t    pj_strdup(pool, key, data);\n\t}\n    } else {\n\tpj_assert(data_type == PJ_STUN_PASSWD_PLAIN);\n\tpj_strdup(pool, key, data);\n    }\n}\n\n\n/*unused PJ_INLINE(pj_uint16_t) GET_VAL16(const pj_uint8_t *pdu, unsigned pos)\n{\n    return (pj_uint16_t) ((pdu[pos] << 8) + pdu[pos+1]);\n}*/\n\n\nPJ_INLINE(void) PUT_VAL16(pj_uint8_t *buf, unsigned pos, pj_uint16_t hval)\n{\n    buf[pos+0] = (pj_uint8_t) ((hval & 0xFF00) >> 8);\n    buf[pos+1] = (pj_uint8_t) ((hval & 0x00FF) >> 0);\n}\n\n\n/* Send 401 response */\nstatic pj_status_t create_challenge(pj_pool_t *pool,\n\t\t\t\t    const pj_stun_msg *msg,\n\t\t\t\t    int err_code,\n\t\t\t\t    const char *errstr,\n\t\t\t\t    const pj_str_t *realm,\n\t\t\t\t    const pj_str_t *nonce,\n\t\t\t\t    pj_stun_msg **p_response)\n{\n    pj_stun_msg *response;\n    pj_str_t tmp_nonce;\n    pj_str_t err_msg;\n    pj_status_t rc;\n\n    rc = pj_stun_msg_create_response(pool, msg, err_code, \n\t\t\t             (errstr?pj_cstr(&err_msg, errstr):NULL), \n\t\t\t\t     &response);\n    if (rc != PJ_SUCCESS)\n\treturn rc;\n\n    /* SHOULD NOT add REALM, NONCE, USERNAME, and M-I on 400 response */\n    if (err_code!=400 && realm && realm->slen) {\n\trc = pj_stun_msg_add_string_attr(pool, response,\n\t\t\t\t\t PJ_STUN_ATTR_REALM, \n\t\t\t\t\t realm);\n\tif (rc != PJ_SUCCESS)\n\t    return rc;\n\n\t/* long term must include nonce */\n\tif (!nonce || nonce->slen == 0) {\n\t    tmp_nonce = pj_str(\"pjstun\");\n\t    nonce = &tmp_nonce;\n\t}\n    }\n\n    if (err_code!=400 && nonce && nonce->slen) {\n\trc = pj_stun_msg_add_string_attr(pool, response,\n\t\t\t\t\t PJ_STUN_ATTR_NONCE, \n\t\t\t\t\t nonce);\n\tif (rc != PJ_SUCCESS)\n\t    return rc;\n    }\n\n    *p_response = response;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Verify credential in the request */\nPJ_DEF(pj_status_t) pj_stun_authenticate_request(const pj_uint8_t *pkt,\n\t\t\t\t\t         unsigned pkt_len,\n\t\t\t\t\t         const pj_stun_msg *msg,\n\t\t\t\t\t         pj_stun_auth_cred *cred,\n\t\t\t\t\t         pj_pool_t *pool,\n\t\t\t\t\t\t pj_stun_req_cred_info *p_info,\n\t\t\t\t\t         pj_stun_msg **p_response)\n{\n    pj_stun_req_cred_info tmp_info;\n    const pj_stun_msgint_attr *amsgi;\n    unsigned i, amsgi_pos;\n    pj_bool_t has_attr_beyond_mi;\n    const pj_stun_username_attr *auser;\n    const pj_stun_realm_attr *arealm;\n    const pj_stun_realm_attr *anonce;\n    pj_hmac_sha1_context ctx;\n    pj_uint8_t digest[PJ_SHA1_DIGEST_SIZE];\n    pj_stun_status err_code;\n    const char *err_text = NULL;\n    pj_status_t status;\n\n    /* msg and credential MUST be specified */\n    PJ_ASSERT_RETURN(pkt && pkt_len && msg && cred, PJ_EINVAL);\n\n    /* If p_response is specified, pool MUST be specified. */\n    PJ_ASSERT_RETURN(!p_response || pool, PJ_EINVAL);\n\n    if (p_response)\n\t*p_response = NULL;\n\n    if (!PJ_STUN_IS_REQUEST(msg->hdr.type))\n\tp_response = NULL;\n\n    if (p_info == NULL)\n\tp_info = &tmp_info;\n\n    pj_bzero(p_info, sizeof(pj_stun_req_cred_info));\n\n    /* Get realm and nonce from credential */\n    p_info->realm.slen = p_info->nonce.slen = 0;\n    if (cred->type == PJ_STUN_AUTH_CRED_STATIC) {\n\tp_info->realm = cred->data.static_cred.realm;\n\tp_info->nonce = cred->data.static_cred.nonce;\n    } else if (cred->type == PJ_STUN_AUTH_CRED_DYNAMIC) {\n\tstatus = cred->data.dyn_cred.get_auth(cred->data.dyn_cred.user_data,\n\t\t\t\t\t      pool, &p_info->realm, \n\t\t\t\t\t      &p_info->nonce);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    } else {\n\tpj_assert(!\"Invalid credential type\");\n\treturn PJ_EBUG;\n    }\n\n    /* Look for MESSAGE-INTEGRITY while counting the position */\n    amsgi_pos = 0;\n    has_attr_beyond_mi = PJ_FALSE;\n    amsgi = NULL;\n    for (i=0; i<msg->attr_count; ++i) {\n\tif (msg->attr[i]->type == PJ_STUN_ATTR_MESSAGE_INTEGRITY) {\n\t    amsgi = (const pj_stun_msgint_attr*) msg->attr[i];\n\t} else if (amsgi) {\n\t    has_attr_beyond_mi = PJ_TRUE;\n\t    break;\n\t} else {\n\t    amsgi_pos += ((msg->attr[i]->length+3) & ~0x03) + 4;\n\t}\n    }\n\n    if (amsgi == NULL) {\n\t/* According to rfc3489bis-10 Sec 10.1.2/10.2.2, we should return 400\n\t   for short term, and 401 for long term.\n\t   The rule has been changed from rfc3489bis-06\n\t*/\n\terr_code = p_info->realm.slen ? PJ_STUN_SC_UNAUTHORIZED : \n\t\t    PJ_STUN_SC_BAD_REQUEST;\n\tgoto on_auth_failed;\n    }\n\n    /* Next check that USERNAME is present */\n    auser = (const pj_stun_username_attr*)\n\t    pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_USERNAME, 0);\n    if (auser == NULL) {\n\t/* According to rfc3489bis-10 Sec 10.1.2/10.2.2, we should return 400\n\t   for both short and long term, since M-I is present.\n\t   The rule has been changed from rfc3489bis-06\n\t*/\n\terr_code = PJ_STUN_SC_BAD_REQUEST;\n\terr_text = \"Missing USERNAME\";\n\tgoto on_auth_failed;\n    }\n\n    /* Get REALM, if any */\n    arealm = (const pj_stun_realm_attr*)\n\t     pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_REALM, 0);\n\n    /* Reject with 400 if we have long term credential and the request\n     * is missing REALM attribute.\n     */\n    if (p_info->realm.slen && arealm==NULL) {\n\terr_code = PJ_STUN_SC_BAD_REQUEST;\n\terr_text = \"Missing REALM\";\n\tgoto on_auth_failed;\n    }\n\n    /* Check if username match */\n    if (cred->type == PJ_STUN_AUTH_CRED_STATIC) {\n\tpj_bool_t username_ok;\n\tusername_ok = !pj_strcmp(&auser->value, \n\t\t\t\t &cred->data.static_cred.username);\n\tif (username_ok) {\n\t    pj_strdup(pool, &p_info->username, \n\t\t      &cred->data.static_cred.username);\n\t    pj_stun_create_key(pool, &p_info->auth_key, &p_info->realm,\n\t\t\t       &auser->value, cred->data.static_cred.data_type,\n\t\t\t       &cred->data.static_cred.data);\n\t} else {\n\t    /* Username mismatch */\n\t    /* According to rfc3489bis-10 Sec 10.1.2/10.2.2, we should \n\t     * return 401 \n\t     */\n\t    err_code = PJ_STUN_SC_UNAUTHORIZED;\n\t    goto on_auth_failed;\n\t}\n    } else if (cred->type == PJ_STUN_AUTH_CRED_DYNAMIC) {\n\tpj_stun_passwd_type data_type = PJ_STUN_PASSWD_PLAIN;\n\tpj_str_t password;\n\tpj_status_t rc;\n\n\trc = cred->data.dyn_cred.get_password(msg, \n\t\t\t\t\t      cred->data.dyn_cred.user_data,\n\t\t\t\t\t      (arealm?&arealm->value:NULL),\n\t\t\t\t\t      &auser->value, pool,\n\t\t\t\t\t      &data_type, &password);\n\tif (rc == PJ_SUCCESS) {\n\t    pj_strdup(pool, &p_info->username, &auser->value);\n\t    pj_stun_create_key(pool, &p_info->auth_key, \n\t\t\t       (arealm?&arealm->value:NULL), &auser->value, \n\t\t\t       data_type, &password);\n\t} else {\n\t    err_code = PJ_STUN_SC_UNAUTHORIZED;\n\t    goto on_auth_failed;\n\t}\n    } else {\n\tpj_assert(!\"Invalid credential type\");\n\treturn PJ_EBUG;\n    }\n\n\n\n    /* Get NONCE attribute */\n    anonce = (pj_stun_nonce_attr*)\n\t     pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_NONCE, 0);\n\n    /* Check for long term/short term requirements. */\n    if (p_info->realm.slen != 0 && arealm == NULL) {\n\t/* Long term credential is required and REALM is not present */\n\terr_code = PJ_STUN_SC_BAD_REQUEST;\n\terr_text = \"Missing REALM\";\n\tgoto on_auth_failed;\n\n    } else if (p_info->realm.slen != 0 && arealm != NULL) {\n\t/* We want long term, and REALM is present */\n\n\t/* NONCE must be present. */\n\tif (anonce == NULL && p_info->nonce.slen) {\n\t    err_code = PJ_STUN_SC_BAD_REQUEST;\n\t    err_text = \"Missing NONCE\";\n\t    goto on_auth_failed;\n\t}\n\n\t/* Verify REALM matches */\n\tif (pj_stricmp(&arealm->value, &p_info->realm)) {\n\t    /* REALM doesn't match */\n\t    err_code = PJ_STUN_SC_UNAUTHORIZED;\n\t    err_text = \"Invalid REALM\";\n\t    goto on_auth_failed;\n\t}\n\n\t/* Valid case, will validate the message integrity later */\n\n    } else if (p_info->realm.slen == 0 && arealm != NULL) {\n\t/* We want to use short term credential, but client uses long\n\t * term credential. The draft doesn't mention anything about\n\t * switching between long term and short term.\n\t */\n\t\n\t/* For now just accept the credential, anyway it will probably\n\t * cause wrong message integrity value later.\n\t */\n    } else if (p_info->realm.slen==0 && arealm == NULL) {\n\t/* Short term authentication is wanted, and one is supplied */\n\n\t/* Application MAY request NONCE to be supplied */\n\tif (p_info->nonce.slen != 0) {\n\t    err_code = PJ_STUN_SC_UNAUTHORIZED;\n\t    err_text = \"NONCE required\";\n\t    goto on_auth_failed;\n\t}\n    }\n\n    /* If NONCE is present, validate it */\n    if (anonce) {\n\tpj_bool_t ok;\n\n\tif (cred->type == PJ_STUN_AUTH_CRED_DYNAMIC &&\n\t    cred->data.dyn_cred.verify_nonce != NULL) \n\t{\n\t    ok=cred->data.dyn_cred.verify_nonce(msg, \n\t\t\t\t\t\tcred->data.dyn_cred.user_data,\n\t\t\t\t\t\t(arealm?&arealm->value:NULL),\n\t\t\t\t\t\t&auser->value,\n\t\t\t\t\t\t&anonce->value);\n\t} else if (cred->type == PJ_STUN_AUTH_CRED_DYNAMIC) {\n\t    ok = PJ_TRUE;\n\t} else {\n\t    if (p_info->nonce.slen) {\n\t\tok = !pj_strcmp(&anonce->value, &p_info->nonce);\n\t    } else {\n\t\tok = PJ_TRUE;\n\t    }\n\t}\n\n\tif (!ok) {\n\t    err_code = PJ_STUN_SC_STALE_NONCE;\n\t    goto on_auth_failed;\n\t}\n    }\n\n    /* Now calculate HMAC of the message. */\n    pj_hmac_sha1_init(&ctx, (pj_uint8_t*)p_info->auth_key.ptr, \n\t\t      (unsigned)p_info->auth_key.slen);\n\n#if PJ_STUN_OLD_STYLE_MI_FINGERPRINT\n    /* Pre rfc3489bis-06 style of calculation */\n    pj_hmac_sha1_update(&ctx, pkt, 20);\n#else\n    /* First calculate HMAC for the header.\n     * The calculation is different depending on whether FINGERPRINT attribute\n     * is present in the message.\n     */\n    if (has_attr_beyond_mi) {\n\tpj_uint8_t hdr_copy[20];\n\tpj_memcpy(hdr_copy, pkt, 20);\n\tPUT_VAL16(hdr_copy, 2, (pj_uint16_t)(amsgi_pos + 24));\n\tpj_hmac_sha1_update(&ctx, hdr_copy, 20);\n    } else {\n\tpj_hmac_sha1_update(&ctx, pkt, 20);\n    }\n#endif\t/* PJ_STUN_OLD_STYLE_MI_FINGERPRINT */\n\n    /* Now update with the message body */\n    pj_hmac_sha1_update(&ctx, pkt+20, amsgi_pos);\n#if PJ_STUN_OLD_STYLE_MI_FINGERPRINT\n    // This is no longer necessary as per rfc3489bis-08\n    if ((amsgi_pos+20) & 0x3F) {\n    \tpj_uint8_t zeroes[64];\n    \tpj_bzero(zeroes, sizeof(zeroes));\n    \tpj_hmac_sha1_update(&ctx, zeroes, 64-((amsgi_pos+20) & 0x3F));\n    }\n#endif\n    pj_hmac_sha1_final(&ctx, digest);\n\n\n    /* Compare HMACs */\n    if (pj_memcmp(amsgi->hmac, digest, 20)) {\n\t/* HMAC value mismatch */\n\t/* According to rfc3489bis-10 Sec 10.1.2 we should return 401 */\n\terr_code = PJ_STUN_SC_UNAUTHORIZED;\n\terr_text = \"MESSAGE-INTEGRITY mismatch\";\n\tgoto on_auth_failed;\n    }\n\n    /* Everything looks okay! */\n    return PJ_SUCCESS;\n\non_auth_failed:\n    if (p_response) {\n\tcreate_challenge(pool, msg, err_code, err_text,\n\t\t\t &p_info->realm, &p_info->nonce, p_response);\n    }\n    return PJ_STATUS_FROM_STUN_CODE(err_code);\n}\n\n\n/* Determine if STUN message can be authenticated */\nPJ_DEF(pj_bool_t) pj_stun_auth_valid_for_msg(const pj_stun_msg *msg)\n{\n    unsigned msg_type = msg->hdr.type;\n    const pj_stun_errcode_attr *err_attr;\n\n    /* STUN requests and success response can be authenticated */\n    if (!PJ_STUN_IS_ERROR_RESPONSE(msg_type) && \n\t!PJ_STUN_IS_INDICATION(msg_type))\n    {\n\treturn PJ_TRUE;\n    }\n\n    /* STUN Indication cannot be authenticated */\n    if (PJ_STUN_IS_INDICATION(msg_type))\n\treturn PJ_FALSE;\n\n    /* Authentication for STUN error responses depend on the error\n     * code.\n     */\n    err_attr = (const pj_stun_errcode_attr*)\n\t       pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ERROR_CODE, 0);\n    if (err_attr == NULL) {\n\tPJ_LOG(4,(THIS_FILE, \"STUN error code attribute not present in \"\n\t\t\t     \"error response\"));\n\treturn PJ_TRUE;\n    }\n\n    switch (err_attr->err_code) {\n    case PJ_STUN_SC_BAD_REQUEST:\t    /* 400 (Bad Request)\t    */\n    case PJ_STUN_SC_UNAUTHORIZED:\t    /* 401 (Unauthorized)\t    */\n    case PJ_STUN_SC_STALE_NONCE:\t    /* 438 (Stale Nonce)\t    */\n\n    /* Due to the way this response is generated here, we can't really\n     * authenticate 420 (Unknown Attribute) response\t\t\t    */\n    case PJ_STUN_SC_UNKNOWN_ATTRIBUTE:\n\treturn PJ_FALSE;\n    default:\n\treturn PJ_TRUE;\n    }\n}\n\n\n/* Authenticate MESSAGE-INTEGRITY in the response */\nPJ_DEF(pj_status_t) pj_stun_authenticate_response(const pj_uint8_t *pkt,\n\t\t\t\t\t          unsigned pkt_len,\n\t\t\t\t\t          const pj_stun_msg *msg,\n\t\t\t\t\t          const pj_str_t *key)\n{\n    const pj_stun_msgint_attr *amsgi;\n    unsigned i, amsgi_pos;\n    pj_bool_t has_attr_beyond_mi;\n    pj_hmac_sha1_context ctx;\n    pj_uint8_t digest[PJ_SHA1_DIGEST_SIZE];\n\n    PJ_ASSERT_RETURN(pkt && pkt_len && msg && key, PJ_EINVAL);\n\n    /* First check that MESSAGE-INTEGRITY is present */\n    amsgi = (const pj_stun_msgint_attr*)\n\t    pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_MESSAGE_INTEGRITY, 0);\n    if (amsgi == NULL) {\n\treturn PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNAUTHORIZED);\n    }\n\n\n    /* Check that message length is valid */\n    if (msg->hdr.length < 24) {\n\treturn PJNATH_EINSTUNMSGLEN;\n    }\n\n    /* Look for MESSAGE-INTEGRITY while counting the position */\n    amsgi_pos = 0;\n    has_attr_beyond_mi = PJ_FALSE;\n    amsgi = NULL;\n    for (i=0; i<msg->attr_count; ++i) {\n\tif (msg->attr[i]->type == PJ_STUN_ATTR_MESSAGE_INTEGRITY) {\n\t    amsgi = (const pj_stun_msgint_attr*) msg->attr[i];\n\t} else if (amsgi) {\n\t    has_attr_beyond_mi = PJ_TRUE;\n\t    break;\n\t} else {\n\t    amsgi_pos += ((msg->attr[i]->length+3) & ~0x03) + 4;\n\t}\n    }\n\n    if (amsgi == NULL) {\n\treturn PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST);\n    }\n\n    /* Now calculate HMAC of the message. */\n    pj_hmac_sha1_init(&ctx, (pj_uint8_t*)key->ptr, (unsigned)key->slen);\n\n#if PJ_STUN_OLD_STYLE_MI_FINGERPRINT\n    /* Pre rfc3489bis-06 style of calculation */\n    pj_hmac_sha1_update(&ctx, pkt, 20);\n#else\n    /* First calculate HMAC for the header.\n     * The calculation is different depending on whether FINGERPRINT attribute\n     * is present in the message.\n     */\n    if (has_attr_beyond_mi) {\n\tpj_uint8_t hdr_copy[20];\n\tpj_memcpy(hdr_copy, pkt, 20);\n\tPUT_VAL16(hdr_copy, 2, (pj_uint16_t)(amsgi_pos+24));\n\tpj_hmac_sha1_update(&ctx, hdr_copy, 20);\n    } else {\n\tpj_hmac_sha1_update(&ctx, pkt, 20);\n    }\n#endif\t/* PJ_STUN_OLD_STYLE_MI_FINGERPRINT */\n\n    /* Now update with the message body */\n    pj_hmac_sha1_update(&ctx, pkt+20, amsgi_pos);\n#if PJ_STUN_OLD_STYLE_MI_FINGERPRINT\n    // This is no longer necessary as per rfc3489bis-08\n    if ((amsgi_pos+20) & 0x3F) {\n    \tpj_uint8_t zeroes[64];\n    \tpj_bzero(zeroes, sizeof(zeroes));\n    \tpj_hmac_sha1_update(&ctx, zeroes, 64-((amsgi_pos+20) & 0x3F));\n    }\n#endif\n    pj_hmac_sha1_final(&ctx, digest);\n\n    /* Compare HMACs */\n    if (pj_memcmp(amsgi->hmac, digest, 20)) {\n\t/* HMAC value mismatch */\n\treturn PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNAUTHORIZED);\n    }\n\n    /* Everything looks okay! */\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjnath/stun_msg.c",
    "content": "/* $Id: stun_msg.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjnath/stun_msg.h>\n#include <pjnath/errno.h>\n#include <pjlib-util/crc32.h>\n#include <pjlib-util/hmac_sha1.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n\n#define THIS_FILE\t\t\"stun_msg.c\"\n#define STUN_XOR_FINGERPRINT\t0x5354554eL\n\nstatic int padding_char;\n\nstatic const char *stun_method_names[PJ_STUN_METHOD_MAX] = \n{\n    \"Unknown\",\t\t\t/* 0 */\n    \"Binding\",\t\t\t/* 1 */\n    \"SharedSecret\",\t\t/* 2 */\n    \"Allocate\",\t\t\t/* 3 */\n    \"Refresh\",\t\t\t/* 4 */\n    \"???\",\t\t\t/* 5 */\n    \"Send\",\t\t\t/* 6 */\n    \"Data\",\t\t\t/* 7 */\n    \"CreatePermission\",\t\t/* 8 */\n    \"ChannelBind\",\t\t/* 9 */\n};\n\nstatic struct\n{\n    int err_code;\n    const char *err_msg;\n} stun_err_msg_map[] = \n{\n    { PJ_STUN_SC_TRY_ALTERNATE,\t\t    \"Try Alternate\"}, \n    { PJ_STUN_SC_BAD_REQUEST,\t\t    \"Bad Request\"},\n    { PJ_STUN_SC_UNAUTHORIZED,\t\t    \"Unauthorized\"},\n    { PJ_STUN_SC_FORBIDDEN,\t\t    \"Forbidden\"},\n    { PJ_STUN_SC_UNKNOWN_ATTRIBUTE,\t    \"Unknown Attribute\"},\n    //{ PJ_STUN_SC_STALE_CREDENTIALS,\t    \"Stale Credentials\"},\n    //{ PJ_STUN_SC_INTEGRITY_CHECK_FAILURE, \"Integrity Check Failure\"},\n    //{ PJ_STUN_SC_MISSING_USERNAME,\t    \"Missing Username\"},\n    //{ PJ_STUN_SC_USE_TLS,\t\t    \"Use TLS\"},\n    //{ PJ_STUN_SC_MISSING_REALM,\t    \"Missing Realm\"},\n    //{ PJ_STUN_SC_MISSING_NONCE,\t    \"Missing Nonce\"},\n    //{ PJ_STUN_SC_UNKNOWN_USERNAME,\t    \"Unknown Username\"},\n    { PJ_STUN_SC_ALLOCATION_MISMATCH,\t    \"Allocation Mismatch\"},\n    { PJ_STUN_SC_STALE_NONCE,\t\t    \"Stale Nonce\"},\n    { PJ_STUN_SC_TRANSITIONING,\t\t    \"Active Destination Already Set\"},\n    { PJ_STUN_SC_WRONG_CREDENTIALS,\t    \"Wrong Credentials\"},\n    { PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO,    \"Unsupported Transport Protocol\"},\n    { PJ_STUN_SC_OPER_TCP_ONLY,\t\t    \"Operation for TCP Only\"},\n    { PJ_STUN_SC_CONNECTION_FAILURE,\t    \"Connection Failure\"},\n    { PJ_STUN_SC_CONNECTION_TIMEOUT,\t    \"Connection Timeout\"},\n    { PJ_STUN_SC_ALLOCATION_QUOTA_REACHED,  \"Allocation Quota Reached\"},\n    { PJ_STUN_SC_ROLE_CONFLICT,\t\t    \"Role Conflict\"},\n    { PJ_STUN_SC_SERVER_ERROR,\t\t    \"Server Error\"},\n    { PJ_STUN_SC_INSUFFICIENT_CAPACITY,\t    \"Insufficient Capacity\"},\n    { PJ_STUN_SC_GLOBAL_FAILURE,\t    \"Global Failure\"}\n};\n\n\n\nstruct attr_desc\n{\n    const char   *name;\n    pj_status_t\t(*decode_attr)(pj_pool_t *pool, const pj_uint8_t *buf, \n\t\t\t       const pj_stun_msg_hdr *msghdr, void **p_attr);\n    pj_status_t (*encode_attr)(const void *a, pj_uint8_t *buf, \n\t\t\t       unsigned len, const pj_stun_msg_hdr *msghdr,\n\t\t\t       unsigned *printed);\n    void*       (*clone_attr)(pj_pool_t *pool, const void *src);\n};\n\nstatic pj_status_t decode_sockaddr_attr(pj_pool_t *pool, \n\t\t\t\t        const pj_uint8_t *buf, \n\t\t\t\t        const pj_stun_msg_hdr *msghdr,\n\t\t\t\t        void **p_attr);\nstatic pj_status_t decode_xored_sockaddr_attr(pj_pool_t *pool, \n\t\t\t\t\t      const pj_uint8_t *buf, \n\t\t\t\t\t      const pj_stun_msg_hdr *msghdr, \n\t\t\t\t\t      void **p_attr);\nstatic pj_status_t encode_sockaddr_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t        unsigned len, \n\t\t\t\t\tconst pj_stun_msg_hdr *msghdr,\n\t\t\t\t        unsigned *printed);\nstatic void*       clone_sockaddr_attr(pj_pool_t *pool, const void *src);\nstatic pj_status_t decode_string_attr(pj_pool_t *pool, \n\t\t\t\t      const pj_uint8_t *buf, \n\t\t\t\t      const pj_stun_msg_hdr *msghdr, \n\t\t\t\t      void **p_attr);\nstatic pj_status_t encode_string_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t      unsigned len, \n\t\t\t\t      const pj_stun_msg_hdr *msghdr,\n\t\t\t\t      unsigned *printed);\nstatic void*       clone_string_attr(pj_pool_t *pool, const void *src);\nstatic pj_status_t decode_msgint_attr(pj_pool_t *pool, \n\t\t\t\t      const pj_uint8_t *buf,\n\t\t\t\t      const pj_stun_msg_hdr *msghdr, \n\t\t\t\t      void **p_attr);\nstatic pj_status_t encode_msgint_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t      unsigned len, \n\t\t\t\t      const pj_stun_msg_hdr *msghdr,\n\t\t\t\t      unsigned *printed);\nstatic void*       clone_msgint_attr(pj_pool_t *pool, const void *src);\nstatic pj_status_t decode_errcode_attr(pj_pool_t *pool, \n\t\t\t\t       const pj_uint8_t *buf,\n\t\t\t\t       const pj_stun_msg_hdr *msghdr, \n\t\t\t\t       void **p_attr);\nstatic pj_status_t encode_errcode_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t       unsigned len, \n\t\t\t\t       const pj_stun_msg_hdr *msghdr,\n\t\t\t\t       unsigned *printed);\nstatic void*       clone_errcode_attr(pj_pool_t *pool, const void *src);\nstatic pj_status_t decode_unknown_attr(pj_pool_t *pool, \n\t\t\t\t       const pj_uint8_t *buf, \n\t\t\t\t       const pj_stun_msg_hdr *msghdr, \n\t\t\t\t       void **p_attr);\nstatic pj_status_t encode_unknown_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t       unsigned len, \n\t\t\t\t       const pj_stun_msg_hdr *msghdr,\n\t\t\t\t       unsigned *printed);\nstatic void*       clone_unknown_attr(pj_pool_t *pool, const void *src);\nstatic pj_status_t decode_uint_attr(pj_pool_t *pool, \n\t\t\t\t    const pj_uint8_t *buf, \n\t\t\t\t    const pj_stun_msg_hdr *msghdr, \n\t\t\t\t    void **p_attr);\nstatic pj_status_t encode_uint_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t    unsigned len, \n\t\t\t\t    const pj_stun_msg_hdr *msghdr,\n\t\t\t\t    unsigned *printed);\nstatic void*       clone_uint_attr(pj_pool_t *pool, const void *src);\nstatic pj_status_t decode_uint64_attr(pj_pool_t *pool, \n\t\t\t\t      const pj_uint8_t *buf, \n\t\t\t\t      const pj_stun_msg_hdr *msghdr, \n\t\t\t\t      void **p_attr);\nstatic pj_status_t encode_uint64_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t      unsigned len, \n\t\t\t\t      const pj_stun_msg_hdr *msghdr,\n\t\t\t\t      unsigned *printed);\nstatic void*       clone_uint64_attr(pj_pool_t *pool, const void *src);\nstatic pj_status_t decode_binary_attr(pj_pool_t *pool, \n\t\t\t\t      const pj_uint8_t *buf,\n\t\t\t\t      const pj_stun_msg_hdr *msghdr, \n\t\t\t\t      void **p_attr);\nstatic pj_status_t encode_binary_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t      unsigned len, \n\t\t\t\t      const pj_stun_msg_hdr *msghdr,\n\t\t\t\t      unsigned *printed);\nstatic void*       clone_binary_attr(pj_pool_t *pool, const void *src);\nstatic pj_status_t decode_empty_attr(pj_pool_t *pool, \n\t\t\t\t     const pj_uint8_t *buf, \n\t\t\t\t     const pj_stun_msg_hdr *msghdr, \n\t\t\t\t     void **p_attr);\nstatic pj_status_t encode_empty_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t     unsigned len, \n\t\t\t\t     const pj_stun_msg_hdr *msghdr,\n\t\t\t\t     unsigned *printed);\nstatic void*       clone_empty_attr(pj_pool_t *pool, const void *src);\n\nstatic struct attr_desc mandatory_attr_desc[] = \n{\n    {\n\t/* type zero */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* PJ_STUN_ATTR_MAPPED_ADDR, */\n\t\"MAPPED-ADDRESS\",\n\t&decode_sockaddr_attr,\n\t&encode_sockaddr_attr,\n\t&clone_sockaddr_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_RESPONSE_ADDR, */\n\t\"RESPONSE-ADDRESS\",\n\t&decode_sockaddr_attr,\n\t&encode_sockaddr_attr,\n\t&clone_sockaddr_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_CHANGE_REQUEST, */\n\t\"CHANGE-REQUEST\",\n\t&decode_uint_attr,\n\t&encode_uint_attr,\n\t&clone_uint_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_SOURCE_ADDR, */\n\t\"SOURCE-ADDRESS\",\n\t&decode_sockaddr_attr,\n\t&encode_sockaddr_attr,\n\t&clone_sockaddr_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_CHANGED_ADDR, */\n\t\"CHANGED-ADDRESS\",\n\t&decode_sockaddr_attr,\n\t&encode_sockaddr_attr,\n\t&clone_sockaddr_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_USERNAME, */\n\t\"USERNAME\",\n\t&decode_string_attr,\n\t&encode_string_attr,\n\t&clone_string_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_PASSWORD, */\n\t\"PASSWORD\",\n\t&decode_string_attr,\n\t&encode_string_attr,\n\t&clone_string_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_MESSAGE_INTEGRITY, */\n\t\"MESSAGE-INTEGRITY\",\n\t&decode_msgint_attr,\n\t&encode_msgint_attr,\n\t&clone_msgint_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_ERROR_CODE, */\n\t\"ERROR-CODE\",\n\t&decode_errcode_attr,\n\t&encode_errcode_attr,\n\t&clone_errcode_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_UNKNOWN_ATTRIBUTES, */\n\t\"UNKNOWN-ATTRIBUTES\",\n\t&decode_unknown_attr,\n\t&encode_unknown_attr,\n\t&clone_unknown_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_REFLECTED_FROM, */\n\t\"REFLECTED-FROM\",\n\t&decode_sockaddr_attr,\n\t&encode_sockaddr_attr,\n\t&clone_sockaddr_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_CHANNEL_NUMBER (0x000C) */\n\t\"CHANNEL-NUMBER\",\n\t&decode_uint_attr,\n\t&encode_uint_attr,\n\t&clone_uint_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_LIFETIME, */\n\t\"LIFETIME\",\n\t&decode_uint_attr,\n\t&encode_uint_attr,\n\t&clone_uint_attr\n    },\n    {\n\t/* ID 0x000E is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* PJ_STUN_ATTR_MAGIC_COOKIE */\n\t\"MAGIC-COOKIE\",\n\t&decode_uint_attr,\n\t&encode_uint_attr,\n\t&clone_uint_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_BANDWIDTH, */\n\t\"BANDWIDTH\",\n\t&decode_uint_attr,\n\t&encode_uint_attr,\n\t&clone_uint_attr\n    },\n    {\n\t/* ID 0x0011 is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* PJ_STUN_ATTR_XOR_PEER_ADDRESS, */\n\t\"XOR-PEER-ADDRESS\",\n\t&decode_xored_sockaddr_attr,\n\t&encode_sockaddr_attr,\n\t&clone_sockaddr_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_DATA, */\n\t\"DATA\",\n\t&decode_binary_attr,\n\t&encode_binary_attr,\n\t&clone_binary_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_REALM, */\n\t\"REALM\",\n\t&decode_string_attr,\n\t&encode_string_attr,\n\t&clone_string_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_NONCE, */\n\t\"NONCE\",\n\t&decode_string_attr,\n\t&encode_string_attr,\n\t&clone_string_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_XOR_RELAYED_ADDR, */\n\t\"XOR-RELAYED-ADDRESS\",\n\t&decode_xored_sockaddr_attr,\n\t&encode_sockaddr_attr,\n\t&clone_sockaddr_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_REQUESTED_ADDR_TYPE, */\n\t\"REQUESTED-ADDRESS-TYPE\",\n\t&decode_uint_attr,\n\t&encode_uint_attr,\n\t&clone_uint_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_EVEN_PORT, */\n\t\"EVEN-PORT\",\n\t&decode_uint_attr,\n\t&encode_uint_attr,\n\t&clone_uint_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_REQUESTED_TRANSPORT, */\n\t\"REQUESTED-TRANSPORT\",\n\t&decode_uint_attr,\n\t&encode_uint_attr,\n\t&clone_uint_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_DONT_FRAGMENT */\n\t\"DONT-FRAGMENT\",\n\t&decode_empty_attr,\n\t&encode_empty_attr,\n\t&clone_empty_attr\n    },\n    {\n\t/* ID 0x001B is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* ID 0x001C is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* ID 0x001D is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* ID 0x001E is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* ID 0x001F is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* PJ_STUN_ATTR_XOR_MAPPED_ADDRESS, */\n\t\"XOR-MAPPED-ADDRESS\",\n\t&decode_xored_sockaddr_attr,\n\t&encode_sockaddr_attr,\n\t&clone_sockaddr_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_TIMER_VAL, */\n\t\"TIMER-VAL\",\n\t&decode_uint_attr,\n\t&encode_uint_attr,\n\t&clone_uint_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_RESERVATION_TOKEN, */\n\t\"RESERVATION-TOKEN\",\n\t&decode_uint64_attr,\n\t&encode_uint64_attr,\n\t&clone_uint64_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_XOR_REFLECTED_FROM, */\n\t\"XOR-REFLECTED-FROM\",\n\t&decode_xored_sockaddr_attr,\n\t&encode_sockaddr_attr,\n\t&clone_sockaddr_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_PRIORITY, */\n\t\"PRIORITY\",\n\t&decode_uint_attr,\n\t&encode_uint_attr,\n\t&clone_uint_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_USE_CANDIDATE, */\n\t\"USE-CANDIDATE\",\n\t&decode_empty_attr,\n\t&encode_empty_attr,\n\t&clone_empty_attr\n    },\n    {\n\t/* ID 0x0026 is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* ID 0x0027 is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* ID 0x0028 is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* ID 0x0029 is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* ID 0x002a is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* ID 0x002b is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* ID 0x002c is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* ID 0x002d is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* ID 0x002e is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* ID 0x002f is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* PJ_STUN_ATTR_ICMP, */\n\t\"ICMP\",\n\t&decode_uint_attr,\n\t&encode_uint_attr,\n\t&clone_uint_attr\n    },\n\n    /* Sentinel */\n    {\n\t/* PJ_STUN_ATTR_END_MANDATORY_ATTR */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    }\n};\n\nstatic struct attr_desc extended_attr_desc[] =\n{\n    {\n\t/* ID 0x8021 is not assigned */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* PJ_STUN_ATTR_SOFTWARE, */\n\t\"SOFTWARE\",\n\t&decode_string_attr,\n\t&encode_string_attr,\n\t&clone_string_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_ALTERNATE_SERVER, */\n\t\"ALTERNATE-SERVER\",\n\t&decode_sockaddr_attr,\n\t&encode_sockaddr_attr,\n\t&clone_sockaddr_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_REFRESH_INTERVAL, */\n\t\"REFRESH-INTERVAL\",\n\t&decode_uint_attr,\n\t&encode_uint_attr,\n\t&clone_uint_attr\n    },\n    {\n\t/* ID 0x8025 is not assigned*/\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* PADDING, 0x8026 */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* CACHE-TIMEOUT, 0x8027 */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL\n    },\n    {\n\t/* PJ_STUN_ATTR_FINGERPRINT, */\n\t\"FINGERPRINT\",\n\t&decode_uint_attr,\n\t&encode_uint_attr,\n\t&clone_uint_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_ICE_CONTROLLED, */\n\t\"ICE-CONTROLLED\",\n\t&decode_uint64_attr,\n\t&encode_uint64_attr,\n\t&clone_uint64_attr\n    },\n    {\n\t/* PJ_STUN_ATTR_ICE_CONTROLLING, */\n\t\"ICE-CONTROLLING\",\n\t&decode_uint64_attr,\n\t&encode_uint64_attr,\n\t&clone_uint64_attr\n    }\n};\n\n\n\n/*\n * Get STUN message type name.\n */\nPJ_DEF(const char*) pj_stun_get_method_name(unsigned msg_type)\n{\n    unsigned method = PJ_STUN_GET_METHOD(msg_type);\n\n    if (method >= PJ_ARRAY_SIZE(stun_method_names))\n\treturn \"???\";\n\n    return stun_method_names[method];\n}\n\n\n/*\n * Get STUN message class name.\n */\nPJ_DEF(const char*) pj_stun_get_class_name(unsigned msg_type)\n{\n    if (PJ_STUN_IS_REQUEST(msg_type))\n\treturn \"request\";\n    else if (PJ_STUN_IS_SUCCESS_RESPONSE(msg_type))\n\treturn \"success response\";\n    else if (PJ_STUN_IS_ERROR_RESPONSE(msg_type))\n\treturn \"error response\";\n    else if (PJ_STUN_IS_INDICATION(msg_type))\n\treturn \"indication\";\n    else\n\treturn \"???\";\n}\n\n\nstatic const struct attr_desc *find_attr_desc(unsigned attr_type)\n{\n    struct attr_desc *desc;\n\n    /* Check that attr_desc array is valid */\n    pj_assert(PJ_ARRAY_SIZE(mandatory_attr_desc)==\n\t      PJ_STUN_ATTR_END_MANDATORY_ATTR+1);\n    pj_assert(mandatory_attr_desc[PJ_STUN_ATTR_END_MANDATORY_ATTR].decode_attr\n\t      == NULL);\n    pj_assert(mandatory_attr_desc[PJ_STUN_ATTR_USE_CANDIDATE].decode_attr \n\t      == &decode_empty_attr);\n    pj_assert(PJ_ARRAY_SIZE(extended_attr_desc) ==\n\t      PJ_STUN_ATTR_END_EXTENDED_ATTR-PJ_STUN_ATTR_START_EXTENDED_ATTR);\n\n    if (attr_type < PJ_STUN_ATTR_END_MANDATORY_ATTR)\n\tdesc = &mandatory_attr_desc[attr_type];\n    else if (attr_type >= PJ_STUN_ATTR_START_EXTENDED_ATTR &&\n\t     attr_type < PJ_STUN_ATTR_END_EXTENDED_ATTR)\n\tdesc = &extended_attr_desc[attr_type-PJ_STUN_ATTR_START_EXTENDED_ATTR];\n    else\n\treturn NULL;\n\n    return desc->decode_attr == NULL ? NULL : desc;\n}\n\n\n/*\n * Get STUN attribute name.\n */\nPJ_DEF(const char*) pj_stun_get_attr_name(unsigned attr_type)\n{\n    const struct attr_desc *attr_desc;\n\n    attr_desc = find_attr_desc(attr_type);\n    if (!attr_desc || attr_desc->name==NULL)\n\treturn \"???\";\n\n    return attr_desc->name;\n}\n\n\n/**\n * Get STUN standard reason phrase for the specified error code.\n */\nPJ_DEF(pj_str_t) pj_stun_get_err_reason(int err_code)\n{\n#if 0\n    /* Find error using linear search */\n    unsigned i;\n\n    for (i=0; i<PJ_ARRAY_SIZE(stun_err_msg_map); ++i) {\n\tif (stun_err_msg_map[i].err_code == err_code)\n\t    return pj_str((char*)stun_err_msg_map[i].err_msg);\n    }\n    return pj_str(NULL);\n#else\n    /* Find error message using binary search */\n    int first = 0;\n    int n = PJ_ARRAY_SIZE(stun_err_msg_map);\n\n    while (n > 0) {\n\tint half = n/2;\n\tint mid = first + half;\n\n\tif (stun_err_msg_map[mid].err_code < err_code) {\n\t    first = mid+1;\n\t    n -= (half+1);\n\t} else if (stun_err_msg_map[mid].err_code > err_code) {\n\t    n = half;\n\t} else {\n\t    first = mid;\n\t    break;\n\t}\n    }\n\n\n    if (stun_err_msg_map[first].err_code == err_code) {\n\treturn pj_str((char*)stun_err_msg_map[first].err_msg);\n    } else {\n\treturn pj_str(NULL);\n    }\n#endif\n}\n\n\n/*\n * Set padding character.\n */\nPJ_DEF(int) pj_stun_set_padding_char(int chr)\n{\n    int old_pad = padding_char;\n    padding_char = chr;\n    return old_pad;\n}\n\n\n//////////////////////////////////////////////////////////////////////////////\n\n\n#define INIT_ATTR(a,t,l)    (a)->hdr.type=(pj_uint16_t)(t), \\\n\t\t\t    (a)->hdr.length=(pj_uint16_t)(l)\n#define ATTR_HDR_LEN\t    4\n\nstatic pj_uint16_t GETVAL16H(const pj_uint8_t *buf, unsigned pos)\n{\n    return (pj_uint16_t) ((buf[pos + 0] << 8) | \\\n\t\t\t  (buf[pos + 1] << 0));\n}\n\n/*unused PJ_INLINE(pj_uint16_t) GETVAL16N(const pj_uint8_t *buf, unsigned pos)\n{\n    return pj_htons(GETVAL16H(buf,pos));\n}*/\n\nstatic void PUTVAL16H(pj_uint8_t *buf, unsigned pos, pj_uint16_t hval)\n{\n    buf[pos+0] = (pj_uint8_t) ((hval & 0xFF00) >> 8);\n    buf[pos+1] = (pj_uint8_t) ((hval & 0x00FF) >> 0);\n}\n\nPJ_INLINE(pj_uint32_t) GETVAL32H(const pj_uint8_t *buf, unsigned pos)\n{\n    return (pj_uint32_t) ((buf[pos + 0] << 24UL) | \\\n\t                  (buf[pos + 1] << 16UL) | \\\n\t                  (buf[pos + 2] <<  8UL) | \\\n\t\t\t  (buf[pos + 3] <<  0UL));\n}\n\n/*unused PJ_INLINE(pj_uint32_t) GETVAL32N(const pj_uint8_t *buf, unsigned pos)\n{\n    return pj_htonl(GETVAL32H(buf,pos));\n}*/\n\nstatic void PUTVAL32H(pj_uint8_t *buf, unsigned pos, pj_uint32_t hval)\n{\n    buf[pos+0] = (pj_uint8_t) ((hval & 0xFF000000UL) >> 24);\n    buf[pos+1] = (pj_uint8_t) ((hval & 0x00FF0000UL) >> 16);\n    buf[pos+2] = (pj_uint8_t) ((hval & 0x0000FF00UL) >>  8);\n    buf[pos+3] = (pj_uint8_t) ((hval & 0x000000FFUL) >>  0);\n}\n\nstatic void GETVAL64H(const pj_uint8_t *buf, unsigned pos, pj_timestamp *ts)\n{\n    ts->u32.hi = GETVAL32H(buf, pos);\n    ts->u32.lo = GETVAL32H(buf, pos+4);\n}\n\nstatic void PUTVAL64H(pj_uint8_t *buf, unsigned pos, const pj_timestamp *ts)\n{\n    PUTVAL32H(buf, pos, ts->u32.hi);\n    PUTVAL32H(buf, pos+4, ts->u32.lo);\n}\n\n\nstatic void GETATTRHDR(const pj_uint8_t *buf, pj_stun_attr_hdr *hdr)\n{\n    hdr->type = GETVAL16H(buf, 0);\n    hdr->length = GETVAL16H(buf, 2);\n}\n\n//////////////////////////////////////////////////////////////////////////////\n/*\n * STUN generic IP address container\n */\n#define STUN_GENERIC_IPV4_ADDR_LEN\t8\n#define STUN_GENERIC_IPV6_ADDR_LEN\t20\n\n/*\n * Init sockaddr attr\n */\nPJ_DEF(pj_status_t) pj_stun_sockaddr_attr_init( pj_stun_sockaddr_attr *attr,\n\t\t\t\t\t\tint attr_type, \n\t\t\t\t\t\tpj_bool_t xor_ed,\n\t\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\t\tunsigned addr_len)\n{\n    unsigned attr_len;\n\n    PJ_ASSERT_RETURN(attr && addr_len && addr, PJ_EINVAL);\n    PJ_ASSERT_RETURN(addr_len == sizeof(pj_sockaddr_in) ||\n\t\t     addr_len == sizeof(pj_sockaddr_in6), PJ_EINVAL);\n\n    attr_len = pj_sockaddr_get_addr_len(addr) + 4;\n    INIT_ATTR(attr, attr_type, attr_len);\n\n    pj_memcpy(&attr->sockaddr, addr, addr_len);\n    attr->xor_ed = xor_ed;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create a generic STUN IP address attribute for IPv4 address.\n */\nPJ_DEF(pj_status_t) pj_stun_sockaddr_attr_create(pj_pool_t *pool,\n\t\t\t\t\t\t int attr_type,\n\t\t\t\t\t\t pj_bool_t xor_ed,\n\t\t\t\t\t\t const pj_sockaddr_t *addr,\n\t\t\t\t\t\t unsigned addr_len,\n\t\t\t\t\t\t pj_stun_sockaddr_attr **p_attr)\n{\n    pj_stun_sockaddr_attr *attr;\n\n    PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL);\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_sockaddr_attr);\n    *p_attr = attr;\n    return pj_stun_sockaddr_attr_init(attr, attr_type, xor_ed, \n\t\t\t\t      addr, addr_len);\n}\n\n\n/*\n * Create and add generic STUN IP address attribute to a STUN message.\n */\nPJ_DEF(pj_status_t) pj_stun_msg_add_sockaddr_attr(pj_pool_t *pool,\n\t\t\t\t\t\t  pj_stun_msg *msg,\n\t\t\t\t\t\t  int attr_type, \n\t\t\t\t\t\t  pj_bool_t xor_ed,\n\t\t\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t\t\t  unsigned addr_len)\n{\n    pj_stun_sockaddr_attr *attr;\n    pj_status_t status;\n\n    status = pj_stun_sockaddr_attr_create(pool, attr_type, xor_ed,\n\t\t\t\t\t         addr, addr_len, &attr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return pj_stun_msg_add_attr(msg, &attr->hdr);\n}\n\nstatic pj_status_t decode_sockaddr_attr(pj_pool_t *pool, \n\t\t\t\t        const pj_uint8_t *buf, \n\t\t\t\t\tconst pj_stun_msg_hdr *msghdr, \n\t\t\t\t        void **p_attr)\n{\n    pj_stun_sockaddr_attr *attr;\n    int af;\n    unsigned addr_len;\n    pj_uint32_t val;\n\n    PJ_CHECK_STACK();\n    \n    PJ_UNUSED_ARG(msghdr);\n\n    /* Create the attribute */\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_sockaddr_attr);\n    GETATTRHDR(buf, &attr->hdr);\n\n    /* Check that the attribute length is valid */\n    if (attr->hdr.length != STUN_GENERIC_IPV4_ADDR_LEN &&\n\tattr->hdr.length != STUN_GENERIC_IPV6_ADDR_LEN)\n    {\n\treturn PJNATH_ESTUNINATTRLEN;\n    }\n\n    /* Check address family */\n    val = *(pj_uint8_t*)(buf + ATTR_HDR_LEN + 1);\n\n    /* Check address family is valid */\n    if (val == 1) {\n\tif (attr->hdr.length != STUN_GENERIC_IPV4_ADDR_LEN)\n\t    return PJNATH_ESTUNINATTRLEN;\n\taf = pj_AF_INET();\n\taddr_len = 4;\n    } else if (val == 2) {\n\tif (attr->hdr.length != STUN_GENERIC_IPV6_ADDR_LEN)\n\t    return PJNATH_ESTUNINATTRLEN;\n\taf = pj_AF_INET6();\n\taddr_len = 16;\n    } else {\n\t/* Invalid address family */\n\treturn PJNATH_EINVAF;\n    }\n\n    /* Get port and address */\n    pj_sockaddr_init(af, &attr->sockaddr, NULL, 0);\n    pj_sockaddr_set_port(&attr->sockaddr, \n\t\t\t GETVAL16H(buf, ATTR_HDR_LEN+2));\n    pj_memcpy(pj_sockaddr_get_addr(&attr->sockaddr),\n\t      buf+ATTR_HDR_LEN+4,\n\t      addr_len);\n\n    /* Done */\n    *p_attr = (void*)attr;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t decode_xored_sockaddr_attr(pj_pool_t *pool, \n\t\t\t\t\t      const pj_uint8_t *buf, \n\t\t\t\t\t      const pj_stun_msg_hdr *msghdr, \n\t\t\t\t\t      void **p_attr)\n{\n    pj_stun_sockaddr_attr *attr;\n    pj_status_t status;\n\n    status = decode_sockaddr_attr(pool, buf, msghdr, p_attr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    attr = *(pj_stun_sockaddr_attr**)p_attr;\n\n    attr->xor_ed = PJ_TRUE;\n\n    if (attr->sockaddr.addr.sa_family == pj_AF_INET()) {\n\tattr->sockaddr.ipv4.sin_port ^= pj_htons(PJ_STUN_MAGIC >> 16);\n\tattr->sockaddr.ipv4.sin_addr.s_addr ^= pj_htonl(PJ_STUN_MAGIC);\n    } else if (attr->sockaddr.addr.sa_family == pj_AF_INET6()) {\n\tunsigned i;\n\tpj_uint8_t *dst = (pj_uint8_t*) &attr->sockaddr.ipv6.sin6_addr;\n\tpj_uint32_t magic = pj_htonl(PJ_STUN_MAGIC);\n\n\tattr->sockaddr.ipv6.sin6_port ^= pj_htons(PJ_STUN_MAGIC >> 16);\n\n\t/* If the IP address family is IPv6, X-Address is computed by\n\t * taking the mapped IP address in host byte order, XOR'ing it\n\t * with the concatenation of the magic cookie and the 96-bit \n\t * transaction ID, and converting the result to network byte \n\t * order.\n\t */\n\tfor (i=0; i<4; ++i) {\n\t    dst[i] ^= ((const pj_uint8_t*)&magic)[i];\n\t}\n\tpj_assert(sizeof(msghdr->tsx_id[0]) == 1);\n\tfor (i=0; i<12; ++i) {\n\t    dst[i+4] ^= msghdr->tsx_id[i];\n\t}\n\n    } else {\n\treturn PJNATH_EINVAF;\n    }\n\n    /* Done */\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t encode_sockaddr_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t        unsigned len, \n\t\t\t\t\tconst pj_stun_msg_hdr *msghdr,\n\t\t\t\t\tunsigned *printed)\n{\n    pj_uint8_t *start_buf = buf;\n    const pj_stun_sockaddr_attr *ca = \n\t(const pj_stun_sockaddr_attr *)a;\n\n    PJ_CHECK_STACK();\n    \n    /* Common: attribute type */\n    PUTVAL16H(buf, 0, ca->hdr.type);\n\n    if (ca->sockaddr.addr.sa_family == pj_AF_INET()) {\n\tenum {\n\t    ATTR_LEN = ATTR_HDR_LEN + STUN_GENERIC_IPV4_ADDR_LEN\n\t};\n\n\tif (len < ATTR_LEN) \n\t    return PJ_ETOOSMALL;\n\n\t/* attribute len */\n\tPUTVAL16H(buf, 2, STUN_GENERIC_IPV4_ADDR_LEN);\n\tbuf += ATTR_HDR_LEN;\n    \n\t/* Ignored */\n\t*buf++ = '\\0';\n\n\t/* Address family, 1 for IPv4 */\n\t*buf++ = 1;\n\n\t/* IPv4 address */\n\tif (ca->xor_ed) {\n\t    pj_uint32_t addr;\n\t    pj_uint16_t port;\n\n\t    addr = ca->sockaddr.ipv4.sin_addr.s_addr;\n\t    port = ca->sockaddr.ipv4.sin_port;\n\n\t    port ^= pj_htons(PJ_STUN_MAGIC >> 16);\n\t    addr ^= pj_htonl(PJ_STUN_MAGIC);\n\n\t    /* Port */\n\t    pj_memcpy(buf, &port, 2);\n\t    buf += 2;\n\n\t    /* Address */\n\t    pj_memcpy(buf, &addr, 4);\n\t    buf += 4;\n\n\t} else {\n\t    /* Port */\n\t    pj_memcpy(buf, &ca->sockaddr.ipv4.sin_port, 2);\n\t    buf += 2;\n\n\t    /* Address */\n\t    pj_memcpy(buf, &ca->sockaddr.ipv4.sin_addr, 4);\n\t    buf += 4;\n\t}\n\n\tpj_assert(buf - start_buf == ATTR_LEN);\n\n    } else if (ca->sockaddr.addr.sa_family == pj_AF_INET6()) {\n\t/* IPv6 address */\n\tenum {\n\t    ATTR_LEN = ATTR_HDR_LEN + STUN_GENERIC_IPV6_ADDR_LEN\n\t};\n\n\tif (len < ATTR_LEN) \n\t    return PJ_ETOOSMALL;\n\n\t/* attribute len */\n\tPUTVAL16H(buf, 2, STUN_GENERIC_IPV6_ADDR_LEN);\n\tbuf += ATTR_HDR_LEN;\n    \n\t/* Ignored */\n\t*buf++ = '\\0';\n\n\t/* Address family, 2 for IPv6 */\n\t*buf++ = 2;\n\n\t/* IPv6 address */\n\tif (ca->xor_ed) {\n\t    unsigned i;\n\t    pj_uint8_t *dst;\n\t    const pj_uint8_t *src;\n\t    pj_uint32_t magic = pj_htonl(PJ_STUN_MAGIC);\n\t    pj_uint16_t port = ca->sockaddr.ipv6.sin6_port;\n\n\t    /* Port */\n\t    port ^= pj_htons(PJ_STUN_MAGIC >> 16);\n\t    pj_memcpy(buf, &port, 2);\n\t    buf += 2;\n\n\t    /* Address */\n\t    dst = buf;\n\t    src = (const pj_uint8_t*) &ca->sockaddr.ipv6.sin6_addr;\n\t    for (i=0; i<4; ++i) {\n\t\tdst[i] = (pj_uint8_t)(src[i] ^ ((const pj_uint8_t*)&magic)[i]);\n\t    }\n\t    pj_assert(sizeof(msghdr->tsx_id[0]) == 1);\n\t    for (i=0; i<12; ++i) {\n\t\tdst[i+4] = (pj_uint8_t)(src[i+4] ^ msghdr->tsx_id[i]);\n\t    }\n\n\t    buf += 16;\n\n\t} else {\n\t    /* Port */\n\t    pj_memcpy(buf, &ca->sockaddr.ipv6.sin6_port, 2);\n\t    buf += 2;\n\n\t    /* Address */\n\t    pj_memcpy(buf, &ca->sockaddr.ipv6.sin6_addr, 16);\n\t    buf += 16;\n\t}\n\n\tpj_assert(buf - start_buf == ATTR_LEN);\n\n    } else {\n\treturn PJNATH_EINVAF;\n    }\n\n    /* Done */\n    *printed = (unsigned)(buf - start_buf);\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void* clone_sockaddr_attr(pj_pool_t *pool, const void *src)\n{\n    pj_stun_sockaddr_attr *dst = PJ_POOL_ALLOC_T(pool, pj_stun_sockaddr_attr);\n    pj_memcpy(dst, src, sizeof(pj_stun_sockaddr_attr));\n    return (void*)dst;\n}\n\n//////////////////////////////////////////////////////////////////////////////\n/*\n * STUN generic string attribute\n */\n\n/*\n * Initialize a STUN generic string attribute.\n */\nPJ_DEF(pj_status_t) pj_stun_string_attr_init( pj_stun_string_attr *attr,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      int attr_type,\n\t\t\t\t\t      const pj_str_t *value)\n{\n    if (value && value->slen) {\n\tINIT_ATTR(attr, attr_type, value->slen);\n\tattr->value.slen = value->slen;\n\tpj_strdup(pool, &attr->value, value);\n    } else {\n\tINIT_ATTR(attr, attr_type, 0);\n    }\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create a STUN generic string attribute.\n */\nPJ_DEF(pj_status_t) pj_stun_string_attr_create(pj_pool_t *pool,\n\t\t\t\t\t       int attr_type,\n\t\t\t\t\t       const pj_str_t *value,\n\t\t\t\t\t       pj_stun_string_attr **p_attr)\n{\n    pj_stun_string_attr *attr;\n\n    PJ_ASSERT_RETURN(pool && value && p_attr, PJ_EINVAL);\n\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_string_attr);\n    *p_attr = attr;\n\n    return pj_stun_string_attr_init(attr, pool, attr_type, value);\n}\n\n\n/*\n * Create and add STUN generic string attribute to the message.\n */\nPJ_DEF(pj_status_t) pj_stun_msg_add_string_attr(pj_pool_t *pool,\n\t\t\t\t\t\tpj_stun_msg *msg,\n\t\t\t\t\t\tint attr_type,\n\t\t\t\t\t\tconst pj_str_t *value)\n{\n    pj_stun_string_attr *attr = NULL;\n    pj_status_t status;\n\n    status = pj_stun_string_attr_create(pool, attr_type, value, \n\t\t\t\t\t\t&attr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return pj_stun_msg_add_attr(msg, &attr->hdr);\n}\n\n\nstatic pj_status_t decode_string_attr(pj_pool_t *pool, \n\t\t\t\t      const pj_uint8_t *buf, \n\t\t\t\t      const pj_stun_msg_hdr *msghdr, \n\t\t\t\t      void **p_attr)\n{\n    pj_stun_string_attr *attr;\n    pj_str_t value;\n\n    PJ_UNUSED_ARG(msghdr);\n\n    /* Create the attribute */\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_string_attr);\n    GETATTRHDR(buf, &attr->hdr);\n\n    /* Get pointer to the string in the message */\n    value.ptr = ((char*)buf + ATTR_HDR_LEN);\n    value.slen = attr->hdr.length;\n\n    /* Copy the string to the attribute */\n    pj_strdup(pool, &attr->value, &value);\n\n    /* Done */\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n\n}\n\n\nstatic pj_status_t encode_string_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t      unsigned len, \n\t\t\t\t      const pj_stun_msg_hdr *msghdr,\n\t\t\t\t      unsigned *printed)\n{\n    const pj_stun_string_attr *ca = \n\t(const pj_stun_string_attr*)a;\n\n    PJ_CHECK_STACK();\n    \n    PJ_UNUSED_ARG(msghdr);\n\n    /* Calculated total attr_len (add padding if necessary) */\n    *printed = ((unsigned)ca->value.slen + ATTR_HDR_LEN + 3) & (~3);\n    if (len < *printed) {\n\t*printed = 0;\n\treturn PJ_ETOOSMALL;\n    }\n\n    PUTVAL16H(buf, 0, ca->hdr.type);\n\n    /* Special treatment for SOFTWARE attribute:\n     * This attribute had caused interop problem when talking to \n     * legacy RFC 3489 STUN servers, due to different \"length\"\n     * rules with RFC 5389.\n     */\n    if (msghdr->magic != PJ_STUN_MAGIC ||\n\tca->hdr.type == PJ_STUN_ATTR_SOFTWARE)\n    {\n\t/* Set the length to be 4-bytes aligned so that we can\n\t * communicate with RFC 3489 endpoints\n\t */\n\tPUTVAL16H(buf, 2, (pj_uint16_t)((ca->value.slen + 3) & (~3)));\n    } else {\n\t/* Use RFC 5389 rule */\n\tPUTVAL16H(buf, 2, (pj_uint16_t)ca->value.slen);\n    }\n\n    /* Copy the string */\n    pj_memcpy(buf+ATTR_HDR_LEN, ca->value.ptr, ca->value.slen);\n\n    /* Add padding character, if string is not 4-bytes aligned. */\n    if (ca->value.slen & 0x03) {\n\tpj_uint8_t pad[3];\n\tpj_memset(pad, padding_char, sizeof(pad));\n\tpj_memcpy(buf+ATTR_HDR_LEN+ca->value.slen, pad,\n\t\t  4-(ca->value.slen & 0x03));\n    }\n\n    /* Done */\n    return PJ_SUCCESS;\n}\n\n\nstatic void* clone_string_attr(pj_pool_t *pool, const void *src)\n{\n    const pj_stun_string_attr *asrc = (const pj_stun_string_attr*)src;\n    pj_stun_string_attr *dst = PJ_POOL_ALLOC_T(pool, pj_stun_string_attr);\n\n    pj_memcpy(dst, src, sizeof(pj_stun_attr_hdr));\n    pj_strdup(pool, &dst->value, &asrc->value);\n\n    return (void*)dst;\n}\n\n//////////////////////////////////////////////////////////////////////////////\n/*\n * STUN empty attribute (used by USE-CANDIDATE).\n */\n\n/*\n * Create a STUN empty attribute.\n */\nPJ_DEF(pj_status_t) pj_stun_empty_attr_create(pj_pool_t *pool,\n\t\t\t\t\t      int attr_type,\n\t\t\t\t\t      pj_stun_empty_attr **p_attr)\n{\n    pj_stun_empty_attr *attr;\n\n    PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL);\n\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_empty_attr);\n    INIT_ATTR(attr, attr_type, 0);\n\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create STUN empty attribute and add the attribute to the message.\n */\nPJ_DEF(pj_status_t) pj_stun_msg_add_empty_attr( pj_pool_t *pool,\n\t\t\t\t\t\tpj_stun_msg *msg,\n\t\t\t\t\t\tint attr_type)\n{\n    pj_stun_empty_attr *attr = NULL;\n    pj_status_t status;\n\n    status = pj_stun_empty_attr_create(pool, attr_type, &attr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return pj_stun_msg_add_attr(msg, &attr->hdr);\n}\n\nstatic pj_status_t decode_empty_attr(pj_pool_t *pool, \n\t\t\t\t     const pj_uint8_t *buf, \n\t\t\t\t     const pj_stun_msg_hdr *msghdr,\n\t\t\t\t     void **p_attr)\n{\n    pj_stun_empty_attr *attr;\n\n    PJ_UNUSED_ARG(msghdr);\n\n    /* Check that the struct address is valid */\n    pj_assert(sizeof(pj_stun_empty_attr) == ATTR_HDR_LEN);\n\n    /* Create the attribute */\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_empty_attr);\n    GETATTRHDR(buf, &attr->hdr);\n\n    /* Check that the attribute length is valid */\n    if (attr->hdr.length != 0)\n\treturn PJNATH_ESTUNINATTRLEN;\n\n    /* Done */\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t encode_empty_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t     unsigned len, \n\t\t\t\t     const pj_stun_msg_hdr *msghdr,\n\t\t\t\t     unsigned *printed)\n{\n    const pj_stun_empty_attr *ca = (pj_stun_empty_attr*)a;\n\n    PJ_UNUSED_ARG(msghdr);\n\n    if (len < ATTR_HDR_LEN) \n\treturn PJ_ETOOSMALL;\n\n    PUTVAL16H(buf, 0, ca->hdr.type);\n    PUTVAL16H(buf, 2, 0);\n\n    /* Done */\n    *printed = ATTR_HDR_LEN;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void* clone_empty_attr(pj_pool_t *pool, const void *src)\n{\n    pj_stun_empty_attr *dst = PJ_POOL_ALLOC_T(pool, pj_stun_empty_attr);\n\n    pj_memcpy(dst, src, sizeof(pj_stun_empty_attr));\n\n    return (void*) dst;\n}\n\n//////////////////////////////////////////////////////////////////////////////\n/*\n * STUN generic 32bit integer attribute.\n */\n\n/*\n * Create a STUN generic 32bit value attribute.\n */\nPJ_DEF(pj_status_t) pj_stun_uint_attr_create(pj_pool_t *pool,\n\t\t\t\t\t     int attr_type,\n\t\t\t\t\t     pj_uint32_t value,\n\t\t\t\t\t     pj_stun_uint_attr **p_attr)\n{\n    pj_stun_uint_attr *attr;\n\n    PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL);\n\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint_attr);\n    INIT_ATTR(attr, attr_type, 4);\n    attr->value = value;\n\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n}\n\n/* Create and add STUN generic 32bit value attribute to the message. */\nPJ_DEF(pj_status_t) pj_stun_msg_add_uint_attr(pj_pool_t *pool,\n\t\t\t\t\t      pj_stun_msg *msg,\n\t\t\t\t\t      int attr_type,\n\t\t\t\t\t      pj_uint32_t value)\n{\n    pj_stun_uint_attr *attr = NULL;\n    pj_status_t status;\n\n    status = pj_stun_uint_attr_create(pool, attr_type, value, &attr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return pj_stun_msg_add_attr(msg, &attr->hdr);\n}\n\nstatic pj_status_t decode_uint_attr(pj_pool_t *pool, \n\t\t\t\t    const pj_uint8_t *buf, \n\t\t\t\t    const pj_stun_msg_hdr *msghdr, \n\t\t\t\t    void **p_attr)\n{\n    pj_stun_uint_attr *attr;\n\n    PJ_UNUSED_ARG(msghdr);\n\n    /* Create the attribute */\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint_attr);\n    GETATTRHDR(buf, &attr->hdr);\n\n    attr->value = GETVAL32H(buf, 4);\n\n    /* Check that the attribute length is valid */\n    if (attr->hdr.length != 4)\n\treturn PJNATH_ESTUNINATTRLEN;\n\n    /* Done */\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t encode_uint_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t    unsigned len, \n\t\t\t\t    const pj_stun_msg_hdr *msghdr,\n\t\t\t\t    unsigned *printed)\n{\n    const pj_stun_uint_attr *ca = (const pj_stun_uint_attr*)a;\n\n    PJ_CHECK_STACK();\n\n    PJ_UNUSED_ARG(msghdr);\n    \n    if (len < 8) \n\treturn PJ_ETOOSMALL;\n\n    PUTVAL16H(buf, 0, ca->hdr.type);\n    PUTVAL16H(buf, 2, (pj_uint16_t)4);\n    PUTVAL32H(buf, 4, ca->value);\n    \n    /* Done */\n    *printed = 8;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void* clone_uint_attr(pj_pool_t *pool, const void *src)\n{\n    pj_stun_uint_attr *dst = PJ_POOL_ALLOC_T(pool, pj_stun_uint_attr);\n\n    pj_memcpy(dst, src, sizeof(pj_stun_uint_attr));\n\n    return (void*)dst;\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\n/*\n * Create a STUN generic 64bit value attribute.\n */\nPJ_DEF(pj_status_t) pj_stun_uint64_attr_create(pj_pool_t *pool,\n\t\t\t\t\t       int attr_type,\n\t\t\t\t\t       const pj_timestamp *value,\n\t\t\t\t\t       pj_stun_uint64_attr **p_attr)\n{\n    pj_stun_uint64_attr *attr;\n\n    PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL);\n\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint64_attr);\n    INIT_ATTR(attr, attr_type, 8);\n\n    if (value) {\n\tattr->value.u32.hi = value->u32.hi;\n\tattr->value.u32.lo = value->u32.lo;\n    }\n\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n}\n\n/* Create and add STUN generic 64bit value attribute to the message. */\nPJ_DEF(pj_status_t)  pj_stun_msg_add_uint64_attr(pj_pool_t *pool,\n\t\t\t\t\t         pj_stun_msg *msg,\n\t\t\t\t\t         int attr_type,\n\t\t\t\t\t         const pj_timestamp *value)\n{\n    pj_stun_uint64_attr *attr = NULL;\n    pj_status_t status;\n\n    status = pj_stun_uint64_attr_create(pool, attr_type, value, &attr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return pj_stun_msg_add_attr(msg, &attr->hdr);\n}\n\nstatic pj_status_t decode_uint64_attr(pj_pool_t *pool, \n\t\t\t\t      const pj_uint8_t *buf, \n\t\t\t\t      const pj_stun_msg_hdr *msghdr, \n\t\t\t\t      void **p_attr)\n{\n    pj_stun_uint64_attr *attr;\n\n    PJ_UNUSED_ARG(msghdr);\n\n    /* Create the attribute */\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint64_attr);\n    GETATTRHDR(buf, &attr->hdr);\n\n    if (attr->hdr.length != 8)\n\treturn PJNATH_ESTUNINATTRLEN;\n\n    GETVAL64H(buf, 4, &attr->value);\t\n\n    /* Done */\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t encode_uint64_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t      unsigned len, \n\t\t\t\t      const pj_stun_msg_hdr *msghdr,\n\t\t\t\t      unsigned *printed)\n{\n    const pj_stun_uint64_attr *ca = (const pj_stun_uint64_attr*)a;\n\n    PJ_CHECK_STACK();\n\n    PJ_UNUSED_ARG(msghdr);\n    \n    if (len < 12) \n\treturn PJ_ETOOSMALL;\n\n    PUTVAL16H(buf, 0, ca->hdr.type);\n    PUTVAL16H(buf, 2, (pj_uint16_t)8);\n    PUTVAL64H(buf, 4, &ca->value);\n\n    /* Done */\n    *printed = 12;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void* clone_uint64_attr(pj_pool_t *pool, const void *src)\n{\n    pj_stun_uint64_attr *dst = PJ_POOL_ALLOC_T(pool, pj_stun_uint64_attr);\n\n    pj_memcpy(dst, src, sizeof(pj_stun_uint64_attr));\n\n    return (void*)dst;\n}\n\n\n//////////////////////////////////////////////////////////////////////////////\n/*\n * STUN MESSAGE-INTEGRITY attribute.\n */\n\n/*\n * Create a STUN MESSAGE-INTEGRITY attribute.\n */\nPJ_DEF(pj_status_t) pj_stun_msgint_attr_create(pj_pool_t *pool,\n\t\t\t\t\t       pj_stun_msgint_attr **p_attr)\n{\n    pj_stun_msgint_attr *attr;\n\n    PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL);\n\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_msgint_attr);\n    INIT_ATTR(attr, PJ_STUN_ATTR_MESSAGE_INTEGRITY, 20);\n\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_stun_msg_add_msgint_attr(pj_pool_t *pool,\n\t\t\t\t\t\tpj_stun_msg *msg)\n{\n    pj_stun_msgint_attr *attr = NULL;\n    pj_status_t status;\n\n    status = pj_stun_msgint_attr_create(pool, &attr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return pj_stun_msg_add_attr(msg, &attr->hdr);\n}\n\nstatic pj_status_t decode_msgint_attr(pj_pool_t *pool, \n\t\t\t\t      const pj_uint8_t *buf,\n\t\t\t\t      const pj_stun_msg_hdr *msghdr, \n\t\t\t\t      void **p_attr)\n{\n    pj_stun_msgint_attr *attr;\n\n    PJ_UNUSED_ARG(msghdr);\n\n    /* Create attribute */\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_msgint_attr);\n    GETATTRHDR(buf, &attr->hdr);\n\n    /* Check that the attribute length is valid */\n    if (attr->hdr.length != 20)\n\treturn PJNATH_ESTUNINATTRLEN;\n\n    /* Copy hmac */\n    pj_memcpy(attr->hmac, buf+4, 20);\n\n    /* Done */\n    *p_attr = attr;\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t encode_msgint_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t      unsigned len, \n\t\t\t\t      const pj_stun_msg_hdr *msghdr,\n\t\t\t\t      unsigned *printed)\n{\n    const pj_stun_msgint_attr *ca = (const pj_stun_msgint_attr*)a;\n\n    PJ_CHECK_STACK();\n    \n    PJ_UNUSED_ARG(msghdr);\n\n    if (len < 24) \n\treturn PJ_ETOOSMALL;\n\n    /* Copy and convert attribute to network byte order */\n    PUTVAL16H(buf, 0, ca->hdr.type);\n    PUTVAL16H(buf, 2, ca->hdr.length);\n\n    pj_memcpy(buf+4, ca->hmac, 20);\n\n    /* Done */\n    *printed = 24;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void* clone_msgint_attr(pj_pool_t *pool, const void *src)\n{\n    pj_stun_msgint_attr *dst = PJ_POOL_ALLOC_T(pool, pj_stun_msgint_attr);\n\n    pj_memcpy(dst, src, sizeof(pj_stun_msgint_attr));\n\n    return (void*) dst;\n}\n\n//////////////////////////////////////////////////////////////////////////////\n/*\n * STUN ERROR-CODE\n */\n\n/*\n * Create a STUN ERROR-CODE attribute.\n */\nPJ_DEF(pj_status_t) pj_stun_errcode_attr_create(pj_pool_t *pool,\n\t\t\t\t\t\tint err_code,\n\t\t\t\t\t\tconst pj_str_t *err_reason,\n\t\t\t\t\t\tpj_stun_errcode_attr **p_attr)\n{\n    pj_stun_errcode_attr *attr;\n    char err_buf[80];\n    pj_str_t str;\n\n    PJ_ASSERT_RETURN(pool && err_code && p_attr, PJ_EINVAL);\n\n    if (err_reason == NULL) {\n\tstr = pj_stun_get_err_reason(err_code);\n\tif (str.slen == 0) {\n\t    str.slen = pj_ansi_snprintf(err_buf, sizeof(err_buf),\n\t\t\t\t        \"Unknown error %d\", err_code);\n\t    str.ptr = err_buf;\n\t}\n\terr_reason = &str;\n    }\n\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_errcode_attr);\n    INIT_ATTR(attr, PJ_STUN_ATTR_ERROR_CODE, 4+err_reason->slen);\n    attr->err_code = err_code;\n    pj_strdup(pool, &attr->reason, err_reason);\n\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_stun_msg_add_errcode_attr(pj_pool_t *pool,\n\t\t\t\t\t\t pj_stun_msg *msg,\n\t\t\t\t\t\t int err_code,\n\t\t\t\t\t\t const pj_str_t *err_reason)\n{\n    pj_stun_errcode_attr *err_attr = NULL;\n    pj_status_t status;\n\n    status = pj_stun_errcode_attr_create(pool, err_code, err_reason,\n\t\t\t\t\t &err_attr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return pj_stun_msg_add_attr(msg, &err_attr->hdr);\n}\n\nstatic pj_status_t decode_errcode_attr(pj_pool_t *pool, \n\t\t\t\t       const pj_uint8_t *buf,\n\t\t\t\t       const pj_stun_msg_hdr *msghdr, \n\t\t\t\t       void **p_attr)\n{\n    pj_stun_errcode_attr *attr;\n    pj_str_t value;\n\n    PJ_UNUSED_ARG(msghdr);\n\n    /* Create the attribute */\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_errcode_attr);\n    GETATTRHDR(buf, &attr->hdr);\n\n    attr->err_code = buf[6] * 100 + buf[7];\n\n    /* Get pointer to the string in the message */\n    value.ptr = ((char*)buf + ATTR_HDR_LEN + 4);\n    value.slen = attr->hdr.length - 4;\n\n    /* Copy the string to the attribute */\n    pj_strdup(pool, &attr->reason, &value);\n\n    /* Done */\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t encode_errcode_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t       unsigned len, \n\t\t\t\t       const pj_stun_msg_hdr *msghdr,\n\t\t\t\t       unsigned *printed)\n{\n    const pj_stun_errcode_attr *ca = \n\t(const pj_stun_errcode_attr*)a;\n\n    PJ_CHECK_STACK();\n    \n    PJ_UNUSED_ARG(msghdr);\n\n    if (len < ATTR_HDR_LEN + 4 + (unsigned)ca->reason.slen) \n\treturn PJ_ETOOSMALL;\n\n    /* Copy and convert attribute to network byte order */\n    PUTVAL16H(buf, 0, ca->hdr.type);\n    PUTVAL16H(buf, 2, (pj_uint16_t)(4 + ca->reason.slen));\n    PUTVAL16H(buf, 4, 0);\n    buf[6] = (pj_uint8_t)(ca->err_code / 100);\n    buf[7] = (pj_uint8_t)(ca->err_code % 100);\n\n    /* Copy error string */\n    pj_memcpy(buf + ATTR_HDR_LEN + 4, ca->reason.ptr, ca->reason.slen);\n\n    /* Done */\n    *printed = (ATTR_HDR_LEN + 4 + (unsigned)ca->reason.slen + 3) & (~3);\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void* clone_errcode_attr(pj_pool_t *pool, const void *src)\n{\n    const pj_stun_errcode_attr *asrc = (const pj_stun_errcode_attr*)src;\n    pj_stun_errcode_attr *dst = PJ_POOL_ALLOC_T(pool, pj_stun_errcode_attr);\n\n    pj_memcpy(dst, src, sizeof(pj_stun_errcode_attr));\n    pj_strdup(pool, &dst->reason, &asrc->reason);\n\n    return (void*)dst;\n}\n\n//////////////////////////////////////////////////////////////////////////////\n/*\n * STUN UNKNOWN-ATTRIBUTES attribute\n */\n\n/*\n * Create an empty instance of STUN UNKNOWN-ATTRIBUTES attribute.\n *\n * @param pool\t\tThe pool to allocate memory from.\n * @param p_attr\tPointer to receive the attribute.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DEF(pj_status_t) pj_stun_unknown_attr_create(pj_pool_t *pool,\n\t\t\t\t\t\tunsigned attr_cnt,\n\t\t\t\t\t\tconst pj_uint16_t attr_array[],\n\t\t\t\t\t\tpj_stun_unknown_attr **p_attr)\n{\n    pj_stun_unknown_attr *attr;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(pool && attr_cnt < PJ_STUN_MAX_ATTR && p_attr, PJ_EINVAL);\n\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_unknown_attr);\n    INIT_ATTR(attr, PJ_STUN_ATTR_UNKNOWN_ATTRIBUTES, attr_cnt * 2);\n\n    attr->attr_count = attr_cnt;\n    for (i=0; i<attr_cnt; ++i) {\n\tattr->attrs[i] = attr_array[i];\n    }\n\n    /* If the number of unknown attributes is an odd number, one of the\n     * attributes MUST be repeated in the list.\n     */\n    /* No longer necessary\n    if ((attr_cnt & 0x01)) {\n\tattr->attrs[attr_cnt] = attr_array[attr_cnt-1];\n    }\n    */\n\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Create and add STUN UNKNOWN-ATTRIBUTES attribute to the message. */\nPJ_DEF(pj_status_t) pj_stun_msg_add_unknown_attr(pj_pool_t *pool,\n\t\t\t\t\t\t pj_stun_msg *msg,\n\t\t\t\t\t\t unsigned attr_cnt,\n\t\t\t\t\t\t const pj_uint16_t attr_type[])\n{\n    pj_stun_unknown_attr *attr = NULL;\n    pj_status_t status;\n\n    status = pj_stun_unknown_attr_create(pool, attr_cnt, attr_type, &attr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return pj_stun_msg_add_attr(msg, &attr->hdr);\n}\n\nstatic pj_status_t decode_unknown_attr(pj_pool_t *pool, \n\t\t\t\t       const pj_uint8_t *buf, \n\t\t\t\t       const pj_stun_msg_hdr *msghdr, \n\t\t\t\t       void **p_attr)\n{\n    pj_stun_unknown_attr *attr;\n    const pj_uint16_t *punk_attr;\n    unsigned i;\n\n    PJ_UNUSED_ARG(msghdr);\n\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_unknown_attr);\n    GETATTRHDR(buf, &attr->hdr);\n \n    attr->attr_count = (attr->hdr.length >> 1);\n    if (attr->attr_count > PJ_STUN_MAX_ATTR)\n\treturn PJ_ETOOMANY;\n\n    punk_attr = (const pj_uint16_t*)(buf + ATTR_HDR_LEN);\n    for (i=0; i<attr->attr_count; ++i) {\n\tattr->attrs[i] = pj_ntohs(punk_attr[i]);\n    }\n\n    /* Done */\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_status_t encode_unknown_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t       unsigned len, \n\t\t\t\t       const pj_stun_msg_hdr *msghdr,\n\t\t\t\t       unsigned *printed)\n{\n    const pj_stun_unknown_attr *ca = (const pj_stun_unknown_attr*) a;\n    pj_uint16_t *dst_unk_attr;\n    unsigned i;\n\n    PJ_CHECK_STACK();\n    \n    PJ_UNUSED_ARG(msghdr);\n\n    /* Check that buffer is enough */\n    if (len < ATTR_HDR_LEN + (ca->attr_count << 1))\n\treturn PJ_ETOOSMALL;\n\n    PUTVAL16H(buf, 0, ca->hdr.type);\n    PUTVAL16H(buf, 2, (pj_uint16_t)(ca->attr_count << 1));\n\n    /* Copy individual attribute */\n    dst_unk_attr = (pj_uint16_t*)(buf + ATTR_HDR_LEN);\n    for (i=0; i < ca->attr_count; ++i, ++dst_unk_attr) {\n\t*dst_unk_attr = pj_htons(ca->attrs[i]);\n    }\n\n    /* Done */\n    *printed = (ATTR_HDR_LEN + (ca->attr_count << 1) + 3) & (~3);\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void* clone_unknown_attr(pj_pool_t *pool, const void *src)\n{\n    pj_stun_unknown_attr *dst = PJ_POOL_ALLOC_T(pool, pj_stun_unknown_attr);\n\n    pj_memcpy(dst, src, sizeof(pj_stun_unknown_attr));\n    \n    return (void*)dst;\n}\n\n//////////////////////////////////////////////////////////////////////////////\n/*\n * STUN generic binary attribute\n */\n\n/*\n * Initialize STUN binary attribute.\n */\nPJ_DEF(pj_status_t) pj_stun_binary_attr_init( pj_stun_binary_attr *attr,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      int attr_type,\n\t\t\t\t\t      const pj_uint8_t *data,\n\t\t\t\t\t      unsigned length)\n{\n    PJ_ASSERT_RETURN(attr_type, PJ_EINVAL);\n\n    INIT_ATTR(attr, attr_type, length);\n\n    attr->magic = PJ_STUN_MAGIC;\n\n    if (data && length) {\n\tattr->length = length;\n\tattr->data = (pj_uint8_t*) pj_pool_alloc(pool, length);\n\tpj_memcpy(attr->data, data, length);\n    } else {\n\tattr->data = NULL;\n\tattr->length = 0;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create a blank binary attribute.\n */\nPJ_DEF(pj_status_t) pj_stun_binary_attr_create(pj_pool_t *pool,\n\t\t\t\t\t       int attr_type,\n\t\t\t\t\t       const pj_uint8_t *data,\n\t\t\t\t\t       unsigned length,\n\t\t\t\t\t       pj_stun_binary_attr **p_attr)\n{\n    pj_stun_binary_attr *attr;\n\n    PJ_ASSERT_RETURN(pool && attr_type && p_attr, PJ_EINVAL);\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_binary_attr);\n    *p_attr = attr;\n    return pj_stun_binary_attr_init(attr, pool, attr_type, data, length);\n}\n\n\n/* Create and add binary attr. */\nPJ_DEF(pj_status_t) pj_stun_msg_add_binary_attr(pj_pool_t *pool,\n\t\t\t\t\t\tpj_stun_msg *msg,\n\t\t\t\t\t\tint attr_type,\n\t\t\t\t\t\tconst pj_uint8_t *data,\n\t\t\t\t\t\tunsigned length)\n{\n    pj_stun_binary_attr *attr = NULL;\n    pj_status_t status;\n\n    status = pj_stun_binary_attr_create(pool, attr_type,\n\t\t\t\t\tdata, length, &attr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return pj_stun_msg_add_attr(msg, &attr->hdr);\n}\n\n\nstatic pj_status_t decode_binary_attr(pj_pool_t *pool, \n\t\t\t\t      const pj_uint8_t *buf,\n\t\t\t\t      const pj_stun_msg_hdr *msghdr,\n\t\t\t\t      void **p_attr)\n{\n    pj_stun_binary_attr *attr;\n\n    PJ_UNUSED_ARG(msghdr);\n\n    /* Create the attribute */\n    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_binary_attr);\n    GETATTRHDR(buf, &attr->hdr);\n\n    /* Copy the data to the attribute */\n    attr->length = attr->hdr.length;\n    attr->data = (pj_uint8_t*) pj_pool_alloc(pool, attr->length);\n    pj_memcpy(attr->data, buf+ATTR_HDR_LEN, attr->length);\n\n    /* Done */\n    *p_attr = attr;\n\n    return PJ_SUCCESS;\n\n}\n\n\nstatic pj_status_t encode_binary_attr(const void *a, pj_uint8_t *buf, \n\t\t\t\t      unsigned len, \n\t\t\t\t      const pj_stun_msg_hdr *msghdr,\n\t\t\t\t      unsigned *printed)\n{\n    const pj_stun_binary_attr *ca = (const pj_stun_binary_attr*)a;\n\n    PJ_CHECK_STACK();\n    \n    PJ_UNUSED_ARG(msghdr);\n\n    /* Calculated total attr_len (add padding if necessary) */\n    *printed = (ca->length + ATTR_HDR_LEN + 3) & (~3);\n    if (len < *printed)\n\treturn PJ_ETOOSMALL;\n\n    PUTVAL16H(buf, 0, ca->hdr.type);\n    PUTVAL16H(buf, 2, (pj_uint16_t) ca->length);\n\n    /* Copy the data */\n    pj_memcpy(buf+ATTR_HDR_LEN, ca->data, ca->length);\n\n    /* Done */\n    return PJ_SUCCESS;\n}\n\n\nstatic void* clone_binary_attr(pj_pool_t *pool, const void *src)\n{\n    const pj_stun_binary_attr *asrc = (const pj_stun_binary_attr*)src;\n    pj_stun_binary_attr *dst = PJ_POOL_ALLOC_T(pool, pj_stun_binary_attr);\n\n    pj_memcpy(dst, src, sizeof(pj_stun_binary_attr));\n\n    if (asrc->length) {\n\tdst->data = (pj_uint8_t*) pj_pool_alloc(pool, asrc->length);\n\tpj_memcpy(dst->data, asrc->data, asrc->length);\n    }\n\n    return (void*)dst;\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\n/*\n * Initialize a generic STUN message.\n */\nPJ_DEF(pj_status_t) pj_stun_msg_init( pj_stun_msg *msg,\n\t\t\t\t      unsigned msg_type,\n\t\t\t\t      pj_uint32_t magic,\n\t\t\t\t      const pj_uint8_t tsx_id[12])\n{\n    PJ_ASSERT_RETURN(msg && msg_type, PJ_EINVAL);\n\n    msg->hdr.type = (pj_uint16_t) msg_type;\n    msg->hdr.length = 0;\n    msg->hdr.magic = magic;\n    msg->attr_count = 0;\n\n    if (tsx_id) {\n\tpj_memcpy(&msg->hdr.tsx_id, tsx_id, sizeof(msg->hdr.tsx_id));\n    } else {\n\tstruct transaction_id\n\t{\n\t    pj_uint32_t\t    proc_id;\n\t    pj_uint32_t\t    random;\n\t    pj_uint32_t\t    counter;\n\t} id;\n\tstatic pj_uint32_t pj_stun_tsx_id_counter;\n\n\tif (!pj_stun_tsx_id_counter)\n\t    pj_stun_tsx_id_counter = pj_rand();\n\n\tid.proc_id = pj_getpid();\n\tid.random = pj_rand();\n\tid.counter = pj_stun_tsx_id_counter++;\n\n\tpj_memcpy(&msg->hdr.tsx_id, &id, sizeof(msg->hdr.tsx_id));\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create a blank STUN message.\n */\nPJ_DEF(pj_status_t) pj_stun_msg_create( pj_pool_t *pool,\n\t\t\t\t\tunsigned msg_type,\n\t\t\t\t\tpj_uint32_t magic,\n\t\t\t\t\tconst pj_uint8_t tsx_id[12],\n\t\t\t\t\tpj_stun_msg **p_msg)\n{\n    pj_stun_msg *msg;\n\n    PJ_ASSERT_RETURN(pool && msg_type && p_msg, PJ_EINVAL);\n\n    msg = PJ_POOL_ZALLOC_T(pool, pj_stun_msg);\n    *p_msg = msg;\n    return pj_stun_msg_init(msg, msg_type, magic, tsx_id);\n}\n\n\n/*\n * Clone a STUN message with all of its attributes.\n */\nPJ_DEF(pj_stun_msg*) pj_stun_msg_clone( pj_pool_t *pool,\n\t\t\t\t\tconst pj_stun_msg *src)\n{\n    pj_stun_msg *dst;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(pool && src, NULL);\n\n    dst = PJ_POOL_ZALLOC_T(pool, pj_stun_msg);\n    pj_memcpy(dst, src, sizeof(pj_stun_msg));\n\n    /* Duplicate the attributes */\n    for (i=0, dst->attr_count=0; i<src->attr_count; ++i) {\n\tdst->attr[dst->attr_count] = pj_stun_attr_clone(pool, src->attr[i]);\n\tif (dst->attr[dst->attr_count])\n\t    ++dst->attr_count;\n    }\n\n    return dst;\n}\n\n\n/*\n * Add STUN attribute to STUN message.\n */\nPJ_DEF(pj_status_t) pj_stun_msg_add_attr(pj_stun_msg *msg,\n\t\t\t\t\t pj_stun_attr_hdr *attr)\n{\n    PJ_ASSERT_RETURN(msg && attr, PJ_EINVAL);\n    PJ_ASSERT_RETURN(msg->attr_count < PJ_STUN_MAX_ATTR, PJ_ETOOMANY);\n\n    msg->attr[msg->attr_count++] = attr;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Check that the PDU is potentially a valid STUN message.\n */\nPJ_DEF(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, pj_size_t pdu_len,\n\t\t\t\t      unsigned options)\n{\n    pj_uint32_t msg_len;\n\n    PJ_ASSERT_RETURN(pdu, PJ_EINVAL);\n\n    if (pdu_len < sizeof(pj_stun_msg_hdr))\n\treturn PJNATH_EINSTUNMSGLEN;\n\n    /* First byte of STUN message is always 0x00 or 0x01. */\n    if (*pdu != 0x00 && *pdu != 0x01)\n\treturn PJNATH_EINSTUNMSGTYPE;\n\n    /* Check the PDU length */\n    msg_len = GETVAL16H(pdu, 2);\n    if ((msg_len + 20 > pdu_len) || \n\t((options & PJ_STUN_IS_DATAGRAM) && msg_len + 20 != pdu_len))\n    {\n\treturn PJNATH_EINSTUNMSGLEN;\n    }\n\n    /* STUN message is always padded to the nearest 4 bytes, thus\n     * the last two bits of the length field are always zero.\n     */\n    if ((msg_len & 0x03) != 0) {\n\treturn PJNATH_EINSTUNMSGLEN;\n    }\n\n    /* If magic is set, then there is great possibility that this is\n     * a STUN message.\n     */\n    if (GETVAL32H(pdu, 4) == PJ_STUN_MAGIC) {\n\n\t/* Check if FINGERPRINT attribute is present */\n\tif ((options & PJ_STUN_NO_FINGERPRINT_CHECK )==0 && \n\t    GETVAL16H(pdu, msg_len + 20 - 8) == PJ_STUN_ATTR_FINGERPRINT) \n\t{\n\t    pj_uint16_t attr_len = GETVAL16H(pdu, msg_len + 20 - 8 + 2);\n\t    pj_uint32_t fingerprint = GETVAL32H(pdu, msg_len + 20 - 8 + 4);\n\t    pj_uint32_t crc;\n\n\t    if (attr_len != 4)\n\t\treturn PJNATH_ESTUNINATTRLEN;\n\n\t    crc = pj_crc32_calc(pdu, msg_len + 20 - 8);\n\t    crc ^= STUN_XOR_FINGERPRINT;\n\n\t    if (crc != fingerprint)\n\t\treturn PJNATH_ESTUNFINGERPRINT;\n\t}\n    }\n\n    /* Could be a STUN message */\n    return PJ_SUCCESS;\n}\n\n\n/* Create error response */\nPJ_DEF(pj_status_t) pj_stun_msg_create_response(pj_pool_t *pool,\n\t\t\t\t\t\tconst pj_stun_msg *req_msg,\n\t\t\t\t\t\tunsigned err_code,\n\t\t\t\t\t\tconst pj_str_t *err_msg,\n\t\t\t\t\t\tpj_stun_msg **p_response)\n{\n    unsigned msg_type = req_msg->hdr.type;\n    pj_stun_msg *response = NULL;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && p_response, PJ_EINVAL);\n\n    PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(msg_type), \n\t\t     PJNATH_EINSTUNMSGTYPE);\n\n    /* Create response or error response */\n    if (err_code)\n\tmsg_type |= PJ_STUN_ERROR_RESPONSE_BIT;\n    else\n\tmsg_type |= PJ_STUN_SUCCESS_RESPONSE_BIT;\n\n    status = pj_stun_msg_create(pool, msg_type, req_msg->hdr.magic, \n\t\t\t\treq_msg->hdr.tsx_id, &response);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    /* Add error code attribute */\n    if (err_code) {\n\tstatus = pj_stun_msg_add_errcode_attr(pool, response, \n\t\t\t\t\t      err_code, err_msg);\n\tif (status != PJ_SUCCESS) {\n\t    return status;\n\t}\n    }\n\n    *p_response = response;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Parse incoming packet into STUN message.\n */\nPJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,\n\t\t\t\t       const pj_uint8_t *pdu,\n\t\t\t\t       pj_size_t pdu_len,\n\t\t\t\t       unsigned options,\n\t\t\t\t       pj_stun_msg **p_msg,\n\t\t\t\t       pj_size_t *p_parsed_len,\n\t\t\t\t       pj_stun_msg **p_response)\n{\n    \n    pj_stun_msg *msg;\n    const pj_uint8_t *start_pdu = pdu;\n    pj_bool_t has_msg_int = PJ_FALSE;\n    pj_bool_t has_fingerprint = PJ_FALSE;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(options);\n\n    PJ_ASSERT_RETURN(pool && pdu && pdu_len && p_msg, PJ_EINVAL);\n    PJ_ASSERT_RETURN(sizeof(pj_stun_msg_hdr) == 20, PJ_EBUG);\n\n    if (p_parsed_len)\n\t*p_parsed_len = 0;\n    if (p_response)\n\t*p_response = NULL;\n\n    /* Check if this is a STUN message, if necessary */\n    if (options & PJ_STUN_CHECK_PACKET) {\n\tstatus = pj_stun_msg_check(pdu, pdu_len, options);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    /* Create the message, copy the header, and convert to host byte order */\n    msg = PJ_POOL_ZALLOC_T(pool, pj_stun_msg);\n    pj_memcpy(&msg->hdr, pdu, sizeof(pj_stun_msg_hdr));\n    msg->hdr.type = pj_ntohs(msg->hdr.type);\n    msg->hdr.length = pj_ntohs(msg->hdr.length);\n    msg->hdr.magic = pj_ntohl(msg->hdr.magic);\n\n    pdu += sizeof(pj_stun_msg_hdr);\n    /* pdu_len -= sizeof(pj_stun_msg_hdr); */\n    pdu_len = msg->hdr.length;\n\n    /* No need to create response if this is not a request */\n    if (!PJ_STUN_IS_REQUEST(msg->hdr.type))\n\tp_response = NULL;\n\n    /* Parse attributes */\n    while (pdu_len >= 4) {\n\tunsigned attr_type, attr_val_len;\n\tconst struct attr_desc *adesc;\n\n\t/* Get attribute type and length. If length is not aligned\n\t * to 4 bytes boundary, add padding.\n\t */\n\tattr_type = GETVAL16H(pdu, 0);\n\tattr_val_len = GETVAL16H(pdu, 2);\n\tattr_val_len = (attr_val_len + 3) & (~3);\n\n\t/* Check length */\n\tif (pdu_len < attr_val_len) {\n\t    pj_str_t err_msg;\n\t    char err_msg_buf[80];\n\n\t    err_msg.ptr = err_msg_buf;\n\t    err_msg.slen = pj_ansi_snprintf(err_msg_buf, sizeof(err_msg_buf),\n\t\t\t\t\t    \"Attribute %s has invalid length\",\n\t\t\t\t\t    pj_stun_get_attr_name(attr_type));\n\n\t    PJ_LOG(4,(THIS_FILE, \"Error decoding message: %.*s\",\n\t\t      (int)err_msg.slen, err_msg.ptr));\n\n\t    if (p_response) {\n\t\tpj_stun_msg_create_response(pool, msg, \n\t\t\t\t\t    PJ_STUN_SC_BAD_REQUEST, \n\t\t\t\t\t    &err_msg, p_response);\n\t    }\n\t    return PJNATH_ESTUNINATTRLEN;\n\t}\n\n\t/* Get the attribute descriptor */\n\tadesc = find_attr_desc(attr_type);\n\n\tif (adesc == NULL) {\n\t    /* Unrecognized attribute */\n\t    pj_stun_binary_attr *attr = NULL;\n\n\t    PJ_LOG(5,(THIS_FILE, \"Unrecognized attribute type 0x%x\", \n\t\t      attr_type));\n\n\t    /* Is this a fatal condition? */\n\t    if (attr_type <= 0x7FFF) {\n\t\t/* This is a mandatory attribute, we must return error\n\t\t * if we don't understand the attribute.\n\t\t */\n\t\tif (p_response) {\n\t\t    unsigned err_code = PJ_STUN_SC_UNKNOWN_ATTRIBUTE;\n\n\t\t    status = pj_stun_msg_create_response(pool, msg,\n\t\t\t\t\t\t\t err_code, NULL, \n\t\t\t\t\t\t\t p_response);\n\t\t    if (status==PJ_SUCCESS) {\n\t\t\tpj_uint16_t d = (pj_uint16_t)attr_type;\n\t\t\tpj_stun_msg_add_unknown_attr(pool, *p_response, 1, &d);\n\t\t    }\n\t\t}\n\n\t\treturn PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNKNOWN_ATTRIBUTE);\n\t    }\n\n\t    /* Make sure we have rooms for the new attribute */\n\t    if (msg->attr_count >= PJ_STUN_MAX_ATTR) {\n\t\tif (p_response) {\n\t\t    pj_stun_msg_create_response(pool, msg,\n\t\t\t\t\t\tPJ_STUN_SC_SERVER_ERROR,\n\t\t\t\t\t\tNULL, p_response);\n\t\t}\n\t\treturn PJNATH_ESTUNTOOMANYATTR;\n\t    }\n\n\t    /* Create binary attribute to represent this */\n\t    status = pj_stun_binary_attr_create(pool, attr_type, pdu+4, \n\t\t\t\t\t\tGETVAL16H(pdu, 2), &attr);\n\t    if (status != PJ_SUCCESS) {\n\t\tif (p_response) {\n\t\t    pj_stun_msg_create_response(pool, msg,\n\t\t\t\t\t\tPJ_STUN_SC_SERVER_ERROR,\n\t\t\t\t\t\tNULL, p_response);\n\t\t}\n\n\t\tPJ_LOG(4,(THIS_FILE, \n\t\t\t  \"Error parsing unknown STUN attribute type %d\",\n\t\t\t  attr_type));\n\n\t\treturn status;\n\t    }\n\n\t    /* Add the attribute */\n\t    msg->attr[msg->attr_count++] = &attr->hdr;\n\n\t} else {\n\t    void *attr;\n\t    char err_msg1[PJ_ERR_MSG_SIZE],\n\t\t err_msg2[PJ_ERR_MSG_SIZE];\n\n\t    /* Parse the attribute */\n\t    status = (adesc->decode_attr)(pool, pdu, &msg->hdr, &attr);\n\n\t    if (status != PJ_SUCCESS) {\n\t\tpj_strerror(status, err_msg1, sizeof(err_msg1));\n\n\t\tif (p_response) {\n\t\t    pj_str_t e;\n\n\t\t    e.ptr = err_msg2;\n\t\t    e.slen= pj_ansi_snprintf(err_msg2, sizeof(err_msg2),\n\t\t\t\t\t     \"%s in %s\",\n\t\t\t\t\t     err_msg1,\n\t\t\t\t\t     pj_stun_get_attr_name(attr_type));\n\t\t    if (e.slen < 1 || e.slen >= (int)sizeof(err_msg2))\n\t\t\te.slen = sizeof(err_msg2) - 1;\n\t\t    pj_stun_msg_create_response(pool, msg,\n\t\t\t\t\t\tPJ_STUN_SC_BAD_REQUEST,\n\t\t\t\t\t\t&e, p_response);\n\t\t}\n\n\t\tPJ_LOG(4,(THIS_FILE, \n\t\t\t  \"Error parsing STUN attribute %s: %s\",\n\t\t\t  pj_stun_get_attr_name(attr_type), \n\t\t\t  err_msg1));\n\n\t\treturn status;\n\t    }\n\n\t    if (attr_type == PJ_STUN_ATTR_MESSAGE_INTEGRITY && \n\t\t!has_fingerprint) \n\t    {\n\t\tif (has_msg_int) {\n\t\t    /* Already has MESSAGE-INTEGRITY */\n\t\t    if (p_response) {\n\t\t\tpj_stun_msg_create_response(pool, msg,\n\t\t\t\t\t\t    PJ_STUN_SC_BAD_REQUEST,\n\t\t\t\t\t\t    NULL, p_response);\n\t\t    }\n\t\t    return PJNATH_ESTUNDUPATTR;\n\t\t}\n\t\thas_msg_int = PJ_TRUE;\n\n\t    } else if (attr_type == PJ_STUN_ATTR_FINGERPRINT) {\n\t\tif (has_fingerprint) {\n\t\t    /* Already has FINGERPRINT */\n\t\t    if (p_response) {\n\t\t\tpj_stun_msg_create_response(pool, msg,\n\t\t\t\t\t\t    PJ_STUN_SC_BAD_REQUEST,\n\t\t\t\t\t\t    NULL, p_response);\n\t\t    }\n\t\t    return PJNATH_ESTUNDUPATTR;\n\t\t}\n\t\thas_fingerprint = PJ_TRUE;\n\t    } else {\n\t\tif (has_fingerprint) {\n\t\t    /* Another attribute is found which is not FINGERPRINT\n\t\t     * after FINGERPRINT. Note that non-FINGERPRINT is\n\t\t     * allowed to appear after M-I\n\t\t     */\n\t\t    if (p_response) {\n\t\t\tpj_stun_msg_create_response(pool, msg,\n\t\t\t\t\t\t    PJ_STUN_SC_BAD_REQUEST,\n\t\t\t\t\t\t    NULL, p_response);\n\t\t    }\n\t\t    return PJNATH_ESTUNFINGERPOS;\n\t\t}\n\t    }\n\n\t    /* Make sure we have rooms for the new attribute */\n\t    if (msg->attr_count >= PJ_STUN_MAX_ATTR) {\n\t\tif (p_response) {\n\t\t    pj_stun_msg_create_response(pool, msg,\n\t\t\t\t\t\tPJ_STUN_SC_SERVER_ERROR,\n\t\t\t\t\t\tNULL, p_response);\n\t\t}\n\t\treturn PJNATH_ESTUNTOOMANYATTR;\n\t    }\n\n\t    /* Add the attribute */\n\t    msg->attr[msg->attr_count++] = (pj_stun_attr_hdr*)attr;\n\t}\n\n\t/* Next attribute */\n\tif (attr_val_len + 4 >= pdu_len) {\n\t    pdu += pdu_len;\n\t    pdu_len = 0;\n\t} else {\n\t    pdu += (attr_val_len + 4);\n\t    pdu_len -= (attr_val_len + 4);\n\t}\n    }\n\n    if (pdu_len > 0) {\n\t/* Stray trailing bytes */\n\tPJ_LOG(4,(THIS_FILE, \n\t\t  \"Error decoding STUN message: unparsed trailing %d bytes\",\n\t\t  pdu_len));\n\treturn PJNATH_EINSTUNMSGLEN;\n    }\n\n    *p_msg = msg;\n\n    if (p_parsed_len)\n\t*p_parsed_len = (pdu - start_pdu);\n\n    return PJ_SUCCESS;\n}\n\n/*\nstatic char *print_binary(const pj_uint8_t *data, unsigned data_len)\n{\n    static char static_buffer[1024];\n    char *buffer = static_buffer;\n    unsigned length=sizeof(static_buffer), i;\n\n    if (length < data_len * 2 + 8)\n\treturn \"\";\n\n    pj_ansi_sprintf(buffer, \", data=\");\n    buffer += 7;\n\n    for (i=0; i<data_len; ++i) {\n\tpj_ansi_sprintf(buffer, \"%02x\", (*data) & 0xFF);\n\tbuffer += 2;\n\tdata++;\n    }\n\n    pj_ansi_sprintf(buffer, \"\\n\");\n    buffer++;\n\n    return static_buffer;\n}\n*/\n\n/*\n * Print the message structure to a buffer.\n */\nPJ_DEF(pj_status_t) pj_stun_msg_encode(pj_stun_msg *msg,\n\t\t\t\t       pj_uint8_t *buf, pj_size_t buf_size,\n\t\t\t\t       unsigned options,\n\t\t\t\t       const pj_str_t *key,\n\t\t\t\t       pj_size_t *p_msg_len)\n{\n    pj_uint8_t *start = buf;\n    pj_stun_msgint_attr *amsgint = NULL;\n    pj_stun_fingerprint_attr *afingerprint = NULL;\n    unsigned printed = 0, body_len;\n    pj_status_t status;\n    unsigned i;\n\n\n    PJ_ASSERT_RETURN(msg && buf && buf_size, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(options);\n    PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);\n\n    /* Copy the message header part and convert the header fields to\n     * network byte order\n     */\n    if (buf_size < sizeof(pj_stun_msg_hdr))\n\treturn PJ_ETOOSMALL;\n    \n    PUTVAL16H(buf, 0, msg->hdr.type);\n    PUTVAL16H(buf, 2, 0);   /* length will be calculated later */\n    PUTVAL32H(buf, 4, msg->hdr.magic);\n    pj_memcpy(buf+8, msg->hdr.tsx_id, sizeof(msg->hdr.tsx_id));\n\n    buf += sizeof(pj_stun_msg_hdr);\n    buf_size -= sizeof(pj_stun_msg_hdr);\n\n    /* Encode each attribute to the message */\n    for (i=0; i<msg->attr_count; ++i) {\n\tconst struct attr_desc *adesc;\n\tconst pj_stun_attr_hdr *attr_hdr = msg->attr[i];\n\n\tif (attr_hdr->type == PJ_STUN_ATTR_MESSAGE_INTEGRITY) {\n\t    pj_assert(amsgint == NULL);\n\t    amsgint = (pj_stun_msgint_attr*) attr_hdr;\n\n\t    /* Stop when encountering MESSAGE-INTEGRITY */\n\t    break;\n\n\t} else if (attr_hdr->type == PJ_STUN_ATTR_FINGERPRINT) {\n\t    afingerprint = (pj_stun_fingerprint_attr*) attr_hdr;\n\t    break;\n\t}\n\n\tadesc = find_attr_desc(attr_hdr->type);\n\tif (adesc) {\n\t    status = adesc->encode_attr(attr_hdr, buf, (unsigned)buf_size, \n\t\t\t\t\t&msg->hdr, &printed);\n\t} else {\n\t    /* This may be a generic attribute */\n\t    const pj_stun_binary_attr *bin_attr = (const pj_stun_binary_attr*) \n\t\t\t\t\t\t   attr_hdr;\n\t    PJ_ASSERT_RETURN(bin_attr->magic == PJ_STUN_MAGIC, PJ_EBUG);\n\t    status = encode_binary_attr(bin_attr, buf, (unsigned)buf_size, \n\t\t\t\t\t&msg->hdr, &printed);\n\t}\n\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tbuf += printed;\n\tbuf_size -= printed;\n    }\n\n    /* We may have stopped printing attribute because we found\n     * MESSAGE-INTEGRITY or FINGERPRINT. Scan the rest of the\n     * attributes.\n     */\n    for ( ++i; i<msg->attr_count; ++i) {\n\tconst pj_stun_attr_hdr *attr_hdr = msg->attr[i];\n\n\t/* There mustn't any attribute after FINGERPRINT */\n\tPJ_ASSERT_RETURN(afingerprint == NULL, PJNATH_ESTUNFINGERPOS);\n\n\tif (attr_hdr->type == PJ_STUN_ATTR_MESSAGE_INTEGRITY) {\n\t    /* There mustn't be MESSAGE-INTEGRITY before */\n\t    PJ_ASSERT_RETURN(amsgint == NULL, \n\t\t\t     PJNATH_ESTUNMSGINTPOS);\n\t    amsgint = (pj_stun_msgint_attr*) attr_hdr;\n\n\t} else if (attr_hdr->type == PJ_STUN_ATTR_FINGERPRINT) {\n\t    afingerprint = (pj_stun_fingerprint_attr*) attr_hdr;\n\t}\n    }\n\n#if PJ_STUN_OLD_STYLE_MI_FINGERPRINT\n    /*\n     * This is the old style MESSAGE-INTEGRITY and FINGERPRINT\n     * calculation, used in rfc3489bis-06 and older.\n     */\n    /* We MUST update the message length in the header NOW before\n     * calculating MESSAGE-INTEGRITY and FINGERPRINT. \n     * Note that length is not including the 20 bytes header.\n      */\n    if (amsgint && afingerprint) {\n\tbody_len = (pj_uint16_t)((buf - start) - 20 + 24 + 8);\n    } else if (amsgint) {\n\tbody_len = (pj_uint16_t)((buf - start) - 20 + 24);\n    } else if (afingerprint) {\n\tbody_len = (pj_uint16_t)((buf - start) - 20 + 8);\n    } else {\n\tbody_len = (pj_uint16_t)((buf - start) - 20);\n    }\n#else\n    /* If MESSAGE-INTEGRITY is present, include the M-I attribute\n     * in message length before calculating M-I\n     */\n    if (amsgint) {\n\tbody_len = (pj_uint16_t)((buf - start) - 20 + 24);\n    } else {\n\tbody_len = (pj_uint16_t)((buf - start) - 20);\n    }\n#endif\t/* PJ_STUN_OLD_STYLE_MI_FINGERPRINT */\n\n    /* hdr->length = pj_htons(length); */\n    PUTVAL16H(start, 2, (pj_uint16_t)body_len);\n\n    /* Calculate message integrity, if present */\n    if (amsgint != NULL) {\n\tpj_hmac_sha1_context ctx;\n\n\t/* Key MUST be specified */\n\tPJ_ASSERT_RETURN(key, PJ_EINVALIDOP);\n\n\t/* MESSAGE-INTEGRITY must be the last attribute in the message, or\n\t * the last attribute before FINGERPRINT.\n\t */\n\tif (msg->attr_count>1 && i < msg->attr_count-2) {\n\t    /* Should not happen for message generated by us */\n\t    pj_assert(PJ_FALSE);\n\t    return PJNATH_ESTUNMSGINTPOS;\n\n\t} else if (i == msg->attr_count-2)  {\n\t    if (msg->attr[i+1]->type != PJ_STUN_ATTR_FINGERPRINT) {\n\t\t/* Should not happen for message generated by us */\n\t\tpj_assert(PJ_FALSE);\n\t\treturn PJNATH_ESTUNMSGINTPOS;\n\t    } else {\n\t\tafingerprint = (pj_stun_fingerprint_attr*) msg->attr[i+1];\n\t    }\n\t}\n\n\t/* Calculate HMAC-SHA1 digest, add zero padding to input\n\t * if necessary to make the input 64 bytes aligned.\n\t */\n\tpj_hmac_sha1_init(&ctx, (const pj_uint8_t*)key->ptr, \n\t\t\t  (unsigned)key->slen);\n\tpj_hmac_sha1_update(&ctx, (const pj_uint8_t*)start, \n\t\t\t    (unsigned)(buf-start));\n#if PJ_STUN_OLD_STYLE_MI_FINGERPRINT\n\t// These are obsoleted in rfc3489bis-08\n\tif ((buf-start) & 0x3F) {\n\t    pj_uint8_t zeroes[64];\n\t    pj_bzero(zeroes, sizeof(zeroes));\n\t    pj_hmac_sha1_update(&ctx, zeroes, 64-((buf-start) & 0x3F));\n\t}\n#endif\t/* PJ_STUN_OLD_STYLE_MI_FINGERPRINT */\n\tpj_hmac_sha1_final(&ctx, amsgint->hmac);\n\n\t/* Put this attribute in the message */\n\tstatus = encode_msgint_attr(amsgint, buf, (unsigned)buf_size, \n\t\t\t            &msg->hdr, &printed);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tbuf += printed;\n\tbuf_size -= printed;\n    }\n\n    /* Calculate FINGERPRINT if present */\n    if (afingerprint != NULL) {\n\n#if !PJ_STUN_OLD_STYLE_MI_FINGERPRINT\n\t/* Update message length */\n\tPUTVAL16H(start, 2, \n\t\t (pj_uint16_t)(GETVAL16H(start, 2)+8));\n#endif\n\n\tafingerprint->value = pj_crc32_calc(start, buf-start);\n\tafingerprint->value ^= STUN_XOR_FINGERPRINT;\n\n\t/* Put this attribute in the message */\n\tstatus = encode_uint_attr(afingerprint, buf, (unsigned)buf_size, \n\t\t\t\t  &msg->hdr, &printed);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\tbuf += printed;\n\tbuf_size -= printed;\n    }\n\n    /* Update message length. */\n    msg->hdr.length = (pj_uint16_t) ((buf - start) - 20);\n\n    /* Return the length */\n    if (p_msg_len)\n\t*p_msg_len = (buf - start);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Find STUN attribute in the STUN message, starting from the specified\n * index.\n */\nPJ_DEF(pj_stun_attr_hdr*) pj_stun_msg_find_attr( const pj_stun_msg *msg,\n\t\t\t\t\t\t int attr_type,\n\t\t\t\t\t\t unsigned index)\n{\n    PJ_ASSERT_RETURN(msg, NULL);\n\n    for (; index < msg->attr_count; ++index) {\n\tif (msg->attr[index]->type == attr_type)\n\t    return (pj_stun_attr_hdr*) msg->attr[index];\n    }\n\n    return NULL;\n}\n\n\n/*\n * Clone a STUN attribute.\n */\nPJ_DEF(pj_stun_attr_hdr*) pj_stun_attr_clone( pj_pool_t *pool,\n\t\t\t\t\t      const pj_stun_attr_hdr *attr)\n{\n    const struct attr_desc *adesc;\n\n    /* Get the attribute descriptor */\n    adesc = find_attr_desc(attr->type);\n    if (adesc) {\n\treturn (pj_stun_attr_hdr*) (*adesc->clone_attr)(pool, attr);\n    } else {\n\t/* Clone generic attribute */\n\tconst pj_stun_binary_attr *bin_attr = (const pj_stun_binary_attr*)\n\t\t\t\t\t       attr;\n\tPJ_ASSERT_RETURN(bin_attr->magic == PJ_STUN_MAGIC, NULL);\n\tif (bin_attr->magic == PJ_STUN_MAGIC) {\n\t    return (pj_stun_attr_hdr*) clone_binary_attr(pool, attr);\n\t} else {\n\t    return NULL;\n\t}\n    }\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjnath/stun_msg_dump.c",
    "content": "/* $Id: stun_msg_dump.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjnath/stun_msg.h>\n#include <pjnath/errno.h>\n#include <pj/assert.h>\n#include <pj/os.h>\n#include <pj/string.h>\n\n#if PJ_LOG_MAX_LEVEL > 0\n\n\n#define APPLY()\t\tif (len < 1 || len >= (end-p)) \\\n\t\t\t    goto on_return; \\\n\t\t\tp += len\n\nstatic int print_binary(char *buffer, unsigned length,\n\t\t\tconst pj_uint8_t *data, unsigned data_len)\n{\n    unsigned i;\n\n    if (length < data_len * 2 + 8)\n\treturn -1;\n\n    pj_ansi_sprintf(buffer, \", data=\");\n    buffer += 7;\n\n    for (i=0; i<data_len; ++i) {\n\tpj_ansi_sprintf(buffer, \"%02x\", (*data) & 0xFF);\n\tbuffer += 2;\n\tdata++;\n    }\n\n    pj_ansi_sprintf(buffer, \"\\n\");\n    buffer++;\n\n    return data_len * 2 + 8;\n}\n\nstatic int print_attr(char *buffer, unsigned length,\n\t\t      const pj_stun_attr_hdr *ahdr)\n{\n    char *p = buffer, *end = buffer + length;\n    const char *attr_name = pj_stun_get_attr_name(ahdr->type);\n    char attr_buf[32];\n    int len;\n\n    if (*attr_name == '?') {\n\tpj_ansi_snprintf(attr_buf, sizeof(attr_buf), \"Attr 0x%x\", \n\t\t\t ahdr->type);\n\tattr_name = attr_buf;\n    }\n\n    len = pj_ansi_snprintf(p, end-p,\n\t\t\t   \"  %s: length=%d\",\n\t\t\t   attr_name,\n\t\t\t   (int)ahdr->length);\n    APPLY();\n\n\n    switch (ahdr->type) {\n    case PJ_STUN_ATTR_MAPPED_ADDR:\n    case PJ_STUN_ATTR_RESPONSE_ADDR:\n    case PJ_STUN_ATTR_SOURCE_ADDR:\n    case PJ_STUN_ATTR_CHANGED_ADDR:\n    case PJ_STUN_ATTR_REFLECTED_FROM:\n    case PJ_STUN_ATTR_XOR_PEER_ADDR:\n    case PJ_STUN_ATTR_XOR_RELAYED_ADDR:\n    case PJ_STUN_ATTR_XOR_MAPPED_ADDR:\n    case PJ_STUN_ATTR_XOR_REFLECTED_FROM:\n    case PJ_STUN_ATTR_ALTERNATE_SERVER:\n\t{\n\t    const pj_stun_sockaddr_attr *attr;\n\n\t    attr = (const pj_stun_sockaddr_attr*)ahdr;\n\n\t    if (attr->sockaddr.addr.sa_family == pj_AF_INET()) {\n\t\tlen = pj_ansi_snprintf(p, end-p,\n\t\t\t\t       \", IPv4 addr=%s:%d\\n\",\n\t\t\t\t       pj_inet_ntoa(attr->sockaddr.ipv4.sin_addr),\n\t\t\t\t       pj_ntohs(attr->sockaddr.ipv4.sin_port));\n\n\t    } else if (attr->sockaddr.addr.sa_family == pj_AF_INET6()) {\n\t\tlen = pj_ansi_snprintf(p, end-p,\n\t\t\t\t       \", IPv6 addr present\\n\");\n\t    } else {\n\t\tlen = pj_ansi_snprintf(p, end-p,\n\t\t\t\t       \", INVALID ADDRESS FAMILY!\\n\");\n\t    }\n\t    APPLY();\n\t}\n\tbreak;\n\n    case PJ_STUN_ATTR_CHANNEL_NUMBER:\n\t{\n\t    const pj_stun_uint_attr *attr;\n\n\t    attr = (const pj_stun_uint_attr*)ahdr;\n\t    len = pj_ansi_snprintf(p, end-p,\n\t\t\t\t   \", chnum=%u (0x%x)\\n\",\n\t\t\t\t   (int)PJ_STUN_GET_CH_NB(attr->value),\n\t\t\t\t   (int)PJ_STUN_GET_CH_NB(attr->value));\n\t    APPLY();\n\t}\n\tbreak;\n\n    case PJ_STUN_ATTR_CHANGE_REQUEST:\n    case PJ_STUN_ATTR_LIFETIME:\n    case PJ_STUN_ATTR_BANDWIDTH:\n    case PJ_STUN_ATTR_REQ_ADDR_TYPE:\n    case PJ_STUN_ATTR_EVEN_PORT:\n    case PJ_STUN_ATTR_REQ_TRANSPORT:\n    case PJ_STUN_ATTR_TIMER_VAL:\n    case PJ_STUN_ATTR_PRIORITY:\n    case PJ_STUN_ATTR_FINGERPRINT:\n    case PJ_STUN_ATTR_REFRESH_INTERVAL:\n    case PJ_STUN_ATTR_ICMP:\n\t{\n\t    const pj_stun_uint_attr *attr;\n\n\t    attr = (const pj_stun_uint_attr*)ahdr;\n\t    len = pj_ansi_snprintf(p, end-p,\n\t\t\t\t   \", value=%u (0x%x)\\n\",\n\t\t\t\t   (pj_uint32_t)attr->value,\n\t\t\t\t   (pj_uint32_t)attr->value);\n\t    APPLY();\n\t}\n\tbreak;\n\n    case PJ_STUN_ATTR_USERNAME:\n    case PJ_STUN_ATTR_PASSWORD:\n    case PJ_STUN_ATTR_REALM:\n    case PJ_STUN_ATTR_NONCE:\n    case PJ_STUN_ATTR_SOFTWARE:\n\t{\n\t    const pj_stun_string_attr *attr;\n\n\t    attr = (pj_stun_string_attr*)ahdr;\n\t    len = pj_ansi_snprintf(p, end-p,\n\t\t\t\t   \", value=\\\"%.*s\\\"\\n\",\n\t\t\t\t   (int)attr->value.slen,\n\t\t\t\t   attr->value.ptr);\n\t    APPLY();\n\t}\n\tbreak;\n\n    case PJ_STUN_ATTR_ERROR_CODE:\n\t{\n\t    const pj_stun_errcode_attr *attr;\n\n\t    attr = (const pj_stun_errcode_attr*) ahdr;\n\t    len = pj_ansi_snprintf(p, end-p,\n\t\t\t\t   \", err_code=%d, reason=\\\"%.*s\\\"\\n\",\n\t\t\t\t   attr->err_code,\n\t\t\t\t   (int)attr->reason.slen,\n\t\t\t\t   attr->reason.ptr);\n\t    APPLY();\n\t}\n\tbreak;\n\n    case PJ_STUN_ATTR_UNKNOWN_ATTRIBUTES:\n\t{\n\t    const pj_stun_unknown_attr *attr;\n\t    unsigned j;\n\n\t    attr = (const pj_stun_unknown_attr*) ahdr;\n\n\t    len = pj_ansi_snprintf(p, end-p,\n\t\t\t\t   \", unknown list:\");\n\t    APPLY();\n\n\t    for (j=0; j<attr->attr_count; ++j) {\n\t\tlen = pj_ansi_snprintf(p, end-p,\n\t\t\t\t       \" %d\",\n\t\t\t\t       (int)attr->attrs[j]);\n\t\tAPPLY();\n\t    }\n\t}\n\tbreak;\n\n    case PJ_STUN_ATTR_MESSAGE_INTEGRITY:\n\t{\n\t    const pj_stun_msgint_attr *attr;\n\n\t    attr = (const pj_stun_msgint_attr*) ahdr;\n\t    len = print_binary(p, (unsigned)(end-p), attr->hmac, 20);\n\t    APPLY();\n\t}\n\tbreak;\n\n    case PJ_STUN_ATTR_DATA:\n\t{\n\t    const pj_stun_binary_attr *attr;\n\n\t    attr = (const pj_stun_binary_attr*) ahdr;\n\t    len = print_binary(p, (unsigned)(end-p), attr->data, attr->length);\n\t    APPLY();\n\t}\n\tbreak;\n    case PJ_STUN_ATTR_ICE_CONTROLLED:\n    case PJ_STUN_ATTR_ICE_CONTROLLING:\n    case PJ_STUN_ATTR_RESERVATION_TOKEN:\n\t{\n\t    const pj_stun_uint64_attr *attr;\n\t    pj_uint8_t data[8];\n\t    int i;\n\n\t    attr = (const pj_stun_uint64_attr*) ahdr;\n\n\t    for (i=0; i<8; ++i)\n\t\tdata[i] = ((const pj_uint8_t*)&attr->value)[7-i];\n\n\t    len = print_binary(p, (unsigned)(end-p), data, 8);\n\t    APPLY();\n\t}\n\tbreak;\n    case PJ_STUN_ATTR_USE_CANDIDATE:\n    case PJ_STUN_ATTR_DONT_FRAGMENT:\n    default:\n\tlen = pj_ansi_snprintf(p, end-p, \"\\n\");\n\tAPPLY();\n\tbreak;\n    }\n\n    return (int)(p-buffer);\n\non_return:\n    return len;\n}\n\n\n/*\n * Dump STUN message to a printable string output.\n */\nPJ_DEF(char*) pj_stun_msg_dump(const pj_stun_msg *msg,\n\t\t\t       char *buffer,\n\t\t\t       unsigned length,\n\t\t\t       unsigned *printed_len)\n{\n    char *p, *end;\n    int len;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(msg && buffer && length, NULL);\n\n    PJ_CHECK_STACK();\n    \n    p = buffer;\n    end = buffer + length;\n\n    len = pj_ansi_snprintf(p, end-p, \"STUN %s %s\\n\",\n\t\t\t   pj_stun_get_method_name(msg->hdr.type),\n\t\t\t   pj_stun_get_class_name(msg->hdr.type));\n    APPLY();\n\n    len = pj_ansi_snprintf(p, end-p, \n\t\t\t   \" Hdr: length=%d, magic=%08x, tsx_id=%08x%08x%08x\\n\"\n\t\t\t   \" Attributes:\\n\",\n\t\t\t   msg->hdr.length,\n\t\t\t   msg->hdr.magic,\n\t\t\t   *(pj_uint32_t*)&msg->hdr.tsx_id[0],\n\t\t\t   *(pj_uint32_t*)&msg->hdr.tsx_id[4],\n\t\t\t   *(pj_uint32_t*)&msg->hdr.tsx_id[8]);\n    APPLY();\n\n    for (i=0; i<msg->attr_count; ++i) {\n\tlen = print_attr(p, (unsigned)(end-p), msg->attr[i]);\n\tAPPLY();\n    }\n\non_return:\n    *p = '\\0';\n    if (printed_len)\n\t*printed_len = (unsigned)(p-buffer);\n    return buffer;\n\n#undef APPLY\n}\n\n\n#endif\t/* PJ_LOG_MAX_LEVEL > 0 */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjnath/stun_session.c",
    "content": "/* $Id: stun_session.c 4360 2013-02-21 11:26:35Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjnath/stun_session.h>\n#include <pjnath/errno.h>\n#include <pjlib.h>\n\nstruct pj_stun_session\n{\n    pj_stun_config\t*cfg;\n    pj_pool_t\t\t*pool;\n    pj_grp_lock_t\t*grp_lock;\n    pj_stun_session_cb\t cb;\n    void\t\t*user_data;\n    pj_bool_t\t\t is_destroying;\n\n    pj_bool_t\t\t use_fingerprint;\n\n    pj_pool_t\t\t*rx_pool;\n\n#if PJ_LOG_MAX_LEVEL >= 5\n    char\t\t dump_buf[1000];\n#endif\n    unsigned\t\t log_flag;\n\n    pj_stun_auth_type\t auth_type;\n    pj_stun_auth_cred\t cred;\n    int\t\t\t auth_retry;\n    pj_str_t\t\t next_nonce;\n    pj_str_t\t\t server_realm;\n\n    pj_str_t\t\t srv_name;\n\n    pj_stun_tx_data\t pending_request_list;\n    pj_stun_tx_data\t cached_response_list;\n};\n\n#define SNAME(s_)\t\t    ((s_)->pool->obj_name)\n#define THIS_FILE\t\t    \"stun_session.c\"\n\n#if 1\n#   define TRACE_(expr)\t\t    PJ_LOG(5,expr)\n#else\n#   define TRACE_(expr)\n#endif\n\n#define LOG_ERR_(sess,title,rc) PJ_PERROR(3,(sess->pool->obj_name,rc,title))\n\n#define TDATA_POOL_SIZE\t\t    PJNATH_POOL_LEN_STUN_TDATA\n#define TDATA_POOL_INC\t\t    PJNATH_POOL_INC_STUN_TDATA\n\n\nstatic void stun_tsx_on_complete(pj_stun_client_tsx *tsx,\n\t\t\t\t pj_status_t status, \n\t\t\t\t const pj_stun_msg *response,\n\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t unsigned src_addr_len);\nstatic pj_status_t stun_tsx_on_send_msg(pj_stun_client_tsx *tsx,\n\t\t\t\t\tconst void *stun_pkt,\n\t\t\t\t\tpj_size_t pkt_size);\nstatic void stun_tsx_on_destroy(pj_stun_client_tsx *tsx);\nstatic void stun_sess_on_destroy(void *comp);\n\nstatic pj_stun_tsx_cb tsx_cb = \n{\n    &stun_tsx_on_complete,\n    &stun_tsx_on_send_msg,\n    &stun_tsx_on_destroy\n};\n\n\nstatic pj_status_t tsx_add(pj_stun_session *sess,\n\t\t\t   pj_stun_tx_data *tdata)\n{\n    pj_list_push_front(&sess->pending_request_list, tdata);\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t tsx_erase(pj_stun_session *sess,\n\t\t\t     pj_stun_tx_data *tdata)\n{\n    PJ_UNUSED_ARG(sess);\n    pj_list_erase(tdata);\n    return PJ_SUCCESS;\n}\n\nstatic pj_stun_tx_data* tsx_lookup(pj_stun_session *sess,\n\t\t\t\t   const pj_stun_msg *msg)\n{\n    pj_stun_tx_data *tdata;\n\n    tdata = sess->pending_request_list.next;\n    while (tdata != &sess->pending_request_list) {\n\tpj_assert(sizeof(tdata->msg_key)==sizeof(msg->hdr.tsx_id));\n\tif (tdata->msg_magic == msg->hdr.magic &&\n\t    pj_memcmp(tdata->msg_key, msg->hdr.tsx_id, \n\t\t      sizeof(msg->hdr.tsx_id))==0)\n\t{\n\t    return tdata;\n\t}\n\ttdata = tdata->next;\n    }\n\n    return NULL;\n}\n\nstatic pj_status_t create_tdata(pj_stun_session *sess,\n\t\t\t        pj_stun_tx_data **p_tdata)\n{\n    pj_pool_t *pool;\n    pj_stun_tx_data *tdata;\n\n    /* Create pool and initialize basic tdata attributes */\n    pool = pj_pool_create(sess->cfg->pf, \"tdata%p\", \n\t\t\t  TDATA_POOL_SIZE, TDATA_POOL_INC, NULL);\n    PJ_ASSERT_RETURN(pool, PJ_ENOMEM);\n\n    tdata = PJ_POOL_ZALLOC_T(pool, pj_stun_tx_data);\n    tdata->pool = pool;\n    tdata->sess = sess;\n\n    pj_list_init(tdata);\n\n    *p_tdata = tdata;\n\n    return PJ_SUCCESS;\n}\n\nstatic void stun_tsx_on_destroy(pj_stun_client_tsx *tsx)\n{\n    pj_stun_tx_data *tdata;\n\n    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx);\n    pj_stun_client_tsx_stop(tsx);\n    if (tdata) {\n        pj_stun_session *sess = tdata->sess;\n        \n        pj_grp_lock_acquire(sess->grp_lock);\n\ttsx_erase(sess, tdata);\n\tpj_pool_release(tdata->pool);\n\tpj_grp_lock_release(sess->grp_lock);\n    }\n\n    pj_stun_client_tsx_destroy(tsx);\n\n    TRACE_((THIS_FILE, \"STUN transaction %p destroyed\", tsx));\n}\n\nstatic void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force)\n{\n    TRACE_((THIS_FILE, \"tdata %p destroy request, force=%d, tsx=%p\", tdata,\n\t    force, tdata->client_tsx));\n\n    if (tdata->res_timer.id != PJ_FALSE) {\n\tpj_timer_heap_cancel_if_active(tdata->sess->cfg->timer_heap,\n\t                               &tdata->res_timer, PJ_FALSE);\n\tpj_list_erase(tdata);\n    }\n\n    if (force) {\n\tpj_list_erase(tdata);\n\tif (tdata->client_tsx) {\n\t    pj_stun_client_tsx_stop(tdata->client_tsx);\n\t    pj_stun_client_tsx_set_data(tdata->client_tsx, NULL);\n\t}\n\tpj_pool_release(tdata->pool);\n\n    } else {\n\tif (tdata->client_tsx) {\n\t    /* \"Probably\" this is to absorb retransmission */\n\t    pj_time_val delay = {0, 300};\n\t    pj_stun_client_tsx_schedule_destroy(tdata->client_tsx, &delay);\n\n\t} else {\n\t    pj_pool_release(tdata->pool);\n\t}\n    }\n}\n\n/*\n * Destroy the transmit data.\n */\nPJ_DEF(void) pj_stun_msg_destroy_tdata( pj_stun_session *sess,\n\t\t\t\t\tpj_stun_tx_data *tdata)\n{\n    PJ_UNUSED_ARG(sess);\n    destroy_tdata(tdata, PJ_FALSE);\n}\n\n\n/* Timer callback to be called when it's time to destroy response cache */\nstatic void on_cache_timeout(pj_timer_heap_t *timer_heap,\n\t\t\t     struct pj_timer_entry *entry)\n{\n    pj_stun_tx_data *tdata;\n    pj_stun_session *sess;\n\n    PJ_UNUSED_ARG(timer_heap);\n\n    entry->id = PJ_FALSE;\n    tdata = (pj_stun_tx_data*) entry->user_data;\n    sess = tdata->sess;\n\n    pj_grp_lock_acquire(sess->grp_lock);\n    if (sess->is_destroying) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn;\n    }\n\n    PJ_LOG(5,(SNAME(tdata->sess), \"Response cache deleted\"));\n\n    pj_list_erase(tdata);\n    pj_grp_lock_release(sess->grp_lock);\n\n    destroy_tdata(tdata, PJ_FALSE);\n}\n\nstatic pj_status_t apply_msg_options(pj_stun_session *sess,\n\t\t\t\t     pj_pool_t *pool,\n\t\t\t\t     const pj_stun_req_cred_info *auth_info,\n\t\t\t\t     pj_stun_msg *msg)\n{\n    pj_status_t status = 0;\n    pj_str_t realm, username, nonce, auth_key;\n\n    /* If the agent is sending a request, it SHOULD add a SOFTWARE attribute\n     * to the request. The server SHOULD include a SOFTWARE attribute in all \n     * responses.\n     *\n     * If magic value is not PJ_STUN_MAGIC, only apply the attribute for\n     * responses.\n     */\n    if (sess->srv_name.slen && \n\tpj_stun_msg_find_attr(msg, PJ_STUN_ATTR_SOFTWARE, 0)==NULL &&\n\t(PJ_STUN_IS_RESPONSE(msg->hdr.type) ||\n\t (PJ_STUN_IS_REQUEST(msg->hdr.type) && msg->hdr.magic==PJ_STUN_MAGIC))) \n    {\n\tpj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SOFTWARE,\n\t\t\t\t    &sess->srv_name);\n    }\n\n    if (pj_stun_auth_valid_for_msg(msg) && auth_info) {\n\trealm = auth_info->realm;\n\tusername = auth_info->username;\n\tnonce = auth_info->nonce;\n\tauth_key = auth_info->auth_key;\n    } else {\n\trealm.slen = username.slen = nonce.slen = auth_key.slen = 0;\n    }\n\n    /* Create and add USERNAME attribute if needed */\n    if (username.slen && PJ_STUN_IS_REQUEST(msg->hdr.type)) {\n\tstatus = pj_stun_msg_add_string_attr(pool, msg,\n\t\t\t\t\t     PJ_STUN_ATTR_USERNAME,\n\t\t\t\t\t     &username);\n\tPJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    }\n\n    /* Add REALM only when long term credential is used */\n    if (realm.slen &&  PJ_STUN_IS_REQUEST(msg->hdr.type)) {\n\tstatus = pj_stun_msg_add_string_attr(pool, msg,\n\t\t\t\t\t    PJ_STUN_ATTR_REALM,\n\t\t\t\t\t    &realm);\n\tPJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    }\n\n    /* Add NONCE when desired */\n    if (nonce.slen && \n\t(PJ_STUN_IS_REQUEST(msg->hdr.type) ||\n\t PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type))) \n    {\n\tstatus = pj_stun_msg_add_string_attr(pool, msg,\n\t\t\t\t\t    PJ_STUN_ATTR_NONCE,\n\t\t\t\t\t    &nonce);\n    }\n\n    /* Add MESSAGE-INTEGRITY attribute */\n    if (username.slen && auth_key.slen) {\n\tstatus = pj_stun_msg_add_msgint_attr(pool, msg);\n\tPJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    }\n\n\n    /* Add FINGERPRINT attribute if necessary */\n    if (sess->use_fingerprint) {\n\tstatus = pj_stun_msg_add_uint_attr(pool, msg, \n\t\t\t\t\t  PJ_STUN_ATTR_FINGERPRINT, 0);\n\tPJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t handle_auth_challenge(pj_stun_session *sess,\n\t\t\t\t\t const pj_stun_tx_data *request,\n\t\t\t\t\t const pj_stun_msg *response,\n\t\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t\t unsigned src_addr_len,\n\t\t\t\t\t pj_bool_t *notify_user)\n{\n    const pj_stun_errcode_attr *ea;\n\n    *notify_user = PJ_TRUE;\n\n    if (response==NULL)\n\treturn PJ_SUCCESS;\n\n    if (sess->auth_type != PJ_STUN_AUTH_LONG_TERM)\n\treturn PJ_SUCCESS;\n    \n    if (!PJ_STUN_IS_ERROR_RESPONSE(response->hdr.type)) {\n\tsess->auth_retry = 0;\n\treturn PJ_SUCCESS;\n    }\n\n    ea = (const pj_stun_errcode_attr*)\n\t pj_stun_msg_find_attr(response, PJ_STUN_ATTR_ERROR_CODE, 0);\n    if (!ea) {\n\tPJ_LOG(4,(SNAME(sess), \"Invalid error response: no ERROR-CODE\"\n\t\t  \" attribute\"));\n\t*notify_user = PJ_FALSE;\n\treturn PJNATH_EINSTUNMSG;\n    }\n\n    if (ea->err_code == PJ_STUN_SC_UNAUTHORIZED || \n\tea->err_code == PJ_STUN_SC_STALE_NONCE)\n    {\n\tconst pj_stun_nonce_attr *anonce;\n\tconst pj_stun_realm_attr *arealm;\n\tpj_stun_tx_data *tdata;\n\tunsigned i;\n\tpj_status_t status;\n\n\tanonce = (const pj_stun_nonce_attr*)\n\t\t pj_stun_msg_find_attr(response, PJ_STUN_ATTR_NONCE, 0);\n\tif (!anonce) {\n\t    PJ_LOG(4,(SNAME(sess), \"Invalid response: missing NONCE\"));\n\t    *notify_user = PJ_FALSE;\n\t    return PJNATH_EINSTUNMSG;\n\t}\n\n\t/* Bail out if we've supplied the correct nonce */\n\tif (pj_strcmp(&anonce->value, &sess->next_nonce)==0) {\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* Bail out if we've tried too many */\n\tif (++sess->auth_retry > 3) {\n\t    PJ_LOG(4,(SNAME(sess), \"Error: authentication failed (too \"\n\t\t      \"many retries)\"));\n\t    return PJ_STATUS_FROM_STUN_CODE(401);\n\t}\n\n\t/* Save next_nonce */\n\tpj_strdup(sess->pool, &sess->next_nonce, &anonce->value);\n\n\t/* Copy the realm from the response */\n\tarealm = (pj_stun_realm_attr*)\n\t\t pj_stun_msg_find_attr(response, PJ_STUN_ATTR_REALM, 0);\n\tif (arealm) {\n\t    pj_strdup(sess->pool, &sess->server_realm, &arealm->value);\n\t    while (sess->server_realm.slen &&\n\t\t    !sess->server_realm.ptr[sess->server_realm.slen-1])\n\t    {\n\t\t--sess->server_realm.slen;\n\t    }\n\t}\n\n\t/* Create new request */\n\tstatus = pj_stun_session_create_req(sess, request->msg->hdr.type,\n\t\t\t\t\t    request->msg->hdr.magic,\n\t\t\t\t\t    NULL, &tdata);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Duplicate all the attributes in the old request, except\n\t * USERNAME, REALM, M-I, and NONCE, which will be filled in\n\t * later.\n\t */\n\tfor (i=0; i<request->msg->attr_count; ++i) {\n\t    const pj_stun_attr_hdr *asrc = request->msg->attr[i];\n\n\t    if (asrc->type == PJ_STUN_ATTR_USERNAME ||\n\t\tasrc->type == PJ_STUN_ATTR_REALM ||\n\t\tasrc->type == PJ_STUN_ATTR_MESSAGE_INTEGRITY ||\n\t\tasrc->type == PJ_STUN_ATTR_NONCE)\n\t    {\n\t\tcontinue;\n\t    }\n\n\t    tdata->msg->attr[tdata->msg->attr_count++] = \n\t\tpj_stun_attr_clone(tdata->pool, asrc);\n\t}\n\n\t/* Will retry the request with authentication, no need to\n\t * notify user.\n\t */\n\t*notify_user = PJ_FALSE;\n\n\tPJ_LOG(4,(SNAME(sess), \"Retrying request with new authentication\"));\n\n\t/* Retry the request */\n\tstatus = pj_stun_session_send_msg(sess, request->token, PJ_TRUE, \n\t\t\t\t\t  request->retransmit, src_addr, \n\t\t\t\t\t  src_addr_len, tdata);\n\n    } else {\n\tsess->auth_retry = 0;\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic void stun_tsx_on_complete(pj_stun_client_tsx *tsx,\n\t\t\t\t pj_status_t status, \n\t\t\t\t const pj_stun_msg *response,\n\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t unsigned src_addr_len)\n{\n    pj_stun_session *sess;\n    pj_bool_t notify_user = PJ_TRUE;\n    pj_stun_tx_data *tdata;\n\n    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx);\n    sess = tdata->sess;\n\n    /* Lock the session and prevent user from destroying us in the callback */\n    pj_grp_lock_acquire(sess->grp_lock);\n    if (sess->is_destroying) {\n\tpj_stun_msg_destroy_tdata(sess, tdata);\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn;\n    }\n\n    /* Handle authentication challenge */\n    handle_auth_challenge(sess, tdata, response, src_addr,\n\t\t          src_addr_len, &notify_user);\n\n    if (notify_user && sess->cb.on_request_complete) {\n\t(*sess->cb.on_request_complete)(sess, status, tdata->token, tdata, \n\t\t\t\t\tresponse, src_addr, src_addr_len);\n    }\n\n    /* Destroy the transmit data. This will remove the transaction\n     * from the pending list too. \n     */\n    if (status == PJNATH_ESTUNTIMEDOUT)\n\tdestroy_tdata(tdata, PJ_TRUE);\n    else\n\tdestroy_tdata(tdata, PJ_FALSE);\n    tdata = NULL;\n\n    pj_grp_lock_release(sess->grp_lock);\n}\n\nstatic pj_status_t stun_tsx_on_send_msg(pj_stun_client_tsx *tsx,\n\t\t\t\t\tconst void *stun_pkt,\n\t\t\t\t\tpj_size_t pkt_size)\n{\n    pj_stun_tx_data *tdata;\n    pj_stun_session *sess;\n    pj_status_t status;\n\n    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx);\n    sess = tdata->sess;\n\n    /* Lock the session and prevent user from destroying us in the callback */\n    pj_grp_lock_acquire(sess->grp_lock);\n    \n    if (sess->is_destroying) {\n\t/* Stray timer */\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    status = sess->cb.on_send_msg(tdata->sess, tdata->token, stun_pkt, \n\t\t\t\t  pkt_size, tdata->dst_addr, \n\t\t\t\t  tdata->addr_len);\n    if (pj_grp_lock_release(sess->grp_lock))\n\treturn PJ_EGONE;\n\n    return status;\n}\n\n/* **************************************************************************/\n\nPJ_DEF(pj_status_t) pj_stun_session_create( pj_stun_config *cfg,\n\t\t\t\t\t    const char *name,\n\t\t\t\t\t    const pj_stun_session_cb *cb,\n\t\t\t\t\t    pj_bool_t fingerprint,\n\t\t\t\t\t    pj_grp_lock_t *grp_lock,\n\t\t\t\t\t    pj_stun_session **p_sess)\n{\n    pj_pool_t\t*pool;\n    pj_stun_session *sess;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(cfg && cb && p_sess, PJ_EINVAL);\n\n    if (name==NULL)\n\tname = \"stuse%p\";\n\n    pool = pj_pool_create(cfg->pf, name, PJNATH_POOL_LEN_STUN_SESS, \n\t\t\t  PJNATH_POOL_INC_STUN_SESS, NULL);\n    PJ_ASSERT_RETURN(pool, PJ_ENOMEM);\n\n    sess = PJ_POOL_ZALLOC_T(pool, pj_stun_session);\n    sess->cfg = cfg;\n    sess->pool = pool;\n    pj_memcpy(&sess->cb, cb, sizeof(*cb));\n    sess->use_fingerprint = fingerprint;\n    sess->log_flag = 0xFFFF;\n\n    if (grp_lock) {\n\tsess->grp_lock = grp_lock;\n    } else {\n\tstatus = pj_grp_lock_create(pool, NULL, &sess->grp_lock);\n\tif (status != PJ_SUCCESS) {\n\t    pj_pool_release(pool);\n\t    return status;\n\t}\n    }\n\n    pj_grp_lock_add_ref(sess->grp_lock);\n    pj_grp_lock_add_handler(sess->grp_lock, pool, sess,\n                            &stun_sess_on_destroy);\n\n    pj_stun_session_set_software_name(sess, &cfg->software_name);\n\n    sess->rx_pool = pj_pool_create(sess->cfg->pf, name,\n\t\t\t\t   PJNATH_POOL_LEN_STUN_TDATA,\n\t\t\t\t   PJNATH_POOL_INC_STUN_TDATA, NULL);\n\n    pj_list_init(&sess->pending_request_list);\n    pj_list_init(&sess->cached_response_list);\n\n    *p_sess = sess;\n\n    return PJ_SUCCESS;\n}\n\nstatic void stun_sess_on_destroy(void *comp)\n{\n    pj_stun_session *sess = (pj_stun_session*)comp;\n\n    while (!pj_list_empty(&sess->pending_request_list)) {\n\tpj_stun_tx_data *tdata = sess->pending_request_list.next;\n\tdestroy_tdata(tdata, PJ_TRUE);\n    }\n\n    while (!pj_list_empty(&sess->cached_response_list)) {\n\tpj_stun_tx_data *tdata = sess->cached_response_list.next;\n\tdestroy_tdata(tdata, PJ_TRUE);\n    }\n\n    if (sess->rx_pool) {\n\tpj_pool_release(sess->rx_pool);\n\tsess->rx_pool = NULL;\n    }\n\n    pj_pool_release(sess->pool);\n\n    TRACE_((THIS_FILE, \"STUN session %p destroyed\", sess));\n}\n\nPJ_DEF(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess)\n{\n    pj_stun_tx_data *tdata;\n\n    PJ_ASSERT_RETURN(sess, PJ_EINVAL);\n\n    TRACE_((SNAME(sess), \"STUN session %p destroy request, ref_cnt=%d\",\n\t     sess, pj_grp_lock_get_ref(sess->grp_lock)));\n\n    pj_grp_lock_acquire(sess->grp_lock);\n\n    if (sess->is_destroying) {\n\t/* Prevent from decrementing the ref counter more than once */\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    sess->is_destroying = PJ_TRUE;\n\n    /* We need to stop transactions and cached response because they are\n     * holding the group lock's reference counter while retransmitting.\n     */\n    tdata = sess->pending_request_list.next;\n    while (tdata != &sess->pending_request_list) {\n\tif (tdata->client_tsx)\n\t    pj_stun_client_tsx_stop(tdata->client_tsx);\n\ttdata = tdata->next;\n    }\n\n    tdata = sess->cached_response_list.next;\n    while (tdata != &sess->cached_response_list) {\n\tpj_timer_heap_cancel_if_active(tdata->sess->cfg->timer_heap,\n\t\t\t\t       &tdata->res_timer, PJ_FALSE);\n\ttdata = tdata->next;\n    }\n\n    pj_grp_lock_dec_ref(sess->grp_lock);\n    pj_grp_lock_release(sess->grp_lock);\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_stun_session_set_user_data( pj_stun_session *sess,\n\t\t\t\t\t\t   void *user_data)\n{\n    PJ_ASSERT_RETURN(sess, PJ_EINVAL);\n    pj_grp_lock_acquire(sess->grp_lock);\n    sess->user_data = user_data;\n    pj_grp_lock_release(sess->grp_lock);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void*) pj_stun_session_get_user_data(pj_stun_session *sess)\n{\n    PJ_ASSERT_RETURN(sess, NULL);\n    return sess->user_data;\n}\n\nPJ_DEF(pj_grp_lock_t *) pj_stun_session_get_grp_lock(pj_stun_session *sess)\n{\n    PJ_ASSERT_RETURN(sess, NULL);\n    return sess->grp_lock;\n}\n\nPJ_DEF(pj_status_t) pj_stun_session_set_software_name(pj_stun_session *sess,\n\t\t\t\t\t\t      const pj_str_t *sw)\n{\n    PJ_ASSERT_RETURN(sess, PJ_EINVAL);\n    pj_grp_lock_acquire(sess->grp_lock);\n    if (sw && sw->slen)\n\tpj_strdup(sess->pool, &sess->srv_name, sw);\n    else\n\tsess->srv_name.slen = 0;\n    pj_grp_lock_release(sess->grp_lock);\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_stun_session_set_credential(pj_stun_session *sess,\n\t\t\t\t\t\t pj_stun_auth_type auth_type,\n\t\t\t\t\t\t const pj_stun_auth_cred *cred)\n{\n    PJ_ASSERT_RETURN(sess, PJ_EINVAL);\n\n    pj_grp_lock_acquire(sess->grp_lock);\n    sess->auth_type = auth_type;\n    if (cred) {\n\tpj_stun_auth_cred_dup(sess->pool, &sess->cred, cred);\n    } else {\n\tsess->auth_type = PJ_STUN_AUTH_NONE;\n\tpj_bzero(&sess->cred, sizeof(sess->cred));\n    }\n    pj_grp_lock_release(sess->grp_lock);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void) pj_stun_session_set_log( pj_stun_session *sess,\n\t\t\t\t      unsigned flags)\n{\n    PJ_ASSERT_ON_FAIL(sess, return);\n    sess->log_flag = flags;\n}\n\nPJ_DEF(pj_bool_t) pj_stun_session_use_fingerprint(pj_stun_session *sess,\n\t\t\t\t\t\t  pj_bool_t use)\n{\n    pj_bool_t old_use;\n\n    PJ_ASSERT_RETURN(sess, PJ_FALSE);\n\n    old_use = sess->use_fingerprint;\n    sess->use_fingerprint = use;\n    return old_use;\n}\n\nstatic pj_status_t get_auth(pj_stun_session *sess,\n\t\t\t    pj_stun_tx_data *tdata)\n{\n    if (sess->cred.type == PJ_STUN_AUTH_CRED_STATIC) {\n\t//tdata->auth_info.realm = sess->cred.data.static_cred.realm;\n\ttdata->auth_info.realm = sess->server_realm;\n\ttdata->auth_info.username = sess->cred.data.static_cred.username;\n\ttdata->auth_info.nonce = sess->cred.data.static_cred.nonce;\n\n\tpj_stun_create_key(tdata->pool, &tdata->auth_info.auth_key, \n\t\t\t   &tdata->auth_info.realm,\n\t\t\t   &tdata->auth_info.username,\n\t\t\t   sess->cred.data.static_cred.data_type,\n\t\t\t   &sess->cred.data.static_cred.data);\n\n    } else if (sess->cred.type == PJ_STUN_AUTH_CRED_DYNAMIC) {\n\tpj_str_t password;\n\tvoid *user_data = sess->cred.data.dyn_cred.user_data;\n\tpj_stun_passwd_type data_type = PJ_STUN_PASSWD_PLAIN;\n\tpj_status_t rc;\n\n\trc = (*sess->cred.data.dyn_cred.get_cred)(tdata->msg, user_data, \n\t\t\t\t\t\t  tdata->pool,\n\t\t\t\t\t\t  &tdata->auth_info.realm, \n\t\t\t\t\t\t  &tdata->auth_info.username,\n\t\t\t\t\t\t  &tdata->auth_info.nonce, \n\t\t\t\t\t\t  &data_type, &password);\n\tif (rc != PJ_SUCCESS)\n\t    return rc;\n\n\tpj_stun_create_key(tdata->pool, &tdata->auth_info.auth_key, \n\t\t\t   &tdata->auth_info.realm, &tdata->auth_info.username,\n\t\t\t   data_type, &password);\n\n    } else {\n\tpj_assert(!\"Unknown credential type\");\n\treturn PJ_EBUG;\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pj_stun_session_create_req(pj_stun_session *sess,\n\t\t\t\t\t       int method,\n\t\t\t\t\t       pj_uint32_t magic,\n\t\t\t\t\t       const pj_uint8_t tsx_id[12],\n\t\t\t\t\t       pj_stun_tx_data **p_tdata)\n{\n    pj_stun_tx_data *tdata = NULL;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sess && p_tdata, PJ_EINVAL);\n\n    pj_grp_lock_acquire(sess->grp_lock);\n    if (sess->is_destroying) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    status = create_tdata(sess, &tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Create STUN message */\n    status = pj_stun_msg_create(tdata->pool, method,  magic, \n\t\t\t\ttsx_id, &tdata->msg);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* copy the request's transaction ID as the transaction key. */\n    pj_assert(sizeof(tdata->msg_key)==sizeof(tdata->msg->hdr.tsx_id));\n    tdata->msg_magic = tdata->msg->hdr.magic;\n    pj_memcpy(tdata->msg_key, tdata->msg->hdr.tsx_id,\n\t      sizeof(tdata->msg->hdr.tsx_id));\n\n    \n    /* Get authentication information for the request */\n    if (sess->auth_type == PJ_STUN_AUTH_NONE) {\n\t/* No authentication */\n\n    } else if (sess->auth_type == PJ_STUN_AUTH_SHORT_TERM) {\n\t/* MUST put authentication in request */\n\tstatus = get_auth(sess, tdata);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n    } else if (sess->auth_type == PJ_STUN_AUTH_LONG_TERM) {\n\t/* Only put authentication information if we've received\n\t * response from server.\n\t */\n\tif (sess->next_nonce.slen != 0) {\n\t    status = get_auth(sess, tdata);\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_error;\n\t    tdata->auth_info.nonce = sess->next_nonce;\n\t    tdata->auth_info.realm = sess->server_realm;\n\t}\n\n    } else {\n\tpj_assert(!\"Invalid authentication type\");\n\tstatus = PJ_EBUG;\n\tgoto on_error;\n    }\n\n    *p_tdata = tdata;\n    pj_grp_lock_release(sess->grp_lock);\n    return PJ_SUCCESS;\n\non_error:\n    if (tdata)\n\tpj_pool_release(tdata->pool);\n    pj_grp_lock_release(sess->grp_lock);\n    return status;\n}\n\nPJ_DEF(pj_status_t) pj_stun_session_create_ind(pj_stun_session *sess,\n\t\t\t\t\t       int msg_type,\n\t\t\t\t\t       pj_stun_tx_data **p_tdata)\n{\n    pj_stun_tx_data *tdata = NULL;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sess && p_tdata, PJ_EINVAL);\n\n    pj_grp_lock_acquire(sess->grp_lock);\n    if (sess->is_destroying) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    status = create_tdata(sess, &tdata);\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn status;\n    }\n\n    /* Create STUN message */\n    msg_type |= PJ_STUN_INDICATION_BIT;\n    status = pj_stun_msg_create(tdata->pool, msg_type,  PJ_STUN_MAGIC, \n\t\t\t\tNULL, &tdata->msg);\n    if (status != PJ_SUCCESS) {\n\tpj_pool_release(tdata->pool);\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn status;\n    }\n\n    *p_tdata = tdata;\n\n    pj_grp_lock_release(sess->grp_lock);\n    return PJ_SUCCESS;\n}\n\n/*\n * Create a STUN response message.\n */\nPJ_DEF(pj_status_t) pj_stun_session_create_res( pj_stun_session *sess,\n\t\t\t\t\t\tconst pj_stun_rx_data *rdata,\n\t\t\t\t\t\tunsigned err_code,\n\t\t\t\t\t\tconst pj_str_t *err_msg,\n\t\t\t\t\t\tpj_stun_tx_data **p_tdata)\n{\n    pj_status_t status;\n    pj_stun_tx_data *tdata = NULL;\n\n    pj_grp_lock_acquire(sess->grp_lock);\n    if (sess->is_destroying) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    status = create_tdata(sess, &tdata);\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn status;\n    }\n\n    /* Create STUN response message */\n    status = pj_stun_msg_create_response(tdata->pool, rdata->msg, \n\t\t\t\t\t err_code, err_msg, &tdata->msg);\n    if (status != PJ_SUCCESS) {\n\tpj_pool_release(tdata->pool);\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn status;\n    }\n\n    /* copy the request's transaction ID as the transaction key. */\n    pj_assert(sizeof(tdata->msg_key)==sizeof(rdata->msg->hdr.tsx_id));\n    tdata->msg_magic = rdata->msg->hdr.magic;\n    pj_memcpy(tdata->msg_key, rdata->msg->hdr.tsx_id, \n\t      sizeof(rdata->msg->hdr.tsx_id));\n\n    /* copy the credential found in the request */\n    pj_stun_req_cred_info_dup(tdata->pool, &tdata->auth_info, &rdata->info);\n\n    *p_tdata = tdata;\n\n    pj_grp_lock_release(sess->grp_lock);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Print outgoing message to log */\nstatic void dump_tx_msg(pj_stun_session *sess, const pj_stun_msg *msg,\n\t\t\tunsigned pkt_size, const pj_sockaddr_t *addr)\n{\n    char dst_name[PJ_INET6_ADDRSTRLEN+10];\n    \n    if ((PJ_STUN_IS_REQUEST(msg->hdr.type) && \n\t (sess->log_flag & PJ_STUN_SESS_LOG_TX_REQ)==0) ||\n\t(PJ_STUN_IS_RESPONSE(msg->hdr.type) &&\n\t (sess->log_flag & PJ_STUN_SESS_LOG_TX_RES)==0) ||\n\t(PJ_STUN_IS_INDICATION(msg->hdr.type) &&\n\t (sess->log_flag & PJ_STUN_SESS_LOG_TX_IND)==0))\n    {\n\treturn;\n    }\n\n    pj_sockaddr_print(addr, dst_name, sizeof(dst_name), 3);\n\n    PJ_LOG(5,(SNAME(sess), \n\t      \"TX %d bytes STUN message to %s:\\n\"\n\t      \"--- begin STUN message ---\\n\"\n\t      \"%s\"\n\t      \"--- end of STUN message ---\\n\",\n\t      pkt_size, dst_name, \n\t      pj_stun_msg_dump(msg, sess->dump_buf, sizeof(sess->dump_buf), \n\t\t\t       NULL)));\n\n}\n\n\nPJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess,\n\t\t\t\t\t      void *token,\n\t\t\t\t\t      pj_bool_t cache_res,\n\t\t\t\t\t      pj_bool_t retransmit,\n\t\t\t\t\t      const pj_sockaddr_t *server,\n\t\t\t\t\t      unsigned addr_len,\n\t\t\t\t\t      pj_stun_tx_data *tdata)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sess && addr_len && server && tdata, PJ_EINVAL);\n\n    /* Lock the session and prevent user from destroying us in the callback */\n    pj_grp_lock_acquire(sess->grp_lock);\n    if (sess->is_destroying) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    pj_log_push_indent();\n\n    /* Allocate packet */\n    tdata->max_len = PJ_STUN_MAX_PKT_LEN;\n    tdata->pkt = pj_pool_alloc(tdata->pool, tdata->max_len);\n\n    tdata->token = token;\n    tdata->retransmit = retransmit;\n\n    /* Apply options */\n    status = apply_msg_options(sess, tdata->pool, &tdata->auth_info, \n\t\t\t       tdata->msg);\n    if (status != PJ_SUCCESS) {\n\tpj_stun_msg_destroy_tdata(sess, tdata);\n\tLOG_ERR_(sess, \"Error applying options\", status);\n\tgoto on_return;\n    }\n\n    /* Encode message */\n    status = pj_stun_msg_encode(tdata->msg, (pj_uint8_t*)tdata->pkt, \n    \t\t\t\ttdata->max_len, 0, \n    \t\t\t\t&tdata->auth_info.auth_key,\n\t\t\t\t&tdata->pkt_size);\n    if (status != PJ_SUCCESS) {\n\tpj_stun_msg_destroy_tdata(sess, tdata);\n\tLOG_ERR_(sess, \"STUN encode() error\", status);\n\tgoto on_return;\n    }\n\n    /* Dump packet */\n    dump_tx_msg(sess, tdata->msg, (unsigned)tdata->pkt_size, server);\n\n    /* If this is a STUN request message, then send the request with\n     * a new STUN client transaction.\n     */\n    if (PJ_STUN_IS_REQUEST(tdata->msg->hdr.type)) {\n\n\t/* Create STUN client transaction */\n\tstatus = pj_stun_client_tsx_create(sess->cfg, tdata->pool,\n\t                                   sess->grp_lock,\n\t\t\t\t\t   &tsx_cb, &tdata->client_tsx);\n\tPJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n\tpj_stun_client_tsx_set_data(tdata->client_tsx, (void*)tdata);\n\n\t/* Save the remote address */\n\ttdata->addr_len = addr_len;\n\ttdata->dst_addr = server;\n\n\t/* Send the request! */\n\tstatus = pj_stun_client_tsx_send_msg(tdata->client_tsx, retransmit,\n\t\t\t\t\t     tdata->pkt, \n\t\t\t\t\t     (unsigned)tdata->pkt_size);\n\tif (status != PJ_SUCCESS && status != PJ_EPENDING) {\n\t    pj_stun_msg_destroy_tdata(sess, tdata);\n\t    LOG_ERR_(sess, \"Error sending STUN request\", status);\n\t    goto on_return;\n\t}\n\n\t/* Add to pending request list */\n\ttsx_add(sess, tdata);\n\n    } else {\n\tif (cache_res && \n\t    (PJ_STUN_IS_SUCCESS_RESPONSE(tdata->msg->hdr.type) ||\n\t     PJ_STUN_IS_ERROR_RESPONSE(tdata->msg->hdr.type))) \n\t{\n\t    /* Requested to keep the response in the cache */\n\t    pj_time_val timeout;\n\t    \n\t    pj_memset(&tdata->res_timer, 0, sizeof(tdata->res_timer));\n\t    pj_timer_entry_init(&tdata->res_timer, PJ_FALSE, tdata,\n\t\t\t\t&on_cache_timeout);\n\n\t    timeout.sec = sess->cfg->res_cache_msec / 1000;\n\t    timeout.msec = sess->cfg->res_cache_msec % 1000;\n\n\t    status = pj_timer_heap_schedule_w_grp_lock(sess->cfg->timer_heap,\n\t                                               &tdata->res_timer,\n\t                                               &timeout, PJ_TRUE,\n\t                                               sess->grp_lock);\n\t    if (status != PJ_SUCCESS) {\n\t\tpj_stun_msg_destroy_tdata(sess, tdata);\n\t\tLOG_ERR_(sess, \"Error scheduling response timer\", status);\n\t\tgoto on_return;\n\t    }\n\n\t    pj_list_push_back(&sess->cached_response_list, tdata);\n\t}\n    \n\t/* Otherwise for non-request message, send directly to transport. */\n\tstatus = sess->cb.on_send_msg(sess, token, tdata->pkt, \n\t\t\t\t      tdata->pkt_size, server, addr_len);\n\n\tif (status != PJ_SUCCESS && status != PJ_EPENDING) {\n\t    pj_stun_msg_destroy_tdata(sess, tdata);\n\t    LOG_ERR_(sess, \"Error sending STUN request\", status);\n\t    goto on_return;\n\t}\n\n\t/* Destroy only when response is not cached*/\n\tif (tdata->res_timer.id == 0) {\n\t    pj_stun_msg_destroy_tdata(sess, tdata);\n\t}\n    }\n\non_return:\n    pj_log_pop_indent();\n\n    if (pj_grp_lock_release(sess->grp_lock))\n\treturn PJ_EGONE;\n\n    return status;\n}\n\n\n/*\n * Create and send STUN response message.\n */\nPJ_DEF(pj_status_t) pj_stun_session_respond( pj_stun_session *sess, \n\t\t\t\t\t     const pj_stun_rx_data *rdata,\n\t\t\t\t\t     unsigned code, \n\t\t\t\t\t     const char *errmsg,\n\t\t\t\t\t     void *token,\n\t\t\t\t\t     pj_bool_t cache, \n\t\t\t\t\t     const pj_sockaddr_t *dst_addr, \n\t\t\t\t\t     unsigned addr_len)\n{\n    pj_status_t status;\n    pj_str_t reason;\n    pj_stun_tx_data *tdata;\n\n    pj_grp_lock_acquire(sess->grp_lock);\n    if (sess->is_destroying) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    status = pj_stun_session_create_res(sess, rdata, code, \n\t\t\t\t\t(errmsg?pj_cstr(&reason,errmsg):NULL), \n\t\t\t\t\t&tdata);\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn status;\n    }\n\n    status = pj_stun_session_send_msg(sess, token, cache, PJ_FALSE,\n                                      dst_addr,  addr_len, tdata);\n\n    pj_grp_lock_release(sess->grp_lock);\n    return status;\n}\n\n\n/*\n * Cancel outgoing STUN transaction. \n */\nPJ_DEF(pj_status_t) pj_stun_session_cancel_req( pj_stun_session *sess,\n\t\t\t\t\t\tpj_stun_tx_data *tdata,\n\t\t\t\t\t\tpj_bool_t notify,\n\t\t\t\t\t\tpj_status_t notify_status)\n{\n    PJ_ASSERT_RETURN(sess && tdata, PJ_EINVAL);\n    PJ_ASSERT_RETURN(!notify || notify_status!=PJ_SUCCESS, PJ_EINVAL);\n    PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(tdata->msg->hdr.type), PJ_EINVAL);\n\n    /* Lock the session and prevent user from destroying us in the callback */\n    pj_grp_lock_acquire(sess->grp_lock);\n    if (sess->is_destroying) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    if (notify) {\n\t(sess->cb.on_request_complete)(sess, notify_status, tdata->token, \n\t\t\t\t       tdata, NULL, NULL, 0);\n    }\n\n    /* Just destroy tdata. This will destroy the transaction as well */\n    pj_stun_msg_destroy_tdata(sess, tdata);\n\n    pj_grp_lock_release(sess->grp_lock);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Explicitly request retransmission of the request.\n */\nPJ_DEF(pj_status_t) pj_stun_session_retransmit_req(pj_stun_session *sess,\n\t\t\t\t\t\t   pj_stun_tx_data *tdata,\n                                                   pj_bool_t mod_count)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sess && tdata, PJ_EINVAL);\n    PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(tdata->msg->hdr.type), PJ_EINVAL);\n\n    /* Lock the session and prevent user from destroying us in the callback */\n    pj_grp_lock_acquire(sess->grp_lock);\n    if (sess->is_destroying) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    status = pj_stun_client_tsx_retransmit(tdata->client_tsx, mod_count);\n\n    pj_grp_lock_release(sess->grp_lock);\n\n    return status;\n}\n\n\n/* Send response */\nstatic pj_status_t send_response(pj_stun_session *sess, void *token,\n\t\t\t\t pj_pool_t *pool, pj_stun_msg *response,\n\t\t\t\t const pj_stun_req_cred_info *auth_info,\n\t\t\t\t pj_bool_t retransmission,\n\t\t\t\t const pj_sockaddr_t *addr, unsigned addr_len)\n{\n    pj_uint8_t *out_pkt;\n    pj_size_t out_max_len, out_len;\n    pj_status_t status;\n\n    /* Apply options */\n    if (!retransmission) {\n\tstatus = apply_msg_options(sess, pool, auth_info, response);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    /* Alloc packet buffer */\n    out_max_len = PJ_STUN_MAX_PKT_LEN;\n    out_pkt = (pj_uint8_t*) pj_pool_alloc(pool, out_max_len);\n\n    /* Encode */\n    status = pj_stun_msg_encode(response, out_pkt, out_max_len, 0, \n\t\t\t\t&auth_info->auth_key, &out_len);\n    if (status != PJ_SUCCESS) {\n\tLOG_ERR_(sess, \"Error encoding message\", status);\n\treturn status;\n    }\n\n    /* Print log */\n    dump_tx_msg(sess, response, (unsigned)out_len, addr);\n\n    /* Send packet */\n    status = sess->cb.on_send_msg(sess, token, out_pkt, (unsigned)out_len, \n\t\t\t\t  addr, addr_len);\n\n    return status;\n}\n\n/* Authenticate incoming message */\nstatic pj_status_t authenticate_req(pj_stun_session *sess,\n\t\t\t\t    void *token,\n\t\t\t\t    const pj_uint8_t *pkt,\n\t\t\t\t    unsigned pkt_len,\n\t\t\t\t    pj_stun_rx_data *rdata,\n\t\t\t\t    pj_pool_t *tmp_pool,\n\t\t\t\t    const pj_sockaddr_t *src_addr,\n\t\t\t\t    unsigned src_addr_len)\n{\n    pj_stun_msg *response;\n    pj_status_t status;\n\n    if (PJ_STUN_IS_ERROR_RESPONSE(rdata->msg->hdr.type) || \n\tsess->auth_type == PJ_STUN_AUTH_NONE)\n    {\n\treturn PJ_SUCCESS;\n    }\n\n    status = pj_stun_authenticate_request(pkt, pkt_len, rdata->msg, \n\t\t\t\t\t  &sess->cred, tmp_pool, &rdata->info,\n\t\t\t\t\t  &response);\n    if (status != PJ_SUCCESS && response != NULL) {\n\tPJ_LOG(5,(SNAME(sess), \"Message authentication failed\"));\n\tsend_response(sess, token, tmp_pool, response, &rdata->info, \n\t\t      PJ_FALSE, src_addr, src_addr_len);\n    }\n\n    return status;\n}\n\n\n/* Handle incoming response */\nstatic pj_status_t on_incoming_response(pj_stun_session *sess,\n\t\t\t\t\tunsigned options,\n\t\t\t\t\tconst pj_uint8_t *pkt,\n\t\t\t\t\tunsigned pkt_len,\n\t\t\t\t\tpj_stun_msg *msg,\n\t\t\t\t\tconst pj_sockaddr_t *src_addr,\n\t\t\t\t\tunsigned src_addr_len)\n{\n    pj_stun_tx_data *tdata;\n    pj_status_t status;\n\n    /* Lookup pending client transaction */\n    tdata = tsx_lookup(sess, msg);\n    if (tdata == NULL) {\n\tPJ_LOG(5,(SNAME(sess), \n\t\t  \"Transaction not found, response silently discarded\"));\n\treturn PJ_SUCCESS;\n    }\n\n    if (sess->auth_type == PJ_STUN_AUTH_NONE)\n\toptions |= PJ_STUN_NO_AUTHENTICATE;\n\n    /* Authenticate the message, unless PJ_STUN_NO_AUTHENTICATE\n     * is specified in the option.\n     */\n    if ((options & PJ_STUN_NO_AUTHENTICATE) == 0 && \n\ttdata->auth_info.auth_key.slen != 0 && \n\tpj_stun_auth_valid_for_msg(msg))\n    {\n\tstatus = pj_stun_authenticate_response(pkt, pkt_len, msg, \n\t\t\t\t\t       &tdata->auth_info.auth_key);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_LOG(5,(SNAME(sess), \n\t\t      \"Response authentication failed\"));\n\t    return status;\n\t}\n    }\n\n    /* Pass the response to the transaction. \n     * If the message is accepted, transaction callback will be called,\n     * and this will call the session callback too.\n     */\n    status = pj_stun_client_tsx_on_rx_msg(tdata->client_tsx, msg, \n\t\t\t\t\t  src_addr, src_addr_len);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* For requests, check if we cache the response */\nstatic pj_status_t check_cached_response(pj_stun_session *sess,\n\t\t\t\t\t pj_pool_t *tmp_pool,\n\t\t\t\t\t const pj_stun_msg *msg,\n\t\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t\t unsigned src_addr_len)\n{\n    pj_stun_tx_data *t;\n\n    /* First lookup response in response cache */\n    t = sess->cached_response_list.next;\n    while (t != &sess->cached_response_list) {\n\tif (t->msg_magic == msg->hdr.magic &&\n\t    t->msg->hdr.type == msg->hdr.type &&\n\t    pj_memcmp(t->msg_key, msg->hdr.tsx_id, \n\t\t      sizeof(msg->hdr.tsx_id))==0)\n\t{\n\t    break;\n\t}\n\tt = t->next;\n    }\n\n    if (t != &sess->cached_response_list) {\n\t/* Found response in the cache */\n\n\tPJ_LOG(5,(SNAME(sess), \n\t\t \"Request retransmission, sending cached response\"));\n\n\tsend_response(sess, t->token, tmp_pool, t->msg, &t->auth_info, \n\t\t      PJ_TRUE, src_addr, src_addr_len);\n\treturn PJ_SUCCESS;\n    }\n\n    return PJ_ENOTFOUND;\n}\n\n/* Handle incoming request */\nstatic pj_status_t on_incoming_request(pj_stun_session *sess,\n\t\t\t\t       unsigned options,\n\t\t\t\t       void *token,\n\t\t\t\t       pj_pool_t *tmp_pool,\n\t\t\t\t       const pj_uint8_t *in_pkt,\n\t\t\t\t       unsigned in_pkt_len,\n\t\t\t\t       pj_stun_msg *msg,\n\t\t\t\t       const pj_sockaddr_t *src_addr,\n\t\t\t\t       unsigned src_addr_len)\n{\n    pj_stun_rx_data rdata;\n    pj_status_t status;\n\n    /* Init rdata */\n    rdata.msg = msg;\n    pj_bzero(&rdata.info, sizeof(rdata.info));\n\n    if (sess->auth_type == PJ_STUN_AUTH_NONE)\n\toptions |= PJ_STUN_NO_AUTHENTICATE;\n\n    /* Authenticate the message, unless PJ_STUN_NO_AUTHENTICATE\n     * is specified in the option.\n     */\n    if ((options & PJ_STUN_NO_AUTHENTICATE) == 0) {\n\tstatus = authenticate_req(sess, token, (const pj_uint8_t*) in_pkt, \n\t\t\t\t  in_pkt_len,&rdata, tmp_pool, src_addr, \n\t\t\t\t  src_addr_len);\n\tif (status != PJ_SUCCESS) {\n\t    return status;\n\t}\n    }\n\n    /* Distribute to handler, or respond with Bad Request */\n    if (sess->cb.on_rx_request) {\n\tstatus = (*sess->cb.on_rx_request)(sess, in_pkt, in_pkt_len, &rdata,\n\t\t\t\t\t   token, src_addr, src_addr_len);\n    } else {\n\tpj_str_t err_text;\n\tpj_stun_msg *response;\n\n\terr_text = pj_str(\"Callback is not set to handle request\");\n\tstatus = pj_stun_msg_create_response(tmp_pool, msg, \n\t\t\t\t\t     PJ_STUN_SC_BAD_REQUEST, \n\t\t\t\t\t     &err_text, &response);\n\tif (status == PJ_SUCCESS && response) {\n\t    status = send_response(sess, token, tmp_pool, response, \n\t\t\t\t   NULL, PJ_FALSE, src_addr, src_addr_len);\n\t}\n    }\n\n    return status;\n}\n\n\n/* Handle incoming indication */\nstatic pj_status_t on_incoming_indication(pj_stun_session *sess,\n\t\t\t\t\t  void *token,\n\t\t\t\t\t  pj_pool_t *tmp_pool,\n\t\t\t\t\t  const pj_uint8_t *in_pkt,\n\t\t\t\t\t  unsigned in_pkt_len,\n\t\t\t\t\t  const pj_stun_msg *msg,\n\t\t\t\t\t  const pj_sockaddr_t *src_addr,\n\t\t\t\t\t  unsigned src_addr_len)\n{\n    PJ_UNUSED_ARG(tmp_pool);\n\n    /* Distribute to handler */\n    if (sess->cb.on_rx_indication) {\n\treturn (*sess->cb.on_rx_indication)(sess, in_pkt, in_pkt_len, msg,\n\t\t\t\t\t    token, src_addr, src_addr_len);\n    } else {\n\treturn PJ_SUCCESS;\n    }\n}\n\n\n/* Print outgoing message to log */\nstatic void dump_rx_msg(pj_stun_session *sess, const pj_stun_msg *msg,\n\t\t\tunsigned pkt_size, const pj_sockaddr_t *addr)\n{\n    char src_info[PJ_INET6_ADDRSTRLEN+10];\n    \n    if ((PJ_STUN_IS_REQUEST(msg->hdr.type) && \n\t (sess->log_flag & PJ_STUN_SESS_LOG_RX_REQ)==0) ||\n\t(PJ_STUN_IS_RESPONSE(msg->hdr.type) &&\n\t (sess->log_flag & PJ_STUN_SESS_LOG_RX_RES)==0) ||\n\t(PJ_STUN_IS_INDICATION(msg->hdr.type) &&\n\t (sess->log_flag & PJ_STUN_SESS_LOG_RX_IND)==0))\n    {\n\treturn;\n    }\n\n    pj_sockaddr_print(addr, src_info, sizeof(src_info), 3);\n\n    PJ_LOG(5,(SNAME(sess),\n\t      \"RX %d bytes STUN message from %s:\\n\"\n\t      \"--- begin STUN message ---\\n\"\n\t      \"%s\"\n\t      \"--- end of STUN message ---\\n\",\n\t      pkt_size, src_info,\n\t      pj_stun_msg_dump(msg, sess->dump_buf, sizeof(sess->dump_buf), \n\t\t\t       NULL)));\n\n}\n\n/* Incoming packet */\nPJ_DEF(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess,\n\t\t\t\t\t      const void *packet,\n\t\t\t\t\t      pj_size_t pkt_size,\n\t\t\t\t\t      unsigned options,\n\t\t\t\t\t      void *token,\n\t\t\t\t\t      pj_size_t *parsed_len,\n\t\t\t\t\t      const pj_sockaddr_t *src_addr,\n\t\t\t\t\t      unsigned src_addr_len)\n{\n    pj_stun_msg *msg, *response;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sess && packet && pkt_size, PJ_EINVAL);\n\n    /* Lock the session and prevent user from destroying us in the callback */\n    pj_grp_lock_acquire(sess->grp_lock);\n\n    if (sess->is_destroying) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    pj_log_push_indent();\n\n    /* Reset pool */\n    pj_pool_reset(sess->rx_pool);\n\n    /* Try to parse the message */\n    status = pj_stun_msg_decode(sess->rx_pool, (const pj_uint8_t*)packet,\n\t\t\t        pkt_size, options, \n\t\t\t\t&msg, parsed_len, &response);\n    if (status != PJ_SUCCESS) {\n\tLOG_ERR_(sess, \"STUN msg_decode() error\", status);\n\tif (response) {\n\t    send_response(sess, token, sess->rx_pool, response, NULL,\n\t\t\t  PJ_FALSE, src_addr, src_addr_len);\n\t}\n\tgoto on_return;\n    }\n\n    dump_rx_msg(sess, msg, (unsigned)pkt_size, src_addr);\n\n    /* For requests, check if we have cached response */\n    status = check_cached_response(sess, sess->rx_pool, msg, \n\t\t\t\t   src_addr, src_addr_len);\n    if (status == PJ_SUCCESS) {\n\tgoto on_return;\n    }\n\n    /* Handle message */\n    if (PJ_STUN_IS_SUCCESS_RESPONSE(msg->hdr.type) ||\n\tPJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type))\n    {\n\tstatus = on_incoming_response(sess, options, \n\t\t\t\t      (const pj_uint8_t*) packet, \n\t\t\t\t      (unsigned)pkt_size, msg, \n\t\t\t\t      src_addr, src_addr_len);\n\n    } else if (PJ_STUN_IS_REQUEST(msg->hdr.type)) {\n\n\tstatus = on_incoming_request(sess, options, token, sess->rx_pool, \n\t\t\t\t     (const pj_uint8_t*) packet, \n\t\t\t\t     (unsigned)pkt_size, \n\t\t\t\t     msg, src_addr, src_addr_len);\n\n    } else if (PJ_STUN_IS_INDICATION(msg->hdr.type)) {\n\n\tstatus = on_incoming_indication(sess, token, sess->rx_pool, \n\t\t\t\t\t(const pj_uint8_t*) packet, \n\t\t\t\t\t(unsigned)pkt_size, msg, src_addr, \n\t\t\t\t\tsrc_addr_len);\n\n    } else {\n\tpj_assert(!\"Unexpected!\");\n\tstatus = PJ_EBUG;\n    }\n\non_return:\n    pj_log_pop_indent();\n\n    if (pj_grp_lock_release(sess->grp_lock))\n\treturn PJ_EGONE;\n\n    return status;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjnath/stun_sock.c",
    "content": "/* $Id: stun_sock.c 4360 2013-02-21 11:26:35Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjnath/stun_sock.h>\n#include <pjnath/errno.h>\n#include <pjnath/stun_transaction.h>\n#include <pjnath/stun_session.h>\n#include <pjlib-util/srv_resolver.h>\n#include <pj/activesock.h>\n#include <pj/addr_resolv.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/ip_helper.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n\n#if 1\n#  define TRACE_(x)\tPJ_LOG(5,x)\n#else\n#  define TRACE_(x)\n#endif\n\nenum { MAX_BIND_RETRY = 100 };\n\nstruct pj_stun_sock\n{\n    char\t\t*obj_name;\t/* Log identification\t    */\n    pj_pool_t\t\t*pool;\t\t/* Pool\t\t\t    */\n    void\t\t*user_data;\t/* Application user data    */\n    pj_bool_t\t\t is_destroying; /* Destroy already called   */\n    int\t\t\t af;\t\t/* Address family\t    */\n    pj_stun_config\t stun_cfg;\t/* STUN config (ioqueue etc)*/\n    pj_stun_sock_cb\t cb;\t\t/* Application callbacks    */\n\n    int\t\t\t ka_interval;\t/* Keep alive interval\t    */\n    pj_timer_entry\t ka_timer;\t/* Keep alive timer.\t    */\n\n    pj_sockaddr\t\t srv_addr;\t/* Resolved server addr\t    */\n    pj_sockaddr\t\t mapped_addr;\t/* Our public address\t    */\n\n    pj_dns_srv_async_query *q;\t\t/* Pending DNS query\t    */\n    pj_sock_t\t\t sock_fd;\t/* Socket descriptor\t    */\n    pj_activesock_t\t*active_sock;\t/* Active socket object\t    */\n    pj_ioqueue_op_key_t\t send_key;\t/* Default send key for app */\n    pj_ioqueue_op_key_t\t int_send_key;\t/* Send key for internal    */\n\n    pj_uint16_t\t\t tsx_id[6];\t/* .. to match STUN msg\t    */\n    pj_stun_session\t*stun_sess;\t/* STUN session\t\t    */\n    pj_grp_lock_t\t*grp_lock;\t/* Session group lock\t    */\n};\n\n/* \n * Prototypes for static functions \n */\n\n/* Destructor for group lock */\nstatic void stun_sock_destructor(void *obj);\n\n/* This callback is called by the STUN session to send packet */\nstatic pj_status_t sess_on_send_msg(pj_stun_session *sess,\n\t\t\t\t    void *token,\n\t\t\t\t    const void *pkt,\n\t\t\t\t    pj_size_t pkt_size,\n\t\t\t\t    const pj_sockaddr_t *dst_addr,\n\t\t\t\t    unsigned addr_len);\n\n/* This callback is called by the STUN session when outgoing transaction \n * is complete\n */\nstatic void sess_on_request_complete(pj_stun_session *sess,\n\t\t\t\t     pj_status_t status,\n\t\t\t\t     void *token,\n\t\t\t\t     pj_stun_tx_data *tdata,\n\t\t\t\t     const pj_stun_msg *response,\n\t\t\t\t     const pj_sockaddr_t *src_addr,\n\t\t\t\t     unsigned src_addr_len);\n/* DNS resolver callback */\nstatic void dns_srv_resolver_cb(void *user_data,\n\t\t\t\tpj_status_t status,\n\t\t\t\tconst pj_dns_srv_record *rec);\n\n/* Start sending STUN Binding request */\nstatic pj_status_t get_mapped_addr(pj_stun_sock *stun_sock);\n\n/* Callback from active socket when incoming packet is received */\nstatic pj_bool_t on_data_recvfrom(pj_activesock_t *asock,\n\t\t\t\t  void *data,\n\t\t\t\t  pj_size_t size,\n\t\t\t\t  const pj_sockaddr_t *src_addr,\n\t\t\t\t  int addr_len,\n\t\t\t\t  pj_status_t status);\n\n/* Callback from active socket about send status */\nstatic pj_bool_t on_data_sent(pj_activesock_t *asock,\n\t\t\t      pj_ioqueue_op_key_t *send_key,\n\t\t\t      pj_ssize_t sent);\n\n/* Schedule keep-alive timer */\nstatic void start_ka_timer(pj_stun_sock *stun_sock);\n\n/* Keep-alive timer callback */\nstatic void ka_timer_cb(pj_timer_heap_t *th, pj_timer_entry *te);\n\n#define INTERNAL_MSG_TOKEN  (void*)(pj_ssize_t)1\n\n\n/*\n * Retrieve the name representing the specified operation.\n */\nPJ_DEF(const char*) pj_stun_sock_op_name(pj_stun_sock_op op)\n{\n    const char *names[] = {\n\t\"?\",\n\t\"DNS resolution\",\n\t\"STUN Binding request\",\n\t\"Keep-alive\",\n\t\"Mapped addr. changed\"\n    };\n\n    return op < PJ_ARRAY_SIZE(names) ? names[op] : \"???\";\n};\n\n\n/*\n * Initialize the STUN transport setting with its default values.\n */\nPJ_DEF(void) pj_stun_sock_cfg_default(pj_stun_sock_cfg *cfg)\n{\n    pj_bzero(cfg, sizeof(*cfg));\n    cfg->max_pkt_size = PJ_STUN_SOCK_PKT_LEN;\n    cfg->async_cnt = 1;\n    cfg->ka_interval = PJ_STUN_KEEP_ALIVE_SEC;\n    cfg->qos_type = PJ_QOS_TYPE_BEST_EFFORT;\n    cfg->qos_ignore_error = PJ_TRUE;\n}\n\n\n/* Check that configuration setting is valid */\nstatic pj_bool_t pj_stun_sock_cfg_is_valid(const pj_stun_sock_cfg *cfg)\n{\n    return cfg->max_pkt_size > 1 && cfg->async_cnt >= 1;\n}\n\n/*\n * Create the STUN transport using the specified configuration.\n */\nPJ_DEF(pj_status_t) pj_stun_sock_create( pj_stun_config *stun_cfg,\n\t\t\t\t\t const char *name,\n\t\t\t\t\t int af,\n\t\t\t\t\t const pj_stun_sock_cb *cb,\n\t\t\t\t\t const pj_stun_sock_cfg *cfg,\n\t\t\t\t\t void *user_data,\n\t\t\t\t\t pj_stun_sock **p_stun_sock)\n{\n    pj_pool_t *pool;\n    pj_stun_sock *stun_sock;\n    pj_stun_sock_cfg default_cfg;\n    pj_sockaddr bound_addr;\n    unsigned i;\n    pj_uint16_t max_bind_retry;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(stun_cfg && cb && p_stun_sock, PJ_EINVAL);\n    PJ_ASSERT_RETURN(af==pj_AF_INET()||af==pj_AF_INET6(), PJ_EAFNOTSUP);\n    PJ_ASSERT_RETURN(!cfg || pj_stun_sock_cfg_is_valid(cfg), PJ_EINVAL);\n    PJ_ASSERT_RETURN(cb->on_status, PJ_EINVAL);\n\n    status = pj_stun_config_check_valid(stun_cfg);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (name == NULL)\n\tname = \"stuntp%p\";\n\n    if (cfg == NULL) {\n\tpj_stun_sock_cfg_default(&default_cfg);\n\tcfg = &default_cfg;\n    }\n\n\n    /* Create structure */\n    pool = pj_pool_create(stun_cfg->pf, name, 256, 512, NULL);\n    stun_sock = PJ_POOL_ZALLOC_T(pool, pj_stun_sock);\n    stun_sock->pool = pool;\n    stun_sock->obj_name = pool->obj_name;\n    stun_sock->user_data = user_data;\n    stun_sock->af = af;\n    stun_sock->sock_fd = PJ_INVALID_SOCKET;\n    pj_memcpy(&stun_sock->stun_cfg, stun_cfg, sizeof(*stun_cfg));\n    pj_memcpy(&stun_sock->cb, cb, sizeof(*cb));\n\n    stun_sock->ka_interval = cfg->ka_interval;\n    if (stun_sock->ka_interval == 0)\n\tstun_sock->ka_interval = PJ_STUN_KEEP_ALIVE_SEC;\n\n    if (cfg->grp_lock) {\n\tstun_sock->grp_lock = cfg->grp_lock;\n    } else {\n\tstatus = pj_grp_lock_create(pool, NULL, &stun_sock->grp_lock);\n\tif (status != PJ_SUCCESS) {\n\t    pj_pool_release(pool);\n\t    return status;\n\t}\n    }\n\n    pj_grp_lock_add_ref(stun_sock->grp_lock);\n    pj_grp_lock_add_handler(stun_sock->grp_lock, pool, stun_sock,\n\t\t\t    &stun_sock_destructor);\n\n    /* Create socket and bind socket */\n    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &stun_sock->sock_fd);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Apply QoS, if specified */\n    status = pj_sock_apply_qos2(stun_sock->sock_fd, cfg->qos_type,\n\t\t\t\t&cfg->qos_params, 2, stun_sock->obj_name,\n\t\t\t\tNULL);\n    if (status != PJ_SUCCESS && !cfg->qos_ignore_error)\n\tgoto on_error;\n\n    /* Apply socket buffer size */\n    if (cfg->so_rcvbuf_size > 0) {\n\tunsigned sobuf_size = cfg->so_rcvbuf_size;\n\tstatus = pj_sock_setsockopt_sobuf(stun_sock->sock_fd, pj_SO_RCVBUF(),\n\t\t\t\t\t  PJ_TRUE, &sobuf_size);\n\tif (status != PJ_SUCCESS) {\n\t    pj_perror(3, stun_sock->obj_name, status,\n\t\t      \"Failed setting SO_RCVBUF\");\n\t} else {\n\t    if (sobuf_size < cfg->so_rcvbuf_size) {\n\t\tPJ_LOG(4, (stun_sock->obj_name, \n\t\t\t   \"Warning! Cannot set SO_RCVBUF as configured, \"\n\t\t\t   \"now=%d, configured=%d\",\n\t\t\t   sobuf_size, cfg->so_rcvbuf_size));\n\t    } else {\n\t\tPJ_LOG(5, (stun_sock->obj_name, \"SO_RCVBUF set to %d\",\n\t\t\t   sobuf_size));\n\t    }\n\t}\n    }\n    if (cfg->so_sndbuf_size > 0) {\n\tunsigned sobuf_size = cfg->so_sndbuf_size;\n\tstatus = pj_sock_setsockopt_sobuf(stun_sock->sock_fd, pj_SO_SNDBUF(),\n\t\t\t\t\t  PJ_TRUE, &sobuf_size);\n\tif (status != PJ_SUCCESS) {\n\t    pj_perror(3, stun_sock->obj_name, status,\n\t\t      \"Failed setting SO_SNDBUF\");\n\t} else {\n\t    if (sobuf_size < cfg->so_sndbuf_size) {\n\t\tPJ_LOG(4, (stun_sock->obj_name, \n\t\t\t   \"Warning! Cannot set SO_SNDBUF as configured, \"\n\t\t\t   \"now=%d, configured=%d\",\n\t\t\t   sobuf_size, cfg->so_sndbuf_size));\n\t    } else {\n\t\tPJ_LOG(5, (stun_sock->obj_name, \"SO_SNDBUF set to %d\",\n\t\t\t   sobuf_size));\n\t    }\n\t}\n    }\n\n    /* Bind socket */\n    max_bind_retry = MAX_BIND_RETRY;\n    if (cfg->port_range && cfg->port_range < max_bind_retry)\n\tmax_bind_retry = cfg->port_range;\n    pj_sockaddr_init(af, &bound_addr, NULL, 0);\n    if (cfg->bound_addr.addr.sa_family == pj_AF_INET() || \n\tcfg->bound_addr.addr.sa_family == pj_AF_INET6())\n    {\n\tpj_sockaddr_cp(&bound_addr, &cfg->bound_addr);\n    }\n    status = pj_sock_bind_random(stun_sock->sock_fd, &bound_addr,\n\t\t\t\t cfg->port_range, max_bind_retry);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Create more useful information string about this transport */\n#if 0\n    {\n\tpj_sockaddr bound_addr;\n\tint addr_len = sizeof(bound_addr);\n\n\tstatus = pj_sock_getsockname(stun_sock->sock_fd, &bound_addr, \n\t\t\t\t     &addr_len);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n\tstun_sock->info = pj_pool_alloc(pool, PJ_INET6_ADDRSTRLEN+10);\n\tpj_sockaddr_print(&bound_addr, stun_sock->info, \n\t\t\t  PJ_INET6_ADDRSTRLEN, 3);\n    }\n#endif\n\n    /* Init active socket configuration */\n    {\n\tpj_activesock_cfg activesock_cfg;\n\tpj_activesock_cb activesock_cb;\n\n\tpj_activesock_cfg_default(&activesock_cfg);\n\tactivesock_cfg.grp_lock = stun_sock->grp_lock;\n\tactivesock_cfg.async_cnt = cfg->async_cnt;\n\tactivesock_cfg.concurrency = 0;\n\n\t/* Create the active socket */\n\tpj_bzero(&activesock_cb, sizeof(activesock_cb));\n\tactivesock_cb.on_data_recvfrom = &on_data_recvfrom;\n\tactivesock_cb.on_data_sent = &on_data_sent;\n\tstatus = pj_activesock_create(pool, stun_sock->sock_fd, \n\t\t\t\t      pj_SOCK_DGRAM(), \n\t\t\t\t      &activesock_cfg, stun_cfg->ioqueue,\n\t\t\t\t      &activesock_cb, stun_sock,\n\t\t\t\t      &stun_sock->active_sock);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n\t/* Start asynchronous read operations */\n\tstatus = pj_activesock_start_recvfrom(stun_sock->active_sock, pool,\n\t\t\t\t\t      cfg->max_pkt_size, 0);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n\t/* Init send keys */\n\tpj_ioqueue_op_key_init(&stun_sock->send_key, \n\t\t\t       sizeof(stun_sock->send_key));\n\tpj_ioqueue_op_key_init(&stun_sock->int_send_key,\n\t\t\t       sizeof(stun_sock->int_send_key));\n    }\n\n    /* Create STUN session */\n    {\n\tpj_stun_session_cb sess_cb;\n\n\tpj_bzero(&sess_cb, sizeof(sess_cb));\n\tsess_cb.on_request_complete = &sess_on_request_complete;\n\tsess_cb.on_send_msg = &sess_on_send_msg;\n\tstatus = pj_stun_session_create(&stun_sock->stun_cfg, \n\t\t\t\t\tstun_sock->obj_name,\n\t\t\t\t\t&sess_cb, PJ_FALSE, \n\t\t\t\t\tstun_sock->grp_lock,\n\t\t\t\t\t&stun_sock->stun_sess);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n    }\n\n    /* Associate us with the STUN session */\n    pj_stun_session_set_user_data(stun_sock->stun_sess, stun_sock);\n\n    /* Initialize random numbers to be used as STUN transaction ID for\n     * outgoing Binding request. We use the 80bit number to distinguish\n     * STUN messages we sent with STUN messages that the application sends.\n     * The last 16bit value in the array is a counter.\n     */\n    for (i=0; i<PJ_ARRAY_SIZE(stun_sock->tsx_id); ++i) {\n\tstun_sock->tsx_id[i] = (pj_uint16_t) pj_rand();\n    }\n    stun_sock->tsx_id[5] = 0;\n\n\n    /* Init timer entry */\n    stun_sock->ka_timer.cb = &ka_timer_cb;\n    stun_sock->ka_timer.user_data = stun_sock;\n\n    /* Done */\n    *p_stun_sock = stun_sock;\n    return PJ_SUCCESS;\n\non_error:\n    pj_stun_sock_destroy(stun_sock);\n    return status;\n}\n\n/* Start socket. */\nPJ_DEF(pj_status_t) pj_stun_sock_start( pj_stun_sock *stun_sock,\n\t\t\t\t        const pj_str_t *domain,\n\t\t\t\t        pj_uint16_t default_port,\n\t\t\t\t        pj_dns_resolver *resolver)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(stun_sock && domain && default_port, PJ_EINVAL);\n\n    pj_grp_lock_acquire(stun_sock->grp_lock);\n\n    /* Check whether the domain contains IP address */\n    stun_sock->srv_addr.addr.sa_family = (pj_uint16_t)stun_sock->af;\n    status = pj_inet_pton(stun_sock->af, domain, \n\t\t\t  pj_sockaddr_get_addr(&stun_sock->srv_addr));\n    if (status != PJ_SUCCESS) {\n\tstun_sock->srv_addr.addr.sa_family = (pj_uint16_t)0;\n    }\n\n    /* If resolver is set, try to resolve with DNS SRV first. It\n     * will fallback to DNS A/AAAA when no SRV record is found.\n     */\n    if (status != PJ_SUCCESS && resolver) {\n\tconst pj_str_t res_name = pj_str(\"_stun._udp.\");\n\tunsigned opt;\n\n\tpj_assert(stun_sock->q == NULL);\n\n\topt = PJ_DNS_SRV_FALLBACK_A;\n\tif (stun_sock->af == pj_AF_INET6()) {\n\t    opt |= (PJ_DNS_SRV_RESOLVE_AAAA | PJ_DNS_SRV_FALLBACK_AAAA);\n\t}\n\n\tstatus = pj_dns_srv_resolve(domain, &res_name, default_port, \n\t\t\t\t    stun_sock->pool, resolver, opt,\n\t\t\t\t    stun_sock, &dns_srv_resolver_cb, \n\t\t\t\t    &stun_sock->q);\n\n\t/* Processing will resume when the DNS SRV callback is called */\n\n    } else {\n\n\tif (status != PJ_SUCCESS) {\n\t    pj_addrinfo ai;\n\t    unsigned cnt = 1;\n\n\t    status = pj_getaddrinfo(stun_sock->af, domain, &cnt, &ai);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    pj_sockaddr_cp(&stun_sock->srv_addr, &ai.ai_addr);\n\t}\n\n\tpj_sockaddr_set_port(&stun_sock->srv_addr, (pj_uint16_t)default_port);\n\n\t/* Start sending Binding request */\n\tstatus = get_mapped_addr(stun_sock);\n    }\n\n    pj_grp_lock_release(stun_sock->grp_lock);\n    return status;\n}\n\n/* Destructor */\nstatic void stun_sock_destructor(void *obj)\n{\n    pj_stun_sock *stun_sock = (pj_stun_sock*)obj;\n\n    if (stun_sock->q) {\n\tpj_dns_srv_cancel_query(stun_sock->q, PJ_FALSE);\n\tstun_sock->q = NULL;\n    }\n\n    /*\n    if (stun_sock->stun_sess) {\n\tpj_stun_session_destroy(stun_sock->stun_sess);\n\tstun_sock->stun_sess = NULL;\n    }\n    */\n\n    if (stun_sock->pool) {\n\tpj_pool_t *pool = stun_sock->pool;\n\tstun_sock->pool = NULL;\n\tpj_pool_release(pool);\n    }\n\n    TRACE_((\"\", \"STUN sock %p destroyed\", stun_sock));\n\n}\n\n/* Destroy */\nPJ_DEF(pj_status_t) pj_stun_sock_destroy(pj_stun_sock *stun_sock)\n{\n    TRACE_((stun_sock->obj_name, \"STUN sock %p request, ref_cnt=%d\",\n\t    stun_sock, pj_grp_lock_get_ref(stun_sock->grp_lock)));\n\n    pj_grp_lock_acquire(stun_sock->grp_lock);\n    if (stun_sock->is_destroying) {\n\t/* Destroy already called */\n\tpj_grp_lock_release(stun_sock->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    stun_sock->is_destroying = PJ_TRUE;\n    pj_timer_heap_cancel_if_active(stun_sock->stun_cfg.timer_heap,\n                                   &stun_sock->ka_timer, 0);\n\n    if (stun_sock->active_sock != NULL) {\n\tstun_sock->sock_fd = PJ_INVALID_SOCKET;\n\tpj_activesock_close(stun_sock->active_sock);\n    } else if (stun_sock->sock_fd != PJ_INVALID_SOCKET) {\n\tpj_sock_close(stun_sock->sock_fd);\n\tstun_sock->sock_fd = PJ_INVALID_SOCKET;\n    }\n\n    if (stun_sock->stun_sess) {\n\tpj_stun_session_destroy(stun_sock->stun_sess);\n    }\n    pj_grp_lock_dec_ref(stun_sock->grp_lock);\n    pj_grp_lock_release(stun_sock->grp_lock);\n    return PJ_SUCCESS;\n}\n\n/* Associate user data */\nPJ_DEF(pj_status_t) pj_stun_sock_set_user_data( pj_stun_sock *stun_sock,\n\t\t\t\t\t        void *user_data)\n{\n    PJ_ASSERT_RETURN(stun_sock, PJ_EINVAL);\n    stun_sock->user_data = user_data;\n    return PJ_SUCCESS;\n}\n\n\n/* Get user data */\nPJ_DEF(void*) pj_stun_sock_get_user_data(pj_stun_sock *stun_sock)\n{\n    PJ_ASSERT_RETURN(stun_sock, NULL);\n    return stun_sock->user_data;\n}\n\n/* Get group lock */\nPJ_DECL(pj_grp_lock_t *) pj_stun_sock_get_grp_lock(pj_stun_sock *stun_sock)\n{\n    PJ_ASSERT_RETURN(stun_sock, NULL);\n    return stun_sock->grp_lock;\n}\n\n/* Notify application that session has failed */\nstatic pj_bool_t sess_fail(pj_stun_sock *stun_sock, \n\t\t\t   pj_stun_sock_op op,\n\t\t\t   pj_status_t status)\n{\n    pj_bool_t ret;\n\n    PJ_PERROR(4,(stun_sock->obj_name, status, \n\t         \"Session failed because %s failed\",\n\t\t pj_stun_sock_op_name(op)));\n\n    ret = (*stun_sock->cb.on_status)(stun_sock, op, status);\n\n    return ret;\n}\n\n/* DNS resolver callback */\nstatic void dns_srv_resolver_cb(void *user_data,\n\t\t\t\tpj_status_t status,\n\t\t\t\tconst pj_dns_srv_record *rec)\n{\n    pj_stun_sock *stun_sock = (pj_stun_sock*) user_data;\n\n    pj_grp_lock_acquire(stun_sock->grp_lock);\n\n    /* Clear query */\n    stun_sock->q = NULL;\n\n    /* Handle error */\n    if (status != PJ_SUCCESS) {\n\tsess_fail(stun_sock, PJ_STUN_SOCK_DNS_OP, status);\n\tpj_grp_lock_release(stun_sock->grp_lock);\n\treturn;\n    }\n\n    pj_assert(rec->count);\n    pj_assert(rec->entry[0].server.addr_count);\n\n    PJ_TODO(SUPPORT_IPV6_IN_RESOLVER);\n    pj_assert(stun_sock->af == pj_AF_INET());\n\n    /* Set the address */\n    pj_sockaddr_in_init(&stun_sock->srv_addr.ipv4, NULL,\n\t\t\trec->entry[0].port);\n    stun_sock->srv_addr.ipv4.sin_addr = rec->entry[0].server.addr[0];\n\n    /* Start sending Binding request */\n    get_mapped_addr(stun_sock);\n\n    pj_grp_lock_release(stun_sock->grp_lock);\n}\n\n\n/* Start sending STUN Binding request */\nstatic pj_status_t get_mapped_addr(pj_stun_sock *stun_sock)\n{\n    pj_stun_tx_data *tdata;\n    pj_status_t status;\n\n    /* Increment request counter and create STUN Binding request */\n    ++stun_sock->tsx_id[5];\n    status = pj_stun_session_create_req(stun_sock->stun_sess,\n\t\t\t\t\tPJ_STUN_BINDING_REQUEST,\n\t\t\t\t\tPJ_STUN_MAGIC, \n\t\t\t\t\t(const pj_uint8_t*)stun_sock->tsx_id, \n\t\t\t\t\t&tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n    \n    /* Send request */\n    status=pj_stun_session_send_msg(stun_sock->stun_sess, INTERNAL_MSG_TOKEN,\n\t\t\t\t    PJ_FALSE, PJ_TRUE, &stun_sock->srv_addr,\n\t\t\t\t    pj_sockaddr_get_len(&stun_sock->srv_addr),\n\t\t\t\t    tdata);\n    if (status != PJ_SUCCESS && status != PJ_EPENDING)\n\tgoto on_error;\n\n    return PJ_SUCCESS;\n\non_error:\n    sess_fail(stun_sock, PJ_STUN_SOCK_BINDING_OP, status);\n    return status;\n}\n\n/* Get info */\nPJ_DEF(pj_status_t) pj_stun_sock_get_info( pj_stun_sock *stun_sock,\n\t\t\t\t\t   pj_stun_sock_info *info)\n{\n    int addr_len;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(stun_sock && info, PJ_EINVAL);\n\n    pj_grp_lock_acquire(stun_sock->grp_lock);\n\n    /* Copy STUN server address and mapped address */\n    pj_memcpy(&info->srv_addr, &stun_sock->srv_addr,\n\t      sizeof(pj_sockaddr));\n    pj_memcpy(&info->mapped_addr, &stun_sock->mapped_addr, \n\t      sizeof(pj_sockaddr));\n\n    /* Retrieve bound address */\n    addr_len = sizeof(info->bound_addr);\n    status = pj_sock_getsockname(stun_sock->sock_fd, &info->bound_addr,\n\t\t\t\t &addr_len);\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_release(stun_sock->grp_lock);\n\treturn status;\n    }\n\n    /* If socket is bound to a specific interface, then only put that\n     * interface in the alias list. Otherwise query all the interfaces \n     * in the host.\n     */\n    if (pj_sockaddr_has_addr(&info->bound_addr)) {\n\tinfo->alias_cnt = 1;\n\tpj_sockaddr_cp(&info->aliases[0], &info->bound_addr);\n    } else {\n\tpj_sockaddr def_addr;\n\tpj_uint16_t port = pj_sockaddr_get_port(&info->bound_addr); \n\tunsigned i;\n\n\t/* Get the default address */\n\tstatus = pj_gethostip(stun_sock->af, &def_addr);\n\tif (status != PJ_SUCCESS) {\n\t    pj_grp_lock_release(stun_sock->grp_lock);\n\t    return status;\n\t}\n\t\n\tpj_sockaddr_set_port(&def_addr, port);\n\t\n\t/* Enum all IP interfaces in the host */\n\tinfo->alias_cnt = PJ_ARRAY_SIZE(info->aliases);\n\tstatus = pj_enum_ip_interface(stun_sock->af, &info->alias_cnt, \n\t\t\t\t      info->aliases);\n\tif (status != PJ_SUCCESS) {\n\t    pj_grp_lock_release(stun_sock->grp_lock);\n\t    return status;\n\t}\n\n\t/* Set the port number for each address.\n\t */\n\tfor (i=0; i<info->alias_cnt; ++i) {\n\t    pj_sockaddr_set_port(&info->aliases[i], port);\n\t}\n\n\t/* Put the default IP in the first slot */\n\tfor (i=0; i<info->alias_cnt; ++i) {\n\t    if (pj_sockaddr_cmp(&info->aliases[i], &def_addr)==0) {\n\t\tif (i!=0) {\n\t\t    pj_sockaddr_cp(&info->aliases[i], &info->aliases[0]);\n\t\t    pj_sockaddr_cp(&info->aliases[0], &def_addr);\n\t\t}\n\t\tbreak;\n\t    }\n\t}\n    }\n\n    pj_grp_lock_release(stun_sock->grp_lock);\n    return PJ_SUCCESS;\n}\n\n/* Send application data */\nPJ_DEF(pj_status_t) pj_stun_sock_sendto( pj_stun_sock *stun_sock,\n\t\t\t\t\t pj_ioqueue_op_key_t *send_key,\n\t\t\t\t\t const void *pkt,\n\t\t\t\t\t unsigned pkt_len,\n\t\t\t\t\t unsigned flag,\n\t\t\t\t\t const pj_sockaddr_t *dst_addr,\n\t\t\t\t\t unsigned addr_len)\n{\n    pj_ssize_t size;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(stun_sock && pkt && dst_addr && addr_len, PJ_EINVAL);\n    \n    pj_grp_lock_acquire(stun_sock->grp_lock);\n\n    if (!stun_sock->active_sock) {\n\t/* We have been shutdown, but this callback may still get called\n\t * by retransmit timer.\n\t */\n\tpj_grp_lock_release(stun_sock->grp_lock);\n\treturn PJ_EINVALIDOP;\n    }\n\n    if (send_key==NULL)\n\tsend_key = &stun_sock->send_key;\n\n    size = pkt_len;\n    status = pj_activesock_sendto(stun_sock->active_sock, send_key,\n                                  pkt, &size, flag, dst_addr, addr_len);\n\n    pj_grp_lock_release(stun_sock->grp_lock);\n    return status;\n}\n\n/* This callback is called by the STUN session to send packet */\nstatic pj_status_t sess_on_send_msg(pj_stun_session *sess,\n\t\t\t\t    void *token,\n\t\t\t\t    const void *pkt,\n\t\t\t\t    pj_size_t pkt_size,\n\t\t\t\t    const pj_sockaddr_t *dst_addr,\n\t\t\t\t    unsigned addr_len)\n{\n    pj_stun_sock *stun_sock;\n    pj_ssize_t size;\n\n    stun_sock = (pj_stun_sock *) pj_stun_session_get_user_data(sess);\n    if (!stun_sock || !stun_sock->active_sock) {\n\t/* We have been shutdown, but this callback may still get called\n\t * by retransmit timer.\n\t */\n\treturn PJ_EINVALIDOP;\n    }\n\n    pj_assert(token==INTERNAL_MSG_TOKEN);\n    PJ_UNUSED_ARG(token);\n\n    size = pkt_size;\n    return pj_activesock_sendto(stun_sock->active_sock,\n\t\t\t\t&stun_sock->int_send_key,\n\t\t\t\tpkt, &size, 0, dst_addr, addr_len);\n}\n\n/* This callback is called by the STUN session when outgoing transaction \n * is complete\n */\nstatic void sess_on_request_complete(pj_stun_session *sess,\n\t\t\t\t     pj_status_t status,\n\t\t\t\t     void *token,\n\t\t\t\t     pj_stun_tx_data *tdata,\n\t\t\t\t     const pj_stun_msg *response,\n\t\t\t\t     const pj_sockaddr_t *src_addr,\n\t\t\t\t     unsigned src_addr_len)\n{\n    pj_stun_sock *stun_sock;\n    const pj_stun_sockaddr_attr *mapped_attr;\n    pj_stun_sock_op op;\n    pj_bool_t mapped_changed;\n    pj_bool_t resched = PJ_TRUE;\n\n    stun_sock = (pj_stun_sock *) pj_stun_session_get_user_data(sess);\n    if (!stun_sock)\n\treturn;\n\n    PJ_UNUSED_ARG(tdata);\n    PJ_UNUSED_ARG(token);\n    PJ_UNUSED_ARG(src_addr);\n    PJ_UNUSED_ARG(src_addr_len);\n\n    /* Check if this is a keep-alive or the first Binding request */\n    if (pj_sockaddr_has_addr(&stun_sock->mapped_addr))\n\top = PJ_STUN_SOCK_KEEP_ALIVE_OP;\n    else\n\top = PJ_STUN_SOCK_BINDING_OP;\n\n    /* Handle failure */\n    if (status != PJ_SUCCESS) {\n\tresched = sess_fail(stun_sock, op, status);\n\tgoto on_return;\n    }\n\n    /* Get XOR-MAPPED-ADDRESS, or MAPPED-ADDRESS when XOR-MAPPED-ADDRESS\n     * doesn't exist.\n     */\n    mapped_attr = (const pj_stun_sockaddr_attr*)\n\t\t  pj_stun_msg_find_attr(response, PJ_STUN_ATTR_XOR_MAPPED_ADDR,\n\t\t\t\t\t0);\n    if (mapped_attr==NULL) {\n\tmapped_attr = (const pj_stun_sockaddr_attr*)\n\t\t      pj_stun_msg_find_attr(response, PJ_STUN_ATTR_MAPPED_ADDR,\n\t\t\t\t\t0);\n    }\n\n    if (mapped_attr == NULL) {\n\tresched = sess_fail(stun_sock, op, PJNATH_ESTUNNOMAPPEDADDR);\n\tgoto on_return;\n    }\n\n    /* Determine if mapped address has changed, and save the new mapped\n     * address and call callback if so \n     */\n    mapped_changed = !pj_sockaddr_has_addr(&stun_sock->mapped_addr) ||\n\t\t     pj_sockaddr_cmp(&stun_sock->mapped_addr, \n\t\t\t\t     &mapped_attr->sockaddr) != 0;\n    if (mapped_changed) {\n\t/* Print mapped adress */\n\t{\n\t    char addrinfo[PJ_INET6_ADDRSTRLEN+10];\n\t    PJ_LOG(4,(stun_sock->obj_name, \n\t\t      \"STUN mapped address found/changed: %s\",\n\t\t      pj_sockaddr_print(&mapped_attr->sockaddr,\n\t\t\t\t\taddrinfo, sizeof(addrinfo), 3)));\n\t}\n\n\tpj_sockaddr_cp(&stun_sock->mapped_addr, &mapped_attr->sockaddr);\n\n\tif (op==PJ_STUN_SOCK_KEEP_ALIVE_OP)\n\t    op = PJ_STUN_SOCK_MAPPED_ADDR_CHANGE;\n    }\n\n    /* Notify user */\n    resched = (*stun_sock->cb.on_status)(stun_sock, op, PJ_SUCCESS);\n\non_return:\n    /* Start/restart keep-alive timer */\n    if (resched)\n\tstart_ka_timer(stun_sock);\n}\n\n/* Schedule keep-alive timer */\nstatic void start_ka_timer(pj_stun_sock *stun_sock)\n{\n    pj_timer_heap_cancel_if_active(stun_sock->stun_cfg.timer_heap,\n                                   &stun_sock->ka_timer, 0);\n\n    pj_assert(stun_sock->ka_interval != 0);\n    if (stun_sock->ka_interval > 0 && !stun_sock->is_destroying) {\n\tpj_time_val delay;\n\n\tdelay.sec = stun_sock->ka_interval;\n\tdelay.msec = 0;\n\n\tpj_timer_heap_schedule_w_grp_lock(stun_sock->stun_cfg.timer_heap,\n\t                                  &stun_sock->ka_timer,\n\t                                  &delay, PJ_TRUE,\n\t                                  stun_sock->grp_lock);\n    }\n}\n\n/* Keep-alive timer callback */\nstatic void ka_timer_cb(pj_timer_heap_t *th, pj_timer_entry *te)\n{\n    pj_stun_sock *stun_sock;\n\n    stun_sock = (pj_stun_sock *) te->user_data;\n\n    PJ_UNUSED_ARG(th);\n    pj_grp_lock_acquire(stun_sock->grp_lock);\n\n    /* Time to send STUN Binding request */\n    if (get_mapped_addr(stun_sock) != PJ_SUCCESS) {\n\tpj_grp_lock_release(stun_sock->grp_lock);\n\treturn;\n    }\n\n    /* Next keep-alive timer will be scheduled once the request\n     * is complete.\n     */\n    pj_grp_lock_release(stun_sock->grp_lock);\n}\n\n/* Callback from active socket when incoming packet is received */\nstatic pj_bool_t on_data_recvfrom(pj_activesock_t *asock,\n\t\t\t\t  void *data,\n\t\t\t\t  pj_size_t size,\n\t\t\t\t  const pj_sockaddr_t *src_addr,\n\t\t\t\t  int addr_len,\n\t\t\t\t  pj_status_t status)\n{\n    pj_stun_sock *stun_sock;\n    pj_stun_msg_hdr *hdr;\n    pj_uint16_t type;\n\n    stun_sock = (pj_stun_sock*) pj_activesock_get_user_data(asock);\n    if (!stun_sock)\n\treturn PJ_FALSE;\n\n    /* Log socket error */\n    if (status != PJ_SUCCESS) {\n\tPJ_PERROR(2,(stun_sock->obj_name, status, \"recvfrom() error\"));\n\treturn PJ_TRUE;\n    }\n\n    pj_grp_lock_acquire(stun_sock->grp_lock);\n\n    /* Check that this is STUN message */\n    status = pj_stun_msg_check((const pj_uint8_t*)data, size, \n    \t\t\t       PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET);\n    if (status != PJ_SUCCESS) {\n\t/* Not STUN -- give it to application */\n\tgoto process_app_data;\n    }\n\n    /* Treat packet as STUN header and copy the STUN message type.\n     * We don't want to access the type directly from the header\n     * since it may not be properly aligned.\n     */\n    hdr = (pj_stun_msg_hdr*) data;\n    pj_memcpy(&type, &hdr->type, 2);\n    type = pj_ntohs(type);\n\n    /* If the packet is a STUN Binding response and part of the\n     * transaction ID matches our internal ID, then this is\n     * our internal STUN message (Binding request or keep alive).\n     * Give it to our STUN session.\n     */\n    if (!PJ_STUN_IS_RESPONSE(type) ||\n\tPJ_STUN_GET_METHOD(type) != PJ_STUN_BINDING_METHOD ||\n\tpj_memcmp(hdr->tsx_id, stun_sock->tsx_id, 10) != 0) \n    {\n\t/* Not STUN Binding response, or STUN transaction ID mismatch.\n\t * This is not our message too -- give it to application.\n\t */\n\tgoto process_app_data;\n    }\n\n    /* This is our STUN Binding response. Give it to the STUN session */\n    status = pj_stun_session_on_rx_pkt(stun_sock->stun_sess, data, size,\n\t\t\t\t       PJ_STUN_IS_DATAGRAM, NULL, NULL,\n\t\t\t\t       src_addr, addr_len);\n\n    status = pj_grp_lock_release(stun_sock->grp_lock);\n\n    return status!=PJ_EGONE ? PJ_TRUE : PJ_FALSE;\n\nprocess_app_data:\n    if (stun_sock->cb.on_rx_data) {\n\t(*stun_sock->cb.on_rx_data)(stun_sock, data, (unsigned)size,\n\t\t\t\t    src_addr, addr_len);\n\tstatus = pj_grp_lock_release(stun_sock->grp_lock);\n\treturn status!=PJ_EGONE ? PJ_TRUE : PJ_FALSE;\n    }\n\n    status = pj_grp_lock_release(stun_sock->grp_lock);\n    return status!=PJ_EGONE ? PJ_TRUE : PJ_FALSE;\n}\n\n/* Callback from active socket about send status */\nstatic pj_bool_t on_data_sent(pj_activesock_t *asock,\n\t\t\t      pj_ioqueue_op_key_t *send_key,\n\t\t\t      pj_ssize_t sent)\n{\n    pj_stun_sock *stun_sock;\n\n    stun_sock = (pj_stun_sock*) pj_activesock_get_user_data(asock);\n    if (!stun_sock)\n\treturn PJ_FALSE;\n\n    /* Don't report to callback if this is internal message */\n    if (send_key == &stun_sock->int_send_key) {\n\treturn PJ_TRUE;\n    }\n\n    /* Report to callback */\n    if (stun_sock->cb.on_data_sent) {\n\tpj_bool_t ret;\n\n\tpj_grp_lock_acquire(stun_sock->grp_lock);\n\n\t/* If app gives NULL send_key in sendto() function, then give\n\t * NULL in the callback too \n\t */\n\tif (send_key == &stun_sock->send_key)\n\t    send_key = NULL;\n\n\t/* Call callback */\n\tret = (*stun_sock->cb.on_data_sent)(stun_sock, send_key, sent);\n\n\tpj_grp_lock_release(stun_sock->grp_lock);\n\treturn ret;\n    }\n\n    return PJ_TRUE;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjnath/stun_transaction.c",
    "content": "/* $Id: stun_transaction.c 4413 2013-03-05 06:29:15Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjnath/stun_transaction.h>\n#include <pjnath/errno.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/timer.h>\n\n\n#define THIS_FILE\t\t\"stun_transaction.c\"\n#define TIMER_INACTIVE\t\t0\n#define TIMER_ACTIVE\t\t1\n\n\nstruct pj_stun_client_tsx\n{\n    char\t\t obj_name[PJ_MAX_OBJ_NAME];\n    pj_stun_tsx_cb\t cb;\n    void\t\t*user_data;\n    pj_grp_lock_t\t*grp_lock;\n\n    pj_bool_t\t\t complete;\n\n    pj_bool_t\t\t require_retransmit;\n    unsigned\t\t rto_msec;\n    pj_timer_entry\t retransmit_timer;\n    unsigned\t\t transmit_count;\n    pj_time_val\t\t retransmit_time;\n    pj_timer_heap_t\t*timer_heap;\n\n    pj_timer_entry\t destroy_timer;\n\n    void\t\t*last_pkt;\n    unsigned\t\t last_pkt_size;\n};\n\n\n#if 1\n#   define TRACE_(expr)\t\t    PJ_LOG(5,expr)\n#else\n#   define TRACE_(expr)\n#endif\n\n\nstatic void retransmit_timer_callback(pj_timer_heap_t *timer_heap, \n\t\t\t\t      pj_timer_entry *timer);\nstatic void destroy_timer_callback(pj_timer_heap_t *timer_heap, \n\t\t\t\t   pj_timer_entry *timer);\n\n/*\n * Create a STUN client transaction.\n */\nPJ_DEF(pj_status_t) pj_stun_client_tsx_create(pj_stun_config *cfg,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      pj_grp_lock_t *grp_lock,\n\t\t\t\t\t      const pj_stun_tsx_cb *cb,\n\t\t\t\t\t      pj_stun_client_tsx **p_tsx)\n{\n    pj_stun_client_tsx *tsx;\n\n    PJ_ASSERT_RETURN(cfg && cb && p_tsx, PJ_EINVAL);\n    PJ_ASSERT_RETURN(cb->on_send_msg, PJ_EINVAL);\n\n    tsx = PJ_POOL_ZALLOC_T(pool, pj_stun_client_tsx);\n    tsx->rto_msec = cfg->rto_msec;\n    tsx->timer_heap = cfg->timer_heap;\n    tsx->grp_lock = grp_lock;\n    pj_memcpy(&tsx->cb, cb, sizeof(*cb));\n\n    tsx->retransmit_timer.cb = &retransmit_timer_callback;\n    tsx->retransmit_timer.user_data = tsx;\n\n    tsx->destroy_timer.cb = &destroy_timer_callback;\n    tsx->destroy_timer.user_data = tsx;\n\n    pj_ansi_snprintf(tsx->obj_name, sizeof(tsx->obj_name), \"utsx%p\", tsx);\n\n    *p_tsx = tsx;\n\n    PJ_LOG(5,(tsx->obj_name, \"STUN client transaction created\"));\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_stun_client_tsx_schedule_destroy(\n\t\t\t\t    pj_stun_client_tsx *tsx,\n\t\t\t\t    const pj_time_val *delay)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(tsx && delay, PJ_EINVAL);\n    PJ_ASSERT_RETURN(tsx->cb.on_destroy, PJ_EINVAL);\n\n    pj_grp_lock_acquire(tsx->grp_lock);\n\n    /* Cancel previously registered timer */\n    pj_timer_heap_cancel_if_active(tsx->timer_heap, &tsx->destroy_timer,\n                                   TIMER_INACTIVE);\n\n    /* Stop retransmission, just in case */\n    pj_timer_heap_cancel_if_active(tsx->timer_heap, &tsx->retransmit_timer,\n                                   TIMER_INACTIVE);\n\n    status = pj_timer_heap_schedule_w_grp_lock(tsx->timer_heap,\n                                               &tsx->destroy_timer, delay,\n                                               TIMER_ACTIVE, tsx->grp_lock);\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_release(tsx->grp_lock);\n\treturn status;\n    }\n\n    tsx->cb.on_complete = NULL;\n\n    pj_grp_lock_release(tsx->grp_lock);\n\n    TRACE_((tsx->obj_name, \"STUN transaction %p schedule destroy\", tsx));\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pj_stun_client_tsx_destroy(pj_stun_client_tsx *tsx)\n{\n    /*\n     * Currently tsx has no objects to destroy so we don't need to do anything\n     * here.\n     */\n    /* pj_stun_client_tsx_stop(tsx); */\n    PJ_UNUSED_ARG(tsx);\n    return PJ_SUCCESS;\n}\n\n/*\n * Destroy transaction immediately.\n */\nPJ_DEF(pj_status_t) pj_stun_client_tsx_stop(pj_stun_client_tsx *tsx)\n{\n    PJ_ASSERT_RETURN(tsx, PJ_EINVAL);\n\n    /* Don't call grp_lock_acquire() because we might be called on\n     * group lock's destructor.\n     */\n    pj_timer_heap_cancel_if_active(tsx->timer_heap, &tsx->retransmit_timer,\n                                   TIMER_INACTIVE);\n    pj_timer_heap_cancel_if_active(tsx->timer_heap, &tsx->destroy_timer,\n                                   TIMER_INACTIVE);\n\n    PJ_LOG(5,(tsx->obj_name, \"STUN client transaction %p stopped, ref_cnt=%d\",\n\t      tsx, pj_grp_lock_get_ref(tsx->grp_lock)));\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Check if transaction has completed.\n */\nPJ_DEF(pj_bool_t) pj_stun_client_tsx_is_complete(pj_stun_client_tsx *tsx)\n{\n    PJ_ASSERT_RETURN(tsx, PJ_FALSE);\n    return tsx->complete;\n}\n\n\n/*\n * Set user data.\n */\nPJ_DEF(pj_status_t) pj_stun_client_tsx_set_data(pj_stun_client_tsx *tsx,\n\t\t\t\t\t\tvoid *data)\n{\n    PJ_ASSERT_RETURN(tsx, PJ_EINVAL);\n    tsx->user_data = data;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the user data\n */\nPJ_DEF(void*) pj_stun_client_tsx_get_data(pj_stun_client_tsx *tsx)\n{\n    PJ_ASSERT_RETURN(tsx, NULL);\n    return tsx->user_data;\n}\n\n\n/*\n * Transmit message.\n */\nstatic pj_status_t tsx_transmit_msg(pj_stun_client_tsx *tsx,\n                                    pj_bool_t mod_count)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(tsx->retransmit_timer.id == TIMER_INACTIVE ||\n\t\t     !tsx->require_retransmit || !mod_count, PJ_EBUSY);\n\n    if (tsx->require_retransmit && mod_count) {\n\t/* Calculate retransmit/timeout delay */\n\tif (tsx->transmit_count == 0) {\n\t    tsx->retransmit_time.sec = 0;\n\t    tsx->retransmit_time.msec = tsx->rto_msec;\n\n\t} else if (tsx->transmit_count < PJ_STUN_MAX_TRANSMIT_COUNT-1) {\n\t    unsigned msec;\n\n\t    msec = PJ_TIME_VAL_MSEC(tsx->retransmit_time);\n\t    msec <<= 1;\n\t    tsx->retransmit_time.sec = msec / 1000;\n\t    tsx->retransmit_time.msec = msec % 1000;\n\n\t} else {\n\t    tsx->retransmit_time.sec = PJ_STUN_TIMEOUT_VALUE / 1000;\n\t    tsx->retransmit_time.msec = PJ_STUN_TIMEOUT_VALUE % 1000;\n\t}\n\n\t/* Schedule timer first because when send_msg() failed we can\n\t * cancel it (as opposed to when schedule_timer() failed we cannot\n\t * cancel transmission).\n\t */;\n\tstatus = pj_timer_heap_schedule_w_grp_lock(tsx->timer_heap,\n\t\t\t\t\t\t   &tsx->retransmit_timer,\n\t\t\t\t\t\t   &tsx->retransmit_time,\n\t\t\t\t\t\t   TIMER_ACTIVE,\n\t\t\t\t\t\t   tsx->grp_lock);\n\tif (status != PJ_SUCCESS) {\n\t    tsx->retransmit_timer.id = TIMER_INACTIVE;\n\t    return status;\n\t}\n    }\n\n\n    if (mod_count)\n        tsx->transmit_count++;\n\n    PJ_LOG(5,(tsx->obj_name, \"STUN sending message (transmit count=%d)\",\n\t      tsx->transmit_count));\n    pj_log_push_indent();\n\n    /* Send message */\n    status = tsx->cb.on_send_msg(tsx, tsx->last_pkt, tsx->last_pkt_size);\n\n    if (status == PJNATH_ESTUNDESTROYED) {\n\t/* We've been destroyed, don't access the object. */\n    } else if (status != PJ_SUCCESS) {\n\tif (mod_count || status == PJ_EINVALIDOP) {\n\t\tpj_timer_heap_cancel_if_active( tsx->timer_heap,\n\t                               \t\t&tsx->retransmit_timer,\n\t                               \t\tTIMER_INACTIVE);\n\t}\n\tPJ_PERROR(4, (tsx->obj_name, status, \"STUN error sending message\"));\n    }\n\n    pj_log_pop_indent();\n    return status;\n}\n\n\n/*\n * Send outgoing message and start STUN transaction.\n */\nPJ_DEF(pj_status_t) pj_stun_client_tsx_send_msg(pj_stun_client_tsx *tsx,\n\t\t\t\t\t\tpj_bool_t retransmit,\n\t\t\t\t\t\tvoid *pkt,\n\t\t\t\t\t\tunsigned pkt_len)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(tsx && pkt && pkt_len, PJ_EINVAL);\n    PJ_ASSERT_RETURN(tsx->retransmit_timer.id == 0, PJ_EBUSY);\n\n    pj_grp_lock_acquire(tsx->grp_lock);\n\n    /* Encode message */\n    tsx->last_pkt = pkt;\n    tsx->last_pkt_size = pkt_len;\n\n    /* Update STUN retransmit flag */\n    tsx->require_retransmit = retransmit;\n\n    /* For TCP, schedule timeout timer after PJ_STUN_TIMEOUT_VALUE.\n     * Since we don't have timeout timer, simulate this by using\n     * retransmit timer.\n     */\n    if (!retransmit) {\n\tunsigned timeout;\n\n\tpj_assert(tsx->retransmit_timer.id == 0);\n\ttsx->transmit_count = PJ_STUN_MAX_TRANSMIT_COUNT;\n\n\ttimeout = tsx->rto_msec * 16;\n\ttsx->retransmit_time.sec = timeout / 1000;\n\ttsx->retransmit_time.msec = timeout % 1000;\n\n\t/* Schedule timer first because when send_msg() failed we can\n\t * cancel it (as opposed to when schedule_timer() failed we cannot\n\t * cancel transmission).\n\t */;\n\tstatus = pj_timer_heap_schedule_w_grp_lock(tsx->timer_heap,\n\t                                           &tsx->retransmit_timer,\n\t                                           &tsx->retransmit_time,\n\t                                           TIMER_ACTIVE,\n\t                                           tsx->grp_lock);\n\tif (status != PJ_SUCCESS) {\n\t    tsx->retransmit_timer.id = TIMER_INACTIVE;\n\t    pj_grp_lock_release(tsx->grp_lock);\n\t    return status;\n\t}\n    }\n\n    /* Send the message */\n    status = tsx_transmit_msg(tsx, PJ_TRUE);\n    if (status != PJ_SUCCESS) {\n\tpj_timer_heap_cancel_if_active(tsx->timer_heap,\n\t                               &tsx->retransmit_timer,\n\t                               TIMER_INACTIVE);\n\tpj_grp_lock_release(tsx->grp_lock);\n\treturn status;\n    }\n\n    pj_grp_lock_release(tsx->grp_lock);\n    return PJ_SUCCESS;\n}\n\n\n/* Retransmit timer callback */\nstatic void retransmit_timer_callback(pj_timer_heap_t *timer_heap, \n\t\t\t\t      pj_timer_entry *timer)\n{\n    pj_stun_client_tsx *tsx = (pj_stun_client_tsx *) timer->user_data;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(timer_heap);\n    pj_grp_lock_acquire(tsx->grp_lock);\n\n    if (tsx->transmit_count >= PJ_STUN_MAX_TRANSMIT_COUNT) {\n        /* tsx may be destroyed when calling the callback below */\n        pj_grp_lock_t *grp_lock = tsx->grp_lock;\n\n\t/* Retransmission count exceeded. Transaction has failed */\n\ttsx->retransmit_timer.id = 0;\n\tPJ_LOG(4,(tsx->obj_name, \"STUN timeout waiting for response\"));\n\tpj_log_push_indent();\n\tif (!tsx->complete) {\n\t    tsx->complete = PJ_TRUE;\n\t    if (tsx->cb.on_complete) {\n\t\ttsx->cb.on_complete(tsx, PJNATH_ESTUNTIMEDOUT, NULL, NULL, 0);\n\t    }\n\t}\n\tpj_grp_lock_release(grp_lock);\n\t/* We might have been destroyed, don't try to access the object */\n\tpj_log_pop_indent();\n\treturn;\n    }\n\n    tsx->retransmit_timer.id = 0;\n    status = tsx_transmit_msg(tsx, PJ_TRUE);\n    if (status != PJ_SUCCESS) {\n\ttsx->retransmit_timer.id = 0;\n\tif (!tsx->complete) {\n\t    tsx->complete = PJ_TRUE;\n\t    if (tsx->cb.on_complete) {\n\t\ttsx->cb.on_complete(tsx, status, NULL, NULL, 0);\n\t    }\n\t}\n    }\n\n    pj_grp_lock_release(tsx->grp_lock);\n    /* We might have been destroyed, don't try to access the object */\n}\n\n/*\n * Request to retransmit the request.\n */\nPJ_DEF(pj_status_t) pj_stun_client_tsx_retransmit(pj_stun_client_tsx *tsx,\n                                                  pj_bool_t mod_count)\n{\n    if (tsx->destroy_timer.id != 0) {\n\treturn PJ_SUCCESS;\n    }\n\n    if (mod_count) {\n        pj_timer_heap_cancel_if_active(tsx->timer_heap, &tsx->retransmit_timer,\n                                       TIMER_INACTIVE);\n    }\n\n    return tsx_transmit_msg(tsx, mod_count);\n}\n\n/* Timer callback to destroy transaction */\nstatic void destroy_timer_callback(pj_timer_heap_t *timer_heap, \n\t\t\t\t   pj_timer_entry *timer)\n{\n    pj_stun_client_tsx *tsx = (pj_stun_client_tsx *) timer->user_data;\n\n    PJ_UNUSED_ARG(timer_heap);\n\n    tsx->destroy_timer.id = PJ_FALSE;\n\n    tsx->cb.on_destroy(tsx);\n    /* Don't access transaction after this */\n}\n\n\n/*\n * Notify the STUN transaction about the arrival of STUN response.\n */\nPJ_DEF(pj_status_t) pj_stun_client_tsx_on_rx_msg(pj_stun_client_tsx *tsx,\n\t\t\t\t\t\t const pj_stun_msg *msg,\n\t\t\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t\t\t unsigned src_addr_len)\n{\n    pj_stun_errcode_attr *err_attr;\n    pj_status_t status;\n\n    /* Must be STUN response message */\n    if (!PJ_STUN_IS_SUCCESS_RESPONSE(msg->hdr.type) && \n\t!PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type))\n    {\n\tPJ_LOG(4,(tsx->obj_name, \n\t\t  \"STUN rx_msg() error: not response message\"));\n\treturn PJNATH_EINSTUNMSGTYPE;\n    }\n\n\n    /* We have a response with matching transaction ID. \n     * We can cancel retransmit timer now.\n     */\n    pj_timer_heap_cancel_if_active(tsx->timer_heap, &tsx->retransmit_timer,\n                                   TIMER_INACTIVE);\n\n    /* Find STUN error code attribute */\n    err_attr = (pj_stun_errcode_attr*) \n\t\tpj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ERROR_CODE, 0);\n\n    if (err_attr && err_attr->err_code <= 200) {\n\t/* draft-ietf-behave-rfc3489bis-05.txt Section 8.3.2:\n\t * Any response between 100 and 299 MUST result in the cessation\n\t * of request retransmissions, but otherwise is discarded.\n\t */\n\tPJ_LOG(4,(tsx->obj_name, \n\t\t  \"STUN rx_msg() error: received provisional %d code (%.*s)\",\n\t\t  err_attr->err_code,\n\t\t  (int)err_attr->reason.slen,\n\t\t  err_attr->reason.ptr));\n\treturn PJ_SUCCESS;\n    }\n\n    if (err_attr == NULL) {\n\tstatus = PJ_SUCCESS;\n    } else {\n\tstatus = PJ_STATUS_FROM_STUN_CODE(err_attr->err_code);\n    }\n\n    /* Call callback */\n    if (!tsx->complete) {\n\ttsx->complete = PJ_TRUE;\n\tif (tsx->cb.on_complete) {\n\t    tsx->cb.on_complete(tsx, status, msg, src_addr, src_addr_len);\n\t}\n\t/* We might have been destroyed, don't try to access the object */\n    }\n\n    return PJ_SUCCESS;\n\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjnath/turn_session.c",
    "content": "/* $Id: turn_session.c 4368 2013-02-21 21:53:28Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjnath/turn_session.h>\n#include <pjnath/errno.h>\n#include <pjlib-util/srv_resolver.h>\n#include <pj/addr_resolv.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/hash.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/sock.h>\n\n#define PJ_TURN_CHANNEL_MIN\t    0x4000\n#define PJ_TURN_CHANNEL_MAX\t    0x7FFF  /* inclusive */\n#define PJ_TURN_CHANNEL_HTABLE_SIZE 8\n#define PJ_TURN_PERM_HTABLE_SIZE    8\n\nstatic const char *state_names[] = \n{\n    \"Null\",\n    \"Resolving\",\n    \"Resolved\",\n    \"Allocating\",\n    \"Ready\",\n    \"Deallocating\",\n    \"Deallocated\",\n    \"Destroying\"\n};\n\nenum timer_id_t\n{\n    TIMER_NONE,\n    TIMER_KEEP_ALIVE,\n    TIMER_DESTROY\n};\n\n/* This structure describes a channel binding. A channel binding is index by\n * the channel number or IP address and port number of the peer.\n */\nstruct ch_t\n{\n    /* The channel number */\n    pj_uint16_t\t    num;\n\n    /* PJ_TRUE if we've received successful response to ChannelBind request\n     * for this channel.\n     */\n    pj_bool_t\t    bound;\n\n    /* The peer IP address and port */\n    pj_sockaddr\t    addr;\n\n    /* The channel binding expiration */\n    pj_time_val\t    expiry;\n};\n\n\n/* This structure describes a permission. A permission is identified by the\n * IP address only.\n */\nstruct perm_t\n{\n    /* Cache of hash value to speed-up lookup */\n    pj_uint32_t\t    hval;\n\n    /* The permission IP address. The port number MUST be zero */\n    pj_sockaddr\t    addr;\n\n    /* Number of peers that uses this permission. */\n    unsigned\t    peer_cnt;\n\n    /* Automatically renew this permission once it expires? */\n    pj_bool_t\t    renew;\n\n    /* The permission expiration */\n    pj_time_val\t    expiry;\n\n    /* Arbitrary/random pointer value (token) to map this perm with the \n     * request to create it. It is used to invalidate this perm when the \n     * request fails.\n     */\n    void\t   *req_token;\n};\n\n\n/* The TURN client session structure */\nstruct pj_turn_session\n{\n    pj_pool_t\t\t*pool;\n    const char\t\t*obj_name;\n    pj_turn_session_cb\t cb;\n    void\t\t*user_data;\n    pj_stun_config\t stun_cfg;\n    pj_bool_t\t\t is_destroying;\n\n    pj_grp_lock_t\t*grp_lock;\n    int\t\t\t busy;\n\n    pj_turn_state_t\t state;\n    pj_status_t\t\t last_status;\n    pj_bool_t\t\t pending_destroy;\n\n    pj_stun_session\t*stun;\n\n    unsigned\t\t lifetime;\n    int\t\t\t ka_interval;\n    pj_time_val\t\t expiry;\n\n    pj_timer_heap_t\t*timer_heap;\n    pj_timer_entry\t timer;\n\n    pj_uint16_t\t\t default_port;\n\n    pj_uint16_t\t\t af;\n    pj_turn_tp_type\t conn_type;\n    pj_uint16_t\t\t srv_addr_cnt;\n    pj_sockaddr\t\t*srv_addr_list;\n    pj_sockaddr\t\t*srv_addr;\n\n    pj_bool_t\t\t pending_alloc;\n    pj_turn_alloc_param\t alloc_param;\n\n    pj_sockaddr\t\t mapped_addr;\n    pj_sockaddr\t\t relay_addr;\n\n    pj_hash_table_t\t*ch_table;\n    pj_hash_table_t\t*perm_table;\n\n    pj_uint32_t\t\t send_ind_tsx_id[3];\n    /* tx_pkt must be 16bit aligned */\n    pj_uint8_t\t\t tx_pkt[PJ_TURN_MAX_PKT_LEN];\n\n    pj_uint16_t\t\t next_ch;\n};\n\n\n/*\n * Prototypes.\n */\nstatic void sess_shutdown(pj_turn_session *sess,\n\t\t\t  pj_status_t status);\nstatic void turn_sess_on_destroy(void *comp);\nstatic void do_destroy(pj_turn_session *sess);\nstatic void send_refresh(pj_turn_session *sess, int lifetime);\nstatic pj_status_t stun_on_send_msg(pj_stun_session *sess,\n\t\t\t\t    void *token,\n\t\t\t\t    const void *pkt,\n\t\t\t\t    pj_size_t pkt_size,\n\t\t\t\t    const pj_sockaddr_t *dst_addr,\n\t\t\t\t    unsigned addr_len);\nstatic void stun_on_request_complete(pj_stun_session *sess,\n\t\t\t\t     pj_status_t status,\n\t\t\t\t     void *token,\n\t\t\t\t     pj_stun_tx_data *tdata,\n\t\t\t\t     const pj_stun_msg *response,\n\t\t\t\t     const pj_sockaddr_t *src_addr,\n\t\t\t\t     unsigned src_addr_len);\nstatic pj_status_t stun_on_rx_indication(pj_stun_session *sess,\n\t\t\t\t\t const pj_uint8_t *pkt,\n\t\t\t\t\t unsigned pkt_len,\n\t\t\t\t\t const pj_stun_msg *msg,\n\t\t\t\t\t void *token,\n\t\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t\t unsigned src_addr_len);\nstatic void dns_srv_resolver_cb(void *user_data,\n\t\t\t\tpj_status_t status,\n\t\t\t\tconst pj_dns_srv_record *rec);\nstatic struct ch_t *lookup_ch_by_addr(pj_turn_session *sess,\n\t\t\t\t      const pj_sockaddr_t *addr,\n\t\t\t\t      unsigned addr_len,\n\t\t\t\t      pj_bool_t update,\n\t\t\t\t      pj_bool_t bind_channel);\nstatic struct ch_t *lookup_ch_by_chnum(pj_turn_session *sess,\n\t\t\t\t       pj_uint16_t chnum);\nstatic struct perm_t *lookup_perm(pj_turn_session *sess,\n\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t  unsigned addr_len,\n\t\t\t\t  pj_bool_t update);\nstatic void invalidate_perm(pj_turn_session *sess,\n\t\t\t    struct perm_t *perm);\nstatic void on_timer_event(pj_timer_heap_t *th, pj_timer_entry *e);\n\n\n/*\n * Create default pj_turn_alloc_param.\n */\nPJ_DEF(void) pj_turn_alloc_param_default(pj_turn_alloc_param *prm)\n{\n    pj_bzero(prm, sizeof(*prm));\n}\n\n/*\n * Duplicate pj_turn_alloc_param.\n */\nPJ_DEF(void) pj_turn_alloc_param_copy( pj_pool_t *pool, \n\t\t\t\t       pj_turn_alloc_param *dst,\n\t\t\t\t       const pj_turn_alloc_param *src)\n{\n    PJ_UNUSED_ARG(pool);\n    pj_memcpy(dst, src, sizeof(*dst));\n}\n\n/*\n * Get TURN state name.\n */\nPJ_DEF(const char*) pj_turn_state_name(pj_turn_state_t state)\n{\n    return state_names[state];\n}\n\n/*\n * Create TURN client session.\n */\nPJ_DEF(pj_status_t) pj_turn_session_create( const pj_stun_config *cfg,\n\t\t\t\t\t    const char *name,\n\t\t\t\t\t    int af,\n\t\t\t\t\t    pj_turn_tp_type conn_type,\n\t\t\t\t\t    pj_grp_lock_t *grp_lock,\n\t\t\t\t\t    const pj_turn_session_cb *cb,\n\t\t\t\t\t    unsigned options,\n\t\t\t\t\t    void *user_data,\n\t\t\t\t\t    pj_turn_session **p_sess)\n{\n    pj_pool_t *pool;\n    pj_turn_session *sess;\n    pj_stun_session_cb stun_cb;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(cfg && cfg->pf && cb && p_sess, PJ_EINVAL);\n    PJ_ASSERT_RETURN(cb->on_send_pkt, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(options);\n\n    if (name == NULL)\n\tname = \"turn%p\";\n\n    /* Allocate and create TURN session */\n    pool = pj_pool_create(cfg->pf, name, PJNATH_POOL_LEN_TURN_SESS,\n\t\t\t  PJNATH_POOL_INC_TURN_SESS, NULL);\n    sess = PJ_POOL_ZALLOC_T(pool, pj_turn_session);\n    sess->pool = pool;\n    sess->obj_name = pool->obj_name;\n    sess->timer_heap = cfg->timer_heap;\n    sess->af = (pj_uint16_t)af;\n    sess->conn_type = conn_type;\n    sess->ka_interval = PJ_TURN_KEEP_ALIVE_SEC;\n    sess->user_data = user_data;\n    sess->next_ch = PJ_TURN_CHANNEL_MIN;\n\n    /* Copy STUN session */\n    pj_memcpy(&sess->stun_cfg, cfg, sizeof(pj_stun_config));\n\n    /* Copy callback */\n    pj_memcpy(&sess->cb, cb, sizeof(*cb));\n\n    /* Peer hash table */\n    sess->ch_table = pj_hash_create(pool, PJ_TURN_CHANNEL_HTABLE_SIZE);\n\n    /* Permission hash table */\n    sess->perm_table = pj_hash_create(pool, PJ_TURN_PERM_HTABLE_SIZE);\n\n    /* Session lock */\n    if (grp_lock) {\n\tsess->grp_lock = grp_lock;\n    } else {\n\tstatus = pj_grp_lock_create(pool, NULL, &sess->grp_lock);\n\tif (status != PJ_SUCCESS) {\n\t    pj_pool_release(pool);\n\t    return status;\n\t}\n    }\n\n    pj_grp_lock_add_ref(sess->grp_lock);\n    pj_grp_lock_add_handler(sess->grp_lock, pool, sess,\n                            &turn_sess_on_destroy);\n\n    /* Timer */\n    pj_timer_entry_init(&sess->timer, TIMER_NONE, sess, &on_timer_event);\n\n    /* Create STUN session */\n    pj_bzero(&stun_cb, sizeof(stun_cb));\n    stun_cb.on_send_msg = &stun_on_send_msg;\n    stun_cb.on_request_complete = &stun_on_request_complete;\n    stun_cb.on_rx_indication = &stun_on_rx_indication;\n    status = pj_stun_session_create(&sess->stun_cfg, sess->obj_name, &stun_cb,\n\t\t\t\t    PJ_FALSE, sess->grp_lock, &sess->stun);\n    if (status != PJ_SUCCESS) {\n\tdo_destroy(sess);\n\treturn status;\n    }\n\n    /* Attach ourself to STUN session */\n    pj_stun_session_set_user_data(sess->stun, sess);\n\n    /* Done */\n\n    PJ_LOG(4,(sess->obj_name, \"TURN client session created\"));\n\n    *p_sess = sess;\n    return PJ_SUCCESS;\n}\n\n\nstatic void turn_sess_on_destroy(void *comp)\n{\n    pj_turn_session *sess = (pj_turn_session*) comp;\n\n    /* Destroy pool */\n    if (sess->pool) {\n\tpj_pool_t *pool = sess->pool;\n\n\tPJ_LOG(4,(sess->obj_name, \"TURN client session destroyed\"));\n\n\tsess->pool = NULL;\n\tpj_pool_release(pool);\n    }\n}\n\n/* Destroy */\nstatic void do_destroy(pj_turn_session *sess)\n{\n    PJ_LOG(4,(sess->obj_name, \"TURN session destroy request, ref_cnt=%d\",\n\t      pj_grp_lock_get_ref(sess->grp_lock)));\n\n    pj_grp_lock_acquire(sess->grp_lock);\n    if (sess->is_destroying) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn;\n    }\n\n    sess->is_destroying = PJ_TRUE;\n    pj_timer_heap_cancel_if_active(sess->timer_heap, &sess->timer, TIMER_NONE);\n    pj_stun_session_destroy(sess->stun);\n\n    pj_grp_lock_dec_ref(sess->grp_lock);\n    pj_grp_lock_release(sess->grp_lock);\n}\n\n\n/* Set session state */\nstatic void set_state(pj_turn_session *sess, enum pj_turn_state_t state)\n{\n    pj_turn_state_t old_state = sess->state;\n\n    if (state==sess->state)\n\treturn;\n\n    PJ_LOG(4,(sess->obj_name, \"State changed %s --> %s\",\n\t      state_names[old_state], state_names[state]));\n    sess->state = state;\n\n    if (sess->cb.on_state) {\n\t(*sess->cb.on_state)(sess, old_state, state);\n    }\n}\n\n/*\n * Notify application and shutdown the TURN session.\n */\nstatic void sess_shutdown(pj_turn_session *sess,\n\t\t\t  pj_status_t status)\n{\n    pj_bool_t can_destroy = PJ_TRUE;\n\n    PJ_LOG(4,(sess->obj_name, \"Request to shutdown in state %s, cause:%d\",\n\t      state_names[sess->state], status));\n\n    if (sess->last_status == PJ_SUCCESS && status != PJ_SUCCESS)\n\tsess->last_status = status;\n\n    switch (sess->state) {\n    case PJ_TURN_STATE_NULL:\n\tbreak;\n    case PJ_TURN_STATE_RESOLVING:\n\t/* Wait for DNS callback invoked, it will call the this function\n\t * again. If the callback happens to get pending_destroy==FALSE,\n\t * the TURN allocation will call this function again.\n\t */\n\tsess->pending_destroy = PJ_TRUE;\n\tcan_destroy = PJ_FALSE;\n\tbreak;\n    case PJ_TURN_STATE_RESOLVED:\n\tbreak;\n    case PJ_TURN_STATE_ALLOCATING:\n\t/* We need to wait until allocation complete */\n\tsess->pending_destroy = PJ_TRUE;\n\tcan_destroy = PJ_FALSE;\n\tbreak;\n    case PJ_TURN_STATE_READY:\n\t/* Send REFRESH with LIFETIME=0 */\n\tcan_destroy = PJ_FALSE;\n\tsend_refresh(sess, 0);\n\tbreak;\n    case PJ_TURN_STATE_DEALLOCATING:\n\tcan_destroy = PJ_FALSE;\n\t/* This may recursively call this function again with\n\t * state==PJ_TURN_STATE_DEALLOCATED.\n\t */\n\t/* No need to deallocate as we're already deallocating!\n\t * See https://trac.pjsip.org/repos/ticket/1551\n\tsend_refresh(sess, 0);\n\t*/\n\tbreak;\n    case PJ_TURN_STATE_DEALLOCATED:\n    case PJ_TURN_STATE_DESTROYING:\n\tbreak;\n    }\n\n    if (can_destroy) {\n\t/* Schedule destroy */\n\tpj_time_val delay = {0, 0};\n\n\tset_state(sess, PJ_TURN_STATE_DESTROYING);\n\n\tpj_timer_heap_cancel_if_active(sess->timer_heap, &sess->timer,\n\t                               TIMER_NONE);\n\tpj_timer_heap_schedule_w_grp_lock(sess->timer_heap, &sess->timer,\n\t                                  &delay, TIMER_DESTROY,\n\t                                  sess->grp_lock);\n    }\n}\n\n\n/*\n * Public API to destroy TURN client session.\n */\nPJ_DEF(pj_status_t) pj_turn_session_shutdown(pj_turn_session *sess)\n{\n    PJ_ASSERT_RETURN(sess, PJ_EINVAL);\n\n    pj_grp_lock_acquire(sess->grp_lock);\n\n    sess_shutdown(sess, PJ_SUCCESS);\n\n    pj_grp_lock_release(sess->grp_lock);\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Forcefully destroy the TURN session.\n */\nPJ_DEF(pj_status_t) pj_turn_session_destroy( pj_turn_session *sess,\n\t\t\t\t\t     pj_status_t last_err)\n{\n    PJ_ASSERT_RETURN(sess, PJ_EINVAL);\n\n    if (last_err != PJ_SUCCESS && sess->last_status == PJ_SUCCESS)\n\tsess->last_status = last_err;\n    set_state(sess, PJ_TURN_STATE_DEALLOCATED);\n    sess_shutdown(sess, PJ_SUCCESS);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get TURN session info.\n */\nPJ_DEF(pj_status_t) pj_turn_session_get_info( pj_turn_session *sess,\n\t\t\t\t\t      pj_turn_session_info *info)\n{\n    pj_time_val now;\n\n    PJ_ASSERT_RETURN(sess && info, PJ_EINVAL);\n\n    pj_gettimeofday(&now);\n\n    info->state = sess->state;\n    info->conn_type = sess->conn_type;\n    info->lifetime = sess->expiry.sec - now.sec;\n    info->last_status = sess->last_status;\n\n    if (sess->srv_addr)\n\tpj_memcpy(&info->server, sess->srv_addr, sizeof(info->server));\n    else\n\tpj_bzero(&info->server, sizeof(info->server));\n\n    pj_memcpy(&info->mapped_addr, &sess->mapped_addr, \n\t      sizeof(sess->mapped_addr));\n    pj_memcpy(&info->relay_addr, &sess->relay_addr, \n\t      sizeof(sess->relay_addr));\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Re-assign user data.\n */\nPJ_DEF(pj_status_t) pj_turn_session_set_user_data( pj_turn_session *sess,\n\t\t\t\t\t\t   void *user_data)\n{\n    sess->user_data = user_data;\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Retrieve user data.\n */\nPJ_DEF(void*) pj_turn_session_get_user_data(pj_turn_session *sess)\n{\n    return sess->user_data;\n}\n\n/**\n * Get group lock.\n */\nPJ_DEF(pj_grp_lock_t *) pj_turn_session_get_grp_lock(pj_turn_session *sess)\n{\n    PJ_ASSERT_RETURN(sess, NULL);\n    return sess->grp_lock;\n}\n\n/*\n * Configure message logging. By default all flags are enabled.\n *\n * @param sess\t\tThe TURN client session.\n * @param flags\t\tBitmask combination of #pj_stun_sess_msg_log_flag\n */\nPJ_DEF(void) pj_turn_session_set_log( pj_turn_session *sess,\n\t\t\t\t      unsigned flags)\n{\n    pj_stun_session_set_log(sess->stun, flags);\n}\n\n\n/*\n * Set software name\n */\nPJ_DEF(pj_status_t) pj_turn_session_set_software_name( pj_turn_session *sess,\n\t\t\t\t\t\t       const pj_str_t *sw)\n{\n    pj_status_t status;\n\n    pj_grp_lock_acquire(sess->grp_lock);\n    status = pj_stun_session_set_software_name(sess->stun, sw);\n    pj_grp_lock_release(sess->grp_lock);\n\n    return status;\n}\n\n\n/**\n * Set the server or domain name of the server.\n */\nPJ_DEF(pj_status_t) pj_turn_session_set_server( pj_turn_session *sess,\n\t\t\t\t\t        const pj_str_t *domain,\n\t\t\t\t\t\tint default_port,\n\t\t\t\t\t\tpj_dns_resolver *resolver)\n{\n    pj_sockaddr tmp_addr;\n    pj_bool_t is_ip_addr;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sess && domain, PJ_EINVAL);\n    PJ_ASSERT_RETURN(sess->state == PJ_TURN_STATE_NULL, PJ_EINVALIDOP);\n\n    pj_grp_lock_acquire(sess->grp_lock);\n\n    /* See if \"domain\" contains just IP address */\n    tmp_addr.addr.sa_family = sess->af;\n    status = pj_inet_pton(sess->af, domain, \n\t\t\t  pj_sockaddr_get_addr(&tmp_addr));\n    is_ip_addr = (status == PJ_SUCCESS);\n\n    if (!is_ip_addr && resolver) {\n\t/* Resolve with DNS SRV resolution, and fallback to DNS A resolution\n\t * if default_port is specified.\n\t */\n\tunsigned opt = 0;\n\tpj_str_t res_name;\n\n\tswitch (sess->conn_type) {\n\tcase PJ_TURN_TP_UDP:\n\t    res_name = pj_str(\"_turn._udp.\");\n\t    break;\n\tcase PJ_TURN_TP_TCP:\n\t    res_name = pj_str(\"_turn._tcp.\");\n\t    break;\n\tcase PJ_TURN_TP_TLS:\n\t    res_name = pj_str(\"_turns._tcp.\");\n\t    break;\n\tdefault:\n\t    status = PJNATH_ETURNINTP;\n\t    goto on_return;\n\t}\n\n\t/* Fallback to DNS A only if default port is specified */\n\tif (default_port>0 && default_port<65536) {\n\t    opt = PJ_DNS_SRV_FALLBACK_A;\n\t    sess->default_port = (pj_uint16_t)default_port;\n\t}\n\n\tPJ_LOG(5,(sess->obj_name, \"Resolving %.*s%.*s with DNS SRV\",\n\t\t  (int)res_name.slen, res_name.ptr,\n\t\t  (int)domain->slen, domain->ptr));\n\tset_state(sess, PJ_TURN_STATE_RESOLVING);\n\n\t/* User may have destroyed us in the callback */\n\tif (sess->state != PJ_TURN_STATE_RESOLVING) {\n\t    status = PJ_ECANCELLED;\n\t    goto on_return;\n\t}\n\n\tstatus = pj_dns_srv_resolve(domain, &res_name, default_port, \n\t\t\t\t    sess->pool, resolver, opt, sess, \n\t\t\t\t    &dns_srv_resolver_cb, NULL);\n\tif (status != PJ_SUCCESS) {\n\t    set_state(sess, PJ_TURN_STATE_NULL);\n\t    goto on_return;\n\t}\n\n    } else {\n\t/* Resolver is not specified, resolve with standard gethostbyname().\n\t * The default_port MUST be specified in this case.\n\t */\n\tpj_addrinfo *ai;\n\tunsigned i, cnt;\n\n\t/* Default port must be specified */\n\tPJ_ASSERT_RETURN(default_port>0 && default_port<65536, PJ_EINVAL);\n\tsess->default_port = (pj_uint16_t)default_port;\n\n\tcnt = PJ_TURN_MAX_DNS_SRV_CNT;\n\tai = (pj_addrinfo*)\n\t     pj_pool_calloc(sess->pool, cnt, sizeof(pj_addrinfo));\n\n\tPJ_LOG(5,(sess->obj_name, \"Resolving %.*s with DNS A\",\n\t\t  (int)domain->slen, domain->ptr));\n\tset_state(sess, PJ_TURN_STATE_RESOLVING);\n\n\t/* User may have destroyed us in the callback */\n\tif (sess->state != PJ_TURN_STATE_RESOLVING) {\n\t    status = PJ_ECANCELLED;\n\t    goto on_return;\n\t}\n\n\tstatus = pj_getaddrinfo(sess->af, domain, &cnt, ai);\n\tif (status != PJ_SUCCESS)\n\t    goto on_return;\n\n\tsess->srv_addr_cnt = (pj_uint16_t)cnt;\n\tsess->srv_addr_list = (pj_sockaddr*)\n\t\t              pj_pool_calloc(sess->pool, cnt, \n\t\t\t\t\t     sizeof(pj_sockaddr));\n\tfor (i=0; i<cnt; ++i) {\n\t    pj_sockaddr *addr = &sess->srv_addr_list[i];\n\t    pj_memcpy(addr, &ai[i].ai_addr, sizeof(pj_sockaddr));\n\t    addr->addr.sa_family = sess->af;\n\t    addr->ipv4.sin_port = pj_htons(sess->default_port);\n\t}\n\n\tsess->srv_addr = &sess->srv_addr_list[0];\n\tset_state(sess, PJ_TURN_STATE_RESOLVED);\n    }\n\non_return:\n    pj_grp_lock_release(sess->grp_lock);\n    return status;\n}\n\n\n/**\n * Set credential to be used by the session.\n */\nPJ_DEF(pj_status_t) pj_turn_session_set_credential(pj_turn_session *sess,\n\t\t\t\t\t     const pj_stun_auth_cred *cred)\n{\n    PJ_ASSERT_RETURN(sess && cred, PJ_EINVAL);\n    PJ_ASSERT_RETURN(sess->stun, PJ_EINVALIDOP);\n\n    pj_grp_lock_acquire(sess->grp_lock);\n\n    pj_stun_session_set_credential(sess->stun, PJ_STUN_AUTH_LONG_TERM, cred);\n\n    pj_grp_lock_release(sess->grp_lock);\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Create TURN allocation.\n */\nPJ_DEF(pj_status_t) pj_turn_session_alloc(pj_turn_session *sess,\n\t\t\t\t\t  const pj_turn_alloc_param *param)\n{\n    pj_stun_tx_data *tdata;\n    pj_bool_t retransmit;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sess, PJ_EINVAL);\n    PJ_ASSERT_RETURN(sess->state>PJ_TURN_STATE_NULL && \n\t\t     sess->state<=PJ_TURN_STATE_RESOLVED, \n\t\t     PJ_EINVALIDOP);\n\n    pj_grp_lock_acquire(sess->grp_lock);\n\n    if (param && param != &sess->alloc_param) \n\tpj_turn_alloc_param_copy(sess->pool, &sess->alloc_param, param);\n\n    if (sess->state < PJ_TURN_STATE_RESOLVED) {\n\tsess->pending_alloc = PJ_TRUE;\n\n\tPJ_LOG(4,(sess->obj_name, \"Pending ALLOCATE in state %s\",\n\t\t  state_names[sess->state]));\n\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn PJ_SUCCESS;\n\n    }\n\n    /* Ready to allocate */\n    pj_assert(sess->state == PJ_TURN_STATE_RESOLVED);\n    \n    /* Create a bare request */\n    status = pj_stun_session_create_req(sess->stun, PJ_STUN_ALLOCATE_REQUEST,\n\t\t\t\t\tPJ_STUN_MAGIC, NULL, &tdata);\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn status;\n    }\n\n    /* MUST include REQUESTED-TRANSPORT attribute */\n    pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,\n\t\t\t      PJ_STUN_ATTR_REQ_TRANSPORT, \n\t\t\t      PJ_STUN_SET_RT_PROTO(PJ_TURN_TP_UDP));\n\n    /* Include BANDWIDTH if requested */\n    if (sess->alloc_param.bandwidth > 0) {\n\tpj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,\n\t\t\t\t  PJ_STUN_ATTR_BANDWIDTH,\n\t\t\t\t  sess->alloc_param.bandwidth);\n    }\n\n    /* Include LIFETIME if requested */\n    if (sess->alloc_param.lifetime > 0) {\n\tpj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,\n\t\t\t\t  PJ_STUN_ATTR_LIFETIME,\n\t\t\t\t  sess->alloc_param.lifetime);\n    }\n\n    /* Server address must be set */\n    pj_assert(sess->srv_addr != NULL);\n\n    /* Send request */\n    set_state(sess, PJ_TURN_STATE_ALLOCATING);\n    retransmit = (sess->conn_type == PJ_TURN_TP_UDP);\n    status = pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE, \n\t\t\t\t      retransmit, sess->srv_addr,\n\t\t\t\t      pj_sockaddr_get_len(sess->srv_addr), \n\t\t\t\t      tdata);\n    if (status != PJ_SUCCESS) {\n\t/* Set state back to RESOLVED. We don't want to destroy session now,\n\t * let the application do it if it wants to.\n\t */\n\tset_state(sess, PJ_TURN_STATE_RESOLVED);\n    }\n\n    pj_grp_lock_release(sess->grp_lock);\n    return status;\n}\n\n\n/*\n * Install or renew permissions\n */\nPJ_DEF(pj_status_t) pj_turn_session_set_perm( pj_turn_session *sess,\n\t\t\t\t\t      unsigned addr_cnt,\n\t\t\t\t\t      const pj_sockaddr addr[],\n\t\t\t\t\t      unsigned options)\n{\n    pj_stun_tx_data *tdata;\n    pj_hash_iterator_t it_buf, *it;\n    void *req_token;\n    unsigned i, attr_added=0;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sess && addr_cnt && addr, PJ_EINVAL);\n\n    pj_grp_lock_acquire(sess->grp_lock);\n\n    /* Create a bare CreatePermission request */\n    status = pj_stun_session_create_req(sess->stun, \n\t\t\t\t\tPJ_STUN_CREATE_PERM_REQUEST,\n\t\t\t\t\tPJ_STUN_MAGIC, NULL, &tdata);\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_release(sess->grp_lock);\n\treturn status;\n    }\n\n    /* Create request token to map the request to the perm structures\n     * which the request belongs.\n     */\n    req_token = (void*)(pj_ssize_t)pj_rand();\n\n    /* Process the addresses */\n    for (i=0; i<addr_cnt; ++i) {\n\tstruct perm_t *perm;\n\n\t/* Lookup the perm structure and create if it doesn't exist */\n\tperm = lookup_perm(sess, &addr[i], pj_sockaddr_get_len(&addr[i]),\n\t\t\t   PJ_TRUE);\n\tperm->renew = (options & 0x01);\n\n\t/* Only add to the request if the request doesn't contain this\n\t * address yet.\n\t */\n\tif (perm->req_token != req_token) {\n\t    perm->req_token = req_token;\n\n\t    /* Add XOR-PEER-ADDRESS */\n\t    status = pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,\n\t\t\t\t\t\t   PJ_STUN_ATTR_XOR_PEER_ADDR,\n\t\t\t\t\t\t   PJ_TRUE,\n\t\t\t\t\t\t   &addr[i],\n\t\t\t\t\t\t   sizeof(addr[i]));\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_error;\n\n\t    ++attr_added;\n\t}\n    }\n\n    pj_assert(attr_added != 0);\n\n    /* Send the request */\n    status = pj_stun_session_send_msg(sess->stun, req_token, PJ_FALSE, \n\t\t\t\t      (sess->conn_type==PJ_TURN_TP_UDP),\n\t\t\t\t      sess->srv_addr,\n\t\t\t\t      pj_sockaddr_get_len(sess->srv_addr), \n\t\t\t\t      tdata);\n    if (status != PJ_SUCCESS) {\n\t/* tdata is already destroyed */\n\ttdata = NULL;\n\tgoto on_error;\n    }\n\n    pj_grp_lock_release(sess->grp_lock);\n    return PJ_SUCCESS;\n\non_error:\n    /* destroy tdata */\n    if (tdata) {\n\tpj_stun_msg_destroy_tdata(sess->stun, tdata);\n    }\n    /* invalidate perm structures associated with this request */\n    it = pj_hash_first(sess->perm_table, &it_buf);\n    while (it) {\n\tstruct perm_t *perm = (struct perm_t*)\n\t\t\t      pj_hash_this(sess->perm_table, it);\n\tit = pj_hash_next(sess->perm_table, it);\n\tif (perm->req_token == req_token)\n\t    invalidate_perm(sess, perm);\n    }\n    pj_grp_lock_release(sess->grp_lock);\n    return status;\n}\n\n/*\n * Send REFRESH\n */\nstatic void send_refresh(pj_turn_session *sess, int lifetime)\n{\n    pj_stun_tx_data *tdata;\n    pj_status_t status;\n\n    PJ_ASSERT_ON_FAIL(sess->state==PJ_TURN_STATE_READY, return);\n\n    /* Create a bare REFRESH request */\n    status = pj_stun_session_create_req(sess->stun, PJ_STUN_REFRESH_REQUEST,\n\t\t\t\t\tPJ_STUN_MAGIC, NULL, &tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Add LIFETIME */\n    if (lifetime >= 0) {\n\tpj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,\n\t\t\t\t  PJ_STUN_ATTR_LIFETIME, lifetime);\n    }\n\n    /* Send request */\n    if (lifetime == 0) {\n\tset_state(sess, PJ_TURN_STATE_DEALLOCATING);\n    }\n\n    status = pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE, \n\t\t\t\t      (sess->conn_type==PJ_TURN_TP_UDP),\n\t\t\t\t      sess->srv_addr,\n\t\t\t\t      pj_sockaddr_get_len(sess->srv_addr), \n\t\t\t\t      tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    return;\n\non_error:\n    if (lifetime == 0) {\n\tset_state(sess, PJ_TURN_STATE_DEALLOCATED);\n\tsess_shutdown(sess, status);\n    }\n}\n\n\n/**\n * Relay data to the specified peer through the session.\n */\nPJ_DEF(pj_status_t) pj_turn_session_sendto( pj_turn_session *sess,\n\t\t\t\t\t    const pj_uint8_t *pkt,\n\t\t\t\t\t    unsigned pkt_len,\n\t\t\t\t\t    const pj_sockaddr_t *addr,\n\t\t\t\t\t    unsigned addr_len)\n{\n    struct ch_t *ch;\n    struct perm_t *perm;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sess && pkt && pkt_len && addr && addr_len, \n\t\t     PJ_EINVAL);\n\n    /* Return error if we're not ready */\n    if (sess->state != PJ_TURN_STATE_READY) {\n\treturn PJ_EIGNORED;\n    }\n\n    /* Lock session now */\n    pj_grp_lock_acquire(sess->grp_lock);\n\n    /* Lookup permission first */\n    perm = lookup_perm(sess, addr, pj_sockaddr_get_len(addr), PJ_FALSE);\n    if (perm == NULL) {\n\t/* Permission doesn't exist, install it first */\n\tchar ipstr[PJ_INET6_ADDRSTRLEN+2];\n\n\tPJ_LOG(4,(sess->obj_name, \n\t\t  \"sendto(): IP %s has no permission, requesting it first..\",\n\t\t  pj_sockaddr_print(addr, ipstr, sizeof(ipstr), 2)));\n\n\tstatus = pj_turn_session_set_perm(sess, 1, (const pj_sockaddr*)addr, \n\t\t\t\t\t  0);\n\tif (status != PJ_SUCCESS) {\n\t    pj_grp_lock_release(sess->grp_lock);\n\t    return status;\n\t}\n    }\n\n    /* See if the peer is bound to a channel number */\n    ch = lookup_ch_by_addr(sess, addr, pj_sockaddr_get_len(addr), \n\t\t\t   PJ_FALSE, PJ_FALSE);\n    if (ch && ch->num != PJ_TURN_INVALID_CHANNEL && ch->bound) {\n\tunsigned total_len;\n\n\t/* Peer is assigned a channel number, we can use ChannelData */\n\tpj_turn_channel_data *cd = (pj_turn_channel_data*)sess->tx_pkt;\n\t\n\tpj_assert(sizeof(*cd)==4);\n\n\t/* Calculate total length, including paddings */\n\ttotal_len = (pkt_len + sizeof(*cd) + 3) & (~3);\n\tif (total_len > sizeof(sess->tx_pkt)) {\n\t    status = PJ_ETOOBIG;\n\t    goto on_return;\n\t}\n\n\tcd->ch_number = pj_htons((pj_uint16_t)ch->num);\n\tcd->length = pj_htons((pj_uint16_t)pkt_len);\n\tpj_memcpy(cd+1, pkt, pkt_len);\n\n\tpj_assert(sess->srv_addr != NULL);\n\n\tstatus = sess->cb.on_send_pkt(sess, sess->tx_pkt, total_len,\n\t\t\t\t      sess->srv_addr,\n\t\t\t\t      pj_sockaddr_get_len(sess->srv_addr));\n\n    } else {\n\t/* Use Send Indication. */\n\tpj_stun_sockaddr_attr peer_attr;\n\tpj_stun_binary_attr data_attr;\n\tpj_stun_msg send_ind;\n\tpj_size_t send_ind_len;\n\n\t/* Increment counter */\n\t++sess->send_ind_tsx_id[2];\n\n\t/* Create blank SEND-INDICATION */\n\tstatus = pj_stun_msg_init(&send_ind, PJ_STUN_SEND_INDICATION,\n\t\t\t\t  PJ_STUN_MAGIC, \n\t\t\t\t  (const pj_uint8_t*)sess->send_ind_tsx_id);\n\tif (status != PJ_SUCCESS)\n\t    goto on_return;\n\n\t/* Add XOR-PEER-ADDRESS */\n\tpj_stun_sockaddr_attr_init(&peer_attr, PJ_STUN_ATTR_XOR_PEER_ADDR,\n\t\t\t\t   PJ_TRUE, addr, addr_len);\n\tpj_stun_msg_add_attr(&send_ind, (pj_stun_attr_hdr*)&peer_attr);\n\n\t/* Add DATA attribute */\n\tpj_stun_binary_attr_init(&data_attr, NULL, PJ_STUN_ATTR_DATA, NULL, 0);\n\tdata_attr.data = (pj_uint8_t*)pkt;\n\tdata_attr.length = pkt_len;\n\tpj_stun_msg_add_attr(&send_ind, (pj_stun_attr_hdr*)&data_attr);\n\n\t/* Encode the message */\n\tstatus = pj_stun_msg_encode(&send_ind, sess->tx_pkt, \n\t\t\t\t    sizeof(sess->tx_pkt), 0,\n\t\t\t\t    NULL, &send_ind_len);\n\tif (status != PJ_SUCCESS)\n\t    goto on_return;\n\n\t/* Send the Send Indication */\n\tstatus = sess->cb.on_send_pkt(sess, sess->tx_pkt, \n\t\t\t\t      (unsigned)send_ind_len,\n\t\t\t\t      sess->srv_addr,\n\t\t\t\t      pj_sockaddr_get_len(sess->srv_addr));\n    }\n\non_return:\n    pj_grp_lock_release(sess->grp_lock);\n    return status;\n}\n\n\n/**\n * Bind a peer address to a channel number.\n */\nPJ_DEF(pj_status_t) pj_turn_session_bind_channel(pj_turn_session *sess,\n\t\t\t\t\t\t const pj_sockaddr_t *peer_adr,\n\t\t\t\t\t\t unsigned addr_len)\n{\n    struct ch_t *ch;\n    pj_stun_tx_data *tdata;\n    pj_uint16_t ch_num;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sess && peer_adr && addr_len, PJ_EINVAL);\n    PJ_ASSERT_RETURN(sess->state == PJ_TURN_STATE_READY, PJ_EINVALIDOP);\n\n    pj_grp_lock_acquire(sess->grp_lock);\n\n    /* Create blank ChannelBind request */\n    status = pj_stun_session_create_req(sess->stun, \n\t\t\t\t\tPJ_STUN_CHANNEL_BIND_REQUEST,\n\t\t\t\t\tPJ_STUN_MAGIC, NULL, &tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Lookup if this peer has already been assigned a number */\n    ch = lookup_ch_by_addr(sess, peer_adr, pj_sockaddr_get_len(peer_adr),\n\t\t\t   PJ_TRUE, PJ_FALSE);\n    pj_assert(ch);\n\n    if (ch->num != PJ_TURN_INVALID_CHANNEL) {\n\t/* Channel is already bound. This is a refresh request. */\n\tch_num = ch->num;\n    } else {\n\tPJ_ASSERT_ON_FAIL(sess->next_ch <= PJ_TURN_CHANNEL_MAX, \n\t\t\t    {status=PJ_ETOOMANY; goto on_return;});\n\tch->num = ch_num = sess->next_ch++;\n    }\n\n    /* Add CHANNEL-NUMBER attribute */\n    pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,\n\t\t\t      PJ_STUN_ATTR_CHANNEL_NUMBER,\n\t\t\t      PJ_STUN_SET_CH_NB(ch_num));\n\n    /* Add XOR-PEER-ADDRESS attribute */\n    pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,\n\t\t\t\t  PJ_STUN_ATTR_XOR_PEER_ADDR, PJ_TRUE,\n\t\t\t\t  peer_adr, addr_len);\n\n    /* Send the request, associate peer data structure with tdata \n     * for future reference when we receive the ChannelBind response.\n     */\n    status = pj_stun_session_send_msg(sess->stun, ch, PJ_FALSE, \n\t\t\t\t      (sess->conn_type==PJ_TURN_TP_UDP),\n\t\t\t\t      sess->srv_addr,\n\t\t\t\t      pj_sockaddr_get_len(sess->srv_addr),\n\t\t\t\t      tdata);\n\non_return:\n    pj_grp_lock_release(sess->grp_lock);\n    return status;\n}\n\n\n/**\n * Notify TURN client session upon receiving a packet from server.\n * The packet maybe a STUN packet or ChannelData packet.\n */\nPJ_DEF(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess,\n\t\t\t\t\t      void *pkt,\n\t\t\t\t\t      pj_size_t pkt_len,\n\t\t\t\t\t      pj_size_t *parsed_len)\n{\n    pj_bool_t is_stun;\n    pj_status_t status;\n    pj_bool_t is_datagram;\n\n    /* Packet could be ChannelData or STUN message (response or\n     * indication).\n     */\n\n    /* Start locking the session */\n    pj_grp_lock_acquire(sess->grp_lock);\n\n    is_datagram = (sess->conn_type==PJ_TURN_TP_UDP);\n\n    /* Quickly check if this is STUN message */\n    is_stun = ((((pj_uint8_t*)pkt)[0] & 0xC0) == 0);\n\n    if (is_stun) {\n\t/* This looks like STUN, give it to the STUN session */\n\tunsigned options;\n\n\toptions = PJ_STUN_CHECK_PACKET | PJ_STUN_NO_FINGERPRINT_CHECK;\n\tif (is_datagram)\n\t    options |= PJ_STUN_IS_DATAGRAM;\n\tstatus=pj_stun_session_on_rx_pkt(sess->stun, pkt, pkt_len,\n\t\t\t\t\t options, NULL, parsed_len,\n\t\t\t\t\t sess->srv_addr,\n\t\t\t\t\t pj_sockaddr_get_len(sess->srv_addr));\n\n    } else {\n\t/* This must be ChannelData. */\n\tpj_turn_channel_data cd;\n\tstruct ch_t *ch;\n\n\tif (pkt_len < 4) {\n\t    if (parsed_len) *parsed_len = 0;\n\t    return PJ_ETOOSMALL;\n\t}\n\n\t/* Decode ChannelData packet */\n\tpj_memcpy(&cd, pkt, sizeof(pj_turn_channel_data));\n\tcd.ch_number = pj_ntohs(cd.ch_number);\n\tcd.length = pj_ntohs(cd.length);\n\n\t/* Check that size is sane */\n\tif (pkt_len < cd.length+sizeof(cd)) {\n\t    if (parsed_len) {\n\t\tif (is_datagram) {\n\t\t    /* Discard the datagram */\n\t\t    *parsed_len = pkt_len;\n\t\t} else {\n\t\t    /* Insufficient fragment */\n\t\t    *parsed_len = 0;\n\t\t}\n\t    }\n\t    status = PJ_ETOOSMALL;\n\t    goto on_return;\n\t} else {\n\t    if (parsed_len) {\n\t\t/* Apply padding too */\n\t\t*parsed_len = ((cd.length + 3) & (~3)) + sizeof(cd);\n\t    }\n\t}\n\n\t/* Lookup channel */\n\tch = lookup_ch_by_chnum(sess, cd.ch_number);\n\tif (!ch || !ch->bound) {\n\t    status = PJ_ENOTFOUND;\n\t    goto on_return;\n\t}\n\n\t/* Notify application */\n\tif (sess->cb.on_rx_data) {\n\t    (*sess->cb.on_rx_data)(sess, ((pj_uint8_t*)pkt)+sizeof(cd), \n\t\t\t\t   cd.length, &ch->addr,\n\t\t\t\t   pj_sockaddr_get_len(&ch->addr));\n\t}\n\n\tstatus = PJ_SUCCESS;\n    }\n\non_return:\n    pj_grp_lock_release(sess->grp_lock);\n    return status;\n}\n\n\n/*\n * This is a callback from STUN session to send outgoing packet.\n */\nstatic pj_status_t stun_on_send_msg(pj_stun_session *stun,\n\t\t\t\t    void *token,\n\t\t\t\t    const void *pkt,\n\t\t\t\t    pj_size_t pkt_size,\n\t\t\t\t    const pj_sockaddr_t *dst_addr,\n\t\t\t\t    unsigned addr_len)\n{\n    pj_turn_session *sess;\n\n    PJ_UNUSED_ARG(token);\n\n    sess = (pj_turn_session*) pj_stun_session_get_user_data(stun);\n    return (*sess->cb.on_send_pkt)(sess, (const pj_uint8_t*)pkt, \n\t\t\t\t   (unsigned)pkt_size, \n\t\t\t\t   dst_addr, addr_len);\n}\n\n\n/*\n * Handle failed ALLOCATE or REFRESH request. This may switch to alternate\n * server if we have one.\n */\nstatic void on_session_fail( pj_turn_session *sess, \n\t\t\t     enum pj_stun_method_e method,\n\t\t\t     pj_status_t status,\n\t\t\t     const pj_str_t *reason)\n{\n    sess->last_status = status;\n\n    do {\n\tpj_str_t reason1;\n\tchar err_msg[PJ_ERR_MSG_SIZE];\n\n\tif (reason == NULL) {\n\t    pj_strerror(status, err_msg, sizeof(err_msg));\n\t    reason1 = pj_str(err_msg);\n\t    reason = &reason1;\n\t}\n\n\tPJ_LOG(4,(sess->obj_name, \"%s error: %.*s\",\n\t\t  pj_stun_get_method_name(method),\n\t\t  (int)reason->slen, reason->ptr));\n\n\t/* If this is ALLOCATE response and we don't have more server \n\t * addresses to try, notify application and destroy the TURN\n\t * session.\n\t */\n\tif (method==PJ_STUN_ALLOCATE_METHOD &&\n\t    sess->srv_addr == &sess->srv_addr_list[sess->srv_addr_cnt-1]) \n\t{\n\n\t    set_state(sess, PJ_TURN_STATE_DEALLOCATED);\n\t    sess_shutdown(sess, status);\n\t    return;\n\t}\n\n\t/* Otherwise if this is not ALLOCATE response, notify application\n\t * that session has been TERMINATED.\n\t */\n\tif (method!=PJ_STUN_ALLOCATE_METHOD) {\n\t    set_state(sess, PJ_TURN_STATE_DEALLOCATED);\n\t    sess_shutdown(sess, status);\n\t    return;\n\t}\n\n\t/* Try next server */\n\t++sess->srv_addr;\n\treason = NULL;\n\n\tPJ_LOG(4,(sess->obj_name, \"Trying next server\"));\n\tset_state(sess, PJ_TURN_STATE_RESOLVED);\n\n    } while (0);\n}\n\n\n/*\n * Handle successful response to ALLOCATE or REFRESH request.\n */\nstatic void on_allocate_success(pj_turn_session *sess, \n\t\t\t\tenum pj_stun_method_e method,\n\t\t\t\tconst pj_stun_msg *msg)\n{\n    const pj_stun_lifetime_attr *lf_attr;\n    const pj_stun_xor_relayed_addr_attr *raddr_attr;\n    const pj_stun_sockaddr_attr *mapped_attr;\n    pj_str_t s;\n\n    /* Must have LIFETIME attribute */\n    lf_attr = (const pj_stun_lifetime_attr*)\n\t      pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_LIFETIME, 0);\n    if (lf_attr == NULL) {\n\ton_session_fail(sess, method, PJNATH_EINSTUNMSG,\n\t\t\tpj_cstr(&s, \"Error: Missing LIFETIME attribute\"));\n\treturn;\n    }\n\n    /* If LIFETIME is zero, this is a deallocation */\n    if (lf_attr->value == 0) {\n\tset_state(sess, PJ_TURN_STATE_DEALLOCATED);\n\tsess_shutdown(sess, PJ_SUCCESS);\n\treturn;\n    }\n\n    /* Update lifetime and keep-alive interval */\n    sess->lifetime = lf_attr->value;\n    pj_gettimeofday(&sess->expiry);\n\n    if (sess->lifetime < PJ_TURN_KEEP_ALIVE_SEC) {\n\tif (sess->lifetime <= 2) {\n\t    on_session_fail(sess, method, PJ_ETOOSMALL,\n\t\t\t     pj_cstr(&s, \"Error: LIFETIME too small\"));\n\t    return;\n\t}\n\tsess->ka_interval = sess->lifetime - 2;\n\tsess->expiry.sec += (sess->ka_interval-1);\n    } else {\n\tint timeout;\n\n\tsess->ka_interval = PJ_TURN_KEEP_ALIVE_SEC;\n\n\ttimeout = sess->lifetime - PJ_TURN_REFRESH_SEC_BEFORE;\n\tif (timeout < sess->ka_interval)\n\t    timeout = sess->ka_interval - 1;\n\n\tsess->expiry.sec += timeout;\n    }\n\n    /* Check that relayed transport address contains correct\n     * address family.\n     */\n    raddr_attr = (const pj_stun_xor_relayed_addr_attr*)\n\t\t pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_RELAYED_ADDR, 0);\n    if (raddr_attr == NULL && method==PJ_STUN_ALLOCATE_METHOD) {\n\ton_session_fail(sess, method, PJNATH_EINSTUNMSG,\n\t\t        pj_cstr(&s, \"Error: Received ALLOCATE without \"\n\t\t\t\t    \"RELAY-ADDRESS attribute\"));\n\treturn;\n    }\n    if (raddr_attr && raddr_attr->sockaddr.addr.sa_family != sess->af) {\n\ton_session_fail(sess, method, PJNATH_EINSTUNMSG,\n\t\t\tpj_cstr(&s, \"Error: RELAY-ADDRESS with non IPv4\"\n\t\t\t\t    \" address family is not supported \"\n\t\t\t\t    \"for now\"));\n\treturn;\n    }\n    if (raddr_attr && !pj_sockaddr_has_addr(&raddr_attr->sockaddr)) {\n\ton_session_fail(sess, method, PJNATH_EINSTUNMSG,\n\t\t\tpj_cstr(&s, \"Error: Invalid IP address in \"\n\t\t\t\t    \"RELAY-ADDRESS attribute\"));\n\treturn;\n    }\n    \n    /* Save relayed address */\n    if (raddr_attr) {\n\t/* If we already have relay address, check if the relay address \n\t * in the response matches our relay address.\n\t */\n\tif (pj_sockaddr_has_addr(&sess->relay_addr)) {\n\t    if (pj_sockaddr_cmp(&sess->relay_addr, &raddr_attr->sockaddr)) {\n\t\ton_session_fail(sess, method, PJNATH_EINSTUNMSG,\n\t\t\t\tpj_cstr(&s, \"Error: different RELAY-ADDRESS is\"\n\t\t\t\t\t    \"returned by server\"));\n\t\treturn;\n\t    }\n\t} else {\n\t    /* Otherwise save the relayed address */\n\t    pj_memcpy(&sess->relay_addr, &raddr_attr->sockaddr, \n\t\t      sizeof(pj_sockaddr));\n\t}\n    }\n\n    /* Get mapped address */\n    mapped_attr = (const pj_stun_sockaddr_attr*)\n\t\t  pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_MAPPED_ADDR, 0);\n    if (mapped_attr) {\n\tpj_memcpy(&sess->mapped_addr, &mapped_attr->sockaddr,\n\t\t  sizeof(mapped_attr->sockaddr));\n    }\n\n    /* Success */\n\n    /* Cancel existing keep-alive timer, if any */\n    pj_assert(sess->timer.id != TIMER_DESTROY);\n    if (sess->timer.id == TIMER_KEEP_ALIVE) {\n\tpj_timer_heap_cancel_if_active(sess->timer_heap, &sess->timer,\n\t\t\t\t       TIMER_NONE);\n    }\n\n    /* Start keep-alive timer once allocation succeeds */\n    if (sess->state < PJ_TURN_STATE_DEALLOCATING) {\n\tpj_time_val timeout;\n\ttimeout.sec = sess->ka_interval;\n\ttimeout.msec = 0;\n\n\tpj_timer_heap_schedule_w_grp_lock(sess->timer_heap, &sess->timer,\n\t\t\t\t\t  &timeout, TIMER_KEEP_ALIVE,\n\t\t\t\t\t  sess->grp_lock);\n\n\tset_state(sess, PJ_TURN_STATE_READY);\n    }\n}\n\n/*\n * Notification from STUN session on request completion.\n */\nstatic void stun_on_request_complete(pj_stun_session *stun,\n\t\t\t\t     pj_status_t status,\n\t\t\t\t     void *token,\n\t\t\t\t     pj_stun_tx_data *tdata,\n\t\t\t\t     const pj_stun_msg *response,\n\t\t\t\t     const pj_sockaddr_t *src_addr,\n\t\t\t\t     unsigned src_addr_len)\n{\n    pj_turn_session *sess;\n    enum pj_stun_method_e method = (enum pj_stun_method_e) \n\t\t\t      \t   PJ_STUN_GET_METHOD(tdata->msg->hdr.type);\n\n    PJ_UNUSED_ARG(src_addr);\n    PJ_UNUSED_ARG(src_addr_len);\n\n    sess = (pj_turn_session*)pj_stun_session_get_user_data(stun);\n\n    if (method == PJ_STUN_ALLOCATE_METHOD) {\n\n\t/* Destroy if we have pending destroy request */\n\tif (sess->pending_destroy) {\n\t    if (status == PJ_SUCCESS)\n\t\tsess->state = PJ_TURN_STATE_READY;\n\t    else\n\t\tsess->state = PJ_TURN_STATE_DEALLOCATED;\n\t    sess_shutdown(sess, PJ_SUCCESS);\n\t    return;\n\t}\n\n\t/* Handle ALLOCATE response */\n\tif (status==PJ_SUCCESS && \n\t    PJ_STUN_IS_SUCCESS_RESPONSE(response->hdr.type)) \n\t{\n\n\t    /* Successful Allocate response */\n\t    on_allocate_success(sess, method, response);\n\n\t} else {\n\t    /* Failed Allocate request */\n\t    const pj_str_t *err_msg = NULL;\n\n\t    if (status == PJ_SUCCESS) {\n\t\tconst pj_stun_errcode_attr *err_attr;\n\t\terr_attr = (const pj_stun_errcode_attr*)\n\t\t\t   pj_stun_msg_find_attr(response,\n\t\t\t\t\t\t PJ_STUN_ATTR_ERROR_CODE, 0);\n\t\tif (err_attr) {\n\t\t    status = PJ_STATUS_FROM_STUN_CODE(err_attr->err_code);\n\t\t    err_msg = &err_attr->reason;\n\t\t} else {\n\t\t    status = PJNATH_EINSTUNMSG;\n\t\t}\n\t    }\n\n\t    on_session_fail(sess, method, status, err_msg);\n\t}\n\n    } else if (method == PJ_STUN_REFRESH_METHOD) {\n\t/* Handle Refresh response */\n\tif (status==PJ_SUCCESS && \n\t    PJ_STUN_IS_SUCCESS_RESPONSE(response->hdr.type)) \n\t{\n\t    /* Success, schedule next refresh. */\n\t    on_allocate_success(sess, method, response);\n\n\t} else {\n\t    /* Failed Refresh request */\n\t    const pj_str_t *err_msg = NULL;\n\n\t    pj_assert(status != PJ_SUCCESS);\n\n\t    if (response) {\n\t\tconst pj_stun_errcode_attr *err_attr;\n\t\terr_attr = (const pj_stun_errcode_attr*)\n\t\t\t   pj_stun_msg_find_attr(response,\n\t\t\t\t\t\t PJ_STUN_ATTR_ERROR_CODE, 0);\n\t\tif (err_attr) {\n\t\t    status = PJ_STATUS_FROM_STUN_CODE(err_attr->err_code);\n\t\t    err_msg = &err_attr->reason;\n\t\t}\n\t    }\n\n\t    /* Notify and destroy */\n\t    on_session_fail(sess, method, status, err_msg);\n\t}\n\n    } else if (method == PJ_STUN_CHANNEL_BIND_METHOD) {\n\t/* Handle ChannelBind response */\n\tif (status==PJ_SUCCESS && \n\t    PJ_STUN_IS_SUCCESS_RESPONSE(response->hdr.type)) \n\t{\n\t    /* Successful ChannelBind response */\n\t    struct ch_t *ch = (struct ch_t*)token;\n\n\t    pj_assert(ch->num != PJ_TURN_INVALID_CHANNEL);\n\t    ch->bound = PJ_TRUE;\n\n\t    /* Update hash table */\n\t    lookup_ch_by_addr(sess, &ch->addr,\n\t\t\t      pj_sockaddr_get_len(&ch->addr),\n\t\t\t      PJ_TRUE, PJ_TRUE);\n\n\t} else {\n\t    /* Failed ChannelBind response */\n\t    pj_str_t reason = {\"\", 0};\n\t    int err_code = 0;\n\t    char errbuf[PJ_ERR_MSG_SIZE];\n\n\t    pj_assert(status != PJ_SUCCESS);\n\n\t    if (response) {\n\t\tconst pj_stun_errcode_attr *err_attr;\n\t\terr_attr = (const pj_stun_errcode_attr*)\n\t\t\t   pj_stun_msg_find_attr(response,\n\t\t\t\t\t\t PJ_STUN_ATTR_ERROR_CODE, 0);\n\t\tif (err_attr) {\n\t\t    err_code = err_attr->err_code;\n\t\t    status = PJ_STATUS_FROM_STUN_CODE(err_attr->err_code);\n\t\t    reason = err_attr->reason;\n\t\t}\n\t    } else {\n\t\terr_code = status;\n\t\treason = pj_strerror(status, errbuf, sizeof(errbuf));\n\t    }\n\n\t    PJ_LOG(1,(sess->obj_name, \"ChannelBind failed: %d/%.*s\",\n\t\t      err_code, (int)reason.slen, reason.ptr));\n\n\t    if (err_code == PJ_STUN_SC_ALLOCATION_MISMATCH) {\n\t\t/* Allocation mismatch means allocation no longer exists */\n\t\ton_session_fail(sess, PJ_STUN_CHANNEL_BIND_METHOD,\n\t\t\t\tstatus, &reason);\n\t\treturn;\n\t    }\n\t}\n\n    } else if (method == PJ_STUN_CREATE_PERM_METHOD) {\n\t/* Handle CreatePermission response */\n\tif (status==PJ_SUCCESS && \n\t    PJ_STUN_IS_SUCCESS_RESPONSE(response->hdr.type)) \n\t{\n\t    /* No special handling when the request is successful. */\n\t} else {\n\t    /* Iterate the permission table and invalidate all permissions\n\t     * that are related to this request.\n\t     */\n\t    pj_hash_iterator_t it_buf, *it;\n\t    char ipstr[PJ_INET6_ADDRSTRLEN+10];\n\t    int err_code;\n\t    char errbuf[PJ_ERR_MSG_SIZE];\n\t    pj_str_t reason;\n\n\t    pj_assert(status != PJ_SUCCESS);\n\n\t    if (response) {\n\t\tconst pj_stun_errcode_attr *eattr;\n\n\t\teattr = (const pj_stun_errcode_attr*)\n\t\t\tpj_stun_msg_find_attr(response, \n\t\t\t\t\t      PJ_STUN_ATTR_ERROR_CODE, 0);\n\t\tif (eattr) {\n\t\t    err_code = eattr->err_code;\n\t\t    reason = eattr->reason;\n\t\t} else {\n\t\t    err_code = -1;\n\t\t    reason = pj_str(\"?\");\n\t\t}\n\t    } else {\n\t\terr_code = status;\n\t\treason = pj_strerror(status, errbuf, sizeof(errbuf));\n\t    }\n\n\t    it = pj_hash_first(sess->perm_table, &it_buf);\n\t    while (it) {\n\t\tstruct perm_t *perm = (struct perm_t*)\n\t\t\t\t      pj_hash_this(sess->perm_table, it);\n\t\tit = pj_hash_next(sess->perm_table, it);\n\n\t\tif (perm->req_token == token) {\n\t\t    PJ_LOG(1,(sess->obj_name, \n\t\t\t      \"CreatePermission failed for IP %s: %d/%.*s\",\n\t\t\t      pj_sockaddr_print(&perm->addr, ipstr, \n\t\t\t\t\t\tsizeof(ipstr), 2),\n\t\t\t      err_code, (int)reason.slen, reason.ptr));\n\n\t\t    invalidate_perm(sess, perm);\n\t\t}\n\t    }\n\n\t    if (err_code == PJ_STUN_SC_ALLOCATION_MISMATCH) {\n\t\t/* Allocation mismatch means allocation no longer exists */\n\t\ton_session_fail(sess, PJ_STUN_CREATE_PERM_METHOD,\n\t\t\t\tstatus, &reason);\n\t\treturn;\n\t    }\n\t}\n\n    } else {\n\tPJ_LOG(4,(sess->obj_name, \"Unexpected STUN %s response\",\n\t\t  pj_stun_get_method_name(response->hdr.type)));\n    }\n}\n\n\n/*\n * Notification from STUN session on incoming STUN Indication\n * message.\n */\nstatic pj_status_t stun_on_rx_indication(pj_stun_session *stun,\n\t\t\t\t\t const pj_uint8_t *pkt,\n\t\t\t\t\t unsigned pkt_len,\n\t\t\t\t\t const pj_stun_msg *msg,\n\t\t\t\t\t void *token,\n\t\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t\t unsigned src_addr_len)\n{\n    pj_turn_session *sess;\n    pj_stun_xor_peer_addr_attr *peer_attr;\n    pj_stun_icmp_attr *icmp;\n    pj_stun_data_attr *data_attr;\n\n    PJ_UNUSED_ARG(token);\n    PJ_UNUSED_ARG(pkt);\n    PJ_UNUSED_ARG(pkt_len);\n    PJ_UNUSED_ARG(src_addr);\n    PJ_UNUSED_ARG(src_addr_len);\n\n    sess = (pj_turn_session*)pj_stun_session_get_user_data(stun);\n\n    /* Expecting Data Indication only */\n    if (msg->hdr.type != PJ_STUN_DATA_INDICATION) {\n\tPJ_LOG(4,(sess->obj_name, \"Unexpected STUN %s indication\",\n\t\t  pj_stun_get_method_name(msg->hdr.type)));\n\treturn PJ_EINVALIDOP;\n    }\n\n    /* Check if there is ICMP attribute in the message */\n    icmp = (pj_stun_icmp_attr*)\n\t   pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ICMP, 0);\n    if (icmp != NULL) {\n\t/* This is a forwarded ICMP packet. Ignore it for now */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Get XOR-PEER-ADDRESS attribute */\n    peer_attr = (pj_stun_xor_peer_addr_attr*)\n\t\tpj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_PEER_ADDR, 0);\n\n    /* Get DATA attribute */\n    data_attr = (pj_stun_data_attr*)\n\t\tpj_stun_msg_find_attr(msg, PJ_STUN_ATTR_DATA, 0);\n\n    /* Must have both XOR-PEER-ADDRESS and DATA attributes */\n    if (!peer_attr || !data_attr) {\n\tPJ_LOG(4,(sess->obj_name, \n\t\t  \"Received Data indication with missing attributes\"));\n\treturn PJ_EINVALIDOP;\n    }\n\n    /* Notify application */\n    if (sess->cb.on_rx_data) {\n\t(*sess->cb.on_rx_data)(sess, data_attr->data, data_attr->length, \n\t\t\t       &peer_attr->sockaddr,\n\t\t\t       pj_sockaddr_get_len(&peer_attr->sockaddr));\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Notification on completion of DNS SRV resolution.\n */\nstatic void dns_srv_resolver_cb(void *user_data,\n\t\t\t\tpj_status_t status,\n\t\t\t\tconst pj_dns_srv_record *rec)\n{\n    pj_turn_session *sess = (pj_turn_session*) user_data;\n    unsigned i, cnt, tot_cnt;\n\n    /* Check failure */\n    if (status != PJ_SUCCESS || sess->pending_destroy) {\n\tset_state(sess, PJ_TURN_STATE_DESTROYING);\n\tsess_shutdown(sess, status);\n\treturn;\n    }\n\n    /* Calculate total number of server entries in the response */\n    tot_cnt = 0;\n    for (i=0; i<rec->count; ++i) {\n\ttot_cnt += rec->entry[i].server.addr_count;\n    }\n\n    if (tot_cnt > PJ_TURN_MAX_DNS_SRV_CNT)\n\ttot_cnt = PJ_TURN_MAX_DNS_SRV_CNT;\n\n    /* Allocate server entries */\n    sess->srv_addr_list = (pj_sockaddr*)\n\t\t           pj_pool_calloc(sess->pool, tot_cnt, \n\t\t\t\t\t  sizeof(pj_sockaddr));\n\n    /* Copy results to server entries */\n    for (i=0, cnt=0; i<rec->count && cnt<PJ_TURN_MAX_DNS_SRV_CNT; ++i) {\n\tunsigned j;\n\n\tfor (j=0; j<rec->entry[i].server.addr_count && \n\t\t  cnt<PJ_TURN_MAX_DNS_SRV_CNT; ++j) \n\t{\n\t    pj_sockaddr_in *addr = &sess->srv_addr_list[cnt].ipv4;\n\n\t    addr->sin_family = sess->af;\n\t    addr->sin_port = pj_htons(rec->entry[i].port);\n\t    addr->sin_addr.s_addr = rec->entry[i].server.addr[j].s_addr;\n\n\t    ++cnt;\n\t}\n    }\n    sess->srv_addr_cnt = (pj_uint16_t)cnt;\n\n    /* Set current server */\n    sess->srv_addr = &sess->srv_addr_list[0];\n\n    /* Set state to PJ_TURN_STATE_RESOLVED */\n    set_state(sess, PJ_TURN_STATE_RESOLVED);\n\n    /* Run pending allocation */\n    if (sess->pending_alloc) {\n\tpj_turn_session_alloc(sess, NULL);\n    }\n}\n\n\n/*\n * Lookup peer descriptor from its address.\n */\nstatic struct ch_t *lookup_ch_by_addr(pj_turn_session *sess,\n\t\t\t\t      const pj_sockaddr_t *addr,\n\t\t\t\t      unsigned addr_len,\n\t\t\t\t      pj_bool_t update,\n\t\t\t\t      pj_bool_t bind_channel)\n{\n    pj_uint32_t hval = 0;\n    struct ch_t *ch;\n\n    ch = (struct ch_t*) \n\t pj_hash_get(sess->ch_table, addr, addr_len, &hval);\n    if (ch == NULL && update) {\n\tch = PJ_POOL_ZALLOC_T(sess->pool, struct ch_t);\n\tch->num = PJ_TURN_INVALID_CHANNEL;\n\tpj_memcpy(&ch->addr, addr, addr_len);\n\n\t/* Register by peer address */\n\tpj_hash_set(sess->pool, sess->ch_table, &ch->addr, addr_len,\n\t\t    hval, ch);\n    }\n\n    if (ch && update) {\n\tpj_gettimeofday(&ch->expiry);\n\tch->expiry.sec += PJ_TURN_PERM_TIMEOUT - sess->ka_interval - 1;\n\n\tif (bind_channel) {\n\t    pj_uint32_t hval2 = 0;\n\t    /* Register by channel number */\n\t    pj_assert(ch->num != PJ_TURN_INVALID_CHANNEL && ch->bound);\n\n\t    if (pj_hash_get(sess->ch_table, &ch->num, \n\t\t\t    sizeof(ch->num), &hval2)==0) {\n\t\tpj_hash_set(sess->pool, sess->ch_table, &ch->num,\n\t\t\t    sizeof(ch->num), hval2, ch);\n\t    }\n\t}\n    }\n\n    /* Also create/update permission for this destination. Ideally we\n     * should update this when we receive the successful response,\n     * but that would cause duplicate CreatePermission to be sent\n     * during refreshing.\n     */\n    if (ch && update) {\n\tlookup_perm(sess, &ch->addr, pj_sockaddr_get_len(&ch->addr), PJ_TRUE);\n    }\n\n    return ch;\n}\n\n\n/*\n * Lookup channel descriptor from its channel number.\n */\nstatic struct ch_t *lookup_ch_by_chnum(pj_turn_session *sess,\n\t\t\t\t\t pj_uint16_t chnum)\n{\n    return (struct ch_t*) pj_hash_get(sess->ch_table, &chnum, \n\t\t\t\t      sizeof(chnum), NULL);\n}\n\n\n/*\n * Lookup permission and optionally create if it doesn't exist.\n */\nstatic struct perm_t *lookup_perm(pj_turn_session *sess,\n\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t  unsigned addr_len,\n\t\t\t\t  pj_bool_t update)\n{\n    pj_uint32_t hval = 0;\n    pj_sockaddr perm_addr;\n    struct perm_t *perm;\n\n    /* make sure port number if zero */\n    if (pj_sockaddr_get_port(addr) != 0) {\n\tpj_memcpy(&perm_addr, addr, addr_len);\n\tpj_sockaddr_set_port(&perm_addr, 0);\n\taddr = &perm_addr;\n    }\n\n    /* lookup and create if it doesn't exist and wanted */\n    perm = (struct perm_t*) \n\t   pj_hash_get(sess->perm_table, addr, addr_len, &hval);\n    if (perm == NULL && update) {\n\tperm = PJ_POOL_ZALLOC_T(sess->pool, struct perm_t);\n\tpj_memcpy(&perm->addr, addr, addr_len);\n\tperm->hval = hval;\n\n\tpj_hash_set(sess->pool, sess->perm_table, &perm->addr, addr_len,\n\t\t    perm->hval, perm);\n    }\n\n    if (perm && update) {\n\tpj_gettimeofday(&perm->expiry);\n\tperm->expiry.sec += PJ_TURN_PERM_TIMEOUT - sess->ka_interval - 1;\n\n    }\n\n    return perm;\n}\n\n/*\n * Delete permission\n */\nstatic void invalidate_perm(pj_turn_session *sess,\n\t\t\t    struct perm_t *perm)\n{\n    pj_hash_set(NULL, sess->perm_table, &perm->addr,\n\t\tpj_sockaddr_get_len(&perm->addr), perm->hval, NULL);\n}\n\n/*\n * Scan permission's hash table to refresh the permission.\n */\nstatic unsigned refresh_permissions(pj_turn_session *sess, \n\t\t\t\t    const pj_time_val *now)\n{\n    pj_stun_tx_data *tdata = NULL;\n    unsigned count = 0;\n    void *req_token = NULL;\n    pj_hash_iterator_t *it, itbuf;\n    pj_status_t status;\n\n    it = pj_hash_first(sess->perm_table, &itbuf);\n    while (it) {\n\tstruct perm_t *perm = (struct perm_t*)\n\t\t\t      pj_hash_this(sess->perm_table, it);\n\n\tit = pj_hash_next(sess->perm_table, it);\n\n\tif (perm->expiry.sec-1 <= now->sec) {\n\t    if (perm->renew) {\n\t\t/* Renew this permission */\n\t\tif (tdata == NULL) {\n\t\t    /* Create a bare CreatePermission request */\n\t\t    status = pj_stun_session_create_req(\n\t\t\t\t\tsess->stun, \n\t\t\t\t\tPJ_STUN_CREATE_PERM_REQUEST,\n\t\t\t\t\tPJ_STUN_MAGIC, NULL, &tdata);\n\t\t    if (status != PJ_SUCCESS) {\n\t\t\tPJ_LOG(1,(sess->obj_name, \n\t\t\t\t \"Error creating CreatePermission request: %d\",\n\t\t\t\t status));\n\t\t\treturn 0;\n\t\t    }\n\n\t\t    /* Create request token to map the request to the perm\n\t\t     * structures which the request belongs.\n\t\t     */\n\t\t    req_token = (void*)(pj_ssize_t)pj_rand();\n\t\t}\n\n\t\tstatus = pj_stun_msg_add_sockaddr_attr(\n\t\t\t\t\ttdata->pool, \n\t\t\t\t\ttdata->msg,\n\t\t\t\t\tPJ_STUN_ATTR_XOR_PEER_ADDR,\n\t\t\t\t\tPJ_TRUE,\n\t\t\t\t\t&perm->addr,\n\t\t\t\t\tsizeof(perm->addr));\n\t\tif (status != PJ_SUCCESS) {\n\t\t    pj_stun_msg_destroy_tdata(sess->stun, tdata);\n\t\t    return 0;\n\t\t}\n\n\t\tperm->expiry = *now;\n\t\tperm->expiry.sec += PJ_TURN_PERM_TIMEOUT-sess->ka_interval-1;\n\t\tperm->req_token = req_token;\n\t\t++count;\n\n\t    } else {\n\t\t/* This permission has expired and app doesn't want\n\t\t * us to renew, so delete it from the hash table.\n\t\t */\n\t\tinvalidate_perm(sess, perm);\n\t    }\n\t}\n    }\n\n    if (tdata) {\n\tstatus = pj_stun_session_send_msg(sess->stun, req_token, PJ_FALSE, \n\t\t\t\t\t  (sess->conn_type==PJ_TURN_TP_UDP),\n\t\t\t\t\t  sess->srv_addr,\n\t\t\t\t\t  pj_sockaddr_get_len(sess->srv_addr), \n\t\t\t\t\t  tdata);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_LOG(1,(sess->obj_name, \n\t\t      \"Error sending CreatePermission request: %d\",\n\t\t      status));\n\t    count = 0;\n\t}\n\n    }\n\n    return count;\n}\n\n/*\n * Timer event.\n */\nstatic void on_timer_event(pj_timer_heap_t *th, pj_timer_entry *e)\n{\n    pj_turn_session *sess = (pj_turn_session*)e->user_data;\n    enum timer_id_t eid;\n\n    PJ_UNUSED_ARG(th);\n\n    pj_grp_lock_acquire(sess->grp_lock);\n\n    eid = (enum timer_id_t) e->id;\n    e->id = TIMER_NONE;\n    \n    if (eid == TIMER_KEEP_ALIVE) {\n\tpj_time_val now;\n\tpj_hash_iterator_t itbuf, *it;\n\tpj_bool_t resched = PJ_TRUE;\n\tpj_bool_t pkt_sent = PJ_FALSE;\n\n\tif (sess->state >= PJ_TURN_STATE_DEALLOCATING) {\n\t    /* Ignore if we're deallocating */\n\t    goto on_return;\n\t}\n\n\tpj_gettimeofday(&now);\n\n\t/* Refresh allocation if it's time to do so */\n\tif (PJ_TIME_VAL_LTE(sess->expiry, now)) {\n\t    int lifetime = sess->alloc_param.lifetime;\n\n\t    if (lifetime == 0)\n\t\tlifetime = -1;\n\n\t    send_refresh(sess, lifetime);\n\t    resched = PJ_FALSE;\n\t    pkt_sent = PJ_TRUE;\n\t}\n\n\t/* Scan hash table to refresh bound channels */\n\tit = pj_hash_first(sess->ch_table, &itbuf);\n\twhile (it) {\n\t    struct ch_t *ch = (struct ch_t*) \n\t\t\t      pj_hash_this(sess->ch_table, it);\n\t    if (ch->bound && PJ_TIME_VAL_LTE(ch->expiry, now)) {\n\n\t\t/* Send ChannelBind to refresh channel binding and \n\t\t * permission.\n\t\t */\n\t\tpj_turn_session_bind_channel(sess, &ch->addr,\n\t\t\t\t\t     pj_sockaddr_get_len(&ch->addr));\n\t\tpkt_sent = PJ_TRUE;\n\t    }\n\n\t    it = pj_hash_next(sess->ch_table, it);\n\t}\n\n\t/* Scan permission table to refresh permissions */\n\tif (refresh_permissions(sess, &now))\n\t    pkt_sent = PJ_TRUE;\n\n\t/* If no packet is sent, send a blank Send indication to\n\t * refresh local NAT.\n\t */\n\tif (!pkt_sent && sess->alloc_param.ka_interval > 0) {\n\t    pj_stun_tx_data *tdata;\n\t    pj_status_t rc;\n\n\t    /* Create blank SEND-INDICATION */\n\t    rc = pj_stun_session_create_ind(sess->stun, \n\t\t\t\t\t    PJ_STUN_SEND_INDICATION, &tdata);\n\t    if (rc == PJ_SUCCESS) {\n\t\t/* Add DATA attribute with zero length */\n\t\tpj_stun_msg_add_binary_attr(tdata->pool, tdata->msg,\n\t\t\t\t\t    PJ_STUN_ATTR_DATA, NULL, 0);\n\n\t\t/* Send the indication */\n\t\tpj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE, \n\t\t\t\t\t PJ_FALSE, sess->srv_addr,\n\t\t\t\t\t pj_sockaddr_get_len(sess->srv_addr),\n\t\t\t\t\t tdata);\n\t    }\n\t}\n\n\t/* Reshcedule timer */\n\tif (resched) {\n\t    pj_time_val delay;\n\n\t    delay.sec = sess->ka_interval;\n\t    delay.msec = 0;\n\n\t    pj_timer_heap_schedule_w_grp_lock(sess->timer_heap, &sess->timer,\n\t                                      &delay, TIMER_KEEP_ALIVE,\n\t                                      sess->grp_lock);\n\t}\n\n    } else if (eid == TIMER_DESTROY) {\n\t/* Time to destroy */\n\tdo_destroy(sess);\n    } else {\n\tpj_assert(!\"Unknown timer event\");\n    }\n\non_return:\n    pj_grp_lock_release(sess->grp_lock);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjnath/turn_sock.c",
    "content": "/* $Id: turn_sock.c 4360 2013-02-21 11:26:35Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjnath/turn_sock.h>\n#include <pj/activesock.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/ioqueue.h>\n\nenum\n{\n    TIMER_NONE,\n    TIMER_DESTROY\n};\n\n\nenum { MAX_BIND_RETRY = 100 };\n\n\n#define INIT\t0x1FFFFFFF\n\nstruct pj_turn_sock\n{\n    pj_pool_t\t\t*pool;\n    const char\t\t*obj_name;\n    pj_turn_session\t*sess;\n    pj_turn_sock_cb\t cb;\n    void\t\t*user_data;\n\n    pj_bool_t\t\t is_destroying;\n    pj_grp_lock_t\t*grp_lock;\n\n    pj_turn_alloc_param\t alloc_param;\n    pj_stun_config\t cfg;\n    pj_turn_sock_cfg\t setting;\n\n    pj_timer_entry\t timer;\n\n    int\t\t\t af;\n    pj_turn_tp_type\t conn_type;\n    pj_activesock_t\t*active_sock;\n    pj_ioqueue_op_key_t\t send_key;\n};\n\n\n/*\n * Callback prototypes.\n */\nstatic pj_status_t turn_on_send_pkt(pj_turn_session *sess,\n\t\t\t\t    const pj_uint8_t *pkt,\n\t\t\t\t    unsigned pkt_len,\n\t\t\t\t    const pj_sockaddr_t *dst_addr,\n\t\t\t\t    unsigned dst_addr_len);\nstatic void turn_on_channel_bound(pj_turn_session *sess,\n\t\t\t\t  const pj_sockaddr_t *peer_addr,\n\t\t\t\t  unsigned addr_len,\n\t\t\t\t  unsigned ch_num);\nstatic void turn_on_rx_data(pj_turn_session *sess,\n\t\t\t    void *pkt,\n\t\t\t    unsigned pkt_len,\n\t\t\t    const pj_sockaddr_t *peer_addr,\n\t\t\t    unsigned addr_len);\nstatic void turn_on_state(pj_turn_session *sess, \n\t\t\t  pj_turn_state_t old_state,\n\t\t\t  pj_turn_state_t new_state);\n\nstatic pj_bool_t on_data_read(pj_activesock_t *asock,\n\t\t\t      void *data,\n\t\t\t      pj_size_t size,\n\t\t\t      pj_status_t status,\n\t\t\t      pj_size_t *remainder);\nstatic pj_bool_t on_connect_complete(pj_activesock_t *asock,\n\t\t\t\t     pj_status_t status);\n\n\n\nstatic void turn_sock_on_destroy(void *comp);\nstatic void destroy(pj_turn_sock *turn_sock);\nstatic void timer_cb(pj_timer_heap_t *th, pj_timer_entry *e);\n\n\n/* Init config */\nPJ_DEF(void) pj_turn_sock_cfg_default(pj_turn_sock_cfg *cfg)\n{\n    pj_bzero(cfg, sizeof(*cfg));\n    cfg->max_pkt_size = PJ_TURN_MAX_PKT_LEN;\n    cfg->qos_type = PJ_QOS_TYPE_BEST_EFFORT;\n    cfg->qos_ignore_error = PJ_TRUE;\n}\n\n\n/*\n * Create.\n */\nPJ_DEF(pj_status_t) pj_turn_sock_create(pj_stun_config *cfg,\n\t\t\t\t\tint af,\n\t\t\t\t\tpj_turn_tp_type conn_type,\n\t\t\t\t\tconst pj_turn_sock_cb *cb,\n\t\t\t\t\tconst pj_turn_sock_cfg *setting,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tpj_turn_sock **p_turn_sock)\n{\n    pj_turn_sock *turn_sock;\n    pj_turn_session_cb sess_cb;\n    pj_turn_sock_cfg default_setting;\n    pj_pool_t *pool;\n    const char *name_tmpl;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(cfg && p_turn_sock, PJ_EINVAL);\n    PJ_ASSERT_RETURN(af==pj_AF_INET() || af==pj_AF_INET6(), PJ_EINVAL);\n    PJ_ASSERT_RETURN(conn_type!=PJ_TURN_TP_TCP || PJ_HAS_TCP, PJ_EINVAL);\n\n    if (!setting) {\n\tpj_turn_sock_cfg_default(&default_setting);\n\tsetting = &default_setting;\n    }\n\n    switch (conn_type) {\n    case PJ_TURN_TP_UDP:\n\tname_tmpl = \"udprel%p\";\n\tbreak;\n    case PJ_TURN_TP_TCP:\n\tname_tmpl = \"tcprel%p\";\n\tbreak;\n    default:\n\tPJ_ASSERT_RETURN(!\"Invalid TURN conn_type\", PJ_EINVAL);\n\tname_tmpl = \"tcprel%p\";\n\tbreak;\n    }\n\n    /* Create and init basic data structure */\n    pool = pj_pool_create(cfg->pf, name_tmpl, PJNATH_POOL_LEN_TURN_SOCK,\n\t\t\t  PJNATH_POOL_INC_TURN_SOCK, NULL);\n    turn_sock = PJ_POOL_ZALLOC_T(pool, pj_turn_sock);\n    turn_sock->pool = pool;\n    turn_sock->obj_name = pool->obj_name;\n    turn_sock->user_data = user_data;\n    turn_sock->af = af;\n    turn_sock->conn_type = conn_type;\n\n    /* Copy STUN config (this contains ioqueue, timer heap, etc.) */\n    pj_memcpy(&turn_sock->cfg, cfg, sizeof(*cfg));\n\n    /* Copy setting (QoS parameters etc */\n    pj_memcpy(&turn_sock->setting, setting, sizeof(*setting));\n\n    /* Set callback */\n    if (cb) {\n\tpj_memcpy(&turn_sock->cb, cb, sizeof(*cb));\n    }\n\n    /* Session lock */\n    if (setting && setting->grp_lock) {\n\tturn_sock->grp_lock = setting->grp_lock;\n    } else {\n\tstatus = pj_grp_lock_create(pool, NULL, &turn_sock->grp_lock);\n\tif (status != PJ_SUCCESS) {\n\t    pj_pool_release(pool);\n\t    return status;\n\t}\n    }\n\n    pj_grp_lock_add_ref(turn_sock->grp_lock);\n    pj_grp_lock_add_handler(turn_sock->grp_lock, pool, turn_sock,\n                            &turn_sock_on_destroy);\n\n    /* Init timer */\n    pj_timer_entry_init(&turn_sock->timer, TIMER_NONE, turn_sock, &timer_cb);\n\n    /* Init TURN session */\n    pj_bzero(&sess_cb, sizeof(sess_cb));\n    sess_cb.on_send_pkt = &turn_on_send_pkt;\n    sess_cb.on_channel_bound = &turn_on_channel_bound;\n    sess_cb.on_rx_data = &turn_on_rx_data;\n    sess_cb.on_state = &turn_on_state;\n    status = pj_turn_session_create(cfg, pool->obj_name, af, conn_type,\n                                    turn_sock->grp_lock, &sess_cb, 0,\n                                    turn_sock, &turn_sock->sess);\n    if (status != PJ_SUCCESS) {\n\tdestroy(turn_sock);\n\treturn status;\n    }\n\n    /* Note: socket and ioqueue will be created later once the TURN server\n     * has been resolved.\n     */\n\n    *p_turn_sock = turn_sock;\n    return PJ_SUCCESS;\n}\n\n/*\n * Destroy.\n */\nstatic void turn_sock_on_destroy(void *comp)\n{\n    pj_turn_sock *turn_sock = (pj_turn_sock*) comp;\n\n    if (turn_sock->pool) {\n\tpj_pool_t *pool = turn_sock->pool;\n\tPJ_LOG(4,(turn_sock->obj_name, \"TURN socket destroyed\"));\n\tturn_sock->pool = NULL;\n\tpj_pool_release(pool);\n    }\n}\n\nstatic void destroy(pj_turn_sock *turn_sock)\n{\n    PJ_LOG(4,(turn_sock->obj_name, \"TURN socket destroy request, ref_cnt=%d\",\n\t      pj_grp_lock_get_ref(turn_sock->grp_lock)));\n\n    pj_grp_lock_acquire(turn_sock->grp_lock);\n    if (turn_sock->is_destroying) {\n\tpj_grp_lock_release(turn_sock->grp_lock);\n\treturn;\n    }\n\n    turn_sock->is_destroying = PJ_TRUE;\n    if (turn_sock->sess)\n\tpj_turn_session_shutdown(turn_sock->sess);\n    if (turn_sock->active_sock)\n\tpj_activesock_close(turn_sock->active_sock);\n    pj_grp_lock_dec_ref(turn_sock->grp_lock);\n    pj_grp_lock_release(turn_sock->grp_lock);\n}\n\nPJ_DEF(void) pj_turn_sock_destroy(pj_turn_sock *turn_sock)\n{\n    pj_grp_lock_acquire(turn_sock->grp_lock);\n    if (turn_sock->is_destroying) {\n\tpj_grp_lock_release(turn_sock->grp_lock);\n\treturn;\n    }\n\n    if (turn_sock->sess) {\n\tpj_turn_session_shutdown(turn_sock->sess);\n\t/* This will ultimately call our state callback, and when\n\t * session state is DESTROYING we will schedule a timer to\n\t * destroy ourselves.\n\t */\n    } else {\n\tdestroy(turn_sock);\n    }\n\n    pj_grp_lock_release(turn_sock->grp_lock);\n}\n\n\n/* Timer callback */\nstatic void timer_cb(pj_timer_heap_t *th, pj_timer_entry *e)\n{\n    pj_turn_sock *turn_sock = (pj_turn_sock*)e->user_data;\n    int eid = e->id;\n\n    PJ_UNUSED_ARG(th);\n\n    e->id = TIMER_NONE;\n\n    switch (eid) {\n    case TIMER_DESTROY:\n\tdestroy(turn_sock);\n\tbreak;\n    default:\n\tpj_assert(!\"Invalid timer id\");\n\tbreak;\n    }\n}\n\n\n/* Display error */\nstatic void show_err(pj_turn_sock *turn_sock, const char *title,\n\t\t     pj_status_t status)\n{\n    PJ_PERROR(4,(turn_sock->obj_name, status, title));\n}\n\n/* On error, terminate session */\nstatic void sess_fail(pj_turn_sock *turn_sock, const char *title,\n\t\t      pj_status_t status)\n{\n    show_err(turn_sock, title, status);\n    if (turn_sock->sess) {\n\tpj_turn_session_destroy(turn_sock->sess, status);\n    }\n}\n\n/*\n * Set user data.\n */\nPJ_DEF(pj_status_t) pj_turn_sock_set_user_data( pj_turn_sock *turn_sock,\n\t\t\t\t\t       void *user_data)\n{\n    PJ_ASSERT_RETURN(turn_sock, PJ_EINVAL);\n    turn_sock->user_data = user_data;\n    return PJ_SUCCESS;\n}\n\n/*\n * Get user data.\n */\nPJ_DEF(void*) pj_turn_sock_get_user_data(pj_turn_sock *turn_sock)\n{\n    PJ_ASSERT_RETURN(turn_sock, NULL);\n    return turn_sock->user_data;\n}\n\n/*\n * Get group lock.\n */\nPJ_DEF(pj_grp_lock_t *) pj_turn_sock_get_grp_lock(pj_turn_sock *turn_sock)\n{\n    PJ_ASSERT_RETURN(turn_sock, NULL);\n    return turn_sock->grp_lock;\n}\n\n/**\n * Get info.\n */\nPJ_DEF(pj_status_t) pj_turn_sock_get_info(pj_turn_sock *turn_sock,\n\t\t\t\t\t  pj_turn_session_info *info)\n{\n    PJ_ASSERT_RETURN(turn_sock && info, PJ_EINVAL);\n\n    if (turn_sock->sess) {\n\treturn pj_turn_session_get_info(turn_sock->sess, info);\n    } else {\n\tpj_bzero(info, sizeof(*info));\n\tinfo->state = PJ_TURN_STATE_NULL;\n\treturn PJ_SUCCESS;\n    }\n}\n\n/**\n * Lock the TURN socket. Application may need to call this function to\n * synchronize access to other objects to avoid deadlock.\n */\nPJ_DEF(pj_status_t) pj_turn_sock_lock(pj_turn_sock *turn_sock)\n{\n    return pj_grp_lock_acquire(turn_sock->grp_lock);\n}\n\n/**\n * Unlock the TURN socket.\n */\nPJ_DEF(pj_status_t) pj_turn_sock_unlock(pj_turn_sock *turn_sock)\n{\n    return pj_grp_lock_release(turn_sock->grp_lock);\n}\n\n/*\n * Set STUN message logging for this TURN session. \n */\nPJ_DEF(void) pj_turn_sock_set_log( pj_turn_sock *turn_sock,\n\t\t\t\t   unsigned flags)\n{\n    pj_turn_session_set_log(turn_sock->sess, flags);\n}\n\n/*\n * Set software name\n */\nPJ_DEF(pj_status_t) pj_turn_sock_set_software_name( pj_turn_sock *turn_sock,\n\t\t\t\t\t\t    const pj_str_t *sw)\n{\n    return pj_turn_session_set_software_name(turn_sock->sess, sw);\n}\n\n/*\n * Initialize.\n */\nPJ_DEF(pj_status_t) pj_turn_sock_alloc(pj_turn_sock *turn_sock,\n\t\t\t\t       const pj_str_t *domain,\n\t\t\t\t       int default_port,\n\t\t\t\t       pj_dns_resolver *resolver,\n\t\t\t\t       const pj_stun_auth_cred *cred,\n\t\t\t\t       const pj_turn_alloc_param *param)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(turn_sock && domain, PJ_EINVAL);\n    PJ_ASSERT_RETURN(turn_sock->sess, PJ_EINVALIDOP);\n\n    pj_grp_lock_acquire(turn_sock->grp_lock);\n\n    /* Copy alloc param. We will call session_alloc() only after the \n     * server address has been resolved.\n     */\n    if (param) {\n\tpj_turn_alloc_param_copy(turn_sock->pool, &turn_sock->alloc_param, param);\n    } else {\n\tpj_turn_alloc_param_default(&turn_sock->alloc_param);\n    }\n\n    /* Set credental */\n    if (cred) {\n\tstatus = pj_turn_session_set_credential(turn_sock->sess, cred);\n\tif (status != PJ_SUCCESS) {\n\t    sess_fail(turn_sock, \"Error setting credential\", status);\n\t    pj_grp_lock_release(turn_sock->grp_lock);\n\t    return status;\n\t}\n    }\n\n    /* Resolve server */\n    status = pj_turn_session_set_server(turn_sock->sess, domain, default_port,\n\t\t\t\t\tresolver);\n    if (status != PJ_SUCCESS) {\n\tsess_fail(turn_sock, \"Error setting TURN server\", status);\n\tpj_grp_lock_release(turn_sock->grp_lock);\n\treturn status;\n    }\n\n    /* Done for now. The next work will be done when session state moved\n     * to RESOLVED state.\n     */\n    pj_grp_lock_release(turn_sock->grp_lock);\n    return PJ_SUCCESS;\n}\n\n/*\n * Install permission\n */\nPJ_DEF(pj_status_t) pj_turn_sock_set_perm( pj_turn_sock *turn_sock,\n\t\t\t\t\t   unsigned addr_cnt,\n\t\t\t\t\t   const pj_sockaddr addr[],\n\t\t\t\t\t   unsigned options)\n{\n    if (turn_sock->sess == NULL)\n\treturn PJ_EINVALIDOP;\n\n    return pj_turn_session_set_perm(turn_sock->sess, addr_cnt, addr, options);\n}\n\n/*\n * Send packet.\n */ \nPJ_DEF(pj_status_t) pj_turn_sock_sendto( pj_turn_sock *turn_sock,\n\t\t\t\t\tconst pj_uint8_t *pkt,\n\t\t\t\t\tunsigned pkt_len,\n\t\t\t\t\tconst pj_sockaddr_t *addr,\n\t\t\t\t\tunsigned addr_len)\n{\n    PJ_ASSERT_RETURN(turn_sock && addr && addr_len, PJ_EINVAL);\n\n    if (turn_sock->sess == NULL)\n\treturn PJ_EINVALIDOP;\n\n    return pj_turn_session_sendto(turn_sock->sess, pkt, pkt_len, \n\t\t\t\t  addr, addr_len);\n}\n\n/*\n * Bind a peer address to a channel number.\n */\nPJ_DEF(pj_status_t) pj_turn_sock_bind_channel( pj_turn_sock *turn_sock,\n\t\t\t\t\t      const pj_sockaddr_t *peer,\n\t\t\t\t\t      unsigned addr_len)\n{\n    PJ_ASSERT_RETURN(turn_sock && peer && addr_len, PJ_EINVAL);\n    PJ_ASSERT_RETURN(turn_sock->sess != NULL, PJ_EINVALIDOP);\n\n    return pj_turn_session_bind_channel(turn_sock->sess, peer, addr_len);\n}\n\n\n/*\n * Notification when outgoing TCP socket has been connected.\n */\nstatic pj_bool_t on_connect_complete(pj_activesock_t *asock,\n\t\t\t\t     pj_status_t status)\n{\n    pj_turn_sock *turn_sock;\n\n    turn_sock = (pj_turn_sock*) pj_activesock_get_user_data(asock);\n    if (!turn_sock)\n        return PJ_FALSE;\n\n    pj_grp_lock_acquire(turn_sock->grp_lock);\n\n    /* TURN session may have already been destroyed here.\n     * See ticket #1557 (http://trac.pjsip.org/repos/ticket/1557).\n     */\n    if (!turn_sock->sess) {\n\tsess_fail(turn_sock, \"TURN session already destroyed\", status);\n\tpj_grp_lock_release(turn_sock->grp_lock);\n\treturn PJ_FALSE;\n    }\n\n    if (status != PJ_SUCCESS) {\n\tsess_fail(turn_sock, \"TCP connect() error\", status);\n\tpj_grp_lock_release(turn_sock->grp_lock);\n\treturn PJ_FALSE;\n    }\n\n    if (turn_sock->conn_type != PJ_TURN_TP_UDP) {\n\tPJ_LOG(5,(turn_sock->obj_name, \"TCP connected\"));\n    }\n\n    /* Kick start pending read operation */\n    status = pj_activesock_start_read(asock, turn_sock->pool, \n\t\t\t\t      turn_sock->setting.max_pkt_size, 0);\n\n    /* Init send_key */\n    pj_ioqueue_op_key_init(&turn_sock->send_key, sizeof(turn_sock->send_key));\n\n    /* Send Allocate request */\n    status = pj_turn_session_alloc(turn_sock->sess, &turn_sock->alloc_param);\n    if (status != PJ_SUCCESS) {\n\tsess_fail(turn_sock, \"Error sending ALLOCATE\", status);\n\tpj_grp_lock_release(turn_sock->grp_lock);\n\treturn PJ_FALSE;\n    }\n\n    pj_grp_lock_release(turn_sock->grp_lock);\n    return PJ_TRUE;\n}\n\nstatic pj_uint16_t GETVAL16H(const pj_uint8_t *buf, unsigned pos)\n{\n    return (pj_uint16_t) ((buf[pos + 0] << 8) | \\\n\t\t\t  (buf[pos + 1] << 0));\n}\n\n/* Quick check to determine if there is enough packet to process in the\n * incoming buffer. Return the packet length, or zero if there's no packet.\n */\nstatic unsigned has_packet(pj_turn_sock *turn_sock, const void *buf, pj_size_t bufsize)\n{\n    pj_bool_t is_stun;\n\n    if (turn_sock->conn_type == PJ_TURN_TP_UDP)\n\treturn (unsigned)bufsize;\n\n    /* Quickly check if this is STUN message, by checking the first two bits and\n     * size field which must be multiple of 4 bytes\n     */\n    is_stun = ((((pj_uint8_t*)buf)[0] & 0xC0) == 0) &&\n\t      ((GETVAL16H((const pj_uint8_t*)buf, 2) & 0x03)==0);\n\n    if (is_stun) {\n\tpj_size_t msg_len = GETVAL16H((const pj_uint8_t*)buf, 2);\n\treturn (unsigned)((msg_len+20 <= bufsize) ? msg_len+20 : 0);\n    } else {\n\t/* This must be ChannelData. */\n\tpj_turn_channel_data cd;\n\n\tif (bufsize < 4)\n\t    return 0;\n\n\t/* Decode ChannelData packet */\n\tpj_memcpy(&cd, buf, sizeof(pj_turn_channel_data));\n\tcd.length = pj_ntohs(cd.length);\n\n\tif (bufsize >= cd.length+sizeof(cd)) \n\t    return (cd.length+sizeof(cd)+3) & (~3);\n\telse\n\t    return 0;\n    }\n}\n\n/*\n * Notification from ioqueue when incoming UDP packet is received.\n */\nstatic pj_bool_t on_data_read(pj_activesock_t *asock,\n\t\t\t      void *data,\n\t\t\t      pj_size_t size,\n\t\t\t      pj_status_t status,\n\t\t\t      pj_size_t *remainder)\n{\n    pj_turn_sock *turn_sock;\n    pj_bool_t ret = PJ_TRUE;\n\n    turn_sock = (pj_turn_sock*) pj_activesock_get_user_data(asock);\n    pj_grp_lock_acquire(turn_sock->grp_lock);\n\n    if (status == PJ_SUCCESS && turn_sock->sess && !turn_sock->is_destroying) {\n\t/* Report incoming packet to TURN session, repeat while we have\n\t * \"packet\" in the buffer (required for stream-oriented transports)\n\t */\n\tunsigned pkt_len;\n\n\t//PJ_LOG(5,(turn_sock->pool->obj_name, \n\t//\t  \"Incoming data, %lu bytes total buffer\", size));\n\n\twhile ((pkt_len=has_packet(turn_sock, data, size)) != 0) {\n\t    pj_size_t parsed_len;\n\t    //const pj_uint8_t *pkt = (const pj_uint8_t*)data;\n\n\t    //PJ_LOG(5,(turn_sock->pool->obj_name, \n\t    //\t      \"Packet start: %02X %02X %02X %02X\", \n\t    //\t      pkt[0], pkt[1], pkt[2], pkt[3]));\n\n\t    //PJ_LOG(5,(turn_sock->pool->obj_name, \n\t    //\t      \"Processing %lu bytes packet of %lu bytes total buffer\",\n\t    //\t      pkt_len, size));\n\n\t    parsed_len = (unsigned)size;\n\t    pj_turn_session_on_rx_pkt(turn_sock->sess, data,  size, &parsed_len);\n\n\t    /* parsed_len may be zero if we have parsing error, so use our\n\t     * previous calculation to exhaust the bad packet.\n\t     */\n\t    if (parsed_len == 0)\n\t\tparsed_len = pkt_len;\n\n\t    if (parsed_len < (unsigned)size) {\n\t\t*remainder = size - parsed_len;\n\t\tpj_memmove(data, ((char*)data)+parsed_len, *remainder);\n\t    } else {\n\t\t*remainder = 0;\n\t    }\n\t    size = *remainder;\n\n\t    //PJ_LOG(5,(turn_sock->pool->obj_name, \n\t    //\t      \"Buffer size now %lu bytes\", size));\n\t}\n    } else if (status != PJ_SUCCESS && \n\t       turn_sock->conn_type != PJ_TURN_TP_UDP) \n    {\n\tsess_fail(turn_sock, \"TCP connection closed\", status);\n\tret = PJ_FALSE;\n\tgoto on_return;\n    }\n\non_return:\n    pj_grp_lock_release(turn_sock->grp_lock);\n\n    return ret;\n}\n\n\n/*\n * Callback from TURN session to send outgoing packet.\n */\nstatic pj_status_t turn_on_send_pkt(pj_turn_session *sess,\n\t\t\t\t    const pj_uint8_t *pkt,\n\t\t\t\t    unsigned pkt_len,\n\t\t\t\t    const pj_sockaddr_t *dst_addr,\n\t\t\t\t    unsigned dst_addr_len)\n{\n    pj_turn_sock *turn_sock = (pj_turn_sock*) \n\t\t\t      pj_turn_session_get_user_data(sess);\n    pj_ssize_t len = pkt_len;\n    pj_status_t status;\n\n    if (turn_sock == NULL || turn_sock->is_destroying) {\n\t/* We've been destroyed */\n\t// https://trac.pjsip.org/repos/ticket/1316\n\t//pj_assert(!\"We should shutdown gracefully\");\n\treturn PJ_EINVALIDOP;\n    }\n\n    PJ_UNUSED_ARG(dst_addr);\n    PJ_UNUSED_ARG(dst_addr_len);\n\n    status = pj_activesock_send(turn_sock->active_sock, &turn_sock->send_key,\n\t\t\t\tpkt, &len, 0);\n    if (status != PJ_SUCCESS && status != PJ_EPENDING) {\n\tshow_err(turn_sock, \"socket send()\", status);\n    }\n\n    return status;\n}\n\n\n/*\n * Callback from TURN session when a channel is successfully bound.\n */\nstatic void turn_on_channel_bound(pj_turn_session *sess,\n\t\t\t\t  const pj_sockaddr_t *peer_addr,\n\t\t\t\t  unsigned addr_len,\n\t\t\t\t  unsigned ch_num)\n{\n    PJ_UNUSED_ARG(sess);\n    PJ_UNUSED_ARG(peer_addr);\n    PJ_UNUSED_ARG(addr_len);\n    PJ_UNUSED_ARG(ch_num);\n}\n\n\n/*\n * Callback from TURN session upon incoming data.\n */\nstatic void turn_on_rx_data(pj_turn_session *sess,\n\t\t\t    void *pkt,\n\t\t\t    unsigned pkt_len,\n\t\t\t    const pj_sockaddr_t *peer_addr,\n\t\t\t    unsigned addr_len)\n{\n    pj_turn_sock *turn_sock = (pj_turn_sock*) \n\t\t\t   pj_turn_session_get_user_data(sess);\n    if (turn_sock == NULL || turn_sock->is_destroying) {\n\t/* We've been destroyed */\n\treturn;\n    }\n\n    if (turn_sock->cb.on_rx_data) {\n\t(*turn_sock->cb.on_rx_data)(turn_sock, pkt, pkt_len, \n\t\t\t\t  peer_addr, addr_len);\n    }\n}\n\n\n/*\n * Callback from TURN session when state has changed\n */\nstatic void turn_on_state(pj_turn_session *sess, \n\t\t\t  pj_turn_state_t old_state,\n\t\t\t  pj_turn_state_t new_state)\n{\n    pj_turn_sock *turn_sock = (pj_turn_sock*) \n\t\t\t   pj_turn_session_get_user_data(sess);\n    pj_status_t status;\n\n    if (turn_sock == NULL) {\n\t/* We've been destroyed */\n\treturn;\n    }\n\n    /* Notify app first */\n    if (turn_sock->cb.on_state) {\n\t(*turn_sock->cb.on_state)(turn_sock, old_state, new_state);\n    }\n\n    /* Make sure user hasn't destroyed us in the callback */\n    if (turn_sock->sess && new_state == PJ_TURN_STATE_RESOLVED) {\n\tpj_turn_session_info info;\n\tpj_turn_session_get_info(turn_sock->sess, &info);\n\tnew_state = info.state;\n    }\n\n    if (turn_sock->sess && new_state == PJ_TURN_STATE_RESOLVED) {\n\t/*\n\t * Once server has been resolved, initiate outgoing TCP\n\t * connection to the server.\n\t */\n\tpj_turn_session_info info;\n\tchar addrtxt[PJ_INET6_ADDRSTRLEN+8];\n\tint sock_type;\n\tpj_sock_t sock;\n\tpj_activesock_cfg asock_cfg;\n\tpj_activesock_cb asock_cb;\n\tpj_sockaddr bound_addr, *cfg_bind_addr;\n\tpj_uint16_t max_bind_retry;\n\n\t/* Close existing connection, if any. This happens when\n\t * we're switching to alternate TURN server when either TCP\n\t * connection or ALLOCATE request failed.\n\t */\n\tif (turn_sock->active_sock) {\n\t    pj_activesock_close(turn_sock->active_sock);\n\t    turn_sock->active_sock = NULL;\n\t}\n\n\t/* Get server address from session info */\n\tpj_turn_session_get_info(sess, &info);\n\n\tif (turn_sock->conn_type == PJ_TURN_TP_UDP)\n\t    sock_type = pj_SOCK_DGRAM();\n\telse\n\t    sock_type = pj_SOCK_STREAM();\n\n\t/* Init socket */\n\tstatus = pj_sock_socket(turn_sock->af, sock_type, 0, &sock);\n\tif (status != PJ_SUCCESS) {\n\t    pj_turn_sock_destroy(turn_sock);\n\t    return;\n\t}\n\n\t/* Bind socket */\n\tcfg_bind_addr = &turn_sock->setting.bound_addr;\n\tmax_bind_retry = MAX_BIND_RETRY;\n\tif (turn_sock->setting.port_range &&\n\t    turn_sock->setting.port_range < max_bind_retry)\n\t{\n\t    max_bind_retry = turn_sock->setting.port_range;\n\t}\n\tpj_sockaddr_init(turn_sock->af, &bound_addr, NULL, 0);\n\tif (cfg_bind_addr->addr.sa_family == pj_AF_INET() || \n\t    cfg_bind_addr->addr.sa_family == pj_AF_INET6())\n\t{\n\t    pj_sockaddr_cp(&bound_addr, cfg_bind_addr);\n\t}\n\tstatus = pj_sock_bind_random(sock, &bound_addr,\n\t\t\t\t     turn_sock->setting.port_range,\n\t\t\t\t     max_bind_retry);\n\tif (status != PJ_SUCCESS) {\n\t    pj_turn_sock_destroy(turn_sock);\n\t    return;\n\t}\n\n\t/* Apply QoS, if specified */\n\tstatus = pj_sock_apply_qos2(sock, turn_sock->setting.qos_type,\n\t\t\t\t    &turn_sock->setting.qos_params, \n\t\t\t\t    (turn_sock->setting.qos_ignore_error?2:1),\n\t\t\t\t    turn_sock->pool->obj_name, NULL);\n\tif (status != PJ_SUCCESS && !turn_sock->setting.qos_ignore_error) {\n\t    pj_turn_sock_destroy(turn_sock);\n\t    return;\n\t}\n\n\t/* Apply socket buffer size */\n\tif (turn_sock->setting.so_rcvbuf_size > 0) {\n\t    unsigned sobuf_size = turn_sock->setting.so_rcvbuf_size;\n\t    status = pj_sock_setsockopt_sobuf(sock, pj_SO_RCVBUF(),\n\t\t\t\t\t      PJ_TRUE, &sobuf_size);\n\t    if (status != PJ_SUCCESS) {\n\t\tpj_perror(3, turn_sock->obj_name, status,\n\t\t\t  \"Failed setting SO_RCVBUF\");\n\t    } else {\n\t\tif (sobuf_size < turn_sock->setting.so_rcvbuf_size) {\n\t\t    PJ_LOG(4, (turn_sock->obj_name, \n\t\t\t       \"Warning! Cannot set SO_RCVBUF as configured,\"\n\t\t\t       \" now=%d, configured=%d\", sobuf_size,\n\t\t\t       turn_sock->setting.so_rcvbuf_size));\n\t\t} else {\n\t\t    PJ_LOG(5, (turn_sock->obj_name, \"SO_RCVBUF set to %d\",\n\t\t\t       sobuf_size));\n\t\t}\n\t    }\n\t}\n\tif (turn_sock->setting.so_sndbuf_size > 0) {\n\t    unsigned sobuf_size = turn_sock->setting.so_sndbuf_size;\n\t    status = pj_sock_setsockopt_sobuf(sock, pj_SO_SNDBUF(),\n\t\t\t\t\t      PJ_TRUE, &sobuf_size);\n\t    if (status != PJ_SUCCESS) {\n\t\tpj_perror(3, turn_sock->obj_name, status,\n\t\t\t  \"Failed setting SO_SNDBUF\");\n\t    } else {\n\t\tif (sobuf_size < turn_sock->setting.so_sndbuf_size) {\n\t\t    PJ_LOG(4, (turn_sock->obj_name, \n\t\t\t       \"Warning! Cannot set SO_SNDBUF as configured,\"\n\t\t\t       \" now=%d, configured=%d\", sobuf_size,\n\t\t\t       turn_sock->setting.so_sndbuf_size));\n\t\t} else {\n\t\t    PJ_LOG(5, (turn_sock->obj_name, \"SO_SNDBUF set to %d\",\n\t\t\t       sobuf_size));\n\t\t}\n\t    }\n\t}\n\n\t/* Create active socket */\n\tpj_activesock_cfg_default(&asock_cfg);\n\tasock_cfg.grp_lock = turn_sock->grp_lock;\n\n\tpj_bzero(&asock_cb, sizeof(asock_cb));\n\tasock_cb.on_data_read = &on_data_read;\n\tasock_cb.on_connect_complete = &on_connect_complete;\n\tstatus = pj_activesock_create(turn_sock->pool, sock,\n\t\t\t\t      sock_type, &asock_cfg,\n\t\t\t\t      turn_sock->cfg.ioqueue, &asock_cb, \n\t\t\t\t      turn_sock,\n\t\t\t\t      &turn_sock->active_sock);\n\tif (status != PJ_SUCCESS) {\n\t    pj_turn_sock_destroy(turn_sock);\n\t    return;\n\t}\n\n\tPJ_LOG(5,(turn_sock->pool->obj_name,\n\t\t  \"Connecting to %s\", \n\t\t  pj_sockaddr_print(&info.server, addrtxt, \n\t\t\t\t    sizeof(addrtxt), 3)));\n\n\t/* Initiate non-blocking connect */\n#if PJ_HAS_TCP\n\tstatus=pj_activesock_start_connect(turn_sock->active_sock, \n\t\t\t\t\t   turn_sock->pool,\n\t\t\t\t\t   &info.server, \n\t\t\t\t\t   pj_sockaddr_get_len(&info.server));\n\tif (status == PJ_SUCCESS) {\n\t    on_connect_complete(turn_sock->active_sock, PJ_SUCCESS);\n\t} else if (status != PJ_EPENDING) {\n\t    pj_turn_sock_destroy(turn_sock);\n\t    return;\n\t}\n#else\n\ton_connect_complete(turn_sock->active_sock, PJ_SUCCESS);\n#endif\n\n\t/* Done for now. Subsequent work will be done in \n\t * on_connect_complete() callback.\n\t */\n    }\n\n    if (new_state >= PJ_TURN_STATE_DESTROYING && turn_sock->sess) {\n\tpj_time_val delay = {0, 0};\n\n\tturn_sock->sess = NULL;\n\tpj_turn_session_set_user_data(sess, NULL);\n\n\tpj_timer_heap_cancel_if_active(turn_sock->cfg.timer_heap,\n\t                               &turn_sock->timer, 0);\n\tpj_timer_heap_schedule_w_grp_lock(turn_sock->cfg.timer_heap,\n\t                                  &turn_sock->timer,\n\t                                  &delay, TIMER_DESTROY,\n\t                                  turn_sock->grp_lock);\n    }\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjturn-client/client_main.c",
    "content": "/* $Id: client_main.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjnath.h>\n#include <pjlib-util.h>\n#include <pjlib.h>\n\n\n#define THIS_FILE\t\"client_main.c\"\n#define LOCAL_PORT\t1998\n#define BANDWIDTH\t64\t\t    /* -1 to disable */\n#define LIFETIME\t600\t\t    /* -1 to disable */\n#define REQ_TRANSPORT\t-1\t\t    /* 0: udp, 1: tcp, -1: disable */\n#define REQ_PORT_PROPS\t-1\t\t    /* -1 to disable */\n#define REQ_IP\t\t0\t\t    /* IP address string */\n\n//#define OPTIONS\t\tPJ_STUN_NO_AUTHENTICATE\n#define OPTIONS\t\t0\n\n\nstruct peer\n{\n    pj_stun_sock   *stun_sock;\n    pj_sockaddr\t    mapped_addr;\n};\n\n\nstatic struct global\n{\n    pj_caching_pool\t cp;\n    pj_pool_t\t\t*pool;\n    pj_stun_config\t stun_config;\n    pj_thread_t\t\t*thread;\n    pj_bool_t\t\t quit;\n\n    pj_dns_resolver\t*resolver;\n\n    pj_turn_sock\t*relay;\n    pj_sockaddr\t\t relay_addr;\n\n    struct peer\t\t peer[2];\n} g;\n\nstatic struct options\n{\n    pj_bool_t\t use_tcp;\n    char\t*srv_addr;\n    char\t*srv_port;\n    char\t*realm;\n    char\t*user_name;\n    char\t*password;\n    pj_bool_t\t use_fingerprint;\n    char\t*stun_server;\n    char\t*nameserver;\n} o;\n\n\nstatic int worker_thread(void *unused);\nstatic void turn_on_rx_data(pj_turn_sock *relay,\n\t\t\t    void *pkt,\n\t\t\t    unsigned pkt_len,\n\t\t\t    const pj_sockaddr_t *peer_addr,\n\t\t\t    unsigned addr_len);\nstatic void turn_on_state(pj_turn_sock *relay, pj_turn_state_t old_state,\n\t\t\t  pj_turn_state_t new_state);\nstatic pj_bool_t stun_sock_on_status(pj_stun_sock *stun_sock, \n\t\t\t\t     pj_stun_sock_op op,\n\t\t\t\t     pj_status_t status);\nstatic pj_bool_t stun_sock_on_rx_data(pj_stun_sock *stun_sock,\n\t\t\t\t      void *pkt,\n\t\t\t\t      unsigned pkt_len,\n\t\t\t\t      const pj_sockaddr_t *src_addr,\n\t\t\t\t      unsigned addr_len);\n\n\nstatic void my_perror(const char *title, pj_status_t status)\n{\n    char errmsg[PJ_ERR_MSG_SIZE];\n    pj_strerror(status, errmsg, sizeof(errmsg));\n\n    PJ_LOG(3,(THIS_FILE, \"%s: %s\", title, errmsg));\n}\n\n#define CHECK(expr)\tstatus=expr; \\\n\t\t\tif (status!=PJ_SUCCESS) { \\\n\t\t\t    my_perror(#expr, status); \\\n\t\t\t    return status; \\\n\t\t\t}\n\nstatic int init()\n{\n    int i;\n    pj_status_t status;\n\n    CHECK( pj_init() );\n    CHECK( pjlib_util_init() );\n    CHECK( pjnath_init() );\n\n    /* Check that server is specified */\n    if (!o.srv_addr) {\n\tprintf(\"Error: server must be specified\\n\");\n\treturn PJ_EINVAL;\n    }\n\n    pj_caching_pool_init(&g.cp, &pj_pool_factory_default_policy, 0);\n\n    g.pool = pj_pool_create(&g.cp.factory, \"main\", 1000, 1000, NULL);\n\n    /* Init global STUN config */\n    pj_stun_config_init(&g.stun_config, &g.cp.factory, 0, NULL, NULL);\n\n    /* Create global timer heap */\n    CHECK( pj_timer_heap_create(g.pool, 1000, &g.stun_config.timer_heap) );\n\n    /* Create global ioqueue */\n    CHECK( pj_ioqueue_create(g.pool, 16, &g.stun_config.ioqueue) );\n\n    /* \n     * Create peers\n     */\n    for (i=0; i<(int)PJ_ARRAY_SIZE(g.peer); ++i) {\n\tpj_stun_sock_cb stun_sock_cb;\n\tchar name[] = \"peer0\";\n\tpj_uint16_t port;\n\tpj_stun_sock_cfg ss_cfg;\n\tpj_str_t server;\n\n\tpj_bzero(&stun_sock_cb, sizeof(stun_sock_cb));\n\tstun_sock_cb.on_rx_data = &stun_sock_on_rx_data;\n\tstun_sock_cb.on_status = &stun_sock_on_status;\n\n\tg.peer[i].mapped_addr.addr.sa_family = pj_AF_INET();\n\n\tpj_stun_sock_cfg_default(&ss_cfg);\n#if 1\n\t/* make reading the log easier */\n\tss_cfg.ka_interval = 300;\n#endif\n\n\tname[strlen(name)-1] = '0'+i;\n\tstatus = pj_stun_sock_create(&g.stun_config, name, pj_AF_INET(), \n\t\t\t\t     &stun_sock_cb, &ss_cfg,\n\t\t\t\t     &g.peer[i], &g.peer[i].stun_sock);\n\tif (status != PJ_SUCCESS) {\n\t    my_perror(\"pj_stun_sock_create()\", status);\n\t    return status;\n\t}\n\n\tif (o.stun_server) {\n\t    server = pj_str(o.stun_server);\n\t    port = PJ_STUN_PORT;\n\t} else {\n\t    server = pj_str(o.srv_addr);\n\t    port = (pj_uint16_t)(o.srv_port?atoi(o.srv_port):PJ_STUN_PORT);\n\t}\n\tstatus = pj_stun_sock_start(g.peer[i].stun_sock, &server, \n\t\t\t\t    port,  NULL);\n\tif (status != PJ_SUCCESS) {\n\t    my_perror(\"pj_stun_sock_start()\", status);\n\t    return status;\n\t}\n    }\n\n    /* Start the worker thread */\n    CHECK( pj_thread_create(g.pool, \"stun\", &worker_thread, NULL, 0, 0, &g.thread) );\n\n\n    return PJ_SUCCESS;\n}\n\n\nstatic int client_shutdown()\n{\n    unsigned i;\n\n    if (g.thread) {\n\tg.quit = 1;\n\tpj_thread_join(g.thread);\n\tpj_thread_destroy(g.thread);\n\tg.thread = NULL;\n    }\n    if (g.relay) {\n\tpj_turn_sock_destroy(g.relay);\n\tg.relay = NULL;\n    }\n    for (i=0; i<PJ_ARRAY_SIZE(g.peer); ++i) {\n\tif (g.peer[i].stun_sock) {\n\t    pj_stun_sock_destroy(g.peer[i].stun_sock);\n\t    g.peer[i].stun_sock = NULL;\n\t}\n    }\n    if (g.stun_config.timer_heap) {\n\tpj_timer_heap_destroy(g.stun_config.timer_heap);\n\tg.stun_config.timer_heap = NULL;\n    }\n    if (g.stun_config.ioqueue) {\n\tpj_ioqueue_destroy(g.stun_config.ioqueue);\n\tg.stun_config.ioqueue = NULL;\n    }\n    if (g.pool) {\n\tpj_pool_release(g.pool);\n\tg.pool = NULL;\n    }\n    pj_pool_factory_dump(&g.cp.factory, PJ_TRUE);\n    pj_caching_pool_destroy(&g.cp);\n\n    return PJ_SUCCESS;\n}\n\n\nstatic int worker_thread(void *unused)\n{\n    PJ_UNUSED_ARG(unused);\n\n    while (!g.quit) {\n\tconst pj_time_val delay = {0, 10};\n\n\t/* Poll ioqueue for the TURN client */\n\tpj_ioqueue_poll(g.stun_config.ioqueue, &delay);\n\n\t/* Poll the timer heap */\n\tpj_timer_heap_poll(g.stun_config.timer_heap, NULL);\n\n    }\n\n    return 0;\n}\n\nstatic pj_status_t create_relay(void)\n{\n    pj_turn_sock_cb rel_cb;\n    pj_stun_auth_cred cred;\n    pj_str_t srv;\n    pj_status_t status;\n\n    if (g.relay) {\n\tPJ_LOG(1,(THIS_FILE, \"Relay already created\"));\n\treturn -1;\n    }\n\n    /* Create DNS resolver if configured */\n    if (o.nameserver) {\n\tpj_str_t ns = pj_str(o.nameserver);\n\n\tstatus = pj_dns_resolver_create(&g.cp.factory, \"resolver\", 0, \n\t\t\t\t\tg.stun_config.timer_heap, \n\t\t\t\t\tg.stun_config.ioqueue, &g.resolver);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_LOG(1,(THIS_FILE, \"Error creating resolver (err=%d)\", status));\n\t    return status;\n\t}\n\n\tstatus = pj_dns_resolver_set_ns(g.resolver, 1, &ns, NULL);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_LOG(1,(THIS_FILE, \"Error configuring nameserver (err=%d)\", status));\n\t    return status;\n\t}\n    }\n\n    pj_bzero(&rel_cb, sizeof(rel_cb));\n    rel_cb.on_rx_data = &turn_on_rx_data;\n    rel_cb.on_state = &turn_on_state;\n    CHECK( pj_turn_sock_create(&g.stun_config, pj_AF_INET(), \n\t\t\t       (o.use_tcp? PJ_TURN_TP_TCP : PJ_TURN_TP_UDP),\n\t\t\t       &rel_cb, 0,\n\t\t\t       NULL, &g.relay) );\n\n    if (o.user_name) {\n\tpj_bzero(&cred, sizeof(cred));\n\tcred.type = PJ_STUN_AUTH_CRED_STATIC;\n\tcred.data.static_cred.realm = pj_str(o.realm);\n\tcred.data.static_cred.username = pj_str(o.user_name);\n\tcred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN;\n\tcred.data.static_cred.data = pj_str(o.password);\n\t//cred.data.static_cred.nonce = pj_str(o.nonce);\n    } else {\n\tPJ_LOG(2,(THIS_FILE, \"Warning: no credential is set\"));\n    }\n\n    srv = pj_str(o.srv_addr);\n    CHECK(pj_turn_sock_alloc(g.relay,\t\t\t\t /* the relay */\n\t\t\t    &srv,\t\t\t\t /* srv addr */\n\t\t\t    (o.srv_port?atoi(o.srv_port):PJ_STUN_PORT),/* def port */\n\t\t\t    g.resolver,\t\t\t\t /* resolver */\n\t\t\t    (o.user_name?&cred:NULL),\t\t /* credential */\n\t\t\t    NULL)\t\t\t\t /* alloc param */\n\t\t\t    );\n\n    return PJ_SUCCESS;\n}\n\nstatic void destroy_relay(void)\n{\n    if (g.relay) {\n\tpj_turn_sock_destroy(g.relay);\n    }\n}\n\n\nstatic void turn_on_rx_data(pj_turn_sock *relay,\n\t\t\t    void *pkt,\n\t\t\t    unsigned pkt_len,\n\t\t\t    const pj_sockaddr_t *peer_addr,\n\t\t\t    unsigned addr_len)\n{\n    char addrinfo[80];\n\n    pj_sockaddr_print(peer_addr, addrinfo, sizeof(addrinfo), 3);\n\n    PJ_LOG(3,(THIS_FILE, \"Client received %d bytes data from %s: %.*s\",\n\t      pkt_len, addrinfo, pkt_len, pkt));\n}\n\n\nstatic void turn_on_state(pj_turn_sock *relay, pj_turn_state_t old_state,\n\t\t\t  pj_turn_state_t new_state)\n{\n    PJ_LOG(3,(THIS_FILE, \"State %s --> %s\", pj_turn_state_name(old_state), \n\t      pj_turn_state_name(new_state)));\n\n    if (new_state == PJ_TURN_STATE_READY) {\n\tpj_turn_session_info info;\n\tpj_turn_sock_get_info(relay, &info);\n\tpj_memcpy(&g.relay_addr, &info.relay_addr, sizeof(pj_sockaddr));\n    } else if (new_state > PJ_TURN_STATE_READY && g.relay) {\n\tPJ_LOG(3,(THIS_FILE, \"Relay shutting down..\"));\n\tg.relay = NULL;\n    }\n}\n\nstatic pj_bool_t stun_sock_on_status(pj_stun_sock *stun_sock, \n\t\t\t\t     pj_stun_sock_op op,\n\t\t\t\t     pj_status_t status)\n{\n    struct peer *peer = (struct peer*) pj_stun_sock_get_user_data(stun_sock);\n\n    if (status == PJ_SUCCESS) {\n\tPJ_LOG(4,(THIS_FILE, \"peer%d: %s success\", peer-g.peer,\n\t\t  pj_stun_sock_op_name(op)));\n    } else {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\tpj_strerror(status, errmsg, sizeof(errmsg));\n\tPJ_LOG(1,(THIS_FILE, \"peer%d: %s error: %s\", peer-g.peer,\n\t\t  pj_stun_sock_op_name(op), errmsg));\n\treturn PJ_FALSE;\n    }\n\n    if (op==PJ_STUN_SOCK_BINDING_OP || op==PJ_STUN_SOCK_KEEP_ALIVE_OP) {\n\tpj_stun_sock_info info;\n\tint cmp;\n\n\tpj_stun_sock_get_info(stun_sock, &info);\n\tcmp = pj_sockaddr_cmp(&info.mapped_addr, &peer->mapped_addr);\n\n\tif (cmp) {\n\t    char straddr[PJ_INET6_ADDRSTRLEN+10];\n\n\t    pj_sockaddr_cp(&peer->mapped_addr, &info.mapped_addr);\n\t    pj_sockaddr_print(&peer->mapped_addr, straddr, sizeof(straddr), 3);\n\t    PJ_LOG(3,(THIS_FILE, \"peer%d: STUN mapped address is %s\",\n\t\t      peer-g.peer, straddr));\n\t}\n    }\n\n    return PJ_TRUE;\n}\n\nstatic pj_bool_t stun_sock_on_rx_data(pj_stun_sock *stun_sock,\n\t\t\t\t      void *pkt,\n\t\t\t\t      unsigned pkt_len,\n\t\t\t\t      const pj_sockaddr_t *src_addr,\n\t\t\t\t      unsigned addr_len)\n{\n    struct peer *peer = (struct peer*) pj_stun_sock_get_user_data(stun_sock);\n    char straddr[PJ_INET6_ADDRSTRLEN+10];\n\n    ((char*)pkt)[pkt_len] = '\\0';\n\n    pj_sockaddr_print(src_addr, straddr, sizeof(straddr), 3);\n    PJ_LOG(3,(THIS_FILE, \"peer%d: received %d bytes data from %s: %s\",\n\t      peer-g.peer, pkt_len, straddr, (char*)pkt));\n\n    return PJ_TRUE;\n}\n\n\nstatic void menu(void)\n{\n    pj_turn_session_info info;\n    char client_state[20], relay_addr[80], peer0_addr[80], peer1_addr[80];\n\n    if (g.relay) {\n\tpj_turn_sock_get_info(g.relay, &info);\n\tstrcpy(client_state, pj_turn_state_name(info.state));\n\tif (info.state >= PJ_TURN_STATE_READY)\n\t    pj_sockaddr_print(&info.relay_addr, relay_addr, sizeof(relay_addr), 3);\n\telse\n\t    strcpy(relay_addr, \"0.0.0.0:0\");\n    } else {\n\tstrcpy(client_state, \"NULL\");\n\tstrcpy(relay_addr, \"0.0.0.0:0\");\n    }\n\n    pj_sockaddr_print(&g.peer[0].mapped_addr, peer0_addr, sizeof(peer0_addr), 3);\n    pj_sockaddr_print(&g.peer[1].mapped_addr, peer1_addr, sizeof(peer1_addr), 3);\n\n\n    puts(\"\\n\");\n    puts(\"+=====================================================================+\");\n    puts(\"|             CLIENT                 |             PEER-0             |\");\n    puts(\"|                                    |                                |\");\n    printf(\"| State     : %-12s           | Address: %-21s |\\n\",\n\t   client_state, peer0_addr);\n    printf(\"| Relay addr: %-21s  |                                |\\n\",\n\t   relay_addr);\n    puts(\"|                                    | 0  Send data to relay address  |\");\n    puts(\"| a      Allocate relay              |                                |\");\n    puts(\"| p,pp   Set permission for peer 0/1 +--------------------------------+\");\n    puts(\"| s,ss   Send data to peer 0/1       |             PEER-1             |\");\n    puts(\"| b,bb   BindChannel to peer 0/1     |                                |\");\n    printf(\"| x      Delete allocation           | Address: %-21s |\\n\",\n\t  peer1_addr);\n    puts(\"+------------------------------------+                                |\");\n    puts(\"| q  Quit                  d  Dump   | 1  Send data to relay adderss  |\");\n    puts(\"+------------------------------------+--------------------------------+\");\n    printf(\">>> \");\n    fflush(stdout);\n}\n\n\nstatic void console_main(void)\n{\n    while (!g.quit) {\n\tchar input[32];\n\tstruct peer *peer;\n\tpj_status_t status;\n\n\tmenu();\n\n\tif (fgets(input, sizeof(input), stdin) == NULL)\n\t    break;\n\t\n\tswitch (input[0]) {\n\tcase 'a':\n\t    create_relay();\n\t    break;\n\tcase 'd':\n\t    pj_pool_factory_dump(&g.cp.factory, PJ_TRUE);\n\t    break;\n\tcase 's':\n\t    if (g.relay == NULL) {\n\t\tputs(\"Error: no relay\");\n\t\tcontinue;\n\t    }\n\t    if (input[1]!='s')\n\t\tpeer = &g.peer[0];\n\t    else\n\t\tpeer = &g.peer[1];\n\n\t    strcpy(input, \"Hello from client\");\n\t    status = pj_turn_sock_sendto(g.relay, (const pj_uint8_t*)input, \n\t\t\t\t\tstrlen(input)+1, \n\t\t\t\t\t&peer->mapped_addr, \n\t\t\t\t\tpj_sockaddr_get_len(&peer->mapped_addr));\n\t    if (status != PJ_SUCCESS)\n\t\tmy_perror(\"turn_udp_sendto() failed\", status);\n\t    break;\n\tcase 'b':\n\t    if (g.relay == NULL) {\n\t\tputs(\"Error: no relay\");\n\t\tcontinue;\n\t    }\n\t    if (input[1]!='b')\n\t\tpeer = &g.peer[0];\n\t    else\n\t\tpeer = &g.peer[1];\n\n\t    status = pj_turn_sock_bind_channel(g.relay, &peer->mapped_addr,\n\t\t\t\t\t      pj_sockaddr_get_len(&peer->mapped_addr));\n\t    if (status != PJ_SUCCESS)\n\t\tmy_perror(\"turn_udp_bind_channel() failed\", status);\n\t    break;\n\tcase 'p':\n\t    if (g.relay == NULL) {\n\t\tputs(\"Error: no relay\");\n\t\tcontinue;\n\t    }\n\t    if (input[1]!='p')\n\t\tpeer = &g.peer[0];\n\t    else\n\t\tpeer = &g.peer[1];\n\n\t    status = pj_turn_sock_set_perm(g.relay, 1, &peer->mapped_addr, 1);\n\t    if (status != PJ_SUCCESS)\n\t\tmy_perror(\"pj_turn_sock_set_perm() failed\", status);\n\t    break;\n\tcase 'x':\n\t    if (g.relay == NULL) {\n\t\tputs(\"Error: no relay\");\n\t\tcontinue;\n\t    }\n\t    destroy_relay();\n\t    break;\n\tcase '0':\n\tcase '1':\n\t    if (g.relay == NULL) {\n\t\tputs(\"No relay\");\n\t\tbreak;\n\t    }\n\t    peer = &g.peer[input[0]-'0'];\n\t    sprintf(input, \"Hello from peer%d\", input[0]-'0');\n\t    pj_stun_sock_sendto(peer->stun_sock, NULL, input, strlen(input)+1, 0,\n\t\t\t\t&g.relay_addr, pj_sockaddr_get_len(&g.relay_addr));\n\t    break;\n\tcase 'q':\n\t    g.quit = PJ_TRUE;\n\t    break;\n\t}\n    }\n}\n\n\nstatic void usage(void)\n{\n    puts(\"Usage: pjturn_client TURN-SERVER [OPTIONS]\");\n    puts(\"\");\n    puts(\"where TURN-SERVER is \\\"host[:port]\\\"\");\n    puts(\"\");\n    puts(\"and OPTIONS:\");\n    puts(\" --tcp, -T             Use TCP to connect to TURN server\");\n    puts(\" --realm, -r REALM     Set realm of the credential to REALM\");\n    puts(\" --username, -u UID    Set username of the credential to UID\");\n    puts(\" --password, -p PASSWD Set password of the credential to PASSWD\");\n    puts(\" --fingerprint, -F     Use fingerprint for outgoing requests\");\n    puts(\" --stun-srv, -S  NAME  Use this STUN srv instead of TURN for Binding discovery\");\n    puts(\" --nameserver, -N IP   Activate DNS SRV, use this DNS server\");\n    puts(\" --help, -h\");\n}\n\nint main(int argc, char *argv[])\n{\n    struct pj_getopt_option long_options[] = {\n\t{ \"realm\",\t1, 0, 'r'},\n\t{ \"username\",\t1, 0, 'u'},\n\t{ \"password\",\t1, 0, 'p'},\n\t{ \"fingerprint\",0, 0, 'F'},\n\t{ \"tcp\",        0, 0, 'T'},\n\t{ \"help\",\t0, 0, 'h'},\n\t{ \"stun-srv\",   1, 0, 'S'},\n\t{ \"nameserver\", 1, 0, 'N'}\n    };\n    int c, opt_id;\n    char *pos;\n    pj_status_t status;\n\n    while((c=pj_getopt_long(argc,argv, \"r:u:p:S:N:hFT\", long_options, &opt_id))!=-1) {\n\tswitch (c) {\n\tcase 'r':\n\t    o.realm = pj_optarg;\n\t    break;\n\tcase 'u':\n\t    o.user_name = pj_optarg;\n\t    break;\n\tcase 'p':\n\t    o.password = pj_optarg;\n\t    break;\n\tcase 'h':\n\t    usage();\n\t    return 0;\n\tcase 'F':\n\t    o.use_fingerprint = PJ_TRUE;\n\t    break;\n\tcase 'T':\n\t    o.use_tcp = PJ_TRUE;\n\t    break;\n\tcase 'S':\n\t    o.stun_server = pj_optarg;\n\t    break;\n\tcase 'N':\n\t    o.nameserver = pj_optarg;\n\t    break;\n\tdefault:\n\t    printf(\"Argument \\\"%s\\\" is not valid. Use -h to see help\",\n\t\t   argv[pj_optind]);\n\t    return 1;\n\t}\n    }\n\n    if (pj_optind == argc) {\n\tputs(\"Error: TARGET is needed\");\n\tusage();\n\treturn 1;\n    }\n\n    if ((pos=pj_ansi_strchr(argv[pj_optind], ':')) != NULL) {\n\to.srv_addr = argv[pj_optind];\n\t*pos = '\\0';\n\to.srv_port = pos+1;\n    } else {\n\to.srv_addr = argv[pj_optind];\n    }\n\n    if ((status=init()) != 0)\n\tgoto on_return;\n    \n    //if ((status=create_relay()) != 0)\n    //\tgoto on_return;\n    \n    console_main();\n\non_return:\n    client_shutdown();\n    return status ? 1 : 0;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjturn-srv/allocation.c",
    "content": "/* $Id: allocation.c 4360 2013-02-21 11:26:35Z bennylp $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include \"turn.h\"\n#include \"auth.h\"\n\n\n#define THIS_FILE   \"allocation.c\"\n\n\nenum {\n    TIMER_ID_NONE,\n    TIMER_ID_TIMEOUT,\n    TIMER_ID_DESTROY\n};\n\n#define DESTROY_DELAY\t    {0, 500}\n#define PEER_TABLE_SIZE\t    32\n\n#define MAX_CLIENT_BANDWIDTH\t128  /* In Kbps */\n#define DEFA_CLIENT_BANDWIDTH\t64\n\n#define MIN_LIFETIME\t\t30\n#define MAX_LIFETIME\t\t600\n#define DEF_LIFETIME\t\t300\n\n\n/* Parsed Allocation request. */\ntypedef struct alloc_request\n{\n    unsigned\t\ttp_type;\t\t    /* Requested transport  */\n    char\t\taddr[PJ_INET6_ADDRSTRLEN];  /* Requested IP\t    */\n    unsigned\t\tbandwidth;\t\t    /* Requested bandwidth  */\n    unsigned\t\tlifetime;\t\t    /* Lifetime.\t    */\n    unsigned\t\trpp_bits;\t\t    /* A bits\t\t    */\n    unsigned\t\trpp_port;\t\t    /* Requested port\t    */\n} alloc_request;\n\n\n\n/* Prototypes */\nstatic void destroy_allocation(pj_turn_allocation *alloc);\nstatic pj_status_t create_relay(pj_turn_srv *srv,\n\t\t\t\tpj_turn_allocation *alloc,\n\t\t\t\tconst pj_stun_msg *msg,\n\t\t\t\tconst alloc_request *req,\n\t\t\t\tpj_turn_relay_res *relay);\nstatic void destroy_relay(pj_turn_relay_res *relay);\nstatic void on_rx_from_peer(pj_ioqueue_key_t *key,\n                            pj_ioqueue_op_key_t *op_key,\n                            pj_ssize_t bytes_read);\nstatic pj_status_t stun_on_send_msg(pj_stun_session *sess,\n\t\t\t\t    void *token,\n\t\t\t\t    const void *pkt,\n\t\t\t\t    pj_size_t pkt_size,\n\t\t\t\t    const pj_sockaddr_t *dst_addr,\n\t\t\t\t    unsigned addr_len);\nstatic pj_status_t stun_on_rx_request(pj_stun_session *sess,\n\t\t\t\t      const pj_uint8_t *pkt,\n\t\t\t\t      unsigned pkt_len,\n\t\t\t\t      const pj_stun_rx_data *rdata,\n\t\t\t\t      void *token,\n\t\t\t\t      const pj_sockaddr_t *src_addr,\n\t\t\t\t      unsigned src_addr_len);\nstatic pj_status_t stun_on_rx_indication(pj_stun_session *sess,\n\t\t\t\t\t const pj_uint8_t *pkt,\n\t\t\t\t\t unsigned pkt_len,\n\t\t\t\t\t const pj_stun_msg *msg,\n\t\t\t\t\t void *token,\n\t\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t\t unsigned src_addr_len);\n\n/* Log allocation error */\nstatic void alloc_err(pj_turn_allocation *alloc, const char *title,\n\t\t      pj_status_t status)\n{\n    char errmsg[PJ_ERR_MSG_SIZE];\n\n    pj_strerror(status, errmsg, sizeof(errmsg));\n    PJ_LOG(4,(alloc->obj_name, \"%s for client %s: %s\",\n\t      title, alloc->info, errmsg));\n}\n\n\n/* Parse ALLOCATE request */\nstatic pj_status_t parse_allocate_req(alloc_request *cfg,\n\t\t\t\t      pj_stun_session *sess,\n\t\t\t\t      const pj_stun_rx_data *rdata,\n\t\t\t\t      const pj_sockaddr_t *src_addr,\n\t\t\t\t      unsigned src_addr_len)\n{\n    const pj_stun_msg *req = rdata->msg;\n    pj_stun_bandwidth_attr *attr_bw;\n    pj_stun_req_transport_attr *attr_req_tp;\n    pj_stun_res_token_attr *attr_res_token;\n    pj_stun_lifetime_attr *attr_lifetime;\n\n    pj_bzero(cfg, sizeof(*cfg));\n\n    /* Get BANDWIDTH attribute, if any. */\n    attr_bw = (pj_stun_uint_attr*)\n\t      pj_stun_msg_find_attr(req, PJ_STUN_ATTR_BANDWIDTH, 0);\n    if (attr_bw) {\n\tcfg->bandwidth = attr_bw->value;\n    } else {\n\tcfg->bandwidth = DEFA_CLIENT_BANDWIDTH;\n    }\n\n    /* Check if we can satisfy the bandwidth */\n    if (cfg->bandwidth > MAX_CLIENT_BANDWIDTH) {\n\tpj_stun_session_respond(sess, rdata,\n\t\t\t\tPJ_STUN_SC_ALLOCATION_QUOTA_REACHED,\n\t\t\t        \"Invalid bandwidth\", NULL, PJ_TRUE,\n\t\t\t\tsrc_addr, src_addr_len);\n\treturn PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_ALLOCATION_QUOTA_REACHED);\n    }\n\n    /* MUST have REQUESTED-TRANSPORT attribute */\n    attr_req_tp = (pj_stun_uint_attr*)\n\t          pj_stun_msg_find_attr(req, PJ_STUN_ATTR_REQ_TRANSPORT, 0);\n    if (attr_req_tp == NULL) {\n\tpj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST,\n\t\t\t        \"Missing REQUESTED-TRANSPORT attribute\",\n\t\t\t\tNULL, PJ_TRUE, src_addr, src_addr_len);\n\treturn PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST);\n    }\n\n    cfg->tp_type = PJ_STUN_GET_RT_PROTO(attr_req_tp->value);\n\n    /* Can only support UDP for now */\n    if (cfg->tp_type != PJ_TURN_TP_UDP) {\n\tpj_stun_session_respond(sess, rdata, PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO,\n\t\t\t\tNULL, NULL, PJ_TRUE, src_addr, src_addr_len);\n\treturn PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO);\n    }\n\n    /* Get RESERVATION-TOKEN attribute, if any */\n    attr_res_token = (pj_stun_res_token_attr*)\n\t             pj_stun_msg_find_attr(req, PJ_STUN_ATTR_RESERVATION_TOKEN,\n\t\t\t\t\t   0);\n    if (attr_res_token) {\n\t/* We don't support RESERVATION-TOKEN for now */\n\tpj_stun_session_respond(sess, rdata,\n\t\t\t\tPJ_STUN_SC_BAD_REQUEST,\n\t\t\t\t\"RESERVATION-TOKEN is not supported\", NULL,\n\t\t\t\tPJ_TRUE, src_addr, src_addr_len);\n\treturn PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST);\n    }\n\n    /* Get LIFETIME attribute */\n    attr_lifetime = (pj_stun_uint_attr*)\n\t            pj_stun_msg_find_attr(req, PJ_STUN_ATTR_LIFETIME, 0);\n    if (attr_lifetime) {\n\tcfg->lifetime = attr_lifetime->value;\n\tif (cfg->lifetime < MIN_LIFETIME) {\n\t    pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST,\n\t\t\t\t    \"LIFETIME too short\", NULL,\n\t\t\t\t    PJ_TRUE, src_addr, src_addr_len);\n\t    return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST);\n\t}\n\tif (cfg->lifetime > MAX_LIFETIME)\n\t    cfg->lifetime = MAX_LIFETIME;\n    } else {\n\tcfg->lifetime = DEF_LIFETIME;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* Respond to ALLOCATE request */\nstatic pj_status_t send_allocate_response(pj_turn_allocation *alloc,\n\t\t\t\t\t  pj_stun_session *srv_sess,\n\t\t\t\t\t  pj_turn_transport *transport,\n\t\t\t\t\t  const pj_stun_rx_data *rdata)\n{\n    pj_stun_tx_data *tdata;\n    pj_status_t status;\n\n    /* Respond the original ALLOCATE request */\n    status = pj_stun_session_create_res(srv_sess, rdata, 0, NULL, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Add XOR-RELAYED-ADDRESS attribute */\n    pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,\n\t\t\t\t  PJ_STUN_ATTR_XOR_RELAYED_ADDR, PJ_TRUE,\n\t\t\t\t  &alloc->relay.hkey.addr,\n\t\t\t\t  pj_sockaddr_get_len(&alloc->relay.hkey.addr));\n\n    /* Add LIFETIME. */\n    pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,\n\t\t\t      PJ_STUN_ATTR_LIFETIME,\n\t\t\t      (unsigned)alloc->relay.lifetime);\n\n    /* Add BANDWIDTH */\n    pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,\n\t\t\t      PJ_STUN_ATTR_BANDWIDTH,\n\t\t\t      alloc->bandwidth);\n\n    /* Add RESERVATION-TOKEN */\n    PJ_TODO(ADD_RESERVATION_TOKEN);\n\n    /* Add XOR-MAPPED-ADDRESS */\n    pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,\n\t\t\t\t  PJ_STUN_ATTR_XOR_MAPPED_ADDR, PJ_TRUE,\n\t\t\t\t  &alloc->hkey.clt_addr,\n\t\t\t\t  pj_sockaddr_get_len(&alloc->hkey.clt_addr));\n\n    /* Send the response */\n    return pj_stun_session_send_msg(srv_sess, transport, PJ_TRUE,\n\t\t\t\t    PJ_FALSE, &alloc->hkey.clt_addr,\n\t\t\t\t    pj_sockaddr_get_len(&alloc->hkey.clt_addr),\n\t\t\t\t    tdata);\n}\n\n\n/*\n * Init credential for the allocation. We use static credential, meaning that\n * the user's password must not change during allocation.\n */\nstatic pj_status_t init_cred(pj_turn_allocation *alloc, const pj_stun_msg *req)\n{\n    const pj_stun_username_attr *user;\n    const pj_stun_realm_attr *realm;\n    const pj_stun_nonce_attr *nonce;\n    pj_status_t status;\n\n    realm = (const pj_stun_realm_attr*)\n\t    pj_stun_msg_find_attr(req, PJ_STUN_ATTR_REALM, 0);\n    PJ_ASSERT_RETURN(realm != NULL, PJ_EBUG);\n\n    user = (const pj_stun_username_attr*)\n\t   pj_stun_msg_find_attr(req, PJ_STUN_ATTR_USERNAME, 0);\n    PJ_ASSERT_RETURN(user != NULL, PJ_EBUG);\n\n    nonce = (const pj_stun_nonce_attr*)\n\t    pj_stun_msg_find_attr(req, PJ_STUN_ATTR_NONCE, 0);\n    PJ_ASSERT_RETURN(nonce != NULL, PJ_EBUG);\n\n    /* Lookup the password */\n    status = pj_turn_get_password(NULL, NULL, &realm->value,\n\t\t\t\t  &user->value, alloc->pool,\n\t\t\t\t  &alloc->cred.data.static_cred.data_type,\n\t\t\t\t  &alloc->cred.data.static_cred.data);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Save credential */\n    alloc->cred.type = PJ_STUN_AUTH_CRED_STATIC;\n    pj_strdup(alloc->pool, &alloc->cred.data.static_cred.realm, &realm->value);\n    pj_strdup(alloc->pool, &alloc->cred.data.static_cred.username, &user->value);\n    pj_strdup(alloc->pool, &alloc->cred.data.static_cred.nonce, &nonce->value);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create new allocation.\n */\nPJ_DEF(pj_status_t) pj_turn_allocation_create(pj_turn_transport *transport,\n\t\t\t\t\t      const pj_sockaddr_t *src_addr,\n\t\t\t\t\t      unsigned src_addr_len,\n\t\t\t\t\t      const pj_stun_rx_data *rdata,\n\t\t\t\t\t      pj_stun_session *srv_sess,\n\t\t\t\t\t      pj_turn_allocation **p_alloc)\n{\n    pj_turn_srv *srv = transport->listener->server;\n    const pj_stun_msg *msg = rdata->msg;\n    pj_pool_t *pool;\n    alloc_request req;\n    pj_turn_allocation *alloc;\n    pj_stun_session_cb sess_cb;\n    char str_tmp[80];\n    pj_status_t status;\n\n    /* Parse ALLOCATE request */\n    status = parse_allocate_req(&req, srv_sess, rdata, src_addr, src_addr_len);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pool = pj_pool_create(srv->core.pf, \"alloc%p\", 1000, 1000, NULL);\n\n    /* Init allocation structure */\n    alloc = PJ_POOL_ZALLOC_T(pool, pj_turn_allocation);\n    alloc->pool = pool;\n    alloc->obj_name = pool->obj_name;\n    alloc->relay.tp.sock = PJ_INVALID_SOCKET;\n    alloc->server = transport->listener->server;\n\n    alloc->bandwidth = req.bandwidth;\n\n    /* Set transport */\n    alloc->transport = transport;\n    pj_turn_transport_add_ref(transport, alloc);\n\n    alloc->hkey.tp_type = transport->listener->tp_type;\n    pj_memcpy(&alloc->hkey.clt_addr, src_addr, src_addr_len);\n\n    status = pj_lock_create_recursive_mutex(pool, alloc->obj_name,\n\t\t\t\t\t    &alloc->lock);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    /* Create peer hash table */\n    alloc->peer_table = pj_hash_create(pool, PEER_TABLE_SIZE);\n\n    /* Create channel hash table */\n    alloc->ch_table = pj_hash_create(pool, PEER_TABLE_SIZE);\n\n    /* Print info */\n    pj_ansi_strcpy(alloc->info,\n\t\t   pj_turn_tp_type_name(transport->listener->tp_type));\n    alloc->info[3] = ':';\n    pj_sockaddr_print(src_addr, alloc->info+4, sizeof(alloc->info)-4, 3);\n\n    /* Create STUN session to handle STUN communication with client */\n    pj_bzero(&sess_cb, sizeof(sess_cb));\n    sess_cb.on_send_msg = &stun_on_send_msg;\n    sess_cb.on_rx_request = &stun_on_rx_request;\n    sess_cb.on_rx_indication = &stun_on_rx_indication;\n    status = pj_stun_session_create(&srv->core.stun_cfg, alloc->obj_name,\n\t\t\t\t    &sess_cb, PJ_FALSE, NULL, &alloc->sess);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    /* Attach to STUN session */\n    pj_stun_session_set_user_data(alloc->sess, alloc);\n\n    /* Init authentication credential */\n    status = init_cred(alloc, msg);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    /* Attach authentication credential to STUN session */\n    pj_stun_session_set_credential(alloc->sess, PJ_STUN_AUTH_LONG_TERM,\n\t\t\t\t   &alloc->cred);\n\n    /* Create the relay resource */\n    status = create_relay(srv, alloc, msg, &req, &alloc->relay);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    /* Register this allocation */\n    pj_turn_srv_register_allocation(srv, alloc);\n\n    /* Respond to ALLOCATE request */\n    status = send_allocate_response(alloc, srv_sess, transport, rdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Done */\n    pj_sockaddr_print(&alloc->relay.hkey.addr, str_tmp,\n\t\t      sizeof(str_tmp), 3);\n    PJ_LOG(4,(alloc->obj_name, \"Client %s created, relay addr=%s:%s\",\n\t      alloc->info, pj_turn_tp_type_name(req.tp_type), str_tmp));\n\n    /* Success */\n    *p_alloc = alloc;\n    return PJ_SUCCESS;\n\non_error:\n    /* Send reply to the ALLOCATE request */\n    pj_strerror(status, str_tmp, sizeof(str_tmp));\n    pj_stun_session_respond(srv_sess, rdata, PJ_STUN_SC_BAD_REQUEST, str_tmp,\n\t\t\t    transport, PJ_TRUE, src_addr, src_addr_len);\n\n    /* Cleanup */\n    destroy_allocation(alloc);\n    return status;\n}\n\n\n/* Destroy relay resource */\nstatic void destroy_relay(pj_turn_relay_res *relay)\n{\n    if (relay->timer.id) {\n\tpj_timer_heap_cancel(relay->allocation->server->core.timer_heap,\n\t\t\t     &relay->timer);\n\trelay->timer.id = PJ_FALSE;\n    }\n\n    if (relay->tp.key) {\n\tpj_ioqueue_unregister(relay->tp.key);\n\trelay->tp.key = NULL;\n\trelay->tp.sock = PJ_INVALID_SOCKET;\n    } else if (relay->tp.sock != PJ_INVALID_SOCKET) {\n\tpj_sock_close(relay->tp.sock);\n\trelay->tp.sock = PJ_INVALID_SOCKET;\n    }\n\n    /* Mark as shutdown */\n    relay->lifetime = 0;\n}\n\n\n/*\n * Really destroy allocation.\n */\nstatic void destroy_allocation(pj_turn_allocation *alloc)\n{\n    pj_pool_t *pool;\n\n    /* Unregister this allocation */\n    pj_turn_srv_unregister_allocation(alloc->server, alloc);\n\n    /* Destroy relay */\n    destroy_relay(&alloc->relay);\n\n    /* Must lock only after destroying relay otherwise deadlock */\n    if (alloc->lock) {\n\tpj_lock_acquire(alloc->lock);\n    }\n\n    /* Unreference transport */\n    if (alloc->transport) {\n\tpj_turn_transport_dec_ref(alloc->transport, alloc);\n\talloc->transport = NULL;\n    }\n\n    /* Destroy STUN session */\n    if (alloc->sess) {\n\tpj_stun_session_destroy(alloc->sess);\n\talloc->sess = NULL;\n    }\n\n    /* Destroy lock */\n    if (alloc->lock) {\n\tpj_lock_release(alloc->lock);\n\tpj_lock_destroy(alloc->lock);\n\talloc->lock = NULL;\n    }\n\n    /* Destroy pool */\n    pool = alloc->pool;\n    if (pool) {\n\talloc->pool = NULL;\n\tpj_pool_release(pool);\n    }\n}\n\n\nPJ_DECL(void) pj_turn_allocation_destroy(pj_turn_allocation *alloc)\n{\n    destroy_allocation(alloc);\n}\n\n\n/*\n * Handle transport closure.\n */\nPJ_DEF(void) pj_turn_allocation_on_transport_closed( pj_turn_allocation *alloc,\n\t\t\t\t\t\t     pj_turn_transport *tp)\n{\n    PJ_LOG(5,(alloc->obj_name, \"Transport %s unexpectedly closed, destroying \"\n\t      \"allocation %s\", tp->info, alloc->info));\n    pj_turn_transport_dec_ref(tp, alloc);\n    alloc->transport = NULL;\n    destroy_allocation(alloc);\n}\n\n\n/* Initiate shutdown sequence for this allocation and start destroy timer.\n * Once allocation is marked as shutting down, any packets will be\n * rejected/discarded\n */\nstatic void alloc_shutdown(pj_turn_allocation *alloc)\n{\n    pj_time_val destroy_delay = DESTROY_DELAY;\n\n    /* Work with existing schedule */\n    if (alloc->relay.timer.id == TIMER_ID_TIMEOUT) {\n\t/* Cancel existing shutdown timer */\n\tpj_timer_heap_cancel(alloc->server->core.timer_heap,\n\t\t\t     &alloc->relay.timer);\n\talloc->relay.timer.id = TIMER_ID_NONE;\n\n    } else if (alloc->relay.timer.id == TIMER_ID_DESTROY) {\n\t/* We've been scheduled to be destroyed, ignore this\n\t * shutdown request.\n\t */\n\treturn;\n    }\n\n    pj_assert(alloc->relay.timer.id == TIMER_ID_NONE);\n\n    /* Shutdown relay socket */\n    destroy_relay(&alloc->relay);\n\n    /* Don't unregister from hash table because we still need to\n     * handle REFRESH retransmission.\n     */\n\n    /* Schedule destroy timer */\n    alloc->relay.timer.id = TIMER_ID_DESTROY;\n    pj_timer_heap_schedule(alloc->server->core.timer_heap,\n\t\t\t   &alloc->relay.timer, &destroy_delay);\n}\n\n\n/* Reschedule timeout using current lifetime setting */\nstatic pj_status_t resched_timeout(pj_turn_allocation *alloc)\n{\n    pj_time_val delay;\n    pj_status_t status;\n\n    pj_gettimeofday(&alloc->relay.expiry);\n    alloc->relay.expiry.sec += alloc->relay.lifetime;\n\n    pj_assert(alloc->relay.timer.id != TIMER_ID_DESTROY);\n    if (alloc->relay.timer.id != 0) {\n\tpj_timer_heap_cancel(alloc->server->core.timer_heap,\n\t\t\t     &alloc->relay.timer);\n\talloc->relay.timer.id = TIMER_ID_NONE;\n    }\n\n    delay.sec = alloc->relay.lifetime;\n    delay.msec = 0;\n\n    alloc->relay.timer.id = TIMER_ID_TIMEOUT;\n    status = pj_timer_heap_schedule(alloc->server->core.timer_heap,\n\t\t\t\t    &alloc->relay.timer, &delay);\n    if (status != PJ_SUCCESS) {\n\talloc->relay.timer.id = TIMER_ID_NONE;\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* Timer timeout callback */\nstatic void relay_timeout_cb(pj_timer_heap_t *heap, pj_timer_entry *e)\n{\n    pj_turn_relay_res *rel;\n    pj_turn_allocation *alloc;\n\n    PJ_UNUSED_ARG(heap);\n\n    rel = (pj_turn_relay_res*) e->user_data;\n    alloc = rel->allocation;\n\n    if (e->id == TIMER_ID_TIMEOUT) {\n\n\te->id = TIMER_ID_NONE;\n\n\tPJ_LOG(4,(alloc->obj_name,\n\t\t  \"Client %s refresh timed-out, shutting down..\",\n\t\t  alloc->info));\n\n\talloc_shutdown(alloc);\n\n    } else if (e->id == TIMER_ID_DESTROY) {\n\te->id = TIMER_ID_NONE;\n\n\tPJ_LOG(4,(alloc->obj_name, \"Client %s destroying..\",\n\t\t  alloc->info));\n\n\tdestroy_allocation(alloc);\n    }\n}\n\n\n/*\n * Create relay.\n */\nstatic pj_status_t create_relay(pj_turn_srv *srv,\n\t\t\t\tpj_turn_allocation *alloc,\n\t\t\t\tconst pj_stun_msg *msg,\n\t\t\t\tconst alloc_request *req,\n\t\t\t\tpj_turn_relay_res *relay)\n{\n    enum { RETRY = 40 };\n    pj_pool_t *pool = alloc->pool;\n    int retry, retry_max, sock_type;\n    pj_ioqueue_callback icb;\n    int af, namelen;\n    pj_stun_string_attr *sa;\n    pj_status_t status;\n\n    pj_bzero(relay, sizeof(*relay));\n\n    relay->allocation = alloc;\n    relay->tp.sock = PJ_INVALID_SOCKET;\n\n    /* TODO: get the requested address family from somewhere */\n    af = alloc->transport->listener->addr.addr.sa_family;\n\n    /* Save realm */\n    sa = (pj_stun_string_attr*)\n\t pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_REALM, 0);\n    PJ_ASSERT_RETURN(sa, PJ_EINVALIDOP);\n    pj_strdup(pool, &relay->realm, &sa->value);\n\n    /* Save username */\n    sa = (pj_stun_string_attr*)\n\t pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_USERNAME, 0);\n    PJ_ASSERT_RETURN(sa, PJ_EINVALIDOP);\n    pj_strdup(pool, &relay->user, &sa->value);\n\n    /* Lifetime and timeout */\n    relay->lifetime = req->lifetime;\n    pj_timer_entry_init(&relay->timer, TIMER_ID_NONE, relay,\n\t\t\t&relay_timeout_cb);\n    resched_timeout(alloc);\n\n    /* Transport type */\n    relay->hkey.tp_type = req->tp_type;\n\n    /* Create the socket */\n    if (req->tp_type == PJ_TURN_TP_UDP) {\n\tsock_type = pj_SOCK_DGRAM();\n    } else if (req->tp_type == PJ_TURN_TP_TCP) {\n\tsock_type = pj_SOCK_STREAM();\n    } else {\n\tpj_assert(!\"Unknown transport\");\n\treturn PJ_EINVALIDOP;\n    }\n\n    status = pj_sock_socket(af, sock_type, 0, &relay->tp.sock);\n    if (status != PJ_SUCCESS) {\n\tpj_bzero(relay, sizeof(*relay));\n\treturn status;\n    }\n\n    /* Find suitable port for this allocation */\n    if (req->rpp_port) {\n\tretry_max = 1;\n    } else {\n\tretry_max = RETRY;\n    }\n\n    for (retry=0; retry<retry_max; ++retry) {\n\tpj_uint16_t port;\n\tpj_sockaddr bound_addr;\n\n\tpj_lock_acquire(srv->core.lock);\n\n\tif (req->rpp_port) {\n\t    port = (pj_uint16_t) req->rpp_port;\n\t} else if (req->tp_type == PJ_TURN_TP_UDP) {\n\t    port = (pj_uint16_t) srv->ports.next_udp++;\n\t    if (srv->ports.next_udp > srv->ports.max_udp)\n\t\tsrv->ports.next_udp = srv->ports.min_udp;\n\t} else if (req->tp_type == PJ_TURN_TP_TCP) {\n\t    port = (pj_uint16_t) srv->ports.next_tcp++;\n\t    if (srv->ports.next_tcp > srv->ports.max_tcp)\n\t\tsrv->ports.next_tcp = srv->ports.min_tcp;\n\t} else {\n\t    pj_assert(!\"Invalid transport\");\n\t    port = 0;\n\t}\n\n\tpj_lock_release(srv->core.lock);\n\n\tpj_sockaddr_init(af, &bound_addr, NULL, port);\n\n\tstatus = pj_sock_bind(relay->tp.sock, &bound_addr,\n\t\t\t      pj_sockaddr_get_len(&bound_addr));\n\tif (status == PJ_SUCCESS)\n\t    break;\n    }\n\n    if (status != PJ_SUCCESS) {\n\t/* Unable to allocate port */\n\tPJ_LOG(4,(THIS_FILE, \"Unable to allocate relay, giving up: err %d\",\n\t\t  status));\n\tpj_sock_close(relay->tp.sock);\n\trelay->tp.sock = PJ_INVALID_SOCKET;\n\treturn status;\n    }\n\n    /* Init relay key */\n    namelen = sizeof(relay->hkey.addr);\n    status = pj_sock_getsockname(relay->tp.sock, &relay->hkey.addr, &namelen);\n    if (status != PJ_SUCCESS) {\n\tPJ_LOG(4,(THIS_FILE, \"pj_sock_getsockname() failed: err %d\",\n\t\t  status));\n\tpj_sock_close(relay->tp.sock);\n\trelay->tp.sock = PJ_INVALID_SOCKET;\n\treturn status;\n    }\n    if (!pj_sockaddr_has_addr(&relay->hkey.addr)) {\n\tpj_sockaddr_copy_addr(&relay->hkey.addr,\n\t\t\t      &alloc->transport->listener->addr);\n    }\n    if (!pj_sockaddr_has_addr(&relay->hkey.addr)) {\n\tpj_sockaddr tmp_addr;\n\tpj_gethostip(af, &tmp_addr);\n\tpj_sockaddr_copy_addr(&relay->hkey.addr, &tmp_addr);\n    }\n\n    /* Init ioqueue */\n    pj_bzero(&icb, sizeof(icb));\n    icb.on_read_complete = &on_rx_from_peer;\n\n    status = pj_ioqueue_register_sock(pool, srv->core.ioqueue, relay->tp.sock,\n\t\t\t\t      relay, &icb, &relay->tp.key);\n    if (status != PJ_SUCCESS) {\n\tPJ_LOG(4,(THIS_FILE, \"pj_ioqueue_register_sock() failed: err %d\",\n\t\t  status));\n\tpj_sock_close(relay->tp.sock);\n\trelay->tp.sock = PJ_INVALID_SOCKET;\n\treturn status;\n    }\n\n    /* Kick off pending read operation */\n    pj_ioqueue_op_key_init(&relay->tp.read_key, sizeof(relay->tp.read_key));\n    on_rx_from_peer(relay->tp.key, &relay->tp.read_key, 0);\n\n    /* Done */\n    return PJ_SUCCESS;\n}\n\n/* Create and send error response */\nstatic void send_reply_err(pj_turn_allocation *alloc,\n\t\t\t   const pj_stun_rx_data *rdata,\n\t\t\t   pj_bool_t cache,\n\t\t\t   int code, const char *errmsg)\n{\n    pj_status_t status;\n\n    status = pj_stun_session_respond(alloc->sess, rdata, code, errmsg, NULL,\n\t\t\t\t     cache, &alloc->hkey.clt_addr,\n\t\t\t\t     pj_sockaddr_get_len(&alloc->hkey.clt_addr.addr));\n    if (status != PJ_SUCCESS) {\n\talloc_err(alloc, \"Error sending STUN error response\", status);\n\treturn;\n    }\n}\n\n/* Create and send successful response */\nstatic void send_reply_ok(pj_turn_allocation *alloc,\n\t\t          const pj_stun_rx_data *rdata)\n{\n    pj_status_t status;\n    unsigned interval;\n    pj_stun_tx_data *tdata;\n\n    status = pj_stun_session_create_res(alloc->sess, rdata, 0, NULL, &tdata);\n    if (status != PJ_SUCCESS) {\n\talloc_err(alloc, \"Error creating STUN success response\", status);\n\treturn;\n    }\n\n    /* Calculate time to expiration */\n    if (alloc->relay.lifetime != 0) {\n\tpj_time_val now;\n\tpj_gettimeofday(&now);\n\tinterval = alloc->relay.expiry.sec - now.sec;\n    } else {\n\tinterval = 0;\n    }\n\n    /* Add LIFETIME if this is not ChannelBind. */\n    if (PJ_STUN_GET_METHOD(tdata->msg->hdr.type)!=PJ_STUN_CHANNEL_BIND_METHOD){\n\tpj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,\n\t\t\t\t  PJ_STUN_ATTR_LIFETIME, interval);\n\n\t/* Add BANDWIDTH if lifetime is not zero */\n\tif (interval != 0) {\n\t    pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,\n\t\t\t\t      PJ_STUN_ATTR_BANDWIDTH,\n\t\t\t\t      alloc->bandwidth);\n\t}\n    }\n\n    status = pj_stun_session_send_msg(alloc->sess, NULL, PJ_TRUE,\n\t\t\t\t      PJ_FALSE, &alloc->hkey.clt_addr,\n\t\t\t\t      pj_sockaddr_get_len(&alloc->hkey.clt_addr),\n\t\t\t\t      tdata);\n    if (status != PJ_SUCCESS) {\n\talloc_err(alloc, \"Error sending STUN success response\", status);\n\treturn;\n    }\n}\n\n\n/* Create new permission */\nstatic pj_turn_permission *create_permission(pj_turn_allocation *alloc,\n\t\t\t\t\t     const pj_sockaddr_t *peer_addr,\n\t\t\t\t\t     unsigned addr_len)\n{\n    pj_turn_permission *perm;\n\n    perm = PJ_POOL_ZALLOC_T(alloc->pool, pj_turn_permission);\n    pj_memcpy(&perm->hkey.peer_addr, peer_addr, addr_len);\n\n    perm->allocation = alloc;\n    perm->channel = PJ_TURN_INVALID_CHANNEL;\n\n    pj_gettimeofday(&perm->expiry);\n    perm->expiry.sec += PJ_TURN_PERM_TIMEOUT;\n\n    /* Register to hash table (only the address part!) */\n    pj_hash_set(alloc->pool, alloc->peer_table,\n\t\tpj_sockaddr_get_addr(&perm->hkey.peer_addr),\n\t        pj_sockaddr_get_addr_len(&perm->hkey.peer_addr), 0, perm);\n\n    return perm;\n}\n\n/* Check if a permission isn't expired. Return NULL if expired. */\nstatic pj_turn_permission *check_permission_expiry(pj_turn_permission *perm)\n{\n    pj_turn_allocation *alloc = perm->allocation;\n    pj_time_val now;\n\n    pj_gettimeofday(&now);\n    if (PJ_TIME_VAL_GT(perm->expiry, now)) {\n\t/* Permission has not expired */\n\treturn perm;\n    }\n\n    /* Remove from permission hash table */\n    pj_hash_set(NULL, alloc->peer_table,\n\t\tpj_sockaddr_get_addr(&perm->hkey.peer_addr),\n\t        pj_sockaddr_get_addr_len(&perm->hkey.peer_addr), 0, NULL);\n\n    /* Remove from channel hash table, if assigned a channel number */\n    if (perm->channel != PJ_TURN_INVALID_CHANNEL) {\n\tpj_hash_set(NULL, alloc->ch_table, &perm->channel,\n\t\t    sizeof(perm->channel), 0, NULL);\n    }\n\n    return NULL;\n}\n\n/* Lookup permission in hash table by the peer address */\nstatic pj_turn_permission*\nlookup_permission_by_addr(pj_turn_allocation *alloc,\n\t\t\t  const pj_sockaddr_t *peer_addr,\n\t\t\t  unsigned addr_len)\n{\n    pj_turn_permission *perm;\n\n    PJ_UNUSED_ARG(addr_len);\n\n    /* Lookup in peer hash table */\n    perm = (pj_turn_permission*)\n\t   pj_hash_get(alloc->peer_table,\n\t\t       pj_sockaddr_get_addr(peer_addr),\n\t\t       pj_sockaddr_get_addr_len(peer_addr),\n\t\t       NULL);\n    return perm ? check_permission_expiry(perm) : NULL;\n}\n\n/* Lookup permission in hash table by the channel number */\nstatic pj_turn_permission*\nlookup_permission_by_chnum(pj_turn_allocation *alloc,\n\t\t\t   unsigned chnum)\n{\n    pj_uint16_t chnum16 = (pj_uint16_t)chnum;\n    pj_turn_permission *perm;\n\n    /* Lookup in peer hash table */\n    perm = (pj_turn_permission*) pj_hash_get(alloc->ch_table, &chnum16,\n\t\t\t\t\t    sizeof(chnum16), NULL);\n    return perm ? check_permission_expiry(perm) : NULL;\n}\n\n/* Update permission because of data from client to peer.\n * Return PJ_TRUE is permission is found.\n */\nstatic pj_bool_t refresh_permission(pj_turn_permission *perm)\n{\n    pj_gettimeofday(&perm->expiry);\n    if (perm->channel == PJ_TURN_INVALID_CHANNEL)\n\tperm->expiry.sec += PJ_TURN_PERM_TIMEOUT;\n    else\n\tperm->expiry.sec += PJ_TURN_CHANNEL_TIMEOUT;\n    return PJ_TRUE;\n}\n\n/*\n * Handle incoming packet from client. This would have been called by\n * server upon receiving packet from a listener.\n */\nPJ_DEF(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc,\n\t\t\t\t\t\t pj_turn_pkt *pkt)\n{\n    pj_bool_t is_stun;\n    pj_status_t status;\n\n    /* Lock this allocation */\n    pj_lock_acquire(alloc->lock);\n\n    /* Quickly check if this is STUN message */\n    is_stun = ((*((pj_uint8_t*)pkt->pkt) & 0xC0) == 0);\n\n    if (is_stun) {\n\t/*\n\t * This could be an incoming STUN requests or indications.\n\t * Pass this through to the STUN session, which will call\n\t * our stun_on_rx_request() or stun_on_rx_indication()\n\t * callbacks.\n\t *\n\t * Note: currently it is necessary to specify the\n\t * PJ_STUN_NO_FINGERPRINT_CHECK otherwise the FINGERPRINT\n\t * attribute inside STUN Send Indication message will mess up\n\t * with fingerprint checking.\n\t */\n\tunsigned options = PJ_STUN_CHECK_PACKET | PJ_STUN_NO_FINGERPRINT_CHECK;\n\tpj_size_t parsed_len = 0;\n\n\tif (pkt->transport->listener->tp_type == PJ_TURN_TP_UDP)\n\t    options |= PJ_STUN_IS_DATAGRAM;\n\n\tstatus = pj_stun_session_on_rx_pkt(alloc->sess, pkt->pkt, pkt->len,\n\t\t\t\t\t   options, NULL, &parsed_len,\n\t\t\t\t\t   &pkt->src.clt_addr,\n\t\t\t\t\t   pkt->src_addr_len);\n\n\tif (pkt->transport->listener->tp_type == PJ_TURN_TP_UDP) {\n\t    pkt->len = 0;\n\t} else if (parsed_len > 0) {\n\t    if (parsed_len == pkt->len) {\n\t\tpkt->len = 0;\n\t    } else {\n\t\tpj_memmove(pkt->pkt, pkt->pkt+parsed_len,\n\t\t\t   pkt->len - parsed_len);\n\t\tpkt->len -= parsed_len;\n\t    }\n\t}\n\n\tif (status != PJ_SUCCESS) {\n\t    alloc_err(alloc, \"Error handling STUN packet\", status);\n\t    goto on_return;\n\t}\n\n    } else {\n\t/*\n\t * This is not a STUN packet, must be ChannelData packet.\n\t */\n\tpj_turn_channel_data *cd = (pj_turn_channel_data*)pkt->pkt;\n\tpj_turn_permission *perm;\n\tpj_ssize_t len;\n\n\tpj_assert(sizeof(*cd)==4);\n\n\t/* For UDP check the packet length */\n\tif (alloc->transport->listener->tp_type == PJ_TURN_TP_UDP) {\n\t    if (pkt->len < pj_ntohs(cd->length)+sizeof(*cd)) {\n\t\tPJ_LOG(4,(alloc->obj_name,\n\t\t\t  \"ChannelData from %s discarded: UDP size error\",\n\t\t\t  alloc->info));\n\t\tgoto on_return;\n\t    }\n\t} else {\n\t    pj_assert(!\"Unsupported transport\");\n\t    goto on_return;\n\t}\n\n\tperm = lookup_permission_by_chnum(alloc, pj_ntohs(cd->ch_number));\n\tif (!perm) {\n\t    /* Discard */\n\t    PJ_LOG(4,(alloc->obj_name,\n\t\t      \"ChannelData from %s discarded: ch#0x%x not found\",\n\t\t      alloc->info, pj_ntohs(cd->ch_number)));\n\t    goto on_return;\n\t}\n\n\t/* Relay the data */\n\tlen = pj_ntohs(cd->length);\n\tpj_sock_sendto(alloc->relay.tp.sock, cd+1, &len, 0,\n\t\t       &perm->hkey.peer_addr,\n\t\t       pj_sockaddr_get_len(&perm->hkey.peer_addr));\n\n\t/* Refresh permission */\n\trefresh_permission(perm);\n    }\n\non_return:\n    /* Release lock */\n    pj_lock_release(alloc->lock);\n}\n\n\n/*\n * Handle incoming packet from peer. This function is called by\n * on_rx_from_peer().\n */\nstatic void handle_peer_pkt(pj_turn_allocation *alloc,\n\t\t\t    pj_turn_relay_res *rel,\n\t\t\t    char *pkt, pj_size_t len,\n\t\t\t    const pj_sockaddr *src_addr)\n{\n    pj_turn_permission *perm;\n\n    /* Lookup permission */\n    perm = lookup_permission_by_addr(alloc, src_addr,\n\t\t\t\t     pj_sockaddr_get_len(src_addr));\n    if (perm == NULL) {\n\t/* No permission, discard data */\n\treturn;\n    }\n\n    /* Send Data Indication or ChannelData, depends on whether\n     * this permission is attached to a channel number.\n     */\n    if (perm->channel != PJ_TURN_INVALID_CHANNEL) {\n\t/* Send ChannelData */\n\tpj_turn_channel_data *cd = (pj_turn_channel_data*)rel->tp.tx_pkt;\n\n\tif (len > PJ_TURN_MAX_PKT_LEN) {\n\t    char peer_addr[80];\n\t    pj_sockaddr_print(src_addr, peer_addr, sizeof(peer_addr), 3);\n\t    PJ_LOG(4,(alloc->obj_name, \"Client %s: discarded data from %s \"\n\t\t      \"because it's too long (%d bytes)\",\n\t\t      alloc->info, peer_addr, len));\n\t    return;\n\t}\n\n\t/* Init header */\n\tcd->ch_number = pj_htons(perm->channel);\n\tcd->length = pj_htons((pj_uint16_t)len);\n\n\t/* Copy data */\n\tpj_memcpy(rel->tp.tx_pkt+sizeof(pj_turn_channel_data), pkt, len);\n\n\t/* Send to client */\n\talloc->transport->sendto(alloc->transport, rel->tp.tx_pkt,\n\t\t\t         len+sizeof(pj_turn_channel_data), 0,\n\t\t\t         &alloc->hkey.clt_addr,\n\t\t\t         pj_sockaddr_get_len(&alloc->hkey.clt_addr));\n    } else {\n\t/* Send Data Indication */\n\tpj_stun_tx_data *tdata;\n\tpj_status_t status;\n\n\tstatus = pj_stun_session_create_ind(alloc->sess,\n\t\t\t\t\t    PJ_STUN_DATA_INDICATION, &tdata);\n\tif (status != PJ_SUCCESS) {\n\t    alloc_err(alloc, \"Error creating Data indication\", status);\n\t    return;\n\t}\n\n\tpj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,\n\t\t\t\t      PJ_STUN_ATTR_XOR_PEER_ADDR, PJ_TRUE,\n\t\t\t\t      src_addr, pj_sockaddr_get_len(src_addr));\n\tpj_stun_msg_add_binary_attr(tdata->pool, tdata->msg,\n\t\t\t\t    PJ_STUN_ATTR_DATA,\n\t\t\t\t    (const pj_uint8_t*)pkt, len);\n\n\tpj_stun_session_send_msg(alloc->sess, NULL, PJ_FALSE,\n\t\t\t\t PJ_FALSE, &alloc->hkey.clt_addr,\n\t\t\t\t pj_sockaddr_get_len(&alloc->hkey.clt_addr),\n\t\t\t\t tdata);\n    }\n}\n\n/*\n * ioqueue notification on RX packets from the relay socket.\n */\nstatic void on_rx_from_peer(pj_ioqueue_key_t *key,\n                            pj_ioqueue_op_key_t *op_key,\n                            pj_ssize_t bytes_read)\n{\n    pj_turn_relay_res *rel;\n    pj_status_t status;\n\n    rel = (pj_turn_relay_res*) pj_ioqueue_get_user_data(key);\n\n    /* Lock the allocation */\n    pj_lock_acquire(rel->allocation->lock);\n\n    do {\n\tif (bytes_read > 0) {\n\t    handle_peer_pkt(rel->allocation, rel, rel->tp.rx_pkt,\n\t\t\t    bytes_read, &rel->tp.src_addr);\n\t}\n\n\t/* Read next packet */\n\tbytes_read = sizeof(rel->tp.rx_pkt);\n\trel->tp.src_addr_len = sizeof(rel->tp.src_addr);\n\tstatus = pj_ioqueue_recvfrom(key, op_key,\n\t\t\t\t     rel->tp.rx_pkt, &bytes_read, 0,\n\t\t\t\t     &rel->tp.src_addr,\n\t\t\t\t     &rel->tp.src_addr_len);\n\n\tif (status != PJ_EPENDING && status != PJ_SUCCESS)\n\t    bytes_read = -status;\n\n    } while (status != PJ_EPENDING && status != PJ_ECANCELLED);\n\n    /* Release allocation lock */\n    pj_lock_release(rel->allocation->lock);\n}\n\n/*\n * Callback notification from STUN session when it wants to send\n * a STUN message towards the client.\n */\nstatic pj_status_t stun_on_send_msg(pj_stun_session *sess,\n\t\t\t\t    void *token,\n\t\t\t\t    const void *pkt,\n\t\t\t\t    pj_size_t pkt_size,\n\t\t\t\t    const pj_sockaddr_t *dst_addr,\n\t\t\t\t    unsigned addr_len)\n{\n    pj_turn_allocation *alloc;\n\n    PJ_UNUSED_ARG(token);\n\n    alloc = (pj_turn_allocation*) pj_stun_session_get_user_data(sess);\n\n    return alloc->transport->sendto(alloc->transport, pkt, pkt_size, 0,\n\t\t\t\t    dst_addr, addr_len);\n}\n\n/*\n * Callback notification from STUN session when it receives STUN\n * requests. This callback was trigger by STUN incoming message\n * processing in pj_turn_allocation_on_rx_client_pkt().\n */\nstatic pj_status_t stun_on_rx_request(pj_stun_session *sess,\n\t\t\t\t      const pj_uint8_t *pkt,\n\t\t\t\t      unsigned pkt_len,\n\t\t\t\t      const pj_stun_rx_data *rdata,\n\t\t\t\t      void *token,\n\t\t\t\t      const pj_sockaddr_t *src_addr,\n\t\t\t\t      unsigned src_addr_len)\n{\n    const pj_stun_msg *msg = rdata->msg;\n    pj_turn_allocation *alloc;\n\n    PJ_UNUSED_ARG(pkt);\n    PJ_UNUSED_ARG(pkt_len);\n    PJ_UNUSED_ARG(token);\n    PJ_UNUSED_ARG(src_addr);\n    PJ_UNUSED_ARG(src_addr_len);\n\n    alloc = (pj_turn_allocation*) pj_stun_session_get_user_data(sess);\n\n    /* Refuse to serve any request if we've been shutdown */\n    if (alloc->relay.lifetime == 0) {\n\t/* Reject with 437 if we're shutting down */\n\tsend_reply_err(alloc, rdata, PJ_TRUE,\n\t\t       PJ_STUN_SC_ALLOCATION_MISMATCH, NULL);\n\treturn PJ_SUCCESS;\n    }\n\n    if (msg->hdr.type == PJ_STUN_REFRESH_REQUEST) {\n\t/*\n\t * Handle REFRESH request\n\t */\n\tpj_stun_lifetime_attr *lifetime;\n\tpj_stun_bandwidth_attr *bandwidth;\n\n\t/* Get LIFETIME attribute */\n\tlifetime = (pj_stun_lifetime_attr*)\n\t\t   pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_LIFETIME, 0);\n\n\t/* Get BANDWIDTH attribute */\n\tbandwidth = (pj_stun_bandwidth_attr*)\n\t            pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_BANDWIDTH, 0);\n\n\t/* TODO: process bandwidth */\n\tPJ_UNUSED_ARG(bandwidth);\n\n\tif (lifetime && lifetime->value==0) {\n\t    /*\n\t     * This is deallocation request.\n\t     */\n\t    alloc->relay.lifetime = 0;\n\n\t    /* Respond first */\n\t    send_reply_ok(alloc, rdata);\n\n\t    /* Shutdown allocation */\n\t    PJ_LOG(4,(alloc->obj_name,\n\t\t      \"Client %s request to dealloc, shutting down\",\n\t\t      alloc->info));\n\n\t    alloc_shutdown(alloc);\n\n\t} else {\n\t    /*\n\t     * This is a refresh request.\n\t     */\n\n\t    /* Update lifetime */\n\t    if (lifetime) {\n\t\talloc->relay.lifetime = lifetime->value;\n\t    }\n\n\t    /* Update bandwidth */\n\t    // TODO:\n\n\t    /* Update expiration timer */\n\t    resched_timeout(alloc);\n\n\t    /* Send reply */\n\t    send_reply_ok(alloc, rdata);\n\t}\n\n    } else if (msg->hdr.type == PJ_STUN_CHANNEL_BIND_REQUEST) {\n\t/*\n\t * ChannelBind request.\n\t */\n\tpj_stun_channel_number_attr *ch_attr;\n\tpj_stun_xor_peer_addr_attr *peer_attr;\n\tpj_turn_permission *p1, *p2;\n\n\tch_attr = (pj_stun_channel_number_attr*)\n\t\t  pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_CHANNEL_NUMBER, 0);\n\tpeer_attr = (pj_stun_xor_peer_addr_attr*)\n\t\t    pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_PEER_ADDR, 0);\n\n\tif (!ch_attr || !peer_attr) {\n\t    send_reply_err(alloc, rdata, PJ_TRUE,\n\t\t\t   PJ_STUN_SC_BAD_REQUEST, NULL);\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* Find permission with the channel number */\n\tp1 = lookup_permission_by_chnum(alloc, PJ_STUN_GET_CH_NB(ch_attr->value));\n\n\t/* If permission is found, this is supposed to be a channel bind\n\t * refresh. Make sure it's for the same peer.\n\t */\n\tif (p1) {\n\t    if (pj_sockaddr_cmp(&p1->hkey.peer_addr, &peer_attr->sockaddr)) {\n\t\t/* Address mismatch. Send 400 */\n\t\tsend_reply_err(alloc, rdata, PJ_TRUE,\n\t\t\t       PJ_STUN_SC_BAD_REQUEST,\n\t\t\t       \"Peer address mismatch\");\n\t\treturn PJ_SUCCESS;\n\t    }\n\n\t    /* Refresh permission */\n\t    refresh_permission(p1);\n\n\t    /* Send response */\n\t    send_reply_ok(alloc, rdata);\n\n\t    /* Done */\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* If permission is not found, create a new one. Make sure the peer\n\t * has not alreadyy assigned with a channel number.\n\t */\n\tp2 = lookup_permission_by_addr(alloc, &peer_attr->sockaddr,\n\t\t\t\t       pj_sockaddr_get_len(&peer_attr->sockaddr));\n\tif (p2 && p2->channel != PJ_TURN_INVALID_CHANNEL) {\n\t    send_reply_err(alloc, rdata, PJ_TRUE, PJ_STUN_SC_BAD_REQUEST,\n\t\t\t   \"Peer address already assigned a channel number\");\n\t    return PJ_SUCCESS;\n\t}\n\n\t/* Create permission if it doesn't exist */\n\tif (!p2) {\n\t    p2 = create_permission(alloc, &peer_attr->sockaddr,\n\t\t\t\t   pj_sockaddr_get_len(&peer_attr->sockaddr));\n\t    if (!p2)\n\t\treturn PJ_SUCCESS;\n\t}\n\n\t/* Assign channel number to permission */\n\tp2->channel = PJ_STUN_GET_CH_NB(ch_attr->value);\n\n\t/* Register to hash table */\n\tpj_assert(sizeof(p2->channel)==2);\n\tpj_hash_set(alloc->pool, alloc->ch_table, &p2->channel,\n\t\t    sizeof(p2->channel), 0, p2);\n\n\t/* Update */\n\trefresh_permission(p2);\n\n\t/* Reply */\n\tsend_reply_ok(alloc, rdata);\n\n\treturn PJ_SUCCESS;\n\n    } else if (msg->hdr.type == PJ_STUN_ALLOCATE_REQUEST) {\n\n\t/* Respond with 437 (section 6.3 turn-07) */\n\tsend_reply_err(alloc, rdata, PJ_TRUE, PJ_STUN_SC_ALLOCATION_MISMATCH,\n\t\t       NULL);\n\n    } else {\n\n\t/* Respond with Bad Request? */\n\tsend_reply_err(alloc, rdata, PJ_TRUE, PJ_STUN_SC_BAD_REQUEST, NULL);\n\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Callback notification from STUN session when it receives STUN\n * indications. This callback was trigger by STUN incoming message\n * processing in pj_turn_allocation_on_rx_client_pkt().\n */\nstatic pj_status_t stun_on_rx_indication(pj_stun_session *sess,\n\t\t\t\t\t const pj_uint8_t *pkt,\n\t\t\t\t\t unsigned pkt_len,\n\t\t\t\t\t const pj_stun_msg *msg,\n\t\t\t\t\t void *token,\n\t\t\t\t\t const pj_sockaddr_t *src_addr,\n\t\t\t\t\t unsigned src_addr_len)\n{\n    pj_stun_xor_peer_addr_attr *peer_attr;\n    pj_stun_data_attr *data_attr;\n    pj_turn_allocation *alloc;\n    pj_turn_permission *perm;\n    pj_ssize_t len;\n\n    PJ_UNUSED_ARG(pkt);\n    PJ_UNUSED_ARG(pkt_len);\n    PJ_UNUSED_ARG(token);\n    PJ_UNUSED_ARG(src_addr);\n    PJ_UNUSED_ARG(src_addr_len);\n\n    alloc = (pj_turn_allocation*) pj_stun_session_get_user_data(sess);\n\n    /* Only expect Send Indication */\n    if (msg->hdr.type != PJ_STUN_SEND_INDICATION) {\n\t/* Ignore */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Get XOR-PEER-ADDRESS attribute */\n    peer_attr = (pj_stun_xor_peer_addr_attr*)\n\t\tpj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_PEER_ADDR, 0);\n\n    /* MUST have XOR-PEER-ADDRESS attribute */\n    if (!peer_attr)\n\treturn PJ_SUCCESS;\n\n    /* Get DATA attribute */\n    data_attr = (pj_stun_data_attr*)\n\t\tpj_stun_msg_find_attr(msg, PJ_STUN_ATTR_DATA, 0);\n\n    /* Create/update/refresh the permission */\n    perm = lookup_permission_by_addr(alloc, &peer_attr->sockaddr,\n\t\t\t\t     pj_sockaddr_get_len(&peer_attr->sockaddr));\n    if (perm == NULL) {\n\tperm = create_permission(alloc, &peer_attr->sockaddr,\n\t\t\t\t pj_sockaddr_get_len(&peer_attr->sockaddr));\n    }\n    refresh_permission(perm);\n\n    /* Return if we don't have data */\n    if (data_attr == NULL)\n\treturn PJ_SUCCESS;\n\n    /* Relay the data to peer */\n    len = data_attr->length;\n    pj_sock_sendto(alloc->relay.tp.sock, data_attr->data,\n\t\t   &len, 0, &peer_attr->sockaddr,\n\t\t   pj_sockaddr_get_len(&peer_attr->sockaddr));\n\n    return PJ_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjturn-srv/auth.c",
    "content": "/* $Id: auth.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include \"auth.h\"\n#include <pjlib.h>\n\n\n#define MAX_REALM\t80\n#define MAX_USERNAME\t32\n#define MAX_PASSWORD\t32\n#define MAX_NONCE\t32\n\nstatic char g_realm[MAX_REALM];\n\nstatic struct cred_t\n{\n    char    username[MAX_USERNAME];\n    char    passwd[MAX_PASSWORD];\n} g_cred[] = \n{\n    { \"100\", \"100\" },\n    { \"700\", \"700\" },\n    { \"701\", \"701\" }\n};\n\n#define THIS_FILE\t\"auth.c\"\n#define THE_NONCE\t\"pjnath\"\n#define LOG(expr)\tPJ_LOG(3,expr)\n\n\n/*\n * Initialize TURN authentication subsystem.\n */\nPJ_DEF(pj_status_t) pj_turn_auth_init(const char *realm)\n{\n    PJ_ASSERT_RETURN(pj_ansi_strlen(realm) < MAX_REALM, PJ_ENAMETOOLONG);\n    pj_ansi_strcpy(g_realm, realm);\n    return PJ_SUCCESS;\n}\n\n/*\n * Shutdown TURN authentication subsystem.\n */\nPJ_DEF(void) pj_turn_auth_dinit(void)\n{\n    /* Nothing to do */\n}\n\n\n/*\n * This function is called by pj_stun_verify_credential() when\n * server needs to challenge the request with 401 response.\n */\nPJ_DEF(pj_status_t) pj_turn_get_auth(void *user_data,\n\t\t\t\t     pj_pool_t *pool,\n\t\t\t\t     pj_str_t *realm,\n\t\t\t\t     pj_str_t *nonce)\n{\n    PJ_UNUSED_ARG(user_data);\n    PJ_UNUSED_ARG(pool);\n\n    *realm = pj_str(g_realm);\n    *nonce = pj_str(THE_NONCE);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * This function is called to get the password for the specified username.\n * This function is also used to check whether the username is valid.\n */\nPJ_DEF(pj_status_t) pj_turn_get_password(const pj_stun_msg *msg,\n\t\t\t\t\t void *user_data, \n\t\t\t\t\t const pj_str_t *realm,\n\t\t\t\t\t const pj_str_t *username,\n\t\t\t\t\t pj_pool_t *pool,\n\t\t\t\t\t pj_stun_passwd_type *data_type,\n\t\t\t\t\t pj_str_t *data)\n{\n    unsigned i;\n\n    PJ_UNUSED_ARG(msg);\n    PJ_UNUSED_ARG(user_data);\n    PJ_UNUSED_ARG(pool);\n\n    if (pj_stricmp2(realm, g_realm)) {\n\tLOG((THIS_FILE, \"auth error: invalid realm '%.*s'\", \n\t\t\t(int)realm->slen, realm->ptr));\n\treturn PJ_EINVAL;\n    }\n\n    for (i=0; i<PJ_ARRAY_SIZE(g_cred); ++i) {\n\tif (pj_stricmp2(username, g_cred[i].username) == 0) {\n\t    *data_type = PJ_STUN_PASSWD_PLAIN;\n\t    *data = pj_str(g_cred[i].passwd);\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    LOG((THIS_FILE, \"auth error: user '%.*s' not found\", \n\t\t    (int)username->slen, username->ptr));\n    return PJ_ENOTFOUND;\n}\n\n/*\n * This function will be called to verify that the NONCE given\n * in the message can be accepted. If this callback returns\n * PJ_FALSE, 438 (Stale Nonce) response will be created.\n */\nPJ_DEF(pj_bool_t) pj_turn_verify_nonce(const pj_stun_msg *msg,\n\t\t\t\t       void *user_data,\n\t\t\t\t       const pj_str_t *realm,\n\t\t\t\t       const pj_str_t *username,\n\t\t\t\t       const pj_str_t *nonce)\n{\n    PJ_UNUSED_ARG(msg);\n    PJ_UNUSED_ARG(user_data);\n    PJ_UNUSED_ARG(realm);\n    PJ_UNUSED_ARG(username);\n\n    if (pj_stricmp2(nonce, THE_NONCE)) {\n\tLOG((THIS_FILE, \"auth error: invalid nonce '%.*s'\", \n\t\t\t(int)nonce->slen, nonce->ptr));\n\treturn PJ_FALSE;\n    }\n\n    return PJ_TRUE;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjturn-srv/auth.h",
    "content": "/* $Id: auth.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_TURN_SRV_AUTH_H__\n#define __PJ_TURN_SRV_AUTH_H__\n\n#include <pjnath.h>\n\n/**\n * Initialize TURN authentication subsystem.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pj_turn_auth_init(const char *realm);\n\n/**\n * Shutdown TURN authentication subsystem.\n */\nPJ_DECL(void) pj_turn_auth_dinit(void);\n\n/**\n * This function is called by pj_stun_verify_credential() when\n * server needs to challenge the request with 401 response.\n *\n * @param user_data\tShould be ignored.\n * @param pool\t\tPool to allocate memory.\n * @param realm\t\tOn return, the function should fill in with\n *\t\t\trealm if application wants to use long term\n *\t\t\tcredential. Otherwise application should set\n *\t\t\tempty string for the realm.\n * @param nonce\t\tOn return, if application wants to use long\n *\t\t\tterm credential, it MUST fill in the nonce\n *\t\t\twith some value. Otherwise  if short term \n *\t\t\tcredential is wanted, it MAY set this value.\n *\t\t\tIf short term credential is wanted and the\n *\t\t\tapplication doesn't want to include NONCE,\n *\t\t\tthen it must set this to empty string.\n *\n * @return\t\tThe callback should return PJ_SUCCESS, or\n *\t\t\totherwise response message will not be \n *\t\t\tcreated.\n */\nPJ_DECL(pj_status_t) pj_turn_get_auth(void *user_data,\n\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t      pj_str_t *realm,\n\t\t\t\t      pj_str_t *nonce);\n\n/**\n * This function is called to get the password for the specified username.\n * This function is also used to check whether the username is valid.\n *\n * @param msg\t\tThe STUN message where the password will be\n *\t\t\tapplied to.\n * @param user_data\tShould be ignored.\n * @param realm\t\tThe realm as specified in the message.\n * @param username\tThe username as specified in the message.\n * @param pool\t\tPool to allocate memory when necessary.\n * @param data_type\tOn return, application should fill up this\n *\t\t\targument with the type of data (which should\n *\t\t\tbe zero if data is a plaintext password).\n * @param data\t\tOn return, application should fill up this\n *\t\t\targument with the password according to\n *\t\t\tdata_type.\n *\n * @return\t\tThe callback should return PJ_SUCCESS if\n *\t\t\tusername has been successfully verified\n *\t\t\tand password was obtained. If non-PJ_SUCCESS\n *\t\t\tis returned, it is assumed that the\n *\t\t\tusername is not valid.\n */\nPJ_DECL(pj_status_t) pj_turn_get_password(const pj_stun_msg *msg,\n\t\t\t\t\t  void *user_data, \n\t\t\t\t\t  const pj_str_t *realm,\n\t\t\t\t\t  const pj_str_t *username,\n\t\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t\t  pj_stun_passwd_type *data_type,\n\t\t\t\t\t  pj_str_t *data);\n\n/**\n * This function will be called to verify that the NONCE given\n * in the message can be accepted. If this callback returns\n * PJ_FALSE, 438 (Stale Nonce) response will be created.\n *\n * @param msg\t\tThe STUN message where the nonce was received.\n * @param user_data\tShould be ignored.\n * @param realm\t\tThe realm as specified in the message.\n * @param username\tThe username as specified in the message.\n * @param nonce\t\tThe nonce to be verified.\n *\n * @return\t\tThe callback MUST return non-zero if the \n *\t\t\tNONCE can be accepted.\n */\nPJ_DECL(pj_bool_t) pj_turn_verify_nonce(const pj_stun_msg *msg,\n\t\t\t\t\tvoid *user_data,\n\t\t\t\t\tconst pj_str_t *realm,\n\t\t\t\t\tconst pj_str_t *username,\n\t\t\t\t\tconst pj_str_t *nonce);\n\n#endif\t/* __PJ_TURN_SRV_AUTH_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjturn-srv/listener_tcp.c",
    "content": "/* $Id: listener_tcp.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include \"turn.h\"\n#include <pj/compat/socket.h>\n\n#if PJ_HAS_TCP\n\nstruct accept_op\n{\n    pj_ioqueue_op_key_t\top_key;\n    pj_sock_t\t\tsock;\n    pj_sockaddr\t\tsrc_addr;\n    int\t\t\tsrc_addr_len;\n};\n\nstruct tcp_listener\n{\n    pj_turn_listener\t     base;\n    pj_ioqueue_key_t\t    *key;\n    unsigned\t\t     accept_cnt;\n    struct accept_op\t    *accept_op;\t/* Array of accept_op's\t*/\n};\n\n\nstatic void lis_on_accept_complete(pj_ioqueue_key_t *key, \n\t\t\t\t   pj_ioqueue_op_key_t *op_key, \n\t\t\t\t   pj_sock_t sock, \n\t\t\t\t   pj_status_t status);\nstatic pj_status_t lis_destroy(pj_turn_listener *listener);\nstatic void transport_create(pj_sock_t sock, pj_turn_listener *lis,\n\t\t\t     pj_sockaddr_t *src_addr, int src_addr_len);\n\nstatic void show_err(const char *sender, const char *title, \n\t\t     pj_status_t status)\n{\n    char errmsg[PJ_ERR_MSG_SIZE];\n\n    pj_strerror(status, errmsg, sizeof(errmsg));\n    PJ_LOG(4,(sender, \"%s: %s\", title, errmsg));\n}\n\n\n/*\n * Create a new listener on the specified port.\n */\nPJ_DEF(pj_status_t) pj_turn_listener_create_tcp(pj_turn_srv *srv,\n\t\t\t\t\t        int af,\n\t\t\t\t\t        const pj_str_t *bound_addr,\n\t\t\t\t\t        unsigned port,\n\t\t\t\t\t\tunsigned concurrency_cnt,\n\t\t\t\t\t\tunsigned flags,\n\t\t\t\t\t\tpj_turn_listener **p_listener)\n{\n    pj_pool_t *pool;\n    struct tcp_listener *tcp_lis;\n    pj_ioqueue_callback ioqueue_cb;\n    unsigned i;\n    pj_status_t status;\n\n    /* Create structure */\n    pool = pj_pool_create(srv->core.pf, \"tcpl%p\", 1000, 1000, NULL);\n    tcp_lis = PJ_POOL_ZALLOC_T(pool, struct tcp_listener);\n    tcp_lis->base.pool = pool;\n    tcp_lis->base.obj_name = pool->obj_name;\n    tcp_lis->base.server = srv;\n    tcp_lis->base.tp_type = PJ_TURN_TP_TCP;\n    tcp_lis->base.sock = PJ_INVALID_SOCKET;\n    //tcp_lis->base.sendto = &tcp_sendto;\n    tcp_lis->base.destroy = &lis_destroy;\n    tcp_lis->accept_cnt = concurrency_cnt;\n    tcp_lis->base.flags = flags;\n\n    /* Create socket */\n    status = pj_sock_socket(af, pj_SOCK_STREAM(), 0, &tcp_lis->base.sock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Init bind address */\n    status = pj_sockaddr_init(af, &tcp_lis->base.addr, bound_addr, \n\t\t\t      (pj_uint16_t)port);\n    if (status != PJ_SUCCESS) \n\tgoto on_error;\n    \n    /* Create info */\n    pj_ansi_strcpy(tcp_lis->base.info, \"TCP:\");\n    pj_sockaddr_print(&tcp_lis->base.addr, tcp_lis->base.info+4, \n\t\t      sizeof(tcp_lis->base.info)-4, 3);\n\n    /* Bind socket */\n    status = pj_sock_bind(tcp_lis->base.sock, &tcp_lis->base.addr, \n\t\t\t  pj_sockaddr_get_len(&tcp_lis->base.addr));\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Listen() */\n    status = pj_sock_listen(tcp_lis->base.sock, 5);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Register to ioqueue */\n    pj_bzero(&ioqueue_cb, sizeof(ioqueue_cb));\n    ioqueue_cb.on_accept_complete = &lis_on_accept_complete;\n    status = pj_ioqueue_register_sock(pool, srv->core.ioqueue, tcp_lis->base.sock,\n\t\t\t\t      tcp_lis, &ioqueue_cb, &tcp_lis->key);\n\n    /* Create op keys */\n    tcp_lis->accept_op = (struct accept_op*)pj_pool_calloc(pool, concurrency_cnt,\n\t\t\t\t\t\t    sizeof(struct accept_op));\n\n    /* Create each accept_op and kick off read operation */\n    for (i=0; i<concurrency_cnt; ++i) {\n\tlis_on_accept_complete(tcp_lis->key, &tcp_lis->accept_op[i].op_key, \n\t\t\t       PJ_INVALID_SOCKET, PJ_EPENDING);\n    }\n\n    /* Done */\n    PJ_LOG(4,(tcp_lis->base.obj_name, \"Listener %s created\", \n\t   tcp_lis->base.info));\n\n    *p_listener = &tcp_lis->base;\n    return PJ_SUCCESS;\n\n\non_error:\n    lis_destroy(&tcp_lis->base);\n    return status;\n}\n\n\n/*\n * Destroy listener.\n */\nstatic pj_status_t lis_destroy(pj_turn_listener *listener)\n{\n    struct tcp_listener *tcp_lis = (struct tcp_listener *)listener;\n    unsigned i;\n\n    if (tcp_lis->key) {\n\tpj_ioqueue_unregister(tcp_lis->key);\n\ttcp_lis->key = NULL;\n\ttcp_lis->base.sock = PJ_INVALID_SOCKET;\n    } else if (tcp_lis->base.sock != PJ_INVALID_SOCKET) {\n\tpj_sock_close(tcp_lis->base.sock);\n\ttcp_lis->base.sock = PJ_INVALID_SOCKET;\n    }\n\n    for (i=0; i<tcp_lis->accept_cnt; ++i) {\n\t/* Nothing to do */\n    }\n\n    if (tcp_lis->base.pool) {\n\tpj_pool_t *pool = tcp_lis->base.pool;\n\n\tPJ_LOG(4,(tcp_lis->base.obj_name, \"Listener %s destroyed\", \n\t\t  tcp_lis->base.info));\n\n\ttcp_lis->base.pool = NULL;\n\tpj_pool_release(pool);\n    }\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Callback on new TCP connection.\n */\nstatic void lis_on_accept_complete(pj_ioqueue_key_t *key, \n\t\t\t\t   pj_ioqueue_op_key_t *op_key, \n\t\t\t\t   pj_sock_t sock, \n\t\t\t\t   pj_status_t status)\n{\n    struct tcp_listener *tcp_lis;\n    struct accept_op *accept_op = (struct accept_op*) op_key;\n\n    tcp_lis = (struct tcp_listener*) pj_ioqueue_get_user_data(key);\n\n    PJ_UNUSED_ARG(sock);\n\n    do {\n\t/* Report new connection. */\n\tif (status == PJ_SUCCESS) {\n\t    char addr[PJ_INET6_ADDRSTRLEN+8];\n\t    PJ_LOG(5,(tcp_lis->base.obj_name, \"Incoming TCP from %s\",\n\t\t      pj_sockaddr_print(&accept_op->src_addr, addr,\n\t\t\t\t\tsizeof(addr), 3)));\n\t    transport_create(accept_op->sock, &tcp_lis->base,\n\t\t\t     &accept_op->src_addr, accept_op->src_addr_len);\n\t} else if (status != PJ_EPENDING) {\n\t    show_err(tcp_lis->base.obj_name, \"accept()\", status);\n\t}\n\n\t/* Prepare next accept() */\n\taccept_op->src_addr_len = sizeof(accept_op->src_addr);\n\tstatus = pj_ioqueue_accept(key, op_key, &accept_op->sock,\n\t\t\t\t   NULL,\n\t\t\t\t   &accept_op->src_addr,\n\t\t\t\t   &accept_op->src_addr_len);\n\n    } while (status != PJ_EPENDING && status != PJ_ECANCELLED &&\n\t     status != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL));\n}\n\n\n/****************************************************************************/\n/*\n * Transport\n */\nenum\n{\n    TIMER_NONE,\n    TIMER_DESTROY\n};\n\n/* The delay in seconds to be applied before TCP transport is destroyed when \n * no allocation is referencing it. This also means the initial time to wait\n * after the initial TCP connection establishment to receive a valid STUN\n * message in the transport.\n */\n#define SHUTDOWN_DELAY  10\n\nstruct recv_op\n{\n    pj_ioqueue_op_key_t\top_key;\n    pj_turn_pkt\t\tpkt;\n};\n\nstruct tcp_transport\n{\n    pj_turn_transport\t base;\n    pj_pool_t\t\t*pool;\n    pj_timer_entry\t timer;\n\n    pj_turn_allocation\t*alloc;\n    int\t\t\t ref_cnt;\n\n    pj_sock_t\t\t sock;\n    pj_ioqueue_key_t\t*key;\n    struct recv_op\t recv_op;\n    pj_ioqueue_op_key_t\t send_op;\n};\n\n\nstatic void tcp_on_read_complete(pj_ioqueue_key_t *key, \n\t\t\t\t pj_ioqueue_op_key_t *op_key, \n\t\t\t\t pj_ssize_t bytes_read);\n\nstatic pj_status_t tcp_sendto(pj_turn_transport *tp,\n\t\t\t      const void *packet,\n\t\t\t      pj_size_t size,\n\t\t\t      unsigned flag,\n\t\t\t      const pj_sockaddr_t *addr,\n\t\t\t      int addr_len);\nstatic void tcp_destroy(struct tcp_transport *tcp);\nstatic void tcp_add_ref(pj_turn_transport *tp,\n\t\t\tpj_turn_allocation *alloc);\nstatic void tcp_dec_ref(pj_turn_transport *tp,\n\t\t\tpj_turn_allocation *alloc);\nstatic void timer_callback(pj_timer_heap_t *timer_heap,\n\t\t\t   pj_timer_entry *entry);\n\nstatic void transport_create(pj_sock_t sock, pj_turn_listener *lis,\n\t\t\t     pj_sockaddr_t *src_addr, int src_addr_len)\n{\n    pj_pool_t *pool;\n    struct tcp_transport *tcp;\n    pj_ioqueue_callback cb;\n    pj_status_t status;\n\n    pool = pj_pool_create(lis->server->core.pf, \"tcp%p\", 1000, 1000, NULL);\n\n    tcp = PJ_POOL_ZALLOC_T(pool, struct tcp_transport);\n    tcp->base.obj_name = pool->obj_name;\n    tcp->base.listener = lis;\n    tcp->base.info = lis->info;\n    tcp->base.sendto = &tcp_sendto;\n    tcp->base.add_ref = &tcp_add_ref;\n    tcp->base.dec_ref = &tcp_dec_ref;\n    tcp->pool = pool;\n    tcp->sock = sock;\n\n    pj_timer_entry_init(&tcp->timer, TIMER_NONE, tcp, &timer_callback);\n\n    /* Register to ioqueue */\n    pj_bzero(&cb, sizeof(cb));\n    cb.on_read_complete = &tcp_on_read_complete;\n    status = pj_ioqueue_register_sock(pool, lis->server->core.ioqueue, sock,\n\t\t\t\t      tcp, &cb, &tcp->key);\n    if (status != PJ_SUCCESS) {\n\ttcp_destroy(tcp);\n\treturn;\n    }\n\n    /* Init pkt */\n    tcp->recv_op.pkt.pool = pj_pool_create(lis->server->core.pf, \"tcpkt%p\", \n\t\t\t\t\t   1000, 1000, NULL);\n    tcp->recv_op.pkt.transport = &tcp->base;\n    tcp->recv_op.pkt.src.tp_type = PJ_TURN_TP_TCP;\n    tcp->recv_op.pkt.src_addr_len = src_addr_len;\n    pj_memcpy(&tcp->recv_op.pkt.src.clt_addr, src_addr, src_addr_len);\n\n    tcp_on_read_complete(tcp->key, &tcp->recv_op.op_key, -PJ_EPENDING);\n    /* Should not access transport from now, it may have been destroyed */\n}\n\n\nstatic void tcp_destroy(struct tcp_transport *tcp)\n{\n    if (tcp->key) {\n\tpj_ioqueue_unregister(tcp->key);\n\ttcp->key = NULL;\n\ttcp->sock = 0;\n    } else if (tcp->sock) {\n\tpj_sock_close(tcp->sock);\n\ttcp->sock = 0;\n    }\n\n    if (tcp->pool) {\n\tpj_pool_release(tcp->pool);\n    }\n}\n\n\nstatic void timer_callback(pj_timer_heap_t *timer_heap,\n\t\t\t   pj_timer_entry *entry)\n{\n    struct tcp_transport *tcp = (struct tcp_transport*) entry->user_data;\n\n    PJ_UNUSED_ARG(timer_heap);\n\n    tcp_destroy(tcp);\n}\n\n\nstatic void tcp_on_read_complete(pj_ioqueue_key_t *key, \n\t\t\t\t pj_ioqueue_op_key_t *op_key, \n\t\t\t\t pj_ssize_t bytes_read)\n{\n    struct tcp_transport *tcp;\n    struct recv_op *recv_op = (struct recv_op*) op_key;\n    pj_status_t status;\n\n    tcp = (struct tcp_transport*) pj_ioqueue_get_user_data(key);\n\n    do {\n\t/* Report to server or allocation, if we have allocation */\n\tif (bytes_read > 0) {\n\n\t    recv_op->pkt.len = bytes_read;\n\t    pj_gettimeofday(&recv_op->pkt.rx_time);\n\n\t    tcp_add_ref(&tcp->base, NULL);\n\n\t    if (tcp->alloc) {\n\t\tpj_turn_allocation_on_rx_client_pkt(tcp->alloc, &recv_op->pkt);\n\t    } else {\n\t\tpj_turn_srv_on_rx_pkt(tcp->base.listener->server, &recv_op->pkt);\n\t    }\n\n\t    pj_assert(tcp->ref_cnt > 0);\n\t    tcp_dec_ref(&tcp->base, NULL);\n\n\t} else if (bytes_read != -PJ_EPENDING) {\n\t    /* TCP connection closed/error. Notify client and then destroy \n\t     * ourselves.\n\t     * Note: the -PJ_EPENDING is the value passed during init.\n\t     */\n\t    ++tcp->ref_cnt;\n\n\t    if (tcp->alloc) {\n\t\tif (bytes_read != 0) {\n\t\t    show_err(tcp->base.obj_name, \"TCP socket error\", \n\t\t\t     -bytes_read);\n\t\t} else {\n\t\t    PJ_LOG(5,(tcp->base.obj_name, \"TCP socket closed\"));\n\t\t}\n\t\tpj_turn_allocation_on_transport_closed(tcp->alloc, &tcp->base);\n\t\ttcp->alloc = NULL;\n\t    }\n\n\t    pj_assert(tcp->ref_cnt > 0);\n\t    if (--tcp->ref_cnt == 0) {\n\t\ttcp_destroy(tcp);\n\t\treturn;\n\t    }\n\t}\n\n\t/* Reset pool */\n\tpj_pool_reset(recv_op->pkt.pool);\n\n\t/* If packet is full discard it */\n\tif (recv_op->pkt.len == sizeof(recv_op->pkt.pkt)) {\n\t    PJ_LOG(4,(tcp->base.obj_name, \"Buffer discarded\"));\n\t    recv_op->pkt.len = 0;\n\t}\n\n\t/* Read next packet */\n\tbytes_read = sizeof(recv_op->pkt.pkt) - recv_op->pkt.len;\n\tstatus = pj_ioqueue_recv(tcp->key, op_key,\n\t\t\t\t recv_op->pkt.pkt + recv_op->pkt.len, \n\t\t\t\t &bytes_read, 0);\n\n\tif (status != PJ_EPENDING && status != PJ_SUCCESS)\n\t    bytes_read = -status;\n\n    } while (status != PJ_EPENDING && status != PJ_ECANCELLED &&\n\t     status != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL));\n\n}\n\n\nstatic pj_status_t tcp_sendto(pj_turn_transport *tp,\n\t\t\t      const void *packet,\n\t\t\t      pj_size_t size,\n\t\t\t      unsigned flag,\n\t\t\t      const pj_sockaddr_t *addr,\n\t\t\t      int addr_len)\n{\n    struct tcp_transport *tcp = (struct tcp_transport*) tp;\n    pj_ssize_t length = size;\n\n    PJ_UNUSED_ARG(addr);\n    PJ_UNUSED_ARG(addr_len);\n\n    return pj_ioqueue_send(tcp->key, &tcp->send_op, packet, &length, flag);\n}\n\n\nstatic void tcp_add_ref(pj_turn_transport *tp,\n\t\t\tpj_turn_allocation *alloc)\n{\n    struct tcp_transport *tcp = (struct tcp_transport*) tp;\n\n    ++tcp->ref_cnt;\n\n    if (tcp->alloc == NULL && alloc) {\n\ttcp->alloc = alloc;\n    }\n\n    /* Cancel shutdown timer if it's running */\n    if (tcp->timer.id != TIMER_NONE) {\n\tpj_timer_heap_cancel(tcp->base.listener->server->core.timer_heap,\n\t\t\t     &tcp->timer);\n\ttcp->timer.id = TIMER_NONE;\n    }\n}\n\n\nstatic void tcp_dec_ref(pj_turn_transport *tp,\n\t\t\tpj_turn_allocation *alloc)\n{\n    struct tcp_transport *tcp = (struct tcp_transport*) tp;\n\n    --tcp->ref_cnt;\n\n    if (alloc && alloc == tcp->alloc) {\n\ttcp->alloc = NULL;\n    }\n\n    if (tcp->ref_cnt == 0 && tcp->timer.id == TIMER_NONE) {\n\tpj_time_val delay = { SHUTDOWN_DELAY, 0 };\n\ttcp->timer.id = TIMER_DESTROY;\n\tpj_timer_heap_schedule(tcp->base.listener->server->core.timer_heap,\n\t\t\t       &tcp->timer, &delay);\n    }\n}\n\n#else\t/* PJ_HAS_TCP */\n\n/* To avoid empty translation unit warning */\nint listener_tcp_dummy = 0;\n\n#endif\t/* PJ_HAS_TCP */\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjturn-srv/listener_udp.c",
    "content": "/* $Id: listener_udp.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include \"turn.h\"\n#include <pj/compat/socket.h>\n\nstruct read_op\n{\n    pj_ioqueue_op_key_t\top_key;\n    pj_turn_pkt\t\tpkt;\n};\n\nstruct udp_listener\n{\n    pj_turn_listener\t     base;\n\n    pj_ioqueue_key_t\t    *key;\n    unsigned\t\t     read_cnt;\n    struct read_op\t    **read_op;\t/* Array of read_op's\t*/\n\n    pj_turn_transport\t     tp;\t/* Transport instance */\n};\n\n\nstatic pj_status_t udp_destroy(pj_turn_listener *udp);\nstatic void on_read_complete(pj_ioqueue_key_t *key, \n\t\t\t     pj_ioqueue_op_key_t *op_key, \n\t\t\t     pj_ssize_t bytes_read);\n\nstatic pj_status_t udp_sendto(pj_turn_transport *tp,\n\t\t\t      const void *packet,\n\t\t\t      pj_size_t size,\n\t\t\t      unsigned flag,\n\t\t\t      const pj_sockaddr_t *addr,\n\t\t\t      int addr_len);\nstatic void udp_add_ref(pj_turn_transport *tp,\n\t\t\tpj_turn_allocation *alloc);\nstatic void udp_dec_ref(pj_turn_transport *tp,\n\t\t\tpj_turn_allocation *alloc);\n\n\n/*\n * Create a new listener on the specified port.\n */\nPJ_DEF(pj_status_t) pj_turn_listener_create_udp( pj_turn_srv *srv,\n\t\t\t\t\t        int af,\n\t\t\t\t\t        const pj_str_t *bound_addr,\n\t\t\t\t\t        unsigned port,\n\t\t\t\t\t\tunsigned concurrency_cnt,\n\t\t\t\t\t\tunsigned flags,\n\t\t\t\t\t\tpj_turn_listener **p_listener)\n{\n    pj_pool_t *pool;\n    struct udp_listener *udp;\n    pj_ioqueue_callback ioqueue_cb;\n    unsigned i;\n    pj_status_t status;\n\n    /* Create structure */\n    pool = pj_pool_create(srv->core.pf, \"udp%p\", 1000, 1000, NULL);\n    udp = PJ_POOL_ZALLOC_T(pool, struct udp_listener);\n    udp->base.pool = pool;\n    udp->base.obj_name = pool->obj_name;\n    udp->base.server = srv;\n    udp->base.tp_type = PJ_TURN_TP_UDP;\n    udp->base.sock = PJ_INVALID_SOCKET;\n    udp->base.destroy = &udp_destroy;\n    udp->read_cnt = concurrency_cnt;\n    udp->base.flags = flags;\n\n    udp->tp.obj_name = udp->base.obj_name;\n    udp->tp.info = udp->base.info;\n    udp->tp.listener = &udp->base;\n    udp->tp.sendto = &udp_sendto;\n    udp->tp.add_ref = &udp_add_ref;\n    udp->tp.dec_ref = &udp_dec_ref;\n\n    /* Create socket */\n    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &udp->base.sock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Init bind address */\n    status = pj_sockaddr_init(af, &udp->base.addr, bound_addr, \n\t\t\t      (pj_uint16_t)port);\n    if (status != PJ_SUCCESS) \n\tgoto on_error;\n    \n    /* Create info */\n    pj_ansi_strcpy(udp->base.info, \"UDP:\");\n    pj_sockaddr_print(&udp->base.addr, udp->base.info+4, \n\t\t      sizeof(udp->base.info)-4, 3);\n\n    /* Bind socket */\n    status = pj_sock_bind(udp->base.sock, &udp->base.addr, \n\t\t\t  pj_sockaddr_get_len(&udp->base.addr));\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Register to ioqueue */\n    pj_bzero(&ioqueue_cb, sizeof(ioqueue_cb));\n    ioqueue_cb.on_read_complete = on_read_complete;\n    status = pj_ioqueue_register_sock(pool, srv->core.ioqueue, udp->base.sock,\n\t\t\t\t      udp, &ioqueue_cb, &udp->key);\n\n    /* Create op keys */\n    udp->read_op = (struct read_op**)pj_pool_calloc(pool, concurrency_cnt, \n\t\t\t\t\t\t    sizeof(struct read_op*));\n\n    /* Create each read_op and kick off read operation */\n    for (i=0; i<concurrency_cnt; ++i) {\n\tpj_pool_t *rpool = pj_pool_create(srv->core.pf, \"rop%p\", \n\t\t\t\t\t  1000, 1000, NULL);\n\n\tudp->read_op[i] = PJ_POOL_ZALLOC_T(pool, struct read_op);\n\tudp->read_op[i]->pkt.pool = rpool;\n\n\ton_read_complete(udp->key, &udp->read_op[i]->op_key, 0);\n    }\n\n    /* Done */\n    PJ_LOG(4,(udp->base.obj_name, \"Listener %s created\", udp->base.info));\n\n    *p_listener = &udp->base;\n    return PJ_SUCCESS;\n\n\non_error:\n    udp_destroy(&udp->base);\n    return status;\n}\n\n\n/*\n * Destroy listener.\n */\nstatic pj_status_t udp_destroy(pj_turn_listener *listener)\n{\n    struct udp_listener *udp = (struct udp_listener *)listener;\n    unsigned i;\n\n    if (udp->key) {\n\tpj_ioqueue_unregister(udp->key);\n\tudp->key = NULL;\n\tudp->base.sock = PJ_INVALID_SOCKET;\n    } else if (udp->base.sock != PJ_INVALID_SOCKET) {\n\tpj_sock_close(udp->base.sock);\n\tudp->base.sock = PJ_INVALID_SOCKET;\n    }\n\n    for (i=0; i<udp->read_cnt; ++i) {\n\tif (udp->read_op[i]->pkt.pool) {\n\t    pj_pool_t *rpool = udp->read_op[i]->pkt.pool;\n\t    udp->read_op[i]->pkt.pool = NULL;\n\t    pj_pool_release(rpool);\n\t}\n    }\n\n    if (udp->base.pool) {\n\tpj_pool_t *pool = udp->base.pool;\n\n\tPJ_LOG(4,(udp->base.obj_name, \"Listener %s destroyed\", \n\t\t  udp->base.info));\n\n\tudp->base.pool = NULL;\n\tpj_pool_release(pool);\n    }\n    return PJ_SUCCESS;\n}\n\n/*\n * Callback to send packet.\n */\nstatic pj_status_t udp_sendto(pj_turn_transport *tp,\n\t\t\t      const void *packet,\n\t\t\t      pj_size_t size,\n\t\t\t      unsigned flag,\n\t\t\t      const pj_sockaddr_t *addr,\n\t\t\t      int addr_len)\n{\n    pj_ssize_t len = size;\n    return pj_sock_sendto(tp->listener->sock, packet, &len, flag, addr, addr_len);\n}\n\n\nstatic void udp_add_ref(pj_turn_transport *tp,\n\t\t\tpj_turn_allocation *alloc)\n{\n    /* Do nothing */\n    PJ_UNUSED_ARG(tp);\n    PJ_UNUSED_ARG(alloc);\n}\n\nstatic void udp_dec_ref(pj_turn_transport *tp,\n\t\t\tpj_turn_allocation *alloc)\n{\n    /* Do nothing */\n    PJ_UNUSED_ARG(tp);\n    PJ_UNUSED_ARG(alloc);\n}\n\n\n/*\n * Callback on received packet.\n */\nstatic void on_read_complete(pj_ioqueue_key_t *key, \n\t\t\t     pj_ioqueue_op_key_t *op_key, \n\t\t\t     pj_ssize_t bytes_read)\n{\n    struct udp_listener *udp;\n    struct read_op *read_op = (struct read_op*) op_key;\n    pj_status_t status;\n\n    udp = (struct udp_listener*) pj_ioqueue_get_user_data(key);\n\n    do {\n\tpj_pool_t *rpool;\n\n\t/* Report to server */\n\tif (bytes_read > 0) {\n\t    read_op->pkt.len = bytes_read;\n\t    pj_gettimeofday(&read_op->pkt.rx_time);\n\n\t    pj_turn_srv_on_rx_pkt(udp->base.server, &read_op->pkt);\n\t}\n\n\t/* Reset pool */\n\trpool = read_op->pkt.pool;\n\tpj_pool_reset(rpool);\n\tread_op->pkt.pool = rpool;\n\tread_op->pkt.transport = &udp->tp;\n\tread_op->pkt.src.tp_type = udp->base.tp_type;\n\n\t/* Read next packet */\n\tbytes_read = sizeof(read_op->pkt.pkt);\n\tread_op->pkt.src_addr_len = sizeof(read_op->pkt.src.clt_addr);\n\tpj_bzero(&read_op->pkt.src.clt_addr, sizeof(read_op->pkt.src.clt_addr));\n\n\tstatus = pj_ioqueue_recvfrom(udp->key, op_key,\n\t\t\t\t     read_op->pkt.pkt, &bytes_read, 0,\n\t\t\t\t     &read_op->pkt.src.clt_addr, \n\t\t\t\t     &read_op->pkt.src_addr_len);\n\n\tif (status != PJ_EPENDING && status != PJ_SUCCESS)\n\t    bytes_read = -status;\n\n    } while (status != PJ_EPENDING && status != PJ_ECANCELLED &&\n\t     status != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL));\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjturn-srv/main.c",
    "content": "/* $Id: main.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include \"turn.h\"\n#include \"auth.h\"\n\n#define REALM\t\t\"pjsip.org\"\n//#define TURN_PORT\tPJ_STUN_TURN_PORT\n#define TURN_PORT\t34780\n#define LOG_LEVEL\t4\n\n\nstatic pj_caching_pool g_cp;\n\nint err(const char *title, pj_status_t status)\n{\n    char errmsg[PJ_ERR_MSG_SIZE];\n    pj_strerror(status, errmsg, sizeof(errmsg));\n\n    printf(\"%s: %s\\n\", title, errmsg);\n    return 1;\n}\n\nstatic void dump_status(pj_turn_srv *srv)\n{\n    char addr[80];\n    pj_hash_iterator_t itbuf, *it;\n    pj_time_val now;\n    unsigned i;\n\n    for (i=0; i<srv->core.lis_cnt; ++i) {\n\tpj_turn_listener *lis = srv->core.listener[i];\n\tprintf(\"Server address : %s\\n\", lis->info);\n    }\n\n    printf(\"Worker threads : %d\\n\", srv->core.thread_cnt);\n    printf(\"Total mem usage: %u.%03uMB\\n\", (unsigned)(g_cp.used_size / 1000000), \n\t   (unsigned)((g_cp.used_size % 1000000)/1000));\n    printf(\"UDP port range : %u %u %u (next/min/max)\\n\", srv->ports.next_udp,\n\t   srv->ports.min_udp, srv->ports.max_udp);\n    printf(\"TCP port range : %u %u %u (next/min/max)\\n\", srv->ports.next_tcp,\n\t   srv->ports.min_tcp, srv->ports.max_tcp);\n    printf(\"Clients #      : %u\\n\", pj_hash_count(srv->tables.alloc));\n\n    puts(\"\");\n\n    if (pj_hash_count(srv->tables.alloc)==0) {\n\treturn;\n    }\n\n    puts(\"#    Client addr.          Alloc addr.            Username Lftm Expy #prm #chl\");\n    puts(\"------------------------------------------------------------------------------\");\n\n    pj_gettimeofday(&now);\n\n    it = pj_hash_first(srv->tables.alloc, &itbuf);\n    i=1;\n    while (it) {\n\tpj_turn_allocation *alloc = (pj_turn_allocation*) \n\t\t\t\t    pj_hash_this(srv->tables.alloc, it);\n\tprintf(\"%-3d %-22s %-22s %-8.*s %-4d %-4ld %-4d %-4d\\n\",\n\t       i,\n\t       alloc->info,\n\t       pj_sockaddr_print(&alloc->relay.hkey.addr, addr, sizeof(addr), 3),\n\t       (int)alloc->cred.data.static_cred.username.slen,\n\t       alloc->cred.data.static_cred.username.ptr,\n\t       alloc->relay.lifetime,\n\t       alloc->relay.expiry.sec - now.sec,\n\t       pj_hash_count(alloc->peer_table), \n\t       pj_hash_count(alloc->ch_table));\n\n\tit = pj_hash_next(srv->tables.alloc, it);\n\t++i;\n    }\n}\n\nstatic void menu(void)\n{\n    puts(\"\");\n    puts(\"Menu:\");\n    puts(\" d   Dump status\");\n    puts(\" q   Quit\");\n    printf(\">> \");\n}\n\nstatic void console_main(pj_turn_srv *srv)\n{\n    pj_bool_t quit = PJ_FALSE;\n\n    while (!quit) {\n\tchar line[10];\n\t\n\tmenu();\n\t    \n\tif (fgets(line, sizeof(line), stdin) == NULL)\n\t    break;\n\n\tswitch (line[0]) {\n\tcase 'd':\n\t    dump_status(srv);\n\t    break;\n\tcase 'q':\n\t    quit = PJ_TRUE;\n\t    break;\n\t}\n    }\n}\n\nint main()\n{\n    pj_turn_srv *srv;\n    pj_turn_listener *listener;\n    pj_status_t status;\n\n    status = pj_init();\n    if (status != PJ_SUCCESS)\n\treturn err(\"pj_init() error\", status);\n\n    pjlib_util_init();\n    pjnath_init();\n\n    pj_caching_pool_init(&g_cp, NULL, 0);\n\n    pj_turn_auth_init(REALM);\n\n    status = pj_turn_srv_create(&g_cp.factory, &srv);\n    if (status != PJ_SUCCESS)\n\treturn err(\"Error creating server\", status);\n\n    status = pj_turn_listener_create_udp(srv, pj_AF_INET(), NULL, \n\t\t\t\t\t TURN_PORT, 1, 0, &listener);\n    if (status != PJ_SUCCESS)\n\treturn err(\"Error creating UDP listener\", status);\n\n#if PJ_HAS_TCP\n    status = pj_turn_listener_create_tcp(srv, pj_AF_INET(), NULL, \n\t\t\t\t\t TURN_PORT, 1, 0, &listener);\n    if (status != PJ_SUCCESS)\n\treturn err(\"Error creating listener\", status);\n#endif\n\n    status = pj_turn_srv_add_listener(srv, listener);\n    if (status != PJ_SUCCESS)\n\treturn err(\"Error adding listener\", status);\n\n    puts(\"Server is running\");\n\n    pj_log_set_level(LOG_LEVEL);\n\n    console_main(srv);\n\n    pj_turn_srv_destroy(srv);\n    pj_caching_pool_destroy(&g_cp);\n    pj_shutdown();\n\n    return 0;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjturn-srv/server.c",
    "content": "/* $Id: server.c 4360 2013-02-21 11:26:35Z bennylp $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include \"turn.h\"\n#include \"auth.h\"\n\n#define MAX_CLIENTS\t\t32\n#define MAX_PEERS_PER_CLIENT\t8\n//#define MAX_HANDLES\t\t(MAX_CLIENTS*MAX_PEERS_PER_CLIENT+MAX_LISTENERS)\n#define MAX_HANDLES\t\tPJ_IOQUEUE_MAX_HANDLES\n#define MAX_TIMER\t\t(MAX_HANDLES * 2)\n#define MIN_PORT\t\t49152\n#define MAX_PORT\t\t65535\n#define MAX_LISTENERS\t\t16\n#define MAX_THREADS\t\t2\n#define MAX_NET_EVENTS\t\t1000\n\n/* Prototypes */\nstatic int server_thread_proc(void *arg);\nstatic pj_status_t on_tx_stun_msg( pj_stun_session *sess,\n\t\t\t\t   void *token,\n\t\t\t\t   const void *pkt,\n\t\t\t\t   pj_size_t pkt_size,\n\t\t\t\t   const pj_sockaddr_t *dst_addr,\n\t\t\t\t   unsigned addr_len);\nstatic pj_status_t on_rx_stun_request(pj_stun_session *sess,\n\t\t\t\t      const pj_uint8_t *pkt,\n\t\t\t\t      unsigned pkt_len,\n\t\t\t\t      const pj_stun_rx_data *rdata,\n\t\t\t\t      void *user_data,\n\t\t\t\t      const pj_sockaddr_t *src_addr,\n\t\t\t\t      unsigned src_addr_len);\n\nstruct saved_cred\n{\n    pj_str_t realm;\n    pj_str_t username;\n    pj_str_t nonce;\n    int\t     data_type;\n    pj_str_t data;\n};\n\n\n/*\n * Get transport type name, normally for logging purpose only.\n */\nPJ_DEF(const char*) pj_turn_tp_type_name(int tp_type)\n{\n    /* Must be 3 characters long! */\n    if (tp_type == PJ_TURN_TP_UDP) {\n\treturn \"UDP\";\n    } else if (tp_type == PJ_TURN_TP_TCP) {\n\treturn \"TCP\";\n    } else {\n\tpj_assert(!\"Unsupported transport\");\n\treturn \"???\";\n    }\n}\n\n/*\n * Create server.\n */\nPJ_DEF(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf,\n\t\t\t\t       pj_turn_srv **p_srv)\n{\n    pj_pool_t *pool;\n    pj_stun_session_cb sess_cb;\n    pj_turn_srv *srv;\n    unsigned i;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pf && p_srv, PJ_EINVAL);\n\n    /* Create server and init core settings */\n    pool = pj_pool_create(pf, \"srv%p\", 1000, 1000, NULL);\n    srv = PJ_POOL_ZALLOC_T(pool, pj_turn_srv);\n    srv->obj_name = pool->obj_name;\n    srv->core.pf = pf;\n    srv->core.pool = pool;\n    srv->core.tls_key = srv->core.tls_data = -1;\n\n    /* Create ioqueue */\n    status = pj_ioqueue_create(pool, MAX_HANDLES, &srv->core.ioqueue);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Server mutex */\n    status = pj_lock_create_recursive_mutex(pool, srv->obj_name,\n\t\t\t\t\t    &srv->core.lock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Allocate TLS */\n    status = pj_thread_local_alloc(&srv->core.tls_key);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    status = pj_thread_local_alloc(&srv->core.tls_data);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Create timer heap */\n    status = pj_timer_heap_create(pool, MAX_TIMER, &srv->core.timer_heap);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Configure lock for the timer heap */\n    pj_timer_heap_set_lock(srv->core.timer_heap, srv->core.lock, PJ_FALSE);\n\n    /* Array of listeners */\n    srv->core.listener = (pj_turn_listener**)\n\t\t\t pj_pool_calloc(pool, MAX_LISTENERS,\n\t\t\t\t\tsizeof(srv->core.listener[0]));\n\n    /* Create hash tables */\n    srv->tables.alloc = pj_hash_create(pool, MAX_CLIENTS);\n    srv->tables.res = pj_hash_create(pool, MAX_CLIENTS);\n\n    /* Init ports settings */\n    srv->ports.min_udp = srv->ports.next_udp = MIN_PORT;\n    srv->ports.max_udp = MAX_PORT;\n    srv->ports.min_tcp = srv->ports.next_tcp = MIN_PORT;\n    srv->ports.max_tcp = MAX_PORT;\n\n    /* Init STUN config */\n    pj_stun_config_init(&srv->core.stun_cfg, pf, 0, srv->core.ioqueue,\n\t\t        srv->core.timer_heap);\n\n    /* Init STUN credential */\n    srv->core.cred.type = PJ_STUN_AUTH_CRED_DYNAMIC;\n    srv->core.cred.data.dyn_cred.user_data = srv;\n    srv->core.cred.data.dyn_cred.get_auth = &pj_turn_get_auth;\n    srv->core.cred.data.dyn_cred.get_password = &pj_turn_get_password;\n    srv->core.cred.data.dyn_cred.verify_nonce = &pj_turn_verify_nonce;\n\n    /* Create STUN session to handle new allocation */\n    pj_bzero(&sess_cb, sizeof(sess_cb));\n    sess_cb.on_rx_request = &on_rx_stun_request;\n    sess_cb.on_send_msg = &on_tx_stun_msg;\n\n    status = pj_stun_session_create(&srv->core.stun_cfg, srv->obj_name,\n\t\t\t\t    &sess_cb, PJ_FALSE, NULL,\n\t\t\t\t    &srv->core.stun_sess);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    pj_stun_session_set_user_data(srv->core.stun_sess, srv);\n    pj_stun_session_set_credential(srv->core.stun_sess, PJ_STUN_AUTH_LONG_TERM,\n\t\t\t\t   &srv->core.cred);\n\n\n    /* Array of worker threads */\n    srv->core.thread_cnt = MAX_THREADS;\n    srv->core.thread = (pj_thread_t**)\n\t\t       pj_pool_calloc(pool, srv->core.thread_cnt,\n\t\t\t\t      sizeof(pj_thread_t*));\n\n    /* Start the worker threads */\n    for (i=0; i<srv->core.thread_cnt; ++i) {\n\tstatus = pj_thread_create(pool, srv->obj_name, &server_thread_proc,\n\t\t\t\t  srv, 0, 0, &srv->core.thread[i]);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n    }\n\n    /* We're done. Application should add listeners now */\n    PJ_LOG(4,(srv->obj_name, \"TURN server v%s is running\",\n\t      pj_get_version()));\n\n    *p_srv = srv;\n    return PJ_SUCCESS;\n\non_error:\n    pj_turn_srv_destroy(srv);\n    return status;\n}\n\n\n/*\n * Handle timer and network events\n */\nstatic void srv_handle_events(pj_turn_srv *srv, const pj_time_val *max_timeout)\n{\n    /* timeout is 'out' var. This just to make compiler happy. */\n    pj_time_val timeout = { 0, 0};\n    unsigned net_event_count = 0;\n    int c;\n\n    /* Poll the timer. The timer heap has its own mutex for better\n     * granularity, so we don't need to lock the server.\n     */\n    timeout.sec = timeout.msec = 0;\n    c = pj_timer_heap_poll( srv->core.timer_heap, &timeout );\n\n    /* timer_heap_poll should never ever returns negative value, or otherwise\n     * ioqueue_poll() will block forever!\n     */\n    pj_assert(timeout.sec >= 0 && timeout.msec >= 0);\n    if (timeout.msec >= 1000) timeout.msec = 999;\n\n    /* If caller specifies maximum time to wait, then compare the value with\n     * the timeout to wait from timer, and use the minimum value.\n     */\n    if (max_timeout && PJ_TIME_VAL_GT(timeout, *max_timeout)) {\n\ttimeout = *max_timeout;\n    }\n\n    /* Poll ioqueue.\n     * Repeat polling the ioqueue while we have immediate events, because\n     * timer heap may process more than one events, so if we only process\n     * one network events at a time (such as when IOCP backend is used),\n     * the ioqueue may have trouble keeping up with the request rate.\n     *\n     * For example, for each send() request, one network event will be\n     *   reported by ioqueue for the send() completion. If we don't poll\n     *   the ioqueue often enough, the send() completion will not be\n     *   reported in timely manner.\n     */\n    do {\n\tc = pj_ioqueue_poll( srv->core.ioqueue, &timeout);\n\tif (c < 0) {\n\t    pj_thread_sleep(PJ_TIME_VAL_MSEC(timeout));\n\t    return;\n\t} else if (c == 0) {\n\t    break;\n\t} else {\n\t    net_event_count += c;\n\t    timeout.sec = timeout.msec = 0;\n\t}\n    } while (c > 0 && net_event_count < MAX_NET_EVENTS);\n\n}\n\n/*\n * Server worker thread proc.\n */\nstatic int server_thread_proc(void *arg)\n{\n    pj_turn_srv *srv = (pj_turn_srv*)arg;\n\n    while (!srv->core.quit) {\n\tpj_time_val timeout_max = {0, 100};\n\tsrv_handle_events(srv, &timeout_max);\n    }\n\n    return 0;\n}\n\n/*\n * Destroy the server.\n */\nPJ_DEF(pj_status_t) pj_turn_srv_destroy(pj_turn_srv *srv)\n{\n    pj_hash_iterator_t itbuf, *it;\n    unsigned i;\n\n    /* Stop all worker threads */\n    srv->core.quit = PJ_TRUE;\n    for (i=0; i<srv->core.thread_cnt; ++i) {\n\tif (srv->core.thread[i]) {\n\t    pj_thread_join(srv->core.thread[i]);\n\t    pj_thread_destroy(srv->core.thread[i]);\n\t    srv->core.thread[i] = NULL;\n\t}\n    }\n\n    /* Destroy all allocations FIRST */\n    if (srv->tables.alloc) {\n\tit = pj_hash_first(srv->tables.alloc, &itbuf);\n\twhile (it != NULL) {\n\t    pj_turn_allocation *alloc = (pj_turn_allocation*)\n\t\t\t\t\tpj_hash_this(srv->tables.alloc, it);\n\t    pj_hash_iterator_t *next = pj_hash_next(srv->tables.alloc, it);\n\t    pj_turn_allocation_destroy(alloc);\n\t    it = next;\n\t}\n    }\n\n    /* Destroy all listeners. */\n    for (i=0; i<srv->core.lis_cnt; ++i) {\n\tif (srv->core.listener[i]) {\n\t    pj_turn_listener_destroy(srv->core.listener[i]);\n\t    srv->core.listener[i] = NULL;\n\t}\n    }\n\n    /* Destroy STUN session */\n    if (srv->core.stun_sess) {\n\tpj_stun_session_destroy(srv->core.stun_sess);\n\tsrv->core.stun_sess = NULL;\n    }\n\n    /* Destroy hash tables (well, sort of) */\n    if (srv->tables.alloc) {\n\tsrv->tables.alloc = NULL;\n\tsrv->tables.res = NULL;\n    }\n\n    /* Destroy timer heap */\n    if (srv->core.timer_heap) {\n\tpj_timer_heap_destroy(srv->core.timer_heap);\n\tsrv->core.timer_heap = NULL;\n    }\n\n    /* Destroy ioqueue */\n    if (srv->core.ioqueue) {\n\tpj_ioqueue_destroy(srv->core.ioqueue);\n\tsrv->core.ioqueue = NULL;\n    }\n\n    /* Destroy thread local IDs */\n    if (srv->core.tls_key != -1) {\n\tpj_thread_local_free(srv->core.tls_key);\n\tsrv->core.tls_key = -1;\n    }\n    if (srv->core.tls_data != -1) {\n\tpj_thread_local_free(srv->core.tls_data);\n\tsrv->core.tls_data = -1;\n    }\n\n    /* Destroy server lock */\n    if (srv->core.lock) {\n\tpj_lock_destroy(srv->core.lock);\n\tsrv->core.lock = NULL;\n    }\n\n    /* Release pool */\n    if (srv->core.pool) {\n\tpj_pool_t *pool = srv->core.pool;\n\tsrv->core.pool = NULL;\n\tpj_pool_release(pool);\n    }\n\n    /* Done */\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Add listener.\n */\nPJ_DEF(pj_status_t) pj_turn_srv_add_listener(pj_turn_srv *srv,\n\t\t\t\t\t     pj_turn_listener *lis)\n{\n    unsigned index;\n\n    PJ_ASSERT_RETURN(srv && lis, PJ_EINVAL);\n    PJ_ASSERT_RETURN(srv->core.lis_cnt < MAX_LISTENERS, PJ_ETOOMANY);\n\n    /* Add to array */\n    index = srv->core.lis_cnt;\n    srv->core.listener[index] = lis;\n    lis->server = srv;\n    lis->id = index;\n    srv->core.lis_cnt++;\n\n    PJ_LOG(4,(srv->obj_name, \"Listener %s/%s added at index %d\",\n\t      lis->obj_name, lis->info, lis->id));\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Destroy listener.\n */\nPJ_DEF(pj_status_t) pj_turn_listener_destroy(pj_turn_listener *listener)\n{\n    pj_turn_srv *srv = listener->server;\n    unsigned i;\n\n    /* Remove from our listener list */\n    pj_lock_acquire(srv->core.lock);\n    for (i=0; i<srv->core.lis_cnt; ++i) {\n\tif (srv->core.listener[i] == listener) {\n\t    srv->core.listener[i] = NULL;\n\t    srv->core.lis_cnt--;\n\t    listener->id = PJ_TURN_INVALID_LIS_ID;\n\t    break;\n\t}\n    }\n    pj_lock_release(srv->core.lock);\n\n    /* Destroy */\n    return listener->destroy(listener);\n}\n\n\n/**\n * Add a reference to a transport.\n */\nPJ_DEF(void) pj_turn_transport_add_ref( pj_turn_transport *transport,\n\t\t\t\t\tpj_turn_allocation *alloc)\n{\n    transport->add_ref(transport, alloc);\n}\n\n\n/**\n * Decrement transport reference counter.\n */\nPJ_DEF(void) pj_turn_transport_dec_ref( pj_turn_transport *transport,\n\t\t\t\t\tpj_turn_allocation *alloc)\n{\n    transport->dec_ref(transport, alloc);\n}\n\n\n/*\n * Register an allocation to the hash tables.\n */\nPJ_DEF(pj_status_t) pj_turn_srv_register_allocation(pj_turn_srv *srv,\n\t\t\t\t\t\t    pj_turn_allocation *alloc)\n{\n    /* Add to hash tables */\n    pj_lock_acquire(srv->core.lock);\n    pj_hash_set(alloc->pool, srv->tables.alloc,\n\t\t&alloc->hkey, sizeof(alloc->hkey), 0, alloc);\n    pj_hash_set(alloc->pool, srv->tables.res,\n\t\t&alloc->relay.hkey, sizeof(alloc->relay.hkey), 0,\n\t\t&alloc->relay);\n    pj_lock_release(srv->core.lock);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Unregister an allocation from the hash tables.\n */\nPJ_DEF(pj_status_t) pj_turn_srv_unregister_allocation(pj_turn_srv *srv,\n\t\t\t\t\t\t     pj_turn_allocation *alloc)\n{\n    /* Unregister from hash tables */\n    pj_lock_acquire(srv->core.lock);\n    pj_hash_set(alloc->pool, srv->tables.alloc,\n\t\t&alloc->hkey, sizeof(alloc->hkey), 0, NULL);\n    pj_hash_set(alloc->pool, srv->tables.res,\n\t\t&alloc->relay.hkey, sizeof(alloc->relay.hkey), 0, NULL);\n    pj_lock_release(srv->core.lock);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Callback from our own STUN session whenever it needs to send\n * outgoing STUN packet.\n */\nstatic pj_status_t on_tx_stun_msg( pj_stun_session *sess,\n\t\t\t\t   void *token,\n\t\t\t\t   const void *pdu,\n\t\t\t\t   pj_size_t pdu_size,\n\t\t\t\t   const pj_sockaddr_t *dst_addr,\n\t\t\t\t   unsigned addr_len)\n{\n    pj_turn_transport *transport = (pj_turn_transport*) token;\n\n    PJ_ASSERT_RETURN(transport!=NULL, PJ_EINVALIDOP);\n\n    PJ_UNUSED_ARG(sess);\n\n    return transport->sendto(transport, pdu, pdu_size, 0,\n\t\t\t     dst_addr, addr_len);\n}\n\n\n/* Respond to STUN request */\nstatic pj_status_t stun_respond(pj_stun_session *sess,\n\t\t\t\tpj_turn_transport *transport,\n\t\t\t\tconst pj_stun_rx_data *rdata,\n\t\t\t\tunsigned code,\n\t\t\t\tconst char *errmsg,\n\t\t\t\tpj_bool_t cache,\n\t\t\t\tconst pj_sockaddr_t *dst_addr,\n\t\t\t\tunsigned addr_len)\n{\n    pj_status_t status;\n    pj_str_t reason;\n    pj_stun_tx_data *tdata;\n\n    /* Create response */\n    status = pj_stun_session_create_res(sess, rdata, code,\n\t\t\t\t\t(errmsg?pj_cstr(&reason,errmsg):NULL),\n\t\t\t\t\t&tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Send the response */\n    return pj_stun_session_send_msg(sess, transport, cache, PJ_FALSE,\n\t\t\t\t    dst_addr,  addr_len, tdata);\n}\n\n\n/* Callback from our own STUN session when incoming request arrives.\n * This function is triggered by pj_stun_session_on_rx_pkt() call in\n * pj_turn_srv_on_rx_pkt() function below.\n */\nstatic pj_status_t on_rx_stun_request(pj_stun_session *sess,\n\t\t\t\t      const pj_uint8_t *pdu,\n\t\t\t\t      unsigned pdu_len,\n\t\t\t\t      const pj_stun_rx_data *rdata,\n\t\t\t\t      void *token,\n\t\t\t\t      const pj_sockaddr_t *src_addr,\n\t\t\t\t      unsigned src_addr_len)\n{\n    pj_turn_transport *transport;\n    const pj_stun_msg *msg = rdata->msg;\n    pj_turn_allocation *alloc;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(pdu);\n    PJ_UNUSED_ARG(pdu_len);\n\n    transport = (pj_turn_transport*) token;\n\n    /* Respond any requests other than ALLOCATE with 437 response */\n    if (msg->hdr.type != PJ_STUN_ALLOCATE_REQUEST) {\n\tstun_respond(sess, transport, rdata, PJ_STUN_SC_ALLOCATION_MISMATCH,\n\t\t     NULL, PJ_FALSE, src_addr, src_addr_len);\n\treturn PJ_SUCCESS;\n    }\n\n    /* Create new allocation. The relay resource will be allocated\n     * in this function.\n     */\n    status = pj_turn_allocation_create(transport, src_addr, src_addr_len,\n\t\t\t\t       rdata, sess, &alloc);\n    if (status != PJ_SUCCESS) {\n\t/* STUN response has been sent, no need to reply here */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Done. */\n    return PJ_SUCCESS;\n}\n\n/* Handle STUN Binding request */\nstatic void handle_binding_request(pj_turn_pkt *pkt,\n\t\t\t\t   unsigned options)\n{\n    pj_stun_msg *request, *response;\n    pj_uint8_t pdu[200];\n    pj_size_t len;\n    pj_status_t status;\n\n    /* Decode request */\n    status = pj_stun_msg_decode(pkt->pool, pkt->pkt, pkt->len, options,\n\t\t\t\t&request, NULL, NULL);\n    if (status != PJ_SUCCESS)\n\treturn;\n\n    /* Create response */\n    status = pj_stun_msg_create_response(pkt->pool, request, 0, NULL,\n\t\t\t\t\t &response);\n    if (status != PJ_SUCCESS)\n\treturn;\n\n    /* Add XOR-MAPPED-ADDRESS */\n    pj_stun_msg_add_sockaddr_attr(pkt->pool, response,\n\t\t\t\t  PJ_STUN_ATTR_XOR_MAPPED_ADDR,\n\t\t\t\t  PJ_TRUE,\n\t\t\t\t  &pkt->src.clt_addr,\n\t\t\t\t  pkt->src_addr_len);\n\n    /* Encode */\n    status = pj_stun_msg_encode(response, pdu, sizeof(pdu), 0, NULL, &len);\n    if (status != PJ_SUCCESS)\n\treturn;\n\n    /* Send response */\n    pkt->transport->sendto(pkt->transport, pdu, len, 0,\n\t\t\t   &pkt->src.clt_addr, pkt->src_addr_len);\n}\n\n/*\n * This callback is called by UDP listener on incoming packet. This is\n * the first entry for incoming packet (from client) to the server. From\n * here, the packet may be handed over to an allocation if an allocation\n * is found for the client address, or handed over to owned STUN session\n * if an allocation is not found.\n */\nPJ_DEF(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv,\n\t\t\t\t   pj_turn_pkt *pkt)\n{\n    pj_turn_allocation *alloc;\n\n    /* Get TURN allocation from the source address */\n    pj_lock_acquire(srv->core.lock);\n    alloc = (pj_turn_allocation*)\n\t    pj_hash_get(srv->tables.alloc, &pkt->src, sizeof(pkt->src), NULL);\n    pj_lock_release(srv->core.lock);\n\n    /* If allocation is found, just hand over the packet to the\n     * allocation.\n     */\n    if (alloc) {\n\tpj_turn_allocation_on_rx_client_pkt(alloc, pkt);\n    } else {\n\t/* Otherwise this is a new client */\n\tunsigned options;\n\tpj_size_t parsed_len;\n\tpj_status_t status;\n\n\t/* Check that this is a STUN message */\n\toptions = PJ_STUN_CHECK_PACKET | PJ_STUN_NO_FINGERPRINT_CHECK;\n\tif (pkt->transport->listener->tp_type == PJ_TURN_TP_UDP)\n\t    options |= PJ_STUN_IS_DATAGRAM;\n\n\tstatus = pj_stun_msg_check(pkt->pkt, pkt->len, options);\n\tif (status != PJ_SUCCESS) {\n\t    /* If the first byte are not STUN, drop the packet. First byte\n\t     * of STUN message is always 0x00 or 0x01. Otherwise wait for\n\t     * more data as the data might have come from TCP.\n\t     *\n\t     * Also drop packet if it's unreasonably too big, as this might\n\t     * indicate invalid data that's building up in the buffer.\n\t     *\n\t     * Or if packet is a datagram.\n\t     */\n\t    if ((*pkt->pkt != 0x00 && *pkt->pkt != 0x01) ||\n\t\tpkt->len > 1600 ||\n\t\t(options & PJ_STUN_IS_DATAGRAM))\n\t    {\n\t\tchar errmsg[PJ_ERR_MSG_SIZE];\n\t\tchar ip[PJ_INET6_ADDRSTRLEN+10];\n\n\t\tpkt->len = 0;\n\n\t\tpj_strerror(status, errmsg, sizeof(errmsg));\n\t\tPJ_LOG(5,(srv->obj_name,\n\t\t\t  \"Non-STUN packet from %s is dropped: %s\",\n\t\t\t  pj_sockaddr_print(&pkt->src.clt_addr, ip, sizeof(ip), 3),\n\t\t\t  errmsg));\n\t    }\n\t    return;\n\t}\n\n\t/* Special handling for Binding Request. We won't give it to the\n\t * STUN session since this request is not authenticated.\n\t */\n\tif (pkt->pkt[1] == 1) {\n\t    handle_binding_request(pkt, options);\n\t    return;\n\t}\n\n\t/* Hand over processing to STUN session. This will trigger\n\t * on_rx_stun_request() callback to be called if the STUN\n\t * message is a request.\n\t */\n\toptions &= ~PJ_STUN_CHECK_PACKET;\n\tparsed_len = 0;\n\tstatus = pj_stun_session_on_rx_pkt(srv->core.stun_sess, pkt->pkt,\n\t\t\t\t\t   pkt->len, options, pkt->transport,\n\t\t\t\t\t   &parsed_len, &pkt->src.clt_addr,\n\t\t\t\t\t   pkt->src_addr_len);\n\tif (status != PJ_SUCCESS) {\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\t    char ip[PJ_INET6_ADDRSTRLEN+10];\n\n\t    pj_strerror(status, errmsg, sizeof(errmsg));\n\t    PJ_LOG(5,(srv->obj_name,\n\t\t      \"Error processing STUN packet from %s: %s\",\n\t\t      pj_sockaddr_print(&pkt->src.clt_addr, ip, sizeof(ip), 3),\n\t\t      errmsg));\n\t}\n\n\tif (pkt->transport->listener->tp_type == PJ_TURN_TP_UDP) {\n\t    pkt->len = 0;\n\t} else if (parsed_len > 0) {\n\t    if (parsed_len == pkt->len) {\n\t\tpkt->len = 0;\n\t    } else {\n\t\tpj_memmove(pkt->pkt, pkt->pkt+parsed_len,\n\t\t\t   pkt->len - parsed_len);\n\t\tpkt->len -= parsed_len;\n\t    }\n\t}\n    }\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjnath/src/pjturn-srv/turn.h",
    "content": "/* $Id: turn.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJ_TURN_SRV_TURN_H__\n#define __PJ_TURN_SRV_TURN_H__\n\n#include <pjlib.h>\n#include <pjnath.h>\n\ntypedef struct pj_turn_relay_res    pj_turn_relay_res;\ntypedef struct pj_turn_listener\t    pj_turn_listener;\ntypedef struct pj_turn_transport    pj_turn_transport;\ntypedef struct pj_turn_permission   pj_turn_permission;\ntypedef struct pj_turn_allocation   pj_turn_allocation;\ntypedef struct pj_turn_srv\t    pj_turn_srv;\ntypedef struct pj_turn_pkt\t    pj_turn_pkt;\n\n\n#define PJ_TURN_INVALID_LIS_ID\t    ((unsigned)-1)\n\n/** \n * Get transport type name string.\n */\nPJ_DECL(const char*) pj_turn_tp_type_name(int tp_type);\n\n/**\n * This structure describes TURN relay resource. An allocation allocates\n * one relay resource, and optionally it may reserve another resource.\n */\nstruct pj_turn_relay_res\n{\n    /** Hash table key */\n    struct {\n\t/** Transport type. */\n\tint\t\t    tp_type;\n\n\t/** Transport/relay address */\n\tpj_sockaddr\t    addr;\n    } hkey;\n\n    /** Allocation who requested or reserved this resource. */\n    pj_turn_allocation *allocation;\n\n    /** Username used in credential */\n    pj_str_t\t    user;\n\n    /** Realm used in credential. */\n    pj_str_t\t    realm;\n\n    /** Lifetime, in seconds. */\n    unsigned\t    lifetime;\n\n    /** Relay/allocation expiration time */\n    pj_time_val\t    expiry;\n\n    /** Timeout timer entry */\n    pj_timer_entry  timer;\n\n    /** Transport. */\n    struct {\n\t/** Transport/relay socket */\n\tpj_sock_t\t    sock;\n\n\t/** Transport/relay ioqueue */\n\tpj_ioqueue_key_t    *key;\n\n\t/** Read operation key. */\n\tpj_ioqueue_op_key_t read_key;\n\n\t/** The incoming packet buffer */\n\tchar\t\t    rx_pkt[PJ_TURN_MAX_PKT_LEN];\n\n\t/** Source address of the packet. */\n\tpj_sockaddr\t    src_addr;\n\n\t/** Source address length */\n\tint\t\t    src_addr_len;\n\n\t/** The outgoing packet buffer. This must be 3wbit aligned. */\n\tchar\t\t    tx_pkt[PJ_TURN_MAX_PKT_LEN+4];\n    } tp;\n};\n\n\n/****************************************************************************/\n/*\n * TURN Allocation API\n */\n\n/**\n * This structure describes key to lookup TURN allocations in the\n * allocation hash table.\n */\ntypedef struct pj_turn_allocation_key\n{\n    int\t\t    tp_type;\t/**< Transport type.\t    */\n    pj_sockaddr\t    clt_addr;\t/**< Client's address.\t    */\n} pj_turn_allocation_key;\n\n\n/**\n * This structure describes TURN pj_turn_allocation session.\n */\nstruct pj_turn_allocation\n{\n    /** Hash table key to identify client. */\n    pj_turn_allocation_key hkey;\n\n    /** Pool for this allocation. */\n    pj_pool_t\t\t*pool;\n\n    /** Object name for logging identification */\n    char\t\t*obj_name;\n\n    /** Client info (IP address and port) */\n    char\t\tinfo[80];\n\n    /** Mutex */\n    pj_lock_t\t\t*lock;\n\n    /** Server instance. */\n    pj_turn_srv\t\t*server;\n\n    /** Transport to send/receive packets to/from client. */\n    pj_turn_transport\t*transport;\n\n    /** The relay resource for this allocation. */\n    pj_turn_relay_res\trelay;\n\n    /** Relay resource reserved by this allocation, if any */\n    pj_turn_relay_res\t*resv;\n\n    /** Requested bandwidth */\n    unsigned\t\tbandwidth;\n\n    /** STUN session for this client */\n    pj_stun_session\t*sess;\n\n    /** Credential for this STUN session. */\n    pj_stun_auth_cred\t cred;\n\n    /** Peer hash table (keyed by peer address) */\n    pj_hash_table_t\t*peer_table;\n\n    /** Channel hash table (keyed by channel number) */\n    pj_hash_table_t\t*ch_table;\n};\n\n\n/**\n * This structure describes the hash table key to lookup TURN\n * permission.\n */\ntypedef struct pj_turn_permission_key\n{\n    /** Peer address. */\n    pj_sockaddr\t\tpeer_addr;\n\n} pj_turn_permission_key;\n\n\n/**\n * This structure describes TURN pj_turn_permission or channel.\n */\nstruct pj_turn_permission\n{\n    /** Hash table key */\n    pj_turn_permission_key hkey;\n\n    /** TURN allocation that owns this permission/channel */\n    pj_turn_allocation\t*allocation;\n\n    /** Optional channel number, or PJ_TURN_INVALID_CHANNEL if channel number\n     *  is not requested for this permission. \n     */\n    pj_uint16_t\t\tchannel;\n\n    /** Permission expiration time. */\n    pj_time_val\t\texpiry;\n};\n\n/**\n * Create new allocation.\n */\nPJ_DECL(pj_status_t) pj_turn_allocation_create(pj_turn_transport *transport,\n\t\t\t\t\t       const pj_sockaddr_t *src_addr,\n\t\t\t\t\t       unsigned src_addr_len,\n\t\t\t\t\t       const pj_stun_rx_data *rdata,\n\t\t\t\t\t       pj_stun_session *srv_sess,\n\t\t\t\t\t       pj_turn_allocation **p_alloc);\n/**\n * Destroy allocation.\n */\nPJ_DECL(void) pj_turn_allocation_destroy(pj_turn_allocation *alloc);\n\n\n/**\n * Handle incoming packet from client.\n */\nPJ_DECL(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc,\n\t\t\t\t\t\t  pj_turn_pkt *pkt);\n\n/**\n * Handle transport closure.\n */\nPJ_DECL(void) pj_turn_allocation_on_transport_closed(pj_turn_allocation *alloc,\n\t\t\t\t\t\t     pj_turn_transport *tp);\n\n/****************************************************************************/\n/*\n * TURN Listener API\n */\n\n/**\n * This structure describes TURN listener socket. A TURN listener socket\n * listens for incoming connections from clients.\n */\nstruct pj_turn_listener\n{\n    /** Object name/identification */\n    char\t\t*obj_name;\n\n    /** Slightly longer info about this listener */\n    char\t\tinfo[80];\n\n    /** TURN server instance. */\n    pj_turn_srv\t\t*server;\n\n    /** Listener index in the server */\n    unsigned\t\tid;\n\n    /** Pool for this listener. */\n    pj_pool_t\t       *pool;\n\n    /** Transport type. */\n    int\t\t\ttp_type;\n\n    /** Bound address of this listener. */\n    pj_sockaddr\t\taddr;\n\n    /** Socket. */\n    pj_sock_t\t\tsock;\n\n    /** Flags. */\n    unsigned\t\tflags;\n\n    /** Destroy handler */\n    pj_status_t\t\t(*destroy)(pj_turn_listener*);\n};\n\n\n/**\n * This structure describes TURN transport socket which is used to send and\n * receive packets towards client.\n */\nstruct pj_turn_transport\n{\n    /** Object name/identification */\n    char\t\t*obj_name;\n\n    /** Slightly longer info about this listener */\n    char\t\t*info;\n\n    /** Listener instance */\n    pj_turn_listener\t*listener;\n\n    /** Sendto handler */\n    pj_status_t\t\t(*sendto)(pj_turn_transport *tp,\n\t\t\t\t  const void *packet,\n\t\t\t\t  pj_size_t size,\n\t\t\t\t  unsigned flag,\n\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t  int addr_len);\n\n    /** Addref handler */\n    void\t\t(*add_ref)(pj_turn_transport *tp,\n\t\t\t\t   pj_turn_allocation *alloc);\n\n    /** Decref handler */\n    void\t\t(*dec_ref)(pj_turn_transport *tp,\n\t\t\t\t   pj_turn_allocation *alloc);\n\n};\n\n\n/**\n * An incoming packet.\n */\nstruct pj_turn_pkt\n{\n    /** Pool for this packet */\n    pj_pool_t\t\t    *pool;\n\n    /** Transport where the packet was received. */\n    pj_turn_transport\t    *transport;\n\n    /** Packet buffer (must be 32bit aligned). */\n    pj_uint8_t\t\t    pkt[PJ_TURN_MAX_PKT_LEN];\n\n    /** Size of the packet */\n    pj_size_t\t\t    len;\n\n    /** Arrival time. */\n    pj_time_val\t\t    rx_time;\n\n    /** Source transport type and source address. */\n    pj_turn_allocation_key   src;\n\n    /** Source address length. */\n    int\t\t\t    src_addr_len;\n};\n\n\n/**\n * Create a UDP listener on the specified port.\n */\nPJ_DECL(pj_status_t) pj_turn_listener_create_udp(pj_turn_srv *srv,\n\t\t\t\t\t\t int af,\n\t\t\t\t\t         const pj_str_t *bound_addr,\n\t\t\t\t\t         unsigned port,\n\t\t\t\t\t\t unsigned concurrency_cnt,\n\t\t\t\t\t\t unsigned flags,\n\t\t\t\t\t\t pj_turn_listener **p_lis);\n\n/**\n * Create a TCP listener on the specified port.\n */\nPJ_DECL(pj_status_t) pj_turn_listener_create_tcp(pj_turn_srv *srv,\n\t\t\t\t\t\t int af,\n\t\t\t\t\t         const pj_str_t *bound_addr,\n\t\t\t\t\t         unsigned port,\n\t\t\t\t\t\t unsigned concurrency_cnt,\n\t\t\t\t\t\t unsigned flags,\n\t\t\t\t\t\t pj_turn_listener **p_lis);\n\n/**\n * Destroy listener.\n */\nPJ_DECL(pj_status_t) pj_turn_listener_destroy(pj_turn_listener *listener);\n\n\n/**\n * Add a reference to a transport.\n */\nPJ_DECL(void) pj_turn_transport_add_ref(pj_turn_transport *transport,\n\t\t\t\t\tpj_turn_allocation *alloc);\n\n\n/**\n * Decrement transport reference counter.\n */\nPJ_DECL(void) pj_turn_transport_dec_ref(pj_turn_transport *transport,\n\t\t\t\t\tpj_turn_allocation *alloc);\n\n\n\n/****************************************************************************/\n/*\n * TURN Server API\n */\n/**\n * This structure describes TURN pj_turn_srv instance.\n */\nstruct pj_turn_srv\n{\n    /** Object name */\n    char\t*obj_name;\n\n    /** Core settings */\n    struct {\n\t/** Pool factory */\n\tpj_pool_factory *pf;\n\n\t/** Pool for this server instance. */\n\tpj_pool_t       *pool;\n\n\t/** Global Ioqueue */\n\tpj_ioqueue_t    *ioqueue;\n\n\t/** Mutex */\n\tpj_lock_t\t*lock;\n\n\t/** Global timer heap instance. */\n\tpj_timer_heap_t *timer_heap;\n\n\t/** Number of listeners */\n\tunsigned         lis_cnt;\n\n\t/** Array of listeners. */\n\tpj_turn_listener **listener;\n\n\t/** STUN session to handle initial Allocate request. */\n\tpj_stun_session\t*stun_sess;\n\n\t/** Number of worker threads. */\n\tunsigned        thread_cnt;\n\n\t/** Array of worker threads. */\n\tpj_thread_t     **thread;\n\n\t/** Thread quit signal */\n\tpj_bool_t\tquit;\n\n\t/** STUN config. */\n\tpj_stun_config\t stun_cfg;\n\n\t/** STUN auth credential. */\n\tpj_stun_auth_cred cred;\n\n\t/** Thread local ID for storing credential */\n\tlong\t\t tls_key, tls_data;\n\n    } core;\n\n    \n    /** Hash tables */\n    struct {\n\t/** Allocations hash table, indexed by transport type and\n\t *  client address. \n\t */\n\tpj_hash_table_t *alloc;\n\n\t/** Relay resource hash table, indexed by transport type and\n\t *  relay address. \n\t */\n\tpj_hash_table_t *res;\n\n    } tables;\n\n    /** Ports settings */\n    struct {\n\t/** Minimum UDP port number. */\n\tpj_uint16_t\t    min_udp;\n\n\t/** Maximum UDP port number. */\n\tpj_uint16_t\t    max_udp;\n\n\t/** Next UDP port number. */\n\tpj_uint16_t\t    next_udp;\n\n\n\t/** Minimum TCP port number. */\n\tpj_uint16_t\t    min_tcp;\n\n\t/** Maximum TCP port number. */\n\tpj_uint16_t\t    max_tcp;\n\n\t/** Next TCP port number. */\n\tpj_uint16_t\t    next_tcp;\n\n    } ports;\n};\n\n\n/** \n * Create server.\n */\nPJ_DECL(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf,\n\t\t\t\t        pj_turn_srv **p_srv);\n\n/** \n * Destroy server.\n */\nPJ_DECL(pj_status_t) pj_turn_srv_destroy(pj_turn_srv *srv);\n\n/** \n * Add listener.\n */\nPJ_DECL(pj_status_t) pj_turn_srv_add_listener(pj_turn_srv *srv,\n\t\t\t\t\t      pj_turn_listener *lis);\n\n/**\n * Register an allocation.\n */\nPJ_DECL(pj_status_t) pj_turn_srv_register_allocation(pj_turn_srv *srv,\n\t\t\t\t\t\t     pj_turn_allocation *alloc);\n\n/**\n * Unregister an allocation.\n */\nPJ_DECL(pj_status_t) pj_turn_srv_unregister_allocation(pj_turn_srv *srv,\n\t\t\t\t\t\t       pj_turn_allocation *alloc);\n\n/**\n * This callback is called by UDP listener on incoming packet.\n */\nPJ_DECL(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv, \n\t\t\t\t    pj_turn_pkt *pkt);\n\n\n#endif\t/* __PJ_TURN_SRV_TURN_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/build/Makefile",
    "content": "# For common OSes, test's main() is defined in main.c.\n# OS specific configuration may want to put it in different file.\n# For example, see os-rtems.mak in current directory.\nexport TEST_OBJS = main.o\n\ninclude ../../build.mak\ninclude ../../version.mak\ninclude $(PJDIR)/build/common.mak\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\nPJLIB_LIB:=../../pjlib/lib/libpj-$(TARGET_NAME)$(LIBEXT)\nPJLIB_UTIL_LIB:=../../pjlib-util/lib/libpjlib-util-$(TARGET_NAME)$(LIBEXT)\nPJMEDIA_LIB:=../../pjmedia/lib/libpjmedia-$(TARGET_NAME)$(LIBEXT)\nPJMEDIA_CODEC_LIB:=../../pjmedia/lib/libpjmedia-codec-$(TARGET_NAME)$(LIBEXT)\n\nexport PJSIP_LIB:=../lib/libpjsip-$(TARGET_NAME)$(LIBEXT)\nexport PJSIP_UA_LIB:=../lib/libpjsip-ua-$(TARGET_NAME)$(LIBEXT)\nexport PJSIP_SIMPLE_LIB:=../lib/libpjsip-simple-$(TARGET_NAME)$(LIBEXT)\n\n\n###############################################################################\n# Gather all flags.\n#\nexport _CFLAGS \t:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t\t   $(CFLAGS) $(CC_INC)../include \\\n\t\t   $(CC_INC)../../pjlib/include \\\n\t\t   $(CC_INC)../../pjlib-util/include \\\n\t\t   $(CC_INC)../../pjnath/include \\\n\t\t   $(CC_INC)../../pjmedia/include\nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\n\n###############################################################################\n# Defines for building PJSIP core library\n#\nexport PJSIP_SRCDIR = ../src/pjsip\nexport PJSIP_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \\\n\t\tsip_config.o sip_multipart.o \\\n\t\tsip_errno.o sip_msg.o sip_parser.o sip_tel_uri.o sip_uri.o \\\n\t\tsip_endpoint.o sip_util.o sip_util_proxy.o \\\n\t\tsip_resolve.o sip_transport.o sip_transport_loop.o \\\n\t\tsip_transport_udp.o sip_transport_tcp.o \\\n\t\tsip_transport_tls.o sip_auth_aka.o sip_auth_client.o \\\n\t\tsip_auth_msg.o sip_auth_parser.o \\\n\t\tsip_auth_server.o \\\n\t\tsip_transaction.o sip_util_statefull.o \\\n\t\tsip_dialog.o sip_ua_layer.o\nexport PJSIP_CFLAGS += $(_CFLAGS)\n\n###############################################################################\n# Defines for building PJSIP UA library\n#\nexport PJSIP_UA_SRCDIR = ../src/pjsip-ua\nexport PJSIP_UA_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \\\n\t\t\tsip_inv.o sip_reg.o sip_replaces.o sip_xfer.o \\\n\t\t\tsip_100rel.o sip_timer.o\nexport PJSIP_UA_CFLAGS += $(_CFLAGS)\n\n\n###############################################################################\n# Defines for building PJSIP SIMPLE library\n#\nexport PJSIP_SIMPLE_SRCDIR = ../src/pjsip-simple\nexport PJSIP_SIMPLE_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \\\n\t\t\terrno.o evsub.o evsub_msg.o iscomposing.o \\\n\t\t\tmwi.o pidf.o presence.o presence_body.o publishc.o \\\n\t\t\trpid.o xpidf.o\nexport PJSIP_SIMPLE_CFLAGS += $(_CFLAGS)\n\n\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT \n\n###############################################################################\n# Defines for building test application\n#\nexport TEST_SRCDIR = ../src/test\nexport TEST_OBJS += dlg_core_test.o dns_test.o msg_err_test.o \\\n\t\t    msg_logger.o msg_test.o multipart_test.o regc_test.o \\\n\t\t    test.o transport_loop_test.o transport_tcp_test.o \\\n\t\t    transport_test.o transport_udp_test.o \\\n\t\t    tsx_basic_test.o tsx_bench.o tsx_uac_test.o \\\n\t\t    tsx_uas_test.o txdata_test.o uri_test.o \\\n\t\t    inv_offer_answer_test.o\nexport TEST_CFLAGS += $(_CFLAGS)\nexport TEST_LDFLAGS += $(PJ_LDFLAGS) $(PJ_LDLIBS) $(LDFLAGS)\nexport TEST_EXE := ../bin/pjsip-test-$(TARGET_NAME)$(HOST_EXE)\n\n\t\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT \n###############################################################################\n# Main entry\n#\n#\nTARGETS := pjsip pjsip-ua pjsip-simple\n\n.PHONY: $(TARGETS)\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && rm -rf docs/$(PJ_VERSION) && doxygen docs/doxygen.cfg\n\t@if [ -n \"$(WWWDIR)\" ] && ! [ -d \"$(WWWDIR)/docs/$(PJ_VERSION)/pjsip/docs/html\" ] ; then \\\n\t\techo \"Creating docs/$(PJ_VERSION)/pjsip/docs/html\" ; \\\n\t\tmkdir -p $(WWWDIR)/docs/$(PJ_VERSION)/pjsip/docs/html ; \\\n\tfi \n\t@if [ -n \"$(WWWDIR)\" ] && [ -d \"$(WWWDIR)/docs/$(PJ_VERSION)/pjsip/docs/html\" ] ; then \\\n\t\techo \"Copying docs/$(PJ_VERSION) to $(WWWDIR)/docs/$(PJ_VERSION)/pjsip/docs/html..\" ; \\\n\t\tcp -v -a ../docs/$(PJ_VERSION)/html/* $(WWWDIR)/docs/$(PJ_VERSION)/pjsip/docs/html/ ; \\\n\tfi\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend pjsip pjsip-ua clean realclean distclean\n\npjsip:\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP app=pjsip $(PJSIP_LIB)\n\npjsip-ua:\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP_UA app=pjsip-ua $(PJSIP_UA_LIB)\n\npjsip-simple:\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP_SIMPLE app=pjsip-simple $(PJSIP_SIMPLE_LIB)\n\npjsip-test: pjsip\n\t$(MAKE) -f $(RULES_MAK) APP=TEST app=pjsip-test $(TEST_EXE)\n\n.PHONY: ../lib/pjsip.ko\n../lib/pjsip.ko:\n\techo Making $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP app=pjsip $@\n\n.PHONY: ../lib/pjsip-ua.ko\n../lib/pjsip-ua.ko:\n\techo Making $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP_UA app=pjsip-ua $@\n\n.PHONY: ../lib/pjsip-simple.ko\n../lib/pjsip-simple.ko:\n\techo Making $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP_SIMPLE app=pjsip-simple $@\n\nclean:\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP app=pjsip $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP_UA app=pjsip-ua $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP_SIMPLE app=pjsip-simple $@\n\t$(MAKE) -f $(RULES_MAK) APP=TEST app=pjsip-test $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP app=pjsip $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP_UA app=pjsip-ua $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP_SIMPLE app=pjsip-simple $@\n\t$(MAKE) -f $(RULES_MAK) APP=TEST app=pjsip-test $@\n\techo '$(TEST_EXE): $(PJMEDIA_LIB) $(PJSIP_SIMPLE_LIB) $(PJSIP_UA_LIB) $(PJSIP_LIB) $(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB)' >> .pjsip-test-$(TARGET_NAME).depend\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjsip-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjsip-ua-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),.pjsip-simple-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP app=pjsip $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP_UA app=pjsip-ua $@\n\t$(MAKE) -f $(RULES_MAK) APP=PJSIP_SIMPLE app=pjsip-simple $@\n\t$(MAKE) -f $(RULES_MAK) APP=TEST app=pjsip-test $@\n\n\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/build/os-auto.mak.in",
    "content": ""
  },
  {
    "path": "deps/pjsip/pjsip/docs/PJSUA-TESTING.txt",
    "content": "TESTING\n\nSANITY CHECKS:\n- Do pjlib-test\n- Do pjsip-test\n\nBASIC FLOW TEST (compaq1.cfg, compaq2.cfg);\n- with other pjsua\n- with EyeBeam\n- Register \n\t- with Route\n\t- without Route\n\t- with TCP\n- Presence (client and server)\n- Call (UAC and UAS)\n\t- hold and being held\n\t- DTMF send/receive\n- IM and typing\n- Call transfer (with and without norefersub)\n- Call Hold\n- Re-Invite\n- DTMF\n- RTCP\n- TCP (if there's UDP route, then Contact will be UDP)\n\n- Repeat basic flow test without Route set (to wheter TCP is correctly specified in the contact etc)\n\n\n- STUN test\t(fwd1.cfg)\n\nCOMPATIBILITY WITH FWD\n- presence (xpidf)\n\n\nMULTIPLE ACCOUNTS (combo.cfg)\n\nDIGEST with qop=auth (sipcenter?)\n\nAUDIO QUALITY\n- call to another pjsua that loops incoming call\n\nTEST THE SAMPLES\n\nLINUX TEST\n\nUPDATE DOCUMENTATION\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/docs/TRANSPORT-PROBLEMS.TXT",
    "content": "Dialog's Contact Address Problems\n\n\nBackground\n\nWhen creating a dialog (UAC or UAS dialog), application needs to specify local address to be put in the Contact header generated by the dialog. This address normally is derived from the transport address created by the application.\n\nThis can be a complicated thing to do, because application needs to select the appropriate address based on the transport being used to contact remote peer, and it's not so easy especially when multiple transports are created, or when multiple interfaces are present in the host (multihoming).\n\n(Note: also similarly for client registration).\n\nSo a change is being/to be made to allow the dialog to automate this process. If application specify NULL as the value of the local contact when creating a dialog, then the dialog should choose the best transport address according to the following rules.\n\n\n1a. UAC\n\nUAC SHOULD select the Contact address based on the transport to be used to send initial request to target (this can be deduced by the \";transport\" param in the target URI).  For example, if initial transport is UDP, then the Contact SHOULD specify the appropriate UDP transport address.\n\nWhen there are multiple transports available to reach the destination (such as multiple UDP transports, although this is not really tested/supported), then which transport to use follows the policy used by the transport manager.\n\nNote that target can be the URI in the request URI, or the first route in the route set. Because initial route set is specified AFTER dialog is created, the Contact header generation is done when the initial request is created/sent.\n\nUnsolved problem(s):\n - what if the remote Contact header in the 2xx response indicates different transport? Ideally the local Contact needs to be updated too, but this is quite a complicated problem, because if we change the local Contact, then remote may change its Contact too, and this can result in an endles loop.\n\n\n1b. UAS\n\nUAS MUST select the Contact address based on the value of Contact header and the Record-Route set in the incoming request.\n\n\n\n\n2. Multihoming\n\nProblem:\nIf application does not specify the address to be used when creating SIP transport, then transport address is calculated based on the primary IP address of the local host. Sometimes this is not the correct IP to be used by the dialog, especially when there are multiple interfaces in the host. If this \"incorrect\" address is specified in the Contact, then remote would not be able to send request to local host.\n\n\nWorkaround:\nChange the behavior of determining local IP. Instead of calling gethostbyname() for local host, the local interface IP is determined by creating an UDP socket, do UDP connect() to some public host, and get the local IP address of the socket.\n\nAlthough this does not fully solve the problem, hopefully it solves many problems in typical desktop systems, where an \"unwanted\" adapter takes precendence over the \"wanted\" adapter on the host/address resolution.\n\nA fully working solution would probably involve having a table to track which interface to use based on the destination, or to query the host's routing table.\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/docs/doxygen.cfg",
    "content": "# Doxyfile 1.3-rc3\r\n\r\n# This file describes the settings to be used by the documentation system\r\n# doxygen (www.doxygen.org) for a project\r\n#\r\n# All text after a hash (#) is considered a comment and will be ignored\r\n# The format is:\r\n#       TAG = value [value, ...]\r\n# For lists items can also be appended using:\r\n#       TAG += value [value, ...]\r\n# Values that contain spaces should be placed between quotes (\" \")\r\n\r\n#---------------------------------------------------------------------------\r\n# General configuration options\r\n#---------------------------------------------------------------------------\r\n\r\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded \r\n# by quotes) that should identify the project.\r\n\r\nPROJECT_NAME           =  \"PJSIP Reference\"\r\n\r\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. \r\n# This could be handy for archiving the generated documentation or \r\n# if some version control system is used.\r\n\r\nPROJECT_NUMBER         = $(PJ_VERSION)\r\n\r\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) \r\n# base path where the generated documentation will be put. \r\n# If a relative path is entered, it will be relative to the location \r\n# where doxygen was started. If left blank the current directory will be used.\r\n\r\nOUTPUT_DIRECTORY       = docs/$(PJ_VERSION)\r\n\r\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all \r\n# documentation generated by doxygen is written. Doxygen will use this \r\n# information to generate all constant output in the proper language. \r\n# The default language is English, other supported languages are: \r\n# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, \r\n# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en \r\n# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, \r\n# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian.\r\n\r\nOUTPUT_LANGUAGE        = English\r\n\r\n# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in \r\n# documentation are documented, even if no documentation was available. \r\n# Private class members and static file members will be hidden unless \r\n# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES\r\n\r\nEXTRACT_ALL            = NO\r\n\r\n# If the EXTRACT_PRIVATE tag is set to YES all private members of a class \r\n# will be included in the documentation.\r\n\r\nEXTRACT_PRIVATE        = NO\r\n\r\n# If the EXTRACT_STATIC tag is set to YES all static members of a file \r\n# will be included in the documentation.\r\n\r\nEXTRACT_STATIC         = NO\r\n\r\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) \r\n# defined locally in source files will be included in the documentation. \r\n# If set to NO only classes defined in header files are included.\r\n\r\nEXTRACT_LOCAL_CLASSES  = YES\r\n\r\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all \r\n# undocumented members of documented classes, files or namespaces. \r\n# If set to NO (the default) these members will be included in the \r\n# various overviews, but no documentation section is generated. \r\n# This option has no effect if EXTRACT_ALL is enabled.\r\n\r\nHIDE_UNDOC_MEMBERS     = NO\r\n\r\n# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all \r\n# undocumented classes that are normally visible in the class hierarchy. \r\n# If set to NO (the default) these class will be included in the various \r\n# overviews. This option has no effect if EXTRACT_ALL is enabled.\r\n\r\nHIDE_UNDOC_CLASSES     = YES\r\n\r\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all \r\n# friend (class|struct|union) declarations. \r\n# If set to NO (the default) these declarations will be included in the \r\n# documentation.\r\n\r\nHIDE_FRIEND_COMPOUNDS  = NO\r\n\r\n# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any \r\n# documentation blocks found inside the body of a function. \r\n# If set to NO (the default) these blocks will be appended to the \r\n# function's detailed documentation block.\r\n\r\nHIDE_IN_BODY_DOCS      = NO\r\n\r\n# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will \r\n# include brief member descriptions after the members that are listed in \r\n# the file and class documentation (similar to JavaDoc). \r\n# Set to NO to disable this.\r\n\r\nBRIEF_MEMBER_DESC      = YES\r\n\r\n# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend \r\n# the brief description of a member or function before the detailed description. \r\n# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the \r\n# brief descriptions will be completely suppressed.\r\n\r\nREPEAT_BRIEF           = NO\r\n\r\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then \r\n# Doxygen will generate a detailed section even if there is only a brief \r\n# description.\r\n\r\nALWAYS_DETAILED_SEC    = YES\r\n\r\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited \r\n# members of a class in the documentation of that class as if those members were \r\n# ordinary class members. Constructors, destructors and assignment operators of \r\n# the base classes will not be shown.\r\n\r\nINLINE_INHERITED_MEMB  = NO\r\n\r\n# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full \r\n# path before files name in the file list and in the header files. If set \r\n# to NO the shortest path that makes the file name unique will be used.\r\n\r\nFULL_PATH_NAMES        = NO\r\n\r\n# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag \r\n# can be used to strip a user defined part of the path. Stripping is \r\n# only done if one of the specified strings matches the left-hand part of \r\n# the path. It is allowed to use relative paths in the argument list.\r\n\r\n#STRIP_FROM_PATH        = \"/cygdrive/e/project/bulukucing.org/pjsip/src\"\r\nSTRIP_FROM_PATH        = \"/c/project/pjproject/pjsip\"\r\n\r\n# The INTERNAL_DOCS tag determines if documentation \r\n# that is typed after a \\internal command is included. If the tag is set \r\n# to NO (the default) then the documentation will be excluded. \r\n# Set it to YES to include the internal documentation.\r\n\r\nINTERNAL_DOCS          = NO\r\n\r\n# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate \r\n# file names in lower case letters. If set to YES upper case letters are also \r\n# allowed. This is useful if you have classes or files whose names only differ \r\n# in case and if your file system supports case sensitive file names. Windows \r\n# users are adviced to set this option to NO.\r\n\r\nCASE_SENSE_NAMES       = YES\r\n\r\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter \r\n# (but less readable) file names. This can be useful is your file systems \r\n# doesn't support long names like on DOS, Mac, or CD-ROM.\r\n\r\nSHORT_NAMES            = NO\r\n\r\n# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen \r\n# will show members with their full class and namespace scopes in the \r\n# documentation. If set to YES the scope will be hidden.\r\n\r\nHIDE_SCOPE_NAMES       = NO\r\n\r\n# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen \r\n# will generate a verbatim copy of the header file for each class for \r\n# which an include is specified. Set to NO to disable this.\r\n\r\nVERBATIM_HEADERS       = NO\r\n\r\n# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen \r\n# will put list of the files that are included by a file in the documentation \r\n# of that file.\r\n\r\nSHOW_INCLUDE_FILES     = YES\r\n\r\n# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen \r\n# will interpret the first line (until the first dot) of a JavaDoc-style \r\n# comment as the brief description. If set to NO, the JavaDoc \r\n# comments  will behave just like the Qt-style comments (thus requiring an \r\n# explict @brief command for a brief description.\r\n\r\nJAVADOC_AUTOBRIEF      = NO\r\n\r\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen \r\n# treat a multi-line C++ special comment block (i.e. a block of //! or /// \r\n# comments) as a brief description. This used to be the default behaviour. \r\n# The new default is to treat a multi-line C++ comment block as a detailed \r\n# description. Set this tag to YES if you prefer the old behaviour instead.\r\n\r\nMULTILINE_CPP_IS_BRIEF = NO\r\n\r\n# If the DETAILS_AT_TOP tag is set to YES then Doxygen \r\n# will output the detailed description near the top, like JavaDoc.\r\n# If set to NO, the detailed description appears after the member \r\n# documentation.\r\n\r\nDETAILS_AT_TOP         = YES\r\n\r\n# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented \r\n# member inherits the documentation from any documented member that it \r\n# reimplements.\r\n\r\nINHERIT_DOCS           = YES\r\n\r\n# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] \r\n# is inserted in the documentation for inline members.\r\n\r\nINLINE_INFO            = YES\r\n\r\n# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen \r\n# will sort the (detailed) documentation of file and class members \r\n# alphabetically by member name. If set to NO the members will appear in \r\n# declaration order.\r\n\r\nSORT_MEMBER_DOCS       = NO\r\n\r\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC \r\n# tag is set to YES, then doxygen will reuse the documentation of the first \r\n# member in the group (if any) for the other members of the group. By default \r\n# all members of a group must be documented explicitly.\r\n\r\nDISTRIBUTE_GROUP_DOC   = NO\r\n\r\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. \r\n# Doxygen uses this value to replace tabs by spaces in code fragments.\r\n\r\nTAB_SIZE               = 8\r\n\r\n# The GENERATE_TODOLIST tag can be used to enable (YES) or \r\n# disable (NO) the todo list. This list is created by putting \\todo \r\n# commands in the documentation.\r\n\r\nGENERATE_TODOLIST      = YES\r\n\r\n# The GENERATE_TESTLIST tag can be used to enable (YES) or \r\n# disable (NO) the test list. This list is created by putting \\test \r\n# commands in the documentation.\r\n\r\nGENERATE_TESTLIST      = YES\r\n\r\n# The GENERATE_BUGLIST tag can be used to enable (YES) or \r\n# disable (NO) the bug list. This list is created by putting \\bug \r\n# commands in the documentation.\r\n\r\nGENERATE_BUGLIST       = YES\r\n\r\n# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or \r\n# disable (NO) the deprecated list. This list is created by putting \r\n# \\deprecated commands in the documentation.\r\n\r\nGENERATE_DEPRECATEDLIST= YES\r\n\r\n# This tag can be used to specify a number of aliases that acts \r\n# as commands in the documentation. An alias has the form \"name=value\". \r\n# For example adding \"sideeffect=\\par Side Effects:\\n\" will allow you to \r\n# put the command \\sideeffect (or @sideeffect) in the documentation, which \r\n# will result in a user defined paragraph with heading \"Side Effects:\". \r\n# You can put \\n's in the value part of an alias to insert newlines.\r\n\r\nALIASES                = \r\n\r\n# The ENABLED_SECTIONS tag can be used to enable conditional \r\n# documentation sections, marked by \\if sectionname ... \\endif.\r\n\r\nENABLED_SECTIONS       = \r\n\r\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines \r\n# the initial value of a variable or define consist of for it to appear in \r\n# the documentation. If the initializer consists of more lines than specified \r\n# here it will be hidden. Use a value of 0 to hide initializers completely. \r\n# The appearance of the initializer of individual variables and defines in the \r\n# documentation can be controlled using \\showinitializer or \\hideinitializer \r\n# command in the documentation regardless of this setting.\r\n\r\nMAX_INITIALIZER_LINES  = 30\r\n\r\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources \r\n# only. Doxygen will then generate output that is more tailored for C. \r\n# For instance some of the names that are used will be different. The list \r\n# of all members will be omitted, etc.\r\n\r\nOPTIMIZE_OUTPUT_FOR_C  = YES\r\n\r\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources \r\n# only. Doxygen will then generate output that is more tailored for Java. \r\n# For instance namespaces will be presented as packages, qualified scopes \r\n# will look different, etc.\r\n\r\nOPTIMIZE_OUTPUT_JAVA   = NO\r\n\r\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated \r\n# at the bottom of the documentation of classes and structs. If set to YES the \r\n# list will mention the files that were used to generate the documentation.\r\n\r\nSHOW_USED_FILES        = YES\r\nTYPEDEF_HIDES_STRUCT\t= YES\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to warning and progress messages\r\n#---------------------------------------------------------------------------\r\n\r\n# The QUIET tag can be used to turn on/off the messages that are generated \r\n# by doxygen. Possible values are YES and NO. If left blank NO is used.\r\n\r\nQUIET                  = NO\r\n\r\n# The WARNINGS tag can be used to turn on/off the warning messages that are \r\n# generated by doxygen. Possible values are YES and NO. If left blank \r\n# NO is used.\r\n\r\nWARNINGS               = YES\r\n\r\n# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings \r\n# for undocumented members. If EXTRACT_ALL is set to YES then this flag will \r\n# automatically be disabled.\r\n\r\nWARN_IF_UNDOCUMENTED   = YES\r\n\r\n# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for \r\n# potential errors in the documentation, such as not documenting some \r\n# parameters in a documented function, or documenting parameters that \r\n# don't exist or using markup commands wrongly.\r\n\r\nWARN_IF_DOC_ERROR      = YES\r\n\r\n# The WARN_FORMAT tag determines the format of the warning messages that \r\n# doxygen can produce. The string should contain the $file, $line, and $text \r\n# tags, which will be replaced by the file and line number from which the \r\n# warning originated and the warning text.\r\n\r\nWARN_FORMAT            = \"$file:$line: $text\"\r\n\r\n# The WARN_LOGFILE tag can be used to specify a file to which warning \r\n# and error messages should be written. If left blank the output is written \r\n# to stderr.\r\n\r\nWARN_LOGFILE           = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the input files\r\n#---------------------------------------------------------------------------\r\n\r\n# The INPUT tag can be used to specify the files and/or directories that contain \r\n# documented source files. You may enter file names like \"myfile.cpp\" or \r\n# directories like \"/usr/src/myproject\". Separate the files or directories \r\n# with spaces.\r\n\r\nINPUT                  =  docs include \r\n\r\n# If the value of the INPUT tag contains directories, you can use the \r\n# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \r\n# and *.h) to filter out the source-files in the directories. If left \r\n# blank the following patterns are tested: \r\n# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp \r\n# *.h++ *.idl *.odl\r\n\r\nFILE_PATTERNS          = *.h *.hpp\r\n\r\n# The RECURSIVE tag can be used to turn specify whether or not subdirectories \r\n# should be searched for input files as well. Possible values are YES and NO. \r\n# If left blank NO is used.\r\n\r\nRECURSIVE              = YES\r\n\r\n# The EXCLUDE tag can be used to specify files and/or directories that should \r\n# excluded from the INPUT source files. This way you can easily exclude a \r\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\r\n\r\nEXCLUDE                = *_i.h pjsua_internal.h\r\n\r\n# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories \r\n# that are symbolic links (a Unix filesystem feature) are excluded from the input.\r\n\r\nEXCLUDE_SYMLINKS       = NO\r\n\r\n# If the value of the INPUT tag contains directories, you can use the \r\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude \r\n# certain files from those directories.\r\n\r\nEXCLUDE_PATTERNS       = \r\n\r\n# The EXAMPLE_PATH tag can be used to specify one or more files or \r\n# directories that contain example code fragments that are included (see \r\n# the \\include command).\r\n\r\nEXAMPLE_PATH           = ../pjsip-apps/src/samples ../pjsip-apps/src/pjsua\r\n\r\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the \r\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \r\n# and *.h) to filter out the source-files in the directories. If left \r\n# blank all files are included.\r\n\r\nEXAMPLE_PATTERNS       = \r\n\r\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be \r\n# searched for input files to be used with the \\include or \\dontinclude \r\n# commands irrespective of the value of the RECURSIVE tag. \r\n# Possible values are YES and NO. If left blank NO is used.\r\n\r\nEXAMPLE_RECURSIVE      = NO\r\n\r\n# The IMAGE_PATH tag can be used to specify one or more files or \r\n# directories that contain image that are included in the documentation (see \r\n# the \\image command).\r\n\r\nIMAGE_PATH             = docs ../pjmedia/docs\r\n\r\n# The INPUT_FILTER tag can be used to specify a program that doxygen should \r\n# invoke to filter for each input file. Doxygen will invoke the filter program \r\n# by executing (via popen()) the command <filter> <input-file>, where <filter> \r\n# is the value of the INPUT_FILTER tag, and <input-file> is the name of an \r\n# input file. Doxygen will then use the output that the filter program writes \r\n# to standard output.\r\n\r\nINPUT_FILTER           = \r\n\r\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using \r\n# INPUT_FILTER) will be used to filter the input files when producing source \r\n# files to browse (i.e. when SOURCE_BROWSER is set to YES).\r\n\r\nFILTER_SOURCE_FILES    = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to source browsing\r\n#---------------------------------------------------------------------------\r\n\r\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will \r\n# be generated. Documented entities will be cross-referenced with these sources.\r\n\r\nSOURCE_BROWSER         = NO\r\n\r\n# Setting the INLINE_SOURCES tag to YES will include the body \r\n# of functions and classes directly in the documentation.\r\n\r\nINLINE_SOURCES         = NO\r\n\r\n# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct \r\n# doxygen to hide any special comment blocks from generated source code \r\n# fragments. Normal C and C++ comments will always remain visible.\r\n\r\nSTRIP_CODE_COMMENTS    = YES\r\n\r\n# If the REFERENCED_BY_RELATION tag is set to YES (the default) \r\n# then for each documented function all documented \r\n# functions referencing it will be listed.\r\n\r\nREFERENCED_BY_RELATION = YES\r\n\r\n# If the REFERENCES_RELATION tag is set to YES (the default) \r\n# then for each documented function all documented entities \r\n# called/used by that function will be listed.\r\n\r\nREFERENCES_RELATION    = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the alphabetical class index\r\n#---------------------------------------------------------------------------\r\n\r\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index \r\n# of all compounds will be generated. Enable this if the project \r\n# contains a lot of classes, structs, unions or interfaces.\r\n\r\nALPHABETICAL_INDEX     = NO\r\n\r\n# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then \r\n# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns \r\n# in which this list will be split (can be a number in the range [1..20])\r\n\r\nCOLS_IN_ALPHA_INDEX    = 5\r\n\r\n# In case all classes in a project start with a common prefix, all \r\n# classes will be put under the same header in the alphabetical index. \r\n# The IGNORE_PREFIX tag can be used to specify one or more prefixes that \r\n# should be ignored while generating the index headers.\r\n\r\nIGNORE_PREFIX          =  /c/project/pjproject/pjsip\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the HTML output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_HTML tag is set to YES (the default) Doxygen will \r\n# generate HTML output.\r\n\r\nGENERATE_HTML          = YES\r\n\r\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `html' will be used as the default path.\r\n\r\nHTML_OUTPUT            = html\r\n\r\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for \r\n# each generated HTML page (for example: .htm,.php,.asp). If it is left blank \r\n# doxygen will generate files with .html extension.\r\n\r\nHTML_FILE_EXTENSION    = .htm\r\n\r\n# The HTML_HEADER tag can be used to specify a personal HTML header for \r\n# each generated HTML page. If it is left blank doxygen will generate a \r\n# standard header.\r\n\r\nHTML_HEADER            =  docs/header.html\r\n\r\n# The HTML_FOOTER tag can be used to specify a personal HTML footer for \r\n# each generated HTML page. If it is left blank doxygen will generate a \r\n# standard footer.\r\n\r\nHTML_FOOTER            =  docs/footer.html\r\n\r\n# The HTML_STYLESHEET tag can be used to specify a user defined cascading \r\n# style sheet that is used by each HTML page. It can be used to \r\n# fine-tune the look of the HTML output. If the tag is left blank doxygen \r\n# will generate a default style sheet\r\n\r\nHTML_STYLESHEET        = \r\n\r\n# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, \r\n# files or namespaces will be aligned in HTML using tables. If set to \r\n# NO a bullet list will be used.\r\n\r\nHTML_ALIGN_MEMBERS     = YES\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, additional index files \r\n# will be generated that can be used as input for tools like the \r\n# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) \r\n# of the generated HTML documentation.\r\n\r\nGENERATE_HTMLHELP      = NO\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can \r\n# be used to specify the file name of the resulting .chm file. You \r\n# can add a path in front of the file if the result should not be \r\n# written to the html output dir.\r\n\r\nCHM_FILE               = \r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can \r\n# be used to specify the location (absolute path including file name) of \r\n# the HTML help compiler (hhc.exe). If non empty doxygen will try to run \r\n# the html help compiler on the generated index.hhp.\r\n\r\nHHC_LOCATION           = \r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag \r\n# controls if a separate .chi index file is generated (YES) or that \r\n# it should be included in the master .chm file (NO).\r\n\r\nGENERATE_CHI           = NO\r\n\r\n# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag \r\n# controls whether a binary table of contents is generated (YES) or a \r\n# normal table of contents (NO) in the .chm file.\r\n\r\nBINARY_TOC             = NO\r\n\r\n# The TOC_EXPAND flag can be set to YES to add extra items for group members \r\n# to the contents of the Html help documentation and to the tree view.\r\n\r\nTOC_EXPAND             = NO\r\n\r\n# The DISABLE_INDEX tag can be used to turn on/off the condensed index at \r\n# top of each HTML page. The value NO (the default) enables the index and \r\n# the value YES disables it.\r\n\r\nDISABLE_INDEX          = NO\r\n\r\n# This tag can be used to set the number of enum values (range [1..20]) \r\n# that doxygen will group on one line in the generated HTML documentation.\r\n\r\nENUM_VALUES_PER_LINE   = 4\r\n\r\n# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be\r\n# generated containing a tree-like index structure (just like the one that \r\n# is generated for HTML Help). For this to work a browser that supports \r\n# JavaScript, DHTML, CSS and frames is required (for instance Mozilla, \r\n# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are \r\n# probably better off using the HTML help feature.\r\n\r\nGENERATE_TREEVIEW      = NO\r\n\r\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be \r\n# used to set the initial width (in pixels) of the frame in which the tree \r\n# is shown.\r\n\r\nTREEVIEW_WIDTH         = 250\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the LaTeX output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will \r\n# generate Latex output.\r\n\r\nGENERATE_LATEX         = NO\r\n\r\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `latex' will be used as the default path.\r\n\r\nLATEX_OUTPUT           = latex\r\n\r\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be \r\n# invoked. If left blank `latex' will be used as the default command name.\r\n\r\nLATEX_CMD_NAME         = latex\r\n\r\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to \r\n# generate index for LaTeX. If left blank `makeindex' will be used as the \r\n# default command name.\r\n\r\nMAKEINDEX_CMD_NAME     = makeindex\r\n\r\n# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact \r\n# LaTeX documents. This may be useful for small projects and may help to \r\n# save some trees in general.\r\n\r\nCOMPACT_LATEX          = NO\r\n\r\n# The PAPER_TYPE tag can be used to set the paper type that is used \r\n# by the printer. Possible values are: a4, a4wide, letter, legal and \r\n# executive. If left blank a4wide will be used.\r\n\r\nPAPER_TYPE             = a4wide\r\n\r\n# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX \r\n# packages that should be included in the LaTeX output.\r\n\r\nEXTRA_PACKAGES         = \r\n\r\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for \r\n# the generated latex document. The header should contain everything until \r\n# the first chapter. If it is left blank doxygen will generate a \r\n# standard header. Notice: only use this tag if you know what you are doing!\r\n\r\nLATEX_HEADER           = \r\n\r\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated \r\n# is prepared for conversion to pdf (using ps2pdf). The pdf file will \r\n# contain links (just like the HTML output) instead of page references \r\n# This makes the output suitable for online browsing using a pdf viewer.\r\n\r\nPDF_HYPERLINKS         = NO\r\n\r\n# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of \r\n# plain latex in the generated Makefile. Set this option to YES to get a \r\n# higher quality PDF documentation.\r\n\r\nUSE_PDFLATEX           = NO\r\n\r\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\\\batchmode. \r\n# command to the generated LaTeX files. This will instruct LaTeX to keep \r\n# running if errors occur, instead of asking the user for help. \r\n# This option is also used when generating formulas in HTML.\r\n\r\nLATEX_BATCHMODE        = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the RTF output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output \r\n# The RTF output is optimised for Word 97 and may not look very pretty with \r\n# other RTF readers or editors.\r\n\r\nGENERATE_RTF           = NO\r\n\r\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `rtf' will be used as the default path.\r\n\r\nRTF_OUTPUT             = rtf\r\n\r\n# If the COMPACT_RTF tag is set to YES Doxygen generates more compact \r\n# RTF documents. This may be useful for small projects and may help to \r\n# save some trees in general.\r\n\r\nCOMPACT_RTF            = NO\r\n\r\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated \r\n# will contain hyperlink fields. The RTF file will \r\n# contain links (just like the HTML output) instead of page references. \r\n# This makes the output suitable for online browsing using WORD or other \r\n# programs which support those fields. \r\n# Note: wordpad (write) and others do not support links.\r\n\r\nRTF_HYPERLINKS         = NO\r\n\r\n# Load stylesheet definitions from file. Syntax is similar to doxygen's \r\n# config file, i.e. a series of assigments. You only have to provide \r\n# replacements, missing definitions are set to their default value.\r\n\r\nRTF_STYLESHEET_FILE    = \r\n\r\n# Set optional variables used in the generation of an rtf document. \r\n# Syntax is similar to doxygen's config file.\r\n\r\nRTF_EXTENSIONS_FILE    = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the man page output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_MAN tag is set to YES (the default) Doxygen will \r\n# generate man pages\r\n\r\nGENERATE_MAN           = NO\r\n\r\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. \r\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \r\n# put in front of it. If left blank `man' will be used as the default path.\r\n\r\nMAN_OUTPUT             = man\r\n\r\n# The MAN_EXTENSION tag determines the extension that is added to \r\n# the generated man pages (default is the subroutine's section .3)\r\n\r\nMAN_EXTENSION          = .3\r\n\r\n# If the MAN_LINKS tag is set to YES and Doxygen generates man output, \r\n# then it will generate one additional man file for each entity \r\n# documented in the real man page(s). These additional files \r\n# only source the real man page, but without them the man command \r\n# would be unable to find the correct page. The default is NO.\r\n\r\nMAN_LINKS              = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the XML output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_XML tag is set to YES Doxygen will \r\n# generate an XML file that captures the structure of \r\n# the code including all documentation. Note that this \r\n# feature is still experimental and incomplete at the \r\n# moment.\r\n\r\nGENERATE_XML           = NO\r\n\r\n# The XML_SCHEMA tag can be used to specify an XML schema, \r\n# which can be used by a validating XML parser to check the \r\n# syntax of the XML files.\r\n\r\nXML_SCHEMA             = \r\n\r\n# The XML_DTD tag can be used to specify an XML DTD, \r\n# which can be used by a validating XML parser to check the \r\n# syntax of the XML files.\r\n\r\nXML_DTD                = \r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options for the AutoGen Definitions output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will \r\n# generate an AutoGen Definitions (see autogen.sf.net) file \r\n# that captures the structure of the code including all \r\n# documentation. Note that this feature is still experimental \r\n# and incomplete at the moment.\r\n\r\nGENERATE_AUTOGEN_DEF   = NO\r\n\r\n#---------------------------------------------------------------------------\r\n# configuration options related to the Perl module output\r\n#---------------------------------------------------------------------------\r\n\r\n# If the GENERATE_PERLMOD tag is set to YES Doxygen will \r\n# generate a Perl module file that captures the structure of \r\n# the code including all documentation. Note that this \r\n# feature is still experimental and incomplete at the \r\n# moment.\r\n\r\nGENERATE_PERLMOD       = NO\r\n\r\n# If the PERLMOD_LATEX tag is set to YES Doxygen will generate \r\n# the necessary Makefile rules, Perl scripts and LaTeX code to be able \r\n# to generate PDF and DVI output from the Perl module output.\r\n\r\nPERLMOD_LATEX          = NO\r\n\r\n# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be \r\n# nicely formatted so it can be parsed by a human reader.  This is useful \r\n# if you want to understand what is going on.  On the other hand, if this \r\n# tag is set to NO the size of the Perl module output will be much smaller \r\n# and Perl will parse it just the same.\r\n\r\nPERLMOD_PRETTY         = YES\r\n\r\n# The names of the make variables in the generated doxyrules.make file \r\n# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. \r\n# This is useful so different doxyrules.make files included by the same \r\n# Makefile don't overwrite each other's variables.\r\n\r\nPERLMOD_MAKEVAR_PREFIX = \r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration options related to the preprocessor   \r\n#---------------------------------------------------------------------------\r\n\r\n# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will \r\n# evaluate all C-preprocessor directives found in the sources and include \r\n# files.\r\n\r\nENABLE_PREPROCESSING   = YES\r\n\r\n# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro \r\n# names in the source code. If set to NO (the default) only conditional \r\n# compilation will be performed. Macro expansion can be done in a controlled \r\n# way by setting EXPAND_ONLY_PREDEF to YES.\r\n\r\nMACRO_EXPANSION        = YES\r\n\r\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES \r\n# then the macro expansion is limited to the macros specified with the \r\n# PREDEFINED and EXPAND_AS_PREDEFINED tags.\r\n\r\nEXPAND_ONLY_PREDEF     = NO\r\n\r\n# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files \r\n# in the INCLUDE_PATH (see below) will be search if a #include is found.\r\n\r\nSEARCH_INCLUDES        = YES\r\n\r\n# The INCLUDE_PATH tag can be used to specify one or more directories that \r\n# contain include files that are not input files but should be processed by \r\n# the preprocessor.\r\n\r\nINCLUDE_PATH           = \r\n\r\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard \r\n# patterns (like *.h and *.hpp) to filter out the header-files in the \r\n# directories. If left blank, the patterns specified with FILE_PATTERNS will \r\n# be used.\r\n\r\nINCLUDE_FILE_PATTERNS  = \r\n\r\n# The PREDEFINED tag can be used to specify one or more macro names that \r\n# are defined before the preprocessor is started (similar to the -D option of \r\n# gcc). The argument of the tag is a list of macros of the form: name \r\n# or name=definition (no spaces). If the definition and the = are \r\n# omitted =1 is assumed.\r\n\r\n\r\nPREDEFINED             = PJ_DECL(x)=x PJ_DEF(x)=x PJ_IDECL(x)=x \\\r\n\t\t\t PJ_IDEF(x)=x PJ_INLINE(x)=x PJ_DECL_DATA(x)=x \\\r\n\t\t\t PJMEDIA_HAS_SRTP=1 \\\r\n\t\t\t PJMEDIA_STREAM_ENABLE_KA=1\r\n\r\n\r\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then \r\n# this tag can be used to specify a list of macro names that should be expanded. \r\n# The macro definition that is found in the sources will be used. \r\n# Use the PREDEFINED tag if you want to use a different macro definition.\r\n\r\nEXPAND_AS_DEFINED      = \r\n\r\n# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then \r\n# doxygen's preprocessor will remove all function-like macros that are alone \r\n# on a line, have an all uppercase name, and do not end with a semicolon. Such \r\n# function macros are typically used for boiler-plate code, and will confuse the \r\n# parser if not removed.\r\n\r\nSKIP_FUNCTION_MACROS   = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration::addtions related to external references   \r\n#---------------------------------------------------------------------------\r\n\r\n# The TAGFILES tag can be used to specify one or more tagfiles.\r\n\r\nTAGFILES               = ../pjlib/docs/pjlib.tag=../../../pjlib/docs/html ../pjlib-util/docs/pjlib-util.tag=../../../pjlib-util/docs/html ../pjnath/docs/pjnath.tag=../../../pjnath/docs/html ../pjmedia/docs/pjmedia.tag=../../../pjmedia/docs/html\r\n\r\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create \r\n# a tag file that is based on the input files it reads.\r\n\r\nGENERATE_TAGFILE       = docs/pjsip.tag\r\n\r\n# If the ALLEXTERNALS tag is set to YES all external classes will be listed \r\n# in the class index. If set to NO only the inherited external classes \r\n# will be listed.\r\n\r\nALLEXTERNALS           = NO\r\n\r\n# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed \r\n# in the modules index. If set to NO, only the current project's groups will \r\n# be listed.\r\n\r\nEXTERNAL_GROUPS        = NO\r\n\r\n# The PERL_PATH should be the absolute path and name of the perl script \r\n# interpreter (i.e. the result of `which perl').\r\n\r\n#PERL_PATH              = /usr/bin/perl\r\nPERL_PATH              = /c/Perl/bin/perl\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration options related to the dot tool   \r\n#---------------------------------------------------------------------------\r\n\r\n# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will \r\n# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or \r\n# super classes. Setting the tag to NO turns the diagrams off. Note that this \r\n# option is superceded by the HAVE_DOT option below. This is only a fallback. It is \r\n# recommended to install and use dot, since it yield more powerful graphs.\r\n\r\nCLASS_DIAGRAMS         = YES\r\n\r\n# If set to YES, the inheritance and collaboration graphs will hide \r\n# inheritance and usage relations if the target is undocumented \r\n# or is not a class.\r\n\r\nHIDE_UNDOC_RELATIONS   = YES\r\n\r\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is \r\n# available from the path. This tool is part of Graphviz, a graph visualization \r\n# toolkit from AT&T and Lucent Bell Labs. The other options in this section \r\n# have no effect if this option is set to NO (the default)\r\n\r\nHAVE_DOT               = NO\r\n\r\n# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen \r\n# will generate a graph for each documented class showing the direct and \r\n# indirect inheritance relations. Setting this tag to YES will force the \r\n# the CLASS_DIAGRAMS tag to NO.\r\n\r\nCLASS_GRAPH            = YES\r\n\r\n# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen \r\n# will generate a graph for each documented class showing the direct and \r\n# indirect implementation dependencies (inheritance, containment, and \r\n# class references variables) of the class with other documented classes.\r\n\r\nCOLLABORATION_GRAPH    = YES\r\n\r\n# If set to YES, the inheritance and collaboration graphs will show the \r\n# relations between templates and their instances.\r\n\r\nTEMPLATE_RELATIONS     = YES\r\n\r\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT \r\n# tags are set to YES then doxygen will generate a graph for each documented \r\n# file showing the direct and indirect include dependencies of the file with \r\n# other documented files.\r\n\r\nINCLUDE_GRAPH          = YES\r\n\r\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and \r\n# HAVE_DOT tags are set to YES then doxygen will generate a graph for each \r\n# documented header file showing the documented files that directly or \r\n# indirectly include this file.\r\n\r\nINCLUDED_BY_GRAPH      = YES\r\n\r\n# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen \r\n# will graphical hierarchy of all classes instead of a textual one.\r\n\r\nGRAPHICAL_HIERARCHY    = YES\r\n\r\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images \r\n# generated by dot. Possible values are png, jpg, or gif\r\n# If left blank png will be used.\r\n\r\nDOT_IMAGE_FORMAT       = png\r\n\r\n# The tag DOT_PATH can be used to specify the path where the dot tool can be \r\n# found. If left blank, it is assumed the dot tool can be found on the path.\r\n\r\nDOT_PATH               = \r\n\r\n# The DOTFILE_DIRS tag can be used to specify one or more directories that \r\n# contain dot files that are included in the documentation (see the \r\n# \\dotfile command).\r\n\r\nDOTFILE_DIRS           = \r\n\r\n# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width \r\n# (in pixels) of the graphs generated by dot. If a graph becomes larger than \r\n# this value, doxygen will try to truncate the graph, so that it fits within \r\n# the specified constraint. Beware that most browsers cannot cope with very \r\n# large images.\r\n\r\nMAX_DOT_GRAPH_WIDTH    = 1024\r\n\r\n# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height \r\n# (in pixels) of the graphs generated by dot. If a graph becomes larger than \r\n# this value, doxygen will try to truncate the graph, so that it fits within \r\n# the specified constraint. Beware that most browsers cannot cope with very \r\n# large images.\r\n\r\nMAX_DOT_GRAPH_HEIGHT   = 1024\r\n\r\n# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will \r\n# generate a legend page explaining the meaning of the various boxes and \r\n# arrows in the dot generated graphs.\r\n\r\nGENERATE_LEGEND        = YES\r\n\r\n# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will \r\n# remove the intermedate dot files that are used to generate \r\n# the various graphs.\r\n\r\nDOT_CLEANUP            = YES\r\n\r\n#---------------------------------------------------------------------------\r\n# Configuration::addtions related to the search engine   \r\n#---------------------------------------------------------------------------\r\n\r\n# The SEARCHENGINE tag specifies whether or not a search engine should be \r\n# used. If set to NO the values of all tags below this one will be ignored.\r\n\r\nSEARCHENGINE           = NO\r\n\r\n"
  },
  {
    "path": "deps/pjsip/pjsip/docs/doxygen.h",
    "content": "/* $Id$ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/**\n * @file doxygen.h\n * @brief PJSIP Doxygen's mainpage.\n */\n\n/*////////////////////////////////////////////////////////////////////////// */\n/*\n\tINTRODUCTION PAGE\n */\n\n/**\n  \\n\n\n  @mainpage PJSIP - Open Source SIP Stack\n\n  \\n\n  \\n\n  @section intro_sec Introduction\n\n  PJSIP is an Open Source SIP prototol stack, designed to be very small in \n  footprint, have high performance, and very flexible.\n\n  @subsection hist_sec History\n\n  PJSIP has been actively developed since 2003, but its history goes well\n  beyond that. The author has been developing SIP stack since 1999 during\n  RFC 2543 era, and after several experimentation with different approaches \n  in the programming (the first stack actually was in C++!), and also with\n  the evolution of the SIP protocol itself, the current/third generation\n  of PJSIP (the 0.2.9 version is the second generation) can be considered \n  as pretty stable in term of design, and should\n  incorporate all design considerations (and implementation tricks!) that \n  have been learned over the years. Of course only time will tell if this \n  statement can still be held true in the future.\n\n\n\n\n  \\n\n  \\n\n  @section pjsipgetting_started Getting Started\n\n  PJSIP consists of multiple levels of APIs, which each of them layered on\n  top of another. Because of this, new readers may find it a bit difficult\n  to find the place to start.\n\n  In general, I think perhaps I can recommend two approaches on using PJSIP.\n\n\n  \\n\n  @subsection getting_started_high Using PJSUA API\n\n  @ref PJSUA_LIB wraps together all SIP components and media into a high level\n  API, suitable for creating typical SIP user agent applications. It \n  features easy to use API for:\n  - multiple client registration (accounts),\n  - high level SIP and media session (calls),\n  - buddy list, presence and instant messaging,\n  - powerful and very easy to use media manipulation,\n\n  while maintaining some space for customization (custom SIP\n  transport, custom SIP media, etc.) needed by some types of applications.\n  @ref PJSUA_LIB is also aimed to be able to run on devices such as PDA\n  or mobile phones, by carefully allowing application to set the appropriate\n  threading strategy and memory limits (number of calls, media ports, etc.).\n\n  However, @ref PJSUA_LIB may not be the most suitable API for some types\n  of applications, since it is directed towards an easy to use API. For\n  more more advanced use, you may better implement the application by using\n  PJSIP + PJMEDIA directly, as described below.\n\n\n  \\n\n  @subsection getting_started_pjsip_pjmedia Using PJSIP and PJMEDIA Directly\n\n  For the ultimate flexibility and power, using PJSIP and PJMEDIA directly\n  is the way to go. The drawback will be, of course, steeper learning curve. \n\n  However, the following links may provide some useful information:\n  - <A HREF=\"/docs.htm\">PJSIP Developer's Guide</A> PDF\n    document is the ultimate guide to understand PJSIP design concept.\n  - there are some samples in <A HREF=\"/cgi-bin/viewcvs.cgi/pjproject/trunk/pjsip-apps/src/samples/\">\n   <b>pjsip-apps/src/samples</b></A> directory.\n  - @ref PJSUA_LIB source code may also be useful to see how high level\n    API are implemented with PJSIP/PJMEDIA.\n  - and finally, you can always <b>Use the Source</b>!\n\n\n\n  \\n\n  \\n\n  @section this_doc About This Document\n\n  This document contains the reference information about PJSIP. For\n  more in-depth guide (and information in general), readers are \n  encouraged to read the <A HREF=\"/docs.htm\">\n  <b>PJSIP Developer's Guide</b></A> PDF document\n  which can be downloaded from http://www.pjsip.org/docs.htm.\n\n  \\n\n  @subsection doc_how_to_read How to Read This Document\n\n  For main navigation, please go to <A HREF=\"modules.htm\"><b>Modules</b></A>\n  link on top of this page.\n\n  This document was generated with <A HREF=\"http://www.doxygen.org\">Doxygen</A>\n  from PJSIP header files.\n\n\n  \\n\n  \\n\n  @section pjsip_toc Documentation Contents\n\n  Click on <A HREF=\"modules.htm\"><b>Modules</b></A> link on top of this page \n  to get the detailed table of contents.\n\n  The following are top level sections in the <A HREF=\"modules.htm\">\n  <b>Modules</b></A>, as laid out in the following diagram:\n\n  \\image html pjsip-arch.jpg \"Static Library Layout\"\n\n  Enumerating the static libraries from the bottom:\n\n  - <A HREF=\"/pjlib/docs/main.htm\">PJLIB</A>, is the platform abstraction\n    and framework library, on which all other libraries depend,\n\n  - PJLIB-UTIL, provides auxiliary functions such as text scanning,\n    XML, and STUN,\n\n  - PJMEDIA is the multimedia framework,\n\n  - PJMEDIA-CODEC is the placeholder for media codecs,\n\n  - @ref PJSIP_CORE (<b>PJSIP-CORE</b>) is the very core of the PJSIP library, \n    and contains the SIP @ref PJSIP_ENDPT, which is the owner/manager for all\n    SIP objects in the application, messaging elements, parsing, transport \n    management, module management, and stateless operations, and also\n    contains:\n\n  - The @ref PJSIP_TRANSACT module inside <b>PJSIP-CORE</b> provides \n    stateful operation, and is the base for higher layer features such as \n    dialogs,\n\n  - The @ref PJSIP_UA module inside <b>PJSIP-CORE</b> manages dialogs, and supports dialog\n    usages,\n\n  - @ref PJSIP_SIMPLE (<b>PJSIP-SIMPLE</b>) provides the base SIP event framework \n    (which uses the common/base dialog framework) and implements presence \n    on top of it, and is also used by call transfer functions,\n\n  - @ref PJSIP_HIGH_UA (<b>PJSIP-UA</b>) is the high level abstraction of INVITE sessions\n    (using the common/base dialog framework). This library also provides\n    SIP client registration and call transfer functionality,\n\n  - and finally, @ref PJSUA_LIB (<b>PJSUA-LIB</b>) is the highest level of abstraction, \n    which wraps together all above functionalities into high level, easy to\n    use API.\n*/\n\n\n/**\n @page page_pjsip_samples PJSIP Samples\n\n I wish I could write more samples, but for now here are some samples or\n working applications that are available from the source tree:\n\n  - @ref page_pjsip_sample_sipstateless_c\\n\n    This is about the simplest SIP application with PJSIP, all it does is\n    respond all incoming requests with 501 (Not Implemented) response\n    statelessly.\n\n  - @ref page_pjsip_sample_simple_ua_c\\n\n    This is a very simple SIP User Agent application that only use PJSIP\n    (without PJSIP-UA). It's able to make and receive call, and play\n    media to the sound device.\n    \n  - @ref page_pjsip_sample_simple_pjsuaua_c\\n\n    Very simple SIP User Agent with registration, call, and media, using\n    PJSUA-API, all in under 200 lines of code.\n\n  - @ref page_pjsip_samples_pjsua\\n\n    This is the reference implementation for PJSIP and PJMEDIA.\n    PJSUA is a console based application, designed to be simple enough\n    to be readble, but powerful enough to demonstrate all features\n    available in PJSIP and PJMEDIA.\\n\n    Screenshot on WinXP: \\image html pjsua.jpg \"pjsua on WinXP\"\n\n  - @ref page_pjmedia_samples_siprtp_c\\n\n    This is a useful program (integrated with PJSIP) to actively measure \n    the network quality/impairment parameters by making one or more SIP \n    calls (or receiving one or more SIP calls) and display the network\n    impairment of each stream direction at the end of the call.\n    The program is able to measure network quality parameters such as\n    jitter, packet lost/reorder/duplicate, round trip time, etc.\\n\n    Note that the remote peer MUST support RTCP so that network quality\n    of each direction can be calculated. Using siprtp for both endpoints\n    is recommended.\\n\n    Screenshots on WinXP: \\image html siprtp.jpg \"siprtp screenshot on WinXP\"\n\n  - @ref page_pjsip_perf_c\\n\n    This sample contains a complete implementation of a SIP performance\n    measurement tool. Unlike other tool such SIPp, pjsip-perf is geared\n    more towards finding the performance of an endpoint by flooding the\n    endpoint with some requests and time the completion of the requests.\\n\n    Screenshots on Linux console: \\image html pjsip-perf.jpg \"pjsip-perf screenshot on Linux\"\n */\n\n/**\n * \\page page_pjsip_samples_pjsua PJSUA\n *\n * This is the reference implementation for PJSIP and PJMEDIA.\n * PJSUA is a console based application, designed to be simple enough\n * to be readble, but powerful enough to demonstrate all features\n * available in PJSIP and PJMEDIA.\n *\n * This file is pjsip-apps/src/pjsua/pjsua_app.c\n *\n * Screenshot on WinXP: \\image html pjsua.jpg \"pjsua on WinXP\"\n *\n * \\includelineno pjsua_app.c\n */\n\n/**\n * \\page page_pjsip_sample_simple_ua_c Samples: Simple UA\n *\n * This is a very simple SIP User Agent application that only use PJSIP\n * (without PJSIP-UA). It's able to make and receive call, and play\n * media to the sound device.\n *\n * \\includelineno simpleua.c\n */\n\n/**\n * \\page page_pjsip_sample_simple_pjsuaua_c Samples: Simple PJSUA\n *\n * Very simple SIP User Agent with registration, call, and media, all\n * in under 200 lines of code.\n *\n * \\includelineno simple_pjsua.c\n */\n\n/**\n * \\page page_pjsip_sample_sipstateless_c Samples: Stateless SIP Endpoint\n *\n * This is about the simplest SIP application with PJSIP, all it does is\n * respond all incoming requests with 501 (Not Implemented) response\n * statelessly.\n *\n * \\includelineno sipstateless.c\n */\n\n/**\n * \\page page_pjmedia_samples_siprtp_c Samples: siprtp - SIP with RTCP Quality Monitoring\n *\n * This source is an example to demonstrate using SIP and RTP/RTCP framework\n * to measure the network quality/impairment from the SIP call. This\n * program can be used to make calls or to receive calls from other\n * SIP endpoint (or other siprtp program), and to display the media\n * quality statistics at the end of the call.\n *\n * Note that the remote peer must support RTCP.\n *\n * The layout of the program has been designed so that custom reporting\n * can be generated instead of plain human readable text.\n *\n * The source code of the file is pjsip-apps/src/samples/siprtp.c\n *\n * Screenshots on WinXP: \\image html siprtp.jpg\n *\n * \\includelineno siprtp.c\n */\n\n/**\n * \\page page_pjsip_perf_c Samples: pjsip-perf - SIP Performance Benchmarking Tool\n *\n * This sample contains a complete implementation of a SIP performance\n * measurement tool. Unlike other tool such SIPp, pjsip-perf is geared\n * more towards finding the performance of an endpoint by flooding the\n * endpoint with some requests and time the completion of the requests.\n *\n * The source code of the file is pjsip-apps/src/samples/pjsip-perf.c\n *\n * Screenshots on Linux console: \\image html pjsip-perf.jpg\n *\n * \\includelineno pjsip-perf.c\n */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/docs/footer.html",
    "content": "<p>&nbsp;</p>\r\n<hr><center>\r\nPJSIP Open Source, high performance, small footprint, and very very portable SIP stack<br>\r\nCopyright (C) 2006-2008 Teluu Inc.\r\n</center>\r\n<!--#include virtual=\"/footer.html\" -->\r\n\r\n</BODY>\r\n</HTML>\r\n"
  },
  {
    "path": "deps/pjsip/pjsip/docs/header.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=iso-8859-1\">\r\n<title>$title ($projectnumber)</title>\r\n<link href=\"/style/style.css\" rel=\"stylesheet\" type=\"text/css\">\r\n</head><body>\r\n\t<!--#include virtual=\"/header.html\" -->\r\n\t<p><A HREF=\"/\">Home</A> --&gt; <A HREF=\"/docs.htm\">Documentations</A> --&gt; PJSIP Reference</p>\r\n\r\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/print_util.h",
    "content": "/* $Id: print_util.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_PRINT_H__\n#define __PJSIP_PRINT_H__\n\n#define copy_advance_char_check(buf,chr)   \\\n\tdo { \\\n\t    if (1 >= (endbuf-buf)) return -1;\t\\\n\t    *buf++ = chr; \\\n\t} while (0)\n\n#define copy_advance_check(buf,str)   \\\n\tdo { \\\n\t    if ((str).slen >= (endbuf-buf)) return -1;\t\\\n\t    pj_memcpy(buf, (str).ptr, (str).slen); \\\n\t    buf += (str).slen; \\\n\t} while (0)\n\n#define copy_advance_pair_check(buf,str1,len1,str2)   \\\n\tdo { \\\n\t    if (str2.slen) { \\\n\t\tprinted = len1+(int)str2.slen; \\\n\t\tif (printed >= (endbuf-buf)) return -1;\t\\\n\t\tpj_memcpy(buf,str1,len1); \\\n\t\tpj_memcpy(buf+len1, str2.ptr, str2.slen); \\\n\t\tbuf += printed; \\\n\t    } \\\n\t} while (0)\n\n#define copy_advance_pair_quote_check(buf,str1,len1,str2,quotebegin,quoteend) \\\n\tdo { \\\n\t    if (str2.slen) { \\\n\t\tprinted = len1+str2.slen+2; \\\n\t\tif (printed >= (endbuf-buf)) return -1;\t\\\n\t\tpj_memcpy(buf,str1,len1); \\\n\t\t*(buf+len1)=quotebegin; \\\n\t\tpj_memcpy(buf+len1+1, str2.ptr, str2.slen); \\\n\t\t*(buf+printed-1) = quoteend; \\\n\t\tbuf += printed; \\\n\t    } \\\n\t} while (0)\n\n#define copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend) \\\n\tdo { \\\n\t\tprinted = len1+(int)str2.slen+2; \\\n\t\tif (printed >= (endbuf-buf)) return -1;\t\\\n\t\tpj_memcpy(buf,str1,len1); \\\n\t\t*(buf+len1)=quotebegin; \\\n\t\tpj_memcpy(buf+len1+1, str2.ptr, str2.slen); \\\n\t\t*(buf+printed-1) = quoteend; \\\n\t\tbuf += printed; \\\n\t} while (0)\n\n#define copy_advance_pair_escape(buf,str1,len1,str2,unres)\t\\\n\tdo { \\\n\t  if (str2.slen) { \\\n\t    if (len1+str2.slen >= (endbuf-buf)) return -1; \\\n\t    pj_memcpy(buf,str1,len1); \\\n\t    printed=(int)pj_strncpy2_escape(buf+len1,&str2,(endbuf-buf-len1), \\\n\t\t\t\t\t    &unres);\\\n\t    if (printed < 0) return -1; \\\n\t    buf += (printed+len1); \\\n\t  } \\\n\t} while (0)\n\n\n#define copy_advance_no_check(buf,str)   \\\n\tdo { \\\n\t    pj_memcpy(buf, (str).ptr, (str).slen); \\\n\t    buf += (str).slen; \\\n\t} while (0)\n\n#define copy_advance_escape(buf,str,unres)    \\\n\tdo { \\\n\t    printed = \\\n\t\t(int)pj_strncpy2_escape(buf, &(str), (endbuf-buf), &(unres)); \\\n\t    if (printed < 0) return -1; \\\n\t    buf += printed; \\\n\t} while (0)\n\n#define copy_advance_pair_no_check(buf,str1,len1,str2)   \\\n\tif (str2.slen) { \\\n\t    pj_memcpy(buf,str1,len1); \\\n\t    pj_memcpy(buf+len1, str2.ptr, str2.slen); \\\n\t    buf += len1+str2.slen; \\\n\t}\n\n#define copy_advance \t\tcopy_advance_check\n#define copy_advance_pair \tcopy_advance_pair_check\n\n/*\n * Append str1 and quoted str2 and copy to buf. \n * No string is copied if str2 is empty.\n */\n#define copy_advance_pair_quote_cond(buf,str1,len1,str2,quotebegin,quoteend) \\\n\tdo {\t\\\n\t  if (str2.slen && *str2.ptr!=quotebegin) \\\n\t    copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend); \\\n\t  else \\\n\t    copy_advance_pair(buf,str1,len1,str2); \\\n\t} while (0)\n\n/*\n * Append str1 and quoted str2 and copy to buf. \n * In case str2 is empty, str1 will be appended with empty quote.\n */\n#define copy_advance_pair_quote_cond_always(buf,str1,len1,str2,quotebegin, \\\n\t\t\t\t\t    quoteend)\\\n    do {\t\\\n       if (!str2.slen) \\\n         copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend); \\\n       else \\\n\t copy_advance_pair_quote_cond(buf,str1,len1,str2,quotebegin,quoteend);\\\n    } while (0)\n\n/*\n * Internal type declarations.\n */\ntypedef void* (*pjsip_hdr_clone_fptr)(pj_pool_t *, const void*);\ntypedef int   (*pjsip_hdr_print_fptr)(void *hdr, char *buf, pj_size_t len);\n\ntypedef struct pjsip_hdr_name_info_t\n{\n    char\t*name;\n    unsigned\t name_len;\n    char\t*sname;\n} pjsip_hdr_name_info_t;\n\nextern const pjsip_hdr_name_info_t pjsip_hdr_names[];\n\nPJ_INLINE(void) init_hdr(void *hptr, pjsip_hdr_e htype, void *vptr)\n{\n    pjsip_hdr *hdr = (pjsip_hdr*) hptr;\n    hdr->type = htype;\n    hdr->name.ptr = pjsip_hdr_names[htype].name;\n    hdr->name.slen = pjsip_hdr_names[htype].name_len;\n    if (pjsip_hdr_names[htype].sname) {\n\thdr->sname.ptr = pjsip_hdr_names[htype].sname;\n\thdr->sname.slen = 1;\n    } else {\n\thdr->sname = hdr->name;\n    }\n    hdr->vptr = (pjsip_hdr_vptr*) vptr;\n    pj_list_init(hdr);\n}\n\n#endif\t/* __PJSIP_PRINT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_auth.h",
    "content": "/* $Id: sip_auth.h 4214 2012-07-25 14:29:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_AUTH_SIP_AUTH_H__\n#define __PJSIP_AUTH_SIP_AUTH_H__\n\n/**\n * @file pjsip_auth.h\n * @brief SIP Authorization Module.\n */\n\n#include <pjsip/sip_config.h>\n#include <pjsip/sip_auth_msg.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @addtogroup PJSIP_AUTH\n * @ingroup PJSIP_CORE\n * @brief Client and server side authentication framework.\n */\n\n/**\n * @defgroup PJSIP_AUTH_API Authentication API's\n * @ingroup PJSIP_AUTH\n * @brief Structures and functions to perform authentication.\n * @{\n */\n\n/** Length of digest string. */\n#define PJSIP_MD5STRLEN 32\n\n\n/** Type of data in the credential information in #pjsip_cred_info. */\ntypedef enum pjsip_cred_data_type\n{\n    PJSIP_CRED_DATA_PLAIN_PASSWD=0, /**< Plain text password.\t\t*/\n    PJSIP_CRED_DATA_DIGEST\t=1, /**< Hashed digest.\t\t\t*/\n\n    PJSIP_CRED_DATA_EXT_AKA\t=16 /**< Extended AKA info is available */\n\n} pjsip_cred_data_type;\n\n/** Authentication's quality of protection (qop) type. */\ntypedef enum pjsip_auth_qop_type\n{\n    PJSIP_AUTH_QOP_NONE,\t    /**< No quality of protection. */\n    PJSIP_AUTH_QOP_AUTH,\t    /**< Authentication. */\n    PJSIP_AUTH_QOP_AUTH_INT,\t    /**< Authentication with integrity protection. */\n    PJSIP_AUTH_QOP_UNKNOWN\t    /**< Unknown protection. */\n} pjsip_auth_qop_type;\n\n\n/**\n * Type of callback function to create authentication response.\n * Application can specify this callback in \\a cb field of the credential info\n * (#pjsip_cred_info) and specifying PJSIP_CRED_DATA_DIGEST_CALLBACK as \n * \\a data_type. When this function is called, most of the fields in the \n * \\a auth authentication response will have been filled by the framework. \n * Application normally should just need to calculate the response digest \n * of the authentication response.\n *\n * @param pool\t    Pool to allocate memory from if application needs to.\n * @param chal\t    The authentication challenge sent by server in 401\n *\t\t    or 401 response, in either Proxy-Authenticate or\n *\t\t    WWW-Authenticate header.\n * @param cred\t    The credential that has been selected by the framework\n *\t\t    to authenticate against the challenge.\n * @param auth\t    The authentication response which application needs to\n *\t\t    calculate the response digest.\n *\n * @return\t    Application may return non-PJ_SUCCESS to abort the\n *\t\t    authentication process. When this happens, the \n *\t\t    framework will return failure to the original function\n *\t\t    that requested authentication.\n */\ntypedef pj_status_t (*pjsip_cred_cb)(pj_pool_t *pool,\n\t\t\t\t     const pjsip_digest_challenge *chal,\n\t\t\t\t     const pjsip_cred_info *cred,\n\t\t\t\t     const pj_str_t *method,\n\t\t\t\t     pjsip_digest_credential *auth);\n\n\n/** \n * This structure describes credential information. \n * A credential information is a static, persistent information that identifies\n * username and password required to authorize to a specific realm.\n *\n * Note that since PJSIP 0.7.0.1, it is possible to make a credential that is\n * valid for any realms, by setting the realm to star/wildcard character,\n * i.e. realm = pj_str(\"*\");.\n */\nstruct pjsip_cred_info\n{\n    pj_str_t    realm;\t\t/**< Realm. Use \"*\" to make a credential that\n\t\t\t\t     can be used to authenticate against any\n\t\t\t\t     challenges.\t\t\t    */\n    pj_str_t\tscheme;\t\t/**< Scheme (e.g. \"digest\").\t\t    */\n    pj_str_t\tusername;\t/**< User name.\t\t\t\t    */\n    int\t\tdata_type;\t/**< Type of data (0 for plaintext passwd). */\n    pj_str_t\tdata;\t\t/**< The data, which can be a plaintext \n\t\t\t\t     password or a hashed digest.\t    */\n\n    /** Extended data */\n    union {\n\t/** Digest AKA credential information. Note that when AKA credential\n\t *  is being used, the \\a data field of this #pjsip_cred_info is\n\t *  not used, but it still must be initialized to an empty string.\n\t * Please see \\ref PJSIP_AUTH_AKA_API for more information.\n\t */\n\tstruct {\n\t    pj_str_t\t  k;\t/**< Permanent subscriber key.\t\t*/\n\t    pj_str_t\t  op;\t/**< Operator variant key.\t\t*/\n\t    pj_str_t\t  amf;\t/**< Authentication Management Field\t*/\n\t    pjsip_cred_cb cb;\t/**< Callback to create AKA digest.\t*/\n\t} aka;\n\n    } ext;\n};\n\n/**\n * This structure describes cached value of previously sent Authorization\n * or Proxy-Authorization header. The authentication framework keeps a list\n * of this structure and will resend the same header to the same server\n * as long as the method, uri, and nonce stays the same.\n */\ntypedef struct pjsip_cached_auth_hdr\n{\n    /** Standard list member */\n    PJ_DECL_LIST_MEMBER(struct pjsip_cached_auth_hdr);\n\n    pjsip_method\t     method;\t/**< To quickly see the method. */\n    pjsip_authorization_hdr *hdr;\t/**< The cached header.\t\t*/\n\n} pjsip_cached_auth_hdr;\n\n\n/**\n * This structure describes authentication information for the specified\n * realm. Each instance of this structure describes authentication \"session\"\n * between this endpoint and remote server. This \"session\" information is\n * usefull to keep information that persists for more than one challenge,\n * such as nonce-count and cnonce value.\n *\n * Other than that, this structure also keeps the last authorization headers\n * that have been sent in the cache list.\n */\ntypedef struct pjsip_cached_auth\n{\n    /** Standard list member */\n    PJ_DECL_LIST_MEMBER(struct pjsip_cached_auth);\n\n    pj_str_t\t\t\t realm;\t    /**< Realm.\t\t\t    */\n    pj_bool_t\t\t\t is_proxy;  /**< Server type (401/407)\t    */\n    pjsip_auth_qop_type\t\t qop_value; /**< qop required by server.    */\n    unsigned\t\t\t stale_cnt; /**< Number of stale retry.\t    */\n#if PJSIP_AUTH_QOP_SUPPORT\n    pj_uint32_t\t\t\t nc;\t    /**< Nonce count.\t\t    */\n    pj_str_t\t\t\t cnonce;    /**< Cnonce value.\t\t    */\n#endif\n    pjsip_www_authenticate_hdr\t*last_chal; /**< Last challenge seen.\t    */\n#if PJSIP_AUTH_HEADER_CACHING\n    pjsip_cached_auth_hdr\t cached_hdr;/**< List of cached header for\n\t\t\t\t\t\t each method.\t\t    */\n#endif\n\n} pjsip_cached_auth;\n\n\n/**\n * This structure describes client authentication session preference.\n * The preference can be set by calling #pjsip_auth_clt_set_prefs().\n */\ntypedef struct pjsip_auth_clt_pref\n{\n    /**\n     * If this flag is set, the authentication client framework will\n     * send an empty Authorization header in each initial request.\n     * Default is no.\n     */\n    pj_bool_t\tinitial_auth;\n\n    /**\n     * Specify the algorithm to use when empty Authorization header \n     * is to be sent for each initial request (see above)\n     */\n    pj_str_t\talgorithm;\n\n} pjsip_auth_clt_pref;\n\n\n/**\n * Duplicate a client authentication preference setting.\n *\n * @param pool\t    The memory pool.\n * @param dst\t    Destination client authentication preference.\n * @param src\t    Source client authentication preference.\n */\nPJ_DECL(void) pjsip_auth_clt_pref_dup(pj_pool_t *pool,\n\t\t\t\t      pjsip_auth_clt_pref *dst,\n\t\t\t\t      const pjsip_auth_clt_pref *src);\n\n\n/**\n * This structure describes client authentication sessions. It keeps\n * all the information needed to authorize the client against all downstream \n * servers.\n */\ntypedef struct pjsip_auth_clt_sess\n{\n    pj_pool_t\t\t*pool;\t\t/**< Pool to use.\t\t    */\n    pjsip_endpoint\t*endpt;\t\t/**< Endpoint where this belongs.   */\n    pjsip_auth_clt_pref  pref;\t\t/**< Preference/options.\t    */\n    unsigned\t\t cred_cnt;\t/**< Number of credentials.\t    */\n    pjsip_cred_info\t*cred_info;\t/**< Array of credential information*/\n    pjsip_cached_auth\t cached_auth;\t/**< Cached authorization info.\t    */\n\n} pjsip_auth_clt_sess;\n\n\n/**\n * Duplicate a credential info.\n *\n * @param pool\t    The memory pool.\n * @param dst\t    Destination credential.\n * @param src\t    Source credential.\n */\nPJ_DECL(void) pjsip_cred_info_dup(pj_pool_t *pool,\n\t\t\t\t  pjsip_cred_info *dst,\n\t\t\t\t  const pjsip_cred_info *src);\n\n/**\n * Compare two credential infos.\n *\n * @param cred1\t    The credential info to compare.\n * @param cred2\t    The credential info to compare.\n *\n * @return\t    0 if both credentials are equal.\n */\nPJ_DECL(int) pjsip_cred_info_cmp(const pjsip_cred_info *cred1,\n\t\t\t\t const pjsip_cred_info *cred2);\n\n\n/**\n * Type of function to lookup credential for the specified name.\n *\n * @param pool\t\tPool to initialize the credential info.\n * @param realm\t\tRealm to find the account.\n * @param acc_name\tAccount name to look for.\n * @param cred_info\tThe structure to put the credential when it's found.\n *\n * @return\t\tThe function MUST return PJ_SUCCESS when it found\n *\t\t\ta correct credential for the specified account and\n *\t\t\trealm. Otherwise it may return PJSIP_EAUTHACCNOTFOUND\n *\t\t\tor PJSIP_EAUTHACCDISABLED.\n */\ntypedef pj_status_t pjsip_auth_lookup_cred( pj_pool_t *pool,\n\t\t\t\t\t    const pj_str_t *realm,\n\t\t\t\t\t    const pj_str_t *acc_name,\n\t\t\t\t\t    pjsip_cred_info *cred_info );\n\n\n/**\n * This structure describes input param for credential lookup.\n */\ntypedef struct pjsip_auth_lookup_cred_param\n{\n    pj_str_t realm;\t    /**< Realm to find the account.\t\t*/\n    pj_str_t acc_name;\t    /**< Account name to look for.\t\t*/\n    pjsip_rx_data *rdata;   /**< Incoming request to be authenticated.\t*/\n\n} pjsip_auth_lookup_cred_param;\n\n\n/**\n * Type of function to lookup credential for the specified name.\n *\n * @param pool\t\tPool to initialize the credential info.\n * @param param\t\tThe input param for credential lookup.\n * @param cred_info\tThe structure to put the credential when it's found.\n *\n * @return\t\tThe function MUST return PJ_SUCCESS when it found\n *\t\t\ta correct credential for the specified account and\n *\t\t\trealm. Otherwise it may return PJSIP_EAUTHACCNOTFOUND\n *\t\t\tor PJSIP_EAUTHACCDISABLED.\n */\ntypedef pj_status_t pjsip_auth_lookup_cred2(\n\t\t\t\tpj_pool_t *pool,\n\t\t\t\tconst pjsip_auth_lookup_cred_param *param,\n\t\t\t\tpjsip_cred_info *cred_info );\n\n\n/** Flag to specify that server is a proxy. */\n#define PJSIP_AUTH_SRV_IS_PROXY\t    1\n\n/**\n * This structure describes server authentication information.\n */\ntypedef struct pjsip_auth_srv\n{\n    pj_str_t\t\t     realm;\t/**< Realm to serve.\t\t    */\n    pj_bool_t\t\t     is_proxy;\t/**< Will issue 407 instead of 401  */\n    pjsip_auth_lookup_cred  *lookup;\t/**< Lookup function.\t\t    */\n    pjsip_auth_lookup_cred2 *lookup2;\t/**< Lookup function with additional\n\t\t\t\t\t     info in its input param.\t    */\n} pjsip_auth_srv;\n\n\n/**\n * Initialize client authentication session data structure, and set the \n * session to use pool for its subsequent memory allocation. The argument \n * options should be set to zero for this PJSIP version.\n *\n * @param sess\t\tThe client authentication session.\n * @param endpt\t\tEndpoint where this session belongs.\n * @param pool\t\tPool to use.\n * @param options\tMust be zero.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_auth_clt_init( pjsip_auth_clt_sess *sess,\n\t\t\t\t\t  pjsip_endpoint *endpt,\n\t\t\t\t\t  pj_pool_t *pool, \n\t\t\t\t\t  unsigned options);\n\n\n/**\n * Clone client initialization session. \n *\n * @param pool\t\tPool to use.\n * @param sess\t\tStructure to put the duplicated session.\n * @param rhs\t\tThe client session to be cloned.\n *\n * @return\t\tPJ_SUCCESS on success;\n */\nPJ_DECL(pj_status_t) pjsip_auth_clt_clone( pj_pool_t *pool,\n\t\t\t\t\t   pjsip_auth_clt_sess *sess,\n\t\t\t\t\t   const pjsip_auth_clt_sess *rhs);\n\n/**\n * Set the credentials to be used during the session. This will duplicate \n * the specified credentials using client authentication's pool.\n *\n * @param sess\t\tThe client authentication session.\n * @param cred_cnt\tNumber of credentials.\n * @param c\t\tArray of credentials.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *sess,\n\t\t\t\t\t\t     int cred_cnt,\n\t\t\t\t\t\t     const pjsip_cred_info *c);\n\n\n/**\n * Set the preference for the client authentication session.\n *\n * @param sess\t\tThe client authentication session.\n * @param p\t\tPreference.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_auth_clt_set_prefs(pjsip_auth_clt_sess *sess,\n\t\t\t\t\t      const pjsip_auth_clt_pref *p);\n\n\n/**\n * Get the preference for the client authentication session.\n *\n * @param sess\t\tThe client authentication session.\n * @param p\t\tPointer to receive the preference.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_auth_clt_get_prefs(pjsip_auth_clt_sess *sess,\n\t\t\t\t\t      pjsip_auth_clt_pref *p);\n\n/**\n * Initialize new request message with authorization headers.\n * This function will put Authorization/Proxy-Authorization headers to the\n * outgoing request message. If caching is enabled (PJSIP_AUTH_HEADER_CACHING)\n * and the session has previously sent Authorization/Proxy-Authorization header\n * with the same method, then the same Authorization/Proxy-Authorization header\n * will be resent from the cache only if qop is not present. If the stack is \n * configured to automatically generate next Authorization/Proxy-Authorization\n * headers (PJSIP_AUTH_AUTO_SEND_NEXT flag), then new Authorization/Proxy-\n * Authorization headers are calculated and generated when they are not present\n * in the case or if authorization session has qop.\n *\n * If both PJSIP_AUTH_HEADER_CACHING flag and PJSIP_AUTH_AUTO_SEND_NEXT flag\n * are not set, this function will do nothing. The stack then will only send\n * Authorization/Proxy-Authorization to respond 401/407 response.\n *\n * @param sess\t\tThe client authentication session.\n * @param tdata\t\tThe request message to be initialized.\n *\n * @return\t\tPJ_SUCCESS if successfull.\n */\nPJ_DECL(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,\n\t\t\t\t\t      pjsip_tx_data *tdata );\n\n\n/**\n * Call this function when a transaction failed with 401 or 407 response.\n * This function will reinitialize the original request message with the\n * authentication challenge found in the response message, and add the\n * new authorization header in the authorization cache.\n *\n * Note that upon return the reference counter of the new transmit data\n * will be set to 1.\n *\n * @param sess\t\tThe client authentication session.\n * @param rdata\t\tThe response message containing 401/407 status.\n * @param old_request\tThe original request message, which will be re-\n *\t\t\tcreated with authorization info.\n * @param new_request\tPointer to receive new request message which\n *\t\t\twill contain all required authorization headers.\n *\n * @return\t\tPJ_SUCCESS if new request can be successfully\n *\t\t\tcreated to respond all the authentication\n *\t\t\tchallenges.\n */\nPJ_DECL(pj_status_t) pjsip_auth_clt_reinit_req(\tpjsip_auth_clt_sess *sess,\n\t\t\t\t\t\tconst pjsip_rx_data *rdata,\n\t\t\t\t\t\tpjsip_tx_data *old_request,\n\t\t\t\t\t\tpjsip_tx_data **new_request );\n\n/**\n * Initialize server authorization session data structure to serve the \n * specified realm and to use lookup_func function to look for the credential \n * info. \n *\n * @param pool\t\tPool used to initialize the authentication server.\n * @param auth_srv\tThe authentication server structure.\n * @param realm\t\tRealm to be served by the server.\n * @param lookup\tAccount lookup function.\n * @param options\tOptions, bitmask of:\n *\t\t\t- PJSIP_AUTH_SRV_IS_PROXY: to specify that the server\n *\t\t\t  will authorize clients as a proxy server (instead of\n *\t\t\t  as UAS), which means that Proxy-Authenticate will \n *\t\t\t  be used instead of WWW-Authenticate.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_auth_srv_init( pj_pool_t *pool,\n\t\t\t\t\t  pjsip_auth_srv *auth_srv,\n\t\t\t\t\t  const pj_str_t *realm,\n\t\t\t\t\t  pjsip_auth_lookup_cred *lookup,\n\t\t\t\t\t  unsigned options );\n\n\n/**\n * This structure describes initialization settings of server authorization\n * session.\n */\ntypedef struct pjsip_auth_srv_init_param\n{\n    /**\n     * Realm to be served by the server.\n     */\n    const pj_str_t\t\t*realm;\n\n    /**\n     * Account lookup function.\n     */\n    pjsip_auth_lookup_cred2\t*lookup2;\n\n    /**\n     * Options, bitmask of:\n     * - PJSIP_AUTH_SRV_IS_PROXY: to specify that the server will authorize\n     *   clients as a proxy server (instead of as UAS), which means that\n     *   Proxy-Authenticate will be used instead of WWW-Authenticate.\n     */\n    unsigned\t\t\t options;\n\n} pjsip_auth_srv_init_param;\n\n\n/**\n * Initialize server authorization session data structure to serve the \n * specified realm and to use lookup_func function to look for the credential\n * info. \n *\n * @param pool\t\tPool used to initialize the authentication server.\n * @param auth_srv\tThe authentication server structure.\n * @param param\t\tThe initialization param.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_auth_srv_init2(\n\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t    pjsip_auth_srv *auth_srv,\n\t\t\t\t    const pjsip_auth_srv_init_param *param);\n\n/**\n * Request the authorization server framework to verify the authorization \n * information in the specified request in rdata.\n *\n * @param auth_srv\tThe server authentication structure.\n * @param rdata\t\tIncoming request to be authenticated.\n * @param status_code\tWhen not null, it will be filled with suitable \n *\t\t\tstatus code to be sent to the client.\n *\n * @return\t\tPJ_SUCCESS if request is successfully authenticated.\n *\t\t\tOtherwise the function may return one of the\n *\t\t\tfollowing error codes:\n *\t\t\t- PJSIP_EAUTHNOAUTH\n *\t\t\t- PJSIP_EINVALIDAUTHSCHEME\n *\t\t\t- PJSIP_EAUTHACCNOTFOUND\n *\t\t\t- PJSIP_EAUTHACCDISABLED\n *\t\t\t- PJSIP_EAUTHINVALIDREALM\n *\t\t\t- PJSIP_EAUTHINVALIDDIGEST\n */\nPJ_DECL(pj_status_t) pjsip_auth_srv_verify( pjsip_auth_srv *auth_srv,\n\t\t\t\t\t    pjsip_rx_data *rdata,\n\t\t\t\t\t    int *status_code );\n\n\n/**\n * Add authentication challenge headers to the outgoing response in tdata. \n * Application may specify its customized nonce and opaque for the challenge, \n * or can leave the value to NULL to make the function fills them in with \n * random characters.\n *\n * @param auth_srv\tThe server authentication structure.\n * @param qop\t\tOptional qop value.\n * @param nonce\t\tOptional nonce value.\n * @param opaque\tOptional opaque value.\n * @param stale\t\tStale indication.\n * @param tdata\t\tThe outgoing response message. The response must have\n *\t\t\t401 or 407 response code.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_auth_srv_challenge( pjsip_auth_srv *auth_srv,\n\t\t\t\t\t       const pj_str_t *qop,\n\t\t\t\t\t       const pj_str_t *nonce,\n\t\t\t\t\t       const pj_str_t *opaque,\n\t\t\t\t\t       pj_bool_t stale,\n\t\t\t\t\t       pjsip_tx_data *tdata);\n\n/**\n * Helper function to create MD5 digest out of the specified \n * parameters.\n *\n * @param result\tString to store the response digest. This string\n *\t\t\tmust have been preallocated by caller with the \n *\t\t\tbuffer at least PJSIP_MD5STRLEN (32 bytes) in size.\n * @param nonce\t\tOptional nonce.\n * @param nc\t\tNonce count.\n * @param cnonce\tOptional cnonce.\n * @param qop\t\tOptional qop.\n * @param uri\t\tURI.\n * @param realm\t\tRealm.\n * @param cred_info\tCredential info.\n * @param method\tSIP method.\n */\nPJ_DECL(void) pjsip_auth_create_digest(pj_str_t *result,\n\t\t\t\t       const pj_str_t *nonce,\n\t\t\t\t       const pj_str_t *nc,\n\t\t\t\t       const pj_str_t *cnonce,\n\t\t\t\t       const pj_str_t *qop,\n\t\t\t\t       const pj_str_t *uri,\n\t\t\t\t       const pj_str_t *realm,\n\t\t\t\t       const pjsip_cred_info *cred_info,\n\t\t\t\t       const pj_str_t *method);\n\n/**\n * @}\n */\n\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJSIP_AUTH_SIP_AUTH_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_auth_aka.h",
    "content": "/* $Id: sip_auth_aka.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_AUTH_SIP_AUTH_AKA_H__\n#define __PJSIP_AUTH_SIP_AUTH_AKA_H__\n\n/**\n * @file sip_auth_aka.h\n * @brief SIP Digest AKA Authorization Module.\n */\n\n#include <pjsip/sip_auth.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_AUTH_AKA_API Digest AKAv1 and AKAv2 Authentication API\n * @ingroup PJSIP_AUTH_API\n * @brief Digest AKAv1 and AKAv2 Authentication API\n * @{\n *\n * This module implements HTTP digest authentication using Authentication\n * and Key Agreement (AKA) version 1 and version 2 (AKAv1-MD5 and AKAv2-MD5),\n * as specified in RFC 3310 and RFC 4169. SIP AKA authentication is used\n * by 3GPP and IMS systems.\n *\n * @section pjsip_aka_using Using Digest AKA Authentication\n *\n * Support for digest AKA authentication is currently made optional, so\n * application needs to declare \\a PJSIP_HAS_DIGEST_AKA_AUTH to non-zero\n * in <tt>config_site.h</tt> to enable AKA support:\n *\n @code\n   #define PJSIP_HAS_DIGEST_AKA_AUTH   1\n @endcode\n\n *\n * In addition, application would need to link with <b>libmilenage</b>\n * library from \\a third_party directory.\n *\n * Application then specifies digest AKA credential by initializing the \n * authentication credential as follows:\n *\n @code\n\n    pjsip_cred_info cred;\n\n    pj_bzero(&cred, sizeof(cred));\n\n    cred.scheme = pj_str(\"Digest\");\n    cred.realm = pj_str(\"ims-domain.test\");\n    cred.username = pj_str(\"user@ims-domain.test\");\n    cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD | PJSIP_CRED_DATA_EXT_AKA;\n    cred.data = pj_str(\"password\");\n\n    // AKA extended info\n    cred.ext.aka.k = pj_str(\"password\");\n    cred.ext.aka.cb = &pjsip_auth_create_aka_response\n\n @endcode\n *\n * Description:\n * - To support AKA, application adds \\a PJSIP_CRED_DATA_EXT_AKA flag in the\n * \\a data_type field. This indicates that extended information specific to\n * AKA authentication is available in the credential, and that response \n * digest computation will use the callback function instead of the usual MD5\n * digest computation.\n *\n * - The \\a scheme for the credential is \"Digest\". \n *\n * - The \\a realm is the expected realm in the challenge. Application may \n * also specify wildcard realm (\"*\") if it wishes to respond to any realms \n * in the challenge.\n *\n * - The \\a data field is optional. Application may fill this with the password\n * if it wants to support both MD5 and AKA MD5 in a single credential. The\n * pjsip_auth_create_aka_response() function will use this field if the\n * challenge indicates \"MD5\" as the algorithm instead of \"AKAv1-MD5\" or\n * \"AKAv2-MD5\".\n *\n * - The \\a ext.aka.k field specifies the permanent subscriber key to be used\n * for AKA authentication. Application may specify binary password containing\n * NULL character in this key, since the length of the key is indicated in\n * the \\a slen field of the string.\n *\n * - The \\a ext.aka.cb field specifies the callback function to calculate the\n * response digest. Application can specify pjsip_auth_create_aka_response()\n * in this field to use PJSIP's implementation, but it's free to provide\n * it's own function.\n *\n * - Optionally application may set \\a ext.aka.op and \\a ext.aka.amf in the\n * credential to specify AKA Operator variant key and AKA Authentication \n * Management Field information.\n */\n\n/**\n * Length of Authentication Key (AK) in bytes.\n */\n#define PJSIP_AKA_AKLEN\t\t6\n\n/**\n * Length of Authentication Management Field (AMF) in bytes.\n */\n#define PJSIP_AKA_AMFLEN\t2\n\n/**\n * Length of AUTN in bytes.\n */\n#define PJSIP_AKA_AUTNLEN\t16\n\n/**\n * Length of Confidentiality Key (CK) in bytes.\n */\n#define PJSIP_AKA_CKLEN\t\t16\n\n/**\n * Length of Integrity Key (AK) in bytes.\n */\n#define PJSIP_AKA_IKLEN\t\t16\n\n/**\n * Length of permanent/subscriber Key (K) in bytes.\n */\n#define PJSIP_AKA_KLEN\t\t16\n\n/**\n * Length of AKA authentication code in bytes.\n */\n#define PJSIP_AKA_MACLEN\t8\n\n/**\n * Length of operator key in bytes.\n */\n#define PJSIP_AKA_OPLEN\t\t16\n\n/**\n * Length of random challenge (RAND) in bytes.\n */\n#define PJSIP_AKA_RANDLEN\t16\n\n/**\n * Length of response digest in bytes.\n */\n#define PJSIP_AKA_RESLEN\t8\n\n/**\n * Length of sequence number (SQN) in bytes.\n */\n#define PJSIP_AKA_SQNLEN\t6\n\n/**\n * This function creates MD5, AKAv1-MD5, or AKAv2-MD5 response for\n * the specified challenge in \\a chal, according to the algorithm \n * specified in the challenge, and based on the information in the \n * credential \\a cred.\n *\n * Application may register this function as \\a ext.aka.cb field of\n * #pjsip_cred_info structure to make PJSIP automatically call this\n * function to calculate the response digest. To do so, it needs to\n * add \\a PJSIP_CRED_DATA_EXT_AKA flag in the \\a data_type field of\n * the credential, and fills up other AKA specific information in\n * the credential.\n *\n * @param pool\t    Pool to allocate memory.\n * @param chal\t    The authentication challenge sent by server in 401\n *\t\t    or 401 response, as either Proxy-Authenticate or\n *\t\t    WWW-Authenticate header.\n * @param cred\t    The credential to be used.\n * @param method    The request method.\n * @param auth\t    The digest credential where the digest response\n *\t\t    will be placed to. Upon calling this function, the\n *\t\t    nonce, nc, cnonce, qop, uri, and realm fields of\n *\t\t    this structure must have been set by caller. Upon\n *\t\t    return, the \\a response field will be initialized\n *\t\t    by this function.\n *\n * @return\t    PJ_SUCCESS if response has been created successfully.\n */\nPJ_DECL(pj_status_t) pjsip_auth_create_aka_response(\n\t\t\t\t\t     pj_pool_t *pool,\n\t\t\t\t\t     const pjsip_digest_challenge*chal,\n\t\t\t\t\t     const pjsip_cred_info *cred,\n\t\t\t\t\t     const pj_str_t *method,\n\t\t\t\t\t     pjsip_digest_credential *auth);\n\n\n/**\n * @}\n */\n\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJSIP_AUTH_SIP_AUTH_AKA_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_auth_msg.h",
    "content": "/* $Id: sip_auth_msg.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_AUTH_SIP_AUTH_MSG_H__\n#define __PJSIP_AUTH_SIP_AUTH_MSG_H__\n\n#include <pjsip/sip_msg.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @addtogroup PJSIP_MSG_HDR\n * @{\n */\n\n/**\n * Common credential structure represents common credential fields\n * present in Authorization/Proxy-Authorization header.\n */\nstruct pjsip_common_credential\n{\n    pj_str_t\trealm;\t\t/**< Credential's realm.    */\n    pjsip_param\tother_param;\t/**< Other parameters.\t    */\n};\n\n/**\n * @see pjsip_common_credential\n */\ntypedef struct pjsip_common_credential pjsip_common_credential;\n\n\n/**\n * This structure describe credential used in Authorization and\n * Proxy-Authorization header for digest authentication scheme.\n */\nstruct pjsip_digest_credential\n{\n    pj_str_t\trealm;\t\t/**< Realm of the credential\t*/\n    pjsip_param\tother_param;\t/**< Other parameters.\t\t*/\n    pj_str_t\tusername;\t/**< Username parameter.\t*/\n    pj_str_t\tnonce;\t\t/**< Nonce parameter.\t\t*/\n    pj_str_t\turi;\t\t/**< URI parameter.\t\t*/ \n    pj_str_t\tresponse;\t/**< Response digest.\t\t*/\n    pj_str_t\talgorithm;\t/**< Algorithm.\t\t\t*/\n    pj_str_t\tcnonce;\t\t/**< Cnonce.\t\t\t*/\n    pj_str_t\topaque;\t\t/**< Opaque value.\t\t*/\n    pj_str_t\tqop;\t\t/**< Quality of protection.\t*/\n    pj_str_t\tnc;\t\t/**< Nonce count.\t\t*/\n};\n\n/**\n * @see pjsip_digest_credential\n */\ntypedef struct pjsip_digest_credential pjsip_digest_credential;\n\n/**\n * This structure describe credential used in Authorization and\n * Proxy-Authorization header for PGP authentication scheme.\n */\nstruct pjsip_pgp_credential\n{\n    pj_str_t\trealm;\t\t/**< Realm.\t\t\t*/\n    pjsip_param\tother_param;\t/**< Other parameters.\t\t*/\n    pj_str_t\tversion;\t/**< Version parameter.\t\t*/\n    pj_str_t\tsignature;\t/**< Signature parameter.\t*/\n    pj_str_t\tsigned_by;\t/**< Signed by parameter.\t*/\n    pj_str_t\tnonce;\t\t/**< Nonce parameter.\t\t*/\n};\n\n/**\n * @see pjsip_pgp_credential\n */\ntypedef struct pjsip_pgp_credential pjsip_pgp_credential;\n\n/**\n * This structure describes SIP Authorization header (and also SIP\n * Proxy-Authorization header).\n */\nstruct pjsip_authorization_hdr\n{\n    /** Standard header fiends. */\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_authorization_hdr);\n\n    /** Authorization scheme.  */\n    pj_str_t scheme;\n\n    /** Type of credentials, depending on the scheme. */\n    union\n    {\n\tpjsip_common_credential common;\t/**< Common fields.\t    */\n\tpjsip_digest_credential digest;\t/**< Digest credentials.    */\n\tpjsip_pgp_credential\tpgp;\t/**< PGP credentials.\t    */\n    } credential;\n};\n\n/**\n * @see pjsip_authorization_hdr.\n */\ntypedef struct pjsip_authorization_hdr pjsip_authorization_hdr;\n\n/** SIP Proxy-Authorization header shares the same structure as SIP\n    Authorization header.\n */\ntypedef struct pjsip_authorization_hdr pjsip_proxy_authorization_hdr;\n\n/**\n * Create SIP Authorization header.\n * @param pool\t    Pool where memory will be allocated from.\n * @return\t    SIP Authorization header.\n */\nPJ_DECL(pjsip_authorization_hdr*) \npjsip_authorization_hdr_create(pj_pool_t *pool);\n\n/**\n * Create SIP Proxy-Authorization header.\n * @param pool\t    Pool where memory will be allocated from.\n * @return SIP\t    Proxy-Authorization header.\n */\nPJ_DECL(pjsip_proxy_authorization_hdr*) \npjsip_proxy_authorization_hdr_create(pj_pool_t *pool);\n\n\n/**\n * This structure describes common fields in authentication challenge\n * headers (WWW-Authenticate and Proxy-Authenticate).\n */\nstruct pjsip_common_challenge\n{\n    pj_str_t\trealm;\t\t/**< Realm for the challenge.\t*/\n    pjsip_param\tother_param;\t/**< Other parameters.\t\t*/\n};\n\n/**\n * @see pjsip_common_challenge\n */\ntypedef struct pjsip_common_challenge pjsip_common_challenge;\n\n/**\n * This structure describes authentication challenge used in Proxy-Authenticate\n * or WWW-Authenticate for digest authentication scheme.\n */\nstruct pjsip_digest_challenge\n{\n    pj_str_t\trealm;\t\t/**< Realm for the challenge.\t*/\n    pjsip_param\tother_param;\t/**< Other parameters.\t\t*/\n    pj_str_t\tdomain;\t\t/**< Domain.\t\t\t*/\n    pj_str_t\tnonce;\t\t/**< Nonce challenge.\t\t*/\n    pj_str_t\topaque;\t\t/**< Opaque value.\t\t*/\n    int\t\tstale;\t\t/**< Stale parameter.\t\t*/\n    pj_str_t\talgorithm;\t/**< Algorithm parameter.\t*/\n    pj_str_t\tqop;\t\t/**< Quality of protection.\t*/\n};\n\n/**\n * @see pjsip_digest_challenge\n */\ntypedef struct pjsip_digest_challenge pjsip_digest_challenge;\n\n/**\n * This structure describes authentication challenge used in Proxy-Authenticate\n * or WWW-Authenticate for PGP authentication scheme.\n */\nstruct pjsip_pgp_challenge\n{\n    pj_str_t\trealm;\t\t/**< Realm for the challenge.\t*/\n    pjsip_param\tother_param;\t/**< Other parameters.\t\t*/\n    pj_str_t\tversion;\t/**< PGP version.\t\t*/\n    pj_str_t\tmicalgorithm;\t/**< micalgorithm parameter.\t*/\n    pj_str_t\tpubalgorithm;\t/**< pubalgorithm parameter.\t*/ \n    pj_str_t\tnonce;\t\t/**< Nonce challenge.\t\t*/\n};\n\n/**\n * @see pjsip_pgp_challenge\n */\ntypedef struct pjsip_pgp_challenge pjsip_pgp_challenge;\n\n/**\n * This structure describe SIP WWW-Authenticate header (Proxy-Authenticate\n * header also uses the same structure).\n */\nstruct pjsip_www_authenticate_hdr\n{\n    /** Standard header fields. */\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_www_authenticate_hdr);\n\n    /** Authentication scheme  */\n    pj_str_t\tscheme;\n\n    /** This union contains structures that are only relevant\n        depending on the value of the scheme being used.\n     */\n    union\n    {\n\tpjsip_common_challenge\tcommon;\t/**< Common fields.\t*/\n\tpjsip_digest_challenge\tdigest;\t/**< Digest challenge.\t*/\n\tpjsip_pgp_challenge\tpgp;\t/**< PGP challenge.\t*/\n    } challenge;\n};\n\n/**\n * WWW-Authenticate header.\n */\ntypedef struct pjsip_www_authenticate_hdr pjsip_www_authenticate_hdr;\n\n/**\n * Proxy-Authenticate header.\n */\ntypedef struct pjsip_www_authenticate_hdr pjsip_proxy_authenticate_hdr;\n\n\n/**\n * Create SIP WWW-Authenticate header.\n *\n * @param pool\t    Pool where memory will be allocated from.\n * @return\t    SIP WWW-Authenticate header.\n */\nPJ_DECL(pjsip_www_authenticate_hdr*) \npjsip_www_authenticate_hdr_create(pj_pool_t *pool);\n\n/**\n * Create SIP Proxy-Authenticate header.\n *\n * @param pool\t    Pool where memory will be allocated from.\n * @return\t    SIP Proxy-Authenticate header.\n */\nPJ_DECL(pjsip_proxy_authenticate_hdr*) \npjsip_proxy_authenticate_hdr_create(pj_pool_t *pool);\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_AUTH_SIP_AUTH_MSG_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_auth_parser.h",
    "content": "/* $Id: sip_auth_parser.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_AUTH_SIP_AUTH_PARSER_H__\n#define __PJSIP_AUTH_SIP_AUTH_PARSER_H__\n\n/**\n * @file sip_auth_parser.h\n * @brief SIP Authorization Parser Module.\n */\n\n#include <pj/types.h>\n\nPJ_BEGIN_DECL\n\n/**\n * Initialize and register authorization parser module.\n * This will register parser handler for various Authorization related headers\n * such as Authorization, WWW-Authenticate, Proxy-Authorizization, and \n * Proxy-Authenticate headers.\n *\n * This function is called automatically by the main SIP parser.\n *\n * @return      PJ_SUCCESS or the appropriate status code.\n */\nPJ_DECL(pj_status_t) pjsip_auth_init_parser(void);\n\n/**\n * DeInitialize authorization parser module.\n */\nPJ_DECL(void) pjsip_auth_deinit_parser();\n\n\n\nextern const pj_str_t\tpjsip_USERNAME_STR, /**< \"username\" string const.   */\n\t\t\tpjsip_REALM_STR,    /**< \"realm\" string const.\t    */\n\t\t\tpjsip_NONCE_STR,    /**< \"nonce\" string const.\t    */\n\t\t\tpjsip_URI_STR,\t    /**< \"uri\" string const.\t    */\n\t\t\tpjsip_RESPONSE_STR, /**< \"response\" string const.   */\n\t\t\tpjsip_ALGORITHM_STR,/**< \"algorithm\" string const.  */\n\t\t\tpjsip_DOMAIN_STR,   /**< \"domain\" string const.\t    */\n\t\t\tpjsip_STALE_STR,    /**< \"stale\" string const.\t    */\n\t\t\tpjsip_QOP_STR,\t    /**< \"qop\" string const.\t    */\n\t\t\tpjsip_CNONCE_STR,   /**< \"cnonce\" string const.\t    */\n\t\t\tpjsip_OPAQUE_STR,   /**< \"opaque\" string const.\t    */\n\t\t\tpjsip_NC_STR,\t    /**< \"nc\" string const.\t    */\n\t\t\tpjsip_TRUE_STR,\t    /**< \"true\" string const.\t    */\n\t\t\tpjsip_FALSE_STR,    /**< \"false\" string const.\t    */\n\t\t\tpjsip_DIGEST_STR,   /**< \"digest\" string const.\t    */\n\t\t\tpjsip_PGP_STR,\t    /**< \"pgp\" string const.\t    */\n\t\t\tpjsip_MD5_STR,\t    /**< \"md5\" string const.\t    */\n\t\t\tpjsip_AUTH_STR;\t    /**< \"auth\" string const.\t    */\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_AUTH_SIP_AUTH_PARSER_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_autoconf.h.in",
    "content": "/* $Id: sip_autoconf.h.in 3295 2010-08-25 12:51:29Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_AUTOCONF_H__\n#define __PJSIP_SIP_AUTOCONF_H__\n\n/**\n * @file sip_autoconf.h\n * @brief Describes operating system specifics (automatically detected by\n *        autoconf)\n */\n\n/*\n * Enable/disable TLS transport, as configured by autoconf.\n * But only do this if user doesn't explicitly configure in pj/config_site.h.\n */\n/* Since 1.5, the default setting will follow PJ_HAS_SSL_SOCK setting. */\n//#ifndef PJSIP_HAS_TLS_TRANSPORT\n//#undef PJSIP_HAS_TLS_TRANSPORT\n//#endif\n\n#endif\t/* __PJSIP_SIP_AUTOCONF_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_config.h",
    "content": "/* $Id: sip_config.h 4530 2013-05-30 09:27:49Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_CONFIG_H__\n#define __PJSIP_SIP_CONFIG_H__\n\n/**\n * @file sip_config.h\n * @brief Compile time configuration.\n */\n#include <pj/types.h>\n\n/**\n * @defgroup PJSIP_CORE Core SIP Library\n * @brief The core framework from which all other SIP components depends on.\n * \n * The PJSIP Core library only provides transport framework, event\n * dispatching/module framework, and SIP message representation and\n * parsing. It doesn't do anything usefull in itself!\n *\n * If application wants the stack to do anything usefull at all,\n * it must registers @ref PJSIP_MOD to the core library. Examples\n * of modules are @ref PJSIP_TRANSACT and @ref PJSUA_UA.\n */\n\n/**\n * @defgroup PJSIP_BASE Base Types\n * @ingroup PJSIP_CORE\n * @brief Basic PJSIP types and configurations.\n */\n\n/**\n * @defgroup PJSIP_CONFIG PJSIP Configurations/Settings\n * @ingroup PJSIP_BASE\n * @brief PJSIP compile time configurations.\n * @{\n */\n\n/*\n * Include sip_autoconf.h if autoconf is used (PJ_AUTOCONF is set)\n */\n#if defined(PJ_AUTOCONF)\n#   include <pjsip/sip_autoconf.h>\n#endif\n\nPJ_BEGIN_DECL\n\n/**\n * This structure describes PJSIP run-time configurations/settings.\n * Application may use #pjsip_cfg() function to modify the settings\n * before creating the stack.\n */\ntypedef struct pjsip_cfg_t\n{\n    /** Global settings. */\n    struct {\n\t/**\n\t * Specify port number should be allowed to appear in To and From\n\t * header. Note that RFC 3261 disallow this, see Table 1 in section\n\t * 19.1.1 of the RFC.\n\t *\n\t * Default is PJSIP_ALLOW_PORT_IN_FROMTO_HDR.\n\t */\n\tpj_bool_t allow_port_in_fromto_hdr;\n\n\t/**\n\t * Accept call replace in early state when invite is not initiated\n\t * by the user agent. RFC 3891 Section 3 disallows this, however,\n\t * for better interoperability reason, this might be ignored.\n\t *\n\t * Default is PJSIP_ACCEPT_REPLACE_IN_EARLY_STATE.\n\t */\n\tpj_bool_t accept_replace_in_early_state;\n\n\t/**\n\t * Allow hash character ('#') to appear in outgoing URIs. See\n\t * https://trac.pjsip.org/repos/ticket/1569.\n\t *\n\t * Default is PJ_FALSE.\n\t */\n\tpj_bool_t allow_tx_hash_in_uri;\n\n\t/**\n\t * Disable rport in request.\n\t *\n\t * Default is PJ_FALSE.\n\t */\n\tpj_bool_t disable_rport;\n\n\t/**\n\t * Disable automatic switching from UDP to TCP if outgoing request\n\t * is greater than 1300 bytes.\n\t *\n\t * Default is PJSIP_DONT_SWITCH_TO_TCP.\n\t */\n\tpj_bool_t disable_tcp_switch;\n\n\t/**\n\t * Disable automatic switching to TLS if target-URI does not use\n\t * \"sips\" scheme nor TLS transport, even when request-URI uses\n\t * \"sips\" scheme.\n\t *\n\t * Default is PJSIP_DONT_SWITCH_TO_TLS.\n\t */\n\tpj_bool_t disable_tls_switch;\n\n\t/**\n\t * Enable call media session to always be updated to the latest\n\t * received early media SDP when receiving forked early media\n\t * (multiple 183 responses with different To tag).\n\t *\n\t * Default is PJSIP_FOLLOW_EARLY_MEDIA_FORK.\n\t */\n\tpj_bool_t follow_early_media_fork;\n\n\t/**\n\t * Specify whether \"alias\" param should be added to the Via header\n\t * in any outgoing request with connection oriented transport.\n\t *\n\t * Default is PJSIP_REQ_HAS_VIA_ALIAS.\n\t */\n\tpj_bool_t req_has_via_alias;\n\n\t/**\n\t * Resolve hostname when trying to get the network interface to be put \n\t * in Via or Contact header.\n\t *\n\t * Default is PJSIP_RESOLVE_HOSTNAME_TO_GET_INTERFACE.\n\t */\n\tpj_bool_t resolve_hostname_to_get_interface;\n\n\t/**\n\t * Disable security check on incoming messages in a secure dialog.\n\t * A secure dialog is created when the request that creates the dialog\n\t * uses \"sips\" scheme in its request URI. Contact URI should use \"sips\"\n\t * scheme and the top-most Record-Route URI, if any, should use either\n\t * \"sips\" scheme or \"transport=tls\" param. See also\n\t * https://trac.pjsip.org/repos/ticket/1735.\n\t *\n\t * Default is PJ_FALSE.\n\t */\n\tpj_bool_t disable_secure_dlg_check;\n\n    } endpt;\n\n    /** Transaction layer settings. */\n    struct {\n\n\t/** Maximum number of transactions. The value is initialized with\n\t *  PJSIP_MAX_TSX_COUNT\n\t */\n\tunsigned max_count;\n\n\t/* Timeout values: */\n\n\t/** Transaction T1 timeout, in msec. Default value is PJSIP_T1_TIMEOUT\n\t */\n\tunsigned t1;\n\n\t/** Transaction T2 timeout, in msec. Default value is PJSIP_T2_TIMEOUT\n\t */\n\tunsigned t2;\n\n\t/** Transaction completed timer for non-INVITE, in msec. Default value\n\t *  is PJSIP_T4_TIMEOUT\n\t */\n\tunsigned t4;\n\n\t/** Transaction completed timer for INVITE, in msec. Default value is\n\t *  PJSIP_TD_TIMEOUT.\n\t */\n\tunsigned td;\n\n    } tsx;\n\n    /* Dialog layer settings .. TODO */\n\n    /** Client registration settings. */\n    struct {\n\t/**\n\t * Specify whether client registration should check for its \n\t * registered contact in Contact header of successful REGISTER \n\t * response to determine whether registration has been successful. \n\t * This setting may be disabled if non-compliant registrar is unable\n\t * to return correct Contact header.\n\t *\n\t * Default is PJSIP_REGISTER_CLIENT_CHECK_CONTACT\n\t */\n\tpj_bool_t   check_contact;\n\n\t/**\n\t * Specify whether client registration should add \"x-uid\" extension\n\t * parameter in all Contact URIs that it registers to assist the\n\t * matching of Contact URIs in the 200/OK REGISTER response, in \n\t * case the registrar is unable to return exact Contact URI in the\n\t * 200/OK response.\n\t *\n\t * Default is PJSIP_REGISTER_CLIENT_ADD_XUID_PARAM.\n\t */\n\tpj_bool_t   add_xuid_param;\n\n    } regc;\n\n    /** TCP transport settings */\n    struct {\n        /**\n         * Set the interval to send keep-alive packet for TCP transports.\n         * If the value is zero, keep-alive will be disabled for TCP.\n         *\n         * Default is PJSIP_TCP_KEEP_ALIVE_INTERVAL.\n         */\n        long keep_alive_interval;\n\n    } tcp;\n\n    /** TLS transport settings */\n    struct {\n        /**\n         * Set the interval to send keep-alive packet for TLS transports.\n         * If the value is zero, keep-alive will be disabled for TLS.\n         *\n         * Default is PJSIP_TLS_KEEP_ALIVE_INTERVAL.\n         */\n        long keep_alive_interval;\n\n    } tls;\n\n} pjsip_cfg_t;\n\n\n#ifdef PJ_DLL\n/**\n * Get pjsip configuration instance. Application may modify the\n * settings before creating the SIP endpoint and modules.\n *\n * @return  Configuration instance.\n */\nPJ_DECL(pjsip_cfg_t*) pjsip_cfg(void);\n\n#else\t/* PJ_DLL */\n\nextern pjsip_cfg_t pjsip_sip_cfg_var;\n\n/**\n * Get pjsip configuration instance. Application may modify the\n * settings before creating the SIP endpoint and modules.\n *\n * @return  Configuration instance.\n */\nPJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)\n{\n    return &pjsip_sip_cfg_var;\n}\n\n#endif\t/* PJ_DLL */\n\n\n/**\n * Specify maximum transaction count in transaction hash table.\n * For efficiency, the value should be 2^n-1 since it will be\n * rounded up to 2^n.\n *\n * Default value is 1023\n */\n#ifndef PJSIP_MAX_TSX_COUNT\n#   define PJSIP_MAX_TSX_COUNT\t\t(1024-1)\n#endif\n\n/**\n * Specify maximum number of dialogs in the dialog hash table.\n * For efficiency, the value should be 2^n-1 since it will be\n * rounded up to 2^n.\n *\n * Default value is 511.\n */\n#ifndef PJSIP_MAX_DIALOG_COUNT\n#   define PJSIP_MAX_DIALOG_COUNT\t(512-1)\n#endif\n\n\n/**\n * Specify maximum number of transports.\n * Default value is equal to maximum number of handles in ioqueue.\n * See also PJSIP_TPMGR_HTABLE_SIZE.\n */\n#ifndef PJSIP_MAX_TRANSPORTS\n#   define PJSIP_MAX_TRANSPORTS\t\t(PJ_IOQUEUE_MAX_HANDLES)\n#endif\n\n\n/**\n * Transport manager hash table size (must be 2^n-1). \n * See also PJSIP_MAX_TRANSPORTS\n */\n#ifndef PJSIP_TPMGR_HTABLE_SIZE\n#   define PJSIP_TPMGR_HTABLE_SIZE\t31\n#endif\n\n\n/**\n * Specify maximum URL size.\n */\n#ifndef PJSIP_MAX_URL_SIZE\n#   define PJSIP_MAX_URL_SIZE\t\t256\n#endif\n\n\n/**\n * Specify maximum number of modules.\n * This mainly affects the size of mod_data array in various components.\n */\n#ifndef PJSIP_MAX_MODULE\n#   define PJSIP_MAX_MODULE\t\t32\n#endif\n\n\n/**\n * Maximum packet length. We set it more than MTU since a SIP PDU\n * containing presence information can be quite large (>1500).\n */\n#ifndef PJSIP_MAX_PKT_LEN\n#   define PJSIP_MAX_PKT_LEN\t\t4000\n#endif\n\n\n/**\n * RFC 3261 section 18.1.1:\n * If a request is within 200 bytes of the path MTU, or if it is larger\n * than 1300 bytes and the path MTU is unknown, the request MUST be sent\n * using an RFC 2914 [43] congestion controlled transport protocol, such\n * as TCP.\n *\n * Disable the behavior of automatic switching to TCP whenever UDP packet\n * size exceeds the threshold defined in PJSIP_UDP_SIZE_THRESHOLD.\n *\n * This option can also be controlled at run-time by the \\a disable_tcp_switch\n * setting in pjsip_cfg_t.\n *\n * Default is 0 (no).\n */\n#ifndef PJSIP_DONT_SWITCH_TO_TCP\n#   define PJSIP_DONT_SWITCH_TO_TCP\t0\n#endif\n\n\n/**\n * As specified RFC 3261 section 8.1.2, when request-URI uses \"sips\" scheme,\n * TLS must always be used regardless of the target-URI scheme or transport\n * type.\n *\n * This option will specify whether the behavior of automatic switching to TLS\n * should be disabled, i.e: regard the target-URI scheme or transport type.\n *\n * This option can also be controlled at run-time by the \\a disable_tls_switch\n * setting in pjsip_cfg_t.\n *\n * Default is 0 (no).\n */\n#ifndef PJSIP_DONT_SWITCH_TO_TLS\n#   define PJSIP_DONT_SWITCH_TO_TLS\t0\n#endif\n\n\n/**\n * Specify whether the call media session should be updated to the latest\n * received early media SDP when receiving forked early media (multiple 183\n * responses with different To tag).\n *\n * This option can also be controlled at run-time by the\n * \\a follow_early_media_fork setting in pjsip_cfg_t.\n *\n * Default is PJ_TRUE.\n */\n#ifndef PJSIP_FOLLOW_EARLY_MEDIA_FORK\n#   define PJSIP_FOLLOW_EARLY_MEDIA_FORK\t    PJ_TRUE\n#endif\n\n\n/**\n * Specify whether \"alias\" param should be added to the Via header\n * in any outgoing request with connection oriented transport.\n *\n * This option can also be controlled at run-time by the\n * \\a req_has_via_alias setting in pjsip_cfg_t.\n *\n * Default is PJ_TRUE.\n */\n#ifndef PJSIP_REQ_HAS_VIA_ALIAS\n#   define PJSIP_REQ_HAS_VIA_ALIAS\t\t    PJ_TRUE\n#endif\n\n/**\n * Resolve hostname when trying to get the network interface to be put in Via \n * or Contact header.\n *\n * This option can also be controlled at run-time by the\n * \\a resolve_hostname_to_get_interface setting in pjsip_cfg_t.\n *\n * Default is PJ_FALSE.\n */\n#ifndef PJSIP_RESOLVE_HOSTNAME_TO_GET_INTERFACE\n#   define PJSIP_RESOLVE_HOSTNAME_TO_GET_INTERFACE  PJ_FALSE\n#endif\n\n/**\n * Accept call replace in early state when invite is not initiated\n * by the user agent. RFC 3891 Section 3 disallows this, however,\n * for better interoperability reason, this might be ignored.\n *\n * This option can also be controlled at run-time by the\n * \\a accept_replace_in_early_state setting in pjsip_cfg_t.\n *\n * Default is 0 (no).\n */\n#ifndef PJSIP_ACCEPT_REPLACE_IN_EARLY_STATE\n#   define PJSIP_ACCEPT_REPLACE_IN_EARLY_STATE\t    0\n#endif\n\n\n/**\n * This setting controls the threshold of the UDP packet, which if it's\n * larger than this value the request will be sent with TCP. This setting\n * is useful only when PJSIP_DONT_SWITCH_TO_TCP is set to 0.\n *\n * Default is 1300 bytes.\n */\n#ifndef PJSIP_UDP_SIZE_THRESHOLD\n#   define PJSIP_UDP_SIZE_THRESHOLD\t1300\n#endif\n\n\n/**\n * Encode SIP headers in their short forms to reduce size. By default,\n * SIP headers in outgoing messages will be encoded in their full names. \n * If this option is enabled, then SIP headers for outgoing messages\n * will be encoded in their short forms, to reduce message size. \n * Note that this does not affect the ability of PJSIP to parse incoming\n * SIP messages, as the parser always supports parsing both the long\n * and short version of the headers.\n *\n * Note that there is also an undocumented variable defined in sip_msg.c\n * to control whether compact form should be used for encoding SIP\n * headers. The default value of this variable is PJSIP_ENCODE_SHORT_HNAME.\n * To change PJSIP behavior during run-time, application can use the \n * following construct:\n *\n \\verbatim\n   extern pj_bool_t pjsip_use_compact_form;\n \n   // enable compact form\n   pjsip_use_compact_form = PJ_TRUE;\n \\endverbatim\n *\n * Default is 0 (no)\n */\n#ifndef PJSIP_ENCODE_SHORT_HNAME\n#   define PJSIP_ENCODE_SHORT_HNAME\t0\n#endif\n\n\n/**\n * Send Allow header in dialog establishing requests?\n * RFC 3261 Allow header SHOULD be included in dialog establishing\n * requests to inform remote agent about which SIP requests are\n * allowed within dialog.\n *\n * Note that there is also an undocumented variable defined in sip_dialog.c\n * to control whether Allow header should be included. The default value \n * of this variable is PJSIP_INCLUDE_ALLOW_HDR_IN_DLG.\n * To change PJSIP behavior during run-time, application can use the \n * following construct:\n *\n \\verbatim\n   extern pj_bool_t pjsip_include_allow_hdr_in_dlg;\n \n   // do not transmit Allow header\n   pjsip_include_allow_hdr_in_dlg = PJ_FALSE;\n \\endverbatim\n *\n * Default is 1 (Yes)\n */\n#ifndef PJSIP_INCLUDE_ALLOW_HDR_IN_DLG\n#   define PJSIP_INCLUDE_ALLOW_HDR_IN_DLG\t1\n#endif\n\n\n/**\n * Allow SIP modules removal or insertions during operation?\n * If yes, then locking will be employed when endpoint need to\n * access module.\n */\n#ifndef PJSIP_SAFE_MODULE\n#   define PJSIP_SAFE_MODULE\t\t1\n#endif\n\n\n/**\n * Perform Via sent-by checking as specified in RFC 3261 Section 18.1.2,\n * which says that UAC MUST silently discard responses with Via sent-by\n * containing values that the UAC doesn't recognize as its transport\n * address.\n *\n * In PJSIP, this will cause response to be discarded and a message is\n * written to the log, saying something like:\n *  \"Dropping response Response msg 200/INVITE/cseq=608594373 (rdata00A99EF4)\n *   from 1.2.3.4:5060 because sent-by is mismatch\"\n *\n * The default behavior is yes, but when the UA supports IP address change\n * for the SIP transport, it will need to turn this checking off since\n * when the transport address is changed between request is sent and \n * response is received, the response will be discarded since its Via\n * sent-by now contains address that is different than the transport\n * address.\n *\n * Update:\n * As of version 2.1, the default value is 0. This change was part of\n * https://trac.pjsip.org/repos/ticket/1412\n */\n#ifndef PJSIP_CHECK_VIA_SENT_BY\n#   define PJSIP_CHECK_VIA_SENT_BY\t0\n#endif\n\n\n/**\n * If non-zero, SIP parser will unescape the escape characters ('%')\n * in the original message, which means that it will modify the\n * original message. Otherwise the parser will create a copy of\n * the string and store the unescaped string to the new location.\n *\n * Unescaping in-place is faster, but less elegant (and it may\n * break certain applications). So normally it's disabled, unless\n * when benchmarking (to show off big performance).\n *\n * Default: 0\n */\n#ifndef PJSIP_UNESCAPE_IN_PLACE\n#   define PJSIP_UNESCAPE_IN_PLACE\t0\n#endif\n\n\n/**\n * Specify port number should be allowed to appear in To and From\n * header. Note that RFC 3261 disallow this, see Table 1 in section\n * 19.1.1 of the RFC. This setting can also be altered at run-time\n * via pjsip_cfg setting, see pjsip_cfg_t.allow_port_in_fromto_hdr\n * field.\n *\n * Default: 0\n */\n#ifndef PJSIP_ALLOW_PORT_IN_FROMTO_HDR\n#   define PJSIP_ALLOW_PORT_IN_FROMTO_HDR\t0\n#endif\n\n/**\n * This macro controls maximum numbers of ioqueue events to be processed\n * in a single pjsip_endpt_handle_events() poll. When PJSIP detects that\n * there are probably more events available from the network and total\n * events so far is less than this value, PJSIP will call pj_ioqueue_poll()\n * again to get more events.\n *\n * Value 1 works best for ioqueue with select() back-end, while for IOCP it is\n * probably best to set this value equal to PJSIP_MAX_TIMED_OUT_ENTRIES\n * since IOCP only processes one event at a time.\n *\n * Default: 1\n */\n#ifndef PJSIP_MAX_NET_EVENTS\n#   define PJSIP_MAX_NET_EVENTS\t\t1\n#endif\n\n\n/**\n * Max entries to process in timer heap per poll. \n * \n * Default: 10\n */\n#ifndef PJSIP_MAX_TIMED_OUT_ENTRIES\n#   define PJSIP_MAX_TIMED_OUT_ENTRIES\t10\n#endif\n\n\n/**\n * Idle timeout interval to be applied to outgoing transports (i.e. client\n * side) with no usage before the transport is destroyed. Value is in\n * seconds.\n *\n * Note that if the value is put lower than 33 seconds, it may cause some\n * pjsip test units to fail. See the comment on the following link:\n * https://trac.pjsip.org/repos/ticket/1465#comment:4\n *\n * Default: 33\n */\n#ifndef PJSIP_TRANSPORT_IDLE_TIME\n#   define PJSIP_TRANSPORT_IDLE_TIME\t33\n#endif\n\n\n/**\n * Idle timeout interval to be applied to incoming transports (i.e. server\n * side) with no usage before the transport is destroyed. Server typically\n * should let client close the connection, hence set this interval to a large\n * value. Value is in seconds.\n *\n * Default: 600\n */\n#ifndef PJSIP_TRANSPORT_SERVER_IDLE_TIME\n#   define PJSIP_TRANSPORT_SERVER_IDLE_TIME\t600\n#endif\n\n\n/**\n * Maximum number of usages for a transport before a new transport is\n * created. This only applies for ephemeral transports such as TCP.\n *\n * Currently this is not used.\n * \n * Default: -1\n */\n#ifndef PJSIP_MAX_TRANSPORT_USAGE\n#   define PJSIP_MAX_TRANSPORT_USAGE\t((unsigned)-1)\n#endif\n\n\n/**\n * The TCP incoming connection backlog number to be set in accept().\n *\n * Default: 5\n *\n * @see PJSIP_TLS_TRANSPORT_BACKLOG\n */\n#ifndef PJSIP_TCP_TRANSPORT_BACKLOG\n#   define PJSIP_TCP_TRANSPORT_BACKLOG\t5\n#endif\n\n\n/**\n * Specify whether TCP listener should use SO_REUSEADDR option. This constant\n * will be used as the default value for the \"reuse_addr\" field in the\n * pjsip_tcp_transport_cfg structure.\n *\n * Default is FALSE on Windows and TRUE on non-Windows.\n *\n * @see PJSIP_TLS_TRANSPORT_REUSEADDR\n */\n#ifndef PJSIP_TCP_TRANSPORT_REUSEADDR\n# if (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_WIN64) && PJ_WIN64)\n#   define PJSIP_TCP_TRANSPORT_REUSEADDR\t0\n# else\n#   define PJSIP_TCP_TRANSPORT_REUSEADDR\t1\n# endif\n#endif\n\n\n/**\n * Specify whether TCP transport should skip creating the listener.\n * Not having a listener means that application will not be able to\n * function in server mode and accept incoming connections.\n *\n * When enabling this setting, if you use PJSUA, it is recommended to set \n * pjsua_acc_config.contact_use_src_port to PJ_TRUE.\n * Warning: If contact_use_src_port is disabled or failed (because it's\n * unsupported in some platforms or automatically turned off due to\n * DNS server resolution), Contact header will be generated from\n * pj_getipinterface()/pj_gethostip(), but the address will not be\n * able to accept connections. \n *\n * Default is FALSE (listener will be created).\n */\n#ifndef PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER\n#   define PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER 0\n#endif\n\n\n/**\n * Specify whether TLS transport should skip creating the listener.\n * Not having a listener means that application will not be able to\n * function in server mode and accept incoming connections.\n *\n * When enabling this setting, if you use PJSUA, it is recommended to set \n * pjsua_acc_config.contact_use_src_port to PJ_TRUE.\n * Warning: If contact_use_src_port is disabled or failed (because it's\n * unsupported in some platforms or automatically turned off due to\n * DNS server resolution), Contact header will be generated from\n * pj_getipinterface()/pj_gethostip(), but the address will not be\n * able to accept connections.\n *\n * Default is FALSE (listener will be created).\n */\n#ifndef PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER\n#   define PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER 0\n#endif\n\n\n/**\n * Set the interval to send keep-alive packet for TCP transports.\n * If the value is zero, keep-alive will be disabled for TCP.\n *\n * This option can be changed in run-time by settting\n * \\a tcp.keep_alive_interval field of pjsip_cfg().\n *\n * Default: 90 (seconds)\n *\n * @see PJSIP_TCP_KEEP_ALIVE_DATA\n */\n#ifndef PJSIP_TCP_KEEP_ALIVE_INTERVAL\n#   define PJSIP_TCP_KEEP_ALIVE_INTERVAL    90\n#endif\n\n\n/**\n * Set the payload of the TCP keep-alive packet.\n *\n * Default: CRLF\n */\n#ifndef PJSIP_TCP_KEEP_ALIVE_DATA\n#   define PJSIP_TCP_KEEP_ALIVE_DATA\t    { \"\\r\\n\\r\\n\", 4 }\n#endif\n\n\n/**\n * Set the interval to send keep-alive packet for TLS transports.\n * If the value is zero, keep-alive will be disabled for TLS.\n *\n * This option can be changed in run-time by settting\n * \\a tls.keep_alive_interval field of pjsip_cfg().\n *\n * Default: 90 (seconds)\n *\n * @see PJSIP_TLS_KEEP_ALIVE_DATA\n */\n#ifndef PJSIP_TLS_KEEP_ALIVE_INTERVAL\n#   define PJSIP_TLS_KEEP_ALIVE_INTERVAL    90\n#endif\n\n\n/**\n * Set the payload of the TLS keep-alive packet.\n *\n * Default: CRLF\n */\n#ifndef PJSIP_TLS_KEEP_ALIVE_DATA\n#   define PJSIP_TLS_KEEP_ALIVE_DATA\t    { \"\\r\\n\\r\\n\", 4 }\n#endif\n\n\n/**\n * This macro specifies whether full DNS resolution should be used.\n * When enabled, #pjsip_resolve() will perform asynchronous DNS SRV and\n * A (or AAAA, when IPv6 is supported) resolution to resolve the SIP\n * domain.\n *\n * Note that even when this setting is enabled, asynchronous DNS resolution\n * will only be done when application calls #pjsip_endpt_create_resolver(),\n * configure the nameservers with pj_dns_resolver_set_ns(), and configure\n * the SIP endpoint's DNS resolver with #pjsip_endpt_set_resolver(). If\n * these steps are not followed, the domain will be resolved with normal\n * pj_gethostbyname() function.\n *\n * Turning off this setting will save the footprint by about 16KB, since\n * it should also exclude dns.o and resolve.o from PJLIB-UTIL.\n *\n * Default: 1 (enabled)\n *\n * @see PJSIP_MAX_RESOLVED_ADDRESSES\n */\n#ifndef PJSIP_HAS_RESOLVER\n#   define PJSIP_HAS_RESOLVER\t\t1\n#endif\n\n\n/** \n * Maximum number of addresses returned by the resolver. The number here \n * will slightly affect stack usage, since each entry will occupy about\n * 32 bytes of stack memory.\n *\n * Default: 8\n *\n * @see PJSIP_HAS_RESOLVER\n */\n#ifndef PJSIP_MAX_RESOLVED_ADDRESSES\n#   define PJSIP_MAX_RESOLVED_ADDRESSES\t    8\n#endif\n\n\n/**\n * Enable TLS SIP transport support. For most systems this means that\n * OpenSSL must be installed.\n *\n * Default: follow PJ_HAS_SSL_SOCK setting, which is 0 (disabled) by default.\n */\n#ifndef PJSIP_HAS_TLS_TRANSPORT\n#   define PJSIP_HAS_TLS_TRANSPORT          PJ_HAS_SSL_SOCK\n#endif\n\n\n/**\n * The TLS pending incoming connection backlog number to be set in accept().\n *\n * Default: 5\n *\n * @see PJSIP_TCP_TRANSPORT_BACKLOG\n */\n#ifndef PJSIP_TLS_TRANSPORT_BACKLOG\n#   define PJSIP_TLS_TRANSPORT_BACKLOG\t    5\n#endif\n\n\n/**\n * Specify whether TLS listener should use SO_REUSEADDR option.\n *\n * Default is FALSE on Windows and TRUE on non-Windows.\n *\n * @see PJSIP_TCP_TRANSPORT_REUSEADDR\n */\n#ifndef PJSIP_TLS_TRANSPORT_REUSEADDR\n# if (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_WIN64) && PJ_WIN64)\n#   define PJSIP_TLS_TRANSPORT_REUSEADDR\t0\n# else\n#   define PJSIP_TLS_TRANSPORT_REUSEADDR\t1\n# endif\n#endif\n\n\n/* Endpoint. */\n#define PJSIP_MAX_TIMER_COUNT\t\t(2*pjsip_cfg()->tsx.max_count + \\\n\t\t\t\t\t 2*PJSIP_MAX_DIALOG_COUNT)\n\n/**\n * Initial memory block for the endpoint.\n */\n#ifndef PJSIP_POOL_LEN_ENDPT\n#   define PJSIP_POOL_LEN_ENDPT\t\t(4000)\n#endif\n\n/**\n * Memory increment for endpoint.\n */\n#ifndef PJSIP_POOL_INC_ENDPT\n#   define PJSIP_POOL_INC_ENDPT\t\t(4000)\n#endif\n\n\n/* Transport related constants. */\n\n/**\n * Initial memory block for rdata.\n */\n#ifndef PJSIP_POOL_RDATA_LEN\n#   define PJSIP_POOL_RDATA_LEN\t\t4000\n#endif\n\n/**\n * Memory increment for rdata.\n */\n#ifndef PJSIP_POOL_RDATA_INC\n#   define PJSIP_POOL_RDATA_INC\t\t4000\n#endif\n\n#define PJSIP_POOL_LEN_TRANSPORT\t512\n#define PJSIP_POOL_INC_TRANSPORT\t512\n\n/**\n * Initial memory block size for tdata.\n */\n#ifndef PJSIP_POOL_LEN_TDATA\n#   define PJSIP_POOL_LEN_TDATA\t\t4000\n#endif\n\n/**\n * Memory increment for tdata.\n */\n#ifndef PJSIP_POOL_INC_TDATA\n#   define PJSIP_POOL_INC_TDATA\t\t4000\n#endif\n\n/**\n * Initial memory size for UA layer\n */\n#ifndef PJSIP_POOL_LEN_UA\n#   define PJSIP_POOL_LEN_UA\t\t512\n#endif\n\n/**\n * Memory increment for UA layer.\n */\n#ifndef PJSIP_POOL_INC_UA\n#   define PJSIP_POOL_INC_UA\t\t512\n#endif\n\n#define PJSIP_MAX_FORWARDS_VALUE\t70\n\n#define PJSIP_RFC3261_BRANCH_ID\t\t\"z9hG4bK\"\n#define PJSIP_RFC3261_BRANCH_LEN\t7\n\n/* Transaction related constants. */\n\n/**\n * Initial memory size for transaction layer. The bulk of pool usage\n * for transaction layer will be used to create the hash table, so \n * setting this value too high will not help too much with reducing\n * fragmentation and the memory will most likely be wasted.\n */\n#ifndef PJSIP_POOL_TSX_LAYER_LEN\n#   define PJSIP_POOL_TSX_LAYER_LEN\t512\n#endif\n\n/**\n * Memory increment for transaction layer. The bulk of pool usage\n * for transaction layer will be used to create the hash table, so \n * setting this value too high will not help too much with reducing\n * fragmentation and the memory will most likely be wasted.\n */\n#ifndef PJSIP_POOL_TSX_LAYER_INC\n#   define PJSIP_POOL_TSX_LAYER_INC\t512\n#endif\n\n/**\n * Initial memory size for a SIP transaction object.\n */\n#ifndef PJSIP_POOL_TSX_LEN\n#   define PJSIP_POOL_TSX_LEN\t\t1536 /* 768 */\n#endif\n\n/**\n * Memory increment for transaction object.\n */\n#ifndef PJSIP_POOL_TSX_INC\n#   define PJSIP_POOL_TSX_INC\t\t256\n#endif\n\n/**\n * Delay for non-100 1xx retransmission, in seconds.\n * Set to 0 to disable this feature.\n *\n * Default: 60 seconds\n */\n#ifndef PJSIP_TSX_1XX_RETRANS_DELAY\n#   define PJSIP_TSX_1XX_RETRANS_DELAY\t60\n#endif\n\n#define PJSIP_MAX_TSX_KEY_LEN\t\t(PJSIP_MAX_URL_SIZE*2)\n\n/* User agent. */\n#define PJSIP_POOL_LEN_USER_AGENT\t1024\n#define PJSIP_POOL_INC_USER_AGENT\t1024\n\n/* Message/URL related constants. */\n#define PJSIP_MAX_CALL_ID_LEN\t\tpj_GUID_STRING_LENGTH()\n#define PJSIP_MAX_TAG_LEN\t\tpj_GUID_STRING_LENGTH()\n#define PJSIP_MAX_BRANCH_LEN\t\t(PJSIP_RFC3261_BRANCH_LEN + pj_GUID_STRING_LENGTH() + 2)\n#define PJSIP_MAX_HNAME_LEN\t\t64\n\n/* Dialog related constants. */\n#define PJSIP_POOL_LEN_DIALOG\t\t1200\n#define PJSIP_POOL_INC_DIALOG\t\t512\n\n/* Maximum header types. */\n#define PJSIP_MAX_HEADER_TYPES\t\t72\n\n/* Maximum URI types. */\n#define PJSIP_MAX_URI_TYPES\t\t4\n\n/*****************************************************************************\n *  Default timeout settings, in miliseconds. \n */\n\n/** Transaction T1 timeout value. */\n#if !defined(PJSIP_T1_TIMEOUT)\n#  define PJSIP_T1_TIMEOUT\t500\n#endif\n\n/** Transaction T2 timeout value. */\n#if !defined(PJSIP_T2_TIMEOUT)\n#  define PJSIP_T2_TIMEOUT\t4000\n#endif\n\n/** Transaction completed timer for non-INVITE */\n#if !defined(PJSIP_T4_TIMEOUT)\n#  define PJSIP_T4_TIMEOUT\t5000\n#endif\n\n/** Transaction completed timer for INVITE */\n#if !defined(PJSIP_TD_TIMEOUT)\n#  define PJSIP_TD_TIMEOUT\t32000\n#endif\n\n\n/*****************************************************************************\n *  Authorization\n */\n\n/**\n * If this flag is set, the stack will keep the Authorization/Proxy-Authorization\n * headers that are sent in a cache. Future requests with the same realm and\n * the same method will use the headers in the cache (as long as no qop is\n * required by server).\n *\n * Turning on this flag will make authorization process goes faster, but\n * will grow the memory usage undefinitely until the dialog/registration\n * session is terminated.\n *\n * Default: 0\n */\n#if !defined(PJSIP_AUTH_HEADER_CACHING)\n#   define PJSIP_AUTH_HEADER_CACHING\t    0\n#endif\n\n/**\n * If this flag is set, the stack will proactively send Authorization/Proxy-\n * Authorization header for next requests. If next request has the same method\n * with any of previous requests, then the last header which is saved in\n * the cache will be used (if PJSIP_AUTH_CACHING is set). Otherwise a fresh\n * header will be recalculated. If a particular server has requested qop, then\n * a fresh header will always be calculated.\n *\n * If this flag is NOT set, then the stack will only send Authorization/Proxy-\n * Authorization headers when it receives 401/407 response from server.\n *\n * Turning ON this flag will grow memory usage of a dialog/registration pool\n * indefinitely until it is terminated, because the stack needs to keep the\n * last WWW-Authenticate/Proxy-Authenticate challenge.\n *\n * Default: 0\n */\n#if !defined(PJSIP_AUTH_AUTO_SEND_NEXT)\n#   define PJSIP_AUTH_AUTO_SEND_NEXT\t    0\n#endif\n\n/**\n * Support qop=\"auth\" directive.\n * This option also requires client to cache the last challenge offered by\n * server.\n *\n * Default: 1\n */\n#if !defined(PJSIP_AUTH_QOP_SUPPORT)\n#   define PJSIP_AUTH_QOP_SUPPORT\t    1\n#endif\n\n\n/**\n * Maximum number of stale retries when server keeps rejecting our request\n * with stale=true.\n *\n * Default: 3\n */\n#ifndef PJSIP_MAX_STALE_COUNT\n#   define PJSIP_MAX_STALE_COUNT\t    3\n#endif\n\n\n/**\n * Specify support for IMS/3GPP digest AKA authentication version 1 and 2\n * (AKAv1-MD5 and AKAv2-MD5 respectively).\n *\n * Note that if this is enabled, application would need to link with\n * <b>libmilenage</b> library from \\a third_party directory.\n *\n * Default: 0 (for now)\n */\n#ifndef PJSIP_HAS_DIGEST_AKA_AUTH\n#   define PJSIP_HAS_DIGEST_AKA_AUTH\t    0\n#endif\n\n\n/**\n * Specify the number of seconds to refresh the client registration\n * before the registration expires.\n *\n * Default: 5 seconds\n */\n#ifndef PJSIP_REGISTER_CLIENT_DELAY_BEFORE_REFRESH\n#   define PJSIP_REGISTER_CLIENT_DELAY_BEFORE_REFRESH  5\n#endif\n\n\n/**\n * Specify whether client registration should check for its registered\n * contact in Contact header of successful REGISTE response to determine\n * whether registration has been successful. This setting may be disabled\n * if non-compliant registrar is unable to return correct Contact header.\n *\n * This setting can be changed in run-time by settting \\a regc.check_contact\n * field of pjsip_cfg().\n *\n * Default is 1\n */\n#ifndef PJSIP_REGISTER_CLIENT_CHECK_CONTACT\n#   define PJSIP_REGISTER_CLIENT_CHECK_CONTACT\t1\n#endif\n\n\n/**\n * Specify whether client registration should add \"x-uid\" extension\n * parameter in all Contact URIs that it registers to assist the\n * matching of Contact URIs in the 200/OK REGISTER response, in \n * case the registrar is unable to return exact Contact URI in the\n * 200/OK response.\n *\n * This setting can be changed in run-time by setting \n * \\a regc.add_xuid_param field of pjsip_cfg().\n *\n * Default is 0.\n */\n#ifndef PJSIP_REGISTER_CLIENT_ADD_XUID_PARAM\n#   define PJSIP_REGISTER_CLIENT_ADD_XUID_PARAM\t0\n#endif\n\n\n/*****************************************************************************\n *  SIP Event framework and presence settings.\n */\n\n/**\n * Specify the time (in seconds) to send SUBSCRIBE to refresh client \n * subscription before the actual interval expires.\n *\n * Default: 5 seconds\n */\n#ifndef PJSIP_EVSUB_TIME_UAC_REFRESH\n#   define PJSIP_EVSUB_TIME_UAC_REFRESH\t\t5\n#endif\n\n\n/**\n * Specify the time (in seconds) to send PUBLISH to refresh client \n * publication before the actual interval expires.\n *\n * Default: 5 seconds\n */\n#ifndef PJSIP_PUBLISHC_DELAY_BEFORE_REFRESH\n#   define PJSIP_PUBLISHC_DELAY_BEFORE_REFRESH\t5\n#endif\n\n\n/**\n * Specify the time (in seconds) to wait for the final NOTIFY from the\n * server after client has sent un-SUBSCRIBE request.\n *\n * Default: 5 seconds\n */\n#ifndef PJSIP_EVSUB_TIME_UAC_TERMINATE\n#   define PJSIP_EVSUB_TIME_UAC_TERMINATE\t5\n#endif\n\n\n/**\n * Specify the time (in seconds) for client subscription to wait for another\n * NOTIFY from the server, if it has rejected the last NOTIFY with non-2xx\n * final response (such as 401). If further NOTIFY is not received within\n * this period, the client will unsubscribe.\n *\n * Default: 5 seconds\n */\n#ifndef PJSIP_EVSUB_TIME_UAC_WAIT_NOTIFY\n#   define PJSIP_EVSUB_TIME_UAC_WAIT_NOTIFY\t5\n#endif\n\n\n/**\n * Specify the default expiration time for presence event subscription, for\n * both client and server subscription. For client subscription, application\n * can override this by specifying positive non-zero value in \"expires\" \n * parameter when calling #pjsip_pres_initiate(). For server subscription,\n * we would take the expiration value from the Expires header sent by client\n * in the SUBSCRIBE request if the header exists and its value is less than \n * this setting, otherwise this setting will be used.\n *\n * Default: 600 seconds (10 minutes)\n */\n#ifndef PJSIP_PRES_DEFAULT_EXPIRES\n#   define PJSIP_PRES_DEFAULT_EXPIRES\t\t600\n#endif\n\n\n/**\n * Specify the status code value to respond to bad message body in NOTIFY\n * request for presence. Scenarios that are considered bad include non-\n * PIDF/XML and non-XPIDF/XML body, multipart message bodies without PIDF/XML\n * nor XPIDF/XML part, and bad (parsing error) PIDF and X-PIDF bodies\n * themselves.\n *\n * Default value is 488. Application may change this to 200 to ignore the\n * unrecognised content (this is useful if the application wishes to handle\n * the content itself). Only non-3xx final response code is allowed here.\n *\n * Default: 488 (Not Acceptable Here)\n */\n#ifndef PJSIP_PRES_BAD_CONTENT_RESPONSE\n#   define PJSIP_PRES_BAD_CONTENT_RESPONSE\t488\n#endif\n\n\n/**\n * Add \"timestamp\" information in generated PIDF document for both server\n * subscription and presence publication.\n *\n * Default: 1 (yes)\n */\n#ifndef PJSIP_PRES_PIDF_ADD_TIMESTAMP\n#   define PJSIP_PRES_PIDF_ADD_TIMESTAMP\t1\n#endif\n\n\n/**\n * Default session interval for Session Timer (RFC 4028) extension, in\n * seconds. As specified in RFC 4028 Section 4, this value must not be \n * less than the absolute minimum for the Session-Expires header field\n * 90 seconds, and the recommended value is 1800 seconds.\n *\n * Default: 1800 seconds\n */\n#ifndef PJSIP_SESS_TIMER_DEF_SE\n#   define PJSIP_SESS_TIMER_DEF_SE\t\t1800\n#endif\n\n\n/**\n * Specify whether the client publication session should queue the\n * PUBLISH request should there be another PUBLISH transaction still\n * pending. If this is set to false, the client will return error\n * on the PUBLISH request if there is another PUBLISH transaction still\n * in progress.\n *\n * Default: 1 (yes)\n */\n#ifndef PJSIP_PUBLISHC_QUEUE_REQUEST\n#   define PJSIP_PUBLISHC_QUEUE_REQUEST\t\t1\n#endif\n\n\n/**\n * Specify the default expiration time for Message Waiting Indication\n * (RFC 3842) event subscription, for both client and server subscription.\n * For client subscription, application can override this by specifying\n * positive non-zero value in \"expires\" parameter when calling\n * #pjsip_mwi_initiate(). For server subscription, we would take the\n * expiration value from the Expires header sent by client in the SUBSCRIBE\n * request if the header exists and its value is less than  this setting,\n * otherwise this setting will be used.\n *\n * Default: 3600 seconds\n */\n#ifndef PJSIP_MWI_DEFAULT_EXPIRES\n#   define PJSIP_MWI_DEFAULT_EXPIRES\t\t3600\n#endif\n\n\n/**\n * Specify whether transport manager should maintain a list of transmit\n * buffer instances, so any possible dangling instance can be cleaned up\n * when the transport manager is shutdown (see also ticket #1671).\n * Note that this feature will have slight impact on the performance as\n * mutex is employed in updating the list, i.e: on creation and destruction\n * of transmit data.\n *\n * Default: 0 (no)\n */\n#ifndef PJSIP_HAS_TX_DATA_LIST\n#   define PJSIP_HAS_TX_DATA_LIST\t\t0\n#endif\n\n/** \n * Specify whether to accept INVITE/re-INVITE with unknown content type,\n * by default the stack will reject this type of message as specified in \n * RFC3261 section 8.2.3.\n * Application that wishes to process the body could set this to PJ_TRUE,\n * be informed that SDP offer/answer will still be present.\n *\n * Default: PJ_FALSE\n */\n#ifndef PJSIP_INV_ACCEPT_UNKNOWN_BODY\n#   define PJSIP_INV_ACCEPT_UNKNOWN_BODY    PJ_FALSE\n#endif\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#include <pj/config.h>\n\n\n#endif\t/* __PJSIP_SIP_CONFIG_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_dialog.h",
    "content": "/* $Id: sip_dialog.h 4173 2012-06-20 10:39:05Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_DIALOG_H__\n#define __PJSIP_SIP_DIALOG_H__\n\n\n/**\n * @file sip_dialog.h\n * @brief SIP Dialog abstraction\n */\n\n#include <pjsip/sip_msg.h>\n#include <pjsip/sip_auth.h>\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_transport.h>\n#include <pjsip/sip_util.h>\n#include <pj/sock.h>\n#include <pj/assert.h>\n\n\n/**\n * @defgroup PJSIP_DIALOG Base Dialog\n * @ingroup PJSIP_UA\n * @brief The base dialog framework to support dialog usages.\n * @{\n *\n * The base dialog framework provides management for base dialog\n * properties such as <b>From</b> header, <b>To</b> header, <b>CSeq</b>\n * sequencing, <b>Call-ID</b> header, <b>Contact</b> header management, \n * dialog <b>route-set</b> management, and common <b>authentication</b>. \n * This basic dialog functionality will be shared by all <b>dialog\n * usages</b> of a particular dialog.\n *\n * More detailed information is explained in\n * <A HREF=\"/docs.htm\">PJSIP Developer's Guide</A>\n * PDF document, and readers are encouraged to read the document to\n * get the concept behind dialog, dialog usages, and INVITE sessions.\n *\n * Application MUST initialize the user agent layer module by calling\n * #pjsip_ua_init_module() before using any of the dialog API, and link\n * the application with with <b>pjsip-core</b> library.\n */\n\nPJ_BEGIN_DECL\n\n\n/* Deprecated API pjsip_dlg_create_uas() due to a fatal bug of possible\n * premature dialog destroy. Application should not change this setting,\n * unless it uses single worker thread.\n * See also https://trac.pjsip.org/repos/ticket/1902.\n */\n#ifndef DEPRECATED_FOR_TICKET_1902\n#  define DEPRECATED_FOR_TICKET_1902      1\n#endif\n\n/**\n * This structure is used to describe dialog's participants, which in this\n * case is local party (i.e. us) and remote party.\n */\ntypedef struct pjsip_dlg_party\n{\n    pjsip_fromto_hdr\t*info;\t    /**< From/To header, inc tag.\t*/\n    pj_str_t\t\t info_str;  /**< String rep of info header.\t*/\n    pj_uint32_t\t\t tag_hval;  /**< Hashed value of the tag.\t*/\n    pjsip_contact_hdr\t*contact;   /**< Contact header.\t\t*/\n    pj_int32_t\t\t first_cseq;/**< First CSeq seen.\t\t*/\n    pj_int32_t\t\t cseq;\t    /**< Next sequence number.\t\t*/\n} pjsip_dlg_party;\n\n\n/**\n * Dialog state.\n */\ntypedef enum pjsip_dialog_state\n{\n    /** Dialog is not established. */\n    PJSIP_DIALOG_STATE_NULL,\n\n    /** Dialog has been established (probably early) */\n    PJSIP_DIALOG_STATE_ESTABLISHED\n} pjsip_dialog_state;\n\n\n/**\n * Dialog capability status.\n */\ntypedef enum pjsip_dialog_cap_status\n{\n    /** Capability is unsupported. */\n    PJSIP_DIALOG_CAP_UNSUPPORTED    = 0,\n\n    /** Capability is supported */\n    PJSIP_DIALOG_CAP_SUPPORTED\t    = 1,\n\n    /** \n     *  Unknown capability status. This is usually because we lack the \n     *  capability info which is retrieved from capability header specified\n     *  in the dialog messages.\n     */\n    PJSIP_DIALOG_CAP_UNKNOWN\t    = 2\n} pjsip_dialog_cap_status;\n\n\n/**\n * This structure describes the dialog structure. Application MUST NOT\n * try to SET the values here directly, but instead it MUST use the\n * appropriate dialog API. The dialog declaration only needs to be made \n * visible because other PJSIP modules need to see it (e.g. INVITE session,\n * the event framework, etc.).\n *\n * Application MAY READ the dialog contents directly after it acquires\n * dialog lock.\n *\n * To acquire dialog lock, use #pjsip_dlg_inc_lock(), and to release it,\n * use #pjsip_dlg_dec_lock(). DO NOT USE pj_mutex_lock()/pj_mutex_unlock()\n * on the dialog's mutex directly, because this will not protect against\n * dialog being destroyed.\n */\nstruct pjsip_dialog\n{\n    /** The dialog set list. */\n    PJ_DECL_LIST_MEMBER(pjsip_dialog);\n\n    /* Dialog's system properties. */\n    char\t\tobj_name[PJ_MAX_OBJ_NAME];  /**< Standard id.\t    */\n    pj_pool_t\t       *pool;\t    /**< Dialog's pool.\t\t\t    */\n    pj_mutex_t\t       *mutex_;\t    /**< Dialog's mutex. Do not call!!\n\t\t\t\t\t Use pjsip_dlg_inc_lock() instead!  */\n    pjsip_user_agent   *ua;\t    /**< User agent instance.\t\t    */\n    pjsip_endpoint     *endpt;\t    /**< Endpoint instance.\t\t    */\n\n    /** The dialog set which this dialog belongs (opaque type). */\n    void\t       *dlg_set;\n\n    /* Dialog's session properties. */\n    pjsip_dialog_state\tstate;\t    /**< Dialog state.\t\t\t    */\n    pjsip_uri\t       *target;\t    /**< Current target.\t\t    */\n    pjsip_target_set\ttarget_set; /**< Target set, for UAC only.\t    */\n    pjsip_hdr\t        inv_hdr;    /**< Headers from hparam in dest URL    */\n    pjsip_dlg_party     local;\t    /**< Local party info.\t\t    */\n    pjsip_dlg_party     remote;\t    /**< Remote party info.\t\t    */\n    pjsip_hdr\t\trem_cap_hdr;/**< List of remote capability header.  */\n    pjsip_role_e\trole;\t    /**< Initial role.\t\t\t    */\n    pj_bool_t\t\tuac_has_2xx;/**< UAC has received 2xx response?\t    */\n    pj_bool_t\t\tsecure;\t    /**< Use secure transport?\t\t    */\n    pj_bool_t\t\tadd_allow;  /**< Add Allow header in requests?\t    */\n    pjsip_cid_hdr      *call_id;    /**< Call-ID header.\t\t    */\n    pjsip_route_hdr\troute_set;  /**< Route set.\t\t\t    */\n    pj_bool_t\t\troute_set_frozen; /**< Route set has been set.\t    */\n    pjsip_auth_clt_sess\tauth_sess;  /**< Client authentication session.\t    */\n\n    /** Session counter. */\n    int\t\t\tsess_count; /**< Number of sessions.\t\t    */\n\n    /** Transaction counter. */\n    int\t\t\ttsx_count;  /**< Number of pending transactions.    */\n\n    /** Transport selector. */\n    pjsip_tpselector\ttp_sel;\n\n    /* Dialog usages. */\n    unsigned\t\tusage_cnt;  /**< Number of registered usages.\t    */\n    pjsip_module       *usage[PJSIP_MAX_MODULE]; /**< Array of usages, \n\t\t\t\t\t priority sorted\t\t    */\n\n    /** Module specific data. */\n    void\t       *mod_data[PJSIP_MAX_MODULE]; /**< Module data.\t    */\n\n    /**\n     * If via_addr is set, it will be used as the \"sent-by\" field of the\n     * Via header for outgoing requests as long as the request uses via_tp\n     * transport. Normally application should not use or access these fields.\n     */\n    pjsip_host_port     via_addr;   /**< Via address.\t                    */\n    const void         *via_tp;     /**< Via transport.\t                    */\n};\n\n\n/**\n * This utility function returns PJ_TRUE if the specified method is a\n * dialog creating request. This method property is used to determine\n * whether Contact header should be included in outgoing request.\n *\n * @param m\t\tThe SIP method.\n *\n * @return\t\tPJ_TRUE if the method creates a dialog.\n */\nPJ_DECL(pj_bool_t) pjsip_method_creates_dialog(const pjsip_method *m);\n\n/**\n * Create a new dialog and return the instance in p_dlg parameter. \n * After creating  the dialog, application can add modules as dialog usages\n * by calling  #pjsip_dlg_add_usage(). \n *\n * If the request has To tag parameter, dialog's local tag will be initialized \n * from this value. Otherwise a globally unique id generator will be invoked to\n * create dialog's local tag.\n *\n * This function also initializes the dialog's route set based on the \n * Record-Route headers in the request, if present.\n *\n * Note that initially, the session count in the dialog will be initialized \n * to zero.\n *\n * @param ua\t\t    The user agent module instance.\n * @param local_uri\t    Dialog local URI (i.e. From header).\n * @param local_contact\t    Optional dialog local Contact to be put as Contact\n *\t\t\t    header value, hence the format must follow\n *\t\t\t    RFC 3261 Section 20.10:\n *\t\t\t    When the header field value contains a display \n *\t\t\t    name, the URI including all URI parameters is \n *\t\t\t    enclosed in \"<\" and \">\".  If no \"<\" and \">\" are \n *\t\t\t    present, all parameters after the URI are header\n *\t\t\t    parameters, not URI parameters.  The display name \n *\t\t\t    can be tokens, or a quoted string, if a larger \n *\t\t\t    character set is desired.\n *\t\t\t    If this argument is NULL, the Contact will be taken\n *\t\t\t    from the local URI.\n * @param remote_uri\t    Dialog remote URI (i.e. To header).\n * @param target\t    Optional initial remote target. If this argument\n *\t\t\t    is NULL, the initial target will be set to\n *\t\t\t    remote URI.\n * @param p_dlg\t\t    Pointer to receive the dialog.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,\n\t\t\t\t\t   const pj_str_t *local_uri,\n\t\t\t\t\t   const pj_str_t *local_contact,\n\t\t\t\t\t   const pj_str_t *remote_uri,\n\t\t\t\t\t   const pj_str_t *target,\n\t\t\t\t\t   pjsip_dialog **p_dlg);\n\n\n#if !DEPRECATED_FOR_TICKET_1902\n/**\n * Initialize UAS dialog from the information found in the incoming request \n * that creates a dialog (such as INVITE, REFER, or SUBSCRIBE), and set the \n * local Contact to contact. If contact is not specified, the local contact \n * is initialized from the URI in the To header in the request. \n *\n * This function will also create UAS transaction for the incoming request,\n * and associate the transaction to the rdata. Application can query the\n * transaction used to handle this request by calling #pjsip_rdata_get_tsx()\n * after this function returns.\n *\n * Note that initially, the session count in the dialog will be initialized \n * to zero.\n *\n *\n * @param ua\t\t    The user agent module instance.\n * @param rdata\t\t    The incoming request that creates the dialog,\n *\t\t\t    such as INVITE, SUBSCRIBE, or REFER.\n * @param contact\t    Optional dialog local Contact to be put as Contact\n *\t\t\t    header value, hence the format must follow\n *\t\t\t    RFC 3261 Section 20.10:\n *\t\t\t    When the header field value contains a display \n *\t\t\t    name, the URI including all URI parameters is \n *\t\t\t    enclosed in \"<\" and \">\".  If no \"<\" and \">\" are \n *\t\t\t    present, all parameters after the URI are header\n *\t\t\t    parameters, not URI parameters.  The display name \n *\t\t\t    can be tokens, or a quoted string, if a larger \n *\t\t\t    character set is desired.\n *\t\t\t    If this argument is NULL, the local contact will be\n *\t\t\t    initialized from the value of To header in the\n *\t\t\t    request.\n * @param p_dlg\t\t    Pointer to receive the dialog.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_create_uas(  pjsip_user_agent *ua,\n\t\t\t\t\t    pjsip_rx_data *rdata,\n\t\t\t\t\t    const pj_str_t *contact,\n\t\t\t\t\t    pjsip_dialog **p_dlg);\n#endif\n\n\n/**\n * Initialize UAS dialog from the information found in the incoming request \n * that creates a dialog (such as INVITE, REFER, or SUBSCRIBE), and set the \n * local Contact to contact. If contact is not specified, the local contact \n * is initialized from the URI in the To header in the request. \n *\n * This function will also create UAS transaction for the incoming request,\n * and associate the transaction to the rdata. Application can query the\n * transaction used to handle this request by calling #pjsip_rdata_get_tsx()\n * after this function returns.\n *\n * Note that initially, the session count in the dialog will be initialized \n * to 1 (one), and the dialog is locked. Application needs to explicitly call\n * #pjsip_dlg_dec_lock() to release the lock and decrease the session count.\n *\n *\n * @param ua\t\t    The user agent module instance.\n * @param rdata\t\t    The incoming request that creates the dialog,\n *\t\t\t    such as INVITE, SUBSCRIBE, or REFER.\n * @param contact\t    Optional dialog local Contact to be put as Contact\n *\t\t\t    header value, hence the format must follow\n *\t\t\t    RFC 3261 Section 20.10:\n *\t\t\t    When the header field value contains a display \n *\t\t\t    name, the URI including all URI parameters is \n *\t\t\t    enclosed in \"<\" and \">\".  If no \"<\" and \">\" are \n *\t\t\t    present, all parameters after the URI are header\n *\t\t\t    parameters, not URI parameters.  The display name \n *\t\t\t    can be tokens, or a quoted string, if a larger \n *\t\t\t    character set is desired.\n *\t\t\t    If this argument is NULL, the local contact will be\n *\t\t\t    initialized from the value of To header in the\n *\t\t\t    request.\n * @param p_dlg\t\t    Pointer to receive the dialog.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t)\npjsip_dlg_create_uas_and_inc_lock(    pjsip_user_agent *ua,\n\t\t\t\t      pjsip_rx_data *rdata,\n\t\t\t\t      const pj_str_t *contact,\n\t\t\t\t      pjsip_dialog **p_dlg);\n\n\n/**\n * Lock/bind dialog to a specific transport/listener. This is optional,\n * as normally transport will be selected automatically based on the \n * destination of messages upon resolver completion. When the dialog is \n * explicitly bound to the specific transport/listener, all transactions\n * originated by this dialog will use the specified transport/listener\n * when sending outgoing requests.\n *\n * Note that this doesn't affect the Contact header generated by this\n * dialog. Application must manually update the Contact header if\n * necessary, to adjust the address according to the transport being\n * selected.\n *\n * @param dlg\t    The dialog instance.\n * @param sel\t    Transport selector containing the specification of\n *\t\t    transport or listener to be used by this dialog\n *\t\t    to send requests.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_set_transport(pjsip_dialog *dlg,\n\t\t\t\t\t     const pjsip_tpselector *sel);\n\n\n/**\n * Set the \"sent-by\" field of the Via header for outgoing requests.\n *\n * @param dlg\t    The dialog instance.\n * @param via_addr  Set via_addr to use for the Via header or NULL to use\n *                  the transport's published name.\n * @param via_tp    via_addr will only be used if we are using via_tp\n *                  transport.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_set_via_sent_by(pjsip_dialog *dlg,\n\t\t\t\t               pjsip_host_port *via_addr,\n                                               pjsip_transport *via_tp);\n\n\n/**\n * Create a new (forked) dialog on receipt on forked response in rdata. \n * The new dialog will be created from original_dlg, except that it will have\n * new remote tag as copied from the To header in the response. Upon return, \n * the new_dlg will have been registered to the user agent. Applications just \n * need to add modules as dialog's usages.\n *\n * Note that initially, the session count in the dialog will be initialized \n * to zero.\n *\n * @param original_dlg\t    The original UAC dialog.\n * @param rdata\t\t    The incoming forked response message.\n * @param new_dlg\t    Pointer to receive the new dialog.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_fork(const pjsip_dialog *original_dlg,\n\t\t\t\t    const pjsip_rx_data *rdata,\n\t\t\t\t    pjsip_dialog **new_dlg );\n\n/**\n * Forcefully terminate the dialog. Application can only call this function\n * when there is no session associated to the dialog. If there are sessions\n * that use this dialog, this function will refuse to terminate the dialog.\n * For this case, application MUST call the appropriate termination function \n * for each dialog session (e.g. #pjsip_inv_terminate() to terminate INVITE\n * session).\n *\n * @param dlg\t\t    The dialog.\n *\n * @return\t\t    PJ_SUCCESS if dialog has been terminated.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_terminate( pjsip_dialog *dlg );\n\n\n/**\n * Set dialog's initial route set to route_set list. This can only be called\n * for UAC dialog, before any request is sent. After dialog has been \n * established, the route set can not be changed.\n *\n * For UAS dialog, the route set will be initialized in\n * pjsip_dlg_create_uas_and_inc_lock() from the Record-Route headers in\n * the incoming request.\n *\n * The route_set argument is standard list of Route headers (i.e. with \n * sentinel).\n *\n * @param dlg\t\t    The UAC dialog.\n * @param route_set\t    List of Route header.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_set_route_set( pjsip_dialog *dlg,\n\t\t\t\t\t      const pjsip_route_hdr *route_set );\n\n/**\n * Increment the number of sessions in the dialog. Note that initially \n * (after created) the dialog has the session counter set to zero.\n *\n * @param dlg\t\t    The dialog.\n * @param mod\t\t    The module that increments the session counter.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg,\n\t\t\t\t\t    pjsip_module *mod);\n\n\n/**\n * Decrement the number of sessions in the dialog. Once the session counter \n * reach zero and there is no pending transaction, the dialog will be \n * destroyed. Note that this function may destroy the dialog immediately \n * if there is no pending transaction when this function is called.\n *\n * @param dlg\t\t    The dialog.\n * @param mod\t\t    The module that decrements the session counter.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg,\n\t\t\t\t\t    pjsip_module *mod);\n\n/**\n * Add a module as dialog usage, and optionally set the module specific data.\n *\n * @param dlg\t\t    The dialog.\n * @param module\t    The module to be registered as dialog usage.\n * @param mod_data\t    Optional arbitrary data to be attached to dialog's\n *\t\t\t    mod_data array at the module's index.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,\n\t\t\t\t\t  pjsip_module *module,\n\t\t\t\t\t  void *mod_data );\n\n/**\n * Check if the specified module has been registered as usage to the dialog.\n *\n * @param dlg\t\t    The dialog.\n * @param module\t    The module.\n *\n * @return\t\t    PJ_TRUE if the specified module is currently\n * \t\t\t    registered as a usage to the dialog.\n */\nPJ_DECL(pj_bool_t) pjsip_dlg_has_usage(pjsip_dialog *dlg,\n\t\t\t\t       pjsip_module *module);\n\n/**\n * Attach module specific data to the dialog. Application can also set \n * the value directly by accessing dlg->mod_data[module_id].\n *\n * @param dlg\t\t    The dialog\n * @param mod_id\t    The ID of the module from which the data is to be\n *\t\t\t    set to the dialog.\n * @param data\t\t    Arbitrary data.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_set_mod_data( pjsip_dialog *dlg,\n\t\t\t\t\t     int mod_id,\n\t\t\t\t\t     void *data );\n\n/**\n * Get module specific data previously attached to the dialog. Application\n * can also get value directly by accessing dlg->mod_data[module_id].\n *\n * @param dlg\t\t    The dialog\n * @param mod_id\t    The ID of the module from which the data is to be\n *\t\t\t    retrieved from the dialog.\n *\n * @return\t\t    The data that was previously set, or NULL.\n */\nPJ_DECL(void*) pjsip_dlg_get_mod_data( pjsip_dialog *dlg,\n\t\t\t\t       int mod_id);\n\n\n/**\n * Lock dialog and increment session counter termporarily, to prevent it \n * from being destroyed.\n *\n * @param dlg\t\t    The dialog.\n */\nPJ_DECL(void) pjsip_dlg_inc_lock( pjsip_dialog *dlg );\n\n/**\n * Try to acquire dialog's lock, but return immediately if lock can not\n * be acquired.\n *\n * @param dlg\t\t    The dialog.\n *\n * @return\t\t    PJ_SUCCESS if lock has been acquired.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_try_inc_lock( pjsip_dialog *dlg );\n\n/**\n * Unlock dialog and decrement temporary session counter. After this function\n * is called, dialog may be destroyed.\n *\n * @param dlg\t\t    The dialog.\n */\nPJ_DECL(void) pjsip_dlg_dec_lock( pjsip_dialog *dlg );\n\n\n/**\n * Get the dialog instance in the incoming rdata. If an incoming message \n * matches an existing dialog, the user agent must have put the matching \n * dialog instance in the rdata, or otherwise this function will return \n * NULL if the message didn't match any existing dialog.\n *\n * This function can only be called after endpoint distributes the message\n * to the transaction layer or UA layer. In other words, application can\n * only call this function in the context of module that runs in priority\n * number higher than PJSIP_MOD_PRIORITY_UA_PROXY_LAYER.\n *\n * @param rdata\t\t    Incoming message buffer.\n *\n * @return\t\t    The dialog instance that \"owns\" the message.\n */\nPJ_DECL(pjsip_dialog*) pjsip_rdata_get_dlg( pjsip_rx_data *rdata );\n\n/**\n * Get the associated dialog for the specified transaction, if any.\n *\n * @param tsx\t\t    The transaction.\n *\n * @return\t\t    The dialog instance which has been registered\n *\t\t\t    to the transaction as transaction user, or\n *\t\t\t    NULL if the transaction is outside any dialogs.\n */\nPJ_DECL(pjsip_dialog*) pjsip_tsx_get_dlg( pjsip_transaction *tsx );\n\n\n/**\n * Create a basic/generic request with the specified method and optionally\n * specify the cseq. Use value -1 for cseq to have the dialog automatically\n * put next cseq number for the request. Otherwise for some requests, \n * e.q. CANCEL and ACK, application must put the CSeq in the original \n * INVITE request as the parameter. \n *\n * This function will also put Contact header where appropriate.\n *\n * @param dlg\t\t    The dialog instance.\n * @param method\t    The method of the request.\n * @param cseq\t\t    Optional CSeq, which only needs to be specified\n *\t\t\t    when creating ACK and CANCEL. For other requests,\n *\t\t\t    specify -1 to use dialog's internal counter.\n * @param tdata\t\t    Pointer to receive the request's transmit\n *\t\t\t    data buffer.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_create_request(\tpjsip_dialog *dlg,\n\t\t\t\t\t\tconst pjsip_method *method,\n\t\t\t\t\t\tint cseq,\n\t\t\t\t\t\tpjsip_tx_data **tdata);\n\n\n/**\n * Send request message to remote peer. If the request is not an ACK request, \n * the dialog will send the request statefully, by creating an UAC transaction\n * and send the request with the transaction. \n *\n * Also when the request is not ACK or CANCEL, the dialog will increment its\n * local cseq number and update the cseq in the request according to dialog's \n * cseq.\n *\n * If p_tsx is not null, this argument will be set with the transaction \n * instance that was used to send the request.\n *\n * This function will decrement the transmit data's reference counter\n * regardless the status of the operation.\n *\n * @param dlg\t\t    The dialog.\n * @param tdata\t\t    The request message to be sent.\n * @param mod_data_id\t    Optional module data index to put an optional data\n *\t\t\t    into the transaction. If no module data is to be\n *\t\t\t    attached, this value should be -1.\n * @param mod_data\t    Optional module data to be attached to the \n *\t\t\t    transaction at mod_data_id index.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_send_request (\tpjsip_dialog *dlg,\n\t\t\t\t\t\tpjsip_tx_data *tdata,\n\t\t\t\t\t\tint mod_data_id,\n\t\t\t\t\t\tvoid *mod_data);\n\n\n/**\n * Create a response message for the incoming request in rdata with status\n * code st_code and optional status text st_text. This function is different\n * than endpoint's API #pjsip_endpt_create_response() in that the dialog \n * function adds Contact header and Record-Routes headers in the response \n * where appropriate.\n *\n * @param dlg\t\t    The dialog.\n * @param rdata\t\t    The incoming request message for which the\n *\t\t\t    response will be created.\n * @param st_code\t    Status code.\n * @param st_text\t    Optional string for custom status reason text.\n * @param tdata\t\t    Pointer to receive the response message transmit\n *\t\t\t    data buffer.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_create_response(\tpjsip_dialog *dlg,\n\t\t\t\t\t\tpjsip_rx_data *rdata,\n\t\t\t\t\t\tint st_code,\n\t\t\t\t\t\tconst pj_str_t *st_text,\n\t\t\t\t\t\tpjsip_tx_data **tdata);\n\n\n/**\n * Modify previously sent response with other status code. Contact header \n * will be added when appropriate.\n *\n * @param dlg\t\t    The dialog.\n * @param tdata\t\t    The transmit data buffer containing response\n *\t\t\t    message to be modified.\n * @param st_code\t    New status code to be set.\n * @param st_text\t    Optional string for custom status reason text.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_modify_response(\tpjsip_dialog *dlg,\n\t\t\t\t\t\tpjsip_tx_data *tdata,\n\t\t\t\t\t\tint st_code,\n\t\t\t\t\t\tconst pj_str_t *st_text);\n\n\n/**\n * Send response message statefully. The transaction instance MUST be the \n * transaction that was reported on on_rx_request() callback.\n *\n * This function decrements the transmit data's reference counter regardless\n * the status of the operation.\n *\n * @param dlg\t\t    The dialog.\n * @param tsx\t\t    The UAS transaction associated with the incoming\n *\t\t\t    request. If the request is within a dialog, or\n *\t\t\t    a dialog has been created for the request that\n *\t\t\t    creates the dialog, application can get the\n *\t\t\t    transaction instance for the request by calling\n *\t\t\t    #pjsip_rdata_get_tsx().\n * @param tdata\t\t    Response message to be sent.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_send_response(\tpjsip_dialog *dlg,\n\t\t\t\t\t\tpjsip_transaction *tsx,\n\t\t\t\t\t\tpjsip_tx_data *tdata);\n\n\n/**\n * This composite function sends response message statefully to an incoming\n * request message inside dialog.\n *\n * @param dlg\t    The endpoint instance.\n * @param rdata\t    The incoming request message.\n * @param st_code   Status code of the response.\n * @param st_text   Optional status text of the response.\n * @param hdr_list  Optional header list to be added to the response.\n * @param body\t    Optional message body to be added to the response.\n *\n * @return\t    PJ_SUCCESS if response message has successfully been\n *\t\t    sent.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_respond( pjsip_dialog *dlg,\n\t\t\t\t\tpjsip_rx_data *rdata,\n\t\t\t\t\tint st_code,\n\t\t\t\t\tconst pj_str_t *st_text,\n\t\t\t\t\tconst pjsip_hdr *hdr_list,\n\t\t\t\t\tconst pjsip_msg_body *body );\n\n\n/**\n * Check if remote peer have the specified capability as published\n * in the dialog messages from remote peer.\n *\n * Notes:\n * - The capability \\a token lookup will apply exact match, but not \n *   case-sensitive, for example: <tt>\"text/html\"</tt> will not match \n *   <tt>\"text / html\"</tt> (notice the spaces).\n *\n * @param dlg\t    The dialog.\n * @param htype\t    The header type to be checked, which value may be:\n *\t\t    - PJSIP_H_ACCEPT\n *\t\t    - PJSIP_H_ALLOW\n *\t\t    - PJSIP_H_SUPPORTED\n * @param hname\t    If htype specifies PJSIP_H_OTHER, then the header name\n *\t\t    must be supplied in this argument. Otherwise the value\n *\t\t    must be set to NULL.\n * @param token\t    The capability token to check. For example, if \\a htype\n *\t\t    is PJSIP_H_ALLOW, then \\a token specifies the method\n *\t\t    names; if \\a htype is PJSIP_H_SUPPORTED, then \\a token\n *\t\t    specifies the extension names such as \"100rel\".\n *\n * @return\t    PJSIP_DIALOG_CAP_SUPPORTED if the specified capability\n *\t\t    is explicitly supported, see @pjsip_dialog_cap_status\n *\t\t    for more info.\n */\nPJ_DECL(pjsip_dialog_cap_status) pjsip_dlg_remote_has_cap(\n\t\t\t\t\t\t    pjsip_dialog *dlg,\n\t\t\t\t\t\t    int htype,\n\t\t\t\t\t\t    const pj_str_t *hname,\n\t\t\t\t\t\t    const pj_str_t *token);\n\n/**\n * Get the specified capability header from the remote capability headers\n * stored in the dialog.\n *\n * @param dlg\t    The dialog.\n * @param htype\t    The header type to be retrieved, which value may be:\n *\t\t    - PJSIP_H_ACCEPT\n *\t\t    - PJSIP_H_ALLOW\n *\t\t    - PJSIP_H_SUPPORTED\n * @param hname\t    If htype specifies PJSIP_H_OTHER, then the header name\n *\t\t    must be supplied in this argument. Otherwise the value\n *\t\t    must be set to NULL.\n *\n * @return\t    The appropriate header, or NULL if the header is not\n *\t\t    available.\n */\nPJ_DECL(const pjsip_hdr*) pjsip_dlg_get_remote_cap_hdr(pjsip_dialog *dlg,\n\t\t\t\t\t\t       int htype,\n\t\t\t\t\t\t       const pj_str_t *hname);\n\n/**\n * Set remote capability from a SIP header containing array of capability \n * tags/values.\n *\n * @param dlg\t    The dialog.\n * @param cap_hdr   The SIP header.\n *\n * @return\t    PJ_SUCCESS when successful, otherwise the appropriate\n *\t\t    error code will be returned.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_set_remote_cap_hdr(\n\t\t\t\t    pjsip_dialog *dlg,\n\t\t\t\t    const pjsip_generic_array_hdr *cap_hdr);\n\n/**\n * Remove a remote capability header.\n *\n * @param dlg\t    The dialog.\n * @param htype\t    The header type to be removed, which value may be:\n *\t\t    - PJSIP_H_ACCEPT\n *\t\t    - PJSIP_H_ALLOW\n *\t\t    - PJSIP_H_SUPPORTED\n * @param hname\t    If htype specifies PJSIP_H_OTHER, then the header name\n *\t\t    must be supplied in this argument. Otherwise the value\n *\t\t    must be set to NULL.\n *\n * @return\t    PJ_SUCCESS when successful, otherwise the appropriate\n *\t\t    error code will be returned.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_remove_remote_cap_hdr(pjsip_dialog *dlg,\n\t\t\t\t\t\t     int htype,\n\t\t\t\t\t\t     const pj_str_t *hname);\n\n/**\n * Update remote capabilities from a received message. The header types\n * to be updated from the message will only be \\a PJSIP_H_ACCEPT, \n * \\a PJSIP_H_ALLOW, and \\a PJSIP_H_SUPPORTED.\n *\n * @param dlg\t    The dialog.\n * @param msg\t    The received message.\n * @param strict    If this is set to PJ_TRUE, any header types missing\n *\t\t    from the message will cause removal of existing\n *\t\t    header types in the capability list. Otherwise, the \n *\t\t    capability list will not be modified when any header\n *                  type is missing.\n *\n * @return\t    PJ_SUCCESS when successful, otherwise the appropriate\n *\t\t    error code will be returned.\n */\nPJ_DECL(pj_status_t) pjsip_dlg_update_remote_cap(pjsip_dialog *dlg,\n\t\t\t\t\t         const pjsip_msg *msg,\n\t\t\t\t\t\t pj_bool_t strict);\n\n\n\n/**\n * @}\n */\n\n/* \n * Internal (called by sip_ua_layer.c)\n */\n\n/* Receives transaction event (called by user_agent module) */\nvoid pjsip_dlg_on_tsx_state( pjsip_dialog *dlg,\n\t\t\t     pjsip_transaction *tsx,\n\t\t\t     pjsip_event *e );\n\nvoid pjsip_dlg_on_rx_request( pjsip_dialog *dlg,\n\t\t\t      pjsip_rx_data *rdata );\n\nvoid pjsip_dlg_on_rx_response( pjsip_dialog *dlg,\n\t\t\t       pjsip_rx_data *rdata );\n\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJSIP_SIP_DIALOG_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_endpoint.h",
    "content": "/* $Id: sip_endpoint.h 4275 2012-10-04 06:11:58Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_ENDPOINT_H__\n#define __PJSIP_SIP_ENDPOINT_H__\n\n/**\n * @file sip_endpoint.h\n * @brief SIP Endpoint.\n */\n\n#include <pjsip/sip_transport.h>\n#include <pjsip/sip_resolve.h>\n\n/**\n * @defgroup PJSIP_CORE_CORE At the Very Core\n * @ingroup PJSIP_CORE\n * @brief The very core of PJSIP.\n */\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_ENDPT Endpoint\n * @ingroup PJSIP_CORE_CORE\n * @brief The master, owner of all objects\n *\n * SIP Endpoint instance (pjsip_endpoint) can be viewed as the master/owner of\n * all SIP objects in an application. It performs the following roles:\n *  - it manages the allocation/deallocation of memory pools for all objects.\n *  - it manages listeners and transports, and how they are used by \n *    transactions.\n *  - it receives incoming messages from transport layer and automatically\n *    dispatches them to the correct transaction (or create a new one).\n *  - it has a single instance of timer management (timer heap).\n *  - it manages modules, which is the primary means of extending the library.\n *  - it provides single polling function for all objects and distributes \n *    events.\n *  - it automatically handles incoming requests which can not be handled by\n *    existing modules (such as when incoming request has unsupported method).\n *  - and so on..\n *\n * Application should only instantiate one SIP endpoint instance for every\n * process.\n *\n * @{\n */\n\n\n/**\n * Type of callback to register to pjsip_endpt_atexit().\n */\ntypedef void (*pjsip_endpt_exit_callback)(pjsip_endpoint *endpt);\n\n\n/**\n * Create an instance of SIP endpoint from the specified pool factory.\n * The pool factory reference then will be kept by the endpoint, so that \n * future memory allocations by SIP components will be taken from the same\n * pool factory.\n *\n * @param pf\t        Pool factory that will be used for the lifetime of \n *                      endpoint.\n * @param name          Optional name to be specified for the endpoint.\n *                      If this parameter is NULL, then the name will use\n *                      local host name.\n * @param endpt         Pointer to receive endpoint instance.\n *\n * @return              PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_create(pj_pool_factory *pf,\n\t\t\t\t\tconst char *name,\n                                        pjsip_endpoint **endpt);\n\n/**\n * Destroy endpoint instance. Application must make sure that all pending\n * transactions have been terminated properly, because this function does not\n * check for the presence of pending transactions.\n *\n * @param endpt\t\tThe SIP endpoint to be destroyed.\n */\nPJ_DECL(void) pjsip_endpt_destroy(pjsip_endpoint *endpt);\n\n/**\n * Get endpoint name.\n *\n * @param endpt         The SIP endpoint instance.\n *\n * @return              Endpoint name, as was registered during endpoint\n *                      creation. The string is NULL terminated.\n */\nPJ_DECL(const pj_str_t*) pjsip_endpt_name(const pjsip_endpoint *endpt);\n\n/**\n * Poll for events. Application must call this function periodically to ensure\n * that all events from both transports and timer heap are handled in timely\n * manner.  This function, like all other endpoint functions, is thread safe, \n * and application may have more than one thread concurrently calling this function.\n *\n * @param endpt\t\tThe endpoint.\n * @param max_timeout\tMaximum time to wait for events, or NULL to wait forever\n *\t\t\tuntil event is received.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_handle_events( pjsip_endpoint *endpt, \n\t\t\t\t\t        const pj_time_val *max_timeout);\n\n\n/**\n * Handle events with additional info about number of events that\n * have been handled.\n *\n * @param endpt\t\tThe endpoint.\n * @param max_timeout\tMaximum time to wait for events, or NULL to wait forever\n *\t\t\tuntil event is received.\n * @param count\t\tOptional argument to receive the number of events that\n *\t\t\thave been handled by the function.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_handle_events2(pjsip_endpoint *endpt,\n\t\t\t\t\t        const pj_time_val *max_timeout,\n\t\t\t\t\t        unsigned *count);\n/**\n * Schedule timer to endpoint's timer heap. Application must poll the endpoint\n * periodically (by calling #pjsip_endpt_handle_events) to ensure that the\n * timer events are handled in timely manner. When the timeout for the timer\n * has elapsed, the callback specified in the entry argument will be called.\n * This function, like all other endpoint functions, is thread safe.\n *\n * @param endpt\t    The endpoint.\n * @param entry\t    The timer entry.\n * @param delay\t    The relative delay of the timer.\n * @return\t    PJ_OK (zero) if successfull.\n */\n#if PJ_TIMER_DEBUG\n#define pjsip_endpt_schedule_timer(ept,ent,d) \\\n\t\t\tpjsip_endpt_schedule_timer_dbg(ept, ent, d, \\\n\t\t\t                               __FILE__, __LINE__)\n\nPJ_DECL(pj_status_t) pjsip_endpt_schedule_timer_dbg(pjsip_endpoint *endpt,\n\t\t\t\t\t\t    pj_timer_entry *entry,\n\t\t\t\t\t\t    const pj_time_val *delay,\n\t\t\t\t\t\t    const char *src_file,\n\t\t\t\t\t\t    int src_line);\n#else\nPJ_DECL(pj_status_t) pjsip_endpt_schedule_timer( pjsip_endpoint *endpt,\n\t\t\t\t\t\t pj_timer_entry *entry,\n\t\t\t\t\t\t const pj_time_val *delay );\n#endif\n\n/**\n * Cancel the previously registered timer.\n * This function, like all other endpoint functions, is thread safe.\n *\n * @param endpt\t    The endpoint.\n * @param entry\t    The timer entry previously registered.\n */\nPJ_DECL(void) pjsip_endpt_cancel_timer( pjsip_endpoint *endpt, \n\t\t\t\t\tpj_timer_entry *entry );\n\n/**\n * Get the timer heap instance of the SIP endpoint.\n *\n * @param endpt\t    The endpoint.\n *\n * @return\t    The timer heap instance.\n */\nPJ_DECL(pj_timer_heap_t*) pjsip_endpt_get_timer_heap(pjsip_endpoint *endpt);\n\n\n/**\n * Register new module to the endpoint.\n * The endpoint will then call the load and start function in the module to \n * properly initialize the module, and assign a unique module ID for the \n * module.\n *\n * @param endpt\t\tThe endpoint.\n * @param module\tThe module to be registered.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_register_module( pjsip_endpoint *endpt,\n\t\t\t\t\t\t  pjsip_module *module );\n\n/**\n * Unregister a module from the endpoint.\n * The endpoint will then call the stop and unload function in the module to \n * properly shutdown the module.\n *\n * @param endpt\t\tThe endpoint.\n * @param module\tThe module to be registered.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_unregister_module( pjsip_endpoint *endpt,\n\t\t\t\t\t\t    pjsip_module *module );\n\n/**\n * This describes additional parameters to pjsip_endpt_process_rx_data()\n * function. Application MUST call pjsip_process_rdata_param_default() to\n * initialize this structure.\n */\ntypedef struct pjsip_process_rdata_param\n{\n    /**\n     * Specify the minimum priority number of the modules that are allowed\n     * to process the message. Default is zero to allow all modules to\n     * process the message.\n     */\n    unsigned start_prio;\n\n    /**\n     * Specify the pointer of the module where processing will start.\n     * The default is NULL, meaning processing will start from the start\n     * of the module list.\n     */\n    void *start_mod;\n\n    /**\n     * Set to N, then processing will start at Nth module after start\n     * module (where start module can be an explicit module as specified\n     * by \\a start_mod or the start of module list when \\a start_mod is\n     * NULL). For example, if set to 1, then processing will start from\n     * the next module after start module. Default is zero.\n     */\n    unsigned idx_after_start;\n\n    /**\n     * Print nothing to log. Default is PJ_FALSE.\n     */\n    pj_bool_t silent;\n\n} pjsip_process_rdata_param;\n\n/**\n * Initialize with default.\n *\n * @param p\tThe param.\n */\nPJ_DECL(void) pjsip_process_rdata_param_default(pjsip_process_rdata_param *p);\n\n/**\n * Manually distribute the specified pjsip_rx_data to registered modules.\n * Normally application does not need to call this function because received\n * messages will be given to endpoint automatically by transports.\n *\n * Application can use this function when it has postponed the processing of\n * an incoming message, for example to perform long operations such as\n * database operation or to consult other servers to decide what to do with\n * the message. In this case, application clones the original rdata, return\n * from the callback, and perform the long operation. Upon completing the\n * long operation, it resumes pjsip's module processing by calling this\n * function, and then free the cloned rdata.\n *\n * @param endpt\t\tThe endpoint instance.\n * @param rdata\t\tThe rdata to be distributed.\n * @param p\t\tOptional pointer to param to specify from which module\n * \t\t\tthe processing should start.\n * @param p_handled\tOptional pointer to receive last return value of\n * \t\t\tmodule's \\a on_rx_request() or \\a on_rx_response()\n * \t\t\tcallback.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_process_rx_data(pjsip_endpoint *endpt,\n                                                 pjsip_rx_data *rdata,\n                                                 pjsip_process_rdata_param *p,\n                                                 pj_bool_t *p_handled);\n\n/**\n * Create pool from the endpoint. All SIP components should allocate their\n * memory pool by calling this function, to make sure that the pools are\n * allocated from the same pool factory. This function, like all other endpoint\n * functions, is thread safe.\n *\n * @param endpt\t\tThe SIP endpoint.\n * @param pool_name\tName to be assigned to the pool.\n * @param initial\tThe initial size of the pool.\n * @param increment\tThe resize size.\n * @return\t\tMemory pool, or NULL on failure.\n *\n * @see pj_pool_create\n */\nPJ_DECL(pj_pool_t*) pjsip_endpt_create_pool( pjsip_endpoint *endpt,\n\t\t\t\t\t     const char *pool_name,\n\t\t\t\t\t     pj_size_t initial,\n\t\t\t\t\t     pj_size_t increment );\n\n/**\n * Return back pool to endpoint to be released back to the pool factory.\n * This function, like all other endpoint functions, is thread safe.\n *\n * @param endpt\t    The endpoint.\n * @param pool\t    The pool to be destroyed.\n */\nPJ_DECL(void) pjsip_endpt_release_pool( pjsip_endpoint *endpt,\n\t\t\t\t\tpj_pool_t *pool );\n\n/**\n * Find transaction in endpoint's transaction table by the transaction's key.\n * This function normally is only used by modules. The key for a transaction\n * can be created by calling #pjsip_tsx_create_key.\n *\n * @param endpt\t    The endpoint instance.\n * @param key\t    Transaction key, as created with #pjsip_tsx_create_key.\n *\n * @return\t    The transaction, or NULL if it's not found.\n */\nPJ_DECL(pjsip_transaction*) pjsip_endpt_find_tsx( pjsip_endpoint *endpt,\n\t\t\t\t\t          const pj_str_t *key );\n\n/**\n * Register the transaction to the endpoint's transaction table.\n * This function should only be used internally by the stack.\n *\n * @param endpt\t    The SIP endpoint.\n * @param tsx\t    The transaction.\n */\nPJ_DECL(void) pjsip_endpt_register_tsx( pjsip_endpoint *endpt,\n\t\t\t\t\tpjsip_transaction *tsx);\n\n/**\n * Forcefull destroy the transaction. This function should only be used\n * internally by the stack.\n *\n * @param endpt\t    The endpoint.\n * @param tsx\t    The transaction to destroy.\n */\nPJ_DECL(void) pjsip_endpt_destroy_tsx( pjsip_endpoint *endpt,\n\t\t\t\t      pjsip_transaction *tsx);\n\n/**\n * Create a new transmit data buffer.\n * This function, like all other endpoint functions, is thread safe.\n *\n * @param endpt\t    The endpoint.\n * @param p_tdata    Pointer to receive transmit data buffer.\n *\n * @return\t    PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_create_tdata( pjsip_endpoint *endpt,\n\t\t\t\t\t       pjsip_tx_data **p_tdata);\n\n/**\n * Create the DNS resolver instance. Application creates the DNS\n * resolver instance, set the nameserver to be used by the DNS\n * resolver, then set the DNS resolver to be used by the endpoint\n * by calling #pjsip_endpt_set_resolver().\n *\n * @param endpt\t\tThe SIP endpoint instance.\n * @param p_resv\tPointer to receive the DNS resolver instance.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error\n *\t\t\tcode.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_create_resolver(pjsip_endpoint *endpt,\n\t\t\t\t\t\t pj_dns_resolver **p_resv);\n\n/**\n * Set DNS resolver to be used by the SIP resolver. Application can set\n * the resolver instance to NULL to disable DNS resolution (perhaps\n * temporarily). When DNS resolver is disabled, the endpoint will resolve\n * hostnames with the normal pj_gethostbyname() function.\n *\n * @param endpt\t\tThe SIP endpoint instance.\n * @param resv\t\tThe resolver instance to be used by the SIP\n *\t\t\tendpoint.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error\n *\t\t\tcode.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_set_resolver(pjsip_endpoint *endpt,\n\t\t\t\t\t      pj_dns_resolver *resv);\n\n/**\n * Set the DNS external resolver implementation to use in the SIP resolver. \n *\n * Note that naturally when implementing its own resolver, application would not\n * need the internal resolver, hence this function will also destroy the \n * PJLIB-UTIL DNS resolver if any (e.g: set using #pjsip_endpt_set_resolver()). \n * Application that needs it, still be able create its own instance. \n *\n * @param res       The SIP resolver engine.\n * @param ext_res   The external resolver implementation callback. This argument\n *\t\t    can be NULL to reset the whole external implementation. \n *\t\t    However, it is prohibited to reset individual callback.\n * \n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_set_ext_resolver(pjsip_endpoint *endpt,\n\t\t\t\t\t\t  pjsip_ext_resolver *ext_res);\n\n/**\n * Get the DNS resolver being used by the SIP resolver.\n *\n * @param endpt\t\tThe SIP endpoint instance.\n *\n * @return\t\tThe DNS resolver instance currently being used\n *\t\t\tby the SIP endpoint.\n */\nPJ_DECL(pj_dns_resolver*) pjsip_endpt_get_resolver(pjsip_endpoint *endpt);\n\n/**\n * Asynchronously resolve a SIP target host or domain according to rule \n * specified in RFC 3263 (Locating SIP Servers). When the resolving operation\n * has completed, the callback will be called.\n *\n * @param endpt\t    The endpoint instance.\n * @param pool\t    The pool to allocate resolver job.\n * @param target    The target specification to be resolved.\n * @param token\t    A user defined token to be passed back to callback function.\n * @param cb\t    The callback function.\n */\nPJ_DECL(void) pjsip_endpt_resolve( pjsip_endpoint *endpt,\n\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t   pjsip_host_info *target,\n\t\t\t\t   void *token,\n\t\t\t\t   pjsip_resolver_callback *cb);\n\n/**\n * Get transport manager instance.\n *\n * @param endpt\t    The endpoint.\n *\n * @return\t    Transport manager instance.\n */\nPJ_DECL(pjsip_tpmgr*) pjsip_endpt_get_tpmgr(pjsip_endpoint *endpt);\n\n/**\n * Get ioqueue instance.\n *\n * @param endpt\t    The endpoint.\n *\n * @return\t    The ioqueue.\n */\nPJ_DECL(pj_ioqueue_t*) pjsip_endpt_get_ioqueue(pjsip_endpoint *endpt);\n\n/**\n * Find a SIP transport suitable for sending SIP message to the specified\n * address. If transport selector (\"sel\") is set, then the function will\n * check if the transport selected is suitable to send requests to the\n * specified address.\n *\n * @see pjsip_tpmgr_acquire_transport\n *\n * @param endpt\t    The SIP endpoint instance.\n * @param type\t    The type of transport to be acquired.\n * @param remote    The remote address to send message to.\n * @param addr_len  Length of the remote address.\n * @param sel\t    Optional pointer to transport selector instance which is\n *\t\t    used to find explicit transport, if required.\n * @param p_tp\t    Pointer to receive the transport instance, if one is found.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) \npjsip_endpt_acquire_transport( pjsip_endpoint *endpt,\n\t\t\t       pjsip_transport_type_e type,\n\t\t\t       const pj_sockaddr_t *remote,\n\t\t\t       int addr_len,\n\t\t\t       const pjsip_tpselector *sel,\n\t\t\t       pjsip_transport **p_tp);\n\n\n/**\n * Find a SIP transport suitable for sending SIP message to the specified\n * address by also considering the outgoing SIP message data. If transport \n * selector (\"sel\") is set, then the function will check if the transport \n * selected is suitable to send requests to the specified address.\n *\n * @see pjsip_tpmgr_acquire_transport\n *\n * @param endpt\t    The SIP endpoint instance.\n * @param type\t    The type of transport to be acquired.\n * @param remote    The remote address to send message to.\n * @param addr_len  Length of the remote address.\n * @param sel\t    Optional pointer to transport selector instance which is\n *\t\t    used to find explicit transport, if required.\n * @param tdata\t    Optional pointer to SIP message data to be sent.\n * @param p_tp\t    Pointer to receive the transport instance, if one is found.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) \npjsip_endpt_acquire_transport2(pjsip_endpoint *endpt,\n\t\t\t       pjsip_transport_type_e type,\n\t\t\t       const pj_sockaddr_t *remote,\n\t\t\t       int addr_len,\n\t\t\t       const pjsip_tpselector *sel,\n\t\t\t       pjsip_tx_data *tdata,\n\t\t\t       pjsip_transport **p_tp);\n\n\n/*****************************************************************************\n *\n * Capabilities Management\n *\n * Modules may implement new capabilities to the stack. These capabilities\n * are indicated by the appropriate SIP header fields, such as Accept,\n * Accept-Encoding, Accept-Language, Allow, Supported, etc.\n *\n * When a module provides new capabilities to the stack, it registers these\n * capabilities to the endpoint by supplying new tags (strings) to the\n * appropriate header fields. Application (or other modules) can then query\n * these header fields to get the list of supported capabilities, and may\n * include these headers in the outgoing message.\n *****************************************************************************\n */\n\n/**\n * Get the value of the specified capability header field.\n *\n * @param endpt\t    The endpoint.\n * @param htype\t    The header type to be retrieved, which value may be:\n *\t\t    - PJSIP_H_ACCEPT\n *\t\t    - PJSIP_H_ALLOW\n *\t\t    - PJSIP_H_SUPPORTED\n * @param hname\t    If htype specifies PJSIP_H_OTHER, then the header name\n *\t\t    must be supplied in this argument. Otherwise the value\n *\t\t    must be set to NULL.\n *\n * @return\t    The appropriate header, or NULL if the header is not\n *\t\t    available.\n */\nPJ_DECL(const pjsip_hdr*) pjsip_endpt_get_capability( pjsip_endpoint *endpt,\n\t\t\t\t\t\t      int htype,\n\t\t\t\t\t\t      const pj_str_t *hname);\n\n\n/**\n * Check if we have the specified capability.\n *\n * @param endpt\t    The endpoint.\n * @param htype\t    The header type to be retrieved, which value may be:\n *\t\t    - PJSIP_H_ACCEPT\n *\t\t    - PJSIP_H_ALLOW\n *\t\t    - PJSIP_H_SUPPORTED\n * @param hname\t    If htype specifies PJSIP_H_OTHER, then the header name\n *\t\t    must be supplied in this argument. Otherwise the value\n *\t\t    must be set to NULL.\n * @param token\t    The capability token to check. For example, if \\a htype\n *\t\t    is PJSIP_H_ALLOW, then \\a token specifies the method\n *\t\t    names; if \\a htype is PJSIP_H_SUPPORTED, then \\a token\n *\t\t    specifies the extension names such as \"100rel\".\n *\n * @return\t    PJ_TRUE if the specified capability is supported,\n *\t\t    otherwise PJ_FALSE..\n */\nPJ_DECL(pj_bool_t) pjsip_endpt_has_capability( pjsip_endpoint *endpt,\n\t\t\t\t\t       int htype,\n\t\t\t\t\t       const pj_str_t *hname,\n\t\t\t\t\t       const pj_str_t *token);\n\n\n/**\n * Add or register new capabilities as indicated by the tags to the\n * appropriate header fields in the endpoint.\n *\n * @param endpt\t    The endpoint.\n * @param mod\t    The module which registers the capability.\n * @param htype\t    The header type to be set, which value may be:\n *\t\t    - PJSIP_H_ACCEPT\n *\t\t    - PJSIP_H_ALLOW\n *\t\t    - PJSIP_H_SUPPORTED\n * @param hname\t    If htype specifies PJSIP_H_OTHER, then the header name\n *\t\t    must be supplied in this argument. Otherwise the value\n *\t\t    must be set to NULL.\n * @param count\t    The number of tags in the array.\n * @param tags\t    Array of tags describing the capabilities or extensions\n *\t\t    to be added to the appropriate header.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_add_capability( pjsip_endpoint *endpt,\n\t\t\t\t\t\t pjsip_module *mod,\n\t\t\t\t\t\t int htype,\n\t\t\t\t\t\t const pj_str_t *hname,\n\t\t\t\t\t\t unsigned count,\n\t\t\t\t\t\t const pj_str_t tags[]);\n\n/**\n * Get list of additional headers to be put in outgoing request message.\n * Currently only Max-Forwards are defined.\n *\n * @param e\t    The endpoint.\n *\n * @return\t    List of headers.\n */\nPJ_DECL(const pjsip_hdr*) pjsip_endpt_get_request_headers(pjsip_endpoint *e);\n\n\n/**\n * Dump endpoint status to the log. This will print the status to the log\n * with log level 3.\n *\n * @param endpt\t\tThe endpoint.\n * @param detail\tIf non zero, then it will dump a detailed output.\n *\t\t\tBEWARE that this option may crash the system because\n *\t\t\tit tries to access all memory pools.\n */\nPJ_DECL(void) pjsip_endpt_dump( pjsip_endpoint *endpt, pj_bool_t detail );\n\n\n/**\n * Register cleanup function to be called by SIP endpoint when \n * #pjsip_endpt_destroy() is called.  Note that application should not\n * use or access any endpoint resource (such as pool, ioqueue, timer heap)\n * from within the callback as such resource may have been released when\n * the callback function is invoked.\n *\n * @param endpt\t\tThe SIP endpoint.\n * @param func\t\tThe function to be registered.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_atexit(pjsip_endpoint *endpt,\n\t\t\t\t\tpjsip_endpt_exit_callback func);\n\n\n/**\n * @}\n */\n\n\n/**\n * Log an error.\n */\nPJ_DECL(void) pjsip_endpt_log_error( pjsip_endpoint *endpt,\n\t\t\t\t     const char *sender,\n                                     pj_status_t error_code,\n                                     const char *format,\n                                     ... );\n\n#define PJSIP_ENDPT_LOG_ERROR(expr)   \\\n            pjsip_endpt_log_error expr\n\n#define PJSIP_ENDPT_TRACE(tracing,expr) \\\n            do {                        \\\n                if ((tracing))          \\\n                    PJ_LOG(4,expr);     \\\n            } while (0)\n\n/*\n * Internal functions.\n */\n/*\n * Receive transaction events from transactions and put in the event queue\n * to be processed later.\n */\nvoid pjsip_endpt_send_tsx_event( pjsip_endpoint *endpt, pjsip_event *evt );\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_SIP_ENDPOINT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_errno.h",
    "content": "/* $Id: sip_errno.h 3553 2011-05-05 06:14:19Z nanang $  */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_ERRNO_H__\n#define __PJSIP_SIP_ERRNO_H__\n\n/**\n * @file sip_errno.h\n * @brief PJSIP Specific Error Code\n */\n\n#include <pj/errno.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_CORE_ERRNO PJSIP Specific Error Code\n * @ingroup PJSIP_BASE\n * @brief PJSIP specific error constants.\n * @{\n */\n\n/*\n * PJSIP error codes occupies 170000 - 219000, and mapped as follows:\n *  - 170100 - 170799: mapped to SIP status code in response msg.\n *  - 171000 - 171999: mapped to errors generated from PJSIP core.\n */\n\n/**\n * Start of error code relative to PJ_ERRNO_START_USER.\n */\n#define PJSIP_ERRNO_START       (PJ_ERRNO_START_USER)\n\n/**\n * Create error value from SIP status code.\n * @param code      SIP status code.\n * @return          Error code in pj_status_t namespace.\n */\n#define PJSIP_ERRNO_FROM_SIP_STATUS(code)   (PJSIP_ERRNO_START+code)\n\n/**\n * Get SIP status code from error value.\n * If conversion to SIP status code is not available, a SIP status code\n * 599 will be returned.\n *\n * @param status    Error code in pj_status_t namespace.\n * @return          SIP status code.\n */\n#define PJSIP_ERRNO_TO_SIP_STATUS(status)               \\\n         ((status>=PJSIP_ERRNO_FROM_SIP_STATUS(100) &&  \\\n           status<PJSIP_ERRNO_FROM_SIP_STATUS(800)) ?   \\\n          status-PJSIP_ERRNO_FROM_SIP_STATUS(0) : 599)\n\n\n/**\n * Start of PJSIP generated error code values.\n */\n#define PJSIP_ERRNO_START_PJSIP (PJSIP_ERRNO_START + 1000)\n\n/************************************************************\n * GENERIC/GENERAL SIP ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * SIP object is busy.\n */\n#define PJSIP_EBUSY\t\t(PJSIP_ERRNO_START_PJSIP + 1)\t/* 171001 */\n/**\n * @hideinitializer\n * SIP object with the same type already exists.\n */\n#define PJSIP_ETYPEEXISTS\t(PJSIP_ERRNO_START_PJSIP + 2)\t/* 171002 */\n/**\n * @hideinitializer\n * SIP stack is shutting down.\n */\n#define PJSIP_ESHUTDOWN\t\t(PJSIP_ERRNO_START_PJSIP + 3)\t/* 171003 */\n/**\n * @hideinitializer\n * SIP object is not initialized.\n */\n#define PJSIP_ENOTINITIALIZED\t(PJSIP_ERRNO_START_PJSIP + 4)\t/* 171004 */\n/**\n * @hideinitializer\n * Missing route set (for tel: URI)\n */\n#define PJSIP_ENOROUTESET\t(PJSIP_ERRNO_START_PJSIP + 5)\t/* 171005 */\n\n\n/************************************************************\n * MESSAGING ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * General invalid message error (e.g. syntax error)\n */\n#define PJSIP_EINVALIDMSG       (PJSIP_ERRNO_START_PJSIP + 20)\t/* 171020 */\n/**\n * @hideinitializer\n * Expecting request message.\n */\n#define PJSIP_ENOTREQUESTMSG\t(PJSIP_ERRNO_START_PJSIP + 21)\t/* 171021 */\n/**\n * @hideinitializer\n * Expecting response message.\n */\n#define PJSIP_ENOTRESPONSEMSG\t(PJSIP_ERRNO_START_PJSIP + 22)\t/* 171022 */\n/**\n * @hideinitializer\n * Message too long. See also PJSIP_ERXOVERFLOW.\n */\n#define PJSIP_EMSGTOOLONG\t(PJSIP_ERRNO_START_PJSIP + 23)\t/* 171023 */\n/**\n * @hideinitializer\n * Message not completely received.\n */\n#define PJSIP_EPARTIALMSG       (PJSIP_ERRNO_START_PJSIP + 24)\t/* 171024 */\n\n/**\n * @hideinitializer\n * Status code is invalid.\n */\n#define PJSIP_EINVALIDSTATUS\t(PJSIP_ERRNO_START_PJSIP + 30)\t/* 171030 */\n\n/**\n * @hideinitializer\n * General Invalid URI error.\n */\n#define PJSIP_EINVALIDURI\t(PJSIP_ERRNO_START_PJSIP + 39)\t/* 171039 */\n/**\n * @hideinitializer\n * Unsupported URL scheme.\n */\n#define PJSIP_EINVALIDSCHEME    (PJSIP_ERRNO_START_PJSIP + 40)\t/* 171040 */\n/**\n * @hideinitializer\n * Missing Request-URI.\n */\n#define PJSIP_EMISSINGREQURI    (PJSIP_ERRNO_START_PJSIP + 41)\t/* 171041 */\n/**\n * @hideinitializer\n * Invalid request URI.\n */\n#define PJSIP_EINVALIDREQURI\t(PJSIP_ERRNO_START_PJSIP + 42)\t/* 171042 */\n/**\n * @hideinitializer\n * URI is too long.\n */\n#define PJSIP_EURITOOLONG\t(PJSIP_ERRNO_START_PJSIP + 43)\t/* 171043 */\n\n/**\n * @hideinitializer\n * Missing required header(s).\n */\n#define PJSIP_EMISSINGHDR       (PJSIP_ERRNO_START_PJSIP + 50)\t/* 171050 */\n/**\n * @hideinitializer\n * Invalid header field.\n */\n#define PJSIP_EINVALIDHDR\t(PJSIP_ERRNO_START_PJSIP + 51)\t/* 171051 */\n/**\n * @hideinitializer\n * Invalid Via header in response (sent-by, etc).\n */\n#define PJSIP_EINVALIDVIA\t(PJSIP_ERRNO_START_PJSIP + 52)\t/* 171052 */\n/**\n * @hideinitializer\n * Multiple Via headers in response.\n */\n#define PJSIP_EMULTIPLEVIA\t(PJSIP_ERRNO_START_PJSIP + 53)\t/* 171053 */\n/**\n * @hideinitializer\n * Missing message body.\n */\n#define PJSIP_EMISSINGBODY\t(PJSIP_ERRNO_START_PJSIP + 54)\t/* 171054 */\n/**\n * @hideinitializer\n * Invalid/unexpected method.\n */\n#define PJSIP_EINVALIDMETHOD\t(PJSIP_ERRNO_START_PJSIP + 55)\t/* 171055 */\n\n\n/************************************************************\n * TRANSPORT ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * Unsupported transport type.\n */\n#define PJSIP_EUNSUPTRANSPORT\t(PJSIP_ERRNO_START_PJSIP + 60)\t/* 171060 */\n/**\n * @hideinitializer\n * Buffer is being sent, operation still pending.\n */\n#define PJSIP_EPENDINGTX\t(PJSIP_ERRNO_START_PJSIP + 61)\t/* 171061 */\n/**\n * @hideinitializer\n * Rx buffer overflow. See also PJSIP_EMSGTOOLONG.\n */\n#define PJSIP_ERXOVERFLOW       (PJSIP_ERRNO_START_PJSIP + 62)\t/* 171062 */\n/**\n * @hideinitializer\n * This is not really an error, it just informs application that\n * transmit data has been deleted on return of pjsip_tx_data_dec_ref().\n */\n#define PJSIP_EBUFDESTROYED     (PJSIP_ERRNO_START_PJSIP + 63)\t/* 171063 */\n/**\n * @hideinitializer\n * Unsuitable transport selected. This error occurs when application\n * has explicitly requested to use a particular transport/listener,\n * but the selected transport is not suitable to send request to\n * the specified destination.\n */\n#define PJSIP_ETPNOTSUITABLE\t(PJSIP_ERRNO_START_PJSIP + 64)\t/* 171064 */\n/**\n * @hideinitializer\n * Transport not available. This error occurs for example when the SIP stack \n * is trying to use a SIP transport while the transport is being paused by \n * application.\n */\n#define PJSIP_ETPNOTAVAIL\t(PJSIP_ERRNO_START_PJSIP + 65)\t/* 171065 */\n\n/************************************************************\n * TRANSACTION ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * Transaction has just been destroyed.\n */\n#define PJSIP_ETSXDESTROYED     (PJSIP_ERRNO_START_PJSIP + 70)\t/* 171070 */\n/**\n * @hideinitializer\n * No transaction.\n */\n#define PJSIP_ENOTSX\t\t(PJSIP_ERRNO_START_PJSIP + 71)\t/* 171071 */\n\n\n/************************************************************\n * URI COMPARISON RESULTS\n ***********************************************************/\n/**\n * @hideinitializer\n * Scheme mismatch.\n */\n#define PJSIP_ECMPSCHEME\t(PJSIP_ERRNO_START_PJSIP + 80)\t/* 171080 */\n/**\n * @hideinitializer\n * User part mismatch.\n */\n#define PJSIP_ECMPUSER\t\t(PJSIP_ERRNO_START_PJSIP + 81)\t/* 171081 */\n/**\n * @hideinitializer\n * Password part mismatch.\n */\n#define PJSIP_ECMPPASSWD\t(PJSIP_ERRNO_START_PJSIP + 82)\t/* 171082 */\n/**\n * @hideinitializer\n * Host part mismatch.\n */\n#define PJSIP_ECMPHOST\t\t(PJSIP_ERRNO_START_PJSIP + 83)\t/* 171083 */\n/**\n * @hideinitializer\n * Port part mismatch.\n */\n#define PJSIP_ECMPPORT\t\t(PJSIP_ERRNO_START_PJSIP + 84)\t/* 171084 */\n/**\n * @hideinitializer\n * Transport parameter part mismatch.\n */\n#define PJSIP_ECMPTRANSPORTPRM\t(PJSIP_ERRNO_START_PJSIP + 85)\t/* 171085 */\n/**\n * @hideinitializer\n * TTL parameter part mismatch.\n */\n#define PJSIP_ECMPTTLPARAM\t(PJSIP_ERRNO_START_PJSIP + 86)\t/* 171086 */\n/**\n * @hideinitializer\n * User parameter part mismatch.\n */\n#define PJSIP_ECMPUSERPARAM\t(PJSIP_ERRNO_START_PJSIP + 87)\t/* 171087 */\n/**\n * @hideinitializer\n * Method parameter part mismatch.\n */\n#define PJSIP_ECMPMETHODPARAM\t(PJSIP_ERRNO_START_PJSIP + 88)\t/* 171088 */\n/**\n * @hideinitializer\n * Maddr parameter part mismatch.\n */\n#define PJSIP_ECMPMADDRPARAM\t(PJSIP_ERRNO_START_PJSIP + 89)\t/* 171089 */\n/**\n * @hideinitializer\n * Parameter part in other_param mismatch.\n */\n#define PJSIP_ECMPOTHERPARAM\t(PJSIP_ERRNO_START_PJSIP + 90)\t/* 171090 */\n/**\n * @hideinitializer\n * Parameter part in header_param mismatch.\n */\n#define PJSIP_ECMPHEADERPARAM\t(PJSIP_ERRNO_START_PJSIP + 91)\t/* 171091 */\n\n\n/************************************************************\n * AUTHENTICATION FRAMEWORK\n ***********************************************************/\n/**\n * @hideinitializer\n * Credential failed to authenticate. For this failure, right credential\n * for the realm has been found and used to authenticate against the challenge,\n * but the server has rejected the authorization request with 401/407 response\n * (either with no stale parameter or with \"stale=false\" parameter). In most\n * cases, this indicates that the username/password combination is incorrect.\n */\n#define PJSIP_EFAILEDCREDENTIAL\t(PJSIP_ERRNO_START_PJSIP + 100)\t/* 171100 */\n/**\n * @hideinitializer\n * No suitable credential is found to authenticate the request against \n * the received authentication challenge in 401/407 response. This often\n * is caused by different realm supplied in the credential than the realm\n * found in the challenge.\n */\n#define PJSIP_ENOCREDENTIAL\t(PJSIP_ERRNO_START_PJSIP + 101)\t/* 171101 */\n/**\n * @hideinitializer\n * Invalid/unsupported algorithm.\n */\n#define PJSIP_EINVALIDALGORITHM\t(PJSIP_ERRNO_START_PJSIP + 102)\t/* 171102 */\n/**\n * @hideinitializer\n * Invalid/unsupported qop.\n */\n#define PJSIP_EINVALIDQOP\t(PJSIP_ERRNO_START_PJSIP + 103)\t/* 171103 */\n/**\n * @hideinitializer\n * Invalid/unsupported authentication scheme.\n */\n#define PJSIP_EINVALIDAUTHSCHEME (PJSIP_ERRNO_START_PJSIP + 104)/* 171104 */\n/**\n * @hideinitializer\n * No previous challenge.\n */\n#define PJSIP_EAUTHNOPREVCHAL\t(PJSIP_ERRNO_START_PJSIP + 105)\t/* 171105 */\n/**\n * @hideinitializer\n * No authorization is found.\n */\n#define PJSIP_EAUTHNOAUTH\t(PJSIP_ERRNO_START_PJSIP + 106)\t/* 171106 */\n/**\n * @hideinitializer\n * Account not found.\n */\n#define PJSIP_EAUTHACCNOTFOUND\t(PJSIP_ERRNO_START_PJSIP + 107)\t/* 171107 */\n/**\n * @hideinitializer\n * Account is disabled.\n */\n#define PJSIP_EAUTHACCDISABLED\t(PJSIP_ERRNO_START_PJSIP + 108)\t/* 171108 */\n/**\n * @hideinitializer\n * Invalid realm.\n */\n#define PJSIP_EAUTHINVALIDREALM\t(PJSIP_ERRNO_START_PJSIP + 109)\t/* 171109 */\n/**\n * @hideinitializer\n * Invalid digest.\n */\n#define PJSIP_EAUTHINVALIDDIGEST (PJSIP_ERRNO_START_PJSIP+110)\t/* 171110 */\n/**\n * @hideinitializer\n * Maximum number of stale retries exceeded. This happens when server \n * keeps rejecting our authorization request with stale=true.\n */\n#define PJSIP_EAUTHSTALECOUNT\t(PJSIP_ERRNO_START_PJSIP + 111)\t/* 171111 */\n/**\n * @hideinitializer\n * Invalid nonce value in the challenge.\n */\n#define PJSIP_EAUTHINNONCE\t(PJSIP_ERRNO_START_PJSIP + 112)\t/* 171112 */\n/**\n * @hideinitializer\n * Invalid AKA credential.\n */\n#define PJSIP_EAUTHINAKACRED\t(PJSIP_ERRNO_START_PJSIP + 113)\t/* 171113 */\n/**\n * No challenge is found in the challenge.\n */\n#define PJSIP_EAUTHNOCHAL\t(PJSIP_ERRNO_START_PJSIP + 114)\t/* 171114 */\n\n/************************************************************\n * UA AND DIALOG ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * Missing From/To tag.\n */\n#define PJSIP_EMISSINGTAG\t (PJSIP_ERRNO_START_PJSIP+120)\t/* 171120 */\n/**\n * @hideinitializer\n * Expecting REFER method\n */\n#define PJSIP_ENOTREFER\t\t (PJSIP_ERRNO_START_PJSIP+121)\t/* 171121 */\n/**\n * @hideinitializer\n * Not associated with REFER subscription\n */\n#define PJSIP_ENOREFERSESSION\t (PJSIP_ERRNO_START_PJSIP+122)\t/* 171122 */\n\n/************************************************************\n * INVITE SESSIONS ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * Session already terminated.\n */\n#define PJSIP_ESESSIONTERMINATED (PJSIP_ERRNO_START_PJSIP+140)\t/* 171140 */\n/**\n * @hideinitializer\n * Invalid session state for the specified operation.\n */\n#define PJSIP_ESESSIONSTATE\t (PJSIP_ERRNO_START_PJSIP+141)\t/* 171141 */\n/**\n * @hideinitializer\n * The feature being requested requires the use of secure session or \n * transport.\n */\n#define PJSIP_ESESSIONINSECURE\t(PJSIP_ERRNO_START_PJSIP+142)\t/* 171142 */\n\n/************************************************************\n * TLS TRANSPORT ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * Unknown TLS error\n */\n#define PJSIP_TLS_EUNKNOWN\t(PJSIP_ERRNO_START_PJSIP+160)\t/* 171160 */\n/**\n * @hideinitializer\n * Invalid SSL protocol method.\n */\n#define PJSIP_TLS_EINVMETHOD\t(PJSIP_ERRNO_START_PJSIP+161)\t/* 171161 */\n/**\n * @hideinitializer\n * Error loading/verifying SSL CA list file.\n */\n#define PJSIP_TLS_ECACERT\t(PJSIP_ERRNO_START_PJSIP+162)\t/* 171162 */\n/**\n * @hideinitializer\n * Error loading SSL certificate chain file.\n */\n#define PJSIP_TLS_ECERTFILE\t(PJSIP_ERRNO_START_PJSIP+163)\t/* 171163 */\n/**\n * @hideinitializer\n * Error adding private key from SSL certificate file.\n */\n#define PJSIP_TLS_EKEYFILE\t(PJSIP_ERRNO_START_PJSIP+164)\t/* 171164 */\n/**\n * @hideinitializer\n * Error setting SSL cipher list.\n */\n#define PJSIP_TLS_ECIPHER\t(PJSIP_ERRNO_START_PJSIP+165)\t/* 171165 */\n/**\n * @hideinitializer\n * Error creating SSL context.\n */\n#define PJSIP_TLS_ECTX\t\t(PJSIP_ERRNO_START_PJSIP+166)\t/* 171166 */\n/**\n * @hideinitializer\n * Error creating SSL connection object.\n */\n#define PJSIP_TLS_ESSLCONN\t(PJSIP_ERRNO_START_PJSIP+167)\t/* 171167 */\n/**\n * @hideinitializer\n * Unknown error when performing SSL connect().\n */\n#define PJSIP_TLS_ECONNECT\t(PJSIP_ERRNO_START_PJSIP+168)\t/* 171168 */\n/**\n * @hideinitializer\n * Unknown error when performing SSL accept().\n */\n#define PJSIP_TLS_EACCEPT\t(PJSIP_ERRNO_START_PJSIP+169)\t/* 171169 */\n/**\n * @hideinitializer\n * Unknown error when sending SSL data\n */\n#define PJSIP_TLS_ESEND\t\t(PJSIP_ERRNO_START_PJSIP+170)\t/* 171170 */\n/**\n * @hideinitializer\n * Unknown error when reading SSL data\n */\n#define PJSIP_TLS_EREAD\t\t(PJSIP_ERRNO_START_PJSIP+171)\t/* 171171 */\n/**\n * @hideinitializer\n * SSL negotiation has exceeded the maximum configured timeout.\n */\n#define PJSIP_TLS_ETIMEDOUT\t(PJSIP_ERRNO_START_PJSIP+172)\t/* 171172 */\n/**\n * @hideinitializer\n * SSL certificate verification error.\n */\n#define PJSIP_TLS_ECERTVERIF\t(PJSIP_ERRNO_START_PJSIP+173)\t/* 171173 */\n\n\n/**\n * Get error message for the specified error code. Note that this\n * function is only able to decode PJSIP specific error code.\n * Application should use pj_strerror(), which should be able to\n * decode all error codes belonging to all subsystems (e.g. pjlib,\n * pjmedia, pjsip, etc).\n *\n * @param status    The error code.\n * @param buffer    The buffer where to put the error message.\n * @param bufsize   Size of the buffer.\n *\n * @return\t    The error message as NULL terminated string,\n *                  wrapped with pj_str_t.\n */\nPJ_DECL(pj_str_t) pjsip_strerror(pj_status_t status, \n\t\t\t\t char *buffer, pj_size_t bufsize);\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n#endif\t/* __PJSIP_SIP_ERRNO_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_event.h",
    "content": "/* $Id: sip_event.h 4154 2012-06-05 10:41:17Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_EVENT_H__\n#define __PJSIP_SIP_EVENT_H__\n\n/**\n * @file sip_event.h\n * @brief SIP Event\n */\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_EVENT Event\n * @ingroup PJSIP_CORE_CORE\n * @brief Representation of events as they are distributed among modules.\n * @{\n */\n#include <pj/types.h>\n#include <pj/timer.h>\n\n\n/** \n * Event IDs.\n */\ntypedef enum pjsip_event_id_e\n{\n    /** Unidentified event. */\n    PJSIP_EVENT_UNKNOWN,\n\n    /** Timer event, normally only used internally in transaction. */\n    PJSIP_EVENT_TIMER,\n\n    /** Message transmission event. */\n    PJSIP_EVENT_TX_MSG,\n\n    /** Message received event. */\n    PJSIP_EVENT_RX_MSG,\n\n    /** Transport error event. */\n    PJSIP_EVENT_TRANSPORT_ERROR,\n\n    /** Transaction state changed event. */\n    PJSIP_EVENT_TSX_STATE,\n\n    /** Indicates that the event was triggered by user action. */\n    PJSIP_EVENT_USER\n\n} pjsip_event_id_e;\n\n\n/**\n * This structure describe event descriptor to fully identify a SIP event.\n *\n * Events are the only way for a lower layer object to inform something\n * to higher layer objects. Normally this is achieved by means of callback,\n * i.e. the higher layer objects register a callback to handle the event on\n * the lower layer objects.\n *\n * This event descriptor is used for example by transactions, to inform\n * endpoint about events, and by transports, to inform endpoint about\n * unexpected transport error.\n */\nstruct pjsip_event\n{\n    /** This is necessary so that we can put events as a list. */\n    PJ_DECL_LIST_MEMBER(struct pjsip_event);\n\n    /** The event type, can be any value of \\b pjsip_event_id_e.\n     */\n    pjsip_event_id_e type;\n\n    /**\n     * The event body as union, which fields depends on the event type.\n     * By convention, the first member of each struct in the union must be\n     * the pointer which is relevant to the event.\n     */\n    union\n    {\n        /** Timer event. */\n        struct\n        {\n            pj_timer_entry *entry;      /**< The timer entry.           */\n        } timer;\n\n        /** Transaction state has changed event. */\n        struct\n        {\n            union\n            {\n                pjsip_rx_data   *rdata; /**< The incoming message.      */\n                pjsip_tx_data   *tdata; /**< The outgoing message.      */\n                pj_timer_entry  *timer; /**< The timer.                 */\n                pj_status_t      status;/**< Transport error status.    */\n                void            *data;  /**< Generic data.              */\n            } src;\n            pjsip_transaction   *tsx;   /**< The transaction.           */\n\t    int\t\t\t prev_state; /**< Previous state.\t*/\n            pjsip_event_id_e     type;  /**< Type of event source:      \n                                         *      - PJSIP_EVENT_TX_MSG\n                                         *      - PJSIP_EVENT_RX_MSG,\n                                         *      - PJSIP_EVENT_TRANSPORT_ERROR\n                                         *      - PJSIP_EVENT_TIMER\n                                         *      - PJSIP_EVENT_USER\n                                         */\n        } tsx_state;\n\n        /** Message transmission event. */\n        struct\n        {\n            pjsip_tx_data       *tdata; /**< The transmit data buffer.  */\n\n        } tx_msg;\n\n        /** Transmission error event. */\n        struct\n        {\n            pjsip_tx_data       *tdata; /**< The transmit data.         */\n            pjsip_transaction   *tsx;   /**< The transaction.           */\n        } tx_error;\n\n        /** Message arrival event. */\n        struct\n        {\n            pjsip_rx_data       *rdata; /**< The receive data buffer.   */\n        } rx_msg;\n\n        /** User event. */\n        struct\n        {\n            void                *user1; /**< User data 1.               */\n            void                *user2; /**< User data 2.               */\n            void                *user3; /**< User data 3.               */\n            void                *user4; /**< User data 4.               */\n        } user;\n\n    } body;\n};\n\n/**\n * Init timer event.\n */\n#define PJSIP_EVENT_INIT_TIMER(event,pentry)            \\\n        do { \\\n            (event).type = PJSIP_EVENT_TIMER;           \\\n            (event).body.timer.entry = pentry;          \\\n        } while (0)\n\n/**\n * Init tsx state event.\n */\n#define PJSIP_EVENT_INIT_TSX_STATE(event,ptsx,ptype,pdata,prev)   \\\n        do { \\\n            (event).type = PJSIP_EVENT_TSX_STATE;           \\\n            (event).body.tsx_state.tsx = ptsx;\t\t    \\\n            (event).body.tsx_state.type = ptype;            \\\n            (event).body.tsx_state.src.data = pdata;        \\\n\t    (event).body.tsx_state.prev_state = prev;\t    \\\n        } while (0)\n\n/**\n * Init tx msg event.\n */\n#define PJSIP_EVENT_INIT_TX_MSG(event,ptdata)\t\\\n        do { \\\n            (event).type = PJSIP_EVENT_TX_MSG;          \\\n            (event).body.tx_msg.tdata = ptdata;\t\t\\\n        } while (0)\n\n/**\n * Init rx msg event.\n */\n#define PJSIP_EVENT_INIT_RX_MSG(event,prdata)\t\\\n        do { \\\n            (event).type = PJSIP_EVENT_RX_MSG;\t\t\\\n            (event).body.rx_msg.rdata = prdata;\t\t\\\n        } while (0)\n\n/**\n * Init transport error event.\n */\n#define PJSIP_EVENT_INIT_TRANSPORT_ERROR(event,ptsx,ptdata)   \\\n        do { \\\n            (event).type = PJSIP_EVENT_TRANSPORT_ERROR; \\\n            (event).body.tx_error.tsx = ptsx;\t\t\\\n            (event).body.tx_error.tdata = ptdata;\t\\\n        } while (0)\n\n/**\n * Init user event.\n */\n#define PJSIP_EVENT_INIT_USER(event,u1,u2,u3,u4)    \\\n        do { \\\n            (event).type = PJSIP_EVENT_USER;        \\\n            (event).body.user.user1 = (void*)u1;     \\\n            (event).body.user.user2 = (void*)u2;     \\\n            (event).body.user.user3 = (void*)u3;     \\\n            (event).body.user.user4 = (void*)u4;     \\\n        } while (0)\n\n/**\n * Get the event string from the event ID.\n * @param e the event ID.\n * @note defined in sip_util.c\n */\nPJ_DECL(const char *) pjsip_event_str(pjsip_event_id_e e);\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_SIP_EVENT_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_module.h",
    "content": "/* $Id: sip_module.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_MODULE_H__\n#define __PJSIP_SIP_MODULE_H__\n\n/**\n * @file sip_module.h\n * @brief Module helpers\n */\n#include <pjsip/sip_types.h>\n#include <pj/list.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_MOD Modules\n * @ingroup PJSIP_CORE_CORE\n * @brief Modules are the primary means to extend PJSIP!\n * @{\n * Modules are the primary means to extend PJSIP. Without modules, PJSIP\n * would not know how to handle messages, and will simply discard all\n * incoming messages.\n *\n * Modules are registered by creating and initializing #pjsip_module \n * structure, and register the structure to PJSIP with \n * #pjsip_endpt_register_module().\n *\n * The <A HREF=\"/docs.htm\">PJSIP Developer's Guide</A>\n * has a thorough discussion on this subject, and readers are encouraged\n * to read the document for more information.\n */\n\n/**\n * The declaration for SIP module. This structure would be passed to\n * #pjsip_endpt_register_module() to register the module to PJSIP.\n */\nstruct pjsip_module\n{\n    /** To allow chaining of modules in the endpoint. */\n    PJ_DECL_LIST_MEMBER(struct pjsip_module);\n\n    /**\n     * Module name to identify the module.\n     *\n     * This field MUST be initialized before registering the module.\n     */\n    pj_str_t name;\n\n    /**\n     * Module ID. Application must initialize this field with -1 before\n     * registering the module to PJSIP. After the module is registered,\n     * this field will contain a unique ID to identify the module.\n     */\n    int id;\n\n    /**\n     * Integer number to identify module initialization and start order with\n     * regard to other modules. Higher number will make the module gets\n     * initialized later.\n     *\n     * This field MUST be initialized before registering the module.\n     */\n    int priority;\n\n    /**\n     * Optional function to be called to initialize the module. This function\n     * will be called by endpoint during module registration. If the value\n     * is NULL, then it's equal to returning PJ_SUCCESS.\n     *\n     * @param endpt\tThe endpoint instance.\n     * @return\t\tModule should return PJ_SUCCESS to indicate success.\n     */\n    pj_status_t (*load)(pjsip_endpoint *endpt);\n\n    /**\n     * Optional function to be called to start the module. This function\n     * will be called by endpoint during module registration. If the value\n     * is NULL, then it's equal to returning PJ_SUCCESS.\n     *\n     * @return\t\tModule should return zero to indicate success.\n     */\n    pj_status_t (*start)(void);\n\n    /**\n     * Optional function to be called to deinitialize the module before\n     * it is unloaded. This function will be called by endpoint during \n     * module unregistration. If the value is NULL, then it's equal to \n     * returning PJ_SUCCESS.\n     *\n     * @return\t\tModule should return PJ_SUCCESS to indicate success.\n     */\n    pj_status_t (*stop)(void);\n\n    /**\n     * Optional function to be called to deinitialize the module before\n     * it is unloaded. This function will be called by endpoint during \n     * module unregistration. If the value is NULL, then it's equal to \n     * returning PJ_SUCCESS.\n     *\n     * @param mod\tThe module.\n     *\n     * @return\t\tModule should return PJ_SUCCESS to indicate success.\n     */\n    pj_status_t (*unload)(void);\n\n    /**\n     * Optional function to be called to process incoming request message.\n     *\n     * @param rdata\tThe incoming message.\n     *\n     * @return\t\tModule should return PJ_TRUE if it handles the request,\n     *\t\t\tor otherwise it should return PJ_FALSE to allow other\n     *\t\t\tmodules to handle the request.\n     */\n    pj_bool_t (*on_rx_request)(pjsip_rx_data *rdata);\n\n    /**\n     * Optional function to be called to process incoming response message.\n     *\n     * @param rdata\tThe incoming message.\n     *\n     * @return\t\tModule should return PJ_TRUE if it handles the \n     *\t\t\tresponse, or otherwise it should return PJ_FALSE to \n     *\t\t\tallow other modules to handle the response.\n     */\n    pj_bool_t (*on_rx_response)(pjsip_rx_data *rdata);\n\n    /**\n     * Optional function to be called when transport layer is about to\n     * transmit outgoing request message.\n     *\n     * @param tdata\tThe outgoing request message.\n     *\n     * @return\t\tModule should return PJ_SUCCESS in all cases. \n     *\t\t\tIf non-zero (or PJ_FALSE) is returned, the message \n     *\t\t\twill not be sent.\n     */\n    pj_status_t (*on_tx_request)(pjsip_tx_data *tdata);\n\n    /**\n     * Optional function to be called when transport layer is about to\n     * transmit outgoing response message.\n     *\n     * @param tdata\tThe outgoing response message.\n     *\n     * @return\t\tModule should return PJ_SUCCESS in all cases. \n     *\t\t\tIf non-zero (or PJ_FALSE) is returned, the message \n     *\t\t\twill not be sent.\n     */\n    pj_status_t (*on_tx_response)(pjsip_tx_data *tdata);\n\n    /**\n     * Optional function to be called when this module is acting as \n     * transaction user for the specified transaction, when the \n     * transaction's state has changed.\n     *\n     * @param tsx\tThe transaction.\n     * @param event\tThe event which has caused the transaction state\n     *\t\t\tto change.\n     */\n    void (*on_tsx_state)(pjsip_transaction *tsx, pjsip_event *event);\n\n};\n\n\n/**\n * Module priority guidelines.\n */\nenum pjsip_module_priority\n{\n    /** \n     * This is the priority used by transport layer.\n     */\n    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER\t= 8,\n\n    /**\n     * This is the priority used by transaction layer.\n     */\n    PJSIP_MOD_PRIORITY_TSX_LAYER\t= 16,\n\n    /**\n     * This is the priority used by the user agent and proxy layer.\n     */\n    PJSIP_MOD_PRIORITY_UA_PROXY_LAYER\t= 32,\n\n    /**\n     * This is the priority used by the dialog usages.\n     */\n    PJSIP_MOD_PRIORITY_DIALOG_USAGE\t= 48,\n\n    /**\n     * This is the recommended priority to be used by applications.\n     */\n    PJSIP_MOD_PRIORITY_APPLICATION\t= 64\n};\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_SIP_MODULE_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_msg.h",
    "content": "/* $Id: sip_msg.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_MSG_H__\n#define __PJSIP_SIP_MSG_H__\n\n/**\n * @file pjsip/sip_msg.h\n * @brief SIP Message Structure.\n */\n\n#include <pjsip/sip_types.h>\n#include <pjsip/sip_uri.h>\n#include <pj/list.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_MSG Messaging Elements\n * @ingroup PJSIP_CORE\n * @brief Various SIP message elements such as methods, headers, URIs, etc.\n * @{\n */\n\n/* **************************************************************************/\n/**\n * @defgroup PJSIP_MSG_METHOD Methods\n * @brief Method names and manipulation.\n * @ingroup PJSIP_MSG\n * @{\n */\n\n/**\n * This enumeration declares SIP methods as described by RFC3261. Additional\n * methods do exist, and they are described by corresponding RFCs for the SIP\n * extentensions. Since they won't alter the characteristic of the processing\n * of the message, they don't need to be explicitly mentioned here.\n */\ntypedef enum pjsip_method_e\n{\n    PJSIP_INVITE_METHOD,    /**< INVITE method, for establishing dialogs.   */\n    PJSIP_CANCEL_METHOD,    /**< CANCEL method, for cancelling request.\t    */\n    PJSIP_ACK_METHOD,\t    /**< ACK method.\t\t\t\t    */\n    PJSIP_BYE_METHOD,\t    /**< BYE method, for terminating dialog.\t    */\n    PJSIP_REGISTER_METHOD,  /**< REGISTER method.\t\t\t    */\n    PJSIP_OPTIONS_METHOD,   /**< OPTIONS method.\t\t\t    */\n\n    PJSIP_OTHER_METHOD\t    /**< Other method.\t\t\t\t    */\n\n} pjsip_method_e;\n\n\n\n/**\n * This structure represents a SIP method.\n * Application must always use either #pjsip_method_init or #pjsip_method_set\n * to make sure that method name is initialized correctly. This way, the name\n * member will always contain a valid method string regardless whether the ID\n * is recognized or not.\n */\nstruct pjsip_method\n{\n    pjsip_method_e id;\t    /**< Method ID, from \\a pjsip_method_e. */\n    pj_str_t\t   name;    /**< Method name, which will always contain the \n\t\t\t         method string. */\n};\n\n\n/*\n * For convenience, standard method structures are defined in the library.\n */\n/** INVITE method constant. @see pjsip_get_invite_method() */\nPJ_DECL_DATA(const pjsip_method) pjsip_invite_method;\n\n/** CANCEL method constant. @see pjsip_get_cancel_method() */\nPJ_DECL_DATA(const pjsip_method) pjsip_cancel_method;\n\n/** ACK method constant. @see pjsip_get_ack_method() */\nPJ_DECL_DATA(const pjsip_method) pjsip_ack_method;\n\n/** BYE method constant. @see pjsip_get_bye_method() */\nPJ_DECL_DATA(const pjsip_method) pjsip_bye_method;\n\n/** REGISTER method constant. @see pjsip_get_register_method() */\nPJ_DECL_DATA(const pjsip_method) pjsip_register_method;\n\n/** OPTIONS method constant. @see pjsip_get_options_method() */\nPJ_DECL_DATA(const pjsip_method) pjsip_options_method;\n\n/*\n * Accessor functions for standard SIP methods.\n */\n/** Get INVITE method constant. */\nPJ_DECL(const pjsip_method*) pjsip_get_invite_method(void);\n/** Get CANCEL method constant. */\nPJ_DECL(const pjsip_method*) pjsip_get_cancel_method(void);\n/** Get ACK method constant. */\nPJ_DECL(const pjsip_method*) pjsip_get_ack_method(void);\n/** Get BYE method constant. */\nPJ_DECL(const pjsip_method*) pjsip_get_bye_method(void);\n/** Get REGISTER method constant.*/\nPJ_DECL(const pjsip_method*) pjsip_get_register_method(void);\n/** Get OPTIONS method constant. */\nPJ_DECL(const pjsip_method*) pjsip_get_options_method(void);\n\n\n/*\n * Accessor functions\n */\n\n/** \n * Initialize the method structure from a string. \n * This function will check whether the method is a known method then set\n * both the id and name accordingly.\n *\n * @param m\tThe method to initialize.\n * @param pool\tPool where memory allocation will be allocated from, if required.\n * @param str\tThe method string.\n */\nPJ_DECL(void) pjsip_method_init( pjsip_method *m, \n\t\t\t\t pj_pool_t *pool, \n\t\t\t\t const pj_str_t *str);\n\n/** \n * Initialize the method structure from a string, without cloning the string.\n * See #pjsip_method_init.\n *\n * @param m\tThe method structure to be initialized.\n * @param str\tThe method string.\n */\nPJ_DECL(void) pjsip_method_init_np( pjsip_method *m,\n\t\t\t\t    pj_str_t *str);\n\n/** \n * Set the method with the predefined method ID. \n * This function will also set the name member of the structure to the correct\n * string according to the method.\n *\n * @param m\tThe method structure.\n * @param id\tThe method ID.\n */\nPJ_DECL(void) pjsip_method_set( pjsip_method *m, pjsip_method_e id );\n\n\n/** \n * Copy one method structure to another. If the method is of the known methods,\n * then memory allocation is not required.\n *\n * @param pool\t    Pool to allocate memory from, if required.\n * @param method    The destination method to copy to.\n * @param rhs\t    The source method to copy from.\n */\nPJ_DECL(void) pjsip_method_copy( pj_pool_t *pool,\n\t\t\t\t pjsip_method *method,\n\t\t\t\t const pjsip_method *rhs );\n\n/** \n * Compare one method with another, and conveniently determine whether the \n * first method is equal, less than, or greater than the second method.\n *\n * @param m1\tThe first method.\n * @param m2\tThe second method.\n *\n * @return\tZero if equal, otherwise will return -1 if less or +1 if greater.\n */\nPJ_DECL(int) pjsip_method_cmp( const pjsip_method *m1, const pjsip_method *m2);\n\n/**\n * @}\n */\n\n/* **************************************************************************/\n/** \n * @defgroup PJSIP_MSG_HDR Header Fields\n * @brief Declarations for various SIP header fields.\n * @ingroup PJSIP_MSG\n * @{\n */\n\n/**\n * Header types, as defined by RFC3261.\n */\ntypedef enum pjsip_hdr_e\n{\n    /*\n     * These are the headers documented in RFC3261. Headers not documented\n     * there must have type PJSIP_H_OTHER, and the header type itself is \n     * recorded in the header name string.\n     *\n     * DO NOT CHANGE THE VALUE/ORDER OF THE HEADER IDs!!!.\n     */\n    PJSIP_H_ACCEPT,\n    PJSIP_H_ACCEPT_ENCODING_UNIMP,\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_ACCEPT_LANGUAGE_UNIMP,\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_ALERT_INFO_UNIMP,\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_ALLOW,\n    PJSIP_H_AUTHENTICATION_INFO_UNIMP,\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_AUTHORIZATION,\n    PJSIP_H_CALL_ID,\n    PJSIP_H_CALL_INFO_UNIMP,\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_CONTACT,\n    PJSIP_H_CONTENT_DISPOSITION_UNIMP,\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_CONTENT_ENCODING_UNIMP,\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_CONTENT_LANGUAGE_UNIMP,\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_CONTENT_LENGTH,\n    PJSIP_H_CONTENT_TYPE,\n    PJSIP_H_CSEQ,\n    PJSIP_H_DATE_UNIMP,\t\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_ERROR_INFO_UNIMP,\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_EXPIRES,\n    PJSIP_H_FROM,\n    PJSIP_H_IN_REPLY_TO_UNIMP,\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_MAX_FORWARDS,\n    PJSIP_H_MIME_VERSION_UNIMP,\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_MIN_EXPIRES,\n    PJSIP_H_ORGANIZATION_UNIMP,\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_PRIORITY_UNIMP,\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_PROXY_AUTHENTICATE,\n    PJSIP_H_PROXY_AUTHORIZATION,\n    PJSIP_H_PROXY_REQUIRE_UNIMP,\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_RECORD_ROUTE,\n    PJSIP_H_REPLY_TO_UNIMP,\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_REQUIRE,\n    PJSIP_H_RETRY_AFTER,\n    PJSIP_H_ROUTE,\n    PJSIP_H_SERVER_UNIMP,\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_SUBJECT_UNIMP,\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_SUPPORTED,\n    PJSIP_H_TIMESTAMP_UNIMP,\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_TO,\n    PJSIP_H_UNSUPPORTED,\n    PJSIP_H_USER_AGENT_UNIMP,\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_VIA,\n    PJSIP_H_WARNING_UNIMP,\t\t/* N/A, use pjsip_generic_string_hdr */\n    PJSIP_H_WWW_AUTHENTICATE,\n\n    PJSIP_H_OTHER\n\n} pjsip_hdr_e;\n\n/**\n * This structure provides the pointer to basic functions that are needed\n * for generic header operations. All header fields will have pointer to\n * this structure, so that they can be manipulated uniformly.\n */\ntypedef struct pjsip_hdr_vptr\n{\n    /** \n     * Function to clone the header. \n     *\n     * @param pool  Memory pool to allocate the new header.\n     * @param hdr   Header to clone.\n     *\n     * @return A new instance of the header.\n     */\n    void *(*clone)(pj_pool_t *pool, const void *hdr);\n\n    /** \n     * Pointer to function to shallow clone the header. \n     * Shallow cloning will just make a memory copy of the original header,\n     * thus all pointers in original header will be kept intact. Because the\n     * function does not need to perform deep copy, the operation should be\n     * faster, but the application must make sure that the original header\n     * is still valid throughout the lifetime of new header.\n     *\n     * @param pool  Memory pool to allocate the new header.\n     * @param hdr   The header to clone.\n     */\n    void *(*shallow_clone)(pj_pool_t *pool, const void *hdr);\n\n    /** Pointer to function to print the header to the specified buffer.\n     *\tReturns the length of string written, or -1 if the remaining buffer\n     *\tis not enough to hold the header.\n     *\n     *  @param hdr  The header to print.\n     *  @param buf  The buffer.\n     *  @param len  The size of the buffer.\n     *\n     *  @return\t    The size copied to buffer, or -1 if there's not enough space.\n     */\n    int (*print_on)(void *hdr, char *buf, pj_size_t len);\n\n} pjsip_hdr_vptr;\n\n\n/**\n * Generic fields for all SIP headers are declared using this macro, to make\n * sure that all headers will have exactly the same layout in their start of\n * the storage. This behaves like C++ inheritance actually.\n */\n#define PJSIP_DECL_HDR_MEMBER(hdr)   \\\n    /** List members. */\t\\\n    PJ_DECL_LIST_MEMBER(hdr);\t\\\n    /** Header type */\t\t\\\n    pjsip_hdr_e\t    type;\t\\\n    /** Header name. */\t\t\\\n    pj_str_t\t    name;\t\\\n    /** Header short name version. */\t\\\n    pj_str_t\t    sname;\t\t\\\n    /** Virtual function table. */\t\\\n    pjsip_hdr_vptr *vptr\n\n\n/**\n * Generic SIP header structure, for generic manipulation for headers in the\n * message. All header fields can be typecasted to this type.\n */\nstruct pjsip_hdr\n{\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_hdr);\n};\n\n\n/**\n * This generic function will clone any header, by calling \"clone\" function\n * in header's virtual function table.\n *\n * @param pool\t    The pool to allocate memory from.\n * @param hdr\t    The header to clone.\n *\n * @return\t    A new instance copied from the original header.\n */\nPJ_DECL(void*) pjsip_hdr_clone( pj_pool_t *pool, const void *hdr );\n\n\n/**\n * This generic function will clone any header, by calling \"shallow_clone\" \n * function in header's virtual function table.\n *\n * @param pool\t    The pool to allocate memory from.\n * @param hdr\t    The header to clone.\n *\n * @return\t    A new instance copied from the original header.\n */\nPJ_DECL(void*) pjsip_hdr_shallow_clone( pj_pool_t *pool, const void *hdr );\n\n/**\n * This generic function will print any header, by calling \"print\" \n * function in header's virtual function table.\n *\n * @param hdr  The header to print.\n * @param buf  The buffer.\n * @param len  The size of the buffer.\n *\n * @return\tThe size copied to buffer, or -1 if there's not enough space.\n */\nPJ_DECL(int) pjsip_hdr_print_on( void *hdr, char *buf, pj_size_t len);\n\n/**\n * @}\n */\n\n/* **************************************************************************/\n/**\n * @defgroup PJSIP_MSG_LINE Request and Status Line.\n * @brief Request and status line structures and manipulation.\n * @ingroup PJSIP_MSG\n * @{\n */\n\n/**\n * This structure describes SIP request line.\n */\ntypedef struct pjsip_request_line \n{\n    pjsip_method    method; /**< Method for this request line. */\n    pjsip_uri *uri;    /**< URI for this request line. */\n} pjsip_request_line;\n\n\n/**\n * This structure describes SIP status line.\n */\ntypedef struct pjsip_status_line \n{\n    int\t\tcode;\t    /**< Status code. */\n    pj_str_t\treason;\t    /**< Reason string. */\n} pjsip_status_line;\n\n\n/**\n * This enumeration lists standard SIP status codes according to RFC 3261.\n * In addition, it also declares new status class 7xx for errors generated\n * by the stack. This status class however should not get transmitted on the \n * wire.\n */\ntypedef enum pjsip_status_code\n{\n    PJSIP_SC_TRYING = 100,\n    PJSIP_SC_RINGING = 180,\n    PJSIP_SC_CALL_BEING_FORWARDED = 181,\n    PJSIP_SC_QUEUED = 182,\n    PJSIP_SC_PROGRESS = 183,\n\n    PJSIP_SC_OK = 200,\n    PJSIP_SC_ACCEPTED = 202,\n\n    PJSIP_SC_MULTIPLE_CHOICES = 300,\n    PJSIP_SC_MOVED_PERMANENTLY = 301,\n    PJSIP_SC_MOVED_TEMPORARILY = 302,\n    PJSIP_SC_USE_PROXY = 305,\n    PJSIP_SC_ALTERNATIVE_SERVICE = 380,\n\n    PJSIP_SC_BAD_REQUEST = 400,\n    PJSIP_SC_UNAUTHORIZED = 401,\n    PJSIP_SC_PAYMENT_REQUIRED = 402,\n    PJSIP_SC_FORBIDDEN = 403,\n    PJSIP_SC_NOT_FOUND = 404,\n    PJSIP_SC_METHOD_NOT_ALLOWED = 405,\n    PJSIP_SC_NOT_ACCEPTABLE = 406,\n    PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED = 407,\n    PJSIP_SC_REQUEST_TIMEOUT = 408,\n    PJSIP_SC_GONE = 410,\n    PJSIP_SC_REQUEST_ENTITY_TOO_LARGE = 413,\n    PJSIP_SC_REQUEST_URI_TOO_LONG = 414,\n    PJSIP_SC_UNSUPPORTED_MEDIA_TYPE = 415,\n    PJSIP_SC_UNSUPPORTED_URI_SCHEME = 416,\n    PJSIP_SC_BAD_EXTENSION = 420,\n    PJSIP_SC_EXTENSION_REQUIRED = 421,\n    PJSIP_SC_SESSION_TIMER_TOO_SMALL = 422,\n    PJSIP_SC_INTERVAL_TOO_BRIEF = 423,\n    PJSIP_SC_TEMPORARILY_UNAVAILABLE = 480,\n    PJSIP_SC_CALL_TSX_DOES_NOT_EXIST = 481,\n    PJSIP_SC_LOOP_DETECTED = 482,\n    PJSIP_SC_TOO_MANY_HOPS = 483,\n    PJSIP_SC_ADDRESS_INCOMPLETE = 484,\n    PJSIP_AC_AMBIGUOUS = 485,\n    PJSIP_SC_BUSY_HERE = 486,\n    PJSIP_SC_REQUEST_TERMINATED = 487,\n    PJSIP_SC_NOT_ACCEPTABLE_HERE = 488,\n    PJSIP_SC_BAD_EVENT = 489,\n    PJSIP_SC_REQUEST_UPDATED = 490,\n    PJSIP_SC_REQUEST_PENDING = 491,\n    PJSIP_SC_UNDECIPHERABLE = 493,\n\n    PJSIP_SC_INTERNAL_SERVER_ERROR = 500,\n    PJSIP_SC_NOT_IMPLEMENTED = 501,\n    PJSIP_SC_BAD_GATEWAY = 502,\n    PJSIP_SC_SERVICE_UNAVAILABLE = 503,\n    PJSIP_SC_SERVER_TIMEOUT = 504,\n    PJSIP_SC_VERSION_NOT_SUPPORTED = 505,\n    PJSIP_SC_MESSAGE_TOO_LARGE = 513,\n    PJSIP_SC_PRECONDITION_FAILURE = 580,\n\n    PJSIP_SC_BUSY_EVERYWHERE = 600,\n    PJSIP_SC_DECLINE = 603,\n    PJSIP_SC_DOES_NOT_EXIST_ANYWHERE = 604,\n    PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE = 606,\n\n    PJSIP_SC_TSX_TIMEOUT = PJSIP_SC_REQUEST_TIMEOUT,\n    /*PJSIP_SC_TSX_RESOLVE_ERROR = 702,*/\n    PJSIP_SC_TSX_TRANSPORT_ERROR = PJSIP_SC_SERVICE_UNAVAILABLE,\n\n    /* This is not an actual status code, but rather a constant\n     * to force GCC to use 32bit to represent this enum, since\n     * we have a code in PJSUA-LIB that assigns an integer\n     * to this enum (see pjsua_acc_get_info() function).\n     */\n    PJSIP_SC__force_32bit = 0x7FFFFFFF\n\n} pjsip_status_code;\n\n/**\n * Get the default status text for the status code.\n *\n * @param status_code\t    SIP Status Code\n *\n * @return\t\t    textual message for the status code.\n */ \nPJ_DECL(const pj_str_t*) pjsip_get_status_text(int status_code);\n\n/**\n * This macro returns non-zero (TRUE) if the specified status_code is\n * in the same class as the code_class.\n *\n * @param status_code\tThe status code.\n * @param code_class\tThe status code in the class (for example 100, 200).\n */\n#define PJSIP_IS_STATUS_IN_CLASS(status_code, code_class)    \\\n\t    (status_code/100 == code_class/100)\n\n/**\n * @}\n */\n\n/* **************************************************************************/\n/**\n * @addtogroup PJSIP_MSG_MEDIA Media/MIME Type\n * @brief Media/MIME type declaration and manipulations.\n * @ingroup PJSIP_MSG\n * @{\n */\n\n/**\n * This structure describes SIP media type, as used for example in \n * Accept and Content-Type header..\n */\ntypedef struct pjsip_media_type\n{\n    pj_str_t type;\t    /**< Media type. */\n    pj_str_t subtype;\t    /**< Media subtype. */\n    pjsip_param param;\t    /**< Media type parameters */\n} pjsip_media_type;\n\n\n/**\n * Initialize the media type with the specified type and subtype string.\n *\n * @param mt\t\tThe media type.\n * @param type\t\tOptionally specify the media type.\n * @param subtype\tOptionally specify the media subtype.\n */\nPJ_DECL(void) pjsip_media_type_init(pjsip_media_type *mt,\n\t\t\t\t    pj_str_t *type,\n\t\t\t\t    pj_str_t *subtype);\n\n/**\n * Initialize the media type with the specified type and subtype string.\n *\n * @param mt\t\tThe media type.\n * @param type\t\tOptionally specify the media type.\n * @param subtype\tOptionally specify the media subtype.\n */\nPJ_DECL(void) pjsip_media_type_init2(pjsip_media_type *mt,\n\t\t\t\t     char *type,\n\t\t\t\t     char *subtype);\n\n/**\n * Compare two media types.\n *\n * @param mt1\t\tThe first media type.\n * @param mt2\t\tThe second media type.\n * @param cmp_param\tSpecify how to compare the media type parameters:\n * \t\t\t - 0: do not compare parameters\n * \t\t\t - 1: compare parameters but ignore parameters that\n * \t\t\t      only appear in one of the media type.\n * \t\t\t - 2: compare the parameters.\n *\n * @return\t\tZero if both media types are equal, -1 if mt1 < mt2,\n * \t\t\t1 if mt1 > mt2.\n */\nPJ_DECL(int) pjsip_media_type_cmp(const pjsip_media_type *mt1,\n\t\t\t\t  const pjsip_media_type *mt2,\n\t\t\t\t  int cmp_param);\n\n/**\n * Copy SIP media type to another.\n *\n * @param pool\t    Pool to duplicate strings.\n * @param dst\t    Destination structure.\n * @param src\t    Source structure.\n */\nPJ_DECL(void) pjsip_media_type_cp(pj_pool_t *pool,\n\t\t\t\t  pjsip_media_type *dst,\n\t\t\t\t  const pjsip_media_type *src);\n\n/**\n * Print media type to the specified buffer.\n *\n * @param buf\t\tDestination buffer.\n * @param len\t\tLength of the buffer.\n * @param mt\t\tThe media type to be printed.\n *\n * @return\t\tThe number of characters printed to the buffer, or -1\n * \t\t\tif there's not enough space in the buffer.\n */\nPJ_DECL(int) pjsip_media_type_print(char *buf, unsigned len,\n\t\t\t\t    const pjsip_media_type *mt);\n\n/**\n * @}\n */\n\n/* **************************************************************************/\n/**\n * @addtogroup PJSIP_MSG_BODY Message Body\n * @brief SIP message body structures and manipulation.\n * @ingroup PJSIP_MSG\n * @{\n */\n\n/**\n * Generic abstraction to message body.\n * When an incoming message is parsed (pjsip_parse_msg()), the parser fills in\n * all members with the appropriate value. The 'data' and 'len' member will\n * describe portion of incoming packet which denotes the message body.\n * When application needs to attach message body to outgoing SIP message, it\n * must fill in all members of this structure. \n */\nstruct pjsip_msg_body\n{\n    /** MIME content type. \n     *  For incoming messages, the parser will fill in this member with the\n     *  content type found in Content-Type header.\n     *\n     *  For outgoing messages, application may fill in this member with\n     *  appropriate value, because the stack will generate Content-Type header\n     *  based on the value specified here.\n     *\n     *  If the content_type is empty, no Content-Type AND Content-Length header\n     *  will be added to the message. The stack assumes that application adds\n     *  these headers themselves.\n     */\n    pjsip_media_type content_type;\n\n    /** Pointer to buffer which holds the message body data. \n     *  For incoming messages, the parser will fill in this member with the\n     *  pointer to the body string.\n     *\n     *  When sending outgoing message, this member doesn't need to point to the\n     *  actual message body string. It can be assigned with arbitrary pointer,\n     *  because the value will only need to be understood by the print_body()\n     *  function. The stack itself will not try to interpret this value, but\n     *  instead will always call the print_body() whenever it needs to get the\n     *  actual body string.\n     */\n    void *data;\n\n    /** The length of the data. \n     *  For incoming messages, the parser will fill in this member with the\n     *  actual length of message body.\n     *\n     *  When sending outgoing message, again just like the \"data\" member, the\n     *  \"len\" member doesn't need to point to the actual length of the body \n     *  string.\n     */\n    unsigned len;\n\n    /** Pointer to function to print this message body. \n     *  Application must set a proper function here when sending outgoing \n     *  message.\n     *\n     *  @param msg_body\t    This structure itself.\n     *  @param buf\t    The buffer.\n     *  @param size\t    The buffer size.\n     *\n     *  @return\t\t    The length of the string printed, or -1 if there is\n     *\t\t\t    not enough space in the buffer to print the whole\n     *\t\t\t    message body.\n     */\n    int (*print_body)(struct pjsip_msg_body *msg_body, \n\t\t      char *buf, pj_size_t size);\n\n    /** Clone the data part only of this message body. Note that this only\n     *  duplicates the data part of the body instead of the whole message\n     *  body. If application wants to duplicate the entire message body\n     *  structure, it must call #pjsip_msg_body_clone().\n     *\n     *  @param pool\t    Pool used to clone the data.\n     *  @param data\t    The data inside message body, to be cloned.\n     *  @param len\t    The length of the data.\n     *\n     *  @return\t\t    New data duplicated from the original data.\n     */\n    void* (*clone_data)(pj_pool_t *pool, const void *data, unsigned len);\n\n};\n\n/**\n * General purpose function to print a SIP message body.\n * Uses the appropriate internal functions to print the string representation\n * of a SIP message body. It sets the output buffer to a statically allocated\n * buffer, so the caller is responsible to copy it.\n *\n * @param msg_body\tThe message body.\n * @param buf\t\tPointer to get the result buffer (statically allocated).\n * @param size\t\tThe size of the buffer.\n *\n * @return\t\tThe length copied to the buffer, or -1.\n */\nPJ_DECL(int) pjsip_print_body( pjsip_msg_body *msg_body,\n\t\t\t\t    char **buf, int *len);\n\n/**\n * General purpose function to textual data in a SIP body. Attach this function\n * in a SIP message body only if the data in pjsip_msg_body is a textual \n * message ready to be embedded in a SIP message. If the data in the message\n * body is not a textual body, then application must supply a custom function\n * to print that body.\n *\n * @param msg_body\tThe message body.\n * @param buf\t\tBuffer to copy the message body to.\n * @param size\t\tThe size of the buffer.\n *\n * @return\t\tThe length copied to the buffer, or -1.\n */\nPJ_DECL(int) pjsip_print_text_body( pjsip_msg_body *msg_body, \n\t\t\t\t    char *buf, pj_size_t size);\n\n/**\n * General purpose function to clone textual data in a SIP body. Attach this\n * function as \"clone_data\" member of the SIP body only if the data type\n * is a text (i.e. C string, not pj_str_t), and the length indicates the\n * length of the text.\n *\n *  @param pool\t\tPool used to clone the data.\n *  @param data\t\tTextual data.\n *  @param len\t\tThe length of the string.\n *\n *  @return\t\tNew text duplicated from the original text.\n */\nPJ_DECL(void*) pjsip_clone_text_data( pj_pool_t *pool, const void *data,\n\t\t\t\t      unsigned len);\n\n\n/**\n * Clone the message body in src_body to the dst_body. This will duplicate\n * the contents of the message body using the \\a clone_data member of the\n * source message body.\n *\n * @param pool\t\tPool to use to duplicate the message body.\n * @param dst_body\tDestination message body.\n * @param src_body\tSource message body to duplicate.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_msg_body_copy( pj_pool_t *pool,\n\t\t\t\t\t  pjsip_msg_body *dst_body,\n\t\t\t\t\t  const pjsip_msg_body *src_body );\n\t\t\t\t\t   \n\n/**\n * Create cloned message body. This will duplicate the contents of the message\n * body using the \\a clone_data member of the source message body.\n *\n * @param pool\t\tPool to use to duplicate the message body.\n * @param body\t\tSource message body to duplicate.\n *\n * @return\t\tThe cloned message body on successfull.\n */\nPJ_DECL(pjsip_msg_body*) pjsip_msg_body_clone( pj_pool_t *pool,\n\t\t\t\t\t       const pjsip_msg_body *body );\n\t\t\t\t\t   \n\n/**\n * Create a text message body. Use this function to create message body when\n * the content is a simple text. For non-text message body (e.g. \n * pjmedia_sdp_session or pj_xml_node), application must construct the message\n * manually.\n *\n * @param pool\t\tPool to allocate message body and its contents.\n * @param type\t\tMIME type (e.g. \"text\").\n * @param subtype\tMIME subtype (e.g. \"plain\").\n * @param text\t\tThe text content to be put in the message body.\n *\n * @return\t\tA new message body with the specified Content-Type and\n *\t\t\ttext.\n */\nPJ_DECL(pjsip_msg_body*) pjsip_msg_body_create( pj_pool_t *pool,\n\t\t\t\t\t        const pj_str_t *type,\n\t\t\t\t\t\tconst pj_str_t *subtype,\n\t\t\t\t\t\tconst pj_str_t *text );\n\n/**\n * @}\n */\n\n/* **************************************************************************/\n/**\n * @defgroup PJSIP_MSG_MSG Message Structure\n * @brief SIP message (request and response) structure and operations.\n * @ingroup PJSIP_MSG\n * @{\n */\n\n/**\n * Message type (request or response).\n */\ntypedef enum pjsip_msg_type_e\n{\n    PJSIP_REQUEST_MSG,\t    /**< Indicates request message. */\n    PJSIP_RESPONSE_MSG\t    /**< Indicates response message. */\n} pjsip_msg_type_e;\n\n\n/**\n * This structure describes a SIP message.\n */\nstruct pjsip_msg\n{\n    /** Message type (ie request or response). */\n    pjsip_msg_type_e  type;\n\n    /** The first line of the message can be either request line for request\n     *\tmessages, or status line for response messages. It is represented here\n     *  as a union.\n     */\n    union\n    {\n\t/** Request Line. */\n\tstruct pjsip_request_line   req;\n\n\t/** Status Line. */\n\tstruct pjsip_status_line    status;\n    } line;\n\n    /** List of message headers. */\n    pjsip_hdr hdr;\n\n    /** Pointer to message body, or NULL if no message body is attached to\n     *\tthis mesage. \n     */\n    pjsip_msg_body *body;\n};\n\n\n/** \n * Create new request or response message.\n *\n * @param pool\t    The pool.\n * @param type\t    Message type.\n * @return\t    New message, or THROW exception if failed.\n */\nPJ_DECL(pjsip_msg*)  pjsip_msg_create( pj_pool_t *pool, pjsip_msg_type_e type);\n\n\n/**\n * Perform a deep clone of a SIP message.\n *\n * @param pool\t    The pool for creating the new message.\n * @param msg\t    The message to be duplicated.\n *\n * @return\t    New message, which is duplicated from the original \n *\t\t    message.\n */\nPJ_DECL(pjsip_msg*) pjsip_msg_clone( pj_pool_t *pool, const pjsip_msg *msg);\n\n\n/** \n * Find a header in the message by the header type.\n *\n * @param msg\t    The message.\n * @param type\t    The header type to find.\n * @param start\t    The first header field where the search should begin.\n *\t\t    If NULL is specified, then the search will begin from the\n *\t\t    first header, otherwise the search will begin at the\n *\t\t    specified header.\n *\n * @return\t    The header field, or NULL if no header with the specified \n *\t\t    type is found.\n */\nPJ_DECL(void*)  pjsip_msg_find_hdr( const pjsip_msg *msg, \n\t\t\t\t    pjsip_hdr_e type, const void *start);\n\n/** \n * Find a header in the message by its name.\n *\n * @param msg\t    The message.\n * @param name\t    The header name to find.\n * @param start\t    The first header field where the search should begin.\n *\t\t    If NULL is specified, then the search will begin from the\n *\t\t    first header, otherwise the search will begin at the\n *\t\t    specified header.\n *\n * @return\t    The header field, or NULL if no header with the specified \n *\t\t    type is found.\n */\nPJ_DECL(void*)  pjsip_msg_find_hdr_by_name( const pjsip_msg *msg, \n\t\t\t\t\t    const pj_str_t *name, \n\t\t\t\t\t    const void *start);\n\n/** \n * Find a header in the message by its name and short name version.\n *\n * @param msg\t    The message.\n * @param name\t    The header name to find.\n * @param sname\t    The short name version of the header name.\n * @param start\t    The first header field where the search should begin.\n *\t\t    If NULL is specified, then the search will begin from the\n *\t\t    first header, otherwise the search will begin at the\n *\t\t    specified header.\n *\n * @return\t    The header field, or NULL if no header with the specified \n *\t\t    type is found.\n */\nPJ_DECL(void*)  pjsip_msg_find_hdr_by_names(const pjsip_msg *msg, \n\t\t\t\t\t    const pj_str_t *name, \n\t\t\t\t\t    const pj_str_t *sname,\n\t\t\t\t\t    const void *start);\n\n/** \n * Find and remove a header in the message. \n *\n * @param msg\t    The message.\n * @param hdr\t    The header type to find.\n * @param start\t    The first header field where the search should begin,\n *\t\t    or NULL to search from the first header in the message.\n *\n * @return\t    The header field, or NULL if not found.\n */\nPJ_DECL(void*)  pjsip_msg_find_remove_hdr( pjsip_msg *msg, \n\t\t\t\t\t   pjsip_hdr_e hdr, void *start);\n\n/**\n * Find and remove a header in the message.\n *\n * @param msg\t    The message.\n * @param name\t    The header name to find.\n * @param start\t    The first header field where the search should begin,\n *\t\t    or NULL to search from the first header in the message.\n *\n * @return\t    The header field, or NULL if not found.\n */\nPJ_DECL(void*)  pjsip_msg_find_remove_hdr_by_name( pjsip_msg *msg,\n                                                   pj_str_t *name,\n                                                   void *start);\n\n/** \n * Add a header to the message, putting it last in the header list.\n *\n * @param msg\t    The message.\n * @param hdr\t    The header to add.\n *\n * @bug Once the header is put in a list (or message), it can not be put in \n *      other list (or message). Otherwise Real Bad Thing will happen.\n */\nPJ_INLINE(void) pjsip_msg_add_hdr( pjsip_msg *msg, pjsip_hdr *hdr )\n{\n    pj_list_insert_before(&msg->hdr, hdr);\n}\n\n/** \n * Add header field to the message, putting it in the front of the header list.\n *\n * @param msg\tThe message.\n * @param hdr\tThe header to add.\n *\n * @bug Once the header is put in a list (or message), it can not be put in \n *      other list (or message). Otherwise Real Bad Thing will happen.\n */\nPJ_INLINE(void) pjsip_msg_insert_first_hdr( pjsip_msg *msg, pjsip_hdr *hdr )\n{\n    pj_list_insert_after(&msg->hdr, hdr);\n}\n\n/** \n * Print the message to the specified buffer. \n *\n * @param msg\tThe message to print.\n * @param buf\tThe buffer\n * @param size\tThe size of the buffer.\n *\n * @return\tThe length of the printed characters (in bytes), or NEGATIVE\n *\t\tvalue if the message is too large for the specified buffer.\n */\nPJ_DECL(pj_ssize_t) pjsip_msg_print(const pjsip_msg *msg, \n\t\t\t\t    char *buf, pj_size_t size);\n\n\n/*\n * Some usefull macros to find common headers.\n */\n\n\n/**\n * Find Call-ID header.\n *\n * @param msg\tThe message.\n * @return\tCall-ID header instance.\n */\n#define PJSIP_MSG_CID_HDR(msg) \\\n\t    ((pjsip_cid_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_CALL_ID, NULL))\n\n/**\n * Find CSeq header.\n *\n * @param msg\tThe message.\n * @return\tCSeq header instance.\n */\n#define PJSIP_MSG_CSEQ_HDR(msg) \\\n\t    ((pjsip_cseq_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL))\n\n/**\n * Find From header.\n *\n * @param msg\tThe message.\n * @return\tFrom header instance.\n */\n#define PJSIP_MSG_FROM_HDR(msg) \\\n\t    ((pjsip_from_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_FROM, NULL))\n\n/**\n * Find To header.\n *\n * @param msg\tThe message.\n * @return\tTo header instance.\n */\n#define PJSIP_MSG_TO_HDR(msg) \\\n\t    ((pjsip_to_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_TO, NULL))\n\n\n/**\n * @}\n */\n\n/* **************************************************************************/\n/**\n * @addtogroup PJSIP_MSG_HDR\n * @{\n */\n\n/**\n * Generic SIP header, which contains hname and a string hvalue.\n * Note that this header is not supposed to be used as 'base' class for headers.\n */\ntypedef struct pjsip_generic_string_hdr\n{\n    /** Standard header field. */\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_string_hdr);\n    /** hvalue */\n    pj_str_t hvalue;\n} pjsip_generic_string_hdr;\n\n\n/**\n * Create a new instance of generic header. A generic header can have an\n * arbitrary header name.\n *\n * @param pool\t    The pool.\n * @param hname\t    The header name to be assigned to the header, or NULL to\n *\t\t    assign the header name with some string.\n * @param hvalue    Optional string to be assigned as the value.\n *\n * @return\t    The header, or THROW exception.\n */\nPJ_DECL(pjsip_generic_string_hdr*) \npjsip_generic_string_hdr_create( pj_pool_t *pool, \n\t\t\t\t const pj_str_t *hname,\n\t\t\t\t const pj_str_t *hvalue);\n\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n * @param hname\t    The header name to be assigned to the header, or NULL to\n *\t\t    assign the header name with some string later.\n * @param hvalue    Optional string to be assigned as the value.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_generic_string_hdr*) \npjsip_generic_string_hdr_init( pj_pool_t *pool,\n\t\t\t       void *mem,\n\t\t\t       const pj_str_t *hname,\n\t\t\t       const pj_str_t *hvalue);\n\n\n/**\n * Construct a generic string header without allocating memory from the pool.\n * This function is useful to create a temporary header which life-time is\n * very short (for example, creating the header in the stack to be passed\n * as argument to a function which will copy the header).\n *\n * @param h\t    The header to be initialized.\n * @param hname\t    The header name to be assigned to the header, or NULL to\n *\t\t    assign the header name with some string.\n * @param hvalue    Optional string to be assigned as the value.\n *\n * @return\t    The header, or THROW exception.\n */\nPJ_DECL(void) pjsip_generic_string_hdr_init2(pjsip_generic_string_hdr *h,\n\t\t\t\t\t     pj_str_t *hname,\n\t\t\t\t\t     pj_str_t *hvalue);\n\n\n/* **************************************************************************/\n\n/**\n * Generic SIP header, which contains hname and an integer ivalue.\n */\ntypedef struct pjsip_generic_int_hdr\n{\n    /** Standard header field. */\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_int_hdr);\n    /** ivalue */\n    pj_int32_t ivalue;\n} pjsip_generic_int_hdr;\n\n\n/**\n * Create a new instance of generic header. A generic header can have an\n * arbitrary header name.\n *\n * @param pool\t    The pool.\n * @param hname\t    The header name to be assigned to the header, or NULL to\n *\t\t    assign the header name with some string.\n * @param hvalue    The value to be assigned to the header.\n *\n * @return\t    The header, or THROW exception.\n */\nPJ_DECL(pjsip_generic_int_hdr*) pjsip_generic_int_hdr_create( pj_pool_t *pool,\n\t\t\t\t\t\t      const pj_str_t *hname,\n\t\t\t\t\t\t      int hvalue );\n\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n * @param hname\t    The header name to be assigned to the header, or NULL to\n *\t\t    assign the header name with some string later.\n * @param value\t    Value to be assigned to the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_generic_int_hdr*) pjsip_generic_int_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t\t    void *mem,\n\t\t\t\t\t\t\t    const pj_str_t *hname,\n\t\t\t\t\t\t\t    int value );\n\n/* **************************************************************************/\n\n/** Maximum elements in the header array. */\n#define PJSIP_GENERIC_ARRAY_MAX_COUNT\t32\n\n/**\n * Generic array of string header.\n */\ntypedef struct pjsip_generic_array_hdr\n{\n    /** Standard header fields. */\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_array_hdr);\n\n    /** Number of tags/elements. */\n    unsigned\tcount;\n\n    /** Tags/elements. */\n    pj_str_t\tvalues[PJSIP_GENERIC_ARRAY_MAX_COUNT];\n\n} pjsip_generic_array_hdr;\n\n/**\n * Create generic array header.\n *\n * @param pool\t    Pool to allocate memory from.\n * @param hname\t    Header name.\n *\n * @return\t    New generic array header.\n */\nPJ_DECL(pjsip_generic_array_hdr*) pjsip_generic_array_hdr_create(pj_pool_t *pool,\n\t\t\t\t\t\t\t     const pj_str_t *hname);\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n * @param hname\t    The header name to be assigned to the header, or NULL to\n *\t\t    assign the header name with some string later.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_generic_array_hdr*) pjsip_generic_array_hdr_init(pj_pool_t *pool,\n\t\t\t\t\t\t\t       void *mem,\n\t\t\t\t\t\t\t       const pj_str_t *hname);\n\n\n/* **************************************************************************/\n\n/** Accept header. */\ntypedef pjsip_generic_array_hdr pjsip_accept_hdr;\n\n/** Maximum fields in Accept header. */\n#define PJSIP_MAX_ACCEPT_COUNT\tPJSIP_GENERIC_ARRAY_MAX_COUNT\n\n/**\n * Create new Accept header instance.\n *\n * @param pool\t    The pool.\n *\n * @return\t    New Accept header instance.\n */\nPJ_DECL(pjsip_accept_hdr*) pjsip_accept_hdr_create(pj_pool_t *pool);\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_accept_hdr*) pjsip_accept_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t  void *mem );\n\n\n/* **************************************************************************/\n\n/**\n * Allow header.\n */\ntypedef pjsip_generic_array_hdr pjsip_allow_hdr;\n\n/**\n * Create new Allow header instance.\n *\n * @param pool\t    The pool.\n *\n * @return\t    New Allow header instance.\n */\nPJ_DECL(pjsip_allow_hdr*) pjsip_allow_hdr_create(pj_pool_t *pool);\n\n\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_allow_hdr*) pjsip_allow_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\tvoid *mem );\n\n/* **************************************************************************/\n\n/**\n * Call-ID header.\n */\ntypedef struct pjsip_cid_hdr\n{\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_cid_hdr);\n    pj_str_t id;\t    /**< Call-ID string. */\n} pjsip_cid_hdr;\n\n\n/**\n * Create new Call-ID header.\n *\n * @param pool\tThe pool.\n *\n * @return\tnew Call-ID header.\n */\nPJ_DECL(pjsip_cid_hdr*) pjsip_cid_hdr_create( pj_pool_t *pool );\n\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_cid_hdr*) pjsip_cid_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t    void *mem );\n\n\n\n/* **************************************************************************/\n/**\n * Content-Length header.\n */\ntypedef struct pjsip_clen_hdr\n{\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_clen_hdr);\n    int len;\t/**< Content length. */\n} pjsip_clen_hdr;\n\n/**\n * Create new Content-Length header.\n *\n * @param pool\tthe pool.\n * @return\tA new Content-Length header instance.\n */\nPJ_DECL(pjsip_clen_hdr*) pjsip_clen_hdr_create( pj_pool_t *pool );\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_clen_hdr*) pjsip_clen_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t      void *mem );\n\n\n/* **************************************************************************/\n/**\n * CSeq header.\n */\ntypedef struct pjsip_cseq_hdr\n{\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_cseq_hdr);\n    pj_int32_t\t    cseq;\t/**< CSeq number. */\n    pjsip_method    method;\t/**< CSeq method. */\n} pjsip_cseq_hdr;\n\n\n/** Create new  CSeq header. \n *\n *  @param pool\tThe pool.\n *  @return A new CSeq header instance.\n */\nPJ_DECL(pjsip_cseq_hdr*) pjsip_cseq_hdr_create( pj_pool_t *pool );\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_cseq_hdr*) pjsip_cseq_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t      void *mem );\n\n/* **************************************************************************/\n/**\n * Contact header.\n * In this library, contact header only contains single URI. If a message has\n * multiple URI in the Contact header, the URI will be put in separate Contact\n * headers.\n */\ntypedef struct pjsip_contact_hdr\n{\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_contact_hdr);\n    int\t\t    star;\t    /**< The contact contains only a '*' character */\n    pjsip_uri\t   *uri;\t    /**< URI in the contact. */\n    int\t\t    q1000;\t    /**< The \"q\" value times 1000 (to avoid float) */\n    pj_int32_t\t    expires;\t    /**< Expires parameter, otherwise -1 if not present. */\n    pjsip_param\t    other_param;    /**< Other parameters, concatenated in a single string. */\n} pjsip_contact_hdr;\n\n\n/**\n * Create a new Contact header.\n *\n * @param pool\tThe pool.\n * @return\tA new instance of Contact header.\n */\nPJ_DECL(pjsip_contact_hdr*) pjsip_contact_hdr_create( pj_pool_t *pool );\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_contact_hdr*) pjsip_contact_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t    void *mem );\n\n\n/* **************************************************************************/\n/**\n * Content-Type.\n */\ntypedef struct pjsip_ctype_hdr\n{\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_ctype_hdr);\n    pjsip_media_type media; /**< Media type. */\n} pjsip_ctype_hdr;\n\n\n/**\n * Create a nwe Content Type header.\n *\n * @param pool\tThe pool.\n * @return\tA new Content-Type header.\n */\nPJ_DECL(pjsip_ctype_hdr*) pjsip_ctype_hdr_create( pj_pool_t *pool );\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_ctype_hdr*) pjsip_ctype_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\tvoid *mem );\n\n/* **************************************************************************/\n/** Expires header. */\ntypedef pjsip_generic_int_hdr pjsip_expires_hdr;\n\n/**\n * Create a new Expires header.\n *\n * @param pool\t    The pool.\n * @param value\t    The expiration value.\n *\n * @return\t    A new Expires header.\n */\nPJ_DECL(pjsip_expires_hdr*) pjsip_expires_hdr_create( pj_pool_t *pool,\n\t\t\t\t\t\t      int value);\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n * @param value\t    The expiration value.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_expires_hdr*) pjsip_expires_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t    void *mem,\n\t\t\t\t\t\t    int value );\n\n\n\n/* **************************************************************************/\n/**\n * To or From header.\n */\ntypedef struct pjsip_fromto_hdr\n{\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_fromto_hdr);\n    pjsip_uri\t    *uri;\t    /**< URI in From/To header. */\n    pj_str_t\t     tag;\t    /**< Header \"tag\" parameter. */\n    pjsip_param\t     other_param;   /**< Other params, concatenated as a single string. */\n} pjsip_fromto_hdr;\n\n/** Alias for From header. */\ntypedef pjsip_fromto_hdr pjsip_from_hdr;\n\n/** Alias for To header. */\ntypedef pjsip_fromto_hdr pjsip_to_hdr;\n\n/**\n * Create a From header.\n *\n * @param pool\tThe pool.\n * @return\tNew instance of From header.\n */\nPJ_DECL(pjsip_from_hdr*) pjsip_from_hdr_create( pj_pool_t *pool );\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_from_hdr*) pjsip_from_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t      void *mem );\n\n/**\n * Create a To header.\n *\n * @param pool\tThe pool.\n * @return\tNew instance of To header.\n */\nPJ_DECL(pjsip_to_hdr*)   pjsip_to_hdr_create( pj_pool_t *pool );\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_to_hdr*) pjsip_to_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t  void *mem );\n\n/**\n * Convert the header to a From header.\n *\n * @param hdr\t    The generic from/to header.\n * @return\t    \"From\" header.\n */\nPJ_DECL(pjsip_from_hdr*) pjsip_fromto_hdr_set_from( pjsip_fromto_hdr *hdr );\n\n/**\n * Convert the header to a To header.\n *\n * @param hdr\t    The generic from/to header.\n * @return\t    \"To\" header.\n */\nPJ_DECL(pjsip_to_hdr*)   pjsip_fromto_hdr_set_to( pjsip_fromto_hdr *hdr );\n\n\n/* **************************************************************************/\n/**\n * Max-Forwards header.\n */\ntypedef pjsip_generic_int_hdr pjsip_max_fwd_hdr;\n\n/**\n * Create new Max-Forwards header instance.\n *\n * @param pool\t    The pool.\n * @param value\t    The Max-Forwards value.\n *\n * @return\t    New Max-Forwards header instance.\n */\nPJ_DECL(pjsip_max_fwd_hdr*) \npjsip_max_fwd_hdr_create(pj_pool_t *pool, int value);\n\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n * @param value\t    The Max-Forwards value.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_max_fwd_hdr*) \npjsip_max_fwd_hdr_init( pj_pool_t *pool, void *mem, int value );\n\n\n/* **************************************************************************/\n/**\n * Min-Expires header.\n */\ntypedef pjsip_generic_int_hdr pjsip_min_expires_hdr;\n\n/**\n * Create new Min-Expires header instance.\n *\n * @param pool\t    The pool.\n * @param value\t    The Min-Expires value.\n *\n * @return\t    New Min-Expires header instance.\n */\nPJ_DECL(pjsip_min_expires_hdr*) pjsip_min_expires_hdr_create(pj_pool_t *pool,\n\t\t\t\t\t\t\t     int value);\n\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n * @param value\t    The Min-Expires value.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_min_expires_hdr*) pjsip_min_expires_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t\t    void *mem,\n\t\t\t\t\t\t\t    int value );\n\n\n/* **************************************************************************/\n/**\n * Record-Route and Route headers.\n */\ntypedef struct pjsip_routing_hdr\n{\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_routing_hdr);  /**< Generic header fields. */\n    pjsip_name_addr  name_addr;\t  /**< The URL in the Route/Record-Route header. */\n    pjsip_param\t     other_param; /**< Other parameter. */\n} pjsip_routing_hdr;\n\n/** Alias for Record-Route header. */\ntypedef pjsip_routing_hdr pjsip_rr_hdr;\n\n/** Alias for Route header. */\ntypedef pjsip_routing_hdr pjsip_route_hdr;\n\n\n/** \n * Create new Record-Route header from the pool. \n *\n * @param pool\tThe pool.\n * @return\tA new instance of Record-Route header.\n */\nPJ_DECL(pjsip_rr_hdr*)\t    pjsip_rr_hdr_create( pj_pool_t *pool );\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_rr_hdr*) pjsip_rr_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t  void *mem );\n\n/** \n * Create new Route header from the pool. \n *\n * @param pool\tThe pool.\n * @return\tA new instance of \"Route\" header.\n */\nPJ_DECL(pjsip_route_hdr*)   pjsip_route_hdr_create( pj_pool_t *pool );\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_route_hdr*) pjsip_route_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t        void *mem );\n\n/** \n * Convert generic routing header to Record-Route header. \n *\n * @param r\tThe generic routing header, or a \"Routing\" header.\n * @return\tRecord-Route header.\n */\nPJ_DECL(pjsip_rr_hdr*)\t    pjsip_routing_hdr_set_rr( pjsip_routing_hdr *r );\n\n/** \n * Convert generic routing header to \"Route\" header. \n *\n * @param r\tThe generic routing header, or a \"Record-Route\" header.\n * @return\t\"Route\" header.\n */\nPJ_DECL(pjsip_route_hdr*)   pjsip_routing_hdr_set_route( pjsip_routing_hdr *r );\n\n/* **************************************************************************/\n/**\n * Require header.\n */\ntypedef pjsip_generic_array_hdr pjsip_require_hdr;\n\n/**\n * Create new Require header instance.\n *\n * @param pool\t    The pool.\n *\n * @return\t    New Require header instance.\n */\nPJ_DECL(pjsip_require_hdr*) pjsip_require_hdr_create(pj_pool_t *pool);\n\n/**\n * Initialize a preallocated memory with the header structure. This function\n * should only be called when application uses its own memory allocation to\n * allocate memory block for the specified header (e.g. in C++, when the \n * header is allocated with \"new\" operator).\n * For normal applications, they should use pjsip_xxx_hdr_create() instead,\n * which allocates memory and initialize it in one go.\n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_require_hdr*) pjsip_require_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t    void *mem );\n\n\n/* **************************************************************************/\n/**\n * Retry-After header.\n */\ntypedef struct pjsip_retry_after_hdr\n{\n    /** Standard header field. */\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_retry_after_hdr); \n    pj_int32_t\tivalue;\t\t/**< Retry-After value\t    */\n    pjsip_param\tparam;\t\t/**< Optional parameters    */\n    pj_str_t\tcomment;\t/**< Optional comments.\t    */\n} pjsip_retry_after_hdr;\n\n\n/**\n * Create new Retry-After header instance.\n *\n * @param pool\t    The pool.\n * @param value\t    The Retry-After value.\n *\n * @return\t    New Retry-After header instance.\n */\nPJ_DECL(pjsip_retry_after_hdr*) pjsip_retry_after_hdr_create(pj_pool_t *pool,\n\t\t\t\t\t\t\t     int value);\n\n/**\n * Initialize a preallocated memory with the header structure. \n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n * @param value\t    The Retry-After value.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_retry_after_hdr*) pjsip_retry_after_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t\t    void *mem,\n\t\t\t\t\t\t\t    int value );\n\n\n/* **************************************************************************/\n/**\n * Supported header.\n */\ntypedef pjsip_generic_array_hdr pjsip_supported_hdr;\n\n/**\n * Create new Supported header instance.\n *\n * @param pool\t    The pool.\n *\n * @return\t    New Supported header instance.\n */\nPJ_DECL(pjsip_supported_hdr*) pjsip_supported_hdr_create(pj_pool_t *pool);\n\n/**\n * Initialize a preallocated memory with the header structure. \n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_supported_hdr*) pjsip_supported_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t\tvoid *mem );\n\n/* **************************************************************************/\n/**\n * Unsupported header.\n */\ntypedef pjsip_generic_array_hdr pjsip_unsupported_hdr;\n\n/**\n * Create new Unsupported header instance.\n *\n * @param pool\t    The pool.\n *\n * @return\t    New Unsupported header instance.\n */\nPJ_DECL(pjsip_unsupported_hdr*) pjsip_unsupported_hdr_create(pj_pool_t *pool);\n\n/**\n * Initialize a preallocated memory with the header structure. \n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_unsupported_hdr*) pjsip_unsupported_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t\t    void *mem );\n\n/* **************************************************************************/\n/**\n * SIP Via header.\n * In this implementation, Via header can only have one element in each header.\n * If a message arrives with multiple elements in a single Via, then they will\n * be split up into multiple Via headers.\n */\ntypedef struct pjsip_via_hdr\n{\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_via_hdr);\n    pj_str_t\t     transport;\t    /**< Transport type. */\n    pjsip_host_port  sent_by;\t    /**< Host and optional port */\n    int\t\t     ttl_param;\t    /**< TTL parameter, or -1 if it's not specified. */\n    int\t\t     rport_param;   /**< \"rport\" parameter, 0 to specify without\n\t\t\t\t\t port number, -1 means doesn't exist. */\n    pj_str_t\t     maddr_param;   /**< \"maddr\" parameter. */\n    pj_str_t\t     recvd_param;   /**< \"received\" parameter. */\n    pj_str_t\t     branch_param;  /**< \"branch\" parameter. */\n    pjsip_param\t     other_param;   /**< Other parameters, concatenated as single string. */\n    pj_str_t\t     comment;\t    /**< Comment. */\n} pjsip_via_hdr;\n\n/**\n * Create a new Via header.\n *\n * @param pool\t    The pool.\n * @return\t    A new \"Via\" header instance.\n */\nPJ_DECL(pjsip_via_hdr*) pjsip_via_hdr_create( pj_pool_t *pool );\n\n/**\n * Initialize a preallocated memory with the header structure. \n *\n * @param pool\t    Pool for additional memory allocation if required.\n * @param mem\t    Pre-allocated memory to be initialized as the header.\n *\n * @return\t    The header instance, which points to the same memory \n *\t\t    location as the mem argument.\n */\nPJ_DECL(pjsip_via_hdr*) pjsip_via_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t    void *mem );\n\n/* **************************************************************************/\n/**\n * SIP Warning header.\n * In this version, Warning header is just a typedef for generic string \n * header.\n */\ntypedef pjsip_generic_string_hdr pjsip_warning_hdr;\n\n/**\n * Create a warning header with the specified contents.\n *\n * @param pool\t    Pool to allocate memory from.\n * @param code\t    Warning code, 300-399.\n * @param host\t    The host portion of the Warning header.\n * @param text\t    The warning text, which MUST not be quoted with\n *\t\t    double quote.\n *\n * @return\t    The Warning header field.\n */\nPJ_DECL(pjsip_warning_hdr*) pjsip_warning_hdr_create( pj_pool_t *pool,\n\t\t\t\t\t\t      int code,\n\t\t\t\t\t\t      const pj_str_t *host,\n\t\t\t\t\t\t      const pj_str_t *text);\n\n/**\n * Create a warning header and initialize the contents from the error\n * message for the specified status code. The warning code will be\n * set to 399.\n *\n * @param pool\t    Pool to allocate memory from.\n * @param host\t    The host portion of the Warning header.\n * @param status    The error status code, which error text will be\n *\t\t    put in as the Warning text.\n *\n * @return\t    The Warning header field.\n */\nPJ_DECL(pjsip_warning_hdr*) \npjsip_warning_hdr_create_from_status( pj_pool_t *pool,\n\t\t\t\t      const pj_str_t *host,\n\t\t\t\t      pj_status_t status);\n\n/* **************************************************************************/\n/** Accept-Encoding header. */\ntypedef pjsip_generic_string_hdr pjsip_accept_encoding_hdr;\n\n/** Create Accept-Encoding header. */\n#define pjsip_accept_encoding_hdr_create pjsip_generic_string_hdr_create\n\n/** Accept-Language header. */\ntypedef pjsip_generic_string_hdr pjsip_accept_lang_hdr;\n\n/** Create Accept-Language header. */\n#define pjsip_accept_lang_hdr_create pjsip_generic_string_hdr_create\n\n/** Alert-Info header. */\ntypedef pjsip_generic_string_hdr pjsip_alert_info_hdr;\n\n/** Create Alert-Info header. */\n#define pjsip_alert_info_hdr_create pjsip_generic_string_hdr_create\n\n/** Authentication-Info header. */\ntypedef pjsip_generic_string_hdr pjsip_auth_info_hdr;\n\n/** Create Authentication-Info header. */\n#define pjsip_auth_info_hdr_create pjsip_generic_string_hdr_create\n\n/** Call-Info header. */\ntypedef pjsip_generic_string_hdr pjsip_call_info_hdr;\n\n/** Create Call-Info header. */\n#define pjsip_call_info_hdr_create pjsip_generic_string_hdr_create\n\n/** Content-Disposition header. */\ntypedef pjsip_generic_string_hdr pjsip_content_disposition_hdr;\n\n/** Create Content-Disposition header. */\n#define pjsip_content_disposition_hdr_create pjsip_generic_string_hdr_create\n\n/** Content-Encoding header. */\ntypedef pjsip_generic_string_hdr pjsip_content_encoding_hdr;\n\n/** Create Content-Encoding header. */\n#define pjsip_content_encoding_hdr_create pjsip_generic_string_hdr_create\n\n/** Content-Language header. */\ntypedef pjsip_generic_string_hdr pjsip_content_lang_hdr;\n\n/** Create Content-Language header. */\n#define pjsip_content_lang_hdr_create pjsip_generic_string_hdr_create\n\n/** Date header. */\ntypedef pjsip_generic_string_hdr pjsip_date_hdr;\n\n/** Create Date header. */\n#define pjsip_date_hdr_create pjsip_generic_string_hdr_create\n\n/** Error-Info header. */\ntypedef pjsip_generic_string_hdr pjsip_err_info_hdr;\n\n/** Create Error-Info header. */\n#define pjsip_err_info_hdr_create pjsip_generic_string_hdr_create\n\n/** In-Reply-To header. */\ntypedef pjsip_generic_string_hdr pjsip_in_reply_to_hdr;\n\n/** Create In-Reply-To header. */\n#define pjsip_in_reply_to_hdr_create pjsip_generic_string_hdr_create\n\n/** MIME-Version header. */\ntypedef pjsip_generic_string_hdr pjsip_mime_version_hdr;\n\n/** Create MIME-Version header. */\n#define pjsip_mime_version_hdr_create pjsip_generic_string_hdr_create\n\n/** Organization header. */\ntypedef pjsip_generic_string_hdr pjsip_organization_hdr;\n\n/** Create Organization header. */\n#define pjsip_organization_hdr_create pjsip_genric_string_hdr_create\n\n/** Priority header. */\ntypedef pjsip_generic_string_hdr pjsip_priority_hdr;\n\n/** Create Priority header. */\n#define pjsip_priority_hdr_create pjsip_generic_string_hdr_create\n\n/** Proxy-Require header. */\ntypedef pjsip_generic_string_hdr pjsip_proxy_require_hdr;\n\n/** Reply-To header. */\ntypedef pjsip_generic_string_hdr pjsip_reply_to_hdr;\n\n/** Create Reply-To header. */\n#define pjsip_reply_to_hdr_create pjsip_generic_string_hdr_create\n\n/** Server header. */\ntypedef pjsip_generic_string_hdr pjsip_server_hdr;\n\n/** Create Server header. */\n#define pjsip_server_hdr_create pjsip_generic_string_hdr_create\n\n/** Subject header. */\ntypedef pjsip_generic_string_hdr pjsip_subject_hdr;\n\n/** Create Subject header. */\n#define pjsip_subject_hdr_create pjsip_generic_string_hdr_create\n\n/** Timestamp header. */\ntypedef pjsip_generic_string_hdr pjsip_timestamp_hdr;\n\n/** Create Timestamp header. */\n#define pjsip_timestamp_hdr_create pjsip_generic_string_hdr_create\n\n/** User-Agent header. */\ntypedef pjsip_generic_string_hdr pjsip_user_agent_hdr;\n\n/** Create User-Agent header. */\n#define pjsip_user_agent_hdr_create pjsip_generic_string_hdr_create\n\n\n/**\n * @}\n */\n\n/**\n * @}  PJSIP_MSG\n */\n\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_SIP_MSG_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_multipart.h",
    "content": "/* $Id: sip_multipart.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_MULTIPART_H__\n#define __PJSIP_SIP_MULTIPART_H__\n\n/**\n * @file pjsip/sip_multipart.h\n * @brief Multipart support.\n */\n\n#include <pjsip/sip_msg.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_MULTIPART Multipart message bodies.\n * @ingroup PJSIP_MSG\n * @brief Support for multipart message bodies.\n * @{\n */\n\n/**\n * This structure describes the individual body part inside a multipart\n * message body. It mainly contains the message body itself and optional\n * headers.\n */\ntypedef struct pjsip_multipart_part\n{\n    /**\n     * Standard list element.\n     */\n    PJ_DECL_LIST_MEMBER(struct pjsip_multipart_part);\n\n    /**\n     * Optional message headers.\n     */\n    pjsip_hdr\t\t    hdr;\n\n    /**\n     * Pointer to the message body.\n     */\n    pjsip_msg_body\t   *body;\n\n} pjsip_multipart_part;\n\n/**\n * Create an empty multipart body.\n *\n * @param pool\t\tMemory pool to allocate memory from.\n * @param ctype\t\tOptional MIME media type of the multipart\n * \t\t\tbodies. If not specified, \"multipart/mixed\"\n * \t\t\twill be used.\n * @param boundary\tOptional string to be set as part boundary.\n * \t\t\tThe boundary string excludes the leading\n * \t\t\thyphens. If this parameter is NULL or empty,\n * \t\t\ta random boundary will be generated.\n *\n * @return\t\tMultipart body instance with no part.\n */\nPJ_DECL(pjsip_msg_body*) pjsip_multipart_create(pj_pool_t *pool,\n\t\t\t\t\t\tconst pjsip_media_type *ctype,\n\t\t\t\t\t\tconst pj_str_t *boundary);\n\n/**\n * Create an empty multipart part.\n *\n * @param pool\t\tThe memory pool.\n *\n * @return\t\tThe multipart part.\n */\nPJ_DECL(pjsip_multipart_part*) pjsip_multipart_create_part(pj_pool_t *pool);\n\n\n/**\n * Perform a deep clone to a multipart part.\n *\n * @param pool\t\tThe memory pool.\n * @param part\t\tThe part to be duplicated.\n *\n * @return\t\tCopy of the multipart part.\n */\nPJ_DECL(pjsip_multipart_part*)\npjsip_multipart_clone_part(pj_pool_t *pool,\n\t\t\t   const pjsip_multipart_part *part);\n\n/**\n * Add a part into multipart bodies.\n *\n * @param pool\t\tThe memory pool.\n * @param mp\t\tThe multipart bodies.\n * @param part\t\tThe part to be added into the bodies.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_multipart_add_part(pj_pool_t *pool,\n\t\t\t\t\t      pjsip_msg_body *mp,\n\t\t\t\t\t      pjsip_multipart_part *part);\n\n/**\n * Get the first part of multipart bodies.\n *\n * @param mp\t\tThe multipart bodies.\n *\n * @return\t\tThe first part, or NULL if the multipart\n * \t\t\tbodies currently doesn't hold any elements.\n */\nPJ_DECL(pjsip_multipart_part*)\npjsip_multipart_get_first_part(const pjsip_msg_body *mp);\n\n/**\n * Get the next part after the specified part.\n *\n * @param mp\t\tThe multipart bodies.\n * @param part\t\tThe part.\n *\n * @return\t\tThe next part, or NULL if there is no other part after\n * \t\t\tthe part.\n */\nPJ_DECL(pjsip_multipart_part*)\npjsip_multipart_get_next_part(const pjsip_msg_body *mp,\n\t\t\t      pjsip_multipart_part *part);\n\n/**\n * Find a body inside multipart bodies which has the specified content type.\n *\n * @param mp\t\tThe multipart body.\n * @param content_type\tContent type to find.\n * @param start\t\tIf specified, the search will begin at\n * \t\t\tstart->next. Otherwise it will begin at\n * \t\t\tthe first part in the multipart bodies.\n *\n * @return\t\tThe first part with the specified content type\n * \t\t\tif found, or NULL.\n */\nPJ_DECL(pjsip_multipart_part*)\npjsip_multipart_find_part( const pjsip_msg_body *mp,\n\t\t\t   const pjsip_media_type *content_type,\n\t\t\t   const pjsip_multipart_part *start);\n\n/**\n * Parse multipart message.\n *\n * @param pool\t\tMemory pool.\n * @param buf\t\tInput buffer.\n * @param len\t\tThe buffer length.\n * @param ctype\t\tContent type of the multipart body.\n * @param options\tParsing options, must be zero for now.\n *\n * @return\t\tMultipart message body.\n */\nPJ_DECL(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,\n\t\t\t\t\t       char *buf, pj_size_t len,\n\t\t\t\t\t       const pjsip_media_type *ctype,\n\t\t\t\t\t       unsigned options);\n\n/**\n * @}  PJSIP_MULTIPART\n */\n\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_SIP_MULTIPART_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_parser.h",
    "content": "/* $Id: sip_parser.h 4445 2013-03-20 11:29:08Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_PARSER_H__\n#define __PJSIP_SIP_PARSER_H__\n\n/**\n * @file sip_parser.h\n * @brief SIP Message Parser\n */\n\n#include <pjsip/sip_msg.h>\n#include <pjlib-util/scanner.h>\n#include <pj/list.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_PARSER Parser\n * @ingroup PJSIP_MSG\n * @brief Message and message elements parsing.\n * @{\n */\n\n/**\n * URI Parsing options.\n */\nenum\n{\n    /** If this option is specified, function #pjsip_parse_uri will return\n     *  the URI object as pjsip_name_addr instead of the corresponding\n     *  URI object.\n     */\n    PJSIP_PARSE_URI_AS_NAMEADDR = 1,\n\n    /** If this option is specified, function #pjsip_parse_uri and other\n     *  internal functions that this function calls will parse URI according\n     *  to convention for parsing From/To/Contact header. For example, when \n     *  the URI is not enclosed in brackets (\"<\" and \">\"), all parameters \n     *  are treated as header parameters (not URI parameters).\n     */\n    PJSIP_PARSE_URI_IN_FROM_TO_HDR = 2\n};\n\n/**\n * Parser syntax error exception value.\n */\nextern int PJSIP_SYN_ERR_EXCEPTION;\n\n/**\n * This structure is used to get error reporting from parser.\n */\ntypedef struct pjsip_parser_err_report\n{\n    /** Standard header fields. */\n    PJ_DECL_LIST_MEMBER(struct pjsip_parser_err_report);\n    int\t\texcept_code;\t/**< Error exception (e.g. PJSIP_SYN_ERR_EXCEPTION) */\n    int\t\tline;\t\t/**< Line number. */\n    int\t\tcol;\t\t/**< Column number. */\n    pj_str_t\thname;\t\t/**< Header name, if any. */\n} pjsip_parser_err_report;\n\n\n/**\n * Parsing context, the default argument for parsing functions.\n */\ntypedef struct pjsip_parse_ctx\n{\n    pj_scanner      *scanner;   /**< The scanner.       */\n    pj_pool_t       *pool;      /**< The pool.          */\n    pjsip_rx_data   *rdata;     /**< Optional rdata.    */\n} pjsip_parse_ctx;\n\n\n/**\n * Type of function to parse header. The parsing function must follow these\n * specification:\n *   - It must not modify the input text.\n *   - The hname and HCOLON has been parsed prior to invoking the handler.\n *   - It returns the header instance on success.\n *   - For error reporting, it must throw PJSIP_SYN_ERR_EXCEPTION exception \n *     instead of just returning NULL. \n *     When exception is thrown, the return value is ignored.\n *   - It must read the header separator after finished reading the header\n *     body. The separator types are described below, and if they don't exist,\n *     exception must be thrown. Header separator can be a:\n *\t- newline, such as when the header is part of a SIP message.\n *\t- ampersand, such as when the header is part of an URI.\n *\t- for the last header, these separator is optional since parsing\n *        can be terminated when seeing EOF.\n */\ntypedef pjsip_hdr* (pjsip_parse_hdr_func)(pjsip_parse_ctx *context);\n\n/**\n * Type of function to parse URI scheme.\n * Most of the specification of header parser handler (pjsip_parse_hdr_func)\n * also applies here (except the separator part).\n */\ntypedef void* (pjsip_parse_uri_func)(pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t\t     pj_bool_t parse_params);\n\n/**\n * Register header parser handler. The parser handler MUST follow the \n * specification of header parser handler function. New registration \n * overwrites previous registration with the same name.\n *\n * @param hname\t\tThe header name.\n * @param hshortname\tThe short header name or NULL.\n * @param fptr\t\tThe pointer to function to parser the header.\n *\n * @return\t\tPJ_SUCCESS if success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_register_hdr_parser( const char *hname,\n\t\t\t\t\t\tconst char *hshortname,\n\t\t\t\t\t\tpjsip_parse_hdr_func *fptr);\n\n/**\n * Unregister previously registered header parser handler.\n * All the arguments MUST exactly equal to the value specified upon \n * registration of the handler.\n *\n * @param hname\t\tThe header name registered.\n * @param hshortname\tThe short header name registered, or NULL.\n * @param fptr\t\tPreviously registered function to parse the header.\n *\n * @return\t\tzero if unregistration was successfull.\n */\nPJ_DECL(pj_status_t) pjsip_unregister_hdr_parser( const char *hname,\n\t\t\t\t\t\t  const char *hshortname,\n\t\t\t\t\t\t  pjsip_parse_hdr_func *fptr);\n\n/**\n * Register URI scheme parser handler.\n *\n * @param scheme\tThe URI scheme registered.\n * @param func\t\tThe URI parser function.\n *\n * @return\t\tzero on success.\n */\nPJ_DECL(pj_status_t) pjsip_register_uri_parser( char *scheme,\n\t\t\t\t\t        pjsip_parse_uri_func *func);\n\n/**\n * Unregister URI scheme parser handler.\n * All the arguments MUST exactly equal to the value specified upon \n * registration of the handler.\n *\n * @param scheme\tThe URI scheme as registered previously.\n * @param func\t\tThe function handler as registered previously.\n *\n * @return\t\tzero if the registration was successfull.\n */\nPJ_DECL(pj_status_t) pjsip_unregister_uri_parser( const char *scheme,\n\t\t\t\t\t\t  pjsip_parse_uri_func *func);\n\n/**\n * Parse an URI in the input and return the correct instance of URI.\n *\n * @param pool\t\tThe pool to get memory allocations.\n * @param buf\t\tThe input buffer, which MUST be NULL terminated.\n * @param size\t\tThe length of the string (not counting NULL terminator).\n * @param options\tIf no options are given (value is zero), the object \n *\t\t\treturned is dependent on the syntax of the URI, \n *\t\t\teg. basic SIP URL, TEL URL, or name address. \n *\t\t\tIf option PJSIP_PARSE_URI_AS_NAMEADDR is given,\n *\t\t\tthen the returned object is always name address object,\n *\t\t\twith the relevant URI object contained in the name \n *\t\t\taddress object.\n * @return\t\tThe URI or NULL when failed. No exception is thrown by \n *\t\t\tthis function (or any public parser functions).\n */\nPJ_DECL(pjsip_uri*) pjsip_parse_uri( pj_pool_t *pool, \n\t\t\t\t     char *buf, pj_size_t size,\n\t\t\t\t     unsigned options);\n\n/**\n * Parse SIP status line.\n *\n * @param buf\t\tText buffer to parse, which MUST be NULL terminated.\n * @param size\t\tThe size of the buffer, excluding the NULL character.\n * @param status_line\tStructure to receive the parsed elements.\n *\n * @return\t\tPJ_SUCCESS if a status line is parsed successfully.\n */\nPJ_DECL(pj_status_t) pjsip_parse_status_line(char *buf, pj_size_t size,\n\t\t\t\t\t     pjsip_status_line *status_line);\n\n\n/**\n * Parse a packet buffer and build a full SIP message from the packet. This\n * function parses all parts of the message, including request/status line,\n * all headers, and the message body. The message body however is only \n * treated as a text block, ie. the function will not try to parse the content\n * of the body.\n *\n * @param pool\t\tThe pool to allocate memory.\n * @param buf\t\tThe input buffer, which MUST be NULL terminated.\n * @param size\t\tThe length of the string (not counting NULL terminator).\n * @param err_list\tIf this parameter is not NULL, then the parser will\n *\t\t\tput error messages during parsing in this list.\n *\n * @return\t\tThe message or NULL when failed. No exception is thrown\n *\t\t\tby this function (or any public parser functions).\n */\nPJ_DECL(pjsip_msg *) pjsip_parse_msg( pj_pool_t *pool, \n\t\t\t\t      char *buf, pj_size_t size,\n\t\t\t\t      pjsip_parser_err_report *err_list);\n\n\n/**\n * Parse a packet buffer and build a rdata. The resulting message will be\n * stored in \\c msg field in the \\c rdata. This behaves pretty much like\n * #pjsip_parse_msg(), except that it will also initialize the header fields\n * in the \\c rdata.\n *\n * This function is normally called by the transport layer.\n *\n * @param buf\t\tThe input buffer, which MUST be NULL terminated.\n * @param size\t\tThe length of the string (not counting NULL terminator).\n * @param rdata         The receive data buffer to store the message and\n *                      its elements.\n *\n * @return              The message inside the rdata if successfull, or NULL.\n */\nPJ_DECL(pjsip_msg *) pjsip_parse_rdata( char *buf, pj_size_t size,\n                                        pjsip_rx_data *rdata );\n\n/**\n * Check incoming packet to see if a (probably) valid SIP message has been \n * received.\n *\n * @param buf\t\tThe input buffer, which must be NULL terminated.\n * @param size\t\tThe buffer size.\n * @param is_datagram\tPut non-zero if transport is datagram oriented.\n * @param msg_size\t[out] If message is valid, this parameter will contain\n *\t\t\tthe size of the SIP message (including body, if any).\n *\n * @return\t\tPJ_SUCCESS if a message is found, or an error code.\n */\nPJ_DECL(pj_status_t) pjsip_find_msg(const char *buf, \n                                    pj_size_t size, \n\t\t\t\t    pj_bool_t is_datagram, \n                                    pj_size_t *msg_size);\n\n/**\n * Parse the content of a header and return the header instance.\n * This function parses the content of a header (ie. part after colon) according\n * to the expected name, and will return the correct instance of header.\n *\n * @param pool\t\tPool to allocate memory for the header.\n * @param hname\t\tHeader name which is used to find the correct function\n *\t\t\tto parse the header.\n * @param line\t\tHeader content, which must be NULL terminated.\n * @param size\t\tThe length of the string (not counting NULL terminator,\n *\t\t\tif any).\n * @param parsed_len\tIf the value is not NULL, then upon return the function\n *\t\t\twill fill the pointer with the length of the string\n *\t\t\tthat has been parsed. This is usefull for two purposes,\n *\t\t\tone is when the string may contain more than one header\n *\t\t\tlines, and two when an error happen the value can\n *\t\t\tpinpoint the location of the error in the buffer.\n *\n * @return\t\tThe instance of the header if parsing was successful,\n *\t\t\tor otherwise a NULL pointer will be returned.\n */\nPJ_DECL(void*) pjsip_parse_hdr( pj_pool_t *pool, const pj_str_t *hname,\n\t\t\t\tchar *line, pj_size_t size,\n\t\t\t\tint *parsed_len);\n\n/**\n * Parse header line(s). Multiple headers can be parsed by this function.\n * When there are multiple headers, the headers MUST be separated by either\n * a newline (as in SIP message) or ampersand mark (as in URI). This separator\n * is optional for the last header.\n *\n * @param pool\t\tThe pool.\n * @param input\t\tThe input text to parse, which must be NULL terminated.\n * @param size\t\tThe text length.\n * @param hlist\t\tThe header list to store the parsed headers.\n *\t\t\tThis list must have been initialized before calling \n *\t\t\tthis function.\n * @param options\tSpecify 1 here to make parsing stop when error is\n * \t\t\tencountered when parsing the header. Otherwise the\n * \t\t\terror is silently ignored and parsing resumes to the\n * \t\t\tnext line.\n * @return\t\tzero if successfull, or -1 if error is encountered. \n *\t\t\tUpon error, the \\a hlist argument MAY contain \n *\t\t\tsuccessfully parsed headers.\n */\nPJ_DECL(pj_status_t) pjsip_parse_headers( pj_pool_t *pool, char *input,\n\t\t\t\t          pj_size_t size, pjsip_hdr *hlist,\n\t\t\t\t          unsigned options);\n\n\n/**\n * @}\n */\n\n\n#ifdef _MSC_VER\n#   pragma warning(push)\n#   pragma warning(disable:4510) // default constructor could not be generated\n#   pragma warning(disable:4512) // assignment operator could not be generated\n#   pragma warning(disable:4610) // user defined constructor required\n#endif\n\n/**\n * Parser constants. @see pjsip_parser_const()\n */\ntypedef struct pjsip_parser_const_t\n{\n    const pj_str_t pjsip_USER_STR;\t/**< \"user\" string constant.    */\n    const pj_str_t pjsip_METHOD_STR;\t/**< \"method\" string constant   */\n    const pj_str_t pjsip_TRANSPORT_STR;\t/**< \"transport\" string const.  */\n    const pj_str_t pjsip_MADDR_STR;\t/**< \"maddr\" string const.\t*/\n    const pj_str_t pjsip_LR_STR;\t/**< \"lr\" string const.\t\t*/\n    const pj_str_t pjsip_SIP_STR;\t/**< \"sip\" string constant.\t*/\n    const pj_str_t pjsip_SIPS_STR;\t/**< \"sips\" string constant.    */\n    const pj_str_t pjsip_TEL_STR;\t/**< \"tel\" string constant.\t*/\n    const pj_str_t pjsip_BRANCH_STR;\t/**< \"branch\" string constant.  */\n    const pj_str_t pjsip_TTL_STR;\t/**< \"ttl\" string constant.\t*/\n    const pj_str_t pjsip_RECEIVED_STR;\t/**< \"received\" string const.   */\n    const pj_str_t pjsip_Q_STR;\t\t/**< \"q\" string constant.\t*/\n    const pj_str_t pjsip_EXPIRES_STR;\t/**< \"expires\" string constant. */\n    const pj_str_t pjsip_TAG_STR;\t/**< \"tag\" string constant.\t*/\n    const pj_str_t pjsip_RPORT_STR;\t/**< \"rport\" string const.\t*/\n\n    pj_cis_t pjsip_HOST_SPEC;\t\t/**< For scanning host part.\t*/\n    pj_cis_t pjsip_DIGIT_SPEC;\t\t/**< Decimal digits\t\t*/\n    pj_cis_t pjsip_ALPHA_SPEC;\t\t/**< Alpha (A-Z, a-z)\t\t*/\n    pj_cis_t pjsip_ALNUM_SPEC;\t\t/**< Decimal + Alpha.\t\t*/\n    pj_cis_t pjsip_TOKEN_SPEC;\t\t/**< Token.\t\t\t*/\n    pj_cis_t pjsip_TOKEN_SPEC_ESC;\t/**< Token without '%' character */\n    pj_cis_t pjsip_VIA_PARAM_SPEC;\t/**< Via param is token + \":\" for\n\t\t\t\t\t     IPv6.\t\t\t*/\n    pj_cis_t pjsip_VIA_PARAM_SPEC_ESC;\t/**< .. as above without '%'\t*/\n    pj_cis_t pjsip_HEX_SPEC;  \t\t/**< Hexadecimal digits.\t*/\n    pj_cis_t pjsip_PARAM_CHAR_SPEC;\t/**< For scanning pname (or pvalue\n\t\t\t\t\t     when it's  not quoted.) in URI */\n    pj_cis_t pjsip_PARAM_CHAR_SPEC_ESC;\t/**< Variant without the escape ('%')\n\t\t\t\t\t     char\t\t\t*/\n    pj_cis_t pjsip_HDR_CHAR_SPEC;\t/**< Chars in hname/havalue in URL. */\n    pj_cis_t pjsip_HDR_CHAR_SPEC_ESC;\t/**< Variant without the escape ('%')\n\t\t\t\t\t     char\t\t\t*/\n    pj_cis_t pjsip_PROBE_USER_HOST_SPEC;/**< Hostname characters.\t*/\n    pj_cis_t pjsip_PASSWD_SPEC;\t\t/**< Password.\t\t\t*/\n    pj_cis_t pjsip_PASSWD_SPEC_ESC;\t/**< Variant without the escape ('%')\n\t\t\t\t\t     char\t\t\t*/\n    pj_cis_t pjsip_USER_SPEC;\t\t/**< User */\n    pj_cis_t pjsip_USER_SPEC_ESC;\t/**< Variant without the escape ('%')\n\t\t\t\t\t     char\t\t\t*/\n    pj_cis_t pjsip_USER_SPEC_LENIENT;\t/**< User, with additional '#' char */\n    pj_cis_t pjsip_USER_SPEC_LENIENT_ESC;/**< pjsip_USER_SPEC_ESC with '#' */\n    pj_cis_t pjsip_NOT_NEWLINE;\t\t/**< For eating up header, basically\n\t\t\t\t\t     any chars except newlines or \n\t\t\t\t\t     zero.\t\t\t*/\n    pj_cis_t pjsip_NOT_COMMA_OR_NEWLINE;/**< Array elements.\t\t*/\n    pj_cis_t pjsip_DISPLAY_SPEC;\t/**< Used when searching for display\n\t\t\t\t\t     name.\t\t\t*/\n    pj_cis_t pjsip_OTHER_URI_CONTENT;\t/**< Generic URI content.\t*/\n\n} pjsip_parser_const_t;\n\n#ifdef _MSC_VER\n#   pragma warning(pop)\n#endif\n\n\n/**\n * Get parser constants.\n */\nPJ_DECL(const pjsip_parser_const_t*) pjsip_parser_const(void);\n\n\n/*\n * Parser utilities.\n */\nenum\n{\n    PJSIP_PARSE_REMOVE_QUOTE = 1\n};\n\n/* Parse parameter in header (matching the character as token) */\nPJ_DECL(void) pjsip_parse_param_imp(pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t     \t    pj_str_t *pname, pj_str_t *pvalue,\n\t\t\t     \t    unsigned opt);\n/* Parse parameter in URL (matching the character as paramchar) */\nPJ_DECL(void) pjsip_parse_uri_param_imp(pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t\t \tpj_str_t *pname, pj_str_t *pvalue,\n\t\t\t\t \tunsigned opt);\nPJ_DECL(void) pjsip_concat_param_imp(pj_str_t *param, pj_pool_t *pool, \n\t\t\t     \t     const pj_str_t *pname, \n\t\t\t\t     const pj_str_t *pvalue, \n\t\t\t     \t     int sepchar);\nPJ_DECL(void) pjsip_parse_end_hdr_imp ( pj_scanner *scanner );\n\n/* Parse generic array header */\nPJ_DECL(void) pjsip_parse_generic_array_hdr_imp(pjsip_generic_array_hdr *hdr,\n\t\t\t\t\t\tpj_scanner *scanner);\n\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_SIP_PARSER_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_private.h",
    "content": "/* $Id: sip_private.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_PRIVATE_H__\n#define __PJSIP_SIP_PRIVATE_H__\n\n/**\n * @file sip_private.h\n * @brief Private structures and functions for PJSIP Library.\n */ \n\n#include <pjsip/sip_types.h>\n\n\n#endif /* __PJSIP_PRIVATE_I_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_resolve.h",
    "content": "/* $Id: sip_resolve.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_RESOLVE_H__\n#define __PJSIP_SIP_RESOLVE_H__\n\n/**\n * @file sip_resolve.h\n * @brief \n * This module contains the mechanism to resolve server address as specified by\n * RFC 3263 - Locating SIP Servers\n */\n\n#include <pjsip/sip_types.h>\n#include <pjlib-util/resolver.h>\n#include <pj/sock.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_RESOLVE SIP SRV Server Resolution (RFC 3263 - Locating SIP Servers)\n * @ingroup PJSIP_TRANSPORT\n * @brief Framework to resolve SIP servers based on RFC 3263.\n * @{\n * \\section PJSIP_RESOLVE_FEATURES Features\n *\n * This is the SIP server resolution framework, which is modelled after \n * RFC 3263 - Locating SIP Servers document. The SIP server resolution\n * framework is asynchronous; callback will be called once the server \n * address has been resolved (successfully or with errors).\n *\n * \\subsection PJSIP_RESOLVE_CONFORMANT Conformance to RFC 3263\n *\n * The SIP server resolution framework is modelled after RFC 3263 (Locating \n * SIP Servers) document, and it provides a single function (#pjsip_resolve())\n * to resolve a domain into actual IP addresses of the servers, by querying \n * DNS SRV record and DNS A record where necessary.\n *\n * The #pjsip_resolve() function performs the server resolution according\n * to RFC 3263 with some additional fallback mechanisms, as follows:\n *  - if the target name is an IP address, the callback will be called\n *    immediately with the IP address. If port number was specified, this\n *    port number will be used, otherwise the default port number for the\n *    transport will be used (5060 for TCP/UDP, 5061 for TLS) if the transport\n *    is specified. If the transport is not specified, UDP with port number\n *    5060 will be used.\n *  - if target name is not an IP address but it contains port number,\n *    then the target name is resolved with DNS A (or AAAA, when IPv6 is\n *    supported in the future) query, and the port is taken from the\n *    port number argument. The callback will be called once the DNS A\n *    resolution completes. If the DNS A resolution returns multiple IP\n *    addresses, these IP addresses will be returned to the caller.\n *  - if target name is not an IP address and port number is not specified,\n *    DNS SRV resolution will be performed for the specified name and\n *    transport type (or UDP when transport is not specified), \n *    then followed by DNS A (or AAAA, when IPv6 is supported)\n *    resolution for each target in the SRV record. If DNS SRV\n *    resolution returns error, DNS A (or AAAA) resolution will be\n *    performed for the original target (it is assumed that the target domain\n *    does not support SRV records). Upon successful completion, \n *    application callback will be called with each IP address of the\n *    target selected based on the load-balancing and fail-over criteria\n *    below.\n *\n * The above server resolution procedure differs from RFC 3263 in these\n * regards:\n *  - currently #pjsip_resolve() doesn't support DNS NAPTR record.\n *  - if transport is not specified, it is assumed to be UDP (the proper\n *    behavior is to query the NAPTR record, but we don't support this\n *    yet).\n *\n *\n * \\subsection PJSIP_SIP_RESOLVE_FAILOVER_LOADBALANCE Load-Balancing and Fail-Over\n *\n * When multiple targets are returned in the DNS SRV response, server entries\n * are selected based on the following rule (which is described in RFC 2782):\n *  - targets will be sorted based on the priority first.\n *  - for targets with the same priority, #pjsip_resolve() will select\n *    only one target according to its weight. To select this one target,\n *    the function associates running-sum for all targets, and generates \n *    a random number between zero and the total running-sum (inclusive).\n *    The target selected is the first target with running-sum greater than\n *    or equal to this random number.\n *\n * The above procedure will select one target for each priority, allowing\n * application to fail-over to the next target when the previous target fails.\n * These targets are returned in the #pjsip_server_addresses structure \n * argument of the callback. \n *\n * \\subsection PJSIP_SIP_RESOLVE_SIP_FEATURES SIP SRV Resolver Features\n *\n * Some features of the SIP resolver:\n *  - DNS SRV entries are returned on sorted order based on priority \n *    to allow failover to the next appropriate server.\n *  - The procedure in RFC 2782 is used to select server with the same\n *    priority to load-balance the servers load.\n *  - A single function (#pjsip_resolve()) performs all server resolution\n *    works, from resolving the SRV records to getting the actual IP addresses\n *    of the servers with DNS A (or AAAA) resolution.\n *  - When multiple DNS SRV records are returned, parallel DNS A (or AAAA)\n *    queries will be issued simultaneously.\n *  - The PJLIB-UTIL DNS resolver provides additional functionality such as\n *    response caching, query aggregation, parallel nameservers, fallback\n *    nameserver, etc., which will be described below.\n *  - Enable application to provide its own resolver implementation.  \n * \n *\n * \\subsection PJSIP_RESOLVE_DNS_FEATURES DNS Resolver Features\n *\n * The PJSIP server resolution framework uses PJLIB-UTIL DNS resolver engine\n * for performing the asynchronous DNS request. The PJLIB-UTIL DNS resolver\n * has some useful features, such as:\n *  - queries are asynchronous with configurable timeout,\n *  - query aggregation to combine multiple pending queries to the same\n *    DNS target into a single DNS request (to save message round-trip and\n *    processing),\n *  - response caching with TTL negotiated between the minimum TTL found in\n *    the response and the maximum TTL allowed in the configuration,\n *  - multiple nameservers, with active nameserver is selected from nameserver\n *    which provides the best response time,\n *  - fallback nameserver, with periodic detection of which name servers are\n *    active or down.\n *  - etc.\n *\n * Please consult PJLIB-UTIL DNS resolver documentation for more details.\n *\n *\n * \\section PJSIP_RESOLVE_USING Using the Resolver\n *\n * To maintain backward compatibility, the resolver MUST be enabled manually.\n * With the default settings, the resolver WILL NOT perform DNS SRV resolution,\n * as it will just resolve the name with standard pj_gethostbyname() function.\n *\n * Application can enable the SRV resolver by creating the PJLIB-UTIL DNS \n * resolver with #pjsip_endpt_create_resolver(), configure the\n * nameservers of the PJLIB-UTIL DNS resolver object by calling\n * pj_dns_resolver_set_ns() function, and pass the DNS resolver object to \n * #pjsip_resolver_set_resolver() function.\n *\n * Once the resolver is set, it will be used automatically by PJSIP everytime\n * PJSIP needs to send SIP request/response messages.\n *\n * \\section PJSIP_RESOLVE_EXT_RESOLVER External Resolver\n * \n * As an alternative to enabling PJLIB-UTIL DNS resolver, application can \n * provide its own resolver implementation by defining the callback in \n * pjsip_ext_resolver and pass the callback to \n * #pjsip_resolver_set_ext_resolver() function. Please note that if the \n * implementation needs feature from PJLIB-UTL DNS resolver, it has to create\n * its own PJLIB-UTL DNS resolver instance.\n *\n * \\section PJSIP_RESOLVE_REFERENCE Reference\n *\n * Reference:\n *  - RFC 2782: A DNS RR for specifying the location of services (DNS SRV)\n *  - RFC 3263: Locating SIP Servers\n */\n\n/**\n * The server addresses returned by the resolver.\n */\ntypedef struct pjsip_server_addresses\n{\n    /** Number of address records. */\n    unsigned\tcount;\n\n    /** Address records. */\n    struct\n    {\n\t/** Preferable transport to be used to contact this address. */\n\tpjsip_transport_type_e\ttype;\n\n\t/** Server priority (the lower the higher the priority). */\n\tunsigned\t\tpriority;\n\n\t/** Server weight (the higher the more load it can handle). */\n\tunsigned\t\tweight;\n\n\t/** The server's address. */\n\tpj_sockaddr\t\taddr;\n\n\t/** Address length. */\n\tint\t\t\taddr_len;\n\n    } entry[PJSIP_MAX_RESOLVED_ADDRESSES];\n\n} pjsip_server_addresses;\n\n\n/**\n * The type of callback function to be called when resolver finishes the job.\n *\n * @param status    The status of the operation, which is zero on success.\n * @param token\t    The token that was associated with the job when application\n *\t\t    call the resolve function.\n * @param addr\t    The addresses resolved by the operation.\n */\ntypedef void pjsip_resolver_callback(pj_status_t status,\n\t\t\t\t     void *token,\n\t\t\t\t     const struct pjsip_server_addresses *addr);\n\n/**\n * This structure describes application callback to receive various event from \n * the SIP resolver engine. Application can use this for its own resolver\n * implementation. \n */\ntypedef struct pjsip_ext_resolver\n{\n    /**\n     * Notify application when the resolution should begin.\n     *\n     * @param resolver      The resolver engine.\n     * @param pool          The pool to allocate resolver job.\n     * @param target        The target specification to be resolved.\n     * @param token         A user defined token to be passed back to callback \n     *                      function.\n     * @param cb            The callback function.\n     */\n    void (*resolve) (pjsip_resolver_t *resolver, pj_pool_t *pool,\n                     const pjsip_host_info *target, void *token,\n                     pjsip_resolver_callback *cb);\n\n} pjsip_ext_resolver;\n\n\n/**\n * Create SIP resolver engine. Note that this function is normally called\n * internally by pjsip_endpoint instance.\n *\n * @param pool\t    Pool to allocate memory from.\n * @param p_res\t    Pointer to receive SIP resolver instance.\n *\n * @return\t    PJ_SUCCESS when resolver can be successfully created.\n */\nPJ_DECL(pj_status_t) pjsip_resolver_create(pj_pool_t *pool,\n\t\t\t\t\t   pjsip_resolver_t **p_res);\n\n/**\n * Set the DNS resolver instance of the SIP resolver engine. Before the\n * DNS resolver is set, the SIP resolver will use standard pj_gethostbyname()\n * to resolve addresses.\n *\n * Note that application normally will use #pjsip_endpt_set_resolver() instead\n * since it does not normally have access to the SIP resolver instance.\n *\n * @param res\t    The SIP resolver engine.\n * @param dns_res   The DNS resolver instance to be used by the SIP resolver.\n *\t\t    This argument can be NULL to reset the internal DNS\n *\t\t    instance.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_resolver_set_resolver(pjsip_resolver_t *res,\n\t\t\t\t\t\t pj_dns_resolver *dns_res);\n\n\n/**\n * Set the DNS external resolver implementation to use in the SIP resolver \n * engine. Naturally when implementing its own resolver, application would not\n * need the internal resolver, hence this function will also destroy the \n * PJLIB-UTIL DNS resolver if any (e.g: set using \n * #pjsip_resolver_set_resolver()). Application that needs it, still be able \n * create its own instance.\n *\n * Note that application normally will use #pjsip_endpt_set_ext_resolver() \n * instead since it does not normally have access to the SIP resolver instance. \n *\n * @param res       The SIP resolver engine.\n * @param ext_res   The external resolver implementation callback. This argument\n *\t\t    can be NULL to reset the whole external implementation. \n *\t\t    However, it is prohibited to reset individual callback.\n * \n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_resolver_set_ext_resolver(\n\t\t\t\t\t\tpjsip_resolver_t *res,\n\t\t\t\t\t        pjsip_ext_resolver *ext_res);\n\n/**\n * Get the DNS resolver instance of the SIP resolver engine. \n *\n * Note that application normally will use #pjsip_endpt_get_resolver() instead\n * since it does not normally have access to the SIP resolver instance.\n *\n * @param res\t    The SIP resolver engine.\n *\n * @return\t    The DNS resolver instance (may be NULL)\n */\nPJ_DECL(pj_dns_resolver*) pjsip_resolver_get_resolver(pjsip_resolver_t *res);\n\n/**\n * Destroy resolver engine. Note that this will also destroy the internal\n * DNS resolver inside the engine. If application doesn't want the internal\n * DNS resolver to be destroyed, it should set the internal DNS resolver\n * to NULL before calling this function.\n *\n * Note that this function will normally called by the SIP endpoint instance\n * when the SIP endpoint instance is destroyed.\n *\n * @param resolver The resolver.\n */\nPJ_DECL(void) pjsip_resolver_destroy(pjsip_resolver_t *resolver);\n\n/**\n * Asynchronously resolve a SIP target host or domain according to rule \n * specified in RFC 3263 (Locating SIP Servers). When the resolving operation\n * has completed, the callback will be called.\n *\n * Note that application normally will use #pjsip_endpt_resolve() instead\n * since it does not normally have access to the SIP resolver instance.\n *\n * @param resolver\tThe resolver engine.\n * @param pool\t\tThe pool to allocate resolver job.\n * @param target\tThe target specification to be resolved.\n * @param token\t\tA user defined token to be passed back to callback function.\n * @param cb\t\tThe callback function.\n */\nPJ_DECL(void) pjsip_resolve( pjsip_resolver_t *resolver,\n\t\t\t     pj_pool_t *pool,\n\t\t\t     const pjsip_host_info *target,\n\t\t\t     void *token,\n\t\t\t     pjsip_resolver_callback *cb);\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_SIP_RESOLVE_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_tel_uri.h",
    "content": "/* $Id: sip_tel_uri.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_TEL_URI_H__\n#define __PJSIP_TEL_URI_H__\n\n/**\n * @file sip_tel_uri.h\n * @brief Tel: URI\n */\n\n#include <pjsip/sip_uri.h>\n\n/**\n * @addtogroup PJSIP_TEL_URI tel URI Scheme\n * @ingroup PJSIP_URI\n * @brief Support for \"tel:\" URI scheme.\n * @{\n */\n\n\nPJ_BEGIN_DECL\n\n/**\n * tel: URI.\n */\ntypedef struct pjsip_tel_uri\n{\n    pjsip_uri_vptr *vptr;\t/**< Pointer to virtual function table.\t*/\n    pj_str_t\t    number;\t/**< Global or local phone number\t*/\n    pj_str_t\t    context;\t/**< Phone context (for local number).\t*/\n    pj_str_t\t    ext_param;\t/**< Extension param.\t\t\t*/\n    pj_str_t\t    isub_param;\t/**< ISDN sub-address param.\t\t*/\n    pjsip_param\t    other_param;/**< Other parameter.\t\t\t*/\n} pjsip_tel_uri;\n\n\n/**\n * Create a new tel: URI.\n *\n * @param pool\t    The pool.\n *\n * @return\t    New instance of tel: URI.\n */\nPJ_DECL(pjsip_tel_uri*) pjsip_tel_uri_create(pj_pool_t *pool);\n\n/**\n * This function compares two numbers for equality, according to rules as\n * specified in RFC 3966.\n *\n * @param nb1\t    The first number.\n * @param nb2\t    The second number.\n *\n * @return\t    Zero if equal, -1 if nb1 is less than nb2, or +1 if\n *\t\t    nb1 is greater than nb2.\n */\nPJ_DECL(int) pjsip_tel_nb_cmp(const pj_str_t *nb1, const pj_str_t *nb2);\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJSIP_TEL_URI_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_transaction.h",
    "content": "/* $Id: sip_transaction.h 4420 2013-03-05 11:59:54Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_TRANSACTION_H__\n#define __PJSIP_SIP_TRANSACTION_H__\n\n/**\n * @file sip_transaction.h\n * @brief SIP Transaction\n */\n\n#include <pjsip/sip_msg.h>\n#include <pjsip/sip_util.h>\n#include <pjsip/sip_transport.h>\n#include <pj/timer.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_TRANSACT Transaction Layer\n * @brief Provides statefull message processing.\n *\n * This module provides stateful processing to incoming or outgoing SIP\n * messages. \n * Before performing any stateful operations, application must register the\n * transaction layer module by calling #pjsip_tsx_layer_init_module().\n *\n * Application should link with <b>pjsip-core</b> library to\n * use the transaction layer.\n */\n\n/**\n * @defgroup PJSIP_TRANSACT_TRANSACTION Transaction\n * @ingroup PJSIP_TRANSACT\n * @brief Transaction instance for all types of SIP transactions.\n * @{\n * The pjsip_transaction describes SIP transaction, and is used for\n * both INVITE and non-INVITE, UAC or UAS. Application must register the\n * transaction layer module with #pjsip_tsx_layer_init_module() before\n * performing any stateful operations.\n */\n\n/**\n * This enumeration represents transaction state.\n */\ntypedef enum pjsip_tsx_state_e\n{\n    PJSIP_TSX_STATE_NULL,\t/**< For UAC, before any message is sent.   */\n    PJSIP_TSX_STATE_CALLING,\t/**< For UAC, just after request is sent.   */\n    PJSIP_TSX_STATE_TRYING,\t/**< For UAS, just after request is received.*/\n    PJSIP_TSX_STATE_PROCEEDING,\t/**< For UAS/UAC, after provisional response.*/\n    PJSIP_TSX_STATE_COMPLETED,\t/**< For UAS/UAC, after final response.\t    */\n    PJSIP_TSX_STATE_CONFIRMED,\t/**< For UAS, after ACK is received.\t    */\n    PJSIP_TSX_STATE_TERMINATED,\t/**< For UAS/UAC, before it's destroyed.    */\n    PJSIP_TSX_STATE_DESTROYED,\t/**< For UAS/UAC, will be destroyed now.    */\n    PJSIP_TSX_STATE_MAX\t\t/**< Number of states.\t\t\t    */\n} pjsip_tsx_state_e;\n\n\n/**\n * This structure describes SIP transaction object. The transaction object\n * is used to handle both UAS and UAC transaction.\n */\nstruct pjsip_transaction\n{\n    /*\n     * Administrivia\n     */\n    pj_pool_t\t\t       *pool;           /**< Pool owned by the tsx. */\n    pjsip_module\t       *tsx_user;\t/**< Transaction user.\t    */\n    pjsip_endpoint\t       *endpt;          /**< Endpoint instance.     */\n    pj_bool_t\t\t\tterminating;\t/**< terminate() was called */\n    pj_grp_lock_t\t       *grp_lock;       /**< Transaction grp lock.  */\n    pj_mutex_t\t\t       *mutex_b;\t/**< Second mutex to avoid\n\t\t\t\t\t\t     deadlock. It is used to\n\t\t\t\t\t\t     protect timer.\t    */\n\n    /*\n     * Transaction identification.\n     */\n    char\t\t\tobj_name[PJ_MAX_OBJ_NAME];  /**< Log info.  */\n    pjsip_role_e\t\trole;           /**< Role (UAS or UAC)      */\n    pjsip_method\t\tmethod;         /**< The method.            */\n    pj_int32_t\t\t\tcseq;           /**< The CSeq               */\n    pj_str_t\t\t\ttransaction_key;/**< Hash table key.        */\n    pj_uint32_t\t\t\thashed_key;\t/**< Key's hashed value.    */\n    pj_str_t\t\t\tbranch;         /**< The branch Id.         */\n\n    /*\n     * State and status.\n     */\n    int\t\t\t\tstatus_code;    /**< Last status code seen. */\n    pj_str_t\t\t\tstatus_text;\t/**< Last reason phrase.    */\n    pjsip_tsx_state_e\t\tstate;          /**< State.                 */\n    int\t\t\t\thandle_200resp; /**< UAS 200/INVITE  retrsm.*/\n    int                         tracing;        /**< Tracing enabled?       */\n\n    /** Handler according to current state. */\n    pj_status_t (*state_handler)(struct pjsip_transaction *, pjsip_event *);\n\n    /*\n     * Transport.\n     */\n    pjsip_transport\t       *transport;      /**< Transport to use.      */\n    pj_bool_t\t\t\tis_reliable;\t/**< Transport is reliable. */\n    pj_sockaddr\t\t\taddr;\t\t/**< Destination address.   */\n    int\t\t\t\taddr_len;\t/**< Address length.\t    */\n    pjsip_response_addr\t\tres_addr;\t/**< Response address.\t    */\n    unsigned\t\t\ttransport_flag;\t/**< Miscelaneous flag.\t    */\n    pj_status_t\t\t\ttransport_err;\t/**< Internal error code.   */\n    pjsip_tpselector\t\ttp_sel;\t\t/**< Transport selector.    */\n    pjsip_tx_data\t       *pending_tx;\t/**< Tdata which caused\n\t\t\t\t\t\t     pending transport flag\n\t\t\t\t\t\t     to be set on tsx.\t    */\n    pjsip_tp_state_listener_key *tp_st_key;     /**< Transport state listener\n\t\t\t\t\t\t     key.\t\t    */\n\n    /*\n     * Messages and timer.\n     */\n    pjsip_tx_data\t       *last_tx;        /**< Msg kept for retrans.  */\n    int\t\t\t\tretransmit_count;/**< Retransmission count. */\n    pj_timer_entry\t\tretransmit_timer;/**< Retransmit timer.     */\n    pj_timer_entry\t\ttimeout_timer;  /**< Timeout timer.         */\n\n    /** Module specific data. */\n    void\t\t       *mod_data[PJSIP_MAX_MODULE];\n};\n\n\n/**\n * Create and register transaction layer module to the specified endpoint.\n *\n * @param endpt\t    The endpoint instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_tsx_layer_init_module(pjsip_endpoint *endpt);\n\n/**\n * Get the instance of the transaction layer module.\n *\n * @return\t    The transaction layer module.\n */\nPJ_DECL(pjsip_module*) pjsip_tsx_layer_instance(void);\n\n/**\n * Unregister and destroy transaction layer module.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_tsx_layer_destroy(void);\n\n/**\n * Retrieve the current number of transactions currently registered\n * in the hash table.\n *\n * @return\t    Number of transactions.\n */\nPJ_DECL(unsigned) pjsip_tsx_layer_get_tsx_count(void);\n\n/**\n * Find a transaction with the specified key. The transaction key normally\n * is created by calling #pjsip_tsx_create_key() from an incoming message.\n *\n * @param key\t    The key string to find the transaction.\n * @param lock\t    If non-zero, transaction will be locked before the\n *\t\t    function returns, to make sure that it's not deleted\n *\t\t    by other threads.\n *\n * @return\t    The matching transaction instance, or NULL if transaction\n *\t\t    can not be found.\n */\nPJ_DECL(pjsip_transaction*) pjsip_tsx_layer_find_tsx( const pj_str_t *key,\n\t\t\t\t\t\t      pj_bool_t lock );\n\n/**\n * Create, initialize, and register a new transaction as UAC from the \n * specified transmit data (\\c tdata). The transmit data must have a valid\n * \\c Request-Line and \\c CSeq header. \n *\n * If \\c Via header does not exist, it will be created along with a unique\n * \\c branch parameter. If it exists and contains branch parameter, then\n * the \\c branch parameter will be used as is as the transaction key. If\n * it exists but branch parameter doesn't exist, a unique branch parameter\n * will be created.\n *\n * @param tsx_user  Module to be registered as transaction user of the new\n *\t\t    transaction, which will receive notification from the\n *\t\t    transaction via on_tsx_state() callback.\n * @param tdata     The outgoing request message.\n * @param p_tsx\t    On return will contain the new transaction instance.\n *\n * @return          PJ_SUCCESS if successfull.\n */\nPJ_DECL(pj_status_t) pjsip_tsx_create_uac( pjsip_module *tsx_user,\n\t\t\t\t\t   pjsip_tx_data *tdata,\n\t\t\t\t\t   pjsip_transaction **p_tsx);\n\n/**\n * Variant of pjsip_tsx_create_uac() with additional parameter to specify\n * the group lock to use. Group lock can be used to synchronize locking\n * among several objects to prevent deadlock, and to synchronize the\n * lifetime of objects sharing the same group lock.\n *\n * See pjsip_tsx_create_uac() for general info about this function.\n *\n * @param tsx_user  Module to be registered as transaction user of the new\n *\t\t    transaction, which will receive notification from the\n *\t\t    transaction via on_tsx_state() callback.\n * @param tdata     The outgoing request message.\n * @param grp_lock  Optional group lock to use by this transaction. If\n * \t\t    the value is NULL, the transaction will create its\n * \t\t    own group lock.\n * @param p_tsx\t    On return will contain the new transaction instance.\n *\n * @return          PJ_SUCCESS if successfull.\n */\nPJ_DECL(pj_status_t) pjsip_tsx_create_uac2(pjsip_module *tsx_user,\n\t\t\t\t\t   pjsip_tx_data *tdata,\n\t\t\t\t\t   pj_grp_lock_t *grp_lock,\n\t\t\t\t\t   pjsip_transaction **p_tsx);\n\n/**\n * Create, initialize, and register a new transaction as UAS from the\n * specified incoming request in \\c rdata. After calling this function,\n * application MUST call #pjsip_tsx_recv_msg() so that transaction\n * moves from state NULL.\n *\n * @param tsx_user  Module to be registered as transaction user of the new\n *\t\t    transaction, which will receive notification from the\n *\t\t    transaction via on_tsx_state() callback.\n * @param rdata     The received incoming request.\n * @param p_tsx\t    On return will contain the new transaction instance.\n *\n * @return\t    PJ_SUCCESS if successfull.\n */\nPJ_DECL(pj_status_t) pjsip_tsx_create_uas( pjsip_module *tsx_user,\n\t\t\t\t\t   pjsip_rx_data *rdata,\n\t\t\t\t\t   pjsip_transaction **p_tsx );\n\n/**\n * Variant of pjsip_tsx_create_uas() with additional parameter to specify\n * the group lock to use. Group lock can be used to synchronize locking\n * among several objects to prevent deadlock, and to synchronize the\n * lifetime of objects sharing the same group lock.\n *\n * See pjsip_tsx_create_uas() for general info about this function.\n *\n * @param tsx_user  Module to be registered as transaction user of the new\n *\t\t    transaction, which will receive notification from the\n *\t\t    transaction via on_tsx_state() callback.\n * @param rdata     The received incoming request.\n * @param grp_lock  Optional group lock to use by this transaction. If\n * \t\t    the value is NULL, the transaction will create its\n * \t\t    own group lock.\n * @param p_tsx\t    On return will contain the new transaction instance.\n *\n * @return\t    PJ_SUCCESS if successfull.\n */\nPJ_DECL(pj_status_t) pjsip_tsx_create_uas2(pjsip_module *tsx_user,\n\t\t\t\t\t   pjsip_rx_data *rdata,\n\t\t\t\t\t   pj_grp_lock_t *grp_lock,\n\t\t\t\t\t   pjsip_transaction **p_tsx );\n\n/**\n * Lock/bind transaction to a specific transport/listener. This is optional,\n * as normally transport will be selected automatically based on the \n * destination of the message upon resolver completion.\n *\n * @param tsx\t    The transaction.\n * @param sel\t    Transport selector containing the specification of\n *\t\t    transport or listener to be used by this transaction\n *\t\t    to send requests.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tsx_set_transport(pjsip_transaction *tsx,\n\t\t\t\t\t     const pjsip_tpselector *sel);\n\n/**\n * Call this function to manually feed a message to the transaction.\n * For UAS transaction, application MUST call this function after\n * UAS transaction has been created.\n *\n * This function SHOULD only be called to pass initial request message\n * to UAS transaction. Before this function returns, on_tsx_state()\n * callback of the transaction user will be called. If response message\n * is passed to this function, then on_rx_response() will also be called\n * before on_tsx_state().\n *\n * @param tsx\t    The transaction.\n * @param rdata\t    The message.\n */\nPJ_DECL(void) pjsip_tsx_recv_msg( pjsip_transaction *tsx, \n\t\t\t\t  pjsip_rx_data *rdata);\n\n/**\n * Transmit message in tdata with this transaction. It is possible to\n * pass NULL in tdata for UAC transaction, which in this case the last \n * message transmitted, or the request message which was specified when\n * calling #pjsip_tsx_create_uac(), will be sent.\n *\n * This function decrements the reference counter of the transmit buffer\n * only when it returns PJ_SUCCESS;\n *\n * @param tsx       The transaction.\n * @param tdata     The outgoing message. If NULL is specified, then the\n *\t\t    last message transmitted (or the message specified \n *\t\t    in UAC initialization) will be sent.\n *\n * @return\t    PJ_SUCCESS if successfull.\n */\nPJ_DECL(pj_status_t) pjsip_tsx_send_msg( pjsip_transaction *tsx,\n\t\t\t\t\t pjsip_tx_data *tdata);\n\n\n/**\n * Manually retransmit the last message transmitted by this transaction,\n * without updating the transaction state. This function is useful when\n * TU wants to maintain the retransmision by itself (for example,\n * retransmitting reliable provisional response).\n *\n * @param tsx\t    The transaction.\n * @param tdata     The outgoing message. If NULL is specified, then the\n *\t\t    last message transmitted (or the message specified \n *\t\t    in UAC initialization) will be sent.\n *\n *\n * @return\t    PJ_SUCCESS if successful.\n */\nPJ_DECL(pj_status_t) pjsip_tsx_retransmit_no_state(pjsip_transaction *tsx,\n\t\t\t\t\t\t   pjsip_tx_data *tdata);\n\n\n/**\n * Create transaction key, which is used to match incoming requests \n * or response (retransmissions) against transactions.\n *\n * @param pool      The pool\n * @param key       Output key.\n * @param role      The role of the transaction.\n * @param method    The method to be put as a key. \n * @param rdata     The received data to calculate.\n *\n * @return          PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tsx_create_key( pj_pool_t *pool,\n\t\t\t\t           pj_str_t *key,\n\t\t\t\t           pjsip_role_e role,\n\t\t\t\t           const pjsip_method *method,\n\t\t\t\t           const pjsip_rx_data *rdata );\n\n/**\n * Force terminate transaction.\n *\n * @param tsx       The transaction.\n * @param code      The status code to report.\n */\nPJ_DECL(pj_status_t) pjsip_tsx_terminate( pjsip_transaction *tsx,\n\t\t\t\t\t  int code );\n\n\n/**\n * Cease retransmission on the UAC transaction. The UAC transaction is\n * still considered running, and it will complete when either final\n * response is received or the transaction times out.\n *\n * This operation normally is used for INVITE transaction only, when\n * the transaction is cancelled before any provisional response has been\n * received.\n *\n * @param tsx       The transaction.\n *\n * @return          PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tsx_stop_retransmit(pjsip_transaction *tsx);\n\n\n/**\n * Start a timer to terminate transaction after the specified time\n * has elapsed. This function is only valid for INVITE transaction,\n * and only before final response is received for the INVITE transaction.\n * It is normally called after the UAC has sent CANCEL for this\n * INVITE transaction. \n *\n * The purpose of this function is to terminate the transaction if UAS \n * does not send final response to this INVITE transaction even after \n * it sends 200/OK to CANCEL (for example when the UAS complies to RFC\n * 2543).\n *\n * Once this timer is set, the transaction will be terminated either when\n * a final response is received or the timer expires.\n *\n * @param tsx       The transaction.\n * @param millisec  Timeout value in milliseconds.\n *\n * @return          PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tsx_set_timeout(pjsip_transaction *tsx,\n\t\t\t\t\t   unsigned millisec);\n\n\n/**\n * Get the transaction instance in the incoming message. If the message\n * has a corresponding transaction, this function will return non NULL\n * value.\n *\n * @param rdata\t    The incoming message buffer.\n *\n * @return\t    The transaction instance associated with this message,\n *\t\t    or NULL if the message doesn't match any transactions.\n */\nPJ_DECL(pjsip_transaction*) pjsip_rdata_get_tsx( pjsip_rx_data *rdata );\n\n\n/**\n * @}\n */\n\n/*\n * Internal.\n */\n\n/*\n * Dump transaction layer.\n */\nPJ_DECL(void) pjsip_tsx_layer_dump(pj_bool_t detail);\n\n/**\n * Get the string name for the state.\n * @param state\tState\n */\nPJ_DECL(const char *) pjsip_tsx_state_str(pjsip_tsx_state_e state);\n\n/**\n * Get the role name.\n * @param role\tRole.\n */\nPJ_DECL(const char *) pjsip_role_name(pjsip_role_e role);\n\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_TRANSACT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_transport.h",
    "content": "/* $Id: sip_transport.h 4275 2012-10-04 06:11:58Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_TRANSPORT_H__\n#define __PJSIP_SIP_TRANSPORT_H__\n\n/**\n * @file sip_transport.h\n * @brief SIP Transport\n */\n\n#include <pjsip/sip_msg.h>\n#include <pjsip/sip_parser.h>\n#include <pjsip/sip_resolve.h>\n#include <pj/sock.h>\n#include <pj/list.h>\n#include <pj/ioqueue.h>\n#include <pj/timer.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_TRANSPORT Transport\n * @ingroup PJSIP_CORE\n * @brief This is the transport framework.\n *\n * The transport framework is fully extensible. Please see\n * <A HREF=\"/docs.htm\">PJSIP Developer's Guide</A> PDF\n * document for more information.\n *\n * Application MUST register at least one transport to PJSIP before any\n * messages can be sent or received. Please see @ref PJSIP_TRANSPORT_UDP\n * on how to create/register UDP transport to the transport framework.\n *\n * @{\n */\n\n/*****************************************************************************\n *\n * GENERAL TRANSPORT (NAMES, TYPES, ETC.)\n *\n *****************************************************************************/\n\n/*\n * Forward declaration for transport factory (since it is referenced by\n * the transport factory itself).\n */\ntypedef struct pjsip_tpfactory pjsip_tpfactory;\n\n\n/**\n * Flags for SIP transports.\n */\nenum pjsip_transport_flags_e\n{\n    PJSIP_TRANSPORT_RELIABLE\t    = 1,    /**< Transport is reliable.\t    */\n    PJSIP_TRANSPORT_SECURE\t    = 2,    /**< Transport is secure.\t    */\n    PJSIP_TRANSPORT_DATAGRAM\t    = 4     /**< Datagram based transport.  \n\t\t\t\t\t         (it's also assumed to be \n\t\t\t\t\t\t connectionless)\t    */\n};\n\n/**\n * Check if transport tp is reliable.\n */\n#define PJSIP_TRANSPORT_IS_RELIABLE(tp)\t    \\\n\t    ((tp)->flag & PJSIP_TRANSPORT_RELIABLE)\n\n/**\n * Check if transport tp is secure.\n */\n#define PJSIP_TRANSPORT_IS_SECURE(tp)\t    \\\n\t    ((tp)->flag & PJSIP_TRANSPORT_SECURE)\n\n/**\n * Register new transport type to PJSIP. The PJSIP transport framework\n * contains the info for some standard transports, as declared by\n * #pjsip_transport_type_e. Application may use non-standard transport\n * with PJSIP, but before it does so, it must register the information\n * about the new transport type to PJSIP by calling this function.\n *\n * @param tp_flag   The flags describing characteristics of this\n *\t\t    transport type.\n * @param tp_name   Transport type name.\n * @param def_port  Default port to be used for the transport.\n * @param p_tp_type On successful registration, it will be filled with\n *\t\t    the registered type. This argument is optional.\n *\n * @return\t    PJ_SUCCESS if registration is successful, or\n *\t\t    PJSIP_ETYPEEXISTS if the same transport type has\n *\t\t    already been registered.\n */\nPJ_DECL(pj_status_t) pjsip_transport_register_type(unsigned tp_flag,\n\t\t\t\t\t\t   const char *tp_name,\n\t\t\t\t\t\t   int def_port,\n\t\t\t\t\t\t   int *p_tp_type);\n\n\n/**\n * Get the transport type from the transport name.\n *\n * @param name\t    Transport name, such as \"TCP\", or \"UDP\".\n *\n * @return\t    The transport type, or PJSIP_TRANSPORT_UNSPECIFIED if \n *\t\t    the name is not recognized as the name of supported \n *\t\t    transport.\n */\nPJ_DECL(pjsip_transport_type_e) \npjsip_transport_get_type_from_name(const pj_str_t *name);\n\n/**\n * Get the transport type for the specified flags.\n *\n * @param flag\t    The transport flag.\n *\n * @return\t    Transport type.\n */\nPJ_DECL(pjsip_transport_type_e) \npjsip_transport_get_type_from_flag(unsigned flag);\n\n/**\n * Get the socket address family of a given transport type.\n *\n * @param type\t    Transport type.\n *\n * @return\t    Transport type.\n */\nPJ_DECL(int) pjsip_transport_type_get_af(pjsip_transport_type_e type);\n\n/**\n * Get transport flag from type.\n *\n * @param type\t    Transport type.\n *\n * @return\t    Transport flags.\n */\nPJ_DECL(unsigned)\npjsip_transport_get_flag_from_type( pjsip_transport_type_e type );\n\n/**\n * Get the default SIP port number for the specified type.\n *\n * @param type\t    Transport type.\n *\n * @return\t    The port number, which is the default SIP port number for\n *\t\t    the specified type.\n */\nPJ_DECL(int) \npjsip_transport_get_default_port_for_type(pjsip_transport_type_e type);\n\n/**\n * Get transport type name.\n *\n * @param t\t    Transport type.\n *\n * @return\t    Transport name.\n */\nPJ_DECL(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e t);\n\n/**\n * Get longer description for the specified transport type.\n *\n * @param t\t    Transport type.\n *\n * @return\t    Transport description.\n */\nPJ_DECL(const char*) pjsip_transport_get_type_desc(pjsip_transport_type_e t);\n\n\n\n/*****************************************************************************\n *\n * TRANSPORT SELECTOR.\n *\n *****************************************************************************/\n\n/**\n * This structure describes the type of data in pjsip_tpselector.\n */\ntypedef enum pjsip_tpselector_type\n{\n    /** Transport is not specified. */\n    PJSIP_TPSELECTOR_NONE,\n\n    /** Use the specific transport to send request. */\n    PJSIP_TPSELECTOR_TRANSPORT,\n\n    /** Use the specific listener to send request. */\n    PJSIP_TPSELECTOR_LISTENER,\n\n} pjsip_tpselector_type;\n\n\n/**\n * This structure describes the transport/listener preference to be used\n * when sending outgoing requests.\n *\n * Normally transport will be selected automatically according to rules about\n * sending requests. But some applications (such as proxies or B2BUAs) may \n * want to explicitly use specific transport to send requests, for example\n * when they want to make sure that outgoing request should go from a specific\n * network interface.\n *\n * The pjsip_tpselector structure is used for that purpose, i.e. to allow\n * application specificly request that a particular transport/listener\n * should be used to send request. This structure is used when calling\n * pjsip_tsx_set_transport() and pjsip_dlg_set_transport().\n */\ntypedef struct pjsip_tpselector\n{\n    /** The type of data in the union */\n    pjsip_tpselector_type   type;\n\n    /** Union representing the transport/listener criteria to be used. */\n    union {\n\tpjsip_transport\t*transport;\n\tpjsip_tpfactory\t*listener;\n\tvoid\t\t*ptr;\n    } u;\n\n} pjsip_tpselector;\n\n\n/**\n * Add transport/listener reference in the selector to prevent the specified\n * transport/listener from being destroyed while application still has\n * reference to it.\n *\n * @param sel\tThe transport selector.\n */\nPJ_DECL(void) pjsip_tpselector_add_ref(pjsip_tpselector *sel);\n\n\n/**\n * Decrement transport/listener reference in the selector.\n * @param sel\tThe transport selector\n */\nPJ_DECL(void) pjsip_tpselector_dec_ref(pjsip_tpselector *sel);\n\n\n/*****************************************************************************\n *\n * RECEIVE DATA BUFFER.\n *\n *****************************************************************************/\n\n/** \n * A customized ioqueue async operation key which is used by transport\n * to locate rdata when a pending read operation completes.\n */\ntypedef struct pjsip_rx_data_op_key\n{\n    pj_ioqueue_op_key_t\t\top_key;\t/**< ioqueue op_key.\t\t*/\n    pjsip_rx_data\t       *rdata;\t/**< rdata associated with this */\n} pjsip_rx_data_op_key;\n\n\n/**\n * Incoming message buffer.\n * This structure keep all the information regarding the received message. This\n * buffer lifetime is only very short, normally after the transaction has been\n * called, this buffer will be deleted/recycled. So care must be taken when\n * allocating storage from the pool of this buffer.\n */\nstruct pjsip_rx_data\n{\n\n    /**\n     * tp_info is part of rdata that remains static for the duration of the\n     * buffer. It is initialized when the buffer was created by transport.\n     */\n    struct \n    {\n\t/** Memory pool for this buffer. */\n\tpj_pool_t\t\t*pool;\n\n\t/** The transport object which received this packet. */\n\tpjsip_transport\t\t*transport;\n\n\t/** Other transport specific data to be attached to this buffer. */\n\tvoid\t\t\t*tp_data;\n\n\t/** Ioqueue key. */\n\tpjsip_rx_data_op_key\t op_key;\n\n    } tp_info;\n\n\n    /**\n     * pkt_info is initialized by transport when it receives an incoming\n     * packet.\n     */\n    struct\n    {\n\t/** Time when the message was received. */\n\tpj_time_val\t\t timestamp;\n\n\t/** Pointer to the original packet. */\n\tchar\t\t\t packet[PJSIP_MAX_PKT_LEN];\n\n\t/** Zero termination for the packet. */\n\tpj_uint32_t\t\t zero;\n\n\t/** The length of the packet received. */\n\tpj_ssize_t\t\t len;\n\n\t/** The source address from which the packet was received. */\n\tpj_sockaddr\t\t src_addr;\n\n\t/** The length of the source address. */\n\tint\t\t\t src_addr_len;\n\n\t/** The IP source address string (NULL terminated). */\n\tchar\t\t\t src_name[PJ_INET6_ADDRSTRLEN];\n\n\t/** The IP source port number. */\n\tint\t\t\t src_port;\n\n    } pkt_info;\n\n\n    /**\n     * msg_info is initialized by transport mgr (tpmgr) before this buffer\n     * is passed to endpoint.\n     */\n    struct\n    {\n\t/** Start of msg buffer. */\n\tchar\t\t\t*msg_buf;\n\n\t/** Length fo message. */\n\tint\t\t\t len;\n\n\t/** The parsed message, if any. */\n\tpjsip_msg\t\t*msg;\n\n\t/** Short description about the message. \n\t *  Application should use #pjsip_rx_data_get_info() instead.\n\t */\n\tchar\t\t\t*info;\n\n\t/** The Call-ID header as found in the message. */\n\tpjsip_cid_hdr\t\t*cid;\n\n\t/** The From header as found in the message. */\n\tpjsip_from_hdr\t\t*from;\n\n\t/** The To header as found in the message. */\n\tpjsip_to_hdr\t\t*to;\n\n\t/** The topmost Via header as found in the message. */\n\tpjsip_via_hdr\t\t*via;\n\n\t/** The CSeq header as found in the message. */\n\tpjsip_cseq_hdr\t\t*cseq;\n\n\t/** Max forwards header. */\n\tpjsip_max_fwd_hdr\t*max_fwd;\n\n\t/** The first route header. */\n\tpjsip_route_hdr\t\t*route;\n\n\t/** The first record-route header. */\n\tpjsip_rr_hdr\t\t*record_route;\n\n\t/** Content-type header. */\n\tpjsip_ctype_hdr\t\t*ctype;\n\n\t/** Content-length header. */\n\tpjsip_clen_hdr\t\t*clen;\n\n\t/** \"Require\" header containing aggregates of all Require\n\t *  headers found in the message, or NULL. \n\t */\n\tpjsip_require_hdr\t*require;\n\n\t/** \"Supported\" header containing aggregates of all Supported\n\t *  headers found in the message, or NULL. \n\t */\n\tpjsip_supported_hdr\t*supported;\n\n\t/** The list of error generated by the parser when parsing \n\t    this message. \n\t */\n\tpjsip_parser_err_report parse_err;\n\n    } msg_info;\n\n\n    /**\n     * endpt_info is initialized by endpoint after this buffer reaches\n     * endpoint.\n     */\n    struct\n    {\n\t/** \n\t * Data attached by modules to this message. \n\t */\n\tvoid\t*mod_data[PJSIP_MAX_MODULE];\n\n    } endpt_info;\n\n};\n\n/**\n * Get printable information about the message in the rdata.\n *\n * @param rdata\t    The receive data buffer.\n *\n * @return\t    Printable information.\n */\nPJ_DECL(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata);\n\n/**\n * Clone pjsip_rx_data. This will duplicate the contents of\n * pjsip_rx_data and add reference count to the transport.\n * Once application has finished using the cloned pjsip_rx_data,\n * it must release it by calling  #pjsip_rx_data_free_cloned().\n *\n * By default (if flags is set to zero), this function copies the\n * transport pointer in \\a tp_info, duplicates the \\a pkt_info,\n * perform deep clone of the \\a msg_info parts of the rdata, and\n * fills the \\a endpt_info (i.e. the \\a mod_data) with zeros.\n *\n * @param src\t    The source to be cloned.\n * @param flags\t    Optional flags. Must be zero for now.\n * @param p_rdata   Pointer to receive the cloned rdata.\n *\n * @return\t    PJ_SUCCESS on success or the appropriate error.\n */\nPJ_DECL(pj_status_t) pjsip_rx_data_clone(const pjsip_rx_data *src,\n                                         unsigned flags,\n                                         pjsip_rx_data **p_rdata);\n\n/**\n * Free cloned pjsip_rx_data. This function must be and must only\n * be called for a cloned pjsip_rx_data. Specifically, it must NOT\n * be called for the original pjsip_rx_data that is returned by\n * transports.\n *\n * This function will free the memory used by the pjsip_rx_data and\n * decrement the transport reference counter.\n *\n * @param rdata\t    The receive data buffer.\n *\n * @return\t    PJ_SUCCESS on success or the appropriate error.\n */\nPJ_DECL(pj_status_t) pjsip_rx_data_free_cloned(pjsip_rx_data *rdata);\n\n\n/*****************************************************************************\n *\n * TRANSMIT DATA BUFFER MANIPULATION.\n *\n *****************************************************************************/\n\n/** Customized ioqueue async operation key, used by transport to keep\n *  callback parameters.\n */\ntypedef struct pjsip_tx_data_op_key\n{\n    /** ioqueue pending operation key. */\n    pj_ioqueue_op_key_t\t    key;\n\n    /** Transmit data associated with this key. */\n    pjsip_tx_data\t   *tdata;\n\n    /** Arbitrary token (attached by transport) */\n    void\t\t   *token;\n\n    /** Callback to be called when pending transmit operation has\n        completed.\n     */\n    void\t\t  (*callback)(pjsip_transport*,void*,pj_ssize_t);\n} pjsip_tx_data_op_key;\n\n\n/**\n * Data structure for sending outgoing message. Application normally creates\n * this buffer by calling #pjsip_endpt_create_tdata.\n *\n * The lifetime of this buffer is controlled by the reference counter in this\n * structure, which is manipulated by calling #pjsip_tx_data_add_ref and\n * #pjsip_tx_data_dec_ref. When the reference counter has reached zero, then\n * this buffer will be destroyed.\n *\n * A transaction object normally will add reference counter to this buffer\n * when application calls #pjsip_tsx_send_msg, because it needs to keep the\n * message for retransmission. The transaction will release the reference\n * counter once its state has reached final state.\n */\nstruct pjsip_tx_data\n{\n    /** This is for transmission queue; it's managed by transports. */\n    PJ_DECL_LIST_MEMBER(struct pjsip_tx_data);\n\n    /** Memory pool for this buffer. */\n    pj_pool_t\t\t*pool;\n\n    /** A name to identify this buffer. */\n    char\t\t obj_name[PJ_MAX_OBJ_NAME];\n\n    /** Short information describing this buffer and the message in it. \n     *  Application should use #pjsip_tx_data_get_info() instead of\n     *  directly accessing this member.\n     */\n    char\t\t*info;\n\n    /** For response message, this contains the reference to timestamp when \n     *  the original request message was received. The value of this field\n     *  is set when application creates response message to a request by\n     *  calling #pjsip_endpt_create_response.\n     */\n    pj_time_val\t\t rx_timestamp;\n\n    /** The transport manager for this buffer. */\n    pjsip_tpmgr\t\t*mgr;\n\n    /** Ioqueue asynchronous operation key. */\n    pjsip_tx_data_op_key op_key;\n\n    /** Lock object. */\n    pj_lock_t\t\t*lock;\n\n    /** The message in this buffer. */\n    pjsip_msg \t\t*msg;\n\n    /** Strict route header saved by #pjsip_process_route_set(), to be\n     *  restored by #pjsip_restore_strict_route_set().\n     */\n    pjsip_route_hdr\t*saved_strict_route;\n\n    /** Buffer to the printed text representation of the message. When the\n     *  content of this buffer is set, then the transport will send the content\n     *  of this buffer instead of re-printing the message structure. If the\n     *  message structure has changed, then application must invalidate this\n     *  buffer by calling #pjsip_tx_data_invalidate_msg.\n     */\n    pjsip_buffer\t buf;\n\n    /** Reference counter. */\n    pj_atomic_t\t\t*ref_cnt;\n\n    /** Being processed by transport? */\n    int\t\t\t is_pending;\n\n    /** Transport manager internal. */\n    void\t\t*token;\n\n    /** Callback to be called when this tx_data has been transmitted.\t*/\n    void\t       (*cb)(void*, pjsip_tx_data*, pj_ssize_t);\n\n    /** Destination information, to be used to determine the network address\n     *  of the message. For a request, this information is  initialized when\n     *  the request is sent with #pjsip_endpt_send_request_stateless() and\n     *  network address is resolved. For CANCEL request, this information\n     *  will be copied from the original INVITE to make sure that the CANCEL\n     *  request goes to the same physical network address as the INVITE\n     *  request.\n     */\n    struct\n    {\n\t/** Server name. \n\t */\n\tpj_str_t\t\t name;\n\n\t/** Server addresses resolved. \n\t */\n\tpjsip_server_addresses   addr;\n\n\t/** Current server address being tried. \n\t */\n\tunsigned cur_addr;\n\n    } dest_info;\n\n    /** Transport information, only valid during on_tx_request() and \n     *  on_tx_response() callback.\n     */\n    struct\n    {\n\tpjsip_transport\t    *transport;\t    /**< Transport being used.\t*/\n\tpj_sockaddr\t     dst_addr;\t    /**< Destination address.\t*/\n\tint\t\t     dst_addr_len;  /**< Length of address.\t*/\n\tchar\t\t     dst_name[PJ_INET6_ADDRSTRLEN]; /**< Destination address.\t*/\n\tint\t\t     dst_port;\t    /**< Destination port.\t*/\n    } tp_info;\n\n    /** \n     * Transport selector, to specify which transport to be used. \n     * The value here must be set with pjsip_tx_data_set_transport(),\n     * to allow reference counter to be set properly.\n     */\n    pjsip_tpselector\t    tp_sel;\n\n    /**\n     * Special flag to indicate that this transmit data is a request that has\n     * been updated with proper authentication response and is ready to be\n     * sent for retry.\n     */\n    pj_bool_t\t\t    auth_retry;\n\n    /**\n     * Arbitrary data attached by PJSIP modules.\n     */\n    void\t\t    *mod_data[PJSIP_MAX_MODULE];\n\n    /**\n     * If via_addr is set, it will be used as the \"sent-by\" field of the\n     * Via header for outgoing requests as long as the request uses via_tp\n     * transport. Normally application should not use or access these fields.\n     */\n    pjsip_host_port          via_addr;      /**< Via address.\t        */\n    const void              *via_tp;        /**< Via transport.\t        */\n};\n\n\n/**\n * Create a new, blank transmit buffer. The reference count is initialized\n * to zero.\n *\n * @param mgr\t\tThe transport manager.\n * @param tdata\t\tPointer to receive transmit data.\n *\n * @return\t\tPJ_SUCCESS, or the appropriate error code.\n *\n * @see pjsip_endpt_create_tdata\n */\nPJ_DECL(pj_status_t) pjsip_tx_data_create( pjsip_tpmgr *mgr,\n\t\t\t\t\t   pjsip_tx_data **tdata );\n\n/**\n * Add reference counter to the transmit buffer. The reference counter controls\n * the life time of the buffer, ie. when the counter reaches zero, then it \n * will be destroyed.\n *\n * @param tdata\t    The transmit buffer.\n */\nPJ_DECL(void) pjsip_tx_data_add_ref( pjsip_tx_data *tdata );\n\n/**\n * Decrement reference counter of the transmit buffer.\n * When the transmit buffer is no longer used, it will be destroyed and\n * caller is informed with PJSIP_EBUFDESTROYED return status.\n *\n * @param tdata\t    The transmit buffer data.\n * @return\t    This function will always succeeded eventhough the return\n *\t\t    status is non-zero. A status PJSIP_EBUFDESTROYED will be\n *\t\t    returned to inform that buffer is destroyed.\n */\nPJ_DECL(pj_status_t) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata );\n\n/**\n * Print the SIP message to transmit data buffer's internal buffer. This\n * may allocate memory for the buffer, if the buffer has not been allocated\n * yet, and encode the SIP message to that buffer.\n *\n * @param tdata\t    The transmit buffer.\n *\n * @return\t    PJ_SUCCESS on success of the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tx_data_encode(pjsip_tx_data *tdata);\n\n/**\n * Check if transmit data buffer contains a valid message.\n *\n * @param tdata\t    The transmit buffer.\n * @return\t    Non-zero (PJ_TRUE) if buffer contains a valid message.\n */\nPJ_DECL(pj_bool_t) pjsip_tx_data_is_valid( pjsip_tx_data *tdata );\n\n/**\n * Invalidate the print buffer to force message to be re-printed. Call\n * when the message has changed after it has been printed to buffer. The\n * message is printed to buffer normally by transport when it is about to be \n * sent to the wire. Subsequent sending of the message will not cause\n * the message to be re-printed, unless application invalidates the buffer\n * by calling this function.\n *\n * @param tdata\t    The transmit buffer.\n */\nPJ_DECL(void) pjsip_tx_data_invalidate_msg( pjsip_tx_data *tdata );\n\n/**\n * Get short printable info about the transmit data. This will normally return\n * short information about the message.\n *\n * @param tdata\t    The transmit buffer.\n *\n * @return\t    Null terminated info string.\n */\nPJ_DECL(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata );\n\n/**\n * Set the explicit transport to be used when sending this transmit data.\n * Application should not need to call this function, but rather use\n * pjsip_tsx_set_transport() and pjsip_dlg_set_transport() instead (which\n * will call this function).\n *\n * @param tdata\t    The transmit buffer.\n * @param sel\t    Transport selector.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_tx_data_set_transport(pjsip_tx_data *tdata,\n\t\t\t\t\t\t const pjsip_tpselector *sel);\n\n\n/*****************************************************************************\n *\n * TRANSPORT\n *\n *****************************************************************************/\n/**\n * Type of callback to receive transport operation status.\n */\ntypedef void (*pjsip_transport_callback)(pjsip_transport *tp, void *token,\n                                         pj_ssize_t sent_bytes);\n\n/**\n * This structure describes transport key to be registered to hash table.\n */\ntypedef struct pjsip_transport_key\n{\n    /**\n     * Transport type.\n     */\n    long\t\t    type;\n\n    /**\n     * Destination address.\n     */\n    pj_sockaddr\t\t    rem_addr;\n\n} pjsip_transport_key;\n\n\n/**\n * Enumeration of transport direction types.\n */\ntypedef enum pjsip_transport_dir\n{\n    PJSIP_TP_DIR_NONE,\t\t    /**< Direction not set, normally used by\n\t\t\t\t         connectionless transports such as \n\t\t\t\t\t UDP transport.\t\t\t    */\n    PJSIP_TP_DIR_OUTGOING,\t    /**< Outgoing connection or client mode,\n\t\t\t\t         this is only for connection-oriented \n\t\t\t\t\t transports.\t\t\t    */\n    PJSIP_TP_DIR_INCOMING,\t    /**< Incoming connection or server mode,\n\t\t\t\t\t this is only for connection-oriented\n\t\t\t\t\t transports.\t\t\t    */\n} pjsip_transport_dir;\n\n\n/**\n * This structure represent the \"public\" interface of a SIP transport.\n * Applications normally extend this structure to include transport\n * specific members.\n */\nstruct pjsip_transport\n{\n    char\t\t    obj_name[PJ_MAX_OBJ_NAME];\t/**< Name. */\n\n    pj_pool_t\t\t   *pool;\t    /**< Pool used by transport.    */\n    pj_atomic_t\t\t   *ref_cnt;\t    /**< Reference counter.\t    */\n    pj_lock_t\t\t   *lock;\t    /**< Lock object.\t\t    */\n    pj_bool_t\t\t    tracing;\t    /**< Tracing enabled?\t    */\n    pj_bool_t\t\t    is_shutdown;    /**< Being shutdown?\t    */\n    pj_bool_t\t\t    is_destroying;  /**< Destroy in progress?\t    */\n\n    /** Key for indexing this transport in hash table. */\n    pjsip_transport_key\t    key;\n\n    char\t\t   *type_name;\t    /**< Type name.\t\t    */\n    unsigned\t\t    flag;\t    /**< #pjsip_transport_flags_e   */\n    char\t\t   *info;\t    /**< Transport info/description.*/\n\n    int\t\t\t    addr_len;\t    /**< Length of addresses.\t    */\n    pj_sockaddr\t\t    local_addr;\t    /**< Bound address.\t\t    */\n    pjsip_host_port\t    local_name;\t    /**< Published name (eg. STUN). */\n    pjsip_host_port\t    remote_name;    /**< Remote address name.\t    */\n    pjsip_transport_dir\t    dir;\t    /**< Connection direction.\t    */\n    \n    pjsip_endpoint\t   *endpt;\t    /**< Endpoint instance.\t    */\n    pjsip_tpmgr\t\t   *tpmgr;\t    /**< Transport manager.\t    */\n    pjsip_tpfactory\t   *factory;\t    /**< Factory instance. Note: it\n\t\t\t\t\t         may be invalid/shutdown.   */\n    pj_timer_entry\t    idle_timer;\t    /**< Timer when ref cnt is zero.*/\n\n    pj_timestamp\t    last_recv_ts;   /**< Last time receiving data.  */\n    pj_size_t\t\t    last_recv_len;  /**< Last received data length. */\n\n    void\t\t   *data;\t    /**< Internal transport data.   */\n\n    /**\n     * Function to be called by transport manager to send SIP message.\n     *\n     * @param transport\t    The transport to send the message.\n     * @param packet\t    The buffer to send.\n     * @param length\t    The length of the buffer to send.\n     * @param op_key\t    Completion token, which will be supplied to\n     *\t\t\t    caller when pending send operation completes.\n     * @param rem_addr\t    The remote destination address.\n     * @param addr_len\t    Size of remote address.\n     * @param callback\t    If supplied, the callback will be called\n     *\t\t\t    once a pending transmission has completed. If\n     *\t\t\t    the function completes immediately (i.e. return\n     *\t\t\t    code is not PJ_EPENDING), the callback will not\n     *\t\t\t    be called.\n     *\n     * @return\t\t    Should return PJ_SUCCESS only if data has been\n     *\t\t\t    succesfully queued to operating system for \n     *\t\t\t    transmission. Otherwise it may return PJ_EPENDING\n     *\t\t\t    if the underlying transport can not send the\n     *\t\t\t    data immediately and will send it later, which in\n     *\t\t\t    this case caller doesn't have to do anything \n     *\t\t\t    except wait the calback to be called, if it \n     *\t\t\t    supplies one.\n     *\t\t\t    Other return values indicate the error code.\n     */\n    pj_status_t (*send_msg)(pjsip_transport *transport, \n\t\t\t    pjsip_tx_data *tdata,\n\t\t\t    const pj_sockaddr_t *rem_addr,\n\t\t\t    int addr_len,\n\t\t\t    void *token,\n\t\t\t    pjsip_transport_callback callback);\n\n    /**\n     * Instruct the transport to initiate graceful shutdown procedure.\n     * After all objects release their reference to this transport,\n     * the transport will be deleted.\n     *\n     * Note that application MUST use #pjsip_transport_shutdown() instead.\n     *\n     * @param transport\t    The transport.\n     *\n     * @return\t\t    PJ_SUCCESS on success.\n     */\n    pj_status_t (*do_shutdown)(pjsip_transport *transport);\n\n    /**\n     * Forcefully destroy this transport regardless whether there are\n     * objects that currently use this transport. This function should only\n     * be called by transport manager or other internal objects (such as the\n     * transport itself) who know what they're doing. Application should use\n     * #pjsip_transport_shutdown() instead.\n     *\n     * @param transport\t    The transport.\n     *\n     * @return\t\t    PJ_SUCCESS on success.\n     */\n    pj_status_t (*destroy)(pjsip_transport *transport);\n\n    /*\n     * Application may extend this structure..\n     */\n};\n\n\n/**\n * Register a transport instance to the transport manager. This function\n * is normally called by the transport instance when it is created\n * by application.\n *\n * @param mgr\t\tThe transport manager.\n * @param tp\t\tThe new transport to be registered.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr,\n\t\t\t\t\t       pjsip_transport *tp );\n\n\n/**\n * Start graceful shutdown procedure for this transport. After graceful\n * shutdown has been initiated, no new reference can be obtained for\n * the transport. However, existing objects that currently uses the\n * transport may still use this transport to send and receive packets.\n *\n * After all objects release their reference to this transport,\n * the transport will be destroyed immediately.\n *\n * @param tp\t\t    The transport.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_transport_shutdown(pjsip_transport *tp);\n\n/**\n * Destroy a transport when there is no object currently uses the transport.\n * This function is normally called internally by transport manager or the\n * transport itself. Application should use #pjsip_transport_shutdown()\n * instead.\n *\n * @param tp\t\tThe transport instance.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n *\t\t\tSome of possible errors are PJSIP_EBUSY if the \n *\t\t\ttransport's reference counter is not zero.\n */\nPJ_DECL(pj_status_t) pjsip_transport_destroy( pjsip_transport *tp);\n\n/**\n * Add reference counter to the specified transport. Any objects that wishes\n * to keep the reference of the transport MUST increment the transport's\n * reference counter to prevent it from being destroyed.\n *\n * @param tp\t\tThe transport instance.\n *\n * @return\t\tPJ_SUCCESS on success or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_transport_add_ref( pjsip_transport *tp );\n\n/**\n * Decrement reference counter of the specified transport. When an object no\n * longer want to keep the reference to the transport, it must decrement the\n * reference counter. When the reference counter of the transport reaches \n * zero, the transport manager will start the idle timer to destroy the\n * transport if no objects acquire the reference counter during the idle\n * interval.\n *\n * @param tp\t\tThe transport instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp );\n\n\n/**\n * This function is called by transport instances to report an incoming \n * packet to the transport manager. The transport manager then would try to\n * parse all SIP messages in the packet, and for each parsed SIP message, it\n * would report the message to the SIP endpoint (#pjsip_endpoint).\n *\n * @param mgr\t\tThe transport manager instance.\n * @param rdata\t\tThe receive data buffer containing the packet. The\n *\t\t\ttransport MUST fully initialize tp_info and pkt_info\n *\t\t\tmember of the rdata.\n *\n * @return\t\tThe number of bytes successfully processed from the\n *\t\t\tpacket. If the transport is datagram oriented, the\n *\t\t\tvalue will be equal to the size of the packet. For\n *\t\t\tstream oriented transport (e.g. TCP, TLS), the value\n *\t\t\treturned may be less than the packet size, if \n *\t\t\tpartial message is received. The transport then MUST\n *\t\t\tkeep the remainder part and report it again to\n *\t\t\tthis function once more data/packet is received.\n */\nPJ_DECL(pj_ssize_t) pjsip_tpmgr_receive_packet(pjsip_tpmgr *mgr,\n\t\t\t\t\t       pjsip_rx_data *rdata);\n\n\n/*****************************************************************************\n *\n * TRANSPORT FACTORY\n *\n *****************************************************************************/\n\n\n/**\n * A transport factory is normally used for connection oriented transports\n * (such as TCP or TLS) to create instances of transports. It registers\n * a new transport type to the transport manager, and the transport manager\n * would ask the factory to create a transport instance when it received\n * command from application to send a SIP message using the specified\n * transport type.\n */\nstruct pjsip_tpfactory\n{\n    /** This list is managed by transport manager. */\n    PJ_DECL_LIST_MEMBER(struct pjsip_tpfactory);\n\n    char\t\t    obj_name[PJ_MAX_OBJ_NAME];\t/**< Name.\t*/\n\n    pj_pool_t\t\t   *pool;\t    /**< Owned memory pool.\t*/\n    pj_lock_t\t\t   *lock;\t    /**< Lock object.\t\t*/\n\n    pjsip_transport_type_e  type;\t    /**< Transport type.\t*/\n    char\t\t   *type_name;      /**< Type string name.\t*/\n    unsigned\t\t    flag;\t    /**< Transport flag.\t*/\n\n    pj_sockaddr\t\t    local_addr;\t    /**< Bound address.\t\t*/\n    pjsip_host_port\t    addr_name;\t    /**< Published name.\t*/\n\n    /**\n     * Create new outbound connection suitable for sending SIP message\n     * to specified remote address.\n     * Note that the factory is responsible for both creating the\n     * transport and registering it to the transport manager.\n     */\n    pj_status_t (*create_transport)(pjsip_tpfactory *factory,\n\t\t\t\t    pjsip_tpmgr *mgr,\n\t\t\t\t    pjsip_endpoint *endpt,\n\t\t\t\t    const pj_sockaddr *rem_addr,\n\t\t\t\t    int addr_len,\n\t\t\t\t    pjsip_transport **transport);\n\n    /**\n     * Create new outbound connection suitable for sending SIP message\n     * to specified remote address by also considering outgoing SIP \n     * message data.\n     * Note that the factory is responsible for both creating the\n     * transport and registering it to the transport manager.\n     */\n    pj_status_t (*create_transport2)(pjsip_tpfactory *factory,\n\t\t\t\t     pjsip_tpmgr *mgr,\n\t\t\t\t     pjsip_endpoint *endpt,\n\t\t\t\t     const pj_sockaddr *rem_addr,\n\t\t\t\t     int addr_len,\n\t\t\t\t     pjsip_tx_data *tdata,\n\t\t\t\t     pjsip_transport **transport);\n\n    /**\n     * Destroy the listener.\n     */\n    pj_status_t (*destroy)(pjsip_tpfactory *factory);\n\n    /*\n     * Application may extend this structure..\n     */\n};\n\n\n\n/**\n * Register a transport factory.\n *\n * @param mgr\t\tThe transport manager.\n * @param tpf\t\tTransport factory.\n *\n * @return\t\tPJ_SUCCESS if listener was successfully created.\n */\nPJ_DECL(pj_status_t) pjsip_tpmgr_register_tpfactory(pjsip_tpmgr *mgr,\n\t\t\t\t\t\t    pjsip_tpfactory *tpf);\n\n/**\n * Unregister factory.\n *\n * @param mgr\t\tThe transport manager.\n * @param tpf\t\tTransport factory.\n *\n * @return\t\tPJ_SUCCESS is sucessfully unregistered.\n */\nPJ_DECL(pj_status_t) pjsip_tpmgr_unregister_tpfactory(pjsip_tpmgr *mgr,\n\t\t\t\t\t\t      pjsip_tpfactory *tpf);\n\n\n/*****************************************************************************\n *\n * TRANSPORT MANAGER\n *\n *****************************************************************************/\n\n/**\n * Type of callback to be called when transport manager receives incoming\n * SIP message.\n *\n * @param ep\t    Endpoint.\n * @param status    Receiption status.\n * @param rd\t    Received packet.\n */\ntypedef void (*pjsip_rx_callback)(pjsip_endpoint *ep, pj_status_t status, \n\t\t\t\t  pjsip_rx_data *rd);\n\n/**\n * Type of callback to be called before transport manager is about\n * to transmit SIP message.\n *\n * @param ep\t    Endpoint.\n * @param td\t    Transmit data.\n */\ntypedef pj_status_t (*pjsip_tx_callback)(pjsip_endpoint *ep, pjsip_tx_data*td);\n\n/**\n * Create a transport manager. Normally application doesn't need to call\n * this function directly, since a transport manager will be created and\n * destroyed automatically by the SIP endpoint.\n *\n * @param pool\t    Pool.\n * @param endpt\t    Endpoint instance.\n * @param rx_cb\t    Callback to receive incoming message.\n * @param tx_cb\t    Callback to be called before transport manager is sending\n *\t\t    outgoing message.\n * @param p_mgr\t    Pointer to receive the new transport manager.\n *\n * @return\t    PJ_SUCCESS or the appropriate error code on error.\n */\nPJ_DECL(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool,\n\t\t\t\t\t pjsip_endpoint * endpt,\n\t\t\t\t\t pjsip_rx_callback rx_cb,\n\t\t\t\t\t pjsip_tx_callback tx_cb,\n\t\t\t\t\t pjsip_tpmgr **p_mgr);\n\n\n/**\n * Find out the appropriate local address info (IP address and port) to\n * advertise in Contact header based on the remote address to be \n * contacted. The local address info would be the address name of the\n * transport or listener which will be used to send the request.\n *\n * In this implementation, it will only select the transport based on\n * the transport type in the request.\n *\n * @see pjsip_tpmgr_find_local_addr2()\n *\n * @param tpmgr\t    The transport manager.\n * @param pool\t    Pool to allocate memory for the IP address.\n * @param type\t    Destination address to contact.\n * @param sel\t    Optional pointer to prefered transport, if any.\n * @param ip_addr   Pointer to receive the IP address.\n * @param port\t    Pointer to receive the port number.\n *\n * @return\t    PJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr,\n\t\t\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t\t\t  pjsip_transport_type_e type,\n\t\t\t\t\t\t  const pjsip_tpselector *sel,\n\t\t\t\t\t\t  pj_str_t *ip_addr,\n\t\t\t\t\t\t  int *port);\n\n/**\n * Parameter for pjsip_tpmgr_find_local_addr2() function.\n */\ntypedef struct pjsip_tpmgr_fla2_param\n{\n    /**\n     * Specify transport type to use. This must be set.\n     */\n    pjsip_transport_type_e\t tp_type;\n\n    /**\n     * Optional pointer to preferred transport, if any.\n     */\n    const pjsip_tpselector\t*tp_sel;\n\n    /**\n     * Destination host, if known. The destination host is needed\n     * if \\a local_if field below is set.\n     */\n    pj_str_t\t\t\t dst_host;\n\n    /**\n     * Specify if the function should return which local interface\n     * to use for the specified destination in \\a dst_host. By definition,\n     * the returned address will always be local interface address.\n     */\n    pj_bool_t\t\t\t local_if;\n\n    /**\n     * The returned address.\n     */\n    pj_str_t\t\t\t ret_addr;\n\n    /**\n     * The returned port.\n     */\n    pj_uint16_t\t\t\t ret_port;\n\n    /**\n     * Returned pointer to the transport. Only set if local_if is set.\n     */\n    const void\t\t\t*ret_tp;\n\n} pjsip_tpmgr_fla2_param;\n\n/**\n * Initialize with default values.\n *\n * @param prm\t    The parameter to be initialized.\n */\nPJ_DECL(void) pjsip_tpmgr_fla2_param_default(pjsip_tpmgr_fla2_param *prm);\n\n/**\n * Find out the appropriate local address info (IP address and port) to\n * advertise in Contact or Via header header based on the remote address\n * to be contacted. The local address info would be the address name of the\n * transport or listener which will be used to send the request.\n *\n * @see pjsip_tpmgr_find_local_addr()\n *\n * @param tpmgr\t    The transport manager.\n * @param pool\t    Pool to allocate memory for the IP address.\n * @param param\t    Function input and output parameters.\n *\n * @return\t    PJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tpmgr_find_local_addr2(pjsip_tpmgr *tpmgr,\n                                                  pj_pool_t *pool,\n                                                  pjsip_tpmgr_fla2_param *prm);\n\n/**\n * Return number of transports currently registered to the transport\n * manager.\n *\n * @param mgr\t    The transport manager.\n *\n * @return\t    Number of transports.\n */\nPJ_DECL(unsigned) pjsip_tpmgr_get_transport_count(pjsip_tpmgr *mgr);\n\n\n/**\n * Destroy a transport manager. Normally application doesn't need to call\n * this function directly, since a transport manager will be created and\n * destroyed automatically by the SIP endpoint.\n *\n * @param mgr\t    The transport manager.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_tpmgr_destroy(pjsip_tpmgr *mgr);\n\n\n/**\n * Dump transport info and status to log.\n *\n * @param mgr\t    The transport manager.\n */\nPJ_DECL(void) pjsip_tpmgr_dump_transports(pjsip_tpmgr *mgr);\n\n\n/*****************************************************************************\n *\n * PUBLIC API\n *\n *****************************************************************************/\n\n\n/**\n * Find transport to be used to send message to remote destination. If no\n * suitable transport is found, a new one will be created.\n *\n * This is an internal function since normally application doesn't have access\n * to transport manager. Application should use pjsip_endpt_acquire_transport()\n * instead.\n *\n * @param mgr\t    The transport manager instance.\n * @param type\t    The type of transport to be acquired.\n * @param remote    The remote address to send message to.\n * @param addr_len  Length of the remote address.\n * @param sel\t    Optional pointer to transport selector instance which is\n *\t\t    used to find explicit transport, if required.\n * @param tp\t    Pointer to receive the transport instance, if one is found.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr,\n\t\t\t\t\t\t   pjsip_transport_type_e type,\n\t\t\t\t\t\t   const pj_sockaddr_t *remote,\n\t\t\t\t\t\t   int addr_len,\n\t\t\t\t\t\t   const pjsip_tpselector *sel,\n\t\t\t\t\t\t   pjsip_transport **tp);\n\n/**\n * Find suitable transport for sending SIP message to specified remote \n * destination by also considering the outgoing SIP message. If no suitable \n * transport is found, a new one will be created.\n *\n * This is an internal function since normally application doesn't have access\n * to transport manager. Application should use pjsip_endpt_acquire_transport2()\n * instead.\n *\n * @param mgr\t    The transport manager instance.\n * @param type\t    The type of transport to be acquired.\n * @param remote    The remote address to send message to.\n * @param addr_len  Length of the remote address.\n * @param sel\t    Optional pointer to transport selector instance which is\n *\t\t    used to find explicit transport, if required.\n * @param tdata\t    Optional pointer to data to be sent.\n * @param tp\t    Pointer to receive the transport instance, if one is found.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,\n\t\t\t\t\t\t    pjsip_transport_type_e type,\n\t\t\t\t\t\t    const pj_sockaddr_t *remote,\n\t\t\t\t\t\t    int addr_len,\n\t\t\t\t\t\t    const pjsip_tpselector *sel,\n\t\t\t\t\t\t    pjsip_tx_data *tdata,\n\t\t\t\t\t\t    pjsip_transport **tp);\n\n/**\n * Type of callback to receive notification when message or raw data\n * has been sent.\n *\n * @param token\t\tThe token that was given when calling the function\n *\t\t\tto send message or raw data.\n * @param tdata\t\tThe transmit buffer used to send the message.\n * @param bytes_sent\tNumber of bytes sent. On success, the value will be\n *\t\t\tpositive number indicating the number of bytes sent.\n *\t\t\tOn failure, the value will be a negative number of\n *\t\t\tthe error code (i.e. bytes_sent = -status).\n */\ntypedef void (*pjsip_tp_send_callback)(void *token, pjsip_tx_data *tdata,\n\t\t\t\t       pj_ssize_t bytes_sent);\n\n\n/**\n * This is a low-level function to send a SIP message using the specified\n * transport to the specified destination.\n * \n * @param tr\t    The SIP transport to be used.\n * @param tdata\t    Transmit data buffer containing SIP message.\n * @param addr\t    Destination address.\n * @param addr_len  Length of destination address.\n * @param token\t    Arbitrary token to be returned back to callback.\n * @param cb\t    Optional callback to be called to notify caller about\n *\t\t    the completion status of the pending send operation.\n *\n * @return\t    If the message has been sent successfully, this function\n *\t\t    will return PJ_SUCCESS and the callback will not be \n *\t\t    called. If message cannot be sent immediately, this\n *\t\t    function will return PJ_EPENDING, and application will\n *\t\t    be notified later about the completion via the callback.\n *\t\t    Any statuses other than PJ_SUCCESS or PJ_EPENDING\n *\t\t    indicates immediate failure, and in this case the \n *\t\t    callback will not be called.\n */\nPJ_DECL(pj_status_t) pjsip_transport_send( pjsip_transport *tr, \n\t\t\t\t\t   pjsip_tx_data *tdata,\n\t\t\t\t\t   const pj_sockaddr_t *addr,\n\t\t\t\t\t   int addr_len,\n\t\t\t\t\t   void *token,\n\t\t\t\t\t   pjsip_tp_send_callback cb);\n\n\n/**\n * This is a low-level function to send raw data to a destination.\n *\n * See also #pjsip_endpt_send_raw() and #pjsip_endpt_send_raw_to_uri().\n *\n * @param mgr\t    Transport manager.\n * @param tp_type   Transport type.\n * @param sel\t    Optional pointer to transport selector instance if\n *\t\t    application wants to use a specific transport instance\n *\t\t    rather then letting transport manager finds the suitable\n *\t\t    transport.\n * @param tdata\t    Optional transmit data buffer to be used. If this value\n *\t\t    is NULL, this function will create one internally. If\n *\t\t    tdata is specified, this function will decrement the\n *\t\t    reference counter upon completion.\n * @param raw_data  The data to be sent.\n * @param data_len  The length of the data.\n * @param addr\t    Destination address.\n * @param addr_len  Length of destination address.\n * @param token\t    Arbitrary token to be returned back to callback.\n * @param cb\t    Optional callback to be called to notify caller about\n *\t\t    the completion status of the pending send operation.\n *\n * @return\t    If the message has been sent successfully, this function\n *\t\t    will return PJ_SUCCESS and the callback will not be \n *\t\t    called. If message cannot be sent immediately, this\n *\t\t    function will return PJ_EPENDING, and application will\n *\t\t    be notified later about the completion via the callback.\n *\t\t    Any statuses other than PJ_SUCCESS or PJ_EPENDING\n *\t\t    indicates immediate failure, and in this case the \n *\t\t    callback will not be called.\n */\nPJ_DECL(pj_status_t) pjsip_tpmgr_send_raw(pjsip_tpmgr *mgr,\n\t\t\t\t\t  pjsip_transport_type_e tp_type,\n\t\t\t\t\t  const pjsip_tpselector *sel,\n\t\t\t\t\t  pjsip_tx_data *tdata,\n\t\t\t\t\t  const void *raw_data,\n\t\t\t\t\t  pj_size_t data_len,\n\t\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t\t  int addr_len,\n\t\t\t\t\t  void *token,\n\t\t\t\t\t  pjsip_tp_send_callback cb);\n\n\n/**\n * Enumeration of transport state types.\n */\ntypedef enum pjsip_transport_state\n{\n    PJSIP_TP_STATE_CONNECTED,\t    /**< Transport connected, applicable only\n\t\t\t\t\t to connection-oriented transports\n\t\t\t\t\t such as TCP and TLS.\t\t    */\n    PJSIP_TP_STATE_DISCONNECTED,    /**< Transport disconnected, applicable\n\t\t\t\t\t only to connection-oriented \n\t\t\t\t\t transports such as TCP and TLS.    */\n    PJSIP_TP_STATE_SHUTDOWN,        /**< Transport shutdown, either\n                                         due to TCP/TLS disconnect error\n                                         from the network, or when shutdown\n                                         is initiated by PJSIP itself.      */\n    PJSIP_TP_STATE_DESTROY,         /**< Transport destroy, when transport\n                                         is about to be destroyed.          */\n} pjsip_transport_state;\n\n\n/**\n * Definition of transport state listener key.\n */\ntypedef void pjsip_tp_state_listener_key;\n\n/**\n * Structure of transport state info passed by #pjsip_tp_state_callback.\n */\ntypedef struct pjsip_transport_state_info {\n    /**\n     * The last error code related to the transport state.\n     */\n    pj_status_t\t\t status;\n\n    /**\n     * Optional extended info, the content is specific for each transport type.\n     */\n    void\t\t*ext_info;\n\n    /**\n     * Optional user data. In global transport state notification, this will\n     * always be NULL.\n     */\n    void\t\t*user_data;\n\n} pjsip_transport_state_info;\n\n\n/**\n * Type of callback to receive transport state notifications, such as\n * transport connected/disconnected. Application may shutdown the transport\n * in this callback.\n *\n * @param tp\t\tThe transport instance.\n * @param state\t\tThe transport state.\n * @param info\t\tThe transport state info.\n */\ntypedef void (*pjsip_tp_state_callback)(\n\t\t\t\t    pjsip_transport *tp,\n\t\t\t\t    pjsip_transport_state state,\n\t\t\t\t    const pjsip_transport_state_info *info);\n\n\n/**\n * Set callback of global transport state notification. The caller will be\n * notified whenever the state of any transport is changed. The type of events\n * are defined in #pjsip_transport_state.\n *\n * Note that this function will override the existing callback, if any, so\n * application is recommended to keep the old callback and manually forward\n * the notification to the old callback, otherwise other component that \n * concerns about the transport state will no longer receive transport state \n * events.\n * \n * @param mgr\t    Transport manager.\n * @param cb\t    Callback to be called to notify caller about transport \n *\t\t    state changing.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tpmgr_set_state_cb(pjsip_tpmgr *mgr,\n\t\t\t\t\t      pjsip_tp_state_callback cb);\n\n\n/**\n * Get the callback of global transport state notification.\n * \n * @param mgr\t    Transport manager.\n *\n * @return\t    The transport state callback or NULL if it is not set.\n */\nPJ_DECL(pjsip_tp_state_callback) pjsip_tpmgr_get_state_cb(\n\t\t\t\t\t      const pjsip_tpmgr *mgr);\n\n\n/**\n * Add a listener to the specified transport for transport state notification.\n * \n * @param tp\t    The transport.\n * @param cb\t    Callback to be called to notify listener about transport \n *\t\t    state changing.\n * @param user_data The user data.\n * @param key\t    Output key, used to remove this listener.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_transport_add_state_listener (\n\t\t\t\t\t    pjsip_transport *tp,\n\t\t\t\t\t    pjsip_tp_state_callback cb,\n\t\t\t\t\t    void *user_data,\n\t\t\t\t\t    pjsip_tp_state_listener_key **key);\n\n\n/**\n * Remove a listener from the specified transport for transport state \n * notification.\n * \n * @param tp\t    The transport.\n * @param key\t    The listener key.\n * @param user_data The user data, for validation purpose.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_transport_remove_state_listener (\n\t\t\t\t    pjsip_transport *tp,\n\t\t\t\t    pjsip_tp_state_listener_key *key,\n\t\t\t\t    const void *user_data);\n\n\n/**\n * Structure of dropped received data.\n */\ntypedef struct pjsip_tp_dropped_data\n{\n    /**\n     * The transport receiving the data.\n     */\n    pjsip_transport *tp;\n\n    /**\n     * The data.\n     */\n    void\t    *data;\n\n    /**\n     * The data length.\n     * If the status field below indicates an invalid SIP message\n     * (PJSIP_EINVALIDMSG) and application detects a SIP message\n     * at position p, it can pass the data back to PJSIP to be processed\n     * by setting the len to p. This can be useful for apps which\n     * wishes to use the same transport for SIP signalling and non-SIP\n     * purposes (such as SIP outbound using STUN message).\n     */\n    pj_size_t\t     len;\n\n    /**\n     * The status or reason of drop. For example, a leading newlines (common\n     * keep-alive packet) will be dropped with status PJ_EIGNORED, an invalid\n     * SIP message will have status PJSIP_EINVALIDMSG, a SIP message overflow\n     * will have status PJSIP_ERXOVERFLOW.\n     */\n    pj_status_t\t     status;\n\n} pjsip_tp_dropped_data;\n\n\n/**\n * Type of callback to data dropping notifications.\n *\n * @param data\t\tThe dropped data.\n */\ntypedef void (*pjsip_tp_on_rx_dropped_cb)(pjsip_tp_dropped_data *data);\n\n\n/**\n * Set callback of data dropping. The caller will be notified whenever any\n * received data is dropped (due to leading newlines or keep-alive packet or\n * invalid SIP message). This callback can be useful for application,\n * for example, to implement custom keep-alive mechanism or connection\n * availability detection.\n *\n * @param mgr\t    Transport manager.\n * @param cb\t    The callback function, set to NULL to reset the callback.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tpmgr_set_drop_data_cb(pjsip_tpmgr *mgr,\n\t\t\t\t\t\t  pjsip_tp_on_rx_dropped_cb cb);\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_SIP_TRANSPORT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_transport_loop.h",
    "content": "/* $Id: sip_transport_loop.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_TRANSPORT_LOOP_H__\n#define __PJSIP_TRANSPORT_LOOP_H__\n\n\n/**\n * @file sip_transport_loop.h\n * @brief \n * Loopback transport (for debugging)\n */\n\n\n#include <pjsip/sip_transport.h>\n\n/**\n * @defgroup PJSIP_TRANSPORT_LOOP Loop Transport\n * @ingroup PJSIP_TRANSPORT\n * @brief Loopback transport (for testing purposes).\n * @{\n * The loopback transport simply bounce back outgoing messages as\n * incoming messages. This feature is used mostly during automated\n * testing, to provide controlled behavior.\n */\n\nPJ_BEGIN_DECL\n\n/**\n * Create and start datagram loop transport.\n *\n * @param endpt\t\tThe endpoint instance.\n * @param transport\tPointer to receive the transport instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_loop_start( pjsip_endpoint *endpt,\n\t\t\t\t       pjsip_transport **transport);\n\n\n/**\n * Enable/disable flag to discard any packets sent using the specified\n * loop transport.\n *\n * @param tp\t\tThe loop transport.\n * @param discard\tIf non-zero, any outgoing packets will be discarded.\n * @param prev_value\tOptional argument to receive previous value of\n *\t\t\tthe discard flag.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_loop_set_discard( pjsip_transport *tp,\n\t\t\t\t\t     pj_bool_t discard,\n\t\t\t\t\t     pj_bool_t *prev_value );\n\n\n/**\n * Enable/disable flag to simulate network error. When this flag is set,\n * outgoing transmission will return either immediate error or error via\n * callback. If error is to be notified via callback, then the notification\n * will occur after some delay, which is controlled by #pjsip_loop_set_delay().\n *\n * @param tp\t\tThe loop transport.\n * @param fail_flag\tIf set to 1, the transport will return fail to deliver\n *\t\t\tthe message. If delay is zero, failure will occur\n *\t\t\timmediately; otherwise it will be reported in callback.\n *\t\t\tIf set to zero, the transport will successfully deliver\n *\t\t\tthe packet.\n * @param prev_value\tOptional argument to receive previous value of\n *\t\t\tthe failure flag.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_loop_set_failure( pjsip_transport *tp,\n\t\t\t\t\t     int fail_flag,\n\t\t\t\t\t     int *prev_value );\n\n\n/**\n * Set delay (in miliseconds) before packet is received by the other end\n * of the loop transport. This will also \n * control the delay for error notification callback.\n *\n * @param tp\t\tThe loop transport.\n * @param delay\t\tDelay, in miliseconds.\n * @param prev_value\tOptional argument to receive previous value of the\n *\t\t\tdelay.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_loop_set_recv_delay( pjsip_transport *tp,\n\t\t\t\t\t\tunsigned delay,\n\t\t\t\t\t\tunsigned *prev_value);\n\n\n/**\n * Set delay (in miliseconds) before send notification is delivered to sender.\n * This will also control the delay for error notification callback.\n *\n * @param tp\t\tThe loop transport.\n * @param delay\t\tDelay, in miliseconds.\n * @param prev_value\tOptional argument to receive previous value of the\n *\t\t\tdelay.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_loop_set_send_callback_delay( pjsip_transport *tp,\n\t\t\t\t\t\t\t unsigned delay,\n\t\t\t\t\t\t\t unsigned *prev_value);\n\n\n/**\n * Set both receive and send notification delay.\n *\n * @param tp\t\tThe loop transport.\n * @param delay\t\tDelay, in miliseconds.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_loop_set_delay( pjsip_transport *tp,\n\t\t\t\t\t   unsigned delay );\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJSIP_TRANSPORT_LOOP_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_transport_tcp.h",
    "content": "/* $Id: sip_transport_tcp.h 4506 2013-04-26 06:01:43Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_TRANSPORT_TCP_H__\n#define __PJSIP_TRANSPORT_TCP_H__\n\n/**\n * @file sip_transport_tcp.h\n * @brief SIP TCP Transport.\n */\n\n#include <pjsip/sip_transport.h>\n#include <pj/sock_qos.h>\n\n\n/* Only declare the API if PJ_HAS_TCP is true */\n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP!=0\n\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_TRANSPORT_TCP TCP Transport\n * @ingroup PJSIP_TRANSPORT\n * @brief API to create and register TCP transport.\n * @{\n * The functions below are used to create TCP transport and register \n * the transport to the framework.\n */\n\n/**\n * Settings to be specified when creating the TCP transport. Application \n * should initialize this structure with its default values by calling \n * pjsip_tcp_transport_cfg_default().\n */\ntypedef struct pjsip_tcp_transport_cfg\n{\n    /**\n     * Address family to use. Valid values are pj_AF_INET() and\n     * pj_AF_INET6(). Default is pj_AF_INET().\n     */\n    int\t\t\taf;\n\n    /**\n     * Optional address to bind the socket to. Default is to bind to \n     * PJ_INADDR_ANY and to any available port.\n     */\n    pj_sockaddr\t\tbind_addr;\n\n    /**\n     * Should SO_REUSEADDR be used for the listener socket.\n     * Default value is PJSIP_TCP_TRANSPORT_REUSEADDR.\n     */\n    pj_bool_t\t\treuse_addr;\n\n    /**\n     * Optional published address, which is the address to be\n     * advertised as the address of this SIP transport. \n     * By default the bound address will be used as the published address.\n     */\n    pjsip_host_port\taddr_name;\n\n    /**\n     * Number of simultaneous asynchronous accept() operations to be \n     * supported. It is recommended that the number here corresponds to \n     * the number of processors in the system (or the number of SIP\n     * worker threads).\n     *\n     * Default: 1\n     */\n    unsigned\t       async_cnt;\n\n    /**\n     * QoS traffic type to be set on this transport. When application wants\n     * to apply QoS tagging to the transport, it's preferable to set this\n     * field rather than \\a qos_param fields since this is more portable.\n     *\n     * Default is QoS not set.\n     */\n    pj_qos_type\t\tqos_type;\n\n    /**\n     * Set the low level QoS parameters to the transport. This is a lower\n     * level operation than setting the \\a qos_type field and may not be\n     * supported on all platforms.\n     *\n     * Default is QoS not set.\n     */\n    pj_qos_params\tqos_params;\n\n    /**\n     * Specify options to be set on the transport. \n     *\n     * By default there is no options.\n     * \n     */\n    pj_sockopt_params\tsockopt_params;\n\n} pjsip_tcp_transport_cfg;\n\n\n/**\n * Initialize pjsip_tcp_transport_cfg structure with default values for\n * the specifed address family.\n *\n * @param cfg\t\tThe structure to initialize.\n * @param af\t\tAddress family to be used.\n */\nPJ_DECL(void) pjsip_tcp_transport_cfg_default(pjsip_tcp_transport_cfg *cfg,\n\t\t\t\t\t      int af);\n\n\n/**\n * Register support for SIP TCP transport by creating TCP listener on\n * the specified address and port. This function will create an\n * instance of SIP TCP transport factory and register it to the\n * transport manager.\n *\n * @param endpt\t\tThe SIP endpoint.\n * @param local\t\tOptional local address to bind, or specify the\n *\t\t\taddress to bind the server socket to. Both IP \n *\t\t\tinterface address and port fields are optional.\n *\t\t\tIf IP interface address is not specified, socket\n *\t\t\twill be bound to PJ_INADDR_ANY. If port is not\n *\t\t\tspecified, socket will be bound to any port\n *\t\t\tselected by the operating system.\n * @param async_cnt\tNumber of simultaneous asynchronous accept()\n *\t\t\toperations to be supported. It is recommended that\n *\t\t\tthe number here corresponds to the number of\n *\t\t\tprocessors in the system (or the number of SIP\n *\t\t\tworker threads).\n * @param p_factory\tOptional pointer to receive the instance of the\n *\t\t\tSIP TCP transport factory just created.\n *\n * @return\t\tPJ_SUCCESS when the transport has been successfully\n *\t\t\tstarted and registered to transport manager, or\n *\t\t\tthe appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tcp_transport_start(pjsip_endpoint *endpt,\n\t\t\t\t\t       const pj_sockaddr_in *local,\n\t\t\t\t\t       unsigned async_cnt,\n\t\t\t\t\t       pjsip_tpfactory **p_factory);\n\n\n\n/**\n * A newer variant of #pjsip_tcp_transport_start(), which allows specifying\n * the published/public address of the TCP transport.\n *\n * @param endpt\t\tThe SIP endpoint.\n * @param local\t\tOptional local address to bind, or specify the\n *\t\t\taddress to bind the server socket to. Both IP \n *\t\t\tinterface address and port fields are optional.\n *\t\t\tIf IP interface address is not specified, socket\n *\t\t\twill be bound to PJ_INADDR_ANY. If port is not\n *\t\t\tspecified, socket will be bound to any port\n *\t\t\tselected by the operating system.\n * @param a_name\tOptional published address, which is the address to be\n *\t\t\tadvertised as the address of this SIP transport. \n *\t\t\tIf this argument is NULL, then the bound address\n *\t\t\twill be used as the published address.\n * @param async_cnt\tNumber of simultaneous asynchronous accept()\n *\t\t\toperations to be supported. It is recommended that\n *\t\t\tthe number here corresponds to the number of\n *\t\t\tprocessors in the system (or the number of SIP\n *\t\t\tworker threads).\n * @param p_factory\tOptional pointer to receive the instance of the\n *\t\t\tSIP TCP transport factory just created.\n *\n * @return\t\tPJ_SUCCESS when the transport has been successfully\n *\t\t\tstarted and registered to transport manager, or\n *\t\t\tthe appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tcp_transport_start2(pjsip_endpoint *endpt,\n\t\t\t\t\t        const pj_sockaddr_in *local,\n\t\t\t\t\t        const pjsip_host_port *a_name,\n\t\t\t\t\t        unsigned async_cnt,\n\t\t\t\t\t        pjsip_tpfactory **p_factory);\n\n/**\n * Another variant of #pjsip_tcp_transport_start().\n *\n * @param endpt\t\tThe SIP endpoint.\n * @param cfg\t\tTCP transport settings. Application should initialize\n *\t\t\tthis setting with #pjsip_tcp_transport_cfg_default().\n * @param p_factory\tOptional pointer to receive the instance of the\n *\t\t\tSIP TCP transport factory just created.\n *\n * @return\t\tPJ_SUCCESS when the transport has been successfully\n *\t\t\tstarted and registered to transport manager, or\n *\t\t\tthe appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tcp_transport_start3(\n\t\t\t\t\tpjsip_endpoint *endpt,\n\t\t\t\t\tconst pjsip_tcp_transport_cfg *cfg,\n\t\t\t\t\tpjsip_tpfactory **p_factory\n\t\t\t\t\t);\n\n/**\n * Retrieve the internal socket handle used by the TCP transport. Note\n * that this socket normally is registered to ioqueue, so application\n * needs to take care not to perform operation that disrupts ioqueue\n * operation.\n *\n * @param transport\tThe TCP transport.\n *\n * @return\t\tThe socket handle, or PJ_INVALID_SOCKET if no socket\n *\t\t\tis currently being used.\n */\nPJ_DECL(pj_sock_t) pjsip_tcp_transport_get_socket(pjsip_transport *transport);\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* PJ_HAS_TCP */\n\n#endif\t/* __PJSIP_TRANSPORT_TCP_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_transport_tls.h",
    "content": "/* $Id: sip_transport_tls.h 4506 2013-04-26 06:01:43Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_TRANSPORT_TLS_H__\n#define __PJSIP_TRANSPORT_TLS_H__\n\n/**\n * @file sip_transport_tls.h\n * @brief SIP TLS Transport.\n */\n\n#include <pjsip/sip_transport.h>\n#include <pj/pool.h>\n#include <pj/ssl_sock.h>\n#include <pj/string.h>\n#include <pj/sock_qos.h>\n\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_TRANSPORT_TLS TLS Transport\n * @ingroup PJSIP_TRANSPORT\n * @brief API to create and register TLS transport.\n * @{\n * The functions below are used to create TLS transport and register \n * the transport to the framework.\n */\n\n/**\n * The default SSL method to be used by PJSIP.\n * Default is PJSIP_TLSV1_METHOD\n */\n#ifndef PJSIP_SSL_DEFAULT_METHOD\n#   define PJSIP_SSL_DEFAULT_METHOD\tPJSIP_TLSV1_METHOD\n#endif\n\n\n/** SSL protocol method constants. */\ntypedef enum pjsip_ssl_method\n{\n    PJSIP_SSL_UNSPECIFIED_METHOD = 0,\t/**< Default protocol method.\t*/    \n    PJSIP_SSLV2_METHOD\t\t = 20,\t/**< Use SSLv2 method.\t\t*/\n    PJSIP_SSLV3_METHOD\t\t = 30,\t/**< Use SSLv3 method.\t\t*/\n    PJSIP_TLSV1_METHOD\t\t = 31,\t/**< Use TLSv1 method.\t\t*/\n    PJSIP_TLSV1_1_METHOD\t = 32,\t/**< Use TLSv1_1 method.\t*/\n    PJSIP_TLSV1_2_METHOD\t = 33,\t/**< Use TLSv1_2 method.\t*/\n    PJSIP_SSLV23_METHOD\t\t = 23,\t/**< Use SSLv23 method.\t\t*/\n} pjsip_ssl_method;\n\n/**\n * The default enabled SSL proto to be used.\n * Default is all protocol above TLSv1 (TLSv1 & TLS v1.1 & TLS v1.2).\n */\n#ifndef PJSIP_SSL_DEFAULT_PROTO\n#   define PJSIP_SSL_DEFAULT_PROTO  (PJ_SSL_SOCK_PROTO_TLS1 | \\\n\t\t\t\t     PJ_SSL_SOCK_PROTO_TLS1_1 | \\\n\t\t\t\t     PJ_SSL_SOCK_PROTO_TLS1_2)\n#endif\n\n/**\n * TLS transport settings.\n */\ntypedef struct pjsip_tls_setting\n{\n    /**\n     * Certificate of Authority (CA) list file.\n     */\n    pj_str_t\tca_list_file;\n\n    /**\n     * Certificate of Authority (CA) list directory path.\n     */\n    pj_str_t\tca_list_path;\n\n    /**\n     * Public endpoint certificate file, which will be used as client-\n     * side  certificate for outgoing TLS connection, and server-side\n     * certificate for incoming TLS connection.\n     */\n    pj_str_t\tcert_file;\n\n    /**\n     * Optional private key of the endpoint certificate to be used.\n     */\n    pj_str_t\tprivkey_file;\n\n    /**\n     * Password to open private key.\n     */\n    pj_str_t\tpassword;\n\n    /**\n     * TLS protocol method from #pjsip_ssl_method. In the future, this field\n     * might be deprecated in favor of <b>proto</b> field. For now, this field \n     * is only applicable only when <b>proto</b> field is set to zero.\n     *\n     * Default is PJSIP_SSL_UNSPECIFIED_METHOD (0), which in turn will\n     * use PJSIP_SSL_DEFAULT_METHOD, which default value is PJSIP_TLSV1_METHOD.\n     */\n    pjsip_ssl_method\tmethod;\n\n    /**\n     * TLS protocol type from #pj_ssl_sock_proto. Use this field to enable \n     * specific protocol type. Use bitwise OR operation to combine the protocol \n     * type.\n     *\n     * Default is PJSIP_SSL_DEFAULT_PROTO.\n     */\n    pj_uint32_t\tproto;\n\n    /**\n     * Number of ciphers contained in the specified cipher preference. \n     * If this is set to zero, then default cipher list of the backend \n     * will be used.\n     *\n     * Default: 0 (zero).\n     */\n    unsigned ciphers_num;\n\n    /**\n     * Ciphers and order preference. The #pj_ssl_cipher_get_availables()\n     * can be used to check the available ciphers supported by backend.\n     */\n    pj_ssl_cipher *ciphers;\n\n    /**\n     * Specifies TLS transport behavior on the server TLS certificate \n     * verification result:\n     * - If \\a verify_server is disabled (set to PJ_FALSE), TLS transport \n     *   will just notify the application via #pjsip_tp_state_callback with\n     *   state PJSIP_TP_STATE_CONNECTED regardless TLS verification result.\n     * - If \\a verify_server is enabled (set to PJ_TRUE), TLS transport \n     *   will be shutdown and application will be notified with state\n     *   PJSIP_TP_STATE_DISCONNECTED whenever there is any TLS verification\n     *   error, otherwise PJSIP_TP_STATE_CONNECTED will be notified.\n     *\n     * In any cases, application can inspect #pjsip_tls_state_info in the\n     * callback to see the verification detail.\n     *\n     * Default value is PJ_FALSE.\n     */\n    pj_bool_t\tverify_server;\n\n    /**\n     * Specifies TLS transport behavior on the client TLS certificate \n     * verification result:\n     * - If \\a verify_client is disabled (set to PJ_FALSE), TLS transport \n     *   will just notify the application via #pjsip_tp_state_callback with\n     *   state PJSIP_TP_STATE_CONNECTED regardless TLS verification result.\n     * - If \\a verify_client is enabled (set to PJ_TRUE), TLS transport \n     *   will be shutdown and application will be notified with state\n     *   PJSIP_TP_STATE_DISCONNECTED whenever there is any TLS verification\n     *   error, otherwise PJSIP_TP_STATE_CONNECTED will be notified.\n     *\n     * In any cases, application can inspect #pjsip_tls_state_info in the\n     * callback to see the verification detail.\n     *\n     * Default value is PJ_FALSE.\n     */\n    pj_bool_t\tverify_client;\n\n    /**\n     * When acting as server (incoming TLS connections), reject inocming\n     * connection if client doesn't supply a TLS certificate.\n     *\n     * This setting corresponds to SSL_VERIFY_FAIL_IF_NO_PEER_CERT flag.\n     * Default value is PJ_FALSE.\n     */\n    pj_bool_t\trequire_client_cert;\n\n    /**\n     * TLS negotiation timeout to be applied for both outgoing and\n     * incoming connection. If both sec and msec member is set to zero,\n     * the SSL negotiation doesn't have a timeout.\n     */\n    pj_time_val\ttimeout;\n\n    /**\n     * Should SO_REUSEADDR be used for the listener socket.\n     * Default value is PJSIP_TLS_TRANSPORT_REUSEADDR.\n     */\n    pj_bool_t reuse_addr;\n\n    /**\n     * QoS traffic type to be set on this transport. When application wants\n     * to apply QoS tagging to the transport, it's preferable to set this\n     * field rather than \\a qos_param fields since this is more portable.\n     *\n     * Default value is PJ_QOS_TYPE_BEST_EFFORT.\n     */\n    pj_qos_type qos_type;\n\n    /**\n     * Set the low level QoS parameters to the transport. This is a lower\n     * level operation than setting the \\a qos_type field and may not be\n     * supported on all platforms.\n     *\n     * By default all settings in this structure are disabled.\n     */\n    pj_qos_params qos_params;\n\n    /**\n     * Specify if the transport should ignore any errors when setting the QoS\n     * traffic type/parameters.\n     *\n     * Default: PJ_TRUE\n     */\n    pj_bool_t qos_ignore_error;\n\n    /**\n     * Specify options to be set on the transport. \n     *\n     * By default there is no options.\n     * \n     */\n    pj_sockopt_params sockopt_params;\n\n    /**\n     * Specify if the transport should ignore any errors when setting the \n     * sockopt parameters.\n     *\n     * Default: PJ_TRUE\n     * \n     */\n    pj_bool_t sockopt_ignore_error;\n\n} pjsip_tls_setting;\n\n\n/**\n * This structure defines TLS transport extended info in <tt>ext_info</tt>\n * field of #pjsip_transport_state_info for the transport state notification\n * callback #pjsip_tp_state_callback.\n */\ntypedef struct pjsip_tls_state_info\n{\n    /**\n     * SSL socket info.\n     */\n    pj_ssl_sock_info\t*ssl_sock_info;\n\n} pjsip_tls_state_info;\n\n\n/**\n * Initialize TLS setting with default values.\n *\n * @param tls_opt   The TLS setting to be initialized.\n */\nPJ_INLINE(void) pjsip_tls_setting_default(pjsip_tls_setting *tls_opt)\n{\n    pj_memset(tls_opt, 0, sizeof(*tls_opt));\n    tls_opt->reuse_addr = PJSIP_TLS_TRANSPORT_REUSEADDR;\n    tls_opt->qos_type = PJ_QOS_TYPE_BEST_EFFORT;\n    tls_opt->qos_ignore_error = PJ_TRUE;\n    tls_opt->sockopt_ignore_error = PJ_TRUE;\n    tls_opt->proto = PJSIP_SSL_DEFAULT_PROTO;\n}\n\n\n/**\n * Copy TLS setting.\n *\n * @param pool\t    The pool to duplicate strings etc.\n * @param dst\t    Destination structure.\n * @param src\t    Source structure.\n */\nPJ_INLINE(void) pjsip_tls_setting_copy(pj_pool_t *pool,\n\t\t\t\t       pjsip_tls_setting *dst,\n\t\t\t\t       const pjsip_tls_setting *src)\n{\n    pj_memcpy(dst, src, sizeof(*dst));\n    pj_strdup_with_null(pool, &dst->ca_list_file, &src->ca_list_file);\n    pj_strdup_with_null(pool, &dst->ca_list_path, &src->ca_list_path);\n    pj_strdup_with_null(pool, &dst->cert_file, &src->cert_file);\n    pj_strdup_with_null(pool, &dst->privkey_file, &src->privkey_file);\n    pj_strdup_with_null(pool, &dst->password, &src->password);\n    if (src->ciphers_num) {\n\tunsigned i;\n\tdst->ciphers = (pj_ssl_cipher*) pj_pool_calloc(pool, src->ciphers_num,\n\t\t\t\t\t\t       sizeof(pj_ssl_cipher));\n\tfor (i=0; i<src->ciphers_num; ++i)\n\t    dst->ciphers[i] = src->ciphers[i];\n    }\n}\n\n\n/**\n * Register support for SIP TLS transport by creating TLS listener on\n * the specified address and port. This function will create an\n * instance of SIP TLS transport factory and register it to the\n * transport manager.\n *\n * See also #pjsip_tls_transport_start2() which supports IPv6.\n *\n * @param endpt\t\tThe SIP endpoint.\n * @param opt\t\tOptional TLS settings.\n * @param local\t\tOptional local address to bind, or specify the\n *\t\t\taddress to bind the server socket to. Both IP \n *\t\t\tinterface address and port fields are optional.\n *\t\t\tIf IP interface address is not specified, socket\n *\t\t\twill be bound to PJ_INADDR_ANY. If port is not\n *\t\t\tspecified, socket will be bound to any port\n *\t\t\tselected by the operating system.\n * @param a_name\tOptional published address, which is the address to be\n *\t\t\tadvertised as the address of this SIP transport. \n *\t\t\tIf this argument is NULL, then the bound address\n *\t\t\twill be used as the published address.\n * @param async_cnt\tNumber of simultaneous asynchronous accept()\n *\t\t\toperations to be supported. It is recommended that\n *\t\t\tthe number here corresponds to the number of\n *\t\t\tprocessors in the system (or the number of SIP\n *\t\t\tworker threads).\n * @param p_factory\tOptional pointer to receive the instance of the\n *\t\t\tSIP TLS transport factory just created.\n *\n * @return\t\tPJ_SUCCESS when the transport has been successfully\n *\t\t\tstarted and registered to transport manager, or\n *\t\t\tthe appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tls_transport_start(pjsip_endpoint *endpt,\n\t\t\t\t\t       const pjsip_tls_setting *opt,\n\t\t\t\t\t       const pj_sockaddr_in *local,\n\t\t\t\t\t       const pjsip_host_port *a_name,\n\t\t\t\t\t       unsigned async_cnt,\n\t\t\t\t\t       pjsip_tpfactory **p_factory);\n\n/**\n * Variant of #pjsip_tls_transport_start() that supports IPv6. To instantiate\n * IPv6 listener, set the address family of the \"local\" argument to IPv6\n * (the host and port part may be left unspecified if not desired, i.e. by\n * filling them with zeroes).\n *\n * @param endpt\t\tThe SIP endpoint.\n * @param opt\t\tOptional TLS settings.\n * @param local\t\tOptional local address to bind, or specify the\n *\t\t\taddress to bind the server socket to. Both IP\n *\t\t\tinterface address and port fields are optional.\n *\t\t\tIf IP interface address is not specified, socket\n *\t\t\twill be bound to any address. If port is not\n *\t\t\tspecified, socket will be bound to any port\n *\t\t\tselected by the operating system.\n * @param a_name\tOptional published address, which is the address to be\n *\t\t\tadvertised as the address of this SIP transport.\n *\t\t\tIf this argument is NULL, then the bound address\n *\t\t\twill be used as the published address.\n * @param async_cnt\tNumber of simultaneous asynchronous accept()\n *\t\t\toperations to be supported. It is recommended that\n *\t\t\tthe number here corresponds to the number of\n *\t\t\tprocessors in the system (or the number of SIP\n *\t\t\tworker threads).\n * @param p_factory\tOptional pointer to receive the instance of the\n *\t\t\tSIP TLS transport factory just created.\n *\n * @return\t\tPJ_SUCCESS when the transport has been successfully\n *\t\t\tstarted and registered to transport manager, or\n *\t\t\tthe appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_tls_transport_start2(pjsip_endpoint *endpt,\n \t\t\t\t\t        const pjsip_tls_setting *opt,\n\t\t\t\t\t        const pj_sockaddr *local,\n\t\t\t\t\t        const pjsip_host_port *a_name,\n\t\t\t\t\t        unsigned async_cnt,\n\t\t\t\t\t        pjsip_tpfactory **p_factory);\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJSIP_TRANSPORT_TLS_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_transport_udp.h",
    "content": "/* $Id: sip_transport_udp.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_TRANSPORT_UDP_H__\n#define __PJSIP_TRANSPORT_UDP_H__\n\n/**\n * @file sip_transport_udp.h\n * @brief SIP UDP Transport.\n */\n\n#include <pjsip/sip_transport.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_TRANSPORT_UDP UDP Transport\n * @ingroup PJSIP_TRANSPORT\n * @brief API to create and register UDP transport.\n * @{\n * The functions below are used to create UDP transport and register \n * the transport to the framework.\n */\n\n/**\n * Flag that can be specified when calling #pjsip_udp_transport_pause() or\n * #pjsip_udp_transport_restart().\n */\nenum\n{\n    /**\n     * This flag tells the transport to keep the existing/internal socket\n     * handle.\n     */\n    PJSIP_UDP_TRANSPORT_KEEP_SOCKET\t= 1,\n\n    /**\n     * This flag tells the transport to destroy the existing/internal socket\n     * handle. Naturally this flag and PJSIP_UDP_TRANSPORT_KEEP_SOCKET are \n     * mutually exclusive.\n     */\n    PJSIP_UDP_TRANSPORT_DESTROY_SOCKET\t= 2\n};\n\n\n/**\n * Start UDP transport.\n *\n * @param endpt\t\tThe SIP endpoint.\n * @param local\t\tOptional local address to bind. If this argument\n *\t\t\tis NULL, the UDP transport will be bound to arbitrary\n *\t\t\tUDP port.\n * @param a_name\tPublished address (only the host and port portion is \n *\t\t\tused). If this argument is NULL, then the bound address\n *\t\t\twill be used as the published address.\n * @param async_cnt\tNumber of simultaneous async operations.\n * @param p_transport\tPointer to receive the transport.\n *\n * @return\t\tPJ_SUCCESS when the transport has been successfully\n *\t\t\tstarted and registered to transport manager, or\n *\t\t\tthe appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_udp_transport_start(pjsip_endpoint *endpt,\n\t\t\t\t\t       const pj_sockaddr_in *local,\n\t\t\t\t\t       const pjsip_host_port *a_name,\n\t\t\t\t\t       unsigned async_cnt,\n\t\t\t\t\t       pjsip_transport **p_transport);\n\n/**\n * Start IPv6 UDP transport.\n */\nPJ_DECL(pj_status_t) pjsip_udp_transport_start6(pjsip_endpoint *endpt,\n\t\t\t\t\t\tconst pj_sockaddr_in6 *local,\n\t\t\t\t\t\tconst pjsip_host_port *a_name,\n\t\t\t\t\t\tunsigned async_cnt,\n\t\t\t\t\t\tpjsip_transport **p_transport);\n\n\n/**\n * Attach IPv4 UDP socket as a new transport and start the transport.\n *\n * @param endpt\t\tThe SIP endpoint.\n * @param sock\t\tUDP socket to use.\n * @param a_name\tPublished address (only the host and port portion is \n *\t\t\tused).\n * @param async_cnt\tNumber of simultaneous async operations.\n * @param p_transport\tPointer to receive the transport.\n *\n * @return\t\tPJ_SUCCESS when the transport has been successfully\n *\t\t\tstarted and registered to transport manager, or\n *\t\t\tthe appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_udp_transport_attach(pjsip_endpoint *endpt,\n\t\t\t\t\t\tpj_sock_t sock,\n\t\t\t\t\t\tconst pjsip_host_port *a_name,\n\t\t\t\t\t\tunsigned async_cnt,\n\t\t\t\t\t\tpjsip_transport **p_transport);\n\n\n/**\n * Attach IPv4 or IPv6 UDP socket as a new transport and start the transport.\n *\n * @param endpt\t\tThe SIP endpoint.\n * @param type\t\tTransport type, which is PJSIP_TRANSPORT_UDP for IPv4\n *\t\t\tor PJSIP_TRANSPORT_UDP6 for IPv6 socket.\n * @param sock\t\tUDP socket to use.\n * @param a_name\tPublished address (only the host and port portion is \n *\t\t\tused).\n * @param async_cnt\tNumber of simultaneous async operations.\n * @param p_transport\tPointer to receive the transport.\n *\n * @return\t\tPJ_SUCCESS when the transport has been successfully\n *\t\t\tstarted and registered to transport manager, or\n *\t\t\tthe appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_udp_transport_attach2(pjsip_endpoint *endpt,\n\t\t\t\t\t\t pjsip_transport_type_e type,\n\t\t\t\t\t\t pj_sock_t sock,\n\t\t\t\t\t\t const pjsip_host_port *a_name,\n\t\t\t\t\t\t unsigned async_cnt,\n\t\t\t\t\t\t pjsip_transport **p_transport);\n\n/**\n * Retrieve the internal socket handle used by the UDP transport. Note\n * that this socket normally is registered to ioqueue, so if application\n * wants to make use of this socket, it should temporarily pause the\n * transport.\n *\n * @param transport\tThe UDP transport.\n *\n * @return\t\tThe socket handle, or PJ_INVALID_SOCKET if no socket\n *\t\t\tis currently being used (for example, when transport\n *\t\t\tis being paused).\n */\nPJ_DECL(pj_sock_t) pjsip_udp_transport_get_socket(pjsip_transport *transport);\n\n\n/**\n * Temporarily pause or shutdown the transport. When transport is being\n * paused, it cannot be used by the SIP stack to send or receive SIP\n * messages.\n *\n * Two types of operations are supported by this function:\n *  - to temporarily make this transport unavailable for SIP uses, but\n *    otherwise keep the socket handle intact. Application then can\n *    retrieve the socket handle with #pjsip_udp_transport_get_socket()\n *    and use it to send/receive application data (for example, STUN\n *    messages). In this case, application should specify\n *    PJSIP_UDP_TRANSPORT_KEEP_SOCKET when calling this function, and\n *    also to specify this flag when calling #pjsip_udp_transport_restart()\n *    later.\n *  - to temporarily shutdown the transport, including closing down\n *    the internal socket handle. This is useful for example to\n *    temporarily suspend the application for an indefinite period. In\n *    this case, application should specify PJSIP_UDP_TRANSPORT_DESTROY_SOCKET\n *    flag when calling this function, and specify a new socket when\n *    calling #pjsip_udp_transport_restart().\n *\n * @param transport\tThe UDP transport.\n * @param option\tPause option.\n *\n * @return\t\tPJ_SUCCESS if transport is paused successfully,\n *\t\t\tor the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_udp_transport_pause(pjsip_transport *transport,\n\t\t\t\t\t       unsigned option);\n\n/**\n * Restart the transport. Several operations are supported by this function:\n *  - if transport was made temporarily unavailable to SIP stack with\n *    pjsip_udp_transport_pause() and PJSIP_UDP_TRANSPORT_KEEP_SOCKET,\n *    application can make the transport available to the SIP stack\n *    again, by specifying PJSIP_UDP_TRANSPORT_KEEP_SOCKET flag here.\n *  - if application wants to replace the internal socket with a new\n *    socket, it must specify PJSIP_UDP_TRANSPORT_DESTROY_SOCKET when\n *    calling this function, so that the internal socket will be destroyed\n *    if it hasn't been closed. In this case, application has two choices\n *    on how to create the new socket: 1) to let the transport create\n *    the new socket, in this case the \\a sock option should be set\n *    to \\a PJ_INVALID_SOCKET and optionally the \\a local parameter can be\n *    filled with the desired address and port where the new socket \n *    should be bound to, or 2) to specify its own socket to be used\n *    by this transport, by specifying a valid socket in \\a sock argument\n *    and set the \\a local argument to NULL. In both cases, application\n *    may specify the published address of the socket in \\a a_name\n *    argument.\n *\n * @param transport\tThe UDP transport.\n * @param option\tRestart option.\n * @param sock\t\tOptional socket to be used by the transport.\n * @param local\t\tThe address where the socket should be bound to.\n *\t\t\tIf this argument is NULL, socket will be bound\n *\t\t\tto any available port.\n * @param a_name\tOptionally specify the published address for\n *\t\t\tthis transport. If the socket is not replaced\n *\t\t\t(PJSIP_UDP_TRANSPORT_KEEP_SOCKET flag is\n *\t\t\tspecified), then if this argument is NULL, the\n *\t\t\tprevious value will be used. If the socket is\n *\t\t\treplaced and this argument is NULL, the bound\n *\t\t\taddress will be used as the published address \n *\t\t\tof the transport.\n *\n * @return\t\tPJ_SUCCESS if transport can be restarted, or\n *\t\t\tthe appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_udp_transport_restart(pjsip_transport *transport,\n\t\t\t\t\t         unsigned option,\n\t\t\t\t\t\t pj_sock_t sock,\n\t\t\t\t\t\t const pj_sockaddr_in *local,\n\t\t\t\t\t\t const pjsip_host_port *a_name);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJSIP_TRANSPORT_UDP_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_types.h",
    "content": "/* $Id: sip_types.h 4262 2012-09-20 06:00:23Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_TYPES_H__\n#define __PJSIP_SIP_TYPES_H__\n\n\n/*\n * My note: Doxygen PJSIP and PJSIP_CORE group is declared in\n *          sip_config.h\n */\n\n/**\n * @file sip_types.h\n * @brief Basic PJSIP types.\n */\n\n#include <pjsip/sip_config.h>\n#include <pj/types.h>\n\n/**\n * @addtogroup PJSIP_BASE\n */\n\n/* @defgroup PJSIP_TYPES Basic Data Types\n * @ingroup PJSIP_BASE\n * @brief Basic data types.\n * @{\n */\n\n\n\n/**\n * Forward declaration for SIP transport.\n */\ntypedef struct pjsip_transport pjsip_transport;\n\n/**\n * Forward declaration for transport manager.\n */\ntypedef struct pjsip_tpmgr pjsip_tpmgr;\n\n/**\n * Transport types.\n */\ntypedef enum pjsip_transport_type_e\n{\n    /** Unspecified. */\n    PJSIP_TRANSPORT_UNSPECIFIED,\n\n    /** UDP. */\n    PJSIP_TRANSPORT_UDP,\n\n    /** TCP. */\n    PJSIP_TRANSPORT_TCP,\n\n    /** TLS. */\n    PJSIP_TRANSPORT_TLS,\n\n    /** SCTP. */\n    PJSIP_TRANSPORT_SCTP,\n\n    /** Loopback (stream, reliable) */\n    PJSIP_TRANSPORT_LOOP,\n\n    /** Loopback (datagram, unreliable) */\n    PJSIP_TRANSPORT_LOOP_DGRAM,\n\n    /** Start of user defined transport */\n    PJSIP_TRANSPORT_START_OTHER,\n\n    /** Start of IPv6 transports */\n    PJSIP_TRANSPORT_IPV6    = 128,\n\n    /** UDP over IPv6 */\n    PJSIP_TRANSPORT_UDP6 = PJSIP_TRANSPORT_UDP + PJSIP_TRANSPORT_IPV6,\n\n    /** TCP over IPv6 */\n    PJSIP_TRANSPORT_TCP6 = PJSIP_TRANSPORT_TCP + PJSIP_TRANSPORT_IPV6,\n\n    /** TLS over IPv6 */\n    PJSIP_TRANSPORT_TLS6 = PJSIP_TRANSPORT_TLS + PJSIP_TRANSPORT_IPV6\n\n} pjsip_transport_type_e;\n\n\n/**\n * Forward declaration for endpoint (sip_endpoint.h).\n */\ntypedef struct pjsip_endpoint pjsip_endpoint;\n\n/**\n * Forward declaration for transactions (sip_transaction.h).\n */\ntypedef struct pjsip_transaction pjsip_transaction;\n\n/**\n * Forward declaration for events (sip_event.h).\n */\ntypedef struct pjsip_event pjsip_event;\n\n/**\n * Forward declaration for transmit data/buffer (sip_transport.h).\n */\ntypedef struct pjsip_tx_data pjsip_tx_data;\n\n/**\n * Forward declaration for receive data/buffer (sip_transport.h).\n */\ntypedef struct pjsip_rx_data pjsip_rx_data;\n\n/**\n * Forward declaration for message (sip_msg.h).\n */\ntypedef struct pjsip_msg pjsip_msg;\n\n/**\n * Forward declaration for message body (sip_msg.h).\n */\ntypedef struct pjsip_msg_body pjsip_msg_body;\n\n/**\n * Forward declaration for header field (sip_msg.h).\n */\ntypedef struct pjsip_hdr pjsip_hdr;\n\n/**\n * Forward declaration for URI (sip_uri.h).\n */\ntypedef struct pjsip_uri pjsip_uri;\n\n/**\n * Forward declaration for SIP method (sip_msg.h)\n */\ntypedef struct pjsip_method pjsip_method;\n\n/**\n * Opaque data type for the resolver engine (sip_resolve.h).\n */\ntypedef struct pjsip_resolver_t pjsip_resolver_t;\n\n/**\n * Forward declaration for credential.\n */\ntypedef struct pjsip_cred_info pjsip_cred_info;\n\n\n/**\n * Forward declaration for module (sip_module.h).\n */\ntypedef struct pjsip_module pjsip_module;\n\n\n/** \n * Forward declaration for user agent type (sip_ua_layer.h). \n */\ntypedef pjsip_module pjsip_user_agent;\n\n/**\n * Forward declaration for dialog (sip_dialog.h).\n */\ntypedef struct pjsip_dialog pjsip_dialog;\n\n/**\n * Transaction role.\n */\ntypedef enum pjsip_role_e\n{\n    PJSIP_ROLE_UAC,\t/**< Role is UAC. */\n    PJSIP_ROLE_UAS,\t/**< Role is UAS. */\n\n    /* Alias: */\n\n    PJSIP_UAC_ROLE = PJSIP_ROLE_UAC,\t/**< Role is UAC. */\n    PJSIP_UAS_ROLE = PJSIP_ROLE_UAS\t/**< Role is UAS. */\n\n} pjsip_role_e;\n\n\n/**\n * General purpose buffer.\n */\ntypedef struct pjsip_buffer\n{\n    /** The start of the buffer. */\n    char *start;\n\n    /** Pointer to current end of the buffer, which also indicates the position\n        of subsequent buffer write.\n     */\n    char *cur;\n\n    /** The absolute end of the buffer. */\n    char *end;\n\n} pjsip_buffer;\n\n\n/**\n * General host:port pair, used for example as Via sent-by.\n */\ntypedef struct pjsip_host_port\n{\n    pj_str_t host;\t/**< Host part or IP address. */\n    int\t     port;\t/**< Port number. */\n} pjsip_host_port;\n\n/**\n * Host information.\n */\ntypedef struct pjsip_host_info\n{\n    unsigned\t\t    flag;   /**< Flags of pjsip_transport_flags_e. */\n    pjsip_transport_type_e  type;   /**< Transport type. */\n    pjsip_host_port\t    addr;   /**< Address information. */\n} pjsip_host_info;\n\n\n/**\n * Convert exception ID into pj_status_t status.\n *\n * @param exception_id  Exception Id.\n *\n * @return              Error code for the specified exception Id.\n */\nPJ_DECL(pj_status_t) pjsip_exception_to_status(int exception_id);\n\n/**\n * Return standard pj_status_t status from current exception.\n */\n#define PJSIP_RETURN_EXCEPTION() pjsip_exception_to_status(PJ_GET_EXCEPTION())\n\n/**\n * Attributes to inform that the function may throw exceptions.\n */\n#define PJSIP_THROW_SPEC(list)\n\n\n/**\n * @}\n */\n\n#endif\t/* __PJSIP_SIP_TYPES_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_ua_layer.h",
    "content": "/* $Id: sip_ua_layer.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_UA_LAYER_H__\n#define __PJSIP_SIP_UA_LAYER_H__\n\n/**\n * @file sip_ua_layer.h\n * @brief SIP User Agent Layer Module\n */\n#include <pjsip/sip_types.h>\n\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_UA Base User Agent Layer/Common Dialog Layer\n * @brief Dialog management.\n *\n * This module provides basic dialog management, which is used by higher\n * layer dialog usages such as INVITE sessions and SIP Event Subscription\n * framework (RFC 3265). Application should link  with <b>pjsip-core</b> \n * library to use this base UA layer. The base UA layer module is initialized\n * with #pjsip_ua_init_module().\n */\n\n/**\n * @defgroup PJSUA_UA SIP User Agent Module\n * @ingroup PJSIP_UA\n * @brief Provides dialog management.\n * @{\n *\n * Application MUST initialize the user agent layer module by calling\n * #pjsip_ua_init_module() before using any of the dialog API, and link\n * the application with with <b>pjsip-core</b> library.\n */\n\n/** User agent initialization parameter. */\ntypedef struct pjsip_ua_init_param\n{\n    /** Callback to be called when the UA layer detects that outgoing\n     *  dialog has forked.\n     */\n    pjsip_dialog* (*on_dlg_forked)(pjsip_dialog *first_set, pjsip_rx_data *res);\n} pjsip_ua_init_param;\n\n/**\n * Initialize user agent layer and register it to the specified endpoint.\n *\n * @param endpt\t\tThe endpoint where the user agent will be\n *\t\t\tregistered.\n * @param prm\t\tUA initialization parameter.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_ua_init_module(pjsip_endpoint *endpt,\n\t\t\t\t\t  const pjsip_ua_init_param *prm);\n\n/**\n * Get the instance of the user agent.\n *\n * @return\t\tThe user agent module instance.\n */\nPJ_DECL(pjsip_user_agent*) pjsip_ua_instance(void);\n\n\n/**\n * Retrieve the current number of dialog-set currently registered\n * in the hash table. Note that dialog-set is different than dialog\n * when the request forks. In this case, all dialogs created from\n * the original request will belong to the same dialog set. When\n * no forking occurs, the number of dialog sets will be equal to\n * the number of dialogs.\n *\n * @return\t    Number of dialog sets.\n */\nPJ_DECL(pj_uint32_t) pjsip_ua_get_dlg_set_count(void);\n\n\n/**\n * Find a dialog with the specified Call-ID and tags properties. This\n * function may optionally lock the matching dialog instance before\n * returning it back to the caller.\n *\n * @param call_id\tThe call ID to be matched.\n * @param local_tag\tThe local tag to be matched.\n * @param remote_tag\tThe remote tag to be matched.\n * @param lock_dialog\tIf non-zero, instruct the function to lock the \n *\t\t\tmatching dialog with #pjsip_dlg_inc_lock(). \n *\t\t\tApplication is responsible to release the dialog's\n *\t\t\tlock after it has finished manipulating the dialog,\n *\t\t\tby calling #pjsip_dlg_dec_lock().\n *\n * @return\t\tThe matching dialog instance, or NULL if no matching\n *\t\t\tdialog is found.\n */\nPJ_DECL(pjsip_dialog*) pjsip_ua_find_dialog(const pj_str_t *call_id,\n\t\t\t\t\t    const pj_str_t *local_tag,\n\t\t\t\t\t    const pj_str_t *remote_tag,\n\t\t\t\t\t    pj_bool_t lock_dialog);\n\n/**\n * Destroy the user agent layer.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_ua_destroy(void);\n\n/**\n * Dump user agent contents (e.g. all dialogs).\n *\n * @param detail\tIf non-zero, list of dialogs will be printed.\n */\nPJ_DECL(void) pjsip_ua_dump(pj_bool_t detail);\n\n/**\n * Get the endpoint instance of a user agent module.\n *\n * @param ua\t\tThe user agent instance.\n *\n * @return\t\tThe endpoint instance where the user agent is\n *\t\t\tregistered.\n */\nPJ_DECL(pjsip_endpoint*) pjsip_ua_get_endpt(pjsip_user_agent *ua);\n\n\n/**\n * @}\n */\n\n\n/*\n * Internal (called by sip_dialog.c).\n */\n\nPJ_DECL(pj_status_t) pjsip_ua_register_dlg( pjsip_user_agent *ua,\n\t\t\t\t\t    pjsip_dialog *dlg );\nPJ_DECL(pj_status_t) pjsip_ua_unregister_dlg(pjsip_user_agent *ua,\n\t\t\t\t\t     pjsip_dialog *dlg );\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJSIP_SIP_UA_LAYER_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_uri.h",
    "content": "/* $Id: sip_uri.h 4370 2013-02-26 05:30:00Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_URI_H__\n#define __PJSIP_SIP_URI_H__\n\n/**\n * @file sip_uri.h\n * @brief SIP URL Structures and Manipulations\n */\n\n#include <pjsip/sip_types.h>\n#include <pjsip/sip_config.h>\n#include <pj/list.h>\n#include <pjlib-util/scanner.h>\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJSIP_URI URI\n * @brief URI types and manipulations.\n * @ingroup PJSIP_MSG\n */\n\n/**\n * @addtogroup PJSIP_URI_PARAM URI Parameter Container\n * @ingroup PJSIP_URI\n * @brief Generic parameter elements container.\n * @{\n */\n\n/**\n * Generic parameter, normally used in other_param or header_param.\n */\ntypedef struct pjsip_param\n{\n    PJ_DECL_LIST_MEMBER(struct pjsip_param);\t/**< Generic list member.   */\n    pj_str_t\t    name;\t\t\t/**< Param/header name.\t    */\n    pj_str_t\t    value;\t\t\t/**< Param/header value.    */\n} pjsip_param;\n\n\n/**\n * Find the specified parameter name in the list. The name will be compared\n * in case-insensitive comparison.\n *\n * @param param_list\tList of parameters to find.\n * @param name\t\tParameter/header name to find.\n *\n * @return\t\tThe parameter if found, or NULL.\n */\nPJ_DECL(pjsip_param*) pjsip_param_find( const pjsip_param *param_list,\n\t\t\t\t\tconst pj_str_t *name );\n\n\n/**\n * Alias for pjsip_param_find()\n */\nPJ_INLINE(pjsip_param*) pjsip_param_cfind(const pjsip_param *param_list,\n\t\t\t\t\t  const pj_str_t *name)\n{\n    return pjsip_param_find(param_list, name);\n}\n\n/**\n * Compare two parameter lists.\n *\n * @param param_list1\tFirst parameter list.\n * @param param_list2\tSecond parameter list.\n * @param ig_nf\t\tIf set to 1, do not compare parameters that only\n * \t\t\tappear in one of the list.\n *\n * @return\t\tZero if the parameter list are equal, non-zero\n * \t\t\totherwise.\n */\nPJ_DECL(int) pjsip_param_cmp(const pjsip_param *param_list1,\n\t\t\t     const pjsip_param *param_list2,\n\t\t\t     pj_bool_t ig_nf);\n\n/**\n * Duplicate the parameters.\n *\n * @param pool\t\tPool to allocate memory from.\n * @param dst_list\tDestination list.\n * @param src_list\tSource list.\n */\nPJ_DECL(void) pjsip_param_clone(pj_pool_t *pool, pjsip_param *dst_list,\n\t\t\t\tconst pjsip_param *src_list);\n\n/**\n * Duplicate the parameters.\n *\n * @param pool\t\tPool to allocate memory from.\n * @param dst_list\tDestination list.\n * @param src_list\tSource list.\n */\nPJ_DECL(void) pjsip_param_shallow_clone(pj_pool_t *pool, \n\t\t\t\t\tpjsip_param *dst_list,\n\t\t\t\t\tconst pjsip_param *src_list);\n\n/**\n * Print parameters.\n *\n * @param param_list\tThe parameter list.\n * @param buf\t\tBuffer.\n * @param size\t\tSize of buffer.\n * @param pname_unres\tSpecification of allowed characters in pname.\n * @param pvalue_unres\tSpecification of allowed characters in pvalue.\n * @param sep\t\tSeparator character (either ';', ',', or '?').\n *\t\t\tWhen separator is set to '?', this function will\n *\t\t\tautomatically adjust the separator character to\n *\t\t\t'&' after the first parameter is printed.\n *\n * @return\t\tThe number of bytes printed, or -1 on errr.\n */\nPJ_DECL(pj_ssize_t) pjsip_param_print_on(const pjsip_param *param_list,\n\t\t\t\t\t char *buf, pj_size_t size,\n\t\t\t\t\t const pj_cis_t *pname_unres,\n\t\t\t\t\t const pj_cis_t *pvalue_unres,\n\t\t\t\t\t int sep);\n\n/**\n * @}\n */\n\n/**\n * @defgroup PJSIP_URI_GENERIC Generic URI\n * @ingroup PJSIP_URI\n * @brief Generic representation for all types of URI.\n * @{\n */\n\n/**\n * URI context.\n */\ntypedef enum pjsip_uri_context_e\n{\n    PJSIP_URI_IN_REQ_URI,\t/**< The URI is in Request URI. */\n    PJSIP_URI_IN_FROMTO_HDR,\t/**< The URI is in From/To header. */\n    PJSIP_URI_IN_CONTACT_HDR,\t/**< The URI is in Contact header. */\n    PJSIP_URI_IN_ROUTING_HDR,\t/**< The URI is in Route/Record-Route header. */\n    PJSIP_URI_IN_OTHER\t\t/**< Other context (web page, business card, etc.) */\n} pjsip_uri_context_e;\n\n/**\n * URI 'virtual' function table.\n * All types of URI in this library (such as sip:, sips:, tel:, and name-addr) \n * will have pointer to this table as their first struct member. This table\n * provides polimorphic behaviour to the URI.\n */\ntypedef struct pjsip_uri_vptr\n{\n    /** \n     * Get URI scheme. \n     * @param uri the URI (self).\n     * @return the URI scheme.\n     */\n    const pj_str_t* (*p_get_scheme)(const void *uri);\n\n    /**\n     * Get the URI object contained by this URI, or the URI itself if\n     * it doesn't contain another URI.\n     * @param uri the URI (self).\n     */\n    void* (*p_get_uri)(void *uri);\n\n    /**\n     * Print URI components to the buffer, following the rule of which \n     * components are allowed for the context.\n     * @param context the context where the URI will be placed.\n     * @param uri the URI (self).\n     * @param buf the buffer.\n     * @param size the size of the buffer.\n     * @return the length printed.\n     */\n    pj_ssize_t (*p_print)(pjsip_uri_context_e context,\n\t\t\t  const void *uri, \n\t\t          char *buf, pj_size_t size);\n\n    /** \n     * Compare two URIs according to the context.\n     * @param context the context.\n     * @param uri1 the first URI (self).\n     * @param uri2 the second URI.\n     * @return PJ_SUCCESS if equal, or otherwise the error status which\n     *\t\t    should point to the mismatch part.\n     */\n    pj_status_t\t(*p_compare)(pjsip_uri_context_e context, \n\t\t\t     const void *uri1, const void *uri2);\n\n    /** \n     * Clone URI. \n     * @param pool the pool.\n     * @param the URI to clone (self).\n     * @return new URI.\n     */\n    void *(*p_clone)(pj_pool_t *pool, const void *uri);\n\n} pjsip_uri_vptr;\n\n\n/**\n * The declaration of 'base class' for all URI scheme.\n */\nstruct pjsip_uri\n{\n    /** All URIs must have URI virtual function table as their first member. */\n    pjsip_uri_vptr *vptr;\n};\n\n/**\n * This macro checks that the URL is a \"sip:\" URL.\n * @param url The URL (pointer to)\n * @return non-zero if TRUE.\n */\n#define PJSIP_URI_SCHEME_IS_SIP(url)\t\\\n    (pj_stricmp2(pjsip_uri_get_scheme(url), \"sip\")==0)\n\n/**\n * This macro checks that the URL is a \"sips:\" URL (not SIP).\n * @param url The URL (pointer to)\n * @return non-zero if TRUE.\n */\n#define PJSIP_URI_SCHEME_IS_SIPS(url)\t\\\n    (pj_stricmp2(pjsip_uri_get_scheme(url), \"sips\")==0)\n\n/**\n * This macro checks that the URL is a \"tel:\" URL.\n * @param url The URL (pointer to)\n * @return non-zero if TRUE.\n */\n#define PJSIP_URI_SCHEME_IS_TEL(url)\t\\\n    (pj_stricmp2(pjsip_uri_get_scheme(url), \"tel\")==0)\n\n\n/**\n * Generic function to get the URI scheme.\n * @param uri\t    the URI object.\n * @return\t    the URI scheme.\n */\nPJ_INLINE(const pj_str_t*) pjsip_uri_get_scheme(const void *uri)\n{\n    return (*((pjsip_uri*)uri)->vptr->p_get_scheme)(uri);\n}\n\n/**\n * Generic function to get the URI object contained by this URI, or the URI \n * itself if it doesn't contain another URI.\n *\n * @param uri\t    the URI.\n * @return\t    the URI.\n */\nPJ_INLINE(void*) pjsip_uri_get_uri(const void *uri)\n{\n    return (*((pjsip_uri*)uri)->vptr->p_get_uri)((void*)uri);\n}\n\n/**\n * Generic function to compare two URIs.\n *\n * @param context   Comparison context.\n * @param uri1\t    The first URI.\n * @param uri2\t    The second URI.\n * @return\t    PJ_SUCCESS if equal, or otherwise the error status which\n *\t\t    should point to the mismatch part.\n */\nPJ_INLINE(pj_status_t) pjsip_uri_cmp(pjsip_uri_context_e context, \n\t\t\t\t     const void *uri1, const void *uri2)\n{\n    return (*((const pjsip_uri*)uri1)->vptr->p_compare)(context, uri1, uri2);\n}\n\n/**\n * Generic function to print an URI object.\n *\n * @param context   Print context.\n * @param uri\t    The URI to print.\n * @param buf\t    The buffer.\n * @param size\t    Size of the buffer.\n * @return\t    Length printed.\n */\nPJ_INLINE(int) pjsip_uri_print(pjsip_uri_context_e context,\n\t\t\t       const void *uri,\n\t\t\t       char *buf, pj_size_t size)\n{\n    return (int)(*((const pjsip_uri*)uri)->vptr->p_print)(context, uri, \n\t\t\t\t\t\t\t  buf, size);\n}\n\n/**\n * Generic function to clone an URI object.\n *\n * @param pool\t    Pool.\n * @param uri\t    URI to clone.\n * @return\t    New URI.\n */\nPJ_INLINE(void*) pjsip_uri_clone( pj_pool_t *pool, const void *uri )\n{\n    return (*((const pjsip_uri*)uri)->vptr->p_clone)(pool, uri);\n}\n\n\n\n/**\n * @}\n */\n\n/**\n * @defgroup PJSIP_SIP_URI SIP URI Scheme and Name address\n * @ingroup PJSIP_URI\n * @brief SIP URL structure (\"sip:\" and \"sips:\")\n * @{\n */\n\n\n/**\n * SIP and SIPS URL scheme.\n */\ntypedef struct pjsip_sip_uri\n{\n    pjsip_uri_vptr *vptr;\t\t/**< Pointer to virtual function table.*/\n    pj_str_t\t    user;\t\t/**< Optional user part. */\n    pj_str_t\t    passwd;\t\t/**< Optional password part. */\n    pj_str_t\t    host;\t\t/**< Host part, always exists. */\n    int\t\t    port;\t\t/**< Optional port number, or zero. */\n    pj_str_t\t    user_param;\t\t/**< Optional user parameter */\n    pj_str_t\t    method_param;\t/**< Optional method parameter. */\n    pj_str_t\t    transport_param;\t/**< Optional transport parameter. */\n    int\t\t    ttl_param;\t\t/**< Optional TTL param, or -1. */\n    int\t\t    lr_param;\t\t/**< Optional loose routing param, or zero */\n    pj_str_t\t    maddr_param;\t/**< Optional maddr param */\n    pjsip_param\t    other_param;\t/**< Other parameters grouped together. */\n    pjsip_param\t    header_param;\t/**< Optional header parameter. */\n} pjsip_sip_uri;\n\n\n/**\n * SIP name-addr, which typically appear in From, To, and Contact header.\n * The SIP name-addr contains a generic URI and a display name.\n */\ntypedef struct pjsip_name_addr\n{\n    /** Pointer to virtual function table. */\n    pjsip_uri_vptr  *vptr;\n\n    /** Optional display name. */\n    pj_str_t\t     display;\n\n    /** URI part. */\n    pjsip_uri\t    *uri;\n\n} pjsip_name_addr;\n\n\n/**\n * Create new SIP URL and initialize all fields with zero or NULL.\n * @param pool\t    The pool.\n * @param secure    Flag to indicate whether secure transport should be used.\n * @return SIP URL.\n */\nPJ_DECL(pjsip_sip_uri*) pjsip_sip_uri_create( pj_pool_t *pool, \n\t\t\t\t\t      pj_bool_t secure );\n\n/**\n * Change the SIP URI scheme to sip or sips based on the secure flag.\n * This would not change anything except the scheme.\n * @param uri\t    The URI\n * @param secure    Non-zero if sips is wanted.\n */\nPJ_DECL(void) pjsip_sip_uri_set_secure( pjsip_sip_uri *uri, \n\t\t\t\t        pj_bool_t secure );\n\n/**\n * Initialize SIP URL (all fields are set to NULL or zero).\n * @param url\t    The URL.\n * @param secure    Create sips URI?\n */\nPJ_DECL(void)  pjsip_sip_uri_init(pjsip_sip_uri *url, pj_bool_t secure);\n\n/**\n * Perform full assignment to the SIP URL.\n * @param pool\t    The pool.\n * @param url\t    Destination URL.\n * @param rhs\t    The source URL.\n */\nPJ_DECL(void)  pjsip_sip_uri_assign(pj_pool_t *pool, pjsip_sip_uri *url, \n\t\t\t\t    const pjsip_sip_uri *rhs);\n\n/**\n * Create new instance of name address and initialize all fields with zero or\n * NULL.\n * @param pool\t    The pool.\n * @return\t    New SIP name address.\n */\nPJ_DECL(pjsip_name_addr*) pjsip_name_addr_create(pj_pool_t *pool);\n\n/**\n * Initialize with default value.\n * @param name_addr The name address.\n */\nPJ_DECL(void) pjsip_name_addr_init(pjsip_name_addr *name_addr);\n\n/**\n * Perform full assignment to the name address.\n * @param pool\t    The pool.\n * @param addr\t    The destination name address.\n * @param rhs\t    The source name address.\n */\nPJ_DECL(void)  pjsip_name_addr_assign(pj_pool_t *pool, \n\t\t\t\t      pjsip_name_addr *addr, \n\t\t\t\t      const pjsip_name_addr *rhs);\n\n/**\n * @}\n */\n\n/**\n * @defgroup PJSIP_OTHER_URI Other URI schemes\n * @ingroup PJSIP_URI\n * @brief Container for non SIP/tel URI scheme (e.g. \"http:\", \"mailto:\")\n * @{\n */\n\n/**\n * Generic URI container for non SIP/tel URI scheme.\n */\ntypedef struct pjsip_other_uri \n{\n    pjsip_uri_vptr *vptr;\t/**< Pointer to virtual function table.\t*/\n    pj_str_t scheme;\t\t/**< The URI scheme (e.g. \"mailto\")\t*/\n    pj_str_t content;\t\t/**< The whole URI content\t\t*/\n} pjsip_other_uri;\n\n\n/**\n * Create a generic URI object.\n *\n * @param pool\t    The pool to allocate memory from.\n *\n * @return\t    The URI instance.\n */\nPJ_DECL(pjsip_other_uri*) pjsip_other_uri_create(pj_pool_t *pool);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_URL_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip/sip_util.h",
    "content": "/* $Id: sip_util.h 4347 2013-02-13 10:19:25Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_MISC_H__\n#define __PJSIP_SIP_MISC_H__\n\n#include <pjsip/sip_msg.h>\n#include <pjsip/sip_transport.h>\n#include <pjsip/sip_resolve.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_ENDPT_TARGET_URI Target URI Management\n * @ingroup PJSIP_CORE_CORE\n * @brief Management of target URI's in case of redirection\n * @{\n * This module provides utility functions to manage target set for UAC.\n * The target set is provided as pjsip_target_set structure. Initially,\n * the target set for UAC contains only one target, that is the target of\n * the initial request. When 3xx/redirection class response is received, \n * the UAC can use the functionality of this module to add the URI's listed\n * in the Contact header(s) in the response to the target set, and retry \n * sending the request to the next destination/target. The UAC may retry \n * this sequentially until one of the target answers with succesful/2xx \n * response, or one target returns global error/6xx response, or all targets\n * are exhausted.\n *\n * This module is currently used by the \\ref PJSIP_INV.\n */\n\n/**\n * This structure describes a target, which can be chained together to form\n * a target set. Each target contains an URI, priority (as q-value), and \n * the last status code and reason phrase received from the target, if the \n * target has been contacted. If the target has not been contacted, the \n * status code field will be zero.\n */\ntypedef struct pjsip_target\n{\n    PJ_DECL_LIST_MEMBER(struct pjsip_target);/**< Standard list element */\n    pjsip_uri\t       *uri;\t/**< The target URI\t\t    */\n    int\t\t\tq1000;\t/**< q-value multiplied by 1000\t    */\n    pjsip_status_code\tcode;\t/**< Last status code received\t    */\n    pj_str_t\t\treason;\t/**< Last reason phrase received    */\n} pjsip_target;\n\n\n/**\n * This describes a target set. A target set contains a linked-list of\n * pjsip_target.\n */\ntypedef struct pjsip_target_set\n{\n    pjsip_target     head;\t    /**< Target linked-list head    */\n    pjsip_target    *current;\t    /**< Current target.\t    */\n} pjsip_target_set;\n\n\n/**\n * These enumerations specify the action to be performed to a redirect\n * response.\n */\ntypedef enum pjsip_redirect_op\n{\n    /**\n     * Reject the redirection to the current target. The UAC will\n     * select the next target from the target set if exists.\n     */\n    PJSIP_REDIRECT_REJECT,\n\n    /**\n     * Accept the redirection to the current target. The INVITE request\n     * will be resent to the current target.\n     */\n    PJSIP_REDIRECT_ACCEPT,\n\n    /**\n     * Accept the redirection to the current target and replace the To\n     * header in the INVITE request with the current target. The INVITE\n     * request will be resent to the current target.\n     */\n    PJSIP_REDIRECT_ACCEPT_REPLACE,\n\n    /**\n     * Defer the redirection decision, for example to request permission\n     * from the end user.\n     */\n    PJSIP_REDIRECT_PENDING,\n\n    /**\n     * Stop the whole redirection process altogether. This will cause\n     * the invite session to be disconnected.\n     */\n    PJSIP_REDIRECT_STOP\n\n} pjsip_redirect_op;\n\n\n/**\n * Initialize target set. This will empty the list of targets in the\n * target set.\n *\n * @param tset\t    The target set.\n */\nPJ_INLINE(void) pjsip_target_set_init(pjsip_target_set *tset)\n{\n    pj_list_init(&tset->head);\n    tset->current = NULL;\n}\n\n\n/**\n * Add an URI to the target set, if the URI is not already in the target set.\n * The URI comparison rule of pjsip_uri_cmp() will be used to determine the\n * equality of this URI compared to existing URI's in the target set. The\n * URI will be cloned using the specified memory pool before it is added to\n * the list.\n *\n * The first URI added to the target set will also be made current target\n * by this function.\n *\n * @param tset\t    The target set.\n * @param pool\t    The memory pool to be used to duplicate the URI.\n * @param uri\t    The URI to be checked and added.\n * @param q1000\t    The q-value multiplied by 1000.\n *\n * @return\t    PJ_SUCCESS if the URI was added to the target set,\n *\t\t    or PJ_EEXISTS if the URI already exists in the target\n *\t\t    set, or other error codes.\n */\nPJ_DECL(pj_status_t) pjsip_target_set_add_uri(pjsip_target_set *tset,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      const pjsip_uri *uri,\n\t\t\t\t\t      int q1000);\n\n/**\n * Extract URI's in the Contact headers of the specified (response) message\n * and add them to the target set. This function will also check if the \n * URI's already exist in the target set before adding them to the list.\n *\n * @param tset\t    The target set.\n * @param pool\t    The memory pool to be used to duplicate the URI's.\n * @param msg\t    SIP message from which the Contact headers will be\n *\t\t    scanned and the URI's to be extracted, checked, and\n *\t\t    added to the target set.\n *\n * @return\t    PJ_SUCCESS if at least one URI was added to the \n *\t\t    target set, or PJ_EEXISTS if all URI's in the message \n *\t\t    already exists in the target set or if the message\n *\t\t    doesn't contain usable Contact headers, or other error\n *\t\t    codes.\n */\nPJ_DECL(pj_status_t) pjsip_target_set_add_from_msg(pjsip_target_set *tset,\n\t\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t\t   const pjsip_msg *msg);\n\n/**\n * Get the next target to be retried. This function will scan the target set\n * for target which hasn't been tried, and return one target with the\n * highest q-value, if such target exists. This function will return NULL\n * if there is one target with 2xx or 6xx code or if all targets have been\n * tried.\n *\n * @param tset\t    The target set.\n *\n * @return\t    The next target to be tried, or NULL if all targets have\n *\t\t    been tried or at least one target returns 2xx or 6xx\n *\t\t    response.\n */\nPJ_DECL(pjsip_target*) \npjsip_target_set_get_next(const pjsip_target_set *tset);\n\n\n/**\n * Set the specified target as the current target in the target set. The\n * current target may be used by application to keep track on which target\n * is currently being operated on.\n *\n * @param tset\t    The target set.\n * @param target    The target to be set as current target.\n *\n * @return\t    PJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_target_set_set_current(pjsip_target_set *tset,\n\t\t\t\t\t\t  pjsip_target *target);\n\n\n/**\n * Set the status code and reason phrase of the specified target.\n *\n * @param target    The target.\n * @param pool\t    The memory pool to be used to duplicate the reason phrase.\n * @param code\t    The SIP status code to be set to the target.\n * @param reason    The reason phrase  to be set to the target.\n *\n * @return\t    PJ_SUCCESS on successful operation or the appropriate\n *\t\t    error code.\n */\nPJ_DECL(pj_status_t) pjsip_target_assign_status(pjsip_target *target,\n\t\t\t\t\t        pj_pool_t *pool,\n\t\t\t\t\t        int status_code,\n\t\t\t\t\t        const pj_str_t *reason);\n\n/**\n * @}\n */\n\n/**\n * @defgroup PJSIP_ENDPT_STATELESS Message Creation and Stateless Operations\n * @ingroup PJSIP_CORE_CORE\n * @brief Utilities to create various messages and base function to send messages.\n * @{\n */\n\n/**\n * Create an independent request message. This can be used to build any\n * request outside a dialog, such as OPTIONS, MESSAGE, etc. To create a request\n * inside a dialog, application should use #pjsip_dlg_create_request.\n *\n * This function adds the following headers in the request:\n *  - From, To, Call-ID, and CSeq,\n *  - Contact header, if contact is specified.\n *  - A blank Via header.\n *  - Additional request headers (such as Max-Forwards) which are copied\n *    from endpoint configuration.\n *\n * In addition, the function adds a unique tag in the From header.\n *\n * Once a transmit data is created, the reference counter is initialized to 1.\n *\n * @param endpt\t    Endpoint instance.\n * @param method    SIP Method.\n * @param target    Target URI.\n * @param from\t    URL to put in From header.\n * @param to\t    URL to put in To header.\n * @param contact   Contact to be put as Contact header value, hence\n *\t\t    the format must follow RFC 3261 Section 20.10:\n *\t\t    When the header field value contains a display \n *\t\t    name, the URI including all URI parameters is \n *\t\t    enclosed in \"<\" and \">\".  If no \"<\" and \">\" are \n *\t\t    present, all parameters after the URI are header\n *\t\t    parameters, not URI parameters.  The display name \n *\t\t    can be tokens, or a quoted string, if a larger \n *\t\t    character set is desired.\n * @param call_id   Optional Call-ID (put NULL to generate unique Call-ID).\n * @param cseq\t    Optional CSeq (put -1 to generate random CSeq).\n * @param text\t    Optional text body (put NULL to omit body).\n * @param p_tdata   Pointer to receive the transmit data.\n *\n * @return\t    PJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_create_request( pjsip_endpoint *endpt, \n\t\t\t\t\t\t const pjsip_method *method,\n\t\t\t\t\t\t const pj_str_t *target,\n\t\t\t\t\t\t const pj_str_t *from,\n\t\t\t\t\t\t const pj_str_t *to, \n\t\t\t\t\t\t const pj_str_t *contact,\n\t\t\t\t\t\t const pj_str_t *call_id,\n\t\t\t\t\t\t int cseq, \n\t\t\t\t\t\t const pj_str_t *text,\n\t\t\t\t\t\t pjsip_tx_data **p_tdata);\n\n/**\n * Create an independent request message from the specified headers. This\n * function will clone the headers and put them in the request.\n *\n * This function adds the following headers in the request:\n *  - From, To, Call-ID, and CSeq,\n *  - Contact header, if contact is specified.\n *  - A blank Via header.\n *  - Additional request headers (such as Max-Forwards) which are copied\n *    from endpoint configuration.\n *\n * In addition, the function adds a unique tag in the From header.\n *\n * Once a transmit data is created, the reference counter is initialized to 1.\n *\n * @param endpt\t    Endpoint instance.\n * @param method    SIP Method.\n * @param target    Target URI.\n * @param from\t    From header.\n * @param to\t    To header.\n * @param contact   Contact header.\n * @param call_id   Optional Call-ID (put NULL to generate unique Call-ID).\n * @param cseq\t    Optional CSeq (put -1 to generate random CSeq).\n * @param text\t    Optional text body (put NULL to omit body).\n * @param p_tdata   Pointer to receive the transmit data.\n *\n * @return\t    PJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t)\npjsip_endpt_create_request_from_hdr( pjsip_endpoint *endpt,\n\t\t\t\t     const pjsip_method *method,\n\t\t\t\t     const pjsip_uri *target,\n\t\t\t\t     const pjsip_from_hdr *from,\n\t\t\t\t     const pjsip_to_hdr *to,\n\t\t\t\t     const pjsip_contact_hdr *contact,\n\t\t\t\t     const pjsip_cid_hdr *call_id,\n\t\t\t\t     int cseq,\n\t\t\t\t     const pj_str_t *text,\n\t\t\t\t     pjsip_tx_data **p_tdata);\n\n/**\n * Construct a minimal response message for the received request. This function\n * will construct all the Via, Record-Route, Call-ID, From, To, CSeq, and \n * Call-ID headers from the request.\n *\n * Note: the txdata reference counter is set to ZERO!.\n *\n * @param endpt\t    The endpoint.\n * @param rdata\t    The request receive data.\n * @param st_code   Status code to be put in the response.\n * @param st_text   Optional status text, or NULL to get the default text.\n * @param p_tdata   Pointer to receive the transmit data.\n *\n * @return\t    PJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_create_response( pjsip_endpoint *endpt,\n\t\t\t\t\t\t  const pjsip_rx_data *rdata,\n\t\t\t\t\t\t  int st_code,\n\t\t\t\t\t\t  const pj_str_t *st_text,\n\t\t\t\t\t\t  pjsip_tx_data **p_tdata);\n\n/**\n * Construct a full ACK request for the received non-2xx final response.\n * This utility function is normally called by the transaction to construct\n * an ACK request to 3xx-6xx final response.\n * The generation of ACK message for 2xx final response is different than\n * this one.\n * \n * @param endpt\t    The endpoint.\n * @param tdata\t    This contains the original INVITE request\n * @param rdata\t    The final response.\n * @param ack\t    The ACK request created.\n *\n * @return\t    PJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_create_ack( pjsip_endpoint *endpt,\n\t\t\t\t\t     const pjsip_tx_data *tdata,\n\t\t\t\t\t     const pjsip_rx_data *rdata,\n\t\t\t\t\t     pjsip_tx_data **ack);\n\n\n/**\n * Construct CANCEL request for the previously sent request.\n *\n * @param endpt\t    The endpoint.\n * @param tdata\t    The transmit buffer for the request being cancelled.\n * @param p_tdata   Pointer to receive the transmit data.\n *\n * @return\t    PJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt,\n\t\t\t\t\t\tconst pjsip_tx_data *tdata,\n\t\t\t\t\t\tpjsip_tx_data **p_tdata);\n\n/**\n * Get destination address and port and transport type information for the\n * specified URI.\n *\n * @param target_uri\tThe destination URI.\n * @param request_uri\tOptional request URI to be considered. May be NULL.\n * @param pool\t\tPool to allocate memory from.\n * @param dest_info\tTo be filled with destination info.\n *\n * @return\t\tPJ_SUCCESS or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_get_dest_info(const pjsip_uri *target_uri,\n\t\t\t\t \t const pjsip_uri *request_uri,\n\t\t\t\t \t pj_pool_t *pool,\n\t\t\t\t \t pjsip_host_info *dest_info);\n\n/**\n * Find which destination to be used to send the request message, based\n * on the request URI and Route headers in the message. The procedure\n * used here follows the guidelines on sending the request in RFC 3261\n * chapter 8.1.2.\n *\n * Note there was a change in the behavior of this function since version\n * 0.5.10.2. Previously this function may modify the request when strict\n * route is present (to update request URI and route-set). This is no\n * longer the case now, and this process is done in separate function\n * (see #pjsip_process_route_set()).\n *\n * @param tdata\t    The transmit data containing the request message.\n * @param dest_info On return, it contains information about destination\n *\t\t    host to contact, along with the preferable transport\n *\t\t    type, if any. Caller will then normally proceed with\n *\t\t    resolving this host with server resolution procedure\n *\t\t    described in RFC 3263.\n *\n * @return\t    PJ_SUCCESS, or the appropriate error code.\n *\n * @see pjsip_process_route_set\n */\nPJ_DECL(pj_status_t) pjsip_get_request_dest(const pjsip_tx_data *tdata,\n\t\t\t\t\t    pjsip_host_info *dest_info );\n\n\n/**\n * Process route-set found in the request and calculate destination to be\n * used to send the request message, based on the request URI and Route \n * headers in the message. The procedure used here follows the guidelines\n * on sending the request in RFC 3261 chapter 8.1.2.\n *\n * This function may modify the message (request line and Route headers),\n * if the Route information specifies strict routing and the request\n * URI in the message is different than the calculated target URI. In that\n * case, the target URI will be put as the request URI of the request and\n * current request URI will be put as the last entry of the Route headers.\n *\n * @param tdata\t    The transmit data containing the request message.\n * @param dest_info On return, it contains information about destination\n *\t\t    host to contact, along with the preferable transport\n *\t\t    type, if any. Caller will then normally proceed with\n *\t\t    resolving this host with server resolution procedure\n *\t\t    described in RFC 3263.\n *\n * @return\t    PJ_SUCCESS, or the appropriate error code.\n *\n * @see pjsip_get_request_addr\n */\nPJ_DECL(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,\n\t\t\t\t\t     pjsip_host_info *dest_info );\n\n\n/**\n * Swap the request URI and strict route back to the original position\n * before #pjsip_process_route_set() function is called. If no strict\n * route URI was found by #pjsip_process_route_set(), this function will\n * do nothing.\n *\n * This function should only used internally by PJSIP client authentication\n * module.\n *\n * @param tdata\t    Transmit data containing request message.\n */\nPJ_DECL(void) pjsip_restore_strict_route_set(pjsip_tx_data *tdata);\n\n\n/**\n * This structure holds the state of outgoing stateless request.\n */\ntypedef struct pjsip_send_state\n{\n    /** Application token, which was specified when the function\n     *  #pjsip_endpt_send_request_stateless() is called.\n     */\n    void *token;\n\n    /** Endpoint instance. \n     */\n    pjsip_endpoint *endpt;\n\n    /** Transmit data buffer being sent. \n     */\n    pjsip_tx_data *tdata;\n\n    /** Current transport being used. \n     */\n    pjsip_transport *cur_transport;\n\n    /** The application callback which was specified when the function\n     *  #pjsip_endpt_send_request_stateless() was called.\n     */\n    void (*app_cb)(struct pjsip_send_state*,\n\t\t   pj_ssize_t sent,\n\t\t   pj_bool_t *cont);\n} pjsip_send_state;\n\n\n/**\n * Declaration for callback function to be specified in \n * #pjsip_endpt_send_request_stateless(), #pjsip_endpt_send_response(), or\n * #pjsip_endpt_send_response2().\n *\n * @param st\t    Structure to keep transmission state.\n * @param sent\t    Number of bytes sent.\n * @param cont\t    When current transmission fails, specify whether\n *\t\t    the function should fallback to next destination.\n */\ntypedef void (*pjsip_send_callback)(pjsip_send_state *st, pj_ssize_t sent,\n\t\t\t\t    pj_bool_t *cont);\n\n/**\n * Send outgoing request statelessly The function will take care of which \n * destination and transport to use based on the information in the message,\n * taking care of URI in the request line and Route header.\n *\n * This function is different than #pjsip_transport_send() in that this \n * function adds/modify the Via header as necessary.\n *\n * @param endpt\t    The endpoint instance.\n * @param tdata\t    The transmit data to be sent.\n * @param token\t    Arbitrary token to be given back on the callback.\n * @param cb\t    Optional callback to notify transmission status (also\n *\t\t    gives chance for application to discontinue retrying\n *\t\t    sending to alternate address).\n *\n * @return\t    PJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) \npjsip_endpt_send_request_stateless( pjsip_endpoint *endpt,\n\t\t\t\t    pjsip_tx_data *tdata,\n\t\t\t\t    void *token,\n\t\t\t\t    pjsip_send_callback cb);\n\n/**\n * This is a low-level function to send raw data to a destination.\n *\n * See also #pjsip_endpt_send_raw_to_uri().\n *\n * @param endpt\t    The SIP endpoint instance.\n * @param tp_type   Transport type.\n * @param sel\t    Optional pointer to transport selector instance if\n *\t\t    application wants to use a specific transport instance\n *\t\t    rather then letting transport manager finds the suitable\n *\t\t    transport..\n * @param raw_data  The data to be sent.\n * @param data_len  The length of the data.\n * @param addr\t    Destination address.\n * @param addr_len  Length of destination address.\n * @param token\t    Arbitrary token to be returned back to callback.\n * @param cb\t    Optional callback to be called to notify caller about\n *\t\t    the completion status of the pending send operation.\n *\n * @return\t    If the message has been sent successfully, this function\n *\t\t    will return PJ_SUCCESS and the callback will not be \n *\t\t    called. If message cannot be sent immediately, this\n *\t\t    function will return PJ_EPENDING, and application will\n *\t\t    be notified later about the completion via the callback.\n *\t\t    Any statuses other than PJ_SUCCESS or PJ_EPENDING\n *\t\t    indicates immediate failure, and in this case the \n *\t\t    callback will not be called.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_send_raw(pjsip_endpoint *endpt,\n\t\t\t\t\t  pjsip_transport_type_e tp_type,\n\t\t\t\t\t  const pjsip_tpselector *sel,\n\t\t\t\t\t  const void *raw_data,\n\t\t\t\t\t  pj_size_t data_len,\n\t\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t\t  int addr_len,\n\t\t\t\t\t  void *token,\n\t\t\t\t\t  pjsip_tp_send_callback cb);\n\n/**\n * Send raw data to the specified destination URI. The actual destination\n * address will be calculated from the URI, using normal SIP URI to host\n * resolution.\n *\n * See also #pjsip_endpt_send_raw().\n *\n * @param endpt\t    The SIP endpoint instance.\n * @param dst_uri   Destination address URI.\n * @param sel\t    Optional pointer to transport selector instance if\n *\t\t    application wants to use a specific transport instance\n *\t\t    rather then letting transport manager finds the suitable\n *\t\t    transport..\n * @param raw_data  The data to be sent.\n * @param data_len  The length of the data.\n * @param token\t    Arbitrary token to be returned back to callback.\n * @param cb\t    Optional callback to be called to notify caller about\n *\t\t    the completion status of the pending send operation.\n *\n * @return\t    If the message has been sent successfully, this function\n *\t\t    will return PJ_SUCCESS and the callback will not be \n *\t\t    called. If message cannot be sent immediately, this\n *\t\t    function will return PJ_EPENDING, and application will\n *\t\t    be notified later about the completion via the callback.\n *\t\t    Any statuses other than PJ_SUCCESS or PJ_EPENDING\n *\t\t    indicates immediate failure, and in this case the \n *\t\t    callback will not be called.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_send_raw_to_uri(pjsip_endpoint *endpt,\n\t\t\t\t\t\t const pj_str_t *dst_uri,\n\t\t\t\t\t\t const pjsip_tpselector *sel,\n\t\t\t\t\t\t const void *raw_data,\n\t\t\t\t\t\t pj_size_t data_len,\n\t\t\t\t\t\t void *token,\n\t\t\t\t\t\t pjsip_tp_send_callback cb);\n\n/**\n * This structure describes destination information to send response.\n * It is initialized by calling #pjsip_get_response_addr().\n *\n * If the response message should be sent using transport from which\n * the request was received, then transport, addr, and addr_len fields\n * are initialized.\n *\n * The dst_host field is also initialized. It should be used when server\n * fails to send the response using the transport from which the request\n * was received, or when the transport is NULL, which means server\n * must send the response to this address (this situation occurs when\n * maddr parameter is set, or when rport param is not set in the request).\n */\ntypedef struct pjsip_response_addr\n{\n    pjsip_transport *transport;\t/**< Immediate transport to be used. */\n    pj_sockaddr\t     addr;\t/**< Immediate address to send to.   */\n    int\t\t     addr_len;\t/**< Address length.\t\t     */\n    pjsip_host_info  dst_host;\t/**< Destination host to contact.    */\n} pjsip_response_addr;\n\n/**\n * Determine which address (and transport) to use to send response message\n * based on the received request. This function follows the specification\n * in section 18.2.2 of RFC 3261 and RFC 3581 for calculating the destination\n * address and transport.\n *\n * The information about destination to send the response will be returned\n * in res_addr argument. Please see #pjsip_response_addr for more info.\n *\n * @param pool\t    The pool.\n * @param rdata\t    The incoming request received by the server.\n * @param res_addr  On return, it will be initialized with information about\n *\t\t    destination address and transport to send the response.\n *\n * @return\t    zero (PJ_OK) if successfull.\n */\nPJ_DECL(pj_status_t) pjsip_get_response_addr(pj_pool_t *pool,\n\t\t\t\t\t     pjsip_rx_data *rdata,\n\t\t\t\t\t     pjsip_response_addr *res_addr);\n\n/**\n * Send response in tdata statelessly. The function will take care of which \n * response destination and transport to use based on the information in the \n * Via header (such as the presence of rport, symmetric transport, etc.).\n *\n * This function will create a new ephemeral transport if no existing \n * transports can be used to send the message to the destination. The ephemeral\n * transport will be destroyed after some period if it is not used to send any \n * more messages.\n *\n * The behavior of this function complies with section 18.2.2 of RFC 3261\n * and RFC 3581.\n *\n * @param endpt\t    The endpoint instance.\n * @param res_addr  The information about the address and transport to send\n *\t\t    the response to. Application can get this information\n *\t\t    by calling #pjsip_get_response_addr().\n * @param tdata\t    The response message to be sent.\n * @param token\t    Token to be passed back when the callback is called.\n * @param cb\t    Optional callback to notify the transmission status\n *\t\t    to application, and to inform whether next address or\n *\t\t    transport will be tried.\n * \n * @return\t    PJ_SUCCESS if response has been successfully created and\n *\t\t    sent to transport layer, or a non-zero error code. \n *\t\t    However, even when it returns PJ_SUCCESS, there is no \n *\t\t    guarantee that the response has been successfully sent.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_send_response( pjsip_endpoint *endpt,\n\t\t\t\t\t        pjsip_response_addr *res_addr,\n\t\t\t\t\t        pjsip_tx_data *tdata,\n\t\t\t\t\t\tvoid *token,\n\t\t\t\t\t\tpjsip_send_callback cb);\n\n/**\n * This is a convenient function which wraps #pjsip_get_response_addr() and\n * #pjsip_endpt_send_response() in a single function.\n *\n * @param endpt\t    The endpoint instance.\n * @param rdata\t    The original request to be responded.\n * @param tdata\t    The response message to be sent.\n * @param token\t    Token to be passed back when the callback is called.\n * @param cb\t    Optional callback to notify the transmission status\n *\t\t    to application, and to inform whether next address or\n *\t\t    transport will be tried.\n * \n * @return\t    PJ_SUCCESS if response has been successfully created and\n *\t\t    sent to transport layer, or a non-zero error code. \n *\t\t    However, even when it returns PJ_SUCCESS, there is no \n *\t\t    guarantee that the response has been successfully sent.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_send_response2(pjsip_endpoint *endpt,\n\t\t\t\t\t        pjsip_rx_data *rdata,\n\t\t\t\t\t        pjsip_tx_data *tdata,\n\t\t\t\t\t\tvoid *token,\n\t\t\t\t\t\tpjsip_send_callback cb);\n\n/**\n * This composite function sends response message statelessly to an incoming\n * request message. Internally it calls #pjsip_endpt_create_response() and\n * #pjsip_endpt_send_response().\n *\n * @param endpt\t    The endpoint instance.\n * @param rdata\t    The incoming request message.\n * @param st_code   Status code of the response.\n * @param st_text   Optional status text of the response.\n * @param hdr_list  Optional header list to be added to the response.\n * @param body\t    Optional message body to be added to the response.\n *\n * @return\t    PJ_SUCCESS if response message has successfully been\n *\t\t    sent.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_respond_stateless(pjsip_endpoint *endpt,\n\t\t\t\t\t\t   pjsip_rx_data *rdata,\n\t\t\t\t\t\t   int st_code,\n\t\t\t\t\t\t   const pj_str_t *st_text,\n\t\t\t\t\t\t   const pjsip_hdr *hdr_list,\n\t\t\t\t\t\t   const pjsip_msg_body *body);\n\t\t\t\t\t\t    \n/**\n * @}\n */\n\n/**\n * @defgroup PJSIP_TRANSACT_UTIL Stateful Operations\n * @ingroup PJSIP_TRANSACT\n * @brief Utility function to send requests/responses statefully.\n * @{\n */\n\n/**\n * This composite function creates and sends response statefully for the\n * incoming request.\n *\n * @param endpt\t    The endpoint instance.\n * @param tsx_user  The module to be registered as transaction user.\n * @param rdata\t    The incoming request message.\n * @param st_code   Status code of the response.\n * @param st_text   Optional status text of the response.\n * @param hdr_list  Optional header list to be added to the response.\n * @param body\t    Optional message body to be added to the response.\n * @param p_tsx\t    Optional pointer to receive the transaction which was\n *\t\t    created to send the response.\n *\n * @return\t    PJ_SUCCESS if response message has successfully been\n *\t\t    created.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_respond( pjsip_endpoint *endpt,\n\t\t\t\t\t  pjsip_module *tsx_user,\n\t\t\t\t\t  pjsip_rx_data *rdata,\n\t\t\t\t\t  int st_code,\n\t\t\t\t\t  const pj_str_t *st_text,\n\t\t\t\t\t  const pjsip_hdr *hdr_list,\n\t\t\t\t\t  const pjsip_msg_body *body,\n\t\t\t\t\t  pjsip_transaction **p_tsx );\n\n/**\n * Type of callback to be specified in #pjsip_endpt_send_request().\n *\n * @param token\t    The token that was given in #pjsip_endpt_send_request()\n * @param e\t    Completion event.\n */\ntypedef void (*pjsip_endpt_send_callback)(void *token, pjsip_event *e);\n\n/**\n * Send outgoing request and initiate UAC transaction for the request.\n * This is an auxiliary function to be used by application to send arbitrary\n * requests outside a dialog. To send a request within a dialog, application\n * should use #pjsip_dlg_send_request instead.\n *\n * @param endpt\t    The endpoint instance.\n * @param tdata\t    The transmit data to be sent.\n * @param timeout   Optional timeout for final response to be received, or -1 \n *\t\t    if the transaction should not have a timeout restriction.\n *\t\t    The value is in miliseconds. Note that this is not \n *\t\t    implemented yet, so application needs to use its own timer \n *\t\t    to handle timeout.\n * @param token\t    Optional token to be associated with the transaction, and \n *\t\t    to be passed to the callback.\n * @param cb\t    Optional callback to be called when the transaction has\n *\t\t    received a final response. The callback will be called with\n *\t\t    the previously registered token and the event that triggers\n *\t\t    the completion of the transaction.\n *\n * @return\t    PJ_SUCCESS, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_send_request( pjsip_endpoint *endpt,\n\t\t\t\t\t       pjsip_tx_data *tdata,\n\t\t\t\t\t       pj_int32_t timeout,\n\t\t\t\t\t       void *token,\n\t\t\t\t\t       pjsip_endpt_send_callback cb);\n\n/**\n * @}\n */\n\n/**\n * @defgroup PJSIP_PROXY_CORE Core Proxy Layer\n * @brief Core proxy operations\n * @{\n */\n\n/**\n * Create new request message to be forwarded upstream to new destination URI \n * in uri. The new request is a full/deep clone of the request received in \n * rdata, unless if other copy mechanism is specified in the options. \n * The branch parameter, if not NULL, will be used as the branch-param in \n * the Via header. If it is NULL, then a unique branch parameter will be used.\n *\n * Note: this function DOES NOT perform Route information preprocessing as\n *\t  described in RFC 3261 Section 16.4. Application must take care of\n *\t  removing/updating the Route headers according of the rules as\n *\t  described in that section.\n *\n * @param endpt\t    The endpoint instance.\n * @param rdata\t    The incoming request message.\n * @param uri\t    The URI where the request will be forwarded to.\n * @param branch    Optional branch parameter. Application may specify its\n *\t\t    own branch, for example if it wishes to perform loop\n *\t\t    detection. If the branch parameter is not specified,\n *\t\t    this function will generate its own by calling \n *\t\t    #pjsip_calculate_branch_id() function.\n * @param options   Optional option flags when duplicating the message.\n * @param tdata\t    The result.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_create_request_fwd(pjsip_endpoint *endpt,\n\t\t\t\t\t\t    pjsip_rx_data *rdata, \n\t\t\t\t\t\t    const pjsip_uri *uri,\n\t\t\t\t\t\t    const pj_str_t *branch,\n\t\t\t\t\t\t    unsigned options,\n\t\t\t\t\t\t    pjsip_tx_data **tdata);\n\n\n\n/**\n * Create new response message to be forwarded downstream by the proxy from \n * the response message found in rdata. Note that this function practically \n * will clone the response as is, i.e. without checking the validity of the \n * response or removing top most Via header. This function will perform \n * full/deep clone of the response, unless other copy mechanism is used in \n * the options.\n *\n * @param endpt\t    The endpoint instance.\n * @param rdata\t    The incoming response message.\n * @param options   Optional option flags when duplicate the message.\n * @param tdata\t    The result\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_endpt_create_response_fwd( pjsip_endpoint *endpt,\n\t\t\t\t\t\t      pjsip_rx_data *rdata, \n\t\t\t\t\t\t      unsigned options,\n\t\t\t\t\t\t      pjsip_tx_data **tdata);\n\n\n\n/**\n * Create a globally unique branch parameter based on the information in \n * the incoming request message, for the purpose of creating a new request\n * for forwarding. This is the default implementation used by \n * #pjsip_endpt_create_request_fwd() function if the branch parameter is\n * not specified.\n *\n * The default implementation here will just create an MD5 hash of the\n * top-most Via.\n *\n * Note that the returned string was allocated from rdata's pool.\n *\n * @param rdata\t    The incoming request message.\n *\n * @return\t    Unique branch-ID string.\n */\nPJ_DECL(pj_str_t) pjsip_calculate_branch_id( pjsip_rx_data *rdata );\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_SIP_MISC_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-simple/errno.h",
    "content": "/* $Id: errno.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef __PJSIP_SIMPLE_ERRNO_H__\n#define __PJSIP_SIMPLE_ERRNO_H__\n\n#include <pjsip/sip_errno.h>\n\nPJ_BEGIN_DECL\n\n/**\n * Start of error code relative to PJ_ERRNO_START_USER.\n */\n#define PJSIP_SIMPLE_ERRNO_START  (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*2)\n\n\n/************************************************************\n * EVENT PACKAGE ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * No event package with the specified name.\n */\n#define PJSIP_SIMPLE_ENOPKG\t    (PJSIP_SIMPLE_ERRNO_START+1)    /*270001*/\n/**\n * @hideinitializer\n * Event package already exists.\n */\n#define PJSIP_SIMPLE_EPKGEXISTS\t    (PJSIP_SIMPLE_ERRNO_START+2)    /*270002*/\n\n\n/************************************************************\n * PRESENCE ERROR\n ***********************************************************/\n/**\n * @hideinitializer\n * Expecting SUBSCRIBE request\n */\n#define PJSIP_SIMPLE_ENOTSUBSCRIBE  (PJSIP_SIMPLE_ERRNO_START+20)   /*270020*/\n/**\n * @hideinitializer\n * No presence associated with subscription\n */\n#define PJSIP_SIMPLE_ENOPRESENCE    (PJSIP_SIMPLE_ERRNO_START+21)   /*270021*/\n/**\n * @hideinitializer\n * No presence info in server subscription\n */\n#define PJSIP_SIMPLE_ENOPRESENCEINFO (PJSIP_SIMPLE_ERRNO_START+22)  /*270022*/\n/**\n * @hideinitializer\n * Bad Content-Type\n */\n#define PJSIP_SIMPLE_EBADCONTENT    (PJSIP_SIMPLE_ERRNO_START+23)   /*270023*/\n/**\n * @hideinitializer\n * Bad PIDF Message\n */\n#define PJSIP_SIMPLE_EBADPIDF\t    (PJSIP_SIMPLE_ERRNO_START+24)   /*270024*/\n/**\n * @hideinitializer\n * Bad XPIDF Message\n */\n#define PJSIP_SIMPLE_EBADXPIDF\t    (PJSIP_SIMPLE_ERRNO_START+25)   /*270025*/\n/**\n * @hideinitializer\n * Bad RPID Message\n */\n#define PJSIP_SIMPLE_EBADRPID\t    (PJSIP_SIMPLE_ERRNO_START+26)   /*270026*/\n\n\n/************************************************************\n * ISCOMPOSING ERRORS\n ***********************************************************/\n/**\n * @hideinitializer\n * Bad isComposing XML message.\n */\n#define PJSIP_SIMPLE_EBADISCOMPOSE  (PJSIP_SIMPLE_ERRNO_START+40)   /*270040*/\n\n/**\n * Get error message for the specified error code. Note that this\n * function is only able to decode PJSIP-SIMPLE specific error code.\n * Application should use pj_strerror(), which should be able to\n * decode all error codes belonging to all subsystems (e.g. pjlib,\n * pjmedia, pjsip, etc).\n *\n * @param status    The error code.\n * @param buffer    The buffer where to put the error message.\n * @param bufsize   Size of the buffer.\n *\n * @return\t    The error message as NULL terminated string,\n *                  wrapped with pj_str_t.\n */\nPJ_DECL(pj_str_t) pjsipsimple_strerror(pj_status_t status, \n\t\t\t\t       char *buffer, pj_size_t bufsize);\n\n\nPJ_END_DECL\n\n#endif\t/* __PJSIP_SIMPLE_ERRNO_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-simple/evsub.h",
    "content": "/* $Id: evsub.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#ifndef __PJSIP_SIMPLE_EVSUB_H__\n#define __PJSIP_SIMPLE_EVSUB_H__\n\n/**\n * @file evsub.h\n * @brief SIP Specific Event Notification Extension (RFC 3265)\n */\n\n#include <pjsip-simple/types.h>\n\n\n/**\n * @defgroup PJSIP_EVENT_NOT SIP Event Notification (RFC 3265) Module\n * @ingroup PJSIP_SIMPLE\n * @brief Core Event Subscription framework, used by presence, call transfer, etc.\n * @{\n *\n * This module provides the implementation of SIP Extension for SIP Specific\n * Event Notification (RFC 3265). It extends PJSIP by supporting SUBSCRIBE and\n * NOTIFY methods.\n *\n * This module itself is extensible; new event packages can be registered to\n * this module to handle specific extensions (such as presence).\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Opaque type for event subscription session.\n */\ntypedef struct pjsip_evsub pjsip_evsub;\n\n\n/**\n * This enumeration describes basic subscription state as described in the \n * RFC 3265. The standard specifies that extensions may define additional \n * states. In the case where the state is not known, the subscription state\n * will be set to PJSIP_EVSUB_STATE_UNKNOWN, and the token will be kept\n * in state_str member of the susbcription structure.\n */\ntypedef enum pjsip_evsub_state\n{\n    PJSIP_EVSUB_STATE_NULL,\t /**< State is NULL.\t\t\t    */\n    PJSIP_EVSUB_STATE_SENT,\t /**< Client has sent SUBSCRIBE request.    */\n    PJSIP_EVSUB_STATE_ACCEPTED,\t /**< 2xx response to SUBSCRIBE has been \n\t\t\t\t      sent/received.\t\t\t    */\n    PJSIP_EVSUB_STATE_PENDING,\t /**< Subscription is pending.\t\t    */\n    PJSIP_EVSUB_STATE_ACTIVE,\t /**< Subscription is active.\t\t    */\n    PJSIP_EVSUB_STATE_TERMINATED,/**< Subscription is terminated.\t    */\n    PJSIP_EVSUB_STATE_UNKNOWN,\t /**< Subscription state can not be determined.\n\t\t\t\t      Application can query the state by \n\t\t\t\t      calling #pjsip_evsub_get_state_name().*/\n} pjsip_evsub_state;\n\n\n/**\n * Some options for the event subscription.\n */\nenum\n{\n    /** \n     * If this flag is set, then outgoing request to create subscription\n     * will not have id in the Event header (e.g. in REFER request). But if \n     * there is an id in the incoming NOTIFY, that id will be used.\n     */\n    PJSIP_EVSUB_NO_EVENT_ID  = 1,\n};\n\n\n/**\n * This structure describes callback that is registered by application or\n * package to receive notifications about subscription events.\n */\nstruct pjsip_evsub_user\n{\n    /**\n     * This callback is called when subscription state has changed.\n     * Application MUST be prepared to receive NULL event and events with\n     * type other than PJSIP_EVENT_TSX_STATE\n     *\n     * This callback is OPTIONAL.\n     *\n     * @param sub\tThe subscription instance.\n     * @param event\tThe event that has caused the state to change,\n     *\t\t\twhich may be NULL or may have type other than\n     *\t\t\tPJSIP_EVENT_TSX_STATE.\n     */\n    void (*on_evsub_state)( pjsip_evsub *sub, pjsip_event *event);\n\n    /**\n     * This callback is called when transaction state has changed.\n     *\n     * @param sub\tThe subscription instance.\n     * @param tsx\tTransaction.\n     * @param event\tThe event.\n     */\n    void (*on_tsx_state)(pjsip_evsub *sub, pjsip_transaction *tsx,\n\t\t\t pjsip_event *event);\n\n    /**\n     * This callback is called when incoming SUBSCRIBE (or any method that\n     * establishes the subscription in the first place) is received. It \n     * allows application to specify what response should be sent to \n     * remote, along with additional headers and message body to be put \n     * in the response.\n     *\n     * This callback is OPTIONAL.\n     *\n     * However, implementation MUST send NOTIFY request upon receiving this\n     * callback. The suggested behavior is to call \n     * #pjsip_evsub_current_notify(), since this function takes care\n     * about unsubscription request and calculates the appropriate expiration\n     * interval.\n     */\n    void (*on_rx_refresh)( pjsip_evsub *sub, \n\t\t\t   pjsip_rx_data *rdata,\n\t\t\t   int *p_st_code,\n\t\t\t   pj_str_t **p_st_text,\n\t\t\t   pjsip_hdr *res_hdr,\n\t\t\t   pjsip_msg_body **p_body);\n\n    /**\n     * This callback is called when client/subscriber received incoming\n     * NOTIFY request. It allows the application to specify what response\n     * should be sent to remote, along with additional headers and message\n     * body to be put in the response.\n     *\n     * This callback is OPTIONAL. When it is not implemented, the default\n     * behavior is to respond incoming NOTIFY request with 200 (OK).\n     *\n     * @param sub\tThe subscription instance.\n     * @param rdata\tThe received NOTIFY request.\n     * @param p_st_code\tApplication MUST set the value of this argument with\n     *\t\t\tfinal status code (200-699) upon returning from the\n     *\t\t\tcallback.\n     * @param p_st_text\tCustom status text, if any.\n     * @param res_hdr\tUpon return, application can put additional headers \n     *\t\t\tto be sent in the response in this list.\n     * @param p_body\tApplication MAY specify message body to be sent in\n     *\t\t\tthe response.\n     */\n    void (*on_rx_notify)(pjsip_evsub *sub, \n\t\t\t pjsip_rx_data *rdata,\n\t\t\t int *p_st_code,\n\t\t\t pj_str_t **p_st_text,\n\t\t\t pjsip_hdr *res_hdr,\n\t\t\t pjsip_msg_body **p_body);\n\n    /**\n     * This callback is called when it is time for the client to refresh\n     * the subscription.\n     *\n     * This callback is OPTIONAL when PJSIP package such as presence or \n     * refer is used; the event package will refresh subscription by sending\n     * SUBSCRIBE with the interval set to current/last interval.\n     *\n     * @param sub\tThe subscription instance.\n     */\n    void (*on_client_refresh)(pjsip_evsub *sub);\n\n    /**\n     * This callback is called when server doesn't receive subscription \n     * refresh after the specified subscription interval.\n     *\n     * This callback is OPTIONAL when PJSIP package such as presence or \n     * refer is used; the event package send NOTIFY to terminate the \n     * subscription.\n     */\n    void (*on_server_timeout)(pjsip_evsub *sub);\n\n};\n\n\n/**\n * @see pjsip_evsub_user\n */\ntypedef struct pjsip_evsub_user pjsip_evsub_user;\n\n\n/**\n * SUBSCRIBE method constant. @see pjsip_get_subscribe_method()\n */\nPJ_DECL_DATA(const pjsip_method) pjsip_subscribe_method;\n\n/**\n * NOTIFY method constant. @see pjsip_get_notify_method()\n */\nPJ_DECL_DATA(const pjsip_method) pjsip_notify_method;\n\n/**\n * SUBSCRIBE method constant.\n */\nPJ_DECL(const pjsip_method*) pjsip_get_subscribe_method(void);\n\n/**\n * NOTIFY method constant.\n */\nPJ_DECL(const pjsip_method*) pjsip_get_notify_method(void);\n\n\n/**\n * Initialize the event subscription module and register the module to the \n * specified endpoint.\n *\n * @param endpt\t\tThe endpoint instance.\n *\n * @return\t\tPJ_SUCCESS if module can be created and registered\n *\t\t\tsuccessfully.\n */\nPJ_DECL(pj_status_t) pjsip_evsub_init_module(pjsip_endpoint *endpt);\n\n\n/**\n * Get the event subscription module instance that was previously created \n * and registered to endpoint.\n *\n * @return\t\tThe event subscription module instance.\n */\nPJ_DECL(pjsip_module*) pjsip_evsub_instance(void);\n\n\n/**\n * Register event package to the event subscription framework.\n *\n * @param pkg_mod\tThe module that implements the event package being\n *\t\t\tregistered.\n * @param event_name\tEvent package identification.\n * @param expires\tDefault subscription expiration time, in seconds.\n * @param accept_cnt\tNumber of strings in Accept array.\n * @param accept\tArray of Accept value.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_evsub_register_pkg( pjsip_module *pkg_mod,\n\t\t\t\t\t       const pj_str_t *event_name,\n\t\t\t\t\t       unsigned expires,\n\t\t\t\t\t       unsigned accept_cnt,\n\t\t\t\t\t       const pj_str_t accept[]);\n\n/**\n * Get the Allow-Events header. This header is built based on the packages\n * that are registered to the evsub module.\n *\n * @param m\t\tPointer to event subscription module instance, or\n *\t\t\tNULL to use default instance (equal to \n *\t\t\t#pjsip_evsub_instance()).\n *\n * @return\t\tThe Allow-Events header.\n */\nPJ_DECL(const pjsip_hdr*) pjsip_evsub_get_allow_events_hdr(pjsip_module *m);\n\n\n/**\n * Create client subscription session.\n *\n * @param dlg\t\tThe underlying dialog to use.\n * @param user_cb\tCallback to receive event subscription notifications.\n * @param event\t\tEvent name.\n * @param option\tBitmask of options.\n * @param p_evsub\tPointer to receive event subscription instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_evsub_create_uac( pjsip_dialog *dlg,\n\t\t\t\t\t     const pjsip_evsub_user *user_cb,\n\t\t\t\t\t     const pj_str_t *event,\n\t\t\t\t\t     unsigned option,\n\t\t\t\t\t     pjsip_evsub **p_evsub);\n\n/**\n * Create server subscription session.\n *\n * @param dlg\t\tThe underlying dialog to use.\n * @param user_cb\tCallback to receive event subscription notifications.\n * @param rdata\t\tThe incoming request that creates the event \n *\t\t\tsubscription, such as SUBSCRIBE or REFER.\n * @param option\tBitmask of options.\n * @param p_evsub\tPointer to receive event subscription instance.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_evsub_create_uas( pjsip_dialog *dlg,\n\t\t\t\t\t     const pjsip_evsub_user *user_cb,\n\t\t\t\t\t     pjsip_rx_data *rdata,\n\t\t\t\t\t     unsigned option,\n\t\t\t\t\t     pjsip_evsub **p_evsub);\n\n/**\n * Forcefully destroy the subscription session. This function should only\n * be called on special condition, such as when the subscription \n * initialization has failed. For other conditions, application MUST terminate\n * the subscription by sending the appropriate un(SUBSCRIBE) or NOTIFY.\n *\n * @param sub\t\tThe event subscription.\n * @param notify\tSpecify whether the state notification callback\n *\t\t\tshould be called.\n *\n * @return\t\tPJ_SUCCESS if subscription session has been destroyed.\n */\nPJ_DECL(pj_status_t) pjsip_evsub_terminate( pjsip_evsub *sub,\n\t\t\t\t\t    pj_bool_t notify );\n\n\n/**\n * Get subscription state.\n *\n * @param sub\t\tEvent subscription instance.\n *\n * @return\t\tSubscription state.\n */\nPJ_DECL(pjsip_evsub_state) pjsip_evsub_get_state(pjsip_evsub *sub);\n\n\n/**\n * Get the string representation of the subscription state.\n *\n * @param sub\t\tEvent subscription instance.\n *\n * @return\t\tNULL terminated string.\n */\nPJ_DECL(const char*) pjsip_evsub_get_state_name(pjsip_evsub *sub);\n\n\n/**\n * Get subscription termination reason, if any. If remote did not\n * send termination reason, this function will return empty string.\n *\n * @param sub\t\tEvent subscription instance.\n *\n * @return\t\tNULL terminated string.\n */\nPJ_DECL(const pj_str_t*) pjsip_evsub_get_termination_reason(pjsip_evsub *sub);\n\n\n/**\n * Call this function to create request to initiate subscription, to \n * refresh subcription, or to request subscription termination.\n *\n * @param sub\t\tClient subscription instance.\n * @param method\tThe method that establishes the subscription, such as\n *\t\t\tSUBSCRIBE or REFER. If this argument is NULL, then\n *\t\t\tSUBSCRIBE will be used.\n * @param expires\tSubscription expiration. If the value is set to zero,\n *\t\t\tthis will request unsubscription. If the value is\n *\t\t\tnegative, default expiration as defined by the package\n *\t\t\twill be used.\n * @param p_tdata\tPointer to receive the request.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_evsub_initiate( pjsip_evsub *sub,\n\t\t\t\t\t   const pjsip_method *method,\n\t\t\t\t\t   pj_int32_t expires,\n\t\t\t\t\t   pjsip_tx_data **p_tdata);\n\n\n/**\n * Add a list of headers to the subscription instance. The list of headers\n * will be added to outgoing presence subscription requests.\n *\n * @param sub\t\tSubscription instance.\n * @param hdr_list\tList of headers to be added.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_evsub_add_header( pjsip_evsub *sub,\n\t\t\t\t\t     const pjsip_hdr *hdr_list );\n\n\n/**\n * Accept the incoming subscription request by sending 2xx response to\n * incoming SUBSCRIBE request.\n *\n * @param sub\t\tServer subscription instance.\n * @param rdata\t\tThe incoming subscription request message.\n * @param st_code\tStatus code, which MUST be final response.\n * @param hdr_list\tOptional list of headers to be added in the response.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_evsub_accept( pjsip_evsub *sub,\n\t\t\t\t\t pjsip_rx_data *rdata,\n\t\t\t\t         int st_code,\n\t\t\t\t\t const pjsip_hdr *hdr_list );\n\n\n/**\n * For notifier, create NOTIFY request to subscriber, and set the state \n * of the subscription.\n *\n * @param sub\t\tThe server subscription (notifier) instance.\n * @param state\t\tNew state to set.\n * @param state_str\tThe state string name, if state contains value other\n *\t\t\tthan active, pending, or terminated. Otherwise this\n *\t\t\targument is ignored.\n * @param reason\tSpecify reason if new state is terminated, otherwise\n *\t\t\tput NULL.\n * @param p_tdata\tPointer to receive request message.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_evsub_notify( pjsip_evsub *sub,\n\t\t\t\t\t pjsip_evsub_state state,\n\t\t\t\t\t const pj_str_t *state_str,\n\t\t\t\t\t const pj_str_t *reason,\n\t\t\t\t\t pjsip_tx_data **p_tdata);\n\n\n/**\n * For notifier, create a NOTIFY request that reflects current subscription\n * status.\n *\n * @param sub\t\tThe server subscription instance.\n * @param p_tdata\tPointer to receive the request messge.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_evsub_current_notify( pjsip_evsub *sub,\n\t\t\t\t\t\t pjsip_tx_data **p_tdata );\n\n\n\n/**\n * Send request message that was previously created with initiate(), notify(),\n * or current_notify(). Application may also send request created with other\n * functions, e.g. authentication. But the request MUST be either request\n * that creates/refresh subscription or NOTIFY request.\n *\n * @param sub\t\tThe event subscription object.\n * @param tdata\t\tRequest message to be send.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_evsub_send_request( pjsip_evsub *sub,\n\t\t\t\t\t       pjsip_tx_data *tdata);\n\n\n\n/**\n * Get the event subscription instance associated with the specified \n * transaction.\n *\n * @param tsx\t\tThe transaction.\n *\n * @return\t\tThe event subscription instance registered in the\n *\t\t\ttransaction, if any.\n */\nPJ_DECL(pjsip_evsub*) pjsip_tsx_get_evsub(pjsip_transaction *tsx);\n\n\n/**\n * Set event subscription's module data.\n *\n * @param sub\t\tThe event subscription.\n * @param mod_id\tThe module id.\n * @param data\t\tArbitrary data.\n */\nPJ_DECL(void) pjsip_evsub_set_mod_data( pjsip_evsub *sub, unsigned mod_id,\n\t\t\t\t        void *data );\n\n\n/**\n * Get event subscription's module data.\n *\n * @param sub\t\tThe event subscription.\n * @param mod_id\tThe module id.\n *\n * @return\t\tData previously set at the specified id.\n */\nPJ_DECL(void*) pjsip_evsub_get_mod_data( pjsip_evsub *sub, unsigned mod_id );\n\n\n/* Update evbsub internal refresh_time with the given interval */\nPJ_DECL(void) pjsip_evsub_update_expires( pjsip_evsub *sub,\n                                          pj_uint32_t interval );\n\n\n/* Set the specified timer (UAC or UAS) to the specified time */\nPJ_DECL(void) pjsip_evsub_set_timer( pjsip_evsub *sub,\n                                     int timer_id,\n                                     pj_int32_t seconds );\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJSIP_SIMPLE_EVSUB_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-simple/evsub_msg.h",
    "content": "/* $Id: evsub_msg.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIMPLE_EVENT_NOTIFY_MSG_H__\n#define __PJSIP_SIMPLE_EVENT_NOTIFY_MSG_H__\n\n/**\n * @file evsub_msg.h\n * @brief SIP Event Notification Headers (RFC 3265)\n */\n#include <pjsip/sip_msg.h>\n\n/**\n * @defgroup PJSIP_EVENT_HDRS Additional Header Fields\n * @ingroup PJSIP_EVENT_NOT\n * @{\n */\n\nPJ_BEGIN_DECL\n\n\n/** Max events in Allow-Events header. */\n#define PJSIP_MAX_ALLOW_EVENTS\t16\n\n/**\n * This structure describes Event header.\n */\ntypedef struct pjsip_event_hdr\n{\n    /** Standard header fields. */\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_event_hdr);\n\n    pj_str_t\t    event_type;\t    /**< Event name. */\n    pj_str_t\t    id_param;\t    /**< Optional event ID parameter. */\n    pjsip_param\t    other_param;    /**< Other parameter. */\n} pjsip_event_hdr;\n\n/**\n * Create an Event header.\n *\n * @param pool\t    The pool.\n *\n * @return\t    New Event header instance.\n */\nPJ_DECL(pjsip_event_hdr*) pjsip_event_hdr_create(pj_pool_t *pool);\n\n\n/**\n * This structure describes Allow-Events header.\n */\ntypedef pjsip_generic_array_hdr pjsip_allow_events_hdr;\n\n\n/**\n * Create a new Allow-Events header.\n *\n * @param pool\t    The pool.\n *\n * @return\t    Allow-Events header.\n */\nPJ_DECL(pjsip_allow_events_hdr*) \npjsip_allow_events_hdr_create(pj_pool_t *pool);\n\n\n/**\n * This structure describes Subscription-State header.\n */\ntypedef struct pjsip_sub_state_hdr\n{\n    /** Standard header fields. */\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_sub_state_hdr);\n\n    pj_str_t\t    sub_state;\t\t/**< Subscription state. */\n    pj_str_t\t    reason_param;\t/**< Optional termination reason. */\n    int\t\t    expires_param;\t/**< Expires param, or -1. */\n    int\t\t    retry_after;\t/**< Retry after param, or -1. */\n    pjsip_param\t    other_param;\t/**< Other parameters. */\n} pjsip_sub_state_hdr;\n\n/**\n * Create new Subscription-State header.\n *\n * @param pool\t    The pool.\n *\n * @return\t    Subscription-State header.\n */\nPJ_DECL(pjsip_sub_state_hdr*) pjsip_sub_state_hdr_create(pj_pool_t *pool);\n\n/**\n * Initialize parser for event notify module.\n */\nPJ_DECL(void) pjsip_evsub_init_parser(void);\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n#endif\t/* __PJSIP_SIMPLE_EVENT_NOTIFY_MSG_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-simple/iscomposing.h",
    "content": "/* $Id: iscomposing.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIMPLE_ISCOMPOSING_H__\n#define __PJSIP_SIMPLE_ISCOMPOSING_H__\n\n/**\n * @file iscomposing.h\n * @brief Support for Indication of Message Composition (RFC 3994)\n */\n#include <pjsip-simple/types.h>\n#include <pjlib-util/xml.h>\n\n/**\n * @defgroup PJSIP_ISCOMPOSING Message Composition Indication (RFC 3994)\n * @ingroup PJSIP_SIMPLE\n * @brief Support for Indication of Message Composition (RFC 3994)\n * @{\n *\n * This implements message composition indication, as described in\n * RFC 3994.\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Create XML message with MIME type \"application/im-iscomposing+xml\"\n * to indicate the message composition status.\n *\n * @param pool\t\t    Pool to allocate memory.\n * @param is_composing\t    Message composition indication status. Set to\n *\t\t\t    PJ_TRUE (or non-zero) to indicate that application\n *\t\t\t    is currently composing an instant message.\n * @param lst_actv\t    Optional attribute to indicate time of last\n *\t\t\t    activity. If none is to be specified, the value\n *\t\t\t    MUST be set to NULL.\n * @param content_tp\t    Optional attribute to indicate the content type of\n *\t\t\t    message being composed. If none is to be specified, \n *\t\t\t    the value MUST be set to NULL.\n * @param refresh\t    Optional attribute to indicate the interval when\n *\t\t\t    next indication will be sent, only when \n *\t\t\t    is_composing is non-zero. If none is to be \n *\t\t\t    specified, the value MUST be set to -1.\n *\n * @return\t\t    An XML message containing the message indication.\n *\t\t\t    NULL will be returned when there's not enough\n *\t\t\t    memory to allocate the message.\n */\nPJ_DECL(pj_xml_node*) pjsip_iscomposing_create_xml(pj_pool_t *pool,\n\t\t\t\t\t\t   pj_bool_t is_composing,\n\t\t\t\t\t\t   const pj_time_val *lst_actv,\n\t\t\t\t\t\t   const pj_str_t *content_tp,\n\t\t\t\t\t\t   int refresh);\n\n\n/**\n * Create message body with Content-Type \"application/im-iscomposing+xml\"\n * to indicate the message composition status.\n *\n * @param pool\t\t    Pool to allocate memory.\n * @param is_composing\t    Message composition indication status. Set to\n *\t\t\t    PJ_TRUE (or non-zero) to indicate that application\n *\t\t\t    is currently composing an instant message.\n * @param lst_actv\t    Optional attribute to indicate time of last\n *\t\t\t    activity. If none is to be specified, the value\n *\t\t\t    MUST be set to NULL.\n * @param content_tp\t    Optional attribute to indicate the content type of\n *\t\t\t    message being composed. If none is to be specified, \n *\t\t\t    the value MUST be set to NULL.\n * @param refresh\t    Optional attribute to indicate the interval when\n *\t\t\t    next indication will be sent, only when \n *\t\t\t    is_composing is non-zero. If none is to be \n *\t\t\t    specified, the value MUST be set to -1.\n *\n * @return\t\t    The SIP message body containing XML message \n *\t\t\t    indication. NULL will be returned when there's not\n *\t\t\t    enough memory to allocate the message.\n */\nPJ_DECL(pjsip_msg_body*) pjsip_iscomposing_create_body( pj_pool_t *pool,\n\t\t\t\t\t\t   pj_bool_t is_composing,\n\t\t\t\t\t\t   const pj_time_val *lst_actv,\n\t\t\t\t\t\t   const pj_str_t *content_tp,\n\t\t\t\t\t\t   int refresh);\n\n\n/**\n * Parse the buffer and return message composition indication in the \n * message.\n *\n * @param pool\t\t    Pool to allocate memory for the parsing process.\n * @param msg\t\t    The message to be parsed.\n * @param len\t\t    Length of the message.\n * @param p_is_composing    Optional pointer to receive iscomposing status.\n * @param p_last_active\t    Optional pointer to receive last active attribute.\n * @param p_content_type    Optional pointer to receive content type attribute.\n * @param p_refresh\t    Optional pointer to receive refresh time.\n *\n * @return\t\t    PJ_SUCCESS if message can be successfully parsed.\n */\nPJ_DECL(pj_status_t) pjsip_iscomposing_parse( pj_pool_t *pool,\n\t\t\t\t\t      char *msg,\n\t\t\t\t\t      pj_size_t len,\n\t\t\t\t\t      pj_bool_t *p_is_composing,\n\t\t\t\t\t      pj_str_t **p_last_active,\n\t\t\t\t\t      pj_str_t **p_content_type,\n\t\t\t\t\t      int *p_refresh );\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJSIP_SIMPLE_ISCOMPOSING_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-simple/mwi.h",
    "content": "/* $Id: mwi.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIMPLE_MWI_H__\n#define __PJSIP_SIMPLE_MWI_H__\n\n/**\n * @file mwi.h\n * @brief SIP Extension for MWI (RFC 3842)\n */\n#include <pjsip-simple/evsub.h>\n#include <pjsip/sip_msg.h>\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup mwi SIP Message Summary and Message Waiting Indication (RFC 3842)\n * @ingroup PJSIP_SIMPLE\n * @brief Support for SIP MWI Extension (RFC 3842)\n * @{\n *\n * This module implements RFC 3842: A Message Summary and Message Waiting\n * Indication Event Package for the Session Initiation Protocol (SIP).\n * It uses the SIP Event Notification framework (evsub.h) and extends the \n * framework by implementing \"message-summary\" event package.\n */\n\n\n/**\n * Initialize the MWI module and register it as endpoint module and\n * package to the event subscription module.\n *\n * @param endpt\t\tThe endpoint instance.\n * @param mod_evsub\tThe event subscription module instance.\n *\n * @return\t\tPJ_SUCCESS if the module is successfully \n *\t\t\tinitialized and registered to both endpoint\n *\t\t\tand the event subscription module.\n */\nPJ_DECL(pj_status_t) pjsip_mwi_init_module(pjsip_endpoint *endpt,\n\t\t\t\t\t   pjsip_module *mod_evsub);\n\n/**\n * Get the MWI module instance.\n *\n * @return\t\tThe MWI module instance.\n */\nPJ_DECL(pjsip_module*) pjsip_mwi_instance(void);\n\n/**\n * Create MWI client subscription session.\n *\n * @param dlg\t\tThe underlying dialog to use.\n * @param user_cb\tPointer to callbacks to receive MWI subscription\n *\t\t\tevents.\n * @param options\tOption flags. Currently only PJSIP_EVSUB_NO_EVENT_ID\n *\t\t\tis recognized.\n * @param p_evsub\tPointer to receive the MWI subscription\n *\t\t\tsession.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_mwi_create_uac( pjsip_dialog *dlg,\n\t\t\t\t\t   const pjsip_evsub_user *user_cb,\n\t\t\t\t\t   unsigned options,\n\t\t\t\t\t   pjsip_evsub **p_evsub );\n\n/**\n * Create MWI server subscription session.\n *\n * @param dlg\t\tThe underlying dialog to use.\n * @param user_cb\tPointer to callbacks to receive MWI subscription\n *\t\t\tevents.\n * @param rdata\t\tThe incoming SUBSCRIBE request that creates the event \n *\t\t\tsubscription.\n * @param p_evsub\tPointer to receive the MWI subscription\n *\t\t\tsession.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_mwi_create_uas( pjsip_dialog *dlg,\n\t\t\t\t\t   const pjsip_evsub_user *user_cb,\n\t\t\t\t\t   pjsip_rx_data *rdata,\n\t\t\t\t\t   pjsip_evsub **p_evsub );\n\n/**\n * Forcefully destroy the MWI subscription. This function should only\n * be called on special condition, such as when the subscription \n * initialization has failed. For other conditions, application MUST terminate\n * the subscription by sending the appropriate un(SUBSCRIBE) or NOTIFY.\n *\n * @param sub\t\tThe MWI subscription.\n * @param notify\tSpecify whether the state notification callback\n *\t\t\tshould be called.\n *\n * @return\t\tPJ_SUCCESS if subscription session has been destroyed.\n */\nPJ_DECL(pj_status_t) pjsip_mwi_terminate( pjsip_evsub *sub,\n\t\t\t\t\t  pj_bool_t notify );\n\n/**\n * Call this function to create request to initiate MWI subscription, to \n * refresh subcription, or to request subscription termination.\n *\n * @param sub\t\tClient subscription instance.\n * @param expires\tSubscription expiration. If the value is set to zero,\n *\t\t\tthis will request unsubscription.\n * @param p_tdata\tPointer to receive the request.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_mwi_initiate( pjsip_evsub *sub,\n\t\t\t\t\t pj_int32_t expires,\n\t\t\t\t\t pjsip_tx_data **p_tdata);\n\n/**\n * Accept the incoming subscription request by sending 2xx response to\n * incoming SUBSCRIBE request.\n *\n * @param sub\t\tServer subscription instance.\n * @param rdata\t\tThe incoming subscription request message.\n * @param st_code\tStatus code, which MUST be final response.\n * @param hdr_list\tOptional list of headers to be added in the response.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_mwi_accept( pjsip_evsub *sub,\n\t\t\t\t       pjsip_rx_data *rdata,\n\t\t\t\t       int st_code,\n\t\t\t\t       const pjsip_hdr *hdr_list );\n\n/**\n * For notifier, create NOTIFY request to subscriber, and set the state \n * of the subscription. \n *\n * @param sub\t\tThe server subscription (notifier) instance.\n * @param state\t\tNew state to set.\n * @param state_str\tThe state string name, if state contains value other\n *\t\t\tthan active, pending, or terminated. Otherwise this\n *\t\t\targument is ignored.\n * @param reason\tSpecify reason if new state is terminated, otherwise\n *\t\t\tput NULL.\n * @param mime_type\tMIME type/content type of the message body.\n * @param body\t\tMessage body to be included in the NOTIFY request.\n * @param p_tdata\tPointer to receive the request.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_mwi_notify( pjsip_evsub *sub,\n\t\t\t\t       pjsip_evsub_state state,\n\t\t\t\t       const pj_str_t *state_str,\n\t\t\t\t       const pj_str_t *reason,\n\t\t\t\t       const pjsip_media_type *mime_type,\n\t\t\t\t       const pj_str_t *body,\n\t\t\t\t       pjsip_tx_data **p_tdata);\n\n/**\n * Create NOTIFY request containing message body from the last NOITFY\n * message created.\n *\n * @param sub\t\tServer subscription object.\n * @param p_tdata\tPointer to receive request.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_mwi_current_notify( pjsip_evsub *sub,\n\t\t\t\t\t       pjsip_tx_data **p_tdata );\n\n\n/**\n * Send request message that was previously created with initiate(), notify(),\n * or current_notify(). Application may also send request created with other\n * functions, e.g. authentication. But the request MUST be either request\n * that creates/refresh subscription or NOTIFY request.\n *\n * @param sub\t\tThe subscription object.\n * @param tdata\t\tRequest message to be sent.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_mwi_send_request( pjsip_evsub *sub,\n\t\t\t\t\t     pjsip_tx_data *tdata );\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJSIP_SIMPLE_MWI_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-simple/pidf.h",
    "content": "/* $Id: pidf.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIMPLE_PIDF_H__\n#define __PJSIP_SIMPLE_PIDF_H__\n\n/**\n * @file pidf.h\n * @brief PIDF/Presence Information Data Format (RFC 3863)\n */\n#include <pjsip-simple/types.h>\n#include <pjlib-util/xml.h>\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJSIP_SIMPLE_PIDF PIDF/Presence Information Data Format (RFC 3863)\n * @ingroup PJSIP_SIMPLE\n * @brief Support for PIDF/Presence Information Data Format (RFC 3863)\n * @{\n *\n * This file provides tools for manipulating Presence Information Data \n * Format (PIDF) as described in RFC 3863.\n */\ntypedef struct pj_xml_node pjpidf_pres;\ntypedef struct pj_xml_node pjpidf_tuple;\ntypedef struct pj_xml_node pjpidf_status;\ntypedef struct pj_xml_node pjpidf_note;\n\ntypedef struct pjpidf_status_op\n{\n    void\t    (*construct)(pj_pool_t*, pjpidf_status*);\n    pj_bool_t\t    (*is_basic_open)(const pjpidf_status*);\n    void\t    (*set_basic_open)(pjpidf_status*, pj_bool_t);\n} pjpidf_status_op;\n\ntypedef struct pjpidf_tuple_op\n{\n    void\t    (*construct)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*);\n\n    const pj_str_t* (*get_id)(const pjpidf_tuple* );\n    void\t    (*set_id)(pj_pool_t*, pjpidf_tuple *, const pj_str_t*);\n\n    pjpidf_status*  (*get_status)(pjpidf_tuple* );\n\n    const pj_str_t* (*get_contact)(const pjpidf_tuple*);\n    void\t    (*set_contact)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*);\n    void\t    (*set_contact_prio)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*);\n    const pj_str_t* (*get_contact_prio)(const pjpidf_tuple*);\n\n    pjpidf_note*    (*add_note)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*);\n    pjpidf_note*    (*get_first_note)(pjpidf_tuple*);\n    pjpidf_note*    (*get_next_note)(pjpidf_tuple*, pjpidf_note*);\n\n    const pj_str_t* (*get_timestamp)(const pjpidf_tuple*);\n    void\t    (*set_timestamp)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*);\n    void\t    (*set_timestamp_np)(pj_pool_t*,pjpidf_tuple*, pj_str_t*);\n\n} pjpidf_tuple_op;\n\ntypedef struct pjpidf_pres_op\n{\n    void\t    (*construct)(pj_pool_t*, pjpidf_pres*, const pj_str_t*);\n\n    pjpidf_tuple*   (*add_tuple)(pj_pool_t*, pjpidf_pres*, const pj_str_t*);\n    pjpidf_tuple*   (*get_first_tuple)(pjpidf_pres*);\n    pjpidf_tuple*   (*get_next_tuple)(pjpidf_pres*, pjpidf_tuple*);\n    pjpidf_tuple*   (*find_tuple)(pjpidf_pres*, const pj_str_t*);\n    void\t    (*remove_tuple)(pjpidf_pres*, pjpidf_tuple*);\n\n    pjpidf_note*    (*add_note)(pj_pool_t*, pjpidf_pres*, const pj_str_t*);\n    pjpidf_note*    (*get_first_note)(pjpidf_pres*);\n    pjpidf_note*    (*get_next_note)(pjpidf_pres*, pjpidf_note*);\n\n} pjpidf_pres_op;\n\n\nextern struct pjpidf_op_desc\n{\n    pjpidf_pres_op\tpres;\n    pjpidf_tuple_op\ttuple;\n    pjpidf_status_op\tstatus;\n} pjpidf_op;\n\n\n/******************************************************************************\n * Top level API for managing presence document. \n *****************************************************************************/\nPJ_DECL(pjpidf_pres*)    pjpidf_create(pj_pool_t *pool, const pj_str_t *entity);\nPJ_DECL(pjpidf_pres*)\t pjpidf_parse(pj_pool_t *pool, char *text, int len);\nPJ_DECL(int)\t\t pjpidf_print(const pjpidf_pres* pres, char *buf, int len);\n\n\n/******************************************************************************\n * API for managing Presence node.\n *****************************************************************************/\nPJ_DECL(void)\t\t pjpidf_pres_construct(pj_pool_t *pool, pjpidf_pres *pres,\n\t\t\t\t\t       const pj_str_t *entity);\nPJ_DECL(pjpidf_tuple*)\t pjpidf_pres_add_tuple(pj_pool_t *pool, pjpidf_pres *pres, \n\t\t\t\t\t       const pj_str_t *id);\nPJ_DECL(pjpidf_tuple*)\t pjpidf_pres_get_first_tuple(pjpidf_pres *pres);\nPJ_DECL(pjpidf_tuple*)\t pjpidf_pres_get_next_tuple(pjpidf_pres *pres, \n\t\t\t\t\t\t    pjpidf_tuple *t);\nPJ_DECL(pjpidf_tuple*)\t pjpidf_pres_find_tuple(pjpidf_pres *pres, \n\t\t\t\t\t\tconst pj_str_t *id);\nPJ_DECL(void)\t\t pjpidf_pres_remove_tuple(pjpidf_pres *pres, \n\t\t\t\t\t\t  pjpidf_tuple*);\n\nPJ_DECL(pjpidf_note*)\t pjpidf_pres_add_note(pj_pool_t *pool, pjpidf_pres *pres, \n\t\t\t\t\t      const pj_str_t *text);\nPJ_DECL(pjpidf_note*)\t pjpidf_pres_get_first_note(pjpidf_pres *pres);\nPJ_DECL(pjpidf_note*)\t pjpidf_pres_get_next_note(pjpidf_pres*, pjpidf_note*);\n\n\n/******************************************************************************\n * API for managing Tuple node.\n *****************************************************************************/\nPJ_DECL(void)\t\t pjpidf_tuple_construct(pj_pool_t *pool, pjpidf_tuple *t,\n\t\t\t\t\t\tconst pj_str_t *id);\nPJ_DECL(const pj_str_t*) pjpidf_tuple_get_id(const pjpidf_tuple *t );\nPJ_DECL(void)\t\t pjpidf_tuple_set_id(pj_pool_t *pool, pjpidf_tuple *t, \n\t\t\t\t\t     const pj_str_t *id);\n\nPJ_DECL(pjpidf_status*)  pjpidf_tuple_get_status(pjpidf_tuple *t);\n\nPJ_DECL(const pj_str_t*) pjpidf_tuple_get_contact(const pjpidf_tuple *t);\nPJ_DECL(void)\t\t pjpidf_tuple_set_contact(pj_pool_t *pool, pjpidf_tuple *t, \n\t\t\t\t\t\t  const pj_str_t *contact);\nPJ_DECL(void)\t\t pjpidf_tuple_set_contact_prio(pj_pool_t *pool, pjpidf_tuple *t, \n\t\t\t\t\t\t       const pj_str_t *prio);\nPJ_DECL(const pj_str_t*) pjpidf_tuple_get_contact_prio(const pjpidf_tuple *t);\n\nPJ_DECL(pjpidf_note*)\t pjpidf_tuple_add_note(pj_pool_t *pool, pjpidf_tuple *t,\n\t\t\t\t\t       const pj_str_t *text);\nPJ_DECL(pjpidf_note*)\t pjpidf_tuple_get_first_note(pjpidf_tuple *t);\nPJ_DECL(pjpidf_note*)\t pjpidf_tuple_get_next_note(pjpidf_tuple *t, pjpidf_note *n);\n\nPJ_DECL(const pj_str_t*) pjpidf_tuple_get_timestamp(const pjpidf_tuple *t);\nPJ_DECL(void)\t\t pjpidf_tuple_set_timestamp(pj_pool_t *pool, pjpidf_tuple *t,\n\t\t\t\t\t\t    const pj_str_t *ts);\nPJ_DECL(void)\t\t pjpidf_tuple_set_timestamp_np(\tpj_pool_t*, pjpidf_tuple *t,\n\t\t\t\t\t\t\tpj_str_t *ts);\n\n\n/******************************************************************************\n * API for managing Status node.\n *****************************************************************************/\nPJ_DECL(void)\t\t pjpidf_status_construct(pj_pool_t*, pjpidf_status*);\nPJ_DECL(pj_bool_t)\t pjpidf_status_is_basic_open(const pjpidf_status*);\nPJ_DECL(void)\t\t pjpidf_status_set_basic_open(pjpidf_status*, pj_bool_t);\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJSIP_SIMPLE_PIDF_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-simple/presence.h",
    "content": "/* $Id: presence.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIMPLE_PRESENCE_H__\n#define __PJSIP_SIMPLE_PRESENCE_H__\n\n/**\n * @file presence.h\n * @brief SIP Extension for Presence (RFC 3856)\n */\n#include <pjsip-simple/evsub.h>\n#include <pjsip-simple/pidf.h>\n#include <pjsip-simple/xpidf.h>\n#include <pjsip-simple/rpid.h>\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJSIP_SIMPLE_PRES SIP Extension for Presence (RFC 3856)\n * @ingroup PJSIP_SIMPLE\n * @brief Support for SIP Extension for Presence (RFC 3856)\n * @{\n *\n * This module contains the implementation of SIP Presence Extension as \n * described in RFC 3856. It uses the SIP Event Notification framework\n * (evsub.h) and extends the framework by implementing \"presence\"\n * event package.\n */\n\n\n\n/**\n * Initialize the presence module and register it as endpoint module and\n * package to the event subscription module.\n *\n * @param endpt\t\tThe endpoint instance.\n * @param mod_evsub\tThe event subscription module instance.\n *\n * @return\t\tPJ_SUCCESS if the module is successfully \n *\t\t\tinitialized and registered to both endpoint\n *\t\t\tand the event subscription module.\n */\nPJ_DECL(pj_status_t) pjsip_pres_init_module(pjsip_endpoint *endpt,\n\t\t\t\t\t    pjsip_module *mod_evsub);\n\n\n/**\n * Get the presence module instance.\n *\n * @return\t\tThe presence module instance.\n */\nPJ_DECL(pjsip_module*) pjsip_pres_instance(void);\n\n\n/**\n * Maximum presence status info.\n */\n#define PJSIP_PRES_STATUS_MAX_INFO  8\n\n\n/**\n * This structure describes presence status of a presentity.\n */\nstruct pjsip_pres_status\n{\n    unsigned\t\tinfo_cnt;\t/**< Number of info in the status.  */\n    struct {\n\n\tpj_bool_t\tbasic_open;\t/**< Basic status/availability.\t    */\n\tpjrpid_element\trpid;\t\t/**< Optional RPID info.\t    */\n\n\tpj_str_t\tid;\t\t/**< Tuple id.\t\t\t    */\n\tpj_str_t\tcontact;\t/**< Optional contact address.\t    */\n\n\tpj_xml_node    *tuple_node;\t/**< Pointer to tuple XML node of\n\t\t\t\t\t     parsed PIDF body received from\n\t\t\t\t\t     remote agent. Only valid for\n\t\t\t\t\t     client subscription. If the\n\t\t\t\t\t     last received NOTIFY request\n\t\t\t\t\t     does not contain any PIDF body,\n\t\t\t\t\t     this valud will be set to NULL */\n\n    } info[PJSIP_PRES_STATUS_MAX_INFO];\t/**< Array of info.\t\t    */\n\n    pj_bool_t\t\t_is_valid;\t/**< Internal flag.\t\t    */\n};\n\n\n/**\n * @see pjsip_pres_status\n */\ntypedef struct pjsip_pres_status pjsip_pres_status;\n\n\n/**\n * Create presence client subscription session.\n *\n * @param dlg\t\tThe underlying dialog to use.\n * @param user_cb\tPointer to callbacks to receive presence subscription\n *\t\t\tevents.\n * @param options\tOption flags. Currently only PJSIP_EVSUB_NO_EVENT_ID\n *\t\t\tis recognized.\n * @param p_evsub\tPointer to receive the presence subscription\n *\t\t\tsession.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_pres_create_uac( pjsip_dialog *dlg,\n\t\t\t\t\t    const pjsip_evsub_user *user_cb,\n\t\t\t\t\t    unsigned options,\n\t\t\t\t\t    pjsip_evsub **p_evsub );\n\n\n/**\n * Create presence server subscription session.\n *\n * @param dlg\t\tThe underlying dialog to use.\n * @param user_cb\tPointer to callbacks to receive presence subscription\n *\t\t\tevents.\n * @param rdata\t\tThe incoming SUBSCRIBE request that creates the event \n *\t\t\tsubscription.\n * @param p_evsub\tPointer to receive the presence subscription\n *\t\t\tsession.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_pres_create_uas( pjsip_dialog *dlg,\n\t\t\t\t\t    const pjsip_evsub_user *user_cb,\n\t\t\t\t\t    pjsip_rx_data *rdata,\n\t\t\t\t\t    pjsip_evsub **p_evsub );\n\n\n/**\n * Forcefully destroy the presence subscription. This function should only\n * be called on special condition, such as when the subscription \n * initialization has failed. For other conditions, application MUST terminate\n * the subscription by sending the appropriate un(SUBSCRIBE) or NOTIFY.\n *\n * @param sub\t\tThe presence subscription.\n * @param notify\tSpecify whether the state notification callback\n *\t\t\tshould be called.\n *\n * @return\t\tPJ_SUCCESS if subscription session has been destroyed.\n */\nPJ_DECL(pj_status_t) pjsip_pres_terminate( pjsip_evsub *sub,\n\t\t\t\t\t   pj_bool_t notify );\n\n\n\n/**\n * Call this function to create request to initiate presence subscription, to \n * refresh subcription, or to request subscription termination.\n *\n * @param sub\t\tClient subscription instance.\n * @param expires\tSubscription expiration. If the value is set to zero,\n *\t\t\tthis will request unsubscription.\n * @param p_tdata\tPointer to receive the request.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_pres_initiate( pjsip_evsub *sub,\n\t\t\t\t\t  pj_int32_t expires,\n\t\t\t\t\t  pjsip_tx_data **p_tdata);\n\n\n/**\n * Add a list of headers to the subscription instance. The list of headers\n * will be added to outgoing presence subscription requests.\n *\n * @param sub\t\tSubscription instance.\n * @param hdr_list\tList of headers to be added.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_pres_add_header( pjsip_evsub *sub,\n\t\t\t\t\t    const pjsip_hdr *hdr_list );\n\n\n/**\n * Accept the incoming subscription request by sending 2xx response to\n * incoming SUBSCRIBE request.\n *\n * @param sub\t\tServer subscription instance.\n * @param rdata\t\tThe incoming subscription request message.\n * @param st_code\tStatus code, which MUST be final response.\n * @param hdr_list\tOptional list of headers to be added in the response.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_pres_accept( pjsip_evsub *sub,\n\t\t\t\t\tpjsip_rx_data *rdata,\n\t\t\t\t        int st_code,\n\t\t\t\t\tconst pjsip_hdr *hdr_list );\n\n\n\n\n/**\n * For notifier, create NOTIFY request to subscriber, and set the state \n * of the subscription. Application MUST set the presence status to the\n * appropriate state (by calling #pjsip_pres_set_status()) before calling\n * this function.\n *\n * @param sub\t\tThe server subscription (notifier) instance.\n * @param state\t\tNew state to set.\n * @param state_str\tThe state string name, if state contains value other\n *\t\t\tthan active, pending, or terminated. Otherwise this\n *\t\t\targument is ignored.\n * @param reason\tSpecify reason if new state is terminated, otherwise\n *\t\t\tput NULL.\n * @param p_tdata\tPointer to receive the request.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_pres_notify( pjsip_evsub *sub,\n\t\t\t\t\tpjsip_evsub_state state,\n\t\t\t\t\tconst pj_str_t *state_str,\n\t\t\t\t\tconst pj_str_t *reason,\n\t\t\t\t\tpjsip_tx_data **p_tdata);\n\n\n/**\n * Create NOTIFY request to reflect current subscription status.\n *\n * @param sub\t\tServer subscription object.\n * @param p_tdata\tPointer to receive request.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_pres_current_notify( pjsip_evsub *sub,\n\t\t\t\t\t        pjsip_tx_data **p_tdata );\n\n\n\n/**\n * Send request message that was previously created with initiate(), notify(),\n * or current_notify(). Application may also send request created with other\n * functions, e.g. authentication. But the request MUST be either request\n * that creates/refresh subscription or NOTIFY request.\n *\n * @param sub\t\tThe subscription object.\n * @param tdata\t\tRequest message to be sent.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_pres_send_request( pjsip_evsub *sub,\n\t\t\t\t\t      pjsip_tx_data *tdata );\n\n\n/**\n * Get the presence status. Client normally would call this function\n * after receiving NOTIFY request from server.\n *\n * @param sub\t\tThe client or server subscription.\n * @param status\tThe structure to receive presence status.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_pres_get_status( pjsip_evsub *sub,\n\t\t\t\t\t    pjsip_pres_status *status );\n\n\n/**\n * Set the presence status. This operation is only valid for server\n * subscription. After calling this function, application would need to\n * send NOTIFY request to client.\n *\n * @param sub\t\tThe server subscription.\n * @param status\tStatus to be set.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_pres_set_status( pjsip_evsub *sub,\n\t\t\t\t\t    const pjsip_pres_status *status );\n\n\n/**\n * This is a utility function to create PIDF message body from PJSIP\n * presence status (pjsip_pres_status).\n *\n * @param pool\t\tThe pool to allocate memory for the message body.\n * @param status\tPresence status to be converted into PIDF message\n *\t\t\tbody.\n * @param entity\tThe entity ID, which normally is equal to the \n *\t\t\tpresentity ID publishing this presence info.\n * @param p_body\tPointer to receive the SIP message body.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_pres_create_pidf( pj_pool_t *pool,\n\t\t\t\t\t     const pjsip_pres_status *status,\n\t\t\t\t\t     const pj_str_t *entity,\n\t\t\t\t\t     pjsip_msg_body **p_body );\n\n\n/**\n * This is a utility function to create X-PIDF message body from PJSIP\n * presence status (pjsip_pres_status).\n *\n * @param pool\t\tThe pool to allocate memory for the message body.\n * @param status\tPresence status to be converted into X-PIDF message\n *\t\t\tbody.\n * @param entity\tThe entity ID, which normally is equal to the \n *\t\t\tpresentity ID publishing this presence info.\n * @param p_body\tPointer to receive the SIP message body.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_pres_create_xpidf(pj_pool_t *pool,\n\t\t\t\t\t     const pjsip_pres_status *status,\n\t\t\t\t\t     const pj_str_t *entity,\n\t\t\t\t\t     pjsip_msg_body **p_body );\n\n\n\n/**\n * This is a utility function to parse PIDF body into PJSIP presence status.\n *\n * @param rdata\t\tThe incoming SIP message containing the PIDF body.\n * @param pool\t\tPool to allocate memory to copy the strings into\n *\t\t\tthe presence status structure.\n * @param status\tThe presence status to be initialized.\n *\n * @return\t\tPJ_SUCCESS on success.\n *\n * @see pjsip_pres_parse_pidf2()\n */\nPJ_DECL(pj_status_t) pjsip_pres_parse_pidf(pjsip_rx_data *rdata,\n\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t   pjsip_pres_status *status);\n\n/**\n * This is a utility function to parse PIDF body into PJSIP presence status.\n *\n * @param body\t\tText body, with one extra space at the end to place\n * \t\t\tNULL character temporarily during parsing.\n * @param body_len\tLength of the body, not including the NULL termination\n * \t\t\tcharacter.\n * @param pool\t\tPool to allocate memory to copy the strings into\n *\t\t\tthe presence status structure.\n * @param status\tThe presence status to be initialized.\n *\n * @return\t\tPJ_SUCCESS on success.\n *\n * @see pjsip_pres_parse_pidf()\n */\nPJ_DECL(pj_status_t) pjsip_pres_parse_pidf2(char *body, unsigned body_len,\n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    pjsip_pres_status *status);\n\n\n/**\n * This is a utility function to parse X-PIDF body into PJSIP presence status.\n *\n * @param rdata\t\tThe incoming SIP message containing the X-PIDF body.\n * @param pool\t\tPool to allocate memory to copy the strings into\n *\t\t\tthe presence status structure.\n * @param status\tThe presence status to be initialized.\n *\n * @return\t\tPJ_SUCCESS on success.\n *\n * @see pjsip_pres_parse_xpidf2()\n */\nPJ_DECL(pj_status_t) pjsip_pres_parse_xpidf(pjsip_rx_data *rdata,\n\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t   pjsip_pres_status *status);\n\n\n/**\n * This is a utility function to parse X-PIDF body into PJSIP presence status.\n *\n * @param body\t\tText body, with one extra space at the end to place\n * \t\t\tNULL character temporarily during parsing.\n * @param body_len\tLength of the body, not including the NULL termination\n * \t\t\tcharacter.\n * @param pool\t\tPool to allocate memory to copy the strings into\n *\t\t\tthe presence status structure.\n * @param status\tThe presence status to be initialized.\n *\n * @return\t\tPJ_SUCCESS on success.\n *\n * @see pjsip_pres_parse_xpidf()\n */\nPJ_DECL(pj_status_t) pjsip_pres_parse_xpidf2(char *body, unsigned body_len,\n\t\t\t\t\t     pj_pool_t *pool,\n\t\t\t\t\t     pjsip_pres_status *status);\n\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJSIP_SIMPLE_PRESENCE_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-simple/publish.h",
    "content": "/* $Id: publish.h 4173 2012-06-20 10:39:05Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIMPLE_PUBLISH_H__\n#define __PJSIP_SIMPLE_PUBLISH_H__\n\n/**\n * @file publish.h\n * @brief SIP Extension for Event State Publication (PUBLISH, RFC 3903)\n */\n\n#include <pjsip/sip_util.h>\n#include <pjsip/sip_auth.h>\n\n\nPJ_BEGIN_DECL\n\n\n/**\n @defgroup PJSIP_SIMPLE_PUBLISH SIP Event State Publication (PUBLISH, RFC 3903)\n @ingroup PJSIP_SIMPLE\n @brief Support for SIP Event State Publication (PUBLISH, RFC 3903)\n @{\n\n This module contains the implementation of Session Initiation Protocol (SIP)\n Extension for Event State Publication (PUBLISH) as defined by RFC 3903.\n */\n\n/**\n * The SIP PUBLISH method constant.\n */\nextern const pjsip_method pjsip_publish_method;\n\n\n/*****************************************************************************\n * @defgroup PJSIP_SIMPLE_PUBLISH_CLIENT SIP Event State Publication Client\n * @ingroup PJSIP_SIMPLE\n * @brief Event State Publication Clien\n * @{\n */\n\n\n/** Expiration not specified. */\n#define PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED\t((pj_uint32_t)0xFFFFFFFFUL)\n\n/**\n * Opaque declaration for client side event publication session.\n */\ntypedef struct pjsip_publishc pjsip_publishc;\n\n\n/**\n * Client publication options. Application should initialize this structure\n * with its default values by calling #pjsip_publishc_opt_default()\n */\ntypedef struct pjsip_publishc_opt\n{\n    /**\n     * Specify whether the client publication session should queue the\n     * PUBLISH request should there be another PUBLISH transaction still\n     * pending. If this is set to false, the client will return error\n     * on the PUBLISH request if there is another PUBLISH transaction still\n     * in progress.\n     *\n     * Default: PJSIP_PUBLISHC_QUEUE_REQUEST\n     */\n    pj_bool_t\tqueue_request;\n\n} pjsip_publishc_opt;\n\n\n/** Structure to hold parameters when calling application's callback.\n *  The application's callback is called when the client publication process\n *  has finished.\n */\nstruct pjsip_publishc_cbparam\n{\n    pjsip_publishc\t*pubc;\t    /**< Client publication structure.\t    */\n    void\t\t*token;\t    /**< Arbitrary token.\t\t    */\n    pj_status_t\t\t status;    /**< Error status.\t\t\t    */\n    int\t\t\t code;\t    /**< SIP status code received.\t    */\n    pj_str_t\t\t reason;    /**< SIP reason phrase received.\t    */\n    pjsip_rx_data\t*rdata;\t    /**< The complete received response.    */\n    int\t\t\t expiration;/**< Next expiration interval. If the\n\t\t\t\t\t value is -1, it means the session\n\t\t\t\t\t will not renew itself.\t\t    */\n};\n\n\n/** Type declaration for callback to receive publication result. */\ntypedef void pjsip_publishc_cb(struct pjsip_publishc_cbparam *param);\n\n\n/**\n * Initialize client publication session option with default values.\n *\n * @param opt\t    The option.\n */\nPJ_DECL(void) pjsip_publishc_opt_default(pjsip_publishc_opt *opt);\n\n\n/**\n * Initialize client publication module.\n *\n * @param endpt\t    SIP endpoint.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_publishc_init_module(pjsip_endpoint *endpt);\n\n\n/**\n * Create client publication structure.\n *\n * @param endpt\t    Endpoint, used to allocate pool from.\n * @param opt\t    Options, or NULL to specify default options.\n * @param token\t    Opaque data to be associated with the client publication.\n * @param cb\t    Pointer to callback function to receive publication status.\n * @param p_pubc    Pointer to receive client publication structure.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_publishc_create( pjsip_endpoint *endpt, \n\t\t\t\t\t    const pjsip_publishc_opt *opt,\n\t\t\t\t\t    void *token,\n\t\t\t\t            pjsip_publishc_cb *cb, \n\t\t\t\t\t    pjsip_publishc **p_pubc);\n\n\n/**\n * Destroy client publication structure. If a publication transaction is\n * in progress, then the structure will be deleted only after a final response\n * has been received, and in this case, the callback won't be called.\n *\n * @param pubc\t    The client publication structure.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_publishc_destroy(pjsip_publishc *pubc);\n\n\n\n/**\n * Get the memory pool associated with a publication client session.\n *\n * @param pubc\t    The client publication structure.\n * @return pool\t    handle.\n */\nPJ_DECL(pj_pool_t*) pjsip_publishc_get_pool(pjsip_publishc *pubc);\n\n\n/**\n * Initialize client publication structure with various information needed to\n * perform the publication.\n *\n * @param pubc\t\tThe client publication structure.\n * @param event\t\tThe Event identification (e.g. \"presence\").\n * @param target_uri\tThe URI of the presentity which the which the status\n *\t\t\tis being published.\n * @param from_uri\tThe URI of the endpoint who sends the event \n *\t\t\tpublication. Normally the value would be the same as\n *\t\t\ttarget_uri.\n * @param to_uri\tThe URI to be put in To header. Normally the value \n *\t\t\twould be the same as target_uri.\n * @param expires\tThe default expiration of the event publication. \n *\t\t\tIf the value PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED is \n *\t\t\tgiven, then no default expiration will be applied.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_publishc_init(pjsip_publishc *pubc,\n\t\t\t\t\t const pj_str_t *event,\n\t\t\t\t\t const pj_str_t *target_uri,\n\t\t\t\t\t const pj_str_t *from_uri,\n\t\t\t\t\t const pj_str_t *to_uri,\n\t\t\t\t\t pj_uint32_t expires);\n\n\n/**\n * Set authentication credentials to use by this publication.\n *\n * @param pubc\t    The publication structure.\n * @param count\t    Number of credentials in the array.\n * @param c\t    Array of credentials.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_publishc_set_credentials(pjsip_publishc *pubc,\n\t\t\t\t\t\t    int count,\n\t\t\t\t\t\t    const pjsip_cred_info c[]);\n\n/**\n * Set route set to be used for outgoing requests.\n *\n * @param pubc\t    The client publication structure.\n * @param rs\t    List containing Route headers.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_publishc_set_route_set(pjsip_publishc *pubc,\n\t\t\t\t\t\t  const pjsip_route_hdr *rs);\n\n\n/**\n * Set list of headers to be added to each PUBLISH request generated by\n * the client publication session. Note that application can also add\n * the headers to the request after calling #pjsip_publishc_publish()\n * or #pjsip_publishc_unpublish(), but the benefit of this function is\n * the headers will also be added to requests generated internally by\n * the session, such as during session renewal/refresh.\n *\n * Note that calling this function will clear the previously added list\n * of headers.\n *\n * @param pubc\t    The client publication structure.\n * @param hdr_list  The list of headers.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_publishc_set_headers(pjsip_publishc *pubc,\n\t\t\t\t\t\tconst pjsip_hdr *hdr_list);\n\n/**\n * Set the \"sent-by\" field of the Via header for outgoing requests.\n *\n * @param pubc\t    The client publication structure.\n * @param via_addr  Set via_addr to use for the Via header or NULL to use\n *                  the transport's published name.\n * @param via_tp    via_addr will only be used if we are using via_tp\n *                  transport.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_publishc_set_via_sent_by(pjsip_publishc *pubc,\n\t\t\t\t                    pjsip_host_port *via_addr,\n                                                    pjsip_transport *via_tp);\n\n\n/**\n * Create PUBLISH request for the specified client publication structure.\n * Application can use this function to both create initial publication\n * or to modify existing publication. \n *\n * After the PUBLISH request is created, application MUST fill in the\n * body part of the request with the appropriate content for the Event\n * being published.\n *\n * Note that publication refresh are handled automatically by the session\n * (as long as auto_refresh argument below is non-zero), and application\n * should not use this function to perform publication refresh.\n *\n * @param pubc\t\tThe client publication session.\n * @param auto_refresh\tIf non zero, the library will automatically \n *\t\t\trefresh the next publication until application \n *\t\t\tunpublish.\n * @param p_tdata\tPointer to receive the PUBLISH request. Note that\n *\t\t\tthe request DOES NOT have a message body.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_publishc_publish(pjsip_publishc *pubc, \n\t\t\t\t\t     pj_bool_t auto_refresh,\n\t\t\t\t\t     pjsip_tx_data **p_tdata);\n\n\n/**\n * Create PUBLISH request to unpublish the current client publication.\n *\n * @param pubc\t    The client publication structure.\n * @param p_tdata   Pointer to receive the PUBLISH request.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_publishc_unpublish(pjsip_publishc *pubc,\n\t\t\t\t\t      pjsip_tx_data **p_tdata);\n\n\n/**\n * Update the client publication expiration value. Note that this DOES NOT\n * automatically send outgoing PUBLISH request to update the publication\n * session. If application wants to do this, then it must construct a\n * PUBLISH request and send it to the server.\n *\n * @param pubc\t    The client publication structure.\n * @param expires   The new expires value.\n *\n * @return\t    PU_SUCCESS on successfull.\n */\nPJ_DECL(pj_status_t) pjsip_publishc_update_expires(pjsip_publishc *pubc,\n\t\t\t\t\t           pj_uint32_t expires );\n\n\n/**\n * Sends outgoing PUBLISH request. The process will complete asynchronously,\n * and application will be notified via the callback when the process \n * completes.\n *\n * If the session has another PUBLISH request outstanding, the behavior\n * depends on whether request queueing is enabled in the session (this was\n * set by setting \\a queue_request field of #pjsip_publishc_opt to true\n * when calling #pjsip_publishc_create(). Default is true). If request\n * queueing is enabled, the request will be queued and the function will \n * return PJ_EPENDING. One the outstanding request is complete, the queued\n * request will be sent automatically. If request queueing is disabled, the\n * function will reject the request and return PJ_EBUSY.\n *\n * @param pubc\t    The client publication structure.\n * @param tdata\t    Transmit data.\n *\n * @return\t    - PJ_SUCCESS on success, or \n *\t\t    - PJ_EPENDING if request is queued, or\n *\t\t    - PJ_EBUSY if request is rejected because another PUBLISH\n *\t\t      request is in progress, or\n *\t\t    - other status code to indicate the error.\n */\nPJ_DECL(pj_status_t) pjsip_publishc_send(pjsip_publishc *pubc, \n\t\t\t\t\t pjsip_tx_data *tdata);\n\n\n\n/**\n * @}\n */\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJSIP_SIMPLE_PUBLISH_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-simple/rpid.h",
    "content": "/* $Id: rpid.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIMPLE_RPID_H__\n#define __PJSIP_SIMPLE_RPID_H__\n\n/**\n * @file rpid.h\n * @brief RPID: Rich Presence Extensions to the PIDF (RFC 4480)\n */\n#include <pjsip-simple/types.h>\n#include <pjsip-simple/pidf.h>\n\nPJ_BEGIN_DECL\n\n\n/**\n * @defgroup PJSIP_SIMPLE_RPID RPID/Rich Presence Extensions to PIDF (RFC 4480)\n * @ingroup PJSIP_SIMPLE\n * @brief RPID/Rich Presence Extensions to PIDF (RFC 4480)\n * @{\n *\n * This file provides tools for managing subset of RPID elements into\n * PIDF document.\n */\n\n/**\n * This enumeration describes subset of standard activities as \n * described by RFC 4880, RPID: Rich Presence Extensions to the \n * Presence Information Data Format (PIDF). \n */\ntypedef enum pjrpid_activity\n{\n    /** Activity is unknown. The activity would then be conceived\n     *  in the \"note\" field.\n     */\n    PJRPID_ACTIVITY_UNKNOWN,\n\n    /** The person is away */\n    PJRPID_ACTIVITY_AWAY,\n\n    /** The person is busy */\n    PJRPID_ACTIVITY_BUSY\n\n} pjrpid_activity;\n\n\n/**\n * This enumeration describes types of RPID element.\n */\ntypedef enum pjrpid_element_type\n{\n    /** RPID <person> element */\n    PJRPID_ELEMENT_TYPE_PERSON\n\n} pjrpid_element_type;\n\n\n/**\n * This structure describes person information in RPID document.\n */\ntypedef struct pjrpid_element\n{\n    /** Element type. */\n    pjrpid_element_type\t    type;\n\n    /** Optional id to set on the element. */\n    pj_str_t\t\t    id;\n\n    /** Activity type. */\n    pjrpid_activity\t    activity;\n\n    /** Optional text describing the person/element. */\n    pj_str_t\t\t    note;\n\n} pjrpid_element;\n\n\n/**\n * Duplicate RPID element.\n *\n * @param pool\t    Pool.\n * @param dst\t    Destination structure.\n * @param src\t    Source structure.\n */\nPJ_DECL(void) pjrpid_element_dup(pj_pool_t *pool, pjrpid_element *dst,\n\t\t\t\t const pjrpid_element *src);\n\n\n/**\n * Add RPID element information into existing PIDF document. This will also\n * add the appropriate XML namespace attributes into the presence's XML\n * node, if the attributes are not already present, and also a <note> element\n * to the first <tuple> element of the PIDF document.\n *\n * @param pres\t    The PIDF presence document.\n * @param pool\t    Pool.\n * @param options   Currently unused, and must be zero.\n * @param elem\t    RPID element information to be added into the PIDF\n *\t\t    document.\n *\n * @return PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjrpid_add_element(pjpidf_pres *pres,\n\t\t\t\t        pj_pool_t *pool,\n\t\t\t\t\tunsigned options,\n\t\t\t\t        const pjrpid_element *elem);\n\n/**\n * Get RPID element information from PIDF document, if any.\n *\n * @param pres\t    The PIDF document containing RPID elements.\n * @param pool\t    Pool to duplicate the information.\n * @param elem\t    Structure to receive the element information.\n *\n * @return PJ_SUCCESS\tif the document does contain RPID element\n *\t\t\tand the information has been parsed successfully.\n */\nPJ_DECL(pj_status_t) pjrpid_get_element(const pjpidf_pres *pres,\n\t\t\t\t        pj_pool_t *pool,\n\t\t\t\t        pjrpid_element *elem);\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n\n#endif\t/* __PJSIP_SIMPLE_RPID_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-simple/types.h",
    "content": "/* $Id: types.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIMPLE_TYPES_H__\n#define __PJSIP_SIMPLE_TYPES_H__\n\n#include <pjsip/sip_types.h>\n\n\n#define PJSIP_EVSUB_POOL_LEN\t4000\n#define PJSIP_EVSUB_POOL_INC\t4000\n\n\n#endif\t/* __PJSIP_SIMPLE_TYPES_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-simple/xpidf.h",
    "content": "/* $Id: xpidf.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIMPLE_XPIDF_H__\n#define __PJSIP_SIMPLE_XPIDF_H__\n\n/**\n * @file xpidf.h\n * @brief XPIDF/Presence Information Data Format\n */\n#include <pjsip-simple/types.h>\n#include <pjlib-util/xml.h>\n\nPJ_BEGIN_DECL\n\n/**\n * @defgroup PJSIP_SIMPLE_XPIDF XPIDF/Presence Information Data Format\n * @ingroup PJSIP_SIMPLE\n * @brief Support for XPIDF/Presence Information Data Format\n * @{\n *\n * This is an old presence data format as described in:\n * draft-rosenberg-impp-pidf-00.txt.\n *\n * We won't support this format extensively here, as it seems there's not\n * too many implementations support this anymore, as it shouldn't.\n */\n\n/** Type definitions for XPIDF root document. */\ntypedef pj_xml_node pjxpidf_pres;\n\n\n/**\n * Create a new XPIDF document.\n *\n * @param pool\t    Pool.\n * @param uri\t    URI to set in the XPIDF document.\n *\n * @return\t    XPIDF document.\n */\nPJ_DECL(pjxpidf_pres*) pjxpidf_create(pj_pool_t *pool, const pj_str_t *uri);\n\n\n/**\n * Parse XPIDF document.\n *\n * @param pool\t    Pool.\n * @param text\t    Input text.\n * @param len\t    Length of input text.\n *\n * @return\t    XPIDF document.\n */\nPJ_DECL(pjxpidf_pres*) pjxpidf_parse(pj_pool_t *pool, char *text, pj_size_t len);\n\n\n/**\n * Print XPIDF document.\n *\n * @param pres\t    The XPIDF document to print.\n * @param text\t    Buffer to place the output.\n * @param len\t    Length of the buffer.\n *\n * @return\t    The length printed.\n */\nPJ_DECL(int) pjxpidf_print( pjxpidf_pres *pres, char *text, pj_size_t len);\n\n\n/**\n * Get URI in the XPIDF document\n *\n * @param pres\t    XPIDF document\n *\n * @return\t    The URI, or an empty string.\n */\nPJ_DECL(pj_str_t*) pjxpidf_get_uri(pjxpidf_pres *pres);\n\n\n/**\n * Set the URI of the XPIDF document.\n *\n * @param pool\t    Pool.\n * @param pres\t    The XPIDF document.\n * @param uri\t    URI to set in the XPIDF document.\n *\n * @return\t    Zero on success.\n */\nPJ_DECL(pj_status_t) pjxpidf_set_uri(pj_pool_t *pool, pjxpidf_pres *pres, \n\t\t\t\t     const pj_str_t *uri);\n\n\n/**\n * Get presence status in the XPIDF document.\n *\n * @param pres\t    XPIDF document.\n *\n * @return\t    True to indicate the contact is online.\n */\nPJ_DECL(pj_bool_t) pjxpidf_get_status(pjxpidf_pres *pres);\n\n\n/**\n * Set presence status in the XPIDF document.\n *\n * @param pres\t    XPIDF document.\n * @param status    Status to set, True for online, False for offline.\n *\n * @return\t    Zero on success.\n */\nPJ_DECL(pj_status_t) pjxpidf_set_status(pjxpidf_pres *pres, pj_bool_t status);\n\n\n/**\n * @}\n */\n\nPJ_END_DECL\n\n\n#endif\t/* __PJSIP_SIMPLE_XPIDF_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-ua/sip_100rel.h",
    "content": "/* $Id: sip_100rel.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __SIP_100REL_H__\n#define __SIP_100REL_H__\n\n/**\n * @file sip_100rel.h\n * @brief PRACK (Reliability of Provisional Responses)\n */\n\n\n#include <pjsip-ua/sip_inv.h>\n\n\n/**\n * @defgroup PJSIP_100REL 100rel/PRACK - Reliability of Provisional Responses\n * @ingroup PJSIP_HIGH_UA\n * @brief PRACK - Reliability of Provisional Responses\n * @{\n *\n * This module provides management of Reliability of Provisional Responses\n * (\\a 100rel and \\a PRACK), as described in RFC 3262.\n *\n * Other than the #pjsip_100rel_init_module() function, the 100rel API\n * exported by this module are not intended to be used by application, but\n * rather they will be invoked by the \\ref PJSIP_INV.\n *\n * \\section pjsip_100rel_using Using Reliable Provisional Response\n *\n * \\subsection pjsip_100rel_init Initializing 100rel Module\n *\n * Application must explicitly initialize 100rel module by calling\n * #pjsip_100rel_init_module() in application initialization function.\n *\n * Once the 100rel module is initialized, it will register \\a PRACK method\n * in \\a Allow header, and \\a 100rel tag in \\a Supported header.\n *\n * \\subsection pjsip_100rel_sess Using 100rel in a Session\n *\n * For UAC, \\a 100rel support will be enabled in the session if \\a 100rel\n * support is enabled in the library (default is yes). \n * Outgoing INVITE request will include \\a 100rel tag in \\a Supported\n * header and \\a PRACK method in \\a Allow header. When callee endpoint\n * sends reliable provisional responses, the UAC will automatically send\n * \\a PRACK request to acknowledge the response. If callee endpoint doesn't\n * send reliable provisional response, the response will be handled using\n * normal, non-100rel procedure (that is, \\a PRACK will not be sent).\n *\n * If the UAC wants to <b>mandate</b> \\a 100rel support, it can specify\n * #PJSIP_INV_REQUIRE_100REL in the \\a options argument when calling\n * #pjsip_inv_create_uac(). In this case, PJSIP will add \\a 100rel tag \n * in the \\a Require header of the outgoing INVITE request.\n *\n * For UAS, if it wants to support \\a 100rel but not to mandate it, \n * it must specify  #PJSIP_INV_SUPPORT_100REL flag in the \\a options \n * argument when calling  #pjsip_inv_verify_request(), and pass the same \n * \\a options variable when calling #pjsip_inv_verify_request. If UAC had \n * specified \\a 100rel in it's list of extensions in \\a Require header, \n * the UAS will send provisional responses reliably. If UAC only listed \n * \\a 100rel in its \\a Supported header but not in \\a Require header, \n * or if UAC does not list \\a 100rel support at all, the UAS WILL NOT \n * send provisional responses reliably.\n * The snippet below can be used to accomplish this task:\n *\n * \\verbatim\n    unsigned options = 0;\n\n    options |= PJSIP_INV_SUPPORT_100REL;\n\n    status = pjsip_inv_verify_request(rdata, &options, answer, NULL,\n\t\t\t\t      endpt, &resp);\n    if (status != PJ_SUCCESS) {\n\t// INVITE request cannot be handled.\n\t// Reject the request with the response in resp.\n\t...\n\treturn;\n    }\n\n    // Create UAS dialog, populate Contact header, etc.\n    ...\n\n    // Create UAS invite session\n    status = pjsip_inv_create_uas( dlg, rdata, answer, options, &inv);\n\n    ..\n\n   \\endverbatim\n *\n * For another requirement, if UAS wants to <b>mandate</b> \\a 100rel support,\n * it can specify #PJSIP_INV_REQUIRE_100REL flag when calling \n * #pjsip_inv_verify_request(), and pass the \\a options when calling \n * #pjsip_inv_verify_request. In this case,\n * \\a 100rel extension will be used if UAC specifies \\a 100rel in its\n * \\a Supported header. If UAC does not list \\a 100rel in \\a Supported header,\n * the incoming INVITE request will be rejected with 421 (Extension Required)\n * response. For the sample code, it should be identical to the snippet\n * above, except that application must specify #PJSIP_INV_REQUIRE_100REL\n * flag in the \\a options instead of #PJSIP_INV_SUPPORT_100REL.\n *\n * For yet another requirement, if UAS <b>does not</b> want to support\n * \\a 100rel extension, it can reject incoming INVITE request with\n * 420 (Bad Extension) response whenever incoming INVITE request has\n * \\a 100rel tag in its \\a Require header. This can be done by specifying\n * zero as the \\a options when calling #pjsip_inv_verify_request().\n */\n\nPJ_BEGIN_DECL\n\n\n/** \n * PRACK method constant. \n * @see pjsip_get_prack_method() \n  */\nPJ_DECL_DATA(const pjsip_method) pjsip_prack_method;\n\n\n/** \n * Get #pjsip_invite_method constant. \n */\nPJ_DECL(const pjsip_method*) pjsip_get_prack_method(void);\n\n\n/**\n * Initialize 100rel module. This function must be called once during\n * application initialization, to register 100rel module to SIP endpoint.\n *\n * @param endpt\t\tThe SIP endpoint instance.\n *\n * @return\t\tPJ_SUCCESS if module is successfully initialized.\n */\nPJ_DECL(pj_status_t) pjsip_100rel_init_module(pjsip_endpoint *endpt);\n\n\n/**\n * Add 100rel support to the specified invite session. This function will\n * be called internally by the invite session if it detects that the\n * session needs 100rel support.\n *\n * @param inv\t\tThe invite session.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pjsip_100rel_attach(pjsip_inv_session *inv);\n\n\n/**\n * Check if incoming response has reliable provisional response feature.\n *\n * @param rdata\t\tReceive data buffer containing the response.\n *\n * @return\t\tPJ_TRUE if the provisional response is reliable.\n */\nPJ_DECL(pj_bool_t) pjsip_100rel_is_reliable(pjsip_rx_data *rdata);\n\n\n/**\n * Create PRACK request for the incoming reliable provisional response.\n * Note that PRACK request MUST be sent using #pjsip_100rel_send_prack().\n *\n * @param inv\t\tThe invite session.\n * @param rdata\t\tThe incoming reliable provisional response.\n * @param p_tdata\tUpon return, it will be initialized with the\n *\t\t\tPRACK request.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pjsip_100rel_create_prack(pjsip_inv_session *inv,\n\t\t\t\t\t       pjsip_rx_data *rdata,\n\t\t\t\t\t       pjsip_tx_data **p_tdata);\n\n/**\n * Send PRACK request.\n *\n * @param inv\t\tThe invite session.\n * @param tdata\t\tThe PRACK request.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pjsip_100rel_send_prack(pjsip_inv_session *inv,\n\t\t\t\t\t     pjsip_tx_data *tdata);\n\n\n/**\n * Handle incoming PRACK request.\n *\n * @param inv\t\tThe invite session.\n * @param rdata\t\tIncoming PRACK request.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pjsip_100rel_on_rx_prack(pjsip_inv_session *inv,\n\t\t\t\t\t      pjsip_rx_data *rdata);\n\n\n/**\n * Transmit INVITE response (provisional or final) reliably according to\n * 100rel specification. The 100rel module will take care of retransmitting\n * or enqueueing the response according to the current state of the\n * reliable response processing. This function will be called internally\n * by invite session.\n *\n * @param inv\t\tThe invite session.\n * @param tdata\t\tThe INVITE response.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pjsip_100rel_tx_response(pjsip_inv_session *inv,\n\t\t\t\t\t      pjsip_tx_data *tdata);\n\n\n/**\n * Notify 100rel module that the invite session has been disconnected.\n *\n * @param inv\t\tThe invite session.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pjsip_100rel_end_session(pjsip_inv_session *inv);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __SIP_100REL_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-ua/sip_inv.h",
    "content": "/* $Id: sip_inv.h 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __SIP_INVITE_SESSION_H__\n#define __SIP_INVITE_SESSION_H__\n\n/**\n * @file sip_inv.h\n * @brief INVITE sessions\n */\n\n\n#include <pjsip/sip_dialog.h>\n#include <pjmedia/sdp_neg.h>\n\n\n/**\n * @defgroup PJSIP_HIGH_UA User Agent Library\n * @brief Mid-level User Agent Library.\n *\n * This is the high level user agent library, which consists of:\n *  - @ref PJSIP_INV, to encapsulate INVITE sessions and SDP\n *    negotiation in the session,\n *  - @ref PJSUA_REGC, high level client registration API, and\n *  - @ref PJSUA_XFER.\n *\n * More detailed information is explained in\n * <A HREF=\"/docs.htm\">PJSIP Developer's Guide</A>\n * PDF document, and readers are encouraged to read the document to\n * get the concept behind dialog, dialog usages, and INVITE sessions.\n *\n * The User Agent Library is implemented in <b>pjsip-ua</b> static\n * library.\n */\n\n/**\n * @defgroup PJSIP_INV INVITE Session\n * @ingroup PJSIP_HIGH_UA\n * @brief Provides INVITE session management.\n * @{\n *\n * The INVITE session uses the @ref PJSIP_DIALOG framework to manage\n * the underlying dialog, and is one type of usages that can use\n * a particular dialog instance (other usages are event subscription,\n * discussed in @ref PJSIP_EVENT_NOT). The INVITE session manages\n * the life-time of the session, and also manages the SDP negotiation.\n *\n * Application must link with  <b>pjsip-ua</b> static library to use this API.\n *\n * More detailed information is explained in\n * <A HREF=\"/docs.htm\">PJSIP Developer's Guide</A>\n * PDF document, and readers are encouraged to read the document to\n * get the concept behind dialog, dialog usages, and INVITE sessions.\n *\n * The INVITE session does NOT manage media. If application wants to\n * use API that encapsulates both signaling and media in a very easy\n * to use API, it can use @ref PJSUA_LIB for this purpose.\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * @see pjsip_inv_session\n */\ntypedef struct pjsip_inv_session pjsip_inv_session;\n\n\n/**\n * This enumeration describes invite session state.\n */\ntypedef enum pjsip_inv_state\n{\n    PJSIP_INV_STATE_NULL,\t    /**< Before INVITE is sent or received  */\n    PJSIP_INV_STATE_CALLING,\t    /**< After INVITE is sent\t\t    */\n    PJSIP_INV_STATE_INCOMING,\t    /**< After INVITE is received.\t    */\n    PJSIP_INV_STATE_EARLY,\t    /**< After response with To tag.\t    */\n    PJSIP_INV_STATE_CONNECTING,\t    /**< After 2xx is sent/received.\t    */\n    PJSIP_INV_STATE_CONFIRMED,\t    /**< After ACK is sent/received.\t    */\n    PJSIP_INV_STATE_DISCONNECTED,   /**< Session is terminated.\t\t    */\n} pjsip_inv_state;\n\n/**\n * This structure contains callbacks to be registered by application to \n * receieve notifications from the framework about various events in\n * the invite session.\n */\ntypedef struct pjsip_inv_callback\n{\n    /**\n     * This callback is called when the invite sesion state has changed. \n     * Application should inspect the session state (inv_sess->state) to get \n     * the current state of the session.\n     *\n     * This callback is mandatory.\n     *\n     * @param inv\tThe invite session.\n     * @param e\t\tThe event which has caused the invite session's \n     *\t\t\tstate to change.\n     */\n    void (*on_state_changed)(pjsip_inv_session *inv, pjsip_event *e);\n\n    /**\n     * This callback is called when the invite usage module has created \n     * a new dialog and invite because of forked outgoing request.\n     *\n     * This callback is mandatory.\n     *\n     * @param inv\tThe new invite session.\n     * @param e\t\tThe event which has caused the dialog to fork.\n     *\t\t\tThe type of this event can be either\n     *\t\t\tPJSIP_EVENT_RX_MSG or PJSIP_EVENT_RX_200_MSG.\n     */\n    void (*on_new_session)(pjsip_inv_session *inv, pjsip_event *e);\n\n    /**\n     * This callback is called whenever any transactions within the session\n     * has changed their state. Application MAY implement this callback, \n     * e.g. to monitor the progress of an outgoing request, or to send\n     * response to unhandled incoming request (such as INFO).\n     *\n     * This callback is optional.\n     *\n     * @param inv\tThe invite session.\n     * @param tsx\tThe transaction, which state has changed.\n     * @param e\t\tThe event which has caused the transation state's\n     *\t\t\tto change.\n     */\n    void (*on_tsx_state_changed)(pjsip_inv_session *inv,\n\t\t\t\t pjsip_transaction *tsx,\n\t\t\t\t pjsip_event *e);\n\n    /**\n     * This callback is called when the invite session has received \n     * new offer from peer. Application can inspect the remote offer \n     * in \"offer\", and set the SDP answer with #pjsip_inv_set_sdp_answer().\n     * When the application sends a SIP message to send the answer, \n     * this SDP answer will be negotiated with the offer, and the result\n     * will be sent with the SIP message.\n     *\n     * @param inv\tThe invite session.\n     * @param offer\tRemote offer.\n     */\n    void (*on_rx_offer)(pjsip_inv_session *inv,\n\t\t\tconst pjmedia_sdp_session *offer);\n\n    /**\n     * This callback is optional, and is called when the invite session has\n     * received a re-INVITE from the peer. It will be called after\n     * on_rx_offer() callback and works only for re-INVITEs. It allows more\n     * fine-grained control over the response to a re-INVITE, e.g. sending\n     * a provisional response first. Application can return PJ_SUCCESS and\n     * send a reply using the function #pjsip_inv_initial_answer() or\n     * #pjsip_inv_answer(), as with the initial INVITE. If application\n     * returns non-PJ_SUCCESS, it needs to set the SDP answer with\n     * #pjsip_inv_set_sdp_answer() and the re-INVITE will be answered\n     * automatically.\n     *\n     * Remarks: Application may need to monitor on_tsx_state_changed()\n     * callback to check whether the re-INVITE is already answered\n     * automatically with 487 due to being cancelled.\n     *\n     * @param inv\tThe invite session.\n     * @param offer\tRemote offer.\n     * @param rdata     The received re-INVITE request.\n     *\n     * @return\t\t- PJ_SUCCESS: application will answer the re-INVITE\n     *                    manually\n     *                  - non-PJ_SUCCESS: answer the re-INVITE automatically\n     *                    using the SDP set via #pjsip_inv_set_sdp_answer()\n     */\n    pj_status_t (*on_rx_reinvite)(pjsip_inv_session *inv,\n    \t\t                  const pjmedia_sdp_session *offer,\n                                  pjsip_rx_data *rdata);\n\n    /**\n     * This callback is optional, and it is used to ask the application\n     * to create a fresh offer, when the invite session has received \n     * re-INVITE without offer. This offer then will be sent in the\n     * 200/OK response to the re-INVITE request.\n     *\n     * If application doesn't implement this callback, the invite session\n     * will send the currently active SDP as the offer.\n     *\n     * @param inv\tThe invite session.\n     * @param p_offer\tPointer to receive the SDP offer created by\n     *\t\t\tapplication.\n     */\n    void (*on_create_offer)(pjsip_inv_session *inv,\n\t\t\t    pjmedia_sdp_session **p_offer);\n\n    /**\n     * This callback is called after SDP offer/answer session has completed.\n     * The status argument specifies the status of the offer/answer, \n     * as returned by pjmedia_sdp_neg_negotiate().\n     * \n     * This callback is optional (from the point of view of the framework), \n     * but all useful applications normally need to implement this callback.\n     *\n     * @param inv\tThe invite session.\n     * @param status\tThe negotiation status.\n     */\n    void (*on_media_update)(pjsip_inv_session *inv_ses, \n\t\t\t    pj_status_t status);\n\n    /**\n     * This callback is called when the framework needs to send\n     * ACK request after it receives incoming  2xx response for \n     * INVITE. It allows application to manually handle the \n     * transmission of ACK request, which is required by some 3PCC\n     * scenarios. If this callback is not implemented, the framework\n     * will handle the ACK transmission automatically.\n     *\n     * When this callback is overridden, application may delay the\n     * sending of the ACK request (for example, when it needs to \n     * wait for answer from the other call leg, in 3PCC scenarios). \n     *\n     * Application creates the ACK request\n     *\n     * Once it has sent the ACK request, the framework will keep \n     * this ACK request in the cache. Subsequent receipt of 2xx response\n     * will not cause this callback to be called, and instead automatic\n     * retransmission of this ACK request from the cache will be done\n     * by the framework.\n     *\n     * This callback is optional.\n     */\n    void (*on_send_ack)(pjsip_inv_session *inv, pjsip_rx_data *rdata);\n\n    /**\n     * This callback is called when the session is about to resend the \n     * INVITE request to the specified target, following the previously\n     * received redirection response.\n     *\n     * Application may accept the redirection to the specified target \n     * (the default behavior if this callback is implemented), reject \n     * this target only and make the session continue to try the next \n     * target in the list if such target exists, stop the whole\n     * redirection process altogether and cause the session to be\n     * disconnected, or defer the decision to ask for user confirmation.\n     *\n     * This callback is optional. If this callback is not implemented,\n     * the default behavior is to NOT follow the redirection response.\n     *\n     * @param inv\tThe invite session.\n     * @param target\tThe current target to be tried.\n     * @param e\t\tThe event that caused this callback to be called.\n     *\t\t\tThis could be the receipt of 3xx response, or\n     *\t\t\t4xx/5xx response received for the INVITE sent to\n     *\t\t\tsubsequent targets, or NULL if this callback is\n     *\t\t\tcalled from within #pjsip_inv_process_redirect()\n     *\t\t\tcontext.\n     *\n     * @return\t\tAction to be performed for the target. Set this\n     *\t\t\tparameter to one of the value below:\n     *\t\t\t- PJSIP_REDIRECT_ACCEPT: immediately accept the\n     *\t\t\t  redirection to this target. When set, the\n     *\t\t\t  session will immediately resend INVITE request\n     *\t\t\t  to the target after this callback returns.\n     *\t\t\t- PJSIP_REDIRECT_REJECT: immediately reject this\n     *\t\t\t  target. The session will continue retrying with\n     *\t\t\t  next target if present, or disconnect the call\n     *\t\t\t  if there is no more target to try.\n     *\t\t\t- PJSIP_REDIRECT_STOP: stop the whole redirection\n     *\t\t\t  process and immediately disconnect the call. The\n     *\t\t\t  on_state_changed() callback will be called with\n     *\t\t\t  PJSIP_INV_STATE_DISCONNECTED state immediately\n     *\t\t\t  after this callback returns.\n     *\t\t\t- PJSIP_REDIRECT_PENDING: set to this value if\n     *\t\t\t  no decision can be made immediately (for example\n     *\t\t\t  to request confirmation from user). Application\n     *\t\t\t  then MUST call #pjsip_inv_process_redirect()\n     *\t\t\t  to either accept or reject the redirection upon\n     *\t\t\t  getting user decision.\n     */\n    pjsip_redirect_op (*on_redirected)(pjsip_inv_session *inv, \n\t\t\t\t       const pjsip_uri *target,\n\t\t\t\t       const pjsip_event *e);\n\n} pjsip_inv_callback;\n\n\n\n/**\n * This enumeration shows various options that can be applied to a session. \n * The bitmask combination of these options need to be specified when \n * creating a session. After the dialog is established (including early), \n * the options member of #pjsip_inv_session shows which capabilities are \n * common in both endpoints.\n */\nenum pjsip_inv_option\n{\t\n    /** \n     * Indicate support for reliable provisional response extension \n     */\n    PJSIP_INV_SUPPORT_100REL\t= 1,\n\n    /** \n     * Indicate support for session timer extension. \n     */\n    PJSIP_INV_SUPPORT_TIMER\t= 2,\n\n    /** \n     * Indicate support for UPDATE method. This is automatically implied\n     * when creating outgoing dialog. After the dialog is established,\n     * the options member of #pjsip_inv_session shows whether peer supports\n     * this method as well.\n     */\n    PJSIP_INV_SUPPORT_UPDATE\t= 4,\n\n    /**\n     * Indicate support for ICE\n     */\n    PJSIP_INV_SUPPORT_ICE\t= 8,\n\n    /**\n     * Require ICE support.\n     */\n    PJSIP_INV_REQUIRE_ICE\t= 16,\n\n    /** \n     * Require reliable provisional response extension. \n     */\n    PJSIP_INV_REQUIRE_100REL\t= 32,\n\n    /**  \n     * Require session timer extension. \n     */\n    PJSIP_INV_REQUIRE_TIMER\t= 64,\n\n    /**  \n     * Session timer extension will always be used even when peer doesn't\n     * support/want session timer.\n     */\n    PJSIP_INV_ALWAYS_USE_TIMER\t= 128\n\n};\n\n/* Forward declaration of Session Timers */\nstruct pjsip_timer;\n\n/**\n * This structure describes the invite session.\n *\n * Note regarding the invite session's pools. The inv_sess used to have\n * only one pool, which is just a pointer to the dialog's pool. Ticket\n * http://trac.pjsip.org/repos/ticket/877 has found that the memory\n * usage will grow considerably everytime re-INVITE or UPDATE is\n * performed.\n *\n * Ticket #877 then created two more memory pools for the inv_sess, so\n * now we have three memory pools:\n *  - pool: to be used to allocate long term data for the session\n *  - pool_prov and pool_active: this is a flip-flop pools to be used\n *     interchangably during re-INVITE and UPDATE. pool_prov is\n *     \"provisional\" pool, used to allocate SDP offer or answer for\n *     the re-INVITE and UPDATE. Once SDP negotiation is done, the\n *     provisional pool will be made as the active pool, then the\n *     existing active pool will be reset, to release the memory\n *     back to the OS. So these pool's lifetime is synchronized to\n *     the SDP offer-answer negotiation.\n *\n * Higher level application such as PJSUA-LIB has been modified to\n * make use of these flip-flop pools, i.e. by creating media objects\n * from the provisional pool rather than from the long term pool.\n *\n * Other applications that want to use these pools must understand\n * that the flip-flop pool's lifetimes are synchronized to the\n * SDP offer-answer negotiation.\n */\nstruct pjsip_inv_session\n{\n    char\t\t obj_name[PJ_MAX_OBJ_NAME]; /**< Log identification */\n    pj_pool_t\t\t*pool;\t\t\t    /**< Long term pool.    */\n    pj_pool_t\t\t*pool_prov;\t\t    /**< Provisional pool   */\n    pj_pool_t\t\t*pool_active;\t\t    /**< Active/current pool*/\n    pjsip_inv_state\t state;\t\t\t    /**< Invite sess state. */\n    pj_bool_t\t\t cancelling;\t\t    /**< CANCEL requested   */\n    pj_bool_t\t\t pending_cancel;\t    /**< Wait to send CANCEL*/\n    pjsip_tx_data\t*pending_bye;               /**< BYE to send later  */\n    pjsip_status_code\t cause;\t\t\t    /**< Disconnect cause.  */\n    pj_str_t\t\t cause_text;\t\t    /**< Cause text.\t    */\n    pj_bool_t\t\t notify;\t\t    /**< Internal.\t    */\n    unsigned\t\t cb_called;\t\t    /**< Cb has been called */\n    pjsip_dialog\t*dlg;\t\t\t    /**< Underlying dialog. */\n    pjsip_role_e\t role;\t\t\t    /**< Invite role.\t    */\n    unsigned\t\t options;\t\t    /**< Options in use.    */\n    pjmedia_sdp_neg\t*neg;\t\t\t    /**< Negotiator.\t    */\n    unsigned             sdp_neg_flags;             /**< SDP neg flags.     */\n    pjsip_transaction\t*invite_tsx;\t\t    /**< 1st invite tsx.    */\n    pjsip_tx_data\t*invite_req;\t\t    /**< Saved invite req   */\n    pjsip_tx_data\t*last_answer;\t\t    /**< Last INVITE resp.  */\n    pjsip_tx_data\t*last_ack;\t\t    /**< Last ACK request   */\n    pj_int32_t\t\t last_ack_cseq;\t\t    /**< CSeq of last ACK   */\n    void\t\t*mod_data[PJSIP_MAX_MODULE];/**< Modules data.\t    */\n    struct pjsip_timer\t*timer;\t\t\t    /**< Session Timers.    */\n    pj_bool_t\t\t following_fork;\t    /**< Internal, following\n\t\t\t\t\t\t\t forked media?\t    */\n};\n\n\n/**\n * This structure represents SDP information in a pjsip_rx_data. Application\n * retrieve this information by calling #pjsip_rdata_get_sdp_info(). This\n * mechanism supports multipart message body.\n */\ntypedef struct pjsip_rdata_sdp_info\n{\n    /**\n     * Pointer and length of the text body in the incoming message. If\n     * the pointer is NULL, it means the message does not contain SDP\n     * body.\n     */\n    pj_str_t\t\t body;\n\n    /**\n     * This will contain non-zero if an invalid SDP body is found in the\n     * message.\n     */\n    pj_status_t\t\t sdp_err;\n\n    /**\n     * A parsed and validated SDP body.\n     */\n    pjmedia_sdp_session *sdp;\n\n} pjsip_rdata_sdp_info;\n\n\n/**\n * Initialize the invite usage module and register it to the endpoint. \n * The callback argument contains pointer to functions to be called on \n * occurences of events in invite sessions.\n *\n * @param endpt\t\tThe endpoint instance.\n * @param cb\t\tCallback structure.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_inv_usage_init(pjsip_endpoint *endpt,\n\t\t\t\t\t  const pjsip_inv_callback *cb);\n\n/**\n * Get the INVITE usage module instance.\n *\n * @return\t\tPJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pjsip_module*) pjsip_inv_usage_instance(void);\n\n\n/**\n * Dump user agent contents (e.g. all dialogs).\n */\nPJ_DECL(void) pjsip_inv_usage_dump(void);\n\n\n/**\n * Create UAC invite session for the specified dialog in dlg. \n *\n * @param dlg\t\tThe dialog which will be used by this invite session.\n * @param local_sdp\tIf application has determined its media capability, \n *\t\t\tit can specify the SDP here. Otherwise it can leave \n *\t\t\tthis to NULL, to let remote UAS specifies an offer.\n * @param options\tThe options argument is bitmask combination of SIP \n *\t\t\tfeatures in pjsip_inv_option enumeration.\n * @param p_inv\t\tOn successful return, the invite session will be put \n *\t\t\tin this argument.\n *\n * @return\t\tThe function will return PJ_SUCCESS if it can create\n *\t\t\tthe session. Otherwise the appropriate error status \n *\t\t\twill be returned on failure.\n */\nPJ_DECL(pj_status_t) pjsip_inv_create_uac(pjsip_dialog *dlg,\n\t\t\t\t\t  const pjmedia_sdp_session *local_sdp,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t\t  pjsip_inv_session **p_inv);\n\n\n/**\n * Application SHOULD call this function upon receiving the initial INVITE \n * request in rdata before creating the invite session (or even dialog), \n * to verify that the invite session can handle the INVITE request. \n * This function verifies that local endpoint is capable to handle required \n * SIP extensions in the request (i.e. Require header) and also the media, \n * if media description is present in the request.\n *\n * @param rdata\t\tThe incoming INVITE request.\n *\n * @param options\tUpon calling this function, the options argument \n *\t\t\tMUST contain the desired SIP extensions to be \n *\t\t\tapplied to the session. Upon return, this argument \n *\t\t\twill contain the SIP extension that will be applied \n *\t\t\tto the session, after considering the Supported, \n *\t\t\tRequire, and Allow headers in the request.\n *\n * @param sdp\t\tIf local media capability has been determined, \n *\t\t\tand if application wishes to verify that it can \n *\t\t\thandle the media offer in the incoming INVITE \n *\t\t\trequest, it SHOULD specify its local media capability\n *\t\t\tin this argument. \n *\t\t\tIf it is not specified, media verification will not\n *\t\t\tbe performed by this function.\n *\n * @param dlg\t\tIf tdata is not NULL, application needs to specify\n *\t\t\thow to create the response. Either dlg or endpt\n *\t\t\targument MUST be specified, with dlg argument takes\n *\t\t\tprecedence when both are specified.\n *\n *\t\t\tIf a dialog has been created prior to calling this \n *\t\t\tfunction, then it MUST be specified in dlg argument. \n *\t\t\tOtherwise application MUST specify the endpt argument\n *\t\t\t(this is useful e.g. when application wants to send \n *\t\t\tthe response statelessly).\n *\n * @param endpt\t\tIf tdata is not NULL, application needs to specify\n *\t\t\thow to create the response. Either dlg or endpt\n *\t\t\targument MUST be specified, with dlg argument takes\n *\t\t\tprecedence when both are specified.\n *\n * @param tdata\t\tIf this argument is not NULL, this function will \n *\t\t\tcreate the appropriate non-2xx final response message\n *\t\t\twhen the verification fails.\n *\n * @return\t\tIf everything has been negotiated successfully, \n *\t\t\tthe function will return PJ_SUCCESS. Otherwise it \n *\t\t\twill return the reason of the failure as the return\n *\t\t\tcode.\n *\n *\t\t\tThis function is capable to create the appropriate \n *\t\t\tresponse message when the verification has failed. \n *\t\t\tIf tdata is specified, then a non-2xx final response\n *\t\t\twill be created and put in this argument upon return,\n *\t\t\twhen the verification has failed. \n *\n *\t\t\tIf a dialog has been created prior to calling this \n *\t\t\tfunction, then it MUST be specified in dlg argument. \n *\t\t\tOtherwise application MUST specify the endpt argument\n *\t\t\t(this is useful e.g. when application wants to send \n *\t\t\tthe response statelessly).\n *\n * @see pjsip_inv_verify_request2()\n */\nPJ_DECL(pj_status_t) pjsip_inv_verify_request(\tpjsip_rx_data *rdata,\n\t\t\t\t\t\tunsigned *options,\n\t\t\t\t\t\tconst pjmedia_sdp_session *sdp,\n\t\t\t\t\t\tpjsip_dialog *dlg,\n\t\t\t\t\t\tpjsip_endpoint *endpt,\n\t\t\t\t\t\tpjsip_tx_data **tdata);\n\n/**\n * Variant of #pjsip_inv_verify_request() which allows application to specify\n * the parsed SDP in the \\a offer argument. This is useful to avoid having to\n * re-parse the SDP in the incoming request.\n *\n * @see pjsip_inv_verify_request()\n */\nPJ_DECL(pj_status_t) pjsip_inv_verify_request2( pjsip_rx_data *rdata,\n\t\t\t\t\t\tunsigned *options,\n\t\t\t\t\t\tconst pjmedia_sdp_session *offer,\n\t\t\t\t\t\tconst pjmedia_sdp_session *answer,\n\t\t\t\t\t\tpjsip_dialog *dlg,\n\t\t\t\t\t\tpjsip_endpoint *endpt,\n\t\t\t\t\t\tpjsip_tx_data **tdata);\n\n/**\n * Variant of #pjsip_inv_verify_request() which allows application not to\n * specify the rdata (i.e. pass NULL as the rdata parameter) and specify\n * the parsed SDP in the \\a offer argument and a temporary pool in the\n * \\a tmp_pool argument.\n * This is useful if application no longer has access to the rdata.\n *\n * @see pjsip_inv_verify_request()\n */\nPJ_DECL(pj_status_t) pjsip_inv_verify_request3( pjsip_rx_data *rdata,\n                                                pj_pool_t *tmp_pool,\n\t\t\t\t\t\tunsigned *options,\n\t\t\t\t\t\tconst pjmedia_sdp_session *offer,\n\t\t\t\t\t\tconst pjmedia_sdp_session *answer,\n\t\t\t\t\t\tpjsip_dialog *dlg,\n\t\t\t\t\t\tpjsip_endpoint *endpt,\n\t\t\t\t\t\tpjsip_tx_data **tdata);\n\n\n/**\n * Create UAS invite session for the specified dialog in dlg. Application \n * SHOULD call the verification function before calling this function, \n * to ensure that it can create the session successfully.\n *\n * @param dlg\t\tThe dialog to be used.\n * @param rdata\t\tApplication MUST specify the received INVITE request \n *\t\t\tin rdata. The invite session needs to inspect the \n *\t\t\treceived request to see if the request contains \n *\t\t\tfeatures that it supports.\n * @param local_sdp\tIf application has determined its media capability, \n *\t\t\tit can specify this capability in this argument. \n *\t\t\tIf SDP is received in the initial INVITE, the UAS \n *\t\t\tcapability specified in this argument doesn't have to\n *\t\t\tmatch the received offer; the SDP negotiator is able \n *\t\t\tto rearrange the media lines in the answer so that it\n *\t\t\tmatches the offer. \n * @param options\tThe options argument is bitmask combination of SIP \n *\t\t\tfeatures in pjsip_inv_option enumeration.\n * @param p_inv\t\tPointer to receive the newly created invite session.\n *\n * @return\t\tOn successful, the invite session will be put in \n *\t\t\tp_inv argument and the function will return PJ_SUCCESS.\n *\t\t\tOtherwise the appropriate error status will be returned \n *\t\t\ton failure.\n */\nPJ_DECL(pj_status_t) pjsip_inv_create_uas(pjsip_dialog *dlg,\n\t\t\t\t\t  pjsip_rx_data *rdata,\n\t\t\t\t\t  const pjmedia_sdp_session *local_sdp,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t\t  pjsip_inv_session **p_inv);\n\n\n/**\n * Forcefully terminate and destroy INVITE session, regardless of\n * the state of the session. Note that this function should only be used\n * when there is failure in the INVITE session creation. After the\n * invite session has been created and initialized, normally application\n * SHOULD use #pjsip_inv_end_session() to end the INVITE session instead.\n *\n * Note also that this function may terminate the underlying dialog, if\n * there are no other sessions in the dialog.\n *\n * @param inv\t\tThe invite session.\n * @param st_code\tStatus code for the reason of the termination.\n * @param notify\tIf set to non-zero, then on_state_changed() \n *\t\t\tcallback will be called.\n *\n * @return\t\tPJ_SUCCESS if the INVITE session has been\n *\t\t\tterminated.\n */\nPJ_DECL(pj_status_t) pjsip_inv_terminate( pjsip_inv_session *inv,\n\t\t\t\t          int st_code,\n\t\t\t\t\t  pj_bool_t notify );\n\n\n/**\n * Restart UAC session and prepare the session for a new initial INVITE.\n * This function can be called for example when the application wants to\n * follow redirection response with a new call reusing this session so\n * that the new call will have the same Call-ID and From headers. After\n * the session is restarted, application may create and send a new INVITE\n * request.\n *\n * @param inv\t\tThe invite session.\n * @param new_offer\tShould be set to PJ_TRUE since the application will\n *\t\t\trestart the session.\n *\n * @return\t\tPJ_SUCCESS on successful operation.\n */\nPJ_DECL(pj_status_t) pjsip_inv_uac_restart(pjsip_inv_session *inv,\n\t\t\t\t\t   pj_bool_t new_offer);\n\n\n/**\n * Accept or reject redirection response. Application MUST call this function\n * after it signaled PJSIP_REDIRECT_PENDING in the \\a on_redirected() \n * callback, to notify the invite session whether to accept or reject the\n * redirection to the current target. Application can use the combination of\n * PJSIP_REDIRECT_PENDING command in \\a on_redirected() callback and this\n * function to ask for user permission before redirecting the call.\n *\n * Note that if the application chooses to reject or stop redirection (by \n * using PJSIP_REDIRECT_REJECT or PJSIP_REDIRECT_STOP respectively), the\n * session disconnection callback will be called before this function returns.\n * And if the application rejects the target, the \\a on_redirected() callback\n * may also be called before this function returns if there is another target\n * to try.\n *\n * @param inv\t\tThe invite session.\n * @param cmd\t\tRedirection operation. The semantic of this argument\n *\t\t\tis similar to the description in the \\a on_redirected()\n *\t\t\tcallback, except that the PJSIP_REDIRECT_PENDING is\n *\t\t\tnot accepted here.\n * @param e\t\tShould be set to NULL.\n *\n * @return\t\tPJ_SUCCESS on successful operation.\n */\nPJ_DECL(pj_status_t) pjsip_inv_process_redirect(pjsip_inv_session *inv,\n\t\t\t\t\t\tpjsip_redirect_op cmd,\n\t\t\t\t\t\tpjsip_event *e);\n\n\n/**\n * Create the initial INVITE request for this session. This function can only \n * be called for UAC session. If local media capability is specified when \n * the invite session was created, then this function will put an SDP offer \n * in the outgoing INVITE request. Otherwise the outgoing request will not \n * contain SDP body.\n *\n * @param inv\t\tThe UAC invite session.\n * @param p_tdata\tThe initial INVITE request will be put in this \n *\t\t\targument if it can be created successfully.\n *\n * @return\t\tPJ_SUCCESS if the INVITE request can be created.\n */\nPJ_DECL(pj_status_t) pjsip_inv_invite( pjsip_inv_session *inv,\n\t\t\t\t       pjsip_tx_data **p_tdata );\n\n\n/**\n * Create the initial response message for the incoming INVITE request in\n * rdata with  status code st_code and optional status text st_text. Use\n * #pjsip_inv_answer() to create subsequent response message.\n */\nPJ_DECL(pj_status_t) pjsip_inv_initial_answer(\tpjsip_inv_session *inv,\n\t\t\t\t\t\tpjsip_rx_data *rdata,\n\t\t\t\t\t\tint st_code,\n\t\t\t\t\t\tconst pj_str_t *st_text,\n\t\t\t\t\t\tconst pjmedia_sdp_session *sdp,\n\t\t\t\t\t\tpjsip_tx_data **p_tdata);\n\n/**\n * Create a response message to an INVITE request.\n *\n * @param inv\t\tThe UAS invite session.\n * @param st_code\tThe st_code contains the status code to be sent, \n *\t\t\twhich may be a provisional or final response. \n * @param st_text\tIf custom status text is desired, application can \n *\t\t\tspecify the text in st_text; otherwise if this \n *\t\t\targument is NULL, default status text will be used.\n * @param local_sdp\tIf application has specified its media capability\n *\t\t\tduring creation of UAS invite session, the local_sdp\n *\t\t\targument MUST be NULL. This is because application \n *\t\t\tcan not perform more than one SDP offer/answer session\n *\t\t\tin a single INVITE transaction.\n *\t\t\tIf application has not specified its media capability \n *\t\t\tduring creation of UAS invite session, it MAY or MUST\n *\t\t\tspecify its capability in local_sdp argument, \n *\t\t\tdepending whether st_code indicates a 2xx final \n *\t\t\tresponse.\n * @param p_tdata\tPointer to receive the response message created by\n *\t\t\tthis function.\n *\n * @return\t\tPJ_SUCCESS if response message was created\n *\t\t\tsuccessfully.\n */\nPJ_DECL(pj_status_t) pjsip_inv_answer(\tpjsip_inv_session *inv,\n\t\t\t\t\tint st_code,\n\t\t\t\t\tconst pj_str_t *st_text,\n\t\t\t\t\tconst pjmedia_sdp_session *local_sdp,\n\t\t\t\t\tpjsip_tx_data **p_tdata );\n\n\n/**\n * Set local offer or answer depending on negotiator state (it may also\n * create a negotiator if it doesn't exist yet).\n *\n * @param inv\t\tThe invite session.\n * @param sdp\t\tThe SDP description which will be set as\n *\t\t\tan offer/answer to remote.\n *\n * @return\t\tPJ_SUCCESS if local offer/answer can be accepted by\n *\t\t\tSDP negotiator.\n */\nPJ_DECL(pj_status_t) pjsip_inv_set_local_sdp(pjsip_inv_session *inv,\n\t\t\t\t\t     const pjmedia_sdp_session *sdp );\n\n\n/**\n * Set local answer to respond to remote SDP offer, to be carried by \n * subsequent response (or request).\n *\n * @param inv\t\tThe invite session.\n * @param sdp\t\tThe SDP description which will be set as answer\n *\t\t\tto remote.\n *\n * @return\t\tPJ_SUCCESS if local answer can be accepted by\n *\t\t\tSDP negotiator.\n */\nPJ_DECL(pj_status_t) pjsip_inv_set_sdp_answer(pjsip_inv_session *inv,\n\t\t\t\t\t      const pjmedia_sdp_session *sdp );\n\n\n/**\n * Create a SIP message to initiate invite session termination. Depending on \n * the state of the session, this function may return CANCEL request, \n * a non-2xx final response, a BYE request, or even no request. \n *\n * For UAS, if the session has not answered the incoming INVITE, this function\n * creates the non-2xx final response with the specified status code in \n * \\a st_code and optional status text in \\a st_text. \n *\n * For UAC, if the original INVITE has not been answered with a final \n * response, the behavior depends on whether provisional response has been\n * received. If provisional response has been received, this function will\n * create CANCEL request. If no provisional response has been received, the\n * function will not create CANCEL request (the function will return \n * PJ_SUCCESS but the \\a p_tdata will contain NULL) because we cannot send\n * CANCEL before receiving provisional response. If then a provisional\n * response is received, the invite session will send CANCEL automatically.\n * \n * For both UAC and UAS, if the INVITE session has been answered with final\n * response, a BYE request will be created.\n *\n * @param inv\t\tThe invite session.\n * @param st_code\tStatus code to be used for terminating the session.\n * @param st_text\tOptional status text.\n * @param p_tdata\tPointer to receive the message to be created. Note\n *\t\t\tthat it's possible to receive NULL here while the\n *\t\t\tfunction returns PJ_SUCCESS, see the description.\n *\n * @return\t\tPJ_SUCCESS if termination is initiated.\n */\nPJ_DECL(pj_status_t) pjsip_inv_end_session( pjsip_inv_session *inv,\n\t\t\t\t\t    int st_code,\n\t\t\t\t\t    const pj_str_t *st_text,\n\t\t\t\t\t    pjsip_tx_data **p_tdata );\n\n\n/**\n * Create a CANCEL request for an ongoing re-INVITE transaction. If no\n * provisional response has been received, the function will not create\n * CANCEL request (the function will return PJ_SUCCESS but the \\a p_tdata\n * will contain NULL) because we cannot send CANCEL before receiving\n * provisional response. If then a provisional response is received,\n * the invite session will send CANCEL automatically.\n *\n * @param inv\t\tThe invite session.\n * @param p_tdata\tPointer to receive the message to be created. Note\n *\t\t\tthat it's possible to receive NULL here while the\n *\t\t\tfunction returns PJ_SUCCESS, see the description.\n *\n * @return\t\tPJ_SUCCESS if termination is initiated.\n */\nPJ_DECL(pj_status_t) pjsip_inv_cancel_reinvite( pjsip_inv_session *inv,\n\t\t\t\t\t        pjsip_tx_data **p_tdata );\n\n\n/**\n * Create a re-INVITE request. \n *\n * @param inv\t\tThe invite session.\n * @param new_contact\tIf application wants to update its local contact and\n *\t\t\tinform peer to perform target refresh with a new \n *\t\t\tcontact, it can specify the new contact in this \n *\t\t\targument; otherwise this argument must be NULL.\n * @param new_offer\tApplication MAY initiate a new SDP offer/answer \n *\t\t\tsession in the request when there is no pending \n *\t\t\tanswer to be sent or received. It can detect this \n *\t\t\tcondition by observing the state of the SDP \n *\t\t\tnegotiator of the invite session. If new offer \n *\t\t\tshould be sent to remote, the offer must be specified\n *\t\t\tin this argument, otherwise it must be NULL.\n * @param p_tdata\tPointer to receive the re-INVITE request message to\n *\t\t\tbe created.\n *\n * @return\t\tPJ_SUCCESS if a re-INVITE request with the specified\n *\t\t\tcharacteristics (e.g. to contain new offer) can be \n *\t\t\tcreated.\n */\nPJ_DECL(pj_status_t) pjsip_inv_reinvite(pjsip_inv_session *inv,\n\t\t\t\t\tconst pj_str_t *new_contact,\n\t\t\t\t\tconst pjmedia_sdp_session *new_offer,\n\t\t\t\t\tpjsip_tx_data **p_tdata );\n\n\n\n/**\n * Create an UPDATE request to initiate new SDP offer.\n *\n * @param inv\t\tThe invite session.\n * @param new_contact\tIf application wants to update its local contact\n *\t\t\tand inform peer to perform target refresh with a new\n *\t\t\tcontact, it can specify the new contact in this \n *\t\t\targument; otherwise this argument must be NULL.\n * @param offer\t\tOffer to be sent to remote. This argument is\n *\t\t\tmandatory.\n * @param p_tdata\tPointer to receive the UPDATE request message to\n *\t\t\tbe created.\n *\n * @return\t\tPJ_SUCCESS if a UPDATE request with the specified\n *\t\t\tcharacteristics (e.g. to contain new offer) can be \n *\t\t\tcreated.\n */\nPJ_DECL(pj_status_t) pjsip_inv_update (\tpjsip_inv_session *inv,\n\t\t\t\t\tconst pj_str_t *new_contact,\n\t\t\t\t\tconst pjmedia_sdp_session *offer,\n\t\t\t\t\tpjsip_tx_data **p_tdata );\n\n\n/**\n * Create an ACK request. Normally ACK request transmission is handled\n * by the framework. Application only needs to use this function if it\n * handles the ACK transmission manually, by overriding \\a on_send_ack()\n * callback in #pjsip_inv_callback.\n *\n * Note that if the invite session has a pending offer to be answered \n * (for example when the last 2xx response to INVITE contains an offer), \n * application MUST have set the SDP answer with #pjsip_create_sdp_body()\n * prior to creating the ACK request. In this case, the ACK request\n * will be added with SDP message body.\n *\n * @param inv\t\tThe invite session.\n * @param cseq\t\tMandatory argument to specify the CSeq of the\n *\t\t\tACK request. This value MUST match the value\n *\t\t\tof the INVITE transaction to be acknowledged.\n * @param p_tdata\tPointer to receive the ACK request message to\n *\t\t\tbe created.\n *\n * @return\t\tPJ_SUCCESS if ACK request has been created.\n */\nPJ_DECL(pj_status_t) pjsip_inv_create_ack(pjsip_inv_session *inv,\n\t\t\t\t\t  int cseq,\n\t\t\t\t\t  pjsip_tx_data **p_tdata);\n\n\n/**\n * Send request or response message in tdata. \n *\n * @param inv\t\tThe invite session.\n * @param tdata\t\tThe message to be sent.\n *\n * @return\t\tPJ_SUCCESS if transaction can be initiated \n *\t\t\tsuccessfully to send this message. Note that the\n *\t\t\tactual final state of the transaction itself will\n *\t\t\tbe reported later, in on_tsx_state_changed()\n *\t\t\tcallback.\n */\nPJ_DECL(pj_status_t) pjsip_inv_send_msg(pjsip_inv_session *inv,\n\t\t\t\t\tpjsip_tx_data *tdata);\n\n\n/**\n * Get the invite session for the dialog, if any.\n *\n * @param dlg\t\tThe dialog which invite session is being queried.\n *\n * @return\t\tThe invite session instance which has been \n *\t\t\tassociated with this dialog, or NULL.\n */\nPJ_DECL(pjsip_inv_session*) pjsip_dlg_get_inv_session(pjsip_dialog *dlg);\n\n/**\n * Get the invite session instance associated with transaction tsx, if any.\n *\n * @param tsx\t\tThe transaction, which invite session is being \n *\t\t\tqueried.\n *\n * @return\t\tThe invite session instance which has been \n *\t\t\tassociated with this transaction, or NULL.\n */\nPJ_DECL(pjsip_inv_session*) pjsip_tsx_get_inv_session(pjsip_transaction *tsx);\n\n\n/**\n * Get state names for INVITE session state.\n *\n * @param state\t\tThe invite state.\n *\n * @return\t\tString describing the state.\n */\nPJ_DECL(const char *) pjsip_inv_state_name(pjsip_inv_state state);\n\n\n/**\n * This is a utility function to create SIP body for SDP content.\n *\n * @param pool\t\tPool to allocate memory.\n * @param sdp\t\tSDP session to be put in the SIP message body.\n * @param p_body\tPointer to receive SIP message body containing\n *\t\t\tthe SDP session.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_create_sdp_body(pj_pool_t *pool,\n\t\t\t\t\t   pjmedia_sdp_session *sdp,\n\t\t\t\t\t   pjsip_msg_body **p_body);\n\n/**\n * Retrieve SDP information from an incoming message. Application should\n * prefer to use this function rather than parsing the SDP manually since\n * this function supports multipart message body.\n *\n * This function will only parse the SDP once, the first time it is called\n * on the same message. Subsequent call on the same message will just pick\n * up the already parsed SDP from the message.\n *\n * @param rdata\t\tThe incoming message.\n *\n * @return\t\tThe SDP info.\n */\nPJ_DECL(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n\n#endif\t/* __SIP_INVITE_SESSION_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-ua/sip_regc.h",
    "content": "/* $Id: sip_regc.h 4173 2012-06-20 10:39:05Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_SIP_REG_H__\n#define __PJSIP_SIP_REG_H__\n\n/**\n * @file sip_regc.h\n * @brief SIP Registration Client\n */\n\n#include <pjsip/sip_types.h>\n#include <pjsip/sip_auth.h>\n#include <pjsip/sip_transport.h>\n\n\n/**\n * @defgroup PJSUA_REGC Client Registration\n * @ingroup PJSIP_HIGH_UA\n * @brief High Layer API for performing client registration.\n * @{\n *\n * This provides API for performing client registration. Application must\n * link with  <b>pjsip-ua</b> static library to use this API.\n\n */\n\n\nPJ_BEGIN_DECL\n\n/** Typedef for client registration data. */\ntypedef struct pjsip_regc pjsip_regc;\n\n/** Maximum contacts in registration. */\n#define PJSIP_REGC_MAX_CONTACT\t10\n\n/** Expiration not specified. */\n#define PJSIP_REGC_EXPIRATION_NOT_SPECIFIED\t((pj_uint32_t)0xFFFFFFFFUL)\n\n/** Buffer to hold all contacts. */\n#define PJSIP_REGC_CONTACT_BUF_SIZE\t512\n\n/** Structure to hold parameters when calling application's callback.\n *  The application's callback is called when the client registration process\n *  has finished.\n */\nstruct pjsip_regc_cbparam\n{\n    pjsip_regc\t\t*regc;\t    /**< Client registration structure.\t    */\n    void\t\t*token;\t    /**< Arbitrary token set by application */\n\n    /** Error status. If this value is non-PJ_SUCCESS, some error has occured.\n     *  Note that even when this contains PJ_SUCCESS the registration might\n     *  have failed; in this case the \\a code field will contain non\n     *  successful (non-2xx status class) code\n     */\n    pj_status_t\t\t status;\n    int\t\t\t code;\t    /**< SIP status code received.\t    */\n    pj_str_t\t\t reason;    /**< SIP reason phrase received.\t    */\n    pjsip_rx_data\t*rdata;\t    /**< The complete received response.    */\n    int\t\t\t expiration;/**< Next expiration interval.\t    */\n    int\t\t\t contact_cnt;/**<Number of contacts in response.    */\n    pjsip_contact_hdr\t*contact[PJSIP_REGC_MAX_CONTACT]; /**< Contacts.    */\n};\n\n\n/** Type declaration for callback to receive registration result. */\ntypedef void pjsip_regc_cb(struct pjsip_regc_cbparam *param);\n\n/**\n * Structure to hold parameters when calling application's callback\n * specified in #pjsip_regc_set_reg_tsx_cb().\n * To update contact address, application can set the field contact_cnt\n * and contact inside the callback.\n */\nstruct pjsip_regc_tsx_cb_param\n{\n    struct pjsip_regc_cbparam   cbparam;\n    int                         contact_cnt;\n    pj_str_t                    contact[PJSIP_REGC_MAX_CONTACT];\n};\n\n/** Type declaration for callback set in #pjsip_regc_set_reg_tsx_cb(). */\ntypedef void pjsip_regc_tsx_cb(struct pjsip_regc_tsx_cb_param *param);\n\n/**\n * Client registration information.\n */\nstruct pjsip_regc_info\n{\n    pj_str_t\tserver_uri; /**< Server URI,\t\t\t\t    */\n    pj_str_t\tclient_uri; /**< Client URI (From header).\t\t    */\n    pj_bool_t\tis_busy;    /**< Have pending transaction?\t\t    */\n    pj_bool_t\tauto_reg;   /**< Will register automatically?\t\t    */\n    int\t\tinterval;   /**< Registration interval (seconds).\t    */\n    int\t\tnext_reg;   /**< Time until next registration (seconds).    */\n    pjsip_transport *transport; /**< Last transport used.\t\t    */\n};\n\n/**\n * @see pjsip_regc_info\n */\ntypedef struct pjsip_regc_info pjsip_regc_info;\n\n\n/**\n * Get the module instance for client registration module.\n *\n * @return\t    client registration module.\n */\nPJ_DECL(pjsip_module*) pjsip_regc_get_module(void);\n\n\n/**\n * Create client registration structure.\n *\n * @param endpt\t    Endpoint, used to allocate pool from.\n * @param token\t    A data to be associated with the client registration struct.\n * @param cb\t    Pointer to callback function to receive registration status.\n * @param p_regc    Pointer to receive client registration structure.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_create( pjsip_endpoint *endpt, void *token,\n\t\t\t\t        pjsip_regc_cb *cb, \n\t\t\t\t\tpjsip_regc **p_regc);\n\n\n/**\n * Destroy client registration structure. If a registration transaction is\n * in progress, then the structure will be deleted only after a final response\n * has been received, and in this case, the callback won't be called.\n *\n * @param regc\t    The client registration structure.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_destroy(pjsip_regc *regc);\n\n/**\n * Get registration info.\n *\n * @param regc\t    The client registration structure.\n * @param info\t    Client registration info.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_get_info( pjsip_regc *regc,\n\t\t\t\t\t  pjsip_regc_info *info );\n\n\n/**\n * Get the memory pool associated with a registration client handle.\n *\n * @param regc\t    The client registration structure.\n * @return pool\t    handle.\n */\nPJ_DECL(pj_pool_t*) pjsip_regc_get_pool(pjsip_regc *regc);\n\n/**\n * Initialize client registration structure with various information needed to\n * perform the registration.\n *\n * @param regc\t    The client registration structure.\n * @param srv_url   Server URL.\n * @param from_url  The person performing the registration, must be a SIP URL type.\n * @param to_url    The address of record for which the registration is targetd, must\n *\t\t    be a SIP/SIPS URL.\n * @param ccnt\t    Number of contacts in the array.\n * @param contact   Array of contacts, each contact item must be formatted\n *\t\t    as described in RFC 3261 Section 20.10:\n *\t\t    When the header field value contains a display \n *\t\t    name, the URI including all URI parameters is \n *\t\t    enclosed in \"<\" and \">\".  If no \"<\" and \">\" are \n *\t\t    present, all parameters after the URI are header\n *\t\t    parameters, not URI parameters.  The display name \n *\t\t    can be tokens, or a quoted string, if a larger \n *\t\t    character set is desired.\n * @param expires   Default expiration interval (in seconds) to be applied for\n *\t\t    contact URL that doesn't have expiration settings. If the\n *\t\t    value PJSIP_REGC_EXPIRATION_NOT_SPECIFIED is given, then \n *\t\t    no default expiration will be applied.\n * @return\t    zero on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_init(pjsip_regc *regc,\n\t\t\t\t     const pj_str_t *srv_url,\n\t\t\t\t     const pj_str_t *from_url,\n\t\t\t\t     const pj_str_t *to_url,\n\t\t\t\t     int ccnt,\n\t\t\t\t     const pj_str_t contact[],\n\t\t\t\t     pj_uint32_t expires);\n\n/**\n * Set callback to be called when the registration received a final response.\n * This callback is different with the one specified during creation via\n * #pjsip_regc_create(). This callback will be called for any final response\n * (including 401/407/423) and before any subsequent requests are sent.\n * In case of unregistration, this callback will not be called.\n *\n * @param regc\t    The client registration structure.\n * @param tsx_cb    Pointer to callback function to receive registration status.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_set_reg_tsx_cb(pjsip_regc *regc,\n\t\t\t\t               pjsip_regc_tsx_cb *tsx_cb);\n\n/**\n * Set the \"sent-by\" field of the Via header for outgoing requests.\n *\n * @param regc\t    The client registration structure.\n * @param via_addr  Set via_addr to use for the Via header or NULL to use\n *                  the transport's published name.\n * @param via_tp    via_addr will only be used if we are using via_tp\n *                  transport.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_set_via_sent_by(pjsip_regc *regc,\n\t\t\t\t                pjsip_host_port *via_addr,\n                                                pjsip_transport *via_tp);\n\n/**\n * Set the number of seconds to refresh the client registration before\n * the registration expires.\n *\n * @param regc\t    The registration structure.\n * @param delay     The number of seconds to refresh the client\n *                  registration before the registration expires.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t)\npjsip_regc_set_delay_before_refresh( pjsip_regc *regc,\n\t\t\t\t     pj_uint32_t delay );\n\n\n/**\n * Set authentication credentials to use by this registration.\n *\n * @param regc\t    The registration structure.\n * @param count\t    Number of credentials in the array.\n * @param cred\t    Array of credentials.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_set_credentials( pjsip_regc *regc,\n\t\t\t\t\t\t int count,\n\t\t\t\t\t\t const pjsip_cred_info cred[] );\n\n/**\n * Set authentication preference.\n *\n * @param regc\t    The registration structure.\n * @param pref\t    Authentication preference.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_set_prefs( pjsip_regc *regc,\n\t\t\t\t\t   const pjsip_auth_clt_pref *pref);\n\n/**\n * Set route set to be used for outgoing requests.\n *\n * @param regc\t    The client registration structure.\n * @param route_set List containing Route headers.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_set_route_set(pjsip_regc *regc,\n\t\t\t\t\t      const pjsip_route_hdr*route_set);\n\n\n/**\n * Lock/bind client registration to a specific transport/listener. \n * This is optional, as normally transport will be selected automatically\n * based on the destination of requests upon resolver completion. \n * When the client registration is explicitly bound to the specific \n * transport/listener, all UAC transactions originated by the client\n * registration will use the specified transport/listener when sending \n * outgoing requests.\n *\n * Note that this doesn't affect the Contact header set for this client\n * registration. Application must manually update the Contact header if\n * necessary, to adjust the address according to the transport being\n * selected.\n *\n * @param regc\t    The client registration instance.\n * @param sel\t    Transport selector containing the specification of\n *\t\t    transport or listener to be used by this session\n *\t\t    to send requests.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_regc_set_transport(pjsip_regc *regc,\n\t\t\t\t\t      const pjsip_tpselector *sel);\n\n/**\n * Release the reference to current transport being used by the regc, if any.\n * The regc keeps the reference to the last transport being used in order\n * to prevent it from being destroyed. In some situation however, such as\n * when the transport is disconnected, it is necessary to instruct the\n * regc to release this reference so that the transport can be destroyed.\n * See https://trac.pjsip.org/repos/ticket/1481 for background info.\n *\n * @param regc\t    The client registration instance.\n *\n * @return\t    PJ_SUCCESS on success, or the appropriate error code.\n */\nPJ_DECL(pj_status_t) pjsip_regc_release_transport(pjsip_regc *regc);\n\n/**\n * Add headers to be added to outgoing REGISTER requests.\n *\n * @param regc\t    The client registration structure.\n * @param hdr_list  List containing SIP headers to be added for all outgoing\n *\t\t    REGISTER requests.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_add_headers(pjsip_regc *regc,\n\t\t\t\t\t    const pjsip_hdr *hdr_list);\n\n\n/**\n * Create REGISTER request for the specified client registration structure.\n *\n * After successfull registration, application can inspect the contacts in\n * the client registration structure to list what contacts are associaciated\n * with the address of record being targeted in the registration.\n *\n * @param regc\t    The client registration structure.\n * @param autoreg   If non zero, the library will automatically refresh the\n *\t\t    next registration until application unregister.\n * @param p_tdata   Pointer to receive the REGISTER request.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg,\n\t\t\t\t\t pjsip_tx_data **p_tdata);\n\n\n/**\n * Create REGISTER request to unregister the contacts that were previously\n * registered by this client registration.\n *\n * @param regc\t    The client registration structure.\n * @param p_tdata   Pointer to receive the REGISTER request.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_unregister(pjsip_regc *regc,\n\t\t\t\t\t   pjsip_tx_data **p_tdata);\n\n/**\n * Create REGISTER request to unregister all contacts from server records.\n * Note that this will unregister all registered contact for the AOR\n * including contacts registered by other user agents. To only unregister\n * contact registered by this client registration instance, use\n * #pjsip_regc_unregister() instead.\n *\n * @param regc\t    The client registration structure.\n * @param p_tdata   Pointer to receive the REGISTER request.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_unregister_all(pjsip_regc *regc,\n\t\t\t\t\t       pjsip_tx_data **p_tdata);\n\n/**\n * Update Contact details in the client registration structure. For each\n * contact, if the contact is not found in existing contact, it will be\n * added to the Contact list. If it matches existing contact, nothing\n * will be added. This function will also mark existing contacts which\n * are not specified in the new contact list as to be removed, by adding\n * \"expires=0\" parameter to these contacts.\n *\n * Once the contact list has been updated, application must update the\n * registration by creating a new REGISTER request and send it to the\n * registrar. This request will contain both old and new contacts; the\n * old contacts will have it's expires parameter set to zero to instruct\n * the registrar to remove the bindings.\n *\n * @param regc\t    The client registration structure.\n * @param ccnt\t    Number of contacts.\n * @param contact   Array of contacts, each contact item must be formatted\n *\t\t    as described in RFC 3261 Section 20.10:\n *\t\t    When the header field value contains a display \n *\t\t    name, the URI including all URI parameters is \n *\t\t    enclosed in \"<\" and \">\".  If no \"<\" and \">\" are \n *\t\t    present, all parameters after the URI are header\n *\t\t    parameters, not URI parameters.  The display name \n *\t\t    can be tokens, or a quoted string, if a larger \n *\t\t    character set is desired.\n * @return\t    PJ_SUCCESS if sucessfull.\n */\nPJ_DECL(pj_status_t) pjsip_regc_update_contact( pjsip_regc *regc,\n\t\t\t\t\t        int ccnt,\n\t\t\t\t\t\tconst pj_str_t contact[] );\n\n/**\n * Update the expires value. The next REGISTER request will contain\n * new expires value for the registration.\n *\n * @param regc\t    The client registration structure.\n * @param expires   The new expires value.\n * @return\t    zero on successfull.\n */\nPJ_DECL(pj_status_t) pjsip_regc_update_expires( pjsip_regc *regc,\n\t\t\t\t\t        pj_uint32_t expires );\n\n/**\n * Sends outgoing REGISTER request.\n * The process will complete asynchronously, and application\n * will be notified via the callback when the process completes.\n *\n * @param regc\t    The client registration structure.\n * @param tdata\t    Transmit data.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJSIP_REG_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-ua/sip_replaces.h",
    "content": "/* $Id: sip_replaces.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_REPLACES_H__\n#define __PJSIP_REPLACES_H__\n\n\n/**\n * @file sip_replaces.h\n * @brief SIP Replaces support (RFC 3891 - SIP \"Replaces\" Header)\n */\n#include <pjsip/sip_msg.h>\n\n/**\n * @defgroup PJSIP_REPLACES SIP Replaces support (RFC 3891 - \"Replaces\" Header)\n * @ingroup PJSIP_HIGH_UA\n * @brief SIP Replaces support (RFC 3891 - \"Replaces\" Header)\n * @{\n *\n * This module implements support for Replaces header in PJSIP. The Replaces\n * specification is written in RFC 3891 - The Session Initiation Protocol (SIP) \n * \"Replaces\" Header, and can be used to enable a variety of features, \n * for example: \"Attended Transfer\" and \"Call Pickup\".\n *\n * \n *\n * \\section PJSIP_REPLACES_USING_SEC Using PJSIP Replaces Support\n *\n * \\subsection PJSIP_REPLACES_INIT_SUBSEC Initialization\n *\n * Application needs to call #pjsip_replaces_init_module() during application\n * initialization stage to register \"replaces\" support in PJSIP. \n *\n *\n * \n * \\subsection PJSIP_REPLACES_UAC_SUBSEC UAC Behavior: Sending a Replaces Header\n *\n * A User Agent that wishes to replace a single existing early or\n * confirmed dialog with a new dialog of its own, MAY send the target\n * User Agent an INVITE request containing a Replaces header field.  The\n * User Agent Client (UAC) places the Call-ID, to-tag, and from-tag\n * information for the target dialog in a single Replaces header field\n * and sends the new INVITE to the target.\n *\n * To initiate outgoing INVITE request with Replaces header, application\n * would create the INVITE request with #pjsip_inv_invite(), then adds\n * #pjsip_replaces_hdr instance into the request, filling up the Call-ID,\n * To-tag, and From-tag properties of the header with the identification\n * of the dialog to be replaced. Application may also optionally\n * set the \\a early_only property of the header to indicate that it only\n * wants to replace early dialog.\n *\n * Note that when the outgoing INVITE request (with Replaces) is initiated\n * from an incoming REFER request (as in Attended Call Transfer case),\n * this process should be done rather more automatically by PJSIP. Upon \n * receiving incoming incoming REFER request, normally these processes\n * will be performed:\n *  - Application finds \\a Refer-To header,\n *  - Application creates outgoing dialog/invite session, specifying\n *    the URI in the \\a Refer-To header as the initial remote target,\n *  - The URI in the \\a Refer-To header may contain header parameters such\n *    as \\a Replaces and \\a Require headers.\n *  - The dialog keeps the header fields in the header parameters\n *    of the URI, and the invite session would add these headers into\n *    the outgoing INVITE request. Because of this, the outgoing \n *    INVITE request will contain the \\a Replaces and \\a Require headers.\n *\n *\n * For more information, please see the implementation of \n * #pjsua_call_xfer_replaces() in \\ref PJSUA_LIB source code.\n *\n *\n * \\subsection PJSIP_REPLACES_UAS_SUBSEC UAS Behavior: Receiving a Replaces Header\n *\n * The Replaces header contains information used to match an existing\n * SIP dialog (call-id, to-tag, and from-tag).  Upon receiving an INVITE\n * with a Replaces header, the User Agent (UA) attempts to match this\n * information with a confirmed or early dialog.  \n *\n * In PJSIP, if application wants to process the Replaces header in the\n * incoming INVITE request, it should call #pjsip_replaces_verify_request()\n * before creating the INVITE session. The #pjsip_replaces_verify_request()\n * function checks and verifies the request to see if Replaces request\n * can be processed. To be more specific, it performs the following\n * verification:\n *  - checks that Replaces header is present. If not, the function will\n *    return PJ_SUCCESS without doing anything.\n *  - checks that no duplicate Replaces headers are present, or otherwise\n *    it will return 400 \"Bad Request\" response.\n *  - checks for matching dialog and verifies that the invite session has\n *    the correct state, and may return 481 \"Call/Transaction Does Not Exist\",\n *    603 \"Declined\", or 486 \"Busy Here\" according to the processing rules\n *    specified in RFC 3891.\n *  - if matching dialog with correct state is found, it will give PJ_SUCCESS\n *    status and return the matching dialog back to the application.\n *\n * The following pseudocode illustrates how application can process the\n * incoming INVITE if it wants to support Replaces extension:\n *\n \\code\n  // Incoming INVITE request handler\n  pj_bool_t on_rx_invite(pjsip_rx_data *rdata)\n  {\n    pjsip_dialog *dlg, *replaced_dlg;\n    pjsip_inv_session *inv;\n    pjsip_tx_data *response;\n    pj_status_t status;\n\n    // Check whether Replaces header is present in the request and process accordingly.\n    //\n    status = pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE, &response);\n    if (status != PJ_SUCCESS) {\n\t// Something wrong with Replaces request.\n\t//\n\tif (response) {\n\t    pjsip_endpt_send_response(endpt, rdata, response, NULL, NULL);\n\t} else {\n\t    // Respond with 500 (Internal Server Error)\n\t    pjsip_endpt_respond_stateless(endpt, rdata, 500, NULL, NULL, NULL);\n\t}\n    }\n\n    // Create UAS Invite session as usual.\n    //\n    status = pjsip_dlg_create_uas_and_inc_lock(.., rdata, .., &dlg);\n    ..\n    status = pjsip_inv_create_uas(dlg, .., &inv);\n\n    // Send initial 100 \"Trying\" to the INVITE request\n    //\n    status = pjsip_inv_initial_answer(inv, rdata, 100, ..., &response);\n    if (status == PJ_SUCCESS)\n\tpjsip_inv_send_msg(inv, response);\n\n\n    // This is where processing is different between normal call\n    // (without Replaces) and call with Replaces.\n    //\n    if (replaced_dlg) {\n\tpjsip_inv_session *replaced_inv;\n\n\t// Always answer the new INVITE with 200, regardless whether\n\t// the replaced call is in early or confirmed state.\n\t//\n\tstatus = pjsip_inv_answer(inv, 200, NULL, NULL, &response);\n\tif (status == PJ_SUCCESS)\n\t    pjsip_inv_send_msg(inv, response);\n\n\n\t// Get the INVITE session associated with the replaced dialog.\n\t//\n\treplaced_inv = pjsip_dlg_get_inv_session(replaced_dlg);\n\n\n\t// Disconnect the \"replaced\" INVITE session.\n\t//\n\tstatus = pjsip_inv_end_session(replaced_inv, PJSIP_SC_GONE, NULL, &tdata);\n\tif (status == PJ_SUCCESS && tdata)\n\t    status = pjsip_inv_send_msg(replaced_inv, tdata);\n\n\n\t// It's up to application to associate the new INVITE session\n\t// with the old (now terminated) session. For example, application\n\t// may assign the same User Interface object for the new INVITE\n\t// session.\n\n    } else {\n\t// Process normal INVITE without Replaces.\n\t...\n    }\n  }\n\n \\endcode\n *\n *\n * For a complete sample implementation, please see \\a pjsua_call_on_incoming()\n * function of \\ref PJSUA_LIB in \\a pjsua_call.c file.\n *\n *\n * \\section PJSIP_REPLACES_REFERENCE References\n *\n * References:\n *  - <A HREF=\"http://www.ietf.org/rfc/rfc3891.txt\">RFC 3891: The Session \n *    Initiation Protocol (SIP) \"Replaces\" Header</A>\n *  - \\ref PJSUA_XFER\n */\n\nPJ_BEGIN_DECL\n\n\n/**\n * Declaration of SIP Replaces header (RFC 3891).\n */\ntypedef struct pjsip_replaces_hdr\n{\n    /** Standard header field. */\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_replaces_hdr);\n\n    /** Call-Id */\n    pj_str_t\tcall_id;\n\n    /** to-tag */\n    pj_str_t\tto_tag;\n\n    /** from-tag */\n    pj_str_t\tfrom_tag;\n\n    /** early-only? */\n    pj_bool_t\tearly_only;\n\n    /** Other parameters */\n    pjsip_param\tother_param;\n\n} pjsip_replaces_hdr;\n\n\n\n/**\n * Initialize Replaces support in PJSIP. This would, among other things, \n * register the header parser for Replaces header.\n *\n * @param endpt\t    The endpoint instance.\n *\n * @return\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_replaces_init_module(pjsip_endpoint *endpt);\n\n\n/**\n * Create Replaces header.\n *\n * @param pool\t    Pool to allocate the header instance from.\n *\n * @return\t    An empty Replaces header instance.\n */\nPJ_DECL(pjsip_replaces_hdr*) pjsip_replaces_hdr_create(pj_pool_t *pool);\n\n\n/**\n * Verify that incoming request with Replaces header can be processed.\n * This function will perform all necessary checks according to RFC 3891\n * Section 3 \"User Agent Server Behavior: Receiving a Replaces Header\".\n *\n * @param rdata\t    The incoming request to be verified.\n * @param p_dlg\t    On return, it will be filled with the matching \n *\t\t    dialog.\n * @param lock_dlg  Specifies whether this function should acquire lock\n *\t\t    to the matching dialog. If yes (and should be yes!),\n *\t\t    then application will need to release the dialog's\n *\t\t    lock with #pjsip_dlg_dec_lock() when the function\n *\t\t    returns PJ_SUCCESS and the \\a p_dlg parameter is filled\n *\t\t    with the dialog instance.\n * @param p_tdata   Upon error, it will be filled with the final response\n *\t\t    to be sent to the request sender.\n *\n * @return\t    The function returns the following:\n *\t\t    - If the request doesn't contain Replaces header, the\n *\t\t      function returns PJ_SUCCESS and \\a p_dlg parameter\n *\t\t      will be set to NULL.\n *\t\t    - If the request contains Replaces header and a valid,\n *\t\t      matching dialog is found, the function returns \n *\t\t      PJ_SUCCESS and \\a p_dlg parameter will be set to the\n *\t\t      matching dialog instance.\n *\t\t    - Upon error condition (as described by RFC 3891), the\n *\t\t      function returns non-PJ_SUCCESS, and \\a p_tdata \n *\t\t      parameter SHOULD be set with a final response message\n *\t\t      to be sent to the sender of the request.\n */\nPJ_DECL(pj_status_t) pjsip_replaces_verify_request(pjsip_rx_data *rdata,\n\t\t\t\t\t\t   pjsip_dialog **p_dlg,\n\t\t\t\t\t\t   pj_bool_t lock_dlg,\n\t\t\t\t\t\t   pjsip_tx_data **p_tdata);\n\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJSIP_REPLACES_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-ua/sip_timer.h",
    "content": "/* $Id: sip_timer.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_TIMER_H__\n#define __PJSIP_TIMER_H__\n\n\n/**\n * @file sip_timer.h\n * @brief SIP Session Timers support (RFC 4028 - Session Timer in SIP)\n */\n\n#include <pjsip-ua/sip_inv.h>\n#include <pjsip/sip_msg.h>\n\n/**\n * @defgroup PJSIP_TIMER SIP Session Timers support (RFC 4028 - Session Timers in SIP)\n * @ingroup PJSIP_HIGH_UA\n * @brief SIP Session Timers support (RFC 4028 - Session Timers in SIP)\n * @{\n *\n * \\section PJSIP_TIMER_REFERENCE References\n *\n * References:\n *  - <A HREF=\"http://www.ietf.org/rfc/rfc4028.txt\">RFC 4028: Session Timers \n *    in the Session Initiation Protocol (SIP)</A>\n */\n\nPJ_BEGIN_DECL\n\n/**\n * Opaque declaration of Session Timers.\n */\ntypedef struct pjsip_timer pjsip_timer;\n\n\n/**\n * This structure describes Session Timers settings in an invite session.\n */\ntypedef struct pjsip_timer_setting\n{\n    /** \n     * Specify minimum session expiration period, in seconds. Must not be\n     * lower than 90. Default is 90.\n     */\n    unsigned\t\t\t min_se;\n\n    /**\n     * Specify session expiration period, in seconds. Must not be lower than\n     * #min_se. Default is 1800.\n     */\n    unsigned\t\t\t sess_expires;\t\n\n} pjsip_timer_setting;\n\n\n/**\n * SIP Session-Expires header (RFC 4028).\n */\ntypedef struct pjsip_sess_expires_hdr\n{\n    /** Standard header field. */\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_sess_expires_hdr);\n\n    /** Session expiration period */\n    unsigned\tsess_expires;\n\n    /** Refresher */\n    pj_str_t\trefresher;\n\n    /** Other parameters */\n    pjsip_param\tother_param;\n\n} pjsip_sess_expires_hdr;\n\n\n/**\n * SIP Min-SE header (RFC 4028).\n */\ntypedef struct pjsip_min_se_hdr\n{\n    /** Standard header field. */\n    PJSIP_DECL_HDR_MEMBER(struct pjsip_min_se_hdr);\n\n    /** Minimum session expiration period */\n    unsigned\tmin_se;\n\n    /** Other parameters */\n    pjsip_param\tother_param;\n\n} pjsip_min_se_hdr;\n\n\n\n/**\n * Initialize Session Timers module. This function must be called once during\n * application initialization, to register this module to SIP endpoint.\n *\n * @param endpt\t\tThe SIP endpoint instance.\n *\n * @return\t\tPJ_SUCCESS if module is successfully initialized.\n */\nPJ_DECL(pj_status_t) pjsip_timer_init_module(pjsip_endpoint *endpt);\n\n\n/**\n * Initialize Session Timers setting with default values.\n *\n * @param setting\tSession Timers setting to be initialized.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pjsip_timer_setting_default(pjsip_timer_setting *setting);\n\n\n/**\n * Initialize Session Timers for an invite session. This function should be\n * called by application to apply Session Timers setting, otherwise invite\n * session will apply default setting to the Session Timers.\n *\n * @param inv\t\tThe invite session.\n * @param setting\tSession Timers setting, see @pjsip_timer_setting.\n *\t\t\tIf setting is NULL, default setting will be applied.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pjsip_timer_init_session(\n\t\t\t\t\tpjsip_inv_session *inv,\n\t\t\t\t\tconst pjsip_timer_setting *setting);\n\n\n/**\n * Create Session-Expires header.\n *\n * @param pool\t\tPool to allocate the header instance from.\n *\n * @return\t\tAn empty Session-Expires header instance.\n */\nPJ_DECL(pjsip_sess_expires_hdr*) pjsip_sess_expires_hdr_create(\n\t\t\t\t\t\t\tpj_pool_t *pool);\n\n\n/**\n * Create Min-SE header.\n *\n * @param pool\t\tPool to allocate the header instance from.\n *\n * @return\t\tAn empty Min-SE header instance.\n */\nPJ_DECL(pjsip_min_se_hdr*) pjsip_min_se_hdr_create(pj_pool_t *pool);\n\n\n/**\n * Update outgoing request to insert Session Timers headers and also\n * signal Session Timers capability in Supported and/or Require headers.\n *\n * This function will be called internally by the invite session if it \n * detects that the session needs Session Timers support.\n *\n * @param inv\t\tThe invite session.\n * @param tdata\t\tOutgoing INVITE or UPDATE request.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pjsip_timer_update_req(pjsip_inv_session *inv,\n\t\t\t\t\t    pjsip_tx_data *tdata);\n\n\n/**\n * Process Session Timers headers in incoming response, this function\n * will only process incoming response with status code 422 (Session\n * Interval Too Small) or 2xx (final response).\n *\n * This function will be called internally by the invite session if it \n * detects that the session needs Session Timers support.\n *\n * @param inv\t\tThe invite session.\n * @param rdata\t\tIncoming response data.\n * @param st_code\tOutput buffer to store corresponding SIP status code \n *\t\t\twhen function returning non-PJ_SUCCESS.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pjsip_timer_process_resp(pjsip_inv_session *inv,\n\t\t\t\t\t      const pjsip_rx_data *rdata,\n\t\t\t\t\t      pjsip_status_code *st_code);\n\n/**\n * Process Session Timers refresh error, this function will process\n * error from refresh request. The error will be handle according the\n * error code, i.e : BYE will be sent after error 503 (Transport Error).\n *\n * @param inv\t\t The invite session.\n * @param event\t\t The event that trigger the error.\n *\n * @return\t\t PJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t)  pjsip_timer_handle_refresh_error(\n\t\t\t\t\t    pjsip_inv_session *inv,\n\t\t\t\t\t    pjsip_event *event);\n\n/**\n * Process Session Timers headers in incoming request, this function\n * will only process incoming INVITE and UPDATE request.\n *\n * This function will be called internally by the invite session if it \n * detects that the session needs Session Timers support.\n *\n * @param inv\t\tThe invite session.\n * @param rdata\t\tIncoming INVITE or UPDATE request.\n * @param st_code\tOutput buffer to store corresponding SIP status code \n *\t\t\twhen function returning non-PJ_SUCCESS.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pjsip_timer_process_req(pjsip_inv_session *inv,\n\t\t\t\t\t     const pjsip_rx_data *rdata,\n\t\t\t\t\t     pjsip_status_code *st_code);\n\n\n/**\n * Update outgoing response to insert Session Timers headers and also\n * signal Session Timers capability in Supported and/or Require headers.\n * This function will only update outgoing response with status code \n * 422 (Session Interval Too Small) or 2xx (final response).\n *\n * This function will be called internally by the invite session if it \n * detects that the session needs Session Timers support.\n *\n * @param inv\t\tThe invite session.\n * @param tdata\t\tOutgoing 422/2xx response.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pjsip_timer_update_resp(pjsip_inv_session *inv,\n\t\t\t\t\t     pjsip_tx_data *tdata);\n\n/**\n * End Session Timers in an invite session.\n *\n * This function will be called internally by the invite session if it \n * detects that the session needs Session Timers support.\n *\n * @param inv\t\tThe invite session.\n *\n * @return\t\tPJ_SUCCESS on successful.\n */\nPJ_DECL(pj_status_t) pjsip_timer_end_session(pjsip_inv_session *inv);\n\n\n\nPJ_END_DECL\n\n\n/**\n * @}\n */\n\n\n#endif\t/* __PJSIP_TIMER_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip-ua/sip_xfer.h",
    "content": "/* $Id: sip_xfer.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_XFER_H__\n#define __PJSIP_XFER_H__\n\n\n\n/**\n * @file sip_xfer.h\n * @brief SIP Transfer (REFER, RFC 3515)\n */\n#include <pjsip-simple/evsub.h>\n#include <pjsip/sip_msg.h>\n\n/**\n * @defgroup PJSUA_XFER SIP REFER (RFC 3515) for Call Transfer etc.\n * @ingroup PJSIP_HIGH_UA\n * @brief SIP REFER dialog usage (call transfer, etc.)\n * @{\n *\n * This describes a generic handling of SIP REFER request. The SIP REFER\n * request is described in RFC 3515, and commonly used to perform call\n * transfer functionality. Other types of SIP REFER usages are described\n * in draft-worley-sip-many-refers-00 draft, for example:\n *  - Remote Dial: where UAC sends REFER to instruct REFER recipient to\n *    initiate an INVITE session to some target.\n * \n * A REFER request can be sent inside or outside existing dialog context,\n * although for call transfer case, it is more common to send REFER inside\n * existing INVITE session context. PJSIP supports both sending REFER request\n * inside or outside dialog context.\n *\n * The REFER framework uses @ref PJSIP_EVENT_NOT to manage the event\n * subscription created by the REFER request. Because of this, application \n * must link with <b>pjsip-ua</b> AND <b>pjsip-simple</b> static libraries \n * to use REFER functionality.\n *\n * Reference:\n *  - <A HREF=\"http://www.ietf.org/rfc/rfc3515.txt\">RFC 3515: The Session \n *    Initiation Protocol (SIP) Refer Method</A>\n *  - @ref PJSIP_EVENT_NOT\n */\n\n\nPJ_BEGIN_DECL\n\n\n/** Declaration for REFER method constant. */\nPJ_DECL_DATA(const pjsip_method) pjsip_refer_method;\n\n/** Get REFER method constant */\nPJ_DECL(const pjsip_method*) pjsip_get_refer_method(void);\n\n\n/**\n * Initialize the REFER subsystem.\n * This currently does very little (only register REFER as supported method).\n */\nPJ_DECL(pj_status_t) pjsip_xfer_init_module(pjsip_endpoint *endpt);\n\n\n\n/**\n * Create transferer (sender of REFER request).\n *\n * @param dlg\t\tThe underlying dialog to use.\n * @param user_cb\tPointer to callbacks to receive presence subscription\n *\t\t\tevents.\n * @param p_evsub\tPointer to receive the presence subscription\n *\t\t\tsession.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_xfer_create_uac( pjsip_dialog *dlg,\n\t\t\t\t\t    const pjsip_evsub_user *user_cb,\n\t\t\t\t\t    pjsip_evsub **p_evsub );\n\n\n/**\n * Create transferee (receiver of REFER request).\n *\n * @param dlg\t\tThe underlying dialog to use.\n * @param user_cb\tPointer to callbacks to receive presence subscription\n *\t\t\tevents.\n * @param rdata\t\tThe incoming SUBSCRIBE request that creates the event \n *\t\t\tsubscription.\n * @param p_evsub\tPointer to receive the presence subscription\n *\t\t\tsession.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_xfer_create_uas( pjsip_dialog *dlg,\n\t\t\t\t\t    const pjsip_evsub_user *user_cb,\n\t\t\t\t\t    pjsip_rx_data *rdata,\n\t\t\t\t\t    pjsip_evsub **p_evsub );\n\n/**\n * Call this function to create request to initiate REFER subscription,\n * to refresh subscription, or to unsubscribe. For request other than\n * the initial REFER request, \"refer_to_uri\" argument may be NULL.\n *\n * @param sub\t\tClient subscription instance.\n * @param refer_to_uri\tURI to be put to the Refer-To header. This argument\n *\t\t\tmay be NULL for subsequent REFER requests.\n * @param p_tdata\tPointer to receive the request.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_xfer_initiate( pjsip_evsub *sub,\n\t\t\t\t\t  const pj_str_t *refer_to_uri,\n\t\t\t\t\t  pjsip_tx_data **p_tdata);\n\n\n/**\n * Accept the incoming REFER request by sending 2xx response.\n *\n * @param sub\t\tServer subscription instance.\n * @param rdata\t\tThe incoming subscription request message.\n * @param st_code\tStatus code, which MUST be 2xx.\n * @param hdr_list\tOptional list of headers to be added in the response.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_xfer_accept( pjsip_evsub *sub,\n\t\t\t\t\tpjsip_rx_data *rdata,\n\t\t\t\t        int st_code,\n\t\t\t\t\tconst pjsip_hdr *hdr_list );\n\n\n/**\n * For notifier, create NOTIFY request to subscriber, and set the state \n * of the subscription. \n *\n * @param sub\t\tThe server subscription (notifier) instance.\n * @param state\t\tNew state to set.\n * @param xfer_st_code\tThe call status code to be reported with the NOTIFY\n *\t\t\trequest.\n * @param xfer_st_text\tOptional call status text to be reported with the \n *\t\t\tNOTIFY request. If the value is NULL, default \n *\t\t\tstatus text will be used.\n * @param p_tdata\tPointer to receive the request.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_xfer_notify( pjsip_evsub *sub,\n\t\t\t\t\tpjsip_evsub_state state,\n\t\t\t\t\tint xfer_st_code,\n\t\t\t\t\tconst pj_str_t *xfer_st_text,\n\t\t\t\t\tpjsip_tx_data **p_tdata);\n\n\n/**\n * Create NOTIFY request to reflect current subscription status. Application\n * can only call this function after it has sent NOTIFY before.\n * This will also re-send the last \"message/sipfrag\" body that was sent\n * in the previous NOTIFY.\n *\n * @param sub\t\tServer subscription object.\n * @param p_tdata\tPointer to receive request.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_xfer_current_notify( pjsip_evsub *sub,\n\t\t\t\t\t        pjsip_tx_data **p_tdata );\n\n\n\n/**\n * Send request message that was previously created with initiate(), notify(),\n * or current_notify(). Application may also send request created with other\n * functions, e.g. authentication. But the request MUST be either request\n * that creates/refresh subscription or NOTIFY request.\n *\n *\n * @param sub\t\tThe event subscription object.\n * @param tdata\t\tRequest message to be send.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) pjsip_xfer_send_request( pjsip_evsub *sub,\n\t\t\t\t\t      pjsip_tx_data *tdata);\n\n\nPJ_END_DECL\n\n/**\n * @}\n */\n\n#endif\t/* __PJSIP_XFER_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip.h",
    "content": "/* $Id: pjsip.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_H__\n#define __PJSIP_H__\n\n/* Base types. */\n#include <pjsip/sip_types.h>\n#include <pjsip/sip_errno.h>\n\n/* Messaging and parsing. */\n#include <pjsip/sip_uri.h>\n#include <pjsip/sip_tel_uri.h>\n#include <pjsip/sip_msg.h>\n#include <pjsip/sip_multipart.h>\n#include <pjsip/sip_parser.h>\n\n/* Core */\n#include <pjsip/sip_event.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_util.h>\n\n/* Transport layer */\n#include <pjsip/sip_transport.h>\n#include <pjsip/sip_transport_udp.h>\n#include <pjsip/sip_transport_loop.h>\n#include <pjsip/sip_transport_tcp.h>\n#include <pjsip/sip_transport_tls.h>\n#include <pjsip/sip_resolve.h>\n\n/* Authentication. */\n#include <pjsip/sip_auth.h>\n#include <pjsip/sip_auth_aka.h>\n\n/* Transaction layer. */\n#include <pjsip/sip_transaction.h>\n\n/* UA Layer. */\n#include <pjsip/sip_ua_layer.h>\n#include <pjsip/sip_dialog.h>\n\n\n#endif\t/* __PJSIP_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip_auth.h",
    "content": "/* $Id: pjsip_auth.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_AUTH_H__\n#define __PJSIP_AUTH_H__\n\n/**\n * @defgroup PJSIP_AUTH SIP Authorization module\n */\n\n/**\n * @file pjsip_auth.h\n * @brief SIP Authorization Module.\n */\n\n\n#include <pjsip_auth/sip_auth.h>\n#include <pjsip_auth/sip_auth_msg.h>\n#include <pjsip_auth/sip_auth_parser.h>\n\n#endif\t/* __PJSIP_AUTH_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip_simple.h",
    "content": "/* $Id: pjsip_simple.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/**\n * @defgroup PJSIP_SIMPLE Event and Presence Framework\n */\n\n/**\n * @file pjsip_simple.h\n * @brief SIP SIMPLE Extension\n */\n\n/*\n * Include this header file to get all functionalities for SIMPLE extension\n * (SIP for Instant Messaging and Presence Leveraging Extension).\n */\n#ifndef __PJSIP_SIMPLE_H__\n#define __PJSIP_SIMPLE_H__\n\n#include <pjsip-simple/evsub.h>\n#include <pjsip-simple/evsub_msg.h>\n#include <pjsip-simple/iscomposing.h>\n#include <pjsip-simple/mwi.h>\n#include <pjsip-simple/presence.h>\n#include <pjsip-simple/pidf.h>\n#include <pjsip-simple/publish.h>\n#include <pjsip-simple/xpidf.h>\n\n#endif\t/* __PJSIP_SIMPLE_H__ */\n"
  },
  {
    "path": "deps/pjsip/pjsip/include/pjsip_ua.h",
    "content": "/* $Id: pjsip_ua.h 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __PJSIP_UA_H__\n#define __PJSIP_UA_H__\n\n#include <pjsip-ua/sip_inv.h>\n#include <pjsip-ua/sip_regc.h>\n#include <pjsip-ua/sip_replaces.h>\n#include <pjsip-ua/sip_xfer.h>\n#include <pjsip-ua/sip_100rel.h>\n#include <pjsip-ua/sip_timer.h>\n\n\n#endif\t/* __PJSIP_UA_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_auth_aka.c",
    "content": "/* $Id: sip_auth_aka.c 3999 2012-03-30 07:10:13Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_auth_aka.h>\n#include <pjsip/sip_errno.h>\n#include <pjlib-util/base64.h>\n#include <pjlib-util/md5.h>\n#include <pjlib-util/hmac_md5.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#if PJSIP_HAS_DIGEST_AKA_AUTH\n\n#include \"../../third_party/milenage/milenage.h\"\n\n/*\n * Create MD5-AKA1 digest response.\n */\nPJ_DEF(pj_status_t) pjsip_auth_create_aka_response( \n\t\t\t\t\t     pj_pool_t *pool,\n\t\t\t\t\t     const pjsip_digest_challenge*chal,\n\t\t\t\t\t     const pjsip_cred_info *cred,\n\t\t\t\t\t     const pj_str_t *method,\n\t\t\t\t\t     pjsip_digest_credential *auth)\n{\n    pj_str_t nonce_bin;\n    int aka_version;\n    const pj_str_t pjsip_AKAv1_MD5 = { \"AKAv1-MD5\", 9 };\n    const pj_str_t pjsip_AKAv2_MD5 = { \"AKAv2-MD5\", 9 };\n    pj_uint8_t *chal_rand, *chal_sqnxoraka, *chal_mac;\n    pj_uint8_t k[PJSIP_AKA_KLEN];\n    pj_uint8_t op[PJSIP_AKA_OPLEN];\n    pj_uint8_t amf[PJSIP_AKA_AMFLEN];\n    pj_uint8_t res[PJSIP_AKA_RESLEN];\n    pj_uint8_t ck[PJSIP_AKA_CKLEN];\n    pj_uint8_t ik[PJSIP_AKA_IKLEN];\n    pj_uint8_t ak[PJSIP_AKA_AKLEN];\n    pj_uint8_t sqn[PJSIP_AKA_SQNLEN];\n    pj_uint8_t xmac[PJSIP_AKA_MACLEN];\n    pjsip_cred_info aka_cred;\n    int i, len;\n    pj_status_t status;\n\n    /* Check the algorithm is supported. */\n    if (chal->algorithm.slen==0 || pj_stricmp2(&chal->algorithm, \"md5\") == 0) {\n\t/*\n\t * A normal MD5 authentication is requested. Fallbackt to the usual\n\t * MD5 digest creation.\n\t */\n\tpjsip_auth_create_digest(&auth->response, &auth->nonce, &auth->nc,\n\t\t\t\t &auth->cnonce, &auth->qop, &auth->uri,\n\t\t\t\t &auth->realm, cred, method);\n\treturn PJ_SUCCESS;\n\n    } else if (pj_stricmp(&chal->algorithm, &pjsip_AKAv1_MD5) == 0) {\n\t/*\n\t * AKA version 1 is requested.\n\t */\n\taka_version = 1;\n\n    } else if (pj_stricmp(&chal->algorithm, &pjsip_AKAv2_MD5) == 0) {\n\t/*\n\t * AKA version 2 is requested.\n\t */\n\taka_version = 2;\n\n    } else {\n\t/* Unsupported algorithm */\n\treturn PJSIP_EINVALIDALGORITHM;\n    }\n\n    /* Decode nonce */\n    nonce_bin.slen = len = PJ_BASE64_TO_BASE256_LEN(chal->nonce.slen);\n    nonce_bin.ptr = pj_pool_alloc(pool, nonce_bin.slen + 1);\n    status = pj_base64_decode(&chal->nonce, (pj_uint8_t*)nonce_bin.ptr, &len);\n    nonce_bin.slen = len;\n    if (status != PJ_SUCCESS)\n\treturn PJSIP_EAUTHINNONCE;\n\n    if (nonce_bin.slen < PJSIP_AKA_RANDLEN + PJSIP_AKA_AUTNLEN)\n\treturn PJSIP_EAUTHINNONCE;\n\n    /* Get RAND, AUTN, and MAC */\n    chal_rand = (pj_uint8_t*)(nonce_bin.ptr + 0);\n    chal_sqnxoraka = (pj_uint8_t*) (nonce_bin.ptr + PJSIP_AKA_RANDLEN);\n    chal_mac = (pj_uint8_t*) (nonce_bin.ptr + PJSIP_AKA_RANDLEN + \n\t\t\t      PJSIP_AKA_SQNLEN + PJSIP_AKA_AMFLEN);\n\n    /* Copy k. op, and amf */\n    pj_bzero(k, sizeof(k));\n    pj_bzero(op, sizeof(op));\n    pj_bzero(amf, sizeof(amf));\n\n    if (cred->ext.aka.k.slen)\n\tpj_memcpy(k, cred->ext.aka.k.ptr, cred->ext.aka.k.slen);\n    if (cred->ext.aka.op.slen)\n\tpj_memcpy(op, cred->ext.aka.op.ptr, cred->ext.aka.op.slen);\n    if (cred->ext.aka.amf.slen)\n\tpj_memcpy(amf, cred->ext.aka.amf.ptr, cred->ext.aka.amf.slen);\n\n    /* Given key K and random challenge RAND, compute response RES,\n     * confidentiality key CK, integrity key IK and anonymity key AK.\n     */\n    f2345(k, chal_rand, res, ck, ik, ak, op);\n\n    /* Compute sequence number SQN */\n    for (i=0; i<PJSIP_AKA_SQNLEN; ++i)\n\tsqn[i] = (pj_uint8_t) (chal_sqnxoraka[i] ^ ak[i]);\n\n    /* Verify MAC in the challenge */\n    /* Compute XMAC */\n    f1(k, chal_rand, sqn, amf, xmac, op);\n\n    if (pj_memcmp(chal_mac, xmac, PJSIP_AKA_MACLEN) != 0) {\n\treturn PJSIP_EAUTHINNONCE;\n    }\n\n    /* Build a temporary credential info to create MD5 digest, using\n     * \"res\" as the password. \n     */\n    pj_memcpy(&aka_cred, cred, sizeof(aka_cred));\n    aka_cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;\n\n    /* Create a response */\n    if (aka_version == 1) {\n\t/*\n\t * For AKAv1, the password is RES\n\t */\n\taka_cred.data.ptr = (char*)res;\n\taka_cred.data.slen = PJSIP_AKA_RESLEN;\n\n\tpjsip_auth_create_digest(&auth->response, &chal->nonce, \n\t\t\t\t &auth->nc, &auth->cnonce, &auth->qop, \n\t\t\t\t &auth->uri, &chal->realm, &aka_cred, method);\n\n    } else if (aka_version == 2) {\n\n\t/*\n\t * For AKAv2, password is base64 encoded [1] parameters:\n\t *    PRF(RES||IK||CK,\"http-digest-akav2-password\")\n\t *\n\t * The pseudo-random function (PRF) is HMAC-MD5 in this case.\n\t */\n\n\tpj_str_t resikck;\n\tconst pj_str_t AKAv2_Passwd = { \"http-digest-akav2-password\", 26 };\n\tpj_uint8_t hmac_digest[16];\n\tchar tmp_buf[48];\n\tint hmac64_len;\n\n\tresikck.slen = PJSIP_AKA_RESLEN + PJSIP_AKA_IKLEN + PJSIP_AKA_CKLEN;\n\tpj_assert(resikck.slen <= PJ_ARRAY_SIZE(tmp_buf));\n\tresikck.ptr = tmp_buf;\n\tpj_memcpy(resikck.ptr + 0, res, PJSIP_AKA_RESLEN);\n\tpj_memcpy(resikck.ptr + PJSIP_AKA_RESLEN, ik, PJSIP_AKA_IKLEN);\n\tpj_memcpy(resikck.ptr + PJSIP_AKA_RESLEN + PJSIP_AKA_IKLEN,\n\t          ck, PJSIP_AKA_CKLEN);\n\n\tpj_hmac_md5((const pj_uint8_t*)AKAv2_Passwd.ptr, AKAv2_Passwd.slen,\n\t            (const pj_uint8_t*)resikck.ptr, resikck.slen,\n\t            hmac_digest);\n\n\taka_cred.data.slen = hmac64_len =\n\t\tPJ_BASE256_TO_BASE64_LEN(PJ_ARRAY_SIZE(hmac_digest));\n\tpj_assert(aka_cred.data.slen+1 <= PJ_ARRAY_SIZE(tmp_buf));\n\taka_cred.data.ptr = tmp_buf;\n\tpj_base64_encode(hmac_digest, PJ_ARRAY_SIZE(hmac_digest),\n\t                 aka_cred.data.ptr, &len);\n\taka_cred.data.slen = hmac64_len;\n\n\tpjsip_auth_create_digest(&auth->response, &chal->nonce, \n\t\t\t\t &auth->nc, &auth->cnonce, &auth->qop, \n\t\t\t\t &auth->uri, &chal->realm, &aka_cred, method);\n\n    } else {\n\tpj_assert(!\"Bug!\");\n\treturn PJ_EBUG;\n    }\n\n    /* Done */\n    return PJ_SUCCESS;\n}\n\n\n#endif\t/* PJSIP_HAS_DIGEST_AKA_AUTH */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_auth_client.c",
    "content": "/* $Id: sip_auth_client.c 4322 2013-01-17 10:09:09Z bennylp $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\n#include <pjsip/sip_auth.h>\n#include <pjsip/sip_auth_parser.h>\t/* just to get pjsip_DIGEST_STR */\n#include <pjsip/sip_auth_aka.h>\n#include <pjsip/sip_transport.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_util.h>\n#include <pjlib-util/md5.h>\n#include <pj/log.h>\n#include <pj/string.h>\n#include <pj/pool.h>\n#include <pj/guid.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n\n\n\n/* A macro just to get rid of type mismatch between char and unsigned char */\n#define MD5_APPEND(pms,buf,len)\tpj_md5_update(pms, (const pj_uint8_t*)buf, \\\n\t\t\t\t\t      (unsigned)len)\n\n/* Logging. */\n#define THIS_FILE   \"sip_auth_client.c\"\n#if 0\n#  define AUTH_TRACE_(expr)  PJ_LOG(3, expr)\n#else\n#  define AUTH_TRACE_(expr)\n#endif\n\n#define PASSWD_MASK\t    0x000F\n#define EXT_MASK\t    0x00F0\n\n\nstatic void dup_bin(pj_pool_t *pool, pj_str_t *dst, const pj_str_t *src)\n{\n    dst->slen = src->slen;\n\n    if (dst->slen) {\n\tdst->ptr = (char*) pj_pool_alloc(pool, src->slen);\n\tpj_memcpy(dst->ptr, src->ptr, src->slen);\n    } else {\n\tdst->ptr = NULL;\n    }\n}\n\nPJ_DEF(void) pjsip_cred_info_dup(pj_pool_t *pool,\n\t\t\t\t pjsip_cred_info *dst,\n\t\t\t\t const pjsip_cred_info *src)\n{\n    pj_memcpy(dst, src, sizeof(pjsip_cred_info));\n\n    pj_strdup_with_null(pool, &dst->realm, &src->realm);\n    pj_strdup_with_null(pool, &dst->scheme, &src->scheme);\n    pj_strdup_with_null(pool, &dst->username, &src->username);\n    pj_strdup_with_null(pool, &dst->data, &src->data);\n\n    if ((dst->data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) {\n\tdup_bin(pool, &dst->ext.aka.k, &src->ext.aka.k);\n\tdup_bin(pool, &dst->ext.aka.op, &src->ext.aka.op);\n\tdup_bin(pool, &dst->ext.aka.amf, &src->ext.aka.amf);\n    }\n}\n\n\nPJ_DEF(int) pjsip_cred_info_cmp(const pjsip_cred_info *cred1,\n\t\t\t\tconst pjsip_cred_info *cred2)\n{\n    int result;\n\n    result = pj_strcmp(&cred1->realm, &cred2->realm);\n    if (result) goto on_return;\n    result = pj_strcmp(&cred1->scheme, &cred2->scheme);\n    if (result) goto on_return;\n    result = pj_strcmp(&cred1->username, &cred2->username);\n    if (result) goto on_return;\n    result = pj_strcmp(&cred1->data, &cred2->data);\n    if (result) goto on_return;\n    result = (cred1->data_type != cred2->data_type);\n    if (result) goto on_return;\n\n    if ((cred1->data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) {\n\tresult = pj_strcmp(&cred1->ext.aka.k, &cred2->ext.aka.k);\n\tif (result) goto on_return;\n\tresult = pj_strcmp(&cred1->ext.aka.op, &cred2->ext.aka.op);\n\tif (result) goto on_return;\n\tresult = pj_strcmp(&cred1->ext.aka.amf, &cred2->ext.aka.amf);\n\tif (result) goto on_return;\n    }\n\non_return:\n    return result;\n}\n\nPJ_DEF(void) pjsip_auth_clt_pref_dup( pj_pool_t *pool,\n\t\t\t\t      pjsip_auth_clt_pref *dst,\n\t\t\t\t      const pjsip_auth_clt_pref *src)\n{\n    pj_memcpy(dst, src, sizeof(pjsip_auth_clt_pref));\n    pj_strdup_with_null(pool, &dst->algorithm, &src->algorithm);\n}\n\n\n/* Transform digest to string.\n * output must be at least PJSIP_MD5STRLEN+1 bytes.\n *\n * NOTE: THE OUTPUT STRING IS NOT NULL TERMINATED!\n */\nstatic void digest2str(const unsigned char digest[], char *output)\n{\n    int i;\n    for (i = 0; i<16; ++i) {\n\tpj_val_to_hex_digit(digest[i], output);\n\toutput += 2;\n    }\n}\n\n\n/*\n * Create response digest based on the parameters and store the\n * digest ASCII in 'result'.\n */\nPJ_DEF(void) pjsip_auth_create_digest( pj_str_t *result,\n\t\t\t\t       const pj_str_t *nonce,\n\t\t\t\t       const pj_str_t *nc,\n\t\t\t\t       const pj_str_t *cnonce,\n\t\t\t\t       const pj_str_t *qop,\n\t\t\t\t       const pj_str_t *uri,\n\t\t\t\t       const pj_str_t *realm,\n\t\t\t\t       const pjsip_cred_info *cred_info,\n\t\t\t\t       const pj_str_t *method)\n{\n    char ha1[PJSIP_MD5STRLEN];\n    char ha2[PJSIP_MD5STRLEN];\n    unsigned char digest[16];\n    pj_md5_context pms;\n\n    pj_assert(result->slen >= PJSIP_MD5STRLEN);\n\n    AUTH_TRACE_((THIS_FILE, \"Begin creating digest\"));\n\n    if ((cred_info->data_type & PASSWD_MASK) == PJSIP_CRED_DATA_PLAIN_PASSWD) {\n\t/***\n\t *** ha1 = MD5(username \":\" realm \":\" password)\n\t ***/\n\tpj_md5_init(&pms);\n\tMD5_APPEND( &pms, cred_info->username.ptr, cred_info->username.slen);\n\tMD5_APPEND( &pms, \":\", 1);\n\tMD5_APPEND( &pms, realm->ptr, realm->slen);\n\tMD5_APPEND( &pms, \":\", 1);\n\tMD5_APPEND( &pms, cred_info->data.ptr, cred_info->data.slen);\n\tpj_md5_final(&pms, digest);\n\n\tdigest2str(digest, ha1);\n\n    } else if ((cred_info->data_type & PASSWD_MASK) == PJSIP_CRED_DATA_DIGEST) {\n\tpj_assert(cred_info->data.slen == 32);\n\tpj_memcpy( ha1, cred_info->data.ptr, cred_info->data.slen );\n    } else {\n\tpj_assert(!\"Invalid data_type\");\n    }\n\n    AUTH_TRACE_((THIS_FILE, \"  ha1=%.32s\", ha1));\n\n    /***\n     *** ha2 = MD5(method \":\" req_uri)\n     ***/\n    pj_md5_init(&pms);\n    MD5_APPEND( &pms, method->ptr, method->slen);\n    MD5_APPEND( &pms, \":\", 1);\n    MD5_APPEND( &pms, uri->ptr, uri->slen);\n    pj_md5_final(&pms, digest);\n    digest2str(digest, ha2);\n\n    AUTH_TRACE_((THIS_FILE, \"  ha2=%.32s\", ha2));\n\n    /***\n     *** When qop is not used:\n     ***    response = MD5(ha1 \":\" nonce \":\" ha2)\n     ***\n     *** When qop=auth is used:\n     ***    response = MD5(ha1 \":\" nonce \":\" nc \":\" cnonce \":\" qop \":\" ha2)\n     ***/\n    pj_md5_init(&pms);\n    MD5_APPEND( &pms, ha1, PJSIP_MD5STRLEN);\n    MD5_APPEND( &pms, \":\", 1);\n    MD5_APPEND( &pms, nonce->ptr, nonce->slen);\n    if (qop && qop->slen != 0) {\n\tMD5_APPEND( &pms, \":\", 1);\n\tMD5_APPEND( &pms, nc->ptr, nc->slen);\n\tMD5_APPEND( &pms, \":\", 1);\n\tMD5_APPEND( &pms, cnonce->ptr, cnonce->slen);\n\tMD5_APPEND( &pms, \":\", 1);\n\tMD5_APPEND( &pms, qop->ptr, qop->slen);\n    }\n    MD5_APPEND( &pms, \":\", 1);\n    MD5_APPEND( &pms, ha2, PJSIP_MD5STRLEN);\n\n    /* This is the final response digest. */\n    pj_md5_final(&pms, digest);\n\n    /* Convert digest to string and store in chal->response. */\n    result->slen = PJSIP_MD5STRLEN;\n    digest2str(digest, result->ptr);\n\n    AUTH_TRACE_((THIS_FILE, \"  digest=%.32s\", result->ptr));\n    AUTH_TRACE_((THIS_FILE, \"Digest created\"));\n}\n\n/*\n * Finds out if qop offer contains \"auth\" token.\n */\nstatic pj_bool_t has_auth_qop( pj_pool_t *pool, const pj_str_t *qop_offer)\n{\n    pj_str_t qop;\n    char *p;\n\n    pj_strdup_with_null( pool, &qop, qop_offer);\n    p = qop.ptr;\n    while (*p) {\n\t*p = (char)pj_tolower(*p);\n\t++p;\n    }\n\n    p = qop.ptr;\n    while (*p) {\n\tif (*p=='a' && *(p+1)=='u' && *(p+2)=='t' && *(p+3)=='h') {\n\t    int e = *(p+4);\n\t    if (e=='\"' || e==',' || e==0)\n\t\treturn PJ_TRUE;\n\t    else\n\t\tp += 4;\n\t} else {\n\t    ++p;\n\t}\n    }\n\n    return PJ_FALSE;\n}\n\n/*\n * Generate response digest.\n * Most of the parameters to generate the digest (i.e. username, realm, uri,\n * and nonce) are expected to be in the credential. Additional parameters (i.e.\n * password and method param) should be supplied in the argument.\n *\n * The resulting digest will be stored in cred->response.\n * The pool is used to allocate 32 bytes to store the digest in cred->response.\n */\nstatic pj_status_t respond_digest( pj_pool_t *pool,\n\t\t\t\t   pjsip_digest_credential *cred,\n\t\t\t\t   const pjsip_digest_challenge *chal,\n\t\t\t\t   const pj_str_t *uri,\n\t\t\t\t   const pjsip_cred_info *cred_info,\n\t\t\t\t   const pj_str_t *cnonce,\n\t\t\t\t   pj_uint32_t nc,\n\t\t\t\t   const pj_str_t *method)\n{\n    const pj_str_t pjsip_AKAv1_MD5_STR = { \"AKAv1-MD5\", 9 };\n\n    /* Check algorithm is supported. We support MD5 and AKAv1-MD5. */\n    if (chal->algorithm.slen==0 ||\n\t(pj_stricmp(&chal->algorithm, &pjsip_MD5_STR)==0 ||\n\t pj_stricmp(&chal->algorithm, &pjsip_AKAv1_MD5_STR)==0))\n    {\n\t;\n    }\n    else {\n\tPJ_LOG(4,(THIS_FILE, \"Unsupported digest algorithm \\\"%.*s\\\"\",\n\t\t  chal->algorithm.slen, chal->algorithm.ptr));\n\treturn PJSIP_EINVALIDALGORITHM;\n    }\n\n    /* Build digest credential from arguments. */\n    pj_strdup(pool, &cred->username, &cred_info->username);\n    pj_strdup(pool, &cred->realm, &chal->realm);\n    pj_strdup(pool, &cred->nonce, &chal->nonce);\n    pj_strdup(pool, &cred->uri, uri);\n    pj_strdup(pool, &cred->algorithm, &chal->algorithm);\n    pj_strdup(pool, &cred->opaque, &chal->opaque);\n\n    /* Allocate memory. */\n    cred->response.ptr = (char*) pj_pool_alloc(pool, PJSIP_MD5STRLEN);\n    cred->response.slen = PJSIP_MD5STRLEN;\n\n    if (chal->qop.slen == 0) {\n\t/* Server doesn't require quality of protection. */\n\n\tif ((cred_info->data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) {\n\t    /* Call application callback to create the response digest */\n\t    return (*cred_info->ext.aka.cb)(pool, chal, cred_info,\n\t\t\t\t\t    method, cred);\n\t}\n\telse {\n\t    /* Convert digest to string and store in chal->response. */\n\t    pjsip_auth_create_digest( &cred->response, &cred->nonce, NULL,\n\t\t\t\t      NULL,  NULL, uri, &chal->realm,\n\t\t\t\t      cred_info, method);\n\t}\n\n    } else if (has_auth_qop(pool, &chal->qop)) {\n\t/* Server requires quality of protection.\n\t * We respond with selecting \"qop=auth\" protection.\n\t */\n\tcred->qop = pjsip_AUTH_STR;\n\tcred->nc.ptr = (char*) pj_pool_alloc(pool, 16);\n\tcred->nc.slen = pj_ansi_snprintf(cred->nc.ptr, 16, \"%08u\", nc);\n\n\tif (cnonce && cnonce->slen) {\n\t    pj_strdup(pool, &cred->cnonce, cnonce);\n\t} else {\n\t    pj_str_t dummy_cnonce = { \"b39971\", 6};\n\t    pj_strdup(pool, &cred->cnonce, &dummy_cnonce);\n\t}\n\n\tif ((cred_info->data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) {\n\t    /* Call application callback to create the response digest */\n\t    return (*cred_info->ext.aka.cb)(pool, chal, cred_info,\n\t\t\t\t\t    method, cred);\n\t}\n\telse {\n\t    pjsip_auth_create_digest( &cred->response, &cred->nonce,\n\t\t\t\t      &cred->nc, &cred->cnonce, &pjsip_AUTH_STR,\n\t\t\t\t      uri, &chal->realm, cred_info, method );\n\t}\n\n    } else {\n\t/* Server requires quality protection that we don't support. */\n\tPJ_LOG(4,(THIS_FILE, \"Unsupported qop offer %.*s\",\n\t\t  chal->qop.slen, chal->qop.ptr));\n\treturn PJSIP_EINVALIDQOP;\n    }\n\n    return PJ_SUCCESS;\n}\n\n#if defined(PJSIP_AUTH_QOP_SUPPORT) && PJSIP_AUTH_QOP_SUPPORT!=0\n/*\n * Update authentication session with a challenge.\n */\nstatic void update_digest_session( pj_pool_t *ses_pool,\n\t\t\t\t   pjsip_cached_auth *cached_auth,\n\t\t\t\t   const pjsip_www_authenticate_hdr *hdr )\n{\n    if (hdr->challenge.digest.qop.slen == 0) {\n#if PJSIP_AUTH_AUTO_SEND_NEXT!=0\n\tif (!cached_auth->last_chal || pj_stricmp2(&hdr->scheme, \"digest\")) {\n\t    cached_auth->last_chal = (pjsip_www_authenticate_hdr*)\n\t\t\t\t     pjsip_hdr_clone(ses_pool, hdr);\n\t} else {\n\t    /* Only update if the new challenge is \"significantly different\"\n\t     * than the one in the cache, to reduce memory usage.\n\t     */\n\t    const pjsip_digest_challenge *d1 =\n\t\t\t&cached_auth->last_chal->challenge.digest;\n\t    const pjsip_digest_challenge *d2 = &hdr->challenge.digest;\n\n\t    if (pj_strcmp(&d1->domain, &d2->domain) ||\n\t\tpj_strcmp(&d1->realm, &d2->realm) ||\n\t\tpj_strcmp(&d1->nonce, &d2->nonce) ||\n\t\tpj_strcmp(&d1->opaque, &d2->opaque) ||\n\t\tpj_strcmp(&d1->algorithm, &d2->algorithm) ||\n\t\tpj_strcmp(&d1->qop, &d2->qop))\n\t    {\n\t\tcached_auth->last_chal = (pjsip_www_authenticate_hdr*)\n\t\t\t\t         pjsip_hdr_clone(ses_pool, hdr);\n\t    }\n\t}\n#endif\n\treturn;\n    }\n\n    /* Initialize cnonce and qop if not present. */\n    if (cached_auth->cnonce.slen == 0) {\n\t/* Save the whole challenge */\n\tcached_auth->last_chal = (pjsip_www_authenticate_hdr*)\n\t\t\t\t pjsip_hdr_clone(ses_pool, hdr);\n\n\t/* Create cnonce */\n\tpj_create_unique_string( ses_pool, &cached_auth->cnonce );\n\n\t/* Initialize nonce-count */\n\tcached_auth->nc = 1;\n\n\t/* Save realm. */\n\t/* Note: allow empty realm (http://trac.pjsip.org/repos/ticket/1061)\n\tpj_assert(cached_auth->realm.slen != 0);\n\t*/\n\tif (cached_auth->realm.slen == 0) {\n\t    pj_strdup(ses_pool, &cached_auth->realm,\n\t\t      &hdr->challenge.digest.realm);\n\t}\n\n    } else {\n\t/* Update last_nonce and nonce-count */\n\tif (!pj_strcmp(&hdr->challenge.digest.nonce,\n\t\t       &cached_auth->last_chal->challenge.digest.nonce))\n\t{\n\t    /* Same nonce, increment nonce-count */\n\t    ++cached_auth->nc;\n\t} else {\n\t    /* Server gives new nonce. */\n\t    pj_strdup(ses_pool, &cached_auth->last_chal->challenge.digest.nonce,\n\t\t      &hdr->challenge.digest.nonce);\n\t    /* Has the opaque changed? */\n\t    if (pj_strcmp(&cached_auth->last_chal->challenge.digest.opaque,\n\t\t\t  &hdr->challenge.digest.opaque))\n\t    {\n\t\tpj_strdup(ses_pool,\n\t\t\t  &cached_auth->last_chal->challenge.digest.opaque,\n\t\t\t  &hdr->challenge.digest.opaque);\n\t    }\n\t    cached_auth->nc = 1;\n\t}\n    }\n}\n#endif\t/* PJSIP_AUTH_QOP_SUPPORT */\n\n\n/* Find cached authentication in the list for the specified realm. */\nstatic pjsip_cached_auth *find_cached_auth( pjsip_auth_clt_sess *sess,\n\t\t\t\t\t    const pj_str_t *realm )\n{\n    pjsip_cached_auth *auth = sess->cached_auth.next;\n    while (auth != &sess->cached_auth) {\n\tif (pj_stricmp(&auth->realm, realm) == 0)\n\t    return auth;\n\tauth = auth->next;\n    }\n\n    return NULL;\n}\n\n/* Find credential to use for the specified realm and auth scheme. */\nstatic const pjsip_cred_info* auth_find_cred( const pjsip_auth_clt_sess *sess,\n\t\t\t\t\t      const pj_str_t *realm,\n\t\t\t\t\t      const pj_str_t *auth_scheme)\n{\n    unsigned i;\n    int wildcard = -1;\n\n    PJ_UNUSED_ARG(auth_scheme);\n\n    for (i=0; i<sess->cred_cnt; ++i) {\n\tif (pj_stricmp(&sess->cred_info[i].realm, realm) == 0)\n\t    return &sess->cred_info[i];\n\telse if (sess->cred_info[i].realm.slen == 1 &&\n\t\t sess->cred_info[i].realm.ptr[0] == '*')\n\t{\n\t    wildcard = i;\n\t}\n    }\n\n    /* No matching realm. See if we have credential with wildcard ('*')\n     * as the realm.\n     */\n    if (wildcard != -1)\n\treturn &sess->cred_info[wildcard];\n\n    /* Nothing is suitable */\n    return NULL;\n}\n\n\n/* Init client session. */\nPJ_DEF(pj_status_t) pjsip_auth_clt_init(  pjsip_auth_clt_sess *sess,\n\t\t\t\t\t  pjsip_endpoint *endpt,\n\t\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t\t  unsigned options)\n{\n    PJ_ASSERT_RETURN(sess && endpt && pool && (options==0), PJ_EINVAL);\n\n    sess->pool = pool;\n    sess->endpt = endpt;\n    sess->cred_cnt = 0;\n    sess->cred_info = NULL;\n    pj_list_init(&sess->cached_auth);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Clone session. */\nPJ_DEF(pj_status_t) pjsip_auth_clt_clone( pj_pool_t *pool,\n\t\t\t\t\t  pjsip_auth_clt_sess *sess,\n\t\t\t\t\t  const pjsip_auth_clt_sess *rhs )\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(pool && sess && rhs, PJ_EINVAL);\n\n    pjsip_auth_clt_init(sess, (pjsip_endpoint*)rhs->endpt, pool, 0);\n\n    sess->cred_cnt = rhs->cred_cnt;\n    sess->cred_info = (pjsip_cred_info*)\n    \t\t      pj_pool_alloc(pool,\n\t\t\t\t    sess->cred_cnt*sizeof(pjsip_cred_info));\n    for (i=0; i<rhs->cred_cnt; ++i) {\n\tpj_strdup(pool, &sess->cred_info[i].realm, &rhs->cred_info[i].realm);\n\tpj_strdup(pool, &sess->cred_info[i].scheme, &rhs->cred_info[i].scheme);\n\tpj_strdup(pool, &sess->cred_info[i].username,\n\t\t  &rhs->cred_info[i].username);\n\tsess->cred_info[i].data_type = rhs->cred_info[i].data_type;\n\tpj_strdup(pool, &sess->cred_info[i].data, &rhs->cred_info[i].data);\n    }\n\n    /* TODO note:\n     * Cloning the full authentication client is quite a big task.\n     * We do only the necessary bits here, i.e. cloning the credentials.\n     * The drawback of this basic approach is, a forked dialog will have to\n     * re-authenticate itself on the next request because it has lost the\n     * cached authentication headers.\n     */\n    PJ_TODO(FULL_CLONE_OF_AUTH_CLIENT_SESSION);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Set client credentials. */\nPJ_DEF(pj_status_t) pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *sess,\n\t\t\t\t\t\t    int cred_cnt,\n\t\t\t\t\t\t    const pjsip_cred_info *c)\n{\n    PJ_ASSERT_RETURN(sess && c, PJ_EINVAL);\n\n    if (cred_cnt == 0) {\n\tsess->cred_cnt = 0;\n    } else {\n\tint i;\n\tsess->cred_info = (pjsip_cred_info*)\n\t\t\t  pj_pool_alloc(sess->pool, cred_cnt * sizeof(*c));\n\tfor (i=0; i<cred_cnt; ++i) {\n\t    sess->cred_info[i].data_type = c[i].data_type;\n\n\t    /* When data_type is PJSIP_CRED_DATA_EXT_AKA,\n\t     * callback must be specified.\n\t     */\n\t    if ((c[i].data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) {\n\n#if !PJSIP_HAS_DIGEST_AKA_AUTH\n\t\tif (!PJSIP_HAS_DIGEST_AKA_AUTH) {\n\t\t    pj_assert(!\"PJSIP_HAS_DIGEST_AKA_AUTH is not enabled\");\n\t\t    return PJSIP_EAUTHINAKACRED;\n\t\t}\n#endif\n\n\t\t/* Callback must be specified */\n\t\tPJ_ASSERT_RETURN(c[i].ext.aka.cb != NULL, PJ_EINVAL);\n\n\t\t/* Verify K len */\n\t\tPJ_ASSERT_RETURN(c[i].ext.aka.k.slen <= PJSIP_AKA_KLEN,\n\t\t\t\t PJSIP_EAUTHINAKACRED);\n\n\t\t/* Verify OP len */\n\t\tPJ_ASSERT_RETURN(c[i].ext.aka.op.slen <= PJSIP_AKA_OPLEN,\n\t\t\t\t PJSIP_EAUTHINAKACRED);\n\n\t\t/* Verify AMF len */\n\t\tPJ_ASSERT_RETURN(c[i].ext.aka.amf.slen <= PJSIP_AKA_AMFLEN,\n\t\t\t\t PJSIP_EAUTHINAKACRED);\n\n\t\tsess->cred_info[i].ext.aka.cb = c[i].ext.aka.cb;\n\t\tpj_strdup(sess->pool, &sess->cred_info[i].ext.aka.k,\n\t\t\t  &c[i].ext.aka.k);\n\t\tpj_strdup(sess->pool, &sess->cred_info[i].ext.aka.op,\n\t\t\t  &c[i].ext.aka.op);\n\t\tpj_strdup(sess->pool, &sess->cred_info[i].ext.aka.amf,\n\t\t\t  &c[i].ext.aka.amf);\n\t    }\n\n\t    pj_strdup(sess->pool, &sess->cred_info[i].scheme, &c[i].scheme);\n\t    pj_strdup(sess->pool, &sess->cred_info[i].realm, &c[i].realm);\n\t    pj_strdup(sess->pool, &sess->cred_info[i].username, &c[i].username);\n\t    pj_strdup(sess->pool, &sess->cred_info[i].data, &c[i].data);\n\t}\n\tsess->cred_cnt = cred_cnt;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Set the preference for the client authentication session.\n */\nPJ_DEF(pj_status_t) pjsip_auth_clt_set_prefs(pjsip_auth_clt_sess *sess,\n\t\t\t\t\t     const pjsip_auth_clt_pref *p)\n{\n    PJ_ASSERT_RETURN(sess && p, PJ_EINVAL);\n\n    pj_memcpy(&sess->pref, p, sizeof(*p));\n    pj_strdup(sess->pool, &sess->pref.algorithm, &p->algorithm);\n    //if (sess->pref.algorithm.slen == 0)\n    //\tsess->pref.algorithm = pj_str(\"md5\");\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the preference for the client authentication session.\n */\nPJ_DEF(pj_status_t) pjsip_auth_clt_get_prefs(pjsip_auth_clt_sess *sess,\n\t\t\t\t\t     pjsip_auth_clt_pref *p)\n{\n    PJ_ASSERT_RETURN(sess && p, PJ_EINVAL);\n\n    pj_memcpy(p, &sess->pref, sizeof(pjsip_auth_clt_pref));\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create Authorization/Proxy-Authorization response header based on the challege\n * in WWW-Authenticate/Proxy-Authenticate header.\n */\nstatic pj_status_t auth_respond( pj_pool_t *req_pool,\n\t\t\t\t const pjsip_www_authenticate_hdr *hdr,\n\t\t\t\t const pjsip_uri *uri,\n\t\t\t\t const pjsip_cred_info *cred_info,\n\t\t\t\t const pjsip_method *method,\n\t\t\t\t pj_pool_t *sess_pool,\n\t\t\t\t pjsip_cached_auth *cached_auth,\n\t\t\t\t pjsip_authorization_hdr **p_h_auth)\n{\n    pjsip_authorization_hdr *hauth;\n    char tmp[PJSIP_MAX_URL_SIZE];\n    pj_str_t uri_str;\n    pj_pool_t *pool;\n    pj_status_t status;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(req_pool && hdr && uri && cred_info && method &&\n\t\t     sess_pool && cached_auth && p_h_auth, PJ_EINVAL);\n\n    /* Print URL in the original request. */\n    uri_str.ptr = tmp;\n    uri_str.slen = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, uri, tmp,sizeof(tmp));\n    if (uri_str.slen < 1) {\n\tpj_assert(!\"URL is too long!\");\n\treturn PJSIP_EURITOOLONG;\n    }\n\n#   if (PJSIP_AUTH_HEADER_CACHING)\n    {\n\tpool = sess_pool;\n\tPJ_UNUSED_ARG(req_pool);\n    }\n#   else\n    {\n\tpool = req_pool;\n\tPJ_UNUSED_ARG(sess_pool);\n    }\n#   endif\n\n    if (hdr->type == PJSIP_H_WWW_AUTHENTICATE)\n\thauth = pjsip_authorization_hdr_create(pool);\n    else if (hdr->type == PJSIP_H_PROXY_AUTHENTICATE)\n\thauth = pjsip_proxy_authorization_hdr_create(pool);\n    else {\n\tpj_assert(!\"Invalid response header!\");\n\treturn PJSIP_EINVALIDHDR;\n    }\n\n    /* Only support digest scheme at the moment. */\n    if (!pj_stricmp(&hdr->scheme, &pjsip_DIGEST_STR)) {\n\tpj_str_t *cnonce = NULL;\n\tpj_uint32_t nc = 1;\n\n\t/* Update the session (nonce-count etc) if required. */\n#\tif PJSIP_AUTH_QOP_SUPPORT\n\t{\n\t    if (cached_auth) {\n\t\tupdate_digest_session( sess_pool, cached_auth, hdr );\n\n\t\tcnonce = &cached_auth->cnonce;\n\t\tnc = cached_auth->nc;\n\t    }\n\t}\n#\tendif\t/* PJSIP_AUTH_QOP_SUPPORT */\n\n\thauth->scheme = pjsip_DIGEST_STR;\n\tstatus = respond_digest( pool, &hauth->credential.digest,\n\t\t\t\t &hdr->challenge.digest, &uri_str, cred_info,\n\t\t\t\t cnonce, nc, &method->name);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Set qop type in auth session the first time only. */\n\tif (hdr->challenge.digest.qop.slen != 0 && cached_auth) {\n\t    if (cached_auth->qop_value == PJSIP_AUTH_QOP_NONE) {\n\t\tpj_str_t *qop_val = &hauth->credential.digest.qop;\n\t\tif (!pj_strcmp(qop_val, &pjsip_AUTH_STR)) {\n\t\t    cached_auth->qop_value = PJSIP_AUTH_QOP_AUTH;\n\t\t} else {\n\t\t    cached_auth->qop_value = PJSIP_AUTH_QOP_UNKNOWN;\n\t\t}\n\t    }\n\t}\n    } else {\n\treturn PJSIP_EINVALIDAUTHSCHEME;\n    }\n\n    /* Keep the new authorization header in the cache, only\n     * if no qop is not present.\n     */\n#   if PJSIP_AUTH_HEADER_CACHING\n    {\n\tif (hauth && cached_auth && cached_auth->qop_value == PJSIP_AUTH_QOP_NONE) {\n\t    pjsip_cached_auth_hdr *cached_hdr;\n\n\t    /* Delete old header with the same method. */\n\t    cached_hdr = cached_auth->cached_hdr.next;\n\t    while (cached_hdr != &cached_auth->cached_hdr) {\n\t\tif (pjsip_method_cmp(method, &cached_hdr->method)==0)\n\t\t    break;\n\t\tcached_hdr = cached_hdr->next;\n\t    }\n\n\t    /* Save the header to the list. */\n\t    if (cached_hdr != &cached_auth->cached_hdr) {\n\t\tcached_hdr->hdr = hauth;\n\t    } else {\n\t\tcached_hdr = pj_pool_alloc(pool, sizeof(*cached_hdr));\n\t\tpjsip_method_copy( pool, &cached_hdr->method, method);\n\t\tcached_hdr->hdr = hauth;\n\t\tpj_list_insert_before( &cached_auth->cached_hdr, cached_hdr );\n\t    }\n\t}\n\n#\tif defined(PJSIP_AUTH_AUTO_SEND_NEXT) && PJSIP_AUTH_AUTO_SEND_NEXT!=0\n\t    if (hdr != cached_auth->last_chal) {\n\t\tcached_auth->last_chal = pjsip_hdr_clone(sess_pool, hdr);\n\t    }\n#\tendif\n    }\n#   endif\n\n    *p_h_auth = hauth;\n    return PJ_SUCCESS;\n\n}\n\n\n#if defined(PJSIP_AUTH_AUTO_SEND_NEXT) && PJSIP_AUTH_AUTO_SEND_NEXT!=0\nstatic pj_status_t new_auth_for_req( pjsip_tx_data *tdata,\n\t\t\t\t     pjsip_auth_clt_sess *sess,\n\t\t\t\t     pjsip_cached_auth *auth,\n\t\t\t\t     pjsip_authorization_hdr **p_h_auth)\n{\n    const pjsip_cred_info *cred;\n    pjsip_authorization_hdr *hauth;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(tdata && sess && auth, PJ_EINVAL);\n    PJ_ASSERT_RETURN(auth->last_chal != NULL, PJSIP_EAUTHNOPREVCHAL);\n\n    cred = auth_find_cred( sess, &auth->realm, &auth->last_chal->scheme );\n    if (!cred)\n\treturn PJSIP_ENOCREDENTIAL;\n\n    status = auth_respond( tdata->pool, auth->last_chal,\n\t\t\t   tdata->msg->line.req.uri,\n\t\t\t   cred, &tdata->msg->line.req.method,\n\t\t\t   sess->pool, auth, &hauth);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)hauth);\n\n    if (p_h_auth)\n\t*p_h_auth = hauth;\n\n    return PJ_SUCCESS;\n}\n#endif\n\n\n/* Find credential in list of (Proxy-)Authorization headers */\nstatic pjsip_authorization_hdr* get_header_for_realm(const pjsip_hdr *hdr_list,\n\t\t\t\t\t\t     const pj_str_t *realm)\n{\n    pjsip_authorization_hdr *h;\n\n    h = (pjsip_authorization_hdr*)hdr_list->next;\n    while (h != (pjsip_authorization_hdr*)hdr_list) {\n\tif (pj_stricmp(&h->credential.digest.realm, realm)==0)\n\t    return h;\n\th = h->next;\n    }\n\n    return NULL;\n}\n\n\n/* Initialize outgoing request. */\nPJ_DEF(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,\n\t\t\t\t\t     pjsip_tx_data *tdata )\n{\n    const pjsip_method *method;\n    pjsip_cached_auth *auth;\n    pjsip_hdr added;\n\n    PJ_ASSERT_RETURN(sess && tdata, PJ_EINVAL);\n    PJ_ASSERT_RETURN(sess->pool, PJSIP_ENOTINITIALIZED);\n    PJ_ASSERT_RETURN(tdata->msg->type==PJSIP_REQUEST_MSG,\n\t\t     PJSIP_ENOTREQUESTMSG);\n\n    /* Init list */\n    pj_list_init(&added);\n\n    /* Get the method. */\n    method = &tdata->msg->line.req.method;\n    PJ_UNUSED_ARG(method); /* Warning about unused var caused by #if below */\n\n    auth = sess->cached_auth.next;\n    while (auth != &sess->cached_auth) {\n\t/* Reset stale counter */\n\tauth->stale_cnt = 0;\n\n\tif (auth->qop_value == PJSIP_AUTH_QOP_NONE) {\n#\t    if defined(PJSIP_AUTH_HEADER_CACHING) && \\\n\t       PJSIP_AUTH_HEADER_CACHING!=0\n\t    {\n\t\tpjsip_cached_auth_hdr *entry = auth->cached_hdr.next;\n\t\twhile (entry != &auth->cached_hdr) {\n\t\t    if (pjsip_method_cmp(&entry->method, method)==0) {\n\t\t\tpjsip_authorization_hdr *hauth;\n\t\t\thauth = pjsip_hdr_shallow_clone(tdata->pool, entry->hdr);\n\t\t\t//pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);\n\t\t\tpj_list_push_back(&added, hauth);\n\t\t\tbreak;\n\t\t    }\n\t\t    entry = entry->next;\n\t\t}\n\n#\t\tif defined(PJSIP_AUTH_AUTO_SEND_NEXT) && \\\n\t\t\t   PJSIP_AUTH_AUTO_SEND_NEXT!=0\n\t\t{\n\t\t    if (entry == &auth->cached_hdr)\n\t\t\tnew_auth_for_req( tdata, sess, auth, NULL);\n\t\t}\n#\t\tendif\n\n\t    }\n#\t    elif defined(PJSIP_AUTH_AUTO_SEND_NEXT) && \\\n\t\t PJSIP_AUTH_AUTO_SEND_NEXT!=0\n\t    {\n\t\tnew_auth_for_req( tdata, sess, auth, NULL);\n\t    }\n#\t    endif\n\n\t}\n#\tif defined(PJSIP_AUTH_QOP_SUPPORT) && \\\n\t   defined(PJSIP_AUTH_AUTO_SEND_NEXT) && \\\n\t   (PJSIP_AUTH_QOP_SUPPORT && PJSIP_AUTH_AUTO_SEND_NEXT)\n\telse if (auth->qop_value == PJSIP_AUTH_QOP_AUTH) {\n\t    /* For qop=\"auth\", we have to re-create the authorization header.\n\t     */\n\t    const pjsip_cred_info *cred;\n\t    pjsip_authorization_hdr *hauth;\n\t    pj_status_t status;\n\n\t    cred = auth_find_cred(sess, &auth->realm,\n\t\t\t\t  &auth->last_chal->scheme);\n\t    if (!cred) {\n\t\tauth = auth->next;\n\t\tcontinue;\n\t    }\n\n\t    status = auth_respond( tdata->pool, auth->last_chal,\n\t\t\t\t   tdata->msg->line.req.uri,\n\t\t\t\t   cred,\n\t\t\t\t   &tdata->msg->line.req.method,\n\t\t\t\t   sess->pool, auth, &hauth);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    //pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);\n\t    pj_list_push_back(&added, hauth);\n\t}\n#\tendif\t/* PJSIP_AUTH_QOP_SUPPORT && PJSIP_AUTH_AUTO_SEND_NEXT */\n\n\tauth = auth->next;\n    }\n\n    if (sess->pref.initial_auth == PJ_FALSE) {\n\tpjsip_hdr *h;\n\n\t/* Don't want to send initial empty Authorization header, so\n\t * just send whatever available in the list (maybe empty).\n\t */\n\n\th = added.next;\n\twhile (h != &added) {\n\t    pjsip_hdr *next = h->next;\n\t    pjsip_msg_add_hdr(tdata->msg, h);\n\t    h = next;\n\t}\n    } else {\n\t/* For each realm, add either the cached authorization header\n\t * or add an empty authorization header.\n\t */\n\tunsigned i;\n\tpj_str_t uri;\n\n\turi.ptr = (char*)pj_pool_alloc(tdata->pool, PJSIP_MAX_URL_SIZE);\n\turi.slen = pjsip_uri_print(PJSIP_URI_IN_REQ_URI,\n\t                           tdata->msg->line.req.uri,\n\t                           uri.ptr, PJSIP_MAX_URL_SIZE);\n\tif (uri.slen < 1 || uri.slen >= PJSIP_MAX_URL_SIZE)\n\t    return PJSIP_EURITOOLONG;\n\n\tfor (i=0; i<sess->cred_cnt; ++i) {\n\t    pjsip_cred_info *c = &sess->cred_info[i];\n\t    pjsip_authorization_hdr *h;\n\n\t    h = get_header_for_realm(&added, &c->realm);\n\t    if (h) {\n\t\tpj_list_erase(h);\n\t\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)h);\n\t    } else {\n\t\tpjsip_authorization_hdr *hs;\n\n\t\ths = pjsip_authorization_hdr_create(tdata->pool);\n\t\tpj_strdup(tdata->pool, &hs->scheme, &c->scheme);\n\t\tpj_strdup(tdata->pool, &hs->credential.digest.username,\n\t\t\t  &c->username);\n\t\tpj_strdup(tdata->pool, &hs->credential.digest.realm,\n\t\t\t  &c->realm);\n\t\tpj_strdup(tdata->pool, &hs->credential.digest.uri, &uri);\n\t\tpj_strdup(tdata->pool, &hs->credential.digest.algorithm,\n\t\t\t  &sess->pref.algorithm);\n\n\t\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hs);\n\t    }\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* Process authorization challenge */\nstatic pj_status_t process_auth( pj_pool_t *req_pool,\n\t\t\t\t const pjsip_www_authenticate_hdr *hchal,\n\t\t\t\t const pjsip_uri *uri,\n\t\t\t\t pjsip_tx_data *tdata,\n\t\t\t\t pjsip_auth_clt_sess *sess,\n\t\t\t\t pjsip_cached_auth *cached_auth,\n\t\t\t\t pjsip_authorization_hdr **h_auth)\n{\n    const pjsip_cred_info *cred;\n    pjsip_authorization_hdr *sent_auth = NULL;\n    pjsip_hdr *hdr;\n    pj_status_t status;\n\n    /* See if we have sent authorization header for this realm */\n    hdr = tdata->msg->hdr.next;\n    while (hdr != &tdata->msg->hdr) {\n\tif ((hchal->type == PJSIP_H_WWW_AUTHENTICATE &&\n\t     hdr->type == PJSIP_H_AUTHORIZATION) ||\n\t    (hchal->type == PJSIP_H_PROXY_AUTHENTICATE &&\n\t     hdr->type == PJSIP_H_PROXY_AUTHORIZATION))\n\t{\n\t    sent_auth = (pjsip_authorization_hdr*) hdr;\n\t    if (pj_stricmp(&hchal->challenge.common.realm,\n\t\t\t   &sent_auth->credential.common.realm )==0)\n\t    {\n\t\t/* If this authorization has empty response, remove it. */\n\t\tif (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 &&\n\t\t    sent_auth->credential.digest.response.slen == 0)\n\t\t{\n\t\t    /* This is empty authorization, remove it. */\n\t\t    hdr = hdr->next;\n\t\t    pj_list_erase(sent_auth);\n\t\t    continue;\n\t\t} else {\n\t\t    /* Found previous authorization attempt */\n\t\t    break;\n\t\t}\n\t    }\n\t}\n\thdr = hdr->next;\n    }\n\n    /* If we have sent, see if server rejected because of stale nonce or\n     * other causes.\n     */\n    if (hdr != &tdata->msg->hdr) {\n\tpj_bool_t stale;\n\n\t/* Detect \"stale\" state */\n\tstale = hchal->challenge.digest.stale;\n\tif (!stale) {\n\t    /* If stale is false, check is nonce has changed. Some servers\n\t     * (broken ones!) want to change nonce but they fail to set\n\t     * stale to true.\n\t     */\n\t    stale = pj_strcmp(&hchal->challenge.digest.nonce,\n\t\t\t      &sent_auth->credential.digest.nonce);\n\t}\n\n\tif (stale == PJ_FALSE) {\n\t    /* Our credential is rejected. No point in trying to re-supply\n\t     * the same credential.\n\t     */\n\t    PJ_LOG(4, (THIS_FILE, \"Authorization failed for %.*s@%.*s: \"\n\t\t       \"server rejected with stale=false\",\n\t\t       sent_auth->credential.digest.username.slen,\n\t\t       sent_auth->credential.digest.username.ptr,\n\t\t       sent_auth->credential.digest.realm.slen,\n\t\t       sent_auth->credential.digest.realm.ptr));\n\t    return PJSIP_EFAILEDCREDENTIAL;\n\t}\n\n\tcached_auth->stale_cnt++;\n\tif (cached_auth->stale_cnt >= PJSIP_MAX_STALE_COUNT) {\n\t    /* Our credential is rejected. No point in trying to re-supply\n\t     * the same credential.\n\t     */\n\t    PJ_LOG(4, (THIS_FILE, \"Authorization failed for %.*s@%.*s: \"\n\t\t       \"maximum number of stale retries exceeded\",\n\t\t       sent_auth->credential.digest.username.slen,\n\t\t       sent_auth->credential.digest.username.ptr,\n\t\t       sent_auth->credential.digest.realm.slen,\n\t\t       sent_auth->credential.digest.realm.ptr));\n\t    return PJSIP_EAUTHSTALECOUNT;\n\t}\n\n\t/* Otherwise remove old, stale authorization header from the mesasge.\n\t * We will supply a new one.\n\t */\n\tpj_list_erase(sent_auth);\n    }\n\n    /* Find credential to be used for the challenge. */\n    cred = auth_find_cred( sess, &hchal->challenge.common.realm,\n\t\t\t   &hchal->scheme);\n    if (!cred) {\n\tconst pj_str_t *realm = &hchal->challenge.common.realm;\n\tPJ_LOG(4,(THIS_FILE,\n\t\t  \"Unable to set auth for %s: can not find credential for %.*s/%.*s\",\n\t\t  tdata->obj_name,\n\t\t  realm->slen, realm->ptr,\n\t\t  hchal->scheme.slen, hchal->scheme.ptr));\n\treturn PJSIP_ENOCREDENTIAL;\n    }\n\n    /* Respond to authorization challenge. */\n    status = auth_respond( req_pool, hchal, uri, cred,\n\t\t\t   &tdata->msg->line.req.method,\n\t\t\t   sess->pool, cached_auth, h_auth);\n    return status;\n}\n\n\n/* Reinitialize outgoing request after 401/407 response is received.\n * The purpose of this function is:\n *  - to add a Authorization/Proxy-Authorization header.\n *  - to put the newly created Authorization/Proxy-Authorization header\n *    in cached_list.\n */\nPJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req(\tpjsip_auth_clt_sess *sess,\n\t\t\t\t\t\tconst pjsip_rx_data *rdata,\n\t\t\t\t\t\tpjsip_tx_data *old_request,\n\t\t\t\t\t\tpjsip_tx_data **new_request )\n{\n    pjsip_tx_data *tdata;\n    const pjsip_hdr *hdr;\n    unsigned chal_cnt;\n    pjsip_via_hdr *via;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sess && rdata && old_request && new_request,\n\t\t     PJ_EINVAL);\n    PJ_ASSERT_RETURN(sess->pool, PJSIP_ENOTINITIALIZED);\n    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG,\n\t\t     PJSIP_ENOTRESPONSEMSG);\n    PJ_ASSERT_RETURN(old_request->msg->type == PJSIP_REQUEST_MSG,\n\t\t     PJSIP_ENOTREQUESTMSG);\n    PJ_ASSERT_RETURN(rdata->msg_info.msg->line.status.code == 401 ||\n\t\t     rdata->msg_info.msg->line.status.code == 407,\n\t\t     PJSIP_EINVALIDSTATUS);\n\n    tdata = old_request;\n    tdata->auth_retry = PJ_FALSE;\n\n    /*\n     * Respond to each authentication challenge.\n     */\n    hdr = rdata->msg_info.msg->hdr.next;\n    chal_cnt = 0;\n    while (hdr != &rdata->msg_info.msg->hdr) {\n\tpjsip_cached_auth *cached_auth;\n\tconst pjsip_www_authenticate_hdr *hchal;\n\tpjsip_authorization_hdr *hauth;\n\n\t/* Find WWW-Authenticate or Proxy-Authenticate header. */\n\twhile (hdr != &rdata->msg_info.msg->hdr &&\n\t       hdr->type != PJSIP_H_WWW_AUTHENTICATE &&\n\t       hdr->type != PJSIP_H_PROXY_AUTHENTICATE)\n\t{\n\t    hdr = hdr->next;\n\t}\n\tif (hdr == &rdata->msg_info.msg->hdr)\n\t    break;\n\n\thchal = (const pjsip_www_authenticate_hdr*) hdr;\n\t++chal_cnt;\n\n\t/* Find authentication session for this realm, create a new one\n\t * if not present.\n\t */\n\tcached_auth = find_cached_auth(sess, &hchal->challenge.common.realm );\n\tif (!cached_auth) {\n\t    cached_auth = PJ_POOL_ZALLOC_T( sess->pool, pjsip_cached_auth);\n\t    pj_strdup( sess->pool, &cached_auth->realm, &hchal->challenge.common.realm);\n\t    cached_auth->is_proxy = (hchal->type == PJSIP_H_PROXY_AUTHENTICATE);\n#\t    if (PJSIP_AUTH_HEADER_CACHING)\n\t    {\n\t\tpj_list_init(&cached_auth->cached_hdr);\n\t    }\n#\t    endif\n\t    pj_list_insert_before( &sess->cached_auth, cached_auth );\n\t}\n\n\t/* Create authorization header for this challenge, and update\n\t * authorization session.\n\t */\n\tstatus = process_auth( tdata->pool, hchal, tdata->msg->line.req.uri,\n\t\t\t       tdata, sess, cached_auth, &hauth);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Add to the message. */\n\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);\n\n\t/* Process next header. */\n\thdr = hdr->next;\n    }\n\n    /* Check if challenge is present */\n    if (chal_cnt == 0)\n\treturn PJSIP_EAUTHNOCHAL;\n\n    /* Remove branch param in Via header. */\n    via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);\n    via->branch_param.slen = 0;\n\n    /* Restore strict route set.\n     * See http://trac.pjsip.org/repos/ticket/492\n     */\n    pjsip_restore_strict_route_set(tdata);\n\n    /* Must invalidate the message! */\n    pjsip_tx_data_invalidate_msg(tdata);\n\n    /* Retrying.. */\n    tdata->auth_retry = PJ_TRUE;\n\n    /* Increment reference counter. */\n    pjsip_tx_data_add_ref(tdata);\n\n    /* Done. */\n    *new_request = tdata;\n    return PJ_SUCCESS;\n\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_auth_msg.c",
    "content": "/* $Id: sip_auth_msg.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_auth_msg.h>\n#include <pjsip/sip_auth_parser.h>\n#include <pjsip/sip_parser.h>\n#include <pj/pool.h>\n#include <pj/list.h>\n#include <pj/string.h>\n#include <pj/assert.h>\n#include <pjsip/print_util.h>\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Authorization and Proxy-Authorization header.\n */\nstatic pjsip_authorization_hdr* pjsip_authorization_hdr_clone( pj_pool_t *pool,\n\t\t\t\t\t\t\t       const pjsip_authorization_hdr *hdr);\nstatic pjsip_authorization_hdr* pjsip_authorization_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t\t\t\t\t       const pjsip_authorization_hdr *hdr);\nstatic int pjsip_authorization_hdr_print( pjsip_authorization_hdr *hdr,\n\t\t\t\t\t  char *buf, pj_size_t size);\n\nstatic pjsip_hdr_vptr authorization_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_authorization_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_authorization_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_authorization_hdr_print,\n};\n\n\nPJ_DEF(pjsip_authorization_hdr*) pjsip_authorization_hdr_create(pj_pool_t *pool)\n{\n    pjsip_authorization_hdr *hdr;\n    hdr = PJ_POOL_ZALLOC_T(pool, pjsip_authorization_hdr);\n    init_hdr(hdr, PJSIP_H_AUTHORIZATION, &authorization_hdr_vptr);\n    pj_list_init(&hdr->credential.common.other_param);\n    return hdr;\n}\n\nPJ_DEF(pjsip_proxy_authorization_hdr*) pjsip_proxy_authorization_hdr_create(pj_pool_t *pool)\n{\n    pjsip_proxy_authorization_hdr *hdr;\n    hdr = PJ_POOL_ZALLOC_T(pool, pjsip_proxy_authorization_hdr);\n    init_hdr(hdr, PJSIP_H_PROXY_AUTHORIZATION, &authorization_hdr_vptr);\n    pj_list_init(&hdr->credential.common.other_param);\n    return hdr;\n}\n\nstatic int print_digest_credential(pjsip_digest_credential *cred, char *buf, pj_size_t size)\n{\n    pj_ssize_t printed;\n    char *startbuf = buf;\n    char *endbuf = buf + size;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n    \n    copy_advance_pair_quote_cond(buf, \"username=\", 9, cred->username, '\"', '\"');\n    copy_advance_pair_quote_cond_always(buf, \", realm=\", 8, cred->realm, '\"', \n\t\t\t\t\t'\"');\n    copy_advance_pair_quote(buf, \", nonce=\", 8, cred->nonce, '\"', '\"');\n    copy_advance_pair_quote_cond(buf, \", uri=\", 6, cred->uri, '\"', '\"');\n    copy_advance_pair_quote(buf, \", response=\", 11, cred->response, '\"', '\"');\n    copy_advance_pair(buf, \", algorithm=\", 12, cred->algorithm);\n    copy_advance_pair_quote_cond(buf, \", cnonce=\", 9, cred->cnonce, '\"', '\"');\n    copy_advance_pair_quote_cond(buf, \", opaque=\", 9, cred->opaque, '\"', '\"');\n    //Note: there's no dbl-quote in qop in Authorization header \n    // (unlike WWW-Authenticate)\n    //copy_advance_pair_quote_cond(buf, \", qop=\", 6, cred->qop, '\"', '\"');\n    copy_advance_pair(buf, \", qop=\", 6, cred->qop);\n    copy_advance_pair(buf, \", nc=\", 5, cred->nc);\n    \n    printed = pjsip_param_print_on(&cred->other_param, buf, endbuf-buf, \n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, \n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, ',');\n    if (printed < 0)\n\treturn -1;\n    buf += printed;\n\n    return (int) (buf-startbuf);\n}\n\nstatic int print_pgp_credential(pjsip_pgp_credential *cred, char *buf, pj_size_t size)\n{\n    PJ_UNUSED_ARG(cred);\n    PJ_UNUSED_ARG(buf);\n    PJ_UNUSED_ARG(size);\n    return -1;\n}\n\nstatic int pjsip_authorization_hdr_print( pjsip_authorization_hdr *hdr,\n\t\t\t\t\t  char *buf, pj_size_t size)\n{\n    int printed;\n    char *startbuf = buf;\n    char *endbuf = buf + size;\n\n    copy_advance(buf, hdr->name);\n    *buf++ = ':';\n    *buf++ = ' ';\n\n    copy_advance(buf, hdr->scheme);\n    *buf++ = ' ';\n\n    if (pj_stricmp(&hdr->scheme, &pjsip_DIGEST_STR) == 0)\n    {\n\tprinted = print_digest_credential(&hdr->credential.digest, buf, endbuf - buf);\n    } \n    else if (pj_stricmp(&hdr->scheme, &pjsip_PGP_STR) == 0)\n    {\n\tprinted = print_pgp_credential(&hdr->credential.pgp, buf, endbuf - buf);\n    } \n    else {\n\tpj_assert(0);\n\treturn -1;\n    }\n\n    if (printed == -1)\n\treturn -1;\n\n    buf += printed;\n    *buf = '\\0';\n    return (int)(buf-startbuf);\n}\n\nstatic pjsip_authorization_hdr* pjsip_authorization_hdr_clone(  pj_pool_t *pool,\n\t\t\t\t\t\t\t\tconst pjsip_authorization_hdr *rhs)\n{\n    /* This function also serves Proxy-Authorization header. */\n    pjsip_authorization_hdr *hdr;\n    if (rhs->type == PJSIP_H_AUTHORIZATION)\n\thdr = pjsip_authorization_hdr_create(pool);\n    else\n\thdr = pjsip_proxy_authorization_hdr_create(pool);\n\n    pj_strdup(pool, &hdr->scheme, &rhs->scheme);\n\n    if (pj_stricmp2(&hdr->scheme, \"digest\") == 0) {\n\tpj_strdup(pool, &hdr->credential.digest.username, &rhs->credential.digest.username);\n\tpj_strdup(pool, &hdr->credential.digest.realm, &rhs->credential.digest.realm);\n\tpj_strdup(pool, &hdr->credential.digest.nonce, &rhs->credential.digest.nonce);\n\tpj_strdup(pool, &hdr->credential.digest.uri, &rhs->credential.digest.uri);\n\tpj_strdup(pool, &hdr->credential.digest.response, &rhs->credential.digest.response);\n\tpj_strdup(pool, &hdr->credential.digest.algorithm, &rhs->credential.digest.algorithm);\n\tpj_strdup(pool, &hdr->credential.digest.cnonce, &rhs->credential.digest.cnonce);\n\tpj_strdup(pool, &hdr->credential.digest.opaque, &rhs->credential.digest.opaque);\n\tpj_strdup(pool, &hdr->credential.digest.qop, &rhs->credential.digest.qop);\n\tpj_strdup(pool, &hdr->credential.digest.nc, &rhs->credential.digest.nc);\n\tpjsip_param_clone(pool, &hdr->credential.digest.other_param, &rhs->credential.digest.other_param);\n    } else if (pj_stricmp2(&hdr->scheme, \"pgp\") == 0) {\n\tpj_assert(0);\n\treturn NULL;\n    } else {\n\tpj_assert(0);\n\treturn NULL;\n    }\n\n    return hdr;\n}\n\nstatic pjsip_authorization_hdr* \npjsip_authorization_hdr_shallow_clone(  pj_pool_t *pool,\n\t\t\t\t\tconst pjsip_authorization_hdr *rhs)\n{\n    /* This function also serves Proxy-Authorization header. */\n    pjsip_authorization_hdr *hdr;\n    hdr = PJ_POOL_ALLOC_T(pool, pjsip_authorization_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    pjsip_param_shallow_clone(pool, &hdr->credential.common.other_param, \n\t\t\t      &rhs->credential.common.other_param);\n    return hdr;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Proxy-Authenticate and WWW-Authenticate header.\n */\nstatic int pjsip_www_authenticate_hdr_print( pjsip_www_authenticate_hdr *hdr,\n\t\t\t\t\t     char *buf, pj_size_t size);\nstatic pjsip_www_authenticate_hdr* pjsip_www_authenticate_hdr_clone( pj_pool_t *pool,\n\t\t\t\t\t\t\t\t     const pjsip_www_authenticate_hdr *hdr);\nstatic pjsip_www_authenticate_hdr* pjsip_www_authenticate_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t\t\t\t\t\t     const pjsip_www_authenticate_hdr *hdr);\n\nstatic pjsip_hdr_vptr www_authenticate_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_www_authenticate_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_www_authenticate_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_www_authenticate_hdr_print,\n};\n\n\nPJ_DEF(pjsip_www_authenticate_hdr*) pjsip_www_authenticate_hdr_create(pj_pool_t *pool)\n{\n    pjsip_www_authenticate_hdr *hdr;\n    hdr = PJ_POOL_ZALLOC_T(pool, pjsip_www_authenticate_hdr);\n    init_hdr(hdr, PJSIP_H_WWW_AUTHENTICATE, &www_authenticate_hdr_vptr);\n    pj_list_init(&hdr->challenge.common.other_param);\n    return hdr;\n}\n\n\nPJ_DEF(pjsip_proxy_authenticate_hdr*) pjsip_proxy_authenticate_hdr_create(pj_pool_t *pool)\n{\n    pjsip_proxy_authenticate_hdr *hdr;\n    hdr = PJ_POOL_ZALLOC_T(pool, pjsip_proxy_authenticate_hdr);\n    init_hdr(hdr, PJSIP_H_PROXY_AUTHENTICATE, &www_authenticate_hdr_vptr);\n    pj_list_init(&hdr->challenge.common.other_param);\n    return hdr;\n}\n\nstatic int print_digest_challenge( pjsip_digest_challenge *chal,\n\t\t\t\t   char *buf, pj_size_t size)\n{\n    pj_ssize_t printed;\n    char *startbuf = buf;\n    char *endbuf = buf + size;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    /* Allow empty realm, see http://trac.pjsip.org/repos/ticket/1061 */\n    copy_advance_pair_quote(buf, \" realm=\", 7, chal->realm, '\"', '\"');\n    copy_advance_pair_quote_cond(buf, \",domain=\", 8, chal->domain, '\"', '\"');\n    copy_advance_pair_quote_cond(buf, \",nonce=\", 7, chal->nonce, '\"', '\"');\n    copy_advance_pair_quote_cond(buf, \",opaque=\", 8, chal->opaque, '\"', '\"');\n    if (chal->stale) {\n\tpj_str_t true_str = { \"true\", 4 };\n\tcopy_advance_pair(buf, \",stale=\", 7, true_str);\n    }\n    copy_advance_pair(buf, \",algorithm=\", 11, chal->algorithm);\n    copy_advance_pair_quote_cond(buf, \",qop=\", 5, chal->qop, '\"', '\"');\n    \n    printed = pjsip_param_print_on(&chal->other_param, buf, endbuf-buf, \n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, \n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, ',');\n    if (printed < 0)\n\treturn -1;\n    buf += printed;\n\n    return (int)(buf-startbuf);\n}\n\nstatic int print_pgp_challenge( pjsip_pgp_challenge *chal,\n\t\t\t        char *buf, pj_size_t size)\n{\n    PJ_UNUSED_ARG(chal);\n    PJ_UNUSED_ARG(buf);\n    PJ_UNUSED_ARG(size);\n    return -1;\n}\n\nstatic int pjsip_www_authenticate_hdr_print( pjsip_www_authenticate_hdr *hdr,\n\t\t\t\t\t     char *buf, pj_size_t size)\n{\n    int printed;\n    char *startbuf = buf;\n    char *endbuf = buf + size;\n\n    copy_advance(buf, hdr->name);\n    *buf++ = ':';\n    *buf++ = ' ';\n\n    copy_advance(buf, hdr->scheme);\n    *buf++ = ' ';\n\n    if (pj_stricmp2(&hdr->scheme, \"digest\") == 0)\n\tprinted = print_digest_challenge(&hdr->challenge.digest, buf, endbuf - buf);\n    else if (pj_stricmp2(&hdr->scheme, \"pgp\") == 0)\n\tprinted = print_pgp_challenge(&hdr->challenge.pgp, buf, endbuf - buf);\n    else {\n\tpj_assert(0);\n\treturn -1;\n    }\n\n    if (printed == -1)\n\treturn -1;\n\n    buf += printed;\n    *buf = '\\0';\n    return (int)(buf-startbuf);\n}\n\nstatic pjsip_www_authenticate_hdr* pjsip_www_authenticate_hdr_clone( pj_pool_t *pool,\n\t\t\t\t\t\t\t\t     const pjsip_www_authenticate_hdr *rhs)\n{\n    /* This function also serves Proxy-Authenticate header. */\n    pjsip_www_authenticate_hdr *hdr;\n    if (rhs->type == PJSIP_H_WWW_AUTHENTICATE)\n\thdr = pjsip_www_authenticate_hdr_create(pool);\n    else\n\thdr = pjsip_proxy_authenticate_hdr_create(pool);\n\n    pj_strdup(pool, &hdr->scheme, &rhs->scheme);\n\n    if (pj_stricmp2(&hdr->scheme, \"digest\") == 0) {\n\tpj_strdup(pool, &hdr->challenge.digest.realm, &rhs->challenge.digest.realm);\n\tpj_strdup(pool, &hdr->challenge.digest.domain, &rhs->challenge.digest.domain);\n\tpj_strdup(pool, &hdr->challenge.digest.nonce, &rhs->challenge.digest.nonce);\n\tpj_strdup(pool, &hdr->challenge.digest.opaque, &rhs->challenge.digest.opaque);\n\thdr->challenge.digest.stale = rhs->challenge.digest.stale;\n\tpj_strdup(pool, &hdr->challenge.digest.algorithm, &rhs->challenge.digest.algorithm);\n\tpj_strdup(pool, &hdr->challenge.digest.qop, &rhs->challenge.digest.qop);\n\tpjsip_param_clone(pool, &hdr->challenge.digest.other_param, \n\t\t\t  &rhs->challenge.digest.other_param);\n    } else if (pj_stricmp2(&hdr->scheme, \"pgp\") == 0) {\n\tpj_assert(0);\n\treturn NULL;\n    } else {\n\tpj_assert(0);\n\treturn NULL;\n    }\n\n    return hdr;\n\n}\n\nstatic pjsip_www_authenticate_hdr* pjsip_www_authenticate_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t\t\t\t\t\t     const pjsip_www_authenticate_hdr *rhs)\n{\n    /* This function also serves Proxy-Authenticate header. */\n    pjsip_www_authenticate_hdr *hdr;\n    hdr = PJ_POOL_ALLOC_T(pool, pjsip_www_authenticate_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    pjsip_param_shallow_clone(pool, &hdr->challenge.common.other_param, \n\t\t\t      &rhs->challenge.common.other_param);\n    return hdr;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_auth_parser.c",
    "content": "/* $Id: sip_auth_parser.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_auth_parser.h>\n#include <pjsip/sip_auth_msg.h>\n#include <pjsip/sip_parser.h>\n#include <pj/assert.h>\n#include <pj/string.h>\n#include <pj/except.h>\n#include <pj/pool.h>\n\nstatic pjsip_hdr* parse_hdr_authorization       ( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr* parse_hdr_proxy_authorization ( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr* parse_hdr_www_authenticate    ( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr* parse_hdr_proxy_authenticate  ( pjsip_parse_ctx *ctx );\n\nstatic void parse_digest_credential ( pj_scanner *scanner, pj_pool_t *pool, \n                                      pjsip_digest_credential *cred);\nstatic void parse_pgp_credential    ( pj_scanner *scanner, pj_pool_t *pool, \n                                      pjsip_pgp_credential *cred);\nstatic void parse_digest_challenge  ( pj_scanner *scanner, pj_pool_t *pool, \n                                      pjsip_digest_challenge *chal);\nstatic void parse_pgp_challenge     ( pj_scanner *scanner, pj_pool_t *pool,\n                                      pjsip_pgp_challenge *chal);\n\nconst pj_str_t\tpjsip_USERNAME_STR =\t    { \"username\", 8 },\n\t\tpjsip_REALM_STR =\t    { \"realm\", 5},\n\t\tpjsip_NONCE_STR =\t    { \"nonce\", 5},\n\t\tpjsip_URI_STR =\t\t    { \"uri\", 3 },\n\t\tpjsip_RESPONSE_STR =\t    { \"response\", 8 },\n\t\tpjsip_ALGORITHM_STR =\t    { \"algorithm\", 9 },\n\t\tpjsip_DOMAIN_STR =\t    { \"domain\", 6 },\n\t\tpjsip_STALE_STR =\t    { \"stale\", 5},\n\t\tpjsip_QOP_STR =\t\t    { \"qop\", 3},\n\t\tpjsip_CNONCE_STR =\t    { \"cnonce\", 6},\n\t\tpjsip_OPAQUE_STR =\t    { \"opaque\", 6},\n\t\tpjsip_NC_STR =\t\t    { \"nc\", 2},\n\t\tpjsip_TRUE_STR =\t    { \"true\", 4},\n\t\tpjsip_QUOTED_TRUE_STR =\t    { \"\\\"true\\\"\", 6},\n\t\tpjsip_FALSE_STR =\t    { \"false\", 5},\n\t\tpjsip_QUOTED_FALSE_STR =    { \"\\\"false\\\"\", 7},\n\t\tpjsip_DIGEST_STR =\t    { \"Digest\", 6},\n\t\tpjsip_QUOTED_DIGEST_STR =   { \"\\\"Digest\\\"\", 8},\n\t\tpjsip_PGP_STR =\t\t    { \"PGP\", 3 },\n\t\tpjsip_QUOTED_PGP_STR =\t    { \"\\\"PGP\\\"\", 5 },\n\t\tpjsip_MD5_STR =\t\t    { \"md5\", 3 },\n\t\tpjsip_QUOTED_MD5_STR =\t    { \"\\\"md5\\\"\", 5},\n\t\tpjsip_AUTH_STR =\t    { \"auth\", 4},\n\t\tpjsip_QUOTED_AUTH_STR =\t    { \"\\\"auth\\\"\", 6 };\n\n\nstatic void parse_digest_credential( pj_scanner *scanner, pj_pool_t *pool, \n                                     pjsip_digest_credential *cred)\n{\n    pj_list_init(&cred->other_param);\n\n    for (;;) {\n\tpj_str_t name, value;\n\n\tpjsip_parse_param_imp(scanner, pool, &name, &value,\n\t\t\t      PJSIP_PARSE_REMOVE_QUOTE);\n\n\tif (!pj_stricmp(&name, &pjsip_USERNAME_STR)) {\n\t    cred->username = value;\n\n\t} else if (!pj_stricmp(&name, &pjsip_REALM_STR)) {\n\t    cred->realm = value;\n\n\t} else if (!pj_stricmp(&name, &pjsip_NONCE_STR)) {\n\t    cred->nonce = value;\n\n\t} else if (!pj_stricmp(&name, &pjsip_URI_STR)) {\n\t    cred->uri = value;\n\n\t} else if (!pj_stricmp(&name, &pjsip_RESPONSE_STR)) {\n\t    cred->response = value;\n\n\t} else if (!pj_stricmp(&name, &pjsip_ALGORITHM_STR)) {\n\t    cred->algorithm = value;\n\n\t} else if (!pj_stricmp(&name, &pjsip_CNONCE_STR)) {\n\t    cred->cnonce = value;\n\n\t} else if (!pj_stricmp(&name, &pjsip_OPAQUE_STR)) {\n\t    cred->opaque = value;\n\n\t} else if (!pj_stricmp(&name, &pjsip_QOP_STR)) {\n\t    cred->qop = value;\n\n\t} else if (!pj_stricmp(&name, &pjsip_NC_STR)) {\n\t    cred->nc = value;\n\n\t} else {\n\t    pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);\n\t    p->name = name;\n\t    p->value = value;\n\t    pj_list_insert_before(&cred->other_param, p);\n\t}\n\n\t/* Eat comma */\n\tif (!pj_scan_is_eof(scanner) && *scanner->curptr == ',')\n\t    pj_scan_get_char(scanner);\n\telse\n\t    break;\n    }\n}\n\nstatic void parse_pgp_credential( pj_scanner *scanner, pj_pool_t *pool, \n                                  pjsip_pgp_credential *cred)\n{\n    PJ_UNUSED_ARG(scanner);\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(cred);\n\n    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n}\n\nstatic void parse_digest_challenge( pj_scanner *scanner, pj_pool_t *pool, \n                                    pjsip_digest_challenge *chal)\n{\n    pj_list_init(&chal->other_param);\n\n    for (;;) {\n\tpj_str_t name, value, unquoted_value;\n\n\tpjsip_parse_param_imp(scanner, pool, &name, &value, 0);\n\n        if (value.ptr && (value.ptr[0] == '\"')) {\n\t    unquoted_value.ptr = value.ptr + 1;\n\t    unquoted_value.slen = value.slen - 2;\n\t} else {\n\t    unquoted_value.ptr = value.ptr;\n\t    unquoted_value.slen = value.slen;\n\t}\n\n\tif (!pj_stricmp(&name, &pjsip_REALM_STR)) {\n\t    chal->realm = unquoted_value;\n\n\t} else if (!pj_stricmp(&name, &pjsip_DOMAIN_STR)) {\n\t    chal->domain = unquoted_value;\n\n\t} else if (!pj_stricmp(&name, &pjsip_NONCE_STR)) {\n\t    chal->nonce = unquoted_value;\n\n\t} else if (!pj_stricmp(&name, &pjsip_OPAQUE_STR)) {\n\t    chal->opaque = unquoted_value;\n\n\t} else if (!pj_stricmp(&name, &pjsip_STALE_STR)) {\n\t    if (!pj_stricmp(&value, &pjsip_TRUE_STR) || \n                !pj_stricmp(&value, &pjsip_QUOTED_TRUE_STR))\n            {\n\t\tchal->stale = 1;\n            }\n\n\t} else if (!pj_stricmp(&name, &pjsip_ALGORITHM_STR)) {\n\t    chal->algorithm = unquoted_value;\n\n\n\t} else if (!pj_stricmp(&name, &pjsip_QOP_STR)) {\n\t    chal->qop = unquoted_value;\n\n\t} else {\n\t    pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);\n\t    p->name = name;\n\t    p->value = value;\n\t    pj_list_insert_before(&chal->other_param, p);\n\t}\n\n\t/* Eat comma */\n\tif (!pj_scan_is_eof(scanner) && *scanner->curptr == ',')\n\t    pj_scan_get_char(scanner);\n\telse\n\t    break;\n    }\n}\n\nstatic void parse_pgp_challenge( pj_scanner *scanner, pj_pool_t *pool, \n                                 pjsip_pgp_challenge *chal)\n{\n    PJ_UNUSED_ARG(scanner);\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(chal);\n\n    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n}\n\nstatic void int_parse_hdr_authorization( pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t\t\t pjsip_authorization_hdr *hdr)\n{\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n    \n    if (*scanner->curptr == '\"') {\n\tpj_scan_get_quote(scanner, '\"', '\"', &hdr->scheme);\n\thdr->scheme.ptr++;\n\thdr->scheme.slen -= 2;\n    } else {\n\tpj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &hdr->scheme);\n    }\n\n    if (!pj_stricmp(&hdr->scheme, &pjsip_DIGEST_STR)) {\n\n\tparse_digest_credential(scanner, pool, &hdr->credential.digest);\n\n    } else if (!pj_stricmp(&hdr->scheme, &pjsip_PGP_STR)) {\n\n\tparse_pgp_credential( scanner, pool, &hdr->credential.pgp);\n\n    } else {\n\tPJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n    }\n\n    pjsip_parse_end_hdr_imp( scanner );\n}\n\nstatic void int_parse_hdr_authenticate( pj_scanner *scanner, pj_pool_t *pool, \n\t\t\t\t\tpjsip_www_authenticate_hdr *hdr)\n{\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    if (*scanner->curptr == '\"') {\n\tpj_scan_get_quote(scanner, '\"', '\"', &hdr->scheme);\n\thdr->scheme.ptr++;\n\thdr->scheme.slen -= 2;\n    } else {\n\tpj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &hdr->scheme);\n    }\n\n    if (!pj_stricmp(&hdr->scheme, &pjsip_DIGEST_STR)) {\n\n\tparse_digest_challenge(scanner, pool, &hdr->challenge.digest);\n\n    } else if (!pj_stricmp(&hdr->scheme, &pjsip_PGP_STR)) {\n\n\tparse_pgp_challenge(scanner, pool, &hdr->challenge.pgp);\n\n    } else {\n\tPJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n    }\n\n    pjsip_parse_end_hdr_imp( scanner );\n}\n\n\nstatic pjsip_hdr* parse_hdr_authorization( pjsip_parse_ctx *ctx )\n{\n    pjsip_authorization_hdr *hdr = pjsip_authorization_hdr_create(ctx->pool);\n    int_parse_hdr_authorization(ctx->scanner, ctx->pool, hdr);\n    return (pjsip_hdr*)hdr;\n}\n\nstatic pjsip_hdr* parse_hdr_proxy_authorization( pjsip_parse_ctx *ctx )\n{\n    pjsip_proxy_authorization_hdr *hdr = \n        pjsip_proxy_authorization_hdr_create(ctx->pool);\n    int_parse_hdr_authorization(ctx->scanner, ctx->pool, hdr);\n    return (pjsip_hdr*)hdr;\n}\n\nstatic pjsip_hdr* parse_hdr_www_authenticate( pjsip_parse_ctx *ctx )\n{\n    pjsip_www_authenticate_hdr *hdr = \n        pjsip_www_authenticate_hdr_create(ctx->pool);\n    int_parse_hdr_authenticate(ctx->scanner, ctx->pool, hdr);\n    return (pjsip_hdr*)hdr;\n}\n\nstatic pjsip_hdr* parse_hdr_proxy_authenticate( pjsip_parse_ctx *ctx )\n{\n    pjsip_proxy_authenticate_hdr *hdr = \n        pjsip_proxy_authenticate_hdr_create(ctx->pool);\n    int_parse_hdr_authenticate(ctx->scanner, ctx->pool, hdr);\n    return (pjsip_hdr*)hdr;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_auth_init_parser()\n{\n    pj_status_t status;\n\n    status = pjsip_register_hdr_parser( \"Authorization\", NULL, \n                                        &parse_hdr_authorization);\n    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    status = pjsip_register_hdr_parser( \"Proxy-Authorization\", NULL, \n                                        &parse_hdr_proxy_authorization);\n    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    status = pjsip_register_hdr_parser( \"WWW-Authenticate\", NULL, \n                                        &parse_hdr_www_authenticate);\n    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    status = pjsip_register_hdr_parser( \"Proxy-Authenticate\", NULL, \n                                        &parse_hdr_proxy_authenticate);\n    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(void) pjsip_auth_deinit_parser()\n{\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_auth_parser_wrap.cpp",
    "content": "/* $Id: sip_auth_parser_wrap.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * This file is a C++ wrapper, see ticket #886 for details.\n */\n\n#include \"sip_auth_parser.c\"\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_auth_server.c",
    "content": "/* $Id: sip_auth_server.c 4214 2012-07-25 14:29:28Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pjsip/sip_auth.h>\n#include <pjsip/sip_auth_parser.h>\t/* just to get pjsip_DIGEST_STR */\n#include <pjsip/sip_auth_msg.h>\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_transport.h>\n#include <pj/string.h>\n#include <pj/assert.h>\n\n\n/*\n * Initialize server authorization session data structure to serve the \n * specified realm and to use lookup_func function to look for the credential \n * info. \n */\nPJ_DEF(pj_status_t) pjsip_auth_srv_init(  pj_pool_t *pool,\n\t\t\t\t\t  pjsip_auth_srv *auth_srv,\n\t\t\t\t\t  const pj_str_t *realm,\n\t\t\t\t\t  pjsip_auth_lookup_cred *lookup,\n\t\t\t\t\t  unsigned options )\n{\n    PJ_ASSERT_RETURN(pool && auth_srv && realm && lookup, PJ_EINVAL);\n\n    pj_bzero(auth_srv, sizeof(*auth_srv));\n    pj_strdup( pool, &auth_srv->realm, realm);\n    auth_srv->lookup = lookup;\n    auth_srv->is_proxy = (options & PJSIP_AUTH_SRV_IS_PROXY);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Initialize server authorization session data structure to serve the \n * specified realm and to use lookup_func function to look for the credential \n * info. \n */\nPJ_DEF(pj_status_t) pjsip_auth_srv_init2(\n\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t    pjsip_auth_srv *auth_srv,\n\t\t\t\t    const pjsip_auth_srv_init_param *param)\n{\n    PJ_ASSERT_RETURN(pool && auth_srv && param, PJ_EINVAL);\n\n    pj_bzero(auth_srv, sizeof(*auth_srv));\n    pj_strdup( pool, &auth_srv->realm, param->realm);\n    auth_srv->lookup2 = param->lookup2;\n    auth_srv->is_proxy = (param->options & PJSIP_AUTH_SRV_IS_PROXY);\n\n    return PJ_SUCCESS;\n}\n\n\n/* Verify incoming Authorization/Proxy-Authorization header against the \n * specified credential.\n */\nstatic pj_status_t pjsip_auth_verify( const pjsip_authorization_hdr *hdr,\n\t\t\t\t      const pj_str_t *method,\n\t\t\t\t      const pjsip_cred_info *cred_info )\n{\n    if (pj_stricmp(&hdr->scheme, &pjsip_DIGEST_STR) == 0) {\n\tchar digest_buf[PJSIP_MD5STRLEN];\n\tpj_str_t digest;\n\tconst pjsip_digest_credential *dig = &hdr->credential.digest;\n\n\t/* Check that username and realm match. \n\t * These checks should have been performed before entering this\n\t * function.\n\t */\n\tPJ_ASSERT_RETURN(pj_strcmp(&dig->username, &cred_info->username) == 0,\n\t\t\t PJ_EINVALIDOP);\n\tPJ_ASSERT_RETURN(pj_strcmp(&dig->realm, &cred_info->realm) == 0,\n\t\t\t PJ_EINVALIDOP);\n\n\t/* Prepare for our digest calculation. */\n\tdigest.ptr = digest_buf;\n\tdigest.slen = PJSIP_MD5STRLEN;\n\n\t/* Create digest for comparison. */\n\tpjsip_auth_create_digest(&digest, \n\t\t\t\t &hdr->credential.digest.nonce,\n\t\t\t\t &hdr->credential.digest.nc, \n\t\t\t\t &hdr->credential.digest.cnonce,\n\t\t\t\t &hdr->credential.digest.qop,\n\t\t\t\t &hdr->credential.digest.uri,\n\t\t\t\t &cred_info->realm,\n\t\t\t\t cred_info, \n\t\t\t\t method );\n\n\t/* Compare digest. */\n\treturn (pj_stricmp(&digest, &hdr->credential.digest.response) == 0) ?\n\t       PJ_SUCCESS : PJSIP_EAUTHINVALIDDIGEST;\n\n    } else {\n\tpj_assert(!\"Unsupported authentication scheme\");\n\treturn PJSIP_EINVALIDAUTHSCHEME;\n    }\n}\n\n\n/*\n * Request the authorization server framework to verify the authorization \n * information in the specified request in rdata.\n */\nPJ_DEF(pj_status_t) pjsip_auth_srv_verify( pjsip_auth_srv *auth_srv,\n\t\t\t\t\t   pjsip_rx_data *rdata,\n\t\t\t\t\t   int *status_code)\n{\n    pjsip_authorization_hdr *h_auth;\n    pjsip_msg *msg = rdata->msg_info.msg;\n    pjsip_hdr_e htype;\n    pj_str_t acc_name;\n    pjsip_cred_info cred_info;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(auth_srv && rdata, PJ_EINVAL);\n    PJ_ASSERT_RETURN(msg->type == PJSIP_REQUEST_MSG, PJSIP_ENOTREQUESTMSG);\n\n    htype = auth_srv->is_proxy ? PJSIP_H_PROXY_AUTHORIZATION : \n\t\t\t\t PJSIP_H_AUTHORIZATION;\n\n    /* Initialize status with 200. */\n    *status_code = 200;\n\n    /* Find authorization header for our realm. */\n    h_auth = (pjsip_authorization_hdr*) pjsip_msg_find_hdr(msg, htype, NULL);\n    while (h_auth) {\n\tif (!pj_stricmp(&h_auth->credential.common.realm, &auth_srv->realm))\n\t    break;\n\n\th_auth = h_auth->next;\n\tif (h_auth == (void*) &msg->hdr) {\n\t    h_auth = NULL;\n\t    break;\n\t}\n\n\th_auth=(pjsip_authorization_hdr*)pjsip_msg_find_hdr(msg,htype,h_auth);\n    }\n\n    if (!h_auth) {\n\t*status_code = auth_srv->is_proxy ? 407 : 401;\n\treturn PJSIP_EAUTHNOAUTH;\n    }\n\n    /* Check authorization scheme. */\n    if (pj_stricmp(&h_auth->scheme, &pjsip_DIGEST_STR) == 0)\n\tacc_name = h_auth->credential.digest.username;\n    else {\n\t*status_code = auth_srv->is_proxy ? 407 : 401;\n\treturn PJSIP_EINVALIDAUTHSCHEME;\n    }\n\n    /* Find the credential information for the account. */\n    if (auth_srv->lookup2) {\n\tpjsip_auth_lookup_cred_param param;\n\n\tpj_bzero(&param, sizeof(param));\n\tparam.realm = auth_srv->realm;\n\tparam.acc_name = acc_name;\n\tparam.rdata = rdata;\n\tstatus = (*auth_srv->lookup2)(rdata->tp_info.pool, &param, &cred_info);\n\tif (status != PJ_SUCCESS) {\n\t    *status_code = PJSIP_SC_FORBIDDEN;\n\t    return status;\n\t}\n    } else {\n\tstatus = (*auth_srv->lookup)(rdata->tp_info.pool, &auth_srv->realm,\n\t\t\t\t     &acc_name, &cred_info);\n\tif (status != PJ_SUCCESS) {\n\t    *status_code = PJSIP_SC_FORBIDDEN;\n\t    return status;\n\t}\n    }\n\n    /* Authenticate with the specified credential. */\n    status = pjsip_auth_verify(h_auth, &msg->line.req.method.name, \n\t\t\t       &cred_info);\n    if (status != PJ_SUCCESS) {\n\t*status_code = PJSIP_SC_FORBIDDEN;\n    }\n    return status;\n}\n\n\n/*\n * Add authentication challenge headers to the outgoing response in tdata. \n * Application may specify its customized nonce and opaque for the challenge, \n * or can leave the value to NULL to make the function fills them in with \n * random characters.\n */\nPJ_DEF(pj_status_t) pjsip_auth_srv_challenge(  pjsip_auth_srv *auth_srv,\n\t\t\t\t\t       const pj_str_t *qop,\n\t\t\t\t\t       const pj_str_t *nonce,\n\t\t\t\t\t       const pj_str_t *opaque,\n\t\t\t\t\t       pj_bool_t stale,\n\t\t\t\t\t       pjsip_tx_data *tdata)\n{\n    pjsip_www_authenticate_hdr *hdr;\n    char nonce_buf[16];\n    pj_str_t random;\n\n    PJ_ASSERT_RETURN( auth_srv && tdata, PJ_EINVAL );\n\n    random.ptr = nonce_buf;\n    random.slen = sizeof(nonce_buf);\n\n    /* Create the header. */\n    if (auth_srv->is_proxy)\n\thdr = pjsip_proxy_authenticate_hdr_create(tdata->pool);\n    else\n\thdr = pjsip_www_authenticate_hdr_create(tdata->pool);\n\n    /* Initialize header. \n     * Note: only support digest authentication now.\n     */\n    hdr->scheme = pjsip_DIGEST_STR;\n    hdr->challenge.digest.algorithm = pjsip_MD5_STR;\n    if (nonce) {\n\tpj_strdup(tdata->pool, &hdr->challenge.digest.nonce, nonce);\n    } else {\n\tpj_create_random_string(nonce_buf, sizeof(nonce_buf));\n\tpj_strdup(tdata->pool, &hdr->challenge.digest.nonce, &random);\n    }\n    if (opaque) {\n\tpj_strdup(tdata->pool, &hdr->challenge.digest.opaque, opaque);\n    } else {\n\tpj_create_random_string(nonce_buf, sizeof(nonce_buf));\n\tpj_strdup(tdata->pool, &hdr->challenge.digest.opaque, &random);\n    }\n    if (qop) {\n\tpj_strdup(tdata->pool, &hdr->challenge.digest.qop, qop);\n    } else {\n\thdr->challenge.digest.qop.slen = 0;\n    }\n    pj_strdup(tdata->pool, &hdr->challenge.digest.realm, &auth_srv->realm);\n    hdr->challenge.digest.stale = stale;\n\n    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_config.c",
    "content": "/* $Id: sip_config.c 4442 2013-03-19 07:39:25Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pjsip/sip_config.h>\n\n/* pjsip configuration instance, initialized with default values */\npjsip_cfg_t pjsip_sip_cfg_var =\n{\n    /* Global settings */\n    {\n       PJSIP_ALLOW_PORT_IN_FROMTO_HDR,\n       PJSIP_ACCEPT_REPLACE_IN_EARLY_STATE,\n       0,\n       0,\n       PJSIP_DONT_SWITCH_TO_TCP,\n       PJSIP_DONT_SWITCH_TO_TLS,\n       PJSIP_FOLLOW_EARLY_MEDIA_FORK,\n       PJSIP_REQ_HAS_VIA_ALIAS,\n       PJSIP_RESOLVE_HOSTNAME_TO_GET_INTERFACE,\n       0\n    },\n\n    /* Transaction settings */\n    {\n       PJSIP_MAX_TSX_COUNT,\n       PJSIP_T1_TIMEOUT,\n       PJSIP_T2_TIMEOUT,\n       PJSIP_T4_TIMEOUT,\n       PJSIP_TD_TIMEOUT\n    },\n\n    /* Client registration client */\n    {\n\tPJSIP_REGISTER_CLIENT_CHECK_CONTACT\n    },\n\n    /* TCP transport settings */\n    {\n        PJSIP_TCP_KEEP_ALIVE_INTERVAL\n    },\n\n    /* TLS transport settings */\n    {\n        PJSIP_TLS_KEEP_ALIVE_INTERVAL\n    }\n};\n\n\n#ifdef PJ_DLL\nPJ_DEF(pjsip_cfg_t*) pjsip_cfg(void)\n{\n    return &pjsip_sip_cfg_var;\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_dialog.c",
    "content": "/* $Id: sip_dialog.c 4208 2012-07-18 07:52:33Z ming $ */\n/*\n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n#include <pjsip/sip_dialog.h>\n#include <pjsip/sip_ua_layer.h>\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_parser.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_util.h>\n#include <pjsip/sip_transaction.h>\n#include <pj/assert.h>\n#include <pj/os.h>\n#include <pj/string.h>\n#include <pj/pool.h>\n#include <pj/guid.h>\n#include <pj/rand.h>\n#include <pj/array.h>\n#include <pj/except.h>\n#include <pj/hash.h>\n#include <pj/log.h>\n\n#define THIS_FILE\t\"sip_dialog.c\"\n\nlong pjsip_dlg_lock_tls_id;\n\n/* Config */\npj_bool_t pjsip_include_allow_hdr_in_dlg = PJSIP_INCLUDE_ALLOW_HDR_IN_DLG;\n\n/* Contact header string */\nstatic const pj_str_t HCONTACT = { \"Contact\", 7 };\n\n\nPJ_DEF(pj_bool_t) pjsip_method_creates_dialog(const pjsip_method *m)\n{\n    const pjsip_method subscribe = { PJSIP_OTHER_METHOD, {\"SUBSCRIBE\", 9}};\n    const pjsip_method refer = { PJSIP_OTHER_METHOD, {\"REFER\", 5}};\n    const pjsip_method notify = { PJSIP_OTHER_METHOD, {\"NOTIFY\", 6}};\n    const pjsip_method update = { PJSIP_OTHER_METHOD, {\"UPDATE\", 6}};\n\n    return m->id == PJSIP_INVITE_METHOD ||\n\t   (pjsip_method_cmp(m, &subscribe)==0) ||\n\t   (pjsip_method_cmp(m, &refer)==0) ||\n\t   (pjsip_method_cmp(m, &notify)==0) ||\n\t   (pjsip_method_cmp(m, &update)==0);\n}\n\nstatic pj_status_t create_dialog( pjsip_user_agent *ua,\n\t\t\t\t  pjsip_dialog **p_dlg)\n{\n    pjsip_endpoint *endpt;\n    pj_pool_t *pool;\n    pjsip_dialog *dlg;\n    pj_status_t status;\n\n    endpt = pjsip_ua_get_endpt(ua);\n    if (!endpt)\n\treturn PJ_EINVALIDOP;\n\n    pool = pjsip_endpt_create_pool(endpt, \"dlg%p\",\n\t\t\t\t   PJSIP_POOL_LEN_DIALOG,\n\t\t\t\t   PJSIP_POOL_INC_DIALOG);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    dlg = PJ_POOL_ZALLOC_T(pool, pjsip_dialog);\n    PJ_ASSERT_RETURN(dlg != NULL, PJ_ENOMEM);\n\n    dlg->pool = pool;\n    pj_ansi_snprintf(dlg->obj_name, sizeof(dlg->obj_name), \"dlg%p\", dlg);\n    dlg->ua = ua;\n    dlg->endpt = endpt;\n    dlg->state = PJSIP_DIALOG_STATE_NULL;\n    dlg->add_allow = pjsip_include_allow_hdr_in_dlg;\n\n    pj_list_init(&dlg->inv_hdr);\n    pj_list_init(&dlg->rem_cap_hdr);\n\n    status = pj_mutex_create_recursive(pool, dlg->obj_name, &dlg->mutex_);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    pjsip_target_set_init(&dlg->target_set);\n\n    *p_dlg = dlg;\n    return PJ_SUCCESS;\n\non_error:\n    if (dlg->mutex_)\n\tpj_mutex_destroy(dlg->mutex_);\n    pjsip_endpt_release_pool(endpt, pool);\n    return status;\n}\n\nstatic void destroy_dialog( pjsip_dialog *dlg, pj_bool_t unlock_mutex )\n{\n    if (dlg->mutex_) {\n        if (unlock_mutex) pj_mutex_unlock(dlg->mutex_);\n\tpj_mutex_destroy(dlg->mutex_);\n\tdlg->mutex_ = NULL;\n    }\n    if (dlg->tp_sel.type != PJSIP_TPSELECTOR_NONE) {\n\tpjsip_tpselector_dec_ref(&dlg->tp_sel);\n\tpj_bzero(&dlg->tp_sel, sizeof(pjsip_tpselector));\n    }\n    pjsip_endpt_release_pool(dlg->endpt, dlg->pool);\n}\n\n\n/*\n * Create an UAC dialog.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,\n\t\t\t\t\t  const pj_str_t *local_uri,\n\t\t\t\t\t  const pj_str_t *local_contact,\n\t\t\t\t\t  const pj_str_t *remote_uri,\n\t\t\t\t\t  const pj_str_t *target,\n\t\t\t\t\t  pjsip_dialog **p_dlg)\n{\n    pj_status_t status;\n    pj_str_t tmp;\n    pjsip_dialog *dlg;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(ua && local_uri && remote_uri && p_dlg, PJ_EINVAL);\n\n    /* Create dialog instance. */\n    status = create_dialog(ua, &dlg);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Parse target. */\n    pj_strdup_with_null(dlg->pool, &tmp, target ? target : remote_uri);\n    dlg->target = pjsip_parse_uri(dlg->pool, tmp.ptr, tmp.slen, 0);\n    if (!dlg->target) {\n\tstatus = PJSIP_EINVALIDURI;\n\tgoto on_error;\n    }\n\n    /* Put any header param in the target URI into INVITE header list. */\n    if (PJSIP_URI_SCHEME_IS_SIP(dlg->target) ||\n\tPJSIP_URI_SCHEME_IS_SIPS(dlg->target))\n    {\n\tpjsip_param *param;\n\tpjsip_sip_uri *uri = (pjsip_sip_uri*)pjsip_uri_get_uri(dlg->target);\n\n\tparam = uri->header_param.next;\n\twhile (param != &uri->header_param) {\n\t    pjsip_hdr *hdr;\n\t    int c;\n\n\t    c = param->value.ptr[param->value.slen];\n\t    param->value.ptr[param->value.slen] = '\\0';\n\n\t    hdr = (pjsip_hdr*)\n\t    \t  pjsip_parse_hdr(dlg->pool, &param->name, param->value.ptr,\n\t\t\t\t  param->value.slen, NULL);\n\n\t    param->value.ptr[param->value.slen] = (char)c;\n\n\t    if (hdr == NULL) {\n\t\tstatus = PJSIP_EINVALIDURI;\n\t\tgoto on_error;\n\t    }\n\t    pj_list_push_back(&dlg->inv_hdr, hdr);\n\n\t    param = param->next;\n\t}\n\n\t/* Now must remove any header params from URL, since that would\n\t * create another header in pjsip_endpt_create_request().\n\t */\n\tpj_list_init(&uri->header_param);\n    }\n\n    /* Add target to the target set */\n    pjsip_target_set_add_uri(&dlg->target_set, dlg->pool, dlg->target, 0);\n\n    /* Init local info. */\n    dlg->local.info = pjsip_from_hdr_create(dlg->pool);\n    pj_strdup_with_null(dlg->pool, &dlg->local.info_str, local_uri);\n    dlg->local.info->uri = pjsip_parse_uri(dlg->pool,\n\t\t\t\t\t   dlg->local.info_str.ptr,\n\t\t\t\t\t   dlg->local.info_str.slen, 0);\n    if (!dlg->local.info->uri) {\n\tstatus = PJSIP_EINVALIDURI;\n\tgoto on_error;\n    }\n\n    /* Generate local tag. */\n    pj_create_unique_string(dlg->pool, &dlg->local.info->tag);\n\n    /* Calculate hash value of local tag. */\n    dlg->local.tag_hval = pj_hash_calc_tolower(0, NULL,\n                                               &dlg->local.info->tag);\n\n    /* Randomize local CSeq. */\n    dlg->local.first_cseq = pj_rand() & 0x7FFF;\n    dlg->local.cseq = dlg->local.first_cseq;\n\n    /* Init local contact. */\n    pj_strdup_with_null(dlg->pool, &tmp,\n\t\t\tlocal_contact ? local_contact : local_uri);\n    dlg->local.contact = (pjsip_contact_hdr*)\n\t\t\t pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr,\n\t\t\t\t\t tmp.slen, NULL);\n    if (!dlg->local.contact) {\n\tstatus = PJSIP_EINVALIDURI;\n\tgoto on_error;\n    }\n\n    /* Init remote info. */\n    dlg->remote.info = pjsip_to_hdr_create(dlg->pool);\n    pj_strdup_with_null(dlg->pool, &dlg->remote.info_str, remote_uri);\n    dlg->remote.info->uri = pjsip_parse_uri(dlg->pool,\n\t\t\t\t\t    dlg->remote.info_str.ptr,\n\t\t\t\t\t    dlg->remote.info_str.slen, 0);\n    if (!dlg->remote.info->uri) {\n\tstatus = PJSIP_EINVALIDURI;\n\tgoto on_error;\n    }\n\n    /* Remove header param from remote.info_str, if any */\n    if (PJSIP_URI_SCHEME_IS_SIP(dlg->remote.info->uri) ||\n\tPJSIP_URI_SCHEME_IS_SIPS(dlg->remote.info->uri))\n    {\n\tpjsip_sip_uri *sip_uri = (pjsip_sip_uri *)\n\t\t\t\t pjsip_uri_get_uri(dlg->remote.info->uri);\n\tif (!pj_list_empty(&sip_uri->header_param)) {\n\t    pj_str_t tmp2;\n\n\t    /* Remove all header param */\n\t    pj_list_init(&sip_uri->header_param);\n\n\t    /* Print URI */\n\t    tmp2.ptr = (char*) pj_pool_alloc(dlg->pool,\n\t    \t\t\t\t    dlg->remote.info_str.slen);\n\t    tmp2.slen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,\n\t\t\t\t       sip_uri, tmp2.ptr,\n\t\t\t\t       dlg->remote.info_str.slen);\n\n\t    if (tmp2.slen < 1) {\n\t\tstatus = PJSIP_EURITOOLONG;\n\t\tgoto on_error;\n\t    }\n\n\t    /* Assign remote.info_str */\n\t    dlg->remote.info_str = tmp2;\n\t}\n    }\n\n\n    /* Initialize remote's CSeq to -1. */\n    dlg->remote.cseq = dlg->remote.first_cseq = -1;\n\n    /* Initial role is UAC. */\n    dlg->role = PJSIP_ROLE_UAC;\n\n    /* Secure? */\n    dlg->secure = PJSIP_URI_SCHEME_IS_SIPS(dlg->target);\n\n    /* Generate Call-ID header. */\n    dlg->call_id = pjsip_cid_hdr_create(dlg->pool);\n    pj_create_unique_string(dlg->pool, &dlg->call_id->id);\n\n    /* Initial route set is empty. */\n    pj_list_init(&dlg->route_set);\n\n    /* Init client authentication session. */\n    status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt,\n\t\t\t\t dlg->pool, 0);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Register this dialog to user agent. */\n    status = pjsip_ua_register_dlg( ua, dlg );\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n\n    /* Done! */\n    *p_dlg = dlg;\n\n\n    PJ_LOG(5,(dlg->obj_name, \"UAC dialog created\"));\n\n    return PJ_SUCCESS;\n\non_error:\n    destroy_dialog(dlg, PJ_FALSE);\n    return status;\n}\n\n\n/*\n * Create UAS dialog.\n */\npj_status_t create_uas_dialog( pjsip_user_agent *ua,\n\t\t\t       pjsip_rx_data *rdata,\n\t\t\t       const pj_str_t *contact,\n\t\t\t       pj_bool_t inc_lock,\n\t\t\t       pjsip_dialog **p_dlg)\n{\n    pj_status_t status;\n    pjsip_hdr *pos = NULL;\n    pjsip_contact_hdr *contact_hdr;\n    pjsip_rr_hdr *rr;\n    pjsip_transaction *tsx = NULL;\n    pj_str_t tmp;\n    enum { TMP_LEN=128};\n    pj_ssize_t len;\n    pjsip_dialog *dlg;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(ua && rdata && p_dlg, PJ_EINVAL);\n\n    /* rdata must have request message. */\n    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,\n\t\t     PJSIP_ENOTREQUESTMSG);\n\n    /* Request must not have To tag.\n     * This should have been checked in the user agent (or application?).\n     */\n    PJ_ASSERT_RETURN(rdata->msg_info.to->tag.slen == 0, PJ_EINVALIDOP);\n\n    /* The request must be a dialog establishing request. */\n    PJ_ASSERT_RETURN(\n\tpjsip_method_creates_dialog(&rdata->msg_info.msg->line.req.method),\n\tPJ_EINVALIDOP);\n\n    /* Create dialog instance. */\n    status = create_dialog(ua, &dlg);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Temprary string for getting the string representation of\n     * both local and remote URI.\n     */\n    tmp.ptr = (char*) pj_pool_alloc(rdata->tp_info.pool, TMP_LEN);\n\n    /* Init local info from the To header. */\n    dlg->local.info = (pjsip_fromto_hdr*)\n    \t\t      pjsip_hdr_clone(dlg->pool, rdata->msg_info.to);\n    pjsip_fromto_hdr_set_from(dlg->local.info);\n\n    /* Generate local tag. */\n    pj_create_unique_string(dlg->pool, &dlg->local.info->tag);\n\n\n    /* Print the local info. */\n    len = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,\n\t\t\t  dlg->local.info->uri, tmp.ptr, TMP_LEN);\n    if (len < 1) {\n\tpj_ansi_strcpy(tmp.ptr, \"<-error: uri too long->\");\n\ttmp.slen = pj_ansi_strlen(tmp.ptr);\n    } else\n\ttmp.slen = len;\n\n    /* Save the local info. */\n    pj_strdup(dlg->pool, &dlg->local.info_str, &tmp);\n\n    /* Calculate hash value of local tag. */\n    dlg->local.tag_hval = pj_hash_calc_tolower(0, NULL, &dlg->local.info->tag);\n\n\n    /* Randomize local cseq */\n    dlg->local.first_cseq = pj_rand() & 0x7FFF;\n    dlg->local.cseq = dlg->local.first_cseq;\n\n    /* Init local contact. */\n    /* TODO:\n     *  Section 12.1.1, paragraph about using SIPS URI in Contact.\n     *  If the request that initiated the dialog contained a SIPS URI\n     *  in the Request-URI or in the top Record-Route header field value,\n     *  if there was any, or the Contact header field if there was no\n     *  Record-Route header field, the Contact header field in the response\n     *  MUST be a SIPS URI.\n     */\n    if (contact) {\n\tpj_str_t tmp2;\n\n\tpj_strdup_with_null(dlg->pool, &tmp2, contact);\n\tdlg->local.contact = (pjsip_contact_hdr*)\n\t\t\t     pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp2.ptr,\n\t\t\t\t\t     tmp2.slen, NULL);\n\tif (!dlg->local.contact) {\n\t    status = PJSIP_EINVALIDURI;\n\t    goto on_error;\n\t}\n\n    } else {\n\tdlg->local.contact = pjsip_contact_hdr_create(dlg->pool);\n\tdlg->local.contact->uri = dlg->local.info->uri;\n    }\n\n    /* Init remote info from the From header. */\n    dlg->remote.info = (pjsip_fromto_hdr*)\n    \t\t       pjsip_hdr_clone(dlg->pool, rdata->msg_info.from);\n    pjsip_fromto_hdr_set_to(dlg->remote.info);\n\n    /* Print the remote info. */\n    len = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,\n\t\t\t  dlg->remote.info->uri, tmp.ptr, TMP_LEN);\n    if (len < 1) {\n\tpj_ansi_strcpy(tmp.ptr, \"<-error: uri too long->\");\n\ttmp.slen = pj_ansi_strlen(tmp.ptr);\n    } else\n\ttmp.slen = len;\n\n    /* Save the remote info. */\n    pj_strdup(dlg->pool, &dlg->remote.info_str, &tmp);\n\n\n    /* Init remote's contact from Contact header.\n     * Iterate the Contact URI until we find sip: or sips: scheme.\n     */\n    do {\n\tcontact_hdr = (pjsip_contact_hdr*)\n\t\t      pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,\n\t\t\t\t         pos);\n\tif (contact_hdr) {\n\t    if (!contact_hdr->uri ||\n\t\t(!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) &&\n\t\t !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)))\n\t    {\n\t\tpos = (pjsip_hdr*)contact_hdr->next;\n\t\tif (pos == &rdata->msg_info.msg->hdr)\n\t\t    contact_hdr = NULL;\n\t    } else {\n\t\tbreak;\n\t    }\n\t}\n    } while (contact_hdr);\n\n    if (!contact_hdr) {\n\tstatus = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);\n\tgoto on_error;\n    }\n\n    dlg->remote.contact = (pjsip_contact_hdr*)\n    \t\t\t  pjsip_hdr_clone(dlg->pool, (pjsip_hdr*)contact_hdr);\n\n    /* Init remote's CSeq from CSeq header */\n    dlg->remote.cseq = dlg->remote.first_cseq = rdata->msg_info.cseq->cseq;\n\n    /* Set initial target to remote's Contact. */\n    dlg->target = dlg->remote.contact->uri;\n\n    /* Initial role is UAS */\n    dlg->role = PJSIP_ROLE_UAS;\n\n    /* Secure?\n     *  RFC 3261 Section 12.1.1:\n     *  If the request arrived over TLS, and the Request-URI contained a\n     *  SIPS URI, the 'secure' flag is set to TRUE.\n     */\n    dlg->secure = PJSIP_TRANSPORT_IS_SECURE(rdata->tp_info.transport) &&\n\t\t  PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri);\n\n    /* Call-ID */\n    dlg->call_id = (pjsip_cid_hdr*)\n    \t\t   pjsip_hdr_clone(dlg->pool, rdata->msg_info.cid);\n\n    /* Route set.\n     *  RFC 3261 Section 12.1.1:\n     *  The route set MUST be set to the list of URIs in the Record-Route\n     *  header field from the request, taken in order and preserving all URI\n     *  parameters. If no Record-Route header field is present in the request,\n     * the route set MUST be set to the empty set.\n     */\n    pj_list_init(&dlg->route_set);\n    rr = rdata->msg_info.record_route;\n    while (rr != NULL) {\n\tpjsip_route_hdr *route;\n\n\t/* Clone the Record-Route, change the type to Route header. */\n\troute = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, rr);\n\tpjsip_routing_hdr_set_route(route);\n\n\t/* Add to route set. */\n\tpj_list_push_back(&dlg->route_set, route);\n\n\t/* Find next Record-Route header. */\n\trr = rr->next;\n\tif (rr == (void*)&rdata->msg_info.msg->hdr)\n\t    break;\n\trr = (pjsip_route_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,\n\t\t\t\t\t\t   PJSIP_H_RECORD_ROUTE, rr);\n    }\n    dlg->route_set_frozen = PJ_TRUE;\n\n    /* Init client authentication session. */\n    status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt,\n\t\t\t\t dlg->pool, 0);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Increment the dialog's lock since tsx may cause the dialog to be\n     * destroyed prematurely (such as in case of transport error).\n     */\n    if (inc_lock)\n        pjsip_dlg_inc_lock(dlg);\n\n    /* Create UAS transaction for this request. */\n    status = pjsip_tsx_create_uas(dlg->ua, rdata, &tsx);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Associate this dialog to the transaction. */\n    tsx->mod_data[dlg->ua->id] = dlg;\n\n    /* Increment tsx counter */\n    ++dlg->tsx_count;\n\n    /* Calculate hash value of remote tag. */\n    dlg->remote.tag_hval = pj_hash_calc_tolower(0, NULL, &dlg->remote.info->tag);\n\n    /* Update remote capabilities info */\n    pjsip_dlg_update_remote_cap(dlg, rdata->msg_info.msg, PJ_TRUE);\n\n    /* Register this dialog to user agent. */\n    status = pjsip_ua_register_dlg( ua, dlg );\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Put this dialog in rdata's mod_data */\n    rdata->endpt_info.mod_data[ua->id] = dlg;\n\n    PJ_TODO(DIALOG_APP_TIMER);\n\n    /* Feed the first request to the transaction. */\n    pjsip_tsx_recv_msg(tsx, rdata);\n\n    /* Done. */\n    *p_dlg = dlg;\n    PJ_LOG(5,(dlg->obj_name, \"UAS dialog created\"));\n    return PJ_SUCCESS;\n\non_error:\n    if (tsx) {\n\tpjsip_tsx_terminate(tsx, 500);\n\tpj_assert(dlg->tsx_count>0);\n\t--dlg->tsx_count;\n    }\n\n    if (inc_lock) {\n        pjsip_dlg_dec_lock(dlg);\n    } else {\n        destroy_dialog(dlg, PJ_FALSE);\n    }\n    \n    return status;\n}\n\n\n#if !DEPRECATED_FOR_TICKET_1902\n/*\n * Create UAS dialog.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_create_uas(   pjsip_user_agent *ua,\n\t\t\t\t\t    pjsip_rx_data *rdata,\n\t\t\t\t\t    const pj_str_t *contact,\n\t\t\t\t\t    pjsip_dialog **p_dlg)\n{\n    return create_uas_dialog(ua, rdata, contact, PJ_FALSE, p_dlg);\n}\n#endif\n\n\n/*\n * Create UAS dialog and increase its session count.\n */\nPJ_DEF(pj_status_t)\npjsip_dlg_create_uas_and_inc_lock(    pjsip_user_agent *ua,\n\t\t\t\t      pjsip_rx_data *rdata,\n\t\t\t\t      const pj_str_t *contact,\n\t\t\t\t      pjsip_dialog **p_dlg)\n{\n    return create_uas_dialog(ua, rdata, contact, PJ_TRUE, p_dlg);\n}\n\n\n/*\n * Bind dialog to a specific transport/listener.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_set_transport( pjsip_dialog *dlg,\n\t\t\t\t\t     const pjsip_tpselector *sel)\n{\n    /* Validate */\n    PJ_ASSERT_RETURN(dlg && sel, PJ_EINVAL);\n\n    /* Start locking the dialog. */\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Decrement reference counter of previous transport selector */\n    pjsip_tpselector_dec_ref(&dlg->tp_sel);\n\n    /* Copy transport selector structure .*/\n    pj_memcpy(&dlg->tp_sel, sel, sizeof(*sel));\n\n    /* Increment reference counter */\n    pjsip_tpselector_add_ref(&dlg->tp_sel);\n\n    /* Unlock dialog. */\n    pjsip_dlg_dec_lock(dlg);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Set \"sent-by\" field of Via header.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_set_via_sent_by( pjsip_dialog *dlg,\n\t\t\t\t               pjsip_host_port *via_addr,\n                                               pjsip_transport *via_tp)\n{\n    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);\n\n    if (!via_addr)\n        pj_bzero(&dlg->via_addr, sizeof(dlg->via_addr));\n    else {\n        if (pj_strcmp(&dlg->via_addr.host, &via_addr->host))\n            pj_strdup(dlg->pool, &dlg->via_addr.host, &via_addr->host);\n        dlg->via_addr.port = via_addr->port;\n    }\n    dlg->via_tp = via_tp;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create forked dialog from a response.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_fork( const pjsip_dialog *first_dlg,\n\t\t\t\t    const pjsip_rx_data *rdata,\n\t\t\t\t    pjsip_dialog **new_dlg )\n{\n    pjsip_dialog *dlg;\n    const pjsip_msg *msg = rdata->msg_info.msg;\n    const pjsip_hdr *end_hdr, *hdr;\n    const pjsip_contact_hdr *contact;\n    pj_status_t status;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(first_dlg && rdata && new_dlg, PJ_EINVAL);\n\n    /* rdata must be response message. */\n    PJ_ASSERT_RETURN(msg->type == PJSIP_RESPONSE_MSG,\n\t\t     PJSIP_ENOTRESPONSEMSG);\n\n    /* Status code MUST be 1xx (but not 100), or 2xx */\n    status = msg->line.status.code;\n    PJ_ASSERT_RETURN( (status/100==1 && status!=100) ||\n\t\t      (status/100==2), PJ_EBUG);\n\n    /* To tag must present in the response. */\n    PJ_ASSERT_RETURN(rdata->msg_info.to->tag.slen != 0, PJSIP_EMISSINGTAG);\n\n    /* Find Contact header in the response */\n    contact = (const pjsip_contact_hdr*)\n\t      pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL);\n    if (contact == NULL || contact->uri == NULL)\n\treturn PJSIP_EMISSINGHDR;\n\n    /* Create the dialog. */\n    status = create_dialog((pjsip_user_agent*)first_dlg->ua, &dlg);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Set remote target from the response. */\n    dlg->target = (pjsip_uri*) pjsip_uri_clone(dlg->pool, contact->uri);\n\n    /* Clone local info. */\n    dlg->local.info = (pjsip_fromto_hdr*)\n    \t\t      pjsip_hdr_clone(dlg->pool, first_dlg->local.info);\n\n    /* Clone local tag. */\n    pj_strdup(dlg->pool, &dlg->local.info->tag, &first_dlg->local.info->tag);\n    dlg->local.tag_hval = first_dlg->local.tag_hval;\n\n    /* Clone local CSeq. */\n    dlg->local.first_cseq = first_dlg->local.first_cseq;\n    dlg->local.cseq = first_dlg->local.cseq;\n\n    /* Clone local Contact. */\n    dlg->local.contact = (pjsip_contact_hdr*)\n    \t\t\t pjsip_hdr_clone(dlg->pool, first_dlg->local.contact);\n\n    /* Clone remote info. */\n    dlg->remote.info = (pjsip_fromto_hdr*)\n    \t\t       pjsip_hdr_clone(dlg->pool, first_dlg->remote.info);\n\n    /* Set remote tag from the response. */\n    pj_strdup(dlg->pool, &dlg->remote.info->tag, &rdata->msg_info.to->tag);\n\n    /* Initialize remote's CSeq to -1. */\n    dlg->remote.cseq = dlg->remote.first_cseq = -1;\n\n    /* Initial role is UAC. */\n    dlg->role = PJSIP_ROLE_UAC;\n\n    /* Dialog state depends on the response. */\n    status = msg->line.status.code/100;\n    if (status == 1 || status == 2)\n\tdlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;\n    else {\n\tpj_assert(!\"Invalid status code\");\n\tdlg->state = PJSIP_DIALOG_STATE_NULL;\n    }\n\n    /* Secure? */\n    dlg->secure = PJSIP_URI_SCHEME_IS_SIPS(dlg->target);\n\n    /* Clone Call-ID header. */\n    dlg->call_id = (pjsip_cid_hdr*)\n    \t\t   pjsip_hdr_clone(dlg->pool, first_dlg->call_id);\n\n    /* Get route-set from the response. */\n    pj_list_init(&dlg->route_set);\n    end_hdr = &msg->hdr;\n    for (hdr=msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) {\n\tif (hdr->type == PJSIP_H_RECORD_ROUTE) {\n\t    pjsip_route_hdr *r;\n\t    r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, hdr);\n\t    pjsip_routing_hdr_set_route(r);\n\t    pj_list_push_back(&dlg->route_set, r);\n\t}\n    }\n\n    //dlg->route_set_frozen = PJ_TRUE;\n\n    /* Clone client authentication session. */\n    status = pjsip_auth_clt_clone(dlg->pool, &dlg->auth_sess,\n\t\t\t\t  &first_dlg->auth_sess);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Register this dialog to user agent. */\n    status = pjsip_ua_register_dlg(dlg->ua, dlg );\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n\n    /* Done! */\n    *new_dlg = dlg;\n\n    PJ_LOG(5,(dlg->obj_name, \"Forked dialog created\"));\n    return PJ_SUCCESS;\n\non_error:\n    destroy_dialog(dlg, PJ_FALSE);\n    return status;\n}\n\n\n/*\n * Destroy dialog.\n */\nstatic pj_status_t unregister_and_destroy_dialog( pjsip_dialog *dlg,\n\t\t\t\t\t\t  pj_bool_t unlock_mutex )\n{\n    pj_status_t status;\n\n    /* Lock must have been held. */\n\n    /* Check dialog state. */\n    /* Number of sessions must be zero. */\n    PJ_ASSERT_RETURN(dlg->sess_count==0, PJ_EINVALIDOP);\n\n    /* MUST not have pending transactions. */\n    PJ_ASSERT_RETURN(dlg->tsx_count==0, PJ_EINVALIDOP);\n\n    /* Unregister from user agent. */\n    status = pjsip_ua_unregister_dlg(dlg->ua, dlg);\n    if (status != PJ_SUCCESS) {\n\tpj_assert(!\"Unexpected failed unregistration!\");\n\treturn status;\n    }\n\n    /* Log */\n    PJ_LOG(5,(dlg->obj_name, \"Dialog destroyed\"));\n\n    /* Destroy this dialog. */\n    destroy_dialog(dlg, unlock_mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Forcefully terminate dialog.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_terminate( pjsip_dialog *dlg )\n{\n    /* Number of sessions must be zero. */\n    PJ_ASSERT_RETURN(dlg->sess_count==0, PJ_EINVALIDOP);\n\n    /* MUST not have pending transactions. */\n    PJ_ASSERT_RETURN(dlg->tsx_count==0, PJ_EINVALIDOP);\n\n    return unregister_and_destroy_dialog(dlg, PJ_FALSE);\n}\n\n\n/*\n * Set route_set\n */\nPJ_DEF(pj_status_t) pjsip_dlg_set_route_set( pjsip_dialog *dlg,\n\t\t\t\t\t     const pjsip_route_hdr *route_set )\n{\n    pjsip_route_hdr *r;\n\n    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);\n\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Clear route set. */\n    pj_list_init(&dlg->route_set);\n\n    if (!route_set) {\n\tpjsip_dlg_dec_lock(dlg);\n\treturn PJ_SUCCESS;\n    }\n\n    r = route_set->next;\n    while (r != route_set) {\n\tpjsip_route_hdr *new_r;\n\n\tnew_r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, r);\n\tpj_list_push_back(&dlg->route_set, new_r);\n\n\tr = r->next;\n    }\n\n    pjsip_dlg_dec_lock(dlg);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Increment session counter.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg,\n\t\t\t\t\t   pjsip_module *mod )\n{\n    PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL);\n\n    pj_log_push_indent();\n\n    pjsip_dlg_inc_lock(dlg);\n    ++dlg->sess_count;\n    pjsip_dlg_dec_lock(dlg);\n\n    PJ_LOG(5,(dlg->obj_name, \"Session count inc to %d by %.*s\",\n\t      dlg->sess_count, (int)mod->name.slen, mod->name.ptr));\n\n    pj_log_pop_indent();\n    return PJ_SUCCESS;\n}\n\n/*\n * Lock dialog and increment session counter temporarily\n * to prevent it from being deleted. In addition, it must lock\n * the user agent's dialog table first, to prevent deadlock.\n */\nPJ_DEF(void) pjsip_dlg_inc_lock(pjsip_dialog *dlg)\n{\n    PJ_LOG(6,(dlg->obj_name, \"Entering pjsip_dlg_inc_lock(), sess_count=%d\",\n\t      dlg->sess_count));\n\n    pj_mutex_lock(dlg->mutex_);\n    dlg->sess_count++;\n\n    PJ_LOG(6,(dlg->obj_name, \"Leaving pjsip_dlg_inc_lock(), sess_count=%d\",\n\t      dlg->sess_count));\n}\n\n/* Try to acquire dialog's mutex, but bail out if mutex can not be\n * acquired immediately.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_try_inc_lock(pjsip_dialog *dlg)\n{\n    pj_status_t status;\n\n    PJ_LOG(6,(dlg->obj_name,\"Entering pjsip_dlg_try_inc_lock(), sess_count=%d\",\n\t      dlg->sess_count));\n\n    status = pj_mutex_trylock(dlg->mutex_);\n    if (status != PJ_SUCCESS) {\n\tPJ_LOG(6,(dlg->obj_name, \"pjsip_dlg_try_inc_lock() failed\"));\n\treturn status;\n    }\n\n    dlg->sess_count++;\n\n    PJ_LOG(6,(dlg->obj_name, \"Leaving pjsip_dlg_try_inc_lock(), sess_count=%d\",\n\t      dlg->sess_count));\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Unlock dialog and decrement session counter.\n * It may delete the dialog!\n */\nPJ_DEF(void) pjsip_dlg_dec_lock(pjsip_dialog *dlg)\n{\n    PJ_ASSERT_ON_FAIL(dlg!=NULL, return);\n\n    PJ_LOG(6,(dlg->obj_name, \"Entering pjsip_dlg_dec_lock(), sess_count=%d\",\n\t      dlg->sess_count));\n\n    pj_assert(dlg->sess_count > 0);\n    --dlg->sess_count;\n\n    if (dlg->sess_count==0 && dlg->tsx_count==0) {\n\tpj_mutex_unlock(dlg->mutex_);\n\tpj_mutex_lock(dlg->mutex_);\n\t/* We are holding the dialog mutex here, so before we destroy\n\t * the dialog, make sure that we unlock it first to avoid\n\t * undefined behaviour on some platforms. See ticket #1886.\n\t */\n\tunregister_and_destroy_dialog(dlg, PJ_TRUE);\n    } else {\n\tpj_mutex_unlock(dlg->mutex_);\n    }\n\n    PJ_LOG(6,(THIS_FILE, \"Leaving pjsip_dlg_dec_lock() (dlg=%p)\", dlg));\n}\n\n\n\n/*\n * Decrement session counter.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg,\n\t\t\t\t\t   pjsip_module *mod)\n{\n    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);\n\n    pj_log_push_indent();\n\n    PJ_LOG(5,(dlg->obj_name, \"Session count dec to %d by %.*s\",\n\t      dlg->sess_count-1, (int)mod->name.slen, mod->name.ptr));\n\n    pjsip_dlg_inc_lock(dlg);\n    --dlg->sess_count;\n    pjsip_dlg_dec_lock(dlg);\n\n    pj_log_pop_indent();\n    return PJ_SUCCESS;\n}\n\n/*\n * Check if the module is registered as a usage\n */\nPJ_DEF(pj_bool_t) pjsip_dlg_has_usage( pjsip_dialog *dlg,\n\t\t\t\t\t  pjsip_module *mod)\n{\n    unsigned index;\n    pj_bool_t found = PJ_FALSE;\n\n    pjsip_dlg_inc_lock(dlg);\n    for (index=0; index<dlg->usage_cnt; ++index) {\n    \tif (dlg->usage[index] == mod) {\n    \t    found = PJ_TRUE;\n    \t    break;\n    \t}\n    }\n    pjsip_dlg_dec_lock(dlg);\n\n    return found;\n}\n\n/*\n * Add usage.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,\n\t\t\t\t\t pjsip_module *mod,\n\t\t\t\t\t void *mod_data )\n{\n    unsigned index;\n\n    PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL);\n    PJ_ASSERT_RETURN(mod->id >= 0 && mod->id < PJSIP_MAX_MODULE,\n\t\t     PJ_EINVAL);\n    PJ_ASSERT_RETURN(dlg->usage_cnt < PJSIP_MAX_MODULE, PJ_EBUG);\n\n    PJ_LOG(5,(dlg->obj_name,\n\t      \"Module %.*s added as dialog usage, data=%p\",\n\t      (int)mod->name.slen, mod->name.ptr, mod_data));\n\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Usages are sorted on priority, lowest number first.\n     * Find position to put the new module, also makes sure that\n     * this module has not been registered before.\n     */\n    for (index=0; index<dlg->usage_cnt; ++index) {\n\tif (dlg->usage[index] == mod) {\n\t    /* Module may be registered more than once in the same dialog.\n\t     * For example, when call transfer fails, application may retry\n\t     * call transfer on the same dialog.\n\t     * So return PJ_SUCCESS here.\n\t     */\n\t    PJ_LOG(4,(dlg->obj_name,\n\t\t      \"Module %.*s already registered as dialog usage, \"\n\t\t      \"updating the data %p\",\n\t\t      (int)mod->name.slen, mod->name.ptr, mod_data));\n\t    dlg->mod_data[mod->id] = mod_data;\n\n\t    pjsip_dlg_dec_lock(dlg);\n\t    return PJ_SUCCESS;\n\n\t    //pj_assert(!\"This module is already registered\");\n\t    //pjsip_dlg_dec_lock(dlg);\n\t    //return PJSIP_ETYPEEXISTS;\n\t}\n\n\tif (dlg->usage[index]->priority > mod->priority)\n\t    break;\n    }\n\n    /* index holds position to put the module.\n     * Insert module at this index.\n     */\n    pj_array_insert(dlg->usage, sizeof(dlg->usage[0]), dlg->usage_cnt,\n\t\t    index, &mod);\n\n    /* Set module data. */\n    dlg->mod_data[mod->id] = mod_data;\n\n    /* Increment count. */\n    ++dlg->usage_cnt;\n\n    pjsip_dlg_dec_lock(dlg);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Attach module specific data to the dialog. Application can also set\n * the value directly by accessing dlg->mod_data[module_id].\n */\nPJ_DEF(pj_status_t) pjsip_dlg_set_mod_data( pjsip_dialog *dlg,\n\t\t\t\t\t    int mod_id,\n\t\t\t\t\t    void *data )\n{\n    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);\n    PJ_ASSERT_RETURN(mod_id >= 0 && mod_id < PJSIP_MAX_MODULE,\n\t\t     PJ_EINVAL);\n    dlg->mod_data[mod_id] = data;\n    return PJ_SUCCESS;\n}\n\n/**\n * Get module specific data previously attached to the dialog. Application\n * can also get value directly by accessing dlg->mod_data[module_id].\n */\nPJ_DEF(void*) pjsip_dlg_get_mod_data( pjsip_dialog *dlg,\n\t\t\t\t      int mod_id)\n{\n    PJ_ASSERT_RETURN(dlg, NULL);\n    PJ_ASSERT_RETURN(mod_id >= 0 && mod_id < PJSIP_MAX_MODULE,\n\t\t     NULL);\n    return dlg->mod_data[mod_id];\n}\n\n\n/*\n * Create a new request within dialog (i.e. after the dialog session has been\n * established). The construction of such requests follows the rule in\n * RFC3261 section 12.2.1.\n */\nstatic pj_status_t dlg_create_request_throw( pjsip_dialog *dlg,\n\t\t\t\t\t     const pjsip_method *method,\n\t\t\t\t\t     int cseq,\n\t\t\t\t\t     pjsip_tx_data **p_tdata )\n{\n    pjsip_tx_data *tdata;\n    pjsip_contact_hdr *contact;\n    pjsip_route_hdr *route, *end_list;\n    pj_status_t status;\n\n    /* Contact Header field.\n     * Contact can only be present in requests that establish dialog (in the\n     * core SIP spec, only INVITE).\n     */\n    if (pjsip_method_creates_dialog(method))\n\tcontact = dlg->local.contact;\n    else\n\tcontact = NULL;\n\n    /*\n     * Create the request by cloning from the headers in the\n     * dialog.\n     */\n    status = pjsip_endpt_create_request_from_hdr(dlg->endpt,\n\t\t\t\t\t\t method,\n\t\t\t\t\t\t dlg->target,\n\t\t\t\t\t\t dlg->local.info,\n\t\t\t\t\t\t dlg->remote.info,\n\t\t\t\t\t\t contact,\n\t\t\t\t\t\t dlg->call_id,\n\t\t\t\t\t\t cseq,\n\t\t\t\t\t\t NULL,\n\t\t\t\t\t\t &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Just copy dialog route-set to Route header.\n     * The transaction will do the processing as specified in Section 12.2.1\n     * of RFC 3261 in function tsx_process_route() in sip_transaction.c.\n     */\n    route = dlg->route_set.next;\n    end_list = &dlg->route_set;\n    for (; route != end_list; route = route->next ) {\n\tpjsip_route_hdr *r;\n\tr = (pjsip_route_hdr*) pjsip_hdr_shallow_clone( tdata->pool, route );\n\tpjsip_routing_hdr_set_route(r);\n\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)r);\n    }\n\n    /* Copy authorization headers, if request is not ACK or CANCEL. */\n    if (method->id != PJSIP_ACK_METHOD && method->id != PJSIP_CANCEL_METHOD) {\n\tstatus = pjsip_auth_clt_init_req( &dlg->auth_sess, tdata );\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    /* Done. */\n    *p_tdata = tdata;\n\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Create outgoing request.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_create_request( pjsip_dialog *dlg,\n\t\t\t\t\t      const pjsip_method *method,\n\t\t\t\t\t      int cseq,\n\t\t\t\t\t      pjsip_tx_data **p_tdata)\n{\n    pj_status_t status;\n    pjsip_tx_data *tdata = NULL;\n    PJ_USE_EXCEPTION;\n\n    PJ_ASSERT_RETURN(dlg && method && p_tdata, PJ_EINVAL);\n\n    /* Lock dialog. */\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Use outgoing CSeq and increment it by one. */\n    if (cseq < 0)\n\tcseq = dlg->local.cseq + 1;\n\n    /* Keep compiler happy */\n    status = PJ_EBUG;\n\n    /* Create the request. */\n    PJ_TRY {\n\tstatus = dlg_create_request_throw(dlg, method, cseq, &tdata);\n    }\n    PJ_CATCH_ANY {\n\tstatus = PJ_ENOMEM;\n    }\n    PJ_END;\n\n    /* Failed! Delete transmit data. */\n    if (status != PJ_SUCCESS && tdata) {\n\tpjsip_tx_data_dec_ref( tdata );\n\ttdata = NULL;\n    }\n\n    /* Unlock dialog. */\n    pjsip_dlg_dec_lock(dlg);\n\n    *p_tdata = tdata;\n\n    return status;\n}\n\n\n/*\n * Send request statefully, and update dialog'c CSeq.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_send_request( pjsip_dialog *dlg,\n\t\t\t\t\t    pjsip_tx_data *tdata,\n\t\t\t\t\t    int mod_data_id,\n\t\t\t\t\t    void *mod_data)\n{\n    pjsip_transaction *tsx;\n    pjsip_msg *msg = tdata->msg;\n    pj_status_t status;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(dlg && tdata && tdata->msg, PJ_EINVAL);\n    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,\n\t\t     PJSIP_ENOTREQUESTMSG);\n\n    pj_log_push_indent();\n    PJ_LOG(5,(dlg->obj_name, \"Sending %s\",\n\t      pjsip_tx_data_get_info(tdata)));\n\n    /* Lock and increment session */\n    pjsip_dlg_inc_lock(dlg);\n\n    /* If via_addr is set, use this address for the Via header. */\n    if (dlg->via_addr.host.slen > 0) {\n        tdata->via_addr = dlg->via_addr;\n        tdata->via_tp = dlg->via_tp;\n    }\n\n    /* Update dialog's CSeq and message's CSeq if request is not\n     * ACK nor CANCEL.\n     */\n    if (msg->line.req.method.id != PJSIP_CANCEL_METHOD &&\n\tmsg->line.req.method.id != PJSIP_ACK_METHOD)\n    {\n\tpjsip_cseq_hdr *ch;\n\n\tch = PJSIP_MSG_CSEQ_HDR(msg);\n\tPJ_ASSERT_RETURN(ch!=NULL, PJ_EBUG);\n\n\tch->cseq = dlg->local.cseq++;\n\n\t/* Force the whole message to be re-printed. */\n\tpjsip_tx_data_invalidate_msg( tdata );\n    }\n\n    /* Create a new transaction if method is not ACK.\n     * The transaction user is the user agent module.\n     */\n    if (msg->line.req.method.id != PJSIP_ACK_METHOD) {\n\tint tsx_count;\n\n\tstatus = pjsip_tsx_create_uac(dlg->ua, tdata, &tsx);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n\t/* Set transport selector */\n\tstatus = pjsip_tsx_set_transport(tsx, &dlg->tp_sel);\n\tpj_assert(status == PJ_SUCCESS);\n\n\t/* Attach this dialog to the transaction, so that user agent\n\t * will dispatch events to this dialog.\n\t */\n\ttsx->mod_data[dlg->ua->id] = dlg;\n\n\t/* Copy optional caller's mod_data, if present */\n\tif (mod_data_id >= 0 && mod_data_id < PJSIP_MAX_MODULE)\n\t    tsx->mod_data[mod_data_id] = mod_data;\n\n\t/* Increment transaction counter. */\n\ttsx_count = ++dlg->tsx_count;\n\n\t/* Send the message. */\n\tstatus = pjsip_tsx_send_msg(tsx, tdata);\n\tif (status != PJ_SUCCESS) {\n\t    if (dlg->tsx_count == tsx_count)\n\t\tpjsip_tsx_terminate(tsx, tsx->status_code);\n\t    goto on_error;\n\t}\n\n    } else {\n\t/* Set transport selector */\n\tpjsip_tx_data_set_transport(tdata, &dlg->tp_sel);\n\n\t/* Send request */\n\tstatus = pjsip_endpt_send_request_stateless(dlg->endpt, tdata,\n\t\t\t\t\t\t    NULL, NULL);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n    }\n\n    /* Unlock dialog, may destroy dialog. */\n    pjsip_dlg_dec_lock(dlg);\n    pj_log_pop_indent();\n    return PJ_SUCCESS;\n\non_error:\n    /* Unlock dialog, may destroy dialog. */\n    pjsip_dlg_dec_lock(dlg);\n\n    /* Whatever happen delete the message. */\n    pjsip_tx_data_dec_ref( tdata );\n    pj_log_pop_indent();\n    return status;\n}\n\n/* Add standard headers for certain types of response */\nstatic void dlg_beautify_response(pjsip_dialog *dlg,\n\t\t\t\t  pj_bool_t add_headers,\n\t\t\t\t  int st_code,\n\t\t\t\t  pjsip_tx_data *tdata)\n{\n    pjsip_cseq_hdr *cseq;\n    int st_class;\n    const pjsip_hdr *c_hdr;\n    pjsip_hdr *hdr;\n\n    cseq = PJSIP_MSG_CSEQ_HDR(tdata->msg);\n    pj_assert(cseq != NULL);\n\n    st_class = st_code / 100;\n\n    /* Contact, Allow, Supported header. */\n    if (add_headers && pjsip_method_creates_dialog(&cseq->method)) {\n\t/* Add Contact header for 1xx, 2xx, 3xx and 485 response. */\n\tif (st_class==2 || st_class==3 || (st_class==1 && st_code != 100) ||\n\t    st_code==485)\n\t{\n\t    /* Add contact header only if one is not present. */\n\t    if (pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL) == 0 &&\n\t\tpjsip_msg_find_hdr_by_name(tdata->msg, &HCONTACT, NULL) == 0)\n\t    {\n\t\thdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool,\n\t\t\t\t\t\t   dlg->local.contact);\n\t\tpjsip_msg_add_hdr(tdata->msg, hdr);\n\t    }\n\t}\n\n\t/* Add Allow header in 18x, 2xx and 405 response. */\n\tif ((((st_code/10==18 || st_class==2) && dlg->add_allow)\n\t     || st_code==405) &&\n\t    pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ALLOW, NULL)==NULL)\n\t{\n\t    c_hdr = pjsip_endpt_get_capability(dlg->endpt,\n\t\t\t\t\t       PJSIP_H_ALLOW, NULL);\n\t    if (c_hdr) {\n\t\thdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, c_hdr);\n\t\tpjsip_msg_add_hdr(tdata->msg, hdr);\n\t    }\n\t}\n\n\t/* Add Supported header in 2xx response. */\n\tif (st_class==2 &&\n\t    pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL)==NULL)\n\t{\n\t    c_hdr = pjsip_endpt_get_capability(dlg->endpt,\n\t\t\t\t\t       PJSIP_H_SUPPORTED, NULL);\n\t    if (c_hdr) {\n\t\thdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, c_hdr);\n\t\tpjsip_msg_add_hdr(tdata->msg, hdr);\n\t    }\n\t}\n\n    }\n\n    /* Add To tag in all responses except 100 */\n    if (st_code != 100) {\n\tpjsip_to_hdr *to;\n\n\tto = PJSIP_MSG_TO_HDR(tdata->msg);\n\tpj_assert(to != NULL);\n\n\tto->tag = dlg->local.info->tag;\n\n\tif (dlg->state == PJSIP_DIALOG_STATE_NULL)\n\t    dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;\n    }\n}\n\n\n/*\n * Create response.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_create_response(\tpjsip_dialog *dlg,\n\t\t\t\t\t\tpjsip_rx_data *rdata,\n\t\t\t\t\t\tint st_code,\n\t\t\t\t\t\tconst pj_str_t *st_text,\n\t\t\t\t\t\tpjsip_tx_data **p_tdata)\n{\n    pj_status_t status;\n    pjsip_tx_data *tdata;\n\n    /* Create generic response.\n     * This will initialize response's Via, To, From, Call-ID, CSeq\n     * and Record-Route headers from the request.\n     */\n    status = pjsip_endpt_create_response(dlg->endpt,\n\t\t\t\t\t rdata, st_code, st_text, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Lock the dialog. */\n    pjsip_dlg_inc_lock(dlg);\n\n    dlg_beautify_response(dlg, PJ_FALSE, st_code, tdata);\n\n    /* Unlock the dialog. */\n    pjsip_dlg_dec_lock(dlg);\n\n    /* Done. */\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n}\n\n/*\n * Modify response.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_modify_response(\tpjsip_dialog *dlg,\n\t\t\t\t\t\tpjsip_tx_data *tdata,\n\t\t\t\t\t\tint st_code,\n\t\t\t\t\t\tconst pj_str_t *st_text)\n{\n    pjsip_hdr *hdr;\n\n    PJ_ASSERT_RETURN(dlg && tdata && tdata->msg, PJ_EINVAL);\n    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_RESPONSE_MSG,\n\t\t     PJSIP_ENOTRESPONSEMSG);\n    PJ_ASSERT_RETURN(st_code >= 100 && st_code <= 699, PJ_EINVAL);\n\n    /* Lock and increment session */\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Replace status code and reason */\n    tdata->msg->line.status.code = st_code;\n    if (st_text) {\n\tpj_strdup(tdata->pool, &tdata->msg->line.status.reason, st_text);\n    } else {\n\ttdata->msg->line.status.reason = *pjsip_get_status_text(st_code);\n    }\n\n    /* Remove existing Contact header (without this, when dialog sent\n     * 180 and then 302, the Contact in 302 will not get updated).\n     */\n    hdr = (pjsip_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);\n    if (hdr)\n\tpj_list_erase(hdr);\n\n    /* Add tag etc. if necessary */\n    dlg_beautify_response(dlg, st_code/100 <= 2, st_code, tdata);\n\n\n    /* Must add reference counter, since tsx_send_msg() will decrement it */\n    pjsip_tx_data_add_ref(tdata);\n\n    /* Force to re-print message. */\n    pjsip_tx_data_invalidate_msg(tdata);\n\n    /* Unlock dialog and dec session, may destroy dialog. */\n    pjsip_dlg_dec_lock(dlg);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Send response statefully.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_send_response( pjsip_dialog *dlg,\n\t\t\t\t\t     pjsip_transaction *tsx,\n\t\t\t\t\t     pjsip_tx_data *tdata)\n{\n    pj_status_t status;\n\n    /* Sanity check. */\n    PJ_ASSERT_RETURN(dlg && tsx && tdata && tdata->msg, PJ_EINVAL);\n    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_RESPONSE_MSG,\n\t\t     PJSIP_ENOTRESPONSEMSG);\n\n    /* The transaction must belong to this dialog.  */\n    PJ_ASSERT_RETURN(tsx->mod_data[dlg->ua->id] == dlg, PJ_EINVALIDOP);\n\n    pj_log_push_indent();\n\n    PJ_LOG(5,(dlg->obj_name, \"Sending %s\",\n\t      pjsip_tx_data_get_info(tdata)));\n\n    /* Check that transaction method and cseq match the response.\n     * This operation is sloooww (search CSeq header twice), that's why\n     * we only do it in debug mode.\n     */\n#if defined(PJ_DEBUG) && PJ_DEBUG!=0\n    PJ_ASSERT_RETURN( PJSIP_MSG_CSEQ_HDR(tdata->msg)->cseq == tsx->cseq &&\n\t\t      pjsip_method_cmp(&PJSIP_MSG_CSEQ_HDR(tdata->msg)->method,\n\t\t\t\t       &tsx->method)==0,\n\t\t      PJ_EINVALIDOP);\n#endif\n\n    /* Must acquire dialog first, to prevent deadlock */\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Last chance to add mandatory headers before the response is\n     * sent.\n     */\n    dlg_beautify_response(dlg, PJ_TRUE, tdata->msg->line.status.code, tdata);\n\n    /* If the dialog is locked to transport, make sure that transaction\n     * is locked to the same transport too.\n     */\n    if (dlg->tp_sel.type != tsx->tp_sel.type ||\n\tdlg->tp_sel.u.ptr != tsx->tp_sel.u.ptr)\n    {\n\tstatus = pjsip_tsx_set_transport(tsx, &dlg->tp_sel);\n\tpj_assert(status == PJ_SUCCESS);\n    }\n\n    /* Ask transaction to send the response */\n    status = pjsip_tsx_send_msg(tsx, tdata);\n\n    /* This function must decrement transmit data request counter\n     * regardless of the operation status. The transaction only\n     * decrements the counter if the operation is successful.\n     */\n    if (status != PJ_SUCCESS) {\n\tpjsip_tx_data_dec_ref(tdata);\n    }\n\n    pjsip_dlg_dec_lock(dlg);\n    pj_log_pop_indent();\n\n    return status;\n}\n\n\n/*\n * Combo function to create and send response statefully.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_respond(  pjsip_dialog *dlg,\n\t\t\t\t\tpjsip_rx_data *rdata,\n\t\t\t\t\tint st_code,\n\t\t\t\t\tconst pj_str_t *st_text,\n\t\t\t\t\tconst pjsip_hdr *hdr_list,\n\t\t\t\t\tconst pjsip_msg_body *body )\n{\n    pj_status_t status;\n    pjsip_tx_data *tdata;\n\n    /* Sanity check. */\n    PJ_ASSERT_RETURN(dlg && rdata && rdata->msg_info.msg, PJ_EINVAL);\n    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,\n\t\t     PJSIP_ENOTREQUESTMSG);\n\n    /* The transaction must belong to this dialog.  */\n    PJ_ASSERT_RETURN(pjsip_rdata_get_tsx(rdata) &&\n\t\t     pjsip_rdata_get_tsx(rdata)->mod_data[dlg->ua->id] == dlg,\n\t\t     PJ_EINVALIDOP);\n\n    /* Create the response. */\n    status = pjsip_dlg_create_response(dlg, rdata, st_code, st_text, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Add additional header, if any */\n    if (hdr_list) {\n\tconst pjsip_hdr *hdr;\n\n\thdr = hdr_list->next;\n\twhile (hdr != hdr_list) {\n\t    pjsip_msg_add_hdr(tdata->msg,\n\t\t\t      (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hdr));\n\t    hdr = hdr->next;\n\t}\n    }\n\n    /* Add the message body, if any. */\n    if (body) {\n\ttdata->msg->body = pjsip_msg_body_clone( tdata->pool, body);\n    }\n\n    /* Send the response. */\n    return pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), tdata);\n}\n\n\n/* This function is called by user agent upon receiving incoming request\n * message.\n */\nvoid pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata )\n{\n    pj_status_t status;\n    pjsip_transaction *tsx = NULL;\n    pj_bool_t processed = PJ_FALSE;\n    unsigned i;\n\n    PJ_LOG(5,(dlg->obj_name, \"Received %s\",\n\t      pjsip_rx_data_get_info(rdata)));\n    pj_log_push_indent();\n\n    /* Lock dialog and increment session. */\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Check CSeq */\n    if (rdata->msg_info.cseq->cseq <= dlg->remote.cseq &&\n\trdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD &&\n\trdata->msg_info.msg->line.req.method.id != PJSIP_CANCEL_METHOD)\n    {\n\t/* Invalid CSeq.\n\t * Respond statelessly with 500 (Internal Server Error)\n\t */\n\tpj_str_t warn_text;\n\n\t/* Unlock dialog and dec session, may destroy dialog. */\n\tpjsip_dlg_dec_lock(dlg);\n\n\tpj_assert(pjsip_rdata_get_tsx(rdata) == NULL);\n\twarn_text = pj_str(\"Invalid CSeq\");\n\tpjsip_endpt_respond_stateless(dlg->endpt,\n\t\t\t\t      rdata, 500, &warn_text, NULL, NULL);\n\tpj_log_pop_indent();\n\treturn;\n    }\n\n    /* Update CSeq. */\n    dlg->remote.cseq = rdata->msg_info.cseq->cseq;\n\n    /* Update To tag if necessary.\n     * This only happens if UAS sends a new request before answering\n     * our request (e.g. UAS sends NOTIFY before answering our\n     * SUBSCRIBE request).\n     */\n    if (dlg->remote.info->tag.slen == 0) {\n\tpj_strdup(dlg->pool, &dlg->remote.info->tag,\n\t\t  &rdata->msg_info.from->tag);\n    }\n\n    /* Create UAS transaction for this request. */\n    if (pjsip_rdata_get_tsx(rdata) == NULL &&\n\trdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD)\n    {\n\tstatus = pjsip_tsx_create_uas(dlg->ua, rdata, &tsx);\n\tif (status != PJ_SUCCESS) {\n\t    /* Once case for this is when re-INVITE contains same\n\t     * Via branch value as previous INVITE (ticket #965).\n\t     */\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\t    pj_str_t reason;\n\n\t    reason = pj_strerror(status, errmsg, sizeof(errmsg));\n\t    pjsip_endpt_respond_stateless(dlg->endpt, rdata, 500, &reason,\n\t\t\t\t\t  NULL, NULL);\n\t    goto on_return;\n\t}\n\n\t/* Put this dialog in the transaction data. */\n\ttsx->mod_data[dlg->ua->id] = dlg;\n\n\t/* Add transaction count. */\n\t++dlg->tsx_count;\n    }\n\n    /* Update the target URI if this is a target refresh request.\n     * We have passed the basic checking for the request, I think we\n     * should update the target URI regardless of whether the request\n     * is accepted or not (e.g. when re-INVITE is answered with 488,\n     * we would still need to update the target URI, otherwise our\n     * target URI would be wrong, wouldn't it).\n     */\n    if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method)) {\n\tpjsip_contact_hdr *contact;\n\n\tcontact = (pjsip_contact_hdr*)\n\t\t  pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,\n\t\t\t\t     NULL);\n\tif (contact && contact->uri &&\n\t    (dlg->remote.contact==NULL ||\n \t     pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI,\n\t\t\t   dlg->remote.contact->uri,\n\t\t\t   contact->uri)))\n\t{\n\t    dlg->remote.contact = (pjsip_contact_hdr*)\n\t    \t\t\t  pjsip_hdr_clone(dlg->pool, contact);\n\t    dlg->target = dlg->remote.contact->uri;\n\t}\n    }\n\n    /* Report the request to dialog usages. */\n    for (i=0; i<dlg->usage_cnt; ++i) {\n\n\tif (!dlg->usage[i]->on_rx_request)\n\t    continue;\n\n\tprocessed = (*dlg->usage[i]->on_rx_request)(rdata);\n\n\tif (processed)\n\t    break;\n    }\n\n    /* Feed the first request to the transaction. */\n    if (tsx)\n\tpjsip_tsx_recv_msg(tsx, rdata);\n\n    /* If no dialog usages has claimed the processing of the transaction,\n     * and if transaction has not sent final response, respond with\n     * 500/Internal Server Error.\n     */\n    if (!processed && tsx && tsx->status_code < 200) {\n\tpjsip_tx_data *tdata;\n\tconst pj_str_t reason = { \"Unhandled by dialog usages\", 26};\n\n\tPJ_LOG(4,(tsx->obj_name, \"%s was unhandled by \"\n\t\t\t\t \"dialog usages, sending 500 response\",\n\t\t\t\t pjsip_rx_data_get_info(rdata)));\n\n\tstatus = pjsip_dlg_create_response(dlg, rdata, 500, &reason, &tdata);\n\tif (status == PJ_SUCCESS) {\n\t    status = pjsip_dlg_send_response(dlg, tsx, tdata);\n\t}\n    }\n\non_return:\n    /* Unlock dialog and dec session, may destroy dialog. */\n    pjsip_dlg_dec_lock(dlg);\n    pj_log_pop_indent();\n}\n\n/* Update route-set from incoming message */\nstatic void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_rx_data *rdata)\n{\n    const pjsip_hdr *hdr, *end_hdr;\n    //pj_int32_t msg_cseq;\n    const pjsip_msg *msg;\n    const pjsip_method update = { PJSIP_OTHER_METHOD, {\"UPDATE\", 6}};\n\n    msg = rdata->msg_info.msg;\n    //msg_cseq = rdata->msg_info.cseq->cseq;\n\n    /* Ignore if route set has been frozen */\n    if (dlg->route_set_frozen)\n\treturn;\n\n    /* Ignore if the message is an UPDATE response (see ticket #1781) */\n    if (pjsip_method_cmp(&rdata->msg_info.cseq->method, &update) == 0)\n\treturn;\n\n    /* Only update route set if this message belongs to the same\n     * transaction as the initial transaction that establishes dialog.\n     */\n    if (dlg->role == PJSIP_ROLE_UAC) {\n\n\t/* Ignore subsequent request from remote */\n\tif (msg->type != PJSIP_RESPONSE_MSG)\n\t    return;\n\n\t/* Ignore subsequent responses with higher CSeq than initial CSeq.\n\t * Unfortunately this would be broken when the first request is\n\t * challenged!\n\t */\n\t//if (msg_cseq != dlg->local.first_cseq)\n\t//    return;\n\n    } else {\n\n\t/* For callee dialog, route set should have been set by initial\n\t * request and it will have been rejected by dlg->route_set_frozen\n\t * check above.\n\t */\n\tpj_assert(!\"Should not happen\");\n\n    }\n\n    /* Based on the checks above, we should only get response message here */\n    pj_assert(msg->type == PJSIP_RESPONSE_MSG);\n\n    /* Ignore if this is not 1xx or 2xx response */\n    if (msg->line.status.code >= 300)\n\treturn;\n\n    /* Reset route set */\n    pj_list_init(&dlg->route_set);\n\n    /* Update route set */\n    end_hdr = &msg->hdr;\n    for (hdr=msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) {\n\tif (hdr->type == PJSIP_H_RECORD_ROUTE) {\n\t    pjsip_route_hdr *r;\n\t    r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, hdr);\n\t    pjsip_routing_hdr_set_route(r);\n\t    pj_list_push_back(&dlg->route_set, r);\n\t}\n    }\n\n    PJ_LOG(5,(dlg->obj_name, \"Route-set updated\"));\n\n    /* Freeze the route set only when the route set comes in 2xx response.\n     * If it is in 1xx response, prepare to recompute the route set when\n     * the 2xx response comes in.\n     *\n     * There is a debate whether route set should be frozen when the dialog\n     * is established with reliable provisional response, but I think\n     * it is safer to not freeze the route set (thus recompute the route set\n     * upon receiving 2xx response). Also RFC 3261 says so in 13.2.2.4.\n     *\n     * The pjsip_method_creates_dialog() check protects from wrongly\n     * freezing the route set upon receiving 200/OK response for PRACK.\n     */\n    if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&\n\tPJSIP_IS_STATUS_IN_CLASS(msg->line.status.code, 200))\n    {\n\tdlg->route_set_frozen = PJ_TRUE;\n\tPJ_LOG(5,(dlg->obj_name, \"Route-set frozen\"));\n    }\n}\n\n\n/* This function is called by user agent upon receiving incoming response\n * message.\n */\nvoid pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )\n{\n    unsigned i;\n    int res_code;\n\n    PJ_LOG(5,(dlg->obj_name, \"Received %s\",\n\t      pjsip_rx_data_get_info(rdata)));\n    pj_log_push_indent();\n\n    /* Lock the dialog and inc session. */\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Check that rdata already has dialog in mod_data. */\n    pj_assert(pjsip_rdata_get_dlg(rdata) == dlg);\n\n    /* Keep the response's status code */\n    res_code = rdata->msg_info.msg->line.status.code;\n\n    /* When we receive response that establishes dialog, update To tag,\n     * route set and dialog target.\n     *\n     * The second condition of the \"if\" is a workaround for forking.\n     * Originally, the dialog takes the first To tag seen and set it as\n     * the remote tag. If the tag in 2xx response is different than this\n     * tag, ACK will be sent with wrong To tag and incoming request with\n     * this tag will be rejected with 481.\n     *\n     * The workaround for this is to take the To tag received in the\n     * 2xx response and set it as remote tag.\n     *\n     * New update:\n     * We also need to update the dialog for 1xx responses, to handle the\n     * case when 100rel is used, otherwise PRACK will be sent to the\n     * wrong target.\n     */\n    if ((dlg->state == PJSIP_DIALOG_STATE_NULL &&\n\t pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&\n\t (res_code > 100 && res_code < 300) &&\n\t rdata->msg_info.to->tag.slen)\n\t ||\n\t(dlg->role==PJSIP_ROLE_UAC &&\n\t !dlg->uac_has_2xx &&\n\t res_code > 100 &&\n\t res_code/100 <= 2 &&\n\t pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&\n\t pj_stricmp(&dlg->remote.info->tag, &rdata->msg_info.to->tag)))\n    {\n\tpjsip_contact_hdr *contact;\n\n\t/* Update remote capability info, when To tags in the dialog remote\n\t * info and the incoming response are different, e.g: first response\n\t * with To-tag or forking, apply strict update.\n\t */\n\tpjsip_dlg_update_remote_cap(dlg, rdata->msg_info.msg,\n\t\t\t\t    pj_stricmp(&dlg->remote.info->tag,\n\t\t\t\t\t      &rdata->msg_info.to->tag));\n\n\t/* Update To tag. */\n\tpj_strdup(dlg->pool, &dlg->remote.info->tag, &rdata->msg_info.to->tag);\n\t/* No need to update remote's tag_hval since its never used. */\n\n\t/* RFC 3271 Section 12.1.2:\n\t * The route set MUST be set to the list of URIs in the Record-Route\n\t * header field from the response, taken in reverse order and\n\t * preserving all URI parameters. If no Record-Route header field\n\t * is present in the response, the route set MUST be set to the\n\t * empty set. This route set, even if empty, overrides any pre-existing\n\t * route set for future requests in this dialog.\n\t */\n\tdlg_update_routeset(dlg, rdata);\n\n\t/* The remote target MUST be set to the URI from the Contact header\n\t * field of the response.\n\t */\n\tcontact = (pjsip_contact_hdr*)\n\t\t  pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,\n\t\t\t\t     NULL);\n\tif (contact && contact->uri &&\n\t    (dlg->remote.contact==NULL ||\n\t     pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI,\n\t\t\t   dlg->remote.contact->uri,\n\t\t\t   contact->uri)))\n\t{\n\t    dlg->remote.contact = (pjsip_contact_hdr*)\n\t    \t\t\t  pjsip_hdr_clone(dlg->pool, contact);\n\t    dlg->target = dlg->remote.contact->uri;\n\t}\n\n\tdlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;\n\n\t/* Prevent dialog from being updated just in case more 2xx\n\t * gets through this dialog (it shouldn't happen).\n\t */\n\tif (dlg->role==PJSIP_ROLE_UAC && !dlg->uac_has_2xx &&\n\t    res_code/100==2)\n\t{\n\t    dlg->uac_has_2xx = PJ_TRUE;\n\t}\n    }\n\n    /* Update remote target (again) when receiving 2xx response messages\n     * that's defined as target refresh.\n     *\n     * Also upon receiving 2xx response, recheck again the route set.\n     * This is for compatibility with RFC 2543, as described in Section\n     * 13.2.2.4 of RFC 3261:\n\n\tIf the dialog identifier in the 2xx response matches the dialog\n\tidentifier of an existing dialog, the dialog MUST be transitioned to\n\tthe \"confirmed\" state, and the route set for the dialog MUST be\n\trecomputed based on the 2xx response using the procedures of Section\n\t12.2.1.2.\n\n\tNote that the only piece of state that is recomputed is the route\n\tset.  Other pieces of state such as the highest sequence numbers\n\t(remote and local) sent within the dialog are not recomputed.  The\n\troute set only is recomputed for backwards compatibility.  RFC\n\t2543 did not mandate mirroring of the Record-Route header field in\n\ta 1xx, only 2xx.\n     */\n    if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&\n\tres_code/100 == 2)\n    {\n\tpjsip_contact_hdr *contact;\n\n\tcontact = (pjsip_contact_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,\n\t\t\t\t\t\t\t  PJSIP_H_CONTACT,\n\t\t\t\t     \t\t\t  NULL);\n\tif (contact && contact->uri &&\n\t    (dlg->remote.contact==NULL ||\n\t     pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI,\n\t\t\t   dlg->remote.contact->uri,\n\t\t\t   contact->uri)))\n\t{\n\t    dlg->remote.contact = (pjsip_contact_hdr*)\n\t    \t\t\t  pjsip_hdr_clone(dlg->pool, contact);\n\t    dlg->target = dlg->remote.contact->uri;\n\t}\n\n\tdlg_update_routeset(dlg, rdata);\n\n\t/* Update remote capability info after the first 2xx response\n\t * (ticket #1539). Note that the remote capability retrieved here\n\t * will be assumed to remain unchanged for the duration of the dialog.\n\t */\n\tif (dlg->role==PJSIP_ROLE_UAC && !dlg->uac_has_2xx) {\n\t    pjsip_dlg_update_remote_cap(dlg, rdata->msg_info.msg, PJ_FALSE);\n\t    dlg->uac_has_2xx = PJ_TRUE;\n\t}\n    }\n\n    /* Pass to dialog usages. */\n    for (i=0; i<dlg->usage_cnt; ++i) {\n\tpj_bool_t processed;\n\n\tif (!dlg->usage[i]->on_rx_response)\n\t    continue;\n\n\tprocessed = (*dlg->usage[i]->on_rx_response)(rdata);\n\n\tif (processed)\n\t    break;\n    }\n\n    /* Handle the case of forked response, when the application creates\n     * the forked dialog but not the invite session. In this case, the\n     * forked 200/OK response will be unhandled, and we must send ACK\n     * here.\n     */\n    if (dlg->usage_cnt==0) {\n\tpj_status_t status;\n\n\tif (rdata->msg_info.cseq->method.id==PJSIP_INVITE_METHOD &&\n\t    rdata->msg_info.msg->line.status.code/100 == 2)\n\t{\n\t    pjsip_tx_data *ack;\n\n\t    status = pjsip_dlg_create_request(dlg, &pjsip_ack_method,\n\t\t\t\t\t      rdata->msg_info.cseq->cseq,\n\t\t\t\t\t      &ack);\n\t    if (status == PJ_SUCCESS)\n\t\tstatus = pjsip_dlg_send_request(dlg, ack, -1, NULL);\n\t} else if (rdata->msg_info.msg->line.status.code==401 ||\n\t\t   rdata->msg_info.msg->line.status.code==407)\n\t{\n\t    pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);\n\t    pjsip_tx_data *tdata;\n\n\t    status = pjsip_auth_clt_reinit_req( &dlg->auth_sess,\n\t\t\t\t\t\trdata, tsx->last_tx,\n\t\t\t\t\t\t&tdata);\n\n\t    if (status == PJ_SUCCESS) {\n\t\t/* Re-send request. */\n\t\tstatus = pjsip_dlg_send_request(dlg, tdata, -1, NULL);\n\t    }\n\t}\n    }\n\n    /* Unhandled response does not necessarily mean error because\n       dialog usages may choose to process the transaction state instead.\n    if (i==dlg->usage_cnt) {\n\tPJ_LOG(4,(dlg->obj_name, \"%s was not claimed by any dialog usages\",\n\t\t  pjsip_rx_data_get_info(rdata)));\n    }\n    */\n\n    /* Unlock dialog and dec session, may destroy dialog. */\n    pjsip_dlg_dec_lock(dlg);\n\n    pj_log_pop_indent();\n}\n\n/* This function is called by user agent upon receiving transaction\n * state notification.\n */\nvoid pjsip_dlg_on_tsx_state( pjsip_dialog *dlg,\n\t\t\t     pjsip_transaction *tsx,\n\t\t\t     pjsip_event *e )\n{\n    unsigned i;\n\n    PJ_LOG(5,(dlg->obj_name, \"Transaction %s state changed to %s\",\n\t      tsx->obj_name, pjsip_tsx_state_str(tsx->state)));\n    pj_log_push_indent();\n\n    /* Lock the dialog and increment session. */\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Pass to dialog usages. */\n    for (i=0; i<dlg->usage_cnt; ++i) {\n\n\tif (!dlg->usage[i]->on_tsx_state)\n\t    continue;\n\n\t(*dlg->usage[i]->on_tsx_state)(tsx, e);\n    }\n\n\n    /* It is possible that the transaction is terminated and this function\n     * is called while we're calling on_tsx_state(). So only decrement\n     * the tsx_count if we're still attached to the transaction.\n     */\n    if (tsx->state == PJSIP_TSX_STATE_TERMINATED &&\n\ttsx->mod_data[dlg->ua->id] == dlg)\n    {\n\tpj_assert(dlg->tsx_count>0);\n\t--dlg->tsx_count;\n\ttsx->mod_data[dlg->ua->id] = NULL;\n    }\n\n    /* Unlock dialog and dec session, may destroy dialog. */\n    pjsip_dlg_dec_lock(dlg);\n    pj_log_pop_indent();\n}\n\n\n/*\n * Check if the specified capability is supported by remote.\n */\nPJ_DEF(pjsip_dialog_cap_status) pjsip_dlg_remote_has_cap(\n\t\t\t\t\t\t    pjsip_dialog *dlg,\n\t\t\t\t\t\t    int htype,\n\t\t\t\t\t\t    const pj_str_t *hname,\n\t\t\t\t\t\t    const pj_str_t *token)\n{\n    const pjsip_generic_array_hdr *hdr;\n    pjsip_dialog_cap_status cap_status = PJSIP_DIALOG_CAP_UNSUPPORTED;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(dlg && token, PJSIP_DIALOG_CAP_UNKNOWN);\n\n    pjsip_dlg_inc_lock(dlg);\n\n    hdr = (const pjsip_generic_array_hdr*)\n\t   pjsip_dlg_get_remote_cap_hdr(dlg, htype, hname);\n    if (!hdr) {\n\tcap_status = PJSIP_DIALOG_CAP_UNKNOWN;\n    } else {\n\tfor (i=0; i<hdr->count; ++i) {\n\t    if (!pj_stricmp(&hdr->values[i], token)) {\n\t\tcap_status = PJSIP_DIALOG_CAP_SUPPORTED;\n\t\tbreak;\n\t    }\n\t}\n    }\n\n    pjsip_dlg_dec_lock(dlg);\n\n    return cap_status;\n}\n\n\n/*\n * Update remote capability of ACCEPT, ALLOW, and SUPPORTED from\n * the received message.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_update_remote_cap(pjsip_dialog *dlg,\n\t\t\t\t\t        const pjsip_msg *msg,\n\t\t\t\t\t\tpj_bool_t strict)\n{\n    pjsip_hdr_e htypes[] =\n\t{ PJSIP_H_ACCEPT, PJSIP_H_ALLOW, PJSIP_H_SUPPORTED };\n    unsigned i;\n\n    PJ_ASSERT_RETURN(dlg && msg, PJ_EINVAL);\n\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Retrieve all specified capability header types */\n    for (i = 0; i < PJ_ARRAY_SIZE(htypes); ++i) {\n\tconst pjsip_generic_array_hdr *hdr;\n\tpj_status_t status;\n\n\t/* Find this capability type in the message */\n\thdr = (const pjsip_generic_array_hdr*)\n\t      pjsip_msg_find_hdr(msg, htypes[i], NULL);\n\tif (!hdr) {\n\t    /* Not found.\n\t     * If strict update is specified, remote this capability type\n\t     * from the capability list.\n\t     */\n\t    if (strict)\n\t\tpjsip_dlg_remove_remote_cap_hdr(dlg, htypes[i], NULL);\n\t} else {\n\t    /* Found, a capability type may be specified in multiple headers,\n\t     * so combine all the capability tags/values into a temporary\n\t     * header.\n\t     */\n\t    pjsip_generic_array_hdr tmp_hdr;\n\n\t    /* Init temporary header */\n\t    pjsip_generic_array_hdr_init(dlg->pool, &tmp_hdr, NULL);\n\t    pj_memcpy(&tmp_hdr, hdr, sizeof(pjsip_hdr));\n\n\t    while (hdr) {\n\t\tunsigned j;\n\n\t\t/* Append the header content to temporary header */\n\t\tfor(j=0; j<hdr->count &&\n\t\t\t tmp_hdr.count<PJSIP_GENERIC_ARRAY_MAX_COUNT; ++j)\n\t\t{\n\t\t    tmp_hdr.values[tmp_hdr.count++] = hdr->values[j];\n\t\t}\n\n\t\t/* Get the next header for this capability */\n\t\thdr = (const pjsip_generic_array_hdr*)\n\t\t      pjsip_msg_find_hdr(msg, htypes[i], hdr->next);\n\t    }\n\n\t    /* Save this capability */\n\t    status = pjsip_dlg_set_remote_cap_hdr(dlg, &tmp_hdr);\n\t    if (status != PJ_SUCCESS) {\n\t\tpjsip_dlg_dec_lock(dlg);\n\t\treturn status;\n\t    }\n\t}\n    }\n\n    pjsip_dlg_dec_lock(dlg);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the value of the specified capability header field of remote.\n */\nPJ_DEF(const pjsip_hdr*) pjsip_dlg_get_remote_cap_hdr(pjsip_dialog *dlg,\n\t\t\t\t\t\t      int htype,\n\t\t\t\t\t\t      const pj_str_t *hname)\n{\n    pjsip_hdr *hdr;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(dlg, NULL);\n    PJ_ASSERT_RETURN((htype != PJSIP_H_OTHER) || (hname && hname->slen),\n\t\t     NULL);\n\n    pjsip_dlg_inc_lock(dlg);\n\n    hdr = dlg->rem_cap_hdr.next;\n    while (hdr != &dlg->rem_cap_hdr) {\n\tif ((htype != PJSIP_H_OTHER && htype == hdr->type) ||\n\t    (htype == PJSIP_H_OTHER && pj_stricmp(&hdr->name, hname) == 0))\n\t{\n\t    pjsip_dlg_dec_lock(dlg);\n\t    return hdr;\n\t}\n\thdr = hdr->next;\n    }\n\n    pjsip_dlg_dec_lock(dlg);\n\n    return NULL;\n}\n\n\n/*\n * Set remote capability header from a SIP header containing array\n * of capability tags/values.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_set_remote_cap_hdr(\n\t\t\t\t    pjsip_dialog *dlg,\n\t\t\t\t    const pjsip_generic_array_hdr *cap_hdr)\n{\n    pjsip_generic_array_hdr *hdr;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(dlg && cap_hdr, PJ_EINVAL);\n\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Find the header. */\n    hdr = (pjsip_generic_array_hdr*)\n\t  pjsip_dlg_get_remote_cap_hdr(dlg, cap_hdr->type, &cap_hdr->name);\n\n    /* Quick compare if the capability is up to date */\n    if (hdr && hdr->count == cap_hdr->count) {\n\tunsigned i;\n\tpj_bool_t uptodate = PJ_TRUE;\n\n\tfor (i=0; i<hdr->count; ++i) {\n\t    if (pj_stricmp(&hdr->values[i], &cap_hdr->values[i]))\n\t\tuptodate = PJ_FALSE;\n\t}\n\n\t/* Capability is up to date, just return PJ_SUCCESS */\n\tif (uptodate) {\n\t    pjsip_dlg_dec_lock(dlg);\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    /* Remove existing capability header if any */\n    if (hdr)\n\tpj_list_erase(hdr);\n\n    /* Add the new capability header */\n    hdr = (pjsip_generic_array_hdr*) pjsip_hdr_clone(dlg->pool, cap_hdr);\n    hdr->type = cap_hdr->type;\n    pj_strdup(dlg->pool, &hdr->name, &cap_hdr->name);\n    pj_list_push_back(&dlg->rem_cap_hdr, hdr);\n\n    pjsip_dlg_dec_lock(dlg);\n\n    /* Done. */\n    return PJ_SUCCESS;\n}\n\n/*\n * Remove a remote capability header.\n */\nPJ_DEF(pj_status_t) pjsip_dlg_remove_remote_cap_hdr(pjsip_dialog *dlg,\n\t\t\t\t\t\t    int htype,\n\t\t\t\t\t\t    const pj_str_t *hname)\n{\n    pjsip_generic_array_hdr *hdr;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);\n    PJ_ASSERT_RETURN((htype != PJSIP_H_OTHER) || (hname && hname->slen),\n\t\t     PJ_EINVAL);\n\n    pjsip_dlg_inc_lock(dlg);\n\n    hdr = (pjsip_generic_array_hdr*)\n\t  pjsip_dlg_get_remote_cap_hdr(dlg, htype, hname);\n    if (!hdr) {\n\tpjsip_dlg_dec_lock(dlg);\n\treturn PJ_ENOTFOUND;\n    }\n\n    pj_list_erase(hdr);\n\n    pjsip_dlg_dec_lock(dlg);\n\n    return PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_dialog_wrap.cpp",
    "content": "/* $Id: sip_dialog_wrap.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * This file is a C++ wrapper, see ticket #886 for details.\n */\n\n#include \"sip_dialog.c\"\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_endpoint.c",
    "content": "/* $Id: sip_endpoint.c 4529 2013-05-30 08:32:07Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_transaction.h>\n#include <pjsip/sip_private.h>\n#include <pjsip/sip_event.h>\n#include <pjsip/sip_resolve.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_util.h>\n#include <pjsip/sip_errno.h>\n#include <pj/except.h>\n#include <pj/log.h>\n#include <pj/string.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/hash.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n#include <pj/lock.h>\n\n#define PJSIP_EX_NO_MEMORY  pj_NO_MEMORY_EXCEPTION()\n#define THIS_FILE\t    \"sip_endpoint.c\"\n\n#define MAX_METHODS   32\n\n\n/* List of SIP endpoint exit callback. */\ntypedef struct exit_cb\n{\n    PJ_DECL_LIST_MEMBER\t\t    (struct exit_cb);\n    pjsip_endpt_exit_callback\t    func;\n} exit_cb;\n\n\n/**\n * The SIP endpoint.\n */\nstruct pjsip_endpoint\n{\n    /** Pool to allocate memory for the endpoint. */\n    pj_pool_t\t\t*pool;\n\n    /** Mutex for the pool, hash table, and event list/queue. */\n    pj_mutex_t\t\t*mutex;\n\n    /** Pool factory. */\n    pj_pool_factory\t*pf;\n\n    /** Name. */\n    pj_str_t\t\t name;\n\n    /** Timer heap. */\n    pj_timer_heap_t\t*timer_heap;\n\n    /** Transport manager. */\n    pjsip_tpmgr\t\t*transport_mgr;\n\n    /** Ioqueue. */\n    pj_ioqueue_t\t*ioqueue;\n\n    /** Last ioqueue err */\n    pj_status_t\t\t ioq_last_err;\n\n    /** DNS Resolver. */\n    pjsip_resolver_t\t*resolver;\n\n    /** Modules lock. */\n    pj_rwmutex_t\t*mod_mutex;\n\n    /** Modules. */\n    pjsip_module        *modules[PJSIP_MAX_MODULE];\n\n    /** Module list, sorted by priority. */\n    pjsip_module\t module_list;\n\n    /** Capability header list. */\n    pjsip_hdr\t\t cap_hdr;\n\n    /** Additional request headers. */\n    pjsip_hdr\t\t req_hdr;\n\n    /** List of exit callback. */\n    exit_cb\t\t exit_cb_list;\n};\n\n\n#if defined(PJSIP_SAFE_MODULE) && PJSIP_SAFE_MODULE!=0\n#   define LOCK_MODULE_ACCESS(ept)\tpj_rwmutex_lock_read(ept->mod_mutex)\n#   define UNLOCK_MODULE_ACCESS(ept)\tpj_rwmutex_unlock_read(ept->mod_mutex)\n#else\n#   define LOCK_MODULE_ACCESS(endpt)\n#   define UNLOCK_MODULE_ACCESS(endpt)\n#endif\n\n\n\n/*\n * Prototypes.\n */\nstatic void endpt_on_rx_msg( pjsip_endpoint*, \n\t\t\t     pj_status_t, pjsip_rx_data*);\nstatic pj_status_t endpt_on_tx_msg( pjsip_endpoint *endpt,\n\t\t\t\t    pjsip_tx_data *tdata );\nstatic pj_status_t unload_module(pjsip_endpoint *endpt,\n\t\t\t\t pjsip_module *mod);\n\n/* Defined in sip_parser.c */\nvoid init_sip_parser(void);\nvoid deinit_sip_parser(void);\n\n/* Defined in sip_tel_uri.c */\npj_status_t pjsip_tel_uri_subsys_init(void);\n\n\n/*\n * This is the global handler for memory allocation failure, for pools that\n * are created by the endpoint (by default, all pools ARE allocated by \n * endpoint). The error is handled by throwing exception, and hopefully,\n * the exception will be handled by the application (or this library).\n */\nstatic void pool_callback( pj_pool_t *pool, pj_size_t size )\n{\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(size);\n\n    PJ_THROW(PJSIP_EX_NO_MEMORY);\n}\n\n\n/* Compare module name, used for searching module based on name. */\nstatic int cmp_mod_name(void *name, const void *mod)\n{\n    return pj_stricmp((const pj_str_t*)name, &((pjsip_module*)mod)->name);\n}\n\n/*\n * Register new module to the endpoint.\n * The endpoint will then call the load and start function in the module to \n * properly initialize the module, and assign a unique module ID for the \n * module.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_register_module( pjsip_endpoint *endpt,\n\t\t\t\t\t\t pjsip_module *mod )\n{\n    pj_status_t status = PJ_SUCCESS;\n    pjsip_module *m;\n    unsigned i;\n\n    pj_rwmutex_lock_write(endpt->mod_mutex);\n\n    /* Make sure that this module has not been registered. */\n    PJ_ASSERT_ON_FAIL(\tpj_list_find_node(&endpt->module_list, mod) == NULL,\n\t\t\t{status = PJ_EEXISTS; goto on_return;});\n\n    /* Make sure that no module with the same name has been registered. */\n    PJ_ASSERT_ON_FAIL(\tpj_list_search(&endpt->module_list, &mod->name, \n\t\t\t\t       &cmp_mod_name)==NULL,\n\t\t\t{status = PJ_EEXISTS; goto on_return; });\n\n    /* Find unused ID for this module. */\n    for (i=0; i<PJ_ARRAY_SIZE(endpt->modules); ++i) {\n\tif (endpt->modules[i] == NULL)\n\t    break;\n    }\n    if (i == PJ_ARRAY_SIZE(endpt->modules)) {\n\tpj_assert(!\"Too many modules registered!\");\n\tstatus = PJ_ETOOMANY;\n\tgoto on_return;\n    }\n\n    /* Assign the ID. */\n    mod->id = i;\n\n    /* Try to load the module. */\n    if (mod->load) {\n\tstatus = (*mod->load)(endpt);\n\tif (status != PJ_SUCCESS)\n\t    goto on_return;\n    }\n\n    /* Try to start the module. */\n    if (mod->start) {\n\tstatus = (*mod->start)();\n\tif (status != PJ_SUCCESS)\n\t    goto on_return;\n    }\n\n    /* Save the module. */\n    endpt->modules[i] = mod;\n\n    /* Put in the module list, sorted by priority. */\n    m = endpt->module_list.next;\n    while (m != &endpt->module_list) {\n\tif (m->priority > mod->priority)\n\t    break;\n\tm = m->next;\n    }\n    pj_list_insert_before(m, mod);\n\n    /* Done. */\n\n    PJ_LOG(4,(THIS_FILE, \"Module \\\"%.*s\\\" registered\", \n\t      (int)mod->name.slen, mod->name.ptr));\n\non_return:\n    pj_rwmutex_unlock_write(endpt->mod_mutex);\n    return status;\n}\n\n/*\n * Unregister a module from the endpoint.\n * The endpoint will then call the stop and unload function in the module to \n * properly shutdown the module.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_unregister_module( pjsip_endpoint *endpt,\n\t\t\t\t\t\t   pjsip_module *mod )\n{\n    pj_status_t status;\n\n    pj_rwmutex_lock_write(endpt->mod_mutex);\n\n    /* Make sure the module exists in the list. */\n    PJ_ASSERT_ON_FAIL(\tpj_list_find_node(&endpt->module_list, mod) == mod,\n\t\t\t{status = PJ_ENOTFOUND;goto on_return;} );\n\n    /* Make sure the module exists in the array. */\n    PJ_ASSERT_ON_FAIL(\tmod->id>=0 && \n\t\t\tmod->id<(int)PJ_ARRAY_SIZE(endpt->modules) &&\n\t\t\tendpt->modules[mod->id] == mod,\n\t\t\t{status = PJ_ENOTFOUND; goto on_return;});\n\n    /* Try to stop the module. */\n    if (mod->stop) {\n\tstatus = (*mod->stop)();\n\tif (status != PJ_SUCCESS) goto on_return;\n    }\n\n    /* Unload module */\n    status = unload_module(endpt, mod);\n\non_return:\n    pj_rwmutex_unlock_write(endpt->mod_mutex);\n\n    if (status != PJ_SUCCESS) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\n\tpj_strerror(status, errmsg, sizeof(errmsg));\n\tPJ_LOG(3,(THIS_FILE, \"Module \\\"%.*s\\\" can not be unregistered: %s\",\n\t\t  (int)mod->name.slen, mod->name.ptr, errmsg));\n    }\n\n    return status;\n}\n\nstatic pj_status_t unload_module(pjsip_endpoint *endpt,\n\t\t\t\t pjsip_module *mod)\n{\n    pj_status_t status;\n\n    /* Try to unload the module. */\n    if (mod->unload) {\n\tstatus = (*mod->unload)();\n\tif (status != PJ_SUCCESS) \n\t    return status;\n    }\n\n    /* Module MUST NOT set module ID to -1. */\n    pj_assert(mod->id >= 0);\n\n    /* Remove module from array. */\n    endpt->modules[mod->id] = NULL;\n\n    /* Remove module from list. */\n    pj_list_erase(mod);\n\n    /* Set module Id to -1. */\n    mod->id = -1;\n\n    /* Done. */\n    status = PJ_SUCCESS;\n\n    PJ_LOG(4,(THIS_FILE, \"Module \\\"%.*s\\\" unregistered\", \n\t      (int)mod->name.slen, mod->name.ptr));\n\n    return status;\n}\n\n\n/*\n * Get the value of the specified capability header field.\n */\nPJ_DEF(const pjsip_hdr*) pjsip_endpt_get_capability( pjsip_endpoint *endpt,\n\t\t\t\t\t\t     int htype,\n\t\t\t\t\t\t     const pj_str_t *hname)\n{\n    pjsip_hdr *hdr = endpt->cap_hdr.next;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(endpt != NULL, NULL);\n    PJ_ASSERT_RETURN(htype != PJSIP_H_OTHER || hname, NULL);\n\n    if (htype != PJSIP_H_OTHER) {\n\twhile (hdr != &endpt->cap_hdr) {\n\t    if (hdr->type == htype)\n\t\treturn hdr;\n\t    hdr = hdr->next;\n\t}\n    }\n    return NULL;\n}\n\n\n/*\n * Check if the specified capability is supported.\n */\nPJ_DEF(pj_bool_t) pjsip_endpt_has_capability( pjsip_endpoint *endpt,\n\t\t\t\t\t      int htype,\n\t\t\t\t\t      const pj_str_t *hname,\n\t\t\t\t\t      const pj_str_t *token)\n{\n    const pjsip_generic_array_hdr *hdr;\n    unsigned i;\n\n    hdr = (const pjsip_generic_array_hdr*) \n\t   pjsip_endpt_get_capability(endpt, htype, hname);\n    if (!hdr)\n\treturn PJ_FALSE;\n\n    PJ_ASSERT_RETURN(token != NULL, PJ_FALSE);\n\n    for (i=0; i<hdr->count; ++i) {\n\tif (!pj_stricmp(&hdr->values[i], token))\n\t    return PJ_TRUE;\n    }\n\n    return PJ_FALSE;\n}\n\n/*\n * Add or register new capabilities as indicated by the tags to the\n * appropriate header fields in the endpoint.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_add_capability( pjsip_endpoint *endpt,\n\t\t\t\t\t\tpjsip_module *mod,\n\t\t\t\t\t\tint htype,\n\t\t\t\t\t\tconst pj_str_t *hname,\n\t\t\t\t\t\tunsigned count,\n\t\t\t\t\t\tconst pj_str_t tags[])\n{\n    pjsip_generic_array_hdr *hdr;\n    unsigned i;\n\n    PJ_UNUSED_ARG(mod);\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(endpt!=NULL && count>0 && tags, PJ_EINVAL);\n    PJ_ASSERT_RETURN(htype==PJSIP_H_ACCEPT || \n\t\t     htype==PJSIP_H_ALLOW ||\n\t\t     htype==PJSIP_H_SUPPORTED,\n\t\t     PJ_EINVAL);\n\n    /* Find the header. */\n    hdr = (pjsip_generic_array_hdr*) pjsip_endpt_get_capability(endpt, \n\t\t\t\t\t\t\t\thtype, hname);\n\n    /* Create the header when it's not present */\n    if (hdr == NULL) {\n\tswitch (htype) {\n\tcase PJSIP_H_ACCEPT:\n\t    hdr = pjsip_accept_hdr_create(endpt->pool);\n\t    break;\n\tcase PJSIP_H_ALLOW:\n\t    hdr = pjsip_allow_hdr_create(endpt->pool);\n\t    break;\n\tcase PJSIP_H_SUPPORTED:\n\t    hdr = pjsip_supported_hdr_create(endpt->pool);\n\t    break;\n\tdefault:\n\t    return PJ_EINVAL;\n\t}\n\n\tif (hdr) {\n\t    pj_list_push_back(&endpt->cap_hdr, hdr);\n\t}\n    }\n\n    /* Add the tags to the header. */\n    for (i=0; i<count; ++i) {\n\tpj_strdup(endpt->pool, &hdr->values[hdr->count], &tags[i]);\n\t++hdr->count;\n    }\n\n    /* Done. */\n    return PJ_SUCCESS;\n}\n\n/*\n * Get additional headers to be put in outgoing request message.\n */\nPJ_DEF(const pjsip_hdr*) pjsip_endpt_get_request_headers(pjsip_endpoint *endpt)\n{\n    return &endpt->req_hdr;\n}\n\n\n/*\n * Initialize endpoint.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_create(pj_pool_factory *pf,\n\t\t\t\t       const char *name,\n                                       pjsip_endpoint **p_endpt)\n{\n    pj_status_t status;\n    pj_pool_t *pool;\n    pjsip_endpoint *endpt;\n    pjsip_max_fwd_hdr *mf_hdr;\n    pj_lock_t *lock = NULL;\n\n\n    status = pj_register_strerror(PJSIP_ERRNO_START, PJ_ERRNO_SPACE_SIZE,\n\t\t\t\t  &pjsip_strerror);\n    pj_assert(status == PJ_SUCCESS);\n\n    PJ_LOG(5, (THIS_FILE, \"Creating endpoint instance...\"));\n\n    *p_endpt = NULL;\n\n    /* Create pool */\n    pool = pj_pool_create(pf, \"pept%p\", \n\t\t\t  PJSIP_POOL_LEN_ENDPT, PJSIP_POOL_INC_ENDPT,\n\t\t\t  &pool_callback);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    /* Create endpoint. */\n    endpt = PJ_POOL_ZALLOC_T(pool, pjsip_endpoint);\n    endpt->pool = pool;\n    endpt->pf = pf;\n\n    /* Init modules list. */\n    pj_list_init(&endpt->module_list);\n\n    /* Initialize exit callback list. */\n    pj_list_init(&endpt->exit_cb_list);\n\n    /* Create R/W mutex for module manipulation. */\n    status = pj_rwmutex_create(endpt->pool, \"ept%p\", &endpt->mod_mutex);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Init parser. */\n    init_sip_parser();\n\n    /* Init tel: uri */\n    pjsip_tel_uri_subsys_init();\n\n    /* Get name. */\n    if (name != NULL) {\n\tpj_str_t temp;\n\tpj_strdup_with_null(endpt->pool, &endpt->name, pj_cstr(&temp, name));\n    } else {\n\tpj_strdup_with_null(endpt->pool, &endpt->name, pj_gethostname());\n    }\n\n    /* Create mutex for the events, etc. */\n    status = pj_mutex_create_recursive( endpt->pool, \"ept%p\", &endpt->mutex );\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    /* Create timer heap to manage all timers within this endpoint. */\n    status = pj_timer_heap_create( endpt->pool, PJSIP_MAX_TIMER_COUNT, \n                                   &endpt->timer_heap);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    /* Set recursive lock for the timer heap. */\n    status = pj_lock_create_recursive_mutex( endpt->pool, \"edpt%p\", &lock);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n    pj_timer_heap_set_lock(endpt->timer_heap, lock, PJ_TRUE);\n\n    /* Set maximum timed out entries to process in a single poll. */\n    pj_timer_heap_set_max_timed_out_per_poll(endpt->timer_heap, \n\t\t\t\t\t     PJSIP_MAX_TIMED_OUT_ENTRIES);\n\n    /* Create ioqueue. */\n    status = pj_ioqueue_create( endpt->pool, PJSIP_MAX_TRANSPORTS, &endpt->ioqueue);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    /* Create transport manager. */\n    status = pjsip_tpmgr_create( endpt->pool, endpt,\n\t\t\t         &endpt_on_rx_msg,\n\t\t\t\t &endpt_on_tx_msg,\n\t\t\t\t &endpt->transport_mgr);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    /* Create asynchronous DNS resolver. */\n    status = pjsip_resolver_create(endpt->pool, &endpt->resolver);\n    if (status != PJ_SUCCESS) {\n\tPJ_LOG(4, (THIS_FILE, \"Error creating resolver instance\"));\n\tgoto on_error;\n    }\n\n    /* Initialize request headers. */\n    pj_list_init(&endpt->req_hdr);\n\n    /* Add \"Max-Forwards\" for request header. */\n    mf_hdr = pjsip_max_fwd_hdr_create(endpt->pool,\n\t\t\t\t      PJSIP_MAX_FORWARDS_VALUE);\n    pj_list_insert_before( &endpt->req_hdr, mf_hdr);\n\n    /* Initialize capability header list. */\n    pj_list_init(&endpt->cap_hdr);\n\n\n    /* Done. */\n    *p_endpt = endpt;\n    return status;\n\non_error:\n    if (endpt->transport_mgr) {\n\tpjsip_tpmgr_destroy(endpt->transport_mgr);\n\tendpt->transport_mgr = NULL;\n    }\n    if (endpt->ioqueue) {\n\tpj_ioqueue_destroy(endpt->ioqueue);\n\tendpt->ioqueue = NULL;\n    }\n    if (endpt->timer_heap) {\n\tpj_timer_heap_destroy(endpt->timer_heap);\n\tendpt->timer_heap = NULL;\n    }\n    if (endpt->mutex) {\n\tpj_mutex_destroy(endpt->mutex);\n\tendpt->mutex = NULL;\n    }\n    deinit_sip_parser();\n    if (endpt->mod_mutex) {\n\tpj_rwmutex_destroy(endpt->mod_mutex);\n\tendpt->mod_mutex = NULL;\n    }\n    pj_pool_release( endpt->pool );\n\n    PJ_LOG(4, (THIS_FILE, \"Error creating endpoint\"));\n    return status;\n}\n\n/*\n * Destroy endpoint.\n */\nPJ_DEF(void) pjsip_endpt_destroy(pjsip_endpoint *endpt)\n{\n    pjsip_module *mod;\n    exit_cb *ecb;\n\n    PJ_LOG(5, (THIS_FILE, \"Destroying endpoing instance..\"));\n\n    /* Phase 1: stop all modules */\n    mod = endpt->module_list.prev;\n    while (mod != &endpt->module_list) {\n\tpjsip_module *prev = mod->prev;\n\tif (mod->stop) {\n\t    (*mod->stop)();\n\t}\n\tmod = prev;\n    }\n\n    /* Phase 2: unload modules. */\n    mod = endpt->module_list.prev;\n    while (mod != &endpt->module_list) {\n\tpjsip_module *prev = mod->prev;\n\tunload_module(endpt, mod);\n\tmod = prev;\n    }\n\n    /* Destroy resolver */\n    pjsip_resolver_destroy(endpt->resolver);\n\n    /* Shutdown and destroy all transports. */\n    pjsip_tpmgr_destroy(endpt->transport_mgr);\n\n    /* Destroy ioqueue */\n    pj_ioqueue_destroy(endpt->ioqueue);\n\n    /* Destroy timer heap */\n#if PJ_TIMER_DEBUG\n    pj_timer_heap_dump(endpt->timer_heap);\n#endif\n    pj_timer_heap_destroy(endpt->timer_heap);\n\n    /* Call all registered exit callbacks */\n    ecb = endpt->exit_cb_list.next;\n    while (ecb != &endpt->exit_cb_list) {\n\t(*ecb->func)(endpt);\n\tecb = ecb->next;\n    }\n\n    /* Delete endpoint mutex. */\n    pj_mutex_destroy(endpt->mutex);\n\n    /* Deinit parser */\n    deinit_sip_parser();\n\n    /* Delete module's mutex */\n    pj_rwmutex_destroy(endpt->mod_mutex);\n\n    /* Finally destroy pool. */\n    pj_pool_release(endpt->pool);\n\n    PJ_LOG(4, (THIS_FILE, \"Endpoint %p destroyed\", endpt));\n}\n\n/*\n * Get endpoint name.\n */\nPJ_DEF(const pj_str_t*) pjsip_endpt_name(const pjsip_endpoint *endpt)\n{\n    return &endpt->name;\n}\n\n\n/*\n * Create new pool.\n */\nPJ_DEF(pj_pool_t*) pjsip_endpt_create_pool( pjsip_endpoint *endpt,\n\t\t\t\t\t       const char *pool_name,\n\t\t\t\t\t       pj_size_t initial,\n\t\t\t\t\t       pj_size_t increment )\n{\n    pj_pool_t *pool;\n\n    /* Lock endpoint mutex. */\n    /* No need to lock mutex. Factory is thread safe.\n    pj_mutex_lock(endpt->mutex);\n     */\n\n    /* Create pool */\n    pool = pj_pool_create( endpt->pf, pool_name,\n\t\t\t   initial, increment, &pool_callback);\n\n    /* Unlock mutex. */\n    /* No need to lock mutex. Factory is thread safe.\n    pj_mutex_unlock(endpt->mutex);\n     */\n\n    if (!pool) {\n\tPJ_LOG(4, (THIS_FILE, \"Unable to create pool %s!\", pool_name));\n    }\n\n    return pool;\n}\n\n/*\n * Return back pool to endpoint's pool manager to be either destroyed or\n * recycled.\n */\nPJ_DEF(void) pjsip_endpt_release_pool( pjsip_endpoint *endpt, pj_pool_t *pool )\n{\n    PJ_LOG(6, (THIS_FILE, \"Releasing pool %s\", pj_pool_getobjname(pool)));\n\n    /* Don't need to acquire mutex since pool factory is thread safe\n       pj_mutex_lock(endpt->mutex);\n     */\n    pj_pool_release( pool );\n\n    PJ_UNUSED_ARG(endpt);\n    /*\n    pj_mutex_unlock(endpt->mutex);\n     */\n}\n\n\nPJ_DEF(pj_status_t) pjsip_endpt_handle_events2(pjsip_endpoint *endpt,\n\t\t\t\t\t       const pj_time_val *max_timeout,\n\t\t\t\t\t       unsigned *p_count)\n{\n    /* timeout is 'out' var. This just to make compiler happy. */\n    pj_time_val timeout = { 0, 0};\n    unsigned count = 0, net_event_count = 0;\n    int c;\n\n    PJ_LOG(6, (THIS_FILE, \"pjsip_endpt_handle_events()\"));\n\n    /* Poll the timer. The timer heap has its own mutex for better \n     * granularity, so we don't need to lock end endpoint. \n     */\n    timeout.sec = timeout.msec = 0;\n    c = pj_timer_heap_poll( endpt->timer_heap, &timeout );\n    if (c > 0)\n\tcount += c;\n\n    /* timer_heap_poll should never ever returns negative value, or otherwise\n     * ioqueue_poll() will block forever!\n     */\n    pj_assert(timeout.sec >= 0 && timeout.msec >= 0);\n    if (timeout.msec >= 1000) timeout.msec = 999;\n\n    /* If caller specifies maximum time to wait, then compare the value with\n     * the timeout to wait from timer, and use the minimum value.\n     */\n    if (max_timeout && PJ_TIME_VAL_GT(timeout, *max_timeout)) {\n\ttimeout = *max_timeout;\n    }\n\n    /* Poll ioqueue. \n     * Repeat polling the ioqueue while we have immediate events, because\n     * timer heap may process more than one events, so if we only process\n     * one network events at a time (such as when IOCP backend is used),\n     * the ioqueue may have trouble keeping up with the request rate.\n     *\n     * For example, for each send() request, one network event will be\n     *   reported by ioqueue for the send() completion. If we don't poll\n     *   the ioqueue often enough, the send() completion will not be\n     *   reported in timely manner.\n     */\n    do {\n\tc = pj_ioqueue_poll( endpt->ioqueue, &timeout);\n\tif (c < 0) {\n\t    pj_status_t err = pj_get_netos_error();\n\t    pj_thread_sleep(PJ_TIME_VAL_MSEC(timeout));\n\t    if (p_count)\n\t\t*p_count = count;\n\t    return err;\n\t} else if (c == 0) {\n\t    break;\n\t} else {\n\t    net_event_count += c;\n\t    timeout.sec = timeout.msec = 0;\n\t}\n    } while (c > 0 && net_event_count < PJSIP_MAX_NET_EVENTS);\n\n    count += net_event_count;\n    if (p_count)\n\t*p_count = count;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Handle events.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_handle_events(pjsip_endpoint *endpt,\n\t\t\t\t\t      const pj_time_val *max_timeout)\n{\n    return pjsip_endpt_handle_events2(endpt, max_timeout, NULL);\n}\n\n/*\n * Schedule timer.\n */\n#if PJ_TIMER_DEBUG\nPJ_DEF(pj_status_t) pjsip_endpt_schedule_timer_dbg(pjsip_endpoint *endpt,\n\t\t\t\t\t\t    pj_timer_entry *entry,\n\t\t\t\t\t\t    const pj_time_val *delay,\n\t\t\t\t\t\t    const char *src_file,\n\t\t\t\t\t\t    int src_line)\n{\n    PJ_LOG(6, (THIS_FILE, \"pjsip_endpt_schedule_timer(entry=%p, delay=%u.%u)\",\n\t\t\t entry, delay->sec, delay->msec));\n    return pj_timer_heap_schedule_dbg(endpt->timer_heap, entry, delay,\n                                      src_file, src_line);\n}\n#else\nPJ_DEF(pj_status_t) pjsip_endpt_schedule_timer( pjsip_endpoint *endpt,\n\t\t\t\t\t\tpj_timer_entry *entry,\n\t\t\t\t\t\tconst pj_time_val *delay )\n{\n    PJ_LOG(6, (THIS_FILE, \"pjsip_endpt_schedule_timer(entry=%p, delay=%u.%u)\",\n\t\t\t entry, delay->sec, delay->msec));\n    return pj_timer_heap_schedule( endpt->timer_heap, entry, delay );\n}\n#endif\n\n/*\n * Cancel the previously registered timer.\n */\nPJ_DEF(void) pjsip_endpt_cancel_timer( pjsip_endpoint *endpt, \n\t\t\t\t       pj_timer_entry *entry )\n{\n    PJ_LOG(6, (THIS_FILE, \"pjsip_endpt_cancel_timer(entry=%p)\", entry));\n    pj_timer_heap_cancel( endpt->timer_heap, entry );\n}\n\n/*\n * Get the timer heap instance of the SIP endpoint.\n */\nPJ_DEF(pj_timer_heap_t*) pjsip_endpt_get_timer_heap(pjsip_endpoint *endpt)\n{\n    return endpt->timer_heap;\n}\n\n/* Init with default */\nPJ_DEF(void) pjsip_process_rdata_param_default(pjsip_process_rdata_param *p)\n{\n    pj_bzero(p, sizeof(*p));\n}\n\n/* Distribute rdata */\nPJ_DEF(pj_status_t) pjsip_endpt_process_rx_data( pjsip_endpoint *endpt,\n                                                 pjsip_rx_data *rdata,\n                                                 pjsip_process_rdata_param *p,\n                                                 pj_bool_t *p_handled)\n{\n    pjsip_msg *msg;\n    pjsip_process_rdata_param def_prm;\n    pjsip_module *mod;\n    pj_bool_t handled = PJ_FALSE;\n    unsigned i;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(endpt && rdata, PJ_EINVAL);\n\n    if (p==NULL) {\n\tp = &def_prm;\n\tpjsip_process_rdata_param_default(p);\n    }\n\n    msg = rdata->msg_info.msg;\n\n    if (p_handled)\n\t*p_handled = PJ_FALSE;\n\n    if (!p->silent) {\n\tPJ_LOG(5, (THIS_FILE, \"Distributing rdata to modules: %s\",\n\t\t   pjsip_rx_data_get_info(rdata)));\n\tpj_log_push_indent();\n    }\n\n    LOCK_MODULE_ACCESS(endpt);\n\n    /* Find start module */\n    if (p->start_mod) {\n\tmod = (pjsip_module*)\n\t      pj_list_find_node(&endpt->module_list, p->start_mod);\n\tif (!mod) {\n\t    status = PJ_ENOTFOUND;\n\t    goto on_return;\n\t}\n    } else {\n\tmod = endpt->module_list.next;\n    }\n\n    /* Start after the specified index */\n    for (i=0; i < p->idx_after_start && mod != &endpt->module_list; ++i) {\n\tmod = mod->next;\n    }\n\n    /* Start with the specified priority */\n    while (mod != &endpt->module_list && mod->priority < (int)p->start_prio) {\n\tmod = mod->next;\n    }\n\n    if (mod == &endpt->module_list) {\n\tstatus = PJ_ENOTFOUND;\n\tgoto on_return;\n    }\n\n    /* Distribute */\n    if (msg->type == PJSIP_REQUEST_MSG) {\n\tdo {\n\t    if (mod->on_rx_request)\n\t\thandled = (*mod->on_rx_request)(rdata);\n\t    if (handled)\n\t\tbreak;\n\t    mod = mod->next;\n\t} while (mod != &endpt->module_list);\n    } else {\n\tdo {\n\t    if (mod->on_rx_response)\n\t\thandled = (*mod->on_rx_response)(rdata);\n\t    if (handled)\n\t\tbreak;\n\t    mod = mod->next;\n\t} while (mod != &endpt->module_list);\n    }\n\n    status = PJ_SUCCESS;\n\non_return:\n    if (p_handled)\n\t*p_handled = handled;\n\n    UNLOCK_MODULE_ACCESS(endpt);\n    if (!p->silent) {\n\tpj_log_pop_indent();\n    }\n    return status;\n}\n\n/*\n * This is the callback that is called by the transport manager when it \n * receives a message from the network.\n */\nstatic void endpt_on_rx_msg( pjsip_endpoint *endpt,\n\t\t\t     pj_status_t status,\n\t\t\t     pjsip_rx_data *rdata )\n{\n    pjsip_msg *msg = rdata->msg_info.msg;\n    pjsip_process_rdata_param proc_prm;\n    pj_bool_t handled = PJ_FALSE;\n\n    PJ_UNUSED_ARG(msg);\n\n    if (status != PJ_SUCCESS) {\n\tchar info[30];\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\n\tinfo[0] = '\\0';\n\n\tif (status == PJSIP_EMISSINGHDR) {\n\t    pj_str_t p;\n\n\t    p.ptr = info; p.slen = 0;\n\n\t    if (rdata->msg_info.cid == NULL || rdata->msg_info.cid->id.slen)\n\t\tpj_strcpy2(&p, \"Call-ID\");\n\t    if (rdata->msg_info.from == NULL)\n\t\tpj_strcpy2(&p, \" From\");\n\t    if (rdata->msg_info.to == NULL)\n\t\tpj_strcpy2(&p, \" To\");\n\t    if (rdata->msg_info.via == NULL)\n\t\tpj_strcpy2(&p, \" Via\");\n\t    if (rdata->msg_info.cseq == NULL) \n\t\tpj_strcpy2(&p, \" CSeq\");\n\n\t    p.ptr[p.slen] = '\\0';\n\t}\n\n\tpj_strerror(status, errmsg, sizeof(errmsg));\n\n\tPJ_LOG(1, (THIS_FILE, \n\t\t  \"Error processing packet from %s:%d: %s %s [code %d]:\\n\"\n\t\t  \"%.*s\\n\"\n\t\t  \"-- end of packet.\",\n\t\t  rdata->pkt_info.src_name, \n\t\t  rdata->pkt_info.src_port,\n\t\t  errmsg,\n\t\t  info,\n\t\t  status,\n\t\t  (int)rdata->msg_info.len,\t\n\t\t  rdata->msg_info.msg_buf));\n\treturn;\n    }\n\n    PJ_LOG(5, (THIS_FILE, \"Processing incoming message: %s\", \n\t       pjsip_rx_data_get_info(rdata)));\n    pj_log_push_indent();\n\n#if defined(PJSIP_CHECK_VIA_SENT_BY) && PJSIP_CHECK_VIA_SENT_BY != 0\n    /* For response, check that the value in Via sent-by match the transport.\n     * If not matched, silently drop the response.\n     * Ref: RFC3261 Section 18.1.2 Receiving Response\n     */\n    if (msg->type == PJSIP_RESPONSE_MSG) {\n\tconst pj_str_t *local_addr;\n\tint port = rdata->msg_info.via->sent_by.port;\n\tpj_bool_t mismatch = PJ_FALSE;\n\tif (port == 0) {\n\t    pjsip_transport_type_e type;\n\t    type = (pjsip_transport_type_e)rdata->tp_info.transport->key.type;\n\t    port = pjsip_transport_get_default_port_for_type(type);\n\t}\n\tlocal_addr = &rdata->tp_info.transport->local_name.host;\n\n\tif (pj_strcmp(&rdata->msg_info.via->sent_by.host, local_addr) != 0) {\n\n\t    /* The RFC says that we should drop response when sent-by\n\t     * address mismatch. But it could happen (e.g. with SER) when\n\t     * endpoint with private IP is sending request to public\n\t     * server.\n\n\t    mismatch = PJ_TRUE;\n\n\t     */\n\n\t} else if (port != rdata->tp_info.transport->local_name.port) {\n\t    /* Port or address mismatch, we should discard response */\n\t    /* But we saw one implementation (we don't want to name it to \n\t     * protect the innocence) which put wrong sent-by port although\n\t     * the \"rport\" parameter is correct.\n\t     * So we discard the response only if the port doesn't match\n\t     * both the port in sent-by and rport. We try to be lenient here!\n\t     */\n\t    if (rdata->msg_info.via->rport_param != \n\t\trdata->tp_info.transport->local_name.port)\n\t\tmismatch = PJ_TRUE;\n\t    else {\n\t\tPJ_LOG(4,(THIS_FILE, \"Message %s from %s has mismatch port in \"\n\t\t\t\t     \"sent-by but the rport parameter is \"\n\t\t\t\t     \"correct\",\n\t\t\t\t     pjsip_rx_data_get_info(rdata), \n\t\t\t\t     rdata->pkt_info.src_name));\n\t    }\n\t}\n\n\tif (mismatch) {\n\t    PJ_TODO(ENDPT_REPORT_WHEN_DROPPING_MESSAGE);\n\t    PJ_LOG(4,(THIS_FILE, \"Dropping response %s from %s:%d because \"\n\t\t\t\t \"sent-by is mismatch\", \n\t\t\t\t pjsip_rx_data_get_info(rdata),\n\t\t\t\t rdata->pkt_info.src_name, \n\t\t\t\t rdata->pkt_info.src_port));\n\t    pj_log_pop_indent();\n\t    return;\n\t}\n    }\n#endif\n\n    pjsip_process_rdata_param_default(&proc_prm);\n    proc_prm.silent = PJ_TRUE;\n\n    pjsip_endpt_process_rx_data(endpt, rdata, &proc_prm, &handled);\n\n    /* No module is able to handle the message */\n    if (!handled) {\n\tPJ_LOG(4,(THIS_FILE, \"%s from %s:%d was dropped/unhandled by\"\n\t\t\t     \" any modules\",\n\t\t\t     pjsip_rx_data_get_info(rdata),\n\t\t\t     rdata->pkt_info.src_name,\n\t\t\t     rdata->pkt_info.src_port));\n    }\n\n    /* Must clear mod_data before returning rdata to transport, since\n     * rdata may be reused.\n     */\n    pj_bzero(&rdata->endpt_info, sizeof(rdata->endpt_info));\n\n    pj_log_pop_indent();\n}\n\n/*\n * This callback is called by transport manager before message is sent.\n * Modules may inspect the message before it's actually sent.\n */\nstatic pj_status_t endpt_on_tx_msg( pjsip_endpoint *endpt,\n\t\t\t\t    pjsip_tx_data *tdata )\n{\n    pj_status_t status = PJ_SUCCESS;\n    pjsip_module *mod;\n\n    /* Distribute to modules, starting from modules with LOWEST priority */\n    LOCK_MODULE_ACCESS(endpt);\n\n    mod = endpt->module_list.prev;\n    if (tdata->msg->type == PJSIP_REQUEST_MSG) {\n\twhile (mod != &endpt->module_list) {\n\t    if (mod->on_tx_request)\n\t\tstatus = (*mod->on_tx_request)(tdata);\n\t    if (status != PJ_SUCCESS)\n\t\tbreak;\n\t    mod = mod->prev;\n\t}\n\n    } else {\n\twhile (mod != &endpt->module_list) {\n\t    if (mod->on_tx_response)\n\t\tstatus = (*mod->on_tx_response)(tdata);\n\t    if (status != PJ_SUCCESS)\n\t\tbreak;\n\t    mod = mod->prev;\n\t}\n    }\n\n    UNLOCK_MODULE_ACCESS(endpt);\n\n    return status;\n}\n\n\n/*\n * Create transmit data buffer.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_create_tdata(  pjsip_endpoint *endpt,\n\t\t\t\t\t       pjsip_tx_data **p_tdata)\n{\n    return pjsip_tx_data_create(endpt->transport_mgr, p_tdata);\n}\n\n/*\n * Create the DNS resolver instance. \n */\nPJ_DEF(pj_status_t) pjsip_endpt_create_resolver(pjsip_endpoint *endpt,\n\t\t\t\t\t\tpj_dns_resolver **p_resv)\n{\n#if PJSIP_HAS_RESOLVER\n    PJ_ASSERT_RETURN(endpt && p_resv, PJ_EINVAL);\n    return pj_dns_resolver_create( endpt->pf, NULL, 0, endpt->timer_heap,\n\t\t\t\t   endpt->ioqueue, p_resv);\n#else\n    PJ_UNUSED_ARG(endpt);\n    PJ_UNUSED_ARG(p_resv);\n    pj_assert(!\"Resolver is disabled (PJSIP_HAS_RESOLVER==0)\");\n    return PJ_EINVALIDOP;\n#endif\n}\n\n/*\n * Set DNS resolver to be used by the SIP resolver.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_set_resolver( pjsip_endpoint *endpt,\n\t\t\t\t\t      pj_dns_resolver *resv)\n{\n    return pjsip_resolver_set_resolver(endpt->resolver, resv);\n}\n\n/*\n * Set DNS external resolver implementation to be used by the SIP resolver.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_set_ext_resolver(pjsip_endpoint *endpt,\n\t\t\t\t\t\t pjsip_ext_resolver *ext_res)\n{\n    return pjsip_resolver_set_ext_resolver(endpt->resolver, ext_res);\n}\n\n/*\n * Get the DNS resolver being used by the SIP resolver.\n */\nPJ_DEF(pj_dns_resolver*) pjsip_endpt_get_resolver(pjsip_endpoint *endpt)\n{\n    PJ_ASSERT_RETURN(endpt, NULL);\n    return pjsip_resolver_get_resolver(endpt->resolver);\n}\n\n/*\n * Resolve\n */\nPJ_DEF(void) pjsip_endpt_resolve( pjsip_endpoint *endpt,\n\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t  pjsip_host_info *target,\n\t\t\t\t  void *token,\n\t\t\t\t  pjsip_resolver_callback *cb)\n{\n    pjsip_resolve( endpt->resolver, pool, target, token, cb);\n}\n\n/*\n * Get transport manager.\n */\nPJ_DEF(pjsip_tpmgr*) pjsip_endpt_get_tpmgr(pjsip_endpoint *endpt)\n{\n    return endpt->transport_mgr;\n}\n\n/*\n * Get ioqueue instance.\n */\nPJ_DEF(pj_ioqueue_t*) pjsip_endpt_get_ioqueue(pjsip_endpoint *endpt)\n{\n    return endpt->ioqueue;\n}\n\n/*\n * Find/create transport.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_acquire_transport(pjsip_endpoint *endpt,\n\t\t\t\t\t\t  pjsip_transport_type_e type,\n\t\t\t\t\t\t  const pj_sockaddr_t *remote,\n\t\t\t\t\t\t  int addr_len,\n\t\t\t\t\t\t  const pjsip_tpselector *sel,\n\t\t\t\t\t\t  pjsip_transport **transport)\n{\n    return pjsip_tpmgr_acquire_transport(endpt->transport_mgr, type, \n\t\t\t\t\t remote, addr_len, sel, transport);\n}\n\n\n/*\n * Find/create transport.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_acquire_transport2(pjsip_endpoint *endpt,\n\t\t\t\t\t\t   pjsip_transport_type_e type,\n\t\t\t\t\t\t   const pj_sockaddr_t *remote,\n\t\t\t\t\t\t   int addr_len,\n\t\t\t\t\t\t   const pjsip_tpselector *sel,\n\t\t\t\t\t\t   pjsip_tx_data *tdata,\n\t\t\t\t\t\t   pjsip_transport **transport)\n{\n    return pjsip_tpmgr_acquire_transport2(endpt->transport_mgr, type, remote, \n\t\t\t\t\t  addr_len, sel, tdata, transport);\n}\n\n\n/*\n * Report error.\n */\nPJ_DEF(void) pjsip_endpt_log_error(  pjsip_endpoint *endpt,\n\t\t\t\t     const char *sender,\n                                     pj_status_t error_code,\n                                     const char *format,\n                                     ... )\n{\n#if PJ_LOG_MAX_LEVEL > 0\n    char newformat[256];\n    pj_size_t len;\n    va_list marker;\n\n    va_start(marker, format);\n\n    PJ_UNUSED_ARG(endpt);\n\n    len = pj_ansi_strlen(format);\n    if (len < (int)sizeof(newformat)-30) {\n\tpj_str_t errstr;\n\n\tpj_ansi_strcpy(newformat, format);\n\tpj_ansi_snprintf(newformat+len, sizeof(newformat)-len-1,\n\t\t\t \": [err %d] \", error_code);\n\tlen += pj_ansi_strlen(newformat+len);\n\n\terrstr = pj_strerror( error_code, newformat+len, \n\t\t\t      sizeof(newformat)-len-1);\n\n\tlen += errstr.slen;\n\tnewformat[len] = '\\0';\n\n\tpj_log(sender, 1, newformat, marker);\n    } else {\n\tpj_log(sender, 1, format, marker);\n    }\n\n    va_end(marker);\n#else\n    PJ_UNUSED_ARG(format);\n    PJ_UNUSED_ARG(error_code);\n    PJ_UNUSED_ARG(sender);\n    PJ_UNUSED_ARG(endpt);\n#endif\n}\n\n\n/*\n * Dump endpoint.\n */\nPJ_DEF(void) pjsip_endpt_dump( pjsip_endpoint *endpt, pj_bool_t detail )\n{\n#if PJ_LOG_MAX_LEVEL >= 3\n    PJ_LOG(5, (THIS_FILE, \"pjsip_endpt_dump()\"));\n\n    /* Lock mutex. */\n    pj_mutex_lock(endpt->mutex);\n\n    PJ_LOG(3, (THIS_FILE, \"Dumping endpoint %p:\", endpt));\n    \n    /* Dumping pool factory. */\n    pj_pool_factory_dump(endpt->pf, detail);\n\n    /* Pool health. */\n    PJ_LOG(3, (THIS_FILE,\" Endpoint pool capacity=%u, used_size=%u\",\n\t       pj_pool_get_capacity(endpt->pool),\n\t       pj_pool_get_used_size(endpt->pool)));\n\n    /* Resolver */\n#if PJSIP_HAS_RESOLVER\n    if (pjsip_endpt_get_resolver(endpt)) {\n\tpj_dns_resolver_dump(pjsip_endpt_get_resolver(endpt), detail);\n    }\n#endif\n\n    /* Transports. \n     */\n    pjsip_tpmgr_dump_transports( endpt->transport_mgr );\n\n    /* Timer. */\n#if PJ_TIMER_DEBUG\n    pj_timer_heap_dump(endpt->timer_heap);\n#else\n    PJ_LOG(3,(THIS_FILE, \" Timer heap has %u entries\", \n\t\t\tpj_timer_heap_count(endpt->timer_heap)));\n#endif\n\n    /* Unlock mutex. */\n    pj_mutex_unlock(endpt->mutex);\n#else\n    PJ_UNUSED_ARG(endpt);\n    PJ_UNUSED_ARG(detail);\n    PJ_LOG(3,(THIS_FILE, \"pjsip_end_dump: can't dump because it's disabled.\"));\n#endif\n}\n\n\nPJ_DEF(pj_status_t) pjsip_endpt_atexit( pjsip_endpoint *endpt,\n\t\t\t\t\tpjsip_endpt_exit_callback func)\n{\n    exit_cb *new_cb;\n\n    PJ_ASSERT_RETURN(endpt && func, PJ_EINVAL);\n\n    new_cb = PJ_POOL_ZALLOC_T(endpt->pool, exit_cb);\n    new_cb->func = func;\n\n    pj_mutex_lock(endpt->mutex);\n    pj_list_push_back(&endpt->exit_cb_list, new_cb);\n    pj_mutex_unlock(endpt->mutex);\n\n    return PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_endpoint_wrap.cpp",
    "content": "/* $Id: sip_endpoint_wrap.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * This file is a C++ wrapper, see ticket #886 for details.\n */\n\n#include \"sip_endpoint.c\"\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_errno.c",
    "content": "/* $Id: sip_errno.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_msg.h>\n#include <pj/string.h>\n#include <pj/errno.h>\n\n/* PJSIP's own error codes/messages \n * MUST KEEP THIS ARRAY SORTED!!\n */\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n\nstatic const struct \n{\n    int code;\n    const char *msg;\n} err_str[] = \n{\n    /* Generic SIP errors */\n    PJ_BUILD_ERR( PJSIP_EBUSY,\t\t\"Object is busy\" ),\n    PJ_BUILD_ERR( PJSIP_ETYPEEXISTS ,\t\"Object with the same type exists\" ),\n    PJ_BUILD_ERR( PJSIP_ESHUTDOWN,\t\"SIP stack shutting down\" ),\n    PJ_BUILD_ERR( PJSIP_ENOTINITIALIZED,\"SIP object is not initialized.\" ),\n    PJ_BUILD_ERR( PJSIP_ENOROUTESET,\t\"Missing route set (for tel: URI)\" ),\n\n    /* Messaging errors */\n    PJ_BUILD_ERR( PJSIP_EINVALIDMSG,\t\"Invalid message/syntax error\" ),\n    PJ_BUILD_ERR( PJSIP_ENOTREQUESTMSG,\t\"Expecting request message\"),\n    PJ_BUILD_ERR( PJSIP_ENOTRESPONSEMSG,\"Expecting response message\"),\n    PJ_BUILD_ERR( PJSIP_EMSGTOOLONG,\t\"Message too long\" ),\n    PJ_BUILD_ERR( PJSIP_EPARTIALMSG,\t\"Partial message\" ),\n\n    PJ_BUILD_ERR( PJSIP_EINVALIDSTATUS,\t\"Invalid/unexpected SIP status code\"),\n\n    PJ_BUILD_ERR( PJSIP_EINVALIDURI,\t\"Invalid URI\" ),\n    PJ_BUILD_ERR( PJSIP_EINVALIDSCHEME,\t\"Invalid URI scheme\" ),\n    PJ_BUILD_ERR( PJSIP_EMISSINGREQURI,\t\"Missing Request-URI\" ),\n    PJ_BUILD_ERR( PJSIP_EINVALIDREQURI,\t\"Invalid Request URI\" ),\n    PJ_BUILD_ERR( PJSIP_EURITOOLONG,\t\"URI is too long\" ), \n\n    PJ_BUILD_ERR( PJSIP_EMISSINGHDR,\t\"Missing required header(s)\" ),\n    PJ_BUILD_ERR( PJSIP_EINVALIDHDR,\t\"Invalid header field\"),\n    PJ_BUILD_ERR( PJSIP_EINVALIDVIA,\t\"Invalid Via header\" ),\n    PJ_BUILD_ERR( PJSIP_EMULTIPLEVIA,\t\"Multiple Via headers in response\" ),\n\n    PJ_BUILD_ERR( PJSIP_EMISSINGBODY,\t\"Missing message body\" ),\n    PJ_BUILD_ERR( PJSIP_EINVALIDMETHOD,\t\"Invalid/unexpected method\" ),\n\n    /* Transport errors */\n    PJ_BUILD_ERR( PJSIP_EUNSUPTRANSPORT,\"Unsupported transport\"),\n    PJ_BUILD_ERR( PJSIP_EPENDINGTX,\t\"Transmit buffer already pending\"),\n    PJ_BUILD_ERR( PJSIP_ERXOVERFLOW,\t\"Rx buffer overflow\"),\n    PJ_BUILD_ERR( PJSIP_EBUFDESTROYED,\t\"Buffer destroyed\"),\n    PJ_BUILD_ERR( PJSIP_ETPNOTSUITABLE,\t\"Unsuitable transport selected\"),\n    PJ_BUILD_ERR( PJSIP_ETPNOTAVAIL,\t\"Transport not available for use\"),\n\n    /* Transaction errors */\n    PJ_BUILD_ERR( PJSIP_ETSXDESTROYED,\t\"Transaction has been destroyed\"),\n    PJ_BUILD_ERR( PJSIP_ENOTSX,\t\t\"No transaction is associated with the object \"\n\t\t\t\t\t\"(expecting stateful processing)\" ),\n\n    /* URI comparison status */\n    PJ_BUILD_ERR( PJSIP_ECMPSCHEME,\t\"URI scheme mismatch\" ),\n    PJ_BUILD_ERR( PJSIP_ECMPUSER,\t\"URI user part mismatch\" ),\n    PJ_BUILD_ERR( PJSIP_ECMPPASSWD,\t\"URI password part mismatch\" ),\n    PJ_BUILD_ERR( PJSIP_ECMPHOST,\t\"URI host part mismatch\" ),\n    PJ_BUILD_ERR( PJSIP_ECMPPORT,\t\"URI port mismatch\" ),\n    PJ_BUILD_ERR( PJSIP_ECMPTRANSPORTPRM,\"URI transport param mismatch\" ),\n    PJ_BUILD_ERR( PJSIP_ECMPTTLPARAM,\t\"URI ttl param mismatch\" ),\n    PJ_BUILD_ERR( PJSIP_ECMPUSERPARAM,\t\"URI user param mismatch\" ),\n    PJ_BUILD_ERR( PJSIP_ECMPMETHODPARAM,\"URI method param mismatch\" ),\n    PJ_BUILD_ERR( PJSIP_ECMPMADDRPARAM,\t\"URI maddr param mismatch\" ),\n    PJ_BUILD_ERR( PJSIP_ECMPOTHERPARAM,\t\"URI other param mismatch\" ),\n    PJ_BUILD_ERR( PJSIP_ECMPHEADERPARAM,\"URI header parameter mismatch\" ),\n\n    /* Authentication. */\n    PJ_BUILD_ERR( PJSIP_EFAILEDCREDENTIAL, \"Credential failed to authenticate\"),\n    PJ_BUILD_ERR( PJSIP_ENOCREDENTIAL,\t   \"No suitable credential\"),\n    PJ_BUILD_ERR( PJSIP_EINVALIDALGORITHM, \"Invalid/unsupported digest algorithm\" ),\n    PJ_BUILD_ERR( PJSIP_EINVALIDQOP,\t   \"Invalid/unsupported digest qop\" ),\n    PJ_BUILD_ERR( PJSIP_EINVALIDAUTHSCHEME,\"Unsupported authentication scheme\" ),\n    PJ_BUILD_ERR( PJSIP_EAUTHNOPREVCHAL,   \"No previous challenge\" ),\n    PJ_BUILD_ERR( PJSIP_EAUTHNOAUTH,\t   \"No suitable authorization header\" ),\n    PJ_BUILD_ERR( PJSIP_EAUTHACCNOTFOUND,  \"Account or credential not found\" ),\n    PJ_BUILD_ERR( PJSIP_EAUTHACCDISABLED,  \"Account or credential is disabled\" ),\n    PJ_BUILD_ERR( PJSIP_EAUTHINVALIDREALM, \"Invalid authorization realm\"),\n    PJ_BUILD_ERR( PJSIP_EAUTHINVALIDDIGEST,\"Invalid authorization digest\" ),\n    PJ_BUILD_ERR( PJSIP_EAUTHSTALECOUNT,   \"Maximum number of stale retries exceeded\"),\n    PJ_BUILD_ERR( PJSIP_EAUTHINNONCE,\t   \"Invalid nonce value in authentication challenge\"),\n    PJ_BUILD_ERR( PJSIP_EAUTHINAKACRED,\t   \"Invalid AKA credential\"),\n    PJ_BUILD_ERR( PJSIP_EAUTHNOCHAL,\t   \"No challenge is found\"),\n\n    /* UA/dialog layer. */\n    PJ_BUILD_ERR( PJSIP_EMISSINGTAG,\t\"Missing From/To tag parameter\" ),\n    PJ_BUILD_ERR( PJSIP_ENOTREFER,\t\"Expecting REFER request\") ,\n    PJ_BUILD_ERR( PJSIP_ENOREFERSESSION,\"Not associated with REFER subscription\"),\n\n    /* Invite session. */\n    PJ_BUILD_ERR( PJSIP_ESESSIONTERMINATED, \"INVITE session already terminated\" ),\n    PJ_BUILD_ERR( PJSIP_ESESSIONSTATE,      \"Invalid INVITE session state\" ),\n    PJ_BUILD_ERR( PJSIP_ESESSIONINSECURE,   \"Require secure session/transport\"),\n\n    /* SSL errors */\n    PJ_BUILD_ERR( PJSIP_TLS_EUNKNOWN,\t\"Unknown TLS error\" ),\n    PJ_BUILD_ERR( PJSIP_TLS_EINVMETHOD,\t\"Invalid SSL protocol method\" ),\n    PJ_BUILD_ERR( PJSIP_TLS_ECACERT,\t\"Error loading/verifying SSL CA list file\"),\n    PJ_BUILD_ERR( PJSIP_TLS_ECERTFILE,\t\"Error loading SSL certificate chain file\"),\n    PJ_BUILD_ERR( PJSIP_TLS_EKEYFILE,\t\"Error adding private key from SSL certificate file\"),\n    PJ_BUILD_ERR( PJSIP_TLS_ECIPHER,\t\"Error setting SSL cipher list\"),\n    PJ_BUILD_ERR( PJSIP_TLS_ECTX,\t\"Error creating SSL context\"),\n    PJ_BUILD_ERR( PJSIP_TLS_ESSLCONN,\t\"Error creating SSL connection object\"),\n    PJ_BUILD_ERR( PJSIP_TLS_ECONNECT,\t\"Unknown error when performing SSL connect()\"),\n    PJ_BUILD_ERR( PJSIP_TLS_EACCEPT,\t\"Unknown error when performing SSL accept()\"),\n    PJ_BUILD_ERR( PJSIP_TLS_ESEND,\t\"Unknown error when sending SSL data\"),\n    PJ_BUILD_ERR( PJSIP_TLS_EREAD,\t\"Unknown error when reading SSL data\"),\n    PJ_BUILD_ERR( PJSIP_TLS_ETIMEDOUT,\t\"SSL negotiation has timed out\"),\n    PJ_BUILD_ERR( PJSIP_TLS_ECERTVERIF,\t\"SSL certificate verification error\"),\n};\n\n\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n\n/*\n * pjsip_strerror()\n */\nPJ_DEF(pj_str_t) pjsip_strerror( pj_status_t statcode, \n\t\t\t\t char *buf, pj_size_t bufsize )\n{\n    pj_str_t errstr;\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n\n    if (statcode >= PJSIP_ERRNO_START && statcode < PJSIP_ERRNO_START+800) \n    {\n\t/* Status code. */\n\tconst pj_str_t *status_text = \n\t    pjsip_get_status_text(PJSIP_ERRNO_TO_SIP_STATUS(statcode));\n\n\terrstr.ptr = buf;\n\tpj_strncpy_with_null(&errstr, status_text, bufsize);\n\treturn errstr;\n    }\n    else if (statcode >= PJSIP_ERRNO_START_PJSIP && \n\t     statcode < PJSIP_ERRNO_START_PJSIP + 1000)\n    {\n\t/* Find the error in the table.\n\t * Use binary search!\n\t */\n\tint first = 0;\n\tint n = PJ_ARRAY_SIZE(err_str);\n\n\twhile (n > 0) {\n\t    int half = n/2;\n\t    int mid = first + half;\n\n\t    if (err_str[mid].code < statcode) {\n\t\tfirst = mid+1;\n\t\tn -= (half+1);\n\t    } else if (err_str[mid].code > statcode) {\n\t\tn = half;\n\t    } else {\n\t\tfirst = mid;\n\t\tbreak;\n\t    }\n\t}\n\n\n\tif (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {\n\t    pj_str_t msg;\n\t    \n\t    msg.ptr = (char*)err_str[first].msg;\n\t    msg.slen = pj_ansi_strlen(err_str[first].msg);\n\n\t    errstr.ptr = buf;\n\t    pj_strncpy_with_null(&errstr, &msg, bufsize);\n\t    return errstr;\n\n\t} \n    }\n\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n    /* Error not found. */\n    errstr.ptr = buf;\n    errstr.slen = pj_ansi_snprintf(buf, bufsize, \n\t\t\t\t   \"Unknown pjsip error %d\",\n\t\t\t\t   statcode);\n    if (errstr.slen < 1 || errstr.slen >= (pj_ssize_t)bufsize)\n\terrstr.slen = bufsize - 1;\n    return errstr;\n\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_msg.c",
    "content": "/* $Id: sip_msg.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_msg.h>\n#include <pjsip/sip_parser.h>\n#include <pjsip/print_util.h>\n#include <pjsip/sip_errno.h>\n#include <pj/ctype.h>\n#include <pj/guid.h>\n#include <pj/string.h>\n#include <pj/pool.h>\n#include <pj/assert.h>\n#include <pjlib-util/string.h>\n\nPJ_DEF_DATA(const pjsip_method) pjsip_invite_method =\n\t{ PJSIP_INVITE_METHOD, { \"INVITE\",6 }};\n\nPJ_DEF_DATA(const pjsip_method) pjsip_cancel_method =\n\t{ PJSIP_CANCEL_METHOD, { \"CANCEL\",6 }};\n\nPJ_DEF_DATA(const pjsip_method) pjsip_ack_method =\n\t{ PJSIP_ACK_METHOD, { \"ACK\",3}};\n\nPJ_DEF_DATA(const pjsip_method) pjsip_bye_method =\n\t{ PJSIP_BYE_METHOD, { \"BYE\",3}};\n\nPJ_DEF_DATA(const pjsip_method) pjsip_register_method =\n\t{ PJSIP_REGISTER_METHOD, { \"REGISTER\", 8}};\n\nPJ_DEF_DATA(const pjsip_method) pjsip_options_method =\n\t{ PJSIP_OPTIONS_METHOD, { \"OPTIONS\",7}};\n\n\n/** INVITE method constant. */\nPJ_DEF(const pjsip_method*) pjsip_get_invite_method(void)\n{\n    return &pjsip_invite_method;\n}\n\n/** CANCEL method constant. */\nPJ_DEF(const pjsip_method*) pjsip_get_cancel_method(void)\n{\n    return &pjsip_cancel_method;\n}\n\n/** ACK method constant. */\nPJ_DEF(const pjsip_method*) pjsip_get_ack_method(void)\n{\n    return &pjsip_ack_method;\n}\n\n/** BYE method constant. */\nPJ_DEF(const pjsip_method*) pjsip_get_bye_method(void)\n{\n    return &pjsip_bye_method;\n}\n\n/** REGISTER method constant.*/\nPJ_DEF(const pjsip_method*) pjsip_get_register_method(void)\n{\n    return &pjsip_register_method;\n}\n\n/** OPTIONS method constant. */\nPJ_DEF(const pjsip_method*) pjsip_get_options_method(void)\n{\n    return &pjsip_options_method;\n}\n\n\nstatic const pj_str_t *method_names[] = \n{\n    &pjsip_invite_method.name,\n    &pjsip_cancel_method.name,\n    &pjsip_ack_method.name,\n    &pjsip_bye_method.name,\n    &pjsip_register_method.name,\n    &pjsip_options_method.name\n};\n\nconst pjsip_hdr_name_info_t pjsip_hdr_names[] = \n{\n    { \"Accept\",\t\t    6,  NULL },   // PJSIP_H_ACCEPT,\n    { \"Accept-Encoding\",    15, NULL },   // PJSIP_H_ACCEPT_ENCODING,\n    { \"Accept-Language\",    15, NULL },   // PJSIP_H_ACCEPT_LANGUAGE,\n    { \"Alert-Info\",\t    10, NULL },   // PJSIP_H_ALERT_INFO,\n    { \"Allow\",\t\t    5,  NULL },   // PJSIP_H_ALLOW,\n    { \"Authentication-Info\",19, NULL },   // PJSIP_H_AUTHENTICATION_INFO,\n    { \"Authorization\",\t    13, NULL },   // PJSIP_H_AUTHORIZATION,\n    { \"Call-ID\",\t    7,  \"i\" },    // PJSIP_H_CALL_ID,\n    { \"Call-Info\",\t    9,  NULL },   // PJSIP_H_CALL_INFO,\n    { \"Contact\",\t    7,  \"m\" },    // PJSIP_H_CONTACT,\n    { \"Content-Disposition\",19, NULL },   // PJSIP_H_CONTENT_DISPOSITION,\n    { \"Content-Encoding\",   16, \"e\" },    // PJSIP_H_CONTENT_ENCODING,\n    { \"Content-Language\",   16, NULL },   // PJSIP_H_CONTENT_LANGUAGE,\n    { \"Content-Length\",\t    14, \"l\" },    // PJSIP_H_CONTENT_LENGTH,\n    { \"Content-Type\",\t    12, \"c\" },    // PJSIP_H_CONTENT_TYPE,\n    { \"CSeq\",\t\t     4, NULL },   // PJSIP_H_CSEQ,\n    { \"Date\",\t\t     4, NULL },   // PJSIP_H_DATE,\n    { \"Error-Info\",\t    10, NULL },   // PJSIP_H_ERROR_INFO,\n    { \"Expires\",\t     7, NULL },   // PJSIP_H_EXPIRES,\n    { \"From\",\t\t     4, \"f\" },    // PJSIP_H_FROM,\n    { \"In-Reply-To\",\t    11, NULL },   // PJSIP_H_IN_REPLY_TO,\n    { \"Max-Forwards\",\t    12, NULL },   // PJSIP_H_MAX_FORWARDS,\n    { \"MIME-Version\",\t    12, NULL },   // PJSIP_H_MIME_VERSION,\n    { \"Min-Expires\",\t    11, NULL },   // PJSIP_H_MIN_EXPIRES,\n    { \"Organization\",\t    12, NULL },   // PJSIP_H_ORGANIZATION,\n    { \"Priority\",\t     8, NULL },   // PJSIP_H_PRIORITY,\n    { \"Proxy-Authenticate\", 18, NULL },   // PJSIP_H_PROXY_AUTHENTICATE,\n    { \"Proxy-Authorization\",19, NULL },   // PJSIP_H_PROXY_AUTHORIZATION,\n    { \"Proxy-Require\",\t    13, NULL },   // PJSIP_H_PROXY_REQUIRE,\n    { \"Record-Route\",\t    12, NULL },   // PJSIP_H_RECORD_ROUTE,\n    { \"Reply-To\",\t     8, NULL },   // PJSIP_H_REPLY_TO,\n    { \"Require\",\t     7, NULL },   // PJSIP_H_REQUIRE,\n    { \"Retry-After\",\t    11, NULL },   // PJSIP_H_RETRY_AFTER,\n    { \"Route\",\t\t     5, NULL },   // PJSIP_H_ROUTE,\n    { \"Server\",\t\t     6, NULL },   // PJSIP_H_SERVER,\n    { \"Subject\",\t     7, \"s\" },    // PJSIP_H_SUBJECT,\n    { \"Supported\",\t     9, \"k\" },    // PJSIP_H_SUPPORTED,\n    { \"Timestamp\",\t     9, NULL },   // PJSIP_H_TIMESTAMP,\n    { \"To\",\t\t     2, \"t\" },    // PJSIP_H_TO,\n    { \"Unsupported\",\t    11, NULL },   // PJSIP_H_UNSUPPORTED,\n    { \"User-Agent\",\t    10, NULL },   // PJSIP_H_USER_AGENT,\n    { \"Via\",\t\t     3, \"v\" },    // PJSIP_H_VIA,\n    { \"Warning\",\t     7, NULL },   // PJSIP_H_WARNING,\n    { \"WWW-Authenticate\",   16, NULL },   // PJSIP_H_WWW_AUTHENTICATE,\n\n    { \"_Unknown-Header\",    15, NULL },   // PJSIP_H_OTHER,\n};\n\npj_bool_t pjsip_use_compact_form = PJSIP_ENCODE_SHORT_HNAME;\n\nstatic pj_str_t status_phrase[710];\nstatic int print_media_type(char *buf, unsigned len,\n\t\t\t    const pjsip_media_type *media);\n\nstatic int init_status_phrase()\n{\n    unsigned i;\n    pj_str_t default_reason_phrase = { \"Default status message\", 22};\n\n    for (i=0; i<PJ_ARRAY_SIZE(status_phrase); ++i)\n\tstatus_phrase[i] = default_reason_phrase;\n\n    pj_strset2( &status_phrase[100], \"Trying\");\n    pj_strset2( &status_phrase[180], \"Ringing\");\n    pj_strset2( &status_phrase[181], \"Call Is Being Forwarded\");\n    pj_strset2( &status_phrase[182], \"Queued\");\n    pj_strset2( &status_phrase[183], \"Session Progress\");\n\n    pj_strset2( &status_phrase[200], \"OK\");\n    pj_strset2( &status_phrase[202], \"Accepted\");\n\n    pj_strset2( &status_phrase[300], \"Multiple Choices\");\n    pj_strset2( &status_phrase[301], \"Moved Permanently\");\n    pj_strset2( &status_phrase[302], \"Moved Temporarily\");\n    pj_strset2( &status_phrase[305], \"Use Proxy\");\n    pj_strset2( &status_phrase[380], \"Alternative Service\");\n\n    pj_strset2( &status_phrase[400], \"Bad Request\");\n    pj_strset2( &status_phrase[401], \"Unauthorized\");\n    pj_strset2( &status_phrase[402], \"Payment Required\");\n    pj_strset2( &status_phrase[403], \"Forbidden\");\n    pj_strset2( &status_phrase[404], \"Not Found\");\n    pj_strset2( &status_phrase[405], \"Method Not Allowed\");\n    pj_strset2( &status_phrase[406], \"Not Acceptable\");\n    pj_strset2( &status_phrase[407], \"Proxy Authentication Required\");\n    pj_strset2( &status_phrase[408], \"Request Timeout\");\n    pj_strset2( &status_phrase[410], \"Gone\");\n    pj_strset2( &status_phrase[413], \"Request Entity Too Large\");\n    pj_strset2( &status_phrase[414], \"Request URI Too Long\");\n    pj_strset2( &status_phrase[415], \"Unsupported Media Type\");\n    pj_strset2( &status_phrase[416], \"Unsupported URI Scheme\");\n    pj_strset2( &status_phrase[420], \"Bad Extension\");\n    pj_strset2( &status_phrase[421], \"Extension Required\");\n    pj_strset2( &status_phrase[422], \"Session Timer Too Small\");\n    pj_strset2( &status_phrase[423], \"Interval Too Brief\");\n    pj_strset2( &status_phrase[480], \"Temporarily Unavailable\");\n    pj_strset2( &status_phrase[481], \"Call/Transaction Does Not Exist\");\n    pj_strset2( &status_phrase[482], \"Loop Detected\");\n    pj_strset2( &status_phrase[483], \"Too Many Hops\");\n    pj_strset2( &status_phrase[484], \"Address Incomplete\");\n    pj_strset2( &status_phrase[485], \"Ambiguous\");\n    pj_strset2( &status_phrase[486], \"Busy Here\");\n    pj_strset2( &status_phrase[487], \"Request Terminated\");\n    pj_strset2( &status_phrase[488], \"Not Acceptable Here\");\n    pj_strset2( &status_phrase[489], \"Bad Event\");\n    pj_strset2( &status_phrase[490], \"Request Updated\");\n    pj_strset2( &status_phrase[491], \"Request Pending\");\n    pj_strset2( &status_phrase[493], \"Undecipherable\");\n\n    pj_strset2( &status_phrase[500], \"Internal Server Error\");\n    pj_strset2( &status_phrase[501], \"Not Implemented\");\n    pj_strset2( &status_phrase[502], \"Bad Gateway\");\n    pj_strset2( &status_phrase[503], \"Service Unavailable\");\n    pj_strset2( &status_phrase[504], \"Server Timeout\");\n    pj_strset2( &status_phrase[505], \"Version Not Supported\");\n    pj_strset2( &status_phrase[513], \"Message Too Large\");\n    pj_strset2( &status_phrase[580], \"Precondition Failure\");\n\n    pj_strset2( &status_phrase[600], \"Busy Everywhere\");\n    pj_strset2( &status_phrase[603], \"Decline\");\n    pj_strset2( &status_phrase[604], \"Does Not Exist Anywhere\");\n    pj_strset2( &status_phrase[606], \"Not Acceptable\");\n\n    pj_strset2( &status_phrase[701], \"No response from destination server\");\n    pj_strset2( &status_phrase[702], \"Unable to resolve destination server\");\n    pj_strset2( &status_phrase[703], \"Error sending message to destination server\");\n\n    return 1;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Method.\n */\n\nPJ_DEF(void) pjsip_method_init( pjsip_method *m, \n\t\t\t        pj_pool_t *pool, \n\t\t\t        const pj_str_t *str)\n{\n    pj_str_t dup;\n    pjsip_method_init_np(m, pj_strdup(pool, &dup, str));\n}\n\nPJ_DEF(void) pjsip_method_set( pjsip_method *m, pjsip_method_e me )\n{\n    pj_assert(me < PJSIP_OTHER_METHOD);\n    m->id = me;\n    m->name = *method_names[me];\n}\n\nPJ_DEF(void) pjsip_method_init_np(pjsip_method *m,\n\t\t\t\t  pj_str_t *str)\n{\n    unsigned i;\n    for (i=0; i<PJ_ARRAY_SIZE(method_names); ++i) {\n\tif (pj_memcmp(str->ptr, method_names[i]->ptr, str->slen)==0 || \n\t    pj_stricmp(str, method_names[i])==0) \n\t{\n\t    m->id = (pjsip_method_e)i;\n\t    m->name = *method_names[i];\n\t    return;\n\t}\n    }\n    m->id = PJSIP_OTHER_METHOD;\n    m->name = *str;\n}\n\nPJ_DEF(void) pjsip_method_copy( pj_pool_t *pool,\n\t\t\t\tpjsip_method *method,\n\t\t\t\tconst pjsip_method *rhs )\n{\n    method->id = rhs->id;\n    if (rhs->id != PJSIP_OTHER_METHOD) {\n\tmethod->name = rhs->name;\n    } else {\n\tpj_strdup(pool, &method->name, &rhs->name);\n    }\n}\n\n\nPJ_DEF(int) pjsip_method_cmp( const pjsip_method *m1, const pjsip_method *m2)\n{\n    if (m1->id == m2->id) {\n\tif (m1->id != PJSIP_OTHER_METHOD)\n\t    return 0;\n\t/* Method comparison is case sensitive! */\n\treturn pj_strcmp(&m1->name, &m2->name);\n    }\n    \n    return ( m1->id < m2->id ) ? -1 : 1;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Message.\n */\n\nPJ_DEF(pjsip_msg*) pjsip_msg_create( pj_pool_t *pool, pjsip_msg_type_e type)\n{\n    pjsip_msg *msg = PJ_POOL_ALLOC_T(pool, pjsip_msg);\n    pj_list_init(&msg->hdr);\n    msg->type = type;\n    msg->body = NULL;\n    return msg;\n}\n\nPJ_DEF(pjsip_msg*) pjsip_msg_clone( pj_pool_t *pool, const pjsip_msg *src)\n{\n    pjsip_msg *dst;\n    const pjsip_hdr *sh;\n\n    dst = pjsip_msg_create(pool, src->type);\n\n    /* Clone request/status line */\n    if (src->type == PJSIP_REQUEST_MSG) {\n\tpjsip_method_copy(pool, &dst->line.req.method, &src->line.req.method);\n\tdst->line.req.uri = (pjsip_uri*) pjsip_uri_clone(pool, \n\t\t\t\t\t\t  \t src->line.req.uri);\n    } else {\n\tdst->line.status.code = src->line.status.code;\n\tpj_strdup(pool, &dst->line.status.reason, &src->line.status.reason);\n    }\n\n    /* Clone headers */\n    sh = src->hdr.next;\n    while (sh != &src->hdr) {\n\tpjsip_hdr *dh = (pjsip_hdr*) pjsip_hdr_clone(pool, sh);\n\tpjsip_msg_add_hdr(dst, dh);\n\tsh = sh->next;\n    }\n\n    /* Clone message body */\n    if (src->body) {\n\tdst->body = pjsip_msg_body_clone(pool, src->body);\n    }\n\n    return dst;\n}\n\nPJ_DEF(void*)  pjsip_msg_find_hdr( const pjsip_msg *msg, \n\t\t\t\t   pjsip_hdr_e hdr_type, const void *start)\n{\n    const pjsip_hdr *hdr=(const pjsip_hdr*) start, *end=&msg->hdr;\n\n    if (hdr == NULL) {\n\thdr = msg->hdr.next;\n    }\n    for (; hdr!=end; hdr = hdr->next) {\n\tif (hdr->type == hdr_type)\n\t    return (void*)hdr;\n    }\n    return NULL;\n}\n\nPJ_DEF(void*)  pjsip_msg_find_hdr_by_name( const pjsip_msg *msg, \n\t\t\t\t\t   const pj_str_t *name, \n\t\t\t\t\t   const void *start)\n{\n    const pjsip_hdr *hdr=(const pjsip_hdr*)start, *end=&msg->hdr;\n\n    if (hdr == NULL) {\n\thdr = msg->hdr.next;\n    }\n    for (; hdr!=end; hdr = hdr->next) {\n\tif (pj_stricmp(&hdr->name, name) == 0)\n\t    return (void*)hdr;\n    }\n    return NULL;\n}\n\nPJ_DEF(void*)  pjsip_msg_find_hdr_by_names( const pjsip_msg *msg, \n\t\t\t\t\t    const pj_str_t *name, \n\t\t\t\t\t    const pj_str_t *sname,\n\t\t\t\t\t    const void *start)\n{\n    const pjsip_hdr *hdr=(const pjsip_hdr*)start, *end=&msg->hdr;\n\n    if (hdr == NULL) {\n\thdr = msg->hdr.next;\n    }\n    for (; hdr!=end; hdr = hdr->next) {\n\tif (pj_stricmp(&hdr->name, name) == 0)\n\t    return (void*)hdr;\n\tif (pj_stricmp(&hdr->name, sname) == 0)\n\t    return (void*)hdr;\n    }\n    return NULL;\n}\n\nPJ_DEF(void*) pjsip_msg_find_remove_hdr( pjsip_msg *msg, \n\t\t\t\t         pjsip_hdr_e hdr_type, void *start)\n{\n    pjsip_hdr *hdr = (pjsip_hdr*) pjsip_msg_find_hdr(msg, hdr_type, start);\n    if (hdr) {\n\tpj_list_erase(hdr);\n    }\n    return hdr;\n}\n\nPJ_DEF(void*) pjsip_msg_find_remove_hdr_by_name( pjsip_msg *msg,\n                                                 pj_str_t *name,\n                                                 void *start)\n{\n    pjsip_hdr *hdr = (pjsip_hdr*) pjsip_msg_find_hdr_by_name(msg, name, start);\n    if (hdr) {\n\tpj_list_erase(hdr);\n    }\n    return hdr;\n}\n\nPJ_DEF(pj_ssize_t) pjsip_msg_print( const pjsip_msg *msg, \n\t\t\t\t    char *buf, pj_size_t size)\n{\n    char *p=buf, *end=buf+size;\n    pj_ssize_t len;\n    pjsip_hdr *hdr;\n    pj_str_t clen_hdr =  { \"Content-Length: \", 16};\n\n    if (pjsip_use_compact_form) {\n\tclen_hdr.ptr = \"l: \";\n\tclen_hdr.slen = 3;\n    }\n\n    /* Get a wild guess on how many bytes are typically needed.\n     * We'll check this later in detail, but this serves as a quick check.\n     */\n    if (size < 256)\n\treturn -1;\n\n    /* Print request line or status line depending on message type */\n    if (msg->type == PJSIP_REQUEST_MSG) {\n\tpjsip_uri *uri;\n\n\t/* Add method. */\n\tlen = msg->line.req.method.name.slen;\n\tpj_memcpy(p, msg->line.req.method.name.ptr, len);\n\tp += len;\n\t*p++ = ' ';\n\n\t/* Add URI */\n\turi = (pjsip_uri*) pjsip_uri_get_uri(msg->line.req.uri);\n\tlen = pjsip_uri_print( PJSIP_URI_IN_REQ_URI, uri, p, end-p);\n\tif (len < 1)\n\t    return -1;\n\tp += len;\n\n\t/* Add ' SIP/2.0' */\n\tif (end-p < 16)\n\t    return -1;\n\tpj_memcpy(p, \" SIP/2.0\\r\\n\", 10);\n\tp += 10;\n\n    } else {\n\n\t/* Add 'SIP/2.0 ' */\n\tpj_memcpy(p, \"SIP/2.0 \", 8);\n\tp += 8;\n\n\t/* Add status code. */\n\tlen = pj_utoa(msg->line.status.code, p);\n\tp += len;\n\t*p++ = ' ';\n\n\t/* Add reason text. */\n\tlen = msg->line.status.reason.slen;\n\tpj_memcpy(p, msg->line.status.reason.ptr, len );\n\tp += len;\n\n\t/* Add newline. */\n\t*p++ = '\\r';\n\t*p++ = '\\n';\n    }\n\n    /* Print each of the headers. */\n    for (hdr=msg->hdr.next; hdr!=&msg->hdr; hdr=hdr->next) {\n\tlen = pjsip_hdr_print_on(hdr, p, end-p);\n\tif (len < 0)\n\t    return -1;\n\n\tif (len > 0) {\n\t    p += len;\n\t    if (p+3 >= end)\n\t\treturn -1;\n\n\t    *p++ = '\\r';\n\t    *p++ = '\\n';\n\t}\n    }\n\n    /* Process message body. */\n    if (msg->body) {\n\tenum { CLEN_SPACE = 5 };\n\tchar *clen_pos = NULL;\n\n\t/* Automaticly adds Content-Type and Content-Length headers, only\n\t * if content_type is set in the message body.\n\t */\n\tif (msg->body->content_type.type.slen) {\n\t    pj_str_t ctype_hdr = { \"Content-Type: \", 14};\n\t    const pjsip_media_type *media = &msg->body->content_type;\n\n\t    if (pjsip_use_compact_form) {\n\t\tctype_hdr.ptr = \"c: \";\n\t\tctype_hdr.slen = 3;\n\t    }\n\n\t    /* Add Content-Type header. */\n\t    if ( (end-p) < 24 + media->type.slen + media->subtype.slen) {\n\t\treturn -1;\n\t    }\n\t    pj_memcpy(p, ctype_hdr.ptr, ctype_hdr.slen);\n\t    p += ctype_hdr.slen;\n\t    p += print_media_type(p, (unsigned)(end-p), media);\n\t    *p++ = '\\r';\n\t    *p++ = '\\n';\n\n\t    /* Add Content-Length header. */\n\t    if ((end-p) < clen_hdr.slen + 12 + 2) {\n\t\treturn -1;\n\t    }\n\t    pj_memcpy(p, clen_hdr.ptr, clen_hdr.slen);\n\t    p += clen_hdr.slen;\n\t    \n\t    /* Print blanks after \"Content-Length:\", this is where we'll put\n\t     * the content length value after we know the length of the\n\t     * body.\n\t     */\n\t    pj_memset(p, ' ', CLEN_SPACE);\n\t    clen_pos = p;\n\t    p += CLEN_SPACE;\n\t    *p++ = '\\r';\n\t    *p++ = '\\n';\n\t}\n\t\n\t/* Add blank newline. */\n\t*p++ = '\\r';\n\t*p++ = '\\n';\n\n\t/* Print the message body itself. */\n\tlen = (*msg->body->print_body)(msg->body, p, end-p);\n\tif (len < 0) {\n\t    return -1;\n\t}\n\tp += len;\n\n\t/* Now that we have the length of the body, print this to the\n\t * Content-Length header.\n\t */\n\tif (clen_pos) {\n\t    char tmp[16];\n\t    len = pj_utoa((unsigned long)len, tmp);\n\t    if (len > CLEN_SPACE) len = CLEN_SPACE;\n\t    pj_memcpy(clen_pos+CLEN_SPACE-len, tmp, len);\n\t}\n\n    } else {\n\t/* There's no message body.\n\t * Add Content-Length with zero value.\n\t */\n\tif ((end-p) < clen_hdr.slen+8) {\n\t    return -1;\n\t}\n\tpj_memcpy(p, clen_hdr.ptr, clen_hdr.slen);\n\tp += clen_hdr.slen;\n\t*p++ = ' ';\n\t*p++ = '0';\n\t*p++ = '\\r';\n\t*p++ = '\\n';\n\t*p++ = '\\r';\n\t*p++ = '\\n';\n    }\n\n    *p = '\\0';\n    return p-buf;\n}\n\n///////////////////////////////////////////////////////////////////////////////\nPJ_DEF(void*) pjsip_hdr_clone( pj_pool_t *pool, const void *hdr_ptr )\n{\n    const pjsip_hdr *hdr = (const pjsip_hdr*) hdr_ptr;\n    return (*hdr->vptr->clone)(pool, hdr_ptr);\n}\n\n\nPJ_DEF(void*) pjsip_hdr_shallow_clone( pj_pool_t *pool, const void *hdr_ptr )\n{\n    const pjsip_hdr *hdr = (const pjsip_hdr*) hdr_ptr;\n    return (*hdr->vptr->shallow_clone)(pool, hdr_ptr);\n}\n\nPJ_DEF(int) pjsip_hdr_print_on( void *hdr_ptr, char *buf, pj_size_t len)\n{\n    pjsip_hdr *hdr = (pjsip_hdr*) hdr_ptr;\n    return (*hdr->vptr->print_on)(hdr_ptr, buf, len);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Status/Reason Phrase\n */\n\nPJ_DEF(const pj_str_t*) pjsip_get_status_text(int code)\n{\n    static int is_initialized;\n    if (is_initialized == 0) {\n\tis_initialized = 1;\n\tinit_status_phrase();\n    }\n\n    return (code>=100 && \n\t    code<(int)(sizeof(status_phrase)/sizeof(status_phrase[0]))) ? \n\t&status_phrase[code] : &status_phrase[0];\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Media type\n */\n/*\n * Init media type.\n */\nPJ_DEF(void) pjsip_media_type_init( pjsip_media_type *mt,\n\t\t\t\t    pj_str_t *type,\n\t\t\t\t    pj_str_t *subtype)\n{\n    pj_bzero(mt, sizeof(*mt));\n    pj_list_init(&mt->param);\n    if (type)\n\tmt->type = *type;\n    if (subtype)\n\tmt->subtype = *subtype;\n}\n\nPJ_DEF(void) pjsip_media_type_init2( pjsip_media_type *mt,\n\t\t\t\t     char *type,\n\t\t\t\t     char *subtype)\n{\n    pj_str_t s_type, s_subtype;\n\n    if (type) {\n\ts_type = pj_str(type);\n    } else {\n\ts_type.ptr = NULL;\n\ts_type.slen = 0;\n    }\n\n    if (subtype) {\n\ts_subtype = pj_str(subtype);\n    } else {\n\ts_subtype.ptr = NULL;\n\ts_subtype.slen = 0;\n    }\n\n    pjsip_media_type_init(mt, &s_type, &s_subtype);\n}\n\n/*\n * Compare two media types.\n */\nPJ_DEF(int) pjsip_media_type_cmp( const pjsip_media_type *mt1,\n\t\t\t\t  const pjsip_media_type *mt2,\n\t\t\t\t  pj_bool_t cmp_param)\n{\n    int rc;\n\n    PJ_ASSERT_RETURN(mt1 && mt2, 1);\n\n    rc = pj_stricmp(&mt1->type, &mt2->type);\n    if (rc) return rc;\n\n    rc = pj_stricmp(&mt1->subtype, &mt2->subtype);\n    if (rc) return rc;\n\n    if (cmp_param) {\n\trc = pjsip_param_cmp(&mt1->param, &mt2->param, (cmp_param==1));\n    }\n\n    return rc;\n}\n\nPJ_DEF(void) pjsip_media_type_cp( pj_pool_t *pool,\n\t\t\t\t  pjsip_media_type *dst,\n\t\t\t\t  const pjsip_media_type *src)\n{\n    PJ_ASSERT_ON_FAIL(pool && dst && src, return);\n    pj_strdup(pool, &dst->type,    &src->type);\n    pj_strdup(pool, &dst->subtype, &src->subtype);\n    pjsip_param_clone(pool, &dst->param, &src->param);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Generic pjsip_hdr_names/hvalue header.\n */\n\nstatic int pjsip_generic_string_hdr_print( pjsip_generic_string_hdr *hdr, \n\t\t\t\t    char *buf, pj_size_t size);\nstatic pjsip_generic_string_hdr* pjsip_generic_string_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t\t   const pjsip_generic_string_hdr *hdr);\nstatic pjsip_generic_string_hdr* pjsip_generic_string_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t\t\t\t   const pjsip_generic_string_hdr *hdr );\n\nstatic pjsip_hdr_vptr generic_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_generic_string_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_generic_string_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_generic_string_hdr_print,\n};\n\n\nPJ_DEF(void) pjsip_generic_string_hdr_init2(pjsip_generic_string_hdr *hdr,\n\t\t\t\t\t    pj_str_t *hname,\n\t\t\t\t\t    pj_str_t *hvalue)\n{\n    init_hdr(hdr, PJSIP_H_OTHER, &generic_hdr_vptr);\n    if (hname) {\n\thdr->name = *hname;\n\thdr->sname = *hname;\n    }\n    if (hvalue) {\n\thdr->hvalue = *hvalue;\n    } else {\n\thdr->hvalue.ptr = NULL;\n\thdr->hvalue.slen = 0;\n    }\n}\n\n\nPJ_DEF(pjsip_generic_string_hdr*) pjsip_generic_string_hdr_init(pj_pool_t *pool,\n\t\t\t\t\t       void *mem,\n\t\t\t\t\t       const pj_str_t *hnames,\n\t\t\t\t\t       const pj_str_t *hvalue)\n{\n    pjsip_generic_string_hdr *hdr = (pjsip_generic_string_hdr*) mem;\n    pj_str_t dup_hname, dup_hval;\n\n    if (hnames) {\n\tpj_strdup(pool, &dup_hname, hnames);\n    } else {\n\tdup_hname.slen = 0;\n    }\n\n    if (hvalue) {\n\tpj_strdup(pool, &dup_hval, hvalue);\n    } else {\n\tdup_hval.slen = 0;\n    }\n\n    pjsip_generic_string_hdr_init2(hdr, &dup_hname, &dup_hval);\n    return hdr;\n}\n\nPJ_DEF(pjsip_generic_string_hdr*) pjsip_generic_string_hdr_create(pj_pool_t *pool,\n\t\t\t\t const pj_str_t *hnames,\n\t\t\t\t const pj_str_t *hvalue)\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_generic_string_hdr));\n    return pjsip_generic_string_hdr_init(pool, mem, hnames, hvalue);\n}\n\nstatic int pjsip_generic_string_hdr_print( pjsip_generic_string_hdr *hdr,\n\t\t\t\t\t   char *buf, pj_size_t size)\n{\n    char *p = buf;\n    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;\n    \n    if ((pj_ssize_t)size < hname->slen + hdr->hvalue.slen + 5)\n\treturn -1;\n\n    pj_memcpy(p, hname->ptr, hname->slen);\n    p += hname->slen;\n    *p++ = ':';\n    *p++ = ' ';\n    pj_memcpy(p, hdr->hvalue.ptr, hdr->hvalue.slen);\n    p += hdr->hvalue.slen;\n    *p = '\\0';\n\n    return (int)(p - buf);\n}\n\nstatic pjsip_generic_string_hdr* pjsip_generic_string_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t           const pjsip_generic_string_hdr *rhs)\n{\n    pjsip_generic_string_hdr *hdr;\n    \n    hdr = pjsip_generic_string_hdr_create(pool, &rhs->name, &rhs->hvalue);\n\n    hdr->type = rhs->type;\n    pj_strdup(pool, &hdr->sname, &rhs->sname);\n    return hdr;\n}\n\nstatic pjsip_generic_string_hdr* pjsip_generic_string_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t\t\t\t   const pjsip_generic_string_hdr *rhs )\n{\n    pjsip_generic_string_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_generic_string_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    return hdr;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Generic pjsip_hdr_names/integer value header.\n */\n\nstatic int pjsip_generic_int_hdr_print( pjsip_generic_int_hdr *hdr, \n\t\t\t\t\tchar *buf, pj_size_t size);\nstatic pjsip_generic_int_hdr* pjsip_generic_int_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t\t   const pjsip_generic_int_hdr *hdr);\nstatic pjsip_generic_int_hdr* pjsip_generic_int_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t\t\t\t   const pjsip_generic_int_hdr *hdr );\n\nstatic pjsip_hdr_vptr generic_int_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_generic_int_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_generic_int_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_generic_int_hdr_print,\n};\n\nPJ_DEF(pjsip_generic_int_hdr*) pjsip_generic_int_hdr_init(  pj_pool_t *pool,\n\t\t\t\t\t\t\t    void *mem,\n\t\t\t\t\t\t\t    const pj_str_t *hnames,\n\t\t\t\t\t\t\t    int value)\n{\n    pjsip_generic_int_hdr *hdr = (pjsip_generic_int_hdr*) mem;\n\n    init_hdr(hdr, PJSIP_H_OTHER, &generic_int_hdr_vptr);\n    if (hnames) {\n\tpj_strdup(pool, &hdr->name, hnames);\n\thdr->sname = hdr->name;\n    }\n    hdr->ivalue = value;\n    return hdr;\n}\n\nPJ_DEF(pjsip_generic_int_hdr*) pjsip_generic_int_hdr_create( pj_pool_t *pool,\n\t\t\t\t\t\t     const pj_str_t *hnames,\n\t\t\t\t\t\t     int value)\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_generic_int_hdr));\n    return pjsip_generic_int_hdr_init(pool, mem, hnames, value);\n}\n\nstatic int pjsip_generic_int_hdr_print( pjsip_generic_int_hdr *hdr, \n\t\t\t\t\tchar *buf, pj_size_t size)\n{\n    char *p = buf;\n    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;\n\n    if ((pj_ssize_t)size < hname->slen + 15)\n\treturn -1;\n\n    pj_memcpy(p, hname->ptr, hname->slen);\n    p += hname->slen;\n    *p++ = ':';\n    *p++ = ' ';\n\n    p += pj_utoa(hdr->ivalue, p);\n\n    return (int)(p - buf);\n}\n\nstatic pjsip_generic_int_hdr* pjsip_generic_int_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t           const pjsip_generic_int_hdr *rhs)\n{\n    pjsip_generic_int_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_generic_int_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    return hdr;\n}\n\nstatic pjsip_generic_int_hdr* pjsip_generic_int_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t\t\t\t   const pjsip_generic_int_hdr *rhs )\n{\n    pjsip_generic_int_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_generic_int_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    return hdr;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Generic array header.\n */\nstatic int pjsip_generic_array_hdr_print( pjsip_generic_array_hdr *hdr, char *buf, pj_size_t size);\nstatic pjsip_generic_array_hdr* pjsip_generic_array_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t\t const pjsip_generic_array_hdr *hdr);\nstatic pjsip_generic_array_hdr* pjsip_generic_array_hdr_shallow_clone( pj_pool_t *pool, \n\t\t\t\t\t\t const pjsip_generic_array_hdr *hdr);\n\nstatic pjsip_hdr_vptr generic_array_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_generic_array_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_generic_array_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_generic_array_hdr_print,\n};\n\n\nPJ_DEF(pjsip_generic_array_hdr*) pjsip_generic_array_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t\t       void *mem,\n\t\t\t\t\t\t\t       const pj_str_t *hnames)\n{\n    pjsip_generic_array_hdr *hdr = (pjsip_generic_array_hdr*) mem;\n\n    init_hdr(hdr, PJSIP_H_OTHER, &generic_array_hdr_vptr);\n    if (hnames) {\n\tpj_strdup(pool, &hdr->name, hnames);\n\thdr->sname = hdr->name;\n    }\n    hdr->count = 0;\n    return hdr;\n}\n\nPJ_DEF(pjsip_generic_array_hdr*) pjsip_generic_array_hdr_create( pj_pool_t *pool,\n\t\t\t\t\t\t\t     const pj_str_t *hnames)\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_generic_array_hdr));\n    return pjsip_generic_array_hdr_init(pool, mem, hnames);\n\n}\n\nstatic int pjsip_generic_array_hdr_print( pjsip_generic_array_hdr *hdr, \n\t\t\t\t\t  char *buf, pj_size_t size)\n{\n    char *p = buf, *endbuf = buf+size;\n    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;\n\n    copy_advance(p, (*hname));\n    *p++ = ':';\n    *p++ = ' ';\n\n    if (hdr->count > 0) {\n\tunsigned i;\n\tint printed;\n\tcopy_advance(p, hdr->values[0]);\n\tfor (i=1; i<hdr->count; ++i) {\n\t    copy_advance_pair(p, \", \", 2, hdr->values[i]);\n\t}\n    }\n\n    return (int)(p - buf);\n}\n\nstatic pjsip_generic_array_hdr* pjsip_generic_array_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t\t const pjsip_generic_array_hdr *rhs)\n{\n    unsigned i;\n    pjsip_generic_array_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_generic_array_hdr);\n\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    for (i=0; i<rhs->count; ++i) {\n\tpj_strdup(pool, &hdr->values[i], &rhs->values[i]);\n    }\n\n    return hdr;\n}\n\n\nstatic pjsip_generic_array_hdr* pjsip_generic_array_hdr_shallow_clone( pj_pool_t *pool, \n\t\t\t\t\t\t const pjsip_generic_array_hdr *rhs)\n{\n    pjsip_generic_array_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_generic_array_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    return hdr;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Accept header.\n */\nPJ_DEF(pjsip_accept_hdr*) pjsip_accept_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t void *mem )\n{\n    pjsip_accept_hdr *hdr = (pjsip_accept_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    init_hdr(hdr, PJSIP_H_ACCEPT, &generic_array_hdr_vptr);\n    hdr->count = 0;\n    return hdr;\n}\n\nPJ_DEF(pjsip_accept_hdr*) pjsip_accept_hdr_create(pj_pool_t *pool)\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_accept_hdr));\n    return pjsip_accept_hdr_init(pool, mem);\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Allow header.\n */\n\nPJ_DEF(pjsip_allow_hdr*) pjsip_allow_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t       void *mem )\n{\n    pjsip_allow_hdr *hdr = (pjsip_allow_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    init_hdr(hdr, PJSIP_H_ALLOW, &generic_array_hdr_vptr);\n    hdr->count = 0;\n    return hdr;\n}\n\nPJ_DEF(pjsip_allow_hdr*) pjsip_allow_hdr_create(pj_pool_t *pool)\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_allow_hdr));\n    return pjsip_allow_hdr_init(pool, mem);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Call-ID header.\n */\n\nPJ_DEF(pjsip_cid_hdr*) pjsip_cid_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t   void *mem )\n{\n    pjsip_cid_hdr *hdr = (pjsip_cid_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    init_hdr(hdr, PJSIP_H_CALL_ID, &generic_hdr_vptr);\n    return hdr;\n\n}\n\nPJ_DEF(pjsip_cid_hdr*) pjsip_cid_hdr_create( pj_pool_t *pool )\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_cid_hdr));\n    return pjsip_cid_hdr_init(pool, mem);\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Content-Length header.\n */\nstatic int pjsip_clen_hdr_print( pjsip_clen_hdr *hdr, char *buf, pj_size_t size);\nstatic pjsip_clen_hdr* pjsip_clen_hdr_clone( pj_pool_t *pool, const pjsip_clen_hdr *hdr);\n#define pjsip_clen_hdr_shallow_clone pjsip_clen_hdr_clone\n\nstatic pjsip_hdr_vptr clen_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_clen_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_clen_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_clen_hdr_print,\n};\n\nPJ_DEF(pjsip_clen_hdr*) pjsip_clen_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t     void *mem )\n{\n    pjsip_clen_hdr *hdr = (pjsip_clen_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    init_hdr(hdr, PJSIP_H_CONTENT_LENGTH, &clen_hdr_vptr);\n    hdr->len = 0;\n    return hdr;\n}\n\nPJ_DEF(pjsip_clen_hdr*) pjsip_clen_hdr_create( pj_pool_t *pool )\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_clen_hdr));\n    return pjsip_clen_hdr_init(pool, mem);\n}\n\nstatic int pjsip_clen_hdr_print( pjsip_clen_hdr *hdr, \n\t\t\t\t char *buf, pj_size_t size)\n{\n    char *p = buf;\n    int len;\n    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;\n\n    if ((pj_ssize_t)size < hname->slen + 14)\n\treturn -1;\n\n    pj_memcpy(p, hname->ptr, hname->slen);\n    p += hname->slen;\n    *p++ = ':';\n    *p++ = ' ';\n\n    len = pj_utoa(hdr->len, p);\n    p += len;\n    *p = '\\0';\n\n    return (int)(p-buf);\n}\n\nstatic pjsip_clen_hdr* pjsip_clen_hdr_clone( pj_pool_t *pool, const pjsip_clen_hdr *rhs)\n{\n    pjsip_clen_hdr *hdr = pjsip_clen_hdr_create(pool);\n    hdr->len = rhs->len;\n    return hdr;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * CSeq header.\n */\nstatic int pjsip_cseq_hdr_print( pjsip_cseq_hdr *hdr, char *buf, pj_size_t size);\nstatic pjsip_cseq_hdr* pjsip_cseq_hdr_clone( pj_pool_t *pool, const pjsip_cseq_hdr *hdr);\nstatic pjsip_cseq_hdr* pjsip_cseq_hdr_shallow_clone( pj_pool_t *pool, const pjsip_cseq_hdr *hdr );\n\nstatic pjsip_hdr_vptr cseq_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_cseq_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_cseq_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_cseq_hdr_print,\n};\n\nPJ_DEF(pjsip_cseq_hdr*) pjsip_cseq_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t     void *mem )\n{\n    pjsip_cseq_hdr *hdr = (pjsip_cseq_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    init_hdr(hdr, PJSIP_H_CSEQ, &cseq_hdr_vptr);\n    hdr->cseq = 0;\n    hdr->method.id = PJSIP_OTHER_METHOD;\n    hdr->method.name.ptr = NULL;\n    hdr->method.name.slen = 0;\n    return hdr;\n}\n\nPJ_DEF(pjsip_cseq_hdr*) pjsip_cseq_hdr_create( pj_pool_t *pool )\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_cseq_hdr));\n    return pjsip_cseq_hdr_init(pool, mem);\n}\n\nstatic int pjsip_cseq_hdr_print( pjsip_cseq_hdr *hdr, char *buf, pj_size_t size)\n{\n    char *p = buf;\n    int len;\n    /* CSeq doesn't have compact form */\n\n    if ((pj_ssize_t)size < hdr->name.slen + hdr->method.name.slen + 15)\n\treturn -1;\n\n    pj_memcpy(p, hdr->name.ptr, hdr->name.slen);\n    p += hdr->name.slen;\n    *p++ = ':';\n    *p++ = ' ';\n\n    len = pj_utoa(hdr->cseq, p);\n    p += len;\n    *p++ = ' ';\n\n    pj_memcpy(p, hdr->method.name.ptr, hdr->method.name.slen);\n    p += hdr->method.name.slen;\n\n    *p = '\\0';\n\n    return (int)(p-buf);\n}\n\nstatic pjsip_cseq_hdr* pjsip_cseq_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t     const pjsip_cseq_hdr *rhs)\n{\n    pjsip_cseq_hdr *hdr = pjsip_cseq_hdr_create(pool);\n    hdr->cseq = rhs->cseq;\n    pjsip_method_copy(pool, &hdr->method, &rhs->method);\n    return hdr;\n}\n\nstatic pjsip_cseq_hdr* pjsip_cseq_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t\t\t     const pjsip_cseq_hdr *rhs )\n{\n    pjsip_cseq_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_cseq_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    return hdr;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Contact header.\n */\nstatic int pjsip_contact_hdr_print( pjsip_contact_hdr *hdr, char *buf, pj_size_t size);\nstatic pjsip_contact_hdr* pjsip_contact_hdr_clone( pj_pool_t *pool, const pjsip_contact_hdr *hdr);\nstatic pjsip_contact_hdr* pjsip_contact_hdr_shallow_clone( pj_pool_t *pool, const pjsip_contact_hdr *);\n\nstatic pjsip_hdr_vptr contact_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_contact_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_contact_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_contact_hdr_print,\n};\n\nPJ_DEF(pjsip_contact_hdr*) pjsip_contact_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t   void *mem )\n{\n    pjsip_contact_hdr *hdr = (pjsip_contact_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    pj_bzero(mem, sizeof(pjsip_contact_hdr));\n    init_hdr(hdr, PJSIP_H_CONTACT, &contact_hdr_vptr);\n    hdr->expires = -1;\n    pj_list_init(&hdr->other_param);\n    return hdr;\n}\n\nPJ_DEF(pjsip_contact_hdr*) pjsip_contact_hdr_create( pj_pool_t *pool )\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_contact_hdr));\n    return pjsip_contact_hdr_init(pool, mem);\n}\n\nstatic int pjsip_contact_hdr_print( pjsip_contact_hdr *hdr, char *buf, \n\t\t\t\t    pj_size_t size)\n{\n    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    if (hdr->star) {\n\tchar *p = buf;\n\tif ((pj_ssize_t)size < hname->slen + 6)\n\t    return -1;\n\tpj_memcpy(p, hname->ptr, hname->slen);\n\tp += hname->slen;\n\t*p++ = ':';\n\t*p++ = ' ';\n\t*p++ = '*';\n\treturn (int)(p - buf);\n\n    } else {\n\tint printed;\n\tchar *startbuf = buf;\n\tchar *endbuf = buf + size;\n\n\tcopy_advance(buf, (*hname));\n\tcopy_advance_char_check(buf, ':');\n\tcopy_advance_char_check(buf, ' ');\n\n\tprinted = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, hdr->uri, \n\t\t\t\t  buf, endbuf-buf);\n\tif (printed < 1)\n\t    return -1;\n\n\tbuf += printed;\n\n\tif (hdr->q1000) {\n\t    unsigned frac;\n\n\t    if (buf+19 >= endbuf)\n\t\treturn -1;\n\n\t    /*\n\t    printed = sprintf(buf, \";q=%u.%03u\",\n\t\t\t\t   hdr->q1000/1000, hdr->q1000 % 1000);\n\t     */\n\t    pj_memcpy(buf, \";q=\", 3);\n\t    printed = pj_utoa(hdr->q1000/1000, buf+3);\n\t    buf += printed + 3;\n\t    frac = hdr->q1000 % 1000;\n\t    if (frac != 0) {\n\t\t*buf++ = '.';\n\t\tif ((frac % 100)==0) frac /= 100;\n\t\tif ((frac % 10)==0) frac /= 10;\n\t\tprinted = pj_utoa(frac, buf);\n\t\tbuf += printed;\n\t    }\n\t}\n\n\tif (hdr->expires >= 0) {\n\t    if (buf+23 >= endbuf)\n\t\treturn -1;\n\n\t    pj_memcpy(buf, \";expires=\", 9);\n\t    printed = pj_utoa(hdr->expires, buf+9);\n\t    buf += printed + 9;\n\t}\n\n\tprinted = (int)pjsip_param_print_on(&hdr->other_param, buf, endbuf-buf,\n\t\t\t\t\t    &pc->pjsip_TOKEN_SPEC,\n\t\t\t\t\t    &pc->pjsip_TOKEN_SPEC, \n\t\t\t\t\t    ';');\n\tif (printed < 0)\n\t    return printed;\n\tbuf += printed;\n\n\treturn (int)(buf-startbuf);\n    }\n}\n\nstatic pjsip_contact_hdr* pjsip_contact_hdr_clone(pj_pool_t *pool, \n\t\t\t\t\t          const pjsip_contact_hdr *rhs)\n{\n    pjsip_contact_hdr *hdr = pjsip_contact_hdr_create(pool);\n\n    hdr->star = rhs->star;\n    if (hdr->star)\n\treturn hdr;\n\n    hdr->uri = (pjsip_uri*) pjsip_uri_clone(pool, rhs->uri);\n    hdr->q1000 = rhs->q1000;\n    hdr->expires = rhs->expires;\n    pjsip_param_clone(pool, &hdr->other_param, &rhs->other_param);\n    return hdr;\n}\n\nstatic pjsip_contact_hdr* \npjsip_contact_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t const pjsip_contact_hdr *rhs)\n{\n    pjsip_contact_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_contact_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    pjsip_param_shallow_clone(pool, &hdr->other_param, &rhs->other_param);\n    return hdr;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Content-Type header..\n */\nstatic int pjsip_ctype_hdr_print( pjsip_ctype_hdr *hdr, char *buf, \n\t\t\t\t  pj_size_t size);\nstatic pjsip_ctype_hdr* pjsip_ctype_hdr_clone(pj_pool_t *pool, \n\t\t\t\t\t      const pjsip_ctype_hdr *hdr);\n#define pjsip_ctype_hdr_shallow_clone pjsip_ctype_hdr_clone\n\nstatic pjsip_hdr_vptr ctype_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_ctype_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_ctype_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_ctype_hdr_print,\n};\n\nPJ_DEF(pjsip_ctype_hdr*) pjsip_ctype_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t       void *mem )\n{\n    pjsip_ctype_hdr *hdr = (pjsip_ctype_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    pj_bzero(mem, sizeof(pjsip_ctype_hdr));\n    init_hdr(hdr, PJSIP_H_CONTENT_TYPE, &ctype_hdr_vptr);\n    pj_list_init(&hdr->media.param);\n    return hdr;\n\n}\n\nPJ_DEF(pjsip_ctype_hdr*) pjsip_ctype_hdr_create( pj_pool_t *pool )\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_ctype_hdr));\n    return pjsip_ctype_hdr_init(pool, mem);\n}\n\nstatic int print_media_type(char *buf, unsigned len,\n\t\t\t    const pjsip_media_type *media)\n{\n    char *p = buf;\n    pj_ssize_t printed;\n    const pjsip_parser_const_t *pc;\n\n    pj_memcpy(p, media->type.ptr, media->type.slen);\n    p += media->type.slen;\n    *p++ = '/';\n    pj_memcpy(p, media->subtype.ptr, media->subtype.slen);\n    p += media->subtype.slen;\n\n    pc = pjsip_parser_const();\n    printed = pjsip_param_print_on(&media->param, p, buf+len-p,\n\t\t\t\t   &pc->pjsip_TOKEN_SPEC,\n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, ';');\n    if (printed < 0)\n\treturn -1;\n\n    p += printed;\n\n    return (int)(p-buf);\n}\n\n\nPJ_DEF(int) pjsip_media_type_print(char *buf, unsigned len,\n\t\t\t\t   const pjsip_media_type *media)\n{\n    return print_media_type(buf, len, media);\n}\n\nstatic int pjsip_ctype_hdr_print( pjsip_ctype_hdr *hdr, \n\t\t\t\t  char *buf, pj_size_t size)\n{\n    char *p = buf;\n    int len;\n    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;\n\n    if ((pj_ssize_t)size < hname->slen + \n\t\t\t   hdr->media.type.slen + hdr->media.subtype.slen + 8)\n    {\n\treturn -1;\n    }\n\n    pj_memcpy(p, hname->ptr, hname->slen);\n    p += hname->slen;\n    *p++ = ':';\n    *p++ = ' ';\n\n    len = print_media_type(p, (unsigned)(buf+size-p), &hdr->media);\n    p += len;\n\n    *p = '\\0';\n    return (int)(p-buf);\n}\n\nstatic pjsip_ctype_hdr* pjsip_ctype_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t       const pjsip_ctype_hdr *rhs)\n{\n    pjsip_ctype_hdr *hdr = pjsip_ctype_hdr_create(pool);\n    pj_strdup(pool, &hdr->media.type, &rhs->media.type);\n    pj_strdup(pool, &hdr->media.subtype, &rhs->media.subtype);\n    pjsip_param_clone(pool, &hdr->media.param, &rhs->media.param);\n    return hdr;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Expires header.\n */\nPJ_DEF(pjsip_expires_hdr*) pjsip_expires_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t   void *mem,\n\t\t\t\t\t\t   int value)\n{\n    pjsip_expires_hdr *hdr = (pjsip_expires_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    init_hdr(hdr, PJSIP_H_EXPIRES, &generic_int_hdr_vptr);\n    hdr->ivalue = value;\n    return hdr;\n\n}\n\nPJ_DEF(pjsip_expires_hdr*) pjsip_expires_hdr_create( pj_pool_t *pool,\n\t\t\t\t\t\t     int value )\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_expires_hdr));\n    return pjsip_expires_hdr_init(pool, mem, value);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * To or From header.\n */\nstatic int pjsip_fromto_hdr_print( pjsip_fromto_hdr *hdr, \n\t\t\t\t   char *buf, pj_size_t size);\nstatic pjsip_fromto_hdr* pjsip_fromto_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t         const pjsip_fromto_hdr *hdr);\nstatic pjsip_fromto_hdr* pjsip_fromto_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t\t\t\t const pjsip_fromto_hdr *hdr);\n\n\nstatic pjsip_hdr_vptr fromto_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_fromto_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_fromto_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_fromto_hdr_print,\n};\n\nPJ_DEF(pjsip_from_hdr*) pjsip_from_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t     void *mem )\n{\n    pjsip_from_hdr *hdr = (pjsip_from_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    pj_bzero(mem, sizeof(pjsip_from_hdr));\n    init_hdr(hdr, PJSIP_H_FROM, &fromto_hdr_vptr);\n    pj_list_init(&hdr->other_param);\n    return hdr;\n}\n\nPJ_DEF(pjsip_from_hdr*) pjsip_from_hdr_create( pj_pool_t *pool )\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_from_hdr));\n    return pjsip_from_hdr_init(pool, mem);\n}\n\nPJ_DEF(pjsip_to_hdr*) pjsip_to_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t void *mem )\n{\n    pjsip_to_hdr *hdr = (pjsip_to_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    pj_bzero(mem, sizeof(pjsip_to_hdr));\n    init_hdr(hdr, PJSIP_H_TO, &fromto_hdr_vptr);\n    pj_list_init(&hdr->other_param);\n    return hdr;\n\n}\n\nPJ_DEF(pjsip_to_hdr*) pjsip_to_hdr_create( pj_pool_t *pool )\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_to_hdr));\n    return pjsip_to_hdr_init(pool, mem);\n}\n\nPJ_DEF(pjsip_from_hdr*) pjsip_fromto_hdr_set_from( pjsip_fromto_hdr *hdr )\n{\n    hdr->type = PJSIP_H_FROM;\n    hdr->name.ptr = pjsip_hdr_names[PJSIP_H_FROM].name;\n    hdr->name.slen = pjsip_hdr_names[PJSIP_H_FROM].name_len;\n    hdr->sname.ptr = pjsip_hdr_names[PJSIP_H_FROM].sname;\n    hdr->sname.slen = 1;\n    return hdr;\n}\n\nPJ_DEF(pjsip_to_hdr*) pjsip_fromto_hdr_set_to( pjsip_fromto_hdr *hdr )\n{\n    hdr->type = PJSIP_H_TO;\n    hdr->name.ptr = pjsip_hdr_names[PJSIP_H_TO].name;\n    hdr->name.slen = pjsip_hdr_names[PJSIP_H_TO].name_len;\n    hdr->sname.ptr = pjsip_hdr_names[PJSIP_H_TO].sname;\n    hdr->sname.slen = 1;\n    return hdr;\n}\n\nstatic int pjsip_fromto_hdr_print( pjsip_fromto_hdr *hdr, \n\t\t\t\t   char *buf, pj_size_t size)\n{\n    pj_ssize_t printed;\n    char *startbuf = buf;\n    char *endbuf = buf + size;\n    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    copy_advance(buf, (*hname));\n    *buf++ = ':';\n    *buf++ = ' ';\n\n    printed = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, hdr->uri, \n\t\t\t      buf, endbuf-buf);\n    if (printed < 1)\n\treturn -1;\n\n    buf += printed;\n\n    copy_advance_pair_escape(buf, \";tag=\", 5, hdr->tag,\n\t\t\t     pc->pjsip_TOKEN_SPEC);\n\n    printed = pjsip_param_print_on(&hdr->other_param, buf, endbuf-buf, \n\t\t\t\t   &pc->pjsip_TOKEN_SPEC,\n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, ';');\n    if (printed < 0)\n\treturn -1;\n    buf += printed;\n\n    return (int)(buf-startbuf);\n}\n\nstatic pjsip_fromto_hdr* pjsip_fromto_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t         const pjsip_fromto_hdr *rhs)\n{\n    pjsip_fromto_hdr *hdr = pjsip_from_hdr_create(pool);\n\n    hdr->type = rhs->type;\n    hdr->name = rhs->name;\n    hdr->sname = rhs->sname;\n    hdr->uri = (pjsip_uri*) pjsip_uri_clone(pool, rhs->uri);\n    pj_strdup( pool, &hdr->tag, &rhs->tag);\n    pjsip_param_clone( pool, &hdr->other_param, &rhs->other_param);\n\n    return hdr;\n}\n\nstatic pjsip_fromto_hdr* \npjsip_fromto_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\tconst pjsip_fromto_hdr *rhs)\n{\n    pjsip_fromto_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_fromto_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    pjsip_param_shallow_clone( pool, &hdr->other_param, &rhs->other_param);\n    return hdr;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Max-Forwards header.\n */\nPJ_DEF(pjsip_max_fwd_hdr*) pjsip_max_fwd_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t   void *mem,\n\t\t\t\t\t\t   int value)\n{\n    pjsip_max_fwd_hdr *hdr = (pjsip_max_fwd_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    init_hdr(hdr, PJSIP_H_MAX_FORWARDS, &generic_int_hdr_vptr);\n    hdr->ivalue = value;\n    return hdr;\n\n}\n\nPJ_DEF(pjsip_max_fwd_hdr*) pjsip_max_fwd_hdr_create(pj_pool_t *pool,\n\t\t\t\t\t\t    int value)\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_max_fwd_hdr));\n    return pjsip_max_fwd_hdr_init(pool, mem, value);\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Min-Expires header.\n */\nPJ_DEF(pjsip_min_expires_hdr*) pjsip_min_expires_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t\t   void *mem,\n\t\t\t\t\t\t\t   int value )\n{\n    pjsip_min_expires_hdr *hdr = (pjsip_min_expires_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    init_hdr(hdr, PJSIP_H_MIN_EXPIRES, &generic_int_hdr_vptr);\n    hdr->ivalue = value;\n    return hdr;\n}\n\nPJ_DEF(pjsip_min_expires_hdr*) pjsip_min_expires_hdr_create(pj_pool_t *pool,\n\t\t\t\t\t\t\t    int value )\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_min_expires_hdr));\n    return pjsip_min_expires_hdr_init(pool, mem, value );\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Record-Route and Route header.\n */\nstatic int pjsip_routing_hdr_print( pjsip_routing_hdr *r, char *buf, pj_size_t size );\nstatic pjsip_routing_hdr* pjsip_routing_hdr_clone( pj_pool_t *pool, const pjsip_routing_hdr *r );\nstatic pjsip_routing_hdr* pjsip_routing_hdr_shallow_clone( pj_pool_t *pool, const pjsip_routing_hdr *r );\n\nstatic pjsip_hdr_vptr routing_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_routing_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_routing_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_routing_hdr_print,\n};\n\nPJ_DEF(pjsip_rr_hdr*) pjsip_rr_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t void *mem )\n{\n    pjsip_rr_hdr *hdr = (pjsip_rr_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    init_hdr(hdr, PJSIP_H_RECORD_ROUTE, &routing_hdr_vptr);\n    pjsip_name_addr_init(&hdr->name_addr);\n    pj_list_init(&hdr->other_param);\n    return hdr;\n\n}\n\nPJ_DEF(pjsip_rr_hdr*) pjsip_rr_hdr_create( pj_pool_t *pool )\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_rr_hdr));\n    return pjsip_rr_hdr_init(pool, mem);\n}\n\nPJ_DEF(pjsip_route_hdr*) pjsip_route_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t       void *mem )\n{\n    pjsip_route_hdr *hdr = (pjsip_route_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    init_hdr(hdr, PJSIP_H_ROUTE, &routing_hdr_vptr);\n    pjsip_name_addr_init(&hdr->name_addr);\n    pj_list_init(&hdr->other_param);\n    return hdr;\n}\n\nPJ_DEF(pjsip_route_hdr*) pjsip_route_hdr_create( pj_pool_t *pool )\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_route_hdr));\n    return pjsip_route_hdr_init(pool, mem);\n}\n\nPJ_DEF(pjsip_rr_hdr*) pjsip_routing_hdr_set_rr( pjsip_routing_hdr *hdr )\n{\n    hdr->type = PJSIP_H_RECORD_ROUTE;\n    hdr->name.ptr = pjsip_hdr_names[PJSIP_H_RECORD_ROUTE].name;\n    hdr->name.slen = pjsip_hdr_names[PJSIP_H_RECORD_ROUTE].name_len;\n    hdr->sname = hdr->name;\n    return hdr;\n}\n\nPJ_DEF(pjsip_route_hdr*) pjsip_routing_hdr_set_route( pjsip_routing_hdr *hdr )\n{\n    hdr->type = PJSIP_H_ROUTE;\n    hdr->name.ptr = pjsip_hdr_names[PJSIP_H_ROUTE].name;\n    hdr->name.slen = pjsip_hdr_names[PJSIP_H_ROUTE].name_len;\n    hdr->sname = hdr->name;\n    return hdr;\n}\n\nstatic int pjsip_routing_hdr_print( pjsip_routing_hdr *hdr,\n\t\t\t\t    char *buf, pj_size_t size )\n{\n    pj_ssize_t printed;\n    char *startbuf = buf;\n    char *endbuf = buf + size;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n    pjsip_sip_uri *sip_uri;\n    pjsip_param *p;\n\n    /* Check the proprietary param 'hide', don't print this header \n     * if it exists in the route URI.\n     */\n    if (PJSIP_URI_SCHEME_IS_SIPS(hdr->name_addr.uri) ||\n\tPJSIP_URI_SCHEME_IS_SIP(hdr->name_addr.uri))\n    {\n\tsip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(hdr->name_addr.uri);\n\tp = sip_uri->other_param.next;\n\twhile (p != &sip_uri->other_param) {\n\t    const pj_str_t st_hide = {\"hide\", 4};\n\n\t    if (pj_stricmp(&p->name, &st_hide) == 0) {\n\t\t/* Check if param 'hide' is specified without 'lr'. */\n\t\tpj_assert(sip_uri->lr_param != 0);\n\t\treturn 0;\n\t    }\n\t    p = p->next;\n\t}\n    }\n\n    /* Route and Record-Route don't compact forms */\n\n    copy_advance(buf, hdr->name);\n    *buf++ = ':';\n    *buf++ = ' ';\n\n    printed = pjsip_uri_print(PJSIP_URI_IN_ROUTING_HDR, &hdr->name_addr, buf, \n\t\t\t      endbuf-buf);\n    if (printed < 1)\n\treturn -1;\n    buf += printed;\n\n    printed = pjsip_param_print_on(&hdr->other_param, buf, endbuf-buf, \n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, \n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, ';');\n    if (printed < 0)\n\treturn -1;\n    buf += printed;\n\n    return (int)(buf-startbuf);\n}\n\nstatic pjsip_routing_hdr* pjsip_routing_hdr_clone( pj_pool_t *pool,\n\t\t\t\t\t\t   const pjsip_routing_hdr *rhs )\n{\n    pjsip_routing_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_routing_hdr);\n\n    init_hdr(hdr, rhs->type, rhs->vptr);\n    pjsip_name_addr_init(&hdr->name_addr);\n    pjsip_name_addr_assign(pool, &hdr->name_addr, &rhs->name_addr);\n    pjsip_param_clone( pool, &hdr->other_param, &rhs->other_param);\n    return hdr;\n}\n\nstatic pjsip_routing_hdr* pjsip_routing_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t\t\t\t   const pjsip_routing_hdr *rhs )\n{\n    pjsip_routing_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_routing_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    pjsip_param_shallow_clone( pool, &hdr->other_param, &rhs->other_param);\n    return hdr;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Require header.\n */\nPJ_DEF(pjsip_require_hdr*) pjsip_require_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t   void *mem )\n{\n    pjsip_require_hdr *hdr = (pjsip_require_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    init_hdr(hdr, PJSIP_H_REQUIRE, &generic_array_hdr_vptr);\n    hdr->count = 0;\n    return hdr;\n}\n\nPJ_DEF(pjsip_require_hdr*) pjsip_require_hdr_create(pj_pool_t *pool)\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_require_hdr));\n    return pjsip_require_hdr_init(pool, mem);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Retry-After header.\n */\nstatic int pjsip_retry_after_hdr_print(pjsip_retry_after_hdr *r, \n\t\t\t\t       char *buf, pj_size_t size );\nstatic pjsip_retry_after_hdr* pjsip_retry_after_hdr_clone(pj_pool_t *pool, \n\t\t\t\t\t\t\t  const pjsip_retry_after_hdr *r);\nstatic pjsip_retry_after_hdr* \npjsip_retry_after_hdr_shallow_clone(pj_pool_t *pool, \n\t\t\t\t    const pjsip_retry_after_hdr *r );\n\nstatic pjsip_hdr_vptr retry_after_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_retry_after_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_retry_after_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_retry_after_hdr_print,\n};\n\n\nPJ_DEF(pjsip_retry_after_hdr*) pjsip_retry_after_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t\t   void *mem,\n\t\t\t\t\t\t\t   int value )\n{\n    pjsip_retry_after_hdr *hdr = (pjsip_retry_after_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    init_hdr(hdr, PJSIP_H_RETRY_AFTER, &retry_after_hdr_vptr);\n    hdr->ivalue = value;\n    hdr->comment.slen = 0;\n    pj_list_init(&hdr->param);\n    return hdr;\n}\n\nPJ_DEF(pjsip_retry_after_hdr*) pjsip_retry_after_hdr_create(pj_pool_t *pool,\n\t\t\t\t\t\t\t    int value )\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_retry_after_hdr));\n    return pjsip_retry_after_hdr_init(pool, mem, value );\n}\n\n\nstatic int pjsip_retry_after_hdr_print(pjsip_retry_after_hdr *hdr, \n\t\t\t    \t       char *buf, pj_size_t size)\n{\n    char *p = buf;\n    char *endbuf = buf + size;\n    const pj_str_t *hname = &hdr->name;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n    pj_ssize_t printed;\n    \n    if ((pj_ssize_t)size < hdr->name.slen + 2+11)\n\treturn -1;\n\n    pj_memcpy(p, hdr->name.ptr, hdr->name.slen);\n    p += hname->slen;\n    *p++ = ':';\n    *p++ = ' ';\n\n    p += pj_utoa(hdr->ivalue, p);\n\n    if (hdr->comment.slen) {\n\tpj_bool_t enclosed;\n\n\tif (endbuf-p < hdr->comment.slen + 3)\n\t    return -1;\n\n\tenclosed = (*hdr->comment.ptr == '(');\n\tif (!enclosed)\n\t    *p++ = '(';\n\tpj_memcpy(p, hdr->comment.ptr, hdr->comment.slen);\n\tp += hdr->comment.slen;\n\tif (!enclosed)\n\t    *p++ = ')';\n\n\tif (!pj_list_empty(&hdr->param))\n\t    *p++ = ' ';\n    }\n\n    printed = pjsip_param_print_on(&hdr->param, p, endbuf-p,\n\t\t\t\t   &pc->pjsip_TOKEN_SPEC,\n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, \n\t\t\t\t   ';');\n    if (printed < 0)\n\treturn (int)printed;\n\n    p += printed;\n\n    return (int)(p - buf);\n}\n\nstatic pjsip_retry_after_hdr* pjsip_retry_after_hdr_clone(pj_pool_t *pool, \n\t\t\t\t\t\t\t  const pjsip_retry_after_hdr *rhs)\n{\n    pjsip_retry_after_hdr *hdr = pjsip_retry_after_hdr_create(pool, rhs->ivalue);\n    pj_strdup(pool, &hdr->comment, &rhs->comment);\n    pjsip_param_clone(pool, &hdr->param, &rhs->param);\n    return hdr;\n}\n\nstatic pjsip_retry_after_hdr* \npjsip_retry_after_hdr_shallow_clone(pj_pool_t *pool, \n\t\t\t\t    const pjsip_retry_after_hdr *rhs)\n{\n    pjsip_retry_after_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_retry_after_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    pjsip_param_shallow_clone(pool, &hdr->param, &rhs->param);\n    return hdr;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Supported header.\n */\nPJ_DEF(pjsip_supported_hdr*) pjsip_supported_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t       void *mem )\n{\n    pjsip_supported_hdr *hdr = (pjsip_supported_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n    init_hdr(hdr, PJSIP_H_SUPPORTED, &generic_array_hdr_vptr);\n    hdr->count = 0;\n    return hdr;\n}\n\nPJ_DEF(pjsip_supported_hdr*) pjsip_supported_hdr_create(pj_pool_t *pool)\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_supported_hdr));\n    return pjsip_supported_hdr_init(pool, mem);\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Unsupported header.\n */\nPJ_DEF(pjsip_unsupported_hdr*) pjsip_unsupported_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t\t\t   void *mem )\n{\n    pjsip_unsupported_hdr *hdr = (pjsip_unsupported_hdr*) mem;\n    \n    PJ_UNUSED_ARG(pool);\n\n    init_hdr(hdr, PJSIP_H_UNSUPPORTED, &generic_array_hdr_vptr);\n    hdr->count = 0;\n    return hdr;\n}\n\nPJ_DEF(pjsip_unsupported_hdr*) pjsip_unsupported_hdr_create(pj_pool_t *pool)\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_unsupported_hdr));\n    return pjsip_unsupported_hdr_init(pool, mem);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Via header.\n */\nstatic int pjsip_via_hdr_print( pjsip_via_hdr *hdr, char *buf, pj_size_t size);\nstatic pjsip_via_hdr* pjsip_via_hdr_clone( pj_pool_t *pool, const pjsip_via_hdr *hdr);\nstatic pjsip_via_hdr* pjsip_via_hdr_shallow_clone( pj_pool_t *pool, const pjsip_via_hdr *hdr );\n\nstatic pjsip_hdr_vptr via_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_via_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_via_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_via_hdr_print,\n};\n\nPJ_DEF(pjsip_via_hdr*) pjsip_via_hdr_init( pj_pool_t *pool,\n\t\t\t\t\t   void *mem )\n{\n    pjsip_via_hdr *hdr = (pjsip_via_hdr*) mem;\n\n    PJ_UNUSED_ARG(pool);\n\n    pj_bzero(mem, sizeof(pjsip_via_hdr));\n    init_hdr(hdr, PJSIP_H_VIA, &via_hdr_vptr);\n    hdr->ttl_param = -1;\n    hdr->rport_param = -1;\n    pj_list_init(&hdr->other_param);\n    return hdr;\n\n}\n\nPJ_DEF(pjsip_via_hdr*) pjsip_via_hdr_create( pj_pool_t *pool )\n{\n    void *mem = pj_pool_alloc(pool, sizeof(pjsip_via_hdr));\n    return pjsip_via_hdr_init(pool, mem);\n}\n\nstatic int pjsip_via_hdr_print( pjsip_via_hdr *hdr, \n\t\t\t\tchar *buf, pj_size_t size)\n{\n    pj_ssize_t printed;\n    char *startbuf = buf;\n    char *endbuf = buf + size;\n    pj_str_t sip_ver = { \"SIP/2.0/\", 8 };\n    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    if ((pj_ssize_t)size < hname->slen + sip_ver.slen + \n\t\t\t   hdr->transport.slen + hdr->sent_by.host.slen + 12)\n    {\n\treturn -1;\n    }\n\n    /* pjsip_hdr_names */\n    copy_advance(buf, (*hname));\n    *buf++ = ':';\n    *buf++ = ' ';\n\n    /* SIP/2.0/transport host:port */\n    pj_memcpy(buf, sip_ver.ptr, sip_ver.slen);\n    buf += sip_ver.slen;\n    //pj_memcpy(buf, hdr->transport.ptr, hdr->transport.slen);\n    /* Convert transport type to UPPERCASE (some endpoints want that) */\n    {\n\tint i;\n\tfor (i=0; i<hdr->transport.slen; ++i) {\n\t    buf[i] = (char)pj_toupper(hdr->transport.ptr[i]);\n\t}\n    }\n    buf += hdr->transport.slen;\n    *buf++ = ' ';\n\n    /* Check if host contains IPv6 */\n    if (pj_memchr(hdr->sent_by.host.ptr, ':', hdr->sent_by.host.slen)) {\n\tcopy_advance_pair_quote_cond(buf, \"\", 0, hdr->sent_by.host, '[', ']');\n    } else {\n\tcopy_advance_check(buf, hdr->sent_by.host);\n    }\n\n    if (hdr->sent_by.port != 0) {\n\t*buf++ = ':';\n\tprinted = pj_utoa(hdr->sent_by.port, buf);\n\tbuf += printed;\n    }\n\n    if (hdr->ttl_param >= 0) {\n\tsize = endbuf-buf;\n\tif (size < 14)\n\t    return -1;\n\tpj_memcpy(buf, \";ttl=\", 5);\n\tprinted = pj_utoa(hdr->ttl_param, buf+5);\n\tbuf += printed + 5;\n    }\n\n    if (hdr->rport_param >= 0) {\n\tsize = endbuf-buf;\n\tif (size < 14)\n\t    return -1;\n\tpj_memcpy(buf, \";rport\", 6);\n\tbuf += 6;\n\tif (hdr->rport_param > 0) {\n\t    *buf++ = '=';\n\t    buf += pj_utoa(hdr->rport_param, buf);\n\t}\n    }\n\n\n    if (hdr->maddr_param.slen) {\n\t/* Detect IPv6 IP address */\n\tif (pj_memchr(hdr->maddr_param.ptr, ':', hdr->maddr_param.slen)) {\n\t    copy_advance_pair_quote_cond(buf, \";maddr=\", 7, hdr->maddr_param,\n\t\t\t\t         '[', ']');\n\t} else {\n\t    copy_advance_pair(buf, \";maddr=\", 7, hdr->maddr_param);\n\t}\n    }\n\n    copy_advance_pair(buf, \";received=\", 10, hdr->recvd_param);\n    copy_advance_pair_escape(buf, \";branch=\", 8, hdr->branch_param,\n\t\t\t     pc->pjsip_TOKEN_SPEC);\n    \n    printed = pjsip_param_print_on(&hdr->other_param, buf, endbuf-buf, \n\t\t\t\t   &pc->pjsip_TOKEN_SPEC,\n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, ';');\n    if (printed < 0)\n\treturn -1;\n    buf += printed;\n    \n    return (int)(buf-startbuf);\n}\n\nstatic pjsip_via_hdr* pjsip_via_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t   const pjsip_via_hdr *rhs)\n{\n    pjsip_via_hdr *hdr = pjsip_via_hdr_create(pool);\n    pj_strdup(pool, &hdr->transport, &rhs->transport);\n    pj_strdup(pool, &hdr->sent_by.host, &rhs->sent_by.host);\n    hdr->sent_by.port = rhs->sent_by.port;\n    hdr->ttl_param = rhs->ttl_param;\n    hdr->rport_param = rhs->rport_param;\n    pj_strdup(pool, &hdr->maddr_param, &rhs->maddr_param);\n    pj_strdup(pool, &hdr->recvd_param, &rhs->recvd_param);\n    pj_strdup(pool, &hdr->branch_param, &rhs->branch_param);\n    pjsip_param_clone(pool, &hdr->other_param, &rhs->other_param);\n    return hdr;\n}\n\nstatic pjsip_via_hdr* pjsip_via_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t\t\t   const pjsip_via_hdr *rhs )\n{\n    pjsip_via_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_via_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    pjsip_param_shallow_clone(pool, &hdr->other_param, &rhs->other_param);\n    return hdr;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Warning header.\n */\nPJ_DEF(pjsip_warning_hdr*) pjsip_warning_hdr_create(  pj_pool_t *pool,\n\t\t\t\t\t\t      int code,\n\t\t\t\t\t\t      const pj_str_t *host,\n\t\t\t\t\t\t      const pj_str_t *text)\n{\n    const pj_str_t str_warning = { \"Warning\", 7 };\n    pj_str_t hvalue;\n\n    hvalue.ptr = (char*) pj_pool_alloc(pool, 10 +\t\t/* code */\n\t\t\t\t     \t     host->slen + 2 +\t/* host */\n\t\t\t\t     \t     text->slen + 2);\t/* text */\n    hvalue.slen = pj_ansi_sprintf(hvalue.ptr, \"%u %.*s \\\"%.*s\\\"\",\n\t\t\t\t  code, (int)host->slen, host->ptr,\n\t\t\t\t  (int)text->slen, text->ptr);\n\n    return pjsip_generic_string_hdr_create(pool, &str_warning, &hvalue);\n}\n\nPJ_DEF(pjsip_warning_hdr*) pjsip_warning_hdr_create_from_status(pj_pool_t *pool,\n\t\t\t\t\t\t      const pj_str_t *host,\n\t\t\t\t\t\t      pj_status_t status)\n{\n    char errbuf[PJ_ERR_MSG_SIZE];\n    pj_str_t text;\n    \n    text = pj_strerror(status, errbuf, sizeof(errbuf));\n    return pjsip_warning_hdr_create(pool, 399, host, &text);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Message body manipulations.\n */\nPJ_DEF(int) pjsip_print_body(pjsip_msg_body *msg_body, char **buf, int *len)\n{\n    static char s_buf[PJSIP_MAX_PKT_LEN];\n    int res;\n\n    res = (*msg_body->print_body)(msg_body, s_buf, PJSIP_MAX_PKT_LEN);\n    if (res < 0) {\n        return -1;\n    }\n    *buf = s_buf;\n    *len = res;\n    return 0;\n}\n\nPJ_DEF(int) pjsip_print_text_body(pjsip_msg_body *msg_body, char *buf, pj_size_t size)\n{\n    if (size < msg_body->len)\n\treturn -1;\n    pj_memcpy(buf, msg_body->data, msg_body->len);\n    return msg_body->len;\n}\n\nPJ_DEF(void*) pjsip_clone_text_data( pj_pool_t *pool, const void *data,\n\t\t\t\t     unsigned len)\n{\n    char *newdata = \"\";\n\n    if (len) {\n\tnewdata = (char*) pj_pool_alloc(pool, len);\n\tpj_memcpy(newdata, data, len);\n    }\n    return newdata;\n}\n\nPJ_DEF(pj_status_t) pjsip_msg_body_copy( pj_pool_t *pool,\n\t\t\t\t\t pjsip_msg_body *dst_body,\n\t\t\t\t\t const pjsip_msg_body *src_body )\n{\n    /* First check if clone_data field is initialized. */\n    PJ_ASSERT_RETURN( src_body->clone_data!=NULL, PJ_EINVAL );\n\n    /* Duplicate content-type */\n    pjsip_media_type_cp(pool, &dst_body->content_type,\n\t\t        &src_body->content_type);\n\n    /* Duplicate data. */\n    dst_body->data = (*src_body->clone_data)(pool, src_body->data, \n\t\t\t\t\t     src_body->len );\n\n    /* Length. */\n    dst_body->len = src_body->len;\n\n    /* Function pointers. */\n    dst_body->print_body = src_body->print_body;\n    dst_body->clone_data = src_body->clone_data;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pjsip_msg_body*) pjsip_msg_body_clone( pj_pool_t *pool,\n\t\t\t\t\t      const pjsip_msg_body *body )\n{\n    pjsip_msg_body *new_body;\n    pj_status_t status;\n\n    new_body = PJ_POOL_ALLOC_T(pool, pjsip_msg_body);\n    PJ_ASSERT_RETURN(new_body, NULL);\n\n    status = pjsip_msg_body_copy(pool, new_body, body);\n\n    return (status==PJ_SUCCESS) ? new_body : NULL;\n}\n\n\nPJ_DEF(pjsip_msg_body*) pjsip_msg_body_create( pj_pool_t *pool,\n\t\t\t\t\t       const pj_str_t *type,\n\t\t\t\t\t       const pj_str_t *subtype,\n\t\t\t\t\t       const pj_str_t *text )\n{\n    pjsip_msg_body *body;\n\n    PJ_ASSERT_RETURN(pool && type && subtype && text, NULL);\n\n    body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body);\n    PJ_ASSERT_RETURN(body != NULL, NULL);\n\n    pj_strdup(pool, &body->content_type.type, type);\n    pj_strdup(pool, &body->content_type.subtype, subtype);\n    pj_list_init(&body->content_type.param);\n\n    body->data = pj_pool_alloc(pool, text->slen);\n    pj_memcpy(body->data, text->ptr, text->slen);\n    body->len = (unsigned)text->slen;\n\n    body->clone_data = &pjsip_clone_text_data;\n    body->print_body = &pjsip_print_text_body;\n\n    return body;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_multipart.c",
    "content": "/* $Id: sip_multipart.c 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_multipart.h>\n#include <pjsip/sip_parser.h>\n#include <pjlib-util/scanner.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n#include <pj/errno.h>\n#include <pj/except.h>\n#include <pj/guid.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#define THIS_FILE\t\t\"sip_multipart.c\"\n\n#define IS_SPACE(c)\t((c)==' ' || (c)=='\\t')\n\n#if 0\n#   define TRACE_(x)\tPJ_LOG(4,x)\n#else\n#   define TRACE_(x)\n#endif\n\nextern pj_bool_t pjsip_use_compact_form;\n\n/* Type of \"data\" in multipart pjsip_msg_body */\nstruct multipart_data\n{\n    pj_str_t\t    \t  boundary;\n    pjsip_multipart_part  part_head;\n};\n\n\nstatic int multipart_print_body(struct pjsip_msg_body *msg_body,\n\t\t\t        char *buf, pj_size_t size)\n{\n    const struct multipart_data *m_data;\n    pj_str_t clen_hdr =  { \"Content-Length: \", 16};\n    pjsip_multipart_part *part;\n    char *p = buf, *end = buf+size;\n\n#define SIZE_LEFT()\t(end-p)\n\n    m_data = (const struct multipart_data*)msg_body->data;\n\n    PJ_ASSERT_RETURN(m_data && !pj_list_empty(&m_data->part_head), PJ_EINVAL);\n\n    part = m_data->part_head.next;\n    while (part != &m_data->part_head) {\n\tenum { CLEN_SPACE = 5 };\n\tchar *clen_pos;\n\tconst pjsip_hdr *hdr;\n\n\tclen_pos = NULL;\n\n\t/* Print delimiter */\n\tif (SIZE_LEFT() <= (m_data->boundary.slen+8) << 1)\n\t    return -1;\n\t*p++ = 13; *p++ = 10; *p++ = '-'; *p++ = '-';\n\tpj_memcpy(p, m_data->boundary.ptr, m_data->boundary.slen);\n\tp += m_data->boundary.slen;\n\t*p++ = 13; *p++ = 10;\n\n\t/* Print optional headers */\n\thdr = part->hdr.next;\n\twhile (hdr != &part->hdr) {\n\t    int printed = pjsip_hdr_print_on((pjsip_hdr*)hdr, p,\n\t                                     SIZE_LEFT()-2);\n\t    if (printed < 0)\n\t\treturn -1;\n\t    p += printed;\n\t    *p++ = '\\r';\n\t    *p++ = '\\n';\n\t    hdr = hdr->next;\n\t}\n\n\t/* Automaticly adds Content-Type and Content-Length headers, only\n\t * if content_type is set in the message body.\n\t */\n\tif (part->body && part->body->content_type.type.slen) {\n\t    pj_str_t ctype_hdr = { \"Content-Type: \", 14};\n\t    const pjsip_media_type *media = &part->body->content_type;\n\n\t    if (pjsip_use_compact_form) {\n\t\tctype_hdr.ptr = \"c: \";\n\t\tctype_hdr.slen = 3;\n\t    }\n\n\t    /* Add Content-Type header. */\n\t    if ( (end-p) < 24 + media->type.slen + media->subtype.slen) {\n\t\treturn -1;\n\t    }\n\t    pj_memcpy(p, ctype_hdr.ptr, ctype_hdr.slen);\n\t    p += ctype_hdr.slen;\n\t    p += pjsip_media_type_print(p, (unsigned)(end-p), media);\n\t    *p++ = '\\r';\n\t    *p++ = '\\n';\n\n\t    /* Add Content-Length header. */\n\t    if ((end-p) < clen_hdr.slen + 12 + 2) {\n\t\treturn -1;\n\t    }\n\t    pj_memcpy(p, clen_hdr.ptr, clen_hdr.slen);\n\t    p += clen_hdr.slen;\n\n\t    /* Print blanks after \"Content-Length:\", this is where we'll put\n\t     * the content length value after we know the length of the\n\t     * body.\n\t     */\n\t    pj_memset(p, ' ', CLEN_SPACE);\n\t    clen_pos = p;\n\t    p += CLEN_SPACE;\n\t    *p++ = '\\r';\n\t    *p++ = '\\n';\n\t}\n\n\t/* Empty newline */\n\t*p++ = 13; *p++ = 10;\n\n\t/* Print the body */\n\tpj_assert(part->body != NULL);\n\tif (part->body) {\n\t    int printed = part->body->print_body(part->body, p, SIZE_LEFT());\n\t    if (printed < 0)\n\t\treturn -1;\n\t    p += printed;\n\n\t    /* Now that we have the length of the body, print this to the\n\t     * Content-Length header.\n\t     */\n\t    if (clen_pos) {\n\t\tchar tmp[16];\n\t\tint len;\n\n\t\tlen = pj_utoa(printed, tmp);\n\t\tif (len > CLEN_SPACE) len = CLEN_SPACE;\n\t\tpj_memcpy(clen_pos+CLEN_SPACE-len, tmp, len);\n\t    }\n\t}\n\n\tpart = part->next;\n    }\n\n    /* Print closing delimiter */\n    if (SIZE_LEFT() < m_data->boundary.slen+8)\n\treturn -1;\n    *p++ = 13; *p++ = 10; *p++ = '-'; *p++ = '-';\n    pj_memcpy(p, m_data->boundary.ptr, m_data->boundary.slen);\n    p += m_data->boundary.slen;\n    *p++ = '-'; *p++ = '-'; *p++ = 13; *p++ = 10;\n\n#undef SIZE_LEFT\n\n    return (int)(p - buf);\n}\n\nstatic void* multipart_clone_data(pj_pool_t *pool, const void *data,\n\t\t\t\t  unsigned len)\n{\n    const struct multipart_data *src;\n    struct multipart_data *dst;\n    const pjsip_multipart_part *src_part;\n\n    PJ_UNUSED_ARG(len);\n\n    src = (const struct multipart_data*) data;\n    dst = PJ_POOL_ALLOC_T(pool, struct multipart_data);\n    pj_list_init(&dst->part_head);\n\n    pj_strdup(pool, &dst->boundary, &src->boundary);\n\n    src_part = src->part_head.next;\n    while (src_part != &src->part_head) {\n\tpjsip_multipart_part *dst_part;\n\tconst pjsip_hdr *src_hdr;\n\n\tdst_part = pjsip_multipart_create_part(pool);\n\n\tsrc_hdr = src_part->hdr.next;\n\twhile (src_hdr != &src_part->hdr) {\n\t    pjsip_hdr *dst_hdr = (pjsip_hdr*)pjsip_hdr_clone(pool, src_hdr);\n\t    pj_list_push_back(&dst_part->hdr, dst_hdr);\n\t    src_hdr = src_hdr->next;\n\t}\n\n\tdst_part->body = pjsip_msg_body_clone(pool, src_part->body);\n\n\tpj_list_push_back(&dst->part_head, dst_part);\n\n\tsrc_part = src_part->next;\n    }\n\n    return (void*)dst;\n}\n\n/*\n * Create an empty multipart body.\n */\nPJ_DEF(pjsip_msg_body*) pjsip_multipart_create( pj_pool_t *pool,\n\t\t\t\t\t\tconst pjsip_media_type *ctype,\n\t\t\t\t\t\tconst pj_str_t *boundary)\n{\n    pjsip_msg_body *body;\n    pjsip_param *ctype_param;\n    struct multipart_data *mp_data;\n    pj_str_t STR_BOUNDARY = { \"boundary\", 8 };\n\n    PJ_ASSERT_RETURN(pool, NULL);\n\n    body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body);\n\n    /* content-type */\n    if (ctype && ctype->type.slen) {\n\tpjsip_media_type_cp(pool, &body->content_type, ctype);\n    } else {\n\tpj_str_t STR_MULTIPART = {\"multipart\", 9};\n\tpj_str_t STR_MIXED = { \"mixed\", 5 };\n\n        pjsip_media_type_init(&body->content_type,\n                              &STR_MULTIPART, &STR_MIXED);\n    }\n\n    /* multipart data */\n    mp_data = PJ_POOL_ZALLOC_T(pool, struct multipart_data);\n    pj_list_init(&mp_data->part_head);\n    if (boundary) {\n\tpj_strdup(pool, &mp_data->boundary, boundary);\n    } else {\n\tpj_create_unique_string(pool, &mp_data->boundary);\n    }\n    body->data = mp_data;\n\n    /* Add \";boundary\" parameter to content_type parameter. */\n    ctype_param = pjsip_param_find(&body->content_type.param, &STR_BOUNDARY);\n    if (!ctype_param) {\n\tctype_param = PJ_POOL_ALLOC_T(pool, pjsip_param);\n\tctype_param->name = STR_BOUNDARY;\n\tpj_list_push_back(&body->content_type.param, ctype_param);\n    }\n    ctype_param->value = mp_data->boundary;\n\n    /* function pointers */\n    body->print_body = &multipart_print_body;\n    body->clone_data = &multipart_clone_data;\n\n    return body;\n}\n\n/*\n * Create an empty multipart part.\n */\nPJ_DEF(pjsip_multipart_part*) pjsip_multipart_create_part(pj_pool_t *pool)\n{\n    pjsip_multipart_part *mp;\n\n    mp = PJ_POOL_ZALLOC_T(pool, pjsip_multipart_part);\n    pj_list_init(&mp->hdr);\n\n    return mp;\n}\n\n\n/*\n * Deep clone.\n */\nPJ_DEF(pjsip_multipart_part*)\npjsip_multipart_clone_part(pj_pool_t *pool,\n\t\t\t   const pjsip_multipart_part *src)\n{\n    pjsip_multipart_part *dst;\n    const pjsip_hdr *hdr;\n\n    dst = pjsip_multipart_create_part(pool);\n\n    hdr = src->hdr.next;\n    while (hdr != &src->hdr) {\n\tpj_list_push_back(&dst->hdr, pjsip_hdr_clone(pool, hdr));\n\thdr = hdr->next;\n    }\n\n    dst->body = pjsip_msg_body_clone(pool, src->body);\n\n    return dst;\n}\n\n\n/*\n * Add a part into multipart bodies.\n */\nPJ_DEF(pj_status_t) pjsip_multipart_add_part( pj_pool_t *pool,\n\t\t\t\t\t      pjsip_msg_body *mp,\n\t\t\t\t\t      pjsip_multipart_part *part)\n{\n    struct multipart_data *m_data;\n\n    /* All params must be specified */\n    PJ_ASSERT_RETURN(pool && mp && part, PJ_EINVAL);\n\n    /* mp must really point to an actual multipart msg body */\n    PJ_ASSERT_RETURN(mp->print_body==&multipart_print_body, PJ_EINVAL);\n\n    /* The multipart part must contain a valid message body */\n    PJ_ASSERT_RETURN(part->body && part->body->print_body, PJ_EINVAL);\n\n    m_data = (struct multipart_data*)mp->data;\n    pj_list_push_back(&m_data->part_head, part);\n\n    PJ_UNUSED_ARG(pool);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get the first part of multipart bodies.\n */\nPJ_DEF(pjsip_multipart_part*)\npjsip_multipart_get_first_part(const pjsip_msg_body *mp)\n{\n    struct multipart_data *m_data;\n\n    /* Must specify mandatory params */\n    PJ_ASSERT_RETURN(mp, NULL);\n\n    /* mp must really point to an actual multipart msg body */\n    PJ_ASSERT_RETURN(mp->print_body==&multipart_print_body, NULL);\n\n    m_data = (struct multipart_data*)mp->data;\n    if (pj_list_empty(&m_data->part_head))\n\treturn NULL;\n\n    return m_data->part_head.next;\n}\n\n/*\n * Get the next part after the specified part.\n */\nPJ_DEF(pjsip_multipart_part*)\npjsip_multipart_get_next_part(const pjsip_msg_body *mp,\n\t\t\t      pjsip_multipart_part *part)\n{\n    struct multipart_data *m_data;\n\n    /* Must specify mandatory params */\n    PJ_ASSERT_RETURN(mp && part, NULL);\n\n    /* mp must really point to an actual multipart msg body */\n    PJ_ASSERT_RETURN(mp->print_body==&multipart_print_body, NULL);\n\n    m_data = (struct multipart_data*)mp->data;\n\n    /* the part parameter must be really member of the list */\n    PJ_ASSERT_RETURN(pj_list_find_node(&m_data->part_head, part) != NULL,\n\t\t     NULL);\n\n    if (part->next == &m_data->part_head)\n\treturn NULL;\n\n    return part->next;\n}\n\n/*\n * Find a body inside multipart bodies which has the specified content type.\n */\nPJ_DEF(pjsip_multipart_part*)\npjsip_multipart_find_part( const pjsip_msg_body *mp,\n\t\t\t   const pjsip_media_type *content_type,\n\t\t\t   const pjsip_multipart_part *start)\n{\n    struct multipart_data *m_data;\n    pjsip_multipart_part *part;\n\n    /* Must specify mandatory params */\n    PJ_ASSERT_RETURN(mp && content_type, NULL);\n\n    /* mp must really point to an actual multipart msg body */\n    PJ_ASSERT_RETURN(mp->print_body==&multipart_print_body, NULL);\n\n    m_data = (struct multipart_data*)mp->data;\n\n    if (start)\n\tpart = start->next;\n    else\n\tpart = m_data->part_head.next;\n\n    while (part != &m_data->part_head) {\n\tif (pjsip_media_type_cmp(&part->body->content_type,\n\t\t\t\t content_type, 0)==0)\n\t{\n\t    return part;\n\t}\n\tpart = part->next;\n    }\n\n    return NULL;\n}\n\n/* Parse a multipart part. \"pct\" is parent content-type  */\nstatic pjsip_multipart_part *parse_multipart_part(pj_pool_t *pool,\n\t\t\t\t\t\t  char *start,\n\t\t\t\t\t\t  pj_size_t len,\n\t\t\t\t\t\t  const pjsip_media_type *pct)\n{\n    pjsip_multipart_part *part = pjsip_multipart_create_part(pool);\n    char *p = start, *end = start+len, *end_hdr = NULL, *start_body = NULL;\n    pjsip_ctype_hdr *ctype_hdr = NULL;\n\n    TRACE_((THIS_FILE, \"Parsing part: begin--\\n%.*s\\n--end\",\n\t    (int)len, start));\n\n    /* Find the end of header area, by looking at an empty line */\n    for (;;) {\n\twhile (p!=end && *p!='\\n') ++p;\n\tif (p==end) {\n\t    start_body = end;\n\t    break;\n\t}\n\tif ((p==start) || (p==start+1 && *(p-1)=='\\r')) {\n\t    /* Empty header section */\n\t    end_hdr = start;\n\t    start_body = ++p;\n\t    break;\n\t} else if (p==end-1) {\n\t    /* Empty body section */\n\t    end_hdr = end;\n\t    start_body = ++p;\n\t} else if ((p>=start+1 && *(p-1)=='\\n') ||\n\t           (p>=start+2 && *(p-1)=='\\r' && *(p-2)=='\\n'))\n\t{\n\t    /* Found it */\n\t    end_hdr = (*(p-1)=='\\r') ? (p-1) : p;\n\t    start_body = ++p;\n\t    break;\n\t} else {\n\t    ++p;\n\t}\n    }\n\n    /* Parse the headers */\n    if (end_hdr-start > 0) {\n\tpjsip_hdr *hdr;\n\tpj_status_t status;\n\n\tstatus = pjsip_parse_headers(pool, start, end_hdr-start, \n\t\t\t\t     &part->hdr, 0);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(2,(THIS_FILE, status, \"Warning: error parsing multipart\"\n\t\t\t\t\t    \" header\"));\n\t}\n\n\t/* Find Content-Type header */\n\thdr = part->hdr.next;\n\twhile (hdr != &part->hdr) {\n\t    TRACE_((THIS_FILE, \"Header parsed: %.*s\", (int)hdr->name.slen,\n\t\t    hdr->name.ptr));\n\t    if (hdr->type == PJSIP_H_CONTENT_TYPE) {\n\t\tctype_hdr = (pjsip_ctype_hdr*)hdr;\n\t    }\n\t    hdr = hdr->next;\n\t}\n    }\n\n    /* Assign the body */\n    part->body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body);\n    if (ctype_hdr) {\n\tpjsip_media_type_cp(pool, &part->body->content_type, &ctype_hdr->media);\n    } else if (pct && pj_stricmp2(&pct->subtype, \"digest\")==0) {\n\tpart->body->content_type.type = pj_str(\"message\");\n\tpart->body->content_type.subtype = pj_str(\"rfc822\");\n    } else {\n\tpart->body->content_type.type = pj_str(\"text\");\n\tpart->body->content_type.subtype = pj_str(\"plain\");\n    }\n\n    if (start_body < end) {\n\tpart->body->data = start_body;\n\tpart->body->len = (unsigned)(end - start_body);\n    } else {\n\tpart->body->data = (void*)\"\";\n\tpart->body->len = 0;\n    }\n    TRACE_((THIS_FILE, \"Body parsed: \\\"%.*s\\\"\", (int)part->body->len,\n\t    part->body->data));\n    part->body->print_body = &pjsip_print_text_body;\n    part->body->clone_data = &pjsip_clone_text_data;\n\n    return part;\n}\n\n/* Public function to parse multipart message bodies into its parts */\nPJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,\n\t\t\t\t\t      char *buf, pj_size_t len,\n\t\t\t\t\t      const pjsip_media_type *ctype,\n\t\t\t\t\t      unsigned options)\n{\n    pj_str_t boundary, delim;\n    char *curptr, *endptr;\n    const pjsip_param *ctype_param;\n    const pj_str_t STR_BOUNDARY = { \"boundary\", 8 };\n    pjsip_msg_body *body = NULL;\n\n    PJ_ASSERT_RETURN(pool && buf && len && ctype && !options, NULL);\n\n    TRACE_((THIS_FILE, \"Started parsing multipart body\"));\n\n    /* Get the boundary value in the ctype */\n    boundary.ptr = NULL;\n    boundary.slen = 0;\n    ctype_param = pjsip_param_find(&ctype->param, &STR_BOUNDARY);\n    if (ctype_param) {\n\tboundary = ctype_param->value;\n\tif (boundary.slen>2 && *boundary.ptr=='\"') {\n\t    /* Remove quote */\n\t    boundary.ptr++;\n\t    boundary.slen -= 2;\n\t}\n\tTRACE_((THIS_FILE, \"Boundary is specified: '%.*s'\", (int)boundary.slen,\n\t\tboundary.ptr));\n    }\n\n    if (!boundary.slen) {\n\t/* Boundary not found or not specified. Try to be clever, get\n\t * the boundary from the body.\n\t */\n\tchar *p=buf, *end=buf+len;\n\n\tPJ_LOG(4,(THIS_FILE, \"Warning: boundary parameter not found or \"\n\t\t\t     \"not specified when parsing multipart body\"));\n\n\t/* Find the first \"--\". This \"--\" must be right after a CRLF, unless\n\t * it really appears at the start of the buffer.\n\t */\n\tfor (;;) {\n\t    while (p!=end && *p!='-') ++p;\n\n\t    if (p == end)\n\t\tbreak;\n\n\t    if ((p+1<end) && *(p+1)=='-' &&\n\t\t((p>buf && *(p-1)=='\\n') || (p==buf)))\n\t    {\n\t\tp+=2;\n\t\tbreak;\n\t    } else {\n\t\t++p;\n\t    }\n\t}\n\n\tif (p==end) {\n\t    /* Unable to determine boundary. Maybe this is not a multipart\n\t     * message?\n\t     */\n\t    PJ_LOG(4,(THIS_FILE, \"Error: multipart boundary not specified and\"\n\t\t\t\t \" unable to calculate from the body\"));\n\t    return NULL;\n\t}\n\n\tboundary.ptr = p;\n\twhile (p!=end && !pj_isspace(*p)) ++p;\n\tboundary.slen = p - boundary.ptr;\n\n\tTRACE_((THIS_FILE, \"Boundary is calculated: '%.*s'\",\n\t\t(int)boundary.slen, boundary.ptr));\n    }\n\n    /* Build the delimiter:\n     *   delimiter = \"--\" boundary\n     */\n    delim.slen = boundary.slen+2;\n    delim.ptr = (char*)pj_pool_alloc(pool, (int)delim.slen);\n    delim.ptr[0] = '-';\n    delim.ptr[1] = '-';\n    pj_memcpy(delim.ptr+2, boundary.ptr, boundary.slen);\n\n    /* Start parsing the body, skip until the first delimiter. */\n    curptr = buf;\n    endptr = buf + len;\n    {\n\tpj_str_t strbody;\n\n\tstrbody.ptr = buf; strbody.slen = len;\n\tcurptr = pj_strstr(&strbody, &delim);\n\tif (!curptr)\n\t    return NULL;\n    }\n\n    body = pjsip_multipart_create(pool, ctype, &boundary);\n\n    for (;;) {\n\tchar *start_body, *end_body;\n\tpjsip_multipart_part *part;\n\n\t/* Eat the boundary */\n\tcurptr += delim.slen;\n\tif (*curptr=='-' && curptr<endptr-1 && *(curptr+1)=='-') {\n\t    /* Found the closing delimiter */\n\t    curptr += 2;\n\t    break;\n\t}\n\t/* Optional whitespace after delimiter */\n\twhile (curptr!=endptr && IS_SPACE(*curptr)) ++curptr;\n\t/* Mandatory CRLF */\n\tif (*curptr=='\\r') ++curptr;\n\tif (*curptr!='\\n') {\n\t    /* Expecting a newline here */\n\t    return NULL;\n\t}\n\t++curptr;\n\n\t/* We now in the start of the body */\n\tstart_body = curptr;\n\n\t/* Find the next delimiter */\n\t{\n\t    pj_str_t subbody;\n\n\t    subbody.ptr = curptr; subbody.slen = endptr - curptr;\n\t    curptr = pj_strstr(&subbody, &delim);\n\t    if (!curptr) {\n\t\t/* We're really expecting end delimiter to be found. */\n\t\treturn NULL;\n\t    }\n\t}\n\n\tend_body = curptr;\n\n\t/* The newline preceeding the delimiter is conceptually part of\n\t * the delimiter, so trim it from the body.\n\t */\n\tif (*(end_body-1) == '\\n')\n\t    --end_body;\n\tif (*(end_body-1) == '\\r')\n\t    --end_body;\n\n\t/* Now that we have determined the part's boundary, parse it\n\t * to get the header and body part of the part.\n\t */\n\tpart = parse_multipart_part(pool, start_body, end_body - start_body,\n\t\t\t\t    ctype);\n\tif (part) {\n\t    pjsip_multipart_add_part(pool, body, part);\n\t}\n    }\n\n    return body;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_parser.c",
    "content": "/* $Id: sip_parser.c 4445 2013-03-20 11:29:08Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_parser.h>\n#include <pjsip/sip_uri.h>\n#include <pjsip/sip_msg.h>\n#include <pjsip/sip_multipart.h>\n#include <pjsip/sip_auth_parser.h>\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_transport.h>        /* rdata structure */\n#include <pjlib-util/scanner.h>\n#include <pjlib-util/string.h>\n#include <pj/except.h>\n#include <pj/log.h>\n#include <pj/hash.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/ctype.h>\n#include <pj/assert.h>\n\n#define THIS_FILE\t    \"sip_parser.c\"\n\n#define ALNUM\n#define RESERVED\t    \";/?:@&=+$,\"\n#define MARK\t\t    \"-_.!~*'()\"\n#define UNRESERVED\t    ALNUM MARK\n#define ESCAPED\t\t    \"%\"\n#define USER_UNRESERVED\t    \"&=+$,;?/\"\n#define PASS\t\t    \"&=+$,\"\n#define TOKEN\t\t    \"-.!%*_`'~+\"   /* '=' was removed for parsing \n\t\t\t\t\t    * param */\n#define HOST\t\t    \"_-.\"\n#define HEX_DIGIT\t    \"abcdefABCDEF\"\n#define PARAM_CHAR\t    \"[]/:&+$\" UNRESERVED ESCAPED\n#define HNV_UNRESERVED\t    \"[]/?:+$\"\n#define HDR_CHAR\t    HNV_UNRESERVED UNRESERVED ESCAPED\n\n/* A generic URI can consist of (For a complete BNF see RFC 2396):\n     #?;:@&=+-_.!~*'()%$,/\n */\n#define GENERIC_URI_CHARS   \"#?;:@&=+-_.!~*'()%$,/\" \"%\"\n\n#define UNREACHED(expr)\n\n#define IS_NEWLINE(c)\t((c)=='\\r' || (c)=='\\n')\n#define IS_SPACE(c)\t((c)==' ' || (c)=='\\t')\n\n/*\n * Header parser records.\n */\ntypedef struct handler_rec\n{\n    char\t\t  hname[PJSIP_MAX_HNAME_LEN+1];\n    pj_size_t\t\t  hname_len;\n    pj_uint32_t\t\t  hname_hash;\n    pjsip_parse_hdr_func *handler;\n} handler_rec;\n\nstatic handler_rec handler[PJSIP_MAX_HEADER_TYPES];\nstatic unsigned handler_count;\nstatic int parser_is_initialized;\n\n/*\n * URI parser records.\n */\ntypedef struct uri_parser_rec\n{\n    pj_str_t\t\t     scheme;\n    pjsip_parse_uri_func    *parse;\n} uri_parser_rec;\n\nstatic uri_parser_rec uri_handler[PJSIP_MAX_URI_TYPES];\nstatic unsigned uri_handler_count;\n\n/*\n * Global vars (also extern).\n */\nint PJSIP_SYN_ERR_EXCEPTION = -1;\n\n/* Parser constants */\nstatic pjsip_parser_const_t pconst =\n{\n    { \"user\", 4},\t/* pjsip_USER_STR\t*/\n    { \"method\", 6},\t/* pjsip_METHOD_STR\t*/\n    { \"transport\", 9},\t/* pjsip_TRANSPORT_STR\t*/\n    { \"maddr\", 5 },\t/* pjsip_MADDR_STR\t*/\n    { \"lr\", 2 },\t/* pjsip_LR_STR\t\t*/\n    { \"sip\", 3 },\t/* pjsip_SIP_STR\t*/\n    { \"sips\", 4 },\t/* pjsip_SIPS_STR\t*/\n    { \"tel\", 3 },\t/* pjsip_TEL_STR\t*/\n    { \"branch\", 6 },\t/* pjsip_BRANCH_STR\t*/\n    { \"ttl\", 3 },\t/* pjsip_TTL_STR\t*/\n    { \"received\", 8 },\t/* pjsip_RECEIVED_STR\t*/\n    { \"q\", 1 },\t\t/* pjsip_Q_STR\t\t*/\n    { \"expires\", 7 },\t/* pjsip_EXPIRES_STR\t*/\n    { \"tag\", 3 },\t/* pjsip_TAG_STR\t*/\n    { \"rport\", 5}\t/* pjsip_RPORT_STR\t*/\n};\n\n/* Character Input Specification buffer. */\nstatic pj_cis_buf_t cis_buf;\n\n\n/*\n * Forward decl.\n */\nstatic pjsip_msg *  int_parse_msg( pjsip_parse_ctx *ctx, \n\t\t\t\t   pjsip_parser_err_report *err_list);\nstatic void\t    int_parse_param( pj_scanner *scanner, \n\t\t\t\t     pj_pool_t *pool,\n\t\t\t\t     pj_str_t *pname, \n\t\t\t\t     pj_str_t *pvalue,\n\t\t\t\t     unsigned option);\nstatic void\t    int_parse_uri_param( pj_scanner *scanner, \n\t\t\t\t\t pj_pool_t *pool,\n\t\t\t\t\t pj_str_t *pname, \n\t\t\t\t\t pj_str_t *pvalue,\n\t\t\t\t\t unsigned option);\nstatic void\t    int_parse_hparam( pj_scanner *scanner,\n\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t      pj_str_t *hname,\n\t\t\t\t      pj_str_t *hvalue );\nstatic void         int_parse_req_line( pj_scanner *scanner, \n\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\tpjsip_request_line *req_line);\nstatic int          int_is_next_user( pj_scanner *scanner);\nstatic void\t    int_parse_status_line( pj_scanner *scanner, \n\t\t\t\t\t   pjsip_status_line *line);\nstatic void\t    int_parse_user_pass( pj_scanner *scanner, \n\t\t\t\t\t pj_pool_t *pool,\n\t\t\t\t\t pj_str_t *user, \n\t\t\t\t\t pj_str_t *pass);\nstatic void\t    int_parse_uri_host_port( pj_scanner *scanner, \n\t\t\t\t\t     pj_str_t *p_host, \n\t\t\t\t\t     int *p_port);\nstatic pjsip_uri *  int_parse_uri_or_name_addr( pj_scanner *scanner, \n\t\t\t\t\t        pj_pool_t *pool, \n                                                unsigned option);\nstatic void*\t    int_parse_sip_url( pj_scanner *scanner, \n\t\t\t\t         pj_pool_t *pool,\n\t\t\t\t         pj_bool_t parse_params);\nstatic pjsip_name_addr *\n                    int_parse_name_addr( pj_scanner *scanner, \n\t\t\t\t\t pj_pool_t *pool );\nstatic void*\t    int_parse_other_uri(pj_scanner *scanner, \n\t\t\t\t\tpj_pool_t *pool,\n\t\t\t\t\tpj_bool_t parse_params);\nstatic void\t    parse_hdr_end( pj_scanner *scanner );\n\nstatic pjsip_hdr*   parse_hdr_accept( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_allow( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_call_id( pjsip_parse_ctx *ctx);\nstatic pjsip_hdr*   parse_hdr_contact( pjsip_parse_ctx *ctx);\nstatic pjsip_hdr*   parse_hdr_content_len( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_content_type( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_cseq( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_expires( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_from( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_max_forwards( pjsip_parse_ctx *ctx);\nstatic pjsip_hdr*   parse_hdr_min_expires( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_rr( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_route( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_require( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_retry_after( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_supported( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_to( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_unsupported( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_via( pjsip_parse_ctx *ctx );\nstatic pjsip_hdr*   parse_hdr_generic_string( pjsip_parse_ctx *ctx);\n\n/* Convert non NULL terminated string to integer. */\nstatic unsigned long pj_strtoul_mindigit(const pj_str_t *str, \n                                         unsigned mindig)\n{\n    unsigned long value;\n    unsigned i;\n\n    value = 0;\n    for (i=0; i<(unsigned)str->slen; ++i) {\n\tvalue = value * 10 + (str->ptr[i] - '0');\n    }\n    for (; i<mindig; ++i) {\n\tvalue = value * 10;\n    }\n    return value;\n}\n\n/* Case insensitive comparison */\n#define parser_stricmp(s1, s2)  (s1.slen!=s2.slen || pj_stricmp_alnum(&s1, &s2))\n\n\n/* Get a token and unescape */\nPJ_INLINE(void) parser_get_and_unescape(pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t\t\tconst pj_cis_t *spec, \n\t\t\t\t\tconst pj_cis_t *unesc_spec,\n\t\t\t\t\tpj_str_t *token)\n{\n#if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(spec);\n    pj_scan_get_unescape(scanner, unesc_spec, token);\n#else\n    PJ_UNUSED_ARG(unesc_spec);\n    pj_scan_get(scanner, spec, token);\n    *token = pj_str_unescape(pool, token);\n#endif\n}\n\n\n\n/* Syntax error handler for parser. */\nstatic void on_syntax_error(pj_scanner *scanner)\n{\n    PJ_UNUSED_ARG(scanner);\n    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n}\n\n/* Get parser constants. */\nPJ_DEF(const pjsip_parser_const_t*) pjsip_parser_const(void)\n{\n    return &pconst;\n}\n\n/* Concatenate unrecognized params into single string. */\nPJ_DEF(void) pjsip_concat_param_imp(pj_str_t *param, pj_pool_t *pool, \n\t\t\t     \t    const pj_str_t *pname, \n\t\t\t\t    const pj_str_t *pvalue, \n                             \t    int sepchar)\n{\n    char *new_param, *p;\n    pj_size_t len;\n\n    len = param->slen + pname->slen + pvalue->slen + 3;\n    p = new_param = (char*) pj_pool_alloc(pool, len);\n    \n    if (param->slen) {\n\tpj_size_t old_len = param->slen;\n\tpj_memcpy(p, param->ptr, old_len);\n\tp += old_len;\n    }\n    *p++ = (char)sepchar;\n    pj_memcpy(p, pname->ptr, pname->slen);\n    p += pname->slen;\n\n    if (pvalue->slen) {\n\t*p++ = '=';\n\tpj_memcpy(p, pvalue->ptr, pvalue->slen);\n\tp += pvalue->slen;\n    }\n\n    *p = '\\0';\n    \n    param->ptr = new_param;\n    param->slen = p - new_param;\n}\n\n/* Initialize static properties of the parser. */\nstatic pj_status_t init_parser()\n{\n    pj_status_t status;\n\n    /*\n     * Syntax error exception number.\n     */\n    pj_assert (PJSIP_SYN_ERR_EXCEPTION == -1);\n    status = pj_exception_id_alloc(\"PJSIP syntax error\", \n\t\t\t\t   &PJSIP_SYN_ERR_EXCEPTION);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    /*\n     * Init character input spec (cis)\n     */\n\n    pj_cis_buf_init(&cis_buf);\n\n    status = pj_cis_init(&cis_buf, &pconst.pjsip_DIGIT_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_num(&pconst.pjsip_DIGIT_SPEC);\n    \n    status = pj_cis_init(&cis_buf, &pconst.pjsip_ALPHA_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_alpha( &pconst.pjsip_ALPHA_SPEC );\n    \n    status = pj_cis_init(&cis_buf, &pconst.pjsip_ALNUM_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_alpha( &pconst.pjsip_ALNUM_SPEC );\n    pj_cis_add_num( &pconst.pjsip_ALNUM_SPEC );\n\n    status = pj_cis_init(&cis_buf, &pconst.pjsip_NOT_NEWLINE);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str(&pconst.pjsip_NOT_NEWLINE, \"\\r\\n\");\n    pj_cis_invert(&pconst.pjsip_NOT_NEWLINE);\n\n    status = pj_cis_init(&cis_buf, &pconst.pjsip_NOT_COMMA_OR_NEWLINE);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str( &pconst.pjsip_NOT_COMMA_OR_NEWLINE, \",\\r\\n\");\n    pj_cis_invert(&pconst.pjsip_NOT_COMMA_OR_NEWLINE);\n\n    status = pj_cis_dup(&pconst.pjsip_TOKEN_SPEC, &pconst.pjsip_ALNUM_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str( &pconst.pjsip_TOKEN_SPEC, TOKEN);\n\n    status = pj_cis_dup(&pconst.pjsip_TOKEN_SPEC_ESC, &pconst.pjsip_TOKEN_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_del_str(&pconst.pjsip_TOKEN_SPEC_ESC, \"%\");\n\n    status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC, &pconst.pjsip_TOKEN_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC, \":\");\n\n    status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC_ESC, &pconst.pjsip_TOKEN_SPEC_ESC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC, \":\");\n\n    status = pj_cis_dup(&pconst.pjsip_HOST_SPEC, &pconst.pjsip_ALNUM_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str( &pconst.pjsip_HOST_SPEC, HOST);\n\n    status = pj_cis_dup(&pconst.pjsip_HEX_SPEC, &pconst.pjsip_DIGIT_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str( &pconst.pjsip_HEX_SPEC, HEX_DIGIT);\n\n    status = pj_cis_dup(&pconst.pjsip_PARAM_CHAR_SPEC, &pconst.pjsip_ALNUM_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str(&pconst.pjsip_PARAM_CHAR_SPEC, PARAM_CHAR);\n\n    status = pj_cis_dup(&pconst.pjsip_PARAM_CHAR_SPEC_ESC, &pconst.pjsip_PARAM_CHAR_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_del_str(&pconst.pjsip_PARAM_CHAR_SPEC_ESC, ESCAPED);\n\n    status = pj_cis_dup(&pconst.pjsip_HDR_CHAR_SPEC, &pconst.pjsip_ALNUM_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str(&pconst.pjsip_HDR_CHAR_SPEC, HDR_CHAR);\n\n    status = pj_cis_dup(&pconst.pjsip_HDR_CHAR_SPEC_ESC, &pconst.pjsip_HDR_CHAR_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_del_str(&pconst.pjsip_HDR_CHAR_SPEC_ESC, ESCAPED);\n\n    status = pj_cis_dup(&pconst.pjsip_USER_SPEC, &pconst.pjsip_ALNUM_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str( &pconst.pjsip_USER_SPEC, UNRESERVED ESCAPED USER_UNRESERVED );\n\n    status = pj_cis_dup(&pconst.pjsip_USER_SPEC_ESC, &pconst.pjsip_USER_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_del_str( &pconst.pjsip_USER_SPEC_ESC, ESCAPED);\n\n    status = pj_cis_dup(&pconst.pjsip_USER_SPEC_LENIENT, &pconst.pjsip_USER_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str(&pconst.pjsip_USER_SPEC_LENIENT, \"#\");\n\n    status = pj_cis_dup(&pconst.pjsip_USER_SPEC_LENIENT_ESC, &pconst.pjsip_USER_SPEC_ESC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str(&pconst.pjsip_USER_SPEC_LENIENT_ESC, \"#\");\n\n    status = pj_cis_dup(&pconst.pjsip_PASSWD_SPEC, &pconst.pjsip_ALNUM_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str( &pconst.pjsip_PASSWD_SPEC, UNRESERVED ESCAPED PASS);\n\n    status = pj_cis_dup(&pconst.pjsip_PASSWD_SPEC_ESC, &pconst.pjsip_PASSWD_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_del_str( &pconst.pjsip_PASSWD_SPEC_ESC, ESCAPED);\n\n    status = pj_cis_init(&cis_buf, &pconst.pjsip_PROBE_USER_HOST_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str( &pconst.pjsip_PROBE_USER_HOST_SPEC, \"@ \\n>\");\n    pj_cis_invert( &pconst.pjsip_PROBE_USER_HOST_SPEC );\n\n    status = pj_cis_init(&cis_buf, &pconst.pjsip_DISPLAY_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str( &pconst.pjsip_DISPLAY_SPEC, \":\\r\\n<\");\n    pj_cis_invert(&pconst.pjsip_DISPLAY_SPEC);\n\n    status = pj_cis_dup(&pconst.pjsip_OTHER_URI_CONTENT, &pconst.pjsip_ALNUM_SPEC);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n    pj_cis_add_str( &pconst.pjsip_OTHER_URI_CONTENT, GENERIC_URI_CHARS);\n\n    /*\n     * Register URI parsers.\n     */\n\n    status = pjsip_register_uri_parser(\"sip\", &int_parse_sip_url);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_uri_parser(\"sips\", &int_parse_sip_url);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    /*\n     * Register header parsers.\n     */\n\n    status = pjsip_register_hdr_parser( \"Accept\", NULL, &parse_hdr_accept);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Allow\", NULL, &parse_hdr_allow);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Call-ID\", \"i\", &parse_hdr_call_id);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Contact\", \"m\", &parse_hdr_contact);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Content-Length\", \"l\", \n                                        &parse_hdr_content_len);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Content-Type\", \"c\", \n                                        &parse_hdr_content_type);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"CSeq\", NULL, &parse_hdr_cseq);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Expires\", NULL, &parse_hdr_expires);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"From\", \"f\", &parse_hdr_from);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Max-Forwards\", NULL, \n                                        &parse_hdr_max_forwards);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Min-Expires\", NULL, \n                                        &parse_hdr_min_expires);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Record-Route\", NULL, &parse_hdr_rr);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Route\", NULL, &parse_hdr_route);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Require\", NULL, &parse_hdr_require);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Retry-After\", NULL, \n                                        &parse_hdr_retry_after);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Supported\", \"k\", \n                                        &parse_hdr_supported);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"To\", \"t\", &parse_hdr_to);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Unsupported\", NULL, \n                                        &parse_hdr_unsupported);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    status = pjsip_register_hdr_parser( \"Via\", \"v\", &parse_hdr_via);\n    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n    /* \n     * Register auth parser. \n     */\n\n    status = pjsip_auth_init_parser();\n\n    return status;\n}\n\nvoid init_sip_parser(void)\n{\n    pj_enter_critical_section();\n    if (++parser_is_initialized == 1) {\n\tinit_parser();\n    }\n    pj_leave_critical_section();\n}\n\nvoid deinit_sip_parser(void)\n{\n    pj_enter_critical_section();\n    if (--parser_is_initialized == 0) {\n\t/* Clear header handlers */\n\tpj_bzero(handler, sizeof(handler));\n\thandler_count = 0;\n\n\t/* Clear URI handlers */\n\tpj_bzero(uri_handler, sizeof(uri_handler));\n\turi_handler_count = 0;\n\n\t/* Deregister exception ID */\n\tpj_exception_id_free(PJSIP_SYN_ERR_EXCEPTION);\n\tPJSIP_SYN_ERR_EXCEPTION = -1;\n    }\n    pj_leave_critical_section();\n}\n\n/* Compare the handler record with header name, and return:\n * - 0  if handler match.\n * - <0 if handler is 'less' than the header name.\n * - >0 if handler is 'greater' than header name.\n */\nPJ_INLINE(int) compare_handler( const handler_rec *r1, \n\t\t\t\tconst char *name, \n\t\t\t\tpj_size_t name_len,\n\t\t\t\tpj_uint32_t hash )\n{\n    PJ_UNUSED_ARG(name_len);\n\n    /* Compare hashed value. */\n    if (r1->hname_hash < hash)\n\treturn -1;\n    if (r1->hname_hash > hash)\n\treturn 1;\n\n    /* Compare length. */\n    /*\n    if (r1->hname_len < name_len)\n\treturn -1;\n    if (r1->hname_len > name_len)\n\treturn 1;\n     */\n\n    /* Equal length and equal hash. compare the strings. */\n    return pj_memcmp(r1->hname, name, name_len);\n}\n\n/* Register one handler for one header name. */\nstatic pj_status_t int_register_parser( const char *name, \n                                        pjsip_parse_hdr_func *fptr )\n{\n    unsigned\tpos;\n    handler_rec rec;\n\n    if (handler_count >= PJ_ARRAY_SIZE(handler)) {\n\tpj_assert(!\"Too many handlers!\");\n\treturn PJ_ETOOMANY;\n    }\n\n    /* Initialize temporary handler. */\n    rec.handler = fptr;\n    rec.hname_len = strlen(name);\n    if (rec.hname_len >= sizeof(rec.hname)) {\n\tpj_assert(!\"Header name is too long!\");\n\treturn PJ_ENAMETOOLONG;\n    }\n    /* Copy name. */\n    pj_memcpy(rec.hname, name, rec.hname_len);\n    rec.hname[rec.hname_len] = '\\0';\n\n    /* Calculate hash value. */\n    rec.hname_hash = pj_hash_calc(0, rec.hname, (unsigned)rec.hname_len);\n\n    /* Get the pos to insert the new handler. */\n    for (pos=0; pos < handler_count; ++pos) {\n\tint d;\n\td = compare_handler(&handler[pos], rec.hname, rec.hname_len, \n                            rec.hname_hash);\n\tif (d == 0) {\n\t    pj_assert(0);\n\t    return PJ_EEXISTS;\n\t}\n\tif (d > 0) {\n\t    break;\n\t}\n    }\n\n    /* Shift handlers. */\n    if (pos != handler_count) {\n\tpj_memmove( &handler[pos+1], &handler[pos], \n                    (handler_count-pos)*sizeof(handler_rec));\n    }\n    /* Add new handler. */\n    pj_memcpy( &handler[pos], &rec, sizeof(handler_rec));\n    ++handler_count;\n\n    return PJ_SUCCESS;\n}\n\n/* Register parser handler. If both header name and short name are valid,\n * then two instances of handler will be registered.\n */\nPJ_DEF(pj_status_t) pjsip_register_hdr_parser( const char *hname,\n\t\t\t\t\t       const char *hshortname,\n\t\t\t\t\t       pjsip_parse_hdr_func *fptr)\n{\n    unsigned i;\n    pj_size_t len;\n    char hname_lcase[PJSIP_MAX_HNAME_LEN+1];\n    pj_status_t status;\n\n    /* Check that name is not too long */\n    len = pj_ansi_strlen(hname);\n    if (len > PJSIP_MAX_HNAME_LEN) {\n\tpj_assert(!\"Header name is too long!\");\n\treturn PJ_ENAMETOOLONG;\n    }\n\n    /* Register the normal Mixed-Case name */\n    status = int_register_parser(hname, fptr);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    /* Get the lower-case name */\n    for (i=0; i<len; ++i) {\n\thname_lcase[i] = (char)pj_tolower(hname[i]);\n    }\n    hname_lcase[len] = '\\0';\n\n    /* Register the lower-case version of the name */\n    status = int_register_parser(hname_lcase, fptr);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n    \n\n    /* Register the shortname version of the name */\n    if (hshortname) {\n        status = int_register_parser(hshortname, fptr);\n        if (status != PJ_SUCCESS) \n\t    return status;\n    }\n    return PJ_SUCCESS;\n}\n\n\n/* Find handler to parse the header name. */\nstatic pjsip_parse_hdr_func * find_handler_imp(pj_uint32_t  hash, \n\t\t\t\t\t       const pj_str_t *hname)\n{\n    handler_rec *first;\n    int\t\t comp;\n    unsigned\t n;\n\n    /* Binary search for the handler. */\n    comp = -1;\n    first = &handler[0];\n    n = handler_count;\n    for (; n > 0; ) {\n\tunsigned half = n / 2;\n\thandler_rec *mid = first + half;\n\n\tcomp = compare_handler(mid, hname->ptr, hname->slen, hash);\n\tif (comp < 0) {\n\t    first = ++mid;\n\t    n -= half + 1;\n\t} else if (comp==0) {\n\t    first = mid;\n\t    break;\n\t} else {\n\t    n = half;\n\t}\n    }\n\n    return comp==0 ? first->handler : NULL;\n}\n\n\n/* Find handler to parse the header name. */\nstatic pjsip_parse_hdr_func* find_handler(const pj_str_t *hname)\n{\n    pj_uint32_t hash;\n    char hname_copy[PJSIP_MAX_HNAME_LEN];\n    pj_str_t tmp;\n    pjsip_parse_hdr_func *func;\n\n    if (hname->slen >= PJSIP_MAX_HNAME_LEN) {\n\t/* Guaranteed not to be able to find handler. */\n        return NULL;\n    }\n\n    /* First, common case, try to find handler with exact name */\n    hash = pj_hash_calc(0, hname->ptr, (unsigned)hname->slen);\n    func = find_handler_imp(hash, hname);\n    if (func)\n\treturn func;\n\n\n    /* If not found, try converting the header name to lowercase and\n     * search again.\n     */\n    hash = pj_hash_calc_tolower(0, hname_copy, hname);\n    tmp.ptr = hname_copy;\n    tmp.slen = hname->slen;\n    return find_handler_imp(hash, &tmp);\n}\n\n\n/* Find URI handler. */\nstatic pjsip_parse_uri_func* find_uri_handler(const pj_str_t *scheme)\n{\n    unsigned i;\n    for (i=0; i<uri_handler_count; ++i) {\n\tif (parser_stricmp(uri_handler[i].scheme, (*scheme))==0)\n\t    return uri_handler[i].parse;\n    }\n    return &int_parse_other_uri;\n}\n\n/* Register URI parser. */\nPJ_DEF(pj_status_t) pjsip_register_uri_parser( char *scheme,\n\t\t\t\t\t       pjsip_parse_uri_func *func)\n{\n    if (uri_handler_count >= PJ_ARRAY_SIZE(uri_handler))\n\treturn PJ_ETOOMANY;\n\n    uri_handler[uri_handler_count].scheme = pj_str((char*)scheme);\n    uri_handler[uri_handler_count].parse = func;\n    ++uri_handler_count;\n\n    return PJ_SUCCESS;\n}\n\n/* Public function to parse SIP message. */\nPJ_DEF(pjsip_msg*) pjsip_parse_msg( pj_pool_t *pool, \n                                    char *buf, pj_size_t size,\n\t\t\t\t    pjsip_parser_err_report *err_list)\n{\n    pjsip_msg *msg = NULL;\n    pj_scanner scanner;\n    pjsip_parse_ctx context;\n\n    pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER, \n                 &on_syntax_error);\n\n    context.scanner = &scanner;\n    context.pool = pool;\n    context.rdata = NULL;\n\n    msg = int_parse_msg(&context, err_list);\n\n    pj_scan_fini(&scanner);\n    return msg;\n}\n\n/* Public function to parse as rdata.*/\nPJ_DEF(pjsip_msg *) pjsip_parse_rdata( char *buf, pj_size_t size,\n                                       pjsip_rx_data *rdata )\n{\n    pj_scanner scanner;\n    pjsip_parse_ctx context;\n\n    pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER, \n                 &on_syntax_error);\n\n    context.scanner = &scanner;\n    context.pool = rdata->tp_info.pool;\n    context.rdata = rdata;\n\n    rdata->msg_info.msg = int_parse_msg(&context, &rdata->msg_info.parse_err);\n\n    pj_scan_fini(&scanner);\n    return rdata->msg_info.msg;\n}\n\n/* Determine if a message has been received. */\nPJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size, \n\t\t\t\t  pj_bool_t is_datagram, pj_size_t *msg_size)\n{\n#if PJ_HAS_TCP\n    const char *hdr_end;\n    const char *body_start;\n    const char *pos;\n    const char *line;\n    int content_length = -1;\n    pj_str_t cur_msg;\n    const pj_str_t end_hdr = { \"\\n\\r\\n\", 3};\n\n    *msg_size = size;\n\n    /* For datagram, the whole datagram IS the message. */\n    if (is_datagram) {\n\treturn PJ_SUCCESS;\n    }\n\n\n    /* Find the end of header area by finding an empty line. \n     * Don't use plain strstr() since we want to be able to handle\n     * NULL character in the message\n     */\n    cur_msg.ptr = (char*)buf; cur_msg.slen = size;\n    pos = pj_strstr(&cur_msg, &end_hdr);\n    if (pos == NULL) {\n\treturn PJSIP_EPARTIALMSG;\n    }\n \n    hdr_end = pos+1;\n    body_start = pos+3;\n\n    /* Find \"Content-Length\" header the hard way. */\n    line = pj_strchr(&cur_msg, '\\n');\n    while (line && line < hdr_end) {\n\t++line;\n\tif ( ((*line=='C' || *line=='c') && \n              strnicmp_alnum(line, \"Content-Length\", 14) == 0) ||\n\t     ((*line=='l' || *line=='L') && \n              (*(line+1)==' ' || *(line+1)=='\\t' || *(line+1)==':')))\n\t{\n\t    /* Try to parse the header. */\n\t    pj_scanner scanner;\n\t    PJ_USE_EXCEPTION;\n\n\t    pj_scan_init(&scanner, (char*)line, hdr_end-line, \n\t\t\t PJ_SCAN_AUTOSKIP_WS_HEADER, &on_syntax_error);\n\n\t    PJ_TRY {\n\t\tpj_str_t str_clen;\n\n\t\t/* Get \"Content-Length\" or \"L\" name */\n\t\tif (*line=='C' || *line=='c')\n\t\t    pj_scan_advance_n(&scanner, 14, PJ_TRUE);\n\t\telse if (*line=='l' || *line=='L')\n\t\t    pj_scan_advance_n(&scanner, 1, PJ_TRUE);\n\n\t\t/* Get colon */\n\t\tif (pj_scan_get_char(&scanner) != ':') {\n\t\t    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n\t\t}\n\n\t\t/* Get number */\n\t\tpj_scan_get(&scanner, &pconst.pjsip_DIGIT_SPEC, &str_clen);\n\n\t\t/* Get newline. */\n\t\tpj_scan_get_newline(&scanner);\n\n\t\t/* Found a valid Content-Length header. */\n\t\tcontent_length = pj_strtoul(&str_clen);\n\t    }\n\t    PJ_CATCH_ANY {\n\t\tcontent_length = -1;\n\t    }\n\t    PJ_END\n\n\t    pj_scan_fini(&scanner);\n\t}\n\n\t/* Found valid Content-Length? */\n\tif (content_length != -1)\n\t    break;\n\n\t/* Go to next line. */\n\tcur_msg.slen -= (line - cur_msg.ptr);\n\tcur_msg.ptr = (char*)line;\n\tline = pj_strchr(&cur_msg, '\\n');\n    }\n\n    /* Found Content-Length? */\n    if (content_length == -1) {\n\treturn PJSIP_EMISSINGHDR;\n    }\n\n    /* Enough packet received? */\n    *msg_size = (body_start - buf) + content_length;\n    return (*msg_size) <= size ? PJ_SUCCESS : PJSIP_EPARTIALMSG;\n#else\n    PJ_UNUSED_ARG(buf);\n    PJ_UNUSED_ARG(is_datagram);\n    *msg_size = size;\n    return PJ_SUCCESS;\n#endif\n}\n\n/* Public function to parse URI */\nPJ_DEF(pjsip_uri*) pjsip_parse_uri( pj_pool_t *pool, \n\t\t\t\t\t char *buf, pj_size_t size,\n\t\t\t\t\t unsigned option)\n{\n    pj_scanner scanner;\n    pjsip_uri *uri = NULL;\n    PJ_USE_EXCEPTION;\n\n    pj_scan_init(&scanner, buf, size, 0, &on_syntax_error);\n\n    \n    PJ_TRY {\n\turi = int_parse_uri_or_name_addr(&scanner, pool, option);\n    }\n    PJ_CATCH_ANY {\n\turi = NULL;\n    }\n    PJ_END;\n\n    /* Must have exhausted all inputs. */\n    if (pj_scan_is_eof(&scanner) || IS_NEWLINE(*scanner.curptr)) {\n\t/* Success. */\n\tpj_scan_fini(&scanner);\n\treturn uri;\n    }\n\n    /* Still have some characters unparsed. */\n    pj_scan_fini(&scanner);\n    return NULL;\n}\n\n/* SIP version */\nstatic void parse_sip_version(pj_scanner *scanner)\n{\n    pj_str_t SIP = { \"SIP\", 3 };\n    pj_str_t V2 = { \"2.0\", 3 };\n    pj_str_t sip, version;\n\n    pj_scan_get( scanner, &pconst.pjsip_ALPHA_SPEC, &sip);\n    if (pj_scan_get_char(scanner) != '/')\n\ton_syntax_error(scanner);\n    pj_scan_get_n( scanner, 3, &version);\n    if (pj_stricmp(&sip, &SIP) || pj_stricmp(&version, &V2))\n\ton_syntax_error(scanner);\n}\n\nstatic pj_bool_t is_next_sip_version(pj_scanner *scanner)\n{\n    pj_str_t SIP = { \"SIP\", 3 };\n    pj_str_t sip;\n    int c;\n\n    c = pj_scan_peek(scanner, &pconst.pjsip_ALPHA_SPEC, &sip);\n    /* return TRUE if it is \"SIP\" followed by \"/\" or space.\n     * we include space since the \"/\" may be separated by space,\n     * although this would mean it would return TRUE if it is a\n     * request and the method is \"SIP\"!\n     */\n    return c && (c=='/' || c==' ' || c=='\\t') && pj_stricmp(&sip, &SIP)==0;\n}\n\n/* Internal function to parse SIP message */\nstatic pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,\n\t\t\t\t pjsip_parser_err_report *err_list)\n{\n    pj_bool_t parsing_headers;\n    pjsip_msg *msg = NULL;\n    pj_str_t hname;\n    pjsip_ctype_hdr *ctype_hdr = NULL;\n    pj_scanner *scanner = ctx->scanner;\n    pj_pool_t *pool = ctx->pool;\n    PJ_USE_EXCEPTION;\n\n    parsing_headers = PJ_FALSE;\n\nretry_parse:\n    PJ_TRY \n    {\n\tif (parsing_headers)\n\t    goto parse_headers;\n\n\t/* Skip leading newlines. */\n\twhile (IS_NEWLINE(*scanner->curptr)) {\n\t    pj_scan_get_newline(scanner);\n\t}\n\n\t/* Check if we still have valid packet.\n\t * Sometimes endpoints just send blank (CRLF) packets just to keep\n\t * NAT bindings open.\n\t */\n\tif (pj_scan_is_eof(scanner))\n\t    return NULL;\n\n\t/* Parse request or status line */\n\tif (is_next_sip_version(scanner)) {\n\t    msg = pjsip_msg_create(pool, PJSIP_RESPONSE_MSG);\n\t    int_parse_status_line( scanner, &msg->line.status );\n\t} else {\n\t    msg = pjsip_msg_create(pool, PJSIP_REQUEST_MSG);\n\t    int_parse_req_line(scanner, pool, &msg->line.req );\n\t}\n\n\tparsing_headers = PJ_TRUE;\n\nparse_headers:\n\t/* Parse headers. */\n\tdo {\n\t    pjsip_parse_hdr_func * func;\n\t    pjsip_hdr *hdr = NULL;\n\n\t    /* Init hname just in case parsing fails.\n\t     * Ref: PROTOS #2412\n\t     */\n\t    hname.slen = 0;\n\t    \n\t    /* Get hname. */\n\t    pj_scan_get( scanner, &pconst.pjsip_TOKEN_SPEC, &hname);\n\t    if (pj_scan_get_char( scanner ) != ':') {\n\t\tPJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n\t    }\n\t    \n\t    /* Find handler. */\n\t    func = find_handler(&hname);\n\t    \n\t    /* Call the handler if found.\n\t     * If no handler is found, then treat the header as generic\n\t     * hname/hvalue pair.\n\t     */\n\t    if (func) {\n\t\thdr = (*func)(ctx);\n\n\t\t/* Note:\n\t\t *  hdr MAY BE NULL, if parsing does not yield a new header\n\t\t *  instance, e.g. the values have been added to existing\n\t\t *  header. See http://trac.pjsip.org/repos/ticket/940\n\t\t */\n\n\t\t/* Check if we've just parsed a Content-Type header. \n\t\t * We will check for a message body if we've got Content-Type \n\t\t * header.\n\t\t */\n\t\tif (hdr && hdr->type == PJSIP_H_CONTENT_TYPE) {\n\t\t    ctype_hdr = (pjsip_ctype_hdr*)hdr;\n\t\t}\n\n\t    } else {\n\t\thdr = parse_hdr_generic_string(ctx);\n\t\thdr->name = hdr->sname = hname;\n\t    }\n\t    \n\t\n\t    /* Single parse of header line can produce multiple headers.\n\t     * For example, if one Contact: header contains Contact list\n\t     * separated by comma, then these Contacts will be split into\n\t     * different Contact headers.\n\t     * So here we must insert list instead of just insert one header.\n\t     */\n\t    if (hdr)\n\t\tpj_list_insert_nodes_before(&msg->hdr, hdr);\n\t    \n\t    /* Parse until EOF or an empty line is found. */\n\t} while (!pj_scan_is_eof(scanner) && !IS_NEWLINE(*scanner->curptr));\n\t\n\tparsing_headers = PJ_FALSE;\n\n\t/* If empty line is found, eat it. */\n\tif (!pj_scan_is_eof(scanner)) {\n\t    if (IS_NEWLINE(*scanner->curptr)) {\n\t\tpj_scan_get_newline(scanner);\n\t    }\n\t}\n\n\t/* If we have Content-Type header, treat the rest of the message \n\t * as body.\n\t */\n\tif (ctype_hdr && scanner->curptr!=scanner->end) {\n\t    /* New: if Content-Type indicates that this is a multipart\n\t     * message body, parse it.\n\t     */\n\t    const pj_str_t STR_MULTIPART = { \"multipart\", 9 };\n\t    pjsip_msg_body *body;\n\n\t    if (pj_stricmp(&ctype_hdr->media.type, &STR_MULTIPART)==0) {\n\t\tbody = pjsip_multipart_parse(pool, scanner->curptr,\n\t\t\t\t\t     scanner->end - scanner->curptr,\n\t\t\t\t\t     &ctype_hdr->media, 0);\n\t    } else {\n\t\tbody = PJ_POOL_ALLOC_T(pool, pjsip_msg_body);\n\t\tpjsip_media_type_cp(pool, &body->content_type,\n\t\t                    &ctype_hdr->media);\n\n\t\tbody->data = scanner->curptr;\n\t\tbody->len = (unsigned)(scanner->end - scanner->curptr);\n\t\tbody->print_body = &pjsip_print_text_body;\n\t\tbody->clone_data = &pjsip_clone_text_data;\n\t    }\n\n\t    msg->body = body;\n\t}\n    }\n    PJ_CATCH_ANY \n    {\n\t/* Exception was thrown during parsing. \n\t * Skip until newline, and parse next header. \n\t */\n\tif (err_list) {\n\t    pjsip_parser_err_report *err_info;\n\t    \n\t    err_info = PJ_POOL_ALLOC_T(pool, pjsip_parser_err_report);\n\t    err_info->except_code = PJ_GET_EXCEPTION();\n\t    err_info->line = scanner->line;\n\t    /* Scanner's column is zero based, so add 1 */\n\t    err_info->col = pj_scan_get_col(scanner) + 1;\n\t    if (parsing_headers)\n\t\terr_info->hname = hname;\n\t    else if (msg && msg->type == PJSIP_REQUEST_MSG)\n\t\terr_info->hname = pj_str(\"Request Line\");\n\t    else if (msg && msg->type == PJSIP_RESPONSE_MSG)\n\t\terr_info->hname = pj_str(\"Status Line\");\n\t    else\n\t\terr_info->hname.slen = 0;\n\t    \n\t    pj_list_insert_before(err_list, err_info);\n\t}\n\t\n\tif (parsing_headers) {\n\t    if (!pj_scan_is_eof(scanner)) {\n\t\t/* Skip until next line.\n\t\t * Watch for header continuation.\n\t\t */\n\t\tdo {\n\t\t    pj_scan_skip_line(scanner);\n\t\t} while (IS_SPACE(*scanner->curptr));\n\t    }\n\n\t    /* Restore flag. Flag may be set in int_parse_sip_url() */\n\t    scanner->skip_ws = PJ_SCAN_AUTOSKIP_WS_HEADER;\n\n\t    /* Continue parse next header, if any. */\n\t    if (!pj_scan_is_eof(scanner) && !IS_NEWLINE(*scanner->curptr)) {\n\t\tgoto retry_parse;\n\t    }\n\t}\n\n\tmsg = NULL;\n    }\n    PJ_END;\n\n    return msg;\n}\n\n\n/* Parse parameter (pname [\"=\" pvalue]). */\nstatic void parse_param_imp( pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t     pj_str_t *pname, pj_str_t *pvalue,\n\t\t\t     const pj_cis_t *spec, const pj_cis_t *esc_spec,\n\t\t\t     unsigned option)\n{\n    /* pname */\n    parser_get_and_unescape(scanner, pool, spec, esc_spec, pname);\n\n    /* init pvalue */\n    pvalue->ptr = NULL;\n    pvalue->slen = 0;\n\n    /* pvalue, if any */\n    if (*scanner->curptr == '=') {\n\tpj_scan_get_char(scanner);\n\tif (!pj_scan_is_eof(scanner)) {\n\t    /* pvalue can be a quoted string. */\n\t    if (*scanner->curptr == '\"') {\n\t\tpj_scan_get_quote( scanner, '\"', '\"', pvalue);\n\t\tif (option & PJSIP_PARSE_REMOVE_QUOTE) {\n\t\t    pvalue->ptr++;\n\t\t    pvalue->slen -= 2;\n\t\t}\n\t    } else if (*scanner->curptr == '[') {\n\t\t/* pvalue can be a quoted IPv6; in this case, the\n\t\t * '[' and ']' quote characters are to be removed\n\t\t * from the pvalue. \n\t\t */\n\t\tpj_scan_get_char(scanner);\n\t\tpj_scan_get_until_ch(scanner, ']', pvalue);\n\t\tpj_scan_get_char(scanner);\n\t    } else if(pj_cis_match(spec, *scanner->curptr)) {\n\t\tparser_get_and_unescape(scanner, pool, spec, esc_spec, pvalue);\n\t    }\n\t}\n    }\n}\n\n/* Parse parameter (pname [\"=\" pvalue]) using token. */\nPJ_DEF(void) pjsip_parse_param_imp(pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t     \t   pj_str_t *pname, pj_str_t *pvalue,\n\t\t\t     \t   unsigned option)\n{\n    parse_param_imp(scanner, pool, pname, pvalue, &pconst.pjsip_TOKEN_SPEC,\n\t\t    &pconst.pjsip_TOKEN_SPEC_ESC, option);\n}\n\n\n/* Parse parameter (pname [\"=\" pvalue]) using paramchar. */\nPJ_DEF(void) pjsip_parse_uri_param_imp( pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t       \t\tpj_str_t *pname, pj_str_t *pvalue,\n\t\t\t       \t\tunsigned option)\n{\n    parse_param_imp(scanner,pool, pname, pvalue, &pconst.pjsip_PARAM_CHAR_SPEC,\n\t\t    &pconst.pjsip_PARAM_CHAR_SPEC_ESC, option);\n}\n\n\n/* Parse parameter (\";\" pname [\"=\" pvalue]) in SIP header. */\nstatic void int_parse_param( pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t     pj_str_t *pname, pj_str_t *pvalue,\n\t\t\t     unsigned option)\n{\n    /* Get ';' character */\n    pj_scan_get_char(scanner);\n\n    /* Get pname and optionally pvalue */\n    pjsip_parse_param_imp(scanner, pool, pname, pvalue, option);\n}\n\n/* Parse parameter (\";\" pname [\"=\" pvalue]) in URI. */\nstatic void int_parse_uri_param( pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t\t pj_str_t *pname, pj_str_t *pvalue,\n\t\t\t\t unsigned option)\n{\n    /* Get ';' character */\n    pj_scan_get_char(scanner);\n\n    /* Get pname and optionally pvalue */\n    pjsip_parse_uri_param_imp(scanner, pool, pname, pvalue, \n\t\t\t      option);\n}\n\n\n/* Parse header parameter. */\nstatic void int_parse_hparam( pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t      pj_str_t *hname, pj_str_t *hvalue )\n{\n    /* Get '?' or '&' character. */\n    pj_scan_get_char(scanner);\n\n    /* hname */\n    parser_get_and_unescape(scanner, pool, &pconst.pjsip_HDR_CHAR_SPEC, \n\t\t\t    &pconst.pjsip_HDR_CHAR_SPEC_ESC, hname);\n\n    /* Init hvalue */\n    hvalue->ptr = NULL;\n    hvalue->slen = 0;\n\n    /* pvalue, if any */\n    if (*scanner->curptr == '=') {\n\tpj_scan_get_char(scanner);\n\tif (!pj_scan_is_eof(scanner) && \n\t    pj_cis_match(&pconst.pjsip_HDR_CHAR_SPEC, *scanner->curptr))\n\t{\n\t    parser_get_and_unescape(scanner, pool, &pconst.pjsip_HDR_CHAR_SPEC,\n\t\t\t\t    &pconst.pjsip_HDR_CHAR_SPEC_ESC, hvalue);\n\t}\n    }\n}\n\n/* Parse host part:\n *   host =  hostname / IPv4address / IPv6reference\n */\nstatic void int_parse_host(pj_scanner *scanner, pj_str_t *host)\n{\n    if (*scanner->curptr == '[') {\n\t/* Note: the '[' and ']' characters are removed from the host */\n\tpj_scan_get_char(scanner);\n\tpj_scan_get_until_ch(scanner, ']', host);\n\tpj_scan_get_char(scanner);\n    } else {\n\tpj_scan_get( scanner, &pconst.pjsip_HOST_SPEC, host);\n    }\n}\n\n/* Parse host:port in URI. */\nstatic void int_parse_uri_host_port( pj_scanner *scanner, \n\t\t\t\t     pj_str_t *host, int *p_port)\n{\n    int_parse_host(scanner, host);\n\n    /* RFC3261 section 19.1.2: host don't need to be unescaped */\n    if (*scanner->curptr == ':') {\n\tpj_str_t port;\n\tpj_scan_get_char(scanner);\n\tpj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &port);\n\t*p_port = pj_strtoul(&port);\n    } else {\n\t*p_port = 0;\n    }\n}\n\n/* Determine if the next token in an URI is a user specification. */\nstatic int int_is_next_user(pj_scanner *scanner)\n{\n    pj_str_t dummy;\n    int is_user;\n\n    /* Find character '@'. If this character exist, then the token\n     * must be a username.\n     */\n    if (pj_scan_peek( scanner, &pconst.pjsip_PROBE_USER_HOST_SPEC, &dummy) == '@')\n\tis_user = 1;\n    else\n\tis_user = 0;\n\n    return is_user;\n}\n\n/* Parse user:pass tokens in an URI. */\nstatic void int_parse_user_pass( pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t\t pj_str_t *user, pj_str_t *pass)\n{\n    parser_get_and_unescape(scanner, pool, &pconst.pjsip_USER_SPEC_LENIENT, \n\t\t\t    &pconst.pjsip_USER_SPEC_LENIENT_ESC, user);\n\n    if ( *scanner->curptr == ':') {\n\tpj_scan_get_char( scanner );\n\tparser_get_and_unescape(scanner, pool, &pconst.pjsip_PASSWD_SPEC,\n\t\t\t\t&pconst.pjsip_PASSWD_SPEC_ESC, pass);\n    } else {\n\tpass->ptr = NULL;\n\tpass->slen = 0;\n    }\n\n    /* Get the '@' */\n    pj_scan_get_char( scanner );\n}\n\n/* Parse all types of URI. */\nstatic pjsip_uri *int_parse_uri_or_name_addr( pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t\t\t      unsigned opt)\n{\n    pjsip_uri *uri;\n    int is_name_addr = 0;\n\n    /* Exhaust any whitespaces. */\n    pj_scan_skip_whitespace(scanner);\n\n    if (*scanner->curptr=='\"' || *scanner->curptr=='<') {\n\turi = (pjsip_uri*)int_parse_name_addr( scanner, pool );\n\tis_name_addr = 1;\n    } else {\n\tpj_str_t scheme;\n\tint next_ch;\n\n\tnext_ch = pj_scan_peek( scanner, &pconst.pjsip_DISPLAY_SPEC, &scheme);\n\n\tif (next_ch==':') {\n\t    pjsip_parse_uri_func *func = find_uri_handler(&scheme);\n\n\t    if (func == NULL) {\n\t\t/* Unsupported URI scheme */\n\t\tPJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n\t    }\n\n\t    uri = (pjsip_uri*)\n\t    \t  (*func)(scanner, pool, \n\t\t\t  (opt & PJSIP_PARSE_URI_IN_FROM_TO_HDR)==0);\n\n\n\t} else {\n\t    uri = (pjsip_uri*)int_parse_name_addr( scanner, pool );\n\t    is_name_addr = 1;\n\t}\n    }\n\n    /* Should we return the URI object as name address? */\n    if (opt & PJSIP_PARSE_URI_AS_NAMEADDR) {\n\tif (is_name_addr == 0) {\n\t    pjsip_name_addr *name_addr;\n\n\t    name_addr = pjsip_name_addr_create(pool);\n\t    name_addr->uri = uri;\n\n\t    uri = (pjsip_uri*)name_addr;\n\t}\n    }\n\n    return uri;\n}\n\n/* Parse URI. */\nstatic pjsip_uri *int_parse_uri(pj_scanner *scanner, pj_pool_t *pool, \n\t\t\t\tpj_bool_t parse_params)\n{\n    /* Bug:\n     * This function should not call back int_parse_name_addr() because\n     * it is called by that function. This would cause stack overflow\n     * with PROTOS test #1223.\n    if (*scanner->curptr=='\"' || *scanner->curptr=='<') {\n\treturn (pjsip_uri*)int_parse_name_addr( scanner, pool );\n    } else {\n    */\n\tpj_str_t scheme;\n\tint colon;\n\tpjsip_parse_uri_func *func;\n\n\t/* Get scheme. */\n\tcolon = pj_scan_peek(scanner, &pconst.pjsip_TOKEN_SPEC, &scheme);\n\tif (colon != ':') {\n\t    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n\t}\n\n\tfunc = find_uri_handler(&scheme);\n\tif (func)  {\n\t    return (pjsip_uri*)(*func)(scanner, pool, parse_params);\n\n\t} else {\n\t    /* Unsupported URI scheme */\n\t    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n\t    UNREACHED({ return NULL; /* Not reached. */ })\n\t}\n\n    /*\n    }\n    */\n}\n\n/* Parse \"sip:\" and \"sips:\" URI. \n * This actually returns (pjsip_sip_uri*) type,\n */\nstatic void* int_parse_sip_url( pj_scanner *scanner, \n\t\t\t\tpj_pool_t *pool,\n\t\t\t\tpj_bool_t parse_params)\n{\n    pj_str_t scheme;\n    pjsip_sip_uri *url = NULL;\n    int colon;\n    int skip_ws = scanner->skip_ws;\n    scanner->skip_ws = 0;\n\n    pj_scan_get(scanner, &pconst.pjsip_TOKEN_SPEC, &scheme);\n    colon = pj_scan_get_char(scanner);\n    if (colon != ':') {\n\tPJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n    }\n\n    if (parser_stricmp(scheme, pconst.pjsip_SIP_STR)==0) {\n\turl = pjsip_sip_uri_create(pool, 0);\n\n    } else if (parser_stricmp(scheme, pconst.pjsip_SIPS_STR)==0) {\n\turl = pjsip_sip_uri_create(pool, 1);\n\n    } else {\n\tPJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n\t/* should not reach here */\n\tUNREACHED({\n\t    pj_assert(0);\n\t    return 0;\n\t})\n    }\n\n    if (int_is_next_user(scanner)) {\n\tint_parse_user_pass(scanner, pool, &url->user, &url->passwd);\n    }\n\n    /* Get host:port */\n    int_parse_uri_host_port(scanner, &url->host, &url->port);\n\n    /* Get URL parameters. */\n    if (parse_params) {\n      while (*scanner->curptr == ';' ) {\n\tpj_str_t pname, pvalue;\n\n\tint_parse_uri_param( scanner, pool, &pname, &pvalue, 0);\n\n\tif (!parser_stricmp(pname, pconst.pjsip_USER_STR) && pvalue.slen) {\n\t    url->user_param = pvalue;\n\n\t} else if (!parser_stricmp(pname, pconst.pjsip_METHOD_STR) && pvalue.slen) {\n\t    url->method_param = pvalue;\n\n\t} else if (!parser_stricmp(pname, pconst.pjsip_TRANSPORT_STR) && pvalue.slen) {\n\t    url->transport_param = pvalue;\n\n\t} else if (!parser_stricmp(pname, pconst.pjsip_TTL_STR) && pvalue.slen) {\n\t    url->ttl_param = pj_strtoul(&pvalue);\n\n\t} else if (!parser_stricmp(pname, pconst.pjsip_MADDR_STR) && pvalue.slen) {\n\t    url->maddr_param = pvalue;\n\n\t} else if (!parser_stricmp(pname, pconst.pjsip_LR_STR)) {\n\t    url->lr_param = 1;\n\n\t} else {\n\t    pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);\n\t    p->name = pname;\n\t    p->value = pvalue;\n\t    pj_list_insert_before(&url->other_param, p);\n\t}\n      }\n    }\n\n    /* Get header params. */\n    if (parse_params && *scanner->curptr == '?') {\n      do {\n\tpjsip_param *param;\n\tparam = PJ_POOL_ALLOC_T(pool, pjsip_param);\n\tint_parse_hparam(scanner, pool, &param->name, &param->value);\n\tpj_list_insert_before(&url->header_param, param);\n      } while (*scanner->curptr == '&');\n    }\n\n    scanner->skip_ws = skip_ws;\n    pj_scan_skip_whitespace(scanner);\n    return url;\n}\n\n/* Parse nameaddr. */\nstatic pjsip_name_addr *int_parse_name_addr( pj_scanner *scanner, \n\t\t\t\t\t     pj_pool_t *pool )\n{\n    int has_bracket;\n    pjsip_name_addr *name_addr;\n\n    name_addr = pjsip_name_addr_create(pool);\n\n    if (*scanner->curptr == '\"') {\n\tpj_scan_get_quote( scanner, '\"', '\"', &name_addr->display);\n\t/* Trim the leading and ending quote */\n\tname_addr->display.ptr++;\n\tname_addr->display.slen -= 2;\n\n    } else if (*scanner->curptr != '<') {\n\tint next;\n\tpj_str_t dummy;\n\n\t/* This can be either the start of display name,\n\t * the start of URL (\"sip:\", \"sips:\", \"tel:\", etc.), or '<' char.\n\t * We're only interested in display name, because SIP URL\n\t * will be parser later.\n\t */\n\tnext = pj_scan_peek(scanner, &pconst.pjsip_DISPLAY_SPEC, &dummy);\n\tif (next == '<') {\n\t    /* Ok, this is what we're looking for, a display name. */\n\t    pj_scan_get_until_ch( scanner, '<', &name_addr->display);\n\t    pj_strtrim(&name_addr->display);\n\t}\n    }\n\n    /* Manually skip whitespace. */\n    pj_scan_skip_whitespace(scanner);\n\n    /* Get the SIP-URL */\n    has_bracket = (*scanner->curptr == '<');\n    if (has_bracket) {\n\tpj_scan_get_char(scanner);\n    } else if (name_addr->display.slen) {\n\t/* Must have bracket now (2012-10-26).\n\t * Allowing (invalid) name-addr to pass URI verification will\n\t * cause us to send invalid URI to the wire.\n\t */\n\tPJ_THROW( PJSIP_SYN_ERR_EXCEPTION);\n    }\n    name_addr->uri = int_parse_uri( scanner, pool, PJ_TRUE );\n    if (has_bracket) {\n\tif (pj_scan_get_char(scanner) != '>')\n\t    PJ_THROW( PJSIP_SYN_ERR_EXCEPTION);\n    }\n\n    return name_addr;\n}\n\n\n/* Parse other URI */\nstatic void* int_parse_other_uri(pj_scanner *scanner, \n\t\t\t\t pj_pool_t *pool,\n\t\t\t\t pj_bool_t parse_params)\n{\n    pjsip_other_uri *uri = 0;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n    int skip_ws = scanner->skip_ws;\n\n    PJ_UNUSED_ARG(parse_params);\n\n    scanner->skip_ws = 0;\n    \n    uri = pjsip_other_uri_create(pool); \n    \n    pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &uri->scheme);\n    if (pj_scan_get_char(scanner) != ':') {\n\tPJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n    }\n    \n    pj_scan_get(scanner, &pc->pjsip_OTHER_URI_CONTENT, &uri->content);\n    scanner->skip_ws = skip_ws;\n    \n    return uri;\n}\n\n\n/* Parse SIP request line. */\nstatic void int_parse_req_line( pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t\tpjsip_request_line *req_line)\n{\n    pj_str_t token;\n\n    pj_scan_get( scanner, &pconst.pjsip_TOKEN_SPEC, &token);\n    pjsip_method_init_np( &req_line->method, &token);\n\n    req_line->uri = int_parse_uri(scanner, pool, PJ_TRUE);\n    parse_sip_version(scanner);\n    pj_scan_get_newline( scanner );\n}\n\n/* Parse status line. */\nstatic void int_parse_status_line( pj_scanner *scanner, \n\t\t\t\t   pjsip_status_line *status_line)\n{\n    pj_str_t token;\n\n    parse_sip_version(scanner);\n    pj_scan_get( scanner, &pconst.pjsip_DIGIT_SPEC, &token);\n    status_line->code = pj_strtoul(&token);\n    if (*scanner->curptr != '\\r' && *scanner->curptr != '\\n')\n\tpj_scan_get( scanner, &pconst.pjsip_NOT_NEWLINE, &status_line->reason);\n    else\n\tstatus_line->reason.slen=0, status_line->reason.ptr=NULL;\n    pj_scan_get_newline( scanner );\n}\n\n\n/*\n * Public API to parse SIP status line.\n */\nPJ_DEF(pj_status_t) pjsip_parse_status_line( char *buf, pj_size_t size,\n\t\t\t\t\t     pjsip_status_line *status_line)\n{\n    pj_scanner scanner;\n    PJ_USE_EXCEPTION;\n\n    pj_bzero(status_line, sizeof(*status_line));\n    pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER, \n\t\t &on_syntax_error);\n\n    PJ_TRY {\n\tint_parse_status_line(&scanner, status_line);\n    } \n    PJ_CATCH_ANY {\n\t/* Tolerate the error if it is caused only by missing newline */\n\tif (status_line->code == 0 && status_line->reason.slen == 0) {\n\t    pj_scan_fini(&scanner);\n\t    return PJSIP_EINVALIDMSG;\n\t}\n    }\n    PJ_END;\n\n    pj_scan_fini(&scanner);\n    return PJ_SUCCESS;\n}\n\n\n/* Parse ending of header. */\nstatic void parse_hdr_end( pj_scanner *scanner )\n{\n    if (pj_scan_is_eof(scanner)) {\n\t;   /* Do nothing. */\n    } else if (*scanner->curptr == '&') {\n\tpj_scan_get_char(scanner);\n    } else {\n\tpj_scan_get_newline(scanner);\n    }\n}\n\n/* Parse ending of header. */\nPJ_DEF(void) pjsip_parse_end_hdr_imp( pj_scanner *scanner )\n{\n    parse_hdr_end(scanner);\n}\n\n/* Parse generic array header. */\nstatic void parse_generic_array_hdr( pjsip_generic_array_hdr *hdr,\n\t\t\t\t     pj_scanner *scanner)\n{\n    /* Some header fields allow empty elements in the value:\n     *   Accept, Allow, Supported\n     */\n    if (pj_scan_is_eof(scanner) || \n\t*scanner->curptr == '\\r' || *scanner->curptr == '\\n') \n    {\n\tgoto end;\n    }\n\n    if (hdr->count >= PJ_ARRAY_SIZE(hdr->values)) {\n\t/* Too many elements */\n\ton_syntax_error(scanner);\n\treturn;\n    }\n\n    pj_scan_get( scanner, &pconst.pjsip_NOT_COMMA_OR_NEWLINE, \n\t\t &hdr->values[hdr->count]);\n    hdr->count++;\n\n    while ((hdr->count < PJSIP_GENERIC_ARRAY_MAX_COUNT) &&\n    \t   (*scanner->curptr == ','))\n    {\n\tpj_scan_get_char(scanner);\n\tpj_scan_get( scanner, &pconst.pjsip_NOT_COMMA_OR_NEWLINE, \n\t\t     &hdr->values[hdr->count]);\n\thdr->count++;\n    }\n\nend:\n    parse_hdr_end(scanner);\n}\n\n/* Parse generic array header. */\nPJ_DEF(void) pjsip_parse_generic_array_hdr_imp( pjsip_generic_array_hdr *hdr,\n\t\t\t\t\t\tpj_scanner *scanner)\n{\n    parse_generic_array_hdr(hdr, scanner);\n}\n\n\n/* Parse generic string header. */\nstatic void parse_generic_string_hdr( pjsip_generic_string_hdr *hdr,\n\t\t\t\t      pjsip_parse_ctx *ctx)\n{\n    pj_scanner *scanner = ctx->scanner;\n\n    hdr->hvalue.slen = 0;\n\n    /* header may be mangled hence the loop */\n    while (pj_cis_match(&pconst.pjsip_NOT_NEWLINE, *scanner->curptr)) {\n\tpj_str_t next, tmp;\n\n\tpj_scan_get( scanner, &pconst.pjsip_NOT_NEWLINE, &hdr->hvalue);\n\tif (pj_scan_is_eof(scanner) || IS_NEWLINE(*scanner->curptr))\n\t    break;\n\t/* mangled, get next fraction */\n\tpj_scan_get( scanner, &pconst.pjsip_NOT_NEWLINE, &next);\n\t/* concatenate */\n\ttmp.ptr = (char*)pj_pool_alloc(ctx->pool, \n\t\t\t\t       hdr->hvalue.slen + next.slen + 2);\n\ttmp.slen = 0;\n\tpj_strcpy(&tmp, &hdr->hvalue);\n\tpj_strcat2(&tmp, \" \");\n\tpj_strcat(&tmp, &next);\n\ttmp.ptr[tmp.slen] = '\\0';\n\n\thdr->hvalue = tmp;\n    }\n\n    parse_hdr_end(scanner);\n}\n\n/* Parse generic integer header. */\nstatic void parse_generic_int_hdr( pjsip_generic_int_hdr *hdr,\n\t\t\t\t   pj_scanner *scanner )\n{\n    pj_str_t tmp;\n    pj_scan_get( scanner, &pconst.pjsip_DIGIT_SPEC, &tmp);\n    hdr->ivalue = pj_strtoul(&tmp);\n    parse_hdr_end(scanner);\n}\n\n\n/* Parse Accept header. */\nstatic pjsip_hdr* parse_hdr_accept(pjsip_parse_ctx *ctx)\n{\n    pjsip_accept_hdr *accept = pjsip_accept_hdr_create(ctx->pool);\n    parse_generic_array_hdr(accept, ctx->scanner);\n    return (pjsip_hdr*)accept;\n}\n\n/* Parse Allow header. */\nstatic pjsip_hdr* parse_hdr_allow(pjsip_parse_ctx *ctx)\n{\n    pjsip_allow_hdr *allow = pjsip_allow_hdr_create(ctx->pool);\n    parse_generic_array_hdr(allow, ctx->scanner);\n    return (pjsip_hdr*)allow;\n}\n\n/* Parse Call-ID header. */\nstatic pjsip_hdr* parse_hdr_call_id(pjsip_parse_ctx *ctx)\n{\n    pjsip_cid_hdr *hdr = pjsip_cid_hdr_create(ctx->pool);\n    pj_scan_get( ctx->scanner, &pconst.pjsip_NOT_NEWLINE, &hdr->id);\n    parse_hdr_end(ctx->scanner);\n\n    if (ctx->rdata)\n        ctx->rdata->msg_info.cid = hdr;\n\n    return (pjsip_hdr*)hdr;\n}\n\n/* Parse and interpret Contact param. */\nstatic void int_parse_contact_param( pjsip_contact_hdr *hdr, \n\t\t\t\t     pj_scanner *scanner,\n\t\t\t\t     pj_pool_t *pool)\n{\n    while ( *scanner->curptr == ';' ) {\n\tpj_str_t pname, pvalue;\n\n\tint_parse_param( scanner, pool, &pname, &pvalue, 0);\n\tif (!parser_stricmp(pname, pconst.pjsip_Q_STR) && pvalue.slen) {\n\t    char *dot_pos = (char*) pj_memchr(pvalue.ptr, '.', pvalue.slen);\n\t    if (!dot_pos) {\n\t\thdr->q1000 = pj_strtoul(&pvalue) * 1000;\n\t    } else {\n\t\tpj_str_t tmp = pvalue;\n\n\t\ttmp.slen = dot_pos - pvalue.ptr;\n\t\thdr->q1000 = pj_strtoul(&tmp) * 1000;\n\n\t\tpvalue.slen = (pvalue.ptr+pvalue.slen) - (dot_pos+1);\n\t\tpvalue.ptr = dot_pos + 1;\n\t\thdr->q1000 += pj_strtoul_mindigit(&pvalue, 3);\n\t    }    \n\t} else if (!parser_stricmp(pname, pconst.pjsip_EXPIRES_STR) && pvalue.slen) {\n\t    hdr->expires = pj_strtoul(&pvalue);\n\n\t} else {\n\t    pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);\n\t    p->name = pname;\n\t    p->value = pvalue;\n\t    pj_list_insert_before(&hdr->other_param, p);\n\t}\n    }\n}\n\n/* Parse Contact header. */\nstatic pjsip_hdr* parse_hdr_contact( pjsip_parse_ctx *ctx )\n{\n    pjsip_contact_hdr *first = NULL;\n    pj_scanner *scanner = ctx->scanner;\n    \n    do {\n\tpjsip_contact_hdr *hdr = pjsip_contact_hdr_create(ctx->pool);\n\tif (first == NULL)\n\t    first = hdr;\n\telse\n\t    pj_list_insert_before(first, hdr);\n\n\tif (*scanner->curptr == '*') {\n\t    pj_scan_get_char(scanner);\n\t    hdr->star = 1;\n\n\t} else {\n\t    hdr->star = 0;\n\t    hdr->uri = int_parse_uri_or_name_addr(scanner, ctx->pool, \n                                                  PJSIP_PARSE_URI_AS_NAMEADDR |\n\t\t\t\t\t\t  PJSIP_PARSE_URI_IN_FROM_TO_HDR);\n\n\t    int_parse_contact_param(hdr, scanner, ctx->pool);\n\t}\n\n\tif (*scanner->curptr != ',')\n\t    break;\n\n\tpj_scan_get_char(scanner);\n\n    } while (1);\n\n    parse_hdr_end(scanner);\n\n    return (pjsip_hdr*)first;\n}\n\n/* Parse Content-Length header. */\nstatic pjsip_hdr* parse_hdr_content_len( pjsip_parse_ctx *ctx )\n{\n    pj_str_t digit;\n    pjsip_clen_hdr *hdr;\n\n    hdr = pjsip_clen_hdr_create(ctx->pool);\n    pj_scan_get(ctx->scanner, &pconst.pjsip_DIGIT_SPEC, &digit);\n    hdr->len = pj_strtoul(&digit);\n    parse_hdr_end(ctx->scanner);\n\n    if (ctx->rdata)\n        ctx->rdata->msg_info.clen = hdr;\n\n    return (pjsip_hdr*)hdr;\n}\n\n/* Parse Content-Type header. */\nstatic pjsip_hdr* parse_hdr_content_type( pjsip_parse_ctx *ctx )\n{\n    pjsip_ctype_hdr *hdr;\n    pj_scanner *scanner = ctx->scanner;\n\n    hdr = pjsip_ctype_hdr_create(ctx->pool);\n    \n    /* Parse media type and subtype. */\n    pj_scan_get(scanner, &pconst.pjsip_TOKEN_SPEC, &hdr->media.type);\n    pj_scan_get_char(scanner);\n    pj_scan_get(scanner, &pconst.pjsip_TOKEN_SPEC, &hdr->media.subtype);\n\n    /* Parse media parameters */\n    while (*scanner->curptr == ';') {\n\tpjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);\n\tint_parse_param(scanner, ctx->pool, &param->name, &param->value, 0);\n\tpj_list_push_back(&hdr->media.param, param);\n    }\n\n    parse_hdr_end(ctx->scanner);\n\n    if (ctx->rdata)\n        ctx->rdata->msg_info.ctype = hdr;\n\n    return (pjsip_hdr*)hdr;\n}\n\n/* Parse CSeq header. */\nstatic pjsip_hdr* parse_hdr_cseq( pjsip_parse_ctx *ctx )\n{\n    pj_str_t cseq, method;\n    pjsip_cseq_hdr *hdr;\n\n    hdr = pjsip_cseq_hdr_create(ctx->pool);\n    pj_scan_get( ctx->scanner, &pconst.pjsip_DIGIT_SPEC, &cseq);\n    hdr->cseq = pj_strtoul(&cseq);\n\n    pj_scan_get( ctx->scanner, &pconst.pjsip_TOKEN_SPEC, &method);\n    pjsip_method_init_np(&hdr->method, &method);\n\n    parse_hdr_end( ctx->scanner );\n\n    if (ctx->rdata)\n        ctx->rdata->msg_info.cseq = hdr;\n\n    return (pjsip_hdr*)hdr;\n}\n\n/* Parse Expires header. */\nstatic pjsip_hdr* parse_hdr_expires(pjsip_parse_ctx *ctx)\n{\n    pjsip_expires_hdr *hdr = pjsip_expires_hdr_create(ctx->pool, 0);\n    parse_generic_int_hdr(hdr, ctx->scanner);\n    return (pjsip_hdr*)hdr;\n}\n\n/* Parse From: or To: header. */\nstatic void parse_hdr_fromto( pj_scanner *scanner, \n\t\t\t      pj_pool_t *pool, \n\t\t\t      pjsip_from_hdr *hdr)\n{\n    hdr->uri = int_parse_uri_or_name_addr(scanner, pool, \n\t\t\t\t\t  PJSIP_PARSE_URI_AS_NAMEADDR |\n\t\t\t\t\t  PJSIP_PARSE_URI_IN_FROM_TO_HDR);\n\n    while ( *scanner->curptr == ';' ) {\n\tpj_str_t pname, pvalue;\n\n\tint_parse_param( scanner, pool, &pname, &pvalue, 0);\n\n\tif (!parser_stricmp(pname, pconst.pjsip_TAG_STR)) {\n\t    hdr->tag = pvalue;\n\t    \n\t} else {\n\t    pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);\n\t    p->name = pname;\n\t    p->value = pvalue;\n\t    pj_list_insert_before(&hdr->other_param, p);\n\t}\n    }\n\n    parse_hdr_end(scanner);\n}\n\n/* Parse From: header. */\nstatic pjsip_hdr* parse_hdr_from( pjsip_parse_ctx *ctx )\n{\n    pjsip_from_hdr *hdr = pjsip_from_hdr_create(ctx->pool);\n    parse_hdr_fromto(ctx->scanner, ctx->pool, hdr);\n    if (ctx->rdata)\n        ctx->rdata->msg_info.from = hdr;\n\n    return (pjsip_hdr*)hdr;\n}\n\n/* Parse Require: header. */\nstatic pjsip_hdr* parse_hdr_require( pjsip_parse_ctx *ctx )\n{\n    pjsip_require_hdr *hdr;\n    pj_bool_t new_hdr = (ctx->rdata==NULL ||\n\t\t\t ctx->rdata->msg_info.require == NULL);\n    \n    if (ctx->rdata && ctx->rdata->msg_info.require) {\n\thdr = ctx->rdata->msg_info.require;\n    } else {\n\thdr = pjsip_require_hdr_create(ctx->pool);\n\tif (ctx->rdata)\n\t    ctx->rdata->msg_info.require = hdr;\n    }\n\n    parse_generic_array_hdr(hdr, ctx->scanner);\n\n    return new_hdr ? (pjsip_hdr*)hdr : NULL;\n}\n\n/* Parse Retry-After: header. */\nstatic pjsip_hdr* parse_hdr_retry_after(pjsip_parse_ctx *ctx)\n{\n    pjsip_retry_after_hdr *hdr;\n    pj_scanner *scanner = ctx->scanner;\n    pj_str_t tmp;\n\n    hdr = pjsip_retry_after_hdr_create(ctx->pool, 0);\n    \n    pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &tmp);\n    hdr->ivalue = pj_strtoul(&tmp);\n\n    while (!pj_scan_is_eof(scanner) && *scanner->curptr!='\\r' &&\n\t   *scanner->curptr!='\\n')\n    {\n\tif (*scanner->curptr=='(') {\n\t    pj_scan_get_quote(scanner, '(', ')', &hdr->comment);\n\t    /* Trim the leading and ending parens */\n\t    hdr->comment.ptr++;\n\t    hdr->comment.slen -= 2;\n\t} else if (*scanner->curptr==';') {\n\t    pjsip_param *prm = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);\n\t    int_parse_param(scanner, ctx->pool, &prm->name, &prm->value, 0);\n\t    pj_list_push_back(&hdr->param, prm);\n\t} else {\n\t    on_syntax_error(scanner);\n\t}\n    }\n\n    parse_hdr_end(scanner);\n    return (pjsip_hdr*)hdr;\n}\n\n/* Parse Supported: header. */\nstatic pjsip_hdr* parse_hdr_supported(pjsip_parse_ctx *ctx)\n{\n    pjsip_supported_hdr *hdr;\n    pj_bool_t new_hdr = (ctx->rdata==NULL || \n\t\t         ctx->rdata->msg_info.supported == NULL);\n\n    if (ctx->rdata && ctx->rdata->msg_info.supported) {\n\thdr = ctx->rdata->msg_info.supported;\n    } else {\n\thdr = pjsip_supported_hdr_create(ctx->pool);\n\tif (ctx->rdata)\n\t    ctx->rdata->msg_info.supported = hdr;\n    }\n\n    parse_generic_array_hdr(hdr, ctx->scanner);\n    return new_hdr ? (pjsip_hdr*)hdr : NULL;\n}\n\n/* Parse To: header. */\nstatic pjsip_hdr* parse_hdr_to( pjsip_parse_ctx *ctx )\n{\n    pjsip_to_hdr *hdr = pjsip_to_hdr_create(ctx->pool);\n    parse_hdr_fromto(ctx->scanner, ctx->pool, hdr);\n\n    if (ctx->rdata)\n        ctx->rdata->msg_info.to = hdr;\n\n    return (pjsip_hdr*)hdr;\n}\n\n/* Parse Unsupported: header. */\nstatic pjsip_hdr* parse_hdr_unsupported(pjsip_parse_ctx *ctx)\n{\n    pjsip_unsupported_hdr *hdr = pjsip_unsupported_hdr_create(ctx->pool);\n    parse_generic_array_hdr(hdr, ctx->scanner);\n    return (pjsip_hdr*)hdr;\n}\n\n/* Parse and interpret Via parameters. */\nstatic void int_parse_via_param( pjsip_via_hdr *hdr, pj_scanner *scanner,\n\t\t\t\t pj_pool_t *pool)\n{\n    while ( *scanner->curptr == ';' ) {\n\tpj_str_t pname, pvalue;\n\n\t//Parse with PARAM_CHAR instead, to allow IPv6\n\t//No, back to using int_parse_param() for the \"`\" character!\n\t//int_parse_param( scanner, pool, &pname, &pvalue, 0);\n\t//parse_param_imp(scanner, pool, &pname, &pvalue, \n\t//\t\t&pconst.pjsip_TOKEN_SPEC,\n\t//\t\t&pconst.pjsip_TOKEN_SPEC_ESC, 0);\n\t//int_parse_param(scanner, pool, &pname, &pvalue, 0);\n\t// This should be the correct one:\n\t//  added special spec for Via parameter, basically token plus\n\t//  \":\" to allow IPv6 address in the received param.\n\tpj_scan_get_char(scanner);\n\tparse_param_imp(scanner, pool, &pname, &pvalue,\n\t\t\t&pconst.pjsip_VIA_PARAM_SPEC,\n\t\t\t&pconst.pjsip_VIA_PARAM_SPEC_ESC,\n\t\t\t0);\n\n\tif (!parser_stricmp(pname, pconst.pjsip_BRANCH_STR) && pvalue.slen) {\n\t    hdr->branch_param = pvalue;\n\n\t} else if (!parser_stricmp(pname, pconst.pjsip_TTL_STR) && pvalue.slen) {\n\t    hdr->ttl_param = pj_strtoul(&pvalue);\n\t    \n\t} else if (!parser_stricmp(pname, pconst.pjsip_MADDR_STR) && pvalue.slen) {\n\t    hdr->maddr_param = pvalue;\n\n\t} else if (!parser_stricmp(pname, pconst.pjsip_RECEIVED_STR) && pvalue.slen) {\n\t    hdr->recvd_param = pvalue;\n\n\t} else if (!parser_stricmp(pname, pconst.pjsip_RPORT_STR)) {\n\t    if (pvalue.slen)\n\t\thdr->rport_param = pj_strtoul(&pvalue);\n\t    else\n\t\thdr->rport_param = 0;\n\t} else {\n\t    pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);\n\t    p->name = pname;\n\t    p->value = pvalue;\n\t    pj_list_insert_before(&hdr->other_param, p);\n\t}\n    }\n}\n\n/* Parse Max-Forwards header. */\nstatic pjsip_hdr* parse_hdr_max_forwards( pjsip_parse_ctx *ctx )\n{\n    pjsip_max_fwd_hdr *hdr;\n    hdr = pjsip_max_fwd_hdr_create(ctx->pool, 0);\n    parse_generic_int_hdr(hdr, ctx->scanner);\n\n    if (ctx->rdata)\n        ctx->rdata->msg_info.max_fwd = hdr;\n\n    return (pjsip_hdr*)hdr;\n}\n\n/* Parse Min-Expires header. */\nstatic pjsip_hdr* parse_hdr_min_expires(pjsip_parse_ctx *ctx)\n{\n    pjsip_min_expires_hdr *hdr;\n    hdr = pjsip_min_expires_hdr_create(ctx->pool, 0);\n    parse_generic_int_hdr(hdr, ctx->scanner);\n    return (pjsip_hdr*)hdr;\n}\n\n\n/* Parse Route: or Record-Route: header. */\nstatic void parse_hdr_rr_route( pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t\tpjsip_routing_hdr *hdr )\n{\n    pjsip_name_addr *temp=int_parse_name_addr(scanner, pool);\n\n    pj_memcpy(&hdr->name_addr, temp, sizeof(*temp));\n\n    while (*scanner->curptr == ';') {\n\tpjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);\n\tint_parse_param(scanner, pool, &p->name, &p->value, 0);\n\tpj_list_insert_before(&hdr->other_param, p);\n    }\n}\n\n/* Parse Record-Route header. */\nstatic pjsip_hdr* parse_hdr_rr( pjsip_parse_ctx *ctx)\n{\n    pjsip_rr_hdr *first = NULL;\n    pj_scanner *scanner = ctx->scanner;\n\n    do {\n\tpjsip_rr_hdr *hdr = pjsip_rr_hdr_create(ctx->pool);\n\tif (!first) {\n\t    first = hdr;\n\t} else {\n\t    pj_list_insert_before(first, hdr);\n\t}\n\tparse_hdr_rr_route(scanner, ctx->pool, hdr);\n\tif (*scanner->curptr == ',') {\n\t    pj_scan_get_char(scanner);\n\t} else {\n\t    break;\n\t}\n    } while (1);\n    parse_hdr_end(scanner);\n\n    if (ctx->rdata && ctx->rdata->msg_info.record_route==NULL)\n        ctx->rdata->msg_info.record_route = first;\n\n    return (pjsip_hdr*)first;\n}\n\n/* Parse Route: header. */\nstatic pjsip_hdr* parse_hdr_route( pjsip_parse_ctx *ctx )\n{\n    pjsip_route_hdr *first = NULL;\n    pj_scanner *scanner = ctx->scanner;\n\n    do {\n\tpjsip_route_hdr *hdr = pjsip_route_hdr_create(ctx->pool);\n\tif (!first) {\n\t    first = hdr;\n\t} else {\n\t    pj_list_insert_before(first, hdr);\n\t}\n\tparse_hdr_rr_route(scanner, ctx->pool, hdr);\n\tif (*scanner->curptr == ',') {\n\t    pj_scan_get_char(scanner);\n\t} else {\n\t    break;\n\t}\n    } while (1);\n    parse_hdr_end(scanner);\n\n    if (ctx->rdata && ctx->rdata->msg_info.route==NULL)\n        ctx->rdata->msg_info.route = first;\n\n    return (pjsip_hdr*)first;\n}\n\n/* Parse Via: header. */\nstatic pjsip_hdr* parse_hdr_via( pjsip_parse_ctx *ctx )\n{\n    pjsip_via_hdr *first = NULL;\n    pj_scanner *scanner = ctx->scanner;\n\n    do {\n\tpjsip_via_hdr *hdr = pjsip_via_hdr_create(ctx->pool);\n\tif (!first)\n\t    first = hdr;\n\telse\n\t    pj_list_insert_before(first, hdr);\n\n\tparse_sip_version(scanner);\n\tif (pj_scan_get_char(scanner) != '/')\n\t    on_syntax_error(scanner);\n\n\tpj_scan_get( scanner, &pconst.pjsip_TOKEN_SPEC, &hdr->transport);\n\tint_parse_host(scanner, &hdr->sent_by.host);\n\n\tif (*scanner->curptr==':') {\n\t    pj_str_t digit;\n\t    pj_scan_get_char(scanner);\n\t    pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &digit);\n\t    hdr->sent_by.port = pj_strtoul(&digit);\n\t}\n\t\n\tint_parse_via_param(hdr, scanner, ctx->pool);\n\n\tif (*scanner->curptr == '(') {\n\t    pj_scan_get_char(scanner);\n\t    pj_scan_get_until_ch( scanner, ')', &hdr->comment);\n\t    pj_scan_get_char( scanner );\n\t}\n\n\tif (*scanner->curptr != ',')\n\t    break;\n\n\tpj_scan_get_char(scanner);\n\n    } while (1);\n\n    parse_hdr_end(scanner);\n\n    if (ctx->rdata && ctx->rdata->msg_info.via == NULL)\n        ctx->rdata->msg_info.via = first;\n\n    return (pjsip_hdr*)first;\n}\n\n/* Parse generic header. */\nstatic pjsip_hdr* parse_hdr_generic_string( pjsip_parse_ctx *ctx )\n{\n    pjsip_generic_string_hdr *hdr;\n\n    hdr = pjsip_generic_string_hdr_create(ctx->pool, NULL, NULL);\n    parse_generic_string_hdr(hdr, ctx);\n    return (pjsip_hdr*)hdr;\n\n}\n\n/* Public function to parse a header value. */\nPJ_DEF(void*) pjsip_parse_hdr( pj_pool_t *pool, const pj_str_t *hname,\n\t\t\t       char *buf, pj_size_t size, int *parsed_len )\n{\n    pj_scanner scanner;\n    pjsip_hdr *hdr = NULL;\n    pjsip_parse_ctx context;\n    PJ_USE_EXCEPTION;\n\n    pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER, \n                 &on_syntax_error);\n\n    context.scanner = &scanner;\n    context.pool = pool;\n    context.rdata = NULL;\n\n    PJ_TRY {\n\tpjsip_parse_hdr_func *func = find_handler(hname);\n\tif (func) {\n\t    hdr = (*func)(&context);\n\t} else {\n\t    hdr = parse_hdr_generic_string(&context);\n\t    hdr->type = PJSIP_H_OTHER;\n\t    pj_strdup(pool, &hdr->name, hname);\n\t    hdr->sname = hdr->name;\n\t}\n\n    } \n    PJ_CATCH_ANY {\n\thdr = NULL;\n    }\n    PJ_END\n\n    if (parsed_len) {\n\t*parsed_len = (unsigned)(scanner.curptr - scanner.begin);\n    }\n\n    pj_scan_fini(&scanner);\n\n    return hdr;\n}\n\n/* Parse multiple header lines */\nPJ_DEF(pj_status_t) pjsip_parse_headers( pj_pool_t *pool, char *input,\n\t\t\t\t         pj_size_t size, pjsip_hdr *hlist,\n\t\t\t\t         unsigned options)\n{\n    enum { STOP_ON_ERROR = 1 };\n    pj_scanner scanner;\n    pjsip_parse_ctx ctx;\n    pj_str_t hname;\n    PJ_USE_EXCEPTION;\n\n    pj_scan_init(&scanner, input, size, PJ_SCAN_AUTOSKIP_WS_HEADER,\n                 &on_syntax_error);\n\n    pj_bzero(&ctx, sizeof(ctx));\n    ctx.scanner = &scanner;\n    ctx.pool = pool;\n\nretry_parse:\n    PJ_TRY\n    {\n\t/* Parse headers. */\n\tdo {\n\t    pjsip_parse_hdr_func * func;\n\t    pjsip_hdr *hdr = NULL;\n\n\t    /* Init hname just in case parsing fails.\n\t     * Ref: PROTOS #2412\n\t     */\n\t    hname.slen = 0;\n\n\t    /* Get hname. */\n\t    pj_scan_get( &scanner, &pconst.pjsip_TOKEN_SPEC, &hname);\n\t    if (pj_scan_get_char( &scanner ) != ':') {\n\t\tPJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n\t    }\n\n\t    /* Find handler. */\n\t    func = find_handler(&hname);\n\n\t    /* Call the handler if found.\n\t     * If no handler is found, then treat the header as generic\n\t     * hname/hvalue pair.\n\t     */\n\t    if (func) {\n\t\thdr = (*func)(&ctx);\n\t    } else {\n\t\thdr = parse_hdr_generic_string(&ctx);\n\t\thdr->name = hdr->sname = hname;\n\t    }\n\n\t    /* Single parse of header line can produce multiple headers.\n\t     * For example, if one Contact: header contains Contact list\n\t     * separated by comma, then these Contacts will be split into\n\t     * different Contact headers.\n\t     * So here we must insert list instead of just insert one header.\n\t     */\n\t    if (hdr)\n\t\tpj_list_insert_nodes_before(hlist, hdr);\n\n\t    /* Parse until EOF or an empty line is found. */\n\t} while (!pj_scan_is_eof(&scanner) && !IS_NEWLINE(*scanner.curptr));\n\n\t/* If empty line is found, eat it. */\n\tif (!pj_scan_is_eof(&scanner)) {\n\t    if (IS_NEWLINE(*scanner.curptr)) {\n\t\tpj_scan_get_newline(&scanner);\n\t    }\n\t}\n    }\n    PJ_CATCH_ANY\n    {\n\tPJ_LOG(4,(THIS_FILE, \"Error parsing header: '%.*s' line %d col %d\",\n\t\t  (int)hname.slen, hname.ptr, scanner.line,\n\t\t  pj_scan_get_col(&scanner)));\n\n\t/* Exception was thrown during parsing. */\n\tif ((options & STOP_ON_ERROR) == STOP_ON_ERROR) {\n\t    pj_scan_fini(&scanner);\n\t    return PJSIP_EINVALIDHDR;\n\t}\n\n\t/* Skip until newline, and parse next header. */\n\tif (!pj_scan_is_eof(&scanner)) {\n\t    /* Skip until next line.\n\t     * Watch for header continuation.\n\t     */\n\t    do {\n\t\tpj_scan_skip_line(&scanner);\n\t    } while (IS_SPACE(*scanner.curptr));\n\t}\n\n\t/* Restore flag. Flag may be set in int_parse_sip_url() */\n\tscanner.skip_ws = PJ_SCAN_AUTOSKIP_WS_HEADER;\n\n\t/* Continue parse next header, if any. */\n\tif (!pj_scan_is_eof(&scanner) && !IS_NEWLINE(*scanner.curptr)) {\n\t    goto retry_parse;\n\t}\n\n    }\n    PJ_END;\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_parser_wrap.cpp",
    "content": "/* $Id: sip_parser_wrap.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * This file is a C++ wrapper, see ticket #886 for details.\n */\n\n#include \"sip_parser.c\"\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_resolve.c",
    "content": "/* $Id: sip_resolve.c 4108 2012-04-27 01:32:12Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_resolve.h>\n#include <pjsip/sip_transport.h>\n#include <pjsip/sip_errno.h>\n#include <pjlib-util/errno.h>\n#include <pjlib-util/srv_resolver.h>\n#include <pj/addr_resolv.h>\n#include <pj/array.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n\n\n#define THIS_FILE   \"sip_resolve.c\"\n\n#define ADDR_MAX_COUNT\t    8\n\nstruct naptr_target\n{\n    pj_str_t\t\t    res_type;\t    /**< e.g. \"_sip._udp\"   */\n    pj_str_t\t\t    name;\t    /**< Domain name.\t    */\n    pjsip_transport_type_e  type;\t    /**< Transport type.    */\n    unsigned\t\t    order;\t    /**< Order\t\t    */\n    unsigned\t\t    pref;\t    /**< Preference.\t    */\n};\n\nstruct query\n{\n    char\t\t    *objname;\n\n    pj_dns_type\t\t     query_type;\n    void\t\t    *token;\n    pjsip_resolver_callback *cb;\n    pj_dns_async_query\t    *object;\n    pj_status_t\t\t     last_error;\n\n    /* Original request: */\n    struct {\n\tpjsip_host_info\t     target;\n\tunsigned\t     def_port;\n    } req;\n\n    /* NAPTR records: */\n    unsigned\t\t     naptr_cnt;\n    struct naptr_target\t     naptr[8];\n};\n\n\nstruct pjsip_resolver_t\n{\n    pj_dns_resolver *res;\n    pjsip_ext_resolver *ext_res;\n};\n\n\nstatic void srv_resolver_cb(void *user_data,\n\t\t\t    pj_status_t status,\n\t\t\t    const pj_dns_srv_record *rec);\nstatic void dns_a_callback(void *user_data,\n\t\t\t   pj_status_t status,\n\t\t\t   pj_dns_parsed_packet *response);\n\n\n/*\n * Public API to create the resolver.\n */\nPJ_DEF(pj_status_t) pjsip_resolver_create( pj_pool_t *pool,\n\t\t\t\t\t   pjsip_resolver_t **p_res)\n{\n    pjsip_resolver_t *resolver;\n\n    PJ_ASSERT_RETURN(pool && p_res, PJ_EINVAL);\n    resolver = PJ_POOL_ZALLOC_T(pool, pjsip_resolver_t);\n    *p_res = resolver;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Public API to set the DNS resolver instance for the SIP resolver.\n */\nPJ_DEF(pj_status_t) pjsip_resolver_set_resolver(pjsip_resolver_t *res,\n\t\t\t\t\t\tpj_dns_resolver *dns_res)\n{\n#if PJSIP_HAS_RESOLVER\n    res->res = dns_res;\n    return PJ_SUCCESS;\n#else\n    PJ_UNUSED_ARG(res);\n    PJ_UNUSED_ARG(dns_res);\n    pj_assert(!\"Resolver is disabled (PJSIP_HAS_RESOLVER==0)\");\n    return PJ_EINVALIDOP;\n#endif\n}\n\n/*\n * Public API to set the DNS external resolver implementation for the SIP \n * resolver.\n */\nPJ_DEF(pj_status_t) pjsip_resolver_set_ext_resolver(pjsip_resolver_t *res,\n                                                    pjsip_ext_resolver *ext_res)\n{\n    if (ext_res && !ext_res->resolve)\n\treturn PJ_EINVAL;\n\n    if (ext_res && res->res) {\n#if PJSIP_HAS_RESOLVER\n\tpj_dns_resolver_destroy(res->res, PJ_FALSE);\n#endif\n\tres->res = NULL;\n    }\n    res->ext_res = ext_res;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Public API to get the internal DNS resolver.\n */\nPJ_DEF(pj_dns_resolver*) pjsip_resolver_get_resolver(pjsip_resolver_t *res)\n{\n    return res->res;\n}\n\n\n/*\n * Public API to create destroy the resolver\n */\nPJ_DEF(void) pjsip_resolver_destroy(pjsip_resolver_t *resolver)\n{\n    if (resolver->res) {\n#if PJSIP_HAS_RESOLVER\n\tpj_dns_resolver_destroy(resolver->res, PJ_FALSE);\n#endif\n\tresolver->res = NULL;\n    }\n}\n\n/*\n * Internal:\n *  determine if an address is a valid IP address, and if it is,\n *  return the IP version (4 or 6).\n */\nstatic int get_ip_addr_ver(const pj_str_t *host)\n{\n    pj_in_addr dummy;\n    pj_in6_addr dummy6;\n\n    /* First check with inet_aton() */\n    if (pj_inet_aton(host, &dummy) > 0)\n\treturn 4;\n\n    /* Then check if this is an IPv6 address */\n    if (pj_inet_pton(pj_AF_INET6(), host, &dummy6) == PJ_SUCCESS)\n\treturn 6;\n\n    /* Not an IP address */\n    return 0;\n}\n\n\n/*\n * This is the main function for performing server resolution.\n */\nPJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver,\n\t\t\t    pj_pool_t *pool,\n\t\t\t    const pjsip_host_info *target,\n\t\t\t    void *token,\n\t\t\t    pjsip_resolver_callback *cb)\n{\n    pjsip_server_addresses svr_addr;\n    pj_status_t status = PJ_SUCCESS;\n    int ip_addr_ver;\n    struct query *query;\n    pjsip_transport_type_e type = target->type;\n\n    /* If an external implementation has been provided use it instead */\n    if (resolver->ext_res) {\n        (*resolver->ext_res->resolve)(resolver, pool, target, token, cb);\n        return;\n    }\n\n    /* Is it IP address or hostname? And if it's an IP, which version? */\n    ip_addr_ver = get_ip_addr_ver(&target->addr.host);\n\n    /* Set the transport type if not explicitly specified. \n     * RFC 3263 section 4.1 specify rules to set up this.\n     */\n    if (type == PJSIP_TRANSPORT_UNSPECIFIED) {\n\tif (ip_addr_ver || (target->addr.port != 0)) {\n#if PJ_HAS_TCP\n\t    if (target->flag & PJSIP_TRANSPORT_SECURE) \n\t    {\n\t\ttype = PJSIP_TRANSPORT_TLS;\n\t    } else if (target->flag & PJSIP_TRANSPORT_RELIABLE) \n\t    {\n\t\ttype = PJSIP_TRANSPORT_TCP;\n\t    } else \n#endif\n\t    {\n\t\ttype = PJSIP_TRANSPORT_UDP;\n\t    }\n\t} else {\n\t    /* No type or explicit port is specified, and the address is\n\t     * not IP address.\n\t     * In this case, full NAPTR resolution must be performed.\n\t     * But we don't support it (yet).\n\t     */\n#if PJ_HAS_TCP\n\t    if (target->flag & PJSIP_TRANSPORT_SECURE) \n\t    {\n\t\ttype = PJSIP_TRANSPORT_TLS;\n\t    } else if (target->flag & PJSIP_TRANSPORT_RELIABLE) \n\t    {\n\t\ttype = PJSIP_TRANSPORT_TCP;\n\t    } else \n#endif\n\t    {\n\t\ttype = PJSIP_TRANSPORT_UDP;\n\t    }\n\t}\n\n\t/* Add IPv6 flag for IPv6 address */\n\tif (ip_addr_ver == 6)\n\t    type = (pjsip_transport_type_e)((int)type + PJSIP_TRANSPORT_IPV6);\n    }\n\n\n    /* If target is an IP address, or if resolver is not configured, \n     * we can just finish the resolution now using pj_gethostbyname()\n     */\n    if (ip_addr_ver || resolver->res == NULL) {\n\tchar addr_str[PJ_INET6_ADDRSTRLEN+10];\n\tpj_uint16_t srv_port;\n\n\tif (ip_addr_ver != 0) {\n\t    /* Target is an IP address, no need to resolve */\n\t    if (ip_addr_ver == 4) {\n\t\tpj_sockaddr_init(pj_AF_INET(), &svr_addr.entry[0].addr, \n\t\t\t\t NULL, 0);\n\t\tpj_inet_aton(&target->addr.host,\n\t\t\t     &svr_addr.entry[0].addr.ipv4.sin_addr);\n\t    } else {\n\t\tpj_sockaddr_init(pj_AF_INET6(), &svr_addr.entry[0].addr, \n\t\t\t\t NULL, 0);\n\t\tpj_inet_pton(pj_AF_INET6(), &target->addr.host,\n\t\t\t     &svr_addr.entry[0].addr.ipv6.sin6_addr);\n\t    }\n\t} else {\n\t    pj_addrinfo ai;\n\t    unsigned count;\n\t    int af;\n\n\t    PJ_LOG(5,(THIS_FILE,\n\t\t      \"DNS resolver not available, target '%.*s:%d' type=%s \"\n\t\t      \"will be resolved with getaddrinfo()\",\n\t\t      target->addr.host.slen,\n\t\t      target->addr.host.ptr,\n\t\t      target->addr.port,\n\t\t      pjsip_transport_get_type_name(target->type)));\n\n\t    if (type & PJSIP_TRANSPORT_IPV6) {\n\t\taf = pj_AF_INET6();\n\t    } else {\n\t\taf = pj_AF_INET();\n\t    }\n\n\t    /* Resolve */\n\t    count = 1;\n\t    status = pj_getaddrinfo(af, &target->addr.host, &count, &ai);\n\t    if (status != PJ_SUCCESS) {\n\t\t/* \"Normalize\" error to PJ_ERESOLVE. This is a special error\n\t\t * because it will be translated to SIP status 502 by\n\t\t * sip_transaction.c\n\t\t */\n\t\tstatus = PJ_ERESOLVE;\n\t\tgoto on_error;\n\t    }\n\n\t    svr_addr.entry[0].addr.addr.sa_family = (pj_uint16_t)af;\n\t    pj_memcpy(&svr_addr.entry[0].addr, &ai.ai_addr,\n\t\t      sizeof(pj_sockaddr));\n\t}\n\n\t/* Set the port number */\n\tif (target->addr.port == 0) {\n\t   srv_port = (pj_uint16_t)\n\t\t      pjsip_transport_get_default_port_for_type(type);\n\t} else {\n\t   srv_port = (pj_uint16_t)target->addr.port;\n\t}\n\tpj_sockaddr_set_port(&svr_addr.entry[0].addr, srv_port);\n\n\t/* Call the callback. */\n\tPJ_LOG(5,(THIS_FILE, \n\t\t  \"Target '%.*s:%d' type=%s resolved to \"\n\t\t  \"'%s' type=%s (%s)\",\n\t\t  (int)target->addr.host.slen,\n\t\t  target->addr.host.ptr,\n\t\t  target->addr.port,\n\t\t  pjsip_transport_get_type_name(target->type),\n\t\t  pj_sockaddr_print(&svr_addr.entry[0].addr, addr_str,\n\t\t\t\t    sizeof(addr_str), 3),\n\t\t  pjsip_transport_get_type_name(type),\n\t\t  pjsip_transport_get_type_desc(type)));\n\tsvr_addr.count = 1;\n\tsvr_addr.entry[0].priority = 0;\n\tsvr_addr.entry[0].weight = 0;\n\tsvr_addr.entry[0].type = type;\n\tsvr_addr.entry[0].addr_len = pj_sockaddr_get_len(&svr_addr.entry[0].addr);\n\t(*cb)(status, token, &svr_addr);\n\n\t/* Done. */\n\treturn;\n    }\n\n    /* Target is not an IP address so we need to resolve it. */\n#if PJSIP_HAS_RESOLVER\n\n    /* Build the query state */\n    query = PJ_POOL_ZALLOC_T(pool, struct query);\n    query->objname = THIS_FILE;\n    query->token = token;\n    query->cb = cb;\n    query->req.target = *target;\n    pj_strdup(pool, &query->req.target.addr.host, &target->addr.host);\n\n    /* If port is not specified, start with SRV resolution\n     * (should be with NAPTR, but we'll do that later)\n     */\n    PJ_TODO(SUPPORT_DNS_NAPTR);\n\n    /* Build dummy NAPTR entry */\n    query->naptr_cnt = 1;\n    pj_bzero(&query->naptr[0], sizeof(query->naptr[0]));\n    query->naptr[0].order = 0;\n    query->naptr[0].pref = 0;\n    query->naptr[0].type = type;\n    pj_strdup(pool, &query->naptr[0].name, &target->addr.host);\n\n\n    /* Start DNS SRV or A resolution, depending on whether port is specified */\n    if (target->addr.port == 0) {\n\tquery->query_type = PJ_DNS_TYPE_SRV;\n\n\tquery->req.def_port = 5060;\n\n\tif (type == PJSIP_TRANSPORT_TLS) {\n\t    query->naptr[0].res_type = pj_str(\"_sips._tcp.\");\n\t    query->req.def_port = 5061;\n\t} else if (type == PJSIP_TRANSPORT_TCP)\n\t    query->naptr[0].res_type = pj_str(\"_sip._tcp.\");\n\telse if (type == PJSIP_TRANSPORT_UDP)\n\t    query->naptr[0].res_type = pj_str(\"_sip._udp.\");\n\telse {\n\t    pj_assert(!\"Unknown transport type\");\n\t    query->naptr[0].res_type = pj_str(\"_sip._udp.\");\n\t    \n\t}\n\n    } else {\n\t/* Otherwise if port is specified, start with A (or AAAA) host \n\t * resolution \n\t */\n\tquery->query_type = PJ_DNS_TYPE_A;\n\tquery->naptr[0].res_type.slen = 0;\n\tquery->req.def_port = target->addr.port;\n    }\n\n    /* Start the asynchronous query */\n    PJ_LOG(5, (query->objname, \n\t       \"Starting async DNS %s query: target=%.*s%.*s, transport=%s, \"\n\t       \"port=%d\",\n\t       pj_dns_get_type_name(query->query_type),\n\t       (int)query->naptr[0].res_type.slen,\n\t       query->naptr[0].res_type.ptr,\n\t       (int)query->naptr[0].name.slen, query->naptr[0].name.ptr,\n\t       pjsip_transport_get_type_name(target->type),\n\t       target->addr.port));\n\n    if (query->query_type == PJ_DNS_TYPE_SRV) {\n\n\tstatus = pj_dns_srv_resolve(&query->naptr[0].name,\n\t\t\t\t    &query->naptr[0].res_type,\n\t\t\t\t    query->req.def_port, pool, resolver->res,\n\t\t\t\t    PJ_TRUE, query, &srv_resolver_cb, NULL);\n\n    } else if (query->query_type == PJ_DNS_TYPE_A) {\n\n\tstatus = pj_dns_resolver_start_query(resolver->res, \n\t\t\t\t\t     &query->naptr[0].name,\n\t\t\t\t\t     PJ_DNS_TYPE_A, 0, \n\t\t\t\t\t     &dns_a_callback,\n    \t\t\t\t\t     query, &query->object);\n\n    } else {\n\tpj_assert(!\"Unexpected\");\n\tstatus = PJ_EBUG;\n    }\n\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    return;\n\n#else /* PJSIP_HAS_RESOLVER */\n    PJ_UNUSED_ARG(pool);\n    PJ_UNUSED_ARG(query);\n    PJ_UNUSED_ARG(srv_name);\n#endif /* PJSIP_HAS_RESOLVER */\n\non_error:\n    if (status != PJ_SUCCESS) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\tPJ_LOG(4,(THIS_FILE, \"Failed to resolve '%.*s'. Err=%d (%s)\",\n\t\t\t     (int)target->addr.host.slen,\n\t\t\t     target->addr.host.ptr,\n\t\t\t     status,\n\t\t\t     pj_strerror(status,errmsg,sizeof(errmsg)).ptr));\n\t(*cb)(status, token, NULL);\n\treturn;\n    }\n}\n\n#if PJSIP_HAS_RESOLVER\n\n/* \n * This callback is called when target is resolved with DNS A query.\n */\nstatic void dns_a_callback(void *user_data,\n\t\t\t   pj_status_t status,\n\t\t\t   pj_dns_parsed_packet *pkt)\n{\n    struct query *query = (struct query*) user_data;\n    pjsip_server_addresses srv;\n    pj_dns_a_record rec;\n    unsigned i;\n\n    rec.addr_count = 0;\n\n    /* Parse the response */\n    if (status == PJ_SUCCESS) {\n\tstatus = pj_dns_parse_a_response(pkt, &rec);\n    }\n\n    if (status != PJ_SUCCESS) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\n\t/* Log error */\n\tpj_strerror(status, errmsg, sizeof(errmsg));\n\tPJ_LOG(4,(query->objname, \"DNS A record resolution failed: %s\", \n\t\t  errmsg));\n\n\t/* Call the callback */\n\t(*query->cb)(status, query->token, NULL);\n\treturn;\n    }\n\n    /* Build server addresses and call callback */\n    srv.count = 0;\n    for (i = 0; i < rec.addr_count &&\n\t\tsrv.count < PJSIP_MAX_RESOLVED_ADDRESSES; ++i)\n    {\n\tsrv.entry[srv.count].type = query->naptr[0].type;\n\tsrv.entry[srv.count].priority = 0;\n\tsrv.entry[srv.count].weight = 0;\n\tsrv.entry[srv.count].addr_len = sizeof(pj_sockaddr_in);\n\tpj_sockaddr_in_init(&srv.entry[srv.count].addr.ipv4,\n\t\t\t    0, (pj_uint16_t)query->req.def_port);\n\tsrv.entry[srv.count].addr.ipv4.sin_addr.s_addr =\n\t    rec.addr[i].s_addr;\n\n\t++srv.count;\n    }\n\n    /* Call the callback */\n    (*query->cb)(PJ_SUCCESS, query->token, &srv);\n}\n\n\n/* Callback to be called by DNS SRV resolution */\nstatic void srv_resolver_cb(void *user_data,\n\t\t\t    pj_status_t status,\n\t\t\t    const pj_dns_srv_record *rec)\n{\n    struct query *query = (struct query*) user_data;\n    pjsip_server_addresses srv;\n    unsigned i;\n\n    if (status != PJ_SUCCESS) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\n\t/* Log error */\n\tpj_strerror(status, errmsg, sizeof(errmsg));\n\tPJ_LOG(4,(query->objname, \"DNS A record resolution failed: %s\", \n\t\t  errmsg));\n\n\t/* Call the callback */\n\t(*query->cb)(status, query->token, NULL);\n\treturn;\n    }\n\n    /* Build server addresses and call callback */\n    srv.count = 0;\n    for (i=0; i<rec->count; ++i) {\n\tunsigned j;\n\n\tfor (j = 0; j < rec->entry[i].server.addr_count &&\n\t\t    srv.count < PJSIP_MAX_RESOLVED_ADDRESSES; ++j)\n\t{\n\t    srv.entry[srv.count].type = query->naptr[0].type;\n\t    srv.entry[srv.count].priority = rec->entry[i].priority;\n\t    srv.entry[srv.count].weight = rec->entry[i].weight;\n\t    srv.entry[srv.count].addr_len = sizeof(pj_sockaddr_in);\n\t    pj_sockaddr_in_init(&srv.entry[srv.count].addr.ipv4,\n\t\t\t\t0, (pj_uint16_t)rec->entry[i].port);\n\t    srv.entry[srv.count].addr.ipv4.sin_addr.s_addr =\n\t\trec->entry[i].server.addr[j].s_addr;\n\n\t    ++srv.count;\n\t}\n    }\n\n    /* Call the callback */\n    (*query->cb)(PJ_SUCCESS, query->token, &srv);\n}\n\n#endif\t/* PJSIP_HAS_RESOLVER */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_tel_uri.c",
    "content": "/* $Id: sip_tel_uri.c 4322 2013-01-17 10:09:09Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_tel_uri.h>\n#include <pjsip/sip_msg.h>\n#include <pjsip/sip_parser.h>\n#include <pjsip/print_util.h>\n#include <pj/pool.h>\n#include <pj/assert.h>\n#include <pj/string.h>\n#include <pj/ctype.h>\n#include <pj/except.h>\n#include <pjlib-util/string.h>\n#include <pjlib-util/scanner.h>\n\n#define ALPHA\n#define DIGITS\t\t    \"0123456789\"\n#define HEX\t\t    \"aAbBcCdDeEfF\"\n#define HEX_DIGITS\t    DIGITS HEX\n#define VISUAL_SEP\t    \"-.()\"\n#define PHONE_DIGITS\t    DIGITS VISUAL_SEP\n#define GLOBAL_DIGITS\t    \"+\" PHONE_DIGITS\n#define LOCAL_DIGITS\t    HEX_DIGITS \"*#\" VISUAL_SEP\n#define NUMBER_SPEC\t    LOCAL_DIGITS GLOBAL_DIGITS\n#define PHONE_CONTEXT\t    ALPHA GLOBAL_DIGITS\n//#define RESERVED\t    \";/?:@&=+$,\"\n#define RESERVED\t    \"/:@&$,+\"\n#define MARK\t\t    \"-_.!~*'()\"\n#define UNRESERVED\t    ALPHA DIGITS MARK\n#define ESCAPED\t\t    \"%\"\n#define URIC\t\t    RESERVED UNRESERVED ESCAPED \"[]+\"\n#define PARAM_UNRESERVED    \"[]/:&+$\"\n#define PARAM_CHAR\t    PARAM_UNRESERVED UNRESERVED ESCAPED\n\nstatic pj_cis_buf_t cis_buf;\nstatic pj_cis_t pjsip_TEL_NUMBER_SPEC;\nstatic pj_cis_t pjsip_TEL_EXT_VALUE_SPEC;\nstatic pj_cis_t pjsip_TEL_PHONE_CONTEXT_SPEC;\nstatic pj_cis_t pjsip_TEL_URIC_SPEC;\nstatic pj_cis_t pjsip_TEL_VISUAL_SEP_SPEC;\nstatic pj_cis_t pjsip_TEL_PNAME_SPEC;\nstatic pj_cis_t pjsip_TEL_PVALUE_SPEC;\nstatic pj_cis_t pjsip_TEL_PVALUE_SPEC_ESC;\nstatic pj_cis_t pjsip_TEL_PARSING_PVALUE_SPEC;\nstatic pj_cis_t pjsip_TEL_PARSING_PVALUE_SPEC_ESC;\n\nstatic pj_str_t pjsip_ISUB_STR = { \"isub\", 4 };\nstatic pj_str_t pjsip_EXT_STR = { \"ext\", 3 };\nstatic pj_str_t pjsip_PH_CTX_STR = { \"phone-context\", 13 };\n\n\nstatic const pj_str_t *tel_uri_get_scheme( const pjsip_tel_uri* );\nstatic void *tel_uri_get_uri( pjsip_tel_uri* );\nstatic pj_ssize_t tel_uri_print( pjsip_uri_context_e context,\n\t\t\t\t const pjsip_tel_uri *url, \n\t\t\t\t char *buf, pj_size_t size);\nstatic int tel_uri_cmp( pjsip_uri_context_e context,\n\t\t\tconst pjsip_tel_uri *url1, const pjsip_tel_uri *url2);\nstatic pjsip_tel_uri* tel_uri_clone(pj_pool_t *pool, const pjsip_tel_uri *rhs);\nstatic void*\t      tel_uri_parse( pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t\t     pj_bool_t parse_params);\n\ntypedef const pj_str_t* (*P_GET_SCHEME)(const void*);\ntypedef void* \t\t(*P_GET_URI)(void*);\ntypedef pj_ssize_t \t(*P_PRINT_URI)(pjsip_uri_context_e,const void *,\n\t\t\t\t       char*,pj_size_t);\ntypedef int \t\t(*P_CMP_URI)(pjsip_uri_context_e, const void*, \n\t\t\t\t     const void*);\ntypedef void* \t\t(*P_CLONE)(pj_pool_t*, const void*);\n\nstatic pjsip_uri_vptr tel_uri_vptr = \n{\n    (P_GET_SCHEME)\t&tel_uri_get_scheme,\n    (P_GET_URI) \t&tel_uri_get_uri,\n    (P_PRINT_URI) \t&tel_uri_print,\n    (P_CMP_URI)\t\t&tel_uri_cmp,\n    (P_CLONE)\t\t&tel_uri_clone\n};\n\n\nPJ_DEF(pjsip_tel_uri*) pjsip_tel_uri_create(pj_pool_t *pool)\n{\n    pjsip_tel_uri *uri = PJ_POOL_ZALLOC_T(pool, pjsip_tel_uri);\n    uri->vptr = &tel_uri_vptr;\n    pj_list_init(&uri->other_param);\n    return uri;\n}\n\n\nstatic const pj_str_t *tel_uri_get_scheme( const pjsip_tel_uri *uri )\n{\n    PJ_UNUSED_ARG(uri);\n    return &pjsip_parser_const()->pjsip_TEL_STR;\n}\n\nstatic void *tel_uri_get_uri( pjsip_tel_uri *uri )\n{\n    return uri;\n}\n\n\npj_status_t pjsip_tel_uri_subsys_init(void)\n{\n    pj_status_t status;\n\n    pj_cis_buf_init(&cis_buf);\n\n    status = pj_cis_init(&cis_buf, &pjsip_TEL_EXT_VALUE_SPEC);\n    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    pj_cis_add_str(&pjsip_TEL_EXT_VALUE_SPEC, PHONE_DIGITS);\n\n    status = pj_cis_init(&cis_buf, &pjsip_TEL_NUMBER_SPEC);\n    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    pj_cis_add_str(&pjsip_TEL_NUMBER_SPEC, NUMBER_SPEC);\n\n    status = pj_cis_init(&cis_buf, &pjsip_TEL_VISUAL_SEP_SPEC);\n    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    pj_cis_add_str(&pjsip_TEL_VISUAL_SEP_SPEC, VISUAL_SEP);\n\n    status = pj_cis_init(&cis_buf, &pjsip_TEL_PHONE_CONTEXT_SPEC);\n    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    pj_cis_add_alpha(&pjsip_TEL_PHONE_CONTEXT_SPEC);\n    pj_cis_add_num(&pjsip_TEL_PHONE_CONTEXT_SPEC);\n    pj_cis_add_str(&pjsip_TEL_PHONE_CONTEXT_SPEC, PHONE_CONTEXT);\n\n    status = pj_cis_init(&cis_buf, &pjsip_TEL_URIC_SPEC);\n    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    pj_cis_add_alpha(&pjsip_TEL_URIC_SPEC);\n    pj_cis_add_num(&pjsip_TEL_URIC_SPEC);\n    pj_cis_add_str(&pjsip_TEL_URIC_SPEC, URIC);\n\n    status = pj_cis_init(&cis_buf, &pjsip_TEL_PNAME_SPEC);\n    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    pj_cis_add_alpha(&pjsip_TEL_PNAME_SPEC);\n    pj_cis_add_num(&pjsip_TEL_PNAME_SPEC);\n    pj_cis_add_str(&pjsip_TEL_PNAME_SPEC, \"-\");\n\n    status = pj_cis_init(&cis_buf, &pjsip_TEL_PVALUE_SPEC);\n    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    pj_cis_add_alpha(&pjsip_TEL_PVALUE_SPEC);\n    pj_cis_add_num(&pjsip_TEL_PVALUE_SPEC);\n    pj_cis_add_str(&pjsip_TEL_PVALUE_SPEC, PARAM_CHAR);\n\n    status = pj_cis_dup(&pjsip_TEL_PVALUE_SPEC_ESC, &pjsip_TEL_PVALUE_SPEC);\n    pj_cis_del_str(&pjsip_TEL_PVALUE_SPEC_ESC, \"%\");\n\n    status = pj_cis_dup(&pjsip_TEL_PARSING_PVALUE_SPEC, &pjsip_TEL_URIC_SPEC);\n    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n    pj_cis_add_cis(&pjsip_TEL_PARSING_PVALUE_SPEC, &pjsip_TEL_PVALUE_SPEC);\n    pj_cis_add_str(&pjsip_TEL_PARSING_PVALUE_SPEC, \"=\");\n\n    status = pj_cis_dup(&pjsip_TEL_PARSING_PVALUE_SPEC_ESC, \n\t\t\t&pjsip_TEL_PARSING_PVALUE_SPEC);\n    pj_cis_del_str(&pjsip_TEL_PARSING_PVALUE_SPEC_ESC, \"%\");\n\n    status = pjsip_register_uri_parser(\"tel\", &tel_uri_parse);\n    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);\n\n    return PJ_SUCCESS;\n}\n\n/* Print tel: URI */\nstatic pj_ssize_t tel_uri_print( pjsip_uri_context_e context,\n\t\t\t\t const pjsip_tel_uri *uri, \n\t\t\t\t char *buf, pj_size_t size)\n{\n    int printed;\n    char *startbuf = buf;\n    char *endbuf = buf+size-1;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    PJ_UNUSED_ARG(context);\n\n    /* Print scheme. */\n    copy_advance(buf, pc->pjsip_TEL_STR);\n    *buf++ = ':';\n\n    /* Print number. */\n    copy_advance_escape(buf, uri->number, pjsip_TEL_NUMBER_SPEC);\n\n    /* ISDN sub-address or extension must appear first. */\n\n    /* Extension param. */\n    copy_advance_pair_escape(buf, \";ext=\", 5, uri->ext_param, \n\t\t\t     pjsip_TEL_EXT_VALUE_SPEC);\n\n    /* ISDN sub-address. */\n    copy_advance_pair_escape(buf, \";isub=\", 6, uri->isub_param, \n\t\t\t     pjsip_TEL_URIC_SPEC);\n\n    /* Followed by phone context, if present. */\n    copy_advance_pair_escape(buf, \";phone-context=\", 15, uri->context, \n\t\t\t     pjsip_TEL_PHONE_CONTEXT_SPEC);\n\n\n    /* Print other parameters. */\n    printed = (int)pjsip_param_print_on(&uri->other_param, buf, (endbuf-buf), \n\t\t\t\t\t&pjsip_TEL_PNAME_SPEC, \n\t\t\t\t\t&pjsip_TEL_PVALUE_SPEC, ';');\n    if (printed < 0)\n\treturn -1;\n    buf += printed;\n\n    *buf = '\\0';\n\n    return (buf-startbuf);\n}\n\n/* Compare two numbers, according to RFC 3966:\n *  - both must be either local or global numbers.\n *  - The 'global-number-digits' and the 'local-number-digits' must be\n *    equal, after removing all visual separators.\n */\nPJ_DEF(int) pjsip_tel_nb_cmp(const pj_str_t *number1, const pj_str_t *number2)\n{\n    const char *s1 = number1->ptr,\n\t       *e1 = number1->ptr + number1->slen,\n\t       *s2 = number2->ptr,\n\t       *e2 = number2->ptr + number2->slen;\n\n    /* Compare each number, ignoreing visual separators. */\n    while (s1!=e1 && s2!=e2) {\n\tint diff;\n\n\tif (pj_cis_match(&pjsip_TEL_VISUAL_SEP_SPEC, *s1)) {\n\t    ++s1;\n\t    continue;\n\t}\n\tif (pj_cis_match(&pjsip_TEL_VISUAL_SEP_SPEC, *s2)) {\n\t    ++s2;\n\t    continue;\n\t}\n\n\tdiff = pj_tolower(*s1) - pj_tolower(*s2);\n\tif (!diff) {\n\t    ++s1, ++s2;\n\t    continue;\n\t} else\n\t    return diff;\n    }\n\n    /* Exhaust remaining visual separators. */\n    while (s1!=e1 && pj_cis_match(&pjsip_TEL_VISUAL_SEP_SPEC, *s1))\n\t++s1;\n    while (s2!=e2 && pj_cis_match(&pjsip_TEL_VISUAL_SEP_SPEC, *s2))\n\t++s2;\n\n    if (s1==e1 && s2==e2)\n\treturn 0;\n    else if (s1==e1)\n\treturn -1;\n    else\n\treturn 1;\n}\n\n/* Compare two tel: URI */\nstatic int tel_uri_cmp( pjsip_uri_context_e context,\n\t\t\tconst pjsip_tel_uri *url1, const pjsip_tel_uri *url2)\n{\n    int result;\n\n    PJ_UNUSED_ARG(context);\n\n    /* Scheme must match. */\n    if (url1->vptr != url2->vptr)\n\treturn -1;\n\n    /* Compare number. */\n    result = pjsip_tel_nb_cmp(&url1->number, &url2->number);\n    if (result != 0)\n\treturn result;\n\n    /* Compare phone-context as hostname or as as global nb. */\n    if (url1->context.slen) {\n\tif (*url1->context.ptr != '+')\n\t    result = pj_stricmp(&url1->context, &url2->context);\n\telse\n\t    result = pjsip_tel_nb_cmp(&url1->context, &url2->context);\n\n\tif (result != 0)\n\t    return result;\n\n    } else if (url2->context.slen)\n\treturn -1;\n\n    /* Compare extension. */\n    if (url1->ext_param.slen) {\n\tresult = pjsip_tel_nb_cmp(&url1->ext_param, &url2->ext_param);\n\tif (result != 0)\n\t    return result;\n    }\n\n    /* Compare isub bytes by bytes. */\n    if (url1->isub_param.slen) {\n\tresult = pj_stricmp(&url1->isub_param, &url2->isub_param);\n\tif (result != 0)\n\t    return result;\n    }\n\n    /* Other parameters are compared regardless of the order.\n     * If one URI has parameter not found in the other URI, the URIs are\n     * not equal.\n     */\n    if (url1->other_param.next != &url1->other_param) {\n\tconst pjsip_param *p1, *p2;\n\tint cnt1 = 0, cnt2 = 0;\n\n\tp1 = url1->other_param.next;\n\twhile (p1 != &url1->other_param) {\n\t    p2 = pjsip_param_cfind(&url2->other_param, &p1->name);\n\t    if (!p2 )\n\t\treturn 1;\n\n\t    result = pj_stricmp(&p1->value, &p2->value);\n\t    if (result != 0)\n\t\treturn result;\n\n\t    p1 = p1->next;\n\t    ++cnt1;\n\t}\n\n\tp2 = url2->other_param.next;\n\twhile (p2 != &url2->other_param)\n\t    ++cnt2, p2 = p2->next;\n\n\tif (cnt1 < cnt2)\n\t    return -1;\n\telse if (cnt1 > cnt2)\n\t    return 1;\n\n    } else if (url2->other_param.next != &url2->other_param)\n\treturn -1;\n\n    /* Equal. */\n    return 0;\n}\n\n/* Clone tel: URI */\nstatic pjsip_tel_uri* tel_uri_clone(pj_pool_t *pool, const pjsip_tel_uri *rhs)\n{\n    pjsip_tel_uri *uri = pjsip_tel_uri_create(pool);\n\n    pj_strdup(pool, &uri->number, &rhs->number);\n    pj_strdup(pool, &uri->context, &rhs->context);\n    pj_strdup(pool, &uri->ext_param, &rhs->ext_param);\n    pj_strdup(pool, &uri->isub_param, &rhs->isub_param);\n    pjsip_param_clone(pool, &uri->other_param, &rhs->other_param);\n\n    return uri;\n}\n\n/* Parse tel: URI \n * THis actually returns (pjsip_tel_uri *) type.\n */\nstatic void* tel_uri_parse( pj_scanner *scanner, pj_pool_t *pool,\n\t\t\t    pj_bool_t parse_params)\n{\n    pjsip_tel_uri *uri;\n    pj_str_t token;\n    int skip_ws = scanner->skip_ws;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    scanner->skip_ws = 0;\n\n    /* Parse scheme. */\n    pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &token);\n    if (pj_scan_get_char(scanner) != ':')\n\tPJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n    if (pj_stricmp_alnum(&token, &pc->pjsip_TEL_STR) != 0)\n\tPJ_THROW(PJSIP_SYN_ERR_EXCEPTION);\n\n    /* Create URI */\n    uri = pjsip_tel_uri_create(pool);\n\n    /* Get the phone number. */\n#if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0\n    pj_scan_get_unescape(scanner, &pjsip_TEL_NUMBER_SPEC, &uri->number);\n#else\n    pj_scan_get(scanner, &pjsip_TEL_NUMBER_SPEC, &uri->number);\n    uri->number = pj_str_unescape(pool, &uri->number);\n#endif\n\n    /* Get all parameters. */\n    if (parse_params && *scanner->curptr==';') {\n\tpj_str_t pname, pvalue;\n\n\tdo {\n\t    /* Eat the ';' separator. */\n\t    pj_scan_get_char(scanner);\n\n\t    /* Get pname. */\n\t    pj_scan_get(scanner, &pc->pjsip_PARAM_CHAR_SPEC, &pname);\n\n\t    if (*scanner->curptr == '=') {\n\t\tpj_scan_get_char(scanner);\n\n#\t\tif defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0\n\t\t    pj_scan_get_unescape(scanner, \n\t\t\t\t\t &pjsip_TEL_PARSING_PVALUE_SPEC_ESC,\n\t\t\t\t\t &pvalue);\n#\t\telse\n\t\t    pj_scan_get(scanner, &pjsip_TEL_PARSING_PVALUE_SPEC, \n\t\t\t\t&pvalue);\n\t\t    pvalue = pj_str_unescape(pool, &pvalue);\n#\t\tendif\n\n\t    } else {\n\t\tpvalue.slen = 0;\n\t\tpvalue.ptr = NULL;\n\t    }\n\n\t    /* Save the parameters. */\n\t    if (pj_stricmp_alnum(&pname, &pjsip_ISUB_STR)==0) {\n\t\turi->isub_param = pvalue;\n\t    } else if (pj_stricmp_alnum(&pname, &pjsip_EXT_STR)==0) {\n\t\turi->ext_param = pvalue;\n\t    } else if (pj_stricmp_alnum(&pname, &pjsip_PH_CTX_STR)==0) {\n\t\turi->context = pvalue;\n\t    } else {\n\t\tpjsip_param *param = PJ_POOL_ALLOC_T(pool, pjsip_param);\n\t\tparam->name = pname;\n\t\tparam->value = pvalue;\n\t\tpj_list_insert_before(&uri->other_param, param);\n\t    }\n\n\t} while (*scanner->curptr==';');\n    }\n\n    scanner->skip_ws = skip_ws;\n    pj_scan_skip_whitespace(scanner);\n    return uri;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_tel_uri_wrap.cpp",
    "content": "/* $Id: sip_tel_uri_wrap.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * This file is a C++ wrapper, see ticket #886 for details.\n */\n\n#include \"sip_tel_uri.c\"\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_transaction.c",
    "content": "/* $Id: sip_transaction.c 4516 2013-05-06 09:10:56Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_transaction.h>\n#include <pjsip/sip_util.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_event.h>\n#include <pjlib-util/errno.h>\n#include <pj/hash.h>\n#include <pj/pool.h>\n#include <pj/os.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n#include <pj/assert.h>\n#include <pj/guid.h>\n#include <pj/log.h>\n\n#define THIS_FILE   \"sip_transaction.c\"\n\n#if 0\n#define TSX_TRACE_(expr)    PJ_LOG(3,expr)\n#else\n#define TSX_TRACE_(expr)\n#endif\n\n/* When this macro is set, transaction will keep the hashed value\n * so that future lookup (to unregister transaction) does not need\n * to recalculate the hash again. It should gains a little bit of\n * performance, so generally we'd want this.\n */\n#define PRECALC_HASH\n\n\n/* Defined in sip_util_statefull.c */\nextern pjsip_module mod_stateful_util;\n\n\n/*****************************************************************************\n **\n ** Declarations and static variable definitions section.\n **\n *****************************************************************************\n **/\n/* Prototypes. */\nstatic pj_status_t mod_tsx_layer_load(pjsip_endpoint *endpt);\nstatic pj_status_t mod_tsx_layer_start(void);\nstatic pj_status_t mod_tsx_layer_stop(void);\nstatic pj_status_t mod_tsx_layer_unload(void);\nstatic pj_bool_t   mod_tsx_layer_on_rx_request(pjsip_rx_data *rdata);\nstatic pj_bool_t   mod_tsx_layer_on_rx_response(pjsip_rx_data *rdata);\n\n/* Transaction layer module definition. */\nstatic struct mod_tsx_layer\n{\n    struct pjsip_module  mod;\n    pj_pool_t\t\t*pool;\n    pjsip_endpoint\t*endpt;\n    pj_mutex_t\t\t*mutex;\n    pj_hash_table_t\t*htable;\n} mod_tsx_layer = \n{   {\n\tNULL, NULL,\t\t\t/* List's prev and next.    */\n\t{ \"mod-tsx-layer\", 13 },\t/* Module name.\t\t    */\n\t-1,\t\t\t\t/* Module ID\t\t    */\n\tPJSIP_MOD_PRIORITY_TSX_LAYER,\t/* Priority.\t\t    */\n\tmod_tsx_layer_load,\t\t/* load().\t\t    */\n\tmod_tsx_layer_start,\t\t/* start()\t\t    */\n\tmod_tsx_layer_stop,\t\t/* stop()\t\t    */\n\tmod_tsx_layer_unload,\t\t/* unload()\t\t    */\n\tmod_tsx_layer_on_rx_request,\t/* on_rx_request()\t    */\n\tmod_tsx_layer_on_rx_response,\t/* on_rx_response()\t    */\n\tNULL\n    }\n};\n\n/* Transaction state names */\nstatic const char *state_str[] = \n{\n    \"Null\",\n    \"Calling\",\n    \"Trying\",\n    \"Proceeding\",\n    \"Completed\",\n    \"Confirmed\",\n    \"Terminated\",\n    \"Destroyed\",\n};\n\n/* Role names */\nstatic const char *role_name[] = \n{\n    \"UAC\",\n    \"UAS\"\n};\n\n/* Transport flag. */\nenum\n{\n    TSX_HAS_PENDING_TRANSPORT\t= 1,\n    TSX_HAS_PENDING_RESCHED\t= 2,\n    TSX_HAS_PENDING_SEND\t= 4,\n    TSX_HAS_PENDING_DESTROY\t= 8,\n    TSX_HAS_RESOLVED_SERVER\t= 16,\n};\n\n/* Timer timeout value constants */\nstatic pj_time_val t1_timer_val = { PJSIP_T1_TIMEOUT/1000, \n                                    PJSIP_T1_TIMEOUT%1000 };\nstatic pj_time_val t2_timer_val = { PJSIP_T2_TIMEOUT/1000, \n                                    PJSIP_T2_TIMEOUT%1000 };\nstatic pj_time_val t4_timer_val = { PJSIP_T4_TIMEOUT/1000, \n                                    PJSIP_T4_TIMEOUT%1000 };\nstatic pj_time_val td_timer_val = { PJSIP_TD_TIMEOUT/1000, \n                                    PJSIP_TD_TIMEOUT%1000 };\nstatic pj_time_val timeout_timer_val = { (64*PJSIP_T1_TIMEOUT)/1000,\n\t\t\t\t\t (64*PJSIP_T1_TIMEOUT)%1000 };\n\n#define TIMER_INACTIVE\t\t0\n#define RETRANSMIT_TIMER\t1\n#define TIMEOUT_TIMER\t\t2\n#define TRANSPORT_ERR_TIMER\t3\n\n/* Flags for tsx_set_state() */\nenum\n{\n    NO_NOTIFY = 1,\n    NO_SCHEDULE_HANDLER = 2,\n};\n\n/* Prototypes. */\nstatic pj_status_t tsx_on_state_null(\t\tpjsip_transaction *tsx, \n\t\t\t\t                pjsip_event *event);\nstatic pj_status_t tsx_on_state_calling(\tpjsip_transaction *tsx, \n\t\t\t\t                pjsip_event *event);\nstatic pj_status_t tsx_on_state_trying(\t\tpjsip_transaction *tsx, \n\t\t\t\t                pjsip_event *event);\nstatic pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx, \n\t\t\t\t\t        pjsip_event *event);\nstatic pj_status_t tsx_on_state_proceeding_uac( pjsip_transaction *tsx,\n\t\t\t\t\t        pjsip_event *event);\nstatic pj_status_t tsx_on_state_completed_uas(\tpjsip_transaction *tsx, \n\t\t\t\t\t        pjsip_event *event);\nstatic pj_status_t tsx_on_state_completed_uac(\tpjsip_transaction *tsx,\n\t\t\t\t\t        pjsip_event *event);\nstatic pj_status_t tsx_on_state_confirmed(\tpjsip_transaction *tsx, \n\t\t\t\t\t        pjsip_event *event);\nstatic pj_status_t tsx_on_state_terminated(\tpjsip_transaction *tsx, \n\t\t\t\t\t        pjsip_event *event);\nstatic pj_status_t tsx_on_state_destroyed(\tpjsip_transaction *tsx, \n\t\t\t\t\t        pjsip_event *event);\nstatic void        tsx_timer_callback( pj_timer_heap_t *theap, \n\t\t\t               pj_timer_entry *entry);\nstatic void\t   tsx_tp_state_callback(\n\t\t\t\t       pjsip_transport *tp,\n\t\t\t\t       pjsip_transport_state state,\n\t\t\t\t       const pjsip_transport_state_info *info);\nstatic void \t   tsx_set_state( pjsip_transaction *tsx,\n            \t                  pjsip_tsx_state_e state,\n            \t                  pjsip_event_id_e event_src_type,\n            \t                  void *event_src,\n\t\t\t\t  int flag);\nstatic void \t   tsx_set_status_code(pjsip_transaction *tsx,\n            \t                       int code, const pj_str_t *reason);\nstatic pj_status_t tsx_create( pjsip_module *tsx_user,\n                               pj_grp_lock_t *grp_lock,\n\t\t\t       pjsip_transaction **p_tsx);\nstatic void\t   tsx_on_destroy(void *arg);\nstatic pj_status_t tsx_shutdown( pjsip_transaction *tsx );\nstatic void\t   tsx_resched_retransmission( pjsip_transaction *tsx );\nstatic pj_status_t tsx_retransmit( pjsip_transaction *tsx, int resched);\nstatic int         tsx_send_msg( pjsip_transaction *tsx, \n                                 pjsip_tx_data *tdata);\nstatic void        tsx_update_transport( pjsip_transaction *tsx, \n\t\t\t\t\t pjsip_transport *tp);\n\n\n/* State handlers for UAC, indexed by state */\nstatic int  (*tsx_state_handler_uac[PJSIP_TSX_STATE_MAX])(pjsip_transaction *,\n\t\t\t\t\t\t\t  pjsip_event *) = \n{\n    &tsx_on_state_null,\n    &tsx_on_state_calling,\n    NULL,\n    &tsx_on_state_proceeding_uac,\n    &tsx_on_state_completed_uac,\n    &tsx_on_state_confirmed,\n    &tsx_on_state_terminated,\n    &tsx_on_state_destroyed,\n};\n\n/* State handlers for UAS */\nstatic int  (*tsx_state_handler_uas[PJSIP_TSX_STATE_MAX])(pjsip_transaction *, \n\t\t\t\t\t\t\t  pjsip_event *) = \n{\n    &tsx_on_state_null,\n    NULL,\n    &tsx_on_state_trying,\n    &tsx_on_state_proceeding_uas,\n    &tsx_on_state_completed_uas,\n    &tsx_on_state_confirmed,\n    &tsx_on_state_terminated,\n    &tsx_on_state_destroyed,\n};\n\n/*****************************************************************************\n **\n ** Utilities\n **\n *****************************************************************************\n */\n/*\n * Get transaction state name.\n */\nPJ_DEF(const char *) pjsip_tsx_state_str(pjsip_tsx_state_e state)\n{\n    return state_str[state];\n}\n\n/*\n * Get the role name.\n */\nPJ_DEF(const char *) pjsip_role_name(pjsip_role_e role)\n{\n    return role_name[role];\n}\n\n\n/*\n * Create transaction key for RFC2543 compliant messages, which don't have\n * unique branch parameter in the top most Via header.\n *\n * INVITE requests matches a transaction if the following attributes\n * match the original request:\n *\t- Request-URI\n *\t- To tag\n *\t- From tag\n *\t- Call-ID\n *\t- CSeq\n *\t- top Via header\n *\n * CANCEL matching is done similarly as INVITE, except:\n *\t- CSeq method will differ\n *\t- To tag is not matched.\n *\n * ACK matching is done similarly, except that:\n *\t- method of the CSeq will differ,\n *\t- To tag is matched to the response sent by the server transaction.\n *\n * The transaction key is constructed from the common components of above\n * components. Additional comparison is needed to fully match a transaction.\n */\nstatic pj_status_t create_tsx_key_2543( pj_pool_t *pool,\n\t\t\t                pj_str_t *str,\n\t\t\t                pjsip_role_e role,\n\t\t\t                const pjsip_method *method,\n\t\t\t                const pjsip_rx_data *rdata )\n{\n#define SEPARATOR   '$'\n    char *key, *p;\n    pj_ssize_t len;\n    pj_size_t len_required;\n    pj_str_t *host;\n\n    PJ_ASSERT_RETURN(pool && str && method && rdata, PJ_EINVAL);\n    PJ_ASSERT_RETURN(rdata->msg_info.msg, PJ_EINVAL);\n    PJ_ASSERT_RETURN(rdata->msg_info.via, PJSIP_EMISSINGHDR);\n    PJ_ASSERT_RETURN(rdata->msg_info.cseq, PJSIP_EMISSINGHDR);\n    PJ_ASSERT_RETURN(rdata->msg_info.from, PJSIP_EMISSINGHDR);\n\n    host = &rdata->msg_info.via->sent_by.host;\n\n    /* Calculate length required. */\n    len_required = 9 +\t\t\t    /* CSeq number */\n\t\t   rdata->msg_info.from->tag.slen +   /* From tag. */\n\t\t   rdata->msg_info.cid->id.slen +    /* Call-ID */\n\t\t   host->slen +\t\t    /* Via host. */\n\t\t   9 +\t\t\t    /* Via port. */\n\t\t   16;\t\t\t    /* Separator+Allowance. */\n    key = p = (char*) pj_pool_alloc(pool, len_required);\n\n    /* Add role. */\n    *p++ = (char)(role==PJSIP_ROLE_UAC ? 'c' : 's');\n    *p++ = SEPARATOR;\n\n    /* Add method, except when method is INVITE or ACK. */\n    if (method->id != PJSIP_INVITE_METHOD && method->id != PJSIP_ACK_METHOD) {\n\tpj_memcpy(p, method->name.ptr, method->name.slen);\n\tp += method->name.slen;\n\t*p++ = '$';\n    }\n\n    /* Add CSeq (only the number). */\n    len = pj_utoa(rdata->msg_info.cseq->cseq, p);\n    p += len;\n    *p++ = SEPARATOR;\n\n    /* Add From tag. */\n    len = rdata->msg_info.from->tag.slen;\n    pj_memcpy( p, rdata->msg_info.from->tag.ptr, len);\n    p += len;\n    *p++ = SEPARATOR;\n\n    /* Add Call-ID. */\n    len = rdata->msg_info.cid->id.slen;\n    pj_memcpy( p, rdata->msg_info.cid->id.ptr, len );\n    p += len;\n    *p++ = SEPARATOR;\n\n    /* Add top Via header. \n     * We don't really care whether the port contains the real port (because\n     * it can be omited if default port is used). Anyway this function is \n     * only used to match request retransmission, and we expect that the \n     * request retransmissions will contain the same port.\n     */\n    pj_memcpy(p, host->ptr, host->slen);\n    p += host->slen;\n    *p++ = ':';\n\n    len = pj_utoa(rdata->msg_info.via->sent_by.port, p);\n    p += len;\n    *p++ = SEPARATOR;\n    \n    *p++ = '\\0';\n\n    /* Done. */\n    str->ptr = key;\n    str->slen = p-key;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Create transaction key for RFC3161 compliant system.\n */\nstatic pj_status_t create_tsx_key_3261( pj_pool_t *pool,\n\t\t                        pj_str_t *key,\n\t\t                        pjsip_role_e role,\n\t\t                        const pjsip_method *method,\n\t\t                        const pj_str_t *branch)\n{\n    char *p;\n\n    PJ_ASSERT_RETURN(pool && key && method && branch, PJ_EINVAL);\n\n    p = key->ptr = (char*) \n    \t\t   pj_pool_alloc(pool, branch->slen + method->name.slen + 4 );\n    \n    /* Add role. */\n    *p++ = (char)(role==PJSIP_ROLE_UAC ? 'c' : 's');\n    *p++ = SEPARATOR;\n\n    /* Add method, except when method is INVITE or ACK. */\n    if (method->id != PJSIP_INVITE_METHOD && method->id != PJSIP_ACK_METHOD) {\n\tpj_memcpy(p, method->name.ptr, method->name.slen);\n\tp += method->name.slen;\n\t*p++ = '$';\n    }\n\n    /* Add branch ID. */\n    pj_memcpy(p, branch->ptr, branch->slen);\n    p += branch->slen;\n\n    /* Set length */\n    key->slen = p - key->ptr;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Create key from the incoming data, to be used to search the transaction\n * in the transaction hash table.\n */\nPJ_DEF(pj_status_t) pjsip_tsx_create_key( pj_pool_t *pool, pj_str_t *key, \n\t\t\t\t          pjsip_role_e role, \n\t\t\t\t          const pjsip_method *method, \n\t\t\t\t          const pjsip_rx_data *rdata)\n{\n    pj_str_t rfc3261_branch = {PJSIP_RFC3261_BRANCH_ID, \n                               PJSIP_RFC3261_BRANCH_LEN};\n\n\n    /* Get the branch parameter in the top-most Via.\n     * If branch parameter is started with \"z9hG4bK\", then the message was\n     * generated by agent compliant with RFC3261. Otherwise, it will be\n     * handled as RFC2543.\n     */\n    const pj_str_t *branch = &rdata->msg_info.via->branch_param;\n\n    if (pj_strnicmp(branch,&rfc3261_branch,PJSIP_RFC3261_BRANCH_LEN)==0) {\n\n\t/* Create transaction key. */\n\treturn create_tsx_key_3261(pool, key, role, method, branch);\n\n    } else {\n\t/* Create the key for the message. This key will be matched up \n         * with the transaction key. For RFC2563 transactions, the \n         * transaction key was created by the same function, so it will \n         * match the message.\n\t */\n\treturn create_tsx_key_2543( pool, key, role, method, rdata );\n    }\n}\n\n/*****************************************************************************\n **\n ** Transaction layer module\n **\n *****************************************************************************\n **/\n/*\n * Create transaction layer module and registers it to the endpoint.\n */\nPJ_DEF(pj_status_t) pjsip_tsx_layer_init_module(pjsip_endpoint *endpt)\n{\n    pj_pool_t *pool;\n    pj_status_t status;\n\n\n    PJ_ASSERT_RETURN(mod_tsx_layer.endpt==NULL, PJ_EINVALIDOP);\n\n    /* Initialize timer values */\n    t1_timer_val.sec  = pjsip_cfg()->tsx.t1 / 1000;\n    t1_timer_val.msec = pjsip_cfg()->tsx.t1 % 1000;\n    t2_timer_val.sec  = pjsip_cfg()->tsx.t2 / 1000;\n    t2_timer_val.msec = pjsip_cfg()->tsx.t2 % 1000;\n    t4_timer_val.sec  = pjsip_cfg()->tsx.t4 / 1000;\n    t4_timer_val.msec = pjsip_cfg()->tsx.t4 % 1000;\n    td_timer_val.sec  = pjsip_cfg()->tsx.td / 1000;\n    td_timer_val.msec = pjsip_cfg()->tsx.td % 1000;\n    /* Changed the initialization below to use td_timer_val instead, to enable\n     * customization to the timeout value.\n     */\n    //timeout_timer_val.sec  = (64 * pjsip_cfg()->tsx.t1) / 1000;\n    //timeout_timer_val.msec = (64 * pjsip_cfg()->tsx.t1) % 1000;\n    timeout_timer_val = td_timer_val;\n\n    /*\n     * Initialize transaction layer structure.\n     */\n\n    /* Create pool for the module. */\n    pool = pjsip_endpt_create_pool(endpt, \"tsxlayer\", \n\t\t\t\t   PJSIP_POOL_TSX_LAYER_LEN,\n\t\t\t\t   PJSIP_POOL_TSX_LAYER_INC );\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    \n    /* Initialize some attributes. */\n    mod_tsx_layer.pool = pool;\n    mod_tsx_layer.endpt = endpt;\n\n\n    /* Create hash table. */\n    mod_tsx_layer.htable = pj_hash_create( pool, pjsip_cfg()->tsx.max_count );\n    if (!mod_tsx_layer.htable) {\n\tpjsip_endpt_release_pool(endpt, pool);\n\treturn PJ_ENOMEM;\n    }\n\n    /* Create group lock. */\n    status = pj_mutex_create_recursive(pool, \"tsxlayer\", &mod_tsx_layer.mutex);\n    if (status != PJ_SUCCESS) {\n\tpjsip_endpt_release_pool(endpt, pool);\n\treturn status;\n    }\n\n    /*\n     * Register transaction layer module to endpoint.\n     */\n    status = pjsip_endpt_register_module( endpt, &mod_tsx_layer.mod );\n    if (status != PJ_SUCCESS) {\n\tpj_mutex_destroy(mod_tsx_layer.mutex);\n\tpjsip_endpt_release_pool(endpt, pool);\n\treturn status;\n    }\n\n    /* Register mod_stateful_util module (sip_util_statefull.c) */\n    status = pjsip_endpt_register_module(endpt, &mod_stateful_util);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the instance of transaction layer module.\n */\nPJ_DEF(pjsip_module*) pjsip_tsx_layer_instance(void)\n{\n    return &mod_tsx_layer.mod;\n}\n\n\n/*\n * Unregister and destroy transaction layer module.\n */\nPJ_DEF(pj_status_t) pjsip_tsx_layer_destroy(void)\n{\n    /* Are we registered? */\n    PJ_ASSERT_RETURN(mod_tsx_layer.endpt!=NULL, PJ_EINVALIDOP);\n\n    /* Unregister from endpoint. \n     * Clean-ups will be done in the unload() module callback.\n     */\n    return pjsip_endpt_unregister_module( mod_tsx_layer.endpt, \n\t\t\t\t\t  &mod_tsx_layer.mod);\n}\n\n\n/*\n * Register the transaction to the hash table.\n */\nstatic pj_status_t mod_tsx_layer_register_tsx( pjsip_transaction *tsx)\n{\n    pj_assert(tsx->transaction_key.slen != 0);\n\n    /* Lock hash table mutex. */\n    pj_mutex_lock(mod_tsx_layer.mutex);\n\n    /* Check if no transaction with the same key exists. \n     * Do not use PJ_ASSERT_RETURN since it evaluates the expression\n     * twice!\n     */\n    if(pj_hash_get_lower(mod_tsx_layer.htable, \n\t\t         tsx->transaction_key.ptr,\n\t\t         (unsigned)tsx->transaction_key.slen, \n\t\t         NULL))\n    {\n\tpj_mutex_unlock(mod_tsx_layer.mutex);\n\tPJ_LOG(2,(THIS_FILE, \n\t\t  \"Unable to register %.*s transaction (key exists)\",\n\t\t  (int)tsx->method.name.slen,\n\t\t  tsx->method.name.ptr));\n\treturn PJ_EEXISTS;\n    }\n\n    TSX_TRACE_((THIS_FILE, \n\t\t\"Transaction %p registered with hkey=0x%p and key=%.*s\",\n\t\ttsx, tsx->hashed_key, tsx->transaction_key.slen,\n\t\ttsx->transaction_key.ptr));\n\n    /* Register the transaction to the hash table. */\n#ifdef PRECALC_HASH\n    pj_hash_set_lower( tsx->pool, mod_tsx_layer.htable,\n                       tsx->transaction_key.ptr,\n    \t\t       (unsigned)tsx->transaction_key.slen, \n\t\t       tsx->hashed_key, tsx);\n#else\n    pj_hash_set_lower( tsx->pool, mod_tsx_layer.htable,\n                       tsx->transaction_key.ptr,\n    \t\t       tsx->transaction_key.slen, 0, tsx);\n#endif\n\n    /* Unlock mutex. */\n    pj_mutex_unlock(mod_tsx_layer.mutex);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Unregister the transaction from the hash table.\n */\nstatic void mod_tsx_layer_unregister_tsx( pjsip_transaction *tsx)\n{\n    if (mod_tsx_layer.mod.id == -1) {\n\t/* The transaction layer has been unregistered. This could happen\n\t * if the transaction was pending on transport and the application\n\t * is shutdown. See http://trac.pjsip.org/repos/ticket/1033. In\n\t * this case just do nothing.\n\t */\n\treturn;\n    }\n\n    pj_assert(tsx->transaction_key.slen != 0);\n    //pj_assert(tsx->state != PJSIP_TSX_STATE_NULL);\n\n    /* Lock hash table mutex. */\n    pj_mutex_lock(mod_tsx_layer.mutex);\n\n    /* Register the transaction to the hash table. */\n#ifdef PRECALC_HASH\n    pj_hash_set_lower( NULL, mod_tsx_layer.htable, tsx->transaction_key.ptr,\n    \t\t       (unsigned)tsx->transaction_key.slen, tsx->hashed_key, \n\t\t       NULL);\n#else\n    pj_hash_set_lower( NULL, mod_tsx_layer.htable, tsx->transaction_key.ptr,\n    \t\t       tsx->transaction_key.slen, 0, NULL);\n#endif\n\n    TSX_TRACE_((THIS_FILE, \n\t\t\"Transaction %p unregistered, hkey=0x%p and key=%.*s\",\n\t\ttsx, tsx->hashed_key, tsx->transaction_key.slen,\n\t\ttsx->transaction_key.ptr));\n\n    /* Unlock mutex. */\n    pj_mutex_unlock(mod_tsx_layer.mutex);\n}\n\n\n/*\n * Retrieve the current number of transactions currently registered in \n * the hash table.\n */\nPJ_DEF(unsigned) pjsip_tsx_layer_get_tsx_count(void)\n{\n    unsigned count;\n\n    /* Are we registered? */\n    PJ_ASSERT_RETURN(mod_tsx_layer.endpt!=NULL, 0);\n\n    pj_mutex_lock(mod_tsx_layer.mutex);\n    count = pj_hash_count(mod_tsx_layer.htable);\n    pj_mutex_unlock(mod_tsx_layer.mutex);\n\n    return count;\n}\n\n\n/*\n * Find a transaction.\n */\nPJ_DEF(pjsip_transaction*) pjsip_tsx_layer_find_tsx( const pj_str_t *key,\n\t\t\t\t\t\t     pj_bool_t lock )\n{\n    pjsip_transaction *tsx;\n    pj_uint32_t hval = 0;\n\n    pj_mutex_lock(mod_tsx_layer.mutex);\n    tsx = (pjsip_transaction*)\n    \t  pj_hash_get_lower( mod_tsx_layer.htable, key->ptr, \n\t\t\t     (unsigned)key->slen, &hval );\n    \n    /* Prevent the transaction to get deleted before we have chance to lock it.\n     */\n    if (tsx && lock)\n        pj_grp_lock_add_ref(tsx->grp_lock);\n    \n    pj_mutex_unlock(mod_tsx_layer.mutex);\n\n    TSX_TRACE_((THIS_FILE, \n\t\t\"Finding tsx with hkey=0x%p and key=%.*s: found %p\",\n\t\thval, key->slen, key->ptr, tsx));\n\n    /* Simulate race condition! */\n    PJ_RACE_ME(5);\n\n    if (tsx && lock) {\n\tpj_grp_lock_acquire(tsx->grp_lock);\n        pj_grp_lock_dec_ref(tsx->grp_lock);\n    }\n\n    return tsx;\n}\n\n\n/* This module callback is called when module is being loaded by\n * endpoint. It does nothing for this module.\n */\nstatic pj_status_t mod_tsx_layer_load(pjsip_endpoint *endpt)\n{\n    PJ_UNUSED_ARG(endpt);\n    return PJ_SUCCESS;\n}\n\n\n/* This module callback is called when module is being started by\n * endpoint. It does nothing for this module.\n */\nstatic pj_status_t mod_tsx_layer_start(void)\n{\n    return PJ_SUCCESS;\n}\n\n\n/* This module callback is called when module is being stopped by\n * endpoint. \n */\nstatic pj_status_t mod_tsx_layer_stop(void)\n{\n    pj_hash_iterator_t it_buf, *it;\n\n    PJ_LOG(4,(THIS_FILE, \"Stopping transaction layer module\"));\n\n    pj_mutex_lock(mod_tsx_layer.mutex);\n\n    /* Destroy all transactions. */\n    it = pj_hash_first(mod_tsx_layer.htable, &it_buf);\n    while (it) {\n\tpjsip_transaction *tsx = (pjsip_transaction*) \n\t\t\t\t pj_hash_this(mod_tsx_layer.htable, it);\n\tpj_hash_iterator_t *next = pj_hash_next(mod_tsx_layer.htable, it);\n\tif (tsx) {\n\t    pjsip_tsx_terminate(tsx, PJSIP_SC_SERVICE_UNAVAILABLE);\n\t    mod_tsx_layer_unregister_tsx(tsx);\n\t    tsx_shutdown(tsx);\n\t}\n\tit = next;\n    }\n\n    pj_mutex_unlock(mod_tsx_layer.mutex);\n\n    PJ_LOG(4,(THIS_FILE, \"Stopped transaction layer module\"));\n\n    return PJ_SUCCESS;\n}\n\n\n/* Destroy this module */\nstatic void tsx_layer_destroy(pjsip_endpoint *endpt)\n{\n    PJ_UNUSED_ARG(endpt);\n\n    /* Destroy mutex. */\n    pj_mutex_destroy(mod_tsx_layer.mutex);\n\n    /* Release pool. */\n    pjsip_endpt_release_pool(mod_tsx_layer.endpt, mod_tsx_layer.pool);\n\n    /* Mark as unregistered. */\n    mod_tsx_layer.endpt = NULL;\n\n    PJ_LOG(4,(THIS_FILE, \"Transaction layer module destroyed\"));\n}\n\n\n/* This module callback is called when module is being unloaded by\n * endpoint.\n */\nstatic pj_status_t mod_tsx_layer_unload(void)\n{\n    /* Only self destroy when there's no transaction in the table.\n     * Transaction may refuse to destroy when it has pending\n     * transmission. If we destroy the module now, application will\n     * crash when the pending transaction finally got error response\n     * from transport and when it tries to unregister itself.\n     */\n    if (pj_hash_count(mod_tsx_layer.htable) != 0) {\n\tif (pjsip_endpt_atexit(mod_tsx_layer.endpt, &tsx_layer_destroy) !=\n\t    PJ_SUCCESS)\n\t{\n\t    PJ_LOG(3,(THIS_FILE, \"Failed to register transaction layer \"\n\t\t\t\t \"module destroy.\"));\n\t}\n\treturn PJ_EBUSY;\n    }\n\n    tsx_layer_destroy(mod_tsx_layer.endpt);\n\n    return PJ_SUCCESS;\n}\n\n\n/* This module callback is called when endpoint has received an\n * incoming request message.\n */\nstatic pj_bool_t mod_tsx_layer_on_rx_request(pjsip_rx_data *rdata)\n{\n    pj_str_t key;\n    pj_uint32_t hval = 0;\n    pjsip_transaction *tsx;\n\n    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAS,\n\t\t\t &rdata->msg_info.cseq->method, rdata);\n\n    /* Find transaction. */\n    pj_mutex_lock( mod_tsx_layer.mutex );\n\n    tsx = (pjsip_transaction*) \n    \t  pj_hash_get_lower( mod_tsx_layer.htable, key.ptr, (unsigned)key.slen, \n\t\t\t     &hval );\n\n\n    TSX_TRACE_((THIS_FILE, \n\t\t\"Finding tsx for request, hkey=0x%p and key=%.*s, found %p\",\n\t\thval, key.slen, key.ptr, tsx));\n\n\n    if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) {\n\t/* Transaction not found.\n\t * Reject the request so that endpoint passes the request to\n\t * upper layer modules.\n\t */\n\tpj_mutex_unlock( mod_tsx_layer.mutex);\n\treturn PJ_FALSE;\n    }\n\n    /* Prevent the transaction to get deleted before we have chance to lock it\n     * in pjsip_tsx_recv_msg().\n     */\n    pj_grp_lock_add_ref(tsx->grp_lock);\n    \n    /* Unlock hash table. */\n    pj_mutex_unlock( mod_tsx_layer.mutex );\n\n    /* Simulate race condition! */\n    PJ_RACE_ME(5);\n\n    /* Pass the message to the transaction. */\n    pjsip_tsx_recv_msg(tsx, rdata );\n    \n    pj_grp_lock_dec_ref(tsx->grp_lock);\n\n    return PJ_TRUE;\n}\n\n\n/* This module callback is called when endpoint has received an\n * incoming response message.\n */\nstatic pj_bool_t mod_tsx_layer_on_rx_response(pjsip_rx_data *rdata)\n{\n    pj_str_t key;\n    pj_uint32_t hval = 0;\n    pjsip_transaction *tsx;\n\n    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAC,\n\t\t\t &rdata->msg_info.cseq->method, rdata);\n\n    /* Find transaction. */\n    pj_mutex_lock( mod_tsx_layer.mutex );\n\n    tsx = (pjsip_transaction*) \n    \t  pj_hash_get_lower( mod_tsx_layer.htable, key.ptr, (unsigned)key.slen, \n\t\t\t     &hval );\n\n\n    TSX_TRACE_((THIS_FILE, \n\t\t\"Finding tsx for response, hkey=0x%p and key=%.*s, found %p\",\n\t\thval, key.slen, key.ptr, tsx));\n\n\n    if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) {\n\t/* Transaction not found.\n\t * Reject the request so that endpoint passes the request to\n\t * upper layer modules.\n\t */\n\tpj_mutex_unlock( mod_tsx_layer.mutex);\n\treturn PJ_FALSE;\n    }\n\n    /* Prevent the transaction to get deleted before we have chance to lock it\n     * in pjsip_tsx_recv_msg().\n     */\n    pj_grp_lock_add_ref(tsx->grp_lock);\n\n    /* Unlock hash table. */\n    pj_mutex_unlock( mod_tsx_layer.mutex );\n\n    /* Simulate race condition! */\n    PJ_RACE_ME(5);\n\n    /* Pass the message to the transaction. */\n    pjsip_tsx_recv_msg(tsx, rdata );\n    \n    pj_grp_lock_dec_ref(tsx->grp_lock);\n\n    return PJ_TRUE;\n}\n\n\n/*\n * Get transaction instance in the rdata.\n */\nPJ_DEF(pjsip_transaction*) pjsip_rdata_get_tsx( pjsip_rx_data *rdata )\n{\n    return (pjsip_transaction*) \n    \t   rdata->endpt_info.mod_data[mod_tsx_layer.mod.id];\n}\n\n\n/*\n * Dump transaction layer.\n */\nPJ_DEF(void) pjsip_tsx_layer_dump(pj_bool_t detail)\n{\n#if PJ_LOG_MAX_LEVEL >= 3\n    pj_hash_iterator_t itbuf, *it;\n\n    /* Lock mutex. */\n    pj_mutex_lock(mod_tsx_layer.mutex);\n\n    PJ_LOG(3, (THIS_FILE, \"Dumping transaction table:\"));\n    PJ_LOG(3, (THIS_FILE, \" Total %d transactions\", \n\t\t\t  pj_hash_count(mod_tsx_layer.htable)));\n\n    if (detail) {\n\tit = pj_hash_first(mod_tsx_layer.htable, &itbuf);\n\tif (it == NULL) {\n\t    PJ_LOG(3, (THIS_FILE, \" - none - \"));\n\t} else {\n\t    while (it != NULL) {\n\t\tpjsip_transaction *tsx = (pjsip_transaction*) \n\t\t\t\t\t pj_hash_this(mod_tsx_layer.htable,it);\n\n\t\tPJ_LOG(3, (THIS_FILE, \" %s %s|%d|%s\",\n\t\t\t   tsx->obj_name,\n\t\t\t   (tsx->last_tx? \n\t\t\t\tpjsip_tx_data_get_info(tsx->last_tx): \n\t\t\t\t\"none\"),\n\t\t\t   tsx->status_code,\n\t\t\t   pjsip_tsx_state_str(tsx->state)));\n\n\t\tit = pj_hash_next(mod_tsx_layer.htable, it);\n\t    }\n\t}\n    }\n\n    /* Unlock mutex. */\n    pj_mutex_unlock(mod_tsx_layer.mutex);\n#endif\n}\n\n/*****************************************************************************\n **\n ** Transaction\n **\n *****************************************************************************\n **/\n/* Lock transaction for accessing the timeout timer only. */\nstatic void lock_timer(pjsip_transaction *tsx)\n{\n    pj_mutex_lock(tsx->mutex_b);\n}\n\n/* Unlock timer */\nstatic void unlock_timer(pjsip_transaction *tsx)\n{\n    pj_mutex_unlock(tsx->mutex_b);\n}\n\n/* Utility: schedule a timer */\nstatic pj_status_t tsx_schedule_timer(pjsip_transaction *tsx,\n                                      pj_timer_entry *entry,\n                                      const pj_time_val *delay,\n                                      int active_id)\n{\n    pj_timer_heap_t *timer_heap = pjsip_endpt_get_timer_heap(tsx->endpt);\n    pj_status_t status;\n\n    pj_assert(active_id != 0);\n    status = pj_timer_heap_schedule_w_grp_lock(timer_heap, entry,\n                                               delay, active_id,\n                                               tsx->grp_lock);\n\n    return status;\n}\n\n/* Utility: cancel a timer */\nstatic int tsx_cancel_timer(pjsip_transaction *tsx,\n                            pj_timer_entry *entry)\n{\n    pj_timer_heap_t *timer_heap = pjsip_endpt_get_timer_heap(tsx->endpt);\n    return pj_timer_heap_cancel_if_active(timer_heap, entry, TIMER_INACTIVE);\n}\n\n/* Create and initialize basic transaction structure.\n * This function is called by both UAC and UAS creation.\n */\nstatic pj_status_t tsx_create( pjsip_module *tsx_user,\n                               pj_grp_lock_t *grp_lock,\n\t\t\t       pjsip_transaction **p_tsx)\n{\n    pj_pool_t *pool;\n    pjsip_transaction *tsx;\n    pj_status_t status;\n\n    pool = pjsip_endpt_create_pool( mod_tsx_layer.endpt, \"tsx\", \n\t\t\t\t    PJSIP_POOL_TSX_LEN, PJSIP_POOL_TSX_INC );\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    tsx = PJ_POOL_ZALLOC_T(pool, pjsip_transaction);\n    tsx->pool = pool;\n    tsx->tsx_user = tsx_user;\n    tsx->endpt = mod_tsx_layer.endpt;\n\n    pj_ansi_snprintf(tsx->obj_name, sizeof(tsx->obj_name), \n\t\t     \"tsx%p\", tsx);\n    pj_memcpy(pool->obj_name, tsx->obj_name, sizeof(pool->obj_name));\n\n    tsx->handle_200resp = 1;\n    tsx->retransmit_timer.id = TIMER_INACTIVE;\n    tsx->retransmit_timer.user_data = tsx;\n    tsx->retransmit_timer.cb = &tsx_timer_callback;\n    tsx->timeout_timer.id = TIMER_INACTIVE;\n    tsx->timeout_timer.user_data = tsx;\n    tsx->timeout_timer.cb = &tsx_timer_callback;\n    \n    if (grp_lock) {\n\ttsx->grp_lock = grp_lock;\n        \n        pj_grp_lock_add_ref(tsx->grp_lock);\n        pj_grp_lock_add_handler(tsx->grp_lock, tsx->pool, tsx, &tsx_on_destroy);\n    } else {\n\tstatus = pj_grp_lock_create_w_handler(pool, NULL, tsx, &tsx_on_destroy,\n\t\t\t\t\t      &tsx->grp_lock);\n\tif (status != PJ_SUCCESS) {\n\t    pjsip_endpt_release_pool(mod_tsx_layer.endpt, pool);\n\t    return status;\n\t}\n\t\n\tpj_grp_lock_add_ref(tsx->grp_lock);\n    }\n\n    status = pj_mutex_create_simple(pool, tsx->obj_name, &tsx->mutex_b);\n    if (status != PJ_SUCCESS) {\n\ttsx_shutdown(tsx);\n\treturn status;\n    }\n\n    *p_tsx = tsx;\n    return PJ_SUCCESS;\n}\n\n/* Really destroy transaction, when grp_lock reference is zero */\nstatic void tsx_on_destroy( void *arg )\n{\n    pjsip_transaction *tsx = (pjsip_transaction*)arg;\n\n    PJ_LOG(5,(tsx->obj_name, \"Transaction destroyed!\"));\n\n    pj_mutex_destroy(tsx->mutex_b);\n    pjsip_endpt_release_pool(tsx->endpt, tsx->pool);\n}\n\n/* Shutdown transaction. */\nstatic pj_status_t tsx_shutdown( pjsip_transaction *tsx )\n{\n    /* Release the transport */\n    tsx_update_transport(tsx, NULL);\n\n    /* Decrement reference counter in transport selector, only if\n     * we haven't been called before */\n    if (!tsx->terminating) {\n\tpjsip_tpselector_dec_ref(&tsx->tp_sel);\n    }\n\n    /* Free last transmitted message. */\n    if (tsx->last_tx) {\n\tpjsip_tx_data_dec_ref( tsx->last_tx );\n\ttsx->last_tx = NULL;\n    }\n    /* Cancel timeout timer. */\n    tsx_cancel_timer(tsx, &tsx->timeout_timer);\n\n    /* Cancel retransmission timer. */\n    tsx_cancel_timer(tsx, &tsx->retransmit_timer);\n\n    /* Clear some pending flags. */\n    tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED | TSX_HAS_PENDING_SEND);\n\n\n    /* Refuse to destroy transaction if it has pending resolving. */\n    if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {\n\ttsx->transport_flag |= TSX_HAS_PENDING_DESTROY;\n\ttsx->tsx_user = NULL;\n\tPJ_LOG(4,(tsx->obj_name, \"Will destroy later because transport is \"\n\t\t\t\t \"in progress\"));\n    }\n\n    if (!tsx->terminating) {\n\ttsx->terminating = PJ_TRUE;\n\tpj_grp_lock_dec_ref(tsx->grp_lock);\n    }\n\n    /* No acccess to tsx after this, it may have been destroyed */\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Callback when timer expires. Transport error also piggybacks this event\n * to avoid deadlock (https://trac.pjsip.org/repos/ticket/1646).\n */\nstatic void tsx_timer_callback( pj_timer_heap_t *theap, pj_timer_entry *entry)\n{\n    pjsip_transaction *tsx = (pjsip_transaction*) entry->user_data;\n\n    PJ_UNUSED_ARG(theap);\n\n    if (entry->id == TRANSPORT_ERR_TIMER) {\n\t/* Posted transport error event */\n\tentry->id = 0;\n\tif (tsx->state < PJSIP_TSX_STATE_TERMINATED) {\n\t    pjsip_tsx_state_e prev_state;\n\t    pj_time_val timeout = { 0, 0 };\n\n\t    pj_grp_lock_acquire(tsx->grp_lock);\n\t    prev_state = tsx->state;\n\n\t    /* Release transport as it's no longer working. */\n\t    tsx_update_transport(tsx, NULL);\n\n\t    if (tsx->status_code < 200) {\n\t\tpj_str_t err;\n\t\tchar errmsg[PJ_ERR_MSG_SIZE];\n\n\t\terr = pj_strerror(tsx->transport_err, errmsg, sizeof(errmsg));\n\t\ttsx_set_status_code(tsx, PJSIP_SC_TSX_TRANSPORT_ERROR, &err);\n\t    }\n\n\t    /* Set transaction state etc, but don't notify TU now,\n\t     * otherwise we'll get a deadlock. See:\n\t     * https://trac.pjsip.org/repos/ticket/1646\n\t     */\n\t    /* Also don't schedule tsx handler, otherwise we'll get race\n\t     * condition of TU notifications due to delayed TERMINATED\n\t     * state TU notification. It happened in multiple worker threads\n\t     * environment between TERMINATED & DESTROYED! See:\n\t     * https://trac.pjsip.org/repos/ticket/1902\n\t     */\n\t    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,\n\t                   PJSIP_EVENT_TRANSPORT_ERROR, NULL,\n\t\t\t   NO_NOTIFY | NO_SCHEDULE_HANDLER);\n\t    pj_grp_lock_release(tsx->grp_lock);\n\n\t    /* Now notify TU about state change, WITHOUT holding the\n\t     * group lock. It should be safe to do so; transaction will\n\t     * not get destroyed because group lock reference counter\n\t     * has been incremented by the timer heap.\n\t     */\n\t    if (tsx->tsx_user && tsx->tsx_user->on_tsx_state) {\n\t\tpjsip_event e;\n\t\tPJSIP_EVENT_INIT_TSX_STATE(e, tsx,\n\t\t                           PJSIP_EVENT_TRANSPORT_ERROR, NULL,\n\t\t\t\t\t   prev_state);\n\t\t(*tsx->tsx_user->on_tsx_state)(tsx, &e);\n\t    }\n\n\t    /* Now let's schedule the tsx handler */\n\t    tsx_schedule_timer(tsx, &tsx->timeout_timer, &timeout,\n\t\t\t       TIMEOUT_TIMER);\n\t}\n    } else {\n\tpjsip_event event;\n\n\tentry->id = 0;\n\n\tPJ_LOG(5,(tsx->obj_name, \"%s timer event\",\n\t\t (entry==&tsx->retransmit_timer ? \"Retransmit\":\"Timeout\")));\n\tpj_log_push_indent();\n\n\n\tPJSIP_EVENT_INIT_TIMER(event, entry);\n\n\t/* Dispatch event to transaction. */\n\tpj_grp_lock_acquire(tsx->grp_lock);\n\t(*tsx->state_handler)(tsx, &event);\n\tpj_grp_lock_release(tsx->grp_lock);\n\n\tpj_log_pop_indent();\n    }\n}\n\n\n/*\n * Set transaction state, and inform TU about the transaction state change.\n */\nstatic void tsx_set_state( pjsip_transaction *tsx,\n\t\t\t   pjsip_tsx_state_e state,\n\t\t\t   pjsip_event_id_e event_src_type,\n                           void *event_src,\n\t\t\t   int flag)\n{\n    pjsip_tsx_state_e prev_state = tsx->state;\n\n    /* New state must be greater than previous state */\n    pj_assert(state >= tsx->state);\n\n    PJ_LOG(5, (tsx->obj_name, \"State changed from %s to %s, event=%s\",\n\t       state_str[tsx->state], state_str[state], \n               pjsip_event_str(event_src_type)));\n    pj_log_push_indent();\n\n    /* Change state. */\n    tsx->state = state;\n\n    /* Update the state handlers. */\n    if (tsx->role == PJSIP_ROLE_UAC) {\n\ttsx->state_handler = tsx_state_handler_uac[state];\n    } else {\n\ttsx->state_handler = tsx_state_handler_uas[state];\n    }\n\n    /* Before informing TU about state changed, inform TU about\n     * rx event.\n     */\n    if (event_src_type==PJSIP_EVENT_RX_MSG && tsx->tsx_user &&\n\t(flag & NO_NOTIFY)==0)\n    {\n\tpjsip_rx_data *rdata = (pjsip_rx_data*) event_src;\n\n\tpj_assert(rdata != NULL);\n\n\tif (rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG &&\n\t\t   tsx->tsx_user->on_rx_response)\n\t{\n\t    (*tsx->tsx_user->on_rx_response)(rdata);\n\t}\n\n    }\n\n    /* Inform TU about state changed. */\n    if (tsx->tsx_user && tsx->tsx_user->on_tsx_state &&\n\t(flag & NO_NOTIFY) == 0)\n    {\n\tpjsip_event e;\n\tPJSIP_EVENT_INIT_TSX_STATE(e, tsx, event_src_type, event_src,\n\t\t\t\t   prev_state);\n\t(*tsx->tsx_user->on_tsx_state)(tsx, &e);\n    }\n    \n\n    /* When the transaction is terminated, release transport, and free the\n     * saved last transmitted message.\n     */\n    if (state == PJSIP_TSX_STATE_TERMINATED) {\n\tpj_time_val timeout = { 0, 0 };\n\n\t/* If we're still waiting for a message to be sent.. */\n\tif (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {\n\t    /* Disassociate ourselves from the outstanding transmit data\n\t     * so that when the send callback is called we will be able\n\t     * to ignore that (otherwise we'll get assertion, see\n\t     * http://trac.pjsip.org/repos/ticket/1033)\n\t     */\n\t    if (tsx->pending_tx) {\n\t\ttsx->pending_tx->mod_data[mod_tsx_layer.mod.id] = NULL;\n\t\ttsx->pending_tx = NULL;\n\t    }\n\t    tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT);\n\t}\n\n\tlock_timer(tsx);\n\ttsx_cancel_timer(tsx, &tsx->timeout_timer);\n\tif ((flag & NO_SCHEDULE_HANDLER) == 0) {\n\t    tsx_schedule_timer(tsx, &tsx->timeout_timer, &timeout,\n\t\t\t       TIMEOUT_TIMER);\n\t}\n\tunlock_timer(tsx);\n\n    } else if (state == PJSIP_TSX_STATE_DESTROYED) {\n\n\t/* Unregister transaction. */\n\tmod_tsx_layer_unregister_tsx(tsx);\n\n\t/* Destroy transaction. */\n\ttsx_shutdown(tsx);\n    }\n\n    pj_log_pop_indent();\n}\n\n/*\n * Create, initialize, and register UAC transaction.\n */\nPJ_DEF(pj_status_t) pjsip_tsx_create_uac( pjsip_module *tsx_user,\n\t\t\t\t\t  pjsip_tx_data *tdata,\n\t\t\t\t\t  pjsip_transaction **p_tsx)\n{\n    return pjsip_tsx_create_uac2(tsx_user, tdata, NULL, p_tsx);\n}\n\nPJ_DEF(pj_status_t) pjsip_tsx_create_uac2(pjsip_module *tsx_user,\n\t\t\t\t\t  pjsip_tx_data *tdata,\n\t\t\t\t\t  pj_grp_lock_t *grp_lock,\n\t\t\t\t\t  pjsip_transaction **p_tsx)\n{\n    pjsip_transaction *tsx;\n    pjsip_msg *msg;\n    pjsip_cseq_hdr *cseq;\n    pjsip_via_hdr *via;\n    pjsip_host_info dst_info;\n    pj_status_t status;\n\n    /* Validate arguments. */\n    PJ_ASSERT_RETURN(tdata && tdata->msg && p_tsx, PJ_EINVAL);\n    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,\n\t\t     PJSIP_ENOTREQUESTMSG);\n\n    /* Method MUST NOT be ACK! */\n    PJ_ASSERT_RETURN(tdata->msg->line.req.method.id != PJSIP_ACK_METHOD,\n\t\t     PJ_EINVALIDOP);\n\n    /* Keep shortcut */\n    msg = tdata->msg;\n\n    /* Make sure CSeq header is present. */\n    cseq = (pjsip_cseq_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL);\n    if (!cseq) {\n\tpj_assert(!\"CSeq header not present in outgoing message!\");\n\treturn PJSIP_EMISSINGHDR;\n    }\n\n\n    /* Create transaction instance. */\n    status = tsx_create( tsx_user, grp_lock, &tsx);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n\n    /* Lock transaction.\n     * We don't need to lock the group lock if none was supplied, while the\n     * newly created group lock has not been exposed.\n     */\n    if (grp_lock)\n        pj_grp_lock_acquire(tsx->grp_lock);\n\n    /* Role is UAC. */\n    tsx->role = PJSIP_ROLE_UAC;\n\n    /* Save method. */\n    pjsip_method_copy( tsx->pool, &tsx->method, &msg->line.req.method);\n\n    /* Save CSeq. */\n    tsx->cseq = cseq->cseq;\n\n    /* Generate Via header if it doesn't exist. */\n    via = (pjsip_via_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_VIA, NULL);\n    if (via == NULL) {\n\tvia = pjsip_via_hdr_create(tdata->pool);\n\tpjsip_msg_insert_first_hdr(msg, (pjsip_hdr*) via);\n    }\n\n    /* Generate branch parameter if it doesn't exist. */\n    if (via->branch_param.slen == 0) {\n\tpj_str_t tmp;\n\tvia->branch_param.ptr = (char*)\n\t\t\t\tpj_pool_alloc(tsx->pool, PJSIP_MAX_BRANCH_LEN);\n\tvia->branch_param.slen = PJSIP_MAX_BRANCH_LEN;\n\tpj_memcpy(via->branch_param.ptr, PJSIP_RFC3261_BRANCH_ID, \n\t\t  PJSIP_RFC3261_BRANCH_LEN);\n\ttmp.ptr = via->branch_param.ptr + PJSIP_RFC3261_BRANCH_LEN + 2;\n\t*(tmp.ptr-2) = 80; *(tmp.ptr-1) = 106;\n\tpj_generate_unique_string( &tmp );\n\n        /* Save branch parameter. */\n        tsx->branch = via->branch_param;\n\n    } else {\n        /* Copy branch parameter. */\n        pj_strdup(tsx->pool, &tsx->branch, &via->branch_param);\n    }\n\n   /* Generate transaction key. */\n    create_tsx_key_3261( tsx->pool, &tsx->transaction_key,\n\t\t\t PJSIP_ROLE_UAC, &tsx->method, \n\t\t\t &via->branch_param);\n\n    /* Calculate hashed key value. */\n#ifdef PRECALC_HASH\n    tsx->hashed_key = pj_hash_calc_tolower(0, NULL, &tsx->transaction_key);\n#endif\n\n    PJ_LOG(6, (tsx->obj_name, \"tsx_key=%.*s\", tsx->transaction_key.slen,\n\t       tsx->transaction_key.ptr));\n\n    /* Begin with State_Null.\n     * Manually set-up the state becase we don't want to call the callback.\n     */\n    tsx->state = PJSIP_TSX_STATE_NULL;\n    tsx->state_handler = &tsx_on_state_null;\n\n    /* Save the message. */\n    tsx->last_tx = tdata;\n    pjsip_tx_data_add_ref(tsx->last_tx);\n\n    /* Determine whether reliable transport should be used initially.\n     * This will be updated whenever transport has changed.\n     */\n    status = pjsip_get_request_dest(tdata, &dst_info);\n    if (status != PJ_SUCCESS) {\n\tif (grp_lock)\n\t    pj_grp_lock_release(tsx->grp_lock);\n\ttsx_shutdown(tsx);\n\treturn status;\n    }\n    tsx->is_reliable = (dst_info.flag & PJSIP_TRANSPORT_RELIABLE);\n\n    /* Register transaction to hash table. */\n    status = mod_tsx_layer_register_tsx(tsx);\n    if (status != PJ_SUCCESS) {\n\t/* The assertion is removed by #1090:\n\tpj_assert(!\"Bug in branch_param generator (i.e. not unique)\");\n\t*/\n\tif (grp_lock)\n\t    pj_grp_lock_release(tsx->grp_lock);\n\ttsx_shutdown(tsx);\n\treturn status;\n    }\n\n\n    /* Unlock transaction and return. */\n    if (grp_lock)\n        pj_grp_lock_release(tsx->grp_lock);\n\n    pj_log_push_indent();\n    PJ_LOG(5,(tsx->obj_name, \"Transaction created for %s\",\n\t      pjsip_tx_data_get_info(tdata)));\n    pj_log_pop_indent();\n\n    *p_tsx = tsx;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create, initialize, and register UAS transaction.\n */\nPJ_DEF(pj_status_t) pjsip_tsx_create_uas( pjsip_module *tsx_user,\n\t\t\t\t\t  pjsip_rx_data *rdata,\n\t\t\t\t\t  pjsip_transaction **p_tsx)\n{\n    return pjsip_tsx_create_uas2(tsx_user, rdata, NULL, p_tsx);\n}\n\nPJ_DEF(pj_status_t) pjsip_tsx_create_uas2(pjsip_module *tsx_user,\n\t\t\t\t\t  pjsip_rx_data *rdata,\n\t\t\t\t\t  pj_grp_lock_t *grp_lock,\n\t\t\t\t\t  pjsip_transaction **p_tsx)\n{\n    pjsip_transaction *tsx;\n    pjsip_msg *msg;\n    pj_str_t *branch;\n    pjsip_cseq_hdr *cseq;\n    pj_status_t status;\n\n    /* Validate arguments. */\n    PJ_ASSERT_RETURN(rdata && rdata->msg_info.msg && p_tsx, PJ_EINVAL);\n\n    /* Keep shortcut to message */\n    msg = rdata->msg_info.msg;\n    \n    /* Make sure this is a request message. */\n    PJ_ASSERT_RETURN(msg->type == PJSIP_REQUEST_MSG, PJSIP_ENOTREQUESTMSG);\n\n    /* Make sure method is not ACK */\n    PJ_ASSERT_RETURN(msg->line.req.method.id != PJSIP_ACK_METHOD,\n\t\t     PJ_EINVALIDOP);\n\n    /* Make sure CSeq header is present. */\n    cseq = rdata->msg_info.cseq;\n    if (!cseq)\n\treturn PJSIP_EMISSINGHDR;\n\n    /* Make sure Via header is present. */\n    if (rdata->msg_info.via == NULL)\n\treturn PJSIP_EMISSINGHDR;\n\n    /* Check that method in CSeq header match request method.\n     * Reference: PROTOS #1922\n     */\n    if (pjsip_method_cmp(&msg->line.req.method, \n\t\t\t &rdata->msg_info.cseq->method) != 0)\n    {\n\tPJ_LOG(4,(THIS_FILE, \"Error: CSeq header contains different \"\n\t\t\t     \"method than the request line\"));\n\treturn PJSIP_EINVALIDHDR;\n    }\n\n    /* \n     * Create transaction instance. \n     */\n    status = tsx_create( tsx_user, grp_lock, &tsx);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n\n    /* Lock transaction. */\n    pj_grp_lock_acquire(tsx->grp_lock);\n\n    /* Role is UAS */\n    tsx->role = PJSIP_ROLE_UAS;\n\n    /* Save method. */\n    pjsip_method_copy( tsx->pool, &tsx->method, &msg->line.req.method);\n\n    /* Save CSeq */\n    tsx->cseq = cseq->cseq;\n\n    /* Get transaction key either from branch for RFC3261 message, or\n     * create transaction key.\n     */\n    status = pjsip_tsx_create_key(tsx->pool, &tsx->transaction_key, \n                                  PJSIP_ROLE_UAS, &tsx->method, rdata);\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_release(tsx->grp_lock);\n\ttsx_shutdown(tsx);\n        return status;\n    }\n\n    /* Calculate hashed key value. */\n#ifdef PRECALC_HASH\n    tsx->hashed_key = pj_hash_calc_tolower(0, NULL, &tsx->transaction_key);\n#endif\n\n    /* Duplicate branch parameter for transaction. */\n    branch = &rdata->msg_info.via->branch_param;\n    pj_strdup(tsx->pool, &tsx->branch, branch);\n\n    PJ_LOG(6, (tsx->obj_name, \"tsx_key=%.*s\", tsx->transaction_key.slen,\n\t       tsx->transaction_key.ptr));\n\n\n    /* Begin with state NULL.\n     * Manually set-up the state becase we don't want to call the callback.\n     */\n    tsx->state = PJSIP_TSX_STATE_NULL; \n    tsx->state_handler = &tsx_on_state_null;\n\n    /* Get response address. */\n    status = pjsip_get_response_addr( tsx->pool, rdata, &tsx->res_addr );\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_release(tsx->grp_lock);\n\ttsx_shutdown(tsx);\n\treturn status;\n    }\n\n    /* If it's decided that we should use current transport, keep the\n     * transport.\n     */\n    if (tsx->res_addr.transport) {\n\ttsx_update_transport(tsx, tsx->res_addr.transport);\n\tpj_memcpy(&tsx->addr, &tsx->res_addr.addr, tsx->res_addr.addr_len);\n\ttsx->addr_len = tsx->res_addr.addr_len;\n\ttsx->is_reliable = PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport);\n    } else {\n\ttsx->is_reliable = \n\t    (tsx->res_addr.dst_host.flag & PJSIP_TRANSPORT_RELIABLE);\n    }\n\n\n    /* Register the transaction. */\n    status = mod_tsx_layer_register_tsx(tsx);\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_release(tsx->grp_lock);\n\ttsx_shutdown(tsx);\n\treturn status;\n    }\n\n    /* Put this transaction in rdata's mod_data. */\n    rdata->endpt_info.mod_data[mod_tsx_layer.mod.id] = tsx;\n\n    /* Unlock transaction and return. */\n    pj_grp_lock_release(tsx->grp_lock);\n\n    pj_log_push_indent();\n    PJ_LOG(5,(tsx->obj_name, \"Transaction created for %s\",\n\t      pjsip_rx_data_get_info(rdata)));\n    pj_log_pop_indent();\n\n\n    *p_tsx = tsx;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Bind transaction to a specific transport/listener. \n */\nPJ_DEF(pj_status_t) pjsip_tsx_set_transport(pjsip_transaction *tsx,\n\t\t\t\t\t    const pjsip_tpselector *sel)\n{\n    /* Must be UAC transaction */\n    PJ_ASSERT_RETURN(tsx && sel, PJ_EINVAL);\n\n    /* Start locking the transaction. */\n    pj_grp_lock_acquire(tsx->grp_lock);\n\n    /* Decrement reference counter of previous transport selector */\n    pjsip_tpselector_dec_ref(&tsx->tp_sel);\n\n    /* Copy transport selector structure .*/\n    pj_memcpy(&tsx->tp_sel, sel, sizeof(*sel));\n\n    /* Increment reference counter */\n    pjsip_tpselector_add_ref(&tsx->tp_sel);\n\n    /* Unlock transaction. */\n    pj_grp_lock_release(tsx->grp_lock);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Set transaction status code and reason.\n */\nstatic void tsx_set_status_code(pjsip_transaction *tsx,\n\t\t\t   \tint code, const pj_str_t *reason)\n{\n    tsx->status_code = code;\n    if (reason)\n\tpj_strdup(tsx->pool, &tsx->status_text, reason);\n    else\n\ttsx->status_text = *pjsip_get_status_text(code);\n}\n\n\n/*\n * Forcely terminate transaction.\n */\nPJ_DEF(pj_status_t) pjsip_tsx_terminate( pjsip_transaction *tsx, int code )\n{\n    PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL);\n\n    PJ_LOG(5,(tsx->obj_name, \"Request to terminate transaction\"));\n\n    PJ_ASSERT_RETURN(code >= 200, PJ_EINVAL);\n\n    pj_log_push_indent();\n\n    pj_grp_lock_acquire(tsx->grp_lock);\n\n    if (tsx->state < PJSIP_TSX_STATE_TERMINATED) {\n        tsx_set_status_code(tsx, code, NULL);\n        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, PJSIP_EVENT_USER,\n\t\t       NULL, 0);\n    }\n    pj_grp_lock_release(tsx->grp_lock);\n\n    pj_log_pop_indent();\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Cease retransmission on the UAC transaction. The UAC transaction is\n * still considered running, and it will complete when either final\n * response is received or the transaction times out.\n */\nPJ_DEF(pj_status_t) pjsip_tsx_stop_retransmit(pjsip_transaction *tsx)\n{\n    PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL);\n    PJ_ASSERT_RETURN(tsx->role == PJSIP_ROLE_UAC &&\n\t\t     tsx->method.id == PJSIP_INVITE_METHOD,\n\t\t     PJ_EINVALIDOP);\n\n    PJ_LOG(5,(tsx->obj_name, \"Request to stop retransmission\"));\n\n    pj_log_push_indent();\n\n    pj_grp_lock_acquire(tsx->grp_lock);\n    /* Cancel retransmission timer. */\n    tsx_cancel_timer(tsx, &tsx->retransmit_timer);\n    pj_grp_lock_release(tsx->grp_lock);\n\n    pj_log_pop_indent();\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Start a timer to terminate transaction after the specified time\n * has elapsed. \n */\nPJ_DEF(pj_status_t) pjsip_tsx_set_timeout( pjsip_transaction *tsx,\n\t\t\t\t\t   unsigned millisec)\n{\n    pj_time_val timeout;\n\n    PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL);\n    PJ_ASSERT_RETURN(tsx->role == PJSIP_ROLE_UAC &&\n\t\t     tsx->method.id == PJSIP_INVITE_METHOD,\n\t\t     PJ_EINVALIDOP);\n\n    /* Note: must not call pj_grp_lock_acquire(tsx->grp_lock) as\n     * that would introduce deadlock. See #1121.\n     */\n    lock_timer(tsx);\n\n    /* Transaction should normally not have final response, but as\n     * #1121 says there is a (tolerable) window of race condition\n     * where this might happen.\n     */\n    if (tsx->status_code >= 200 && tsx->timeout_timer.id != 0) {\n\t/* Timeout is already set */\n\tunlock_timer(tsx);\n\treturn PJ_EEXISTS;\n    }\n\n    tsx_cancel_timer(tsx, &tsx->timeout_timer);\n\n    timeout.sec = 0;\n    timeout.msec = millisec;\n    pj_time_val_normalize(&timeout);\n\n    tsx_schedule_timer(tsx, &tsx->timeout_timer, &timeout, TIMEOUT_TIMER);\n\n    unlock_timer(tsx);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * This function is called by TU to send a message.\n */\nPJ_DEF(pj_status_t) pjsip_tsx_send_msg( pjsip_transaction *tsx, \n\t\t\t\t        pjsip_tx_data *tdata )\n{\n    pjsip_event event;\n    pj_status_t status;\n\n    if (tdata == NULL)\n\ttdata = tsx->last_tx;\n\n    PJ_ASSERT_RETURN(tdata != NULL, PJ_EINVALIDOP);\n\n    PJ_LOG(5,(tsx->obj_name, \"Sending %s in state %s\",\n                             pjsip_tx_data_get_info(tdata),\n\t\t\t     state_str[tsx->state]));\n    pj_log_push_indent();\n\n    PJSIP_EVENT_INIT_TX_MSG(event, tdata);\n\n    /* Dispatch to transaction. */\n    pj_grp_lock_acquire(tsx->grp_lock);\n\n    /* Set transport selector to tdata */\n    pjsip_tx_data_set_transport(tdata, &tsx->tp_sel);\n\n    /* Dispatch to state handler */\n    status = (*tsx->state_handler)(tsx, &event);\n\n    pj_grp_lock_release(tsx->grp_lock);\n\n    /* Only decrement reference counter when it returns success.\n     * (This is the specification from the .PDF design document).\n     */\n    if (status == PJ_SUCCESS) {\n\tpjsip_tx_data_dec_ref(tdata);\n    }\n\n    pj_log_pop_indent();\n\n    return status;\n}\n\n\n/*\n * This function is called by endpoint when incoming message for the \n * transaction is received.\n */\nPJ_DEF(void) pjsip_tsx_recv_msg( pjsip_transaction *tsx, \n\t\t\t\t pjsip_rx_data *rdata)\n{\n    pjsip_event event;\n\n    PJ_LOG(5,(tsx->obj_name, \"Incoming %s in state %s\", \n\t      pjsip_rx_data_get_info(rdata), state_str[tsx->state]));\n    pj_log_push_indent();\n\n    /* Put the transaction in the rdata's mod_data. */\n    rdata->endpt_info.mod_data[mod_tsx_layer.mod.id] = tsx;\n\n    /* Init event. */\n    PJSIP_EVENT_INIT_RX_MSG(event, rdata);\n\n    /* Dispatch to transaction. */\n    pj_grp_lock_acquire(tsx->grp_lock);\n    (*tsx->state_handler)(tsx, &event);\n    pj_grp_lock_release(tsx->grp_lock);\n\n    pj_log_pop_indent();\n}\n\n\n/* Callback called by send message framework */\nstatic void send_msg_callback( pjsip_send_state *send_state,\n\t\t\t       pj_ssize_t sent, pj_bool_t *cont )\n{\n    pjsip_transaction *tsx = (pjsip_transaction*) send_state->token;\n    pjsip_tx_data *tdata = send_state->tdata;\n\n    /* Check if transaction has cancelled itself from this transmit\n     * notification (https://trac.pjsip.org/repos/ticket/1033).\n     * Also check if the transaction layer itself may have been shutdown\n     * (https://trac.pjsip.org/repos/ticket/1535)\n     */\n    if (mod_tsx_layer.mod.id < 0 ||\n\ttdata->mod_data[mod_tsx_layer.mod.id] == NULL)\n    {\n\t*cont = PJ_FALSE;\n\n\t/* Decrease pending send counter */\n\tpj_grp_lock_dec_ref(tsx->grp_lock);\n\treturn;\n    }\n\n    pj_grp_lock_acquire(tsx->grp_lock);\n\n    /* Decrease pending send counter */\n    pj_grp_lock_dec_ref(tsx->grp_lock);\n\n    /* Reset */\n    tdata->mod_data[mod_tsx_layer.mod.id] = NULL;\n    tsx->pending_tx = NULL;\n\n    if (sent > 0) {\n\t/* Successfully sent! */\n\tpj_assert(send_state->cur_transport != NULL);\n\n\tif (tsx->transport != send_state->cur_transport) {\n\t    /* Update transport. */\n\t    tsx_update_transport(tsx, send_state->cur_transport);\n\n\t    /* Update remote address. */\n\t    tsx->addr_len = tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr_len;\n\t    pj_memcpy(&tsx->addr, \n\t\t      &tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr,\n\t\t      tsx->addr_len);\n\n\t    /* Update is_reliable flag. */\n\t    tsx->is_reliable = PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport);\n\t}\n\n\t/* Clear pending transport flag. */\n\ttsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT);\n\n\t/* Mark that we have resolved the addresses. */\n\ttsx->transport_flag |= TSX_HAS_RESOLVED_SERVER;\n\n\t/* Pending destroy? */\n\tif (tsx->transport_flag & TSX_HAS_PENDING_DESTROY) {\n\t    tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED, \n\t\t\t   PJSIP_EVENT_UNKNOWN, NULL, 0 );\n\t    pj_grp_lock_release(tsx->grp_lock);\n\t    return;\n\t}\n\n\t/* Need to transmit a message? */\n\tif (tsx->transport_flag & TSX_HAS_PENDING_SEND) {\n\t    tsx->transport_flag &= ~(TSX_HAS_PENDING_SEND);\n\t    tsx_send_msg(tsx, tsx->last_tx);\n\t}\n\n\t/* Need to reschedule retransmission?\n\t * Note that when sending a pending message above, tsx_send_msg()\n\t * may set the flag TSX_HAS_PENDING_TRANSPORT.\n\t * Please refer to ticket #1875.\n\t */\n\tif (tsx->transport_flag & TSX_HAS_PENDING_RESCHED &&\n\t    !(tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT))\n\t{\n\t    tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED);\n\n\t    /* Only update when transport turns out to be unreliable. */\n\t    if (!tsx->is_reliable) {\n\t\ttsx_resched_retransmission(tsx);\n\t    }\n\t}\n\n    } else {\n\t/* Failed to send! */\n\tpj_assert(sent != 0);\n\n\t/* If transaction is using the same transport as the failed one, \n\t * release the transport.\n\t */\n\tif (send_state->cur_transport==tsx->transport)\n\t    tsx_update_transport(tsx, NULL);\n\n\t/* Also stop processing if transaction has been flagged with\n\t * pending destroy (http://trac.pjsip.org/repos/ticket/906)\n\t */\n\tif ((!*cont) || (tsx->transport_flag & TSX_HAS_PENDING_DESTROY)) {\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\t    pjsip_status_code sc;\n\t    pj_str_t err;\n\n\t    tsx->transport_err = (pj_status_t)-sent;\n\n\t    err =pj_strerror((pj_status_t)-sent, errmsg, sizeof(errmsg));\n\n\t    PJ_LOG(3,(tsx->obj_name,\n\t\t      \"Failed to send %s! err=%d (%s)\",\n\t\t      pjsip_tx_data_get_info(send_state->tdata), -sent,\n\t\t      errmsg));\n\n\t    /* Clear pending transport flag. */\n\t    tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT);\n\n\t    /* Mark that we have resolved the addresses. */\n\t    tsx->transport_flag |= TSX_HAS_RESOLVED_SERVER;\n\n\t    /* Server resolution error is now mapped to 502 instead of 503,\n\t     * since with 503 normally client should try again.\n\t     * See http://trac.pjsip.org/repos/ticket/870\n\t     */\n\t    if (-sent==PJ_ERESOLVE || -sent==PJLIB_UTIL_EDNS_NXDOMAIN)\n\t\tsc = PJSIP_SC_BAD_GATEWAY;\n\t    else\n\t\tsc = PJSIP_SC_TSX_TRANSPORT_ERROR;\n\n\t    /* Terminate transaction, if it's not already terminated. */\n\t    tsx_set_status_code(tsx, sc, &err);\n\t    if (tsx->state != PJSIP_TSX_STATE_TERMINATED &&\n\t\ttsx->state != PJSIP_TSX_STATE_DESTROYED)\n\t    {\n\t\ttsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, \n\t\t\t       PJSIP_EVENT_TRANSPORT_ERROR,\n\t\t\t       send_state->tdata, 0);\n\t    } \n\t    /* Don't forget to destroy if we have pending destroy flag\n\t     * (http://trac.pjsip.org/repos/ticket/906)\n\t     */\n\t    else if (tsx->transport_flag & TSX_HAS_PENDING_DESTROY)\n\t    {\n\t\ttsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED, \n\t\t\t       PJSIP_EVENT_TRANSPORT_ERROR,\n\t\t\t       send_state->tdata, 0);\n\t    }\n\n\t} else {\n\t    PJ_PERROR(3,(tsx->obj_name, (pj_status_t)-sent,\n\t\t         \"Temporary failure in sending %s, \"\n\t\t         \"will try next server\",\n\t\t         pjsip_tx_data_get_info(send_state->tdata)));\n\n\t    /* Reset retransmission count */\n\t    tsx->retransmit_count = 0;\n\n\t    /* And reset timeout timer */\n\t    if (tsx->timeout_timer.id) {\n\t\tlock_timer(tsx);\n\t\ttsx_cancel_timer(tsx, &tsx->timeout_timer);\n\t\ttsx_schedule_timer( tsx, &tsx->timeout_timer,\n\t\t\t\t    &timeout_timer_val, TIMEOUT_TIMER);\n\t\tunlock_timer(tsx);\n\t    }\n\n\t    /* Put again pending tdata */\n\t    tdata->mod_data[mod_tsx_layer.mod.id] = tsx;\n\t    tsx->pending_tx = tdata;\n\n\t    /* Increment group lock again for the next sending retry,\n\t     * to prevent us from being destroyed prematurely (ticket #1859).\n\t     */\n\t    pj_grp_lock_add_ref(tsx->grp_lock);\n\t}\n    }\n\n    pj_grp_lock_release(tsx->grp_lock);\n}\n\n\n/* Transport callback. */\nstatic void transport_callback(void *token, pjsip_tx_data *tdata,\n\t\t\t       pj_ssize_t sent)\n{\n    pjsip_transaction *tsx = (pjsip_transaction*) token;\n\n    /* In other circumstances, locking tsx->grp_lock AFTER transport mutex\n     * will introduce deadlock if another thread is currently sending a\n     * SIP message to the transport. But this should be safe as there should\n     * be no way this callback could be called while another thread is\n     * sending a message.\n     */\n    pj_grp_lock_acquire(tsx->grp_lock);\n    tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT);\n    pj_grp_lock_release(tsx->grp_lock);\n\n    if (sent < 0) {\n\tpj_time_val delay = {0, 0};\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\n\tpj_strerror((pj_status_t)-sent, errmsg, sizeof(errmsg));\n\n\tPJ_LOG(2,(tsx->obj_name, \"Transport failed to send %s! Err=%d (%s)\",\n\t\tpjsip_tx_data_get_info(tdata), -sent, errmsg));\n\n\t/* Post the event for later processing, to avoid deadlock.\n\t * See https://trac.pjsip.org/repos/ticket/1646\n\t */\n\tlock_timer(tsx);\n\ttsx->transport_err = (pj_status_t)-sent;\n\ttsx_cancel_timer(tsx, &tsx->timeout_timer);\n\ttsx_schedule_timer(tsx, &tsx->timeout_timer, &delay,\n\t                   TRANSPORT_ERR_TIMER);\n\tunlock_timer(tsx);\n   }\n\n    /* Decrease pending send counter */\n    pj_grp_lock_dec_ref(tsx->grp_lock);\n}\n\n\n/*\n * Callback when transport state changes.\n */\nstatic void tsx_tp_state_callback( pjsip_transport *tp,\n\t\t\t\t   pjsip_transport_state state,\n\t\t\t\t   const pjsip_transport_state_info *info)\n{\n    PJ_UNUSED_ARG(tp);\n\n    if (state == PJSIP_TP_STATE_DISCONNECTED) {\n\tpjsip_transaction *tsx;\n\tpj_time_val delay = {0, 0};\n\n\tpj_assert(tp && info && info->user_data);\n\n\ttsx = (pjsip_transaction*)info->user_data;\n\n\t/* Post the event for later processing, to avoid deadlock.\n\t * See https://trac.pjsip.org/repos/ticket/1646\n\t */\n\tlock_timer(tsx);\n\ttsx->transport_err = info->status;\n\ttsx_cancel_timer(tsx, &tsx->timeout_timer);\n\ttsx_schedule_timer(tsx, &tsx->timeout_timer, &delay,\n\t                   TRANSPORT_ERR_TIMER);\n\tunlock_timer(tsx);\n    }\n}\n\n\n/*\n * Send message to the transport.\n */\nstatic pj_status_t tsx_send_msg( pjsip_transaction *tsx, \n                                 pjsip_tx_data *tdata)\n{\n    pj_status_t status = PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(tsx && tdata, PJ_EINVAL);\n\n    /* Send later if transport is still pending. */\n    if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {\n\ttsx->transport_flag |= TSX_HAS_PENDING_SEND;\n\treturn PJ_SUCCESS;\n    }\n\n    /* Skip send if previous tdata transmission is pending (see #1665). */\n    if (tdata->is_pending) {\n\tPJ_LOG(2,(THIS_FILE, \"Unable to send %s: message is pending\", \n\t\t\t     pjsip_tx_data_get_info(tdata)));\n\treturn PJ_SUCCESS;\n    }\n\n    /* If we have the transport, send the message using that transport.\n     * Otherwise perform full transport resolution.\n     */\n    if (tsx->transport) {\n\t/* Increment group lock while waiting for send operation to complete,\n\t * to prevent us from being destroyed prematurely. See\n\t * https://trac.pjsip.org/repos/ticket/1646\n\t */\n\tpj_grp_lock_add_ref(tsx->grp_lock);\n\ttsx->transport_flag |= TSX_HAS_PENDING_TRANSPORT;\n\n\tstatus = pjsip_transport_send( tsx->transport, tdata, &tsx->addr,\n\t\t\t\t       tsx->addr_len, tsx, \n\t\t\t\t       &transport_callback);\n\tif (status == PJ_EPENDING)\n\t    status = PJ_SUCCESS;\n\telse {\n\t    /* Operation completes immediately */\n\t    tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT);\n\t    pj_grp_lock_dec_ref(tsx->grp_lock);\n\t}\n\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(2,(tsx->obj_name, status,\n\t\t         \"Error sending %s\",\n\t\t         pjsip_tx_data_get_info(tdata)));\n\n\t    /* On error, release transport to force using full transport\n\t     * resolution procedure.\n\t     */\n\t    tsx_update_transport(tsx, NULL);\n\n\t    tsx->addr_len = 0;\n\t    tsx->res_addr.transport = NULL;\n\t    tsx->res_addr.addr_len = 0;\n\t} else {\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    /* We are here because we don't have transport, or we failed to send\n     * the message using existing transport. If we haven't resolved the\n     * server before, then begin the long process of resolving the server\n     * and send the message with possibly new server.\n     */\n    pj_assert(status != PJ_SUCCESS || tsx->transport == NULL);\n\n    /* If we have resolved the server, we treat the error as permanent error.\n     * Terminate transaction with transport error failure.\n     */\n    if (tsx->transport_flag & TSX_HAS_RESOLVED_SERVER) {\n\t\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\tpj_str_t err;\n\n\tif (status == PJ_SUCCESS) {\n\t    pj_assert(!\"Unexpected status!\");\n\t    status = PJ_EUNKNOWN;\n\t}\n\n\t/* We have resolved the server!.\n\t * Treat this as permanent transport error.\n\t */\n\terr = pj_strerror(status, errmsg, sizeof(errmsg));\n\n\tPJ_LOG(2,(tsx->obj_name, \n\t\t  \"Transport error, terminating transaction. \"\n\t\t  \"Err=%d (%s)\",\n\t\t  status, errmsg));\n\n\ttsx_set_status_code(tsx, PJSIP_SC_TSX_TRANSPORT_ERROR, &err);\n\ttsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, \n\t\t       PJSIP_EVENT_TRANSPORT_ERROR, NULL, 0 );\n\n\treturn status;\n    }\n\n    /* Must add reference counter because the send request functions\n     * decrement the reference counter.\n     */\n    pjsip_tx_data_add_ref(tdata);\n\n    /* Also attach ourselves to the transmit data so that we'll be able\n     * to unregister ourselves from the send notification of this\n     * transmit data.\n     */\n    tdata->mod_data[mod_tsx_layer.mod.id] = tsx;\n    tsx->pending_tx = tdata;\n\n    /* Increment group lock while waiting for send operation to complete,\n     * to prevent us from being destroyed prematurely (ticket #1859).\n     */\n    pj_grp_lock_add_ref(tsx->grp_lock);\n\n    /* Begin resolving destination etc to send the message. */\n    if (tdata->msg->type == PJSIP_REQUEST_MSG) {\n\n\ttsx->transport_flag |= TSX_HAS_PENDING_TRANSPORT;\n\tstatus = pjsip_endpt_send_request_stateless(tsx->endpt, tdata, tsx,\n\t\t\t\t\t\t    &send_msg_callback);\n\tif (status == PJ_EPENDING)\n\t    status = PJ_SUCCESS;\n\tif (status != PJ_SUCCESS) {\n\t    pj_grp_lock_dec_ref(tsx->grp_lock);\n\t    pjsip_tx_data_dec_ref(tdata);\n\t    tdata->mod_data[mod_tsx_layer.mod.id] = NULL;\n\t    tsx->pending_tx = NULL;\n\t}\n\t\n\t/* Check if transaction is terminated. */\n\tif (status==PJ_SUCCESS && tsx->state == PJSIP_TSX_STATE_TERMINATED)\n\t    status = tsx->transport_err;\n\n    } else {\n\n\ttsx->transport_flag |= TSX_HAS_PENDING_TRANSPORT;\n\tstatus = pjsip_endpt_send_response( tsx->endpt, &tsx->res_addr, \n\t\t\t\t\t    tdata, tsx, \n\t\t\t\t\t    &send_msg_callback);\n\tif (status == PJ_EPENDING)\n\t    status = PJ_SUCCESS;\n\tif (status != PJ_SUCCESS) {\n\t    pjsip_tx_data_dec_ref(tdata);\n\t    tdata->mod_data[mod_tsx_layer.mod.id] = NULL;\n\t    tsx->pending_tx = NULL;\n\t}\n\n\t/* Check if transaction is terminated. */\n\tif (status==PJ_SUCCESS && tsx->state == PJSIP_TSX_STATE_TERMINATED)\n\t    status = tsx->transport_err;\n\n    }\n\n\n    return status;\n}\n\n\n/*\n * Manually retransmit the last messagewithout updating the transaction state.\n */\nPJ_DEF(pj_status_t) pjsip_tsx_retransmit_no_state(pjsip_transaction *tsx,\n\t\t\t\t\t\t  pjsip_tx_data *tdata)\n{\n    pj_status_t status;\n\n    pj_grp_lock_acquire(tsx->grp_lock);\n    if (tdata == NULL) {\n\ttdata = tsx->last_tx;\n\tpjsip_tx_data_add_ref(tdata);\n    }\n    status = tsx_send_msg(tsx, tdata);\n    pj_grp_lock_release(tsx->grp_lock);\n\n    /* Only decrement reference counter when it returns success.\n     * (This is the specification from the .PDF design document).\n     */\n    if (status == PJ_SUCCESS) {\n\tpjsip_tx_data_dec_ref(tdata);\n    }\n\n    return status;\n}\n\n\n/*\n * Retransmit last message sent.\n */\nstatic void tsx_resched_retransmission( pjsip_transaction *tsx )\n{\n    pj_uint32_t msec_time;\n\n    pj_assert((tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) == 0);\n\n    if (tsx->role==PJSIP_ROLE_UAC && tsx->status_code >= 100)\n\tmsec_time = pjsip_cfg()->tsx.t2;\n    else\n\tmsec_time = (1 << (tsx->retransmit_count)) * pjsip_cfg()->tsx.t1;\n\n    if (tsx->role == PJSIP_ROLE_UAC) {\n\tpj_assert(tsx->status_code < 200);\n\t/* Retransmission for non-INVITE transaction caps-off at T2 */\n\tif (msec_time > pjsip_cfg()->tsx.t2 && \n\t    tsx->method.id != PJSIP_INVITE_METHOD)\n\t{\n\t    msec_time = pjsip_cfg()->tsx.t2;\n\t}\n    } else {\n\t/* For UAS, this can be retransmission of 2xx response for INVITE\n\t * or non-100 1xx response.\n\t */\n\tif (tsx->status_code < 200) {\n\t    /* non-100 1xx retransmission is at 60 seconds */\n\t    msec_time = PJSIP_TSX_1XX_RETRANS_DELAY * 1000;\n\t} else {\n\t    /* Retransmission of INVITE final response also caps-off at T2 */\n\t    pj_assert(tsx->status_code >= 200);\n\t    if (msec_time > pjsip_cfg()->tsx.t2)\n\t\tmsec_time = pjsip_cfg()->tsx.t2;\n\t}\n    }\n\n    if (msec_time != 0) {\n\tpj_time_val timeout;\n\n\ttimeout.sec = msec_time / 1000;\n\ttimeout.msec = msec_time % 1000;\n\ttsx_schedule_timer( tsx, &tsx->retransmit_timer, &timeout,\n\t                    RETRANSMIT_TIMER);\n    }\n}\n\n/*\n * Retransmit last message sent.\n */\nstatic pj_status_t tsx_retransmit( pjsip_transaction *tsx, int resched)\n{\n    pj_status_t status;\n\n    if (resched && pj_timer_entry_running(&tsx->retransmit_timer)) {\n\t/* We've been asked to reschedule but the timer is already rerunning.\n\t * This can only happen in a race condition where, between removing\n\t * this retransmit timer from the heap and actually scheduling it,\n\t * another thread has got in and rescheduled the timer itself.  In\n\t * this scenario, the transmission has already happened and so we\n\t * should just quit out immediately, without either resending the\n\t * message or restarting the timer.\n\t */\n\treturn PJ_SUCCESS;\n    }\n\n    PJ_ASSERT_RETURN(tsx->last_tx!=NULL, PJ_EBUG);\n\n    PJ_LOG(5,(tsx->obj_name, \"Retransmiting %s, count=%d, restart?=%d\", \n\t      pjsip_tx_data_get_info(tsx->last_tx), \n\t      tsx->retransmit_count, resched));\n\n    ++tsx->retransmit_count;\n\n    /* Restart timer T1 first before sending the message to ensure that\n     * retransmission timer is not engaged when loop transport is used.\n     */\n    if (resched) {\n\tpj_assert(tsx->state != PJSIP_TSX_STATE_CONFIRMED);\n\tif (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {\n\t    tsx->transport_flag |= TSX_HAS_PENDING_RESCHED;\n\t} else {\n\t    tsx_resched_retransmission(tsx);\n\t}\n    }\n\n    status = tsx_send_msg( tsx, tsx->last_tx);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic void tsx_update_transport( pjsip_transaction *tsx, \n\t\t\t\t  pjsip_transport *tp)\n{\n    pj_assert(tsx);\n\n    if (tsx->transport) {\n\tpjsip_transport_remove_state_listener(tsx->transport, \n\t\t\t\t\t       tsx->tp_st_key, tsx);\n\tpjsip_transport_dec_ref( tsx->transport );\n\ttsx->transport = NULL;\n    }\n\n    if (tp) {\n\ttsx->transport = tp;\n\tpjsip_transport_add_ref(tp);\n\tpjsip_transport_add_state_listener(tp, &tsx_tp_state_callback, tsx,\n\t\t\t\t\t    &tsx->tp_st_key);\n        if (tp->is_shutdown) {\n\t    pjsip_transport_state_info info;\n\n\t    pj_bzero(&info, sizeof(info));\n            info.user_data = tsx;\n            info.status = PJSIP_SC_TSX_TRANSPORT_ERROR;\n            tsx_tp_state_callback(tp, PJSIP_TP_STATE_DISCONNECTED, &info);\n        }\n    }\n}\n\n/*\n * Handler for events in state Null.\n */\nstatic pj_status_t tsx_on_state_null( pjsip_transaction *tsx, \n                                      pjsip_event *event )\n{\n    pj_status_t status;\n\n    pj_assert(tsx->state == PJSIP_TSX_STATE_NULL);\n\n    if (tsx->role == PJSIP_ROLE_UAS) {\n\n\t/* Set state to Trying. */\n\tpj_assert(event->type == PJSIP_EVENT_RX_MSG &&\n\t\t  event->body.rx_msg.rdata->msg_info.msg->type == \n\t\t    PJSIP_REQUEST_MSG);\n\ttsx_set_state( tsx, PJSIP_TSX_STATE_TRYING, PJSIP_EVENT_RX_MSG,\n\t\t       event->body.rx_msg.rdata, 0);\n\n    } else {\n\tpjsip_tx_data *tdata;\n\n\t/* Must be transmit event. \n\t * You may got this assertion when using loop transport with delay \n\t * set to zero. That would cause on_rx_response() callback to be \n\t * called before tsx_send_msg() has completed.\n\t */\n\tPJ_ASSERT_RETURN(event->type == PJSIP_EVENT_TX_MSG, PJ_EBUG);\n\n\t/* Get the txdata */\n\ttdata = event->body.tx_msg.tdata;\n\n\t/* Save the message for retransmission. */\n\tif (tsx->last_tx && tsx->last_tx != tdata) {\n\t    pjsip_tx_data_dec_ref(tsx->last_tx);\n\t    tsx->last_tx = NULL;\n\t}\n\tif (tsx->last_tx != tdata) {\n\t    tsx->last_tx = tdata;\n\t    pjsip_tx_data_add_ref(tdata);\n\t}\n\n\t/* Send the message. */\n        status = tsx_send_msg( tsx, tdata);\n\tif (status != PJ_SUCCESS) {\n\t    return status;\n\t}\n\n\t/* Start Timer B (or called timer F for non-INVITE) for transaction \n\t * timeout.\n\t */\n\tlock_timer(tsx);\n\ttsx_cancel_timer( tsx, &tsx->timeout_timer );\n\ttsx_schedule_timer( tsx, &tsx->timeout_timer, &timeout_timer_val,\n\t                    TIMEOUT_TIMER);\n\tunlock_timer(tsx);\n\n\t/* Start Timer A (or timer E) for retransmission only if unreliable \n\t * transport is being used.\n\t */\n\tif (!tsx->is_reliable)  {\n\t    tsx->retransmit_count = 0;\n\t    if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {\n\t\ttsx->transport_flag |= TSX_HAS_PENDING_RESCHED;\n\t    } else {\n\t\ttsx_schedule_timer(tsx, &tsx->retransmit_timer,\n\t\t                   &t1_timer_val, RETRANSMIT_TIMER);\n\t    }\n\t}\n\n\t/* Move state. */\n\ttsx_set_state( tsx, PJSIP_TSX_STATE_CALLING, \n                       PJSIP_EVENT_TX_MSG, tdata, 0);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * State Calling is for UAC after it sends request but before any responses\n * is received.\n */\nstatic pj_status_t tsx_on_state_calling( pjsip_transaction *tsx, \n\t\t\t\t         pjsip_event *event )\n{\n    pj_assert(tsx->state == PJSIP_TSX_STATE_CALLING);\n    pj_assert(tsx->role == PJSIP_ROLE_UAC);\n\n    if (event->type == PJSIP_EVENT_TIMER && \n\tevent->body.timer.entry == &tsx->retransmit_timer) \n    {\n        pj_status_t status;\n\n\t/* Retransmit the request. */\n        status = tsx_retransmit( tsx, 1 );\n\tif (status != PJ_SUCCESS) {\n\t    return status;\n\t}\n\n    } else if (event->type == PJSIP_EVENT_TIMER && \n\t       event->body.timer.entry == &tsx->timeout_timer) \n    {\n\t/* Cancel retransmission timer. */\n\ttsx_cancel_timer(tsx, &tsx->retransmit_timer);\n\n\ttsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED);\n\n\t/* Set status code */\n\ttsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);\n\n\t/* Inform TU. */\n\ttsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,\n                       PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0);\n\n\t/* Transaction is destroyed */\n\t//return PJSIP_ETSXDESTROYED;\n\n    } else if (event->type == PJSIP_EVENT_RX_MSG) {\n\tpjsip_msg *msg;\n\tint code;\n\n\t/* Get message instance */\n\tmsg = event->body.rx_msg.rdata->msg_info.msg;\n\n\t/* Better be a response message. */\n\tif (msg->type != PJSIP_RESPONSE_MSG)\n\t    return PJSIP_ENOTRESPONSEMSG;\n\n\tcode = msg->line.status.code;\n\n\t/* If the response is final, cancel both retransmission and timeout\n\t * timer.\n\t */\n\tif (code >= 200) {\n\t    tsx_cancel_timer(tsx, &tsx->retransmit_timer);\n\n\t    if (tsx->timeout_timer.id != 0) {\n\t\tlock_timer(tsx);\n\t\ttsx_cancel_timer(tsx, &tsx->timeout_timer);\n\t\tunlock_timer(tsx);\n\t    }\n\n\t} else {\n\t    /* Cancel retransmit timer (for non-INVITE transaction, the\n\t     * retransmit timer will be rescheduled at T2.\n\t     */\n\t    tsx_cancel_timer(tsx, &tsx->retransmit_timer);\n\n\t    /* For provisional response, only cancel retransmit when this\n\t     * is an INVITE transaction. For non-INVITE, section 17.1.2.1\n\t     * of RFC 3261 says that:\n\t     *\t- retransmit timer is set to T2\n\t     *\t- timeout timer F is not deleted.\n\t     */\n\t    if (tsx->method.id == PJSIP_INVITE_METHOD) {\n\n\t\t/* Cancel timeout timer */\n\t\tlock_timer(tsx);\n\t\ttsx_cancel_timer(tsx, &tsx->timeout_timer);\n\t\tunlock_timer(tsx);\n\n\t    } else {\n\t\tif (!tsx->is_reliable) {\n\t\t    tsx_schedule_timer(tsx, &tsx->retransmit_timer,\n\t\t                       &t2_timer_val, RETRANSMIT_TIMER);\n\t\t}\n\t    }\n\t}\n\t \n\ttsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED);\n\n\n\t/* Discard retransmission message if it is not INVITE.\n\t * The INVITE tdata is needed in case we have to generate ACK for\n\t * the final response.\n\t */\n\t/* Keep last_tx for authorization. */\n\t//blp: always keep last_tx until transaction is destroyed\n\t//code = msg->line.status.code;\n\t//if (tsx->method.id != PJSIP_INVITE_METHOD && code!=401 && code!=407) {\n\t//    pjsip_tx_data_dec_ref(tsx->last_tx);\n\t//    tsx->last_tx = NULL;\n\t//}\n\n\t/* Processing is similar to state Proceeding. */\n\ttsx_on_state_proceeding_uac( tsx, event);\n\n    } else {\n\tpj_assert(!\"Unexpected event\");\n        return PJ_EBUG;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * State Trying is for UAS after it received request but before any responses\n * is sent.\n * Note: this is different than RFC3261, which can use Trying state for\n *\t non-INVITE client transaction (bug in RFC?).\n */\nstatic pj_status_t tsx_on_state_trying( pjsip_transaction *tsx, \n                                        pjsip_event *event)\n{\n    pj_status_t status;\n\n    pj_assert(tsx->state == PJSIP_TSX_STATE_TRYING);\n\n    /* This state is only for UAS */\n    pj_assert(tsx->role == PJSIP_ROLE_UAS);\n\n    /* Better be transmission of response message.\n     * If we've got request retransmission, this means that the TU hasn't\n     * transmitted any responses within 500 ms, which is not allowed. If\n     * this happens, just ignore the event (we couldn't retransmit last\n     * response because we haven't sent any!).\n     */\n    if (event->type != PJSIP_EVENT_TX_MSG) {\n\treturn PJ_SUCCESS;\n    }\n\n    /* The rest of the processing of the event is exactly the same as in\n     * \"Proceeding\" state.\n     */\n    status = tsx_on_state_proceeding_uas( tsx, event);\n\n    /* Inform the TU of the state transision if state is still State_Trying */\n    if (status==PJ_SUCCESS && tsx->state == PJSIP_TSX_STATE_TRYING) {\n\n\ttsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, \n                       PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata, 0);\n\n    }\n\n    return status;\n}\n\n\n/*\n * Handler for events in Proceeding for UAS\n * This state happens after the TU sends provisional response.\n */\nstatic pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx,\n                                                pjsip_event *event)\n{\n    pj_assert(tsx->state == PJSIP_TSX_STATE_PROCEEDING || \n\t      tsx->state == PJSIP_TSX_STATE_TRYING);\n\n    /* This state is only for UAS. */\n    pj_assert(tsx->role == PJSIP_ROLE_UAS);\n\n    /* Receive request retransmission. */\n    if (event->type == PJSIP_EVENT_RX_MSG) {\n\n        pj_status_t status;\n\n\t/* Must have last response sent. */\n\tPJ_ASSERT_RETURN(tsx->last_tx != NULL, PJ_EBUG);\n\n\t/* Send last response */\n\tif (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {\n\t    tsx->transport_flag |= TSX_HAS_PENDING_SEND;\n\t} else {\n\t    status = tsx_send_msg(tsx, tsx->last_tx);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\t}\n\t\n    } else if (event->type == PJSIP_EVENT_TX_MSG ) {\n\tpjsip_tx_data *tdata = event->body.tx_msg.tdata;\n        pj_status_t status;\n\n\t/* The TU sends response message to the request. Save this message so\n\t * that we can retransmit the last response in case we receive request\n\t * retransmission.\n\t */\n\tpjsip_msg *msg = tdata->msg;\n\n\t/* This can only be a response message. */\n\tPJ_ASSERT_RETURN(msg->type==PJSIP_RESPONSE_MSG, PJSIP_ENOTRESPONSEMSG);\n\n\t/* Update last status */\n\ttsx_set_status_code(tsx, msg->line.status.code, \n\t\t\t    &msg->line.status.reason);\n\n\t/* Discard the saved last response (it will be updated later as\n\t * necessary).\n\t */\n\tif (tsx->last_tx && tsx->last_tx != tdata) {\n\t    pjsip_tx_data_dec_ref( tsx->last_tx );\n\t    tsx->last_tx = NULL;\n\t}\n\n\t/* Send the message. */\n        status = tsx_send_msg(tsx, tdata);\n\tif (status != PJ_SUCCESS) {\n\t    return status;\n\t}\n\n\t// Update To tag header for RFC2543 transaction.\n\t// TODO:\n\n\t/* Update transaction state */\n\tif (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 100)) {\n\n\t    if (tsx->last_tx != tdata) {\n\t\ttsx->last_tx = tdata;\n\t\tpjsip_tx_data_add_ref( tdata );\n\t    }\n\n\t    tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, \n                           PJSIP_EVENT_TX_MSG, tdata, 0 );\n\n\t    /* Retransmit provisional response every 1 minute if this is\n\t     * an INVITE provisional response greater than 100.\n\t     */\n\t    if (PJSIP_TSX_1XX_RETRANS_DELAY > 0 && \n\t\ttsx->method.id==PJSIP_INVITE_METHOD && tsx->status_code>100)\n\t    {\n\n\t\t/* Stop 1xx retransmission timer, if any */\n\t\ttsx_cancel_timer(tsx, &tsx->retransmit_timer);\n\n\t\t/* Schedule retransmission */\n\t\ttsx->retransmit_count = 0;\n\t\tif (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {\n\t\t    tsx->transport_flag |= TSX_HAS_PENDING_RESCHED;\n\t\t} else {\n\t\t    pj_time_val delay = {PJSIP_TSX_1XX_RETRANS_DELAY, 0};\n\t\t    tsx_schedule_timer( tsx, &tsx->retransmit_timer, &delay,\n\t\t                        RETRANSMIT_TIMER);\n\t\t}\n\t    }\n\n\t} else if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 200)) {\n\n\t    /* Stop 1xx retransmission timer, if any */\n\t    tsx_cancel_timer(tsx, &tsx->retransmit_timer);\n\n\t    if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->handle_200resp==0) {\n\n\t\t/* 2xx class message is not saved, because retransmission \n                 * is handled by TU.\n\t\t */\n\t\ttsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, \n                               PJSIP_EVENT_TX_MSG, tdata, 0 );\n\n\t\t/* Transaction is destroyed. */\n\t\t//return PJSIP_ETSXDESTROYED;\n\n\t    } else {\n\t\tpj_time_val timeout;\n\n\t\tif (tsx->method.id == PJSIP_INVITE_METHOD) {\n\t\t    tsx->retransmit_count = 0;\n\t\t    if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {\n\t\t\ttsx->transport_flag |= TSX_HAS_PENDING_RESCHED;\n\t\t    } else {\n\t\t\ttsx_schedule_timer( tsx, &tsx->retransmit_timer,\n\t\t\t\t\t    &t1_timer_val, RETRANSMIT_TIMER);\n\t\t    }\n\t\t}\n\n\t\t/* Save last response sent for retransmission when request \n\t\t * retransmission is received.\n\t\t */\n\t\tif (tsx->last_tx != tdata) {\n\t\t    tsx->last_tx = tdata;\n\t\t    pjsip_tx_data_add_ref(tdata);\n\t\t}\n\n\t\t/* Setup timeout timer: */\n\t\t\n\t\tif (tsx->method.id == PJSIP_INVITE_METHOD) {\n\t\t    \n\t\t    /* Start Timer H at 64*T1 for INVITE server transaction,\n\t\t     * regardless of transport.\n\t\t     */\n\t\t    timeout = timeout_timer_val;\n\t\t    \n\t\t} else if (!tsx->is_reliable) {\n\t\t    \n\t\t    /* For non-INVITE, start timer J at 64*T1 for unreliable\n\t\t     * transport.\n\t\t     */\n\t\t    timeout = timeout_timer_val;\n\t\t    \n\t\t} else {\n\t\t    \n\t\t    /* Transaction terminates immediately for non-INVITE when\n\t\t     * reliable transport is used.\n\t\t     */\n\t\t    timeout.sec = timeout.msec = 0;\n\t\t}\n\n\t\tlock_timer(tsx);\n\t\ttsx_cancel_timer(tsx, &tsx->timeout_timer);\n\t\ttsx_schedule_timer( tsx, &tsx->timeout_timer,\n                                    &timeout, TIMEOUT_TIMER);\n\t\tunlock_timer(tsx);\n\n\t\t/* Set state to \"Completed\" */\n\t\ttsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, \n                               PJSIP_EVENT_TX_MSG, tdata, 0 );\n\t    }\n\n\t} else if (tsx->status_code >= 300) {\n\n\t    /* Stop 1xx retransmission timer, if any */\n\t    tsx_cancel_timer(tsx, &tsx->retransmit_timer);\n\n\t    /* 3xx-6xx class message causes transaction to move to \n             * \"Completed\" state. \n             */\n\t    if (tsx->last_tx != tdata) {\n\t\ttsx->last_tx = tdata;\n\t\tpjsip_tx_data_add_ref( tdata );\n\t    }\n\n\t    /* For INVITE, start timer H for transaction termination \n\t     * regardless whether transport is reliable or not.\n\t     * For non-INVITE, start timer J with the value of 64*T1 for\n\t     * non-reliable transports, and zero for reliable transports.\n\t     */\n\t    lock_timer(tsx);\n\t    tsx_cancel_timer(tsx, &tsx->timeout_timer);\n\t    if (tsx->method.id == PJSIP_INVITE_METHOD) {\n\t\t/* Start timer H for INVITE */\n\t\ttsx_schedule_timer(tsx, &tsx->timeout_timer,\n\t\t\t\t   &timeout_timer_val, TIMEOUT_TIMER);\n\t    } else if (!tsx->is_reliable) {\n\t\t/* Start timer J on 64*T1 seconds for non-INVITE */\n\t\ttsx_schedule_timer(tsx, &tsx->timeout_timer,\n\t\t\t\t   &timeout_timer_val, TIMEOUT_TIMER);\n\t    } else {\n\t\t/* Start timer J on zero seconds for non-INVITE */\n\t\tpj_time_val zero_time = { 0, 0 };\n\t\ttsx_schedule_timer(tsx, &tsx->timeout_timer,\n\t\t\t\t   &zero_time, TIMEOUT_TIMER);\n\t    }\n\t    unlock_timer(tsx);\n\n\t    /* For INVITE, if unreliable transport is used, retransmission \n\t     * timer G will be scheduled (retransmission).\n\t     */\n\t    if (!tsx->is_reliable) {\n\t\tpjsip_cseq_hdr *cseq = (pjsip_cseq_hdr*)\n\t\t\t\t       pjsip_msg_find_hdr( msg, PJSIP_H_CSEQ,\n                                                           NULL);\n\t\tif (cseq->method.id == PJSIP_INVITE_METHOD) {\n\t\t    tsx->retransmit_count = 0;\n\t\t    if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {\n\t\t\ttsx->transport_flag |= TSX_HAS_PENDING_RESCHED;\n\t\t    } else {\n\t\t\ttsx_schedule_timer(tsx, &tsx->retransmit_timer,\n\t\t\t\t\t   &t1_timer_val, RETRANSMIT_TIMER);\n\t\t    }\n\t\t}\n\t    }\n\n\t    /* Inform TU */\n\t    tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, \n                           PJSIP_EVENT_TX_MSG, tdata, 0 );\n\n\t} else {\n\t    pj_assert(0);\n\t}\n\n\n    } else if (event->type == PJSIP_EVENT_TIMER && \n\t       event->body.timer.entry == &tsx->retransmit_timer) {\n\n\t/* Retransmission timer elapsed. */\n        pj_status_t status;\n\n\t/* Must not be triggered while transport is pending. */\n\tpj_assert((tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) == 0);\n\n\t/* Must have last response to retransmit. */\n\tpj_assert(tsx->last_tx != NULL);\n\n\t/* Retransmit the last response. */\n        status = tsx_retransmit( tsx, 1 );\n\tif (status != PJ_SUCCESS) {\n\t    return status;\n\t}\n\n    } else if (event->type == PJSIP_EVENT_TIMER && \n\t       event->body.timer.entry == &tsx->timeout_timer) {\n\n\t/* Timeout timer. should not happen? */\n\tpj_assert(!\"Should not happen(?)\");\n\n\ttsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);\n\n\ttsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,\n                       PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0);\n\n\treturn PJ_EBUG;\n\n    } else {\n\tpj_assert(!\"Unexpected event\");\n        return PJ_EBUG;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Handler for events in Proceeding for UAC\n * This state happens after provisional response(s) has been received from\n * UAS.\n */\nstatic pj_status_t tsx_on_state_proceeding_uac(pjsip_transaction *tsx, \n                                               pjsip_event *event)\n{\n\n    pj_assert(tsx->state == PJSIP_TSX_STATE_PROCEEDING || \n\t      tsx->state == PJSIP_TSX_STATE_CALLING);\n\n    if (event->type != PJSIP_EVENT_TIMER) {\n\tpjsip_msg *msg;\n\n\t/* Must be incoming response, because we should not retransmit\n\t * request once response has been received.\n\t */\n\tpj_assert(event->type == PJSIP_EVENT_RX_MSG);\n\tif (event->type != PJSIP_EVENT_RX_MSG) {\n\t    return PJ_EINVALIDOP;\n\t}\n\n\tmsg = event->body.rx_msg.rdata->msg_info.msg;\n\n\t/* Must be a response message. */\n\tif (msg->type != PJSIP_RESPONSE_MSG) {\n\t    pj_assert(!\"Expecting response message!\");\n\t    return PJSIP_ENOTRESPONSEMSG;\n\t}\n\n\ttsx_set_status_code(tsx, msg->line.status.code, \n\t\t\t    &msg->line.status.reason);\n\n    } else {\n\tif (event->body.timer.entry == &tsx->retransmit_timer) {\n\t    /* Retransmit message. */\n            pj_status_t status;\n\n            status = tsx_retransmit( tsx, 1 );\n\t    \n\t    return status;\n\n\t} else {\n\t    tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);\n\t}\n    }\n\n    if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 100)) {\n\n\t/* Inform the message to TU. */\n\ttsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, \n                       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 );\n\n    } else if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code,200)) {\n\n\t/* Stop timeout timer B/F. */\n\tlock_timer(tsx);\n\ttsx_cancel_timer( tsx, &tsx->timeout_timer );\n\tunlock_timer(tsx);\n\n\t/* For INVITE, the state moves to Terminated state (because ACK is\n\t * handled in TU). For non-INVITE, state moves to Completed.\n\t */\n\tif (tsx->method.id == PJSIP_INVITE_METHOD) {\n\t    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, \n                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 );\n\t    //return PJSIP_ETSXDESTROYED;\n\n\t} else {\n\t    pj_time_val timeout;\n\n\t    /* For unreliable transport, start timer D (for INVITE) or \n\t     * timer K for non-INVITE. */\n\t    if (!tsx->is_reliable) {\n\t\tif (tsx->method.id == PJSIP_INVITE_METHOD) {\n\t\t    timeout = td_timer_val;\n\t\t} else {\n\t\t    timeout = t4_timer_val;\n\t\t}\n\t    } else {\n\t\ttimeout.sec = timeout.msec = 0;\n\t    }\n\t    lock_timer(tsx);\n\t    tsx_schedule_timer( tsx, &tsx->timeout_timer,\n\t\t\t\t&timeout, TIMEOUT_TIMER);\n\t    unlock_timer(tsx);\n\n\t    /* Cancel retransmission timer */\n\t    tsx_cancel_timer(tsx, &tsx->retransmit_timer);\n\n\t    /* Move state to Completed, inform TU. */\n\t    tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, \n                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 );\n\t}\n\n    } else if (event->type == PJSIP_EVENT_TIMER &&\n\t       event->body.timer.entry == &tsx->timeout_timer) {\n\n\t/* Inform TU. */\n\ttsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,\n\t\t       PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0);\n\n\n    } else if (tsx->status_code >= 300 && tsx->status_code <= 699) {\n\n\n#if 0\n\t/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */\n\t/*\n\t * This is the old code; it's broken for authentication.\n\t */\n\tpj_time_val timeout;\n        pj_status_t status;\n\n\t/* Stop timer B. */\n\ttsx_cancel_timer( tsx, &tsx->timeout_timer );\n\n\t/* Generate and send ACK for INVITE. */\n\tif (tsx->method.id == PJSIP_INVITE_METHOD) {\n\t    pjsip_tx_data *ack;\n\n\t    status = pjsip_endpt_create_ack( tsx->endpt, tsx->last_tx, \n\t\t\t\t\t     event->body.rx_msg.rdata,\n\t\t\t\t\t     &ack);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    if (ack != tsx->last_tx) {\n\t\tpjsip_tx_data_dec_ref(tsx->last_tx);\n\t\ttsx->last_tx = ack;\n\t    }\n\n            status = tsx_send_msg( tsx, tsx->last_tx);\n\t    if (status != PJ_SUCCESS) {\n\t\treturn status;\n\t    }\n\t}\n\n\t/* Start Timer D with TD/T4 timer if unreliable transport is used. */\n\tif (!tsx->is_reliable) {\n\t    if (tsx->method.id == PJSIP_INVITE_METHOD) {\n\t\ttimeout = td_timer_val;\n\t    } else {\n\t\ttimeout = t4_timer_val;\n\t    }\n\t} else {\n\t    timeout.sec = timeout.msec = 0;\n\t}\n\ttsx_schedule_timer( tsx, &tsx->timeout_timer, &timeout, TIMEOUT_TIMER);\n\n\t/* Inform TU. \n\t * blp: You might be tempted to move this notification before\n\t *      sending ACK, but I think you shouldn't. Better set-up\n\t *      everything before calling tsx_user's callback to avoid\n\t *      mess up.\n\t */\n\ttsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, \n                       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );\n\n\t/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */\n#endif\n\n\t/* New code, taken from 0.2.9.x branch */\n\tpj_time_val timeout;\n\tpjsip_tx_data *ack_tdata = NULL;\n\n\t/* Cancel retransmission timer */\n\ttsx_cancel_timer(tsx, &tsx->retransmit_timer);\n\n\t/* Stop timer B. */\n\tlock_timer(tsx);\n\ttsx_cancel_timer( tsx, &tsx->timeout_timer );\n\tunlock_timer(tsx);\n\n\t/* Generate and send ACK (for INVITE) */\n\tif (tsx->method.id == PJSIP_INVITE_METHOD) {\n\t    pj_status_t status;\n\n\t    status = pjsip_endpt_create_ack( tsx->endpt, tsx->last_tx, \n\t\t\t\t\t     event->body.rx_msg.rdata,\n\t\t\t\t\t     &ack_tdata);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    status = tsx_send_msg( tsx, ack_tdata);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\t}\n\n\t/* Inform TU. */\n\ttsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, \n\t\t       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0);\n\n\t/* Generate and send ACK for INVITE. */\n\tif (tsx->method.id == PJSIP_INVITE_METHOD) {\n\t    if (ack_tdata != tsx->last_tx) {\n\t\tpjsip_tx_data_dec_ref(tsx->last_tx);\n\t\ttsx->last_tx = ack_tdata;\n\n\t\t/* This is a bug.\n\t\t   tsx_send_msg() does NOT decrement tdata's reference counter,\n\t\t   so if we add the reference counter here, tdata will have\n\t\t   reference counter 2, causing it to leak.\n\t\tpjsip_tx_data_add_ref(ack_tdata);\n\t\t*/\n\t    }\n\t}\n\n\t/* Start Timer D with TD/T4 timer if unreliable transport is used. */\n\t/* Note: tsx->transport may be NULL! */\n\tif (!tsx->is_reliable) {\n\t    if (tsx->method.id == PJSIP_INVITE_METHOD) {\n\t\ttimeout = td_timer_val;\n\t    } else {\n\t\ttimeout = t4_timer_val;\n\t    }\n\t} else {\n\t    timeout.sec = timeout.msec = 0;\n\t}\n\tlock_timer(tsx);\n\t/* In the short period above timer may have been inserted\n\t * by set_timeout() (by CANCEL). Cancel it if necessary. See:\n\t *  https://trac.pjsip.org/repos/ticket/1374\n\t */\n\ttsx_cancel_timer( tsx, &tsx->timeout_timer );\n\ttsx_schedule_timer( tsx, &tsx->timeout_timer, &timeout,\n\t                    TIMEOUT_TIMER);\n\tunlock_timer(tsx);\n\n    } else {\n\t// Shouldn't happen because there's no timer for this state.\n\tpj_assert(!\"Unexpected event\");\n        return PJ_EBUG;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Handler for events in Completed state for UAS\n */\nstatic pj_status_t tsx_on_state_completed_uas( pjsip_transaction *tsx, \n                                               pjsip_event *event)\n{\n    pj_assert(tsx->state == PJSIP_TSX_STATE_COMPLETED);\n\n    if (event->type == PJSIP_EVENT_RX_MSG) {\n\tpjsip_msg *msg = event->body.rx_msg.rdata->msg_info.msg;\n\n\t/* This must be a request message retransmission. */\n\tif (msg->type != PJSIP_REQUEST_MSG)\n\t    return PJSIP_ENOTREQUESTMSG;\n\n\t/* On receive request retransmission, retransmit last response. */\n\tif (msg->line.req.method.id != PJSIP_ACK_METHOD) {\n            pj_status_t status;\n\n            status = tsx_retransmit( tsx, 0 );\n\t    if (status != PJ_SUCCESS) {\n\t\treturn status;\n\t    }\n\n\t} else {\n\t    pj_time_val timeout;\n\n\t    /* Process incoming ACK request. */\n\n\t    /* Verify that this is an INVITE transaction */\n\t    if (tsx->method.id != PJSIP_INVITE_METHOD) {\n\t\tPJ_LOG(2, (tsx->obj_name, \n\t\t\t   \"Received illegal ACK for %.*s transaction\",\n\t\t\t   (int)tsx->method.name.slen,\n\t\t\t   tsx->method.name.ptr));\n\t\treturn PJSIP_EINVALIDMETHOD;\n\t    }\n\n\t    /* Cease retransmission. */\n\t    tsx_cancel_timer(tsx, &tsx->retransmit_timer);\n\n\t    tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED);\n\n\t    /* Reschedule timeout timer. */\n\t    lock_timer(tsx);\n\t    tsx_cancel_timer( tsx, &tsx->timeout_timer );\n\n\t    /* Timer I is T4 timer for unreliable transports, and\n\t     * zero seconds for reliable transports.\n\t     */\n\t    if (tsx->is_reliable) {\n\t\ttimeout.sec = 0; \n\t\ttimeout.msec = 0;\n\t    } else {\n\t\ttimeout.sec = t4_timer_val.sec;\n\t\ttimeout.msec = t4_timer_val.msec;\n\t    }\n\t    tsx_schedule_timer( tsx, &tsx->timeout_timer,\n\t\t\t\t&timeout, TIMEOUT_TIMER);\n\t    unlock_timer(tsx);\n\n\t    /* Move state to \"Confirmed\" */\n\t    tsx_set_state( tsx, PJSIP_TSX_STATE_CONFIRMED, \n                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 );\n\t}\t\n\n    } else if (event->type == PJSIP_EVENT_TIMER) {\n\n\tif (event->body.timer.entry == &tsx->retransmit_timer) {\n\t    /* Retransmit message. */\n            pj_status_t status;\n\n            status = tsx_retransmit( tsx, 1 );\n\t    if (status != PJ_SUCCESS) {\n\t\treturn status;\n\t    }\n\n\t} else {\n\t    if (tsx->method.id == PJSIP_INVITE_METHOD) {\n\n\t\t/* For INVITE, this means that ACK was never received.\n\t\t * Set state to Terminated, and inform TU.\n\t\t */\n\n\t\ttsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);\n\n\t\ttsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, \n                               PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0 );\n\n\t\t//return PJSIP_ETSXDESTROYED;\n\n\t    } else {\n\t\t/* Transaction terminated, it can now be deleted. */\n\t\ttsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, \n                               PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0 );\n\t\t//return PJSIP_ETSXDESTROYED;\n\t    }\n\t}\n\n    } else {\n\t/* Ignore request to transmit. */\n\tPJ_ASSERT_RETURN(event->type == PJSIP_EVENT_TX_MSG && \n\t\t\t event->body.tx_msg.tdata == tsx->last_tx, \n\t\t\t PJ_EINVALIDOP);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Handler for events in Completed state for UAC transaction.\n */\nstatic pj_status_t tsx_on_state_completed_uac( pjsip_transaction *tsx,\n                                               pjsip_event *event)\n{\n    pj_assert(tsx->state == PJSIP_TSX_STATE_COMPLETED);\n\n    if (event->type == PJSIP_EVENT_TIMER) {\n\t/* Ignore stray retransmit event\n\t *  https://trac.pjsip.org/repos/ticket/1766\n\t */\n\tif (event->body.timer.entry != &tsx->timeout_timer)\n\t    return PJ_SUCCESS;\n\n\t/* Move to Terminated state. */\n\ttsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,\n                       PJSIP_EVENT_TIMER, event->body.timer.entry, 0 );\n\n\t/* Transaction has been destroyed. */\n\t//return PJSIP_ETSXDESTROYED;\n\n    } else if (event->type == PJSIP_EVENT_RX_MSG) {\n\tif (tsx->method.id == PJSIP_INVITE_METHOD) {\n\t    /* On received of final response retransmission, retransmit the ACK.\n\t     * TU doesn't need to be informed.\n\t     */\n\t    pjsip_msg *msg = event->body.rx_msg.rdata->msg_info.msg;\n\t    pj_assert(msg->type == PJSIP_RESPONSE_MSG);\n\t    if (msg->type==PJSIP_RESPONSE_MSG &&\n\t\tmsg->line.status.code >= 200)\n\t    {\n                pj_status_t status;\n\n                status = tsx_retransmit( tsx, 0 );\n\t\tif (status != PJ_SUCCESS) {\n\t\t    return status;\n\t\t}\n\t    } else {\n\t\t/* Very late retransmission of privisional response. */\n\t\tpj_assert( msg->type == PJSIP_RESPONSE_MSG );\n\t    }\n\t} else {\n\t    /* Just drop the response. */\n\t}\n\n    } else {\n\tpj_assert(!\"Unexpected event\");\n        return PJ_EINVALIDOP;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Handler for events in state Confirmed.\n */\nstatic pj_status_t tsx_on_state_confirmed( pjsip_transaction *tsx,\n                                           pjsip_event *event)\n{\n    pj_assert(tsx->state == PJSIP_TSX_STATE_CONFIRMED);\n\n    /* This state is only for UAS for INVITE. */\n    pj_assert(tsx->role == PJSIP_ROLE_UAS);\n    pj_assert(tsx->method.id == PJSIP_INVITE_METHOD);\n\n    /* Absorb any ACK received. */\n    if (event->type == PJSIP_EVENT_RX_MSG) {\n\n\tpjsip_msg *msg = event->body.rx_msg.rdata->msg_info.msg;\n\n\t/* Only expecting request message. */\n\tif (msg->type != PJSIP_REQUEST_MSG)\n\t    return PJSIP_ENOTREQUESTMSG;\n\n\t/* Must be an ACK request or a late INVITE retransmission. */\n\tpj_assert(msg->line.req.method.id == PJSIP_ACK_METHOD || \n\t\t  msg->line.req.method.id == PJSIP_INVITE_METHOD);\n\n    } else if (event->type == PJSIP_EVENT_TIMER) {\n\t/* Ignore overlapped retransmit timer.\n\t * https://trac.pjsip.org/repos/ticket/1746\n\t */\n\tif (event->body.timer.entry == &tsx->retransmit_timer) {\n\t    /* Ignore */\n\t} else {\n\t    /* Must be from timeout_timer_. */\n\t    pj_assert(event->body.timer.entry == &tsx->timeout_timer);\n\n\t    /* Move to Terminated state. */\n\t    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,\n\t\t\t   PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0 );\n\n\t    /* Transaction has been destroyed. */\n\t    //return PJSIP_ETSXDESTROYED;\n\t}\n    } else {\n\tpj_assert(!\"Unexpected event\");\n        return PJ_EBUG;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Handler for events in state Terminated.\n */\nstatic pj_status_t tsx_on_state_terminated( pjsip_transaction *tsx,\n                                            pjsip_event *event)\n{\n    pj_assert(tsx->state == PJSIP_TSX_STATE_TERMINATED);\n\n    /* Ignore events other than timer. This used to be an assertion but\n     * events may genuinely arrive at this state.\n     */\n    if (event->type != PJSIP_EVENT_TIMER) {\n\treturn PJ_EIGNORED;\n    }\n\n    /* Destroy this transaction */\n    tsx_set_state(tsx, PJSIP_TSX_STATE_DESTROYED, \n                  event->type, event->body.user.user1, 0 );\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Handler for events in state Destroyed.\n * Shouldn't happen!\n */\nstatic pj_status_t tsx_on_state_destroyed(pjsip_transaction *tsx,\n                                          pjsip_event *event)\n{\n    PJ_UNUSED_ARG(tsx);\n    PJ_UNUSED_ARG(event);\n\n    // See https://trac.pjsip.org/repos/ticket/1432\n    //pj_assert(!\"Not expecting any events!!\");\n\n    return PJ_EIGNORED;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_transport.c",
    "content": "/* $Id: sip_transport.c 4530 2013-05-30 09:27:49Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_transport.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_parser.h>\n#include <pjsip/sip_msg.h>\n#include <pjsip/sip_private.h>\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_module.h>\n#include <pj/addr_resolv.h>\n#include <pj/except.h>\n#include <pj/os.h>\n#include <pj/log.h>\n#include <pj/ioqueue.h>\n#include <pj/hash.h>\n#include <pj/string.h>\n#include <pj/pool.h>\n#include <pj/assert.h>\n#include <pj/lock.h>\n#include <pj/list.h>\n\n\n#define THIS_FILE    \"sip_transport.c\"\n\n#if 0\n#   define TRACE_(x)\tPJ_LOG(5,x)\n\nstatic const char *addr_string(const pj_sockaddr_t *addr)\n{\n    static char str[PJ_INET6_ADDRSTRLEN];\n    pj_inet_ntop(((const pj_sockaddr*)addr)->addr.sa_family, \n\t\t pj_sockaddr_get_addr(addr),\n\t\t str, sizeof(str));\n    return str;\n}\n#else\n#   define TRACE_(x)\n#endif\n\n/* Prototype. */\nstatic pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata);\n\n/* This module has sole purpose to print transmit data to contigous buffer\n * before actually transmitted to the wire. \n */\nstatic pjsip_module mod_msg_print = \n{\n    NULL, NULL,\t\t\t\t/* prev and next\t\t    */\n    { \"mod-msg-print\", 13},\t\t/* Name.\t\t\t    */\n    -1,\t\t\t\t\t/* Id\t\t\t\t    */\n    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER,\t/* Priority\t\t\t    */\n    NULL,\t\t\t\t/* load()\t\t\t    */\n    NULL,\t\t\t\t/* start()\t\t\t    */\n    NULL,\t\t\t\t/* stop()\t\t\t    */\n    NULL,\t\t\t\t/* unload()\t\t\t    */\n    NULL,\t\t\t\t/* on_rx_request()\t\t    */\n    NULL,\t\t\t\t/* on_rx_response()\t\t    */\n    &mod_on_tx_msg,\t\t\t/* on_tx_request()\t\t    */\n    &mod_on_tx_msg,\t\t\t/* on_tx_response()\t\t    */\n    NULL,\t\t\t\t/* on_tsx_state()\t\t    */\n};\n\n/* Transport list item */\ntypedef struct transport\n{\n    PJ_DECL_LIST_MEMBER(struct transport);\n    pjsip_transport *tp;\n} transport;\n\n/*\n * Transport manager.\n */\nstruct pjsip_tpmgr \n{\n    pj_hash_table_t *table;\n    pj_lock_t\t    *lock;\n    pjsip_endpoint  *endpt;\n    pjsip_tpfactory  factory_list;\n#if defined(PJ_DEBUG) && PJ_DEBUG!=0\n    pj_atomic_t\t    *tdata_counter;\n#endif\n    void           (*on_rx_msg)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*);\n    pj_status_t\t   (*on_tx_msg)(pjsip_endpoint*, pjsip_tx_data*);\n    pjsip_tp_state_callback tp_state_cb;\n    pjsip_tp_on_rx_dropped_cb tp_drop_data_cb;\n\n    /* Transmit data list, for transmit data cleanup when transport manager\n     * is destroyed.\n     */\n    pjsip_tx_data    tdata_list;\n    \n    /* List of transports which are NOT stored in the hash table, so\n     * that it can be properly cleaned up when transport manager\n     * is destroyed.\n     */\n    transport        tp_list;\n};\n\n\n/* Transport state listener list type */\ntypedef struct tp_state_listener\n{\n    PJ_DECL_LIST_MEMBER(struct tp_state_listener);\n\n    pjsip_tp_state_callback  cb;\n    void *user_data;\n} tp_state_listener;\n\n\n/*\n * Transport data.\n */\ntypedef struct transport_data\n{\n    /* Transport listeners */\n    tp_state_listener\t    st_listeners;\n    tp_state_listener\t    st_listeners_empty;\n} transport_data;\n\n\n/*****************************************************************************\n *\n * GENERAL TRANSPORT (NAMES, TYPES, ETC.)\n *\n *****************************************************************************/\n\n/*\n * Transport names.\n */\nstatic struct transport_names_t\n{\n    pjsip_transport_type_e type;\t    /* Transport type\t    */\n    pj_uint16_t\t\t   port;\t    /* Default port number  */\n    pj_str_t\t\t   name;\t    /* Id tag\t\t    */\n    const char\t\t  *description;\t    /* Longer description   */\n    unsigned\t\t   flag;\t    /* Flags\t\t    */\n    char\t\t   name_buf[16];    /* For user's transport */\n} transport_names[16] = \n{\n    { \n\tPJSIP_TRANSPORT_UNSPECIFIED, \n\t0, \n\t{\"Unspecified\", 11}, \n\t\"Unspecified\", \n\t0\n    },\n    { \n\tPJSIP_TRANSPORT_UDP, \n\t5060, \n\t{\"UDP\", 3}, \n\t\"UDP transport\", \n\tPJSIP_TRANSPORT_DATAGRAM\n    },\n    { \n\tPJSIP_TRANSPORT_TCP, \n\t5060, \n\t{\"TCP\", 3}, \n\t\"TCP transport\", \n\tPJSIP_TRANSPORT_RELIABLE\n    },\n    { \n\tPJSIP_TRANSPORT_TLS, \n\t5061, \n\t{\"TLS\", 3}, \n\t\"TLS transport\", \n\tPJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE\n    },\n    { \n\tPJSIP_TRANSPORT_SCTP, \n\t5060, \n\t{\"SCTP\", 4}, \n\t\"SCTP transport\", \n\tPJSIP_TRANSPORT_RELIABLE\n    },\n    { \n\tPJSIP_TRANSPORT_LOOP, \n\t15060, \n\t{\"LOOP\", 4}, \n\t\"Loopback transport\", \n\tPJSIP_TRANSPORT_RELIABLE\n    }, \n    { \n\tPJSIP_TRANSPORT_LOOP_DGRAM, \n\t15060, \n\t{\"LOOP-DGRAM\", 10}, \n\t\"Loopback datagram transport\", \n\tPJSIP_TRANSPORT_DATAGRAM\n    },\n    { \n\tPJSIP_TRANSPORT_UDP6, \n\t5060, \n\t{\"UDP\", 3}, \n\t\"UDP IPv6 transport\", \n\tPJSIP_TRANSPORT_DATAGRAM\n    },\n    { \n\tPJSIP_TRANSPORT_TCP6, \n\t5060, \n\t{\"TCP\", 3}, \n\t\"TCP IPv6 transport\", \n\tPJSIP_TRANSPORT_RELIABLE\n    },\n    {\n\tPJSIP_TRANSPORT_TLS6,\n\t5061,\n\t{\"TLS\", 3},\n\t\"TLS IPv6 transport\",\n\tPJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE\n    },\n};\n\nstatic void tp_state_callback(pjsip_transport *tp,\n\t\t\t      pjsip_transport_state state,\n\t\t\t      const pjsip_transport_state_info *info);\n\n\nstatic struct transport_names_t *get_tpname(pjsip_transport_type_e type)\n{\n    unsigned i;\n    for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {\n\tif (transport_names[i].type == type)\n\t    return &transport_names[i];\n    }\n    pj_assert(!\"Invalid transport type!\");\n    return NULL;\n}\n\n\n\n/*\n * Register new transport type to PJSIP.\n */\nPJ_DEF(pj_status_t) pjsip_transport_register_type( unsigned tp_flag,\n\t\t\t\t\t\t   const char *tp_name,\n\t\t\t\t\t\t   int def_port,\n\t\t\t\t\t\t   int *p_tp_type)\n{\n    unsigned i;\n\n    PJ_ASSERT_RETURN(tp_flag && tp_name && def_port, PJ_EINVAL);\n    PJ_ASSERT_RETURN(pj_ansi_strlen(tp_name) < \n\t\t\tPJ_ARRAY_SIZE(transport_names[0].name_buf), \n\t\t     PJ_ENAMETOOLONG);\n\n    for (i=1; i<PJ_ARRAY_SIZE(transport_names); ++i) {\n\tif (transport_names[i].type == 0)\n\t    break;\n    }\n\n    if (i == PJ_ARRAY_SIZE(transport_names))\n\treturn PJ_ETOOMANY;\n\n    transport_names[i].type = (pjsip_transport_type_e)i;\n    transport_names[i].port = (pj_uint16_t)def_port;\n    pj_ansi_strcpy(transport_names[i].name_buf, tp_name);\n    transport_names[i].name = pj_str(transport_names[i].name_buf);\n    transport_names[i].flag = tp_flag;\n\n    if (p_tp_type)\n\t*p_tp_type = i;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get transport type from name.\n */\nPJ_DEF(pjsip_transport_type_e) pjsip_transport_get_type_from_name(const pj_str_t *name)\n{\n    unsigned i;\n\n    if (name->slen == 0)\n\treturn PJSIP_TRANSPORT_UNSPECIFIED;\n\n    /* Get transport type from name. */\n    for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {\n\tif (pj_stricmp(name, &transport_names[i].name) == 0) {\n\t    return transport_names[i].type;\n\t}\n    }\n\n    pj_assert(!\"Invalid transport name\");\n    return PJSIP_TRANSPORT_UNSPECIFIED;\n}\n\n\n/*\n * Get the transport type for the specified flags.\n */\nPJ_DEF(pjsip_transport_type_e) pjsip_transport_get_type_from_flag(unsigned flag)\n{\n    unsigned i;\n\n    /* Get the transport type for the specified flags. */\n    for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {\n\tif (transport_names[i].flag == flag) {\n\t    return transport_names[i].type;\n\t}\n    }\n\n    pj_assert(!\"Invalid transport type\");\n    return PJSIP_TRANSPORT_UNSPECIFIED;\n}\n\n/*\n * Get the socket address family of a given transport type.\n */\nPJ_DEF(int) pjsip_transport_type_get_af(pjsip_transport_type_e type)\n{\n    if (type & PJSIP_TRANSPORT_IPV6)\n\treturn pj_AF_INET6();\n    else\n\treturn pj_AF_INET();\n}\n\nPJ_DEF(unsigned) pjsip_transport_get_flag_from_type(pjsip_transport_type_e type)\n{\n    /* Return transport flag. */\n    return get_tpname(type)->flag;\n}\n\n/*\n * Get the default SIP port number for the specified type.\n */\nPJ_DEF(int) pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type)\n{\n    /* Return the port. */\n    return get_tpname(type)->port;\n}\n\n/*\n * Get transport name.\n */\nPJ_DEF(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e type)\n{\n    /* Return the name. */\n    return get_tpname(type)->name.ptr;\n}\n\n/*\n * Get transport description.\n */\nPJ_DEF(const char*) pjsip_transport_get_type_desc(pjsip_transport_type_e type)\n{\n    /* Return the description. */\n    return get_tpname(type)->description;\n}\n\n\n/*****************************************************************************\n *\n * TRANSPORT SELECTOR\n *\n *****************************************************************************/\n\n/*\n * Add transport/listener reference in the selector.\n */\nPJ_DEF(void) pjsip_tpselector_add_ref(pjsip_tpselector *sel)\n{\n    if (sel->type == PJSIP_TPSELECTOR_TRANSPORT && sel->u.transport != NULL)\n\tpjsip_transport_add_ref(sel->u.transport);\n    else if (sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener != NULL)\n\t; /* Hmm.. looks like we don't have reference counter for listener */\n}\n\n\n/*\n * Decrement transport/listener reference in the selector.\n */\nPJ_DEF(void) pjsip_tpselector_dec_ref(pjsip_tpselector *sel)\n{\n    if (sel->type == PJSIP_TPSELECTOR_TRANSPORT && sel->u.transport != NULL)\n\tpjsip_transport_dec_ref(sel->u.transport);\n    else if (sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener != NULL)\n\t; /* Hmm.. looks like we don't have reference counter for listener */\n}\n\n\n/*****************************************************************************\n *\n * TRANSMIT DATA BUFFER MANIPULATION.\n *\n *****************************************************************************/\n\n/*\n * Create new transmit buffer.\n */\nPJ_DEF(pj_status_t) pjsip_tx_data_create( pjsip_tpmgr *mgr,\n\t\t\t\t\t  pjsip_tx_data **p_tdata )\n{\n    pj_pool_t *pool;\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(mgr && p_tdata, PJ_EINVAL);\n\n    pool = pjsip_endpt_create_pool( mgr->endpt, \"tdta%p\",\n\t\t\t\t    PJSIP_POOL_LEN_TDATA,\n\t\t\t\t    PJSIP_POOL_INC_TDATA );\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    tdata = PJ_POOL_ZALLOC_T(pool, pjsip_tx_data);\n    tdata->pool = pool;\n    tdata->mgr = mgr;\n    pj_memcpy(tdata->obj_name, pool->obj_name, PJ_MAX_OBJ_NAME);\n\n    status = pj_atomic_create(tdata->pool, 0, &tdata->ref_cnt);\n    if (status != PJ_SUCCESS) {\n\tpjsip_endpt_release_pool( mgr->endpt, tdata->pool );\n\treturn status;\n    }\n    \n    //status = pj_lock_create_simple_mutex(pool, \"tdta%p\", &tdata->lock);\n    status = pj_lock_create_null_mutex(pool, \"tdta%p\", &tdata->lock);\n    if (status != PJ_SUCCESS) {\n\tpjsip_endpt_release_pool( mgr->endpt, tdata->pool );\n\treturn status;\n    }\n\n    pj_ioqueue_op_key_init(&tdata->op_key.key, sizeof(tdata->op_key.key));\n    pj_list_init(tdata);\n\n#if defined(PJSIP_HAS_TX_DATA_LIST) && PJSIP_HAS_TX_DATA_LIST!=0\n    /* Append this just created tdata to transmit buffer list */\n    pj_lock_acquire(mgr->lock);\n    pj_list_push_back(&mgr->tdata_list, tdata);\n    pj_lock_release(mgr->lock);\n#endif\n\n#if defined(PJ_DEBUG) && PJ_DEBUG!=0\n    pj_atomic_inc( tdata->mgr->tdata_counter );\n#endif\n\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Add reference to tx buffer.\n */\nPJ_DEF(void) pjsip_tx_data_add_ref( pjsip_tx_data *tdata )\n{\n    pj_atomic_inc(tdata->ref_cnt);\n}\n\nstatic void tx_data_destroy(pjsip_tx_data *tdata)\n{\n    PJ_LOG(5,(tdata->obj_name, \"Destroying txdata %s\",\n\t      pjsip_tx_data_get_info(tdata)));\n    pjsip_tpselector_dec_ref(&tdata->tp_sel);\n#if defined(PJ_DEBUG) && PJ_DEBUG!=0\n    pj_atomic_dec( tdata->mgr->tdata_counter );\n#endif\n\n#if defined(PJSIP_HAS_TX_DATA_LIST) && PJSIP_HAS_TX_DATA_LIST!=0\n    /* Remove this tdata from transmit buffer list */\n    pj_lock_acquire(tdata->mgr->lock);\n    pj_list_erase(tdata);\n    pj_lock_release(tdata->mgr->lock);\n#endif\n\n    pj_atomic_destroy( tdata->ref_cnt );\n    pj_lock_destroy( tdata->lock );\n    pjsip_endpt_release_pool( tdata->mgr->endpt, tdata->pool );\n}\n\n/*\n * Decrease transport data reference, destroy it when the reference count\n * reaches zero.\n */\nPJ_DEF(pj_status_t) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata )\n{\n    pj_assert( pj_atomic_get(tdata->ref_cnt) > 0);\n    if (pj_atomic_dec_and_get(tdata->ref_cnt) <= 0) {\n\ttx_data_destroy(tdata);\n\treturn PJSIP_EBUFDESTROYED;\n    } else {\n\treturn PJ_SUCCESS;\n    }\n}\n\n/*\n * Invalidate the content of the print buffer to force the message to be\n * re-printed when sent.\n */\nPJ_DEF(void) pjsip_tx_data_invalidate_msg( pjsip_tx_data *tdata )\n{\n    tdata->buf.cur = tdata->buf.start;\n    tdata->info = NULL;\n}\n\n/*\n * Print the SIP message to transmit data buffer's internal buffer.\n */\nPJ_DEF(pj_status_t) pjsip_tx_data_encode(pjsip_tx_data *tdata)\n{\n    /* Allocate buffer if necessary. */\n    if (tdata->buf.start == NULL) {\n\tPJ_USE_EXCEPTION;\n\n\tPJ_TRY {\n\t    tdata->buf.start = (char*) \n\t\t\t       pj_pool_alloc(tdata->pool, PJSIP_MAX_PKT_LEN);\n\t}\n\tPJ_CATCH_ANY {\n\t    return PJ_ENOMEM;\n\t}\n\tPJ_END\n\n\ttdata->buf.cur = tdata->buf.start;\n\ttdata->buf.end = tdata->buf.start + PJSIP_MAX_PKT_LEN;\n    }\n\n    /* Do we need to reprint? */\n    if (!pjsip_tx_data_is_valid(tdata)) {\n\tpj_ssize_t size;\n\n\tsize = pjsip_msg_print( tdata->msg, tdata->buf.start, \n\t\t\t        tdata->buf.end - tdata->buf.start);\n\tif (size < 0) {\n\t    return PJSIP_EMSGTOOLONG;\n\t}\n\tpj_assert(size != 0);\n\ttdata->buf.cur[size] = '\\0';\n\ttdata->buf.cur += size;\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_bool_t) pjsip_tx_data_is_valid( pjsip_tx_data *tdata )\n{\n    return tdata->buf.cur != tdata->buf.start;\n}\n\nstatic char *get_msg_info(pj_pool_t *pool, const char *obj_name,\n\t\t\t  const pjsip_msg *msg)\n{\n    char info_buf[128], *info;\n    const pjsip_cseq_hdr *cseq;\n    int len;\n\n    cseq = (const pjsip_cseq_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL);\n    PJ_ASSERT_RETURN(cseq != NULL, \"INVALID MSG\");\n\n    if (msg->type == PJSIP_REQUEST_MSG) {\n\tlen = pj_ansi_snprintf(info_buf, sizeof(info_buf), \n\t\t\t       \"Request msg %.*s/cseq=%d (%s)\",\n\t\t\t       (int)msg->line.req.method.name.slen,\n\t\t\t       msg->line.req.method.name.ptr,\n\t\t\t       cseq->cseq, obj_name);\n    } else {\n\tlen = pj_ansi_snprintf(info_buf, sizeof(info_buf),\n\t\t\t       \"Response msg %d/%.*s/cseq=%d (%s)\",\n\t\t\t       msg->line.status.code,\n\t\t\t       (int)cseq->method.name.slen,\n\t\t\t       cseq->method.name.ptr,\n\t\t\t       cseq->cseq, obj_name);\n    }\n\n    if (len < 1 || len >= (int)sizeof(info_buf)) {\n\treturn (char*)obj_name;\n    }\n\n    info = (char*) pj_pool_alloc(pool, len+1);\n    pj_memcpy(info, info_buf, len+1);\n\n    return info;\n}\n\nPJ_DEF(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata )\n{\n    PJ_ASSERT_RETURN(tdata, \"NULL\");\n\n    /* tdata->info may be assigned by application so if it exists\n     * just return it.\n     */\n    if (tdata->info)\n\treturn tdata->info;\n\n    if (tdata->msg==NULL)\n\treturn \"NULL\";\n\n    pj_lock_acquire(tdata->lock);\n    tdata->info = get_msg_info(tdata->pool, tdata->obj_name, tdata->msg);\n    pj_lock_release(tdata->lock);\n\n    return tdata->info;\n}\n\nPJ_DEF(pj_status_t) pjsip_tx_data_set_transport(pjsip_tx_data *tdata,\n\t\t\t\t\t\tconst pjsip_tpselector *sel)\n{\n    PJ_ASSERT_RETURN(tdata && sel, PJ_EINVAL);\n\n    pj_lock_acquire(tdata->lock);\n\n    pjsip_tpselector_dec_ref(&tdata->tp_sel);\n\n    pj_memcpy(&tdata->tp_sel, sel, sizeof(*sel));\n    pjsip_tpselector_add_ref(&tdata->tp_sel);\n\n    pj_lock_release(tdata->lock);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata)\n{\n    char obj_name[PJ_MAX_OBJ_NAME];\n\n    PJ_ASSERT_RETURN(rdata->msg_info.msg, \"INVALID MSG\");\n\n    if (rdata->msg_info.info)\n\treturn rdata->msg_info.info;\n\n    pj_ansi_strcpy(obj_name, \"rdata\");\n    pj_ansi_snprintf(obj_name+5, sizeof(obj_name)-5, \"%p\", rdata);\n\n    rdata->msg_info.info = get_msg_info(rdata->tp_info.pool, obj_name,\n\t\t\t\t\trdata->msg_info.msg);\n    return rdata->msg_info.info;\n}\n\n/* Clone pjsip_rx_data. */\nPJ_DEF(pj_status_t) pjsip_rx_data_clone( const pjsip_rx_data *src,\n                                         unsigned flags,\n                                         pjsip_rx_data **p_rdata)\n{\n    pj_pool_t *pool;\n    pjsip_rx_data *dst;\n    pjsip_hdr *hdr;\n\n    PJ_ASSERT_RETURN(src && flags==0 && p_rdata, PJ_EINVAL);\n\n    pool = pj_pool_create(src->tp_info.pool->factory,\n                          \"rtd%p\",\n                          PJSIP_POOL_RDATA_LEN,\n                          PJSIP_POOL_RDATA_INC,\n                          NULL);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    dst = PJ_POOL_ZALLOC_T(pool, pjsip_rx_data);\n\n    /* Parts of tp_info */\n    dst->tp_info.pool = pool;\n    dst->tp_info.transport = (pjsip_transport*)src->tp_info.transport;\n\n    /* pkt_info can be memcopied */\n    pj_memcpy(&dst->pkt_info, &src->pkt_info, sizeof(src->pkt_info));\n\n    /* msg_info needs deep clone */\n    dst->msg_info.msg_buf = dst->pkt_info.packet;\n    dst->msg_info.len = src->msg_info.len;\n    dst->msg_info.msg = pjsip_msg_clone(pool, src->msg_info.msg);\n    pj_list_init(&dst->msg_info.parse_err);\n\n#define GET_MSG_HDR2(TYPE, type, var)\t\\\n\t\t\tcase PJSIP_H_##TYPE: \\\n\t\t\t    if (!dst->msg_info.var) { \\\n\t\t\t\tdst->msg_info.var = (pjsip_##type##_hdr*)hdr; \\\n\t\t\t    } \\\n\t\t\t    break\n#define GET_MSG_HDR(TYPE, var_type)\tGET_MSG_HDR2(TYPE, var_type, var_type)\n\n    hdr = dst->msg_info.msg->hdr.next;\n    while (hdr != &dst->msg_info.msg->hdr) {\n\tswitch (hdr->type) {\n\tGET_MSG_HDR(CALL_ID, cid);\n\tGET_MSG_HDR(FROM, from);\n\tGET_MSG_HDR(TO, to);\n\tGET_MSG_HDR(VIA, via);\n\tGET_MSG_HDR(CSEQ, cseq);\n\tGET_MSG_HDR(MAX_FORWARDS, max_fwd);\n\tGET_MSG_HDR(ROUTE, route);\n\tGET_MSG_HDR2(RECORD_ROUTE, rr, record_route);\n\tGET_MSG_HDR(CONTENT_TYPE, ctype);\n\tGET_MSG_HDR(CONTENT_LENGTH, clen);\n\tGET_MSG_HDR(REQUIRE, require);\n\tGET_MSG_HDR(SUPPORTED, supported);\n\tdefault:\n\t    break;\n\t}\n\thdr = hdr->next;\n    }\n\n#undef GET_MSG_HDR\n#undef GET_MSG_HDR2\n\n    *p_rdata = dst;\n\n    /* Finally add transport ref */\n    return pjsip_transport_add_ref(dst->tp_info.transport);\n}\n\n/* Free previously cloned pjsip_rx_data. */\nPJ_DEF(pj_status_t) pjsip_rx_data_free_cloned(pjsip_rx_data *rdata)\n{\n    PJ_ASSERT_RETURN(rdata, PJ_EINVAL);\n\n    pjsip_transport_dec_ref(rdata->tp_info.transport);\n    pj_pool_release(rdata->tp_info.pool);\n\n    return PJ_SUCCESS;\n}\n\n/*****************************************************************************\n *\n * TRANSPORT KEY\n *\n *****************************************************************************/\n\n\n/*****************************************************************************\n *\n * TRANSPORT\n *\n *****************************************************************************/\n\nstatic void transport_send_callback(pjsip_transport *transport,\n\t\t\t\t    void *token,\n\t\t\t\t    pj_ssize_t size)\n{\n    pjsip_tx_data *tdata = (pjsip_tx_data*) token;\n\n    PJ_UNUSED_ARG(transport);\n\n    /* Mark pending off so that app can resend/reuse txdata from inside\n     * the callback.\n     */\n    tdata->is_pending = 0;\n\n    /* Call callback, if any. */\n    if (tdata->cb) {\n\t(*tdata->cb)(tdata->token, tdata, size);\n    }\n\n    /* Decrement reference count. */\n    pjsip_tx_data_dec_ref(tdata);\n}\n\n/* This function is called by endpoint for on_tx_request() and on_tx_response()\n * notification.\n */\nstatic pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata)\n{\n    return pjsip_tx_data_encode(tdata);\n}\n\n/*\n * Send a SIP message using the specified transport.\n */\nPJ_DEF(pj_status_t) pjsip_transport_send(  pjsip_transport *tr, \n\t\t\t\t\t   pjsip_tx_data *tdata,\n\t\t\t\t\t   const pj_sockaddr_t *addr,\n\t\t\t\t\t   int addr_len,\n\t\t\t\t\t   void *token,\n\t\t\t\t\t   pjsip_tp_send_callback cb)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(tr && tdata && addr, PJ_EINVAL);\n\n    /* Is it currently being sent? */\n    if (tdata->is_pending) {\n\tpj_assert(!\"Invalid operation step!\");\n\tPJ_LOG(2,(THIS_FILE, \"Unable to send %s: message is pending\", \n\t\t\t     pjsip_tx_data_get_info(tdata)));\n\treturn PJSIP_EPENDINGTX;\n    }\n\n    /* Add reference to prevent deletion, and to cancel idle timer if\n     * it's running.\n     */\n    pjsip_transport_add_ref(tr);\n\n    /* Fill in tp_info. */\n    tdata->tp_info.transport = tr;\n    pj_memcpy(&tdata->tp_info.dst_addr, addr, addr_len);\n    tdata->tp_info.dst_addr_len = addr_len;\n\n    pj_inet_ntop(((pj_sockaddr*)addr)->addr.sa_family,\n\t\t pj_sockaddr_get_addr(addr),\n\t\t tdata->tp_info.dst_name,\n\t\t sizeof(tdata->tp_info.dst_name));\n    tdata->tp_info.dst_port = pj_sockaddr_get_port(addr);\n\n    /* Distribute to modules. \n     * When the message reach mod_msg_print, the contents of the message will\n     * be \"printed\" to contiguous buffer.\n     */\n    if (tr->tpmgr->on_tx_msg) {\n\tstatus = (*tr->tpmgr->on_tx_msg)(tr->endpt, tdata);\n\tif (status != PJ_SUCCESS) {\n\t    pjsip_transport_dec_ref(tr);\n\t    return status;\n\t}\n    }\n\n    /* Save callback data. */\n    tdata->token = token;\n    tdata->cb = cb;\n\n    /* Add reference counter. */\n    pjsip_tx_data_add_ref(tdata);\n\n    /* Mark as pending. */\n    tdata->is_pending = 1;\n\n    /* Send to transport. */\n    status = (*tr->send_msg)(tr, tdata,  addr, addr_len, (void*)tdata, \n\t\t\t     &transport_send_callback);\n\n    if (status != PJ_EPENDING) {\n\ttdata->is_pending = 0;\n\tpjsip_tx_data_dec_ref(tdata);\n    }\n\n    pjsip_transport_dec_ref(tr);\n    return status;\n}\n\n\n/* send_raw() callback */\nstatic void send_raw_callback(pjsip_transport *transport,\n\t\t\t      void *token,\n\t\t\t      pj_ssize_t size)\n{\n    pjsip_tx_data *tdata = (pjsip_tx_data*) token;\n\n    /* Mark pending off so that app can resend/reuse txdata from inside\n     * the callback.\n     */\n    tdata->is_pending = 0;\n\n    /* Call callback, if any. */\n    if (tdata->cb) {\n\t(*tdata->cb)(tdata->token, tdata, size);\n    }\n\n    /* Decrement tdata reference count. */\n    pjsip_tx_data_dec_ref(tdata);\n\n    /* Decrement transport reference count */\n    pjsip_transport_dec_ref(transport);\n}\n\n\n/* Send raw data */\nPJ_DEF(pj_status_t) pjsip_tpmgr_send_raw(pjsip_tpmgr *mgr,\n\t\t\t\t\t pjsip_transport_type_e tp_type,\n\t\t\t\t\t const pjsip_tpselector *sel,\n\t\t\t\t\t pjsip_tx_data *tdata,\n\t\t\t\t\t const void *raw_data,\n\t\t\t\t\t pj_size_t data_len,\n\t\t\t\t\t const pj_sockaddr_t *addr,\n\t\t\t\t\t int addr_len,\n\t\t\t\t\t void *token,\n\t\t\t\t\t pjsip_tp_send_callback cb)\n{\n    pjsip_transport *tr;\n    pj_status_t status;\n \n    /* Acquire the transport */\n    status = pjsip_tpmgr_acquire_transport(mgr, tp_type, addr, addr_len,\n\t\t\t\t\t   sel, &tr);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Create transmit data buffer if one is not specified */\n    if (tdata == NULL) {\n\tstatus = pjsip_endpt_create_tdata(tr->endpt, &tdata);\n\tif (status != PJ_SUCCESS) {\n\t    pjsip_transport_dec_ref(tr);\n\t    return status;\n\t}\n\n\ttdata->info = \"raw\";\n\n\t/* Add reference counter. */\n\tpjsip_tx_data_add_ref(tdata);\n    }\n\n    /* Allocate buffer */\n    if (tdata->buf.start == NULL ||\n\t(tdata->buf.end - tdata->buf.start) < (int)data_len)\n    {\n\t/* Note: data_len may be zero, so allocate +1 */\n\ttdata->buf.start = (char*) pj_pool_alloc(tdata->pool, data_len+1);\n\ttdata->buf.end = tdata->buf.start + data_len + 1;\n    }\n \n    /* Copy data, if any! (application may send zero len packet) */\n    if (data_len) {\n\tpj_memcpy(tdata->buf.start, raw_data, data_len);\n    }\n    tdata->buf.cur = tdata->buf.start + data_len;\n \n    /* Save callback data. */\n    tdata->token = token;\n    tdata->cb = cb;\n\n    /* Mark as pending. */\n    tdata->is_pending = 1;\n\n    /* Send to transport */\n    status = tr->send_msg(tr, tdata, addr, addr_len,\n\t\t\t  tdata, &send_raw_callback);\n \n    if (status != PJ_EPENDING) {\n\t/* callback will not be called, so destroy tdata now. */\n\tpjsip_tx_data_dec_ref(tdata);\n\tpjsip_transport_dec_ref(tr);\n    }\n\n    return status;\n}\n\n\nstatic void transport_idle_callback(pj_timer_heap_t *timer_heap,\n\t\t\t\t    struct pj_timer_entry *entry)\n{\n    pjsip_transport *tp = (pjsip_transport*) entry->user_data;\n    pj_assert(tp != NULL);\n\n    PJ_UNUSED_ARG(timer_heap);\n\n    entry->id = PJ_FALSE;\n    pjsip_transport_destroy(tp);\n}\n\n\nstatic pj_bool_t is_transport_valid(pjsip_transport *tp, pjsip_tpmgr *tpmgr,\n\t\t\t\t    const pjsip_transport_key *key,\n\t\t\t\t    int key_len)\n{\n    return (pj_hash_get(tpmgr->table, key, key_len, NULL) == (void*)tp);\n}\n\n/*\n * Add ref.\n */\nPJ_DEF(pj_status_t) pjsip_transport_add_ref( pjsip_transport *tp )\n{\n    pjsip_tpmgr *tpmgr;\n    pjsip_transport_key key;\n    int key_len;\n\n    PJ_ASSERT_RETURN(tp != NULL, PJ_EINVAL);\n\n    /* Cache some vars for checking transport validity later */\n    tpmgr = tp->tpmgr;\n    key_len = sizeof(tp->key.type) + tp->addr_len;\n    pj_memcpy(&key, &tp->key, key_len);\n\n    if (pj_atomic_inc_and_get(tp->ref_cnt) == 1) {\n\tpj_lock_acquire(tpmgr->lock);\n\t/* Verify again. But first, make sure transport is still valid\n\t * (see #1883).\n\t */\n\tif (is_transport_valid(tp, tpmgr, &key, key_len) &&\n\t    pj_atomic_get(tp->ref_cnt) == 1)\n\t{\n\t    if (tp->idle_timer.id != PJ_FALSE) {\n\t\tpjsip_endpt_cancel_timer(tp->tpmgr->endpt, &tp->idle_timer);\n\t\ttp->idle_timer.id = PJ_FALSE;\n\t    }\n\t}\n\tpj_lock_release(tpmgr->lock);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Dec ref.\n */\nPJ_DEF(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp )\n{\n    pjsip_tpmgr *tpmgr;\n    pjsip_transport_key key;\n    int key_len;\n\n    PJ_ASSERT_RETURN(tp != NULL, PJ_EINVAL);\n    pj_assert(pj_atomic_get(tp->ref_cnt) > 0);\n\n    /* Cache some vars for checking transport validity later */\n    tpmgr = tp->tpmgr;\n    key_len = sizeof(tp->key.type) + tp->addr_len;\n    pj_memcpy(&key, &tp->key, key_len);\n\n    if (pj_atomic_dec_and_get(tp->ref_cnt) == 0) {\n\tpj_lock_acquire(tpmgr->lock);\n\t/* Verify again. Do not register timer if the transport is\n\t * being destroyed. But first, make sure transport is still valid\n\t * (see #1883).\n\t */\n\tif (is_transport_valid(tp, tpmgr, &key, key_len) &&\n\t    !tp->is_destroying && pj_atomic_get(tp->ref_cnt) == 0)\n\t{\n\t    pj_time_val delay;\n\t    \n\t    /* If transport is in graceful shutdown, then this is the\n\t     * last user who uses the transport. Schedule to destroy the\n\t     * transport immediately. Otherwise schedule idle timer.\n\t     */\n\t    if (tp->is_shutdown) {\n\t\tdelay.sec = delay.msec = 0;\n\t    } else {\n\t\tdelay.sec = (tp->dir==PJSIP_TP_DIR_OUTGOING) ?\n\t\t\t\tPJSIP_TRANSPORT_IDLE_TIME :\n\t\t\t\tPJSIP_TRANSPORT_SERVER_IDLE_TIME;\n\t\tdelay.msec = 0;\n\t    }\n\n\t    pj_assert(tp->idle_timer.id == 0);\n\t    tp->idle_timer.id = PJ_TRUE;\n\t    pjsip_endpt_schedule_timer(tp->tpmgr->endpt, &tp->idle_timer, \n\t\t\t\t       &delay);\n\t}\n\tpj_lock_release(tpmgr->lock);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Register a transport.\n */\nPJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr,\n\t\t\t\t\t      pjsip_transport *tp )\n{\n    int key_len;\n    pj_uint32_t hval;\n    void *entry;\n\n    /* Init. */\n    tp->tpmgr = mgr;\n    pj_bzero(&tp->idle_timer, sizeof(tp->idle_timer));\n    tp->idle_timer.user_data = tp;\n    tp->idle_timer.cb = &transport_idle_callback;\n\n    /* \n     * Register to hash table (see Trac ticket #42).\n     */\n    key_len = sizeof(tp->key.type) + tp->addr_len;\n    pj_lock_acquire(mgr->lock);\n\n    /* If entry already occupied, unregister previous entry */\n    hval = 0;\n    entry = pj_hash_get(mgr->table, &tp->key, key_len, &hval);\n    if (entry != NULL) {\n        transport *tp_ref;\n        \n        tp_ref = PJ_POOL_ZALLOC_T(((pjsip_transport *)entry)->pool, transport);\n        \n        /*\n         * Add transport to the list before removing it from the hash table.\n         * See ticket #1774 for more details.\n         */\n        tp_ref->tp = (pjsip_transport *)entry;\n        pj_list_push_back(&mgr->tp_list, tp_ref);\n\tpj_hash_set(NULL, mgr->table, &tp->key, key_len, hval, NULL);\n    }\n\n    /* Register new entry */\n    pj_hash_set(tp->pool, mgr->table, &tp->key, key_len, hval, tp);\n\n    pj_lock_release(mgr->lock);\n\n    TRACE_((THIS_FILE,\"Transport %s registered: type=%s, remote=%s:%d\",\n\t\t       tp->obj_name,\n\t\t       pjsip_transport_get_type_name(tp->key.type),\n\t\t       addr_string(&tp->key.rem_addr),\n\t\t       pj_sockaddr_get_port(&tp->key.rem_addr)));\n\n    return PJ_SUCCESS;\n}\n\n/* Force destroy transport (e.g. during transport manager shutdown. */\nstatic pj_status_t destroy_transport( pjsip_tpmgr *mgr,\n\t\t\t\t      pjsip_transport *tp )\n{\n    int key_len;\n    pj_uint32_t hval;\n    void *entry;\n\n    tp->is_destroying = PJ_TRUE;\n\n    TRACE_((THIS_FILE, \"Transport %s is being destroyed\", tp->obj_name));\n\n    pj_lock_acquire(tp->lock);\n    pj_lock_acquire(mgr->lock);\n\n    /*\n     * Unregister timer, if any.\n     */\n    //pj_assert(tp->idle_timer.id == PJ_FALSE);\n    if (tp->idle_timer.id != PJ_FALSE) {\n\tpjsip_endpt_cancel_timer(mgr->endpt, &tp->idle_timer);\n\ttp->idle_timer.id = PJ_FALSE;\n    }\n\n    /*\n     * Unregister from hash table (see Trac ticket #42).\n     */\n    key_len = sizeof(tp->key.type) + tp->addr_len;\n    hval = 0;\n    entry = pj_hash_get(mgr->table, &tp->key, key_len, &hval);\n    if (entry == (void*)tp) {\n\tpj_hash_set(NULL, mgr->table, &tp->key, key_len, hval, NULL);\n    } else {\n        /* If not found in hash table, remove from the tranport list. */\n        transport *tp_iter = mgr->tp_list.next;\n        while (tp_iter != &mgr->tp_list) {\n            if (tp_iter->tp == tp) {\n                pj_list_erase(tp_iter);\n                break;\n            }\n            tp_iter = tp_iter->next;\n        }\n    }\n\n    pj_lock_release(mgr->lock);\n    pj_lock_release(tp->lock);\n\n    /* Destroy. */\n    return tp->destroy(tp);\n}\n\n\n/*\n * Start graceful shutdown procedure for this transport. \n */\nPJ_DEF(pj_status_t) pjsip_transport_shutdown(pjsip_transport *tp)\n{\n    pjsip_tpmgr *mgr;\n    pj_status_t status;\n    pjsip_tp_state_callback state_cb;\n\n    TRACE_((THIS_FILE, \"Transport %s shutting down\", tp->obj_name));\n\n    pj_lock_acquire(tp->lock);\n\n    mgr = tp->tpmgr;\n    pj_lock_acquire(mgr->lock);\n\n    /* Do nothing if transport is being shutdown already */\n    if (tp->is_shutdown) {\n\tpj_lock_release(mgr->lock);\n\tpj_lock_release(tp->lock);\n\treturn PJ_SUCCESS;\n    }\n\n    status = PJ_SUCCESS;\n\n    /* Instruct transport to shutdown itself */\n    if (tp->do_shutdown)\n\tstatus = tp->do_shutdown(tp);\n\n    /* Notify application of transport shutdown */\n    state_cb = pjsip_tpmgr_get_state_cb(tp->tpmgr);\n    if (state_cb) {\n\tpjsip_transport_state_info state_info;\n\n\tpj_bzero(&state_info, sizeof(state_info));\n\tstate_info.status = status;\n        (*state_cb)(tp, PJSIP_TP_STATE_SHUTDOWN, &state_info);\n    }\n\n    if (status == PJ_SUCCESS)\n\ttp->is_shutdown = PJ_TRUE;\n\n    /* If transport reference count is zero, start timer count-down */\n    if (pj_atomic_get(tp->ref_cnt) == 0) {\n\tpjsip_transport_add_ref(tp);\n\tpjsip_transport_dec_ref(tp);\n    }\n\n    pj_lock_release(mgr->lock);\n    pj_lock_release(tp->lock);\n\n    return status;\n}\n\n\n/**\n * Unregister transport.\n */\nPJ_DEF(pj_status_t) pjsip_transport_destroy( pjsip_transport *tp)\n{\n    pjsip_tp_state_callback state_cb;\n\n    /* Must have no user. */\n    PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY);\n\n    /* Notify application of transport destroy */\n    state_cb = pjsip_tpmgr_get_state_cb(tp->tpmgr);\n    if (state_cb) {\n\tpjsip_transport_state_info state_info;\n\n\tpj_bzero(&state_info, sizeof(state_info));\n        (*state_cb)(tp, PJSIP_TP_STATE_DESTROY, &state_info);\n    }\n\n    /* Destroy. */\n    return destroy_transport(tp->tpmgr, tp);\n}\n\n\n\n/*****************************************************************************\n *\n * TRANSPORT FACTORY\n *\n *****************************************************************************/\n\n\nPJ_DEF(pj_status_t) pjsip_tpmgr_register_tpfactory( pjsip_tpmgr *mgr,\n\t\t\t\t\t\t    pjsip_tpfactory *tpf)\n{\n    pjsip_tpfactory *p;\n    pj_status_t status;\n\n    pj_lock_acquire(mgr->lock);\n\n    /* Check that no factory with the same type has been registered. */\n    status = PJ_SUCCESS;\n    for (p=mgr->factory_list.next; p!=&mgr->factory_list; p=p->next) {\n\tif (p->type == tpf->type) {\n\t    status = PJSIP_ETYPEEXISTS;\n\t    break;\n\t}\n\tif (p == tpf) {\n\t    status = PJ_EEXISTS;\n\t    break;\n\t}\n    }\n\n    if (status != PJ_SUCCESS) {\n\tpj_lock_release(mgr->lock);\n\treturn status;\n    }\n\n    pj_list_insert_before(&mgr->factory_list, tpf);\n\n    pj_lock_release(mgr->lock);\n\n    return PJ_SUCCESS;\n}\n\n\n/**\n * Unregister factory.\n */\nPJ_DEF(pj_status_t) pjsip_tpmgr_unregister_tpfactory( pjsip_tpmgr *mgr,\n\t\t\t\t\t\t      pjsip_tpfactory *tpf)\n{\n    pj_lock_acquire(mgr->lock);\n\n    pj_assert(pj_list_find_node(&mgr->factory_list, tpf) == tpf);\n    pj_list_erase(tpf);\n\n    pj_lock_release(mgr->lock);\n\n    return PJ_SUCCESS;\n}\n\nPJ_DECL(void) pjsip_tpmgr_fla2_param_default(pjsip_tpmgr_fla2_param *prm)\n{\n    pj_bzero(prm, sizeof(*prm));\n}\n\nstatic pj_bool_t pjsip_tpmgr_is_tpfactory_valid(pjsip_tpmgr *mgr,\n\t\t\t\t\t\tpjsip_tpfactory *tpf)\n{\n    pjsip_tpfactory *p;\n\n    pj_lock_acquire(mgr->lock);\n    for (p=mgr->factory_list.next; p!=&mgr->factory_list; p=p->next) {\n\tif (p == tpf) {\n\t    pj_lock_release(mgr->lock);\n\t    return PJ_TRUE;\n\t}\n    }\n    pj_lock_release(mgr->lock);\n\n    return PJ_FALSE;\n}\n\n/*****************************************************************************\n *\n * TRANSPORT MANAGER\n *\n *****************************************************************************/\n\n/*\n * Create a new transport manager.\n */\nPJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool,\n\t\t\t\t\tpjsip_endpoint *endpt,\n\t\t\t\t\tpjsip_rx_callback rx_cb,\n\t\t\t\t\tpjsip_tx_callback tx_cb,\n\t\t\t\t\tpjsip_tpmgr **p_mgr)\n{\n    pjsip_tpmgr *mgr;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pool && endpt && rx_cb && p_mgr, PJ_EINVAL);\n\n    /* Register mod_msg_print module. */\n    status = pjsip_endpt_register_module(endpt, &mod_msg_print);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Create and initialize transport manager. */\n    mgr = PJ_POOL_ZALLOC_T(pool, pjsip_tpmgr);\n    mgr->endpt = endpt;\n    mgr->on_rx_msg = rx_cb;\n    mgr->on_tx_msg = tx_cb;\n    pj_list_init(&mgr->factory_list);\n    pj_list_init(&mgr->tdata_list);\n    pj_list_init(&mgr->tp_list);\n\n    mgr->table = pj_hash_create(pool, PJSIP_TPMGR_HTABLE_SIZE);\n    if (!mgr->table)\n\treturn PJ_ENOMEM;\n\n    status = pj_lock_create_recursive_mutex(pool, \"tmgr%p\", &mgr->lock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n#if defined(PJ_DEBUG) && PJ_DEBUG!=0\n    status = pj_atomic_create(pool, 0, &mgr->tdata_counter);\n    if (status != PJ_SUCCESS) {\n    \tpj_lock_destroy(mgr->lock);\n    \treturn status;\n    }\n#endif\n\n    /* Set transport state callback */\n    pjsip_tpmgr_set_state_cb(mgr, &tp_state_callback);\n\n    PJ_LOG(5, (THIS_FILE, \"Transport manager created.\"));\n\n    *p_mgr = mgr;\n    return PJ_SUCCESS;\n}\n\n/* Get the interface to send packet to the specified address */\nstatic pj_status_t get_net_interface(pjsip_transport_type_e tp_type,\n\t\t\t\t     const pj_str_t *dst,\n                                     pj_str_t *itf_str_addr)\n{\n    int af;\n    pj_sockaddr itf_addr;\n    pj_status_t status = -1;\n\n    af = (tp_type & PJSIP_TRANSPORT_IPV6)? PJ_AF_INET6 : PJ_AF_INET;\n\n    if (pjsip_cfg()->endpt.resolve_hostname_to_get_interface) {\n\tstatus = pj_getipinterface(af, dst, &itf_addr, PJ_TRUE, NULL);\n    }\n\n    if (status != PJ_SUCCESS) { \n\tstatus = pj_getipinterface(af, dst, &itf_addr, PJ_FALSE, NULL);\n\tif (status != PJ_SUCCESS) {\n\t    /* If it fails, e.g: on WM6(http://support.microsoft.com/kb/129065),\n\t     * just fallback using pj_gethostip(), see ticket #1660.\n\t     */\n\t    PJ_LOG(5,(THIS_FILE,\"Warning: unable to determine local \"\n\t\t\t\t\"interface, fallback to default interface!\"));\n\t    status = pj_gethostip(af, &itf_addr);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\t}\n    }\n\n    /* Print address */\n    pj_sockaddr_print(&itf_addr, itf_str_addr->ptr,\n\t\t      PJ_INET6_ADDRSTRLEN, 0);\n    itf_str_addr->slen = pj_ansi_strlen(itf_str_addr->ptr);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Find out the appropriate local address info (IP address and port) to\n * advertise in Contact header based on the remote address to be \n * contacted. The local address info would be the address name of the\n * transport or listener which will be used to send the request.\n *\n * In this implementation, it will only select the transport based on\n * the transport type in the request.\n */\nPJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr2(pjsip_tpmgr *tpmgr,\n\t\t\t\t\t\t pj_pool_t *pool,\n\t\t\t\t\t\t pjsip_tpmgr_fla2_param *prm)\n{\n    char tmp_buf[PJ_INET6_ADDRSTRLEN+10];\n    pj_str_t tmp_str;\n    pj_status_t status = PJSIP_EUNSUPTRANSPORT;\n    unsigned flag;\n\n    /* Sanity checks */\n    PJ_ASSERT_RETURN(tpmgr && pool && prm, PJ_EINVAL);\n\n    pj_strset(&tmp_str, tmp_buf, 0);\n    prm->ret_addr.slen = 0;\n    prm->ret_port = 0;\n    prm->ret_tp = NULL;\n\n    flag = pjsip_transport_get_flag_from_type(prm->tp_type);\n\n    if (prm->tp_sel && prm->tp_sel->type == PJSIP_TPSELECTOR_TRANSPORT &&\n\tprm->tp_sel->u.transport)\n    {\n\tconst pjsip_transport *tp = prm->tp_sel->u.transport;\n\tif (prm->local_if) {\n\t    status = get_net_interface((pjsip_transport_type_e)tp->key.type,\n\t\t\t\t       &prm->dst_host, &tmp_str);\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_return;\n\t    pj_strdup(pool, &prm->ret_addr, &tmp_str);\n\t    prm->ret_port = pj_sockaddr_get_port(&tp->local_addr);\n\t    prm->ret_tp = tp;\n\t} else {\n\t    pj_strdup(pool, &prm->ret_addr, &tp->local_name.host);\n\t    prm->ret_port = (pj_uint16_t)tp->local_name.port;\n\t}\n\tstatus = PJ_SUCCESS;\n\n    } else if (prm->tp_sel && prm->tp_sel->type == PJSIP_TPSELECTOR_LISTENER &&\n\t       prm->tp_sel->u.listener)\n    {\n\tif (prm->local_if) {\n\t    status = get_net_interface(prm->tp_sel->u.listener->type,\n\t                               &prm->dst_host, &tmp_str);\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_return;\n\t    pj_strdup(pool, &prm->ret_addr, &tmp_str);\n\t} else {\n\t    pj_strdup(pool, &prm->ret_addr,\n\t\t      &prm->tp_sel->u.listener->addr_name.host);\n\t}\n\tprm->ret_port = (pj_uint16_t)prm->tp_sel->u.listener->addr_name.port;\n\tstatus = PJ_SUCCESS;\n\n    } else if ((flag & PJSIP_TRANSPORT_DATAGRAM) != 0) {\n\tpj_sockaddr remote;\n\tint addr_len;\n\tpjsip_transport *tp;\n\n\tpj_bzero(&remote, sizeof(remote));\n\tif (prm->tp_type & PJSIP_TRANSPORT_IPV6) {\n\t    addr_len = sizeof(pj_sockaddr_in6);\n\t    remote.addr.sa_family = pj_AF_INET6();\n\t} else {\n\t    addr_len = sizeof(pj_sockaddr_in);\n\t    remote.addr.sa_family = pj_AF_INET();\n\t}\n\n\tstatus = pjsip_tpmgr_acquire_transport(tpmgr, prm->tp_type, &remote,\n\t\t\t\t\t       addr_len, NULL, &tp);\n\n\tif (status == PJ_SUCCESS) {\n\t    if (prm->local_if) {\n\t\tstatus = get_net_interface((pjsip_transport_type_e)\n\t\t\t\t\t   tp->key.type,\n\t\t\t\t\t   &prm->dst_host, &tmp_str);\n\t\tif (status != PJ_SUCCESS)\n\t\t    goto on_return;\n\t\tpj_strdup(pool, &prm->ret_addr, &tmp_str);\n\t\tprm->ret_port = pj_sockaddr_get_port(&tp->local_addr);\n\t\tprm->ret_tp = tp;\n\t    } else {\n\t\tpj_strdup(pool, &prm->ret_addr, &tp->local_name.host);\n\t\tprm->ret_port = (pj_uint16_t)tp->local_name.port;\n\t    }\n\n\t    pjsip_transport_dec_ref(tp);\n\t}\n\n    } else {\n\t/* For connection oriented transport, enum the factories */\n\tpjsip_tpfactory *f;\n\n\tpj_lock_acquire(tpmgr->lock);\n\n\tf = tpmgr->factory_list.next;\n\twhile (f != &tpmgr->factory_list) {\n\t    if (f->type == prm->tp_type)\n\t\tbreak;\n\t    f = f->next;\n\t}\n\n\tif (f != &tpmgr->factory_list) {\n\t    if (prm->local_if) {\n\t\tstatus = get_net_interface(f->type, &prm->dst_host,\n\t\t\t\t\t   &tmp_str);\n\t\tif (status == PJ_SUCCESS) {\n\t\t    pj_strdup(pool, &prm->ret_addr, &tmp_str);\n\t\t} else {\n\t\t    /* It could fail \"normally\" on certain cases, e.g.\n\t\t     * when connecting to IPv6 link local address, it\n\t\t     * will wail with EINVAL.\n\t\t     * In this case, fallback to use the default interface\n\t\t     * rather than failing the call.\n\t\t     */\n\t\t    PJ_PERROR(5,(THIS_FILE, status, \"Warning: unable to \"\n\t\t\t         \"determine local interface\"));\n\t\t    pj_strdup(pool, &prm->ret_addr, &f->addr_name.host);\n\t\t    status = PJ_SUCCESS;\n\t\t}\n\t    } else {\n\t\tpj_strdup(pool, &prm->ret_addr, &f->addr_name.host);\n\t    }\n\t    prm->ret_port = (pj_uint16_t)f->addr_name.port;\n\t    status = PJ_SUCCESS;\n\t}\n\tpj_lock_release(tpmgr->lock);\n    }\n\non_return:\n    return status;\n}\n\nPJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr,\n\t\t\t\t\t\t pj_pool_t *pool,\n\t\t\t\t\t\t pjsip_transport_type_e type,\n\t\t\t\t\t\t const pjsip_tpselector *sel,\n\t\t\t\t\t\t pj_str_t *ip_addr,\n\t\t\t\t\t\t int *port)\n{\n    pjsip_tpmgr_fla2_param prm;\n    pj_status_t status;\n\n    pjsip_tpmgr_fla2_param_default(&prm);\n    prm.tp_type = type;\n    prm.tp_sel = sel;\n\n    status = pjsip_tpmgr_find_local_addr2(tpmgr, pool, &prm);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    *ip_addr = prm.ret_addr;\n    *port = prm.ret_port;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Return number of transports currently registered to the transport\n * manager.\n */\nPJ_DEF(unsigned) pjsip_tpmgr_get_transport_count(pjsip_tpmgr *mgr)\n{\n    pj_hash_iterator_t itr_val;\n    pj_hash_iterator_t *itr;\n    int nr_of_transports = 0;\n    \n    pj_lock_acquire(mgr->lock);\n    \n    itr = pj_hash_first(mgr->table, &itr_val);\n    while (itr) {\n\tnr_of_transports++;\n\titr = pj_hash_next(mgr->table, itr);\n    }\n    \n    pj_lock_release(mgr->lock);\n\n    return nr_of_transports;\n}\n\n/*\n * pjsip_tpmgr_destroy()\n *\n * Destroy transport manager.\n */\nPJ_DEF(pj_status_t) pjsip_tpmgr_destroy( pjsip_tpmgr *mgr )\n{\n    pj_hash_iterator_t itr_val;\n    pj_hash_iterator_t *itr;\n    pjsip_tpfactory *factory;\n    pjsip_endpoint *endpt = mgr->endpt;\n    \n    PJ_LOG(5, (THIS_FILE, \"Destroying transport manager\"));\n\n    pj_lock_acquire(mgr->lock);\n\n    /*\n     * Destroy all transports in the hash table.\n     */\n    itr = pj_hash_first(mgr->table, &itr_val);\n    while (itr != NULL) {\n\tpj_hash_iterator_t *next;\n\tpjsip_transport *transport;\n\t\n\ttransport = (pjsip_transport*) pj_hash_this(mgr->table, itr);\n\n\tnext = pj_hash_next(mgr->table, itr);\n\n\tdestroy_transport(mgr, transport);\n\n\titr = next;\n    }\n\n    /*\n     * Destroy transports in the list.\n     */\n    if (!pj_list_empty(&mgr->tp_list)) {\n        transport *tp_iter = mgr->tp_list.next;\n        while (tp_iter != &mgr->tp_list) {\n\t    transport *next = tp_iter->next;\n\t    destroy_transport(mgr, tp_iter->tp);\n\t    tp_iter = next;\n        }\n    }\n    \n    /*\n     * Destroy all factories/listeners.\n     */\n    factory = mgr->factory_list.next;\n    while (factory != &mgr->factory_list) {\n\tpjsip_tpfactory *next = factory->next;\n\t\n\tfactory->destroy(factory);\n\n\tfactory = next;\n    }\n\n    pj_lock_release(mgr->lock);\n\n#if defined(PJ_DEBUG) && PJ_DEBUG!=0\n    /* If you encounter assert error on this line, it means there are\n     * leakings in transmit data (i.e. some transmit data have not been\n     * destroyed).\n     */\n    //pj_assert(pj_atomic_get(mgr->tdata_counter) == 0);\n    if (pj_atomic_get(mgr->tdata_counter) != 0) {\n\tPJ_LOG(3,(THIS_FILE, \"Warning: %d transmit buffer(s) not freed!\",\n\t\t  pj_atomic_get(mgr->tdata_counter)));\n    }\n#endif\n\n    /*\n     * Destroy any dangling transmit buffer.\n     */\n    if (!pj_list_empty(&mgr->tdata_list)) {\n\tpjsip_tx_data *tdata = mgr->tdata_list.next;\n\twhile (tdata != &mgr->tdata_list) {\n\t    pjsip_tx_data *next = tdata->next;\n\t    tx_data_destroy(tdata);\n\t    tdata = next;\n\t}\n\tPJ_LOG(3,(THIS_FILE, \"Cleaned up dangling transmit buffer(s).\"));\n    }\n\n#if defined(PJ_DEBUG) && PJ_DEBUG!=0\n    pj_atomic_destroy(mgr->tdata_counter);\n#endif\n\n    pj_lock_destroy(mgr->lock);\n\n    /* Unregister mod_msg_print. */\n    if (mod_msg_print.id != -1) {\n\tpjsip_endpt_unregister_module(endpt, &mod_msg_print);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * pjsip_tpmgr_receive_packet()\n *\n * Called by tranports when they receive a new packet.\n */\nPJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr,\n\t\t\t\t\t       pjsip_rx_data *rdata)\n{\n    pjsip_transport *tr = rdata->tp_info.transport;\n\n    char *current_pkt;\n    pj_size_t remaining_len;\n    pj_size_t total_processed = 0;\n\n    /* Check size. */\n    pj_assert(rdata->pkt_info.len > 0);\n    if (rdata->pkt_info.len <= 0)\n\treturn -1;\n\n    current_pkt = rdata->pkt_info.packet;\n    remaining_len = rdata->pkt_info.len;\n\n    tr->last_recv_len = rdata->pkt_info.len;\n    pj_get_timestamp(&tr->last_recv_ts);\n    \n    /* Must NULL terminate buffer. This is the requirement of the \n     * parser etc. \n     */\n    current_pkt[remaining_len] = '\\0';\n\n    /* Process all message fragments. */\n    while (remaining_len > 0) {\n\n\tpjsip_msg *msg;\n\tchar *p, *end;\n\tchar saved;\n\tpj_size_t msg_fragment_size;\n\n\t/* Skip leading newlines as pjsip_find_msg() currently can't\n\t * handle leading newlines.\n\t */\n\tfor (p=current_pkt, end=p+remaining_len; p!=end; ++p) {\n\t    if (*p != '\\r' && *p != '\\n')\n\t\tbreak;\n\t}\n\tif (p!=current_pkt) {\n\t    remaining_len -= (p - current_pkt);\n\t    total_processed += (p - current_pkt);\n\n\t    /* Notify application about the dropped newlines */\n\t    if (mgr->tp_drop_data_cb) {\n\t\tpjsip_tp_dropped_data dd;\n\t\tpj_bzero(&dd, sizeof(dd));\n\t\tdd.tp = tr;\n\t\tdd.data = current_pkt;\n\t\tdd.len = p - current_pkt;\n\t\tdd.status = PJ_EIGNORED;\n\t\t(*mgr->tp_drop_data_cb)(&dd);\n\t    }\n\n\t    current_pkt = p;\n\t    if (remaining_len == 0) {\n\t\treturn total_processed;\n\t    }\n\t}\n\n\t/* Initialize default fragment size. */\n\tmsg_fragment_size = remaining_len;\n\n\t/* Clear and init msg_info in rdata. \n\t * Endpoint might inspect the values there when we call the callback\n\t * to report some errors.\n\t */\n\tpj_bzero(&rdata->msg_info, sizeof(rdata->msg_info));\n\tpj_list_init(&rdata->msg_info.parse_err);\n\trdata->msg_info.msg_buf = current_pkt;\n\trdata->msg_info.len = (int)remaining_len;\n\n\t/* For TCP transport, check if the whole message has been received. */\n\tif ((tr->flag & PJSIP_TRANSPORT_DATAGRAM) == 0) {\n\t    pj_status_t msg_status;\n\t    msg_status = pjsip_find_msg(current_pkt, remaining_len, PJ_FALSE, \n                                        &msg_fragment_size);\n\t    if (msg_status != PJ_SUCCESS) {\n\t\tif (remaining_len == PJSIP_MAX_PKT_LEN) {\n\t\t    mgr->on_rx_msg(mgr->endpt, PJSIP_ERXOVERFLOW, rdata);\n\t\t    \n\t\t    /* Notify application about the message overflow */\n\t    \t    if (mgr->tp_drop_data_cb) {\n\t\t\tpjsip_tp_dropped_data dd;\n\t\t\tpj_bzero(&dd, sizeof(dd));\n\t\t\tdd.tp = tr;\n\t\t\tdd.data = current_pkt;\n\t\t\tdd.len = msg_fragment_size;\n\t\t\tdd.status = PJSIP_ERXOVERFLOW;\n\t\t\t(*mgr->tp_drop_data_cb)(&dd);\n\t    \t    }\n\t\t    \n\t\t    /* Exhaust all data. */\n\t\t    return rdata->pkt_info.len;\n\t\t} else {\n\t\t    /* Not enough data in packet. */\n\t\t    return total_processed;\n\t\t}\n\t    }\n\t}\n\n\t/* Update msg_info. */\n\trdata->msg_info.len = (int)msg_fragment_size;\n\n\t/* Null terminate packet */\n\tsaved = current_pkt[msg_fragment_size];\n\tcurrent_pkt[msg_fragment_size] = '\\0';\n\n\t/* Parse the message. */\n\trdata->msg_info.msg = msg = \n\t    pjsip_parse_rdata( current_pkt, msg_fragment_size, rdata);\n\n\t/* Restore null termination */\n\tcurrent_pkt[msg_fragment_size] = saved;\n\n\t/* Check for parsing syntax error */\n\tif (msg==NULL || !pj_list_empty(&rdata->msg_info.parse_err)) {\n\t    pjsip_parser_err_report *err;\n\t    char buf[128];\n\t    pj_str_t tmp;\n\n\t    /* Gather syntax error information */\n\t    tmp.ptr = buf; tmp.slen = 0;\n\t    err = rdata->msg_info.parse_err.next;\n\t    while (err != &rdata->msg_info.parse_err) {\n\t\tint len;\n\t\tlen = pj_ansi_snprintf(tmp.ptr+tmp.slen, sizeof(buf)-tmp.slen,\n\t\t\t\t       \": %s exception when parsing '%.*s' \"\n\t\t\t\t       \"header on line %d col %d\",\n\t\t\t\t       pj_exception_id_name(err->except_code),\n\t\t\t\t       (int)err->hname.slen, err->hname.ptr,\n\t\t\t\t       err->line, err->col);\n\t\tif (len > 0 && len < (int) (sizeof(buf)-tmp.slen)) {\n\t\t    tmp.slen += len;\n\t\t}\n\t\terr = err->next;\n\t    }\n\n\t    /* Only print error message if there's error.\n\t     * Sometimes we receive blank packets (packets with only CRLF)\n\t     * which were sent to keep NAT bindings.\n\t     */\n\t    if (tmp.slen) {\n\t\tPJ_LOG(1, (THIS_FILE, \n\t\t      \"Error processing %d bytes packet from %s %s:%d %.*s:\\n\"\n\t\t      \"%.*s\\n\"\n\t\t      \"-- end of packet.\",\n\t\t      msg_fragment_size,\n\t\t      rdata->tp_info.transport->type_name,\n\t\t      rdata->pkt_info.src_name, \n\t\t      rdata->pkt_info.src_port,\n\t\t      (int)tmp.slen, tmp.ptr,\n\t\t      (int)msg_fragment_size,\n\t\t      rdata->msg_info.msg_buf));\n\t    }\n\n\t    /* Notify application about the dropped data (syntax error) */\n\t    if (tmp.slen && mgr->tp_drop_data_cb) {\n\t\tpjsip_tp_dropped_data dd;\n\t\tpj_bzero(&dd, sizeof(dd));\n\t\tdd.tp = tr;\n\t\tdd.data = current_pkt;\n\t\tdd.len = msg_fragment_size;\n\t\tdd.status = PJSIP_EINVALIDMSG;\n\t\t(*mgr->tp_drop_data_cb)(&dd);\n\t\t\n\t\tif (dd.len > 0 && dd.len < msg_fragment_size)\n\t\t    msg_fragment_size = dd.len;\n\t    }\n\n\t    goto finish_process_fragment;\n\t}\n\n\t/* Perform basic header checking. */\n\tif (rdata->msg_info.cid == NULL ||\n\t    rdata->msg_info.cid->id.slen == 0 || \n\t    rdata->msg_info.from == NULL || \n\t    rdata->msg_info.to == NULL || \n\t    rdata->msg_info.via == NULL || \n\t    rdata->msg_info.cseq == NULL) \n\t{\n\t    mgr->on_rx_msg(mgr->endpt, PJSIP_EMISSINGHDR, rdata);\n\t    goto finish_process_fragment;\n\t}\n\n\t/* For request: */\n\tif (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {\n\t    /* always add received parameter to the via. */\n\t    pj_strdup2(rdata->tp_info.pool, \n\t\t       &rdata->msg_info.via->recvd_param, \n\t\t       rdata->pkt_info.src_name);\n\n\t    /* RFC 3581:\n\t     * If message contains \"rport\" param, put the received port there.\n\t     */\n\t    if (rdata->msg_info.via->rport_param == 0) {\n\t\trdata->msg_info.via->rport_param = rdata->pkt_info.src_port;\n\t    }\n\t} else {\n\t    /* Drop malformed responses */\n\t    if (rdata->msg_info.msg->line.status.code < 100 ||\n\t\trdata->msg_info.msg->line.status.code >= 700)\n\t    {\n\t\tmgr->on_rx_msg(mgr->endpt, PJSIP_EINVALIDSTATUS, rdata);\n\t\tgoto finish_process_fragment;\n\t    }\n\t}\n\n\t/* Drop response message if it has more than one Via.\n\t*/\n\t/* This is wrong. Proxy DOES receive responses with multiple\n\t * Via headers! Thanks Aldo <acampi at deis.unibo.it> for pointing\n\t * this out.\n\n\tif (msg->type == PJSIP_RESPONSE_MSG) {\n\t    pjsip_hdr *hdr;\n\t    hdr = (pjsip_hdr*)rdata->msg_info.via->next;\n\t    if (hdr != &msg->hdr) {\n\t\thdr = pjsip_msg_find_hdr(msg, PJSIP_H_VIA, hdr);\n\t\tif (hdr) {\n\t\t    mgr->on_rx_msg(mgr->endpt, PJSIP_EMULTIPLEVIA, rdata);\n\t\t    goto finish_process_fragment;\n\t\t}\n\t    }\n\t}\n\t*/\n\n\t/* Call the transport manager's upstream message callback.\n\t */\n\tmgr->on_rx_msg(mgr->endpt, PJ_SUCCESS, rdata);\n\n\nfinish_process_fragment:\n\ttotal_processed += msg_fragment_size;\n\tcurrent_pkt += msg_fragment_size;\n\tremaining_len -= msg_fragment_size;\n\n    }\t/* while (rdata->pkt_info.len > 0) */\n\n\n    return total_processed;\n}\n\n\n/*\n * pjsip_tpmgr_acquire_transport()\n *\n * Get transport suitable to communicate to remote. Create a new one\n * if necessary.\n */\nPJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr,\n\t\t\t\t\t\t  pjsip_transport_type_e type,\n\t\t\t\t\t\t  const pj_sockaddr_t *remote,\n\t\t\t\t\t\t  int addr_len,\n\t\t\t\t\t\t  const pjsip_tpselector *sel,\n\t\t\t\t\t\t  pjsip_transport **tp)\n{\n    return pjsip_tpmgr_acquire_transport2(mgr, type, remote, addr_len, sel,\n\t\t\t\t\t  NULL, tp);\n}\n\n/*\n * pjsip_tpmgr_acquire_transport2()\n *\n * Get transport suitable to communicate to remote. Create a new one\n * if necessary.\n */\nPJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,\n\t\t\t\t\t\t   pjsip_transport_type_e type,\n\t\t\t\t\t\t   const pj_sockaddr_t *remote,\n\t\t\t\t\t\t   int addr_len,\n\t\t\t\t\t\t   const pjsip_tpselector *sel,\n\t\t\t\t\t\t   pjsip_tx_data *tdata,\n\t\t\t\t\t\t   pjsip_transport **tp)\n{\n    pjsip_tpfactory *factory;\n    pj_status_t status;\n\n    TRACE_((THIS_FILE,\"Acquiring transport type=%s, remote=%s:%d\",\n\t\t       pjsip_transport_get_type_name(type),\n\t\t       addr_string(remote),\n\t\t       pj_sockaddr_get_port(remote)));\n\n    pj_lock_acquire(mgr->lock);\n\n    /* If transport is specified, then just use it if it is suitable\n     * for the destination.\n     */\n    if (sel && sel->type == PJSIP_TPSELECTOR_TRANSPORT &&\n\tsel->u.transport) \n    {\n\tpjsip_transport *seltp = sel->u.transport;\n\n\t/* See if the transport is (not) suitable */\n\tif (seltp->key.type != type) {\n\t    pj_lock_release(mgr->lock);\n\t    return PJSIP_ETPNOTSUITABLE;\n\t}\n\n\t/* We could also verify that the destination address is reachable\n\t * from this transport (i.e. both are equal), but if application\n\t * has requested a specific transport to be used, assume that\n\t * it knows what to do.\n\t *\n\t * In other words, I don't think destination verification is a good\n\t * idea for now.\n\t */\n\n\t/* Transport looks to be suitable to use, so just use it. */\n\tpjsip_transport_add_ref(seltp);\n\tpj_lock_release(mgr->lock);\n\t*tp = seltp;\n\n\tTRACE_((THIS_FILE, \"Transport %s acquired\", seltp->obj_name));\n\treturn PJ_SUCCESS;\n\n    } else {\n\n\t/*\n\t * This is the \"normal\" flow, where application doesn't specify\n\t * specific transport to be used to send message to.\n\t * In this case, lookup the transport from the hash table.\n\t */\n\tpjsip_transport_key key;\n\tint key_len;\n\tpjsip_transport *transport;\n\n\t/* If listener is specified, verify that the listener type matches\n\t * the destination type.\n\t */\n\tif (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener)\n\t{\n\t    if (sel->u.listener->type != type) {\n\t\tpj_lock_release(mgr->lock);\n\t\treturn PJSIP_ETPNOTSUITABLE;\n\t    }\n\t}\n\n\tpj_bzero(&key, sizeof(key));\n\tkey_len = sizeof(key.type) + addr_len;\n\n\t/* First try to get exact destination. */\n\tkey.type = type;\n\tpj_memcpy(&key.rem_addr, remote, addr_len);\n\n\ttransport = (pjsip_transport*)\n\t\t    pj_hash_get(mgr->table, &key, key_len, NULL);\n\n\tif (transport == NULL) {\n\t    unsigned flag = pjsip_transport_get_flag_from_type(type);\n\t    const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote;\n\n\n\t    /* Ignore address for loop transports. */\n\t    if (type == PJSIP_TRANSPORT_LOOP ||\n\t\t     type == PJSIP_TRANSPORT_LOOP_DGRAM)\n\t    {\n\t\tpj_sockaddr *addr = &key.rem_addr;\n\n\t\tpj_bzero(addr, addr_len);\n\t\tkey_len = sizeof(key.type) + addr_len;\n\t\ttransport = (pjsip_transport*) \n\t\t\t    pj_hash_get(mgr->table, &key, key_len, NULL);\n\t    }\n\t    /* For datagram transports, try lookup with zero address.\n\t     */\n\t    else if (flag & PJSIP_TRANSPORT_DATAGRAM)\n\t    {\n\t\tpj_sockaddr *addr = &key.rem_addr;\n\n\t\tpj_bzero(addr, addr_len);\n\t\taddr->addr.sa_family = remote_addr->addr.sa_family;\n\n\t\tkey_len = sizeof(key.type) + addr_len;\n\t\ttransport = (pjsip_transport*)\n\t\t\t    pj_hash_get(mgr->table, &key, key_len, NULL);\n\t    }\n\t}\n\n\t/* If transport is found and listener is specified, verify listener */\n\telse if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&\n\t\t sel->u.listener && transport->factory != sel->u.listener)\n\t{\n\t    transport = NULL;\n\t    /* This will cause a new transport to be created which will be a\n\t     * 'duplicate' of the existing transport (same type & remote addr,\n\t     * but different factory). Any future hash lookup will return\n\t     * the new one, and eventually the old one will still be freed\n\t     * (by application or #1774).\n\t     */\n\t}\n\n\tif (transport!=NULL && !transport->is_shutdown) {\n\t    /*\n\t     * Transport found!\n\t     */\n\t    pjsip_transport_add_ref(transport);\n\t    pj_lock_release(mgr->lock);\n\t    *tp = transport;\n\n\t    TRACE_((THIS_FILE, \"Transport %s acquired\", transport->obj_name));\n\t    return PJ_SUCCESS;\n\t}\n\n\n\t/*\n\t * Transport not found!\n\t * So we need to create one, find factory that can create\n\t * such transport.\n\t */\n\tif (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener)\n\t{\n\t    /* Application has requested that a specific listener is to\n\t     * be used.\n\t     */\n\n\t    /* Verify that the listener type matches the destination type */\n\t    if (sel->u.listener->type != type) {\n\t\tpj_lock_release(mgr->lock);\n\t\treturn PJSIP_ETPNOTSUITABLE;\n\t    }\n\n\t    /* We'll use this listener to create transport */\n\t    factory = sel->u.listener;\n\n\t    /* Verify if listener is still valid */\n\t    if (!pjsip_tpmgr_is_tpfactory_valid(mgr, factory)) {\n\t\tpj_lock_release(mgr->lock);\n\t\tPJ_LOG(3,(THIS_FILE, \"Specified factory for creating \"\n\t\t\t\t     \"transport is not found\"));\n\t\treturn PJ_ENOTFOUND;\n\t    }\n\n\t} else {\n\n\t    /* Find factory with type matches the destination type */\n\t    factory = mgr->factory_list.next;\n\t    while (factory != &mgr->factory_list) {\n\t\tif (factory->type == type)\n\t\t    break;\n\t\tfactory = factory->next;\n\t    }\n\n\t    if (factory == &mgr->factory_list) {\n\t\t/* No factory can create the transport! */\n\t\tpj_lock_release(mgr->lock);\n\t\tTRACE_((THIS_FILE, \"No suitable factory was found either\"));\n\t\treturn PJSIP_EUNSUPTRANSPORT;\n\t    }\n\t}\n    }\n\n    TRACE_((THIS_FILE, \"Creating new transport from factory\"));\n\n    /* Request factory to create transport. */\n    if (factory->create_transport2) {\n\tstatus = factory->create_transport2(factory, mgr, mgr->endpt,\n\t\t\t\t\t    (const pj_sockaddr*) remote, \n\t\t\t\t\t    addr_len, tdata, tp);\n    } else {\n\tstatus = factory->create_transport(factory, mgr, mgr->endpt,\n\t\t\t\t\t   (const pj_sockaddr*) remote, \n\t\t\t\t\t   addr_len, tp);\n    }\n    if (status == PJ_SUCCESS) {\n\tPJ_ASSERT_ON_FAIL(tp!=NULL, \n\t    {pj_lock_release(mgr->lock); return PJ_EBUG;});\n\tpjsip_transport_add_ref(*tp);\n\t(*tp)->factory = factory;\n    }\n    pj_lock_release(mgr->lock);\n    return status;\n}\n\n/**\n * Dump transport info.\n */\nPJ_DEF(void) pjsip_tpmgr_dump_transports(pjsip_tpmgr *mgr)\n{\n#if PJ_LOG_MAX_LEVEL >= 3\n    pj_hash_iterator_t itr_val;\n    pj_hash_iterator_t *itr;\n    pjsip_tpfactory *factory;\n\n    pj_lock_acquire(mgr->lock);\n\n#if defined(PJ_DEBUG) && PJ_DEBUG!=0\n    PJ_LOG(3,(THIS_FILE, \" Outstanding transmit buffers: %d\",\n\t      pj_atomic_get(mgr->tdata_counter)));\n#endif\n\n    PJ_LOG(3, (THIS_FILE, \" Dumping listeners:\"));\n    factory = mgr->factory_list.next;\n    while (factory != &mgr->factory_list) {\n\tPJ_LOG(3, (THIS_FILE, \"  %s %s:%.*s:%d\", \n\t\t   factory->obj_name,\n\t\t   factory->type_name,\n\t\t   (int)factory->addr_name.host.slen,\n\t\t   factory->addr_name.host.ptr,\n\t\t   (int)factory->addr_name.port));\n\tfactory = factory->next;\n    }\n\n    itr = pj_hash_first(mgr->table, &itr_val);\n    if (itr) {\n\tPJ_LOG(3, (THIS_FILE, \" Dumping transports:\"));\n\n\tdo {\n\t    pjsip_transport *t = (pjsip_transport*) \n\t    \t\t\t pj_hash_this(mgr->table, itr);\n\n\t    PJ_LOG(3, (THIS_FILE, \"  %s %s (refcnt=%d%s)\", \n\t\t       t->obj_name,\n\t\t       t->info,\n\t\t       pj_atomic_get(t->ref_cnt),\n\t\t       (t->idle_timer.id ? \" [idle]\" : \"\")));\n\n\t    itr = pj_hash_next(mgr->table, itr);\n\t} while (itr);\n    }\n\n    pj_lock_release(mgr->lock);\n#else\n    PJ_UNUSED_ARG(mgr);\n#endif\n}\n\n/**\n * Set callback of global transport state notification.\n */\nPJ_DEF(pj_status_t) pjsip_tpmgr_set_state_cb(pjsip_tpmgr *mgr,\n\t\t\t\t\t     pjsip_tp_state_callback cb)\n{\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    mgr->tp_state_cb = cb;\n\n    return PJ_SUCCESS;\n}\n\n/**\n * Get callback of global transport state notification.\n */\nPJ_DEF(pjsip_tp_state_callback) pjsip_tpmgr_get_state_cb(\n\t\t\t\t\t     const pjsip_tpmgr *mgr)\n{\n    PJ_ASSERT_RETURN(mgr, NULL);\n\n    return mgr->tp_state_cb;\n}\n\n\n/**\n * Allocate and init transport data.\n */\nstatic void init_tp_data(pjsip_transport *tp)\n{\n    transport_data *tp_data;\n\n    pj_assert(tp && !tp->data);\n\n    tp_data = PJ_POOL_ZALLOC_T(tp->pool, transport_data);\n    pj_list_init(&tp_data->st_listeners);\n    pj_list_init(&tp_data->st_listeners_empty);\n    tp->data = tp_data;\n}\n\n\nstatic void tp_state_callback(pjsip_transport *tp,\n\t\t\t      pjsip_transport_state state,\n\t\t\t      const pjsip_transport_state_info *info)\n{\n    transport_data *tp_data;\n\n    pj_lock_acquire(tp->lock);\n\n    tp_data = (transport_data*)tp->data;\n\n    /* Notify the transport state listeners, if any. */\n    if (!tp_data || pj_list_empty(&tp_data->st_listeners)) {\n\tgoto on_return;\n    } else {\n\tpjsip_transport_state_info st_info;\n\ttp_state_listener *st_listener = tp_data->st_listeners.next;\n\n\t/* As we need to put the user data into the transport state info,\n\t * let's use a copy of transport state info.\n\t */\n\tpj_memcpy(&st_info, info, sizeof(st_info));\n\twhile (st_listener != &tp_data->st_listeners) {\n\t    st_info.user_data = st_listener->user_data;\n\t    (*st_listener->cb)(tp, state, &st_info);\n\n\t    st_listener = st_listener->next;\n\t}\n    }\n\non_return:\n    pj_lock_release(tp->lock);\n}\n\n\n/**\n * Add a listener to the specified transport for transport state notification.\n */\nPJ_DEF(pj_status_t) pjsip_transport_add_state_listener (\n\t\t\t\t\t    pjsip_transport *tp,\n\t\t\t\t\t    pjsip_tp_state_callback cb,\n\t\t\t\t\t    void *user_data,\n\t\t\t\t\t    pjsip_tp_state_listener_key **key)\n{\n    transport_data *tp_data;\n    tp_state_listener *entry;\n\n    PJ_ASSERT_RETURN(tp && cb && key, PJ_EINVAL);\n\n    pj_lock_acquire(tp->lock);\n\n    /* Init transport data, if it hasn't */\n    if (!tp->data)\n\tinit_tp_data(tp);\n\n    tp_data = (transport_data*)tp->data;\n\n    /* Init the new listener entry. Use available empty slot, if any,\n     * otherwise allocate it using the transport pool.\n     */\n    if (!pj_list_empty(&tp_data->st_listeners_empty)) {\n\tentry = tp_data->st_listeners_empty.next;\n\tpj_list_erase(entry);\n    } else {\n\tentry = PJ_POOL_ZALLOC_T(tp->pool, tp_state_listener);\n    }\n    entry->cb = cb;\n    entry->user_data = user_data;\n\n    /* Add the new listener entry to the listeners list */\n    pj_list_push_back(&tp_data->st_listeners, entry);\n\n    *key = entry;\n\n    pj_lock_release(tp->lock);\n\n    return PJ_SUCCESS;\n}\n\n/**\n * Remove a listener from the specified transport for transport state \n * notification.\n */\nPJ_DEF(pj_status_t) pjsip_transport_remove_state_listener (\n\t\t\t\t    pjsip_transport *tp,\n\t\t\t\t    pjsip_tp_state_listener_key *key,\n\t\t\t\t    const void *user_data)\n{\n    transport_data *tp_data;\n    tp_state_listener *entry;\n\n    PJ_ASSERT_RETURN(tp && key, PJ_EINVAL);\n\n    pj_lock_acquire(tp->lock);\n\n    tp_data = (transport_data*)tp->data;\n\n    /* Transport data is NULL or no registered listener? */\n    if (!tp_data || pj_list_empty(&tp_data->st_listeners)) {\n\tpj_lock_release(tp->lock);\n\treturn PJ_ENOTFOUND;\n    }\n\n    entry = (tp_state_listener*)key;\n\n    /* Validate the user data */\n    if (entry->user_data != user_data) {\n\tpj_assert(!\"Invalid transport state listener key\");\n\tpj_lock_release(tp->lock);\n\treturn PJ_EBUG;\n    }\n\n    /* Reset the entry and move it to the empty list */\n    entry->cb = NULL;\n    entry->user_data = NULL;\n    pj_list_erase(entry);\n    pj_list_push_back(&tp_data->st_listeners_empty, entry);\n\n    pj_lock_release(tp->lock);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Set callback of data dropping.\n */\nPJ_DEF(pj_status_t) pjsip_tpmgr_set_drop_data_cb(pjsip_tpmgr *mgr,\n\t\t\t\t\t\t pjsip_tp_on_rx_dropped_cb cb)\n{\n    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);\n\n    mgr->tp_drop_data_cb = cb;\n\n    return PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_transport_loop.c",
    "content": "/* $Id: sip_transport_loop.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_transport_loop.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_errno.h>\n#include <pj/pool.h>\n#include <pj/os.h>\n#include <pj/string.h>\n#include <pj/lock.h>\n#include <pj/assert.h>\n#include <pj/compat/socket.h>\n\n\n#define ADDR_LOOP\t\"128.0.0.1\"\n#define ADDR_LOOP_DGRAM\t\"129.0.0.1\"\n\n\n/** This structure describes incoming packet. */\nstruct recv_list\n{\n    PJ_DECL_LIST_MEMBER(struct recv_list);\n    pjsip_rx_data  rdata;\n};\n\n/** This structure is used to keep delayed send failure. */\nstruct send_list\n{\n    PJ_DECL_LIST_MEMBER(struct send_list);\n    pj_time_val    sent_time;\n    pj_ssize_t\t   sent;\n    pjsip_tx_data *tdata;\n    void\t  *token;\n    void\t (*callback)(pjsip_transport*, void*, pj_ssize_t);\n};\n\n/** This structure describes the loop transport. */\nstruct loop_transport\n{\n    pjsip_transport\t     base;\n    pj_pool_t\t\t    *pool;\n    pj_thread_t\t\t    *thread;\n    pj_bool_t\t\t     thread_quit_flag;\n    pj_bool_t\t\t     discard;\n    int\t\t\t     fail_mode;\n    unsigned\t\t     recv_delay;\n    unsigned\t\t     send_delay;\n    struct recv_list\t     recv_list;\n    struct send_list\t     send_list;\n};\n\n\n/* Helper function to create \"incoming\" packet */\nstatic struct recv_list *create_incoming_packet( struct loop_transport *loop,\n\t\t\t\t\t\t pjsip_tx_data *tdata )\n{\n    pj_pool_t *pool;\n    struct recv_list *pkt;\n\n    pool = pjsip_endpt_create_pool(loop->base.endpt, \"rdata\", \n\t\t\t\t   PJSIP_POOL_RDATA_LEN, \n\t\t\t\t   PJSIP_POOL_RDATA_INC+5);\n    if (!pool)\n\treturn NULL;\n\n    pkt = PJ_POOL_ZALLOC_T(pool, struct recv_list);\n\n    /* Initialize rdata. */\n    pkt->rdata.tp_info.pool = pool;\n    pkt->rdata.tp_info.transport = &loop->base;\n    \n    /* Copy the packet. */\n    pj_memcpy(pkt->rdata.pkt_info.packet, tdata->buf.start,\n\t      tdata->buf.cur - tdata->buf.start);\n    pkt->rdata.pkt_info.len = tdata->buf.cur - tdata->buf.start;\n\n    /* the source address */\n    pkt->rdata.pkt_info.src_addr.addr.sa_family = pj_AF_INET();\n\n    /* \"Source address\" info. */\n    pkt->rdata.pkt_info.src_addr_len = sizeof(pj_sockaddr_in);\n    if (loop->base.key.type == PJSIP_TRANSPORT_LOOP) {\n\tpj_ansi_strcpy(pkt->rdata.pkt_info.src_name, ADDR_LOOP);\n    } else {\n\tpj_ansi_strcpy(pkt->rdata.pkt_info.src_name, ADDR_LOOP_DGRAM);\n    }\n    pkt->rdata.pkt_info.src_port = loop->base.local_name.port;\n\n    /* When do we need to \"deliver\" this packet. */\n    pj_gettimeofday(&pkt->rdata.pkt_info.timestamp);\n    pkt->rdata.pkt_info.timestamp.msec += loop->recv_delay;\n    pj_time_val_normalize(&pkt->rdata.pkt_info.timestamp);\n\n    /* Done. */\n\n    return pkt;\n}\n\n\n/* Helper function to add pending notification callback. */\nstatic pj_status_t add_notification( struct loop_transport *loop,\n\t\t\t\t     pjsip_tx_data *tdata,\n\t\t\t\t     pj_ssize_t sent,\n\t\t\t\t     void *token,\n\t\t\t\t     void (*callback)(pjsip_transport*, \n\t\t\t\t\t\t      void*, pj_ssize_t))\n{\n    struct send_list *sent_status;\n\n    pjsip_tx_data_add_ref(tdata);\n    pj_lock_acquire(tdata->lock);\n    sent_status = PJ_POOL_ALLOC_T(tdata->pool, struct send_list);\n    pj_lock_release(tdata->lock);\n\n    sent_status->sent = sent;\n    sent_status->tdata = tdata;\n    sent_status->token = token;\n    sent_status->callback = callback;\n\n    pj_gettimeofday(&sent_status->sent_time);\n    sent_status->sent_time.msec += loop->send_delay;\n    pj_time_val_normalize(&sent_status->sent_time);\n\n    pj_lock_acquire(loop->base.lock);\n    pj_list_push_back(&loop->send_list, sent_status);\n    pj_lock_release(loop->base.lock);\n\n    return PJ_SUCCESS;\n}\n\n/* Handler for sending outgoing message; called by transport manager. */\nstatic pj_status_t loop_send_msg( pjsip_transport *tp, \n\t\t\t\t  pjsip_tx_data *tdata,\n\t\t\t\t  const pj_sockaddr_t *rem_addr,\n\t\t\t\t  int addr_len,\n\t\t\t\t  void *token,\n\t\t\t\t  pjsip_transport_callback cb)\n{\n    struct loop_transport *loop = (struct loop_transport*)tp;\n    struct recv_list *recv_pkt;\n    \n    PJ_ASSERT_RETURN(tp && (tp->key.type == PJSIP_TRANSPORT_LOOP ||\n\t             tp->key.type == PJSIP_TRANSPORT_LOOP_DGRAM), PJ_EINVAL);\n\n    PJ_UNUSED_ARG(rem_addr);\n    PJ_UNUSED_ARG(addr_len);\n\n\n    /* Need to send failure? */\n    if (loop->fail_mode) {\n\tif (loop->send_delay == 0) {\n\t    return PJ_STATUS_FROM_OS(OSERR_ECONNRESET);\n\t} else {\n\t    add_notification(loop, tdata, -PJ_STATUS_FROM_OS(OSERR_ECONNRESET),\n\t\t\t     token, cb);\n\n\t    return PJ_EPENDING;\n\t}\n    }\n\n    /* Discard any packets? */\n    if (loop->discard)\n\treturn PJ_SUCCESS;\n\n    /* Create rdata for the \"incoming\" packet. */\n    recv_pkt = create_incoming_packet(loop, tdata);\n    if (!recv_pkt)\n\treturn PJ_ENOMEM;\n\n    /* If delay is not configured, deliver this packet now! */\n    if (loop->recv_delay == 0) {\n\tpj_ssize_t size_eaten;\n\n\tsize_eaten = pjsip_tpmgr_receive_packet( loop->base.tpmgr, \n\t\t\t\t\t\t &recv_pkt->rdata);\n\tpj_assert(size_eaten == recv_pkt->rdata.pkt_info.len);\n\n\tpjsip_endpt_release_pool(loop->base.endpt, \n\t\t\t\t recv_pkt->rdata.tp_info.pool);\n\n    } else {\n\t/* Otherwise if delay is configured, add the \"packet\" to the \n\t * receive list to be processed by worker thread.\n\t */\n\tpj_lock_acquire(loop->base.lock);\n\tpj_list_push_back(&loop->recv_list, recv_pkt);\n\tpj_lock_release(loop->base.lock);\n    }\n\n    if (loop->send_delay != 0) {\n\tadd_notification(loop, tdata, tdata->buf.cur - tdata->buf.start,\n\t\t\t token, cb);\n\treturn PJ_EPENDING;\n    } else {\n\treturn PJ_SUCCESS;\n    }\n}\n\n/* Handler to destroy the transport; called by transport manager */\nstatic pj_status_t loop_destroy(pjsip_transport *tp)\n{\n    struct loop_transport *loop = (struct loop_transport*)tp;\n    \n    PJ_ASSERT_RETURN(tp && (tp->key.type == PJSIP_TRANSPORT_LOOP ||\n\t             tp->key.type == PJSIP_TRANSPORT_LOOP_DGRAM), PJ_EINVAL);\n    \n    loop->thread_quit_flag = 1;\n    /* Unlock transport mutex before joining thread. */\n    /// This raised assertion failed \"mutex->owner == pj_thread_this()\",\n    /// where mutex->owner==NULL\n    //pj_lock_release(tp->lock);\n    pj_thread_join(loop->thread);\n    pj_thread_destroy(loop->thread);\n\n    /* Clear pending send notifications. */\n    while (!pj_list_empty(&loop->send_list)) {\n\tstruct send_list *node = loop->send_list.next;\n\t/* Notify callback. */\n\tif (node->callback) {\n\t    (*node->callback)(&loop->base, node->token, -PJSIP_ESHUTDOWN);\n\t}\n\tpj_list_erase(node);\n\tpjsip_tx_data_dec_ref(node->tdata);\n    }\n\n    /* Clear \"incoming\" packets in the queue. */\n    while (!pj_list_empty(&loop->recv_list)) {\n\tstruct recv_list *node = loop->recv_list.next;\n\tpj_list_erase(node);\n\tpjsip_endpt_release_pool(loop->base.endpt,\n\t\t\t\t node->rdata.tp_info.pool);\n    }\n\n    /* Self destruct.. heheh.. */\n    pj_lock_destroy(loop->base.lock);\n    pj_atomic_destroy(loop->base.ref_cnt);\n    pjsip_endpt_release_pool(loop->base.endpt, loop->base.pool);\n\n    return PJ_SUCCESS;\n}\n\n/* Worker thread for loop transport. */\nstatic int loop_transport_worker_thread(void *arg)\n{\n    struct loop_transport *loop = (struct loop_transport*) arg;\n    struct recv_list r;\n    struct send_list s;\n\n    pj_list_init(&r);\n    pj_list_init(&s);\n\n    while (!loop->thread_quit_flag) {\n\tpj_time_val now;\n\n\tpj_thread_sleep(1);\n\tpj_gettimeofday(&now);\n\n\tpj_lock_acquire(loop->base.lock);\n\n\t/* Move expired send notification to local list. */\n\twhile (!pj_list_empty(&loop->send_list)) {\n\t    struct send_list *node = loop->send_list.next;\n\n\t    /* Break when next node time is greater than now. */\n\t    if (PJ_TIME_VAL_GTE(node->sent_time, now))\n\t\tbreak;\n\n\t    /* Delete this from the list. */\n\t    pj_list_erase(node);\n\n\t    /* Add to local list. */\n\t    pj_list_push_back(&s, node);\n\t}\n\n\t/* Move expired \"incoming\" packet to local list. */\n\twhile (!pj_list_empty(&loop->recv_list)) {\n\t    struct recv_list *node = loop->recv_list.next;\n\n\t    /* Break when next node time is greater than now. */\n\t    if (PJ_TIME_VAL_GTE(node->rdata.pkt_info.timestamp, now))\n\t\tbreak;\n\n\t    /* Delete this from the list. */\n\t    pj_list_erase(node);\n\n\t    /* Add to local list. */\n\t    pj_list_push_back(&r, node);\n\n\t}\n\n\tpj_lock_release(loop->base.lock);\n\n\t/* Process send notification and incoming packet notification\n\t * without holding down the loop's mutex.\n\t */\n\twhile (!pj_list_empty(&s)) {\n\t    struct send_list *node = s.next;\n\n\t    pj_list_erase(node);\n\n\t    /* Notify callback. */\n\t    if (node->callback) {\n\t\t(*node->callback)(&loop->base, node->token, node->sent);\n\t    }\n\n\t    /* Decrement tdata reference counter. */\n\t    pjsip_tx_data_dec_ref(node->tdata);\n\t}\n\n\t/* Process \"incoming\" packet. */\n\twhile (!pj_list_empty(&r)) {\n\t    struct recv_list *node = r.next;\n\t    pj_ssize_t size_eaten;\n\n\t    pj_list_erase(node);\n\n\t    /* Notify transport manager about the \"incoming packet\" */\n\t    size_eaten = pjsip_tpmgr_receive_packet(loop->base.tpmgr,\n\t\t\t\t\t\t    &node->rdata);\n\n\t    /* Must \"eat\" all the packets. */\n\t    pj_assert(size_eaten == node->rdata.pkt_info.len);\n\n\t    /* Done. */\n\t    pjsip_endpt_release_pool(loop->base.endpt,\n\t\t\t\t     node->rdata.tp_info.pool);\n\t}\n    }\n\n    return 0;\n}\n\n\n/* Start loop transport. */\nPJ_DEF(pj_status_t) pjsip_loop_start( pjsip_endpoint *endpt,\n\t\t\t\t      pjsip_transport **transport)\n{\n    pj_pool_t *pool;\n    struct loop_transport *loop;\n    pj_status_t status;\n\n    /* Create pool. */\n    pool = pjsip_endpt_create_pool(endpt, \"loop\", 4000, 4000);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    /* Create the loop structure. */\n    loop = PJ_POOL_ZALLOC_T(pool, struct loop_transport);\n    \n    /* Initialize transport properties. */\n    pj_ansi_snprintf(loop->base.obj_name, sizeof(loop->base.obj_name), \n\t\t     \"loop%p\", loop);\n    loop->base.pool = pool;\n    status = pj_atomic_create(pool, 0, &loop->base.ref_cnt);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n    status = pj_lock_create_recursive_mutex(pool, \"loop\", &loop->base.lock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n    loop->base.key.type = PJSIP_TRANSPORT_LOOP_DGRAM;\n    //loop->base.key.rem_addr.sa_family = pj_AF_INET();\n    loop->base.type_name = \"LOOP-DGRAM\";\n    loop->base.info = \"LOOP-DGRAM\";\n    loop->base.flag = PJSIP_TRANSPORT_DATAGRAM;\n    loop->base.local_name.host = pj_str(ADDR_LOOP_DGRAM);\n    loop->base.local_name.port = \n\tpjsip_transport_get_default_port_for_type((pjsip_transport_type_e)\n\t\t\t\t\t\t  loop->base.key.type);\n    loop->base.addr_len = sizeof(pj_sockaddr_in);\n    loop->base.dir = PJSIP_TP_DIR_NONE;\n    loop->base.endpt = endpt;\n    loop->base.tpmgr = pjsip_endpt_get_tpmgr(endpt);\n    loop->base.send_msg = &loop_send_msg;\n    loop->base.destroy = &loop_destroy;\n\n    pj_list_init(&loop->recv_list);\n    pj_list_init(&loop->send_list);\n\n    /* Create worker thread. */\n    status = pj_thread_create(pool, \"loop\", \n\t\t\t      &loop_transport_worker_thread, loop, 0, \n\t\t\t      PJ_THREAD_SUSPENDED, &loop->thread);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Register to transport manager. */\n    status = pjsip_transport_register( loop->base.tpmgr, &loop->base);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Start the thread. */\n    status = pj_thread_resume(loop->thread);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /*\n     * Done.\n     */\n\n    if (transport)\n\t*transport = &loop->base;\n\n    return PJ_SUCCESS;\n\non_error:\n    if (loop->base.lock)\n\tpj_lock_destroy(loop->base.lock);\n    if (loop->thread)\n\tpj_thread_destroy(loop->thread);\n    if (loop->base.ref_cnt)\n\tpj_atomic_destroy(loop->base.ref_cnt);\n    pjsip_endpt_release_pool(endpt, loop->pool);\n    return status;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_loop_set_discard( pjsip_transport *tp,\n\t\t\t\t\t    pj_bool_t discard,\n\t\t\t\t\t    pj_bool_t *prev_value )\n{\n    struct loop_transport *loop = (struct loop_transport*)tp;\n\n    PJ_ASSERT_RETURN(tp && (tp->key.type == PJSIP_TRANSPORT_LOOP ||\n\t             tp->key.type == PJSIP_TRANSPORT_LOOP_DGRAM), PJ_EINVAL);\n\n    if (prev_value)\n\t*prev_value = loop->discard;\n    loop->discard = discard;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_loop_set_failure( pjsip_transport *tp,\n\t\t\t\t\t    int fail_flag,\n\t\t\t\t\t    int *prev_value )\n{\n    struct loop_transport *loop = (struct loop_transport*)tp;\n\n    PJ_ASSERT_RETURN(tp && (tp->key.type == PJSIP_TRANSPORT_LOOP ||\n\t             tp->key.type == PJSIP_TRANSPORT_LOOP_DGRAM), PJ_EINVAL);\n\n    if (prev_value)\n\t*prev_value = loop->fail_mode;\n    loop->fail_mode = fail_flag;\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_loop_set_recv_delay( pjsip_transport *tp,\n\t\t\t\t\t       unsigned delay,\n\t\t\t\t\t       unsigned *prev_value)\n{\n    struct loop_transport *loop = (struct loop_transport*)tp;\n\n    PJ_ASSERT_RETURN(tp && (tp->key.type == PJSIP_TRANSPORT_LOOP ||\n\t             tp->key.type == PJSIP_TRANSPORT_LOOP_DGRAM), PJ_EINVAL);\n\n    if (prev_value)\n\t*prev_value = loop->recv_delay;\n    loop->recv_delay = delay;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjsip_loop_set_send_callback_delay( pjsip_transport *tp,\n\t\t\t\t\t\t\tunsigned delay,\n\t\t\t\t\t\t\tunsigned *prev_value)\n{\n    struct loop_transport *loop = (struct loop_transport*)tp;\n\n    PJ_ASSERT_RETURN(tp && (tp->key.type == PJSIP_TRANSPORT_LOOP ||\n\t             tp->key.type == PJSIP_TRANSPORT_LOOP_DGRAM), PJ_EINVAL);\n\n    if (prev_value)\n\t*prev_value = loop->send_delay;\n    loop->send_delay = delay;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjsip_loop_set_delay( pjsip_transport *tp, unsigned delay )\n{\n    struct loop_transport *loop = (struct loop_transport*)tp;\n\n    PJ_ASSERT_RETURN(tp && (tp->key.type == PJSIP_TRANSPORT_LOOP ||\n\t             tp->key.type == PJSIP_TRANSPORT_LOOP_DGRAM), PJ_EINVAL);\n\n    loop->recv_delay = delay;\n    loop->send_delay = delay;\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_transport_tcp.c",
    "content": "/* $Id: sip_transport_tcp.c 4506 2013-04-26 06:01:43Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_transport_tcp.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_errno.h>\n#include <pj/compat/socket.h>\n#include <pj/addr_resolv.h>\n#include <pj/activesock.h>\n#include <pj/assert.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n/* Only declare the API if PJ_HAS_TCP is true */\n#if defined(PJ_HAS_TCP) && PJ_HAS_TCP!=0\n\n\n#define THIS_FILE\t\"sip_transport_tcp.c\"\n\n#define MAX_ASYNC_CNT\t16\n#define POOL_LIS_INIT\t512\n#define POOL_LIS_INC\t512\n#define POOL_TP_INIT\t512\n#define POOL_TP_INC\t512\n\nstruct tcp_listener;\nstruct tcp_transport;\n\n\n/*\n * This is the TCP listener, which is a \"descendant\" of pjsip_tpfactory (the\n * SIP transport factory).\n */\nstruct tcp_listener\n{\n    pjsip_tpfactory\t     factory;\n    pj_bool_t\t\t     is_registered;\n    pjsip_endpoint\t    *endpt;\n    pjsip_tpmgr\t\t    *tpmgr;\n    pj_activesock_t\t    *asock;\n    pj_sockaddr\t\t     bound_addr;\n    pj_qos_type\t\t     qos_type;\n    pj_qos_params\t     qos_params;\n    pj_sockopt_params\t     sockopt_params;\n\n    /* Group lock to be used by TCP listener and ioqueue key */\n    pj_grp_lock_t\t    *grp_lock;\n};\n\n\n/*\n * This structure is used to keep delayed transmit operation in a list.\n * A delayed transmission occurs when application sends tx_data when\n * the TCP connect/establishment is still in progress. These delayed\n * transmission will be \"flushed\" once the socket is connected (either\n * successfully or with errors).\n */\nstruct delayed_tdata\n{\n    PJ_DECL_LIST_MEMBER(struct delayed_tdata);\n    pjsip_tx_data_op_key    *tdata_op_key;\n    pj_time_val              timeout;\n};\n\n\n/*\n * This structure describes the TCP transport, and it's descendant of\n * pjsip_transport.\n */\nstruct tcp_transport\n{\n    pjsip_transport\t     base;\n    pj_bool_t\t\t     is_server;\n\n    /* Do not save listener instance in the transport, because\n     * listener might be destroyed during transport's lifetime.\n     * See http://trac.pjsip.org/repos/ticket/491\n    struct tcp_listener\t    *listener;\n     */\n\n    pj_bool_t\t\t     is_registered;\n    pj_bool_t\t\t     is_closing;\n    pj_status_t\t\t     close_reason;\n    pj_sock_t\t\t     sock;\n    pj_activesock_t\t    *asock;\n    pj_bool_t\t\t     has_pending_connect;\n\n    /* Keep-alive timer. */\n    pj_timer_entry\t     ka_timer;\n    pj_time_val\t\t     last_activity;\n    pjsip_tx_data_op_key     ka_op_key;\n    pj_str_t\t\t     ka_pkt;\n\n    /* TCP transport can only have  one rdata!\n     * Otherwise chunks of incoming PDU may be received on different\n     * buffer.\n     */\n    pjsip_rx_data\t     rdata;\n\n    /* Pending transmission list. */\n    struct delayed_tdata     delayed_list;\n\n    /* Group lock to be used by TCP transport and ioqueue key */\n    pj_grp_lock_t\t    *grp_lock;\n};\n\n\n/****************************************************************************\n * PROTOTYPES\n */\n\n/* This callback is called when pending accept() operation completes. */\nstatic pj_bool_t on_accept_complete(pj_activesock_t *asock,\n\t\t\t\t    pj_sock_t newsock,\n\t\t\t\t    const pj_sockaddr_t *src_addr,\n\t\t\t\t    int src_addr_len);\n\n/* This callback is called by transport manager to destroy listener */\nstatic pj_status_t lis_destroy(pjsip_tpfactory *factory);\n\n/* Clean up listener resources (group lock handler) */\nstatic void lis_on_destroy(void *arg);\n\n/* This callback is called by transport manager to create transport */\nstatic pj_status_t lis_create_transport(pjsip_tpfactory *factory,\n\t\t\t\t\tpjsip_tpmgr *mgr,\n\t\t\t\t\tpjsip_endpoint *endpt,\n\t\t\t\t\tconst pj_sockaddr *rem_addr,\n\t\t\t\t\tint addr_len,\n\t\t\t\t\tpjsip_transport **transport);\n\n/* Common function to create and initialize transport */\nstatic pj_status_t tcp_create(struct tcp_listener *listener,\n\t\t\t      pj_pool_t *pool,\n\t\t\t      pj_sock_t sock, pj_bool_t is_server,\n\t\t\t      const pj_sockaddr *local,\n\t\t\t      const pj_sockaddr *remote,\n\t\t\t      struct tcp_transport **p_tcp);\n\n\nstatic void tcp_perror(const char *sender, const char *title,\n\t\t       pj_status_t status)\n{\n    char errmsg[PJ_ERR_MSG_SIZE];\n\n    pj_strerror(status, errmsg, sizeof(errmsg));\n\n    PJ_LOG(3,(sender, \"%s: %s [code=%d]\", title, errmsg, status));\n}\n\n\nstatic void sockaddr_to_host_port( pj_pool_t *pool,\n\t\t\t\t   pjsip_host_port *host_port,\n\t\t\t\t   const pj_sockaddr *addr )\n{\n    host_port->host.ptr = (char*) pj_pool_alloc(pool, PJ_INET6_ADDRSTRLEN+4);\n    pj_sockaddr_print(addr, host_port->host.ptr, PJ_INET6_ADDRSTRLEN+4, 0);\n    host_port->host.slen = pj_ansi_strlen(host_port->host.ptr);\n    host_port->port = pj_sockaddr_get_port(addr);\n}\n\n\nstatic void tcp_init_shutdown(struct tcp_transport *tcp, pj_status_t status)\n{\n    pjsip_tp_state_callback state_cb;\n\n    if (tcp->close_reason == PJ_SUCCESS)\n\ttcp->close_reason = status;\n\n    if (tcp->base.is_shutdown || tcp->base.is_destroying)\n\treturn;\n\n    /* Prevent immediate transport destroy by application, as transport\n     * state notification callback may be stacked and transport instance\n     * must remain valid at any point in the callback.\n     */\n    pjsip_transport_add_ref(&tcp->base);\n\n    /* Notify application of transport disconnected state */\n    state_cb = pjsip_tpmgr_get_state_cb(tcp->base.tpmgr);\n    if (state_cb) {\n\tpjsip_transport_state_info state_info;\n\n\tpj_bzero(&state_info, sizeof(state_info));\n\tstate_info.status = tcp->close_reason;\n\t(*state_cb)(&tcp->base, PJSIP_TP_STATE_DISCONNECTED, &state_info);\n    }\n\n    /* check again */\n    if (tcp->base.is_shutdown || tcp->base.is_destroying) {\n        pjsip_transport_dec_ref(&tcp->base);\n\treturn;\n    }\n\n    /* We can not destroy the transport since high level objects may\n     * still keep reference to this transport. So we can only \n     * instruct transport manager to gracefully start the shutdown\n     * procedure for this transport.\n     */\n    pjsip_transport_shutdown(&tcp->base);\n\n    /* Now, it is ok to destroy the transport. */\n    pjsip_transport_dec_ref(&tcp->base);\n}\n\n\n/*\n * Initialize pjsip_tcp_transport_cfg structure with default values.\n */\nPJ_DEF(void) pjsip_tcp_transport_cfg_default(pjsip_tcp_transport_cfg *cfg,\n\t\t\t\t\t     int af)\n{\n    pj_bzero(cfg, sizeof(*cfg));\n    cfg->af = af;\n    pj_sockaddr_init(cfg->af, &cfg->bind_addr, NULL, 0);\n    cfg->async_cnt = 1;\n    cfg->reuse_addr = PJSIP_TCP_TRANSPORT_REUSEADDR;\n}\n\n\n/****************************************************************************\n * The TCP listener/transport factory.\n */\n\n/*\n * This is the public API to create, initialize, register, and start the\n * TCP listener.\n */\nPJ_DEF(pj_status_t) pjsip_tcp_transport_start3(\n\t\t\t\t\tpjsip_endpoint *endpt,\n\t\t\t\t\tconst pjsip_tcp_transport_cfg *cfg,\n\t\t\t\t\tpjsip_tpfactory **p_factory\n\t\t\t\t\t)\n{\n    pj_pool_t *pool;\n    pj_sock_t sock = PJ_INVALID_SOCKET;\n    struct tcp_listener *listener;\n    pj_activesock_cfg asock_cfg;\n    pj_activesock_cb listener_cb;\n    pj_sockaddr *listener_addr;\n    int addr_len;\n    pj_bool_t has_listener = PJ_FALSE;\n    pj_status_t status;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(endpt && cfg->async_cnt, PJ_EINVAL);\n\n    /* Verify that address given in a_name (if any) is valid */\n    if (cfg->addr_name.host.slen) {\n\tpj_sockaddr tmp;\n\n\tstatus = pj_sockaddr_init(cfg->af, &tmp, &cfg->addr_name.host, \n\t\t\t\t  (pj_uint16_t)cfg->addr_name.port);\n\tif (status != PJ_SUCCESS || !pj_sockaddr_has_addr(&tmp) ||\n\t    (cfg->af==pj_AF_INET() && \n\t     tmp.ipv4.sin_addr.s_addr==PJ_INADDR_NONE)) \n\t{\n\t    /* Invalid address */\n\t    return PJ_EINVAL;\n\t}\n    }\n\n    pool = pjsip_endpt_create_pool(endpt, \"tcptp\", POOL_LIS_INIT, \n\t\t\t\t   POOL_LIS_INC);\n    PJ_ASSERT_RETURN(pool, PJ_ENOMEM);\n\n\n    listener = PJ_POOL_ZALLOC_T(pool, struct tcp_listener);\n    listener->factory.pool = pool;\n    listener->factory.type = cfg->af==pj_AF_INET() ? PJSIP_TRANSPORT_TCP :\n\t\t\t\t\t\t     PJSIP_TRANSPORT_TCP6;\n    listener->factory.type_name = (char*)\n\t\tpjsip_transport_get_type_name(listener->factory.type);\n    listener->factory.flag = \n\tpjsip_transport_get_flag_from_type(listener->factory.type);\n    listener->qos_type = cfg->qos_type;\n    pj_memcpy(&listener->qos_params, &cfg->qos_params,\n\t      sizeof(cfg->qos_params));\n    pj_memcpy(&listener->sockopt_params, &cfg->sockopt_params,\n\t      sizeof(cfg->sockopt_params));\n\n    pj_ansi_strcpy(listener->factory.obj_name, \"tcptp\");\n    if (listener->factory.type==PJSIP_TRANSPORT_TCP6)\n\tpj_ansi_strcat(listener->factory.obj_name, \"6\");\n\n    status = pj_lock_create_recursive_mutex(pool, listener->factory.obj_name,\n\t\t\t\t\t    &listener->factory.lock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n#if !(defined(PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER) && \\\n      PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER != 0)\n\n    /* Create socket */\n    status = pj_sock_socket(cfg->af, pj_SOCK_STREAM(), 0, &sock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Apply QoS, if specified */\n    status = pj_sock_apply_qos2(sock, cfg->qos_type, &cfg->qos_params, \n\t\t\t\t2, listener->factory.obj_name, \n\t\t\t\t\"SIP TCP listener socket\");\n\n    /* Apply SO_REUSEADDR */\n    if (cfg->reuse_addr) {\n\tint enabled = 1;\n\tstatus = pj_sock_setsockopt(sock, pj_SOL_SOCKET(), pj_SO_REUSEADDR(),\n\t\t\t\t    &enabled, sizeof(enabled));\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(listener->factory.obj_name, status,\n\t\t         \"Warning: error applying SO_REUSEADDR\"));\n\t}\n    }\n\n    /* Apply socket options, if specified */\n    if (cfg->sockopt_params.cnt)\n\tstatus = pj_sock_setsockopt_params(sock, &cfg->sockopt_params);\n\n#else\n    PJ_UNUSED_ARG(addr_len);\n#endif\n\n    /* Bind address may be different than factory.local_addr because\n     * factory.local_addr will be resolved below.\n     */\n    pj_sockaddr_cp(&listener->bound_addr, &cfg->bind_addr);\n\n    /* Bind socket */\n    listener_addr = &listener->factory.local_addr;\n    pj_sockaddr_cp(listener_addr, &cfg->bind_addr);\n\n#if !(defined(PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER) && \\\n      PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER != 0)\n\n    status = pj_sock_bind(sock, listener_addr, \n\t\t\t  pj_sockaddr_get_len(listener_addr));\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Retrieve the bound address */\n    addr_len = pj_sockaddr_get_len(listener_addr);\n    status = pj_sock_getsockname(sock, listener_addr, &addr_len);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n#endif\n\n    /* If published host/IP is specified, then use that address as the\n     * listener advertised address.\n     */\n    if (cfg->addr_name.host.slen) {\n\t/* Copy the address */\n\tlistener->factory.addr_name = cfg->addr_name;\n\tpj_strdup(listener->factory.pool, &listener->factory.addr_name.host, \n\t\t  &cfg->addr_name.host);\n\tlistener->factory.addr_name.port = cfg->addr_name.port;\n\n    } else {\n\t/* No published address is given, use the bound address */\n\n\t/* If the address returns 0.0.0.0, use the default\n\t * interface address as the transport's address.\n\t */\n\tif (!pj_sockaddr_has_addr(listener_addr)) {\n\t    pj_sockaddr hostip;\n\n\t    status = pj_gethostip(listener->bound_addr.addr.sa_family,\n\t                          &hostip);\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_error;\n\n\t    pj_sockaddr_copy_addr(listener_addr, &hostip);\n\t}\n\n\t/* Save the address name */\n\tsockaddr_to_host_port(listener->factory.pool, \n\t\t\t      &listener->factory.addr_name, \n\t\t\t      listener_addr);\n    }\n\n    /* If port is zero, get the bound port */\n    if (listener->factory.addr_name.port == 0) {\n\tlistener->factory.addr_name.port = pj_sockaddr_get_port(listener_addr);\n    }\n\n    pj_ansi_snprintf(listener->factory.obj_name, \n\t\t     sizeof(listener->factory.obj_name),\n\t\t     \"tcptp:%d\",  listener->factory.addr_name.port);\n\n\n#if !(defined(PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER) && \\\n      PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER != 0)\n\n    /* Start listening to the address */\n    status = pj_sock_listen(sock, PJSIP_TCP_TRANSPORT_BACKLOG);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n\n    /* Create active socket */\n    pj_activesock_cfg_default(&asock_cfg);\n    if (cfg->async_cnt > MAX_ASYNC_CNT) \n\tasock_cfg.async_cnt = MAX_ASYNC_CNT;\n    else\n\tasock_cfg.async_cnt = cfg->async_cnt;\n\n#endif\n\n    /* Create group lock */\n    status = pj_grp_lock_create(pool, NULL, &listener->grp_lock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_grp_lock_add_ref(listener->grp_lock);\n    pj_grp_lock_add_handler(listener->grp_lock, pool, listener,\n\t\t\t    &lis_on_destroy);\n\n    asock_cfg.grp_lock = listener->grp_lock;\n\n    pj_bzero(&listener_cb, sizeof(listener_cb));\n    listener_cb.on_accept_complete = &on_accept_complete;\n\n#if !(defined(PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER) && \\\n      PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER != 0)\n\n    status = pj_activesock_create(pool, sock, pj_SOCK_STREAM(), &asock_cfg,\n\t\t\t\t  pjsip_endpt_get_ioqueue(endpt), \n\t\t\t\t  &listener_cb, listener,\n\t\t\t\t  &listener->asock);\n\n#endif\n\n    /* Register to transport manager */\n    listener->endpt = endpt;\n    listener->tpmgr = pjsip_endpt_get_tpmgr(endpt);\n    listener->factory.create_transport = lis_create_transport;\n    listener->factory.destroy = lis_destroy;\n    listener->is_registered = PJ_TRUE;\n    status = pjsip_tpmgr_register_tpfactory(listener->tpmgr,\n\t\t\t\t\t    &listener->factory);\n    if (status != PJ_SUCCESS) {\n\tlistener->is_registered = PJ_FALSE;\n\tgoto on_error;\n    }\n\n#if !(defined(PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER) && \\\n      PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER != 0)\n\n    /* Start pending accept() operations */\n    status = pj_activesock_start_accept(listener->asock, pool);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\t\n    has_listener = PJ_TRUE;\n\n#endif\n\n    if (has_listener) {\n        PJ_LOG(4,(listener->factory.obj_name, \n\t         \"SIP TCP listener ready for incoming connections at %.*s:%d\",\n\t         (int)listener->factory.addr_name.host.slen,\n\t         listener->factory.addr_name.host.ptr,\n\t         listener->factory.addr_name.port));\n    } else {\n\tPJ_LOG(4,(listener->factory.obj_name, \"SIP TCP is ready \"\n\t\t  \"(client only)\"));    \n    }\n\n    /* Return the pointer to user */\n    if (p_factory) *p_factory = &listener->factory;\n\n    return PJ_SUCCESS;\n\non_error:\n    if (listener->asock==NULL && sock!=PJ_INVALID_SOCKET)\n\tpj_sock_close(sock);\n    lis_destroy(&listener->factory);\n    return status;\n}\n\n\n/*\n * This is the public API to create, initialize, register, and start the\n * TCP listener.\n */\nPJ_DEF(pj_status_t) pjsip_tcp_transport_start2(pjsip_endpoint *endpt,\n\t\t\t\t\t       const pj_sockaddr_in *local,\n\t\t\t\t\t       const pjsip_host_port *a_name,\n\t\t\t\t\t       unsigned async_cnt,\n\t\t\t\t\t       pjsip_tpfactory **p_factory)\n{\n    pjsip_tcp_transport_cfg cfg;\n\n    pjsip_tcp_transport_cfg_default(&cfg, pj_AF_INET());\n\n    if (local)\n\tpj_sockaddr_cp(&cfg.bind_addr, local);\n    else\n\tpj_sockaddr_init(cfg.af, &cfg.bind_addr, NULL, 0);\n\n    if (a_name)\n\tpj_memcpy(&cfg.addr_name, a_name, sizeof(*a_name));\n\n    if (async_cnt)\n\tcfg.async_cnt = async_cnt;\n\n    return pjsip_tcp_transport_start3(endpt, &cfg, p_factory);\n}\n\n\n/*\n * This is the public API to create, initialize, register, and start the\n * TCP listener.\n */\nPJ_DEF(pj_status_t) pjsip_tcp_transport_start( pjsip_endpoint *endpt,\n\t\t\t\t\t       const pj_sockaddr_in *local,\n\t\t\t\t\t       unsigned async_cnt,\n\t\t\t\t\t       pjsip_tpfactory **p_factory)\n{\n    return pjsip_tcp_transport_start2(endpt, local, NULL, async_cnt, p_factory);\n}\n\n\n/* Clean up listener resources */\nstatic void lis_on_destroy(void *arg)\n{\n    struct tcp_listener *listener = (struct tcp_listener *)arg;\n\n    if (listener->factory.lock) {\n\tpj_lock_destroy(listener->factory.lock);\n\tlistener->factory.lock = NULL;\n    }\n\n    if (listener->factory.pool) {\n\tpj_pool_t *pool = listener->factory.pool;\n\n\tPJ_LOG(4,(listener->factory.obj_name,  \"SIP TCP transport destroyed\"));\n\n\tlistener->factory.pool = NULL;\n\tpj_pool_release(pool);\n    }\n}\n\n\n/* This callback is called by transport manager to destroy listener */\nstatic pj_status_t lis_destroy(pjsip_tpfactory *factory)\n{\n    struct tcp_listener *listener = (struct tcp_listener *)factory;\n\n    if (listener->is_registered) {\n\tpjsip_tpmgr_unregister_tpfactory(listener->tpmgr, &listener->factory);\n\tlistener->is_registered = PJ_FALSE;\n    }\n\n    if (listener->asock) {\n\tpj_activesock_close(listener->asock);\n\tlistener->asock = NULL;\n    }\n\n    if (listener->grp_lock) {\n\tpj_grp_lock_t *grp_lock = listener->grp_lock;\n\tlistener->grp_lock = NULL;\n\tpj_grp_lock_dec_ref(grp_lock);\n\t/* Listener may have been deleted at this point */\n    } else {\n\tlis_on_destroy(listener);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/***************************************************************************/\n/*\n * TCP Transport\n */\n\n/*\n * Prototypes.\n */\n/* Called by transport manager to send message */\nstatic pj_status_t tcp_send_msg(pjsip_transport *transport, \n\t\t\t\tpjsip_tx_data *tdata,\n\t\t\t\tconst pj_sockaddr_t *rem_addr,\n\t\t\t\tint addr_len,\n\t\t\t\tvoid *token,\n\t\t\t\tpjsip_transport_callback callback);\n\n/* Called by transport manager to shutdown */\nstatic pj_status_t tcp_shutdown(pjsip_transport *transport);\n\n/* Called by transport manager to destroy transport */\nstatic pj_status_t tcp_destroy_transport(pjsip_transport *transport);\n\n/* Utility to destroy transport */\nstatic pj_status_t tcp_destroy(pjsip_transport *transport,\n\t\t\t       pj_status_t reason);\n\n/* Callback on incoming data */\nstatic pj_bool_t on_data_read(pj_activesock_t *asock,\n\t\t\t      void *data,\n\t\t\t      pj_size_t size,\n\t\t\t      pj_status_t status,\n\t\t\t      pj_size_t *remainder);\n\n/* Callback when packet is sent */\nstatic pj_bool_t on_data_sent(pj_activesock_t *asock,\n\t\t\t      pj_ioqueue_op_key_t *send_key,\n\t\t\t      pj_ssize_t sent);\n\n/* Callback when connect completes */\nstatic pj_bool_t on_connect_complete(pj_activesock_t *asock,\n\t\t\t\t     pj_status_t status);\n\n/* TCP keep-alive timer callback */\nstatic void tcp_keep_alive_timer(pj_timer_heap_t *th, pj_timer_entry *e);\n\n/* Clean up TCP resources */\nstatic void tcp_on_destroy(void *arg);\n\n/*\n * Common function to create TCP transport, called when pending accept() and\n * pending connect() complete.\n */\nstatic pj_status_t tcp_create( struct tcp_listener *listener,\n\t\t\t       pj_pool_t *pool,\n\t\t\t       pj_sock_t sock, pj_bool_t is_server,\n\t\t\t       const pj_sockaddr *local,\n\t\t\t       const pj_sockaddr *remote,\n\t\t\t       struct tcp_transport **p_tcp)\n{\n    struct tcp_transport *tcp;\n    pj_ioqueue_t *ioqueue;\n    pj_activesock_cfg asock_cfg;\n    pj_activesock_cb tcp_callback;\n    const pj_str_t ka_pkt = PJSIP_TCP_KEEP_ALIVE_DATA;\n    char print_addr[PJ_INET6_ADDRSTRLEN+10];\n    pj_status_t status;\n    \n\n    PJ_ASSERT_RETURN(sock != PJ_INVALID_SOCKET, PJ_EINVAL);\n\n\n    if (pool == NULL) {\n\tpool = pjsip_endpt_create_pool(listener->endpt, \"tcp\",\n\t\t\t\t       POOL_TP_INIT, POOL_TP_INC);\n\tPJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n    }    \n\n    /*\n     * Create and initialize basic transport structure.\n     */\n    tcp = PJ_POOL_ZALLOC_T(pool, struct tcp_transport);\n    tcp->is_server = is_server;\n    tcp->sock = sock;\n    /*tcp->listener = listener;*/\n    pj_list_init(&tcp->delayed_list);\n    tcp->base.pool = pool;\n\n    pj_ansi_snprintf(tcp->base.obj_name, PJ_MAX_OBJ_NAME, \n\t\t     (is_server ? \"tcps%p\" :\"tcpc%p\"), tcp);\n\n    status = pj_atomic_create(pool, 0, &tcp->base.ref_cnt);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    status = pj_lock_create_recursive_mutex(pool, \"tcp\", &tcp->base.lock);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    tcp->base.key.type = listener->factory.type;\n    pj_sockaddr_cp(&tcp->base.key.rem_addr, remote);\n    tcp->base.type_name = (char*)pjsip_transport_get_type_name(\n\t\t\t\t(pjsip_transport_type_e)tcp->base.key.type);\n    tcp->base.flag = pjsip_transport_get_flag_from_type(\n\t\t\t\t(pjsip_transport_type_e)tcp->base.key.type);\n\n    tcp->base.info = (char*) pj_pool_alloc(pool, 64);\n    pj_ansi_snprintf(tcp->base.info, 64, \"%s to %s\",\n                     tcp->base.type_name,\n                     pj_sockaddr_print(remote, print_addr,\n                                       sizeof(print_addr), 3));\n\n    tcp->base.addr_len = pj_sockaddr_get_len(remote);\n    pj_sockaddr_cp(&tcp->base.local_addr, local);\n    sockaddr_to_host_port(pool, &tcp->base.local_name, local);\n    sockaddr_to_host_port(pool, &tcp->base.remote_name, remote);\n    tcp->base.dir = is_server? PJSIP_TP_DIR_INCOMING : PJSIP_TP_DIR_OUTGOING;\n\n    tcp->base.endpt = listener->endpt;\n    tcp->base.tpmgr = listener->tpmgr;\n    tcp->base.send_msg = &tcp_send_msg;\n    tcp->base.do_shutdown = &tcp_shutdown;\n    tcp->base.destroy = &tcp_destroy_transport;\n\n    /* Create group lock */\n    status = pj_grp_lock_create(pool, NULL, &tcp->grp_lock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    pj_grp_lock_add_ref(tcp->grp_lock);\n    pj_grp_lock_add_handler(tcp->grp_lock, pool, tcp, &tcp_on_destroy);\n\n    /* Create active socket */\n    pj_activesock_cfg_default(&asock_cfg);\n    asock_cfg.async_cnt = 1;\n    asock_cfg.grp_lock = tcp->grp_lock;\n\n    pj_bzero(&tcp_callback, sizeof(tcp_callback));\n    tcp_callback.on_data_read = &on_data_read;\n    tcp_callback.on_data_sent = &on_data_sent;\n    tcp_callback.on_connect_complete = &on_connect_complete;\n\n    ioqueue = pjsip_endpt_get_ioqueue(listener->endpt);\n    status = pj_activesock_create(pool, sock, pj_SOCK_STREAM(), &asock_cfg,\n\t\t\t\t  ioqueue, &tcp_callback, tcp, &tcp->asock);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    /* Register transport to transport manager */\n    status = pjsip_transport_register(listener->tpmgr, &tcp->base);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    tcp->is_registered = PJ_TRUE;\n\n    /* Initialize keep-alive timer */\n    tcp->ka_timer.user_data = (void*)tcp;\n    tcp->ka_timer.cb = &tcp_keep_alive_timer;\n    pj_ioqueue_op_key_init(&tcp->ka_op_key.key, sizeof(pj_ioqueue_op_key_t));\n    pj_strdup(tcp->base.pool, &tcp->ka_pkt, &ka_pkt);\n\n    /* Done setting up basic transport. */\n    *p_tcp = tcp;\n\n    PJ_LOG(4,(tcp->base.obj_name, \"TCP %s transport created\",\n\t      (tcp->is_server ? \"server\" : \"client\")));\n\n    return PJ_SUCCESS;\n\non_error:\n    tcp_destroy(&tcp->base, status);\n    return status;\n}\n\n\n/* Flush all delayed transmision once the socket is connected. */\nstatic void tcp_flush_pending_tx(struct tcp_transport *tcp)\n{\n    pj_time_val now;\n\n    pj_gettickcount(&now);\n    pj_lock_acquire(tcp->base.lock);\n    while (!pj_list_empty(&tcp->delayed_list)) {\n\tstruct delayed_tdata *pending_tx;\n\tpjsip_tx_data *tdata;\n\tpj_ioqueue_op_key_t *op_key;\n\tpj_ssize_t size;\n\tpj_status_t status;\n\n\tpending_tx = tcp->delayed_list.next;\n\tpj_list_erase(pending_tx);\n\n\ttdata = pending_tx->tdata_op_key->tdata;\n\top_key = (pj_ioqueue_op_key_t*)pending_tx->tdata_op_key;\n\n        if (pending_tx->timeout.sec > 0 &&\n            PJ_TIME_VAL_GT(now, pending_tx->timeout))\n        {\n            continue;\n        }\n\n\t/* send! */\n\tsize = tdata->buf.cur - tdata->buf.start;\n\tstatus = pj_activesock_send(tcp->asock, op_key, tdata->buf.start, \n\t\t\t\t    &size, 0);\n\tif (status != PJ_EPENDING) {\n            pj_lock_release(tcp->base.lock);\n\t    on_data_sent(tcp->asock, op_key, size);\n            pj_lock_acquire(tcp->base.lock);\n\t}\n\n    }\n    pj_lock_release(tcp->base.lock);\n}\n\n\n/* Called by transport manager to destroy transport */\nstatic pj_status_t tcp_destroy_transport(pjsip_transport *transport)\n{\n    struct tcp_transport *tcp = (struct tcp_transport*)transport;\n\n    /* Transport would have been unregistered by now since this callback\n     * is called by transport manager.\n     */\n    tcp->is_registered = PJ_FALSE;\n\n    return tcp_destroy(transport, tcp->close_reason);\n}\n\n\n/* Destroy TCP transport */\nstatic pj_status_t tcp_destroy(pjsip_transport *transport, \n\t\t\t       pj_status_t reason)\n{\n    struct tcp_transport *tcp = (struct tcp_transport*)transport;\n\n    if (tcp->close_reason == 0)\n\ttcp->close_reason = reason;\n\n    if (tcp->is_registered) {\n\ttcp->is_registered = PJ_FALSE;\n\tpjsip_transport_destroy(transport);\n\n\t/* pjsip_transport_destroy will recursively call this function\n\t * again.\n\t */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Mark transport as closing */\n    tcp->is_closing = PJ_TRUE;\n\n    /* Stop keep-alive timer. */\n    if (tcp->ka_timer.id) {\n\tpjsip_endpt_cancel_timer(tcp->base.endpt, &tcp->ka_timer);\n\ttcp->ka_timer.id = PJ_FALSE;\n    }\n\n    /* Cancel all delayed transmits */\n    while (!pj_list_empty(&tcp->delayed_list)) {\n\tstruct delayed_tdata *pending_tx;\n\tpj_ioqueue_op_key_t *op_key;\n\n\tpending_tx = tcp->delayed_list.next;\n\tpj_list_erase(pending_tx);\n\n\top_key = (pj_ioqueue_op_key_t*)pending_tx->tdata_op_key;\n\n\ton_data_sent(tcp->asock, op_key, -reason);\n    }\n\n    if (tcp->asock) {\n\tpj_activesock_close(tcp->asock);\n\ttcp->asock = NULL;\n\ttcp->sock = PJ_INVALID_SOCKET;\n    } else if (tcp->sock != PJ_INVALID_SOCKET) {\n\tpj_sock_close(tcp->sock);\n\ttcp->sock = PJ_INVALID_SOCKET;\n    }\n\n    if (tcp->grp_lock) {\n\tpj_grp_lock_t *grp_lock = tcp->grp_lock;\n\ttcp->grp_lock = NULL;\n\tpj_grp_lock_dec_ref(grp_lock);\n\t/* Transport may have been deleted at this point */\n    } else {\n\ttcp_on_destroy(tcp);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/* Clean up TCP resources */\nstatic void tcp_on_destroy(void *arg)\n{\n    struct tcp_transport *tcp = (struct tcp_transport*)arg;\n\n    if (tcp->base.lock) {\n\tpj_lock_destroy(tcp->base.lock);\n\ttcp->base.lock = NULL;\n    }\n\n    if (tcp->base.ref_cnt) {\n\tpj_atomic_destroy(tcp->base.ref_cnt);\n\ttcp->base.ref_cnt = NULL;\n    }\n\n    if (tcp->rdata.tp_info.pool) {\n\tpj_pool_release(tcp->rdata.tp_info.pool);\n\ttcp->rdata.tp_info.pool = NULL;\n    }\n\n    if (tcp->base.pool) {\n\tpj_pool_t *pool;\n\n\tif (tcp->close_reason != PJ_SUCCESS) {\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\n\t    pj_strerror(tcp->close_reason, errmsg, sizeof(errmsg));\n\t    PJ_LOG(4,(tcp->base.obj_name, \n\t\t      \"TCP transport destroyed with reason %d: %s\", \n\t\t      tcp->close_reason, errmsg));\n\n\t} else {\n\n\t    PJ_LOG(4,(tcp->base.obj_name, \n\t\t      \"TCP transport destroyed normally\"));\n\n\t}\n\n\tpool = tcp->base.pool;\n\ttcp->base.pool = NULL;\n\tpj_pool_release(pool);\n    }\n}\n\n/*\n * This utility function creates receive data buffers and start\n * asynchronous recv() operations from the socket. It is called after\n * accept() or connect() operation complete.\n */\nstatic pj_status_t tcp_start_read(struct tcp_transport *tcp)\n{\n    pj_pool_t *pool;\n    pj_uint32_t size;\n    pj_sockaddr *rem_addr;\n    void *readbuf[1];\n    pj_status_t status;\n\n    /* Init rdata */\n    pool = pjsip_endpt_create_pool(tcp->base.endpt,\n\t\t\t\t   \"rtd%p\",\n\t\t\t\t   PJSIP_POOL_RDATA_LEN,\n\t\t\t\t   PJSIP_POOL_RDATA_INC);\n    if (!pool) {\n\ttcp_perror(tcp->base.obj_name, \"Unable to create pool\", PJ_ENOMEM);\n\treturn PJ_ENOMEM;\n    }\n\n    tcp->rdata.tp_info.pool = pool;\n\n    tcp->rdata.tp_info.transport = &tcp->base;\n    tcp->rdata.tp_info.tp_data = tcp;\n    tcp->rdata.tp_info.op_key.rdata = &tcp->rdata;\n    pj_ioqueue_op_key_init(&tcp->rdata.tp_info.op_key.op_key, \n\t\t\t   sizeof(pj_ioqueue_op_key_t));\n\n    tcp->rdata.pkt_info.src_addr = tcp->base.key.rem_addr;\n    tcp->rdata.pkt_info.src_addr_len = sizeof(tcp->rdata.pkt_info.src_addr);\n    rem_addr = &tcp->base.key.rem_addr;\n    pj_sockaddr_print(rem_addr, tcp->rdata.pkt_info.src_name,\n                      sizeof(tcp->rdata.pkt_info.src_name), 0);\n    tcp->rdata.pkt_info.src_port = pj_sockaddr_get_port(rem_addr);\n\n    size = sizeof(tcp->rdata.pkt_info.packet);\n    readbuf[0] = tcp->rdata.pkt_info.packet;\n    status = pj_activesock_start_read2(tcp->asock, tcp->base.pool, size,\n\t\t\t\t       readbuf, 0);\n    if (status != PJ_SUCCESS && status != PJ_EPENDING) {\n\tPJ_LOG(4, (tcp->base.obj_name, \n\t\t   \"pj_activesock_start_read() error, status=%d\", \n\t\t   status));\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* This callback is called by transport manager for the TCP factory\n * to create outgoing transport to the specified destination.\n */\nstatic pj_status_t lis_create_transport(pjsip_tpfactory *factory,\n\t\t\t\t\tpjsip_tpmgr *mgr,\n\t\t\t\t\tpjsip_endpoint *endpt,\n\t\t\t\t\tconst pj_sockaddr *rem_addr,\n\t\t\t\t\tint addr_len,\n\t\t\t\t\tpjsip_transport **p_transport)\n{\n    struct tcp_listener *listener;\n    struct tcp_transport *tcp;\n    pj_sock_t sock;\n    pj_sockaddr local_addr;\n    pj_status_t status;\n\n    /* Sanity checks */\n    PJ_ASSERT_RETURN(factory && mgr && endpt && rem_addr &&\n\t\t     addr_len && p_transport, PJ_EINVAL);\n\n    /* Check that address is a sockaddr_in or sockaddr_in6*/\n    PJ_ASSERT_RETURN((rem_addr->addr.sa_family == pj_AF_INET() &&\n\t\t      addr_len == sizeof(pj_sockaddr_in)) ||\n\t\t     (rem_addr->addr.sa_family == pj_AF_INET6() &&\n\t\t      addr_len == sizeof(pj_sockaddr_in6)), PJ_EINVAL);\n\n\n    listener = (struct tcp_listener*)factory;\n\n    /* Create socket */\n    status = pj_sock_socket(rem_addr->addr.sa_family, pj_SOCK_STREAM(),\n                            0, &sock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Apply QoS, if specified */\n    status = pj_sock_apply_qos2(sock, listener->qos_type, \n\t\t\t\t&listener->qos_params, \n\t\t\t\t2, listener->factory.obj_name, \n\t\t\t\t\"outgoing SIP TCP socket\");\n\n    /* Apply socket options, if specified */\n    if (listener->sockopt_params.cnt)\n\tstatus = pj_sock_setsockopt_params(sock, &listener->sockopt_params);\n\n\n    /* Bind to listener's address and any port */\n    pj_bzero(&local_addr, sizeof(local_addr));\n    pj_sockaddr_cp(&local_addr, &listener->bound_addr);\n    pj_sockaddr_set_port(&local_addr, 0);\n\n    status = pj_sock_bind(sock, &local_addr,\n                          pj_sockaddr_get_len(&local_addr));\n    if (status != PJ_SUCCESS) {\n\tpj_sock_close(sock);\n\treturn status;\n    }\n\n    /* Get the local port */\n    addr_len = sizeof(local_addr);\n    status = pj_sock_getsockname(sock, &local_addr, &addr_len);\n    if (status != PJ_SUCCESS) {\n\tpj_sock_close(sock);\n\treturn status;\n    }\n\n    /* Initially set the address from the listener's address */\n    if (!pj_sockaddr_has_addr(&local_addr)) {\n\tpj_sockaddr_copy_addr(&local_addr, &listener->factory.local_addr);\n    }\n\n    /* Create the transport descriptor */\n    status = tcp_create(listener, NULL, sock, PJ_FALSE, &local_addr, \n\t\t\trem_addr, &tcp);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n\n    /* Start asynchronous connect() operation */\n    tcp->has_pending_connect = PJ_TRUE;\n    status = pj_activesock_start_connect(tcp->asock, tcp->base.pool, rem_addr,\n\t\t\t\t\t addr_len);\n    if (status == PJ_SUCCESS) {\n\ton_connect_complete(tcp->asock, PJ_SUCCESS);\n    } else if (status != PJ_EPENDING) {\n\ttcp_destroy(&tcp->base, status);\n\treturn status;\n    }\n\n    if (tcp->has_pending_connect) {\n\t/* Update (again) local address, just in case local address currently\n\t * set is different now that asynchronous connect() is started.\n\t */\n\taddr_len = sizeof(local_addr);\n\tif (pj_sock_getsockname(sock, &local_addr, &addr_len)==PJ_SUCCESS) {\n\t    pj_sockaddr *tp_addr = &tcp->base.local_addr;\n\n\t    /* Some systems (like old Win32 perhaps) may not set local address\n\t     * properly before socket is fully connected.\n\t     */\n\t    if (pj_sockaddr_cmp(tp_addr, &local_addr) &&\n                pj_sockaddr_has_addr(&local_addr) &&\n\t\tpj_sockaddr_get_port(&local_addr) != 0)\n\t    {\n\t\tpj_sockaddr_cp(tp_addr, &local_addr);\n\t\tsockaddr_to_host_port(tcp->base.pool, &tcp->base.local_name,\n\t\t\t\t      &local_addr);\n\t    }\n\t}\n\t\n\tPJ_LOG(4,(tcp->base.obj_name, \n\t\t  \"TCP transport %.*s:%d is connecting to %.*s:%d...\",\n\t\t  (int)tcp->base.local_name.host.slen,\n\t\t  tcp->base.local_name.host.ptr,\n\t\t  tcp->base.local_name.port,\n\t\t  (int)tcp->base.remote_name.host.slen,\n\t\t  tcp->base.remote_name.host.ptr,\n\t\t  tcp->base.remote_name.port));\n    }\n\n    /* Done */\n    *p_transport = &tcp->base;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * This callback is called by active socket when pending accept() operation\n * has completed.\n */\nstatic pj_bool_t on_accept_complete(pj_activesock_t *asock,\n\t\t\t\t    pj_sock_t sock,\n\t\t\t\t    const pj_sockaddr_t *src_addr,\n\t\t\t\t    int src_addr_len)\n{\n    struct tcp_listener *listener;\n    struct tcp_transport *tcp;\n    char addr[PJ_INET6_ADDRSTRLEN+10];\n    pjsip_tp_state_callback state_cb;\n    pj_sockaddr tmp_src_addr, tmp_dst_addr;\n    int addr_len;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(src_addr_len);\n\n    listener = (struct tcp_listener*) pj_activesock_get_user_data(asock);\n\n    PJ_ASSERT_RETURN(sock != PJ_INVALID_SOCKET, PJ_TRUE);\n\n    if (!listener->is_registered)\n\treturn PJ_FALSE;\n\n    PJ_LOG(4,(listener->factory.obj_name, \n\t      \"TCP listener %.*s:%d: got incoming TCP connection \"\n\t      \"from %s, sock=%d\",\n\t      (int)listener->factory.addr_name.host.slen,\n\t      listener->factory.addr_name.host.ptr,\n\t      listener->factory.addr_name.port,\n\t      pj_sockaddr_print(src_addr, addr, sizeof(addr), 3),\n\t      sock));\n\n    /* Apply QoS, if specified */\n    status = pj_sock_apply_qos2(sock, listener->qos_type, \n\t\t\t\t&listener->qos_params, \n\t\t\t\t2, listener->factory.obj_name, \n\t\t\t\t\"incoming SIP TCP socket\");\n\n    /* Apply socket options, if specified */\n    if (listener->sockopt_params.cnt)\n\tstatus = pj_sock_setsockopt_params(sock, &listener->sockopt_params);\n\n    /* tcp_create() expect pj_sockaddr, so copy src_addr to temporary var,\n     * just in case.\n     */\n    pj_bzero(&tmp_src_addr, sizeof(tmp_src_addr));\n    pj_sockaddr_cp(&tmp_src_addr, src_addr);\n\n    /* Get local address */\n    addr_len = sizeof(tmp_dst_addr);\n    status = pj_sock_getsockname(sock, &tmp_dst_addr, &addr_len);\n    if (status != PJ_SUCCESS) {\n\tpj_sockaddr_cp(&tmp_dst_addr, &listener->factory.local_addr);\n    }\n\n    /* \n     * Incoming connection!\n     * Create TCP transport for the new socket.\n     */\n    status = tcp_create( listener, NULL, sock, PJ_TRUE,\n\t\t\t &tmp_dst_addr, &tmp_src_addr, &tcp);\n    if (status == PJ_SUCCESS) {\n\tstatus = tcp_start_read(tcp);\n\tif (status != PJ_SUCCESS) {\n\t    PJ_LOG(3,(tcp->base.obj_name, \"New transport cancelled\"));\n\t    tcp_destroy(&tcp->base, status);\n\t} else {\n\t    if (tcp->base.is_shutdown || tcp->base.is_destroying) {\n\t\treturn PJ_TRUE;\n\t    }\n\t    /* Start keep-alive timer */\n\t    if (pjsip_cfg()->tcp.keep_alive_interval) {\n\t\tpj_time_val delay = { 0 };\n\t\tdelay.sec = pjsip_cfg()->tcp.keep_alive_interval;\n\t\tpjsip_endpt_schedule_timer(listener->endpt, \n\t\t\t\t\t   &tcp->ka_timer, \n\t\t\t\t\t   &delay);\n\t\ttcp->ka_timer.id = PJ_TRUE;\n\t\tpj_gettimeofday(&tcp->last_activity);\n\t    }\n\t    /* Notify application of transport state accepted */\n\t    state_cb = pjsip_tpmgr_get_state_cb(tcp->base.tpmgr);\n\t    if (state_cb) {\n\t\tpjsip_transport_state_info state_info;\n\n\t\tpj_bzero(&state_info, sizeof(state_info));\n\t\t(*state_cb)(&tcp->base, PJSIP_TP_STATE_CONNECTED, &state_info);\n\t    }\n\t}\n    }\n\n    return PJ_TRUE;\n}\n\n\n/* \n * Callback from ioqueue when packet is sent.\n */\nstatic pj_bool_t on_data_sent(pj_activesock_t *asock,\n\t\t\t      pj_ioqueue_op_key_t *op_key,\n\t\t\t      pj_ssize_t bytes_sent)\n{\n    struct tcp_transport *tcp = (struct tcp_transport*) \n    \t\t\t\tpj_activesock_get_user_data(asock);\n    pjsip_tx_data_op_key *tdata_op_key = (pjsip_tx_data_op_key*)op_key;\n\n    /* Note that op_key may be the op_key from keep-alive, thus\n     * it will not have tdata etc.\n     */\n\n    tdata_op_key->tdata = NULL;\n\n    if (tdata_op_key->callback) {\n\t/*\n\t * Notify sip_transport.c that packet has been sent.\n\t */\n\tif (bytes_sent == 0)\n\t    bytes_sent = -PJ_RETURN_OS_ERROR(OSERR_ENOTCONN);\n\n\ttdata_op_key->callback(&tcp->base, tdata_op_key->token, bytes_sent);\n\n\t/* Mark last activity time */\n\tpj_gettimeofday(&tcp->last_activity);\n\n    }\n\n    /* Check for error/closure */\n    if (bytes_sent <= 0) {\n\tpj_status_t status;\n\n\tPJ_LOG(5,(tcp->base.obj_name, \"TCP send() error, sent=%d\", \n\t\t  bytes_sent));\n\n\tstatus = (bytes_sent == 0) ? PJ_RETURN_OS_ERROR(OSERR_ENOTCONN) :\n\t\t\t\t     (pj_status_t)-bytes_sent;\n\n\ttcp_init_shutdown(tcp, status);\n\n\treturn PJ_FALSE;\n    }\n\n    return PJ_TRUE;\n}\n\n\n/* \n * This callback is called by transport manager to send SIP message \n */\nstatic pj_status_t tcp_send_msg(pjsip_transport *transport, \n\t\t\t\tpjsip_tx_data *tdata,\n\t\t\t\tconst pj_sockaddr_t *rem_addr,\n\t\t\t\tint addr_len,\n\t\t\t\tvoid *token,\n\t\t\t\tpjsip_transport_callback callback)\n{\n    struct tcp_transport *tcp = (struct tcp_transport*)transport;\n    pj_ssize_t size;\n    pj_bool_t delayed = PJ_FALSE;\n    pj_status_t status = PJ_SUCCESS;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(transport && tdata, PJ_EINVAL);\n\n    /* Check that there's no pending operation associated with the tdata */\n    PJ_ASSERT_RETURN(tdata->op_key.tdata == NULL, PJSIP_EPENDINGTX);\n    \n    /* Check the address is supported */\n    PJ_ASSERT_RETURN(rem_addr && (addr_len==sizeof(pj_sockaddr_in) ||\n\t                          addr_len==sizeof(pj_sockaddr_in6)),\n\t             PJ_EINVAL);\n\n    /* Init op key. */\n    tdata->op_key.tdata = tdata;\n    tdata->op_key.token = token;\n    tdata->op_key.callback = callback;\n\n    /* If asynchronous connect() has not completed yet, just put the\n     * transmit data in the pending transmission list since we can not\n     * use the socket yet.\n     */\n    if (tcp->has_pending_connect) {\n\n\t/*\n\t * Looks like connect() is still in progress. Check again (this time\n\t * with holding the lock) to be sure.\n\t */\n\tpj_lock_acquire(tcp->base.lock);\n\n\tif (tcp->has_pending_connect) {\n\t    struct delayed_tdata *delayed_tdata;\n\n\t    /*\n\t     * connect() is still in progress. Put the transmit data to\n\t     * the delayed list.\n             * Starting from #1583 (https://trac.pjsip.org/repos/ticket/1583),\n             * we also add timeout value for the transmit data. When the\n             * connect() is completed, the timeout value will be checked to\n             * determine whether the transmit data needs to be sent.\n\t     */\n\t    delayed_tdata = PJ_POOL_ZALLOC_T(tdata->pool, \n\t\t\t\t\t     struct delayed_tdata);\n\t    delayed_tdata->tdata_op_key = &tdata->op_key;\n            if (tdata->msg && tdata->msg->type == PJSIP_REQUEST_MSG) {\n                pj_gettickcount(&delayed_tdata->timeout);\n                delayed_tdata->timeout.msec += pjsip_cfg()->tsx.td;\n                pj_time_val_normalize(&delayed_tdata->timeout);\n            }\n\n\t    pj_list_push_back(&tcp->delayed_list, delayed_tdata);\n\t    status = PJ_EPENDING;\n\n\t    /* Prevent pj_ioqueue_send() to be called below */\n\t    delayed = PJ_TRUE;\n\t}\n\n\tpj_lock_release(tcp->base.lock);\n    } \n    \n    if (!delayed) {\n\t/*\n\t * Transport is ready to go. Send the packet to ioqueue to be\n\t * sent asynchronously.\n\t */\n\tsize = tdata->buf.cur - tdata->buf.start;\n\tstatus = pj_activesock_send(tcp->asock, \n\t\t\t\t    (pj_ioqueue_op_key_t*)&tdata->op_key,\n\t\t\t\t    tdata->buf.start, &size, 0);\n\n\tif (status != PJ_EPENDING) {\n\t    /* Not pending (could be immediate success or error) */\n\t    tdata->op_key.tdata = NULL;\n\n\t    /* Shutdown transport on closure/errors */\n\t    if (size <= 0) {\n\n\t\tPJ_LOG(5,(tcp->base.obj_name, \"TCP send() error, sent=%d\", \n\t\t\t  size));\n\n\t\tif (status == PJ_SUCCESS) \n\t\t    status = PJ_RETURN_OS_ERROR(OSERR_ENOTCONN);\n\n\t\ttcp_init_shutdown(tcp, status);\n\t    }\n\t}\n    }\n\n    return status;\n}\n\n\n/* \n * This callback is called by transport manager to shutdown transport.\n */\nstatic pj_status_t tcp_shutdown(pjsip_transport *transport)\n{\n    struct tcp_transport *tcp = (struct tcp_transport*)transport;\n    \n    /* Stop keep-alive timer. */\n    if (tcp->ka_timer.id) {\n\tpjsip_endpt_cancel_timer(tcp->base.endpt, &tcp->ka_timer);\n\ttcp->ka_timer.id = PJ_FALSE;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* \n * Callback from ioqueue that an incoming data is received from the socket.\n */\nstatic pj_bool_t on_data_read(pj_activesock_t *asock,\n\t\t\t      void *data,\n\t\t\t      pj_size_t size,\n\t\t\t      pj_status_t status,\n\t\t\t      pj_size_t *remainder)\n{\n    enum { MAX_IMMEDIATE_PACKET = 10 };\n    struct tcp_transport *tcp;\n    pjsip_rx_data *rdata;\n\n    PJ_UNUSED_ARG(data);\n\n    tcp = (struct tcp_transport*) pj_activesock_get_user_data(asock);\n    rdata = &tcp->rdata;\n\n    /* Don't do anything if transport is closing. */\n    if (tcp->is_closing) {\n\ttcp->is_closing++;\n\treturn PJ_FALSE;\n    }\n\n    /* Houston, we have packet! Report the packet to transport manager\n     * to be parsed.\n     */\n    if (status == PJ_SUCCESS) {\n\tpj_size_t size_eaten;\n\n\t/* Mark this as an activity */\n\tpj_gettimeofday(&tcp->last_activity);\n\n\tpj_assert((void*)rdata->pkt_info.packet == data);\n\n\t/* Init pkt_info part. */\n\trdata->pkt_info.len = size;\n\trdata->pkt_info.zero = 0;\n\tpj_gettimeofday(&rdata->pkt_info.timestamp);\n\n\t/* Report to transport manager.\n\t * The transport manager will tell us how many bytes of the packet\n\t * have been processed (as valid SIP message).\n\t */\n\tsize_eaten = \n\t    pjsip_tpmgr_receive_packet(rdata->tp_info.transport->tpmgr, \n\t\t\t\t       rdata);\n\n\tpj_assert(size_eaten <= (pj_size_t)rdata->pkt_info.len);\n\n\t/* Move unprocessed data to the front of the buffer */\n\t*remainder = size - size_eaten;\n\tif (*remainder > 0 && *remainder != size) {\n\t    pj_memmove(rdata->pkt_info.packet,\n\t\t       rdata->pkt_info.packet + size_eaten,\n\t\t       *remainder);\n\t}\n\n    } else {\n\n\t/* Transport is closed */\n\tPJ_LOG(4,(tcp->base.obj_name, \"TCP connection closed\"));\n\t\n\ttcp_init_shutdown(tcp, status);\n\n\treturn PJ_FALSE;\n\n    }\n\n    /* Reset pool. */\n    pj_pool_reset(rdata->tp_info.pool);\n\n    return PJ_TRUE;\n}\n\n\n/* \n * Callback from ioqueue when asynchronous connect() operation completes.\n */\nstatic pj_bool_t on_connect_complete(pj_activesock_t *asock,\n\t\t\t\t     pj_status_t status)\n{\n    struct tcp_transport *tcp;\n    pj_sockaddr addr;\n    int addrlen;\n    pjsip_tp_state_callback state_cb;\n\n    tcp = (struct tcp_transport*) pj_activesock_get_user_data(asock);\n\n    /* Mark that pending connect() operation has completed. */\n    tcp->has_pending_connect = PJ_FALSE;\n\n    /* If transport is being shutdown/destroyed, proceed as error connect.\n     * Note that it is important to notify application via on_data_sent()\n     * as otherwise the transport reference counter may never reach zero\n     * (see #1898).\n     */\n    if ((tcp->base.is_shutdown || tcp->base.is_destroying) &&\n\tstatus == PJ_SUCCESS)\n    {\n\tstatus = PJ_ECANCELLED;\n    }\n\n    /* Check connect() status */\n    if (status != PJ_SUCCESS) {\n\n\ttcp_perror(tcp->base.obj_name, \"TCP connect() error\", status);\n\n\t/* Cancel all delayed transmits */\n\twhile (!pj_list_empty(&tcp->delayed_list)) {\n\t    struct delayed_tdata *pending_tx;\n\t    pj_ioqueue_op_key_t *op_key;\n\n\t    pending_tx = tcp->delayed_list.next;\n\t    pj_list_erase(pending_tx);\n\n\t    op_key = (pj_ioqueue_op_key_t*)pending_tx->tdata_op_key;\n\n\t    on_data_sent(tcp->asock, op_key, -status);\n\t}\n\n\ttcp_init_shutdown(tcp, status);\n\treturn PJ_FALSE;\n    }\n\n    PJ_LOG(4,(tcp->base.obj_name, \n\t      \"TCP transport %.*s:%d is connected to %.*s:%d\",\n\t      (int)tcp->base.local_name.host.slen,\n\t      tcp->base.local_name.host.ptr,\n\t      tcp->base.local_name.port,\n\t      (int)tcp->base.remote_name.host.slen,\n\t      tcp->base.remote_name.host.ptr,\n\t      tcp->base.remote_name.port));\n\n\n    /* Update (again) local address, just in case local address currently\n     * set is different now that the socket is connected (could happen\n     * on some systems, like old Win32 probably?).\n     */\n    addrlen = sizeof(addr);\n    if (pj_sock_getsockname(tcp->sock, &addr, &addrlen)==PJ_SUCCESS) {\n\tpj_sockaddr *tp_addr = &tcp->base.local_addr;\n\n\tif (pj_sockaddr_has_addr(&addr) &&\n\t    pj_sockaddr_cmp(&addr, tp_addr) != 0)\n\t{\n\t    pj_sockaddr_cp(tp_addr, &addr);\n\t    sockaddr_to_host_port(tcp->base.pool, &tcp->base.local_name,\n\t\t\t\t  tp_addr);\n\t}\n    }\n\n    /* Start pending read */\n    status = tcp_start_read(tcp);\n    if (status != PJ_SUCCESS) {\n\ttcp_init_shutdown(tcp, status);\n\treturn PJ_FALSE;\n    }\n\n    /* Notify application of transport state connected */\n    state_cb = pjsip_tpmgr_get_state_cb(tcp->base.tpmgr);\n    if (state_cb) {\n\tpjsip_transport_state_info state_info;\n\t\n\tpj_bzero(&state_info, sizeof(state_info));\n\t(*state_cb)(&tcp->base, PJSIP_TP_STATE_CONNECTED, &state_info);\n    }\n\n    /* Flush all pending send operations */\n    tcp_flush_pending_tx(tcp);\n\n    /* Start keep-alive timer */\n    if (pjsip_cfg()->tcp.keep_alive_interval) {\n\tpj_time_val delay = { 0 };\n\tdelay.sec = pjsip_cfg()->tcp.keep_alive_interval;\n\tpjsip_endpt_schedule_timer(tcp->base.endpt, &tcp->ka_timer, \n\t\t\t\t   &delay);\n\ttcp->ka_timer.id = PJ_TRUE;\n\tpj_gettimeofday(&tcp->last_activity);\n    }\n\n    return PJ_TRUE;\n}\n\n/* Transport keep-alive timer callback */\nstatic void tcp_keep_alive_timer(pj_timer_heap_t *th, pj_timer_entry *e)\n{\n    struct tcp_transport *tcp = (struct tcp_transport*) e->user_data;\n    pj_time_val delay;\n    pj_time_val now;\n    pj_ssize_t size;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(th);\n\n    tcp->ka_timer.id = PJ_TRUE;\n\n    pj_gettimeofday(&now);\n    PJ_TIME_VAL_SUB(now, tcp->last_activity);\n\n    if (now.sec > 0 && now.sec < pjsip_cfg()->tcp.keep_alive_interval) {\n\t/* There has been activity, so don't send keep-alive */\n\tdelay.sec = pjsip_cfg()->tcp.keep_alive_interval - now.sec;\n\tdelay.msec = 0;\n\n\tpjsip_endpt_schedule_timer(tcp->base.endpt, &tcp->ka_timer, \n\t\t\t\t   &delay);\n\ttcp->ka_timer.id = PJ_TRUE;\n\treturn;\n    }\n\n    PJ_LOG(5,(tcp->base.obj_name, \"Sending %d byte(s) keep-alive to %.*s:%d\", \n\t      (int)tcp->ka_pkt.slen, (int)tcp->base.remote_name.host.slen,\n\t      tcp->base.remote_name.host.ptr,\n\t      tcp->base.remote_name.port));\n\n    /* Send the data */\n    size = tcp->ka_pkt.slen;\n    status = pj_activesock_send(tcp->asock, &tcp->ka_op_key.key,\n\t\t\t\ttcp->ka_pkt.ptr, &size, 0);\n\n    if (status != PJ_SUCCESS && status != PJ_EPENDING) {\n\ttcp_perror(tcp->base.obj_name, \n\t\t   \"Error sending keep-alive packet\", status);\n\ttcp_init_shutdown(tcp, status);\n\treturn;\n    }\n\n    /* Register next keep-alive */\n    delay.sec = pjsip_cfg()->tcp.keep_alive_interval;\n    delay.msec = 0;\n\n    pjsip_endpt_schedule_timer(tcp->base.endpt, &tcp->ka_timer, \n\t\t\t       &delay);\n    tcp->ka_timer.id = PJ_TRUE;\n}\n\n\nPJ_DEF(pj_sock_t) pjsip_tcp_transport_get_socket(pjsip_transport *transport)\n{\n    struct tcp_transport *tcp = (struct tcp_transport*)transport;\n\n    PJ_ASSERT_RETURN(transport, PJ_INVALID_SOCKET);\n    return tcp->sock;\n}\n\n\n#endif\t/* PJ_HAS_TCP */\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_transport_tls.c",
    "content": "/* $Id: sip_transport_tls.c 4506 2013-04-26 06:01:43Z bennylp $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n#include <pjsip/sip_transport_tls.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_errno.h>\n#include <pj/compat/socket.h>\n#include <pj/addr_resolv.h>\n#include <pj/ssl_sock.h>\n#include <pj/assert.h>\n#include <pj/hash.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#if defined(PJSIP_HAS_TLS_TRANSPORT) && PJSIP_HAS_TLS_TRANSPORT!=0\n\n#define THIS_FILE\t\"sip_transport_tls.c\"\n\n#define MAX_ASYNC_CNT\t16\n#define POOL_LIS_INIT\t512\n#define POOL_LIS_INC\t512\n#define POOL_TP_INIT\t512\n#define POOL_TP_INC\t512\n\nstruct tls_listener;\nstruct tls_transport;\n\n/*\n * Definition of TLS/SSL transport listener, and it's descendant of\n * pjsip_tpfactory.\n */\nstruct tls_listener\n{\n    pjsip_tpfactory\t     factory;\n    pj_bool_t\t\t     is_registered;\n    pjsip_endpoint\t    *endpt;\n    pjsip_tpmgr\t\t    *tpmgr;\n    pj_ssl_sock_t\t    *ssock;\n    pj_sockaddr\t\t     bound_addr;\n    pj_ssl_cert_t\t    *cert;\n    pjsip_tls_setting\t     tls_setting;\n\n    /* Group lock to be used by TLS transport and ioqueue key */\n    pj_grp_lock_t\t    *grp_lock;\n};\n\n\n/*\n * This structure is used to keep delayed transmit operation in a list.\n * A delayed transmission occurs when application sends tx_data when\n * the TLS connect/establishment is still in progress. These delayed\n * transmission will be \"flushed\" once the socket is connected (either\n * successfully or with errors).\n */\nstruct delayed_tdata\n{\n    PJ_DECL_LIST_MEMBER(struct delayed_tdata);\n    pjsip_tx_data_op_key    *tdata_op_key;\n    pj_time_val              timeout;\n};\n\n\n/*\n * TLS/SSL transport, and it's descendant of pjsip_transport.\n */\nstruct tls_transport\n{\n    pjsip_transport\t     base;\n    pj_bool_t\t\t     is_server;\n    pj_str_t\t\t     remote_name;\n\n    pj_bool_t\t\t     is_registered;\n    pj_bool_t\t\t     is_closing;\n    pj_status_t\t\t     close_reason;\n    pj_ssl_sock_t\t    *ssock;\n    pj_bool_t\t\t     has_pending_connect;\n    pj_bool_t\t\t     verify_server;\n\n    /* Keep-alive timer. */\n    pj_timer_entry\t     ka_timer;\n    pj_time_val\t\t     last_activity;\n    pjsip_tx_data_op_key     ka_op_key;\n    pj_str_t\t\t     ka_pkt;\n\n    /* TLS transport can only have  one rdata!\n     * Otherwise chunks of incoming PDU may be received on different\n     * buffer.\n     */\n    pjsip_rx_data\t     rdata;\n\n    /* Pending transmission list. */\n    struct delayed_tdata     delayed_list;\n\n    /* Group lock to be used by TLS transport and ioqueue key */\n    pj_grp_lock_t\t    *grp_lock;\n};\n\n\n/****************************************************************************\n * PROTOTYPES\n */\n\n/* This callback is called when pending accept() operation completes. */\nstatic pj_bool_t on_accept_complete(pj_ssl_sock_t *ssock,\n\t\t\t\t    pj_ssl_sock_t *new_ssock,\n\t\t\t\t    const pj_sockaddr_t *src_addr,\n\t\t\t\t    int src_addr_len);\n\n/* Callback on incoming data */\nstatic pj_bool_t on_data_read(pj_ssl_sock_t *ssock,\n\t\t\t      void *data,\n\t\t\t      pj_size_t size,\n\t\t\t      pj_status_t status,\n\t\t\t      pj_size_t *remainder);\n\n/* Callback when packet is sent */\nstatic pj_bool_t on_data_sent(pj_ssl_sock_t *ssock,\n\t\t\t      pj_ioqueue_op_key_t *send_key,\n\t\t\t      pj_ssize_t sent);\n\n/* This callback is called by transport manager to destroy listener */\nstatic pj_status_t lis_destroy(pjsip_tpfactory *factory);\n\n/* Clean up listener resources (group lock handler) */\nstatic void lis_on_destroy(void *arg);\n\n/* This callback is called by transport manager to create transport */\nstatic pj_status_t lis_create_transport(pjsip_tpfactory *factory,\n\t\t\t\t\tpjsip_tpmgr *mgr,\n\t\t\t\t\tpjsip_endpoint *endpt,\n\t\t\t\t\tconst pj_sockaddr *rem_addr,\n\t\t\t\t\tint addr_len,\n\t\t\t\t\tpjsip_tx_data *tdata,\n\t\t\t\t\tpjsip_transport **transport);\n\n/* Common function to create and initialize transport */\nstatic pj_status_t tls_create(struct tls_listener *listener,\n\t\t\t      pj_pool_t *pool,\n\t\t\t      pj_ssl_sock_t *ssock, \n\t\t\t      pj_bool_t is_server,\n\t\t\t      const pj_sockaddr *local,\n\t\t\t      const pj_sockaddr *remote,\n\t\t\t      const pj_str_t *remote_name,\n\t\t\t      struct tls_transport **p_tls);\n\n\nstatic void tls_perror(const char *sender, const char *title,\n\t\t       pj_status_t status)\n{\n    char errmsg[PJ_ERR_MSG_SIZE];\n\n    pj_strerror(status, errmsg, sizeof(errmsg));\n\n    PJ_LOG(3,(sender, \"%s: %s [code=%d]\", title, errmsg, status));\n}\n\n\nstatic void sockaddr_to_host_port( pj_pool_t *pool,\n\t\t\t\t   pjsip_host_port *host_port,\n\t\t\t\t   const pj_sockaddr *addr )\n{\n    host_port->host.ptr = (char*) pj_pool_alloc(pool, PJ_INET6_ADDRSTRLEN+4);\n    pj_sockaddr_print(addr, host_port->host.ptr, PJ_INET6_ADDRSTRLEN+4, 0);\n    host_port->host.slen = pj_ansi_strlen(host_port->host.ptr);\n    host_port->port = pj_sockaddr_get_port(addr);\n}\n\n\nstatic pj_uint32_t ssl_get_proto(pjsip_ssl_method ssl_method, pj_uint32_t proto)\n{\n    pj_uint32_t out_proto;\n\n    if (proto)\n\treturn proto;\n\n    if (ssl_method == PJSIP_SSL_UNSPECIFIED_METHOD)\n\tssl_method = PJSIP_SSL_DEFAULT_METHOD;\n\n    switch(ssl_method) {\n    case PJSIP_SSLV2_METHOD:\n\tout_proto = PJ_SSL_SOCK_PROTO_SSL2;\n\tbreak;\n    case PJSIP_SSLV3_METHOD:\n\tout_proto = PJ_SSL_SOCK_PROTO_SSL3;\n\tbreak;\n    case PJSIP_TLSV1_METHOD:\n\tout_proto = PJ_SSL_SOCK_PROTO_TLS1;\n\tbreak;\n    case PJSIP_TLSV1_1_METHOD:\n\tout_proto = PJ_SSL_SOCK_PROTO_TLS1_1;\n\tbreak;\n    case PJSIP_TLSV1_2_METHOD:\n\tout_proto = PJ_SSL_SOCK_PROTO_TLS1_2;\n\tbreak;\n    case PJSIP_SSLV23_METHOD:\n\tout_proto = PJ_SSL_SOCK_PROTO_SSL23;\n\tbreak;\n    default:\n\tout_proto = PJ_SSL_SOCK_PROTO_DEFAULT;\n\tbreak;\n    }   \n    return out_proto;\n}\n\n\nstatic void tls_init_shutdown(struct tls_transport *tls, pj_status_t status)\n{\n    pjsip_tp_state_callback state_cb;\n\n    if (tls->close_reason == PJ_SUCCESS)\n\ttls->close_reason = status;\n\n    if (tls->base.is_shutdown || tls->base.is_destroying)\n\treturn;\n\n    /* Prevent immediate transport destroy by application, as transport\n     * state notification callback may be stacked and transport instance\n     * must remain valid at any point in the callback.\n     */\n    pjsip_transport_add_ref(&tls->base);\n\n    /* Notify application of transport disconnected state */\n    state_cb = pjsip_tpmgr_get_state_cb(tls->base.tpmgr);\n    if (state_cb) {\n\tpjsip_transport_state_info state_info;\n\tpjsip_tls_state_info tls_info;\n\tpj_ssl_sock_info ssl_info;\n\t\n\t/* Init transport state info */\n\tpj_bzero(&state_info, sizeof(state_info));\n\tstate_info.status = tls->close_reason;\n\n\tif (tls->ssock && \n\t    pj_ssl_sock_get_info(tls->ssock, &ssl_info) == PJ_SUCCESS)\n\t{\n\t    pj_bzero(&tls_info, sizeof(tls_info));\n\t    tls_info.ssl_sock_info = &ssl_info;\n\t    state_info.ext_info = &tls_info;\n\t}\n\n\t(*state_cb)(&tls->base, PJSIP_TP_STATE_DISCONNECTED, &state_info);\n    }\n\n    /* check again */\n    if (tls->base.is_shutdown || tls->base.is_destroying) {\n        pjsip_transport_dec_ref(&tls->base);\n\treturn;\n    }\n\n    /* We can not destroy the transport since high level objects may\n     * still keep reference to this transport. So we can only \n     * instruct transport manager to gracefully start the shutdown\n     * procedure for this transport.\n     */\n    pjsip_transport_shutdown(&tls->base);\n\n    /* Now, it is ok to destroy the transport. */\n    pjsip_transport_dec_ref(&tls->base);\n}\n\n\n/****************************************************************************\n * The TLS listener/transport factory.\n */\n\n/*\n * This is the public API to create, initialize, register, and start the\n * TLS listener.\n */\nPJ_DEF(pj_status_t) pjsip_tls_transport_start (pjsip_endpoint *endpt,\n\t\t\t\t\t       const pjsip_tls_setting *opt,\n\t\t\t\t\t       const pj_sockaddr_in *local_in,\n\t\t\t\t\t       const pjsip_host_port *a_name,\n\t\t\t\t\t       unsigned async_cnt,\n\t\t\t\t\t       pjsip_tpfactory **p_factory)\n{\n    pj_sockaddr local;\n\n    if (local_in)\n\tpj_sockaddr_cp(&local, local_in);\n\n    return pjsip_tls_transport_start2(endpt, opt, (local_in? &local : NULL),\n                                      a_name, async_cnt, p_factory);\n}\n\nPJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt,\n \t\t\t\t\t        const pjsip_tls_setting *opt,\n\t\t\t\t\t        const pj_sockaddr *local,\n\t\t\t\t\t        const pjsip_host_port *a_name,\n\t\t\t\t\t        unsigned async_cnt,\n\t\t\t\t\t        pjsip_tpfactory **p_factory)\n{\n    pj_pool_t *pool;\n    pj_bool_t is_ipv6;\n    int af, sip_ssl_method;\n    pj_uint32_t sip_ssl_proto;\n    struct tls_listener *listener;\n    pj_ssl_sock_param ssock_param, newsock_param;\n    pj_sockaddr *listener_addr;\n    pj_bool_t has_listener;\n    pj_status_t status;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL);\n\n    is_ipv6 = (local && local->addr.sa_family == pj_AF_INET6());\n    af = is_ipv6 ? pj_AF_INET6() : pj_AF_INET();\n\n    /* Verify that address given in a_name (if any) is valid */\n    if (a_name && a_name->host.slen) {\n\tpj_sockaddr tmp;\n\n\tstatus = pj_sockaddr_init(af, &tmp, &a_name->host,\n\t\t\t\t  (pj_uint16_t)a_name->port);\n\tif (status != PJ_SUCCESS || !pj_sockaddr_has_addr(&tmp) ||\n\t    (!is_ipv6 && tmp.ipv4.sin_addr.s_addr == PJ_INADDR_NONE))\n\t{\n\t    /* Invalid address */\n\t    return PJ_EINVAL;\n\t}\n    }\n\n    pool = pjsip_endpt_create_pool(endpt, \"tlstp\", POOL_LIS_INIT, \n\t\t\t\t   POOL_LIS_INC);\n    PJ_ASSERT_RETURN(pool, PJ_ENOMEM);\n\n    listener = PJ_POOL_ZALLOC_T(pool, struct tls_listener);\n    listener->factory.pool = pool;\n    if (is_ipv6)\n\tlistener->factory.type = PJSIP_TRANSPORT_TLS6;\n    else\n\tlistener->factory.type = PJSIP_TRANSPORT_TLS;\n    listener->factory.type_name = (char*)\n\t\tpjsip_transport_get_type_name(listener->factory.type);\n    listener->factory.flag = \n\tpjsip_transport_get_flag_from_type(listener->factory.type);\n\n    pj_ansi_strcpy(listener->factory.obj_name, \"tlstp\");\n    if (is_ipv6)\n\tpj_ansi_strcat(listener->factory.obj_name, \"6\");\n\n    if (opt)\n\tpjsip_tls_setting_copy(pool, &listener->tls_setting, opt);\n    else\n\tpjsip_tls_setting_default(&listener->tls_setting);\n\n    status = pj_lock_create_recursive_mutex(pool, listener->factory.obj_name,\n\t\t\t\t\t    &listener->factory.lock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    if (async_cnt > MAX_ASYNC_CNT) \n\tasync_cnt = MAX_ASYNC_CNT;\n\n    /* Build SSL socket param */\n    pj_ssl_sock_param_default(&ssock_param);\n    ssock_param.sock_af = af;\n    ssock_param.cb.on_accept_complete = &on_accept_complete;\n    ssock_param.async_cnt = async_cnt;\n    ssock_param.ioqueue = pjsip_endpt_get_ioqueue(endpt);\n    ssock_param.require_client_cert = listener->tls_setting.require_client_cert;\n    ssock_param.timeout = listener->tls_setting.timeout;\n    ssock_param.user_data = listener;\n    ssock_param.verify_peer = PJ_FALSE; /* avoid SSL socket closing the socket\n\t\t\t\t\t * due to verification error */\n    if (ssock_param.send_buffer_size < PJSIP_MAX_PKT_LEN)\n\tssock_param.send_buffer_size = PJSIP_MAX_PKT_LEN;\n    if (ssock_param.read_buffer_size < PJSIP_MAX_PKT_LEN)\n\tssock_param.read_buffer_size = PJSIP_MAX_PKT_LEN;\n    ssock_param.ciphers_num = listener->tls_setting.ciphers_num;\n    ssock_param.ciphers = listener->tls_setting.ciphers;\n    ssock_param.reuse_addr = listener->tls_setting.reuse_addr;\n    ssock_param.qos_type = listener->tls_setting.qos_type;\n    ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error;\n    pj_memcpy(&ssock_param.qos_params, &listener->tls_setting.qos_params,\n\t      sizeof(ssock_param.qos_params));\n\n    ssock_param.sockopt_ignore_error = \n\t\t\t\t     listener->tls_setting.sockopt_ignore_error;\n    /* Copy the sockopt */\n    pj_memcpy(&ssock_param.sockopt_params, \n\t      &listener->tls_setting.sockopt_params,\n\t      sizeof(listener->tls_setting.sockopt_params));\n\n    has_listener = PJ_FALSE;\n\n    sip_ssl_method = listener->tls_setting.method;\n    sip_ssl_proto = listener->tls_setting.proto;\n    ssock_param.proto = ssl_get_proto(sip_ssl_method, sip_ssl_proto); \n\n    /* Create group lock */\n    status = pj_grp_lock_create(pool, NULL, &listener->grp_lock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Setup group lock handler */\n    pj_grp_lock_add_ref(listener->grp_lock);\n    pj_grp_lock_add_handler(listener->grp_lock, pool, listener,\n\t\t\t    &lis_on_destroy);\n\n#if !(defined(PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER) && \\\n      PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER != 0)\n\n    ssock_param.grp_lock = listener->grp_lock;\n\n    /* Create SSL socket */\n    status = pj_ssl_sock_create(pool, &ssock_param, &listener->ssock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n#endif\n\n    /* Bind address may be different than factory.local_addr because\n     * factory.local_addr will be resolved below.\n     */\n    listener_addr = &listener->factory.local_addr;\n    if (local) {\n\tpj_sockaddr_cp((pj_sockaddr_t*)listener_addr, \n\t\t       (const pj_sockaddr_t*)local);\n\tpj_sockaddr_cp(&listener->bound_addr, local);\n    } else {\n\tpj_sockaddr_init(af, listener_addr, NULL, 0);\n\tpj_sockaddr_init(af, &listener->bound_addr, NULL, 0);\n    }\n\n#if !(defined(PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER) && \\\n      PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER != 0)\n\n    /* Check if certificate/CA list for SSL socket is set */\n    if (listener->tls_setting.cert_file.slen ||\n\tlistener->tls_setting.ca_list_file.slen ||\n\tlistener->tls_setting.ca_list_path.slen) \n    {\n\tstatus = pj_ssl_cert_load_from_files2(pool,\n\t\t\t&listener->tls_setting.ca_list_file,\n\t\t\t&listener->tls_setting.ca_list_path,\n\t\t\t&listener->tls_setting.cert_file,\n\t\t\t&listener->tls_setting.privkey_file,\n\t\t\t&listener->tls_setting.password,\n\t\t\t&listener->cert);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n\tstatus = pj_ssl_sock_set_certificate(listener->ssock, pool, \n\t\t\t\t\t     listener->cert);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n    }\n\n    /* Start accepting incoming connections. Note that some TLS/SSL backends\n     * may not support for SSL socket server.\n     */\n    has_listener = PJ_FALSE;\n\n    pj_memcpy(&newsock_param, &ssock_param, sizeof(newsock_param));\n    newsock_param.async_cnt = 1;\n    newsock_param.cb.on_data_read = &on_data_read;\n    newsock_param.cb.on_data_sent = &on_data_sent;\n    status = pj_ssl_sock_start_accept2(listener->ssock, pool, \n\t\t\t  (pj_sockaddr_t*)listener_addr, \n\t\t\t  pj_sockaddr_get_len((pj_sockaddr_t*)listener_addr),\n\t\t\t  &newsock_param);\n    if (status == PJ_SUCCESS || status == PJ_EPENDING) {\n\tpj_ssl_sock_info info;\n\thas_listener = PJ_TRUE;\n\n\t/* Retrieve the bound address */\n\tstatus = pj_ssl_sock_get_info(listener->ssock, &info);\n\tif (status == PJ_SUCCESS)\n\t    pj_sockaddr_cp(listener_addr, (pj_sockaddr_t*)&info.local_addr);\n    } else if (status != PJ_ENOTSUP) {\n\tgoto on_error;\n    }\n\n#endif\n\n    /* If published host/IP is specified, then use that address as the\n     * listener advertised address.\n     */\n    if (a_name && a_name->host.slen) {\n\t/* Copy the address */\n\tlistener->factory.addr_name = *a_name;\n\tpj_strdup(listener->factory.pool, &listener->factory.addr_name.host, \n\t\t  &a_name->host);\n\tlistener->factory.addr_name.port = a_name->port;\n\n    } else {\n\t/* No published address is given, use the bound address */\n\n\t/* If the address returns 0.0.0.0, use the default\n\t * interface address as the transport's address.\n\t */\n\tif (!pj_sockaddr_has_addr(listener_addr)) {\n\t    pj_sockaddr hostip;\n\n\t    status = pj_gethostip(af, &hostip);\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_error;\n\n\t    pj_sockaddr_copy_addr(listener_addr, &hostip);\n\t}\n\n\t/* Save the address name */\n\tsockaddr_to_host_port(listener->factory.pool, \n\t\t\t      &listener->factory.addr_name, listener_addr);\n    }\n\n    /* If port is zero, get the bound port */\n    if (listener->factory.addr_name.port == 0) {\n\tlistener->factory.addr_name.port = pj_sockaddr_get_port(listener_addr);\n    }\n\n    pj_ansi_snprintf(listener->factory.obj_name, \n\t\t     sizeof(listener->factory.obj_name),\n\t\t     \"tlstp:%d\",  listener->factory.addr_name.port);\n\n    /* Register to transport manager */\n    listener->endpt = endpt;\n    listener->tpmgr = pjsip_endpt_get_tpmgr(endpt);\n    listener->factory.create_transport2 = lis_create_transport;\n    listener->factory.destroy = lis_destroy;\n    listener->is_registered = PJ_TRUE;\n    status = pjsip_tpmgr_register_tpfactory(listener->tpmgr,\n\t\t\t\t\t    &listener->factory);\n    if (status != PJ_SUCCESS) {\n\tlistener->is_registered = PJ_FALSE;\n\tgoto on_error;\n    }\n\n    if (has_listener) {\n\tPJ_LOG(4,(listener->factory.obj_name, \n\t\t \"SIP TLS listener is ready for incoming connections \"\n\t\t \"at %.*s:%d\",\n\t\t (int)listener->factory.addr_name.host.slen,\n\t\t listener->factory.addr_name.host.ptr,\n\t\t listener->factory.addr_name.port));\n    } else {\n\tPJ_LOG(4,(listener->factory.obj_name, \"SIP TLS is ready \"\n\t\t  \"(client only)\"));\n    }\n\n    /* Return the pointer to user */\n    if (p_factory) *p_factory = &listener->factory;\n\n    return PJ_SUCCESS;\n\non_error:\n    lis_destroy(&listener->factory);\n    return status;\n}\n\n\n/* Clean up listener resources */\nstatic void lis_on_destroy(void *arg)\n{\n    struct tls_listener *listener = (struct tls_listener*)arg;\n\n    if (listener->factory.lock) {\n\tpj_lock_destroy(listener->factory.lock);\n\tlistener->factory.lock = NULL;\n    }\n\n    if (listener->factory.pool) {\n\tpj_pool_t *pool = listener->factory.pool;\n\n\tPJ_LOG(4,(listener->factory.obj_name,  \"SIP TLS transport destroyed\"));\n\n\tlistener->factory.pool = NULL;\n\tpj_pool_release(pool);\n    }\n}\n\n\n/* This callback is called by transport manager to destroy listener */\nstatic pj_status_t lis_destroy(pjsip_tpfactory *factory)\n{\n    struct tls_listener *listener = (struct tls_listener *)factory;\n\n    if (listener->is_registered) {\n\tpjsip_tpmgr_unregister_tpfactory(listener->tpmgr, &listener->factory);\n\tlistener->is_registered = PJ_FALSE;\n    }\n\n    if (listener->ssock) {\n\tpj_ssl_sock_close(listener->ssock);\n\tlistener->ssock = NULL;\n    }\n\n    if (listener->grp_lock) {\n\tpj_grp_lock_t *grp_lock = listener->grp_lock;\n\tlistener->grp_lock = NULL;\n\tpj_grp_lock_dec_ref(grp_lock);\n\t/* Listener may have been deleted at this point */\n    } else {\n\tlis_on_destroy(listener);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/***************************************************************************/\n/*\n * TLS Transport\n */\n\n/*\n * Prototypes.\n */\n/* Called by transport manager to send message */\nstatic pj_status_t tls_send_msg(pjsip_transport *transport, \n\t\t\t\tpjsip_tx_data *tdata,\n\t\t\t\tconst pj_sockaddr_t *rem_addr,\n\t\t\t\tint addr_len,\n\t\t\t\tvoid *token,\n\t\t\t\tpjsip_transport_callback callback);\n\n/* Called by transport manager to shutdown */\nstatic pj_status_t tls_shutdown(pjsip_transport *transport);\n\n/* Called by transport manager to destroy transport */\nstatic pj_status_t tls_destroy_transport(pjsip_transport *transport);\n\n/* Utility to destroy transport */\nstatic pj_status_t tls_destroy(pjsip_transport *transport,\n\t\t\t       pj_status_t reason);\n\n/* Callback when connect completes */\nstatic pj_bool_t on_connect_complete(pj_ssl_sock_t *ssock,\n\t\t\t\t     pj_status_t status);\n\n/* TLS keep-alive timer callback */\nstatic void tls_keep_alive_timer(pj_timer_heap_t *th, pj_timer_entry *e);\n\n/*\n * Common function to create TLS transport, called when pending accept() and\n * pending connect() complete.\n */\nstatic pj_status_t tls_create( struct tls_listener *listener,\n\t\t\t       pj_pool_t *pool,\n\t\t\t       pj_ssl_sock_t *ssock,\n\t\t\t       pj_bool_t is_server,\n\t\t\t       const pj_sockaddr *local,\n\t\t\t       const pj_sockaddr *remote,\n\t\t\t       const pj_str_t *remote_name,\n\t\t\t       struct tls_transport **p_tls)\n{\n    struct tls_transport *tls;\n    const pj_str_t ka_pkt = PJSIP_TLS_KEEP_ALIVE_DATA;\n    char print_addr[PJ_INET6_ADDRSTRLEN+10];\n    pj_status_t status;\n    \n\n    PJ_ASSERT_RETURN(listener && ssock && local && remote && p_tls, PJ_EINVAL);\n\n\n    if (pool == NULL) {\n\tpool = pjsip_endpt_create_pool(listener->endpt, \"tls\",\n\t\t\t\t       POOL_TP_INIT, POOL_TP_INC);\n\tPJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n    }    \n\n    /*\n     * Create and initialize basic transport structure.\n     */\n    tls = PJ_POOL_ZALLOC_T(pool, struct tls_transport);\n    tls->is_server = is_server;\n    tls->verify_server = listener->tls_setting.verify_server;\n    pj_list_init(&tls->delayed_list);\n    tls->base.pool = pool;\n\n    pj_ansi_snprintf(tls->base.obj_name, PJ_MAX_OBJ_NAME, \n\t\t     (is_server ? \"tlss%p\" :\"tlsc%p\"), tls);\n\n    status = pj_atomic_create(pool, 0, &tls->base.ref_cnt);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    status = pj_lock_create_recursive_mutex(pool, \"tls\", &tls->base.lock);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    if (remote_name)\n\tpj_strdup(pool, &tls->remote_name, remote_name);\n\n    tls->base.key.type = listener->factory.type;\n    pj_sockaddr_cp(&tls->base.key.rem_addr, remote);\n    tls->base.type_name = (char*)pjsip_transport_get_type_name(\n\t\t\t\t   (pjsip_transport_type_e)tls->base.key.type);\n    tls->base.flag = pjsip_transport_get_flag_from_type(\n\t\t\t\t   (pjsip_transport_type_e)tls->base.key.type);\n\n    tls->base.info = (char*) pj_pool_alloc(pool, 64);\n    pj_ansi_snprintf(tls->base.info, 64, \"%s to %s\",\n                     tls->base.type_name,\n                     pj_sockaddr_print(remote, print_addr,\n                                       sizeof(print_addr), 3));\n\n\n    tls->base.addr_len = pj_sockaddr_get_len(remote);\n    tls->base.dir = is_server? PJSIP_TP_DIR_INCOMING : PJSIP_TP_DIR_OUTGOING;\n    \n    /* Set initial local address */\n    if (!pj_sockaddr_has_addr(local)) {\n        pj_sockaddr_cp(&tls->base.local_addr,\n                       &listener->factory.local_addr);\n    } else {\n\tpj_sockaddr_cp(&tls->base.local_addr, local);\n    }\n    \n    sockaddr_to_host_port(pool, &tls->base.local_name, &tls->base.local_addr);\n    if (tls->remote_name.slen) {\n\ttls->base.remote_name.host = tls->remote_name;\n\ttls->base.remote_name.port = pj_sockaddr_get_port(remote);\n    } else {\n\tsockaddr_to_host_port(pool, &tls->base.remote_name, remote);\n    }\n\n    tls->base.endpt = listener->endpt;\n    tls->base.tpmgr = listener->tpmgr;\n    tls->base.send_msg = &tls_send_msg;\n    tls->base.do_shutdown = &tls_shutdown;\n    tls->base.destroy = &tls_destroy_transport;\n\n    tls->ssock = ssock;\n\n    /* Register transport to transport manager */\n    status = pjsip_transport_register(listener->tpmgr, &tls->base);\n    if (status != PJ_SUCCESS) {\n\tgoto on_error;\n    }\n\n    tls->is_registered = PJ_TRUE;\n\n    /* Initialize keep-alive timer */\n    tls->ka_timer.user_data = (void*)tls;\n    tls->ka_timer.cb = &tls_keep_alive_timer;\n    pj_ioqueue_op_key_init(&tls->ka_op_key.key, sizeof(pj_ioqueue_op_key_t));\n    pj_strdup(tls->base.pool, &tls->ka_pkt, &ka_pkt);\n    \n    /* Done setting up basic transport. */\n    *p_tls = tls;\n\n    PJ_LOG(4,(tls->base.obj_name, \"TLS %s transport created\",\n\t      (tls->is_server ? \"server\" : \"client\")));\n\n    return PJ_SUCCESS;\n\non_error:\n    tls_destroy(&tls->base, status);\n    return status;\n}\n\n\n/* Flush all delayed transmision once the socket is connected. */\nstatic void tls_flush_pending_tx(struct tls_transport *tls)\n{\n    pj_time_val now;\n\n    pj_gettickcount(&now);\n    pj_lock_acquire(tls->base.lock);\n    while (!pj_list_empty(&tls->delayed_list)) {\n\tstruct delayed_tdata *pending_tx;\n\tpjsip_tx_data *tdata;\n\tpj_ioqueue_op_key_t *op_key;\n\tpj_ssize_t size;\n\tpj_status_t status;\n\n\tpending_tx = tls->delayed_list.next;\n\tpj_list_erase(pending_tx);\n\n\ttdata = pending_tx->tdata_op_key->tdata;\n\top_key = (pj_ioqueue_op_key_t*)pending_tx->tdata_op_key;\n\n        if (pending_tx->timeout.sec > 0 &&\n            PJ_TIME_VAL_GT(now, pending_tx->timeout))\n        {\n            continue;\n        }\n\n\t/* send! */\n\tsize = tdata->buf.cur - tdata->buf.start;\n\tstatus = pj_ssl_sock_send(tls->ssock, op_key, tdata->buf.start, \n\t\t\t\t  &size, 0);\n\n\tif (status != PJ_EPENDING) {\n            pj_lock_release(tls->base.lock);\n\t    on_data_sent(tls->ssock, op_key, size);\n            pj_lock_acquire(tls->base.lock);\n\t}\n    }\n    pj_lock_release(tls->base.lock);\n}\n\n\n/* Called by transport manager to destroy transport */\nstatic pj_status_t tls_destroy_transport(pjsip_transport *transport)\n{\n    struct tls_transport *tls = (struct tls_transport*)transport;\n\n    /* Transport would have been unregistered by now since this callback\n     * is called by transport manager.\n     */\n    tls->is_registered = PJ_FALSE;\n\n    return tls_destroy(transport, tls->close_reason);\n}\n\n\n/* Clean up TLS resources */\nstatic void tls_on_destroy(void *arg)\n{\n    struct tls_transport *tls = (struct tls_transport*)arg;\n\n    if (tls->rdata.tp_info.pool) {\n\tpj_pool_release(tls->rdata.tp_info.pool);\n\ttls->rdata.tp_info.pool = NULL;\n    }\n\n    if (tls->base.lock) {\n\tpj_lock_destroy(tls->base.lock);\n\ttls->base.lock = NULL;\n    }\n\n    if (tls->base.ref_cnt) {\n\tpj_atomic_destroy(tls->base.ref_cnt);\n\ttls->base.ref_cnt = NULL;\n    }\n\n    if (tls->base.pool) {\n\tpj_pool_t *pool;\n\n\tif (tls->close_reason != PJ_SUCCESS) {\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\n\t    pj_strerror(tls->close_reason, errmsg, sizeof(errmsg));\n\t    PJ_LOG(4,(tls->base.obj_name, \n\t\t      \"TLS transport destroyed with reason %d: %s\", \n\t\t      tls->close_reason, errmsg));\n\n\t} else {\n\n\t    PJ_LOG(4,(tls->base.obj_name, \n\t\t      \"TLS transport destroyed normally\"));\n\n\t}\n\n\tpool = tls->base.pool;\n\ttls->base.pool = NULL;\n\tpj_pool_release(pool);\n    }\n}\n\n/* Destroy TLS transport */\nstatic pj_status_t tls_destroy(pjsip_transport *transport, \n\t\t\t       pj_status_t reason)\n{\n    struct tls_transport *tls = (struct tls_transport*)transport;\n\n    if (tls->close_reason == 0)\n\ttls->close_reason = reason;\n\n    if (tls->is_registered) {\n\ttls->is_registered = PJ_FALSE;\n\tpjsip_transport_destroy(transport);\n\n\t/* pjsip_transport_destroy will recursively call this function\n\t * again.\n\t */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Mark transport as closing */\n    tls->is_closing = PJ_TRUE;\n\n    /* Stop keep-alive timer. */\n    if (tls->ka_timer.id) {\n\tpjsip_endpt_cancel_timer(tls->base.endpt, &tls->ka_timer);\n\ttls->ka_timer.id = PJ_FALSE;\n    }\n\n    /* Cancel all delayed transmits */\n    while (!pj_list_empty(&tls->delayed_list)) {\n\tstruct delayed_tdata *pending_tx;\n\tpj_ioqueue_op_key_t *op_key;\n\n\tpending_tx = tls->delayed_list.next;\n\tpj_list_erase(pending_tx);\n\n\top_key = (pj_ioqueue_op_key_t*)pending_tx->tdata_op_key;\n\n\ton_data_sent(tls->ssock, op_key, -reason);\n    }\n\n    if (tls->ssock) {\n\tpj_ssl_sock_close(tls->ssock);\n\ttls->ssock = NULL;\n    }\n\n    if (tls->grp_lock) {\n\tpj_grp_lock_t *grp_lock = tls->grp_lock;\n\ttls->grp_lock = NULL;\n\tpj_grp_lock_dec_ref(grp_lock);\n\t/* Transport may have been deleted at this point */\n    } else {\n\ttls_on_destroy(tls);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * This utility function creates receive data buffers and start\n * asynchronous recv() operations from the socket. It is called after\n * accept() or connect() operation complete.\n */\nstatic pj_status_t tls_start_read(struct tls_transport *tls)\n{\n    pj_pool_t *pool;\n    pj_uint32_t size;\n    pj_sockaddr *rem_addr;\n    void *readbuf[1];\n    pj_status_t status;\n\n    /* Init rdata */\n    pool = pjsip_endpt_create_pool(tls->base.endpt,\n\t\t\t\t   \"rtd%p\",\n\t\t\t\t   PJSIP_POOL_RDATA_LEN,\n\t\t\t\t   PJSIP_POOL_RDATA_INC);\n    if (!pool) {\n\ttls_perror(tls->base.obj_name, \"Unable to create pool\", PJ_ENOMEM);\n\treturn PJ_ENOMEM;\n    }\n\n    tls->rdata.tp_info.pool = pool;\n\n    tls->rdata.tp_info.transport = &tls->base;\n    tls->rdata.tp_info.tp_data = tls;\n    tls->rdata.tp_info.op_key.rdata = &tls->rdata;\n    pj_ioqueue_op_key_init(&tls->rdata.tp_info.op_key.op_key, \n\t\t\t   sizeof(pj_ioqueue_op_key_t));\n\n    tls->rdata.pkt_info.src_addr = tls->base.key.rem_addr;\n    tls->rdata.pkt_info.src_addr_len = sizeof(tls->rdata.pkt_info.src_addr);\n    rem_addr = &tls->base.key.rem_addr;\n    pj_sockaddr_print(rem_addr, tls->rdata.pkt_info.src_name,\n                          sizeof(tls->rdata.pkt_info.src_name), 0);\n    tls->rdata.pkt_info.src_port = pj_sockaddr_get_port(rem_addr);\n\n    size = sizeof(tls->rdata.pkt_info.packet);\n    readbuf[0] = tls->rdata.pkt_info.packet;\n    status = pj_ssl_sock_start_read2(tls->ssock, tls->base.pool, size,\n\t\t\t\t     readbuf, 0);\n    if (status != PJ_SUCCESS && status != PJ_EPENDING) {\n\tPJ_LOG(4, (tls->base.obj_name, \n\t\t   \"pj_ssl_sock_start_read() error, status=%d\", \n\t\t   status));\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* This callback is called by transport manager for the TLS factory\n * to create outgoing transport to the specified destination.\n */\nstatic pj_status_t lis_create_transport(pjsip_tpfactory *factory,\n\t\t\t\t\tpjsip_tpmgr *mgr,\n\t\t\t\t\tpjsip_endpoint *endpt,\n\t\t\t\t\tconst pj_sockaddr *rem_addr,\n\t\t\t\t\tint addr_len,\n\t\t\t\t\tpjsip_tx_data *tdata,\n\t\t\t\t\tpjsip_transport **p_transport)\n{\n    struct tls_listener *listener;\n    struct tls_transport *tls;\n    int sip_ssl_method;\n    pj_uint32_t sip_ssl_proto;\n    pj_pool_t *pool;\n    pj_grp_lock_t *glock;\n    pj_ssl_sock_t *ssock;\n    pj_ssl_sock_param ssock_param;\n    pj_sockaddr local_addr;\n    pj_str_t remote_name;\n    pj_status_t status;\n\n    /* Sanity checks */\n    PJ_ASSERT_RETURN(factory && mgr && endpt && rem_addr &&\n\t\t     addr_len && p_transport, PJ_EINVAL);\n\n    /* Check that address is a sockaddr_in or sockaddr_in6*/\n    PJ_ASSERT_RETURN((rem_addr->addr.sa_family == pj_AF_INET() &&\n\t\t      addr_len == sizeof(pj_sockaddr_in)) ||\n\t\t     (rem_addr->addr.sa_family == pj_AF_INET6() &&\n\t\t      addr_len == sizeof(pj_sockaddr_in6)), PJ_EINVAL);\n\n\n    listener = (struct tls_listener*)factory;\n\n    pool = pjsip_endpt_create_pool(listener->endpt, \"tls\",\n\t\t\t\t   POOL_TP_INIT, POOL_TP_INC);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    /* Get remote host name from tdata */\n    if (tdata)\n\tremote_name = tdata->dest_info.name;\n    else\n\tpj_bzero(&remote_name, sizeof(remote_name));\n\n    /* Build SSL socket param */\n    pj_ssl_sock_param_default(&ssock_param);\n    ssock_param.sock_af = (factory->type & PJSIP_TRANSPORT_IPV6) ?\n\t\t\t    pj_AF_INET6() : pj_AF_INET();\n    ssock_param.cb.on_connect_complete = &on_connect_complete;\n    ssock_param.cb.on_data_read = &on_data_read;\n    ssock_param.cb.on_data_sent = &on_data_sent;\n    ssock_param.async_cnt = 1;\n    ssock_param.ioqueue = pjsip_endpt_get_ioqueue(listener->endpt);\n    ssock_param.server_name = remote_name;\n    ssock_param.timeout = listener->tls_setting.timeout;\n    ssock_param.user_data = NULL; /* pending, must be set later */\n    ssock_param.verify_peer = PJ_FALSE; /* avoid SSL socket closing the socket\n\t\t\t\t\t * due to verification error */\n    if (ssock_param.send_buffer_size < PJSIP_MAX_PKT_LEN)\n\tssock_param.send_buffer_size = PJSIP_MAX_PKT_LEN;\n    if (ssock_param.read_buffer_size < PJSIP_MAX_PKT_LEN)\n\tssock_param.read_buffer_size = PJSIP_MAX_PKT_LEN;\n    ssock_param.ciphers_num = listener->tls_setting.ciphers_num;\n    ssock_param.ciphers = listener->tls_setting.ciphers;\n    ssock_param.qos_type = listener->tls_setting.qos_type;\n    ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error;\n    pj_memcpy(&ssock_param.qos_params, &listener->tls_setting.qos_params,\n\t      sizeof(ssock_param.qos_params));\n\n    ssock_param.sockopt_ignore_error = \n\t\t\t\t     listener->tls_setting.sockopt_ignore_error;\n    /* Copy the sockopt */\n    pj_memcpy(&ssock_param.sockopt_params, \n\t      &listener->tls_setting.sockopt_params,\n\t      sizeof(listener->tls_setting.sockopt_params));\n\n    sip_ssl_method = listener->tls_setting.method;\n    sip_ssl_proto = listener->tls_setting.proto;\n    ssock_param.proto = ssl_get_proto(sip_ssl_method, sip_ssl_proto);\n\n    /* Create group lock */\n    status = pj_grp_lock_create(pool, NULL, &glock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    ssock_param.grp_lock = glock;\n    status = pj_ssl_sock_create(pool, &ssock_param, &ssock);\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_destroy(glock);\n\treturn status;\n    }\n\n    /* Apply SSL certificate */\n    if (listener->cert) {\n\tstatus = pj_ssl_sock_set_certificate(ssock, pool, listener->cert);\n\tif (status != PJ_SUCCESS) {\n\t    pj_grp_lock_destroy(glock);\n\t    return status;\n\t}\n    }\n\n    /* Initially set bind address to listener's bind address */\n    pj_sockaddr_init(listener->bound_addr.addr.sa_family,\n\t\t     &local_addr, NULL, 0);\n    pj_sockaddr_copy_addr(&local_addr, &listener->bound_addr);\n\n    /* Create the transport descriptor */\n    status = tls_create(listener, pool, ssock, PJ_FALSE, &local_addr, \n\t\t\trem_addr, &remote_name, &tls);\n    if (status != PJ_SUCCESS) {\n\tpj_grp_lock_destroy(glock);\n\treturn status;\n    }\n\n    /* Set the \"pending\" SSL socket user data */\n    pj_ssl_sock_set_user_data(tls->ssock, tls);\n\n    /* Set up the group lock */\n    tls->grp_lock = glock;\n    pj_grp_lock_add_ref(tls->grp_lock);\n    pj_grp_lock_add_handler(tls->grp_lock, pool, tls, &tls_on_destroy);\n\n    /* Start asynchronous connect() operation */\n    tls->has_pending_connect = PJ_TRUE;\n    status = pj_ssl_sock_start_connect(tls->ssock, tls->base.pool, \n\t\t\t\t       (pj_sockaddr_t*)&local_addr,\n\t\t\t\t       (pj_sockaddr_t*)rem_addr,\n\t\t\t\t       addr_len);\n    if (status == PJ_SUCCESS) {\n\ton_connect_complete(tls->ssock, PJ_SUCCESS);\n    } else if (status != PJ_EPENDING) {\n\ttls_destroy(&tls->base, status);\n\treturn status;\n    }\n\n    if (tls->has_pending_connect) {\n\tpj_ssl_sock_info info;\n\n\t/* Update local address, just in case local address currently set is \n\t * different now that asynchronous connect() is started.\n\t */\n\n\t/* Retrieve the bound address */\n\tstatus = pj_ssl_sock_get_info(tls->ssock, &info);\n\tif (status == PJ_SUCCESS) {\n\t    pj_uint16_t new_port;\n\n\t    new_port = pj_sockaddr_get_port((pj_sockaddr_t*)&info.local_addr);\n\n\t    if (pj_sockaddr_has_addr((pj_sockaddr_t*)&info.local_addr)) {\n\t\t/* Update sockaddr */\n\t\tpj_sockaddr_cp((pj_sockaddr_t*)&tls->base.local_addr,\n\t\t\t       (pj_sockaddr_t*)&info.local_addr);\n\t    } else if (new_port && new_port != pj_sockaddr_get_port(\n\t\t\t\t\t(pj_sockaddr_t*)&tls->base.local_addr))\n\t    {\n\t\t/* Update port only */\n\t\tpj_sockaddr_set_port(&tls->base.local_addr, \n\t\t\t\t     new_port);\n\t    }\n\n\t    sockaddr_to_host_port(tls->base.pool, &tls->base.local_name,\n\t\t\t\t  &tls->base.local_addr);\n\t}\n\n\tPJ_LOG(4,(tls->base.obj_name, \n\t\t  \"TLS transport %.*s:%d is connecting to %.*s:%d...\",\n\t\t  (int)tls->base.local_name.host.slen,\n\t\t  tls->base.local_name.host.ptr,\n\t\t  tls->base.local_name.port,\n\t\t  (int)tls->base.remote_name.host.slen,\n\t\t  tls->base.remote_name.host.ptr,\n\t\t  tls->base.remote_name.port));\n    }\n\n    /* Done */\n    *p_transport = &tls->base;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * This callback is called by SSL socket when pending accept() operation\n * has completed.\n */\nstatic pj_bool_t on_accept_complete(pj_ssl_sock_t *ssock,\n\t\t\t\t    pj_ssl_sock_t *new_ssock,\n\t\t\t\t    const pj_sockaddr_t *src_addr,\n\t\t\t\t    int src_addr_len)\n{\n    struct tls_listener *listener;\n    struct tls_transport *tls;\n    pj_ssl_sock_info ssl_info;\n    char addr[PJ_INET6_ADDRSTRLEN+10];\n    pjsip_tp_state_callback state_cb;\n    pj_sockaddr tmp_src_addr;\n    pj_bool_t is_shutdown;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(src_addr_len);\n\n    listener = (struct tls_listener*) pj_ssl_sock_get_user_data(ssock);\n\n    PJ_ASSERT_RETURN(new_ssock, PJ_TRUE);\n\n    if (!listener->is_registered)\n\treturn PJ_FALSE;\n\n    PJ_LOG(4,(listener->factory.obj_name, \n\t      \"TLS listener %.*s:%d: got incoming TLS connection \"\n\t      \"from %s, sock=%d\",\n\t      (int)listener->factory.addr_name.host.slen,\n\t      listener->factory.addr_name.host.ptr,\n\t      listener->factory.addr_name.port,\n\t      pj_sockaddr_print(src_addr, addr, sizeof(addr), 3),\n\t      new_ssock));\n\n    /* Retrieve SSL socket info, close the socket if this is failed\n     * as the SSL socket info availability is rather critical here.\n     */\n    status = pj_ssl_sock_get_info(new_ssock, &ssl_info);\n    if (status != PJ_SUCCESS) {\n\tpj_ssl_sock_close(new_ssock);\n\treturn PJ_TRUE;\n    }\n\n    /* Copy to larger buffer, just in case */\n    pj_bzero(&tmp_src_addr, sizeof(tmp_src_addr));\n    pj_sockaddr_cp(&tmp_src_addr, src_addr);\n\n    /* \n     * Incoming connection!\n     * Create TLS transport for the new socket.\n     */\n    status = tls_create( listener, NULL, new_ssock, PJ_TRUE,\n\t\t\t &ssl_info.local_addr, &tmp_src_addr, NULL, &tls);\n    \n    if (status != PJ_SUCCESS)\n\treturn PJ_TRUE;\n\n    /* Set the \"pending\" SSL socket user data */\n    pj_ssl_sock_set_user_data(new_ssock, tls);\n\n    /* Set up the group lock */\n    if (ssl_info.grp_lock) {\n\ttls->grp_lock = ssl_info.grp_lock;\n\tpj_grp_lock_add_ref(tls->grp_lock);\n\tpj_grp_lock_add_handler(tls->grp_lock, tls->base.pool, tls,\n\t\t\t\t&tls_on_destroy);\n    }\n\n    /* Prevent immediate transport destroy as application may access it \n     * (getting info, etc) in transport state notification callback.\n     */\n    pjsip_transport_add_ref(&tls->base);\n\n    /* If there is verification error and verification is mandatory, shutdown\n     * and destroy the transport.\n     */\n    if (ssl_info.verify_status && listener->tls_setting.verify_client) {\n\tif (tls->close_reason == PJ_SUCCESS) \n\t    tls->close_reason = PJSIP_TLS_ECERTVERIF;\n\tpjsip_transport_shutdown(&tls->base);\n    }\n    /* Notify transport state to application */\n    state_cb = pjsip_tpmgr_get_state_cb(tls->base.tpmgr);\n    if (state_cb) {\n\tpjsip_transport_state_info state_info;\n\tpjsip_tls_state_info tls_info;\n\tpjsip_transport_state tp_state;\n\n\t/* Init transport state info */\n\tpj_bzero(&tls_info, sizeof(tls_info));\n\tpj_bzero(&state_info, sizeof(state_info));\n\ttls_info.ssl_sock_info = &ssl_info;\n\tstate_info.ext_info = &tls_info;\n\n\t/* Set transport state based on verification status */\n\tif (ssl_info.verify_status && listener->tls_setting.verify_client)\n\t{\n\t    tp_state = PJSIP_TP_STATE_DISCONNECTED;\n\t    state_info.status = PJSIP_TLS_ECERTVERIF;\n\t} else {\n\t    tp_state = PJSIP_TP_STATE_CONNECTED;\n\t    state_info.status = PJ_SUCCESS;\n\t}\n\n\t(*state_cb)(&tls->base, tp_state, &state_info);\n    }\n\n    /* Release transport reference. If transport is shutting down, it may\n     * get destroyed here.\n     */\n    is_shutdown = tls->base.is_shutdown;\n    pjsip_transport_dec_ref(&tls->base);\n    if (is_shutdown)\n\treturn PJ_TRUE;\n\n\n    status = tls_start_read(tls);\n    if (status != PJ_SUCCESS) {\n\tPJ_LOG(3,(tls->base.obj_name, \"New transport cancelled\"));\n\ttls_init_shutdown(tls, status);\n\ttls_destroy(&tls->base, status);\n    } else {\n\t/* Start keep-alive timer */\n\tif (pjsip_cfg()->tls.keep_alive_interval) {\n\t    pj_time_val delay = {pjsip_cfg()->tls.keep_alive_interval, 0};\n\t    pjsip_endpt_schedule_timer(listener->endpt, \n\t\t\t\t       &tls->ka_timer, \n\t\t\t\t       &delay);\n\t    tls->ka_timer.id = PJ_TRUE;\n\t    pj_gettimeofday(&tls->last_activity);\n\t}\n    }\n\n    return PJ_TRUE;\n}\n\n\n/* \n * Callback from ioqueue when packet is sent.\n */\nstatic pj_bool_t on_data_sent(pj_ssl_sock_t *ssock,\n\t\t\t      pj_ioqueue_op_key_t *op_key,\n\t\t\t      pj_ssize_t bytes_sent)\n{\n    struct tls_transport *tls = (struct tls_transport*) \n    \t\t\t\tpj_ssl_sock_get_user_data(ssock);\n    pjsip_tx_data_op_key *tdata_op_key = (pjsip_tx_data_op_key*)op_key;\n\n    /* Note that op_key may be the op_key from keep-alive, thus\n     * it will not have tdata etc.\n     */\n\n    tdata_op_key->tdata = NULL;\n\n    if (tdata_op_key->callback) {\n\t/*\n\t * Notify sip_transport.c that packet has been sent.\n\t */\n\tif (bytes_sent == 0)\n\t    bytes_sent = -PJ_RETURN_OS_ERROR(OSERR_ENOTCONN);\n\n\ttdata_op_key->callback(&tls->base, tdata_op_key->token, bytes_sent);\n\n\t/* Mark last activity time */\n\tpj_gettimeofday(&tls->last_activity);\n\n    }\n\n    /* Check for error/closure */\n    if (bytes_sent <= 0) {\n\tpj_status_t status;\n\n\tPJ_LOG(5,(tls->base.obj_name, \"TLS send() error, sent=%d\", \n\t\t  bytes_sent));\n\n\tstatus = (bytes_sent == 0) ? PJ_RETURN_OS_ERROR(OSERR_ENOTCONN) :\n\t\t\t\t     (pj_status_t)-bytes_sent;\n\n\ttls_init_shutdown(tls, status);\n\n\treturn PJ_FALSE;\n    }\n    \n    return PJ_TRUE;\n}\n\n\n/* \n * This callback is called by transport manager to send SIP message \n */\nstatic pj_status_t tls_send_msg(pjsip_transport *transport, \n\t\t\t\tpjsip_tx_data *tdata,\n\t\t\t\tconst pj_sockaddr_t *rem_addr,\n\t\t\t\tint addr_len,\n\t\t\t\tvoid *token,\n\t\t\t\tpjsip_transport_callback callback)\n{\n    struct tls_transport *tls = (struct tls_transport*)transport;\n    pj_ssize_t size;\n    pj_bool_t delayed = PJ_FALSE;\n    pj_status_t status = PJ_SUCCESS;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(transport && tdata, PJ_EINVAL);\n\n    /* Check that there's no pending operation associated with the tdata */\n    PJ_ASSERT_RETURN(tdata->op_key.tdata == NULL, PJSIP_EPENDINGTX);\n    \n    /* Check the address is supported */\n    PJ_ASSERT_RETURN(rem_addr && (addr_len==sizeof(pj_sockaddr_in) ||\n\t                          addr_len==sizeof(pj_sockaddr_in6)),\n\t             PJ_EINVAL);\n\n    /* Init op key. */\n    tdata->op_key.tdata = tdata;\n    tdata->op_key.token = token;\n    tdata->op_key.callback = callback;\n\n    /* If asynchronous connect() has not completed yet, just put the\n     * transmit data in the pending transmission list since we can not\n     * use the socket yet.\n     */\n    if (tls->has_pending_connect) {\n\n\t/*\n\t * Looks like connect() is still in progress. Check again (this time\n\t * with holding the lock) to be sure.\n\t */\n\tpj_lock_acquire(tls->base.lock);\n\n\tif (tls->has_pending_connect) {\n\t    struct delayed_tdata *delayed_tdata;\n\n\t    /*\n\t     * connect() is still in progress. Put the transmit data to\n\t     * the delayed list.\n             * Starting from #1583 (https://trac.pjsip.org/repos/ticket/1583),\n             * we also add timeout value for the transmit data. When the\n             * connect() is completed, the timeout value will be checked to\n             * determine whether the transmit data needs to be sent.\n\t     */\n\t    delayed_tdata = PJ_POOL_ZALLOC_T(tdata->pool, \n\t\t\t\t\t     struct delayed_tdata);\n\t    delayed_tdata->tdata_op_key = &tdata->op_key;\n            if (tdata->msg && tdata->msg->type == PJSIP_REQUEST_MSG) {\n                pj_gettickcount(&delayed_tdata->timeout);\n                delayed_tdata->timeout.msec += pjsip_cfg()->tsx.td;\n                pj_time_val_normalize(&delayed_tdata->timeout);\n            }\n\n\t    pj_list_push_back(&tls->delayed_list, delayed_tdata);\n\t    status = PJ_EPENDING;\n\n\t    /* Prevent pj_ioqueue_send() to be called below */\n\t    delayed = PJ_TRUE;\n\t}\n\n\tpj_lock_release(tls->base.lock);\n    } \n    \n    if (!delayed) {\n\t/*\n\t * Transport is ready to go. Send the packet to ioqueue to be\n\t * sent asynchronously.\n\t */\n\tsize = tdata->buf.cur - tdata->buf.start;\n\tstatus = pj_ssl_sock_send(tls->ssock, \n\t\t\t\t    (pj_ioqueue_op_key_t*)&tdata->op_key,\n\t\t\t\t    tdata->buf.start, &size, 0);\n\n\tif (status != PJ_EPENDING) {\n\t    /* Not pending (could be immediate success or error) */\n\t    tdata->op_key.tdata = NULL;\n\n\t    /* Shutdown transport on closure/errors */\n\t    if (size <= 0) {\n\n\t\tPJ_LOG(5,(tls->base.obj_name, \"TLS send() error, sent=%d\", \n\t\t\t  size));\n\n\t\tif (status == PJ_SUCCESS) \n\t\t    status = PJ_RETURN_OS_ERROR(OSERR_ENOTCONN);\n\n\t\ttls_init_shutdown(tls, status);\n\t    }\n\t}\n    }\n\n    return status;\n}\n\n\n/* \n * This callback is called by transport manager to shutdown transport.\n */\nstatic pj_status_t tls_shutdown(pjsip_transport *transport)\n{\n    struct tls_transport *tls = (struct tls_transport*)transport;\n    \n    /* Stop keep-alive timer. */\n    if (tls->ka_timer.id) {\n\tpjsip_endpt_cancel_timer(tls->base.endpt, &tls->ka_timer);\n\ttls->ka_timer.id = PJ_FALSE;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/* \n * Callback from ioqueue that an incoming data is received from the socket.\n */\nstatic pj_bool_t on_data_read(pj_ssl_sock_t *ssock,\n\t\t\t      void *data,\n\t\t\t      pj_size_t size,\n\t\t\t      pj_status_t status,\n\t\t\t      pj_size_t *remainder)\n{\n    enum { MAX_IMMEDIATE_PACKET = 10 };\n    struct tls_transport *tls;\n    pjsip_rx_data *rdata;\n\n    PJ_UNUSED_ARG(data);\n\n    tls = (struct tls_transport*) pj_ssl_sock_get_user_data(ssock);\n    rdata = &tls->rdata;\n\n    /* Don't do anything if transport is closing. */\n    if (tls->is_closing) {\n\ttls->is_closing++;\n\treturn PJ_FALSE;\n    }\n\n    /* Houston, we have packet! Report the packet to transport manager\n     * to be parsed.\n     */\n    if (status == PJ_SUCCESS) {\n\tpj_size_t size_eaten;\n\n\t/* Mark this as an activity */\n\tpj_gettimeofday(&tls->last_activity);\n\n\tpj_assert((void*)rdata->pkt_info.packet == data);\n\n\t/* Init pkt_info part. */\n\trdata->pkt_info.len = size;\n\trdata->pkt_info.zero = 0;\n\tpj_gettimeofday(&rdata->pkt_info.timestamp);\n\n\t/* Report to transport manager.\n\t * The transport manager will tell us how many bytes of the packet\n\t * have been processed (as valid SIP message).\n\t */\n\tsize_eaten = \n\t    pjsip_tpmgr_receive_packet(rdata->tp_info.transport->tpmgr, \n\t\t\t\t       rdata);\n\n\tpj_assert(size_eaten <= (pj_size_t)rdata->pkt_info.len);\n\n\t/* Move unprocessed data to the front of the buffer */\n\t*remainder = size - size_eaten;\n\tif (*remainder > 0 && *remainder != size) {\n\t    pj_memmove(rdata->pkt_info.packet,\n\t\t       rdata->pkt_info.packet + size_eaten,\n\t\t       *remainder);\n\t}\n\n    } else {\n\n\t/* Transport is closed */\n\tPJ_LOG(4,(tls->base.obj_name, \"TLS connection closed\"));\n\n\ttls_init_shutdown(tls, status);\n\n\treturn PJ_FALSE;\n\n    }\n\n    /* Reset pool. */\n    pj_pool_reset(rdata->tp_info.pool);\n\n    return PJ_TRUE;\n}\n\n\n/* \n * Callback from ioqueue when asynchronous connect() operation completes.\n */\nstatic pj_bool_t on_connect_complete(pj_ssl_sock_t *ssock,\n\t\t\t\t     pj_status_t status)\n{\n    struct tls_transport *tls;\n    pj_ssl_sock_info ssl_info;\n    pj_sockaddr addr, *tp_addr;\n    pjsip_tp_state_callback state_cb;\n    pj_bool_t is_shutdown;\n\n    tls = (struct tls_transport*) pj_ssl_sock_get_user_data(ssock);\n\n    /* If transport is being shutdown/destroyed, proceed as error connect.\n     * Note that it is important to notify application via on_data_sent()\n     * as otherwise the transport reference counter may never reach zero\n     * (see #1898).\n     */\n    if ((tls->base.is_shutdown || tls->base.is_destroying) &&\n\tstatus == PJ_SUCCESS)\n    {\n\tstatus = PJ_ECANCELLED;\n    }\n\n    /* Check connect() status */\n    if (status != PJ_SUCCESS) {\n\n\ttls_perror(tls->base.obj_name, \"TLS connect() error\", status);\n\n\t/* Cancel all delayed transmits */\n\twhile (!pj_list_empty(&tls->delayed_list)) {\n\t    struct delayed_tdata *pending_tx;\n\t    pj_ioqueue_op_key_t *op_key;\n\n\t    pending_tx = tls->delayed_list.next;\n\t    pj_list_erase(pending_tx);\n\n\t    op_key = (pj_ioqueue_op_key_t*)pending_tx->tdata_op_key;\n\n\t    on_data_sent(tls->ssock, op_key, -status);\n\t}\n\n\tgoto on_error;\n    }\n\n    /* Retrieve SSL socket info, shutdown the transport if this is failed\n     * as the SSL socket info availability is rather critical here.\n     */\n    status = pj_ssl_sock_get_info(tls->ssock, &ssl_info);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Update (again) local address, just in case local address currently\n     * set is different now that the socket is connected (could happen\n     * on some systems, like old Win32 probably?).\n     */\n    tp_addr = &tls->base.local_addr;\n    pj_sockaddr_cp((pj_sockaddr_t*)&addr, \n\t\t   (pj_sockaddr_t*)&ssl_info.local_addr);\n    if (pj_sockaddr_cmp(tp_addr, &addr) != 0) {\n\tpj_sockaddr_cp(tp_addr, &addr);\n\tsockaddr_to_host_port(tls->base.pool, &tls->base.local_name,\n\t\t\t      tp_addr);\n    }\n\n    /* Server identity verification based on server certificate. */\n    if (ssl_info.remote_cert_info->version) {\n\tpj_str_t *remote_name;\n\tpj_ssl_cert_info *serv_cert = ssl_info.remote_cert_info;\n\tpj_bool_t matched = PJ_FALSE;\n\tunsigned i;\n\n\t/* Remote name may be hostname or IP address */\n\tif (tls->remote_name.slen)\n\t    remote_name = &tls->remote_name;\n\telse\n\t    remote_name = &tls->base.remote_name.host;\n\n\t/* Start matching remote name with SubjectAltName fields of \n\t * server certificate.\n\t */\n\tfor (i = 0; i < serv_cert->subj_alt_name.cnt && !matched; ++i) {\n\t    pj_str_t *cert_name = &serv_cert->subj_alt_name.entry[i].name;\n\n\t    switch (serv_cert->subj_alt_name.entry[i].type) {\n\t    case PJ_SSL_CERT_NAME_DNS:\n\t    case PJ_SSL_CERT_NAME_IP:\n\t\tmatched = !pj_stricmp(remote_name, cert_name);\n\t\tbreak;\n\t    case PJ_SSL_CERT_NAME_URI:\n\t\tif (pj_strnicmp2(cert_name, \"sip:\", 4) == 0 ||\n\t\t    pj_strnicmp2(cert_name, \"sips:\", 5) == 0)\n\t\t{\n\t\t    pj_str_t host_part;\n\t\t    char *p;\n\n\t\t    p = pj_strchr(cert_name, ':') + 1;\n\t\t    pj_strset(&host_part, p, cert_name->slen - \n\t\t\t\t\t     (p - cert_name->ptr));\n\t\t    matched = !pj_stricmp(remote_name, &host_part);\n\t\t}\n\t\tbreak;\n\t    default:\n\t\tbreak;\n\t    }\n\t}\n    \t\n\t/* When still not matched or no SubjectAltName fields in server\n\t * certificate, try with Common Name of Subject field.\n\t */\n\tif (!matched) {\n\t    matched = !pj_stricmp(remote_name, &serv_cert->subject.cn);\n\t}\n\n\tif (!matched) {\n\t    if (pj_strnicmp2(&serv_cert->subject.cn, \"*.\", 2) == 0) {\n\t\tPJ_LOG(1,(tls->base.obj_name,\n\t\t    \"RFC 5922 (section 7.2) does not allow TLS wildcard \"\n\t\t\t\"certificates. Advise your SIP provider, please!\"));\n\t    }\n\t    ssl_info.verify_status |= PJ_SSL_CERT_EIDENTITY_NOT_MATCH;\n\t}\n    }\n\n    /* Prevent immediate transport destroy as application may access it \n     * (getting info, etc) in transport state notification callback.\n     */\n    pjsip_transport_add_ref(&tls->base);\n\n    /* If there is verification error and verification is mandatory, shutdown\n     * and destroy the transport.\n     */\n    if (ssl_info.verify_status && tls->verify_server) {\n\tif (tls->close_reason == PJ_SUCCESS) \n\t    tls->close_reason = PJSIP_TLS_ECERTVERIF;\n\tpjsip_transport_shutdown(&tls->base);\n    }\n\n    /* Notify transport state to application */\n    state_cb = pjsip_tpmgr_get_state_cb(tls->base.tpmgr);\n    if (state_cb) {\n\tpjsip_transport_state_info state_info;\n\tpjsip_tls_state_info tls_info;\n\tpjsip_transport_state tp_state;\n\n\t/* Init transport state info */\n\tpj_bzero(&state_info, sizeof(state_info));\n\tpj_bzero(&tls_info, sizeof(tls_info));\n\tstate_info.ext_info = &tls_info;\n\ttls_info.ssl_sock_info = &ssl_info;\n\n\t/* Set transport state based on verification status */\n\tif (ssl_info.verify_status && tls->verify_server)\n\t{\n\t    tp_state = PJSIP_TP_STATE_DISCONNECTED;\n\t    state_info.status = PJSIP_TLS_ECERTVERIF;\n\t} else {\n\t    tp_state = PJSIP_TP_STATE_CONNECTED;\n\t    state_info.status = PJ_SUCCESS;\n\t}\n\n\t(*state_cb)(&tls->base, tp_state, &state_info);\n    }\n\n    /* Release transport reference. If transport is shutting down, it may\n     * get destroyed here.\n     */\n    is_shutdown = tls->base.is_shutdown;\n    pjsip_transport_dec_ref(&tls->base);\n    if (is_shutdown) {\n\tstatus = tls->close_reason;\n\ttls_perror(tls->base.obj_name, \"TLS connect() error\", status);\n\n\t/* Cancel all delayed transmits */\n\twhile (!pj_list_empty(&tls->delayed_list)) {\n\t    struct delayed_tdata *pending_tx;\n\t    pj_ioqueue_op_key_t *op_key;\n\n\t    pending_tx = tls->delayed_list.next;\n\t    pj_list_erase(pending_tx);\n\n\t    op_key = (pj_ioqueue_op_key_t*)pending_tx->tdata_op_key;\n\n\t    on_data_sent(tls->ssock, op_key, -status);\n\t}\n\n\treturn PJ_FALSE;\n    }\n\n\n    /* Mark that pending connect() operation has completed. */\n    tls->has_pending_connect = PJ_FALSE;\n\n    PJ_LOG(4,(tls->base.obj_name, \n\t      \"TLS transport %.*s:%d is connected to %.*s:%d\",\n\t      (int)tls->base.local_name.host.slen,\n\t      tls->base.local_name.host.ptr,\n\t      tls->base.local_name.port,\n\t      (int)tls->base.remote_name.host.slen,\n\t      tls->base.remote_name.host.ptr,\n\t      tls->base.remote_name.port));\n\n    /* Start pending read */\n    status = tls_start_read(tls);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Flush all pending send operations */\n    tls_flush_pending_tx(tls);\n\n    /* Start keep-alive timer */\n    if (pjsip_cfg()->tls.keep_alive_interval) {\n\tpj_time_val delay = { pjsip_cfg()->tls.keep_alive_interval, 0 };\n\tpjsip_endpt_schedule_timer(tls->base.endpt, &tls->ka_timer, \n\t\t\t\t   &delay);\n\ttls->ka_timer.id = PJ_TRUE;\n\tpj_gettimeofday(&tls->last_activity);\n    }\n\n    return PJ_TRUE;\n\non_error:\n    tls_init_shutdown(tls, status);\n\n    return PJ_FALSE;\n}\n\n\n/* Transport keep-alive timer callback */\nstatic void tls_keep_alive_timer(pj_timer_heap_t *th, pj_timer_entry *e)\n{\n    struct tls_transport *tls = (struct tls_transport*) e->user_data;\n    pj_time_val delay;\n    pj_time_val now;\n    pj_ssize_t size;\n    pj_status_t status;\n\n    PJ_UNUSED_ARG(th);\n\n    tls->ka_timer.id = PJ_TRUE;\n\n    pj_gettimeofday(&now);\n    PJ_TIME_VAL_SUB(now, tls->last_activity);\n\n    if (now.sec > 0 && now.sec < pjsip_cfg()->tls.keep_alive_interval) {\n\t/* There has been activity, so don't send keep-alive */\n\tdelay.sec = pjsip_cfg()->tls.keep_alive_interval - now.sec;\n\tdelay.msec = 0;\n\n\tpjsip_endpt_schedule_timer(tls->base.endpt, &tls->ka_timer, \n\t\t\t\t   &delay);\n\ttls->ka_timer.id = PJ_TRUE;\n\treturn;\n    }\n\n    PJ_LOG(5,(tls->base.obj_name, \"Sending %d byte(s) keep-alive to %.*s:%d\", \n\t      (int)tls->ka_pkt.slen, (int)tls->base.remote_name.host.slen,\n\t      tls->base.remote_name.host.ptr,\n\t      tls->base.remote_name.port));\n\n    /* Send the data */\n    size = tls->ka_pkt.slen;\n    status = pj_ssl_sock_send(tls->ssock, &tls->ka_op_key.key,\n\t\t\t      tls->ka_pkt.ptr, &size, 0);\n\n    if (status != PJ_SUCCESS && status != PJ_EPENDING) {\n\ttls_perror(tls->base.obj_name, \n\t\t   \"Error sending keep-alive packet\", status);\n\n\ttls_init_shutdown(tls, status);\n\treturn;\n    }\n\n    /* Register next keep-alive */\n    delay.sec = pjsip_cfg()->tls.keep_alive_interval;\n    delay.msec = 0;\n\n    pjsip_endpt_schedule_timer(tls->base.endpt, &tls->ka_timer, \n\t\t\t       &delay);\n    tls->ka_timer.id = PJ_TRUE;\n}\n\n#endif /* PJSIP_HAS_TLS_TRANSPORT */\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_transport_udp.c",
    "content": "/* $Id: sip_transport_udp.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_transport_udp.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_errno.h>\n#include <pj/addr_resolv.h>\n#include <pj/assert.h>\n#include <pj/lock.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/sock.h>\n#include <pj/compat/socket.h>\n#include <pj/string.h>\n\n\n#define THIS_FILE   \"sip_transport_udp.c\"\n\n/**\n * These are the target values for socket send and receive buffer sizes,\n * respectively. They will be applied to UDP socket with setsockopt().\n * When transport failed to set these size, it will decrease it until\n * sufficiently large number has been successfully set.\n *\n * The buffer size is important, especially in WinXP/2000 machines.\n * Basicly the lower the size, the more packets will be lost (dropped?)\n * when we're sending (receiving?) packets in large volumes.\n * \n * The figure here is taken based on my experiment on WinXP/2000 machine,\n * and with this value, the rate of dropped packet is about 8% when\n * sending 1800 requests simultaneously (percentage taken as average\n * after 50K requests or so).\n *\n * More experiments are needed probably.\n */\n/* 2010/01/14\n *  Too many people complained about seeing \"Error setting SNDBUF\" log,\n *  so lets just remove this. People who want to have SNDBUF set can\n *  still do so by declaring these two macros in config_site.h\n */\n#ifndef PJSIP_UDP_SO_SNDBUF_SIZE\n/*#   define PJSIP_UDP_SO_SNDBUF_SIZE\t(24*1024*1024)*/\n#   define PJSIP_UDP_SO_SNDBUF_SIZE\t0\n#endif\n\n#ifndef PJSIP_UDP_SO_RCVBUF_SIZE\n/*#   define PJSIP_UDP_SO_RCVBUF_SIZE\t(24*1024*1024)*/\n#   define PJSIP_UDP_SO_RCVBUF_SIZE\t0\n#endif\n\n\n/* Struct udp_transport \"inherits\" struct pjsip_transport */\nstruct udp_transport\n{\n    pjsip_transport\tbase;\n    pj_sock_t\t\tsock;\n    pj_ioqueue_key_t   *key;\n    int\t\t\trdata_cnt;\n    pjsip_rx_data     **rdata;\n    int\t\t\tis_closing;\n    pj_bool_t\t\tis_paused;\n\n    /* Group lock to be used by UDP transport and ioqueue key */\n    pj_grp_lock_t      *grp_lock;\n};\n\n\n/*\n * Initialize transport's receive buffer from the specified pool.\n */\nstatic void init_rdata(struct udp_transport *tp, unsigned rdata_index,\n\t\t       pj_pool_t *pool, pjsip_rx_data **p_rdata)\n{\n    pjsip_rx_data *rdata;\n\n    /* Reset pool. */\n    //note: already done by caller\n    //pj_pool_reset(pool);\n\n    rdata = PJ_POOL_ZALLOC_T(pool, pjsip_rx_data);\n\n    /* Init tp_info part. */\n    rdata->tp_info.pool = pool;\n    rdata->tp_info.transport = &tp->base;\n    rdata->tp_info.tp_data = (void*)(pj_ssize_t)rdata_index;\n    rdata->tp_info.op_key.rdata = rdata;\n    pj_ioqueue_op_key_init(&rdata->tp_info.op_key.op_key, \n\t\t\t   sizeof(pj_ioqueue_op_key_t));\n\n    tp->rdata[rdata_index] = rdata;\n\n    if (p_rdata)\n\t*p_rdata = rdata;\n}\n\n\n/*\n * udp_on_read_complete()\n *\n * This is callback notification from ioqueue that a pending recvfrom()\n * operation has completed.\n */\nstatic void udp_on_read_complete( pj_ioqueue_key_t *key, \n\t\t\t\t  pj_ioqueue_op_key_t *op_key, \n\t\t\t\t  pj_ssize_t bytes_read)\n{\n    /* See https://trac.pjsip.org/repos/ticket/1197 */\n    enum { MAX_IMMEDIATE_PACKET = 50 };\n    pjsip_rx_data_op_key *rdata_op_key = (pjsip_rx_data_op_key*) op_key;\n    pjsip_rx_data *rdata = rdata_op_key->rdata;\n    struct udp_transport *tp = (struct udp_transport*)rdata->tp_info.transport;\n    int i;\n    pj_status_t status;\n\n    /* Don't do anything if transport is closing. */\n    if (tp->is_closing) {\n\ttp->is_closing++;\n\treturn;\n    }\n\n    /* Don't do anything if transport is being paused. */\n    if (tp->is_paused)\n\treturn;\n\n    /*\n     * The idea of the loop is to process immediate data received by\n     * pj_ioqueue_recvfrom(), as long as i < MAX_IMMEDIATE_PACKET. When\n     * i is >= MAX_IMMEDIATE_PACKET, we force the recvfrom() operation to\n     * complete asynchronously, to allow other sockets to get their data.\n     */\n    for (i=0;; ++i) {\n    \tenum { MIN_SIZE = 32 };\n\tpj_uint32_t flags;\n\n\t/* Report the packet to transport manager. Only do so if packet size\n\t * is relatively big enough for a SIP packet.\n\t */\n\tif (bytes_read > MIN_SIZE) {\n\t    pj_ssize_t size_eaten;\n\t    const pj_sockaddr *src_addr = &rdata->pkt_info.src_addr;\n\n\t    /* Init pkt_info part. */\n\t    rdata->pkt_info.len = bytes_read;\n\t    rdata->pkt_info.zero = 0;\n\t    pj_gettimeofday(&rdata->pkt_info.timestamp);\n\t    if (src_addr->addr.sa_family == pj_AF_INET()) {\n\t\tpj_ansi_strcpy(rdata->pkt_info.src_name,\n\t\t\t       pj_inet_ntoa(src_addr->ipv4.sin_addr));\n\t\trdata->pkt_info.src_port = pj_ntohs(src_addr->ipv4.sin_port);\n\t    } else {\n\t\tpj_inet_ntop(pj_AF_INET6(), \n\t\t\t     pj_sockaddr_get_addr(&rdata->pkt_info.src_addr),\n\t\t\t     rdata->pkt_info.src_name,\n\t\t\t     sizeof(rdata->pkt_info.src_name));\n\t\trdata->pkt_info.src_port = pj_ntohs(src_addr->ipv6.sin6_port);\n\t    }\n\n\t    size_eaten = \n\t\tpjsip_tpmgr_receive_packet(rdata->tp_info.transport->tpmgr, \n\t\t\t\t\t   rdata);\n\n\t    if (size_eaten < 0) {\n\t\tpj_assert(!\"It shouldn't happen!\");\n\t\tsize_eaten = rdata->pkt_info.len;\n\t    }\n\n\t    /* Since this is UDP, the whole buffer is the message. */\n\t    rdata->pkt_info.len = 0;\n\n\t} else if (bytes_read <= MIN_SIZE) {\n\n\t    /* TODO: */\n\n\t} else if (-bytes_read != PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK) &&\n\t\t   -bytes_read != PJ_STATUS_FROM_OS(OSERR_EINPROGRESS) && \n\t\t   -bytes_read != PJ_STATUS_FROM_OS(OSERR_ECONNRESET)) \n\t{\n\n\t    /* Report error to endpoint. */\n\t    PJSIP_ENDPT_LOG_ERROR((rdata->tp_info.transport->endpt,\n\t\t\t\t   rdata->tp_info.transport->obj_name,\n\t\t\t\t   (pj_status_t)-bytes_read, \n\t\t\t\t   \"Warning: pj_ioqueue_recvfrom()\"\n\t\t\t\t   \" callback error\"));\n\t}\n\n\tif (i >= MAX_IMMEDIATE_PACKET) {\n\t    /* Force ioqueue_recvfrom() to return PJ_EPENDING */\n\t    flags = PJ_IOQUEUE_ALWAYS_ASYNC;\n\t} else {\n\t    flags = 0;\n\t}\n\n\t/* Reset pool. \n\t * Need to copy rdata fields to temp variable because they will\n\t * be invalid after pj_pool_reset().\n\t */\n\t{\n\t    pj_pool_t *rdata_pool = rdata->tp_info.pool;\n\t    struct udp_transport *rdata_tp ;\n\t    unsigned rdata_index;\n\n\t    rdata_tp = (struct udp_transport*)rdata->tp_info.transport;\n\t    rdata_index = (unsigned)(unsigned long)(pj_ssize_t)\n\t\t\t  rdata->tp_info.tp_data;\n\n\t    pj_pool_reset(rdata_pool);\n\t    init_rdata(rdata_tp, rdata_index, rdata_pool, &rdata);\n\n\t    /* Change some vars to point to new location after\n\t     * pool reset.\n\t     */\n\t    op_key = &rdata->tp_info.op_key.op_key;\n\t}\n\n\t/* Only read next packet if transport is not being paused. This\n\t * check handles the case where transport is paused while endpoint\n\t * is still processing a SIP message.\n\t */\n\tif (tp->is_paused)\n\t    return;\n\n\t/* Read next packet. */\n\tbytes_read = sizeof(rdata->pkt_info.packet);\n\trdata->pkt_info.src_addr_len = sizeof(rdata->pkt_info.src_addr);\n\tstatus = pj_ioqueue_recvfrom(key, op_key, \n\t\t\t\t     rdata->pkt_info.packet,\n\t\t\t\t     &bytes_read, flags,\n\t\t\t\t     &rdata->pkt_info.src_addr, \n\t\t\t\t     &rdata->pkt_info.src_addr_len);\n\n\tif (status == PJ_SUCCESS) {\n\t    /* Continue loop. */\n\t    pj_assert(i < MAX_IMMEDIATE_PACKET);\n\n\t} else if (status == PJ_EPENDING) {\n\t    break;\n\n\t} else {\n\n\t    if (i < MAX_IMMEDIATE_PACKET) {\n\n\t\t/* Report error to endpoint if this is not EWOULDBLOCK error.*/\n\t\tif (status != PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK) &&\n\t\t    status != PJ_STATUS_FROM_OS(OSERR_EINPROGRESS) && \n\t\t    status != PJ_STATUS_FROM_OS(OSERR_ECONNRESET)) \n\t\t{\n\n\t\t    PJSIP_ENDPT_LOG_ERROR((rdata->tp_info.transport->endpt,\n\t\t\t\t\t   rdata->tp_info.transport->obj_name,\n\t\t\t\t\t   status, \n\t\t\t\t\t   \"Warning: pj_ioqueue_recvfrom\"));\n\t\t}\n\n\t\t/* Continue loop. */\n\t\tbytes_read = 0;\n\t    } else {\n\t\t/* This is fatal error.\n\t\t * Ioqueue operation will stop for this transport!\n\t\t */\n\t\tPJSIP_ENDPT_LOG_ERROR((rdata->tp_info.transport->endpt,\n\t\t\t\t       rdata->tp_info.transport->obj_name,\n\t\t\t\t       status, \n\t\t\t\t       \"FATAL: pj_ioqueue_recvfrom() error, \"\n\t\t\t\t       \"UDP transport stopping! Error\"));\n\t\tbreak;\n\t    }\n\t}\n    }\n}\n\n/*\n * udp_on_write_complete()\n *\n * This is callback notification from ioqueue that a pending sendto()\n * operation has completed.\n */\nstatic void udp_on_write_complete( pj_ioqueue_key_t *key, \n\t\t\t\t   pj_ioqueue_op_key_t *op_key,\n\t\t\t\t   pj_ssize_t bytes_sent)\n{\n    struct udp_transport *tp = (struct udp_transport*) \n    \t\t\t       pj_ioqueue_get_user_data(key);\n    pjsip_tx_data_op_key *tdata_op_key = (pjsip_tx_data_op_key*)op_key;\n\n    tdata_op_key->tdata = NULL;\n\n    if (tdata_op_key->callback) {\n\ttdata_op_key->callback(&tp->base, tdata_op_key->token, bytes_sent);\n    }\n}\n\n/*\n * udp_send_msg()\n *\n * This function is called by transport manager (by transport->send_msg())\n * to send outgoing message.\n */\nstatic pj_status_t udp_send_msg( pjsip_transport *transport,\n\t\t\t\t pjsip_tx_data *tdata,\n\t\t\t\t const pj_sockaddr_t *rem_addr,\n\t\t\t\t int addr_len,\n\t\t\t\t void *token,\n\t\t\t\t pjsip_transport_callback callback)\n{\n    struct udp_transport *tp = (struct udp_transport*)transport;\n    pj_ssize_t size;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(transport && tdata, PJ_EINVAL);\n    PJ_ASSERT_RETURN(tdata->op_key.tdata == NULL, PJSIP_EPENDINGTX);\n    \n    /* Return error if transport is paused */\n    if (tp->is_paused)\n\treturn PJSIP_ETPNOTAVAIL;\n\n    /* Init op key. */\n    tdata->op_key.tdata = tdata;\n    tdata->op_key.token = token;\n    tdata->op_key.callback = callback;\n\n    /* Send to ioqueue! */\n    size = tdata->buf.cur - tdata->buf.start;\n    status = pj_ioqueue_sendto(tp->key, (pj_ioqueue_op_key_t*)&tdata->op_key,\n\t\t\t       tdata->buf.start, &size, 0,\n\t\t\t       rem_addr, addr_len);\n\n    if (status != PJ_EPENDING)\n\ttdata->op_key.tdata = NULL;\n\n    return status;\n}\n\n\n/* Clean up UDP resources */\nstatic void udp_on_destroy(void *arg)\n{\n    struct udp_transport *tp = (struct udp_transport*)arg;\n    int i;\n\n    /* Destroy rdata */\n    for (i=0; i<tp->rdata_cnt; ++i) {\n\tpj_pool_release(tp->rdata[i]->tp_info.pool);\n    }\n\n    /* Destroy reference counter. */\n    if (tp->base.ref_cnt)\n\tpj_atomic_destroy(tp->base.ref_cnt);\n\n    /* Destroy lock */\n    if (tp->base.lock)\n\tpj_lock_destroy(tp->base.lock);\n\n    PJ_LOG(4,(tp->base.obj_name, \"SIP UDP transport destroyed\"));\n\n    /* Destroy pool. */\n    pjsip_endpt_release_pool(tp->base.endpt, tp->base.pool);\n}\n\n\n/*\n * udp_destroy()\n *\n * This function is called by transport manager (by transport->destroy()).\n */\nstatic pj_status_t udp_destroy( pjsip_transport *transport )\n{\n    struct udp_transport *tp = (struct udp_transport*)transport;\n    int i;\n\n    /* Mark this transport as closing. */\n    tp->is_closing = 1;\n\n    /* Cancel all pending operations. */\n    /* blp: NO NO NO...\n     *      No need to post queued completion as we poll the ioqueue until\n     *      we've got events anyway. Posting completion will only cause\n     *      callback to be called twice with IOCP: one for the post completion\n     *      and another one for closing the socket.\n     *\n    for (i=0; i<tp->rdata_cnt; ++i) {\n\tpj_ioqueue_post_completion(tp->key, \n\t\t\t\t   &tp->rdata[i]->tp_info.op_key.op_key, -1);\n    }\n    */\n\n    /* Unregister from ioqueue. */\n    if (tp->key) {\n\tpj_ioqueue_unregister(tp->key);\n\ttp->key = NULL;\n    } else {\n\t/* Close socket. */\n\tif (tp->sock && tp->sock != PJ_INVALID_SOCKET) {\n\t    pj_sock_close(tp->sock);\n\t    tp->sock = PJ_INVALID_SOCKET;\n\t}\n    }\n\n    /* Must poll ioqueue because IOCP calls the callback when socket\n     * is closed. We poll the ioqueue until all pending callbacks \n     * have been called.\n     */\n    for (i=0; i<50 && tp->is_closing < 1+tp->rdata_cnt; ++i) {\n\tint cnt;\n\tpj_time_val timeout = {0, 1};\n\n\tcnt = pj_ioqueue_poll(pjsip_endpt_get_ioqueue(transport->endpt), \n\t\t\t      &timeout);\n\tif (cnt == 0)\n\t    break;\n    }\n\n    if (tp->grp_lock) {\n\tpj_grp_lock_t *grp_lock = tp->grp_lock;\n\ttp->grp_lock = NULL;\n\tpj_grp_lock_dec_ref(grp_lock);\n\t/* Transport may have been deleted at this point */\n    } else {\n\tudp_on_destroy(tp);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * udp_shutdown()\n *\n * Start graceful UDP shutdown.\n */\nstatic pj_status_t udp_shutdown(pjsip_transport *transport)\n{\n    return pjsip_transport_dec_ref(transport);\n}\n\n\n/* Create socket */\nstatic pj_status_t create_socket(int af, const pj_sockaddr_t *local_a,\n\t\t\t\t int addr_len, pj_sock_t *p_sock)\n{\n    pj_sock_t sock;\n    pj_sockaddr_in tmp_addr;\n    pj_sockaddr_in6 tmp_addr6;\n    pj_status_t status;\n\n    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (local_a == NULL) {\n\tif (af == pj_AF_INET6()) {\n\t    pj_bzero(&tmp_addr6, sizeof(tmp_addr6));\n\t    tmp_addr6.sin6_family = (pj_uint16_t)af;\n\t    local_a = &tmp_addr6;\n\t    addr_len = sizeof(tmp_addr6);\n\t} else {\n\t    pj_sockaddr_in_init(&tmp_addr, NULL, 0);\n\t    local_a = &tmp_addr;\n\t    addr_len = sizeof(tmp_addr);\n\t}\n    }\n\n    status = pj_sock_bind(sock, local_a, addr_len);\n    if (status != PJ_SUCCESS) {\n\tpj_sock_close(sock);\n\treturn status;\n    }\n\n    *p_sock = sock;\n    return PJ_SUCCESS;\n}\n\n\n/* Generate transport's published address */\nstatic pj_status_t get_published_name(pj_sock_t sock,\n\t\t\t\t      char hostbuf[],\n\t\t\t\t      int hostbufsz,\n\t\t\t\t      pjsip_host_port *bound_name)\n{\n    pj_sockaddr tmp_addr;\n    int addr_len;\n    pj_status_t status;\n\n    addr_len = sizeof(tmp_addr);\n    status = pj_sock_getsockname(sock, &tmp_addr, &addr_len);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    bound_name->host.ptr = hostbuf;\n    if (tmp_addr.addr.sa_family == pj_AF_INET()) {\n\tbound_name->port = pj_ntohs(tmp_addr.ipv4.sin_port);\n\n\t/* If bound address specifies \"0.0.0.0\", get the IP address\n\t * of local hostname.\n\t */\n\tif (tmp_addr.ipv4.sin_addr.s_addr == PJ_INADDR_ANY) {\n\t    pj_sockaddr hostip;\n\n\t    status = pj_gethostip(pj_AF_INET(), &hostip);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    pj_strcpy2(&bound_name->host, pj_inet_ntoa(hostip.ipv4.sin_addr));\n\t} else {\n\t    /* Otherwise use bound address. */\n\t    pj_strcpy2(&bound_name->host, \n\t\t       pj_inet_ntoa(tmp_addr.ipv4.sin_addr));\n\t    status = PJ_SUCCESS;\n\t}\n\n    } else {\n\t/* If bound address specifies \"INADDR_ANY\" (IPv6), get the\n         * IP address of local hostname\n         */\n\tpj_uint32_t loop6[4] = { 0, 0, 0, 0};\n\n\tbound_name->port = pj_ntohs(tmp_addr.ipv6.sin6_port);\n\n\tif (pj_memcmp(&tmp_addr.ipv6.sin6_addr, loop6, sizeof(loop6))==0) {\n\t    status = pj_gethostip(tmp_addr.addr.sa_family, &tmp_addr);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\t}\n\n\tstatus = pj_inet_ntop(tmp_addr.addr.sa_family, \n\t\t\t      pj_sockaddr_get_addr(&tmp_addr),\n\t\t\t      hostbuf, hostbufsz);\n\tif (status == PJ_SUCCESS) {\n\t    bound_name->host.slen = pj_ansi_strlen(hostbuf);\n\t}\n    }\n\n\n    return status;\n}\n\n/* Set the published address of the transport */\nstatic void udp_set_pub_name(struct udp_transport *tp,\n\t\t\t     const pjsip_host_port *a_name)\n{\n    enum { INFO_LEN = 80 };\n    char local_addr[PJ_INET6_ADDRSTRLEN+10];\n\n    pj_assert(a_name->host.slen != 0);\n    pj_strdup_with_null(tp->base.pool, &tp->base.local_name.host, \n\t\t\t&a_name->host);\n    tp->base.local_name.port = a_name->port;\n\n    /* Update transport info. */\n    if (tp->base.info == NULL) {\n\ttp->base.info = (char*) pj_pool_alloc(tp->base.pool, INFO_LEN);\n    }\n\n    pj_sockaddr_print(&tp->base.local_addr, local_addr, sizeof(local_addr), 3);\n\n    pj_ansi_snprintf( \n\ttp->base.info, INFO_LEN, \"udp %s [published as %s:%d]\",\n\tlocal_addr,\n\ttp->base.local_name.host.ptr,\n\ttp->base.local_name.port);\n}\n\n/* Set the socket handle of the transport */\nstatic void udp_set_socket(struct udp_transport *tp,\n\t\t\t   pj_sock_t sock,\n\t\t\t   const pjsip_host_port *a_name)\n{\n#if PJSIP_UDP_SO_RCVBUF_SIZE || PJSIP_UDP_SO_SNDBUF_SIZE\n    long sobuf_size;\n    pj_status_t status;\n#endif\n\n    /* Adjust socket rcvbuf size */\n#if PJSIP_UDP_SO_RCVBUF_SIZE\n    sobuf_size = PJSIP_UDP_SO_RCVBUF_SIZE;\n    status = pj_sock_setsockopt(sock, pj_SOL_SOCKET(), pj_SO_RCVBUF(),\n\t\t\t\t&sobuf_size, sizeof(sobuf_size));\n    if (status != PJ_SUCCESS) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\tpj_strerror(status, errmsg, sizeof(errmsg));\n\tPJ_LOG(4,(THIS_FILE, \"Error setting SO_RCVBUF: %s [%d]\", errmsg,\n\t\t  status));\n    }\n#endif\n\n    /* Adjust socket sndbuf size */\n#if PJSIP_UDP_SO_SNDBUF_SIZE\n    sobuf_size = PJSIP_UDP_SO_SNDBUF_SIZE;\n    status = pj_sock_setsockopt(sock, pj_SOL_SOCKET(), pj_SO_SNDBUF(),\n\t\t\t\t&sobuf_size, sizeof(sobuf_size));\n    if (status != PJ_SUCCESS) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\tpj_strerror(status, errmsg, sizeof(errmsg));\n\tPJ_LOG(4,(THIS_FILE, \"Error setting SO_SNDBUF: %s [%d]\", errmsg,\n\t\t  status));\n    }\n#endif\n\n    /* Set the socket. */\n    tp->sock = sock;\n\n    /* Init address name (published address) */\n    udp_set_pub_name(tp, a_name);\n}\n\n/* Register socket to ioqueue */\nstatic pj_status_t register_to_ioqueue(struct udp_transport *tp)\n{\n    pj_ioqueue_t *ioqueue;\n    pj_ioqueue_callback ioqueue_cb;\n    pj_status_t status;\n\n    /* Ignore if already registered */\n    if (tp->key != NULL)\n    \treturn PJ_SUCCESS;\n\n    /* Create group lock */\n    status = pj_grp_lock_create(tp->base.pool, NULL, &tp->grp_lock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_grp_lock_add_ref(tp->grp_lock);\n    pj_grp_lock_add_handler(tp->grp_lock, tp->base.pool, tp, &udp_on_destroy);\n    \n    /* Register to ioqueue. */\n    ioqueue = pjsip_endpt_get_ioqueue(tp->base.endpt);\n    pj_memset(&ioqueue_cb, 0, sizeof(ioqueue_cb));\n    ioqueue_cb.on_read_complete = &udp_on_read_complete;\n    ioqueue_cb.on_write_complete = &udp_on_write_complete;\n\n    return pj_ioqueue_register_sock2(tp->base.pool, ioqueue, tp->sock,\n\t\t\t\t     tp->grp_lock, tp, &ioqueue_cb, &tp->key);\n}\n\n/* Start ioqueue asynchronous reading to all rdata */\nstatic pj_status_t start_async_read(struct udp_transport *tp)\n{\n    int i;\n    pj_status_t status;\n\n    /* Start reading the ioqueue. */\n    for (i=0; i<tp->rdata_cnt; ++i) {\n\tpj_ssize_t size;\n\n\tsize = sizeof(tp->rdata[i]->pkt_info.packet);\n\ttp->rdata[i]->pkt_info.src_addr_len = sizeof(tp->rdata[i]->pkt_info.src_addr);\n\tstatus = pj_ioqueue_recvfrom(tp->key, \n\t\t\t\t     &tp->rdata[i]->tp_info.op_key.op_key,\n\t\t\t\t     tp->rdata[i]->pkt_info.packet,\n\t\t\t\t     &size, PJ_IOQUEUE_ALWAYS_ASYNC,\n\t\t\t\t     &tp->rdata[i]->pkt_info.src_addr,\n\t\t\t\t     &tp->rdata[i]->pkt_info.src_addr_len);\n\tif (status == PJ_SUCCESS) {\n\t    pj_assert(!\"Shouldn't happen because PJ_IOQUEUE_ALWAYS_ASYNC!\");\n\t    udp_on_read_complete(tp->key, &tp->rdata[i]->tp_info.op_key.op_key,\n\t\t\t\t size);\n\t} else if (status != PJ_EPENDING) {\n\t    /* Error! */\n\t    return status;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * pjsip_udp_transport_attach()\n *\n * Attach UDP socket and start transport.\n */\nstatic pj_status_t transport_attach( pjsip_endpoint *endpt,\n\t\t\t\t     pjsip_transport_type_e type,\n\t\t\t\t     pj_sock_t sock,\n\t\t\t\t     const pjsip_host_port *a_name,\n\t\t\t\t     unsigned async_cnt,\n\t\t\t\t     pjsip_transport **p_transport)\n{\n    pj_pool_t *pool;\n    struct udp_transport *tp;\n    const char *format, *ipv6_quoteb, *ipv6_quotee;\n    unsigned i;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(endpt && sock!=PJ_INVALID_SOCKET && a_name && async_cnt>0,\n\t\t     PJ_EINVAL);\n\n    /* Object name. */\n    if (type & PJSIP_TRANSPORT_IPV6) {\n\tformat = \"udpv6%p\";\n\tipv6_quoteb = \"[\";\n\tipv6_quotee = \"]\";\n    } else {\n\tformat = \"udp%p\";\n\tipv6_quoteb = ipv6_quotee = \"\";\n    }\n\n    /* Create pool. */\n    pool = pjsip_endpt_create_pool(endpt, format, PJSIP_POOL_LEN_TRANSPORT, \n\t\t\t\t   PJSIP_POOL_INC_TRANSPORT);\n    if (!pool)\n\treturn PJ_ENOMEM;\n\n    /* Create the UDP transport object. */\n    tp = PJ_POOL_ZALLOC_T(pool, struct udp_transport);\n\n    /* Save pool. */\n    tp->base.pool = pool;\n\n    pj_memcpy(tp->base.obj_name, pool->obj_name, PJ_MAX_OBJ_NAME);\n\n    /* Init reference counter. */\n    status = pj_atomic_create(pool, 0, &tp->base.ref_cnt);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Init lock. */\n    status = pj_lock_create_recursive_mutex(pool, pool->obj_name, \n\t\t\t\t\t    &tp->base.lock);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Set type. */\n    tp->base.key.type = type;\n\n    /* Remote address is left zero (except the family) */\n    tp->base.key.rem_addr.addr.sa_family = (pj_uint16_t)\n\t((type & PJSIP_TRANSPORT_IPV6) ? pj_AF_INET6() : pj_AF_INET());\n\n    /* Type name. */\n    tp->base.type_name = \"UDP\";\n\n    /* Transport flag */\n    tp->base.flag = pjsip_transport_get_flag_from_type(type);\n\n\n    /* Length of addressess. */\n    tp->base.addr_len = sizeof(tp->base.local_addr);\n\n    /* Init local address. */\n    status = pj_sock_getsockname(sock, &tp->base.local_addr, \n\t\t\t\t &tp->base.addr_len);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Init remote name. */\n    if (type == PJSIP_TRANSPORT_UDP)\n\ttp->base.remote_name.host = pj_str(\"0.0.0.0\");\n    else\n\ttp->base.remote_name.host = pj_str(\"::0\");\n    tp->base.remote_name.port = 0;\n\n    /* Init direction */\n    tp->base.dir = PJSIP_TP_DIR_NONE;\n\n    /* Set endpoint. */\n    tp->base.endpt = endpt;\n\n    /* Transport manager and timer will be initialized by tpmgr */\n\n    /* Attach socket and assign name. */\n    udp_set_socket(tp, sock, a_name);\n\n    /* Register to ioqueue */\n    status = register_to_ioqueue(tp);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Set functions. */\n    tp->base.send_msg = &udp_send_msg;\n    tp->base.do_shutdown = &udp_shutdown;\n    tp->base.destroy = &udp_destroy;\n\n    /* This is a permanent transport, so we initialize the ref count\n     * to one so that transport manager don't destroy this transport\n     * when there's no user!\n     */\n    pj_atomic_inc(tp->base.ref_cnt);\n\n    /* Register to transport manager. */\n    tp->base.tpmgr = pjsip_endpt_get_tpmgr(endpt);\n    status = pjsip_transport_register( tp->base.tpmgr, (pjsip_transport*)tp);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n\n    /* Create rdata and put it in the array. */\n    tp->rdata_cnt = 0;\n    tp->rdata = (pjsip_rx_data**)\n    \t\tpj_pool_calloc(tp->base.pool, async_cnt, \n\t\t\t       sizeof(pjsip_rx_data*));\n    for (i=0; i<async_cnt; ++i) {\n\tpj_pool_t *rdata_pool = pjsip_endpt_create_pool(endpt, \"rtd%p\", \n\t\t\t\t\t\t\tPJSIP_POOL_RDATA_LEN,\n\t\t\t\t\t\t\tPJSIP_POOL_RDATA_INC);\n\tif (!rdata_pool) {\n\t    pj_atomic_set(tp->base.ref_cnt, 0);\n\t    pjsip_transport_destroy(&tp->base);\n\t    return PJ_ENOMEM;\n\t}\n\n\tinit_rdata(tp, i, rdata_pool, NULL);\n\ttp->rdata_cnt++;\n    }\n\n    /* Start reading the ioqueue. */\n    status = start_async_read(tp);\n    if (status != PJ_SUCCESS) {\n\tpjsip_transport_destroy(&tp->base);\n\treturn status;\n    }\n\n    /* Done. */\n    if (p_transport)\n\t*p_transport = &tp->base;\n    \n    PJ_LOG(4,(tp->base.obj_name, \n\t      \"SIP %s started, published address is %s%.*s%s:%d\",\n\t      pjsip_transport_get_type_desc((pjsip_transport_type_e)tp->base.key.type),\n\t      ipv6_quoteb,\n\t      (int)tp->base.local_name.host.slen,\n\t      tp->base.local_name.host.ptr,\n\t      ipv6_quotee,\n\t      tp->base.local_name.port));\n\n    return PJ_SUCCESS;\n\non_error:\n    udp_destroy((pjsip_transport*)tp);\n    return status;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_udp_transport_attach( pjsip_endpoint *endpt,\n\t\t\t\t\t\tpj_sock_t sock,\n\t\t\t\t\t\tconst pjsip_host_port *a_name,\n\t\t\t\t\t\tunsigned async_cnt,\n\t\t\t\t\t\tpjsip_transport **p_transport)\n{\n    return transport_attach(endpt, PJSIP_TRANSPORT_UDP, sock, a_name,\n\t\t\t    async_cnt, p_transport);\n}\n\nPJ_DEF(pj_status_t) pjsip_udp_transport_attach2( pjsip_endpoint *endpt,\n\t\t\t\t\t\t pjsip_transport_type_e type,\n\t\t\t\t\t\t pj_sock_t sock,\n\t\t\t\t\t\t const pjsip_host_port *a_name,\n\t\t\t\t\t\t unsigned async_cnt,\n\t\t\t\t\t\t pjsip_transport **p_transport)\n{\n    return transport_attach(endpt, type, sock, a_name,\n\t\t\t    async_cnt, p_transport);\n}\n\n/*\n * pjsip_udp_transport_start()\n *\n * Create a UDP socket in the specified address and start a transport.\n */\nPJ_DEF(pj_status_t) pjsip_udp_transport_start( pjsip_endpoint *endpt,\n\t\t\t\t\t       const pj_sockaddr_in *local_a,\n\t\t\t\t\t       const pjsip_host_port *a_name,\n\t\t\t\t\t       unsigned async_cnt,\n\t\t\t\t\t       pjsip_transport **p_transport)\n{\n    pj_sock_t sock;\n    pj_status_t status;\n    char addr_buf[PJ_INET6_ADDRSTRLEN];\n    pjsip_host_port bound_name;\n\n    PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL);\n\n    status = create_socket(pj_AF_INET(), local_a, sizeof(pj_sockaddr_in), \n\t\t\t   &sock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (a_name == NULL) {\n\t/* Address name is not specified. \n\t * Build a name based on bound address.\n\t */\n\tstatus = get_published_name(sock, addr_buf, sizeof(addr_buf), \n\t\t\t\t    &bound_name);\n\tif (status != PJ_SUCCESS) {\n\t    pj_sock_close(sock);\n\t    return status;\n\t}\n\n\ta_name = &bound_name;\n    }\n\n    return pjsip_udp_transport_attach( endpt, sock, a_name, async_cnt, \n\t\t\t\t       p_transport );\n}\n\n\n/*\n * pjsip_udp_transport_start()\n *\n * Create a UDP socket in the specified address and start a transport.\n */\nPJ_DEF(pj_status_t) pjsip_udp_transport_start6(pjsip_endpoint *endpt,\n\t\t\t\t\t       const pj_sockaddr_in6 *local_a,\n\t\t\t\t\t       const pjsip_host_port *a_name,\n\t\t\t\t\t       unsigned async_cnt,\n\t\t\t\t\t       pjsip_transport **p_transport)\n{\n    pj_sock_t sock;\n    pj_status_t status;\n    char addr_buf[PJ_INET6_ADDRSTRLEN];\n    pjsip_host_port bound_name;\n\n    PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL);\n\n    status = create_socket(pj_AF_INET6(), local_a, sizeof(pj_sockaddr_in6), \n\t\t\t   &sock);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    if (a_name == NULL) {\n\t/* Address name is not specified. \n\t * Build a name based on bound address.\n\t */\n\tstatus = get_published_name(sock, addr_buf, sizeof(addr_buf), \n\t\t\t\t    &bound_name);\n\tif (status != PJ_SUCCESS) {\n\t    pj_sock_close(sock);\n\t    return status;\n\t}\n\n\ta_name = &bound_name;\n    }\n\n    return pjsip_udp_transport_attach2(endpt, PJSIP_TRANSPORT_UDP6,\n\t\t\t\t       sock, a_name, async_cnt, p_transport);\n}\n\n/*\n * Retrieve the internal socket handle used by the UDP transport.\n */\nPJ_DEF(pj_sock_t) pjsip_udp_transport_get_socket(pjsip_transport *transport)\n{\n    struct udp_transport *tp;\n\n    PJ_ASSERT_RETURN(transport != NULL, PJ_INVALID_SOCKET);\n\n    tp = (struct udp_transport*) transport;\n\n    return tp->sock;\n}\n\n\n/*\n * Temporarily pause or shutdown the transport. \n */\nPJ_DEF(pj_status_t) pjsip_udp_transport_pause(pjsip_transport *transport,\n\t\t\t\t\t      unsigned option)\n{\n    struct udp_transport *tp;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(transport != NULL, PJ_EINVAL);\n\n    /* Flag must be specified */\n    PJ_ASSERT_RETURN((option & 0x03) != 0, PJ_EINVAL);\n\n    tp = (struct udp_transport*) transport;\n\n    /* Transport must not have been paused */\n    PJ_ASSERT_RETURN(tp->is_paused==0, PJ_EINVALIDOP);\n\n    /* Set transport to paused first, so that when the read callback is \n     * called by pj_ioqueue_post_completion() it will not try to\n     * re-register the rdata.\n     */\n    tp->is_paused = PJ_TRUE;\n\n    /* Cancel the ioqueue operation. */\n    for (i=0; i<(unsigned)tp->rdata_cnt; ++i) {\n\tpj_ioqueue_post_completion(tp->key, \n\t\t\t\t   &tp->rdata[i]->tp_info.op_key.op_key, -1);\n    }\n\n    /* Destroy the socket? */\n    if (option & PJSIP_UDP_TRANSPORT_DESTROY_SOCKET) {\n\tif (tp->key) {\n\t    /* This implicitly closes the socket */\n\t    pj_ioqueue_unregister(tp->key);\n\t    tp->key = NULL;\n\t} else {\n\t    /* Close socket. */\n\t    if (tp->sock && tp->sock != PJ_INVALID_SOCKET) {\n\t\tpj_sock_close(tp->sock);\n\t\ttp->sock = PJ_INVALID_SOCKET;\n\t    }\n\t}\n\ttp->sock = PJ_INVALID_SOCKET;\n\t\n    }\n\n    PJ_LOG(4,(tp->base.obj_name, \"SIP UDP transport paused\"));\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Restart transport.\n *\n * If option is KEEP_SOCKET, just re-activate ioqueue operation.\n *\n * If option is DESTROY_SOCKET:\n *  - if socket is specified, replace.\n *  - if socket is not specified, create and replace.\n */\nPJ_DEF(pj_status_t) pjsip_udp_transport_restart(pjsip_transport *transport,\n\t\t\t\t\t        unsigned option,\n\t\t\t\t\t\tpj_sock_t sock,\n\t\t\t\t\t\tconst pj_sockaddr_in *local,\n\t\t\t\t\t\tconst pjsip_host_port *a_name)\n{\n    struct udp_transport *tp;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(transport != NULL, PJ_EINVAL);\n    /* Flag must be specified */\n    PJ_ASSERT_RETURN((option & 0x03) != 0, PJ_EINVAL);\n\n    tp = (struct udp_transport*) transport;\n\n    if (option & PJSIP_UDP_TRANSPORT_DESTROY_SOCKET) {\n\tchar addr_buf[PJ_INET6_ADDRSTRLEN];\n\tpjsip_host_port bound_name;\n\n\t/* Request to recreate transport */\n\n\t/* Destroy existing socket, if any. */\n\tif (tp->key) {\n\t    /* This implicitly closes the socket */\n\t    pj_ioqueue_unregister(tp->key);\n\t    tp->key = NULL;\n\t} else {\n\t    /* Close socket. */\n\t    if (tp->sock && tp->sock != PJ_INVALID_SOCKET) {\n\t\tpj_sock_close(tp->sock);\n\t\ttp->sock = PJ_INVALID_SOCKET;\n\t    }\n\t}\n\ttp->sock = PJ_INVALID_SOCKET;\n\n\t/* Create the socket if it's not specified */\n\tif (sock == PJ_INVALID_SOCKET) {\n\t    status = create_socket(pj_AF_INET(), local, \n\t\t\t\t   sizeof(pj_sockaddr_in), &sock);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\t}\n\n\t/* If transport published name is not specified, calculate it\n\t * from the bound address.\n\t */\n\tif (a_name == NULL) {\n\t    status = get_published_name(sock, addr_buf, sizeof(addr_buf),\n\t\t\t\t\t&bound_name);\n\t    if (status != PJ_SUCCESS) {\n\t\tpj_sock_close(sock);\n\t\treturn status;\n\t    }\n\n\t    a_name = &bound_name;\n\t}\n\n        /* Init local address. */\n        status = pj_sock_getsockname(sock, &tp->base.local_addr, \n\t\t\t\t     &tp->base.addr_len);\n        if (status != PJ_SUCCESS) {\n            pj_sock_close(sock);\n            return status;\n        }\n\n\t/* Assign the socket and published address to transport. */\n\tudp_set_socket(tp, sock, a_name);\n\n    } else {\n\n\t/* For KEEP_SOCKET, transport must have been paused before */\n\tPJ_ASSERT_RETURN(tp->is_paused, PJ_EINVALIDOP);\n\n\t/* If address name is specified, update it */\n\tif (a_name != NULL)\n\t    udp_set_pub_name(tp, a_name);\n    }\n\n    /* Re-register new or existing socket to ioqueue. */\n    status = register_to_ioqueue(tp);\n    if (status != PJ_SUCCESS) {\n\treturn status;\n    }\n\n    /* Restart async read operation. */\n    status = start_async_read(tp);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Everything has been set up */\n    tp->is_paused = PJ_FALSE;\n\n    PJ_LOG(4,(tp->base.obj_name, \n\t      \"SIP UDP transport restarted, published address is %.*s:%d\",\n\t      (int)tp->base.local_name.host.slen,\n\t      tp->base.local_name.host.ptr,\n\t      tp->base.local_name.port));\n\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_transport_wrap.cpp",
    "content": "/* $Id: sip_transport_wrap.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * This file is a C++ wrapper, see ticket #886 for details.\n */\n\n#include \"sip_transport.c\"\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_ua_layer.c",
    "content": "/* $Id: sip_ua_layer.c 4420 2013-03-05 11:59:54Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_ua_layer.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_dialog.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_transaction.h>\n#include <pj/os.h>\n#include <pj/hash.h>\n#include <pj/assert.h>\n#include <pj/string.h>\n#include <pj/pool.h>\n#include <pj/log.h>\n\n\n#define THIS_FILE    \"sip_ua_layer.c\"\n\n/*\n * Static prototypes.\n */\nstatic pj_status_t mod_ua_load(pjsip_endpoint *endpt);\nstatic pj_status_t mod_ua_unload(void);\nstatic pj_bool_t   mod_ua_on_rx_request(pjsip_rx_data *rdata);\nstatic pj_bool_t   mod_ua_on_rx_response(pjsip_rx_data *rdata);\nstatic void\t   mod_ua_on_tsx_state(pjsip_transaction*, pjsip_event*);\n\n\nextern long pjsip_dlg_lock_tls_id;\t/* defined in sip_dialog.c */\n\n/* This struct is used to represent list of dialog inside a dialog set.\n * We don't want to use pjsip_dialog for this purpose, to save some\n * memory (about 100 bytes per dialog set).\n */\nstruct dlg_set_head\n{\n    PJ_DECL_LIST_MEMBER(pjsip_dialog);\n};\n\n/* This struct represents a dialog set.\n * This is the value that will be put in the UA's hash table.\n */\nstruct dlg_set\n{\n    /* To put this node in free dlg_set nodes in UA. */\n    PJ_DECL_LIST_MEMBER(struct dlg_set);\n\n    /* This is the buffer to store this entry in the hash table. */\n    pj_hash_entry_buf ht_entry;\n\n    /* List of dialog in this dialog set. */\n    struct dlg_set_head  dlg_list;\n};\n\n\n/*\n * Module interface.\n */\nstatic struct user_agent\n{\n    pjsip_module\t mod;\n    pj_pool_t\t\t*pool;\n    pjsip_endpoint\t*endpt;\n    pj_mutex_t\t\t*mutex;\n    pj_hash_table_t\t*dlg_table;\n    pjsip_ua_init_param  param;\n    struct dlg_set\t free_dlgset_nodes;\n\n} mod_ua = \n{\n  {\n    NULL, NULL,\t\t    /* prev, next.\t\t\t*/\n    { \"mod-ua\", 6 },\t    /* Name.\t\t\t\t*/\n    -1,\t\t\t    /* Id\t\t\t\t*/\n    PJSIP_MOD_PRIORITY_UA_PROXY_LAYER,\t/* Priority\t\t*/\n    &mod_ua_load,\t    /* load()\t\t\t\t*/\n    NULL,\t\t    /* start()\t\t\t\t*/\n    NULL,\t\t    /* stop()\t\t\t\t*/\n    &mod_ua_unload,\t    /* unload()\t\t\t\t*/\n    &mod_ua_on_rx_request,  /* on_rx_request()\t\t\t*/\n    &mod_ua_on_rx_response, /* on_rx_response()\t\t\t*/\n    NULL,\t\t    /* on_tx_request.\t\t\t*/\n    NULL,\t\t    /* on_tx_response()\t\t\t*/\n    &mod_ua_on_tsx_state,   /* on_tsx_state()\t\t\t*/\n  }\n};\n\n/* \n * mod_ua_load()\n *\n * Called when module is being loaded by endpoint.\n */\nstatic pj_status_t mod_ua_load(pjsip_endpoint *endpt)\n{\n    pj_status_t status;\n\n    /* Initialize the user agent. */\n    mod_ua.endpt = endpt;\n    mod_ua.pool = pjsip_endpt_create_pool( endpt, \"ua%p\", PJSIP_POOL_LEN_UA,\n\t\t\t\t\t   PJSIP_POOL_INC_UA);\n    if (mod_ua.pool == NULL)\n\treturn PJ_ENOMEM;\n\n    status = pj_mutex_create_recursive(mod_ua.pool, \" ua%p\", &mod_ua.mutex);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    mod_ua.dlg_table = pj_hash_create(mod_ua.pool, PJSIP_MAX_DIALOG_COUNT);\n    if (mod_ua.dlg_table == NULL)\n\treturn PJ_ENOMEM;\n\n    pj_list_init(&mod_ua.free_dlgset_nodes);\n\n    /* Initialize dialog lock. */\n    status = pj_thread_local_alloc(&pjsip_dlg_lock_tls_id);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_thread_local_set(pjsip_dlg_lock_tls_id, NULL);\n\n    return PJ_SUCCESS;\n\n}\n\n/*\n * mod_ua_unload()\n *\n * Called when module is being unloaded.\n */\nstatic pj_status_t mod_ua_unload(void)\n{\n    pj_thread_local_free(pjsip_dlg_lock_tls_id);\n    pj_mutex_destroy(mod_ua.mutex);\n\n    /* Release pool */\n    if (mod_ua.pool) {\n\tpjsip_endpt_release_pool( mod_ua.endpt, mod_ua.pool );\n    }\n    return PJ_SUCCESS;\n}\n\n/*\n * mod_ua_on_tsx_stats()\n *\n * Called on changed on transaction state.\n */\nstatic void mod_ua_on_tsx_state( pjsip_transaction *tsx, pjsip_event *e)\n{\n    pjsip_dialog *dlg;\n\n    /* Get the dialog where this transaction belongs. */\n    dlg = (pjsip_dialog*) tsx->mod_data[mod_ua.mod.id];\n    \n    /* If dialog instance has gone, it could mean that the dialog\n     * may has been destroyed.\n     */\n    if (dlg == NULL)\n\treturn;\n\n    /* Hand over the event to the dialog. */\n    pjsip_dlg_on_tsx_state(dlg, tsx, e);\n}\n\n\n/*\n * Init user agent module and register it to the endpoint.\n */\nPJ_DEF(pj_status_t) pjsip_ua_init_module( pjsip_endpoint *endpt,\n\t\t\t\t\t  const pjsip_ua_init_param *prm)\n{\n    pj_status_t status;\n\n    /* Check if module already registered. */\n    PJ_ASSERT_RETURN(mod_ua.mod.id == -1, PJ_EINVALIDOP);\n\n    /* Copy param, if exists. */\n    if (prm)\n\tpj_memcpy(&mod_ua.param, prm, sizeof(pjsip_ua_init_param));\n\n    /* Register the module. */\n    status = pjsip_endpt_register_module(endpt, &mod_ua.mod);\n\n    return status;\n}\n\n/*\n * Get the instance of the user agent.\n *\n */\nPJ_DEF(pjsip_user_agent*) pjsip_ua_instance(void)\n{\n    return &mod_ua.mod;\n}\n\n\n/*\n * Get the endpoint where this UA is currently registered.\n */\nPJ_DEF(pjsip_endpoint*) pjsip_ua_get_endpt(pjsip_user_agent *ua)\n{\n    PJ_UNUSED_ARG(ua);\n    pj_assert(ua == &mod_ua.mod);\n    return mod_ua.endpt;\n}\n\n\n/*\n * Destroy the user agent layer.\n */\nPJ_DEF(pj_status_t) pjsip_ua_destroy(void)\n{\n    /* Check if module already destroyed. */\n    PJ_ASSERT_RETURN(mod_ua.mod.id != -1, PJ_EINVALIDOP);\n\n    return pjsip_endpt_unregister_module(mod_ua.endpt, &mod_ua.mod);\n}\n\n\n\n/*\n * Create key to identify dialog set.\n */\n/*\nPJ_DEF(void) pjsip_ua_create_dlg_set_key( pj_pool_t *pool,\n\t\t\t\t\t  pj_str_t *set_key,\n\t\t\t\t\t  const pj_str_t *call_id,\n\t\t\t\t\t  const pj_str_t *local_tag)\n{\n    PJ_ASSERT_ON_FAIL(pool && set_key && call_id && local_tag, return;);\n\n    set_key->slen = call_id->slen + local_tag->slen + 1;\n    set_key->ptr = (char*) pj_pool_alloc(pool, set_key->slen);\n    pj_assert(set_key->ptr != NULL);\n\n    pj_memcpy(set_key->ptr, call_id->ptr, call_id->slen);\n    set_key->ptr[call_id->slen] = '$';\n    pj_memcpy(set_key->ptr + call_id->slen + 1, \n\t      local_tag->ptr, local_tag->slen);\n}\n*/\n\n/*\n * Acquire one dlg_set node to be put in the hash table.\n * This will first look in the free nodes list, then allocate\n * a new one from UA's pool when one is not available.\n */\nstatic struct dlg_set *alloc_dlgset_node(void)\n{\n    struct dlg_set *set;\n\n    if (!pj_list_empty(&mod_ua.free_dlgset_nodes)) {\n\tset = mod_ua.free_dlgset_nodes.next;\n\tpj_list_erase(set);\n\treturn set;\n    } else {\n\tset = PJ_POOL_ALLOC_T(mod_ua.pool, struct dlg_set);\n\treturn set;\n    }\n}\n\n/*\n * Register new dialog. Called by pjsip_dlg_create_uac() and\n * pjsip_dlg_create_uas_and_inc_lock();\n */\nPJ_DEF(pj_status_t) pjsip_ua_register_dlg( pjsip_user_agent *ua,\n\t\t\t\t\t   pjsip_dialog *dlg )\n{\n    /* Sanity check. */\n    PJ_ASSERT_RETURN(ua && dlg, PJ_EINVAL);\n\n    /* For all dialogs, local tag (inc hash) must has been initialized. */\n    PJ_ASSERT_RETURN(dlg->local.info && dlg->local.info->tag.slen &&\n\t\t     dlg->local.tag_hval != 0, PJ_EBUG);\n\n    /* For UAS dialog, remote tag (inc hash) must have been initialized. */\n    //PJ_ASSERT_RETURN(dlg->role==PJSIP_ROLE_UAC ||\n    //\t\t     (dlg->role==PJSIP_ROLE_UAS && dlg->remote.info->tag.slen\n    //\t\t      && dlg->remote.tag_hval != 0), PJ_EBUG);\n\n    /* Lock the user agent. */\n    pj_mutex_lock(mod_ua.mutex);\n\n    /* For UAC, check if there is existing dialog in the same set. */\n    if (dlg->role == PJSIP_ROLE_UAC) {\n\tstruct dlg_set *dlg_set;\n\n\tdlg_set = (struct dlg_set*)\n\t\t  pj_hash_get_lower( mod_ua.dlg_table,\n                                     dlg->local.info->tag.ptr, \n\t\t\t             (unsigned)dlg->local.info->tag.slen,\n\t\t\t             &dlg->local.tag_hval);\n\n\tif (dlg_set) {\n\t    /* This is NOT the first dialog in the dialog set. \n\t     * Just add this dialog in the list.\n\t     */\n\t    pj_assert(dlg_set->dlg_list.next != (void*)&dlg_set->dlg_list);\n\t    pj_list_push_back(&dlg_set->dlg_list, dlg);\n\n\t    dlg->dlg_set = dlg_set;\n\n\t} else {\n\t    /* This is the first dialog in the dialog set. \n\t     * Create the dialog set and add this dialog to it.\n\t     */\n\t    dlg_set = alloc_dlgset_node();\n\t    pj_list_init(&dlg_set->dlg_list);\n\t    pj_list_push_back(&dlg_set->dlg_list, dlg);\n\n\t    dlg->dlg_set = dlg_set;\n\n\t    /* Register the dialog set in the hash table. */\n\t    pj_hash_set_np_lower(mod_ua.dlg_table, \n\t\t\t         dlg->local.info->tag.ptr,\n                                 (unsigned)dlg->local.info->tag.slen,\n\t\t\t         dlg->local.tag_hval, dlg_set->ht_entry,\n                                 dlg_set);\n\t}\n\n    } else {\n\t/* For UAS, create the dialog set with a single dialog as member. */\n\tstruct dlg_set *dlg_set;\n\n\tdlg_set = alloc_dlgset_node();\n\tpj_list_init(&dlg_set->dlg_list);\n\tpj_list_push_back(&dlg_set->dlg_list, dlg);\n\n\tdlg->dlg_set = dlg_set;\n\n\tpj_hash_set_np_lower(mod_ua.dlg_table, \n\t\t             dlg->local.info->tag.ptr,\n                             (unsigned)dlg->local.info->tag.slen,\n\t\t             dlg->local.tag_hval, dlg_set->ht_entry, dlg_set);\n    }\n\n    /* Unlock user agent. */\n    pj_mutex_unlock(mod_ua.mutex);\n\n    /* Done. */\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_ua_unregister_dlg( pjsip_user_agent *ua,\n\t\t\t\t\t     pjsip_dialog *dlg )\n{\n    struct dlg_set *dlg_set;\n    pjsip_dialog *d;\n\n    /* Sanity-check arguments. */\n    PJ_ASSERT_RETURN(ua && dlg, PJ_EINVAL);\n\n    /* Check that dialog has been registered. */\n    PJ_ASSERT_RETURN(dlg->dlg_set, PJ_EINVALIDOP);\n\n    /* Lock user agent. */\n    pj_mutex_lock(mod_ua.mutex);\n\n    /* Find this dialog from the dialog set. */\n    dlg_set = (struct dlg_set*) dlg->dlg_set;\n    d = dlg_set->dlg_list.next;\n    while (d != (pjsip_dialog*)&dlg_set->dlg_list && d != dlg) {\n\td = d->next;\n    }\n\n    if (d != dlg) {\n\tpj_assert(!\"Dialog is not registered!\");\n\tpj_mutex_unlock(mod_ua.mutex);\n\treturn PJ_EINVALIDOP;\n    }\n\n    /* Remove this dialog from the list. */\n    pj_list_erase(dlg);\n\n    /* If dialog list is empty, remove the dialog set from the hash table. */\n    if (pj_list_empty(&dlg_set->dlg_list)) {\n\tpj_hash_set_lower(NULL, mod_ua.dlg_table, dlg->local.info->tag.ptr,\n\t\t          (unsigned)dlg->local.info->tag.slen, \n\t\t\t  dlg->local.tag_hval, NULL);\n\n\t/* Return dlg_set to free nodes. */\n\tpj_list_push_back(&mod_ua.free_dlgset_nodes, dlg_set);\n    }\n\n    /* Unlock user agent. */\n    pj_mutex_unlock(mod_ua.mutex);\n\n    /* Done. */\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pjsip_dialog*) pjsip_rdata_get_dlg( pjsip_rx_data *rdata )\n{\n    return (pjsip_dialog*) rdata->endpt_info.mod_data[mod_ua.mod.id];\n}\n\nPJ_DEF(pjsip_dialog*) pjsip_tsx_get_dlg( pjsip_transaction *tsx )\n{\n    return (pjsip_dialog*) tsx->mod_data[mod_ua.mod.id];\n}\n\n\n/*\n * Retrieve the current number of dialog-set currently registered\n * in the hash table. \n */\nPJ_DEF(unsigned) pjsip_ua_get_dlg_set_count(void)\n{\n    unsigned count;\n\n    PJ_ASSERT_RETURN(mod_ua.endpt, 0);\n\n    pj_mutex_lock(mod_ua.mutex);\n    count = pj_hash_count(mod_ua.dlg_table);\n    pj_mutex_unlock(mod_ua.mutex);\n\n    return count;\n}\n\n\n/* \n * Find a dialog.\n */\nPJ_DEF(pjsip_dialog*) pjsip_ua_find_dialog(const pj_str_t *call_id,\n\t\t\t\t\t   const pj_str_t *local_tag,\n\t\t\t\t\t   const pj_str_t *remote_tag,\n\t\t\t\t\t   pj_bool_t lock_dialog)\n{\n    struct dlg_set *dlg_set;\n    pjsip_dialog *dlg;\n\n    PJ_ASSERT_RETURN(call_id && local_tag && remote_tag, NULL);\n\n    /* Lock user agent. */\n    pj_mutex_lock(mod_ua.mutex);\n\n    /* Lookup the dialog set. */\n    dlg_set = (struct dlg_set*)\n    \t      pj_hash_get_lower(mod_ua.dlg_table, local_tag->ptr,\n                                (unsigned)local_tag->slen, NULL);\n    if (dlg_set == NULL) {\n\t/* Not found */\n\tpj_mutex_unlock(mod_ua.mutex);\n\treturn NULL;\n    }\n\n    /* Dialog set is found, now find the matching dialog based on the\n     * remote tag.\n     */\n    dlg = dlg_set->dlg_list.next;\n    while (dlg != (pjsip_dialog*)&dlg_set->dlg_list) {\t\n\tif (pj_stricmp(&dlg->remote.info->tag, remote_tag) == 0)\n\t    break;\n\tdlg = dlg->next;\n    }\n\n    if (dlg == (pjsip_dialog*)&dlg_set->dlg_list) {\n\t/* Not found */\n\tpj_mutex_unlock(mod_ua.mutex);\n\treturn NULL;\n    }\n\n    /* Dialog has been found. It SHOULD have the right Call-ID!! */\n    if (pj_strcmp(&dlg->call_id->id, call_id)!=0) {\n\n\tPJ_LOG(6, (THIS_FILE, \"Dialog not found: local and remote tags \"\n\t\t              \"matched but not call id\"));\n\n        pj_mutex_unlock(mod_ua.mutex);\n        return NULL;\n    }\n\n    if (lock_dialog) {\n\tif (pjsip_dlg_try_inc_lock(dlg) != PJ_SUCCESS) {\n\n\t    /*\n\t     * Unable to acquire dialog's lock while holding the user\n\t     * agent's mutex. Release the UA mutex before retrying once\n\t     * more.\n\t     *\n\t     * THIS MAY CAUSE RACE CONDITION!\n\t     */\n\n\t    /* Unlock user agent. */\n\t    pj_mutex_unlock(mod_ua.mutex);\n\t    /* Lock dialog */\n\t    pjsip_dlg_inc_lock(dlg);\n\n\t} else {\n\t    /* Unlock user agent. */\n\t    pj_mutex_unlock(mod_ua.mutex);\n\t}\n\n    } else {\n\t/* Unlock user agent. */\n\tpj_mutex_unlock(mod_ua.mutex);\n    }\n\n    return dlg;\n}\n\n\n/*\n * Find the first dialog in dialog set in hash table for an incoming message.\n */\nstatic struct dlg_set *find_dlg_set_for_msg( pjsip_rx_data *rdata )\n{\n    /* CANCEL message doesn't have To tag, so we must lookup the dialog\n     * by finding the INVITE UAS transaction being cancelled.\n     */\n    if (rdata->msg_info.cseq->method.id == PJSIP_CANCEL_METHOD) {\n\n\tpjsip_dialog *dlg;\n\n\t/* Create key for the rdata, but this time, use INVITE as the\n\t * method.\n\t */\n\tpj_str_t key;\n\tpjsip_role_e role;\n\tpjsip_transaction *tsx;\n\n\tif (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG)\n\t    role = PJSIP_ROLE_UAS;\n\telse\n\t    role = PJSIP_ROLE_UAC;\n\n\tpjsip_tsx_create_key(rdata->tp_info.pool, &key, role, \n\t\t\t     pjsip_get_invite_method(), rdata);\n\n\t/* Lookup the INVITE transaction */\n\ttsx = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE);\n\n\t/* We should find the dialog attached to the INVITE transaction */\n\tif (tsx) {\n\t    dlg = (pjsip_dialog*) tsx->mod_data[mod_ua.mod.id];\n\t    pj_grp_lock_release(tsx->grp_lock);\n\n\t    /* Dlg may be NULL on some extreme condition\n\t     * (e.g. during debugging where initially there is a dialog)\n\t     */\n\t    return dlg ? (struct dlg_set*) dlg->dlg_set : NULL;\n\n\t} else {\n\t    return NULL;\n\t}\n\n\n    } else {\n\tpj_str_t *tag;\n\tstruct dlg_set *dlg_set;\n\n\tif (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG)\n\t    tag = &rdata->msg_info.to->tag;\n\telse\n\t    tag = &rdata->msg_info.from->tag;\n\n\t/* Lookup the dialog set. */\n\tdlg_set = (struct dlg_set*)\n\t\t  pj_hash_get_lower(mod_ua.dlg_table, tag->ptr, \n\t\t\t\t    (unsigned)tag->slen, NULL);\n\treturn dlg_set;\n    }\n}\n\n/* On received requests. */\nstatic pj_bool_t mod_ua_on_rx_request(pjsip_rx_data *rdata)\n{\n    struct dlg_set *dlg_set;\n    pj_str_t *from_tag;\n    pjsip_dialog *dlg;\n    pj_status_t status;\n\n    /* Optimized path: bail out early if request is not CANCEL and it doesn't\n     * have To tag \n     */\n    if (rdata->msg_info.to->tag.slen == 0 && \n\trdata->msg_info.msg->line.req.method.id != PJSIP_CANCEL_METHOD)\n    {\n\treturn PJ_FALSE;\n    }\n\n    /* Incoming REGISTER may have tags in it */\n    if (rdata->msg_info.msg->line.req.method.id == PJSIP_REGISTER_METHOD)\n\treturn PJ_FALSE;\n\nretry_on_deadlock:\n\n    /* Lock user agent before looking up the dialog hash table. */\n    pj_mutex_lock(mod_ua.mutex);\n\n    /* Lookup the dialog set, based on the To tag header. */\n    dlg_set = find_dlg_set_for_msg(rdata);\n\n    /* If dialog is not found, respond with 481 (Call/Transaction\n     * Does Not Exist).\n     */\n    if (dlg_set == NULL) {\n\t/* Unable to find dialog. */\n\tpj_mutex_unlock(mod_ua.mutex);\n\n\tif (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {\n\t    PJ_LOG(5,(THIS_FILE, \n\t\t      \"Unable to find dialogset for %s, answering with 481\",\n\t\t      pjsip_rx_data_get_info(rdata)));\n\n\t    /* Respond with 481 . */\n\t    pjsip_endpt_respond_stateless( mod_ua.endpt, rdata, 481, NULL, \n\t\t\t\t\t   NULL, NULL );\n\t}\n\treturn PJ_TRUE;\n    }\n\n    /* Dialog set has been found.\n     * Find the dialog in the dialog set based on the content of the remote \n     * tag.\n     */\n    from_tag = &rdata->msg_info.from->tag;\n    dlg = dlg_set->dlg_list.next;\n    while (dlg != (pjsip_dialog*)&dlg_set->dlg_list) {\n\t\n\tif (pj_stricmp(&dlg->remote.info->tag, from_tag) == 0)\n\t    break;\n\n\tdlg = dlg->next;\n    }\n\n    /* Dialog may not be found, e.g. in this case:\n     *\t- UAC sends SUBSCRIBE, then UAS sends NOTIFY before answering\n     *    SUBSCRIBE request with 2xx.\n     *\n     * In this case, we can accept the request ONLY when the original \n     * dialog still has empty To tag.\n     */\n    if (dlg == (pjsip_dialog*)&dlg_set->dlg_list) {\n\n\tpjsip_dialog *first_dlg = dlg_set->dlg_list.next;\n\n\tif (first_dlg->remote.info->tag.slen != 0) {\n\t    /* Not found. Mulfunction UAC? */\n\t    pj_mutex_unlock(mod_ua.mutex);\n\n\t    if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {\n\t\tPJ_LOG(5,(THIS_FILE, \n\t\t          \"Unable to find dialog for %s, answering with 481\",\n\t\t          pjsip_rx_data_get_info(rdata)));\n\n\t\tpjsip_endpt_respond_stateless(mod_ua.endpt, rdata,\n\t\t\t\t\t      PJSIP_SC_CALL_TSX_DOES_NOT_EXIST, \n\t\t\t\t\t      NULL, NULL, NULL);\n\t    } else {\n\t\tPJ_LOG(5,(THIS_FILE, \n\t\t          \"Unable to find dialog for %s\",\n\t\t          pjsip_rx_data_get_info(rdata)));\n\t    }\n\t    return PJ_TRUE;\n\t}\n\n\tdlg = first_dlg;\n    }\n\n    /* Mark the dialog id of the request. */\n    rdata->endpt_info.mod_data[mod_ua.mod.id] = dlg;\n\n    /* Try to lock the dialog */\n    PJ_LOG(6,(dlg->obj_name, \"UA layer acquiring dialog lock for request\"));\n    status = pjsip_dlg_try_inc_lock(dlg);\n    if (status != PJ_SUCCESS) {\n\t/* Failed to acquire dialog mutex immediately, this could be \n\t * because of deadlock. Release UA mutex, yield, and retry \n\t * the whole thing once again.\n\t */\n\tpj_mutex_unlock(mod_ua.mutex);\n\tpj_thread_sleep(0);\n\tgoto retry_on_deadlock;\n    }\n\n    /* Done with processing in UA layer, release lock */\n    pj_mutex_unlock(mod_ua.mutex);\n\n    /* Pass to dialog. */\n    pjsip_dlg_on_rx_request(dlg, rdata);\n\n    /* Unlock the dialog. This may destroy the dialog */\n    pjsip_dlg_dec_lock(dlg);\n\n    /* Report as handled. */\n    return PJ_TRUE;\n}\n\n\n/* On rx response notification.\n */\nstatic pj_bool_t mod_ua_on_rx_response(pjsip_rx_data *rdata)\n{\n    pjsip_transaction *tsx;\n    struct dlg_set *dlg_set;\n    pjsip_dialog *dlg;\n    pj_status_t status;\n\n    /*\n     * Find the dialog instance for the response.\n     * All outgoing dialog requests are sent statefully, which means\n     * there will be an UAC transaction associated with this response,\n     * and the dialog instance will be recorded in that transaction.\n     *\n     * But even when transaction is found, there is possibility that\n     * the response is a forked response.\n     */\n\nretry_on_deadlock:\n\n    dlg = NULL;\n\n    /* Lock user agent dlg table before we're doing anything. */\n    pj_mutex_lock(mod_ua.mutex);\n\n    /* Check if transaction is present. */\n    tsx = pjsip_rdata_get_tsx(rdata);\n    if (tsx) {\n\t/* Check if dialog is present in the transaction. */\n\tdlg = pjsip_tsx_get_dlg(tsx);\n\tif (!dlg) {\n\t    /* Unlock dialog hash table. */\n\t    pj_mutex_unlock(mod_ua.mutex);\n\t    return PJ_FALSE;\n\t}\n\n\t/* Get the dialog set. */\n\tdlg_set = (struct dlg_set*) dlg->dlg_set;\n\n\t/* Even if transaction is found and (candidate) dialog has been \n\t * identified, it's possible that the request has forked.\n\t */\n\n    } else {\n\t/* Transaction is not present.\n\t * Check if this is a 2xx/OK response to INVITE, which in this\n\t * case the response will be handled directly by the\n\t * dialog.\n\t */\n\tpjsip_cseq_hdr *cseq_hdr = rdata->msg_info.cseq;\n\n\tif (cseq_hdr->method.id != PJSIP_INVITE_METHOD ||\n\t    rdata->msg_info.msg->line.status.code / 100 != 2)\n\t{\n\t    /* Not a 2xx response to INVITE.\n\t     * This must be some stateless response sent by other modules,\n\t     * or a very late response.\n\t     */\n\t    /* Unlock dialog hash table. */\n\t    pj_mutex_unlock(mod_ua.mutex);\n\t    return PJ_FALSE;\n\t}\n\n\n\t/* Get the dialog set. */\n\tdlg_set = (struct dlg_set*)\n\t\t  pj_hash_get_lower(mod_ua.dlg_table, \n\t\t\t            rdata->msg_info.from->tag.ptr,\n\t\t\t            (unsigned)rdata->msg_info.from->tag.slen,\n\t\t\t            NULL);\n\n\tif (!dlg_set) {\n\t    /* Unlock dialog hash table. */\n\t    pj_mutex_unlock(mod_ua.mutex);\n\n\t    /* Strayed 2xx response!! */\n\t    PJ_LOG(4,(THIS_FILE, \n\t\t      \"Received strayed 2xx response (no dialog is found)\"\n\t\t      \" from %s:%d: %s\",\n\t\t      rdata->pkt_info.src_name, rdata->pkt_info.src_port,\n\t\t      pjsip_rx_data_get_info(rdata)));\n\n\t    return PJ_TRUE;\n\t}\n    }\n\n    /* At this point, we must have the dialog set, and the dialog set\n     * must have a dialog in the list.\n     */\n    pj_assert(dlg_set && !pj_list_empty(&dlg_set->dlg_list));\n\n    /* Check for forked response. \n     * Request will fork only for the initial INVITE request.\n     */\n\n    //This doesn't work when there is authentication challenge, since \n    //first_cseq evaluation will yield false.\n    //if (rdata->msg_info.cseq->method.id == PJSIP_INVITE_METHOD &&\n    //\trdata->msg_info.cseq->cseq == dlg_set->dlg_list.next->local.first_cseq)\n\n    if (rdata->msg_info.cseq->method.id == PJSIP_INVITE_METHOD) {\n\t\n\tint st_code = rdata->msg_info.msg->line.status.code;\n\tpj_str_t *to_tag = &rdata->msg_info.to->tag;\n\n\tdlg = dlg_set->dlg_list.next;\n\n\twhile (dlg != (pjsip_dialog*)&dlg_set->dlg_list) {\n\n\t    /* If there is dialog with no remote tag (i.e. dialog has not\n\t     * been established yet), then send this response to that\n\t     * dialog.\n\t     */\n\t    if (dlg->remote.info->tag.slen == 0)\n\t\tbreak;\n\n\t    /* Otherwise find the one with matching To tag. */\n\t    if (pj_stricmp(to_tag, &dlg->remote.info->tag) == 0)\n\t\tbreak;\n\n\t    dlg = dlg->next;\n\t}\n\n\t/* If no dialog with matching remote tag is found, this must be\n\t * a forked response. Respond to this ONLY when response is non-100\n\t * provisional response OR a 2xx response.\n\t */\n\tif (dlg == (pjsip_dialog*)&dlg_set->dlg_list &&\n\t    ((st_code/100==1 && st_code!=100) || st_code/100==2)) \n\t{\n\n\t    PJ_LOG(5,(THIS_FILE, \n\t\t      \"Received forked %s for existing dialog %s\",\n\t\t      pjsip_rx_data_get_info(rdata), \n\t\t      dlg_set->dlg_list.next->obj_name));\n\n\t    /* Report to application about forked condition.\n\t     * Application can either create a dialog or ignore the response.\n\t     */\n\t    if (mod_ua.param.on_dlg_forked) {\n\t\tdlg = (*mod_ua.param.on_dlg_forked)(dlg_set->dlg_list.next, \n\t\t\t\t\t\t    rdata);\n\t\tif (dlg == NULL) {\n\t\t    pj_mutex_unlock(mod_ua.mutex);\n\t\t    return PJ_TRUE;\n\t\t}\n\t    } else {\n\t\tdlg = dlg_set->dlg_list.next;\n\n\t\tPJ_LOG(4,(THIS_FILE, \n\t\t\t  \"Unhandled forked %s from %s:%d, response will be \"\n\t\t\t  \"handed over to the first dialog\",\n\t\t\t  pjsip_rx_data_get_info(rdata),\n\t\t\t  rdata->pkt_info.src_name, rdata->pkt_info.src_port));\n\t    }\n\n\t} else if (dlg == (pjsip_dialog*)&dlg_set->dlg_list) {\n\n\t    /* For 100 or non-2xx response which has different To tag,\n\t     * pass the response to the first dialog.\n\t     */\n\n\t    dlg = dlg_set->dlg_list.next;\n\n\t}\n\n    } else {\n\t/* Either this is a non-INVITE response, or subsequent INVITE\n\t * within dialog. The dialog should have been identified when\n\t * the transaction was found.\n\t */\n\tpj_assert(tsx != NULL);\n\tpj_assert(dlg != NULL);\n    }\n\n    /* The dialog must have been found. */\n    pj_assert(dlg != NULL);\n\n    /* Put the dialog instance in the rdata. */\n    rdata->endpt_info.mod_data[mod_ua.mod.id] = dlg;\n\n    /* Attempt to acquire lock to the dialog. */\n    PJ_LOG(6,(dlg->obj_name, \"UA layer acquiring dialog lock for response\"));\n    status = pjsip_dlg_try_inc_lock(dlg);\n    if (status != PJ_SUCCESS) {\n\t/* Failed to acquire dialog mutex. This could indicate a deadlock\n\t * situation, and for safety, try to avoid deadlock by releasing\n\t * UA mutex, yield, and retry the whole processing once again.\n\t */\n\tpj_mutex_unlock(mod_ua.mutex);\n\tpj_thread_sleep(0);\n\tgoto retry_on_deadlock;\n    }\n\n    /* We're done with processing in the UA layer, we can release the mutex */\n    pj_mutex_unlock(mod_ua.mutex);\n\n    /* Pass the response to the dialog. */\n    pjsip_dlg_on_rx_response(dlg, rdata);\n\n    /* Unlock the dialog. This may destroy the dialog. */\n    pjsip_dlg_dec_lock(dlg);\n\n    /* Done. */\n    return PJ_TRUE;\n}\n\n\n#if PJ_LOG_MAX_LEVEL >= 3\nstatic void print_dialog( const char *title,\n\t\t\t  pjsip_dialog *dlg, char *buf, pj_size_t size)\n{\n    int len;\n    char userinfo[128];\n\n    len = pjsip_hdr_print_on(dlg->remote.info, userinfo, sizeof(userinfo));\n    if (len < 0)\n\tpj_ansi_strcpy(userinfo, \"<--uri too long-->\");\n    else\n\tuserinfo[len] = '\\0';\n    \n    len = pj_ansi_snprintf(buf, size, \"%s[%s]  %s\",\n\t\t\t   title,\n\t\t\t   (dlg->state==PJSIP_DIALOG_STATE_NULL ? \" - \" :\n\t\t\t\t\t\t\t     \"est\"),\n\t\t      userinfo);\n    if (len < 1 || len >= (int)size) {\n\tpj_ansi_strcpy(buf, \"<--uri too long-->\");\n    } else\n\tbuf[len] = '\\0';\n}\n#endif\n\n/*\n * Dump user agent contents (e.g. all dialogs).\n */\nPJ_DEF(void) pjsip_ua_dump(pj_bool_t detail)\n{\n#if PJ_LOG_MAX_LEVEL >= 3\n    pj_hash_iterator_t itbuf, *it;\n    char dlginfo[128];\n\n    pj_mutex_lock(mod_ua.mutex);\n\n    PJ_LOG(3, (THIS_FILE, \"Number of dialog sets: %u\", \n\t\t\t  pj_hash_count(mod_ua.dlg_table)));\n\n    if (detail && pj_hash_count(mod_ua.dlg_table)) {\n\tPJ_LOG(3, (THIS_FILE, \"Dumping dialog sets:\"));\n\tit = pj_hash_first(mod_ua.dlg_table, &itbuf);\n\tfor (; it != NULL; it = pj_hash_next(mod_ua.dlg_table, it))  {\n\t    struct dlg_set *dlg_set;\n\t    pjsip_dialog *dlg;\n\t    const char *title;\n\n\t    dlg_set = (struct dlg_set*) pj_hash_this(mod_ua.dlg_table, it);\n\t    if (!dlg_set || pj_list_empty(&dlg_set->dlg_list)) continue;\n\n\t    /* First dialog in dialog set. */\n\t    dlg = dlg_set->dlg_list.next;\n\t    if (dlg->role == PJSIP_ROLE_UAC)\n\t\ttitle = \"  [out] \";\n\t    else\n\t\ttitle = \"  [in]  \";\n\n\t    print_dialog(title, dlg, dlginfo, sizeof(dlginfo));\n\t    PJ_LOG(3,(THIS_FILE, \"%s\", dlginfo));\n\n\t    /* Next dialog in dialog set (forked) */\n\t    dlg = dlg->next;\n\t    while (dlg != (pjsip_dialog*) &dlg_set->dlg_list) {\n\t\tprint_dialog(\"    [forked] \", dlg, dlginfo, sizeof(dlginfo));\n\t\tdlg = dlg->next;\n\t    }\n\t}\n    }\n\n    pj_mutex_unlock(mod_ua.mutex);\n#endif\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_uri.c",
    "content": "/* $Id: sip_uri.c 4228 2012-08-13 07:26:03Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_uri.h>\n#include <pjsip/sip_msg.h>\n#include <pjsip/sip_parser.h>\n#include <pjsip/print_util.h>\n#include <pjsip/sip_errno.h>\n#include <pjlib-util/string.h>\n#include <pj/string.h>\n#include <pj/pool.h>\n#include <pj/assert.h>\n\n/*\n * Generic parameter manipulation.\n */\nPJ_DEF(pjsip_param*) pjsip_param_find(  const pjsip_param *param_list,\n\t\t\t\t\tconst pj_str_t *name )\n{\n    pjsip_param *p = (pjsip_param*)param_list->next;\n    while (p != param_list) {\n\tif (pj_stricmp(&p->name, name)==0)\n\t    return p;\n\tp = p->next;\n    }\n    return NULL;\n}\n\nPJ_DEF(int) pjsip_param_cmp( const pjsip_param *param_list1,\n\t\t\t     const pjsip_param *param_list2,\n\t\t\t     pj_bool_t ig_nf)\n{\n    const pjsip_param *p1;\n\n    if ((ig_nf & 1)==0 && pj_list_size(param_list1)!=pj_list_size(param_list2))\n\treturn 1;\n\n    p1 = param_list1->next;\n    while (p1 != param_list1) {\n\tconst pjsip_param *p2;\n\tp2 = pjsip_param_find(param_list2, &p1->name);\n\tif (p2 ) {\n\t    int rc = pj_stricmp(&p1->value, &p2->value);\n\t    if (rc != 0)\n\t\treturn rc;\n\t} else if ((ig_nf & 1)==0)\n\t    return 1;\n\n\tp1 = p1->next;\n    }\n\n    return 0;\n}\n\nPJ_DEF(void) pjsip_param_clone( pj_pool_t *pool, pjsip_param *dst_list,\n\t\t\t\tconst pjsip_param *src_list)\n{\n    const pjsip_param *p = src_list->next;\n\n    pj_list_init(dst_list);\n    while (p && p != src_list) {\n\tpjsip_param *new_param = PJ_POOL_ALLOC_T(pool, pjsip_param);\n\tpj_strdup(pool, &new_param->name, &p->name);\n\tpj_strdup(pool, &new_param->value, &p->value);\n\tpj_list_insert_before(dst_list, new_param);\n\tp = p->next;\n    }\n}\n\n\nPJ_DEF(void) pjsip_param_shallow_clone( pj_pool_t *pool, \n\t\t\t\t\tpjsip_param *dst_list,\n\t\t\t\t\tconst pjsip_param *src_list)\n{\n    const pjsip_param *p = src_list->next;\n\n    pj_list_init(dst_list);\n    while (p != src_list) {\n\tpjsip_param *new_param = PJ_POOL_ALLOC_T(pool, pjsip_param);\n\tnew_param->name = p->name;\n\tnew_param->value = p->value;\n\tpj_list_insert_before(dst_list, new_param);\n\tp = p->next;\n    }\n}\n\nPJ_DEF(pj_ssize_t) pjsip_param_print_on( const pjsip_param *param_list,\n\t\t\t\t\t char *buf, pj_size_t size,\n\t\t\t\t\t const pj_cis_t *pname_spec,\n\t\t\t\t\t const pj_cis_t *pvalue_spec,\n\t\t\t\t\t int sep)\n{\n    const pjsip_param *p;\n    char *startbuf;\n    char *endbuf;\n    int printed;\n\n    p = param_list->next;\n    if (p == NULL || p == param_list)\n\treturn 0;\n\n    startbuf = buf;\n    endbuf = buf + size;\n\n    PJ_UNUSED_ARG(pname_spec);\n\n    do {\n\tcopy_advance_char_check(buf, (char)sep);\n\tcopy_advance_escape(buf, p->name, (*pname_spec));\n\tif (p->value.slen) {\n\t    copy_advance_char_check(buf, '=');\n\t    if (*p->value.ptr == '\"')\n\t\tcopy_advance(buf, p->value);\n\t    else\n\t\tcopy_advance_escape(buf, p->value, (*pvalue_spec));\n\t}\n\tp = p->next;\n\tif (sep == '?') sep = '&';\n    } while (p != param_list);\n\n    return buf-startbuf;\n}\n\n\n/*\n * URI stuffs\n */\n#define IS_SIPS(url)\t((url)->vptr==&sips_url_vptr)\n\nstatic const pj_str_t *pjsip_url_get_scheme( const pjsip_sip_uri* );\nstatic const pj_str_t *pjsips_url_get_scheme( const pjsip_sip_uri* );\nstatic const pj_str_t *pjsip_name_addr_get_scheme( const pjsip_name_addr * );\nstatic void *pjsip_get_uri( pjsip_uri *uri );\nstatic void *pjsip_name_addr_get_uri( pjsip_name_addr *name );\n\nstatic pj_str_t sip_str = { \"sip\", 3 };\nstatic pj_str_t sips_str = { \"sips\", 4 };\n\nstatic pjsip_name_addr* pjsip_name_addr_clone( pj_pool_t *pool, \n\t\t\t\t\t       const pjsip_name_addr *rhs);\nstatic pj_ssize_t pjsip_name_addr_print(pjsip_uri_context_e context,\n\t\t\t\t\tconst pjsip_name_addr *name, \n\t\t\t\t\tchar *buf, pj_size_t size);\nstatic int pjsip_name_addr_compare(  pjsip_uri_context_e context,\n\t\t\t\t     const pjsip_name_addr *naddr1,\n\t\t\t\t     const pjsip_name_addr *naddr2);\nstatic pj_ssize_t pjsip_url_print(  pjsip_uri_context_e context,\n\t\t\t\t    const pjsip_sip_uri *url, \n\t\t\t\t    char *buf, pj_size_t size);\nstatic int pjsip_url_compare( pjsip_uri_context_e context,\n\t\t\t      const pjsip_sip_uri *url1, \n\t\t\t      const pjsip_sip_uri *url2);\nstatic pjsip_sip_uri* pjsip_url_clone(pj_pool_t *pool, \n\t\t\t\t      const pjsip_sip_uri *rhs);\n\ntypedef const pj_str_t* (*P_GET_SCHEME)(const void*);\ntypedef void* \t\t(*P_GET_URI)(void*);\ntypedef pj_ssize_t \t(*P_PRINT_URI)(pjsip_uri_context_e,const void *,\n\t\t\t\t       char*,pj_size_t);\ntypedef int \t\t(*P_CMP_URI)(pjsip_uri_context_e, const void*, \n\t\t\t\t     const void*);\ntypedef void* \t\t(*P_CLONE)(pj_pool_t*, const void*);\n\n\nstatic pjsip_uri_vptr sip_url_vptr = \n{\n    (P_GET_SCHEME)\t&pjsip_url_get_scheme,\n    (P_GET_URI)\t\t&pjsip_get_uri,\n    (P_PRINT_URI) \t&pjsip_url_print,\n    (P_CMP_URI) \t&pjsip_url_compare,\n    (P_CLONE) \t\t&pjsip_url_clone\n};\n\nstatic pjsip_uri_vptr sips_url_vptr = \n{\n    (P_GET_SCHEME)\t&pjsips_url_get_scheme,\n    (P_GET_URI)\t\t&pjsip_get_uri,\n    (P_PRINT_URI) \t&pjsip_url_print,\n    (P_CMP_URI) \t&pjsip_url_compare,\n    (P_CLONE) \t\t&pjsip_url_clone\n};\n\nstatic pjsip_uri_vptr name_addr_vptr = \n{\n    (P_GET_SCHEME)\t&pjsip_name_addr_get_scheme,\n    (P_GET_URI)\t\t&pjsip_name_addr_get_uri,\n    (P_PRINT_URI) \t&pjsip_name_addr_print,\n    (P_CMP_URI) \t&pjsip_name_addr_compare,\n    (P_CLONE) \t\t&pjsip_name_addr_clone\n};\n\nstatic const pj_str_t *pjsip_url_get_scheme(const pjsip_sip_uri *url)\n{\n    PJ_UNUSED_ARG(url);\n    return &sip_str;\n}\n\nstatic const pj_str_t *pjsips_url_get_scheme(const pjsip_sip_uri *url)\n{\n    PJ_UNUSED_ARG(url);\n    return &sips_str;\n}\n\nstatic void *pjsip_get_uri( pjsip_uri *uri )\n{\n    return uri;\n}\n\nstatic void *pjsip_name_addr_get_uri( pjsip_name_addr *name )\n{\n    return pjsip_uri_get_uri(name->uri);\n}\n\nPJ_DEF(void) pjsip_sip_uri_set_secure( pjsip_sip_uri *url, \n\t\t\t\t       pj_bool_t secure )\n{\n    url->vptr = secure ? &sips_url_vptr : &sip_url_vptr;\n}\n\nPJ_DEF(void) pjsip_sip_uri_init(pjsip_sip_uri *url, pj_bool_t secure)\n{\n    pj_bzero(url, sizeof(*url));\n    url->ttl_param = -1;\n    pjsip_sip_uri_set_secure(url, secure);\n    pj_list_init(&url->other_param);\n    pj_list_init(&url->header_param);\n}\n\nPJ_DEF(pjsip_sip_uri*) pjsip_sip_uri_create( pj_pool_t *pool, \n\t\t\t\t\t     pj_bool_t secure )\n{\n    pjsip_sip_uri *url = PJ_POOL_ALLOC_T(pool, pjsip_sip_uri);\n    pjsip_sip_uri_init(url, secure);\n    return url;\n}\n\nstatic pj_ssize_t pjsip_url_print(  pjsip_uri_context_e context,\n\t\t\t\t    const pjsip_sip_uri *url, \n\t\t\t\t    char *buf, pj_size_t size)\n{\n    int printed;\n    char *startbuf = buf;\n    char *endbuf = buf+size;\n    const pj_str_t *scheme;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    *buf = '\\0';\n\n    /* Print scheme (\"sip:\" or \"sips:\") */\n    scheme = pjsip_uri_get_scheme(url);\n    copy_advance_check(buf, *scheme);\n    copy_advance_char_check(buf, ':');\n\n    /* Print \"user:password@\", if any. */\n    if (url->user.slen) {\n\tconst pj_cis_t *spec = pjsip_cfg()->endpt.allow_tx_hash_in_uri ?\n\t\t\t\t&pc->pjsip_USER_SPEC_LENIENT :\n\t\t\t\t&pc->pjsip_USER_SPEC;\n\tcopy_advance_escape(buf, url->user, *spec);\n\tif (url->passwd.slen) {\n\t    copy_advance_char_check(buf, ':');\n\t    copy_advance_escape(buf, url->passwd, pc->pjsip_PASSWD_SPEC);\n\t}\n\n\tcopy_advance_char_check(buf, '@');\n    }\n\n    /* Print host. */\n    pj_assert(url->host.slen != 0);\n    /* Detect IPv6 IP address */\n    if (pj_memchr(url->host.ptr, ':', url->host.slen)) {\n\tcopy_advance_pair_quote_cond(buf, \"\", 0, url->host, '[', ']');\n    } else {\n\tcopy_advance_check(buf, url->host);\n    }\n\n    /* Only print port if it is explicitly specified. \n     * Port is not allowed in To and From header, see Table 1 in\n     * RFC 3261 Section 19.1.1\n     */\n    /* Note: ticket #1141 adds run-time setting to allow port number to\n     * appear in From/To header. Default is still false.\n     */\n    if (url->port &&\n\t(context != PJSIP_URI_IN_FROMTO_HDR ||\n\t pjsip_cfg()->endpt.allow_port_in_fromto_hdr))\n    {\n\tif (endbuf - buf < 10)\n\t    return -1;\n\n\tcopy_advance_char_check(buf, ':');\n\tprinted = pj_utoa(url->port, buf);\n\tbuf += printed;\n    }\n\n    /* User param is allowed in all contexes */\n    copy_advance_pair_check(buf, \";user=\", 6, url->user_param);\n\n    /* Method param is only allowed in external/other context. */\n    if (context == PJSIP_URI_IN_OTHER) {\n\tcopy_advance_pair_escape(buf, \";method=\", 8, url->method_param, \n\t\t\t\t pc->pjsip_PARAM_CHAR_SPEC);\n    }\n\n    /* Transport is not allowed in From/To header. */\n    if (context != PJSIP_URI_IN_FROMTO_HDR) {\n\tcopy_advance_pair_escape(buf, \";transport=\", 11, url->transport_param,\n\t\t\t\t pc->pjsip_PARAM_CHAR_SPEC);\n    }\n\n    /* TTL param is not allowed in From, To, Route, and Record-Route header. */\n    if (url->ttl_param >= 0 && context != PJSIP_URI_IN_FROMTO_HDR &&\n\tcontext != PJSIP_URI_IN_ROUTING_HDR) \n    {\n\tif (endbuf - buf < 15)\n\t    return -1;\n\tpj_memcpy(buf, \";ttl=\", 5);\n\tprinted = pj_utoa(url->ttl_param, buf+5);\n\tbuf += printed + 5;\n    }\n\n    /* maddr param is not allowed in From and To header. */\n    if (context != PJSIP_URI_IN_FROMTO_HDR && url->maddr_param.slen) {\n\t/* Detect IPv6 IP address */\n\tif (pj_memchr(url->maddr_param.ptr, ':', url->maddr_param.slen)) {\n\t    copy_advance_pair_quote_cond(buf, \";maddr=\", 7, url->maddr_param,\n\t\t\t\t         '[', ']');\n\t} else {\n\t    copy_advance_pair_escape(buf, \";maddr=\", 7, url->maddr_param,\n\t\t\t\t     pc->pjsip_PARAM_CHAR_SPEC);\n\t}\n    }\n\n    /* lr param is not allowed in From, To, and Contact header. */\n    if (url->lr_param && context != PJSIP_URI_IN_FROMTO_HDR &&\n\tcontext != PJSIP_URI_IN_CONTACT_HDR) \n    {\n\tpj_str_t lr = { \";lr\", 3 };\n\tif (endbuf - buf < 3)\n\t    return -1;\n\tcopy_advance_check(buf, lr);\n    }\n\n    /* Other param. */\n    printed = (int)pjsip_param_print_on(&url->other_param, buf, endbuf-buf, \n\t\t\t\t\t&pc->pjsip_PARAM_CHAR_SPEC, \n\t\t\t\t\t&pc->pjsip_PARAM_CHAR_SPEC, ';');\n    if (printed < 0)\n\treturn -1;\n    buf += printed;\n\n    /* Header param. \n     * Header param is only allowed in these contexts:\n     *\t- PJSIP_URI_IN_CONTACT_HDR\n     *\t- PJSIP_URI_IN_OTHER\n     */\n    if (context == PJSIP_URI_IN_CONTACT_HDR || context == PJSIP_URI_IN_OTHER) {\n\tprinted = (int)pjsip_param_print_on(&url->header_param, buf, endbuf-buf,\n\t\t\t\t\t    &pc->pjsip_HDR_CHAR_SPEC, \n\t\t\t\t\t    &pc->pjsip_HDR_CHAR_SPEC, '?');\n\tif (printed < 0)\n\t    return -1;\n\tbuf += printed;\n    }\n\n    *buf = '\\0';\n    return buf-startbuf;\n}\n\nstatic pj_status_t pjsip_url_compare( pjsip_uri_context_e context,\n\t\t\t\t      const pjsip_sip_uri *url1, \n\t\t\t\t      const pjsip_sip_uri *url2)\n{\n    const pjsip_param *p1;\n\n    /*\n     * Compare two SIP URL's according to Section 19.1.4 of RFC 3261.\n     */\n\n    /* SIP and SIPS URI are never equivalent. \n     * Note: just compare the vptr to avoid string comparison. \n     *       Pretty neat huh!!\n     */\n    if (url1->vptr != url2->vptr)\n\treturn PJSIP_ECMPSCHEME;\n\n    /* Comparison of the userinfo of SIP and SIPS URIs is case-sensitive. \n     * This includes userinfo containing passwords or formatted as \n     * telephone-subscribers.\n     */\n    if (pj_strcmp(&url1->user, &url2->user) != 0)\n\treturn PJSIP_ECMPUSER;\n    if (pj_strcmp(&url1->passwd, &url2->passwd) != 0)\n\treturn PJSIP_ECMPPASSWD;\n    \n    /* Comparison of all other components of the URI is\n     * case-insensitive unless explicitly defined otherwise.\n     */\n\n    /* The ordering of parameters and header fields is not significant \n     * in comparing SIP and SIPS URIs.\n     */\n\n    /* Characters other than those in the reserved set (see RFC 2396 [5])\n     * are equivalent to their encoding.\n     */\n\n    /* An IP address that is the result of a DNS lookup of a host name \n     * does not match that host name.\n     */\n    if (pj_stricmp(&url1->host, &url2->host) != 0)\n\treturn PJSIP_ECMPHOST;\n\n    /* A URI omitting any component with a default value will not match a URI\n     * explicitly containing that component with its default value. \n     * For instance, a URI omitting the optional port component will not match\n     * a URI explicitly declaring port 5060. \n     * The same is true for the transport-parameter, ttl-parameter, \n     * user-parameter, and method components.\n     */\n\n    /* Port is not allowed in To and From header.\n     */\n    if (context != PJSIP_URI_IN_FROMTO_HDR) {\n\tif (url1->port != url2->port)\n\t    return PJSIP_ECMPPORT;\n    }\n    /* Transport is not allowed in From/To header. */\n    if (context != PJSIP_URI_IN_FROMTO_HDR) {\n\tif (pj_stricmp(&url1->transport_param, &url2->transport_param) != 0)\n\t    return PJSIP_ECMPTRANSPORTPRM;\n    }\n    /* TTL param is not allowed in From, To, Route, and Record-Route header. */\n    if (context != PJSIP_URI_IN_FROMTO_HDR &&\n\tcontext != PJSIP_URI_IN_ROUTING_HDR)\n    {\n\tif (url1->ttl_param != url2->ttl_param)\n\t    return PJSIP_ECMPTTLPARAM;\n    }\n    /* User param is allowed in all contexes */\n    if (pj_stricmp(&url1->user_param, &url2->user_param) != 0)\n\treturn PJSIP_ECMPUSERPARAM;\n    /* Method param is only allowed in external/other context. */\n    if (context == PJSIP_URI_IN_OTHER) {\n\tif (pj_stricmp(&url1->method_param, &url2->method_param) != 0)\n\t    return PJSIP_ECMPMETHODPARAM;\n    }\n    /* maddr param is not allowed in From and To header. */\n    if (context != PJSIP_URI_IN_FROMTO_HDR) {\n\tif (pj_stricmp(&url1->maddr_param, &url2->maddr_param) != 0)\n\t    return PJSIP_ECMPMADDRPARAM;\n    }\n\n    /* lr parameter is ignored (?) */\n    /* lr param is not allowed in From, To, and Contact header. */\n\n\n    /* All other uri-parameters appearing in only one URI are ignored when \n     * comparing the URIs.\n     */\n    if (pjsip_param_cmp(&url1->other_param, &url2->other_param, 1)!=0)\n\treturn PJSIP_ECMPOTHERPARAM;\n\n    /* URI header components are never ignored. Any present header component\n     * MUST be present in both URIs and match for the URIs to match. \n     * The matching rules are defined for each header field in Section 20.\n     */\n    p1 = url1->header_param.next;\n    while (p1 != &url1->header_param) {\n\tconst pjsip_param *p2;\n\tp2 = pjsip_param_find(&url2->header_param, &p1->name);\n\tif (p2) {\n\t    /* It seems too much to compare two header params according to\n\t     * the rule of each header. We'll just compare them string to\n\t     * string..\n\t     */\n\t    if (pj_stricmp(&p1->value, &p2->value) != 0)\n\t\treturn PJSIP_ECMPHEADERPARAM;\n\t} else {\n\t    return PJSIP_ECMPHEADERPARAM;\n\t}\n\tp1 = p1->next;\n    }\n\n    /* Equal!! Pheuww.. */\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(void) pjsip_sip_uri_assign(pj_pool_t *pool, pjsip_sip_uri *url, \n\t\t\t\t  const pjsip_sip_uri *rhs)\n{\n    pj_strdup( pool, &url->user, &rhs->user);\n    pj_strdup( pool, &url->passwd, &rhs->passwd);\n    pj_strdup( pool, &url->host, &rhs->host);\n    url->port = rhs->port;\n    pj_strdup( pool, &url->user_param, &rhs->user_param);\n    pj_strdup( pool, &url->method_param, &rhs->method_param);\n    pj_strdup( pool, &url->transport_param, &rhs->transport_param);\n    url->ttl_param = rhs->ttl_param;\n    pj_strdup( pool, &url->maddr_param, &rhs->maddr_param);\n    pjsip_param_clone(pool, &url->other_param, &rhs->other_param);\n    pjsip_param_clone(pool, &url->header_param, &rhs->header_param);\n    url->lr_param = rhs->lr_param;\n}\n\nstatic pjsip_sip_uri* pjsip_url_clone(pj_pool_t *pool, const pjsip_sip_uri *rhs)\n{\n    pjsip_sip_uri *url = PJ_POOL_ALLOC_T(pool, pjsip_sip_uri);\n    if (!url)\n\treturn NULL;\n\n    pjsip_sip_uri_init(url, IS_SIPS(rhs));\n    pjsip_sip_uri_assign(pool, url, rhs);\n    return url;\n}\n\nstatic const pj_str_t *pjsip_name_addr_get_scheme(const pjsip_name_addr *name)\n{\n    pj_assert(name->uri != NULL);\n    return pjsip_uri_get_scheme(name->uri);\n}\n\nPJ_DEF(void) pjsip_name_addr_init(pjsip_name_addr *name)\n{\n    name->vptr = &name_addr_vptr;\n    name->uri = NULL;\n    name->display.slen = 0;\n    name->display.ptr = NULL;\n}\n\nPJ_DEF(pjsip_name_addr*) pjsip_name_addr_create(pj_pool_t *pool)\n{\n    pjsip_name_addr *name_addr = PJ_POOL_ALLOC_T(pool, pjsip_name_addr);\n    pjsip_name_addr_init(name_addr);\n    return name_addr;\n}\n\nstatic pj_ssize_t pjsip_name_addr_print(pjsip_uri_context_e context,\n\t\t\t\t\tconst pjsip_name_addr *name, \n\t\t\t\t\tchar *buf, pj_size_t size)\n{\n    int printed;\n    char *startbuf = buf;\n    char *endbuf = buf + size;\n    pjsip_uri *uri;\n\n    uri = (pjsip_uri*) pjsip_uri_get_uri(name->uri);\n    pj_assert(uri != NULL);\n\n    if (context != PJSIP_URI_IN_REQ_URI) {\n\tif (name->display.slen) {\n\t    if (endbuf-buf < name->display.slen + 3) return -1;\n\t    copy_advance_char_check(buf, '\"');\n\t    copy_advance(buf, name->display);\n\t    copy_advance_char_check(buf, '\"');\n\t    copy_advance_char_check(buf, ' ');\n\t}\n\tcopy_advance_char_check(buf, '<');;\n    }\n\n    printed = pjsip_uri_print(context,uri, buf, size-(buf-startbuf));\n    if (printed < 1)\n\treturn -1;\n    buf += printed;\n\n    if (context != PJSIP_URI_IN_REQ_URI) {\n\tcopy_advance_char_check(buf, '>');\n    }\n\n    *buf = '\\0';\n    return buf-startbuf;\n}\n\nPJ_DEF(void) pjsip_name_addr_assign(pj_pool_t *pool, pjsip_name_addr *dst,\n\t\t\t\t    const pjsip_name_addr *src)\n{\n    pj_strdup( pool, &dst->display, &src->display);\n    dst->uri = (pjsip_uri*) pjsip_uri_clone(pool, src->uri);\n}\n\nstatic pjsip_name_addr* pjsip_name_addr_clone( pj_pool_t *pool, \n\t\t\t\t\t       const pjsip_name_addr *rhs)\n{\n    pjsip_name_addr *addr = PJ_POOL_ALLOC_T(pool, pjsip_name_addr);\n    if (!addr)\n\treturn NULL;\n\n    pjsip_name_addr_init(addr);\n    pjsip_name_addr_assign(pool, addr, rhs);\n    return addr;\n}\n\nstatic int pjsip_name_addr_compare(  pjsip_uri_context_e context,\n\t\t\t\t     const pjsip_name_addr *naddr1,\n\t\t\t\t     const pjsip_name_addr *naddr2)\n{\n    int d;\n\n    /* Check that naddr2 is also a name_addr */\n    if (naddr1->vptr != naddr2->vptr)\n\treturn -1;\n\n    /* I'm not sure whether display name is included in the comparison. */\n    if (pj_strcmp(&naddr1->display, &naddr2->display) != 0) {\n\treturn -1;\n    }\n\n    pj_assert( naddr1->uri != NULL );\n    pj_assert( naddr2->uri != NULL );\n\n    /* Compare name-addr as URL */\n    d = pjsip_uri_cmp( context, naddr1->uri, naddr2->uri);\n    if (d)\n\treturn d;\n\n    return 0;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nstatic const pj_str_t *other_uri_get_scheme( const pjsip_other_uri*);\nstatic void *other_uri_get_uri( pjsip_other_uri*);\nstatic pj_ssize_t other_uri_print( pjsip_uri_context_e context,\n\t\t\t\t   const pjsip_other_uri *url, \n\t\t\t\t   char *buf, pj_size_t size);\nstatic int other_uri_cmp( pjsip_uri_context_e context,\n\t\t\t  const pjsip_other_uri *url1, \n\t\t\t  const pjsip_other_uri *url2);\nstatic pjsip_other_uri* other_uri_clone( pj_pool_t *pool, \n\t\t\t\t\t const pjsip_other_uri *rhs);\n\nstatic pjsip_uri_vptr other_uri_vptr = \n{\n    (P_GET_SCHEME)  &other_uri_get_scheme,\n    (P_GET_URI)\t    &other_uri_get_uri,\n    (P_PRINT_URI)   &other_uri_print,\n    (P_CMP_URI)\t    &other_uri_cmp,\n    (P_CLONE) \t    &other_uri_clone\n};\n\n\nPJ_DEF(pjsip_other_uri*) pjsip_other_uri_create(pj_pool_t *pool) \n{\n    pjsip_other_uri *uri = PJ_POOL_ZALLOC_T(pool, pjsip_other_uri);\n    uri->vptr = &other_uri_vptr;\n    return uri;\n}\n\nstatic const pj_str_t *other_uri_get_scheme( const pjsip_other_uri *uri )\n{\n\treturn &uri->scheme;\n}\n\nstatic void *other_uri_get_uri( pjsip_other_uri *uri )\n{\n    return uri;\n}\n\nstatic pj_ssize_t other_uri_print(pjsip_uri_context_e context,\n\t\t\t\t  const pjsip_other_uri *uri, \n\t\t\t\t  char *buf, pj_size_t size)\n{\n    char *startbuf = buf;\n    char *endbuf = buf + size;\n    \n    PJ_UNUSED_ARG(context);\n    \n    if (uri->scheme.slen + uri->content.slen + 1 > (int)size)\n\treturn -1;\n\n    /* Print scheme. */\n    copy_advance(buf, uri->scheme);\n    *buf++ = ':';\n    \n    /* Print content. */\n    copy_advance(buf, uri->content);\n    \n    return (buf - startbuf);\n}\n\nstatic int other_uri_cmp(pjsip_uri_context_e context,\n\t\t\t const pjsip_other_uri *uri1,\n\t\t\t const pjsip_other_uri *uri2)\n{\n    PJ_UNUSED_ARG(context);\n\n    /* Check that uri2 is also an other_uri */\n    if (uri1->vptr != uri2->vptr)\n\treturn -1;\n    \n    /* Scheme must match. */\n    if (pj_stricmp(&uri1->scheme, &uri2->scheme) != 0) {\n\treturn PJSIP_ECMPSCHEME;\n    }\n    \n    /* Content must match. */\n    if(pj_stricmp(&uri1->content, &uri2->content) != 0) {\n\treturn -1;\n    }\n    \n    /* Equal. */\n    return 0;\n}\n\n/* Clone *: URI */\nstatic pjsip_other_uri* other_uri_clone(pj_pool_t *pool, \n\t\t\t\t\tconst pjsip_other_uri *rhs) \n{\n    pjsip_other_uri *uri = pjsip_other_uri_create(pool);\n    pj_strdup(pool, &uri->scheme, &rhs->scheme);\n    pj_strdup(pool, &uri->content, &rhs->content);\n\n    return uri;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_util.c",
    "content": "/* $Id: sip_util.c 4442 2013-03-19 07:39:25Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_util.h>\n#include <pjsip/sip_transport.h>\n#include <pjsip/sip_msg.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_event.h>\n#include <pjsip/sip_transaction.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_errno.h>\n#include <pj/log.h>\n#include <pj/string.h>\n#include <pj/guid.h>\n#include <pj/pool.h>\n#include <pj/except.h>\n#include <pj/rand.h>\n#include <pj/assert.h>\n#include <pj/errno.h>\n\n#define THIS_FILE    \"endpoint\"\n\nstatic const char *event_str[] = \n{\n    \"UNIDENTIFIED\",\n    \"TIMER\",\n    \"TX_MSG\",\n    \"RX_MSG\",\n    \"TRANSPORT_ERROR\",\n    \"TSX_STATE\",\n    \"USER\",\n};\n\nstatic pj_str_t str_TEXT = { \"text\", 4},\n\t\tstr_PLAIN = { \"plain\", 5 };\n\n/* Add URI to target-set */\nPJ_DEF(pj_status_t) pjsip_target_set_add_uri( pjsip_target_set *tset,\n\t\t\t\t\t      pj_pool_t *pool,\n\t\t\t\t\t      const pjsip_uri *uri,\n\t\t\t\t\t      int q1000)\n{\n    pjsip_target *t, *pos = NULL;\n\n    PJ_ASSERT_RETURN(tset && pool && uri, PJ_EINVAL);\n\n    /* Set q-value to 1 if it is not set */\n    if (q1000 <= 0)\n\tq1000 = 1000;\n\n    /* Scan all the elements to see for duplicates, and at the same time\n     * get the position where the new element should be inserted to\n     * based on the q-value.\n     */\n    t = tset->head.next;\n    while (t != &tset->head) {\n\tif (pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, t->uri, uri)==PJ_SUCCESS)\n\t    return PJ_EEXISTS;\n\tif (pos==NULL && t->q1000 < q1000)\n\t    pos = t;\n\tt = t->next;\n    }\n\n    /* Create new element */\n    t = PJ_POOL_ZALLOC_T(pool, pjsip_target);\n    t->uri = (pjsip_uri*)pjsip_uri_clone(pool, uri);\n    t->q1000 = q1000;\n\n    /* Insert */\n    if (pos == NULL)\n\tpj_list_push_back(&tset->head, t);\n    else\n\tpj_list_insert_before(pos, t);\n\n    /* Set current target if this is the first URI */\n    if (tset->current == NULL)\n\ttset->current = t;\n\n    return PJ_SUCCESS;\n}\n\n/* Add URI's in the Contact header in the message to target-set */\nPJ_DEF(pj_status_t) pjsip_target_set_add_from_msg( pjsip_target_set *tset,\n\t\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t\t   const pjsip_msg *msg)\n{\n    const pjsip_hdr *hdr;\n    unsigned added = 0;\n\n    PJ_ASSERT_RETURN(tset && pool && msg, PJ_EINVAL);\n\n    /* Scan for Contact headers and add the URI */\n    hdr = msg->hdr.next;\n    while (hdr != &msg->hdr) {\n\tif (hdr->type == PJSIP_H_CONTACT) {\n\t    const pjsip_contact_hdr *cn_hdr = (const pjsip_contact_hdr*)hdr;\n\n\t    if (!cn_hdr->star) {\n\t\tpj_status_t rc;\n\t\trc = pjsip_target_set_add_uri(tset, pool, cn_hdr->uri, \n\t\t\t\t\t      cn_hdr->q1000);\n\t\tif (rc == PJ_SUCCESS)\n\t\t    ++added;\n\t    }\n\t}\n\thdr = hdr->next;\n    }\n\n    return added ? PJ_SUCCESS : PJ_EEXISTS;\n}\n\n\n/* Get next target, if any */\nPJ_DEF(pjsip_target*) pjsip_target_set_get_next(const pjsip_target_set *tset)\n{\n    const pjsip_target *t, *next = NULL;\n\n    t = tset->head.next;\n    while (t != &tset->head) {\n\tif (PJSIP_IS_STATUS_IN_CLASS(t->code, 200)) {\n\t    /* No more target since one target has been successful */\n\t    return NULL;\n\t}\n\tif (PJSIP_IS_STATUS_IN_CLASS(t->code, 600)) {\n\t    /* No more target since one target returned global error */\n\t    return NULL;\n\t}\n\tif (t->code==0 && next==NULL) {\n\t    /* This would be the next target as long as we don't find\n\t     * targets with 2xx or 6xx status after this.\n\t     */\n\t    next = t;\n\t}\n\tt = t->next;\n    }\n\n    return (pjsip_target*)next;\n}\n\n\n/* Set current target */\nPJ_DEF(pj_status_t) pjsip_target_set_set_current( pjsip_target_set *tset,\n\t\t\t\t\t\t  pjsip_target *target)\n{\n    PJ_ASSERT_RETURN(tset && target, PJ_EINVAL);\n    PJ_ASSERT_RETURN(pj_list_find_node(tset, target) != NULL, PJ_ENOTFOUND);\n\n    tset->current = target;\n\n    return PJ_SUCCESS;\n}\n\n\n/* Assign status to a target */\nPJ_DEF(pj_status_t) pjsip_target_assign_status( pjsip_target *target,\n\t\t\t\t\t        pj_pool_t *pool,\n\t\t\t\t\t        int status_code,\n\t\t\t\t\t        const pj_str_t *reason)\n{\n    PJ_ASSERT_RETURN(target && pool && status_code && reason, PJ_EINVAL);\n\n    target->code = (pjsip_status_code)status_code;\n    pj_strdup(pool, &target->reason, reason);\n\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Initialize transmit data (msg) with the headers and optional body.\n * This will just put the headers in the message as it is. Be carefull\n * when calling this function because once a header is put in a message, \n * it CAN NOT be put in other message until the first message is deleted, \n * because the way the header is put in the list.\n * That's why the session will shallow_clone it's headers before calling\n * this function.\n */\nstatic void init_request_throw( pjsip_endpoint *endpt,\n                                pjsip_tx_data *tdata, \n\t\t\t\tpjsip_method *method,\n\t\t\t\tpjsip_uri *param_target,\n\t\t\t\tpjsip_from_hdr *param_from,\n\t\t\t\tpjsip_to_hdr *param_to, \n\t\t\t\tpjsip_contact_hdr *param_contact,\n\t\t\t\tpjsip_cid_hdr *param_call_id,\n\t\t\t\tpjsip_cseq_hdr *param_cseq, \n\t\t\t\tconst pj_str_t *param_text)\n{\n    pjsip_msg *msg;\n    pjsip_msg_body *body;\n    pjsip_via_hdr *via;\n    const pjsip_hdr *endpt_hdr;\n\n    /* Create the message. */\n    msg = tdata->msg = pjsip_msg_create(tdata->pool, PJSIP_REQUEST_MSG);\n\n    /* Init request URI. */\n    pj_memcpy(&msg->line.req.method, method, sizeof(*method));\n    msg->line.req.uri = param_target;\n\n    /* Add additional request headers from endpoint. */\n    endpt_hdr = pjsip_endpt_get_request_headers(endpt)->next;\n    while (endpt_hdr != pjsip_endpt_get_request_headers(endpt)) {\n\tpjsip_hdr *hdr = (pjsip_hdr*) \n\t\t\t pjsip_hdr_shallow_clone(tdata->pool, endpt_hdr);\n\tpjsip_msg_add_hdr( tdata->msg, hdr );\n\tendpt_hdr = endpt_hdr->next;\n    }\n\n    /* Add From header. */\n    if (param_from->tag.slen == 0)\n\tpj_create_unique_string(tdata->pool, &param_from->tag);\n    pjsip_msg_add_hdr(msg, (pjsip_hdr*)param_from);\n\n    /* Add To header. */\n    pjsip_msg_add_hdr(msg, (pjsip_hdr*)param_to);\n\n    /* Add Contact header. */\n    if (param_contact) {\n\tpjsip_msg_add_hdr(msg, (pjsip_hdr*)param_contact);\n    }\n\n    /* Add Call-ID header. */\n    pjsip_msg_add_hdr(msg, (pjsip_hdr*)param_call_id);\n\n    /* Add CSeq header. */\n    pjsip_msg_add_hdr(msg, (pjsip_hdr*)param_cseq);\n\n    /* Add a blank Via header in the front of the message. */\n    via = pjsip_via_hdr_create(tdata->pool);\n    via->rport_param = pjsip_cfg()->endpt.disable_rport ? -1 : 0;\n    pjsip_msg_insert_first_hdr(msg, (pjsip_hdr*)via);\n\n    /* Add header params as request headers */\n    if (PJSIP_URI_SCHEME_IS_SIP(param_target) || \n\tPJSIP_URI_SCHEME_IS_SIPS(param_target)) \n    {\n\tpjsip_sip_uri *uri = (pjsip_sip_uri*) pjsip_uri_get_uri(param_target);\n\tpjsip_param *hparam;\n\n\thparam = uri->header_param.next;\n\twhile (hparam != &uri->header_param) {\n\t    pjsip_generic_string_hdr *hdr;\n\n\t    hdr = pjsip_generic_string_hdr_create(tdata->pool, \n\t\t\t\t\t\t  &hparam->name,\n\t\t\t\t\t\t  &hparam->value);\n\t    pjsip_msg_add_hdr(msg, (pjsip_hdr*)hdr);\n\t    hparam = hparam->next;\n\t}\n    }\n\n    /* Create message body. */\n    if (param_text) {\n\tbody = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_msg_body);\n\tbody->content_type.type = str_TEXT;\n\tbody->content_type.subtype = str_PLAIN;\n\tbody->data = pj_pool_alloc(tdata->pool, param_text->slen );\n\tpj_memcpy(body->data, param_text->ptr, param_text->slen);\n\tbody->len = (unsigned)param_text->slen;\n\tbody->print_body = &pjsip_print_text_body;\n\tmsg->body = body;\n    }\n\n    PJ_LOG(5,(THIS_FILE, \"%s created.\", \n\t\t\t pjsip_tx_data_get_info(tdata)));\n\n}\n\n/*\n * Create arbitrary request.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_create_request(  pjsip_endpoint *endpt, \n\t\t\t\t\t\t const pjsip_method *method,\n\t\t\t\t\t\t const pj_str_t *param_target,\n\t\t\t\t\t\t const pj_str_t *param_from,\n\t\t\t\t\t\t const pj_str_t *param_to, \n\t\t\t\t\t\t const pj_str_t *param_contact,\n\t\t\t\t\t\t const pj_str_t *param_call_id,\n\t\t\t\t\t\t int param_cseq, \n\t\t\t\t\t\t const pj_str_t *param_text,\n\t\t\t\t\t\t pjsip_tx_data **p_tdata)\n{\n    pjsip_uri *target;\n    pjsip_tx_data *tdata;\n    pjsip_from_hdr *from;\n    pjsip_to_hdr *to;\n    pjsip_contact_hdr *contact;\n    pjsip_cseq_hdr *cseq = NULL;    /* = NULL, warning in VC6 */\n    pjsip_cid_hdr *call_id;\n    pj_str_t tmp;\n    pj_status_t status;\n    const pj_str_t STR_CONTACT = { \"Contact\", 7 };\n    PJ_USE_EXCEPTION;\n\n    status = pjsip_endpt_create_tdata(endpt, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Init reference counter to 1. */\n    pjsip_tx_data_add_ref(tdata);\n\n    PJ_TRY {\n\t/* Request target. */\n\tpj_strdup_with_null(tdata->pool, &tmp, param_target);\n\ttarget = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen, 0);\n\tif (target == NULL) {\n\t    status = PJSIP_EINVALIDREQURI;\n\t    goto on_error;\n\t}\n\n\t/* From */\n\tfrom = pjsip_from_hdr_create(tdata->pool);\n\tpj_strdup_with_null(tdata->pool, &tmp, param_from);\n\tfrom->uri = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen, \n\t\t\t\t     PJSIP_PARSE_URI_AS_NAMEADDR);\n\tif (from->uri == NULL) {\n\t    status = PJSIP_EINVALIDHDR;\n\t    goto on_error;\n\t}\n\tpj_create_unique_string(tdata->pool, &from->tag);\n\n\t/* To */\n\tto = pjsip_to_hdr_create(tdata->pool);\n\tpj_strdup_with_null(tdata->pool, &tmp, param_to);\n\tto->uri = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen, \n\t\t\t\t   PJSIP_PARSE_URI_AS_NAMEADDR);\n\tif (to->uri == NULL) {\n\t    status = PJSIP_EINVALIDHDR;\n\t    goto on_error;\n\t}\n\n\t/* Contact. */\n\tif (param_contact) {\n\t    pj_strdup_with_null(tdata->pool, &tmp, param_contact);\n\t    contact = (pjsip_contact_hdr*)\n\t\t      pjsip_parse_hdr(tdata->pool, &STR_CONTACT, tmp.ptr, \n\t\t\t\t      tmp.slen, NULL);\n\t    if (contact == NULL) {\n\t\tstatus = PJSIP_EINVALIDHDR;\n\t\tgoto on_error;\n\t    }\n\t} else {\n\t    contact = NULL;\n\t}\n\n\t/* Call-ID */\n\tcall_id = pjsip_cid_hdr_create(tdata->pool);\n\tif (param_call_id != NULL && param_call_id->slen)\n\t    pj_strdup(tdata->pool, &call_id->id, param_call_id);\n\telse\n\t    pj_create_unique_string(tdata->pool, &call_id->id);\n\n\t/* CSeq */\n\tcseq = pjsip_cseq_hdr_create(tdata->pool);\n\tif (param_cseq >= 0)\n\t    cseq->cseq = param_cseq;\n\telse\n\t    cseq->cseq = pj_rand() & 0xFFFF;\n\n\t/* Method */\n\tpjsip_method_copy(tdata->pool, &cseq->method, method);\n\n\t/* Create the request. */\n\tinit_request_throw( endpt, tdata, &cseq->method, target, from, to, \n                            contact, call_id, cseq, param_text);\n    }\n    PJ_CATCH_ANY {\n\tstatus = PJ_ENOMEM;\n\tgoto on_error;\n    }\n    PJ_END\n\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n\non_error:\n    pjsip_tx_data_dec_ref(tdata);\n    return status;\n}\n\nPJ_DEF(pj_status_t) pjsip_endpt_create_request_from_hdr( pjsip_endpoint *endpt,\n\t\t\t\t     const pjsip_method *method,\n\t\t\t\t     const pjsip_uri *param_target,\n\t\t\t\t     const pjsip_from_hdr *param_from,\n\t\t\t\t     const pjsip_to_hdr *param_to,\n\t\t\t\t     const pjsip_contact_hdr *param_contact,\n\t\t\t\t     const pjsip_cid_hdr *param_call_id,\n\t\t\t\t     int param_cseq,\n\t\t\t\t     const pj_str_t *param_text,\n\t\t\t\t     pjsip_tx_data **p_tdata)\n{\n    pjsip_uri *target;\n    pjsip_tx_data *tdata;\n    pjsip_from_hdr *from;\n    pjsip_to_hdr *to;\n    pjsip_contact_hdr *contact;\n    pjsip_cid_hdr *call_id;\n    pjsip_cseq_hdr *cseq = NULL; /* The NULL because warning in VC6 */\n    pj_status_t status;\n    PJ_USE_EXCEPTION;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(endpt && method && param_target && param_from &&\n\t\t     param_to && p_tdata, PJ_EINVAL);\n\n    /* Create new transmit data. */\n    status = pjsip_endpt_create_tdata(endpt, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Set initial reference counter to 1. */\n    pjsip_tx_data_add_ref(tdata);\n\n    PJ_TRY {\n\t/* Duplicate target URI and headers. */\n\ttarget = (pjsip_uri*) pjsip_uri_clone(tdata->pool, param_target);\n\tfrom = (pjsip_from_hdr*) pjsip_hdr_clone(tdata->pool, param_from);\n\tpjsip_fromto_hdr_set_from(from);\n\tto = (pjsip_to_hdr*) pjsip_hdr_clone(tdata->pool, param_to);\n\tpjsip_fromto_hdr_set_to(to);\n\tif (param_contact) {\n\t    contact = (pjsip_contact_hdr*) \n\t    \t      pjsip_hdr_clone(tdata->pool, param_contact);\n\t} else {\n\t    contact = NULL;\n\t}\n\tcall_id = pjsip_cid_hdr_create(tdata->pool);\n\tif (param_call_id != NULL && param_call_id->id.slen)\n\t    pj_strdup(tdata->pool, &call_id->id, &param_call_id->id);\n\telse\n\t    pj_create_unique_string(tdata->pool, &call_id->id);\n\n\tcseq = pjsip_cseq_hdr_create(tdata->pool);\n\tif (param_cseq >= 0)\n\t    cseq->cseq = param_cseq;\n\telse\n\t    cseq->cseq = pj_rand() % 0xFFFF;\n\tpjsip_method_copy(tdata->pool, &cseq->method, method);\n\n\t/* Copy headers to the request. */\n\tinit_request_throw(endpt, tdata, &cseq->method, target, from, to, \n                           contact, call_id, cseq, param_text);\n    }\n    PJ_CATCH_ANY {\n\tstatus = PJ_ENOMEM;\n\tgoto on_error;\n    }\n    PJ_END;\n\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n\non_error:\n    pjsip_tx_data_dec_ref(tdata);\n    return status;\n}\n\n/*\n * Construct a minimal response message for the received request.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_create_response( pjsip_endpoint *endpt,\n\t\t\t\t\t\t const pjsip_rx_data *rdata,\n\t\t\t\t\t\t int st_code,\n\t\t\t\t\t\t const pj_str_t *st_text,\n\t\t\t\t\t\t pjsip_tx_data **p_tdata)\n{\n    pjsip_tx_data *tdata;\n    pjsip_msg *msg, *req_msg;\n    pjsip_hdr *hdr;\n    pjsip_to_hdr *to_hdr;\n    pjsip_via_hdr *top_via = NULL, *via;\n    pjsip_rr_hdr *rr;\n    pj_status_t status;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(endpt && rdata && p_tdata, PJ_EINVAL);\n\n    /* Check status code. */\n    PJ_ASSERT_RETURN(st_code >= 100 && st_code <= 699, PJ_EINVAL);\n\n    /* rdata must be a request message. */\n    req_msg = rdata->msg_info.msg;\n    pj_assert(req_msg->type == PJSIP_REQUEST_MSG);\n\n    /* Request MUST NOT be ACK request! */\n    PJ_ASSERT_RETURN(req_msg->line.req.method.id != PJSIP_ACK_METHOD,\n\t\t     PJ_EINVALIDOP);\n\n    /* Create a new transmit buffer. */\n    status = pjsip_endpt_create_tdata( endpt, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Set initial reference count to 1. */\n    pjsip_tx_data_add_ref(tdata);\n\n    /* Create new response message. */\n    tdata->msg = msg = pjsip_msg_create(tdata->pool, PJSIP_RESPONSE_MSG);\n\n    /* Set status code and reason text. */\n    msg->line.status.code = st_code;\n    if (st_text)\n\tpj_strdup(tdata->pool, &msg->line.status.reason, st_text);\n    else\n\tmsg->line.status.reason = *pjsip_get_status_text(st_code);\n\n    /* Set TX data attributes. */\n    tdata->rx_timestamp = rdata->pkt_info.timestamp;\n\n    /* Copy all the via headers, in order. */\n    via = rdata->msg_info.via;\n    while (via) {\n\tpjsip_via_hdr *new_via;\n\n\tnew_via = (pjsip_via_hdr*)pjsip_hdr_clone(tdata->pool, via);\n\tif (top_via == NULL)\n\t    top_via = new_via;\n\n\tpjsip_msg_add_hdr( msg, (pjsip_hdr*)new_via);\n\tvia = via->next;\n\tif (via != (void*)&req_msg->hdr)\n\t    via = (pjsip_via_hdr*) \n\t    \t  pjsip_msg_find_hdr(req_msg, PJSIP_H_VIA, via);\n\telse\n\t    break;\n    }\n\n    /* Copy all Record-Route headers, in order. */\n    rr = (pjsip_rr_hdr*) \n    \t pjsip_msg_find_hdr(req_msg, PJSIP_H_RECORD_ROUTE, NULL);\n    while (rr) {\n\tpjsip_msg_add_hdr(msg, (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, rr));\n\trr = rr->next;\n\tif (rr != (void*)&req_msg->hdr)\n\t    rr = (pjsip_rr_hdr*) pjsip_msg_find_hdr(req_msg, \n\t    \t\t\t\t\t    PJSIP_H_RECORD_ROUTE, rr);\n\telse\n\t    break;\n    }\n\n    /* Copy Call-ID header. */\n    hdr = (pjsip_hdr*) pjsip_msg_find_hdr( req_msg, PJSIP_H_CALL_ID, NULL);\n    pjsip_msg_add_hdr(msg, (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, hdr));\n\n    /* Copy From header. */\n    hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, rdata->msg_info.from);\n    pjsip_msg_add_hdr( msg, hdr);\n\n    /* Copy To header. */\n    to_hdr = (pjsip_to_hdr*) pjsip_hdr_clone(tdata->pool, rdata->msg_info.to);\n    pjsip_msg_add_hdr( msg, (pjsip_hdr*)to_hdr);\n\n    /* Must add To tag in the response (Section 8.2.6.2), except if this is\n     * 100 (Trying) response. Same tag must be created for the same request\n     * (e.g. same tag in provisional and final response). The easiest way\n     * to do this is to derive the tag from Via branch parameter (or to\n     * use it directly).\n     */\n    if (to_hdr->tag.slen==0 && st_code > 100 && top_via) {\n\tto_hdr->tag = top_via->branch_param;\n    }\n\n    /* Copy CSeq header. */\n    hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, rdata->msg_info.cseq);\n    pjsip_msg_add_hdr( msg, hdr);\n\n    /* All done. */\n    *p_tdata = tdata;\n\n    PJ_LOG(5,(THIS_FILE, \"%s created\", pjsip_tx_data_get_info(tdata)));\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Construct ACK for 3xx-6xx final response (according to chapter 17.1.1 of\n * RFC3261). Note that the generation of ACK for 2xx response is different,\n * and one must not use this function to generate such ACK.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_create_ack( pjsip_endpoint *endpt,\n\t\t\t\t\t    const pjsip_tx_data *tdata,\n\t\t\t\t\t    const pjsip_rx_data *rdata,\n\t\t\t\t\t    pjsip_tx_data **ack_tdata)\n{\n    pjsip_tx_data *ack = NULL;\n    const pjsip_msg *invite_msg;\n    const pjsip_from_hdr *from_hdr;\n    const pjsip_to_hdr *to_hdr;\n    const pjsip_cid_hdr *cid_hdr;\n    const pjsip_cseq_hdr *cseq_hdr;\n    const pjsip_hdr *hdr;\n    pjsip_hdr *via;\n    pjsip_to_hdr *to;\n    pj_status_t status;\n\n    /* rdata must be a non-2xx final response. */\n    pj_assert(rdata->msg_info.msg->type==PJSIP_RESPONSE_MSG &&\n\t      rdata->msg_info.msg->line.status.code >= 300);\n\n    /* Initialize return value to NULL. */\n    *ack_tdata = NULL;\n\n    /* The original INVITE message. */\n    invite_msg = tdata->msg;\n\n    /* Get the headers from original INVITE request. */\n#   define FIND_HDR(m,HNAME) pjsip_msg_find_hdr(m, PJSIP_H_##HNAME, NULL)\n\n    from_hdr = (const pjsip_from_hdr*) FIND_HDR(invite_msg, FROM);\n    PJ_ASSERT_ON_FAIL(from_hdr != NULL, goto on_missing_hdr);\n\n    to_hdr = (const pjsip_to_hdr*) FIND_HDR(invite_msg, TO);\n    PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr);\n\n    cid_hdr = (const pjsip_cid_hdr*) FIND_HDR(invite_msg, CALL_ID);\n    PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr);\n\n    cseq_hdr = (const pjsip_cseq_hdr*) FIND_HDR(invite_msg, CSEQ);\n    PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr);\n\n#   undef FIND_HDR\n\n    /* Create new request message from the headers. */\n    status = pjsip_endpt_create_request_from_hdr(endpt, \n\t\t\t\t\t\t pjsip_get_ack_method(),\n\t\t\t\t\t\t tdata->msg->line.req.uri,\n\t\t\t\t\t\t from_hdr, to_hdr,\n\t\t\t\t\t\t NULL, cid_hdr,\n\t\t\t\t\t\t cseq_hdr->cseq, NULL,\n\t\t\t\t\t\t &ack);\n\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Update tag in To header with the one from the response (if any). */\n    to = (pjsip_to_hdr*) pjsip_msg_find_hdr(ack->msg, PJSIP_H_TO, NULL);\n    pj_strdup(ack->pool, &to->tag, &rdata->msg_info.to->tag);\n\n\n    /* Clear Via headers in the new request. */\n    while ((via=(pjsip_hdr*)pjsip_msg_find_hdr(ack->msg, PJSIP_H_VIA, NULL)) != NULL)\n\tpj_list_erase(via);\n\n    /* Must contain single Via, just as the original INVITE. */\n    hdr = (pjsip_hdr*) pjsip_msg_find_hdr( invite_msg, PJSIP_H_VIA, NULL);\n    pjsip_msg_insert_first_hdr( ack->msg, \n    \t\t\t        (pjsip_hdr*) pjsip_hdr_clone(ack->pool,hdr) );\n\n    /* If the original INVITE has Route headers, those header fields MUST \n     * appear in the ACK.\n     */\n    hdr = (pjsip_hdr*) pjsip_msg_find_hdr( invite_msg, PJSIP_H_ROUTE, NULL);\n    while (hdr != NULL) {\n\tpjsip_msg_add_hdr( ack->msg, \n\t\t\t   (pjsip_hdr*) pjsip_hdr_clone(ack->pool, hdr) );\n\thdr = hdr->next;\n\tif (hdr == &invite_msg->hdr)\n\t    break;\n\thdr = (pjsip_hdr*) pjsip_msg_find_hdr( invite_msg, PJSIP_H_ROUTE, hdr);\n    }\n\n    /* We're done.\n     * \"tdata\" parameter now contains the ACK message.\n     */\n    *ack_tdata = ack;\n    return PJ_SUCCESS;\n\non_missing_hdr:\n    if (ack)\n\tpjsip_tx_data_dec_ref(ack);\n    return PJSIP_EMISSINGHDR;\n}\n\n\n/*\n * Construct CANCEL request for the previously sent request, according to\n * chapter 9.1 of RFC3261.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt,\n\t\t\t\t\t       const pjsip_tx_data *req_tdata,\n\t\t\t\t\t       pjsip_tx_data **p_tdata)\n{\n    pjsip_tx_data *cancel_tdata = NULL;\n    const pjsip_from_hdr *from_hdr;\n    const pjsip_to_hdr *to_hdr;\n    const pjsip_cid_hdr *cid_hdr;\n    const pjsip_cseq_hdr *cseq_hdr;\n    const pjsip_hdr *hdr;\n    pjsip_hdr *via;\n    pj_status_t status;\n\n    /* The transmit buffer must INVITE request. */\n    PJ_ASSERT_RETURN(req_tdata->msg->type == PJSIP_REQUEST_MSG &&\n\t\t     req_tdata->msg->line.req.method.id == PJSIP_INVITE_METHOD,\n\t\t     PJ_EINVAL);\n\n    /* Get the headers from original INVITE request. */\n#   define FIND_HDR(m,HNAME) pjsip_msg_find_hdr(m, PJSIP_H_##HNAME, NULL)\n\n    from_hdr = (const pjsip_from_hdr*) FIND_HDR(req_tdata->msg, FROM);\n    PJ_ASSERT_ON_FAIL(from_hdr != NULL, goto on_missing_hdr);\n\n    to_hdr = (const pjsip_to_hdr*) FIND_HDR(req_tdata->msg, TO);\n    PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr);\n\n    cid_hdr = (const pjsip_cid_hdr*) FIND_HDR(req_tdata->msg, CALL_ID);\n    PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr);\n\n    cseq_hdr = (const pjsip_cseq_hdr*) FIND_HDR(req_tdata->msg, CSEQ);\n    PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr);\n\n#   undef FIND_HDR\n\n    /* Create new request message from the headers. */\n    status = pjsip_endpt_create_request_from_hdr(endpt, \n\t\t\t\t\t\t pjsip_get_cancel_method(),\n\t\t\t\t\t\t req_tdata->msg->line.req.uri,\n\t\t\t\t\t\t from_hdr, to_hdr,\n\t\t\t\t\t\t NULL, cid_hdr,\n\t\t\t\t\t\t cseq_hdr->cseq, NULL,\n\t\t\t\t\t\t &cancel_tdata);\n\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Clear Via headers in the new request. */\n    while ((via=(pjsip_hdr*)pjsip_msg_find_hdr(cancel_tdata->msg, PJSIP_H_VIA, NULL)) != NULL)\n\tpj_list_erase(via);\n\n\n    /* Must only have single Via which matches the top-most Via in the \n     * request being cancelled. \n     */\n    hdr = (pjsip_hdr*) pjsip_msg_find_hdr(req_tdata->msg, PJSIP_H_VIA, NULL);\n    if (hdr) {\n\tpjsip_msg_insert_first_hdr(cancel_tdata->msg, \n\t\t\t\t   (pjsip_hdr*)pjsip_hdr_clone(cancel_tdata->pool, hdr));\n    }\n\n    /* If the original request has Route header, the CANCEL request must also\n     * has exactly the same.\n     * Copy \"Route\" header from the request.\n     */\n    hdr = (pjsip_hdr*) pjsip_msg_find_hdr(req_tdata->msg, PJSIP_H_ROUTE, NULL);\n    while (hdr != NULL) {\n\tpjsip_msg_add_hdr(cancel_tdata->msg, \n\t\t\t  (pjsip_hdr*) pjsip_hdr_clone(cancel_tdata->pool, hdr));\n\thdr = hdr->next;\n\tif (hdr != &req_tdata->msg->hdr)\n\t    hdr = (pjsip_hdr*) pjsip_msg_find_hdr(req_tdata->msg, \n\t    \t\t\t\t\t  PJSIP_H_ROUTE, hdr);\n\telse\n\t    break;\n    }\n\n    /* Must also copy the saved strict route header, otherwise CANCEL will be\n     * sent with swapped Route and request URI!\n     */\n    if (req_tdata->saved_strict_route) {\n\tcancel_tdata->saved_strict_route = (pjsip_route_hdr*)\n\t    pjsip_hdr_clone(cancel_tdata->pool, req_tdata->saved_strict_route);\n    }\n\n    /* Copy the destination host name from the original request */\n    pj_strdup(cancel_tdata->pool, &cancel_tdata->dest_info.name,\n\t      &req_tdata->dest_info.name);\n\n    /* Finally copy the destination info from the original request */\n    pj_memcpy(&cancel_tdata->dest_info, &req_tdata->dest_info,\n\t      sizeof(req_tdata->dest_info));\n\n    /* Done.\n     * Return the transmit buffer containing the CANCEL request.\n     */\n    *p_tdata = cancel_tdata;\n    return PJ_SUCCESS;\n\non_missing_hdr:\n    if (cancel_tdata)\n\tpjsip_tx_data_dec_ref(cancel_tdata);\n    return PJSIP_EMISSINGHDR;\n}\n\n\n/* Fill-up destination information from a target URI */\nPJ_DEF(pj_status_t) pjsip_get_dest_info(const pjsip_uri *target_uri,\n\t\t\t\t \tconst pjsip_uri *request_uri,\n\t\t\t\t \tpj_pool_t *pool,\n\t\t\t\t \tpjsip_host_info *dest_info)\n{\n    /* The target URI must be a SIP/SIPS URL so we can resolve it's address.\n     * Otherwise we're in trouble (i.e. there's no host part in tel: URL).\n     */\n    pj_bzero(dest_info, sizeof(*dest_info));\n\n    /* When request URI uses sips scheme, TLS must always be used regardless\n     * of the target scheme or transport type (see ticket #1740).\n     */\n    if (PJSIP_URI_SCHEME_IS_SIPS(target_uri) || \n\t(pjsip_cfg()->endpt.disable_tls_switch == 0 && request_uri &&\n\t PJSIP_URI_SCHEME_IS_SIPS(request_uri)))\n    {\n\tpjsip_uri *uri = (pjsip_uri*) target_uri;\n\tconst pjsip_sip_uri *url=(const pjsip_sip_uri*)pjsip_uri_get_uri(uri);\n\tunsigned flag;\n\n\tif (!PJSIP_URI_SCHEME_IS_SIPS(target_uri)) {\n\t    PJ_LOG(4,(THIS_FILE, \"Automatic switch to TLS transport as \"\n\t\t\t\t \"request-URI uses \"\"sips\"\" scheme.\"));\n\t}\n\n\tdest_info->flag |= (PJSIP_TRANSPORT_SECURE | PJSIP_TRANSPORT_RELIABLE);\n\tif (url->maddr_param.slen)\n\t    pj_strdup(pool, &dest_info->addr.host, &url->maddr_param);\n\telse\n\t    pj_strdup(pool, &dest_info->addr.host, &url->host);\n        dest_info->addr.port = url->port;\n\tdest_info->type = \n            pjsip_transport_get_type_from_name(&url->transport_param);\n\t/* Double-check that the transport parameter match.\n\t * Sample case:     sips:host;transport=tcp\n\t * See https://trac.pjsip.org/repos/ticket/1319\n\t */\n\tflag = pjsip_transport_get_flag_from_type(dest_info->type);\n\tif ((flag & dest_info->flag) != dest_info->flag) {\n\t    pjsip_transport_type_e t;\n\n\t    t = pjsip_transport_get_type_from_flag(dest_info->flag);\n\t    if (t != PJSIP_TRANSPORT_UNSPECIFIED)\n\t\tdest_info->type = t;\n\t}\n\n    } else if (PJSIP_URI_SCHEME_IS_SIP(target_uri)) {\n\tpjsip_uri *uri = (pjsip_uri*) target_uri;\n\tconst pjsip_sip_uri *url=(const pjsip_sip_uri*)pjsip_uri_get_uri(uri);\n\tif (url->maddr_param.slen)\n\t    pj_strdup(pool, &dest_info->addr.host, &url->maddr_param);\n\telse\n\t    pj_strdup(pool, &dest_info->addr.host, &url->host);\n\tdest_info->addr.port = url->port;\n\tdest_info->type = \n            pjsip_transport_get_type_from_name(&url->transport_param);\n\tdest_info->flag = \n\t    pjsip_transport_get_flag_from_type(dest_info->type);\n    } else {\n\t/* Should have never reached here; app should have configured route\n\t * set when sending to tel: URI\n        pj_assert(!\"Unsupported URI scheme!\");\n\t */\n\tPJ_TODO(SUPPORT_REQUEST_ADDR_RESOLUTION_FOR_TEL_URI);\n\treturn PJSIP_ENOROUTESET;\n    }\n\n    /* Handle IPv6 (http://trac.pjsip.org/repos/ticket/861) */\n    if (dest_info->type != PJSIP_TRANSPORT_UNSPECIFIED && \n\tpj_strchr(&dest_info->addr.host, ':'))\n    {\n\tdest_info->type = (pjsip_transport_type_e)\n\t\t\t  ((int)dest_info->type | PJSIP_TRANSPORT_IPV6);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Find which destination to be used to send the request message, based\n * on the request URI and Route headers in the message. The procedure\n * used here follows the guidelines on sending the request in RFC 3261\n * chapter 8.1.2.\n */\nPJ_DEF(pj_status_t) pjsip_get_request_dest(const pjsip_tx_data *tdata,\n\t\t\t\t\t   pjsip_host_info *dest_info )\n{\n    const pjsip_uri *target_uri;\n    const pjsip_route_hdr *first_route_hdr;\n    \n    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG, \n\t\t     PJSIP_ENOTREQUESTMSG);\n    PJ_ASSERT_RETURN(dest_info != NULL, PJ_EINVAL);\n\n    /* Get the first \"Route\" header from the message.\n     */\n    first_route_hdr = (const pjsip_route_hdr*) \n    \t\t      pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);\n    if (first_route_hdr) {\n\ttarget_uri = first_route_hdr->name_addr.uri;\n    } else {\n\ttarget_uri = tdata->msg->line.req.uri;\n    }\n\n    return pjsip_get_dest_info(target_uri, tdata->msg->line.req.uri,\n\t\t\t       (pj_pool_t*)tdata->pool, dest_info);\n}\n\n\n/*\n * Process route-set found in the request and calculate\n * the destination to be used to send the request message, based\n * on the request URI and Route headers in the message. The procedure\n * used here follows the guidelines on sending the request in RFC 3261\n * chapter 8.1.2.\n */\nPJ_DEF(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,\n\t\t\t\t\t    pjsip_host_info *dest_info )\n{\n    const pjsip_uri *new_request_uri, *target_uri;\n    const pjsip_name_addr *topmost_route_uri;\n    pjsip_route_hdr *first_route_hdr, *last_route_hdr;\n    pj_status_t status;\n    \n    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG, \n\t\t     PJSIP_ENOTREQUESTMSG);\n    PJ_ASSERT_RETURN(dest_info != NULL, PJ_EINVAL);\n\n    /* If the request contains strict route, check that the strict route\n     * has been restored to its original values before processing the\n     * route set. The strict route is restored to the original values\n     * with pjsip_restore_strict_route_set(). If caller did not restore\n     * the strict route before calling this function, we need to call it\n     * here, or otherwise the strict-route and Request-URI will be swapped\n     * twice!\n     */\n    if (tdata->saved_strict_route != NULL) {\n\tpjsip_restore_strict_route_set(tdata);\n    }\n    PJ_ASSERT_RETURN(tdata->saved_strict_route==NULL, PJ_EBUG);\n\n    /* Find the first and last \"Route\" headers from the message. */\n    last_route_hdr = first_route_hdr = (pjsip_route_hdr*)\n\tpjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);\n    if (first_route_hdr) {\n\ttopmost_route_uri = &first_route_hdr->name_addr;\n\twhile (last_route_hdr->next != (void*)&tdata->msg->hdr) {\n\t    pjsip_route_hdr *hdr;\n\t    hdr = (pjsip_route_hdr*)\n\t    \t  pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, \n                                     last_route_hdr->next);\n\t    if (!hdr)\n\t\tbreak;\n\t    last_route_hdr = hdr;\n\t}\n    } else {\n\ttopmost_route_uri = NULL;\n    }\n\n    /* If Route headers exist, and the first element indicates loose-route,\n     * the URI is taken from the Request-URI, and we keep all existing Route\n     * headers intact.\n     * If Route headers exist, and the first element DOESN'T indicate loose\n     * route, the URI is taken from the first Route header, and remove the\n     * first Route header from the message.\n     * Otherwise if there's no Route headers, the URI is taken from the\n     * Request-URI.\n     */\n    if (topmost_route_uri) {\n\tpj_bool_t has_lr_param;\n\n\tif (PJSIP_URI_SCHEME_IS_SIP(topmost_route_uri) ||\n\t    PJSIP_URI_SCHEME_IS_SIPS(topmost_route_uri))\n\t{\n\t    const pjsip_sip_uri *url = (const pjsip_sip_uri*)\n\t\tpjsip_uri_get_uri((const void*)topmost_route_uri);\n\t    has_lr_param = url->lr_param;\n\t} else {\n\t    has_lr_param = 0;\n\t}\n\n\tif (has_lr_param) {\n\t    new_request_uri = tdata->msg->line.req.uri;\n\t    /* We shouldn't need to delete topmost Route if it has lr param.\n\t     * But seems like it breaks some proxy implementation, so we\n\t     * delete it anyway.\n\t     */\n\t    /*\n\t    pj_list_erase(first_route_hdr);\n\t    if (first_route_hdr == last_route_hdr)\n\t\tlast_route_hdr = NULL;\n\t    */\n\t} else {\n\t    new_request_uri = (const pjsip_uri*) \n\t    \t\t      pjsip_uri_get_uri((pjsip_uri*)topmost_route_uri);\n\t    pj_list_erase(first_route_hdr);\n\t    tdata->saved_strict_route = first_route_hdr;\n\t    if (first_route_hdr == last_route_hdr)\n\t\tfirst_route_hdr = last_route_hdr = NULL;\n\t}\n\n\ttarget_uri = (pjsip_uri*)topmost_route_uri;\n\n    } else {\n\ttarget_uri = new_request_uri = tdata->msg->line.req.uri;\n    }\n\n    /* Fill up the destination host/port from the URI. */\n    status = pjsip_get_dest_info(target_uri, new_request_uri, tdata->pool,\n\t\t\t   \t dest_info);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* If target URI is different than request URI, replace \n     * request URI add put the original URI in the last Route header.\n     */\n    if (new_request_uri && new_request_uri!=tdata->msg->line.req.uri) {\n\tpjsip_route_hdr *route = pjsip_route_hdr_create(tdata->pool);\n\troute->name_addr.uri = (pjsip_uri*) \n\t\t\t       pjsip_uri_get_uri(tdata->msg->line.req.uri);\n\tif (last_route_hdr)\n\t    pj_list_insert_after(last_route_hdr, route);\n\telse\n\t    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)route);\n\ttdata->msg->line.req.uri = (pjsip_uri*)new_request_uri;\n    }\n\n    /* Success. */\n    return PJ_SUCCESS;  \n}\n\n\n/*\n * Swap the request URI and strict route back to the original position\n * before #pjsip_process_route_set() function is called. This function\n * should only used internally by PJSIP client authentication module.\n */\nPJ_DEF(void) pjsip_restore_strict_route_set(pjsip_tx_data *tdata)\n{\n    pjsip_route_hdr *first_route_hdr, *last_route_hdr;\n\n    /* Check if we have found strict route before */\n    if (tdata->saved_strict_route == NULL) {\n\t/* This request doesn't contain strict route */\n\treturn;\n    }\n\n    /* Find the first \"Route\" headers from the message. */\n    first_route_hdr = (pjsip_route_hdr*)\n\t\t      pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);\n\n    if (first_route_hdr == NULL) {\n\t/* User has modified message route? We don't expect this! */\n\tpj_assert(!\"Message route was modified?\");\n\ttdata->saved_strict_route = NULL;\n\treturn;\n    }\n\n    /* Find last Route header */\n    last_route_hdr = first_route_hdr;\n    while (last_route_hdr->next != (void*)&tdata->msg->hdr) {\n\tpjsip_route_hdr *hdr;\n\thdr = (pjsip_route_hdr*)\n\t      pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, \n                                 last_route_hdr->next);\n\tif (!hdr)\n\t    break;\n\tlast_route_hdr = hdr;\n    }\n\n    /* Put the last Route header as request URI, delete last Route\n     * header, and insert the saved strict route as the first Route.\n     */\n    tdata->msg->line.req.uri = last_route_hdr->name_addr.uri;\n    pj_list_insert_before(first_route_hdr, tdata->saved_strict_route);\n    pj_list_erase(last_route_hdr);\n\n    /* Reset */\n    tdata->saved_strict_route = NULL;\n}\n\n\n/* Transport callback for sending stateless request. \n * This is one of the most bizzare function in pjsip, so\n * good luck if you happen to debug this function!!\n */\nstatic void stateless_send_transport_cb( void *token,\n\t\t\t\t\t pjsip_tx_data *tdata,\n\t\t\t\t\t pj_ssize_t sent )\n{\n    pjsip_send_state *stateless_data = (pjsip_send_state*) token;\n\n    PJ_UNUSED_ARG(tdata);\n    pj_assert(tdata == stateless_data->tdata);\n\n    for (;;) {\n\tpj_status_t status;\n\tpj_bool_t cont;\n\n\tpj_sockaddr_t *cur_addr;\n\tpjsip_transport_type_e cur_addr_type;\n\tint cur_addr_len;\n\n\tpjsip_via_hdr *via;\n\n\tif (sent == -PJ_EPENDING) {\n\t    /* This is the initial process.\n\t     * When the process started, this function will be called by\n\t     * stateless_send_resolver_callback() with sent argument set to\n\t     * -PJ_EPENDING.\n\t     */\n\t    cont = PJ_TRUE;\n\t} else {\n\t    /* There are two conditions here:\n\t     * (1) Message is sent (i.e. sent > 0),\n\t     * (2) Failure (i.e. sent <= 0)\n\t     */\n\t    cont = (sent > 0) ? PJ_FALSE :\n\t\t   (tdata->dest_info.cur_addr<tdata->dest_info.addr.count-1);\n\t    if (stateless_data->app_cb) {\n\t\t(*stateless_data->app_cb)(stateless_data, sent, &cont);\n\t    } else {\n\t\t/* Doesn't have application callback.\n\t\t * Terminate the process.\n\t\t */\n\t\tcont = PJ_FALSE;\n\t    }\n\t}\n\n\t/* Finished with this transport. */\n\tif (stateless_data->cur_transport) {\n\t    pjsip_transport_dec_ref(stateless_data->cur_transport);\n\t    stateless_data->cur_transport = NULL;\n\t}\n\n\t/* Done if application doesn't want to continue. */\n\tif (sent > 0 || !cont) {\n\t    pjsip_tx_data_dec_ref(tdata);\n\t    return;\n\t}\n\n\t/* Try next address, if any, and only when this is not the \n\t * first invocation. \n\t */\n\tif (sent != -PJ_EPENDING) {\n\t    tdata->dest_info.cur_addr++;\n\t}\n\n\t/* Have next address? */\n\tif (tdata->dest_info.cur_addr >= tdata->dest_info.addr.count) {\n\t    /* This only happens when a rather buggy application has\n\t     * sent 'cont' to PJ_TRUE when the initial value was PJ_FALSE.\n\t     * In this case just stop the processing; we don't need to\n\t     * call the callback again as application has been informed\n\t     * before.\n\t     */\n\t    pjsip_tx_data_dec_ref(tdata);\n\t    return;\n\t}\n\n\t/* Keep current server address information handy. */\n\tcur_addr = &tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr;\n\tcur_addr_type = tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].type;\n\tcur_addr_len = tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr_len;\n\n\t/* Acquire transport. */\n\tstatus = pjsip_endpt_acquire_transport2(stateless_data->endpt,\n\t\t\t\t\t\tcur_addr_type,\n\t\t\t\t\t\tcur_addr,\n\t\t\t\t\t\tcur_addr_len,\n\t\t\t\t\t\t&tdata->tp_sel,\n\t\t\t\t\t\ttdata,\n\t\t\t\t\t\t&stateless_data->cur_transport);\n\tif (status != PJ_SUCCESS) {\n\t    sent = -status;\n\t    continue;\n\t}\n\n\t/* Modify Via header. */\n\tvia = (pjsip_via_hdr*) pjsip_msg_find_hdr( tdata->msg,\n\t\t\t\t\t\t   PJSIP_H_VIA, NULL);\n\tif (!via) {\n\t    /* Shouldn't happen if request was created with PJSIP API! \n\t     * But we handle the case anyway for robustness.\n\t     */\n\t    pj_assert(!\"Via header not found!\");\n\t    via = pjsip_via_hdr_create(tdata->pool);\n\t    pjsip_msg_insert_first_hdr(tdata->msg, (pjsip_hdr*)via);\n\t}\n\n\tif (via->branch_param.slen == 0) {\n\t    pj_str_t tmp;\n\t    via->branch_param.ptr = (char*)pj_pool_alloc(tdata->pool,\n\t\t\t\t\t\t  \t PJSIP_MAX_BRANCH_LEN);\n\t    via->branch_param.slen = PJSIP_MAX_BRANCH_LEN;\n\t    pj_memcpy(via->branch_param.ptr, PJSIP_RFC3261_BRANCH_ID,\n\t\t      PJSIP_RFC3261_BRANCH_LEN);\n\t    tmp.ptr = via->branch_param.ptr + PJSIP_RFC3261_BRANCH_LEN + 2;\n\t    *(tmp.ptr-2) = 80; *(tmp.ptr-1) = 106;\n\t    pj_generate_unique_string(&tmp);\n\t}\n\n\tvia->transport = pj_str(stateless_data->cur_transport->type_name);\n        if (tdata->via_addr.host.slen > 0 &&\n            tdata->via_tp == (void *)stateless_data->cur_transport)\n        {\n            via->sent_by = tdata->via_addr;\n        } else {\n\t    via->sent_by = stateless_data->cur_transport->local_name;\n        }\n\tvia->rport_param = pjsip_cfg()->endpt.disable_rport ? -1 : 0;\n\n\t/* Add/remove \"alias\" param to/from Via header on connection \n\t * oriented/less transport, if configured.\n\t */\n\tif (pjsip_cfg()->endpt.req_has_via_alias &&\n\t    tdata->msg->type == PJSIP_REQUEST_MSG)\n\t{\n\t    const pj_str_t ALIAS_STR = {\"alias\", 5};\n\t    pjsip_param *alias_param;\n\t    pj_bool_t is_datagram;\n\n\t    alias_param = pjsip_param_find(&via->other_param, &ALIAS_STR);\n\t    is_datagram = (stateless_data->cur_transport->flag & \n\t\t\t   PJSIP_TRANSPORT_DATAGRAM);\n\t    if (!is_datagram && !alias_param) {\n\t\talias_param = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_param);\n\t\talias_param->name = ALIAS_STR;\n\t\tpj_list_push_back(&via->other_param, alias_param);\n\t    } else if (is_datagram && alias_param) {\n\t\tpj_list_erase(alias_param);\n\t    }\n\t}\n\n\tpjsip_tx_data_invalidate_msg(tdata);\n\n\t/* Send message using this transport. */\n\tstatus = pjsip_transport_send( stateless_data->cur_transport,\n\t\t\t\t       tdata,\n\t\t\t\t       cur_addr,\n\t\t\t\t       cur_addr_len,\n\t\t\t\t       stateless_data,\n\t\t\t\t       &stateless_send_transport_cb);\n\tif (status == PJ_SUCCESS) {\n\t    /* Recursively call this function. */\n\t    sent = tdata->buf.cur - tdata->buf.start;\n\t    stateless_send_transport_cb( stateless_data, tdata, sent );\n\t    return;\n\t} else if (status == PJ_EPENDING) {\n\t    /* This callback will be called later. */\n\t    return;\n\t} else {\n\t    /* Recursively call this function. */\n\t    sent = -status;\n\t    stateless_send_transport_cb( stateless_data, tdata, sent );\n\t    return;\n\t}\n    }\n\n}\n\n/* Resolver callback for sending stateless request. */\nstatic void \nstateless_send_resolver_callback( pj_status_t status,\n\t\t\t\t  void *token,\n\t\t\t\t  const struct pjsip_server_addresses *addr)\n{\n    pjsip_send_state *stateless_data = (pjsip_send_state*) token;\n    pjsip_tx_data *tdata = stateless_data->tdata;\n\n    /* Fail on server resolution. */\n    if (status != PJ_SUCCESS) {\n\tif (stateless_data->app_cb) {\n\t    pj_bool_t cont = PJ_FALSE;\n\t    (*stateless_data->app_cb)(stateless_data, -status, &cont);\n\t}\n\tpjsip_tx_data_dec_ref(tdata);\n\treturn;\n    }\n\n    /* Copy server addresses */\n    if (addr && addr != &tdata->dest_info.addr) {\n\tpj_memcpy( &tdata->dest_info.addr, addr, \n\t           sizeof(pjsip_server_addresses));\n    }\n    pj_assert(tdata->dest_info.addr.count != 0);\n\n    /* RFC 3261 section 18.1.1:\n     * If a request is within 200 bytes of the path MTU, or if it is larger\n     * than 1300 bytes and the path MTU is unknown, the request MUST be sent\n     * using an RFC 2914 [43] congestion controlled transport protocol, such\n     * as TCP.\n     */\n    if (pjsip_cfg()->endpt.disable_tcp_switch==0 &&\n\ttdata->msg->type == PJSIP_REQUEST_MSG &&\n\ttdata->dest_info.addr.count > 0 && \n\ttdata->dest_info.addr.entry[0].type == PJSIP_TRANSPORT_UDP)\n    {\n\tint len;\n\n\t/* Encode the request */\n\tstatus = pjsip_tx_data_encode(tdata);\n\tif (status != PJ_SUCCESS) {\n\t    if (stateless_data->app_cb) {\n\t\tpj_bool_t cont = PJ_FALSE;\n\t\t(*stateless_data->app_cb)(stateless_data, -status, &cont);\n\t    }\n\t    pjsip_tx_data_dec_ref(tdata);\n\t    return;\n\t}\n\n\t/* Check if request message is larger than 1300 bytes. */\n\tlen = (int)(tdata->buf.cur - tdata->buf.start);\n\tif (len >= PJSIP_UDP_SIZE_THRESHOLD) {\n\t    int i;\n\t    int count = tdata->dest_info.addr.count;\n\n\t    PJ_LOG(5,(THIS_FILE, \"%s exceeds UDP size threshold (%u), \"\n\t\t\t\t \"sending with TCP\",\n\t\t\t\t pjsip_tx_data_get_info(tdata),\n\t\t\t\t PJSIP_UDP_SIZE_THRESHOLD));\n\n\t    /* Insert \"TCP version\" of resolved UDP addresses at the\n\t     * beginning.\n\t     */\n\t    if (count * 2 > PJSIP_MAX_RESOLVED_ADDRESSES)\n\t\tcount = PJSIP_MAX_RESOLVED_ADDRESSES / 2;\n\t    for (i = 0; i < count; ++i) {\n\t\tpj_memcpy(&tdata->dest_info.addr.entry[i+count],\n\t\t\t  &tdata->dest_info.addr.entry[i],\n\t\t\t  sizeof(tdata->dest_info.addr.entry[0]));\n\t\ttdata->dest_info.addr.entry[i].type = PJSIP_TRANSPORT_TCP;\n\t    }\n\t    tdata->dest_info.addr.count = count * 2;\n\t}\n    }\n\n    /* Process the addresses. */\n    stateless_send_transport_cb( stateless_data, tdata, -PJ_EPENDING);\n}\n\n/*\n * Send stateless request.\n * The sending process consists of several stages:\n *  - determine which host to contact (#pjsip_get_request_addr).\n *  - resolve the host (#pjsip_endpt_resolve)\n *  - establish transport (#pjsip_endpt_acquire_transport)\n *  - send the message (#pjsip_transport_send)\n */\nPJ_DEF(pj_status_t) pjsip_endpt_send_request_stateless(pjsip_endpoint *endpt, \n\t\t\t\t   pjsip_tx_data *tdata,\n\t\t\t\t   void *token,\n\t\t\t\t   pjsip_send_callback cb)\n{\n    pjsip_host_info dest_info;\n    pjsip_send_state *stateless_data;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(endpt && tdata, PJ_EINVAL);\n\n    /* Get destination name to contact. */\n    status = pjsip_process_route_set(tdata, &dest_info);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Keep stateless data. */\n    stateless_data = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_send_state);\n    stateless_data->token = token;\n    stateless_data->endpt = endpt;\n    stateless_data->tdata = tdata;\n    stateless_data->app_cb = cb;\n\n    /* If destination info has not been initialized (this applies for most\n     * all requests except CANCEL), resolve destination host. The processing\n     * then resumed when the resolving callback is called. For CANCEL, the\n     * destination info must have been copied from the original INVITE so\n     * proceed to sending the request directly.\n     */\n    if (tdata->dest_info.addr.count == 0) {\n\t/* Copy the destination host name to TX data */\n\tpj_strdup(tdata->pool, &tdata->dest_info.name, &dest_info.addr.host);\n\n\tpjsip_endpt_resolve( endpt, tdata->pool, &dest_info, stateless_data,\n\t\t\t     &stateless_send_resolver_callback);\n    } else {\n\tPJ_LOG(5,(THIS_FILE, \"%s: skipping target resolution because \"\n\t                     \"address is already set\",\n\t\t\t     pjsip_tx_data_get_info(tdata)));\n\tstateless_send_resolver_callback(PJ_SUCCESS, stateless_data,\n\t\t\t\t\t &tdata->dest_info.addr);\n    }\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Send raw data to a destination.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_send_raw( pjsip_endpoint *endpt,\n\t\t\t\t\t  pjsip_transport_type_e tp_type,\n\t\t\t\t\t  const pjsip_tpselector *sel,\n\t\t\t\t\t  const void *raw_data,\n\t\t\t\t\t  pj_size_t data_len,\n\t\t\t\t\t  const pj_sockaddr_t *addr,\n\t\t\t\t\t  int addr_len,\n\t\t\t\t\t  void *token,\n\t\t\t\t\t  pjsip_tp_send_callback cb)\n{\n    return pjsip_tpmgr_send_raw(pjsip_endpt_get_tpmgr(endpt), tp_type, sel,\n\t\t\t\tNULL, raw_data, data_len, addr, addr_len,\n\t\t\t\ttoken, cb);\n}\n\n\n/* Callback data for sending raw data */\nstruct send_raw_data\n{\n    pjsip_endpoint\t    *endpt;\n    pjsip_tx_data\t    *tdata;\n    pjsip_tpselector\t    *sel;\n    void\t\t    *app_token;\n    pjsip_tp_send_callback   app_cb;\n};\n\n\n/* Resolver callback for sending raw data. */\nstatic void send_raw_resolver_callback( pj_status_t status,\n    \t\t\t\t\tvoid *token,\n\t\t\t\t\tconst pjsip_server_addresses *addr)\n{\n    struct send_raw_data *sraw_data = (struct send_raw_data*) token;\n\n    if (status != PJ_SUCCESS) {\n\tif (sraw_data->app_cb) {\n\t    (*sraw_data->app_cb)(sraw_data->app_token, sraw_data->tdata,\n\t\t\t\t -status);\n\t}\n    } else {\n\tpj_size_t data_len;\n\n\tpj_assert(addr->count != 0);\n\n\t/* Avoid tdata destroyed by pjsip_tpmgr_send_raw(). */\n\tpjsip_tx_data_add_ref(sraw_data->tdata);\n\n\tdata_len = sraw_data->tdata->buf.cur - sraw_data->tdata->buf.start;\n\tstatus = pjsip_tpmgr_send_raw(pjsip_endpt_get_tpmgr(sraw_data->endpt),\n\t\t\t\t      addr->entry[0].type,\n\t\t\t\t      sraw_data->sel, sraw_data->tdata,\n\t\t\t\t      sraw_data->tdata->buf.start, data_len,\n\t\t\t\t      &addr->entry[0].addr, \n\t\t\t\t      addr->entry[0].addr_len, \n\t\t\t\t      sraw_data->app_token,\n\t\t\t\t      sraw_data->app_cb);\n\tif (status == PJ_SUCCESS) {\n\t    (*sraw_data->app_cb)(sraw_data->app_token, sraw_data->tdata,\n\t\t\t\t data_len);\n\t} else if (status != PJ_EPENDING) {\n\t    (*sraw_data->app_cb)(sraw_data->app_token, sraw_data->tdata,\n\t\t\t\t -status);\n\t}\n    }\n\n    if (sraw_data->sel) {\n\tpjsip_tpselector_dec_ref(sraw_data->sel);\n    }\n    pjsip_tx_data_dec_ref(sraw_data->tdata);\n}\n\n\n/*\n * Send raw data to the specified destination URI. \n */\nPJ_DEF(pj_status_t) pjsip_endpt_send_raw_to_uri(pjsip_endpoint *endpt,\n\t\t\t\t\t\tconst pj_str_t *p_dst_uri,\n\t\t\t\t\t\tconst pjsip_tpselector *sel,\n\t\t\t\t\t\tconst void *raw_data,\n\t\t\t\t\t\tpj_size_t data_len,\n\t\t\t\t\t\tvoid *token,\n\t\t\t\t\t\tpjsip_tp_send_callback cb)\n{\n    pjsip_tx_data *tdata;\n    struct send_raw_data *sraw_data;\n    pj_str_t dst_uri;\n    pjsip_uri *uri;\n    pjsip_host_info dest_info;\n    pj_status_t status;\n\n    /* Allocate buffer */\n    status = pjsip_endpt_create_tdata(endpt, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pjsip_tx_data_add_ref(tdata);\n\n    /* Duplicate URI since parser requires URI to be NULL terminated */\n    pj_strdup_with_null(tdata->pool, &dst_uri, p_dst_uri);\n\n    /* Parse URI */\n    uri = pjsip_parse_uri(tdata->pool, dst_uri.ptr, dst_uri.slen, 0);\n    if (uri == NULL) {\n\tpjsip_tx_data_dec_ref(tdata);\n\treturn PJSIP_EINVALIDURI;\n    }\n\n    /* Build destination info. */\n    status = pjsip_get_dest_info(uri, NULL, tdata->pool, &dest_info);\n    if (status != PJ_SUCCESS) {\n\tpjsip_tx_data_dec_ref(tdata);\n\treturn status;\n    }\n\n    /* Copy data (note: data_len may be zero!) */\n    tdata->buf.start = (char*) pj_pool_alloc(tdata->pool, data_len+1);\n    tdata->buf.end = tdata->buf.start + data_len + 1;\n    if (data_len)\n\tpj_memcpy(tdata->buf.start, raw_data, data_len);\n    tdata->buf.cur = tdata->buf.start + data_len;\n\n    /* Init send_raw_data */\n    sraw_data = PJ_POOL_ZALLOC_T(tdata->pool, struct send_raw_data);\n    sraw_data->endpt = endpt;\n    sraw_data->tdata = tdata;\n    sraw_data->app_token = token;\n    sraw_data->app_cb = cb;\n\n    if (sel) {\n\tsraw_data->sel = PJ_POOL_ALLOC_T(tdata->pool, pjsip_tpselector);\n\tpj_memcpy(sraw_data->sel, sel, sizeof(pjsip_tpselector));\n\tpjsip_tpselector_add_ref(sraw_data->sel);\n    }\n\n    /* Copy the destination host name to TX data */\n    pj_strdup(tdata->pool, &tdata->dest_info.name, &dest_info.addr.host);\n\n    /* Resolve destination host.\n     * The processing then resumed when the resolving callback is called.\n     */\n    pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, sraw_data,\n\t\t\t &send_raw_resolver_callback);\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Determine which address (and transport) to use to send response message\n * based on the received request. This function follows the specification\n * in section 18.2.2 of RFC 3261 and RFC 3581 for calculating the destination\n * address and transport.\n */\nPJ_DEF(pj_status_t) pjsip_get_response_addr( pj_pool_t *pool,\n\t\t\t\t\t     pjsip_rx_data *rdata,\n\t\t\t\t\t     pjsip_response_addr *res_addr )\n{\n    pjsip_transport *src_transport = rdata->tp_info.transport;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(pool && rdata && res_addr, PJ_EINVAL);\n\n    /* rdata must be a request message! */\n    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,\n\t\t     PJ_EINVAL);\n\n    /* All requests must have \"received\" parameter.\n     * This must always be done in transport layer.\n     */\n    pj_assert(rdata->msg_info.via->recvd_param.slen != 0);\n\n    /* Do the calculation based on RFC 3261 Section 18.2.2 and RFC 3581 */\n\n    if (PJSIP_TRANSPORT_IS_RELIABLE(src_transport)) {\n\t/* For reliable protocol such as TCP or SCTP, or TLS over those, the\n\t * response MUST be sent using the existing connection to the source\n\t * of the original request that created the transaction, if that \n\t * connection is still open. \n\t * If that connection is no longer open, the server SHOULD open a \n\t * connection to the IP address in the received parameter, if present,\n\t * using the port in the sent-by value, or the default port for that \n\t * transport, if no port is specified. \n\t * If that connection attempt fails, the server SHOULD use the \n\t * procedures in [4] for servers in order to determine the IP address\n\t * and port to open the connection and send the response to.\n\t */\n\tres_addr->transport = rdata->tp_info.transport;\n\tpj_memcpy(&res_addr->addr, &rdata->pkt_info.src_addr,\n\t\t  rdata->pkt_info.src_addr_len);\n\tres_addr->addr_len = rdata->pkt_info.src_addr_len;\n\tres_addr->dst_host.type=(pjsip_transport_type_e)src_transport->key.type;\n\tres_addr->dst_host.flag = src_transport->flag;\n\tpj_strdup( pool, &res_addr->dst_host.addr.host, \n\t\t   &rdata->msg_info.via->recvd_param);\n\tres_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port;\n\tif (res_addr->dst_host.addr.port == 0) {\n\t    res_addr->dst_host.addr.port = \n\t\tpjsip_transport_get_default_port_for_type(res_addr->dst_host.type);\n\t}\n\n    } else if (rdata->msg_info.via->maddr_param.slen) {\n\t/* Otherwise, if the Via header field value contains a maddr parameter,\n\t * the response MUST be forwarded to the address listed there, using \n\t * the port indicated in sent-by, or port 5060 if none is present. \n\t * If the address is a multicast address, the response SHOULD be sent \n\t * using the TTL indicated in the ttl parameter, or with a TTL of 1 if\n\t * that parameter is not present. \n\t */\n\tres_addr->transport = NULL;\n\tres_addr->dst_host.type=(pjsip_transport_type_e)src_transport->key.type;\n\tres_addr->dst_host.flag = src_transport->flag;\n\tpj_strdup( pool, &res_addr->dst_host.addr.host, \n\t\t   &rdata->msg_info.via->maddr_param);\n\tres_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port;\n\tif (res_addr->dst_host.addr.port == 0)\n\t    res_addr->dst_host.addr.port = 5060;\n\n    } else if (rdata->msg_info.via->rport_param >= 0) {\n\t/* There is both a \"received\" parameter and an \"rport\" parameter, \n\t * the response MUST be sent to the IP address listed in the \"received\"\n\t * parameter, and the port in the \"rport\" parameter. \n\t * The response MUST be sent from the same address and port that the \n\t * corresponding request was received on.\n\t */\n\tres_addr->transport = rdata->tp_info.transport;\n\tpj_memcpy(&res_addr->addr, &rdata->pkt_info.src_addr,\n\t\t  rdata->pkt_info.src_addr_len);\n\tres_addr->addr_len = rdata->pkt_info.src_addr_len;\n\tres_addr->dst_host.type=(pjsip_transport_type_e)src_transport->key.type;\n\tres_addr->dst_host.flag = src_transport->flag;\n\tpj_strdup( pool, &res_addr->dst_host.addr.host, \n\t\t   &rdata->msg_info.via->recvd_param);\n\tres_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port;\n\tif (res_addr->dst_host.addr.port == 0) {\n\t    res_addr->dst_host.addr.port = \n\t\tpjsip_transport_get_default_port_for_type(res_addr->dst_host.type);\n\t}\n\n    } else {\n\tres_addr->transport = NULL;\n\tres_addr->dst_host.type=(pjsip_transport_type_e)src_transport->key.type;\n\tres_addr->dst_host.flag = src_transport->flag;\n\tpj_strdup( pool, &res_addr->dst_host.addr.host, \n\t\t   &rdata->msg_info.via->recvd_param);\n\tres_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port;\n\tif (res_addr->dst_host.addr.port == 0) {\n\t    res_addr->dst_host.addr.port = \n\t\tpjsip_transport_get_default_port_for_type(res_addr->dst_host.type);\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Callback called by transport during send_response.\n */\nstatic void send_response_transport_cb(void *token, pjsip_tx_data *tdata,\n\t\t\t\t       pj_ssize_t sent)\n{\n    pjsip_send_state *send_state = (pjsip_send_state*) token;\n    pj_bool_t cont = PJ_FALSE;\n\n    /* Call callback, if any. */\n    if (send_state->app_cb)\n\t(*send_state->app_cb)(send_state, sent, &cont);\n\n    /* Decrement transport reference counter. */\n    pjsip_transport_dec_ref(send_state->cur_transport);\n\n    /* Decrement transmit data ref counter. */\n    pjsip_tx_data_dec_ref(tdata);\n}\n\n/*\n * Resolver calback during send_response.\n */\nstatic void send_response_resolver_cb( pj_status_t status, void *token,\n\t\t\t\t       const pjsip_server_addresses *addr )\n{\n    pjsip_send_state *send_state = (pjsip_send_state*) token;\n\n    if (status != PJ_SUCCESS) {\n\tif (send_state->app_cb) {\n\t    pj_bool_t cont = PJ_FALSE;\n\t    (*send_state->app_cb)(send_state, -status, &cont);\n\t}\n\tpjsip_tx_data_dec_ref(send_state->tdata);\n\treturn;\n    }\n\n    /* Only handle the first address resolved. */\n\n    /* Acquire transport. */\n    status = pjsip_endpt_acquire_transport2(send_state->endpt, \n\t\t\t\t\t    addr->entry[0].type,\n\t\t\t\t\t    &addr->entry[0].addr,\n\t\t\t\t\t    addr->entry[0].addr_len,\n\t\t\t\t\t    &send_state->tdata->tp_sel,\n\t\t\t\t\t    send_state->tdata,\n\t\t\t\t\t    &send_state->cur_transport);\n    if (status != PJ_SUCCESS) {\n\tif (send_state->app_cb) {\n\t    pj_bool_t cont = PJ_FALSE;\n\t    (*send_state->app_cb)(send_state, -status, &cont);\n\t}\n\tpjsip_tx_data_dec_ref(send_state->tdata);\n\treturn;\n    }\n\n    /* Update address in send_state. */\n    pj_memcpy(&send_state->tdata->dest_info.addr, addr, sizeof(*addr));\n\n    /* Send response using the transoprt. */\n    status = pjsip_transport_send( send_state->cur_transport, \n\t\t\t\t   send_state->tdata,\n\t\t\t\t   &addr->entry[0].addr,\n\t\t\t\t   addr->entry[0].addr_len,\n\t\t\t\t   send_state,\n\t\t\t\t   &send_response_transport_cb);\n    if (status == PJ_SUCCESS) {\n\tpj_ssize_t sent = send_state->tdata->buf.cur - \n\t\t\t  send_state->tdata->buf.start;\n\tsend_response_transport_cb(send_state, send_state->tdata, sent);\n\n    } else if (status == PJ_EPENDING) {\n\t/* Transport callback will be called later. */\n    } else {\n\tsend_response_transport_cb(send_state, send_state->tdata, -status);\n    }\n}\n\n/*\n * Send response.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_send_response( pjsip_endpoint *endpt,\n\t\t\t\t\t       pjsip_response_addr *res_addr,\n\t\t\t\t\t       pjsip_tx_data *tdata,\n\t\t\t\t\t       void *token,\n\t\t\t\t\t       pjsip_send_callback cb)\n{\n    /* Determine which transports and addresses to send the response,\n     * based on Section 18.2.2 of RFC 3261.\n     */\n    pjsip_send_state *send_state;\n    pj_status_t status;\n\n    /* Create structure to keep the sending state. */\n    send_state = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_send_state);\n    send_state->endpt = endpt;\n    send_state->tdata = tdata;\n    send_state->token = token;\n    send_state->app_cb = cb;\n\n    if (res_addr->transport != NULL) {\n\tsend_state->cur_transport = res_addr->transport;\n\tpjsip_transport_add_ref(send_state->cur_transport);\n\n\tstatus = pjsip_transport_send( send_state->cur_transport, tdata, \n\t\t\t\t       &res_addr->addr,\n\t\t\t\t       res_addr->addr_len,\n\t\t\t\t       send_state,\n\t\t\t\t       &send_response_transport_cb );\n\tif (status == PJ_SUCCESS) {\n\t    pj_ssize_t sent = tdata->buf.cur - tdata->buf.start;\n\t    send_response_transport_cb(send_state, tdata, sent);\n\t    return PJ_SUCCESS;\n\t} else if (status == PJ_EPENDING) {\n\t    /* Callback will be called later. */\n\t    return PJ_SUCCESS;\n\t} else {\n\t    pjsip_transport_dec_ref(send_state->cur_transport);\n\t    return status;\n\t}\n    } else {\n\t/* Copy the destination host name to TX data */\n\tpj_strdup(tdata->pool, &tdata->dest_info.name, \n\t\t  &res_addr->dst_host.addr.host);\n\n\tpjsip_endpt_resolve(endpt, tdata->pool, &res_addr->dst_host, \n\t\t\t    send_state, &send_response_resolver_cb);\n\treturn PJ_SUCCESS;\n    }\n}\n\n/*\n * Send response combo\n */\nPJ_DEF(pj_status_t) pjsip_endpt_send_response2( pjsip_endpoint *endpt,\n\t\t\t\t\t        pjsip_rx_data *rdata,\n\t\t\t\t\t        pjsip_tx_data *tdata,\n\t\t\t\t\t\tvoid *token,\n\t\t\t\t\t\tpjsip_send_callback cb)\n{\n    pjsip_response_addr res_addr;\n    pj_status_t status;\n\n    status = pjsip_get_response_addr(tdata->pool, rdata, &res_addr);\n    if (status != PJ_SUCCESS) {\n\tpjsip_tx_data_dec_ref(tdata);\n\treturn PJ_SUCCESS;\n    }\n\n    status = pjsip_endpt_send_response(endpt, &res_addr, tdata, token, cb);\n    return status;\n}\n\n\n/*\n * Send response\n */\nPJ_DEF(pj_status_t) pjsip_endpt_respond_stateless( pjsip_endpoint *endpt,\n\t\t\t\t\t\t   pjsip_rx_data *rdata,\n\t\t\t\t\t\t   int st_code,\n\t\t\t\t\t\t   const pj_str_t *st_text,\n\t\t\t\t\t\t   const pjsip_hdr *hdr_list,\n\t\t\t\t\t\t   const pjsip_msg_body *body)\n{\n    pj_status_t status;\n    pjsip_response_addr res_addr;\n    pjsip_tx_data *tdata;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(endpt && rdata, PJ_EINVAL);\n    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,\n\t\t     PJSIP_ENOTREQUESTMSG);\n\n    /* Check that no UAS transaction has been created for this request. \n     * If UAS transaction has been created for this request, application\n     * MUST send the response statefully using that transaction.\n     */\n    PJ_ASSERT_RETURN(pjsip_rdata_get_tsx(rdata)==NULL, PJ_EINVALIDOP);\n\n    /* Create response message */\n    status = pjsip_endpt_create_response( endpt, rdata, st_code, st_text, \n\t\t\t\t\t  &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Add the message headers, if any */\n    if (hdr_list) {\n\tconst pjsip_hdr *hdr = hdr_list->next;\n\twhile (hdr != hdr_list) {\n\t    pjsip_msg_add_hdr(tdata->msg, \n\t    \t\t      (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, hdr) );\n\t    hdr = hdr->next;\n\t}\n    }\n\n    /* Add the message body, if any. */\n    if (body) {\n\ttdata->msg->body = pjsip_msg_body_clone( tdata->pool, body );\n\tif (tdata->msg->body == NULL) {\n\t    pjsip_tx_data_dec_ref(tdata);\n\t    return status;\n\t}\n    }\n\n    /* Get where to send request. */\n    status = pjsip_get_response_addr( tdata->pool, rdata, &res_addr );\n    if (status != PJ_SUCCESS) {\n\tpjsip_tx_data_dec_ref(tdata);\n\treturn status;\n    }\n\n    /* Send! */\n    status = pjsip_endpt_send_response( endpt, &res_addr, tdata, NULL, NULL );\n    if (status != PJ_SUCCESS) {\n\tpjsip_tx_data_dec_ref(tdata);\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get the event string from the event ID.\n */\nPJ_DEF(const char *) pjsip_event_str(pjsip_event_id_e e)\n{\n    return event_str[e];\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_util_proxy.c",
    "content": "/* $Id: sip_util_proxy.c 4208 2012-07-18 07:52:33Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_util.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_msg.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n#include <pj/except.h>\n#include <pj/guid.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pjlib-util/md5.h>\n\n\n/**\n * Clone the incoming SIP request or response message. A forwarding proxy\n * typically would need to clone the incoming SIP message before processing\n * the message.\n *\n * Once a transmit data is created, the reference counter is initialized to 1.\n *\n * @param endpt\t    The endpoint instance.\n * @param rdata\t    The incoming SIP message.\n * @param p_tdata   Pointer to receive the transmit data containing\n *\t\t    the duplicated message.\n *\n * @return\t    PJ_SUCCESS on success.\n */\n/*\nPJ_DEF(pj_status_t) pjsip_endpt_clone_msg( pjsip_endpoint *endpt,\n\t\t\t\t\t   const pjsip_rx_data *rdata,\n\t\t\t\t\t   pjsip_tx_data **p_tdata)\n{\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n\n    status = pjsip_endpt_create_tdata(endpt, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    tdata->msg = pjsip_msg_clone(tdata->pool, rdata->msg_info.msg);\n\n    pjsip_tx_data_add_ref(tdata);\n    \n    *p_tdata = tdata;\n\n    return PJ_SUCCESS;\n}\n*/\n\n\n/*\n * Create new request message to be forwarded upstream to new destination URI \n * in uri. \n */\nPJ_DEF(pj_status_t) pjsip_endpt_create_request_fwd(pjsip_endpoint *endpt,\n\t\t\t\t\t\t   pjsip_rx_data *rdata, \n\t\t\t\t\t\t   const pjsip_uri *uri,\n\t\t\t\t\t\t   const pj_str_t *branch,\n\t\t\t\t\t\t   unsigned options,\n\t\t\t\t\t\t   pjsip_tx_data **p_tdata)\n{\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n    PJ_USE_EXCEPTION;\n\n\n    PJ_ASSERT_RETURN(endpt && rdata && p_tdata, PJ_EINVAL);\n    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG, \n\t\t     PJSIP_ENOTREQUESTMSG);\n\n    PJ_UNUSED_ARG(options);\n\n\n    /* Request forwarding rule in RFC 3261 section 16.6:\n     *\n     * For each target, the proxy forwards the request following these\n     * steps:\n     * \n     * 1.  Make a copy of the received request\n     * 2.  Update the Request-URI\n     * 3.  Update the Max-Forwards header field\n     * 4.  Optionally add a Record-route header field value\n     * 5.  Optionally add additional header fields\n     * 6.  Postprocess routing information\n     * 7.  Determine the next-hop address, port, and transport\n     * 8.  Add a Via header field value\n     * 9.  Add a Content-Length header field if necessary\n     * 10. Forward the new request\n     *\n     * Of these steps, we only do step 1-3, since the later will be\n     * done by application.\n     */\n\n    status = pjsip_endpt_create_tdata(endpt, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Always increment ref counter to 1 */\n    pjsip_tx_data_add_ref(tdata);\n\n    /* Duplicate the request */\n    PJ_TRY {\n\tpjsip_msg *dst;\n\tconst pjsip_msg *src = rdata->msg_info.msg;\n\tconst pjsip_hdr *hsrc;\n\n\t/* Create the request */\n\ttdata->msg = dst = pjsip_msg_create(tdata->pool, PJSIP_REQUEST_MSG);\n\n\t/* Duplicate request method */\n\tpjsip_method_copy(tdata->pool, &tdata->msg->line.req.method,\n\t\t\t  &src->line.req.method);\n\n\t/* Set request URI */\n\tif (uri) {\n\t    dst->line.req.uri = (pjsip_uri*) \n\t    \t\t\tpjsip_uri_clone(tdata->pool, uri);\n\t} else {\n\t    dst->line.req.uri= (pjsip_uri*)\n\t    \t\t       pjsip_uri_clone(tdata->pool, src->line.req.uri);\n\t}\n\n\t/* Clone ALL headers */\n\thsrc = src->hdr.next;\n\twhile (hsrc != &src->hdr) {\n\n\t    pjsip_hdr *hdst;\n\n\t    /* If this is the top-most Via header, insert our own before\n\t     * cloning the header.\n\t     */\n\t    if (hsrc == (pjsip_hdr*)rdata->msg_info.via) {\n\t\tpjsip_via_hdr *hvia;\n\t\thvia = pjsip_via_hdr_create(tdata->pool);\n\t\tif (branch)\n\t\t    pj_strdup(tdata->pool, &hvia->branch_param, branch);\n\t\telse {\n\t\t    pj_str_t new_branch = pjsip_calculate_branch_id(rdata);\n\t\t    pj_strdup(tdata->pool, &hvia->branch_param, &new_branch);\n\t\t}\n\t\tpjsip_msg_add_hdr(dst, (pjsip_hdr*)hvia);\n\n\t    }\n\t    /* Skip Content-Type and Content-Length as these would be \n\t     * generated when the the message is printed.\n\t     */\n\t    else if (hsrc->type == PJSIP_H_CONTENT_LENGTH ||\n\t\t     hsrc->type == PJSIP_H_CONTENT_TYPE) {\n\n\t\thsrc = hsrc->next;\n\t\tcontinue;\n\n\t    }\n#if 0\n\t    /* If this is the top-most Route header and it indicates loose\n\t     * route, remove the header.\n\t     */\n\t    else if (hsrc == (pjsip_hdr*)rdata->msg_info.route) {\n\n\t\tconst pjsip_route_hdr *hroute = (const pjsip_route_hdr*) hsrc;\n\t\tconst pjsip_sip_uri *sip_uri;\n\n\t\tif (!PJSIP_URI_SCHEME_IS_SIP(hroute->name_addr.uri) &&\n\t\t    !PJSIP_URI_SCHEME_IS_SIPS(hroute->name_addr.uri))\n\t\t{\n\t\t    /* This is a bad request! */\n\t\t    status = PJSIP_EINVALIDHDR;\n\t\t    goto on_error;\n\t\t}\n\n\t\tsip_uri = (pjsip_sip_uri*) hroute->name_addr.uri;\n\n\t\tif (sip_uri->lr_param) {\n\t\t    /* Yes lr param is present, skip this Route header */\n\t\t    hsrc = hsrc->next;\n\t\t    continue;\n\t\t}\n\t    }\n#endif\n\n\t    /* Clone the header */\n\t    hdst = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, hsrc);\n\n\t    /* If this is Max-Forward header, decrement the value */\n\t    if (hdst->type == PJSIP_H_MAX_FORWARDS) {\n\t\tpjsip_max_fwd_hdr *hmaxfwd = (pjsip_max_fwd_hdr*)hdst;\n\t\t--hmaxfwd->ivalue;\n\t    }\n\n\t    /* Append header to new request */\n\t    pjsip_msg_add_hdr(dst, hdst);\n\n\n\t    hsrc = hsrc->next;\n\t}\n\n\t/* 16.6.3:\n\t * If the copy does not contain a Max-Forwards header field, the\n         * proxy MUST add one with a field value, which SHOULD be 70.\n\t */\n\tif (rdata->msg_info.max_fwd == NULL) {\n\t    pjsip_max_fwd_hdr *hmaxfwd = \n\t\tpjsip_max_fwd_hdr_create(tdata->pool, 70);\n\t    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hmaxfwd);\n\t}\n\n\t/* Clone request body */\n\tif (src->body) {\n\t    dst->body = pjsip_msg_body_clone(tdata->pool, src->body);\n\t}\n\n    }\n    PJ_CATCH_ANY {\n\tstatus = PJ_ENOMEM;\n\tgoto on_error;\n    }\n    PJ_END\n\n\n    /* Done */\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n\non_error:\n    pjsip_tx_data_dec_ref(tdata);\n    return status;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_endpt_create_response_fwd( pjsip_endpoint *endpt,\n\t\t\t\t\t\t     pjsip_rx_data *rdata, \n\t\t\t\t\t\t     unsigned options,\n\t\t\t\t\t\t     pjsip_tx_data **p_tdata)\n{\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n    PJ_USE_EXCEPTION;\n\n    PJ_UNUSED_ARG(options);\n\n    status = pjsip_endpt_create_tdata(endpt, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pjsip_tx_data_add_ref(tdata);\n\n    PJ_TRY {\n\tpjsip_msg *dst;\n\tconst pjsip_msg *src = rdata->msg_info.msg;\n\tconst pjsip_hdr *hsrc;\n\n\t/* Create the request */\n\ttdata->msg = dst = pjsip_msg_create(tdata->pool, PJSIP_RESPONSE_MSG);\n\n\t/* Clone the status line */\n\tdst->line.status.code = src->line.status.code;\n\tpj_strdup(tdata->pool, &dst->line.status.reason, \n\t\t  &src->line.status.reason);\n\n\t/* Duplicate all headers */\n\thsrc = src->hdr.next;\n\twhile (hsrc != &src->hdr) {\n\t    \n\t    /* Skip Content-Type and Content-Length as these would be \n\t     * generated when the the message is printed.\n\t     */\n\t    if (hsrc->type == PJSIP_H_CONTENT_LENGTH ||\n\t\thsrc->type == PJSIP_H_CONTENT_TYPE) {\n\n\t\thsrc = hsrc->next;\n\t\tcontinue;\n\n\t    }\n\t    /* Remove the first Via header */\n\t    else if (hsrc == (pjsip_hdr*) rdata->msg_info.via) {\n\n\t\thsrc = hsrc->next;\n\t\tcontinue;\n\t    }\n\n\t    pjsip_msg_add_hdr(dst, \n\t    \t\t      (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hsrc));\n\n\t    hsrc = hsrc->next;\n\t}\n\n\t/* Clone message body */\n\tif (src->body)\n\t    dst->body = pjsip_msg_body_clone(tdata->pool, src->body);\n\n\n    }\n    PJ_CATCH_ANY {\n\tstatus = PJ_ENOMEM;\n\tgoto on_error;\n    }\n    PJ_END;\n\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n\non_error:\n    pjsip_tx_data_dec_ref(tdata);\n    return status;\n}\n\n\nstatic void digest2str(const unsigned char digest[], char *output)\n{\n    int i;\n    for (i = 0; i<16; ++i) {\n\tpj_val_to_hex_digit(digest[i], output);\n\toutput += 2;\n    }\n}\n\n\nPJ_DEF(pj_str_t) pjsip_calculate_branch_id( pjsip_rx_data *rdata )\n{\n    pj_md5_context ctx;\n    pj_uint8_t digest[16];\n    pj_str_t branch;\n    pj_str_t rfc3261_branch = {PJSIP_RFC3261_BRANCH_ID, \n                               PJSIP_RFC3261_BRANCH_LEN};\n\n    /* If incoming request does not have RFC 3261 branch value, create\n     * a branch value from GUID .\n     */\n    if (pj_strnicmp(&rdata->msg_info.via->branch_param, \n\t\t   &rfc3261_branch, PJSIP_RFC3261_BRANCH_LEN) != 0 ) \n    {\n\tpj_str_t tmp;\n\n\tbranch.ptr = (char*)\n\t\t     pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_BRANCH_LEN);\n\tbranch.slen = PJSIP_RFC3261_BRANCH_LEN;\n\tpj_memcpy(branch.ptr, PJSIP_RFC3261_BRANCH_ID, \n\t          PJSIP_RFC3261_BRANCH_LEN);\n\n\ttmp.ptr = branch.ptr + PJSIP_RFC3261_BRANCH_LEN + 2;\n\t*(tmp.ptr-2) = (pj_int8_t)(branch.slen+73); \n\t*(tmp.ptr-1) = (pj_int8_t)(branch.slen+99);\n\tpj_generate_unique_string( &tmp );\n\n\tbranch.slen = PJSIP_MAX_BRANCH_LEN;\n\treturn branch;\n    }\n\n    /* Create branch ID for new request by calculating MD5 hash\n     * of the branch parameter in top-most Via header.\n     */\n    pj_md5_init(&ctx);\n    pj_md5_update(&ctx, (pj_uint8_t*)rdata->msg_info.via->branch_param.ptr,\n\t\t  (unsigned)rdata->msg_info.via->branch_param.slen);\n    pj_md5_final(&ctx, digest);\n\n    branch.ptr = (char*)\n    \t\t pj_pool_alloc(rdata->tp_info.pool, \n\t\t\t       34 + PJSIP_RFC3261_BRANCH_LEN);\n    pj_memcpy(branch.ptr, PJSIP_RFC3261_BRANCH_ID, PJSIP_RFC3261_BRANCH_LEN);\n    branch.slen = PJSIP_RFC3261_BRANCH_LEN;\n    *(branch.ptr+PJSIP_RFC3261_BRANCH_LEN) = (pj_int8_t)(branch.slen+73);\n    *(branch.ptr+PJSIP_RFC3261_BRANCH_LEN+1) = (pj_int8_t)(branch.slen+99);\n    digest2str(digest, branch.ptr+PJSIP_RFC3261_BRANCH_LEN+2);\n    branch.slen = 34 + PJSIP_RFC3261_BRANCH_LEN;\n\n    return branch;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_util_proxy_wrap.cpp",
    "content": "/* $Id: sip_util_proxy_wrap.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * This file is a C++ wrapper, see ticket #886 for details.\n */\n\n#include \"sip_util_proxy.c\"\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_util_statefull.c",
    "content": "/* $Id: sip_util_statefull.c 4169 2012-06-18 09:19:58Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip/sip_util.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_transaction.h>\n#include <pjsip/sip_event.h>\n#include <pjsip/sip_errno.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\nstruct tsx_data\n{\n    void *token;\n    void (*cb)(void*, pjsip_event*);\n};\n\nstatic void mod_util_on_tsx_state(pjsip_transaction*, pjsip_event*);\n\n/* This module will be registered in pjsip_endpt.c */\n\npjsip_module mod_stateful_util = \n{\n    NULL, NULL,\t\t\t    /* prev, next.\t\t\t*/\n    { \"mod-stateful-util\", 17 },    /* Name.\t\t\t\t*/\n    -1,\t\t\t\t    /* Id\t\t\t\t*/\n    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority\t\t\t\t*/\n    NULL,\t\t\t    /* load()\t\t\t\t*/\n    NULL,\t\t\t    /* start()\t\t\t\t*/\n    NULL,\t\t\t    /* stop()\t\t\t\t*/\n    NULL,\t\t\t    /* unload()\t\t\t\t*/\n    NULL,\t\t\t    /* on_rx_request()\t\t\t*/\n    NULL,\t\t\t    /* on_rx_response()\t\t\t*/\n    NULL,\t\t\t    /* on_tx_request.\t\t\t*/\n    NULL,\t\t\t    /* on_tx_response()\t\t\t*/\n    &mod_util_on_tsx_state,\t    /* on_tsx_state()\t\t\t*/\n};\n\nstatic void mod_util_on_tsx_state(pjsip_transaction *tsx, pjsip_event *event)\n{\n    struct tsx_data *tsx_data;\n\n    /* Check if the module has been unregistered (see ticket #1535) and also\n     * verify the event type.\n     */\n    if (mod_stateful_util.id < 0 || event->type != PJSIP_EVENT_TSX_STATE)\n\treturn;\n\n    tsx_data = (struct tsx_data*) tsx->mod_data[mod_stateful_util.id];\n    if (tsx_data == NULL)\n\treturn;\n\n    if (tsx->status_code < 200)\n\treturn;\n\n    /* Call the callback, if any, and prevent the callback to be called again\n     * by clearing the transaction's module_data.\n     */\n    tsx->mod_data[mod_stateful_util.id] = NULL;\n\n    if (tsx_data->cb) {\n\t(*tsx_data->cb)(tsx_data->token, event);\n    }\n}\n\n\nPJ_DEF(pj_status_t) pjsip_endpt_send_request(  pjsip_endpoint *endpt,\n\t\t\t\t\t       pjsip_tx_data *tdata,\n\t\t\t\t\t       pj_int32_t timeout,\n\t\t\t\t\t       void *token,\n\t\t\t\t\t       pjsip_endpt_send_callback cb)\n{\n    pjsip_transaction *tsx;\n    struct tsx_data *tsx_data;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(endpt && tdata && (timeout==-1 || timeout>0), PJ_EINVAL);\n\n    /* Check that transaction layer module is registered to endpoint */\n    PJ_ASSERT_RETURN(mod_stateful_util.id != -1, PJ_EINVALIDOP);\n\n    PJ_UNUSED_ARG(timeout);\n\n    status = pjsip_tsx_create_uac(&mod_stateful_util, tdata, &tsx);\n    if (status != PJ_SUCCESS) {\n\tpjsip_tx_data_dec_ref(tdata);\n\treturn status;\n    }\n\n    pjsip_tsx_set_transport(tsx, &tdata->tp_sel);\n\n    tsx_data = PJ_POOL_ALLOC_T(tsx->pool, struct tsx_data);\n    tsx_data->token = token;\n    tsx_data->cb = cb;\n\n    tsx->mod_data[mod_stateful_util.id] = tsx_data;\n\n    status = pjsip_tsx_send_msg(tsx, NULL);\n    if (status != PJ_SUCCESS)\n\tpjsip_tx_data_dec_ref(tdata);\n\n    return status;\n}\n\n\n/*\n * Send response statefully.\n */\nPJ_DEF(pj_status_t) pjsip_endpt_respond(  pjsip_endpoint *endpt,\n\t\t\t\t\t  pjsip_module *tsx_user,\n\t\t\t\t\t  pjsip_rx_data *rdata,\n\t\t\t\t\t  int st_code,\n\t\t\t\t\t  const pj_str_t *st_text,\n\t\t\t\t\t  const pjsip_hdr *hdr_list,\n\t\t\t\t\t  const pjsip_msg_body *body,\n\t\t\t\t\t  pjsip_transaction **p_tsx )\n{\n    pj_status_t status;\n    pjsip_tx_data *tdata;\n    pjsip_transaction *tsx;\n\n    /* Validate arguments. */\n    PJ_ASSERT_RETURN(endpt && rdata, PJ_EINVAL);\n\n    if (p_tsx) *p_tsx = NULL;\n\n    /* Create response message */\n    status = pjsip_endpt_create_response( endpt, rdata, st_code, st_text, \n\t\t\t\t\t  &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Add the message headers, if any */\n    if (hdr_list) {\n\tconst pjsip_hdr *hdr = hdr_list->next;\n\twhile (hdr != hdr_list) {\n\t    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)\n\t    \t\t      pjsip_hdr_clone(tdata->pool, hdr) );\n\t    hdr = hdr->next;\n\t}\n    }\n\n    /* Add the message body, if any. */\n    if (body) {\n\ttdata->msg->body = pjsip_msg_body_clone( tdata->pool, body );\n\tif (tdata->msg->body == NULL) {\n\t    pjsip_tx_data_dec_ref(tdata);\n\t    return status;\n\t}\n    }\n\n    /* Create UAS transaction. */\n    status = pjsip_tsx_create_uas(tsx_user, rdata, &tsx);\n    if (status != PJ_SUCCESS) {\n\tpjsip_tx_data_dec_ref(tdata);\n\treturn status;\n    }\n\n    /* Feed the request to the transaction. */\n    pjsip_tsx_recv_msg(tsx, rdata);\n\n    /* Send the message. */\n    status = pjsip_tsx_send_msg(tsx, tdata);\n    if (status != PJ_SUCCESS) {\n\tpjsip_tx_data_dec_ref(tdata);\n    } else if (p_tsx) {\n\t*p_tsx = tsx;\n    }\n\n    return status;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip/sip_util_wrap.cpp",
    "content": "/* $Id: sip_util_wrap.cpp 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * This file is a C++ wrapper, see ticket #886 for details.\n */\n\n#include \"sip_util.c\"\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-simple/errno.c",
    "content": "/* $Id: errno.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-simple/errno.h>\n#include <pj/string.h>\n\n/* PJSIP-SIMPLE's own error codes/messages \n * MUST KEEP THIS ARRAY SORTED!!\n * Message must be limited to 64 chars!\n */\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n\nstatic const struct \n{\n    int code;\n    const char *msg;\n} err_str[] = \n{\n    /* Event errors */\n    { PJSIP_SIMPLE_ENOPKG,\t    \"No SIP event package with the specified name\" },\n    { PJSIP_SIMPLE_EPKGEXISTS,\t    \"SIP event package already exist\" },\n\n    /* Presence errors */\n    { PJSIP_SIMPLE_ENOTSUBSCRIBE,   \"Expecting SUBSCRIBE request\" },\n    { PJSIP_SIMPLE_ENOPRESENCE,\t    \"No presence associated with the subscription\" },\n    { PJSIP_SIMPLE_ENOPRESENCEINFO, \"No presence info in the server subscription\" },\n    { PJSIP_SIMPLE_EBADCONTENT,\t    \"Bad Content-Type for presence\" },\n    { PJSIP_SIMPLE_EBADPIDF,\t    \"Bad PIDF content for presence\" },\n    { PJSIP_SIMPLE_EBADXPIDF,\t    \"Bad XPIDF content for presence\" },\n    { PJSIP_SIMPLE_EBADRPID,\t    \"Invalid or bad RPID document\"},\n\n    /* isComposing errors. */\n    { PJSIP_SIMPLE_EBADISCOMPOSE,   \"Bad isComposing indication/XML message\" },\n};\n\n\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n\n/*\n * pjsipsimple_strerror()\n */\nPJ_DEF(pj_str_t) pjsipsimple_strerror( pj_status_t statcode, \n\t\t\t\t       char *buf, pj_size_t bufsize )\n{\n    pj_str_t errstr;\n\n#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)\n\n    if (statcode >= PJSIP_SIMPLE_ERRNO_START && \n\tstatcode < PJSIP_SIMPLE_ERRNO_START + PJ_ERRNO_SPACE_SIZE)\n    {\n\t/* Find the error in the table.\n\t * Use binary search!\n\t */\n\tint first = 0;\n\tint n = PJ_ARRAY_SIZE(err_str);\n\n\twhile (n > 0) {\n\t    int half = n/2;\n\t    int mid = first + half;\n\n\t    if (err_str[mid].code < statcode) {\n\t\tfirst = mid+1;\n\t\tn -= (half+1);\n\t    } else if (err_str[mid].code > statcode) {\n\t\tn = half;\n\t    } else {\n\t\tfirst = mid;\n\t\tbreak;\n\t    }\n\t}\n\n\n\tif (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {\n\t    pj_str_t msg;\n\t    \n\t    msg.ptr = (char*)err_str[first].msg;\n\t    msg.slen = pj_ansi_strlen(err_str[first].msg);\n\n\t    errstr.ptr = buf;\n\t    pj_strncpy_with_null(&errstr, &msg, bufsize);\n\t    return errstr;\n\n\t} \n    }\n\n#endif\t/* PJ_HAS_ERROR_STRING */\n\n\n    /* Error not found. */\n    errstr.ptr = buf;\n    errstr.slen = pj_ansi_snprintf(buf, bufsize, \n\t\t\t\t   \"Unknown pjsip-simple error %d\",\n \t\t\t\t   statcode);\n    if (errstr.slen < 1 || errstr.slen >= (pj_ssize_t)bufsize)\n\terrstr.slen = bufsize - 1;\n    return errstr;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-simple/evsub.c",
    "content": "/* $Id: evsub.c 4447 2013-03-21 08:28:21Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-simple/evsub.h>\n#include <pjsip-simple/evsub_msg.h>\n#include <pjsip-simple/errno.h>\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_dialog.h>\n#include <pjsip/sip_auth.h>\n#include <pjsip/sip_transaction.h>\n#include <pjsip/sip_event.h>\n#include <pj/assert.h>\n#include <pj/guid.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n\n\n#define THIS_FILE\t\"evsub.c\"\n\n/*\n * Global constant\n */\n\n/* Let's define this enum, so that it'll trigger compilation error\n * when somebody define the same enum in sip_msg.h\n */\nenum\n{\n    PJSIP_SUBSCRIBE_METHOD = PJSIP_OTHER_METHOD,\n    PJSIP_NOTIFY_METHOD = PJSIP_OTHER_METHOD\n};\n\nPJ_DEF_DATA(const pjsip_method) pjsip_subscribe_method = \n{\n    (pjsip_method_e) PJSIP_SUBSCRIBE_METHOD,\n    { \"SUBSCRIBE\", 9 }\n};\n\nPJ_DEF_DATA(const pjsip_method) pjsip_notify_method = \n{\n    (pjsip_method_e) PJSIP_NOTIFY_METHOD,\n    { \"NOTIFY\", 6 }\n};\n\n/**\n * SUBSCRIBE method constant.\n */\nPJ_DEF(const pjsip_method*) pjsip_get_subscribe_method()\n{\n    return &pjsip_subscribe_method;\n}\n\n/**\n * NOTIFY method constant.\n */\nPJ_DEF(const pjsip_method*) pjsip_get_notify_method()\n{\n    return &pjsip_notify_method;\n}\n\n\n/*\n * Static prototypes.\n */\nstatic void\t   mod_evsub_on_tsx_state(pjsip_transaction*, pjsip_event*);\nstatic pj_status_t mod_evsub_unload(void);\n\n\n/*\n * State names.\n */\nstatic pj_str_t evsub_state_names[] = \n{\n    { \"NULL\",\t    4},\n    { \"SENT\",\t    4},\n    { \"ACCEPTED\",   8},\n    { \"PENDING\",    7},\n    { \"ACTIVE\",\t    6},\n    { \"TERMINATED\", 10},\n    { \"UNKNOWN\",    7}\n};\n\n/*\n * Timer constants.\n */\n\n/* Number of seconds to send SUBSCRIBE before the actual expiration */\n#define TIME_UAC_REFRESH\tPJSIP_EVSUB_TIME_UAC_REFRESH\n\n/* Time to wait for the final NOTIFY after sending unsubscription */\n#define TIME_UAC_TERMINATE\tPJSIP_EVSUB_TIME_UAC_TERMINATE\n\n/* If client responds NOTIFY with non-2xx final response (such as 401),\n * wait for this seconds for further NOTIFY, otherwise client will\n * unsubscribe\n */\n#define TIME_UAC_WAIT_NOTIFY\tPJSIP_EVSUB_TIME_UAC_WAIT_NOTIFY\n\n\n/*\n * Timer id\n */\nenum timer_id\n{\n    /* No timer. */\n    TIMER_TYPE_NONE,\n\n    /* Time to refresh client subscription. \n     * The action is to call on_client_refresh() callback.\n     */\n    TIMER_TYPE_UAC_REFRESH,\n\n    /* UAS timeout after to subscription refresh. \n     * The action is to call on_server_timeout() callback.\n     */\n    TIMER_TYPE_UAS_TIMEOUT,\n\n    /* UAC waiting for final NOTIFY after unsubscribing \n     * The action is to terminate.\n     */\n    TIMER_TYPE_UAC_TERMINATE,\n\n    /* UAC waiting for further NOTIFY after sending non-2xx response to \n     * NOTIFY. The action is to unsubscribe.\n     */\n    TIMER_TYPE_UAC_WAIT_NOTIFY,\n\n    /* Max nb of timer types. */\n    TIMER_TYPE_MAX\n};\n\nstatic const char *timer_names[] = \n{\n    \"None\",\n    \"UAC_REFRESH\",\n    \"UAS_TIMEOUT\",\n    \"UAC_TERMINATE\",\n    \"UAC_WAIT_NOTIFY\",\n    \"INVALID_TIMER\"\n};\n\n/*\n * Definition of event package.\n */\nstruct evpkg\n{\n    PJ_DECL_LIST_MEMBER(struct evpkg);\n\n    pj_str_t\t\t pkg_name;\n    pjsip_module\t*pkg_mod;\n    unsigned\t\t pkg_expires;\n    pjsip_accept_hdr\t*pkg_accept;\n};\n\n\n/*\n * Event subscription module (mod-evsub).\n */\nstatic struct mod_evsub\n{\n    pjsip_module\t     mod;\n    pj_pool_t\t\t    *pool;\n    pjsip_endpoint\t    *endpt;\n    struct evpkg\t     pkg_list;\n    pjsip_allow_events_hdr  *allow_events_hdr;\n\n} mod_evsub = \n{\n    {\n\tNULL, NULL,\t\t\t    /* prev, next.\t\t*/\n\t{ \"mod-evsub\", 9 },\t\t    /* Name.\t\t\t*/\n\t-1,\t\t\t\t    /* Id\t\t\t*/\n\tPJSIP_MOD_PRIORITY_DIALOG_USAGE,    /* Priority\t\t\t*/\n\tNULL,\t\t\t\t    /* load()\t\t\t*/\n\tNULL,\t\t\t\t    /* start()\t\t\t*/\n\tNULL,\t\t\t\t    /* stop()\t\t\t*/\n\t&mod_evsub_unload,\t\t    /* unload()\t\t\t*/\n\tNULL,\t\t\t\t    /* on_rx_request()\t\t*/\n\tNULL,\t\t\t\t    /* on_rx_response()\t\t*/\n\tNULL,\t\t\t\t    /* on_tx_request.\t\t*/\n\tNULL,\t\t\t\t    /* on_tx_response()\t\t*/\n\t&mod_evsub_on_tsx_state,\t    /* on_tsx_state()\t\t*/\n    }\n};\n\n\n/*\n * Event subscription session.\n */\nstruct pjsip_evsub\n{\n    char\t\t  obj_name[PJ_MAX_OBJ_NAME]; /**< Name.\t\t    */\n    pj_pool_t\t\t *pool;\t\t/**< Pool.\t\t\t    */\n    pjsip_endpoint\t *endpt;\t/**< Endpoint instance.\t\t    */\n    pjsip_dialog\t *dlg;\t\t/**< Underlying dialog.\t\t    */\n    struct evpkg\t *pkg;\t\t/**< The event package.\t\t    */\n    unsigned\t\t  option;\t/**< Options.\t\t\t    */\n    pjsip_evsub_user\t  user;\t\t/**< Callback.\t\t\t    */\n    pj_bool_t\t\t  call_cb;\t/**< Notify callback?\t\t    */\n    pjsip_role_e\t  role;\t\t/**< UAC=subscriber, UAS=notifier   */\n    pjsip_evsub_state\t  state;\t/**< Subscription state.\t    */\n    pj_str_t\t\t  state_str;\t/**< String describing the state.   */\n    pjsip_evsub_state\t  dst_state;\t/**< Pending state to be set.\t    */\n    pj_str_t\t\t  dst_state_str;/**< Pending state to be set.\t    */\n    pj_str_t\t\t  term_reason;\t/**< Termination reason.\t    */\n    pjsip_method\t  method;\t/**< Method that established subscr.*/\n    pjsip_event_hdr\t *event;\t/**< Event description.\t\t    */\n    pjsip_expires_hdr\t *expires;\t/**< Expires header\t\t    */\n    pjsip_accept_hdr\t *accept;\t/**< Local Accept header.\t    */\n    pjsip_hdr             sub_hdr_list; /**< User-defined header.           */\n\n    pj_time_val\t\t  refresh_time;\t/**< Time to refresh.\t\t    */\n    pj_timer_entry\t  timer;\t/**< Internal timer.\t\t    */\n    int\t\t\t  pending_tsx;\t/**< Number of pending transactions.*/\n    pjsip_transaction\t *pending_sub;\t/**< Pending UAC SUBSCRIBE tsx.\t    */\n    pj_timer_entry\t *pending_sub_timer; /**< Stop pending sub timer.   */\n    pj_grp_lock_t\t *grp_lock;\t/* Session group lock\t    */\n\n    void\t\t *mod_data[PJSIP_MAX_MODULE];\t/**< Module data.   */\n};\n\n\n/*\n * This is the structure that will be \"attached\" to dialog.\n * The purpose is to allow multiple subscriptions inside a dialog.\n */\nstruct dlgsub\n{\n    PJ_DECL_LIST_MEMBER(struct dlgsub);\n    pjsip_evsub *sub;\n};\n\n\n/* Static vars. */\nstatic const pj_str_t STR_EVENT\t       = { \"Event\", 5 };\nstatic const pj_str_t STR_EVENT_S      = { \"o\", 1 };\nstatic const pj_str_t STR_SUB_STATE    = { \"Subscription-State\", 18 };\nstatic const pj_str_t STR_TERMINATED   = { \"terminated\", 10 };\nstatic const pj_str_t STR_ACTIVE       = { \"active\", 6 };\nstatic const pj_str_t STR_PENDING      = { \"pending\", 7 };\nstatic const pj_str_t STR_TIMEOUT      = { \"timeout\", 7};\nstatic const pj_str_t STR_RETRY_AFTER  = { \"Retry-After\", 11 };\n\n\n/*\n * On unload module.\n */\nstatic pj_status_t mod_evsub_unload(void)\n{\n    pjsip_endpt_release_pool(mod_evsub.endpt, mod_evsub.pool);\n    mod_evsub.pool = NULL;\n\n    return PJ_SUCCESS;\n}\n\n/* Proto for pjsipsimple_strerror().\n * Defined in errno.c\n */\nPJ_DECL(pj_str_t) pjsipsimple_strerror( pj_status_t statcode, \n\t\t\t\t        char *buf, pj_size_t bufsize );\n\n/*\n * Init and register module.\n */\nPJ_DEF(pj_status_t) pjsip_evsub_init_module(pjsip_endpoint *endpt)\n{\n    pj_status_t status;\n    pj_str_t method_tags[] = {\n\t{ \"SUBSCRIBE\", 9},\n\t{ \"NOTIFY\", 6}\n    };\n\n    status = pj_register_strerror(PJSIP_SIMPLE_ERRNO_START,\n\t\t\t\t  PJ_ERRNO_SPACE_SIZE,\n\t\t\t\t  &pjsipsimple_strerror);\n    pj_assert(status == PJ_SUCCESS);\n\n    PJ_ASSERT_RETURN(endpt != NULL, PJ_EINVAL);\n    PJ_ASSERT_RETURN(mod_evsub.mod.id == -1, PJ_EINVALIDOP);\n\n    /* Keep endpoint for future reference: */\n    mod_evsub.endpt = endpt;\n\n    /* Init event package list: */\n    pj_list_init(&mod_evsub.pkg_list);\n\n    /* Create pool: */\n    mod_evsub.pool = pjsip_endpt_create_pool(endpt, \"evsub\", 512, 512);\n    if (!mod_evsub.pool)\n\treturn PJ_ENOMEM;\n\n    /* Register module: */\n    status = pjsip_endpt_register_module(endpt, &mod_evsub.mod);\n    if (status  != PJ_SUCCESS)\n\tgoto on_error;\n \n    /* Create Allow-Events header: */\n    mod_evsub.allow_events_hdr = pjsip_allow_events_hdr_create(mod_evsub.pool);\n\n    /* Register SIP-event specific headers parser: */\n    pjsip_evsub_init_parser();\n\n    /* Register new methods SUBSCRIBE and NOTIFY in Allow-ed header */\n    pjsip_endpt_add_capability(endpt, &mod_evsub.mod, PJSIP_H_ALLOW, NULL,\n\t\t\t       2, method_tags);\n\n    /* Done. */\n    return PJ_SUCCESS;\n\non_error:\n    if (mod_evsub.pool) {\n\tpjsip_endpt_release_pool(endpt, mod_evsub.pool);\n\tmod_evsub.pool = NULL;\n    }\n    mod_evsub.endpt = NULL;\n    return status;\n}\n\n\n/*\n * Get the instance of the module.\n */\nPJ_DEF(pjsip_module*) pjsip_evsub_instance(void)\n{\n    PJ_ASSERT_RETURN(mod_evsub.mod.id != -1, NULL);\n\n    return &mod_evsub.mod;\n}\n\n\n/*\n * Get the event subscription instance in the transaction.\n */\nPJ_DEF(pjsip_evsub*) pjsip_tsx_get_evsub(pjsip_transaction *tsx)\n{\n    return (pjsip_evsub*) tsx->mod_data[mod_evsub.mod.id];\n}\n\n\n/*\n * Set event subscription's module data.\n */\nPJ_DEF(void) pjsip_evsub_set_mod_data( pjsip_evsub *sub, unsigned mod_id,\n\t\t\t\t       void *data )\n{\n    PJ_ASSERT_ON_FAIL(mod_id < PJSIP_MAX_MODULE, return);\n    sub->mod_data[mod_id] = data;\n}\n\n\n/*\n * Get event subscription's module data.\n */\nPJ_DEF(void*) pjsip_evsub_get_mod_data( pjsip_evsub *sub, unsigned mod_id )\n{\n    PJ_ASSERT_RETURN(mod_id < PJSIP_MAX_MODULE, NULL);\n    return sub->mod_data[mod_id];\n}\n\n\n/*\n * Find registered event package with matching name.\n */\nstatic struct evpkg* find_pkg(const pj_str_t *event_name)\n{\n    struct evpkg *pkg;\n\n    pkg = mod_evsub.pkg_list.next;\n    while (pkg != &mod_evsub.pkg_list) {\n\n\tif (pj_stricmp(&pkg->pkg_name, event_name) == 0) {\n\t    return pkg;\n\t}\n\n\tpkg = pkg->next;\n    }\n\n    return NULL;\n}\n\n/*\n * Register an event package\n */\nPJ_DEF(pj_status_t) pjsip_evsub_register_pkg( pjsip_module *pkg_mod,\n\t\t\t\t\t      const pj_str_t *event_name,\n\t\t\t\t\t      unsigned expires,\n\t\t\t\t\t      unsigned accept_cnt,\n\t\t\t\t\t      const pj_str_t accept[])\n{\n    struct evpkg *pkg;\n    unsigned i;\n\n    PJ_ASSERT_RETURN(pkg_mod && event_name, PJ_EINVAL);\n    PJ_ASSERT_RETURN(accept_cnt < PJ_ARRAY_SIZE(pkg->pkg_accept->values), \n\t\t     PJ_ETOOMANY);\n\n    /* Make sure evsub module has been initialized */\n    PJ_ASSERT_RETURN(mod_evsub.mod.id != -1, PJ_EINVALIDOP);\n\n    /* Make sure no module with the specified name already registered: */\n\n    PJ_ASSERT_RETURN(find_pkg(event_name) == NULL, PJSIP_SIMPLE_EPKGEXISTS);\n\n\n    /* Create new event package: */\n\n    pkg = PJ_POOL_ALLOC_T(mod_evsub.pool, struct evpkg);\n    pkg->pkg_mod = pkg_mod;\n    pkg->pkg_expires = expires;\n    pj_strdup(mod_evsub.pool, &pkg->pkg_name, event_name);\n\n    pkg->pkg_accept = pjsip_accept_hdr_create(mod_evsub.pool);\n    pkg->pkg_accept->count = accept_cnt;\n    for (i=0; i<accept_cnt; ++i) {\n\tpj_strdup(mod_evsub.pool, &pkg->pkg_accept->values[i], &accept[i]);\n    }\n\n    /* Add to package list: */\n\n    pj_list_push_back(&mod_evsub.pkg_list, pkg);\n\n    /* Add to Allow-Events header: */\n\n    if (mod_evsub.allow_events_hdr->count !=\n\tPJ_ARRAY_SIZE(mod_evsub.allow_events_hdr->values))\n    {\n\tmod_evsub.allow_events_hdr->values[mod_evsub.allow_events_hdr->count] =\n\t    pkg->pkg_name;\n\t++mod_evsub.allow_events_hdr->count;\n    }\n    \n    /* Add to endpoint's Accept header */\n    pjsip_endpt_add_capability(mod_evsub.endpt, &mod_evsub.mod,\n\t\t\t       PJSIP_H_ACCEPT, NULL,\n\t\t\t       pkg->pkg_accept->count,\n\t\t\t       pkg->pkg_accept->values);\n\n\n    /* Done */\n\n    PJ_LOG(5,(THIS_FILE, \"Event pkg \\\"%.*s\\\" registered by %.*s\",\n\t      (int)event_name->slen, event_name->ptr,\n\t      (int)pkg_mod->name.slen, pkg_mod->name.ptr));\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Retrieve Allow-Events header\n */\nPJ_DEF(const pjsip_hdr*) pjsip_evsub_get_allow_events_hdr(pjsip_module *m)\n{\n    struct mod_evsub *mod;\n\n    if (m == NULL)\n\tm = pjsip_evsub_instance();\n\n    mod = (struct mod_evsub*)m;\n\n    return (pjsip_hdr*) mod->allow_events_hdr;\n}\n\n\n/*\n * Update expiration time.\n */\nstatic void update_expires( pjsip_evsub *sub, pj_uint32_t interval )\n{\n    pj_gettimeofday(&sub->refresh_time);\n    sub->refresh_time.sec += interval;\n}\n\nPJ_DEF(void) pjsip_evsub_update_expires( pjsip_evsub *sub, pj_uint32_t interval )\n{\n    update_expires(sub, interval);\n}\n\n\n/* \n * Schedule timer.\n */\nstatic void set_timer( pjsip_evsub *sub, int timer_id,\n\t\t       pj_int32_t seconds)\n{\n    if (sub->timer.id != TIMER_TYPE_NONE) {\n\tPJ_LOG(5,(sub->obj_name, \"%s %s timer\", \n\t\t  (timer_id==sub->timer.id ? \"Updating\" : \"Cancelling\"),\n\t\t  timer_names[sub->timer.id]));\n\tpjsip_endpt_cancel_timer(sub->endpt, &sub->timer);\n\tsub->timer.id = TIMER_TYPE_NONE;\n    }\n\n    if (timer_id != TIMER_TYPE_NONE) {\n\tpj_time_val timeout;\n\n\tPJ_ASSERT_ON_FAIL(seconds > 0, return);\n\tPJ_ASSERT_ON_FAIL(timer_id>TIMER_TYPE_NONE && timer_id<TIMER_TYPE_MAX,\n\t\t\t  return);\n\n\ttimeout.sec = seconds;\n\ttimeout.msec = 0;\n\n\tpj_timer_heap_schedule_w_grp_lock(\n\t\t\t    pjsip_endpt_get_timer_heap(sub->endpt),\n\t\t\t    &sub->timer, &timeout, timer_id, sub->grp_lock);\n\n\tPJ_LOG(5,(sub->obj_name, \"Timer %s scheduled in %d seconds\", \n\t\t  timer_names[sub->timer.id], timeout.sec));\n    }\n}\n\nPJ_DEF(void) pjsip_evsub_set_timer( pjsip_evsub *sub, int timer_id,\n\t\t                    pj_int32_t seconds)\n{\n    set_timer(sub, timer_id, seconds);\n}\n\n\n/*\n * Destructor.\n */\nstatic void evsub_on_destroy(void *obj)\n{\n    pjsip_evsub *sub = (pjsip_evsub*)obj;\n\n    /* Decrement dialog's session */\n    pjsip_dlg_dec_session(sub->dlg, &mod_evsub.mod);\n}\n\n\n/*\n * Destroy session.\n */\nstatic void evsub_destroy( pjsip_evsub *sub )\n{\n    struct dlgsub *dlgsub_head, *dlgsub;\n\n    PJ_LOG(4,(sub->obj_name, \"Subscription destroyed\"));\n\n    /* Kill timer */\n    set_timer(sub, TIMER_TYPE_NONE, 0);\n\n    /* Kill timer for stopping pending sub (see ticket #1807) */\n    if (sub->pending_sub_timer && sub->pending_sub_timer->id == 1) {\n\tpjsip_endpt_cancel_timer(sub->endpt, sub->pending_sub_timer);\n\tsub->pending_sub_timer->id = 0;\n\tsub->pending_sub_timer = NULL;\n    }\n\n    /* Remove this session from dialog's list of subscription */\n    dlgsub_head = (struct dlgsub *) sub->dlg->mod_data[mod_evsub.mod.id];\n    dlgsub = dlgsub_head->next;\n    while (dlgsub != dlgsub_head) {\n\t\n\tif (dlgsub->sub == sub) {\n\t    pj_list_erase(dlgsub);\n\t    break;\n\t}\n\n\tdlgsub = dlgsub->next;\n    }\n\n    pj_grp_lock_dec_ref(sub->grp_lock);\n}\n\n/*\n * Set subscription session state.\n */\nstatic void set_state( pjsip_evsub *sub, pjsip_evsub_state state,\n\t\t       const pj_str_t *state_str, pjsip_event *event,\n\t\t       const pj_str_t *reason)\n{\n    pjsip_evsub_state prev_state = sub->state;\n    pj_str_t old_state_str = sub->state_str;\n    pjsip_event dummy_event;\n\n    sub->state = state;\n\n    if (state_str && state_str->slen)\n\tpj_strdup_with_null(sub->pool, &sub->state_str, state_str);\n    else\n\tsub->state_str = evsub_state_names[state];\n\n    if (reason && sub->term_reason.slen==0)\n\tpj_strdup(sub->pool, &sub->term_reason, reason);\n\n    PJ_LOG(4,(sub->obj_name, \n\t      \"Subscription state changed %.*s --> %.*s\",\n\t      (int)old_state_str.slen,\n\t      old_state_str.ptr,\n\t      (int)sub->state_str.slen,\n\t      sub->state_str.ptr));\n    pj_log_push_indent();\n\n    /* don't call the callback with NULL event, it may crash the app! */\n    if (!event) {\n\tPJSIP_EVENT_INIT_USER(dummy_event, 0, 0, 0, 0);\n\tevent = &dummy_event;\n    }\n\n    if (sub->user.on_evsub_state && sub->call_cb)\n\t(*sub->user.on_evsub_state)(sub, event);\n\n    if (state == PJSIP_EVSUB_STATE_TERMINATED &&\n\tprev_state != PJSIP_EVSUB_STATE_TERMINATED) \n    {\n\t/* Kill any timer. */\n\tset_timer(sub, TIMER_TYPE_NONE, 0);\n\n\tif (sub->pending_tsx == 0) {\n\t    evsub_destroy(sub);\n\t}\n    }\n\n    pj_log_pop_indent();\n}\n\n\n/*\n * Timer callback.\n */\nstatic void on_timer( pj_timer_heap_t *timer_heap,\n\t\t      struct pj_timer_entry *entry)\n{\n    pjsip_evsub *sub;\n    int timer_id;\n\n    PJ_UNUSED_ARG(timer_heap);\n\n    sub = (pjsip_evsub*) entry->user_data;\n\n    pjsip_dlg_inc_lock(sub->dlg);\n\n    /* If this timer entry has just been rescheduled or cancelled\n     * while waiting for dialog mutex, just return (see #1885 scenario 1).\n     */\n    if (pj_timer_entry_running(entry) || entry->id == TIMER_TYPE_NONE) {\n\tpjsip_dlg_dec_lock(sub->dlg);\n\treturn;\n    }\n\n    timer_id = entry->id;\n    entry->id = TIMER_TYPE_NONE;\n\n    switch (timer_id) {\n\n    case TIMER_TYPE_UAC_REFRESH:\n\t/* Time for UAC to refresh subscription */\n\tif (sub->user.on_client_refresh && sub->call_cb) {\n\t    (*sub->user.on_client_refresh)(sub);\n\t} else {\n\t    pjsip_tx_data *tdata;\n\t    pj_status_t status;\n\n\t    PJ_LOG(5,(sub->obj_name, \"Refreshing subscription.\"));\n\t    pj_log_push_indent();\n\t    status = pjsip_evsub_initiate(sub, NULL, \n\t\t\t\t\t  sub->expires->ivalue,\n\t\t\t\t\t  &tdata);\n\t    if (status == PJ_SUCCESS)\n\t\tpjsip_evsub_send_request(sub, tdata);\n\n\t    pj_log_pop_indent();\n\t}\n\tbreak;\n\n    case TIMER_TYPE_UAS_TIMEOUT:\n\t/* Refresh from UAC has not been received */\n\tif (sub->user.on_server_timeout && sub->call_cb) {\n\t    (*sub->user.on_server_timeout)(sub);\n\t} else {\n\t    pjsip_tx_data *tdata;\n\t    pj_status_t status;\n\n\t    PJ_LOG(5,(sub->obj_name, \"Timeout waiting for refresh. \"\n\t\t\t\t     \"Sending NOTIFY to terminate.\"));\n\t    pj_log_push_indent();\n\t    status = pjsip_evsub_notify( sub, PJSIP_EVSUB_STATE_TERMINATED, \n\t\t\t\t\t NULL, &STR_TIMEOUT, &tdata);\n\t    if (status == PJ_SUCCESS)\n\t\tpjsip_evsub_send_request(sub, tdata);\n\n\t    pj_log_pop_indent();\n\t}\n\tbreak;\n\n    case TIMER_TYPE_UAC_TERMINATE:\n\t{\n\t    pj_str_t timeout = {\"timeout\", 7};\n\n\t    PJ_LOG(5,(sub->obj_name, \"Timeout waiting for final NOTIFY. \"\n\t\t\t\t     \"Terminating..\"));\n\t    pj_log_push_indent();\n\t    set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL, \n\t\t      &timeout);\n\t    pj_log_pop_indent();\n\t}\n\tbreak;\n\n    case TIMER_TYPE_UAC_WAIT_NOTIFY:\n\t{\n\t    pjsip_tx_data *tdata;\n\t    pj_status_t status;\n\n\t    PJ_LOG(5,(sub->obj_name, \n\t\t     \"Timeout waiting for subsequent NOTIFY (we did \"\n\t\t     \"send non-2xx response for previous NOTIFY). \"\n\t\t     \"Unsubscribing..\"));\n\t    pj_log_push_indent();\n\t    status = pjsip_evsub_initiate( sub, NULL, 0, &tdata);\n\t    if (status == PJ_SUCCESS)\n\t\tpjsip_evsub_send_request(sub, tdata);\n\n\t    pj_log_pop_indent();\n\t}\n\tbreak;\n\n    default:\n\tpj_assert(!\"Invalid timer id\");\n    }\n\n    pjsip_dlg_dec_lock(sub->dlg);\n}\n\n\n/*\n * Create subscription session, used for both client and notifier.\n */\nstatic pj_status_t evsub_create( pjsip_dialog *dlg,\n\t\t\t\t pjsip_role_e role,\n\t\t\t\t const pjsip_evsub_user *user_cb,\n\t\t\t\t const pj_str_t *event,\n\t\t\t\t unsigned option,\n\t\t\t\t pjsip_evsub **p_evsub )\n{\n    pjsip_evsub *sub;\n    struct evpkg *pkg;\n    struct dlgsub *dlgsub_head, *dlgsub;\n    pj_status_t status;\n\n    /* Make sure there's package register for the event name: */\n\n    pkg = find_pkg(event);\n    if (pkg == NULL)\n\treturn PJSIP_SIMPLE_ENOPKG;\n\n\n    /* Must lock dialog before using pool etc. */\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Init attributes: */\n\n    sub = PJ_POOL_ZALLOC_T(dlg->pool, struct pjsip_evsub);\n    sub->pool = dlg->pool;\n    sub->endpt = dlg->endpt;\n    sub->dlg = dlg;\n    sub->pkg = pkg;\n    sub->role = role;\n    sub->call_cb = PJ_TRUE;\n    sub->option = option;\n    sub->state = PJSIP_EVSUB_STATE_NULL;\n    sub->state_str = evsub_state_names[sub->state];\n    sub->expires = pjsip_expires_hdr_create(sub->pool, pkg->pkg_expires);\n    sub->accept = (pjsip_accept_hdr*) \n    \t\t  pjsip_hdr_clone(sub->pool, pkg->pkg_accept);\n    pj_list_init(&sub->sub_hdr_list);\n\n    sub->timer.user_data = sub;\n    sub->timer.cb = &on_timer;\n\n    /* Set name. */\n    pj_ansi_snprintf(sub->obj_name, PJ_ARRAY_SIZE(sub->obj_name),\n\t\t     \"evsub%p\", sub);\n\n\n    /* Copy callback, if any: */\n    if (user_cb)\n\tpj_memcpy(&sub->user, user_cb, sizeof(pjsip_evsub_user));\n\n\n    /* Create Event header: */\n    sub->event = pjsip_event_hdr_create(sub->pool);\n    pj_strdup(sub->pool, &sub->event->event_type, event);\n\n\n    /* Check if another subscription has been registered to the dialog. In\n     * that case, just add ourselves to the subscription list, otherwise\n     * create and register a new subscription list.\n     */\n    if (pjsip_dlg_has_usage(dlg, &mod_evsub.mod)) {\n\tdlgsub_head = (struct dlgsub*) dlg->mod_data[mod_evsub.mod.id];\n\tdlgsub = PJ_POOL_ALLOC_T(sub->pool, struct dlgsub);\n\tdlgsub->sub = sub;\n\tpj_list_push_back(dlgsub_head, dlgsub);\n    } else {\n\tdlgsub_head = PJ_POOL_ALLOC_T(sub->pool, struct dlgsub);\n\tdlgsub = PJ_POOL_ALLOC_T(sub->pool, struct dlgsub);\n\tdlgsub->sub = sub;\n\n\tpj_list_init(dlgsub_head);\n\tpj_list_push_back(dlgsub_head, dlgsub);\n\n\n\t/* Register as dialog usage: */\n\n\tstatus = pjsip_dlg_add_usage(dlg, &mod_evsub.mod, dlgsub_head);\n\tif (status != PJ_SUCCESS) {\n\t    pjsip_dlg_dec_lock(dlg);\n\t    return status;\n\t}\n    }\n\n    PJ_LOG(5,(sub->obj_name, \"%s subscription created, using dialog %s\",\n\t      (role==PJSIP_ROLE_UAC ? \"UAC\" : \"UAS\"),\n\t      dlg->obj_name));\n\n    *p_evsub = sub;\n    pjsip_dlg_dec_lock(dlg);\n\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Create client subscription session.\n */\nPJ_DEF(pj_status_t) pjsip_evsub_create_uac( pjsip_dialog *dlg,\n\t\t\t\t\t    const pjsip_evsub_user *user_cb,\n\t\t\t\t\t    const pj_str_t *event,\n\t\t\t\t\t    unsigned option,\n\t\t\t\t\t    pjsip_evsub **p_evsub)\n{\n    pjsip_evsub *sub;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(dlg && event && p_evsub, PJ_EINVAL);\n\n    pjsip_dlg_inc_lock(dlg);\n    status = evsub_create(dlg, PJSIP_UAC_ROLE, user_cb, event, option, &sub);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Add unique Id to Event header, only when PJSIP_EVSUB_NO_EVENT_ID\n     * is not specified.\n     */\n    if ((option & PJSIP_EVSUB_NO_EVENT_ID) == 0) {\n\tpj_create_unique_string(sub->pool, &sub->event->id_param);\n    }\n\n    /* Increment dlg session. */\n    pjsip_dlg_inc_session(sub->dlg, &mod_evsub.mod);\n\n    /* Init group lock */\n    status = pj_grp_lock_create(dlg->pool, NULL, &sub->grp_lock);\n    if (status != PJ_SUCCESS) {\n\tpjsip_dlg_dec_session(sub->dlg, &mod_evsub.mod);\n\tgoto on_return;\n    }\n\n    pj_grp_lock_add_ref(sub->grp_lock);\n    pj_grp_lock_add_handler(sub->grp_lock, dlg->pool, sub, &evsub_on_destroy);\n\n    /* Done */\n    *p_evsub = sub;\n\non_return:\n    pjsip_dlg_dec_lock(dlg);\n    return status;\n}\n\n\n/*\n * Create server subscription session from incoming request.\n */\nPJ_DEF(pj_status_t) pjsip_evsub_create_uas( pjsip_dialog *dlg,\n\t\t\t\t\t    const pjsip_evsub_user *user_cb,\n\t\t\t\t\t    pjsip_rx_data *rdata,\n\t\t\t\t\t    unsigned option,\n\t\t\t\t\t    pjsip_evsub **p_evsub)\n{\n    pjsip_evsub *sub;\n    pjsip_transaction *tsx;\n    pjsip_accept_hdr *accept_hdr;\n    pjsip_event_hdr *event_hdr;\n    pjsip_expires_hdr *expires_hdr;\n    pj_status_t status;\n\n    /* Check arguments: */\n    PJ_ASSERT_RETURN(dlg && rdata && p_evsub, PJ_EINVAL);\n\n    /* MUST be request message: */\n    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,\n\t\t     PJSIP_ENOTREQUESTMSG);\n\n    /* Transaction MUST have been created (in the dialog) */\n    tsx = pjsip_rdata_get_tsx(rdata);\n    PJ_ASSERT_RETURN(tsx != NULL, PJSIP_ENOTSX);\n\n    /* No subscription must have been attached to transaction */\n    PJ_ASSERT_RETURN(tsx->mod_data[mod_evsub.mod.id] == NULL, \n\t\t     PJSIP_ETYPEEXISTS);\n\n    /* Package MUST implement on_rx_refresh */\n    PJ_ASSERT_RETURN(user_cb->on_rx_refresh, PJ_EINVALIDOP);\n\n    /* Request MUST have \"Event\" header. We need the Event header to get \n     * the package name (don't want to add more arguments in the function).\n     */\n    event_hdr = (pjsip_event_hdr*) \n\t\t pjsip_msg_find_hdr_by_names(rdata->msg_info.msg, &STR_EVENT,\n\t\t\t\t\t     &STR_EVENT_S, NULL);\n    if (event_hdr == NULL) {\n\treturn PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);\n    }\n\n    /* Start locking the mutex: */\n\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Create the session: */\n\n    status = evsub_create(dlg, PJSIP_UAS_ROLE, user_cb, \n\t\t\t  &event_hdr->event_type, option, &sub);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Just duplicate Event header from the request */\n    sub->event = (pjsip_event_hdr*) pjsip_hdr_clone(sub->pool, event_hdr);\n\n    /* Set the method: */\n    pjsip_method_copy(sub->pool, &sub->method, \n\t\t      &rdata->msg_info.msg->line.req.method);\n\n    /* Update expiration time according to client request: */\n\n    expires_hdr = (pjsip_expires_hdr*)\n\tpjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);\n    if (expires_hdr) {\n\tsub->expires->ivalue = expires_hdr->ivalue;\n    }\n\n    /* Update time. */\n    update_expires(sub, sub->expires->ivalue);\n\n    /* Update Accept header: */\n\n    accept_hdr = (pjsip_accept_hdr*)\n\tpjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, NULL);\n    if (accept_hdr)\n\tsub->accept = (pjsip_accept_hdr*)pjsip_hdr_clone(sub->pool,accept_hdr);\n\n    /* Increment dlg session. */\n    pjsip_dlg_inc_session(dlg, &mod_evsub.mod);\n\n    /* Init group lock */\n    status = pj_grp_lock_create(dlg->pool, NULL, &sub->grp_lock);\n    if (status != PJ_SUCCESS) {\n\tpjsip_dlg_dec_session(sub->dlg, &mod_evsub.mod);\n\tgoto on_return;\n    }\n\n    pj_grp_lock_add_ref(sub->grp_lock);\n    pj_grp_lock_add_handler(sub->grp_lock, dlg->pool, sub, &evsub_on_destroy);\n\n    /* We can start the session: */\n\n    sub->pending_tsx++;\n    tsx->mod_data[mod_evsub.mod.id] = sub;\n\n    /* Done. */\n    *p_evsub = sub;\n\n\non_return:\n    pjsip_dlg_dec_lock(dlg);\n    return status;\n}\n\n\n/*\n * Forcefully destroy subscription.\n */\nPJ_DEF(pj_status_t) pjsip_evsub_terminate( pjsip_evsub *sub,\n\t\t\t\t\t   pj_bool_t notify )\n{\n    PJ_ASSERT_RETURN(sub, PJ_EINVAL);\n\n    pjsip_dlg_inc_lock(sub->dlg);\n\n    /* I think it's pretty safe to disable this check.\n     \n    if (sub->pending_tsx) {\n\tpj_assert(!\"Unable to terminate when there's pending tsx\");\n\tpjsip_dlg_dec_lock(sub->dlg);\n\treturn PJ_EINVALIDOP;\n    }\n    */\n\n    sub->call_cb = notify;\n    set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL, NULL);\n\n    pjsip_dlg_dec_lock(sub->dlg);\n    return PJ_SUCCESS;\n}\n\n/*\n * Get subscription state.\n */\nPJ_DEF(pjsip_evsub_state) pjsip_evsub_get_state(pjsip_evsub *sub)\n{\n    return sub->state;\n}\n\n/*\n * Get state name.\n */\nPJ_DEF(const char*) pjsip_evsub_get_state_name(pjsip_evsub *sub)\n{\n    return sub->state_str.ptr;\n}\n\n/*\n * Get termination reason.\n */\nPJ_DEF(const pj_str_t*) pjsip_evsub_get_termination_reason(pjsip_evsub *sub)\n{\n    return &sub->term_reason;\n}\n\n/*\n * Initiate client subscription\n */\nPJ_DEF(pj_status_t) pjsip_evsub_initiate( pjsip_evsub *sub,\n\t\t\t\t\t  const pjsip_method *method,\n\t\t\t\t\t  pj_int32_t expires,\n\t\t\t\t\t  pjsip_tx_data **p_tdata)\n{\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(sub!=NULL && p_tdata!=NULL, PJ_EINVAL);\n\n    /* Use SUBSCRIBE if method is not specified */\n    if (method == NULL)\n\tmethod = &pjsip_subscribe_method;\n\n    pjsip_dlg_inc_lock(sub->dlg);\n\n    /* Update method: */\n    if (sub->state == PJSIP_EVSUB_STATE_NULL)\n\tpjsip_method_copy(sub->pool, &sub->method, method);\n\n    status = pjsip_dlg_create_request( sub->dlg, method, -1, &tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n\n    /* Add Event header: */\n    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)\n\t\t       pjsip_hdr_shallow_clone(tdata->pool, sub->event));\n\n    /* Update and add expires header: */\n    if (expires >= 0)\n\tsub->expires->ivalue = expires;\n    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)\n\t\t       pjsip_hdr_shallow_clone(tdata->pool, sub->expires));\n\n    /* Add Supported header (it's optional in RFC 3265, but some event package\n     * RFC may bring this requirement to SHOULD strength - e.g. RFC 5373)\n     */\n    {\n       const pjsip_hdr *hdr = pjsip_endpt_get_capability(sub->endpt,\n\t\t\t\t\t\t         PJSIP_H_SUPPORTED,\n\t\t\t\t\t\t         NULL);\n       if (hdr) {\n\t   pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)\n\t\t\t     pjsip_hdr_shallow_clone(tdata->pool, hdr));\n       }\n    }\n\n    /* Add Accept header: */\n    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)\n\t\t       pjsip_hdr_shallow_clone(tdata->pool, sub->accept));\n    \n\n    /* Add Allow-Events header: */\n    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)\n\t\t       pjsip_hdr_shallow_clone(tdata->pool, \n\t\t\t\t\t       mod_evsub.allow_events_hdr));\n\n\n    /* Add custom headers */\n    {\n\tconst pjsip_hdr *hdr = sub->sub_hdr_list.next;\n\twhile (hdr != &sub->sub_hdr_list) {\n\t    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)\n\t\t\t       pjsip_hdr_shallow_clone(tdata->pool, hdr));\n\t    hdr = hdr->next;\n\t}\n    }\n\n\n    *p_tdata = tdata;\n\n\non_return:\n\n    pjsip_dlg_dec_lock(sub->dlg);\n    return status;\n}\n\n\n/*\n * Add custom headers.\n */\nPJ_DEF(pj_status_t) pjsip_evsub_add_header( pjsip_evsub *sub,\n\t\t\t\t\t    const pjsip_hdr *hdr_list )\n{\n    const pjsip_hdr *hdr;\n\n    PJ_ASSERT_RETURN(sub && hdr_list, PJ_EINVAL);\n\n    hdr = hdr_list->next;\n    while (hdr != hdr_list) {\n        pj_list_push_back(&sub->sub_hdr_list, (pjsip_hdr*)\n\t\t          pjsip_hdr_clone(sub->pool, hdr));\n\thdr = hdr->next;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Accept incoming subscription request.\n */\nPJ_DEF(pj_status_t) pjsip_evsub_accept( pjsip_evsub *sub,\n\t\t\t\t\tpjsip_rx_data *rdata,\n\t\t\t\t        int st_code,\n\t\t\t\t\tconst pjsip_hdr *hdr_list )\n{\n    pjsip_tx_data *tdata;\n    pjsip_transaction *tsx;\n    pj_status_t status;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(sub && rdata, PJ_EINVAL);\n\n    /* Can only be for server subscription: */\n    PJ_ASSERT_RETURN(sub->role == PJSIP_ROLE_UAS, PJ_EINVALIDOP);\n\n    /* Only expect 2xx status code (for now) */\n    PJ_ASSERT_RETURN(st_code/100 == 2, PJ_EINVALIDOP);\n\n    /* Subscription MUST have been attached to the transaction.\n     * Initial subscription request will be attached on evsub_create_uas(),\n     * while subsequent requests will be attached in tsx_state()\n     */\n    tsx = pjsip_rdata_get_tsx(rdata);\n    PJ_ASSERT_RETURN(tsx->mod_data[mod_evsub.mod.id] != NULL,\n\t\t     PJ_EINVALIDOP);\n\n    /* Lock dialog */\n    pjsip_dlg_inc_lock(sub->dlg);\n\n    /* Create response: */\n    status = pjsip_dlg_create_response( sub->dlg, rdata, st_code, NULL, \n\t\t\t\t\t&tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n\n    /* Add expires header: */\n    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)\n\t\t       pjsip_hdr_shallow_clone(tdata->pool, sub->expires));\n\n    /* Add additional header, if any. */\n    if (hdr_list) {\n\tconst pjsip_hdr *hdr = hdr_list->next;\n\twhile (hdr != hdr_list) {\n\t    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)\n\t\t\t       pjsip_hdr_clone(tdata->pool, hdr));\n\t    hdr = hdr->next;\n\t}\n    }\n\n    /* Send the response: */\n    status = pjsip_dlg_send_response( sub->dlg, tsx, tdata );\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Set UAS timeout timer, when status code is 2xx and state is not\n     * terminated.\n     */\n    if (st_code/100 == 2 && sub->state != PJSIP_EVSUB_STATE_TERMINATED) {\n\tPJ_LOG(5,(sub->obj_name, \"UAS timeout in %d seconds\",\n\t\t  sub->expires->ivalue));\n\tset_timer(sub, TIMER_TYPE_UAS_TIMEOUT, sub->expires->ivalue);\n    }\n\non_return:\n\n    pjsip_dlg_dec_lock(sub->dlg);\n    return status;\n}\n\n\n/*\n * Create Subscription-State header based on current server subscription\n * state.\n */\nstatic pjsip_sub_state_hdr* sub_state_create( pj_pool_t *pool,\n\t\t\t\t\t      pjsip_evsub *sub,\n\t\t\t\t\t      pjsip_evsub_state state,\n\t\t\t\t\t      const pj_str_t *state_str,\n\t\t\t\t\t      const pj_str_t *reason )\n{\n    pjsip_sub_state_hdr *sub_state;\n    pj_time_val now, delay;\n\n    /* Get the remaining time before refresh is required */\n    pj_gettimeofday(&now);\n    delay = sub->refresh_time;\n    PJ_TIME_VAL_SUB(delay, now);\n\n    /* Create the Subscription-State header */\n    sub_state = pjsip_sub_state_hdr_create(pool);\n\n    /* Fill up the header */\n    switch (state) {\n    case PJSIP_EVSUB_STATE_NULL:\n    case PJSIP_EVSUB_STATE_SENT:\n\tpj_assert(!\"Invalid state!\");\n\t/* Treat as pending */\n\n    case PJSIP_EVSUB_STATE_ACCEPTED:\n    case PJSIP_EVSUB_STATE_PENDING:\n\tsub_state->sub_state = STR_PENDING;\n\tsub_state->expires_param = delay.sec;\n\tbreak;\n\n    case PJSIP_EVSUB_STATE_ACTIVE:\n\tsub_state->sub_state = STR_ACTIVE;\n\tsub_state->expires_param = delay.sec;\n\tbreak;\n\n    case PJSIP_EVSUB_STATE_TERMINATED:\n\tsub_state->sub_state = STR_TERMINATED;\n\tif (reason != NULL)\n\t    pj_strdup(pool, &sub_state->reason_param, reason);\n\tbreak;\n\n    case PJSIP_EVSUB_STATE_UNKNOWN:\n\tpj_assert(state_str != NULL);\n\tpj_strdup(pool, &sub_state->sub_state, state_str);\n\tbreak;\n    }\n    \n    return sub_state;\n}\n\n/*\n * Create and send NOTIFY request.\n */\nPJ_DEF(pj_status_t) pjsip_evsub_notify( pjsip_evsub *sub,\n\t\t\t\t\tpjsip_evsub_state state,\n\t\t\t\t\tconst pj_str_t *state_str,\n\t\t\t\t\tconst pj_str_t *reason,\n\t\t\t\t\tpjsip_tx_data **p_tdata)\n{\n    pjsip_tx_data *tdata;\n    pjsip_sub_state_hdr *sub_state;\n    pj_status_t status;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(sub!=NULL && p_tdata!=NULL, PJ_EINVAL);\n\n    /* Lock dialog. */\n    pjsip_dlg_inc_lock(sub->dlg);\n\n    /* Create NOTIFY request */\n    status = pjsip_dlg_create_request( sub->dlg, pjsip_get_notify_method(), \n\t\t\t\t       -1, &tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Add Event header */\n    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)\n\t\t      pjsip_hdr_shallow_clone(tdata->pool, sub->event));\n\n    /* Add Subscription-State header */\n    sub_state = sub_state_create(tdata->pool, sub, state, state_str,\n\t\t\t\t reason);\n    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)sub_state);\n\n    /* Add Allow-Events header */\n    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)\n\t\t      pjsip_hdr_shallow_clone(tdata->pool, mod_evsub.allow_events_hdr));\n\n    /* Add Authentication headers. */\n    pjsip_auth_clt_init_req( &sub->dlg->auth_sess, tdata );\n\n    /* Update reason */\n    if (reason)\n\tpj_strdup(sub->dlg->pool, &sub->term_reason, reason);\n\n    /* Save destination state. */\n    sub->dst_state = state;\n    if (state_str)\n\tpj_strdup(sub->pool, &sub->dst_state_str, state_str);\n    else\n\tsub->dst_state_str.slen = 0;\n\n\n    *p_tdata = tdata;\n\non_return:\n    /* Unlock dialog */\n    pjsip_dlg_dec_lock(sub->dlg);\n    return status;\n}\n\n\n/*\n * Create NOTIFY to reflect current status.\n */\nPJ_DEF(pj_status_t) pjsip_evsub_current_notify( pjsip_evsub *sub,\n\t\t\t\t\t\tpjsip_tx_data **p_tdata )\n{\n    return pjsip_evsub_notify( sub, sub->state, &sub->state_str, \n\t\t\t       NULL, p_tdata );\n}\n\n\n/*\n * Send request.\n */\nPJ_DEF(pj_status_t) pjsip_evsub_send_request( pjsip_evsub *sub,\n\t\t\t\t\t      pjsip_tx_data *tdata)\n{\n    pj_status_t status;\n\n    /* Must be request message. */\n    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,\n\t\t     PJSIP_ENOTREQUESTMSG);\n\n    /* Lock */\n    pjsip_dlg_inc_lock(sub->dlg);\n\n    /* Send the request. */\n    status = pjsip_dlg_send_request(sub->dlg, tdata, -1, NULL);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n\n    /* Special case for NOTIFY:\n     * The new state was set in pjsip_evsub_notify(), but we apply the\n     * new state now, when the request was actually sent.\n     */\n    if (pjsip_method_cmp(&tdata->msg->line.req.method, \n\t\t\t &pjsip_notify_method)==0) \n    {\n\tPJ_ASSERT_ON_FAIL(  sub->dst_state!=PJSIP_EVSUB_STATE_NULL,\n\t\t\t    {goto on_return;});\n\n\tset_state(sub, sub->dst_state, \n\t\t  (sub->dst_state_str.slen ? &sub->dst_state_str : NULL), \n\t\t  NULL, NULL);\n\n\tsub->dst_state = PJSIP_EVSUB_STATE_NULL;\n\tsub->dst_state_str.slen = 0;\n\n    }\n\n\non_return:\n    pjsip_dlg_dec_lock(sub->dlg);\n    return status;\n}\n\n\n/* Callback to be called to terminate transaction. */\nstatic void terminate_timer_cb(pj_timer_heap_t *timer_heap,\n\t\t\t       struct pj_timer_entry *entry)\n{\n    pj_str_t *key;\n    pjsip_transaction *tsx;\n\n    PJ_UNUSED_ARG(timer_heap);\n\n    /* Clear timer ID */\n    entry->id = 0;\n\n    key = (pj_str_t*)entry->user_data;\n    tsx = pjsip_tsx_layer_find_tsx(key, PJ_FALSE);\n    /* Chance of race condition here */\n    if (tsx) {\n\tpjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_UPDATED);\n    }\n}\n\n\n/*\n * Attach subscription session to newly created transaction, if appropriate.\n */\nstatic pjsip_evsub *on_new_transaction( pjsip_transaction *tsx,\n\t\t\t\t        pjsip_event *event)\n{\n    /*\n     * Newly created transaction will not have subscription session\n     * attached to it. Find the subscription session from the dialog,\n     * by matching the Event header.\n     */\n    pjsip_dialog *dlg;\n    pjsip_event_hdr *event_hdr;\n    pjsip_msg *msg;\n    struct dlgsub *dlgsub_head, *dlgsub;\n    pjsip_evsub *sub;\n    \n    dlg = pjsip_tsx_get_dlg(tsx);\n    if (!dlg) {\n\tpj_assert(!\"Transaction should have a dialog instance!\");\n\treturn NULL;\n    }\n\n\n    switch (event->body.tsx_state.type) {\n    case PJSIP_EVENT_RX_MSG:\n\tmsg = event->body.tsx_state.src.rdata->msg_info.msg;\n\tbreak;\n    case PJSIP_EVENT_TX_MSG:\n\tmsg = event->body.tsx_state.src.tdata->msg;\n\tbreak;\n    default:\n\tif (tsx->role == PJSIP_ROLE_UAC)\n\t    msg = tsx->last_tx->msg;\n\telse\n\t    msg = NULL;\n\tbreak;\n    }\n    \n    if (!msg) {\n\t//Note:\n\t// this transaction can be other transaction in the dialog.\n\t// The assertion below probably only valid for dialog that\n\t// only has one event subscription usage.\n\t//pj_assert(!\"First transaction event is not TX or RX!\");\n\treturn NULL;\n    }\n\n    event_hdr = (pjsip_event_hdr*)\n    \t\tpjsip_msg_find_hdr_by_names(msg, &STR_EVENT, \n\t\t\t\t\t    &STR_EVENT_S, NULL);\n    if (!event_hdr) {\n\t/* Not subscription related message */\n\treturn NULL;\n    }\n\n    /* Find the subscription in the dialog, based on the content\n     * of Event header: \n     */\n\n    dlgsub_head = (struct dlgsub*) dlg->mod_data[mod_evsub.mod.id];\n    if (dlgsub_head == NULL) {\n\tdlgsub_head = PJ_POOL_ALLOC_T(dlg->pool, struct dlgsub);\n\tpj_list_init(dlgsub_head);\n\tdlg->mod_data[mod_evsub.mod.id] = dlgsub_head;\n    }\n    dlgsub = dlgsub_head->next;\n\n    while (dlgsub != dlgsub_head) {\n\n\tif (pj_stricmp(&dlgsub->sub->event->event_type, \n\t\t       &event_hdr->event_type)==0)\n\t{\n\t    /* Event type matched. \n\t     * Check if event ID matched too.\n\t     */\n\t    if (pj_strcmp(&dlgsub->sub->event->id_param, \n\t\t\t  &event_hdr->id_param)==0)\n\t    {\n\t\t/* Skip this subscription if it has no event ID and has been\n\t\t * terminated (see ticket #1647).\n\t\t */\n\t\tif ((dlgsub->sub->option & PJSIP_EVSUB_NO_EVENT_ID) &&\n\t\t    (pjsip_evsub_get_state(dlgsub->sub)==\n\t\t\t\t\tPJSIP_EVSUB_STATE_TERMINATED))\n\t\t{\n\t\t    dlgsub = dlgsub->next;\n    \t\t    continue;\n\t\t} else {\n\t\t    break;\n\t\t}\n\n\t    }\n\t    /*\n\t     * Otherwise if it is an UAC subscription, AND\n\t     * PJSIP_EVSUB_NO_EVENT_ID flag is set, AND\n\t     * the session's event id is NULL, AND\n\t     * the incoming request is NOTIFY with event ID, then\n\t     * we consider it as a match, and update the\n\t     * session's event id.\n\t     */\n\t    else if (dlgsub->sub->role == PJSIP_ROLE_UAC &&\n\t\t     (dlgsub->sub->option & PJSIP_EVSUB_NO_EVENT_ID)!=0 &&\n\t\t     dlgsub->sub->event->id_param.slen==0 &&\n\t\t     !pjsip_method_cmp(&tsx->method, &pjsip_notify_method))\n\t    {\n\t\t/* Update session's event id. */\n\t\tpj_strdup(dlgsub->sub->pool, \n\t\t\t  &dlgsub->sub->event->id_param,\n\t\t\t  &event_hdr->id_param);\n\n\t\tbreak;\n\t    }\n\t}\n\t\n\n\n\tdlgsub = dlgsub->next;\n    }\n\n    /* Note: \n     *  the second condition is for http://trac.pjsip.org/repos/ticket/911 \n     */\n    if (dlgsub == dlgsub_head ||\n\t(dlgsub->sub && \n\t    pjsip_evsub_get_state(dlgsub->sub)==PJSIP_EVSUB_STATE_TERMINATED))\n    {\n\tconst char *reason_msg = \n\t    (dlgsub == dlgsub_head ? \"Subscription Does Not Exist\" :\n\t     \"Subscription already terminated\");\n\n\t/* This could be incoming request to create new subscription */\n\tPJ_LOG(4,(THIS_FILE, \n\t\t  \"%s for %.*s, event=%.*s;id=%.*s\",\n\t\t  reason_msg,\n\t\t  (int)tsx->method.name.slen,\n\t\t  tsx->method.name.ptr,\n\t\t  (int)event_hdr->event_type.slen,\n\t\t  event_hdr->event_type.ptr,\n\t\t  (int)event_hdr->id_param.slen,\n\t\t  event_hdr->id_param.ptr));\n\n\t/* If this is an incoming NOTIFY, reject with 481 */\n\tif (tsx->state == PJSIP_TSX_STATE_TRYING &&\n\t    pjsip_method_cmp(&tsx->method, &pjsip_notify_method)==0)\n\t{\n\t    pj_str_t reason;\n\t    pjsip_tx_data *tdata;\n\t    pj_status_t status;\n\n\t    pj_cstr(&reason, reason_msg);\n\t    status = pjsip_dlg_create_response(dlg, \n\t\t\t\t\t       event->body.tsx_state.src.rdata, \n\t\t\t\t\t       481, &reason, \n\t\t\t\t\t       &tdata);\n\t    if (status == PJ_SUCCESS) {\n\t\tstatus = pjsip_dlg_send_response(dlg, tsx, tdata);\n\t    }\n\t}\n\treturn NULL;\n    }\n\n    /* Found! */\n    sub = dlgsub->sub;\n\n    /* Attach session to the transaction */\n    tsx->mod_data[mod_evsub.mod.id] = sub;\n    sub->pending_tsx++;\n\n    /* Special case for outgoing/UAC SUBSCRIBE/REFER transaction. \n     * We can only have one pending UAC SUBSCRIBE/REFER, so if another \n     * transaction is started while previous one still alive, terminate\n     * the older one.\n     *\n     * Sample scenario:\n     *\t- subscribe sent to destination that doesn't exist, transaction\n     *\t  is still retransmitting request, then unsubscribe is sent.\n     */\n    if (tsx->role == PJSIP_ROLE_UAC &&\n\ttsx->state == PJSIP_TSX_STATE_CALLING &&\n\t(pjsip_method_cmp(&tsx->method, &sub->method) == 0  ||\n\t pjsip_method_cmp(&tsx->method, &pjsip_subscribe_method) == 0))\n    {\n\n\tif (sub->pending_sub && \n\t    sub->pending_sub->state < PJSIP_TSX_STATE_COMPLETED) \n\t{\n\t    pj_timer_entry *timer;\n\t    pj_str_t *key;\n\t    pj_time_val timeout = {0, 0};\n\n\t    PJ_LOG(4,(sub->obj_name, \n\t\t      \"Cancelling pending subscription request\"));\n\n\t    /* By convention, we use 490 (Request Updated) status code.\n\t     * When transaction handler (below) see this status code, it\n\t     * will ignore the transaction.\n\t     */\n\t    /* This unfortunately may cause deadlock, because at the moment\n\t     * we are holding dialog's mutex. If a response to this\n\t     * transaction is in progress in another thread, that thread\n\t     * will deadlock when trying to acquire dialog mutex, because\n\t     * it is holding the transaction mutex.\n\t     *\n\t     * So the solution is to register timer to kill this transaction.\n\t     */\n\t    //pjsip_tsx_terminate(sub->pending_sub, PJSIP_SC_REQUEST_UPDATED);\n\t    timer = PJ_POOL_ZALLOC_T(dlg->pool, pj_timer_entry);\n\t    key = PJ_POOL_ALLOC_T(dlg->pool, pj_str_t);\n\t    pj_strdup(dlg->pool, key, &sub->pending_sub->transaction_key);\n\t    timer->cb = &terminate_timer_cb;\n\t    timer->user_data = key;\n\t    timer->id = 1;\n\t    sub->pending_sub_timer = timer;\n\n\t    pjsip_endpt_schedule_timer(dlg->endpt, timer, &timeout);\n\t}\n\n\tsub->pending_sub = tsx;\n\n    }\n\n    return sub;\n}\n\n\n/*\n * Create response, adding custome headers and msg body.\n */\nstatic pj_status_t create_response( pjsip_evsub *sub,\n\t\t\t\t    pjsip_rx_data *rdata,\n\t\t\t\t    int st_code,\n\t\t\t\t    const pj_str_t *st_text,\n\t\t\t\t    const pjsip_hdr *res_hdr,\n\t\t\t\t    const pjsip_msg_body *body,\n\t\t\t\t    pjsip_tx_data **p_tdata)\n{\n    pjsip_tx_data *tdata;\n    pjsip_hdr *hdr;\n    pj_status_t status;\n\n    status = pjsip_dlg_create_response(sub->dlg, rdata,\n\t\t\t\t       st_code, st_text, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    *p_tdata = tdata;\n\n    /* Add response headers. */\n    hdr = res_hdr->next;\n    while (hdr != res_hdr) {\n\tpjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)\n\t\t\t   pjsip_hdr_clone(tdata->pool, hdr));\n\thdr = hdr->next;\n    }\n\n    /* Add msg body, if any */\n    if (body) {\n\ttdata->msg->body = pjsip_msg_body_clone(tdata->pool, body);\n\tif (tdata->msg->body == NULL) {\n\n\t    PJ_LOG(4,(THIS_FILE, \"Error: unable to clone msg body\"));\n\n\t    /* Ignore */\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get subscription state from the value of Subscription-State header.\n */\nstatic void get_hdr_state( pjsip_sub_state_hdr *sub_state,\n\t\t\t   pjsip_evsub_state *state,\n\t\t\t   pj_str_t **state_str )\n{\n    if (pj_stricmp(&sub_state->sub_state, &STR_TERMINATED)==0) {\n\n\t*state = PJSIP_EVSUB_STATE_TERMINATED;\n\t*state_str = NULL;\n\n    } else if (pj_stricmp(&sub_state->sub_state, &STR_ACTIVE)==0) {\n\n\t*state = PJSIP_EVSUB_STATE_ACTIVE;\n\t*state_str = NULL;\n\n    } else if (pj_stricmp(&sub_state->sub_state, &STR_PENDING)==0) {\n\n\t*state = PJSIP_EVSUB_STATE_PENDING;\n\t*state_str = NULL;\n\n    } else {\n\n\t*state = PJSIP_EVSUB_STATE_UNKNOWN;\n\t*state_str = &sub_state->sub_state;\n\n    }\n}\n\n/*\n * Transaction event processing by UAC, after subscription is sent.\n */\nstatic void on_tsx_state_uac( pjsip_evsub *sub, pjsip_transaction *tsx,\n\t\t\t      pjsip_event *event )\n{\n\n    if (pjsip_method_cmp(&tsx->method, &sub->method)==0 || \n\tpjsip_method_cmp(&tsx->method, &pjsip_subscribe_method)==0) \n    {\n\n\t/* Received response to outgoing request that establishes/refresh\n\t * subscription. \n\t */\n\n\t/* First time initial request is sent. */\n\tif (sub->state == PJSIP_EVSUB_STATE_NULL &&\n\t    tsx->state == PJSIP_TSX_STATE_CALLING)\n\t{\n\t    set_state(sub, PJSIP_EVSUB_STATE_SENT, NULL, event, NULL);\n\t    return;\n\t}\n\n\t/* Only interested in final response */\n\tif (tsx->state != PJSIP_TSX_STATE_COMPLETED &&\n\t    tsx->state != PJSIP_TSX_STATE_TERMINATED)\n\t{\n\t    return;\n\t}\n\n\t/* Clear pending subscription */\n\tif (tsx == sub->pending_sub) {\n\t    sub->pending_sub = NULL;\n\t} else if (sub->pending_sub != NULL) {\n\t    /* This SUBSCRIBE transaction has been \"renewed\" with another\n\t     * SUBSCRIBE, so we can just ignore this. For example, user\n\t     * sent SUBSCRIBE followed immediately with UN-SUBSCRIBE.\n\t     */\n\t    return;\n\t}\n\n\t/* Handle authentication. */\n\tif (tsx->status_code==401 || tsx->status_code==407) {\n\t    pjsip_tx_data *tdata;\n\t    pj_status_t status;\n\n\t    if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {\n\t\t/* Previously failed transaction has terminated */\n\t\treturn;\n\t    }\n\n\t    status = pjsip_auth_clt_reinit_req(&sub->dlg->auth_sess,\n\t\t\t\t\t       event->body.tsx_state.src.rdata,\n\t\t\t\t\t       tsx->last_tx, &tdata);\n\t    if (status == PJ_SUCCESS) \n\t\tstatus = pjsip_dlg_send_request(sub->dlg, tdata, -1, NULL);\n\t    \n\t    if (status != PJ_SUCCESS) {\n\t\t/* Authentication failed! */\n\t\tset_state(sub, PJSIP_EVSUB_STATE_TERMINATED,\n\t\t\t  NULL, event, &tsx->status_text);\n\t\treturn;\n\t    }\n\n\t    return;\n\t}\n\n\tif (tsx->status_code/100 == 2) {\n\n\t    /* Successfull SUBSCRIBE request! \n\t     * This could be:\n\t     *\t- response to initial SUBSCRIBE request\n\t     *\t- response to subsequent refresh\n\t     *\t- response to unsubscription\n\t     */\n\n\t    if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {\n\t\t/* Ignore; this transaction has been processed before */\n\t\treturn;\n\t    }\n\n\t    /* Update UAC refresh time, if response contains Expires header,\n\t     * only when we're not unsubscribing. \n\t     */\n\t    if (sub->expires->ivalue != 0) {\n\t\tpjsip_msg *msg;\n\t\tpjsip_expires_hdr *expires;\n\n\t\tmsg = event->body.tsx_state.src.rdata->msg_info.msg;\n\t\texpires = (pjsip_expires_hdr*)\n\t\t\t  pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL);\n\t\tif (expires) {\n\t\t    sub->expires->ivalue = expires->ivalue;\n\t\t}\n\t    }\n\n\t    /* Update time */\n\t    update_expires(sub, sub->expires->ivalue);\n\n\t    /* Start UAC refresh timer, only when we're not unsubscribing */\n\t    if (sub->expires->ivalue != 0) {\n\t\tunsigned timeout = (sub->expires->ivalue > TIME_UAC_REFRESH) ?\n\t\t    sub->expires->ivalue - TIME_UAC_REFRESH : sub->expires->ivalue;\n\n\t\t/* Reduce timeout by about 1 - 10 secs (randomized) */\n\t\tif (timeout > 10)\n\t\t    timeout += -10 + (pj_rand() % 10);\n\n\t\tPJ_LOG(5,(sub->obj_name, \"Will refresh in %d seconds\", \n\t\t\t  timeout));\n\t\tset_timer(sub, TIMER_TYPE_UAC_REFRESH, timeout);\n\n\t    } else {\n\t\t/* Otherwise set timer to terminate client subscription when\n\t\t * NOTIFY to end subscription is not received.\n\t\t */\n\t\tset_timer(sub, TIMER_TYPE_UAC_TERMINATE, TIME_UAC_TERMINATE);\n\t    }\n\t    \n\t    /* Set state, if necessary */\n\t    pj_assert(sub->state != PJSIP_EVSUB_STATE_NULL);\n\t    if (sub->state == PJSIP_EVSUB_STATE_SENT) {\n\t\tset_state(sub, PJSIP_EVSUB_STATE_ACCEPTED, NULL, event, NULL);\n\t    }\n\n\t} else {\n\n\t    /* Failed SUBSCRIBE request! \n\t     *\n\t     * The RFC 3265 says that if outgoing SUBSCRIBE fails with status\n\t     * other than 481, the subscription is still considered valid for\n\t     * the duration of the last Expires.\n\t     *\n\t     * Since we send refresh about 5 seconds (TIME_UAC_REFRESH) before \n\t     * expiration, theoritically the expiration is still valid for the \n\t     * next 5 seconds even when we receive non-481 failed response.\n\t     *\n\t     * Ah, what the heck!\n\t     *\n\t     * Just terminate now!\n\t     *\n\t     */\n\n\t    if (sub->state == PJSIP_EVSUB_STATE_TERMINATED) {\n\t\t/* Ignore, has been handled before */\n\t\treturn;\n\t    }\n\n\t    /* Ignore 490 (Request Updated) status. \n\t     * This happens when application sends SUBSCRIBE/REFER while \n\t     * another one is still in progress.\n\t     */\n\t    if (tsx->status_code == PJSIP_SC_REQUEST_UPDATED) {\n\t\treturn;\n\t    }\n\n\t    /* Set state to TERMINATED */\n\t    set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, \n\t\t      NULL, event, &tsx->status_text);\n\n\t}\n\n    } else if (pjsip_method_cmp(&tsx->method, &pjsip_notify_method) == 0) {\n\n\t/* Incoming NOTIFY. \n\t * This can be the result of:\n\t *  - Initial subscription response\n\t *  - UAS updating the resource info.\n\t *  - Unsubscription response.\n\t */\n\tint st_code = 200;\n\tpj_str_t *st_text = NULL;\n\tpjsip_hdr res_hdr;\n\tpjsip_msg_body *body = NULL;\n\n\tpjsip_rx_data *rdata;\n\tpjsip_msg *msg;\n\tpjsip_sub_state_hdr *sub_state;\n\n\tpjsip_evsub_state new_state;\n\tpj_str_t *new_state_str;\n\n\tpjsip_tx_data *tdata;\n\tpj_status_t status;\n\n\t/* Only want to handle initial NOTIFY receive event. */\n\tif (tsx->state != PJSIP_TSX_STATE_TRYING)\n\t    return;\n\n\n\trdata = event->body.tsx_state.src.rdata;\n\tmsg = rdata->msg_info.msg;\n\n\tpj_list_init(&res_hdr);\n\n\t/* Get subscription state header. */\n\tsub_state = (pjsip_sub_state_hdr*)\n\t\t    pjsip_msg_find_hdr_by_name(msg, &STR_SUB_STATE, NULL);\n\tif (sub_state == NULL) {\n\n\t    pjsip_warning_hdr *warn_hdr;\n\t    pj_str_t warn_text = { \"Missing Subscription-State header\", 33};\n\n\t    /* Bad request! Add warning header. */\n\t    st_code = PJSIP_SC_BAD_REQUEST;\n\t    warn_hdr = pjsip_warning_hdr_create(rdata->tp_info.pool, 399,\n\t\t\t\t\t        pjsip_endpt_name(sub->endpt),\n\t\t\t\t\t\t&warn_text);\n\t    pj_list_push_back(&res_hdr, warn_hdr);\n\t}\n\n\t/* Call application registered callback to handle incoming NOTIFY,\n\t * if any.\n\t */\n\tif (st_code==200 && sub->user.on_rx_notify && sub->call_cb) {\n\t    (*sub->user.on_rx_notify)(sub, rdata, &st_code, &st_text, \n\t\t\t\t      &res_hdr, &body);\n\n\t    /* Application MUST specify final response! */\n\t    PJ_ASSERT_ON_FAIL(st_code >= 200, {st_code=200; });\n\n\t    /* Must be a valid status code */\n\t    PJ_ASSERT_ON_FAIL(st_code <= 699, {st_code=500; });\n\t}\n\n\n\t/* If non-2xx should be returned, then send the response.\n\t * No need to update server subscription state.\n\t */\n\tif (st_code >= 300) {\n\t    status = create_response(sub, rdata, st_code, st_text, &res_hdr,\n\t\t\t\t     body, &tdata);\n\t    if (status == PJ_SUCCESS) {\n\t\tstatus = pjsip_dlg_send_response(sub->dlg, tsx, tdata);\n\t    }\n\n\t    /* Start timer to terminate subscription, just in case server\n\t     * is not able to generate NOTIFY to our response.\n\t     */\n\t    if (status == PJ_SUCCESS) {\n\t\tunsigned timeout = TIME_UAC_WAIT_NOTIFY;\n\t\tset_timer(sub, TIMER_TYPE_UAC_WAIT_NOTIFY, timeout);\n\t    } else {\n\t\tchar errmsg[PJ_ERR_MSG_SIZE];\n\t\tpj_str_t reason;\n\n\t\treason = pj_strerror(status, errmsg, sizeof(errmsg));\n\t\tset_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL, \n\t\t\t  &reason);\n\t    }\n\n\t    return;\n\t}\n\n\t/* Update expiration from the value of expires param in\n\t * Subscription-State header, but ONLY when subscription state \n\t * is \"active\" or \"pending\", AND the header contains expires param.\n\t */\n\tif (sub->expires->ivalue != 0 &&\n\t    sub_state->expires_param >= 0 &&\n\t    (pj_stricmp(&sub_state->sub_state, &STR_ACTIVE)==0 ||\n\t     pj_stricmp(&sub_state->sub_state, &STR_PENDING)==0))\n\t{\n\t    int next_refresh = sub_state->expires_param;\n\t    unsigned timeout;\n\n\t    update_expires(sub, next_refresh);\n\n\t    /* Start UAC refresh timer, only when we're not unsubscribing */\n\t    timeout = (next_refresh > TIME_UAC_REFRESH) ?\n\t\t\tnext_refresh - TIME_UAC_REFRESH : next_refresh;\n\n\t    PJ_LOG(5,(sub->obj_name, \"Will refresh in %d seconds\", timeout));\n\t    set_timer(sub, TIMER_TYPE_UAC_REFRESH, timeout);\n\t}\n\t\n\t/* Find out the state */\n\tget_hdr_state(sub_state, &new_state, &new_state_str);\n\n\t/* Send response. */\n\tstatus = create_response(sub, rdata, st_code, st_text, &res_hdr,\n\t\t\t\t body, &tdata);\n\tif (status == PJ_SUCCESS)\n\t    status = pjsip_dlg_send_response(sub->dlg, tsx, tdata);\n\n\t/* Set the state */\n\tif (status == PJ_SUCCESS) {\n\t    set_state(sub, new_state, new_state_str, event, \n\t\t      &sub_state->reason_param);\n\t} else {\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\t    pj_str_t reason;\n\n\t    reason = pj_strerror(status, errmsg, sizeof(errmsg));\n\t    set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, event, \n\t\t      &reason);\n\t}\n\n\n    } else {\n\n\t/*\n\t * Unexpected method!\n\t */\n\tPJ_LOG(4,(sub->obj_name, \"Unexpected transaction method %.*s\",\n\t\t (int)tsx->method.name.slen, tsx->method.name.ptr));\n    }\n}\n\n\n/*\n * Transaction event processing by UAS, after subscription is accepted.\n */\nstatic void on_tsx_state_uas( pjsip_evsub *sub, pjsip_transaction *tsx,\n\t\t\t      pjsip_event *event)\n{\n\n    if (pjsip_method_cmp(&tsx->method, &sub->method) == 0 ||\n\tpjsip_method_cmp(&tsx->method, &pjsip_subscribe_method) == 0) \n    {\n\t\n\t/*\n\t * Incoming request (e.g. SUBSCRIBE or REFER) to refresh subsciption.\n\t *\n\t */\n\tpjsip_rx_data *rdata;\n\tpjsip_event_hdr *event_hdr;\n\tpjsip_expires_hdr *expires;\n\tpjsip_msg *msg;\n\tpjsip_tx_data *tdata;\n\tint st_code = 200;\n\tpj_str_t *st_text = NULL;\n\tpjsip_hdr res_hdr;\n\tpjsip_msg_body *body = NULL;\n\tpjsip_evsub_state old_state;\n\tpj_str_t old_state_str;\n\tpj_str_t reason = { NULL, 0 };\n\tpj_status_t status;\n\n\n\t/* Only wants to handle the first event when the request is \n\t * received.\n\t */\n\tif (tsx->state != PJSIP_TSX_STATE_TRYING)\n\t    return;\n\n\trdata = event->body.tsx_state.src.rdata;\n\tmsg = rdata->msg_info.msg;\n\n\t/* Set expiration time based on client request (in Expires header),\n\t * or package default expiration time.\n\t */\n\tevent_hdr = (pjsip_event_hdr*)\n\t\t    pjsip_msg_find_hdr_by_names(msg, &STR_EVENT, \n\t\t\t\t\t        &STR_EVENT, NULL);\n\texpires = (pjsip_expires_hdr*)\n\t\t  pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL);\n\tif (event_hdr && expires) {\n\t    struct evpkg *evpkg;\n\n\t    evpkg = find_pkg(&event_hdr->event_type);\n\t    if (evpkg) {\n\t\tif (expires->ivalue < (pj_int32_t)evpkg->pkg_expires)\n\t\t    sub->expires->ivalue = expires->ivalue;\n\t\telse\n\t\t    sub->expires->ivalue = evpkg->pkg_expires;\n\t    }\n\t}\n\t\n\t/* Update time (before calling on_rx_refresh, since application\n\t * will send NOTIFY.\n\t */\n\tupdate_expires(sub, sub->expires->ivalue);\n\n\n\t/* Save old state.\n\t * If application respond with non-2xx, revert to old state.\n\t */\n\told_state = sub->state;\n\told_state_str = sub->state_str;\n\n\tif (sub->expires->ivalue == 0) {\n\t    sub->state = PJSIP_EVSUB_STATE_TERMINATED;\n\t    sub->state_str = evsub_state_names[sub->state];\n\t} else  if (sub->state == PJSIP_EVSUB_STATE_NULL) {\n\t    sub->state = PJSIP_EVSUB_STATE_ACCEPTED;\n\t    sub->state_str = evsub_state_names[sub->state];\n\t}\n\n\t/* Call application's on_rx_refresh, just in case it wants to send\n\t * response other than 200 (OK)\n\t */\n\tpj_list_init(&res_hdr);\n\n\tif (sub->user.on_rx_refresh && sub->call_cb) {\n\t    (*sub->user.on_rx_refresh)(sub, rdata, &st_code, &st_text, \n\t\t\t\t       &res_hdr, &body);\n\t}\n\n\t/* Application MUST specify final response! */\n\tPJ_ASSERT_ON_FAIL(st_code >= 200, {st_code=200; });\n\n\t/* Must be a valid status code */\n\tPJ_ASSERT_ON_FAIL(st_code <= 699, {st_code=500; });\n\n\n\t/* Create and send response */\n\tstatus = create_response(sub, rdata, st_code, st_text, &res_hdr,\n\t\t\t\t body, &tdata);\n\tif (status == PJ_SUCCESS) {\n\t    /* Add expires header: */\n\t    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)\n\t\t\t       pjsip_hdr_shallow_clone(tdata->pool, \n\t\t\t\t\t\t       sub->expires));\n\n\t    /* Send */\n\t    status = pjsip_dlg_send_response(sub->dlg, tsx, tdata);\n\t}\n\n\t/* Update state or revert state */\n\tif (st_code/100==2) {\n\t    \n\t    if (sub->expires->ivalue == 0) {\n\t\tset_state(sub, sub->state, NULL, event, &reason);\n\t    } else  if (sub->state == PJSIP_EVSUB_STATE_NULL) {\n\t\tset_state(sub, sub->state, NULL, event, &reason);\n\t    }\n\n\t    /* Set UAS timeout timer, when state is not terminated. */\n\t    if (sub->state != PJSIP_EVSUB_STATE_TERMINATED) {\n\t\tPJ_LOG(5,(sub->obj_name, \"UAS timeout in %d seconds\",\n\t\t\t  sub->expires->ivalue));\n\t\tset_timer(sub, TIMER_TYPE_UAS_TIMEOUT, \n\t\t\t  sub->expires->ivalue);\n\t    }\n\n\t}  else {\n\t    sub->state = old_state;\n\t    sub->state_str = old_state_str;\n\t}\n\n\n    } else if (pjsip_method_cmp(&tsx->method, &pjsip_notify_method)==0) {\n\n\t/* Handle authentication */\n\tif (tsx->state == PJSIP_TSX_STATE_COMPLETED &&\n\t    (tsx->status_code==401 || tsx->status_code==407))\n\t{\t    \n\t    pjsip_tx_data *tdata;\n\t    pj_status_t status;\n\t    pjsip_rx_data *rdata = event->body.tsx_state.src.rdata;\n\n\t    status = pjsip_auth_clt_reinit_req(&sub->dlg->auth_sess, rdata,\n\t\t\t\t\t       tsx->last_tx, &tdata);\n\t    if (status == PJ_SUCCESS)\n\t\tstatus = pjsip_dlg_send_request(sub->dlg, tdata, -1, NULL);\n\n\t    if (status != PJ_SUCCESS) {\n\t\t/* Can't authenticate. Terminate session (?) */\n\t\tset_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL,\n\t\t\t  &tsx->status_text);\n\t\treturn;\n\t    }\n\n\t}\n\n\tif (sub->state == PJSIP_EVSUB_STATE_TERMINATED)\n\t    return;\n\n\t/* NOTIFY failure check */\n\tif (tsx->status_code/100 != 2) {\n\t    pj_bool_t should_terminate_sub = PJ_FALSE;\n\n\t    if (event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {\n\t\tif (tsx->status_code == 481) {\n\t\t    should_terminate_sub = PJ_TRUE;\n\t\t} else {\n\t\t    pjsip_retry_after_hdr *retry_after;\n\t\t    pjsip_rx_data *rdata = event->body.tsx_state.src.rdata;\n\t\t    pjsip_msg *msg = rdata->msg_info.msg;\t\t    \n\n\t\t    retry_after = (pjsip_retry_after_hdr*)\n\t\t       pjsip_msg_find_hdr_by_name(msg, &STR_RETRY_AFTER, NULL);\n\n\t\t    if (!retry_after) {\n\t\t\tshould_terminate_sub = PJ_TRUE;\n\t\t    }\n\t\t}\n\t    } else if (event->body.tsx_state.type == PJSIP_EVENT_TIMER) {\n\t\tif (tsx->status_code == 408) {\n\t\t    should_terminate_sub = PJ_TRUE;\n\t\t}\n\t    }\n\n\t    /*\n\t     * Terminate event usage if we receive non 2xx without retry_after\n\t     * parameter, 481, 408 responses.\n\t     */\n\t    if (should_terminate_sub) {\n\t\tset_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, event,\n\t\t\t  &tsx->status_text);\n\t\treturn;\n\t    }\n\t}\n    } else {\n\n\t/*\n\t * Unexpected method!\n\t */\n\tPJ_LOG(4,(sub->obj_name, \"Unexpected transaction method %.*s\",\n\t\t (int)tsx->method.name.slen, tsx->method.name.ptr));\n    \n    }\n}\n\n\n/*\n * Notification when transaction state has changed!\n */\nstatic void mod_evsub_on_tsx_state(pjsip_transaction *tsx, pjsip_event *event)\n{\n    pjsip_evsub *sub = pjsip_tsx_get_evsub(tsx);\n\n    if (sub == NULL) {\n\tsub = on_new_transaction(tsx, event);\n\tif (sub == NULL)\n\t    return;\n    }\n\n\n    /* Call on_tsx_state callback, if any. */\n    if (sub->user.on_tsx_state && sub->call_cb)\n\t(*sub->user.on_tsx_state)(sub, tsx, event);\n\n\n    /* Process the event: */\n\n    if (sub->role == PJSIP_ROLE_UAC) {\n\ton_tsx_state_uac(sub, tsx, event);\n    } else {\n\ton_tsx_state_uas(sub, tsx, event);\n    }\n\n\n    /* Check transaction TERMINATE event */\n    if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {\n\n\t--sub->pending_tsx;\n\n\tif (sub->state == PJSIP_EVSUB_STATE_TERMINATED &&\n\t    sub->pending_tsx == 0)\n\t{\n\t    evsub_destroy(sub);\n\t}\n\n    }\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-simple/evsub_msg.c",
    "content": "/* $Id: evsub_msg.c 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-simple/evsub_msg.h>\n#include <pjsip/print_util.h>\n#include <pjsip/sip_parser.h>\n#include <pjlib-util/string.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/except.h>\n\n/*\n * Event header.\n */\nstatic int pjsip_event_hdr_print( pjsip_event_hdr *hdr, \n\t\t\t\t  char *buf, pj_size_t size);\nstatic pjsip_event_hdr* pjsip_event_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t       const pjsip_event_hdr *hdr);\nstatic pjsip_event_hdr* pjsip_event_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t\t\t       const pjsip_event_hdr*);\n\nstatic pjsip_hdr_vptr event_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_event_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_event_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_event_hdr_print,\n};\n\n\nPJ_DEF(pjsip_event_hdr*) pjsip_event_hdr_create(pj_pool_t *pool)\n{\n    pjsip_event_hdr *hdr = PJ_POOL_ZALLOC_T(pool, pjsip_event_hdr);\n    hdr->type = PJSIP_H_OTHER;\n    hdr->name.ptr = \"Event\";\n    hdr->name.slen = 5;\n    hdr->sname.ptr = \"o\";\n    hdr->sname.slen = 1;\n    hdr->vptr = &event_hdr_vptr;\n    pj_list_init(hdr);\n    pj_list_init(&hdr->other_param);\n    return hdr;\n}\n\nstatic int pjsip_event_hdr_print( pjsip_event_hdr *hdr, \n\t\t\t\t  char *buf, pj_size_t size)\n{\n    char *p = buf;\n    char *endbuf = buf+size;\n    pj_ssize_t printed;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    copy_advance(p, hdr->name);\n    *p++ = ':';\n    *p++ = ' ';\n\n    copy_advance(p, hdr->event_type);\n    copy_advance_pair(p, \";id=\", 4, hdr->id_param);\n    \n    printed = pjsip_param_print_on(&hdr->other_param, p, endbuf-p,\n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, \n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, ';');\n    if (printed < 0)\n\treturn (int)printed;\n\n    p += printed;\n    return (int)(p - buf);\n}\n\nstatic pjsip_event_hdr* pjsip_event_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t       const pjsip_event_hdr *rhs)\n{\n    pjsip_event_hdr *hdr = pjsip_event_hdr_create(pool);\n    pj_strdup(pool, &hdr->event_type, &rhs->event_type);\n    pj_strdup(pool, &hdr->id_param, &rhs->id_param);\n    pjsip_param_clone(pool, &hdr->other_param, &rhs->other_param);\n    return hdr;\n}\n\nstatic pjsip_event_hdr* \npjsip_event_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t       const pjsip_event_hdr *rhs )\n{\n    pjsip_event_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_event_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    pjsip_param_shallow_clone(pool, &hdr->other_param, &rhs->other_param);\n    return hdr;\n}\n\n\n/*\n * Allow-Events header.\n */\nPJ_DEF(pjsip_allow_events_hdr*) pjsip_allow_events_hdr_create(pj_pool_t *pool)\n{\n    const pj_str_t STR_ALLOW_EVENTS = { \"Allow-Events\", 12};\n    pjsip_allow_events_hdr *hdr;\n\n    hdr = pjsip_generic_array_hdr_create(pool, &STR_ALLOW_EVENTS);\n\n    if (hdr) {\n\thdr->sname.ptr = \"u\";\n\thdr->sname.slen = 1;\n    }\n\n    return hdr;\n}\n\n\n/*\n * Subscription-State header.\n */\nstatic int pjsip_sub_state_hdr_print(pjsip_sub_state_hdr *hdr, \n\t\t\t\t     char *buf, pj_size_t size);\nstatic pjsip_sub_state_hdr* \npjsip_sub_state_hdr_clone(pj_pool_t *pool, \n\t\t\t  const pjsip_sub_state_hdr *hdr);\nstatic pjsip_sub_state_hdr* \npjsip_sub_state_hdr_shallow_clone(pj_pool_t *pool,\n\t\t\t\t  const pjsip_sub_state_hdr*);\n\nstatic pjsip_hdr_vptr sub_state_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &pjsip_sub_state_hdr_clone,\n    (pjsip_hdr_clone_fptr) &pjsip_sub_state_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &pjsip_sub_state_hdr_print,\n};\n\n\nPJ_DEF(pjsip_sub_state_hdr*) pjsip_sub_state_hdr_create(pj_pool_t *pool)\n{\n    pj_str_t sub_state = { \"Subscription-State\", 18 };\n    pjsip_sub_state_hdr *hdr = PJ_POOL_ZALLOC_T(pool, pjsip_sub_state_hdr);\n    hdr->type = PJSIP_H_OTHER;\n    hdr->name = hdr->sname = sub_state;\n    hdr->vptr = &sub_state_hdr_vptr;\n    hdr->expires_param = -1;\n    hdr->retry_after = -1;\n    pj_list_init(hdr);\n    pj_list_init(&hdr->other_param);\n    return hdr;\n}\n\nstatic int pjsip_sub_state_hdr_print(pjsip_sub_state_hdr *hdr, \n\t\t\t\t     char *buf, pj_size_t size)\n{\n    char *p = buf;\n    char *endbuf = buf+size;\n    pj_ssize_t printed;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    copy_advance(p, hdr->name);\n    *p++ = ':';\n    *p++ = ' ';\n\n    copy_advance_escape(p, hdr->sub_state, pc->pjsip_TOKEN_SPEC);\n    copy_advance_pair_escape(p, \";reason=\", 8, hdr->reason_param,\n\t\t\t     pc->pjsip_TOKEN_SPEC);\n    if (hdr->expires_param >= 0) {\n\tpj_memcpy(p, \";expires=\", 9);\n\tp += 9;\n\tprinted = pj_utoa(hdr->expires_param, p);\n\tp += printed;\n    }\n    if (hdr->retry_after >= 0) {\n\tpj_memcpy(p, \";retry-after=\", 13);\n\tp += 9;\n\tprinted = pj_utoa(hdr->retry_after, p);\n\tp += printed;\n    }\n    \n    printed = pjsip_param_print_on( &hdr->other_param, p, endbuf-p, \n\t\t\t\t    &pc->pjsip_TOKEN_SPEC,\n\t\t\t\t    &pc->pjsip_TOKEN_SPEC,\n\t\t\t\t    ';');\n    if (printed < 0)\n\treturn (int)printed;\n\n    p += printed;\n\n    return (int)(p - buf);\n}\n\nstatic pjsip_sub_state_hdr* \npjsip_sub_state_hdr_clone(pj_pool_t *pool, \n\t\t\t  const pjsip_sub_state_hdr *rhs)\n{\n    pjsip_sub_state_hdr *hdr = pjsip_sub_state_hdr_create(pool);\n    pj_strdup(pool, &hdr->sub_state, &rhs->sub_state);\n    pj_strdup(pool, &hdr->reason_param, &rhs->reason_param);\n    hdr->retry_after = rhs->retry_after;\n    hdr->expires_param = rhs->expires_param;\n    pjsip_param_clone(pool, &hdr->other_param, &rhs->other_param);\n    return hdr;\n}\n\nstatic pjsip_sub_state_hdr* \npjsip_sub_state_hdr_shallow_clone(pj_pool_t *pool,\n\t\t\t\t  const pjsip_sub_state_hdr *rhs)\n{\n    pjsip_sub_state_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_sub_state_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    pjsip_param_shallow_clone(pool, &hdr->other_param, &rhs->other_param);\n    return hdr;\n}\n\n\n/*\n * Parse Event header.\n */\nstatic pjsip_hdr *parse_hdr_event(pjsip_parse_ctx *ctx)\n{\n    pjsip_event_hdr *hdr = pjsip_event_hdr_create(ctx->pool);\n    const pj_str_t id_param = { \"id\", 2 };\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    pj_scan_get(ctx->scanner, &pc->pjsip_TOKEN_SPEC, &hdr->event_type);\n\n    while (*ctx->scanner->curptr == ';') {\n\tpj_str_t pname, pvalue;\n\n\tpj_scan_get_char(ctx->scanner);\n\tpjsip_parse_param_imp(ctx->scanner, ctx->pool, &pname, &pvalue, 0);\n\n\tif (pj_stricmp(&pname, &id_param)==0) {\n\t    hdr->id_param = pvalue;\n\t} else {\n\t    pjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);\n\t    param->name = pname;\n\t    param->value = pvalue;\n\t    pj_list_push_back(&hdr->other_param, param);\n\t}\n    }\n    pjsip_parse_end_hdr_imp( ctx->scanner );\n    return (pjsip_hdr*)hdr;\n}\n\n/*\n * Parse Subscription-State header.\n */\nstatic pjsip_hdr* parse_hdr_sub_state( pjsip_parse_ctx *ctx )\n{\n    pjsip_sub_state_hdr *hdr = pjsip_sub_state_hdr_create(ctx->pool);\n    const pj_str_t reason = { \"reason\", 6 },\n\t\t   expires = { \"expires\", 7 },\n\t\t   retry_after = { \"retry-after\", 11 };\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    pj_scan_get(ctx->scanner, &pc->pjsip_TOKEN_SPEC, &hdr->sub_state);\n\n    while (*ctx->scanner->curptr == ';') {\n\tpj_str_t pname, pvalue;\n\n\tpj_scan_get_char(ctx->scanner);\n\tpjsip_parse_param_imp(ctx->scanner, ctx->pool, &pname, &pvalue, 0);\n\n\tif (pj_stricmp(&pname, &reason) == 0) {\n\t    hdr->reason_param = pvalue;\n\n\t} else if (pj_stricmp(&pname, &expires) == 0) {\n\t    hdr->expires_param = pj_strtoul(&pvalue);\n\n\t} else if (pj_stricmp(&pname, &retry_after) == 0) {\n\t    hdr->retry_after = pj_strtoul(&pvalue);\n\n\t} else {\n\t    pjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);\n\t    param->name = pname;\n\t    param->value = pvalue;\n\t    pj_list_push_back(&hdr->other_param, param);\n\t}\n    }\n\n    pjsip_parse_end_hdr_imp( ctx->scanner );\n    return (pjsip_hdr*)hdr;\n}\n\n/*\n * Parse Allow-Events header.\n */\nstatic pjsip_hdr* parse_hdr_allow_events(pjsip_parse_ctx *ctx)\n{\n    pjsip_allow_events_hdr *allow_events =\n             pjsip_allow_events_hdr_create(ctx->pool);\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n    pj_scanner *scanner = ctx->scanner;\n\n    /* Some header fields allow empty elements in the value:\n     *   Accept, Allow, Supported\n     */\n    if (pj_scan_is_eof(scanner) ||\n    *scanner->curptr == '\\r' || *scanner->curptr == '\\n')\n    {\n    goto end;\n    }\n\n    pj_scan_get( scanner, &pc->pjsip_NOT_COMMA_OR_NEWLINE,\n             &allow_events->values[0]);\n    allow_events->count++;\n\n    while (*scanner->curptr == ',') {\n    pj_scan_get_char(scanner);\n    pj_scan_get( scanner, &pc->pjsip_NOT_COMMA_OR_NEWLINE,\n             &allow_events->values[allow_events->count]);\n    allow_events->count++;\n\n    if (allow_events->count >= PJSIP_MAX_ALLOW_EVENTS)\n        break;\n    }\n\nend:\n    pjsip_parse_end_hdr_imp(scanner);\n    return (pjsip_hdr*)allow_events;\n}\n\n/*\n * Register header parsers.\n */\nPJ_DEF(void) pjsip_evsub_init_parser(void)\n{\n    pjsip_register_hdr_parser( \"Event\", \"o\",\n\t\t\t       &parse_hdr_event);\n\n    pjsip_register_hdr_parser( \"Subscription-State\", NULL, \n\t\t\t       &parse_hdr_sub_state);\n\n    pjsip_register_hdr_parser( \"Allow-Events\", NULL,\n                   &parse_hdr_allow_events);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-simple/iscomposing.c",
    "content": "/* $Id: iscomposing.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-simple/iscomposing.h>\n#include <pjsip-simple/errno.h>\n#include <pjsip/sip_msg.h>\n#include <pjlib-util/errno.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n/* MIME */\nstatic const pj_str_t STR_MIME_TYPE = { \"application\", 11 };\nstatic const pj_str_t STR_MIME_SUBTYPE = { \"im-iscomposing+xml\", 18 };\n\n\n/* XML node constants. */\nstatic const pj_str_t STR_ISCOMPOSING\t= { \"isComposing\", 11 };\nstatic const pj_str_t STR_STATE\t\t= { \"state\", 5 };\nstatic const pj_str_t STR_ACTIVE\t= { \"active\", 6 };\nstatic const pj_str_t STR_IDLE\t\t= { \"idle\", 4 };\nstatic const pj_str_t STR_LASTACTIVE\t= { \"lastactive\", 10 };\nstatic const pj_str_t STR_CONTENTTYPE\t= { \"contenttype\", 11 };\nstatic const pj_str_t STR_REFRESH\t= { \"refresh\", 7 };\n\n\n/* XML attributes constants */\nstatic const pj_str_t STR_XMLNS_NAME =     { \"xmlns\", 5 };\nstatic const pj_str_t STR_XMLNS_VAL =      { \"urn:ietf:params:xml:ns:im-iscomposing\", 37 };\nstatic const pj_str_t STR_XMLNS_XSI_NAME = { \"xmlns:xsi\", 9 };\nstatic const pj_str_t STR_XMLNS_XSI_VAL  = { \"http://www.w3.org/2001/XMLSchema-instance\", 41 };\nstatic const pj_str_t STR_XSI_SLOC_NAME =  { \"xsi:schemaLocation\", 18 };\nstatic const pj_str_t STR_XSI_SLOC_VAL =   { \"urn:ietf:params:xml:ns:im-composing iscomposing.xsd\", 51 };\n\n\nPJ_DEF(pj_xml_node*) pjsip_iscomposing_create_xml( pj_pool_t *pool,\n\t\t\t\t\t\t   pj_bool_t is_composing,\n\t\t\t\t\t\t   const pj_time_val *lst_actv,\n\t\t\t\t\t\t   const pj_str_t *content_tp,\n\t\t\t\t\t\t   int refresh)\n{\n    pj_xml_node *doc, *node;\n    pj_xml_attr *attr;\n\n    /* Root document. */\n    doc = pj_xml_node_new(pool, &STR_ISCOMPOSING);\n\n    /* Add attributes */\n    attr = pj_xml_attr_new(pool, &STR_XMLNS_NAME, &STR_XMLNS_VAL);\n    pj_xml_add_attr(doc, attr);\n\n    attr = pj_xml_attr_new(pool, &STR_XMLNS_XSI_NAME, &STR_XMLNS_XSI_VAL);\n    pj_xml_add_attr(doc, attr);\n\n    attr = pj_xml_attr_new(pool, &STR_XSI_SLOC_NAME, &STR_XSI_SLOC_VAL);\n    pj_xml_add_attr(doc, attr);\n\n\n    /* Add state. */\n    node = pj_xml_node_new(pool, &STR_STATE);\n    if (is_composing)\n\tnode->content = STR_ACTIVE;\n    else\n\tnode->content = STR_IDLE;\n    pj_xml_add_node(doc, node);\n\n    /* Add lastactive, if any. */\n    PJ_UNUSED_ARG(lst_actv);\n    //if (!is_composing && lst_actv) {\n    //\tPJ_TODO(IMPLEMENT_LAST_ACTIVE_ATTRIBUTE);\n    //}\n\n    /* Add contenttype, if any. */\n    if (content_tp) {\n\tnode = pj_xml_node_new(pool, &STR_CONTENTTYPE);\n\tpj_strdup(pool, &node->content, content_tp);\n\tpj_xml_add_node(doc, node);\n    }\n\n    /* Add refresh, if any. */\n    if (is_composing && refresh > 1 && refresh < 3601) {\n\tnode = pj_xml_node_new(pool, &STR_REFRESH);\n\tnode->content.ptr = (char*) pj_pool_alloc(pool, 10);\n\tnode->content.slen = pj_utoa(refresh, node->content.ptr);\n\tpj_xml_add_node(doc, node);\n    }\n\n    /* Done! */\n\n    return doc;\n}\n\n\n\n/*\n * Function to print XML message body.\n */\nstatic int xml_print_body( struct pjsip_msg_body *msg_body, \n\t\t\t   char *buf, pj_size_t size)\n{\n    return pj_xml_print((const pj_xml_node*)msg_body->data, buf, size, \n    \t\t\tPJ_TRUE);\n}\n\n\n/*\n * Function to clone XML document.\n */\nstatic void* xml_clone_data(pj_pool_t *pool, const void *data, unsigned len)\n{\n    PJ_UNUSED_ARG(len);\n    return pj_xml_clone( pool, (const pj_xml_node*)data);\n}\n\n\n\nPJ_DEF(pjsip_msg_body*) pjsip_iscomposing_create_body( pj_pool_t *pool,\n\t\t\t\t\t\t   pj_bool_t is_composing,\n\t\t\t\t\t\t   const pj_time_val *lst_actv,\n\t\t\t\t\t\t   const pj_str_t *content_tp,\n\t\t\t\t\t\t   int refresh)\n{\n    pj_xml_node *doc;\n    pjsip_msg_body *body;\n\n    doc = pjsip_iscomposing_create_xml( pool, is_composing, lst_actv,\n\t\t\t\t\tcontent_tp, refresh);\n    if (doc == NULL)\n\treturn NULL;\n\n\n    body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body);\n    body->content_type.type = STR_MIME_TYPE;\n    body->content_type.subtype = STR_MIME_SUBTYPE;\n\n    body->data = doc;\n    body->len = 0;\n\n    body->print_body = &xml_print_body;\n    body->clone_data = &xml_clone_data;\n\n    return body;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_iscomposing_parse( pj_pool_t *pool,\n\t\t\t\t\t     char *msg,\n\t\t\t\t\t     pj_size_t len,\n\t\t\t\t\t     pj_bool_t *p_is_composing,\n\t\t\t\t\t     pj_str_t **p_last_active,\n\t\t\t\t\t     pj_str_t **p_content_type,\n\t\t\t\t\t     int *p_refresh )\n{\n    pj_xml_node *doc, *node;\n\n    /* Set defaults: */\n    if (p_is_composing) *p_is_composing = PJ_FALSE;\n    if (p_last_active) *p_last_active = NULL; \n    if (p_content_type) *p_content_type = NULL;\n\n    /* Parse XML */\n    doc = pj_xml_parse( pool, msg, len);\n    if (!doc)\n\treturn PJLIB_UTIL_EINXML;\n\n    /* Root document must be \"isComposing\" */\n    if (pj_stricmp(&doc->name, &STR_ISCOMPOSING) != 0)\n\treturn PJSIP_SIMPLE_EBADISCOMPOSE;\n\n    /* Get the status. */\n    if (p_is_composing) {\n\tnode = pj_xml_find_node(doc, &STR_STATE);\n\tif (node == NULL)\n\t    return PJSIP_SIMPLE_EBADISCOMPOSE;\n\t*p_is_composing = (pj_stricmp(&node->content, &STR_ACTIVE)==0);\n    }\n\n    /* Get last active. */\n    if (p_last_active) {\n\tnode = pj_xml_find_node(doc, &STR_LASTACTIVE);\n\tif (node)\n\t    *p_last_active = &node->content;\n    }\n\n    /* Get content type */\n    if (p_content_type) {\n\tnode = pj_xml_find_node(doc, &STR_CONTENTTYPE);\n\tif (node)\n\t    *p_content_type = &node->content;\n    }\n\n    /* Get refresh */\n    if (p_refresh) {\n\tnode = pj_xml_find_node(doc, &STR_REFRESH);\n\tif (node)\n\t    *p_refresh = pj_strtoul(&node->content);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-simple/mwi.c",
    "content": "/* $Id: mwi.c 4172 2012-06-19 14:35:18Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-simple/mwi.h>\n#include <pjsip-simple/errno.h>\n#include <pjsip-simple/evsub_msg.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_dialog.h>\n#include <pj/assert.h>\n#include <pj/guid.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n#define THIS_FILE\t\t    \"mwi.c\"\n\n /*\n * MWI module (mod-mdi)\n */\nstatic struct pjsip_module mod_mwi = \n{\n    NULL, NULL,\t\t\t    /* prev, next.\t\t\t*/\n    { \"mod-mwi\", 7 },\t\t    /* Name.\t\t\t\t*/\n    -1,\t\t\t\t    /* Id\t\t\t\t*/\n    PJSIP_MOD_PRIORITY_DIALOG_USAGE,/* Priority\t\t\t\t*/\n    NULL,\t\t\t    /* load()\t\t\t\t*/\n    NULL,\t\t\t    /* start()\t\t\t\t*/\n    NULL,\t\t\t    /* stop()\t\t\t\t*/\n    NULL,\t\t\t    /* unload()\t\t\t\t*/\n    NULL,\t\t\t    /* on_rx_request()\t\t\t*/\n    NULL,\t\t\t    /* on_rx_response()\t\t\t*/\n    NULL,\t\t\t    /* on_tx_request.\t\t\t*/\n    NULL,\t\t\t    /* on_tx_response()\t\t\t*/\n    NULL,\t\t\t    /* on_tsx_state()\t\t\t*/\n};\n\n\n/*\n * This structure describe an mwi agent (both client and server)\n */\ntypedef struct pjsip_mwi\n{\n    pjsip_evsub\t\t*sub;\t\t/**< Event subscribtion record.\t    */\n    pjsip_dialog\t*dlg;\t\t/**< The dialog.\t\t    */\n    pjsip_evsub_user\t user_cb;\t/**< The user callback.\t\t    */\n\n    /* These are for server subscriptions */\n    pj_pool_t\t\t*body_pool;\t/**< Pool to save message body\t    */\n    pjsip_media_type\t mime_type;\t/**< MIME type of last msg body\t    */\n    pj_str_t\t\t body;\t\t/**< Last sent message body\t    */\n} pjsip_mwi;\n\n\n/*\n * Forward decl for evsub callbacks.\n */\nstatic void mwi_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);\nstatic void mwi_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,\n\t\t\t\t    pjsip_event *event);\nstatic void mwi_on_evsub_rx_refresh( pjsip_evsub *sub, \n\t\t\t\t     pjsip_rx_data *rdata,\n\t\t\t\t     int *p_st_code,\n\t\t\t\t     pj_str_t **p_st_text,\n\t\t\t\t     pjsip_hdr *res_hdr,\n\t\t\t\t     pjsip_msg_body **p_body);\nstatic void mwi_on_evsub_rx_notify( pjsip_evsub *sub, \n\t\t\t\t    pjsip_rx_data *rdata,\n\t\t\t\t    int *p_st_code,\n\t\t\t\t    pj_str_t **p_st_text,\n\t\t\t\t    pjsip_hdr *res_hdr,\n\t\t\t\t    pjsip_msg_body **p_body);\nstatic void mwi_on_evsub_client_refresh(pjsip_evsub *sub);\nstatic void mwi_on_evsub_server_timeout(pjsip_evsub *sub);\n\n\n/*\n * Event subscription callback for mwi.\n */\nstatic pjsip_evsub_user mwi_user = \n{\n    &mwi_on_evsub_state,\n    &mwi_on_evsub_tsx_state,\n    &mwi_on_evsub_rx_refresh,\n    &mwi_on_evsub_rx_notify,\n    &mwi_on_evsub_client_refresh,\n    &mwi_on_evsub_server_timeout,\n};\n\n\n/*\n * Some static constants.\n */\nstatic const pj_str_t STR_EVENT\t\t = { \"Event\", 5 };\nstatic const pj_str_t STR_MWI\t\t = { \"message-summary\", 15 };\nstatic const pj_str_t STR_APP_SIMPLE_SMS = { \"application/simple-message-summary\", 34};\n\n/*\n * Init mwi module.\n */\nPJ_DEF(pj_status_t) pjsip_mwi_init_module( pjsip_endpoint *endpt,\n\t\t\t\t\t   pjsip_module *mod_evsub)\n{\n    pj_status_t status;\n    pj_str_t accept[1];\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(endpt && mod_evsub, PJ_EINVAL);\n\n    /* Must have not been registered */\n    PJ_ASSERT_RETURN(mod_mwi.id == -1, PJ_EINVALIDOP);\n\n    /* Register to endpoint */\n    status = pjsip_endpt_register_module(endpt, &mod_mwi);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    accept[0] = STR_APP_SIMPLE_SMS;\n\n    /* Register event package to event module. */\n    status = pjsip_evsub_register_pkg( &mod_mwi, &STR_MWI, \n\t\t\t\t       PJSIP_MWI_DEFAULT_EXPIRES, \n\t\t\t\t       PJ_ARRAY_SIZE(accept), accept);\n    if (status != PJ_SUCCESS) {\n\tpjsip_endpt_unregister_module(endpt, &mod_mwi);\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get mwi module instance.\n */\nPJ_DEF(pjsip_module*) pjsip_mwi_instance(void)\n{\n    return &mod_mwi;\n}\n\n\n/*\n * Create client subscription.\n */\nPJ_DEF(pj_status_t) pjsip_mwi_create_uac( pjsip_dialog *dlg,\n\t\t\t\t\t  const pjsip_evsub_user *user_cb,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t\t  pjsip_evsub **p_evsub )\n{\n    pj_status_t status;\n    pjsip_mwi *mwi;\n    pjsip_evsub *sub;\n\n    PJ_ASSERT_RETURN(dlg && p_evsub, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(options);\n\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Create event subscription */\n    status = pjsip_evsub_create_uac( dlg,  &mwi_user, &STR_MWI, \n\t\t\t\t     options, &sub);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Create mwi */\n    mwi = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_mwi);\n    mwi->dlg = dlg;\n    mwi->sub = sub;\n    if (user_cb)\n\tpj_memcpy(&mwi->user_cb, user_cb, sizeof(pjsip_evsub_user));\n\n    /* Attach to evsub */\n    pjsip_evsub_set_mod_data(sub, mod_mwi.id, mwi);\n\n    *p_evsub = sub;\n\non_return:\n    pjsip_dlg_dec_lock(dlg);\n    return status;\n}\n\n\n/*\n * Create server subscription.\n */\nPJ_DEF(pj_status_t) pjsip_mwi_create_uas( pjsip_dialog *dlg,\n\t\t\t\t\t  const pjsip_evsub_user *user_cb,\n\t\t\t\t\t  pjsip_rx_data *rdata,\n\t\t\t\t\t  pjsip_evsub **p_evsub )\n{\n    pjsip_accept_hdr *accept;\n    pjsip_event_hdr *event;\n    pjsip_evsub *sub;\n    pjsip_mwi *mwi;\n    char obj_name[PJ_MAX_OBJ_NAME];\n    pj_status_t status;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(dlg && rdata && p_evsub, PJ_EINVAL);\n\n    /* Must be request message */\n    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,\n\t\t     PJSIP_ENOTREQUESTMSG);\n\n    /* Check that request is SUBSCRIBE */\n    PJ_ASSERT_RETURN(pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,\n\t\t\t\t      &pjsip_subscribe_method)==0,\n\t\t     PJSIP_SIMPLE_ENOTSUBSCRIBE);\n\n    /* Check that Event header contains \"mwi\" */\n    event = (pjsip_event_hdr*)\n    \t    pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &STR_EVENT, NULL);\n    if (!event) {\n\treturn PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);\n    }\n    if (pj_stricmp(&event->event_type, &STR_MWI) != 0) {\n\treturn PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_EVENT);\n    }\n\n    /* Check that request contains compatible Accept header. */\n    accept = (pjsip_accept_hdr*)\n    \t     pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, NULL);\n    if (accept) {\n\tunsigned i;\n\tfor (i=0; i<accept->count; ++i) {\n\t    if (pj_stricmp(&accept->values[i], &STR_APP_SIMPLE_SMS)==0) {\n\t\tbreak;\n\t    }\n\t}\n\n\tif (i==accept->count) {\n\t    /* Nothing is acceptable */\n\t    return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE);\n\t}\n\n    } else {\n\t/* No Accept header. \n\t * Assume client supports \"application/simple-message-summary\" \n\t*/\n    }\n\n    /* Lock dialog */\n    pjsip_dlg_inc_lock(dlg);\n\n\n    /* Create server subscription */\n    status = pjsip_evsub_create_uas( dlg, &mwi_user, rdata, 0, &sub);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Create server mwi subscription */\n    mwi = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_mwi);\n    mwi->dlg = dlg;\n    mwi->sub = sub;\n    if (user_cb)\n\tpj_memcpy(&mwi->user_cb, user_cb, sizeof(pjsip_evsub_user));\n\n    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, \"mwibd%p\", dlg->pool);\n    mwi->body_pool = pj_pool_create(dlg->pool->factory, obj_name, \n\t\t\t\t    512, 512, NULL);\n\n    /* Attach to evsub */\n    pjsip_evsub_set_mod_data(sub, mod_mwi.id, mwi);\n\n    /* Done: */\n    *p_evsub = sub;\n\non_return:\n    pjsip_dlg_dec_lock(dlg);\n    return status;\n}\n\n\n/*\n * Forcefully terminate mwi.\n */\nPJ_DEF(pj_status_t) pjsip_mwi_terminate( pjsip_evsub *sub,\n\t\t\t\t\t pj_bool_t notify )\n{\n    return pjsip_evsub_terminate(sub, notify);\n}\n\n/*\n * Create SUBSCRIBE\n */\nPJ_DEF(pj_status_t) pjsip_mwi_initiate( pjsip_evsub *sub,\n\t\t\t\t\tpj_int32_t expires,\n\t\t\t\t\tpjsip_tx_data **p_tdata)\n{\n    return pjsip_evsub_initiate(sub, &pjsip_subscribe_method, expires, \n\t\t\t\tp_tdata);\n}\n\n\n/*\n * Accept incoming subscription.\n */\nPJ_DEF(pj_status_t) pjsip_mwi_accept( pjsip_evsub *sub,\n\t\t\t\t      pjsip_rx_data *rdata,\n\t\t\t\t      int st_code,\n\t\t\t\t      const pjsip_hdr *hdr_list )\n{\n    return pjsip_evsub_accept( sub, rdata, st_code, hdr_list );\n}\n\n/*\n * Create message body and attach it to the (NOTIFY) request.\n */\nstatic pj_status_t mwi_create_msg_body( pjsip_mwi *mwi, \n\t\t\t\t\tpjsip_tx_data *tdata)\n{\n    pjsip_msg_body *body;\n    pj_str_t dup_text;\n\n    PJ_ASSERT_RETURN(mwi->mime_type.type.slen && mwi->body.slen, PJ_EINVALIDOP);\n    \n    /* Clone the message body and mime type */\n    pj_strdup(tdata->pool, &dup_text, &mwi->body);\n\n    /* Create the message body */\n    body = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_msg_body);\n    pjsip_media_type_cp(tdata->pool, &body->content_type, &mwi->mime_type);\n    body->data = dup_text.ptr;\n    body->len = (unsigned)dup_text.slen;\n    body->print_body = &pjsip_print_text_body;\n    body->clone_data = &pjsip_clone_text_data;\n\n    /* Attach to tdata */\n    tdata->msg->body = body;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create NOTIFY\n */\nPJ_DEF(pj_status_t) pjsip_mwi_notify(  pjsip_evsub *sub,\n\t\t\t\t       pjsip_evsub_state state,\n\t\t\t\t       const pj_str_t *state_str,\n\t\t\t\t       const pj_str_t *reason,\n\t\t\t\t       const pjsip_media_type *mime_type,\n\t\t\t\t       const pj_str_t *body,\n\t\t\t\t       pjsip_tx_data **p_tdata)\n{\n    pjsip_mwi *mwi;\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n    \n    /* Check arguments. */\n    PJ_ASSERT_RETURN(sub && mime_type && body && p_tdata, PJ_EINVAL);\n\n    /* Get the mwi object. */\n    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);\n    PJ_ASSERT_RETURN(mwi != NULL, PJ_EINVALIDOP);\n\n    /* Lock object. */\n    pjsip_dlg_inc_lock(mwi->dlg);\n\n    /* Create the NOTIFY request. */\n    status = pjsip_evsub_notify( sub, state, state_str, reason, &tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Update the cached message body */\n    if (mime_type || body)\n\tpj_pool_reset(mwi->body_pool);\n    if (mime_type)\n\tpjsip_media_type_cp(mwi->body_pool, &mwi->mime_type, mime_type);\n    if (body)\n\tpj_strdup(mwi->body_pool, &mwi->body, body);\n\n    /* Create message body */\n    status = mwi_create_msg_body( mwi, tdata );\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Done. */\n    *p_tdata = tdata;\n\non_return:\n    pjsip_dlg_dec_lock(mwi->dlg);\n    return status;\n}\n\n\n/*\n * Create NOTIFY that reflect current state.\n */\nPJ_DEF(pj_status_t) pjsip_mwi_current_notify( pjsip_evsub *sub,\n\t\t\t\t\t      pjsip_tx_data **p_tdata )\n{\n    pjsip_mwi *mwi;\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n    \n    /* Check arguments. */\n    PJ_ASSERT_RETURN(sub && p_tdata, PJ_EINVAL);\n\n    /* Get the mwi object. */\n    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);\n    PJ_ASSERT_RETURN(mwi != NULL, PJ_EINVALIDOP);\n\n    /* Lock object. */\n    pjsip_dlg_inc_lock(mwi->dlg);\n\n    /* Create the NOTIFY request. */\n    status = pjsip_evsub_current_notify( sub, &tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n\n    /* Create message body to reflect the mwi status. */\n    status = mwi_create_msg_body( mwi, tdata );\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Done. */\n    *p_tdata = tdata;\n\non_return:\n    pjsip_dlg_dec_lock(mwi->dlg);\n    return status;\n}\n\n\n/*\n * Send request.\n */\nPJ_DEF(pj_status_t) pjsip_mwi_send_request( pjsip_evsub *sub,\n\t\t\t\t\t     pjsip_tx_data *tdata )\n{\n    return pjsip_evsub_send_request(sub, tdata);\n}\n\n/*\n * This callback is called by event subscription when subscription\n * state has changed.\n */\nstatic void mwi_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)\n{\n    pjsip_mwi *mwi;\n\n    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);\n    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});\n\n    if (mwi->user_cb.on_evsub_state)\n\t(*mwi->user_cb.on_evsub_state)(sub, event);\n\n    if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {\n\tif (mwi->body_pool) {\n\t    pj_pool_release(mwi->body_pool);\n\t    mwi->body_pool = NULL;\n\t}\n    }\n}\n\n/*\n * Called when transaction state has changed.\n */\nstatic void mwi_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,\n\t\t\t\t     pjsip_event *event)\n{\n    pjsip_mwi *mwi;\n\n    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);\n    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});\n\n    if (mwi->user_cb.on_tsx_state)\n\t(*mwi->user_cb.on_tsx_state)(sub, tsx, event);\n}\n\n\n/*\n * Called when SUBSCRIBE is received.\n */\nstatic void mwi_on_evsub_rx_refresh( pjsip_evsub *sub, \n\t\t\t\t     pjsip_rx_data *rdata,\n\t\t\t\t     int *p_st_code,\n\t\t\t\t     pj_str_t **p_st_text,\n\t\t\t\t     pjsip_hdr *res_hdr,\n\t\t\t\t     pjsip_msg_body **p_body)\n{\n    pjsip_mwi *mwi;\n\n    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);\n    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});\n\n    if (mwi->user_cb.on_rx_refresh) {\n\t(*mwi->user_cb.on_rx_refresh)(sub, rdata, p_st_code, p_st_text,\n\t\t\t\t       res_hdr, p_body);\n\n    } else {\n\t/* Implementors MUST send NOTIFY if it implements on_rx_refresh */\n\tpjsip_tx_data *tdata;\n\tpj_str_t timeout = { \"timeout\", 7};\n\tpj_status_t status;\n\n\tif (pjsip_evsub_get_state(sub)==PJSIP_EVSUB_STATE_TERMINATED) {\n\t    status = pjsip_mwi_notify( sub, PJSIP_EVSUB_STATE_TERMINATED,\n\t\t\t\t       NULL, &timeout, NULL, NULL, &tdata);\n\t} else {\n\t    status = pjsip_mwi_current_notify(sub, &tdata);\n\t}\n\n\tif (status == PJ_SUCCESS)\n\t    pjsip_mwi_send_request(sub, tdata);\n    }\n}\n\n\n/*\n * Called when NOTIFY is received.\n */\nstatic void mwi_on_evsub_rx_notify( pjsip_evsub *sub, \n\t\t\t\t     pjsip_rx_data *rdata,\n\t\t\t\t     int *p_st_code,\n\t\t\t\t     pj_str_t **p_st_text,\n\t\t\t\t     pjsip_hdr *res_hdr,\n\t\t\t\t     pjsip_msg_body **p_body)\n{\n    pjsip_mwi *mwi;\n\n    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);\n    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});\n\n    /* Just notify application. */\n    if (mwi->user_cb.on_rx_notify) {\n\t(*mwi->user_cb.on_rx_notify)(sub, rdata, p_st_code, p_st_text, \n\t\t\t\t     res_hdr, p_body);\n    }\n}\n\n/*\n * Called when it's time to send SUBSCRIBE.\n */\nstatic void mwi_on_evsub_client_refresh(pjsip_evsub *sub)\n{\n    pjsip_mwi *mwi;\n\n    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);\n    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});\n\n    if (mwi->user_cb.on_client_refresh) {\n\t(*mwi->user_cb.on_client_refresh)(sub);\n    } else {\n\tpj_status_t status;\n\tpjsip_tx_data *tdata;\n\n\tstatus = pjsip_mwi_initiate(sub, -1, &tdata);\n\tif (status == PJ_SUCCESS)\n\t    pjsip_mwi_send_request(sub, tdata);\n    }\n}\n\n/*\n * Called when no refresh is received after the interval.\n */\nstatic void mwi_on_evsub_server_timeout(pjsip_evsub *sub)\n{\n    pjsip_mwi *mwi;\n\n    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);\n    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});\n\n    if (mwi->user_cb.on_server_timeout) {\n\t(*mwi->user_cb.on_server_timeout)(sub);\n    } else {\n\tpj_status_t status;\n\tpjsip_tx_data *tdata;\n\tpj_str_t reason = { \"timeout\", 7 };\n\n\tstatus = pjsip_mwi_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,\n\t\t\t\t   NULL, &reason, NULL, NULL, &tdata);\n\tif (status == PJ_SUCCESS)\n\t    pjsip_mwi_send_request(sub, tdata);\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-simple/pidf.c",
    "content": "/* $Id: pidf.c 3841 2011-10-24 09:28:13Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-simple/pidf.h>\n#include <pj/string.h>\n#include <pj/pool.h>\n#include <pj/assert.h>\n\n\nstruct pjpidf_op_desc pjpidf_op = \n{\n    {\n\t&pjpidf_pres_construct,\n\t&pjpidf_pres_add_tuple,\n\t&pjpidf_pres_get_first_tuple,\n\t&pjpidf_pres_get_next_tuple,\n\t&pjpidf_pres_find_tuple,\n\t&pjpidf_pres_remove_tuple,\n\t&pjpidf_pres_add_note,\n\t&pjpidf_pres_get_first_note,\n\t&pjpidf_pres_get_next_note\n    },\n    {\n\t&pjpidf_tuple_construct,\n\t&pjpidf_tuple_get_id,\n\t&pjpidf_tuple_set_id,\n\t&pjpidf_tuple_get_status,\n\t&pjpidf_tuple_get_contact,\n\t&pjpidf_tuple_set_contact,\n\t&pjpidf_tuple_set_contact_prio,\n\t&pjpidf_tuple_get_contact_prio,\n\t&pjpidf_tuple_add_note,\n\t&pjpidf_tuple_get_first_note,\n\t&pjpidf_tuple_get_next_note,\n\t&pjpidf_tuple_get_timestamp,\n\t&pjpidf_tuple_set_timestamp,\n\t&pjpidf_tuple_set_timestamp_np\n    },\n    {\n\t&pjpidf_status_construct,\n\t&pjpidf_status_is_basic_open,\n\t&pjpidf_status_set_basic_open\n    }\n};\n\nstatic pj_str_t PRESENCE = { \"presence\", 8 };\nstatic pj_str_t ENTITY = { \"entity\", 6};\nstatic pj_str_t\tTUPLE = { \"tuple\", 5 };\nstatic pj_str_t ID = { \"id\", 2 };\nstatic pj_str_t NOTE = { \"note\", 4 };\nstatic pj_str_t STATUS = { \"status\", 6 };\nstatic pj_str_t CONTACT = { \"contact\", 7 };\nstatic pj_str_t PRIORITY = { \"priority\", 8 };\nstatic pj_str_t TIMESTAMP = { \"timestamp\", 9 };\nstatic pj_str_t BASIC = { \"basic\", 5 };\nstatic pj_str_t OPEN = { \"open\", 4 };\nstatic pj_str_t CLOSED = { \"closed\", 6 };\nstatic pj_str_t EMPTY_STRING = { NULL, 0 };\n\nstatic pj_str_t XMLNS = { \"xmlns\", 5 };\nstatic pj_str_t PIDF_XMLNS = { \"urn:ietf:params:xml:ns:pidf\", 27 };\n\nstatic void xml_init_node(pj_pool_t *pool, pj_xml_node *node,\n\t\t\t  pj_str_t *name, const pj_str_t *value)\n{\n    pj_list_init(&node->attr_head);\n    pj_list_init(&node->node_head);\n    node->name = *name;\n    if (value) pj_strdup(pool, &node->content, value);\n    else node->content.ptr=NULL, node->content.slen=0;\n}\n\nstatic pj_xml_attr* xml_create_attr(pj_pool_t *pool, pj_str_t *name,\n\t\t\t\t    const pj_str_t *value)\n{\n    pj_xml_attr *attr = PJ_POOL_ALLOC_T(pool, pj_xml_attr);\n    attr->name = *name;\n    pj_strdup(pool, &attr->value, value);\n    return attr;\n}\n\n/* Presence */\nPJ_DEF(void) pjpidf_pres_construct(pj_pool_t *pool, pjpidf_pres *pres,\n\t\t\t\t   const pj_str_t *entity)\n{\n    pj_xml_attr *attr;\n\n    xml_init_node(pool, pres, &PRESENCE, NULL);\n    attr = xml_create_attr(pool, &ENTITY, entity);\n    pj_xml_add_attr(pres, attr);\n    attr = xml_create_attr(pool, &XMLNS, &PIDF_XMLNS);\n    pj_xml_add_attr(pres, attr);\n}\n\nPJ_DEF(pjpidf_tuple*) pjpidf_pres_add_tuple(pj_pool_t *pool, pjpidf_pres *pres,\n\t\t\t\t\t    const pj_str_t *id)\n{\n    pjpidf_tuple *t = PJ_POOL_ALLOC_T(pool, pjpidf_tuple);\n    pjpidf_tuple_construct(pool, t, id);\n    pj_xml_add_node(pres, t);\n    return t;\n}\n\nPJ_DEF(pjpidf_tuple*) pjpidf_pres_get_first_tuple(pjpidf_pres *pres)\n{\n    return pj_xml_find_node(pres, &TUPLE);\n}\n\nPJ_DEF(pjpidf_tuple*) pjpidf_pres_get_next_tuple(pjpidf_pres *pres, \n\t\t\t\t\t\t pjpidf_tuple *tuple)\n{\n    return pj_xml_find_next_node(pres, tuple, &TUPLE);\n}\n\nstatic pj_bool_t find_tuple_by_id(const pj_xml_node *node, const void *id)\n{\n    return pj_xml_find_attr(node, &ID, (const pj_str_t*)id) != NULL;\n}\n\nPJ_DEF(pjpidf_tuple*) pjpidf_pres_find_tuple(pjpidf_pres *pres, const pj_str_t *id)\n{\n    return pj_xml_find(pres, &TUPLE, id, &find_tuple_by_id);\n}\n\nPJ_DEF(void) pjpidf_pres_remove_tuple(pjpidf_pres *pres, pjpidf_tuple *t)\n{\n    PJ_UNUSED_ARG(pres);\n    pj_list_erase(t);\n}\n\nPJ_DEF(pjpidf_note*) pjpidf_pres_add_note(pj_pool_t *pool, pjpidf_pres *pres, \n\t\t\t\t\t  const pj_str_t *text)\n{\n    pjpidf_note *note = PJ_POOL_ALLOC_T(pool, pjpidf_note);\n    xml_init_node(pool, note, &NOTE, text);\n    pj_xml_add_node(pres, note);\n    return note;\n}\n\nPJ_DEF(pjpidf_note*) pjpidf_pres_get_first_note(pjpidf_pres *pres)\n{\n    return pj_xml_find_node( pres, &NOTE);\n}\n\nPJ_DEF(pjpidf_note*) pjpidf_pres_get_next_note(pjpidf_pres *t, pjpidf_note *note)\n{\n    return pj_xml_find_next_node(t, note, &NOTE);\n}\n\n\n/* Tuple */\nPJ_DEF(void) pjpidf_tuple_construct(pj_pool_t *pool, pjpidf_tuple *t,\n\t\t\t\t    const pj_str_t *id)\n{\n    pj_xml_attr *attr;\n    pjpidf_status *st;\n\n    xml_init_node(pool, t, &TUPLE, NULL);\n    attr = xml_create_attr(pool, &ID, id);\n    pj_xml_add_attr(t, attr);\n    st = PJ_POOL_ALLOC_T(pool, pjpidf_status);\n    pjpidf_status_construct(pool, st);\n    pj_xml_add_node(t, st);\n}\n\nPJ_DEF(const pj_str_t*) pjpidf_tuple_get_id(const pjpidf_tuple *t)\n{\n    const pj_xml_attr *attr = pj_xml_find_attr((pj_xml_node*)t, &ID, NULL);\n    pj_assert(attr);\n    return &attr->value;\n}\n\nPJ_DEF(void) pjpidf_tuple_set_id(pj_pool_t *pool, pjpidf_tuple *t, const pj_str_t *id)\n{\n    pj_xml_attr *attr = pj_xml_find_attr(t, &ID, NULL);\n    pj_assert(attr);\n    pj_strdup(pool, &attr->value, id);\n}\n\n\nPJ_DEF(pjpidf_status*) pjpidf_tuple_get_status(pjpidf_tuple *t)\n{\n    pjpidf_status *st = (pjpidf_status*)pj_xml_find_node(t, &STATUS);\n    pj_assert(st);\n    return st;\n}\n\n\nPJ_DEF(const pj_str_t*) pjpidf_tuple_get_contact(const pjpidf_tuple *t)\n{\n    pj_xml_node *node = pj_xml_find_node((pj_xml_node*)t, &CONTACT);\n    if (!node)\n\treturn &EMPTY_STRING;\n    return &node->content;\n}\n\nPJ_DEF(void) pjpidf_tuple_set_contact(pj_pool_t *pool, pjpidf_tuple *t, \n\t\t\t\t      const pj_str_t *contact)\n{\n    pj_xml_node *node = pj_xml_find_node(t, &CONTACT);\n    if (!node) {\n\tnode = PJ_POOL_ALLOC_T(pool, pj_xml_node);\n\txml_init_node(pool, node, &CONTACT, contact);\n\tpj_xml_add_node(t, node);\n    } else {\n\tpj_strdup(pool, &node->content, contact);\n    }\n}\n\nPJ_DEF(void) pjpidf_tuple_set_contact_prio(pj_pool_t *pool, pjpidf_tuple *t, \n\t\t\t\t\t   const pj_str_t *prio)\n{\n    pj_xml_node *node = pj_xml_find_node(t, &CONTACT);\n    pj_xml_attr *attr;\n\n    if (!node) {\n\tnode = PJ_POOL_ALLOC_T(pool, pj_xml_node);\n\txml_init_node(pool, node, &CONTACT, NULL);\n\tpj_xml_add_node(t, node);\n    }\n    attr = pj_xml_find_attr(node, &PRIORITY, NULL);\n    if (!attr) {\n\tattr = xml_create_attr(pool, &PRIORITY, prio);\n\tpj_xml_add_attr(node, attr);\n    } else {\n\tpj_strdup(pool, &attr->value, prio);\n    }\n}\n\nPJ_DEF(const pj_str_t*) pjpidf_tuple_get_contact_prio(const pjpidf_tuple *t)\n{\n    pj_xml_node *node = pj_xml_find_node((pj_xml_node*)t, &CONTACT);\n    pj_xml_attr *attr;\n\n    if (!node)\n\treturn &EMPTY_STRING;\n    attr = pj_xml_find_attr(node, &PRIORITY, NULL);\n    if (!attr)\n\treturn &EMPTY_STRING;\n    return &attr->value;\n}\n\n\nPJ_DEF(pjpidf_note*) pjpidf_tuple_add_note(pj_pool_t *pool, pjpidf_tuple *t,\n\t\t\t\t\t   const pj_str_t *text)\n{\n    pjpidf_note *note = PJ_POOL_ALLOC_T(pool, pjpidf_note);\n    xml_init_node(pool, note, &NOTE, text);\n    pj_xml_add_node(t, note);\n    return note;\n}\n\nPJ_DEF(pjpidf_note*) pjpidf_tuple_get_first_note(pjpidf_tuple *t)\n{\n    return pj_xml_find_node(t, &NOTE);\n}\n\nPJ_DEF(pjpidf_note*) pjpidf_tuple_get_next_note(pjpidf_tuple *t, pjpidf_note *n)\n{\n    return pj_xml_find_next_node(t, n, &NOTE);\n}\n\n\nPJ_DEF(const pj_str_t*) pjpidf_tuple_get_timestamp(const pjpidf_tuple *t)\n{\n    pj_xml_node *node = pj_xml_find_node((pj_xml_node*)t, &TIMESTAMP);\n    return node ? &node->content : &EMPTY_STRING;\n}\n\nPJ_DEF(void) pjpidf_tuple_set_timestamp(pj_pool_t *pool, pjpidf_tuple *t,\n\t\t\t\t\tconst pj_str_t *ts)\n{\n    pj_xml_node *node = pj_xml_find_node(t, &TIMESTAMP);\n    if (!node) {\n\tnode = PJ_POOL_ALLOC_T(pool, pj_xml_node);\n\txml_init_node(pool, node, &TIMESTAMP, ts);\n\tpj_xml_add_node(t, node);\n    } else {\n\tpj_strdup(pool, &node->content, ts);\n    }\n}\n\n\nPJ_DEF(void) pjpidf_tuple_set_timestamp_np(pj_pool_t *pool, pjpidf_tuple *t, \n\t\t\t\t\t   pj_str_t *ts)\n{\n    pj_xml_node *node = pj_xml_find_node(t, &TIMESTAMP);\n    if (!node) {\n\tnode = PJ_POOL_ALLOC_T(pool, pj_xml_node);\n\txml_init_node(pool, node, &TIMESTAMP, ts);\n    } else {\n\tnode->content = *ts;\n    }\n}\n\n\n/* Status */\nPJ_DEF(void) pjpidf_status_construct(pj_pool_t *pool, pjpidf_status *st)\n{\n    pj_xml_node *node;\n\n    xml_init_node(pool, st, &STATUS, NULL);\n    node = PJ_POOL_ALLOC_T(pool, pj_xml_node);\n    xml_init_node(pool, node, &BASIC, &CLOSED);\n    pj_xml_add_node(st, node);\n}\n\nPJ_DEF(pj_bool_t) pjpidf_status_is_basic_open(const pjpidf_status *st)\n{\n    pj_xml_node *node = pj_xml_find_node((pj_xml_node*)st, &BASIC);\n    if (!node)\n\treturn PJ_FALSE;\n    return pj_stricmp(&node->content, &OPEN)==0;\n}\n\nPJ_DEF(void) pjpidf_status_set_basic_open(pjpidf_status *st, pj_bool_t open)\n{\n    pj_xml_node *node = pj_xml_find_node(st, &BASIC);\n    if (node)\n\tnode->content = open ? OPEN : CLOSED;\n}\n\nPJ_DEF(pjpidf_pres*) pjpidf_create(pj_pool_t *pool, const pj_str_t *entity)\n{\n    pjpidf_pres *pres = PJ_POOL_ALLOC_T(pool, pjpidf_pres);\n    pjpidf_pres_construct(pool, pres, entity);\n    return pres;\n}\n\nPJ_DEF(pjpidf_pres*) pjpidf_parse(pj_pool_t *pool, char *text, int len)\n{\n    pjpidf_pres *pres = pj_xml_parse(pool, text, len);\n    if (pres && pres->name.slen >= 8) {\n\tpj_str_t name;\n\n\tname.ptr = pres->name.ptr + (pres->name.slen - 8);\n\tname.slen = 8;\n\n\tif (pj_stricmp(&name, &PRESENCE) == 0)\n\t    return pres;\n    }\n    return NULL;\n}\n\nPJ_DEF(int) pjpidf_print(const pjpidf_pres* pres, char *buf, int len)\n{\n    return pj_xml_print(pres, buf, len, PJ_TRUE);\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-simple/presence.c",
    "content": "/* $Id: presence.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-simple/presence.h>\n#include <pjsip-simple/errno.h>\n#include <pjsip-simple/evsub_msg.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_multipart.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_dialog.h>\n#include <pj/assert.h>\n#include <pj/guid.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n#define THIS_FILE\t\t    \"presence.c\"\n#define PRES_DEFAULT_EXPIRES\t    PJSIP_PRES_DEFAULT_EXPIRES\n\n#if PJSIP_PRES_BAD_CONTENT_RESPONSE < 200 || \\\n    PJSIP_PRES_BAD_CONTENT_RESPONSE > 699 || \\\n    PJSIP_PRES_BAD_CONTENT_RESPONSE/100 == 3\n# error Invalid PJSIP_PRES_BAD_CONTENT_RESPONSE value\n#endif\n\n/*\n * Presence module (mod-presence)\n */\nstatic struct pjsip_module mod_presence = \n{\n    NULL, NULL,\t\t\t    /* prev, next.\t\t\t*/\n    { \"mod-presence\", 12 },\t    /* Name.\t\t\t\t*/\n    -1,\t\t\t\t    /* Id\t\t\t\t*/\n    PJSIP_MOD_PRIORITY_DIALOG_USAGE,/* Priority\t\t\t\t*/\n    NULL,\t\t\t    /* load()\t\t\t\t*/\n    NULL,\t\t\t    /* start()\t\t\t\t*/\n    NULL,\t\t\t    /* stop()\t\t\t\t*/\n    NULL,\t\t\t    /* unload()\t\t\t\t*/\n    NULL,\t\t\t    /* on_rx_request()\t\t\t*/\n    NULL,\t\t\t    /* on_rx_response()\t\t\t*/\n    NULL,\t\t\t    /* on_tx_request.\t\t\t*/\n    NULL,\t\t\t    /* on_tx_response()\t\t\t*/\n    NULL,\t\t\t    /* on_tsx_state()\t\t\t*/\n};\n\n\n/*\n * Presence message body type.\n */\ntypedef enum content_type_e\n{\n    CONTENT_TYPE_NONE,\n    CONTENT_TYPE_PIDF,\n    CONTENT_TYPE_XPIDF,\n} content_type_e;\n\n/*\n * This structure describe a presentity, for both subscriber and notifier.\n */\nstruct pjsip_pres\n{\n    pjsip_evsub\t\t*sub;\t\t/**< Event subscribtion record.\t    */\n    pjsip_dialog\t*dlg;\t\t/**< The dialog.\t\t    */\n    content_type_e\t content_type;\t/**< Content-Type.\t\t    */\n    pj_pool_t\t\t*status_pool;\t/**< Pool for pres_status\t    */\n    pjsip_pres_status\t status;\t/**< Presence status.\t\t    */\n    pj_pool_t\t\t*tmp_pool;\t/**< Pool for tmp_status\t    */\n    pjsip_pres_status\t tmp_status;\t/**< Temp, before NOTIFY is answred.*/\n    pjsip_evsub_user\t user_cb;\t/**< The user callback.\t\t    */\n};\n\n\ntypedef struct pjsip_pres pjsip_pres;\n\n\n/*\n * Forward decl for evsub callback.\n */\nstatic void pres_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);\nstatic void pres_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,\n\t\t\t\t     pjsip_event *event);\nstatic void pres_on_evsub_rx_refresh( pjsip_evsub *sub, \n\t\t\t\t      pjsip_rx_data *rdata,\n\t\t\t\t      int *p_st_code,\n\t\t\t\t      pj_str_t **p_st_text,\n\t\t\t\t      pjsip_hdr *res_hdr,\n\t\t\t\t      pjsip_msg_body **p_body);\nstatic void pres_on_evsub_rx_notify( pjsip_evsub *sub, \n\t\t\t\t     pjsip_rx_data *rdata,\n\t\t\t\t     int *p_st_code,\n\t\t\t\t     pj_str_t **p_st_text,\n\t\t\t\t     pjsip_hdr *res_hdr,\n\t\t\t\t     pjsip_msg_body **p_body);\nstatic void pres_on_evsub_client_refresh(pjsip_evsub *sub);\nstatic void pres_on_evsub_server_timeout(pjsip_evsub *sub);\n\n\n/*\n * Event subscription callback for presence.\n */\nstatic pjsip_evsub_user pres_user = \n{\n    &pres_on_evsub_state,\n    &pres_on_evsub_tsx_state,\n    &pres_on_evsub_rx_refresh,\n    &pres_on_evsub_rx_notify,\n    &pres_on_evsub_client_refresh,\n    &pres_on_evsub_server_timeout,\n};\n\n\n/*\n * Some static constants.\n */\nstatic const pj_str_t STR_EVENT\t    = { \"Event\", 5 };\nstatic const pj_str_t STR_PRESENCE\t    = { \"presence\", 8 };\nstatic const pj_str_t STR_APPLICATION\t    = { \"application\", 11 };\nstatic const pj_str_t STR_PIDF_XML\t    = { \"pidf+xml\", 8};\nstatic const pj_str_t STR_XPIDF_XML\t    = { \"xpidf+xml\", 9};\nstatic const pj_str_t STR_APP_PIDF_XML\t    = { \"application/pidf+xml\", 20 };\nstatic const pj_str_t STR_APP_XPIDF_XML    = { \"application/xpidf+xml\", 21 };\n\n\n/*\n * Init presence module.\n */\nPJ_DEF(pj_status_t) pjsip_pres_init_module( pjsip_endpoint *endpt,\n\t\t\t\t\t    pjsip_module *mod_evsub)\n{\n    pj_status_t status;\n    pj_str_t accept[2];\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(endpt && mod_evsub, PJ_EINVAL);\n\n    /* Must have not been registered */\n    PJ_ASSERT_RETURN(mod_presence.id == -1, PJ_EINVALIDOP);\n\n    /* Register to endpoint */\n    status = pjsip_endpt_register_module(endpt, &mod_presence);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    accept[0] = STR_APP_PIDF_XML;\n    accept[1] = STR_APP_XPIDF_XML;\n\n    /* Register event package to event module. */\n    status = pjsip_evsub_register_pkg( &mod_presence, &STR_PRESENCE, \n\t\t\t\t       PRES_DEFAULT_EXPIRES, \n\t\t\t\t       PJ_ARRAY_SIZE(accept), accept);\n    if (status != PJ_SUCCESS) {\n\tpjsip_endpt_unregister_module(endpt, &mod_presence);\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Get presence module instance.\n */\nPJ_DEF(pjsip_module*) pjsip_pres_instance(void)\n{\n    return &mod_presence;\n}\n\n\n/*\n * Create client subscription.\n */\nPJ_DEF(pj_status_t) pjsip_pres_create_uac( pjsip_dialog *dlg,\n\t\t\t\t\t   const pjsip_evsub_user *user_cb,\n\t\t\t\t\t   unsigned options,\n\t\t\t\t\t   pjsip_evsub **p_evsub )\n{\n    pj_status_t status;\n    pjsip_pres *pres;\n    char obj_name[PJ_MAX_OBJ_NAME];\n    pjsip_evsub *sub;\n\n    PJ_ASSERT_RETURN(dlg && p_evsub, PJ_EINVAL);\n\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Create event subscription */\n    status = pjsip_evsub_create_uac( dlg,  &pres_user, &STR_PRESENCE, \n\t\t\t\t     options, &sub);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Create presence */\n    pres = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_pres);\n    pres->dlg = dlg;\n    pres->sub = sub;\n    if (user_cb)\n\tpj_memcpy(&pres->user_cb, user_cb, sizeof(pjsip_evsub_user));\n\n    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, \"pres%p\", dlg->pool);\n    pres->status_pool = pj_pool_create(dlg->pool->factory, obj_name, \n\t\t\t\t       512, 512, NULL);\n    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, \"tmpres%p\", dlg->pool);\n    pres->tmp_pool = pj_pool_create(dlg->pool->factory, obj_name, \n\t\t\t\t    512, 512, NULL);\n\n    /* Attach to evsub */\n    pjsip_evsub_set_mod_data(sub, mod_presence.id, pres);\n\n    *p_evsub = sub;\n\non_return:\n    pjsip_dlg_dec_lock(dlg);\n    return status;\n}\n\n\n/*\n * Create server subscription.\n */\nPJ_DEF(pj_status_t) pjsip_pres_create_uas( pjsip_dialog *dlg,\n\t\t\t\t\t   const pjsip_evsub_user *user_cb,\n\t\t\t\t\t   pjsip_rx_data *rdata,\n\t\t\t\t\t   pjsip_evsub **p_evsub )\n{\n    pjsip_accept_hdr *accept;\n    pjsip_event_hdr *event;\n    content_type_e content_type = CONTENT_TYPE_NONE;\n    pjsip_evsub *sub;\n    pjsip_pres *pres;\n    char obj_name[PJ_MAX_OBJ_NAME];\n    pj_status_t status;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(dlg && rdata && p_evsub, PJ_EINVAL);\n\n    /* Must be request message */\n    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,\n\t\t     PJSIP_ENOTREQUESTMSG);\n\n    /* Check that request is SUBSCRIBE */\n    PJ_ASSERT_RETURN(pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,\n\t\t\t\t      &pjsip_subscribe_method)==0,\n\t\t     PJSIP_SIMPLE_ENOTSUBSCRIBE);\n\n    /* Check that Event header contains \"presence\" */\n    event = (pjsip_event_hdr*)\n    \t    pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &STR_EVENT, NULL);\n    if (!event) {\n\treturn PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);\n    }\n    if (pj_stricmp(&event->event_type, &STR_PRESENCE) != 0) {\n\treturn PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_EVENT);\n    }\n\n    /* Check that request contains compatible Accept header. */\n    accept = (pjsip_accept_hdr*)\n    \t     pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, NULL);\n    if (accept) {\n\tunsigned i;\n\tfor (i=0; i<accept->count; ++i) {\n\t    if (pj_stricmp(&accept->values[i], &STR_APP_PIDF_XML)==0) {\n\t\tcontent_type = CONTENT_TYPE_PIDF;\n\t\tbreak;\n\t    } else\n\t    if (pj_stricmp(&accept->values[i], &STR_APP_XPIDF_XML)==0) {\n\t\tcontent_type = CONTENT_TYPE_XPIDF;\n\t\tbreak;\n\t    }\n\t}\n\n\tif (i==accept->count) {\n\t    /* Nothing is acceptable */\n\t    return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE);\n\t}\n\n    } else {\n\t/* No Accept header.\n\t * Treat as \"application/pidf+xml\"\n\t */\n\tcontent_type = CONTENT_TYPE_PIDF;\n    }\n\n    /* Lock dialog */\n    pjsip_dlg_inc_lock(dlg);\n\n\n    /* Create server subscription */\n    status = pjsip_evsub_create_uas( dlg, &pres_user, rdata, 0, &sub);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Create server presence subscription */\n    pres = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_pres);\n    pres->dlg = dlg;\n    pres->sub = sub;\n    pres->content_type = content_type;\n    if (user_cb)\n\tpj_memcpy(&pres->user_cb, user_cb, sizeof(pjsip_evsub_user));\n\n    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, \"pres%p\", dlg->pool);\n    pres->status_pool = pj_pool_create(dlg->pool->factory, obj_name, \n\t\t\t\t       512, 512, NULL);\n    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, \"tmpres%p\", dlg->pool);\n    pres->tmp_pool = pj_pool_create(dlg->pool->factory, obj_name, \n\t\t\t\t    512, 512, NULL);\n\n    /* Attach to evsub */\n    pjsip_evsub_set_mod_data(sub, mod_presence.id, pres);\n\n    /* Done: */\n    *p_evsub = sub;\n\non_return:\n    pjsip_dlg_dec_lock(dlg);\n    return status;\n}\n\n\n/*\n * Forcefully terminate presence.\n */\nPJ_DEF(pj_status_t) pjsip_pres_terminate( pjsip_evsub *sub,\n\t\t\t\t\t  pj_bool_t notify )\n{\n    return pjsip_evsub_terminate(sub, notify);\n}\n\n/*\n * Create SUBSCRIBE\n */\nPJ_DEF(pj_status_t) pjsip_pres_initiate( pjsip_evsub *sub,\n\t\t\t\t\t pj_int32_t expires,\n\t\t\t\t\t pjsip_tx_data **p_tdata)\n{\n    return pjsip_evsub_initiate(sub, &pjsip_subscribe_method, expires, \n\t\t\t\tp_tdata);\n}\n\n\n/*\n * Add custom headers.\n */\nPJ_DEF(pj_status_t) pjsip_pres_add_header( pjsip_evsub *sub,\n\t\t\t\t\t   const pjsip_hdr *hdr_list )\n{\n    return pjsip_evsub_add_header( sub, hdr_list );\n}\n\n\n/*\n * Accept incoming subscription.\n */\nPJ_DEF(pj_status_t) pjsip_pres_accept( pjsip_evsub *sub,\n\t\t\t\t       pjsip_rx_data *rdata,\n\t\t\t\t       int st_code,\n\t\t\t\t       const pjsip_hdr *hdr_list )\n{\n    return pjsip_evsub_accept( sub, rdata, st_code, hdr_list );\n}\n\n\n/*\n * Get presence status.\n */\nPJ_DEF(pj_status_t) pjsip_pres_get_status( pjsip_evsub *sub,\n\t\t\t\t\t   pjsip_pres_status *status )\n{\n    pjsip_pres *pres;\n\n    PJ_ASSERT_RETURN(sub && status, PJ_EINVAL);\n\n    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);\n    PJ_ASSERT_RETURN(pres!=NULL, PJSIP_SIMPLE_ENOPRESENCE);\n\n    if (pres->tmp_status._is_valid) {\n\tPJ_ASSERT_RETURN(pres->tmp_pool!=NULL, PJSIP_SIMPLE_ENOPRESENCE);\n\tpj_memcpy(status, &pres->tmp_status, sizeof(pjsip_pres_status));\n    } else {\n\tPJ_ASSERT_RETURN(pres->status_pool!=NULL, PJSIP_SIMPLE_ENOPRESENCE);\n\tpj_memcpy(status, &pres->status, sizeof(pjsip_pres_status));\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Set presence status.\n */\nPJ_DEF(pj_status_t) pjsip_pres_set_status( pjsip_evsub *sub,\n\t\t\t\t\t   const pjsip_pres_status *status )\n{\n    unsigned i;\n    pj_pool_t *tmp;\n    pjsip_pres *pres;\n\n    PJ_ASSERT_RETURN(sub && status, PJ_EINVAL);\n\n    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);\n    PJ_ASSERT_RETURN(pres!=NULL, PJSIP_SIMPLE_ENOPRESENCE);\n\n    for (i=0; i<status->info_cnt; ++i) {\n\tpres->status.info[i].basic_open = status->info[i].basic_open;\n\tif (pres->status.info[i].id.slen) {\n\t    /* Id already set */\n\t} else if (status->info[i].id.slen == 0) {\n\t    pj_create_unique_string(pres->dlg->pool, \n\t    \t\t\t    &pres->status.info[i].id);\n\t} else {\n\t    pj_strdup(pres->dlg->pool, \n\t\t      &pres->status.info[i].id,\n\t\t      &status->info[i].id);\n\t}\n\tpj_strdup(pres->tmp_pool, \n\t\t  &pres->status.info[i].contact,\n\t\t  &status->info[i].contact);\n\n\t/* Duplicate <person> */\n\tpres->status.info[i].rpid.activity = \n\t    status->info[i].rpid.activity;\n\tpj_strdup(pres->tmp_pool, \n\t\t  &pres->status.info[i].rpid.id,\n\t\t  &status->info[i].rpid.id);\n\tpj_strdup(pres->tmp_pool,\n\t\t  &pres->status.info[i].rpid.note,\n\t\t  &status->info[i].rpid.note);\n\n    }\n\n    pres->status.info_cnt = status->info_cnt;\n\n    /* Swap pools */\n    tmp = pres->tmp_pool;\n    pres->tmp_pool = pres->status_pool;\n    pres->status_pool = tmp;\n    pj_pool_reset(pres->tmp_pool);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create message body.\n */\nstatic pj_status_t pres_create_msg_body( pjsip_pres *pres, \n\t\t\t\t\t pjsip_tx_data *tdata)\n{\n    pj_str_t entity;\n\n    /* Get publisher URI */\n    entity.ptr = (char*) pj_pool_alloc(tdata->pool, PJSIP_MAX_URL_SIZE);\n    entity.slen = pjsip_uri_print(PJSIP_URI_IN_REQ_URI,\n\t\t\t\t  pres->dlg->local.info->uri,\n\t\t\t\t  entity.ptr, PJSIP_MAX_URL_SIZE);\n    if (entity.slen < 1)\n\treturn PJ_ENOMEM;\n\n    if (pres->content_type == CONTENT_TYPE_PIDF) {\n\n\treturn pjsip_pres_create_pidf(tdata->pool, &pres->status,\n\t\t\t\t      &entity, &tdata->msg->body);\n\n    } else if (pres->content_type == CONTENT_TYPE_XPIDF) {\n\n\treturn pjsip_pres_create_xpidf(tdata->pool, &pres->status,\n\t\t\t\t       &entity, &tdata->msg->body);\n\n    } else {\n\treturn PJSIP_SIMPLE_EBADCONTENT;\n    }\n}\n\n\n/*\n * Create NOTIFY\n */\nPJ_DEF(pj_status_t) pjsip_pres_notify( pjsip_evsub *sub,\n\t\t\t\t       pjsip_evsub_state state,\n\t\t\t\t       const pj_str_t *state_str,\n\t\t\t\t       const pj_str_t *reason,\n\t\t\t\t       pjsip_tx_data **p_tdata)\n{\n    pjsip_pres *pres;\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n    \n    /* Check arguments. */\n    PJ_ASSERT_RETURN(sub, PJ_EINVAL);\n\n    /* Get the presence object. */\n    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);\n    PJ_ASSERT_RETURN(pres != NULL, PJSIP_SIMPLE_ENOPRESENCE);\n\n    /* Must have at least one presence info, unless state is \n     * PJSIP_EVSUB_STATE_TERMINATED. This could happen if subscription\n     * has not been active (e.g. we're waiting for user authorization)\n     * and remote cancels the subscription.\n     */\n    PJ_ASSERT_RETURN(state==PJSIP_EVSUB_STATE_TERMINATED ||\n\t\t     pres->status.info_cnt > 0, PJSIP_SIMPLE_ENOPRESENCEINFO);\n\n\n    /* Lock object. */\n    pjsip_dlg_inc_lock(pres->dlg);\n\n    /* Create the NOTIFY request. */\n    status = pjsip_evsub_notify( sub, state, state_str, reason, &tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n\n    /* Create message body to reflect the presence status. \n     * Only do this if we have presence status info to send (see above).\n     */\n    if (pres->status.info_cnt > 0) {\n\tstatus = pres_create_msg_body( pres, tdata );\n\tif (status != PJ_SUCCESS)\n\t    goto on_return;\n    }\n\n    /* Done. */\n    *p_tdata = tdata;\n\n\non_return:\n    pjsip_dlg_dec_lock(pres->dlg);\n    return status;\n}\n\n\n/*\n * Create NOTIFY that reflect current state.\n */\nPJ_DEF(pj_status_t) pjsip_pres_current_notify( pjsip_evsub *sub,\n\t\t\t\t\t       pjsip_tx_data **p_tdata )\n{\n    pjsip_pres *pres;\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n    \n    /* Check arguments. */\n    PJ_ASSERT_RETURN(sub, PJ_EINVAL);\n\n    /* Get the presence object. */\n    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);\n    PJ_ASSERT_RETURN(pres != NULL, PJSIP_SIMPLE_ENOPRESENCE);\n\n    /* We may not have a presence info yet, e.g. when we receive SUBSCRIBE\n     * to refresh subscription while we're waiting for user authorization.\n     */\n    //PJ_ASSERT_RETURN(pres->status.info_cnt > 0, \n    //\t\t       PJSIP_SIMPLE_ENOPRESENCEINFO);\n\n\n    /* Lock object. */\n    pjsip_dlg_inc_lock(pres->dlg);\n\n    /* Create the NOTIFY request. */\n    status = pjsip_evsub_current_notify( sub, &tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n\n    /* Create message body to reflect the presence status. */\n    if (pres->status.info_cnt > 0) {\n\tstatus = pres_create_msg_body( pres, tdata );\n\tif (status != PJ_SUCCESS)\n\t    goto on_return;\n    }\n\n    /* Done. */\n    *p_tdata = tdata;\n\n\non_return:\n    pjsip_dlg_dec_lock(pres->dlg);\n    return status;\n}\n\n\n/*\n * Send request.\n */\nPJ_DEF(pj_status_t) pjsip_pres_send_request( pjsip_evsub *sub,\n\t\t\t\t\t     pjsip_tx_data *tdata )\n{\n    return pjsip_evsub_send_request(sub, tdata);\n}\n\n\n/*\n * This callback is called by event subscription when subscription\n * state has changed.\n */\nstatic void pres_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)\n{\n    pjsip_pres *pres;\n\n    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);\n    PJ_ASSERT_ON_FAIL(pres!=NULL, {return;});\n\n    if (pres->user_cb.on_evsub_state)\n\t(*pres->user_cb.on_evsub_state)(sub, event);\n\n    if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {\n\tif (pres->status_pool) {\n\t    pj_pool_release(pres->status_pool);\n\t    pres->status_pool = NULL;\n\t}\n\tif (pres->tmp_pool) {\n\t    pj_pool_release(pres->tmp_pool);\n\t    pres->tmp_pool = NULL;\n\t}\n    }\n}\n\n/*\n * Called when transaction state has changed.\n */\nstatic void pres_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,\n\t\t\t\t     pjsip_event *event)\n{\n    pjsip_pres *pres;\n\n    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);\n    PJ_ASSERT_ON_FAIL(pres!=NULL, {return;});\n\n    if (pres->user_cb.on_tsx_state)\n\t(*pres->user_cb.on_tsx_state)(sub, tsx, event);\n}\n\n\n/*\n * Called when SUBSCRIBE is received.\n */\nstatic void pres_on_evsub_rx_refresh( pjsip_evsub *sub, \n\t\t\t\t      pjsip_rx_data *rdata,\n\t\t\t\t      int *p_st_code,\n\t\t\t\t      pj_str_t **p_st_text,\n\t\t\t\t      pjsip_hdr *res_hdr,\n\t\t\t\t      pjsip_msg_body **p_body)\n{\n    pjsip_pres *pres;\n\n    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);\n    PJ_ASSERT_ON_FAIL(pres!=NULL, {return;});\n\n    if (pres->user_cb.on_rx_refresh) {\n\t(*pres->user_cb.on_rx_refresh)(sub, rdata, p_st_code, p_st_text,\n\t\t\t\t       res_hdr, p_body);\n\n    } else {\n\t/* Implementors MUST send NOTIFY if it implements on_rx_refresh */\n\tpjsip_tx_data *tdata;\n\tpj_str_t timeout = { \"timeout\", 7};\n\tpj_status_t status;\n\n\tif (pjsip_evsub_get_state(sub)==PJSIP_EVSUB_STATE_TERMINATED) {\n\t    status = pjsip_pres_notify( sub, PJSIP_EVSUB_STATE_TERMINATED,\n\t\t\t\t\tNULL, &timeout, &tdata);\n\t} else {\n\t    status = pjsip_pres_current_notify(sub, &tdata);\n\t}\n\n\tif (status == PJ_SUCCESS)\n\t    pjsip_pres_send_request(sub, tdata);\n    }\n}\n\n\n/*\n * Process the content of incoming NOTIFY request and update temporary\n * status.\n *\n * return PJ_SUCCESS if incoming request is acceptable. If return value\n *\t  is not PJ_SUCCESS, res_hdr may be added with Warning header.\n */\nstatic pj_status_t pres_process_rx_notify( pjsip_pres *pres,\n\t\t\t\t\t   pjsip_rx_data *rdata, \n\t\t\t\t\t   int *p_st_code,\n\t\t\t\t\t   pj_str_t **p_st_text,\n\t\t\t\t\t   pjsip_hdr *res_hdr)\n{\n    const pj_str_t STR_MULTIPART = { \"multipart\", 9 };\n    pjsip_ctype_hdr *ctype_hdr;\n    pj_status_t status = PJ_SUCCESS;\n\n    *p_st_text = NULL;\n\n    /* Check Content-Type and msg body are present. */\n    ctype_hdr = rdata->msg_info.ctype;\n\n    if (ctype_hdr==NULL || rdata->msg_info.msg->body==NULL) {\n\t\n\tpjsip_warning_hdr *warn_hdr;\n\tpj_str_t warn_text;\n\n\t*p_st_code = PJSIP_SC_BAD_REQUEST;\n\n\twarn_text = pj_str(\"Message body is not present\");\n\twarn_hdr = pjsip_warning_hdr_create(rdata->tp_info.pool, 399,\n\t\t\t\t\t    pjsip_endpt_name(pres->dlg->endpt),\n\t\t\t\t\t    &warn_text);\n\tpj_list_push_back(res_hdr, warn_hdr);\n\n\treturn PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);\n    }\n\n    /* Parse content. */\n    if (pj_stricmp(&ctype_hdr->media.type, &STR_MULTIPART)==0) {\n\tpjsip_multipart_part *mpart;\n\tpjsip_media_type ctype;\n\n\tpjsip_media_type_init(&ctype, (pj_str_t*)&STR_APPLICATION,\n\t\t\t      (pj_str_t*)&STR_PIDF_XML);\n\tmpart = pjsip_multipart_find_part(rdata->msg_info.msg->body,\n\t\t\t\t\t  &ctype, NULL);\n\tif (mpart) {\n\t    status = pjsip_pres_parse_pidf2((char*)mpart->body->data,\n\t\t\t\t\t    mpart->body->len, pres->tmp_pool,\n\t\t\t\t\t    &pres->tmp_status);\n\t}\n\n\tif (mpart==NULL) {\n\t    pjsip_media_type_init(&ctype, (pj_str_t*)&STR_APPLICATION,\n\t\t\t\t  (pj_str_t*)&STR_XPIDF_XML);\n\t    mpart = pjsip_multipart_find_part(rdata->msg_info.msg->body,\n\t\t\t\t\t      &ctype, NULL);\n\t    if (mpart) {\n\t\tstatus = pjsip_pres_parse_xpidf2((char*)mpart->body->data,\n\t\t\t\t\t\t mpart->body->len,\n\t\t\t\t\t\t pres->tmp_pool,\n\t\t\t\t\t\t &pres->tmp_status);\n\t    } else {\n\t\tstatus = PJSIP_SIMPLE_EBADCONTENT;\n\t    }\n\t}\n    }\n    else\n    if (pj_stricmp(&ctype_hdr->media.type, &STR_APPLICATION)==0 &&\n\tpj_stricmp(&ctype_hdr->media.subtype, &STR_PIDF_XML)==0)\n    {\n\tstatus = pjsip_pres_parse_pidf( rdata, pres->tmp_pool,\n\t\t\t\t\t&pres->tmp_status);\n    }\n    else \n    if (pj_stricmp(&ctype_hdr->media.type, &STR_APPLICATION)==0 &&\n\tpj_stricmp(&ctype_hdr->media.subtype, &STR_XPIDF_XML)==0)\n    {\n\tstatus = pjsip_pres_parse_xpidf( rdata, pres->tmp_pool,\n\t\t\t\t\t &pres->tmp_status);\n    }\n    else\n    {\n\tstatus = PJSIP_SIMPLE_EBADCONTENT;\n    }\n\n    if (status != PJ_SUCCESS) {\n\t/* Unsupported or bad Content-Type */\n\tif (PJSIP_PRES_BAD_CONTENT_RESPONSE >= 300) {\n\t    pjsip_accept_hdr *accept_hdr;\n\t    pjsip_warning_hdr *warn_hdr;\n\n\t    *p_st_code = PJSIP_PRES_BAD_CONTENT_RESPONSE;\n\n\t    /* Add Accept header */\n\t    accept_hdr = pjsip_accept_hdr_create(rdata->tp_info.pool);\n\t    accept_hdr->values[accept_hdr->count++] = STR_APP_PIDF_XML;\n\t    accept_hdr->values[accept_hdr->count++] = STR_APP_XPIDF_XML;\n\t    pj_list_push_back(res_hdr, accept_hdr);\n\n\t    /* Add Warning header */\n\t    warn_hdr = pjsip_warning_hdr_create_from_status(\n\t\t\t\t\trdata->tp_info.pool,\n\t\t\t\t\tpjsip_endpt_name(pres->dlg->endpt),\n\t\t\t\t\tstatus);\n\t    pj_list_push_back(res_hdr, warn_hdr);\n\n\t    return status;\n\t} else {\n\t    pj_assert(PJSIP_PRES_BAD_CONTENT_RESPONSE/100 == 2);\n\t    PJ_PERROR(4,(THIS_FILE, status,\n\t\t\t \"Ignoring presence error due to \"\n\t\t         \"PJSIP_PRES_BAD_CONTENT_RESPONSE setting [%d]\",\n\t\t         PJSIP_PRES_BAD_CONTENT_RESPONSE));\n\t    *p_st_code = PJSIP_PRES_BAD_CONTENT_RESPONSE;\n\t    status = PJ_SUCCESS;\n\t}\n    }\n\n    /* If application calls pres_get_status(), redirect the call to\n     * retrieve the temporary status.\n     */\n    pres->tmp_status._is_valid = PJ_TRUE;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Called when NOTIFY is received.\n */\nstatic void pres_on_evsub_rx_notify( pjsip_evsub *sub, \n\t\t\t\t     pjsip_rx_data *rdata,\n\t\t\t\t     int *p_st_code,\n\t\t\t\t     pj_str_t **p_st_text,\n\t\t\t\t     pjsip_hdr *res_hdr,\n\t\t\t\t     pjsip_msg_body **p_body)\n{\n    pjsip_pres *pres;\n    pj_status_t status;\n\n    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);\n    PJ_ASSERT_ON_FAIL(pres!=NULL, {return;});\n\n    if (rdata->msg_info.msg->body) {\n\tstatus = pres_process_rx_notify( pres, rdata, p_st_code, p_st_text,\n\t\t\t\t\t res_hdr );\n\tif (status != PJ_SUCCESS)\n\t    return;\n\n    } else {\n#if 1\n\t/* This is the newest change, http://trac.pjsip.org/repos/ticket/873\n\t * Some app want to be notified about the empty NOTIFY, e.g. to \n\t * decide whether it should consider the buddy as offline.\n\t * In this case, leave the buddy state unchanged, but set the\n\t * \"tuple_node\" in pjsip_pres_status to NULL.\n\t */\n\tunsigned i;\n\tfor (i=0; i<pres->status.info_cnt; ++i) {\n\t    pres->status.info[i].tuple_node = NULL;\n\t}\n\n#elif 0\n\t/* This has just been changed. Previously, we treat incoming NOTIFY\n\t * with no message body as having the presence subscription closed.\n\t * Now we treat it as no change in presence status (ref: EyeBeam).\n\t */\n\t*p_st_code = 200;\n\treturn;\n#else\n\tunsigned i;\n\t/* Subscription is terminated. Consider contact is offline */\n\tpres->tmp_status._is_valid = PJ_TRUE;\n\tfor (i=0; i<pres->tmp_status.info_cnt; ++i)\n\t    pres->tmp_status.info[i].basic_open = PJ_FALSE;\n#endif\n    }\n\n    /* Notify application. */\n    if (pres->user_cb.on_rx_notify) {\n\t(*pres->user_cb.on_rx_notify)(sub, rdata, p_st_code, p_st_text, \n\t\t\t\t      res_hdr, p_body);\n    }\n\n    \n    /* If application responded NOTIFY with 2xx, copy temporary status\n     * to main status, and mark the temporary status as invalid.\n     */\n    if ((*p_st_code)/100 == 2) {\n\tpj_pool_t *tmp;\n\n\tpj_memcpy(&pres->status, &pres->tmp_status, sizeof(pjsip_pres_status));\n\n\t/* Swap the pool */\n\ttmp = pres->tmp_pool;\n\tpres->tmp_pool = pres->status_pool;\n\tpres->status_pool = tmp;\n    }\n\n    pres->tmp_status._is_valid = PJ_FALSE;\n    pj_pool_reset(pres->tmp_pool);\n\n    /* Done */\n}\n\n/*\n * Called when it's time to send SUBSCRIBE.\n */\nstatic void pres_on_evsub_client_refresh(pjsip_evsub *sub)\n{\n    pjsip_pres *pres;\n\n    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);\n    PJ_ASSERT_ON_FAIL(pres!=NULL, {return;});\n\n    if (pres->user_cb.on_client_refresh) {\n\t(*pres->user_cb.on_client_refresh)(sub);\n    } else {\n\tpj_status_t status;\n\tpjsip_tx_data *tdata;\n\n\tstatus = pjsip_pres_initiate(sub, -1, &tdata);\n\tif (status == PJ_SUCCESS)\n\t    pjsip_pres_send_request(sub, tdata);\n    }\n}\n\n/*\n * Called when no refresh is received after the interval.\n */\nstatic void pres_on_evsub_server_timeout(pjsip_evsub *sub)\n{\n    pjsip_pres *pres;\n\n    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);\n    PJ_ASSERT_ON_FAIL(pres!=NULL, {return;});\n\n    if (pres->user_cb.on_server_timeout) {\n\t(*pres->user_cb.on_server_timeout)(sub);\n    } else {\n\tpj_status_t status;\n\tpjsip_tx_data *tdata;\n\tpj_str_t reason = { \"timeout\", 7 };\n\n\tstatus = pjsip_pres_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,\n\t\t\t\t   NULL, &reason, &tdata);\n\tif (status == PJ_SUCCESS)\n\t    pjsip_pres_send_request(sub, tdata);\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-simple/presence_body.c",
    "content": "/* $Id: presence_body.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-simple/presence.h>\n#include <pjsip-simple/errno.h>\n#include <pjsip/sip_msg.h>\n#include <pjsip/sip_transport.h>\n#include <pj/guid.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\n#define THIS_FILE   \"presence_body.c\"\n\n\nstatic const pj_str_t STR_APPLICATION = { \"application\", 11 };\nstatic const pj_str_t STR_PIDF_XML =\t{ \"pidf+xml\", 8 };\nstatic const pj_str_t STR_XPIDF_XML =\t{ \"xpidf+xml\", 9 };\n\n\n\n\n/*\n * Function to print XML message body.\n */\nstatic int pres_print_body(struct pjsip_msg_body *msg_body, \n\t\t\t   char *buf, pj_size_t size)\n{\n    return pj_xml_print((const pj_xml_node*)msg_body->data, buf, size, \n    \t\t\tPJ_TRUE);\n}\n\n\n/*\n * Function to clone XML document.\n */\nstatic void* xml_clone_data(pj_pool_t *pool, const void *data, unsigned len)\n{\n    PJ_UNUSED_ARG(len);\n    return pj_xml_clone( pool, (const pj_xml_node*) data);\n}\n\n\n/*\n * This is a utility function to create PIDF message body from PJSIP\n * presence status (pjsip_pres_status).\n */\nPJ_DEF(pj_status_t) pjsip_pres_create_pidf( pj_pool_t *pool,\n\t\t\t\t\t    const pjsip_pres_status *status,\n\t\t\t\t\t    const pj_str_t *entity,\n\t\t\t\t\t    pjsip_msg_body **p_body )\n{\n    pjpidf_pres *pidf;\n    pjsip_msg_body *body;\n    unsigned i;\n\n    /* Create <presence>. */\n    pidf = pjpidf_create(pool, entity);\n\n    /* Create <tuple> */\n    for (i=0; i<status->info_cnt; ++i) {\n\n\tpjpidf_tuple *pidf_tuple;\n\tpjpidf_status *pidf_status;\n\tpj_str_t id;\n\n\t/* Add tuple id. */\n\tif (status->info[i].id.slen == 0) {\n\t    /* xs:ID must start with letter */\n\t    //pj_create_unique_string(pool, &id);\n\t    id.ptr = (char*)pj_pool_alloc(pool, PJ_GUID_STRING_LENGTH+2);\n\t    id.ptr += 2;\n\t    pj_generate_unique_string(&id);\n\t    id.ptr -= 2;\n\t    id.ptr[0] = 'p';\n\t    id.ptr[1] = 'j';\n\t    id.slen += 2;\n\t} else {\n\t    id = status->info[i].id;\n\t}\n\n\tpidf_tuple = pjpidf_pres_add_tuple(pool, pidf, &id);\n\n\t/* Set <contact> */\n\tif (status->info[i].contact.slen)\n\t    pjpidf_tuple_set_contact(pool, pidf_tuple, \n\t\t\t\t     &status->info[i].contact);\n\n\n\t/* Set basic status */\n\tpidf_status = pjpidf_tuple_get_status(pidf_tuple);\n\tpjpidf_status_set_basic_open(pidf_status, \n\t\t\t\t     status->info[i].basic_open);\n\n\t/* Add <timestamp> if configured */\n#if defined(PJSIP_PRES_PIDF_ADD_TIMESTAMP) && PJSIP_PRES_PIDF_ADD_TIMESTAMP\n\tif (PJSIP_PRES_PIDF_ADD_TIMESTAMP) {\n\t  char buf[50];\n\t  int tslen = 0;\n\t  pj_time_val tv;\n\t  pj_parsed_time pt;\n\n\t  pj_gettimeofday(&tv);\n\t  /* TODO: convert time to GMT! (unsupported by pjlib) */\n\t  pj_time_decode( &tv, &pt);\n\n\t  tslen = pj_ansi_snprintf(buf, sizeof(buf),\n\t\t\t\t   \"%04d-%02d-%02dT%02d:%02d:%02d.%03dZ\",\n\t\t\t\t   pt.year, pt.mon+1, pt.day, \n\t\t\t\t   pt.hour, pt.min, pt.sec, pt.msec);\n\t  if (tslen > 0 && tslen < (int)sizeof(buf)) {\n\t      pj_str_t time = pj_str(buf);\n\t      pjpidf_tuple_set_timestamp(pool, pidf_tuple, &time);\n\t  }\n\t}\n#endif\n    }\n\n    /* Create <person> (RPID) */\n    if (status->info_cnt) {\n\tpjrpid_add_element(pidf, pool, 0, &status->info[0].rpid);\n    }\n\n    body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body);\n    body->data = pidf;\n    body->content_type.type = STR_APPLICATION;\n    body->content_type.subtype = STR_PIDF_XML;\n    body->print_body = &pres_print_body;\n    body->clone_data = &xml_clone_data;\n\n    *p_body = body;\n\n    return PJ_SUCCESS;    \n}\n\n\n/*\n * This is a utility function to create X-PIDF message body from PJSIP\n * presence status (pjsip_pres_status).\n */\nPJ_DEF(pj_status_t) pjsip_pres_create_xpidf( pj_pool_t *pool,\n\t\t\t\t\t     const pjsip_pres_status *status,\n\t\t\t\t\t     const pj_str_t *entity,\n\t\t\t\t\t     pjsip_msg_body **p_body )\n{\n    /* Note: PJSIP implementation of XPIDF is not complete!\n     */\n    pjxpidf_pres *xpidf;\n    pjsip_msg_body *body;\n\n    PJ_LOG(4,(THIS_FILE, \"Warning: XPIDF format is not fully supported \"\n\t\t\t \"by PJSIP\"));\n\n    /* Create XPIDF document. */\n    xpidf = pjxpidf_create(pool, entity);\n\n    /* Set basic status. */\n    if (status->info_cnt > 0)\n\tpjxpidf_set_status( xpidf, status->info[0].basic_open);\n    else\n\tpjxpidf_set_status( xpidf, PJ_FALSE);\n\n    body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body);\n    body->data = xpidf;\n    body->content_type.type = STR_APPLICATION;\n    body->content_type.subtype = STR_XPIDF_XML;\n    body->print_body = &pres_print_body;\n    body->clone_data = &xml_clone_data;\n\n    *p_body = body;\n\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * This is a utility function to parse PIDF body into PJSIP presence status.\n */\nPJ_DEF(pj_status_t) pjsip_pres_parse_pidf( pjsip_rx_data *rdata,\n\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t   pjsip_pres_status *pres_status)\n{\n    return pjsip_pres_parse_pidf2((char*)rdata->msg_info.msg->body->data,\n\t\t\t\t  rdata->msg_info.msg->body->len,\n\t\t\t\t  pool, pres_status);\n}\n\nPJ_DEF(pj_status_t) pjsip_pres_parse_pidf2(char *body, unsigned body_len,\n\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t   pjsip_pres_status *pres_status)\n{\n    pjpidf_pres *pidf;\n    pjpidf_tuple *pidf_tuple;\n\n    pidf = pjpidf_parse(pool, body, body_len);\n    if (pidf == NULL)\n\treturn PJSIP_SIMPLE_EBADPIDF;\n\n    pres_status->info_cnt = 0;\n\n    pidf_tuple = pjpidf_pres_get_first_tuple(pidf);\n    while (pidf_tuple && pres_status->info_cnt < PJSIP_PRES_STATUS_MAX_INFO) {\n\tpjpidf_status *pidf_status;\n\n\tpres_status->info[pres_status->info_cnt].tuple_node = \n\t    pj_xml_clone(pool, pidf_tuple);\n\n\tpj_strdup(pool, \n\t\t  &pres_status->info[pres_status->info_cnt].id,\n\t\t  pjpidf_tuple_get_id(pidf_tuple));\n\n\tpj_strdup(pool, \n\t\t  &pres_status->info[pres_status->info_cnt].contact,\n\t\t  pjpidf_tuple_get_contact(pidf_tuple));\n\n\tpidf_status = pjpidf_tuple_get_status(pidf_tuple);\n\tif (pidf_status) {\n\t    pres_status->info[pres_status->info_cnt].basic_open = \n\t\tpjpidf_status_is_basic_open(pidf_status);\n\t} else {\n\t    pres_status->info[pres_status->info_cnt].basic_open = PJ_FALSE;\n\t}\n\n\tpidf_tuple = pjpidf_pres_get_next_tuple( pidf, pidf_tuple );\n\tpres_status->info_cnt++;\n    }\n\n    /* Parse <person> (RPID) */\n    pjrpid_get_element(pidf, pool, &pres_status->info[0].rpid);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * This is a utility function to parse X-PIDF body into PJSIP presence status.\n */\nPJ_DEF(pj_status_t) pjsip_pres_parse_xpidf(pjsip_rx_data *rdata,\n\t\t\t\t\t   pj_pool_t *pool,\n\t\t\t\t\t   pjsip_pres_status *pres_status)\n{\n    return pjsip_pres_parse_xpidf2((char*)rdata->msg_info.msg->body->data,\n\t\t\t\t   rdata->msg_info.msg->body->len,\n\t\t\t\t   pool, pres_status);\n}\n\nPJ_DEF(pj_status_t) pjsip_pres_parse_xpidf2(char *body, unsigned body_len,\n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    pjsip_pres_status *pres_status)\n{\n    pjxpidf_pres *xpidf;\n\n    xpidf = pjxpidf_parse(pool, body, body_len);\n    if (xpidf == NULL)\n\treturn PJSIP_SIMPLE_EBADXPIDF;\n\n    pres_status->info_cnt = 1;\n    \n    pj_strdup(pool,\n\t      &pres_status->info[0].contact,\n\t      pjxpidf_get_uri(xpidf));\n    pres_status->info[0].basic_open = pjxpidf_get_status(xpidf);\n    pres_status->info[0].id.slen = 0;\n    pres_status->info[0].tuple_node = NULL;\n\n    return PJ_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-simple/publishc.c",
    "content": "/* $Id: publishc.c 4530 2013-05-30 09:27:49Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-simple/publish.h>\n#include <pjsip/sip_auth.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_event.h>\n#include <pjsip/sip_msg.h>\n#include <pjsip/sip_transaction.h>\n#include <pjsip/sip_uri.h>\n#include <pjsip/sip_util.h>\n#include <pj/assert.h>\n#include <pj/guid.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n#include <pj/timer.h>\n\n\n#define REFRESH_TIMER\t\t1\n#define DELAY_BEFORE_REFRESH\tPJSIP_PUBLISHC_DELAY_BEFORE_REFRESH\n#define THIS_FILE\t\t\"publishc.c\"\n\n\n/* Let's define this enum, so that it'll trigger compilation error\n * when somebody define the same enum in sip_msg.h\n */\nenum\n{\n    PJSIP_PUBLISH_METHOD = PJSIP_OTHER_METHOD,\n};\n\nconst pjsip_method pjsip_publish_method = \n{\n    (pjsip_method_e)PJSIP_PUBLISH_METHOD,\n    { \"PUBLISH\", 7 }\n};\n\n\n/**\n * Pending request list.\n */\ntypedef struct pending_publish\n{\n    PJ_DECL_LIST_MEMBER(struct pending_publish);\n    pjsip_tx_data\t\t*tdata;\n} pending_publish;\n\n\n/**\n * SIP client publication structure.\n */\nstruct pjsip_publishc\n{\n    pj_pool_t\t\t\t*pool;\n    pjsip_endpoint\t\t*endpt;\n    pj_bool_t\t\t\t _delete_flag;\n    int\t\t\t\t pending_tsx;\n    pj_bool_t\t\t\t in_callback;\n    pj_mutex_t\t\t\t*mutex;\n\n    pjsip_publishc_opt\t\t opt;\n    void\t\t\t*token;\n    pjsip_publishc_cb\t\t*cb;\n\n    pj_str_t\t\t\t event;\n    pj_str_t\t\t\t str_target_uri;\n    pjsip_uri\t\t\t*target_uri;\n    pjsip_cid_hdr\t\t*cid_hdr;\n    pjsip_cseq_hdr\t\t*cseq_hdr;\n    pj_str_t\t\t\t from_uri;\n    pjsip_from_hdr\t\t*from_hdr;\n    pjsip_to_hdr\t\t*to_hdr;\n    pj_str_t\t\t\t etag;\n    pjsip_expires_hdr\t\t*expires_hdr;\n    pj_uint32_t\t\t\t expires;\n    pjsip_route_hdr\t\t route_set;\n    pjsip_hdr\t\t\t usr_hdr;\n    pjsip_host_port              via_addr;\n    const void                  *via_tp;\n\n    /* Authorization sessions. */\n    pjsip_auth_clt_sess\t\t auth_sess;\n\n    /* Auto refresh publication. */\n    pj_bool_t\t\t\t auto_refresh;\n    pj_time_val\t\t\t last_refresh;\n    pj_time_val\t\t\t next_refresh;\n    pj_timer_entry\t\t timer;\n\n    /* Pending PUBLISH request */\n    pending_publish\t\t pending_reqs;\n    pending_publish\t\t pending_reqs_empty;\n};\n\n\nPJ_DEF(void) pjsip_publishc_opt_default(pjsip_publishc_opt *opt)\n{\n    pj_bzero(opt, sizeof(*opt));\n    opt->queue_request = PJSIP_PUBLISHC_QUEUE_REQUEST;\n}\n\n\n/*\n * Initialize client publication module.\n */\nPJ_DEF(pj_status_t) pjsip_publishc_init_module(pjsip_endpoint *endpt)\n{\n    /* Note:\n\tCommented out the capability registration below, since it's\n\twrong to include PUBLISH in Allow header of INVITE requests/\n\tresponses.\n\n\t13.2.1 Creating the Initial INVITE\n\t  An Allow header field (Section 20.5) SHOULD be present in the \n\t  INVITE. It indicates what methods can be invoked within a dialog\n\n\t20.5 Allow\n\t  The Allow header field lists the set of methods supported by the\n\t  UA generating the message.\n\n\tWhile the semantic of Allow header in non-dialog requests is unclear,\n\tit's probably best not to include PUBLISH in Allow header for now\n\tuntil we can find out how to customize the inclusion of methods in\n\tAllow header for in-dialog vs out-dialog requests.\n\n    return pjsip_endpt_add_capability( endpt, NULL, PJSIP_H_ALLOW, NULL,\n\t\t\t\t       1, &pjsip_publish_method.name);\n     */\n    PJ_UNUSED_ARG(endpt);\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_publishc_create( pjsip_endpoint *endpt, \n\t\t\t\t\t   const pjsip_publishc_opt *opt,\n\t\t\t\t\t   void *token,\n\t\t\t\t\t   pjsip_publishc_cb *cb,\t\n\t\t\t\t\t   pjsip_publishc **p_pubc)\n{\n    pj_pool_t *pool;\n    pjsip_publishc *pubc;\n    pjsip_publishc_opt default_opt;\n    pj_status_t status;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(endpt && cb && p_pubc, PJ_EINVAL);\n\n    pool = pjsip_endpt_create_pool(endpt, \"pubc%p\", 1024, 1024);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    pubc = PJ_POOL_ZALLOC_T(pool, pjsip_publishc);\n\n    pubc->pool = pool;\n    pubc->endpt = endpt;\n    pubc->token = token;\n    pubc->cb = cb;\n    pubc->expires = PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED;\n\n    if (!opt) {\n\tpjsip_publishc_opt_default(&default_opt);\n\topt = &default_opt;\n    }\n    pj_memcpy(&pubc->opt, opt, sizeof(*opt));\n    pj_list_init(&pubc->pending_reqs);\n    pj_list_init(&pubc->pending_reqs_empty);\n\n    status = pj_mutex_create_recursive(pubc->pool, \"pubc%p\", &pubc->mutex);\n    if (status != PJ_SUCCESS) {\n\tpj_pool_release(pool);\n\treturn status;\n    }\n\n    status = pjsip_auth_clt_init(&pubc->auth_sess, endpt, pubc->pool, 0);\n    if (status != PJ_SUCCESS) {\n\tpj_mutex_destroy(pubc->mutex);\n\tpj_pool_release(pool);\n\treturn status;\n    }\n\n    pj_list_init(&pubc->route_set);\n    pj_list_init(&pubc->usr_hdr);\n\n    /* Done */\n    *p_pubc = pubc;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_publishc_destroy(pjsip_publishc *pubc)\n{\n    PJ_ASSERT_RETURN(pubc, PJ_EINVAL);\n\n    if (pubc->pending_tsx || pubc->in_callback) {\n\tpubc->_delete_flag = 1;\n\tpubc->cb = NULL;\n    } else {\n\t/* Cancel existing timer, if any */\n\tif (pubc->timer.id != 0) {\n\t    pjsip_endpt_cancel_timer(pubc->endpt, &pubc->timer);\n\t    pubc->timer.id = 0;\n\t}\n\n\tif (pubc->mutex)\n\t    pj_mutex_destroy(pubc->mutex);\n\tpjsip_endpt_release_pool(pubc->endpt, pubc->pool);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_pool_t*) pjsip_publishc_get_pool(pjsip_publishc *pubc)\n{\n    return pubc->pool;\n}\n\nstatic void set_expires( pjsip_publishc *pubc, pj_uint32_t expires)\n{\n    if (expires != pubc->expires && \n\texpires != PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED) \n    {\n\tpubc->expires_hdr = pjsip_expires_hdr_create(pubc->pool, expires);\n    } else {\n\tpubc->expires_hdr = NULL;\n    }\n}\n\n\nPJ_DEF(pj_status_t) pjsip_publishc_init(pjsip_publishc *pubc,\n\t\t\t\t\tconst pj_str_t *event,\n\t\t\t\t\tconst pj_str_t *target_uri,\n\t\t\t\t\tconst pj_str_t *from_uri,\n\t\t\t\t\tconst pj_str_t *to_uri,\n\t\t\t\t\tpj_uint32_t expires)\n{\n    pj_str_t tmp;\n\n    PJ_ASSERT_RETURN(pubc && event && target_uri && from_uri && to_uri && \n\t\t     expires, PJ_EINVAL);\n\n    /* Copy event type */\n    pj_strdup_with_null(pubc->pool, &pubc->event, event);\n\n    /* Copy server URL. */\n    pj_strdup_with_null(pubc->pool, &pubc->str_target_uri, target_uri);\n\n    /* Set server URL. */\n    tmp = pubc->str_target_uri;\n    pubc->target_uri = pjsip_parse_uri( pubc->pool, tmp.ptr, tmp.slen, 0);\n    if (pubc->target_uri == NULL) {\n\treturn PJSIP_EINVALIDURI;\n    }\n\n    /* Set \"From\" header. */\n    pj_strdup_with_null(pubc->pool, &pubc->from_uri, from_uri);\n    tmp = pubc->from_uri;\n    pubc->from_hdr = pjsip_from_hdr_create(pubc->pool);\n    pubc->from_hdr->uri = pjsip_parse_uri(pubc->pool, tmp.ptr, tmp.slen, \n\t\t\t\t\t  PJSIP_PARSE_URI_AS_NAMEADDR);\n    if (!pubc->from_hdr->uri) {\n\treturn PJSIP_EINVALIDURI;\n    }\n\n    /* Set \"To\" header. */\n    pj_strdup_with_null(pubc->pool, &tmp, to_uri);\n    pubc->to_hdr = pjsip_to_hdr_create(pubc->pool);\n    pubc->to_hdr->uri = pjsip_parse_uri(pubc->pool, tmp.ptr, tmp.slen, \n\t\t\t\t\tPJSIP_PARSE_URI_AS_NAMEADDR);\n    if (!pubc->to_hdr->uri) {\n\treturn PJSIP_EINVALIDURI;\n    }\n\n\n    /* Set \"Expires\" header, if required. */\n    set_expires( pubc, expires);\n\n    /* Set \"Call-ID\" header. */\n    pubc->cid_hdr = pjsip_cid_hdr_create(pubc->pool);\n    pj_create_unique_string(pubc->pool, &pubc->cid_hdr->id);\n\n    /* Set \"CSeq\" header. */\n    pubc->cseq_hdr = pjsip_cseq_hdr_create(pubc->pool);\n    pubc->cseq_hdr->cseq = pj_rand() % 0xFFFF;\n    pjsip_method_set( &pubc->cseq_hdr->method, PJSIP_REGISTER_METHOD);\n\n    /* Done. */\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjsip_publishc_set_credentials( pjsip_publishc *pubc,\n\t\t\t\t\t\tint count,\n\t\t\t\t\t\tconst pjsip_cred_info cred[] )\n{\n    PJ_ASSERT_RETURN(pubc && count && cred, PJ_EINVAL);\n    return pjsip_auth_clt_set_credentials(&pubc->auth_sess, count, cred);\n}\n\nPJ_DEF(pj_status_t) pjsip_publishc_set_route_set( pjsip_publishc *pubc,\n\t\t\t\t\t      const pjsip_route_hdr *route_set)\n{\n    const pjsip_route_hdr *chdr;\n\n    PJ_ASSERT_RETURN(pubc && route_set, PJ_EINVAL);\n\n    pj_list_init(&pubc->route_set);\n\n    chdr = route_set->next;\n    while (chdr != route_set) {\n\tpj_list_push_back(&pubc->route_set, pjsip_hdr_clone(pubc->pool, chdr));\n\tchdr = chdr->next;\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjsip_publishc_set_headers( pjsip_publishc *pubc,\n\t\t\t\t\t\tconst pjsip_hdr *hdr_list)\n{\n    const pjsip_hdr *h;\n\n    PJ_ASSERT_RETURN(pubc && hdr_list, PJ_EINVAL);\n\n    pj_list_init(&pubc->usr_hdr);\n    h = hdr_list->next;\n    while (h != hdr_list) {\n\tpj_list_push_back(&pubc->usr_hdr, pjsip_hdr_clone(pubc->pool, h));\n\th = h->next;\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjsip_publishc_set_via_sent_by(pjsip_publishc *pubc,\n\t\t\t\t                   pjsip_host_port *via_addr,\n                                                   pjsip_transport *via_tp)\n{\n    PJ_ASSERT_RETURN(pubc, PJ_EINVAL);\n\n    if (!via_addr)\n        pj_bzero(&pubc->via_addr, sizeof(pubc->via_addr));\n    else {\n        if (pj_strcmp(&pubc->via_addr.host, &via_addr->host))\n            pj_strdup(pubc->pool, &pubc->via_addr.host, &via_addr->host);\n        pubc->via_addr.port = via_addr->port;\n    }\n    pubc->via_tp = via_tp;\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t create_request(pjsip_publishc *pubc, \n\t\t\t\t  pjsip_tx_data **p_tdata)\n{\n    const pj_str_t STR_EVENT = { \"Event\", 5 };\n    pj_status_t status;\n    pjsip_generic_string_hdr *hdr;\n    pjsip_tx_data *tdata;\n\n    PJ_ASSERT_RETURN(pubc && p_tdata, PJ_EINVAL);\n\n    /* Create the request. */\n    status = pjsip_endpt_create_request_from_hdr( pubc->endpt, \n\t\t\t\t\t\t  &pjsip_publish_method,\n\t\t\t\t\t\t  pubc->target_uri,\n\t\t\t\t\t\t  pubc->from_hdr,\n\t\t\t\t\t\t  pubc->to_hdr,\n\t\t\t\t\t\t  NULL,\n\t\t\t\t\t\t  pubc->cid_hdr,\n\t\t\t\t\t\t  pubc->cseq_hdr->cseq,\n\t\t\t\t\t\t  NULL,\n\t\t\t\t\t\t  &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Add cached authorization headers. */\n    pjsip_auth_clt_init_req( &pubc->auth_sess, tdata );\n\n    /* Add Route headers from route set, ideally after Via header */\n    if (!pj_list_empty(&pubc->route_set)) {\n\tpjsip_hdr *route_pos;\n\tconst pjsip_route_hdr *route;\n\n\troute_pos = (pjsip_hdr*)\n\t\t    pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);\n\tif (!route_pos)\n\t    route_pos = &tdata->msg->hdr;\n\n\troute = pubc->route_set.next;\n\twhile (route != &pubc->route_set) {\n\t    pjsip_hdr *new_hdr = (pjsip_hdr*)\n\t    \t\t\t pjsip_hdr_shallow_clone(tdata->pool, route);\n\t    pj_list_insert_after(route_pos, new_hdr);\n\t    route_pos = new_hdr;\n\t    route = route->next;\n\t}\n    }\n\n    /* Add Event header */\n    hdr = pjsip_generic_string_hdr_create(tdata->pool, &STR_EVENT,\n\t\t\t\t\t  &pubc->event);\n    if (hdr)\n\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);\n\n\n    /* Add SIP-If-Match if we have etag */\n    if (pubc->etag.slen) {\n\tconst pj_str_t STR_HNAME = { \"SIP-If-Match\", 12 };\n\n\thdr = pjsip_generic_string_hdr_create(tdata->pool, &STR_HNAME,\n\t\t\t\t\t      &pubc->etag);\n\tif (hdr)\n\t    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);\n    }\n\n    /* Add user headers */\n    if (!pj_list_empty(&pubc->usr_hdr)) {\n\tconst pjsip_hdr *uhdr;\n\n\tuhdr = pubc->usr_hdr.next;\n\twhile (uhdr != &pubc->usr_hdr) {\n\t    pjsip_hdr *new_hdr = (pjsip_hdr*)\n\t    \t\t\t pjsip_hdr_shallow_clone(tdata->pool, uhdr);\n\t    pjsip_msg_add_hdr(tdata->msg, new_hdr);\n\t    uhdr = uhdr->next;\n\t}\n    }\n\n\n    /* Done. */\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_publishc_publish(pjsip_publishc *pubc, \n\t\t\t\t\t   pj_bool_t auto_refresh,\n\t\t\t\t\t   pjsip_tx_data **p_tdata)\n{\n    pj_status_t status;\n    pjsip_tx_data *tdata;\n\n    PJ_ASSERT_RETURN(pubc && p_tdata, PJ_EINVAL);\n\n    status = create_request(pubc, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Add Expires header */\n    if (pubc->expires_hdr) {\n\tpjsip_hdr *dup;\n\n\tdup = (pjsip_hdr*)\n\t      pjsip_hdr_shallow_clone(tdata->pool, pubc->expires_hdr);\n\tif (dup)\n\t    pjsip_msg_add_hdr(tdata->msg, dup);\n    }\n\n    /* Cancel existing timer */\n    if (pubc->timer.id != 0) {\n\tpjsip_endpt_cancel_timer(pubc->endpt, &pubc->timer);\n\tpubc->timer.id = 0;\n    }\n\n    pubc->auto_refresh = auto_refresh;\n\n    /* Done */\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_publishc_unpublish(pjsip_publishc *pubc,\n\t\t\t\t\t     pjsip_tx_data **p_tdata)\n{\n    pjsip_tx_data *tdata;\n    pjsip_msg *msg;\n    pjsip_expires_hdr *expires;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pubc && p_tdata, PJ_EINVAL);\n\n    if (pubc->timer.id != 0) {\n\tpjsip_endpt_cancel_timer(pubc->endpt, &pubc->timer);\n\tpubc->timer.id = 0;\n    }\n\n    status = create_request(pubc, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    msg = tdata->msg;\n\n    /* Add Expires:0 header */\n    expires = pjsip_expires_hdr_create(tdata->pool, 0);\n    pjsip_msg_add_hdr( msg, (pjsip_hdr*)expires);\n\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_publishc_update_expires( pjsip_publishc *pubc,\n\t\t\t\t\t           pj_uint32_t expires )\n{\n    PJ_ASSERT_RETURN(pubc, PJ_EINVAL);\n    set_expires( pubc, expires );\n    return PJ_SUCCESS;\n}\n\n\nstatic void call_callback(pjsip_publishc *pubc, pj_status_t status, \n\t\t\t  int st_code, const pj_str_t *reason,\n\t\t\t  pjsip_rx_data *rdata, pj_int32_t expiration)\n{\n    struct pjsip_publishc_cbparam cbparam;\n\n\n    cbparam.pubc = pubc;\n    cbparam.token = pubc->token;\n    cbparam.status = status;\n    cbparam.code = st_code;\n    cbparam.reason = *reason;\n    cbparam.rdata = rdata;\n    cbparam.expiration = expiration;\n\n    (*pubc->cb)(&cbparam);\n}\n\nstatic void pubc_refresh_timer_cb( pj_timer_heap_t *timer_heap,\n\t\t\t\t   struct pj_timer_entry *entry)\n{\n    pjsip_publishc *pubc = (pjsip_publishc*) entry->user_data;\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n    \n    PJ_UNUSED_ARG(timer_heap);\n\n    entry->id = 0;\n    status = pjsip_publishc_publish(pubc, 1, &tdata);\n    if (status != PJ_SUCCESS) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\tpj_str_t reason = pj_strerror(status, errmsg, sizeof(errmsg));\n\tcall_callback(pubc, status, 400, &reason, NULL, -1);\n\treturn;\n    }\n\n    status = pjsip_publishc_send(pubc, tdata);\n    /* No need to call callback as it should have been called */\n}\n\nstatic void tsx_callback(void *token, pjsip_event *event)\n{\n    pj_status_t status;\n    pjsip_publishc *pubc = (pjsip_publishc*) token;\n    pjsip_transaction *tsx = event->body.tsx_state.tsx;\n    \n    /* Decrement pending transaction counter. */\n    pj_assert(pubc->pending_tsx > 0);\n    --pubc->pending_tsx;\n\n    /* Mark that we're in callback to prevent deletion (#1164) */\n    ++pubc->in_callback;\n\n    /* If publication data has been deleted by user then remove publication \n     * data from transaction's callback, and don't call callback.\n     */\n    if (pubc->_delete_flag) {\n\n\t/* Nothing to do */\n\t;\n\n    } else if (tsx->status_code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED ||\n\t       tsx->status_code == PJSIP_SC_UNAUTHORIZED)\n    {\n\tpjsip_rx_data *rdata = event->body.tsx_state.src.rdata;\n\tpjsip_tx_data *tdata;\n\n\tstatus = pjsip_auth_clt_reinit_req( &pubc->auth_sess,\n\t\t\t\t\t    rdata, \n\t\t\t\t\t    tsx->last_tx,  \n\t\t\t\t\t    &tdata);\n\tif (status != PJ_SUCCESS) {\n\t    call_callback(pubc, status, tsx->status_code, \n\t\t\t  &rdata->msg_info.msg->line.status.reason,\n\t\t\t  rdata, -1);\n\t} else {\n    \t    status = pjsip_publishc_send(pubc, tdata);\n\t}\n\n    } else {\n\tpjsip_rx_data *rdata;\n\tpj_int32_t expiration = 0xFFFF;\n\n\tif (tsx->status_code/100 == 2) {\n\t    pjsip_msg *msg;\n\t    pjsip_expires_hdr *expires;\n\t    pjsip_generic_string_hdr *etag_hdr;\n\t    const pj_str_t STR_ETAG = { \"SIP-ETag\", 8 };\n\n\t    rdata = event->body.tsx_state.src.rdata;\n\t    msg = rdata->msg_info.msg;\n\n\t    /* Save ETag value */\n\t    etag_hdr = (pjsip_generic_string_hdr*)\n\t\t       pjsip_msg_find_hdr_by_name(msg, &STR_ETAG, NULL);\n\t    if (etag_hdr) {\n\t\tpj_strdup(pubc->pool, &pubc->etag, &etag_hdr->hvalue);\n\t    } else {\n\t\tpubc->etag.slen = 0;\n\t    }\n\n\t    /* Update expires value */\n\t    expires = (pjsip_expires_hdr*)\n\t    \t      pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL);\n\n\t    if (pubc->auto_refresh && expires)\n\t\texpiration = expires->ivalue;\n\t    \n\t    if (pubc->auto_refresh && expiration!=0 && expiration!=0xFFFF) {\n\t\tpj_time_val delay = { 0, 0};\n\n\t\t/* Cancel existing timer, if any */\n\t\tif (pubc->timer.id != 0) {\n\t\t    pjsip_endpt_cancel_timer(pubc->endpt, &pubc->timer);\n\t\t    pubc->timer.id = 0;\n\t\t}\n\n\t\tdelay.sec = expiration - DELAY_BEFORE_REFRESH;\n\t\tif (pubc->expires != PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED && \n\t\t    delay.sec > (pj_int32_t)pubc->expires) \n\t\t{\n\t\t    delay.sec = pubc->expires;\n\t\t}\n\t\tif (delay.sec < DELAY_BEFORE_REFRESH) \n\t\t    delay.sec = DELAY_BEFORE_REFRESH;\n\t\tpubc->timer.cb = &pubc_refresh_timer_cb;\n\t\tpubc->timer.id = REFRESH_TIMER;\n\t\tpubc->timer.user_data = pubc;\n\t\tpjsip_endpt_schedule_timer( pubc->endpt, &pubc->timer, &delay);\n\t\tpj_gettimeofday(&pubc->last_refresh);\n\t\tpubc->next_refresh = pubc->last_refresh;\n\t\tpubc->next_refresh.sec += delay.sec;\n\t    }\n\n\t} else {\n\t    rdata = (event->body.tsx_state.type==PJSIP_EVENT_RX_MSG) ? \n\t\t\tevent->body.tsx_state.src.rdata : NULL;\n\t}\n\n\n\t/* Call callback. */\n\tif (expiration == 0xFFFF) expiration = -1;\n\n\t/* Temporarily increment pending_tsx to prevent callback from\n\t * destroying pubc.\n\t */\n\t++pubc->pending_tsx;\n\n\tcall_callback(pubc, PJ_SUCCESS, tsx->status_code, \n\t\t      (rdata ? &rdata->msg_info.msg->line.status.reason \n\t\t\t: pjsip_get_status_text(tsx->status_code)),\n\t\t      rdata, expiration);\n\n\t--pubc->pending_tsx;\n\n\t/* If we have pending request(s), send them now */\n\tpj_mutex_lock(pubc->mutex);\n\twhile (!pj_list_empty(&pubc->pending_reqs)) {\n\t    pending_publish *pp = pubc->pending_reqs.next;\n\t    pjsip_tx_data *tdata = pp->tdata;\n\n\t    /* Remove the request from pending request list,\n\t     * and keep the unused entry into pending_reqs_empty pool.\n\t     */\n\t    pj_list_erase(pp);\n\t    pj_list_push_back(&pubc->pending_reqs_empty, pp);\n\n\t    /* Add SIP-If-Match if we have etag and the request doesn't have\n\t     * one (http://trac.pjsip.org/repos/ticket/996)\n\t     */\n\t    if (pubc->etag.slen) {\n\t\tconst pj_str_t STR_HNAME = { \"SIP-If-Match\", 12 };\n\t\tpjsip_generic_string_hdr *sim_hdr;\n\n\t\tsim_hdr = (pjsip_generic_string_hdr*)\n\t\t\t  pjsip_msg_find_hdr_by_name(tdata->msg, &STR_HNAME, NULL);\n\t\tif (!sim_hdr) {\n\t\t    /* Create the header */\n\t\t    sim_hdr = pjsip_generic_string_hdr_create(tdata->pool,\n\t\t\t\t\t\t\t      &STR_HNAME,\n\t\t\t\t\t\t\t      &pubc->etag);\n\t\t    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)sim_hdr);\n\n\t\t} else {\n\t\t    /* Update */\n\t\t    if (pj_strcmp(&pubc->etag, &sim_hdr->hvalue))\n\t\t\tpj_strdup(tdata->pool, &sim_hdr->hvalue, &pubc->etag);\n\t\t}\n\t    }\n\n\t    status = pjsip_publishc_send(pubc, tdata);\n\t    if (status == PJ_EPENDING) {\n\t\tpj_assert(!\"Not expected\");\n\t\tpjsip_tx_data_dec_ref(tdata);\n\t    } else if (status == PJ_SUCCESS) {\n\t\tbreak;\n\t    }\n\t}\n\tpj_mutex_unlock(pubc->mutex);\n    }\n\n    /* No longer in callback. */\n    --pubc->in_callback;\n\n    /* Delete the record if user destroy pubc during the callback. */\n    if (pubc->_delete_flag && pubc->pending_tsx==0) {\n\tpjsip_publishc_destroy(pubc);\n    }\n}\n\n\nPJ_DEF(pj_status_t) pjsip_publishc_send(pjsip_publishc *pubc, \n\t\t\t\t\tpjsip_tx_data *tdata)\n{\n    pj_status_t status;\n    pjsip_cseq_hdr *cseq_hdr;\n    pj_uint32_t cseq;\n\n    PJ_ASSERT_RETURN(pubc && tdata, PJ_EINVAL);\n\n    /* Make sure we don't have pending transaction. */\n    pj_mutex_lock(pubc->mutex);\n    if (pubc->pending_tsx) {\n\tif (pubc->opt.queue_request) {\n\t    pending_publish *pp = NULL;\n\t    if (pj_list_empty(&pubc->pending_reqs_empty)) {\n\t\tpp = PJ_POOL_ZALLOC_T(pubc->pool, pending_publish);\n\t    } else {\n\t\tpp = pubc->pending_reqs_empty.next;\n\t\tpj_list_erase(pp);\n\t    }\n\t    pp->tdata = tdata;\n\t    pj_list_push_back(&pubc->pending_reqs, pp);\n\t    pj_mutex_unlock(pubc->mutex);\n\t    PJ_LOG(4,(THIS_FILE, \"Request is queued, pubc has another \"\n\t\t\t\t \"transaction pending\"));\n\t    return PJ_EPENDING;\n\t} else {\n\t    pjsip_tx_data_dec_ref(tdata);\n\t    pj_mutex_unlock(pubc->mutex);\n\t    PJ_LOG(4,(THIS_FILE, \"Unable to send request, pubc has another \"\n\t\t\t\t \"transaction pending\"));\n\t    return PJ_EBUSY;\n\t}\n    }\n    pj_mutex_unlock(pubc->mutex);\n\n    /* If via_addr is set, use this address for the Via header. */\n    if (pubc->via_addr.host.slen > 0) {\n        tdata->via_addr = pubc->via_addr;\n        tdata->via_tp = pubc->via_tp;\n    }\n\n    /* Invalidate message buffer. */\n    pjsip_tx_data_invalidate_msg(tdata);\n\n    /* Increment CSeq */\n    cseq = ++pubc->cseq_hdr->cseq;\n    cseq_hdr = (pjsip_cseq_hdr*)\n    \t       pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);\n    cseq_hdr->cseq = cseq;\n\n    /* Increment pending transaction first, since transaction callback\n     * may be called even before send_request() returns!\n     */\n    ++pubc->pending_tsx;\n    status = pjsip_endpt_send_request(pubc->endpt, tdata, -1, pubc, \n\t\t\t\t      &tsx_callback);\n    if (status!=PJ_SUCCESS) {\n\t// no need to decrement, callback has been called and it should\n\t// already decremented pending_tsx. Decrementing this here may \n\t// cause accessing freed memory location.\n\t//--pubc->pending_tsx;\n\tPJ_LOG(4,(THIS_FILE, \"Error sending request, status=%d\", status));\n    }\n\n    return status;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-simple/rpid.c",
    "content": "/* $Id: rpid.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-simple/rpid.h>\n#include <pjsip-simple/errno.h>\n#include <pj/assert.h>\n#include <pj/guid.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n\nstatic const pj_str_t DM_NAME = {\"xmlns:dm\", 8};\nstatic const pj_str_t DM_VAL = {\"urn:ietf:params:xml:ns:pidf:data-model\", 38};\nstatic const pj_str_t RPID_NAME = {\"xmlns:rpid\", 10};\nstatic const pj_str_t RPID_VAL = {\"urn:ietf:params:xml:ns:pidf:rpid\", 32};\n\nstatic const pj_str_t DM_NOTE = {\"dm:note\", 7};\nstatic const pj_str_t DM_PERSON = {\"dm:person\", 9};\nstatic const pj_str_t ID = {\"id\", 2};\nstatic const pj_str_t NOTE = {\"note\", 4};\nstatic const pj_str_t RPID_ACTIVITIES = {\"rpid:activities\", 15};\nstatic const pj_str_t RPID_AWAY = {\"rpid:away\", 9};\nstatic const pj_str_t RPID_BUSY = {\"rpid:busy\", 9};\nstatic const pj_str_t RPID_UNKNOWN = {\"rpid:unknown\", 12};\n\n\n/* Duplicate RPID element */\nPJ_DEF(void) pjrpid_element_dup(pj_pool_t *pool, pjrpid_element *dst,\n\t\t\t\tconst pjrpid_element *src)\n{\n    pj_memcpy(dst, src, sizeof(pjrpid_element));\n    pj_strdup(pool, &dst->id, &src->id);\n    pj_strdup(pool, &dst->note, &src->note);\n}\n\n\n/* Update RPID namespaces. */\nstatic void update_namespaces(pjpidf_pres *pres,\n\t\t\t      pj_pool_t *pool)\n{\n    /* Check if namespace is already present. */\n    if (pj_xml_find_attr(pres, &DM_NAME, NULL) != NULL)\n\treturn;\n\n    pj_xml_add_attr(pres, pj_xml_attr_new(pool, &DM_NAME, &DM_VAL));\n    pj_xml_add_attr(pres, pj_xml_attr_new(pool, &RPID_NAME, &RPID_VAL));\n}\n\n\n/* Comparison function to find node name substring */\nstatic pj_bool_t substring_match(const pj_xml_node *node, \n\t\t\t\t const char *part_name,\n\t\t\t\t pj_ssize_t part_len)\n{\n    pj_str_t end_name;\n\n    if (part_len < 1)\n\tpart_len = pj_ansi_strlen(part_name);\n\n    if (node->name.slen < part_len)\n\treturn PJ_FALSE;\n\n    end_name.ptr = node->name.ptr + (node->name.slen - part_len);\n    end_name.slen = part_len;\n\n    return pj_strnicmp2(&end_name, part_name, part_len)==0;\n}\n\n/* Util to find child node with the specified substring */\nstatic pj_xml_node *find_node(const pj_xml_node *parent, \n\t\t\t      const char *part_name)\n{\n    const pj_xml_node *node = parent->node_head.next, \n\t\t      *head = (pj_xml_node*) &parent->node_head;\n    pj_ssize_t part_len = pj_ansi_strlen(part_name);\n\n    while (node != head) {\n\tif (substring_match(node, part_name, part_len))\n\t    return (pj_xml_node*) node;\n\n\tnode = node->next;\n    }\n\n    return NULL;\n}\n\n/*\n * Add RPID element into existing PIDF document.\n */\nPJ_DEF(pj_status_t) pjrpid_add_element(pjpidf_pres *pres, \n\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t       unsigned options,\n\t\t\t\t       const pjrpid_element *elem)\n{\n    pj_xml_node *nd_person, *nd_activities, *nd_activity, *nd_note;\n    pj_xml_attr *attr;\n\n    PJ_ASSERT_RETURN(pres && pool && options==0 && elem, PJ_EINVAL);\n\n    PJ_UNUSED_ARG(options);\n\n    /* Check if we need to add RPID information into the PIDF document. */\n    if (elem->id.slen==0 && \n\telem->activity==PJRPID_ACTIVITY_UNKNOWN &&\n\telem->note.slen==0)\n    {\n\t/* No RPID information to be added. */\n\treturn PJ_SUCCESS;\n    }\n\n    /* Add <note> to <tuple> */\n    if (elem->note.slen != 0) {\n\tpj_xml_node *nd_tuple;\n\n\tnd_tuple = find_node(pres, \"tuple\");\n\n\tif (nd_tuple) {\n\t    nd_note = pj_xml_node_new(pool, &NOTE);\n\t    pj_strdup(pool, &nd_note->content, &elem->note);\n\t    pj_xml_add_node(nd_tuple, nd_note);\n\t    nd_note = NULL;\n\t}\n    }\n\n    /* Update namespace */\n    update_namespaces(pres, pool);\n\n    /* Add <person> */\n    nd_person = pj_xml_node_new(pool, &DM_PERSON);\n    if (elem->id.slen != 0) {\n\tattr = pj_xml_attr_new(pool, &ID, &elem->id);\n    } else {\n\tpj_str_t person_id;\n\t/* xs:ID must start with letter */\n\t//pj_create_unique_string(pool, &person_id);\n\tperson_id.ptr = (char*)pj_pool_alloc(pool, PJ_GUID_STRING_LENGTH+2);\n\tperson_id.ptr += 2;\n\tpj_generate_unique_string(&person_id);\n\tperson_id.ptr -= 2;\n\tperson_id.ptr[0] = 'p';\n\tperson_id.ptr[1] = 'j';\n\tperson_id.slen += 2;\n\n\tattr = pj_xml_attr_new(pool, &ID, &person_id);\n    }\n    pj_xml_add_attr(nd_person, attr);\n    pj_xml_add_node(pres, nd_person);\n\n    /* Add <activities> */\n    nd_activities = pj_xml_node_new(pool, &RPID_ACTIVITIES);\n    pj_xml_add_node(nd_person, nd_activities);\n\n    /* Add the activity */\n    switch (elem->activity) {\n    case PJRPID_ACTIVITY_AWAY:\n\tnd_activity = pj_xml_node_new(pool, &RPID_AWAY);\n\tbreak;\n    case PJRPID_ACTIVITY_BUSY:\n\tnd_activity = pj_xml_node_new(pool, &RPID_BUSY);\n\tbreak;\n    case PJRPID_ACTIVITY_UNKNOWN:\n    default:\n\tnd_activity = pj_xml_node_new(pool, &RPID_UNKNOWN);\n\tbreak;\n    }\n    pj_xml_add_node(nd_activities, nd_activity);\n\n    /* Add custom text if required. */\n    if (elem->note.slen != 0) {\n\tnd_note = pj_xml_node_new(pool, &DM_NOTE);\n\tpj_strdup(pool, &nd_note->content, &elem->note);\n\tpj_xml_add_node(nd_person, nd_note);\n    }\n\n    /* Done */\n    return PJ_SUCCESS;\n}\n\n\n/* Get <note> element from PIDF <tuple> element */\nstatic pj_status_t get_tuple_note(const pjpidf_pres *pres,\n\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t  pjrpid_element *elem)\n{\n    const pj_xml_node *nd_tuple, *nd_note;\n\n    nd_tuple = find_node(pres, \"tuple\");\n    if (!nd_tuple)\n\treturn PJSIP_SIMPLE_EBADRPID;\n\n    nd_note = find_node(pres, \"note\");\n    if (nd_note) {\n\tpj_strdup(pool, &elem->note, &nd_note->content);\n\treturn PJ_SUCCESS;\n    }\n\n    return PJSIP_SIMPLE_EBADRPID;\n}\n\n/*\n * Get RPID element from PIDF document, if any.\n */\nPJ_DEF(pj_status_t) pjrpid_get_element(const pjpidf_pres *pres,\n\t\t\t\t       pj_pool_t *pool,\n\t\t\t\t       pjrpid_element *elem)\n{\n    const pj_xml_node *nd_person, *nd_activities, *nd_note = NULL;\n    const pj_xml_attr *attr;\n\n    /* Reset */\n    pj_bzero(elem, sizeof(*elem));\n    elem->activity = PJRPID_ACTIVITY_UNKNOWN;\n\n    /* Find <person> */\n    nd_person = find_node(pres, \"person\");\n    if (!nd_person) {\n\t/* <person> not found, try to get <note> from <tuple> */\n\treturn get_tuple_note(pres, pool, elem);\n    }\n\n    /* Get element id attribute */\n    attr = pj_xml_find_attr((pj_xml_node*)nd_person, &ID, NULL);\n    if (attr)\n\tpj_strdup(pool, &elem->id, &attr->value);\n\n    /* Get <activities> */\n    nd_activities = find_node(nd_person, \"activities\");\n    if (nd_activities) {\n\tconst pj_xml_node *nd_activity;\n\n\t/* Try to get <note> from <activities> */\n\tnd_note = find_node(nd_activities, \"note\");\n\n\t/* Get the activity */\n\tnd_activity = nd_activities->node_head.next;\n\tif (nd_activity == nd_note)\n\t    nd_activity = nd_activity->next;\n\n\tif (nd_activity != (pj_xml_node*) &nd_activities->node_head) {\n\t    if (substring_match(nd_activity, \"busy\", -1))\n\t\telem->activity = PJRPID_ACTIVITY_BUSY;\n\t    else if (substring_match(nd_activity, \"away\", -1))\n\t\telem->activity = PJRPID_ACTIVITY_AWAY;\n\t    else\n\t\telem->activity = PJRPID_ACTIVITY_UNKNOWN;\n\n\t}\n    }\n\n    /* If <note> is not found, get <note> from <person> */\n    if (nd_note == NULL)\n\tnd_note = find_node(nd_person, \"note\");\n\n    if (nd_note) {\n\tpj_strdup(pool, &elem->note, &nd_note->content);\n    } else {\n\tget_tuple_note(pres, pool, elem);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-simple/xpidf.c",
    "content": "/* $Id: xpidf.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-simple/xpidf.h>\n#include <pj/assert.h>\n#include <pj/guid.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\nstatic pj_str_t STR_PRESENCE = { \"presence\", 8 };\nstatic pj_str_t STR_STATUS = { \"status\", 6 };\nstatic pj_str_t STR_OPEN = { \"open\", 4 };\nstatic pj_str_t STR_CLOSED = { \"closed\", 6 };\nstatic pj_str_t STR_URI = { \"uri\", 3 };\nstatic pj_str_t STR_ATOM = { \"atom\", 4 };\nstatic pj_str_t STR_ATOMID = { \"atomid\", 6 };\nstatic pj_str_t STR_ID = { \"id\", 2 };\nstatic pj_str_t STR_ADDRESS = { \"address\", 7 };\nstatic pj_str_t STR_SUBSCRIBE_PARAM = { \";method=SUBSCRIBE\", 17 };\nstatic pj_str_t STR_PRESENTITY = { \"presentity\", 10 };\nstatic pj_str_t STR_EMPTY_STRING = { NULL, 0 };\n\nstatic pj_xml_node* xml_create_node(pj_pool_t *pool, \n\t\t\t\t    pj_str_t *name, const pj_str_t *value)\n{\n    pj_xml_node *node;\n\n    node = PJ_POOL_ALLOC_T(pool, pj_xml_node);\n    pj_list_init(&node->attr_head);\n    pj_list_init(&node->node_head);\n    node->name = *name;\n    if (value) pj_strdup(pool, &node->content, value);\n    else node->content.ptr=NULL, node->content.slen=0;\n\n    return node;\n}\n\nstatic pj_xml_attr* xml_create_attr(pj_pool_t *pool, pj_str_t *name,\n\t\t\t\t    const pj_str_t *value)\n{\n    pj_xml_attr *attr = PJ_POOL_ALLOC_T(pool, pj_xml_attr);\n    attr->name = *name;\n    pj_strdup(pool, &attr->value, value);\n    return attr;\n}\n\n\nPJ_DEF(pjxpidf_pres*) pjxpidf_create(pj_pool_t *pool, const pj_str_t *uri_cstr)\n{\n    pjxpidf_pres *pres;\n    pj_xml_node *presentity;\n    pj_xml_node *atom;\n    pj_xml_node *addr;\n    pj_xml_node *status;\n    pj_xml_attr *attr;\n    pj_str_t uri;\n    pj_str_t tmp;\n\n    /* <presence> */\n    pres = xml_create_node(pool, &STR_PRESENCE, NULL);\n\n    /* <presentity> */\n    presentity = xml_create_node(pool, &STR_PRESENTITY, NULL);\n    pj_xml_add_node(pres, presentity);\n\n    /* uri attribute */\n    uri.ptr = (char*) pj_pool_alloc(pool, uri_cstr->slen + \n    \t\t\t\t\t   STR_SUBSCRIBE_PARAM.slen);\n    pj_strcpy( &uri, uri_cstr);\n    pj_strcat( &uri, &STR_SUBSCRIBE_PARAM);\n    attr = xml_create_attr(pool, &STR_URI, &uri);\n    pj_xml_add_attr(presentity, attr);\n\n    /* <atom> */\n    atom = xml_create_node(pool, &STR_ATOM, NULL);\n    pj_xml_add_node(pres, atom);\n\n    /* atom id */\n    pj_create_unique_string(pool, &tmp);\n    attr = xml_create_attr(pool, &STR_ATOMID, &tmp);\n    pj_xml_add_attr(atom, attr);\n\n    /* address */\n    addr = xml_create_node(pool, &STR_ADDRESS, NULL);\n    pj_xml_add_node(atom, addr);\n\n    /* address'es uri */\n    attr = xml_create_attr(pool, &STR_URI, uri_cstr);\n    pj_xml_add_attr(addr, attr);\n\n    /* status */\n    status = xml_create_node(pool, &STR_STATUS, NULL);\n    pj_xml_add_node(addr, status);\n\n    /* status attr */\n    attr = xml_create_attr(pool, &STR_STATUS, &STR_OPEN);\n    pj_xml_add_attr(status, attr);\n\n    return pres;\n}   \n\n\n\nPJ_DEF(pjxpidf_pres*) pjxpidf_parse(pj_pool_t *pool, char *text, pj_size_t len)\n{\n    pjxpidf_pres *pres;\n    pj_xml_node *node;\n\n    pres = pj_xml_parse(pool, text, len);\n    if (!pres)\n\treturn NULL;\n\n    /* Validate <presence> */\n    if (pj_stricmp(&pres->name, &STR_PRESENCE) != 0)\n\treturn NULL;\n\n    /* Validate <presentity> */\n    node = pj_xml_find_node(pres, &STR_PRESENTITY);\n    if (node == NULL)\n\treturn NULL;\n    if (pj_xml_find_attr(node, &STR_URI, NULL) == NULL)\n\treturn NULL;\n\n    /* Validate <atom> */\n    node = pj_xml_find_node(pres, &STR_ATOM);\n    if (node == NULL)\n\treturn NULL;\n    if (pj_xml_find_attr(node, &STR_ATOMID, NULL) == NULL && \n\tpj_xml_find_attr(node, &STR_ID, NULL) == NULL)\n    {\n\treturn NULL;\n    }\n\n    /* Address */\n    node = pj_xml_find_node(node, &STR_ADDRESS);\n    if (node == NULL)\n\treturn NULL;\n    if (pj_xml_find_attr(node, &STR_URI, NULL) == NULL)\n\treturn NULL;\n\n\n    /* Status */\n    node = pj_xml_find_node(node, &STR_STATUS);\n    if (node == NULL)\n\treturn NULL;\n    if (pj_xml_find_attr(node, &STR_STATUS, NULL) == NULL)\n\treturn NULL;\n\n    return pres;\n}\n\n\nPJ_DEF(int) pjxpidf_print( pjxpidf_pres *pres, char *text, pj_size_t len)\n{\n    return pj_xml_print(pres, text, len, PJ_TRUE);\n}\n\n\nPJ_DEF(pj_str_t*) pjxpidf_get_uri(pjxpidf_pres *pres)\n{\n    pj_xml_node *presentity;\n    pj_xml_attr *attr;\n\n    presentity = pj_xml_find_node(pres, &STR_PRESENTITY);\n    if (!presentity)\n\treturn &STR_EMPTY_STRING;\n\n    attr = pj_xml_find_attr(presentity, &STR_URI, NULL);\n    if (!attr)\n\treturn &STR_EMPTY_STRING;\n\n    return &attr->value;\n}\n\n\nPJ_DEF(pj_status_t) pjxpidf_set_uri(pj_pool_t *pool, pjxpidf_pres *pres, \n\t\t\t\t    const pj_str_t *uri)\n{\n    pj_xml_node *presentity;\n    pj_xml_node *atom;\n    pj_xml_node *addr;\n    pj_xml_attr *attr;\n    pj_str_t dup_uri;\n\n    presentity = pj_xml_find_node(pres, &STR_PRESENTITY);\n    if (!presentity) {\n\tpj_assert(0);\n\treturn -1;\n    }\n    atom = pj_xml_find_node(pres, &STR_ATOM);\n    if (!atom) {\n\tpj_assert(0);\n\treturn -1;\n    }\n    addr = pj_xml_find_node(atom, &STR_ADDRESS);\n    if (!addr) {\n\tpj_assert(0);\n\treturn -1;\n    }\n\n    /* Set uri in presentity */\n    attr = pj_xml_find_attr(presentity, &STR_URI, NULL);\n    if (!attr) {\n\tpj_assert(0);\n\treturn -1;\n    }\n    pj_strdup(pool, &dup_uri, uri);\n    attr->value = dup_uri;\n\n    /* Set uri in address. */\n    attr = pj_xml_find_attr(addr, &STR_URI, NULL);\n    if (!attr) {\n\tpj_assert(0);\n\treturn -1;\n    }\n    attr->value = dup_uri;\n\n    return 0;\n}\n\n\nPJ_DEF(pj_bool_t) pjxpidf_get_status(pjxpidf_pres *pres)\n{\n    pj_xml_node *atom;\n    pj_xml_node *addr;\n    pj_xml_node *status;\n    pj_xml_attr *attr;\n\n    atom = pj_xml_find_node(pres, &STR_ATOM);\n    if (!atom) {\n\tpj_assert(0);\n\treturn PJ_FALSE;\n    }\n    addr = pj_xml_find_node(atom, &STR_ADDRESS);\n    if (!addr) {\n\tpj_assert(0);\n\treturn PJ_FALSE;\n    }\n    status = pj_xml_find_node(addr, &STR_STATUS);\n    if (!status) {\n\tpj_assert(0);\n\treturn PJ_FALSE;\n    }\n    attr = pj_xml_find_attr(status, &STR_STATUS, NULL);\n    if (!attr) {\n\tpj_assert(0);\n\treturn PJ_FALSE;\n    }\n\n    return pj_stricmp(&attr->value, &STR_OPEN)==0 ? PJ_TRUE : PJ_FALSE;\n}\n\n\nPJ_DEF(pj_status_t) pjxpidf_set_status(pjxpidf_pres *pres, pj_bool_t online_status)\n{\n    pj_xml_node *atom;\n    pj_xml_node *addr;\n    pj_xml_node *status;\n    pj_xml_attr *attr;\n\n    atom = pj_xml_find_node(pres, &STR_ATOM);\n    if (!atom) {\n\tpj_assert(0);\n\treturn -1;\n    }\n    addr = pj_xml_find_node(atom, &STR_ADDRESS);\n    if (!addr) {\n\tpj_assert(0);\n\treturn -1;\n    }\n    status = pj_xml_find_node(addr, &STR_STATUS);\n    if (!status) {\n\tpj_assert(0);\n\treturn -1;\n    }\n    attr = pj_xml_find_attr(status, &STR_STATUS, NULL);\n    if (!attr) {\n\tpj_assert(0);\n\treturn -1;\n    }\n\n    attr->value = ( online_status ? STR_OPEN : STR_CLOSED );\n    return 0;\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-ua/sip_100rel.c",
    "content": "/* $Id: sip_100rel.c 4208 2012-07-18 07:52:33Z ming $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-ua/sip_100rel.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_event.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_transaction.h>\n#include <pj/assert.h>\n#include <pj/ctype.h>\n#include <pj/log.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n\n#define THIS_FILE\t\"sip_100rel.c\"\n\n/* PRACK method */\nPJ_DEF_DATA(const pjsip_method) pjsip_prack_method =\n{\n    PJSIP_OTHER_METHOD,\n    { \"PRACK\", 5 }\n};\n\ntypedef struct dlg_data dlg_data;\n\n/*\n * Static prototypes.\n */\nstatic pj_status_t mod_100rel_load(pjsip_endpoint *endpt);\n\nstatic void on_retransmit(pj_timer_heap_t *timer_heap,\n\t\t\t  struct pj_timer_entry *entry);\n\n\nstatic const pj_str_t tag_100rel = { \"100rel\", 6 };\nstatic const pj_str_t RSEQ = { \"RSeq\", 4 };\nstatic const pj_str_t RACK = { \"RAck\", 4 };\n\n\n/* 100rel module */\nstatic struct mod_100rel\n{\n    pjsip_module\t mod;\n    pjsip_endpoint\t*endpt;\n} mod_100rel = \n{\n    {\n\tNULL, NULL,\t\t\t    /* prev, next.\t\t*/\n\t{ \"mod-100rel\", 10 },\t\t    /* Name.\t\t\t*/\n\t-1,\t\t\t\t    /* Id\t\t\t*/\n\tPJSIP_MOD_PRIORITY_DIALOG_USAGE,    /* Priority\t\t\t*/\n\t&mod_100rel_load,\t\t    /* load()\t\t\t*/\n\tNULL,\t\t\t\t    /* start()\t\t\t*/\n\tNULL,\t\t\t\t    /* stop()\t\t\t*/\n\tNULL,\t\t\t\t    /* unload()\t\t\t*/\n\tNULL,\t\t\t\t    /* on_rx_request()\t\t*/\n\tNULL,\t\t\t\t    /* on_rx_response()\t\t*/\n\tNULL,\t\t\t\t    /* on_tx_request.\t\t*/\n\tNULL,\t\t\t\t    /* on_tx_response()\t\t*/\n\tNULL,\t\t\t\t    /* on_tsx_state()\t\t*/\n    }\n\n};\n\n/* List of pending transmission (may include the final response as well) */\ntypedef struct tx_data_list_t\n{\n\tPJ_DECL_LIST_MEMBER(struct tx_data_list_t);\n\tpj_uint32_t\t rseq;\n\tpjsip_tx_data\t*tdata;\n} tx_data_list_t;\n\n\n/* Below, UAS and UAC roles are of the INVITE transaction */\n\n/* UAS state. */\ntypedef struct uas_state_t\n{\n\tpj_int32_t\t cseq;\n\tpj_uint32_t\t rseq;\t/* Initialized to -1 */\n\ttx_data_list_t\t tx_data_list;\n\tunsigned\t retransmit_count;\n\tpj_timer_entry\t retransmit_timer;\n} uas_state_t;\n\n\n/* UAC state */\ntypedef struct uac_state_t\n{\n    pj_str_t\t\ttag;\t/* To tag\t     \t*/\n    pj_int32_t\t\tcseq;\n    pj_uint32_t\t\trseq;\t/* Initialized to -1 \t*/\n    struct uac_state_t *next;\t/* next call leg\t*/\n} uac_state_t;\n\n\n/* State attached to each dialog. */\nstruct dlg_data\n{\n\tpjsip_inv_session\t*inv;\n\tuas_state_t\t\t*uas_state;\n\tuac_state_t\t\t*uac_state_list;\n};\n\n\n/*****************************************************************************\n **\n ** Module\n **\n *****************************************************************************\n */\nstatic pj_status_t mod_100rel_load(pjsip_endpoint *endpt)\n{\n    mod_100rel.endpt = endpt;\n    pjsip_endpt_add_capability(endpt, &mod_100rel.mod, \n\t\t\t       PJSIP_H_ALLOW, NULL,\n\t\t\t       1, &pjsip_prack_method.name);\n    pjsip_endpt_add_capability(endpt, &mod_100rel.mod, \n\t\t\t       PJSIP_H_SUPPORTED, NULL,\n\t\t\t       1, &tag_100rel);\n\n    return PJ_SUCCESS;\n}\n\nstatic pjsip_require_hdr *find_req_hdr(pjsip_msg *msg)\n{\n    pjsip_require_hdr *hreq;\n\n    hreq = (pjsip_require_hdr*)\n\t    pjsip_msg_find_hdr(msg, PJSIP_H_REQUIRE, NULL);\n\n    while (hreq) {\n\tunsigned i;\n\tfor (i=0; i<hreq->count; ++i) {\n\t    if (!pj_stricmp(&hreq->values[i], &tag_100rel)) {\n\t\treturn hreq;\n\t    }\n\t}\n\n\tif ((void*)hreq->next == (void*)&msg->hdr)\n\t    return NULL;\n\n\threq = (pjsip_require_hdr*)\n\t\tpjsip_msg_find_hdr(msg, PJSIP_H_REQUIRE, hreq->next);\n\n    }\n\n    return NULL;\n}\n\n\n/*\n * Get PRACK method constant. \n */\nPJ_DEF(const pjsip_method*) pjsip_get_prack_method(void)\n{\n    return &pjsip_prack_method;\n}\n\n\n/*\n * init module\n */\nPJ_DEF(pj_status_t) pjsip_100rel_init_module(pjsip_endpoint *endpt)\n{\n    if (mod_100rel.mod.id != -1)\n\treturn PJ_SUCCESS;\n\n    return pjsip_endpt_register_module(endpt, &mod_100rel.mod);\n}\n\n\n/*\n * API: attach 100rel support in invite session. Called by\n *      sip_inv.c\n */\nPJ_DEF(pj_status_t) pjsip_100rel_attach(pjsip_inv_session *inv)\n{\n    dlg_data *dd;\n\n    /* Check that 100rel module has been initialized */\n    PJ_ASSERT_RETURN(mod_100rel.mod.id >= 0, PJ_EINVALIDOP);\n\n    /* Create and attach as dialog usage */\n    dd = PJ_POOL_ZALLOC_T(inv->dlg->pool, dlg_data);\n    dd->inv = inv;\n    pjsip_dlg_add_usage(inv->dlg, &mod_100rel.mod, (void*)dd);\n\n    PJ_LOG(5,(dd->inv->dlg->obj_name, \"100rel module attached\"));\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Check if incoming response has reliable provisional response feature.\n */\nPJ_DEF(pj_bool_t) pjsip_100rel_is_reliable(pjsip_rx_data *rdata)\n{\n    pjsip_msg *msg = rdata->msg_info.msg;\n\n    PJ_ASSERT_RETURN(msg->type == PJSIP_RESPONSE_MSG, PJ_FALSE);\n\n    return msg->line.status.code > 100 && msg->line.status.code < 200 &&\n\t   rdata->msg_info.require != NULL &&\n\t   find_req_hdr(msg) != NULL;\n}\n\n\n/*\n * Create PRACK request for the incoming reliable provisional response.\n */\nPJ_DEF(pj_status_t) pjsip_100rel_create_prack( pjsip_inv_session *inv,\n\t\t\t\t\t       pjsip_rx_data *rdata,\n\t\t\t\t\t       pjsip_tx_data **p_tdata)\n{\n    dlg_data *dd;\n    uac_state_t *uac_state = NULL;\n    const pj_str_t *to_tag = &rdata->msg_info.to->tag;\n    pjsip_transaction *tsx;\n    pjsip_msg *msg;\n    pjsip_generic_string_hdr *rseq_hdr;\n    pjsip_generic_string_hdr *rack_hdr;\n    unsigned rseq;\n    pj_str_t rack;\n    char rack_buf[80];\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n\n    *p_tdata = NULL;\n\n    dd = (dlg_data*) inv->dlg->mod_data[mod_100rel.mod.id];\n    PJ_ASSERT_RETURN(dd != NULL, PJSIP_ENOTINITIALIZED);\n\n    tsx = pjsip_rdata_get_tsx(rdata);\n    msg = rdata->msg_info.msg;\n\n    /* Check our assumptions */\n    pj_assert( tsx->role == PJSIP_ROLE_UAC &&\n\t       tsx->method.id == PJSIP_INVITE_METHOD &&\n\t       msg->line.status.code > 100 &&\n\t       msg->line.status.code < 200);\n\n\n    /* Get the RSeq header */\n    rseq_hdr = (pjsip_generic_string_hdr*)\n\t       pjsip_msg_find_hdr_by_name(msg, &RSEQ, NULL);\n    if (rseq_hdr == NULL) {\n\tPJ_LOG(4,(dd->inv->dlg->obj_name, \n\t\t \"Ignoring 100rel response with no RSeq header\"));\n\treturn PJSIP_EMISSINGHDR;\n    }\n    rseq = (pj_uint32_t) pj_strtoul(&rseq_hdr->hvalue);\n\n    /* Find UAC state for the specified call leg */\n    uac_state = dd->uac_state_list;\n    while (uac_state) {\n\tif (pj_stricmp(&uac_state->tag, to_tag)==0)\n\t    break;\n\tuac_state = uac_state->next;\n    }\n\n    /* Create new UAC state if we don't have one */\n    if (uac_state == NULL) {\n\tuac_state = PJ_POOL_ZALLOC_T(dd->inv->dlg->pool, uac_state_t);\n\tuac_state->cseq = rdata->msg_info.cseq->cseq;\n\tuac_state->rseq = rseq - 1;\n\tpj_strdup(dd->inv->dlg->pool, &uac_state->tag, to_tag);\n\tuac_state->next = dd->uac_state_list;\n\tdd->uac_state_list = uac_state;\n    }\n\n    /* If this is from new INVITE transaction, reset UAC state. */\n    if (rdata->msg_info.cseq->cseq != uac_state->cseq) {\n\tuac_state->cseq = rdata->msg_info.cseq->cseq;\n\tuac_state->rseq = rseq - 1;\n    }\n\n    /* Ignore provisional response retransmission */\n    if (rseq <= uac_state->rseq) {\n\t/* This should have been handled before */\n\treturn PJ_EIGNORED;\n\n    /* Ignore provisional response with out-of-order RSeq */\n    } else if (rseq != uac_state->rseq + 1) {\n\tPJ_LOG(4,(dd->inv->dlg->obj_name, \n\t\t \"Ignoring 100rel response because RSeq jump \"\n\t\t \"(expecting %u, got %u)\",\n\t\t uac_state->rseq+1, rseq));\n\treturn PJ_EIGNORED;\n    }\n\n    /* Update our RSeq */\n    uac_state->rseq = rseq;\n\n    /* Create PRACK */\n    status = pjsip_dlg_create_request(dd->inv->dlg, &pjsip_prack_method,\n\t\t\t\t      -1, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* If this response is a forked response from a different call-leg,\n     * update the req URI (https://trac.pjsip.org/repos/ticket/1364)\n     */\n    if (pj_stricmp(&uac_state->tag, &dd->inv->dlg->remote.info->tag)) {\n\tconst pjsip_contact_hdr *mhdr;\n\n\tmhdr = (const pjsip_contact_hdr*)\n\t       pjsip_msg_find_hdr(rdata->msg_info.msg,\n\t                          PJSIP_H_CONTACT, NULL);\n\tif (!mhdr || !mhdr->uri) {\n\t    PJ_LOG(4,(dd->inv->dlg->obj_name,\n\t\t     \"Ignoring 100rel response with no or \"\n\t\t     \"invalid Contact header\"));\n\t    pjsip_tx_data_dec_ref(tdata);\n\t    return PJ_EIGNORED;\n\t}\n\ttdata->msg->line.req.uri = (pjsip_uri*)\n\t\t\t\t   pjsip_uri_clone(tdata->pool, mhdr->uri);\n    }\n\n    /* Create RAck header */\n    rack.ptr = rack_buf;\n    rack.slen = pj_ansi_snprintf(rack.ptr, sizeof(rack_buf),\n\t\t\t\t \"%u %u %.*s\",\n\t\t\t\t rseq, rdata->msg_info.cseq->cseq,\n\t\t\t\t (int)tsx->method.name.slen,\n\t\t\t\t tsx->method.name.ptr);\n    if (rack.slen < 1 || rack.slen >= (int)sizeof(rack_buf)) {\n\treturn PJ_ETOOSMALL;\n    }\n    rack_hdr = pjsip_generic_string_hdr_create(tdata->pool, &RACK, &rack);\n    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) rack_hdr);\n\n    /* Done */\n    *p_tdata = tdata;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Send PRACK request.\n */\nPJ_DEF(pj_status_t) pjsip_100rel_send_prack( pjsip_inv_session *inv,\n\t\t\t\t\t     pjsip_tx_data *tdata)\n{\n    dlg_data *dd;\n\n    dd = (dlg_data*) inv->dlg->mod_data[mod_100rel.mod.id];\n    PJ_ASSERT_ON_FAIL(dd != NULL, \n    {pjsip_tx_data_dec_ref(tdata); return PJSIP_ENOTINITIALIZED; });\n\n    return pjsip_dlg_send_request(inv->dlg, tdata, \n\t\t\t\t  mod_100rel.mod.id, (void*) dd);\n\n}\n\n\n/* Clear all responses in the transmission list */\nstatic void clear_all_responses(dlg_data *dd)\n{\n    tx_data_list_t *tl;\n\n    tl = dd->uas_state->tx_data_list.next;\n    while (tl != &dd->uas_state->tx_data_list) {\n\tpjsip_tx_data_dec_ref(tl->tdata);\n\ttl = tl->next;\n    }\n    pj_list_init(&dd->uas_state->tx_data_list);\n}\n\n/*\n * Notify 100rel module that the invite session has been disconnected.\n */\nPJ_DEF(pj_status_t) pjsip_100rel_end_session(pjsip_inv_session *inv)\n{\n    dlg_data *dd;\n\n    dd = (dlg_data*) inv->dlg->mod_data[mod_100rel.mod.id];\n    if (!dd)\n\treturn PJ_SUCCESS;\n\n    /* Make sure we don't have pending transmission */\n    if (dd->uas_state) {\n       /* Cancel the retransmit timer */\n    \tif (dd->uas_state->retransmit_timer.id) {\n\t    pjsip_endpt_cancel_timer(dd->inv->dlg->endpt,\n\t\t\t\t     &dd->uas_state->retransmit_timer);\n\t    dd->uas_state->retransmit_timer.id = PJ_FALSE;\n\t}\n\tif (!pj_list_empty(&dd->uas_state->tx_data_list)) {\n\t    /* Clear all pending responses (drop 'em) */\n\t    clear_all_responses(dd);\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void parse_rack(const pj_str_t *rack,\n\t\t       pj_uint32_t *p_rseq, pj_int32_t *p_seq,\n\t\t       pj_str_t *p_method)\n{\n    const char *p = rack->ptr, *end = p + rack->slen;\n    pj_str_t token;\n\n    token.ptr = (char*)p;\n    while (p < end && pj_isdigit(*p))\n\t++p;\n    token.slen = p - token.ptr;\n    *p_rseq = pj_strtoul(&token);\n\n    ++p;\n    token.ptr = (char*)p;\n    while (p < end && pj_isdigit(*p))\n\t++p;\n    token.slen = p - token.ptr;\n    *p_seq = pj_strtoul(&token);\n\n    ++p;\n    if (p < end) {\n\tp_method->ptr = (char*)p;\n\tp_method->slen = end - p;\n    } else {\n\tp_method->ptr = NULL;\n\tp_method->slen = 0;\n    }\n}\n\n\n/*\n * Handle incoming PRACK request.\n */\nPJ_DEF(pj_status_t) pjsip_100rel_on_rx_prack( pjsip_inv_session *inv,\n\t\t\t\t\t      pjsip_rx_data *rdata)\n{\n    dlg_data *dd;\n    pjsip_transaction *tsx;\n    pjsip_msg *msg;\n    pjsip_generic_string_hdr *rack_hdr;\n    pjsip_tx_data *tdata;\n    pj_uint32_t rseq;\n    pj_int32_t cseq;\n    pj_str_t method;\n    pj_status_t status;\n\n    tsx = pjsip_rdata_get_tsx(rdata);\n    pj_assert(tsx != NULL);\n\n    msg = rdata->msg_info.msg;\n\n    dd = (dlg_data*) inv->dlg->mod_data[mod_100rel.mod.id];\n    if (dd == NULL) {\n\t/* UAC sends us PRACK while we didn't send reliable provisional \n\t * response. Respond with 400 (?) \n\t */\n\tconst pj_str_t reason = pj_str(\"Unexpected PRACK\");\n\n\tstatus = pjsip_dlg_create_response(inv->dlg, rdata, 400, \n\t\t\t\t\t   &reason, &tdata);\n\tif (status == PJ_SUCCESS) {\n\t    status = pjsip_dlg_send_response(inv->dlg, tsx, tdata);\n\t}\n\treturn PJSIP_ENOTINITIALIZED;\n    }\n\n    /* Always reply with 200/OK for PRACK */\n    status = pjsip_dlg_create_response(inv->dlg, rdata, 200, NULL, &tdata);\n    if (status == PJ_SUCCESS) {\n\tstatus = pjsip_dlg_send_response(inv->dlg, tsx, tdata);\n    }\n\n    /* Ignore if we don't have pending transmission */\n    if (dd->uas_state == NULL || pj_list_empty(&dd->uas_state->tx_data_list)) {\n\tPJ_LOG(4,(dd->inv->dlg->obj_name, \n\t\t  \"PRACK ignored - no pending response\"));\n\treturn PJ_EIGNORED;\n    }\n\n    /* Find RAck header */\n    rack_hdr = (pjsip_generic_string_hdr*)\n\t       pjsip_msg_find_hdr_by_name(msg, &RACK, NULL);\n    if (!rack_hdr) {\n\t/* RAck header not found */\n\tPJ_LOG(4,(dd->inv->dlg->obj_name, \"No RAck header\"));\n\treturn PJSIP_EMISSINGHDR;\n    }\n\n    /* Parse RAck header */\n    parse_rack(&rack_hdr->hvalue, &rseq, &cseq, &method);\n\n\n    /* Match RAck against outgoing transmission */\n    if (rseq == dd->uas_state->tx_data_list.next->rseq &&\n\tcseq == dd->uas_state->cseq)\n    {\n\t/* \n\t * Yes this PRACK matches outgoing transmission.\n\t */\n\ttx_data_list_t *tl = dd->uas_state->tx_data_list.next;\n\n\tif (dd->uas_state->retransmit_timer.id) {\n\t    pjsip_endpt_cancel_timer(dd->inv->dlg->endpt,\n\t\t\t\t     &dd->uas_state->retransmit_timer);\n\t    dd->uas_state->retransmit_timer.id = PJ_FALSE;\n\t}\n\n\t/* Remove from the list */\n\tif (tl != &dd->uas_state->tx_data_list) {\n\t    pj_list_erase(tl);\n\n\t    /* Destroy the response */\n\t    pjsip_tx_data_dec_ref(tl->tdata);\n\t}\n\n\t/* Schedule next packet */\n\tdd->uas_state->retransmit_count = 0;\n\tif (!pj_list_empty(&dd->uas_state->tx_data_list)) {\n\t    on_retransmit(NULL, &dd->uas_state->retransmit_timer);\n\t}\n\n    } else {\n\t/* No it doesn't match */\n\tPJ_LOG(4,(dd->inv->dlg->obj_name, \n\t\t \"Rx PRACK with no matching reliable response\"));\n\treturn PJ_EIGNORED;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * This is retransmit timer callback, called initially to send the response,\n * and subsequently when the retransmission time elapses.\n */\nstatic void on_retransmit(pj_timer_heap_t *timer_heap,\n\t\t\t  struct pj_timer_entry *entry)\n{\n    dlg_data *dd;\n    tx_data_list_t *tl;\n    pjsip_tx_data *tdata;\n    pj_bool_t final;\n    pj_time_val delay;\n\n    PJ_UNUSED_ARG(timer_heap);\n\n    dd = (dlg_data*) entry->user_data;\n\n    entry->id = PJ_FALSE;\n\n    ++dd->uas_state->retransmit_count;\n    if (dd->uas_state->retransmit_count >= 7) {\n\t/* If a reliable provisional response is retransmitted for\n\t   64*T1 seconds  without reception of a corresponding PRACK,\n\t   the UAS SHOULD reject the original request with a 5xx \n\t   response.\n\t*/\n\tpj_str_t reason = pj_str(\"Reliable response timed out\");\n\tpj_status_t status;\n\n\t/* Clear all pending responses */\n\tclear_all_responses(dd);\n\n\t/* Send 500 response */\n\tstatus = pjsip_inv_end_session(dd->inv, 500, &reason, &tdata);\n\tif (status == PJ_SUCCESS) {\n\t    pjsip_dlg_send_response(dd->inv->dlg, \n\t\t\t\t    dd->inv->invite_tsx,\n\t\t\t\t    tdata);\n\t}\n\treturn;\n    }\n\n    pj_assert(!pj_list_empty(&dd->uas_state->tx_data_list));\n    tl = dd->uas_state->tx_data_list.next;\n    tdata = tl->tdata;\n\n    pjsip_tx_data_add_ref(tdata);\n    final = tdata->msg->line.status.code >= 200;\n\n    if (dd->uas_state->retransmit_count == 1) {\n\tpjsip_tsx_send_msg(dd->inv->invite_tsx, tdata);\n    } else {\n\tpjsip_tsx_retransmit_no_state(dd->inv->invite_tsx, tdata);\n    }\n\n    if (final) {\n\t/* This is final response, which will be retransmitted by\n\t * UA layer. There's no more task to do, so clear the\n\t * transmission list and bail out.\n\t */\n\tclear_all_responses(dd);\n\treturn;\n    }\n\n    /* Schedule next retransmission */\n    if (dd->uas_state->retransmit_count < 6) {\n\tdelay.sec = 0;\n\tdelay.msec = (1 << dd->uas_state->retransmit_count) * \n\t\t     pjsip_cfg()->tsx.t1;\n\tpj_time_val_normalize(&delay);\n    } else {\n\tdelay.sec = 1;\n\tdelay.msec = 500;\n    }\n\n\n    pjsip_endpt_schedule_timer(dd->inv->dlg->endpt, \n\t\t\t       &dd->uas_state->retransmit_timer,\n\t\t\t       &delay);\n\n    entry->id = PJ_TRUE;\n}\n\n\n/* Clone response. */\nstatic pjsip_tx_data *clone_tdata(dlg_data *dd,\n\t\t\t\t  const pjsip_tx_data *src)\n{\n    pjsip_tx_data *dst;\n    const pjsip_hdr *hsrc;\n    pjsip_msg *msg;\n    pj_status_t status;\n\n    status = pjsip_endpt_create_tdata(dd->inv->dlg->endpt, &dst);\n    if (status != PJ_SUCCESS)\n\treturn NULL;\n\n    msg = pjsip_msg_create(dst->pool, PJSIP_RESPONSE_MSG);\n    dst->msg = msg;\n    pjsip_tx_data_add_ref(dst);\n\n    /* Duplicate status line */\n    msg->line.status.code = src->msg->line.status.code;\n    pj_strdup(dst->pool, &msg->line.status.reason, \n\t      &src->msg->line.status.reason);\n\n    /* Duplicate all headers */\n    hsrc = src->msg->hdr.next;\n    while (hsrc != &src->msg->hdr) {\n\tpjsip_hdr *h = (pjsip_hdr*) pjsip_hdr_clone(dst->pool, hsrc);\n\tpjsip_msg_add_hdr(msg, h);\n\thsrc = hsrc->next;\n    }\n\n    /* Duplicate message body */\n    if (src->msg->body)\n\tmsg->body = pjsip_msg_body_clone(dst->pool, src->msg->body);\n\n    PJ_LOG(5,(dd->inv->dlg->obj_name,\n\t     \"Reliable response %s created\",\n\t     pjsip_tx_data_get_info(dst)));\n\n    return dst;\n}\n\n\n/* Check if any pending response in transmission list has SDP */\nstatic pj_bool_t has_sdp(dlg_data *dd)\n{\n    tx_data_list_t *tl;\n\n    tl = dd->uas_state->tx_data_list.next;\n    while (tl != &dd->uas_state->tx_data_list) {\n\t    if (tl->tdata->msg->body)\n\t\t    return PJ_TRUE;\n\t    tl = tl->next;\n    }\n\n    return PJ_FALSE;\n}\n\n\n/* Send response reliably */\nPJ_DEF(pj_status_t) pjsip_100rel_tx_response(pjsip_inv_session *inv,\n\t\t\t\t\t     pjsip_tx_data *tdata)\n{\n    pjsip_cseq_hdr *cseq_hdr;\n    pjsip_generic_string_hdr *rseq_hdr;\n    pjsip_require_hdr *req_hdr;\n    int status_code;\n    dlg_data *dd;\n    pjsip_tx_data *old_tdata;\n    pj_status_t status;\n    \n    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_RESPONSE_MSG,\n\t\t     PJSIP_ENOTRESPONSEMSG);\n    \n    status_code = tdata->msg->line.status.code;\n    \n    /* 100 response doesn't need PRACK */\n    if (status_code == 100)\n\treturn pjsip_dlg_send_response(inv->dlg, inv->invite_tsx, tdata);\n    \n\n    /* Get the 100rel data attached to this dialog */\n    dd = (dlg_data*) inv->dlg->mod_data[mod_100rel.mod.id];\n    PJ_ASSERT_RETURN(dd != NULL, PJ_EINVALIDOP);\n    \n    \n    /* Clone tdata.\n     * We need to clone tdata because we may need to keep it in our\n     * retransmission list, while the original dialog may modify it\n     * if it wants to send another response.\n     */\n    old_tdata = tdata;\n    tdata = clone_tdata(dd, old_tdata);\n    pjsip_tx_data_dec_ref(old_tdata);\n    \n\n    /* Get CSeq header, and make sure this is INVITE response */\n    cseq_hdr = (pjsip_cseq_hdr*)\n\t        pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);\n    PJ_ASSERT_RETURN(cseq_hdr != NULL, PJ_EBUG);\n    PJ_ASSERT_RETURN(cseq_hdr->method.id == PJSIP_INVITE_METHOD, \n\tPJ_EINVALIDOP);\n    \n    /* Remove existing Require header */\n    req_hdr = find_req_hdr(tdata->msg);\n    if (req_hdr) {\n\tpj_list_erase(req_hdr);\n    }\n    \n    /* Remove existing RSeq header */\n    rseq_hdr = (pjsip_generic_string_hdr*)\n\tpjsip_msg_find_hdr_by_name(tdata->msg, &RSEQ, NULL);\n    if (rseq_hdr)\n\tpj_list_erase(rseq_hdr);\n    \n    /* Different treatment for provisional and final response */\n    if (status_code/100 == 2) {\n\t\n\t/* RFC 3262 Section 3: UAS Behavior:\n    \n\t  The UAS MAY send a final response to the initial request \n\t  before having received PRACKs for all unacknowledged \n\t  reliable provisional responses, unless the final response \n\t  is 2xx and any of the unacknowledged reliable provisional \n\t  responses contained a session description.  In that case, \n\t  it MUST NOT send a final response until those provisional \n\t  responses are acknowledged.\n\t*/\n\t\n\tif (dd->uas_state && has_sdp(dd)) {\n\t    /* Yes we have transmitted 1xx with SDP reliably.\n\t     * In this case, must queue the 2xx response.\n\t     */\n\t    tx_data_list_t *tl;\n\t    \n\t    tl = PJ_POOL_ZALLOC_T(tdata->pool, tx_data_list_t);\n\t    tl->tdata = tdata;\n\t    tl->rseq = (pj_uint32_t)-1;\n\t    pj_list_push_back(&dd->uas_state->tx_data_list, tl);\n\t    \n\t    /* Will send later */\n\t    status = PJ_SUCCESS;\n\t    \n\t    PJ_LOG(4,(dd->inv->dlg->obj_name, \n\t\t      \"2xx response will be sent after PRACK\"));\n\t    \n\t} else if (dd->uas_state) {\n\t    /* \n\t    RFC 3262 Section 3: UAS Behavior:\n\n\t    If the UAS does send a final response when reliable\n\t    responses are still unacknowledged, it SHOULD NOT \n\t    continue to retransmit the unacknowledged reliable\n\t    provisional responses, but it MUST be prepared to \n\t    process PRACK requests for those outstanding \n\t    responses.\n\t    */\n\t    \n\t    PJ_LOG(4,(dd->inv->dlg->obj_name, \n\t\t      \"No SDP sent so far, sending 2xx now\"));\n\t    \n\t    /* Cancel the retransmit timer */\n\t    if (dd->uas_state->retransmit_timer.id) {\n\t\tpjsip_endpt_cancel_timer(dd->inv->dlg->endpt,\n\t\t\t\t\t &dd->uas_state->retransmit_timer);\n\t\tdd->uas_state->retransmit_timer.id = PJ_FALSE;\n\t    }\n\t    \n\t    /* Clear all pending responses (drop 'em) */\n\t    clear_all_responses(dd);\n\t    \n\t    /* And transmit the 2xx response */\n\t    status=pjsip_dlg_send_response(inv->dlg, \n\t\t\t\t\t   inv->invite_tsx, tdata);\n\t    \n\t} else {\n\t    /* We didn't send any reliable provisional response */\n\t    \n\t    /* Transmit the 2xx response */\n\t    status=pjsip_dlg_send_response(inv->dlg, \n\t\t\t\t\t   inv->invite_tsx, tdata);\n\t}\n\t\n    } else if (status_code >= 300) {\n\t\n\t/* \n\tRFC 3262 Section 3: UAS Behavior:\n\n\tIf the UAS does send a final response when reliable\n\tresponses are still unacknowledged, it SHOULD NOT \n\tcontinue to retransmit the unacknowledged reliable\n\tprovisional responses, but it MUST be prepared to \n\tprocess PRACK requests for those outstanding \n\tresponses.\n\t*/\n\t\n\t/* Cancel the retransmit timer */\n\tif (dd->uas_state && dd->uas_state->retransmit_timer.id) {\n\t    pjsip_endpt_cancel_timer(dd->inv->dlg->endpt,\n\t\t\t\t     &dd->uas_state->retransmit_timer);\n\t    dd->uas_state->retransmit_timer.id = PJ_FALSE;\n\t    \n\t    /* Clear all pending responses (drop 'em) */\n\t    clear_all_responses(dd);\n\t}\n\t\n\t/* And transmit the 2xx response */\n\tstatus=pjsip_dlg_send_response(inv->dlg, \n\t\t\t\t       inv->invite_tsx, tdata);\n\t\n    } else {\n\t/*\n\t * This is provisional response.\n\t */\n\tchar rseq_str[32];\n\tpj_str_t rseq;\n\ttx_data_list_t *tl;\n\t\n\t/* Create UAS state if we don't have one */\n\tif (dd->uas_state == NULL) {\n\t    dd->uas_state = PJ_POOL_ZALLOC_T(inv->dlg->pool,\n\t\t\t\t\t     uas_state_t);\n\t    dd->uas_state->cseq = cseq_hdr->cseq;\n\t    dd->uas_state->rseq = pj_rand() % 0x7FFF;\n\t    pj_list_init(&dd->uas_state->tx_data_list);\n\t    dd->uas_state->retransmit_timer.user_data = dd;\n\t    dd->uas_state->retransmit_timer.cb = &on_retransmit;\n\t}\n\t\n\t/* Check that CSeq match */\n\tPJ_ASSERT_RETURN(cseq_hdr->cseq == dd->uas_state->cseq,\n\t\t\t PJ_EINVALIDOP);\n\t\n\t/* Add Require header */\n\treq_hdr = pjsip_require_hdr_create(tdata->pool);\n\treq_hdr->count = 1;\n\treq_hdr->values[0] = tag_100rel;\n\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)req_hdr);\n\t\n\t/* Add RSeq header */\n\tpj_ansi_snprintf(rseq_str, sizeof(rseq_str), \"%u\",\n\t\t\t dd->uas_state->rseq);\n\trseq = pj_str(rseq_str);\n\trseq_hdr = pjsip_generic_string_hdr_create(tdata->pool, \n\t\t\t\t\t\t   &RSEQ, &rseq);\n\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)rseq_hdr);\n\t\n\t/* Create list entry for this response */\n\ttl = PJ_POOL_ZALLOC_T(tdata->pool, tx_data_list_t);\n\ttl->tdata = tdata;\n\ttl->rseq = dd->uas_state->rseq++;\n\t\n\t/* Add to queue if there's pending response, otherwise\n\t * transmit immediately.\n\t */\n\tif (!pj_list_empty(&dd->uas_state->tx_data_list)) {\n\t    \n\t    int code = tdata->msg->line.status.code;\n\t    \n\t    /* Will send later */\n\t    pj_list_push_back(&dd->uas_state->tx_data_list, tl);\n\t    status = PJ_SUCCESS;\n\t    \n\t    PJ_LOG(4,(dd->inv->dlg->obj_name, \n\t\t      \"Reliable %d response enqueued (%d pending)\", \n\t\t      code, pj_list_size(&dd->uas_state->tx_data_list)));\n\t    \n\t} else {\n\t    pj_list_push_back(&dd->uas_state->tx_data_list, tl);\n\t    \n\t    dd->uas_state->retransmit_count = 0;\n\t    on_retransmit(NULL, &dd->uas_state->retransmit_timer);\n\t    status = PJ_SUCCESS;\n\t}\n\t\n    }\n    \n    return status;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-ua/sip_inv.c",
    "content": "/* $Id: sip_inv.c 4521 2013-05-18 05:54:22Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-ua/sip_inv.h>\n#include <pjsip-ua/sip_100rel.h>\n#include <pjsip-ua/sip_timer.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_event.h>\n#include <pjsip/sip_multipart.h>\n#include <pjsip/sip_transaction.h>\n#include <pjmedia/sdp.h>\n#include <pjmedia/sdp_neg.h>\n#include <pjmedia/errno.h>\n#include <pj/array.h>\n#include <pj/string.h>\n#include <pj/pool.h>\n#include <pj/assert.h>\n#include <pj/os.h>\n#include <pj/log.h>\n#include <pj/rand.h>\n\n/* \n * Note on offer/answer:\n *\n * The offer/answer framework in this implementation assumes the occurence\n * of SDP in a particular request/response according to this table:\n\n\t\t  offer   answer    Note:\n    ========================================================================\n    INVITE\t    X\t\t    INVITE may contain offer\n    18x/INVITE\t    X\t    X\t    Response may contain offer or answer\n    2xx/INVITE\t    X\t    X\t    Response may contain offer or answer\n    ACK\t\t\t    X\t    ACK may contain answer\n\n    PRACK\t\t    X\t    PRACK can only contain answer\n    2xx/PRACK\t    \t\t    Response may not have offer nor answer\n\n    UPDATE\t    X\t\t    UPDATE may only contain offer\n    2xx/UPDATE\t\t    X\t    Response may only contain answer\n    ========================================================================\n\n  *\n  */\n\n#define THIS_FILE\t\"sip_inv.c\"\n\nstatic const char *inv_state_names[] =\n{\n    \"NULL\",\n    \"CALLING\",\n    \"INCOMING\",\n    \"EARLY\",\n    \"CONNECTING\",\n    \"CONFIRMED\",\n    \"DISCONNCTD\",\n    \"TERMINATED\",\n};\n\n/* UPDATE method */\nstatic const pjsip_method pjsip_update_method =\n{\n    PJSIP_OTHER_METHOD,\n    { \"UPDATE\", 6 }\n};\n\n#define POOL_INIT_SIZE\t256\n#define POOL_INC_SIZE\t256\n\n/*\n * Static prototypes.\n */\nstatic pj_status_t mod_inv_load(pjsip_endpoint *endpt);\nstatic pj_status_t mod_inv_unload(void);\nstatic pj_bool_t   mod_inv_on_rx_request(pjsip_rx_data *rdata);\nstatic pj_bool_t   mod_inv_on_rx_response(pjsip_rx_data *rdata);\nstatic void\t   mod_inv_on_tsx_state(pjsip_transaction*, pjsip_event*);\n\nstatic void inv_on_state_null( pjsip_inv_session *inv, pjsip_event *e);\nstatic void inv_on_state_calling( pjsip_inv_session *inv, pjsip_event *e);\nstatic void inv_on_state_incoming( pjsip_inv_session *inv, pjsip_event *e);\nstatic void inv_on_state_early( pjsip_inv_session *inv, pjsip_event *e);\nstatic void inv_on_state_connecting( pjsip_inv_session *inv, pjsip_event *e);\nstatic void inv_on_state_confirmed( pjsip_inv_session *inv, pjsip_event *e);\nstatic void inv_on_state_disconnected( pjsip_inv_session *inv, pjsip_event *e);\n\nstatic pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,\n\t\t\t\t\t\t  pjsip_transaction *tsx,\n\t\t\t\t\t\t  pjsip_rx_data *rdata);\nstatic pj_status_t inv_negotiate_sdp( pjsip_inv_session *inv );\nstatic pjsip_msg_body *create_sdp_body(pj_pool_t *pool,\n\t\t\t\t       const pjmedia_sdp_session *c_sdp);\nstatic pj_status_t process_answer( pjsip_inv_session *inv,\n\t\t\t\t   int st_code,\n\t\t\t\t   pjsip_tx_data *tdata,\n\t\t\t\t   const pjmedia_sdp_session *local_sdp);\n\nstatic pj_status_t handle_timer_response(pjsip_inv_session *inv,\n\t\t\t\t         const pjsip_rx_data *rdata,\n\t\t\t\t         pj_bool_t end_sess_on_failure);\n\nstatic pj_bool_t inv_check_secure_dlg(pjsip_inv_session *inv,\n\t\t\t\t      pjsip_event *e);\n\nstatic void (*inv_state_handler[])( pjsip_inv_session *inv, pjsip_event *e) = \n{\n    &inv_on_state_null,\n    &inv_on_state_calling,\n    &inv_on_state_incoming,\n    &inv_on_state_early,\n    &inv_on_state_connecting,\n    &inv_on_state_confirmed,\n    &inv_on_state_disconnected,\n};\n\nstatic struct mod_inv\n{\n    pjsip_module\t mod;\n    pjsip_endpoint\t*endpt;\n    pjsip_inv_callback\t cb;\n} mod_inv = \n{\n    {\n\tNULL, NULL,\t\t\t    /* prev, next.\t\t*/\n\t{ \"mod-invite\", 10 },\t\t    /* Name.\t\t\t*/\n\t-1,\t\t\t\t    /* Id\t\t\t*/\n\tPJSIP_MOD_PRIORITY_DIALOG_USAGE,    /* Priority\t\t\t*/\n\t&mod_inv_load,\t\t\t    /* load()\t\t\t*/\n\tNULL,\t\t\t\t    /* start()\t\t\t*/\n\tNULL,\t\t\t\t    /* stop()\t\t\t*/\n\t&mod_inv_unload,\t\t    /* unload()\t\t\t*/\n\t&mod_inv_on_rx_request,\t\t    /* on_rx_request()\t\t*/\n\t&mod_inv_on_rx_response,\t    /* on_rx_response()\t\t*/\n\tNULL,\t\t\t\t    /* on_tx_request.\t\t*/\n\tNULL,\t\t\t\t    /* on_tx_response()\t\t*/\n\t&mod_inv_on_tsx_state,\t\t    /* on_tsx_state()\t\t*/\n    }\n};\n\n\n/* Invite session data to be attached to transaction. */\nstruct tsx_inv_data\n{\n    pjsip_inv_session\t*inv;\t    /* The invite session\t\t    */\n    pj_bool_t\t\t sdp_done;  /* SDP negotiation done for this tsx?   */\n    pj_bool_t\t\t retrying;  /* Resend (e.g. due to 401/407)         */\n    pj_str_t\t\t done_tag;  /* To tag in RX response with answer    */\n    pj_bool_t\t\t done_early;/* Negotiation was done for early med?  */\n    pj_bool_t\t\t has_sdp;   /* Message with SDP?\t\t    */\n};\n\n/*\n * Module load()\n */\nstatic pj_status_t mod_inv_load(pjsip_endpoint *endpt)\n{\n    pj_str_t allowed[] = {{\"INVITE\", 6}, {\"ACK\",3}, {\"BYE\",3}, {\"CANCEL\",6},\n\t\t\t    { \"UPDATE\", 6}};\n    pj_str_t accepted = { \"application/sdp\", 15 };\n\n    /* Register supported methods: INVITE, ACK, BYE, CANCEL, UPDATE */\n    pjsip_endpt_add_capability(endpt, &mod_inv.mod, PJSIP_H_ALLOW, NULL,\n\t\t\t       PJ_ARRAY_SIZE(allowed), allowed);\n\n    /* Register \"application/sdp\" in Accept header */\n    pjsip_endpt_add_capability(endpt, &mod_inv.mod, PJSIP_H_ACCEPT, NULL,\n\t\t\t       1, &accepted);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Module unload()\n */\nstatic pj_status_t mod_inv_unload(void)\n{\n    /* Should remove capability here */\n    return PJ_SUCCESS;\n}\n\n/*\n * Set session state.\n */\nstatic void inv_set_state(pjsip_inv_session *inv, pjsip_inv_state state,\n\t\t\t  pjsip_event *e)\n{\n    pjsip_inv_state prev_state = inv->state;\n    pj_bool_t dont_notify = PJ_FALSE;\n    pj_status_t status;\n\n    /* Prevent STATE_CALLING from being reported more than once because\n     * of authentication\n     * https://trac.pjsip.org/repos/ticket/1318\n     */\n    if (state==PJSIP_INV_STATE_CALLING && \n\t(inv->cb_called & (1 << PJSIP_INV_STATE_CALLING)) != 0)\n    {\n\tdont_notify = PJ_TRUE;\n    }\n\n    /* If state is confirmed, check that SDP negotiation is done,\n     * otherwise disconnect the session.\n     */\n    if (state == PJSIP_INV_STATE_CONFIRMED) {\n\tstruct tsx_inv_data *tsx_inv_data = NULL;\n\n\tif (inv->invite_tsx) {\n\t    tsx_inv_data = (struct tsx_inv_data*)\n\t\t\t   inv->invite_tsx->mod_data[mod_inv.mod.id];\n\t}\n\n\tif (pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE &&\n\t    (tsx_inv_data && !tsx_inv_data->sdp_done) )\n\t{\n\t    pjsip_tx_data *bye;\n\n\t    PJ_LOG(4,(inv->obj_name, \"SDP offer/answer incomplete, ending the \"\n\t\t      \"session\"));\n\n\t    status = pjsip_inv_end_session(inv, PJSIP_SC_NOT_ACCEPTABLE, \n\t\t\t\t\t   NULL, &bye);\n\t    if (status == PJ_SUCCESS && bye)\n\t\tstatus = pjsip_inv_send_msg(inv, bye);\n\n\t    return;\n\t}\n    }\n\n    /* Set state. */\n    inv->state = state;\n\n    /* If state is DISCONNECTED, cause code MUST have been set. */\n    pj_assert(inv->state != PJSIP_INV_STATE_DISCONNECTED ||\n\t      inv->cause != 0);\n\n    /* Mark the callback as called for this state */\n    inv->cb_called |= (1 << state);\n\n    /* Call on_state_changed() callback. */\n    if (mod_inv.cb.on_state_changed && inv->notify && !dont_notify)\n\t(*mod_inv.cb.on_state_changed)(inv, e);\n\n    /* Only decrement when previous state is not already DISCONNECTED */\n    if (inv->state == PJSIP_INV_STATE_DISCONNECTED &&\n\tprev_state != PJSIP_INV_STATE_DISCONNECTED) \n    {\n\tif (inv->last_ack) {\n\t    pjsip_tx_data_dec_ref(inv->last_ack);\n\t    inv->last_ack = NULL;\n\t}\n\tif (inv->invite_req) {\n\t    pjsip_tx_data_dec_ref(inv->invite_req);\n\t    inv->invite_req = NULL;\n\t}\n\tif (inv->pending_bye) {\n\t    pjsip_tx_data_dec_ref(inv->pending_bye);\n\t    inv->pending_bye = NULL;\n\t}\n\tpjsip_100rel_end_session(inv);\n\tpjsip_timer_end_session(inv);\n\tpjsip_dlg_dec_session(inv->dlg, &mod_inv.mod);\n\n\t/* Release the flip-flop pools */\n\tpj_pool_release(inv->pool_prov);\n\tinv->pool_prov = NULL;\n\tpj_pool_release(inv->pool_active);\n\tinv->pool_active = NULL;\n    }\n}\n\n\n/*\n * Set cause code.\n */\nstatic void inv_set_cause(pjsip_inv_session *inv, int cause_code,\n\t\t\t  const pj_str_t *cause_text)\n{\n    if ((cause_code > inv->cause) || inv->pending_bye) {\n\tinv->cause = (pjsip_status_code) cause_code;\n\tif (cause_text)\n\t    pj_strdup(inv->pool, &inv->cause_text, cause_text);\n\telse if (cause_code/100 == 2)\n\t    inv->cause_text = pj_str(\"Normal call clearing\");\n\telse\n\t    inv->cause_text = *pjsip_get_status_text(cause_code);\n    }\n}\n\n\n/*\n * Check if outgoing request needs to have SDP answer.\n * This applies for both ACK and PRACK requests.\n */\nstatic const pjmedia_sdp_session *inv_has_pending_answer(pjsip_inv_session *inv,\n\t\t\t\t\t\t         pjsip_transaction *tsx)\n{\n    pjmedia_sdp_neg_state neg_state;\n    const pjmedia_sdp_session *sdp = NULL;\n    pj_status_t status;\n\n    /* If SDP negotiator is ready, start negotiation. */\n\n    /* Start nego when appropriate. */\n    neg_state = inv->neg ? pjmedia_sdp_neg_get_state(inv->neg) :\n\t\tPJMEDIA_SDP_NEG_STATE_NULL;\n\n    if (neg_state == PJMEDIA_SDP_NEG_STATE_DONE) {\n\n\t/* Nothing to do */\n\n    } else if (neg_state == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO &&\n\t       pjmedia_sdp_neg_has_local_answer(inv->neg) )\n    {\n\tstruct tsx_inv_data *tsx_inv_data;\n\tstruct tsx_inv_data dummy;\n\n\t/* Get invite session's transaction data.\n\t * Note that tsx may be NULL, for example when application sends\n\t * delayed ACK request (at this time, the original INVITE \n\t * transaction may have been destroyed.\n\t */\n\tif (tsx) {\n\t    tsx_inv_data = (struct tsx_inv_data*)tsx->mod_data[mod_inv.mod.id];\n\t} else {\n\t    tsx_inv_data = &dummy;\n\t    pj_bzero(&dummy, sizeof(dummy));\n\t    dummy.inv = inv;\n\t}\n\n\tstatus = inv_negotiate_sdp(inv);\n\tif (status != PJ_SUCCESS)\n\t    return NULL;\n\t\n\t/* Mark this transaction has having SDP offer/answer done. */\n\ttsx_inv_data->sdp_done = 1;\n\n\tstatus = pjmedia_sdp_neg_get_active_local(inv->neg, &sdp);\n\n    } else {\n\t/* This remark is only valid for ACK.\n\tPJ_LOG(4,(inv->dlg->obj_name,\n\t\t  \"FYI, the SDP negotiator state (%s) is in a mess \"\n\t\t  \"when sending this ACK/PRACK request\",\n\t\t  pjmedia_sdp_neg_state_str(neg_state)));\n\t */\n    }\n\n    return sdp;\n}\n\n/* Process pending disconnection\n *  http://trac.pjsip.org/repos/ticket/1712\n */\nstatic void inv_perform_pending_bye(pjsip_inv_session *inv)\n{\n    if (inv->pending_bye) {\n\tpjsip_tx_data *bye = inv->pending_bye;\n\tpj_status_t status;\n\n\tPJ_LOG(4,(inv->dlg->obj_name, \"Sending pending BYE\"));\n\n\tinv->pending_bye = NULL;\n\tstatus = pjsip_inv_send_msg(inv, bye);\n\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(1,(inv->dlg->obj_name, status,\n\t\t\t \"Failed sending pending BYE\"));\n\t}\n    }\n}\n\n/*\n * Send ACK for 2xx response.\n */\nstatic pj_status_t inv_send_ack(pjsip_inv_session *inv, pjsip_event *e)\n{\n    pjsip_rx_data *rdata;\n    pjsip_event ack_e;\n    pj_status_t status;\n\n    if (e->type == PJSIP_EVENT_TSX_STATE)\n\trdata = e->body.tsx_state.src.rdata;\n    else if (e->type == PJSIP_EVENT_RX_MSG)\n\trdata = e->body.rx_msg.rdata;\n    else {\n\tpj_assert(!\"Unsupported event type\");\n\treturn PJ_EBUG;\n    }\n\n    /* Note that with https://trac.pjsip.org/repos/ticket/1725, this\n     * function can be called to send ACK for previous INVITE 200/OK\n     * retransmission\n     */\n\n    PJ_LOG(5,(inv->obj_name, \"Received %s, sending ACK\",\n\t      pjsip_rx_data_get_info(rdata)));\n\n    /* Check if we have cached ACK request. Must not use the cached ACK\n     * if it's still marked as pending by transport (#1011)\n     */\n    if (inv->last_ack && rdata->msg_info.cseq->cseq == inv->last_ack_cseq &&\n\t!inv->last_ack->is_pending)\n    {\n\tpjsip_tx_data_add_ref(inv->last_ack);\n\n    } else if (mod_inv.cb.on_send_ack) {\n\t/* If application handles ACK transmission manually, just notify the\n\t * callback\n\t */\n\tPJ_LOG(5,(inv->obj_name, \"Received %s, notifying application callback\",\n\t\t  pjsip_rx_data_get_info(rdata)));\n\n\t(*mod_inv.cb.on_send_ack)(inv, rdata);\n\treturn PJ_SUCCESS;\n\n    } else {\n\tstatus = pjsip_inv_create_ack(inv, rdata->msg_info.cseq->cseq,\n\t\t\t\t      &inv->last_ack);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n    }\n\n    PJSIP_EVENT_INIT_TX_MSG(ack_e, inv->last_ack);\n\n    /* Send ACK */\n    status = pjsip_dlg_send_request(inv->dlg, inv->last_ack, -1, NULL);\n    if (status != PJ_SUCCESS) {\n\t/* Better luck next time */\n\tpj_assert(!\"Unable to send ACK!\");\n\treturn status;\n    }\n\n\n    /* Set state to CONFIRMED (if we're not in CONFIRMED yet).\n     * But don't set it to CONFIRMED if we're already DISCONNECTED\n     * (this may have been a late 200/OK response.\n     */\n    if (inv->state < PJSIP_INV_STATE_CONFIRMED) {\n\tinv_set_state(inv, PJSIP_INV_STATE_CONFIRMED, &ack_e);\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Module on_rx_request()\n *\n * This callback is called for these events:\n *  - endpoint receives request which was unhandled by higher priority\n *    modules (e.g. transaction layer, dialog layer).\n *  - dialog distributes incoming request to its usages.\n */\nstatic pj_bool_t mod_inv_on_rx_request(pjsip_rx_data *rdata)\n{\n    pjsip_method *method;\n    pjsip_dialog *dlg;\n    pjsip_inv_session *inv;\n\n    /* Only wants to receive request from a dialog. */\n    dlg = pjsip_rdata_get_dlg(rdata);\n    if (dlg == NULL)\n\treturn PJ_FALSE;\n\n    inv = (pjsip_inv_session*) dlg->mod_data[mod_inv.mod.id];\n\n    /* Report to dialog that we handle INVITE, CANCEL, BYE, ACK. \n     * If we need to send response, it will be sent in the state\n     * handlers.\n     */\n    method = &rdata->msg_info.msg->line.req.method;\n\n    if (method->id == PJSIP_INVITE_METHOD) {\n\treturn PJ_TRUE;\n    }\n\n    /* BYE and CANCEL must have existing invite session */\n    if (method->id == PJSIP_BYE_METHOD ||\n\tmethod->id == PJSIP_CANCEL_METHOD)\n    {\n\tif (inv == NULL)\n\t    return PJ_FALSE;\n\n\treturn PJ_TRUE;\n    }\n\n    /* On receipt ACK request, when state is CONNECTING,\n     * move state to CONFIRMED.\n     */\n    if (method->id == PJSIP_ACK_METHOD && inv) {\n\n\t/* Ignore if we don't have INVITE in progress */\n\tif (!inv->invite_tsx) {\n\t    return PJ_TRUE;\n\t}\n\n\t/* Ignore ACK if pending INVITE transaction has not finished. */\n\tif (inv->invite_tsx->state < PJSIP_TSX_STATE_COMPLETED) {\n\t    return PJ_TRUE;\n\t}\n\n\t/* Ignore ACK with different CSeq\n\t * https://trac.pjsip.org/repos/ticket/1391\n\t */\n\tif (rdata->msg_info.cseq->cseq != inv->invite_tsx->cseq) {\n\t    return PJ_TRUE;\n\t}\n\n\t/* Terminate INVITE transaction, if it's still present. */\n\tif (inv->invite_tsx->state <= PJSIP_TSX_STATE_COMPLETED) {\n\t    /* Before we terminate INVITE transaction, process the SDP\n\t     * in the ACK request, if any. \n\t     * Only do this when invite state is not already disconnected\n\t     * (http://trac.pjsip.org/repos/ticket/640).\n\t     */\n\t    if (inv->state < PJSIP_INV_STATE_DISCONNECTED) {\n\t\tinv_check_sdp_in_incoming_msg(inv, inv->invite_tsx, rdata);\n\n\t\t/* Check if local offer got no SDP answer and INVITE session\n\t\t * is in CONFIRMED state.\n\t\t */\n\t\tif (pjmedia_sdp_neg_get_state(inv->neg)==\n\t\t    PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER &&\n\t\t    inv->state==PJSIP_INV_STATE_CONFIRMED)\n\t\t{\n\t\t    pjmedia_sdp_neg_cancel_offer(inv->neg);\n\t\t}\n\t    }\n\n\t    /* Now we can terminate the INVITE transaction */\n\t    pj_assert(inv->invite_tsx->status_code >= 200);\n\t    pjsip_tsx_terminate(inv->invite_tsx, \n\t\t\t\tinv->invite_tsx->status_code);\n\t    inv->invite_tsx = NULL;\n\t    if (inv->last_answer) {\n\t\t    pjsip_tx_data_dec_ref(inv->last_answer);\n\t\t    inv->last_answer = NULL;\n\t    }\n\t}\n\n\t/* On receipt of ACK, only set state to confirmed when state\n\t * is CONNECTING (e.g. we don't want to set the state to confirmed\n\t * when we receive ACK retransmission after sending non-2xx!)\n\t */\n\tif (inv->state == PJSIP_INV_STATE_CONNECTING) {\n\t    pjsip_event event;\n\n\t    PJSIP_EVENT_INIT_RX_MSG(event, rdata);\n\t    inv_set_state(inv, PJSIP_INV_STATE_CONFIRMED, &event);\n\n\t    /* Send pending BYE if any:\n\t     *   http://trac.pjsip.org/repos/ticket/1712\n\t     * Do this after setting the state to CONFIRMED, so that we\n\t     * have consistent CONFIRMED state between caller and callee.\n\t     */\n\t    if (inv->pending_bye)\n\t\tinv_perform_pending_bye(inv);\n\t}\n    }\n\n    return PJ_FALSE;\n}\n\n/* This function will process Session Timer headers in received \n * 2xx or 422 response of INVITE/UPDATE request.\n */\nstatic pj_status_t handle_timer_response(pjsip_inv_session *inv,\n\t\t\t\t         const pjsip_rx_data *rdata,\n\t\t\t\t\t pj_bool_t end_sess_on_failure)\n{\n    pjsip_status_code st_code;\n    pj_status_t status;\n\n    status = pjsip_timer_process_resp(inv, rdata, &st_code);\n    if (status != PJ_SUCCESS && end_sess_on_failure) {\n\tpjsip_tx_data *tdata;\n\tpj_status_t status2;\n\n\tstatus2 = pjsip_inv_end_session(inv, st_code, NULL, &tdata);\n\tif (tdata && status2 == PJ_SUCCESS)\n\t    pjsip_inv_send_msg(inv, tdata);\n    }\n\n    return status;\n}\n\n/*\n * Module on_rx_response().\n *\n * This callback is called for these events:\n *  - dialog distributes incoming 2xx response to INVITE (outside\n *    transaction) to its usages.\n *  - endpoint distributes strayed responses.\n */\nstatic pj_bool_t mod_inv_on_rx_response(pjsip_rx_data *rdata)\n{\n    pjsip_dialog *dlg;\n    pjsip_inv_session *inv;\n    pjsip_msg *msg = rdata->msg_info.msg;\n\n    dlg = pjsip_rdata_get_dlg(rdata);\n\n    /* Ignore responses outside dialog */\n    if (dlg == NULL)\n\treturn PJ_FALSE;\n\n    /* Ignore responses not belonging to invite session */\n    inv = pjsip_dlg_get_inv_session(dlg);\n    if (inv == NULL)\n\treturn PJ_FALSE;\n\n    /* This MAY be retransmission of 2xx response to INVITE. \n     * If it is, we need to send ACK.\n     */\n    if (msg->type == PJSIP_RESPONSE_MSG && msg->line.status.code/100==2 &&\n\trdata->msg_info.cseq->method.id == PJSIP_INVITE_METHOD)\n    {\n\t/* The code inside \"if\" is called the second time 200/OK\n\t * retransmission is received. Also handle the situation\n\t * when we have another re-INVITE on going and 200/OK\n\t * retransmission is received. See:\n\t * https://trac.pjsip.org/repos/ticket/1725.\n\t * Also send ACK for 200/OK of pending re-INVITE after call is\n\t * disconnected (see https://trac.pjsip.org/repos/ticket/1755).\n\t */\n\tif (inv->invite_tsx == NULL ||\n\t    inv->state == PJSIP_INV_STATE_DISCONNECTED ||\n\t    (inv->last_ack && inv->last_ack_cseq==rdata->msg_info.cseq->cseq))\n\t{\n\t    pjsip_event e;\n\n\t    PJSIP_EVENT_INIT_RX_MSG(e, rdata);\n\t    inv_send_ack(inv, &e);\n\t    return PJ_TRUE;\n\t}\n    }\n\n    /* No other processing needs to be done here. */\n    return PJ_FALSE;\n}\n\n/*\n * Module on_tsx_state()\n *\n * This callback is called by dialog framework for all transactions\n * inside the dialog for all its dialog usages.\n */\nstatic void mod_inv_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)\n{\n    pjsip_dialog *dlg;\n    pjsip_inv_session *inv;\n\n    dlg = pjsip_tsx_get_dlg(tsx);\n    if (dlg == NULL)\n\treturn;\n\n    inv = pjsip_dlg_get_inv_session(dlg);\n    if (inv == NULL)\n\treturn;\n\n    /* Call state handler for the invite session. */\n    (*inv_state_handler[inv->state])(inv, e);\n\n    /* Clear invite transaction when tsx is terminated. \n     * Necessary for app that wants to send a new re-INVITE request immediately\n     * after the transaction is terminated. \n     */\n    if (tsx->state==PJSIP_TSX_STATE_TERMINATED  && tsx == inv->invite_tsx) {\n\tinv->invite_tsx = NULL;    \n\n\tif (inv->last_answer) {\n\t\tpjsip_tx_data_dec_ref(inv->last_answer);\n\t\tinv->last_answer = NULL;\n\t}\n    }\n\n    /* Call on_tsx_state. CANCEL request is a special case and has been\n     * reported earlier in inv_respond_incoming_cancel()\n     */\n    if (mod_inv.cb.on_tsx_state_changed && inv->notify &&\n        !(tsx->method.id==PJSIP_CANCEL_METHOD &&\n          e->body.tsx_state.type==PJSIP_EVENT_RX_MSG))\n    {\n\t(*mod_inv.cb.on_tsx_state_changed)(inv, tsx, e);\n    }\n\n    /* Clear invite transaction when tsx is confirmed.\n     * Previously we set invite_tsx to NULL only when transaction has\n     * terminated, but this didn't work when ACK has the same Via branch\n     * value as the INVITE (see http://www.pjsip.org/trac/ticket/113)\n     */\n    if (tsx->state>=PJSIP_TSX_STATE_CONFIRMED && tsx == inv->invite_tsx) {\t\n\tinv->invite_tsx = NULL;\n\n\tif (inv->last_answer) {\n\t\tpjsip_tx_data_dec_ref(inv->last_answer);\n\t\tinv->last_answer = NULL;\n\t}\n    }\n}\n\n/* \n * Check if tx_data has sdp. \n */\nstatic pj_bool_t tx_data_has_sdp(const pjsip_tx_data *tdata)\n{\n    pjsip_msg_body *body = tdata->msg->body;\n    pjsip_media_type app_sdp;\n\n    PJ_ASSERT_RETURN(tdata, PJ_FALSE);\n\n    pjsip_media_type_init2(&app_sdp, \"application\", \"sdp\");\n\n    if (body &&\n\tpj_stricmp(&body->content_type.type, &app_sdp.type)==0 && \n\tpj_stricmp(&body->content_type.subtype, &app_sdp.subtype)==0) \n    {\n\treturn PJ_TRUE;\n\n    } else if (body && \n\t       pj_stricmp2(&body->content_type.type, \"multipart\") && \n\t       (pj_stricmp2(&body->content_type.subtype, \"mixed\")==0 ||\n\t        pj_stricmp2(&body->content_type.subtype, \"alternative\")==0))    \n    {\n\tpjsip_multipart_part *part;\n\n\tpart = pjsip_multipart_find_part(body, &app_sdp, NULL);\n\tif (part) {\n\t    return PJ_TRUE;\n\t}\n    }\n\n    return PJ_FALSE;\n}\n\n\n/*\n * Initialize the invite module.\n */\nPJ_DEF(pj_status_t) pjsip_inv_usage_init( pjsip_endpoint *endpt,\n\t\t\t\t\t  const pjsip_inv_callback *cb)\n{\n    pj_status_t status;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(endpt && cb, PJ_EINVAL);\n\n    /* Some callbacks are mandatory */\n    PJ_ASSERT_RETURN(cb->on_state_changed && cb->on_new_session, PJ_EINVAL);\n\n    /* Check if module already registered. */\n    PJ_ASSERT_RETURN(mod_inv.mod.id == -1, PJ_EINVALIDOP);\n\n    /* Copy param. */\n    pj_memcpy(&mod_inv.cb, cb, sizeof(pjsip_inv_callback));\n\n    mod_inv.endpt = endpt;\n\n    /* Register the module. */\n    status = pjsip_endpt_register_module(endpt, &mod_inv.mod);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get the instance of invite module.\n */\nPJ_DEF(pjsip_module*) pjsip_inv_usage_instance(void)\n{\n    return &mod_inv.mod;\n}\n\n\n\n/*\n * Return the invite session for the specified dialog.\n */\nPJ_DEF(pjsip_inv_session*) pjsip_dlg_get_inv_session(pjsip_dialog *dlg)\n{\n    return (pjsip_inv_session*) dlg->mod_data[mod_inv.mod.id];\n}\n\n\n/*\n * Get INVITE state name.\n */\nPJ_DEF(const char *) pjsip_inv_state_name(pjsip_inv_state state)\n{\n    PJ_ASSERT_RETURN(state >= PJSIP_INV_STATE_NULL && \n\t\t     state <= PJSIP_INV_STATE_DISCONNECTED,\n\t\t     \"??\");\n\n    return inv_state_names[state];\n}\n\n/*\n * Create UAC invite session.\n */\nPJ_DEF(pj_status_t) pjsip_inv_create_uac( pjsip_dialog *dlg,\n\t\t\t\t\t  const pjmedia_sdp_session *local_sdp,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t\t  pjsip_inv_session **p_inv)\n{\n    pjsip_inv_session *inv;\n    pj_status_t status;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(dlg && p_inv, PJ_EINVAL);\n\n    /* Must lock dialog first */\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Normalize options */\n    if (options & PJSIP_INV_REQUIRE_100REL)\n\toptions |= PJSIP_INV_SUPPORT_100REL;\n    if (options & PJSIP_INV_REQUIRE_TIMER)\n\toptions |= PJSIP_INV_SUPPORT_TIMER;\n\n    /* Create the session */\n    inv = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_inv_session);\n    pj_assert(inv != NULL);\n\n    inv->pool = dlg->pool;\n    inv->role = PJSIP_ROLE_UAC;\n    inv->state = PJSIP_INV_STATE_NULL;\n    inv->dlg = dlg;\n    inv->options = options;\n    inv->notify = PJ_TRUE;\n    inv->cause = (pjsip_status_code) 0;\n\n    /* Create flip-flop pool (see ticket #877) */\n    /* (using inv->obj_name as temporary variable for pool names */\n    pj_ansi_snprintf(inv->obj_name, PJ_MAX_OBJ_NAME, \"inv%p\", dlg->pool);\n    inv->pool_prov = pjsip_endpt_create_pool(dlg->endpt, inv->obj_name,\n\t\t\t\t\t     POOL_INIT_SIZE, POOL_INC_SIZE);\n    inv->pool_active = pjsip_endpt_create_pool(dlg->endpt, inv->obj_name,\n\t\t\t\t\t       POOL_INIT_SIZE, POOL_INC_SIZE);\n\n    /* Object name will use the same dialog pointer. */\n    pj_ansi_snprintf(inv->obj_name, PJ_MAX_OBJ_NAME, \"inv%p\", dlg);\n\n    /* Create negotiator if local_sdp is specified. */\n    if (local_sdp) {\n\tstatus = pjmedia_sdp_neg_create_w_local_offer(inv->pool, \n\t\t\t\t\t\t      local_sdp, &inv->neg);\n\tif (status != PJ_SUCCESS) {\n\t    pjsip_dlg_dec_lock(dlg);\n\t    return status;\n\t}\n    }\n\n    /* Register invite as dialog usage. */\n    status = pjsip_dlg_add_usage(dlg, &mod_inv.mod, inv);\n    if (status != PJ_SUCCESS) {\n\tpjsip_dlg_dec_lock(dlg);\n\treturn status;\n    }\n\n    /* Increment dialog session */\n    pjsip_dlg_inc_session(dlg, &mod_inv.mod);\n\n    /* Create 100rel handler */\n    pjsip_100rel_attach(inv);\n\n    /* Done */\n    *p_inv = inv;\n\n    pjsip_dlg_dec_lock(dlg);\n\n    PJ_LOG(5,(inv->obj_name, \"UAC invite session created for dialog %s\",\n\t      dlg->obj_name));\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata)\n{\n    pjsip_rdata_sdp_info *sdp_info;\n    pjsip_msg_body *body = rdata->msg_info.msg->body;\n    pjsip_ctype_hdr *ctype_hdr = rdata->msg_info.ctype;\n    pjsip_media_type app_sdp;\n\n    sdp_info = (pjsip_rdata_sdp_info*)\n\t       rdata->endpt_info.mod_data[mod_inv.mod.id];\n    if (sdp_info)\n\treturn sdp_info;\n\n    sdp_info = PJ_POOL_ZALLOC_T(rdata->tp_info.pool,\n\t\t\t\tpjsip_rdata_sdp_info);\n    PJ_ASSERT_RETURN(mod_inv.mod.id >= 0, sdp_info);\n    rdata->endpt_info.mod_data[mod_inv.mod.id] = sdp_info;\n\n    pjsip_media_type_init2(&app_sdp, \"application\", \"sdp\");\n\n    if (body && ctype_hdr &&\n\tpj_stricmp(&ctype_hdr->media.type, &app_sdp.type)==0 &&\n\tpj_stricmp(&ctype_hdr->media.subtype, &app_sdp.subtype)==0)\n    {\n\tsdp_info->body.ptr = (char*)body->data;\n\tsdp_info->body.slen = body->len;\n    } else if  (body && ctype_hdr &&\n\t    \tpj_stricmp2(&ctype_hdr->media.type, \"multipart\")==0 &&\n\t    \t(pj_stricmp2(&ctype_hdr->media.subtype, \"mixed\")==0 ||\n\t    \t pj_stricmp2(&ctype_hdr->media.subtype, \"alternative\")==0))\n    {\n\tpjsip_multipart_part *part;\n\n\tpart = pjsip_multipart_find_part(body, &app_sdp, NULL);\n\tif (part) {\n\t    sdp_info->body.ptr = (char*)part->body->data;\n\t    sdp_info->body.slen = part->body->len;\n\t}\n    }\n\n    if (sdp_info->body.ptr) {\n\tpj_status_t status;\n\tstatus = pjmedia_sdp_parse(rdata->tp_info.pool,\n\t\t\t\t   sdp_info->body.ptr,\n\t\t\t\t   sdp_info->body.slen,\n\t\t\t\t   &sdp_info->sdp);\n\tif (status == PJ_SUCCESS)\n\t    status = pjmedia_sdp_validate2(sdp_info->sdp, PJ_FALSE);\n\n\tif (status != PJ_SUCCESS) {\n\t    sdp_info->sdp = NULL;\n\t    PJ_PERROR(1,(THIS_FILE, status,\n\t\t\t \"Error parsing/validating SDP body\"));\n\t}\n\n\tsdp_info->sdp_err = status;\n    }\n\n    return sdp_info;\n}\n\n\n/*\n * Verify incoming INVITE request.\n */\nPJ_DEF(pj_status_t) pjsip_inv_verify_request3(pjsip_rx_data *rdata,\n                                              pj_pool_t *tmp_pool,\n\t\t\t\t\t      unsigned *options,\n\t\t\t\t\t      const pjmedia_sdp_session *r_sdp,\n\t\t\t\t\t      const pjmedia_sdp_session *l_sdp,\n\t\t\t\t\t      pjsip_dialog *dlg,\n\t\t\t\t\t      pjsip_endpoint *endpt,\n\t\t\t\t\t      pjsip_tx_data **p_tdata)\n{\n    pjsip_msg *msg = NULL;\n    pjsip_allow_hdr *allow = NULL;\n    pjsip_supported_hdr *sup_hdr = NULL;\n    pjsip_require_hdr *req_hdr = NULL;\n    pjsip_contact_hdr *c_hdr = NULL;\n    int code = 200;\n    unsigned rem_option = 0;\n    pj_status_t status = PJ_SUCCESS;\n    pjsip_hdr res_hdr_list;\n    pjsip_rdata_sdp_info *sdp_info;\n\n    /* Init return arguments. */\n    if (p_tdata) *p_tdata = NULL;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(tmp_pool != NULL && options != NULL, PJ_EINVAL);\n\n    /* Normalize options */\n    if (*options & PJSIP_INV_REQUIRE_100REL)\n\t*options |= PJSIP_INV_SUPPORT_100REL;\n    if (*options & PJSIP_INV_REQUIRE_TIMER)\n\t*options |= PJSIP_INV_SUPPORT_TIMER;\n    if (*options & PJSIP_INV_REQUIRE_ICE)\n\t*options |= PJSIP_INV_SUPPORT_ICE;\n\n    if (rdata) {\n        /* Get the message in rdata */\n        msg = rdata->msg_info.msg;\n    \n        /* Must be INVITE request. */\n        PJ_ASSERT_RETURN(msg && msg->type == PJSIP_REQUEST_MSG &&\n\t\t         msg->line.req.method.id == PJSIP_INVITE_METHOD,\n\t\t         PJ_EINVAL);\n    }\n\n    /* If tdata is specified, then either dlg or endpt must be specified */\n    PJ_ASSERT_RETURN((!p_tdata) || (endpt || dlg), PJ_EINVAL);\n\n    /* Get the endpoint */\n    endpt = endpt ? endpt : dlg->endpt;\n\n    /* Init response header list */\n    pj_list_init(&res_hdr_list);\n\n    /* Check the Contact header */\n    if (msg) {\n        c_hdr = (pjsip_contact_hdr*)\n\t        pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL);\n    }\n    if (msg && (!c_hdr || !c_hdr->uri)) {\n        /* Missing Contact header or Contact contains \"*\" */\n\tpjsip_warning_hdr *w;\n\tpj_str_t warn_text;\n\n\twarn_text = pj_str(\"Bad/missing Contact header\");\n\tw = pjsip_warning_hdr_create(tmp_pool, 399,\n\t\t\t\t     pjsip_endpt_name(endpt),\n\t\t\t\t     &warn_text);\n\tif (w) {\n\t    pj_list_push_back(&res_hdr_list, w);\n\t}\n\n\tcode = PJSIP_SC_BAD_REQUEST;\n\tstatus = PJSIP_ERRNO_FROM_SIP_STATUS(code);\n\tgoto on_return;\n    }\n\n    /* Ticket #1735: Check Contact/Record-Route header in a secure dialog. */\n    if (pjsip_cfg()->endpt.disable_secure_dlg_check == PJ_FALSE &&\n\tmsg && PJSIP_URI_SCHEME_IS_SIPS(msg->line.req.uri))\n    {\n\t/* Check Contact header */\n\tif (!PJSIP_URI_SCHEME_IS_SIPS(c_hdr->uri))\n\t    status = PJSIP_ESESSIONINSECURE;\n\n\t/* Check top Record-Route header */\n\tif (status == PJ_SUCCESS) {\n\t    pjsip_rr_hdr *r = (pjsip_rr_hdr*)\n\t\t\t      pjsip_msg_find_hdr(msg, PJSIP_H_RECORD_ROUTE,\n\t\t\t\t\t\t NULL);\n\t    if (r && !PJSIP_URI_SCHEME_IS_SIPS(&r->name_addr)) {\n\t\t/* Not \"sips\", check if it is \"sip\" and has param\n\t\t * \"transport=tls\".\n\t\t */\n\t\tif (PJSIP_URI_SCHEME_IS_SIP(&r->name_addr)) {\n\t\t    pjsip_sip_uri *sip_uri = (pjsip_sip_uri*)\n\t\t\t\t     pjsip_uri_get_uri(r->name_addr.uri);\n\t\t    if (pj_stricmp2(&sip_uri->transport_param, \"tls\")!=0)\n\t\t\tstatus = PJSIP_ESESSIONINSECURE;\n\t\t} else {\n\t\t    /* Not \"sips\" nor \"sip\", treat it as insecure? */\n\t\t    status = PJSIP_ESESSIONINSECURE;\n\t\t}\n\t    }\n\t}\n\n\tif (status != PJ_SUCCESS) {\n\t    pjsip_warning_hdr *w;\n\t    pj_str_t warn_text = pj_str(\"SIPS Required\");\n\t    w = pjsip_warning_hdr_create(tmp_pool, 381,\n\t\t\t\t\t pjsip_endpt_name(endpt),\n\t\t\t\t\t &warn_text);\n\t    if (w) {\n\t\tpj_list_push_back(&res_hdr_list, w);\n\t    }\n\t    code = PJSIP_SC_TEMPORARILY_UNAVAILABLE;\n\t    goto on_return;\n\t}\n    }\n\n    /* Check the request body, see if it's something that we support,\n     * only when the body hasn't been parsed before.\n     */\n    if (r_sdp == NULL && rdata) {\n\tsdp_info = pjsip_rdata_get_sdp_info(rdata);\n    } else {\n\tsdp_info = NULL;\n    }\n\n    if (r_sdp==NULL && msg && msg->body) {\n\n\t/* Check if body really contains SDP. */\n\tif (sdp_info->body.ptr == NULL && !PJSIP_INV_ACCEPT_UNKNOWN_BODY) {\n\t    /* Couldn't find \"application/sdp\" */\n\t    code = PJSIP_SC_UNSUPPORTED_MEDIA_TYPE;\n\t    status = PJSIP_ERRNO_FROM_SIP_STATUS(code);\n\n\t    if (p_tdata) {\n\t\t/* Add Accept header to response */\n\t\tpjsip_accept_hdr *acc;\n\n\t\tacc = pjsip_accept_hdr_create(tmp_pool);\n\t\tPJ_ASSERT_RETURN(acc, PJ_ENOMEM);\n\t\tacc->values[acc->count++] = pj_str(\"application/sdp\");\n\t\tpj_list_push_back(&res_hdr_list, acc);\n\t    }\n\n\t    goto on_return;\n\t}\n\n\tif (sdp_info->sdp_err != PJ_SUCCESS) {\n\t    /* Unparseable or invalid SDP */\n\t    code = PJSIP_SC_BAD_REQUEST;\n\n\t    if (p_tdata) {\n\t\t/* Add Warning header. */\n\t\tpjsip_warning_hdr *w;\n\n\t\tw = pjsip_warning_hdr_create_from_status(tmp_pool,\n\t\t\t\t\t\t\t pjsip_endpt_name(endpt),\n\t\t\t\t\t\t\t sdp_info->sdp_err);\n\t\tPJ_ASSERT_RETURN(w, PJ_ENOMEM);\n\n\t\tpj_list_push_back(&res_hdr_list, w);\n\t    }\n\n\t    goto on_return;\n\t}\n\n\tr_sdp = sdp_info->sdp;\n    }\n\n    if (r_sdp) {\n\t/* Negotiate with local SDP */\n\tif (l_sdp) {\n\t    pjmedia_sdp_neg *neg;\n\n\t    /* Local SDP must be valid! */\n\t    PJ_ASSERT_RETURN((status=pjmedia_sdp_validate(l_sdp))==PJ_SUCCESS,\n\t\t\t     status);\n\n\t    /* Create SDP negotiator */\n\t    status = pjmedia_sdp_neg_create_w_remote_offer(\n\t\t\t    tmp_pool, l_sdp, r_sdp, &neg);\n\t    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);\n\n\t    /* Negotiate SDP */\n\t    status = pjmedia_sdp_neg_negotiate(tmp_pool, neg, 0);\n\t    if (status != PJ_SUCCESS) {\n\n\t\t/* Incompatible media */\n\t\tcode = PJSIP_SC_NOT_ACCEPTABLE_HERE;\n\n\t\tif (p_tdata) {\n\t\t    pjsip_accept_hdr *acc;\n\t\t    pjsip_warning_hdr *w;\n\n\t\t    /* Add Warning header. */\n\t\t    w = pjsip_warning_hdr_create_from_status(\n\t\t\t\t\t    tmp_pool, \n\t\t\t\t\t    pjsip_endpt_name(endpt), status);\n\t\t    PJ_ASSERT_RETURN(w, PJ_ENOMEM);\n\n\t\t    pj_list_push_back(&res_hdr_list, w);\n\n\t\t    /* Add Accept header to response */\n\t\t    acc = pjsip_accept_hdr_create(tmp_pool);\n\t\t    PJ_ASSERT_RETURN(acc, PJ_ENOMEM);\n\t\t    acc->values[acc->count++] = pj_str(\"application/sdp\");\n\t\t    pj_list_push_back(&res_hdr_list, acc);\n\n\t\t}\n\n\t\tgoto on_return;\n\t    }\n\t}\n    }\n\n    /* Check supported methods, see if peer supports UPDATE.\n     * We just assume that peer supports standard INVITE, ACK, CANCEL, and BYE\n     * implicitly by sending this INVITE.\n     */\n    if (msg) {\n        allow = (pjsip_allow_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_ALLOW,\n                                                      NULL);\n    }\n    if (allow) {\n\tunsigned i;\n\tconst pj_str_t STR_UPDATE = { \"UPDATE\", 6 };\n\n\tfor (i=0; i<allow->count; ++i) {\n\t    if (pj_stricmp(&allow->values[i], &STR_UPDATE)==0)\n\t\tbreak;\n\t}\n\n\tif (i != allow->count) {\n\t    /* UPDATE is present in Allow */\n\t    rem_option |= PJSIP_INV_SUPPORT_UPDATE;\n\t}\n\n    }\n\n    /* Check Supported header */\n    if (msg) {\n        sup_hdr = (pjsip_supported_hdr*)\n\t          pjsip_msg_find_hdr(msg, PJSIP_H_SUPPORTED, NULL);\n    }\n    if (sup_hdr) {\n\tunsigned i;\n\tconst pj_str_t STR_100REL = { \"100rel\", 6};\n\tconst pj_str_t STR_TIMER = { \"timer\", 5};\n\tconst pj_str_t STR_ICE = { \"ice\", 3 };\n\n\tfor (i=0; i<sup_hdr->count; ++i) {\n\t    if (pj_stricmp(&sup_hdr->values[i], &STR_100REL)==0)\n\t\trem_option |= PJSIP_INV_SUPPORT_100REL;\n\t    else if (pj_stricmp(&sup_hdr->values[i], &STR_TIMER)==0)\n\t\trem_option |= PJSIP_INV_SUPPORT_TIMER;\n\t    else if (pj_stricmp(&sup_hdr->values[i], &STR_ICE)==0)\n\t\trem_option |= PJSIP_INV_SUPPORT_ICE;\n\t}\n    }\n\n    /* Check Require header */\n    if (msg) {\n        req_hdr = (pjsip_require_hdr*)\n\t          pjsip_msg_find_hdr(msg, PJSIP_H_REQUIRE, NULL);\n    }\n    if (req_hdr) {\n\tunsigned i;\n\tconst pj_str_t STR_100REL = { \"100rel\", 6};\n\tconst pj_str_t STR_REPLACES = { \"replaces\", 8 };\n\tconst pj_str_t STR_TIMER = { \"timer\", 5 };\n\tconst pj_str_t STR_ICE = { \"ice\", 3 };\n\tunsigned unsupp_cnt = 0;\n\tpj_str_t unsupp_tags[PJSIP_GENERIC_ARRAY_MAX_COUNT];\n\t\n\tfor (i=0; i<req_hdr->count; ++i) {\n\t    if ((*options & PJSIP_INV_SUPPORT_100REL) && \n\t\tpj_stricmp(&req_hdr->values[i], &STR_100REL)==0)\n\t    {\n\t\trem_option |= PJSIP_INV_REQUIRE_100REL;\n\n\t    } else if ((*options & PJSIP_INV_SUPPORT_TIMER) && \n\t\tpj_stricmp(&req_hdr->values[i], &STR_TIMER)==0)\n\t    {\n\t\trem_option |= PJSIP_INV_REQUIRE_TIMER;\n\n\t    } else if (pj_stricmp(&req_hdr->values[i], &STR_REPLACES)==0) {\n\t\tpj_bool_t supp;\n\t\t\n\t\tsupp = pjsip_endpt_has_capability(endpt, PJSIP_H_SUPPORTED, \n\t\t\t\t\t\t  NULL, &STR_REPLACES);\n\t\tif (!supp)\n\t\t    unsupp_tags[unsupp_cnt++] = req_hdr->values[i];\n\t    } else if ((*options & PJSIP_INV_SUPPORT_ICE) &&\n\t\tpj_stricmp(&req_hdr->values[i], &STR_ICE)==0)\n\t    {\n\t\trem_option |= PJSIP_INV_REQUIRE_ICE;\n\n\t    } else if (!pjsip_endpt_has_capability(endpt, PJSIP_H_SUPPORTED,\n\t\t\t\t\t\t   NULL, &req_hdr->values[i]))\n\t    {\n\t\t/* Unknown/unsupported extension tag!  */\n\t\tunsupp_tags[unsupp_cnt++] = req_hdr->values[i];\n\t    }\n\t}\n\n\t/* Check if there are required tags that we don't support */\n\tif (unsupp_cnt) {\n\n\t    code = PJSIP_SC_BAD_EXTENSION;\n\t    status = PJSIP_ERRNO_FROM_SIP_STATUS(code);\n\n\t    if (p_tdata) {\n\t\tpjsip_unsupported_hdr *unsupp_hdr;\n\t\tconst pjsip_hdr *h;\n\n\t\t/* Add Unsupported header. */\n\t\tunsupp_hdr = pjsip_unsupported_hdr_create(tmp_pool);\n\t\tPJ_ASSERT_RETURN(unsupp_hdr != NULL, PJ_ENOMEM);\n\n\t\tunsupp_hdr->count = unsupp_cnt;\n\t\tfor (i=0; i<unsupp_cnt; ++i)\n\t\t    unsupp_hdr->values[i] = unsupp_tags[i];\n\n\t\tpj_list_push_back(&res_hdr_list, unsupp_hdr);\n\n\t\t/* Add Supported header. */\n\t\th = pjsip_endpt_get_capability(endpt, PJSIP_H_SUPPORTED, \n\t\t\t\t\t       NULL);\n\t\tpj_assert(h);\n\t\tif (h) {\n\t\t    sup_hdr = (pjsip_supported_hdr*)\n\t\t\t      pjsip_hdr_clone(tmp_pool, h);\n\t\t    pj_list_push_back(&res_hdr_list, sup_hdr);\n\t\t}\n\t    }\n\n\t    goto on_return;\n\t}\n    }\n\n    /* Check if there are local requirements that are not supported\n     * by peer.\n     */\n    if ( msg && (((*options & PJSIP_INV_REQUIRE_100REL)!=0 && \n\t  (rem_option & PJSIP_INV_SUPPORT_100REL)==0) ||\n\t ((*options & PJSIP_INV_REQUIRE_TIMER)!=0 && \n\t  (rem_option & PJSIP_INV_SUPPORT_TIMER)==0)))\n    {\n\tcode = PJSIP_SC_EXTENSION_REQUIRED;\n\tstatus = PJSIP_ERRNO_FROM_SIP_STATUS(code);\n\n\tif (p_tdata) {\n\t    const pjsip_hdr *h;\n\n\t    /* Add Require header. */\n\t    req_hdr = pjsip_require_hdr_create(tmp_pool);\n\t    PJ_ASSERT_RETURN(req_hdr != NULL, PJ_ENOMEM);\n\n\t    if (*options & PJSIP_INV_REQUIRE_100REL)\n\t\treq_hdr->values[req_hdr->count++] = pj_str(\"100rel\");\n\t    if (*options & PJSIP_INV_REQUIRE_TIMER)\n\t\treq_hdr->values[req_hdr->count++] = pj_str(\"timer\");\n\n\t    pj_list_push_back(&res_hdr_list, req_hdr);\n\n\t    /* Add Supported header. */\n\t    h = pjsip_endpt_get_capability(endpt, PJSIP_H_SUPPORTED, \n\t\t\t\t\t   NULL);\n\t    pj_assert(h);\n\t    if (h) {\n\t\tsup_hdr = (pjsip_supported_hdr*)\n\t\t\t  pjsip_hdr_clone(tmp_pool, h);\n\t\tpj_list_push_back(&res_hdr_list, sup_hdr);\n\t    }\n\n\t}\n\n\tgoto on_return;\n    }\n\n    /* If remote Require something that we support, make us Require\n     * that feature too.\n     */\n    if (rem_option & PJSIP_INV_REQUIRE_100REL) {\n\t    pj_assert(*options & PJSIP_INV_SUPPORT_100REL);\n\t    *options |= PJSIP_INV_REQUIRE_100REL;\n    }\n    if (rem_option & PJSIP_INV_REQUIRE_TIMER) {\n\t    pj_assert(*options & PJSIP_INV_SUPPORT_TIMER);\n\t    *options |= PJSIP_INV_REQUIRE_TIMER;\n    }\n\non_return:\n\n    /* Create response if necessary */\n    if (code != 200 && p_tdata) {\n\tpjsip_tx_data *tdata;\n\tconst pjsip_hdr *h;\n\n        if (!rdata) {\n            return PJSIP_ERRNO_FROM_SIP_STATUS(code);\n        }\n\n\tif (dlg) {\n\t    status = pjsip_dlg_create_response(dlg, rdata, code, NULL, \n\t\t\t\t\t       &tdata);\n\t} else {\n\t    status = pjsip_endpt_create_response(endpt, rdata, code, NULL, \n\t\t\t\t\t\t &tdata);\n\t}\n\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Add response headers. */\n\th = res_hdr_list.next;\n\twhile (h != &res_hdr_list) {\n\t    pjsip_hdr *cloned;\n\n\t    cloned = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, h);\n\t    PJ_ASSERT_RETURN(cloned, PJ_ENOMEM);\n\n\t    pjsip_msg_add_hdr(tdata->msg, cloned);\n\n\t    h = h->next;\n\t}\n\n\t*p_tdata = tdata;\n\n\t/* Can not return PJ_SUCCESS when response message is produced.\n\t * Ref: PROTOS test ~#2490\n\t */\n\tif (status == PJ_SUCCESS)\n\t    status = PJSIP_ERRNO_FROM_SIP_STATUS(code);\n\n    }\n\n    return status;\n}\n\n\n/*\n * Verify incoming INVITE request.\n */\nPJ_DEF(pj_status_t) pjsip_inv_verify_request2(pjsip_rx_data *rdata,\n\t\t\t\t\t      unsigned *options,\n\t\t\t\t\t      const pjmedia_sdp_session *r_sdp,\n\t\t\t\t\t      const pjmedia_sdp_session *l_sdp,\n\t\t\t\t\t      pjsip_dialog *dlg,\n\t\t\t\t\t      pjsip_endpoint *endpt,\n\t\t\t\t\t      pjsip_tx_data **p_tdata)\n{\n    return pjsip_inv_verify_request3(rdata, rdata->tp_info.pool,\n                                     options, r_sdp, l_sdp, dlg, \n\t\t\t\t     endpt, p_tdata);\n}\n\n\n/*\n * Verify incoming INVITE request.\n */\nPJ_DEF(pj_status_t) pjsip_inv_verify_request( pjsip_rx_data *rdata,\n\t\t\t\t\t      unsigned *options,\n\t\t\t\t\t      const pjmedia_sdp_session *l_sdp,\n\t\t\t\t\t      pjsip_dialog *dlg,\n\t\t\t\t\t      pjsip_endpoint *endpt,\n\t\t\t\t\t      pjsip_tx_data **p_tdata)\n{\n    return pjsip_inv_verify_request3(rdata, rdata->tp_info.pool,\n                                     options, NULL, l_sdp, dlg, \n\t\t\t\t     endpt, p_tdata);\n}\n\n/*\n * Create UAS invite session.\n */\nPJ_DEF(pj_status_t) pjsip_inv_create_uas( pjsip_dialog *dlg,\n\t\t\t\t\t  pjsip_rx_data *rdata,\n\t\t\t\t\t  const pjmedia_sdp_session *local_sdp,\n\t\t\t\t\t  unsigned options,\n\t\t\t\t\t  pjsip_inv_session **p_inv)\n{\n    pjsip_inv_session *inv;\n    struct tsx_inv_data *tsx_inv_data;\n    pjsip_msg *msg;\n    pjsip_rdata_sdp_info *sdp_info;\n    pj_status_t status;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(dlg && rdata && p_inv, PJ_EINVAL);\n\n    /* Dialog MUST have been initialised. */\n    PJ_ASSERT_RETURN(pjsip_rdata_get_tsx(rdata) != NULL, PJ_EINVALIDOP);\n\n    msg = rdata->msg_info.msg;\n\n    /* rdata MUST contain INVITE request */\n    PJ_ASSERT_RETURN(msg->type == PJSIP_REQUEST_MSG &&\n\t\t     msg->line.req.method.id == PJSIP_INVITE_METHOD,\n\t\t     PJ_EINVALIDOP);\n\n    /* Lock dialog */\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Normalize options */\n    if (options & PJSIP_INV_REQUIRE_100REL)\n\toptions |= PJSIP_INV_SUPPORT_100REL;\n    if (options & PJSIP_INV_REQUIRE_TIMER)\n\toptions |= PJSIP_INV_SUPPORT_TIMER;\n\n    /* Create the session */\n    inv = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_inv_session);\n    pj_assert(inv != NULL);\n\n    inv->pool = dlg->pool;\n    inv->role = PJSIP_ROLE_UAS;\n    inv->state = PJSIP_INV_STATE_NULL;\n    inv->dlg = dlg;\n    inv->options = options;\n    inv->notify = PJ_TRUE;\n    inv->cause = (pjsip_status_code) 0;\n\n    /* Create flip-flop pool (see ticket #877) */\n    /* (using inv->obj_name as temporary variable for pool names */\n    pj_ansi_snprintf(inv->obj_name, PJ_MAX_OBJ_NAME, \"inv%p\", dlg->pool);\n    inv->pool_prov = pjsip_endpt_create_pool(dlg->endpt, inv->obj_name,\n\t\t\t\t\t     POOL_INIT_SIZE, POOL_INC_SIZE);\n    inv->pool_active = pjsip_endpt_create_pool(dlg->endpt, inv->obj_name,\n\t\t\t\t\t       POOL_INIT_SIZE, POOL_INC_SIZE);\n\n    /* Object name will use the same dialog pointer. */\n    pj_ansi_snprintf(inv->obj_name, PJ_MAX_OBJ_NAME, \"inv%p\", dlg);\n\n    /* Process SDP in message body, if present. */\n    sdp_info = pjsip_rdata_get_sdp_info(rdata);\n    if (sdp_info->sdp_err) {\n\tpjsip_dlg_dec_lock(dlg);\n\treturn sdp_info->sdp_err;\n    }\n\n    /* Create negotiator. */\n    if (sdp_info->sdp) {\n\tstatus = pjmedia_sdp_neg_create_w_remote_offer(inv->pool, local_sdp,\n\t\t\t\t\t\t       sdp_info->sdp,\n\t\t\t\t\t\t       &inv->neg);\n\t\t\t\t\t\t\n    } else if (local_sdp) {\n\tstatus = pjmedia_sdp_neg_create_w_local_offer(inv->pool, \n\t\t\t\t\t\t      local_sdp, &inv->neg);\n    } else {\n\tstatus = PJ_SUCCESS;\n    }\n\n    if (status != PJ_SUCCESS) {\n\tpjsip_dlg_dec_lock(dlg);\n\treturn status;\n    }\n\n    /* Register invite as dialog usage. */\n    status = pjsip_dlg_add_usage(dlg, &mod_inv.mod, inv);\n    if (status != PJ_SUCCESS) {\n\tpjsip_dlg_dec_lock(dlg);\n\treturn status;\n    }\n\n    /* Increment session in the dialog. */\n    pjsip_dlg_inc_session(dlg, &mod_inv.mod);\n\n    /* Save the invite transaction. */\n    inv->invite_tsx = pjsip_rdata_get_tsx(rdata);\n\n    /* Attach our data to the transaction. */\n    tsx_inv_data = PJ_POOL_ZALLOC_T(inv->invite_tsx->pool, struct tsx_inv_data);\n    tsx_inv_data->inv = inv;\n    tsx_inv_data->has_sdp = (sdp_info->sdp!=NULL);\n    inv->invite_tsx->mod_data[mod_inv.mod.id] = tsx_inv_data;\n\n    /* Create 100rel handler */\n    if (inv->options & PJSIP_INV_REQUIRE_100REL) {\n\tpjsip_100rel_attach(inv);\n    }\n\n    /* Done */\n    pjsip_dlg_dec_lock(dlg);\n    *p_inv = inv;\n\n    PJ_LOG(5,(inv->obj_name, \"UAS invite session created for dialog %s\",\n\t      dlg->obj_name));\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Forcefully terminate the session.\n */\nPJ_DEF(pj_status_t) pjsip_inv_terminate( pjsip_inv_session *inv,\n\t\t\t\t         int st_code,\n\t\t\t\t\t pj_bool_t notify)\n{\n    PJ_ASSERT_RETURN(inv, PJ_EINVAL);\n\n    /* Lock dialog. */\n    pjsip_dlg_inc_lock(inv->dlg);\n\n    /* Set callback notify flag. */\n    inv->notify = notify;\n\n    /* If there's pending transaction, terminate the transaction. \n     * This may subsequently set the INVITE session state to\n     * disconnected.\n     */\n    if (inv->invite_tsx && \n\tinv->invite_tsx->state <= PJSIP_TSX_STATE_COMPLETED)\n    {\n\tpjsip_tsx_terminate(inv->invite_tsx, st_code);\n\n    }\n\n    /* Set cause. */\n    inv_set_cause(inv, st_code, NULL);\n\n    /* Forcefully terminate the session if state is not DISCONNECTED */\n    if (inv->state != PJSIP_INV_STATE_DISCONNECTED) {\n\tpjsip_event usr_event;\n\n\tPJSIP_EVENT_INIT_USER(usr_event, NULL, NULL, NULL, NULL);\n\tinv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, &usr_event);\n    }\n\n    /* Done.\n     * The dec_lock() below will actually destroys the dialog if it\n     * has no other session.\n     */\n    pjsip_dlg_dec_lock(inv->dlg);\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Restart UAC session, possibly because app or us wants to re-send the \n * INVITE request due to 401/407 challenge or 3xx response.\n */\nPJ_DEF(pj_status_t) pjsip_inv_uac_restart(pjsip_inv_session *inv,\n\t\t\t\t\t  pj_bool_t new_offer)\n{\n    PJ_ASSERT_RETURN(inv, PJ_EINVAL);\n\n    inv->state = PJSIP_INV_STATE_NULL;\n    inv->invite_tsx = NULL;\n    if (inv->last_answer) {\n\tpjsip_tx_data_dec_ref(inv->last_answer);\n\tinv->last_answer = NULL;\n    }\n\n    if (new_offer && inv->neg) {\n\tpjmedia_sdp_neg_state neg_state;\n\n\tneg_state = pjmedia_sdp_neg_get_state(inv->neg);\n\tif (neg_state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) {\n\t    pjmedia_sdp_neg_cancel_offer(inv->neg);\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nstatic void *clone_sdp(pj_pool_t *pool, const void *data, unsigned len)\n{\n    PJ_UNUSED_ARG(len);\n    return pjmedia_sdp_session_clone(pool, (const pjmedia_sdp_session*)data);\n}\n\nstatic int print_sdp(pjsip_msg_body *body, char *buf, pj_size_t len)\n{\n    return pjmedia_sdp_print((const pjmedia_sdp_session*)body->data, buf, len);\n}\n\n\nPJ_DEF(pj_status_t) pjsip_create_sdp_body( pj_pool_t *pool,\n\t\t\t\t\t   pjmedia_sdp_session *sdp,\n\t\t\t\t\t   pjsip_msg_body **p_body)\n{\n    const pj_str_t STR_APPLICATION = { \"application\", 11};\n    const pj_str_t STR_SDP = { \"sdp\", 3 };\n    pjsip_msg_body *body;\n\n    body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body);\n    PJ_ASSERT_RETURN(body != NULL, PJ_ENOMEM);\n\n    pjsip_media_type_init(&body->content_type, (pj_str_t*)&STR_APPLICATION,\n\t\t\t  (pj_str_t*)&STR_SDP);\n    body->data = sdp;\n    body->len = 0;\n    body->clone_data = &clone_sdp;\n    body->print_body = &print_sdp;\n\n    *p_body = body;\n\n    return PJ_SUCCESS;\n}\n\nstatic pjsip_msg_body *create_sdp_body(pj_pool_t *pool,\n\t\t\t\t       const pjmedia_sdp_session *c_sdp)\n{\n    pjsip_msg_body *body;\n    pj_status_t status;\n\n    status = pjsip_create_sdp_body(pool, \n\t\t\t\t   pjmedia_sdp_session_clone(pool, c_sdp),\n\t\t\t\t   &body);\n\n    if (status != PJ_SUCCESS)\n\treturn NULL;\n\n    return body;\n}\n\n/* Utility to remove a string value from generic array header */\nstatic void remove_val_from_array_hdr(pjsip_generic_array_hdr *arr_hdr,\n\t\t\t\t      const pj_str_t *val)\n{\n    unsigned i;\n    for (i=0; i<arr_hdr->count; ++i) {\n\tif (pj_stricmp(&arr_hdr->values[i], val)==0) {\n\t    pj_array_erase(arr_hdr->values, sizeof(arr_hdr->values[0]),\n\t\t\t   arr_hdr->count, i);\n\t    --arr_hdr->count;\n\t    break;\n\t}\n    }\n}\n\n\n/* Remove disabled extensions, e.g: timer & 100rel, from Allow/Supported\n * headers (see ticket #1858).\n */\nstatic void cleanup_allow_sup_hdr(unsigned inv_option,\n\t\t\t\t  pjsip_tx_data *tdata,\n\t\t\t\t  pjsip_allow_hdr *allow_hdr,\n\t\t\t\t  pjsip_supported_hdr *sup_hdr)\n{\n    /* If all extensions are enabled, nothing to do */\n    if ((inv_option & PJSIP_INV_SUPPORT_100REL) &&\n\t(inv_option & PJSIP_INV_SUPPORT_TIMER))\n    {\n\treturn;\n    }\n\n    if (!allow_hdr && tdata) {\n\tallow_hdr = (pjsip_allow_hdr*) pjsip_msg_find_hdr(tdata->msg,\n\t\t\t\t\t\t\t  PJSIP_H_ALLOW,\n\t\t\t\t\t\t\t  NULL);\n    }\n    if (!sup_hdr && tdata) {\n\tsup_hdr = (pjsip_supported_hdr*) pjsip_msg_find_hdr(tdata->msg,\n\t\t\t\t\t\t\t    PJSIP_H_SUPPORTED,\n\t\t\t\t\t\t\t    NULL);\n    }\n\n    /* Remove \"timer\" from Supported header if Session-Timers is\n     * disabled (https://trac.pjsip.org/repos/ticket/1761)\n     */\n    if ((inv_option & PJSIP_INV_SUPPORT_TIMER) == 0 && sup_hdr) {\n\tconst pj_str_t STR_TIMER = { \"timer\", 5 };\n\tremove_val_from_array_hdr(sup_hdr, &STR_TIMER);\n    }\n\n    if ((inv_option & PJSIP_INV_SUPPORT_100REL) == 0) {\n\tconst pj_str_t STR_PRACK  = { \"PRACK\", 5 };\n\tconst pj_str_t STR_100REL = { \"100rel\", 6 };\n\n\tif (allow_hdr)\n\t    remove_val_from_array_hdr(allow_hdr, &STR_PRACK);\n\tif (sup_hdr)\n\t    remove_val_from_array_hdr(sup_hdr, &STR_100REL);\n    }\n}\n\n/*\n * Create initial INVITE request.\n */\nPJ_DEF(pj_status_t) pjsip_inv_invite( pjsip_inv_session *inv,\n\t\t\t\t      pjsip_tx_data **p_tdata )\n{\n    pjsip_tx_data *tdata;\n    const pjsip_hdr *hdr;\n    pjsip_allow_hdr *allow_hdr = NULL;\n    pjsip_supported_hdr *sup_hdr = NULL;\n    pj_bool_t has_sdp;\n    pj_status_t status;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(inv && p_tdata, PJ_EINVAL);\n\n    /* State MUST be NULL or CONFIRMED. */\n    PJ_ASSERT_RETURN(inv->state == PJSIP_INV_STATE_NULL ||\n\t\t     inv->state == PJSIP_INV_STATE_CONFIRMED, \n\t\t     PJ_EINVALIDOP);\n\n    /* Lock dialog. */\n    pjsip_dlg_inc_lock(inv->dlg);\n\n    /* Create the INVITE request. */\n    status = pjsip_dlg_create_request(inv->dlg, pjsip_get_invite_method(), -1,\n\t\t\t\t      &tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n\n    /* If this is the first INVITE, then copy the headers from inv_hdr.\n     * These are the headers parsed from the request URI when the\n     * dialog was created.\n     */\n    if (inv->state == PJSIP_INV_STATE_NULL) {\n\thdr = inv->dlg->inv_hdr.next;\n\n\twhile (hdr != &inv->dlg->inv_hdr) {\n\t    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)\n\t\t\t      pjsip_hdr_shallow_clone(tdata->pool, hdr));\n\t    hdr = hdr->next;\n\t}\n    }\n\n    /* See if we have SDP to send. */\n    if (inv->neg) {\n\tpjmedia_sdp_neg_state neg_state;\n\n\tneg_state = pjmedia_sdp_neg_get_state(inv->neg);\n\n\thas_sdp = (neg_state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER ||\n\t\t   (neg_state == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO &&\n\t\t    pjmedia_sdp_neg_has_local_answer(inv->neg)));\n\n\n    } else {\n\thas_sdp = PJ_FALSE;\n    }\n\n    /* Add SDP, if any. */\n    if (has_sdp) {\n\tconst pjmedia_sdp_session *offer;\n\n\tstatus = pjmedia_sdp_neg_get_neg_local(inv->neg, &offer);\n\tif (status != PJ_SUCCESS) {\n\t    pjsip_tx_data_dec_ref(tdata);\n\t    goto on_return;\n\t}\n\n\ttdata->msg->body = create_sdp_body(tdata->pool, offer);\n    }\n\n    /* Add Allow header. */\n    if (inv->dlg->add_allow) {\n\thdr = pjsip_endpt_get_capability(inv->dlg->endpt, PJSIP_H_ALLOW, NULL);\n\tif (hdr) {\n\t    allow_hdr = (pjsip_allow_hdr*)\n\t\t\tpjsip_hdr_shallow_clone(tdata->pool, hdr);\n\t    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)allow_hdr);\n\t}\n    }\n\n    /* Add Supported header */\n    hdr = pjsip_endpt_get_capability(inv->dlg->endpt, PJSIP_H_SUPPORTED, NULL);\n    if (hdr) {\n\tsup_hdr = (pjsip_supported_hdr*)\n\t\t   pjsip_hdr_shallow_clone(tdata->pool, hdr);\n\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)sup_hdr);\n    }\n\n    /* Cleanup Allow & Supported headers from disabled extensions */\n    cleanup_allow_sup_hdr(inv->options, NULL, allow_hdr, sup_hdr);\n\n    /* Add Require header. */\n    if ((inv->options & PJSIP_INV_REQUIRE_100REL) ||\n\t(inv->options & PJSIP_INV_REQUIRE_TIMER)) \n    {\n\tpjsip_require_hdr *hreq;\n\n\threq = pjsip_require_hdr_create(tdata->pool);\n\n\tif (inv->options & PJSIP_INV_REQUIRE_100REL)\n\t    hreq->values[hreq->count++] = pj_str(\"100rel\");\n\tif (inv->options & PJSIP_INV_REQUIRE_TIMER)\n\t    hreq->values[hreq->count++] = pj_str(\"timer\");\n\n\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) hreq);\n    }\n\n    status = pjsip_timer_update_req(inv, tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Done. */\n    *p_tdata = tdata;\n\n\non_return:\n    pjsip_dlg_dec_lock(inv->dlg);\n    return status;\n}\n\n\n/* Util: swap pool */\nstatic void swap_pool(pj_pool_t **p1, pj_pool_t **p2)\n{\n    pj_pool_t *tmp = *p1;\n    *p1 = *p2;\n    *p2 = tmp;\n}\n\n\n/*\n * Initiate SDP negotiation in the SDP negotiator.\n */\nstatic pj_status_t inv_negotiate_sdp( pjsip_inv_session *inv )\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(pjmedia_sdp_neg_get_state(inv->neg) ==\n\t\t     PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, \n\t\t     PJMEDIA_SDPNEG_EINSTATE);\n\n    status = pjmedia_sdp_neg_negotiate(inv->pool_prov, inv->neg, 0);\n\n    PJ_LOG(5,(inv->obj_name, \"SDP negotiation done, status=%d\", status));\n\n    if (mod_inv.cb.on_media_update && inv->notify)\n\t(*mod_inv.cb.on_media_update)(inv, status);\n\n    /* Invite session may have been terminated by the application even \n     * after a successful SDP negotiation, for example when no audio \n     * codec is present in the offer (see ticket #1034).\n     */\n    if (inv->state != PJSIP_INV_STATE_DISCONNECTED) {\n\n\t/* Swap the flip-flop pool when SDP negotiation success. */\n\tif (status == PJ_SUCCESS) {\n\t    swap_pool(&inv->pool_prov, &inv->pool_active);\n\t}\n\n\t/* Reset the provisional pool regardless SDP negotiation result. */\n\tpj_pool_reset(inv->pool_prov);\n\n    } else {\n\n\tstatus = PJSIP_ERRNO_FROM_SIP_STATUS(inv->cause);\n    }\n\n    return status;\n}\n\n/*\n * Check in incoming message for SDP offer/answer.\n */\nstatic pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,\n\t\t\t\t\t\t  pjsip_transaction *tsx,\n\t\t\t\t\t\t  pjsip_rx_data *rdata)\n{\n    struct tsx_inv_data *tsx_inv_data;\n    pj_status_t status;\n    pjsip_msg *msg;\n    pjsip_rdata_sdp_info *sdp_info;\n\n    /* Check if SDP is present in the message. */\n\n    msg = rdata->msg_info.msg;\n    if (msg->body == NULL) {\n\t/* Message doesn't have body. */\n\treturn PJ_SUCCESS;\n    }\n\n    sdp_info = pjsip_rdata_get_sdp_info(rdata);\n    if (sdp_info->body.ptr == NULL) {\n\t/* Message body is not \"application/sdp\" */\n\treturn PJMEDIA_SDP_EINSDP;\n    }\n\n    /* Only accept SDP in INVITE, UPDATE and ACK requests, 18x (reliable) and 183 provisional responses\n     * and 200 final response.\n     */\n    if (!(msg->type == PJSIP_REQUEST_MSG && msg->line.req.method.id == PJSIP_INVITE_METHOD) &&\n        !(msg->type == PJSIP_REQUEST_MSG && msg->line.req.method.id == PJSIP_ACK_METHOD) &&\n        !(msg->type == PJSIP_REQUEST_MSG && pjsip_method_cmp(&msg->line.req.method, &pjsip_update_method)==0) &&\n        !(msg->type == PJSIP_RESPONSE_MSG && msg->line.status.code/10==18 && pjsip_100rel_is_reliable(rdata)) &&\n        !(msg->type == PJSIP_RESPONSE_MSG && msg->line.status.code == 183) &&\n        !(msg->type == PJSIP_RESPONSE_MSG && msg->line.status.code == 200)) {\n\t    PJ_LOG(4,(inv->obj_name, \"ignored SDP body\"));\n        return PJ_SUCCESS;\n    }\n\n    /* Get/attach invite session's transaction data */\n    tsx_inv_data = (struct tsx_inv_data*) tsx->mod_data[mod_inv.mod.id];\n    if (tsx_inv_data == NULL) {\n\ttsx_inv_data = PJ_POOL_ZALLOC_T(tsx->pool, struct tsx_inv_data);\n\ttsx_inv_data->inv = inv;\n\ttsx_inv_data->has_sdp = (sdp_info->sdp!=NULL);\n\ttsx->mod_data[mod_inv.mod.id] = tsx_inv_data;\n    }\n\n    /* Initialize info that we are following forked media */\n    inv->following_fork = PJ_FALSE;\n\n    /* MUST NOT do multiple SDP offer/answer in a single transaction,\n     * EXCEPT if:\n     *\t- this is an initial UAC INVITE transaction (i.e. not re-INVITE), and\n     *\t- the previous negotiation was done on an early media (18x) and\n     *    this response is a final/2xx response, and\n     *  - the 2xx response has different To tag than the 18x response\n     *    (i.e. the request has forked).\n     *\n     * The exception above is to add a rudimentary support for early media\n     * forking (sample case: custom ringback). See this ticket for more\n     * info: http://trac.pjsip.org/repos/ticket/657\n     */\n    if (tsx_inv_data->sdp_done) {\n\tpj_str_t res_tag;\n\tint st_code;\n\n\tres_tag = rdata->msg_info.to->tag;\n\tst_code = rdata->msg_info.msg->line.status.code;\n\n\t/* Allow final/early response after SDP has been negotiated in early\n\t * media, IF this response is a final/early response with different\n\t * tag.\n         * See ticket #1644 and #1764 for forked early media case.\n\t */\n\tif (tsx->role == PJSIP_ROLE_UAC &&\n\t    (st_code/100 == 2 ||\n\t     (st_code/10 == 18 /* st_code == 18x */\n              && pjsip_cfg()->endpt.follow_early_media_fork)) &&\n\t    tsx_inv_data->done_early &&\n\t    pj_stricmp(&tsx_inv_data->done_tag, &res_tag))\n\t{\n\t    const pjmedia_sdp_session *reoffer_sdp = NULL;\n\n\t    PJ_LOG(4,(inv->obj_name, \"Received forked %s response \"\n\t\t      \"after SDP negotiation has been done in early \"\n\t\t      \"media. Renegotiating SDP..\",\n\t\t      (st_code/10==18? \"early\" : \"final\" )));\n\n\t    /* Retrieve original SDP offer from INVITE request */\n\t    reoffer_sdp = (const pjmedia_sdp_session*) \n\t\t\t  tsx->last_tx->msg->body->data;\n\n\t    /* Feed the original offer to negotiator */\n\t    status = pjmedia_sdp_neg_modify_local_offer2(inv->pool_prov, \n\t\t\t\t\t\t\t inv->neg,\n                                                         inv->sdp_neg_flags,\n\t\t\t\t\t\t         reoffer_sdp);\n\t    if (status != PJ_SUCCESS) {\n\t\tPJ_LOG(1,(inv->obj_name, \"Error updating local offer for \"\n\t\t\t  \"forked 2xx/18x response (err=%d)\", status));\n\t\treturn status;\n\t    }\n\n\t    inv->following_fork = PJ_TRUE;\n\n\t} else {\n\n\t    if (rdata->msg_info.msg->body) {\n\t\tPJ_LOG(4,(inv->obj_name, \"SDP negotiation done, message \"\n\t\t\t  \"body is ignored\"));\n\t    }\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    /* Process the SDP body. */\n    if (sdp_info->sdp_err) {\n\tPJ_PERROR(4,(THIS_FILE, sdp_info->sdp_err,\n\t\t     \"Error parsing SDP in %s\",\n\t\t     pjsip_rx_data_get_info(rdata)));\n\treturn PJMEDIA_SDP_EINSDP;\n    }\n\n    pj_assert(sdp_info->sdp != NULL);\n\n    /* The SDP can be an offer or answer, depending on negotiator's state */\n\n    if (inv->neg == NULL ||\n\tpjmedia_sdp_neg_get_state(inv->neg) == PJMEDIA_SDP_NEG_STATE_DONE) \n    {\n\n\t/* This is an offer. */\n\n\tPJ_LOG(5,(inv->obj_name, \"Got SDP offer in %s\", \n\t\t  pjsip_rx_data_get_info(rdata)));\n\n\tif (inv->neg == NULL) {\n\t    status=pjmedia_sdp_neg_create_w_remote_offer(inv->pool, NULL,\n\t\t\t\t\t\t\t sdp_info->sdp,\n\t\t\t\t\t\t\t &inv->neg);\n\t} else {\n\t    status=pjmedia_sdp_neg_set_remote_offer(inv->pool_prov, inv->neg, \n\t\t\t\t\t\t    sdp_info->sdp);\n\t}\n\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(THIS_FILE, status, \"Error processing SDP offer in %\",\n\t\t      pjsip_rx_data_get_info(rdata)));\n\t    return PJMEDIA_SDP_EINSDP;\n\t}\n\n\t/* Inform application about remote offer. */\n\tif (mod_inv.cb.on_rx_offer && inv->notify) {\n\n\t    (*mod_inv.cb.on_rx_offer)(inv, sdp_info->sdp);\n\n\t}\n\n\t/* application must have supplied an answer at this point. */\n\tif (pjmedia_sdp_neg_get_state(inv->neg) !=\n\t\tPJMEDIA_SDP_NEG_STATE_WAIT_NEGO)\n\t{\n            if (mod_inv.cb.on_rx_reinvite && inv->notify &&\n                msg->type == PJSIP_REQUEST_MSG &&\n                msg->line.req.method.id == PJSIP_INVITE_METHOD)\n            {\n                /* Do not return failure first, allow the application\n                 * to set the answer in the on_rx_reinvite() callback.\n                 */\n        \tPJ_LOG(5,(inv->obj_name, \"Ignoring on_rx_offer() status \"\n        \t\t  \"because on_rx_reinvite() is implemented\"));\n                return PJ_SUCCESS;\n            }\n\t    return PJ_EINVALIDOP;\n\t}\n\n    } else if (pjmedia_sdp_neg_get_state(inv->neg) == \n\t\tPJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) \n    {\n\tint status_code;\n\n\t/* This is an answer. \n\t * Process and negotiate remote answer.\n\t */\n\n\tPJ_LOG(5,(inv->obj_name, \"Got SDP answer in %s\", \n\t\t  pjsip_rx_data_get_info(rdata)));\n\n\tstatus = pjmedia_sdp_neg_set_remote_answer(inv->pool_prov, inv->neg,\n\t\t\t\t\t\t   sdp_info->sdp);\n\n\tif (status != PJ_SUCCESS) {\n\t    PJ_PERROR(4,(THIS_FILE, status, \"Error processing SDP answer in %s\",\n\t\t      pjsip_rx_data_get_info(rdata)));\n\t    return PJMEDIA_SDP_EINSDP;\n\t}\n\n\t/* Negotiate SDP */\n\n\tinv_negotiate_sdp(inv);\n\n\t/* Mark this transaction has having SDP offer/answer done, and\n\t * save the reference to the To tag\n\t */\n\n\ttsx_inv_data->sdp_done = 1;\n\tstatus_code = rdata->msg_info.msg->line.status.code;\n\ttsx_inv_data->done_early = (status_code/100==1);\n\tpj_strdup(tsx->pool, &tsx_inv_data->done_tag, \n\t\t  &rdata->msg_info.to->tag);\n\n    } else {\n\t\n\tPJ_LOG(5,(THIS_FILE, \"Ignored SDP in %s: negotiator state is %s\",\n\t      pjsip_rx_data_get_info(rdata), \n\t      pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_get_state(inv->neg))));\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Process INVITE answer, for both initial and subsequent re-INVITE\n */\nstatic pj_status_t process_answer( pjsip_inv_session *inv,\n\t\t\t\t   int st_code,\n\t\t\t\t   pjsip_tx_data *tdata,\n\t\t\t\t   const pjmedia_sdp_session *local_sdp)\n{\n    pj_status_t status;\n    const pjmedia_sdp_session *sdp = NULL;\n\n    /* If local_sdp is specified, then we MUST NOT have answered the\n     * offer before. \n     */\n    if (local_sdp && (st_code/100==1 || st_code/100==2)) {\n\n\tif (inv->neg == NULL) {\n\t    status = pjmedia_sdp_neg_create_w_local_offer(inv->pool, \n\t\t\t\t\t\t\t  local_sdp,\n\t\t\t\t\t\t\t  &inv->neg);\n\t} else if (pjmedia_sdp_neg_get_state(inv->neg)==\n\t\t   PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER)\n\t{\n\t    status = pjmedia_sdp_neg_set_local_answer(inv->pool_prov, inv->neg,\n\t\t\t\t\t\t      local_sdp);\n\t} else if (pjmedia_sdp_neg_get_state(inv->neg)==\n\t\t   PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER)\n\t{\n\t    /* Go forward with our local offer */\n\t    status = PJ_SUCCESS;\n\t} else {\n\n\t    /* Can not specify local SDP at this state. */\n\t    pj_assert(0);\n\t    status = PJMEDIA_SDPNEG_EINSTATE;\n\t}\n\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n    }\n\n\n     /* If SDP negotiator is ready, start negotiation. */\n    if (st_code/100==2 || (st_code/10==18 && st_code!=180 && st_code!=181)) {\n\n\tpjmedia_sdp_neg_state neg_state;\n\n\t/* Start nego when appropriate. */\n\tneg_state = inv->neg ? pjmedia_sdp_neg_get_state(inv->neg) :\n\t\t    PJMEDIA_SDP_NEG_STATE_NULL;\n\n\tif (neg_state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) {\n\n\t    status = pjmedia_sdp_neg_get_neg_local(inv->neg, &sdp);\n\n\t} else if (neg_state == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO &&\n\t\t   pjmedia_sdp_neg_has_local_answer(inv->neg) )\n\t{\n\t    struct tsx_inv_data *tsx_inv_data;\n\n\t    /* Get invite session's transaction data */\n\t    tsx_inv_data = (struct tsx_inv_data*) \n\t\t           inv->invite_tsx->mod_data[mod_inv.mod.id];\n\n\t    status = inv_negotiate_sdp(inv);\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\t    \n\t    /* Mark this transaction has having SDP offer/answer done. */\n\t    tsx_inv_data->sdp_done = 1;\n\n\t    status = pjmedia_sdp_neg_get_active_local(inv->neg, &sdp);\n\t}\n    }\n\n    /* Include SDP when it's available for 2xx and 18x (but not 180 and 181)\n     * response. Subsequent response will include this SDP.\n     *\n     * Note note:\n     *\t- When offer/answer has been completed in reliable 183, we MUST NOT\n     *\t  send SDP in 2xx response. So if we don't have SDP to send, clear\n     *\t  the SDP in the message body ONLY if 100rel is active in this \n     *    session.\n     */\n    if (sdp) {\n\ttdata->msg->body = create_sdp_body(tdata->pool, sdp);\n    } else {\n\tif (inv->options & PJSIP_INV_REQUIRE_100REL) {\n\t    tdata->msg->body = NULL;\n\t}\n    }\n\n    /* Cancel SDP negotiation if this is a negative reply to a re-INVITE */\n    if (st_code >= 300 && inv->neg != NULL &&\n        inv->state == PJSIP_INV_STATE_CONFIRMED)\n    {\n        pjmedia_sdp_neg_state neg_state;\n        neg_state = pjmedia_sdp_neg_get_state(inv->neg);\n        if (neg_state == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER) {\n            pjmedia_sdp_neg_cancel_offer(inv->neg);\n        }\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create first response to INVITE\n */\nPJ_DEF(pj_status_t) pjsip_inv_initial_answer(\tpjsip_inv_session *inv,\n\t\t\t\t\t\tpjsip_rx_data *rdata,\n\t\t\t\t\t\tint st_code,\n\t\t\t\t\t\tconst pj_str_t *st_text,\n\t\t\t\t\t\tconst pjmedia_sdp_session *sdp,\n\t\t\t\t\t\tpjsip_tx_data **p_tdata)\n{\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n    pjsip_status_code st_code2;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(inv && p_tdata, PJ_EINVAL);\n\n    /* Must have INVITE transaction. */\n    PJ_ASSERT_RETURN(inv->invite_tsx, PJ_EBUG);\n\n    pj_log_push_indent();\n\n    pjsip_dlg_inc_lock(inv->dlg);\n\n    /* Create response */\n    status = pjsip_dlg_create_response(inv->dlg, rdata, st_code, st_text,\n\t\t\t\t       &tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Invoke Session Timers module */\n    status = pjsip_timer_process_req(inv, rdata, &st_code2);\n    if (status != PJ_SUCCESS) {\n\tpj_status_t status2;\n\n\tstatus2 = pjsip_dlg_modify_response(inv->dlg, tdata, st_code2, NULL);\n\tif (status2 != PJ_SUCCESS) {\n\t    pjsip_tx_data_dec_ref(tdata);\n\t    goto on_return;\n\t}\n\tstatus2 = pjsip_timer_update_resp(inv, tdata);\n\tif (status2 == PJ_SUCCESS)\n\t    *p_tdata = tdata;\n\telse\n\t    pjsip_tx_data_dec_ref(tdata);\n\n\tgoto on_return;\n    }\n\n    /* Process SDP in answer */\n    status = process_answer(inv, st_code, tdata, sdp);\n    if (status != PJ_SUCCESS) {\n\tpjsip_tx_data_dec_ref(tdata);\n\tgoto on_return;\n    }\n\n    /* Cleanup Allow & Supported headers from disabled extensions */\n    cleanup_allow_sup_hdr(inv->options, tdata, NULL, NULL);\n\n    /* Save this answer */\n    inv->last_answer = tdata;\n    pjsip_tx_data_add_ref(inv->last_answer);\n    PJ_LOG(5,(inv->dlg->obj_name, \"Initial answer %s\",\n\t      pjsip_tx_data_get_info(inv->last_answer)));\n\n    /* Invoke Session Timers */\n    pjsip_timer_update_resp(inv, tdata);\n\n    *p_tdata = tdata;\n\non_return:\n    pjsip_dlg_dec_lock(inv->dlg);\n    pj_log_pop_indent();\n    return status;\n}\n\n\n/*\n * Answer INVITE request.\n */ \nPJ_DEF(pj_status_t) pjsip_inv_answer(\tpjsip_inv_session *inv,\n\t\t\t\t\tint st_code,\n\t\t\t\t\tconst pj_str_t *st_text,\n\t\t\t\t\tconst pjmedia_sdp_session *local_sdp,\n\t\t\t\t\tpjsip_tx_data **p_tdata )\n{\n    pjsip_tx_data *last_res;\n    pj_status_t status;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(inv && p_tdata, PJ_EINVAL);\n\n    /* Must have INVITE transaction. */\n    PJ_ASSERT_RETURN(inv->invite_tsx, PJ_EBUG);\n\n    /* Must have created an answer before */\n    PJ_ASSERT_RETURN(inv->last_answer, PJ_EINVALIDOP);\n\n    pj_log_push_indent();\n\n    pjsip_dlg_inc_lock(inv->dlg);\n\n    /* Modify last response. */\n    last_res = inv->last_answer;\n    status = pjsip_dlg_modify_response(inv->dlg, last_res, st_code, st_text);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* For non-2xx final response, strip message body */\n    if (st_code >= 300) {\n\tlast_res->msg->body = NULL;\n    }\n\n    /* Process SDP in answer */\n    status = process_answer(inv, st_code, last_res, local_sdp);\n    if (status != PJ_SUCCESS) {\n\tpjsip_tx_data_dec_ref(last_res);\n\tgoto on_return;\n    }\n\n    /* Invoke Session Timers */\n    pjsip_timer_update_resp(inv, last_res);\n\n    /* Cleanup Allow & Supported headers from disabled extensions */\n    cleanup_allow_sup_hdr(inv->options, last_res, NULL, NULL);\n\n    *p_tdata = last_res;\n\non_return:\n    pjsip_dlg_dec_lock(inv->dlg);\n    pj_log_pop_indent();\n    return status;\n}\n\n\n/*\n * Set local SDP offer/answer.\n */\nPJ_DEF(pj_status_t) pjsip_inv_set_local_sdp(pjsip_inv_session *inv,\n\t\t\t\t\t    const pjmedia_sdp_session *sdp )\n{\n    const pjmedia_sdp_session *offer;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(inv && sdp, PJ_EINVAL);\n\n    /* If we have remote SDP offer, set local answer to respond to the offer,\n     * otherwise we set/modify our local offer (and create an SDP negotiator\n     * if we don't have one yet).\n     */\n    if (inv->neg) {\n        pjmedia_sdp_neg_state neg_state = pjmedia_sdp_neg_get_state(inv->neg);\n\n        if ((neg_state == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER ||\n\t     neg_state == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) &&\n            pjmedia_sdp_neg_get_neg_remote(inv->neg, &offer) == PJ_SUCCESS)\n        {\n            status = pjsip_inv_set_sdp_answer(inv, sdp);\n        }  else if (neg_state == PJMEDIA_SDP_NEG_STATE_DONE) {\n            status = pjmedia_sdp_neg_modify_local_offer2(inv->pool, inv->neg,\n                                                         inv->sdp_neg_flags,\n                                                         sdp);\n        } else\n            return PJMEDIA_SDPNEG_EINSTATE;\n    } else {\n\tstatus = pjmedia_sdp_neg_create_w_local_offer(inv->pool, \n\t\t\t\t\t\t      sdp, &inv->neg);\n    }\n\n    return status;\n}\n\n\n/*\n * Set SDP answer.\n */\nPJ_DEF(pj_status_t) pjsip_inv_set_sdp_answer( pjsip_inv_session *inv,\n\t\t\t\t\t      const pjmedia_sdp_session *sdp )\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(inv && sdp, PJ_EINVAL);\n\n    pjsip_dlg_inc_lock(inv->dlg);\n    status = pjmedia_sdp_neg_set_local_answer( inv->pool_prov, inv->neg, sdp);\n    pjsip_dlg_dec_lock(inv->dlg);\n\n    return status;\n}\n\n\n/*\n * End session.\n */\nPJ_DEF(pj_status_t) pjsip_inv_end_session(  pjsip_inv_session *inv,\n\t\t\t\t\t    int st_code,\n\t\t\t\t\t    const pj_str_t *st_text,\n\t\t\t\t\t    pjsip_tx_data **p_tdata )\n{\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(inv && p_tdata, PJ_EINVAL);\n\n    pj_log_push_indent();\n\n    /* Set cause code. */\n    inv_set_cause(inv, st_code, st_text);\n\n    /* Create appropriate message. */\n    switch (inv->state) {\n    case PJSIP_INV_STATE_CALLING:\n    case PJSIP_INV_STATE_EARLY:\n    case PJSIP_INV_STATE_INCOMING:\n\n\tif (inv->role == PJSIP_ROLE_UAC) {\n\n\t    /* For UAC when session has not been confirmed, create CANCEL. */\n\n\t    /* MUST have the original UAC INVITE transaction. */\n\t    PJ_ASSERT_RETURN(inv->invite_tsx != NULL, PJ_EBUG);\n\n\t    /* But CANCEL should only be called when we have received a\n\t     * provisional response. If we haven't received any responses,\n\t     * just destroy the transaction.\n\t     */\n\t    if (inv->invite_tsx->status_code < 100) {\n\n\t\t/* Do not stop INVITE retransmission, see ticket #506 */\n\t\t//pjsip_tsx_stop_retransmit(inv->invite_tsx);\n\t\tinv->cancelling = PJ_TRUE;\n\t\tinv->pending_cancel = PJ_TRUE;\n\t\t*p_tdata = NULL;\n\t\tPJ_LOG(4, (inv->obj_name, \"Delaying CANCEL since no \"\n\t\t\t   \"provisional response is received yet\"));\n\t\tpj_log_pop_indent();\n\t\treturn PJ_SUCCESS;\n\t    }\n\n\t    /* The CSeq here assumes that the dialog is started with an\n\t     * INVITE session. This may not be correct; dialog can be \n\t     * started as SUBSCRIBE session.\n\t     * So fix this!\n\t     */\n\t    status = pjsip_endpt_create_cancel(inv->dlg->endpt, \n\t\t\t\t\t       inv->invite_tsx->last_tx,\n\t\t\t\t\t       &tdata);\n\t    if (status != PJ_SUCCESS) {\n\t\tpj_log_pop_indent();\n\t\treturn status;\n\t    }\n\n\t    /* Set timeout for the INVITE transaction, in case UAS is not\n\t     * able to respond the INVITE with 487 final response. The \n\t     * timeout value is 64*T1.\n\t     */\n\t    pjsip_tsx_set_timeout(inv->invite_tsx, 64 * pjsip_cfg()->tsx.t1);\n\n\t} else {\n\n\t    /* For UAS, send a final response. */\n\t    tdata = inv->invite_tsx->last_tx;\n\t    PJ_ASSERT_RETURN(tdata != NULL, PJ_EINVALIDOP);\n\n\t    //status = pjsip_dlg_modify_response(inv->dlg, tdata, st_code,\n\t    //\t\t\t\t       st_text);\n\t    status = pjsip_inv_answer(inv, st_code, st_text, NULL, &tdata);\n\t}\n\tbreak;\n\n    case PJSIP_INV_STATE_CONNECTING:\n    case PJSIP_INV_STATE_CONFIRMED:\n\t/* End Session Timer */\n\tpjsip_timer_end_session(inv);\n\n\t/* For established dialog, send BYE */\n\tstatus = pjsip_dlg_create_request(inv->dlg, pjsip_get_bye_method(), \n\t\t\t\t\t  -1, &tdata);\n\tbreak;\n\n    case PJSIP_INV_STATE_DISCONNECTED:\n\t/* No need to do anything. */\n\tpj_log_pop_indent();\n\treturn PJSIP_ESESSIONTERMINATED;\n\n    default:\n\tpj_assert(!\"Invalid operation!\");\n\tpj_log_pop_indent();\n\treturn PJ_EINVALIDOP;\n    }\n\n    if (status != PJ_SUCCESS) {\n\tpj_log_pop_indent();\n\treturn status;\n    }\n\n\n    /* Done */\n\n    inv->cancelling = PJ_TRUE;\n    *p_tdata = tdata;\n\n    pj_log_pop_indent();\n    return PJ_SUCCESS;\n}\n\n/*\n * Cancel re-INVITE transaction.\n */\nPJ_DEF(pj_status_t) pjsip_inv_cancel_reinvite( pjsip_inv_session *inv,\n                                               pjsip_tx_data **p_tdata )\n{\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(inv && p_tdata, PJ_EINVAL);\n    \n    pj_log_push_indent();\n\n    /* Create appropriate message. */\n    switch (inv->state) {\n    case PJSIP_INV_STATE_CONFIRMED:\n        /* MUST have the original UAC INVITE transaction  */\n        PJ_ASSERT_RETURN(inv->invite_tsx != NULL, PJ_EBUG);\n\n        /* CANCEL should only be called when we have received a\n         * provisional response.\n         */\n        if (inv->invite_tsx->status_code < 100) {\n            inv->cancelling = PJ_TRUE;\n            inv->pending_cancel = PJ_TRUE;\n            *p_tdata = NULL;\n            PJ_LOG(4, (inv->obj_name, \"Delaying CANCEL since no \"\n                       \"provisional response is received yet\"));\n            pj_log_pop_indent();\n            return PJ_SUCCESS;\n        }\n\n        status = pjsip_endpt_create_cancel(inv->dlg->endpt, \n                                           inv->invite_tsx->last_tx,\n                                           &tdata);\n        if (status != PJ_SUCCESS) {\n            pj_log_pop_indent();\n            return status;\n        }\n\tbreak;\n\n    default:\n        /* We cannot send CANCEL to a re-INVITE if the INVITE session is\n         * not confirmed.\n         */\n        pj_log_pop_indent();\n        return PJ_EINVALIDOP;\n    }\n\n    pj_log_pop_indent();\n\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n}\n\n/* Following redirection recursion, get next target from the target set and\n * notify user.\n *\n * Returns PJ_FALSE if recursion fails (either because there's no more target\n * or user rejects the recursion). If we return PJ_FALSE, caller should\n * disconnect the session.\n *\n * Note:\n *   the event 'e' argument may be NULL.\n */\nstatic pj_bool_t inv_uac_recurse(pjsip_inv_session *inv, int code,\n\t\t\t\t const pj_str_t *reason, pjsip_event *e)\n{\n    pjsip_redirect_op op;\n    pjsip_target *target;\n\n    /* Won't redirect if the callback is not implemented. */\n    if (mod_inv.cb.on_redirected == NULL)\n\treturn PJ_FALSE;\n\n    if (reason == NULL)\n\treason = pjsip_get_status_text(code);\n\n    /* Set status of current target */\n    pjsip_target_assign_status(inv->dlg->target_set.current, inv->dlg->pool,\n\t\t\t       code, reason);\n\n    /* Fetch next target from the target set. We only want to\n     * process SIP/SIPS URI for now.\n     */\n    for (;;) {\n\ttarget = pjsip_target_set_get_next(&inv->dlg->target_set);\n\tif (target == NULL) {\n\t    /* No more target. */\n\t    return PJ_FALSE;\n\t}\n\n\tif (!PJSIP_URI_SCHEME_IS_SIP(target->uri) &&\n\t    !PJSIP_URI_SCHEME_IS_SIPS(target->uri))\n\t{\n\t    code = PJSIP_SC_UNSUPPORTED_URI_SCHEME;\n\t    reason = pjsip_get_status_text(code);\n\n\t    /* Mark this target as unusable and fetch next target. */\n\t    pjsip_target_assign_status(target, inv->dlg->pool, code, reason);\n\t} else {\n\t    /* Found a target */\n\t    break;\n\t}\n    }\n\n    /* We have target in 'target'. Set this target as current target\n     * and notify callback. \n     */\n    pjsip_target_set_set_current(&inv->dlg->target_set, target);\n\n    op = (*mod_inv.cb.on_redirected)(inv, target->uri, e);\n\n\n    /* Check what the application wants to do now */\n    switch (op) {\n    case PJSIP_REDIRECT_ACCEPT:\n    case PJSIP_REDIRECT_ACCEPT_REPLACE:\n    case PJSIP_REDIRECT_STOP:\n\t/* Must increment session counter, that's the convention of the \n\t * pjsip_inv_process_redirect().\n\t */\n\tpjsip_dlg_inc_session(inv->dlg, &mod_inv.mod);\n\n\t/* Act on the recursion */\n\tpjsip_inv_process_redirect(inv, op, e);\n\treturn PJ_TRUE;\n\n    case PJSIP_REDIRECT_PENDING:\n\t/* Increment session so that the dialog/session is not destroyed \n\t * while we're waiting for user confirmation.\n\t */\n\tpjsip_dlg_inc_session(inv->dlg, &mod_inv.mod);\n\n\t/* Also clear the invite_tsx variable, otherwise when this tsx is\n\t * terminated, it will also terminate the session.\n\t */\n\tinv->invite_tsx = NULL;\n\n\t/* Done. The processing will continue once the application calls\n\t * pjsip_inv_process_redirect().\n\t */\n\treturn PJ_TRUE;\n\n    case PJSIP_REDIRECT_REJECT:\n\t/* Recursively call  this function again to fetch next target, if any.\n\t */\n\treturn inv_uac_recurse(inv, PJSIP_SC_REQUEST_TERMINATED, NULL, e);\n\n    }\n\n    pj_assert(!\"Should not reach here\");\n    return PJ_FALSE;\n}\n\n\n/* Process redirection/recursion */\nPJ_DEF(pj_status_t) pjsip_inv_process_redirect( pjsip_inv_session *inv,\n\t\t\t\t\t\tpjsip_redirect_op op,\n\t\t\t\t\t\tpjsip_event *e)\n{\n    const pjsip_status_code cancel_code = PJSIP_SC_REQUEST_TERMINATED;\n    pjsip_event usr_event;\n    pj_status_t status = PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(inv && op != PJSIP_REDIRECT_PENDING, PJ_EINVAL);\n\n    if (e == NULL) {\n\tPJSIP_EVENT_INIT_USER(usr_event, NULL, NULL, NULL, NULL);\n\te = &usr_event;\n    }\n\n    pjsip_dlg_inc_lock(inv->dlg);\n\n    /* Decrement session. That's the convention here to prevent the dialog \n     * or session from being destroyed while we're waiting for user\n     * confirmation.\n     */\n    pjsip_dlg_dec_session(inv->dlg, &mod_inv.mod);\n\n    /* See what the application wants to do now */\n    switch (op) {\n    case PJSIP_REDIRECT_ACCEPT:\n    case PJSIP_REDIRECT_ACCEPT_REPLACE:\n\t/* User accept the redirection. Reset the session and resend the \n\t * INVITE request.\n\t */\n\t{\n\t    pjsip_tx_data *tdata;\n\t    pjsip_via_hdr *via;\n\n\t    /* Get the original INVITE request. */\n\t    tdata = inv->invite_req;\n\t    pjsip_tx_data_add_ref(tdata);\n\n\t    /* Restore strict route set.\n\t     * See http://trac.pjsip.org/repos/ticket/492\n\t     */\n\t    pjsip_restore_strict_route_set(tdata);\n\n\t    /* Set target */\n\t    tdata->msg->line.req.uri = (pjsip_uri*)\n\t       pjsip_uri_clone(tdata->pool, inv->dlg->target_set.current->uri);\n\n\t    /* Remove branch param in Via header. */\n\t    via = (pjsip_via_hdr*) \n\t\t  pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);\n\t    via->branch_param.slen = 0;\n\n\t    /* Process PJSIP_REDIRECT_ACCEPT_REPLACE */\n\t    if (op == PJSIP_REDIRECT_ACCEPT_REPLACE) {\n\t\tpjsip_to_hdr *to;\n\t\tpjsip_dialog *dlg = inv->dlg;\n\t\tenum { TMP_LEN = 128 };\n\t\tchar tmp[TMP_LEN];\n\t\tint len;\n\n\t\t/* Replace To header */\n\t\tto = PJSIP_MSG_TO_HDR(tdata->msg);\n\t\tto->uri = (pjsip_uri*)\n\t\t\t  pjsip_uri_clone(tdata->pool,\n\t\t\t\t          dlg->target_set.current->uri);\n\t\tto->tag.slen = 0;\n\t\tpj_list_init(&to->other_param);\n\t\t\n\t\t/* Re-init dialog remote info */\n\t\tdlg->remote.info = (pjsip_to_hdr*)\n\t\t\t\t   pjsip_hdr_clone(dlg->pool, to);\n\n\t\t/* Remove header param from remote info */\n\t\tif (PJSIP_URI_SCHEME_IS_SIP(dlg->remote.info->uri) ||\n\t\t    PJSIP_URI_SCHEME_IS_SIPS(dlg->remote.info->uri))\n\t\t{\n\t\t    pjsip_sip_uri *sip_uri = (pjsip_sip_uri *) \n\t\t\t\t   pjsip_uri_get_uri(dlg->remote.info->uri);\n\t\t    if (!pj_list_empty(&sip_uri->header_param)) {\n\t\t\t/* Remove all header param */\n\t\t\tpj_list_init(&sip_uri->header_param);\n\t\t    }\n\t\t}\n\n\t\t/* Print the remote info. */\n\t\tlen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,\n\t\t\t\t      dlg->remote.info->uri, tmp, TMP_LEN);\n\t\tif (len < 1) {\n\t\t    pj_ansi_strcpy(tmp, \"<-error: uri too long->\");\n\t\t    len = (int)pj_ansi_strlen(tmp);\n\t\t}\n\t\tpj_strdup2_with_null(dlg->pool, &dlg->remote.info_str, tmp);\n\n\t\t/* Secure? */\n\t\tdlg->secure = PJSIP_URI_SCHEME_IS_SIPS(to->uri);\n\t    }\n\n\t    /* Reset message destination info (see #1248). */\n\t    pj_bzero(&tdata->dest_info, sizeof(tdata->dest_info));\n\n\t    /* Must invalidate the message! */\n\t    pjsip_tx_data_invalidate_msg(tdata);\n\n\t    /* Reset the session */\n\t    pjsip_inv_uac_restart(inv, PJ_FALSE);\n\n\t    /* (re)Send the INVITE request */\n\t    status = pjsip_inv_send_msg(inv, tdata);\n\t}\n\tbreak;\n\n    case PJSIP_REDIRECT_STOP:\n\t/* User doesn't want the redirection. Disconnect the session now. */\n\tinv_set_cause(inv, cancel_code, pjsip_get_status_text(cancel_code));\n\tinv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\n\t/* Caller should expect that the invite session is gone now, so\n\t * we don't need to set status to PJSIP_ESESSIONTERMINATED here.\n\t */\n\tbreak;\n\n    case PJSIP_REDIRECT_REJECT:\n\t/* Current target is rejected. Fetch next target if any. */\n\tif (inv_uac_recurse(inv, cancel_code, NULL, NULL) == PJ_FALSE) {\n\t    inv_set_cause(inv, cancel_code, \n\t\t\t  pjsip_get_status_text(cancel_code));\n\t    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\n\t    /* Tell caller that the invite session is gone now */\n\t    status = PJSIP_ESESSIONTERMINATED;\n\t}\n\tbreak;\n\n\n    case PJSIP_REDIRECT_PENDING:\n\tpj_assert(!\"Should not happen\");\n\tbreak;\n    }\n\n\n    pjsip_dlg_dec_lock(inv->dlg);\n\n    return status;\n}\n\n\n/*\n * Create re-INVITE.\n */\nPJ_DEF(pj_status_t) pjsip_inv_reinvite( pjsip_inv_session *inv,\n\t\t\t\t\tconst pj_str_t *new_contact,\n\t\t\t\t\tconst pjmedia_sdp_session *new_offer,\n\t\t\t\t\tpjsip_tx_data **p_tdata )\n{\n    pj_status_t status;\n    pjsip_contact_hdr *contact_hdr = NULL;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(inv && p_tdata, PJ_EINVAL);\n\n    /* Must NOT have a pending INVITE transaction */\n    if (inv->invite_tsx!=NULL)\n\treturn PJ_EINVALIDOP;\n\n    pj_log_push_indent();\n\n    pjsip_dlg_inc_lock(inv->dlg);\n\n    if (new_contact) {\n\tpj_str_t tmp;\n\tconst pj_str_t STR_CONTACT = { \"Contact\", 7 };\n\n\tpj_strdup_with_null(inv->dlg->pool, &tmp, new_contact);\n\tcontact_hdr = (pjsip_contact_hdr*)\n\t\t      pjsip_parse_hdr(inv->dlg->pool, &STR_CONTACT, \n\t\t\t\t      tmp.ptr, tmp.slen, NULL);\n\tif (!contact_hdr) {\n\t    status = PJSIP_EINVALIDURI;\n\t    goto on_return;\n\t}\n    }\n\n\n    if (new_offer) {\n\tif (!inv->neg) {\n\t    status = pjmedia_sdp_neg_create_w_local_offer(inv->pool, \n\t\t\t\t\t\t\t  new_offer,\n\t\t\t\t\t\t\t  &inv->neg);\n\t    if (status != PJ_SUCCESS)\n\t\tgoto on_return;\n\n\t} else switch (pjmedia_sdp_neg_get_state(inv->neg)) {\n\n\t    case PJMEDIA_SDP_NEG_STATE_NULL:\n\t\tpj_assert(!\"Unexpected SDP neg state NULL\");\n\t\tstatus = PJ_EBUG;\n\t\tgoto on_return;\n\n\t    case PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER:\n\t\tPJ_LOG(4,(inv->obj_name, \n\t\t\t  \"pjsip_inv_reinvite: already have an offer, new \"\n\t\t\t  \"offer is ignored\"));\n\t\tbreak;\n\n\t    case PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER:\n\t\tstatus = pjmedia_sdp_neg_set_local_answer(inv->pool_prov, \n\t\t\t\t\t\t\t  inv->neg,\n\t\t\t\t\t\t\t  new_offer);\n\t\tif (status != PJ_SUCCESS)\n\t\t    goto on_return;\n\t\tbreak;\n\n\t    case PJMEDIA_SDP_NEG_STATE_WAIT_NEGO:\n\t\tPJ_LOG(4,(inv->obj_name, \n\t\t\t  \"pjsip_inv_reinvite: SDP in WAIT_NEGO state, new \"\n\t\t\t  \"offer is ignored\"));\n\t\tbreak;\n\n\t    case PJMEDIA_SDP_NEG_STATE_DONE:\n\t\tstatus = pjmedia_sdp_neg_modify_local_offer2(\n                             inv->pool_prov, inv->neg,\n                             inv->sdp_neg_flags, new_offer);\n\t\tif (status != PJ_SUCCESS)\n\t\t    goto on_return;\n\t\tbreak;\n\t}\n    }\n\n    if (contact_hdr)\n\tinv->dlg->local.contact = contact_hdr;\n\n    status = pjsip_inv_invite(inv, p_tdata);\n\non_return:\n    pjsip_dlg_dec_lock(inv->dlg);\n    pj_log_pop_indent();\n    return status;\n}\n\n/*\n * Create UPDATE.\n */\nPJ_DEF(pj_status_t) pjsip_inv_update (\tpjsip_inv_session *inv,\n\t\t\t\t\tconst pj_str_t *new_contact,\n\t\t\t\t\tconst pjmedia_sdp_session *offer,\n\t\t\t\t\tpjsip_tx_data **p_tdata )\n{\n    pjsip_contact_hdr *contact_hdr = NULL;\n    pjsip_tx_data *tdata = NULL;\n    pjmedia_sdp_session *sdp_copy;\n    const pjsip_hdr *hdr;\n    pjsip_supported_hdr *sup_hdr = NULL;\n    pj_status_t status = PJ_SUCCESS;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(inv && p_tdata, PJ_EINVAL);\n\n    /* Dialog must have been established */\n    PJ_ASSERT_RETURN(inv->dlg->state == PJSIP_DIALOG_STATE_ESTABLISHED,\n\t\t     PJ_EINVALIDOP);\n\n    /* Invite session must not have been disconnected */\n    PJ_ASSERT_RETURN(inv->state < PJSIP_INV_STATE_DISCONNECTED,\n\t\t     PJ_EINVALIDOP);\n\n    pj_log_push_indent();\n\n    /* Lock dialog. */\n    pjsip_dlg_inc_lock(inv->dlg);\n\n    /* Process offer, if any */\n    if (offer) {\n\tif (pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE) {\n\t    PJ_LOG(4,(inv->dlg->obj_name,\n\t\t      \"Invalid SDP offer/answer state for UPDATE\"));\n\t    status = PJ_EINVALIDOP;\n\t    goto on_error;\n\t}\n\n\t/* Notify negotiator about the new offer. This will fix the offer\n\t * with correct SDP origin.\n\t */\n\tstatus = pjmedia_sdp_neg_modify_local_offer2(inv->pool_prov, inv->neg,\n\t\t\t\t\t\t     inv->sdp_neg_flags, offer);\n\tif (status != PJ_SUCCESS)\n\t    goto on_error;\n\n\t/* Retrieve the \"fixed\" offer from negotiator */\n\tpjmedia_sdp_neg_get_neg_local(inv->neg, &offer);\n    }\n\n    /* Update Contact if required */\n    if (new_contact) {\n\tpj_str_t tmp;\n\tconst pj_str_t STR_CONTACT = { \"Contact\", 7 };\n\n\tpj_strdup_with_null(inv->dlg->pool, &tmp, new_contact);\n\tcontact_hdr = (pjsip_contact_hdr*)\n\t\t      pjsip_parse_hdr(inv->dlg->pool, &STR_CONTACT, \n\t\t\t\t      tmp.ptr, tmp.slen, NULL);\n\tif (!contact_hdr) {\n\t    status = PJSIP_EINVALIDURI;\n\t    goto on_error;\n\t}\n\n\tinv->dlg->local.contact = contact_hdr;\n    }\n\n    /* Create request */\n    status = pjsip_dlg_create_request(inv->dlg, &pjsip_update_method,\n\t\t\t\t      -1, &tdata);\n    if (status != PJ_SUCCESS)\n\t    goto on_error;\n\n    /* Attach SDP body */\n    if (offer) {\n\tsdp_copy = pjmedia_sdp_session_clone(tdata->pool, offer);\n\tpjsip_create_sdp_body(tdata->pool, sdp_copy, &tdata->msg->body);\n    }\n\n    /* Session Timers spec (RFC 4028) says that Supported header MUST be put\n     * in refresh requests. So here we'll just put the Supported header in\n     * all cases regardless of whether session timers is used or not, just\n     * in case this is a common behavior.\n     */\n    hdr = pjsip_endpt_get_capability(inv->dlg->endpt, PJSIP_H_SUPPORTED, NULL);\n    if (hdr) {\n\tsup_hdr = (pjsip_supported_hdr*)\n\t\t   pjsip_hdr_shallow_clone(tdata->pool, hdr);\n\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)sup_hdr);\n    }\n\n    status = pjsip_timer_update_req(inv, tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_error;\n\n    /* Cleanup Allow & Supported headers from disabled extensions */\n    cleanup_allow_sup_hdr(inv->options, NULL, NULL, sup_hdr);\n\n    /* Unlock dialog. */\n    pjsip_dlg_dec_lock(inv->dlg);\n\n    *p_tdata = tdata;\n\n    pj_log_pop_indent();\n    return PJ_SUCCESS;\n\non_error:\n    if (tdata)\n\tpjsip_tx_data_dec_ref(tdata);\n\n    /* Unlock dialog. */\n    pjsip_dlg_dec_lock(inv->dlg);\n\n    pj_log_pop_indent();\n    return status;\n}\n\n/*\n * Create an ACK request.\n */\nPJ_DEF(pj_status_t) pjsip_inv_create_ack(pjsip_inv_session *inv,\n\t\t\t\t\t int cseq,\n\t\t\t\t\t pjsip_tx_data **p_tdata)\n{\n    const pjmedia_sdp_session *sdp = NULL;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(inv && p_tdata, PJ_EINVAL);\n\n    /* Lock dialog. */\n    pjsip_dlg_inc_lock(inv->dlg);\n\n    /* Destroy last_ack */\n    if (inv->last_ack) {\n\tpjsip_tx_data_dec_ref(inv->last_ack);\n\tinv->last_ack = NULL;\n    }\n\n    /* Create new ACK request */\n    status = pjsip_dlg_create_request(inv->dlg, pjsip_get_ack_method(), \n\t\t\t\t      cseq, &inv->last_ack);\n    if (status != PJ_SUCCESS) {\n\tpjsip_dlg_dec_lock(inv->dlg);\n\treturn status;\n    }\n\n    /* See if we have pending SDP answer to send */\n    sdp = inv_has_pending_answer(inv, inv->invite_tsx);\n    if (sdp) {\n\tinv->last_ack->msg->body = create_sdp_body(inv->last_ack->pool, sdp);\n    }\n\n    /* Keep this for subsequent response retransmission */\n    inv->last_ack_cseq = cseq;\n    pjsip_tx_data_add_ref(inv->last_ack);\n\n    /* Done */\n    *p_tdata = inv->last_ack;\n\n    /* Unlock dialog. */\n    pjsip_dlg_dec_lock(inv->dlg);\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Send a request or response message.\n */\nPJ_DEF(pj_status_t) pjsip_inv_send_msg( pjsip_inv_session *inv,\n\t\t\t\t\tpjsip_tx_data *tdata)\n{\n    pj_status_t status;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(inv && tdata, PJ_EINVAL);\n\n    pj_log_push_indent();\n\n    PJ_LOG(5,(inv->obj_name, \"Sending %s\", \n\t      pjsip_tx_data_get_info(tdata)));\n\n    if (tdata->msg->type == PJSIP_REQUEST_MSG) {\n\tstruct tsx_inv_data *tsx_inv_data;\n\n\tpjsip_dlg_inc_lock(inv->dlg);\n\n\t/* Check again that we didn't receive incoming re-INVITE */\n\tif (tdata->msg->line.req.method.id==PJSIP_INVITE_METHOD && \n\t    inv->invite_tsx) \n\t{\n\t    pjsip_tx_data_dec_ref(tdata);\n\t    pjsip_dlg_dec_lock(inv->dlg);\n\t    status = PJ_EINVALIDOP;\n\t    goto on_error;\n\t}\n\n\t/* Don't send BYE before ACK is received\n\t * http://trac.pjsip.org/repos/ticket/1712\n\t */\n\tif (tdata->msg->line.req.method.id == PJSIP_BYE_METHOD &&\n\t    inv->role == PJSIP_ROLE_UAS &&\n\t    inv->state == PJSIP_INV_STATE_CONNECTING &&\n\t    inv->cause != PJSIP_SC_REQUEST_TIMEOUT &&\n\t    inv->cause != PJSIP_SC_TSX_TRANSPORT_ERROR)\n\t{\n\t    if (inv->pending_bye)\n\t\tpjsip_tx_data_dec_ref(inv->pending_bye);\n\n\t    inv->pending_bye = tdata;\n\t    PJ_LOG(4, (inv->obj_name, \"Delaying BYE request until \"\n\t\t       \"ACK is received\"));\n\t    pjsip_dlg_dec_lock(inv->dlg);\n\t    goto on_return;\n\t}\n\n\t/* Associate our data in outgoing invite transaction */\n\ttsx_inv_data = PJ_POOL_ZALLOC_T(inv->pool, struct tsx_inv_data);\n\ttsx_inv_data->inv = inv;\n\ttsx_inv_data->has_sdp = tx_data_has_sdp(tdata);\n\n\tpjsip_dlg_dec_lock(inv->dlg);\n\n\tstatus = pjsip_dlg_send_request(inv->dlg, tdata, mod_inv.mod.id, \n\t\t\t\t\ttsx_inv_data);\n\tif (status != PJ_SUCCESS) {\n\t    goto on_error;\n\t}\n\n    } else {\n\tpjsip_cseq_hdr *cseq;\n\n\t/* Can only do this to send response to original INVITE\n\t * request.\n\t */\n\tPJ_ASSERT_RETURN((cseq=(pjsip_cseq_hdr*)pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL))!=NULL\n\t\t\t  && (cseq->cseq == inv->invite_tsx->cseq),\n\t\t\t PJ_EINVALIDOP);\n\n\tif (inv->options & PJSIP_INV_REQUIRE_100REL) {\n\t    status = pjsip_100rel_tx_response(inv, tdata);\n\t} else \n\t{\n\t    status = pjsip_dlg_send_response(inv->dlg, inv->invite_tsx, tdata);\n\t}\n\n\tif (status != PJ_SUCCESS) {\n\t    goto on_error;\n\t}\n    }\n\n    /* Done */\non_return:\n    pj_log_pop_indent();\n    return PJ_SUCCESS;\n\non_error:\n    pj_log_pop_indent();\n    return status;\n}\n\n\n/*\n * Respond to incoming CANCEL request.\n */\nstatic void inv_respond_incoming_cancel(pjsip_inv_session *inv,\n\t\t\t\t\tpjsip_transaction *cancel_tsx,\n\t\t\t\t\tpjsip_event *e)\n{\n    pjsip_tx_data *tdata;\n    pjsip_transaction *invite_tsx;\n    pjsip_rx_data *rdata;\n    pj_str_t key;\n    pj_status_t status;\n\n    pj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG);\n    rdata = e->body.tsx_state.src.rdata;\n\n    /* https://trac.pjsip.org/repos/ticket/1651\n     * Special treatment for CANCEL. Since here we're responding to CANCEL\n     * automatically (including 487 to INVITE), application will see the\n     * 200/OK response to CANCEL first in the callback, and then 487 to\n     * INVITE, before the CANCEL request itself. And worse, pjsua application\n     * may not see the CANCEL request at all because by the time the CANCEL\n     * request is reported, call has been disconnected and further events\n     * from the INVITE session has been suppressed.\n     */\n    if (mod_inv.cb.on_tsx_state_changed && inv->notify)\n\t(*mod_inv.cb.on_tsx_state_changed)(inv, cancel_tsx, e);\n\n    /* See if we have matching INVITE server transaction: */\n\n    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAS,\n\t\t\t pjsip_get_invite_method(), rdata);\n    invite_tsx = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE);\n\n    if (invite_tsx == NULL) {\n\n\t/* Invite transaction not found! \n\t * Respond CANCEL with 481 (RFC 3261 Section 9.2 page 55)\n\t */\n\tstatus = pjsip_dlg_create_response( inv->dlg, rdata, 481, NULL, \n\t\t\t\t\t    &tdata);\n\n    } else {\n\t/* Always answer CANCEL will 200 (OK) regardless of\n\t * the state of the INVITE transaction.\n\t */\n\tstatus = pjsip_dlg_create_response( inv->dlg, rdata, 200, NULL, \n\t\t\t\t\t    &tdata);\n    }\n\n    /* See if we have created the response successfully. */\n    if (status != PJ_SUCCESS) return;\n\n    /* Send the CANCEL response */\n    status = pjsip_dlg_send_response(inv->dlg, cancel_tsx, tdata);\n    if (status != PJ_SUCCESS) return;\n\n\n    /* See if we need to terminate the UAS INVITE transaction\n     * with 487 (Request Terminated) response. \n     */\n    if (invite_tsx && invite_tsx->status_code < 200) {\n\n\tpj_assert(invite_tsx->last_tx != NULL);\n\n\ttdata = invite_tsx->last_tx;\n\n\tstatus = pjsip_dlg_modify_response(inv->dlg, tdata, 487, NULL);\n\tif (status == PJ_SUCCESS) {\n\t    /* Remove the message body */\n\t    tdata->msg->body = NULL;\n\t    if (inv->options & PJSIP_INV_REQUIRE_100REL) {\n\t\tstatus = pjsip_100rel_tx_response(inv, tdata);\n\t    } else {\n\t\tstatus = pjsip_dlg_send_response(inv->dlg, invite_tsx, \n\t\t\t\t\t\t tdata);\n\t    }\n\t}\n    }\n\n    if (invite_tsx)\n\tpj_grp_lock_release(invite_tsx->grp_lock);\n}\n\n\n/*\n * Respond to incoming BYE request.\n */\nstatic void inv_respond_incoming_bye( pjsip_inv_session *inv,\n\t\t\t\t      pjsip_transaction *bye_tsx,\n\t\t\t\t      pjsip_rx_data *rdata,\n\t\t\t\t      pjsip_event *e )\n{\n    pj_status_t status;\n    pjsip_tx_data *tdata;\n\n    /* Respond BYE with 200: */\n\n    status = pjsip_dlg_create_response(inv->dlg, rdata, 200, NULL, &tdata);\n    if (status != PJ_SUCCESS) return;\n\n    status = pjsip_dlg_send_response(inv->dlg, bye_tsx, tdata);\n    if (status != PJ_SUCCESS) return;\n\n    /* Terminate session: */\n\n    if (inv->state != PJSIP_INV_STATE_DISCONNECTED) {\n\tinv_set_cause(inv, PJSIP_SC_OK, NULL);\n\tinv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n    }\n}\n\n/*\n * Respond to BYE request.\n */\nstatic void inv_handle_bye_response( pjsip_inv_session *inv,\n\t\t\t\t     pjsip_transaction *tsx,\n\t\t\t\t     pjsip_rx_data *rdata,\n\t\t\t\t     pjsip_event *e )\n{\n    pj_status_t status;\n    \n    if (e->body.tsx_state.type != PJSIP_EVENT_RX_MSG) {\n\tinv_set_cause(inv, PJSIP_SC_OK, NULL);\n\tinv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\treturn;\n    }\n\n    /* Handle 401/407 challenge. */\n    if (tsx->status_code == 401 || tsx->status_code == 407) {\n\n\tpjsip_tx_data *tdata;\n\t\n\tstatus = pjsip_auth_clt_reinit_req( &inv->dlg->auth_sess, \n\t\t\t\t\t    rdata,\n\t\t\t\t\t    tsx->last_tx,\n\t\t\t\t\t    &tdata);\n\t\n\tif (status != PJ_SUCCESS) {\n\t    \n\t    /* Does not have proper credentials. \n\t     * End the session anyway.\n\t     */\n\t    inv_set_cause(inv, PJSIP_SC_OK, NULL);\n\t    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\t    \n\t} else {\n\t    struct tsx_inv_data *tsx_inv_data;\n\n\t    tsx_inv_data = (struct tsx_inv_data*)tsx->mod_data[mod_inv.mod.id];\n\t    if (tsx_inv_data)\n\t\ttsx_inv_data->retrying = PJ_TRUE;\n\n\t    /* Re-send BYE. */\n\t    status = pjsip_inv_send_msg(inv, tdata);\n\t}\n\n    } else {\n\n\t/* End the session. */\n\tinv_set_cause(inv, PJSIP_SC_OK, NULL);\n\tinv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n    }\n\n}\n\n/*\n * Respond to incoming UPDATE request.\n */\nstatic void inv_respond_incoming_update(pjsip_inv_session *inv,\n\t\t\t\t\tpjsip_event *e)\n{\n    pjmedia_sdp_neg_state neg_state;\n    pj_status_t status;\n    pjsip_tx_data *tdata = NULL;\n    pjsip_rx_data *rdata;\n    pjsip_status_code st_code;\n\n    pj_assert(e->type == PJSIP_EVENT_TSX_STATE &&\n\t      e->body.tsx_state.type == PJSIP_EVENT_RX_MSG);\n    rdata = e->body.tsx_state.src.rdata;\n\n    /* Check routing URI scheme for secure dialog */\n    if (!inv_check_secure_dlg(inv, e))\n\treturn;\n\n    /* Invoke Session Timers module */\n    status = pjsip_timer_process_req(inv, rdata, &st_code);\n    if (status != PJ_SUCCESS) {\n\tstatus = pjsip_dlg_create_response(inv->dlg, rdata, st_code,\n\t\t\t\t\t   NULL, &tdata);\n\tgoto on_return;\n    }\n\n    neg_state = pjmedia_sdp_neg_get_state(inv->neg);\n\n    /* If UPDATE doesn't contain SDP, just respond with 200/OK.\n     * This is a valid scenario according to session-timer draft.\n     */\n    if (rdata->msg_info.msg->body == NULL) {\n\n\tstatus = pjsip_dlg_create_response(inv->dlg, rdata, \n\t\t\t\t\t   200, NULL, &tdata);\n    }\n    /* Send 491 if we receive UPDATE while we're waiting for an answer */\n    else if (neg_state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) {\n\tstatus = pjsip_dlg_create_response(inv->dlg, rdata, \n\t\t\t\t\t   PJSIP_SC_REQUEST_PENDING, NULL,\n\t\t\t\t\t   &tdata);\n    }\n    /* Send 500 with Retry-After header set randomly between 0 and 10 if we \n     * receive UPDATE while we haven't sent answer.\n     */\n    else if (neg_state == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER ||\n\t     neg_state == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO)\n    {\n        pjsip_retry_after_hdr *ra_hdr;\n\tint val;\n\n        status = pjsip_dlg_create_response(inv->dlg, rdata, \n\t\t\t\t\t   PJSIP_SC_INTERNAL_SERVER_ERROR,\n\t\t\t\t\t   NULL, &tdata);\n\n        val = (pj_rand() % 10);\n        ra_hdr = pjsip_retry_after_hdr_create(tdata->pool, val);\n        pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)ra_hdr);\n\n    } else {\n\t/* We receive new offer from remote */\n\tinv_check_sdp_in_incoming_msg(inv, pjsip_rdata_get_tsx(rdata), rdata);\n\n\t/* Application MUST have supplied the answer by now.\n\t * If so, negotiate the SDP.\n\t */\n\tneg_state = pjmedia_sdp_neg_get_state(inv->neg);\n\tif (neg_state != PJMEDIA_SDP_NEG_STATE_WAIT_NEGO ||\n\t    (status=inv_negotiate_sdp(inv)) != PJ_SUCCESS)\n\t{\n\t    /* Negotiation has failed. If negotiator is still\n\t     * stuck at non-DONE state, cancel any ongoing offer.\n\t     */\n\t    neg_state = pjmedia_sdp_neg_get_state(inv->neg);\n\t    if (neg_state != PJMEDIA_SDP_NEG_STATE_DONE) {\n\t\tpjmedia_sdp_neg_cancel_offer(inv->neg);\n\t    }\n\n\t    status = pjsip_dlg_create_response(inv->dlg, rdata, \n\t\t\t\t\t       PJSIP_SC_NOT_ACCEPTABLE_HERE,\n\t\t\t\t\t       NULL, &tdata);\n\t} else {\n\t    /* New media has been negotiated successfully, send 200/OK */\n\t    status = pjsip_dlg_create_response(inv->dlg, rdata, \n\t\t\t\t\t       PJSIP_SC_OK, NULL, &tdata);\n\t    if (status == PJ_SUCCESS) {\n\t\tconst pjmedia_sdp_session *sdp;\n\t\tstatus = pjmedia_sdp_neg_get_active_local(inv->neg, &sdp);\n\t\tif (status == PJ_SUCCESS)\n\t\t    tdata->msg->body = create_sdp_body(tdata->pool, sdp);\n\t    }\n\t}\n    }\n\non_return:\n    /* Invoke Session Timers */\n    if (status == PJ_SUCCESS)\n\tstatus = pjsip_timer_update_resp(inv, tdata);\n\n    if (status != PJ_SUCCESS) {\n\tif (tdata != NULL) {\n\t    pjsip_tx_data_dec_ref(tdata);\n\t    tdata = NULL;\n\t}\n\treturn;\n    }\n\n    pjsip_dlg_send_response(inv->dlg, pjsip_rdata_get_tsx(rdata), tdata);\n}\n\n\n/*\n * Handle incoming response to UAC UPDATE request.\n */\nstatic pj_bool_t inv_handle_update_response( pjsip_inv_session *inv,\n                                             pjsip_event *e)\n{\n    pjsip_transaction *tsx = e->body.tsx_state.tsx;\n    struct tsx_inv_data *tsx_inv_data;\n    pj_bool_t handled = PJ_FALSE;\n    pj_status_t status = -1;\n\n    tsx_inv_data = (struct tsx_inv_data*)tsx->mod_data[mod_inv.mod.id];\n    pj_assert(tsx_inv_data);\n\n    /* Handle 401/407 challenge. */\n    if (tsx->state == PJSIP_TSX_STATE_COMPLETED &&\n\t(tsx->status_code == 401 || tsx->status_code == 407))\n    {\n\tpjsip_tx_data *tdata;\n\n\tstatus = pjsip_auth_clt_reinit_req( &inv->dlg->auth_sess, \n\t\t\t\t\t    e->body.tsx_state.src.rdata,\n\t\t\t\t\t    tsx->last_tx,\n\t\t\t\t\t    &tdata);\n\t\n\tif (status != PJ_SUCCESS) {\n\t    \n\t    /* Somehow failed. Probably it's not a good idea to terminate\n\t     * the session since this is just a request within dialog. And\n\t     * even if we terminate we should send BYE.\n\t     */\n\t    /*\n\t    inv_set_cause(inv, PJSIP_SC_OK, NULL);\n\t    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\t    */\n\t    \n\t} else {\n\t    if (tsx_inv_data)\n\t\ttsx_inv_data->retrying = PJ_TRUE;\n\n\t    /* Re-send request. */\n\t    status = pjsip_inv_send_msg(inv, tdata);\n\t}\n\n\thandled = PJ_TRUE;\n    }\n\n    /* Process 422 response */\n    else if (tsx->state == PJSIP_TSX_STATE_COMPLETED &&\n\t     tsx->status_code == 422)\n    {\n\tstatus = handle_timer_response(inv, e->body.tsx_state.src.rdata,\n\t\t\t\t       PJ_FALSE);\n\thandled = PJ_TRUE;\n    }\n\n    /* Process 2xx response */\n    else if (tsx->state == PJSIP_TSX_STATE_COMPLETED &&\n\ttsx->status_code/100 == 2)\n    {\n\tpjsip_rx_data *rdata = e->body.tsx_state.src.rdata;\n\n\t/* Check routing URI scheme for secure dialog */\n\tif (inv_check_secure_dlg(inv, e)) {\n\n\t    status = handle_timer_response(inv, rdata, PJ_FALSE);\n\n\t    if (rdata->msg_info.msg->body) {\n\t\t/* Only process remote SDP if we have sent local offer */\n\t\tif (inv->neg && pjmedia_sdp_neg_get_state(inv->neg) == \n\t\t\t\t\t    PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER)\n\t\t{\n\t\t    status = inv_check_sdp_in_incoming_msg(inv, tsx, rdata);\n\t\t} else {\n\t\t    PJ_LOG(5,(THIS_FILE, \"Ignored message body in %s as no \"\n\t\t\t\t\t \"local offer was sent\",\n\t\t\t\t\t pjsip_rx_data_get_info(rdata)));\n\t\t}\n\t    }\n\t}\n\n        handled = PJ_TRUE;\n    }\n\n    /* Process 502/503 error */\n    else if ((tsx->state == PJSIP_TSX_STATE_TERMINATED) &&\n\t     (tsx->status_code == 503 || tsx->status_code == 502))\n    {\n\tstatus = pjsip_timer_handle_refresh_error(inv, e);\n\n\thandled = PJ_TRUE;\n    }\n    \n    /* Get/attach invite session's transaction data */\n    else \n    {\n\t/* Session-Timer needs to see any error responses, to determine\n\t * whether peer supports UPDATE with empty body.\n\t */\n\tif (tsx->state == PJSIP_TSX_STATE_COMPLETED &&\n\t    tsx->role == PJSIP_ROLE_UAC)\n\t{\n\t    status = handle_timer_response(inv, e->body.tsx_state.src.rdata,\n\t\t\t\t\t   PJ_FALSE);\n\t    handled = PJ_TRUE;\n\t}\n    }\n\n    /* Cancel the negotiation if we don't get successful negotiation by now,\n     * unless it's authentication challenge and the request is being retried.\n     */\n    if (pjmedia_sdp_neg_get_state(inv->neg) ==\n\t\tPJMEDIA_SDP_NEG_STATE_LOCAL_OFFER &&\n\ttsx_inv_data && tsx_inv_data->sdp_done == PJ_FALSE &&\n\t!tsx_inv_data->retrying && tsx_inv_data->has_sdp)\n    {\n\tpjmedia_sdp_neg_cancel_offer(inv->neg);\n\n\t/* Prevent from us cancelling different offer! */\n\ttsx_inv_data->sdp_done = PJ_TRUE;\n    }\n\n    return handled;\n}\n\n\n/*\n * Handle incoming reliable response.\n */\nstatic void inv_handle_incoming_reliable_response(pjsip_inv_session *inv,\n\t\t\t\t\t\t  pjsip_rx_data *rdata)\n{\n    pjsip_tx_data *tdata;\n    const pjmedia_sdp_session *sdp;\n    pj_status_t status;\n\n    /* Create PRACK */\n    status = pjsip_100rel_create_prack(inv, rdata, &tdata);\n    if (status != PJ_SUCCESS)\n\treturn;\n\n    /* See if we need to attach SDP answer on the PRACK request */\n    sdp = inv_has_pending_answer(inv, pjsip_rdata_get_tsx(rdata));\n    if (sdp) {\n\ttdata->msg->body = create_sdp_body(tdata->pool, sdp);\n    }\n\n    /* Send PRACK (must be using 100rel module!) */\n    pjsip_100rel_send_prack(inv, tdata);\n}\n\n\n/*\n * Handle incoming PRACK.\n */\nstatic void inv_respond_incoming_prack(pjsip_inv_session *inv,\n\t\t\t\t       pjsip_rx_data *rdata)\n{\n    pj_status_t status;\n\n    /* Run through 100rel module to see if we can accept this\n     * PRACK request. The 100rel will send 200/OK to PRACK request.\n     */\n    status = pjsip_100rel_on_rx_prack(inv, rdata);\n    if (status != PJ_SUCCESS)\n\treturn;\n\n    /* Now check for SDP answer in the PRACK request */\n    if (rdata->msg_info.msg->body) {\n\tstatus = inv_check_sdp_in_incoming_msg(inv, \n\t\t\t\t\tpjsip_rdata_get_tsx(rdata), rdata);\n    } else {\n\t/* No SDP body */\n\tstatus = -1;\n    }\n\n    /* If SDP negotiation has been successful, also mark the\n     * SDP negotiation flag in the invite transaction to be\n     * done too.\n     */\n    if (status == PJ_SUCCESS && inv->invite_tsx) {\n\tstruct tsx_inv_data *tsx_inv_data;\n\n\t/* Get/attach invite session's transaction data */\n\ttsx_inv_data = (struct tsx_inv_data*) \n\t\t       inv->invite_tsx->mod_data[mod_inv.mod.id];\n\tif (tsx_inv_data == NULL) {\n\t    tsx_inv_data = PJ_POOL_ZALLOC_T(inv->invite_tsx->pool, \n\t\t\t\t\t    struct tsx_inv_data);\n\t    tsx_inv_data->inv = inv;\n\t    tsx_inv_data->has_sdp = PJ_TRUE;\n\t    inv->invite_tsx->mod_data[mod_inv.mod.id] = tsx_inv_data;\n\t}\n\t\n\ttsx_inv_data->sdp_done = PJ_TRUE;\n    }\n}\n\n\n/* Ticket #1735: If this is a secure dialog, make sure that any incoming\n * initial/subsequent INVITE/UPDATE request or the 2xx response to INVITE/\n * UPDATE specifies secure Contact and Record-Route headers.\n */\nstatic pj_bool_t inv_check_secure_dlg(pjsip_inv_session *inv,\n\t\t\t\t      pjsip_event *e)\n{\n    pjsip_transaction *tsx = e->body.tsx_state.tsx;\n    pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx);\n\n    if (pjsip_cfg()->endpt.disable_secure_dlg_check == PJ_FALSE &&\n\tdlg->secure && e->body.tsx_state.type==PJSIP_EVENT_RX_MSG &&\n\t((tsx->role==PJSIP_ROLE_UAC && tsx->status_code/100 == 2) ||\n\t (tsx->role==PJSIP_ROLE_UAS && tsx->state == PJSIP_TSX_STATE_TRYING))\n\t&&\n\t(tsx->method.id==PJSIP_INVITE_METHOD || \n\t pjsip_method_cmp(&tsx->method, &pjsip_update_method)==0))\n    {\n\tconst pjsip_msg *msg = e->body.tsx_state.src.rdata->msg_info.msg;\n\tpj_status_t status = PJ_SUCCESS;\n\tpjsip_contact_hdr *c;\n\n\t/* Check Contact header */\n\tc = (pjsip_contact_hdr*)\n\t    pjsip_msg_find_hdr(msg,PJSIP_H_CONTACT, NULL);\n\tif (!(c && c->uri && PJSIP_URI_SCHEME_IS_SIPS(c->uri)))\n\t    status = PJSIP_ESESSIONINSECURE;\n\n\t/* Check top Record-Route header */\n\tif (status == PJ_SUCCESS) {\n\t    pjsip_rr_hdr *r = (pjsip_rr_hdr*)\n\t\t\t      pjsip_msg_find_hdr(msg, PJSIP_H_RECORD_ROUTE,\n\t\t\t\t\t\t NULL);\n\t    if (r && !PJSIP_URI_SCHEME_IS_SIPS(&r->name_addr)) {\n\t\t/* Not \"sips\", check if it is \"sip\" and has param\n\t\t * \"transport=tls\".\n\t\t */\n\t\tif (PJSIP_URI_SCHEME_IS_SIP(&r->name_addr)) {\n\t\t    pjsip_sip_uri *sip_uri = (pjsip_sip_uri*)\n\t\t\t\t     pjsip_uri_get_uri(r->name_addr.uri);\n\t\t    if (pj_stricmp2(&sip_uri->transport_param, \"tls\")!=0)\n\t\t\tstatus = PJSIP_ESESSIONINSECURE;\n\t\t} else {\n\t\t    /* Not \"sips\" nor \"sip\", treat it as insecure? */\n\t\t    status = PJSIP_ESESSIONINSECURE;\n\t\t}\n\t    }\n\t}\n\n\tif (status == PJSIP_ESESSIONINSECURE) {\n\t    /* Found non-SIPS scheme in Contact/Record-Route header */\n\n\t    pj_str_t warn_text = pj_str(\"SIPS Required\");\n\n\t    if (tsx->role == PJSIP_ROLE_UAC) {\n\n\t\t/* If we are UAC, terminate the session */\n\t\tpjsip_tx_data *bye;\n\n\t\tPJ_LOG(4,(inv->obj_name,\n\t\t\t  \"Secure dialog requires SIPS scheme in Contact and \"\n\t\t\t  \"Record-Route headers, ending the session\"));\n\n\t\tstatus = pjsip_inv_end_session(inv, 480, NULL, &bye);\n\t\tif (status == PJ_SUCCESS && bye) {\n\t\t    pjsip_warning_hdr *w;\n\t\t    w = pjsip_warning_hdr_create(bye->pool, 381,\n\t\t\t\t\t\t pjsip_endpt_name(dlg->endpt),\n\t\t\t\t\t\t &warn_text);\n\t\t    if (w)\n\t\t\tpjsip_msg_add_hdr(bye->msg, (pjsip_hdr*)w);\n\n\t\t    status = pjsip_inv_send_msg(inv, bye);\n\t\t}\n\n\t    } else {\n\n\t\t/* If we are UAS, reject the request */\n\t\tpjsip_rx_data *rdata = e->body.tsx_state.src.rdata;\n\t\tpjsip_tx_data *tdata;\n\n\t\tPJ_LOG(4,(inv->obj_name,\n\t\t\t  \"Secure dialog requires SIPS scheme in Contact and \"\n\t\t\t  \"Route headers, rejecting the request\"));\n\n\t\tstatus = pjsip_dlg_create_response(inv->dlg, rdata, 480,\n\t\t\t\t\t\t   NULL, &tdata);\n\t\tif (status == PJ_SUCCESS) {\n\t\t    pjsip_warning_hdr *w;\n\t\t    w = pjsip_warning_hdr_create(tdata->pool, 381,\n\t\t\t\t\t\t pjsip_endpt_name(dlg->endpt),\n\t\t\t\t\t\t &warn_text);\n\t\t    if (w)\n\t\t\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)w);\n\n\t\t    pjsip_dlg_send_response(dlg, tsx, tdata);\n\t\t}\n\n\t    }\n\n    \t    return PJ_FALSE;\n\t}\n    }\n\n    return PJ_TRUE;\n}\n\n\n\n/*\n * State NULL is before anything is sent/received.\n */\nstatic void inv_on_state_null( pjsip_inv_session *inv, pjsip_event *e)\n{\n    pjsip_transaction *tsx = e->body.tsx_state.tsx;\n    pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx);\n\n    PJ_ASSERT_ON_FAIL(tsx && dlg, return);\n\n    if (tsx->method.id == PJSIP_INVITE_METHOD) {\n\n\t/* Keep the initial INVITE transaction. */\n\tif (inv->invite_tsx == NULL)\n\t    inv->invite_tsx = tsx;\n\n\tif (dlg->role == PJSIP_ROLE_UAC) {\n\n\t    /* Save the original INVITE request.\n             * We may need to resend the INVITE if we receive redirection\n             * or session timer too small response.\n\t     */\n\t    if (1) {\n\t\tif (inv->invite_req) {\n\t\t    pjsip_tx_data_dec_ref(inv->invite_req);\n\t\t    inv->invite_req = NULL;\n\t\t}\n\t\tinv->invite_req = tsx->last_tx;\n\t\tpjsip_tx_data_add_ref(inv->invite_req);\n\t    }\n\n\t    switch (tsx->state) {\n\t    case PJSIP_TSX_STATE_CALLING:\n\t\tinv_set_state(inv, PJSIP_INV_STATE_CALLING, e);\n\t\tbreak;\n\t    default:\n\t\tinv_on_state_calling(inv, e);\n\t\tbreak;\n\t    }\n\n\t} else {\n\t    switch (tsx->state) {\n\t    case PJSIP_TSX_STATE_TRYING:\n\t\tinv_set_state(inv, PJSIP_INV_STATE_INCOMING, e);\n\t\tbreak;\n\t    case PJSIP_TSX_STATE_PROCEEDING:\n\t\tinv_set_state(inv, PJSIP_INV_STATE_INCOMING, e);\n\t\tif (tsx->status_code > 100)\n\t\t    inv_set_state(inv, PJSIP_INV_STATE_EARLY, e);\n\t\tbreak;\n\t    case PJSIP_TSX_STATE_TERMINATED:\n\t\t/* there is a failure in sending response. */\n\t\tinv_set_cause(inv, tsx->status_code, &tsx->status_text);\n\t\tinv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\t\tbreak;\n\t    default:\n\t\tinv_on_state_incoming(inv, e);\n\t\tbreak;\n\t    }\n\t}\n\n    } else {\n\tpj_assert(!\"Unexpected transaction type\");\n    }\n}\n\n/*\n * Generic UAC transaction handler:\n *  - resend request on 401 or 407 response.\n *  - terminate dialog on 408 and 481 response.\n *  - resend request on 422 response.\n */\nstatic pj_bool_t handle_uac_tsx_response(pjsip_inv_session *inv, \n\t\t\t\t\t pjsip_event *e)\n{\n    /* RFC 3261 Section 12.2.1.2:\n     *  If the response for a request within a dialog is a 481\n     *  (Call/Transaction Does Not Exist) or a 408 (Request Timeout), the UAC\n     *  SHOULD terminate the dialog.  A UAC SHOULD also terminate a dialog if\n     *  no response at all is received for the request (the client\n     *  transaction would inform the TU about the timeout.)\n     * \n     *  For INVITE initiated dialogs, terminating the dialog consists of\n     *  sending a BYE.\n     *\n     * Note:\n     *  according to X, this should terminate dialog usage only, not the \n     *  dialog.\n     */\n    pjsip_transaction *tsx = e->body.tsx_state.tsx;\n\n    pj_assert(tsx->role == PJSIP_UAC_ROLE);\n\n    /* Note that 481 response to CANCEL does not terminate dialog usage,\n     * but only the transaction.\n     */\n    if (inv->state != PJSIP_INV_STATE_DISCONNECTED &&\n\t((tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST &&\n\t    tsx->method.id != PJSIP_CANCEL_METHOD) ||\n\t (inv->state != PJSIP_INV_STATE_CONFIRMED &&\n    \t    (tsx->status_code == PJSIP_SC_TSX_TIMEOUT ||\n\t     tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR))))\n    {\n\tpjsip_tx_data *bye;\n\tpj_status_t status;\n\n\tinv_set_cause(inv, tsx->status_code, &tsx->status_text);\n\tinv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\n\t/* Send BYE */\n\tstatus = pjsip_dlg_create_request(inv->dlg, pjsip_get_bye_method(), \n\t\t\t\t\t  -1, &bye);\n\tif (status == PJ_SUCCESS) {\n\t    pjsip_inv_send_msg(inv, bye);\n\t}\n\n\treturn PJ_TRUE; /* Handled */\n\n    } \n    /* Handle 401/407 challenge. */\n    else if (tsx->state == PJSIP_TSX_STATE_COMPLETED &&\n\t     (tsx->status_code == PJSIP_SC_UNAUTHORIZED ||\n\t      tsx->status_code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED)) \n    {\n\tpjsip_tx_data *tdata;\n\tpj_status_t status;\n\n\tif (tsx->method.id == PJSIP_INVITE_METHOD)\n\t    inv->invite_tsx = NULL;\n\n\tstatus = pjsip_auth_clt_reinit_req( &inv->dlg->auth_sess, \n\t\t\t\t\t    e->body.tsx_state.src.rdata,\n\t\t\t\t\t    tsx->last_tx, &tdata);\n    \n\tif (status != PJ_SUCCESS) {\n\t    /* Somehow failed. Probably it's not a good idea to terminate\n\t     * the session since this is just a request within dialog. And\n\t     * even if we terminate we should send BYE.\n\t     */\n\t    /*\n\t    inv_set_cause(inv, PJSIP_SC_OK, NULL);\n\t    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\t    */\n\t    \n\t} else {\n\t    struct tsx_inv_data *tsx_inv_data;\n\n\t    tsx_inv_data = (struct tsx_inv_data*)tsx->mod_data[mod_inv.mod.id];\n\t    if (tsx_inv_data)\n\t\ttsx_inv_data->retrying = PJ_TRUE;\n\n\t    /* Re-send request. */\n\t    status = pjsip_inv_send_msg(inv, tdata);\n\t}\n\n\treturn PJ_TRUE;\t/* Handled */\n    }\n\n    /* Handle session timer 422 response. */\n    else if (tsx->state == PJSIP_TSX_STATE_COMPLETED &&\n\t     tsx->status_code == PJSIP_SC_SESSION_TIMER_TOO_SMALL) \n    {\n\thandle_timer_response(inv, e->body.tsx_state.src.rdata, \n\t\t\t      PJ_FALSE);\n\n\treturn PJ_TRUE;\t/* Handled */\n\n    } \n    /* Process 502/503 error */\n    else if ((tsx->state == PJSIP_TSX_STATE_TERMINATED) &&\n\t     (tsx->status_code == 503 || tsx->status_code == 502))\n    {\n\tpjsip_timer_handle_refresh_error(inv, e);\n\n\treturn PJ_TRUE;\n    }    \n    else {\n\treturn PJ_FALSE; /* Unhandled */\n    }\n}\n\n\n/* Handle call rejection, especially with regard to processing call\n * redirection. We need to handle the following scenarios:\n *  - 3xx response is received -- see if on_redirected() callback is\n *    implemented. If so, add the Contact URIs in the response to the\n *    target set and notify user.\n *  - 4xx - 6xx resposne is received -- see if we're currently recursing,\n *    if so fetch the next target if any and notify the on_redirected()\n *    callback.\n *  - for other cases -- disconnect the session.\n */\nstatic void handle_uac_call_rejection(pjsip_inv_session *inv, pjsip_event *e)\n{\n    pjsip_transaction *tsx = e->body.tsx_state.tsx;\n    pj_status_t status;\n    \n    if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 300)) {\n\n\tif (mod_inv.cb.on_redirected == NULL) {\n\n\t    /* Redirection callback is not implemented, disconnect the\n\t     * call.\n\t     */\n\t    goto terminate_session;\n\n\t} else {\n\t    const pjsip_msg *res_msg;\n\n\t    res_msg = e->body.tsx_state.src.rdata->msg_info.msg;\n\n\t    /* Gather all Contact URI's in the response and add them\n\t     * to target set. The function will take care of removing\n\t     * duplicate URI's.\n\t     */\n\t    pjsip_target_set_add_from_msg(&inv->dlg->target_set, \n\t\t\t\t\t  inv->dlg->pool, res_msg);\n\n\t    /* Recurse to alternate targets if application allows us */\n\t    if (!inv_uac_recurse(inv, tsx->status_code, &tsx->status_text, e))\n\t    {\n\t\t/* Recursion fails, terminate session now */\n\t\tgoto terminate_session;\n\t    }\n\n\t    /* Done */\n\t}\n\n    } else if ((tsx->status_code==401 || tsx->status_code==407) &&\n\t\t!inv->cancelling) \n    {\n\n\t/* Handle authentication failure:\n\t * Resend the request with Authorization header.\n\t */\n\tpjsip_tx_data *tdata;\n\n\tstatus = pjsip_auth_clt_reinit_req(&inv->dlg->auth_sess, \n\t\t\t\t\t   e->body.tsx_state.src.rdata,\n\t\t\t\t\t   tsx->last_tx,\n\t\t\t\t\t   &tdata);\n\n\tif (status != PJ_SUCCESS) {\n\n\t    /* Does not have proper credentials. If we are currently \n\t     * recursing, try the next target. Otherwise end the session.\n\t     */\n\t    if (!inv_uac_recurse(inv, tsx->status_code, &tsx->status_text, e))\n\t    {\n\t\t/* Recursion fails, terminate session now */\n\t\tgoto terminate_session;\n\t    }\n\n\t} else {\n\n\t    /* Restart session. */\n\t    pjsip_inv_uac_restart(inv, PJ_FALSE);\n\n\t    /* Send the request. */\n\t    status = pjsip_inv_send_msg(inv, tdata);\n\t}\n\n    } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED &&\n\t       tsx->status_code == PJSIP_SC_SESSION_TIMER_TOO_SMALL) \n    {\n\t/* Handle session timer 422 response:\n\t * Resend the request with requested session timer setting.\n\t */\n\tstatus = handle_timer_response(inv, e->body.tsx_state.src.rdata,\n\t\t\t\t       PJ_FALSE);\n\tif (status != PJ_SUCCESS)\n\t    goto terminate_session;\n\n    } else if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 600)) {\n\t/* Global error */\n\tgoto terminate_session;\n\n    } else {\n\t/* See if we have alternate target to try */\n\tif (!inv_uac_recurse(inv, tsx->status_code, &tsx->status_text, e)) {\n\t    /* Recursion fails, terminate session now */\n\t    goto terminate_session;\n\t}\n    }\n    return;\n\nterminate_session:\n    inv_set_cause(inv, tsx->status_code, &tsx->status_text);\n    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n}\n\n\n/*\n * State CALLING is after sending initial INVITE request but before\n * any response (with tag) is received.\n */\nstatic void inv_on_state_calling( pjsip_inv_session *inv, pjsip_event *e)\n{\n    pjsip_transaction *tsx = e->body.tsx_state.tsx;\n    pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx);\n    pj_status_t status;\n\n    PJ_ASSERT_ON_FAIL(tsx && dlg, return);\n    \n    if (tsx == inv->invite_tsx) {\n\n\tswitch (tsx->state) {\n\n\tcase PJSIP_TSX_STATE_CALLING:\n\t    inv_set_state(inv, PJSIP_INV_STATE_CALLING, e);\n\t    break;\n\n\tcase PJSIP_TSX_STATE_PROCEEDING:\n\t    if (inv->pending_cancel) {\n\t\tpjsip_tx_data *cancel;\n\n\t\tinv->pending_cancel = PJ_FALSE;\n\n\t\tstatus = pjsip_inv_end_session(inv, 487, NULL, &cancel);\n\t\tif (status == PJ_SUCCESS && cancel)\n\t\t    status = pjsip_inv_send_msg(inv, cancel);\n\t    }\n\n\t    if (dlg->remote.info->tag.slen) {\n\n\t\tinv_set_state(inv, PJSIP_INV_STATE_EARLY, e);\n\n\t\tinv_check_sdp_in_incoming_msg(inv, tsx, \n\t\t\t\t\t      e->body.tsx_state.src.rdata);\n\n\t\tif (pjsip_100rel_is_reliable(e->body.tsx_state.src.rdata)) {\n\t\t    inv_handle_incoming_reliable_response(\n\t\t\tinv, e->body.tsx_state.src.rdata);\n\t\t}\n\n\t    } else {\n\t\t/* Ignore 100 (Trying) response, as it doesn't change\n\t\t * session state. It only ceases retransmissions.\n\t\t */\n\t    }\n\t    break;\n\n\tcase PJSIP_TSX_STATE_COMPLETED:\n\t    if (tsx->status_code/100 == 2) {\n\n\t\t/* This should not happen.\n\t\t * When transaction receives 2xx, it should be terminated\n\t\t */\n\t\tpj_assert(0);\n\n\t\tinv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e);\n\n\t\t/* Check routing URI scheme for secure dialog */\n\t\tif (!inv_check_secure_dlg(inv, e))\n\t\t    break;\n\n\t\t/* Process session timer response. */\n\t\tstatus = handle_timer_response(inv,\n\t\t\t\t\t       e->body.tsx_state.src.rdata,\n\t\t\t\t\t       PJ_TRUE);\n\t\tif (status != PJ_SUCCESS)\n\t\t    break;\n\n\t\tinv_check_sdp_in_incoming_msg(inv, tsx, \n\t\t\t\t\t      e->body.tsx_state.src.rdata);\n\n\t    } else {\n\t\thandle_uac_call_rejection(inv, e);\n\t    }\n\t    break;\n\n\tcase PJSIP_TSX_STATE_TERMINATED:\n\t    /* INVITE transaction can be terminated either because UAC\n\t     * transaction received 2xx response or because of transport\n\t     * error.\n\t     */\n\t    if (tsx->status_code/100 == 2) {\n\t\t/* This must be receipt of 2xx response */\n\t\tpj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG);\n\n\t\t/* Set state to CONNECTING */\n\t\tinv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e);\n\n\t\t/* Check routing URI scheme for secure dialog */\n\t\tif (!inv_check_secure_dlg(inv, e))\n\t\t    break;\n\n\t\t/* Process session timer response. */\n\t\tstatus = handle_timer_response(inv,\n\t\t\t\t\t       e->body.tsx_state.src.rdata,\n\t\t\t\t\t       PJ_TRUE);\n\t\tif (status != PJ_SUCCESS)\n\t\t    break;\n\n\t\tinv_check_sdp_in_incoming_msg(inv, tsx, \n\t\t\t\t\t      e->body.tsx_state.src.rdata);\n\t\t/* Send ACK */\n\t\tinv_send_ack(inv, e);\n\n\t    } else  {\n\t\tinv_set_cause(inv, tsx->status_code, &tsx->status_text);\n\t\tinv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\t    }\n\t    break;\n\n\tdefault:\n\t    break;\n\t}\n\n    } else if (tsx->role == PJSIP_ROLE_UAC) {\n\t/*\n\t * Handle case when outgoing request is answered with 481 (Call/\n\t * Transaction Does Not Exist), 408, or when it's timed out. In these\n\t * cases, disconnect session (i.e. dialog usage only).\n\t * Note that 481 response to CANCEL does not terminate dialog usage,\n\t * but only the transaction.\n\t */\n\tif ((tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST &&\n\t\ttsx->method.id != PJSIP_CANCEL_METHOD) ||\n\t    tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT ||\n\t    tsx->status_code == PJSIP_SC_TSX_TIMEOUT ||\n\t    tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR)\n\t{\n\t    inv_set_cause(inv, tsx->status_code, &tsx->status_text);\n\t    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\t}\n    } else if (tsx->role == PJSIP_ROLE_UAS &&\n\t       tsx->state == PJSIP_TSX_STATE_TRYING &&\n\t       pjsip_method_cmp(&tsx->method, &pjsip_update_method)==0)\n    {\n\t/*\n\t * Handle a very early UPDATE\n\t */\n\tinv_respond_incoming_update(inv, e);\n\n\n    }\n}\n\n/*\n * State INCOMING is after we received the request, but before\n * responses with tag are sent.\n */\nstatic void inv_on_state_incoming( pjsip_inv_session *inv, pjsip_event *e)\n{\n    pjsip_transaction *tsx = e->body.tsx_state.tsx;\n    pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx);\n\n    PJ_ASSERT_ON_FAIL(tsx && dlg, return);\n\n    if (tsx == inv->invite_tsx) {\n\n\t/*\n\t * Handle the INVITE state transition.\n\t */\n\n\tswitch (tsx->state) {\n\n\tcase PJSIP_TSX_STATE_TRYING:\n\t    inv_set_state(inv, PJSIP_INV_STATE_INCOMING, e);\n\t    break;\n\n\tcase PJSIP_TSX_STATE_PROCEEDING:\n\t    /*\n\t     * Transaction sent provisional response.\n\t     */\n\t    if (tsx->status_code > 100)\n\t\tinv_set_state(inv, PJSIP_INV_STATE_EARLY, e);\n\t    break;\n\n\tcase PJSIP_TSX_STATE_COMPLETED:\n\t    /*\n\t     * Transaction sent final response.\n\t     */\n\t    if (tsx->status_code/100 == 2) {\n\t\tinv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e);\n\t    } else {\n\t\tinv_set_cause(inv, tsx->status_code, &tsx->status_text);\n\t\tinv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\t    }\n\t    break;\n\n\tcase PJSIP_TSX_STATE_TERMINATED:\n\t    /* \n\t     * This happens on transport error (e.g. failed to send\n\t     * response)\n\t     */\n\t    inv_set_cause(inv, tsx->status_code, &tsx->status_text);\n\t    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\t    break;\n\n\tdefault:\n\t    pj_assert(!\"Unexpected INVITE state\");\n\t    break;\n\t}\n\n    } else if (tsx->method.id == PJSIP_CANCEL_METHOD &&\n\t       tsx->role == PJSIP_ROLE_UAS &&\n\t       tsx->state < PJSIP_TSX_STATE_COMPLETED &&\n\t       e->body.tsx_state.type == PJSIP_EVENT_RX_MSG )\n    {\n\n\t/*\n\t * Handle incoming CANCEL request.\n\t */\n\n\tinv_respond_incoming_cancel(inv, tsx, e);\n\n    }\n}\n\n/*\n * State EARLY is for both UAS and UAC, after response with To tag\n * is sent/received.\n */\nstatic void inv_on_state_early( pjsip_inv_session *inv, pjsip_event *e)\n{\n    pjsip_transaction *tsx = e->body.tsx_state.tsx;\n    pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx);\n\n    PJ_ASSERT_ON_FAIL(tsx && dlg, return);\n\n    if (tsx == inv->invite_tsx) {\n\n\t/*\n\t * Handle the INVITE state progress.\n\t */\n\n\tswitch (tsx->state) {\n\n\tcase PJSIP_TSX_STATE_PROCEEDING:\n\t    /* Send/received another provisional response. */\n\t    inv_set_state(inv, PJSIP_INV_STATE_EARLY, e);\n\n\t    if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {\n\t\tinv_check_sdp_in_incoming_msg(inv, tsx, \n\t\t\t\t\t      e->body.tsx_state.src.rdata);\n\n\t\tif (pjsip_100rel_is_reliable(e->body.tsx_state.src.rdata)) {\n\t\t    inv_handle_incoming_reliable_response(\n\t\t\tinv, e->body.tsx_state.src.rdata);\n\t\t}\n\t    }\n\t    break;\n\n\tcase PJSIP_TSX_STATE_COMPLETED:\n\t    if (tsx->status_code/100 == 2) {\n\t\tinv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e);\n\t\tif (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {\n\t\t    pj_status_t status;\n\n\t\t    /* Check routing URI scheme for secure dialog */\n\t\t    if (!inv_check_secure_dlg(inv, e))\n\t\t\tbreak;\n\n\t\t    /* Process session timer response. */\n\t\t    status = handle_timer_response(inv, \n\t\t\t\t\t\t   e->body.tsx_state.src.rdata,\n\t\t\t\t\t\t   PJ_TRUE);\n\t\t    if (status != PJ_SUCCESS)\n\t\t\tbreak;\n\n\t\t    inv_check_sdp_in_incoming_msg(inv, tsx, \n\t\t\t\t\t\t  e->body.tsx_state.src.rdata);\n\t\t}\n\n\t    } else if (tsx->role == PJSIP_ROLE_UAC) {\n\n\t\thandle_uac_call_rejection(inv, e);\n\n\t    } else {\n\t\tinv_set_cause(inv, tsx->status_code, &tsx->status_text);\n\t\tinv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\t    }\n\t    break;\n\n\tcase PJSIP_TSX_STATE_CONFIRMED:\n\t    /* For some reason can go here (maybe when ACK for 2xx has\n\t     * the same branch value as the INVITE transaction) */\n\n\tcase PJSIP_TSX_STATE_TERMINATED:\n\t    /* INVITE transaction can be terminated either because UAC\n\t     * transaction received 2xx response or because of transport\n\t     * error.\n\t     */\n\t    if (tsx->status_code/100 == 2) {\n\n\t\t/* This must be receipt of 2xx response */\n\n\t\t/* Set state to CONNECTING */\n\t\tinv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e);\n\n\t\tif (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {\n\t\t    pj_status_t status;\n\t\t    \n\t\t    /* Check routing URI scheme for secure dialog */\n\t\t    if (!inv_check_secure_dlg(inv, e))\n\t\t\tbreak;\n\n\t\t    /* Process session timer response. */\n\t\t    status = handle_timer_response(inv, \n\t\t\t\t\t\t   e->body.tsx_state.src.rdata,\n\t\t\t\t\t\t   PJ_TRUE);\n\t\t    if (status != PJ_SUCCESS)\n\t\t\tbreak;\n\n\t\t    inv_check_sdp_in_incoming_msg(inv, tsx, \n\t\t\t\t\t\t  e->body.tsx_state.src.rdata);\n\t\t}\n\n\t\t/* if UAC, send ACK and move state to confirmed. */\n\t\tif (tsx->role == PJSIP_ROLE_UAC) {\n\t\t    pj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG);\n\n\t\t    inv_send_ack(inv, e);\n\t\t}\n\n\t    } else  {\n\t\tinv_set_cause(inv, tsx->status_code, &tsx->status_text);\n\t\tinv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\t    }\n\t    break;\n\n\tdefault:\n\t    pj_assert(!\"Unexpected INVITE tsx state\");\n\t    break;\n\t}\n\n    } else if (inv->role == PJSIP_ROLE_UAS &&\n\t       tsx->role == PJSIP_ROLE_UAS &&\n\t       tsx->method.id == PJSIP_CANCEL_METHOD &&\n\t       tsx->state < PJSIP_TSX_STATE_COMPLETED &&\n\t       e->body.tsx_state.type == PJSIP_EVENT_RX_MSG )\n    {\n\n\t/*\n\t * Handle incoming CANCEL request.\n\t */\n\n\tinv_respond_incoming_cancel(inv, tsx, e);\n\n    } else if (tsx->role == PJSIP_ROLE_UAS &&\n\t       tsx->state == PJSIP_TSX_STATE_TRYING &&\n\t       pjsip_method_cmp(&tsx->method, &pjsip_update_method)==0)\n    {\n\t/*\n\t * Handle incoming UPDATE\n\t */\n\tinv_respond_incoming_update(inv, e);\n\n\n    } else if (tsx->role == PJSIP_ROLE_UAC &&\n\t       (tsx->state == PJSIP_TSX_STATE_COMPLETED ||\n\t        tsx->state == PJSIP_TSX_STATE_TERMINATED) &&\n\t       pjsip_method_cmp(&tsx->method, &pjsip_update_method)==0)\n    {\n\t/*\n\t * Handle response to outgoing UPDATE request.\n\t */\n\tinv_handle_update_response(inv, e);\n\n    } else if (tsx->role == PJSIP_ROLE_UAS &&\n\t       tsx->state == PJSIP_TSX_STATE_TRYING &&\n\t       pjsip_method_cmp(&tsx->method, &pjsip_prack_method)==0)\n    {\n\t/*\n\t * Handle incoming PRACK\n\t */\n\tinv_respond_incoming_prack(inv, e->body.tsx_state.src.rdata);\n\n    } else if (tsx->role == PJSIP_ROLE_UAC) {\n\t\n\t/* Generic handling for UAC tsx completion */\n\thandle_uac_tsx_response(inv, e);\n\n    } else if (tsx->role == PJSIP_ROLE_UAS &&\n\t       tsx->method.id == PJSIP_BYE_METHOD &&\n\t       tsx->status_code < 200 &&\n\t       e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)\n    {\n\t/* Received BYE before the 2xx/OK response to INVITE.\n\t * Assume that the 2xx/OK response is lost and the BYE\n\t * arrives earlier.\n\t */\n\tinv_respond_incoming_bye(inv, tsx, e->body.tsx_state.src.rdata, e);\n\n\tif (inv->invite_tsx->role == PJSIP_ROLE_UAC) {\n\t    /* Set timer just in case we will never get the final response\n\t     * for INVITE.\n\t     */\n\t    pjsip_tsx_set_timeout(inv->invite_tsx, 64*pjsip_cfg()->tsx.t1);\n\t} else if (inv->invite_tsx->status_code < 200) {\n\t    pjsip_tx_data *tdata;\n\t    pjsip_msg *msg;\n\n\t    /* For UAS, send a final response. */\n\t    tdata = inv->invite_tsx->last_tx;\n\t    PJ_ASSERT_ON_FAIL(tdata != NULL, return);\n\n\t    msg = tdata->msg;\n\t    msg->line.status.code = PJSIP_SC_REQUEST_TERMINATED;\n\t    msg->line.status.reason =\n\t\t    *pjsip_get_status_text(PJSIP_SC_REQUEST_TERMINATED);\n\t    msg->body = NULL;\n\n\t    pjsip_tx_data_invalidate_msg(tdata);\n\t    pjsip_tx_data_add_ref(tdata);\n\n\t    pjsip_dlg_send_response(inv->dlg, inv->invite_tsx, tdata);\n\t}\n    }\n}\n\n/*\n * State CONNECTING is after 2xx response to INVITE is sent/received.\n */\nstatic void inv_on_state_connecting( pjsip_inv_session *inv, pjsip_event *e)\n{\n    pjsip_transaction *tsx = e->body.tsx_state.tsx;\n    pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx);\n\n    PJ_ASSERT_ON_FAIL(tsx && dlg, return);\n\n    if (tsx == inv->invite_tsx) {\n\n\t/*\n\t * Handle INVITE state progression.\n\t */\n\tswitch (tsx->state) {\n\n\tcase PJSIP_TSX_STATE_CONFIRMED:\n\t    /* It can only go here if incoming ACK request has the same Via\n\t     * branch parameter as the INVITE transaction.\n\t     */\n\t    if (tsx->status_code/100 == 2) {\n\t\tif (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {\n\t\t    inv_check_sdp_in_incoming_msg(inv, tsx,\n\t\t\t\t\t\t  e->body.tsx_state.src.rdata);\n\t\t}\n\n\t\tinv_set_state(inv, PJSIP_INV_STATE_CONFIRMED, e);\n\n\t\t/* Send pending BYE if any:\n\t\t *   http://trac.pjsip.org/repos/ticket/1712\n\t\t * Do this after setting the state to CONFIRMED, so that we\n\t\t * have consistent CONFIRMED state between caller and callee.\n\t\t */\n\t\tif (inv->pending_bye)\n\t\t    inv_perform_pending_bye(inv);\n\n\t    }\n\t    break;\n\n\tcase PJSIP_TSX_STATE_TERMINATED:\n\t    /* INVITE transaction can be terminated either because UAC\n\t     * transaction received 2xx response or because of transport\n\t     * error.\n\t     */\n\t    if (tsx->status_code/100 != 2) {\n\t\tif (tsx->role == PJSIP_ROLE_UAC) {\n\t\t    inv_set_cause(inv, tsx->status_code, &tsx->status_text);\n\t\t    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);\n\t\t} else {\n\t\t    pjsip_tx_data *bye;\n\t\t    pj_status_t status;\n\n\t\t    inv_set_cause(inv, tsx->status_code, &tsx->status_text);\n\n\t\t    /* Send BYE */\n\t\t    status = pjsip_dlg_create_request(inv->dlg,\n\t\t\t\t\t\t      pjsip_get_bye_method(),\n\t\t\t\t\t\t      -1, &bye);\n\t\t    if (status == PJ_SUCCESS) {\n\t\t\tpjsip_inv_send_msg(inv, bye);\n\n\t\t\tif (inv->pending_bye) {\n\t\t\t    pjsip_tx_data_dec_ref(inv->pending_bye);\n\t\t\t    inv->pending_bye = NULL;\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\t    break;\n\n\tcase PJSIP_TSX_STATE_DESTROYED:\n\t    /* Do nothing. */\n\t    break;\n\n\tdefault:\n\t    pj_assert(!\"Unexpected state\");\n\t    break;\n\t}\n\n    } else if (tsx->role == PJSIP_ROLE_UAS &&\n\t       tsx->method.id == PJSIP_BYE_METHOD &&\n\t       tsx->status_code < 200 &&\n\t       e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) \n    {\n\n\t/*\n\t * Handle incoming BYE.\n\t */\n\n\tinv_respond_incoming_bye( inv, tsx, e->body.tsx_state.src.rdata, e );\n\n    } else if (tsx->method.id == PJSIP_BYE_METHOD &&\n\t       tsx->role == PJSIP_ROLE_UAC &&\n\t       (tsx->state == PJSIP_TSX_STATE_COMPLETED ||\n\t        tsx->state == PJSIP_TSX_STATE_TERMINATED))\n    {\n\n\t/*\n\t * Outgoing BYE\n\t */\n\tinv_handle_bye_response( inv, tsx, e->body.tsx_state.src.rdata, e);\n\n    }\n    else if (tsx->method.id == PJSIP_CANCEL_METHOD &&\n\t     tsx->role == PJSIP_ROLE_UAS &&\n\t     tsx->status_code < 200 &&\n\t     e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) \n    {\n\n\t/*\n\t * Handle strandled incoming CANCEL or CANCEL for re-INVITE\n\t */\n        inv_respond_incoming_cancel(inv, tsx, e);\n\n    } else if (tsx->role == PJSIP_ROLE_UAS &&\n\t       tsx->state == PJSIP_TSX_STATE_TRYING &&\n\t       pjsip_method_cmp(&tsx->method, &pjsip_invite_method)==0)\n    {\n\tpjsip_rx_data *rdata = e->body.tsx_state.src.rdata;\n\tpjsip_tx_data *tdata;\n\tpj_status_t status;\n\n\t/* See https://trac.pjsip.org/repos/ticket/1455\n\t * Handle incoming re-INVITE before current INVITE is confirmed.\n\t * According to RFC 5407:\n\t *  - answer with 200 if we don't have pending offer-answer\n\t *  - answer with 491 if we *have* pending offer-answer\n\t *\n\t *  But unfortunately accepting the re-INVITE would mean we have\n\t *  two outstanding INVITEs, and we don't support that because\n\t *  we will get confused when we handle the ACK.\n\t */\n\tstatus = pjsip_dlg_create_response(inv->dlg, rdata,\n\t\t\t\t\t   PJSIP_SC_REQUEST_PENDING,\n\t\t\t\t\t   NULL, &tdata);\n\tif (status != PJ_SUCCESS)\n\t    return;\n\tpjsip_timer_update_resp(inv, tdata);\n\tstatus = pjsip_dlg_send_response(dlg, tsx, tdata);\n\n    } else if (tsx->role == PJSIP_ROLE_UAS &&\n\t       tsx->state == PJSIP_TSX_STATE_TRYING &&\n\t       pjsip_method_cmp(&tsx->method, &pjsip_update_method)==0)\n    {\n\t/*\n\t * Handle incoming UPDATE\n\t */\n\tinv_respond_incoming_update(inv, e);\n\n\n    } else if (tsx->role == PJSIP_ROLE_UAC &&\n\t       (tsx->state == PJSIP_TSX_STATE_COMPLETED ||\n\t        tsx->state == PJSIP_TSX_STATE_TERMINATED) &&\n\t       pjsip_method_cmp(&tsx->method, &pjsip_update_method)==0)\n    {\n\t/*\n\t * Handle response to outgoing UPDATE request.\n\t */\n\tif (inv_handle_update_response(inv, e) == PJ_FALSE)\n\t    handle_uac_tsx_response(inv, e);\n\n    } else if (tsx->role == PJSIP_ROLE_UAS &&\n\t       tsx->state == PJSIP_TSX_STATE_TRYING &&\n\t       pjsip_method_cmp(&tsx->method, &pjsip_prack_method)==0)\n    {\n\t/*\n\t * Handle incoming PRACK\n\t */\n\tinv_respond_incoming_prack(inv, e->body.tsx_state.src.rdata);\n\n    } else if (tsx->role == PJSIP_ROLE_UAC) {\n\t\n\t/* Generic handling for UAC tsx completion */\n\thandle_uac_tsx_response(inv, e);\n\n    }\n\n}\n\n/*\n * State CONFIRMED is after ACK is sent/received.\n */\nstatic void inv_on_state_confirmed( pjsip_inv_session *inv, pjsip_event *e)\n{\n    pjsip_transaction *tsx = e->body.tsx_state.tsx;\n    pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx);\n\n    PJ_ASSERT_ON_FAIL(tsx && dlg, return);\n\n\n    if (tsx->method.id == PJSIP_BYE_METHOD &&\n\ttsx->role == PJSIP_ROLE_UAC &&\n\t(tsx->state == PJSIP_TSX_STATE_COMPLETED ||\n\t tsx->state == PJSIP_TSX_STATE_TERMINATED))\n    {\n\n\t/*\n\t * Outgoing BYE\n\t */\n\n\tinv_handle_bye_response( inv, tsx, e->body.tsx_state.src.rdata, e);\n\n    }\n    else if (tsx->method.id == PJSIP_BYE_METHOD &&\n\t     tsx->role == PJSIP_ROLE_UAS &&\n\t     tsx->status_code < 200 &&\n\t     e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) \n    {\n\n\t/*\n\t * Handle incoming BYE.\n\t */\n\n\tinv_respond_incoming_bye( inv, tsx, e->body.tsx_state.src.rdata, e );\n\n    }\n    else if (tsx->method.id == PJSIP_CANCEL_METHOD &&\n\t     tsx->role == PJSIP_ROLE_UAS &&\n\t     tsx->status_code < 200 &&\n\t     e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) \n    {\n\n\t/*\n\t * Handle strandled incoming CANCEL or CANCEL for re-INVITE\n\t */\n        inv_respond_incoming_cancel(inv, tsx, e);\n\n    }\n    else if (tsx->method.id == PJSIP_INVITE_METHOD &&\n\t     tsx->role == PJSIP_ROLE_UAS)\n    {\n\n\t/*\n\t * Handle incoming re-INVITE\n\t */\n\tif (tsx->state == PJSIP_TSX_STATE_TRYING) {\n\t    \n\t    pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;\n\t    pjsip_tx_data *tdata;\n\t    pj_status_t status;\n\t    pjsip_rdata_sdp_info *sdp_info = NULL;\n\t    pjsip_status_code st_code;\n\n\t    /* Check if we have INVITE pending. */\n\t    if (inv->invite_tsx && inv->invite_tsx!=tsx) {\n\t\tint code;\n\t\tpj_str_t reason;\n\n\t\treason = pj_str(\"Another INVITE transaction in progress\");\n\n\t\tif (inv->invite_tsx->role == PJSIP_ROLE_UAC)\n\t\t    code = 491;\n\t\telse\n\t\t    code = 500;\n\n\t\t/* Can not receive re-INVITE while another one is pending. */\n\t\tstatus = pjsip_dlg_create_response( inv->dlg, rdata, code,\n\t\t\t\t\t\t    &reason, &tdata);\n\t\tif (status != PJ_SUCCESS)\n\t\t    return;\n\n\t\tif (code == 500) {\n\t\t    /* MUST include Retry-After header with random value\n\t\t     * between 0-10.\n\t\t     */\n\t\t    pjsip_retry_after_hdr *ra_hdr;\n\t\t    int val = (pj_rand() % 10);\n\n\t\t    ra_hdr = pjsip_retry_after_hdr_create(tdata->pool, val);\n\t\t    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)ra_hdr);\n\t\t}\n\n\t\tstatus = pjsip_dlg_send_response( inv->dlg, tsx, tdata);\n\t\t\n\n\t\treturn;\n\t    }\n\n\t    /* Check routing URI scheme for secure dialog */\n\t    if (!inv_check_secure_dlg(inv, e))\n\t\treturn;\n\n\t    /* Save the invite transaction. */\n\t    inv->invite_tsx = tsx;\n\n\t    /* Process session timers headers in the re-INVITE */\n\t    status = pjsip_timer_process_req(inv, rdata, &st_code);\n\t    if (status != PJ_SUCCESS) {\n\t\tstatus = pjsip_dlg_create_response(inv->dlg, rdata, st_code,\n\t\t\t\t\t\t   NULL, &tdata);\n\t\tif (status != PJ_SUCCESS)\n\t\t    return;\n\n\t\tpjsip_timer_update_resp(inv, tdata);\n\t\tstatus = pjsip_dlg_send_response(dlg, tsx, tdata);\n\t\treturn;\n\t    }\n\n\t    /* Send 491 if we receive re-INVITE while another offer/answer\n\t     * negotiation is in progress\n\t     */\n\t    if (pjmedia_sdp_neg_get_state(inv->neg) !=\n\t\t    PJMEDIA_SDP_NEG_STATE_DONE)\n\t    {\n\t\tstatus = pjsip_dlg_create_response(inv->dlg, rdata,\n\t\t\t\t\t\t   PJSIP_SC_REQUEST_PENDING,\n\t\t\t\t\t\t   NULL, &tdata);\n\t\tif (status != PJ_SUCCESS)\n\t\t    return;\n\t\tpjsip_timer_update_resp(inv, tdata);\n\t\tstatus = pjsip_dlg_send_response(dlg, tsx, tdata);\n\t\treturn;\n\t    }\n\n\t    /* Process SDP in incoming message. */\n\t    status = inv_check_sdp_in_incoming_msg(inv, tsx, rdata);\n\n            if (status == PJ_SUCCESS && mod_inv.cb.on_rx_reinvite &&\n                inv->notify)\n            {\n        \tpj_status_t rc;\n\n\t        sdp_info = pjsip_rdata_get_sdp_info(rdata);\n                rc = (*mod_inv.cb.on_rx_reinvite)(inv, sdp_info->sdp,\n                \t\t\t\t  rdata);\n                if (rc == PJ_SUCCESS) {\n                    /* Application will send its own response.\n                     * Our job is done. */\n\t\t    PJ_LOG(5,(inv->obj_name, \"on_rx_reinvite() returns %d\",\n\t\t\t      rc));\n                    return;\n                }\n\n                /* If application lets us answer the re-INVITE,\n                 * application must set the SDP answer with\n                 * #pjsip_inv_set_sdp_answer().\n                 */\n                if (pjmedia_sdp_neg_get_state(inv->neg) !=\n\t\t    PJMEDIA_SDP_NEG_STATE_WAIT_NEGO)\n                {\n                    status = PJ_EINVALIDOP;\n                }\n            }\n\n\t    if (status != PJ_SUCCESS) {\n\t\tpj_bool_t reject_message = PJ_TRUE;\n\n\t\tif (status == PJMEDIA_SDP_EINSDP)\n\t\t{\n\t\t    sdp_info = pjsip_rdata_get_sdp_info(rdata);\n\t\t    if (sdp_info->body.ptr == NULL && \n\t\t\tPJSIP_INV_ACCEPT_UNKNOWN_BODY) \n\t\t    {\n\t\t\t/* Message body is not \"application/sdp\" */\n\t\t\treject_message = PJ_FALSE;\n\t\t    }\t\t    \n\t\t}\n\n\t\tif (reject_message) {\n\t\t    /* Not Acceptable */\n\t\t    const pjsip_hdr *accept;\n\n\t\t    /* The incoming SDP is unacceptable. If the SDP negotiator\n\t\t     * state has just been changed, i.e: DONE -> REMOTE_OFFER,\n\t\t     * revert it back.\n\t\t     */\n\t\t    if (pjmedia_sdp_neg_get_state(inv->neg) ==\n\t\t\tPJMEDIA_SDP_NEG_STATE_REMOTE_OFFER)\n\t\t    {\n\t\t\tpjmedia_sdp_neg_cancel_offer(inv->neg);\n\t\t    }\n\n\t\t    status = pjsip_dlg_create_response(inv->dlg, rdata, \n\t\t\t\t\t (status == PJMEDIA_SDP_EINSDP)?415:488,\n\t\t\t\t\t  NULL, &tdata);\n\n\t\t    if (status != PJ_SUCCESS)\n\t\t\treturn;\n\n\n\t\t    accept = pjsip_endpt_get_capability(dlg->endpt, \n\t\t\t\t\t\t\tPJSIP_H_ACCEPT,\n\t\t\t\t\t\t\tNULL);\n\t\t    if (accept) {\n\t\t\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)\n\t\t\t\t\t  pjsip_hdr_clone(tdata->pool, accept));\n\t\t    }\n\n\t\t    status = pjsip_dlg_send_response(dlg, tsx, tdata);\n\n\t\t    return;\n\t\t}\n\t    }\n\n\t    /* Create 2xx ANSWER */\n\t    status = pjsip_dlg_create_response(dlg, rdata, 200, NULL, &tdata);\n\t    if (status != PJ_SUCCESS)\n\t\treturn;\n\n\t    /* If the INVITE request has SDP body, send answer.\n\t     * Otherwise generate offer from local active SDP.\n\t     */\n            if (!sdp_info)\n                sdp_info = pjsip_rdata_get_sdp_info(rdata);\n\t    if (sdp_info->sdp != NULL) {\n\t\tstatus = process_answer(inv, 200, tdata, NULL);\n\t    } else {\n\t\t/* INVITE does not have SDP. \n\t\t * If on_create_offer() callback is implemented, ask app.\n\t\t * to generate an offer, otherwise just send active local\n\t\t * SDP to signal that nothing gets modified.\n\t\t */\n\t\tpjmedia_sdp_session *sdp = NULL;\n\n\t\tif (mod_inv.cb.on_create_offer)  {\n\t\t    (*mod_inv.cb.on_create_offer)(inv, &sdp);\n\t\t    if (sdp) {\n\t\t\t/* Notify negotiator about the new offer. This will\n\t\t\t * fix the offer with correct SDP origin.\n\t\t\t */\n\t\t\tstatus = \n\t\t\t    pjmedia_sdp_neg_modify_local_offer2(\n                                inv->pool_prov, inv->neg,\n                                inv->sdp_neg_flags, sdp);\n\n\t\t\t/* Retrieve the \"fixed\" offer from negotiator */\n\t\t\tif (status==PJ_SUCCESS) {\n\t\t\t    const pjmedia_sdp_session *lsdp = NULL;\n\t\t\t    pjmedia_sdp_neg_get_neg_local(inv->neg, &lsdp);\n\t\t\t    sdp = (pjmedia_sdp_session*)lsdp;\n\t\t\t}\n\t\t    }\n\t\t} \n\t\t\n\t\tif (sdp == NULL) {\n\t\t    const pjmedia_sdp_session *active_sdp = NULL;\n\t\t    status = pjmedia_sdp_neg_send_local_offer(inv->pool_prov,\n\t\t\t\t\t\t\t      inv->neg, \n\t\t\t\t\t\t\t      &active_sdp);\n\t\t    if (status == PJ_SUCCESS)\n\t\t\tsdp = (pjmedia_sdp_session*) active_sdp;\n\t\t}\n\n\t\tif (sdp) {\n\t\t    tdata->msg->body = create_sdp_body(tdata->pool, sdp);\n\t\t}\n\t    }\n\n\t    if (status != PJ_SUCCESS) {\n\t\t/*\n\t\t * SDP negotiation has failed.\n\t\t */\n\t\tpj_status_t rc;\n\t\tpj_str_t reason;\n\n\t\t/* Delete the 2xx answer */\n\t\tpjsip_tx_data_dec_ref(tdata);\n\t\t\n\t\t/* Create 500 response */\n\t\treason = pj_str(\"SDP negotiation failed\");\n\t\trc = pjsip_dlg_create_response(dlg, rdata, 500, &reason, \n\t\t\t\t\t       &tdata);\n\t\tif (rc == PJ_SUCCESS) {\n\t\t    pjsip_warning_hdr *w;\n\t\t    const pj_str_t *endpt_name;\n\n\t\t    endpt_name = pjsip_endpt_name(dlg->endpt);\n\t\t    w = pjsip_warning_hdr_create_from_status(tdata->pool, \n\t\t\t\t\t\t\t     endpt_name,\n\t\t\t\t\t\t\t     status);\n\t\t    if (w)\n\t\t\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)w);\n\n\t\t    pjsip_inv_send_msg(inv, tdata);\n\t\t}\n\t\treturn;\n\t    }\n\n\t    /* Invoke Session Timers */\n\t    pjsip_timer_update_resp(inv, tdata);\n\n\t    /* Send 2xx regardless of the status of negotiation */\n\t    status = pjsip_inv_send_msg(inv, tdata);\n\n\t} else if (tsx->state == PJSIP_TSX_STATE_CONFIRMED) {\n\t    /* This is the case where ACK has the same branch as\n\t     * the INVITE request.\n\t     */\n\t    if (tsx->status_code/100 == 2 &&\n\t\te->body.tsx_state.type == PJSIP_EVENT_RX_MSG) \n\t    {\n\t\tinv_check_sdp_in_incoming_msg(inv, tsx,\n\t\t\t\t\t      e->body.tsx_state.src.rdata);\n\n\t\t/* Check if local offer got no SDP answer */\n\t\tif (pjmedia_sdp_neg_get_state(inv->neg)==\n\t\t    PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER)\n\t\t{\n\t\t    pjmedia_sdp_neg_cancel_offer(inv->neg);\n\t\t}\n\t    }\n\n\t}\n\n    }\n    else if (tsx->method.id == PJSIP_INVITE_METHOD &&\n\t     tsx->role == PJSIP_ROLE_UAC)\n    {\n\n\t/*\n\t * Handle outgoing re-INVITE\n\t */\n\tif (tsx->state == PJSIP_TSX_STATE_CALLING) {\n\n\t    /* Must not have other pending INVITE transaction */\n\t    pj_assert(inv->invite_tsx==NULL || tsx==inv->invite_tsx);\n\n\t    /* Save pending invite transaction */\n\t    inv->invite_tsx = tsx;\n\n        } else if (tsx->state == PJSIP_TSX_STATE_PROCEEDING) {\n            \n            /* CANCEL the re-INVITE if necessary */\n            if (inv->pending_cancel) {\n\t        pj_status_t status;\n\t\tpjsip_tx_data *cancel;\n\n\t\tinv->pending_cancel = PJ_FALSE;\n\n\t\tstatus = pjsip_inv_cancel_reinvite(inv, &cancel);\n\t\tif (status == PJ_SUCCESS && cancel)\n\t\t    status = pjsip_inv_send_msg(inv, cancel);\n            }\n\n\t} else if (tsx->state == PJSIP_TSX_STATE_TERMINATED &&\n\t\t   tsx->status_code/100 == 2) \n\t{\n\t    pj_status_t status;\n\n\t    /* Re-INVITE was accepted. */\n\n\t    /* Check routing URI scheme for secure dialog */\n\t    if (!inv_check_secure_dlg(inv, e))\n\t\treturn;\n\n\t    /* Process session timer response. */\n\t    status = handle_timer_response(inv, \n\t\t\t\t\t   e->body.tsx_state.src.rdata,\n\t\t\t\t\t   PJ_TRUE);\n\t    if (status != PJ_SUCCESS)\n\t\treturn;\n\n\t    /* Process SDP */\n\t    inv_check_sdp_in_incoming_msg(inv, tsx, \n\t\t\t\t\t  e->body.tsx_state.src.rdata);\n\n\t    /* Check if local offer got no SDP answer */\n\t    if (pjmedia_sdp_neg_get_state(inv->neg)==\n\t\tPJMEDIA_SDP_NEG_STATE_LOCAL_OFFER)\n\t    {\n\t\tpjmedia_sdp_neg_cancel_offer(inv->neg);\n\t    }\n\n\t    /* Send ACK */\n\t    inv_send_ack(inv, e);\n\n\t} else if (handle_uac_tsx_response(inv, e)) {\n\n\t    /* Handle response that terminates dialog */\n\t    /* Nothing to do (already handled) */\n\n\t} else if (tsx->status_code >= 300 && tsx->status_code < 700 &&\n\t\t   e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED)\n\t{\n\t    /* Ticket #1654: do not cancel SDP offer when tsx state changing\n\t     * from 'completed' to 'terminated', as it should have already\n\t     * been cancelled when tsx state is 'completed'.\n\t     */\n\n\t    pjmedia_sdp_neg_state neg_state;\n\t    struct tsx_inv_data *tsx_inv_data;\n\n\t    tsx_inv_data = (struct tsx_inv_data*)tsx->mod_data[mod_inv.mod.id];\n\n\t    /* Outgoing INVITE transaction has failed, cancel SDP nego */\n\t    neg_state = pjmedia_sdp_neg_get_state(inv->neg);\n\t    if (neg_state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER &&\n\t\ttsx_inv_data->retrying == PJ_FALSE)\n\t    {\n\t\tpjmedia_sdp_neg_cancel_offer(inv->neg);\n\t    }\n\n\t    if (tsx == inv->invite_tsx)\n\t\tinv->invite_tsx = NULL;\n\t}\n\n    } else if (tsx->role == PJSIP_ROLE_UAS &&\n\t       tsx->state == PJSIP_TSX_STATE_TRYING &&\n\t       pjsip_method_cmp(&tsx->method, &pjsip_update_method)==0)\n    {\n\t/*\n\t * Handle incoming UPDATE\n\t */\n\tinv_respond_incoming_update(inv, e);\n\n    } else if (tsx->role == PJSIP_ROLE_UAC &&\n\t       (tsx->state == PJSIP_TSX_STATE_COMPLETED ||\n\t        tsx->state == PJSIP_TSX_STATE_TERMINATED) &&\n\t       pjsip_method_cmp(&tsx->method, &pjsip_update_method)==0)\n    {\n\t/*\n\t * Handle response to outgoing UPDATE request.\n\t */\n\tif (inv_handle_update_response(inv, e) == PJ_FALSE)\n\t    handle_uac_tsx_response(inv, e);\n\n    } else if (tsx->role == PJSIP_ROLE_UAS &&\n\t       tsx->state == PJSIP_TSX_STATE_TRYING &&\n\t       pjsip_method_cmp(&tsx->method, &pjsip_prack_method)==0)\n    {\n\t/*\n\t * Handle strandled incoming PRACK\n\t */\n\tinv_respond_incoming_prack(inv, e->body.tsx_state.src.rdata);\n\n    } else if (tsx->role == PJSIP_ROLE_UAC) {\n\t/*\n\t * Handle 401/407/408/481/422 response\n\t */\n\thandle_uac_tsx_response(inv, e);\n    }\n\n}\n\n/*\n * After session has been terminated, but before dialog is destroyed\n * (because dialog has other usages, or because dialog is waiting for\n * the last transaction to terminate).\n */\nstatic void inv_on_state_disconnected( pjsip_inv_session *inv, pjsip_event *e)\n{\n    pjsip_transaction *tsx = e->body.tsx_state.tsx;\n    pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx);\n\n    PJ_ASSERT_ON_FAIL(tsx && dlg, return);\n\n    if (tsx->role == PJSIP_ROLE_UAS &&\n\ttsx->status_code < 200 &&\n\te->body.tsx_state.type == PJSIP_EVENT_RX_MSG) \n    {\n\tpjsip_rx_data *rdata = e->body.tsx_state.src.rdata;\n\n\t/*\n\t * Respond BYE with 200/OK\n\t */\n\tif (tsx->method.id == PJSIP_BYE_METHOD) {\n\t    inv_respond_incoming_bye( inv, tsx, rdata, e );\n\t} else if (tsx->method.id == PJSIP_CANCEL_METHOD) {\n\t    /*\n\t     * Respond CANCEL with 200/OK too.\n\t     */\n\t    pjsip_tx_data *tdata;\n\t    pj_status_t status;\n\n\t    status = pjsip_dlg_create_response(dlg, rdata, 200, NULL, &tdata);\n\t    if (status != PJ_SUCCESS) return;\n\n\t    status = pjsip_dlg_send_response(dlg, tsx, tdata);\n\t    if (status != PJ_SUCCESS) return;\n\n\t}\n\n    } else if (tsx->role == PJSIP_ROLE_UAC) {\n\t/*\n\t * Handle 401/407/408/481/422 response\n\t */\n\thandle_uac_tsx_response(inv, e);\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-ua/sip_reg.c",
    "content": "/* $Id: sip_reg.c 4319 2013-01-16 10:20:55Z bennylp $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-ua/sip_regc.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_parser.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_transaction.h>\n#include <pjsip/sip_event.h>\n#include <pjsip/sip_util.h>\n#include <pjsip/sip_auth_msg.h>\n#include <pjsip/sip_errno.h>\n#include <pj/assert.h>\n#include <pj/guid.h>\n#include <pj/lock.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n#include <pj/log.h>\n#include <pj/rand.h>\n#include <pj/string.h>\n\n\n#define REFRESH_TIMER\t\t1\n#define DELAY_BEFORE_REFRESH    PJSIP_REGISTER_CLIENT_DELAY_BEFORE_REFRESH\n#define THIS_FILE\t\t\"sip_reg.c\"\n\n/* Outgoing transaction timeout when server sends 100 but never replies\n * with final response. Value is in MILISECONDS!\n */\n#define REGC_TSX_TIMEOUT\t33000\n\nenum { NOEXP = 0x1FFFFFFF };\n\nstatic const pj_str_t XUID_PARAM_NAME = { \"x-uid\", 5 };\n\n\n/* Current/pending operation */\nenum regc_op\n{\n    REGC_IDLE,\n    REGC_REGISTERING,\n    REGC_UNREGISTERING\n};\n\n/**\n * SIP client registration structure.\n */\nstruct pjsip_regc\n{\n    pj_pool_t\t\t\t*pool;\n    pjsip_endpoint\t\t*endpt;\n    pj_lock_t\t\t\t*lock;\n    pj_bool_t\t\t\t _delete_flag;\n    pj_bool_t\t\t\t has_tsx;\n    pj_atomic_t\t\t\t*busy_ctr;\n    enum regc_op\t\t current_op;\n\n    pj_bool_t\t\t\t add_xuid_param;\n\n    void\t\t\t*token;\n    pjsip_regc_cb\t\t*cb;\n    pjsip_regc_tsx_cb           *tsx_cb;\n\n    pj_str_t\t\t\t str_srv_url;\n    pjsip_uri\t\t\t*srv_url;\n    pjsip_cid_hdr\t\t*cid_hdr;\n    pjsip_cseq_hdr\t\t*cseq_hdr;\n    pj_str_t\t\t\t from_uri;\n    pjsip_from_hdr\t\t*from_hdr;\n    pjsip_to_hdr\t\t*to_hdr;\n    pjsip_contact_hdr\t\t contact_hdr_list;\n    pjsip_contact_hdr\t\t removed_contact_hdr_list;\n    pjsip_expires_hdr\t\t*expires_hdr;\n    pj_uint32_t\t\t\t expires;\n    pj_uint32_t\t\t\t expires_requested;\n    pj_uint32_t\t\t\t delay_before_refresh;\n    pjsip_route_hdr\t\t route_set;\n    pjsip_hdr\t\t\t hdr_list;\n    pjsip_host_port              via_addr;\n    const void                  *via_tp;\n\n    /* Authorization sessions. */\n    pjsip_auth_clt_sess\t\t auth_sess;\n\n    /* Auto refresh registration. */\n    pj_bool_t\t\t\t auto_reg;\n    pj_time_val\t\t\t last_reg;\n    pj_time_val\t\t\t next_reg;\n    pj_timer_entry\t\t timer;\n\n    /* Transport selector */\n    pjsip_tpselector\t\t tp_sel;\n\n    /* Last transport used. We acquire the transport to keep\n     * it open.\n     */\n    pjsip_transport\t\t*last_transport;\n};\n\n\nPJ_DEF(pj_status_t) pjsip_regc_create( pjsip_endpoint *endpt, void *token,\n\t\t\t\t       pjsip_regc_cb *cb,\n\t\t\t\t       pjsip_regc **p_regc)\n{\n    pj_pool_t *pool;\n    pjsip_regc *regc;\n    pj_status_t status;\n\n    /* Verify arguments. */\n    PJ_ASSERT_RETURN(endpt && cb && p_regc, PJ_EINVAL);\n\n    pool = pjsip_endpt_create_pool(endpt, \"regc%p\", 1024, 1024);\n    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);\n\n    regc = PJ_POOL_ZALLOC_T(pool, pjsip_regc);\n\n    regc->pool = pool;\n    regc->endpt = endpt;\n    regc->token = token;\n    regc->cb = cb;\n    regc->expires = PJSIP_REGC_EXPIRATION_NOT_SPECIFIED;\n    regc->add_xuid_param = pjsip_cfg()->regc.add_xuid_param;\n\n    status = pj_lock_create_recursive_mutex(pool, pool->obj_name, \n\t\t\t\t\t    &regc->lock);\n    if (status != PJ_SUCCESS) {\n\tpj_pool_release(pool);\n\treturn status;\n    }\n\n    status = pj_atomic_create(pool, 0, &regc->busy_ctr);\n    if (status != PJ_SUCCESS) {\n\tpj_lock_destroy(regc->lock);\n\tpj_pool_release(pool);\n\treturn status;\n    }\n\n    status = pjsip_auth_clt_init(&regc->auth_sess, endpt, regc->pool, 0);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    pj_list_init(&regc->route_set);\n    pj_list_init(&regc->hdr_list);\n    pj_list_init(&regc->contact_hdr_list);\n    pj_list_init(&regc->removed_contact_hdr_list);\n\n    /* Done */\n    *p_regc = regc;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_regc_destroy(pjsip_regc *regc)\n{\n    PJ_ASSERT_RETURN(regc, PJ_EINVAL);\n\n    pj_lock_acquire(regc->lock);\n    if (regc->has_tsx || pj_atomic_get(regc->busy_ctr) != 0) {\n\tregc->_delete_flag = 1;\n\tregc->cb = NULL;\n\tpj_lock_release(regc->lock);\n    } else {\n\tpjsip_tpselector_dec_ref(&regc->tp_sel);\n\tif (regc->last_transport) {\n\t    pjsip_transport_dec_ref(regc->last_transport);\n\t    regc->last_transport = NULL;\n\t}\n\tif (regc->timer.id != 0) {\n\t    pjsip_endpt_cancel_timer(regc->endpt, &regc->timer);\n\t    regc->timer.id = 0;\n\t}\n\tpj_atomic_destroy(regc->busy_ctr);\n\tpj_lock_release(regc->lock);\n\tpj_lock_destroy(regc->lock);\n\tregc->lock = NULL;\n\tpjsip_endpt_release_pool(regc->endpt, regc->pool);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_regc_get_info( pjsip_regc *regc,\n\t\t\t\t\t pjsip_regc_info *info )\n{\n    PJ_ASSERT_RETURN(regc && info, PJ_EINVAL);\n\n    pj_lock_acquire(regc->lock);\n\n    info->server_uri = regc->str_srv_url;\n    info->client_uri = regc->from_uri;\n    info->is_busy = (pj_atomic_get(regc->busy_ctr) || regc->has_tsx);\n    info->auto_reg = regc->auto_reg;\n    info->interval = regc->expires;\n    info->transport = regc->last_transport;\n    \n    if (regc->has_tsx)\n\tinfo->next_reg = 0;\n    else if (regc->auto_reg == 0)\n\tinfo->next_reg = 0;\n    else if (regc->expires == PJSIP_REGC_EXPIRATION_NOT_SPECIFIED)\n\tinfo->next_reg = regc->expires;\n    else {\n\tpj_time_val now, next_reg;\n\n\tnext_reg = regc->next_reg;\n\tpj_gettimeofday(&now);\n\tPJ_TIME_VAL_SUB(next_reg, now);\n\tinfo->next_reg = next_reg.sec;\n    }\n\n    pj_lock_release(regc->lock);\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_pool_t*) pjsip_regc_get_pool(pjsip_regc *regc)\n{\n    return regc->pool;\n}\n\nstatic void set_expires( pjsip_regc *regc, pj_uint32_t expires)\n{\n    if (expires != regc->expires) {\n\tregc->expires_hdr = pjsip_expires_hdr_create(regc->pool, expires);\n    } else {\n\tregc->expires_hdr = NULL;\n    }\n}\n\n\nstatic pj_status_t set_contact( pjsip_regc *regc,\n\t\t\t        int contact_cnt,\n\t\t\t\tconst pj_str_t contact[] )\n{\n    const pj_str_t CONTACT = { \"Contact\", 7 };\n    pjsip_contact_hdr *h;\n    int i;\n    \n    /* Save existing contact list to removed_contact_hdr_list and\n     * clear contact_hdr_list.\n     */\n    pj_list_merge_last(&regc->removed_contact_hdr_list, \n\t\t       &regc->contact_hdr_list);\n\n    /* Set the expiration of Contacts in to removed_contact_hdr_list \n     * zero.\n     */\n    h = regc->removed_contact_hdr_list.next;\n    while (h != &regc->removed_contact_hdr_list) {\n\th->expires = 0;\n\th = h->next;\n    }\n\n    /* Process new contacts */\n    for (i=0; i<contact_cnt; ++i) {\n\tpjsip_contact_hdr *hdr;\n\tpj_str_t tmp;\n\n\tpj_strdup_with_null(regc->pool, &tmp, &contact[i]);\n\thdr = (pjsip_contact_hdr*)\n              pjsip_parse_hdr(regc->pool, &CONTACT, tmp.ptr, tmp.slen, NULL);\n\tif (hdr == NULL) {\n\t    PJ_LOG(4,(THIS_FILE, \"Invalid Contact: \\\"%.*s\\\"\", \n\t\t     (int)tmp.slen, tmp.ptr));\n\t    return PJSIP_EINVALIDURI;\n\t}\n\n\t/* Find the new contact in old contact list. If found, remove\n\t * the old header from the old header list.\n\t */\n\th = regc->removed_contact_hdr_list.next;\n\twhile (h != &regc->removed_contact_hdr_list) {\n\t    int rc;\n\n\t    rc = pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR, \n\t\t\t       h->uri, hdr->uri);\n\t    if (rc == 0) {\n\t\t/* Match */\n\t\tpj_list_erase(h);\n\t\tbreak;\n\t    }\n\n\t    h = h->next;\n\t}\n\n\t/* If add_xuid_param option is enabled and Contact URI is sip/sips,\n\t * add xuid parameter to assist matching the Contact URI in the \n\t * REGISTER response later.\n\t */\n\tif (regc->add_xuid_param && (PJSIP_URI_SCHEME_IS_SIP(hdr->uri) ||\n\t\t\t\t     PJSIP_URI_SCHEME_IS_SIPS(hdr->uri))) \n\t{\n\t    pjsip_param *xuid_param;\n\t    pjsip_sip_uri *sip_uri;\n\n\t    xuid_param = PJ_POOL_ZALLOC_T(regc->pool, pjsip_param);\n\t    xuid_param->name = XUID_PARAM_NAME;\n\t    pj_create_unique_string(regc->pool, &xuid_param->value);\n\n\t    sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(hdr->uri);\n\t    pj_list_push_back(&sip_uri->other_param, xuid_param);\n\t}\n\n\tpj_list_push_back(&regc->contact_hdr_list, hdr);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_regc_init( pjsip_regc *regc,\n\t\t\t\t     const pj_str_t *srv_url,\n\t\t\t\t     const pj_str_t *from_url,\n\t\t\t\t     const pj_str_t *to_url,\n\t\t\t\t     int contact_cnt,\n\t\t\t\t     const pj_str_t contact[],\n\t\t\t\t     pj_uint32_t expires)\n{\n    pj_str_t tmp;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(regc && srv_url && from_url && to_url && \n\t\t     expires, PJ_EINVAL);\n\n    /* Copy server URL. */\n    pj_strdup_with_null(regc->pool, &regc->str_srv_url, srv_url);\n\n    /* Set server URL. */\n    tmp = regc->str_srv_url;\n    regc->srv_url = pjsip_parse_uri( regc->pool, tmp.ptr, tmp.slen, 0);\n    if (regc->srv_url == NULL) {\n\treturn PJSIP_EINVALIDURI;\n    }\n\n    /* Set \"From\" header. */\n    pj_strdup_with_null(regc->pool, &regc->from_uri, from_url);\n    tmp = regc->from_uri;\n    regc->from_hdr = pjsip_from_hdr_create(regc->pool);\n    regc->from_hdr->uri = pjsip_parse_uri(regc->pool, tmp.ptr, tmp.slen, \n\t\t\t\t\t  PJSIP_PARSE_URI_AS_NAMEADDR);\n    if (!regc->from_hdr->uri) {\n\tPJ_LOG(4,(THIS_FILE, \"regc: invalid source URI %.*s\", \n\t\t  from_url->slen, from_url->ptr));\n\treturn PJSIP_EINVALIDURI;\n    }\n\n    /* Set \"To\" header. */\n    pj_strdup_with_null(regc->pool, &tmp, to_url);\n    regc->to_hdr = pjsip_to_hdr_create(regc->pool);\n    regc->to_hdr->uri = pjsip_parse_uri(regc->pool, tmp.ptr, tmp.slen, \n\t\t\t\t\tPJSIP_PARSE_URI_AS_NAMEADDR);\n    if (!regc->to_hdr->uri) {\n\tPJ_LOG(4,(THIS_FILE, \"regc: invalid target URI %.*s\", to_url->slen, to_url->ptr));\n\treturn PJSIP_EINVALIDURI;\n    }\n\n\n    /* Set \"Contact\" header. */\n    status = set_contact( regc, contact_cnt, contact);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Set \"Expires\" header, if required. */\n    set_expires( regc, expires);\n    regc->delay_before_refresh = DELAY_BEFORE_REFRESH;\n\n    /* Set \"Call-ID\" header. */\n    regc->cid_hdr = pjsip_cid_hdr_create(regc->pool);\n    pj_create_unique_string(regc->pool, &regc->cid_hdr->id);\n\n    /* Set \"CSeq\" header. */\n    regc->cseq_hdr = pjsip_cseq_hdr_create(regc->pool);\n    regc->cseq_hdr->cseq = pj_rand() % 0xFFFF;\n    pjsip_method_set( &regc->cseq_hdr->method, PJSIP_REGISTER_METHOD);\n\n    /* Done. */\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjsip_regc_set_credentials( pjsip_regc *regc,\n\t\t\t\t\t\tint count,\n\t\t\t\t\t\tconst pjsip_cred_info cred[] )\n{\n    PJ_ASSERT_RETURN(regc && count && cred, PJ_EINVAL);\n    return pjsip_auth_clt_set_credentials(&regc->auth_sess, count, cred);\n}\n\nPJ_DEF(pj_status_t) pjsip_regc_set_prefs( pjsip_regc *regc,\n\t\t\t\t\t  const pjsip_auth_clt_pref *pref)\n{\n    PJ_ASSERT_RETURN(regc && pref, PJ_EINVAL);\n    return pjsip_auth_clt_set_prefs(&regc->auth_sess, pref);\n}\n\nPJ_DEF(pj_status_t) pjsip_regc_set_route_set( pjsip_regc *regc,\n\t\t\t\t\t      const pjsip_route_hdr *route_set)\n{\n    const pjsip_route_hdr *chdr;\n\n    PJ_ASSERT_RETURN(regc && route_set, PJ_EINVAL);\n\n    pj_list_init(&regc->route_set);\n\n    chdr = route_set->next;\n    while (chdr != route_set) {\n\tpj_list_push_back(&regc->route_set, pjsip_hdr_clone(regc->pool, chdr));\n\tchdr = chdr->next;\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Bind client registration to a specific transport/listener. \n */\nPJ_DEF(pj_status_t) pjsip_regc_set_transport( pjsip_regc *regc,\n\t\t\t\t\t      const pjsip_tpselector *sel)\n{\n    PJ_ASSERT_RETURN(regc && sel, PJ_EINVAL);\n\n    pjsip_tpselector_dec_ref(&regc->tp_sel);\n    pj_memcpy(&regc->tp_sel, sel, sizeof(*sel));\n    pjsip_tpselector_add_ref(&regc->tp_sel);\n\n    return PJ_SUCCESS;\n}\n\n/* Release transport */\nPJ_DEF(pj_status_t) pjsip_regc_release_transport(pjsip_regc *regc)\n{\n    PJ_ASSERT_RETURN(regc, PJ_EINVAL);\n    if (regc->last_transport) {\n\tpjsip_transport_dec_ref(regc->last_transport);\n\tregc->last_transport = NULL;\n    }\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_regc_add_headers( pjsip_regc *regc,\n\t\t\t\t\t    const pjsip_hdr *hdr_list)\n{\n    const pjsip_hdr *hdr;\n\n    PJ_ASSERT_RETURN(regc && hdr_list, PJ_EINVAL);\n\n    //This is \"add\" operation, so don't remove headers.\n    //pj_list_init(&regc->hdr_list);\n\n    hdr = hdr_list->next;\n    while (hdr != hdr_list) {\n\tpj_list_push_back(&regc->hdr_list, pjsip_hdr_clone(regc->pool, hdr));\n\thdr = hdr->next;\n    }\n\n    return PJ_SUCCESS;\n}\n\nstatic pj_status_t create_request(pjsip_regc *regc, \n\t\t\t\t  pjsip_tx_data **p_tdata)\n{\n    pj_status_t status;\n    pjsip_tx_data *tdata;\n\n    PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL);\n\n    /* Create the request. */\n    status = pjsip_endpt_create_request_from_hdr( regc->endpt, \n\t\t\t\t\t\t  pjsip_get_register_method(),\n\t\t\t\t\t\t  regc->srv_url,\n\t\t\t\t\t\t  regc->from_hdr,\n\t\t\t\t\t\t  regc->to_hdr,\n\t\t\t\t\t\t  NULL,\n\t\t\t\t\t\t  regc->cid_hdr,\n\t\t\t\t\t\t  regc->cseq_hdr->cseq,\n\t\t\t\t\t\t  NULL,\n\t\t\t\t\t\t  &tdata);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Add cached authorization headers. */\n    pjsip_auth_clt_init_req( &regc->auth_sess, tdata );\n\n    /* Add Route headers from route set, ideally after Via header */\n    if (!pj_list_empty(&regc->route_set)) {\n\tpjsip_hdr *route_pos;\n\tconst pjsip_route_hdr *route;\n\n\troute_pos = (pjsip_hdr*)\n\t\t    pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);\n\tif (!route_pos)\n\t    route_pos = &tdata->msg->hdr;\n\n\troute = regc->route_set.next;\n\twhile (route != &regc->route_set) {\n\t    pjsip_hdr *new_hdr = (pjsip_hdr*)\n\t\t\t\t pjsip_hdr_shallow_clone(tdata->pool, route);\n\t    pj_list_insert_after(route_pos, new_hdr);\n\t    route_pos = new_hdr;\n\t    route = route->next;\n\t}\n    }\n\n    /* Add additional request headers */\n    if (!pj_list_empty(&regc->hdr_list)) {\n\tconst pjsip_hdr *hdr;\n\n\thdr = regc->hdr_list.next;\n\twhile (hdr != &regc->hdr_list) {\n\t    pjsip_hdr *new_hdr = (pjsip_hdr*)\n\t\t\t\t pjsip_hdr_shallow_clone(tdata->pool, hdr);\n\t    pjsip_msg_add_hdr(tdata->msg, new_hdr);\n\t    hdr = hdr->next;\n\t}\n    }\n\n    /* Done. */\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg,\n\t\t\t\t\tpjsip_tx_data **p_tdata)\n{\n    pjsip_msg *msg;\n    pjsip_contact_hdr *hdr;\n    const pjsip_hdr *h_allow;\n    pj_status_t status;\n    pjsip_tx_data *tdata;\n\n    PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL);\n\n    pj_lock_acquire(regc->lock);\n    \n    regc->expires_requested = 1;\n\n    status = create_request(regc, &tdata);\n    if (status != PJ_SUCCESS) {\n\tpj_lock_release(regc->lock);\n\treturn status;\n    }\n\n    msg = tdata->msg;\n\n    /* Add Contact headers. */\n    hdr = regc->contact_hdr_list.next;\n    while (hdr != &regc->contact_hdr_list) {\n\tpjsip_msg_add_hdr(msg, (pjsip_hdr*)\n\t\t\t       pjsip_hdr_shallow_clone(tdata->pool, hdr));\n\thdr = hdr->next;\n    }\n\n    /* Also add bindings which are to be removed */\n    while (!pj_list_empty(&regc->removed_contact_hdr_list)) {\n\thdr = regc->removed_contact_hdr_list.next;\n\tpjsip_msg_add_hdr(msg, (pjsip_hdr*)\n\t\t\t       pjsip_hdr_clone(tdata->pool, hdr));\n\tpj_list_erase(hdr);\n    }\n    \n\n    if (regc->expires_hdr)\n\tpjsip_msg_add_hdr(msg, (pjsip_hdr*)\n\t\t\t       pjsip_hdr_shallow_clone(tdata->pool,\n\t\t\t\t\t\t       regc->expires_hdr));\n\n    if (regc->timer.id != 0) {\n\tpjsip_endpt_cancel_timer(regc->endpt, &regc->timer);\n\tregc->timer.id = 0;\n    }\n\n    /* Add Allow header (http://trac.pjsip.org/repos/ticket/1039) */\n    h_allow = pjsip_endpt_get_capability(regc->endpt, PJSIP_H_ALLOW, NULL);\n    if (h_allow) {\n\tpjsip_msg_add_hdr(msg, (pjsip_hdr*)\n\t\t\t       pjsip_hdr_shallow_clone(tdata->pool, h_allow));\n\n    }\n\n    regc->auto_reg = autoreg;\n\n    pj_lock_release(regc->lock);\n\n    /* Done */\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_regc_unregister(pjsip_regc *regc,\n\t\t\t\t\t  pjsip_tx_data **p_tdata)\n{\n    pjsip_tx_data *tdata;\n    pjsip_msg *msg;\n    pjsip_hdr *hdr;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL);\n\n    pj_lock_acquire(regc->lock);\n\n    if (regc->timer.id != 0) {\n\tpjsip_endpt_cancel_timer(regc->endpt, &regc->timer);\n\tregc->timer.id = 0;\n    }\n\n    regc->expires_requested = 0;\n\n    status = create_request(regc, &tdata);\n    if (status != PJ_SUCCESS) {\n\tpj_lock_release(regc->lock);\n\treturn status;\n    }\n\n    msg = tdata->msg;\n\n    /* Add Contact headers. */\n    hdr = (pjsip_hdr*)regc->contact_hdr_list.next;\n    while ((void*)hdr != (void*)&regc->contact_hdr_list) {\n\tpjsip_msg_add_hdr(msg, (pjsip_hdr*)\n\t\t\t       pjsip_hdr_shallow_clone(tdata->pool, hdr));\n\thdr = hdr->next;\n    }\n\n    /* Also add bindings which are to be removed */\n    while (!pj_list_empty(&regc->removed_contact_hdr_list)) {\n\thdr = (pjsip_hdr*)regc->removed_contact_hdr_list.next;\n\tpjsip_msg_add_hdr(msg, (pjsip_hdr*)\n\t\t\t       pjsip_hdr_clone(tdata->pool, hdr));\n\tpj_list_erase(hdr);\n    }\n\n    /* Add Expires:0 header */\n    hdr = (pjsip_hdr*) pjsip_expires_hdr_create(tdata->pool, 0);\n    pjsip_msg_add_hdr(msg, hdr);\n\n    pj_lock_release(regc->lock);\n\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t) pjsip_regc_unregister_all(pjsip_regc *regc,\n\t\t\t\t\t      pjsip_tx_data **p_tdata)\n{\n    pjsip_tx_data *tdata;\n    pjsip_contact_hdr *hcontact;\n    pjsip_hdr *hdr;\n    pjsip_msg *msg;\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL);\n\n    pj_lock_acquire(regc->lock);\n\n    if (regc->timer.id != 0) {\n\tpjsip_endpt_cancel_timer(regc->endpt, &regc->timer);\n\tregc->timer.id = 0;\n    }\n\n    status = create_request(regc, &tdata);\n    if (status != PJ_SUCCESS) {\n\tpj_lock_release(regc->lock);\n\treturn status;\n    }\n\n    msg = tdata->msg;\n\n    /* Clear removed_contact_hdr_list */\n    pj_list_init(&regc->removed_contact_hdr_list);\n\n    /* Add Contact:* header */\n    hcontact = pjsip_contact_hdr_create(tdata->pool);\n    hcontact->star = 1;\n    pjsip_msg_add_hdr(msg, (pjsip_hdr*)hcontact);\n    \n    /* Add Expires:0 header */\n    hdr = (pjsip_hdr*) pjsip_expires_hdr_create(tdata->pool, 0);\n    pjsip_msg_add_hdr(msg, hdr);\n\n    pj_lock_release(regc->lock);\n\n    *p_tdata = tdata;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_regc_update_contact(  pjsip_regc *regc,\n\t\t\t\t\t        int contact_cnt,\n\t\t\t\t\t\tconst pj_str_t contact[] )\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(regc, PJ_EINVAL);\n\n    pj_lock_acquire(regc->lock);\n    status = set_contact( regc, contact_cnt, contact );\n    pj_lock_release(regc->lock);\n\n    return status;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_regc_update_expires(  pjsip_regc *regc,\n\t\t\t\t\t        pj_uint32_t expires )\n{\n    PJ_ASSERT_RETURN(regc, PJ_EINVAL);\n\n    pj_lock_acquire(regc->lock);\n    set_expires( regc, expires );\n    pj_lock_release(regc->lock);\n\n    return PJ_SUCCESS;\n}\n\nstatic void cbparam_init( struct pjsip_regc_cbparam *cbparam,\n                          pjsip_regc *regc, \n                          pj_status_t status, int st_code, \n\t\t\t  const pj_str_t *reason,\n\t\t\t  pjsip_rx_data *rdata, pj_int32_t expiration,\n\t\t\t  int contact_cnt, pjsip_contact_hdr *contact[])\n{\n    cbparam->regc = regc;\n    cbparam->token = regc->token;\n    cbparam->status = status;\n    cbparam->code = st_code;\n    cbparam->reason = *reason;\n    cbparam->rdata = rdata;\n    cbparam->contact_cnt = contact_cnt;\n    cbparam->expiration = (expiration >= 0? expiration:\n          \t\t   regc->expires_requested);\n    if (contact_cnt) {\n\tpj_memcpy( cbparam->contact, contact, \n\t\t   contact_cnt*sizeof(pjsip_contact_hdr*));\n    }\n}\n\nstatic void call_callback(pjsip_regc *regc, pj_status_t status, int st_code, \n\t\t\t  const pj_str_t *reason,\n\t\t\t  pjsip_rx_data *rdata, pj_int32_t expiration,\n\t\t\t  int contact_cnt, pjsip_contact_hdr *contact[])\n{\n    struct pjsip_regc_cbparam cbparam;\n\n    if (!regc->cb)\n\treturn;\n\n    cbparam_init(&cbparam, regc, status, st_code, reason, rdata, expiration,\n                 contact_cnt, contact);\n    (*regc->cb)(&cbparam);\n}\n\nstatic void regc_refresh_timer_cb( pj_timer_heap_t *timer_heap,\n\t\t\t\t   struct pj_timer_entry *entry)\n{\n    pjsip_regc *regc = (pjsip_regc*) entry->user_data;\n    pjsip_tx_data *tdata;\n    pj_status_t status;\n    \n    PJ_UNUSED_ARG(timer_heap);\n\n    /* Temporarily increase busy flag to prevent regc from being deleted\n     * in pjsip_regc_send() or in the callback\n     */\n    pj_atomic_inc(regc->busy_ctr);\n\n    entry->id = 0;\n    status = pjsip_regc_register(regc, 1, &tdata);\n    if (status == PJ_SUCCESS) {\n\tstatus = pjsip_regc_send(regc, tdata);\n    } \n    \n    if (status != PJ_SUCCESS && regc->cb) {\n\tchar errmsg[PJ_ERR_MSG_SIZE];\n\tpj_str_t reason = pj_strerror(status, errmsg, sizeof(errmsg));\n\tcall_callback(regc, status, 400, &reason, NULL, -1, 0, NULL);\n    }\n\n    /* Delete the record if user destroy regc during the callback. */\n    if (pj_atomic_dec_and_get(regc->busy_ctr)==0 && regc->_delete_flag) {\n\tpjsip_regc_destroy(regc);\n    }\n}\n\nstatic void schedule_registration ( pjsip_regc *regc, pj_int32_t expiration )\n{\n    if (regc->auto_reg && expiration > 0) {\n        pj_time_val delay = { 0, 0};\n\n        pj_timer_heap_cancel_if_active(pjsip_endpt_get_timer_heap(regc->endpt),\n                                       &regc->timer, 0);\n\n        delay.sec = expiration - regc->delay_before_refresh;\n        if (regc->expires != PJSIP_REGC_EXPIRATION_NOT_SPECIFIED && \n            delay.sec > (pj_int32_t)regc->expires) \n        {\n            delay.sec = regc->expires;\n        }\n        if (delay.sec < DELAY_BEFORE_REFRESH) \n            delay.sec = DELAY_BEFORE_REFRESH;\n        regc->timer.cb = &regc_refresh_timer_cb;\n        regc->timer.id = REFRESH_TIMER;\n        regc->timer.user_data = regc;\n        pjsip_endpt_schedule_timer( regc->endpt, &regc->timer, &delay);\n        pj_gettimeofday(&regc->last_reg);\n        regc->next_reg = regc->last_reg;\n        regc->next_reg.sec += delay.sec;\n    }\n}\n\nPJ_DEF(pj_status_t) pjsip_regc_set_reg_tsx_cb( pjsip_regc *regc,\n\t\t\t\t               pjsip_regc_tsx_cb *tsx_cb)\n{\n    PJ_ASSERT_RETURN(regc, PJ_EINVAL);\n    regc->tsx_cb = tsx_cb;\n    return PJ_SUCCESS;\n}\n\n\nPJ_DEF(pj_status_t) pjsip_regc_set_via_sent_by( pjsip_regc *regc,\n\t\t\t\t                pjsip_host_port *via_addr,\n                                                pjsip_transport *via_tp)\n{\n    PJ_ASSERT_RETURN(regc, PJ_EINVAL);\n\n    if (!via_addr)\n        pj_bzero(&regc->via_addr, sizeof(regc->via_addr));\n    else {\n        if (pj_strcmp(&regc->via_addr.host, &via_addr->host))\n            pj_strdup(regc->pool, &regc->via_addr.host, &via_addr->host);\n        regc->via_addr.port = via_addr->port;\n    }\n    regc->via_tp = via_tp;\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t)\npjsip_regc_set_delay_before_refresh( pjsip_regc *regc,\n\t\t\t\t     pj_uint32_t delay )\n{\n    PJ_ASSERT_RETURN(regc, PJ_EINVAL);\n\n    if (delay > regc->expires)\n        return PJ_ETOOBIG;\n\n    pj_lock_acquire(regc->lock);\n\n    if (regc->delay_before_refresh != delay)\n    {\n        regc->delay_before_refresh = delay;\n\n        if (regc->timer.id != 0) {\n            /* Cancel registration timer */\n            pjsip_endpt_cancel_timer(regc->endpt, &regc->timer);\n            regc->timer.id = 0;\n\n            /* Schedule next registration */\n            schedule_registration(regc, regc->expires);\n        }\n    }\n\n    pj_lock_release(regc->lock);\n\n    return PJ_SUCCESS;\n}\n\n\nstatic pj_int32_t calculate_response_expiration(const pjsip_regc *regc,\n\t\t\t\t\t        const pjsip_rx_data *rdata,\n\t\t\t\t\t\tunsigned *contact_cnt,\n\t\t\t\t\t\tunsigned max_contact,\n\t\t\t\t\t\tpjsip_contact_hdr *contacts[])\n{\n    pj_int32_t expiration = NOEXP;\n    const pjsip_msg *msg = rdata->msg_info.msg;\n    const pjsip_hdr *hdr;\n\n    /* Enumerate all Contact headers in the response */\n    *contact_cnt = 0;\n    for (hdr=msg->hdr.next; hdr!=&msg->hdr; hdr=hdr->next) {\n\tif (hdr->type == PJSIP_H_CONTACT && \n\t    *contact_cnt < max_contact) \n\t{\n\t    contacts[*contact_cnt] = (pjsip_contact_hdr*)hdr;\n\t    ++(*contact_cnt);\n\t}\n    }\n\n    if (regc->current_op == REGC_REGISTERING) {\n\tpj_bool_t has_our_contact = PJ_FALSE;\n\tconst pjsip_expires_hdr *expires;\n\n\t/* Get Expires header */\n\texpires = (const pjsip_expires_hdr*)\n\t\t  pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL);\n\n\t/* Try to find the Contact URIs that we register, in the response\n\t * to get the expires value. We'll try both with comparing the URI\n\t * and comparing the extension param only.\n\t */\n\tif (pjsip_cfg()->regc.check_contact || regc->add_xuid_param) {\n\t    unsigned i;\n\t    for (i=0; i<*contact_cnt; ++i) {\n\t\tconst pjsip_contact_hdr *our_hdr;\n\n\t\tour_hdr = (const pjsip_contact_hdr*) \n\t\t\t  regc->contact_hdr_list.next;\n\n\t\t/* Match with our Contact header(s) */\n\t\twhile ((void*)our_hdr != (void*)&regc->contact_hdr_list) {\n\n\t\t    const pjsip_uri *uri1, *uri2;\n\t\t    pj_bool_t matched = PJ_FALSE;\n\n\t\t    /* Exclude the display name when comparing the URI \n\t\t     * since server may not return it.\n\t\t     */\n\t\t    uri1 = (const pjsip_uri*)\n\t\t\t   pjsip_uri_get_uri(contacts[i]->uri);\n\t\t    uri2 = (const pjsip_uri*)\n\t\t\t   pjsip_uri_get_uri(our_hdr->uri);\n\n\t\t    /* First try with exact matching, according to RFC 3261\n\t\t     * Section 19.1.4 URI Comparison\n\t\t     */\n\t\t    if (pjsip_cfg()->regc.check_contact) {\n\t\t\tmatched = pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR,\n\t\t\t\t\t\turi1, uri2)==0;\n\t\t    }\n\n\t\t    /* If no match is found, try with matching the extension\n\t\t     * parameter only if extension parameter was added.\n\t\t     */\n\t\t    if (!matched && regc->add_xuid_param &&\n\t\t\t(PJSIP_URI_SCHEME_IS_SIP(uri1) ||\n\t\t\t PJSIP_URI_SCHEME_IS_SIPS(uri1)) && \n\t\t\t(PJSIP_URI_SCHEME_IS_SIP(uri2) ||\n\t\t\t PJSIP_URI_SCHEME_IS_SIPS(uri2))) \n\t\t    {\n\t\t\tconst pjsip_sip_uri *sip_uri1, *sip_uri2;\n\t\t\tconst pjsip_param *p1, *p2;\n\t\t\n\t\t\tsip_uri1 = (const pjsip_sip_uri*)uri1;\n\t\t\tsip_uri2 = (const pjsip_sip_uri*)uri2;\n\n\t\t\tp1 = pjsip_param_cfind(&sip_uri1->other_param,\n\t\t\t\t\t       &XUID_PARAM_NAME);\n\t\t\tp2 = pjsip_param_cfind(&sip_uri2->other_param,\n\t\t\t\t\t       &XUID_PARAM_NAME);\n\t\t\tmatched = p1 && p2 &&\n\t\t\t\t  pj_strcmp(&p1->value, &p2->value)==0;\n\n\t\t    }\n\n\t\t    if (matched) {\n\t\t\thas_our_contact = PJ_TRUE;\n\n\t\t\tif (contacts[i]->expires >= 0 && \n\t\t\t    contacts[i]->expires < expiration) \n\t\t\t{\n\t\t\t    /* Get the lowest expiration time. */\n\t\t\t    expiration = contacts[i]->expires;\n\t\t\t}\n\n\t\t\tbreak;\n\t\t    }\n\n\t\t    our_hdr = our_hdr->next;\n\n\t\t} /* while ((void.. */\n\n\t    }  /* for (i=.. */\n\n\t    /* If matching Contact header(s) are found but the\n\t     * header doesn't contain expires parameter, get the\n\t     * expiration value from the Expires header. And\n\t     * if Expires header is not present, get the expiration\n\t     * value from the request.\n\t     */\n\t    if (has_our_contact && expiration == NOEXP) {\n\t\tif (expires) {\n\t\t    expiration = expires->ivalue;\n\t\t} else if (regc->expires_hdr) {\n\t\t    expiration = regc->expires_hdr->ivalue;\n\t\t} else {\n\t\t    /* We didn't request explicit expiration value,\n\t\t     * and server doesn't specify it either. This \n\t\t     * shouldn't happen unless we have a broken\n\t\t     * registrar.\n\t\t     */\n\t\t    expiration = 3600;\n\t\t}\n\t    }\n\n\t}\n\n\t/* If we still couldn't get matching Contact header(s), it means\n\t * there must be something wrong with the  registrar (e.g. it may\n\t * have modified the URI's in the response, which is prohibited).\n\t */\n\tif (expiration==NOEXP) {\n\t    /* If the number of Contact headers in the response matches \n\t     * ours, they're all probably ours. Get the expiration\n\t     * from there if this is the case, or from Expires header\n\t     * if we don't have exact Contact header count, or\n\t     * from the request as the last resort.\n\t     */\n\t    pj_size_t our_contact_cnt;\n\n\t    our_contact_cnt = pj_list_size(&regc->contact_hdr_list);\n\n\t    if (*contact_cnt == our_contact_cnt && *contact_cnt &&\n\t\tcontacts[0]->expires >= 0) \n\t    {\n\t\texpiration = contacts[0]->expires;\n\t    } else if (expires)\n\t\texpiration = expires->ivalue;\n\t    else if (regc->expires_hdr)\n\t\texpiration = regc->expires_hdr->ivalue;\n\t    else\n\t\texpiration = 3600;\n\t}\n\n    } else {\n\t/* Just assume that the unregistration has been successful. */\n\texpiration = 0;\n    }\n\n    /* Must have expiration value by now */\n    pj_assert(expiration != NOEXP);\n\n    return expiration;\n}\n\nstatic void regc_tsx_callback(void *token, pjsip_event *event)\n{\n    pj_status_t status;\n    pjsip_regc *regc = (pjsip_regc*) token;\n    pjsip_transaction *tsx = event->body.tsx_state.tsx;\n    pj_bool_t handled = PJ_TRUE;\n    pj_bool_t update_contact = PJ_FALSE;\n\n    pj_atomic_inc(regc->busy_ctr);\n    pj_lock_acquire(regc->lock);\n\n    /* Decrement pending transaction counter. */\n    pj_assert(regc->has_tsx);\n    regc->has_tsx = PJ_FALSE;\n\n    /* Add reference to the transport */\n    if (tsx->transport != regc->last_transport) {\n\tif (regc->last_transport) {\n\t    pjsip_transport_dec_ref(regc->last_transport);\n\t    regc->last_transport = NULL;\n\t}\n\n\tif (tsx->transport) {\n\t    regc->last_transport = tsx->transport;\n\t    pjsip_transport_add_ref(regc->last_transport);\n\t}\n    }\n\n    if (regc->_delete_flag == 0 && regc->tsx_cb &&\n        regc->current_op == REGC_REGISTERING)\n    {\n        struct pjsip_regc_tsx_cb_param param;\n\n        param.contact_cnt = -1;\n        cbparam_init(&param.cbparam, regc, PJ_SUCCESS, tsx->status_code,\n\t\t     &tsx->status_text,\n                     (event->body.tsx_state.type==PJSIP_EVENT_RX_MSG) ? \n\t              event->body.tsx_state.src.rdata : NULL,\n                     -1, 0, NULL);\n\n        /* Call regc tsx callback before handling any response */\n        pj_lock_release(regc->lock);\n        (*regc->tsx_cb)(&param);\n        pj_lock_acquire(regc->lock);\n\n        if (param.contact_cnt >= 0) {\n            /* Since we receive non-2xx response, it means that (some) contact\n             * bindings haven't been established so we can safely remove these\n             * contact headers. This is to avoid removing non-existent contact\n             * bindings later.\n             */\n            if (tsx->status_code/100 != 2) {\n                pjsip_contact_hdr *h;\n\n\t        h = regc->contact_hdr_list.next;\n\t        while (h != &regc->contact_hdr_list) {\n                    pjsip_contact_hdr *next = h->next;\n\n                    if (h->expires == -1) {\n                        pj_list_erase(h);\n                    }\n                    h = next;\n                }\n\t    }\n\n            /* Update contact address */\n            pjsip_regc_update_contact(regc, param.contact_cnt, param.contact);\n            update_contact = PJ_TRUE;\n        }\n    }\n\n    /* Handle 401/407 challenge (even when _delete_flag is set) */\n    if (tsx->status_code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED ||\n\ttsx->status_code == PJSIP_SC_UNAUTHORIZED)\n    {\n\tpjsip_rx_data *rdata = event->body.tsx_state.src.rdata;\n\tpjsip_tx_data *tdata;\n\n\t/* reset current op */\n\tregc->current_op = REGC_IDLE;\n\n        if (update_contact) {\n            pjsip_msg *msg;\n            pjsip_hdr *hdr, *ins_hdr;\n            pjsip_contact_hdr *chdr;\n\n            /* Delete Contact headers, but we shouldn't delete headers\n             * which are supposed to remove contact bindings since\n             * we cannot reconstruct those headers.\n             */\n            msg = tsx->last_tx->msg;\n            hdr = msg->hdr.next;\n            ins_hdr = &msg->hdr;\n            while (hdr != &msg->hdr) {\n                pjsip_hdr *next = hdr->next;\n\n                if (hdr->type == PJSIP_H_CONTACT) {\n                    chdr = (pjsip_contact_hdr *)hdr;\n                    if (chdr->expires != 0) {\n                        pj_list_erase(hdr);\n                        ins_hdr = next;\n                    }\n                }\n                hdr = next;\n            }\n\n            /* Add Contact headers. */\n            chdr = regc->contact_hdr_list.next;\n            while (chdr != &regc->contact_hdr_list) {\n\t        pj_list_insert_before(ins_hdr, (pjsip_hdr*)\n                    pjsip_hdr_shallow_clone(tsx->last_tx->pool, chdr));\n\t        chdr = chdr->next;\n            }\n\n            /* Also add bindings which are to be removed */\n            while (!pj_list_empty(&regc->removed_contact_hdr_list)) {\n\t        chdr = regc->removed_contact_hdr_list.next;\n\t        pj_list_insert_before(ins_hdr, (pjsip_hdr*)\n                    pjsip_hdr_clone(tsx->last_tx->pool, chdr));\n\t        pj_list_erase(chdr);\n            }\n        }\n\n        status = pjsip_auth_clt_reinit_req( &regc->auth_sess,\n\t\t\t\t\t    rdata, \n\t\t\t\t\t    tsx->last_tx,  \n\t\t\t\t\t    &tdata);\n\n\tif (status == PJ_SUCCESS) {\n\t    status = pjsip_regc_send(regc, tdata);\n\t}\n\t\n\tif (status != PJ_SUCCESS) {\n\n\t    /* Only call callback if application is still interested\n\t     * in it.\n\t     */\n\t    if (regc->_delete_flag == 0) {\n\t\t/* Should be safe to release the lock temporarily.\n\t\t * We do this to avoid deadlock. \n\t\t */\n\t\tpj_lock_release(regc->lock);\n\t\tcall_callback(regc, status, tsx->status_code, \n\t\t\t      &rdata->msg_info.msg->line.status.reason,\n\t\t\t      rdata, -1, 0, NULL);\n\t\tpj_lock_acquire(regc->lock);\n\t    }\n\t}\n\n    } else if (regc->_delete_flag) {\n\n\t/* User has called pjsip_regc_destroy(), so don't call callback. \n\t * This regc will be destroyed later in this function.\n\t */\n\n\t/* Just reset current op */\n\tregc->current_op = REGC_IDLE;\n\n    } else if (tsx->status_code == PJSIP_SC_INTERVAL_TOO_BRIEF &&\n\t       regc->current_op == REGC_REGISTERING)\n    {\n\t/* Handle 423 response automatically:\n\t *  - set requested expiration to Min-Expires header, ONLY IF\n\t *    the original request is a registration (as opposed to\n\t *    unregistration) and the requested expiration was indeed\n\t *    lower than Min-Expires)\n\t *  - resend the request\n\t */\n\tpjsip_rx_data *rdata = event->body.tsx_state.src.rdata;\n\tpjsip_min_expires_hdr *me_hdr;\n\tpjsip_tx_data *tdata;\n\tpj_int32_t min_exp;\n\n\t/* reset current op */\n\tregc->current_op = REGC_IDLE;\n\n\t/* Update requested expiration */\n\tme_hdr = (pjsip_min_expires_hdr*)\n\t\t pjsip_msg_find_hdr(rdata->msg_info.msg,\n\t\t\t\t    PJSIP_H_MIN_EXPIRES, NULL);\n\tif (me_hdr) {\n\t    min_exp = me_hdr->ivalue;\n\t} else {\n\t    /* Broken server, Min-Expires doesn't exist.\n\t     * Just guestimate then, BUT ONLY if if this is the\n\t     * first time we received such response.\n\t     */\n\t    enum {\n\t\t/* Note: changing this value would require changing couple of\n\t\t *       Python test scripts.\n\t\t */\n\t\tUNSPECIFIED_MIN_EXPIRES = 3601\n\t    };\n\t    if (!regc->expires_hdr ||\n\t\t regc->expires_hdr->ivalue != UNSPECIFIED_MIN_EXPIRES)\n\t    {\n\t\tmin_exp = UNSPECIFIED_MIN_EXPIRES;\n\t    } else {\n\t\thandled = PJ_FALSE;\n\t\tPJ_LOG(4,(THIS_FILE, \"Registration failed: 423 response \"\n\t\t\t\t     \"without Min-Expires header is invalid\"));\n\t\tgoto handle_err;\n\t    }\n\t}\n\n\tif (regc->expires_hdr && regc->expires_hdr->ivalue >= min_exp) {\n\t    /* But we already send with greater expiration time, why does\n\t     * the server send us with 423? Oh well, just fail the request.\n\t     */\n\t    handled = PJ_FALSE;\n\t    PJ_LOG(4,(THIS_FILE, \"Registration failed: invalid \"\n\t\t\t         \"Min-Expires header value in response\"));\n\t    goto handle_err;\n\t}\n\n\tset_expires(regc, min_exp);\n\n\tstatus = pjsip_regc_register(regc, regc->auto_reg, &tdata);\n\tif (status == PJ_SUCCESS) {\n\t    status = pjsip_regc_send(regc, tdata);\n\t}\n\n\tif (status != PJ_SUCCESS) {\n\t    /* Only call callback if application is still interested\n\t     * in it.\n\t     */\n\t    if (!regc->_delete_flag) {\n\t\t/* Should be safe to release the lock temporarily.\n\t\t * We do this to avoid deadlock.\n\t\t */\n\t\tpj_lock_release(regc->lock);\n\t\tcall_callback(regc, status, tsx->status_code,\n\t\t\t      &rdata->msg_info.msg->line.status.reason,\n\t\t\t      rdata, -1, 0, NULL);\n\t\tpj_lock_acquire(regc->lock);\n\t    }\n\t}\n\n    } else {\n\thandled = PJ_FALSE;\n    }\n\nhandle_err:\n    if (!handled) {\n\tpjsip_rx_data *rdata;\n\tpj_int32_t expiration = NOEXP;\n\tunsigned contact_cnt = 0;\n\tpjsip_contact_hdr *contact[PJSIP_REGC_MAX_CONTACT];\n\n\tif (tsx->status_code/100 == 2) {\n\n\t    rdata = event->body.tsx_state.src.rdata;\n\n\t    /* Calculate expiration */\n\t    expiration = calculate_response_expiration(regc, rdata, \n\t\t\t\t\t\t       &contact_cnt,\n\t\t\t\t\t\t       PJSIP_REGC_MAX_CONTACT,\n\t\t\t\t\t\t       contact);\n\n\t    /* Schedule next registration */\n            schedule_registration(regc, expiration);\n\n\t} else {\n\t    rdata = (event->body.tsx_state.type==PJSIP_EVENT_RX_MSG) ? \n\t\t\tevent->body.tsx_state.src.rdata : NULL;\n\t}\n\n\t/* Update registration */\n\tif (expiration==NOEXP) expiration=-1;\n\tregc->expires = expiration;\n\n\t/* Mark operation as complete */\n\tregc->current_op = REGC_IDLE;\n\n\t/* Call callback. */\n\t/* Should be safe to release the lock temporarily.\n\t * We do this to avoid deadlock. \n\t */\n\tpj_lock_release(regc->lock);\n\tcall_callback(regc, PJ_SUCCESS, tsx->status_code, \n\t\t      (rdata ? &rdata->msg_info.msg->line.status.reason \n\t\t\t: &tsx->status_text),\n\t\t      rdata, expiration, \n\t\t      contact_cnt, contact);\n\tpj_lock_acquire(regc->lock);\n    }\n\n    pj_lock_release(regc->lock);\n\n    /* Delete the record if user destroy regc during the callback. */\n    if (pj_atomic_dec_and_get(regc->busy_ctr)==0 && regc->_delete_flag) {\n\tpjsip_regc_destroy(regc);\n    }\n}\n\nPJ_DEF(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata)\n{\n    pj_status_t status;\n    pjsip_cseq_hdr *cseq_hdr;\n    pjsip_expires_hdr *expires_hdr;\n    pj_uint32_t cseq;\n\n    pj_atomic_inc(regc->busy_ctr);\n    pj_lock_acquire(regc->lock);\n\n    /* Make sure we don't have pending transaction. */\n    if (regc->has_tsx) {\n\tPJ_LOG(4,(THIS_FILE, \"Unable to send request, regc has another \"\n\t\t\t     \"transaction pending\"));\n\tpjsip_tx_data_dec_ref( tdata );\n\tpj_lock_release(regc->lock);\n\tpj_atomic_dec(regc->busy_ctr);\n\treturn PJSIP_EBUSY;\n    }\n\n    /* Just regc->has_tsx check above should be enough. This assertion check\n     * may cause problem, e.g: when regc_tsx_callback() invokes callback,\n     * lock is released and 'has_tsx' is set to FALSE and 'current_op' has\n     * not been updated to REGC_IDLE yet.\n     */\n    //pj_assert(regc->current_op == REGC_IDLE);\n\n    /* Invalidate message buffer. */\n    pjsip_tx_data_invalidate_msg(tdata);\n\n    /* Increment CSeq */\n    cseq = ++regc->cseq_hdr->cseq;\n    cseq_hdr = (pjsip_cseq_hdr*)\n\t       pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);\n    cseq_hdr->cseq = cseq;\n\n    /* Find Expires header */\n    expires_hdr = (pjsip_expires_hdr*)\n\t\t  pjsip_msg_find_hdr(tdata->msg, PJSIP_H_EXPIRES, NULL);\n\n    /* Bind to transport selector */\n    pjsip_tx_data_set_transport(tdata, &regc->tp_sel);\n\n    regc->has_tsx = PJ_TRUE;\n\n    /* Set current operation based on the value of Expires header */\n    if (expires_hdr && expires_hdr->ivalue==0)\n\tregc->current_op = REGC_UNREGISTERING;\n    else\n\tregc->current_op = REGC_REGISTERING;\n    \n    if (expires_hdr && expires_hdr->ivalue)\n\tregc->expires_requested = expires_hdr->ivalue;\n\n    /* Prevent deletion of tdata, e.g: when something wrong in sending,\n     * we need tdata to retrieve the transport.\n     */\n    pjsip_tx_data_add_ref(tdata);\n\n    /* If via_addr is set, use this address for the Via header. */\n    if (regc->via_addr.host.slen > 0) {\n        tdata->via_addr = regc->via_addr;\n        tdata->via_tp = regc->via_tp;\n    }\n\n    /* Need to unlock the regc temporarily while sending the message to\n     * prevent deadlock (https://trac.pjsip.org/repos/ticket/1247).\n     * It should be safe to do this since the regc's refcount has been\n     * incremented.\n     */\n    pj_lock_release(regc->lock);\n\n    /* Now send the message */\n    status = pjsip_endpt_send_request(regc->endpt, tdata, REGC_TSX_TIMEOUT,\n\t\t\t\t      regc, &regc_tsx_callback);\n    if (status!=PJ_SUCCESS) {\n\tPJ_LOG(4,(THIS_FILE, \"Error sending request, status=%d\", status));\n    }\n\n    /* Reacquire the lock */\n    pj_lock_acquire(regc->lock);\n\n    /* Get last transport used and add reference to it */\n    if (tdata->tp_info.transport != regc->last_transport &&\n\tstatus==PJ_SUCCESS)\n    {\n\tif (regc->last_transport) {\n\t    pjsip_transport_dec_ref(regc->last_transport);\n\t    regc->last_transport = NULL;\n\t}\n\n\tif (tdata->tp_info.transport) {\n\t    regc->last_transport = tdata->tp_info.transport;\n\t    pjsip_transport_add_ref(regc->last_transport);\n\t}\n    }\n\n    /* Release tdata */\n    pjsip_tx_data_dec_ref(tdata);\n\n    pj_lock_release(regc->lock);\n\n    /* Delete the record if user destroy regc during the callback. */\n    if (pj_atomic_dec_and_get(regc->busy_ctr)==0 && regc->_delete_flag) {\n\tpjsip_regc_destroy(regc);\n    }\n\n    return status;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-ua/sip_replaces.c",
    "content": "/* $Id: sip_replaces.c 4268 2012-09-28 08:56:08Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-ua/sip_replaces.h>\n#include <pjsip-ua/sip_inv.h>\n#include <pjsip/print_util.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_parser.h>\n#include <pjsip/sip_transport.h>\n#include <pjsip/sip_ua_layer.h>\n#include <pjsip/sip_util.h>\n#include <pj/assert.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n#define THIS_FILE\t\t\"sip_replaces.c\"\n\n\n/*\n * Replaces header vptr.\n */\nstatic int replaces_hdr_print( pjsip_replaces_hdr *hdr, \n\t\t\t       char *buf, pj_size_t size);\nstatic pjsip_replaces_hdr* replaces_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t       const pjsip_replaces_hdr *hdr);\nstatic pjsip_replaces_hdr* replaces_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t\t\t\t       const pjsip_replaces_hdr*);\n\nstatic pjsip_hdr_vptr replaces_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &replaces_hdr_clone,\n    (pjsip_hdr_clone_fptr) &replaces_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &replaces_hdr_print,\n};\n\n/* Globals */\nstatic pjsip_endpoint *the_endpt;\nstatic pj_bool_t is_initialized;\n\nPJ_DEF(pjsip_replaces_hdr*) pjsip_replaces_hdr_create(pj_pool_t *pool)\n{\n    pjsip_replaces_hdr *hdr = PJ_POOL_ZALLOC_T(pool, pjsip_replaces_hdr);\n    hdr->type = PJSIP_H_OTHER;\n    hdr->name.ptr = \"Replaces\";\n    hdr->name.slen = 8;\n    hdr->vptr = &replaces_hdr_vptr;\n    pj_list_init(hdr);\n    pj_list_init(&hdr->other_param);\n    return hdr;\n}\n\nstatic int replaces_hdr_print( pjsip_replaces_hdr *hdr, \n\t\t\t       char *buf, pj_size_t size)\n{\n    char *p = buf;\n    char *endbuf = buf+size;\n    pj_ssize_t printed;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    copy_advance(p, hdr->name);\n    *p++ = ':';\n    *p++ = ' ';\n\n    copy_advance(p, hdr->call_id);\n    copy_advance_pair(p, \";to-tag=\", 8, hdr->to_tag);\n    copy_advance_pair(p, \";from-tag=\", 10, hdr->from_tag);\n\n    if (hdr->early_only) {\n\tconst pj_str_t str_early_only = { \";early-only\", 11 };\n\tcopy_advance(p, str_early_only);\n    }\n    \n    printed = pjsip_param_print_on(&hdr->other_param, p, endbuf-p,\n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, \n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, ';');\n    if (printed < 0)\n\treturn (int)printed;\n\n    p += printed;\n    return (int)(p - buf);\n}\n\nstatic pjsip_replaces_hdr* replaces_hdr_clone( pj_pool_t *pool, \n\t\t\t\t\t       const pjsip_replaces_hdr *rhs)\n{\n    pjsip_replaces_hdr *hdr = pjsip_replaces_hdr_create(pool);\n    pj_strdup(pool, &hdr->call_id, &rhs->call_id);\n    pj_strdup(pool, &hdr->to_tag, &rhs->to_tag);\n    pj_strdup(pool, &hdr->from_tag, &rhs->from_tag);\n    hdr->early_only = rhs->early_only;\n    pjsip_param_clone(pool, &hdr->other_param, &rhs->other_param);\n    return hdr;\n}\n\nstatic pjsip_replaces_hdr* \nreplaces_hdr_shallow_clone( pj_pool_t *pool,\n\t\t\t    const pjsip_replaces_hdr *rhs )\n{\n    pjsip_replaces_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_replaces_hdr);\n    pj_memcpy(hdr, rhs, sizeof(*hdr));\n    pjsip_param_shallow_clone(pool, &hdr->other_param, &rhs->other_param);\n    return hdr;\n}\n\n\n/*\n * Parse Replaces header.\n */\nstatic pjsip_hdr *parse_hdr_replaces(pjsip_parse_ctx *ctx)\n{\n    pjsip_replaces_hdr *hdr = pjsip_replaces_hdr_create(ctx->pool);\n    const pj_str_t to_tag = { \"to-tag\", 6 };\n    const pj_str_t from_tag = { \"from-tag\", 8 };\n    const pj_str_t early_only_tag = { \"early-only\", 10 };\n\n    /*pj_scan_get(ctx->scanner, &pjsip_TOKEN_SPEC, &hdr->call_id);*/\n    /* Get Call-ID (until ';' is found). using pjsip_TOKEN_SPEC doesn't work\n     * because it stops parsing when '@' character is found.\n     */\n    pj_scan_get_until_ch(ctx->scanner, ';', &hdr->call_id);\n\n    while (*ctx->scanner->curptr == ';') {\n\tpj_str_t pname, pvalue;\n\n\tpj_scan_get_char(ctx->scanner);\n\tpjsip_parse_param_imp(ctx->scanner, ctx->pool, &pname, &pvalue, 0);\n\n\tif (pj_stricmp(&pname, &to_tag)==0) {\n\t    hdr->to_tag = pvalue;\n\t} else if (pj_stricmp(&pname, &from_tag)==0) {\n\t    hdr->from_tag = pvalue;\n\t} else if (pj_stricmp(&pname, &early_only_tag)==0) {\n\t    hdr->early_only = PJ_TRUE;\n\t} else {\n\t    pjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);\n\t    param->name = pname;\n\t    param->value = pvalue;\n\t    pj_list_push_back(&hdr->other_param, param);\n\t}\n    }\n    pjsip_parse_end_hdr_imp( ctx->scanner );\n    return (pjsip_hdr*)hdr;\n}\n\n\n/* Deinitialize Replaces */\nstatic void pjsip_replaces_deinit_module(pjsip_endpoint *endpt)\n{\n    PJ_TODO(provide_initialized_flag_for_each_endpoint);\n    PJ_UNUSED_ARG(endpt);\n    is_initialized = PJ_FALSE;\n}\n\n/*\n * Initialize Replaces support in PJSIP. \n */\nPJ_DEF(pj_status_t) pjsip_replaces_init_module(pjsip_endpoint *endpt)\n{\n    pj_status_t status;\n    const pj_str_t STR_REPLACES = { \"replaces\", 8 };\n\n    the_endpt = endpt;\n\n    if (is_initialized)\n\treturn PJ_SUCCESS;\n\n    /* Register Replaces header parser */\n    status = pjsip_register_hdr_parser( \"Replaces\", NULL, \n\t\t\t\t        &parse_hdr_replaces);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Register \"replaces\" capability */\n    status = pjsip_endpt_add_capability(endpt, NULL, PJSIP_H_SUPPORTED, NULL,\n\t\t\t\t\t1, &STR_REPLACES);\n\n    /* Register deinit module to be executed when PJLIB shutdown */\n    if (pjsip_endpt_atexit(endpt, &pjsip_replaces_deinit_module) != PJ_SUCCESS)\n    {\n\t/* Failure to register this function may cause this module won't \n\t * work properly when the stack is restarted (without quitting \n\t * application).\n\t */\n\tpj_assert(!\"Failed to register Replaces deinit.\");\n\tPJ_LOG(1, (THIS_FILE, \"Failed to register Replaces deinit.\"));\n    }\n\n    is_initialized = PJ_TRUE;\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Verify that incoming request with Replaces header can be processed.\n */\nPJ_DEF(pj_status_t) pjsip_replaces_verify_request( pjsip_rx_data *rdata,\n\t\t\t\t\t\t   pjsip_dialog **p_dlg,\n\t\t\t\t\t\t   pj_bool_t lock_dlg,\n\t\t\t\t\t\t   pjsip_tx_data **p_tdata)\n{\n    const pj_str_t STR_REPLACES = { \"Replaces\", 8 };\n    pjsip_replaces_hdr *rep_hdr;\n    int code = 200;\n    const char *warn_text = NULL;\n    pjsip_hdr res_hdr_list;\n    pjsip_dialog *dlg = NULL;\n    pjsip_inv_session *inv;\n    pj_status_t status = PJ_SUCCESS;\n\n    PJ_ASSERT_RETURN(rdata && p_dlg, PJ_EINVAL);\n\n    /* Check that pjsip_replaces_init_module() has been called. */\n    PJ_ASSERT_RETURN(the_endpt != NULL, PJ_EINVALIDOP);\n\n\n    /* Init output arguments */\n    *p_dlg = NULL;\n    if (p_tdata) *p_tdata = NULL;\n\n    pj_list_init(&res_hdr_list);\n\n    /* Find Replaces header */\n    rep_hdr = (pjsip_replaces_hdr*) \n\t      pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &STR_REPLACES, \n\t\t\t\t\t NULL);\n    if (!rep_hdr) {\n\t/* No Replaces header. No further processing is necessary. */\n\treturn PJ_SUCCESS;\n    }\n\n\n    /* Check that there's no other Replaces header and return 400 Bad Request\n     * if not. \n     */\n    if (pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &STR_REPLACES, \n\t\t\t\t   rep_hdr->next)) {\n\tcode = PJSIP_SC_BAD_REQUEST;\n\twarn_text = \"Found multiple Replaces headers\";\n\tgoto on_return;\n    }\n\n    /* Find the dialog identified by Replaces header (and always lock the\n     * dialog no matter what application wants).\n     */\n    dlg = pjsip_ua_find_dialog(&rep_hdr->call_id, &rep_hdr->to_tag,\n\t\t\t       &rep_hdr->from_tag, PJ_TRUE);\n\n    /* Respond with 481 \"Call/Transaction Does Not Exist\" response if\n     * no dialog is found.\n     */\n    if (dlg == NULL) {\n\tcode = PJSIP_SC_CALL_TSX_DOES_NOT_EXIST;\n\twarn_text = \"No dialog found for Replaces request\";\n\tgoto on_return;\n    }\n\n    /* Get the invite session within the dialog */\n    inv = pjsip_dlg_get_inv_session(dlg);\n\n    /* Return 481 if no invite session is present. */\n    if (inv == NULL) {\n\tcode = PJSIP_SC_CALL_TSX_DOES_NOT_EXIST;\n\twarn_text = \"No INVITE session found for Replaces request\";\n\tgoto on_return;\n    }\n\n    /* Return 603 Declined response if invite session has already \n     * terminated \n     */\n    if (inv->state >= PJSIP_INV_STATE_DISCONNECTED) {\n\tcode = PJSIP_SC_DECLINE;\n\twarn_text = \"INVITE session already terminated\";\n\tgoto on_return;\n    }\n\n    /* If \"early-only\" flag is present, check that the invite session\n     * has not been confirmed yet. If the session has been confirmed, \n     * return 486 \"Busy Here\" response.\n     */\n    if (rep_hdr->early_only && inv->state >= PJSIP_INV_STATE_CONNECTING) {\n\tcode = PJSIP_SC_BUSY_HERE;\n\twarn_text = \"INVITE session already established\";\n\tgoto on_return;\n    }\n\n    /* If the Replaces header field matches an early dialog that was not\n     * initiated by this UA, it returns a 481 (Call/Transaction Does Not\n     * Exist) response to the new INVITE.\n     */\n    if (inv->state <= PJSIP_INV_STATE_EARLY && inv->role != PJSIP_ROLE_UAC)\n    {\n\t/* Really return 481 only if call haven't reached early state or\n\t * accept-replace-in-early-state (ticket #1587) is not allowed.\n\t */\n\tif (inv->state != PJSIP_INV_STATE_EARLY ||\n\t    pjsip_cfg()->endpt.accept_replace_in_early_state == PJ_FALSE)\n\t{\n\t    code = PJSIP_SC_CALL_TSX_DOES_NOT_EXIST;\n\t    warn_text = \"Found early INVITE session but not initiated by \"\n\t\t\t\"this UA\";\n\t    goto on_return;\n\t}\n    }\n\n\n    /*\n     * Looks like everything is okay!!\n     */\n    *p_dlg = dlg;\n    status = PJ_SUCCESS;\n    code = 200;\n\non_return:\n\n    /* Create response if necessary */\n    if (code != 200) {\n\t/* If we have dialog we must unlock it */\n\tif (dlg)\n\t    pjsip_dlg_dec_lock(dlg);\n\n\t/* Create response */\n\tif (p_tdata) {\n\t    pjsip_tx_data *tdata;\n\t    const pjsip_hdr *h;\n\n\t    status = pjsip_endpt_create_response(the_endpt, rdata, code, \n\t\t\t\t\t\t NULL, &tdata);\n\n\t    if (status != PJ_SUCCESS)\n\t\treturn status;\n\n\t    /* Add response headers. */\n\t    h = res_hdr_list.next;\n\t    while (h != &res_hdr_list) {\n\t\tpjsip_hdr *cloned;\n\n\t\tcloned = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, h);\n\t\tPJ_ASSERT_RETURN(cloned, PJ_ENOMEM);\n\n\t\tpjsip_msg_add_hdr(tdata->msg, cloned);\n\n\t\th = h->next;\n\t    }\n\n\t    /* Add warn text, if any */\n\t    if (warn_text) {\n\t\tpjsip_warning_hdr *warn_hdr;\n\t\tpj_str_t warn_value = pj_str((char*)warn_text);\n\n\t\twarn_hdr=pjsip_warning_hdr_create(tdata->pool, 399, \n\t\t\t\t\t\t  pjsip_endpt_name(the_endpt),\n\t\t\t\t\t\t  &warn_value);\n\t\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)warn_hdr);\n\t    }\n\n\t    *p_tdata = tdata;\n\t}\n\n\t/* Can not return PJ_SUCCESS when response message is produced.\n\t * Ref: PROTOS test ~#2490\n\t */\n\tif (status == PJ_SUCCESS)\n\t    status = PJSIP_ERRNO_FROM_SIP_STATUS(code);\n\n    } else {\n\t/* If application doesn't want to lock the dialog, unlock it */\n\tif (!lock_dlg)\n\t    pjsip_dlg_dec_lock(dlg);\n    }\n\n    return status;\n}\n\n\n\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-ua/sip_timer.c",
    "content": "/* $Id: sip_timer.c 4213 2012-07-23 13:31:26Z nanang $ */\n/* \n * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-ua/sip_timer.h>\n#include <pjsip/print_util.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_event.h>\n#include <pjsip/sip_transaction.h>\n#include <pj/log.h>\n#include <pj/math.h>\n#include <pj/os.h>\n#include <pj/pool.h>\n\n#define THIS_FILE\t\t\"sip_timer.c\"\n\n\n/* Constant of Session Timers */\n#define ABS_MIN_SE\t\t    90\t/* Absolute Min-SE, in seconds\t    */\n#define REFRESHER_EXPIRE_TIMER_ID   2\t/* Refresher expire timer id\t    */ \n\n/* String definitions */\nstatic const pj_str_t STR_SE\t\t= {\"Session-Expires\", 15};\nstatic const pj_str_t STR_SHORT_SE\t= {\"x\", 1};\nstatic const pj_str_t STR_MIN_SE\t= {\"Min-SE\", 6};\nstatic const pj_str_t STR_REFRESHER\t= {\"refresher\", 9};\nstatic const pj_str_t STR_UAC\t\t= {\"uac\", 3};\nstatic const pj_str_t STR_UAS\t\t= {\"uas\", 3};\nstatic const pj_str_t STR_TIMER\t\t= {\"timer\", 5};\n\n\n/* Enumeration of refresher */\nenum timer_refresher {\n    TR_UNKNOWN,\n    TR_UAC,\n    TR_UAS\n};\n\n/* Structure definition of Session Timers */\nstruct pjsip_timer \n{\n    pj_bool_t\t\t\t active;\t/**< Active/inactive flag   */\n    pjsip_timer_setting\t\t setting;\t/**< Session Timers setting */\n    enum timer_refresher\t refresher;\t/**< Session refresher\t    */\n    pj_time_val\t\t\t last_refresh;\t/**< Timestamp of last\n\t\t\t\t\t\t     refresh\t\t    */\n    pj_timer_entry\t\t timer;\t\t/**< Timer entry\t    */\n    pj_bool_t\t\t\t use_update;\t/**< Use UPDATE method to\n\t\t\t\t\t\t     refresh the session    */\n    pj_bool_t\t\t  \t with_sdp;\t/**< SDP in UPDATE?\t    */\n    pjsip_role_e\t\t role;\t\t/**< Role in last INVITE/\n\t\t\t\t\t\t     UPDATE transaction.    */    \n    void\t\t\t*refresh_tdata; /**< The tdata of refresh \n\t\t\t\t\t\t     request\t\t    */\n    pj_timer_entry\t\t expire_timer;\t/**< Timer entry for expire \n\t\t\t\t\t\t     refresher\t\t    */\n};\n\n/* External global vars */\nextern pj_bool_t pjsip_use_compact_form;\n\n/* Local functions & vars */\nstatic void stop_timer(pjsip_inv_session *inv);\nstatic void start_timer(pjsip_inv_session *inv);\nstatic pj_bool_t is_initialized;\nconst pjsip_method pjsip_update_method = { PJSIP_OTHER_METHOD, {\"UPDATE\", 6}};\n/*\n * Session-Expires header vptr.\n */\nstatic int se_hdr_print(pjsip_sess_expires_hdr *hdr, \n\t\t\tchar *buf, pj_size_t size);\nstatic pjsip_sess_expires_hdr* se_hdr_clone(pj_pool_t *pool, \n\t\t\t\t\t    const pjsip_sess_expires_hdr *hdr);\nstatic pjsip_sess_expires_hdr* se_hdr_shallow_clone( \n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    const pjsip_sess_expires_hdr* hdr);\n\nstatic pjsip_hdr_vptr se_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &se_hdr_clone,\n    (pjsip_hdr_clone_fptr) &se_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &se_hdr_print,\n};\n\n/*\n * Min-SE header vptr.\n */\nstatic int min_se_hdr_print(pjsip_min_se_hdr *hdr, \n\t\t\t    char *buf, pj_size_t size);\nstatic pjsip_min_se_hdr* min_se_hdr_clone(pj_pool_t *pool, \n\t\t\t\t\t  const pjsip_min_se_hdr *hdr);\nstatic pjsip_min_se_hdr* min_se_hdr_shallow_clone( \n\t\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t\t  const pjsip_min_se_hdr* hdr);\n\nstatic pjsip_hdr_vptr min_se_hdr_vptr = \n{\n    (pjsip_hdr_clone_fptr) &min_se_hdr_clone,\n    (pjsip_hdr_clone_fptr) &min_se_hdr_shallow_clone,\n    (pjsip_hdr_print_fptr) &min_se_hdr_print,\n};\n\n/*\n * Session-Expires header vptr.\n */\nstatic int se_hdr_print(pjsip_sess_expires_hdr *hdr, \n\t\t\tchar *buf, pj_size_t size)\n{\n    char *p = buf;\n    char *endbuf = buf+size;\n    pj_ssize_t printed;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;\n\n    /* Print header name and value */\n    if ((endbuf - p) < (hname->slen + 16))\n\treturn -1;\n\n    copy_advance(p, (*hname));\n    *p++ = ':';\n    *p++ = ' ';\n\n    printed = pj_utoa(hdr->sess_expires, p);\n    p += printed;\n\n    /* Print 'refresher' param */\n    if (hdr->refresher.slen)\n    {\n\tif  ((endbuf - p) < (STR_REFRESHER.slen + 2 + hdr->refresher.slen))\n\t    return -1;\n\n\t*p++ = ';';\n\tcopy_advance(p, STR_REFRESHER);\n\t*p++ = '=';\n\tcopy_advance(p, hdr->refresher);\n    }\n\n    /* Print generic params */\n    printed = pjsip_param_print_on(&hdr->other_param, p, endbuf-p,\n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, \n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, ';');\n    if (printed < 0)\n\treturn (int)printed;\n\n    p += printed;\n    return (int)(p - buf);\n}\n\nstatic pjsip_sess_expires_hdr* se_hdr_clone(pj_pool_t *pool, \n\t\t\t\t\t    const pjsip_sess_expires_hdr *hsrc)\n{\n    pjsip_sess_expires_hdr *hdr = pjsip_sess_expires_hdr_create(pool);\n    hdr->sess_expires = hsrc->sess_expires;\n    pj_strdup(pool, &hdr->refresher, &hsrc->refresher);\n    pjsip_param_clone(pool, &hdr->other_param, &hsrc->other_param);\n    return hdr;\n}\n\nstatic pjsip_sess_expires_hdr* se_hdr_shallow_clone( \n\t\t\t\t\t    pj_pool_t *pool,\n\t\t\t\t\t    const pjsip_sess_expires_hdr* hsrc)\n{\n    pjsip_sess_expires_hdr *hdr = PJ_POOL_ALLOC_T(pool,pjsip_sess_expires_hdr);\n    pj_memcpy(hdr, hsrc, sizeof(*hdr));\n    pjsip_param_shallow_clone(pool, &hdr->other_param, &hsrc->other_param);\n    return hdr;\n}\n\n/*\n * Min-SE header vptr.\n */\nstatic int min_se_hdr_print(pjsip_min_se_hdr *hdr, \n\t\t\t    char *buf, pj_size_t size)\n{\n    char *p = buf;\n    char *endbuf = buf+size;\n    pj_ssize_t printed;\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n\n    /* Print header name and value */\n    if ((endbuf - p) < (hdr->name.slen + 16))\n\treturn -1;\n\n    copy_advance(p, hdr->name);\n    *p++ = ':';\n    *p++ = ' ';\n\n    printed = pj_utoa(hdr->min_se, p);\n    p += printed;\n\n    /* Print generic params */\n    printed = pjsip_param_print_on(&hdr->other_param, p, endbuf-p,\n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, \n\t\t\t\t   &pc->pjsip_TOKEN_SPEC, ';');\n    if (printed < 0)\n\treturn (int)printed;\n\n    p += printed;\n    return (int)(p - buf);\n}\n\nstatic pjsip_min_se_hdr* min_se_hdr_clone(pj_pool_t *pool, \n\t\t\t\t\t  const pjsip_min_se_hdr *hsrc)\n{\n    pjsip_min_se_hdr *hdr = pjsip_min_se_hdr_create(pool);\n    hdr->min_se = hsrc->min_se;\n    pjsip_param_clone(pool, &hdr->other_param, &hsrc->other_param);\n    return hdr;\n}\n\nstatic pjsip_min_se_hdr* min_se_hdr_shallow_clone( \n\t\t\t\t\t  pj_pool_t *pool,\n\t\t\t\t\t  const pjsip_min_se_hdr* hsrc)\n{\n    pjsip_min_se_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_min_se_hdr);\n    pj_memcpy(hdr, hsrc, sizeof(*hdr));\n    pjsip_param_shallow_clone(pool, &hdr->other_param, &hsrc->other_param);\n    return hdr;\n}\n\n\n/*\n * Parse Session-Expires header.\n */\nstatic pjsip_hdr *parse_hdr_se(pjsip_parse_ctx *ctx)\n{\n    pjsip_sess_expires_hdr *hdr = pjsip_sess_expires_hdr_create(ctx->pool);\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n    pj_str_t token;\n\n    pj_scan_get(ctx->scanner, &pc->pjsip_DIGIT_SPEC, &token);\n    hdr->sess_expires = pj_strtoul(&token);\n\n    while (*ctx->scanner->curptr == ';') {\n\tpj_str_t pname, pvalue;\n\n\tpj_scan_get_char(ctx->scanner);\n\tpjsip_parse_param_imp(ctx->scanner, ctx->pool, &pname, &pvalue, 0);\n\n\tif (pj_stricmp(&pname, &STR_REFRESHER)==0) {\n\t    hdr->refresher = pvalue;\n\t} else {\n\t    pjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);\n\t    param->name = pname;\n\t    param->value = pvalue;\n\t    pj_list_push_back(&hdr->other_param, param);\n\t}\n    }\n    pjsip_parse_end_hdr_imp( ctx->scanner );\n    return (pjsip_hdr*)hdr;\n}\n\n/*\n * Parse Min-SE header.\n */\nstatic pjsip_hdr *parse_hdr_min_se(pjsip_parse_ctx *ctx)\n{\n    pjsip_min_se_hdr *hdr = pjsip_min_se_hdr_create(ctx->pool);\n    const pjsip_parser_const_t *pc = pjsip_parser_const();\n    pj_str_t token;\n\n    pj_scan_get(ctx->scanner, &pc->pjsip_DIGIT_SPEC, &token);\n    hdr->min_se = pj_strtoul(&token);\n\n    while (*ctx->scanner->curptr == ';') {\n\tpj_str_t pname, pvalue;\n\tpjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);\n\n\tpj_scan_get_char(ctx->scanner);\n\tpjsip_parse_param_imp(ctx->scanner, ctx->pool, &pname, &pvalue, 0);\n\n\tparam->name = pname;\n\tparam->value = pvalue;\n\tpj_list_push_back(&hdr->other_param, param);\n    }\n    pjsip_parse_end_hdr_imp( ctx->scanner );\n    return (pjsip_hdr*)hdr;\n}\n\n\n/* Add \"Session-Expires\" and \"Min-SE\" headers. Note that \"Min-SE\" header\n * can only be added to INVITE/UPDATE request and 422 response.\n */\nstatic void add_timer_headers(pjsip_inv_session *inv, pjsip_tx_data *tdata,\n\t\t\t      pj_bool_t add_se, pj_bool_t add_min_se)\n{\n    pjsip_timer *timer = inv->timer;\n\n    /* Add Session-Expires header */\n    if (add_se) {\n\tpjsip_sess_expires_hdr *hdr;\n\n\thdr = pjsip_sess_expires_hdr_create(tdata->pool);\n\thdr->sess_expires = timer->setting.sess_expires;\n\tif (timer->refresher != TR_UNKNOWN)\n\t    hdr->refresher = (timer->refresher == TR_UAC? STR_UAC : STR_UAS);\n\n\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) hdr);\n    }\n\n    /* Add Min-SE header */\n    if (add_min_se) {\n\tpjsip_min_se_hdr *hdr;\n\n\thdr = pjsip_min_se_hdr_create(tdata->pool);\n\thdr->min_se = timer->setting.min_se;\n\n\tpjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) hdr);\n    }\n}\n\n/* Timer callback. When the timer is fired, it can be time to refresh\n * the session if UA is the refresher, otherwise it is time to end \n * the session.\n */\nstatic void timer_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)\n{\n    pjsip_inv_session *inv = (pjsip_inv_session*) entry->user_data;\n    pjsip_tx_data *tdata = NULL;\n    pj_status_t status;\n    pj_bool_t as_refresher;\n\n    pj_assert(inv);\n\n    PJ_UNUSED_ARG(timer_heap);\n\n    /* Lock dialog. */\n    pjsip_dlg_inc_lock(inv->dlg);\n\n    /* Check our role */\n    as_refresher =\n\t(inv->timer->refresher == TR_UAC && inv->timer->role == PJSIP_ROLE_UAC) ||\n\t(inv->timer->refresher == TR_UAS && inv->timer->role == PJSIP_ROLE_UAS);    \n\n    /* Do action based on role(refresher or refreshee). \n     * As refresher:\n     * - send refresh, or  \n     * - end session if there is no response to the refresh request.\n     * As refreshee:\n     * - end session if there is no refresh request received.\n     */\n    if (as_refresher && (entry->id != REFRESHER_EXPIRE_TIMER_ID)) {\n\tpj_time_val now;\n\n\t/* As refresher, reshedule the refresh request on the following:\n\t *  - must not send re-INVITE if another INVITE or SDP negotiation\n\t *    is in progress.\n\t *  - must not send UPDATE with SDP if SDP negotiation is in progress\n\t */\n\tpjmedia_sdp_neg_state neg_state = pjmedia_sdp_neg_get_state(inv->neg);\n\n\tinv->timer->timer.id = 0;\n\n\tif ( (!inv->timer->use_update && (\n\t\t\tinv->invite_tsx != NULL ||\n\t\t\tneg_state != PJMEDIA_SDP_NEG_STATE_DONE)\n             )\n\t     ||\n\t     (inv->timer->use_update && inv->timer->with_sdp &&\n\t\t     neg_state != PJMEDIA_SDP_NEG_STATE_DONE\n\t     )\n\t   )\n\t{\n\t    pj_time_val delay = {1, 0};\n\n\t    inv->timer->timer.id = 1;\n\t    pjsip_endpt_schedule_timer(inv->dlg->endpt, &inv->timer->timer,\n\t\t\t\t       &delay);\n\t    pjsip_dlg_dec_lock(inv->dlg);\n\t    return;\n\t}\n\n\t/* Refresher, refresh the session */\n\tif (inv->timer->use_update) {\n\t    const pjmedia_sdp_session *offer = NULL;\n\n\t    if (inv->timer->with_sdp) {\n\t\tpjmedia_sdp_neg_get_active_local(inv->neg, &offer);\n\t    }\n\t    status = pjsip_inv_update(inv, NULL, offer, &tdata);\n\t} else {\n\t    /* Create re-INVITE without modifying session */\n\t    pjsip_msg_body *body;\n\t    const pjmedia_sdp_session *offer = NULL;\n\n\t    pj_assert(pjmedia_sdp_neg_get_state(inv->neg) == \n\t\t      PJMEDIA_SDP_NEG_STATE_DONE);\n\n\t    status = pjsip_inv_invite(inv, &tdata);\n\t    if (status == PJ_SUCCESS)\n\t\tstatus = pjmedia_sdp_neg_send_local_offer(inv->pool_prov, \n\t\t\t\t\t\t\t  inv->neg, &offer);\n\t    if (status == PJ_SUCCESS)\n\t\tstatus = pjmedia_sdp_neg_get_neg_local(inv->neg, &offer);\n\t    if (status == PJ_SUCCESS) {\n\t\tstatus = pjsip_create_sdp_body(tdata->pool, \n\t\t\t\t\t(pjmedia_sdp_session*)offer, &body);\n\t\ttdata->msg->body = body;\n\t    }\n\t}\n\n\tpj_gettimeofday(&now);\n\tPJ_LOG(4, (inv->pool->obj_name,\n\t\t   \"Refreshing session after %ds (expiration period=%ds)\",\n\t\t   (now.sec-inv->timer->last_refresh.sec),\n\t\t   inv->timer->setting.sess_expires));\n    } else {\n\t\n\tpj_time_val now;\n\n\tif (as_refresher)\n\t    inv->timer->expire_timer.id = 0;\n\telse\n\t    inv->timer->timer.id = 0;\n\n\t/* Terminate the session */\n\tstatus = pjsip_inv_end_session(inv, PJSIP_SC_REQUEST_TIMEOUT, \n\t\t\t\t       NULL, &tdata);\n\n\tpj_gettimeofday(&now);\n\tPJ_LOG(3, (inv->pool->obj_name, \n\t\t   \"No session %s received after %ds \"\n\t\t   \"(expiration period=%ds), stopping session now!\",\n\t\t   (as_refresher?\"refresh response\":\"refresh\"),\n\t\t   (now.sec-inv->timer->last_refresh.sec),\n\t\t   inv->timer->setting.sess_expires));\n\n    }\n\n    /* Unlock dialog. */\n    pjsip_dlg_dec_lock(inv->dlg);\n\n    /* Send message, if any */\n    if (tdata && status == PJ_SUCCESS) {\n\tinv->timer->refresh_tdata = tdata;\n\n\tstatus = pjsip_inv_send_msg(inv, tdata);\t\n    }\n\n    /* Print error message, if any */\n    if (status != PJ_SUCCESS) {\n\tPJ_PERROR(2, (inv->pool->obj_name, status,\n\t\t     \"Error in %s session timer\",\n\t\t     ((as_refresher && entry->id != REFRESHER_EXPIRE_TIMER_ID)? \n\t\t       \"refreshing\" : \"terminating\")));\n    }\n}\n\n/* Start Session Timers */\nstatic void start_timer(pjsip_inv_session *inv)\n{\n    const pj_str_t UPDATE = { \"UPDATE\", 6 };\n    pjsip_timer *timer = inv->timer;\n    pj_time_val delay = {0};\n\n    pj_assert(inv->timer->active == PJ_TRUE);\n\n    stop_timer(inv);\n\n    inv->timer->use_update =\n\t    (pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL,\n\t\t\t\t      &UPDATE) == PJSIP_DIALOG_CAP_SUPPORTED);\n    if (!inv->timer->use_update) {\n\t/* INVITE always needs SDP */\n\tinv->timer->with_sdp = PJ_TRUE;\n    }\n\n    pj_timer_entry_init(&timer->timer,\n\t\t\t1,\t\t    /* id */\n\t\t\tinv,\t\t    /* user data */\n\t\t\ttimer_cb);\t    /* callback */\n    \n    /* Set delay based on role, refresher or refreshee */\n    if ((timer->refresher == TR_UAC && inv->timer->role == PJSIP_ROLE_UAC) ||\n\t(timer->refresher == TR_UAS && inv->timer->role == PJSIP_ROLE_UAS))\n    {\n\t/* Add refresher expire timer */\n\tpj_timer_entry_init(&timer->expire_timer,\n\t\t\t    REFRESHER_EXPIRE_TIMER_ID,\t    /* id */\n\t\t\t    inv,\t\t\t    /* user data */\n\t\t\t    timer_cb);\t\t\t    /* callback */\n\n\tdelay.sec = timer->setting.sess_expires;\n\t/* Schedule the timer */\n\tpjsip_endpt_schedule_timer(inv->dlg->endpt, &timer->expire_timer, \n\t\t\t\t   &delay);\n\n\t/* Next refresh, the delay is half of session expire */\n\tdelay.sec = timer->setting.sess_expires / 2;\n    } else {\n\t/* Send BYE if no refresh received until this timer fired, delay\n\t * is the minimum of 32 seconds and one third of the session interval\n\t * before session expiration.\n\t */\n\tdelay.sec = timer->setting.sess_expires - \n\t\t    timer->setting.sess_expires/3;\n\tdelay.sec = PJ_MAX((long)timer->setting.sess_expires-32, delay.sec);\n    }\n\n    /* Schedule the timer */\n    pjsip_endpt_schedule_timer(inv->dlg->endpt, &timer->timer, &delay);\n\n    /* Update last refresh time */\n    pj_gettimeofday(&timer->last_refresh);\n}\n\n/* Stop Session Timers */\nstatic void stop_timer(pjsip_inv_session *inv)\n{\n    if (inv->timer->timer.id != 0) {\n\tpjsip_endpt_cancel_timer(inv->dlg->endpt, &inv->timer->timer);\n\tinv->timer->timer.id = 0;\t\n    }\n\n    if (inv->timer->expire_timer.id != 0) {\n\tpjsip_endpt_cancel_timer(inv->dlg->endpt, &inv->timer->expire_timer);\n\tinv->timer->expire_timer.id = 0;\n    }\n}\n\n/* Deinitialize Session Timers */\nstatic void pjsip_timer_deinit_module(pjsip_endpoint *endpt)\n{\n    PJ_TODO(provide_initialized_flag_for_each_endpoint);\n    PJ_UNUSED_ARG(endpt);\n    is_initialized = PJ_FALSE;\n}\n\n/*\n * Initialize Session Timers support in PJSIP. \n */\nPJ_DEF(pj_status_t) pjsip_timer_init_module(pjsip_endpoint *endpt)\n{\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(endpt, PJ_EINVAL);\n\n    if (is_initialized)\n\treturn PJ_SUCCESS;\n\n    /* Register Session-Expires header parser */\n    status = pjsip_register_hdr_parser( STR_SE.ptr, STR_SHORT_SE.ptr, \n\t\t\t\t        &parse_hdr_se);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Register Min-SE header parser */\n    status = pjsip_register_hdr_parser( STR_MIN_SE.ptr, NULL, \n\t\t\t\t        &parse_hdr_min_se);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Register 'timer' capability to endpoint */\n    status = pjsip_endpt_add_capability(endpt, NULL, PJSIP_H_SUPPORTED,\n\t\t\t\t\tNULL, 1, &STR_TIMER);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Register deinit module to be executed when PJLIB shutdown */\n    if (pjsip_endpt_atexit(endpt, &pjsip_timer_deinit_module) != PJ_SUCCESS) {\n\t/* Failure to register this function may cause this module won't \n\t * work properly when the stack is restarted (without quitting \n\t * application).\n\t */\n\tpj_assert(!\"Failed to register Session Timer deinit.\");\n\tPJ_LOG(1, (THIS_FILE, \"Failed to register Session Timer deinit.\"));\n    }\n\n    is_initialized = PJ_TRUE;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Initialize Session Timers setting with default values.\n */\nPJ_DEF(pj_status_t) pjsip_timer_setting_default(pjsip_timer_setting *setting)\n{\n    pj_bzero(setting, sizeof(pjsip_timer_setting));\n\n    setting->sess_expires = PJSIP_SESS_TIMER_DEF_SE;\n    setting->min_se = ABS_MIN_SE;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Initialize Session Timers in an INVITE session. \n */\nPJ_DEF(pj_status_t) pjsip_timer_init_session(\n\t\t\t\t\tpjsip_inv_session *inv,\n\t\t\t\t\tconst pjsip_timer_setting *setting)\n{\n    pjsip_timer_setting *s;\n\n    pj_assert(is_initialized);\n    PJ_ASSERT_RETURN(inv, PJ_EINVAL);\n\n    /* Allocate and/or reset Session Timers structure */\n    if (!inv->timer)\n\tinv->timer = PJ_POOL_ZALLOC_T(inv->pool, pjsip_timer);\n    else\n\tpj_bzero(inv->timer, sizeof(pjsip_timer));\n\n    s = &inv->timer->setting;\n\n    /* Init Session Timers setting */\n    if (setting) {\n\tPJ_ASSERT_RETURN(setting->min_se >= ABS_MIN_SE,\n\t\t\t PJ_ETOOSMALL);\n\tPJ_ASSERT_RETURN(setting->sess_expires >= setting->min_se,\n\t\t\t PJ_EINVAL);\n\n\tpj_memcpy(s, setting, sizeof(*s));\n    } else {\n\tpjsip_timer_setting_default(s);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create Session-Expires header.\n */\nPJ_DEF(pjsip_sess_expires_hdr*) pjsip_sess_expires_hdr_create(\n\t\t\t\t\t\t\tpj_pool_t *pool)\n{\n    pjsip_sess_expires_hdr *hdr = PJ_POOL_ZALLOC_T(pool,\n\t\t\t\t\t\t   pjsip_sess_expires_hdr);\n\n    pj_assert(is_initialized);\n\n    hdr->type = PJSIP_H_OTHER;\n    hdr->name = STR_SE;\n    hdr->sname = STR_SHORT_SE;\n    hdr->vptr = &se_hdr_vptr;\n    pj_list_init(hdr);\n    pj_list_init(&hdr->other_param);\n    return hdr;\n}\n\n\n/*\n * Create Min-SE header.\n */\nPJ_DEF(pjsip_min_se_hdr*) pjsip_min_se_hdr_create(pj_pool_t *pool)\n{\n    pjsip_min_se_hdr *hdr = PJ_POOL_ZALLOC_T(pool, pjsip_min_se_hdr);\n\n    pj_assert(is_initialized);\n\n    hdr->type = PJSIP_H_OTHER;\n    hdr->name = STR_MIN_SE;\n    hdr->vptr = &min_se_hdr_vptr;\n    pj_list_init(hdr);\n    pj_list_init(&hdr->other_param);\n    return hdr;\n}\n\n\n/* \n * This function generates headers for Session Timers for intial and\n * refresh INVITE or UPDATE.\n */\nPJ_DEF(pj_status_t) pjsip_timer_update_req(pjsip_inv_session *inv,\n\t\t\t\t\t   pjsip_tx_data *tdata)\n{\n    PJ_ASSERT_RETURN(inv && tdata, PJ_EINVAL);\n\n    /* Check if Session Timers is supported */\n    if ((inv->options & PJSIP_INV_SUPPORT_TIMER) == 0)\n\treturn PJ_SUCCESS;\n\n    pj_assert(is_initialized);\n\n    /* Make sure Session Timers is initialized */\n    if (inv->timer == NULL)\n\tpjsip_timer_init_session(inv, NULL);\n\n    /* If refresher role (i.e: ours or peer) has been set/negotiated, \n     * better to keep it.\n     */\n    if (inv->timer->refresher != TR_UNKNOWN) {\n\tpj_bool_t as_refresher;\n\n\t/* Check our refresher role */\n\tas_refresher = \n\t    (inv->timer->refresher==TR_UAC && inv->timer->role==PJSIP_ROLE_UAC) ||\n\t    (inv->timer->refresher==TR_UAS && inv->timer->role==PJSIP_ROLE_UAS);\n\n\t/* Update transaction role */\n\tinv->timer->role = PJSIP_ROLE_UAC;\n\n\t/* Update refresher role */\n\tinv->timer->refresher = as_refresher? TR_UAC : TR_UAS;\n    }\n\n    /* Add Session Timers headers */\n    add_timer_headers(inv, tdata, PJ_TRUE, PJ_TRUE);\n\n    return PJ_SUCCESS;\n}\n\n/* \n * This function will handle Session Timers part of INVITE/UPDATE \n * responses with code:\n * - 422 (Session Interval Too Small)\n * - 2xx final response\n */\nPJ_DEF(pj_status_t) pjsip_timer_process_resp(pjsip_inv_session *inv,\n\t\t\t\t\t     const pjsip_rx_data *rdata,\n\t\t\t\t\t     pjsip_status_code *st_code)\n{\n    const pjsip_msg *msg;\n\n    PJ_ASSERT_ON_FAIL(inv && rdata,\n\t{if(st_code)*st_code=PJSIP_SC_INTERNAL_SERVER_ERROR;return PJ_EINVAL;});\n\n    /* Check if Session Timers is supported */\n    if ((inv->options & PJSIP_INV_SUPPORT_TIMER) == 0)\n\treturn PJ_SUCCESS;\n\n    pj_assert(is_initialized);\n\n    msg = rdata->msg_info.msg;\n    pj_assert(msg->type == PJSIP_RESPONSE_MSG);\n\n    /* Only process response of INVITE or UPDATE */\n    if (rdata->msg_info.cseq->method.id != PJSIP_INVITE_METHOD &&\n\tpjsip_method_cmp(&rdata->msg_info.cseq->method, &pjsip_update_method))\n    {\n\treturn PJ_SUCCESS;\n    }\n    \n    if (msg->line.status.code == PJSIP_SC_SESSION_TIMER_TOO_SMALL) {\n\t/* Our Session-Expires is too small, let's update it based on\n\t * Min-SE header in the response.\n\t */\n\tpjsip_tx_data *tdata;\n\tpjsip_min_se_hdr *min_se_hdr;\n\tpjsip_hdr *hdr;\n\tpjsip_via_hdr *via;\n\n\t/* Get Min-SE value from response */\n\tmin_se_hdr = (pjsip_min_se_hdr*) \n\t\t     pjsip_msg_find_hdr_by_name(msg, &STR_MIN_SE, NULL);\n\tif (min_se_hdr == NULL) {\n\t    /* Response 422 MUST contain Min-SE header */\n\t    PJ_LOG(3, (inv->pool->obj_name, \n\t\t       \"Received 422 (Session Interval Too Small) response \"\n\t\t       \"without Min-SE header!\"));\n\n\t    pjsip_timer_end_session(inv);\n\t    return PJSIP_EMISSINGHDR;\n\t}\n\n\t/* Session Timers should have been initialized here */\n\tpj_assert(inv->timer);\n\n\t/* Update Min-SE */\n\tinv->timer->setting.min_se = PJ_MAX(min_se_hdr->min_se, \n\t\t\t\t\t    inv->timer->setting.min_se);\n\n\t/* Update Session Timers setting */\n\tif (inv->timer->setting.sess_expires < inv->timer->setting.min_se)\n\t    inv->timer->setting.sess_expires = inv->timer->setting.min_se;\n\n\t/* Prepare to restart the request */\n\n\t/* Get the original INVITE request. */\n\ttdata = inv->invite_req;\n\n\t/* Remove branch param in Via header. */\n\tvia = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);\n\tpj_assert(via);\n\tvia->branch_param.slen = 0;\n\n\t/* Restore strict route set.\n\t * See http://trac.pjsip.org/repos/ticket/492\n\t */\n\tpjsip_restore_strict_route_set(tdata);\n\n\t/* Must invalidate the message! */\n\tpjsip_tx_data_invalidate_msg(tdata);\n\n\tpjsip_tx_data_add_ref(tdata);\n\n\t/* Update Session Timers headers */\n\thdr = (pjsip_hdr*) pjsip_msg_find_hdr_by_name(tdata->msg, \n\t\t\t\t\t\t      &STR_MIN_SE, NULL);\n\tif (hdr != NULL) pj_list_erase(hdr);\n\n\thdr = (pjsip_hdr*) pjsip_msg_find_hdr_by_names(tdata->msg, &STR_SE,\n\t\t\t\t\t\t       &STR_SHORT_SE, NULL);\n\tif (hdr != NULL) pj_list_erase(hdr);\n\n\tadd_timer_headers(inv, tdata, PJ_TRUE, PJ_TRUE);\n\n\t/* Restart UAC */\n\tpjsip_inv_uac_restart(inv, PJ_FALSE);\n\tpjsip_inv_send_msg(inv, tdata);\n\n\treturn PJ_SUCCESS;\n\n    } else if (msg->line.status.code/100 == 2) {\n\n\tpjsip_sess_expires_hdr *se_hdr;\n\n\t/* Find Session-Expires header */\n\tse_hdr = (pjsip_sess_expires_hdr*) pjsip_msg_find_hdr_by_names(\n\t\t\t\t\t\tmsg, &STR_SE, \n\t\t\t\t\t\t&STR_SHORT_SE, NULL);\n\tif (se_hdr == NULL) {\n\t    /* Remote doesn't support/want Session Timers, check if local \n\t     * require or force to use Session Timers.\n\t     */\n\t    if (inv->options & PJSIP_INV_REQUIRE_TIMER) {\n\t\tif (st_code)\n\t\t    *st_code = PJSIP_SC_EXTENSION_REQUIRED;\n\t\tpjsip_timer_end_session(inv);\n\t\treturn PJSIP_ERRNO_FROM_SIP_STATUS(\n\t\t\t\t\t    PJSIP_SC_EXTENSION_REQUIRED);\n\t    }\n\n\t    if ((inv->options & PJSIP_INV_ALWAYS_USE_TIMER) == 0) {\n\t\t/* Session Timers not forced */\n\t\tpjsip_timer_end_session(inv);\n\t\treturn PJ_SUCCESS;\n\t    }\n\t}\n\t    \n\t/* Make sure Session Timers is initialized */\n\tif (inv->timer == NULL)\n\t    pjsip_timer_init_session(inv, NULL);\n\n\t/* Session expiration period specified by remote is lower than our\n\t * Min-SE.\n\t */\n\tif (se_hdr && \n\t    se_hdr->sess_expires < inv->timer->setting.min_se)\n\t{\n\t    /* See ticket #954, instead of returning non-PJ_SUCCESS (which\n\t     * may cause disconnecting call/dialog), let's just accept the\n\t     * SE and update our local SE, as long as it isn't less than 90s.\n\t     */\n\t    if (se_hdr->sess_expires >= ABS_MIN_SE) {\n\t\tPJ_LOG(3, (inv->pool->obj_name, \n\t\t\t   \"Peer responds with bad Session-Expires, %ds, \"\n\t\t\t   \"which is less than Min-SE specified in request, \"\n\t\t\t   \"%ds. Well, let's just accept and use it.\",\n\t\t\t   se_hdr->sess_expires, inv->timer->setting.min_se));\n\n\t\tinv->timer->setting.sess_expires = se_hdr->sess_expires;\n\t\tinv->timer->setting.min_se = se_hdr->sess_expires;\n\t    }\n\n\t    //if (st_code)\n\t    //\t*st_code = PJSIP_SC_SESSION_TIMER_TOO_SMALL;\n\t    //pjsip_timer_end_session(inv);\n\t    //return PJSIP_ERRNO_FROM_SIP_STATUS(\n\t    //\t\t\t\t    PJSIP_SC_SESSION_TIMER_TOO_SMALL);\n\t}\n\n\t/* Update SE. Session-Expires in response cannot be lower than Min-SE.\n\t * Session-Expires in response can only be equal or lower than in \n\t * request.\n\t */\n\tif (se_hdr && \n\t    se_hdr->sess_expires <= inv->timer->setting.sess_expires &&\n\t    se_hdr->sess_expires >= inv->timer->setting.min_se)\n\t{\n\t    /* Good SE from remote, update local SE */\n\t    inv->timer->setting.sess_expires = se_hdr->sess_expires;\n\t}\n\n\t/* Set the refresher */\n\tif (se_hdr && pj_stricmp(&se_hdr->refresher, &STR_UAC) == 0)\n\t    inv->timer->refresher = TR_UAC;\n\telse if (se_hdr && pj_stricmp(&se_hdr->refresher, &STR_UAS) == 0)\n\t    inv->timer->refresher = TR_UAS;\n\telse\n\t    /* UAS should set the refresher, however, there is a case that\n\t     * UAS doesn't support/want Session Timers but the UAC insists\n\t     * to use Session Timers.\n\t     */\n\t    inv->timer->refresher = TR_UAC;\n\n\t/* Remember our role in this transaction */\n\tinv->timer->role = PJSIP_ROLE_UAC;\n\n\t/* Finally, set active flag and start the Session Timers */\n\tinv->timer->active = PJ_TRUE;\n\tstart_timer(inv);\n\n    } else if (pjsip_method_cmp(&rdata->msg_info.cseq->method,\n\t\t\t\t&pjsip_update_method) == 0 &&\n\t       msg->line.status.code >= 400 && msg->line.status.code < 600)\n    {\n\t/* This is to handle error response to previous UPDATE that was\n\t * sent without SDP. In this case, retry sending UPDATE but\n\t * with SDP this time.\n\t * Note: the additional expressions are to check that the\n\t *       UPDATE was really the one sent by us, not by other\n\t *       call components (e.g. to change codec)\n\t */\n\tif (inv->timer->timer.id == 0 && inv->timer->use_update &&\n\t    inv->timer->with_sdp == PJ_FALSE)\n\t{\n\t    inv->timer->with_sdp = PJ_TRUE;\n\t    timer_cb(NULL, &inv->timer->timer);\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\nPJ_DEF(pj_status_t)  pjsip_timer_handle_refresh_error(\n\t\t\t\t\t    pjsip_inv_session *inv,\n\t\t\t\t\t    pjsip_event *event)\n{    \n    PJ_ASSERT_RETURN(inv && event, PJ_EINVAL);\n\n    /* Check if Session Timers is supported */\n    if ((inv->options & PJSIP_INV_SUPPORT_TIMER) == 0)\n\treturn PJ_SUCCESS;    \n\n    pj_assert(is_initialized);\n\n    if (inv->timer && inv->timer->active) {\n\tpj_bool_t as_refresher;\n\n\t/* Check our role */\n\tas_refresher = ((inv->timer->refresher == TR_UAC) && \n\t\t\t(inv->timer->role == PJSIP_ROLE_UAC)) ||\n\t\t       ((inv->timer->refresher == TR_UAS) && \n\t\t\t(inv->timer->role == PJSIP_ROLE_UAS));\n\n\n\tif ((as_refresher) && (event->type == PJSIP_EVENT_TSX_STATE) && \n\t    (inv->timer->refresh_tdata == event->body.tsx_state.tsx->last_tx)) \n\t{\n\t    pjsip_status_code st_code;\n\t    pjsip_tx_data *bye;\n\t    pj_status_t status;\n\n\t    st_code = \n\t\t    (pjsip_status_code)event->body.tsx_state.tsx->status_code;\n\n\t    PJ_LOG(3, (inv->pool->obj_name, \n\t\t\t\"Receive error %d for refresh request %.*s/cseq=%d, \"\n\t\t\t\"stopping session now\", st_code, \n\t\t\tevent->body.tsx_state.tsx->method.name.slen,\n\t\t\tevent->body.tsx_state.tsx->method.name.ptr,\n\t\t\tevent->body.tsx_state.tsx->cseq));\n\n\t    status = pjsip_inv_end_session(inv, \n\t\t\t\t    event->body.tsx_state.tsx->status_code, \n\t\t\t\t    pjsip_get_status_text(st_code), \n\t\t\t\t    &bye);\n\n\t    if (status == PJ_SUCCESS && bye)\n\t\tstatus = pjsip_inv_send_msg(inv, bye);\n\n\t}\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Handle incoming INVITE or UPDATE request.\n */\nPJ_DEF(pj_status_t) pjsip_timer_process_req(pjsip_inv_session *inv,\n\t\t\t\t\t    const pjsip_rx_data *rdata,\n\t\t\t\t\t    pjsip_status_code *st_code)\n{\n    pjsip_min_se_hdr *min_se_hdr;\n    pjsip_sess_expires_hdr *se_hdr;\n    const pjsip_msg *msg;\n    unsigned min_se;\n\n    PJ_ASSERT_ON_FAIL(inv && rdata,\n\t{if(st_code)*st_code=PJSIP_SC_INTERNAL_SERVER_ERROR;return PJ_EINVAL;});\n\n    /* Check if Session Timers is supported */\n    if ((inv->options & PJSIP_INV_SUPPORT_TIMER) == 0)\n\treturn PJ_SUCCESS;\n\n    pj_assert(is_initialized);\n\n    msg = rdata->msg_info.msg;\n    pj_assert(msg->type == PJSIP_REQUEST_MSG);\n\n    /* Only process INVITE or UPDATE request */\n    if (msg->line.req.method.id != PJSIP_INVITE_METHOD &&\n\tpjsip_method_cmp(&rdata->msg_info.cseq->method, &pjsip_update_method))\n    {\n\treturn PJ_SUCCESS;\n    }\n\n    /* Find Session-Expires header */\n    se_hdr = (pjsip_sess_expires_hdr*) pjsip_msg_find_hdr_by_names(\n\t\t\t\t\t    msg, &STR_SE, &STR_SHORT_SE, NULL);\n    if (se_hdr == NULL) {\n\t/* Remote doesn't support/want Session Timers, check if local \n\t * require or force to use Session Timers. Note that Supported and \n\t * Require headers negotiation should have been verified by invite \n\t * session.\n\t */\n\tif ((inv->options & \n\t    (PJSIP_INV_REQUIRE_TIMER | PJSIP_INV_ALWAYS_USE_TIMER)) == 0)\n\t{\n\t    /* Session Timers not forced/required */\n\t    pjsip_timer_end_session(inv);\n\t    return PJ_SUCCESS;\n\t}\n    }\n\n    /* Make sure Session Timers is initialized */\n    if (inv->timer == NULL)\n\tpjsip_timer_init_session(inv, NULL);\n\n    /* Find Min-SE header */\n    min_se_hdr = (pjsip_min_se_hdr*) pjsip_msg_find_hdr_by_name(msg, \n\t\t\t\t\t\t\t    &STR_MIN_SE, NULL);\n    /* Update Min-SE */\n    min_se = inv->timer->setting.min_se;\n    if (min_se_hdr)\n\tmin_se = PJ_MAX(min_se_hdr->min_se, min_se);\n\n    /* Validate SE. Session-Expires cannot be lower than Min-SE \n     * (or 90 seconds if Min-SE is not set).\n     */\n    if (se_hdr && se_hdr->sess_expires < min_se) {\n\tif (st_code)\n\t    *st_code = PJSIP_SC_SESSION_TIMER_TOO_SMALL;\n\treturn PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_SESSION_TIMER_TOO_SMALL);\n    }\n\n    /* Update SE. Note that there is a case that SE is not available in the\n     * request (which means remote doesn't want/support it), but local insists\n     * to use Session Timers.\n     */\n    if (se_hdr) {\n\t/* Update SE as specified by peer. */\n\tinv->timer->setting.sess_expires = se_hdr->sess_expires;\n    } else if (inv->timer->setting.sess_expires < min_se) {\n\t/* There is no SE in the request (remote support Session Timers but\n\t * doesn't want to use it, it just specify Min-SE) and local SE is \n\t * lower than Min-SE specified by remote.\n\t */\n\tinv->timer->setting.sess_expires = min_se;\n    }\n\n    /* Set the refresher */\n    if (se_hdr && pj_stricmp(&se_hdr->refresher, &STR_UAC) == 0)\n\tinv->timer->refresher = TR_UAC;\n    else if (se_hdr && pj_stricmp(&se_hdr->refresher, &STR_UAS) == 0)\n\tinv->timer->refresher = TR_UAS;\n    else {\n\t/* If refresher role (i.e: ours or peer) has been set/negotiated, \n\t * better to keep it.\n\t */\n\tif (inv->timer->refresher != TR_UNKNOWN) {\n\t    pj_bool_t as_refresher;\n\n\t    /* Check our refresher role */\n\t    as_refresher = \n\t\t(inv->timer->refresher==TR_UAC && inv->timer->role==PJSIP_ROLE_UAC) ||\n\t\t(inv->timer->refresher==TR_UAS && inv->timer->role==PJSIP_ROLE_UAS);\n\n\t    /* Update refresher role */\n\t    inv->timer->refresher = as_refresher? TR_UAS : TR_UAC;\n\t} else {\n\t    /* If UAC supports timer and Session-Expires header is present\n             * in the request, set UAC as refresher.\n\t     * If UAC doesn't support timer and a proxy inserts a\n\t     * Session-Expires header, then UAS has to be the\n\t     * refresher (according to RFC 4028 Section 9).\n\t     */\n\t    pj_bool_t uac_supports_timer = PJ_FALSE;\n            pjsip_supported_hdr *sup_hdr;\n            \n            sup_hdr = (pjsip_supported_hdr*)\n                      pjsip_msg_find_hdr(msg, PJSIP_H_SUPPORTED, NULL);\n            if (sup_hdr) {\n                unsigned i;\n                \n                for (i = 0; i < sup_hdr->count; i++) {\n                    if (pj_stricmp(&sup_hdr->values[i], &STR_TIMER) == 0) {\n                        uac_supports_timer = PJ_TRUE;\n                        break;\n                    }\n                }\n            }\n            inv->timer->refresher = (uac_supports_timer && se_hdr)? TR_UAC:\n            \t\t\t    TR_UAS;\n\t}\n    }\n\n    /* Remember our role in this transaction */\n    inv->timer->role = PJSIP_ROLE_UAS;\n\n    /* Set active flag */\n    inv->timer->active = PJ_TRUE;\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Handle outgoing response with status code 2xx & 422.\n */\nPJ_DEF(pj_status_t) pjsip_timer_update_resp(pjsip_inv_session *inv,\n\t\t\t\t\t    pjsip_tx_data *tdata)\n{\n    pjsip_msg *msg;\n\n    /* Check if Session Timers is supported */\n    if ((inv->options & PJSIP_INV_SUPPORT_TIMER) == 0)\n\treturn PJ_SUCCESS;\n\n    pj_assert(is_initialized);\n    PJ_ASSERT_RETURN(inv && tdata, PJ_EINVAL);\n\n    msg = tdata->msg;\n\n    if (msg->line.status.code/100 == 2)\n    {\n\tif (inv->timer && inv->timer->active) {\n\t    /* Add Session-Expires header and start the timer */\n\t    add_timer_headers(inv, tdata, PJ_TRUE, PJ_FALSE);\n\n\t    /* Add 'timer' to Require header (see ticket #1560). */\n\t    if (inv->timer->refresher == TR_UAC) {\n\t\tpjsip_require_hdr *req_hdr;\n\t\tpj_bool_t req_hdr_has_timer = PJ_FALSE;\n\n\t\treq_hdr = (pjsip_require_hdr*)\n\t\t\t   pjsip_msg_find_hdr(tdata->msg, PJSIP_H_REQUIRE,\n\t\t\t\t\t      NULL);\n\t\tif (req_hdr == NULL) {\n\t\t    req_hdr = pjsip_require_hdr_create(tdata->pool);\n\t\t    PJ_ASSERT_RETURN(req_hdr, PJ_ENOMEM);\n\t\t    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)req_hdr);\n\t\t} else {\n\t\t    unsigned i;\n\t\t    for (i = 0; i < req_hdr->count; ++i) {\n\t\t\tif (pj_stricmp(&req_hdr->values[i], &STR_TIMER)) {\n\t\t\t    req_hdr_has_timer = PJ_TRUE;\n\t\t\t    break;\n\t\t\t}\n\t\t    }\n\t\t}\n\t\tif (!req_hdr_has_timer)\n\t\t    req_hdr->values[req_hdr->count++] = STR_TIMER;\n\t    }\n\t    \n\t    /* Finally, start timer. */\n\t    start_timer(inv);\n\t}\n    } \n    else if (msg->line.status.code == PJSIP_SC_SESSION_TIMER_TOO_SMALL)\n    {\n\t/* Add Min-SE header */\n\tadd_timer_headers(inv, tdata, PJ_FALSE, PJ_TRUE);\n    }\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * End the Session Timers.\n */\nPJ_DEF(pj_status_t) pjsip_timer_end_session(pjsip_inv_session *inv)\n{\n    PJ_ASSERT_RETURN(inv, PJ_EINVAL);\n\n    if (inv->timer) {\n\t/* Reset active flag */\n\tinv->timer->active = PJ_FALSE;\n\n\t/* Stop Session Timers */\n\tstop_timer(inv);\n    }\n\n    return PJ_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/pjsip/src/pjsip-ua/sip_xfer.c",
    "content": "/* $Id: sip_xfer.c 3553 2011-05-05 06:14:19Z nanang $ */\n/* \n * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)\n * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include <pjsip-ua/sip_xfer.h>\n#include <pjsip-simple/evsub_msg.h>\n#include <pjsip/sip_dialog.h>\n#include <pjsip/sip_errno.h>\n#include <pjsip/sip_endpoint.h>\n#include <pjsip/sip_module.h>\n#include <pjsip/sip_transport.h>\n#include <pj/assert.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n\n/* Subscription expiration */\n#ifndef PJSIP_XFER_EXPIRES\n#   define PJSIP_XFER_EXPIRES\t    600\n#endif\n\n\n/*\n * Refer module (mod-refer)\n */\nstatic struct pjsip_module mod_xfer = \n{\n    NULL, NULL,\t\t\t\t/* prev, next.\t\t\t*/\n    { \"mod-refer\", 9 },\t\t\t/* Name.\t\t\t*/\n    -1,\t\t\t\t\t/* Id\t\t\t\t*/\n    PJSIP_MOD_PRIORITY_DIALOG_USAGE,\t/* Priority\t\t\t*/\n    NULL,\t\t\t\t/* load()\t\t\t*/\n    NULL,\t\t\t\t/* start()\t\t\t*/\n    NULL,\t\t\t\t/* stop()\t\t\t*/\n    NULL,\t\t\t\t/* unload()\t\t\t*/\n    NULL,\t\t\t\t/* on_rx_request()\t\t*/\n    NULL,\t\t\t\t/* on_rx_response()\t\t*/\n    NULL,\t\t\t\t/* on_tx_request.\t\t*/\n    NULL,\t\t\t\t/* on_tx_response()\t\t*/\n    NULL,\t\t\t\t/* on_tsx_state()\t\t*/\n};\n\n\n/* Declare PJSIP_REFER_METHOD, so that if somebody declares this in\n * sip_msg.h we can catch the error here.\n */\nenum\n{\n    PJSIP_REFER_METHOD = PJSIP_OTHER_METHOD\n};\n\nPJ_DEF_DATA(const pjsip_method) pjsip_refer_method = {\n    (pjsip_method_e) PJSIP_REFER_METHOD,\n    { \"REFER\", 5}\n};\n\nPJ_DEF(const pjsip_method*) pjsip_get_refer_method()\n{\n    return &pjsip_refer_method;\n}\n\n/*\n * String constants\n */\nstatic const pj_str_t STR_REFER = { \"refer\", 5 };\nstatic const pj_str_t STR_MESSAGE = { \"message\", 7 };\nstatic const pj_str_t STR_SIPFRAG = { \"sipfrag\", 7 };\n\n\n/*\n * Transfer struct.\n */\nstruct pjsip_xfer\n{\n    pjsip_evsub\t\t*sub;\t\t/**< Event subscribtion record.\t    */\n    pjsip_dialog\t*dlg;\t\t/**< The dialog.\t\t    */\n    pjsip_evsub_user\t user_cb;\t/**< The user callback.\t\t    */\n    pj_str_t\t\t refer_to_uri;\t/**< The full Refer-To URI.\t    */\n    int\t\t\t last_st_code;\t/**< st_code sent in last NOTIFY    */\n    pj_str_t\t\t last_st_text;\t/**< st_text sent in last NOTIFY    */\n};\n\n\ntypedef struct pjsip_xfer pjsip_xfer;\n\n\n\n/*\n * Forward decl for evsub callback.\n */\nstatic void xfer_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);\nstatic void xfer_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,\n\t\t\t\t     pjsip_event *event);\nstatic void xfer_on_evsub_rx_refresh( pjsip_evsub *sub, \n\t\t\t\t      pjsip_rx_data *rdata,\n\t\t\t\t      int *p_st_code,\n\t\t\t\t      pj_str_t **p_st_text,\n\t\t\t\t      pjsip_hdr *res_hdr,\n\t\t\t\t      pjsip_msg_body **p_body);\nstatic void xfer_on_evsub_rx_notify( pjsip_evsub *sub, \n\t\t\t\t     pjsip_rx_data *rdata,\n\t\t\t\t     int *p_st_code,\n\t\t\t\t     pj_str_t **p_st_text,\n\t\t\t\t     pjsip_hdr *res_hdr,\n\t\t\t\t     pjsip_msg_body **p_body);\nstatic void xfer_on_evsub_client_refresh(pjsip_evsub *sub);\nstatic void xfer_on_evsub_server_timeout(pjsip_evsub *sub);\n\n\n/*\n * Event subscription callback for xference.\n */\nstatic pjsip_evsub_user xfer_user = \n{\n    &xfer_on_evsub_state,\n    &xfer_on_evsub_tsx_state,\n    &xfer_on_evsub_rx_refresh,\n    &xfer_on_evsub_rx_notify,\n    &xfer_on_evsub_client_refresh,\n    &xfer_on_evsub_server_timeout,\n};\n\n\n\n\n/*\n * Initialize the REFER subsystem.\n */\nPJ_DEF(pj_status_t) pjsip_xfer_init_module(pjsip_endpoint *endpt)\n{\n    const pj_str_t accept = { \"message/sipfrag;version=2.0\", 27 };\n    pj_status_t status;\n\n    PJ_ASSERT_RETURN(endpt != NULL, PJ_EINVAL);\n    PJ_ASSERT_RETURN(mod_xfer.id == -1, PJ_EINVALIDOP);\n\n    status = pjsip_endpt_register_module(endpt, &mod_xfer);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    status = pjsip_endpt_add_capability( endpt, &mod_xfer, PJSIP_H_ALLOW, \n\t\t\t\t\t NULL, 1, \n\t\t\t\t\t &pjsip_get_refer_method()->name);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    status = pjsip_evsub_register_pkg(&mod_xfer, &STR_REFER, \n\t\t\t\t      PJSIP_XFER_EXPIRES, 1, &accept);\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create transferer (sender of REFER request).\n *\n */\nPJ_DEF(pj_status_t) pjsip_xfer_create_uac( pjsip_dialog *dlg,\n\t\t\t\t\t   const pjsip_evsub_user *user_cb,\n\t\t\t\t\t   pjsip_evsub **p_evsub )\n{\n    pj_status_t status;\n    pjsip_xfer *xfer;\n    pjsip_evsub *sub;\n\n    PJ_ASSERT_RETURN(dlg && p_evsub, PJ_EINVAL);\n\n    pjsip_dlg_inc_lock(dlg);\n\n    /* Create event subscription */\n    status = pjsip_evsub_create_uac( dlg,  &xfer_user, &STR_REFER, \n\t\t\t\t     PJSIP_EVSUB_NO_EVENT_ID, &sub);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Create xfer session */\n    xfer = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_xfer);\n    xfer->dlg = dlg;\n    xfer->sub = sub;\n    if (user_cb)\n\tpj_memcpy(&xfer->user_cb, user_cb, sizeof(pjsip_evsub_user));\n\n    /* Attach to evsub */\n    pjsip_evsub_set_mod_data(sub, mod_xfer.id, xfer);\n\n    *p_evsub = sub;\n\non_return:\n    pjsip_dlg_dec_lock(dlg);\n    return status;\n\n}\n\n\n\n\n/*\n * Create transferee (receiver of REFER request).\n *\n */\nPJ_DEF(pj_status_t) pjsip_xfer_create_uas( pjsip_dialog *dlg,\n\t\t\t\t\t   const pjsip_evsub_user *user_cb,\n\t\t\t\t\t   pjsip_rx_data *rdata,\n\t\t\t\t\t   pjsip_evsub **p_evsub )\n{\n    pjsip_evsub *sub;\n    pjsip_xfer *xfer;\n    const pj_str_t STR_EVENT = {\"Event\", 5 };\n    pjsip_event_hdr *event_hdr;\n    pj_status_t status;\n\n    /* Check arguments */\n    PJ_ASSERT_RETURN(dlg && rdata && p_evsub, PJ_EINVAL);\n\n    /* Must be request message */\n    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,\n\t\t     PJSIP_ENOTREQUESTMSG);\n\n    /* Check that request is REFER */\n    PJ_ASSERT_RETURN(pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,\n\t\t\t\t      pjsip_get_refer_method())==0,\n\t\t     PJSIP_ENOTREFER);\n\n    /* Lock dialog */\n    pjsip_dlg_inc_lock(dlg);\n\n    /* The evsub framework expects an Event header in the request,\n     * while a REFER request conveniently doesn't have one (pun intended!).\n     * So create a dummy Event header.\n     */\n    if (pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,\n\t\t\t\t   &STR_EVENT, NULL)==NULL)\n    {\n\tevent_hdr = pjsip_event_hdr_create(rdata->tp_info.pool);\n\tevent_hdr->event_type = STR_REFER;\n\tpjsip_msg_add_hdr(rdata->msg_info.msg, (pjsip_hdr*)event_hdr);\n    }\n\n    /* Create server subscription */\n    status = pjsip_evsub_create_uas( dlg, &xfer_user, rdata, \n\t\t\t\t     PJSIP_EVSUB_NO_EVENT_ID, &sub);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Create server xfer subscription */\n    xfer = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_xfer);\n    xfer->dlg = dlg;\n    xfer->sub = sub;\n    if (user_cb)\n\tpj_memcpy(&xfer->user_cb, user_cb, sizeof(pjsip_evsub_user));\n\n    /* Attach to evsub */\n    pjsip_evsub_set_mod_data(sub, mod_xfer.id, xfer);\n\n    /* Done: */\n    *p_evsub = sub;\n\non_return:\n    pjsip_dlg_dec_lock(dlg);\n    return status;\n}\n\n\n\n/*\n * Call this function to create request to initiate REFER subscription.\n *\n */\nPJ_DEF(pj_status_t) pjsip_xfer_initiate( pjsip_evsub *sub,\n\t\t\t\t\t const pj_str_t *refer_to_uri,\n\t\t\t\t\t pjsip_tx_data **p_tdata)\n{\n    pjsip_xfer *xfer;\n    const pj_str_t refer_to = { \"Refer-To\", 8};\n    pjsip_tx_data *tdata;\n    pjsip_generic_string_hdr *hdr;\n    pj_status_t status;\n\n    /* sub and p_tdata argument must be valid.  */\n    PJ_ASSERT_RETURN(sub && p_tdata, PJ_EINVAL);\n\n\n    /* Get the xfer object. */\n    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);\n    PJ_ASSERT_RETURN(xfer != NULL, PJSIP_ENOREFERSESSION);\n\n    /* refer_to_uri argument MAY be NULL for subsequent REFER requests,\n     * but it MUST be specified in the first REFER.\n     */\n    PJ_ASSERT_RETURN((refer_to_uri || xfer->refer_to_uri.slen), PJ_EINVAL);\n\n    /* Lock dialog. */\n    pjsip_dlg_inc_lock(xfer->dlg);\n\n    /* Create basic REFER request */\n    status = pjsip_evsub_initiate(sub, pjsip_get_refer_method(), -1, \n\t\t\t\t  &tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n    /* Save Refer-To URI. */\n    if (refer_to_uri == NULL) {\n\trefer_to_uri = &xfer->refer_to_uri;\n    } else {\n\tpj_strdup(xfer->dlg->pool, &xfer->refer_to_uri, refer_to_uri);\n    }\n\n    /* Create and add Refer-To header. */\n    hdr = pjsip_generic_string_hdr_create(tdata->pool, &refer_to,\n\t\t\t\t\t  refer_to_uri);\n    if (!hdr) {\n\tpjsip_tx_data_dec_ref(tdata);\n\tstatus = PJ_ENOMEM;\n\tgoto on_return;\n    }\n\n    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);\n\n\n    /* Done. */\n    *p_tdata = tdata;\n\n    status = PJ_SUCCESS;\n\non_return:\n    pjsip_dlg_dec_lock(xfer->dlg);\n    return status;\n}\n\n\n/*\n * Accept the incoming REFER request by sending 2xx response.\n *\n */\nPJ_DEF(pj_status_t) pjsip_xfer_accept( pjsip_evsub *sub,\n\t\t\t\t       pjsip_rx_data *rdata,\n\t\t\t\t       int st_code,\n\t\t\t\t       const pjsip_hdr *hdr_list )\n{\n    /*\n     * Don't need to add custom headers, so just call basic\n     * evsub response.\n     */\n    return pjsip_evsub_accept( sub, rdata, st_code, hdr_list );\n}\n\n\n/*\n * For notifier, create NOTIFY request to subscriber, and set the state \n * of the subscription. \n */\nPJ_DEF(pj_status_t) pjsip_xfer_notify( pjsip_evsub *sub,\n\t\t\t\t       pjsip_evsub_state state,\n\t\t\t\t       int xfer_st_code,\n\t\t\t\t       const pj_str_t *xfer_st_text,\n\t\t\t\t       pjsip_tx_data **p_tdata)\n{\n    pjsip_tx_data *tdata;\n    pjsip_xfer *xfer;\n    pjsip_param *param;\n    const pj_str_t reason = { \"noresource\", 10 };\n    char *body;\n    int bodylen;\n    pjsip_msg_body *msg_body;\n    pj_status_t status;\n    \n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(sub, PJ_EINVAL);\n\n    /* Get the xfer object. */\n    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);\n    PJ_ASSERT_RETURN(xfer != NULL, PJSIP_ENOREFERSESSION);\n\n\n    /* Lock object. */\n    pjsip_dlg_inc_lock(xfer->dlg);\n\n    /* Create the NOTIFY request. \n     * Note that reason is only used when state is TERMINATED, and\n     * the defined termination reason for REFER is \"noresource\".\n     */\n    status = pjsip_evsub_notify( sub, state, NULL, &reason, &tdata);\n    if (status != PJ_SUCCESS)\n\tgoto on_return;\n\n\n    /* Check status text */\n    if (xfer_st_text==NULL || xfer_st_text->slen==0)\n\txfer_st_text = pjsip_get_status_text(xfer_st_code);\n\n    /* Save st_code and st_text, for current_notify() */\n    xfer->last_st_code = xfer_st_code;\n    pj_strdup(xfer->dlg->pool, &xfer->last_st_text, xfer_st_text);\n\n    /* Create sipfrag content. */\n    body = (char*) pj_pool_alloc(tdata->pool, 128);\n    bodylen = pj_ansi_snprintf(body, 128, \"SIP/2.0 %u %.*s\\r\\n\",\n\t\t\t       xfer_st_code,\n\t\t\t       (int)xfer_st_text->slen,\n\t\t\t       xfer_st_text->ptr);\n    PJ_ASSERT_ON_FAIL(bodylen > 0 && bodylen < 128, \n\t\t\t{status=PJ_EBUG; pjsip_tx_data_dec_ref(tdata); \n\t\t\t goto on_return; });\n\n\n    /* Create SIP message body. */\n    msg_body = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_msg_body);\n    pjsip_media_type_init(&msg_body->content_type, (pj_str_t*)&STR_MESSAGE,\n\t\t\t  (pj_str_t*)&STR_SIPFRAG);\n    msg_body->data = body;\n    msg_body->len = bodylen;\n    msg_body->print_body = &pjsip_print_text_body;\n    msg_body->clone_data = &pjsip_clone_text_data;\n\n    param = PJ_POOL_ALLOC_T(tdata->pool, pjsip_param);\n    param->name = pj_str(\"version\");\n    param->value = pj_str(\"2.0\");\n    pj_list_push_back(&msg_body->content_type.param, param);\n\n    /* Attach sipfrag body. */\n    tdata->msg->body = msg_body;\n\n\n    /* Done. */\n    *p_tdata = tdata;\n\n\non_return:\n    pjsip_dlg_dec_lock(xfer->dlg);\n    return status;\n\n}\n\n\n/*\n * Send current state and the last sipfrag body.\n */\nPJ_DEF(pj_status_t) pjsip_xfer_current_notify( pjsip_evsub *sub,\n\t\t\t\t\t       pjsip_tx_data **p_tdata )\n{\n    pjsip_xfer *xfer;\n    pj_status_t status;\n    \n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(sub, PJ_EINVAL);\n\n    /* Get the xfer object. */\n    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);\n    PJ_ASSERT_RETURN(xfer != NULL, PJSIP_ENOREFERSESSION);\n\n    pjsip_dlg_inc_lock(xfer->dlg);\n\n    status = pjsip_xfer_notify(sub, pjsip_evsub_get_state(sub),\n\t\t\t       xfer->last_st_code, &xfer->last_st_text,\n\t\t\t       p_tdata);\n\n    pjsip_dlg_dec_lock(xfer->dlg);\n\n    return status;\n}\n\n\n/*\n * Send request message. \n */\nPJ_DEF(pj_status_t) pjsip_xfer_send_request( pjsip_evsub *sub,\n\t\t\t\t\t     pjsip_tx_data *tdata)\n{\n    return pjsip_evsub_send_request(sub, tdata);\n}\n\n\n/*\n * This callback is called by event subscription when subscription\n * state has changed.\n */\nstatic void xfer_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)\n{\n    pjsip_xfer *xfer;\n\n    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);\n    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});\n\n    if (xfer->user_cb.on_evsub_state)\n\t(*xfer->user_cb.on_evsub_state)(sub, event);\n\n}\n\n/*\n * Called when transaction state has changed.\n */\nstatic void xfer_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,\n\t\t\t\t     pjsip_event *event)\n{\n    pjsip_xfer *xfer;\n\n    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);\n    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});\n\n    if (xfer->user_cb.on_tsx_state)\n\t(*xfer->user_cb.on_tsx_state)(sub, tsx, event);\n}\n\n/*\n * Called when REFER is received to refresh subscription.\n */\nstatic void xfer_on_evsub_rx_refresh( pjsip_evsub *sub, \n\t\t\t\t      pjsip_rx_data *rdata,\n\t\t\t\t      int *p_st_code,\n\t\t\t\t      pj_str_t **p_st_text,\n\t\t\t\t      pjsip_hdr *res_hdr,\n\t\t\t\t      pjsip_msg_body **p_body)\n{\n    pjsip_xfer *xfer;\n\n    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);\n    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});\n\n    if (xfer->user_cb.on_rx_refresh) {\n\t(*xfer->user_cb.on_rx_refresh)(sub, rdata, p_st_code, p_st_text,\n\t\t\t\t       res_hdr, p_body);\n\n    } else {\n\t/* Implementors MUST send NOTIFY if it implements on_rx_refresh\n\t * (implementor == \"us\" from evsub point of view.\n\t */\n\tpjsip_tx_data *tdata;\n\tpj_status_t status;\n\n\tif (pjsip_evsub_get_state(sub)==PJSIP_EVSUB_STATE_TERMINATED) {\n\t    status = pjsip_xfer_notify( sub, PJSIP_EVSUB_STATE_TERMINATED,\n\t\t\t\t\txfer->last_st_code,\n\t\t\t\t\t&xfer->last_st_text, \n\t\t\t\t\t&tdata);\n\t} else {\n\t    status = pjsip_xfer_current_notify(sub, &tdata);\n\t}\n\n\tif (status == PJ_SUCCESS)\n\t    pjsip_xfer_send_request(sub, tdata);\n    }\n}\n\n\n/*\n * Called when NOTIFY is received.\n */\nstatic void xfer_on_evsub_rx_notify( pjsip_evsub *sub, \n\t\t\t\t     pjsip_rx_data *rdata,\n\t\t\t\t     int *p_st_code,\n\t\t\t\t     pj_str_t **p_st_text,\n\t\t\t\t     pjsip_hdr *res_hdr,\n\t\t\t\t     pjsip_msg_body **p_body)\n{\n    pjsip_xfer *xfer;\n\n    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);\n    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});\n\n    if (xfer->user_cb.on_rx_notify)\n\t(*xfer->user_cb.on_rx_notify)(sub, rdata, p_st_code, p_st_text,\n\t\t\t\t      res_hdr, p_body);\n}\n\n/*\n * Called when it's time to send SUBSCRIBE.\n */\nstatic void xfer_on_evsub_client_refresh(pjsip_evsub *sub)\n{\n    pjsip_xfer *xfer;\n\n    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);\n    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});\n\n    if (xfer->user_cb.on_client_refresh) {\n\t(*xfer->user_cb.on_client_refresh)(sub);\n    } else {\n\tpj_status_t status;\n\tpjsip_tx_data *tdata;\n\n\tstatus = pjsip_evsub_initiate(sub, NULL, PJSIP_XFER_EXPIRES, &tdata);\n\tif (status == PJ_SUCCESS)\n\t    pjsip_xfer_send_request(sub, tdata);\n    }\n}\n\n\n/*\n * Called when no refresh is received after the interval.\n */\nstatic void xfer_on_evsub_server_timeout(pjsip_evsub *sub)\n{\n    pjsip_xfer *xfer;\n\n    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);\n    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});\n\n    if (xfer->user_cb.on_server_timeout) {\n\t(*xfer->user_cb.on_server_timeout)(sub);\n    } else {\n\tpj_status_t status;\n\tpjsip_tx_data *tdata;\n\n\tstatus = pjsip_xfer_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,\n\t\t\t\t   xfer->last_st_code, \n\t\t\t\t   &xfer->last_st_text, &tdata);\n\tif (status == PJ_SUCCESS)\n\t    pjsip_xfer_send_request(sub, tdata);\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/README.txt",
    "content": "Third Party Software\n\nThis directory contains third party software that is\nused by PJ project.\n\n= Building the third party libraries =\n\nGo to build directory, rather than building the library\nusing the project files/Makefiles provided by the software.\n\n\n= Versions =\n\nspeex:\t\tSVN -r12832\nportaudio:\tSVN -r1186\ngsm:\t\tgsm-1.0.12\nilbc:\t\tfrom RFC\nresample:\tlib-resample, I think version 1.7\nsrtp\t\tlibsrtp-1.4.4\n"
  },
  {
    "path": "deps/pjsip/third_party/bdsound/include/bdimad.h",
    "content": " /**\r\n * @file bdIMADpj.h\r\n * @brief bdSound IMproved Audio Device for PJSIP.\r\n */\r\n \r\n/**\r\n * @defgroup bd_IMAD bdIMADpj bdSound IMproved Audio Device for PJSIP.\r\n * @ingroup audio_device_api\r\n * \r\n * <b>bdSound IMproved Audio Device</b> is a multiplatform audio interface\r\n * created to integrate in <b>PJSIP</b> library with no effort.\r\n * \\n Porting <b>bdIMADpj</b> across the main operating systems is\r\n * straightforward, without the need of change a single line of code.\r\n *\r\n *    - <b>Features</b>\r\n *       - Echo cancellation (Full Duplex)\r\n *       - Noise reduction\r\n *       - Automatic Gain Control\r\n *       - Audio Enhancement\r\n *\r\n *    - <b>Supported operating systems</b>\r\n *       - Windows\r\n *       - Android\r\n *       - MacOS X\r\n *       - iOS\r\n *       - Linux / Alsa\r\n *\r\n *    - <b>Supported platforms</b>\r\n *       - x86\r\n *       - x64\r\n *       - ARM Cortex-A8/A9/A15 with NEON\r\n * \r\n * Visit <a href=\"http:/www.bdsound.com\" target=\"new\">bdSound</a> for updated\r\n * features, supported operating systems and platforms.\r\n * \r\n * <b>Using PJSIP with bdIMAD audio device</b>\r\n * \r\n *    - <b>Integration</b>\r\n *    \\n Using <b>bdIMAD</b> within <b>PJSIP</b> is simple:\r\n *       -# Request for bdIMADpj library to\r\n *       <a href=\"http:/www.bdsound.com\" target=\"new\">bdSound</a>:\r\n *        bdSound will provide instruction to integrate the library depending on\r\n *        the platform / O.S. / toolchain;\r\n *       -# Add the <code>bdimad_dev.c</code> file to\r\n *       <code>pjmedia/src/pjmedia-audiodev</code> folder;\r\n *       -# Enable the bdIMAD audio device defining the periferal in the\r\n *       <code>pj/config_site.h</code> and disabling all other devices:\r\n *       <pre>\r\n *       #define PJMEDIA_AUDIO_DEV_HAS_BDIMAD 1\r\n *       </pre>\r\n *\r\n *    - <b>Usage</b>\r\n *    \\n There are only a couple of things the customer have to pay attention on\r\n *    �when using bdIMAD library.\r\n *\r\n *       - <b>Initialization</b>\r\n *       \\n Since the bdIMAD library provide itself the echo cancellation\r\n *       and the latency management, is necessary to disable these features\r\n *       in the PJSIP librariy applications.\r\n *       \\n For example in PJSUA sample application there is the need\r\n *       to provide the following commands:\r\n *       <pre>\r\n *       --ec-tail=0\r\n *       --no-vad\r\n *       --capture-lat=0\r\n *       --playback-lat=0\r\n *       </pre>\r\n * \r\n *       - <b>Supported set capability</b>\r\n *          - <code>PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING</code>\r\n *          \\n Setting speaker volume.\r\n *          - <code>PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING</code>\r\n *          \\n Setting michrophone volume.\r\n *          - <code>PJMEDIA_AUD_DEV_CAP_EC</code>\r\n *          \\n Enable/disable echo cancellation.\r\n *\r\n * For additional information visit\r\n * <a href=\"http:/www.bdsound.com\" target=\"new\">www.bdsound.com</a>\r\n * or write to info@bdsound.com\r\n *\r\n * @author bdSound\r\n * @version   1.0.1\r\n * @copyright 2012 bdSound srl. All rights reserved.\r\n *\r\n */\r\n\r\n/**        \r\n * @defgroup groupFunction Functions      \r\n * @ingroup bd_IMAD  \r\n * \r\n * Functions defined in bdIMAD.\r\n */\r\n\r\n/**        \r\n * @defgroup groupCallback Callbacks      \r\n * @ingroup bd_IMAD    \r\n * \r\n * Callbacks defined in bdIMAD.\r\n */\r\n \r\n/**        \r\n * @defgroup groupStructEnum Structs and Enums       \r\n * @ingroup bd_IMAD   \r\n * \r\n * Struct and Enum defined in bdIMAD.\r\n */\r\n\r\n#ifndef BD_IMAD_PJ_H__\r\n#define BD_IMAD_PJ_H__\r\n  \r\n/**\r\n * @brief Macro for Windows DLL Support.\r\n */\r\n \r\n#ifdef _BDIMADPJ_EXPORTDLL\r\n\t#ifdef WIN32\r\n\t\t#define BDIMADPJ_API __declspec(dllexport)\r\n\t#else\r\n\t\t#define BDIMADPJ_API __attribute__((visibility(\"default\")))\t\r\n\t#endif\r\n#else\r\n\t#define BDIMADPJ_API\r\n#endif\r\n\r\n#define BD_IMAD_CAPTURE_DEVICES      1\r\n#define BD_IMAD_PLAYBACK_DEVICES     0\r\n#define BD_IMAD_DIAGNOSTIC_ENABLE    1\r\n#define BD_IMAD_DIAGNOSTIC_DISABLE   0\r\n\r\n#define BD_IMAD_BITS_X_SAMPLE\t     16                  /**< Bits per sample */\r\n\r\ntypedef void* bdIMADpj;\r\n\r\n/**\r\n * @addtogroup groupCallback\r\n * @{\r\n */\r\n\r\n/**\r\n * @brief Callback used to fill the playback buffer of bdIMAD.\r\n * The function is called by bdIMAD each time are required sample to be played.\r\n * @param[in] *buffer                  pointer to the buffer with the audio\r\n * \t\t\t\t       samples to be played(short type).\r\n * @param[in] nSamples                 number of samples required.\r\n * @param[in] user_data                pointer to the user data structure\r\n * \t\t\t\t       defined in the bdIMADpj_Setting_t\r\n * \t\t\t\t       structure.\r\n * @return none.\r\n */\r\n\r\ntypedef int (* cb_fillPlayBackB_t) (void *buffer, int nSamples,\r\n\t\t\t\t    void *user_data);\r\n\r\n/**\r\n * @brief Callback used to retrive the caputre buffer of bdIMAD. The function\r\n * is called by bdIMAD each time processed mic samples are available.\r\n * @param[out] *buffer                 pointer to the buffer with the audio\r\n * \t\t\t\t       samples to download(short type).\r\n * @param[in] nSamples                 number of samples processed to download.\r\n * @param[in] user_data                pointer to the user data structure\r\n *                                     defined in the MainSet structure.\r\n * @return none.\r\n */\r\n\r\ntypedef void (* cb_emptyCaptureB_t) (void *buffer, int nSamples,\r\n\t\t\t\t     void *user_data);\r\n/**\r\n * @}\r\n */\r\n\r\n/**\r\n * @addtogroup groupStructEnum\r\n * @{\r\n */\r\n \r\n/**\r\n * @brief Error status returned by some functions in the library.\r\n */\r\n\r\ntypedef enum bdIMADpj_Status{\r\n    /**< No error. */\r\n    BD_PJ_OK                                     = 0,\r\n    /**< Watch bdIMADpj_Warnings_t structure to find the warnings. */\r\n    BD_PJ_WARN_BDIMAD_WARNING_ASSERTED           = 1,\r\n    /**< Error not identified. */\r\n    BD_PJ_ERROR_GENERIC                          = 2,\r\n    /**< The pointer passed is NULL. */\r\n    BD_PJ_ERROR_NULL_POINTER                     = 3,\r\n    /**< Allocation procedure failed. */\r\n    BD_PJ_ERROR_ALLOCATION                       = 4,\r\n    /**< The parameter is not existent or the set/get function is not active. */\r\n    BD_PJ_ERROR_PARAMETER_NOT_FOUND              = 5,\r\n    /**< No capture device found. */\r\n    BD_PJ_ERROR_IMAD_NONE_CAPTURE_DEV            = 10,\r\n    /**< No play device found. */\r\n    BD_PJ_ERROR_IMAD_NONE_PLAY_DEV               = 11,\r\n    /**< Frame size not allowed. */\r\n    BD_PJ_ERROR_IMAD_FRAME_SIZE                  = 12,\r\n    /**< Sample frequency not allowed. */\r\n    BD_PJ_ERROR_IMAD_SAMPLE_FREQ                 = 13,\r\n    /**< Samples missing. */\r\n    BD_PJ_ERROR_IMAD_MISSING_SAMPLES             = 14,\r\n    /**< Device list is empty. */\r\n    BD_PJ_ERROR_IMAD_DEVICE_LIST_EMPTY           = 15,\r\n    /**< Library not authorized, entering demo mode. */\r\n    BD_PJ_ERROR_IMAD_LIB_NOT_AUTHORIZED          = 16,\r\n    /**< The input channel memory has not been allocated. */\r\n    BD_PJ_ERROR_IMAD_INPUT_CH_NOT_ALLOCATED      = 17,\r\n    /**< The library has expired, entering demo mode. */\r\n    BD_PJ_ERROR_IMAD_LICENSE_EXPIRED             = 18,\r\n    /**< Open of capture device failed. */\r\n    BD_PJ_ERROR_IMAD_OPEN_CAPTURE_DEV_FAILED     = 19,\r\n    /**< Open of play device failed.  */\r\n    BD_PJ_ERROR_IMAD_OPEN_PLAY_DEV_FAILED        = 20,\r\n    /**< Start of play device failed. */\r\n    BD_PJ_ERROR_IMAD_START_PLAY_DEV_FAILED       = 21,\r\n    /**< Start of capture device failed. */\r\n    BD_PJ_ERROR_IMAD_START_CAPTURE_DEV_FAILED    = 22,\r\n    /**< Start of time process failed. */\r\n    BD_PJ_ERROR_IMAD_START_TIME_PROCESS_FAILED   = 23,\r\n    /**< Start of thread process failed. */\r\n    BD_PJ_ERROR_IMAD_THREAD_PROCESS_FAILED       = 24,\r\n    /**< No volume control available. */\r\n    BD_PJ_ERROR_IMAD_NO_VOL_CONTROL_AVAILABLE    = 25,\r\n} bdIMADpj_Status;\r\n\r\n/**\r\n * @brief Parameter to pass to set and get parameter functions. \r\n *\r\n * For each enumeration are defined the data type and the supported operations\r\n * on that parameter (set and get).\r\n */\r\n   \r\ntypedef enum bdIMADpj_Parameter{\r\n    /**< int*   \\n set/get \\n 1 enable / 0 disable echo cancellation. */\r\n    BD_PARAM_IMAD_PJ_AEC_ENABLE                 = 1,\r\n    /**< int*   \\n set/get \\n 1 enable / 0 disable microphone control\r\n     * (when possible). */\r\n    BD_PARAM_IMAD_PJ_MIC_CONTROL_ENABLE         = 2,\r\n    /**< int*   \\n set/get \\n 1 ebable / 0 disable noise reduction. */\r\n    BD_PARAM_IMAD_PJ_NOISE_REDUCTION_ENABLE     = 3,\r\n    /**< int*   \\n set     \\n number of channel to reset. Used to reset\r\n     * the input channel statistics. To be used when the same channel\r\n     * is assigned to another partecipant. */\r\n    BD_PARAM_IMAD_PJ_RESET_STATISTIC_IN_CH      = 4,\r\n    /**< float* \\n set/get \\n 0.0f -> 1.0f volume of\r\n     * the microphone(when possible). */\r\n    BD_PARAM_IMAD_PJ_MIC_VOLUME                 = 5,\r\n    /**< int*   \\n set/get \\n 0 mute / 1 not mute on microphone\r\n     * (when possible). */\r\n    BD_PARAM_IMAD_PJ_MIC_MUTE                   = 6,\r\n    /**< float* \\n set/get \\n 0.0f -> 1.0f volume of the speaker. */\r\n    BD_PARAM_IMAD_PJ_SPK_VOLUME                 = 7,\r\n    /**< int*   \\n set/get \\n 0 mute / 1 not mute on speaker. */\r\n    BD_PARAM_IMAD_PJ_SPK_MUTE                   = 8,\r\n} bdIMADpj_Parameter;\r\n\r\n\r\n/**\r\n * @brief Instance structure for the information regarding the aec engine.\r\n */\r\n\r\ntypedef struct bdIMADpj_Setting_t{\r\n    /**< Sample frequency (8kHz or 16kHz). */\r\n    int                 SamplingFrequency;\r\n    /**< Audio buffer managed by the aec bdIMAD functions.\r\n     * (from 16ms to 80ms, 16ms recommended). */\r\n    int                 FrameSize_ms;\r\n    /**< Points to the validation functions in the validation library. */\r\n    void                *validate;\r\n    /**< Points to the the callback function used for filling\r\n     * the playback buffer of bdIMAD. */\r\n    cb_fillPlayBackB_t  cb_fillPlayBackBuffer;\r\n    /**< Points to user data to pass to the callback. */\r\n    void                *cb_fillPlayBackBuffer_user_data;\r\n    /**< Points to the callback function used for retreive the processed\r\n     * audio present in the capture buffer of bdIMAD. */\r\n    cb_emptyCaptureB_t  cb_emptyCaptureBuffer;\r\n    /**< Points to user data to pass to the callback. */\r\n    void                *cb_emptyCaptureBuffer_user_data;\r\n    /**< Is a wide char pointer to the capture device name. */\r\n    wchar_t             *CaptureDevice;\r\n    /**< Is a wide char pointer to the play device name. */\r\n    wchar_t             *PlayDevice;\r\n    /**< True to enable diagnostic, false to disable. */\r\n    int \t            DiagnosticEnable;\r\n    /**< Directory which will contains the files generated for diagnostic. */\r\n    wchar_t             *DiagnosticFolderPath;\r\n    /**< Is an auxiliary settings pointer used internally by bdIMAD. */\r\n    void                *bdIMADwr_SettingsData;\r\n} bdIMADpj_Setting_t;\r\n\r\n/**\r\n * @brief Instance structure for the warnings generated by the initialization\r\n * functions.\r\n */\r\n\r\ntypedef struct bdIMADpj_Warnings_t{\r\n    /**< The capture device indicated can't be opened, has been selected\r\n     * the default capture device. */\r\n    int DefaultCaptureDeviceAutomaticallySelected;\r\n    /**< The capture device opened has not volume control. */\r\n    int CaptureDeviceWithoutVolumeControl;\r\n    /**< The play device indicated can't be opened, has been selected\r\n     * the default play device. */\r\n    int DefaultPlayDeviceAutomaticallySelected;\r\n    /**< The number of channel requested is out of range. The number of\r\n     * channel opened is equal to the maximum. */\r\n    int NumberOfChannelsOutOfRange;\r\n    /**< The diagnostic files could not be saved. */\r\n    int DiagnosticSaveNotAllowed;\r\n    /**< The nlp level requested is not allowed, it has been automatically\r\n     * changed to the default value. */\r\n    int nlpLevelChangeSettting;\r\n    /**< No capture device is present. Anyway the bdSES has been\r\n     * istantiated only for playback. */\r\n    int NoCaptureDevicePresent;\r\n    /**< The cpu is not adapt to run the aec engine, the aec has been disabled.\r\n     * This appens for very old cpu like pentium III. */\r\n    int oldCPUdetected_AECdisable;\r\n    /**< Windows Direct Sound error. */\r\n    long directSoundError;\r\n    /**< Windows Direct Sound volume error. */\r\n    long directSoundLevel;\r\n    /**< No play device is present. Anyway the bdSES has been istantiated\r\n     * only for capture. */\r\n    int NoPlayDevicePresent;\r\n} bdIMADpj_Warnings_t;\r\n\r\n/**\r\n * @brief Instance structure for the library version\r\n */\r\n\r\ntypedef struct bdIMADpj_libVersion_t{\r\n    int     major;                                /**< major version. */\r\n    int\t    minor;                                /**< minor version. */\r\n    int\t    build;                                /**< build number. */\r\n    char    *name;                                /**< name \"bdIMADpj ver.X\". */\r\n    char    *version;                             /**< beta, RC, release. */\r\n    char    *buildDate;                           /**< build date. */\r\n} bdIMADpj_libVersion_t;\r\n\r\n\r\n/**\r\n * @brief Audio output routing setting to pass to set and get route output device functions.\r\n */\r\ntypedef enum bdIMADpj_out_dev_route{\r\n    /** Default route. */\r\n    BD_AUD_DEV_ROUTE_DEFAULT = 0,\r\n\r\n    /** Route to loudspeaker */\r\n    BD_AUD_DEV_ROUTE_LOUDSPEAKER = 1,\r\n\r\n    /** Route to earpiece */\r\n    BD_AUD_DEV_ROUTE_EARPIECE = 2\r\n}bdIMADpj_out_dev_route;\r\n\r\n\r\n/**\r\n * @}\r\n */\r\n\r\n\r\n\r\n/**\r\n * @addtogroup groupFunction\r\n * @{\r\n */\r\n\r\n#ifdef __cplusplus\r\nextern \"C\" {\r\n#endif\r\n\r\n/**\r\n * @brief Must be used to allocate and set to default parameter the memory\r\n * for the bdIMAD.\r\n *\r\n * The function generate a structure bdIMADpj_Setting_t filled with the\r\n * default settings.\r\n * \\n The user can change this settings according to the need and then\r\n * launch the ::bdIMADpj_InitAEC.\r\n * \\n The function generate also a warning structure (::bdIMADpj_Warnings_t)\r\n * that could be used in ::bdIMADpj_InitAEC to handle eventual warnings.\r\n * @param[out] **ppSettings            Points to the pointer of the\r\n *                                     allocated ::bdIMADpj_Setting_t.\r\n * @param[out] **ppWarningMessages     Points to the pointer of the\r\n *                                     allocated ::bdIMADpj_Warnings_t.\r\n * @return                             ::BD_PJ_OK if the function has been\r\n *                                     performed successfully, otherwise return\r\n *                                     an error (refer to ::bdIMADpj_Status).\r\n */\r\nBDIMADPJ_API bdIMADpj_Status bdIMADpj_CreateStructures(\r\n\t\t\t\t    bdIMADpj_Setting_t **ppSettings,\r\n\t\t\t\t    bdIMADpj_Warnings_t **ppWarningMessages);\r\n\r\n/**\r\n * @brief Is used to free the memory for the ::bdIMADpj_Setting_t structure and\r\n * ::bdIMADpj_Warnings_t structure allocated with\r\n * the ::bdIMADpj_CreateStructures.\r\n * @param[in] **ppSettings             Pointer to a memory location filled\r\n * \t\t\t\t       with the address of the\r\n * \t\t\t\t       ::bdIMADpj_Setting_t structure to free.\r\n * This address will be set to NULL.\r\n * @param[in] **ppWarningMessages      Pointer to a memory location filled\r\n * \t\t\t\t       with the address of the allocated\r\n * \t\t\t\t       ::bdIMADpj_Warnings_t structure to free.\r\n * \t\t\t\t       This address will be set to NULL.\r\n * @return                             ::BD_PJ_OK if the function has been\r\n * \t\t\t\t       performed successfully, otherwise return\r\n * \t\t\t\t       an error (refer to ::bdIMADpj_Status).\r\n */\r\nBDIMADPJ_API bdIMADpj_Status bdIMADpj_FreeStructures(\r\n\t\t\t\t    bdIMADpj_Setting_t **ppSettings,\r\n\t\t\t\t    bdIMADpj_Warnings_t **ppWarningMessages);\r\n\r\n/**\r\n * @brief Is used to initialize the memory for bdIMAD with the settings\r\n * contained in the <code>ppSettings</code>.\r\n * @param[out] *pBdIMADInstance        Is the pointer to the bdIMAD object.\r\n * @param[in] **ppSettings             Pointer to pointer to a\r\n * \t\t\t\t       ::bdIMADpj_Setting_t structure, filled\r\n * \t\t\t\t       with initialization settings to be\r\n * \t\t\t\t       applied to the bdIMAD.\r\n *                                     \\n Note, the <code>pBdIMADInstance</code>\r\n *                                     is modified with the applied settings.\r\n * @param[out] **ppWarningMessages     Pointer to pointer to a\r\n * \t\t\t\t       ::bdIMADpj_Warnings_t structure,\r\n * \t\t\t\t       which reports the warnings after the\r\n * \t\t\t\t       initialization.\r\n * @return                             ::BD_PJ_OK if the function has been\r\n * \t\t\t\t       performed successfully, otherwise return\r\n * \t\t\t\t       an error (refer to ::bdIMADpj_Status).\r\n *                                     \\n If the error is\r\n *                                     ::BD_PJ_WARN_BDIMAD_WARNING_ASSERTED\r\n *                                     the init has been performed with success,\r\n *                                     but with a different settings\r\n *                                     respect to the ones required.\r\n *                                     This mainly happens if the audio\r\n *                                     device opened is different to the\r\n *                                     one requested.\r\n */\r\nBDIMADPJ_API bdIMADpj_Status bdIMADpj_InitAEC(bdIMADpj *pBdIMADInstance,\r\n\t\t\t\t      bdIMADpj_Setting_t **ppSettings,\r\n\t\t\t\t      bdIMADpj_Warnings_t **ppWarningMessages);\r\n\r\n/**\r\n * @brief Is used to free the bdIMAD object pointed by the\r\n * <code>pBdIMADInstance</code>.\r\n * @param[in] *pBdIMADInstance         Pointer to the bdIMAD object to free.\r\n * @return                             ::BD_PJ_OK if the function has been\r\n * \t\t\t\t       performed successfully, otherwise return\r\n * \t\t\t\t       an error (refer to ::bdIMADpj_Status).\r\n */\r\nBDIMADPJ_API bdIMADpj_Status bdIMADpj_FreeAEC(bdIMADpj *pBdIMADInstance);\r\n\r\n/**\r\n * @brief Is used to make a list of capure and play devices available\r\n * on the system.\r\n * @param[in] captureDevice            Set to 1 to get the list of capture\r\n * \t\t\t\t       devices. Set to 0 to get the list of\r\n * \t\t\t\t       play devices.\r\n * @param[in] **deviceName             Pointer to pointer to a wide char\r\n * \t\t\t\t       containing the names of capture/play\r\n * \t\t\t\t       devices.\r\n * @return                             ::BD_PJ_OK if the function has been\r\n * \t\t\t\t       performed successfully, otherwise return\r\n * \t\t\t\t       an error (refer to ::bdIMADpj_Status).\r\n */\r\nBDIMADPJ_API bdIMADpj_Status bdIMADpj_getDeviceName(int captureDevice,\r\n\t\t\t\t\t\t    wchar_t **deviceName);\r\n\r\n/**\r\n * @brief Is used to freeze the bdIMAD, stopping the audio playback\r\n * and recording.\r\n * @param[in] bdIMADInstance           bdIMAD object.\r\n * @return                             ::BD_PJ_OK if the function has been\r\n * \t\t\t\t       performed successfully, otherwise\r\n * \t\t\t\t       return an error (refer to\r\n * \t\t\t\t       ::bdIMADpj_Status).\r\n */\r\nBDIMADPJ_API bdIMADpj_Status bdIMADpj_stop(bdIMADpj bdIMADInstance);\r\n\r\n/**\r\n * @brief Is used to put back in play the audio after it has been stopped by the\r\n * ::bdIMADpj_stop functions.\r\n * @param[in] bdIMADInstance           bdIMAD object.\r\n * @return                             ::BD_PJ_OK if the function has been\r\n * \t\t\t\t       performed successfully, otherwise\r\n * \t\t\t\t       return an error (refer to\r\n * \t\t\t\t       ::bdIMADpj_Status).\r\n */\r\nBDIMADPJ_API bdIMADpj_Status bdIMADpj_run(bdIMADpj bdIMADInstance);\r\n\r\n/**\r\n * @brief Print on a standard output the warning messages.\r\n * @param[in] *pWarningMessages        Pointer to the warning structure\r\n * \t\t\t\t       to be printed.\r\n * @return                             ::BD_PJ_OK if the function has been\r\n * \t\t\t\t       performed successfully, otherwise\r\n * \t\t\t\t       return an error\r\n * \t\t\t\t       (refer to ::bdIMADpj_Status).\r\n */\r\nBDIMADPJ_API bdIMADpj_Status bdIMADpj_DisplayWarnings(\r\n\t\t\t\t\tbdIMADpj_Warnings_t *pWarningMessages);\r\n\r\n/**\r\n * @brief Clear the warning structure after being read.\r\n * @param[out] **ppWarningMessages     Pointer to pointer to the warning\r\n * \t\t\t\t       structure to be cleared.\r\n * @return                             ::BD_PJ_OK if the function has been\r\n * \t\t\t\t       performed successfully, otherwise\r\n * \t\t\t\t       return an error (refer to\r\n * \t\t\t\t       ::bdIMADpj_Status).\r\n */\r\nBDIMADPJ_API bdIMADpj_Status bdIMADpj_ClearAllWarnings(\r\n\t\t\t\t       bdIMADpj_Warnings_t **ppWarningMessages);\r\n\r\n/**\r\n * @brief Is used to set a parameter of the bdIMAD object pointed by the\r\n * <code>pBdIMADInstance</code>.\r\n * @param[in] bdIMADInstance           bdIMAD object.\r\n * @param[in] parameterName            Indicate the parameter to set.\r\n * @param[in] *pValue                  Is a pointer to the value to set\r\n * \t\t\t\t       cast to void.\r\n * \t\t\t\t       \\n In the ::bdIMADpj_Parameter\r\n * \t\t\t\t       declaration is indicated the real type of\r\n * \t\t\t\t       the value, depending on the\r\n * \t\t\t\t       <code>parameterName</code>.\r\n * @return                             ::BD_PJ_OK if the function has been\r\n * \t\t\t\t       performed successfully, otherwise\r\n * \t\t\t\t       return an error (refer to\r\n * \t\t\t\t       �::bdIMADpj_Status).\r\n */\r\nBDIMADPJ_API bdIMADpj_Status bdIMADpj_setParameter(bdIMADpj bdIMADInstance,\r\n\t\t\t\tbdIMADpj_Parameter parameterName, void *pValue);\r\n\r\n/**\r\n * @brief Is used to get a parameter of the bdIMAD object pointed by the\r\n * <code>pBdIMADInstance</code>.\r\n * @param[in] bdIMADInstance           bdIMAD object.\r\n * @param[in] parameterName            Indicate the parameter to get.\r\n * @param[out] *pValue                 Is a pointer to the value to get cast\r\n * \t\t\t\t       to void. \\n In the\r\n * \t\t\t\t       ::bdIMADpj_Parameter declaration is\r\n * \t\t\t\t       indicated the real type of the value,\r\n * \t\t\t\t       depending on the\r\n * \t\t\t\t       <code>parameterName</code>.\r\n * @return                             ::BD_PJ_OK if the function has been\r\n * \t\t\t\t       performed successfully, otherwise return\r\n * \t\t\t\t       an error (refer to ::bdIMADpj_Status).\r\n */\r\nBDIMADPJ_API bdIMADpj_Status bdIMADpj_getParameter(bdIMADpj bdIMADInstance,\r\n\t\t\t\tbdIMADpj_Parameter parameterName, void *pValue);\r\n\r\n/**\r\n * @brief Is used to set the route of the output device of the bdIMAD object pointed by the\r\n * <code>pBdIMADInstance</code>.\r\n * @param[in] bdIMADInstance           bdIMAD object.\r\n * @param[in] outputRoute\t       Indicate the route of the output device to set.\r\n * @param[out] **ppWarningMessages     Pointer to pointer to a\r\n * \t\t\t\t       ::bdIMADpj_Warnings_t structure,\r\n * \t\t\t\t       which reports the warnings after the\r\n * \t\t\t\t       set function.\r\n * @return                             ::BD_PJ_OK if the function has been\r\n * \t\t\t\t       performed successfully, otherwise return\r\n * \t\t\t\t       an error (refer to ::bdIMADpj_Status).\r\n */\r\nBDIMADPJ_API bdIMADpj_Status bdIMADpj_setRouteOutputDevice(bdIMADpj bdIMADInstance, bdIMADpj_out_dev_route outputRoute, bdIMADpj_Warnings_t **ppWarningMessages);\r\n\r\n/**\r\n * @brief Is used to get the route of the output device of the bdIMAD object pointed by the\r\n * <code>pBdIMADInstance</code>.\r\n * @param[in] bdIMADInstance           bdIMAD object.\r\n * @param[out] *outputRoute            Is a pointer to the route of the output device currently setted.\r\n * @return                             ::BD_PJ_OK if the function has been\r\n * \t\t\t\t       performed successfully, otherwise return\r\n * \t\t\t\t       an error (refer to ::bdIMADpj_Status).\r\n */\r\nBDIMADPJ_API bdIMADpj_Status bdIMADpj_getRouteOutputDevice(bdIMADpj bdIMADInstance, bdIMADpj_out_dev_route *outputRoute);\r\n\r\n#ifdef __cplusplus\r\n}\r\n#endif\r\n/**\r\n * @}\r\n */\r\n\r\n#endif //BD_IMAD_PJ_H__\r\n"
  },
  {
    "path": "deps/pjsip/third_party/build/Makefile",
    "content": "DIRS = resample milenage srtp\n\ninclude ../../build.mak\ninclude $(PJDIR)/build/common.mak\n\nall clean dep depend distclean realclean:\n\tfor dir in $(DIRS); do \\\n\t\tif $(MAKE) $(MAKE_FLAGS) -C $$dir $@; then \\\n\t\t    true; \\\n\t\telse \\\n\t\t    exit 1; \\\n\t\tfi; \\\n\tdone\n\ndoc:\n\t\n"
  },
  {
    "path": "deps/pjsip/third_party/build/g7221/Makefile",
    "content": "include ../../../build.mak\ninclude ../../../build/common.mak\n\nexport LIBDIR := ../../lib\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\nexport G7221_CODEC_LIB := ../../lib/libg7221codec-$(TARGET_NAME)$(LIBEXT)\n\n###############################################################################\n# Gather all flags.\n#\nexport _CFLAGS \t:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t\t   $(CFLAGS) $(CC_INC)../.. $(CC_INC)../../g7221/common \\\n\t\t   $(CC_INC)../../g7221/common/stl-files \\\n\t\t   $(CC_INC)../../../pjlib/include\nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\nexport _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(LDFLAGS) \n\nexport G7221_CODEC_SRCDIR = ../../g7221\nexport G7221_CODEC_OBJS = common/common.o common/huff_tab.o common/tables.o \\\n                \tcommon/basic_op.o  \\\n                \tdecode/coef2sam.o decode/dct4_s.o decode/decoder.o \\\n                \tencode/dct4_a.o encode/sam2coef.o encode/encoder.o\n\nexport G7221_CODEC_CFLAGS = $(_CFLAGS)\n\n\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT \n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\nTARGETS := libg7221codec\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && doxygen docs/doxygen.cfg\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend libg7221codec clean realclean distclean\n\nlibg7221codec:\n\t$(MAKE) -f $(RULES_MAK) APP=G7221_CODEC app=libg7221codec $(G7221_CODEC_LIB)\n\nclean print_lib:\n\t$(MAKE) -f $(RULES_MAK) APP=G7221_CODEC app=libg7221codec $@\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.ilbc-$(TARGET_NAME).depend),$(HOST_RMR))\n\t\n\t$(MAKE) -f $(RULES_MAK) APP=G7221_CODEC app=libg7221codec $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=G7221_CODEC app=libg7221codec $@\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/gsm/Makefile",
    "content": "include ../../../build.mak\ninclude ../../../build/common.mak\n\nexport LIBDIR := ../../lib\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\nexport GSM_CODEC_LIB := ../../lib/libgsmcodec-$(TARGET_NAME)$(LIBEXT)\n\n###############################################################################\n# Gather all flags.\n#\nexport _CFLAGS \t:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t\t   $(CFLAGS) $(CC_INC). $(CC_INC)../../gsm/inc \\\n\t\t   $(CC_INC)../../../pjlib/include\nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\nexport _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(LDFLAGS) \n\nexport GSM_CODEC_SRCDIR = ../../gsm/src\nexport GSM_CODEC_OBJS = add.o code.o decode.o \\\n                \tgsm_create.o gsm_decode.o gsm_destroy.o \\\n                \tgsm_encode.o gsm_explode.o gsm_implode.o \\\n                \tgsm_option.o long_term.o \\\n                \tlpc.o preprocess.o rpe.o short_term.o \\\n                \ttable.o\n\nexport GSM_CODEC_CFLAGS = -DSASR -DWAV49 -DNeedFunctionPrototypes=1 $(_CFLAGS)\n\n\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT \n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\nTARGETS := libgsmcodec\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && doxygen docs/doxygen.cfg\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend libgsmcodec clean realclean distclean\n\nlibgsmcodec:\n\t$(MAKE) -f $(RULES_MAK) APP=GSM_CODEC app=libgsmcodec $(GSM_CODEC_LIB)\n\nclean print_lib:\n\t$(MAKE) -f $(RULES_MAK) APP=GSM_CODEC app=libgsmcodec $@\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.ilbc-$(TARGET_NAME).depend),$(HOST_RMR))\n\t\n\t$(MAKE) -f $(RULES_MAK) APP=GSM_CODEC app=libgsmcodec $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=GSM_CODEC app=libgsmcodec $@\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/gsm/config.h",
    "content": "#ifdef _MSC_VER\n#   pragma warning(disable: 4100)   // unreferenced formal parameter\n#   pragma warning(disable: 4101)   // unreferenced local variable\n#   pragma warning(disable: 4244)   // conversion from 'double ' to 'float '\n#   pragma warning(disable: 4305)   // truncation from 'const double ' to 'float '\n#   pragma warning(disable: 4018)   // signed/unsigned mismatch\n//#   pragma warning(disable: 4701)   // local variable used without initialized\n#endif\n\n#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 402\n#  pragma GCC diagnostic ignored \"-Wpragmas\"\n#  pragma GCC diagnostic ignored \"-Wunused-const-variable\"\n#endif\n\n#include <string.h>\n#include \"../../gsm/inc/config.h\"\n"
  },
  {
    "path": "deps/pjsip/third_party/build/ilbc/Makefile",
    "content": "include ../../../build.mak\ninclude ../../../build/common.mak\n\nexport LIBDIR := ../../lib\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\nexport ILBC_LIB := ../../lib/libilbccodec-$(TARGET_NAME)$(LIBEXT)\n\n###############################################################################\n# Gather all flags.\n#\nexport _CFLAGS \t:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t\t   $(CFLAGS) $(CC_INC). $(CC_INC)../../ilbc \\\n\t\t   $(CC_INC)../../../pjlib/include\nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\nexport _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(LDFLAGS) \n\nexport ILBC_SRCDIR = ../../ilbc\nexport ILBC_OBJS = FrameClassify.o LPCdecode.o LPCencode.o \\\n\t\t   StateConstructW.o StateSearchW.o anaFilter.o \\\n\t\t   constants.o createCB.o doCPLC.o \\\n\t\t   enhancer.o filter.o gainquant.o \\\n\t\t   getCBvec.o helpfun.o hpInput.o \\\n\t\t   hpOutput.o iCBConstruct.o iCBSearch.o \\\n\t\t   iLBC_decode.o iLBC_encode.o lsf.o \\\n\t\t   packing.o syntFilter.o\nexport ILBC_CFLAGS = $(_CFLAGS)\n\n\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT \n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\nTARGETS := libilbccodec\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && doxygen docs/doxygen.cfg\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend libilbccodec clean realclean distclean\n\nlibilbccodec:\n\t$(MAKE) -f $(RULES_MAK) APP=ILBC app=libilbccodec $(ILBC_LIB)\n\nclean print_lib:\n\t$(MAKE) -f $(RULES_MAK) APP=ILBC app=libilbccodec $@\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.ilbc-$(TARGET_NAME).depend),$(HOST_RMR))\n\t\n\t$(MAKE) -f $(RULES_MAK) APP=ILBC app=libilbccodec $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=ILBC app=libilbccodec $@\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/milenage/Makefile",
    "content": "include ../../../build.mak\ninclude ../../../build/common.mak\n\nexport LIBDIR := ../../lib\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\nexport MILENAGE_LIB := ../../lib/libmilenage-$(TARGET_NAME)$(LIBEXT)\n\n###############################################################################\n# Gather all flags.\n#\nexport _CFLAGS \t:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t\t   $(CFLAGS) $(CC_INC). $(CC_INC)../../milenage/include \\\n\t\t   $(CC_INC)../../../pjlib/include\nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\nexport _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(LDFLAGS) \n\nexport MILENAGE_SRCDIR = ../../milenage\nexport MILENAGE_OBJS = milenage.o rijndael.o\nexport MILENAGE_CFLAGS = $(_CFLAGS)\n\n\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT \n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\nTARGETS := libmilenage\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && doxygen docs/doxygen.cfg\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend libmilenage clean realclean distclean\n\nlibmilenage:\n\t$(MAKE) -f $(RULES_MAK) APP=MILENAGE app=libmilenage $(MILENAGE_LIB)\n\nclean print_lib:\n\t$(MAKE) -f $(RULES_MAK) APP=MILENAGE app=libmilenage $@\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.ilbc-$(TARGET_NAME).depend),$(HOST_RMR))\n\t\n\t$(MAKE) -f $(RULES_MAK) APP=MILENAGE app=libmilenage $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=MILENAGE app=libmilenage $@\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/opus/Makefile",
    "content": "include ../../../build.mak\ninclude ../../../build/common.mak\n\nexport LIBDIR := ../../lib\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\nexport OPUS_LIB := ../../lib/libopuscodec-$(TARGET_NAME)$(LIBEXT)\n\n###############################################################################\n# Gather all flags.\n#\nOPUS_DEFS := \\\n\t-DOPUS_BUILD \\\n\t-DHAVE_LRINT \\\n\t-DVAR_ARRAYS\n\nOPUS_SRC_BASE := ../../opus\n\ninclude $(OPUS_SRC_BASE)/silk_sources.mk\ninclude $(OPUS_SRC_BASE)/celt_sources.mk\ninclude $(OPUS_SRC_BASE)/opus_sources.mk\n\nOPUS_INCS := \\\n\t\t   $(CC_INC)$(OPUS_SRC_BASE)/include \\\n\t\t   $(CC_INC)$(OPUS_SRC_BASE)/celt \\\n\t\t   $(CC_INC)$(OPUS_SRC_BASE)/silk \\\n\t\t   $(CC_INC)$(OPUS_SRC_BASE)/silk/float\n\nexport _CFLAGS \t:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t           $(OPUS_DEFS) \\\n\t\t   $(CFLAGS) $(CC_INC). \\\n\t\t   $(CC_INC)../../../pjlib/include \\\n\t\t   $(OPUS_INCS)\nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\nexport _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(LDFLAGS)\n\nOPUS_SRCS_C = $(SILK_SOURCES) $(SILK_SOURCES_FLOAT) $(CELT_SOURCES) $(OPUS_SOURCES) $(OPUS_SOURCES_FLOAT)\n\nexport OPUS_SRCDIR = $(OPUS_SRC_BASE)\nexport OPUS_OBJS := $(patsubst %.c,%.o,$(OPUS_SRCS_C))\nexport OPUS_CFLAGS = $(_CFLAGS)\nexport OPUS_CXXFLAGS = $(_CXXFLAGS)\n\n\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT\n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\nTARGETS := libopuscodec\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && doxygen docs/doxygen.cfg\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend libopuscodec clean realclean distclean\n\nlibopuscodec:\n\t$(MAKE) -f $(RULES_MAK) APP=OPUS app=libopuscodec $(OPUS_LIB)\n\nclean print_lib:\n\t$(MAKE) -f $(RULES_MAK) APP=OPUS app=libopuscodec $@\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.opus-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(MAKE) -f $(RULES_MAK) APP=OPUS app=libopuscodec $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=OPUS app=libopuscodec $@\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/os-auto.mak.in",
    "content": "\nifneq (@ac_no_gsm_codec@,1)\nifeq (@ac_external_gsm@,1)\n# External\nelse\nDIRS += gsm\nendif\nendif\n\nifneq (@ac_no_ilbc_codec@,1)\nDIRS += ilbc\nendif\n\nifneq (@ac_no_speex_codec@,1)\nifeq (@ac_external_speex@,1)\n# External speex\nelse\nDIRS += speex\nendif\nendif\n\nifneq (@ac_no_g7221_codec@,1)\nDIRS += g7221\nendif\n\nifneq ($(findstring webrtc,@ac_webrtc_platform@),)\nDIRS += webrtc\nendif\n\nDIRS += opus\n\nDIRS += zsrtp\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/resample/Makefile",
    "content": "include ../../../build.mak\ninclude ../../../build/common.mak\n\nexport LIBDIR := ../../lib\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\n\n###############################################################################\n# Gather all flags.\n#\nexport _CFLAGS \t:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t\t   $(CFLAGS) $(CC_INC). $(CC_INC)../../resample/include \\\n\t\t   $(CC_INC)../../../pjlib/include\nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\nexport _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(LDFLAGS) \n\nexport RESAMPLE_SRCDIR = ../../resample/src\nexport RESAMPLE_OBJS = resamplesubs.o\nexport RESAMPLE_CFLAGS = $(_CFLAGS)\n\nSHLIB_NAME := libresample.$(SHLIB_SUFFIX)\nexport RESAMPLE_SHLIB := ../../lib/$(SHLIB_NAME).$(PJ_VERSION_MAJOR)\nexport RESAMPLE_LIB := ../../lib/libresample-$(TARGET_NAME)$(LIBEXT)\n\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT \n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\nifeq ($(PJ_RESAMPLE_DLL),1)\nTARGETS := ../../lib/$(SHLIB_NAME)\nifeq ($(SHLIB_SUFFIX),so)\nSHLIB_OPT := -Wl,-soname,$(SHLIB_NAME).$(PJ_VERSION_MAJOR)\nelse\nSHLIB_OPT := \nendif\nexport RESAMPLE_CFLAGS := -fPIC $(RESAMPLE_CFLAGS)\nexport RESAMPLE_LDFLAGS := -shared $(SHLIB_OPT) $(RESAMPLE_LDFLAGS)\nelse\nTARGETS := libresample\nendif\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && doxygen docs/doxygen.cfg\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend libresample clean realclean distclean\n\nlibresample:\n\t$(MAKE) -f $(RULES_MAK) APP=RESAMPLE app=libresample $(RESAMPLE_LIB)\n\n../../lib/$(SHLIB_NAME): $(RESAMPLE_SHLIB)\n\tln -s $(SHLIB_NAME).$(PJ_VERSION_MAJOR) $@\n\n$(RESAMPLE_SHLIB):\n\t$(MAKE) -f $(RULES_MAK) APP=RESAMPLE app=libresample $(RESAMPLE_SHLIB)\n\t\nclean print_lib:\n\t$(MAKE) -f $(RULES_MAK) APP=RESAMPLE app=libresample $@\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),../../lib/$(SHLIB_NAME)),$(HOST_RMR))\n\t$(subst @@,$(subst /,$(HOST_PSEP),$(RESAMPLE_SHLIB)),$(HOST_RMR))\n\t$(MAKE) -f $(RULES_MAK) APP=RESAMPLE app=libresample $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=RESAMPLE app=libresample $@\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/resample/config.h",
    "content": "#ifndef RESAMPLE_HAS_SMALL_FILTER\n#   define RESAMPLE_HAS_SMALL_FILTER\t1\n#endif\n\n#ifndef RESAMPLE_HAS_LARGE_FILTER\n#   define RESAMPLE_HAS_LARGE_FILTER\t1\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/build/speex/Makefile",
    "content": "include ../../../build.mak\ninclude ../../../build/common.mak\n\nexport LIBDIR := ../../lib\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\nexport SPEEX_LIB := ../../lib/libspeex-$(TARGET_NAME)$(LIBEXT)\n\n###############################################################################\n# Gather all flags.\n#\nexport _CFLAGS \t:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t\t   $(CFLAGS) $(CC_INC). $(CC_INC)../../speex/include \\\n\t\t   $(CC_INC)../../speex/libspeex \\\n\t\t   $(CC_INC)../../../pjlib/include\nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\nexport _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(APP_LDFLAGS) $(LDFLAGS) \n\nexport SPEEX_SRCDIR = ../../speex/libspeex\nexport SPEEX_OBJS = \tbits.o cb_search.o exc_10_16_table.o  \\\n\t\t\texc_10_32_table.o exc_20_32_table.o \\\n\t\t\texc_5_256_table.o exc_5_64_table.o \\\n\t\t\texc_8_128_table.o fftwrap.o filterbank.o \\\n\t\t\tfilters.o gain_table.o gain_table_lbr.o \\\n\t\t\thexc_10_32_table.o hexc_table.o \\\n\t\t\thigh_lsp_tables.o \\\n\t\t\tkiss_fft.o kiss_fftr.o lpc.o \\\n\t\t\tlsp.o lsp_tables_nb.o ltp.o \\\n\t\t\tmdf.o modes.o modes_wb.o \\\n\t\t\tnb_celp.o preprocess.o \\\n\t\t\tquant_lsp.o resample.o sb_celp.o smallft.o \\\n\t\t\tspeex.o speex_callbacks.o speex_header.o \\\n\t\t\tstereo.o vbr.o vq.o window.o\n\nexport SPEEX_CFLAGS = -DHAVE_CONFIG_H $(_CFLAGS)\nexport SPEEX_LDFLAGS := $(PJLIB_LDLIB) $(_LDFLAGS)\n\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT \n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\nTARGETS := libspeex\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && doxygen docs/doxygen.cfg\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend libspeex clean realclean distclean\n\nlibspeex:\n\t$(MAKE) -f $(RULES_MAK) APP=SPEEX app=libspeex $(SPEEX_LIB)\n\nclean print_lib:\n\t$(MAKE) -f $(RULES_MAK) APP=SPEEX app=libspeex $@\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.ilbc-$(TARGET_NAME).depend),$(HOST_RMR))\n\t\n\t$(MAKE) -f $(RULES_MAK) APP=SPEEX app=libspeex $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=SPEEX app=libspeex $@\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/speex/config.h",
    "content": "#include <pj/types.h>\n\n/* Check if we need to use the fixed point version */\n#if !defined(PJ_HAS_FLOATING_POINT) || PJ_HAS_FLOATING_POINT==0\n#   define FIXED_POINT\n#   define USE_KISS_FFT\n#else \n#   define FLOATING_POINT\n#   define USE_SMALLFT\n#endif\n\n#define EXPORT\n\n#if (defined(PJ_WIN32) && PJ_WIN32!=0) || \\\n    (defined(PJ_WIN64) && PJ_WIN64!=0) || \\\n    (defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE != 0) \n#   include \"../../speex/win32/config.h\"\n#else\n#define inline __inline\n#define restrict\n#endif\n\n#ifdef _MSC_VER\n#   pragma warning(disable: 4100)   // unreferenced formal parameter\n#   pragma warning(disable: 4101)   // unreferenced local variable\n#   pragma warning(disable: 4244)   // conversion from 'double ' to 'float '\n#   pragma warning(disable: 4305)   // truncation from 'const double ' to 'float '\n#   pragma warning(disable: 4018)   // signed/unsigned mismatch\n#   pragma warning(disable: 4456)   // declaration of '[var]' hides previous local declaration\n//#   pragma warning(disable: 4701)   // local variable used without initialized\n#endif\n\n#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 402\n#  pragma GCC diagnostic ignored \"-Wpragmas\"\n#  pragma GCC diagnostic ignored \"-Wunused-but-set-variable\"\n#endif\n\n#include <pj/log.h>\n\n/*\n * Override miscellaneous Speex functions.\n */\n#define OVERRIDE_SPEEX_ERROR\n#define speex_error(str) PJ_LOG(4,(\"speex\", \"error: %s\", str))\n\n#define OVERRIDE_SPEEX_WARNING\n#define speex_warning(str) PJ_LOG(5,(\"speex\", \"warning: %s\", str))\n\n#define OVERRIDE_SPEEX_WARNING_INT\n#define speex_warning_int(str,val)  PJ_LOG(5,(\"speex\", \"warning: %s: %d\", str, val))\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/speex/speex/speex_config_types.h",
    "content": "#include <pj/types.h>\ntypedef pj_int16_t\tspx_int16_t;\ntypedef pj_uint16_t\tspx_uint16_t;\ntypedef pj_int32_t\tspx_int32_t;\ntypedef pj_uint32_t\tspx_uint32_t;\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/srtp/Makefile",
    "content": "include ../../../build.mak\ninclude ../../../build/common.mak\n\nexport LIBDIR := ../../lib\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\nexport SRTP_LIB := ../../lib/libsrtp-$(TARGET_NAME)$(LIBEXT)\n\n###############################################################################\n# Gather all flags.\n#\nexport _CFLAGS \t:= $(CC_INC). $(CC_INC)../../srtp/crypto/include \\\n\t\t   $(CC_INC)../../srtp/include \\\n\t\t   $(CC_INC)../../../pjlib/include \\\n\t\t   $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t\t   $(CFLAGS) \nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\nexport _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(APP_LDFLAGS) $(LDFLAGS) \n\n# libcrypt.a (the crypto engine) \nciphers = crypto/cipher/cipher.o crypto/cipher/null_cipher.o      \\\n          crypto/cipher/aes.o crypto/cipher/aes_icm.o             \\\n          crypto/cipher/aes_cbc.o\n\nhashes  = crypto/hash/null_auth.o crypto/hash/sha1.o \\\n          crypto/hash/hmac.o crypto/hash/auth.o # crypto/hash/tmmhv2.o \n\nreplay  = crypto/replay/rdb.o crypto/replay/rdbx.o               \\\n          crypto/replay/ut_sim.o \n\nmath    = crypto/math/datatypes.o crypto/math/stat.o\n\nust     = crypto/ust/ust.o \n\nrng     = crypto/rng/rand_source.o crypto/rng/prng.o crypto/rng/ctr_prng.o\n\nerr     = pjlib/srtp_err.o\n\nkernel  = crypto/kernel/crypto_kernel.o  crypto/kernel/alloc.o   \\\n          crypto/kernel/key.o $(rng) $(err) # $(ust) \n\nsrtpobj = srtp/srtp.o \n\ncryptobj =  $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(replay)\n\nexport SRTP_SRCDIR = ../../srtp\nexport SRTP_OBJS = $(cryptobj) $(srtpobj)\nexport SRTP_CFLAGS = -DHAVE_CONFIG_H $(_CFLAGS)\nexport SRTP_LDFLAGS = $(PJLIB_LDLIB) $(_LDFLAGS)\n\n\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT \n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\nTARGETS := libsrtp\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && doxygen docs/doxygen.cfg\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend libsrtp clean realclean distclean\n\nlibsrtp:\n\t$(MAKE) -f $(RULES_MAK) APP=SRTP app=libsrtp $(SRTP_LIB)\n\nclean print_lib:\n\t$(MAKE) -f $(RULES_MAK) APP=SRTP app=libsrtp $@\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.ilbc-$(TARGET_NAME).depend),$(HOST_RMR))\n\t\n\t$(MAKE) -f $(RULES_MAK) APP=SRTP app=libsrtp $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=SRTP app=libsrtp $@\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/srtp/srtp_config.h",
    "content": "/* $Id: srtp_config.h 2660 2009-04-28 19:38:43Z nanang $ */\n/* \n * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef __SRTP_CONFIG_H__\n#define __SRTP_CONFIG_H__\n\n#include <pj/types.h>\n\n/* We'll just define CISC if it's x86 family */\n#if defined (PJ_M_I386) || defined(_i386_) || defined(i_386_) || \\\n    defined(_X86_) || defined(x86) || defined(__i386__) || \\\n    defined(__i386) || defined(_M_IX86) || defined(__I86__) || \\\n    defined (PJ_M_X86_64) || defined(__amd64__) || defined(__amd64) || \\\n    defined(__x86_64__) || defined(__x86_64) || \\\n    defined(PJ_M_IA64) || defined(__ia64__) || defined(_IA64) || \\\n    defined(__IA64__) || defined(_M_IA64)\n#   define CPU_CISC\t    1\n/* #   define HAVE_X86\t    1   use X86 inlined assembly code */\n#else\n/*#   define CPU_RISC\t    1*/\n#   define CPU_CISC\t    1\n#endif\n\n/* Define to compile in dynamic debugging system. */\n#define ENABLE_DEBUGGING    PJ_DEBUG\n\n/* Define to 1 if you have the <arpa/inet.h> header file. */\n#if defined(PJ_HAS_ARPA_INET_H) && PJ_HAS_ARPA_INET_H!=0\n#   define HAVE_ARPA_INET_H 1\n#endif\n\n/* Define to 1 if you have the <byteswap.h> header file. */\n/* #undef HAVE_BYTESWAP_H */\n\n/* Define to 1 if you have the `inet_aton' function. */\n#if defined(PJ_SOCK_HAS_INET_PTON) && PJ_SOCK_HAS_INET_PTON\n#   define HAVE_INET_ATON   1\n#endif\n\n\n/* Define to 1 if you have the <netinet/in.h> header file. */\n#if defined(PJ_HAS_NETINET_IN_H) && PJ_HAS_NETINET_IN_H!=0\n#   define HAVE_NETINET_IN_H\t1\n#endif\n\n/* Define to 1 if you have the <stdlib.h> header file. */\n#if defined(PJ_HAS_STDLIB_H) && PJ_HAS_STDLIB_H!=0\n#   define HAVE_STDLIB_H    1\n#endif\n\n/* Define to 1 if you have the <string.h> header file. */\n#if defined(PJ_HAS_STRING_H) && PJ_HAS_STRING_H!=0\n#   define HAVE_STRING_H    1\n#endif\n\n/* Define to 1 if you have the <sys/socket.h> header file. */\n#if defined(PJ_HAS_SYS_SOCKET_H) && PJ_HAS_SYS_SOCKET_H!=0\n#   define HAVE_SYS_SOCKET_H\t1\n#endif\n\n/* Define to 1 if you have the <sys/types.h> header file. */\n#if defined(PJ_HAS_SYS_TYPES_H) && PJ_HAS_SYS_TYPES_H!=0\n#   define HAVE_SYS_TYPES_H 1\n#endif\n\n/* Define to 1 if you have the <unistd.h> header file. */\n/* Define to 1 if you have the `usleep' function. */\n#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H!=0\n#   define HAVE_UNISTD_H    1\n#   define HAVE_USLEEP\t    1\n#endif\n\n\n/* Define to 1 if you have the <windows.h> header file. */\n#if (defined(PJ_WIN32) && PJ_WIN32!=0) || (defined(PJ_WIN64) && PJ_WIN64 != 0)\n#   define HAVE_WINDOWS_H   1\n#endif\n\n/* Define to 1 if you have the <winsock2.h> header file. */\n#if defined(PJ_HAS_WINSOCK2_H) && PJ_HAS_WINSOCK2_H!=0\n#   define HAVE_WINSOCK2_H  1\n#endif\n\n#define HAVE_INT16_T\t    1\n#define HAVE_INT32_T\t    1\n#define HAVE_INT8_T\t    1\n#define HAVE_UINT8_T\t    1\n#define HAVE_UINT16_T\t    1\n#define HAVE_UINT32_T\t    1\n#define HAVE_UINT64_T\t    1\n\n/* Define to 1 if you have the <stdint.h> header file. */\n#if defined(PJ_HAS_STDINT_H) && PJ_HAS_STDINT_H!=0\n#   define HAVE_STDINT_H    1\n#else\n    typedef pj_uint8_t\t    uint8_t;\n    typedef pj_uint16_t\t    uint16_t;\n    typedef pj_uint32_t\t    uint32_t;\n    typedef pj_uint64_t\t    uint64_t;\n    typedef pj_int8_t\t    int8_t;\n    typedef pj_int16_t\t    int16_t;\n    typedef pj_int32_t\t    int32_t;\n    typedef pj_int64_t\t    int64_t;\n#endif\n\n/* These shouldn't really matter as long as HAVE_UINT64_T is set */\n#define SIZEOF_UNSIGNED_LONG\t    (sizeof(unsigned long))\n#define SIZEOF_UNSIGNED_LONG_LONG   8\n\n\n#if (_MSC_VER >= 1400) // VC8+\n#   ifndef _CRT_SECURE_NO_DEPRECATE\n#\tdefine _CRT_SECURE_NO_DEPRECATE\n#   endif\n#   ifndef _CRT_NONSTDC_NO_DEPRECATE\n#\tdefine _CRT_NONSTDC_NO_DEPRECATE\n#   endif\n#endif // VC8+\n\n#ifdef _MSC_VER\n#   ifndef __cplusplus\n#\tdefine inline _inline\n#   endif\n\n#   pragma warning(disable:4311)\n#   pragma warning(disable:4761) // integral mismatch\n#   pragma warning(disable:4018) // signed/unsigned mismatch\n#   pragma warning(disable:4244) // conversion from int64 to int\n#   pragma warning(disable:4100) // unreferenced formal parameter\n#endif\n\n/* clock()  */\n#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0\n    /* clock() causes unresolved symbol on linking */\n#   define _CLOCK_T_DEFINED\n#   define CLOCKS_PER_SEC   1000\n#   define clock_t\t    unsigned\n\n    #include <windows.h>\n    static clock_t clock(void)\n    {\n\treturn GetTickCount();\n    }\n#endif\n\n\n/* Path to random device */\n/* #define DEV_URANDOM \"/dev/urandom\" */\n\n/* Only with PJSIP:\n * Try to open PJ_DEV_URANDOM if present\n */\n#if defined(PJ_HAS_FCNTL_H) && defined(PJ_HAS_UNISTD_H)\n#   define PJ_DEV_URANDOM\t\"/dev/urandom\"\n#endif\n\n/* We have overridden libsrtp error mechanism, so these are not used. */\n/* #undef ERR_REPORTING_FILE */\n/* #undef ERR_REPORTING_STDOUT */\n/* #undef USE_ERR_REPORTING_FILE */\n/* #undef USE_SYSLOG */\n/* #undef HAVE_SYSLOG_H */\n\n\n/* Define this to use ISMAcryp code. */\n/* #undef GENERIC_AESICM */\n\n/* Define to 1 if you have the <inttypes.h> header file. */\n/* #undef HAVE_INTTYPES_H */\n\n/* Define to 1 if you have the `socket' function. */\n/* #undef HAVE_SOCKET */\n\n/* Define to 1 if you have the `socket' library (-lsocket). */\n/* #undef HAVE_LIBSOCKET */\n\n/* Define to 1 if you have the <machine/types.h> header file. */\n/* #undef HAVE_MACHINE_TYPES_H */\n\n\n/* Define to 1 if you have the <strings.h> header file. */\n//#define HAVE_STRINGS_H 1\n\n/* Define to 1 if you have the <sys/int_types.h> header file. */\n/* #undef HAVE_SYS_INT_TYPES_H */\n\n/* Define to use GDOI. */\n/* #undef SRTP_GDOI */\n\n/* Define to compile for kernel contexts. */\n/* #undef SRTP_KERNEL */\n\n/* Define to compile for Linux kernel context. */\n/* #undef SRTP_KERNEL_LINUX */\n\n/* Define to 1 if you have the ANSI C header files. */\n//#define STDC_HEADERS 1\n\n/* Endianness would have been set by pjlib. */\n/* #undef WORDS_BIGENDIAN */\n\n/* Define to empty if `const' does not conform to ANSI C. */\n/* #undef const */\n\n/* Define to `unsigned' if <sys/types.h> does not define. */\n/* #undef size_t */\n\n\n#endif\t/* __SRTP_CONFIG_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/webrtc/Makefile",
    "content": "include ../../../build.mak\ninclude ../../../build/common.mak\n\nexport LIBDIR := ../../lib\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\nexport WEBRTCAEC_LIB := ../../lib/libwebrtcaec-$(TARGET_NAME)$(LIBEXT)\n\nWEBRTC_DEFS := \\\n\t-D__STDC_FORMAT_MACROS \\\n\t-DDYNAMIC_ANNOTATIONS_ENABLED=1 \\\n\t-D_DEBUG\n\nWEBRTC_CFLAGS := \\\n\t-fno-exceptions \\\n\t-Wall \\\n\t-Wno-unused-parameter \\\n\t-Wno-missing-field-initializers \\\n\t-D_FILE_OFFSET_BITS=64 \\\n\t-fvisibility=hidden \\\n\t-pipe \\\n\t-fno-strict-aliasing\n\nWEBRTC_CFLAGS_CC := \\\n\t-fno-threadsafe-statics \\\n\t-fvisibility-inlines-hidden \\\n\t-Wsign-compare\n\nWEBRTC_SRC_BASE := ../../webrtc\n\nWEBRTCAEC_INCS := \\\n\t\t   $(CC_INC)$(WEBRTC_SRC_BASE)/src \\\n\t\t   $(CC_INC)$(WEBRTC_SRC_BASE)/src/common_audio/signal_processing_library/main/interface \\\n\t\t   $(CC_INC)$(WEBRTC_SRC_BASE)/src/modules/audio_processing/aec/main/interface \\\n\t\t   $(CC_INC)$(WEBRTC_SRC_BASE)/src/modules/audio_processing/agc/main/interface \\\n\t\t   $(CC_INC)$(WEBRTC_SRC_BASE)/src/modules/audio_processing/ns/main/interface \\\n\t\t   $(CC_INC)$(WEBRTC_SRC_BASE)/src/modules/audio_processing/utility \\\n\t\t   $(CC_INC)$(WEBRTC_SRC_BASE)/src/system_wrappers/source/spreadsortlib \\\n\t\t   $(CC_INC)$(WEBRTC_SRC_BASE)/src/system_wrappers/interface\n\nexport _CFLAGS \t:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) $(CFLAGS) \\\n\t\t   $(WEBRTC_DEFS) $(WEBRTC_CFLAGS) \\\n\t\t   $(CC_INC). \\\n\t\t   $(CC_INC)../../../pjlib/include \\\n\t\t   $(WEBRTCAEC_INCS)\nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) $(HOST_CXXFLAGS) $(CXXFLAGS) \\\n\t\t   $(WEBRTC_DEFS) $(WEBRTC_CFLAGS_CC)\nexport _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(LDFLAGS)\n\n\nAEC_OBJS := modules/audio_processing/aec/main/source/echo_cancellation.o \\\n\t    modules/audio_processing/aec/main/source/aec_core.o \\\n\t    modules/audio_processing/aec/main/source/aec_core_sse2.o \\\n\t    modules/audio_processing/aec/main/source/aec_rdft.o \\\n\t    modules/audio_processing/aec/main/source/aec_rdft_sse2.o \\\n\t    modules/audio_processing/aec/main/source/resampler.o\n\nAGC_OBJS := modules/audio_processing/agc/main/source/analog_agc.o \\\n\t    modules/audio_processing/agc/main/source/digital_agc.o\n\nAPM_OBJS := modules/audio_processing/utility/ring_buffer.o \\\n\t    modules/audio_processing/utility/fft4g.o\n\nSPL_OBJS := common_audio/signal_processing_library/main/source/auto_corr_to_refl_coef.o \\\n\t    common_audio/signal_processing_library/main/source/auto_correlation.o \\\n\t    common_audio/signal_processing_library/main/source/complex_fft.o \\\n\t    common_audio/signal_processing_library/main/source/complex_ifft.o \\\n\t    common_audio/signal_processing_library/main/source/complex_bit_reverse.o \\\n\t    common_audio/signal_processing_library/main/source/copy_set_operations.o \\\n\t    common_audio/signal_processing_library/main/source/cos_table.o \\\n\t    common_audio/signal_processing_library/main/source/cross_correlation.o \\\n\t    common_audio/signal_processing_library/main/source/division_operations.o \\\n\t    common_audio/signal_processing_library/main/source/dot_product_with_scale.o \\\n\t    common_audio/signal_processing_library/main/source/downsample_fast.o \\\n\t    common_audio/signal_processing_library/main/source/energy.o \\\n\t    common_audio/signal_processing_library/main/source/filter_ar.o \\\n\t    common_audio/signal_processing_library/main/source/filter_ar_fast_q12.o \\\n\t    common_audio/signal_processing_library/main/source/filter_ma_fast_q12.o \\\n\t    common_audio/signal_processing_library/main/source/get_hanning_window.o \\\n\t    common_audio/signal_processing_library/main/source/get_scaling_square.o \\\n\t    common_audio/signal_processing_library/main/source/hanning_table.o \\\n\t    common_audio/signal_processing_library/main/source/ilbc_specific_functions.o \\\n\t    common_audio/signal_processing_library/main/source/levinson_durbin.o \\\n\t    common_audio/signal_processing_library/main/source/lpc_to_refl_coef.o \\\n\t    common_audio/signal_processing_library/main/source/min_max_operations.o \\\n\t    common_audio/signal_processing_library/main/source/randn_table.o \\\n\t    common_audio/signal_processing_library/main/source/randomization_functions.o \\\n\t    common_audio/signal_processing_library/main/source/refl_coef_to_lpc.o \\\n\t    common_audio/signal_processing_library/main/source/resample.o \\\n\t    common_audio/signal_processing_library/main/source/resample_48khz.o \\\n\t    common_audio/signal_processing_library/main/source/resample_by_2.o \\\n\t    common_audio/signal_processing_library/main/source/resample_by_2_internal.o \\\n\t    common_audio/signal_processing_library/main/source/resample_fractional.o \\\n\t    common_audio/signal_processing_library/main/source/sin_table.o \\\n\t    common_audio/signal_processing_library/main/source/sin_table_1024.o \\\n\t    common_audio/signal_processing_library/main/source/spl_sqrt.o \\\n\t    common_audio/signal_processing_library/main/source/spl_sqrt_floor.o \\\n\t    common_audio/signal_processing_library/main/source/spl_version.o \\\n\t    common_audio/signal_processing_library/main/source/splitting_filter.o \\\n\t    common_audio/signal_processing_library/main/source/sqrt_of_one_minus_x_squared.o \\\n\t    common_audio/signal_processing_library/main/source/vector_scaling_operations.o \\\n\t    common_audio/signal_processing_library/main/source/webrtc_fft_t_1024_8.o \\\n\t    common_audio/signal_processing_library/main/source/webrtc_fft_t_rad.o\n\nSWR_OBJS := system_wrappers/source/aligned_malloc.o \\\n            system_wrappers/source/atomic32.o \\\n            system_wrappers/source/condition_variable.o \\\n            system_wrappers/source/cpu.o \\\n            system_wrappers/source/cpu_features.o \\\n            system_wrappers/source/critical_section.o \\\n            system_wrappers/source/event.o \\\n            system_wrappers/source/file_impl.o \\\n            system_wrappers/source/list_no_stl.o \\\n            system_wrappers/source/map.o \\\n            system_wrappers/source/rw_lock.o \\\n            system_wrappers/source/sort.o \\\n            system_wrappers/source/thread.o \\\n            system_wrappers/source/trace_impl.o\n\nNS_OBJS := modules/audio_processing/ns/main/source/noise_suppression.o \\\n\t   modules/audio_processing/ns/main/source/ns_core.o\n\nexport WEBRTCAEC_SRCDIR = $(WEBRTC_SRC_BASE)/src\nexport WEBRTCAEC_OBJS = $(AEC_OBJS) $(AGC_OBJS) $(NS_OBJS) $(APM_OBJS) $(SWR_OBJS) $(SPL_OBJS)\nexport WEBRTCAEC_CFLAGS = $(_CFLAGS)\nexport WEBRTCAEC_CXXFLAGS = $(_CXXFLAGS)\n\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT\n\n\n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\nTARGETS := libwebrtcaec\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && doxygen docs/doxygen.cfg\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend libwebrtcaec clean realclean distclean\n\nlibwebrtcaec:\n\t$(MAKE) -f $(RULES_MAK) APP=WEBRTCAEC app=libwebrtcaec $(WEBRTCAEC_LIB)\n\nclean print_lib:\n\t$(MAKE) -f $(RULES_MAK) APP=WEBRTCAEC app=libwebrtcaec $@\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.ilbc-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(MAKE) -f $(RULES_MAK) APP=WEBRTCAEC app=libwebrtcaec $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=WEBRTCAEC app=libwebrtcaec $@\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/webrtc/os-auto.mak.in",
    "content": "# @configure_input@\n\nAC_WEBRTC_PLATFORM=@ac_webrtc_platform@\n\nifeq ($(AC_WEBRTC_PLATFORM),webrtc_linux)\nexport CFLAGS += -DWEBRTC_TARGET_PC -DWEBRTC_LINUX -DWEBRTC_THREAD_RR\nexport CFLAGS += -pthread\n\nexport WEBRTCAEC_OBJS += system_wrappers/source/condition_variable_posix.o \\\n            \t\t system_wrappers/source/critical_section_posix.o \\\n            \t\t system_wrappers/source/event_posix.o \\\n            \t\t system_wrappers/source/rw_lock_posix.o \\\n            \t\t system_wrappers/source/thread_posix.o \\\n            \t\t system_wrappers/source/trace_posix.o \\\n            \t\t system_wrappers/source/cpu_linux.o\nendif\n\nifeq ($(AC_WEBRTC_PLATFORM),webrtc_darwinos)\nexport CFLAGS += -DWEBRTC_TARGET_MAC_INTEL -DWEBRTC_MAC_INTEL -DWEBRTC_MAC -DWEBRTC_THREAD_RR -DWEBRTC_CLOCK_TYPE_REALTIME\nexport CFLAGS += -pthread\n\nexport WEBRTCAEC_OBJS += system_wrappers/source/condition_variable_posix.o \\\n            \t\t system_wrappers/source/critical_section_posix.o \\\n            \t\t system_wrappers/source/event_posix.o \\\n            \t\t system_wrappers/source/rw_lock_posix.o \\\n            \t\t system_wrappers/source/thread_posix.o \\\n            \t\t system_wrappers/source/trace_posix.o \\\n            \t\t system_wrappers/source/cpu_mac.o\nendif\n\nifeq ($(AC_WEBRTC_PLATFORM),webrtc_win32)\nexport CFLAGS += -DWEBRTC_TARGET_PC -D_WIN32 -D_CRT_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_DEPRECATE -D__STD_C\n\nexport WEBRTCAEC_OBJS += system_wrappers/source/condition_variable_windows.o \\\n            \t\t system_wrappers/source/critical_section_windows.o \\\n            \t\t system_wrappers/source/event_windows.o \\\n            \t\t system_wrappers/source/rw_lock_windows.o \\\n            \t\t system_wrappers/source/thread_windows.o \\\n            \t\t system_wrappers/source/trace_windows.o \\\n            \t\t system_wrappers/source/cpu_windows.o\nendif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/build/zsrtp/Makefile",
    "content": "include ../../../build.mak\ninclude ../../../build/common.mak\n\nexport LIBDIR := ../../lib\n\nRULES_MAK := $(PJDIR)/build/rules.mak\n\nexport ZSRTP_LIB := ../../lib/libzsrtp-$(TARGET_NAME)$(LIBEXT)\n\n###############################################################################\n# Gather all flags.\n#\nexport _CFLAGS \t:= $(CC_INC). $(CC_INC)../../zsrtp/include \\\n\t\t   $(CC_INC)../../zsrtp/zrtp \\\n\t\t   $(CC_INC)../../zsrtp/zrtp/zrtp \\\n\t\t   $(CC_INC)../../zsrtp/zrtp/zrtp/libzrtpcpp \\\n\t\t   $(CC_INC)../../zsrtp/zrtp/srtp \\\n\t\t   $(CC_INC)../../zsrtp/zrtp/srtp/crypto \\\n\t\t   $(CC_INC)../../../pjlib/include \\\n\t\t   $(CC_INC)../../../pjlib-util/include \\\n\t\t   $(CC_INC)../../../pjmedia/include \\\n\t\t   $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \\\n\t\t   $(CFLAGS)  -fno-strict-aliasing\nexport _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \\\n\t\t   $(HOST_CXXFLAGS) $(CXXFLAGS)\nexport _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \\\n\t\t   $(LDFLAGS) -lsqlite3 -lstdc++\n\nciphersossl = zrtp/srtp/crypto/openssl/SrtpSymCrypto.o \\\n    \t      zrtp/srtp/crypto/openssl/hmac.o \\\n\t      zrtp/zrtp/crypto/openssl/zrtpDH.o \\\n\t      zrtp/zrtp/crypto/openssl/hmac256.o \\\n\t      zrtp/zrtp/crypto/openssl/sha256.o \\\n\t      zrtp/zrtp/crypto/openssl/hmac384.o \\\n\t      zrtp/zrtp/crypto/openssl/sha384.o \\\n\t      zrtp/zrtp/crypto/openssl/aesCFB.o\n\nskeinmac = zrtp/cryptcommon/skein.o \\\n\t   zrtp/cryptcommon/skein_block.o \\\n\t   zrtp/cryptcommon/skeinApi.o \\\n    \t   zrtp/cryptcommon/macSkein.o \\\n\t   zrtp/zrtp/crypto/skein256.o \\\n\t   zrtp/zrtp/crypto/skein384.o \\\n\t   zrtp/zrtp/crypto/skeinMac256.o \\\n\t   zrtp/zrtp/crypto/skeinMac384.o\n\ntwofish = zrtp/cryptcommon/twofish.o \\\n\t  zrtp/cryptcommon/twofish_cfb.o \\\n\t  zrtp/zrtp/crypto/twoCFB.o\n\ncommon = zrtp/common/osSpecifics.o\n\n# Gcrypt support currently not tested\n#ciphersgcrypt = crypto/gcrypt/gcryptAesSrtp.o crypto/gcrypt/gcrypthmac.o \\\n#          crypto/gcrypt/InitializeGcrypt.o\n\nzrtpobj = zrtp/zrtp/ZrtpCallbackWrapper.o \\\n          zrtp/zrtp/ZIDCacheDb.o \\\n          zrtp/zrtp/ZIDRecordDb.o \\\n          zrtp/zrtp/zrtpCacheSqliteBackend.o \\\n          zrtp/zrtp/ZRtp.o \\\n          zrtp/zrtp/ZrtpCrc32.o \\\n          zrtp/zrtp/ZrtpPacketCommit.o \\\n          zrtp/zrtp/ZrtpPacketConf2Ack.o \\\n          zrtp/zrtp/ZrtpPacketConfirm.o \\\n          zrtp/zrtp/ZrtpPacketDHPart.o \\\n          zrtp/zrtp/ZrtpPacketGoClear.o \\\n          zrtp/zrtp/ZrtpPacketClearAck.o \\\n          zrtp/zrtp/ZrtpPacketHelloAck.o \\\n          zrtp/zrtp/ZrtpPacketHello.o \\\n          zrtp/zrtp/ZrtpPacketError.o \\\n          zrtp/zrtp/ZrtpPacketErrorAck.o \\\n          zrtp/zrtp/ZrtpPacketPingAck.o \\\n          zrtp/zrtp/ZrtpPacketPing.o \\\n          zrtp/zrtp/ZrtpPacketSASrelay.o \\\n          zrtp/zrtp/ZrtpPacketRelayAck.o \\\n          zrtp/zrtp/ZrtpStateClass.o \\\n          zrtp/zrtp/ZrtpTextData.o \\\n          zrtp/zrtp/ZrtpConfigure.o \\\n          zrtp/zrtp/ZrtpCWrapper.o \\\n          zrtp/zrtp/Base32.o \\\n          zrtp/zrtp/zrtpB64Encode.o \\\n          zrtp/zrtp/zrtpB64Decode.o\n\nsrtpobj = srtp/ZsrtpCWrapper.o \\\n\t  zrtp/srtp/CryptoContext.o \\\n\t  zrtp/srtp/CryptoContextCtrl.o\n\ncryptobj =  $(ciphersossl) $(skeinmac) $(twofish)\n\nexport ZSRTP_SRCDIR = ../../zsrtp\nexport ZSRTP_OBJS = $(zrtpobj) $(cryptobj) $(srtpobj) $(common)\nexport ZSRTP_CFLAGS = $(_CFLAGS)\nexport ZSRTP_CXXFLAGS = $(_CXXFLAGS)\n\n\nexport CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT\n###############################################################################\n# Main entry\n#\n# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.\n#\nTARGETS := libzsrtp\n\nall: $(TARGETS)\n\ndoc:\n\tcd .. && doxygen docs/doxygen.cfg\n\ndep: depend\ndistclean: realclean\n\n.PHONY: dep depend libzsrtp clean realclean distclean\n\nlibzsrtp:\n\t$(MAKE) -f $(RULES_MAK) APP=ZSRTP app=libzsrtp $(ZSRTP_LIB)\n\nclean print_lib:\n\t$(MAKE) -f $(RULES_MAK) APP=ZSRTP app=libzsrtp $@\n\nrealclean:\n\t$(subst @@,$(subst /,$(HOST_PSEP),.ilbc-$(TARGET_NAME).depend),$(HOST_RMR))\n\t$(MAKE) -f $(RULES_MAK) APP=ZSRTP app=libzsrtp $@\n\ndepend:\n\t$(MAKE) -f $(RULES_MAK) APP=ZSRTP app=libzsrtp $@\n\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/common/basic_op.c",
    "content": "#include \"config.h\"\n\n#if !PJMEDIA_LIBG7221_FUNCS_INLINED || \\\n    (PJMEDIA_LIBG7221_FUNCS_INLINED && defined(__BASIC_OP_H__))\n\n/*___________________________________________________________________________\n |                                                                           |\n | Basic arithmetic operators.                                               |\n |___________________________________________________________________________|\n*/\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Include-Files                                                           |\n |___________________________________________________________________________|\n*/\n\n//#include <stdio.h>\n//#include <stdlib.h>\n#include \"typedef.h\"\n#include \"basic_op.h\"\n#include <pj/assert.h>\n\n#if (WMOPS)\n#include \"count.h\"\nextern BASIC_OP multiCounter[MAXCOUNTERS];\nextern int currCounter;\n\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Constants and Globals                                                   |\n |___________________________________________________________________________|\n*/\n#if INCLUDE_UNSAFE\nFlag g7221_Overflow = 0;\nFlag g7221_Carry = 0;\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Functions                                                               |\n |___________________________________________________________________________|\n*/\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : shr                                                     |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Arithmetically shift the 16 bit input var1 right var2 positions with    |\n |   sign extension. If var2 is negative, arithmetically shift var1 left by  |\n |   -var2 with sign extension. Saturate the result in case of underflows or |\n |   overflows.                                                              |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word16) shr (Word16 var1, Word16 var2)\n{\n    if (var2 < 0)\n    {\n        if (var2 < -16)\n            var2 = -16;\n        return shl_nocheck(var1, (Word16) -var2);\n    }\n    else\n    {\n        return shr_nocheck(var1, var2);\n    }\n}\n/* ------------------------- End of shr() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : shl                                                     |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill|\n |   the var2 LSB of the result. If var2 is negative, arithmetically shift   |\n |   var1 right by -var2 with sign extension. Saturate the result in case of |\n |   underflows or overflows.                                                |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word16) shl (Word16 var1, Word16 var2)\n{\n    if (var2 < 0)\n    {\n        return shr_nocheck(var1, (Word16) -var2);\n    }\n    else\n    {\n        return shl_nocheck(var1, var2);\n    }\n}\n/* ------------------------- End of shl() ------------------------- */\n\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : mult                                                    |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |    Performs the multiplication of var1 by var2 and gives a 16 bit result  |\n |    which is scaled i.e.:                                                  |\n |             mult(var1,var2) = extract_l(L_shr((var1 times var2),15)) and  |\n |             mult(-32768,-32768) = 32767.                                  |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word16) mult (Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n    Word32 L_product;\n\n    L_product = (Word32) var1 *(Word32) var2;\n\n    L_product = (L_product & (Word32) 0xffff8000L) >> 15;\n\n    if (L_product & (Word32) 0x00010000L)\n        L_product = L_product | (Word32) 0xffff0000L;\n\n    var_out = saturate (L_product);\n#if (WMOPS)\n    multiCounter[currCounter].mult++;\n#endif\n    return (var_out);\n}\n/* ------------------------- End of mult() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_msu                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Multiply var1 by var2 and shift the result left by 1. Subtract the 32   |\n |   bit result to L_var3 with saturation, return a 32 bit result:           |\n |        L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)).         |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word32) L_msu (Word32 L_var3, Word16 var1, Word16 var2)\n{\n    Word32 L_var_out;\n    Word32 L_product;\n\n    L_product = L_mult (var1, var2);\n#if (WMOPS)\n    multiCounter[currCounter].L_mult--;\n#endif\n    L_var_out = L_sub (L_var3, L_product);\n#if (WMOPS)\n    multiCounter[currCounter].L_sub--;\n    multiCounter[currCounter].L_msu++;\n#endif\n    return (L_var_out);\n}\n/* ------------------------- End of L_msu() ------------------------- */\n\n#if INCLUDE_UNSAFE\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_macNs                                                 |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Multiply var1 by var2 and shift the result left by 1. Add the 32 bit    |\n |   result to L_var3 without saturation, return a 32 bit result. Generate   |\n |   carry and overflow values :                                             |\n |        L_macNs(L_var3,var1,var2) = L_add_c(L_var3,L_mult(var1,var2)).     |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |                                                                           |\n |   Caution :                                                               |\n |                                                                           |\n |    In some cases the Carry flag has to be cleared or set before using     |\n |    operators which take into account its value.                           |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word32) L_macNs (Word32 L_var3, Word16 var1, Word16 var2)\n{\n    Word32 L_var_out;\n\n    L_var_out = L_mult (var1, var2);\n#if (WMOPS)\n    multiCounter[currCounter].L_mult--;\n#endif\n    L_var_out = L_add_c (L_var3, L_var_out);\n#if (WMOPS)\n    multiCounter[currCounter].L_add_c--;\n    multiCounter[currCounter].L_macNs++;\n#endif\n    return (L_var_out);\n}\n#endif\n/* ------------------------- End of L_macNs() ------------------------- */\n\n#if INCLUDE_UNSAFE\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_msuNs                                                 |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Multiply var1 by var2 and shift the result left by 1. Subtract the 32   |\n |   bit result from L_var3 without saturation, return a 32 bit result. Ge-  |\n |   nerate carry and overflow values :                                      |\n |        L_msuNs(L_var3,var1,var2) = L_sub_c(L_var3,L_mult(var1,var2)).     |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |                                                                           |\n |   Caution :                                                               |\n |                                                                           |\n |    In some cases the Carry flag has to be cleared or set before using     |\n |    operators which take into account its value.                           |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word32) L_msuNs (Word32 L_var3, Word16 var1, Word16 var2)\n{\n    Word32 L_var_out;\n\n    L_var_out = L_mult (var1, var2);\n#if (WMOPS)\n    multiCounter[currCounter].L_mult--;\n#endif\n    L_var_out = L_sub_c (L_var3, L_var_out);\n#if (WMOPS)\n    multiCounter[currCounter].L_sub_c--;\n    multiCounter[currCounter].L_msuNs++;\n#endif\n    return (L_var_out);\n}\n#endif\n\n/* ------------------------- End of L_msuNs() ------------------------- */\n\n\n#if INCLUDE_UNSAFE\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_add_c                                                 |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Performs 32 bits addition of the two 32 bits variables (L_var1+L_var2+C)|\n |   with carry. No saturation. Generate carry and Overflow values. The car- |\n |   ry and overflow values are binary variables which can be tested and as- |\n |   signed values.                                                          |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |                                                                           |\n |   Caution :                                                               |\n |                                                                           |\n |    In some cases the Carry flag has to be cleared or set before using     |\n |    operators which take into account its value.                           |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word32) L_add_c (Word32 L_var1, Word32 L_var2)\n{\n    Word32 L_var_out;\n    Word32 L_test;\n    Flag carry_int = 0;\n\n    L_var_out = L_var1 + L_var2 + GET_CARRY();\n\n    L_test = L_var1 + L_var2;\n\n    if ((L_var1 > 0) && (L_var2 > 0) && (L_test < 0))\n    {\n        SET_OVERFLOW(1);\n        carry_int = 0;\n    }\n    else\n    {\n        if ((L_var1 < 0) && (L_var2 < 0))\n        {\n            if (L_test >= 0)\n\t    {\n                SET_OVERFLOW(1);\n                carry_int = 1;\n\t    }\n            else\n\t    {\n                SET_OVERFLOW(0);\n                carry_int = 1;\n\t    }\n        }\n        else\n        {\n            if (((L_var1 ^ L_var2) < 0) && (L_test >= 0))\n            {\n                SET_OVERFLOW(0);\n                carry_int = 1;\n            }\n            else\n            {\n                SET_OVERFLOW(0);\n                carry_int = 0;\n            }\n        }\n    }\n\n    if (GET_CARRY())\n    {\n        if (L_test == MAX_32)\n        {\n            SET_OVERFLOW(1);\n            SET_CARRY(carry_int);\n        }\n        else\n        {\n            if (L_test == (Word32) 0xFFFFFFFFL)\n            {\n                SET_CARRY(1);\n            }\n            else\n            {\n                SET_CARRY(carry_int);\n            }\n        }\n    }\n    else\n    {\n        SET_CARRY(carry_int);\n    }\n\n#if (WMOPS)\n    multiCounter[currCounter].L_add_c++;\n#endif\n    return (L_var_out);\n}\n#endif\n\n/* ------------------------- End of L_add_c() ------------------------- */\n\n#if INCLUDE_UNSAFE\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_sub_c                                                 |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Performs 32 bits subtraction of the two 32 bits variables with carry    |\n |   (borrow) : L_var1-L_var2-C. No saturation. Generate carry and Overflow  |\n |   values. The carry and overflow values are binary variables which can    |\n |   be tested and assigned values.                                          |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |                                                                           |\n |   Caution :                                                               |\n |                                                                           |\n |    In some cases the Carry flag has to be cleared or set before using     |\n |    operators which take into account its value.                           |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word32) L_sub_c (Word32 L_var1, Word32 L_var2)\n{\n    Word32 L_var_out;\n    Word32 L_test;\n    Flag carry_int = 0;\n\n    if (GET_CARRY())\n    {\n        SET_CARRY(0);\n        if (L_var2 != MIN_32)\n        {\n            L_var_out = L_add_c (L_var1, -L_var2);\n#if (WMOPS)\n            multiCounter[currCounter].L_add_c--;\n#endif\n        }\n        else\n        {\n            L_var_out = L_var1 - L_var2;\n            if (L_var1 > 0L)\n            {\n                SET_OVERFLOW(1);\n                SET_CARRY(0);\n            }\n        }\n    }\n    else\n    {\n        L_var_out = L_var1 - L_var2 - (Word32) 0X00000001L;\n        L_test = L_var1 - L_var2;\n\n        if ((L_test < 0) && (L_var1 > 0) && (L_var2 < 0))\n        {\n            SET_OVERFLOW(1);\n            carry_int = 0;\n        }\n        else if ((L_test > 0) && (L_var1 < 0) && (L_var2 > 0))\n        {\n            SET_OVERFLOW(1);\n            carry_int = 1;\n        }\n        else if ((L_test > 0) && ((L_var1 ^ L_var2) > 0))\n        {\n            SET_OVERFLOW(0);\n            carry_int = 1;\n        }\n        if (L_test == MIN_32)\n        {\n            SET_OVERFLOW(1);\n            SET_CARRY(carry_int);\n        }\n        else\n        {\n            SET_CARRY(carry_int);\n        }\n    }\n\n#if (WMOPS)\n    multiCounter[currCounter].L_sub_c++;\n#endif\n    return (L_var_out);\n}\n#endif\n/* ------------------------- End of L_sub_c() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_negate                                                |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Negate the 32 bit variable L_var1 with saturation; saturate in the case |\n |   where input is -2147483648 (0x8000 0000).                               |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word32) L_negate (Word32 L_var1)\n{\n    Word32 L_var_out;\n\n    L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1;\n#if (WMOPS)\n    multiCounter[currCounter].L_negate++;\n#endif\n    return (L_var_out);\n}\n/* ------------------------- End of L_negate() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : mult_r                                                  |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Same as mult with rounding, i.e.:                                       |\n |     mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and  |\n |     mult_r(-32768,-32768) = 32767.                                        |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word16) mult_r (Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n    Word32 L_product_arr;\n\n    L_product_arr = (Word32) var1 *(Word32) var2;       /* product */\n    L_product_arr += (Word32) 0x00004000L;      /* round */\n    L_product_arr &= (Word32) 0xffff8000L;\n    L_product_arr >>= 15;       /* shift */\n\n    if (L_product_arr & (Word32) 0x00010000L)   /* sign extend when necessary */\n    {\n        L_product_arr |= (Word32) 0xffff0000L;\n    }\n    var_out = saturate (L_product_arr);\n#if (WMOPS)\n    multiCounter[currCounter].mult_r++;\n#endif\n    return (var_out);\n}\n/* ------------------------- End of mult_r() ------------------------- */\n\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : shr_r                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Same as shr(var1,var2) but with rounding. Saturate the result in case of|\n |   underflows or overflows :                                               |\n |    - If var2 is greater than zero :                                       |\n |          if (sub(shl(shr(var1,var2),1),shr(var1,sub(var2,1))))            |\n |          is equal to zero                                                 |\n |                     then                                                  |\n |                     shr_r(var1,var2) = shr(var1,var2)                     |\n |                     else                                                  |\n |                     shr_r(var1,var2) = add(shr(var1,var2),1)              |\n |    - If var2 is less than or equal to zero :                              |\n |                     shr_r(var1,var2) = shr(var1,var2).                    |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word16) shr_r (Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n\n    if (var2 > 15)\n    {\n        var_out = 0;\n    }\n    else\n    {\n        var_out = shr (var1, var2);\n#if (WMOPS)\n        multiCounter[currCounter].shr--;\n#endif\n\n        if (var2 > 0)\n        {\n            if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)\n            {\n                var_out++;\n            }\n        }\n    }\n#if (WMOPS)\n    multiCounter[currCounter].shr_r++;\n#endif\n    return (var_out);\n}\n/* ------------------------- End of shr_r() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : mac_r                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Multiply var1 by var2 and shift the result left by 1. Add the 32 bit    |\n |   result to L_var3 with saturation. Round the LS 16 bits of the result    |\n |   into the MS 16 bits with saturation and shift the result right by 16.   |\n |   Return a 16 bit result.                                                 |\n |            mac_r(L_var3,var1,var2) = round(L_mac(L_var3,var1,var2))       |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 8000 <= L_var_out <= 0x0000 7fff.              |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word16) mac_r (Word32 L_var3, Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n\n    L_var3 = L_mac (L_var3, var1, var2);\n#if (WMOPS)\n    multiCounter[currCounter].L_mac--;\n#endif\n    L_var3 = L_add (L_var3, (Word32) 0x00008000L);\n#if (WMOPS)\n    multiCounter[currCounter].L_add--;\n#endif\n    var_out = extract_h (L_var3);\n#if (WMOPS)\n    multiCounter[currCounter].extract_h--;\n    multiCounter[currCounter].mac_r++;\n#endif\n    return (var_out);\n}\n/* ------------------------- End of mac_r() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : msu_r                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Multiply var1 by var2 and shift the result left by 1. Subtract the 32   |\n |   bit result to L_var3 with saturation. Round the LS 16 bits of the res-  |\n |   ult into the MS 16 bits with saturation and shift the result right by   |\n |   16. Return a 16 bit result.                                             |\n |            msu_r(L_var3,var1,var2) = round(L_msu(L_var3,var1,var2))       |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 8000 <= L_var_out <= 0x0000 7fff.              |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word16) msu_r (Word32 L_var3, Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n\n    L_var3 = L_msu (L_var3, var1, var2);\n#if (WMOPS)\n    multiCounter[currCounter].L_msu--;\n#endif\n    L_var3 = L_add (L_var3, (Word32) 0x00008000L);\n#if (WMOPS)\n    multiCounter[currCounter].L_add--;\n#endif\n    var_out = extract_h (L_var3);\n#if (WMOPS)\n    multiCounter[currCounter].extract_h--;\n    multiCounter[currCounter].msu_r++;\n#endif\n    return (var_out);\n}\n/* ------------------------- End of msu_r() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_deposit_h                                             |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Deposit the 16 bit var1 into the 16 MS bits of the 32 bit output. The   |\n |   16 LS bits of the output are zeroed.                                    |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= var_out <= 0x7fff 0000.                |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word32) L_deposit_h (Word16 var1)\n{\n    Word32 L_var_out;\n\n    L_var_out = (Word32) var1 << 16;\n#if (WMOPS)\n    multiCounter[currCounter].L_deposit_h++;\n#endif\n    return (L_var_out);\n}\n/* ------------------------- End of L_deposit_h() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_deposit_l                                             |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The   |\n |   16 MS bits of the output are sign extended.                             |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0xFFFF 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word32) L_deposit_l (Word16 var1)\n{\n    Word32 L_var_out;\n\n    L_var_out = (Word32) var1;\n#if (WMOPS)\n    multiCounter[currCounter].L_deposit_l++;\n#endif\n    return (L_var_out);\n}\n/* ------------------------- End of L_deposit_l() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_shr_r                                                 |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Same as L_shr(L_var1,var2) but with rounding. Saturate the result in    |\n |   case of underflows or overflows :                                       |\n |    - If var2 is greater than zero :                                       |\n |          if (L_sub(L_shl(L_shr(L_var1,var2),1),L_shr(L_var1,sub(var2,1))))|\n |          is equal to zero                                                 |\n |                     then                                                  |\n |                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2)             |\n |                     else                                                  |\n |                     L_shr_r(L_var1,var2) = L_add(L_shr(L_var1,var2),1)    |\n |    - If var2 is less than or equal to zero :                              |\n |                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2).            |\n |                                                                           |\n |   Complexity weight : 3                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= var_out <= 0x7fff ffff.                |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word32) L_shr_r (Word32 L_var1, Word16 var2)\n{\n    Word32 L_var_out;\n\n    if (var2 > 31)\n    {\n        L_var_out = 0;\n    }\n    else\n    {\n        L_var_out = L_shr (L_var1, var2);\n#if (WMOPS)\n        multiCounter[currCounter].L_shr--;\n#endif\n        if (var2 > 0)\n        {\n            if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)\n            {\n                L_var_out++;\n            }\n        }\n    }\n#if (WMOPS)\n    multiCounter[currCounter].L_shr_r++;\n#endif\n    return (L_var_out);\n}\n/* ------------------------- End of L_shr_r() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_abs                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |    Absolute value of L_var1; Saturate in case where the input is          |\n |                                                               -214783648  |\n |                                                                           |\n |   Complexity weight : 3                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x0000 0000 <= var_out <= 0x7fff ffff.                |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word32) L_abs (Word32 L_var1)\n{\n    Word32 L_var_out;\n\n    if (L_var1 == MIN_32)\n    {\n        L_var_out = MAX_32;\n    }\n    else\n    {\n        if (L_var1 < 0)\n        {\n            L_var_out = -L_var1;\n        }\n        else\n        {\n            L_var_out = L_var1;\n        }\n    }\n\n#if (WMOPS)\n    multiCounter[currCounter].L_abs++;\n#endif\n    return (L_var_out);\n}\n/* ------------------------- End of L_abs() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : norm_s                                                  |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Produces the number of left shift needed to normalize the 16 bit varia- |\n |   ble var1 for positive values on the interval with minimum of 16384 and  |\n |   maximum of 32767, and for negative values on the interval with minimum  |\n |   of -32768 and maximum of -16384; in order to normalize the result, the  |\n |   following operation must be done :                                      |\n |                    norm_var1 = shl(var1,norm_s(var1)).                    |\n |                                                                           |\n |   Complexity weight : 15                                                  |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 0000 <= var_out <= 0x0000 000f.                |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word16) norm_s (Word16 var1)\n{\n    Word16 var_out;\n\n    if (var1 == 0)\n    {\n        var_out = 0;\n    }\n    else\n    {\n        if ((UWord16)var1 == (UWord16)0xffff)\n        {\n            var_out = 15;\n        }\n        else\n        {\n            if (var1 < 0)\n            {\n                var1 = (Word16)(~var1);\n            }\n            for (var_out = 0; var1 < 0x4000; var_out++)\n            {\n                var1 <<= 1;\n            }\n        }\n    }\n\n#if (WMOPS)\n    multiCounter[currCounter].norm_s++;\n#endif\n    return (var_out);\n}\n/* ------------------------- End of norm_s() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : div_s                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Produces a result which is the fractional integer division of var1  by  |\n |   var2; var1 and var2 must be positive and var2 must be greater or equal  |\n |   to var1; the result is positive (leading bit equal to 0) and truncated  |\n |   to 16 bits.                                                             |\n |   If var1 = var2 then div(var1,var2) = 32767.                             |\n |                                                                           |\n |   Complexity weight : 18                                                  |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 0000 <= var1 <= var2 and var2 != 0.            |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : var1 <= var2 <= 0x0000 7fff and var2 != 0.            |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 0000 <= var_out <= 0x0000 7fff.                |\n |             It's a Q15 value (point between b15 and b14).                 |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word16) div_s (Word16 var1, Word16 var2)\n{\n    Word16 var_out = 0;\n    Word16 iteration;\n    Word32 L_num;\n    Word32 L_denom;\n\n    if ((var1 > var2) || (var1 < 0) || (var2 < 0))\n    {\n        //printf (\"Division Error var1=%d  var2=%d\\n\", var1, var2);\n        //abort(); /* exit (0); */\n\tpj_assert(!\"Division Error\");\n    }\n    if (var2 == 0)\n    {\n        //printf (\"Division by 0, Fatal error \\n\");\n        //abort(); /* exit (0); */\n\tassert(!\"Division by 0\");\n    }\n    if (var1 == 0)\n    {\n        var_out = 0;\n    }\n    else\n    {\n        if (var1 == var2)\n        {\n            var_out = MAX_16;\n        }\n        else\n        {\n            L_num = L_deposit_l (var1);\n#if (WMOPS)\n            multiCounter[currCounter].L_deposit_l--;\n#endif\n            L_denom = L_deposit_l (var2);\n#if (WMOPS)\n            multiCounter[currCounter].L_deposit_l--;\n#endif\n\n            for (iteration = 0; iteration < 15; iteration++)\n            {\n                var_out <<= 1;\n                L_num <<= 1;\n\n                if (L_num >= L_denom)\n                {\n                    L_num = L_sub (L_num, L_denom);\n#if (WMOPS)\n                    multiCounter[currCounter].L_sub--;\n#endif\n                    var_out = add (var_out, 1);\n#if (WMOPS)\n                    multiCounter[currCounter].add--;\n#endif\n                }\n            }\n        }\n    }\n\n#if (WMOPS)\n    multiCounter[currCounter].div_s++;\n#endif\n    return (var_out);\n}\n/* ------------------------- End of div_s() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : norm_l                                                  |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Produces the number of left shifts needed to normalize the 32 bit varia-|\n |   ble L_var1 for positive values on the interval with minimum of          |\n |   1073741824 and maximum of 2147483647, and for negative values on the in-|\n |   terval with minimum of -2147483648 and maximum of -1073741824; in order |\n |   to normalize the result, the following operation must be done :         |\n |                   norm_L_var1 = L_shl(L_var1,norm_l(L_var1)).             |\n |                                                                           |\n |   Complexity weight : 30                                                  |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 0000 <= var_out <= 0x0000 001f.                |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word16) norm_l (Word32 L_var1)\n{\n    Word16 var_out;\n\n    if (L_var1 == 0)\n    {\n        var_out = 0;\n    }\n    else\n    {\n        if (L_var1 == (Word32) 0xffffffffL)\n        {\n            var_out = 31;\n        }\n        else\n        {\n            if (L_var1 < 0)\n            {\n                L_var1 = ~L_var1;\n            }\n            for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)\n            {\n                L_var1 <<= 1;\n            }\n        }\n    }\n\n#if (WMOPS)\n    multiCounter[currCounter].norm_l++;\n#endif\n    return (var_out);\n}\n/* ------------------------- End of norm_l() ------------------------- */\n\n\n/*\n  *****************************************************************\n   Additional operators extracted from the G.723.1 Library\n   Adapted for WMOPS calculations\n  *****************************************************************\n*/\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_mls                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Multiplies a 16 bit word v by a 32 bit word Lv and returns a 32 bit     |\n |   word (multiplying 16 by 32 bit words gives 48 bit word; the function    |\n |   extracts the 32 MSB and shift the result to the left by 1).             |\n |                                                                           |\n |   A 32 bit word can be written as                                         |\n |    Lv = a  +  b * 2^16                                                    |\n |   where a= unsigned 16 LSBs and b= signed 16 MSBs.                        |\n |   The function returns v * Lv  /  2^15  which is equivalent to            |\n |        a*v / 2^15 + b*v*2                                                 |\n |                                                                           |\n |   Complexity weight : 6 [to be confirmed]                                 |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |   Lv                                                                      |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |\n |   v                                                                       |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x8000 <= var1 <= 0x7fff.                             |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= var_out <= 0x7fff ffff.                |\n |                                                                           |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word32) L_mls (Word32 Lv, Word16 v)\n{\n   Word32   Temp  ;\n\n   Temp = Lv & (Word32) 0x0000ffff ;\n   Temp = Temp * (Word32) v ;\n   Temp = L_shr_nocheck( Temp, (Word16) 15 ) ;\n   Temp = L_mac( Temp, v, extract_h(Lv) ) ;\n\n#if (WMOPS)\n   multiCounter[currCounter].L_shr--;\n   multiCounter[currCounter].L_mac--;\n   multiCounter[currCounter].extract_h--;\n   multiCounter[currCounter].L_mls++;\n#endif\n\n   return Temp ;\n}\n/* ------------------------- End of L_mls() ------------------------- */\n\n\n/*__________________________________________________________________________\n|                                                                           |\n|   Function Name : div_l                                                   |\n|                                                                           |\n|   Purpose :                                                               |\n|                                                                           |\n|   Produces a result which is the fractional integer division of L_var1 by|\n|   var2; L_var1 and var2 must be positive and var2 << 16 must be greater or|\n|   equal to L_var1; the result is positive (leading bit equal to 0) and    |\n|   truncated to 16 bits.                                                   |\n|   If L_var1 == var2 << 16 then div_l(L_var1,var2) = 32767.                |\n|                                                                           |\n|   Complexity weight : 20                                                  |\n|                                                                           |\n|   Inputs :                                                                |\n|                                                                           |\n|    L_var1                                                                 |\n|             32 bit long signed integer (Word32) whose value falls in the  |\n|             range : 0x0000 0000 <= var1 <= (var2 << 16)  and var2 != 0.   |\n|             L_var1 must be considered as a Q.31 value                     |\n|                                                                           |\n|    var2                                                                   |\n|             16 bit short signed integer (Word16) whose value falls in the |\n|             range : var1 <= (var2<< 16) <= 0x7fff0000 and var2 != 0.      |\n|             var2 must be considered as a Q.15 value                       |\n|                                                                           |\n|   Outputs :                                                               |\n|                                                                           |\n|    none                                                                   |\n|                                                                           |\n|   Return Value :                                                          |\n|                                                                           |\n|    var_out                                                                |\n|             16 bit short signed integer (Word16) whose value falls in the |\n|             range : 0x0000 0000 <= var_out <= 0x0000 7fff.                |\n|             It's a Q15 value (point between b15 and b14).                 |\n|___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word16) div_l (Word32  L_num, Word16 den)\n{\n    Word16   var_out = (Word16)0;\n    Word32   L_den;\n    Word16   iteration;\n\n#if (WMOPS)\n    multiCounter[currCounter].div_l++;\n#endif\n\n    if ( den == (Word16) 0 ) {\n        //printf(\"Division by 0 in div_l, Fatal error \\n\");\n        //exit(0);\n\tassert(!\"Division by 0\");\n    }\n\n    if ( (L_num < (Word32) 0) || (den < (Word16) 0) ) {\n        //printf(\"Division Error in div_l, Fatal error \\n\");\n        //exit(0);\n\tassert(!\"Division Error\");\n    }\n\n    L_den = L_deposit_h( den ) ;\n#if (WMOPS)\n    multiCounter[currCounter].L_deposit_h--;\n#endif\n\n    if ( L_num >= L_den ){\n        return MAX_16 ;\n    }\n    else {\n        L_num = L_shr_nocheck(L_num, (Word16)1) ;\n        L_den = L_shr_nocheck(L_den, (Word16)1);\n#if (WMOPS)\n        multiCounter[currCounter].L_shr-=2;\n#endif\n        for(iteration=(Word16)0; iteration< (Word16)15;iteration++) {\n            var_out = shl_nocheck( var_out, (Word16)1);\n            L_num   = L_shl_nocheck( L_num, (Word16)1);\n#if (WMOPS)\n            multiCounter[currCounter].shl--;\n            multiCounter[currCounter].L_shl--;\n#endif\n            if (L_num >= L_den) {\n                L_num = L_sub(L_num,L_den);\n                var_out = add(var_out, (Word16)1);\n#if (WMOPS)\n            multiCounter[currCounter].L_sub--;\n            multiCounter[currCounter].add--;\n#endif\n            }\n        }\n\n        return var_out;\n    }\n}\n/* ------------------------- End of div_l() ------------------------- */\n\n\n/*__________________________________________________________________________\n|                                                                           |\n|   Function Name : i_mult                                                  |\n|                                                                           |\n|   Purpose :                                                               |\n|                                                                           |\n|   Integer 16-bit multiplication. No overflow protection is performed if   |\n|   ORIGINAL_G7231 is defined.                                              |\n|                                                                           |\n|   Complexity weight : TBD                                                 |\n|                                                                           |\n|   Inputs :                                                                |\n|                                                                           |\n|    a                                                                      |\n|             16 bit short signed integer (Word16).                         |\n|                                                                           |\n|    b                                                                      |\n|             16 bit short signed integer (Word16).                         |\n|                                                                           |\n|   Outputs :                                                               |\n|                                                                           |\n|    none                                                                   |\n|                                                                           |\n|   Return Value :                                                          |\n|                                                                           |\n|             16 bit short signed integer (Word16). No overflow checks      |\n|             are performed if ORIGINAL_G7231 is defined.                   |\n|___________________________________________________________________________|\n*/\nLIBG7221_DEF(Word16) i_mult (Word16 a, Word16 b)\n{\n#ifdef ORIGINAL_G7231\n   return a*b ;\n#else\n   Word32 register c=a*b;\n#if (WMOPS)\n    multiCounter[currCounter].i_mult++;\n#endif\n   return saturate(c) ;\n#endif\n}\n/* ------------------------- End of i_mult() ------------------------- */\n\n\n/*\n   ********************************************************************** \n   The following three operators are not part of the original \n   G.729/G.723.1 set of basic operators and implement shiftless\n   accumulation operation.\n   ********************************************************************** \n*/\n\n/*___________________________________________________________________________\n |\n |   Function Name : L_mult0\n |\n |   Purpose :\n |\n |   L_mult0 is the 32 bit result of the multiplication of var1 times var2\n |   without one left shift.\n |\n |   Complexity weight : 1\n |\n |   Inputs :\n |\n |    var1     16 bit short signed integer (Word16) whose value falls in the\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.\n |\n |    var2     16 bit short signed integer (Word16) whose value falls in the\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.\n |\n |   Return Value :\n |\n |    L_var_out\n |             32 bit long signed integer (Word32) whose value falls in the\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.\n |___________________________________________________________________________\n*/\nLIBG7221_DEF(Word32) L_mult0 (Word16 var1,Word16 var2)\n{\n  Word32 L_var_out;\n\n  L_var_out = (Word32)var1 * (Word32)var2;\n\n#if (WMOPS)\n    multiCounter[currCounter].L_mult0++;\n#endif\n  return(L_var_out);\n}\n/* ------------------------- End of L_mult0() ------------------------- */\n\n\n/*___________________________________________________________________________\n |\n |   Function Name : L_mac0\n |\n |   Purpose :\n |\n |   Multiply var1 by var2 (without left shift) and add the 32 bit result to\n |   L_var3 with saturation, return a 32 bit result:\n |        L_mac0(L_var3,var1,var2) = L_add(L_var3,(L_mult0(var1,var2)).\n |\n |   Complexity weight : 1\n |\n |   Inputs :\n |\n |    L_var3   32 bit long signed integer (Word32) whose value falls in the\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.\n |\n |    var1     16 bit short signed integer (Word16) whose value falls in the\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.\n |\n |    var2     16 bit short signed integer (Word16) whose value falls in the\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.\n |\n |   Return Value :\n |\n |    L_var_out\n |             32 bit long signed integer (Word32) whose value falls in the\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.\n |___________________________________________________________________________\n*/\nLIBG7221_DEF(Word32) L_mac0 (Word32 L_var3, Word16 var1, Word16 var2)\n{\n  Word32 L_var_out;\n  Word32 L_product;\n\n  L_product = L_mult0(var1,var2);\n  L_var_out = L_add(L_var3,L_product);\n\n#if (WMOPS)\n    multiCounter[currCounter].L_mac0++;\n    multiCounter[currCounter].L_mult0--;\n    multiCounter[currCounter].L_add--;\n#endif\n  return(L_var_out);\n}\n/* ------------------------- End of L_mac0() ------------------------- */\n\n\n/*___________________________________________________________________________\n |\n |   Function Name : L_msu0\n |\n |   Purpose :\n |\n |   Multiply var1 by var2 (without left shift) and subtract the 32 bit\n |   result to L_var3 with saturation, return a 32 bit result:\n |        L_msu0(L_var3,var1,var2) = L_sub(L_var3,(L_mult0(var1,var2)).\n |\n |   Complexity weight : 1\n |\n |   Inputs :\n |\n |    L_var3   32 bit long signed integer (Word32) whose value falls in the\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.\n |\n |    var1     16 bit short signed integer (Word16) whose value falls in the\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.\n |\n |    var2     16 bit short signed integer (Word16) whose value falls in the\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.\n |\n |   Return Value :\n |\n |    L_var_out\n |             32 bit long signed integer (Word32) whose value falls in the\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.\n |___________________________________________________________________________\n*/\nLIBG7221_DEF(Word32) L_msu0 (Word32 L_var3, Word16 var1, Word16 var2)\n{\n  Word32 L_var_out;\n  Word32 L_product;\n\n  L_product = L_mult0(var1,var2);\n  L_var_out = L_sub(L_var3,L_product);\n\n#if (WMOPS)\n    multiCounter[currCounter].L_msu0++;\n    multiCounter[currCounter].L_mult0--;\n    multiCounter[currCounter].L_sub--;\n#endif\n  return(L_var_out);\n}\n/* ------------------------- End of L_msu0() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : LU_shl                                                  |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero  |\n |   fill the var2 LSB of the result. If var2 is negative, arithmetically    |\n |   shift L_var1 right by -var2 with sign extension. Saturate the result in |\n |   case of underflows or overflows.                                        |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(UWord32) LU_shl (UWord32 L_var1, Word16 var2)\n{\n    Word16 neg_var2;\n    UWord32 L_var_out = 0;\n\n    if (var2 <= 0)\n    {\n        if (var2 < -32)\n            var2 = -32;\n        neg_var2 = negate(var2);\n        L_var_out = LU_shr (L_var1, neg_var2);\n#if (WMOPS)\n        multiCounter[currCounter].negate--;\n        multiCounter[currCounter].LU_shr--;\n#endif\n    }\n    else\n    {\n        for (; var2 > 0; var2--)\n        {\n            if (L_var1 > (UWord32) 0X7fffffffL)\n            {\n                SET_OVERFLOW(1);\n                L_var_out = UMAX_32;\n                break;\n            }\n            else\n            {\n                if (L_var1 < (UWord32) 0x00000001L)\n                {\n                    SET_OVERFLOW(1);\n                    L_var_out = (UWord32)MIN_32;\n                    break;\n                }\n            }\n            L_var1 *= 2;\n            L_var_out = L_var1;\n        }\n    }\n#if (WMOPS)\n    multiCounter[currCounter].LU_shl++;\n#endif\n    return (L_var_out);\n}\n/* ------------------------- End of LU_shl() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : LU_shr                                                  |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Arithmetically shift the 32 bit input L_var1 right var2 positions with  |\n |   sign extension. If var2 is negative, arithmetically shift L_var1 left   |\n |   by -var2 and zero fill the -var2 LSB of the result. Saturate the result |\n |   in case of underflows or overflows.                                     |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\nLIBG7221_DEF(UWord32) LU_shr (UWord32 L_var1, Word16 var2)\n{\n    Word16  neg_var2;\n    UWord32 L_var_out;\n\n    if (var2 < 0)\n    {\n        if (var2 < -32)\n            var2 = -32;\n        neg_var2 = negate(var2);\n        L_var_out = LU_shl (L_var1, neg_var2);\n#if (WMOPS)\n        multiCounter[currCounter].negate--;\n        multiCounter[currCounter].LU_shl--;\n#endif\n    }\n    else\n    {\n        if (var2 >= 32)\n        {\n            L_var_out = 0L;\n        }\n        else\n        {\n            L_var_out = L_var1 >> var2;\n        }\n    }\n#if (WMOPS)\n    multiCounter[currCounter].LU_shr++;\n#endif\n    return (L_var_out);\n}\n/* ------------------------- End of LU_shr() ------------------------- */\n\n#endif /* PJMEDIA_LIBG7221_FUNCS_INLINED */\n\n/* ************************** END OF BASOP32.C ************************** */\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/common/basic_op.h",
    "content": "#ifndef __BASIC_OP_H__\n#define __BASIC_OP_H__\n\n#include \"config.h\"\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Constants and Globals                                                   |\n |___________________________________________________________________________|\n*/\n\n#define MAX_32 (Word32)0x7fffffffL\n#define MIN_32 (Word32)0x80000000L\n\n#define MAX_16 (Word16)0x7fff\n#define MIN_16 (Word16)(pj_uint16_t)0x8000\n\n#define UMAX_32 (UWord32)0xffffffffL\n#define UMIN_32 (UWord32)0x00000000L\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Prototypes for basic arithmetic operators                               |\n |___________________________________________________________________________|\n*/\n\nPJ_INLINE(Word16) add (Word16 var1, Word16 var2);    /* Short add,           1   */\nPJ_INLINE(Word16) sub (Word16 var1, Word16 var2);    /* Short sub,           1   */\nPJ_INLINE(Word16) abs_s (Word16 var1);               /* Short abs,           1   */\nLIBG7221_DECL(Word16) shl (Word16 var1, Word16 var2);    /* Short shift left,    1   */\nPJ_INLINE(Word16) shl_nocheck(Word16 var1, Word16 var2);\nLIBG7221_DECL(Word16) shr (Word16 var1, Word16 var2);    /* Short shift right,   1   */\nPJ_INLINE(Word16) shr_nocheck(Word16 var1, Word16 var2);\nLIBG7221_DECL(Word16) mult (Word16 var1, Word16 var2);   /* Short mult,          1   */\nPJ_INLINE(Word32) L_mult (Word16 var1, Word16 var2); /* Long mult,           1   */\nPJ_INLINE(Word16) negate (Word16 var1);              /* Short negate,        1   */\nPJ_INLINE(Word16) extract_h (Word32 L_var1);         /* Extract high,        1   */\nPJ_INLINE(Word16) extract_l (Word32 L_var1);         /* Extract low,         1   */\nPJ_INLINE(Word16) itu_round (Word32 L_var1);         /* Round,               1   */\nPJ_INLINE(Word32) L_mac (Word32 L_var3, Word16 var1, Word16 var2);   /* Mac,  1  */\nLIBG7221_DECL(Word32) L_msu (Word32 L_var3, Word16 var1, Word16 var2);   /* Msu,  1  */\nLIBG7221_DECL(Word32) L_macNs (Word32 L_var3, Word16 var1, Word16 var2); /* Mac without\n\t\t\t\t\t\t\t\t       sat, 1   */\nLIBG7221_DECL(Word32) L_msuNs (Word32 L_var3, Word16 var1, Word16 var2); /* Msu without\n\t\t\t\t\t\t\t\t       sat, 1   */\n//PJ_INLINE(Word32) L_add (Word32 L_var1, Word32 L_var2);    /* Long add,        2 */\nPJ_INLINE(Word32) L_sub (Word32 L_var1, Word32 L_var2);    /* Long sub,        2 */\nLIBG7221_DECL(Word32) L_add_c (Word32 L_var1, Word32 L_var2);  /* Long add with c, 2 */\nLIBG7221_DECL(Word32) L_sub_c (Word32 L_var1, Word32 L_var2);  /* Long sub with c, 2 */\nLIBG7221_DECL(Word32) L_negate (Word32 L_var1);                /* Long negate,     2 */\nLIBG7221_DECL(Word16) mult_r (Word16 var1, Word16 var2);       /* Mult with round, 2 */\nPJ_INLINE(Word32) L_shl (Word32 L_var1, Word16 var2);      /* Long shift left, 2 */\nPJ_INLINE(Word32) L_shr (Word32 L_var1, Word16 var2);      /* Long shift right, 2*/\nLIBG7221_DECL(Word16) shr_r (Word16 var1, Word16 var2);        /* Shift right with\n\t\t\t\t\t\t\t     round, 2           */\nLIBG7221_DECL(Word16) mac_r (Word32 L_var3, Word16 var1, Word16 var2); /* Mac with\n                                                           rounding,2 */\nLIBG7221_DECL(Word16) msu_r (Word32 L_var3, Word16 var1, Word16 var2); /* Msu with\n                                                           rounding,2 */\nLIBG7221_DECL(Word32) L_deposit_h (Word16 var1);        /* 16 bit var1 -> MSB,     2 */\nLIBG7221_DECL(Word32) L_deposit_l (Word16 var1);        /* 16 bit var1 -> LSB,     2 */\n\nLIBG7221_DECL(Word32) L_shr_r (Word32 L_var1, Word16 var2); /* Long shift right with\n\t\t\t\t\t\t\t  round,  3             */\nLIBG7221_DECL(Word32) L_abs (Word32 L_var1);            /* Long abs,              3  */\nLIBG7221_DECL(Word32) L_sat (Word32 L_var1);            /* Long saturation,       4  */\nLIBG7221_DECL(Word16) norm_s (Word16 var1);             /* Short norm,           15  */\nLIBG7221_DECL(Word16) div_s (Word16 var1, Word16 var2); /* Short division,       18  */\nLIBG7221_DECL(Word16) norm_l (Word32 L_var1);           /* Long norm,            30  */   \n\n/*\n   Additional G.723.1 operators\n*/\nLIBG7221_DECL(Word32) L_mls( Word32, Word16 ) ;    /* Weight FFS; currently assigned 1 */\nLIBG7221_DECL(Word16) div_l( Word32, Word16 ) ;    /* Weight FFS; currently assigned 1 */\nLIBG7221_DECL(Word16) i_mult(Word16 a, Word16 b);  /* Weight FFS; currently assigned 1 */\n\n/* \n    New shiftless operators, not used in G.729/G.723.1\n*/\nLIBG7221_DECL(Word32) L_mult0(Word16 v1, Word16 v2); /* 32-bit Multiply w/o shift         1 */\nLIBG7221_DECL(Word32) L_mac0(Word32 L_v3, Word16 v1, Word16 v2); /* 32-bit Mac w/o shift  1 */\nLIBG7221_DECL(Word32) L_msu0(Word32 L_v3, Word16 v1, Word16 v2); /* 32-bit Msu w/o shift  1 */\n\n/* \n    Additional G.722.1 operators\n*/\nLIBG7221_DECL(UWord32) LU_shl (UWord32 L_var1, Word16 var2);\nLIBG7221_DECL(UWord32) LU_shr (UWord32 L_var1, Word16 var2);\n\n#define INCLUDE_UNSAFE\t    0\n\n/* Local */\nPJ_INLINE(Word16) saturate (Word32 L_var1);\n\n#if INCLUDE_UNSAFE\n    extern Flag g7221_Overflow;\n    extern Flag g7221_Carry;\n#   define SET_OVERFLOW(n)  g7221_Overflow = n\n#   define SET_CARRY(n)\t    g7221_Carry = n\n\n#else\n#   define SET_OVERFLOW(n)\n#   define SET_CARRY(n)\n#   define GET_OVERFLOW()   0\n#   define GET_CARRY()\t    0\n#endif\n\n#include \"basic_op_i.h\"\n\n#if PJMEDIA_LIBG7221_FUNCS_INLINED\n#   include \"basic_op.c\"\n#endif\n\n#endif /* __BASIC_OP_H__ */\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/common/basic_op_i.h",
    "content": "/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : extract_h                                               |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Return the 16 MSB of L_var1.                                            |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32 ) whose value falls in the |\n |             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word16) extract_h (Word32 L_var1)\n{\n    return (Word16) (L_var1 >> 16);\n}\n/* ------------------------- End of extract_h() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : extract_l                                               |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Return the 16 LSB of L_var1.                                            |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32 ) whose value falls in the |\n |             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word16) extract_l (Word32 L_var1)\n{\n    return (Word16) L_var1;\n}\n\n/* ------------------------- End of extract_l() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : saturate                                                |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |    Limit the 32 bit input to the range of a 16 bit word.                  |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word16) saturate (Word32 L_var1)\n{\n    Word16 val16 = (Word16) L_var1;\n\n    if (val16 == L_var1)\n\treturn val16;\n\n    if (L_var1 > MAX_16)\n        return MAX_16;\n    return MIN_16;\n}\n/* ------------------------- End of saturate() ------------------------- */\n\n\n#if PJ_HAS_INT64\nPJ_INLINE(Word32) L_saturate (pj_int64_t LL_var1)\n{\n    pj_int32_t L_var1 = (pj_int32_t)LL_var1;\n    if (LL_var1 == L_var1)\n\treturn L_var1;\n    else if (LL_var1 > MAX_32)\n\treturn MAX_32;\n    else\n\treturn MIN_32;\n}\n#endif\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : add                                                     |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |    Performs the addition (var1+var2) with overflow control and saturation;|\n |    the 16 bit result is set at +32767 when overflow occurs or at -32768   |\n |    when underflow occurs.                                                 |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word16) add (Word16 var1, Word16 var2)\n{\n    return saturate (var1 + var2);\n}\n/* ------------------------- End of add() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : sub                                                     |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |    Performs the subtraction (var1+var2) with overflow control and satu-   |\n |    ration; the 16 bit result is set at +32767 when overflow occurs or at  |\n |    -32768 when underflow occurs.                                          |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word16) sub (Word16 var1, Word16 var2)\n{\n    return saturate ((Word32) var1 - var2);\n}\n/* ------------------------- End of sub() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : negate                                                  |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Negate var1 with saturation, saturate in the case where input is -32768:|\n |                negate(var1) = sub(0,var1).                                |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word16) negate (Word16 var1)\n{\n    return (Word16)((var1 == MIN_16) ? MAX_16 : -var1);\n}\n/* ------------------------- End of negate() ------------------------- */\n\n\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_add                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   32 bits addition of the two 32 bits variables (L_var1+L_var2) with      |\n |   overflow control and saturation; the result is set at +2147483647 when  |\n |   overflow occurs or at -2147483648 when underflow occurs.                |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word32) L_add (Word32 L_var1, Word32 L_var2)\n{\n#if PJ_HAS_INT64\n    return L_saturate(((pj_int64_t)L_var1) + L_var2);\n#else\n    Word32 L_var_out;\n\n    L_var_out = L_var1 + L_var2;\n\n    if (((L_var1 ^ L_var2) & MIN_32) == 0)\n    {\n        if ((L_var_out ^ L_var1) & MIN_32)\n        {\n            SET_OVERFLOW(1);\n            L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;\n        }\n    }\n    return (L_var_out);\n#endif\n}\n\n/* ------------------------- End of L_add() ------------------------- */\n\n\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_sub                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with   |\n |   overflow control and saturation; the result is set at +2147483647 when  |\n |   overflow occurs or at -2147483648 when underflow occurs.                |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word32) L_sub (Word32 L_var1, Word32 L_var2)\n{\n#if PJ_HAS_INT64\n    return L_saturate((pj_int64_t)L_var1 - L_var2);\n#else\n    Word32 L_var_out;\n\n    L_var_out = L_var1 - L_var2;\n\n    if (((L_var1 ^ L_var2) & MIN_32) != 0)\n    {\n        if ((L_var_out ^ L_var1) & MIN_32)\n        {\n            L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;\n            SET_OVERFLOW(1);\n        }\n    }\n    return (L_var_out);\n#endif\n}\n/* ------------------------- End of L_sub() ------------------------- */\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_mult                                                  |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   L_mult is the 32 bit result of the multiplication of var1 times var2    |\n |   with one shift left i.e.:                                               |\n |        L_mult(var1,var2) = L_shl((var1 times var2),1) and                 |\n |        L_mult(-32768,-32768) = 2147483647.                                |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word32) L_mult (Word16 var1, Word16 var2)\n{\n    Word32 L_var_out;\n\n    L_var_out = (Word32) var1 *(Word32) var2;\n\n    if (L_var_out != (Word32) 0x40000000L)\n    {\n        return L_var_out << 1;\n    }\n    else\n    {\n        SET_OVERFLOW(1);\n        return MAX_32;\n    }\n}\n/* ------------------------- End of L_mult() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_mac                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Multiply var1 by var2 and shift the result left by 1. Add the 32 bit    |\n |   result to L_var3 with saturation, return a 32 bit result:               |\n |        L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)).         |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word32) L_mac (Word32 L_var3, Word16 var1, Word16 var2)\n{\n    return L_add (L_var3, L_mult (var1, var2));\n}\n/* ------------------------- End of L_mac() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : round                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Round the lower 16 bits of the 32 bit input number into the MS 16 bits  |\n |   with saturation. Shift the resulting bits right by 16 and return the 16 |\n |   bit number:                                                             |\n |               round(L_var1) = extract_h(L_add(L_var1,32768))              |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32 ) whose value falls in the |\n |             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word16) itu_round (Word32 L_var1)\n{\n    return extract_h (L_add (L_var1, (Word32) 0x00008000L));\n}\n/* ------------------------- End of round() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_shr                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Arithmetically shift the 32 bit input L_var1 right var2 positions with  |\n |   sign extension. If var2 is negative, arithmetically shift L_var1 left   |\n |   by -var2 and zero fill the -var2 LSB of the result. Saturate the result |\n |   in case of underflows or overflows.                                     |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word32) L_shr_nocheck(Word32 L_var1, Word16 var2)\n{\n#if 1\n    return L_var1 >> var2;\n#else\n    if (var2 >= 31)\n    {\n        return (L_var1 < 0L) ? -1 : 0;\n    }\n    else\n    {\n        if (L_var1 < 0)\n        {\n            return ~((~L_var1) >> var2);\n        }\n        else\n        {\n            return L_var1 >> var2;\n        }\n    }\n#endif\n}\n\nPJ_INLINE(Word32) L_shl_nocheck (Word32 L_var1, Word16 var2)\n{\n#if PJ_HAS_INT64\n    return L_saturate( ((pj_int64_t)L_var1) << var2 );\n#else\n    for (; var2 > 0; var2--)\n    {\n        if (L_var1 > (Word32) 0X3fffffffL)\n        {\n            SET_OVERFLOW(1);\n            return MAX_32;\n        }\n        else\n        {\n            if (L_var1 < (Word32) 0xc0000000L)\n            {\n                SET_OVERFLOW(1);\n                return MIN_32;\n            }\n        }\n        L_var1 <<= 1;\n    }\n    return (L_var1);\n#endif\n}\n\nPJ_INLINE(Word32) L_shr (Word32 L_var1, Word16 var2)\n{\n    if (var2 < 0)\n    {\n        if (var2 < -32)\n            var2 = -32;\n        return L_shl_nocheck (L_var1, (Word16) -var2);\n    }\n    else\n    {\n\treturn L_shr_nocheck(L_var1, var2);\n    }\n}\n/* ------------------------- End of L_shr() ------------------------- */\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_shl                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero  |\n |   fill the var2 LSB of the result. If var2 is negative, arithmetically    |\n |   shift L_var1 right by -var2 with sign extension. Saturate the result in |\n |   case of underflows or overflows.                                        |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word32) L_shl (Word32 L_var1, Word16 var2)\n{\n    if (var2 <= 0)\n    {\n        if (var2 < -32)\n            var2 = -32;\n        return L_shr_nocheck(L_var1, (Word16) -var2);\n    }\n    else\n    {\n\treturn L_shl_nocheck(L_var1, var2);\n    }\n}\n/* ------------------------- End of L_shl() ------------------------- */\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : abs_s                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |    Absolute value of var1; abs_s(-32768) = 32767.                         |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 0000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\nPJ_INLINE(Word16) abs_s (Word16 var1)\n{\n#if 1\n    if (var1 >= 0)\n    \treturn var1;\n    else if (var1 == MIN_16)\n \treturn MAX_16;\n    else\n    \treturn (Word16)-var1;\n#else\n    if (var1 == MIN_16)\n    {\n        return MAX_16;\n    }\n    else\n    {\n        if (var1 < 0)\n        {\n            return (Word16)-var1;\n        }\n        else\n        {\n            return var1;\n        }\n    }\n#endif\n}\n/* ------------------------- End of abs_s() ------------------------- */\n\n\nPJ_INLINE(Word16) shl_nocheck(Word16 var1, Word16 var2)\n{\n#if 1\n    /* blp: this should be more optimized */\n    return saturate (((Word32)var1) << var2);\n#else\n    /* Original algorithm */\n    Word32 result = (Word32) var1 *((Word32) 1 << var2);\n\n    if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))\n    {\n        SET_OVERFLOW(1);\n        return (Word16) ((var1 > 0) ? MAX_16 : MIN_16);\n    }\n    else\n    {\n        return extract_l (result);\n    }\n#endif\n}\n\nPJ_INLINE(Word16) shr_nocheck(Word16 var1, Word16 var2)\n{\n#if 1\n    /* blp: this should yield the same value */\n    return (Word16) (var1 >> var2);\n#else\n    /* Original algorithm */\n    if (var2 >= 15)\n    {\n        return (Word16)((var1 < 0) ? -1 : 0);\n    }\n    else\n    {\n        if (var1 < 0)\n        {\n            return (Word16) (~((~var1) >> var2));\n        }\n        else\n        {\n            return (Word16)(var1 >> var2);\n        }\n    }\n#endif\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/common/common.c",
    "content": "/****************************************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**\t All rights reserved.\n**\n****************************************************************************************/\n\n/****************************************************************************************\n  Filename:    common.c    \n\n  Purpose:     Contains the functions used for both G.722.1 Annex C encoder and decoder\n\t\t\n  Design Notes:\n\n****************************************************************************************/\n/****************************************************************************************\n Include files                                                           \n****************************************************************************************/\n#include \"defs.h\"\n#include \"huff_def.h\"\n#include \"huff_tab.h\"\n#include \"tables.h\"\n#include \"count.h\"\n\n/****************************************************************************************\n Function:    categorize\n\n Syntax:      void categorize(Word16 number_of_available_bits,   \n                              Word16 number_of_regions,\n                              Word16 num_categorization_control_possibilities,\n                              Word16 rms_index,                  \n                              Word16 power_categories,           \n                              Word16 category_balances)          \n\n                  inputs:   number_of_regions\n                            num_categorization_control_possibilities\n                            number_of_available_bits\n                            rms_index[MAX_NUMBER_OF_REGIONS]                              \n                  \n                  outputs:  power_categories[MAX_NUMBER_OF_REGIONS]                       \n                            category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1]\n\n Description: Computes a series of categorizations \n\n WMOPS:     7kHz |    24kbit    |     32kbit\n          -------|--------------|----------------\n            AVG  |    0.14      |     0.14\n          -------|--------------|----------------  \n            MAX  |    0.15      |     0.15\n          -------|--------------|---------------- \n   \t\t\t\n           14kHz |    24kbit    |     32kbit     |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.42      |     0.45       |     0.48   \n          -------|--------------|----------------|----------------\n            MAX  |    0.47      |     0.52       |     0.52   \n          -------|--------------|----------------|----------------\n\n****************************************************************************************/\nvoid categorize(Word16 number_of_available_bits,\n\t\t        Word16 number_of_regions,\n\t\t        Word16 num_categorization_control_possibilities,\n\t\t        Word16 *rms_index,\n\t\t        Word16 *power_categories,\n\t\t        Word16 *category_balances)\n{\n    \n    Word16 offset;\n    Word16 temp;\n    Word16 frame_size;\n\n    /* At higher bit rates, there is an increase for most categories in average bit\n       consumption per region. We compensate for this by pretending we have fewer\n       available bits. */\n    test();\n    if (number_of_regions == NUMBER_OF_REGIONS)\n    {\n        frame_size = DCT_LENGTH;\n    }\n    else\n    {\n        frame_size = MAX_DCT_LENGTH;\n    }\n\n    temp = sub(number_of_available_bits,frame_size);\n    \n    test();\n    if (temp > 0)\n    {\n        number_of_available_bits = sub(number_of_available_bits,frame_size);\n        number_of_available_bits = extract_l(L_mult0(number_of_available_bits,5));\n        number_of_available_bits = shr_nocheck(number_of_available_bits,3);\n        number_of_available_bits = add(number_of_available_bits,frame_size);\n    }\n\n    /* calculate the offset using the original category assignments */\n    offset = calc_offset(rms_index,number_of_regions,number_of_available_bits);\n\n\n\n    /* compute the power categories based on the uniform offset */\n    compute_raw_pow_categories(power_categories,rms_index,number_of_regions,offset);\n    \n    \n    /* adjust the category assignments */\n    /* compute the new power categories and category balances */\n    comp_powercat_and_catbalance(power_categories,category_balances,rms_index,number_of_available_bits,number_of_regions,num_categorization_control_possibilities,offset);\n\n}\n    \n/***************************************************************************\n Function:    comp_powercat_and_catbalance\n\n Syntax:      void comp_powercat_and_catbalance(Word16 *power_categories,\n                                                Word16 *category_balances,\n                                                Word16 *rms_index,  \n                                                Word16 number_of_available_bits,                                  \n                                                Word16 number_of_regions,\n                                                Word16 num_categorization_control_possibilities,\n                                                Word16 offset)                                                    \n\n                \n                inputs:   *rms_index                              \n                          number_of_available_bits                 \n                          number_of_regions\n                          num_categorization_control_possibilities\n                          offset\n                           \n                outputs:  *power_categories  \n                          *category_balances \n                \n                \n Description: Computes the power_categories and the category balances\n\n WMOPS:     7kHz |    24kbit    |     32kbit\n          -------|--------------|----------------\n            AVG  |    0.10      |     0.10\n          -------|--------------|----------------  \n            MAX  |    0.11      |     0.11\n          -------|--------------|---------------- \n\t\t\t\t\n           14kHz |    24kbit    |     32kbit     |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.32      |     0.35       |     0.38   \n          -------|--------------|----------------|----------------\n            MAX  |    0.38      |     0.42       |     0.43   \n          -------|--------------|----------------|----------------\n\n***************************************************************************/\nvoid comp_powercat_and_catbalance(Word16 *power_categories,\n                                  Word16 *category_balances,\n                                  Word16 *rms_index,\n                                  Word16 number_of_available_bits,\n                                  Word16 number_of_regions,\n                                  Word16 num_categorization_control_possibilities,\n\t\t\t\t\t\t\t\t  Word16 offset)\n{\n    \n    Word16 expected_number_of_code_bits;\n    Word16 region;\n    Word16 max_region;\n    Word16 j;\n    Word16 max_rate_categories[MAX_NUMBER_OF_REGIONS];\n    Word16 min_rate_categories[MAX_NUMBER_OF_REGIONS];\n    Word16 temp_category_balances[2*MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES];\n    Word16 raw_max, raw_min;\n    Word16 raw_max_index=0, raw_min_index=0;\n    Word16 max_rate_pointer, min_rate_pointer;\n    Word16 max, min;\n    Word16 itemp0;\n    Word16 itemp1;\n    Word16 min_plus_max;\n    Word16 two_x_number_of_available_bits;\n\n    Word16 temp;\n\n    expected_number_of_code_bits = 0;\n    move16();\n\n    for (region=0; region<number_of_regions; region++)\n        expected_number_of_code_bits = add(expected_number_of_code_bits,expected_bits_table[power_categories[region]]);\n\n\n    for (region=0; region<number_of_regions; region++) \n    {\n        max_rate_categories[region] = power_categories[region];\n        move16();\n        \n        min_rate_categories[region] = power_categories[region];\n        move16();\n    }\n    \n    max = expected_number_of_code_bits;\n    move16();\n    min = expected_number_of_code_bits;\n    move16();\n    max_rate_pointer = num_categorization_control_possibilities;\n    move16();\n    min_rate_pointer = num_categorization_control_possibilities;\n    move16();\n    \n    for (j=0; j<num_categorization_control_possibilities-1; j++) \n    {\n        min_plus_max = add(max,min);\n        two_x_number_of_available_bits = shl_nocheck(number_of_available_bits,1);\n        \n        temp = sub(min_plus_max,two_x_number_of_available_bits);\n        test();\n        if (temp <= 0) \n        {\n            raw_min = 99;\n            move16();\n            /* Search from lowest freq regions to highest for best */\n            /* region to reassign to a higher bit rate category.   */\n            for (region=0; region<number_of_regions; region++) \n            {\n                test();\n                if (max_rate_categories[region] > 0) \n                {\n                    itemp0 = shl_nocheck(max_rate_categories[region],1);\n                    itemp1 = sub(offset,rms_index[region]);\n                    itemp0 = sub(itemp1,itemp0);\n                    \n                    temp = sub(itemp0,raw_min);\n                    test();\n                    if (temp < 0) \n                    {\n                        raw_min = itemp0;\n                        raw_min_index = region;\n                    }\n                }\n            }\n            max_rate_pointer = sub(max_rate_pointer,1);\n            temp_category_balances[max_rate_pointer] = raw_min_index;\n            move16();\n\n        \tmax = sub(max,expected_bits_table[max_rate_categories[raw_min_index]]);\n        \tmax_rate_categories[raw_min_index] = sub(max_rate_categories[raw_min_index],1);\n        \tmove16();\n\n            max = add(max,expected_bits_table[max_rate_categories[raw_min_index]]);\n        }\n        else \n        {\n            raw_max = -99;\n            move16();\n            /* Search from highest freq regions to lowest for best region to reassign to\n            a lower bit rate category. */\n            max_region = sub(number_of_regions,1);\n            for (region= max_region; region >= 0; region--) \n            {\n                temp = sub(min_rate_categories[region],(NUM_CATEGORIES-1));\n                test();\n                if (temp < 0)\n                {\n                    itemp0 = shl_nocheck(min_rate_categories[region],1);\n                    itemp1 = sub(offset,rms_index[region]);\n                    itemp0 = sub(itemp1,itemp0);\n                    \n                    temp = sub(itemp0,raw_max);\n                    test();\n                    if (temp > 0) \n                    {\n                        raw_max = itemp0;\n                        move16();\n                        raw_max_index = region;\n                        move16();\n                    }\n                }\n            }\n            temp_category_balances[min_rate_pointer] = raw_max_index;\n            move16();\n            \n            min_rate_pointer = add(min_rate_pointer,1);\n            min = sub(min,expected_bits_table[min_rate_categories[raw_max_index]]);\n            \n            min_rate_categories[raw_max_index] = add(min_rate_categories[raw_max_index],1);\n            move16();\n            \n            min = add(min,expected_bits_table[min_rate_categories[raw_max_index]]);\n        }\n    }\n    \n    for (region=0; region<number_of_regions; region++)\n    {\n        power_categories[region] = max_rate_categories[region];\n        move16();\n    }\n    \n    for (j=0; j<num_categorization_control_possibilities-1; j++)\n    {\n        category_balances[j] = temp_category_balances[max_rate_pointer++];\n        move16();\n    }\n\n}\n/***************************************************************************\n Function:    calc_offset\n\n Syntax:      offset=calc_offset(Word16 *rms_index,Word16 number_of_regions,Word16 available_bits)  \n\n                input:  Word16 *rms_index\n                        Word16 number_of_regions\n                        Word16 available_bits\n                        \n                output: Word16 offset                        \n\n Description: Calculates the the category offset.  This is the shift required\n              To get the most out of the number of available bits.  A binary \n              type search is used to find the offset.\n\n WMOPS:     7kHz |    24kbit    |     32kbit\n          -------|--------------|----------------\n            AVG  |    0.04      |     0.04\n          -------|--------------|----------------  \n            MAX  |    0.04      |     0.04\n          -------|--------------|---------------- \n\n           14kHz |    24kbit    |     32kbit     |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.08      |     0.08       |     0.08   \n          -------|--------------|----------------|----------------\n            MAX  |    0.09      |     0.09       |     0.09   \n          -------|--------------|----------------|----------------\n\n***************************************************************************/\nWord16 calc_offset(Word16 *rms_index,Word16 number_of_regions,Word16 available_bits)    \n{\n\n    Word16 answer;\n    Word16 delta;\n    Word16 test_offset;\n    Word16 region,j;\n    Word16 power_cats[MAX_NUMBER_OF_REGIONS];\n    Word16 bits;\n    Word16 offset;\n    Word16 temp;\n\n    /* initialize vars */\n    answer = -32;\n    move16();\n    delta = 32;\n    move16();\n    \n    do \n    {\n        test_offset = add(answer,delta);\n        \n        /* obtain a category for each region */\n        /* using the test offset             */\n        for (region=0; region<number_of_regions; region++) \n        {\n            j = sub(test_offset,rms_index[region]);\n            j = shr_nocheck(j,1);\n            \n            /* Ensure j is between 0 and NUM_CAT-1 */\n            test();\n            if (j < 0) \n            {\n                j = 0;\n                move16();\n            }\n            temp = sub(j,NUM_CATEGORIES-1);\n            test();\n            if (temp > 0) \n            {\n                j = sub(NUM_CATEGORIES,1);\n                move16();\n            }\n            power_cats[region] = j;\n            move16();\n        }\n        bits = 0;\n        move16();\n\n        /* compute the number of bits that will be used given the cat assignments */\n        for (region=0; region<number_of_regions; region++)\n            bits = add(bits,expected_bits_table[power_cats[region]]);\n\n        /* if (bits > available_bits - 32) then divide the offset region for the bin search */\n        offset = sub(available_bits,32);\n        temp = sub(bits,offset);\n        test();\n        if (temp >= 0)\n        {\n            answer = test_offset;\n            move16();\n        }\n        delta = shr_nocheck(delta,1);\n        test(); /* for the while loop */\n    } while (delta > 0);\n\n    return(answer);\n}\n/***************************************************************************\n Function:    compute_raw_pow_categories\n\n Syntax:      void compute_raw_pow_categories(Word16 *power_categories,\n                                              Word16 *rms_index,\n                                              Word16 number_of_regions,\n                                              Word16 offset)\n              inputs:  *rms_index\n                       number_of_regions\n                       offset\n                    \n              outputs: *power_categories                    \n\n\n\n Description: This function computes the power categories given the offset\n              This is kind of redundant since they were already computed\n              in calc_offset to determine the offset.\n\n WMOPS:          |    24kbit    |     32kbit\n          -------|--------------|----------------\n            AVG  |    0.01      |     0.01\n          -------|--------------|----------------  \n            MAX  |    0.01      |     0.01\n          -------|--------------|---------------- \n\n           14kHz |    24kbit    |     32kbit     |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.01      |     0.01       |     0.01   \n          -------|--------------|----------------|----------------\n            MAX  |    0.01      |     0.01       |     0.01   \n          -------|--------------|----------------|----------------\n\n***************************************************************************/\nvoid compute_raw_pow_categories(Word16 *power_categories,Word16 *rms_index,Word16 number_of_regions,Word16 offset)\n{\n    Word16 region;\n    Word16 j;\n    Word16 temp;\n\n    for (region=0; region<number_of_regions; region++) \n    {\n        j = sub(offset,rms_index[region]);\n        j = shr_nocheck(j,1);\n        \n        /* make sure j is between 0 and NUM_CAT-1 */\n        test();\n        if (j < 0) \n        {\n            j = 0;\n            move16();\n        }\n        temp = sub(j,(NUM_CATEGORIES-1));\n        test();\n        if (temp > 0) \n            j = sub(NUM_CATEGORIES,1);\n        \n        power_categories[region] = j;\n        move16();\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/common/config.h",
    "content": "#ifndef __LIBG7221_CONFIG_H__\n#define __LIBG7221_CONFIG_H__\n\n#include <pj/config.h>\n\n/**\n * Expand all basic operation functions as inline. Even if this is set to\n * zero, some critical functions would still be expanded as inline. Note\n * also that enabling this may generate some warning messages about functions\n * not being referenced (with gcc).\n *\n * Default: 0 (no)\n */\n#ifndef PJMEDIA_LIBG7221_FUNCS_INLINED\n#   define PJMEDIA_LIBG7221_FUNCS_INLINED   0\n#endif\n\n/* Declare/define a function that may be expanded as inline. */\n#if PJMEDIA_LIBG7221_FUNCS_INLINED\n#  define LIBG7221_DECL(type)  PJ_INLINE(type)\n#  define LIBG7221_DEF(type)   PJ_INLINE(type)\n#else\n#  define LIBG7221_DECL(type)  PJ_DECL(type)\n#  define LIBG7221_DEF(type)   PJ_DEF(type)\n#endif\n\n#endif /* __LIBG7221_CONFIG_H__ */\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/common/count.h",
    "content": "/* $Id: count.h 2623 2009-04-20 18:38:15Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef COUNT_H\n#define COUNT_H\n\n#define move16()\n#define move32()\n#define logic16()\n#define logic32()\n#define test()\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/common/defs.h",
    "content": "/***********************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**   All rights reserved.\n**\n***********************************************************************/\n\n#include <stdio.h>\n#include <math.h>\n#include <stdlib.h>\n#include \"g7221/common/typedef.h\"\n#include \"g7221/common/basic_op.h\"\n\n#define  PI             3.141592653589793238462\n\n#define MAX_DCT_LENGTH      640\n#define DCT_LENGTH          320\n#define DCT_LENGTH_DIV_2    160\n#define DCT_LENGTH_DIV_4     80\n#define DCT_LENGTH_DIV_8     40\n#define DCT_LENGTH_DIV_16    20\n#define DCT_LENGTH_DIV_32    10\n#define DCT_LENGTH_DIV_64     5\n\n\n#define MAX(a,b) (a > b ? a : b)\n#define MIN(a,b) (a < b ? a : b)\n\n#define NUM_CATEGORIES                  8\n#define NUM_CATEGORIZATION_CONTROL_BITS           4\n#define NUM_CATEGORIZATION_CONTROL_POSSIBILITIES  16\n#define CORE_SIZE       10\n#define DCT_LENGTH_LOG  6\n#define MAX_DCT_LENGTH_LOG  7\n\n/*  region_size = (BLOCK_SIZE * 0.875)/NUM_REGIONS; */\n#define NUMBER_OF_REGIONS       14\n#define MAX_NUMBER_OF_REGIONS   28\n#define REGION_SIZE             20\n#define NUMBER_OF_VALID_COEFS   (NUMBER_OF_REGIONS * REGION_SIZE)\n#define MAX_NUMBER_OF_VALID_COEFS   (MAX_NUMBER_OF_REGIONS * REGION_SIZE)\n\n#define REGION_POWER_TABLE_SIZE 64\n#define REGION_POWER_TABLE_NUM_NEGATIVES 24\n\n#define MAX_NUM_CATEGORIZATION_CONTROL_BITS 5\n#define MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES 32\n\n#define ENCODER_SCALE_FACTOR 18318.0\n\n/* The MLT output is incorrectly scaled by the factor\n   product of ENCODER_SCALE_FACTOR and sqrt(160.)\n   This is now (9/30/96) 1.0/2^(4.5) or 1/22.627.\n   In the current implementation this  \n   must be an integer power of sqrt(2). The\n   integer power is ESF_ADJUSTMENT_TO_RMS_INDEX.\n   The -2 is to conform with the range defined in the spec. */\n\n \n#define ESF_ADJUSTMENT_TO_RMS_INDEX (9-2)\n \n\n#define INTERMEDIATE_FILES_FLAG 0\n\n/* Max bit rate is 48000 bits/sec. */\n#define MAX_BITS_PER_FRAME 960\n\n\n/***************************************************************************/\n/* Type definitions                                                        */\n/***************************************************************************/\ntypedef struct\n{\n    Word16 code_bit_count;      /* bit count of the current word */\n    Word16 current_word;        /* current word in the bitstream being processed */\n    Word16 *code_word_ptr;      /* pointer to the bitstream */\n    Word16 number_of_bits_left; /* number of bits left in the current word */\n    Word16 next_bit;            /* next bit in the current word */\n}Bit_Obj;\n\ntypedef struct\n{\n    Word16 seed0;\n    Word16 seed1;\n    Word16 seed2;\n    Word16 seed3;\n}Rand_Obj;\n\n/***************************************************************************/\n/* Function definitions                                                    */\n/***************************************************************************/\nextern Word16  compute_region_powers(Word16  *mlt_coefs,\n                             Word16  mag_shift,\n                             Word16  *drp_num_bits,\n                             UWord16 *drp_code_bits,\n                             Word16  *absolute_region_power_index,\n                             Word16  number_of_regions);\n\nvoid    vector_quantize_mlts(Word16 number_of_available_bits,\n                          Word16 number_of_regions,\n                          Word16 num_categorization_control_possibilities,\n                          Word16 *mlt_coefs,\n                          Word16 *absolute_region_power_index,\n                          Word16 *power_categories,\n                          Word16 *category_balances,\n                          Word16 *p_categorization_control,\n                          Word16 *region_mlt_bit_counts,\n                          UWord32 *region_mlt_bits);\n\nWord16  vector_huffman(Word16 category,\n                      Word16 power_index,\n                      Word16 *raw_mlt_ptr,\n                      UWord32 *word_ptr);\n\n\nvoid    adjust_abs_region_power_index(Word16 *absolute_region_power_index,Word16 *mlt_coefs,Word16 number_of_regions);\n\nvoid    bits_to_words(UWord32 *region_mlt_bits,Word16 *region_mlt_bit_counts,\n                      Word16 *drp_num_bits,UWord16 *drp_code_bits,Word16 *out_words,\n                      Word16 categorization_control, Word16  number_of_regions,\n                      Word16  num_categorization_control_bits, Word16 number_of_bits_per_frame);\n\nvoid    encoder(Word16  number_of_available_bits,\n                Word16  number_of_regions,\n                Word16  *mlt_coefs,\n                Word16  mag_shift,\n                Word16  *out_words);\n\nvoid decoder(Bit_Obj *bitobj,\n    \t     Rand_Obj *randobj,\n             Word16 number_of_regions,\n             Word16 *decoder_mlt_coefs,\n\t         Word16 *p_mag_shift,\n\t         Word16 *p_old_mag_shift,\n\t         Word16 *old_decoder_mlt_coefs,\n\t         Word16 frame_error_flag);\n\nWord16  samples_to_rmlt_coefs(const Word16 *new_samples,Word16 *history,Word16 *coefs,Word16 dct_length);\nvoid rmlt_coefs_to_samples(Word16 *coefs,     \n                           Word16 *old_samples,           \n                           Word16 *out_samples,           \n                           Word16 dct_length,           \n                           Word16 mag_shift);\n\nWord16  index_to_array(Word16 index,Word16 *array,Word16 category);\nvoid    categorize(Word16 number_of_available_bits,\n                   Word16 number_of_regions,\n\t\t\t\t   Word16 num_categorization_control_possibilities,\n\t\t           Word16 *rms_index,\n\t\t           Word16 *power_categories,\n\t\t           Word16 *category_balances);\n\nWord16 calc_offset(Word16 *rms_index,Word16 number_of_regions,Word16 available_bits);    \nvoid   compute_raw_pow_categories(Word16 *power_categories,Word16 *rms_index,Word16 number_of_regions,Word16 offset);\nvoid   comp_powercat_and_catbalance(Word16 *power_categories,\n                                    Word16 *category_balances,\n                                    Word16 *rms_index,\n                                    Word16 number_of_available_bits,\n                                    Word16 number_of_regions,\n                                    Word16 num_categorization_control_possibilities,\n                                    Word16 offset);\n \nvoid dct_type_iv_a (Word16 *input,Word16 *output,Word16 dct_length);\nvoid dct_type_iv_s(Word16 *input,Word16 *output,Word16 dct_length);\nvoid decode_envelope(Bit_Obj *bitobj,\n                     Word16  number_of_regions,\n                     Word16  *decoder_region_standard_deviation,\n\t\t             Word16  *absolute_region_power_index,\n\t\t             Word16  *p_mag_shift);\n\nvoid decode_vector_quantized_mlt_indices(Bit_Obj  *bitobj,\n                                         Rand_Obj *randobj,\n                                         Word16   number_of_regions,\n                                         Word16   *decoder_region_standard_deviation,\n\t\t\t\t\t                     Word16   *dedecoder_power_categories,\n\t\t\t\t\t                     Word16   *dedecoder_mlt_coefs);\n\nvoid rate_adjust_categories(Word16 categorization_control,\n\t\t\t                Word16 *decoder_power_categories,\n\t\t\t                Word16 *decoder_category_balances);\n\nvoid get_next_bit(Bit_Obj *bitobj);\nWord16 get_rand(Rand_Obj *randobj);\n\nvoid test_4_frame_errors(Bit_Obj *bitobj,\n                         Word16 number_of_regions,\n                         Word16 num_categorization_control_possibilities,\n                         Word16 *frame_error_flag,\n                         Word16 categorization_control,\n                         Word16 *absolute_region_power_index);\n\nvoid error_handling(Word16 number_of_coefs,\n                    Word16 number_of_valid_coefs,\n                    Word16 *frame_error_flag,\n                    Word16 *decoder_mlt_coefs,\n                    Word16 *old_decoder_mlt_coefs,\n                    Word16 *p_mag_shift,\n                    Word16 *p_old_mag_shift);\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/common/huff_def.h",
    "content": "/***********************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**   All rights reserved.\n**\n***********************************************************************/\n\n#define REGION_POWER_STEPSIZE_DB 3.010299957\n#define ABS_REGION_POWER_LEVELS  32\n#define DIFF_REGION_POWER_LEVELS 24\n\n#define DRP_DIFF_MIN -12\n#define DRP_DIFF_MAX 11\n\n#define MAX_NUM_BINS 16\n#define MAX_VECTOR_INDICES 625\n#define MAX_VECTOR_DIMENSION 5\n\nextern Word16  differential_region_power_bits[MAX_NUMBER_OF_REGIONS][DIFF_REGION_POWER_LEVELS];\nextern UWord16 differential_region_power_codes[MAX_NUMBER_OF_REGIONS][DIFF_REGION_POWER_LEVELS];\nextern Word16  differential_region_power_decoder_tree[MAX_NUMBER_OF_REGIONS][DIFF_REGION_POWER_LEVELS-1][2];\nextern Word16  mlt_quant_centroid[NUM_CATEGORIES][MAX_NUM_BINS];\nextern Word16  expected_bits_table[NUM_CATEGORIES];\nextern Word16  mlt_sqvh_bitcount_category_0[196];\nextern UWord16 mlt_sqvh_code_category_0[196];\nextern Word16  mlt_sqvh_bitcount_category_1[100];\nextern UWord16 mlt_sqvh_code_category_1[100];\nextern Word16  mlt_sqvh_bitcount_category_2[49];\nextern UWord16 mlt_sqvh_code_category_2[49];\nextern Word16  mlt_sqvh_bitcount_category_3[625];\nextern UWord16 mlt_sqvh_code_category_3[625];\nextern Word16  mlt_sqvh_bitcount_category_4[256];\nextern UWord16 mlt_sqvh_code_category_4[256];\nextern Word16  mlt_sqvh_bitcount_category_5[243];\nextern UWord16 mlt_sqvh_code_category_5[243];\nextern Word16  mlt_sqvh_bitcount_category_6[32];\nextern UWord16 mlt_sqvh_code_category_6[32];\nextern Word16  *table_of_bitcount_tables[NUM_CATEGORIES-1];\nextern UWord16 *table_of_code_tables[NUM_CATEGORIES-1];\nextern Word16  mlt_decoder_tree_category_0[180][2];\nextern Word16  mlt_decoder_tree_category_1[93][2];\nextern Word16  mlt_decoder_tree_category_2[47][2];\nextern Word16  mlt_decoder_tree_category_3[519][2];\nextern Word16  mlt_decoder_tree_category_4[208][2];\nextern Word16  mlt_decoder_tree_category_5[191][2];\nextern Word16  mlt_decoder_tree_category_6[31][2];\nextern Word16  *table_of_decoder_tables[NUM_CATEGORIES-1];\n\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/common/huff_tab.c",
    "content": "/***********************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**   All rights reserved.\n**\n***********************************************************************/\n#include \"defs.h\"\n#include \"huff_def.h\"\n\nWord16 differential_region_power_bits[MAX_NUMBER_OF_REGIONS][DIFF_REGION_POWER_LEVELS] = {\n{99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99},\n{ 4, 6, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 4, 5, 7, 8, 9,11,11,12,12,12,12},\n{10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 7, 9,11,12,13,15,15,15,16,16},\n{12,10, 8, 6, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 4, 4, 5, 5, 7, 9,11,13,14,14},\n{13,10, 9, 9, 7, 7, 5, 5, 4, 3, 3, 3, 3, 3, 4, 4, 4, 5, 7, 9,11,13,13,13},\n{12,13,10, 8, 6, 6, 5, 5, 4, 4, 3, 3, 3, 3, 3, 4, 5, 5, 6, 7, 9,11,14,14},\n{12,11, 9, 8, 8, 7, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 5, 7, 8,10,13,14,14},\n{15,16,15,12,10, 8, 6, 5, 4, 3, 3, 3, 2, 3, 4, 5, 5, 7, 9,11,13,16,16,16},\n{14,14,11,10, 9, 7, 7, 5, 5, 4, 3, 3, 2, 3, 3, 4, 5, 7, 9, 9,12,14,15,15},\n{ 9, 9, 9, 8, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8,10,11,12,13,13},\n{14,12,10, 8, 6, 6, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 6, 8, 8, 9,11,14,14,14},\n{13,10, 9, 8, 6, 6, 5, 4, 4, 4, 3, 3, 2, 3, 4, 5, 6, 8, 9, 9,11,12,14,14},\n{16,13,12,11, 9, 6, 5, 5, 4, 4, 4, 3, 2, 3, 3, 4, 5, 7, 8,10,14,16,16,16},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14},\n{13,14,14,14,10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9,11,14,14,14}};\n\nUWord16 differential_region_power_codes[MAX_NUMBER_OF_REGIONS][DIFF_REGION_POWER_LEVELS] = {\n{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\n{ 8,38,18,10, 7, 6, 3, 2, 0, 1, 7, 6, 5, 4,11,78,158,318,1278,1279,2552,2553,2554,2555},\n{36, 8, 3, 5, 0, 1, 7, 6, 4, 3, 2, 5, 3, 4, 5,19,74,150,302,1213,1214,1215,2424,2425},\n{2582,644,160,41, 5,11, 7, 5, 4, 1, 0, 6, 4, 7, 3, 6, 4,21,81,323,1290,5167,10332,10333},\n{2940,366,181,180,47,46,27,10, 8, 5, 1, 0, 3, 7, 4, 9,12,26,44,182,734,2941,2942,2943},\n{3982,7967,994,249,63,26,19,18,14, 8, 6, 1, 0, 2, 5, 7,12,30,27,125,496,1990,15932,15933},\n{3254,1626,407,206,202,100,30,14, 3, 5, 3, 0, 2, 4, 2,13,24,31,102,207,812,6511,13020,13021},\n{1110,2216,1111,139,35, 9, 3,20,11, 4, 2, 1, 3, 3, 1, 0,21, 5,16,68,276,2217,2218,2219},\n{1013,1014,127,62,29, 6, 4,16, 0, 1, 3, 2, 3, 1, 5, 9,17, 5,28,30,252,1015,2024,2025},\n{381,380,372,191,94,44,16,10, 7, 3, 1, 0, 2, 6, 9,17,45,92,187,746,1494,2991,5980,5981},\n{3036,758,188,45,43,10, 4, 3, 6, 4, 2, 0, 3, 7,11,20,42,44,46,95,378,3037,3038,3039},\n{751,92,45,20,26, 4,12, 7, 4, 0, 4, 1, 3, 5, 5, 3,27,21,44,47,186,374,1500,1501},\n{45572U,5697,2849,1425,357,45,23, 6,10, 7, 2, 2, 3, 0, 4, 6, 7,88,179,713,11392,45573U,45574U,45575U},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021},\n{2511,5016,5018,5017,312,79,38,36,30,14, 6, 0, 2, 1, 3, 5, 8,31,37,157,626,5019,5020,5021}};\n\nWord16 differential_region_power_decoder_tree[MAX_NUMBER_OF_REGIONS][DIFF_REGION_POWER_LEVELS-1][2] = {\n{{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0},{  0,  0}},\n{{  1,  2},{  3,  4},{  5,  6},{  7,  8},{  9, 10},{ 11,-12},{-11,-10},{ -8, -9},{ -7, -6},{-13, 12},{ -5, -4},{  0, 13},{ -3,-14},{ -2, 14},{ -1, 15},{-15, 16},{-16, 17},{-17, 18},{ 19, 20},{ 21, 22},{-18,-19},{-20,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{  5,  6},{  7,  8},{-10, -9},{ -8,-11},{ -7, -6},{  9, -5},{ 10,-12},{ -4, 11},{-13, -3},{ 12, -2},{ 13,-14},{ -1, 14},{ 15,-15},{  0, 16},{-16, 17},{-17, 18},{-18, 19},{ 20, 21},{ 22,-19},{-20,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{  5,  6},{  7,  8},{  9, 10},{-12, 11},{-11,-13},{-10, -9},{ 12,-14},{ -8, -7},{-15, -6},{ 13, -5},{-16, -4},{ 14,-17},{ 15, -3},{ 16,-18},{ -2, 17},{ 18,-19},{ -1, 19},{-20, 20},{  0, 21},{ 22,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{  5,  6},{-11,-10},{  7,-12},{  8, -9},{  9,-13},{-14, 10},{ -8,-15},{-16, 11},{ -7, 12},{-17, -6},{ 13, 14},{-18, 15},{ -5, -4},{ 16, 17},{ -3, -2},{-19, 18},{ -1, 19},{-20, 20},{ 21, 22},{  0,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{  5,  6},{-12,-11},{-13,  7},{  8,-14},{-10,  9},{ 10,-15},{ -9, 11},{ -8, 12},{-16, 13},{ -7, -6},{-17, 14},{ -5,-18},{ 15, -4},{ 16,-19},{ 17, -3},{-20, 18},{ -2, 19},{-21, 20},{  0, 21},{ 22, -1},{-22,-23}},\n{{  1,  2},{  3,  4},{  5,  6},{-11,  7},{-12,-10},{-13, -9},{  8,  9},{-14, -8},{ 10,-15},{ -7, 11},{-16, 12},{ -6,-17},{ 13, 14},{ -5, 15},{-18, 16},{ -4, 17},{ -3,-19},{ 18, -2},{-20, 19},{ -1, 20},{  0, 21},{ 22,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{  5,-12},{  6,-11},{-10,-13},{ -9,  7},{  8,-14},{  9, -8},{-15, 10},{ -7,-16},{ 11, -6},{ 12,-17},{ 13, -5},{-18, 14},{ 15, -4},{-19, 16},{ 17, -3},{-20, 18},{ 19, 20},{ 21, 22},{  0, -2},{ -1,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{  5,-12},{  6,-13},{-11,-10},{  7,-14},{  8, -9},{  9,-15},{ -8, 10},{ -7,-16},{ 11, 12},{ -6,-17},{ -5, 13},{ 14, 15},{-18, -4},{-19, 16},{ -3, 17},{ 18, -2},{-20, 19},{ 20, 21},{ 22,  0},{ -1,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{  5,  6},{-11,-10},{-12, -9},{  7,  8},{-13, -8},{  9,-14},{ -7, 10},{ -6,-15},{ 11, 12},{ -5,-16},{ 13, 14},{-17, 15},{ -4, 16},{ 17,-18},{ 18, -3},{ -2, 19},{ -1,  0},{-19, 20},{-20, 21},{ 22,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{  5,  6},{-11,  7},{-10,-12},{ -9,  8},{ -8,-13},{  9, -7},{ 10,-14},{ -6, 11},{-15, 12},{ -5, 13},{-16, -4},{ 14, 15},{-17, -3},{-18, 16},{ 17,-19},{ -2, 18},{-20, 19},{ -1, 20},{ 21, 22},{  0,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{  5,-12},{  6,-11},{  7,  8},{-10,-13},{ -9,  9},{ -8,-14},{ 10, -7},{ 11,-15},{ -6, 12},{ -5, 13},{ -4,-16},{ 14, 15},{ -3,-17},{ 16, 17},{-18, -2},{ 18,-19},{ -1, 19},{-20, 20},{-21, 21},{ 22,  0},{-22,-23}},\n{{  1,  2},{  3,  4},{  5,-12},{-13,  6},{-11,  7},{-14,  8},{-10,  9},{-15, -9},{ -8, 10},{ -7,-16},{ 11, -6},{ 12, -5},{-17, 13},{ 14,-18},{ 15, -4},{ 16,-19},{ 17, -3},{ 18, -2},{ 19, -1},{-20, 20},{ 21, 22},{  0,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}},\n{{  1,  2},{  3,  4},{-12,  5},{-11,-13},{  6,-14},{-10,  7},{  8,-15},{ -9,  9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22,  0},{ -1, -3},{ -2,-21},{-22,-23}}};\n\nWord16 mlt_quant_centroid[NUM_CATEGORIES][MAX_NUM_BINS] = {\n{    0, 1606, 3119, 4586, 6049, 7502, 8941,10406,11851,13292,14736,16146,17566,19351,    0,    0},\n{    0, 2229, 4341, 6401, 8471,10531,12583,14588,16673,18924,    0,    0,    0,    0,    0,    0},\n{    0, 3055, 5998, 8929,11806,14680,17680,    0,    0,    0,    0,    0,    0,    0,    0,    0},\n{    0, 4121, 8192,12259,16322,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0},\n{    0, 5413,11071,16315,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0},\n{    0, 6785,14300,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0},\n{    0, 8044,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0},\n{    0, 8019,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}};\n\nWord16 expected_bits_table[NUM_CATEGORIES] = {52, 47, 43, 37, 29, 22, 16,   0};\n\n\nWord16 mlt_sqvh_bitcount_category_0[196] = {\n 1, 4, 6, 6, 7, 7, 8, 8, 8, 9, 9,10,11,11, 4, 5,\n 6, 7, 7, 8, 8, 9, 9, 9, 9,10,11,11, 5, 6, 7, 8,\n 8, 9, 9, 9, 9,10,10,10,11,12, 6, 7, 8, 9, 9, 9,\n 9,10,10,10,10,11,12,13, 7, 7, 8, 9, 9, 9,10,10,\n10,10,11,11,12,13, 8, 8, 9, 9, 9,10,10,10,10,11,\n11,12,13,14, 8, 8, 9, 9,10,10,11,11,11,12,12,13,\n13,15, 8, 8, 9, 9,10,10,11,11,11,12,12,13,14,15,\n 9, 9, 9,10,10,10,11,11,12,13,12,14,15,16, 9, 9,\n10,10,10,10,11,12,12,14,14,16,16,16, 9, 9,10,10,\n11,11,12,13,13,14,14,15,15,16,10,10,10,11,11,12,\n12,13,15,15,16,14,15,15,11,11,11,12,13,13,13,15,\n16,16,16,16,14,15,11,11,12,13,13,14,15,16,16,16,\n16,16,16,14};\nUWord16 mlt_sqvh_code_category_0[196] = {\n    1,    2,    1,   24,   14,   51,    9,   68,  110,   26,  218,   54,  154,  761,    3,   10,\n   22,    8,   58,   22,   71,   16,   30,   50,  213,   75,   94,  632,   15,   18,   52,   23,\n  107,    5,   54,   63,  239,   46,  276,  271,  851,  252,   28,   10,   12,    1,   22,  133,\n  191,   55,  105,  278,  317,  554,  310,  276,   32,   50,   94,   20,  187,  219,   13,  268,\n  473,  445,  145,  849, 1277,  623,    1,   14,    0,   55,  238,  121,  120,  269,  318,  530,\n  639, 1117,  509,  556,   24,   78,   51,  153,   62,  308,   16,   25,   68, 1058,  428,  277,\n 2233, 1114,   92,  108,  141,  223,  270,  381,   24,  212,  760,   35, 1063,  279, 1717, 3439,\n    7,   21,  152,   73,  309,  310,   95,  944, 1890, 2232, 1891, 5107,10213, 4981,   61,   62,\n    9,   79,  474,  475,  848, 1059, 1056, 1716,  139, 4978, 4983, 4983,  140,  186,   76,  444,\n  144,  633, 1057,  838, 2237, 4472, 4473,10212,10212, 4983,   74,   78,  311,  213,  850, 1062,\n 1119,  508,  276,  277, 4982, 4473,10212,10212,  208,   70,  555,  418,   68,  510, 2552, 1115,\n 4980, 4979, 4982, 4982, 4473,10212,  215,   71,  253,  511,  839, 1718, 2488, 6876, 6877, 4979,\n 4979, 4982, 4982, 4473};\nWord16 mlt_sqvh_bitcount_category_1[100] = {\n 1, 4, 5, 6, 7, 8, 8, 9,10,10, 4, 5, 6, 7, 7, 8,\n 8, 9, 9,11, 5, 5, 6, 7, 8, 8, 9, 9,10,11, 6, 6,\n 7, 8, 8, 9, 9,10,11,12, 7, 7, 8, 8, 9, 9,10,11,\n11,13, 8, 8, 8, 9, 9,10,10,11,12,14, 8, 8, 8, 9,\n10,11,11,12,13,15, 9, 9, 9,10,11,12,12,14,14,14,\n 9, 9, 9,10,11,12,14,16,14,14,10,10,11,12,13,14,\n16,16,16,14};\nUWord16 mlt_sqvh_code_category_1[100] = {\n    1,    2,   11,   27,   31,    9,  120,   31,  275,  310,    1,    0,   12,    5,   33,   54,\n  102,  111,  246,  448,   10,   14,   31,   39,   59,  100,  114,  202,  485,  969,   24,   26,\n   36,   52,  103,   30,  120,  242,   69, 1244,   35,   32,   14,   61,  113,  117,  233,  486,\n  487, 2491,   13,   12,   69,  110,  149,   35,  495,  449, 1978, 7751,   76,   75,  122,  136,\n  213,   68,  623,  930, 3959, 9961,  115,   16,  107,  225,  424,  850, 1936, 7916, 4981, 4981,\n  148,  154,  243,  407,  988,  851, 7750,19920, 7916, 4981,  406,  274,  464,  931, 3874, 7917,\n19921,19920,19920, 7916};\nWord16 mlt_sqvh_bitcount_category_2[49] = {\n 1, 4, 5, 7, 8, 9,10, 3, 4, 5, 7, 8, 9,10, 5, 5,\n 6, 7, 8,10,10, 7, 6, 7, 8, 9,10,12, 8, 8, 8, 9,\n10,12,14, 8, 9, 9,10,11,15,16, 9,10,11,12,13,16,\n15};\nUWord16 mlt_sqvh_code_category_2[49] = {\n    1,    0,   10,   11,   28,   62,  363,    3,    2,    9,    8,   24,   53,  352,    7,    8,\n   13,   25,   89,   74,  355,   10,   23,   24,   29,   55,  354, 1449,   25,   19,   30,   52,\n  108,  438, 5793,   91,   36,   63,  353,  725,11584,23170,  180,   75,  218,  439, 2897,23171,\n11584};\nWord16 mlt_sqvh_bitcount_category_3[625] = {\n 2, 4, 6, 8,10, 5, 5, 6, 8,10, 7, 8, 8,10,12, 9,\n 9,10,12,15,10,11,13,16,16, 5, 6, 8,10,11, 5, 6,\n 8,10,12, 7, 7, 8,10,13, 9, 9,10,12,15,12,11,13,\n16,16, 7, 9,10,12,15, 7, 8,10,12,13, 9, 9,11,13,\n16,11,11,12,14,16,12,12,14,16,14, 9,11,12,16,16,\n 9,10,13,15,16,10,11,12,16,16,13,13,16,16,16,16,\n16,15,16,16,11,13,16,16,15,11,13,15,16,16,13,13,\n16,16,16,14,16,16,16,16,16,16,16,16,16, 4, 6, 8,\n10,13, 6, 6, 8,10,13, 9, 8,10,12,16,10,10,11,15,\n16,13,12,14,16,16, 5, 6, 8,11,13, 6, 6, 8,10,13,\n 8, 8, 9,11,14,10,10,12,12,16,13,12,13,15,16, 7,\n 8, 9,12,16, 7, 8,10,12,14, 9, 9,10,13,16,11,10,\n12,15,16,13,13,16,16,15, 9,11,13,16,16, 9,10,12,\n15,16,10,11,13,16,16,13,12,16,16,16,16,16,16,16,\n16,11,13,16,16,16,11,13,16,16,16,12,13,15,16,16,\n16,16,16,16,16,16,16,16,16,16, 6, 8,11,13,16, 8,\n 8,10,12,16,11,10,11,13,16,12,13,13,15,16,16,16,\n14,16,15, 6, 8,10,13,16, 8, 8,10,12,16,10,10,11,\n13,16,13,12,13,16,16,14,14,14,16,16, 8, 9,11,13,\n16, 8, 9,11,16,14,10,10,12,15,16,12,12,13,16,16,\n15,16,16,16,16,10,12,15,16,16,10,12,12,14,16,12,\n12,13,16,16,14,15,16,16,16,16,16,16,16,16,12,15,\n15,16,16,13,13,16,16,14,14,16,16,16,16,16,16,16,\n16,16,14,15,16,16,16, 8,10,13,15,16,10,11,13,16,\n16,13,13,14,16,16,16,16,16,16,16,16,16,16,16,16,\n 8,10,11,15,16, 9,10,12,16,16,12,12,15,16,16,16,\n14,16,16,16,16,16,16,16,16, 9,11,14,16,16,10,11,\n13,16,16,14,13,14,16,16,16,15,15,16,16,16,16,16,\n16,16,11,13,16,16,16,11,13,15,16,16,13,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,15,16,16,16,16,\n14,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16, 9,13,16,16,16,11,13,16,16,16,14,15,\n16,16,16,15,16,16,16,16,16,16,16,16,16, 9,13,15,\n15,16,12,13,14,16,16,16,15,16,16,16,16,16,16,16,\n16,16,16,16,16,16,11,13,15,16,16,12,14,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,15,15,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,15,\n16,16,13,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16};\nUWord16 mlt_sqvh_code_category_3[625] = {\n    3,    8,   46,  145,  228,    4,    8,   47,   28,  455,   89,    2,  180,    5, 1335,  250,\n   12,  644, 1311,  139,  729,  251,  870, 2172, 2211,    5,   23,  112,  334, 1469,   21,    3,\n    5,  111, 2014,   88,   79,  152,  124, 2685,  297,   48,  110, 1310,  149,  501, 1231,  153,\n 2267, 2569,   57,   13,  653, 2587,  143,   75,  124,  118, 2611, 5242,   61,   50,  253, 3633,\n 2216,  476,   39,   57, 1926, 2236, 2586, 1329, 1920, 2566, 1926,  296,  233, 2590, 2240, 2217,\n  253,  613,  867,  144,  318,  614,  252, 2589, 2242, 2218,  872,  866, 2187, 2296, 2155, 2568,\n 2227,  150, 2567, 2296,  199, 2686, 2160, 2290,19145,  232, 2680,  128, 2192, 2212, 2684,  793,\n 2281, 2223, 2242, 1934, 2165, 2146, 2291, 2296, 2222, 2189, 2187, 2296, 2296,    6,    4,   82,\n  725, 3632,   15,   21,   56,  599,  148,    3,  162,   42,  411, 2301,  735,  654,  930,  137,\n 2586,  869, 1334, 1931, 2300, 2213,    9,   22,  146, 1290, 5240,    5,   12,   53,  630,  875,\n   80,    9,    8,   86, 2002,  210,  117,   56, 2019, 2162,  146,  397,  868,  131, 2151,   77,\n  160,  365, 2610, 2252,   59,   54,   41, 2591, 1928,  226,   14,  121, 5792, 2295, 1197,  728,\n  408,  130, 2157, 3635,  155, 2573, 2587,  130,  314,   64,  144, 2173, 2176,  115,   30,  409,\n  153, 2590,  631,   26, 4787, 2221, 2174, 2683, 1863, 2572,  319, 2150, 2177, 2194, 2571, 2257,\n  319,   65,  145, 2251, 2156, 2161,  909,  864, 2193, 2197, 2246, 2588, 5797,  156, 2258, 2221,\n 2158, 2199, 2214, 2152,  319, 2188, 2264, 2572,  319,  319,   30,  117,  219,  865, 2263,  147,\n  127,  239,  410, 2247,   27,  324, 1468, 2681, 2180, 1328, 5241,  147,  142, 2237, 2241, 2245,\n 1921, 2262,  142,   41,   11,  505, 2682, 2591,    0,   26,  229, 2015, 2577,  464,   98,   87,\n 5243, 2166,  149, 2016, 5244, 2190, 2198, 9573,11598,11599, 2235, 2190,  144,  298, 1004, 5245,\n 2277,  156,  104,  254, 2560, 1922,  612,  325, 2017,  129, 2588, 2608, 1330,  871, 2144, 2145,\n  132, 2147, 2148, 2149, 2144,  119, 1331,  133, 2153, 2154,  211,   58, 2609, 1923, 2159,  510,\n  163, 5246, 2163, 2164, 1924,  134, 2167, 2168, 2168, 2169, 2170, 2171, 2168, 2168, 1332,  135,\n  136, 2175, 2153,  150,  873, 2178, 2179, 1923, 1925, 2181, 2182, 2183, 2163, 2184, 2185, 2186,\n 2168, 2168, 1924,  134, 2167, 2168, 2168,   58,  326, 2687,  138, 2191,   31,   66,  874, 2195,\n 2196,  151,  152, 1927, 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2210, 2205,\n   55,  103, 1230,  140, 2215,  118,   15, 1333, 2219, 2220, 2018,  511,  141, 2224, 2225, 2226,\n 1929, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2229,  366, 1005, 1930, 2238, 2239,   12, 1006,\n 5247, 2243, 2244, 1932, 3634, 1933, 2248, 2249, 2250,  145,  146, 2253, 2253, 2254, 2255, 2256,\n 2253, 2253, 1291, 5793, 2259, 2260, 2261,  477, 5794,  147, 2265, 2266, 5795, 2268, 2269, 2270,\n 2270, 2271, 2272, 2273, 2274, 2274, 2275, 2276, 2273, 2274, 2274,  148, 2278, 2279, 2280, 2260,\n 1935, 2282, 2283, 2284, 2265, 2285, 2286, 2287, 2270, 2270, 2288, 2289, 2273, 2274, 2274, 2271,\n 2272, 2273, 2274, 2274,  233, 5796, 2292, 2293, 2294, 1292, 3724, 2297, 2298, 2299, 2000,  151,\n 2302, 2303, 2200,  152, 2561, 2562, 2563, 2205, 2564, 2565, 2204, 2205, 2205,  363,  154,  154,\n  155, 2570,   59, 3725, 2001, 2574, 2575, 2576,  157, 2578, 2579, 2224, 2580, 2581, 2582, 2583,\n 2229, 2584, 2585, 2228, 2229, 2229,  654, 5798,  158, 2589, 2238, 2392, 2003, 2592, 2593, 2243,\n 2594, 2595, 2596, 2597, 2248, 2598, 2599, 2600, 2253, 2253, 2250,  145,  146, 2253, 2253, 2601,\n 2602, 2603, 2604, 2260, 2605, 2606, 2607, 6336, 2265, 6337, 6338, 6339, 2270, 2270, 6340, 6341,\n 2273, 2274, 2274, 2271, 2272, 2273, 2274, 2274, 6342, 6343, 2259, 2260, 2260,38288U,38289U,  147,\n 2265, 2265, 5795, 2268, 2269, 2270, 2270, 2271, 2272, 2273, 2274, 2274, 2271, 2272, 2273, 2274,\n 2274};\nWord16 mlt_sqvh_bitcount_category_4[256] = {\n 2, 4, 7,10, 4, 5, 7,10, 7, 8,10,14,11,11,15,15,\n 4, 5, 9,12, 5, 5, 8,12, 8, 7,10,15,11,11,15,15,\n 7, 9,12,15, 8, 8,12,15,10,10,13,15,14,14,15,13,\n11,13,15,15,11,13,15,15,14,15,15,13,15,15,13,13,\n 4, 5, 9,13, 5, 6, 9,13, 9, 9,11,15,14,13,15,15,\n 4, 6, 9,12, 5, 6, 9,13, 9, 8,11,15,13,12,15,15,\n 7, 9,12,15, 7, 8,11,15,10,10,14,15,14,15,15,14,\n10,12,15,15,11,13,15,15,15,15,15,14,15,15,14,14,\n 6, 9,13,14, 8, 9,12,15,12,12,15,15,15,15,15,15,\n 7, 9,13,15, 8, 9,12,15,11,12,15,15,15,15,15,15,\n 9,11,15,15, 9,11,15,15,14,14,15,15,15,15,15,15,\n14,15,15,15,14,15,15,15,15,15,15,15,14,14,15,15,\n 9,12,15,15,12,13,15,15,15,15,15,15,15,15,15,15,\n10,12,15,15,12,14,15,15,15,15,15,15,15,15,15,15,\n14,15,15,15,15,15,15,15,15,15,15,15,14,14,15,15,\n15,15,15,15,15,15,15,15,14,14,15,15,14,14,15,15};\nUWord16 mlt_sqvh_code_category_4[256] = {\n    1,    2,    4,  572,   10,    0,   69,  712,   91,   10,   46, 9182, 1426, 1430,30172,30194,\n    9,   28,   22, 2258,   16,   25,  142, 2179,   15,  111,  719, 1521, 1131, 1437, 1520,30196,\n   88,  283, 3803,30193,   13,  236, 2856,30166,  545,  951, 5709, 1522, 3241, 9180,30179, 5709,\n 1088, 4356,30410,30175, 1146,  377,30162,30163, 8715,30176,30165, 5709,30197,30184, 5709, 5709,\n    1,   23,   28, 5710,   26,   14,   29, 7538,  102,  103, 1429, 1524, 3237, 7060,30401,30201,\n   15,   13,  470, 3768,   24,   15,  281, 5747,   24,  181, 1128,30206, 5711, 3531,30156,30158,\n  116,  100, 2260,30187,  119,  234, 1764,30171,  716,  883, 9183,30164, 3236, 1528,30180, 9183,\n  885, 2870, 1532,30160, 1431, 5708,30192,30205,30402,30168,30173, 9183,30157,30161, 9183, 9183,\n   54,   25, 1621,15211,  180,  287, 2261,30198,  808,  811,30411,30413,30414,22986,22987,30411,\n   24,  273,  376,30159,  137,  280, 2871, 1523, 1768, 2259, 1525,30167, 1526,30169,30170, 1525,\n  443, 1434, 1527,30174,  474, 1769,30177,30178, 3238, 3239,30181,30181,30182,30183,30181,30181,\n 3240,30185,30186, 1527, 9181,30188,30189,30177,30190,30191,30181,30181, 3238, 3239,30181,30181,\n  440, 2857, 1529,30195, 2294, 7061, 1530,30199,30200, 1531,30202,30411,30203,30204,30411,30411,\n  203, 2872,30207,30400,  189,11492,30403,30404,30405,30406,30407, 1525,30408,30409, 1525, 1525,\n 8714, 1533,30412, 1527, 1534, 1535,30415,30177,30416,30417,30181,30181, 3238, 3239,30181,30181,\n30418,30419, 1527, 1527,30420,30421,30177,30177, 3238, 3239,30181,30181, 3238, 3239,30181,30181};\nWord16 mlt_sqvh_bitcount_category_5[243] = {\n 2, 4, 8, 4, 5, 9, 9,10,14, 4, 6,11, 5, 6,12,10,\n11,15, 9,11,15,10,13,15,14,15, 6, 4, 6,12, 6, 7,\n12,12,12,15, 5, 7,13, 6, 7,13,12,13,15,10,12,15,\n11,13,15,15,15, 7, 8,13,15,11,12,15,15,15, 7,10,\n13,15,12,15,15,15,15, 7,15,15, 7,15,15, 7, 6, 7,\n 7, 4, 5,11, 5, 7,12,11,12,15, 6, 7,13, 7, 8,14,\n12,14,15,11,13,15,12,13,15,15,15, 8, 5, 6,13, 7,\n 8,15,12,14,15, 6, 8,14, 7, 8,15,14,15,15,12,12,\n15,12,13,15,15,15, 8, 9,13,15,12,13,15,15,15, 8,\n11,13,15,13,13,15,15,15, 8,14,15, 8,15,15, 8, 7,\n 8, 8, 8,10,15,11,12,15,15,15, 7,10,12,15,12,13,\n15,15,15, 8,14,15, 7,15,15, 8, 7, 8, 8, 8,12,15,\n12,13,15,15,15, 8,11,13,15,13,15,15,15,15, 8,15,\n15, 8,15,15, 8, 7, 8, 8,14,15, 6,15,15, 8, 7, 8,\n 8,15,15, 8,15,15, 8, 7, 8, 8, 6, 8, 8, 7, 8, 8,\n 7, 8, 8};\nUWord16 mlt_sqvh_code_category_5[243] = {\n    0,    5,  220,   10,   16,  443,  390,  391,14333,   11,   26, 1566,   26,   54, 3135,  508,\n 1558,28581,  255, 1782,28599,  885, 6208,28578,14335,28579,   54,    9,   35, 3129,   27,   68,\n 3537, 1562, 3568,28610,   25,   62, 4078,   58,  118, 7763, 3107, 7758,28563,  778, 3131,28598,\n  780, 7123,28630,28593,28586,  118,  243, 6210,28614, 1018, 3567,28601,28611,28570,   68,  388,\n 6256,28619, 1559,28562,28606,28565,28591,  118,28594,28571,   62,28618,28590,  118,   58,  118,\n  118,    4,   28, 1781,   31,   60, 3134, 1938, 3882,28574,   25,   96, 7757,   49,  126,14244,\n 3883,14334,28613, 1769, 4077,28602, 3106, 7756,28582,28621,28566,  126,   14,   61, 4079,   61,\n  138,28491, 3536, 8153,28573,   49,   96,12442,  119,  240,28490,12443,28560,28561, 3111, 3580,\n28564, 3130, 7759,28567,28568,28569,  240,  444, 6209,28572, 3569, 6211,28575,28576,28577,  138,\n  778, 7760,28580, 7761, 7762,28583,28584,28585,  240,14319,28587,   96,28588,28589,  240,  119,\n  240,  240,  139,  968,28592, 1554, 3581,28595,28596,28597,   60,  971, 3560,28600, 3582, 7132,\n28603,28604,28605,  126,14332,28607,   96,28608,28609,  126,   49,  126,  126,  241, 1558,28612,\n 1563, 6257,28615,28616,28617,  138, 1559, 7133,28620, 6220,28622,28623,28624,28625,  240,28626,\n28627,   96,28628,28629,  240,  119,  240,  240, 8152,28631,   61,28632,28633,  138,   61,  138,\n  138,28634,28635,   96,28636,28637,  240,  119,  240,  240,   49,   96,   96,  119,  240,  240,\n  119,  240,  240};\nWord16 mlt_sqvh_bitcount_category_6[32] = {\n 1, 4, 4, 6, 4, 6, 6, 8, 4, 6, 6, 8, 6, 9, 8,10,\n 4, 6, 7, 8, 6, 9, 8,11, 6, 9, 8,10, 8,10, 9,11};\nUWord16 mlt_sqvh_code_category_6[32] = {\n    1,    2,    4,    2,    5,   29,   24,  101,    3,   31,   28,  105,    3,    5,  102,  424,\n    1,   30,    0,  107,   27,  200,  103,  806,    1,    4,  104,  402,    3,  425,  213,  807};\n\nWord16 *table_of_bitcount_tables[NUM_CATEGORIES-1] = {\nmlt_sqvh_bitcount_category_0,\nmlt_sqvh_bitcount_category_1,\nmlt_sqvh_bitcount_category_2,\nmlt_sqvh_bitcount_category_3,\nmlt_sqvh_bitcount_category_4,\nmlt_sqvh_bitcount_category_5,\nmlt_sqvh_bitcount_category_6\n};\n\n\nUWord16 *table_of_code_tables[NUM_CATEGORIES-1] = {\n(UWord16 *)mlt_sqvh_code_category_0,\n(UWord16 *)mlt_sqvh_code_category_1,\n(UWord16 *)mlt_sqvh_code_category_2,\n(UWord16 *)mlt_sqvh_code_category_3,\n(UWord16 *)mlt_sqvh_code_category_4,\n(UWord16 *)mlt_sqvh_code_category_5,\n(UWord16 *)mlt_sqvh_code_category_6\n};\n\nWord16 mlt_decoder_tree_category_0[180][2] = {\n{   1,   0},{   2,   3},{   4,   5},{   6,   7},{   8,   9},{  -1, -14},{  10,  11},{  12,  13},\n{  14,  15},{  16,  17},{  18,  19},{ -15,  20},{  21,  22},{  23, -28},{  24,  -2},{  25,  26},\n{  27,  28},{  29,  30},{  31,  32},{ -29,  33},{ -16,  34},{  -3,  35},{  36,  37},{ -42,  38},\n{  39,  40},{  41,  42},{  43,  44},{ -17,  45},{ -43,  46},{  47,  48},{  -4,  49},{ -56,  50},\n{  51,  52},{  53,  54},{  55,  56},{ -57,  -5},{ -30,  57},{  58,  59},{ -18,  60},{  61, -70},\n{  62,  63},{  64,  -6},{  65,  66},{ -44,  67},{ -71,  68},{  69,  70},{ -19, -31},{ -84,  71},\n{  72,  73},{  74,  75},{  76,  77},{  -7,  78},{  79, -20},{  80,  81},{ -85,  82},{ -98,  83},\n{ -58,  84},{  85, -32},{ -99,  86},{  -8,  87},{  88,  89},{ -72, -45},{  90, -33},{  91,-112},\n{ -21,  92},{ -59,-113},{ -46,  93},{  -9,  94},{ -22,  95},{  96,  97},{  98,  99},{ -23, -86},\n{ 100, 101},{ -34, -73},{ 102,-126},{-127, -35},{ 103, -47},{ 104, 105},{ 106, 107},{-140,-100},\n{-114, -87},{ 108, 109},{ 110, 111},{-141, -60},{ 112, -48},{ 113, -24},{ -10, -61},{ 114,-101},\n{ 115, 116},{ -74, -36},{ 117,-128},{ 118, -62},{ 119, 120},{ -37, 121},{ -11, -49},{ -88, 122},\n{ 123,-115},{-154, -25},{-142, 124},{-155,-129},{ 125, -50},{ 126, 127},{ -76, -75},{ 128, 129},\n{ -63, -77},{-102, -39},{ -38, 130},{ -51, 131},{ -89,-116},{-117,-156},{ 132, -52},{ -78, 133},\n{ 134,-103},{ 135, 136},{-143, -65},{ 137, -64},{-130,-131},{ -90, 138},{-104, -91},{ -92, 139},\n{-169,-183},{ -26,-118},{ 140, 141},{-144, -66},{ -12, 142},{-168, 143},{-105,-157},{ 144,-182},\n{ 145, 146},{ -79, 147},{ -53,-170},{ 148, 149},{ -27,-145},{ 150, -80},{-106, -13},{-132, -67},\n{-158, -40},{-119, 151},{ 152,-107},{ 153, 154},{ -41,-184},{ 155, 156},{ -54, 157},{-171, 158},\n{ -94, 159},{-134,-146},{ -93,-133},{-159,-108},{ 160, -81},{ 161,-160},{ 162, -68},{-120,-122},\n{-172, 163},{ -55, -95},{ 164,-109},{-161, -82},{-173,-185},{ 165, -69},{-147,-186},{ 166, 167},\n{-121, -96},{ 168,-148},{-174, 169},{ 170,-136},{ -83, 171},{ 172, 173},{-135,-110},{-187, 174},\n{-149,-150},{ 175,-123},{-162,-163},{ -97,-175},{-188, 176},{ 177, 178},{ 179,-111},{-151,-124},\n{-137,-177},{-176,-125},{-164,-138},{-189,-190},};\nWord16 mlt_decoder_tree_category_1[93][2] = {\n{   1,   0},{   2,   3},{   4,   5},{   6,   7},{   8, -10},{  -1,   9},{  10,  11},{  12,  13},\n{ -11,  14},{  15,  16},{  17,  18},{ -20,  -2},{  19,  20},{ -21,  21},{  22,  23},{ -12,  24},\n{  25,  26},{  27,  28},{  29,  30},{ -30,  31},{ -31,  -3},{  32, -22},{  33, -13},{  34,  35},\n{  36,  37},{  38,  39},{  40,  -4},{ -41, -14},{  41, -40},{ -32,  42},{  43, -23},{  44,  45},\n{  46,  47},{  48,  -5},{ -51, -50},{ -42,  49},{ -33,  50},{ -15,  51},{  52,  53},{  54, -24},\n{  55, -43},{  56, -52},{  57, -61},{ -60,  58},{ -25,  59},{ -16, -34},{  -6,  60},{ -62,  61},\n{ -71,  62},{ -35,  -7},{  63, -72},{ -53, -17},{  64, -44},{ -26, -70},{  65, -45},{ -36,  66},\n{ -63,  67},{ -80, -54},{ -81,  68},{ -27,  69},{  70, -82},{ -18,  71},{  72, -55},{  73, -64},\n{  74, -73},{  75, -46},{ -37,  76},{ -91,  -8},{  -9,  77},{ -90, -83},{  78, -28},{  79, -56},\n{ -65, -38},{ -74,  80},{ -19, -57},{ -92,  81},{ -47, -48},{  82, -66},{  83, -29},{ -84,  84},\n{ -75, -85},{ -67, -93},{ -39,  85},{ -76,  86},{ -58,  87},{  88, -49},{ -94,  89},{  90, -68},\n{  91, -78},{ -86, -59},{ -77, -95},{  92, -69},{ -87, -96},};\nWord16 mlt_decoder_tree_category_2[47][2] = {\n{   1,   0},{   2,   3},{   4,   5},{   6,  -7},{  -1,   7},{  -8,   8},{   9,  10},{  11,  12},\n{  13, -14},{ -15,  -9},{  -2,  14},{  15,  16},{  17,  18},{  19, -16},{  20, -22},{ -10,  21},\n{ -21,  -3},{  22,  23},{  24,  25},{ -23, -17},{  26,  27},{  28, -29},{ -11, -28},{  29,  30},\n{  -4, -24},{ -30,  31},{  32, -18},{  33, -35},{ -36,  34},{ -31, -12},{  35, -25},{  -5, -37},\n{  36,  37},{ -42,  38},{ -19, -43},{ -32,  39},{ -13, -38},{ -26, -20},{  40,  -6},{ -44,  41},\n{  42, -39},{ -33, -45},{  43, -27},{  44, -46},{  45, -34},{ -40,  46},{ -41, -47},};\nWord16 mlt_decoder_tree_category_3[519][2] = {\n{   1,   2},{   3,   4},{   5,   0},{   6,   7},{   8,   9},{  10,  11},{  12,  13},{  14,  15},\n{  16,  17},{-125,  18},{  -1,  19},{  20,  21},{  22,  23},{  24,  25},{  -5, -25},{  26,  27},\n{  -6,-150},{  28,  29},{  30,  31},{  32,  33},{  34, -30},{  35,  36},{  37,  38},{  39, -31},\n{-126,-155},{  40,  41},{-156,  42},{  43,-130},{  44,-131},{-151, -26},{  45,  46},{-250,  47},\n{  48,  49},{  50,  51},{  52,-275},{  53,  54},{  -2,  -7},{  55,  56},{  57,  58},{  59,  60},\n{  61,  62},{  63,  64},{  65,  66},{  67,  68},{  69,  70},{  71, -50},{  72,-180},{  73,  74},\n{  75,  76},{  77, -55},{  78,-175},{  79, -36},{  80,  81},{ -35, -10},{  82,  83},{-280,  84},\n{ -11,  85},{  86, -32},{  87,  88},{  89,-161},{  90,-276},{  91,  92},{-281,  93},{  -8,  94},\n{  95,  96},{  97,-157},{-181,-400},{-132,  98},{-375,  99},{-160, 100},{-127, 101},{ -27, 102},\n{ 103,-251},{ -56, 104},{ 105,-256},{-300,  -3},{-152,-255},{ 106, 107},{ -37, 108},{-305, 109},\n{-176, 110},{-136, 111},{ -12, 112},{ 113, 114},{ 115,-135},{ 116, 117},{-162, 118},{ -16, -51},\n{-186, 119},{ 120, 121},{ 122, 123},{ -41, 124},{ -61, 125},{ 126, 127},{ 128, 129},{ 130, -60},\n{ 131, 132},{-306, 133},{ 134,-205},{-405, 135},{ 136, 137},{ 138, 139},{-185, 140},{ 141,-500},\n{ -15, 142},{ 143, -80},{ -75, -40},{-301, 144},{ 145, 146},{-200, 147},{ 148, 149},{ 150, 151},\n{ 152,-525},{ 153,-177},{-425, 154},{ 155, -13},{-430, 156},{ 157,-406},{ 158, 159},{-206,-380},\n{ 160, 161},{ 162, 163},{ 164,-182},{-137, 165},{-286, 166},{ 167,-401},{ 168, 169},{ -42, -33},\n{ 170,-166},{ -57,-325},{ 171,-187},{ -38, 172},{ 173, 174},{-165,-330},{  -4,-282},{ 175,-257},\n{-261,-311},{-376, 176},{ 177, 178},{ -28, 179},{ 180,  -9},{-285, 181},{ 182, 183},{ 184,-277},\n{ 185,-133},{-310, -81},{ -85, 186},{-158,-210},{ -17, 187},{ 188, 189},{ 190, -52},{-141, 191},\n{ 192,-128},{-191, -20},{ 193,-140},{ 194, 195},{-211,-260},{ 196, 197},{ 198, 199},{ 200, -66},\n{-201,-225},{-381, 201},{ 202, 203},{ 204, 205},{ 206, 207},{-163,-287},{ 208,-100},{ 209, 210},\n{ 211, 212},{ 213,-252},{-105, -76},{ 214, 215},{ 216, -21},{ -86, -62},{-307, 217},{ -65,-455},\n{-550, 218},{ 219, 220},{ 221, 222},{ 223, 224},{ 225,-230},{-142, 226},{-302,-426},{-431, 227},\n{ 228, 229},{ 230,-190},{-402, -46},{-153,-450},{-505, 231},{ 232, 233},{ 234, 235},{ 236, 237},\n{ 238, 239},{-262, -29},{ 240, 241},{ 242, 243},{-167, -67},{-331,-530},{ 244, 245},{ 246, 247},\n{ 248, 249},{ 250, 251},{ 252, 253},{ 254, 255},{ 256, 257},{ 258, 259},{ 260, 261},{ 262,-336},\n{ 263,-171},{-192,-207},{-258,-138},{ 264, 265},{ 266, 267},{ 268, 269},{ 270, 271},{ 272, 273},\n{ 274, -45},{-335,-411},{ -43, -18},{-265, -71},{-316,-326},{-350,-407},{-146, -14},{ 275, 276},\n{ 277, 278},{ 279, 280},{ 281,-216},{ -34,-283},{-291,-312},{-410,-168},{-555, 282},{ -70, -53},\n{-235, -87},{ -77,-183},{-315,-332},{-178, -58},{ 283, 284},{ 285, 286},{ 287, 288},{ 289, 290},\n{ 291, 292},{ 293, 294},{ 295, 296},{ 297, 298},{-202,-226},{-170,-267},{-134,-290},{-355,-385},\n{-386, -47},{-526,-196},{ 299, 300},{ 301, 302},{ 303, 304},{ 305, 306},{ 307, 308},{ 309, 310},\n{ 311, 312},{ 313, 314},{ 315, 316},{ 317, 318},{ 319, 320},{ 321, 322},{ 323, 324},{ 325,-111},\n{-231,-253},{ -91, -82},{-172,-145},{ -22,-317},{ -90,-356},{-382,-159},{ 326, 327},{ 328, 329},\n{ 330, 331},{ 332, 333},{ 334, 335},{-106,-263},{-278,-215},{-110, -39},{-101,-377},{-129, -63},\n{-436,-195},{-506,-531},{ 336,-212},{-154,-266},{ -59,-288},{-292,-303},{-337,-432},{-188,-451},\n{-456,-460},{-501,-236},{-551, 337},{ 338, 339},{ 340, 341},{ 342, 343},{ 344, 345},{ 346, 347},\n{ 348, 349},{ 350, 351},{ 352, 353},{ 354, 355},{ 356, 357},{ 358, 359},{ 360, 361},{ 362, 363},\n{ 364, 365},{ 366, 367},{ 368, 369},{ 370, 371},{ 372, 373},{ 374, 375},{ 376, 377},{ 378, 379},\n{ 380, 381},{ 382, 383},{ 384, 385},{ 386, 387},{ 388, 389},{ 390, 391},{ 392, 393},{ 394, 395},\n{ 396, 397},{ 398, 399},{ 400, 401},{ 402, 403},{ 404, 405},{ 406, 407},{ -72,-272},{-309,-333},\n{-340,-360},{ -68,-387},{-184,-416},{-427,-147},{-435,-437},{-115,-480},{-510,-532},{-164,-556},\n{ 408,-295},{-296,-297},{-107,-313},{-193,-173},{-320,-327},{-341,-351},{-352,-143},{-378, -19},\n{-403,-412},{-268, -54},{ -83,-441},{-442,-457},{-475, -44},{ -97,-511},{-515,-208},{-527,-528},\n{-237,-536},{-552, 409},{ 410, 411},{ 412, 413},{ 414, 415},{ 416, 417},{ 418, 419},{ 420, 421},\n{ 422, 423},{ 424, 425},{ 426, 427},{ 428, 429},{ 430, 431},{ 432, 433},{ 434, 435},{ 436, 437},\n{ 438, 439},{ 440, 441},{ 442, 443},{ 444, 445},{ 446, 447},{ 448, 449},{ 450, 451},{ 452, 453},\n{ 454, 455},{ 456, 457},{ 458, 459},{ 460, 461},{ 462, 463},{ 464, 465},{ 466, 467},{ 468, 469},\n{ 470, 471},{ 472, 473},{ 474, 475},{ 476, 477},{ 478, 479},{ 480, 481},{ 482, 483},{ 484, 485},\n{ 486, 487},{ 488, 489},{ 490, 491},{ 492, 493},{ 494, 495},{ 496, 497},{ 498, 499},{ 500, 501},\n{ 502, 503},{ 504, 505},{ 506, 507},{ 508, 509},{ 510, 511},{ 512, 513},{ 514, 515},{ 516, 517},\n{ 518,-104},{ -84,-218},{-318,-319},{-117,-321},{-322,-323},{-219,-174},{-243,-328},{-329, -94},\n{-228,-194},{-240,-334},{-102,-229},{-169,-338},{-339,-116},{-289,-342},{-343,-345},{-346,-347},\n{ -23,-203},{-214,-353},{-204,-220},{-357,-358},{-264,-361},{-362,-363},{-365,-366},{-367, -92},\n{-245,-121},{-293,-379},{-108,-232},{-221,-383},{-384,-233},{-294,-241},{-388,-389},{-390,-391},\n{-392,-393},{-394,-395},{-396,-397},{-398, -24},{-109,-149},{-242,-404},{ -64, -79},{ -89,-408},\n{-409,-213},{-120,-113},{-413,-414},{-415, -96},{-417,-418},{-419,-420},{-421,-422},{-423,-298},\n{ -69,-269},{-428,-429},{ -78,-270},{ -88,-433},{-434,-271},{-234,-259},{-438,-439},{-440,-227},\n{-179,-443},{-445,-446},{-447,-223},{-238,-452},{-453,-454},{-273,-254},{-246,-458},{-459, -48},\n{-461,-462},{-463,-465},{-466,-467},{-468,-470},{-471,-304},{-476,-477},{-478,-112},{-481,-482},\n{-483,-485},{-486,-487},{-490,-491},{-103,-118},{-502,-503},{-504,-189},{ -93,-507},{-508,-509},\n{-148,-139},{-512,-513},{-308,-516},{-517,-518},{-520,-521},{ -73, -98},{ -95, -49},{-529,-222},\n{-217,-197},{-533,-534},{-535,-284},{-537,-538},{-540,-541},{-542,-543},{-545,-546},{-144,-198},\n{-314,-553},{-209,-279},{-557,-558},{-560,-561},{-562,-563},{-565,-566},{-567,-575},{-576,-577},\n{-578,-580},{-581,-582},{-583,-585},{-586,-587},{-590,-591},{-600,-601},{-605,-606},};\nWord16 mlt_decoder_tree_category_4[208][2] = {\n{   1,   2},{   3,   0},{   4,   5},{   6,   7},{   8,   9},{  10,  11},{  12, -64},{  -1,  13},\n{  14, -16},{  -4,  15},{  16,  17},{  18, -80},{  -5,  19},{  20,  21},{ -20,  22},{  23, -65},\n{ -84, -21},{ -68,  24},{ -17,  25},{  26,  27},{  28, -81},{ -69, -85},{  29,  30},{  31,  32},\n{-128,  33},{  34,  35},{  -2,  36},{  37,  38},{-144,  39},{  40,  -6},{  41,  42},{ -32,  43},\n{  44,  -8},{  45, -25},{ -96,  46},{  47,-100},{  -9,  48},{  49, -36},{  50, -24},{  51,  52},\n{  53,-148},{  54,  55},{ -22,  56},{  57,  58},{-132, -89},{  59,  60},{-101,  61},{ -37,  62},\n{ -18,  63},{ -88,-129},{ -66, -70},{ -97,  64},{ -72, -73},{  65,-145},{-149, -86},{  66, -33},\n{  67,-133},{  68,  69},{  70,  71},{-192,  72},{  73,-160},{ -82,  74},{-164,  75},{ -10,  76},\n{  77,-208},{  78, -40},{  79,  80},{  -3,  81},{  -7,  82},{  83,  84},{-104,  85},{  86, -26},\n{  87,-105},{  88,-112},{  89,  90},{  91, -41},{  92,  93},{  94,  95},{ -48,  96},{ -90,  97},\n{  98, -28},{ -52,  99},{ -12, 100},{ 101, -74},{ -13,-116},{-161, 102},{ 103, -29},{-102, 104},\n{-152,-165},{ 105, 106},{ 107, 108},{ 109, 110},{ 111,-212},{ 112, 113},{-136, 114},{ 115,-137},\n{ 116, -23},{ -19,-153},{ -98,-134},{-196, 117},{ 118, 119},{ -38,-193},{-113,-150},{-209, 120},\n{ 121, -93},{ -83, 122},{ 123, 124},{ 125, 126},{ 127, 128},{ 129, 130},{ 131, -34},{-146, -53},\n{ 132, 133},{ 134, 135},{ 136, 137},{ 138,-130},{ -49, 139},{ 140, 141},{-117, -42},{ -67, -92},\n{ 142, -87},{ -77,-197},{ -71, 143},{ 144, 145},{ 146, 147},{ 148, 149},{ 150, 151},{ 152, 153},\n{ 154, 155},{ 156, 157},{ 158, 159},{ 160, 161},{ 162, 163},{ 164, 165},{ 166, 167},{ 168, 169},\n{-108, -76},{-168,-169},{-176, -44},{-224, -56},{ -45,-180},{ -11,-106},{-213, 170},{ 171, 172},\n{ 173, 174},{ 175, 176},{ 177, 178},{ 179, 180},{ 181, 182},{ 183, 184},{ 185, 186},{ 187, 188},\n{ 189, 190},{ 191, 192},{ 193, 194},{ 195, 196},{ 197, 198},{ 199, 200},{ 201, 202},{ 203, 204},\n{ 205, 206},{ 207,-131},{ -30, -27},{ -43,-151},{ -75,-154},{-156,-162},{-109,-194},{-198,-201},\n{-114,-225},{-228,-229},{-141,-142},{ -94,-124},{ -95,-147},{-115,-125},{ -54, -55},{-107, -58},\n{ -39,-155},{-121,-157},{-158,-103},{ -14,-122},{-163, -51},{ -57,-166},{-167, -46},{-110,-170},\n{-172,-173},{ -61,-177},{-178, -99},{-181,-182},{-184,-185},{-118, -35},{ -15,-195},{ -31, -60},\n{-135,-199},{-200, -79},{-202,-204},{-205,-119},{ -91,-210},{-211, -78},{-120,-214},{-215,-216},\n{-217,-218},{-220,-221},{ -50,-138},{-226,-139},{-140,-230},{-232,-233},{-240,-241},{-244,-245},\n};\nWord16 mlt_decoder_tree_category_5[191][2] = {\n{   1,   2},{   0,   3},{   4,   5},{   6,   7},{   8,   9},{  10,  11},{ -81,  -1},{  12,  13},\n{  14, -27},{  -3,  -9},{  15,  16},{  17,  18},{  19,  20},{-108,  21},{  -4,  22},{  23, -36},\n{ -12,  24},{ -82,  25},{  26, -84},{  27, -90},{ -10, -30},{  28,  29},{  30, -28},{  31,-117},\n{ -13,  32},{ -39,  33},{  34,-109},{  35, -93},{ -85,-111},{ -37,  36},{ -31,  37},{ -91,  38},\n{  39,  40},{ -40,-120},{  41,  42},{-118,  43},{ -94,  44},{-112,-162},{  45,  46},{  -2,  47},\n{  48,  49},{-121,-189},{  50, -54},{  51,  52},{  53, -18},{  54,  55},{  -6,  56},{  57,  -5},\n{-135,  58},{  59,  60},{  61,  62},{ -63,  63},{  64,  -7},{ -15,  65},{  66,  67},{ -45,  68},\n{  69,  70},{  71, -21},{  72,  73},{  74,  75},{  76,  77},{-163,  78},{  79,-171},{-144,  80},\n{ -48,  81},{ -57,  82},{  83,  84},{-165,  85},{ -16,-198},{  86,  87},{ -11,  88},{  89, -99},\n{  90, -83},{ -19,  91},{  92,  93},{  94,  95},{  96,  97},{  98,  99},{ -87, 100},{ 101, 102},\n{-190, -66},{ -33,-192},{ 103, 104},{ 105, 106},{-102, -42},{ 107,-126},{ 108, -29},{-129, -46},\n{ -86, -14},{-114, -32},{-172, 109},{ 110, -58},{ -34,-138},{ 111, 112},{ 113, 114},{ 115, 116},\n{ 117, 118},{ 119, 120},{-127,-166},{-174, 121},{ 122, 123},{ 124, 125},{ -88, -96},{ 126,-100},\n{ -38,-110},{ -22,-136},{ -55,-139},{-201, 127},{ -64,-193},{ 128, -49},{-175,-199},{ 129, 130},\n{ 131, 132},{ 133, 134},{ 135, 136},{ 137, 138},{ 139, 140},{ 141, 142},{ 143, 144},{ 145, 146},\n{ 147, 148},{ 149, 150},{-103, -92},{ -43,-130},{-145,-147},{-148, -41},{-216,-115},{-119,-123},\n{ -95, 151},{ 152, 153},{ 154, 155},{ 156, 157},{ 158, 159},{ 160, 161},{ 162, 163},{ 164, 165},\n{ 166, 167},{ 168, 169},{ 170, 171},{ 172, 173},{ 174, 175},{ 176, 177},{ 178, 179},{ 180, 181},\n{ 182, 183},{ 184, 185},{ 186, 187},{ 188, 189},{ 190,-153},{-180,  -8},{ -97, -24},{-122,-113},\n{-124,-125},{ -67, -44},{-128, -69},{-106,-131},{-132,-133},{ -61, -73},{-137,-116},{ -89,-140},\n{-141,-142},{ -23, -25},{-146, -17},{-104,-149},{-150,-151},{ -52,-154},{-156,-157},{ -76, -70},\n{-164, -51},{ -72,-167},{-168,-169},{ -47, -20},{-173, -59},{-101,-176},{-177,-178},{ -68,-181},\n{-183,-184},{ -35, -60},{-191, -98},{ -56,-194},{-195,-196},{ -75, -65},{-200,-105},{-202,-203},\n{-204,-205},{-207,-208},{-210,-211},{ -50,-217},{-219,-220},{-225,-226},{-228,-229},};\nWord16 mlt_decoder_tree_category_6[31][2] = {\n{   1,   0},{   2,   3},{   4,   5},{   6,   7},{   8, -16},{  -1,  -8},{  -2,  -4},{   9,  10},\n{  11,  12},{  13,  14},{  15,  16},{  17, -24},{  -3, -12},{  -6,  18},{  19, -20},{ -10,  -5},\n{ -17,  -9},{ -18,  20},{  21,  22},{  23,  24},{  25, -28},{  26,  -7},{ -14, -22},{ -26, -11},\n{  27, -19},{ -25, -13},{ -21,  28},{  29, -30},{ -27,  30},{ -15, -29},{ -23, -31},};\n\nWord16 *table_of_decoder_tables[NUM_CATEGORIES-1] = {\n(Word16 *)mlt_decoder_tree_category_0,\n(Word16 *)mlt_decoder_tree_category_1,\n(Word16 *)mlt_decoder_tree_category_2,\n(Word16 *)mlt_decoder_tree_category_3,\n(Word16 *)mlt_decoder_tree_category_4,\n(Word16 *)mlt_decoder_tree_category_5,\n(Word16 *)mlt_decoder_tree_category_6,\n};\n\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/common/huff_tab.h",
    "content": "/***********************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**   All rights reserved.\n**\n***********************************************************************/\n\nextern Word16  differential_region_power_bits[MAX_NUMBER_OF_REGIONS][DIFF_REGION_POWER_LEVELS];\nextern UWord16 differential_region_power_codes[MAX_NUMBER_OF_REGIONS][DIFF_REGION_POWER_LEVELS];\nextern Word16  differential_region_power_decoder_tree[MAX_NUMBER_OF_REGIONS][DIFF_REGION_POWER_LEVELS-1][2];\nextern Word16  mlt_quant_centroid[NUM_CATEGORIES][MAX_NUM_BINS];\nextern Word16  expected_bits_table[NUM_CATEGORIES];\nextern Word16  mlt_sqvh_bitcount_category_0[196];\nextern UWord16 mlt_sqvh_code_category_0[196];\nextern Word16  mlt_sqvh_bitcount_category_1[100];\nextern UWord16 mlt_sqvh_code_category_1[100];\nextern Word16  mlt_sqvh_bitcount_category_2[49];\nextern UWord16 mlt_sqvh_code_category_2[49];\nextern Word16  mlt_sqvh_bitcount_category_3[625];\nextern UWord16 mlt_sqvh_code_category_3[625];\nextern Word16  mlt_sqvh_bitcount_category_4[256];\nextern UWord16 mlt_sqvh_code_category_4[256];\nextern Word16  mlt_sqvh_bitcount_category_5[243];\nextern UWord16 mlt_sqvh_code_category_5[243];\nextern Word16  mlt_sqvh_bitcount_category_6[32];\nextern UWord16 mlt_sqvh_code_category_6[32];\nextern Word16  *table_of_bitcount_tables[NUM_CATEGORIES-1];\nextern UWord16 *table_of_code_tables[NUM_CATEGORIES-1];\nextern Word16  mlt_decoder_tree_category_0[180][2];\nextern Word16  mlt_decoder_tree_category_1[93][2];\nextern Word16  mlt_decoder_tree_category_2[47][2];\nextern Word16  mlt_decoder_tree_category_3[519][2];\nextern Word16  mlt_decoder_tree_category_4[208][2];\nextern Word16  mlt_decoder_tree_category_5[191][2];\nextern Word16  mlt_decoder_tree_category_6[31][2];\nextern Word16  *table_of_decoder_tables[NUM_CATEGORIES-1];\n\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/common/tables.c",
    "content": "/****************************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**   All rights reserved.\n**\n****************************************************************************/\n\n/****************************************************************************\n  Filename:    tables.c    \n\n  Purpose:     Contains tables used by G.722.1 Annex C\n\t\t\n  Design Notes:\n\n****************************************************************************/\n\n/***************************************************************************\n Include files                                                           \n***************************************************************************/\n#include \"defs.h\"\n\nWord16 int_region_standard_deviation_table[REGION_POWER_TABLE_SIZE] = {\n    0,     0,   0, 0, 0, 0, 0, 0, 0, 0,\n    0,     0,   0, 0, 0, 0, 0, 0, 0, 0,\n    0,     0,   1, 1, 1, 1, 2, 3, 4, 6,\n    8,    11,   16, 23, 32, 45, 64, 91, 128, 181,\n  256,   362,  512, 724, 1024, 1448, 2048, 2896, 4096, 5793,\n 8192, 11585, 16384, 23170, 0,0,0,0,0,0,\n 0,0,0,0};\n\nWord16 standard_deviation_inverse_table[REGION_POWER_TABLE_SIZE] = {\n  32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,\n  32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,\n  32767, 32767, 32767, 32767, 32767, 23170, 16384, 11585, 8192, 5793,\n  4096, 2896, 2048, 1448, 1024, 724, 512, 362, 256, 181,\n  128, 91, 64, 45, 32, 23, 16, 11, 8, 6,\n  4, 3, 2, 1, 1, 1, 1, 0, 0, 0,\n  0, 0, 0, 0};\n\n\nWord16 step_size_inverse_table[NUM_CATEGORIES]={\n\t23167,16384,11585,8192,5793,4096,2896,2896\n};\n \n\nWord16 vector_dimension[NUM_CATEGORIES] =  { 2, 2, 2, 4, 4, 5, 5, 1};\nWord16 number_of_vectors[NUM_CATEGORIES] = {10,10,10, 5, 5, 4, 4,20};\n/* The last category isn't really coded with scalar quantization. */\n\nWord16 max_bin[NUM_CATEGORIES] = {13, 9, 6, 4, 3, 2, 1, 1};\n\nWord16 max_bin_plus_one_inverse[NUM_CATEGORIES] = \n{\n\t2341,3277,4682,6554,8193,10923,16385,16385\n};\n\n/*\n * Release 1.2.\n * Add new version of int_dead_zone[] to go with\n * changes to vector_huffman() in encoder.c.\n * \n */\n\n/************** See new version of table below\nWord16 int_dead_zone[NUM_CATEGORIES]=\n{\n\t9830,10813,11796,12780,13763,14746,16384,16384\n};\n***************/\n\n/******** New version of table added in Release 1.2 ********/\nWord16 int_dead_zone[NUM_CATEGORIES]=         \n{\n2457, 2703, 2949, 3195, 3440, 3686, 4096, 4096\n};\n\n \n/*\n * Release 1.2.\n * Added this new table to go with\n * changes to vector_huffman() in encoder.c,\n * accompanies the new table for int_dead_zone[].\n */\n\nWord16 int_dead_zone_low_bits[NUM_CATEGORIES]=\n{\n2, 1, 0, 0, 3, 2, 0, 0\n};\n\n\nWord16 samples_to_rmlt_window[DCT_LENGTH]=\n{   44,   134,   224,   314,   404,   494,   584,   674,   764,   853,\n   943,  1033,  1123,  1213,  1302,  1392,  1482,  1571,  1661,  1750,\n  1840,  1929,  2019,  2108,  2197,  2286,  2376,  2465,  2554,  2643,\n  2732,  2821,  2909,  2998,  3087,  3175,  3264,  3352,  3441,  3529,\n  3617,  3705,  3793,  3881,  3969,  4057,  4144,  4232,  4319,  4407,\n  4494,  4581,  4668,  4755,  4842,  4928,  5015,  5101,  5188,  5274,\n  5360,  5446,  5532,  5617,  5703,  5788,  5873,  5959,  6043,  6128,\n  6213,  6297,  6382,  6466,  6550,  6634,  6718,  6801,  6885,  6968,\n  7051,  7134,  7217,  7299,  7382,  7464,  7546,  7628,  7709,  7791,\n  7872,  7953,  8034,  8115,  8195,  8276,  8356,  8436,  8515,  8595,\n  8674,  8753,  8832,  8911,  8989,  9068,  9146,  9223,  9301,  9378,\n  9455,  9532,  9609,  9685,  9762,  9838,  9913,  9989, 10064, 10139,\n 10214, 10288, 10363, 10437, 10510, 10584, 10657, 10730, 10803, 10875,\n 10948, 11020, 11091, 11163, 11234, 11305, 11375, 11446, 11516, 11586,\n 11655, 11724, 11793, 11862, 11930, 11998, 12066, 12134, 12201, 12268,\n 12334, 12401, 12467, 12532, 12598, 12663, 12728, 12792, 12857, 12920,\n 12984, 13047, 13110, 13173, 13235, 13297, 13359, 13420, 13481, 13542,\n 13602, 13662, 13722, 13782, 13841, 13899, 13958, 14016, 14074, 14131,\n 14188, 14245, 14301, 14357, 14413, 14468, 14523, 14578, 14632, 14686,\n 14739, 14793, 14845, 14898, 14950, 15002, 15053, 15104, 15155, 15205,\n 15255, 15305, 15354, 15403, 15451, 15500, 15547, 15595, 15642, 15688,\n 15734, 15780, 15826, 15871, 15916, 15960, 16004, 16047, 16091, 16133,\n 16176, 16218, 16259, 16300, 16341, 16382, 16422, 16461, 16501, 16540,\n 16578, 16616, 16654, 16691, 16728, 16764, 16800, 16836, 16871, 16906,\n 16940, 16974, 17008, 17041, 17074, 17106, 17138, 17170, 17201, 17232,\n 17262, 17292, 17321, 17350, 17379, 17407, 17435, 17462, 17489, 17516,\n 17542, 17567, 17593, 17617, 17642, 17666, 17689, 17713, 17735, 17758,\n 17779, 17801, 17822, 17842, 17863, 17882, 17901, 17920, 17939, 17957,\n 17974, 17991, 18008, 18024, 18040, 18055, 18070, 18085, 18099, 18113,\n 18126, 18139, 18151, 18163, 18174, 18185, 18196, 18206, 18216, 18225,\n 18234, 18242, 18250, 18257, 18265, 18271, 18277, 18283, 18288, 18293,\n 18298, 18302, 18305, 18308, 18311, 18313, 18315, 18316, 18317, 18317,\n};\n\nWord16 rmlt_to_samples_window[DCT_LENGTH]=\n{  44,    133,   222,   310,   399,   488,   577,   666,   754,   843,\n   932,   1020,  1109,  1198,  1286,  1375,  1464,  1552,  1641,  1729,\n   1817,  1906,  1994,  2082,  2171,  2259,  2347,  2435,  2523,  2611,\n   2699,  2786,  2874,  2962,  3049,  3137,  3224,  3312,  3399,  3486,\n   3573,  3660,  3747,  3834,  3921,  4008,  4094,  4181,  4267,  4353,\n   4439,  4526,  4611,  4697,  4783,  4869,  4954,  5040,  5125,  5210,\n   5295,  5380,  5465,  5549,  5634,  5718,  5802,  5886,  5970,  6054,\n   6138,  6221,  6304,  6388,  6471,  6553,  6636,  6719,  6801,  6883,\n   6965,  7047,  7129,  7211,  7292,  7373,  7454,  7535,  7616,  7696,\n   7777,  7857,  7937,  8016,  8096,  8175,  8254,  8333,  8412,  8491,\n   8569,  8647,  8725,  8803,  8880,  8957,  9035,  9111,  9188,  9264,\n   9341,  9417,  9492,  9568,  9643,  9718,  9793,  9868,  9942, 10016,\n  10090, 10163, 10237, 10310, 10383, 10455, 10528, 10600, 10672, 10743,\n  10815, 10886, 10957, 11027, 11098, 11168, 11237, 11307, 11376, 11445,\n  11514, 11582, 11650, 11718, 11785, 11853, 11920, 11986, 12053, 12119,\n  12185, 12250, 12315, 12380, 12445, 12509, 12573, 12637, 12701, 12764,\n  12826, 12889, 12951, 13013, 13075, 13136, 13197, 13257, 13318, 13378,\n  13437, 13497, 13556, 13614, 13673, 13731, 13788, 13846, 13903, 13959,\n  14016, 14072, 14128, 14183, 14238, 14292, 14347, 14401, 14454, 14508,\n  14561, 14613, 14665, 14717, 14769, 14820, 14871, 14921, 14971, 15021,\n  15070, 15119, 15168, 15216, 15264, 15311, 15359, 15405, 15452, 15498,\n  15544, 15589, 15634, 15678, 15722, 15766, 15810, 15853, 15895, 15938,\n  15979, 16021, 16062, 16103, 16143, 16183, 16223, 16262, 16300, 16339,\n  16377, 16414, 16452, 16488, 16525, 16561, 16596, 16632, 16666, 16701,\n  16735, 16768, 16801, 16834, 16867, 16899, 16930, 16961, 16992, 17022,\n  17052, 17082, 17111, 17140, 17168, 17196, 17223, 17250, 17277, 17303,\n  17329, 17354, 17379, 17404, 17428, 17452, 17475, 17498, 17520, 17542,\n  17564, 17585, 17606, 17626, 17646, 17665, 17684, 17703, 17721, 17739,\n  17756, 17773, 17790, 17806, 17821, 17836, 17851, 17865, 17879, 17893,\n  17906, 17918, 17931, 17942, 17954, 17965, 17975, 17985, 17995, 18004,\n  18012, 18021, 18028, 18036, 18043, 18049, 18055, 18061, 18066, 18071,\n  18076, 18079, 18083, 18086, 18089, 18091, 18093, 18094, 18095, 18095,\n};\n\nWord16 max_samples_to_rmlt_window[MAX_DCT_LENGTH]={\n0,\t\t43,\t\t89,\t\t133,\t178,\t222,\t268,\t314,\t357,\t403,\n447,\t493,\t538,\t582,\t628,\t671,\t717,\t763,\t807,\t853,\n896,\t942,\t987,\t1031,\t1077,\t1121,\t1166,\t1212,\t1256,\t1301,\n1345,\t1390,\t1436,\t1480,\t1526,\t1569,\t1615,\t1660,\t1704,\t1749,\n1793,\t1838,\t1884,\t1928,\t1973,\t2016,\t2062,\t2107,\t2151,\t2196,\n2239,\t2285,\t2331,\t2374,\t2419,\t2463,\t2508,\t2553,\t2597,\t2642,\n2685,\t2730,\t2776,\t2819,\t2864,\t2908,\t2952,\t2998,\t3041,\t3086,\n3129,\t3174,\t3219,\t3263,\t3307,\t3350,\t3396,\t3440,\t3483,\t3528,\n3571,\t3616,\t3661,\t3704,\t3748,\t3791,\t3836,\t3881,\t3923,\t3968,\n4011,\t4055,\t4100,\t4143,\t4187,\t4230,\t4274,\t4318,\t4362,\t4406,\n4448,\t4493,\t4537,\t4580,\t4624,\t4666,\t4710,\t4755,\t4797,\t4841,\n4883,\t4927,\t4971,\t5013,\t5057,\t5099,\t5144,\t5187,\t5229,\t5273,\n5315,\t5359,\t5402,\t5444,\t5488,\t5530,\t5573,\t5617,\t5658,\t5702,\n5743,\t5787,\t5830,\t5871,\t5915,\t5956,\t6000,\t6043,\t6084,\t6127,\n6169,\t6211,\t6254,\t6296,\t6339,\t6380,\t6423,\t6465,\t6507,\t6549,\n6590,\t6633,\t6675,\t6716,\t6759,\t6799,\t6842,\t6884,\t6925,\t6967,\n7007,\t7050,\t7092,\t7132,\t7175,\t7215,\t7257,\t7299,\t7339,\t7381,\n7421,\t7462,\t7504,\t7544,\t7586,\t7626,\t7667,\t7709,\t7749,\t7790,\n7830,\t7871,\t7912,\t7952,\t7993,\t8032,\t8073,\t8114,\t8153,\t8194,\n8234,\t8275,\t8315,\t8355,\t8395,\t8434,\t8474,\t8515,\t8554,\t8594,\n8632,\t8673,\t8713,\t8752,\t8792,\t8830,\t8871,\t8910,\t8949,\t8989,\n9027,\t9066,\t9106,\t9144,\t9184,\t9221,\t9261,\t9300,\t9338,\t9378,\n9415,\t9454,\t9493,\t9531,\t9570,\t9607,\t9646,\t9685,\t9722,\t9761,\n9798,\t9836,\t9875,\t9912,\t9950,\t9987,\t10025,\t10064,\t10100,\t10138,\n10175,\t10213,\t10250,\t10287,\t10325,\t10361,\t10398,\t10436,\t10472,\t10510,\n10545,\t10583,\t10620,\t10656,\t10692,\t10728,\t10766,\t10803,\t10838,\t10874,\n10910,\t10947,\t10983,\t11018,\t11055,\t11089,\t11126,\t11162,\t11197,\t11233,\n11268,\t11303,\t11340,\t11374,\t11410,\t11444,\t11480,\t11515,\t11549,\t11585,\n11619,\t11654,\t11689,\t11723,\t11758,\t11791,\t11826,\t11861,\t11895,\t11930,\n11963,\t11997,\t12032,\t12065,\t12099,\t12132,\t12166,\t12201,\t12233,\t12267,\n12300,\t12333,\t12367,\t12400,\t12433,\t12465,\t12499,\t12532,\t12563,\t12597,\n12629,\t12662,\t12695,\t12727,\t12759,\t12790,\t12823,\t12856,\t12887,\t12920,\n12951,\t12983,\t13016,\t13046,\t13078,\t13109,\t13141,\t13173,\t13203,\t13235,\n13266,\t13296,\t13328,\t13358,\t13389,\t13419,\t13450,\t13481,\t13510,\t13541,\n13571,\t13602,\t13632,\t13661,\t13692,\t13721,\t13751,\t13781,\t13810,\t13840,\n13869,\t13898,\t13929,\t13957,\t13986,\t14015,\t14044,\t14073,\t14101,\t14130,\n14158,\t14187,\t14216,\t14244,\t14272,\t14300,\t14328,\t14357,\t14384,\t14412,\n14439,\t14468,\t14495,\t14522,\t14550,\t14577,\t14604,\t14632,\t14658,\t14686,\n14711,\t14739,\t14765,\t14792,\t14819,\t14844,\t14871,\t14897,\t14923,\t14949,\n14975,\t15001,\t15027,\t15053,\t15079,\t15103,\t15129,\t15155,\t15180,\t15205,\n15229,\t15255,\t15280,\t15304,\t15329,\t15353,\t15378,\t15403,\t15426,\t15451,\n15475,\t15499,\t15523,\t15546,\t15570,\t15594,\t15618,\t15641,\t15664,\t15688,\n15711,\t15734,\t15757,\t15780,\t15802,\t15825,\t15848,\t15871,\t15892,\t15915,\n15937,\t15960,\t15982,\t16003,\t16026,\t16047,\t16069,\t16090,\t16112,\t16133,\n16154,\t16175,\t16197,\t16217,\t16239,\t16259,\t16279,\t16301,\t16320,\t16341,\n16361,\t16382,\t16402,\t16421,\t16441,\t16461,\t16481,\t16501,\t16520,\t16539,\n16558,\t16578,\t16597,\t16615,\t16635,\t16653,\t16672,\t16691,\t16709,\t16728,\n16746,\t16764,\t16782,\t16800,\t16818,\t16835,\t16853,\t16871,\t16888,\t16905,\n16923,\t16940,\t16957,\t16974,\t16991,\t17008,\t17024,\t17041,\t17057,\t17074,\n17090,\t17106,\t17122,\t17138,\t17154,\t17169,\t17185,\t17201,\t17216,\t17231,\n17246,\t17262,\t17277,\t17291,\t17306,\t17321,\t17336,\t17350,\t17364,\t17379,\n17393,\t17407,\t17421,\t17435,\t17449,\t17462,\t17476,\t17490,\t17502,\t17515,\n17528,\t17542,\t17554,\t17567,\t17580,\t17592,\t17605,\t17618,\t17629,\t17642,\n17653,\t17666,\t17678,\t17689,\t17701,\t17712,\t17724,\t17736,\t17746,\t17757,\n17768,\t17779,\t17790,\t17800,\t17811,\t17822,\t17832,\t17842,\t17852,\t17862,\n17872,\t17882,\t17892,\t17902,\t17911,\t17920,\t17930,\t17938,\t17947,\t17956,\n17965,\t17974,\t17983,\t17991,\t17999,\t18008,\t18016,\t18025,\t18032,\t18040,\n18047,\t18055,\t18063,\t18070,\t18078,\t18085,\t18092,\t18099,\t18106,\t18112,\n18119,\t18126,\t18132,\t18138,\t18144,\t18151,\t18157,\t18163,\t18168,\t18174,\n18179,\t18185,\t18191,\t18196,\t18201,\t18206,\t18211,\t18216,\t18220,\t18225,\n18229,\t18234,\t18238,\t18242,\t18246,\t18250,\t18254,\t18257,\t18260,\t18264,\n18268,\t18271,\t18274,\t18277,\t18280,\t18283,\t18286,\t18288,\t18291,\t18293,\n18295,\t18297,\t18300,\t18301,\t18303,\t18305,\t18306,\t18308,\t18309,\t18311,\n18312,\t18312,\t18314,\t18315,\t18315,\t18316,\t18316,\t18317,\t18317,\t18317\n};\n\nWord16 max_rmlt_to_samples_window[MAX_DCT_LENGTH]={\n0,\t\t43,\t\t88,\t\t131,\t176,\t219,\t265,\t310,\t353,\t398,\n442,\t487,\t532,\t575,\t620,\t663,\t709,\t754,\t797,\t842,\n885,\t931,\t975,\t1019,\t1064,\t1107,\t1152,\t1197,\t1240,\t1286,\n1329,\t1373,\t1419,\t1462,\t1507,\t1550,\t1595,\t1640,\t1683,\t1728,\n1771,\t1816,\t1861,\t1904,\t1949,\t1992,\t2037,\t2081,\t2125,\t2170,\n2212,\t2258,\t2302,\t2345,\t2390,\t2433,\t2477,\t2522,\t2565,\t2610,\n2652,\t2697,\t2742,\t2784,\t2829,\t2872,\t2916,\t2961,\t3004,\t3048,\n3091,\t3136,\t3180,\t3223,\t3267,\t3310,\t3354,\t3399,\t3441,\t3485,\n3528,\t3572,\t3616,\t3659,\t3703,\t3745,\t3790,\t3834,\t3876,\t3920,\n3962,\t4006,\t4050,\t4093,\t4136,\t4179,\t4222,\t4266,\t4309,\t4352,\n4394,\t4438,\t4482,\t4524,\t4568,\t4610,\t4653,\t4697,\t4739,\t4782,\n4824,\t4867,\t4911,\t4953,\t4996,\t5038,\t5081,\t5124,\t5166,\t5209,\n5251,\t5294,\t5337,\t5378,\t5421,\t5463,\t5506,\t5548,\t5590,\t5633,\n5674,\t5717,\t5759,\t5800,\t5843,\t5884,\t5927,\t5970,\t6011,\t6053,\n6094,\t6136,\t6178,\t6219,\t6262,\t6302,\t6345,\t6387,\t6428,\t6470,\n6510,\t6552,\t6594,\t6635,\t6677,\t6717,\t6759,\t6801,\t6841,\t6883,\n6922,\t6964,\t7006,\t7046,\t7087,\t7127,\t7169,\t7210,\t7250,\t7291,\n7331,\t7372,\t7413,\t7453,\t7494,\t7533,\t7574,\t7615,\t7655,\t7695,\n7735,\t7776,\t7816,\t7855,\t7896,\t7935,\t7975,\t8016,\t8054,\t8095,\n8134,\t8174,\t8214,\t8253,\t8293,\t8332,\t8371,\t8412,\t8450,\t8490,\n8528,\t8568,\t8607,\t8646,\t8685,\t8723,\t8763,\t8802,\t8840,\t8879,\n8917,\t8956,\t8995,\t9033,\t9072,\t9109,\t9148,\t9187,\t9225,\t9264,\n9301,\t9340,\t9378,\t9415,\t9454,\t9491,\t9529,\t9567,\t9604,\t9642,\n9679,\t9717,\t9755,\t9791,\t9829,\t9866,\t9903,\t9941,\t9977,\t10015,\n10051,\t10089,\t10126,\t10162,\t10199,\t10235,\t10272,\t10309,\t10345,\t10382,\n10417,\t10454,\t10491,\t10526,\t10563,\t10598,\t10635,\t10672,\t10706,\t10742,\n10778,\t10814,\t10850,\t10885,\t10921,\t10955,\t10991,\t11027,\t11061,\t11097,\n11131,\t11166,\t11202,\t11236,\t11271,\t11305,\t11340,\t11376,\t11409,\t11444,\n11478,\t11513,\t11547,\t11580,\t11615,\t11648,\t11683,\t11717,\t11751,\t11785,\n11817,\t11852,\t11886,\t11918,\t11952,\t11985,\t12018,\t12053,\t12085,\t12118,\n12150,\t12184,\t12217,\t12249,\t12282,\t12314,\t12347,\t12380,\t12411,\t12444,\n12476,\t12508,\t12541,\t12572,\t12604,\t12635,\t12668,\t12700,\t12731,\t12763,\n12794,\t12826,\t12858,\t12888,\t12920,\t12950,\t12982,\t13013,\t13043,\t13074,\n13105,\t13135,\t13166,\t13196,\t13227,\t13257,\t13287,\t13317,\t13347,\t13377,\n13407,\t13437,\t13467,\t13496,\t13525,\t13555,\t13585,\t13614,\t13643,\t13672,\n13701,\t13730,\t13760,\t13787,\t13817,\t13845,\t13873,\t13903,\t13930,\t13959,\n13987,\t14015,\t14043,\t14071,\t14099,\t14126,\t14154,\t14183,\t14209,\t14237,\n14264,\t14292,\t14319,\t14346,\t14373,\t14400,\t14427,\t14454,\t14480,\t14507,\n14533,\t14560,\t14586,\t14612,\t14639,\t14664,\t14691,\t14717,\t14742,\t14768,\n14793,\t14819,\t14845,\t14870,\t14896,\t14920,\t14945,\t14971,\t14996,\t15020,\n15044,\t15070,\t15094,\t15118,\t15143,\t15167,\t15192,\t15216,\t15239,\t15263,\n15287,\t15311,\t15335,\t15358,\t15382,\t15405,\t15428,\t15452,\t15474,\t15498,\n15520,\t15543,\t15566,\t15588,\t15611,\t15633,\t15656,\t15678,\t15700,\t15722,\n15744,\t15766,\t15788,\t15809,\t15831,\t15852,\t15874,\t15895,\t15916,\t15937,\n15958,\t15979,\t16000,\t16020,\t16041,\t16061,\t16082,\t16103,\t16122,\t16143,\n16162,\t16183,\t16203,\t16222,\t16242,\t16261,\t16281,\t16300,\t16319,\t16339,\n16357,\t16377,\t16396,\t16414,\t16433,\t16451,\t16470,\t16488,\t16506,\t16525,\n16542,\t16561,\t16579,\t16596,\t16614,\t16631,\t16649,\t16667,\t16683,\t16700,\n16717,\t16735,\t16752,\t16768,\t16785,\t16801,\t16818,\t16834,\t16850,\t16867,\n16883,\t16899,\t16915,\t16930,\t16945,\t16961,\t16977,\t16992,\t17007,\t17022,\n17037,\t17052,\t17067,\t17081,\t17096,\t17111,\t17126,\t17140,\t17154,\t17168,\n17182,\t17196,\t17209,\t17223,\t17237,\t17250,\t17264,\t17277,\t17290,\t17303,\n17315,\t17329,\t17341,\t17354,\t17367,\t17379,\t17391,\t17404,\t17415,\t17428,\n17439,\t17451,\t17463,\t17475,\t17486,\t17497,\t17509,\t17520,\t17531,\t17542,\n17552,\t17563,\t17574,\t17584,\t17595,\t17605,\t17616,\t17626,\t17636,\t17646,\n17655,\t17665,\t17675,\t17684,\t17694,\t17703,\t17712,\t17721,\t17730,\t17739,\n17747,\t17756,\t17764,\t17773,\t17781,\t17789,\t17798,\t17806,\t17813,\t17821,\n17829,\t17836,\t17843,\t17851,\t17858,\t17866,\t17872,\t17879,\t17886,\t17893,\n17899,\t17906,\t17912,\t17918,\t17924,\t17931,\t17937,\t17942,\t17948,\t17953,\n17959,\t17964,\t17970,\t17975,\t17980,\t17985,\t17990,\t17995,\t17999,\t18004,\n18008,\t18012,\t18016,\t18021,\t18025,\t18028,\t18032,\t18036,\t18039,\t18043,\n18046,\t18049,\t18052,\t18055,\t18058,\t18061,\t18064,\t18067,\t18069,\t18071,\n18073,\t18075,\t18078,\t18079,\t18081,\t18083,\t18084,\t18086,\t18087,\t18089,\n18090,\t18090,\t18091,\t18092,\t18093,\t18094,\t18094,\t18095,\t18095,\t18095\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/common/tables.h",
    "content": "/***********************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    1999 PictureTel Coporation\n**          Andover, MA, USA  \n**\n**\t    All rights reserved.\n**\n***********************************************************************/\n\n/***********************************************************************\n  Filename:    tables.h    \n\n  Purpose:     Contains table definitions used by G.722.1 Annex C\n\t\t\n  Design Notes:\n\n***********************************************************************/\n\n/***********************************************************************\n Include files                                                           \n***********************************************************************/\n#define REGION_POWER_TABLE_SIZE 64\n#define NUM_CATEGORIES          8\n#define DCT_LENGTH              320\n#define MAX_DCT_LENGTH          640\n\nextern Word16 int_region_standard_deviation_table[REGION_POWER_TABLE_SIZE];\nextern Word16 standard_deviation_inverse_table[REGION_POWER_TABLE_SIZE];\nextern Word16 step_size_inverse_table[NUM_CATEGORIES];\nextern Word16 vector_dimension[NUM_CATEGORIES];\nextern Word16 number_of_vectors[NUM_CATEGORIES];\n/* The last category isn't really coded with scalar quantization. */\nextern Word16 max_bin[NUM_CATEGORIES];\nextern Word16 max_bin_plus_one_inverse[NUM_CATEGORIES];\nextern Word16 int_dead_zone[NUM_CATEGORIES];\nextern Word16 samples_to_rmlt_window[DCT_LENGTH];\nextern Word16 rmlt_to_samples_window[DCT_LENGTH];\n\n/* Add next line in Release 1.2 */\nextern Word16 int_dead_zone_low_bits[NUM_CATEGORIES];\n\nextern Word16 max_samples_to_rmlt_window[MAX_DCT_LENGTH];\nextern Word16 max_rmlt_to_samples_window[MAX_DCT_LENGTH];\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/common/typedef.h",
    "content": "/* $Id: typedef.h 2623 2009-04-20 18:38:15Z bennylp $ */\n/* \n * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#ifndef TYPEDEF_H\n#define TYPEDEF_H\n\n#include <pj/types.h>\n\ntypedef pj_int8_t Word8;\ntypedef pj_int16_t Word16;\ntypedef pj_int32_t Word32;\ntypedef pj_uint16_t UWord16;\ntypedef pj_uint32_t UWord32;\ntypedef int Flag;\n\n#endif /* TYPEDEF_H */\n\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/decode/coef2sam.c",
    "content": "/*****************************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**   All rights reserved.\n**\n*****************************************************************************/\n\n/*****************************************************************************\n* Filename: rmlt_coefs_to_samples.c\n*\n* Purpose:  Convert Reversed MLT (Modulated Lapped Transform) \n*           Coefficients to Samples\n*\n*     The \"Reversed MLT\" is an overlapped block transform which uses\n*     even symmetry * on the left, odd symmetry on the right and a\n*     Type IV DCT as the block transform.  * It is thus similar to a\n*     MLT which uses odd symmetry on the left, even symmetry * on the\n*     right and a Type IV DST as the block transform.  In fact, it is\n*     equivalent * to reversing the order of the samples, performing\n*     an MLT and then negating all * the even-numbered coefficients.\n*\n*****************************************************************************/\n\n/***************************************************************************\n Include files                                                           \n***************************************************************************/\n#include \"defs.h\"\n#include \"tables.h\"\n#include \"count.h\"\n\n/***************************************************************************\n Function:     rmlt_coefs_to_samples \n\n Syntax:       void rmlt_coefs_to_samples(Word16 *coefs,       \n                                          Word16 *old_samples, \n                                          Word16 *out_samples, \n                                          Word16 dct_length,\n                                          Word16 mag_shift)    \n            \n               inputs:    Word16 *coefs\n                          Word16 *old_samples\n                          Word16 dct_length\n                          Word16 mag_shift\n                          \n                          \n               outputs:   Word16 *out_samples\n               \n Description:  Converts the mlt_coefs to samples\n\n Design Notes:\n \n WMOPS:     7kHz |    24kbit    |    32kbit\n          -------|--------------|----------------\n            AVG  |     1.91     |    1.91\n          -------|--------------|----------------  \n            MAX  |     1.91     |    1.91\n          -------|--------------|---------------- \n\t\t\t\t\n           14kHz |    24kbit    |    32kbit      |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |     3.97     |    3.97        |     3.97   \n          -------|--------------|----------------|----------------\n            MAX  |     3.97     |    3.97        |     3.97   \n          -------|--------------|----------------|----------------\n\n***************************************************************************/\n\nvoid rmlt_coefs_to_samples(Word16 *coefs,     \n                           Word16 *old_samples,\n                           Word16 *out_samples,           \n                           Word16 dct_length,\n                           Word16 mag_shift)             \n{\n\n    \n    Word16\tindex, vals_left;\n    Word16\tnew_samples[MAX_DCT_LENGTH];\n    Word16\t*new_ptr, *old_ptr;\n    Word16\t*win_new, *win_old;\n    Word16\t*out_ptr;\n    Word16  half_dct_size;\n    Word32  sum;\n\n    \n\n    half_dct_size = shr_nocheck(dct_length,1);\n    \n    /* Perform a Type IV (inverse) DCT on the coefficients */\n    dct_type_iv_s(coefs, new_samples, dct_length);\n    \n    test();\n    if (mag_shift > 0) \n    {\n        for(index=0;index<dct_length;index++)\n        {\n            new_samples[index] = shr_nocheck(new_samples[index],mag_shift);\n            move16();\n        }\n    }\n    else \n    {\n        test();\n        if (mag_shift < 0) \n        {\n            mag_shift = negate(mag_shift);\n            for(index=0;index<dct_length;index++)\n            {\n                new_samples[index] = shl_nocheck(new_samples[index],mag_shift);\n                move16();\n            }\n        }\n\n    }\n\n    /* Get the first half of the windowed samples */\n    \n    out_ptr = out_samples;\n    move16();\n    test();\n    if (dct_length==DCT_LENGTH)\n    {\n        win_new = rmlt_to_samples_window;\n        move16();\n        win_old = rmlt_to_samples_window + dct_length;\n        move16();\n    }\n    else\n    {\n        win_new = max_rmlt_to_samples_window;\n        move16();\n        win_old = max_rmlt_to_samples_window + dct_length;\n        move16();\n    }\n    old_ptr = old_samples;\n    move16();\n    new_ptr = new_samples + half_dct_size;\n    move16();\n    \n    for (vals_left = half_dct_size;    vals_left > 0;    vals_left--)\n    {\n        sum = 0L;\n        move32();\n        sum = L_mac(sum,*win_new++, *--new_ptr);\n        sum = L_mac(sum,*--win_old, *old_ptr++);\n        *out_ptr++ = itu_round(L_shl_nocheck(sum,2));\n        move16();\n\n    }\n    \n    /* Get the second half of the windowed samples */\n    \n    for (vals_left = half_dct_size;    vals_left > 0;    vals_left--)\n    {\n        sum = 0L;\n        move32();\n        sum = L_mac(sum,*win_new++, *new_ptr++);\n        sum = L_mac(sum,negate(*--win_old), *--old_ptr);\n        *out_ptr++ = itu_round(L_shl_nocheck(sum,2));\n        move16();\n    }\n        \n    /* Save the second half of the new samples for   */\n    /* next time, when they will be the old samples. */\n    \n    /* pointer arithmetic */\n    new_ptr = new_samples + half_dct_size;\n    move16();\n    old_ptr = old_samples;\n    move16();\n    for (vals_left = half_dct_size;    vals_left > 0;    vals_left--)\n    {\n        *old_ptr++ = *new_ptr++;\n        move16();\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/decode/dct4_s.c",
    "content": "/********************************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**   All rights reserved.\n**\n********************************************************************************/\n\n/********************************************************************************\n* Filename: dct_type_iv_s.c\n*\n* Purpose:  Discrete Cosine Transform, Type IV used for inverse MLT\n*\n* The basis functions are\n*\n*\t cos(PI*(t+0.5)*(k+0.5)/block_length)\n*\n* for time t and basis function number k.  Due to the symmetry of the expression\n* in t and k, it is clear that the forward and inverse transforms are the same.\n*\n*********************************************************************************/\n\n/***************************************************************************\n Include files                                                           \n***************************************************************************/\n#include \"defs.h\"\n#include \"count.h\"\n#include \"dct4_s.h\"\n\n/***************************************************************************\n External variable declarations                                          \n***************************************************************************/\nextern Word16    syn_bias_7khz[DCT_LENGTH];\nextern Word16    dither[DCT_LENGTH];\nextern Word16    max_dither[MAX_DCT_LENGTH];\n\nextern Word16       dct_core_s[DCT_LENGTH_DIV_32][DCT_LENGTH_DIV_32];\nextern cos_msin_t\ts_cos_msin_2[DCT_LENGTH_DIV_32];\nextern cos_msin_t\ts_cos_msin_4[DCT_LENGTH_DIV_16];\nextern cos_msin_t\ts_cos_msin_8[DCT_LENGTH_DIV_8];\nextern cos_msin_t\ts_cos_msin_16[DCT_LENGTH_DIV_4];\nextern cos_msin_t\ts_cos_msin_32[DCT_LENGTH_DIV_2];\nextern cos_msin_t\ts_cos_msin_64[DCT_LENGTH];\nextern cos_msin_t\t*s_cos_msin_table[];\n\n/********************************************************************************\n Function:    dct_type_iv_s\n\n Syntax:      void dct_type_iv_s (Word16 *input,Word16 *output,Word16 dct_length)\n              \n\n Description: Discrete Cosine Transform, Type IV used for inverse MLT\n\n Design Notes:\n \n WMOPS:     7kHz |    24kbit    |    32kbit\n          -------|--------------|----------------\n            AVG  |     1.74     |     1.74\n          -------|--------------|----------------  \n            MAX  |     1.74     |     1.74\n          -------|--------------|---------------- \n\t\t\t\t\n           14kHz |    24kbit    |    32kbit      |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |     3.62     |     3.62       |      3.62   \n          -------|--------------|----------------|----------------\n            MAX  |     3.62     |     3.62       |      3.62   \n          -------|--------------|----------------|----------------\n\n********************************************************************************/\n\nvoid dct_type_iv_s (Word16 *input,Word16 *output,Word16 dct_length)\n{\n    Word16   buffer_a[MAX_DCT_LENGTH], buffer_b[MAX_DCT_LENGTH], buffer_c[MAX_DCT_LENGTH];\n    Word16   *in_ptr, *in_ptr_low, *in_ptr_high, *next_in_base;\n    Word16   *out_ptr_low, *out_ptr_high, *next_out_base;\n    Word16   *out_buffer, *in_buffer, *buffer_swap;\n    Word16   in_val_low, in_val_high;\n    Word16   out_val_low, out_val_high;\n    Word16   in_low_even, in_low_odd;\n    Word16   in_high_even, in_high_odd;\n    Word16   out_low_even, out_low_odd;\n    Word16   out_high_even, out_high_odd;\n    Word16   *pair_ptr;\n    Word16   cos_even, cos_odd, msin_even, msin_odd;\n    Word16   set_span, set_count, set_count_log, pairs_left, sets_left;\n    Word16   i,k;\n    Word16   index;\n    Word16   dummy;\n    Word32 \t sum;\n    cos_msin_t\t**table_ptr_ptr, *cos_msin_ptr;\n\n    Word32 acca;\n    Word16 temp;\n\n    Word16   dct_length_log;\n    Word16   *dither_ptr;\n    \n    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n    /* Do the sum/difference butterflies, the first part of */\n    /* converting one N-point transform into 32 - 10 point transforms  */\n    /* transforms, where N = 1 << DCT_LENGTH_LOG.           */\n    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n    test();\n    if (dct_length==DCT_LENGTH)\n    {\n        dct_length_log = DCT_LENGTH_LOG;\n        move16();\n        dither_ptr = dither;\n        move16();\n    }\n    else\n    {\n        dct_length_log = MAX_DCT_LENGTH_LOG;\n        move16();\n        dither_ptr = max_dither;\n        move16();\n    }\n    \n    in_buffer  = input;\n    move16();\n    out_buffer = buffer_a;\n    move16();\n    \n    index=0;\n    move16();\n    \n    i=0;\n    move16();\n\n    for (set_count_log = 0;    set_count_log <= dct_length_log - 2;    set_count_log++) \n    {\n\n        /*===========================================================*/\n        /* Initialization for the loop over sets at the current size */\n        /*===========================================================*/\n        \n        /*    set_span      = 1 << (DCT_LENGTH_LOG - set_count_log); */\n        set_span = shr_nocheck(dct_length,set_count_log);\n           \n        set_count     = shl_nocheck(1,set_count_log);\n        in_ptr        = in_buffer;\n        move16();\n        next_out_base = out_buffer;\n        move16();\n        \n        /*=====================================*/\n        /* Loop over all the sets of this size */\n        /*=====================================*/\n        temp = sub(index,1);\n        test();\n        if(temp < 0)\n        {\n            for (sets_left = set_count;sets_left > 0;sets_left--) \n            {\n    \n                /*||||||||||||||||||||||||||||||||||||||||||||*/\n                /* Set up output pointers for the current set */\n                /*||||||||||||||||||||||||||||||||||||||||||||*/\n                /* pointer arithmetic */\n                out_ptr_low    = next_out_base;\n                move16();\n                next_out_base += set_span;\n                move16();\n                out_ptr_high   = next_out_base;\n                move16();\n\n                /*||||||||||||||||||||||||||||||||||||||||||||||||||*/\n                /* Loop over all the butterflies in the current set */\n                /*||||||||||||||||||||||||||||||||||||||||||||||||||*/\n                    \n                do \n                {\n                    in_val_low      = *in_ptr++;\n                    move16();\n                    in_val_high     = *in_ptr++;\n                    move16();\n\n                    /* BEST METHOD OF GETTING RID OF BIAS, BUT COMPUTATIONALLY UNPLEASANT */\n                    /* ALTERNATIVE METHOD, SMEARS BIAS OVER THE ENTIRE FRAME, COMPUTATIONALLY SIMPLEST. */\n                    /* IF THIS WORKS, IT'S PREFERABLE */\n                        \n                    dummy = add(in_val_low,dither_ptr[i++]);\n\t\t    // blp: addition of two 16bits vars, there's no way\n\t\t    //      they'll overflow a 32bit var\n                    //acca = L_add(dummy,in_val_high);\n\t\t    acca = dummy + in_val_high;\n                    out_val_low = extract_l(L_shr_nocheck(acca,1));\n                    \n                    dummy = add(in_val_low,dither_ptr[i++]);\n\t\t    // blp: addition of two 16bits vars, there's no way\n\t\t    //      they'll overflow a 32bit var\n                    //acca = L_add(dummy,-in_val_high);\n\t\t    acca = dummy - in_val_high;\n                    out_val_high = extract_l(L_shr_nocheck(acca,1));\n                    \n                    *out_ptr_low++  = out_val_low;\n                    move16();\n                    *--out_ptr_high = out_val_high;\n                    move16();\n\n                    test();\n                    \n                    /* this involves comparison of pointers */\n                    /* pointer arithmetic */\n\n                } while (out_ptr_low < out_ptr_high);\n    \n            } /* End of loop over sets of the current size */\n        }\n        else\n        {\n            for (sets_left = set_count;    sets_left > 0;    sets_left--) \n            {\n                /*||||||||||||||||||||||||||||||||||||||||||||*/\n                /* Set up output pointers for the current set */\n                /*||||||||||||||||||||||||||||||||||||||||||||*/\n                \n                out_ptr_low    = next_out_base;\n                move16();\n                next_out_base += set_span;\n                move16();\n                out_ptr_high   = next_out_base;\n                move16();\n\n            \t/*||||||||||||||||||||||||||||||||||||||||||||||||||*/\n            \t/* Loop over all the butterflies in the current set */\n            \t/*||||||||||||||||||||||||||||||||||||||||||||||||||*/\n                \n                do \n                {\n                    in_val_low      = *in_ptr++;\n                    move16();\n                    in_val_high     = *in_ptr++;\n                    move16();\n\n                    out_val_low     = add(in_val_low,in_val_high);\n                    out_val_high    = add(in_val_low,negate(in_val_high));\n                    \n                    *out_ptr_low++  = out_val_low;\n                    move16();\n                    *--out_ptr_high = out_val_high;\n                    move16();\n\n                    test();\n                } while (out_ptr_low < out_ptr_high);\n    \n            } /* End of loop over sets of the current size */\n        }\n\n        /*============================================================*/\n        /* Decide which buffers to use as input and output next time. */\n        /* Except for the first time (when the input buffer is the    */\n        /* subroutine input) we just alternate the local buffers.     */\n        /*============================================================*/\n        \n        in_buffer = out_buffer;\n        move16();\n        \n        test();\n        if (out_buffer == buffer_a)\n        {\n            out_buffer = buffer_b;\n            move16();\n        }\n        else\n        {\n            out_buffer = buffer_a;\n            move16();\n        }\n        \n        index = add(index,1);\n    } /* End of loop over set sizes */\n\n\n    /*++++++++++++++++++++++++++++++++*/\n    /* Do 32 - 10 point transforms */\n    /*++++++++++++++++++++++++++++++++*/\n    \n    pair_ptr = in_buffer;\n    move16();\n    buffer_swap = buffer_c;\n    move16();\n\n    for (pairs_left = 1 << (dct_length_log - 1);    pairs_left > 0;    pairs_left--) \n    {\n        for ( k=0; k<CORE_SIZE; k++ )\n        {\n#if PJ_HAS_INT64\n\t    /* blp: danger danger! not really compatible but faster */\n\t    pj_int64_t sum64=0;\n            move32();\n            \n            for ( i=0; i<CORE_SIZE; i++ )\n            {\n                sum64 += L_mult(pair_ptr[i], dct_core_s[i][k]);\n            }\n\t    sum = L_saturate(sum64);\n#else\n            sum=0L;\n            move32();\n            \n            for ( i=0; i<CORE_SIZE; i++ )\n            {\n                sum = L_mac(sum, pair_ptr[i],dct_core_s[i][k]);\n            }\n#endif\n            buffer_swap[k] = itu_round(sum);\n        }\n        \n        pair_ptr   += CORE_SIZE;\n        move16();\n        buffer_swap += CORE_SIZE;\n        move16();\n    }\n    \n    for (i=0;i<dct_length;i++)\n    {\n        in_buffer[i] = buffer_c[i];\n        move16();\n    }\n\n    table_ptr_ptr = s_cos_msin_table;\n    move16();\n\n    /*++++++++++++++++++++++++++++++*/\n    /* Perform rotation butterflies */\n    /*++++++++++++++++++++++++++++++*/\n    index=0;\n    move16();\n    \n    for (set_count_log = dct_length_log - 2 ;    set_count_log >= 0;    set_count_log--) \n    {\n\n        /*===========================================================*/\n        /* Initialization for the loop over sets at the current size */\n        /*===========================================================*/\n        \n        /*    set_span      = 1 << (DCT_LENGTH_LOG - set_count_log); */\n        set_span = shr_nocheck(dct_length,set_count_log);\n        \n        set_count     = shl_nocheck(1,set_count_log);\n        next_in_base  = in_buffer;\n        move16();\n        test();\n        if (set_count_log == 0)\n        {\n            next_out_base = output;\n            move16();\n        }\n        else\n        {\n            next_out_base = out_buffer;\n            move16();\n        }\n        \n        /*=====================================*/\n        /* Loop over all the sets of this size */\n        /*=====================================*/\n\n        for (sets_left = set_count;    sets_left > 0;    sets_left--) \n        {\n\n            /*|||||||||||||||||||||||||||||||||||||||||*/\n            /* Set up the pointers for the current set */\n            /*|||||||||||||||||||||||||||||||||||||||||*/\n            \n            in_ptr_low     = next_in_base;\n            move16();\n            \n            temp = shr_nocheck(set_span,1);\n            in_ptr_high    = in_ptr_low + temp;\n            move16();\n            \n            next_in_base  += set_span;\n            move16();\n            \n            out_ptr_low    = next_out_base;\n            move16();\n            \n            next_out_base += set_span;\n            move16();\n            out_ptr_high   = next_out_base;\n            move16();\n            \n            cos_msin_ptr   = *table_ptr_ptr;\n            move16();\n\n            /*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/\n            /* Loop over all the butterfly pairs in the current set */\n            /*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/\n\n\t        do \n            {\n                in_low_even     = *in_ptr_low++;\n                move16();\n                in_low_odd      = *in_ptr_low++;\n                move16();\n                in_high_even    = *in_ptr_high++;\n                move16();\n                in_high_odd     = *in_ptr_high++;\n                move16();\n                cos_even        = cos_msin_ptr[0].cosine;\n                move16();\n                msin_even       = cos_msin_ptr[0].minus_sine;\n                move16();\n                cos_odd         = cos_msin_ptr[1].cosine;\n                move16();\n                msin_odd        = cos_msin_ptr[1].minus_sine;\n                move16();\n                cos_msin_ptr   += 2;\n                \n                sum = 0L;\n                move32();\n                \n                sum = L_mac(sum,cos_even,in_low_even);\n                sum = L_mac(sum,negate(msin_even),in_high_even);\n                out_low_even = itu_round(L_shl_nocheck(sum,1));\n                \n                sum = 0L;\n                move32();\n                sum = L_mac(sum,msin_even,in_low_even);\n                sum = L_mac(sum,cos_even,in_high_even);\n                out_high_even = itu_round(L_shl_nocheck(sum,1));\n                \n                sum = 0L;\n                move32();\n                sum = L_mac(sum,cos_odd,in_low_odd);\n                sum = L_mac(sum,msin_odd,in_high_odd);\n                out_low_odd = itu_round(L_shl_nocheck(sum,1));\n                \n                sum = 0L;\n                move32();\n                sum = L_mac(sum,msin_odd,in_low_odd);\n                sum = L_mac(sum,negate(cos_odd),in_high_odd);\n                out_high_odd = itu_round(L_shl_nocheck(sum,1));\n                \n                *out_ptr_low++  = out_low_even;\n                move16();\n                *--out_ptr_high = out_high_even;\n                move16();\n                *out_ptr_low++  = out_low_odd;\n                move16();\n                *--out_ptr_high = out_high_odd;\n                move16();\n            \n                test();\n            } while (out_ptr_low < out_ptr_high);\n\n\t    } /* End of loop over sets of the current size */\n\n        /*=============================================*/\n        /* Swap input and output buffers for next time */\n        /*=============================================*/\n        \n        buffer_swap = in_buffer;\n        move16();\n        in_buffer   = out_buffer;\n        move16();\n        out_buffer  = buffer_swap;\n        move16();\n        \n        index = add(index,1);\n        table_ptr_ptr++;\n    }\n    /*------------------------------------\n    \n         ADD IN BIAS FOR OUTPUT\n         \n    -----------------------------------*/\n    if (dct_length==DCT_LENGTH)\n    {\n        for(i=0;i<320;i++) \n        {\n\t   // blp: addition of two 16bits vars, there's no way\n\t   //      they'll overflow a 32bit var\n           //sum = L_add(output[i],syn_bias_7khz[i]);\n\t   sum = output[i] + syn_bias_7khz[i];\n           acca = L_sub(sum,32767);\n           test();\n           if (acca > 0) \n           {\n               sum = 32767L;\n               move32();\n           }\n\t   // blp: addition of two 16bits vars, there's no way\n\t   //      they'll overflow 32bit var\n           //acca = L_add(sum,32768L);\n\t   acca = sum + 32768;\n           test();\n           if (acca < 0) \n           {\n               sum = -32768L;\n               move32();\n           }\n           output[i] = extract_l(sum);\n        }\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/decode/dct4_s.h",
    "content": "/***********************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**   All rights reserved.\n**\n***********************************************************************/\n\n/***********************************************************************\n  Filename:    dct4_s.h    \n\n  Purpose:     Contains tables used by dct4_s.c\n\t\t\n  Design Notes:\n\n***********************************************************************/\n\n/***************************************************************************\n Include files                                                           \n***************************************************************************/\n\ntypedef struct \n{\n    Word16 cosine;\n    Word16 minus_sine;\n} cos_msin_t;\n\n/***************************************************************************\n  The dct_core_s table was generated by the following code\n\n      for(i=0;i<10;++i)\n      {\n          for(k=0;k<10;++k)\n          {\n              dct_core_s[i][k]=(short) (FTOI(((.9*32768.)*cos(3.1415926*(k+0.5)*(i+0.5)/10.))));\n          }\n      }\n***************************************************************************/\nWord16 dct_core_s[10][10] = {\n{ 29400,   28676,   27246,   25145,   22425,   19153,   15409,   11286,    6885,  2314 },\n{ 28676,   22425,   11286,   -2314,  -15409,  -25145,  -29400,  -27246,  -19153,  -6885 },\n{ 27246,   11286,  -11286,  -27246,  -27246,  -11286,   11286,   27246,   27246,  11286 },\n{ 25145,   -2314,  -27246,  -22425,    6885,   28676,   19153,  -11286,  -29400,  -15409 },\n{ 22425,  -15409,  -27246,    6885,   29400,    2314,  -28676,  -11286,   25145,  19153 },\n{ 19153,  -25145,  -11286,   28676,    2314,  -29400,    6885,   27246,  -15409,  -22425 },\n{ 15409,  -29400,   11286,   19153,  -28676,    6885,   22425,  -27246,    2314,  25145 },\n{ 11286,  -27246,   27246,  -11286,  -11286,   27246,  -27246,   11286,   11286,  -27246 },\n{  6885,  -19153,   27246,  -29400,   25145,  -15409,    2314,   11286,  -22425,  28676 },\n{  2314,   -6885,   11286,  -15409,   19153,  -22425,   25145,  -27246,   28676,  -29400 }\n};    \n\nWord16 syn_bias_7khz[DCT_LENGTH] = {\n -4,  4, -5, -2,  0, -4,  6,  2, -2, -4,\n -3,  3,  0,  0, -2,  4,  0,  0,  3, -6,\n  8,  5,  4,  5, -8,  0, -2,  0,  0, -3,\n  3,  0,  0,  0,  1, -1, -2,  0,  0,  2,\n -2, -5, -2,  3,  2, -1, -1, -6,  3,  1,\n -7,  4,  4,  0,  1,  4,  1,  0,  1, -5,\n -1,  1, -6,  0, -1, -1,  3,  0, -2,  1,\n  2, -4,  0,  9,  0, -3,  1,  1,  1,  0,\n -3, -2, -1, -4, -2,  0,  5,  2, -3,  5,\n  0, -2,  4,  4,  0, -6, -4,  2,  0,  0,\n  0, -1, -1, -2,  0,  6,  1,  0,  0, -1,\n  0, -4, -1,  0, -4,  1, -1, -5,  0,  1,\n  2,  4,  0, -8, -4,  0, -2, -2,  2,  5,\n -3, -1,  1, -4,  0,  0,  0, -1, -3,  0,\n -5, -4,  0, -2,  0,  7,  1,  0,  5, -2,\n -1,  2,  2, -2,  3,  7, -3,  4,  1, -4,\n  0,  0,  3, -7, -5,  0,  0,  4,  0, -2,\n -1,  0, -5,  0,  2,  0, 11,  5, -1,  0,\n  2,  2, -2, -2,  5,  4, -3,  1,  0, -2,\n  1,  3,  2,  0,  1,  0,  0,  0,  5,  6,\n -2, -1,  0,  2,  3,  2,  0, -3,  4,  5,\n  0, -1,  0,  3,  1, -2, -3, -2, -1,  2,\n -1, -1, -2, -7,  4,  6, -5, -6, -3, -4,\n  0,  2, -5, -2,  3,  0,  0,  0,  2, -2,\n -4,  3,  3,  1,  0,  0,  4, -1,  8, 13,\n  1,  2,  0,  2,  0, -1,  4, -3,  1,  0,\n -1,  3,  0,  0, -5,  0,  6,  2,  4,  5,\n  2, -1, -1,  3,  6,  1,  1,  2, -4,  0,\n -1, -6, -2, -2,  2,  1,  2,  6,  2,  0,\n -2, -2,  0, -1,  2,  0,  0,  3, -2,  1,\n  3,  1,  2, -1, -2,  2,  2, -4,  0,  0,\n -3,  0, -4, -3,  6,  7,  2,  2,  0, -3};\n\nWord16 dither[DCT_LENGTH]= {\n  1,  0,  0,  0,  1,  0,  0,  1,  1,  1,\n  1,  0,  0,  0,  1,  1,  1,  1,  1,  0,\n  0,  1,  1,  1,  0,  1,  1,  0,  0,  0,\n  1,  0,  0,  1,  0,  1,  0,  0,  1,  0,\n  1,  0,  0,  0,  1,  0,  1,  0,  0,  0,\n  1,  1,  1,  1,  1,  0,  0,  1,  0,  0,\n  0,  0,  1,  0,  0,  0,  1,  0,  0,  1,\n  1,  1,  1,  1,  1,  0,  1,  0,  0,  1,\n  1,  0,  0,  1,  0,  0,  0,  1,  0,  1,\n  0,  0,  1,  1,  0,  1,  0,  1,  1,  1,\n  1,  0,  0,  0,  0,  1,  1,  1,  1,  1,\n  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,\n  1,  1,  0,  0,  1,  1,  1,  1,  1,  0,\n  0,  1,  1,  1,  1,  0,  1,  1,  1,  0,\n  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,\n  1,  0,  1,  1,  1,  1,  0,  0,  0,  0,\n  1,  1,  0,  1,  0,  0,  1,  0,  0,  1,\n  0,  0,  0,  1,  1,  0,  0,  1,  1,  1,\n  1,  0,  0,  0,  0,  0,  1,  1,  1,  1,\n  1,  0,  0,  1,  1,  0,  1,  1,  0,  0,\n  1,  1,  1,  0,  1,  1,  0,  1,  0,  1,\n  0,  0,  1,  1,  1,  1,  1,  1,  0,  1,\n  0,  1,  1,  1,  1,  0,  1,  1,  1,  0,\n  1,  1,  1,  0,  1,  1,  1,  0,  1,  0,\n  1,  1,  0,  0,  1,  0,  0,  1,  0,  1,\n  0,  1,  1,  0,  1,  0,  1,  0,  1,  1,\n  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,\n  0,  1,  0,  0,  0,  1,  0,  0,  0,  1,\n  1,  0,  0,  0,  1,  0,  0,  1,  0,  1,\n  1,  0,  1,  1,  0,  0,  1,  1,  0,  1,\n  1,  0,  1,  1,  1,  1,  1,  1,  0,  1,\n  1,  1,  1,  0,  1,  0,  0,  0,  1,  0};\n\nWord16 max_dither[MAX_DCT_LENGTH]= {\n  1,  0,  1,  0,  1,  1,  0,  1,  0,  1,\n  1,  1,  0,  0,  0,  0,  0,  1,  1,  1,\n  1,  1,  1,  0,  1,  1,  0,  0,  0,  1,\n  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,\n  1,  1,  1,  0,  1,  0,  1,  1,  1,  1,\n  0,  1,  0,  1,  1,  1,  1,  1,  1,  0,\n  1,  0,  1,  1,  0,  1,  0,  0,  0,  1,\n  0,  1,  1,  1,  1,  1,  0,  1,  1,  0,\n  0,  0,  1,  1,  0,  0,  0,  1,  1,  1,\n  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,\n  1,  0,  1,  0,  1,  0,  0,  0,  1,  1,\n  0,  1,  1,  1,  1,  1,  1,  0,  1,  0,\n  0,  0,  1,  0,  1,  0,  0,  0,  1,  0,\n  0,  1,  0,  1,  0,  0,  0,  0,  1,  0,\n  1,  0,  0,  1,  0,  1,  0,  0,  0,  1,\n  0,  1,  0,  0,  1,  1,  1,  1,  0,  1,\n  1,  0,  0,  0,  1,  1,  0,  1,  0,  1,\n  0,  1,  0,  1,  0,  1,  1,  1,  0,  1,\n  1,  0,  0,  1,  1,  1,  1,  0,  1,  1,\n  1,  1,  1,  0,  1,  1,  0,  0,  0,  0,\n  1,  0,  1,  0,  0,  0,  0,  1,  1,  0,\n  1,  1,  0,  0,  0,  0,  1,  0,  0,  1,\n  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,\n  0,  0,  1,  1,  1,  0,  1,  1,  1,  0,\n  0,  1,  1,  1,  1,  1,  1,  1,  0,  0,\n  1,  1,  1,  1,  1,  1,  0,  1,  1,  1,\n  0,  0,  1,  1,  0,  1,  0,  1,  0,  1,\n  0,  0,  1,  1,  1,  1,  1,  1,  0,  1,\n  0,  1,  1,  1,  0,  1,  0,  1,  0,  0,\n  0,  1,  0,  1,  1,  0,  0,  0,  1,  0,\n  1,  1,  0,  0,  1,  1,  1,  1,  0,  0,\n  0,  0,  1,  1,  1,  1,  0,  0,  1,  1,\n  1,  1,  1,  0,  1,  0,  0,  0,  1,  0,\n  0,  1,  1,  1,  0,  1,  0,  1,  0,  0,\n  1,  1,  0,  1,  0,  1,  1,  0,  0,  0,\n  0,  1,  1,  0,  1,  1,  1,  0,  1,  1,\n  0,  0,  1,  1,  1,  1,  1,  1,  0,  1,\n  1,  1,  0,  0,  0,  1,  1,  1,  1,  0,\n  0,  1,  0,  1,  0,  1,  1,  0,  1,  0,\n  1,  1,  1,  0,  0,  1,  1,  0,  0,  1,\n  0,  1,  0,  0,  0,  1,  1,  0,  0,  1,\n  0,  0,  1,  1,  0,  1,  0,  1,  0,  1,\n  1,  1,  0,  1,  0,  0,  1,  1,  0,  0,\n  1,  0,  1,  0,  1,  0,  0,  1,  0,  0,\n  0,  1,  0,  1,  1,  1,  1,  1,  1,  0,\n  0,  1,  1,  0,  0,  0,  1,  1,  1,  0,\n  1,  1,  1,  0,  1,  1,  1,  0,  0,  0,\n  0,  0,  1,  0,  0,  1,  0,  0,  0,  1,\n  0,  0,  0,  1,  1,  0,  0,  1,  0,  1,\n  1,  1,  1,  1,  0,  0,  1,  0,  1,  0,\n  0,  1,  0,  1,  1,  1,  1,  1,  1,  0,\n  0,  0,  1,  0,  1,  0,  0,  1,  0,  1,\n  1,  0,  1,  0,  1,  1,  0,  0,  1,  1,\n  1,  1,  1,  0,  1,  0,  0,  1,  1,  1,\n  0,  1,  0,  1,  0,  1,  0,  0,  0,  1,\n  1,  0,  0,  1,  0,  0,  1,  1,  0,  1,\n  1,  0,  1,  0,  1,  1,  0,  0,  1,  1,\n  0,  0,  0,  1,  0,  1,  1,  1,  0,  0,\n  1,  0,  1,  0,  1,  1,  0,  0,  0,  1,\n  1,  0,  1,  0,  0,  1,  1,  1,  0,  1,\n  0,  0,  1,  1,  1,  1,  1,  0,  0,  0,\n  0,  1,  0,  1,  0,  0,  1,  0,  1,  0,\n  0,  1,  1,  1,  1,  0,  0,  0,  1,  0,\n  0,  1,  0,  1,  0,  1,  0,  0,  0,  0\n};\n\n\n/********************************************************************************\n  The s_cos_min tables were generated by the following code:\n      double\t\tangle, scale;\n      int\t\t    index;\n\n      for (index = 0;index < length;index++) \n      {\n          angle = scale * ((double)index + 0.5);\n          table[index].cosine     = (short) (FTOI((18427)* cos(angle)));\n          table[index].minus_sine = (short) (FTOI((18427)*(-sin(angle))));\n      }\n\n\n********************************************************************************/\n\ncos_msin_t\ts_cos_msin_2[DCT_LENGTH_DIV_32] = {\n    {  18413   ,   -723   } , \n    {  18299   ,   -2166   } , \n    {  18073   ,   -3595   } , \n    {  17735   ,   -5002   } , \n    {  17288   ,   -6378   } , \n    {  16734   ,   -7715   } , \n    {  16077   ,   -9004   } , \n    {  15321   ,   -10237   } , \n    {  14471   ,   -11408   } , \n    {  13531   ,   -12508   } \n    };\ncos_msin_t\ts_cos_msin_4[DCT_LENGTH_DIV_16] = {\n    {  18423   ,   -362   } , \n    {  18395   ,   -1085   } , \n    {  18338   ,   -1806   } , \n    {  18253   ,   -2525   } , \n    {  18140   ,   -3239   } , \n    {  17999   ,   -3949   } , \n    {  17830   ,   -4653   } , \n    {  17634   ,   -5349   } , \n    {  17410   ,   -6037   } , \n    {  17159   ,   -6716   } , \n    {  16883   ,   -7385   } , \n    {  16580   ,   -8042   } , \n    {  16251   ,   -8686   } , \n    {  15898   ,   -9318   } , \n    {  15520   ,   -9935   } , \n    {  15118   ,   -10536   } , \n    {  14692   ,   -11122   } , \n    {  14244   ,   -11690   } , \n    {  13774   ,   -12240   } , \n    {  13283   ,   -12772   } \n    };\ncos_msin_t\ts_cos_msin_8[DCT_LENGTH_DIV_8] = {\n    {  18426   ,   -181   } , \n    {  18419   ,   -543   } , \n    {  18405   ,   -904   } , \n    {  18384   ,   -1265   } , \n    {  18355   ,   -1626   } , \n    {  18320   ,   -1986   } , \n    {  18277   ,   -2345   } , \n    {  18228   ,   -2704   } , \n    {  18171   ,   -3061   } , \n    {  18107   ,   -3417   } , \n    {  18037   ,   -3772   } , \n    {  17959   ,   -4126   } , \n    {  17875   ,   -4477   } , \n    {  17783   ,   -4827   } , \n    {  17685   ,   -5176   } , \n    {  17580   ,   -5522   } , \n    {  17468   ,   -5866   } , \n    {  17350   ,   -6208   } , \n    {  17225   ,   -6547   } , \n    {  17093   ,   -6884   } , \n    {  16954   ,   -7219   } , \n    {  16809   ,   -7550   } , \n    {  16658   ,   -7879   } , \n    {  16500   ,   -8204   } , \n    {  16336   ,   -8526   } , \n    {  16165   ,   -8846   } , \n    {  15988   ,   -9161   } , \n    {  15805   ,   -9473   } , \n    {  15616   ,   -9782   } , \n    {  15421   ,   -10087   } , \n    {  15220   ,   -10387   } , \n    {  15013   ,   -10684   } , \n    {  14801   ,   -10977   } , \n    {  14582   ,   -11265   } , \n    {  14358   ,   -11550   } , \n    {  14129   ,   -11829   } , \n    {  13894   ,   -12104   } , \n    {  13654   ,   -12375   } , \n    {  13408   ,   -12641   } , \n    {  13157   ,   -12901   } \n    };\ncos_msin_t\ts_cos_msin_16[DCT_LENGTH_DIV_4] = {\n    {  18427   ,   -90   } , \n    {  18425   ,   -271   } , \n    {  18421   ,   -452   } , \n    {  18416   ,   -633   } , \n    {  18409   ,   -814   } , \n    {  18400   ,   -995   } , \n    {  18389   ,   -1175   } , \n    {  18377   ,   -1356   } , \n    {  18363   ,   -1536   } , \n    {  18347   ,   -1716   } , \n    {  18329   ,   -1896   } , \n    {  18310   ,   -2076   } , \n    {  18288   ,   -2256   } , \n    {  18265   ,   -2435   } , \n    {  18241   ,   -2614   } , \n    {  18214   ,   -2793   } , \n    {  18186   ,   -2972   } , \n    {  18156   ,   -3150   } , \n    {  18124   ,   -3328   } , \n    {  18090   ,   -3506   } , \n    {  18055   ,   -3684   } , \n    {  18018   ,   -3861   } , \n    {  17979   ,   -4037   } , \n    {  17939   ,   -4214   } , \n    {  17897   ,   -4390   } , \n    {  17853   ,   -4565   } , \n    {  17807   ,   -4740   } , \n    {  17760   ,   -4915   } , \n    {  17710   ,   -5089   } , \n    {  17660   ,   -5262   } , \n    {  17607   ,   -5436   } , \n    {  17553   ,   -5608   } , \n    {  17497   ,   -5780   } , \n    {  17439   ,   -5952   } , \n    {  17380   ,   -6123   } , \n    {  17319   ,   -6293   } , \n    {  17257   ,   -6463   } , \n    {  17192   ,   -6632   } , \n    {  17126   ,   -6800   } , \n    {  17059   ,   -6968   } , \n    {  16990   ,   -7135   } , \n    {  16919   ,   -7302   } , \n    {  16846   ,   -7467   } , \n    {  16772   ,   -7632   } , \n    {  16696   ,   -7797   } , \n    {  16619   ,   -7960   } , \n    {  16540   ,   -8123   } , \n    {  16459   ,   -8285   } , \n    {  16377   ,   -8446   } , \n    {  16294   ,   -8607   } , \n    {  16208   ,   -8766   } , \n    {  16121   ,   -8925   } , \n    {  16033   ,   -9083   } , \n    {  15943   ,   -9240   } , \n    {  15852   ,   -9396   } , \n    {  15759   ,   -9551   } , \n    {  15664   ,   -9705   } , \n    {  15568   ,   -9858   } , \n    {  15471   ,   -10011   } , \n    {  15372   ,   -10162   } , \n    {  15271   ,   -10313   } , \n    {  15169   ,   -10462   } , \n    {  15066   ,   -10610   } , \n    {  14961   ,   -10758   } , \n    {  14854   ,   -10904   } , \n    {  14747   ,   -11049   } , \n    {  14637   ,   -11194   } , \n    {  14527   ,   -11337   } , \n    {  14415   ,   -11479   } , \n    {  14301   ,   -11620   } , \n    {  14187   ,   -11760   } , \n    {  14071   ,   -11898   } , \n    {  13953   ,   -12036   } , \n    {  13834   ,   -12172   } , \n    {  13714   ,   -12308   } , \n    {  13593   ,   -12442   } , \n    {  13470   ,   -12575   } , \n    {  13346   ,   -12706   } , \n    {  13220   ,   -12837   } , \n    {  13094   ,   -12966   } \n    };\ncos_msin_t\ts_cos_msin_32[DCT_LENGTH_DIV_2] = {\n    {  18427   ,   -45   } , \n    {  18427   ,   -136   } , \n    {  18426   ,   -226   } , \n    {  18424   ,   -317   } , \n    {  18423   ,   -407   } , \n    {  18420   ,   -497   } , \n    {  18418   ,   -588   } , \n    {  18415   ,   -678   } , \n    {  18411   ,   -769   } , \n    {  18407   ,   -859   } , \n    {  18403   ,   -949   } , \n    {  18398   ,   -1040   } , \n    {  18392   ,   -1130   } , \n    {  18387   ,   -1220   } , \n    {  18380   ,   -1310   } , \n    {  18374   ,   -1401   } , \n    {  18367   ,   -1491   } , \n    {  18359   ,   -1581   } , \n    {  18351   ,   -1671   } , \n    {  18343   ,   -1761   } , \n    {  18334   ,   -1851   } , \n    {  18324   ,   -1941   } , \n    {  18315   ,   -2031   } , \n    {  18305   ,   -2121   } , \n    {  18294   ,   -2211   } , \n    {  18283   ,   -2301   } , \n    {  18271   ,   -2390   } , \n    {  18259   ,   -2480   } , \n    {  18247   ,   -2570   } , \n    {  18234   ,   -2659   } , \n    {  18221   ,   -2749   } , \n    {  18207   ,   -2838   } , \n    {  18193   ,   -2927   } , \n    {  18178   ,   -3017   } , \n    {  18163   ,   -3106   } , \n    {  18148   ,   -3195   } , \n    {  18132   ,   -3284   } , \n    {  18116   ,   -3373   } , \n    {  18099   ,   -3462   } , \n    {  18082   ,   -3551   } , \n    {  18064   ,   -3639   } , \n    {  18046   ,   -3728   } , \n    {  18027   ,   -3816   } , \n    {  18009   ,   -3905   } , \n    {  17989   ,   -3993   } , \n    {  17969   ,   -4081   } , \n    {  17949   ,   -4170   } , \n    {  17928   ,   -4258   } , \n    {  17907   ,   -4346   } , \n    {  17886   ,   -4434   } , \n    {  17864   ,   -4521   } , \n    {  17841   ,   -4609   } , \n    {  17818   ,   -4696   } , \n    {  17795   ,   -4784   } , \n    {  17772   ,   -4871   } , \n    {  17747   ,   -4958   } , \n    {  17723   ,   -5045   } , \n    {  17698   ,   -5132   } , \n    {  17672   ,   -5219   } , \n    {  17647   ,   -5306   } , \n    {  17620   ,   -5392   } , \n    {  17594   ,   -5479   } , \n    {  17567   ,   -5565   } , \n    {  17539   ,   -5651   } , \n    {  17511   ,   -5737   } , \n    {  17483   ,   -5823   } , \n    {  17454   ,   -5909   } , \n    {  17425   ,   -5994   } , \n    {  17395   ,   -6080   } , \n    {  17365   ,   -6165   } , \n    {  17335   ,   -6250   } , \n    {  17304   ,   -6335   } , \n    {  17272   ,   -6420   } , \n    {  17241   ,   -6505   } , \n    {  17208   ,   -6590   } , \n    {  17176   ,   -6674   } , \n    {  17143   ,   -6758   } , \n    {  17110   ,   -6842   } , \n    {  17076   ,   -6926   } , \n    {  17042   ,   -7010   } , \n    {  17007   ,   -7093   } , \n    {  16972   ,   -7177   } , \n    {  16937   ,   -7260   } , \n    {  16901   ,   -7343   } , \n    {  16864   ,   -7426   } , \n    {  16828   ,   -7509   } , \n    {  16791   ,   -7591   } , \n    {  16753   ,   -7674   } , \n    {  16715   ,   -7756   } , \n    {  16677   ,   -7838   } , \n    {  16638   ,   -7919   } , \n    {  16599   ,   -8001   } , \n    {  16560   ,   -8082   } , \n    {  16520   ,   -8164   } , \n    {  16480   ,   -8245   } , \n    {  16439   ,   -8325   } , \n    {  16398   ,   -8406   } , \n    {  16357   ,   -8486   } , \n    {  16315   ,   -8567   } , \n    {  16272   ,   -8647   } , \n    {  16230   ,   -8726   } , \n    {  16187   ,   -8806   } , \n    {  16143   ,   -8885   } , \n    {  16100   ,   -8964   } , \n    {  16055   ,   -9043   } , \n    {  16011   ,   -9122   } , \n    {  15966   ,   -9200   } , \n    {  15920   ,   -9279   } , \n    {  15875   ,   -9357   } , \n    {  15829   ,   -9435   } , \n    {  15782   ,   -9512   } , \n    {  15735   ,   -9589   } , \n    {  15688   ,   -9667   } , \n    {  15640   ,   -9744   } , \n    {  15592   ,   -9820   } , \n    {  15544   ,   -9897   } , \n    {  15495   ,   -9973   } , \n    {  15446   ,   -10049   } , \n    {  15396   ,   -10124   } , \n    {  15347   ,   -10200   } , \n    {  15296   ,   -10275   } , \n    {  15246   ,   -10350   } , \n    {  15195   ,   -10425   } , \n    {  15143   ,   -10499   } , \n    {  15092   ,   -10573   } , \n    {  15040   ,   -10647   } , \n    {  14987   ,   -10721   } , \n    {  14934   ,   -10794   } , \n    {  14881   ,   -10868   } , \n    {  14828   ,   -10941   } , \n    {  14774   ,   -11013   } , \n    {  14719   ,   -11086   } , \n    {  14665   ,   -11158   } , \n    {  14610   ,   -11230   } , \n    {  14555   ,   -11301   } , \n    {  14499   ,   -11372   } , \n    {  14443   ,   -11444   } , \n    {  14387   ,   -11514   } , \n    {  14330   ,   -11585   } , \n    {  14273   ,   -11655   } , \n    {  14216   ,   -11725   } , \n    {  14158   ,   -11795   } , \n    {  14100   ,   -11864   } , \n    {  14041   ,   -11933   } , \n    {  13983   ,   -12002   } , \n    {  13924   ,   -12070   } , \n    {  13864   ,   -12138   } , \n    {  13804   ,   -12206   } , \n    {  13744   ,   -12274   } , \n    {  13684   ,   -12341   } , \n    {  13623   ,   -12408   } , \n    {  13562   ,   -12475   } , \n    {  13501   ,   -12541   } , \n    {  13439   ,   -12608   } , \n    {  13377   ,   -12673   } , \n    {  13314   ,   -12739   } , \n    {  13252   ,   -12804   } , \n    {  13189   ,   -12869   } , \n    {  13125   ,   -12934   } , \n    {  13062   ,   -12998   } \n    };\ncos_msin_t\ts_cos_msin_64[DCT_LENGTH] = {\n{18426,\t-21},\n{18426,\t-66},\n{18426,\t-110},\n{18426,\t-154},\n{18425,\t-198},\n{18425,\t-242},\n{18424,\t-286},\n{18424,\t-331},\n{18423,\t-374},\n{18421,\t-419},\n{18421,\t-463},\n{18419,\t-507},\n{18418,\t-552},\n{18417,\t-595},\n{18415,\t-639},\n{18414,\t-684},\n{18412,\t-728},\n{18410,\t-772},\n{18408,\t-816},\n{18406,\t-860},\n{18404,\t-904},\n{18402,\t-949},\n{18400,\t-992},\n{18397,\t-1037},\n{18394,\t-1081},\n{18392,\t-1125},\n{18389,\t-1169},\n{18387,\t-1213},\n{18384,\t-1257},\n{18380,\t-1301},\n{18378,\t-1345},\n{18374,\t-1389},\n{18371,\t-1433},\n{18367,\t-1477},\n{18364,\t-1521},\n{18360,\t-1566},\n{18356,\t-1609},\n{18352,\t-1653},\n{18348,\t-1697},\n{18344,\t-1742},\n{18339,\t-1785},\n{18335,\t-1829},\n{18331,\t-1873},\n{18326,\t-1917},\n{18322,\t-1961},\n{18317,\t-2005},\n{18312,\t-2049},\n{18307,\t-2092},\n{18302,\t-2137},\n{18297,\t-2180},\n{18292,\t-2224},\n{18286,\t-2268},\n{18281,\t-2312},\n{18275,\t-2356},\n{18270,\t-2399},\n{18264,\t-2443},\n{18258,\t-2487},\n{18252,\t-2531},\n{18246,\t-2574},\n{18240,\t-2618},\n{18233,\t-2662},\n{18227,\t-2706},\n{18220,\t-2749},\n{18214,\t-2793},\n{18207,\t-2836},\n{18200,\t-2880},\n{18193,\t-2924},\n{18186,\t-2967},\n{18179,\t-3011},\n{18172,\t-3055},\n{18164,\t-3098},\n{18157,\t-3142},\n{18149,\t-3185},\n{18141,\t-3229},\n{18134,\t-3272},\n{18126,\t-3316},\n{18118,\t-3359},\n{18109,\t-3403},\n{18101,\t-3446},\n{18094,\t-3489},\n{18085,\t-3533},\n{18076,\t-3576},\n{18068,\t-3619},\n{18059,\t-3663},\n{18050,\t-3706},\n{18041,\t-3749},\n{18032,\t-3792},\n{18023,\t-3836},\n{18014,\t-3879},\n{18005,\t-3922},\n{17995,\t-3965},\n{17986,\t-4008},\n{17975,\t-4051},\n{17966,\t-4094},\n{17956,\t-4138},\n{17946,\t-4180},\n{17936,\t-4224},\n{17926,\t-4266},\n{17916,\t-4309},\n{17905,\t-4353},\n{17895,\t-4395},\n{17884,\t-4438},\n{17874,\t-4481},\n{17863,\t-4524},\n{17852,\t-4567},\n{17841,\t-4609},\n{17830,\t-4652},\n{17819,\t-4695},\n{17807,\t-4738},\n{17796,\t-4780},\n{17784,\t-4823},\n{17772,\t-4865},\n{17761,\t-4908},\n{17749,\t-4951},\n{17738,\t-4993},\n{17725,\t-5036},\n{17713,\t-5078},\n{17701,\t-5121},\n{17689,\t-5163},\n{17676,\t-5205},\n{17664,\t-5248},\n{17651,\t-5290},\n{17638,\t-5333},\n{17626,\t-5375},\n{17613,\t-5417},\n{17599,\t-5459},\n{17586,\t-5501},\n{17573,\t-5544},\n{17560,\t-5586},\n{17546,\t-5627},\n{17533,\t-5670},\n{17519,\t-5712},\n{17505,\t-5753},\n{17492,\t-5795},\n{17478,\t-5837},\n{17464,\t-5879},\n{17450,\t-5921},\n{17435,\t-5963},\n{17421,\t-6005},\n{17406,\t-6046},\n{17392,\t-6088},\n{17377,\t-6130},\n{17363,\t-6172},\n{17348,\t-6213},\n{17333,\t-6254},\n{17318,\t-6296},\n{17303,\t-6338},\n{17288,\t-6379},\n{17272,\t-6420},\n{17257,\t-6462},\n{17241,\t-6503},\n{17225,\t-6545},\n{17210,\t-6586},\n{17194,\t-6627},\n{17178,\t-6668},\n{17162,\t-6709},\n{17145,\t-6750},\n{17130,\t-6791},\n{17113,\t-6832},\n{17097,\t-6874},\n{17080,\t-6915},\n{17064,\t-6956},\n{17047,\t-6996},\n{17030,\t-7037},\n{17013,\t-7078},\n{16996,\t-7119},\n{16979,\t-7159},\n{16962,\t-7200},\n{16945,\t-7241},\n{16927,\t-7281},\n{16910,\t-7322},\n{16892,\t-7362},\n{16874,\t-7403},\n{16856,\t-7444},\n{16838,\t-7484},\n{16821,\t-7524},\n{16802,\t-7564},\n{16784,\t-7605},\n{16766,\t-7645},\n{16748,\t-7685},\n{16729,\t-7725},\n{16711,\t-7765},\n{16692,\t-7805},\n{16674,\t-7845},\n{16654,\t-7885},\n{16635,\t-7925},\n{16616,\t-7964},\n{16597,\t-8004},\n{16578,\t-8044},\n{16559,\t-8084},\n{16539,\t-8124},\n{16520,\t-8164},\n{16500,\t-8203},\n{16480,\t-8242},\n{16461,\t-8282},\n{16441,\t-8322},\n{16421,\t-8361},\n{16401,\t-8400},\n{16380,\t-8440},\n{16360,\t-8479},\n{16340,\t-8518},\n{16319,\t-8557},\n{16299,\t-8597},\n{16278,\t-8635},\n{16257,\t-8674},\n{16237,\t-8713},\n{16215,\t-8752},\n{16195,\t-8791},\n{16173,\t-8829},\n{16152,\t-8868},\n{16131,\t-8907},\n{16110,\t-8946},\n{16088,\t-8985},\n{16067,\t-9023},\n{16045,\t-9061},\n{16023,\t-9100},\n{16001,\t-9138},\n{15979,\t-9176},\n{15957,\t-9215},\n{15935,\t-9253},\n{15913,\t-9291},\n{15891,\t-9329},\n{15868,\t-9367},\n{15846,\t-9405},\n{15823,\t-9443},\n{15800,\t-9481},\n{15778,\t-9519},\n{15755,\t-9557},\n{15732,\t-9595},\n{15709,\t-9632},\n{15686,\t-9670},\n{15662,\t-9708},\n{15639,\t-9745},\n{15615,\t-9782},\n{15592,\t-9820},\n{15569,\t-9857},\n{15544,\t-9894},\n{15521,\t-9932},\n{15497,\t-9969},\n{15473,\t-10006},\n{15449,\t-10043},\n{15425,\t-10080},\n{15401,\t-10117},\n{15377,\t-10154},\n{15352,\t-10191},\n{15327,\t-10227},\n{15303,\t-10264},\n{15278,\t-10301},\n{15254,\t-10337},\n{15229,\t-10374},\n{15204,\t-10411},\n{15180,\t-10447},\n{15154,\t-10483},\n{15129,\t-10519},\n{15104,\t-10556},\n{15078,\t-10592},\n{15053,\t-10628},\n{15027,\t-10664},\n{15002,\t-10700},\n{14976,\t-10736},\n{14950,\t-10772},\n{14924,\t-10808},\n{14898,\t-10844},\n{14872,\t-10879},\n{14846,\t-10915},\n{14820,\t-10950},\n{14794,\t-10985},\n{14767,\t-11021},\n{14741,\t-11056},\n{14714,\t-11092},\n{14687,\t-11127},\n{14661,\t-11162},\n{14635,\t-11197},\n{14607,\t-11232},\n{14581,\t-11267},\n{14554,\t-11302},\n{14526,\t-11337},\n{14499,\t-11372},\n{14472,\t-11407},\n{14444,\t-11441},\n{14417,\t-11476},\n{14389,\t-11511},\n{14362,\t-11545},\n{14334,\t-11579},\n{14306,\t-11614},\n{14278,\t-11648},\n{14251,\t-11682},\n{14222,\t-11716},\n{14194,\t-11750},\n{14166,\t-11784},\n{14137,\t-11818},\n{14109,\t-11852},\n{14081,\t-11886},\n{14053,\t-11919},\n{14023,\t-11953},\n{13995,\t-11987},\n{13966,\t-12020},\n{13937,\t-12054},\n{13909,\t-12087},\n{13879,\t-12120},\n{13851,\t-12153},\n{13821,\t-12187},\n{13792,\t-12220},\n{13763,\t-12253},\n{13733,\t-12286},\n{13704,\t-12319},\n{13674,\t-12351},\n{13645,\t-12385},\n{13615,\t-12417},\n{13585,\t-12450},\n{13555,\t-12482},\n{13525,\t-12514},\n{13495,\t-12546},\n{13465,\t-12579},\n{13435,\t-12611},\n{13405,\t-12644},\n{13374,\t-12676},\n{13345,\t-12708},\n{13314,\t-12739},\n{13283,\t-12772}\n};\n\n\n\ncos_msin_t\t*s_cos_msin_table[] = {s_cos_msin_2,  s_cos_msin_4,\n                                   s_cos_msin_8,  s_cos_msin_16,\n                                   s_cos_msin_32, s_cos_msin_64\n                                  };\n\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/decode/decoder.c",
    "content": "/***************************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**   All rights reserved.\n**\n***************************************************************************/\n\n/***************************************************************************\n  Filename:    decoder.c    \n\n  Purpose:     Contains files used to implement the G.722.1 Annex C decoder\n\t\t\n  Design Notes:\n\n***************************************************************************/\n\n/***************************************************************************\n Include files                                                           \n***************************************************************************/\n#include \"defs.h\"\n#include \"tables.h\"\n#include \"huff_def.h\"\n#include \"count.h\"\n\n\n/***************************************************************************\n Function:    decoder\n\n Syntax:      void decoder(Bit_Obj *bitobj,                   \n                           Rand_Obj *randobj,             \n                           Word16 number_of_regions,\n                           Word16 *decoder_mlt_coefs,     \n                           Word16 *p_mag_shift,           \n                           Word16 *p_old_mag_shift,       \n                           Word16 *old_decoder_mlt_coefs,    \n                           Word16 frame_error_flag)      \n              \n              inputs:    Bit_Obj *bitobj\n                         Rand_Obj *randobj\n                         Word16 number_of_regions\n                         Word16 *p_old_mag_shift\n                         Word16 *old_decoder_mlt_coefs\n                         Word16 frame_error_flag\n              \n              outputs:   Word16 *decoder_mlt_coefs,    \n                         Word16 *p_mag_shift,          \n                  \n                  \n\n Description: Decodes the out_words into mlt coefs using G.722.1 Annex C\n\n Design Notes:\n \n WMOPS:     7kHz |   24kbit    |    32kbit\n          -------|-------------|----------------\n            AVG  |    0.84     |    0.94\n          -------|-------------|----------------  \n            MAX  |    0.90     |    1.00\n          -------|-------------|---------------- \n\t\t\t\t\n           14kHz |   24kbit    |    32kbit      |     48kbit\n          -------|-------------|----------------|----------------\n            AVG  |    1.31     |    1.56        |     1.88   \n          -------|-------------|----------------|----------------\n            MAX  |    1.59     |    1.80        |     1.98   \n          -------|-------------|----------------|----------------\n\t\t\t\t\n***************************************************************************/\nvoid decoder(Bit_Obj *bitobj,\n             Rand_Obj *randobj,\n             Word16 number_of_regions,\n\t         Word16 *decoder_mlt_coefs,\n\t         Word16 *p_mag_shift,\n             Word16 *p_old_mag_shift,\n             Word16 *old_decoder_mlt_coefs,\n             Word16 frame_error_flag)\n{\n\n\n    Word16  absolute_region_power_index[MAX_NUMBER_OF_REGIONS];\n    Word16  decoder_power_categories[MAX_NUMBER_OF_REGIONS];\n    Word16  decoder_category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1];\n    UWord16 categorization_control;\n    Word16  decoder_region_standard_deviation[MAX_NUMBER_OF_REGIONS];\n    Word16  i;\n\n    Word16  num_categorization_control_bits;\n    Word16  num_categorization_control_possibilities;\n    Word16  number_of_coefs;\n    Word16  number_of_valid_coefs;\n    \n    \n    test();\n    if (number_of_regions==NUMBER_OF_REGIONS)\n    {\n        num_categorization_control_bits = NUM_CATEGORIZATION_CONTROL_BITS;\n        move16();\n        num_categorization_control_possibilities = NUM_CATEGORIZATION_CONTROL_POSSIBILITIES;\n        move16();\n        number_of_coefs = DCT_LENGTH;\n        move16();\n        number_of_valid_coefs = NUMBER_OF_VALID_COEFS;\n        move16();\n    }\n    else\n    {\n        num_categorization_control_bits = MAX_NUM_CATEGORIZATION_CONTROL_BITS;\n        move16();\n        num_categorization_control_possibilities = MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES;\n        move16();\n        number_of_coefs = MAX_DCT_LENGTH;\n        move16();\n        number_of_valid_coefs = MAX_NUMBER_OF_VALID_COEFS;\n        move16();\n    }\n\n    test();\n    if (frame_error_flag == 0) \n    {\n\n        /* convert the bits to absolute region power index and decoder_region_standard_deviation */\n        \n        decode_envelope(bitobj,\n                        number_of_regions,\n                        decoder_region_standard_deviation,\n\t\t                absolute_region_power_index,\n\t\t                p_mag_shift);\n\n        /* fill the categorization_control with NUM_CATEGORIZATION_CONTROL_BITS */\n        categorization_control = 0;\n        for (i=0; i<num_categorization_control_bits; i++) \n        {\n        \tget_next_bit(bitobj);\n        \tcategorization_control = shl_nocheck(categorization_control,1);\n        \tcategorization_control = add(categorization_control,bitobj->next_bit);\n        }\n        \n        bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,num_categorization_control_bits);\n\n        /* obtain decoder power categories and category balances */\n        /* based on the absolute region power index              */\n        categorize(bitobj->number_of_bits_left,\n\t               number_of_regions,\n\t               num_categorization_control_possibilities,\n\t               absolute_region_power_index,\n\t               decoder_power_categories,\n\t               decoder_category_balances);\n\n        /* perform adjustmaents to the power categories and category balances based on the cat control */\n        rate_adjust_categories(categorization_control,\n\t\t\t                   decoder_power_categories,\n\t\t\t                   decoder_category_balances);\n\n        /* decode the quantized bits into mlt coefs */\n        decode_vector_quantized_mlt_indices(bitobj,\n                                            randobj,\n                                            number_of_regions,\n                                            decoder_region_standard_deviation,\n\t\t\t\t\t                        decoder_power_categories,\n\t\t\t\t\t                        decoder_mlt_coefs);\n\n        /* test for frame errors */\n        test_4_frame_errors(bitobj,\n                            number_of_regions,\n                            num_categorization_control_possibilities,\n                            &frame_error_flag,\n                            categorization_control,\n                            absolute_region_power_index);\n    }\n\n    /* perform error handling operations */\n    error_handling(number_of_coefs,\n                   number_of_valid_coefs,\n                   &frame_error_flag,\n                   decoder_mlt_coefs,\n                   old_decoder_mlt_coefs,\n                   p_mag_shift,\n                   p_old_mag_shift);\n\n}\n\n/***************************************************************************\n Function:    decode_envelope\n\n Syntax:      void decode_envelope(Bit_Obj *bitobj,                              \n                                   Word16  number_of_regions,\n                                   Word16  *decoder_region_standard_deviation,   \n                                   Word16  *absolute_region_power_index,         \n                                   Word16  *p_mag_shift)                         \n              \n              inputs:   Bit_Obj *bitobj\n                        Word16  number_of_regions\n                        \n                        \n              outputs:  Word16  *decoder_region_standard_deviation\n                        Word16  *absolute_region_power_index\n                        Word16  *p_mag_shift\n              \n \n Description: Recover differential_region_power_index from code bits\n\n Design Notes:\n \n WMOPS:     7kHz |    24kbit    |    32kbit\n          -------|--------------|----------------\n            AVG  |     0.04     |    0.04\n          -------|--------------|----------------  \n            MAX  |     0.05     |    0.05\n          -------|--------------|---------------- \n\t\t\t\t\n           14kHz |    24kbit    |    32kbit      |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |     0.08     |    0.08        |     0.08   \n          -------|--------------|----------------|----------------\n            MAX  |     0.10     |    0.10        |     0.10   \n          -------|--------------|----------------|----------------\n\t\t\t\t\n***************************************************************************/\nvoid decode_envelope(Bit_Obj *bitobj,\n                     Word16  number_of_regions,\n                     Word16  *decoder_region_standard_deviation,\n\t\t             Word16  *absolute_region_power_index,\n\t\t             Word16  *p_mag_shift)\n     \n{\n    Word16 region;\n    Word16 i;\n    Word16 index;\n    Word16 differential_region_power_index[MAX_NUMBER_OF_REGIONS];\n    Word16 max_index;\n    \n    Word16 temp;\n    Word16 temp1;\n    Word16 temp2;\n    Word32 acca;\n\n    index = 0;\n    move16();\n\n    /* get 5 bits from the current code word */\n    for (i=0; i<5; i++) \n    {\n        get_next_bit(bitobj);\n        index = shl_nocheck(index,1);\n        index = add(index,bitobj->next_bit);\n    }\n    bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,5);\n\n    /* ESF_ADJUSTMENT_TO_RMS_INDEX compensates for the current (9/30/96)\n        IMLT being scaled to high by the ninth power of sqrt(2). */\n    differential_region_power_index[0] = sub(index,ESF_ADJUSTMENT_TO_RMS_INDEX);\n    move16();\n\n    /* obtain differential_region_power_index */\n    for (region=1; region<number_of_regions; region++) \n    {\n        index = 0;\n        move16();\n        do \n        {\n            get_next_bit(bitobj);\n            test();\n            if (bitobj->next_bit == 0)\n            {\n\t            index = differential_region_power_decoder_tree[region][index][0];\n                move16();\n            }\n            else\n            {\n\t            index = differential_region_power_decoder_tree[region][index][1];\n                move16();\n            }\n            bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,1);\n            test();\n        } while (index > 0);\n        \n        differential_region_power_index[region] = negate(index);\n        move16();\n    }\n\n    /* Reconstruct absolute_region_power_index[] from differential_region_power_index[]. */\n    absolute_region_power_index[0] = differential_region_power_index[0];\n    move16();\n    for (region=1; region<number_of_regions; region++) \n    {\n        acca = L_add(absolute_region_power_index[region-1],differential_region_power_index[region]);\n        acca = L_add(acca,DRP_DIFF_MIN);\n        absolute_region_power_index[region] = extract_l(acca);        \n    }\n\n    /* Reconstruct decoder_region_standard_deviation[] from absolute_region_power_index[]. */\n    /* DEBUG!!!! - This integer method jointly computes the mag_shift\n       and the standard deviations already mag_shift compensated. It\n       relies on REGION_POWER_STEPSIZE_DB being exactly 3.010299957 db\n       or a square root of 2 chnage in standard deviation. If\n       REGION_POWER_STEPSIZE_DB changes, this software must be\n       reworked. */\n\n    temp = 0;\n    move16();\n    max_index = 0;\n    move16();\n    for (region=0; region<number_of_regions; region++) \n    {\n        acca = L_add(absolute_region_power_index[region],REGION_POWER_TABLE_NUM_NEGATIVES);\n        i = extract_l(acca);\n        \n        temp1 = sub(i,max_index);\n        test();\n        if (temp1 > 0) \n        {\n            max_index = i;\n            move16();\n        }\n        temp = add(temp,int_region_standard_deviation_table[i]);\n    }\n    i = 9;\n    move16();\n\n    temp1 = sub(temp,8);\n    temp2 = sub(max_index,28);\n    test();\n    test();\n    logic16();\n    test();\n    logic16();\n    while ((i >= 0) && ((temp1 >= 0) || (temp2 > 0))) \n    {\n        i = sub(i,1);\n        temp = shr_nocheck(temp,1);\n        max_index = sub(max_index,2);\n        temp1 = sub(temp,8);\n        temp2 = sub(max_index,28);\n        test();\n        test();\n        logic16();\n        test();\n        logic16();\n    }\n    \n    *p_mag_shift = i;\n    move16();\n    \n    /* pointer arithmetic */\n    temp = (Word16 )(REGION_POWER_TABLE_NUM_NEGATIVES + (*p_mag_shift * 2));\n    \n    for (region=0; region<number_of_regions; region++) \n    {\n        acca = L_add(absolute_region_power_index[region],temp);\n        i = extract_l(acca);\n        decoder_region_standard_deviation[region] = int_region_standard_deviation_table[i];\n        move16();\n    }\n\n}\n\n/***************************************************************************\n Function:     rate_adjust_categories\n\n Syntax:       void rate_adjust_categories(Word16 categorization_control,            \n                                           Word16 *decoder_power_categories,         \n                                           Word16 *decoder_category_balances)        \n               \n               inputs:    Word16 categorization_control,   \n                          Word16 *decoder_power_categories,\n                          Word16 *decoder_category_balances\n                          \n               outputs:   Word16 categorization_control,   \n                          Word16 *decoder_power_categories,\n \n Description:  Adjust the power categories based on the categorization control\n\n Design Notes:\n \n WMOPS:     7kHz |    24kbit    |    32kbit\n          -------|--------------|----------------\n            AVG  |    0.00      |    0.00\n          -------|--------------|----------------  \n            MAX  |    0.00      |    0.00\n          -------|--------------|---------------- \n\t\t\t\t\n           14kHz |    24kbit    |    32kbit      |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.00      |    0.00        |     0.00   \n          -------|--------------|----------------|----------------\n            MAX  |    0.01      |    0.01        |     0.01   \n          -------|--------------|----------------|----------------\n\t\t\t\t\n***************************************************************************/\nvoid rate_adjust_categories(Word16 categorization_control,\n\t\t\t                Word16 *decoder_power_categories,\n\t\t\t                Word16 *decoder_category_balances)\n{\n    Word16 i;\n    Word16 region;\n    \n    i = 0;\n    move16();\n\n    test();\n    while (categorization_control > 0) \n    {\n        region = decoder_category_balances[i++];\n        move16();\n        decoder_power_categories[region] = add(decoder_power_categories[region],1);\n        move16();\n        categorization_control = sub(categorization_control,1);\n    }\n\n}\n\n/***************************************************************************\n Function:    decode_vector_quantized_mlt_indices\n\n Syntax:      void decode_vector_quantized_mlt_indices(Bit_Obj  *bitobj,                                      \n                                                       Rand_Obj *randobj,                           \n                                                       Word16   number_of_regions,\n                                                       Word16   *decoder_region_standard_deviation, \n                                                       Word16   *decoder_power_categories,          \n                                                       Word16   *decoder_mlt_coefs)                 \n              inputs:    Bit_Obj  *bitobj                           \n                         Rand_Obj *randobj\n                         Word16   number_of_regions\n                         Word16   *decoder_region_standard_deviation\n                         Word16   *decoder_power_categories\n            \n            \n              outputs:   Word16   *decoder_mlt_coefs\n             \n\n Description: Decode MLT coefficients\n\n Design Notes:\n \n WMOPS:     7kHz |    24kbit    |    32kbit\n          -------|--------------|----------------\n            AVG  |    0.60      |    0.72\n          -------|--------------|----------------  \n            MAX  |    0.67      |    0.76\n          -------|--------------|---------------- \n\t\t\t\t\n           14kHz |    24kbit    |    32kbit      |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.77      |    0.98        |     1.28   \n          -------|--------------|----------------|----------------\n            MAX  |    1.05      |    1.18        |     1.36   \n          -------|--------------|----------------|----------------\n\t\t\t\t\n***************************************************************************/\nvoid decode_vector_quantized_mlt_indices(Bit_Obj  *bitobj,\n                                         Rand_Obj *randobj,\n                                         Word16   number_of_regions,\n                                         Word16   *decoder_region_standard_deviation,\n\t\t\t\t\t                     Word16   *decoder_power_categories,\n\t\t\t\t\t                     Word16   *decoder_mlt_coefs)\n{\n    Word16 standard_deviation;\n    Word16 *decoder_mlt_ptr;\n    Word16 decoder_mlt_value;\n    Word16 noifillpos;\n    Word16 noifillneg;\n    Word16 noise_fill_factor[3] = {5793,8192,23170};\n    Word16 region;\n    Word16 category;\n    Word16 j,n;\n    Word16 k[MAX_VECTOR_DIMENSION];\n    Word16 vec_dim;\n    Word16 num_vecs;\n    Word16 index;\n    Word16 bit=0;\n    Word16 signs_index=0;\n    Word16 num_sign_bits;\n    Word16 ran_out_of_bits_flag;\n    Word16 *decoder_table_ptr;\n    Word16 random_word;\n    \n    Word16 temp1;\n    Word16 temp;\n    Word32 acca;\n\n    ran_out_of_bits_flag = 0;\n    move16();\n\n    for (region=0; region<number_of_regions; region++) \n    {\n        category = (Word16)decoder_power_categories[region];\n        move16();\n        acca = L_mult0(region,REGION_SIZE);\n        index = extract_l(acca);\n        decoder_mlt_ptr = &decoder_mlt_coefs[index];\n        move16();\n        standard_deviation = decoder_region_standard_deviation[region];\n        move16();\n        \n        temp = sub(category,7);\n        test();\n        if (temp < 0)\n        {\n            /* Get the proper table of decoder tables, vec_dim, and num_vecs for the cat */\n            decoder_table_ptr = (Word16 *) table_of_decoder_tables[category];\n            move16();\n            vec_dim = vector_dimension[category];\n            move16();\n            num_vecs = number_of_vectors[category];\n            move16();\n            \n            for (n=0; n<num_vecs; n++) \n            {\n                index = 0;\n                move16();\n                \n                /* get index */\n                do \n                {\n                    test();\n                    if (bitobj->number_of_bits_left <= 0) \n                    {\n                        ran_out_of_bits_flag = 1;\n                        move16();\n    \t                break;\n    \t            }\n    \n    \t            get_next_bit(bitobj);\n\t                \n                    test();\n                    if (bitobj->next_bit == 0)\n\t                {\n                        temp = shl_nocheck(index,1);\n                        index = (Word16)*(decoder_table_ptr + temp);\n                        move16();\n                    }\n\t                else\n\t                {\n                        temp = shl_nocheck(index,1);\n                        index = (Word16)*(decoder_table_ptr + temp + 1);\n                        move16();\n                    }\n\t                bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,1);\n                    test();\n\t            \n                } while (index > 0);\n\t  \n                test();\n                if (ran_out_of_bits_flag != 0)\n\t                break;\n\t  \n                index = negate(index);\n\t            \n                /* convert index into array used to access the centroid table */\n                /* get the number of sign bits in the index */\n                num_sign_bits = index_to_array(index,k,category);\n\n\t            temp = sub(bitobj->number_of_bits_left,num_sign_bits);\n                test();\n                if (temp >= 0) \n                {\n\n\t                test();\n                    if (num_sign_bits != 0) \n                    {\n\t                    signs_index = 0;\n\t                    move16();\n                        for (j=0; j<num_sign_bits; j++) \n                        {\n\t\t                    get_next_bit(bitobj);\n       \t\t                signs_index = shl_nocheck(signs_index,1);\n\t\t                    signs_index = add(signs_index,bitobj->next_bit);\n\t\t                    bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,1);\n\t                    }\n\t                    temp = sub(num_sign_bits,1);\n                        bit = shl_nocheck(1,(temp));\n\t                }\n\t                \n                    for (j=0; j<vec_dim; j++) \n                    {\n\t                    acca = L_mult0(standard_deviation,mlt_quant_centroid[category][k[j]]);\n                        acca = L_shr_nocheck(acca,12);\n                        decoder_mlt_value = extract_l(acca);\n\t                    \n                        test();\n                        if (decoder_mlt_value != 0) \n                        {\n\t\t                    test();\n                            if ((signs_index & bit) == 0)\n\t\t                        decoder_mlt_value = negate(decoder_mlt_value);\n\t\t                    bit = shr_nocheck(bit,1);\n\t                    }\n                        *decoder_mlt_ptr++ = decoder_mlt_value;\n                        move16();\n\t                }\n\t            }\n\t            else \n                {\n\t                ran_out_of_bits_flag = 1;\n                    move16();\n\t                break;\n\t            }\n\t        }\n            /* If ran out of bits during decoding do noise fill for remaining regions. */\n            /* DEBUG!! - For now also redo all of last region with all noise fill. */\n        \ttest();\n            if (ran_out_of_bits_flag != 0) \n            {\n        \t    temp = add(region,1);\n                for (j=temp; j<number_of_regions; j++)\n                {\n                    decoder_power_categories[j] = 7;\n                    move16();\n                }\n        \t    category = 7;\n                move16();\n        \t    decoder_mlt_ptr = &decoder_mlt_coefs[region*REGION_SIZE];\n                move16();\n        \t}\n        }\n\n        temp = sub(category,5);\n        temp1 = sub(category,6);\n        test();\n        test();\n        logic16();\n        if ((temp == 0) || (temp1 == 0))\n        {\n \n\t        decoder_mlt_ptr = &decoder_mlt_coefs[region*REGION_SIZE];\n\t        move16();\n            noifillpos = mult(standard_deviation,noise_fill_factor[category - 5]);\n            noifillneg = negate(noifillpos);\n\n\t        random_word = get_rand(randobj);\n\n\t        for (j=0; j<10; j++) \n            {\n\t            test();\n                if (*decoder_mlt_ptr == 0) \n                {\n\t                logic16();\n                    test();\n                    if ((random_word & 1) == 0) \n                    {\n                        temp1 = noifillneg;\n                        move16();\n                    }\n\t                else\n                    {\n                        temp1 = noifillpos;\n                        move16();\n                    }\n\t                *decoder_mlt_ptr = temp1;\n                    move16();\n\t                random_word = shr_nocheck(random_word,1);\n\t            }\n\t            /* pointer arithmetic */\n                decoder_mlt_ptr++;\n\t        }\n\t        random_word = get_rand(randobj);\n\t        for (j=0; j<10; j++) \n            {\n\t            test();\n                if (*decoder_mlt_ptr == 0) \n                {\n\t                logic16();\n                    test();\n                    if ((random_word & 1) == 0) \n                    {\n                        temp1 = noifillneg;\n                        move16();\n                    }\n\t                else\n                    {\n                        temp1 = noifillpos;\n                        move16();\n                    }\n\t                *decoder_mlt_ptr = temp1;\n                    move16();\n\t                random_word  = shr_nocheck(random_word,1);\n\t            }\n\t            /* pointer arithmetic */\n                decoder_mlt_ptr++;\n\t        }\n        }\n\n        /* if (category == 7) */\n        temp1 = sub(category,7);\n        test();\n        if (temp1 == 0)\n        {\n\t        index = sub(category,5);\n            noifillpos = mult(standard_deviation,noise_fill_factor[index]);\n\t        noifillneg = negate(noifillpos);\n\n            random_word = get_rand(randobj);\n            for (j=0; j<10; j++) \n            {\n                logic16();\n                test();\n                if ((random_word & 1) == 0) \n                {\n                    temp1 = noifillneg;\n                    move16();\n                }\n                else\n                {\n                    temp1 = noifillpos;\n                    move16();\n                }\n                *decoder_mlt_ptr++ = temp1;\n                move16();\n                random_word = shr_nocheck(random_word,1);\n            }\n            random_word = get_rand(randobj);\n            for (j=0; j<10; j++) \n            {\n                logic16();\n                test();\n                if ((random_word & 1) == 0) \n                {\n                    temp1 = noifillneg;\n                    move16();\n                }\n                else\n                {\n                    temp1 = noifillpos;\n                    move16();\n                }\n                \n                *decoder_mlt_ptr++ = temp1;\n                move16();\n                random_word = shr_nocheck(random_word,1);\n            }\n        }\n    }\n\n    test();\n    if (ran_out_of_bits_flag)\n        bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,1);\n}\n/****************************************************************************************\n Function:    index_to_array \n\n Syntax:      number_of_non_zero = index_to_array(Word16 index, \n                                                  Word16 array[MAX_VECTOR_DIMENSION],\n                                                  Word16 category)\n\n                inputs:  Word16 index\n                         Word16 category                     \n                       \n                outputs: Word16 array[MAX_VECTOR_DIMENSION] - used in decoder to access\n                                                             mlt_quant_centroid table\n                        \n                         Word16 number_of_non_zero          - number of non zero elements\n                                                             in the array\n \n Description: Computes an array of sign bits with the length of the category vector\n              Returns the number of sign bits and the array\n\n WMOPS:     7kHz |    24kbit    |    32kbit\n          -------|--------------|----------------\n            AVG  |     0.00     |     0.00\n          -------|--------------|----------------  \n            MAX  |     0.00     |     0.00\n          -------|--------------|---------------- \n\n           14kHz |    24kbit    |    32kbit      |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |     0.00     |     0.00       |      0.00   \n          -------|--------------|----------------|----------------\n            MAX  |     0.00     |     0.00       |      0.00   \n          -------|--------------|----------------|----------------\n\n****************************************************************************************/\nWord16 index_to_array(Word16 index,Word16 *array,Word16 category)\n{\n    Word16 j,q,p;\n    Word16 number_of_non_zero;\n    Word16 max_bin_plus_one;\n    Word16 inverse_of_max_bin_plus_one;\n    Word16 temp;\n\n    number_of_non_zero = 0;\n    move16();\n\n    p = index;\n    move16();\n\n    max_bin_plus_one = add(max_bin[category],1);\n    inverse_of_max_bin_plus_one = max_bin_plus_one_inverse[category];\n    move16();\n\n    temp = sub(vector_dimension[category],1);\n    for (j=temp; j>=0; j--) \n    {\n        q = mult(p,inverse_of_max_bin_plus_one);\n\t\ttemp = extract_l(L_mult0(q,max_bin_plus_one));\n        array[j] = sub(p,temp);\n        move16();\n\n        p = q;\n        move16();\n\n        temp = array[j];\n        move16();\n        test();\n        if (temp != 0) \n            number_of_non_zero = add(number_of_non_zero,1);\n    }\n    return(number_of_non_zero);\n}\n/***************************************************************************\n Function:     test_4_frame_errors\n\n Syntax:       void test_4_frame_errors(Bit_Obj *bitobj,                        \n                                        Word16 number_of_regions,\n                                        Word16 num_categorization_control_possibilities,\n                                        Word16 *frame_error_flag,                \n                                        Word16 categorization_control,          \n                                        Word16 *absolute_region_power_index)    \n        \n               inputs:   bit_obj\n                         number_of_regions\n                         num_categorization_control_possibilities\n                         frame_error_flag\n                         categorization_control\n                         absolute_region_power_index\n               \n               \n               outputs:  frame_error_flag\n               \n               \n               \n        \n Description:  Tests for error conditions and sets the frame_error_flag accordingly \n\n Design Notes:\n \n WMOPS:     7kHz |    24kbit    |    32kbit\n          -------|--------------|----------------\n            AVG  |    0.01      |     0.01\n          -------|--------------|----------------  \n            MAX  |    0.04      |     0.08\n          -------|--------------|---------------- \n\t\t\t\t\n           14kHz |    24kbit    |    32kbit      |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.01      |     0.01       |      0.01   \n          -------|--------------|----------------|----------------\n            MAX  |    0.02      |     0.06       |      0.08   \n          -------|--------------|----------------|----------------\n\t\t\t\t\n***************************************************************************/\nvoid test_4_frame_errors(Bit_Obj *bitobj,\n                         Word16 number_of_regions,\n                         Word16 num_categorization_control_possibilities,\n                         Word16 *frame_error_flag,\n                         Word16 categorization_control,\n                         Word16 *absolute_region_power_index)\n{\n    Word16 region;\n    Word16 i;\n    Word16 temp;\n    Word32 acca;\n    Word32 accb;\n    \n    /* Test for bit stream errors. */\n\n    test();\n    if (bitobj->number_of_bits_left > 0) \n    {\n        for (i=0; i<bitobj->number_of_bits_left; i++) \n        {\n            get_next_bit(bitobj);\n            test();\n            if (bitobj->next_bit == 0) \n            {\n                *frame_error_flag = 1;\n                move16();\n            }\n        }\t\n    }\n    else \n    {\n        temp = sub(categorization_control,sub(num_categorization_control_possibilities,1));\n        test();\n        if (temp < 0) \n        {\n            test();\n            if (bitobj->number_of_bits_left < 0)\n            {\n                *frame_error_flag |= 2;\n                logic16();\n            }\n        }\n    }\n\n    /* checks to ensure that abs_region_power_index is within range */\n    /* the error flag is set if it is out of range */\n    for (region=0; region<number_of_regions; region++) \n    {\n        /*  the next two lines of comments were modified in release 1.2\n\t   *  to correct the description of the range of \n\t   *  absolute_region_power_index[] to be tested in the next\n\t   *  9 lines of code.\n\t   */\n\t  /*  if ((absolute_region_power_index[region] > 31) ||\n            (absolute_region_power_index[region] < -8) */\n\n        acca = L_add(absolute_region_power_index[region],ESF_ADJUSTMENT_TO_RMS_INDEX);\n        accb = L_sub(acca,31);\n        acca = L_add(acca,8);\n        test();\n\n        /* the next line was modifed in release 1.2 to\n\t   * correct miss typed code and error checking.\n\t   */\n        if ((accb > 0) || (acca < 0))\n        {\n            *frame_error_flag |= 4;\n            logic16();\n        }\n    }\n\n}\n/***************************************************************************\n Function:    error_handling\n\n Syntax:      void error_handling(Word16 number_of_coefs,\n                                  Word16 number_of_valid_coefs,\n                                  Word16 *frame_error_flag,     \n                                  Word16 *decoder_mlt_coefs,    \n                                  Word16 *old_decoder_mlt_coefs,\n                                  Word16 *p_mag_shift,          \n                                  Word16 *p_old_mag_shift)      \n              \n              inputs:  number_of_coefs\n                       number_of_valid_coefs\n                       frame_error_flag\n                       old_decoder_mlt_coefs\n                       p_old_mag_shift\n              \n              \n              outputs: decoder_mlt_coefs\n                       old_decoder_mlt_coefs\n                       p_mag_shift\n                       p_old_mag_shift\n \n       \n\n Description: If both the current and previous frames are errored,             \n              set the mlt coefficients to 0. If only the current frame         \n              is errored, then repeat the previous frame's mlt coefficients.   \n    \n Design Notes:\n \n WMOPS:     7kHz |    24kbit    |    32kbit\n          -------|--------------|----------------\n            AVG  |    0.02      |     0.02\n          -------|--------------|----------------  \n            MAX  |    0.03      |     0.03\n          -------|--------------|---------------- \n\t\t\t\t\n           14kHz |    24kbit    |    32kbit      |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.03      |     0.03       |     0.03   \n          -------|--------------|----------------|----------------\n            MAX  |    0.03      |     0.03       |     0.06   \n          -------|--------------|----------------|----------------\n\t\t\t\t\n***************************************************************************/\nvoid error_handling(Word16 number_of_coefs,\n                    Word16 number_of_valid_coefs,\n                    Word16 *frame_error_flag,\n                    Word16 *decoder_mlt_coefs,\n                    Word16 *old_decoder_mlt_coefs,\n                    Word16 *p_mag_shift,\n                    Word16 *p_old_mag_shift)\n{\n    Word16 i;\n\n    test();\n    if (*frame_error_flag != 0) \n    {\n\n        for (i = 0; i < number_of_valid_coefs; i++)\n        {\n            decoder_mlt_coefs[i] = old_decoder_mlt_coefs[i];\n            move16();\n        }\n\n        for (i = 0; i < number_of_valid_coefs; i++)\n        {\n            old_decoder_mlt_coefs[i] = 0;\n            move16();\n        }\n        \n        *p_mag_shift = *p_old_mag_shift;\n        move16();\n\n        *p_old_mag_shift = 0;\n        move16();\n    }\n    else \n    {\n        /* Store in case next frame is errored. */\n        for (i = 0; i < number_of_valid_coefs; i++)\n        {\n            old_decoder_mlt_coefs[i] = decoder_mlt_coefs[i];\n            move16();\n        }\n  \n        *p_old_mag_shift = *p_mag_shift;\n        move16();\n    }\n\n\n    /* Zero out the upper 1/8 of the spectrum. */\n    for (i = number_of_valid_coefs; i < number_of_coefs; i++)\n    {\n        decoder_mlt_coefs[i] = 0;\n        move16();\n    }\n\n}\n/****************************************************************************************\n Function:    get_next_bit\n\n Syntax:      void get_next_bit(Bit_Obj *bitobj)\n \n Description: Returns the next bit in the current word inside the bit object\n \n WMOPS:     7kHz |    24kbit    |    32kbit\n          -------|--------------|----------------\n            AVG  |    0.00      |    0.00\n          -------|--------------|----------------  \n            MAX  |    0.00      |    0.00\n          -------|--------------|---------------- \n\n           14kHz |    24kbit    |    32kbit      |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.00      |    0.00        |     0.00   \n          -------|--------------|----------------|----------------\n            MAX  |    0.00      |    0.00        |     0.00   \n          -------|--------------|----------------|----------------\n\n****************************************************************************************/\nvoid get_next_bit(Bit_Obj *bitobj)\n{\n    Word16 temp;\n\n    test();\n    if (bitobj->code_bit_count == 0)\n    {                        \n        bitobj->current_word = *bitobj->code_word_ptr++; \n        move16();\n        bitobj->code_bit_count = 16;           \n        move16();\n    }\n    bitobj->code_bit_count = sub(bitobj->code_bit_count,1);\n    temp = shr_nocheck(bitobj->current_word,bitobj->code_bit_count);\n    logic16();\n    bitobj->next_bit = (Word16 )(temp & 1);\n\n}\n/****************************************************************************************\n Function:    get_rand\n\n Syntax:      Word16 get_rand(Rand_Obj *randobj)\n \n Description: Returns a random Word16 based on the seeds inside the rand object  \n \n WMOPS:     7kHz |    24kbit    |    32kbit\n          -------|--------------|----------------\n            AVG  |    0.00      |    0.00\n          -------|--------------|----------------  \n            MAX  |    0.00      |    0.00\n          -------|--------------|---------------- \n\n           14kHz |    24kbit    |    32kbit      |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.00      |    0.00        |     0.00   \n          -------|--------------|----------------|----------------\n            MAX  |    0.00      |    0.00        |     0.00   \n          -------|--------------|----------------|----------------\n\n****************************************************************************************/\nWord16 get_rand(Rand_Obj *randobj)\n{\n    Word16 random_word;\n    Word32 acca;\n\n    acca = L_add(randobj->seed0,randobj->seed3); \n    random_word = extract_l(acca);\n    \n    logic16();\n    test();\n\tif ((random_word & 32768L) != 0)\n        random_word = add(random_word,1);\n    \n    randobj->seed3 = randobj->seed2;\n    move16();\n    randobj->seed2 = randobj->seed1;\n    move16();\n    randobj->seed1 = randobj->seed0;\n    move16();\n    randobj->seed0 = random_word;\n    move16();\n\n    return(random_word);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/encode/dct4_a.c",
    "content": "/*********************************************************************************\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**\t All rights reserved.\n**\n*********************************************************************************/\n\n/*********************************************************************************\n* Filename: dct_type_iv_a.c\n*\n* Purpose:  Discrete Cosine Transform, Type IV used for MLT\n*\n* The basis functions are\n*\n*\t cos(PI*(t+0.5)*(k+0.5)/block_length)\n*\n* for time t and basis function number k.  Due to the symmetry of the expression\n* in t and k, it is clear that the forward and inverse transforms are the same.\n*\n*********************************************************************************/\n\n/*********************************************************************************\n Include files                                                           \n*********************************************************************************/\n#include \"defs.h\"\n#include \"count.h\"\n#include \"dct4_a.h\"\n\n/*********************************************************************************\n External variable declarations                                          \n*********************************************************************************/\nextern Word16       anal_bias[DCT_LENGTH];\nextern Word16       dct_core_a[DCT_LENGTH_DIV_32][DCT_LENGTH_DIV_32];\nextern cos_msin_t   a_cos_msin_2 [DCT_LENGTH_DIV_32];\nextern cos_msin_t   a_cos_msin_4 [DCT_LENGTH_DIV_16];\nextern cos_msin_t   a_cos_msin_8 [DCT_LENGTH_DIV_8];\nextern cos_msin_t   a_cos_msin_16[DCT_LENGTH_DIV_4];\nextern cos_msin_t   a_cos_msin_32[DCT_LENGTH_DIV_2];\nextern cos_msin_t   a_cos_msin_64[DCT_LENGTH];\nextern cos_msin_t   *a_cos_msin_table[];\n\n/*********************************************************************************\n Function:    dct_type_iv_a\n\n Syntax:      void dct_type_iv_a (input, output, dct_length) \n                        Word16   input[], output[], dct_length;              \n\n Description: Discrete Cosine Transform, Type IV used for MLT\n\n Design Notes:\n                \n WMOPS:          |    24kbit    |     32kbit\n          -------|--------------|----------------\n            AVG  |    1.14      |     1.14\n          -------|--------------|----------------  \n            MAX  |    1.14      |     1.14\n          -------|--------------|---------------- \n                \n           14kHz |    24kbit    |     32kbit     |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    2.57      |     2.57       |     2.57\n          -------|--------------|----------------|----------------\n            MAX  |    2.57      |     2.57       |     2.57\n          -------|--------------|----------------|----------------\n\n*********************************************************************************/\n\nvoid dct_type_iv_a (Word16 *input,Word16 *output,Word16 dct_length)\n{\n    Word16   buffer_a[MAX_DCT_LENGTH], buffer_b[MAX_DCT_LENGTH], buffer_c[MAX_DCT_LENGTH];\n    Word16   *in_ptr, *in_ptr_low, *in_ptr_high, *next_in_base;\n    Word16   *out_ptr_low, *out_ptr_high, *next_out_base;\n    Word16   *out_buffer, *in_buffer, *buffer_swap;\n    Word16   in_val_low, in_val_high;\n    Word16   out_val_low, out_val_high;\n    Word16   in_low_even, in_low_odd;\n    Word16   in_high_even, in_high_odd;\n    Word16   out_low_even, out_low_odd;\n    Word16   out_high_even, out_high_odd;\n    Word16   *pair_ptr;\n    Word16   cos_even, cos_odd, msin_even, msin_odd;\n    Word16   neg_cos_odd;\n    Word16   neg_msin_even;\n    Word32   sum;\n    Word16   set_span, set_count, set_count_log, pairs_left, sets_left;\n    Word16   i,k;\n    Word16   index;\n    cos_msin_t  **table_ptr_ptr, *cos_msin_ptr;\n    \n    Word16   temp;\n    Word32   acca;\n\n    Word16   dct_length_log;\n\n\n    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n    /* Do the sum/difference butterflies, the first part of */\n    /* converting one N-point transform into N/2 two-point  */\n    /* transforms, where N = 1 << DCT_LENGTH_LOG. = 64/128  */\n    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n    test();\n    if (dct_length==DCT_LENGTH)\n    {\n        dct_length_log = DCT_LENGTH_LOG;\n\n        /* Add bias offsets */\n        for (i=0;i<dct_length;i++)\n        {\n            input[i] = add(input[i],anal_bias[i]);\n            move16();\n        }\n    }\n    else\n        dct_length_log = MAX_DCT_LENGTH_LOG;\n\n    index = 0L;\n    move16();\n\n    in_buffer  = input;\n    move16();\n\n    out_buffer = buffer_a;\n    move16();\n\n    temp = sub(dct_length_log,2);\n    for (set_count_log=0;set_count_log<=temp;set_count_log++)\n    {\n\n        /*===========================================================*/\n        /* Initialization for the loop over sets at the current size */\n        /*===========================================================*/\n\n        /*    set_span      = 1 << (DCT_LENGTH_LOG - set_count_log); */\n        set_span = shr_nocheck(dct_length,set_count_log);\n\n        set_count     = shl_nocheck(1,set_count_log);\n\n        in_ptr        = in_buffer;\n        move16();\n\n        next_out_base = out_buffer;\n        move16();\n\n        /*=====================================*/\n        /* Loop over all the sets of this size */\n        /*=====================================*/\n\n        for (sets_left=set_count;sets_left>0;sets_left--)\n        {\n\n            /*||||||||||||||||||||||||||||||||||||||||||||*/\n            /* Set up output pointers for the current set */\n            /*||||||||||||||||||||||||||||||||||||||||||||*/\n\n            out_ptr_low    = next_out_base;\n            next_out_base  = next_out_base + set_span;\n            out_ptr_high   = next_out_base;\n\n            /*||||||||||||||||||||||||||||||||||||||||||||||||||*/\n            /* Loop over all the butterflies in the current set */\n            /*||||||||||||||||||||||||||||||||||||||||||||||||||*/\n\n            do \n            {\n                in_val_low      = *in_ptr++;\n                in_val_high     = *in_ptr++;\n\t\t// blp: addition of two 16bits vars, there's no way\n\t\t//      they'll overflow a 32bit var\n                //acca            = L_add(in_val_low,in_val_high);\n\t\tacca = (in_val_low + in_val_high);\n\t\tacca            = L_shr_nocheck(acca,1);\n                out_val_low     = extract_l(acca);\n\n                acca            = L_sub(in_val_low,in_val_high);\n                acca            = L_shr_nocheck(acca,1);\n                out_val_high    = extract_l(acca);\n\n                *out_ptr_low++  = out_val_low;\n                *--out_ptr_high = out_val_high;\n\n                test();\n            } while (out_ptr_low < out_ptr_high);\n\n        } /* End of loop over sets of the current size */\n\n        /*============================================================*/\n        /* Decide which buffers to use as input and output next time. */\n        /* Except for the first time (when the input buffer is the    */\n        /* subroutine input) we just alternate the local buffers.     */\n        /*============================================================*/\n\n        in_buffer = out_buffer;\n        move16();\n        if (out_buffer == buffer_a)\n            out_buffer = buffer_b;\n        else\n            out_buffer = buffer_a;\n        index = add(index,1);\n\n    } /* End of loop over set sizes */\n\n\n    /*++++++++++++++++++++++++++++++++*/\n    /* Do N/2 two-point transforms,   */\n    /* where N =  1 << DCT_LENGTH_LOG */\n    /*++++++++++++++++++++++++++++++++*/\n\n    pair_ptr = in_buffer;\n    move16();\n\n    buffer_swap = buffer_c;\n    move16();\n\n    temp = sub(dct_length_log,1);\n    temp = shl_nocheck(1,temp);\n\n    for (pairs_left=temp; pairs_left > 0; pairs_left--)\n    {\n        for ( k=0; k<CORE_SIZE; k++ )\n        {\n#if PJ_HAS_INT64\n\t    /* blp: danger danger! not really compatible but faster */\n\t    pj_int64_t sum64=0;\n            move32();\n            \n            for ( i=0; i<CORE_SIZE; i++ )\n            {\n                sum64 += L_mult(pair_ptr[i], dct_core_a[i][k]);\n            }\n\t    sum = L_saturate(sum64);\n#else\n            sum=0L;\n            move32();\n            for ( i=0; i<CORE_SIZE; i++ )\n            {\n                sum = L_mac(sum, pair_ptr[i],dct_core_a[i][k]);\n            }\n#endif\n            buffer_swap[k] = itu_round(sum);\n        }\n        /* address arithmetic */\n        pair_ptr   += CORE_SIZE;\n        buffer_swap += CORE_SIZE;\n    }\n\n    for (i=0;i<dct_length;i++)\n    {\n        in_buffer[i] = buffer_c[i];\n        move16();\n    }\n    \n    table_ptr_ptr = a_cos_msin_table;\n\n    /*++++++++++++++++++++++++++++++*/\n    /* Perform rotation butterflies */\n    /*++++++++++++++++++++++++++++++*/\n    temp = sub(dct_length_log,2);\n    for (set_count_log = temp; set_count_log >= 0;    set_count_log--)\n    {\n        /*===========================================================*/\n        /* Initialization for the loop over sets at the current size */\n        /*===========================================================*/\n        /*    set_span      = 1 << (DCT_LENGTH_LOG - set_count_log); */\n        set_span = shr_nocheck(dct_length,set_count_log);\n\n        set_count     = shl_nocheck(1,set_count_log);\n        next_in_base  = in_buffer;\n        move16();\n\n        test();\n        if (set_count_log == 0)\n        {\n            next_out_base = output;\n        }\n        else\n        {\n            next_out_base = out_buffer;\n        }\n\n\n        /*=====================================*/\n        /* Loop over all the sets of this size */\n        /*=====================================*/\n        for (sets_left = set_count; sets_left > 0;sets_left--)\n        {\n            /*|||||||||||||||||||||||||||||||||||||||||*/\n            /* Set up the pointers for the current set */\n            /*|||||||||||||||||||||||||||||||||||||||||*/\n            in_ptr_low     = next_in_base;\n            move16();\n            temp           = shr_nocheck(set_span,1);\n\n            /* address arithmetic */\n            in_ptr_high    = in_ptr_low + temp;\n            next_in_base  += set_span;\n            out_ptr_low    = next_out_base;\n            next_out_base += set_span;\n            out_ptr_high   = next_out_base;\n            cos_msin_ptr   = *table_ptr_ptr;\n\n            /*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/\n            /* Loop over all the butterfly pairs in the current set */\n            /*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/\n\n            do \n            {\n                /* address arithmetic */\n                in_low_even     = *in_ptr_low++;\n                in_low_odd      = *in_ptr_low++;\n                in_high_even    = *in_ptr_high++;\n                in_high_odd     = *in_ptr_high++;\n                cos_even        = cos_msin_ptr[0].cosine;\n                move16();\n                msin_even       = cos_msin_ptr[0].minus_sine;\n                move16();\n                cos_odd         = cos_msin_ptr[1].cosine;\n                move16();\n                msin_odd        = cos_msin_ptr[1].minus_sine;\n                move16();\n                cos_msin_ptr   += 2;\n\n                sum = 0L;\n                sum=L_mac(sum,cos_even,in_low_even);\n                neg_msin_even = negate(msin_even);\n                sum=L_mac(sum,neg_msin_even,in_high_even);\n                out_low_even = itu_round(sum);\n\n                sum = 0L;\n                sum=L_mac(sum,msin_even,in_low_even);\n                sum=L_mac(sum,cos_even,in_high_even);\n                out_high_even= itu_round(sum);\n\n                sum = 0L;\n                sum=L_mac(sum,cos_odd,in_low_odd);\n                sum=L_mac(sum,msin_odd,in_high_odd);\n                out_low_odd= itu_round(sum);\n\n                sum = 0L;\n                sum=L_mac(sum,msin_odd,in_low_odd);\n                neg_cos_odd = negate(cos_odd);\n                sum=L_mac(sum,neg_cos_odd,in_high_odd);\n                out_high_odd= itu_round(sum);\n\n                *out_ptr_low++  = out_low_even;\n                *--out_ptr_high = out_high_even;\n                *out_ptr_low++  = out_low_odd;\n                *--out_ptr_high = out_high_odd;\n                test();\n            } while (out_ptr_low < out_ptr_high);\n\n        } /* End of loop over sets of the current size */\n\n        /*=============================================*/\n        /* Swap input and output buffers for next time */\n        /*=============================================*/\n\n        buffer_swap = in_buffer;\n        in_buffer   = out_buffer;\n        out_buffer  = buffer_swap;\n        table_ptr_ptr++;\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/encode/dct4_a.h",
    "content": "/****************************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**\t All rights reserved.\n**\n****************************************************************************/\n\n/****************************************************************************\n  Filename:    dct4_a.h    \n\n  Purpose:     Contains tables used by dct4_a.c\n\t\t\n  Design Notes:\n\n****************************************************************************/\n\n/***************************************************************************\n Include files                                                           \n***************************************************************************/\n#include <stdio.h>\n#include <math.h>\n\ntypedef struct \n{\n    Word16\tcosine;\n    Word16\tminus_sine;\n} cos_msin_t;\n\ncos_msin_t\ta_cos_msin_2[10] = {\n    {  29805   ,   -1171   } , \n    {  29621   ,   -3506   } , \n    {  29255   ,   -5819   } , \n    {  28708   ,   -8097   } , \n    {  27984   ,   -10324   } , \n    {  27088   ,   -12488   } , \n    {  26025   ,   -14575   } , \n    {  24801   ,   -16572   } , \n    {  23425   ,   -18466   } , \n    {  21903   ,   -20247   }  \n    }; \ncos_msin_t\ta_cos_msin_4[20] = {\n    {  29822   ,   -586   } , \n    {  29776   ,   -1756   } , \n    {  29684   ,   -2924   } , \n    {  29547   ,   -4087   } , \n    {  29364   ,   -5244   } , \n    {  29135   ,   -6392   } , \n    {  28862   ,   -7531   } , \n    {  28544   ,   -8659   } , \n    {  28182   ,   -9773   } , \n    {  27776   ,   -10871   } , \n    {  27328   ,   -11954   } , \n    {  26838   ,   -13017   } , \n    {  26306   ,   -14061   } , \n    {  25734   ,   -15083   } , \n    {  25122   ,   -16081   } , \n    {  24471   ,   -17055   } , \n    {  23783   ,   -18003   } , \n    {  23057   ,   -18923   } , \n    {  22297   ,   -19813   } , \n    {  21502   ,   -20673   } \n    };\ncos_msin_t\ta_cos_msin_8[40] = {\n    {  29827   ,   -293   } , \n    {  29815   ,   -878   } , \n    {  29792   ,   -1464   } , \n    {  29758   ,   -2048   } , \n    {  29712   ,   -2632   } , \n    {  29654   ,   -3215   } , \n    {  29586   ,   -3797   } , \n    {  29505   ,   -4377   } , \n    {  29414   ,   -4955   } , \n    {  29311   ,   -5532   } , \n    {  29196   ,   -6106   } , \n    {  29071   ,   -6678   } , \n    {  28934   ,   -7248   } , \n    {  28786   ,   -7814   } , \n    {  28627   ,   -8378   } , \n    {  28457   ,   -8938   } , \n    {  28276   ,   -9495   } , \n    {  28084   ,   -10049   } , \n    {  27882   ,   -10598   } , \n    {  27668   ,   -11144   } , \n    {  27444   ,   -11685   } , \n    {  27209   ,   -12221   } , \n    {  26964   ,   -12753   } , \n    {  26709   ,   -13280   } , \n    {  26443   ,   -13802   } , \n    {  26167   ,   -14318   } , \n    {  25881   ,   -14829   } , \n    {  25584   ,   -15335   } , \n    {  25278   ,   -15834   } , \n    {  24963   ,   -16327   } , \n    {  24637   ,   -16814   } , \n    {  24302   ,   -17295   } , \n    {  23958   ,   -17769   } , \n    {  23605   ,   -18236   } , \n    {  23242   ,   -18695   } , \n    {  22871   ,   -19148   } , \n    {  22490   ,   -19594   } , \n    {  22101   ,   -20031   } , \n    {  21704   ,   -20461   } , \n    {  21298   ,   -20884   } \n    };\ncos_msin_t\ta_cos_msin_16[80] = {\n    {  29828   ,   -146   } , \n    {  29825   ,   -439   } , \n    {  29819   ,   -732   } , \n    {  29811   ,   -1025   } , \n    {  29799   ,   -1317   } , \n    {  29785   ,   -1610   } , \n    {  29767   ,   -1902   } , \n    {  29747   ,   -2194   } , \n    {  29724   ,   -2486   } , \n    {  29698   ,   -2778   } , \n    {  29670   ,   -3069   } , \n    {  29638   ,   -3360   } , \n    {  29604   ,   -3651   } , \n    {  29567   ,   -3942   } , \n    {  29526   ,   -4232   } , \n    {  29483   ,   -4521   } , \n    {  29438   ,   -4811   } , \n    {  29389   ,   -5099   } , \n    {  29338   ,   -5388   } , \n    {  29283   ,   -5676   } , \n    {  29226   ,   -5963   } , \n    {  29166   ,   -6249   } , \n    {  29103   ,   -6535   } , \n    {  29038   ,   -6821   } , \n    {  28969   ,   -7106   } , \n    {  28898   ,   -7390   } , \n    {  28824   ,   -7673   } , \n    {  28748   ,   -7956   } , \n    {  28668   ,   -8237   } , \n    {  28586   ,   -8518   } , \n    {  28501   ,   -8799   } , \n    {  28413   ,   -9078   } , \n    {  28323   ,   -9357   } , \n    {  28229   ,   -9634   } , \n    {  28133   ,   -9911   } , \n    {  28035   ,   -10187   } , \n    {  27933   ,   -10461   } , \n    {  27829   ,   -10735   } , \n    {  27723   ,   -11008   } , \n    {  27613   ,   -11279   } , \n    {  27501   ,   -11550   } , \n    {  27387   ,   -11819   } , \n    {  27269   ,   -12088   } , \n    {  27149   ,   -12355   } , \n    {  27027   ,   -12621   } , \n    {  26901   ,   -12885   } , \n    {  26774   ,   -13149   } , \n    {  26643   ,   -13411   } , \n    {  26510   ,   -13672   } , \n    {  26375   ,   -13932   } , \n    {  26237   ,   -14190   } , \n    {  26096   ,   -14447   } , \n    {  25953   ,   -14702   } , \n    {  25807   ,   -14956   } , \n    {  25659   ,   -15209   } , \n    {  25509   ,   -15460   } , \n    {  25356   ,   -15710   } , \n    {  25200   ,   -15958   } , \n    {  25043   ,   -16205   } , \n    {  24882   ,   -16450   } , \n    {  24720   ,   -16693   } , \n    {  24554   ,   -16935   } , \n    {  24387   ,   -17175   } , \n    {  24217   ,   -17414   } , \n    {  24045   ,   -17651   } , \n    {  23871   ,   -17886   } , \n    {  23694   ,   -18119   } , \n    {  23515   ,   -18351   } , \n    {  23334   ,   -18581   } , \n    {  23150   ,   -18809   } , \n    {  22964   ,   -19036   } , \n    {  22776   ,   -19260   } , \n    {  22586   ,   -19483   } , \n    {  22394   ,   -19704   } , \n    {  22199   ,   -19923   } , \n    {  22003   ,   -20140   } , \n    {  21804   ,   -20355   } , \n    {  21603   ,   -20568   } , \n    {  21400   ,   -20779   } , \n    {  21195   ,   -20988   } \n    };\ncos_msin_t\ta_cos_msin_32[160]= {\n    {  29828   ,   -73   } , \n    {  29827   ,   -220   } , \n    {  29826   ,   -366   } , \n    {  29824   ,   -512   } , \n    {  29821   ,   -659   } , \n    {  29817   ,   -805   } , \n    {  29813   ,   -952   } , \n    {  29808   ,   -1098   } , \n    {  29802   ,   -1244   } , \n    {  29796   ,   -1390   } , \n    {  29789   ,   -1537   } , \n    {  29781   ,   -1683   } , \n    {  29772   ,   -1829   } , \n    {  29763   ,   -1975   } , \n    {  29753   ,   -2121   } , \n    {  29742   ,   -2267   } , \n    {  29730   ,   -2413   } , \n    {  29718   ,   -2559   } , \n    {  29705   ,   -2705   } , \n    {  29692   ,   -2851   } , \n    {  29677   ,   -2997   } , \n    {  29662   ,   -3142   } , \n    {  29646   ,   -3288   } , \n    {  29630   ,   -3433   } , \n    {  29613   ,   -3579   } , \n    {  29595   ,   -3724   } , \n    {  29576   ,   -3869   } , \n    {  29557   ,   -4014   } , \n    {  29537   ,   -4159   } , \n    {  29516   ,   -4304   } , \n    {  29494   ,   -4449   } , \n    {  29472   ,   -4594   } , \n    {  29449   ,   -4738   } , \n    {  29426   ,   -4883   } , \n    {  29401   ,   -5027   } , \n    {  29376   ,   -5172   } , \n    {  29351   ,   -5316   } , \n    {  29324   ,   -5460   } , \n    {  29297   ,   -5604   } , \n    {  29269   ,   -5747   } , \n    {  29241   ,   -5891   } , \n    {  29211   ,   -6034   } , \n    {  29181   ,   -6178   } , \n    {  29151   ,   -6321   } , \n    {  29119   ,   -6464   } , \n    {  29087   ,   -6607   } , \n    {  29054   ,   -6749   } , \n    {  29021   ,   -6892   } , \n    {  28987   ,   -7034   } , \n    {  28952   ,   -7177   } , \n    {  28916   ,   -7319   } , \n    {  28880   ,   -7460   } , \n    {  28843   ,   -7602   } , \n    {  28805   ,   -7744   } , \n    {  28767   ,   -7885   } , \n    {  28728   ,   -8026   } , \n    {  28688   ,   -8167   } , \n    {  28648   ,   -8308   } , \n    {  28607   ,   -8448   } , \n    {  28565   ,   -8589   } , \n    {  28522   ,   -8729   } , \n    {  28479   ,   -8869   } , \n    {  28435   ,   -9008   } , \n    {  28391   ,   -9148   } , \n    {  28346   ,   -9287   } , \n    {  28300   ,   -9426   } , \n    {  28253   ,   -9565   } , \n    {  28206   ,   -9703   } , \n    {  28158   ,   -9842   } , \n    {  28109   ,   -9980   } , \n    {  28060   ,   -10118   } , \n    {  28010   ,   -10255   } , \n    {  27959   ,   -10393   } , \n    {  27908   ,   -10530   } , \n    {  27856   ,   -10667   } , \n    {  27803   ,   -10803   } , \n    {  27750   ,   -10940   } , \n    {  27696   ,   -11076   } , \n    {  27641   ,   -11212   } , \n    {  27586   ,   -11347   } , \n    {  27529   ,   -11482   } , \n    {  27473   ,   -11617   } , \n    {  27415   ,   -11752   } , \n    {  27357   ,   -11886   } , \n    {  27299   ,   -12021   } , \n    {  27239   ,   -12154   } , \n    {  27179   ,   -12288   } , \n    {  27119   ,   -12421   } , \n    {  27057   ,   -12554   } , \n    {  26996   ,   -12687   } , \n    {  26933   ,   -12819   } , \n    {  26870   ,   -12951   } , \n    {  26806   ,   -13083   } , \n    {  26741   ,   -13215   } , \n    {  26676   ,   -13346   } , \n    {  26610   ,   -13476   } , \n    {  26544   ,   -13607   } , \n    {  26477   ,   -13737   } , \n    {  26409   ,   -13867   } , \n    {  26340   ,   -13996   } , \n    {  26271   ,   -14125   } , \n    {  26202   ,   -14254   } , \n    {  26132   ,   -14383   } , \n    {  26061   ,   -14511   } , \n    {  25989   ,   -14638   } , \n    {  25917   ,   -14766   } , \n    {  25844   ,   -14893   } , \n    {  25771   ,   -15020   } , \n    {  25697   ,   -15146   } , \n    {  25622   ,   -15272   } , \n    {  25547   ,   -15397   } , \n    {  25471   ,   -15523   } , \n    {  25394   ,   -15648   } , \n    {  25317   ,   -15772   } , \n    {  25239   ,   -15896   } , \n    {  25161   ,   -16020   } , \n    {  25082   ,   -16143   } , \n    {  25003   ,   -16266   } , \n    {  24923   ,   -16389   } , \n    {  24842   ,   -16511   } , \n    {  24760   ,   -16632   } , \n    {  24678   ,   -16754   } , \n    {  24596   ,   -16875   } , \n    {  24513   ,   -16995   } , \n    {  24429   ,   -17115   } , \n    {  24345   ,   -17235   } , \n    {  24260   ,   -17354   } , \n    {  24174   ,   -17473   } , \n    {  24088   ,   -17592   } , \n    {  24002   ,   -17710   } , \n    {  23914   ,   -17827   } , \n    {  23827   ,   -17945   } , \n    {  23738   ,   -18061   } , \n    {  23649   ,   -18178   } , \n    {  23560   ,   -18293   } , \n    {  23470   ,   -18409   } , \n    {  23379   ,   -18524   } , \n    {  23288   ,   -18638   } , \n    {  23196   ,   -18752   } , \n    {  23104   ,   -18866   } , \n    {  23011   ,   -18979   } , \n    {  22917   ,   -19092   } , \n    {  22824   ,   -19204   } , \n    {  22729   ,   -19316   } , \n    {  22634   ,   -19427   } , \n    {  22538   ,   -19538   } , \n    {  22442   ,   -19649   } , \n    {  22345   ,   -19759   } , \n    {  22248   ,   -19868   } , \n    {  22150   ,   -19977   } , \n    {  22052   ,   -20086   } , \n    {  21953   ,   -20194   } , \n    {  21854   ,   -20301   } , \n    {  21754   ,   -20408   } , \n    {  21653   ,   -20515   } , \n    {  21552   ,   -20621   } , \n    {  21451   ,   -20726   } , \n    {  21349   ,   -20831   } , \n    {  21246   ,   -20936   } , \n    {  21143   ,   -21040   } \n    };\ncos_msin_t\ta_cos_msin_64[320] = {\n{29827,\t-34},\n{29827,\t-106},\n{29827,\t-177},\n{29827,\t-249},\n{29826,\t-320},\n{29825,\t-392},\n{29824,\t-463},\n{29823,\t-535},\n{29821,\t-606},\n{29819,\t-678},\n{29818,\t-750},\n{29816,\t-821},\n{29814,\t-893},\n{29812,\t-964},\n{29809,\t-1035},\n{29807,\t-1106},\n{29804,\t-1177},\n{29801,\t-1249},\n{29797,\t-1320},\n{29795,\t-1392},\n{29791,\t-1463},\n{29787,\t-1535},\n{29784,\t-1606},\n{29780,\t-1678},\n{29776,\t-1749},\n{29771,\t-1820},\n{29767,\t-1892},\n{29763,\t-1963},\n{29758,\t-2035},\n{29753,\t-2106},\n{29748,\t-2177},\n{29742,\t-2249},\n{29737,\t-2320},\n{29731,\t-2391},\n{29726,\t-2462},\n{29719,\t-2534},\n{29713,\t-2605},\n{29707,\t-2676},\n{29701,\t-2747},\n{29694,\t-2819},\n{29686,\t-2890},\n{29680,\t-2961},\n{29673,\t-3032},\n{29665,\t-3103},\n{29658,\t-3174},\n{29650,\t-3245},\n{29643,\t-3316},\n{29635,\t-3387},\n{29626,\t-3459},\n{29618,\t-3529},\n{29610,\t-3600},\n{29601,\t-3671},\n{29592,\t-3742},\n{29583,\t-3813},\n{29574,\t-3884},\n{29564,\t-3955},\n{29554,\t-4026},\n{29544,\t-4097},\n{29535,\t-4167},\n{29525,\t-4238},\n{29514,\t-4309},\n{29504,\t-4380},\n{29493,\t-4450},\n{29483,\t-4521},\n{29472,\t-4591},\n{29461,\t-4662},\n{29450,\t-4733},\n{29439,\t-4803},\n{29427,\t-4874},\n{29415,\t-4944},\n{29403,\t-5015},\n{29391,\t-5085},\n{29379,\t-5155},\n{29366,\t-5226},\n{29353,\t-5296},\n{29341,\t-5367},\n{29328,\t-5438},\n{29314,\t-5508},\n{29301,\t-5578},\n{29289,\t-5648},\n{29274,\t-5718},\n{29260,\t-5788},\n{29247,\t-5858},\n{29232,\t-5928},\n{29218,\t-5998},\n{29204,\t-6068},\n{29188,\t-6139},\n{29175,\t-6209},\n{29159,\t-6279},\n{29145,\t-6348},\n{29128,\t-6418},\n{29114,\t-6488},\n{29097,\t-6557},\n{29082,\t-6627},\n{29066,\t-6697},\n{29050,\t-6767},\n{29034,\t-6837},\n{29017,\t-6906},\n{29001,\t-6975},\n{28984,\t-7045},\n{28966,\t-7114},\n{28950,\t-7184},\n{28933,\t-7254},\n{28915,\t-7323},\n{28897,\t-7392},\n{28880,\t-7461},\n{28862,\t-7530},\n{28843,\t-7600},\n{28825,\t-7669},\n{28807,\t-7738},\n{28788,\t-7806},\n{28769,\t-7875},\n{28751,\t-7944},\n{28732,\t-8014},\n{28712,\t-8082},\n{28692,\t-8151},\n{28672,\t-8219},\n{28653,\t-8289},\n{28633,\t-8357},\n{28613,\t-8425},\n{28593,\t-8494},\n{28572,\t-8563},\n{28551,\t-8632},\n{28531,\t-8700},\n{28510,\t-8768},\n{28488,\t-8837},\n{28468,\t-8905},\n{28447,\t-8973},\n{28425,\t-9041},\n{28403,\t-9109},\n{28381,\t-9177},\n{28359,\t-9245},\n{28336,\t-9313},\n{28315,\t-9381},\n{28292,\t-9448},\n{28269,\t-9517},\n{28246,\t-9584},\n{28223,\t-9652},\n{28200,\t-9720},\n{28176,\t-9787},\n{28153,\t-9854},\n{28129,\t-9922},\n{28105,\t-9990},\n{28082,\t-10056},\n{28057,\t-10124},\n{28032,\t-10191},\n{28009,\t-10258},\n{27984,\t-10326},\n{27959,\t-10392},\n{27934,\t-10460},\n{27909,\t-10526},\n{27883,\t-10593},\n{27858,\t-10661},\n{27832,\t-10727},\n{27807,\t-10794},\n{27780,\t-10860},\n{27754,\t-10927},\n{27728,\t-10993},\n{27701,\t-11059},\n{27676,\t-11126},\n{27648,\t-11192},\n{27622,\t-11259},\n{27595,\t-11324},\n{27567,\t-11391},\n{27540,\t-11456},\n{27512,\t-11523},\n{27484,\t-11588},\n{27456,\t-11655},\n{27429,\t-11720},\n{27401,\t-11786},\n{27372,\t-11852},\n{27344,\t-11917},\n{27315,\t-11982},\n{27286,\t-12049},\n{27257,\t-12114},\n{27229,\t-12179},\n{27199,\t-12244},\n{27169,\t-12309},\n{27140,\t-12375},\n{27110,\t-12439},\n{27080,\t-12505},\n{27050,\t-12570},\n{27019,\t-12634},\n{26990,\t-12699},\n{26958,\t-12764},\n{26928,\t-12828},\n{26897,\t-12892},\n{26866,\t-12956},\n{26835,\t-13021},\n{26804,\t-13086},\n{26773,\t-13149},\n{26741,\t-13214},\n{26709,\t-13278},\n{26677,\t-13342},\n{26645,\t-13406},\n{26613,\t-13470},\n{26581,\t-13534},\n{26549,\t-13597},\n{26515,\t-13661},\n{26483,\t-13725},\n{26450,\t-13788},\n{26417,\t-13851},\n{26384,\t-13915},\n{26350,\t-13978},\n{26316,\t-14041},\n{26283,\t-14103},\n{26248,\t-14166},\n{26215,\t-14229},\n{26180,\t-14292},\n{26146,\t-14355},\n{26112,\t-14417},\n{26077,\t-14480},\n{26042,\t-14543},\n{26008,\t-14605},\n{25972,\t-14667},\n{25937,\t-14730},\n{25901,\t-14792},\n{25866,\t-14854},\n{25830,\t-14916},\n{25794,\t-14977},\n{25759,\t-15039},\n{25723,\t-15101},\n{25687,\t-15162},\n{25650,\t-15224},\n{25613,\t-15286},\n{25577,\t-15347},\n{25540,\t-15408},\n{25503,\t-15470},\n{25465,\t-15531},\n{25428,\t-15592},\n{25391,\t-15653},\n{25353,\t-15714},\n{25315,\t-15774},\n{25277,\t-15834},\n{25240,\t-15895},\n{25201,\t-15956},\n{25162,\t-16016},\n{25124,\t-16076},\n{25086,\t-16136},\n{25047,\t-16196},\n{25008,\t-16256},\n{24969,\t-16316},\n{24930,\t-16375},\n{24891,\t-16436},\n{24851,\t-16496},\n{24811,\t-16555},\n{24772,\t-16615},\n{24732,\t-16674},\n{24692,\t-16732},\n{24652,\t-16791},\n{24612,\t-16852},\n{24572,\t-16911},\n{24531,\t-16969},\n{24490,\t-17027},\n{24449,\t-17086},\n{24408,\t-17145},\n{24367,\t-17203},\n{24325,\t-17261},\n{24284,\t-17320},\n{24242,\t-17379},\n{24200,\t-17436},\n{24158,\t-17494},\n{24116,\t-17552},\n{24075,\t-17610},\n{24032,\t-17668},\n{23990,\t-17725},\n{23947,\t-17782},\n{23904,\t-17840},\n{23862,\t-17897},\n{23819,\t-17954},\n{23775,\t-18011},\n{23732,\t-18068},\n{23689,\t-18125},\n{23645,\t-18181},\n{23602,\t-18238},\n{23558,\t-18294},\n{23514,\t-18351},\n{23470,\t-18407},\n{23426,\t-18464},\n{23381,\t-18520},\n{23337,\t-18576},\n{23293,\t-18632},\n{23248,\t-18688},\n{23202,\t-18743},\n{23158,\t-18799},\n{23112,\t-18854},\n{23068,\t-18910},\n{23022,\t-18964},\n{22977,\t-19020},\n{22931,\t-19074},\n{22885,\t-19129},\n{22839,\t-19185},\n{22793,\t-19239},\n{22747,\t-19294},\n{22700,\t-19348},\n{22655,\t-19403},\n{22607,\t-19457},\n{22561,\t-19511},\n{22514,\t-19565},\n{22467,\t-19619},\n{22421,\t-19673},\n{22373,\t-19726},\n{22326,\t-19780},\n{22279,\t-19834},\n{22230,\t-19887},\n{22183,\t-19940},\n{22135,\t-19993},\n{22087,\t-20047},\n{22039,\t-20099},\n{21991,\t-20152},\n{21942,\t-20205},\n{21894,\t-20257},\n{21845,\t-20309},\n{21797,\t-20362},\n{21748,\t-20413},\n{21699,\t-20466},\n{21650,\t-20518},\n{21601,\t-20570},\n{21551,\t-20621},\n{21502,\t-20674}\n};\n\ncos_msin_t\t*a_cos_msin_table[] = {a_cos_msin_2, a_cos_msin_4,\n                                   a_cos_msin_8, a_cos_msin_16,\n                                   a_cos_msin_32,a_cos_msin_64\n\t\t\t                      };\n\nWord16 dct_core_a[10][10] = {\n\n{ 10453,  10196,   9688,   8941,   7973,   6810,   5479,   4013,   2448,    823 },\n{ 10196,   7973,   4013,   -823,  -5479,  -8941, -10453,  -9688,  -6810,  -2448 },\n{ 9688 ,   4013,  -4013,  -9688,  -9688,  -4013,   4013,   9688,   9688,   4013 },\n{ 8941 ,   -823,  -9688,  -7973,   2448,  10196,   6810,  -4013, -10453,  -5479 },\n{ 7973 ,  -5479,  -9688,   2448,  10453,    823, -10196,  -4013,   8941,   6810 },\n{ 6810 ,  -8941,  -4013,  10196,    823, -10453,   2448,   9688,  -5479,  -7973 },\n{ 5479 , -10453,   4013,   6810, -10196,   2448,   7973,  -9688,    823,   8941 },\n{ 4013 ,  -9688,   9688,  -4013,  -4013,   9688,  -9688,   4013,   4013,  -9688 },\n{ 2448 ,  -6810,   9688, -10453,   8941,  -5479,    823,   4013,  -7973,  10196 },\n{ 823  ,  -2448,   4013,  -5479,   6810,  -7973,   8941,  -9688,  10196, -10453 }};\n\nWord16 anal_bias[320] = {\n  1,  1,  3,  1,  4,  1,  3, -2,  4,  3,\n  4,  1,  3,  0,  2, -3,  0,  0,  2,  2,\n  4,  1,  1, -5,  4,  1,  2, -1,  0, -1,\n  1, -2,  0,  2,  2,  2,  4,  1,  3,  0,\n  5,  3,  2,  0,  3,  0,  1, -4,  1,  1,\n  2,  0,  4,  0,  1, -4,  6,  1,  3, -1,\n  1,  0,  0, -4,  1,  1,  3,  1,  3,  2,\n  4, -2,  4,  3,  5,  1,  3,  0,  1, -3,\n  1,  1,  2,  0,  4,  1,  2, -4,  4,  2,\n  2, -1,  1, -1,  1, -4,  0,  0,  3,  0,\n  5,  2,  3, -1,  6,  2,  5,  0,  4,  0,\n  1, -3,  1,  0,  3,  0,  4,  0,  1, -3,\n  4,  1,  3, -1,  1, -2,  1, -4,  0,  1,\n  2,  1,  3,  2,  2, -2,  4,  3,  3,  0,\n  3,  0,  0, -2,  1,  0,  2,  0,  5, -1,\n  1, -3,  4,  2,  2,  0,  2, -3,  1, -4,\n -1,  1,  2,  2,  4,  1,  3, -1,  5,  2,\n  2,  0,  3, -1,  2, -3,  0,  1,  2,  2,\n  4,  0,  1, -5,  5,  1,  3,  0,  2, -1,\n  0, -2,  1,  2,  2,  2,  4,  1,  0,  0,\n  4,  2,  4,  1,  4, -1,  1, -4,  0,  1,\n  3,  1,  5,  1,  1, -2,  4,  0,  2,  0,\n  2, -1,  0, -2,  0,  1,  1,  1,  4,  2,\n  3, -2,  5,  4,  4,  0,  3,  0,  3, -4,\n  1,  2,  2,  0,  4,  1,  0, -3,  4,  2,\n  3, -1,  1, -1,  1, -4,  0,  2,  3,  1,\n  4,  1,  3,  0,  3,  3,  4,  1,  2,  0,\n  1, -3,  2,  2,  2,  1,  5,  0,  1, -4,\n  4,  1,  3, -2,  3, -1,  0, -2,  0,  2,\n  2,  0,  5,  1,  4, -1,  4,  3,  4,  1,\n  3,  0,  1, -4,  2,  0,  3,  1,  5,  0,\n  1, -5,  5,  2,  2,  0,  0,  0,  0, -4};\n\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/encode/encoder.c",
    "content": "/***************************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**   All rights reserved.\n**\n***************************************************************************/\n\n/***************************************************************************\n  Filename:    encoder.c    \n\n  Purpose:     Contains files used to implement the G.722.1 Annex C encoder\n\n  Design Notes:\n\n***************************************************************************/\n\n/***************************************************************************\n Include files                                                           \n***************************************************************************/\n\n#include <stdio.h>\n#include <math.h>\n#include \"defs.h\"\n#include \"huff_def.h\"\n#include \"tables.h\"\n#include \"count.h\"\n\n/***************************************************************************\n Function:    encoder                                                     \n                                                                         \n Syntax:      void encoder(Word16 number_of_available_bits,                     \n                           Word16 number_of_regions,\n                           Word16 mlt_coefs,                                        \n                           Word16 mag_shift,                                        \n                           Word16 out_words)                                        \n              \n              inputs:   number_of_available_bits\n                        number_of_regions\n                        mag_shift\n                        mlt_coefs[DCT_LENGTH]\n                        \n              outputs:  out_words[MAX_BITS_PER_FRAME/16]\n                                                                         \n                                                                         \n Description: Encodes the mlt coefs into out_words using G.722.1 Annex C\n                                                           \n                                                                         \n WMOPS:     7kHz |    24kbit    |     32kbit\n          -------|--------------|----------------\n            AVG  |    0.93      |     1.04\n          -------|--------------|----------------  \n            MAX  |    1.20      |     1.28\n          -------|--------------|---------------- \n                                                                        \n           14kHz |    24kbit    |     32kbit     |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    1.39      |     1.71       |     2.01\n          -------|--------------|----------------|----------------\n            MAX  |    2.00      |     2.30       |     2.52\n          -------|--------------|----------------|----------------\n                                                                         \n***************************************************************************/\n\nvoid encoder(Word16  number_of_available_bits,\n             Word16  number_of_regions,\n             Word16  *mlt_coefs,\n             Word16  mag_shift,\n             Word16  *out_words)\n{\n\n    Word16  num_categorization_control_bits;\n    Word16  num_categorization_control_possibilities;\n    Word16  number_of_bits_per_frame;\n    Word16  number_of_envelope_bits;\n    Word16  categorization_control;\n    Word16  region;\n    Word16  absolute_region_power_index[MAX_NUMBER_OF_REGIONS];\n    Word16  power_categories[MAX_NUMBER_OF_REGIONS];\n    Word16  category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1];\n    Word16  drp_num_bits[MAX_NUMBER_OF_REGIONS+1];\n    UWord16 drp_code_bits[MAX_NUMBER_OF_REGIONS+1];\n    Word16  region_mlt_bit_counts[MAX_NUMBER_OF_REGIONS];\n    UWord32 region_mlt_bits[4*MAX_NUMBER_OF_REGIONS];\n    Word16  mag_shift_offset;\n\n    Word16 temp;\n\n    /* initialize variables */\n    test();\n    if (number_of_regions == NUMBER_OF_REGIONS)\n    {\n        num_categorization_control_bits = NUM_CATEGORIZATION_CONTROL_BITS;\n        move16();\n        num_categorization_control_possibilities = NUM_CATEGORIZATION_CONTROL_POSSIBILITIES;\n        move16();\n    } \n    else\n    {\n        num_categorization_control_bits = MAX_NUM_CATEGORIZATION_CONTROL_BITS;\n        move16();\n        num_categorization_control_possibilities = MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES;\n        move16();\n    }\n\n    number_of_bits_per_frame = number_of_available_bits;\n    move16();\n\n    for (region=0; region<number_of_regions; region++)\n    {\n        region_mlt_bit_counts[region] = 0;\n        move16();\n    }\n    \n    /* Estimate power envelope. */\n    number_of_envelope_bits = compute_region_powers(mlt_coefs,\n                                                    mag_shift,\n                                                    drp_num_bits,\n                                                    drp_code_bits,\n                                                    absolute_region_power_index,\n                                                    number_of_regions);\n\n    /* Adjust number of available bits based on power envelope estimate */\n    temp = sub(number_of_available_bits,number_of_envelope_bits);\n    number_of_available_bits = sub(temp,num_categorization_control_bits);\n\n    /* get categorizations */\n    categorize(number_of_available_bits,\n               number_of_regions,\n               num_categorization_control_possibilities,\n               absolute_region_power_index,\n               power_categories,\n               category_balances);\n\n    /* Adjust absolute_region_category_index[] for mag_shift.\n       This assumes that REGION_POWER_STEPSIZE_DB is defined\n       to be exactly 3.010299957 or 20.0 times log base 10\n       of square root of 2. */\n    temp = shl_nocheck(mag_shift,1);\n    mag_shift_offset = add(temp,REGION_POWER_TABLE_NUM_NEGATIVES);\n    \n    for (region=0; region<number_of_regions; region++)\n    {\n        absolute_region_power_index[region] = add(absolute_region_power_index[region],mag_shift_offset);\n        move16();\n    }\n\n    /* adjust the absolute power region index based on the mlt coefs */\n    adjust_abs_region_power_index(absolute_region_power_index,mlt_coefs,number_of_regions);\n\n\n    /* quantize and code the mlt coefficients based on categorizations */\n    vector_quantize_mlts(number_of_available_bits,\n                         number_of_regions,\n                         num_categorization_control_possibilities,\n                         mlt_coefs,\n                         absolute_region_power_index,\n                         power_categories,\n                         category_balances,\n                         &categorization_control,\n                         region_mlt_bit_counts,\n                         region_mlt_bits);\n\n    /* stuff bits into words */\n    bits_to_words(region_mlt_bits,\n                  region_mlt_bit_counts,\n                  drp_num_bits,\n                  drp_code_bits,\n                  out_words,\n                  categorization_control,\n                  number_of_regions,\n                  num_categorization_control_bits,\n                  number_of_bits_per_frame);\n\n}\n\n/***************************************************************************\n Function:    bits_to_words\n\n Syntax:      bits_to_words(UWord32 *region_mlt_bits,              \n                            Word16  *region_mlt_bit_counts,                                                             \n                            Word16  *drp_num_bits,                                                                      \n                            UWord16 *drp_code_bits,                                                                     \n                            Word16  *out_words,                                                                         \n                            Word16  categorization_control,                                                                         \n                            Word16  number_of_regions,\n                            Word16  num_categorization_control_bits,\n                            Word16  number_of_bits_per_frame)                                                           \n                                                                   \n                                                                   \n Description: Stuffs the bits into words for output\n\n WMOPS:     7kHz |    24kbit    |      32kbit\n          -------|--------------|----------------\n            AVG  |    0.09      |     0.12\n          -------|--------------|----------------  \n            MAX  |    0.10      |     0.13\n          -------|--------------|---------------- \n          \n           14kHz |    24kbit    |     32kbit     |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.12      |     0.15       |     0.19\n          -------|--------------|----------------|----------------\n            MAX  |    0.14      |     0.17       |     0.21\n          -------|--------------|----------------|----------------\n\n***************************************************************************/\nvoid bits_to_words(UWord32 *region_mlt_bits,\n                   Word16  *region_mlt_bit_counts,\n                   Word16  *drp_num_bits,\n                   UWord16 *drp_code_bits,\n                   Word16  *out_words,\n                   Word16  categorization_control,\n                   Word16  number_of_regions,\n                   Word16  num_categorization_control_bits,\n                   Word16  number_of_bits_per_frame)\n{\n    Word16  out_word_index = 0;\n    Word16  j;\n    Word16  region;\n    Word16  out_word;\n    Word16  region_bit_count;\n    Word16  current_word_bits_left;\n    UWord16 slice;\n    Word16  out_word_bits_free = 16;\n    UWord32 *in_word_ptr;\n    UWord32 current_word;\n    \n    Word32  acca = 0;\n    Word32  accb;\n    Word16  temp;\n\n    /* First set up the categorization control bits to look like one more set of region power bits. */\n    out_word = 0;\n    move16();\n\n    drp_num_bits[number_of_regions] = num_categorization_control_bits;\n    move16();\n    \n    drp_code_bits[number_of_regions] = (UWord16)categorization_control;\n    move16();\n\n    /* These code bits are right justified. */\n    for (region=0; region <= number_of_regions; region++)\n    {\n        current_word_bits_left = drp_num_bits[region];\n        move16();\n        \n        current_word = (UWord32)drp_code_bits[region];\n        move16();\n        \n        j = sub(current_word_bits_left,out_word_bits_free);\n\n        test();\n        if (j >= 0)\n        {\n            temp = extract_l(L_shr_nocheck(current_word,j));\n            out_word = add(out_word,temp);\n\n            out_words[out_word_index++] = out_word;\n            move16();\n            \n            out_word_bits_free = 16;\n            move16();\n            \n            out_word_bits_free = sub(out_word_bits_free,j);\n            \n            acca = (current_word << out_word_bits_free);\n            out_word = extract_l(acca);\n        }\n        else\n        {\n            j = negate(j);\n\n            acca = (current_word << j);\n            accb = L_deposit_l(out_word);\n            acca = L_add(accb,acca);\n            out_word = extract_l(acca);\n            \n            out_word_bits_free = sub(out_word_bits_free,current_word_bits_left);\n        }\n    }\n\n    /* These code bits are left justified. */\n    \n    for (region=0;region<number_of_regions; region++)\n    {\n        accb = L_deposit_l(out_word_index);\n        accb = L_shl_nocheck(accb,4);\n        accb = L_sub(accb,number_of_bits_per_frame);\n        test();\n        if(accb < 0)        \n        {\n            temp = shl_nocheck(region,2);\n            in_word_ptr = &region_mlt_bits[temp];\n            region_bit_count = region_mlt_bit_counts[region];\n            move16();\n\n            temp = sub(32,region_bit_count);\n            test();\n            if(temp > 0)\n                current_word_bits_left = region_bit_count;\n            else\n                current_word_bits_left = 32;\n\n            current_word = *in_word_ptr++;\n    \n            acca = L_deposit_l(out_word_index);\n            acca = L_shl_nocheck(acca,4);\n            acca = L_sub(acca,number_of_bits_per_frame);\n            \n            /* from while loop */\n            test();\n            test();\n            logic16(); \n            while ((region_bit_count > 0) && (acca < 0))\n            {\n                /* from while loop */\n                test();\n                test();\n                logic16(); \n                \n                temp = sub(current_word_bits_left,out_word_bits_free);\n                test();\n                if (temp >= 0)\n                {\n                    temp = sub(32,out_word_bits_free);\n                    accb = LU_shr(current_word,temp);\n                    slice = (UWord16)extract_l(accb);\n                    \n                    out_word = add(out_word,slice);\n    \n                    test();\n                    current_word <<= out_word_bits_free;\n\n                    current_word_bits_left = sub(current_word_bits_left,out_word_bits_free);\n                    out_words[out_word_index++] = extract_l(out_word);\n                    move16();\n\n                    out_word = 0;\n                    move16();\n\n                    out_word_bits_free = 16;\n                    move16();\n                }\n                else\n                {\n                    temp = sub(32,current_word_bits_left);\n                    accb = LU_shr(current_word,temp);\n                    slice = (UWord16)extract_l(accb);\n                    \n                    temp = sub(out_word_bits_free,current_word_bits_left);\n                    test();\n                    accb = slice << temp;\n                    acca = L_deposit_l(out_word);\n                    acca = L_add(acca,accb);\n                    out_word = extract_l(acca);\n                    out_word_bits_free = sub(out_word_bits_free,current_word_bits_left);\n                    \n                    current_word_bits_left = 0;\n                    move16();\n                }\n    \n                test();\n                if (current_word_bits_left == 0)\n                {\n                    current_word = *in_word_ptr++;\n                    region_bit_count = sub(region_bit_count,32);\n                    \n                    /* current_word_bits_left = MIN(32,region_bit_count); */\n                    temp = sub(32,region_bit_count);\n                    test();\n                    if(temp > 0)\n                        current_word_bits_left = region_bit_count;\n                    else\n                        current_word_bits_left = 32;\n                    \n                }\n                acca = L_deposit_l(out_word_index);\n                acca = L_shl_nocheck(acca,4);\n                acca = L_sub(acca,number_of_bits_per_frame);\n            }\n            accb = L_deposit_l(out_word_index);\n            accb = L_shl_nocheck(accb,4);\n            accb = L_sub(accb,number_of_bits_per_frame);\n        }\n    }\n\n    /* Fill out with 1's. */\n\n    test();\n    while (acca < 0)\n    {\n        test();\n        current_word = 0x0000ffff;\n        move32();\n\n        temp = sub(16,out_word_bits_free);\n        acca = LU_shr(current_word,temp);\n        slice = (UWord16)extract_l(acca);\n\n        out_word = add(out_word,slice);\n        out_words[out_word_index++] = out_word;\n        move16();\n\n        out_word = 0;\n        move16();\n        \n        out_word_bits_free = 16;\n        move16();\n        \n        acca = L_deposit_l(out_word_index);\n        acca = L_shl_nocheck(acca,4);\n        acca = L_sub(acca,number_of_bits_per_frame);\n    }\n}\n/***************************************************************************\n Function:    adjust_abs_region_power_index\n\n Syntax:      adjust_abs_region_power_index(Word16 *absolute_region_power_index,\n                                            Word16 *mlt_coefs,\n                                            Word16 number_of_regions)\n\n              inputs:   *mlt_coefs\n                        *absolute_region_power_index\n                        number_of_regions\n            \n              outputs:  *absolute_region_power_index\n \n Description: Adjusts the absolute power index\n \n \n WMOPS:     7kHz |    24kbit    |      32kbit\n          -------|--------------|----------------\n            AVG  |    0.03      |      0.03\n          -------|--------------|----------------  \n            MAX  |    0.12      |      0.12\n          -------|--------------|---------------- \n\n           14kHz |    24kbit    |     32kbit     |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.03      |     0.03       |     0.03\n          -------|--------------|----------------|----------------\n            MAX  |    0.14      |     0.14       |     0.14\n          -------|--------------|----------------|----------------\n\n***************************************************************************/\nvoid adjust_abs_region_power_index(Word16 *absolute_region_power_index,Word16 *mlt_coefs,Word16 number_of_regions)\n{\n    Word16 n,i;\n    Word16 region;\n    Word16 *raw_mlt_ptr;\n    \n    Word32 acca;\n    Word16 temp;\n\n    for (region=0; region<number_of_regions; region++)\n    {\n        n = sub(absolute_region_power_index[region],39);\n        n = shr_nocheck(n,1);\n        \n        test();\n        if (n > 0)\n        {\n            temp = extract_l(L_mult0(region,REGION_SIZE));\n\n            raw_mlt_ptr = &mlt_coefs[temp];\n\n            for (i=0; i<REGION_SIZE; i++)\n            {\n                acca = L_shl_nocheck(*raw_mlt_ptr,16);\n                acca = L_add(acca,32768L);\n                acca = L_shr_nocheck(acca,n);\n                acca = L_shr_nocheck(acca,16);\n                *raw_mlt_ptr++ = extract_l(acca);\n            }\n\n            temp = shl_nocheck(n,1);\n            temp = sub(absolute_region_power_index[region],temp);\n            absolute_region_power_index[region] = temp;\n            move16();\n        }\n    }\n}\n\n/***************************************************************************\n Function:    compute_region_powers\n\n Syntax:      Word16 compute_region_powers(Word16  *mlt_coefs,                         \n                                           Word16  mag_shift,                         \n                                           Word16  *drp_num_bits,                      \n                                           UWord16 *drp_code_bits,                     \n                                           Word16  *absolute_region_power_index,       \n                                           Word16  number_of_regions)\n                mlt_coefs[DCT_LENGTH];                      \n                mag_shift;                                          \n                drp_num_bits[MAX_NUMBER_OF_REGIONS];                      \n                drp_code_bits[MAX_NUMBER_OF_REGIONS];                     \n                absolute_region_power_index[MAX_NUMBER_OF_REGIONS];       \n                number_of_regions;\n                                                                   \n Description: Computes the power for each of the regions\n\n \n WMOPS:     7kHz |    24kbit    |    32kbit\n          -------|--------------|----------------\n            AVG  |    0.09      |    0.09\n          -------|--------------|----------------  \n            MAX  |    0.13      |    0.13\n          -------|--------------|---------------- \n\n           14kHz |    24kbit    |     32kbit     |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.20      |     0.20       |     0.20\n          -------|--------------|----------------|----------------\n            MAX  |    0.29      |     0.29       |     0.29\n          -------|--------------|----------------|----------------\n\n***************************************************************************/\n\nWord16 compute_region_powers(Word16  *mlt_coefs,\n                             Word16  mag_shift,\n                             Word16  *drp_num_bits,\n                             UWord16 *drp_code_bits,\n                             Word16  *absolute_region_power_index,\n                             Word16  number_of_regions)\n{\n\n    Word16 *input_ptr;\n    Word32 long_accumulator;\n    Word16 itemp1;\n    Word16 power_shift;\n    Word16 region;\n    Word16 j;\n    Word16 differential_region_power_index[MAX_NUMBER_OF_REGIONS];\n    Word16 number_of_bits;\n    \n    Word32 acca;\n    Word16 temp;\n    Word16 temp1;\n    Word16 temp2;\n\n\n    input_ptr = mlt_coefs;\n    for (region=0; region<number_of_regions; region++)\n    {\n        long_accumulator = L_deposit_l(0);\n\n        for (j=0; j<REGION_SIZE; j++)\n        {\n            itemp1 = *input_ptr++;\n            move16();\n            long_accumulator = L_mac0(long_accumulator,itemp1,itemp1);\n        }\n\n        power_shift = 0;\n        move16();\n\n        acca = (long_accumulator & 0x7fff0000L);\n        logic32();\n\n        test();\n        while (acca > 0)\n        {\n            test();\n            long_accumulator = L_shr_nocheck(long_accumulator,1);\n            \n            acca = (long_accumulator & 0x7fff0000L);\n            logic32();\n\n            power_shift = add(power_shift,1);\n        }\n        \n        acca = L_sub(long_accumulator,32767);\n        \n        temp = add(power_shift,15);\n        test();\n        test();\n        logic16();\n        while ((acca <= 0) && (temp >= 0))\n        {\n            test();\n            test();\n            logic16();\n            \n            long_accumulator = L_shl_nocheck(long_accumulator,1);\n            acca = L_sub(long_accumulator,32767);\n            power_shift--;\n            temp = add(power_shift,15);\n        }\n        long_accumulator = L_shr_nocheck(long_accumulator,1);\n        /* 28963 corresponds to square root of 2 times REGION_SIZE(20). */\n        acca = L_sub(long_accumulator,28963);\n        \n        test();\n        if (acca >= 0)\n            power_shift = add(power_shift,1);\n        \n        acca = L_deposit_l(mag_shift);\n        acca = L_shl_nocheck(acca,1);\n        acca = L_sub(power_shift,acca);\n        acca = L_add(35,acca);\n        acca = L_sub(acca,REGION_POWER_TABLE_NUM_NEGATIVES);\n        absolute_region_power_index[region] = extract_l(acca);\n    }\n\n\n    /* Before we differentially encode the quantized region powers, adjust upward the\n    valleys to make sure all the peaks can be accurately represented. */\n    temp = sub(number_of_regions,2);\n\n    for (region = temp; region >= 0; region--)\n    {\n        temp1 = sub(absolute_region_power_index[region+1],DRP_DIFF_MAX);\n        temp2 = sub(absolute_region_power_index[region],temp1);\n        test();\n        if (temp2 < 0)\n        {\n            absolute_region_power_index[region] = temp1;\n            move16();\n        }\n    }\n\n    /* The MLT is currently scaled too low by the factor\n       ENCODER_SCALE_FACTOR(=18318)/32768 * (1./sqrt(160).\n       This is the ninth power of 1 over the square root of 2.\n       So later we will add ESF_ADJUSTMENT_TO_RMS_INDEX (now 9)\n       to drp_code_bits[0]. */\n\n    /* drp_code_bits[0] can range from 1 to 31. 0 will be used only as an escape sequence. */\n    temp1 = sub(1,ESF_ADJUSTMENT_TO_RMS_INDEX);\n    temp2 = sub(absolute_region_power_index[0],temp1);\n    test();\n    if (temp2 < 0)\n    {\n        absolute_region_power_index[0] = temp1;\n        move16();\n    }\n    \n    temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX);\n\n\t/*\n\t * The next line was corrected in Release 1.2 \n\t */\n\n    temp2 = sub(absolute_region_power_index[0], temp1);  \n    test();\n    if (temp2 > 0)\n    {\n        absolute_region_power_index[0] = temp1;\n        move16();\n    }\n\n    differential_region_power_index[0] = absolute_region_power_index[0];\n    move16();\n    \n    number_of_bits = 5;\n    move16();\n    \n    drp_num_bits[0] = 5;\n    move16();\n    \n    drp_code_bits[0] = (UWord16)add(absolute_region_power_index[0],ESF_ADJUSTMENT_TO_RMS_INDEX);\n    move16();\n\n    /* Lower limit the absolute region power indices to -8 and upper limit them to 31. Such extremes\n     may be mathematically impossible anyway.*/\n    for (region=1; region<number_of_regions; region++)\n    {\n        temp1 = sub(-8,ESF_ADJUSTMENT_TO_RMS_INDEX);\n        temp2 = sub(absolute_region_power_index[region],temp1);\n        test();\n        if (temp2 < 0)\n        {\n            absolute_region_power_index[region] = temp1;\n            move16();\n        }\n\n        temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX);\n        temp2 = sub(absolute_region_power_index[region],temp1);\n        test();\n        if (temp2 > 0)\n        {\n            absolute_region_power_index[region] = temp1;\n            move16();\n        }\n    }\n\n    for (region=1; region<number_of_regions; region++)\n    {\n        j = sub(absolute_region_power_index[region],absolute_region_power_index[region-1]);\n        temp = sub(j,DRP_DIFF_MIN);\n        test();\n        if (temp < 0)\n        {\n            j = DRP_DIFF_MIN;\n        }\n        j = sub(j,DRP_DIFF_MIN);\n        move16();\n        differential_region_power_index[region] = j;\n        move16();\n        \n        temp = add(absolute_region_power_index[region-1],differential_region_power_index[region]);\n        temp = add(temp,DRP_DIFF_MIN);\n        absolute_region_power_index[region] = temp;\n        move16();\n\n        number_of_bits = add(number_of_bits,differential_region_power_bits[region][j]);\n        drp_num_bits[region] = differential_region_power_bits[region][j];\n        move16();\n        drp_code_bits[region] = differential_region_power_codes[region][j];\n        move16();\n    }\n\n    return (number_of_bits);\n}\n\n/***************************************************************************\n Function:    vector_quantize_mlts\n\n Syntax:      void vector_quantize_mlts(number_of_available_bits,\n                                        number_of_regions,                     \n                                        num_categorization_control_possibilities,\n                                        mlt_coefs,                                    \n                                        absolute_region_power_index,                  \n                                        power_categories,                             \n                                        category_balances,                            \n                                        p_categorization_control,                               \n                                        region_mlt_bit_counts,                        \n                                        region_mlt_bits)                              \n                                                                                    \n              Word16 number_of_available_bits;                                        \n              Word16 number_of_regions;\n              Word16 num_categorization_control_possibilities;\n              Word16 mlt_coefs[DCT_LENGTH];                                         \n              Word16 absolute_region_power_index[MAX_NUMBER_OF_REGIONS];                  \n              Word16 power_categories[MAX_NUMBER_OF_REGIONS];                             \n              Word16 category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1];         \n              Word16 *p_categorization_control;                                                 \n              Word16 region_mlt_bit_counts[MAX_NUMBER_OF_REGIONS];                        \n              Word32 region_mlt_bits[4*MAX_NUMBER_OF_REGIONS];                            \n\n Description: Scalar quantized vector Huffman coding (SQVH)\n\n \n WMOPS:     7kHz |    24kbit    |     32kbit\n          -------|--------------|----------------\n            AVG  |    0.57      |     0.65\n          -------|--------------|----------------  \n            MAX  |    0.78      |     0.83\n          -------|--------------|---------------- \n\n           14kHz |    24kbit    |     32kbit     |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.62      |     0.90       |     1.11\n          -------|--------------|----------------|----------------\n            MAX  |    1.16      |     1.39       |     1.54\n          -------|--------------|----------------|----------------\n\n***************************************************************************/\n\nvoid vector_quantize_mlts(Word16 number_of_available_bits,\n                          Word16 number_of_regions,\n                          Word16 num_categorization_control_possibilities,\n                          Word16 *mlt_coefs,\n                          Word16 *absolute_region_power_index,\n                          Word16 *power_categories,\n                          Word16 *category_balances,\n                          Word16 *p_categorization_control,\n                          Word16 *region_mlt_bit_counts,\n                          UWord32 *region_mlt_bits)\n{\n\n    Word16 *raw_mlt_ptr;\n    Word16 region;\n    Word16 category;\n    Word16 total_mlt_bits = 0;\n\n    Word16 temp;\n    Word16 temp1;\n    Word16 temp2;\n\n    /* Start in the middle of the categorization control range. */\n    temp = shr_nocheck(num_categorization_control_possibilities,1);\n    temp = sub(temp,1);\n    for (*p_categorization_control = 0; *p_categorization_control < temp; (*p_categorization_control)++)\n    {\n        region = category_balances[*p_categorization_control];\n        move16();\n        power_categories[region] = add(power_categories[region],1);\n        move16();\n    }\n\n    for (region=0; region<number_of_regions; region++)\n    {\n        category = power_categories[region];\n        move16();\n        temp = extract_l(L_mult0(region,REGION_SIZE));\n        raw_mlt_ptr = &mlt_coefs[temp];\n        move16();\n        temp = sub(category,(NUM_CATEGORIES-1));\n        test();\n        if (temp < 0)\n        {\n            region_mlt_bit_counts[region] =\n            vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,\n                           &region_mlt_bits[shl_nocheck(region,2)]);\n        }\n        else\n        {\n            region_mlt_bit_counts[region] = 0;\n            move16();\n        }\n        total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);\n    }\n\n\n    /* If too few bits... */\n    temp = sub(total_mlt_bits,number_of_available_bits);\n    test();\n    test();\n    logic16();\n    while ((temp < 0) && (*p_categorization_control > 0))\n    {\n        test();\n        test();\n        logic16();\n        (*p_categorization_control)--;\n        region = category_balances[*p_categorization_control];\n        move16();\n        \n        power_categories[region] = sub(power_categories[region],1);\n        move16();\n\n        total_mlt_bits = sub(total_mlt_bits,region_mlt_bit_counts[region]);\n        category = power_categories[region];\n        move16();\n        \n        raw_mlt_ptr = &mlt_coefs[region*REGION_SIZE];\n        move16();\n        \n        temp = sub(category,(NUM_CATEGORIES-1));\n        test();\n        if (temp < 0)\n        {\n            region_mlt_bit_counts[region] =\n                vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,\n                           &region_mlt_bits[shl_nocheck(region,2)]);\n        }\n        else\n        {\n            region_mlt_bit_counts[region] = 0;\n            move16();\n        }\n        total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);\n        temp = sub(total_mlt_bits,number_of_available_bits);\n    }\n\n    /* If too many bits... */\n    /* Set up for while loop test */\n    temp1 = sub(total_mlt_bits,number_of_available_bits);\n    temp2 = sub(*p_categorization_control,sub(num_categorization_control_possibilities,1));\n    test();\n    test();\n    logic16();\n    \n    while ((temp1 > 0) && (temp2 < 0))\n    {\n        /* operations for while contitions */\n        test();\n        test();\n        logic16();\n        \n        region = category_balances[*p_categorization_control];\n        move16();\n        \n        power_categories[region] = add(power_categories[region],1);\n        move16();\n\n        total_mlt_bits = sub(total_mlt_bits,region_mlt_bit_counts[region]);\n        category = power_categories[region];\n        move16();\n        \n        temp = extract_l(L_mult0(region,REGION_SIZE));\n        raw_mlt_ptr = &mlt_coefs[temp];\n        move16();\n        \n        temp = sub(category,(NUM_CATEGORIES-1));\n        test();\n        if (temp < 0)\n        {\n            region_mlt_bit_counts[region] =\n                vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,\n                           &region_mlt_bits[shl_nocheck(region,2)]);\n        }\n        else\n        {\n            region_mlt_bit_counts[region] = 0;\n            move16();\n        }\n        total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);\n        (*p_categorization_control)++;\n        \n        temp1 = sub(total_mlt_bits,number_of_available_bits);\n        temp2 = sub(*p_categorization_control,sub(num_categorization_control_possibilities,1));\n    }\n}\n\n/***************************************************************************\n Function:    vector_huffman\n\n Syntax:      Word16 vector_huffman(Word16  category,     \n                                    Word16  power_index,  \n                                    Word16  *raw_mlt_ptr,  \n                                    UWord32 *word_ptr)     \n                                              \n              inputs:     Word16  category\n                          Word16  power_index\n                          Word16  *raw_mlt_ptr\n             \n              outputs:    number_of_region_bits\n                          *word_ptr\n                                      \n\n Description: Huffman encoding for each region based on category and power_index  \n\n WMOPS:     7kHz |    24kbit    |     32kbit\n          -------|--------------|----------------\n            AVG  |    0.03      |     0.03\n          -------|--------------|----------------  \n            MAX  |    0.04      |     0.04\n          -------|--------------|---------------- \n\n           14kHz |    24kbit    |     32kbit     |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    0.03      |     0.03       |     0.03\n          -------|--------------|----------------|----------------\n            MAX  |    0.04      |     0.04       |     0.04\n          -------|--------------|----------------|----------------\n\n***************************************************************************/\nWord16 vector_huffman(Word16 category,\n                      Word16 power_index,\n                      Word16 *raw_mlt_ptr,\n                      UWord32 *word_ptr)\n{\n \n\n    Word16  inv_of_step_size_times_std_dev;\n    Word16  j,n;\n    Word16  k;\n    Word16  number_of_region_bits;\n    Word16  number_of_non_zero;\n    Word16  vec_dim;\n    Word16  num_vecs;\n    Word16  kmax, kmax_plus_one;\n    Word16  index,signs_index;\n    Word16  *bitcount_table_ptr;\n    UWord16 *code_table_ptr;\n    Word32  code_bits;\n    Word16  number_of_code_bits;\n    UWord32 current_word;\n    Word16  current_word_bits_free;\n    \n    Word32 acca;\n    Word32 accb;\n    Word16 temp;\n\n    Word16 mytemp;\t\t\t /* new variable in Release 1.2 */\n    Word16 myacca;\t\t\t /* new variable in Release 1.2 */\n\n\n    /* initialize variables */\n    vec_dim = vector_dimension[category];\n    move16();\n\n    num_vecs = number_of_vectors[category];\n    move16();\n\n    kmax = max_bin[category];\n    move16();\n\n    kmax_plus_one = add(kmax,1);\n    move16();\n\n    current_word = 0L;\n    move16();\n\n    current_word_bits_free = 32;\n    move16();\n\n    number_of_region_bits = 0;\n    move16();\n\n    /* set up table pointers */\n    bitcount_table_ptr = (Word16 *)table_of_bitcount_tables[category];\n    code_table_ptr = (UWord16 *) table_of_code_tables[category];\n\n    /* compute inverse of step size * standard deviation */\n    acca = L_mult(step_size_inverse_table[category],standard_deviation_inverse_table[power_index]);\n    acca = L_shr_nocheck(acca,1);\n    acca = L_add(acca,4096);\n    acca = L_shr_nocheck(acca,13);\n\n\t/*\n\t *  The next two lines are new to Release 1.2 \n\t */\n     \n\tmytemp = (Word16)(acca & 0x3);\n    acca = L_shr_nocheck(acca,2);\n\n    inv_of_step_size_times_std_dev = extract_l(acca);\n\n\n    for (n=0; n<num_vecs; n++)\n    {\n        index = 0;\n        move16();\n        \n        signs_index = 0;\n        move16();\n        \n        number_of_non_zero = 0;\n        move16();\n        \n        for (j=0; j<vec_dim; j++)\n        {\n            k = abs_s(*raw_mlt_ptr);\n            \n            acca = L_mult(k,inv_of_step_size_times_std_dev);\n            acca = L_shr_nocheck(acca,1);\n\t\t    \n\t\t\t/*\n\t\t\t *  The next four lines are new to Release 1.2\n\t\t\t */\n\n\t\t\tmyacca = (Word16)L_mult(k,mytemp);\n\t\t\tmyacca = (Word16)L_shr_nocheck(myacca,1);\n\t\t\tmyacca = (Word16)L_add(myacca,int_dead_zone_low_bits[category]);\n\t\t\tmyacca = (Word16)L_shr_nocheck(myacca,2);\n\n            acca = L_add(acca,int_dead_zone[category]);\n\n\t\t\t/*\n\t\t\t *  The next two lines are new to Release 1.2\n\t\t\t */\n\n\t\t\tacca = L_add(acca,myacca);\n\t\t\tacca = L_shr_nocheck(acca,13);\n\n            k = extract_l(acca);\n\n            test();\n            if (k != 0)\n            {\n                number_of_non_zero = add(number_of_non_zero,1);\n                signs_index = shl_nocheck(signs_index,1);\n                \n                test();\n                if (*raw_mlt_ptr > 0)\n                {\n                    signs_index = add(signs_index,1);\n                }\n                \n                temp = sub(k,kmax);\n                test();\n                if (temp > 0)\n                {\n                    k = kmax;\n                    move16();\n                }\n            }\n            acca = L_shr_nocheck(L_mult(index,(kmax_plus_one)),1);\n            index = extract_l(acca);\n            index = add(index,k);\n            raw_mlt_ptr++;\n        }\n\n        code_bits = *(code_table_ptr+index);\n        number_of_code_bits = add((*(bitcount_table_ptr+index)),number_of_non_zero);\n        number_of_region_bits = add(number_of_region_bits,number_of_code_bits);\n\n        acca = code_bits << number_of_non_zero;\n        accb = L_deposit_l(signs_index);\n        acca = L_add(acca,accb);\n        code_bits = acca;\n        move32();\n\n        /* msb of codebits is transmitted first. */\n        j = sub(current_word_bits_free,number_of_code_bits);\n        test();\n        if (j >= 0)\n        {\n            test();\n            acca = code_bits << j;\n            current_word = L_add(current_word,acca);\n            current_word_bits_free = j;\n            move16();\n        }\n        else\n        {\n            j = negate(j);\n            acca = L_shr_nocheck(code_bits,j);\n            current_word = L_add(current_word,acca);\n            \n            *word_ptr++ = current_word;\n            move16();\n\n            current_word_bits_free = sub(32,j);\n            test();\n            current_word = code_bits << current_word_bits_free;\n        }\n    }\n\n    *word_ptr++ = current_word;\n    move16();\n\n    return (number_of_region_bits);\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/g7221/encode/sam2coef.c",
    "content": "/******************************************************************************\n**\n**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C\n**   > Software Release 2.1 (2008-06)\n**     (Simple repackaging; no change from 2005-05 Release 2.0 code)\n**\n**    2004 Polycom, Inc.\n**\n**\t All rights reserved.\n**\n******************************************************************************/\n\n/******************************************************************************\n* Filename: samples_to_rmlt_coefs.c\n*\n* Purpose:  Convert Samples to Reversed MLT (Modulated Lapped Transform) \n*           Coefficients\n*\n*     The \"Reversed MLT\" is an overlapped block transform which uses\n*     even symmetry * on the left, odd symmetry on the right and a\n*     Type IV DCT as the block transform.  * It is thus similar to a\n*     MLT which uses odd symmetry on the left, even symmetry * on the\n*     right and a Type IV DST as the block transform.  In fact, it is\n*     equivalent * to reversing the order of the samples, performing\n*     an MLT and then negating all * the even-numbered coefficients.\n*\n******************************************************************************/\n\n/***************************************************************************\n Include files                                                           \n***************************************************************************/\n#include \"defs.h\"\n#include \"tables.h\"\n#include \"count.h\"\n\n/***************************************************************************\n Function:    samples_to_rmlt_coefs \n\n Syntax:      Word16 samples_to_rmlt_coefs(new_samples, \n                                           old_samples,\n                                           coefs,\n                                           dct_length)\n                    Word16 *new_samples;           \n                    Word16 *old_samples;           \n                    Word16 *coefs;                 \n                    Word16 dct_length;\n\n Description: Convert samples to MLT coefficients\n\n Design Notes:\n\n WMOPS:     7kHz |    24kbit    |     32kbit\n          -------|--------------|----------------\n            AVG  |    1.40      |     1.40\n          -------|--------------|----------------  \n            MAX  |    1.40      |     1.40\n          -------|--------------|---------------- \n\t\t\t\t\n           14kHz |    24kbit    |     32kbit     |     48kbit\n          -------|--------------|----------------|----------------\n            AVG  |    3.07      |     3.07       |     3.07\n          -------|--------------|----------------|----------------\n            MAX  |    3.10      |     3.10       |     3.10\n          -------|--------------|----------------|----------------\n\t\t\t\t\n***************************************************************************/\n\nWord16 samples_to_rmlt_coefs(const Word16 *new_samples,Word16 *old_samples,Word16 *coefs,Word16 dct_length)\n{\n\n    Word16\tindex, vals_left,mag_shift,n;\n    Word16\twindowed_data[MAX_DCT_LENGTH];\n    Word16\t*old_ptr;\n    const Word16 *new_ptr, *sam_low, *sam_high;\n    Word16\t*win_low, *win_high;\n    Word16\t*dst_ptr;\n    Word16  neg_win_low;\n    Word16  samp_high;\n    Word16  half_dct_size;\n    \n    Word32\tacca;\n    Word32\taccb;\n    Word16\ttemp;\n    Word16\ttemp1;\n    Word16\ttemp2;\n    Word16\ttemp5;\n   \n    half_dct_size = shr_nocheck(dct_length,1);\n   \n    /*++++++++++++++++++++++++++++++++++++++++++++*/\n    /* Get the first half of the windowed samples */\n    /*++++++++++++++++++++++++++++++++++++++++++++*/\n    \n    dst_ptr  = windowed_data;\n    move16();\n    \n    /* address arithmetic */\n    test();\n    if (dct_length==DCT_LENGTH)\n    {\n        win_high = samples_to_rmlt_window + half_dct_size;\n    }\n    else\n    {\n        win_high = max_samples_to_rmlt_window + half_dct_size;\n    }\n    \n    win_low  = win_high;\n    move16();\n    \n    /* address arithmetic */\n    sam_high = old_samples + half_dct_size;\n    \n    sam_low  = sam_high;\n    move16();\n    \n    for (vals_left = half_dct_size;vals_left > 0;vals_left--)\n    {\n        acca = 0L;\n        move32();\n        \n        acca = L_mac(acca,*--win_low, *--sam_low);\n        acca = L_mac(acca,*win_high++, *sam_high++);\n        temp = itu_round(acca); \n        \n        *dst_ptr++ = temp;\n        move16();\n    }           \n    \n    /*+++++++++++++++++++++++++++++++++++++++++++++*/\n    /* Get the second half of the windowed samples */\n    /*+++++++++++++++++++++++++++++++++++++++++++++*/\n    \n    sam_low  = new_samples;\n    move16();\n\n    /* address arithmetic */\n    sam_high = new_samples + dct_length;\n    \n    for (vals_left = half_dct_size;    vals_left > 0;    vals_left--)\n    {\n        acca = 0L;\n        move32();\n\n        acca = L_mac(acca,*--win_high, *sam_low++);\n        neg_win_low = negate(*win_low++);\n        samp_high = *--sam_high;\n        acca = L_mac(acca, neg_win_low, samp_high);\n        temp = itu_round(acca); \n        \n        *dst_ptr++=temp;\n        move16();\n    }\n       \n    /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n    /* Save the new samples for next time, when they will be the old samples */\n    /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n    \n    new_ptr = new_samples;\n    move16();\n\n    old_ptr = old_samples;\n    move16();\n\n    for (vals_left = dct_length;vals_left > 0;vals_left--)\n    {\n        *old_ptr++ = *new_ptr++;\n        move16();\n    }\n    \n    /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n    /* Calculate how many bits to shift up the input to the DCT.             */\n    /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n    \n    temp1=0;\n    move16();\n\n    for(index=0;index<dct_length;index++)\n    {\n        temp2 = abs_s(windowed_data[index]);\n        temp = sub(temp2,temp1);\n        test();\n        if(temp > 0)\n        {\n            move16();\n            temp1 = temp2;\n        }\n    }\n    \n    mag_shift=0;\n    move16();\n\n    temp = sub(temp1,14000);\n    test();\n    if (temp >= 0)\n    {\n        mag_shift = 0;\n        move16();\n    }\n    else\n    {\n        temp = sub(temp1,438);\n        test();\n        if(temp < 0)\n            temp = add(temp1,1);\n        else \n        {\n            temp = temp1;\n            move16();\n        }\n        accb = L_mult(temp,9587);\n        acca = L_shr_nocheck(accb,20);\n        temp5 = extract_l(acca);\n        temp = norm_s(temp5);\n        test();\n        if (temp == 0)\n        {\n            mag_shift = 9;\n            move16();\n        }\n        else\n            mag_shift = sub(temp,6);\n        \n    }\n\n    acca = 0L;\n    move32();\n    for(index=0; index<dct_length; index++)\n    {\n        temp = abs_s( windowed_data[index]);\n        acca = L_add(acca,temp);\n    }\n    \n    acca = L_shr_nocheck(acca,7);\n    \n    test();\n    if (temp1 < acca)\n    {\n        mag_shift = sub(mag_shift,1);\n    }\n\n    test();\n    if (mag_shift > 0) \n    {\n        for(index=0;index<dct_length;index++)\n        {\n            windowed_data[index] = shl_nocheck(windowed_data[index],mag_shift);\n        }\n    }\n    else \n    {\n        test();\n        if (mag_shift < 0) \n        {\n            n = negate(mag_shift);\n            for(index=0;index<dct_length;index++)\n            {\n                windowed_data[index] = shr_nocheck(windowed_data[index],n);\n                move16();\n            }\n        }\n    }\n\n    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n    /* Perform a Type IV DCT on the windowed data to get the coefficients */\n    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n\n    dct_type_iv_a(windowed_data, coefs, dct_length);\n\n    return(mag_shift);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/COPYRIGHT",
    "content": "Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,\nTechnische Universitaet Berlin\n\nAny use of this software is permitted provided that this notice is not\nremoved and that neither the authors nor the Technische Universitaet Berlin\nare deemed to have made any representations as to the suitability of this\nsoftware for any purpose nor are held responsible for any defects of\nthis software.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n\nAs a matter of courtesy, the authors request to be informed about uses\nthis software has found, about bugs in this software, and about any\nimprovements that may be of general interest.\n\nBerlin, 28.11.1994\nJutta Degener\nCarsten Bormann\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/ChangeLog",
    "content": "\nFri Jun  2 06:27:56 2006\tJutta Degener (jutta@pobox.com)\n\n\t* Release 1.0 Patchlevel 12\n\tsrc/code.c: removed modifiable static storage that made the library\n\t \tnon-reentrant.  (Thanks to Paul Gibbs for pointing out the bug.)\n\nSat Mar 18 11:48:28 2006\tJutta Degener (jutta@pobox.com)\n\n\t* Release 1.0 Patchlevel 11\n\tsrc/gsm_implode.c: fix WAV49 implode\n\tmove source archive location\n\nFri Jul  5 19:26:37 1996 \tJutta Degener (jutta@cs.tu-berlin.de)\n\n\t* Release 1.0 Patchlevel 10\n\tsrc/toast_alaw.c: exchanged A-law tables for something\n\t\tslightly more A-law.\n\nTue Jul  2 12:18:20 1996  Jutta Degener (jutta@cs.tu-berlin.de)\n\n\t* Release 1.0 Patchlevel 9\n\tsrc/long_term.c: in FLOAT_MUL mode, an array was accessed past its end\n\tsrc/gsm_option.c: three options related to WAV #49 packing\n\tsrc/gsm_encode.c: support WAV #49-style encoding.\n\tsrc/gsm_decode.c: support WAV #49-style decoding.\n\ttls/sour.c: generate the WAV bit shifting code, encode\n\ttls/ginger.c: generate the WAV bit shifting code, decode\n\tThe WAV code goes back to an inofficial patch #8 that\n\tJeff Chilton sent us (hence the jump from 7 to 9).\n\tsrc/toast.c: add _fsetmode() calls to set stdin/stdout to\n\t\tbinary (from an OS/2 port by Arnd Gronenberg.)\n\nTue Mar  7 01:55:10 1995  Jutta Degener (jutta@cs.tu-berlin.de)\n\n\t* Release 1.0 Patchlevel 7\n\tsrc/long_term.c: Yet another 16-bit overflow\n\tsrc/toast.c: -C option to toast, cuts LPC time\n\tsrc/gsm_option.c: corresponding LPC_CUT option to GSM library\n\nFri Dec 30 23:33:50 1994  Jutta Degener (jutta@cs.tu-berlin.de)\n\n        * Release 1.0 Patchlevel 6\n        src/lpc.c: fixed 16-bit addition overflow in Autocorrelation code\n        src/add.c: gsm_L_asl should fall back on gsm_L_asr, not gsm_asr\n\nMon Nov 28 20:49:57 1994  Jutta Degener (jutta@cs.tu-berlin.de)\n\t\n\t* Release 1.0 Patchlevel 5\n\tsrc/toast_audio.c: initialization should return -1 on error\n\tsrc/gsm_destroy.c: #include configuration header file\n\tsrc/add.c: gsm_sub should cast its parameters to longword\n\tman/*: bug reports to {jutta,cabo}@cs.tu-berlin.de, not to toast@tub\n\tinc/private.h: longword long by default, not int\n\tinc/toast.h: read/write fopen modes \"rb\" and \"wb\", not just \"r\"\n\tsrc/toast.c: better (or different, anyway) error handling in process()\n\nTue May 10 19:41:34 1994  Jutta Degener (jutta at kugelbus)\n\t\n\t* Release 1.0 Patchlevel 4\n\tinc/private.h: GSM_ADD should cast to ulongword, not to unsigned.\n\tsrc/long_term.c: missing cast to longword.\n\tadd-test/add_test.c: Test macros too, not only functions,\n\tthanks to Simao Ferraz de Campos Neto, simao@dragon.cpqd.ansp.br\n\tGeneral cleanup: remove unused variables, add function prototypes.\n\nTue Jan 25 22:53:40 1994  Jutta Degener (jutta at kugelbus)\n\n\t* Release 1.0 Patchlevel 3\n\tchanged rpe.c's STEP macro to work with 16-bit integers,\n\tthanks to Dr Alex Lee (alexlee@solomon.technet.sg);\n\tremoved non-fatal bugs from add-test.dta, private.h\n\tand toast_audio.c, thanks to P. Emanuelsson.\n\nFri Jan 29 19:02:12 1993  Jutta Degener  (jutta at kraftbus)\n\t\n\t* Release 1.0 Patchlevel 2\n\tfixed L_add(0,-1) in src/add.c and inc/private.h,\n\tthanks to Raphael Trommer at AT&T Bell Laboratories;\n\tvarious other ANSI C compatibility details\n\nFri Oct 30 17:58:54 1992  Jutta Degener  (jutta at kraftbus)\n\n\t* Release 1.0 Patchlevel 1\n\tSwitched uid/gid in toast's [f]chown calls.\n\nWed Oct 28 14:12:35 1992  Carsten Bormann  (cabo at kubus)\n\n\t* Release 1.0: released\n\tCopyright 1992 by Jutta Degener and Carsten Bormann, Technische\n\tUniversitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n\tdetails.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/INSTALL",
    "content": "How to get started:\n\n   Edit the Makefile.\n\n\tYou should configure a few machine-dependencies and what\n\tcompiler you want to use.\n\n  \tThe code works both with ANSI and K&R-C.  Use\n\t-DNeedFunctionPrototypes to compile with, or\n\t-UNeedFunctionPrototypes to compile without, function\n\tprototypes in the header files.\n \n   Make addtst\n\n\tThe \"add\" program that will be compiled and run checks whether\n\tthe basic math functions of the gsm library work with your\n\tcompiler.  If it prints anything to stderr, complain (to us).\n\n   Edit inc/config.h.\n\n   Make\n\n   \tLocal versions of the gsm library and the \"compress\"-like filters\n\ttoast, untoast and tcat will be generated.\n\n   \tIf the compilation aborts because of a missing function,\n\tdeclaration, or header file, see if there's something in\n\tinc/config.h to work around it.  If not, complain.\n\n   Try it\n\n\tGrab an audio file from somewhere (raw u-law or Sun .au is fine, \n    \tlinear 16-bit in host byte order will do), copy it, toast it,\n\tuntoast it, and listen to the result.\n    \n\tThe GSM-encoded and -decoded audio should have the quality\n\tof a good phone line.  If the resulting audio is noisier than\n\tyour original, or if you hear compression artifacts, complain;\n\tthat's a bug in our software, not a bug in the GSM encoding\n\tstandard itself.\n\nInstallation\n\n   You can install the gsm library interface, or the toast binaries,\n   or both.\n\n   Edit the Makefile\n\t\n\tFill in the directories where you want to install the\n\tlibrary, header files, manual pages, and binaries.\n\n\tTurn off the installation of one half of the distribution\n\t(i.e., gsm library or toast binaries) by not setting the\n\tcorresponding directory root Makefile macro.\n\n   make install\n\n\twill install the programs \"toast\" with two links named\n\t\"tcat\" and \"untoast\", and the gsm library \"libgsm.a\" with\n\ta \"gsm.h\" header file, and their respective manual pages.\n\n\nOptimizing\n\n   This code was developed on a machine without an integer\n   multiplication instruction, where we obtained the fastest result by\n   replacing some of the integer multiplications with floating point\n   multiplications.\n\n   If your machine does multiply integers fast enough,\n   leave USE_FLOAT_MUL undefined.  The results should be the\n   same in both cases.\n\n   On machines with fast floating point arithmetic, defining\n   both USE_FLOAT_MUL and FAST makes a run-time library\n   option available that will (in a few crucial places) use\n   ``native'' floating point operations rather than the bit-by-bit\n   defined ones of the GSM standard.  If you use this fast\n   option, the outcome will not be bitwise identical to the\n   results prescribed by the standard, but it is compatible with\n   the standard encoding, and a user is unlikely to notice a\n   difference.\n\n\nBug Reports\n\n   Please direct bug reports, questions, and comments to\n   jutta@cs.tu-berlin.de and cabo@informatik.uni-bremen.de.\n\n\nGood luck,\n\n   Jutta Degener,\n   Carsten Bormann\n\n--\nCopyright 1992, 1993, 1994, by Jutta Degener and Carsten Bormann,\nTechnische Universitaet Berlin.  See the accompanying file \"COPYRIGHT\"\nfor details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/MACHINES",
    "content": "The gsm library has been tested successfully on the following platforms:\n\n- Various Sun4s running SunOS 4.1.2\n- SPARC1 (SunOS 4.1.1)\n- Integrated Solutions 68k Optimum running 4.3BSD UNIX with a Green Hills cc\n- NeXTstation running NeXT-OS/Mach 3.0\n- No-name AT/386 with Xenix 2.3.2 (using -DSTUPID_COMPILER)\n- RS/6000-350 running AIX 3.2.0\n- RS/6000-320 running AIX 3.1.5\n- Alliant FX80 (Concentrix 5.7)\n- SGI Indigo XS4000 (IRIX 4.0.5F)\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/MANIFEST",
    "content": "gsm-1.0/COPYRIGHT\ngsm-1.0/ChangeLog\ngsm-1.0/INSTALL\ngsm-1.0/MACHINES\ngsm-1.0/MANIFEST\ngsm-1.0/Makefile\ngsm-1.0/README\ngsm-1.0/add-test/add_test.c\ngsm-1.0/add-test/add_test.dta\ngsm-1.0/inc/gsm.h\ngsm-1.0/inc/proto.h\ngsm-1.0/inc/unproto.h\ngsm-1.0/inc/config.h\ngsm-1.0/inc/private.h\ngsm-1.0/inc/toast.h\ngsm-1.0/man/bitter.1\ngsm-1.0/man/gsm.3\ngsm-1.0/man/gsm_explode.3\ngsm-1.0/man/gsm_print.3\ngsm-1.0/man/gsm_option.3\ngsm-1.0/man/toast.1\ngsm-1.0/src/add.c\ngsm-1.0/src/code.c\ngsm-1.0/src/debug.c\ngsm-1.0/src/decode.c\ngsm-1.0/src/gsm_destroy.c\ngsm-1.0/src/gsm_decode.c\ngsm-1.0/src/gsm_encode.c\ngsm-1.0/src/gsm_explode.c\ngsm-1.0/src/gsm_implode.c\ngsm-1.0/src/gsm_create.c\ngsm-1.0/src/gsm_print.c\ngsm-1.0/src/gsm_option.c\ngsm-1.0/src/long_term.c\ngsm-1.0/src/lpc.c\ngsm-1.0/src/preprocess.c\ngsm-1.0/src/rpe.c\ngsm-1.0/src/short_term.c\ngsm-1.0/src/table.c\ngsm-1.0/src/toast.c\ngsm-1.0/src/toast_alaw.c\ngsm-1.0/src/toast_audio.c\ngsm-1.0/src/toast_lin.c\ngsm-1.0/src/toast_ulaw.c\ngsm-1.0/tls/bitter.c\ngsm-1.0/tls/bitter.dta\ngsm-1.0/tls/taste.c\ngsm-1.0/tls/taste.h\ngsm-1.0/tls/sweet.c\ngsm-1.0/tls/sour.c\ngsm-1.0/tls/sour1.dta\ngsm-1.0/tls/sour2.dta\ngsm-1.0/tls/ginger.c\ngsm-1.0/tst/cod2lin.c\ngsm-1.0/tst/cod2txt.c\ngsm-1.0/tst/gsm2cod.c\ngsm-1.0/tst/lin2cod.c\ngsm-1.0/tst/lin2txt.c\ngsm-1.0/tst/run\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/Makefile",
    "content": "# Copyright 1992-1996 by Jutta Degener and Carsten Bormann, Technische\n# Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n# details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n\n# Machine- or installation dependent flags you should configure to port\n\nSASR\t= -DSASR\n######### Define SASR if >> is a signed arithmetic shift (-1 >> 1 == -1)\n\n# MULHACK = -DUSE_FLOAT_MUL\n######### Define this if your host multiplies floats faster than integers,\n######### e.g. on a SPARCstation.\n\n# FAST\t= -DFAST\n######### Define together with USE_FLOAT_MUL to enable the GSM library's\n######### approximation option for incorrect, but good-enough results.\n\n# LTP_CUT\t= -DLTP_CUT\nLTP_CUT\t=\n######### Define to enable the GSM library's long-term correlation \n######### approximation option---faster, but worse; works for\n######### both integer and floating point multiplications.\n######### This flag is still in the experimental stage.\n\nWAV49\t= -DWAV49\n# WAV49\t=\n######### Define to enable the GSM library's option to pack GSM frames \n######### in the style used by the WAV #49 format.  If you want to write\n######### a tool that produces .WAV files which contain GSM-encoded data,\n######### define this, and read about the GSM_OPT_WAV49 option in the\n######### manual page on gsm_option(3).\n\n# Choose a compiler.  The code works both with ANSI and K&R-C.\n# Use -DNeedFunctionPrototypes to compile with, -UNeedFunctionPrototypes to\n# compile without, function prototypes in the header files.\n#\n# You can use the -DSTUPID_COMPILER to circumvent some compilers'\n# static limits regarding the number of subexpressions in a statement.\n\n# CC\t\t= cc\n# CCFLAGS \t= -c -DSTUPID_COMPILER\n\n# CC\t\t= /usr/lang/acc\n# CCFLAGS \t= -c -O\n\nCC\t\t= gcc -ansi -pedantic\nCCFLAGS \t= -c -O2 -DNeedFunctionPrototypes=1\n\nLD \t\t= $(CC)\n\n# LD\t\t= gcc\n# LDFLAGS \t=\n\n\n# If your compiler needs additional flags/libraries, regardless of\n# the source compiled, configure them here.\n\n# CCINC\t= -I/usr/gnu/lib/gcc-2.1/gcc-lib/sparc-sun-sunos4.1.2/2.1/include\n######### Includes needed by $(CC)\n\n# LDINC\t= -L/usr/gnu/lib/gcc-2.1/gcc-lib/sparc-sun-sunos4.1.2/2.1\n######### Library paths needed by $(LD)\n\n# LDLIB\t= -lgcc\n######### Additional libraries needed by $(LD)\n\n\n# Where do you want to install libraries, binaries, a header file\n# and the manual pages?\n#\n# Leave INSTALL_ROOT empty (or just don't execute \"make install\") to\n# not install gsm and toast outside of this directory.\n\nINSTALL_ROOT\t=\n\n# Where do you want to install the gsm library, header file, and manpages?\n#\n# Leave GSM_INSTALL_ROOT empty to not install the GSM library outside of\n# this directory.\n\nGSM_INSTALL_ROOT = $(INSTALL_ROOT)\nGSM_INSTALL_LIB = $(GSM_INSTALL_ROOT)/lib\nGSM_INSTALL_INC = $(GSM_INSTALL_ROOT)/inc\nGSM_INSTALL_MAN = $(GSM_INSTALL_ROOT)/man/man3\n\n\n# Where do you want to install the toast binaries and their manpage?\n#\n# Leave TOAST_INSTALL_ROOT empty to not install the toast binaries outside\n# of this directory.\n\nTOAST_INSTALL_ROOT\t  = $(INSTALL_ROOT)\nTOAST_INSTALL_BIN = $(TOAST_INSTALL_ROOT)/bin\nTOAST_INSTALL_MAN = $(TOAST_INSTALL_ROOT)/man/man1\n\n#  Other tools\n\nSHELL\t\t= /bin/sh\nLN\t\t= ln\nBASENAME \t= basename\nAR\t\t= ar\nARFLAGS\t\t= cr\nRMFLAGS\t\t=\nFIND\t\t= find\nCOMPRESS \t= compress\nCOMPRESSFLAGS \t= \n# RANLIB \t= true\nRANLIB\t \t= ranlib\n\n#\n#    You shouldn't have to configure below this line if you're porting.\n# \n\n\n# Local Directories\n\nROOT\t= .\nADDTST\t= $(ROOT)/add-test\nTST\t= $(ROOT)/tst\nMAN\t= $(ROOT)/man\nBIN\t= $(ROOT)/bin\nSRC\t= $(ROOT)/src\nLIB\t= $(ROOT)/lib\nTLS\t= $(ROOT)/tls\nINC\t= $(ROOT)/inc\n\n# Flags\n\n# DEBUG\t= -DNDEBUG\n######### Remove -DNDEBUG to enable assertions.\n\nCFLAGS\t= $(CCFLAGS) $(SASR) $(DEBUG) $(MULHACK) $(FAST) $(LTP_CUT) \\\n\t$(WAV49) $(CCINC) -I$(INC)\n######### It's $(CC) $(CFLAGS)\n\nLFLAGS\t= $(LDFLAGS) $(LDINC)\n######### It's $(LD) $(LFLAGS)\n\n\n# Targets\n\nLIBGSM\t= $(LIB)/libgsm.a\n\nTOAST\t= $(BIN)/toast\nUNTOAST\t= $(BIN)/untoast\nTCAT\t= $(BIN)/tcat\n\n# Headers\n\nGSM_HEADERS =\t$(INC)/gsm.h\n\nHEADERS\t=\t$(INC)/proto.h\t\t\\\n\t\t$(INC)/unproto.h\t\\\n\t\t$(INC)/config.h\t\t\\\n\t\t$(INC)/private.h\t\\\n\t\t$(INC)/gsm.h\t\t\\\n\t\t$(INC)/toast.h\t\t\\\n\t\t$(TLS)/taste.h\n\n# Sources\n\nGSM_SOURCES =\t$(SRC)/add.c\t\t\\\n\t\t$(SRC)/code.c\t\t\\\n\t\t$(SRC)/debug.c\t\t\\\n\t\t$(SRC)/decode.c\t\t\\\n\t\t$(SRC)/long_term.c\t\\\n\t\t$(SRC)/lpc.c\t\t\\\n\t\t$(SRC)/preprocess.c\t\\\n\t\t$(SRC)/rpe.c\t\t\\\n\t\t$(SRC)/gsm_destroy.c\t\\\n\t\t$(SRC)/gsm_decode.c\t\\\n\t\t$(SRC)/gsm_encode.c\t\\\n\t\t$(SRC)/gsm_explode.c\t\\\n\t\t$(SRC)/gsm_implode.c\t\\\n\t\t$(SRC)/gsm_create.c\t\\\n\t\t$(SRC)/gsm_print.c\t\\\n\t\t$(SRC)/gsm_option.c\t\\\n\t\t$(SRC)/short_term.c\t\\\n\t\t$(SRC)/table.c\n\nTOAST_SOURCES = $(SRC)/toast.c \t\t\\\n\t\t$(SRC)/toast_lin.c\t\\\n\t\t$(SRC)/toast_ulaw.c\t\\\n\t\t$(SRC)/toast_alaw.c\t\\\n\t\t$(SRC)/toast_audio.c\n\nSOURCES\t=\t$(GSM_SOURCES)\t\t\\\n\t\t$(TOAST_SOURCES)\t\\\n\t\t$(ADDTST)/add_test.c\t\\\n\t\t$(TLS)/sour.c\t\t\\\n\t\t$(TLS)/ginger.c\t\t\\\n\t\t$(TLS)/sour1.dta\t\\\n\t\t$(TLS)/sour2.dta\t\\\n\t\t$(TLS)/bitter.c\t\t\\\n\t\t$(TLS)/bitter.dta\t\\\n\t\t$(TLS)/taste.c\t\t\\\n\t\t$(TLS)/sweet.c\t\t\\\n\t\t$(TST)/cod2lin.c\t\\\n\t\t$(TST)/cod2txt.c\t\\\n\t\t$(TST)/gsm2cod.c\t\\\n\t\t$(TST)/lin2cod.c\t\\\n\t\t$(TST)/lin2txt.c\n\n# Object files\n\nGSM_OBJECTS =\t$(SRC)/add.o\t\t\\\n\t\t$(SRC)/code.o\t\t\\\n\t\t$(SRC)/debug.o\t\t\\\n\t\t$(SRC)/decode.o\t\t\\\n\t\t$(SRC)/long_term.o\t\\\n\t\t$(SRC)/lpc.o\t\t\\\n\t\t$(SRC)/preprocess.o\t\\\n\t\t$(SRC)/rpe.o\t\t\\\n\t\t$(SRC)/gsm_destroy.o\t\\\n\t\t$(SRC)/gsm_decode.o\t\\\n\t\t$(SRC)/gsm_encode.o\t\\\n\t\t$(SRC)/gsm_explode.o\t\\\n\t\t$(SRC)/gsm_implode.o\t\\\n\t\t$(SRC)/gsm_create.o\t\\\n\t\t$(SRC)/gsm_print.o\t\\\n\t\t$(SRC)/gsm_option.o\t\\\n\t\t$(SRC)/short_term.o\t\\\n\t\t$(SRC)/table.o\n\nTOAST_OBJECTS =\t$(SRC)/toast.o \t\t\\\n\t\t$(SRC)/toast_lin.o\t\\\n\t\t$(SRC)/toast_ulaw.o\t\\\n\t\t$(SRC)/toast_alaw.o\t\\\n\t\t$(SRC)/toast_audio.o\n\nOBJECTS =\t $(GSM_OBJECTS) $(TOAST_OBJECTS)\n\n# Manuals\n\nGSM_MANUALS =\t$(MAN)/gsm.3\t\t\\\n\t\t$(MAN)/gsm_explode.3\t\\\n\t\t$(MAN)/gsm_option.3\t\\\n\t\t$(MAN)/gsm_print.3\n\nTOAST_MANUALS =\t$(MAN)/toast.1\n\nMANUALS\t= \t$(GSM_MANUALS) $(TOAST_MANUALS) $(MAN)/bitter.1\n\n# Other stuff in the distribution\n\nSTUFF = \tChangeLog\t\t\t\\\n\t\tINSTALL\t\t\t\\\n\t\tMACHINES\t\t\\\n\t\tMANIFEST\t\t\\\n\t\tMakefile\t\t\\\n\t\tREADME\t\t\t\\\n\t\t$(ADDTST)/add_test.dta\t\\\n\t\t$(TLS)/bitter.dta\t\\\n\t\t$(TST)/run\n\n\n# Install targets\n\nGSM_INSTALL_TARGETS =\t\\\n\t\t$(GSM_INSTALL_LIB)/libgsm.a\t\t\\\n\t\t$(GSM_INSTALL_INC)/gsm.h\t\t\\\n\t\t$(GSM_INSTALL_MAN)/gsm.3\t\t\\\n\t\t$(GSM_INSTALL_MAN)/gsm_explode.3\t\\\n\t\t$(GSM_INSTALL_MAN)/gsm_option.3\t\t\\\n\t\t$(GSM_INSTALL_MAN)/gsm_print.3\n\nTOAST_INSTALL_TARGETS =\t\\\n\t\t$(TOAST_INSTALL_BIN)/toast\t\t\\\n\t\t$(TOAST_INSTALL_BIN)/tcat\t\t\\\n\t\t$(TOAST_INSTALL_BIN)/untoast\t\t\\\n\t\t$(TOAST_INSTALL_MAN)/toast.1\n\n\n# Default rules\n\n.c.o:\n\t\t$(CC) $(CFLAGS) $?\n\t\t@-mv `$(BASENAME) $@` $@ > /dev/null 2>&1\n\n# Target rules\n\nall:\t\t$(LIBGSM) $(TOAST) $(TCAT) $(UNTOAST)\n\t\t@-echo $(ROOT): Done.\n\ntst:\t\t$(TST)/lin2cod $(TST)/cod2lin $(TOAST) $(TST)/test-result\n\t\t@-echo tst: Done.\n\naddtst:\t\t$(ADDTST)/add $(ADDTST)/add_test.dta\n\t\t$(ADDTST)/add < $(ADDTST)/add_test.dta > /dev/null\n\t\t@-echo addtst: Done.\n\nmisc:\t\t$(TLS)/sweet $(TLS)/bitter $(TLS)/sour $(TLS)/ginger \t\\\n\t\t\t$(TST)/lin2txt $(TST)/cod2txt $(TST)/gsm2cod\n\t\t@-echo misc: Done.\n\ninstall:\ttoastinstall gsminstall\n\t\t@-echo install: Done.\n\n\n# The basic API: libgsm\n\n$(LIBGSM):\t$(LIB) $(GSM_OBJECTS)\n\t\t-rm $(RMFLAGS) $(LIBGSM)\n\t\t$(AR) $(ARFLAGS) $(LIBGSM) $(GSM_OBJECTS)\n\t\t$(RANLIB) $(LIBGSM)\n\n\n# Toast, Untoast and Tcat -- the compress-like frontends to gsm.\n\n$(TOAST):\t$(BIN) $(TOAST_OBJECTS) $(LIBGSM)\n\t\t$(LD) $(LFLAGS) -o $(TOAST) $(TOAST_OBJECTS) $(LIBGSM) $(LDLIB)\n\n$(UNTOAST):\t$(BIN) $(TOAST)\n\t\t-rm $(RMFLAGS) $(UNTOAST)\n\t\t$(LN) $(TOAST) $(UNTOAST)\n\n$(TCAT):\t$(BIN) $(TOAST)\n\t\t-rm $(RMFLAGS) $(TCAT)\n\t\t$(LN) $(TOAST) $(TCAT)\n\n\n# The local bin and lib directories\n\n$(BIN):\n\t\tif [ ! -d $(BIN) ] ; then mkdir $(BIN) ; fi\n\n$(LIB):\n\t\tif [ ! -d $(LIB) ] ; then mkdir $(LIB) ; fi\n\n\n# Installation\n\ngsminstall:\n\t\t-if [ x\"$(GSM_INSTALL_ROOT)\" != x ] ; then\t\\\n\t\t\tmake $(GSM_INSTALL_TARGETS) ;\t\\\n\t\tfi\n\ntoastinstall:\n\t\t-if [ x\"$(TOAST_INSTALL_ROOT)\" != x ]; then\t\\\n\t\t\tmake $(TOAST_INSTALL_TARGETS);\t\\\n\t\tfi\n\ngsmuninstall:\n\t\t-if [ x\"$(GSM_INSTALL_ROOT)\" != x ] ; then\t\\\n\t\t\trm $(RMFLAGS) $(GSM_INSTALL_TARGETS) ;\t\\\n\t\tfi\n\ntoastuninstall:\n\t\t-if [ x\"$(TOAST_INSTALL_ROOT)\" != x ] ; then \t\\\n\t\t\trm $(RMFLAGS) $(TOAST_INSTALL_TARGETS);\t\\\n\t\tfi\n\n$(TOAST_INSTALL_BIN)/toast:\t$(TOAST)\n\t\t-rm $@\n\t\tcp $(TOAST) $@\n\t\tchmod 755 $@\n\n$(TOAST_INSTALL_BIN)/untoast:\t$(TOAST_INSTALL_BIN)/toast\n\t\t-rm $@\n\t\tln $? $@\n\n$(TOAST_INSTALL_BIN)/tcat:\t$(TOAST_INSTALL_BIN)/toast\n\t\t-rm $@\n\t\tln $? $@\n\n$(TOAST_INSTALL_MAN)/toast.1:\t$(MAN)/toast.1\n\t\t-rm $@\n\t\tcp $? $@\n\t\tchmod 444 $@\n\n$(GSM_INSTALL_MAN)/gsm.3:\t$(MAN)/gsm.3\n\t\t-rm $@\n\t\tcp $? $@\n\t\tchmod 444 $@\n\n$(GSM_INSTALL_MAN)/gsm_option.3:\t$(MAN)/gsm_option.3\n\t\t-rm $@\n\t\tcp $? $@\n\t\tchmod 444 $@\n\n$(GSM_INSTALL_MAN)/gsm_explode.3:\t$(MAN)/gsm_explode.3\n\t\t-rm $@\n\t\tcp $? $@\n\t\tchmod 444 $@\n\n$(GSM_INSTALL_MAN)/gsm_print.3:\t$(MAN)/gsm_print.3\n\t\t-rm $@\n\t\tcp $? $@\n\t\tchmod 444 $@\n\n$(GSM_INSTALL_INC)/gsm.h:\t$(INC)/gsm.h\n\t\t-rm $@\n\t\tcp $? $@\n\t\tchmod 444 $@\n\n$(GSM_INSTALL_LIB)/libgsm.a:\t$(LIBGSM)\n\t\t-rm $@\n\t\tcp $? $@\n\t\tchmod 444 $@\n\n\n# Distribution\n\ndist:\t\tgsm-1.0.tar.Z\n\t\t@echo dist: Done.\n\ngsm-1.0.tar.Z:\t$(STUFF) $(SOURCES) $(HEADERS) $(MANUALS)\n\t\t(\tcd $(ROOT)/..;\t\t\t\t\\\n\t\t\ttar cvf - `cat $(ROOT)/gsm-1.0/MANIFEST\t\\\n\t\t\t\t| sed '/^#/d'`\t\t\t\\\n\t\t) | $(COMPRESS) $(COMPRESSFLAGS) > $(ROOT)/gsm-1.0.tar.Z\n\n# Clean\n\nuninstall:\ttoastuninstall gsmuninstall\n\t\t@-echo uninstall: Done.\n\nsemi-clean:\n\t\t-rm $(RMFLAGS)  */*.o\t\t\t\\\n\t\t\t$(TST)/lin2cod $(TST)/lin2txt\t\\\n\t\t\t$(TST)/cod2lin $(TST)/cod2txt\t\\\n\t\t\t$(TST)/gsm2cod \t\t\t\\\n\t\t\t$(TST)/*.*.*\n\t\t-$(FIND) . \\( -name core -o -name foo \\) \\\n\t\t\t-print | xargs rm $(RMFLAGS)\n\nclean:\tsemi-clean\n\t\t-rm $(RMFLAGS) $(LIBGSM) $(ADDTST)/add\t\t\\\n\t\t\t$(TOAST) $(TCAT) $(UNTOAST)\t\\\n\t\t\t$(ROOT)/gsm-1.0.tar.Z\n\n\n# Two tools that helped me generate gsm_encode.c and gsm_decode.c,\n# but aren't generally needed to port this.\n\n$(TLS)/sweet:\t$(TLS)/sweet.o $(TLS)/taste.o\n\t\t$(LD) $(LFLAGS) -o $(TLS)/sweet \\\n\t\t\t$(TLS)/sweet.o $(TLS)/taste.o $(LDLIB)\n\n$(TLS)/bitter:\t$(TLS)/bitter.o $(TLS)/taste.o\n\t\t$(LD) $(LFLAGS) -o $(TLS)/bitter \\\n\t\t\t$(TLS)/bitter.o $(TLS)/taste.o $(LDLIB)\n\n# A version of the same family that Jeff Chilton used to implement\n# the WAV #49 GSM format.\n\n$(TLS)/ginger:\t$(TLS)/ginger.o $(TLS)/taste.o\n\t\t$(LD) $(LFLAGS) -o $(TLS)/ginger \\\n\t\t\t$(TLS)/ginger.o $(TLS)/taste.o $(LDLIB)\n\n$(TLS)/sour:\t$(TLS)/sour.o $(TLS)/taste.o\n\t\t$(LD) $(LFLAGS) -o $(TLS)/sour \\\n\t\t\t$(TLS)/sour.o $(TLS)/taste.o $(LDLIB)\n\n# Run $(ADDTST)/add < $(ADDTST)/add_test.dta to make sure the\n# basic arithmetic functions work as intended.\n\n$(ADDTST)/add:\t$(ADDTST)/add_test.o\n\t\t$(LD) $(LFLAGS) -o $(ADDTST)/add $(ADDTST)/add_test.o $(LDLIB)\n\n\n# Various conversion programs between linear, text, .gsm and the code\n# format used by the tests we ran (.cod).  We paid for the test data,\n# so I guess we can't just provide them with this package.  Still,\n# if you happen to have them lying around, here's the code.\n# \n# You can use gsm2cod | cod2txt independently to look at what's\n# coded inside the compressed frames, although this shouldn't be\n# hard to roll on your own using the gsm_print() function from\n# the API.\n\n\n$(TST)/test-result:\t$(TST)/lin2cod $(TST)/cod2lin $(TOAST) $(TST)/run\n\t\t\t( cd $(TST); ./run ) \n\n$(TST)/lin2txt:\t\t$(TST)/lin2txt.o $(LIBGSM)\n\t\t\t$(LD) $(LFLAGS) -o $(TST)/lin2txt \\\n\t\t\t\t$(TST)/lin2txt.o $(LIBGSM) $(LDLIB)\n\n$(TST)/lin2cod:\t\t$(TST)/lin2cod.o $(LIBGSM)\n\t\t\t$(LD) $(LFLAGS) -o $(TST)/lin2cod \\\n\t\t\t\t$(TST)/lin2cod.o $(LIBGSM) $(LDLIB)\n\n$(TST)/gsm2cod:\t\t$(TST)/gsm2cod.o $(LIBGSM)\n\t\t\t$(LD) $(LFLAGS) -o $(TST)/gsm2cod \\\n\t\t\t\t$(TST)/gsm2cod.o $(LIBGSM) $(LDLIB)\n\n$(TST)/cod2txt:\t\t$(TST)/cod2txt.o $(LIBGSM)\n\t\t\t$(LD) $(LFLAGS) -o $(TST)/cod2txt \\\n\t\t\t\t$(TST)/cod2txt.o $(LIBGSM) $(LDLIB)\n\n$(TST)/cod2lin:\t\t$(TST)/cod2lin.o $(LIBGSM)\n\t\t\t$(LD) $(LFLAGS) -o $(TST)/cod2lin \\\n\t\t\t\t$(TST)/cod2lin.o $(LIBGSM) $(LDLIB)\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/README",
    "content": "\nGSM 06.10 13 kbit/s RPE/LTP speech compression available\n--------------------------------------------------------\n\nThe Communications and Operating Systems Research Group (KBS) at the\nTechnische Universitaet Berlin is currently working on a set of\nUNIX-based tools for computer-mediated telecooperation that will be\nmade freely available.\n\nAs part of this effort we are publishing an implementation of the\nEuropean GSM 06.10 provisional standard for full-rate speech\ntranscoding, prI-ETS 300 036, which uses RPE/LTP (residual pulse\nexcitation/long term prediction) coding at 13 kbit/s.\n\nGSM 06.10 compresses frames of 160 13-bit samples (8 kHz sampling\nrate, i.e. a frame rate of 50 Hz) into 260 bits; for compatibility\nwith typical UNIX applications, our implementation turns frames of 160\n16-bit linear samples into 33-byte frames (1650 Bytes/s).\nThe quality of the algorithm is good enough for reliable speaker\nrecognition; even music often survives transcoding in recognizable \nform (given the bandwidth limitations of 8 kHz sampling rate).\n\nThe interfaces offered are a front end modelled after compress(1), and\na library API.  Compression and decompression run faster than realtime\non most SPARCstations.  The implementation has been verified against the\nETSI standard test patterns.\n\nJutta Degener (jutta@cs.tu-berlin.de)\nCarsten Bormann (cabo@cs.tu-berlin.de)\n\nCommunications and Operating Systems Research Group, TU Berlin\nFax: +49.30.31425156, Phone: +49.30.31424315\n\n--\nCopyright 1992 by Jutta Degener and Carsten Bormann, Technische\nUniversitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\ndetails.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/add-test/add_test.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/add_test.c,v 1.2 1994/05/10 20:18:17 jutta Exp $ */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"gsm.h\"\n\n#include \"../src/add.c\"\n\nint\t\tinteractive = 1;\n\nchar\t\t* opname;\nlongword\tL_op1, L_op2, L_expect;\nword\t\top1, op2, expect;\nint\t\tdo_expect;\n\nword M_gsm_add P((word op1, word op2));\nword M_gsm_sub P((word op1, word op2));\nword M_gsm_mult P((word op1, word op2));\nword M_gsm_mult_r P((word op1, word op2));\nword M_gsm_abs P((word op1));\nlongword M_gsm_L_mult P((word op1, word op2));\nlongword M_gsm_L_add P((longword op1, longword op2));\n\nhelp()\n{\nputs( \"  add a b      sub a b     mult a b   div    a b\" );\nputs( \"L_add A B    L_sub A B   L_mult A B   mult_r a b\" );\nputs( \"\" );\nputs( \"abs   a      norm  a        >> a b      << a b\" );\nputs( \"                          L_>> A B    L_<< A B\" );\n\n}\n\nchar * strtek P2((str, sep), char * str, char * sep) {\n\n\tstatic char     * S = (char *)0;\n\tchar\t\t* c, * base;\n\n\tif (str) S = str;\n\n\tif (!S || !*S) return (char *)0;\n\n\t/*  Skip delimiters.\n\t */\n\twhile (*S) {\n\t\tfor (c = sep; *c && *c != *S; c++) ;\n\t\tif (*c) *S++ = 0;\n\t\telse break;\n\t}\n\n\tbase = S;\n\n\t/*   Skip non-delimiters.\n\t */\n\tfor (base = S; *S; S++) {\n\n\t\tfor (c = sep; *c; c++)\n\t\t\tif (*c == *S) {\n\t\t\t\t*S++ = 0;\n\t\t\t\treturn base;\n\t\t\t}\n\t}\n\n\treturn base == S ? (char *)0 : base;\n}\n\nlong value P1((s), char * s)\n{\n\tswitch (*s) {\n\tcase '-': switch (s[1]) {\n\t\t  case '\\0': return MIN_WORD;\n\t\t  case '-':  return MIN_LONGWORD;\n\t\t  default:   break;\n\t\t  }\n\t\t  break;\n\n\tcase '+': switch (s[1]) {\n\t\t  case '\\0': return MAX_WORD;\n\t\t  case '+':  return MAX_LONGWORD;\n\t\t  default:   break;\n\t\t  }\n\tdefault:  break;\n\t}\n\n\treturn strtol(s, (char **)0, 0);\n}\n\nchar * parse P1((buf), char * buf)\n{\n\tchar  * s, * a;\n\tlong\tl;\n\n\tif (a = strchr(buf, '=')) *a++ = 0;\n\n\topname = s = strtek(buf, \" \\t(\"); \n\tif (!s) return (char *)0;\n\n\top1 = op2 = L_op1 = L_op2 = 0;\n\n\tif (s = strtek( (char *)0, \"( \\t,\")) {\n\t\top1 = L_op1 = value(s);\n\t\tif (s = strtek( (char *)0, \", \\t)\")) op2 = L_op2 = value(s);\n\t}\n\n\tif (a) {\n\t\tdo_expect = 1;\n\t\twhile (*a == ' ' || *a == '\\t') a++;\n\t\texpect = L_expect = value(a);\n\t}\n\n\treturn opname;\n}\n\nvoid fprint_word P2((f, w), FILE * f,  word w)\n{\n\tif (!w) putc('0', f);\n\telse fprintf(f, \"0x%4.4x (%d%s)\",\n\t\t(unsigned int)w,\n\t\t(int)w,\n\t\tw == MIN_WORD? \"/-\" : (w == MAX_WORD ? \"/+\" : \"\"));\n}\n\nvoid print_word P1((w), word w)\n{\n\tfprint_word( stdout, w );\n}\n\nvoid fprint_longword P2((f, w), FILE * f, longword w)\n{\n\tif (!w) putc('0', f);\n\telse fprintf(f, \"0x%8.8x (%ld%s)\",\n\t\tw, w, w == MIN_WORD ? \"/-\"\n\t\t: (w == MAX_WORD ? \"/+\"\n\t\t: (w == MIN_LONGWORD ? \"/--\" \n\t\t: (w == MAX_LONGWORD ? \"/++\" : \"\"))));\n}\n\nvoid print_longword P1((w),longword w)\n{\n\tfprint_longword(stdout, w);\n}\n\nvoid do_longword P1((w), longword w)\n{\n\tif (interactive) print_longword(w);\n\tif (do_expect) {\n\t\tif (w != L_expect) {\n\t\t\tif (!interactive) fprint_longword(stderr, w);\n\t\t\tfprintf(stderr, \" != %s (%ld, %ld) -- expected \",\n\t\t\t\topname, L_op1, L_op2 );\n\t\t\tfprint_longword(stderr, L_expect);\n\t\t\tputc( '\\n', stderr );\n\t\t}\n\t} else if (interactive) putchar('\\n');\n}\n\nvoid do_word P1((w), word w )\n{\n\tif (interactive) print_word(w);\n\tif (do_expect) {\n\t\tif (w != expect) {\n\t\t\tif (!interactive) fprint_word(stderr, w);\n\t\t\tfprintf(stderr, \" != %s (%ld, %ld) -- expected \",\n\t\t\t\topname, L_op1, L_op2 );\n\t\t\tfprint_word(stderr, expect);\n\t\t\tputc('\\n', stderr);\n\t\t}\n\t} else if (interactive) putchar('\\n');\n}\n\nint main(ac, av) char ** av;\n{\n\tchar\tbuf[299];\n\tchar\t* c;\n\tFILE \t* in;\n\n\tif (ac > 2) {\n\t\tfprintf(stderr, \"Usage: %s [filename]\\n\", av[0]);\nfail:\n#ifdef EXIT_FAILURE\n\t\texit(EXIT_FAILURE);\n#else\n\t\texit(1);\n#endif\n\t}\n\tif (ac < 2) in = stdin;\n\telse if (!(in = fopen(av[1], \"r\"))) {\n\t\tperror(av[1]);\n\t\tfprintf(stderr, \"%s: cannot open file \\\"%s\\\" for reading\\n\",\n\t\t\tav[0], av[1]);\n\t\tgoto fail;\n\t}\n\n\tinteractive = isatty(fileno(in));\n\n\tfor (;;) {\n\t\tif (interactive) fprintf(stderr, \"? \");\n\n\t\tif (!fgets(buf, sizeof(buf), in)) exit(0);\n\t\tif (c = strchr(buf, '\\n')) *c = 0;\n\n\t\tif (*buf == ';' || *buf == '#') continue;\n\t\tif (*buf == '\\'') {\n\t\t\tputs(buf + 1);\n\t\t\tcontinue;\n\t\t}\n\t\tif (*buf == '\\\"') {\n\t\t\tfprintf(stderr,  \"%s\\n\", buf + 1);\n\t\t\tcontinue;\n\t\t}\n\n\t\tc = parse(buf);\n\n\t\tif (!c) continue;\n\t\tif (!strcmp(c,   \"add\")) {\n\t\t\tdo_word(    gsm_add( op1, op2 ));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!strcmp(c,   \"M_add\")) {\n\t\t\tdo_word(    M_gsm_add( op1, op2 ));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!strcmp(c, \"sub\")) {\n\t\t\tdo_word(    gsm_sub( op1, op2 ));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!strcmp(c, \"M_sub\")) {\n\t\t\tdo_word(    M_gsm_sub( op1, op2 ));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!strcmp(c, \"mult\")) {\n\t\t\tdo_word(    gsm_mult( op1, op2 ));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!strcmp(c, \"M_mult\")) {\n\t\t\tdo_word(    M_gsm_mult( op1, op2 ));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!strcmp(c, \"mult_r\")) {\n\t\t\tdo_word(    gsm_mult_r(op1, op2));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!strcmp(c, \"M_mult_r\")) {\n\t\t\tdo_word(    M_gsm_mult_r(op1, op2));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!strcmp(c, \"abs\" )) {\n\t\t\tdo_word(    gsm_abs(op1) );\n\t\t\tcontinue;\n\t\t} \n\t\tif (!strcmp(c, \"M_abs\" )) {\n\t\t\tdo_word(    M_gsm_abs(op1) );\n\t\t\tcontinue;\n\t\t} \n\t\tif (!strcmp(c, \"div\" )) {\n\t\t\tdo_word(    gsm_div( op1, op2 ));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!strcmp(c,  \"norm\" )) {\n\t\t\tdo_word(\tgsm_norm(L_op1));\n\t\t\tcontinue;\n\t\t} \n\t\tif (!strcmp(c,  \"<<\" )) {\n\t\t\tdo_word(    gsm_asl( op1, op2));\n\t\t\tcontinue;\n\t\t} \n\t\tif (!strcmp(c,  \">>\" )) {\n\t\t\tdo_word(    gsm_asr( op1, op2 ));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!strcmp(c,  \"L_mult\")) {\n\t\t\tdo_longword( gsm_L_mult( op1, op2 ));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!strcmp(c,  \"M_L_mult\")) {\n\t\t\tdo_longword( M_gsm_L_mult( op1, op2 ));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!strcmp(c,  \"L_add\" )) {\n\t\t\tdo_longword( gsm_L_add( L_op1, L_op2 ));\n\t\t\tcontinue;\n\t\t} \n\t\tif (!strcmp(c,  \"M_L_add\" )) {\n\t\t\tdo_longword( M_gsm_L_add( L_op1, L_op2 ));\n\t\t\tcontinue;\n\t\t} \n\t\tif (!strcmp(c,  \"L_sub\" )) {\n\t\t\tdo_longword( gsm_L_sub( L_op1, L_op2 ));\n\t\t\tcontinue;\n\t\t} \n\t\tif (!strcmp(c,  \"L_<<\" )) {\n\t\t\tdo_longword(    gsm_L_asl( L_op1, L_op2 ));\n\t\t\tcontinue;\n\t\t} \n\t\tif (!strcmp(c,  \"L_>>\")) {\n\t\t\tdo_longword(    gsm_L_asr( L_op1, L_op2 ));\n\t\t\tcontinue;\n\t\t}\n\t\thelp();\n\t}\n}\n\n#include \"private.h\"\n\n/*\n * Function stubs for macro implementations of commonly used\n * math functions\n */\nword M_gsm_add P2((op1, op2),word op1, word op2)\n{\n\tlongword ltmp;\n\treturn GSM_ADD(op1, op2);\n}\n\nword M_gsm_sub P2((op1, op2), word op1, word op2)\n{\n\tlongword ltmp;\n\treturn GSM_SUB(op1, op2);\n}\n\nword M_gsm_mult P2((op1, op2), word op1, word op2)\n{\n\treturn GSM_MULT(op1, op2);\n}\n\nword M_gsm_mult_r P2((op1, op2), word op1, word op2)\n{\n\treturn GSM_MULT_R(op1, op2);\n}\n\nword M_gsm_abs P1((op1), word op1)\n{\n\treturn GSM_ABS(op1);\n}\n\nlongword M_gsm_L_mult P2((op1, op2), word op1, word op2)\n{\n\treturn GSM_L_MULT(op1, op2);\n}\n\nlongword M_gsm_L_add P2((op1, op2), longword op1, longword op2)\n{\n\tulongword utmp;\n\treturn GSM_L_ADD(op1, op2);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/add-test/add_test.dta",
    "content": ";\n; Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n; Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n; details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n;\n;\n;\tLines starting with ' (in the first col) are echoed.\n;\tLines starting with \" (in the first col) are echoed to stderr.\n;\tLines starting with ; or empty lines are ignored.\n;\n;\tThe part after (including) a trailing '=' is what you expect;\n;\tthere will be output if the result is different.\n;\n;\t-  and +  by itself mean MIN_WORD and MAX_WORD, respectively;\n;\t-- and ++ mean MIN_LONGWORD and MAX_LONGWORD.\n;\n\n'test the basic arithmetic operations used for the rpe-ltd filtering.\n'\n'add ================\n'  basic\n\n\tadd  0  0 \t=  0\n\tadd  7  4\t= 11\n\tadd  4  6 \t= 10\n\tadd  1  1 \t=  2\n\n'  negative operands\n\n\tadd  -7  4\t= -3\n\tadd   4 -6 \t= -2\n\tadd  -1 -3 \t= -4\n\tadd   7 -4\t=  3\n\tadd  -4  6 \t=  2\n\n'  positive overflow\n; (max-word = 32767)\n\tadd  + 1\t= +\n\tadd  + +\t= +\n\tadd  -1 + \t= 32766\n\tadd  32766 2\t= +\n\tadd  1 32766  \t= +\n\n'  underflow\n; (min-word = 32768)\n\n\tadd  - -1\t= -\n\tadd  - -\t= -\n\tadd  1 -\t= -32767  \n\tadd  -32767 -2\t= -\n\tadd  -1 -32766 \t= -32767\n\tadd  -32767 -1\t= -\n\tadd  - +\t= -1\n\tadd  + -\t= -1\n\tadd  0 -\t= -\n\tadd  0 +\t= +\n'\n\n'L_add ================\n'  basic \n\n\tL_add  0  0 \t=  0\n\tL_add  7  4\t= 11\n\tL_add  4  6 \t= 10\n\tL_add  1  1 \t=  2\n\n'  negative operands\n\n\tL_add  -7  4\t= -3\n\tL_add   4 -6 \t= -2\n\tL_add  -1 -3 \t= -4\n\tL_add   7 -4\t=  3\n\tL_add  -4  6 \t=  2\n\tL_add   0 -1 \t= -1\n\n'  positive overflow\n; (max-longword = 2147483647)\n\tL_add  ++ 1\t= ++\n\tL_add  ++ ++\t= ++\n\tL_add  -1 ++ \t= 2147483646\n\tL_add  2147483646 2 = ++\n\tL_add  1 2147483645 = 2147483646\n\n'  underflow\n; (min-longword = -2147483648)\n\n\tL_add  -- -1\t= --\n\tL_add  -- --\t= --\n\tL_add  1 --\t= -2147483647\n\tL_add  -2147483647 -2\t= --\n\tL_add  -1 -2147483646 \t= -2147483647\n\tL_add  -2147483647 -1\t= --\n\tL_add  -- ++\t= -1\n\tL_add  ++ --\t= -1\n\tL_add  0 --\t= --\n\tL_add  0 ++\t= ++\n'\n\n'sub ================\n'  basic \n\n\tsub  0  0 \t=  0\n\tsub  7  4\t=  3\n\tsub  4  6 \t= -2\n\tsub  1  0 \t=  1\n\n'  negative operands\n\n\tsub  -7  4\t= -11\n\tsub   4 -6 \t=  10\n\tsub  -1 -3 \t=  2\n\tsub   7 -4\t=  11\n\tsub  -4  6 \t= -10\n\n'  positive overflow\n; (max-word = 32767)\n\tsub  1 -\t= +\n\tsub  + +\t= 0\n\tsub  + 0\t= +\n\tsub  + -1 \t= +\n\tsub  + 1 \t= 32766\n\tsub  1 + \t= -32766 \n\tsub  0 +  \t= -32767\n\n'  underflow\n; (min-word = 32768)\n\n\tsub  - -1\t= -32767\n\tsub  - 1\t= -\n\tsub  - -\t= 0\n\tsub  - +\t= -\n\tsub  + -\t= +\n\tsub  1 -\t= +\n\tsub  -1 -\t= +\n\tsub  -32767 2\t= -\n\tsub  0 -\t= +\n' \n\n'L_sub ================\n'  basic \n\n\tL_sub  0  0 \t=  0\n\tL_sub  7  4\t=  3\n\tL_sub  4  6 \t= -2\n\tL_sub  1  0 \t=  1\n\n'  negative operands\n\n\tL_sub  -7  4\t= -11\n\tL_sub   4 -6 \t=  10\n\tL_sub  -1 -3 \t=  2\n\tL_sub   7 -4\t=  11\n\tL_sub  -4  6 \t= -10\n\n'  positive overflow\n\tL_sub  1 --\t= ++\n\tL_sub  ++ ++\t= 0\n\tL_sub  ++ 0\t= ++\n\tL_sub  ++ -1 \t= ++\n\tL_sub  ++ 1 \t=  2147483646\n\tL_sub  1 ++ \t= -2147483646\n\tL_sub  0 ++  \t= -2147483647\n\n'  underflow\n\n\tL_sub  -- -1\t= -2147483647\n\tL_sub  -- 1\t= --\n\tL_sub  -- --\t= 0\n\tL_sub  -- ++\t= --\n\tL_sub  + --\t= ++\n\tL_sub  1 --\t= ++\n\tL_sub  -1 --\t= ++\n\tL_sub  -2147483647 2 = --\n\tL_sub  0 --\t= ++\n\n'\n'abs ================\n'  basic \n\n\tabs\t   0\t=   0\n\tabs\t   2\t=   2\n\tabs\t-459\t= 459\n\n'  overflow\n\n\tabs\t +\t=   +\n\tabs\t -\t=   +\n\tabs \t-32767  =   +\n\tabs \t 32766  = 32766\n\tabs \t-32766  = 32766\n\n'\n'mult ================\n;  actually, a * b >> 15\n\n'  basic \n\tmult\t0  0\t\t= 0\n\tmult\t0x100 0x100\t= 2\n\tmult\t4711 0x4000\t= 2355\n\n'  negative operands\n\tmult\t-1  0\t\t=  0\n\n\tmult\t-0x100   0x100\t= -2\n\tmult\t 0x100  -0x100\t= -2\n\tmult\t-0x100  -0x100\t=  2\n\n\tmult\t-4711   0x4000\t= -2356\n\tmult\t 4711  -0x4000\t= -2356\n\tmult\t-4711  -0x4000\t=  2355\n\n'  overflow\n\tmult\t+ + \t = 32766\n\tmult\t+ 0x4000 = 0x3fff\n\tmult\t0x4000 + = 0x3fff\n\tmult\t+ 1\t = 0\n\tmult\t+ 2\t = 1\n\tmult\t+ 3\t = 2\n\n'  underflow\n\tmult\t- - \t = +\n\tmult\t- + \t = -32767\n\tmult\t+ - \t = -32767\n\tmult\t- 1\t = -1\n\tmult\t- 2\t = -2\n\tmult\t- 3\t = -3\n\n'\n'mult_r ================\n;  actually, (a * b + 16384) >> 15\n\n'  basic \n\tmult_r\t0  0\t\t= 0\n\tmult_r\t0x100 0x100\t= 2\n\tmult_r\t4711 0x4000\t= 2356\n\n'  negative operands\n\tmult_r\t-1  0\t\t=  0\n\n\tmult_r\t-0x100   0x100\t= -2\n\tmult_r\t 0x100  -0x100\t= -2\n\tmult_r\t-0x100  -0x100\t=  2\n\n\tmult_r\t-4711   0x4000\t= -2355\n\tmult_r\t 4711  -0x4000\t= -2355\n\tmult_r\t-4711  -0x4000\t=  2356\n\n'  overflow\n\tmult_r\t+ + \t = 32766\n\tmult_r\t+ 32766\t = 32765\n\tmult_r\t32766 +\t = 32765\n\tmult_r\t+ 0x4000 = 0x4000\n\tmult_r\t0x4000 + = 0x4000\n\tmult_r\t+ 0x4001 = 0x4000\n\tmult_r\t0x4001 + = 0x4000\n\tmult_r\t+ 2\t = 2\n\tmult_r\t+ 1\t = 1\n\tmult_r\t1 +\t = 1\n\tmult_r\t+ 0\t = 0\n\tmult_r\t0 +\t = 0\n\n'  underflow\n\tmult_r\t- - \t = +\n\tmult_r\t- + \t = -32767\n\tmult_r\t+ - \t = -32767\n\tmult_r\t- 1\t = -1\n\tmult_r\t- 2\t = -2\n\tmult_r\t- 3\t = -3\n\n'\n'L_mult ================\n;  actually, (a * b) << 1\n;  assert (a != MIN_WORD && b != MIN_WORD)\n\n'  basic \n\tL_mult\t0  0\t= 0\n\tL_mult\t2  3\t= 12\n\tL_mult\t4711 5\t= 47110\n\n'  negative operands\n\n\tL_mult\t-2  3\t= -12\n\tL_mult\t 2 -3\t= -12\n\tL_mult\t-2 -3\t=  12\n\tL_mult -4711  5\t= -47110\n\tL_mult\t4711 -5\t= -47110\n\tL_mult -4711 -5\t=  47110\n\n'  overflow\n\tL_mult\t+ + \t = 2147352578\n\tL_mult\t+ -32767 = -2147352578\n\tL_mult\t-32767 + = -2147352578\n\tL_mult\t+ 2\t = 131068\n\tL_mult\t+ 1\t = 65534\n\tL_mult\t1 +\t = 65534\n\tL_mult\t+ 0\t = 0\n\tL_mult\t0 +\t = 0\n\n'\n'div ================\n;  actually, (32767 * a) / b\n;  assert (a > 0 && b >= a)\n\n'  basic \n\tdiv\t1 1\t\t= +\n\tdiv\t4711 4711 \t= +\n\tdiv\t5 10\t\t= 0x4000\n\tdiv\t5 20\t\t= 0x2000\n\tdiv\t5 40\t\t= 0x1000\n\n'  overflow\n\tdiv\t+ + \t\t= +\n\tdiv\t0x4000 +\t= 0x4000\n\tdiv\t1 +\t\t= 1\n\tdiv\t1 2\t\t= 0x4000\n'\n'norm ================\n\n'  positive\n\tnorm\t1\t\t= 30\n\tnorm\t2\t\t= 29\n\tnorm\t3\t\t= 29\n\tnorm\t4\t\t= 28\n\tnorm\t5\t\t= 28\n; etc, etc...\n\tnorm\t0x08000000\t= 3\n\tnorm\t0x10000000\t= 2\n\tnorm\t0x20000000\t= 1\n\tnorm\t0x20000001\t= 1\n\tnorm\t0x3fffffff\t= 1\n\tnorm\t0x40000000\t= 0\n\tnorm\t0x40000001\t= 0\n\tnorm\t0x4ffffffe\t= 0\n\tnorm\t++\t\t= 0\n\n'  negative\n\tnorm\t-1\t\t= 31\n\tnorm\t-2\t\t= 30\n\tnorm\t-3\t\t= 29\n\tnorm\t-4\t\t= 29\n\tnorm\t-5\t\t= 28\n; etc, etc...\n\tnorm\t0x4fffffff\t= 0\n\tnorm\t--\t\t= 0\n'\n'>> ================\n\n'  basic \n\t>>\t1 1\t\t= 0\n\t>>\t4 2\t\t= 1\n\t>>\t0x1100 5\t= 0x88\n\n'  negative operand\n\n\t>>\t1 -1\t\t= 2\n\t>>\t1 -2\t\t= 4\n\t>>\t0x88 -5\t\t= 0x1100\n\n'  overflow\n\t>>\t-1 4711\t\t= -1\n\t>>\t1  4711\t\t= 0\n\t>>\t-4711 4711 \t= -1\n\t>>\t4711 4711 \t= 0\n\t>>\t+ 1\t\t=  16383\n\t>>\t- 1\t\t= -16384\n'\n'L_>> ================\n\n'  basic \n\tL_>>\t1 1\t\t= 0\n\tL_>>\t4 2\t\t= 1\n\tL_>>\t0x1100 5\t= 0x88\n\n'  negative operand\n\n\tL_>>\t1 -1\t\t= 2\n\tL_>>\t1 -2\t\t= 4\n\tL_>>\t0x88 -5\t\t= 0x1100\n\n'  overflow\n\tL_>>\t-1 4711\t\t= -1\n\tL_>>\t1  4711\t\t= 0\n\tL_>>\t-4711 4711 \t= -1\n\tL_>>\t4711 4711 \t= 0\n\tL_>>\t++ 1\t\t=  1073741823\n\tL_>>\t-- 1\t\t= -1073741824\n\n'\n'<< ================\n\n'  basic \n\t<<\t1 1\t\t= 2\n\t<<\t4 2\t\t= 16\n\t<<\t0x0088 5\t= 0x1100\n\n'  negative operand\n\n\t<<\t1 -1\t\t= 0\n\t<<\t4 -2\t\t= 1\n\t<<\t0x1100 -5\t= 0x0088\n\n'  overflow\n\t<<\t-1 4711\t\t= 0\n\t<<\t1  4711\t\t= 0\n\t<<\t-4711 4711 \t= 0\n\t<<\t4711 4711 \t= 0\n\t<<\t4711 -4711 \t= 0\n\t<<\t-4711 -4711 \t= -1\n\t<<\t+ 1\t\t= 0xfffe\n\t<<\t-1 1\t\t= 0xfffe\n\t<<\t- 1\t\t= 0\n'\n'L_<< ================\n\n'  basic \n\tL_<<\t1 1\t\t= 2\n\tL_<<\t4 2\t\t= 16\n\tL_<<\t0x0088 5\t= 0x1100\n\n'  negative operand\n\n\tL_<<\t1 -1\t\t= 0\n\tL_<<\t4 -2\t\t= 1\n\tL_<<\t0x1100 -5\t= 0x0088\n\n'  overflow\n\tL_<<\t-1 4711\t\t= 0\n\tL_<<\t1  4711\t\t= 0\n\tL_<<\t-4711 4711 \t= 0\n\tL_<<\t4711 4711 \t= 0\n\tL_<<\t4711 -4711 \t= 0\n\tL_<<\t-4711 -4711 \t= -1\n\tL_<<\t++ 1\t\t= -2\n\tL_<<\t-1 1\t\t= -2\n\tL_<<\t-- 1\t\t= 0\n\n'macros\n'\n'add ================\n'  basic\n\n\tM_add  0  0 \t=  0\n\tM_add  7  4\t= 11\n\tM_add  4  6 \t= 10\n\tM_add  1  1 \t=  2\n\n'  negative operands\n\n\tM_add  -7  4\t= -3\n\tM_add   4 -6 \t= -2\n\tM_add  -1 -3 \t= -4\n\tM_add   7 -4\t=  3\n\tM_add  -4  6 \t=  2\n\n'  positive overflow\n; (max-word = 32767)\n\tM_add  + 1\t= +\n\tM_add  + +\t= +\n\tM_add  -1 + \t= 32766\n\tM_add  32766 2\t= +\n\tM_add  1 32766  \t= +\n\n'  underflow\n; (min-word = 32768)\n\n\tM_add  - -1\t= -\n\tM_add  - -\t= -\n\tM_add  1 -\t= -32767  \n\tM_add  -32767 -2 = -\n\tM_add  -1 -32766 = -32767\n\tM_add  -32767 -1 = -\n\tM_add  - +\t= -1\n\tM_add  + -\t= -1\n\tM_add  0 -\t= -\n\tM_add  0 +\t= +\n'\n\n'L_add ================\n'  basic \n\n\tM_L_add  0  0 \t=  0\n\tM_L_add  7  4\t= 11\n\tM_L_add  4  6 \t= 10\n\tM_L_add  1  1 \t=  2\n\n'  negative operands\n\n\tM_L_add  -7  4\t= -3\n\tM_L_add   4 -6 \t= -2\n\tM_L_add  -1 -3 \t= -4\n\tM_L_add   7 -4\t=  3\n\tM_L_add  -4  6 \t=  2\n\tM_L_add   0 -1 \t= -1\n\n'  positive overflow\n; (max-longword = 2147483647)\n\tM_L_add  ++ 1\t= ++\n\tM_L_add  ++ ++\t= ++\n\tM_L_add  -1 ++ \t= 2147483646\n\tM_L_add  2147483646 2 = ++\n\tM_L_add  1 2147483645 = 2147483646\n\n'  underflow\n; (min-longword = -2147483648)\n\n\tM_L_add  -- -1\t= --\n\tM_L_add  -- --\t= --\n\tM_L_add  1 --\t= -2147483647\n\tM_L_add  -2147483647 -2\t= --\n\tM_L_add  -1 -2147483646 \t= -2147483647\n\tM_L_add  -2147483647 -1\t= --\n\tM_L_add  -- ++\t= -1\n\tM_L_add  ++ --\t= -1\n\tM_L_add  0 --\t= --\n\tM_L_add  0 ++\t= ++\n'\n\n'sub ================\n'  basic \n\n\tM_sub  0  0 \t=  0\n\tM_sub  7  4\t=  3\n\tM_sub  4  6 \t= -2\n\tM_sub  1  0 \t=  1\n\n'  negative operands\n\n\tM_sub  -7  4\t= -11\n\tM_sub   4 -6 \t=  10\n\tM_sub  -1 -3 \t=  2\n\tM_sub   7 -4\t=  11\n\tM_sub  -4  6 \t= -10\n\n'  positive overflow\n; (max-word = 32767)\n\tM_sub  1 -\t= +\n\tM_sub  + +\t= 0\n\tM_sub  + 0\t= +\n\tM_sub  + -1 \t= +\n\tM_sub  + 1 \t= 32766\n\tM_sub  1 + \t= -32766 \n\tM_sub  0 +  \t= -32767\n\n'  underflow\n; (min-word = 32768)\n\n\tM_sub  - -1\t= -32767\n\tM_sub  - 1\t= -\n\tM_sub  - -\t= 0\n\tM_sub  - +\t= -\n\tM_sub  + -\t= +\n\tM_sub  1 -\t= +\n\tM_sub  -1 -\t= +\n\tM_sub  -32767 2\t= -\n\tM_sub  0 -\t= +\n' \n'\n'abs ================\n'  basic \n\n\tM_abs\t   0\t=   0\n\tM_abs\t   2\t=   2\n\tM_abs\t-459\t= 459\n\n'  overflow\n\n\tM_abs\t +\t=   +\n\tM_abs\t -\t=   +\n\tM_abs \t-32767  =   +\n\tM_abs \t 32766  = 32766\n\tM_abs \t-32766  = 32766\n\n'\n'mult ================\n;  actually, a * b >> 15\n\n'  basic \n\tM_mult\t0  0\t\t= 0\n\tM_mult\t0x100 0x100\t= 2\n\tM_mult\t4711 0x4000\t= 2355\n\n'  negative operands\n\tM_mult\t-1  0\t\t=  0\n\n\tM_mult\t-0x100   0x100\t= -2\n\tM_mult\t 0x100  -0x100\t= -2\n\tM_mult\t-0x100  -0x100\t=  2\n\n\tM_mult\t-4711   0x4000\t= -2356\n\tM_mult\t 4711  -0x4000\t= -2356\n\tM_mult\t-4711  -0x4000\t=  2355\n\n'  overflow\n\tM_mult\t+ + \t = 32766\n\tM_mult\t+ 0x4000 = 0x3fff\n\tM_mult\t0x4000 + = 0x3fff\n\tM_mult\t+ 1\t = 0\n\tM_mult\t+ 2\t = 1\n\tM_mult\t+ 3\t = 2\n\n'  underflow\n;\tM_mult - - \t= +\t\t\tassert !(a == b && b == MIN_WORD)\n \tM_mult - -32767\t= +\n \tM_mult -32767 -\t= +\n\tM_mult\t- + \t= -32767\n\tM_mult\t+ - \t= -32767\n\tM_mult\t- 1\t= -1\n\tM_mult\t- 2\t= -2\n\tM_mult\t- 3\t= -3\n\n'\n'mult_r ================\n;  actually, (a * b + 16384) >> 15\n\n'  basic \n\tM_mult_r 0  0\t\t= 0\n\tM_mult_r 0x100 0x100\t= 2\n\tM_mult_r 4711 0x4000\t= 2356\n\n'  negative operands\n\tM_mult_r -1  0\t\t=  0\n\n\tM_mult_r -0x100   0x100\t= -2\n\tM_mult_r  0x100  -0x100\t= -2\n\tM_mult_r -0x100  -0x100\t=  2\n\n\tM_mult_r -4711   0x4000\t= -2355\n\tM_mult_r  4711  -0x4000\t= -2355\n\tM_mult_r -4711  -0x4000\t=  2356\n\n'  overflow\n\tM_mult_r + + \t = 32766\n\tM_mult_r + 32766  = 32765\n\tM_mult_r 32766 +  = 32765\n\tM_mult_r + 0x4000 = 0x4000\n\tM_mult_r 0x4000 + = 0x4000\n\tM_mult_r + 0x4001 = 0x4000\n\tM_mult_r 0x4001 + = 0x4000\n\tM_mult_r + 2\t = 2\n\tM_mult_r + 1\t = 1\n\tM_mult_r 1 +\t = 1\n\tM_mult_r + 0\t = 0\n\tM_mult_r 0 +\t = 0\n\n'  underflow\n;\tM_mult_r - - \t = +\t\t\tassert !(a == b && b == MIN_WORD)\n \tM_mult_r - -32767 = +\n \tM_mult_r -32767 - = +\n\tM_mult_r - + \t = -32767\n\tM_mult_r + - \t = -32767\n\tM_mult_r - 1\t = -1\n\tM_mult_r - 2\t = -2\n\tM_mult_r - 3\t = -3\n\n'\n'L_mult ================\n;  actually, (a * b) << 1\n;  assert (a != MIN_WORD && b != MIN_WORD)\n\n'  basic \n\tM_L_mult\t0  0\t= 0\n\tM_L_mult\t2  3\t= 12\n\tM_L_mult\t4711 5\t= 47110\n\n'  negative operands\n\n\tM_L_mult\t-2  3\t= -12\n\tM_L_mult\t 2 -3\t= -12\n\tM_L_mult\t-2 -3\t=  12\n\tM_L_mult -4711  5\t= -47110\n\tM_L_mult\t4711 -5\t= -47110\n\tM_L_mult -4711 -5\t=  47110\n\n'  overflow\n \tM_L_mult\t+ + \t = 2147352578\n\tM_L_mult\t+ -32767 = -2147352578\n\tM_L_mult\t-32767 + = -2147352578\n\tM_L_mult\t+ 2\t = 131068\n\tM_L_mult\t+ 1\t = 65534\n\tM_L_mult\t1 +\t = 65534\n\tM_L_mult\t+ 0\t = 0\n\tM_L_mult\t0 +\t = 0\n\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/inc/config.h",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/config.h,v 1.5 1996/07/02 11:26:20 jutta Exp $*/\n\n#ifndef\tCONFIG_H\n#define\tCONFIG_H\n\n/*efine\tSIGHANDLER_T\tint \t\t* signal handlers are void\t*/\n/*efine HAS_SYSV_SIGNAL\t1\t\t* sigs not blocked/reset?\t*/\n\n#define\tHAS_STDLIB_H\t1\t\t/* /usr/include/stdlib.h\t*/\n#define\tHAS_LIMITS_H\t1\t\t/* /usr/include/limits.h\t*/\n#define\tHAS_FCNTL_H\t1\t\t/* /usr/include/fcntl.h\t\t*/\n#define\tHAS_ERRNO_DECL\t1\t\t/* errno.h declares errno\t*/\n\n#define\tHAS_FSTAT \t1\t\t/* fstat syscall\t\t*/\n#define\tHAS_FCHMOD \t1\t\t/* fchmod syscall\t\t*/\n#define\tHAS_CHMOD \t1\t\t/* chmod syscall\t\t*/\n#define\tHAS_FCHOWN \t1\t\t/* fchown syscall\t\t*/\n#define\tHAS_CHOWN \t1\t\t/* chown syscall\t\t*/\n/*efine\tHAS__FSETMODE \t1\t\t* _fsetmode -- set file mode\t*/\n\n#define\tHAS_STRING_H \t1\t\t/* /usr/include/string.h \t*/\n/*efine\tHAS_STRINGS_H\t1\t\t* /usr/include/strings.h \t*/\n\n#define\tHAS_UNISTD_H\t1\t\t/* /usr/include/unistd.h\t*/\n#define\tHAS_UTIME\t1\t\t/* POSIX utime(path, times)\t*/\n/*efine\tHAS_UTIMES\t1\t\t* use utimes()\tsyscall instead\t*/\n#define\tHAS_UTIME_H\t1\t\t/* UTIME header file\t\t*/\n#define\tHAS_UTIMBUF\t1\t\t/* struct utimbuf\t\t*/\n/*efine\tHAS_UTIMEUSEC   1\t\t* microseconds in utimbuf?\t*/\n\n#endif\t/* CONFIG_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/inc/gsm.h",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header: /home/kbs/jutta/src/gsm/gsm-1.0/inc/RCS/gsm.h,v 1.11 1996/07/05 18:02:56 jutta Exp $*/\n\n#ifndef\tGSM_H\n#define\tGSM_H\n\n#ifdef __cplusplus\n#\tdefine\tNeedFunctionPrototypes\t1\n#endif\n\n#if __STDC__\n#\tdefine\tNeedFunctionPrototypes\t1\n#endif\n\n#ifdef _NO_PROTO\n#\tundef\tNeedFunctionPrototypes\n#endif\n\n#ifdef NeedFunctionPrototypes\n#   include\t<stdio.h>\t\t/* for FILE * \t*/\n#endif\n\n#undef GSM_P\n#if NeedFunctionPrototypes\n#\tdefine\tGSM_P( protos )\tprotos\n#else\n#\tdefine  GSM_P( protos )\t( /* protos */ )\n#endif\n\n/*\n *\tInterface\n */\n\ntypedef struct gsm_state * \tgsm;\ntypedef short\t\t   \tgsm_signal;\t\t/* signed 16 bit */\ntypedef unsigned char\t\tgsm_byte;\ntypedef gsm_byte \t\tgsm_frame[33];\t\t/* 33 * 8 bits\t */\n\n#define\tGSM_MAGIC\t\t0xD\t\t  \t/* 13 kbit/s RPE-LTP */\n\n#define\tGSM_PATCHLEVEL\t\t10\n#define\tGSM_MINOR\t\t0\n#define\tGSM_MAJOR\t\t1\n\n#define\tGSM_OPT_VERBOSE\t\t1\n#define\tGSM_OPT_FAST\t\t2\n#define\tGSM_OPT_LTP_CUT\t\t3\n#define\tGSM_OPT_WAV49\t\t4\n#define\tGSM_OPT_FRAME_INDEX\t5\n#define\tGSM_OPT_FRAME_CHAIN\t6\n\nextern gsm  gsm_create \tGSM_P((void));\nextern void gsm_destroy GSM_P((gsm));\t\n\nextern int  gsm_print   GSM_P((FILE *, gsm, gsm_byte  *));\nextern int  gsm_option  GSM_P((gsm, int, int *));\n\nextern void gsm_encode  GSM_P((gsm, gsm_signal *, gsm_byte  *));\nextern int  gsm_decode  GSM_P((gsm, gsm_byte   *, gsm_signal *));\n\nextern int  gsm_explode GSM_P((gsm, gsm_byte   *, gsm_signal *));\nextern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte   *));\n\n#undef\tGSM_P\n\n#endif\t/* GSM_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/inc/private.h",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/private.h,v 1.6 1996/07/02 10:15:26 jutta Exp $*/\n\n#ifndef\tPRIVATE_H\n#define\tPRIVATE_H\n\ntypedef short\t\t\tword;\t\t/* 16 bit signed int\t*/\ntypedef long\t\t\tlongword;\t/* 32 bit signed int\t*/\n\ntypedef unsigned short\t\tuword;\t\t/* unsigned word\t*/\ntypedef unsigned long\t\tulongword;\t/* unsigned longword\t*/\n\nstruct gsm_state {\n\n\tword\t\tdp0[ 280 ];\n\tword\t\te[ 50 ];\t/* code.c \t\t\t*/\n\n\tword\t\tz1;\t\t/* preprocessing.c, Offset_com. */\n\tlongword\tL_z2;\t\t/*                  Offset_com. */\n\tint\t\tmp;\t\t/*                  Preemphasis\t*/\n\n\tword\t\tu[8];\t\t/* short_term_aly_filter.c\t*/\n\tword\t\tLARpp[2][8]; \t/*                              */\n\tword\t\tj;\t\t/*                              */\n\n\tword            ltp_cut;        /* long_term.c, LTP crosscorr.  */\n\tword\t\tnrp; /* 40 */\t/* long_term.c, synthesis\t*/\n\tword\t\tv[9];\t\t/* short_term.c, synthesis\t*/\n\tword\t\tmsr;\t\t/* decoder.c,\tPostprocessing\t*/\n\n\tchar\t\tverbose;\t/* only used if !NDEBUG\t\t*/\n\tchar\t\tfast;\t\t/* only used if FAST\t\t*/\n\n\tchar\t\twav_fmt;\t/* only used if WAV49 defined\t*/\n\tunsigned char\tframe_index;\t/*            odd/even chaining\t*/\n\tunsigned char\tframe_chain;\t/*   half-byte to carry forward\t*/\n};\n\n\n#define\tMIN_WORD\t(-32767 - 1)\n#define\tMAX_WORD\t  32767\n\n#define\tMIN_LONGWORD\t(-2147483647 - 1)\n#define\tMAX_LONGWORD\t  2147483647\n\n#ifdef\tSASR\t\t/* flag: >> is a signed arithmetic shift right */\n#undef\tSASR\n#define\tSASR(x, by)\t((x) >> (by))\n#else\n#define\tSASR(x, by)\t((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by))))\n#endif\t/* SASR */\n\n#include \"proto.h\"\n\n/*\n *\tPrototypes from add.c\n */\nextern word\tgsm_mult \tP((word a, word b));\nextern longword gsm_L_mult \tP((word a, word b));\nextern word\tgsm_mult_r\tP((word a, word b));\n\nextern word\tgsm_div  \tP((word num, word denum));\n\nextern word\tgsm_add \tP(( word a, word b ));\nextern longword gsm_L_add \tP(( longword a, longword b ));\n\nextern word\tgsm_sub \tP((word a, word b));\nextern longword gsm_L_sub \tP((longword a, longword b));\n\nextern word\tgsm_abs \tP((word a));\n\nextern word\tgsm_norm \tP(( longword a ));\n\nextern longword gsm_L_asl  \tP((longword a, int n));\nextern word\tgsm_asl \tP((word a, int n));\n\nextern longword gsm_L_asr  \tP((longword a, int n));\nextern word\tgsm_asr  \tP((word a, int n));\n\n/*\n *  Inlined functions from add.h \n */\n\n/* \n * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *)\t\\\n *\t(0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15))\n */\n#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */\t\\\n\t(SASR( ((longword)(a) * (longword)(b) + 16384), 15 ))\n\n# define GSM_MULT(a,b)\t /* word a, word b, !(a == b == MIN_WORD) */\t\\\n\t(SASR( ((longword)(a) * (longword)(b)), 15 ))\n\n# define GSM_L_MULT(a, b) /* word a, word b */\t\\\n\t(((longword)(a) * (longword)(b)) << 1)\n\n# define GSM_L_ADD(a, b)\t\\\n\t( (a) <  0 ? ( (b) >= 0 ? (a) + (b)\t\\\n\t\t : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \\\n\t\t   >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 )   \\\n\t: ((b) <= 0 ? (a) + (b)   \\\n\t          : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \\\n\t\t    ? MAX_LONGWORD : utmp))\n\n/*\n * # define GSM_ADD(a, b)\t\\\n * \t((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \\\n * \t? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)\n */\n/* Nonportable, but faster: */\n\n#define\tGSM_ADD(a, b)\t\\\n\t((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \\\n\t\tMAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp)\n\n# define GSM_SUB(a, b)\t\\\n\t((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \\\n\t? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)\n\n# define GSM_ABS(a)\t((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a))\n\n/* Use these if necessary:\n\n# define GSM_MULT_R(a, b)\tgsm_mult_r(a, b)\n# define GSM_MULT(a, b)\t\tgsm_mult(a, b)\n# define GSM_L_MULT(a, b)\tgsm_L_mult(a, b)\n\n# define GSM_L_ADD(a, b)\tgsm_L_add(a, b)\n# define GSM_ADD(a, b)\t\tgsm_add(a, b)\n# define GSM_SUB(a, b)\t\tgsm_sub(a, b)\n\n# define GSM_ABS(a)\t\tgsm_abs(a)\n\n*/\n\n/*\n *  More prototypes from implementations..\n */\nextern void Gsm_Coder P((\n\t\tstruct gsm_state\t* S,\n\t\tword\t* s,\t/* [0..159] samples\t\tIN\t*/\n\t\tword\t* LARc,\t/* [0..7] LAR coefficients\tOUT\t*/\n\t\tword\t* Nc,\t/* [0..3] LTP lag\t\tOUT \t*/\n\t\tword\t* bc,\t/* [0..3] coded LTP gain\tOUT \t*/\n\t\tword\t* Mc,\t/* [0..3] RPE grid selection\tOUT     */\n\t\tword\t* xmaxc,/* [0..3] Coded maximum amplitude OUT\t*/\n\t\tword\t* xMc\t/* [13*4] normalized RPE samples OUT\t*/));\n\nextern void Gsm_Long_Term_Predictor P((\t\t/* 4x for 160 samples */\n\t\tstruct gsm_state * S,\n\t\tword\t* d,\t/* [0..39]   residual signal\tIN\t*/\n\t\tword\t* dp,\t/* [-120..-1] d'\t\tIN\t*/\n\t\tword\t* e,\t/* [0..40] \t\t\tOUT\t*/\n\t\tword\t* dpp,\t/* [0..40] \t\t\tOUT\t*/\n\t\tword\t* Nc,\t/* correlation lag\t\tOUT\t*/\n\t\tword\t* bc\t/* gain factor\t\t\tOUT\t*/));\n\nextern void Gsm_LPC_Analysis P((\n\t\tstruct gsm_state * S,\n\t\tword * s,\t /* 0..159 signals\tIN/OUT\t*/\n\t        word * LARc));   /* 0..7   LARc's\tOUT\t*/\n\nextern void Gsm_Preprocess P((\n\t\tstruct gsm_state * S,\n\t\tword * s, word * so));\n\nextern void Gsm_Encoding P((\n\t\tstruct gsm_state * S,\n\t\tword\t* e,\t\n\t\tword\t* ep,\t\n\t\tword\t* xmaxc,\n\t\tword\t* Mc,\t\n\t\tword\t* xMc));\n\nextern void Gsm_Short_Term_Analysis_Filter P((\n\t\tstruct gsm_state * S,\n\t\tword\t* LARc,\t/* coded log area ratio [0..7]  IN\t*/\n\t\tword\t* d\t/* st res. signal [0..159]\tIN/OUT\t*/));\n\nextern void Gsm_Decoder P((\n\t\tstruct gsm_state * S,\n\t\tword\t* LARcr,\t/* [0..7]\t\tIN\t*/\n\t\tword\t* Ncr,\t\t/* [0..3] \t\tIN \t*/\n\t\tword\t* bcr,\t\t/* [0..3]\t\tIN\t*/\n\t\tword\t* Mcr,\t\t/* [0..3] \t\tIN \t*/\n\t\tword\t* xmaxcr,\t/* [0..3]\t\tIN \t*/\n\t\tword\t* xMcr,\t\t/* [0..13*4]\t\tIN\t*/\n\t\tword\t* s));\t\t/* [0..159]\t\tOUT \t*/\n\nextern void Gsm_Decoding P((\n\t\tstruct gsm_state * S,\n\t\tword \txmaxcr,\n\t\tword\tMcr,\n\t\tword\t* xMcr,  \t/* [0..12]\t\tIN\t*/\n\t\tword\t* erp)); \t/* [0..39]\t\tOUT \t*/\n\nextern void Gsm_Long_Term_Synthesis_Filtering P((\n\t\tstruct gsm_state* S,\n\t\tword\tNcr,\n\t\tword\tbcr,\n\t\tword\t* erp,\t\t/* [0..39]\t\t  IN \t*/\n\t\tword\t* drp)); \t/* [-120..-1] IN, [0..40] OUT \t*/\n\nvoid Gsm_RPE_Decoding P((\n\tstruct gsm_state *S,\n\t\tword xmaxcr,\n\t\tword Mcr,\n\t\tword * xMcr,  /* [0..12], 3 bits             IN      */\n\t\tword * erp)); /* [0..39]                     OUT     */\n\nvoid Gsm_RPE_Encoding P((\n\t\tstruct gsm_state * S,\n\t\tword    * e,            /* -5..-1][0..39][40..44     IN/OUT  */\n\t\tword    * xmaxc,        /*                              OUT */\n\t\tword    * Mc,           /*                              OUT */\n\t\tword    * xMc));        /* [0..12]                      OUT */\n\nextern void Gsm_Short_Term_Synthesis_Filter P((\n\t\tstruct gsm_state * S,\n\t\tword\t* LARcr, \t/* log area ratios [0..7]  IN\t*/\n\t\tword\t* drp,\t\t/* received d [0...39]\t   IN\t*/\n\t\tword\t* s));\t\t/* signal   s [0..159]\t  OUT\t*/\n\nextern void Gsm_Update_of_reconstructed_short_time_residual_signal P((\n\t\tword\t* dpp,\t\t/* [0...39]\tIN\t*/\n\t\tword\t* ep,\t\t/* [0...39]\tIN\t*/\n\t\tword\t* dp));\t\t/* [-120...-1]  IN/OUT \t*/\n\n/*\n *  Tables from table.c\n */\n#ifndef\tGSM_TABLE_C\n\nextern word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8];\nextern word gsm_INVA[8];\nextern word gsm_DLB[4], gsm_QLB[4];\nextern word gsm_H[11];\nextern word gsm_NRFAC[8];\nextern word gsm_FAC[8];\n\n#endif\t/* GSM_TABLE_C */\n\n/*\n *  Debugging\n */\n#ifdef NDEBUG\n\n#\tdefine\tgsm_debug_words(a, b, c, d)\t\t/* nil */\n#\tdefine\tgsm_debug_longwords(a, b, c, d)\t\t/* nil */\n#\tdefine\tgsm_debug_word(a, b)\t\t\t/* nil */\n#\tdefine\tgsm_debug_longword(a, b)\t\t/* nil */\n\n#else\t/* !NDEBUG => DEBUG */\n\n\textern void  gsm_debug_words     P((char * name, int, int, word *));\n\textern void  gsm_debug_longwords P((char * name, int, int, longword *));\n\textern void  gsm_debug_longword  P((char * name, longword));\n\textern void  gsm_debug_word      P((char * name, word));\n\n#endif /* !NDEBUG */\n\n#include \"unproto.h\"\n\n#endif\t/* PRIVATE_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/inc/proto.h",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/proto.h,v 1.1 1992/10/28 00:11:08 jutta Exp $*/\n\n#ifndef\tPROTO_H\n#define\tPROTO_H\n\n#if __cplusplus\n#\tdefine\tNeedFunctionPrototypes\t1\n#endif\n\n#if __STDC__\n#\tdefine\tNeedFunctionPrototypes\t1\n#endif\n\n#ifdef\t_NO_PROTO\n#\tundef\tNeedFunctionPrototypes\n#endif\n\n#undef\tP\t/* gnu stdio.h actually defines this... \t*/\n#undef\tP0\n#undef\tP1\n#undef\tP2\n#undef\tP3\n#undef\tP4\n#undef\tP5\n#undef\tP6\n#undef\tP7\n#undef\tP8\n\n#if NeedFunctionPrototypes\n\n#\tdefine\tP( protos )\tprotos\n\n#\tdefine\tP0()\t\t\t\t(void)\n#\tdefine\tP1(x, a)\t\t\t(a)\n#\tdefine\tP2(x, a, b)\t\t\t(a, b)\n#\tdefine\tP3(x, a, b, c)\t\t\t(a, b, c)\n#\tdefine\tP4(x, a, b, c, d)\t\t(a, b, c, d)\t\n#\tdefine\tP5(x, a, b, c, d, e)\t\t(a, b, c, d, e)\n#\tdefine\tP6(x, a, b, c, d, e, f)\t\t(a, b, c, d, e, f)\n#\tdefine\tP7(x, a, b, c, d, e, f, g)\t(a, b, c, d, e, f, g)\n#\tdefine\tP8(x, a, b, c, d, e, f, g, h)\t(a, b, c, d, e, f, g, h)\n\n#else /* !NeedFunctionPrototypes */\n\n#\tdefine\tP( protos )\t( /* protos */ )\n\n#\tdefine\tP0()\t\t\t\t()\n#\tdefine\tP1(x, a)\t\t\tx a;\n#\tdefine\tP2(x, a, b)\t\t\tx a; b;\n#\tdefine\tP3(x, a, b, c)\t\t\tx a; b; c;\n#\tdefine\tP4(x, a, b, c, d)\t\tx a; b; c; d;\n#\tdefine\tP5(x, a, b, c, d, e)\t\tx a; b; c; d; e;\n#\tdefine\tP6(x, a, b, c, d, e, f)\t\tx a; b; c; d; e; f;\n#\tdefine\tP7(x, a, b, c, d, e, f, g)\tx a; b; c; d; e; f; g;\n#\tdefine\tP8(x, a, b, c, d, e, f, g, h)\tx a; b; c; d; e; f; g; h;\n\n#endif  /* !NeedFunctionPrototypes */\n\n#endif\t/* PROTO_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/inc/toast.h",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/toast.h,v 1.4 1995/03/07 21:26:16 jutta Exp $ */\n\n#ifndef\tTOAST_H\n#define\tTOAST_H\t\t\t\t/* Guard against multiple includes */\n\n#include \"config.h\"\n\n#include <sys/types.h>\n#include <sys/stat.h>\n\n#include <stdio.h>\n#include <ctype.h>\n#include <signal.h>\n\n#include <errno.h>\n#ifndef\tHAS_ERRNO_DECL\n\t extern int\terrno;\n#endif\n\n#ifdef\tHAS_LIMITS_H\n#include <limits.h>\n#endif\n\n#ifdef\tHAS_FCNTL_H\n# include <fcntl.h>\n#endif\n\n#ifdef\tHAS_UTIME\n# ifdef\tHAS_UTIME_H\n#  include <utime.h>\n# endif\n#endif\n\n#include \"gsm.h\"\n\n#ifndef\tS_ISREG\n#define\tS_ISREG(x)\t((x) & S_IFREG)\n#endif\t/* S_ISREG */\n\n\n# define\tREAD\t\"rb\"\n# define\tWRITE\t\"wb\"\n#ifdef  O_BINARY\n# define\tO_WRITE_EXCL\tO_WRONLY|O_CREAT|O_EXCL|O_BINARY\n#else\n# define\tO_WRITE_EXCL\tO_WRONLY|O_CREAT|O_EXCL\n#endif\n\n#ifndef SIGHANDLER_T\n#define SIGHANDLER_T\tvoid\t/* what does a signal handler return? */\n#endif\n\n\n#ifdef\tHAS_STRING_H\n#include\t<string.h>\n#else\n#\tifdef HAS_STRINGS_H\n#\tinclude <strings.h>\n#\telse\n#\t\tinclude \"proto.h\"\n\n\t\textern int\tstrlen\tP((char *));\n\t\textern char *\tstrcpy  P((char *, char *));\n\t\textern char *\tstrcat  P((char *,  char *));\n\t\textern char *\tstrrchr P((char *, int));\n\n#\t\tinclude \"unproto.h\"\n#\tendif\n#endif\n\n\n#ifdef\tHAS_STDLIB_H\n#include\t<stdlib.h>\n#else\n#\tinclude \"proto.h\"\n#\tifdef\tHAS_MALLOC_H\n#\tinclude <malloc.h>\n#\telse\n\t\textern char\t* malloc P((unsigned));\n#\tendif\n\textern int\texit P((int));\n#\tinclude \"unproto.h\"\n#endif\n\n\n#ifdef\tHAS_UNISTD_H\n#\tinclude\t<unistd.h>\n#endif\n\n/*\n *\tThis suffix is tacked onto/removed from filenames\n *\tsimilar to the way freeze and compress do it.\n */\n#define\tSUFFIX_TOASTED\t\t\".gsm\"\n\n#include\t\"proto.h\"\n\nextern int \taudio_init_input P((void)), audio_init_output P((void));\nextern int\tulaw_input   P((gsm_signal*)), ulaw_output   P((gsm_signal *));\nextern int\talaw_input   P((gsm_signal*)), alaw_output   P((gsm_signal *));\nextern int\tlinear_input P((gsm_signal*)), linear_output P((gsm_signal *));\n\n#endif\t\t/* TOAST_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/inc/unproto.h",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/unproto.h,v 1.1 1992/10/28 00:11:08 jutta Exp $*/\n\n#ifdef\tPROTO_H\t\t/* sic */\n#undef\tPROTO_H\n\n#undef\tP\n#undef\tP0\n#undef\tP1\n#undef\tP2\n#undef\tP3\n#undef\tP4\n#undef\tP5\n#undef\tP6\n#undef\tP7\n#undef\tP8\n\n#endif\t/* PROTO_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/man/bitter.1",
    "content": ".\\\"\n.\\\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n.\\\" Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n.\\\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n.\\\"\n.PU\n.TH BITTER 1 \n.SH NAME\nbitter, sweet \\(em code-generators for packing bits\n.SH SYNOPSIS\nbitter < input > output\n.br\nsweet < input > output\n.SH \"DESCRIPTION\"\nBitter and sweet are two filters which turn a description of the\nform \n.nf\n\tname\tnumber-of-bits\n\tname \tnumber-of-bits\n\t...\n.nf\ninto code.\n.PP\nBitter generates code that packs the specified bits from their\nvariables into an array of unsigned char referenced by an\nadvancing pointer c.\n.PP\nSweet generates code that unpacks the specified bits from an array\nof unsigned char referenced by a mutable pointer c into the\nnamed variables.\n.\\\" .SH OPTIONS\n.\\\" .SH \"RETURN VALUE\"\n.\\\" .SH ERRORS\n.SH EXAMPLES\n.nf\n% cat in\namaretto 1\nbanana 2\ncherry 3\nstrawberry 4\nvanilla 15\nwalnut 15\n\n% bitter < in\n\t*c++ =   ((amaretto & 0x1) << 7)\n\t       | ((banana & 0x3) << 5)\n\t       | ((cherry & 0x7) << 2)\n\t       | ((strawberry >> 2) & 0x3);\n\t*c++ =   ((strawberry & 0x3) << 6)\n\t       | ((vanilla >> 9) & 0x3F);\n\t*c++ =   ((vanilla >> 1) & 0xFF);\n\t*c++ =   ((vanilla & 0x1) << 7)\n\t       | ((walnut >> 8) & 0x7F);\n\t*c++ =   walnut & 0xFF;\n\n% sweet < in\n\tamaretto  = (*c >> 7) & 0x1;\n\tbanana  = (*c >> 5) & 0x3;\n\tcherry  = (*c >> 2) & 0x7;\n\tstrawberry  = (*c++ & 0x3) << 2;\n\tstrawberry |= (*c >> 6) & 0x3;\n\tvanilla  = (*c++ & 0x3F) << 9;\n\tvanilla |= (*c++ & 0xFF) << 1;\n\tvanilla |= (*c >> 7) & 0x1;\n\twalnut  = (*c++ & 0x7F) << 8;\n\twalnut |= *c++;\n.SH NOTES\nThis is a quick hack for the gsm_encode() and gsm_decode() routines.\n.SH BUGS\nPlease direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de.\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/man/gsm.3",
    "content": ".\\\"\n.\\\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n.\\\" Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n.\\\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n.\\\"\n.PU\n.TH GSM 3 \n.SH NAME\ngsm_create, gsm_destroy, gsm_encode, gsm_decode \\(em GSM\\ 06.10 lossy sound compression\n.SH SYNOPSIS\n.PP\n#include \"gsm.h\"\n.PP\ngsm gsm_create();\n.PP\nvoid gsm_encode(handle, src, dst)\n.br\ngsm handle;\n.br\ngsm_signal src[160];\n.br\ngsm_frame dst;\n.PP\nint gsm_decode(handle, src, dst)\n.br\ngsm handle;\n.br\ngsm_frame src;\n.br\ngsm_signal dst[160];\n.PP\nvoid gsm_destroy(handle)\n.br\ngsm handle;\n.br\n.SH \"DESCRIPTION\"\nGsm is an implementation of the final draft GSM 06.10\nstandard for full-rate speech transcoding.\n.PP\ngsm_create() initializes a gsm pass and returns a 'gsm' object\nwhich can be used as a handle in subsequent calls to gsm_decode(),\ngsm_encode() or gsm_destroy().\n.PP\ngsm_encode() encodes an array of 160 13-bit samples (given as\ngsm_signal's, signed integral values of at least 16 bits) into\na gsm_frame of 33 bytes.\n(gsm_frame is a type defined as an array of 33 gsm_bytes in gsm.h.)\n.PP\ngsm_decode() decodes a gsm_frame into an array of 160 13-bit samples\n(given as gsm_signals), which sound rather like what you handed to\ngsm_encode() on the other side of the wire.\n.PP\ngsm_destroy() finishes a gsm pass and frees all storage associated\nwith it.\n.SS \"Sample format\"\nThe following scaling is assumed for input to the algorithm:\n.br\n.nf\n   0  1                             11 12\n   S..v..v..v..v..v..v..v..v..v..v..v..v..*..*..*\n.nf\n.br\nOnly the top 13 bits are used as a signed input value.\nThe output of gsm_decode() has the three lower bits set to zero.\n.\\\" .SH OPTIONS\n.SH \"RETURN VALUE\"\ngsm_create() returns an opaque handle object of type gsm, or 0 on error.\ngsm_decode() returns -1 if the passed frame is invalid, else 0.\n.SH EXAMPLE\n.nf\n#include \"gsm.h\"\n\ngsm handle;\ngsm_frame buf;\ngsm_signal sample[160];\nint cc, soundfd;\n\nplay() {\t/* read compressed data from standard input, write to soundfd */\n\n\tif (!(handle = gsm_create())) error...\n\twhile (cc = read(0, (char *)buf, sizeof buf)) {\n\t\tif (cc != sizeof buf) error...\n\t\tif (gsm_decode(handle, buf, sample) < 0) error... \n\t\tif (write(soundfd, sample, sizeof sample) != sizeof sample)\n\t\t\terror...\n\t}\n\tgsm_destroy(handle);\n}\n\nrecord() {\t/* read from soundfd, write compressed to standard output */\n\n\tif (!(handle = gsm_create())) error...\n\twhile (cc = read(soundfd, sample, sizeof sample)) {\n\t\tif (cc != sizeof sample) error...\n\t\tgsm_encode(handle, sample, buf);\n\t\tif (write(1, (char *)buf, sizeof buf) != sizeof sample) \n\t\t\terror...\n\t}\n\tgsm_destroy(handle);\n}\n.nf\n.SH BUGS\nPlease direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de.\n.SH \"SEE ALSO\"\ntoast(1), gsm_print(3), gsm_explode(3), gsm_option(3)\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/man/gsm_explode.3",
    "content": ".\\\"\n.\\\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n.\\\" Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n.\\\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n.\\\"\n.PU\n.TH GSM_EXPLODE 3 \n.SH NAME\ngsm_explode, gsm_implode \\(em GSM\\ 06.10 supplementary\nfunctions for testing\n.SH SYNOPSIS\n#include \"gsm.h\"\n.PP\nvoid gsm_explode(g, frame, xframe)\n.br\ngsm        g;\n.br\ngsm_frame  frame;\n.br\ngsm_signal xframe[ 76 ];\n.PP\nvoid gsm_implode(g, xframe, frame)\n.br\ngsm        g;\n.br\ngsm_signal xframe[ 76 ];\n.br\ngsm_frame  frame;\n.SH \"DESCRIPTION\"\nGsm is an implementation of the final draft GSM 06.10\nstandard for full-rate speech transcoding.\nTest data for implementations of this particular document\ncan be bought and used to verify an implementation.\n.PP\nThe encoded test data uses a format different from what\none would use to transmit frames with the least number\nof bits.\nGsm_explode() and gsm_implode() convert between the\ninternal, small, 33-byte format and the 76-word format\nused by the test data.\n.PP\n.SH \"RETURN VALUE\"\ngsm_explode() returns -1 if the passed frame is invalid, else 0.\n.SH BUGS\nPlease direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de.\n.SH \"SEE ALSO\"\ngsm(3)\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/man/gsm_option.3",
    "content": ".\\\"\n.\\\" Copyright 1992-1995 by Jutta Degener and Carsten Bormann, Technische\n.\\\" Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n.\\\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n.\\\"\n.PU\n.TH GSM_OPTION 3 \n.SH NAME\ngsm_option \\(em customizing the GSM 06.10 implementation\n.SH SYNOPSIS\n#include \"gsm.h\"\n.PP\nint gsm_option(handle, option, valueP);\n.br\ngsm handle;\n.br\nint option;\n.br\nint * valueP;\n.SH \"DESCRIPTION\"\nThe gsm library is an implementation of the final draft GSM 06.10\nstandard for full-rate speech transcoding, a lossy\nspeech compression algorithm.\n.PP\nThe gsm_option() function can be used to set and query various\noptions or flags that are not needed for regular GSM 06.10 encoding\nor decoding, but might be of interest in special cases.\n.PP\nThe second argument to gsm_option specifies what parameter\nshould be changed or queried.\nThe third argument is either a null pointer, in which case\nthe current value of that parameter is returned;\nor it is a pointer to an integer containing the value\nyou want to set, in which case the previous value will\nbe returned.\n.PP\nThe following options are defined:\n.PP\n.I GSM_OPT_VERBOSE\nVerbosity level.\n.br\n.in+5\nThis option is only supported if the library was compiled\nwith debugging turned on, and may be used by developers of\ncompression algorithms to aid debugging.\n.br\nThe verbosity level can be changed at any time during encoding or decoding.\n.in-5\n.sp\n.PP\n.I GSM_OPT_FAST\nFaster compression algorithm.\n.br\n.in+5\nThis implementation offers a not strictly standard-compliant, but\nfaster compression algorithm that is compatible with the regular\nmethod and does not noticably degrade audio quality.\n.br\nThe value passed to \n.br\n.nf\n\tgsm_option(handle, GSM_OPT_FAST, & value)\n.fi\n.br \nfunctions as a boolean flag; if it is zero, the regular algorithm\nwill be used, if not, the faster version will be used.\n.br\nThe availability of this option depends on the hardware used;\nif it is not available, gsm_option will return -1 on an attempt\nto set or query it.\n.br\nThis option can be set any time during encoding or decoding.\n.in-5\n.ne 5\n.sp\n.PP\n.I GSM_OPT_LTP_CUT\nEnable, disable, or query the LTP cut-off optimization.\n.br\n.in+5\nDuring encoding, the search for the long-term correlation\nlag forms the bottleneck of the algorithm. \nThe ltp-cut option enables an approximation that disregards most\nof the samples for purposes of finding that correlation,\nand hence speeds up the encoding at a noticable loss in quality.\n.br\nThe value passed to \n.br\n.nf\n\tgsm_option(handle, GSM_OPT_LTP_CUT, & value)\n.fi\n.br \nturns the optimization on if nonzero, and off if zero.\n.br\nThis option can be set any time during encoding\nor decoding; it will only affect the encoding pass, not\nthe decoding.\n.sp\n.PP\n.I GSM_OPT_WAV49\nWAV-style byte ordering.\n.br\n.in+5\nA WAV file of type #49 contains GSM 06.10-encoded frames.\nUnfortunately, the framing and code ordering of the WAV version\nare incompatible with the native ones of this GSM 06.10 library.\nThe GSM_OPT_WAV49 option turns on a different packing\nalgorithm that produces alternating frames of 32 and 33 bytes\n(or makes it consume alternating frames of 33 and 32 bytes, note\nthe opposite order of the two numbers) which, when concatenated,\ncan be used in the body of a WAV #49 frame.\nIt is up to the user program to write a WAV header, if any;\nneither the library itself nor the toast program produce\ncomplete WAV files.\n.br\nThe value passed to \n.br\n.nf\n\tgsm_option(handle, GSM_OPT_WAV49, & value)\n.fi\n.br \nfunctions as a boolean flag; if it is zero, the library's native\nframing algorithm will be used, if nonzero, WAV-type packing is in effect.\n.br\nThis option should be used before any frames are encoded.\nWhether or not it is supported at all depends on a\ncompile-time switch, WAV49.\nBoth option and compile time switch are new to the library\nas of patchlevel 9, and are considerably less tested than the\nwell-worn rest of the it.\n.br\nThanks to Jeff Chilton for the detective work and first free\nimplementation of this version of the GSM 06.10 encoding.\n.sp\n.PP\n.I GSM_OPT_FRAME_CHAIN\nQuery or set the chaining byte.\n.br\n.in+5\nBetween the two frames of a WAV-style encoding, the GSM 06.10 library\nmust keep track of one half-byte that is technically part of the first\nframe, but will be written as the first four bits of the second.\nThis half-byte are the lowest four bits of the value returned by,\nand optionally set by,\n.br\n.nf\n\tgsm_option(handle, GSM_OPT_FRAME_CHAIN, & value)\n.fi\n.br \nThis option can be queried and set at any time.\n.sp\n.PP\n.I GSM_OPT_FRAME_INDEX\nQuery or set the current frame's index in a format's\nalternating list of frames.\n.br\n.in+5\nThe WAV #49 framing uses two alternating types of frames.\nWhich type the next GSM-coded frame belongs to can be queried, or,\nwhen decoding, announced, using\n.br\n.nf\n\tgsm_option(handle, GSM_OPT_FRAME_INDEX, & value)\n.fi\n.br \nFor WAV-style framing, the value should be 0 or 1; the first frame\nof an encoding has an index of 0. \nAt library initialization, the index is set to zero.\n.br \nThe frame index can be queried and set at any time.\nUsed in combination with the\n.IR GSM_OPT_FRAME_CHAIN ,\noption, it can be used to position on arbitrary GSM frames\nwithin a format like WAV #49 (not accounting for the lost\ninternal GSM state).\n.in-5\n.SH \"RETURN VALUE\"\ngsm_option() returns -1 if an option is not supported, the\nprevious value of the option otherwise.\n.SH BUGS\nPlease direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de.\n.SH \"SEE ALSO\"\ntoast(1), gsm(3), gsm_explode(3), gsm_print(3)\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/man/gsm_print.3",
    "content": ".\\\"\n.\\\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n.\\\" Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n.\\\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n.\\\"\n.PU\n.TH GSM_PRINT 3 \n.SH NAME\ngsm_print \\(em GSM\\ 06.10 supplementary function for debugging\n.SH SYNOPSIS\n#include \"gsm.h\"\n#include <stdio.h>\n\nint gsm_print(f, g, frame);\n.br\nFILE * f;\n.br\ngsm    g;\n.br\ngsm_frame frame;\n.SH \"DESCRIPTION\"\nGsm is an implementation of the final draft GSM 06.10\nstandard for full-rate speech transcoding, a lossy\nspeech compression algorithm.\nThe compressed form involves 76 variables with different numbers\nof significant bits packed into 33 bytes.\n.PP\nIf you are interested in investigating the details of this\ncoding scheme, gsm_print() can be used to dump the contents\nof individual gsm_frames to a file pointer provided by\nthe application.\n.PP\n.SH \"RETURN VALUE\"\ngsm_print() returns -1 if the frame is invalid, else 0.\n.SH EXAMPLE\nA single frame looks like this:\n.br\n.nf\nLARc:   29  32  20  11  08  05  06  07\n#1:     Nc 0040    bc 0    Mc 1    xmaxc 60\n        06 04 00 03 03 06 04 02 02 04 05 04 01\n#2:     Nc 0045    bc 1    Mc 1    xmaxc 48\n        03 07 01 03 04 04 07 01 03 02 04 05 03\n#3:     Nc 0091    bc 1    Mc 1    xmaxc 46\n        00 03 03 07 01 06 02 04 05 03 03 02 04\n#4:     Nc 0120    bc 0    Mc 1    xmaxc 47\n        07 03 06 00 03 03 06 05 00 03 02 07 04\n.nf\n.SH BUGS\nPlease direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de.\n.SH \"SEE ALSO\"\ngsm(3), gsm_explode(3) \n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/man/toast.1",
    "content": ".\\\"\n.\\\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n.\\\" Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n.\\\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n.\\\"\n.if n .ds mU u\n.if t .ds mU \\(*m\n.\\\"\n.TH TOAST 1 local\n.SH NAME\ntoast \\(em GSM\\ 06.10 lossy sound compression\n.SH SYNOPSIS\n.ll +8\n.B toast\n[\n.B \\-cdfpvhualsFC\n] [\n.I \"filename...\\&\"\n]\n.LP\n.B untoast\n[\n.B \\-cfpvhuaslF\n] [\n.I \"filename...\\&\"\n]\n.LP\n.B tcat\n[\n.B \\-vhuaslF\n] [\n.I \"filename...\\&\"\n]\n.ll -8\n.SH DESCRIPTION\nToast compresses the sound files given on its command line.\nEach file is replaced by a file with the extension\n.I \\&.gsm .\nIf no files are specified, the compression is applied to the\nstandard input, and its result is written to standard output.\n.PP\nToasted files can be restored to something not quite unlike\ntheir original form by running toast\n.I \"\\-d\"\n, or \n.I untoast\n, on the \\&.gsm-files or standard input.\n.PP\nThe program \n.I tcat\n(the same as running\n.I \"untoast \\-c\"\n)  uncompresses its input on standard output,\nbut leaves the compressed .gsm\\-files alone.\n.PP\nWhen files are compressed or uncompressed into other files,\nthe ownership (if run by root), modes, accessed and modified times\nare maintained between both versions.\n.SH OPTIONS\n.TP\n.B \\-c\n(cat)\nWrite to the standard output; no files are changed.\n.TP\n.B \\-d\n(decode)\nDecode, rather than encode, the files.\n.TP\n.B \\-f\n(force)\nForce replacement of output files if they exist.\nIf \\-f is omitted and toast (or untoast) is run interactively from\na terminal, the user is prompted as to whether the file should be replaced.\n.TP\n.B \\-p\n(precious)\nDo not delete the source files.\nSource files are implicitly left alone whenever \\-c is\nspecified or tcat is run.\n.TP\n.B \\-C\n(LTP cut-off)\nIgnore most sample values when calculating the GSM long-term\ncorrelation lag during encoding.\n(The multiplications that do this are a bottleneck\nof the algorithm.)\nThe resulting encoding process will not produce\nexactly the same results as GSM 06.10 would,\nbut remains close enough to be compatible.\n.br\nThe\n.B \\-C\noption applies only to the encoder and is silently\nignored by the decoder.\n.TP\n.B \\-F\n(fast)\nOn systems with a floating point processor, but without\na multiplication instruction, \\-F sacrifices standard conformance to\nperformance and nearly doubles the speed of the algorithm.\n.br\nThe resulting encoding and decoding process will not produce\nexactly the same results as GSM 06.10 would, but remains close\nenough to be compatible.\n.br\nThe default is standard-conforming operation.\n.TP\n.B \\-v\n(version)\\ \noutputs the version of toast (or untoast or tcat) to stdout and exits.\n.TP\n.B \\-h\n(help)\\ \nprints a short overview of the options.\n.PP\nToast, untoast and tcat try to guess the appropriate audio data \nformat from the file suffix.\nCommand line options can also specify a format to be used for \nall files.\n.br\nThe following formats are supported:\n.TP\n.B \"\\-u\"\n(\\(*mU-law)\n8 kHz, 8 bit \\(*mU-law encoding (file suffix .u)\n.TP\n.B \"\\-a\"\n(A-law)\n8 kHz, 8 bit A-law encoding (file suffix .A)\n.TP\n.B \"\\-s\"\n(Sun audio)\n8 kHz, 8 bit \\(*mU-law encoding with audio header (file suffix .au)\n.TP\n.B \"-l\"\n(linear)\n8 kHz, 16 bit signed linear encoding in host byte order\nwith 13 significant bits (file suffix .l)\n.PP\nIn absence of options or suffixes to specify a format, \n\\(*mU-law encoding as forced by \\-u is assumed.\n.PP\n.SH PECULIARITIES\nA four bit magic number is prefixed to each 32 1/2-byte GSM frame,\nmainly because 32 1/2-bytes are rather clumsy to handle.\n.SH WARNING\nThe compression algorithm used is a lossy compression algorithm\ndevised especially for speech; on no account should it be used\nfor text, pictures or any other non-speech-data you consider\nvaluable.\n.SH BUGS\nPlease direct bug reports to jutta@cs.tu-berlin.de.\n.SH \"SEE ALSO\"\ngsm(3)\n.\\\"\n.\\\" Toast is dedicated to Bill Sienkiewicz, author of \"Stray Toasters\".\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/add.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/add.c,v 1.6 1996/07/02 09:57:33 jutta Exp $ */\n\n/*\n *  See private.h for the more commonly used macro versions.\n */\n\n#include\t\"config.h\"\n#include\t<stdio.h>\n#include\t<assert.h>\n\n#include\t\"private.h\"\n#include\t\"gsm.h\"\n#include\t\"proto.h\"\n\n#define\tsaturate(x) \t\\\n\t((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))\n\nword gsm_add P2((a,b), word a, word b)\n{\n\tlongword sum = (longword)a + (longword)b;\n\treturn saturate(sum);\n}\n\nword gsm_sub P2((a,b), word a, word b)\n{\n\tlongword diff = (longword)a - (longword)b;\n\treturn saturate(diff);\n}\n\nword gsm_mult P2((a,b), word a, word b)\n{\n\tif (a == MIN_WORD && b == MIN_WORD) return MAX_WORD;\n\telse return SASR( (longword)a * (longword)b, 15 );\n}\n\nword gsm_mult_r P2((a,b), word a, word b)\n{\n\tif (b == MIN_WORD && a == MIN_WORD) return MAX_WORD;\n\telse {\n\t\tlongword prod = (longword)a * (longword)b + 16384;\n\t\tprod >>= 15;\n\t\treturn prod & 0xFFFF;\n\t}\n}\n\nword gsm_abs P1((a), word a)\n{\n\treturn a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;\n}\n\nlongword gsm_L_mult P2((a,b),word a, word b)\n{\n\tassert( a != MIN_WORD || b != MIN_WORD );\n\treturn ((longword)a * (longword)b) << 1;\n}\n\nlongword gsm_L_add P2((a,b), longword a, longword b)\n{\n\tif (a < 0) {\n\t\tif (b >= 0) return a + b;\n\t\telse {\n\t\t\tulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);\n\t\t\treturn A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;\n\t\t}\n\t}\n\telse if (b <= 0) return a + b;\n\telse {\n\t\tulongword A = (ulongword)a + (ulongword)b;\n\t\treturn A > MAX_LONGWORD ? MAX_LONGWORD : A;\n\t}\n}\n\nlongword gsm_L_sub P2((a,b), longword a, longword b)\n{\n\tif (a >= 0) {\n\t\tif (b >= 0) return a - b;\n\t\telse {\n\t\t\t/* a>=0, b<0 */\n\n\t\t\tulongword A = (ulongword)a + -(b + 1);\n\t\t\treturn A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);\n\t\t}\n\t}\n\telse if (b <= 0) return a - b;\n\telse {\n\t\t/* a<0, b>0 */  \n\n\t\tulongword A = (ulongword)-(a + 1) + b;\n\t\treturn A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;\n\t}\n}\n\nstatic unsigned char const bitoff[ 256 ] = {\n\t 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,\n\t 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n};\n\nword gsm_norm P1((a), longword a )\n/*\n * the number of left shifts needed to normalize the 32 bit\n * variable L_var1 for positive values on the interval\n *\n * with minimum of\n * minimum of 1073741824  (01000000000000000000000000000000) and \n * maximum of 2147483647  (01111111111111111111111111111111)\n *\n *\n * and for negative values on the interval with\n * minimum of -2147483648 (-10000000000000000000000000000000) and\n * maximum of -1073741824 ( -1000000000000000000000000000000).\n *\n * in order to normalize the result, the following\n * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );\n *\n * (That's 'ffs', only from the left, not the right..)\n */\n{\n\tassert(a != 0);\n\n\tif (a < 0) {\n\t\tif (a <= -1073741824) return 0;\n\t\ta = ~a;\n\t}\n\n\treturn    a & 0xffff0000 \n\t\t? ( a & 0xff000000\n\t\t  ?  -1 + bitoff[ 0xFF & (a >> 24) ]\n\t\t  :   7 + bitoff[ 0xFF & (a >> 16) ] )\n\t\t: ( a & 0xff00\n\t\t  ?  15 + bitoff[ 0xFF & (a >> 8) ]\n\t\t  :  23 + bitoff[ 0xFF & a ] );\n}\n\nlongword gsm_L_asl P2((a,n), longword a, int n)\n{\n\tif (n >= 32) return 0;\n\tif (n <= -32) return -(a < 0);\n\tif (n < 0) return gsm_L_asr(a, -n);\n\treturn a << n;\n}\n\nword gsm_asl P2((a,n), word a, int n)\n{\n\tif (n >= 16) return 0;\n\tif (n <= -16) return -(a < 0);\n\tif (n < 0) return gsm_asr(a, -n);\n\treturn a << n;\n}\n\nlongword gsm_L_asr P2((a,n), longword a, int n)\n{\n\tif (n >= 32) return -(a < 0);\n\tif (n <= -32) return 0;\n\tif (n < 0) return a << -n;\n\n#\tifdef\tSASR\n\t\treturn a >> n;\n#\telse\n\t\tif (a >= 0) return a >> n;\n\t\telse return -(longword)( -(ulongword)a >> n );\n#\tendif\n}\n\nword gsm_asr P2((a,n), word a, int n)\n{\n\tif (n >= 16) return -(a < 0);\n\tif (n <= -16) return 0;\n\tif (n < 0) return a << -n;\n\n#\tifdef\tSASR\n\t\treturn a >> n;\n#\telse\n\t\tif (a >= 0) return a >> n;\n\t\telse return -(word)( -(uword)a >> n );\n#\tendif\n}\n\n/* \n *  (From p. 46, end of section 4.2.5)\n *\n *  NOTE: The following lines gives [sic] one correct implementation\n *  \t  of the div(num, denum) arithmetic operation.  Compute div\n *        which is the integer division of num by denum: with denum\n *\t  >= num > 0\n */\n\nword gsm_div P2((num,denum), word num, word denum)\n{\n\tlongword\tL_num   = num;\n\tlongword\tL_denum = denum;\n\tword\t\tdiv \t= 0;\n\tint\t\tk \t= 15;\n\n\t/* The parameter num sometimes becomes zero.\n\t * Although this is explicitly guarded against in 4.2.5,\n\t * we assume that the result should then be zero as well.\n\t */\n\n\t/* assert(num != 0); */\n\n\tassert(num >= 0 && denum >= num);\n\tif (num == 0)\n\t    return 0;\n\n\twhile (k--) {\n\t\tdiv   <<= 1;\n\t\tL_num <<= 1;\n\n\t\tif (L_num >= L_denum) {\n\t\t\tL_num -= L_denum;\n\t\t\tdiv++;\n\t\t}\n\t}\n\n\treturn div;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/code.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/code.c,v 1.3 1996/07/02 09:59:05 jutta Exp $ */\n\n#include\t\"config.h\"\n\n\n#ifdef\tHAS_STDLIB_H\n#include\t<stdlib.h>\n#else\n#\tinclude \"proto.h\"\n\textern char\t* memcpy P((char *, char *, int));\n#endif\n\n#include\t\"private.h\"\n#include\t\"gsm.h\"\n#include\t\"proto.h\"\n\n/* \n *  4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER \n */\n\nvoid Gsm_Coder P8((S,s,LARc,Nc,bc,Mc,xmaxc,xMc),\n\n\tstruct gsm_state\t* S,\n\n\tword\t* s,\t/* [0..159] samples\t\t  \tIN\t*/\n\n/*\n * The RPE-LTD coder works on a frame by frame basis.  The length of\n * the frame is equal to 160 samples.  Some computations are done\n * once per frame to produce at the output of the coder the\n * LARc[1..8] parameters which are the coded LAR coefficients and \n * also to realize the inverse filtering operation for the entire\n * frame (160 samples of signal d[0..159]).  These parts produce at\n * the output of the coder:\n */\n\n\tword\t* LARc,\t/* [0..7] LAR coefficients\t\tOUT\t*/\n\n/*\n * Procedure 4.2.11 to 4.2.18 are to be executed four times per\n * frame.  That means once for each sub-segment RPE-LTP analysis of\n * 40 samples.  These parts produce at the output of the coder:\n */\n\n\tword\t* Nc,\t/* [0..3] LTP lag\t\t\tOUT \t*/\n\tword\t* bc,\t/* [0..3] coded LTP gain\t\tOUT \t*/\n\tword\t* Mc,\t/* [0..3] RPE grid selection\t\tOUT     */\n\tword\t* xmaxc,/* [0..3] Coded maximum amplitude\tOUT\t*/\n\tword\t* xMc\t/* [13*4] normalized RPE samples\tOUT\t*/\n)\n{\n\tint\tk;\n\tword\t* dp  = S->dp0 + 120;\t/* [ -120...-1 ] */\n\tword\t* dpp = dp;\t\t/* [ 0...39 ]\t */\n\n\tword\tso[160];\n\n\tGsm_Preprocess\t\t\t(S, s, so);\n\tGsm_LPC_Analysis\t\t(S, so, LARc);\n\tGsm_Short_Term_Analysis_Filter\t(S, LARc, so);\n\n\tfor (k = 0; k <= 3; k++, xMc += 13) {\n\n\t\tGsm_Long_Term_Predictor\t( S,\n\t\t\t\t\t so+k*40, /* d      [0..39] IN\t*/\n\t\t\t\t\t dp,\t  /* dp  [-120..-1] IN\t*/\n\t\t\t\t\tS->e + 5, /* e      [0..39] OUT\t*/\n\t\t\t\t\tdpp,\t  /* dpp    [0..39] OUT */\n\t\t\t\t\t Nc++,\n\t\t\t\t\t bc++);\n\n\t\tGsm_RPE_Encoding\t( S,\n\t\t\t\t\tS->e + 5,/* e\t  ][0..39][ IN/OUT */\n\t\t\t\t\t  xmaxc++, Mc++, xMc );\n\t\t/*\n\t\t * Gsm_Update_of_reconstructed_short_time_residual_signal\n\t\t *\t\t\t( dpp, S->e + 5, dp );\n\t\t */\n\n\t\t{ register int i;\n\t\t  register longword ltmp;\n\t\t  for (i = 0; i <= 39; i++)\n\t\t\tdp[ i ] = GSM_ADD( S->e[5 + i], dpp[i] );\n\t\t}\n\t\tdp  += 40;\n\t\tdpp += 40;\n\n\t}\n\t(void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160),\n\t\t120 * sizeof(*S->dp0) );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/debug.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/debug.c,v 1.2 1993/01/29 18:22:20 jutta Exp $ */\n\n#include \"private.h\"\n\n#ifndef\tNDEBUG\n\n/* If NDEBUG _is_ defined and no debugging should be performed,\n * calls to functions in this module are #defined to nothing\n * in private.h.\n */\n\n#include <stdio.h>\n#include \"proto.h\"\n\nvoid gsm_debug_words P4( (name, from, to, ptr), \n\tchar \t      * name,\n\tint\t\tfrom,\n\tint\t\tto,\n\tword\t\t* ptr)\n{\n\tint \tnprinted = 0;\n\n\tfprintf( stderr, \"%s [%d .. %d]: \", name, from, to );\n\twhile (from <= to) {\n\t\tfprintf(stderr, \"%d \", ptr[ from ] );\n\t\tfrom++;\n\t\tif (nprinted++ >= 7) {\n\t\t\tnprinted = 0;\n\t\t\tif (from < to) putc('\\n', stderr);\n\t\t}\n\t}\n\tputc('\\n', stderr);\n}\n\nvoid gsm_debug_longwords P4( (name, from, to, ptr),\n\tchar \t      * name,\n\tint\t\tfrom,\n\tint\t\tto,\n\tlongword      * ptr)\n{\n\tint \tnprinted = 0;\n\n\tfprintf( stderr, \"%s [%d .. %d]: \", name, from, to );\n\twhile (from <= to) {\n\n\t\tfprintf(stderr, \"%d \", ptr[ from ] );\n\t\tfrom++;\n\t\tif (nprinted++ >= 7) {\n\t\t\tnprinted = 0;\n\t\t\tif (from < to) putc('\\n', stderr);\n\t\t}\n\t}\n\tputc('\\n', stderr);\n}\n\nvoid gsm_debug_longword P2(  (name, value),\n\tchar\t\t* name,\n\tlongword\t  value\t)\n{\n\tfprintf(stderr, \"%s: %d\\n\", name, (long)value );\n}\n\nvoid gsm_debug_word P2(  (name, value),\n\tchar\t* name,\n\tword\t  value\t)\n{\n\tfprintf(stderr, \"%s: %d\\n\", name, (long)value);\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/decode.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/decode.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */\n\n#include \"config.h\"\n#include <stdio.h>\n\n#include\t\"private.h\"\n#include\t\"gsm.h\"\n#include\t\"proto.h\"\n\n/*\n *  4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER\n */\n\nstatic void Postprocessing P2((S,s),\n\tstruct gsm_state\t* S,\n\tregister word \t\t* s)\n{\n\tregister int\t\tk;\n\tregister word\t\tmsr = S->msr;\n\tregister longword\tltmp;\t/* for GSM_ADD */\n\tregister word\t\ttmp;\n\n\tfor (k = 160; k--; s++) {\n\t\ttmp = GSM_MULT_R( msr, 28180 );\n\t\tmsr = GSM_ADD(*s, tmp);  \t   /* Deemphasis \t     */\n\t\t*s  = GSM_ADD(msr, msr) & 0xFFF8;  /* Truncation & Upscaling */\n\t}\n\tS->msr = msr;\n}\n\nvoid Gsm_Decoder P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s),\n\tstruct gsm_state\t* S,\n\n\tword\t\t* LARcr,\t/* [0..7]\t\tIN\t*/\n\n\tword\t\t* Ncr,\t\t/* [0..3] \t\tIN \t*/\n\tword\t\t* bcr,\t\t/* [0..3]\t\tIN\t*/\n\tword\t\t* Mcr,\t\t/* [0..3] \t\tIN \t*/\n\tword\t\t* xmaxcr,\t/* [0..3]\t\tIN \t*/\n\tword\t\t* xMcr,\t\t/* [0..13*4]\t\tIN\t*/\n\n\tword\t\t* s)\t\t/* [0..159]\t\tOUT \t*/\n{\n\tint\t\tj, k;\n\tword\t\terp[40], wt[160];\n\tword\t\t* drp = S->dp0 + 120;\n\n\tfor (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) {\n\n\t\tGsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp );\n\t\tGsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp );\n\n\t\tfor (k = 0; k <= 39; k++) wt[ j * 40 + k ] =  drp[ k ];\n\t}\n\n\tGsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s );\n\tPostprocessing(S, s);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/gsm_create.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n#include\t\"config.h\"\n\nstatic char const\tident[] = \"$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_create.c,v 1.4 1996/07/02 09:59:05 jutta Exp $\";\n\n#ifdef\tHAS_STRING_H\n#include\t<string.h>\n#else\n#\tinclude \"proto.h\"\n\textern char\t* memset P((char *, int, int));\n#endif\n\n#ifdef\tHAS_STDLIB_H\n#\tinclude\t<stdlib.h>\n#else\n#\tifdef\tHAS_MALLOC_H\n#\t\tinclude \t<malloc.h>\n#\telse\n\t\textern char * malloc();\n#\tendif\n#endif\n\n#include <stdio.h>\n\n#include \"gsm.h\"\n#include \"private.h\"\n#include \"proto.h\"\n\ngsm gsm_create P0()\n{\n\tgsm  r;\n\n\tr = (gsm)malloc(sizeof(struct gsm_state));\n\tif (!r) return r;\n\n\tmemset((char *)r, 0, sizeof(*r));\n\tr->nrp = 40;\n\n\treturn r;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/gsm_decode.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_decode.c,v 1.2 1996/07/02 09:59:05 jutta Exp $ */\n\n#include \"private.h\"\n\n#include \"gsm.h\"\n#include \"proto.h\"\n\nint gsm_decode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target)\n{\n\tword  \tLARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];\n\n#ifdef WAV49\n\tif (s->wav_fmt) {\n\n\t\tuword sr = 0;\n\n\t\ts->frame_index = !s->frame_index;\n\t\tif (s->frame_index) {\n\n\t\t\tsr = *c++;\n\t\t\tLARc[0] = sr & 0x3f;  sr >>= 6;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\tLARc[1] = sr & 0x3f;  sr >>= 6;\n\t\t\tsr |= (uword)*c++ << 4;\n\t\t\tLARc[2] = sr & 0x1f;  sr >>= 5;\n\t\t\tLARc[3] = sr & 0x1f;  sr >>= 5;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\tLARc[4] = sr & 0xf;  sr >>= 4;\n\t\t\tLARc[5] = sr & 0xf;  sr >>= 4;\n\t\t\tsr |= (uword)*c++ << 2;\t\t\t/* 5 */\n\t\t\tLARc[6] = sr & 0x7;  sr >>= 3;\n\t\t\tLARc[7] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 4;\n\t\t\tNc[0] = sr & 0x7f;  sr >>= 7;\n\t\t\tbc[0] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[0] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmaxc[0] = sr & 0x3f;  sr >>= 6;\n\t\t\txmc[0] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[1] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[2] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[3] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[4] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[5] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\t\t\t/* 10 */\n\t\t\txmc[6] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[7] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[8] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[9] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[10] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[11] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[12] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 4;\n\t\t\tNc[1] = sr & 0x7f;  sr >>= 7;\n\t\t\tbc[1] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[1] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmaxc[1] = sr & 0x3f;  sr >>= 6;\n\t\t\txmc[13] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\t\t\t\t/* 15 */\n\t\t\txmc[14] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[15] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[16] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[17] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[18] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[19] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[20] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[21] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[22] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[23] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[24] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[25] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 4;\t\t\t/* 20 */\n\t\t\tNc[2] = sr & 0x7f;  sr >>= 7;\n\t\t\tbc[2] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[2] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmaxc[2] = sr & 0x3f;  sr >>= 6;\n\t\t\txmc[26] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[27] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[28] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[29] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[30] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[31] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[32] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[33] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[34] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\t\t\t\t/* 25 */\n\t\t\txmc[35] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[36] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[37] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[38] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 4;\n\t\t\tNc[3] = sr & 0x7f;  sr >>= 7;\n\t\t\tbc[3] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[3] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmaxc[3] = sr & 0x3f;  sr >>= 6;\n\t\t\txmc[39] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[40] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[41] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\t\t\t/* 30 */\n\t\t\txmc[42] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[43] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[44] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[45] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[46] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[47] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[48] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[49] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[50] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[51] = sr & 0x7;  sr >>= 3;\n\n\t\t\ts->frame_chain = sr & 0xf;\n\t\t}\n\t\telse {\n\t\t\tsr = s->frame_chain;\n\t\t\tsr |= (uword)*c++ << 4;\t\t\t/* 1 */\n\t\t\tLARc[0] = sr & 0x3f;  sr >>= 6;\n\t\t\tLARc[1] = sr & 0x3f;  sr >>= 6;\n\t\t\tsr = *c++;\n\t\t\tLARc[2] = sr & 0x1f;  sr >>= 5;\n\t\t\tsr |= (uword)*c++ << 3;\n\t\t\tLARc[3] = sr & 0x1f;  sr >>= 5;\n\t\t\tLARc[4] = sr & 0xf;  sr >>= 4;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\tLARc[5] = sr & 0xf;  sr >>= 4;\n\t\t\tLARc[6] = sr & 0x7;  sr >>= 3;\n\t\t\tLARc[7] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\t\t\t\t/* 5 */\n\t\t\tNc[0] = sr & 0x7f;  sr >>= 7;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\tbc[0] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[0] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 5;\n\t\t\txmaxc[0] = sr & 0x3f;  sr >>= 6;\n\t\t\txmc[0] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[1] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[2] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[3] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[4] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[5] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[6] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\t\t\t/* 10 */\n\t\t\txmc[7] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[8] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[9] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[10] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[11] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[12] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\tNc[1] = sr & 0x7f;  sr >>= 7;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\tbc[1] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[1] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 5;\n\t\t\txmaxc[1] = sr & 0x3f;  sr >>= 6;\n\t\t\txmc[13] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[14] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\t\t\t/* 15 */\n\t\t\txmc[15] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[16] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[17] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[18] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[19] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[20] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[21] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[22] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[23] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[24] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[25] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\tNc[2] = sr & 0x7f;  sr >>= 7;\n\t\t\tsr |= (uword)*c++ << 1;\t\t\t/* 20 */\n\t\t\tbc[2] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[2] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 5;\n\t\t\txmaxc[2] = sr & 0x3f;  sr >>= 6;\n\t\t\txmc[26] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[27] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\t\n\t\t\txmc[28] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[29] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[30] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[31] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[32] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[33] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[34] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[35] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\t\t\t/* 25 */\n\t\t\txmc[36] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[37] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[38] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\tNc[3] = sr & 0x7f;  sr >>= 7;\n\t\t\tsr |= (uword)*c++ << 1;\t\t\n\t\t\tbc[3] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[3] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 5;\n\t\t\txmaxc[3] = sr & 0x3f;  sr >>= 6;\n\t\t\txmc[39] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[40] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[41] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[42] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[43] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\t\t\t\t/* 30 */\n\t\t\txmc[44] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[45] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[46] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[47] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[48] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[49] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[50] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[51] = sr & 0x7;  sr >>= 3;\n\t\t}\n\t}\n\telse\n#endif\n\t{\n\t\t/* GSM_MAGIC  = (*c >> 4) & 0xF; */\n\n\t\tif (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;\n\n\t\tLARc[0]  = (*c++ & 0xF) << 2;\t\t/* 1 */\n\t\tLARc[0] |= (*c >> 6) & 0x3;\n\t\tLARc[1]  = *c++ & 0x3F;\n\t\tLARc[2]  = (*c >> 3) & 0x1F;\n\t\tLARc[3]  = (*c++ & 0x7) << 2;\n\t\tLARc[3] |= (*c >> 6) & 0x3;\n\t\tLARc[4]  = (*c >> 2) & 0xF;\n\t\tLARc[5]  = (*c++ & 0x3) << 2;\n\t\tLARc[5] |= (*c >> 6) & 0x3;\n\t\tLARc[6]  = (*c >> 3) & 0x7;\n\t\tLARc[7]  = *c++ & 0x7;\n\t\tNc[0]  = (*c >> 1) & 0x7F;\n\t\tbc[0]  = (*c++ & 0x1) << 1;\n\t\tbc[0] |= (*c >> 7) & 0x1;\n\t\tMc[0]  = (*c >> 5) & 0x3;\n\t\txmaxc[0]  = (*c++ & 0x1F) << 1;\n\t\txmaxc[0] |= (*c >> 7) & 0x1;\n\t\txmc[0]  = (*c >> 4) & 0x7;\n\t\txmc[1]  = (*c >> 1) & 0x7;\n\t\txmc[2]  = (*c++ & 0x1) << 2;\n\t\txmc[2] |= (*c >> 6) & 0x3;\n\t\txmc[3]  = (*c >> 3) & 0x7;\n\t\txmc[4]  = *c++ & 0x7;\n\t\txmc[5]  = (*c >> 5) & 0x7;\n\t\txmc[6]  = (*c >> 2) & 0x7;\n\t\txmc[7]  = (*c++ & 0x3) << 1;\t\t/* 10 */\n\t\txmc[7] |= (*c >> 7) & 0x1;\n\t\txmc[8]  = (*c >> 4) & 0x7;\n\t\txmc[9]  = (*c >> 1) & 0x7;\n\t\txmc[10]  = (*c++ & 0x1) << 2;\n\t\txmc[10] |= (*c >> 6) & 0x3;\n\t\txmc[11]  = (*c >> 3) & 0x7;\n\t\txmc[12]  = *c++ & 0x7;\n\t\tNc[1]  = (*c >> 1) & 0x7F;\n\t\tbc[1]  = (*c++ & 0x1) << 1;\n\t\tbc[1] |= (*c >> 7) & 0x1;\n\t\tMc[1]  = (*c >> 5) & 0x3;\n\t\txmaxc[1]  = (*c++ & 0x1F) << 1;\n\t\txmaxc[1] |= (*c >> 7) & 0x1;\n\t\txmc[13]  = (*c >> 4) & 0x7;\n\t\txmc[14]  = (*c >> 1) & 0x7;\n\t\txmc[15]  = (*c++ & 0x1) << 2;\n\t\txmc[15] |= (*c >> 6) & 0x3;\n\t\txmc[16]  = (*c >> 3) & 0x7;\n\t\txmc[17]  = *c++ & 0x7;\n\t\txmc[18]  = (*c >> 5) & 0x7;\n\t\txmc[19]  = (*c >> 2) & 0x7;\n\t\txmc[20]  = (*c++ & 0x3) << 1;\n\t\txmc[20] |= (*c >> 7) & 0x1;\n\t\txmc[21]  = (*c >> 4) & 0x7;\n\t\txmc[22]  = (*c >> 1) & 0x7;\n\t\txmc[23]  = (*c++ & 0x1) << 2;\n\t\txmc[23] |= (*c >> 6) & 0x3;\n\t\txmc[24]  = (*c >> 3) & 0x7;\n\t\txmc[25]  = *c++ & 0x7;\n\t\tNc[2]  = (*c >> 1) & 0x7F;\n\t\tbc[2]  = (*c++ & 0x1) << 1;\t\t/* 20 */\n\t\tbc[2] |= (*c >> 7) & 0x1;\n\t\tMc[2]  = (*c >> 5) & 0x3;\n\t\txmaxc[2]  = (*c++ & 0x1F) << 1;\n\t\txmaxc[2] |= (*c >> 7) & 0x1;\n\t\txmc[26]  = (*c >> 4) & 0x7;\n\t\txmc[27]  = (*c >> 1) & 0x7;\n\t\txmc[28]  = (*c++ & 0x1) << 2;\n\t\txmc[28] |= (*c >> 6) & 0x3;\n\t\txmc[29]  = (*c >> 3) & 0x7;\n\t\txmc[30]  = *c++ & 0x7;\n\t\txmc[31]  = (*c >> 5) & 0x7;\n\t\txmc[32]  = (*c >> 2) & 0x7;\n\t\txmc[33]  = (*c++ & 0x3) << 1;\n\t\txmc[33] |= (*c >> 7) & 0x1;\n\t\txmc[34]  = (*c >> 4) & 0x7;\n\t\txmc[35]  = (*c >> 1) & 0x7;\n\t\txmc[36]  = (*c++ & 0x1) << 2;\n\t\txmc[36] |= (*c >> 6) & 0x3;\n\t\txmc[37]  = (*c >> 3) & 0x7;\n\t\txmc[38]  = *c++ & 0x7;\n\t\tNc[3]  = (*c >> 1) & 0x7F;\n\t\tbc[3]  = (*c++ & 0x1) << 1;\n\t\tbc[3] |= (*c >> 7) & 0x1;\n\t\tMc[3]  = (*c >> 5) & 0x3;\n\t\txmaxc[3]  = (*c++ & 0x1F) << 1;\n\t\txmaxc[3] |= (*c >> 7) & 0x1;\n\t\txmc[39]  = (*c >> 4) & 0x7;\n\t\txmc[40]  = (*c >> 1) & 0x7;\n\t\txmc[41]  = (*c++ & 0x1) << 2;\n\t\txmc[41] |= (*c >> 6) & 0x3;\n\t\txmc[42]  = (*c >> 3) & 0x7;\n\t\txmc[43]  = *c++ & 0x7;\t\t\t/* 30  */\n\t\txmc[44]  = (*c >> 5) & 0x7;\n\t\txmc[45]  = (*c >> 2) & 0x7;\n\t\txmc[46]  = (*c++ & 0x3) << 1;\n\t\txmc[46] |= (*c >> 7) & 0x1;\n\t\txmc[47]  = (*c >> 4) & 0x7;\n\t\txmc[48]  = (*c >> 1) & 0x7;\n\t\txmc[49]  = (*c++ & 0x1) << 2;\n\t\txmc[49] |= (*c >> 6) & 0x3;\n\t\txmc[50]  = (*c >> 3) & 0x7;\n\t\txmc[51]  = *c & 0x7;\t\t\t/* 33 */\n\t}\n\n\tGsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/gsm_destroy.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_destroy.c,v 1.3 1994/11/28 19:52:25 jutta Exp $ */\n\n#include \"gsm.h\"\n#include \"config.h\"\n#include \"proto.h\"\n\n#ifdef\tHAS_STDLIB_H\n#\tinclude\t<stdlib.h>\n#else\n#\tifdef\tHAS_MALLOC_H\n#\t\tinclude \t<malloc.h>\n#\telse\n\t\textern void free();\n#\tendif\n#endif\n\nvoid gsm_destroy P1((S), gsm S)\n{\n\tif (S) free((char *)S);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/gsm_encode.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_encode.c,v 1.2 1996/07/02 09:59:05 jutta Exp $ */\n\n#include \"private.h\"\n#include \"gsm.h\"\n#include \"proto.h\"\n\nvoid gsm_encode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c)\n{\n\tword\t \tLARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];\n\n\tGsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc);\n\n\n\t/*\tvariable\tsize\n\n\t\tGSM_MAGIC\t4\n\n\t\tLARc[0]\t\t6\n\t\tLARc[1]\t\t6\n\t\tLARc[2]\t\t5\n\t\tLARc[3]\t\t5\n\t\tLARc[4]\t\t4\n\t\tLARc[5]\t\t4\n\t\tLARc[6]\t\t3\n\t\tLARc[7]\t\t3\n\n\t\tNc[0]\t\t7\n\t\tbc[0]\t\t2\n\t\tMc[0]\t\t2\n\t\txmaxc[0]\t6\n\t\txmc[0]\t\t3\n\t\txmc[1]\t\t3\n\t\txmc[2]\t\t3\n\t\txmc[3]\t\t3\n\t\txmc[4]\t\t3\n\t\txmc[5]\t\t3\n\t\txmc[6]\t\t3\n\t\txmc[7]\t\t3\n\t\txmc[8]\t\t3\n\t\txmc[9]\t\t3\n\t\txmc[10]\t\t3\n\t\txmc[11]\t\t3\n\t\txmc[12]\t\t3\n\n\t\tNc[1]\t\t7\n\t\tbc[1]\t\t2\n\t\tMc[1]\t\t2\n\t\txmaxc[1]\t6\n\t\txmc[13]\t\t3\n\t\txmc[14]\t\t3\n\t\txmc[15]\t\t3\n\t\txmc[16]\t\t3\n\t\txmc[17]\t\t3\n\t\txmc[18]\t\t3\n\t\txmc[19]\t\t3\n\t\txmc[20]\t\t3\n\t\txmc[21]\t\t3\n\t\txmc[22]\t\t3\n\t\txmc[23]\t\t3\n\t\txmc[24]\t\t3\n\t\txmc[25]\t\t3\n\n\t\tNc[2]\t\t7\n\t\tbc[2]\t\t2\n\t\tMc[2]\t\t2\n\t\txmaxc[2]\t6\n\t\txmc[26]\t\t3\n\t\txmc[27]\t\t3\n\t\txmc[28]\t\t3\n\t\txmc[29]\t\t3\n\t\txmc[30]\t\t3\n\t\txmc[31]\t\t3\n\t\txmc[32]\t\t3\n\t\txmc[33]\t\t3\n\t\txmc[34]\t\t3\n\t\txmc[35]\t\t3\n\t\txmc[36]\t\t3\n\t\txmc[37]\t\t3\n\t\txmc[38]\t\t3\n\n\t\tNc[3]\t\t7\n\t\tbc[3]\t\t2\n\t\tMc[3]\t\t2\n\t\txmaxc[3]\t6\n\t\txmc[39]\t\t3\n\t\txmc[40]\t\t3\n\t\txmc[41]\t\t3\n\t\txmc[42]\t\t3\n\t\txmc[43]\t\t3\n\t\txmc[44]\t\t3\n\t\txmc[45]\t\t3\n\t\txmc[46]\t\t3\n\t\txmc[47]\t\t3\n\t\txmc[48]\t\t3\n\t\txmc[49]\t\t3\n\t\txmc[50]\t\t3\n\t\txmc[51]\t\t3\n\t*/\n\n#ifdef WAV49\n\n\tif (s->wav_fmt) {\n\t\ts->frame_index = !s->frame_index;\n\t\tif (s->frame_index) {\n\n\t\t\tuword sr;\n\n\t\t\tsr = 0;\n\t\t\tsr = sr >> 6 | LARc[0] << 10;\n\t\t\tsr = sr >> 6 | LARc[1] << 10;\n\t\t\t*c++ = sr >> 4;\n\t\t\tsr = sr >> 5 | LARc[2] << 11;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 5 | LARc[3] << 11;\n\t\t\tsr = sr >> 4 | LARc[4] << 12;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 4 | LARc[5] << 12;\n\t\t\tsr = sr >> 3 | LARc[6] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | LARc[7] << 13;\n\t\t\tsr = sr >> 7 | Nc[0] << 9;\n\t\t\t*c++ = sr >> 5;\n\t\t\tsr = sr >> 2 | bc[0] << 14;\n\t\t\tsr = sr >> 2 | Mc[0] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[0] << 10;\n\t\t\t*c++ = sr >> 3;\n\t\t\tsr = sr >> 3 | xmc[0] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[1] << 13;\n\t\t\tsr = sr >> 3 | xmc[2] << 13;\n\t\t\tsr = sr >> 3 | xmc[3] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[4] << 13;\n\t\t\tsr = sr >> 3 | xmc[5] << 13;\n\t\t\tsr = sr >> 3 | xmc[6] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[7] << 13;\n\t\t\tsr = sr >> 3 | xmc[8] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[9] << 13;\n\t\t\tsr = sr >> 3 | xmc[10] << 13;\n\t\t\tsr = sr >> 3 | xmc[11] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[12] << 13;\n\t\t\tsr = sr >> 7 | Nc[1] << 9;\n\t\t\t*c++ = sr >> 5;\n\t\t\tsr = sr >> 2 | bc[1] << 14;\n\t\t\tsr = sr >> 2 | Mc[1] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[1] << 10;\n\t\t\t*c++ = sr >> 3;\n\t\t\tsr = sr >> 3 | xmc[13] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[14] << 13;\n\t\t\tsr = sr >> 3 | xmc[15] << 13;\n\t\t\tsr = sr >> 3 | xmc[16] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[17] << 13;\n\t\t\tsr = sr >> 3 | xmc[18] << 13;\n\t\t\tsr = sr >> 3 | xmc[19] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[20] << 13;\n\t\t\tsr = sr >> 3 | xmc[21] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[22] << 13;\n\t\t\tsr = sr >> 3 | xmc[23] << 13;\n\t\t\tsr = sr >> 3 | xmc[24] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[25] << 13;\n\t\t\tsr = sr >> 7 | Nc[2] << 9;\n\t\t\t*c++ = sr >> 5;\n\t\t\tsr = sr >> 2 | bc[2] << 14;\n\t\t\tsr = sr >> 2 | Mc[2] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[2] << 10;\n\t\t\t*c++ = sr >> 3;\n\t\t\tsr = sr >> 3 | xmc[26] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[27] << 13;\n\t\t\tsr = sr >> 3 | xmc[28] << 13;\n\t\t\tsr = sr >> 3 | xmc[29] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[30] << 13;\n\t\t\tsr = sr >> 3 | xmc[31] << 13;\n\t\t\tsr = sr >> 3 | xmc[32] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[33] << 13;\n\t\t\tsr = sr >> 3 | xmc[34] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[35] << 13;\n\t\t\tsr = sr >> 3 | xmc[36] << 13;\n\t\t\tsr = sr >> 3 | xmc[37] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[38] << 13;\n\t\t\tsr = sr >> 7 | Nc[3] << 9;\n\t\t\t*c++ = sr >> 5;\n\t\t\tsr = sr >> 2 | bc[3] << 14;\n\t\t\tsr = sr >> 2 | Mc[3] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[3] << 10;\n\t\t\t*c++ = sr >> 3;\n\t\t\tsr = sr >> 3 | xmc[39] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[40] << 13;\n\t\t\tsr = sr >> 3 | xmc[41] << 13;\n\t\t\tsr = sr >> 3 | xmc[42] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[43] << 13;\n\t\t\tsr = sr >> 3 | xmc[44] << 13;\n\t\t\tsr = sr >> 3 | xmc[45] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[46] << 13;\n\t\t\tsr = sr >> 3 | xmc[47] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[48] << 13;\n\t\t\tsr = sr >> 3 | xmc[49] << 13;\n\t\t\tsr = sr >> 3 | xmc[50] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[51] << 13;\n\t\t\tsr = sr >> 4;\n\t\t\t*c = sr >> 8;\n\t\t\ts->frame_chain = *c;\n\t\t}\n\t\telse {\n\t\t\tuword sr;\n\n\t\t\tsr = 0;\n\t\t\tsr = sr >> 4 | s->frame_chain << 12;\n\t\t\tsr = sr >> 6 | LARc[0] << 10;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 6 | LARc[1] << 10;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 5 | LARc[2] << 11;\n\t\t\tsr = sr >> 5 | LARc[3] << 11;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 4 | LARc[4] << 12;\n\t\t\tsr = sr >> 4 | LARc[5] << 12;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | LARc[6] << 13;\n\t\t\tsr = sr >> 3 | LARc[7] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 7 | Nc[0] << 9;\n\t\t\tsr = sr >> 2 | bc[0] << 14;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 2 | Mc[0] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[0] << 10;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[0] << 13;\n\t\t\tsr = sr >> 3 | xmc[1] << 13;\n\t\t\tsr = sr >> 3 | xmc[2] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[3] << 13;\n\t\t\tsr = sr >> 3 | xmc[4] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[5] << 13;\n\t\t\tsr = sr >> 3 | xmc[6] << 13;\n\t\t\tsr = sr >> 3 | xmc[7] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[8] << 13;\n\t\t\tsr = sr >> 3 | xmc[9] << 13;\n\t\t\tsr = sr >> 3 | xmc[10] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[11] << 13;\n\t\t\tsr = sr >> 3 | xmc[12] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 7 | Nc[1] << 9;\n\t\t\tsr = sr >> 2 | bc[1] << 14;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 2 | Mc[1] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[1] << 10;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[13] << 13;\n\t\t\tsr = sr >> 3 | xmc[14] << 13;\n\t\t\tsr = sr >> 3 | xmc[15] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[16] << 13;\n\t\t\tsr = sr >> 3 | xmc[17] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[18] << 13;\n\t\t\tsr = sr >> 3 | xmc[19] << 13;\n\t\t\tsr = sr >> 3 | xmc[20] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[21] << 13;\n\t\t\tsr = sr >> 3 | xmc[22] << 13;\n\t\t\tsr = sr >> 3 | xmc[23] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[24] << 13;\n\t\t\tsr = sr >> 3 | xmc[25] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 7 | Nc[2] << 9;\n\t\t\tsr = sr >> 2 | bc[2] << 14;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 2 | Mc[2] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[2] << 10;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[26] << 13;\n\t\t\tsr = sr >> 3 | xmc[27] << 13;\n\t\t\tsr = sr >> 3 | xmc[28] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[29] << 13;\n\t\t\tsr = sr >> 3 | xmc[30] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[31] << 13;\n\t\t\tsr = sr >> 3 | xmc[32] << 13;\n\t\t\tsr = sr >> 3 | xmc[33] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[34] << 13;\n\t\t\tsr = sr >> 3 | xmc[35] << 13;\n\t\t\tsr = sr >> 3 | xmc[36] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[37] << 13;\n\t\t\tsr = sr >> 3 | xmc[38] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 7 | Nc[3] << 9;\n\t\t\tsr = sr >> 2 | bc[3] << 14;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 2 | Mc[3] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[3] << 10;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[39] << 13;\n\t\t\tsr = sr >> 3 | xmc[40] << 13;\n\t\t\tsr = sr >> 3 | xmc[41] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[42] << 13;\n\t\t\tsr = sr >> 3 | xmc[43] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[44] << 13;\n\t\t\tsr = sr >> 3 | xmc[45] << 13;\n\t\t\tsr = sr >> 3 | xmc[46] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[47] << 13;\n\t\t\tsr = sr >> 3 | xmc[48] << 13;\n\t\t\tsr = sr >> 3 | xmc[49] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[50] << 13;\n\t\t\tsr = sr >> 3 | xmc[51] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t}\n\t}\n\n\telse\n\n#endif\t/* WAV49 */\n\t{\n\n\t\t*c++ =   ((GSM_MAGIC & 0xF) << 4)\t\t/* 1 */\n\t\t       | ((LARc[0] >> 2) & 0xF);\n\t\t*c++ =   ((LARc[0] & 0x3) << 6)\n\t\t       | (LARc[1] & 0x3F);\n\t\t*c++ =   ((LARc[2] & 0x1F) << 3)\n\t\t       | ((LARc[3] >> 2) & 0x7);\n\t\t*c++ =   ((LARc[3] & 0x3) << 6)\n\t\t       | ((LARc[4] & 0xF) << 2)\n\t\t       | ((LARc[5] >> 2) & 0x3);\n\t\t*c++ =   ((LARc[5] & 0x3) << 6)\n\t\t       | ((LARc[6] & 0x7) << 3)\n\t\t       | (LARc[7] & 0x7);\n\t\t*c++ =   ((Nc[0] & 0x7F) << 1)\n\t\t       | ((bc[0] >> 1) & 0x1);\n\t\t*c++ =   ((bc[0] & 0x1) << 7)\n\t\t       | ((Mc[0] & 0x3) << 5)\n\t\t       | ((xmaxc[0] >> 1) & 0x1F);\n\t\t*c++ =   ((xmaxc[0] & 0x1) << 7)\n\t\t       | ((xmc[0] & 0x7) << 4)\n\t\t       | ((xmc[1] & 0x7) << 1)\n\t\t       | ((xmc[2] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[2] & 0x3) << 6)\n\t\t       | ((xmc[3] & 0x7) << 3)\n\t\t       | (xmc[4] & 0x7);\n\t\t*c++ =   ((xmc[5] & 0x7) << 5)\t\t\t/* 10 */\n\t\t       | ((xmc[6] & 0x7) << 2)\n\t\t       | ((xmc[7] >> 1) & 0x3);\n\t\t*c++ =   ((xmc[7] & 0x1) << 7)\n\t\t       | ((xmc[8] & 0x7) << 4)\n\t\t       | ((xmc[9] & 0x7) << 1)\n\t\t       | ((xmc[10] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[10] & 0x3) << 6)\n\t\t       | ((xmc[11] & 0x7) << 3)\n\t\t       | (xmc[12] & 0x7);\n\t\t*c++ =   ((Nc[1] & 0x7F) << 1)\n\t\t       | ((bc[1] >> 1) & 0x1);\n\t\t*c++ =   ((bc[1] & 0x1) << 7)\n\t\t       | ((Mc[1] & 0x3) << 5)\n\t\t       | ((xmaxc[1] >> 1) & 0x1F);\n\t\t*c++ =   ((xmaxc[1] & 0x1) << 7)\n\t\t       | ((xmc[13] & 0x7) << 4)\n\t\t       | ((xmc[14] & 0x7) << 1)\n\t\t       | ((xmc[15] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[15] & 0x3) << 6)\n\t\t       | ((xmc[16] & 0x7) << 3)\n\t\t       | (xmc[17] & 0x7);\n\t\t*c++ =   ((xmc[18] & 0x7) << 5)\n\t\t       | ((xmc[19] & 0x7) << 2)\n\t\t       | ((xmc[20] >> 1) & 0x3);\n\t\t*c++ =   ((xmc[20] & 0x1) << 7)\n\t\t       | ((xmc[21] & 0x7) << 4)\n\t\t       | ((xmc[22] & 0x7) << 1)\n\t\t       | ((xmc[23] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[23] & 0x3) << 6)\n\t\t       | ((xmc[24] & 0x7) << 3)\n\t\t       | (xmc[25] & 0x7);\n\t\t*c++ =   ((Nc[2] & 0x7F) << 1)\t\t\t/* 20 */\n\t\t       | ((bc[2] >> 1) & 0x1);\n\t\t*c++ =   ((bc[2] & 0x1) << 7)\n\t\t       | ((Mc[2] & 0x3) << 5)\n\t\t       | ((xmaxc[2] >> 1) & 0x1F);\n\t\t*c++ =   ((xmaxc[2] & 0x1) << 7)\n\t\t       | ((xmc[26] & 0x7) << 4)\n\t\t       | ((xmc[27] & 0x7) << 1)\n\t\t       | ((xmc[28] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[28] & 0x3) << 6)\n\t\t       | ((xmc[29] & 0x7) << 3)\n\t\t       | (xmc[30] & 0x7);\n\t\t*c++ =   ((xmc[31] & 0x7) << 5)\n\t\t       | ((xmc[32] & 0x7) << 2)\n\t\t       | ((xmc[33] >> 1) & 0x3);\n\t\t*c++ =   ((xmc[33] & 0x1) << 7)\n\t\t       | ((xmc[34] & 0x7) << 4)\n\t\t       | ((xmc[35] & 0x7) << 1)\n\t\t       | ((xmc[36] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[36] & 0x3) << 6)\n\t\t       | ((xmc[37] & 0x7) << 3)\n\t\t       | (xmc[38] & 0x7);\n\t\t*c++ =   ((Nc[3] & 0x7F) << 1)\n\t\t       | ((bc[3] >> 1) & 0x1);\n\t\t*c++ =   ((bc[3] & 0x1) << 7)\n\t\t       | ((Mc[3] & 0x3) << 5)\n\t\t       | ((xmaxc[3] >> 1) & 0x1F);\n\t\t*c++ =   ((xmaxc[3] & 0x1) << 7)\n\t\t       | ((xmc[39] & 0x7) << 4)\n\t\t       | ((xmc[40] & 0x7) << 1)\n\t\t       | ((xmc[41] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[41] & 0x3) << 6)\t\t\t/* 30 */\n\t\t       | ((xmc[42] & 0x7) << 3)\n\t\t       | (xmc[43] & 0x7);\n\t\t*c++ =   ((xmc[44] & 0x7) << 5)\n\t\t       | ((xmc[45] & 0x7) << 2)\n\t\t       | ((xmc[46] >> 1) & 0x3);\n\t\t*c++ =   ((xmc[46] & 0x1) << 7)\n\t\t       | ((xmc[47] & 0x7) << 4)\n\t\t       | ((xmc[48] & 0x7) << 1)\n\t\t       | ((xmc[49] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[49] & 0x3) << 6)\n\t\t       | ((xmc[50] & 0x7) << 3)\n\t\t       | (xmc[51] & 0x7);\n\n\t}\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/gsm_explode.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_explode.c,v 1.2 1996/07/02 14:32:42 jutta Exp jutta $ */\n\n#include \"private.h\"\n#include \"gsm.h\"\n#include \"proto.h\"\n\nint gsm_explode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target)\n{\n#\tdefine\tLARc\ttarget\n#\tdefine\tNc\t*((gsm_signal (*) [17])(target + 8))\n#\tdefine\tbc\t*((gsm_signal (*) [17])(target + 9))\n#\tdefine\tMc\t*((gsm_signal (*) [17])(target + 10))\n#\tdefine\txmaxc\t*((gsm_signal (*) [17])(target + 11))\n\n\n#ifdef WAV49\n\tif (s->wav_fmt) {\n\n\t\tuword sr = 0;\n\n\t\tif (s->frame_index == 1) {\n\n\t\t\tsr = *c++;\n\t\t\tLARc[0] = sr & 0x3f;  sr >>= 6;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\tLARc[1] = sr & 0x3f;  sr >>= 6;\n\t\t\tsr |= (uword)*c++ << 4;\n\t\t\tLARc[2] = sr & 0x1f;  sr >>= 5;\n\t\t\tLARc[3] = sr & 0x1f;  sr >>= 5;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\tLARc[4] = sr & 0xf;  sr >>= 4;\n\t\t\tLARc[5] = sr & 0xf;  sr >>= 4;\n\t\t\tsr |= (uword)*c++ << 2;\t\t\t/* 5 */\n\t\t\tLARc[6] = sr & 0x7;  sr >>= 3;\n\t\t\tLARc[7] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 4;\n\t\t\tNc[0] = sr & 0x7f;  sr >>= 7;\n\t\t\tbc[0] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[0] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmaxc[0] = sr & 0x3f;  sr >>= 6;\n#undef\txmc\n#define\txmc\t(target + 12)\n\t\t\txmc[0] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[1] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[2] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[3] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[4] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[5] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\t\t\t/* 10 */\n\t\t\txmc[6] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[7] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[8] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[9] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[10] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[11] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[12] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 4;\n\t\t\tNc[1] = sr & 0x7f;  sr >>= 7;\n\t\t\tbc[1] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[1] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmaxc[1] = sr & 0x3f;  sr >>= 6;\n#undef\txmc\n#define\txmc\t(target + 29 - 13)\n\n\t\t\txmc[13] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\t\t\t\t/* 15 */\n\t\t\txmc[14] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[15] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[16] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[17] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[18] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[19] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[20] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[21] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[22] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[23] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[24] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[25] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 4;\t\t\t/* 20 */\n\t\t\tNc[2] = sr & 0x7f;  sr >>= 7;\n\t\t\tbc[2] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[2] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmaxc[2] = sr & 0x3f;  sr >>= 6;\n\n#undef\txmc\n#define\txmc\t(target + 46 - 26)\n\n\t\t\txmc[26] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[27] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[28] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[29] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[30] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[31] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[32] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[33] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[34] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\t\t\t\t/* 25 */\n\t\t\txmc[35] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[36] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[37] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[38] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 4;\n\t\t\tNc[3] = sr & 0x7f;  sr >>= 7;\n\t\t\tbc[3] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[3] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmaxc[3] = sr & 0x3f;  sr >>= 6;\n#undef\txmc\n#define\txmc\t(target + 63 - 39)\n\n\t\t\txmc[39] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[40] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[41] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\t\t\t/* 30 */\n\t\t\txmc[42] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[43] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[44] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[45] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[46] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[47] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[48] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[49] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[50] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[51] = sr & 0x7;  sr >>= 3;\n\n\t\t\ts->frame_chain = sr & 0xf;\n\t\t}\n\t\telse {\n\t\t\tsr = s->frame_chain;\n\t\t\tsr |= (uword)*c++ << 4;\t\t\t/* 1 */\n\t\t\tLARc[0] = sr & 0x3f;  sr >>= 6;\n\t\t\tLARc[1] = sr & 0x3f;  sr >>= 6;\n\t\t\tsr = *c++;\n\t\t\tLARc[2] = sr & 0x1f;  sr >>= 5;\n\t\t\tsr |= (uword)*c++ << 3;\n\t\t\tLARc[3] = sr & 0x1f;  sr >>= 5;\n\t\t\tLARc[4] = sr & 0xf;  sr >>= 4;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\tLARc[5] = sr & 0xf;  sr >>= 4;\n\t\t\tLARc[6] = sr & 0x7;  sr >>= 3;\n\t\t\tLARc[7] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\t\t\t\t/* 5 */\n\t\t\tNc[0] = sr & 0x7f;  sr >>= 7;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\tbc[0] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[0] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 5;\n\t\t\txmaxc[0] = sr & 0x3f;  sr >>= 6;\n#undef\txmc\n#define\txmc\t(target + 12)\n\t\t\txmc[0] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[1] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[2] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[3] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[4] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[5] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[6] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\t\t\t/* 10 */\n\t\t\txmc[7] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[8] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[9] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[10] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[11] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[12] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\tNc[1] = sr & 0x7f;  sr >>= 7;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\tbc[1] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[1] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 5;\n\t\t\txmaxc[1] = sr & 0x3f;  sr >>= 6;\n#undef\txmc\n#define\txmc\t(target + 29 - 13)\n\n\t\t\txmc[13] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[14] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\t\t\t/* 15 */\n\t\t\txmc[15] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[16] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[17] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[18] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[19] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[20] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[21] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[22] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[23] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[24] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[25] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\tNc[2] = sr & 0x7f;  sr >>= 7;\n\t\t\tsr |= (uword)*c++ << 1;\t\t\t/* 20 */\n\t\t\tbc[2] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[2] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 5;\n\t\t\txmaxc[2] = sr & 0x3f;  sr >>= 6;\n#undef\txmc\n#define\txmc\t(target + 46 - 26)\n\t\t\txmc[26] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[27] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\t\n\t\t\txmc[28] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[29] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[30] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\txmc[31] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[32] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[33] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[34] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[35] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\t\t\t/* 25 */\n\t\t\txmc[36] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[37] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[38] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\n\t\t\tNc[3] = sr & 0x7f;  sr >>= 7;\n\t\t\tsr |= (uword)*c++ << 1;\t\t\n\t\t\tbc[3] = sr & 0x3;  sr >>= 2;\n\t\t\tMc[3] = sr & 0x3;  sr >>= 2;\n\t\t\tsr |= (uword)*c++ << 5;\n\t\t\txmaxc[3] = sr & 0x3f;  sr >>= 6;\n\n#undef\txmc\n#define\txmc\t(target + 63 - 39)\n\n\t\t\txmc[39] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[40] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[41] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[42] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[43] = sr & 0x7;  sr >>= 3;\n\t\t\tsr = *c++;\t\t\t\t/* 30 */\n\t\t\txmc[44] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[45] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 2;\n\t\t\txmc[46] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[47] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[48] = sr & 0x7;  sr >>= 3;\n\t\t\tsr |= (uword)*c++ << 1;\n\t\t\txmc[49] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[50] = sr & 0x7;  sr >>= 3;\n\t\t\txmc[51] = sr & 0x7;  sr >>= 3;\n\t\t}\n\t}\n\telse \n#endif\n\t{\n\t/* GSM_MAGIC  = (*c >> 4) & 0xF; */\n\n\tif (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;\n\n\tLARc[0]  = (*c++ & 0xF) << 2;\t\t/* 1 */\n\tLARc[0] |= (*c >> 6) & 0x3;\n\tLARc[1]  = *c++ & 0x3F;\n\tLARc[2]  = (*c >> 3) & 0x1F;\n\tLARc[3]  = (*c++ & 0x7) << 2;\n\tLARc[3] |= (*c >> 6) & 0x3;\n\tLARc[4]  = (*c >> 2) & 0xF;\n\tLARc[5]  = (*c++ & 0x3) << 2;\n\tLARc[5] |= (*c >> 6) & 0x3;\n\tLARc[6]  = (*c >> 3) & 0x7;\n\tLARc[7]  = *c++ & 0x7;\n\n\tNc[0]  = (*c >> 1) & 0x7F;\n\n\tbc[0]  = (*c++ & 0x1) << 1;\n\tbc[0] |= (*c >> 7) & 0x1;\n\n\tMc[0]  = (*c >> 5) & 0x3;\n\n\txmaxc[0]  = (*c++ & 0x1F) << 1;\n\txmaxc[0] |= (*c >> 7) & 0x1;\n\n#undef\txmc\n#define\txmc\t(target + 12)\n\n\txmc[0]  = (*c >> 4) & 0x7;\n\txmc[1]  = (*c >> 1) & 0x7;\n\txmc[2]  = (*c++ & 0x1) << 2;\n\txmc[2] |= (*c >> 6) & 0x3;\n\txmc[3]  = (*c >> 3) & 0x7;\n\txmc[4]  = *c++ & 0x7;\n\txmc[5]  = (*c >> 5) & 0x7;\n\txmc[6]  = (*c >> 2) & 0x7;\n\txmc[7]  = (*c++ & 0x3) << 1;\t\t/* 10 */\n\txmc[7] |= (*c >> 7) & 0x1;\n\txmc[8]  = (*c >> 4) & 0x7;\n\txmc[9]  = (*c >> 1) & 0x7;\n\txmc[10]  = (*c++ & 0x1) << 2;\n\txmc[10] |= (*c >> 6) & 0x3;\n\txmc[11]  = (*c >> 3) & 0x7;\n\txmc[12]  = *c++ & 0x7;\n\n\tNc[1]  = (*c >> 1) & 0x7F;\n\n\tbc[1]  = (*c++ & 0x1) << 1;\n\tbc[1] |= (*c >> 7) & 0x1;\n\n\tMc[1]  = (*c >> 5) & 0x3;\n\n\txmaxc[1]  = (*c++ & 0x1F) << 1;\n\txmaxc[1] |= (*c >> 7) & 0x1;\n\n#undef\txmc\n#define\txmc\t(target + 29 - 13)\n\n\txmc[13]  = (*c >> 4) & 0x7;\n\txmc[14]  = (*c >> 1) & 0x7;\n\txmc[15]  = (*c++ & 0x1) << 2;\n\txmc[15] |= (*c >> 6) & 0x3;\n\txmc[16]  = (*c >> 3) & 0x7;\n\txmc[17]  = *c++ & 0x7;\n\txmc[18]  = (*c >> 5) & 0x7;\n\txmc[19]  = (*c >> 2) & 0x7;\n\txmc[20]  = (*c++ & 0x3) << 1;\n\txmc[20] |= (*c >> 7) & 0x1;\n\txmc[21]  = (*c >> 4) & 0x7;\n\txmc[22]  = (*c >> 1) & 0x7;\n\txmc[23]  = (*c++ & 0x1) << 2;\n\txmc[23] |= (*c >> 6) & 0x3;\n\txmc[24]  = (*c >> 3) & 0x7;\n\txmc[25]  = *c++ & 0x7;\n\n\tNc[2]  = (*c >> 1) & 0x7F;\n\n\tbc[2]  = (*c++ & 0x1) << 1;\t\t/* 20 */\n\tbc[2] |= (*c >> 7) & 0x1;\n\n\tMc[2]  = (*c >> 5) & 0x3;\n\n\txmaxc[2]  = (*c++ & 0x1F) << 1;\n\txmaxc[2] |= (*c >> 7) & 0x1;\n\n#undef\txmc\n#define\txmc\t(target + 46 - 26)\n\n\txmc[26]  = (*c >> 4) & 0x7;\n\txmc[27]  = (*c >> 1) & 0x7;\n\txmc[28]  = (*c++ & 0x1) << 2;\n\txmc[28] |= (*c >> 6) & 0x3;\n\txmc[29]  = (*c >> 3) & 0x7;\n\txmc[30]  = *c++ & 0x7;\n\txmc[31]  = (*c >> 5) & 0x7;\n\txmc[32]  = (*c >> 2) & 0x7;\n\txmc[33]  = (*c++ & 0x3) << 1;\n\txmc[33] |= (*c >> 7) & 0x1;\n\txmc[34]  = (*c >> 4) & 0x7;\n\txmc[35]  = (*c >> 1) & 0x7;\n\txmc[36]  = (*c++ & 0x1) << 2;\n\txmc[36] |= (*c >> 6) & 0x3;\n\txmc[37]  = (*c >> 3) & 0x7;\n\txmc[38]  = *c++ & 0x7;\n\n\tNc[3]  = (*c >> 1) & 0x7F;\n\n\tbc[3]  = (*c++ & 0x1) << 1;\n\tbc[3] |= (*c >> 7) & 0x1;\n\n\tMc[3]  = (*c >> 5) & 0x3;\n\n\txmaxc[3]  = (*c++ & 0x1F) << 1;\n\txmaxc[3] |= (*c >> 7) & 0x1;\n\n#undef\txmc\n#define\txmc\t(target + 63 - 39)\n\n\txmc[39]  = (*c >> 4) & 0x7;\n\txmc[40]  = (*c >> 1) & 0x7;\n\txmc[41]  = (*c++ & 0x1) << 2;\n\txmc[41] |= (*c >> 6) & 0x3;\n\txmc[42]  = (*c >> 3) & 0x7;\n\txmc[43]  = *c++ & 0x7;\t\t\t/* 30  */\n\txmc[44]  = (*c >> 5) & 0x7;\n\txmc[45]  = (*c >> 2) & 0x7;\n\txmc[46]  = (*c++ & 0x3) << 1;\n\txmc[46] |= (*c >> 7) & 0x1;\n\txmc[47]  = (*c >> 4) & 0x7;\n\txmc[48]  = (*c >> 1) & 0x7;\n\txmc[49]  = (*c++ & 0x1) << 2;\n\txmc[49] |= (*c >> 6) & 0x3;\n\txmc[50]  = (*c >> 3) & 0x7;\n\txmc[51]  = *c & 0x7;\t\t\t/* 33 */\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/gsm_implode.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_implode.c,v 1.2 1996/07/02 14:32:43 jutta Exp jutta $ */\n\n#include \"private.h\"\n\n#include \"gsm.h\"\n#include \"proto.h\"\n\nvoid gsm_implode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c)\n{\n\t/*\tvariable\tsize\tindex\n\n\t\tGSM_MAGIC\t4\t-\n\n\t\tLARc[0]\t\t6\t0\n\t\tLARc[1]\t\t6\t1\n\t\tLARc[2]\t\t5\t2\n\t\tLARc[3]\t\t5\t3\n\t\tLARc[4]\t\t4\t4\n\t\tLARc[5]\t\t4\t5\n\t\tLARc[6]\t\t3\t6\n\t\tLARc[7]\t\t3\t7\n\n\t\tNc[0]\t\t7\t8\n\t\tbc[0]\t\t2\t9\n\t\tMc[0]\t\t2\t10\n\t\txmaxc[0]\t6\t11\n\t\txmc[0]\t\t3\t12\n\t\txmc[1]\t\t3\t13\n\t\txmc[2]\t\t3\t14\n\t\txmc[3]\t\t3\t15\n\t\txmc[4]\t\t3\t16\n\t\txmc[5]\t\t3\t17\n\t\txmc[6]\t\t3\t18\n\t\txmc[7]\t\t3\t19\n\t\txmc[8]\t\t3\t20\n\t\txmc[9]\t\t3\t21\n\t\txmc[10]\t\t3\t22\n\t\txmc[11]\t\t3\t23\n\t\txmc[12]\t\t3\t24\n\n\t\tNc[1]\t\t7\t25\n\t\tbc[1]\t\t2\t26\n\t\tMc[1]\t\t2\t27\n\t\txmaxc[1]\t6\t28\n\t\txmc[13]\t\t3\t29\n\t\txmc[14]\t\t3\t30\n\t\txmc[15]\t\t3\t31\n\t\txmc[16]\t\t3\t32\n\t\txmc[17]\t\t3\t33\n\t\txmc[18]\t\t3\t34\n\t\txmc[19]\t\t3\t35\n\t\txmc[20]\t\t3\t36\n\t\txmc[21]\t\t3\t37\n\t\txmc[22]\t\t3\t38\n\t\txmc[23]\t\t3\t39\n\t\txmc[24]\t\t3\t40\n\t\txmc[25]\t\t3\t41\n\n\t\tNc[2]\t\t7\t42\n\t\tbc[2]\t\t2\t43\n\t\tMc[2]\t\t2\t44\n\t\txmaxc[2]\t6\t45\n\t\txmc[26]\t\t3\t46\n\t\txmc[27]\t\t3\t47\n\t\txmc[28]\t\t3\t48\n\t\txmc[29]\t\t3\t49\n\t\txmc[30]\t\t3\t50\n\t\txmc[31]\t\t3\t51\n\t\txmc[32]\t\t3\t52\n\t\txmc[33]\t\t3\t53\n\t\txmc[34]\t\t3\t54\n\t\txmc[35]\t\t3\t55\n\t\txmc[36]\t\t3\t56\n\t\txmc[37]\t\t3\t57\n\t\txmc[38]\t\t3\t58\n\n\t\tNc[3]\t\t7\t59\n\t\tbc[3]\t\t2\t60\n\t\tMc[3]\t\t2\t61\n\t\txmaxc[3]\t6\t62\n\t\txmc[39]\t\t3\t63\n\t\txmc[40]\t\t3\t64\n\t\txmc[41]\t\t3\t65\n\t\txmc[42]\t\t3\t66\n\t\txmc[43]\t\t3\t67\n\t\txmc[44]\t\t3\t68\n\t\txmc[45]\t\t3\t69\n\t\txmc[46]\t\t3\t70\n\t\txmc[47]\t\t3\t71\n\t\txmc[48]\t\t3\t72\n\t\txmc[49]\t\t3\t73\n\t\txmc[50]\t\t3\t74\n\t\txmc[51]\t\t3\t75\n\t*/\n\n\t/*\tThere are 76 parameters per frame.  The first eight are\n\t * \tunique.  The remaining 68 are four identical subframes of\n\t * \t17 parameters each.  gsm_implode converts from a representation\n\t * \tof these parameters as values in one array of signed words\n\t * \tto the \"packed\" version of a GSM frame.\n\t */\n\n#\tdefine\tLARc\tsource\n#\tdefine\tNc\t*((gsm_signal (*) [17])(source + 8))\n#\tdefine\tbc\t*((gsm_signal (*) [17])(source + 9))\n#\tdefine\tMc\t*((gsm_signal (*) [17])(source + 10))\n#\tdefine\txmaxc\t*((gsm_signal (*) [17])(source + 11))\n\n#ifdef WAV49\n\tif (s->wav_fmt) {\n\n\t\tuword sr = 0;\n\t\tif (s->frame_index) {\n\t\t\tsr = sr >> 6 | LARc[0] << 10;\n\t\t\tsr = sr >> 6 | LARc[1] << 10;\n\t\t\t*c++ = sr >> 4;\n\t\t\tsr = sr >> 5 | LARc[2] << 11;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 5 | LARc[3] << 11;\n\t\t\tsr = sr >> 4 | LARc[4] << 12;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 4 | LARc[5] << 12;\n\t\t\tsr = sr >> 3 | LARc[6] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | LARc[7] << 13;\n\t\t\tsr = sr >> 7 | Nc[0] << 9;\n\t\t\t*c++ = sr >> 5;\n\t\t\tsr = sr >> 2 | bc[0] << 14;\n\t\t\tsr = sr >> 2 | Mc[0] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[0] << 10;\n\t\t\t*c++ = sr >> 3;\n#undef xmc\n#define\txmc\t(source + 12)\n\n\t\t\tsr = sr >> 3 | xmc[0] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[1] << 13;\n\t\t\tsr = sr >> 3 | xmc[2] << 13;\n\t\t\tsr = sr >> 3 | xmc[3] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[4] << 13;\n\t\t\tsr = sr >> 3 | xmc[5] << 13;\n\t\t\tsr = sr >> 3 | xmc[6] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[7] << 13;\n\t\t\tsr = sr >> 3 | xmc[8] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[9] << 13;\n\t\t\tsr = sr >> 3 | xmc[10] << 13;\n\t\t\tsr = sr >> 3 | xmc[11] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[12] << 13;\n\t\t\tsr = sr >> 7 | Nc[1] << 9;\n\t\t\t*c++ = sr >> 5;\n\t\t\tsr = sr >> 2 | bc[1] << 14;\n\t\t\tsr = sr >> 2 | Mc[1] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[1] << 10;\n\t\t\t*c++ = sr >> 3;\n#undef\txmc\n#define\txmc\t(source + 29 - 13)\n\n\t\t\tsr = sr >> 3 | xmc[13] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[14] << 13;\n\t\t\tsr = sr >> 3 | xmc[15] << 13;\n\t\t\tsr = sr >> 3 | xmc[16] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[17] << 13;\n\t\t\tsr = sr >> 3 | xmc[18] << 13;\n\t\t\tsr = sr >> 3 | xmc[19] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[20] << 13;\n\t\t\tsr = sr >> 3 | xmc[21] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[22] << 13;\n\t\t\tsr = sr >> 3 | xmc[23] << 13;\n\t\t\tsr = sr >> 3 | xmc[24] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[25] << 13;\n\t\t\tsr = sr >> 7 | Nc[2] << 9;\n\t\t\t*c++ = sr >> 5;\n\t\t\tsr = sr >> 2 | bc[2] << 14;\n\t\t\tsr = sr >> 2 | Mc[2] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[2] << 10;\n\t\t\t*c++ = sr >> 3;\n#undef\txmc\n#define\txmc\t(source + 46 - 26)\n\n\t\t\tsr = sr >> 3 | xmc[26] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[27] << 13;\n\t\t\tsr = sr >> 3 | xmc[28] << 13;\n\t\t\tsr = sr >> 3 | xmc[29] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[30] << 13;\n\t\t\tsr = sr >> 3 | xmc[31] << 13;\n\t\t\tsr = sr >> 3 | xmc[32] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[33] << 13;\n\t\t\tsr = sr >> 3 | xmc[34] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[35] << 13;\n\t\t\tsr = sr >> 3 | xmc[36] << 13;\n\t\t\tsr = sr >> 3 | xmc[37] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[38] << 13;\n\t\t\tsr = sr >> 7 | Nc[3] << 9;\n\t\t\t*c++ = sr >> 5;\n\t\t\tsr = sr >> 2 | bc[3] << 14;\n\t\t\tsr = sr >> 2 | Mc[3] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[3] << 10;\n\t\t\t*c++ = sr >> 3;\n#undef\txmc\n#define\txmc\t(source + 63 - 39)\n\n\t\t\tsr = sr >> 3 | xmc[39] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[40] << 13;\n\t\t\tsr = sr >> 3 | xmc[41] << 13;\n\t\t\tsr = sr >> 3 | xmc[42] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[43] << 13;\n\t\t\tsr = sr >> 3 | xmc[44] << 13;\n\t\t\tsr = sr >> 3 | xmc[45] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[46] << 13;\n\t\t\tsr = sr >> 3 | xmc[47] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[48] << 13;\n\t\t\tsr = sr >> 3 | xmc[49] << 13;\n\t\t\tsr = sr >> 3 | xmc[50] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[51] << 13;\n\t\t\tsr = sr >> 4;\n\t\t\t*c = sr >> 8;\n\t\t\ts->frame_chain = *c;\n\t\t}\n\t\telse {\n\t\t\tsr = sr >> 4 | s->frame_chain << 12;\n\t\t\tsr = sr >> 6 | LARc[0] << 10;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 6 | LARc[1] << 10;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 5 | LARc[2] << 11;\n\t\t\tsr = sr >> 5 | LARc[3] << 11;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 4 | LARc[4] << 12;\n\t\t\tsr = sr >> 4 | LARc[5] << 12;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | LARc[6] << 13;\n\t\t\tsr = sr >> 3 | LARc[7] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 7 | Nc[0] << 9;\n\t\t\tsr = sr >> 2 | bc[0] << 14;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 2 | Mc[0] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[0] << 10;\n\t\t\t*c++ = sr >> 7;\n#undef xmc\n#define\txmc\t(source + 12)\n\n\t\t\tsr = sr >> 3 | xmc[0] << 13;\n\t\t\tsr = sr >> 3 | xmc[1] << 13;\n\t\t\tsr = sr >> 3 | xmc[2] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[3] << 13;\n\t\t\tsr = sr >> 3 | xmc[4] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[5] << 13;\n\t\t\tsr = sr >> 3 | xmc[6] << 13;\n\t\t\tsr = sr >> 3 | xmc[7] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[8] << 13;\n\t\t\tsr = sr >> 3 | xmc[9] << 13;\n\t\t\tsr = sr >> 3 | xmc[10] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[11] << 13;\n\t\t\tsr = sr >> 3 | xmc[12] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 7 | Nc[1] << 9;\n\t\t\tsr = sr >> 2 | bc[1] << 14;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 2 | Mc[1] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[1] << 10;\n\t\t\t*c++ = sr >> 7;\n#undef\txmc\n#define\txmc\t(source + 29 - 13)\n\n\t\t\tsr = sr >> 3 | xmc[13] << 13;\n\t\t\tsr = sr >> 3 | xmc[14] << 13;\n\t\t\tsr = sr >> 3 | xmc[15] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[16] << 13;\n\t\t\tsr = sr >> 3 | xmc[17] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[18] << 13;\n\t\t\tsr = sr >> 3 | xmc[19] << 13;\n\t\t\tsr = sr >> 3 | xmc[20] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[21] << 13;\n\t\t\tsr = sr >> 3 | xmc[22] << 13;\n\t\t\tsr = sr >> 3 | xmc[23] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[24] << 13;\n\t\t\tsr = sr >> 3 | xmc[25] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 7 | Nc[2] << 9;\n\t\t\tsr = sr >> 2 | bc[2] << 14;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 2 | Mc[2] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[2] << 10;\n\t\t\t*c++ = sr >> 7;\n#undef\txmc\n#define\txmc\t(source + 46 - 26)\n\n\t\t\tsr = sr >> 3 | xmc[26] << 13;\n\t\t\tsr = sr >> 3 | xmc[27] << 13;\n\t\t\tsr = sr >> 3 | xmc[28] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[29] << 13;\n\t\t\tsr = sr >> 3 | xmc[30] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[31] << 13;\n\t\t\tsr = sr >> 3 | xmc[32] << 13;\n\t\t\tsr = sr >> 3 | xmc[33] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[34] << 13;\n\t\t\tsr = sr >> 3 | xmc[35] << 13;\n\t\t\tsr = sr >> 3 | xmc[36] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[37] << 13;\n\t\t\tsr = sr >> 3 | xmc[38] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 7 | Nc[3] << 9;\n\t\t\tsr = sr >> 2 | bc[3] << 14;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 2 | Mc[3] << 14;\n\t\t\tsr = sr >> 6 | xmaxc[3] << 10;\n\t\t\t*c++ = sr >> 7;\n#undef\txmc\n#define\txmc\t(source + 63 - 39)\n\n\t\t\tsr = sr >> 3 | xmc[39] << 13;\n\t\t\tsr = sr >> 3 | xmc[40] << 13;\n\t\t\tsr = sr >> 3 | xmc[41] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[42] << 13;\n\t\t\tsr = sr >> 3 | xmc[43] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t\tsr = sr >> 3 | xmc[44] << 13;\n\t\t\tsr = sr >> 3 | xmc[45] << 13;\n\t\t\tsr = sr >> 3 | xmc[46] << 13;\n\t\t\t*c++ = sr >> 7;\n\t\t\tsr = sr >> 3 | xmc[47] << 13;\n\t\t\tsr = sr >> 3 | xmc[48] << 13;\n\t\t\tsr = sr >> 3 | xmc[49] << 13;\n\t\t\t*c++ = sr >> 6;\n\t\t\tsr = sr >> 3 | xmc[50] << 13;\n\t\t\tsr = sr >> 3 | xmc[51] << 13;\n\t\t\t*c++ = sr >> 8;\n\t\t}\n\t}\n\telse\n#endif \n\t{\n\n\t\t*c++ =   ((GSM_MAGIC & 0xF) << 4)\t\t/* 1 */\n\t\t       | ((LARc[0] >> 2) & 0xF);\n\t\t*c++ =   ((LARc[0] & 0x3) << 6)\n\t\t       | (LARc[1] & 0x3F);\n\t\t*c++ =   ((LARc[2] & 0x1F) << 3)\n\t\t       | ((LARc[3] >> 2) & 0x7);\n\t\t*c++ =   ((LARc[3] & 0x3) << 6)\n\t\t       | ((LARc[4] & 0xF) << 2)\n\t\t       | ((LARc[5] >> 2) & 0x3);\n\t\t*c++ =   ((LARc[5] & 0x3) << 6)\n\t\t       | ((LARc[6] & 0x7) << 3)\n\t\t       | (LARc[7] & 0x7);\n\n\n\t\t*c++ =   ((Nc[0] & 0x7F) << 1)\n\n\n\t\t       | ((bc[0] >> 1) & 0x1);\n\t\t*c++ =   ((bc[0] & 0x1) << 7)\n\n\n\t\t       | ((Mc[0] & 0x3) << 5)\n\n\t\t       | ((xmaxc[0] >> 1) & 0x1F);\n\t\t*c++ =   ((xmaxc[0] & 0x1) << 7)\n\n#undef xmc\n#define\txmc\t(source + 12)\n\n\t\t       | ((xmc[0] & 0x7) << 4)\n\t\t       | ((xmc[1] & 0x7) << 1)\n\t\t       | ((xmc[2] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[2] & 0x3) << 6)\n\t\t       | ((xmc[3] & 0x7) << 3)\n\t\t       | (xmc[4] & 0x7);\n\t\t*c++ =   ((xmc[5] & 0x7) << 5)\t\t\t/* 10 */\n\t\t       | ((xmc[6] & 0x7) << 2)\n\t\t       | ((xmc[7] >> 1) & 0x3);\n\t\t*c++ =   ((xmc[7] & 0x1) << 7)\n\t\t       | ((xmc[8] & 0x7) << 4)\n\t\t       | ((xmc[9] & 0x7) << 1)\n\t\t       | ((xmc[10] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[10] & 0x3) << 6)\n\t\t       | ((xmc[11] & 0x7) << 3)\n\t\t       | (xmc[12] & 0x7);\n\n\n\t\t*c++ =   ((Nc[1] & 0x7F) << 1)\n\n\n\t\t       | ((bc[1] >> 1) & 0x1);\n\t\t*c++ =   ((bc[1] & 0x1) << 7)\n\n\n\t\t       | ((Mc[1] & 0x3) << 5)\n\n\n\t\t       | ((xmaxc[1] >> 1) & 0x1F);\n\t\t*c++ =   ((xmaxc[1] & 0x1) << 7)\n\n#undef\txmc\n#define\txmc\t(source + 29 - 13)\n\n\t\t       | ((xmc[13] & 0x7) << 4)\n\t\t       | ((xmc[14] & 0x7) << 1)\n\t\t       | ((xmc[15] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[15] & 0x3) << 6)\n\t\t       | ((xmc[16] & 0x7) << 3)\n\t\t       | (xmc[17] & 0x7);\n\t\t*c++ =   ((xmc[18] & 0x7) << 5)\n\t\t       | ((xmc[19] & 0x7) << 2)\n\t\t       | ((xmc[20] >> 1) & 0x3);\n\t\t*c++ =   ((xmc[20] & 0x1) << 7)\n\t\t       | ((xmc[21] & 0x7) << 4)\n\t\t       | ((xmc[22] & 0x7) << 1)\n\t\t       | ((xmc[23] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[23] & 0x3) << 6)\n\t\t       | ((xmc[24] & 0x7) << 3)\n\t\t       | (xmc[25] & 0x7);\n\n\n\t\t*c++ =   ((Nc[2] & 0x7F) << 1)\t\t\t/* 20 */\n\n\n\t\t       | ((bc[2] >> 1) & 0x1);\n\t\t*c++ =   ((bc[2] & 0x1) << 7)\n\n\n\t\t       | ((Mc[2] & 0x3) << 5)\n\n\n\t\t       | ((xmaxc[2] >> 1) & 0x1F);\n\t\t*c++ =   ((xmaxc[2] & 0x1) << 7)\n\n#undef\txmc\n#define\txmc\t(source + 46 - 26)\n\n\t\t       | ((xmc[26] & 0x7) << 4)\n\t\t       | ((xmc[27] & 0x7) << 1)\n\t\t       | ((xmc[28] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[28] & 0x3) << 6)\n\t\t       | ((xmc[29] & 0x7) << 3)\n\t\t       | (xmc[30] & 0x7);\n\t\t*c++ =   ((xmc[31] & 0x7) << 5)\n\t\t       | ((xmc[32] & 0x7) << 2)\n\t\t       | ((xmc[33] >> 1) & 0x3);\n\t\t*c++ =   ((xmc[33] & 0x1) << 7)\n\t\t       | ((xmc[34] & 0x7) << 4)\n\t\t       | ((xmc[35] & 0x7) << 1)\n\t\t       | ((xmc[36] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[36] & 0x3) << 6)\n\t\t       | ((xmc[37] & 0x7) << 3)\n\t\t       | (xmc[38] & 0x7);\n\n\n\t\t*c++ =   ((Nc[3] & 0x7F) << 1)\n\n\n\t\t       | ((bc[3] >> 1) & 0x1);\n\t\t*c++ =   ((bc[3] & 0x1) << 7)\n\n\n\t\t       | ((Mc[3] & 0x3) << 5)\n\n\n\t\t       | ((xmaxc[3] >> 1) & 0x1F);\n\t\t*c++ =   ((xmaxc[3] & 0x1) << 7)\n\n#undef\txmc\n#define\txmc\t(source + 63 - 39)\n\n\t\t       | ((xmc[39] & 0x7) << 4)\n\t\t       | ((xmc[40] & 0x7) << 1)\n\t\t       | ((xmc[41] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[41] & 0x3) << 6)\t\t\t/* 30 */\n\t\t       | ((xmc[42] & 0x7) << 3)\n\t\t       | (xmc[43] & 0x7);\n\t\t*c++ =   ((xmc[44] & 0x7) << 5)\n\t\t       | ((xmc[45] & 0x7) << 2)\n\t\t       | ((xmc[46] >> 1) & 0x3);\n\t\t*c++ =   ((xmc[46] & 0x1) << 7)\n\t\t       | ((xmc[47] & 0x7) << 4)\n\t\t       | ((xmc[48] & 0x7) << 1)\n\t\t       | ((xmc[49] >> 2) & 0x1);\n\t\t*c++ =   ((xmc[49] & 0x3) << 6)\n\t\t       | ((xmc[50] & 0x7) << 3)\n\t\t       | (xmc[51] & 0x7);\n\t}\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/gsm_option.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_option.c,v 1.3 1996/07/02 09:59:05 jutta Exp $ */\n\n#include \"private.h\"\n\n#include \"gsm.h\"\n#include \"proto.h\"\n\nint gsm_option P3((r, opt, val), gsm r, int opt, int * val)\n{\n\tint \tresult = -1;\n\n\tswitch (opt) {\n\tcase GSM_OPT_LTP_CUT:\n#ifdef \tLTP_CUT\n\t\tresult = r->ltp_cut;\n\t\tif (val) r->ltp_cut = *val;\n#endif\n\t\tbreak;\n\n\tcase GSM_OPT_VERBOSE:\n#ifndef\tNDEBUG\n\t\tresult = r->verbose;\n\t\tif (val) r->verbose = *val;\n#endif\n\t\tbreak;\n\n\tcase GSM_OPT_FAST:\n\n#if\tdefined(FAST) && defined(USE_FLOAT_MUL)\n\t\tresult = r->fast;\n\t\tif (val) r->fast = !!*val;\n#endif\n\t\tbreak;\n\n\tcase GSM_OPT_FRAME_CHAIN:\n\n#ifdef WAV49\n\t\tresult = r->frame_chain;\n\t\tif (val) r->frame_chain = *val;\n#endif\n\t\tbreak;\n\n\tcase GSM_OPT_FRAME_INDEX:\n\n#ifdef WAV49\n\t\tresult = r->frame_index;\n\t\tif (val) r->frame_index = *val;\n#endif\n\t\tbreak;\n\n\tcase GSM_OPT_WAV49:\n\n#ifdef WAV49 \n\t\tresult = r->wav_fmt;\n\t\tif (val) r->wav_fmt = !!*val;\n#endif\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\treturn result;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/gsm_print.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_print.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */\n\n#include\t<stdio.h>\n\n#include \"private.h\"\n\n#include \"gsm.h\"\n#include \"proto.h\"\n\nint gsm_print P3((f, s, c), FILE * f, gsm s, gsm_byte * c)\n{\n\tword  \tLARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];\n\n\t/* GSM_MAGIC  = (*c >> 4) & 0xF; */\n\n\tif (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;\n\n\tLARc[0]  = (*c++ & 0xF) << 2;\t\t/* 1 */\n\tLARc[0] |= (*c >> 6) & 0x3;\n\tLARc[1]  = *c++ & 0x3F;\n\tLARc[2]  = (*c >> 3) & 0x1F;\n\tLARc[3]  = (*c++ & 0x7) << 2;\n\tLARc[3] |= (*c >> 6) & 0x3;\n\tLARc[4]  = (*c >> 2) & 0xF;\n\tLARc[5]  = (*c++ & 0x3) << 2;\n\tLARc[5] |= (*c >> 6) & 0x3;\n\tLARc[6]  = (*c >> 3) & 0x7;\n\tLARc[7]  = *c++ & 0x7;\n\n\n\tNc[0]  = (*c >> 1) & 0x7F;\n\tbc[0]  = (*c++ & 0x1) << 1;\n\tbc[0] |= (*c >> 7) & 0x1;\n\tMc[0]  = (*c >> 5) & 0x3;\n\txmaxc[0]  = (*c++ & 0x1F) << 1;\n\txmaxc[0] |= (*c >> 7) & 0x1;\n\txmc[0]  = (*c >> 4) & 0x7;\n\txmc[1]  = (*c >> 1) & 0x7;\n\txmc[2]  = (*c++ & 0x1) << 2;\n\txmc[2] |= (*c >> 6) & 0x3;\n\txmc[3]  = (*c >> 3) & 0x7;\n\txmc[4]  = *c++ & 0x7;\n\txmc[5]  = (*c >> 5) & 0x7;\n\txmc[6]  = (*c >> 2) & 0x7;\n\txmc[7]  = (*c++ & 0x3) << 1;\t\t/* 10 */\n\txmc[7] |= (*c >> 7) & 0x1;\n\txmc[8]  = (*c >> 4) & 0x7;\n\txmc[9]  = (*c >> 1) & 0x7;\n\txmc[10]  = (*c++ & 0x1) << 2;\n\txmc[10] |= (*c >> 6) & 0x3;\n\txmc[11]  = (*c >> 3) & 0x7;\n\txmc[12]  = *c++ & 0x7;\n\n\tNc[1]  = (*c >> 1) & 0x7F;\n\tbc[1]  = (*c++ & 0x1) << 1;\n\tbc[1] |= (*c >> 7) & 0x1;\n\tMc[1]  = (*c >> 5) & 0x3;\n\txmaxc[1]  = (*c++ & 0x1F) << 1;\n\txmaxc[1] |= (*c >> 7) & 0x1;\n\txmc[13]  = (*c >> 4) & 0x7;\n\txmc[14]  = (*c >> 1) & 0x7;\n\txmc[15]  = (*c++ & 0x1) << 2;\n\txmc[15] |= (*c >> 6) & 0x3;\n\txmc[16]  = (*c >> 3) & 0x7;\n\txmc[17]  = *c++ & 0x7;\n\txmc[18]  = (*c >> 5) & 0x7;\n\txmc[19]  = (*c >> 2) & 0x7;\n\txmc[20]  = (*c++ & 0x3) << 1;\n\txmc[20] |= (*c >> 7) & 0x1;\n\txmc[21]  = (*c >> 4) & 0x7;\n\txmc[22]  = (*c >> 1) & 0x7;\n\txmc[23]  = (*c++ & 0x1) << 2;\n\txmc[23] |= (*c >> 6) & 0x3;\n\txmc[24]  = (*c >> 3) & 0x7;\n\txmc[25]  = *c++ & 0x7;\n\n\n\tNc[2]  = (*c >> 1) & 0x7F;\n\tbc[2]  = (*c++ & 0x1) << 1;\t\t/* 20 */\n\tbc[2] |= (*c >> 7) & 0x1;\n\tMc[2]  = (*c >> 5) & 0x3;\n\txmaxc[2]  = (*c++ & 0x1F) << 1;\n\txmaxc[2] |= (*c >> 7) & 0x1;\n\txmc[26]  = (*c >> 4) & 0x7;\n\txmc[27]  = (*c >> 1) & 0x7;\n\txmc[28]  = (*c++ & 0x1) << 2;\n\txmc[28] |= (*c >> 6) & 0x3;\n\txmc[29]  = (*c >> 3) & 0x7;\n\txmc[30]  = *c++ & 0x7;\n\txmc[31]  = (*c >> 5) & 0x7;\n\txmc[32]  = (*c >> 2) & 0x7;\n\txmc[33]  = (*c++ & 0x3) << 1;\n\txmc[33] |= (*c >> 7) & 0x1;\n\txmc[34]  = (*c >> 4) & 0x7;\n\txmc[35]  = (*c >> 1) & 0x7;\n\txmc[36]  = (*c++ & 0x1) << 2;\n\txmc[36] |= (*c >> 6) & 0x3;\n\txmc[37]  = (*c >> 3) & 0x7;\n\txmc[38]  = *c++ & 0x7;\n\n\tNc[3]  = (*c >> 1) & 0x7F;\n\tbc[3]  = (*c++ & 0x1) << 1;\n\tbc[3] |= (*c >> 7) & 0x1;\n\tMc[3]  = (*c >> 5) & 0x3;\n\txmaxc[3]  = (*c++ & 0x1F) << 1;\n\txmaxc[3] |= (*c >> 7) & 0x1;\n\n\txmc[39]  = (*c >> 4) & 0x7;\n\txmc[40]  = (*c >> 1) & 0x7;\n\txmc[41]  = (*c++ & 0x1) << 2;\n\txmc[41] |= (*c >> 6) & 0x3;\n\txmc[42]  = (*c >> 3) & 0x7;\n\txmc[43]  = *c++ & 0x7;\t\t\t/* 30  */\n\txmc[44]  = (*c >> 5) & 0x7;\n\txmc[45]  = (*c >> 2) & 0x7;\n\txmc[46]  = (*c++ & 0x3) << 1;\n\txmc[46] |= (*c >> 7) & 0x1;\n\txmc[47]  = (*c >> 4) & 0x7;\n\txmc[48]  = (*c >> 1) & 0x7;\n\txmc[49]  = (*c++ & 0x1) << 2;\n\txmc[49] |= (*c >> 6) & 0x3;\n\txmc[50]  = (*c >> 3) & 0x7;\n\txmc[51]  = *c & 0x7;\t\t\t/* 33 */\n\n\tfprintf(f,\n\t      \"LARc:\\t%2.2d  %2.2d  %2.2d  %2.2d  %2.2d  %2.2d  %2.2d  %2.2d\\n\",\n\t       LARc[0],LARc[1],LARc[2],LARc[3],LARc[4],LARc[5],LARc[6],LARc[7]);\n\n\tfprintf(f, \"#1: \tNc %4.4d    bc %d    Mc %d    xmaxc %d\\n\",\n\t\tNc[0], bc[0], Mc[0], xmaxc[0]);\n\tfprintf(f,\n\"\\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\\n\",\n\t\txmc[0],xmc[1],xmc[2],xmc[3],xmc[4],xmc[5],xmc[6],\n\t\txmc[7],xmc[8],xmc[9],xmc[10],xmc[11],xmc[12] );\n\n\tfprintf(f, \"#2: \tNc %4.4d    bc %d    Mc %d    xmaxc %d\\n\",\n\t\tNc[1], bc[1], Mc[1], xmaxc[1]);\n\tfprintf(f,\n\"\\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\\n\",\n\t\txmc[13+0],xmc[13+1],xmc[13+2],xmc[13+3],xmc[13+4],xmc[13+5],\n\t\txmc[13+6], xmc[13+7],xmc[13+8],xmc[13+9],xmc[13+10],xmc[13+11],\n\t\txmc[13+12] );\n\n\tfprintf(f, \"#3: \tNc %4.4d    bc %d    Mc %d    xmaxc %d\\n\",\n\t\tNc[2], bc[2], Mc[2], xmaxc[2]);\n\tfprintf(f,\n\"\\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\\n\",\n\t\txmc[26+0],xmc[26+1],xmc[26+2],xmc[26+3],xmc[26+4],xmc[26+5],\n\t\txmc[26+6], xmc[26+7],xmc[26+8],xmc[26+9],xmc[26+10],xmc[26+11],\n\t\txmc[26+12] );\n\n\tfprintf(f, \"#4: \tNc %4.4d    bc %d    Mc %d    xmaxc %d\\n\",\n\t\tNc[3], bc[3], Mc[3], xmaxc[3]);\n\tfprintf(f,\n\"\\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\\n\",\n\t\txmc[39+0],xmc[39+1],xmc[39+2],xmc[39+3],xmc[39+4],xmc[39+5],\n\t\txmc[39+6], xmc[39+7],xmc[39+8],xmc[39+9],xmc[39+10],xmc[39+11],\n\t\txmc[39+12] );\n\n\treturn 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/long_term.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/long_term.c,v 1.6 1996/07/02 12:33:19 jutta Exp $ */\n\n#include \"config.h\"\n#include <stdio.h>\n#include <assert.h>\n\n#include \"private.h\"\n\n#include \"gsm.h\"\n#include \"proto.h\"\n\n/*\n *  4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION\n */\n\n\n/*\n * This module computes the LTP gain (bc) and the LTP lag (Nc)\n * for the long term analysis filter.   This is done by calculating a\n * maximum of the cross-correlation function between the current\n * sub-segment short term residual signal d[0..39] (output of\n * the short term analysis filter; for simplification the index\n * of this array begins at 0 and ends at 39 for each sub-segment of the\n * RPE-LTP analysis) and the previous reconstructed short term\n * residual signal dp[ -120 .. -1 ].  A dynamic scaling must be\n * performed to avoid overflow.\n */\n\n /* The next procedure exists in six versions.  First two integer\n  * version (if USE_FLOAT_MUL is not defined); then four floating\n  * point versions, twice with proper scaling (USE_FLOAT_MUL defined),\n  * once without (USE_FLOAT_MUL and FAST defined, and fast run-time\n  * option used).  Every pair has first a Cut version (see the -C\n  * option to toast or the LTP_CUT option to gsm_option()), then the\n  * uncut one.  (For a detailed explanation of why this is altogether\n  * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered\n  * Harmful''.)\n  */\n\n#ifndef  USE_FLOAT_MUL\n\n#ifdef\tLTP_CUT\n\nstatic void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out),\n\n\tstruct gsm_state * st,\n\n\tregister word\t* d,\t\t/* [0..39]\tIN\t*/\n\tregister word\t* dp,\t\t/* [-120..-1]\tIN\t*/\n\tword\t\t* bc_out,\t/* \t\tOUT\t*/\n\tword\t\t* Nc_out\t/* \t\tOUT\t*/\n)\n{\n\tregister int  \tk, lambda;\n\tword\t\tNc, bc;\n\tword\t\twt[40];\n\n\tlongword\tL_result;\n\tlongword\tL_max, L_power;\n\tword\t\tR, S, dmax, scal, best_k;\n\tword\t\tltp_cut;\n\n\tregister word\ttemp, wt_k;\n\n\t/*  Search of the optimum scaling of d[0..39].\n\t */\n\tdmax = 0;\n\tfor (k = 0; k <= 39; k++) {\n\t\ttemp = d[k];\n\t\ttemp = GSM_ABS( temp );\n\t\tif (temp > dmax) {\n\t\t\tdmax = temp;\n\t\t\tbest_k = k;\n\t\t}\n\t}\n\ttemp = 0;\n\tif (dmax == 0) scal = 0;\n\telse {\n\t\tassert(dmax > 0);\n\t\ttemp = gsm_norm( (longword)dmax << 16 );\n\t}\n\tif (temp > 6) scal = 0;\n\telse scal = 6 - temp;\n\tassert(scal >= 0);\n\n\t/* Search for the maximum cross-correlation and coding of the LTP lag\n\t */\n\tL_max = 0;\n\tNc    = 40;\t/* index for the maximum cross-correlation */\n\twt_k  = SASR(d[best_k], scal);\n\n\tfor (lambda = 40; lambda <= 120; lambda++) {\n\t\tL_result = (longword)wt_k * dp[best_k - lambda];\n\t\tif (L_result > L_max) {\n\t\t\tNc    = lambda;\n\t\t\tL_max = L_result;\n\t\t}\n\t}\n\t*Nc_out = Nc;\n\tL_max <<= 1;\n\n\t/*  Rescaling of L_max\n\t */\n\tassert(scal <= 100 && scal >= -100);\n\tL_max = L_max >> (6 - scal);\t/* sub(6, scal) */\n\n\tassert( Nc <= 120 && Nc >= 40);\n\n\t/*   Compute the power of the reconstructed short term residual\n\t *   signal dp[..]\n\t */\n\tL_power = 0;\n\tfor (k = 0; k <= 39; k++) {\n\n\t\tregister longword L_temp;\n\n\t\tL_temp   = SASR( dp[k - Nc], 3 );\n\t\tL_power += L_temp * L_temp;\n\t}\n\tL_power <<= 1;\t/* from L_MULT */\n\n\t/*  Normalization of L_max and L_power\n\t */\n\n\tif (L_max <= 0)  {\n\t\t*bc_out = 0;\n\t\treturn;\n\t}\n\tif (L_max >= L_power) {\n\t\t*bc_out = 3;\n\t\treturn;\n\t}\n\n\ttemp = gsm_norm( L_power );\n\n\tR = SASR( L_max   << temp, 16 );\n\tS = SASR( L_power << temp, 16 );\n\n\t/*  Coding of the LTP gain\n\t */\n\n\t/*  Table 4.3a must be used to obtain the level DLB[i] for the\n\t *  quantization of the LTP gain b to get the coded version bc.\n\t */\n\tfor (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;\n\t*bc_out = bc;\n}\n\n#endif \t/* LTP_CUT */\n\nstatic void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),\n\tregister word\t* d,\t\t/* [0..39]\tIN\t*/\n\tregister word\t* dp,\t\t/* [-120..-1]\tIN\t*/\n\tword\t\t* bc_out,\t/* \t\tOUT\t*/\n\tword\t\t* Nc_out\t/* \t\tOUT\t*/\n)\n{\n\tregister int  \tk, lambda;\n\tword\t\tNc, bc;\n\tword\t\twt[40];\n\n\tlongword\tL_max, L_power;\n\tword\t\tR, S, dmax, scal;\n\tregister word\ttemp;\n\n\t/*  Search of the optimum scaling of d[0..39].\n\t */\n\tdmax = 0;\n\n\tfor (k = 0; k <= 39; k++) {\n\t\ttemp = d[k];\n\t\ttemp = GSM_ABS( temp );\n\t\tif (temp > dmax) dmax = temp;\n\t}\n\n\ttemp = 0;\n\tif (dmax == 0) scal = 0;\n\telse {\n\t\tassert(dmax > 0);\n\t\ttemp = gsm_norm( (longword)dmax << 16 );\n\t}\n\n\tif (temp > 6) scal = 0;\n\telse scal = 6 - temp;\n\n\tassert(scal >= 0);\n\n\t/*  Initialization of a working array wt\n\t */\n\n\tfor (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal );\n\n\t/* Search for the maximum cross-correlation and coding of the LTP lag\n\t */\n\tL_max = 0;\n\tNc    = 40;\t/* index for the maximum cross-correlation */\n\n\tfor (lambda = 40; lambda <= 120; lambda++) {\n\n# undef STEP\n#\t\tdefine STEP(k) \t(longword)wt[k] * dp[k - lambda]\n\n\t\tregister longword L_result;\n\n\t\tL_result  = STEP(0)  ; L_result += STEP(1) ;\n\t\tL_result += STEP(2)  ; L_result += STEP(3) ;\n\t\tL_result += STEP(4)  ; L_result += STEP(5)  ;\n\t\tL_result += STEP(6)  ; L_result += STEP(7)  ;\n\t\tL_result += STEP(8)  ; L_result += STEP(9)  ;\n\t\tL_result += STEP(10) ; L_result += STEP(11) ;\n\t\tL_result += STEP(12) ; L_result += STEP(13) ;\n\t\tL_result += STEP(14) ; L_result += STEP(15) ;\n\t\tL_result += STEP(16) ; L_result += STEP(17) ;\n\t\tL_result += STEP(18) ; L_result += STEP(19) ;\n\t\tL_result += STEP(20) ; L_result += STEP(21) ;\n\t\tL_result += STEP(22) ; L_result += STEP(23) ;\n\t\tL_result += STEP(24) ; L_result += STEP(25) ;\n\t\tL_result += STEP(26) ; L_result += STEP(27) ;\n\t\tL_result += STEP(28) ; L_result += STEP(29) ;\n\t\tL_result += STEP(30) ; L_result += STEP(31) ;\n\t\tL_result += STEP(32) ; L_result += STEP(33) ;\n\t\tL_result += STEP(34) ; L_result += STEP(35) ;\n\t\tL_result += STEP(36) ; L_result += STEP(37) ;\n\t\tL_result += STEP(38) ; L_result += STEP(39) ;\n\n\t\tif (L_result > L_max) {\n\n\t\t\tNc    = lambda;\n\t\t\tL_max = L_result;\n\t\t}\n\t}\n\n\t*Nc_out = Nc;\n\n\tL_max <<= 1;\n\n\t/*  Rescaling of L_max\n\t */\n\tassert(scal <= 100 && scal >=  -100);\n\tL_max = L_max >> (6 - scal);\t/* sub(6, scal) */\n\n\tassert( Nc <= 120 && Nc >= 40);\n\n\t/*   Compute the power of the reconstructed short term residual\n\t *   signal dp[..]\n\t */\n\tL_power = 0;\n\tfor (k = 0; k <= 39; k++) {\n\n\t\tregister longword L_temp;\n\n\t\tL_temp   = SASR( dp[k - Nc], 3 );\n\t\tL_power += L_temp * L_temp;\n\t}\n\tL_power <<= 1;\t/* from L_MULT */\n\n\t/*  Normalization of L_max and L_power\n\t */\n\n\tif (L_max <= 0)  {\n\t\t*bc_out = 0;\n\t\treturn;\n\t}\n\tif (L_max >= L_power) {\n\t\t*bc_out = 3;\n\t\treturn;\n\t}\n\n\ttemp = gsm_norm( L_power );\n\n\tR = SASR( L_max   << temp, 16 );\n\tS = SASR( L_power << temp, 16 );\n\n\t/*  Coding of the LTP gain\n\t */\n\n\t/*  Table 4.3a must be used to obtain the level DLB[i] for the\n\t *  quantization of the LTP gain b to get the coded version bc.\n\t */\n\tfor (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;\n\t*bc_out = bc;\n}\n\n#else\t/* USE_FLOAT_MUL */\n\n#ifdef\tLTP_CUT\n\nstatic void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out),\n\tstruct gsm_state * st,\t\t/*              IN \t*/\n\tregister word\t* d,\t\t/* [0..39]\tIN\t*/\n\tregister word\t* dp,\t\t/* [-120..-1]\tIN\t*/\n\tword\t\t* bc_out,\t/* \t\tOUT\t*/\n\tword\t\t* Nc_out\t/* \t\tOUT\t*/\n)\n{\n\tregister int  \tk, lambda;\n\tword\t\tNc, bc;\n\tword\t\tltp_cut;\n\n\tfloat\t\twt_float[40];\n\tfloat\t\tdp_float_base[120], * dp_float = dp_float_base + 120;\n\n\tlongword\tL_max, L_power;\n\tword\t\tR, S, dmax, scal;\n\tregister word\ttemp;\n\n\t/*  Search of the optimum scaling of d[0..39].\n\t */\n\tdmax = 0;\n\n\tfor (k = 0; k <= 39; k++) {\n\t\ttemp = d[k];\n\t\ttemp = GSM_ABS( temp );\n\t\tif (temp > dmax) dmax = temp;\n\t}\n\n\ttemp = 0;\n\tif (dmax == 0) scal = 0;\n\telse {\n\t\tassert(dmax > 0);\n\t\ttemp = gsm_norm( (longword)dmax << 16 );\n\t}\n\n\tif (temp > 6) scal = 0;\n\telse scal = 6 - temp;\n\n\tassert(scal >= 0);\n\tltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100; \n\n\n\t/*  Initialization of a working array wt\n\t */\n\n\tfor (k = 0; k < 40; k++) {\n\t\tregister word w = SASR( d[k], scal );\n\t\tif (w < 0 ? w > -ltp_cut : w < ltp_cut) {\n\t\t\twt_float[k] = 0.0;\n\t\t}\n\t\telse {\n\t\t\twt_float[k] =  w;\n\t\t}\n\t}\n\tfor (k = -120; k <  0; k++) dp_float[k] =  dp[k];\n\n\t/* Search for the maximum cross-correlation and coding of the LTP lag\n\t */\n\tL_max = 0;\n\tNc    = 40;\t/* index for the maximum cross-correlation */\n\n\tfor (lambda = 40; lambda <= 120; lambda += 9) {\n\n\t\t/*  Calculate L_result for l = lambda .. lambda + 9.\n\t\t */\n\t\tregister float *lp = dp_float - lambda;\n\n\t\tregister float\tW;\n\t\tregister float\ta = lp[-8], b = lp[-7], c = lp[-6],\n\t\t\t\td = lp[-5], e = lp[-4], f = lp[-3],\n\t\t\t\tg = lp[-2], h = lp[-1];\n\t\tregister float  E; \n\t\tregister float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,\n\t\t\t\tS5 = 0, S6 = 0, S7 = 0, S8 = 0;\n\n#\t\tundef STEP\n#\t\tdefine\tSTEP(K, a, b, c, d, e, f, g, h) \\\n\t\t\tif ((W = wt_float[K]) != 0.0) {\t\\\n\t\t\tE = W * a; S8 += E;\t\t\\\n\t\t\tE = W * b; S7 += E;\t\t\\\n\t\t\tE = W * c; S6 += E;\t\t\\\n\t\t\tE = W * d; S5 += E;\t\t\\\n\t\t\tE = W * e; S4 += E;\t\t\\\n\t\t\tE = W * f; S3 += E;\t\t\\\n\t\t\tE = W * g; S2 += E;\t\t\\\n\t\t\tE = W * h; S1 += E;\t\t\\\n\t\t\ta  = lp[K];\t\t\t\\\n\t\t\tE = W * a; S0 += E; } else (a = lp[K])\n\n#\t\tdefine\tSTEP_A(K)\tSTEP(K, a, b, c, d, e, f, g, h)\n#\t\tdefine\tSTEP_B(K)\tSTEP(K, b, c, d, e, f, g, h, a)\n#\t\tdefine\tSTEP_C(K)\tSTEP(K, c, d, e, f, g, h, a, b)\n#\t\tdefine\tSTEP_D(K)\tSTEP(K, d, e, f, g, h, a, b, c)\n#\t\tdefine\tSTEP_E(K)\tSTEP(K, e, f, g, h, a, b, c, d)\n#\t\tdefine\tSTEP_F(K)\tSTEP(K, f, g, h, a, b, c, d, e)\n#\t\tdefine\tSTEP_G(K)\tSTEP(K, g, h, a, b, c, d, e, f)\n#\t\tdefine\tSTEP_H(K)\tSTEP(K, h, a, b, c, d, e, f, g)\n\n\t\tSTEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);\n\t\tSTEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);\n\n\t\tSTEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);\n\t\tSTEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);\n\n\t\tSTEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);\n\t\tSTEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);\n\n\t\tSTEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);\n\t\tSTEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);\n\n\t\tSTEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);\n\t\tSTEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);\n\n\t\tif (S0 > L_max) { L_max = S0; Nc = lambda;     }\n\t\tif (S1 > L_max) { L_max = S1; Nc = lambda + 1; }\n\t\tif (S2 > L_max) { L_max = S2; Nc = lambda + 2; }\n\t\tif (S3 > L_max) { L_max = S3; Nc = lambda + 3; }\n\t\tif (S4 > L_max) { L_max = S4; Nc = lambda + 4; }\n\t\tif (S5 > L_max) { L_max = S5; Nc = lambda + 5; }\n\t\tif (S6 > L_max) { L_max = S6; Nc = lambda + 6; }\n\t\tif (S7 > L_max) { L_max = S7; Nc = lambda + 7; }\n\t\tif (S8 > L_max) { L_max = S8; Nc = lambda + 8; }\n\n\t}\n\t*Nc_out = Nc;\n\n\tL_max <<= 1;\n\n\t/*  Rescaling of L_max\n\t */\n\tassert(scal <= 100 && scal >=  -100);\n\tL_max = L_max >> (6 - scal);\t/* sub(6, scal) */\n\n\tassert( Nc <= 120 && Nc >= 40);\n\n\t/*   Compute the power of the reconstructed short term residual\n\t *   signal dp[..]\n\t */\n\tL_power = 0;\n\tfor (k = 0; k <= 39; k++) {\n\n\t\tregister longword L_temp;\n\n\t\tL_temp   = SASR( dp[k - Nc], 3 );\n\t\tL_power += L_temp * L_temp;\n\t}\n\tL_power <<= 1;\t/* from L_MULT */\n\n\t/*  Normalization of L_max and L_power\n\t */\n\n\tif (L_max <= 0)  {\n\t\t*bc_out = 0;\n\t\treturn;\n\t}\n\tif (L_max >= L_power) {\n\t\t*bc_out = 3;\n\t\treturn;\n\t}\n\n\ttemp = gsm_norm( L_power );\n\n\tR = SASR( L_max   << temp, 16 );\n\tS = SASR( L_power << temp, 16 );\n\n\t/*  Coding of the LTP gain\n\t */\n\n\t/*  Table 4.3a must be used to obtain the level DLB[i] for the\n\t *  quantization of the LTP gain b to get the coded version bc.\n\t */\n\tfor (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;\n\t*bc_out = bc;\n}\n\n#endif /* LTP_CUT */\n\nstatic void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),\n\tregister word\t* d,\t\t/* [0..39]\tIN\t*/\n\tregister word\t* dp,\t\t/* [-120..-1]\tIN\t*/\n\tword\t\t* bc_out,\t/* \t\tOUT\t*/\n\tword\t\t* Nc_out\t/* \t\tOUT\t*/\n)\n{\n\tregister int  \tk, lambda;\n\tword\t\tNc, bc;\n\n\tfloat\t\twt_float[40];\n\tfloat\t\tdp_float_base[120], * dp_float = dp_float_base + 120;\n\n\tlongword\tL_max, L_power;\n\tword\t\tR, S, dmax, scal;\n\tregister word\ttemp;\n\n\t/*  Search of the optimum scaling of d[0..39].\n\t */\n\tdmax = 0;\n\n\tfor (k = 0; k <= 39; k++) {\n\t\ttemp = d[k];\n\t\ttemp = GSM_ABS( temp );\n\t\tif (temp > dmax) dmax = temp;\n\t}\n\n\ttemp = 0;\n\tif (dmax == 0) scal = 0;\n\telse {\n\t\tassert(dmax > 0);\n\t\ttemp = gsm_norm( (longword)dmax << 16 );\n\t}\n\n\tif (temp > 6) scal = 0;\n\telse scal = 6 - temp;\n\n\tassert(scal >= 0);\n\n\t/*  Initialization of a working array wt\n\t */\n\n\tfor (k =    0; k < 40; k++) wt_float[k] =  SASR( d[k], scal );\n\tfor (k = -120; k <  0; k++) dp_float[k] =  dp[k];\n\n\t/* Search for the maximum cross-correlation and coding of the LTP lag\n\t */\n\tL_max = 0;\n\tNc    = 40;\t/* index for the maximum cross-correlation */\n\n\tfor (lambda = 40; lambda <= 120; lambda += 9) {\n\n\t\t/*  Calculate L_result for l = lambda .. lambda + 9.\n\t\t */\n\t\tregister float *lp = dp_float - lambda;\n\n\t\tregister float\tW;\n\t\tregister float\ta = lp[-8], b = lp[-7], c = lp[-6],\n\t\t\t\td = lp[-5], e = lp[-4], f = lp[-3],\n\t\t\t\tg = lp[-2], h = lp[-1];\n\t\tregister float  E; \n\t\tregister float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,\n\t\t\t\tS5 = 0, S6 = 0, S7 = 0, S8 = 0;\n\n#\t\tundef STEP\n#\t\tdefine\tSTEP(K, a, b, c, d, e, f, g, h) \\\n\t\t\tW = wt_float[K];\t\t\\\n\t\t\tE = W * a; S8 += E;\t\t\\\n\t\t\tE = W * b; S7 += E;\t\t\\\n\t\t\tE = W * c; S6 += E;\t\t\\\n\t\t\tE = W * d; S5 += E;\t\t\\\n\t\t\tE = W * e; S4 += E;\t\t\\\n\t\t\tE = W * f; S3 += E;\t\t\\\n\t\t\tE = W * g; S2 += E;\t\t\\\n\t\t\tE = W * h; S1 += E;\t\t\\\n\t\t\ta  = lp[K];\t\t\t\\\n\t\t\tE = W * a; S0 += E\n\n#\t\tdefine\tSTEP_A(K)\tSTEP(K, a, b, c, d, e, f, g, h)\n#\t\tdefine\tSTEP_B(K)\tSTEP(K, b, c, d, e, f, g, h, a)\n#\t\tdefine\tSTEP_C(K)\tSTEP(K, c, d, e, f, g, h, a, b)\n#\t\tdefine\tSTEP_D(K)\tSTEP(K, d, e, f, g, h, a, b, c)\n#\t\tdefine\tSTEP_E(K)\tSTEP(K, e, f, g, h, a, b, c, d)\n#\t\tdefine\tSTEP_F(K)\tSTEP(K, f, g, h, a, b, c, d, e)\n#\t\tdefine\tSTEP_G(K)\tSTEP(K, g, h, a, b, c, d, e, f)\n#\t\tdefine\tSTEP_H(K)\tSTEP(K, h, a, b, c, d, e, f, g)\n\n\t\tSTEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);\n\t\tSTEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);\n\n\t\tSTEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);\n\t\tSTEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);\n\n\t\tSTEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);\n\t\tSTEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);\n\n\t\tSTEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);\n\t\tSTEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);\n\n\t\tSTEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);\n\t\tSTEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);\n\n\t\tif (S0 > L_max) { L_max = S0; Nc = lambda;     }\n\t\tif (S1 > L_max) { L_max = S1; Nc = lambda + 1; }\n\t\tif (S2 > L_max) { L_max = S2; Nc = lambda + 2; }\n\t\tif (S3 > L_max) { L_max = S3; Nc = lambda + 3; }\n\t\tif (S4 > L_max) { L_max = S4; Nc = lambda + 4; }\n\t\tif (S5 > L_max) { L_max = S5; Nc = lambda + 5; }\n\t\tif (S6 > L_max) { L_max = S6; Nc = lambda + 6; }\n\t\tif (S7 > L_max) { L_max = S7; Nc = lambda + 7; }\n\t\tif (S8 > L_max) { L_max = S8; Nc = lambda + 8; }\n\t}\n\t*Nc_out = Nc;\n\n\tL_max <<= 1;\n\n\t/*  Rescaling of L_max\n\t */\n\tassert(scal <= 100 && scal >=  -100);\n\tL_max = L_max >> (6 - scal);\t/* sub(6, scal) */\n\n\tassert( Nc <= 120 && Nc >= 40);\n\n\t/*   Compute the power of the reconstructed short term residual\n\t *   signal dp[..]\n\t */\n\tL_power = 0;\n\tfor (k = 0; k <= 39; k++) {\n\n\t\tregister longword L_temp;\n\n\t\tL_temp   = SASR( dp[k - Nc], 3 );\n\t\tL_power += L_temp * L_temp;\n\t}\n\tL_power <<= 1;\t/* from L_MULT */\n\n\t/*  Normalization of L_max and L_power\n\t */\n\n\tif (L_max <= 0)  {\n\t\t*bc_out = 0;\n\t\treturn;\n\t}\n\tif (L_max >= L_power) {\n\t\t*bc_out = 3;\n\t\treturn;\n\t}\n\n\ttemp = gsm_norm( L_power );\n\n\tR = SASR( L_max   << temp, 16 );\n\tS = SASR( L_power << temp, 16 );\n\n\t/*  Coding of the LTP gain\n\t */\n\n\t/*  Table 4.3a must be used to obtain the level DLB[i] for the\n\t *  quantization of the LTP gain b to get the coded version bc.\n\t */\n\tfor (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;\n\t*bc_out = bc;\n}\n\n#ifdef\tFAST\n#ifdef\tLTP_CUT\n\nstatic void Cut_Fast_Calculation_of_the_LTP_parameters P5((st,\n\t\t\t\t\t\t\td,dp,bc_out,Nc_out),\n\tstruct gsm_state * st,\t\t/*              IN\t*/\n\tregister word\t* d,\t\t/* [0..39]\tIN\t*/\n\tregister word\t* dp,\t\t/* [-120..-1]\tIN\t*/\n\tword\t\t* bc_out,\t/* \t\tOUT\t*/\n\tword\t\t* Nc_out\t/* \t\tOUT\t*/\n)\n{\n\tregister int  \tk, lambda;\n\tregister float\twt_float;\n\tword\t\tNc, bc;\n\tword\t\twt_max, best_k, ltp_cut;\n\n\tfloat\t\tdp_float_base[120], * dp_float = dp_float_base + 120;\n\n\tregister float\tL_result, L_max, L_power;\n\n\twt_max = 0;\n\n\tfor (k = 0; k < 40; ++k) {\n\t\tif      ( d[k] > wt_max) wt_max =  d[best_k = k];\n\t\telse if (-d[k] > wt_max) wt_max = -d[best_k = k];\n\t}\n\n\tassert(wt_max >= 0);\n\twt_float = (float)wt_max;\n\n\tfor (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];\n\n\t/* Search for the maximum cross-correlation and coding of the LTP lag\n\t */\n\tL_max = 0;\n\tNc    = 40;\t/* index for the maximum cross-correlation */\n\n\tfor (lambda = 40; lambda <= 120; lambda++) {\n\t\tL_result = wt_float * dp_float[best_k - lambda];\n\t\tif (L_result > L_max) {\n\t\t\tNc    = lambda;\n\t\t\tL_max = L_result;\n\t\t}\n\t}\n\n\t*Nc_out = Nc;\n\tif (L_max <= 0.)  {\n\t\t*bc_out = 0;\n\t\treturn;\n\t}\n\n\t/*  Compute the power of the reconstructed short term residual\n\t *  signal dp[..]\n\t */\n\tdp_float -= Nc;\n\tL_power = 0;\n\tfor (k = 0; k < 40; ++k) {\n\t\tregister float f = dp_float[k];\n\t\tL_power += f * f;\n\t}\n\n\tif (L_max >= L_power) {\n\t\t*bc_out = 3;\n\t\treturn;\n\t}\n\n\t/*  Coding of the LTP gain\n\t *  Table 4.3a must be used to obtain the level DLB[i] for the\n\t *  quantization of the LTP gain b to get the coded version bc.\n\t */\n\tlambda = L_max / L_power * 32768.;\n\tfor (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;\n\t*bc_out = bc;\n}\n\n#endif /* LTP_CUT */\n\nstatic void Fast_Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),\n\tregister word\t* d,\t\t/* [0..39]\tIN\t*/\n\tregister word\t* dp,\t\t/* [-120..-1]\tIN\t*/\n\tword\t\t* bc_out,\t/* \t\tOUT\t*/\n\tword\t\t* Nc_out\t/* \t\tOUT\t*/\n)\n{\n\tregister int  \tk, lambda;\n\tword\t\tNc, bc;\n\n\tfloat\t\twt_float[40];\n\tfloat\t\tdp_float_base[120], * dp_float = dp_float_base + 120;\n\n\tregister float\tL_max, L_power;\n\n\tfor (k = 0; k < 40; ++k) wt_float[k] = (float)d[k];\n\tfor (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];\n\n\t/* Search for the maximum cross-correlation and coding of the LTP lag\n\t */\n\tL_max = 0;\n\tNc    = 40;\t/* index for the maximum cross-correlation */\n\n\tfor (lambda = 40; lambda <= 120; lambda += 9) {\n\n\t\t/*  Calculate L_result for l = lambda .. lambda + 9.\n\t\t */\n\t\tregister float *lp = dp_float - lambda;\n\n\t\tregister float\tW;\n\t\tregister float\ta = lp[-8], b = lp[-7], c = lp[-6],\n\t\t\t\td = lp[-5], e = lp[-4], f = lp[-3],\n\t\t\t\tg = lp[-2], h = lp[-1];\n\t\tregister float  E; \n\t\tregister float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,\n\t\t\t\tS5 = 0, S6 = 0, S7 = 0, S8 = 0;\n\n#\t\tundef STEP\n#\t\tdefine\tSTEP(K, a, b, c, d, e, f, g, h) \\\n\t\t\tW = wt_float[K];\t\t\\\n\t\t\tE = W * a; S8 += E;\t\t\\\n\t\t\tE = W * b; S7 += E;\t\t\\\n\t\t\tE = W * c; S6 += E;\t\t\\\n\t\t\tE = W * d; S5 += E;\t\t\\\n\t\t\tE = W * e; S4 += E;\t\t\\\n\t\t\tE = W * f; S3 += E;\t\t\\\n\t\t\tE = W * g; S2 += E;\t\t\\\n\t\t\tE = W * h; S1 += E;\t\t\\\n\t\t\ta  = lp[K];\t\t\t\\\n\t\t\tE = W * a; S0 += E\n\n#\t\tdefine\tSTEP_A(K)\tSTEP(K, a, b, c, d, e, f, g, h)\n#\t\tdefine\tSTEP_B(K)\tSTEP(K, b, c, d, e, f, g, h, a)\n#\t\tdefine\tSTEP_C(K)\tSTEP(K, c, d, e, f, g, h, a, b)\n#\t\tdefine\tSTEP_D(K)\tSTEP(K, d, e, f, g, h, a, b, c)\n#\t\tdefine\tSTEP_E(K)\tSTEP(K, e, f, g, h, a, b, c, d)\n#\t\tdefine\tSTEP_F(K)\tSTEP(K, f, g, h, a, b, c, d, e)\n#\t\tdefine\tSTEP_G(K)\tSTEP(K, g, h, a, b, c, d, e, f)\n#\t\tdefine\tSTEP_H(K)\tSTEP(K, h, a, b, c, d, e, f, g)\n\n\t\tSTEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);\n\t\tSTEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);\n\n\t\tSTEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);\n\t\tSTEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);\n\n\t\tSTEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);\n\t\tSTEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);\n\n\t\tSTEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);\n\t\tSTEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);\n\n\t\tSTEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);\n\t\tSTEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);\n\n\t\tif (S0 > L_max) { L_max = S0; Nc = lambda;     }\n\t\tif (S1 > L_max) { L_max = S1; Nc = lambda + 1; }\n\t\tif (S2 > L_max) { L_max = S2; Nc = lambda + 2; }\n\t\tif (S3 > L_max) { L_max = S3; Nc = lambda + 3; }\n\t\tif (S4 > L_max) { L_max = S4; Nc = lambda + 4; }\n\t\tif (S5 > L_max) { L_max = S5; Nc = lambda + 5; }\n\t\tif (S6 > L_max) { L_max = S6; Nc = lambda + 6; }\n\t\tif (S7 > L_max) { L_max = S7; Nc = lambda + 7; }\n\t\tif (S8 > L_max) { L_max = S8; Nc = lambda + 8; }\n\t}\n\t*Nc_out = Nc;\n\n\tif (L_max <= 0.)  {\n\t\t*bc_out = 0;\n\t\treturn;\n\t}\n\n\t/*  Compute the power of the reconstructed short term residual\n\t *  signal dp[..]\n\t */\n\tdp_float -= Nc;\n\tL_power = 0;\n\tfor (k = 0; k < 40; ++k) {\n\t\tregister float f = dp_float[k];\n\t\tL_power += f * f;\n\t}\n\n\tif (L_max >= L_power) {\n\t\t*bc_out = 3;\n\t\treturn;\n\t}\n\n\t/*  Coding of the LTP gain\n\t *  Table 4.3a must be used to obtain the level DLB[i] for the\n\t *  quantization of the LTP gain b to get the coded version bc.\n\t */\n\tlambda = L_max / L_power * 32768.;\n\tfor (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;\n\t*bc_out = bc;\n}\n\n#endif\t/* FAST \t */\n#endif\t/* USE_FLOAT_MUL */\n\n\n/* 4.2.12 */\n\nstatic void Long_term_analysis_filtering P6((bc,Nc,dp,d,dpp,e),\n\tword\t\tbc,\t/* \t\t\t\t\tIN  */\n\tword\t\tNc,\t/* \t\t\t\t\tIN  */\n\tregister word\t* dp,\t/* previous d\t[-120..-1]\t\tIN  */\n\tregister word\t* d,\t/* d\t\t[0..39]\t\t\tIN  */\n\tregister word\t* dpp,\t/* estimate\t[0..39]\t\t\tOUT */\n\tregister word\t* e\t/* long term res. signal [0..39]\tOUT */\n)\n/*\n *  In this part, we have to decode the bc parameter to compute\n *  the samples of the estimate dpp[0..39].  The decoding of bc needs the\n *  use of table 4.3b.  The long term residual signal e[0..39]\n *  is then calculated to be fed to the RPE encoding section.\n */\n{\n\tregister int      k;\n\tregister longword ltmp;\n\n#\tundef STEP\n#\tdefine STEP(BP)\t\t\t\t\t\\\n\tfor (k = 0; k <= 39; k++) {\t\t\t\\\n\t\tdpp[k]  = GSM_MULT_R( BP, dp[k - Nc]);\t\\\n\t\te[k]\t= GSM_SUB( d[k], dpp[k] );\t\\\n\t}\n\n\tswitch (bc) {\n\tcase 0:\tSTEP(  3277 ); break;\n\tcase 1:\tSTEP( 11469 ); break;\n\tcase 2: STEP( 21299 ); break;\n\tcase 3: STEP( 32767 ); break; \n\t}\n}\n\nvoid Gsm_Long_Term_Predictor P7((S,d,dp,e,dpp,Nc,bc), \t/* 4x for 160 samples */\n\n\tstruct gsm_state\t* S,\n\n\tword\t* d,\t/* [0..39]   residual signal\tIN\t*/\n\tword\t* dp,\t/* [-120..-1] d'\t\tIN\t*/\n\n\tword\t* e,\t/* [0..39] \t\t\tOUT\t*/\n\tword\t* dpp,\t/* [0..39] \t\t\tOUT\t*/\n\tword\t* Nc,\t/* correlation lag\t\tOUT\t*/\n\tword\t* bc\t/* gain factor\t\t\tOUT\t*/\n)\n{\n\tassert( d  ); assert( dp ); assert( e  );\n\tassert( dpp); assert( Nc ); assert( bc );\n\n#if defined(FAST) && defined(USE_FLOAT_MUL)\n\tif (S->fast) \n#if   defined (LTP_CUT)\n\t\tif (S->ltp_cut)\n\t\t\tCut_Fast_Calculation_of_the_LTP_parameters(S,\n\t\t\t\td, dp, bc, Nc);\n\t\telse\n#endif /* LTP_CUT */\n\t\t\tFast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc );\n\telse \n#endif /* FAST & USE_FLOAT_MUL */\n#ifdef LTP_CUT\n\t\tif (S->ltp_cut)\n\t\t\tCut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc);\n\t\telse\n#endif\n\t\t\tCalculation_of_the_LTP_parameters(d, dp, bc, Nc);\n\n\tLong_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e );\n}\n\n/* 4.3.2 */\nvoid Gsm_Long_Term_Synthesis_Filtering P5((S,Ncr,bcr,erp,drp),\n\tstruct gsm_state\t* S,\n\n\tword\t\t\tNcr,\n\tword\t\t\tbcr,\n\tregister word\t\t* erp,\t   /* [0..39]\t\t  \t IN */\n\tregister word\t\t* drp\t   /* [-120..-1] IN, [-120..40] OUT */\n)\n/*\n *  This procedure uses the bcr and Ncr parameter to realize the\n *  long term synthesis filtering.  The decoding of bcr needs\n *  table 4.3b.\n */\n{\n\tregister longword\tltmp;\t/* for ADD */\n\tregister int \t\tk;\n\tword\t\t\tbrp, drpp, Nr;\n\n\t/*  Check the limits of Nr.\n\t */\n\tNr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr;\n\tS->nrp = Nr;\n\tassert(Nr >= 40 && Nr <= 120);\n\n\t/*  Decoding of the LTP gain bcr\n\t */\n\tbrp = gsm_QLB[ bcr ];\n\n\t/*  Computation of the reconstructed short term residual \n\t *  signal drp[0..39]\n\t */\n\tassert(brp != MIN_WORD);\n\n\tfor (k = 0; k <= 39; k++) {\n\t\tdrpp   = GSM_MULT_R( brp, drp[ k - Nr ] );\n\t\tdrp[k] = GSM_ADD( erp[k], drpp );\n\t}\n\n\t/*\n\t *  Update of the reconstructed short term residual signal\n\t *  drp[ -1..-120 ]\n\t */\n\n\tfor (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ];\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/lpc.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/lpc.c,v 1.5 1994/12/30 23:14:54 jutta Exp $ */\n\n#include \"config.h\"\n#include <stdio.h>\n#include <assert.h>\n\n#include \"private.h\"\n\n#include \"gsm.h\"\n#include \"proto.h\"\n\n#undef\tP\n\n/*\n *  4.2.4 .. 4.2.7 LPC ANALYSIS SECTION\n */\n\n/* 4.2.4 */\n\n\nstatic void Autocorrelation P2((s, L_ACF),\n\tword     * s,\t\t/* [0..159]\tIN/OUT  */\n \tlongword * L_ACF)\t/* [0..8]\tOUT     */\n/*\n *  The goal is to compute the array L_ACF[k].  The signal s[i] must\n *  be scaled in order to avoid an overflow situation.\n */\n{\n\tregister int\tk, i;\n\n\tword\t\ttemp, smax, scalauto;\n\n#ifdef\tUSE_FLOAT_MUL\n\tfloat\t\tfloat_s[160];\n#endif\n\n\t/*  Dynamic scaling of the array  s[0..159]\n\t */\n\n\t/*  Search for the maximum.\n\t */\n\tsmax = 0;\n\tfor (k = 0; k <= 159; k++) {\n\t\ttemp = GSM_ABS( s[k] );\n\t\tif (temp > smax) smax = temp;\n\t}\n\n\t/*  Computation of the scaling factor.\n\t */\n\tif (smax == 0) scalauto = 0;\n\telse {\n\t\tassert(smax > 0);\n\t\tscalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */\n\t}\n\n\t/*  Scaling of the array s[0...159]\n\t */\n\n\tif (scalauto > 0) {\n\n# ifdef USE_FLOAT_MUL\n#   define SCALE(n)\t\\\n\tcase n: for (k = 0; k <= 159; k++) \\\n\t\t\tfloat_s[k] = (float)\t\\\n\t\t\t\t(s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\\\n\t\tbreak;\n# else \n#   define SCALE(n)\t\\\n\tcase n: for (k = 0; k <= 159; k++) \\\n\t\t\ts[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\\\n\t\tbreak;\n# endif /* USE_FLOAT_MUL */\n\n\t\tswitch (scalauto) {\n\t\tSCALE(1)\n\t\tSCALE(2)\n\t\tSCALE(3)\n\t\tSCALE(4)\n\t\t}\n# undef\tSCALE\n\t}\n# ifdef\tUSE_FLOAT_MUL\n\telse for (k = 0; k <= 159; k++) float_s[k] = (float) s[k];\n# endif\n\n\t/*  Compute the L_ACF[..].\n\t */\n\t{\n# ifdef\tUSE_FLOAT_MUL\n\t\tregister float * sp = float_s;\n\t\tregister float   sl = *sp;\n\n#\t\tdefine STEP(k)\t L_ACF[k] += (longword)(sl * sp[ -(k) ]);\n# else\n\t\tword  * sp = s;\n\t\tword    sl = *sp;\n\n#\t\tdefine STEP(k)\t L_ACF[k] += ((longword)sl * sp[ -(k) ]);\n# endif\n\n#\tdefine NEXTI\t sl = *++sp\n\n\n\tfor (k = 9; k--; L_ACF[k] = 0) ;\n\n\tSTEP (0);\n\tNEXTI;\n\tSTEP(0); STEP(1);\n\tNEXTI;\n\tSTEP(0); STEP(1); STEP(2);\n\tNEXTI;\n\tSTEP(0); STEP(1); STEP(2); STEP(3);\n\tNEXTI;\n\tSTEP(0); STEP(1); STEP(2); STEP(3); STEP(4);\n\tNEXTI;\n\tSTEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5);\n\tNEXTI;\n\tSTEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6);\n\tNEXTI;\n\tSTEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7);\n\n\tfor (i = 8; i <= 159; i++) {\n\n\t\tNEXTI;\n\n\t\tSTEP(0);\n\t\tSTEP(1); STEP(2); STEP(3); STEP(4);\n\t\tSTEP(5); STEP(6); STEP(7); STEP(8);\n\t}\n\n\tfor (k = 9; k--; L_ACF[k] <<= 1) ; \n\n\t}\n\t/*   Rescaling of the array s[0..159]\n\t */\n\tif (scalauto > 0) {\n\t\tassert(scalauto <= 4); \n\t\tfor (k = 160; k--; *s++ <<= scalauto) ;\n\t}\n}\n\n#if defined(USE_FLOAT_MUL) && defined(FAST)\n\nstatic void Fast_Autocorrelation P2((s, L_ACF),\n\tword * s,\t\t/* [0..159]\tIN/OUT  */\n \tlongword * L_ACF)\t/* [0..8]\tOUT     */\n{\n\tregister int\tk, i;\n\tfloat f_L_ACF[9];\n\tfloat scale;\n\n\tfloat          s_f[160];\n\tregister float *sf = s_f;\n\n\tfor (i = 0; i < 160; ++i) sf[i] = s[i];\n\tfor (k = 0; k <= 8; k++) {\n\t\tregister float L_temp2 = 0;\n\t\tregister float *sfl = sf - k;\n\t\tfor (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i];\n\t\tf_L_ACF[k] = L_temp2;\n\t}\n\tscale = MAX_LONGWORD / f_L_ACF[0];\n\n\tfor (k = 0; k <= 8; k++) {\n\t\tL_ACF[k] = f_L_ACF[k] * scale;\n\t}\n}\n#endif\t/* defined (USE_FLOAT_MUL) && defined (FAST) */\n\n/* 4.2.5 */\n\nstatic void Reflection_coefficients P2( (L_ACF, r),\n\tlongword\t* L_ACF,\t\t/* 0...8\tIN\t*/\n\tregister word\t* r\t\t\t/* 0...7\tOUT \t*/\n)\n{\n\tregister int\ti, m, n;\n\tregister word\ttemp;\n\tregister longword ltmp;\n\tword\t\tACF[9];\t/* 0..8 */\n\tword\t\tP[  9];\t/* 0..8 */\n\tword\t\tK[  9]; /* 2..8 */\n\n\t/*  Schur recursion with 16 bits arithmetic.\n\t */\n\n\tif (L_ACF[0] == 0) {\n\t\tfor (i = 8; i--; *r++ = 0) ;\n\t\treturn;\n\t}\n\n\tassert( L_ACF[0] != 0 );\n\ttemp = gsm_norm( L_ACF[0] );\n\n\tassert(temp >= 0 && temp < 32);\n\n\t/* ? overflow ? */\n\tfor (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 );\n\n\t/*   Initialize array P[..] and K[..] for the recursion.\n\t */\n\n\tfor (i = 1; i <= 7; i++) K[ i ] = ACF[ i ];\n\tfor (i = 0; i <= 8; i++) P[ i ] = ACF[ i ];\n\n\t/*   Compute reflection coefficients\n\t */\n\tfor (n = 1; n <= 8; n++, r++) {\n\n\t\ttemp = P[1];\n\t\ttemp = GSM_ABS(temp);\n\t\tif (P[0] < temp) {\n\t\t\tfor (i = n; i <= 8; i++) *r++ = 0;\n\t\t\treturn;\n\t\t}\n\n\t\t*r = gsm_div( temp, P[0] );\n\n\t\tassert(*r >= 0);\n\t\tif (P[1] > 0) *r = -*r;\t\t/* r[n] = sub(0, r[n]) */\n\t\tassert (*r != MIN_WORD);\n\t\tif (n == 8) return; \n\n\t\t/*  Schur recursion\n\t\t */\n\t\ttemp = GSM_MULT_R( P[1], *r );\n\t\tP[0] = GSM_ADD( P[0], temp );\n\n\t\tfor (m = 1; m <= 8 - n; m++) {\n\t\t\ttemp     = GSM_MULT_R( K[ m   ],    *r );\n\t\t\tP[m]     = GSM_ADD(    P[ m+1 ],  temp );\n\n\t\t\ttemp     = GSM_MULT_R( P[ m+1 ],    *r );\n\t\t\tK[m]     = GSM_ADD(    K[ m   ],  temp );\n\t\t}\n\t}\n}\n\n/* 4.2.6 */\n\nstatic void Transformation_to_Log_Area_Ratios P1((r),\n\tregister word\t* r \t\t\t/* 0..7\t   IN/OUT */\n)\n/*\n *  The following scaling for r[..] and LAR[..] has been used:\n *\n *  r[..]   = integer( real_r[..]*32768. ); -1 <= real_r < 1.\n *  LAR[..] = integer( real_LAR[..] * 16384 );\n *  with -1.625 <= real_LAR <= 1.625\n */\n{\n\tregister word\ttemp;\n\tregister int\ti;\n\n\n\t/* Computation of the LAR[0..7] from the r[0..7]\n\t */\n\tfor (i = 1; i <= 8; i++, r++) {\n\n\t\ttemp = *r;\n\t\ttemp = GSM_ABS(temp);\n\t\tassert(temp >= 0);\n\n\t\tif (temp < 22118) {\n\t\t\ttemp >>= 1;\n\t\t} else if (temp < 31130) {\n\t\t\tassert( temp >= 11059 );\n\t\t\ttemp -= 11059;\n\t\t} else {\n\t\t\tassert( temp >= 26112 );\n\t\t\ttemp -= 26112;\n\t\t\ttemp <<= 2;\n\t\t}\n\n\t\t*r = *r < 0 ? -temp : temp;\n\t\tassert( *r != MIN_WORD );\n\t}\n}\n\n/* 4.2.7 */\n\nstatic void Quantization_and_coding P1((LAR),\n\tregister word * LAR    \t/* [0..7]\tIN/OUT\t*/\n)\n{\n\tregister word\ttemp;\n\tlongword\tltmp;\n\n\n\t/*  This procedure needs four tables; the following equations\n\t *  give the optimum scaling for the constants:\n\t *  \n\t *  A[0..7] = integer( real_A[0..7] * 1024 )\n\t *  B[0..7] = integer( real_B[0..7] *  512 )\n\t *  MAC[0..7] = maximum of the LARc[0..7]\n\t *  MIC[0..7] = minimum of the LARc[0..7]\n\t */\n\n#\tundef STEP\n#\tdefine\tSTEP( A, B, MAC, MIC )\t\t\\\n\t\ttemp = GSM_MULT( A,   *LAR );\t\\\n\t\ttemp = GSM_ADD(  temp,   B );\t\\\n\t\ttemp = GSM_ADD(  temp, 256 );\t\\\n\t\ttemp = SASR(     temp,   9 );\t\\\n\t\t*LAR  =  temp>MAC ? MAC - MIC : (temp<MIC ? 0 : temp - MIC); \\\n\t\tLAR++;\n\n\tSTEP(  20480,     0,  31, -32 );\n\tSTEP(  20480,     0,  31, -32 );\n\tSTEP(  20480,  2048,  15, -16 );\n\tSTEP(  20480, -2560,  15, -16 );\n\n\tSTEP(  13964,    94,   7,  -8 );\n\tSTEP(  15360, -1792,   7,  -8 );\n\tSTEP(   8534,  -341,   3,  -4 );\n\tSTEP(   9036, -1144,   3,  -4 );\n\n#\tundef\tSTEP\n}\n\nvoid Gsm_LPC_Analysis P3((S, s,LARc),\n\tstruct gsm_state *S,\n\tword \t\t * s,\t\t/* 0..159 signals\tIN/OUT\t*/\n        word \t\t * LARc)\t/* 0..7   LARc's\tOUT\t*/\n{\n\tlongword\tL_ACF[9];\n\n#if defined(USE_FLOAT_MUL) && defined(FAST)\n\tif (S->fast) Fast_Autocorrelation (s,\t  L_ACF );\n\telse\n#endif\n\tAutocorrelation\t\t\t  (s,\t  L_ACF\t);\n\tReflection_coefficients\t\t  (L_ACF, LARc\t);\n\tTransformation_to_Log_Area_Ratios (LARc);\n\tQuantization_and_coding\t\t  (LARc);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/preprocess.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/preprocess.c,v 1.2 1994/05/10 20:18:45 jutta Exp $ */\n\n#include\t\"config.h\"\n#include\t<stdio.h>\n#include\t<assert.h>\n\n#include \"private.h\"\n\n#include\t\"gsm.h\"\n#include \t\"proto.h\"\n\n/*\t4.2.0 .. 4.2.3\tPREPROCESSING SECTION\n *  \n *  \tAfter A-law to linear conversion (or directly from the\n *   \tAto D converter) the following scaling is assumed for\n * \tinput to the RPE-LTP algorithm:\n *\n *      in:  0.1.....................12\n *\t     S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.*\n *\n *\tWhere S is the sign bit, v a valid bit, and * a \"don't care\" bit.\n * \tThe original signal is called sop[..]\n *\n *      out:   0.1................... 12 \n *\t     S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0\n */\n\n\nvoid Gsm_Preprocess P3((S, s, so),\n\tstruct gsm_state * S,\n\tword\t\t * s,\n\tword \t\t * so )\t\t/* [0..159] \tIN/OUT\t*/\n{\n\n\tword       z1 = S->z1;\n\tlongword L_z2 = S->L_z2;\n\tword \t   mp = S->mp;\n\n\tword \t   \ts1;\n\tlongword      L_s2;\n\n\tlongword      L_temp;\n\n\tword\t\tmsp, lsp;\n\tword\t\tSO;\n\n\tlongword\tltmp;\t\t/* for   ADD */\n\tulongword\tutmp;\t\t/* for L_ADD */\n\n\tregister int\t\tk = 160;\n\n\twhile (k--) {\n\n\t/*  4.2.1   Downscaling of the input signal\n\t */\n\t\tSO = SASR( *s, 3 ) << 2;\n\t\ts++;\n\n\t\tassert (SO >= -0x4000);\t/* downscaled by     */\n\t\tassert (SO <=  0x3FFC);\t/* previous routine. */\n\n\n\t/*  4.2.2   Offset compensation\n\t * \n\t *  This part implements a high-pass filter and requires extended\n\t *  arithmetic precision for the recursive part of this filter.\n\t *  The input of this procedure is the array so[0...159] and the\n\t *  output the array sof[ 0...159 ].\n\t */\n\t\t/*   Compute the non-recursive part\n\t\t */\n\n\t\ts1 = SO - z1;\t\t\t/* s1 = gsm_sub( *so, z1 ); */\n\t\tz1 = SO;\n\n\t\tassert(s1 != MIN_WORD);\n\n\t\t/*   Compute the recursive part\n\t\t */\n\t\tL_s2 = s1;\n\t\tL_s2 <<= 15;\n\n\t\t/*   Execution of a 31 bv 16 bits multiplication\n\t\t */\n\n\t\tmsp = SASR( L_z2, 15 );\n\t\tlsp = L_z2-((longword)msp<<15); /* gsm_L_sub(L_z2,(msp<<15)); */\n\n\t\tL_s2  += GSM_MULT_R( lsp, 32735 );\n\t\tL_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/\n\t\tL_z2   = GSM_L_ADD( L_temp, L_s2 );\n\n\t\t/*    Compute sof[k] with rounding\n\t\t */\n\t\tL_temp = GSM_L_ADD( L_z2, 16384 );\n\n\t/*   4.2.3  Preemphasis\n\t */\n\n\t\tmsp   = GSM_MULT_R( mp, -28180 );\n\t\tmp    = SASR( L_temp, 15 );\n\t\t*so++ = GSM_ADD( mp, msp );\n\t}\n\n\tS->z1   = z1;\n\tS->L_z2 = L_z2;\n\tS->mp   = mp;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/rpe.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/rpe.c,v 1.3 1994/05/10 20:18:46 jutta Exp $ */\n\n#include \"config.h\"\n#include <stdio.h>\n#include <assert.h>\n\n#include \"private.h\"\n\n#include \"gsm.h\"\n#include \"proto.h\"\n\n/*  4.2.13 .. 4.2.17  RPE ENCODING SECTION\n */\n\n/* 4.2.13 */\n\nstatic void Weighting_filter P2((e, x),\n\tregister word\t* e,\t\t/* signal [-5..0.39.44]\tIN  */\n\tword\t\t* x\t\t/* signal [0..39]\tOUT */\n)\n/*\n *  The coefficients of the weighting filter are stored in a table\n *  (see table 4.4).  The following scaling is used:\n *\n *\tH[0..10] = integer( real_H[ 0..10] * 8192 ); \n */\n{\n\t/* word\t\t\twt[ 50 ]; */\n\n\tregister longword\tL_result;\n\tregister int\t\tk /* , i */ ;\n\n\t/*  Initialization of a temporary working array wt[0...49]\n\t */\n\n\t/* for (k =  0; k <=  4; k++) wt[k] = 0;\n\t * for (k =  5; k <= 44; k++) wt[k] = *e++;\n\t * for (k = 45; k <= 49; k++) wt[k] = 0;\n\t *\n\t *  (e[-5..-1] and e[40..44] are allocated by the caller,\n\t *  are initially zero and are not written anywhere.)\n\t */\n\te -= 5;\n\n\t/*  Compute the signal x[0..39]\n\t */ \n\tfor (k = 0; k <= 39; k++) {\n\n\t\tL_result = 8192 >> 1;\n\n\t\t/* for (i = 0; i <= 10; i++) {\n\t\t *\tL_temp   = GSM_L_MULT( wt[k+i], gsm_H[i] );\n\t\t *\tL_result = GSM_L_ADD( L_result, L_temp );\n\t\t * }\n\t\t */\n\n#undef\tSTEP\n#define\tSTEP( i, H )\t(e[ k + i ] * (longword)H)\n\n\t\t/*  Every one of these multiplications is done twice --\n\t\t *  but I don't see an elegant way to optimize this. \n\t\t *  Do you?\n\t\t */\n\n#ifdef\tSTUPID_COMPILER\n\t\tL_result += STEP(\t0, \t-134 ) ;\n\t\tL_result += STEP(\t1, \t-374 )  ;\n\t               /* + STEP(\t2, \t0    )  */\n\t\tL_result += STEP(\t3, \t2054 ) ;\n\t\tL_result += STEP(\t4, \t5741 ) ;\n\t\tL_result += STEP(\t5, \t8192 ) ;\n\t\tL_result += STEP(\t6, \t5741 ) ;\n\t\tL_result += STEP(\t7, \t2054 ) ;\n\t \t       /* + STEP(\t8, \t0    )  */\n\t\tL_result += STEP(\t9, \t-374 ) ;\n\t\tL_result += STEP(\t10, \t-134 ) ;\n#else\n\t\tL_result +=\n\t\t  STEP(\t0, \t-134 ) \n\t\t+ STEP(\t1, \t-374 ) \n\t     /* + STEP(\t2, \t0    )  */\n\t\t+ STEP(\t3, \t2054 ) \n\t\t+ STEP(\t4, \t5741 ) \n\t\t+ STEP(\t5, \t8192 ) \n\t\t+ STEP(\t6, \t5741 ) \n\t\t+ STEP(\t7, \t2054 ) \n\t     /* + STEP(\t8, \t0    )  */\n\t\t+ STEP(\t9, \t-374 ) \n\t\t+ STEP(10, \t-134 )\n\t\t;\n#endif\n\n\t\t/* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *)\n\t\t * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *)\n\t\t *\n\t\t * x[k] = SASR( L_result, 16 );\n\t\t */\n\n\t\t/* 2 adds vs. >>16 => 14, minus one shift to compensate for\n\t\t * those we lost when replacing L_MULT by '*'.\n\t\t */\n\n\t\tL_result = SASR( L_result, 13 );\n\t\tx[k] =  (  L_result < MIN_WORD ? MIN_WORD\n\t\t\t: (L_result > MAX_WORD ? MAX_WORD : L_result ));\n\t}\n}\n\n/* 4.2.14 */\n\nstatic void RPE_grid_selection P3((x,xM,Mc_out),\n\tword\t\t* x,\t\t/* [0..39]\t\tIN  */ \n\tword\t\t* xM,\t\t/* [0..12]\t\tOUT */\n\tword\t\t* Mc_out\t/*\t\t\tOUT */\n)\n/*\n *  The signal x[0..39] is used to select the RPE grid which is\n *  represented by Mc.\n */\n{\n\t/* register word\ttemp1;\t*/\n\tregister int\t\t/* m, */  i;\n\tregister longword\tL_result, L_temp;\n\tlongword\t\tEM;\t/* xxx should be L_EM? */\n\tword\t\t\tMc;\n\n\tlongword\t\tL_common_0_3;\n\n\tEM = 0;\n\tMc = 0;\n\n\t/* for (m = 0; m <= 3; m++) {\n\t *\tL_result = 0;\n\t *\n\t *\n\t *\tfor (i = 0; i <= 12; i++) {\n\t *\n\t *\t\ttemp1    = SASR( x[m + 3*i], 2 );\n\t *\n\t *\t\tassert(temp1 != MIN_WORD);\n\t *\n\t *\t\tL_temp   = GSM_L_MULT( temp1, temp1 );\n\t *\t\tL_result = GSM_L_ADD( L_temp, L_result );\n\t *\t}\n\t * \n\t *\tif (L_result > EM) {\n\t *\t\tMc = m;\n\t *\t\tEM = L_result;\n\t *\t}\n\t * }\n\t */\n\n#undef\tSTEP\n#define\tSTEP( m, i )\t\tL_temp = SASR( x[m + 3 * i], 2 );\t\\\n\t\t\t\tL_result += L_temp * L_temp;\n\n\t/* common part of 0 and 3 */\n\n\tL_result = 0;\n\tSTEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 );\n\tSTEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 );\n\tSTEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12);\n\tL_common_0_3 = L_result;\n\n\t/* i = 0 */\n\n\tSTEP( 0, 0 );\n\tL_result <<= 1;\t/* implicit in L_MULT */\n\tEM = L_result;\n\n\t/* i = 1 */\n\n\tL_result = 0;\n\tSTEP( 1, 0 );\n\tSTEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 );\n\tSTEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 );\n\tSTEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12);\n\tL_result <<= 1;\n\tif (L_result > EM) {\n\t\tMc = 1;\n\t \tEM = L_result;\n\t}\n\n\t/* i = 2 */\n\n\tL_result = 0;\n\tSTEP( 2, 0 );\n\tSTEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 );\n\tSTEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 );\n\tSTEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12);\n\tL_result <<= 1;\n\tif (L_result > EM) {\n\t\tMc = 2;\n\t \tEM = L_result;\n\t}\n\n\t/* i = 3 */\n\n\tL_result = L_common_0_3;\n\tSTEP( 3, 12 );\n\tL_result <<= 1;\n\tif (L_result > EM) {\n\t\tMc = 3;\n\t \tEM = L_result;\n\t}\n\n\t/**/\n\n\t/*  Down-sampling by a factor 3 to get the selected xM[0..12]\n\t *  RPE sequence.\n\t */\n\tfor (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i];\n\t*Mc_out = Mc;\n}\n\n/* 4.12.15 */\n\nstatic void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out),\n\tword\t\txmaxc,\t\t/* IN \t*/\n\tword\t\t* exp_out,\t/* OUT\t*/\n\tword\t\t* mant_out )\t/* OUT  */\n{\n\tword\texp, mant;\n\n\t/* Compute exponent and mantissa of the decoded version of xmaxc\n\t */\n\n\texp = 0;\n\tif (xmaxc > 15) exp = SASR(xmaxc, 3) - 1;\n\tmant = xmaxc - (exp << 3);\n\n\tif (mant == 0) {\n\t\texp  = -4;\n\t\tmant = 7;\n\t}\n\telse {\n\t\twhile (mant <= 7) {\n\t\t\tmant = mant << 1 | 1;\n\t\t\texp--;\n\t\t}\n\t\tmant -= 8;\n\t}\n\n\tassert( exp  >= -4 && exp <= 6 );\n\tassert( mant >= 0 && mant <= 7 );\n\n\t*exp_out  = exp;\n\t*mant_out = mant;\n}\n\nstatic void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out),\n\tword\t\t* xM,\t\t/* [0..12]\t\tIN\t*/\n\n\tword\t\t* xMc,\t\t/* [0..12]\t\tOUT\t*/\n\tword\t\t* mant_out,\t/* \t\t\tOUT\t*/\n\tword\t\t* exp_out,\t/*\t\t\tOUT\t*/\n\tword\t\t* xmaxc_out\t/*\t\t\tOUT\t*/\n)\n{\n\tint\ti, itest;\n\n\tword\txmax, xmaxc, temp, temp1, temp2;\n\tword\texp, mant;\n\n\n\t/*  Find the maximum absolute value xmax of xM[0..12].\n\t */\n\n\txmax = 0;\n\tfor (i = 0; i <= 12; i++) {\n\t\ttemp = xM[i];\n\t\ttemp = GSM_ABS(temp);\n\t\tif (temp > xmax) xmax = temp;\n\t}\n\n\t/*  Qantizing and coding of xmax to get xmaxc.\n\t */\n\n\texp   = 0;\n\ttemp  = SASR( xmax, 9 );\n\titest = 0;\n\n\tfor (i = 0; i <= 5; i++) {\n\n\t\titest |= (temp <= 0);\n\t\ttemp = SASR( temp, 1 );\n\n\t\tassert(exp <= 5);\n\t\tif (itest == 0) exp++;\t\t/* exp = add (exp, 1) */\n\t}\n\n\tassert(exp <= 6 && exp >= 0);\n\ttemp = exp + 5;\n\n\tassert(temp <= 11 && temp >= 0);\n\txmaxc = gsm_add( SASR(xmax, temp), exp << 3 );\n\n\t/*   Quantizing and coding of the xM[0..12] RPE sequence\n\t *   to get the xMc[0..12]\n\t */\n\n\tAPCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant );\n\n\t/*  This computation uses the fact that the decoded version of xmaxc\n\t *  can be calculated by using the exponent and the mantissa part of\n\t *  xmaxc (logarithmic table).\n\t *  So, this method avoids any division and uses only a scaling\n\t *  of the RPE samples by a function of the exponent.  A direct \n\t *  multiplication by the inverse of the mantissa (NRFAC[0..7]\n\t *  found in table 4.5) gives the 3 bit coded version xMc[0..12]\n\t *  of the RPE samples.\n\t */\n\n\n\t/* Direct computation of xMc[0..12] using table 4.5\n\t */\n\n\tassert( exp <= 4096 && exp >= -4096);\n\tassert( mant >= 0 && mant <= 7 ); \n\n\ttemp1 = 6 - exp;\t\t/* normalization by the exponent */\n\ttemp2 = gsm_NRFAC[ mant ];  \t/* inverse mantissa \t\t */\n\n\tfor (i = 0; i <= 12; i++) {\n\n\t\tassert(temp1 >= 0 && temp1 < 16);\n\n\t\ttemp = xM[i] << temp1;\n\t\ttemp = GSM_MULT( temp, temp2 );\n\t\ttemp = SASR(temp, 12);\n\t\txMc[i] = temp + 4;\t\t/* see note below */\n\t}\n\n\t/*  NOTE: This equation is used to make all the xMc[i] positive.\n\t */\n\n\t*mant_out  = mant;\n\t*exp_out   = exp;\n\t*xmaxc_out = xmaxc;\n}\n\n/* 4.2.16 */\n\nstatic void APCM_inverse_quantization P4((xMc,mant,exp,xMp),\n\tregister word\t* xMc,\t/* [0..12]\t\t\tIN \t*/\n\tword\t\tmant,\n\tword\t\texp,\n\tregister word\t* xMp)\t/* [0..12]\t\t\tOUT \t*/\n/* \n *  This part is for decoding the RPE sequence of coded xMc[0..12]\n *  samples to obtain the xMp[0..12] array.  Table 4.6 is used to get\n *  the mantissa of xmaxc (FAC[0..7]).\n */\n{\n\tint\ti;\n\tword\ttemp, temp1, temp2, temp3;\n\tlongword\tltmp;\n\n\tassert( mant >= 0 && mant <= 7 ); \n\n\ttemp1 = gsm_FAC[ mant ];\t/* see 4.2-15 for mant */\n\ttemp2 = gsm_sub( 6, exp );\t/* see 4.2-15 for exp  */\n\ttemp3 = gsm_asl( 1, gsm_sub( temp2, 1 ));\n\n\tfor (i = 13; i--;) {\n\n\t\tassert( *xMc <= 7 && *xMc >= 0 ); \t/* 3 bit unsigned */\n\n\t\t/* temp = gsm_sub( *xMc++ << 1, 7 ); */\n\t\ttemp = (*xMc++ << 1) - 7;\t        /* restore sign   */\n\t\tassert( temp <= 7 && temp >= -7 ); \t/* 4 bit signed   */\n\n\t\ttemp <<= 12;\t\t\t\t/* 16 bit signed  */\n\t\ttemp = GSM_MULT_R( temp1, temp );\n\t\ttemp = GSM_ADD( temp, temp3 );\n\t\t*xMp++ = gsm_asr( temp, temp2 );\n\t}\n}\n\n/* 4.2.17 */\n\nstatic void RPE_grid_positioning P3((Mc,xMp,ep),\n\tword\t\tMc,\t\t/* grid position\tIN\t*/\n\tregister word\t* xMp,\t\t/* [0..12]\t\tIN\t*/\n\tregister word\t* ep\t\t/* [0..39]\t\tOUT\t*/\n)\n/*\n *  This procedure computes the reconstructed long term residual signal\n *  ep[0..39] for the LTP analysis filter.  The inputs are the Mc\n *  which is the grid position selection and the xMp[0..12] decoded\n *  RPE samples which are upsampled by a factor of 3 by inserting zero\n *  values.\n */\n{\n\tint\ti = 13;\n\n\tassert(0 <= Mc && Mc <= 3);\n\n        switch (Mc) {\n                case 3: *ep++ = 0;\n                case 2:  do {\n                                *ep++ = 0;\n                case 1:         *ep++ = 0;\n                case 0:         *ep++ = *xMp++;\n                         } while (--i);\n        }\n        while (++Mc < 4) *ep++ = 0;\n\n\t/*\n\n\tint i, k;\n\tfor (k = 0; k <= 39; k++) ep[k] = 0;\n\tfor (i = 0; i <= 12; i++) {\n\t\tep[ Mc + (3*i) ] = xMp[i];\n\t}\n\t*/\n}\n\n/* 4.2.18 */\n\n/*  This procedure adds the reconstructed long term residual signal\n *  ep[0..39] to the estimated signal dpp[0..39] from the long term\n *  analysis filter to compute the reconstructed short term residual\n *  signal dp[-40..-1]; also the reconstructed short term residual\n *  array dp[-120..-41] is updated.\n */\n\n#if 0\t/* Has been inlined in code.c */\nvoid Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp),\n\tword\t* dpp,\t\t/* [0...39]\tIN\t*/\n\tword\t* ep,\t\t/* [0...39]\tIN\t*/\n\tword\t* dp)\t\t/* [-120...-1]  IN/OUT \t*/\n{\n\tint \t\tk;\n\n\tfor (k = 0; k <= 79; k++) \n\t\tdp[ -120 + k ] = dp[ -80 + k ];\n\n\tfor (k = 0; k <= 39; k++)\n\t\tdp[ -40 + k ] = gsm_add( ep[k], dpp[k] );\n}\n#endif\t/* Has been inlined in code.c */\n\nvoid Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc),\n\n\tstruct gsm_state * S,\n\n\tword\t* e,\t\t/* -5..-1][0..39][40..44\tIN/OUT  */\n\tword\t* xmaxc,\t/* \t\t\t\tOUT */\n\tword\t* Mc,\t\t/* \t\t\t  \tOUT */\n\tword\t* xMc)\t\t/* [0..12]\t\t\tOUT */\n{\n\tword\tx[40];\n\tword\txM[13], xMp[13];\n\tword\tmant, exp;\n\n\tWeighting_filter(e, x);\n\tRPE_grid_selection(x, xM, Mc);\n\n\tAPCM_quantization(\txM, xMc, &mant, &exp, xmaxc);\n\tAPCM_inverse_quantization(  xMc,  mant,  exp, xMp);\n\n\tRPE_grid_positioning( *Mc, xMp, e );\n\n}\n\nvoid Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp),\n\tstruct gsm_state\t* S,\n\n\tword \t\txmaxcr,\n\tword\t\tMcr,\n\tword\t\t* xMcr,  /* [0..12], 3 bits \t\tIN\t*/\n\tword\t\t* erp\t /* [0..39]\t\t\tOUT \t*/\n)\n{\n\tword\texp, mant;\n\tword\txMp[ 13 ];\n\n\tAPCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant );\n\tAPCM_inverse_quantization( xMcr, mant, exp, xMp );\n\tRPE_grid_positioning( Mcr, xMp, erp );\n\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/short_term.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/short_term.c,v 1.2 1994/05/10 20:18:47 jutta Exp $ */\n\n#include \"config.h\"\n#include <stdio.h>\n#include <assert.h>\n\n#include \"private.h\"\n\n#include \"gsm.h\"\n#include \"proto.h\"\n\n/*\n *  SHORT TERM ANALYSIS FILTERING SECTION\n */\n\n/* 4.2.8 */\n\nstatic void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp),\n\tword \t* LARc,\t\t/* coded log area ratio\t[0..7] \tIN\t*/\n\tword\t* LARpp)\t/* out: decoded ..\t\t\t*/\n{\n\tregister word\ttemp1 /* , temp2 */;\n\tregister long\tltmp;\t/* for GSM_ADD */\n\n\t/*  This procedure requires for efficient implementation\n\t *  two tables.\n \t *\n\t *  INVA[1..8] = integer( (32768 * 8) / real_A[1..8])\n\t *  MIC[1..8]  = minimum value of the LARc[1..8]\n\t */\n\n\t/*  Compute the LARpp[1..8]\n\t */\n\n\t/* \tfor (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) {\n\t *\n\t *\t\ttemp1  = GSM_ADD( *LARc, *MIC ) << 10;\n\t *\t\ttemp2  = *B << 1;\n\t *\t\ttemp1  = GSM_SUB( temp1, temp2 );\n\t *\n\t *\t\tassert(*INVA != MIN_WORD);\n\t *\n\t *\t\ttemp1  = GSM_MULT_R( *INVA, temp1 );\n\t *\t\t*LARpp = GSM_ADD( temp1, temp1 );\n\t *\t}\n\t */\n\n#undef\tSTEP\n#define\tSTEP( B, MIC, INVA )\t\\\n\t\ttemp1    = GSM_ADD( *LARc++, MIC ) << 10;\t\\\n\t\ttemp1    = GSM_SUB( temp1, B << 1 );\t\t\\\n\t\ttemp1    = GSM_MULT_R( INVA, temp1 );\t\t\\\n\t\t*LARpp++ = GSM_ADD( temp1, temp1 );\n\n\tSTEP(      0,  -32,  13107 );\n\tSTEP(      0,  -32,  13107 );\n\tSTEP(   2048,  -16,  13107 );\n\tSTEP(  -2560,  -16,  13107 );\n\n\tSTEP(     94,   -8,  19223 );\n\tSTEP(  -1792,   -8,  17476 );\n\tSTEP(   -341,   -4,  31454 );\n\tSTEP(  -1144,   -4,  29708 );\n\n\t/* NOTE: the addition of *MIC is used to restore\n\t * \t the sign of *LARc.\n\t */\n}\n\n/* 4.2.9 */\n/* Computation of the quantized reflection coefficients \n */\n\n/* 4.2.9.1  Interpolation of the LARpp[1..8] to get the LARp[1..8]\n */\n\n/*\n *  Within each frame of 160 analyzed speech samples the short term\n *  analysis and synthesis filters operate with four different sets of\n *  coefficients, derived from the previous set of decoded LARs(LARpp(j-1))\n *  and the actual set of decoded LARs (LARpp(j))\n *\n * (Initial value: LARpp(j-1)[1..8] = 0.)\n */\n\nstatic void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp),\n\tregister word * LARpp_j_1,\n\tregister word * LARpp_j,\n\tregister word * LARp)\n{\n\tregister int \ti;\n\tregister longword ltmp;\n\n\tfor (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) {\n\t\t*LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));\n\t\t*LARp = GSM_ADD( *LARp,  SASR( *LARpp_j_1, 1));\n\t}\n}\n\nstatic void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp),\n\tregister word * LARpp_j_1,\n\tregister word * LARpp_j,\n\tregister word * LARp)\n{\n\tregister int i;\n\tregister longword ltmp;\n\tfor (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {\n\t\t*LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 ));\n\t}\n}\n\nstatic void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp),\n\tregister word * LARpp_j_1,\n\tregister word * LARpp_j,\n\tregister word * LARp)\n{\n\tregister int i;\n\tregister longword ltmp;\n\n\tfor (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {\n\t\t*LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));\n\t\t*LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 ));\n\t}\n}\n\n\nstatic void Coefficients_40_159 P2((LARpp_j, LARp),\n\tregister word * LARpp_j,\n\tregister word * LARp)\n{\n\tregister int i;\n\n\tfor (i = 1; i <= 8; i++, LARp++, LARpp_j++)\n\t\t*LARp = *LARpp_j;\n}\n\n/* 4.2.9.2 */\n\nstatic void LARp_to_rp P1((LARp),\n\tregister word * LARp)\t/* [0..7] IN/OUT  */\n/*\n *  The input of this procedure is the interpolated LARp[0..7] array.\n *  The reflection coefficients, rp[i], are used in the analysis\n *  filter and in the synthesis filter.\n */\n{\n\tregister int \t\ti;\n\tregister word\t\ttemp;\n\tregister longword\tltmp;\n\n\tfor (i = 1; i <= 8; i++, LARp++) {\n\n\t\t/* temp = GSM_ABS( *LARp );\n\t         *\n\t\t * if (temp < 11059) temp <<= 1;\n\t\t * else if (temp < 20070) temp += 11059;\n\t\t * else temp = GSM_ADD( temp >> 2, 26112 );\n\t\t *\n\t\t * *LARp = *LARp < 0 ? -temp : temp;\n\t\t */\n\n\t\tif (*LARp < 0) {\n\t\t\ttemp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp);\n\t\t\t*LARp = - ((temp < 11059) ? temp << 1\n\t\t\t\t: ((temp < 20070) ? temp + 11059\n\t\t\t\t:  GSM_ADD( temp >> 2, 26112 )));\n\t\t} else {\n\t\t\ttemp  = *LARp;\n\t\t\t*LARp =    (temp < 11059) ? temp << 1\n\t\t\t\t: ((temp < 20070) ? temp + 11059\n\t\t\t\t:  GSM_ADD( temp >> 2, 26112 ));\n\t\t}\n\t}\n}\n\n\n/* 4.2.10 */\nstatic void Short_term_analysis_filtering P4((S,rp,k_n,s),\n\tstruct gsm_state * S,\n\tregister word\t* rp,\t/* [0..7]\tIN\t*/\n\tregister int \tk_n, \t/*   k_end - k_start\t*/\n\tregister word\t* s\t/* [0..n-1]\tIN/OUT\t*/\n)\n/*\n *  This procedure computes the short term residual signal d[..] to be fed\n *  to the RPE-LTP loop from the s[..] signal and from the local rp[..]\n *  array (quantized reflection coefficients).  As the call of this\n *  procedure can be done in many ways (see the interpolation of the LAR\n *  coefficient), it is assumed that the computation begins with index\n *  k_start (for arrays d[..] and s[..]) and stops with index k_end\n *  (k_start and k_end are defined in 4.2.9.1).  This procedure also\n *  needs to keep the array u[0..7] in memory for each call.\n */\n{\n\tregister word\t\t* u = S->u;\n\tregister int\t\ti;\n\tregister word\t\tdi, zzz, ui, sav, rpi;\n\tregister longword \tltmp;\n\n\tfor (; k_n--; s++) {\n\n\t\tdi = sav = *s;\n\n\t\tfor (i = 0; i < 8; i++) {\t\t/* YYY */\n\n\t\t\tui    = u[i];\n\t\t\trpi   = rp[i];\n\t\t\tu[i]  = sav;\n\n\t\t\tzzz   = GSM_MULT_R(rpi, di);\n\t\t\tsav   = GSM_ADD(   ui,  zzz);\n\n\t\t\tzzz   = GSM_MULT_R(rpi, ui);\n\t\t\tdi    = GSM_ADD(   di,  zzz );\n\t\t}\n\n\t\t*s = di;\n\t}\n}\n\n#if defined(USE_FLOAT_MUL) && defined(FAST)\n\nstatic void Fast_Short_term_analysis_filtering P4((S,rp,k_n,s),\n\tstruct gsm_state * S,\n\tregister word\t* rp,\t/* [0..7]\tIN\t*/\n\tregister int \tk_n, \t/*   k_end - k_start\t*/\n\tregister word\t* s\t/* [0..n-1]\tIN/OUT\t*/\n)\n{\n\tregister word\t\t* u = S->u;\n\tregister int\t\ti;\n\n\tfloat \t  uf[8],\n\t\t rpf[8];\n\n\tregister float scalef = 3.0517578125e-5;\n\tregister float\t\tsav, di, temp;\n\n\tfor (i = 0; i < 8; ++i) {\n\t\tuf[i]  = u[i];\n\t\trpf[i] = rp[i] * scalef;\n\t}\n\tfor (; k_n--; s++) {\n\t\tsav = di = *s;\n\t\tfor (i = 0; i < 8; ++i) {\n\t\t\tregister float rpfi = rpf[i];\n\t\t\tregister float ufi  = uf[i];\n\n\t\t\tuf[i] = sav;\n\t\t\ttemp  = rpfi * di + ufi;\n\t\t\tdi   += rpfi * ufi;\n\t\t\tsav   = temp;\n\t\t}\n\t\t*s = di;\n\t}\n\tfor (i = 0; i < 8; ++i) u[i] = uf[i];\n}\n#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */\n\nstatic void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),\n\tstruct gsm_state * S,\n\tregister word\t* rrp,\t/* [0..7]\tIN\t*/\n\tregister int\tk,\t/* k_end - k_start\t*/\n\tregister word\t* wt,\t/* [0..k-1]\tIN\t*/\n\tregister word\t* sr\t/* [0..k-1]\tOUT\t*/\n)\n{\n\tregister word\t\t* v = S->v;\n\tregister int\t\ti;\n\tregister word\t\tsri, tmp1, tmp2;\n\tregister longword\tltmp;\t/* for GSM_ADD  & GSM_SUB */\n\n\twhile (k--) {\n\t\tsri = *wt++;\n\t\tfor (i = 8; i--;) {\n\n\t\t\t/* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) );\n\t\t\t */\n\t\t\ttmp1 = rrp[i];\n\t\t\ttmp2 = v[i];\n\t\t\ttmp2 =  ( tmp1 == MIN_WORD && tmp2 == MIN_WORD\n\t\t\t\t? MAX_WORD\n\t\t\t\t: 0x0FFFF & (( (longword)tmp1 * (longword)tmp2\n\t\t\t\t\t     + 16384) >> 15)) ;\n\n\t\t\tsri  = GSM_SUB( sri, tmp2 );\n\n\t\t\t/* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) );\n\t\t\t */\n\t\t\ttmp1  = ( tmp1 == MIN_WORD && sri == MIN_WORD\n\t\t\t\t? MAX_WORD\n\t\t\t\t: 0x0FFFF & (( (longword)tmp1 * (longword)sri\n\t\t\t\t\t     + 16384) >> 15)) ;\n\n\t\t\tv[i+1] = GSM_ADD( v[i], tmp1);\n\t\t}\n\t\t*sr++ = v[0] = sri;\n\t}\n}\n\n\n#if defined(FAST) && defined(USE_FLOAT_MUL)\n\nstatic void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),\n\tstruct gsm_state * S,\n\tregister word\t* rrp,\t/* [0..7]\tIN\t*/\n\tregister int\tk,\t/* k_end - k_start\t*/\n\tregister word\t* wt,\t/* [0..k-1]\tIN\t*/\n\tregister word\t* sr\t/* [0..k-1]\tOUT\t*/\n)\n{\n\tregister word\t\t* v = S->v;\n\tregister int\t\ti;\n\n\tfloat va[9], rrpa[8];\n\tregister float scalef = 3.0517578125e-5, temp;\n\n\tfor (i = 0; i < 8; ++i) {\n\t\tva[i]   = v[i];\n\t\trrpa[i] = (float)rrp[i] * scalef;\n\t}\n\twhile (k--) {\n\t\tregister float sri = *wt++;\n\t\tfor (i = 8; i--;) {\n\t\t\tsri -= rrpa[i] * va[i];\n\t\t\tif     (sri < -32768.) sri = -32768.;\n\t\t\telse if (sri > 32767.) sri =  32767.;\n\n\t\t\ttemp = va[i] + rrpa[i] * sri;\n\t\t\tif     (temp < -32768.) temp = -32768.;\n\t\t\telse if (temp > 32767.) temp =  32767.;\n\t\t\tva[i+1] = temp;\n\t\t}\n\t\t*sr++ = va[0] = sri;\n\t}\n\tfor (i = 0; i < 9; ++i) v[i] = va[i];\n}\n\n#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */\n\nvoid Gsm_Short_Term_Analysis_Filter P3((S,LARc,s),\n\n\tstruct gsm_state * S,\n\n\tword\t* LARc,\t\t/* coded log area ratio [0..7]  IN\t*/\n\tword\t* s\t\t/* signal [0..159]\t\tIN/OUT\t*/\n)\n{\n\tword\t\t* LARpp_j\t= S->LARpp[ S->j      ];\n\tword\t\t* LARpp_j_1\t= S->LARpp[ S->j ^= 1 ];\n\n\tword\t\tLARp[8];\n\n#undef\tFILTER\n#if \tdefined(FAST) && defined(USE_FLOAT_MUL)\n# \tdefine\tFILTER \t(* (S->fast\t\t\t\\\n\t\t\t   ? Fast_Short_term_analysis_filtering\t\\\n\t\t    \t   : Short_term_analysis_filtering\t))\n\n#else\n# \tdefine\tFILTER\tShort_term_analysis_filtering\n#endif\n\n\tDecoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j );\n\n\tCoefficients_0_12(  LARpp_j_1, LARpp_j, LARp );\n\tLARp_to_rp( LARp );\n\tFILTER( S, LARp, 13, s);\n\n\tCoefficients_13_26( LARpp_j_1, LARpp_j, LARp);\n\tLARp_to_rp( LARp );\n\tFILTER( S, LARp, 14, s + 13);\n\n\tCoefficients_27_39( LARpp_j_1, LARpp_j, LARp);\n\tLARp_to_rp( LARp );\n\tFILTER( S, LARp, 13, s + 27);\n\n\tCoefficients_40_159( LARpp_j, LARp);\n\tLARp_to_rp( LARp );\n\tFILTER( S, LARp, 120, s + 40);\n}\n\nvoid Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s),\n\tstruct gsm_state * S,\n\n\tword\t* LARcr,\t/* received log area ratios [0..7] IN  */\n\tword\t* wt,\t\t/* received d [0..159]\t\t   IN  */\n\n\tword\t* s\t\t/* signal   s [0..159]\t\t  OUT  */\n)\n{\n\tword\t\t* LARpp_j\t= S->LARpp[ S->j     ];\n\tword\t\t* LARpp_j_1\t= S->LARpp[ S->j ^=1 ];\n\n\tword\t\tLARp[8];\n\n#undef\tFILTER\n#if \tdefined(FAST) && defined(USE_FLOAT_MUL)\n\n# \tdefine\tFILTER \t(* (S->fast\t\t\t\\\n\t\t\t   ? Fast_Short_term_synthesis_filtering\t\\\n\t\t    \t   : Short_term_synthesis_filtering\t))\n#else\n#\tdefine\tFILTER\tShort_term_synthesis_filtering\n#endif\n\n\tDecoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j );\n\n\tCoefficients_0_12( LARpp_j_1, LARpp_j, LARp );\n\tLARp_to_rp( LARp );\n\tFILTER( S, LARp, 13, wt, s );\n\n\tCoefficients_13_26( LARpp_j_1, LARpp_j, LARp);\n\tLARp_to_rp( LARp );\n\tFILTER( S, LARp, 14, wt + 13, s + 13 );\n\n\tCoefficients_27_39( LARpp_j_1, LARpp_j, LARp);\n\tLARp_to_rp( LARp );\n\tFILTER( S, LARp, 13, wt + 27, s + 27 );\n\n\tCoefficients_40_159( LARpp_j, LARp );\n\tLARp_to_rp( LARp );\n\tFILTER(S, LARp, 120, wt + 40, s + 40);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/table.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/table.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */\n\n/*  Most of these tables are inlined at their point of use.\n */\n\n/*  4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP\n *      CODER AND DECODER\n *\n *\t(Most of them inlined, so watch out.)\n */\n\n#define\tGSM_TABLE_C\n#include \"private.h\"\n#include\t\"gsm.h\"\n\n/*  Table 4.1  Quantization of the Log.-Area Ratios\n */\n/* i \t\t     1      2      3        4      5      6        7       8 */\nword gsm_A[8]   = {20480, 20480, 20480,  20480,  13964,  15360,   8534,  9036};\nword gsm_B[8]   = {    0,     0,  2048,  -2560,     94,  -1792,   -341, -1144};\nword gsm_MIC[8] = { -32,   -32,   -16,    -16,     -8,     -8,     -4,    -4 };\nword gsm_MAC[8] = {  31,    31,    15,     15,      7,      7,      3,     3 };\n\n\n/*  Table 4.2  Tabulation  of 1/A[1..8]\n */\nword gsm_INVA[8]={ 13107, 13107,  13107, 13107,  19223, 17476,  31454, 29708 };\n\n\n/*   Table 4.3a  Decision level of the LTP gain quantizer\n */\n/*  bc\t\t      0\t        1\t  2\t     3\t\t\t*/\nword gsm_DLB[4] = {  6554,    16384,\t26214,\t   32767\t};\n\n\n/*   Table 4.3b   Quantization levels of the LTP gain quantizer\n */\n/* bc\t\t      0          1        2          3\t\t\t*/\nword gsm_QLB[4] = {  3277,    11469,\t21299,\t   32767\t};\n\n\n/*   Table 4.4\t Coefficients of the weighting filter\n */\n/* i\t\t    0      1   2    3   4      5      6     7   8   9    10  */\nword gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 };\n\n\n/*   Table 4.5 \t Normalized inverse mantissa used to compute xM/xmax \n */\n/* i\t\t \t0        1    2      3      4      5     6      7   */\nword gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 };\n\n\n/*   Table 4.6\t Normalized direct mantissa used to compute xM/xmax\n */\n/* i                  0      1       2      3      4      5      6      7   */\nword gsm_FAC[8]\t= { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 };\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/toast.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/toast.c,v 1.8 1996/07/02 10:41:04 jutta Exp $ */\n\n#include\t\"toast.h\"\n\n/*  toast -- lossy sound compression using the gsm library.\n */\n\nchar   * progname;\n\nint\tf_decode   = 0;\t\t/* decode rather than encode\t (-d) */\nint \tf_cat\t   = 0;\t\t/* write to stdout; implies -p   (-c) */\nint\tf_force\t   = 0;\t\t/* don't ask about replacements  (-f) */\nint\tf_precious = 0;\t\t/* avoid deletion of original\t (-p) */\nint\tf_fast\t   = 0;\t\t/* use faster fpt algorithm\t (-F) */\nint\tf_verbose  = 0;\t\t/* debugging\t\t\t (-V) */\nint\tf_ltp_cut  = 0;\t\t/* LTP cut-off margin\t      \t (-C) */\n\nstruct stat instat;\t\t/* stat (inname) \t\t */\n\nFILE\t*in, \t *out;\nchar\t*inname, *outname;\n\n/*\n *  The function (*output)() writes a frame of 160 samples given as\n *  160 signed 16 bit values (gsm_signals) to <out>.\n *  The function (*input)() reads one such frame from <in>.\n *  The function (*init_output)() begins output (e.g. writes a header).,\n *  The function (*init_input)() begins input (e.g. skips a header).\n *\n *  There are different versions of input, output, init_input and init_output\n *  for different formats understood by toast; which ones are used \n *  depends on the command line arguments and, in their absence, the\n *  filename; the fallback is #defined in toast.h\n *\n *  The specific implementations of input, output, init_input and init_output\n *  for a format `foo' live in toast_foo.c.\n */\n\nint\t(*output   ) P((gsm_signal *)),\n\t(*input    ) P((gsm_signal *));\nint\t(*init_input)  P((void)),\n\t(*init_output) P((void));\n\nstatic int\tgeneric_init P0() { return 0; }\t/* NOP */\n\nstruct fmtdesc {\n\n\tchar * name, * longname, * suffix;\n\n\tint  (* init_input )  P((void)),\n\t     (* init_output)  P((void));\n\n\tint  (* input ) P((gsm_signal * )),\n\t     (* output) P((gsm_signal * ));\n\n} f_audio = {\n\t\t\"audio\",\n\t\t\"8 kHz, 8 bit u-law encoding with Sun audio header\", \".au\",\n\t\taudio_init_input,\n\t\taudio_init_output,\n\t\tulaw_input,\n\t\tulaw_output\n}, f_ulaw = {\n\t\t\"u-law\", \"plain 8 kHz, 8 bit u-law encoding\", \".u\",\n\t\tgeneric_init,\n\t\tgeneric_init,\n\t\tulaw_input,\n\t\tulaw_output \n\n}, f_alaw = {\n\t\t\"A-law\", \"8 kHz, 8 bit A-law encoding\", \".A\",\n\t\tgeneric_init,\n\t\tgeneric_init,\n\t\talaw_input,\n\t\talaw_output\n\n}, f_linear = {\n\t\t\"linear\",\n\t\t\"16 bit (13 significant) signed 8 kHz signal\", \".l\",\n\t\tgeneric_init,\n\t\tgeneric_init,\n\t\tlinear_input,\n\t\tlinear_output\n};\n\nstruct fmtdesc * alldescs[] = {\n\t&f_audio,\n\t&f_alaw,\n\t&f_ulaw,\n\t&f_linear,\n\t(struct fmtdesc *)NULL\n};\n\n#define\tDEFAULT_FORMAT\tf_ulaw\t\t/* default audio format, others\t*/\n\t\t\t\t\t/* are: f_alaw,f_audio,f_linear */\nstruct fmtdesc * f_format  = 0;\n\n/*\n *  basename + suffix of a pathname\n */\nstatic char * endname P1((name), char * name)\n{\n\tif (name) {\n\t\tchar * s = strrchr(name, '/');\n\t\tif (s && s[1]) name = s + 1;\n\t}\n\treturn name;\n\n}\n\n/*\n *  Try to figure out what we're supposed to do from the argv[0], if\n *  any, and set the parameters accordingly.\n */\nstatic void parse_argv0 P1((av0), char * av0 )\n{\n\tint \tl;\n\n\tprogname = av0 = endname(av0 ? av0 : \"toast\");\n\n\t/*  If the name starts with `un', we want to decode, not code.\n\t *  If the name ends in `cat', we want to write to stdout,\n\t *  and decode as well.\n\t */\n\n\tif (!strncmp(av0, \"un\", 2)) f_decode = 1;\n\tif (  (l = strlen(av0)) >= 3 /* strlen(\"cat\") */\n\t   && !strcmp( av0 + l - 3, \"cat\" )) f_cat = f_decode = 1;\n}\n\n\n/*\n *  Check whether the name (possibly generated by appending\n *  .gsm to something else) is short enough for this system.\n */\nstatic int length_okay P1((name), char * name)\n{\n\tlong\tmax_filename_length = 0;\n\tchar\t* end;\n\n\t/* If our _pathname_ is too long, we'll usually not be\n\t * able to open the file at all -- don't worry about that.\n\t * \n\t * But if the _filename_ is too long, there is danger of\n\t * silent truncation on some systems, which results\n\t * in the target replacing the source!\n\t */\n\n\tif (!name) return 0;\n\tend = endname(name);\n\n#ifdef\tNAME_MAX\n\tmax_filename_length  = NAME_MAX;\n#else\n#ifdef\t_PC_NAME_MAX\n#ifdef USE_PATHCONF\n\t{\tchar * s, tmp; \n\t\t\n\t\t/*  s = dirname(name)\n\t\t */\n\t\tif ((s = end) > name) {\n\t\t\tif (s > name + 1) s--;\n\t\t\ttmp = s;\n\t\t\t*s  = 0;\n\t\t}\n\n\t\terrno = 0;\n\t\tmax_filename_length = pathconf(s > name ? name : \".\",\n\t\t\t_PC_NAME_MAX);\n\t\tif (max_filename_length == -1 && errno) {\n\t\t\tperror( s > name ? name : \".\" );\n\t\t\tfprintf(stderr,\n\t\t\"%s: cannot get dynamic filename length limit for %s.\\n\",\n\t\t\t\tprogname, s > name ? name : \".\");\n\t\t\treturn 0;\n\t\t}\n\t\tif (s > name) *s = tmp;\n\t}\n#endif /* USE_PATHCONF  */\n#endif /* _PC_NAME_MAX  */\n#endif /* !NAME_MAX \t*/\n\n\tif (max_filename_length > 0 && strlen(end) > max_filename_length) {\n\t\tfprintf(stderr,\n\t\t\t\"%s: filename \\\"%s\\\" is too long (maximum is %ld)\\n\",\n\t\t\tprogname, endname(name), max_filename_length );\n\t\treturn 0;\n\t}\n\n\treturn 1;\n}\n\n/*\n *  Return a pointer the suffix of a string, if any.\n *  A suffix alone has no suffix, an empty suffix can not be had.\n */\nstatic char * suffix P2((name, suf), char *name, char * suf) \n{\n\tsize_t nlen = strlen(name);\n\tsize_t slen = strlen(suf);\n\n\tif (!slen || nlen <= slen) return (char *)0;\n\tname += nlen - slen;\n\treturn memcmp(name, suf, slen) ? (char *)0 : name;\n}\n\n\nstatic void catch_signals P1((fun), SIGHANDLER_T (*fun) ()) \n{\n#ifdef\tSIGHUP\n\tsignal( SIGHUP,   fun );\n#endif\n#ifdef\tSIGINT\n\tsignal( SIGINT,   fun );\n#endif\n#ifdef\tSIGPIPE\n\tsignal( SIGPIPE,  fun );\n#endif\n#ifdef\tSIGTERM\n\tsignal( SIGTERM,  fun );\n#endif\n#ifdef\tSIGXFSZ\n\tsignal( SIGXFSZ,  fun );\n#endif\n}\n\nstatic SIGHANDLER_T onintr P0()\n{\n\tchar * tmp = outname;\n\n#ifdef\tHAS_SYSV_SIGNALS\n\tcatch_signals( SIG_IGN );\n#endif\n\n\toutname = (char *)0;\n\tif (tmp) (void)unlink(tmp);\n\n\texit(1);\n}\n\n/*\n *  Allocate some memory and complain if it fails.\n */\nstatic char * emalloc P1((len), size_t len)\n{\n\tchar * s;\n\tif (!(s = malloc(len))) {\n\t\tfprintf(stderr, \"%s: failed to malloc %d bytes -- abort\\n\",\n\t\t\tprogname, len);\n\t\tonintr();\n\t\texit(1);\n\t}\n\treturn s;\n}\n\nstatic char* normalname P3((name, want, cut), char *name, char *want,char *cut)\n{\n\tsize_t\tmaxlen;\n\tchar \t* s, * p;\n\n\tp = (char *)0;\n\tif (!name) return p;\n\n\tmaxlen = strlen(name) + 1 + strlen(want) + strlen(cut);\n\tp = strcpy(emalloc(maxlen), name);\n\n\tif (s = suffix(p, cut)) strcpy(s, want);\n\telse if (*want && !suffix(p, want)) strcat(p, want);\n\n\treturn p;\n}\n\n/*\n *  Generate a `plain' (non-encoded) name from a given name.\n */\nstatic char * plainname P1((name), char *name)\n{\n\treturn normalname(name, \"\", SUFFIX_TOASTED );\n}\n\n/*\n *  Generate a `code' name from a given name.\n */\nstatic char * codename P1((name), char *name)\n{\n\treturn normalname( name, SUFFIX_TOASTED, \"\" );\n}\n\n/*\n *  If we're supposed to ask (fileno (stderr) is a tty, and f_force not\n *  set), ask the user whether to overwrite a file or not.\n */\nstatic int ok_to_replace P1(( name ), char * name)\n{\n\tint reply, c;\n\n\tif (f_force) return 1;\t\t\t/* YES, do replace   */\n\tif (!isatty(fileno(stderr))) return 0;\t/* NO, don't replace */\n\n\tfprintf(stderr,\n\t\t\"%s already exists; do you wish to overwrite %s (y or n)? \",\n\t\tname, name);\n\tfflush(stderr);\n\n\tfor (c = reply = getchar(); c != '\\n' && c != EOF; c = getchar()) ;\n\tif (reply == 'y') return 1;\n\n\tfprintf(stderr, \"\\tnot overwritten\\n\");\n\treturn 0;\n}\n\nstatic void update_mode P0()\n{\n\tif (!instat.st_nlink) return;\t\t/* couldn't stat in */\n\n#ifdef HAS_FCHMOD\n\tif (fchmod(fileno(out), instat.st_mode & 07777)) {\n\t\tperror(outname);\n\t\tfprintf(stderr, \"%s: could not change file mode of \\\"%s\\\"\\n\",\n\t\t\tprogname, outname);\n\t}\n#else \n#ifdef HAS_CHMOD\n\tif (outname && chmod(outname, instat.st_mode & 07777)) {\n\t\tperror(outname);\n\t\tfprintf(stderr, \"%s: could not change file mode of \\\"%s\\\"\\n\",\n\t\t\tprogname, outname);\n\t}\n#endif /* HAS_CHMOD  */\n#endif /* HAS_FCHMOD */\n}\n\nstatic void update_own P0()\n{\n\tif (!instat.st_nlink) return; /* couldn't stat in */\n#ifdef HAS_FCHOWN\n\t(void)fchown(fileno(out), instat.st_uid, instat.st_gid);\n#else \n#ifdef HAS_CHOWN\n\t(void)chown(outname, instat.st_uid, instat.st_gid);\n#endif /* HAS_CHOWN  */\n#endif /* HAS_FCHOWN */\n}\n\nstatic void update_times P0()\n{\n\tif (!instat.st_nlink) return; \t/* couldn't stat in */\n\n#ifdef HAS_UTIMES\n\tif (outname) {\n\t\tstruct timeval tv[2];\n\n\t\ttv[0].tv_sec  = instat.st_atime;\n\t\ttv[1].tv_sec  = instat.st_mtime;\n\t\ttv[0].tv_usec = tv[1].tv_usec = 0;\n\t\t(void) utimes(outname, tv);\n\t}\n#else\n#ifdef HAS_UTIME\n\n\tif (outname) {\n\n#ifdef\tHAS_UTIMBUF\n\t\tstruct utimbuf ut;\n\n\t\tut.actime     = instat.st_atime;\n\t\tut.modtime    = instat.st_mtime;\n\n#\tifdef\tHAS_UTIMEUSEC\n\t\tut.acusec     = instat.st_ausec;\n\t\tut.modusec    = instat.st_musec;\n#\tendif \t/* HAS_UTIMEUSEC */\n\n\t\t(void) utime(outname, &ut);\n\n#else /* UTIMBUF */\n\n\t\ttime_t ut[2];\n\n\t\tut[0] = instat.st_atime;\n\t\tut[1] = instat.st_mtime;\n\n\t\t(void) utime(outname, ut);\n\n#endif\t/* UTIMBUF */\n\t}\n#endif /* HAS_UTIME */\n#endif /* HAS_UTIMES */\n}\n\n\nstatic int okay_as_input P3((name,f,st), char* name, FILE* f, struct stat * st)\n{\n# ifdef\tHAS_FSTAT\n\tif (fstat(fileno(f), st) < 0)\n# else\n\tif (stat(name, st) < 0)\n# endif\n\t{\n\t\tperror(name);\n\t\tfprintf(stderr, \"%s: cannot stat \\\"%s\\\"\\n\", progname, name);\n\t\treturn 0;\n\t}\n\n\tif (!S_ISREG(st->st_mode)) {\n\t\tfprintf(stderr,\n\t\t\t\"%s: \\\"%s\\\" is not a regular file -- unchanged.\\n\",\n\t\t\tprogname, name);\n\t\treturn 0;\n\t}\n\tif (st->st_nlink > 1 && !f_cat && !f_precious) {\n\t\tfprintf(stderr, \n\t\t      \"%s: \\\"%s\\\" has %s other link%s -- unchanged.\\n\",\n\t\t\tprogname,name,st->st_nlink - 1,\"s\" + (st->st_nlink<=2));\n\t\treturn 0;\n\t}\n\treturn 1;\n}\n\nstatic void prepare_io P1(( desc), struct fmtdesc * desc)\n{\n\toutput      = desc->output;\n\tinput       = desc->input;\n\n\tinit_input  = desc->init_input;\n\tinit_output = desc->init_output;\n}\n\nstatic struct fmtdesc * grok_format P1((name), char * name)\n{\n\tchar * c;\n\tstruct fmtdesc ** f;\n\n\tif (name) {\n\t\tc = plainname(name);\n\n\t\tfor (f = alldescs; *f; f++) {\n\t\t\tif (  (*f)->suffix\n\t\t\t   && *(*f)->suffix\n\t\t\t   && suffix(c, (*f)->suffix)) {\n\n\t\t\t\tfree(c);\n\t\t\t\treturn *f;\n\t\t\t}\n\t\t}\n\n\t\tfree(c);\n\t}\n\treturn (struct fmtdesc *)0;\n}\n\nstatic int open_input P2((name, st), char * name, struct stat * st)\n{\n\tstruct fmtdesc * f = f_format;\n\n\tst->st_nlink = 0;\t/* indicates `undefined' value */\n\tif (!name) {\n\t\tinname = (char *)NULL;\n\t\tin     = stdin;\n#ifdef\tHAS__FSETMODE\n\t\t_fsetmode(in, \"b\");\n#endif\n\t}\n\telse {\n\t\tif (f_decode) inname = codename(name);\n\t\telse {\n\t\t\tif (!f_cat && suffix(name, SUFFIX_TOASTED)) {\n\t\t\t\tfprintf(stderr,\n\t\t\t\"%s: %s already has \\\"%s\\\" suffix -- unchanged.\\n\",\n\t\t\t\t\tprogname, name, SUFFIX_TOASTED );\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tinname = strcpy(emalloc(strlen(name)+1), name);\n\t\t}\n\t\tif (!(in = fopen(inname, READ))) {\n\t\t\tperror(inname);\t/* not guaranteed to be valid here */\n\t\t\tfprintf(stderr, \"%s: cannot open \\\"%s\\\" for reading\\n\",\n\t\t\t\tprogname, inname);\n\t\t\treturn 0;\n\t\t}\n\t\tif (!okay_as_input(inname, in, st)) return 0;\n\t\tif (!f) f = grok_format(inname);\n\t}\n\tprepare_io( f ? f : & DEFAULT_FORMAT );\n\treturn 1;\n}\n\nstatic int open_output P1((name), char *name)\n{\n\tif (!name || f_cat) {\n\t\tout     = stdout;\n\t\toutname = (char *)NULL;\n#ifdef\tHAS__FSETMODE\n\t\t_fsetmode(out, \"b\"); \n#endif\n\t}\n\telse {\n\t\tint outfd = -1;\n\t\tchar * o;\n\n\t\to = (*(f_decode ? plainname : codename))(name);\n\t\tif (!length_okay(o)) return 0;\n\t\tif ((outfd = open(o, O_WRITE_EXCL, 0666)) >= 0)\n\t\t\tout = fdopen(outfd, WRITE);\n\t\telse if (errno != EEXIST) out = (FILE *)NULL;\n\t\telse if (ok_to_replace(o)) out = fopen(o, WRITE);\n\t\telse return 0;\n\n\t\tif (!out) {\n\t\t\tperror(o);\n\t\t\tfprintf(stderr,\n\t\t\t\t\"%s: can't open \\\"%s\\\" for writing\\n\",\n\t\t\t\tprogname, o);\n\t\t\tif (outfd >= 0) (void)close(outfd);\n\t\t\treturn 0;\n\t\t}\n\n\t\toutname = o;\n\t}\n\treturn 1;\n}\n\nstatic int process_encode P0()\n{\n\tgsm      \tr;\n\tgsm_signal    \ts[ 160 ];\n\tgsm_frame\td;\n \n\tint\t\tcc;\n\n\tif (!(r = gsm_create())) {\n\t\tperror(progname);\n\t\treturn -1;\n\t}\n\t(void)gsm_option(r, GSM_OPT_FAST,       &f_fast);\n\t(void)gsm_option(r, GSM_OPT_VERBOSE,    &f_verbose);\n\t(void)gsm_option(r, GSM_OPT_LTP_CUT,\t&f_ltp_cut);\n\n\twhile ((cc = (*input)(s)) > 0) {\n\t\tif (cc < sizeof(s) / sizeof(*s))\n\t\t\tmemset((char *)(s+cc), 0, sizeof(s)-(cc * sizeof(*s)));\n\t\tgsm_encode(r, s, d);\n\t\tif (fwrite((char *)d, sizeof(d), 1, out) != 1) {\n\t\t\tperror(outname ? outname : \"stdout\");\n\t\t\tfprintf(stderr, \"%s: error writing to %s\\n\",\n\t\t\t\tprogname, outname ? outname : \"stdout\");\n\t\t\tgsm_destroy(r);\n\t\t\treturn -1;\n\t\t}\n\t}\n\tif (cc < 0) {\n\t\tperror(inname ? inname : \"stdin\");\n\t\tfprintf(stderr, \"%s: error reading from %s\\n\",\n\t\t\tprogname, inname ? inname : \"stdin\");\n\t\tgsm_destroy(r);\n\t\treturn -1;\n\t}\n\tgsm_destroy(r);\n\n\treturn 0;\n}\n\nstatic int process_decode P0()\n{\n\tgsm      \tr;\n\tgsm_frame\ts;\n\tgsm_signal\td[ 160 ];\n \n\tint\t\tcc;\n\n\tif (!(r = gsm_create())) {\t/* malloc failed */\n\t\tperror(progname);\n\t\treturn -1;\n\t}\n\t(void)gsm_option(r, GSM_OPT_FAST,    &f_fast);\n\t(void)gsm_option(r, GSM_OPT_VERBOSE, &f_verbose);\n\n\twhile ((cc = fread(s, 1, sizeof(s), in)) > 0) {\n\n\t\tif (cc != sizeof(s)) {\n\t\t\tif (cc >= 0) fprintf(stderr,\n\t\t\t\"%s: incomplete frame (%d byte%s missing) from %s\\n\",\n\t\t\t\t\tprogname, sizeof(s) - cc,\n\t\t\t\t\t\"s\" + (sizeof(s) - cc == 1),\n\t\t\t\t\tinname ? inname : \"stdin\" );\n\t\t\tgsm_destroy(r);\n\t\t\terrno = 0;\n\t\t\treturn -1;\n\t\t}\n\t\tif (gsm_decode(r, s, d)) {\n\t\t\tfprintf(stderr, \"%s: bad frame in %s\\n\", \n\t\t\t\tprogname, inname ? inname : \"stdin\");\n\t\t\tgsm_destroy(r);\n\t\t\terrno = 0;\n\t\t\treturn -1;\n\t\t}\n\n\t\tif ((*output)(d) < 0) {\n\t\t\tperror(outname);\n\t\t\tfprintf(stderr, \"%s: error writing to %s\\n\",\n\t\t\t\t\tprogname, outname);\n\t\t\tgsm_destroy(r);\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\tif (cc < 0) {\n\t\tperror(inname ? inname : \"stdin\" );\n\t\tfprintf(stderr, \"%s: error reading from %s\\n\", progname,\n\t\t\tinname ? inname : \"stdin\");\n\t\tgsm_destroy(r);\n\t\treturn -1;\n\t}\n\n\tgsm_destroy(r);\n\treturn 0;\n}\n\nstatic int process P1((name), char * name)\n{\n\tint step = 0;\n\n\tout     = (FILE *)0;\n\tin      = (FILE *)0;\n\n\toutname = (char *)0;\n\tinname  = (char *)0;\n\n\tif (!open_input(name, &instat) || !open_output(name))\n\t\tgoto err;\n\n\tif ((*(f_decode ? init_output    : init_input))()) {\n\t\tfprintf(stderr, \"%s: error %s %s\\n\",\n\t\t\tprogname,\n\t\t\tf_decode ? \"writing header to\" : \"reading header from\",\n\t\t\tf_decode ? (outname ? outname : \"stdout\")\n\t\t\t\t : (inname ? inname : \"stdin\"));\n\t\tgoto err;\n\t}\n\n\tif ((*(f_decode ? process_decode : process_encode))())\n\t\tgoto err;\n\n\tif (fflush(out) < 0 || ferror(out)) {\n\t\tperror(outname ? outname : \"stdout\");\n\t\tfprintf(stderr, \"%s: error writing \\\"%s\\\"\\n\", progname,\n\t\t\t\toutname ? outname:\"stdout\");\n\t\tgoto err;\n\t}\n\n\tif (out != stdout) {\n\n\t\tupdate_times();\n\t\tupdate_mode ();\n\t\tupdate_own  ();\n\n\t\tif (fclose(out) < 0) {\n\t\t\tperror(outname);\n\t\t\tfprintf(stderr, \"%s: error writing \\\"%s\\\"\\n\",\n\t\t\t\tprogname, outname);\n\t\t\tgoto err;\n\t\t}\n\t\tif (outname != name) free(outname);\n\t\toutname = (char *)0;\n\t}\n\tout = (FILE *)0;\n\tif (in  != stdin) {\n\t\t(void)fclose(in), in = (FILE *)0;\n\t\tif (!f_cat && !f_precious) {\n\t\t\tif (unlink(inname) < 0) {\n\t\t\t\tperror(inname);\n\t\t\t\tfprintf(stderr,\n\t\t\t\t\t\"%s: source \\\"%s\\\" not deleted.\\n\",\n\t\t\t\t\tprogname, inname);\n\t\t\t}\n\t\t\tgoto err;\n\t\t}\n\t\tif (inname != name) free(inname);\n\t\tinname = (char *)0;\n\t}\n\treturn 0;\n\n\t/*\n\t *  Error handling and cleanup.\n\t */\nerr:\n\tif (out && out != stdout) {\n\t\t(void)fclose(out), out = (FILE *)0;\n\t\tif (unlink(outname) < 0 && errno != ENOENT && errno != EINTR) {\n\t\t\tperror(outname);\n\t\t\tfprintf(stderr, \"%s: could not unlink \\\"%s\\\"\\n\",\n\t\t\t\tprogname, outname);\n\t\t}\n\t}\n\tif (in && in != stdin) (void)fclose(in), in = (FILE *)0;\n\n\tif (inname  && inname  != name) free(inname);\n\tif (outname && outname != name) free(outname);\n\n\treturn -1;\n}\n\nstatic void version P0()\n{\n\tprintf( \"%s 1.0, version %s\\n\",\n\t\tprogname,\n\t\t\"$Id: toast.c,v 1.8 1996/07/02 10:41:04 jutta Exp $\" );\n}\n\nstatic void help P0()\n{\n\tprintf(\"Usage: %s [-fcpdhvaulsFC] [files...]\\n\", progname);\n\tprintf(\"\\n\");\n\n\tprintf(\" -f  force     Replace existing files without asking\\n\");\n\tprintf(\" -c  cat       Write to stdout, do not remove source files\\n\");\n\tprintf(\" -d  decode    Decode data (default is encode)\\n\");\n\tprintf(\" -p  precious  Do not delete the source\\n\");\n\tprintf(\"\\n\");\n\n\tprintf(\" -u  u-law     Force 8 kHz/8 bit u-law in/output format\\n\");\n\tprintf(\" -s  sun .au   Force Sun .au u-law in/output format\\n\");\n\tprintf(\" -a  A-law     Force 8 kHz/8 bit A-law in/output format\\n\");\n\tprintf(\" -l  linear    Force 16 bit linear in/output format\\n\");\n\tprintf(\"\\n\");\n\n\tprintf(\" -F  fast      Sacrifice conformance to performance\\n\");\n\tprintf(\" -C  cutoff    Ignore most samples during LTP\\n\");\n\tprintf(\" -v  version   Show version information\\n\");\n\tprintf(\" -h  help      Print this text\\n\");\n\tprintf(\"\\n\");\n}\n\n\nstatic void set_format P1((f), struct fmtdesc * f)\n{\n\tif (f_format && f_format != f) {\n\t\tfprintf( stderr,\n\t\"%s: only one of -[uals] is possible (%s -h for help)\\n\",\n\t\t\tprogname, progname);\n\t\texit(1);\n\t}\n\n\tf_format = f;\n}\n\nint main P2((ac, av), int ac, char **av)\n{\n\tint  \t\topt;\n\textern int\toptind;\n\textern char\t* optarg;\n\n\tparse_argv0(*av);\n\n\twhile ((opt = getopt(ac, av, \"fcdpvhuaslVFC:\")) != EOF) switch (opt) {\n\n\tcase 'd': f_decode   = 1; break;\n\tcase 'f': f_force    = 1; break;\n\tcase 'c': f_cat      = 1; break;\n\tcase 'p': f_precious = 1; break;\n\tcase 'F': f_fast     = 1; break;\n\tcase 'C': f_ltp_cut  = 100; break;\n#ifndef\tNDEBUG\n\tcase 'V': f_verbose  = 1; break;\t/* undocumented */\n#endif\n\n\tcase 'u': set_format( &f_ulaw   ); break;\n\tcase 'l': set_format( &f_linear ); break;\n\tcase 'a': set_format( &f_alaw\t); break;\n\tcase 's': set_format( &f_audio  ); break;\n\n\tcase 'v': version(); exit(0);\n\tcase 'h': help();    exit(0);\n\n\tdefault: \n\tusage:\n\t\tfprintf(stderr,\n\t\"Usage: %s [-fcpdhvuaslFC] [files...] (-h for help)\\n\",\n\t\t\tprogname);\n\t\texit(1);\n\t}\n\n\tf_precious |= f_cat;\n\n\tav += optind;\n\tac -= optind;\n\n\tcatch_signals(onintr);\n\n\tif (ac <= 0) process( (char *)0 );\n\telse while (ac--) process( *av++ );\n\n\texit(0);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/toast_alaw.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /home/kbs/jutta/src/gsm/gsm-1.0/src/RCS/toast_alaw.c,v 1.2 1996/07/05 17:23:46 jutta Exp $ */\n\n#include\t\"toast.h\"\n\n/*  toast_alaw.c -- manipulate A-law encoded sound.\n */\n\nextern FILE\t* in, * out;\n\n#define\tA2S(x)\t(a2s[  (unsigned char )(x)       ])\n#define\tS2A(x)\t(s2a[ ((unsigned short)(x)) >> 4 ])\n\nstatic unsigned short a2s[] = {\n\n 60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800,\n 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752,\n 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168,\n 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144,\n 43520, 44544, 41472, 42496, 47616, 48640, 45568, 46592,\n 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400,\n 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064,\n 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968,\n 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240,\n 65064, 65080, 65032, 65048, 65128, 65144, 65096, 65112,\n 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496,\n 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368,\n 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352,\n 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840,\n 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944,\n 64592, 64624, 64528, 64560, 64720, 64752, 64656, 64688,\n  5504,  5248,  6016,  5760,  4480,  4224,  4992,  4736,\n  7552,  7296,  8064,  7808,  6528,  6272,  7040,  6784,\n  2752,  2624,  3008,  2880,  2240,  2112,  2496,  2368,\n  3776,  3648,  4032,  3904,  3264,  3136,  3520,  3392,\n 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,\n 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,\n 11008, 10496, 12032, 11520,  8960,  8448,  9984,  9472,\n 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,\n   344,   328,   376,   360,   280,   264,   312,   296,\n   472,   456,   504,   488,   408,   392,   440,   424,\n    88,    72,   120,   104,    24,     8,    56,    40,\n   216,   200,   248,   232,   152,   136,   184,   168,\n  1376,  1312,  1504,  1440,  1120,  1056,  1248,  1184,\n  1888,  1824,  2016,  1952,  1632,  1568,  1760,  1696,\n   688,   656,   752,   720,   560,   528,   624,   592,\n   944,   912,  1008,   976,   816,   784,   880,   848\n\n};\n\n\nstatic unsigned char  s2a[] = {\n\n\t213,212,215,214,209,208,211,210,221,220,223,222,217,216,219,218,\n\t197,196,199,198,193,192,195,194,205,204,207,206,201,200,203,202,\n\t245,245,244,244,247,247,246,246,241,241,240,240,243,243,242,242,\n\t253,253,252,252,255,255,254,254,249,249,248,248,251,251,250,250,\n\t229,229,229,229,228,228,228,228,231,231,231,231,230,230,230,230,\n\t225,225,225,225,224,224,224,224,227,227,227,227,226,226,226,226,\n\t237,237,237,237,236,236,236,236,239,239,239,239,238,238,238,238,\n\t233,233,233,233,232,232,232,232,235,235,235,235,234,234,234,234,\n\t149,149,149,149,149,149,149,149,148,148,148,148,148,148,148,148,\n\t151,151,151,151,151,151,151,151,150,150,150,150,150,150,150,150,\n\t145,145,145,145,145,145,145,145,144,144,144,144,144,144,144,144,\n\t147,147,147,147,147,147,147,147,146,146,146,146,146,146,146,146,\n\t157,157,157,157,157,157,157,157,156,156,156,156,156,156,156,156,\n\t159,159,159,159,159,159,159,159,158,158,158,158,158,158,158,158,\n\t153,153,153,153,153,153,153,153,152,152,152,152,152,152,152,152,\n\t155,155,155,155,155,155,155,155,154,154,154,154,154,154,154,154,\n\t133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,\n\t132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,\n\t135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,\n\t134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,\n\t129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,\n\t128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,\n\t131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,\n\t130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,\n\t141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,\n\t140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,\n\t143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,\n\t142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,\n\t137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,\n\t136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,\n\t139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,\n\t138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,\n\t181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,\n\t181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,\n\t180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,\n\t180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,\n\t183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,\n\t183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,\n\t182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,\n\t182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,\n\t177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,\n\t177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,\n\t176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,\n\t176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,\n\t179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,\n\t179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,\n\t178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,\n\t178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,\n\t189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,\n\t189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,\n\t188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,\n\t188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,\n\t191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,\n\t191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,\n\t190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,\n\t190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,\n\t185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,\n\t185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,\n\t184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,\n\t184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,\n\t187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,\n\t187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,\n\t186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,\n\t186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,\n\t165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,\n\t165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,\n\t165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,\n\t165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,\n\t164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,\n\t164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,\n\t164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,\n\t164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,\n\t167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,\n\t167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,\n\t167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,\n\t167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,\n\t166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,\n\t166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,\n\t166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,\n\t166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,\n\t161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,\n\t161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,\n\t161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,\n\t161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,\n\t160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,\n\t160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,\n\t160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,\n\t160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,\n\t163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,\n\t163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,\n\t163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,\n\t163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,\n\t162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,\n\t162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,\n\t162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,\n\t162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,\n\t173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,\n\t173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,\n\t173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,\n\t173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,\n\t172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,\n\t172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,\n\t172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,\n\t172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,\n\t175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,\n\t175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,\n\t175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,\n\t175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,\n\t174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,\n\t174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,\n\t174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,\n\t174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,\n\t169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,\n\t169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,\n\t169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,\n\t169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,\n\t168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,\n\t168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,\n\t168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,\n\t168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,\n\t171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,\n\t171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,\n\t171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,\n\t171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,\n\t170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,\n\t170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,\n\t170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,\n\t170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,\n\t 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,\n\t 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,\n\t 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,\n\t 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,\n\t 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\n\t 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\n\t 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\n\t 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\n\t 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,\n\t 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,\n\t 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,\n\t 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,\n\t 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,\n\t 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,\n\t 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,\n\t 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,\n\t 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,\n\t 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,\n\t 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,\n\t 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,\n\t 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,\n\t 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,\n\t 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,\n\t 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,\n\t 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n\t 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n\t 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n\t 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n\t 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,\n\t 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,\n\t 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,\n\t 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,\n\t 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,\n\t 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,\n\t 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,\n\t 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,\n\t 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n\t 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n\t 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n\t 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n\t 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,\n\t 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,\n\t 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,\n\t 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,\n\t 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,\n\t 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,\n\t 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,\n\t 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,\n\t 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,\n\t 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,\n\t 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,\n\t 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,\n\t 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,\n\t 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,\n\t 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,\n\t 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,\n\t 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\n\t 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\n\t 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\n\t 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\n\t 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,\n\t 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,\n\t 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,\n\t 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,\n\t 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,\n\t 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,\n\t 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,\n\t 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,\n\t 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,\n\t 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,\n\t 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,\n\t 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,\n\t 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,\n\t 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,\n\t 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,\n\t 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,\n\t 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n\t 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n\t 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,\n\t 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,\n\t 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,\n\t 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,\n\t 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,\n\t 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,\n\t 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,\n\t 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,\n\t 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,\n\t 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,\n\t 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,\n\t 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,\n\t 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,\n\t 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,\n\t 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n\t  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n\t  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,\n\t 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25,\n\t 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31,\n\t 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29,\n\t 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19,\n\t 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17,\n\t 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,\n\t 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21,\n\t106,106,106,106,107,107,107,107,104,104,104,104,105,105,105,105,\n\t110,110,110,110,111,111,111,111,108,108,108,108,109,109,109,109,\n\t 98, 98, 98, 98, 99, 99, 99, 99, 96, 96, 96, 96, 97, 97, 97, 97,\n\t102,102,102,102,103,103,103,103,100,100,100,100,101,101,101,101,\n\t122,122,123,123,120,120,121,121,126,126,127,127,124,124,125,125,\n\t114,114,115,115,112,112,113,113,118,118,119,119,116,116,117,117,\n\t 74, 75, 72, 73, 78, 79, 76, 77, 66, 67, 64, 65, 70, 71, 68, 69,\n\t 90, 91, 88, 89, 94, 95, 92, 93, 82, 83, 80, 81, 86, 87, 84, 85\n};\n\nint alaw_input P1((buf), gsm_signal * buf) \n{\n\tint  i, c;\n\n\tfor (i = 0; i < 160 && (c = fgetc(in)) != EOF; i++) buf[i] = A2S( c );\n\tif (c == EOF && ferror(in)) return -1;\n\treturn i;\n}\n\nint alaw_output P1((buf), gsm_signal * buf) \n{\n\tint  i;\n\n\tfor (i = 0; i < 160; i++, buf++)\n\t\tif (fputc( S2A( *buf ), out) == EOF) return -1;\n\treturn 0;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/toast_audio.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/toast_audio.c,v 1.6 1995/03/07 21:21:24 jutta Exp $ */\n\n#include\t\"toast.h\"\n\n/*  toast_audio -- functions to manipulate SunOS audio files.\n *\n *  This is reverse engineered from our present soundfiles\n *  and in no way portable, durable or aesthetically pleasing.\n */\n\nextern FILE\t* in, \t  * out;\nextern char\t* inname;\nextern char\t* progname;\n\nextern int\t(*output) P((gsm_signal *)),\n\t\t(*input ) P((gsm_signal *));\n\nextern int\talaw_input   P((gsm_signal *)),\n\t\tulaw_input   P((gsm_signal *)),\n\t\tlinear_input P((gsm_signal *));\n\nextern int\tulaw_output P((gsm_signal *));\n\nstatic int put_u32 P2((f, u), FILE * f, unsigned long u)\n{\n\t/*  Write a 32-bit unsigned value msb first. \n\t */\n\tif (  putc( (char)((u>>24) & 0x0FF), f) == EOF\n\t   || putc( (char)((u>>16) & 0x0FF), f) == EOF\n\t   || putc( (char)((u>> 8) & 0x0FF), f) == EOF\n\t   || putc( (char)( u      & 0x0FF), f) == EOF) return -1;\n\n\treturn 0;\n}\n\nstatic int get_u32 P2((f, up), FILE * f, unsigned long * up)\n{\n\t/*  Read a 32-bit unsigned value msb first.\n\t */\n\tint\t\ti;\n\tunsigned long \tu;\n\n\tif (  \t\t\t\t      (i = getc(f)) == EOF\n\t   || ((u =        (unsigned char)i), (i = getc(f)) == EOF)\n\t   || ((u = (u<<8)|(unsigned char)i), (i = getc(f)) == EOF)\n\t   || ((u = (u<<8)|(unsigned char)i), (i = getc(f)) == EOF)) return -1;\n\t*up = \t    (u<<8)|(unsigned char)i;\n\treturn 0;\n}\n\nint audio_init_input P0()\n{\n\tunsigned long\tlen, enc;\t/* unsigned 32 bits\t*/\n\n\tif (  fgetc(in) != '.' \n\t   || fgetc(in) != 's'\n\t   || fgetc(in) != 'n'\n\t   || fgetc(in) != 'd'\n\t   || get_u32( in, &len )\n\t   || get_u32( in, &enc )\t/* skip this */\n\t   || get_u32( in, &enc )) {\n\t\tfprintf(stderr, \n\t\"%s: bad (missing?) header in Sun audio file \\\"%s\\\";\\n\\\n\tTry one of -u, -a, -l instead (%s -h for help).\\n\",\n\t\t\tprogname, inname ? inname : \"stdin\", progname);\n\t\treturn -1;\n\t}\n\n\tswitch (enc) {\n\tcase 1:\tinput = ulaw_input;  \tbreak;\n\tcase 2: input = alaw_input;  \tbreak;\n\tcase 3: input = linear_input; \tbreak;\n\tdefault:\n\t\tfprintf(stderr,\n\"%s: warning: file format #%lu for %s not implemented, defaulting to u-law.\\n\",\n\t\t\tprogname, enc, inname);\n\t\tinput = ulaw_input;\n\t\tbreak;\n\t}\n\n\twhile (len > 4*4)\n\t\tif (getc(in) == EOF) {\n\t\t\tfprintf(stderr, \n\t\t\t\"%s: EOF in header of Sun audio file \\\"%s\\\";\\n\\\n\t\t\tTry one of -u, -a, -l instead (%s -h for help).\\n\",\n\t\t\t\tprogname, inname ? inname : \"stdin\", progname);\n\t\t\treturn -1;\n\t\t}\n\t\telse len--;\n\n\treturn 0;\n}\n\nint audio_init_output P0()\n{\n\tif (  fputs(\".snd\", out) == EOF\n\t   || put_u32(out, 32)\n\t   || put_u32(out, ~(unsigned long)0)\n\t   || put_u32(out, 1)\n\t   || put_u32(out, 8000)\n\t   || put_u32(out, 1)\n\t   || put_u32(out, 0)\n\t   || put_u32(out, 0)) return -1;\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/toast_lin.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/toast_lin.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */\n\n#include\t\"toast.h\"\n\n/*  toast_linear.c -- read and write 16 bit linear sound in host byte order.\n */\n\nextern FILE\t*in, *out;\n\nint linear_input (buf) gsm_signal * buf;\n{\n\treturn fread( (char *)buf, sizeof(*buf), 160, in );\n}\n\nint linear_output P1((buf), gsm_signal * buf) \n{\n\treturn -( fwrite( (char *)buf, sizeof(*buf), 160, out ) != 160 );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/src/toast_ulaw.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/toast_ulaw.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */\n\n#include\t\"toast.h\"\n\n/* toast_ulaw -- functions to manipulate u-law encoded sound.\n */\n\nextern FILE\t*in, *out;\n\n#define\tU2S(x)\t(u2s[  (unsigned  char)(x)       ])\n#define\tS2U(x)\t(s2u[ ((unsigned short)(x)) >> 3 ])\n\nstatic unsigned short u2s[] = {\n\t33280, 34308, 35336, 36364, 37393, 38421, 39449, 40477,\n\t41505, 42534, 43562, 44590, 45618, 46647, 47675, 48703,\n\t49474, 49988, 50503, 51017, 51531, 52045, 52559, 53073,\n\t53587, 54101, 54616, 55130, 55644, 56158, 56672, 57186,\n\t57572, 57829, 58086, 58343, 58600, 58857, 59114, 59371,\n\t59628, 59885, 60142, 60399, 60656, 60913, 61171, 61428,\n\t61620, 61749, 61877, 62006, 62134, 62263, 62392, 62520,\n\t62649, 62777, 62906, 63034, 63163, 63291, 63420, 63548,\n\t63645, 63709, 63773, 63838, 63902, 63966, 64030, 64095,\n\t64159, 64223, 64287, 64352, 64416, 64480, 64544, 64609,\n\t64657, 64689, 64721, 64753, 64785, 64818, 64850, 64882,\n\t64914, 64946, 64978, 65010, 65042, 65075, 65107, 65139,\n\t65163, 65179, 65195, 65211, 65227, 65243, 65259, 65275,\n\t65291, 65308, 65324, 65340, 65356, 65372, 65388, 65404,\n\t65416, 65424, 65432, 65440, 65448, 65456, 65464, 65472,\n\t65480, 65488, 65496, 65504, 65512, 65520, 65528,     0,\n\t32256, 31228, 30200, 29172, 28143, 27115, 26087, 25059,\n\t24031, 23002, 21974, 20946, 19918, 18889, 17861, 16833,\n\t16062, 15548, 15033, 14519, 14005, 13491, 12977, 12463,\n\t11949, 11435, 10920, 10406,  9892,  9378,  8864,  8350,\n\t 7964,  7707,  7450,  7193,  6936,  6679,  6422,  6165, \n\t 5908,  5651,  5394,  5137,  4880,  4623,  4365,  4108, \n\t 3916,  3787,  3659,  3530,  3402,  3273,  3144,  3016, \n\t 2887,  2759,  2630,  2502,  2373,  2245,  2116,  1988, \n\t 1891,  1827,  1763,  1698,  1634,  1570,  1506,  1441, \n\t 1377,  1313,  1249,  1184,  1120,  1056,   992,   927, \n\t  879,   847,   815,   783,   751,   718,   686,   654,\n\t  622,   590,   558,   526,   494,   461,   429,   397,\n\t  373,   357,   341,   325,   309,   293,   277,   261,\n\t  245,   228,   212,   196,   180,   164,   148,   132,\n\t  120,   112,   104,    96,    88,    80,    72,    64,\n \t   56,    48,    40,    32,    24,    16,    8,      0\n};\n\nstatic unsigned char s2u[] = {\n0377,0376,0375,0374,0373,0372,0371,0370,0367,0366,0365,0364,0363,0362,0361,\n0360,0357,0357,0356,0356,0355,0355,0354,0354,0353,0353,0352,0352,0351,0351,\n0350,0350,0347,0347,0346,0346,0345,0345,0344,0344,0343,0343,0342,0342,0341,\n0341,0340,0340,0337,0337,0337,0337,0336,0336,0336,0336,0335,0335,0335,0335,\n0334,0334,0334,0334,0333,0333,0333,0333,0332,0332,0332,0332,0331,0331,0331,\n0331,0330,0330,0330,0330,0327,0327,0327,0327,0326,0326,0326,0326,0325,0325,\n0325,0325,0324,0324,0324,0324,0323,0323,0323,0323,0322,0322,0322,0322,0321,\n0321,0321,0321,0320,0320,0320,0320,0317,0317,0317,0317,0317,0317,0317,0317,\n0316,0316,0316,0316,0316,0316,0316,0316,0315,0315,0315,0315,0315,0315,0315,\n0315,0314,0314,0314,0314,0314,0314,0314,0314,0313,0313,0313,0313,0313,0313,\n0313,0313,0312,0312,0312,0312,0312,0312,0312,0312,0311,0311,0311,0311,0311,\n0311,0311,0311,0310,0310,0310,0310,0310,0310,0310,0310,0307,0307,0307,0307,\n0307,0307,0307,0307,0306,0306,0306,0306,0306,0306,0306,0306,0305,0305,0305,\n0305,0305,0305,0305,0305,0304,0304,0304,0304,0304,0304,0304,0304,0303,0303,\n0303,0303,0303,0303,0303,0303,0303,0302,0302,0302,0302,0302,0302,0302,0302,\n0301,0301,0301,0301,0301,0301,0301,0301,0300,0300,0300,0300,0300,0300,0300,\n0300,0277,0277,0277,0277,0277,0277,0277,0277,0277,0277,0277,0277,0277,0277,\n0277,0277,0276,0276,0276,0276,0276,0276,0276,0276,0276,0276,0276,0276,0276,\n0276,0276,0276,0275,0275,0275,0275,0275,0275,0275,0275,0275,0275,0275,0275,\n0275,0275,0275,0275,0274,0274,0274,0274,0274,0274,0274,0274,0274,0274,0274,\n0274,0274,0274,0274,0274,0273,0273,0273,0273,0273,0273,0273,0273,0273,0273,\n0273,0273,0273,0273,0273,0273,0272,0272,0272,0272,0272,0272,0272,0272,0272,\n0272,0272,0272,0272,0272,0272,0272,0271,0271,0271,0271,0271,0271,0271,0271,\n0271,0271,0271,0271,0271,0271,0271,0271,0270,0270,0270,0270,0270,0270,0270,\n0270,0270,0270,0270,0270,0270,0270,0270,0270,0267,0267,0267,0267,0267,0267,\n0267,0267,0267,0267,0267,0267,0267,0267,0267,0267,0266,0266,0266,0266,0266,\n0266,0266,0266,0266,0266,0266,0266,0266,0266,0266,0266,0265,0265,0265,0265,\n0265,0265,0265,0265,0265,0265,0265,0265,0265,0265,0265,0265,0264,0264,0264,\n0264,0264,0264,0264,0264,0264,0264,0264,0264,0264,0264,0264,0264,0263,0263,\n0263,0263,0263,0263,0263,0263,0263,0263,0263,0263,0263,0263,0263,0263,0262,\n0262,0262,0262,0262,0262,0262,0262,0262,0262,0262,0262,0262,0262,0262,0262,\n0262,0261,0261,0261,0261,0261,0261,0261,0261,0261,0261,0261,0261,0261,0261,\n0261,0261,0260,0260,0260,0260,0260,0260,0260,0260,0260,0260,0260,0260,0260,\n0260,0260,0260,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,\n0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,\n0257,0257,0257,0257,0257,0256,0256,0256,0256,0256,0256,0256,0256,0256,0256,\n0256,0256,0256,0256,0256,0256,0256,0256,0256,0256,0256,0256,0256,0256,0256,\n0256,0256,0256,0256,0256,0256,0256,0255,0255,0255,0255,0255,0255,0255,0255,\n0255,0255,0255,0255,0255,0255,0255,0255,0255,0255,0255,0255,0255,0255,0255,\n0255,0255,0255,0255,0255,0255,0255,0255,0255,0254,0254,0254,0254,0254,0254,\n0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,\n0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0253,0253,0253,0253,\n0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,\n0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0252,0252,\n0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,\n0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,\n0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,\n0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,\n0251,0251,0251,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,\n0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,\n0250,0250,0250,0250,0250,0247,0247,0247,0247,0247,0247,0247,0247,0247,0247,\n0247,0247,0247,0247,0247,0247,0247,0247,0247,0247,0247,0247,0247,0247,0247,\n0247,0247,0247,0247,0247,0247,0247,0246,0246,0246,0246,0246,0246,0246,0246,\n0246,0246,0246,0246,0246,0246,0246,0246,0246,0246,0246,0246,0246,0246,0246,\n0246,0246,0246,0246,0246,0246,0246,0246,0246,0245,0245,0245,0245,0245,0245,\n0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,\n0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0244,0244,0244,0244,\n0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,\n0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0243,0243,\n0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,\n0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,\n0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,\n0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,\n0242,0242,0242,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,\n0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,\n0241,0241,0241,0241,0241,0240,0240,0240,0240,0240,0240,0240,0240,0240,0240,\n0240,0240,0240,0240,0240,0240,0240,0240,0240,0240,0240,0240,0240,0240,0240,\n0240,0240,0240,0240,0240,0240,0240,0237,0237,0237,0237,0237,0237,0237,0237,\n0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,\n0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,\n0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,\n0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0236,0236,0236,0236,\n0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,\n0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,\n0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,\n0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,\n0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,\n0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,\n0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,\n0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,\n0235,0235,0235,0235,0235,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,\n0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,\n0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,\n0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,\n0234,0234,0234,0234,0234,0234,0234,0234,0234,0233,0233,0233,0233,0233,0233,\n0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,\n0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,\n0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,\n0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0232,0232,\n0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,\n0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,\n0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,\n0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,\n0232,0232,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,\n0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,\n0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,\n0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,\n0231,0231,0231,0231,0231,0231,0231,0230,0230,0230,0230,0230,0230,0230,0230,\n0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,\n0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,\n0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,\n0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0227,0227,0227,0227,\n0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,\n0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,\n0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,\n0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,\n0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,\n0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,\n0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,\n0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,\n0226,0226,0226,0226,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,\n0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,\n0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,\n0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,\n0225,0225,0225,0225,0225,0225,0225,0225,0225,0224,0224,0224,0224,0224,0224,\n0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,\n0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,\n0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,\n0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0223,0223,\n0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,\n0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,\n0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,\n0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,\n0223,0223,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,\n0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,\n0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,\n0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,\n0222,0222,0222,0222,0222,0222,0221,0221,0221,0221,0221,0221,0221,0221,0221,\n0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,\n0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,\n0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,\n0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0220,0220,0220,0220,\n0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,\n0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,\n0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,\n0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,\n0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,\n0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,\n0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,\n0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,\n0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,\n0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,\n0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,\n0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,\n0217,0217,0217,0217,0217,0217,0217,0217,0217,0216,0216,0216,0216,0216,0216,\n0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,\n0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,\n0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,\n0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,\n0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,\n0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,\n0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,\n0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,\n0216,0216,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,\n0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,\n0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,\n0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,\n0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,\n0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,\n0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,\n0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,\n0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0214,0214,0214,0214,\n0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,\n0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,\n0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,\n0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,\n0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,\n0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,\n0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,\n0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,\n0214,0214,0214,0214,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,\n0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,\n0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,\n0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,\n0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,\n0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,\n0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,\n0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,\n0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0212,0212,\n0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,\n0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,\n0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,\n0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,\n0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,\n0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,\n0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,\n0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,\n0212,0212,0212,0212,0212,0212,0211,0211,0211,0211,0211,0211,0211,0211,0211,\n0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,\n0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,\n0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,\n0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,\n0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,\n0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,\n0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,\n0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,\n0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,\n0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,\n0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,\n0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,\n0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,\n0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,\n0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,\n0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,\n0210,0210,0210,0210,0210,0210,0210,0210,0207,0207,0207,0207,0207,0207,0207,\n0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,\n0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,\n0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,\n0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,\n0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,\n0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,\n0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,\n0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,\n0207,0207,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,\n0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,\n0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,\n0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,\n0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,\n0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,\n0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,\n0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,\n0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0205,0205,0205,0205,0205,\n0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,\n0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,\n0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,\n0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,\n0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,\n0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,\n0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,\n0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,\n0205,0205,0205,0205,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,\n0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,\n0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,\n0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,\n0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,\n0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,\n0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,\n0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,\n0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0203,0203,0203,\n0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,\n0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,\n0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,\n0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,\n0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,\n0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,\n0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,\n0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,\n0203,0203,0203,0203,0203,0203,0202,0202,0202,0202,0202,0202,0202,0202,0202,\n0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,\n0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,\n0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,\n0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,\n0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,\n0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,\n0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,\n0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0201,\n0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,\n0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,\n0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,\n0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,\n0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,\n0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,\n0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,\n0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,\n0201,0201,0201,0201,0201,0201,0201,0201,0200,0200,0200,0200,0200,0200,0200,\n0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,\n0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,\n0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,\n0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,\n0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,\n0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,\n0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,\n0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,\n0200,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,\n0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,\n0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,\n0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,\n0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,\n0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,\n0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,\n0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,\n0000,0000,0000,0000,0000,0000,0000,0000,0000,0001,0001,0001,0001,0001,0001,\n0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,\n0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,\n0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,\n0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,\n0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,\n0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,\n0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,\n0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,\n0001,0001,0001,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,\n0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,\n0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,\n0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,\n0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,\n0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,\n0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,\n0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,\n0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0003,0003,0003,0003,\n0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,\n0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,\n0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,\n0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,\n0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,\n0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,\n0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,\n0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,\n0003,0003,0003,0003,0003,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,\n0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,\n0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,\n0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,\n0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,\n0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,\n0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,\n0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,\n0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0005,0005,\n0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,\n0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,\n0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,\n0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,\n0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,\n0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,\n0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,\n0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,\n0005,0005,0005,0005,0005,0005,0005,0006,0006,0006,0006,0006,0006,0006,0006,\n0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,\n0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,\n0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,\n0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,\n0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,\n0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,\n0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,\n0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,\n0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,\n0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,\n0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,\n0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,\n0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,\n0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,\n0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,\n0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,\n0007,0007,0007,0007,0007,0007,0007,0007,0007,0010,0010,0010,0010,0010,0010,\n0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,\n0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,\n0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,\n0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,\n0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,\n0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,\n0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,\n0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,\n0010,0010,0010,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,\n0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,\n0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,\n0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,\n0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,\n0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,\n0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,\n0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,\n0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0012,0012,0012,0012,\n0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,\n0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,\n0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,\n0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,\n0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,\n0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,\n0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,\n0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,\n0012,0012,0012,0012,0012,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,\n0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,\n0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,\n0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,\n0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,\n0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,\n0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,\n0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,\n0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0014,0014,\n0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,\n0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,\n0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,\n0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,\n0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,\n0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,\n0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,\n0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,\n0014,0014,0014,0014,0014,0014,0014,0015,0015,0015,0015,0015,0015,0015,0015,\n0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,\n0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,\n0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,\n0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,\n0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,\n0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,\n0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,\n0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,\n0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,\n0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,\n0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,\n0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,\n0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,\n0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,\n0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,\n0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,\n0016,0016,0016,0016,0016,0016,0016,0016,0016,0017,0017,0017,0017,0017,0017,\n0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,\n0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,\n0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,\n0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,\n0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,\n0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,\n0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,\n0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,\n0017,0017,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,\n0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,\n0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,\n0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,\n0020,0020,0020,0020,0020,0020,0021,0021,0021,0021,0021,0021,0021,0021,0021,\n0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,\n0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,\n0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,\n0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0022,0022,0022,0022,\n0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,\n0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,\n0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,\n0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,\n0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,\n0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,\n0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,\n0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,\n0023,0023,0023,0023,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,\n0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,\n0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,\n0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,\n0024,0024,0024,0024,0024,0024,0024,0024,0024,0025,0025,0025,0025,0025,0025,\n0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,\n0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,\n0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,\n0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0026,0026,\n0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,\n0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,\n0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,\n0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,\n0026,0026,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,\n0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,\n0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,\n0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,\n0027,0027,0027,0027,0027,0027,0030,0030,0030,0030,0030,0030,0030,0030,0030,\n0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,\n0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,\n0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,\n0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0031,0031,0031,0031,\n0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,\n0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,\n0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,\n0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,\n0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,\n0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,\n0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,\n0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,\n0032,0032,0032,0032,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,\n0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,\n0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,\n0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,\n0033,0033,0033,0033,0033,0033,0033,0033,0034,0034,0034,0034,0034,0034,0034,\n0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,\n0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,\n0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,\n0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0035,0035,\n0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,\n0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,\n0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,\n0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,\n0035,0035,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,\n0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,\n0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,\n0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,\n0036,0036,0036,0036,0036,0036,0037,0037,0037,0037,0037,0037,0037,0037,0037,\n0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,\n0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,\n0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,\n0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0040,0040,0040,0040,0040,\n0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,\n0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0041,0041,\n0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,\n0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,\n0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,\n0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,\n0042,0042,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,\n0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,\n0043,0043,0043,0043,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,\n0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,\n0044,0044,0044,0044,0044,0044,0045,0045,0045,0045,0045,0045,0045,0045,0045,\n0045,0045,0045,0045,0045,0045,0045,0045,0045,0045,0045,0045,0045,0045,0045,\n0045,0045,0045,0045,0045,0045,0045,0045,0046,0046,0046,0046,0046,0046,0046,\n0046,0046,0046,0046,0046,0046,0046,0046,0046,0046,0046,0046,0046,0046,0046,\n0046,0046,0046,0046,0046,0046,0046,0046,0046,0046,0047,0047,0047,0047,0047,\n0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,\n0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0050,0050,\n0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,\n0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,\n0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,\n0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,\n0051,0051,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,\n0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,\n0052,0052,0052,0052,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,\n0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,\n0053,0053,0053,0053,0053,0053,0054,0054,0054,0054,0054,0054,0054,0054,0054,\n0054,0054,0054,0054,0054,0054,0054,0054,0054,0054,0054,0054,0054,0054,0054,\n0054,0054,0054,0054,0054,0054,0054,0054,0055,0055,0055,0055,0055,0055,0055,\n0055,0055,0055,0055,0055,0055,0055,0055,0055,0055,0055,0055,0055,0055,0055,\n0055,0055,0055,0055,0055,0055,0055,0055,0055,0055,0056,0056,0056,0056,0056,\n0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,\n0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0057,0057,0057,\n0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,\n0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,\n0060,0060,0060,0060,0060,0060,0060,0060,0060,0060,0060,0060,0060,0060,0060,\n0060,0061,0061,0061,0061,0061,0061,0061,0061,0061,0061,0061,0061,0061,0061,\n0061,0061,0062,0062,0062,0062,0062,0062,0062,0062,0062,0062,0062,0062,0062,\n0062,0062,0062,0063,0063,0063,0063,0063,0063,0063,0063,0063,0063,0063,0063,\n0063,0063,0063,0063,0064,0064,0064,0064,0064,0064,0064,0064,0064,0064,0064,\n0064,0064,0064,0064,0064,0065,0065,0065,0065,0065,0065,0065,0065,0065,0065,\n0065,0065,0065,0065,0065,0065,0066,0066,0066,0066,0066,0066,0066,0066,0066,\n0066,0066,0066,0066,0066,0066,0066,0067,0067,0067,0067,0067,0067,0067,0067,\n0067,0067,0067,0067,0067,0067,0067,0067,0070,0070,0070,0070,0070,0070,0070,\n0070,0070,0070,0070,0070,0070,0070,0070,0070,0071,0071,0071,0071,0071,0071,\n0071,0071,0071,0071,0071,0071,0071,0071,0071,0071,0072,0072,0072,0072,0072,\n0072,0072,0072,0072,0072,0072,0072,0072,0072,0072,0072,0073,0073,0073,0073,\n0073,0073,0073,0073,0073,0073,0073,0073,0073,0073,0073,0073,0074,0074,0074,\n0074,0074,0074,0074,0074,0074,0074,0074,0074,0074,0074,0074,0074,0075,0075,\n0075,0075,0075,0075,0075,0075,0075,0075,0075,0075,0075,0075,0075,0075,0075,\n0076,0076,0076,0076,0076,0076,0076,0076,0076,0076,0076,0076,0076,0076,0076,\n0076,0077,0077,0077,0077,0077,0077,0077,0077,0077,0077,0077,0077,0077,0077,\n0077,0077,0100,0100,0100,0100,0100,0100,0100,0100,0101,0101,0101,0101,0101,\n0101,0101,0101,0102,0102,0102,0102,0102,0102,0102,0102,0103,0103,0103,0103,\n0103,0103,0103,0103,0104,0104,0104,0104,0104,0104,0104,0104,0105,0105,0105,\n0105,0105,0105,0105,0105,0106,0106,0106,0106,0106,0106,0106,0106,0107,0107,\n0107,0107,0107,0107,0107,0107,0110,0110,0110,0110,0110,0110,0110,0110,0111,\n0111,0111,0111,0111,0111,0111,0111,0112,0112,0112,0112,0112,0112,0112,0112,\n0113,0113,0113,0113,0113,0113,0113,0113,0114,0114,0114,0114,0114,0114,0114,\n0114,0115,0115,0115,0115,0115,0115,0115,0115,0116,0116,0116,0116,0116,0116,\n0116,0116,0117,0117,0117,0117,0117,0117,0117,0117,0120,0120,0120,0120,0121,\n0121,0121,0121,0122,0122,0122,0122,0123,0123,0123,0123,0124,0124,0124,0124,\n0125,0125,0125,0125,0126,0126,0126,0126,0127,0127,0127,0127,0130,0130,0130,\n0130,0131,0131,0131,0131,0132,0132,0132,0132,0133,0133,0133,0133,0134,0134,\n0134,0134,0135,0135,0135,0135,0136,0136,0136,0136,0137,0137,0137,0137,0140,\n0140,0141,0141,0142,0142,0143,0143,0144,0144,0145,0145,0146,0146,0147,0147,\n0150,0150,0150,0151,0151,0152,0152,0153,0153,0154,0154,0155,0155,0156,0156,\n0157,0157,0160,0161,0162,0163,0164,0165,0166,0167,0170,0171,0172,0173,0174,\n0175,0176\n};\n\nint ulaw_input P1((buf), gsm_signal * buf)\n{\n\tint i, c;\n\n\tfor (i = 0; i < 160 && (c = fgetc(in)) != EOF; i++) buf[i] = U2S(c);\n\tif (c == EOF && ferror(in)) return -1;\n\treturn i;\n}\n\nint ulaw_output P1((buf), gsm_signal * buf)\n{\n\tint i;\n\n\tfor(i = 0; i < 160; i++, buf++)\n\t\tif (fputc( (char)S2U( (unsigned short)*buf ), out) == EOF)\n\t\t\treturn -1;\n\treturn 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tls/bitter.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/bitter.c,v 1.1 1992/10/28 00:28:39 jutta Exp $*/\n\n/* Generate code to pack a bit array from a name:#bits description */\n\n#include\t<stdio.h>\n#include\t\"taste.h\"\n#include\t\"proto.h\"\n\nvoid write_code P2((s_spex, n_spex), struct spex * s_spex, int n_spex)\n{\n\tstruct spex\t* sp = s_spex;\n\tint\t\tbits = 8;\n\tint\t\tvars;\n\n\tif (!n_spex) return;\n\n\tvars = sp->varsize;\n\n\twhile (n_spex) {\n\n\t\tif (bits == 8) printf(\"\\t*c++ =   \");\n\t\telse printf(\"\\t       | \");\n\n\t\tif (vars == bits) {\n\t\n\t\t\tprintf( (bits==8? \"%s & 0x%lX;\\n\" : \"(%s & 0x%lX);\\n\"),\n\t\t\t\tsp->var, \n\t\t\t\t~(0xfffffffe << (bits - 1)));\n\t\t\tif (!-- n_spex) break;\n\t\t\tsp++;\n\n\t\t\tvars = sp->varsize;\n\t\t\tbits = 8;\n\n\t\t} else if (vars < bits) {\n\n\t\t\tprintf( \"((%s & 0x%lX) << %d)\",\n\t\t\t\tsp->var,\n\t\t\t\t~(0xfffffffe << (vars - 1)),\n\t\t\t\tbits - vars);\n\t\t\tbits -= vars;\n\t\t\tif (!--n_spex) {\n\t\t\t\tputs(\";\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse putchar('\\n');\n\t\t\tsp++;\n\t\t\tvars = sp->varsize;\n\n\t\t} else {\n\t\t\tprintf(\"((%s >> %d) & 0x%X);\\n\",\n\t\t\t\tsp->var, \n\t\t\t\tvars - bits,\n\t\t\t\t~(0xfffffffe << (bits - 1)));\n\t\t\t\n\t\t\tvars -= bits;\n\t\t\tbits = 8;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tls/bitter.dta",
    "content": ";\n; Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n; Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n; details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n;\n;\n; Variable     Size\n\nGSM_MAGIC\t4\n\nLARc[0]\t\t6\nLARc[1]\t\t6\nLARc[2]\t\t5\nLARc[3]\t\t5\nLARc[4]\t\t4\nLARc[5]\t\t4\nLARc[6]\t\t3\nLARc[7]\t\t3\n\nNc[0]\t\t7\nbc[0]\t\t2\nMc[0]\t\t2\nxmaxc[0]\t6\nxmc[0]\t\t3\nxmc[1]\t\t3\nxmc[2]\t\t3\nxmc[3]\t\t3\nxmc[4]\t\t3\nxmc[5]\t\t3\nxmc[6]\t\t3\nxmc[7]\t\t3\nxmc[8]\t\t3\nxmc[9]\t\t3\nxmc[10]\t\t3\nxmc[11]\t\t3\nxmc[12]\t\t3\n\nNc[1]\t\t7\nbc[1]\t\t2\nMc[1]\t\t2\nxmaxc[1]\t6\nxmc[13]\t\t3\nxmc[14]\t\t3\nxmc[15]\t\t3\nxmc[16]\t\t3\nxmc[17]\t\t3\nxmc[18]\t\t3\nxmc[19]\t\t3\nxmc[20]\t\t3\nxmc[21]\t\t3\nxmc[22]\t\t3\nxmc[23]\t\t3\nxmc[24]\t\t3\nxmc[25]\t\t3\n\nNc[2]\t\t7\nbc[2]\t\t2\nMc[2]\t\t2\nxmaxc[2]\t6\nxmc[26]\t\t3\nxmc[27]\t\t3\nxmc[28]\t\t3\nxmc[29]\t\t3\nxmc[30]\t\t3\nxmc[31]\t\t3\nxmc[32]\t\t3\nxmc[33]\t\t3\nxmc[34]\t\t3\nxmc[35]\t\t3\nxmc[36]\t\t3\nxmc[37]\t\t3\nxmc[38]\t\t3\n\nNc[3]\t\t7\nbc[3]\t\t2\nMc[3]\t\t2\nxmaxc[3]\t6\nxmc[39]\t\t3\nxmc[40]\t\t3\nxmc[41]\t\t3\nxmc[42]\t\t3\nxmc[43]\t\t3\nxmc[44]\t\t3\nxmc[45]\t\t3\nxmc[46]\t\t3\nxmc[47]\t\t3\nxmc[48]\t\t3\nxmc[49]\t\t3\nxmc[50]\t\t3\nxmc[51]\t\t3\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tls/ginger.c",
    "content": "/*\n * Copyright 1996 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header*/\n\n/* Generate code to pack a bit array from a name:#bits description */\n\n#include\t<stdio.h>\n#include\t\"taste.h\"\n#include\t\"proto.h\"\n#include\t<limits.h>\n\n/* This module is the opposite of sour.   Sweet was already taken,\n * that's why it's called ginger.  (Add one point if that reminds\n * you of Gary Larson.)\n */\n\n#define WORD_BITS\t16\t/* sizeof(uword) * CHAR_BIT on the \n\t\t\t\t * target architecture---if this isn't 16,\n\t\t\t\t * you're in trouble with this library anyway.\n\t\t\t\t */\n\n#define BYTE_BITS\t 8\t/* CHAR_BIT on the target architecture---\n\t\t\t\t * if this isn't 8, you're in *deep* trouble.\n\t\t\t\t */\n\nvoid write_code P2((s_spex, n_spex), struct spex * s_spex, int n_spex)\n{\n\tstruct spex\t* sp = s_spex;\n\tint\t\t  n_in = 0;\n\n\tprintf(\"uword sr = 0;\\n\");\n\n\tfor (; n_spex > 0; n_spex--, sp++) {\n\n\t\twhile (n_in < sp->varsize) {\n\t\t\tif (n_in) printf(\"sr |= (uword)*c++ << %d;\\n\", n_in);\n\t\t\telse printf(\"sr = *c++;\\n\");\n\t\t\tn_in += BYTE_BITS;\n\t\t}\n\n\t\tprintf(\"%s = sr & %#x;  sr >>= %d;\\n\",\n\t\t\tsp->var, ~(~0U << sp->varsize), sp->varsize);\n\n\t\tn_in -= sp->varsize;\n\t}\n\n\tif (n_in > 0) {\n\t\tfprintf(stderr, \"%d bits left over\\n\", n_in);\n\t}\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tls/sour.c",
    "content": "/*\n * Copyright 1996 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header*/\n\n/* Generate code to pack a bit array from a name:#bits description,\n * WAV #49 style.\n */\n\n#include\t<stdio.h>\n#include\t\"taste.h\"\n#include\t\"proto.h\"\n#include\t<limits.h>\n\n/* This module goes back to one Jeff Chilton used for his implementation\n * of the #49 WAV GSM format.  (In his original patch 8, it replaced\n * bitter.c.)\n *\n * In Microsoft's WAV #49 version of the GSM format, two 32 1/2\n * byte GSM frames are packed together to make one WAV frame, and\n * the GSM parameters are packed into bytes right-to-left rather\n * than left-to-right.\n *\n * That is, where toast's GSM format writes\n *\n * \taaaaaabb bbbbcccc cdddddee ...\n *\t___1____ ___2____ ___3____\n *\n *  for parameters a (6 bits), b (6 bits), c (5 bits), d (5 bits), e ..\n *  the WAV format has\n *\n * \tbbaaaaaa ccccbbbb eedddddc ...\n *\t___1____ ___2____ ___3____\n *\n *  (This format looks a lot prettier if one pictures octets coming\n *  in through a fifo queue from the left, rather than waiting in the\n *  right-hand remainder of a C array.)\n */\n\n#define WORD_BITS\t16\t/* sizeof(uword) * CHAR_BIT on the \n\t\t\t\t * target architecture---if this isn't 16,\n\t\t\t\t * you're in trouble with this library anyway.\n\t\t\t\t */\n\n#define BYTE_BITS\t 8\t/* CHAR_BIT on the target architecture---\n\t\t\t\t * if this isn't 8, you're in *deep* trouble.\n\t\t\t\t */\n\nvoid write_code P2((s_spex, n_spex), struct spex * s_spex, int n_spex)\n{\n\tstruct spex\t* sp = s_spex;\n\tint\t\t  n_in = 0;\n\n\tprintf(\"uword sr = 0;\\n\");\n\n\tfor (; n_spex > 0; n_spex--, sp++) {\n\n\t\t/*\tinsert       old \n\t\t *\tnew var\t     value     unused\n\t\t *\there  \n\t\t *\n\t\t *\t[____________xxxxxx**********]\n\t\t *\n\t\t *\t<----- n_in ------>\n\t\t */\n\t\tprintf(\"sr = sr >> %d | %s << %d;\\n\",\n\t\t\tsp->varsize,\n\t\t\tsp->var, \n\t\t\tWORD_BITS - sp->varsize);\n\n\t\tn_in += sp->varsize;\n\n\t\twhile (n_in >= BYTE_BITS) {\n\t\t\tprintf(\"*c++ = sr >> %d;\\n\",\n\t\t\t\tWORD_BITS - n_in);\n\t\t\tn_in -= BYTE_BITS;\n\t\t}\n\t}\n\n\twhile (n_in >= BYTE_BITS) {\n\t\tprintf(\"*c++ = sr >> %d;\\n\", WORD_BITS - n_in);\n\t\tn_in -= BYTE_BITS;\n\t}\n\n\tif (n_in > 0) {\n\t\tfprintf(stderr, \"warning: %d bits left over\\n\", n_in);\n\t}\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tls/sour1.dta",
    "content": ";\n; Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n; Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n; details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n;\n;\n; Variable     Size\n\nLARc[0]\t\t6\nLARc[1]\t\t6\nLARc[2]\t\t5\nLARc[3]\t\t5\nLARc[4]\t\t4\nLARc[5]\t\t4\nLARc[6]\t\t3\nLARc[7]\t\t3\n\nNc[0]\t\t7\nbc[0]\t\t2\nMc[0]\t\t2\nxmaxc[0]\t6\nxmc[0]\t\t3\nxmc[1]\t\t3\nxmc[2]\t\t3\nxmc[3]\t\t3\nxmc[4]\t\t3\nxmc[5]\t\t3\nxmc[6]\t\t3\nxmc[7]\t\t3\nxmc[8]\t\t3\nxmc[9]\t\t3\nxmc[10]\t\t3\nxmc[11]\t\t3\nxmc[12]\t\t3\n\nNc[1]\t\t7\nbc[1]\t\t2\nMc[1]\t\t2\nxmaxc[1]\t6\nxmc[13]\t\t3\nxmc[14]\t\t3\nxmc[15]\t\t3\nxmc[16]\t\t3\nxmc[17]\t\t3\nxmc[18]\t\t3\nxmc[19]\t\t3\nxmc[20]\t\t3\nxmc[21]\t\t3\nxmc[22]\t\t3\nxmc[23]\t\t3\nxmc[24]\t\t3\nxmc[25]\t\t3\n\nNc[2]\t\t7\nbc[2]\t\t2\nMc[2]\t\t2\nxmaxc[2]\t6\nxmc[26]\t\t3\nxmc[27]\t\t3\nxmc[28]\t\t3\nxmc[29]\t\t3\nxmc[30]\t\t3\nxmc[31]\t\t3\nxmc[32]\t\t3\nxmc[33]\t\t3\nxmc[34]\t\t3\nxmc[35]\t\t3\nxmc[36]\t\t3\nxmc[37]\t\t3\nxmc[38]\t\t3\n\nNc[3]\t\t7\nbc[3]\t\t2\nMc[3]\t\t2\nxmaxc[3]\t6\nxmc[39]\t\t3\nxmc[40]\t\t3\nxmc[41]\t\t3\nxmc[42]\t\t3\nxmc[43]\t\t3\nxmc[44]\t\t3\nxmc[45]\t\t3\nxmc[46]\t\t3\nxmc[47]\t\t3\nxmc[48]\t\t3\nxmc[49]\t\t3\nxmc[50]\t\t3\nxmc[51]\t\t3\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tls/sour2.dta",
    "content": ";\n; Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n; Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n; details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n;\n;\n; Variable     Size\n\ng->chain\t4\n\nLARc[0]\t\t6\nLARc[1]\t\t6\nLARc[2]\t\t5\nLARc[3]\t\t5\nLARc[4]\t\t4\nLARc[5]\t\t4\nLARc[6]\t\t3\nLARc[7]\t\t3\n\nNc[0]\t\t7\nbc[0]\t\t2\nMc[0]\t\t2\nxmaxc[0]\t6\nxmc[0]\t\t3\nxmc[1]\t\t3\nxmc[2]\t\t3\nxmc[3]\t\t3\nxmc[4]\t\t3\nxmc[5]\t\t3\nxmc[6]\t\t3\nxmc[7]\t\t3\nxmc[8]\t\t3\nxmc[9]\t\t3\nxmc[10]\t\t3\nxmc[11]\t\t3\nxmc[12]\t\t3\n\nNc[1]\t\t7\nbc[1]\t\t2\nMc[1]\t\t2\nxmaxc[1]\t6\nxmc[13]\t\t3\nxmc[14]\t\t3\nxmc[15]\t\t3\nxmc[16]\t\t3\nxmc[17]\t\t3\nxmc[18]\t\t3\nxmc[19]\t\t3\nxmc[20]\t\t3\nxmc[21]\t\t3\nxmc[22]\t\t3\nxmc[23]\t\t3\nxmc[24]\t\t3\nxmc[25]\t\t3\n\nNc[2]\t\t7\nbc[2]\t\t2\nMc[2]\t\t2\nxmaxc[2]\t6\nxmc[26]\t\t3\nxmc[27]\t\t3\nxmc[28]\t\t3\nxmc[29]\t\t3\nxmc[30]\t\t3\nxmc[31]\t\t3\nxmc[32]\t\t3\nxmc[33]\t\t3\nxmc[34]\t\t3\nxmc[35]\t\t3\nxmc[36]\t\t3\nxmc[37]\t\t3\nxmc[38]\t\t3\n\nNc[3]\t\t7\nbc[3]\t\t2\nMc[3]\t\t2\nxmaxc[3]\t6\nxmc[39]\t\t3\nxmc[40]\t\t3\nxmc[41]\t\t3\nxmc[42]\t\t3\nxmc[43]\t\t3\nxmc[44]\t\t3\nxmc[45]\t\t3\nxmc[46]\t\t3\nxmc[47]\t\t3\nxmc[48]\t\t3\nxmc[49]\t\t3\nxmc[50]\t\t3\nxmc[51]\t\t3\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tls/sweet.c",
    "content": " /*\n  * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n  * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n  */\n\n/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/sweet.c,v 1.2 1996/07/02 10:15:53 jutta Exp $*/\n \n/* Generate code to unpack a bit array from name:#bits description */\n\n#include\t<stdio.h>\n#include\t\"taste.h\"\n#include\t\"proto.h\"\n\nvoid write_code P2((s_spex, n_spex), struct spex * s_spex, int n_spex)\n{\n\tstruct spex\t* sp = s_spex;\n\tint\t\tbits = 8;\n\tint\t\tvars;\n\n\tif (!n_spex) return;\n\n\tvars = sp->varsize;\n\n\twhile (n_spex) {\n\n\t\tif (vars == sp->varsize) {\n\t\t\tprintf(\"\\t%s  = \", sp->var);\n\t\t} else printf(\"\\t%s |= \", sp->var);\n\n\t\tif (vars == bits) {\n\t\n\t\t\tif (bits == 8) printf( \"*c++;\\n\" );\n\t\t\telse printf( \"*c++ & 0x%lX;\\n\",\n\t\t\t\t~(0xfffffffe << (bits - 1)) );\n\n\t\t\tif (!-- n_spex) break;\n\t\t\tsp++;\n\t\t\tvars = sp->varsize;\n\t\t\tbits = 8;\n\n\t\t} else if (vars < bits) {\n\n\t\t\tprintf( \"(*c >> %d) & 0x%lX;\\n\", \n\t\t\t\tbits - vars,\n\t\t\t\t~(0xfffffffe << (vars - 1)));\n\n\t\t\tbits -= vars;\n\t\t\tif (!--n_spex) break;\n\t\t\tsp++;\n\t\t\tvars = sp->varsize;\n\n\t\t} else {\n\t\t\t/*   vars > bits.  We're eating lower-all of c,\n\t\t\t *   but we must shift it.\n\t\t\t */\n\t\t\tprintf(\t\"(*c++ & 0x%X) << %d;\\n\",\n\t\t\t\t~(0xfffffffe << (bits - 1)),\n\t\t\t\tvars - bits );\n\n\t\t\tvars -= bits;\n\t\t\tbits = 8;\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tls/taste.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/taste.c,v 1.1 1992/10/28 00:28:39 jutta Exp $*/\n\n#include\t<stdio.h>\n#include\t<string.h>\n#include\t<memory.h>\n\n#include\t\"config.h\"\n\n#ifdef\tHAS_STDLIB_H\n#\tinclude\t<stdlib.h>\n#else\n#include \"proto.h\"\n#\tifdef\tHAS_MALLOC_H\n#\tinclude <malloc.h>\n#\telse\n\t\textern char\t* malloc P((char *)), * realloc P((char *,int));\n#\tendif\n\textern int exit P((int));\n#endif\n\n#include \"proto.h\"\n\n/*\n * common code to sweet.c and bitter.c: read the name:#bits description.\n */\n\n#include\t\"taste.h\"\n\nstatic struct spex  * s_spex;\nstatic int n_spex, m_spex;\n\nextern void\twrite_code P((struct spex *, int));\n\nchar * strsave P1((str), char * str)\t\t/* strdup() + errors */\n{\n\tint    n = strlen(str) + 1;\n\tchar * s = malloc(n);\n\tif (!s) {\n\t\tfprintf(stderr, \"Failed to malloc %d bytes, abort\\n\",\n\t\t\tstrlen(str) + 1);\n\t\texit(1);\n\t}\n\treturn memcpy(s, str, n);\n}\n\nstruct spex * new_spex P0()\n{\n\tif (n_spex >= m_spex) {\n\t\tm_spex += 500;\n\t\tif (!(s_spex = (struct spex *)(n_spex\n\t\t\t? realloc((char *)s_spex, m_spex * sizeof(*s_spex))\n\t\t\t: malloc( m_spex * sizeof(*s_spex))))) {\n\t\t\tfprintf(stderr, \"Failed to malloc %d bytes, abort\\n\",\n\t\t\t\tm_spex * sizeof(*s_spex));\n\t\t\texit(1);\n\t\t}\n\t}\n\treturn s_spex + n_spex;\n}\n\nchar * strtek P2((str, sep), char * str, char * sep) {\n\n\tstatic char     * S = (char *)0;\n\tchar\t\t* c, * base;\n\n\tif (str) S = str;\n\n\tif (!S || !*S) return (char *)0;\n\n\t/*  Skip delimiters.\n\t */\n\twhile (*S) {\n\t\tfor (c = sep; *c && *c != *S; c++) ;\n\t\tif (*c) *S++ = 0;\n\t\telse break;\n\t}\n\n\tbase = S;\n\n\t/*   Skip non-delimiters.\n\t */\n\tfor (base = S; *S; S++) {\n\n\t\tfor (c = sep; *c; c++)\n\t\t\tif (*c == *S) {\n\t\t\t\t*S++ = 0;\n\t\t\t\treturn base;\n\t\t\t}\n\t}\n\n\treturn base == S ? (char *)0 : base;\n}\n\nint read_spex P0()\n{\n\tchar buf[200];\n\tchar * s, *t;\n\tstruct spex\t* sp = s_spex;\t\n\n\twhile (fgets(buf, sizeof buf, stdin)) {\n\n\t\tchar \t* nl;\n\n\t\tif (nl = strchr(buf, '\\n'))\n\t\t\t*nl = '\\0';\n\n\t\tif (!*buf || *buf == ';') continue;\n\t\ts = strtek(buf, \" \\t\");\n\t\tif (!s) {\n\t\t\tfprintf(stderr, \"? %s\\n\", buf);\n\t\t\tcontinue;\n\t\t}\n\t\tsp = new_spex();\n\t\tsp->var = strsave(s);\n\t\ts = strtek((char*)0, \" \\t\");\n\t\tif (!s) {\n\t\t\tfprintf(stderr, \"varsize?\\n\");\n\t\t\tcontinue;\n\t\t}\n\t\tsp->varsize = strtol(s, (char **)0, 0);\n\t\tn_spex++;\n\t}\n\n\treturn sp - s_spex;\n}\n\nint main P0()\n{\n\tread_spex();\n\twrite_code(s_spex, n_spex);\n\n\texit(0);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tls/taste.h",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n \n/*\n * common code to sweet.c and bitter.c\n */\n\n#ifndef\tTASTE_H\n#define\tTASTE_H\n\nstruct spex {\n\n\tchar\t* var;\n\tint\tvarsize;\n} ;\n\n#endif\t/* TASTE_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tst/cod2lin.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/cod2lin.c,v 1.2 1996/07/02 14:33:10 jutta Exp jutta $*/\n\n#include <stdio.h>\n#include <assert.h>\n\n#include\t\"gsm.h\"\n#include\t\"proto.h\"\n\nchar  * pname;\n\nint\tdebug      = 0;\nint\tverbosity  = 0;\nint\tfast       = 0;\nint\twav        = 0;\nint\terror      = 0;\n\nusage P0()\n{\n\tfprintf(stderr, \"Usage: %s [-vwF] [files...]\\n\", pname);\n\texit(1);\n}\n\nvoid process P2((f, filename), FILE * f, char * filename)\n{\n\tgsm_frame\tbuf;\n\tgsm_signal\tsource[160];\n\n\tint\t\tcc;\n\tgsm\t\tr;\n\n\t(void)memset(source, 0x00, sizeof(source));\n\n\tif (!(r = gsm_create())) {\n\t\tperror(\"gsm_create\");\n\t\terror = 1;\n\t\treturn ;\n\t}\n\tgsm_option(r, GSM_OPT_VERBOSE, &verbosity);\n\tgsm_option(r, GSM_OPT_FAST,    &fast);\n\tgsm_option(r, GSM_OPT_WAV49,   &wav);\n\tfor (;;) {\n\t\tcc = fread((char *)source, sizeof(*source), 76, f);\n\t\tif (cc == 0) {\n\t\t\tgsm_destroy(r);\n\t\t\treturn;\n\t\t}\n\t\tif (cc != 76) {\n\t\t\terror = 1;\n\t\t\tfprintf(stderr,\n\t\t\t\t\"%s: %s -- %d trailing bytes ignored\\n\",\n\t\t\t\tpname, filename, cc);\n\t\t\tgsm_destroy(r);\n\t\t\treturn;\n\t\t}\n\n\t\tgsm_implode(r, source, buf);\n\t\tgsm_decode(r, buf, source);\n\n\t\tif (write(1, source, sizeof(source)) != sizeof(source)) {\n\t\t\tperror(\"write\");\n\t\t\terror = 1;\n\t\t\tgsm_destroy(r);\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nmain P2((ac, av), int ac, char ** av)\n{\n\tint \t\topt;\n\textern char   * optarg;\n\textern int\toptind;\n\n\tFILE\t\t* f;\n\n\tif (!(pname = av[0])) pname = \"cod2out\";\n\n\twhile ((opt = getopt(ac, av, \"vwF\")) != EOF) switch (opt) {\n\tcase 'v': verbosity++; \t  break;\n\tcase 'w': wav++; \t  break;\n\tcase 'F': fast++;\t  break;\n\tdefault:  usage();\n\t}\n\n\tac -= optind;\n\tav += optind;\n\n\tif (!ac) process(stdin, \"*stdin*\");\n\telse for (; *av; av++) {\n\t\tif (!(f = fopen(*av, \"r\"))) perror(*av);\n\t\telse {\n\t\t\tprocess(f, *av);\n\t\t\tfclose(f);\n\t\t}\n\t}\n\n\texit(error);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tst/cod2txt.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/cod2txt.c,v 1.1 1994/10/21 20:52:11 jutta Exp $*/\n\n#include <stdio.h>\n#include <assert.h>\n\n#include\t\"gsm.h\"\n#include\t\"proto.h\"\n\nchar  * pname;\n\nint\tdebug      = 0;\nint\tverbosity  = 0;\nint\terror      = 0;\n\nusage P0()\n{\n\tfprintf(stderr, \"Usage: %s [files...]\\n\", pname);\n\texit(1);\n}\n\nvoid process P2((f, filename), FILE * f, char * filename)\n{\n\tgsm_frame\tbuf;\n\tgsm_signal\tsource[160];\n\n\tint\t\tcc;\n\tgsm\t\tr;\n\tint\t\tnr=0;\n\n\t(void)memset(source, 0, sizeof(source));\n\n\tif (!(r = gsm_create())) {\n\t\tperror(\"gsm_create\");\n\t\terror = 1;\n\t\treturn ;\n\t}\n\tgsm_option(r, GSM_OPT_VERBOSE, &verbosity);\n\tfor (;;) {\n\t\tcc = fread((char *)source, sizeof(*source), 76, f);\n\t\tif (cc == 0) {\n\t\t\tgsm_destroy(r);\n\t\t\treturn;\n\t\t}\n\t\tif (cc != 76) {\n\t\t\terror = 1;\n\t\t\tfprintf(stderr,\n\t\t\t\t\"%s: %s -- %d trailing bytes ignored\\n\",\n\t\t\t\tpname, filename, cc);\n\t\t\tgsm_destroy(r);\n\t\t\treturn;\n\t\t}\n\n\t\tgsm_implode(r, source, buf);\n\t\tprintf(\"[%d] \", ++nr);\n\t\tif (gsm_print(stdout, r, buf)) {\n\t\t\tfprintf(stderr,\n\t\t\t\t\"%s: %s: bad magic\\n\", pname, filename);\n\t\t\tgsm_destroy(r);\n\t\t\treturn;\n\n\t\t}\n\t}\n}\n\nmain P2((ac, av), int ac, char ** av)\n{\n\tint \t\topt;\n\textern char   * optarg;\n\textern int\toptind;\n\n\tFILE\t\t* f;\n\n\tif (!(pname = av[0])) pname = \"cod2txt\";\n\n\tac--;\n\tav++;\n\n\tif (!ac) process(stdin, \"*stdin*\");\n\telse for (; *av; av++) {\n\t\tif (!(f = fopen(*av, \"r\"))) perror(*av);\n\t\telse {\n\t\t\tprocess(f, *av);\n\t\t\tfclose(f);\n\t\t}\n\t}\n\n\texit(error);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tst/gsm2cod.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm2cod.c,v 1.1 1994/10/21 20:52:11 jutta Exp $*/\n\n#include <stdio.h>\n#include <assert.h>\n\n#include\t\"gsm.h\"\n#include\t\"proto.h\"\n\nchar  * pname;\n\nint\tdebug      = 0;\nint\tverbosity  = 0;\nint\terror      = 0;\n\nusage P0()\n{\n\tfprintf(stderr, \"Usage: %s [files...]\\n\", pname);\n\texit(1);\n}\n\nvoid process P2((f, filename), FILE * f, char * filename)\n{\n\tgsm_frame\tbuf;\n\tgsm_signal\tsource[76];\n\n\tint\t\tcc;\n\tgsm\t\tr;\n\tint\t\tnr=0;\n\n\t(void)memset(source, 0, sizeof(source));\n\n\tif (!(r = gsm_create())) {\n\t\tperror(\"gsm_create\");\n\t\terror = 1;\n\t\treturn ;\n\t}\n\tgsm_option(r, GSM_OPT_VERBOSE, &verbosity);\n\tfor (;;) {\n\t\tcc = fread((char *)buf, sizeof(buf), 1, f);\n\t\tif (cc == 0) {\n\t\t\tgsm_destroy(r);\n\t\t\treturn;\n\t\t}\n\t\tif (cc != 1) {\n\t\t\terror = 1;\n\t\t\tfprintf(stderr,\n\t\t\t\t\"%s: %s -- trailing bytes ignored\\n\",\n\t\t\t\tpname, filename);\n\t\t\tgsm_destroy(r);\n\t\t\treturn;\n\t\t}\n\n\t\tgsm_explode(r, buf, source);\n\t\tif (write(1, (char *)source, sizeof(source))!= sizeof(source)) {\n\n\t\t\tperror(\"write\");\n\t\t\terror = 1;\n\t\t\tgsm_destroy(r);\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nmain P2((ac, av), int ac, char ** av)\n{\n\tint \t\topt;\n\textern char   * optarg;\n\textern int\toptind;\n\n\tFILE\t\t* f;\n\n\tif (!(pname = av[0])) pname = \"gsm2cod\";\n\n\tac--;\n\tav++;\n\n\tif (!ac) process(stdin, \"*stdin*\");\n\telse for (; *av; av++) {\n\t\tif (!(f = fopen(*av, \"r\"))) perror(*av);\n\t\telse {\n\t\t\tprocess(f, *av);\n\t\t\tfclose(f);\n\t\t}\n\t}\n\n\texit(error);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tst/lin2cod.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/lin2cod.c,v 1.2 1996/07/02 14:33:13 jutta Exp jutta $*/\n\n#include <stdio.h>\n\n#include \"gsm.h\"\n#include \"proto.h\"\n\nchar  * pname;\n\nint\tdebug      = 0;\nint\tverbosity  = 0;\nint\tfast       = 0;\nint\twav        = 0;\nint\terror      = 0;\n\nusage P0()\n{\n\tfprintf(stderr, \"Usage: %s [-vwF] [files...]\\n\", pname);\n\texit(1);\n}\n\nvoid process P2((f, filename), FILE * f, char * filename)\n{\n\tgsm_frame\tbuf;\n\tshort\t\tsource[160];\n\tint\t\tcc;\n\tgsm\t\tr;\n\n\tif (!(r = gsm_create())) {\n\t\tperror(\"gsm_create\");\n\t\terror = 1;\n\t\treturn ;\n\t}\n\tgsm_option(r, GSM_OPT_VERBOSE, &verbosity);\n\tgsm_option(r, GSM_OPT_FAST,    &fast);\n\tgsm_option(r, GSM_OPT_WAV49,   &wav);\n\tfor (;;) {\n\n\t\tif ((cc = fread((char *)source, 1, sizeof(source), f)) == 0) {\n\t\t\tgsm_destroy(r);\n#ifdef\tCOUNT_OVERFLOW\n\t\t\tdump_overflow(stderr);\n#endif\n\t\t\treturn;\n\t\t}\n\n\t\tif (cc != sizeof(source)) {\n\t\t\terror = 1;\n\t\t\tperror(filename);\n\t\t\tfprintf(stderr, \"%s: cannot read input from %s\\n\",\n\t\t\t\tpname, filename);\n\t\t\tgsm_destroy(r);\n\t\t\treturn;\n\t\t}\n\n\t\tgsm_encode(r, source, buf);\n\t\tgsm_explode(r, buf, source);\t/* 76 shorts */\n\t\tif (write(1, source, sizeof(*source) * 76)\n\t\t\t!= sizeof(*source) * 76) {\n\n\t\t\tperror(\"write\");\n\t\t\terror = 1;\n\t\t\tgsm_destroy(r);\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nmain P2((ac, av), int ac, char ** av)\n{\n\tint \t\topt;\n\textern char   * optarg;\n\textern int\toptind;\n\n\tFILE\t\t* f;\n\n\tif (!(pname = av[0])) pname = \"inp2cod\";\n\n\twhile ((opt = getopt(ac, av, \"vwF\")) != EOF) switch (opt) {\n\tcase 'v': verbosity++;    break;\n\tcase 'w': wav++;    \t  break;\n\tcase 'F': fast++;         break;\n\tdefault:  usage();\n\t}\n\n\tac -= optind;\n\tav += optind;\n\n\tif (!ac) process(stdin, \"*stdin*\");\n\telse for (; *av; av++) {\n\t\tif (!(f = fopen(*av, \"r\"))) perror(*av);\n\t\telse {\n\t\t\tprocess(f, *av);\n\t\t\tfclose(f);\n\t\t}\n\t}\n\n\texit(error);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tst/lin2txt.c",
    "content": "/*\n * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n * Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n */\n\n/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/lin2txt.c,v 1.1 1994/10/21 20:52:11 jutta Exp $*/\n\n#include <stdio.h>\n\n#include \"gsm.h\"\n#include \"proto.h\"\n\nchar  * pname;\n\nint\tdebug      = 0;\nint\tverbosity  = 0;\nint\terror      = 0;\n\nusage P0()\n{\n\tfprintf(stderr, \"Usage: %s [-v] [files...]\\n\", pname);\n\texit(1);\n}\n\nvoid process P2((f, filename), FILE * f, char * filename)\n{\n\tshort\t\tsource[160];\n\tint\t\tcc, j, k;\n\tgsm\t\tr;\n\n\tif (!(r = gsm_create())) {\n\t\tperror(\"gsm_create\");\n\t\terror = 1;\n\t\treturn ;\n\t}\n\tgsm_option(r, GSM_OPT_VERBOSE, &verbosity);\n\tfor (;;) {\n\n\t\tif ((cc = fread((char *)source, 1, sizeof(source), f)) == 0) {\n\t\t\tgsm_destroy(r);\n#ifdef\tCOUNT_OVERFLOW\n\t\t\tdump_overflow(stderr);\n#endif\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tprintf(\"{\\t\");\n\t\tfor (j = 0; j < 4; j++) {\n\t\t\tprintf(\"{\\t\");\n\t\t\tfor (k = 0; k < 40; k++) {\n\t\t\t\tprintf(\"%d\", (int)source[ j * 40 + k ]);\n\t\t\t\tif (k < 39) {\n\t\t\t\t\tprintf(\", \");\n\t\t\t\t\tif (k % 4 == 3) printf(\"\\n\\t\\t\");\n\t\t\t\t} else {\n\t\t\t\t\tprintf(\"\\t}\");\n\t\t\t\t\tif (j == 3) printf(\"\\t},\\n\");\n\t\t\t\t\telse printf(\",\\n\\t\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nmain P2((ac, av), int ac, char ** av)\n{\n\tint \t\topt;\n\textern char   * optarg;\n\textern int\toptind;\n\n\tFILE\t\t* f;\n\n\tif (!(pname = av[0])) pname = \"inp2txt\";\n\n\twhile ((opt = getopt(ac, av, \"v\")) != EOF) switch (opt) {\n\tcase 'v': verbosity++;    break;\n\tdefault:  usage();\n\t}\n\n\tac -= optind;\n\tav += optind;\n\n\tif (!ac) process(stdin, \"*stdin*\");\n\telse for (; *av; av++) {\n\t\tif (!(f = fopen(*av, \"r\"))) perror(*av);\n\t\telse {\n\t\t\tprocess(f, *av);\n\t\t\tfclose(f);\n\t\t}\n\t}\n\n\texit(error);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/gsm/tst/run",
    "content": ":\n#\n# Copyright 1992 by Jutta Degener and Carsten Bormann, Technische\n# Universitaet Berlin.  See the accompanying file \"COPYRIGHT\" for\n# details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n#\nif [ ! -f 1.inp ] ; then\n\techo Sorry, but we cannot provide the test data with this release.\n\texit\nfi\n\necho -n 'Linear to code: '\nfor i in 1 2 3 4\ndo \n\techo -n $i..\n \t./lin2cod  < $i.inp | cmp - $i.cod\ndone\necho \"\"\n\necho -n 'Code to linear: '\nfor i in 1 2 3 4\ndo \n\techo -n $i..\n\t./cod2lin < $i.cod | cmp - $i.out\ndone\necho \"\"\n\necho -n 'Toast: '\nfor i in 1 2 3 4\ndo\n\techo -n $i..\n\t../bin/toast -l < $i.inp | ../bin/toast -dl | cmp - $i.out\ndone\necho \"\"\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/FrameClassify.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       FrameClassify.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include \"iLBC_define.h\"\n\n   /*---------------------------------------------------------------*\n    *  Classification of subframes to localize start state\n    *--------------------------------------------------------------*/\n\n   int FrameClassify(      /* index to the max-energy sub-frame */\n       iLBC_Enc_Inst_t *iLBCenc_inst,\n                           /* (i/o) the encoder state structure */\n       float *residual     /* (i) lpc residual signal */\n   ) {\n       float max_ssqEn, fssqEn[NSUB_MAX], bssqEn[NSUB_MAX], *pp;\n       int n, l, max_ssqEn_n;\n       const float ssqEn_win[NSUB_MAX-1]={(float)0.8,(float)0.9,\n           (float)1.0,(float)0.9,(float)0.8};\n       const float sampEn_win[5]={(float)1.0/(float)6.0,\n           (float)2.0/(float)6.0, (float)3.0/(float)6.0,\n           (float)4.0/(float)6.0, (float)5.0/(float)6.0};\n\n       /* init the front and back energies to zero */\n\n       memset(fssqEn, 0, NSUB_MAX*sizeof(float));\n       memset(bssqEn, 0, NSUB_MAX*sizeof(float));\n\n       /* Calculate front of first seqence */\n\n       n=0;\n       pp=residual;\n       for (l=0; l<5; l++) {\n           fssqEn[n] += sampEn_win[l] * (*pp) * (*pp);\n           pp++;\n       }\n       for (l=5; l<SUBL; l++) {\n\n\n\n\n\n           fssqEn[n] += (*pp) * (*pp);\n           pp++;\n       }\n\n       /* Calculate front and back of all middle sequences */\n\n       for (n=1; n<iLBCenc_inst->nsub-1; n++) {\n           pp=residual+n*SUBL;\n           for (l=0; l<5; l++) {\n               fssqEn[n] += sampEn_win[l] * (*pp) * (*pp);\n               bssqEn[n] += (*pp) * (*pp);\n               pp++;\n           }\n           for (l=5; l<SUBL-5; l++) {\n               fssqEn[n] += (*pp) * (*pp);\n               bssqEn[n] += (*pp) * (*pp);\n               pp++;\n           }\n           for (l=SUBL-5; l<SUBL; l++) {\n               fssqEn[n] += (*pp) * (*pp);\n               bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp);\n               pp++;\n           }\n       }\n\n       /* Calculate back of last seqence */\n\n       n=iLBCenc_inst->nsub-1;\n       pp=residual+n*SUBL;\n       for (l=0; l<SUBL-5; l++) {\n           bssqEn[n] += (*pp) * (*pp);\n           pp++;\n       }\n       for (l=SUBL-5; l<SUBL; l++) {\n           bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp);\n           pp++;\n       }\n\n       /* find the index to the weighted 80 sample with\n          most energy */\n\n       if (iLBCenc_inst->mode==20) l=1;\n       else                        l=0;\n\n       max_ssqEn=(fssqEn[0]+bssqEn[1])*ssqEn_win[l];\n       max_ssqEn_n=1;\n       for (n=2; n<iLBCenc_inst->nsub; n++) {\n\n\n\n\n\n\n           l++;\n           if ((fssqEn[n-1]+bssqEn[n])*ssqEn_win[l] > max_ssqEn) {\n               max_ssqEn=(fssqEn[n-1]+bssqEn[n]) *\n                               ssqEn_win[l];\n               max_ssqEn_n=n;\n           }\n       }\n\n       return max_ssqEn_n;\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/FrameClassify.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       FrameClassify.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_FRAMECLASSIFY_H\n   #define __iLBC_FRAMECLASSIFY_H\n\n   int FrameClassify(      /* index to the max-energy sub-frame */\n       iLBC_Enc_Inst_t *iLBCenc_inst,\n                           /* (i/o) the encoder state structure */\n       float *residual     /* (i) lpc residual signal */\n   );\n\n\n\n\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/LPCdecode.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       LPC_decode.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <math.h>\n   #include <string.h>\n\n   #include \"helpfun.h\"\n   #include \"lsf.h\"\n   #include \"iLBC_define.h\"\n   #include \"constants.h\"\n\n   /*---------------------------------------------------------------*\n    *  interpolation of lsf coefficients for the decoder\n    *--------------------------------------------------------------*/\n\n   void LSFinterpolate2a_dec(\n       float *a,           /* (o) lpc coefficients for a sub-frame */\n       float *lsf1,    /* (i) first lsf coefficient vector */\n       float *lsf2,    /* (i) second lsf coefficient vector */\n       float coef,         /* (i) interpolation weight */\n       int length          /* (i) length of lsf vectors */\n   ){\n       float  lsftmp[LPC_FILTERORDER];\n\n       interpolate(lsftmp, lsf1, lsf2, coef, length);\n       lsf2a(a, lsftmp);\n   }\n\n   /*---------------------------------------------------------------*\n    *  obtain dequantized lsf coefficients from quantization index\n    *--------------------------------------------------------------*/\n\n   void SimplelsfDEQ(\n       float *lsfdeq,    /* (o) dequantized lsf coefficients */\n       int *index,         /* (i) quantization index */\n       int lpc_n           /* (i) number of LPCs */\n   ){\n       int i, j, pos, cb_pos;\n\n\n\n\n\n       /* decode first LSF */\n\n       pos = 0;\n       cb_pos = 0;\n       for (i = 0; i < LSF_NSPLIT; i++) {\n           for (j = 0; j < dim_lsfCbTbl[i]; j++) {\n               lsfdeq[pos + j] = lsfCbTbl[cb_pos +\n                   (long)(index[i])*dim_lsfCbTbl[i] + j];\n           }\n           pos += dim_lsfCbTbl[i];\n           cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i];\n       }\n\n       if (lpc_n>1) {\n\n           /* decode last LSF */\n\n           pos = 0;\n           cb_pos = 0;\n           for (i = 0; i < LSF_NSPLIT; i++) {\n               for (j = 0; j < dim_lsfCbTbl[i]; j++) {\n                   lsfdeq[LPC_FILTERORDER + pos + j] =\n                       lsfCbTbl[cb_pos +\n                       (long)(index[LSF_NSPLIT + i])*\n                       dim_lsfCbTbl[i] + j];\n               }\n               pos += dim_lsfCbTbl[i];\n               cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i];\n           }\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  obtain synthesis and weighting filters form lsf coefficients\n    *---------------------------------------------------------------*/\n\n   void DecoderInterpolateLSF(\n       float *syntdenum, /* (o) synthesis filter coefficients */\n       float *weightdenum, /* (o) weighting denumerator\n                                  coefficients */\n       float *lsfdeq,       /* (i) dequantized lsf coefficients */\n       int length,         /* (i) length of lsf coefficient vector */\n       iLBC_Dec_Inst_t *iLBCdec_inst\n                           /* (i) the decoder state structure */\n   ){\n       int    i, pos, lp_length;\n       float  lp[LPC_FILTERORDER + 1], *lsfdeq2;\n\n\n\n\n\n\n       lsfdeq2 = lsfdeq + length;\n       lp_length = length + 1;\n\n       if (iLBCdec_inst->mode==30) {\n           /* sub-frame 1: Interpolation between old and first */\n\n           LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, lsfdeq,\n               lsf_weightTbl_30ms[0], length);\n           memcpy(syntdenum,lp,lp_length*sizeof(float));\n           bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM,\n               lp_length);\n\n           /* sub-frames 2 to 6: interpolation between first\n              and last LSF */\n\n           pos = lp_length;\n           for (i = 1; i < 6; i++) {\n               LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq2,\n                   lsf_weightTbl_30ms[i], length);\n               memcpy(syntdenum + pos,lp,lp_length*sizeof(float));\n               bwexpand(weightdenum + pos, lp,\n                   LPC_CHIRP_WEIGHTDENUM, lp_length);\n               pos += lp_length;\n           }\n       }\n       else {\n           pos = 0;\n           for (i = 0; i < iLBCdec_inst->nsub; i++) {\n               LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold,\n                   lsfdeq, lsf_weightTbl_20ms[i], length);\n               memcpy(syntdenum+pos,lp,lp_length*sizeof(float));\n               bwexpand(weightdenum+pos, lp, LPC_CHIRP_WEIGHTDENUM,\n                   lp_length);\n               pos += lp_length;\n           }\n       }\n\n       /* update memory */\n\n       if (iLBCdec_inst->mode==30)\n           memcpy(iLBCdec_inst->lsfdeqold, lsfdeq2,\n                       length*sizeof(float));\n       else\n           memcpy(iLBCdec_inst->lsfdeqold, lsfdeq,\n                       length*sizeof(float));\n\n   }\n\n\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/LPCdecode.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       LPC_decode.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_LPC_DECODE_H\n   #define __iLBC_LPC_DECODE_H\n\n   void LSFinterpolate2a_dec(\n       float *a,           /* (o) lpc coefficients for a sub-frame */\n       float *lsf1,    /* (i) first lsf coefficient vector */\n       float *lsf2,    /* (i) second lsf coefficient vector */\n       float coef,         /* (i) interpolation weight */\n       int length          /* (i) length of lsf vectors */\n   );\n\n   void SimplelsfDEQ(\n       float *lsfdeq,      /* (o) dequantized lsf coefficients */\n       int *index,         /* (i) quantization index */\n       int lpc_n           /* (i) number of LPCs */\n   );\n\n   void DecoderInterpolateLSF(\n       float *syntdenum,   /* (o) synthesis filter coefficients */\n       float *weightdenum, /* (o) weighting denumerator\n                                  coefficients */\n       float *lsfdeq,      /* (i) dequantized lsf coefficients */\n       int length,         /* (i) length of lsf coefficient vector */\n       iLBC_Dec_Inst_t *iLBCdec_inst\n                           /* (i) the decoder state structure */\n   );\n\n   #endif\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/LPCencode.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       LPCencode.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <string.h>\n\n   #include \"iLBC_define.h\"\n   #include \"helpfun.h\"\n   #include \"lsf.h\"\n   #include \"constants.h\"\n\n\n\n\n\n   /*----------------------------------------------------------------*\n    *  lpc analysis (subrutine to LPCencode)\n    *---------------------------------------------------------------*/\n\n   void SimpleAnalysis(\n       float *lsf,         /* (o) lsf coefficients */\n       float *data,    /* (i) new data vector */\n       iLBC_Enc_Inst_t *iLBCenc_inst\n                           /* (i/o) the encoder state structure */\n   ){\n       int k, is;\n       float temp[BLOCKL_MAX], lp[LPC_FILTERORDER + 1];\n       float lp2[LPC_FILTERORDER + 1];\n       float r[LPC_FILTERORDER + 1];\n\n       is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;\n       memcpy(iLBCenc_inst->lpc_buffer+is,data,\n           iLBCenc_inst->blockl*sizeof(float));\n\n       /* No lookahead, last window is asymmetric */\n\n       for (k = 0; k < iLBCenc_inst->lpc_n; k++) {\n\n           is = LPC_LOOKBACK;\n\n           if (k < (iLBCenc_inst->lpc_n - 1)) {\n               window(temp, lpc_winTbl,\n                   iLBCenc_inst->lpc_buffer, BLOCKL_MAX);\n           } else {\n               window(temp, lpc_asymwinTbl,\n                   iLBCenc_inst->lpc_buffer + is, BLOCKL_MAX);\n           }\n\n           autocorr(r, temp, BLOCKL_MAX, LPC_FILTERORDER);\n           window(r, r, lpc_lagwinTbl, LPC_FILTERORDER + 1);\n\n           levdurb(lp, temp, r, LPC_FILTERORDER);\n           bwexpand(lp2, lp, LPC_CHIRP_SYNTDENUM, LPC_FILTERORDER+1);\n\n           a2lsf(lsf + k*LPC_FILTERORDER, lp2);\n       }\n       is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;\n       memmove(iLBCenc_inst->lpc_buffer,\n           iLBCenc_inst->lpc_buffer+LPC_LOOKBACK+BLOCKL_MAX-is,\n           is*sizeof(float));\n   }\n\n   /*----------------------------------------------------------------*\n\n\n\n\n\n    *  lsf interpolator and conversion from lsf to a coefficients\n    *  (subrutine to SimpleInterpolateLSF)\n    *---------------------------------------------------------------*/\n\n   void LSFinterpolate2a_enc(\n       float *a,       /* (o) lpc coefficients */\n       float *lsf1,/* (i) first set of lsf coefficients */\n       float *lsf2,/* (i) second set of lsf coefficients */\n       float coef,     /* (i) weighting coefficient to use between\n                              lsf1 and lsf2 */\n       long length      /* (i) length of coefficient vectors */\n   ){\n       float  lsftmp[LPC_FILTERORDER];\n\n       interpolate(lsftmp, lsf1, lsf2, coef, length);\n       lsf2a(a, lsftmp);\n   }\n\n   /*----------------------------------------------------------------*\n    *  lsf interpolator (subrutine to LPCencode)\n    *---------------------------------------------------------------*/\n\n   void SimpleInterpolateLSF(\n       float *syntdenum,   /* (o) the synthesis filter denominator\n                                  resulting from the quantized\n                                  interpolated lsf */\n       float *weightdenum, /* (o) the weighting filter denominator\n                                  resulting from the unquantized\n                                  interpolated lsf */\n       float *lsf,         /* (i) the unquantized lsf coefficients */\n       float *lsfdeq,      /* (i) the dequantized lsf coefficients */\n       float *lsfold,      /* (i) the unquantized lsf coefficients of\n                                  the previous signal frame */\n       float *lsfdeqold, /* (i) the dequantized lsf coefficients of\n                                  the previous signal frame */\n       int length,         /* (i) should equate LPC_FILTERORDER */\n       iLBC_Enc_Inst_t *iLBCenc_inst\n                           /* (i/o) the encoder state structure */\n   ){\n       int    i, pos, lp_length;\n       float  lp[LPC_FILTERORDER + 1], *lsf2, *lsfdeq2;\n\n       lsf2 = lsf + length;\n       lsfdeq2 = lsfdeq + length;\n       lp_length = length + 1;\n\n       if (iLBCenc_inst->mode==30) {\n           /* sub-frame 1: Interpolation between old and first\n\n\n\n\n\n              set of lsf coefficients */\n\n           LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq,\n               lsf_weightTbl_30ms[0], length);\n           memcpy(syntdenum,lp,lp_length*sizeof(float));\n           LSFinterpolate2a_enc(lp, lsfold, lsf,\n               lsf_weightTbl_30ms[0], length);\n           bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, lp_length);\n\n           /* sub-frame 2 to 6: Interpolation between first\n              and second set of lsf coefficients */\n\n           pos = lp_length;\n           for (i = 1; i < iLBCenc_inst->nsub; i++) {\n               LSFinterpolate2a_enc(lp, lsfdeq, lsfdeq2,\n                   lsf_weightTbl_30ms[i], length);\n               memcpy(syntdenum + pos,lp,lp_length*sizeof(float));\n\n               LSFinterpolate2a_enc(lp, lsf, lsf2,\n                   lsf_weightTbl_30ms[i], length);\n               bwexpand(weightdenum + pos, lp,\n                   LPC_CHIRP_WEIGHTDENUM, lp_length);\n               pos += lp_length;\n           }\n       }\n       else {\n           pos = 0;\n           for (i = 0; i < iLBCenc_inst->nsub; i++) {\n               LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq,\n                   lsf_weightTbl_20ms[i], length);\n               memcpy(syntdenum+pos,lp,lp_length*sizeof(float));\n               LSFinterpolate2a_enc(lp, lsfold, lsf,\n                   lsf_weightTbl_20ms[i], length);\n               bwexpand(weightdenum+pos, lp,\n                   LPC_CHIRP_WEIGHTDENUM, lp_length);\n               pos += lp_length;\n           }\n       }\n\n       /* update memory */\n\n       if (iLBCenc_inst->mode==30) {\n           memcpy(lsfold, lsf2, length*sizeof(float));\n           memcpy(lsfdeqold, lsfdeq2, length*sizeof(float));\n       }\n       else {\n           memcpy(lsfold, lsf, length*sizeof(float));\n           memcpy(lsfdeqold, lsfdeq, length*sizeof(float));\n\n\n\n\n\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  lsf quantizer (subrutine to LPCencode)\n    *---------------------------------------------------------------*/\n\n   void SimplelsfQ(\n       float *lsfdeq,    /* (o) dequantized lsf coefficients\n                              (dimension FILTERORDER) */\n       int *index,     /* (o) quantization index */\n       float *lsf,      /* (i) the lsf coefficient vector to be\n                              quantized (dimension FILTERORDER ) */\n       int lpc_n     /* (i) number of lsf sets to quantize */\n   ){\n       /* Quantize first LSF with memoryless split VQ */\n       SplitVQ(lsfdeq, index, lsf, lsfCbTbl, LSF_NSPLIT,\n           dim_lsfCbTbl, size_lsfCbTbl);\n\n       if (lpc_n==2) {\n           /* Quantize second LSF with memoryless split VQ */\n           SplitVQ(lsfdeq + LPC_FILTERORDER, index + LSF_NSPLIT,\n               lsf + LPC_FILTERORDER, lsfCbTbl, LSF_NSPLIT,\n               dim_lsfCbTbl, size_lsfCbTbl);\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  lpc encoder\n    *---------------------------------------------------------------*/\n\n   void LPCencode(\n       float *syntdenum, /* (i/o) synthesis filter coefficients\n                                  before/after encoding */\n       float *weightdenum, /* (i/o) weighting denumerator\n                                  coefficients before/after\n                                  encoding */\n       int *lsf_index,     /* (o) lsf quantization index */\n       float *data,    /* (i) lsf coefficients to quantize */\n       iLBC_Enc_Inst_t *iLBCenc_inst\n                           /* (i/o) the encoder state structure */\n   ){\n       float lsf[LPC_FILTERORDER * LPC_N_MAX];\n       float lsfdeq[LPC_FILTERORDER * LPC_N_MAX];\n\n       SimpleAnalysis(lsf, data, iLBCenc_inst);\n       SimplelsfQ(lsfdeq, lsf_index, lsf, iLBCenc_inst->lpc_n);\n\n\n\n\n\n       LSF_check(lsfdeq, LPC_FILTERORDER, iLBCenc_inst->lpc_n);\n       SimpleInterpolateLSF(syntdenum, weightdenum,\n           lsf, lsfdeq, iLBCenc_inst->lsfold,\n           iLBCenc_inst->lsfdeqold, LPC_FILTERORDER, iLBCenc_inst);\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/LPCencode.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       LPCencode.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_LPCENCOD_H\n   #define __iLBC_LPCENCOD_H\n\n   void LPCencode(\n       float *syntdenum,   /* (i/o) synthesis filter coefficients\n                                  before/after encoding */\n       float *weightdenum, /* (i/o) weighting denumerator coefficients\n                                  before/after encoding */\n       int *lsf_index,     /* (o) lsf quantization index */\n       float *data,    /* (i) lsf coefficients to quantize */\n       iLBC_Enc_Inst_t *iLBCenc_inst\n                           /* (i/o) the encoder state structure */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/StateConstructW.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       StateConstructW.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <math.h>\n   #include <string.h>\n\n   #include \"iLBC_define.h\"\n   #include \"constants.h\"\n   #include \"filter.h\"\n\n   /*----------------------------------------------------------------*\n    *  decoding of the start state\n    *---------------------------------------------------------------*/\n\n   void StateConstructW(\n       int idxForMax,      /* (i) 6-bit index for the quantization of\n                                  max amplitude */\n       int *idxVec,    /* (i) vector of quantization indexes */\n       float *syntDenum,   /* (i) synthesis filter denumerator */\n\n\n\n\n\n       float *out,         /* (o) the decoded state vector */\n       int len             /* (i) length of a state vector */\n   ){\n       float maxVal, tmpbuf[LPC_FILTERORDER+2*STATE_LEN], *tmp,\n           numerator[LPC_FILTERORDER+1];\n       float foutbuf[LPC_FILTERORDER+2*STATE_LEN], *fout;\n       int k,tmpi;\n\n       /* decoding of the maximum value */\n\n       maxVal = state_frgqTbl[idxForMax];\n       maxVal = (float)pow(10,maxVal)/(float)4.5;\n\n       /* initialization of buffers and coefficients */\n\n       memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float));\n       memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float));\n       for (k=0; k<LPC_FILTERORDER; k++) {\n           numerator[k]=syntDenum[LPC_FILTERORDER-k];\n       }\n       numerator[LPC_FILTERORDER]=syntDenum[0];\n       tmp = &tmpbuf[LPC_FILTERORDER];\n       fout = &foutbuf[LPC_FILTERORDER];\n\n       /* decoding of the sample values */\n\n       for (k=0; k<len; k++) {\n           tmpi = len-1-k;\n           /* maxVal = 1/scal */\n           tmp[k] = maxVal*state_sq3Tbl[idxVec[tmpi]];\n       }\n\n       /* circular convolution with all-pass filter */\n\n       memset(tmp+len, 0, len*sizeof(float));\n       ZeroPoleFilter(tmp, numerator, syntDenum, 2*len,\n           LPC_FILTERORDER, fout);\n       for (k=0;k<len;k++) {\n           out[k] = fout[len-1-k]+fout[2*len-1-k];\n       }\n   }\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/StateConstructW.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       StateConstructW.h\n\n\n\n\n\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_STATECONSTRUCTW_H\n   #define __iLBC_STATECONSTRUCTW_H\n\n   void StateConstructW(\n       int idxForMax,      /* (i) 6-bit index for the quantization of\n                                  max amplitude */\n       int *idxVec,    /* (i) vector of quantization indexes */\n       float *syntDenum,   /* (i) synthesis filter denumerator */\n       float *out,         /* (o) the decoded state vector */\n       int len             /* (i) length of a state vector */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/StateSearchW.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       StateSearchW.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <math.h>\n   #include <string.h>\n\n   #include \"iLBC_define.h\"\n   #include \"constants.h\"\n   #include \"filter.h\"\n   #include \"helpfun.h\"\n\n   /*----------------------------------------------------------------*\n    *  predictive noise shaping encoding of scaled start state\n    *  (subrutine for StateSearchW)\n    *---------------------------------------------------------------*/\n\n   void AbsQuantW(\n       iLBC_Enc_Inst_t *iLBCenc_inst,\n                           /* (i) Encoder instance */\n       float *in,          /* (i) vector to encode */\n       float *syntDenum,   /* (i) denominator of synthesis filter */\n       float *weightDenum, /* (i) denominator of weighting filter */\n       int *out,           /* (o) vector of quantizer indexes */\n       int len,        /* (i) length of vector to encode and\n                                  vector of quantizer indexes */\n       int state_first     /* (i) position of start state in the\n                                  80 vec */\n   ){\n       float *syntOut;\n       float syntOutBuf[LPC_FILTERORDER+STATE_SHORT_LEN_30MS];\n       float toQ, xq;\n       int n;\n       int index;\n\n       /* initialization of buffer for filtering */\n\n       memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float));\n\n\n\n\n\n\n       /* initialization of pointer for filtering */\n\n       syntOut = &syntOutBuf[LPC_FILTERORDER];\n\n       /* synthesis and weighting filters on input */\n\n       if (state_first) {\n           AllPoleFilter (in, weightDenum, SUBL, LPC_FILTERORDER);\n       } else {\n           AllPoleFilter (in, weightDenum,\n               iLBCenc_inst->state_short_len-SUBL,\n               LPC_FILTERORDER);\n       }\n\n       /* encoding loop */\n\n       for (n=0; n<len; n++) {\n\n           /* time update of filter coefficients */\n\n           if ((state_first)&&(n==SUBL)){\n               syntDenum += (LPC_FILTERORDER+1);\n               weightDenum += (LPC_FILTERORDER+1);\n\n               /* synthesis and weighting filters on input */\n               AllPoleFilter (&in[n], weightDenum, len-n,\n                   LPC_FILTERORDER);\n\n           } else if ((state_first==0)&&\n               (n==(iLBCenc_inst->state_short_len-SUBL))) {\n               syntDenum += (LPC_FILTERORDER+1);\n               weightDenum += (LPC_FILTERORDER+1);\n\n               /* synthesis and weighting filters on input */\n               AllPoleFilter (&in[n], weightDenum, len-n,\n                   LPC_FILTERORDER);\n\n           }\n\n           /* prediction of synthesized and weighted input */\n\n           syntOut[n] = 0.0;\n           AllPoleFilter (&syntOut[n], weightDenum, 1,\n               LPC_FILTERORDER);\n\n           /* quantization */\n\n           toQ = in[n]-syntOut[n];\n\n\n\n\n\n           sort_sq(&xq, &index, toQ, state_sq3Tbl, 8);\n           out[n]=index;\n           syntOut[n] = state_sq3Tbl[out[n]];\n\n           /* update of the prediction filter */\n\n           AllPoleFilter(&syntOut[n], weightDenum, 1,\n               LPC_FILTERORDER);\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  encoding of start state\n    *---------------------------------------------------------------*/\n\n   void StateSearchW(\n       iLBC_Enc_Inst_t *iLBCenc_inst,\n                           /* (i) Encoder instance */\n       float *residual,/* (i) target residual vector */\n       float *syntDenum,   /* (i) lpc synthesis filter */\n       float *weightDenum, /* (i) weighting filter denuminator */\n       int *idxForMax,     /* (o) quantizer index for maximum\n                                  amplitude */\n       int *idxVec,    /* (o) vector of quantization indexes */\n       int len,        /* (i) length of all vectors */\n       int state_first     /* (i) position of start state in the\n                                  80 vec */\n   ){\n       float dtmp, maxVal;\n       float tmpbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS];\n       float *tmp, numerator[1+LPC_FILTERORDER];\n       float foutbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS], *fout;\n       int k;\n       float qmax, scal;\n\n       /* initialization of buffers and filter coefficients */\n\n       memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float));\n       memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float));\n       for (k=0; k<LPC_FILTERORDER; k++) {\n           numerator[k]=syntDenum[LPC_FILTERORDER-k];\n       }\n       numerator[LPC_FILTERORDER]=syntDenum[0];\n       tmp = &tmpbuf[LPC_FILTERORDER];\n       fout = &foutbuf[LPC_FILTERORDER];\n\n       /* circular convolution with the all-pass filter */\n\n\n\n\n\n\n       memcpy(tmp, residual, len*sizeof(float));\n       memset(tmp+len, 0, len*sizeof(float));\n       ZeroPoleFilter(tmp, numerator, syntDenum, 2*len,\n           LPC_FILTERORDER, fout);\n       for (k=0; k<len; k++) {\n           fout[k] += fout[k+len];\n       }\n\n       /* identification of the maximum amplitude value */\n\n       maxVal = fout[0];\n       for (k=1; k<len; k++) {\n\n           if (fout[k]*fout[k] > maxVal*maxVal){\n               maxVal = fout[k];\n           }\n       }\n       maxVal=(float)fabs(maxVal);\n\n       /* encoding of the maximum amplitude value */\n\n       if (maxVal < 10.0) {\n           maxVal = 10.0;\n       }\n       maxVal = (float)log10(maxVal);\n       sort_sq(&dtmp, idxForMax, maxVal, state_frgqTbl, 64);\n\n       /* decoding of the maximum amplitude representation value,\n          and corresponding scaling of start state */\n\n       maxVal=state_frgqTbl[*idxForMax];\n       qmax = (float)pow(10,maxVal);\n       scal = (float)(4.5)/qmax;\n       for (k=0; k<len; k++){\n           fout[k] *= scal;\n       }\n\n       /* predictive noise shaping encoding of scaled start state */\n\n       AbsQuantW(iLBCenc_inst, fout,syntDenum,\n           weightDenum,idxVec, len, state_first);\n   }\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/StateSearchW.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       StateSearchW.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_STATESEARCHW_H\n   #define __iLBC_STATESEARCHW_H\n\n   void AbsQuantW(\n       iLBC_Enc_Inst_t *iLBCenc_inst,\n                           /* (i) Encoder instance */\n       float *in,          /* (i) vector to encode */\n       float *syntDenum,   /* (i) denominator of synthesis filter */\n       float *weightDenum, /* (i) denominator of weighting filter */\n       int *out,           /* (o) vector of quantizer indexes */\n       int len,        /* (i) length of vector to encode and\n                                  vector of quantizer indexes */\n       int state_first     /* (i) position of start state in the\n                                  80 vec */\n   );\n\n   void StateSearchW(\n       iLBC_Enc_Inst_t *iLBCenc_inst,\n                           /* (i) Encoder instance */\n       float *residual,/* (i) target residual vector */\n       float *syntDenum,   /* (i) lpc synthesis filter */\n       float *weightDenum, /* (i) weighting filter denuminator */\n       int *idxForMax,     /* (o) quantizer index for maximum\n                                  amplitude */\n       int *idxVec,    /* (o) vector of quantization indexes */\n       int len,        /* (i) length of all vectors */\n       int state_first     /* (i) position of start state in the\n                                  80 vec */\n   );\n\n\n   #endif\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/anaFilter.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       anaFilter.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <string.h>\n   #include \"iLBC_define.h\"\n\n   /*----------------------------------------------------------------*\n    *  LP analysis filter.\n    *---------------------------------------------------------------*/\n\n   void anaFilter(\n       float *In,  /* (i) Signal to be filtered */\n       float *a,   /* (i) LP parameters */\n       int len,/* (i) Length of signal */\n       float *Out, /* (o) Filtered signal */\n       float *mem  /* (i/o) Filter state */\n   ){\n       int i, j;\n       float *po, *pi, *pm, *pa;\n\n       po = Out;\n\n       /* Filter first part using memory from past */\n\n       for (i=0; i<LPC_FILTERORDER; i++) {\n           pi = &In[i];\n           pm = &mem[LPC_FILTERORDER-1];\n           pa = a;\n           *po=0.0;\n\n\n\n\n\n           for (j=0; j<=i; j++) {\n               *po+=(*pa++)*(*pi--);\n           }\n           for (j=i+1; j<LPC_FILTERORDER+1; j++) {\n\n               *po+=(*pa++)*(*pm--);\n           }\n           po++;\n       }\n\n       /* Filter last part where the state is entirely\n          in the input vector */\n\n       for (i=LPC_FILTERORDER; i<len; i++) {\n           pi = &In[i];\n           pa = a;\n           *po=0.0;\n           for (j=0; j<LPC_FILTERORDER+1; j++) {\n               *po+=(*pa++)*(*pi--);\n           }\n           po++;\n       }\n\n       /* Update state vector */\n\n       memcpy(mem, &In[len-LPC_FILTERORDER],\n           LPC_FILTERORDER*sizeof(float));\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/anaFilter.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       anaFilter.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_ANAFILTER_H\n   #define __iLBC_ANAFILTER_H\n\n   void anaFilter(\n\n\n\n\n\n       float *In,  /* (i) Signal to be filtered */\n       float *a,   /* (i) LP parameters */\n       int len,/* (i) Length of signal */\n       float *Out, /* (o) Filtered signal */\n       float *mem  /* (i/o) Filter state */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/constants.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       constants.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include \"iLBC_define.h\"\n\n   /* ULP bit allocation */\n\n       /* 20 ms frame */\n\n   const iLBC_ULP_Inst_t ULP_20msTbl = {\n       /* LSF */\n       {   {6,0,0,0,0}, {7,0,0,0,0}, {7,0,0,0,0},\n           {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},\n       /* Start state location, gain and samples */\n       {2,0,0,0,0},\n       {1,0,0,0,0},\n       {6,0,0,0,0},\n       {0,1,2,0,0},\n       /* extra CB index and extra CB gain */\n       {{6,0,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}},\n       {{2,0,3,0,0}, {1,1,2,0,0}, {0,0,3,0,0}},\n       /* CB index and CB gain */\n       {   {{7,0,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}},\n           {{0,0,8,0,0}, {0,0,8,0,0}, {0,0,8,0,0}},\n           {{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},\n           {{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}},\n       {   {{1,2,2,0,0}, {1,1,2,0,0}, {0,0,3,0,0}},\n           {{1,1,3,0,0}, {0,2,2,0,0}, {0,0,3,0,0}},\n           {{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},\n           {{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}}\n   };\n\n       /* 30 ms frame */\n\n   const iLBC_ULP_Inst_t ULP_30msTbl = {\n       /* LSF */\n\n\n\n\n\n       {   {6,0,0,0,0}, {7,0,0,0,0}, {7,0,0,0,0},\n           {6,0,0,0,0}, {7,0,0,0,0}, {7,0,0,0,0}},\n       /* Start state location, gain and samples */\n       {3,0,0,0,0},\n       {1,0,0,0,0},\n       {6,0,0,0,0},\n       {0,1,2,0,0},\n       /* extra CB index and extra CB gain */\n       {{4,2,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}},\n       {{1,1,3,0,0}, {1,1,2,0,0}, {0,0,3,0,0}},\n       /* CB index and CB gain */\n       {   {{6,1,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}},\n           {{0,7,1,0,0}, {0,0,8,0,0}, {0,0,8,0,0}},\n           {{0,7,1,0,0}, {0,0,8,0,0}, {0,0,8,0,0}},\n           {{0,7,1,0,0}, {0,0,8,0,0}, {0,0,8,0,0}}},\n       {   {{1,2,2,0,0}, {1,2,1,0,0}, {0,0,3,0,0}},\n           {{0,2,3,0,0}, {0,2,2,0,0}, {0,0,3,0,0}},\n           {{0,1,4,0,0}, {0,1,3,0,0}, {0,0,3,0,0}},\n           {{0,1,4,0,0}, {0,1,3,0,0}, {0,0,3,0,0}}}\n   };\n\n   /* HP Filters */\n\n   float hpi_zero_coefsTbl[3] = {\n       (float)0.92727436, (float)-1.8544941, (float)0.92727436\n   };\n   float hpi_pole_coefsTbl[3] = {\n       (float)1.0, (float)-1.9059465, (float)0.9114024\n   };\n   float hpo_zero_coefsTbl[3] = {\n       (float)0.93980581, (float)-1.8795834, (float)0.93980581\n   };\n   float hpo_pole_coefsTbl[3] = {\n       (float)1.0, (float)-1.9330735, (float)0.93589199\n   };\n\n   /* LP Filter */\n\n   float lpFilt_coefsTbl[FILTERORDER_DS]={\n       (float)-0.066650, (float)0.125000, (float)0.316650,\n       (float)0.414063, (float)0.316650,\n       (float)0.125000, (float)-0.066650\n   };\n\n   /* State quantization tables */\n\n   float state_sq3Tbl[8] = {\n       (float)-3.719849, (float)-2.177490, (float)-1.130005,\n\n\n\n\n\n       (float)-0.309692, (float)0.444214, (float)1.329712,\n       (float)2.436279, (float)3.983887\n   };\n\n   float state_frgqTbl[64] = {\n       (float)1.000085, (float)1.071695, (float)1.140395,\n       (float)1.206868, (float)1.277188, (float)1.351503,\n       (float)1.429380, (float)1.500727, (float)1.569049,\n       (float)1.639599, (float)1.707071, (float)1.781531,\n       (float)1.840799, (float)1.901550, (float)1.956695,\n       (float)2.006750, (float)2.055474, (float)2.102787,\n       (float)2.142819, (float)2.183592, (float)2.217962,\n       (float)2.257177, (float)2.295739, (float)2.332967,\n       (float)2.369248, (float)2.402792, (float)2.435080,\n       (float)2.468598, (float)2.503394, (float)2.539284,\n       (float)2.572944, (float)2.605036, (float)2.636331,\n       (float)2.668939, (float)2.698780, (float)2.729101,\n       (float)2.759786, (float)2.789834, (float)2.818679,\n       (float)2.848074, (float)2.877470, (float)2.906899,\n       (float)2.936655, (float)2.967804, (float)3.000115,\n       (float)3.033367, (float)3.066355, (float)3.104231,\n       (float)3.141499, (float)3.183012, (float)3.222952,\n       (float)3.265433, (float)3.308441, (float)3.350823,\n       (float)3.395275, (float)3.442793, (float)3.490801,\n       (float)3.542514, (float)3.604064, (float)3.666050,\n       (float)3.740994, (float)3.830749, (float)3.938770,\n       (float)4.101764\n   };\n\n   /* CB tables */\n\n   int search_rangeTbl[5][CB_NSTAGES]={{58,58,58}, {108,44,44},\n               {108,108,108}, {108,108,108}, {108,108,108}};\n   int stMemLTbl=85;\n   int memLfTbl[NASUB_MAX]={147,147,147,147};\n\n   /* expansion filter(s) */\n\n   float cbfiltersTbl[CB_FILTERLEN]={\n       (float)-0.034180, (float)0.108887, (float)-0.184326,\n       (float)0.806152,  (float)0.713379, (float)-0.144043,\n       (float)0.083740,  (float)-0.033691\n   };\n\n   /* Gain Quantization */\n\n   float gain_sq3Tbl[8]={\n       (float)-1.000000,  (float)-0.659973,  (float)-0.330017,\n\n\n\n\n\n       (float)0.000000, (float)0.250000, (float)0.500000,\n       (float)0.750000, (float)1.00000};\n\n   float gain_sq4Tbl[16]={\n       (float)-1.049988, (float)-0.900024, (float)-0.750000,\n       (float)-0.599976, (float)-0.450012, (float)-0.299988,\n       (float)-0.150024, (float)0.000000, (float)0.150024,\n       (float)0.299988, (float)0.450012, (float)0.599976,\n       (float)0.750000, (float)0.900024, (float)1.049988,\n       (float)1.200012};\n\n   float gain_sq5Tbl[32]={\n       (float)0.037476, (float)0.075012, (float)0.112488,\n       (float)0.150024, (float)0.187500, (float)0.224976,\n       (float)0.262512, (float)0.299988, (float)0.337524,\n       (float)0.375000, (float)0.412476, (float)0.450012,\n       (float)0.487488, (float)0.525024, (float)0.562500,\n       (float)0.599976, (float)0.637512, (float)0.674988,\n       (float)0.712524, (float)0.750000, (float)0.787476,\n       (float)0.825012, (float)0.862488, (float)0.900024,\n       (float)0.937500, (float)0.974976, (float)1.012512,\n       (float)1.049988, (float)1.087524, (float)1.125000,\n       (float)1.162476, (float)1.200012};\n\n   /* Enhancer - Upsamling a factor 4 (ENH_UPS0 = 4) */\n   float polyphaserTbl[ENH_UPS0*(2*ENH_FL0+1)]={\n       (float)0.000000, (float)0.000000, (float)0.000000,\n   (float)1.000000,\n           (float)0.000000, (float)0.000000, (float)0.000000,\n       (float)0.015625, (float)-0.076904, (float)0.288330,\n   (float)0.862061,\n           (float)-0.106445, (float)0.018799, (float)-0.015625,\n       (float)0.023682, (float)-0.124268, (float)0.601563,\n   (float)0.601563,\n           (float)-0.124268, (float)0.023682, (float)-0.023682,\n       (float)0.018799, (float)-0.106445, (float)0.862061,\n   (float)0.288330,\n           (float)-0.076904, (float)0.015625, (float)-0.018799};\n\n   float enh_plocsTbl[ENH_NBLOCKS_TOT] = {(float)40.0, (float)120.0,\n               (float)200.0, (float)280.0, (float)360.0,\n               (float)440.0, (float)520.0, (float)600.0};\n\n   /* LPC analysis and quantization */\n\n   int dim_lsfCbTbl[LSF_NSPLIT] = {3, 3, 4};\n   int size_lsfCbTbl[LSF_NSPLIT] = {64,128,128};\n\n\n\n\n\n\n   float lsfmeanTbl[LPC_FILTERORDER] = {\n       (float)0.281738, (float)0.445801, (float)0.663330,\n       (float)0.962524, (float)1.251831, (float)1.533081,\n       (float)1.850586, (float)2.137817, (float)2.481445,\n       (float)2.777344};\n\n   float lsf_weightTbl_30ms[6] = {(float)(1.0/2.0), (float)1.0,\n   (float)(2.0/3.0),\n       (float)(1.0/3.0), (float)0.0, (float)0.0};\n\n   float lsf_weightTbl_20ms[4] = {(float)(3.0/4.0), (float)(2.0/4.0),\n       (float)(1.0/4.0), (float)(0.0)};\n\n   /* Hanning LPC window */\n   float lpc_winTbl[BLOCKL_MAX]={\n       (float)0.000183, (float)0.000671, (float)0.001526,\n       (float)0.002716, (float)0.004242, (float)0.006104,\n       (float)0.008301, (float)0.010834, (float)0.013702,\n       (float)0.016907, (float)0.020416, (float)0.024261,\n       (float)0.028442, (float)0.032928, (float)0.037750,\n       (float)0.042877, (float)0.048309, (float)0.054047,\n       (float)0.060089, (float)0.066437, (float)0.073090,\n       (float)0.080017, (float)0.087219, (float)0.094727,\n       (float)0.102509, (float)0.110535, (float)0.118835,\n       (float)0.127411, (float)0.136230, (float)0.145294,\n       (float)0.154602, (float)0.164154, (float)0.173920,\n       (float)0.183899, (float)0.194122, (float)0.204529,\n       (float)0.215149, (float)0.225952, (float)0.236938,\n       (float)0.248108, (float)0.259460, (float)0.270966,\n       (float)0.282654, (float)0.294464, (float)0.306396,\n       (float)0.318481, (float)0.330688, (float)0.343018,\n       (float)0.355438, (float)0.367981, (float)0.380585,\n       (float)0.393280, (float)0.406067, (float)0.418884,\n       (float)0.431763, (float)0.444702, (float)0.457672,\n       (float)0.470673, (float)0.483704, (float)0.496735,\n       (float)0.509766, (float)0.522797, (float)0.535828,\n       (float)0.548798, (float)0.561768, (float)0.574677,\n       (float)0.587524, (float)0.600342, (float)0.613068,\n       (float)0.625732, (float)0.638306, (float)0.650787,\n       (float)0.663147, (float)0.675415, (float)0.687561,\n       (float)0.699585, (float)0.711487, (float)0.723206,\n       (float)0.734802, (float)0.746216, (float)0.757477,\n       (float)0.768585, (float)0.779480, (float)0.790192,\n       (float)0.800720, (float)0.811005, (float)0.821106,\n       (float)0.830994, (float)0.840668, (float)0.850067,\n       (float)0.859253, (float)0.868225, (float)0.876892,\n       (float)0.885345, (float)0.893524, (float)0.901428,\n       (float)0.909058, (float)0.916412, (float)0.923492,\n\n\n\n\n\n       (float)0.930267, (float)0.936768, (float)0.942963,\n       (float)0.948853, (float)0.954437, (float)0.959717,\n       (float)0.964691, (float)0.969360, (float)0.973694,\n       (float)0.977692, (float)0.981384, (float)0.984741,\n       (float)0.987762, (float)0.990479, (float)0.992828,\n       (float)0.994873, (float)0.996552, (float)0.997925,\n       (float)0.998932, (float)0.999603, (float)0.999969,\n       (float)0.999969, (float)0.999603, (float)0.998932,\n       (float)0.997925, (float)0.996552, (float)0.994873,\n       (float)0.992828, (float)0.990479, (float)0.987762,\n       (float)0.984741, (float)0.981384, (float)0.977692,\n       (float)0.973694, (float)0.969360, (float)0.964691,\n       (float)0.959717, (float)0.954437, (float)0.948853,\n       (float)0.942963, (float)0.936768, (float)0.930267,\n       (float)0.923492, (float)0.916412, (float)0.909058,\n       (float)0.901428, (float)0.893524, (float)0.885345,\n       (float)0.876892, (float)0.868225, (float)0.859253,\n       (float)0.850067, (float)0.840668, (float)0.830994,\n       (float)0.821106, (float)0.811005, (float)0.800720,\n       (float)0.790192, (float)0.779480, (float)0.768585,\n       (float)0.757477, (float)0.746216, (float)0.734802,\n       (float)0.723206, (float)0.711487, (float)0.699585,\n       (float)0.687561, (float)0.675415, (float)0.663147,\n       (float)0.650787, (float)0.638306, (float)0.625732,\n       (float)0.613068, (float)0.600342, (float)0.587524,\n       (float)0.574677, (float)0.561768, (float)0.548798,\n       (float)0.535828, (float)0.522797, (float)0.509766,\n       (float)0.496735, (float)0.483704, (float)0.470673,\n       (float)0.457672, (float)0.444702, (float)0.431763,\n       (float)0.418884, (float)0.406067, (float)0.393280,\n       (float)0.380585, (float)0.367981, (float)0.355438,\n       (float)0.343018, (float)0.330688, (float)0.318481,\n       (float)0.306396, (float)0.294464, (float)0.282654,\n       (float)0.270966, (float)0.259460, (float)0.248108,\n       (float)0.236938, (float)0.225952, (float)0.215149,\n       (float)0.204529, (float)0.194122, (float)0.183899,\n       (float)0.173920, (float)0.164154, (float)0.154602,\n       (float)0.145294, (float)0.136230, (float)0.127411,\n       (float)0.118835, (float)0.110535, (float)0.102509,\n       (float)0.094727, (float)0.087219, (float)0.080017,\n       (float)0.073090, (float)0.066437, (float)0.060089,\n       (float)0.054047, (float)0.048309, (float)0.042877,\n       (float)0.037750, (float)0.032928, (float)0.028442,\n       (float)0.024261, (float)0.020416, (float)0.016907,\n       (float)0.013702, (float)0.010834, (float)0.008301,\n       (float)0.006104, (float)0.004242, (float)0.002716,\n       (float)0.001526, (float)0.000671, (float)0.000183\n   };\n\n\n\n\n\n   /* Asymmetric LPC window */\n   float lpc_asymwinTbl[BLOCKL_MAX]={\n       (float)0.000061, (float)0.000214, (float)0.000458,\n       (float)0.000824, (float)0.001282, (float)0.001831,\n       (float)0.002472, (float)0.003235, (float)0.004120,\n       (float)0.005066, (float)0.006134, (float)0.007294,\n       (float)0.008545, (float)0.009918, (float)0.011383,\n       (float)0.012939, (float)0.014587, (float)0.016357,\n       (float)0.018219, (float)0.020172, (float)0.022217,\n       (float)0.024353, (float)0.026611, (float)0.028961,\n       (float)0.031372, (float)0.033905, (float)0.036530,\n       (float)0.039276, (float)0.042084, (float)0.044983,\n       (float)0.047974, (float)0.051086, (float)0.054260,\n       (float)0.057526, (float)0.060883, (float)0.064331,\n       (float)0.067871, (float)0.071503, (float)0.075226,\n       (float)0.079010, (float)0.082916, (float)0.086884,\n       (float)0.090942, (float)0.095062, (float)0.099304,\n       (float)0.103607, (float)0.107971, (float)0.112427,\n       (float)0.116974, (float)0.121582, (float)0.126282,\n       (float)0.131073, (float)0.135895, (float)0.140839,\n       (float)0.145813, (float)0.150879, (float)0.156006,\n       (float)0.161224, (float)0.166504, (float)0.171844,\n       (float)0.177246, (float)0.182709, (float)0.188263,\n       (float)0.193848, (float)0.199524, (float)0.205231,\n       (float)0.211029, (float)0.216858, (float)0.222778,\n       (float)0.228729, (float)0.234741, (float)0.240814,\n       (float)0.246918, (float)0.253082, (float)0.259308,\n       (float)0.265564, (float)0.271881, (float)0.278259,\n       (float)0.284668, (float)0.291107, (float)0.297607,\n       (float)0.304138, (float)0.310730, (float)0.317322,\n       (float)0.323975, (float)0.330658, (float)0.337372,\n       (float)0.344147, (float)0.350922, (float)0.357727,\n       (float)0.364594, (float)0.371460, (float)0.378357,\n       (float)0.385284, (float)0.392212, (float)0.399170,\n       (float)0.406158, (float)0.413177, (float)0.420197,\n       (float)0.427246, (float)0.434296, (float)0.441376,\n       (float)0.448456, (float)0.455536, (float)0.462646,\n       (float)0.469757, (float)0.476868, (float)0.483978,\n       (float)0.491089, (float)0.498230, (float)0.505341,\n       (float)0.512451, (float)0.519592, (float)0.526703,\n       (float)0.533813, (float)0.540924, (float)0.548004,\n       (float)0.555084, (float)0.562164, (float)0.569244,\n       (float)0.576294, (float)0.583313, (float)0.590332,\n       (float)0.597321, (float)0.604309, (float)0.611267,\n       (float)0.618195, (float)0.625092, (float)0.631989,\n       (float)0.638855, (float)0.645660, (float)0.652466,\n       (float)0.659241, (float)0.665985, (float)0.672668,\n       (float)0.679352, (float)0.685974, (float)0.692566,\n\n\n\n\n\n       (float)0.699127, (float)0.705658, (float)0.712128,\n       (float)0.718536, (float)0.724945, (float)0.731262,\n       (float)0.737549, (float)0.743805, (float)0.750000,\n       (float)0.756134, (float)0.762238, (float)0.768280,\n       (float)0.774261, (float)0.780182, (float)0.786072,\n       (float)0.791870, (float)0.797638, (float)0.803314,\n       (float)0.808960, (float)0.814514, (float)0.820038,\n       (float)0.825470, (float)0.830841, (float)0.836151,\n       (float)0.841400, (float)0.846558, (float)0.851654,\n       (float)0.856689, (float)0.861633, (float)0.866516,\n       (float)0.871338, (float)0.876068, (float)0.880737,\n       (float)0.885315, (float)0.889801, (float)0.894226,\n       (float)0.898560, (float)0.902832, (float)0.907013,\n       (float)0.911102, (float)0.915100, (float)0.919037,\n       (float)0.922882, (float)0.926636, (float)0.930328,\n       (float)0.933899, (float)0.937408, (float)0.940796,\n       (float)0.944122, (float)0.947357, (float)0.950470,\n       (float)0.953522, (float)0.956482, (float)0.959351,\n       (float)0.962097, (float)0.964783, (float)0.967377,\n       (float)0.969849, (float)0.972229, (float)0.974518,\n       (float)0.976715, (float)0.978821, (float)0.980835,\n       (float)0.982727, (float)0.984528, (float)0.986237,\n       (float)0.987854, (float)0.989380, (float)0.990784,\n       (float)0.992096, (float)0.993317, (float)0.994415,\n       (float)0.995422, (float)0.996338, (float)0.997162,\n       (float)0.997864, (float)0.998474, (float)0.998962,\n       (float)0.999390, (float)0.999695, (float)0.999878,\n       (float)0.999969, (float)0.999969, (float)0.996918,\n       (float)0.987701, (float)0.972382, (float)0.951050,\n       (float)0.923889, (float)0.891022, (float)0.852631,\n       (float)0.809021, (float)0.760406, (float)0.707092,\n       (float)0.649445, (float)0.587799, (float)0.522491,\n       (float)0.453979, (float)0.382690, (float)0.309021,\n       (float)0.233459, (float)0.156433, (float)0.078461\n   };\n\n   /* Lag window for LPC */\n   float lpc_lagwinTbl[LPC_FILTERORDER + 1]={\n       (float)1.000100, (float)0.998890, (float)0.995569,\n           (float)0.990057, (float)0.982392,\n       (float)0.972623, (float)0.960816, (float)0.947047,\n           (float)0.931405, (float)0.913989, (float)0.894909};\n\n   /* LSF quantization*/\n   float lsfCbTbl[64 * 3 + 128 * 3 + 128 * 4] = {\n   (float)0.155396, (float)0.273193, (float)0.451172,\n   (float)0.390503, (float)0.648071, (float)1.002075,\n   (float)0.440186, (float)0.692261, (float)0.955688,\n\n\n\n\n\n   (float)0.343628, (float)0.642334, (float)1.071533,\n   (float)0.318359, (float)0.491577, (float)0.670532,\n   (float)0.193115, (float)0.375488, (float)0.725708,\n   (float)0.364136, (float)0.510376, (float)0.658691,\n   (float)0.297485, (float)0.527588, (float)0.842529,\n   (float)0.227173, (float)0.365967, (float)0.563110,\n   (float)0.244995, (float)0.396729, (float)0.636475,\n   (float)0.169434, (float)0.300171, (float)0.520264,\n   (float)0.312866, (float)0.464478, (float)0.643188,\n   (float)0.248535, (float)0.429932, (float)0.626099,\n   (float)0.236206, (float)0.491333, (float)0.817139,\n   (float)0.334961, (float)0.625122, (float)0.895752,\n   (float)0.343018, (float)0.518555, (float)0.698608,\n   (float)0.372803, (float)0.659790, (float)0.945435,\n   (float)0.176880, (float)0.316528, (float)0.581421,\n   (float)0.416382, (float)0.625977, (float)0.805176,\n   (float)0.303223, (float)0.568726, (float)0.915039,\n   (float)0.203613, (float)0.351440, (float)0.588135,\n   (float)0.221191, (float)0.375000, (float)0.614746,\n   (float)0.199951, (float)0.323364, (float)0.476074,\n   (float)0.300781, (float)0.433350, (float)0.566895,\n   (float)0.226196, (float)0.354004, (float)0.507568,\n   (float)0.300049, (float)0.508179, (float)0.711670,\n   (float)0.312012, (float)0.492676, (float)0.763428,\n   (float)0.329956, (float)0.541016, (float)0.795776,\n   (float)0.373779, (float)0.604614, (float)0.928833,\n   (float)0.210571, (float)0.452026, (float)0.755249,\n   (float)0.271118, (float)0.473267, (float)0.662476,\n   (float)0.285522, (float)0.436890, (float)0.634399,\n   (float)0.246704, (float)0.565552, (float)0.859009,\n   (float)0.270508, (float)0.406250, (float)0.553589,\n   (float)0.361450, (float)0.578491, (float)0.813843,\n   (float)0.342651, (float)0.482788, (float)0.622437,\n   (float)0.340332, (float)0.549438, (float)0.743164,\n   (float)0.200439, (float)0.336304, (float)0.540894,\n   (float)0.407837, (float)0.644775, (float)0.895142,\n   (float)0.294678, (float)0.454834, (float)0.699097,\n   (float)0.193115, (float)0.344482, (float)0.643188,\n   (float)0.275757, (float)0.420776, (float)0.598755,\n   (float)0.380493, (float)0.608643, (float)0.861084,\n   (float)0.222778, (float)0.426147, (float)0.676514,\n   (float)0.407471, (float)0.700195, (float)1.053101,\n   (float)0.218384, (float)0.377197, (float)0.669922,\n   (float)0.313232, (float)0.454102, (float)0.600952,\n   (float)0.347412, (float)0.571533, (float)0.874146,\n   (float)0.238037, (float)0.405396, (float)0.729492,\n   (float)0.223877, (float)0.412964, (float)0.822021,\n   (float)0.395264, (float)0.582153, (float)0.743896,\n\n\n\n\n\n   (float)0.247925, (float)0.485596, (float)0.720581,\n   (float)0.229126, (float)0.496582, (float)0.907715,\n   (float)0.260132, (float)0.566895, (float)1.012695,\n   (float)0.337402, (float)0.611572, (float)0.978149,\n   (float)0.267822, (float)0.447632, (float)0.769287,\n   (float)0.250610, (float)0.381714, (float)0.530029,\n   (float)0.430054, (float)0.805054, (float)1.221924,\n   (float)0.382568, (float)0.544067, (float)0.701660,\n   (float)0.383545, (float)0.710327, (float)1.149170,\n   (float)0.271362, (float)0.529053, (float)0.775513,\n   (float)0.246826, (float)0.393555, (float)0.588623,\n   (float)0.266846, (float)0.422119, (float)0.676758,\n   (float)0.311523, (float)0.580688, (float)0.838623,\n   (float)1.331177, (float)1.576782, (float)1.779541,\n   (float)1.160034, (float)1.401978, (float)1.768188,\n   (float)1.161865, (float)1.525146, (float)1.715332,\n   (float)0.759521, (float)0.913940, (float)1.119873,\n   (float)0.947144, (float)1.121338, (float)1.282471,\n   (float)1.015015, (float)1.557007, (float)1.804932,\n   (float)1.172974, (float)1.402100, (float)1.692627,\n   (float)1.087524, (float)1.474243, (float)1.665405,\n   (float)0.899536, (float)1.105225, (float)1.406250,\n   (float)1.148438, (float)1.484741, (float)1.796265,\n   (float)0.785645, (float)1.209839, (float)1.567749,\n   (float)0.867798, (float)1.166504, (float)1.450684,\n   (float)0.922485, (float)1.229858, (float)1.420898,\n   (float)0.791260, (float)1.123291, (float)1.409546,\n   (float)0.788940, (float)0.966064, (float)1.340332,\n   (float)1.051147, (float)1.272827, (float)1.556641,\n   (float)0.866821, (float)1.181152, (float)1.538818,\n   (float)0.906738, (float)1.373535, (float)1.607910,\n   (float)1.244751, (float)1.581421, (float)1.933838,\n   (float)0.913940, (float)1.337280, (float)1.539673,\n   (float)0.680542, (float)0.959229, (float)1.662720,\n   (float)0.887207, (float)1.430542, (float)1.800781,\n   (float)0.912598, (float)1.433594, (float)1.683960,\n   (float)0.860474, (float)1.060303, (float)1.455322,\n   (float)1.005127, (float)1.381104, (float)1.706909,\n   (float)0.800781, (float)1.363892, (float)1.829102,\n   (float)0.781860, (float)1.124390, (float)1.505981,\n   (float)1.003662, (float)1.471436, (float)1.684692,\n   (float)0.981323, (float)1.309570, (float)1.618042,\n   (float)1.228760, (float)1.554321, (float)1.756470,\n   (float)0.734375, (float)0.895752, (float)1.225586,\n   (float)0.841797, (float)1.055664, (float)1.249268,\n   (float)0.920166, (float)1.119385, (float)1.486206,\n   (float)0.894409, (float)1.539063, (float)1.828979,\n   (float)1.283691, (float)1.543335, (float)1.858276,\n\n\n\n\n\n   (float)0.676025, (float)0.933105, (float)1.490845,\n   (float)0.821289, (float)1.491821, (float)1.739868,\n   (float)0.923218, (float)1.144653, (float)1.580566,\n   (float)1.057251, (float)1.345581, (float)1.635864,\n   (float)0.888672, (float)1.074951, (float)1.353149,\n   (float)0.942749, (float)1.195435, (float)1.505493,\n   (float)1.492310, (float)1.788086, (float)2.039673,\n   (float)1.070313, (float)1.634399, (float)1.860962,\n   (float)1.253296, (float)1.488892, (float)1.686035,\n   (float)0.647095, (float)0.864014, (float)1.401855,\n   (float)0.866699, (float)1.254883, (float)1.453369,\n   (float)1.063965, (float)1.532593, (float)1.731323,\n   (float)1.167847, (float)1.521484, (float)1.884033,\n   (float)0.956055, (float)1.502075, (float)1.745605,\n   (float)0.928711, (float)1.288574, (float)1.479614,\n   (float)1.088013, (float)1.380737, (float)1.570801,\n   (float)0.905029, (float)1.186768, (float)1.371948,\n   (float)1.057861, (float)1.421021, (float)1.617432,\n   (float)1.108276, (float)1.312500, (float)1.501465,\n   (float)0.979492, (float)1.416992, (float)1.624268,\n   (float)1.276001, (float)1.661011, (float)2.007935,\n   (float)0.993042, (float)1.168579, (float)1.331665,\n   (float)0.778198, (float)0.944946, (float)1.235962,\n   (float)1.223755, (float)1.491333, (float)1.815674,\n   (float)0.852661, (float)1.350464, (float)1.722290,\n   (float)1.134766, (float)1.593140, (float)1.787354,\n   (float)1.051392, (float)1.339722, (float)1.531006,\n   (float)0.803589, (float)1.271240, (float)1.652100,\n   (float)0.755737, (float)1.143555, (float)1.639404,\n   (float)0.700928, (float)0.837280, (float)1.130371,\n   (float)0.942749, (float)1.197876, (float)1.669800,\n   (float)0.993286, (float)1.378296, (float)1.566528,\n   (float)0.801025, (float)1.095337, (float)1.298950,\n   (float)0.739990, (float)1.032959, (float)1.383667,\n   (float)0.845703, (float)1.072266, (float)1.543823,\n   (float)0.915649, (float)1.072266, (float)1.224487,\n   (float)1.021973, (float)1.226196, (float)1.481323,\n   (float)0.999878, (float)1.204102, (float)1.555908,\n   (float)0.722290, (float)0.913940, (float)1.340210,\n   (float)0.673340, (float)0.835938, (float)1.259521,\n   (float)0.832397, (float)1.208374, (float)1.394165,\n   (float)0.962158, (float)1.576172, (float)1.912842,\n   (float)1.166748, (float)1.370850, (float)1.556763,\n   (float)0.946289, (float)1.138550, (float)1.400391,\n   (float)1.035034, (float)1.218262, (float)1.386475,\n   (float)1.393799, (float)1.717773, (float)2.000244,\n   (float)0.972656, (float)1.260986, (float)1.760620,\n   (float)1.028198, (float)1.288452, (float)1.484619,\n\n\n\n\n\n   (float)0.773560, (float)1.258057, (float)1.756714,\n   (float)1.080322, (float)1.328003, (float)1.742676,\n   (float)0.823975, (float)1.450806, (float)1.917725,\n   (float)0.859009, (float)1.016602, (float)1.191895,\n   (float)0.843994, (float)1.131104, (float)1.645020,\n   (float)1.189697, (float)1.702759, (float)1.894409,\n   (float)1.346680, (float)1.763184, (float)2.066040,\n   (float)0.980469, (float)1.253784, (float)1.441650,\n   (float)1.338135, (float)1.641968, (float)1.932739,\n   (float)1.223267, (float)1.424194, (float)1.626465,\n   (float)0.765747, (float)1.004150, (float)1.579102,\n   (float)1.042847, (float)1.269165, (float)1.647461,\n   (float)0.968750, (float)1.257568, (float)1.555786,\n   (float)0.826294, (float)0.993408, (float)1.275146,\n   (float)0.742310, (float)0.950439, (float)1.430542,\n   (float)1.054321, (float)1.439819, (float)1.828003,\n   (float)1.072998, (float)1.261719, (float)1.441895,\n   (float)0.859375, (float)1.036377, (float)1.314819,\n   (float)0.895752, (float)1.267212, (float)1.605591,\n   (float)0.805420, (float)0.962891, (float)1.142334,\n   (float)0.795654, (float)1.005493, (float)1.468506,\n   (float)1.105347, (float)1.313843, (float)1.584839,\n   (float)0.792236, (float)1.221802, (float)1.465698,\n   (float)1.170532, (float)1.467651, (float)1.664063,\n   (float)0.838257, (float)1.153198, (float)1.342163,\n   (float)0.968018, (float)1.198242, (float)1.391235,\n   (float)1.250122, (float)1.623535, (float)1.823608,\n   (float)0.711670, (float)1.058350, (float)1.512085,\n   (float)1.204834, (float)1.454468, (float)1.739136,\n   (float)1.137451, (float)1.421753, (float)1.620117,\n   (float)0.820435, (float)1.322754, (float)1.578247,\n   (float)0.798706, (float)1.005005, (float)1.213867,\n   (float)0.980713, (float)1.324951, (float)1.512939,\n   (float)1.112305, (float)1.438843, (float)1.735596,\n   (float)1.135498, (float)1.356689, (float)1.635742,\n   (float)1.101318, (float)1.387451, (float)1.686523,\n   (float)0.849854, (float)1.276978, (float)1.523438,\n   (float)1.377930, (float)1.627563, (float)1.858154,\n   (float)0.884888, (float)1.095459, (float)1.287476,\n   (float)1.289795, (float)1.505859, (float)1.756592,\n   (float)0.817505, (float)1.384155, (float)1.650513,\n   (float)1.446655, (float)1.702148, (float)1.931885,\n   (float)0.835815, (float)1.023071, (float)1.385376,\n   (float)0.916626, (float)1.139038, (float)1.335327,\n   (float)0.980103, (float)1.174072, (float)1.453735,\n   (float)1.705688, (float)2.153809, (float)2.398315, (float)2.743408,\n   (float)1.797119, (float)2.016846, (float)2.445679, (float)2.701904,\n   (float)1.990356, (float)2.219116, (float)2.576416, (float)2.813477,\n\n\n\n\n\n   (float)1.849365, (float)2.190918, (float)2.611572, (float)2.835083,\n   (float)1.657959, (float)1.854370, (float)2.159058, (float)2.726196,\n   (float)1.437744, (float)1.897705, (float)2.253174, (float)2.655396,\n   (float)2.028687, (float)2.247314, (float)2.542358, (float)2.875854,\n   (float)1.736938, (float)1.922119, (float)2.185913, (float)2.743408,\n   (float)1.521606, (float)1.870972, (float)2.526855, (float)2.786987,\n   (float)1.841431, (float)2.050659, (float)2.463623, (float)2.857666,\n   (float)1.590088, (float)2.067261, (float)2.427979, (float)2.794434,\n   (float)1.746826, (float)2.057373, (float)2.320190, (float)2.800781,\n   (float)1.734619, (float)1.940552, (float)2.306030, (float)2.826416,\n   (float)1.786255, (float)2.204468, (float)2.457520, (float)2.795288,\n   (float)1.861084, (float)2.170532, (float)2.414551, (float)2.763672,\n   (float)2.001465, (float)2.307617, (float)2.552734, (float)2.811890,\n   (float)1.784424, (float)2.124146, (float)2.381592, (float)2.645508,\n   (float)1.888794, (float)2.135864, (float)2.418579, (float)2.861206,\n   (float)2.301147, (float)2.531250, (float)2.724976, (float)2.913086,\n   (float)1.837769, (float)2.051270, (float)2.261963, (float)2.553223,\n   (float)2.012939, (float)2.221191, (float)2.440186, (float)2.678101,\n   (float)1.429565, (float)1.858276, (float)2.582275, (float)2.845703,\n   (float)1.622803, (float)1.897705, (float)2.367310, (float)2.621094,\n   (float)1.581543, (float)1.960449, (float)2.515869, (float)2.736450,\n   (float)1.419434, (float)1.933960, (float)2.394653, (float)2.746704,\n   (float)1.721924, (float)2.059570, (float)2.421753, (float)2.769653,\n   (float)1.911011, (float)2.220703, (float)2.461060, (float)2.740723,\n   (float)1.581177, (float)1.860840, (float)2.516968, (float)2.874634,\n   (float)1.870361, (float)2.098755, (float)2.432373, (float)2.656494,\n   (float)2.059692, (float)2.279785, (float)2.495605, (float)2.729370,\n   (float)1.815674, (float)2.181519, (float)2.451538, (float)2.680542,\n   (float)1.407959, (float)1.768311, (float)2.343018, (float)2.668091,\n   (float)2.168701, (float)2.394653, (float)2.604736, (float)2.829346,\n   (float)1.636230, (float)1.865723, (float)2.329102, (float)2.824219,\n   (float)1.878906, (float)2.139526, (float)2.376709, (float)2.679810,\n   (float)1.765381, (float)1.971802, (float)2.195435, (float)2.586914,\n   (float)2.164795, (float)2.410889, (float)2.673706, (float)2.903198,\n   (float)2.071899, (float)2.331055, (float)2.645874, (float)2.907104,\n   (float)2.026001, (float)2.311523, (float)2.594849, (float)2.863892,\n   (float)1.948975, (float)2.180786, (float)2.514893, (float)2.797852,\n   (float)1.881836, (float)2.130859, (float)2.478149, (float)2.804199,\n   (float)2.238159, (float)2.452759, (float)2.652832, (float)2.868286,\n   (float)1.897949, (float)2.101685, (float)2.524292, (float)2.880127,\n   (float)1.856445, (float)2.074585, (float)2.541016, (float)2.791748,\n   (float)1.695557, (float)2.199097, (float)2.506226, (float)2.742676,\n   (float)1.612671, (float)1.877075, (float)2.435425, (float)2.732910,\n   (float)1.568848, (float)1.786499, (float)2.194580, (float)2.768555,\n   (float)1.953369, (float)2.164551, (float)2.486938, (float)2.874023,\n   (float)1.388306, (float)1.725342, (float)2.384521, (float)2.771851,\n   (float)2.115356, (float)2.337769, (float)2.592896, (float)2.864014,\n   (float)1.905762, (float)2.111328, (float)2.363525, (float)2.789307,\n\n\n\n\n\n   (float)1.882568, (float)2.332031, (float)2.598267, (float)2.827637,\n   (float)1.683594, (float)2.088745, (float)2.361938, (float)2.608643,\n   (float)1.874023, (float)2.182129, (float)2.536133, (float)2.766968,\n   (float)1.861938, (float)2.070435, (float)2.309692, (float)2.700562,\n   (float)1.722168, (float)2.107422, (float)2.477295, (float)2.837646,\n   (float)1.926880, (float)2.184692, (float)2.442627, (float)2.663818,\n   (float)2.123901, (float)2.337280, (float)2.553101, (float)2.777466,\n   (float)1.588135, (float)1.911499, (float)2.212769, (float)2.543945,\n   (float)2.053955, (float)2.370850, (float)2.712158, (float)2.939941,\n   (float)2.210449, (float)2.519653, (float)2.770386, (float)2.958618,\n   (float)2.199463, (float)2.474731, (float)2.718262, (float)2.919922,\n   (float)1.960083, (float)2.175415, (float)2.608032, (float)2.888794,\n   (float)1.953735, (float)2.185181, (float)2.428223, (float)2.809570,\n   (float)1.615234, (float)2.036499, (float)2.576538, (float)2.834595,\n   (float)1.621094, (float)2.028198, (float)2.431030, (float)2.664673,\n   (float)1.824951, (float)2.267456, (float)2.514526, (float)2.747925,\n   (float)1.994263, (float)2.229126, (float)2.475220, (float)2.833984,\n   (float)1.746338, (float)2.011353, (float)2.588257, (float)2.826904,\n   (float)1.562866, (float)2.135986, (float)2.471680, (float)2.687256,\n   (float)1.748901, (float)2.083496, (float)2.460938, (float)2.686279,\n   (float)1.758057, (float)2.131470, (float)2.636597, (float)2.891602,\n   (float)2.071289, (float)2.299072, (float)2.550781, (float)2.814331,\n   (float)1.839600, (float)2.094360, (float)2.496460, (float)2.723999,\n   (float)1.882202, (float)2.088257, (float)2.636841, (float)2.923096,\n   (float)1.957886, (float)2.153198, (float)2.384399, (float)2.615234,\n   (float)1.992920, (float)2.351196, (float)2.654419, (float)2.889771,\n   (float)2.012817, (float)2.262451, (float)2.643799, (float)2.903076,\n   (float)2.025635, (float)2.254761, (float)2.508423, (float)2.784058,\n   (float)2.316040, (float)2.589355, (float)2.794189, (float)2.963623,\n   (float)1.741211, (float)2.279541, (float)2.578491, (float)2.816284,\n   (float)1.845337, (float)2.055786, (float)2.348511, (float)2.822021,\n   (float)1.679932, (float)1.926514, (float)2.499756, (float)2.835693,\n   (float)1.722534, (float)1.946899, (float)2.448486, (float)2.728760,\n   (float)1.829834, (float)2.043213, (float)2.580444, (float)2.867676,\n   (float)1.676636, (float)2.071655, (float)2.322510, (float)2.704834,\n   (float)1.791504, (float)2.113525, (float)2.469727, (float)2.784058,\n   (float)1.977051, (float)2.215088, (float)2.497437, (float)2.726929,\n   (float)1.800171, (float)2.106689, (float)2.357788, (float)2.738892,\n   (float)1.827759, (float)2.170166, (float)2.525879, (float)2.852417,\n   (float)1.918335, (float)2.132813, (float)2.488403, (float)2.728149,\n   (float)1.916748, (float)2.225098, (float)2.542603, (float)2.857666,\n   (float)1.761230, (float)1.976074, (float)2.507446, (float)2.884521,\n   (float)2.053711, (float)2.367432, (float)2.608032, (float)2.837646,\n   (float)1.595337, (float)2.000977, (float)2.307129, (float)2.578247,\n   (float)1.470581, (float)2.031250, (float)2.375854, (float)2.647583,\n   (float)1.801392, (float)2.128052, (float)2.399780, (float)2.822876,\n   (float)1.853638, (float)2.066650, (float)2.429199, (float)2.751465,\n   (float)1.956299, (float)2.163696, (float)2.394775, (float)2.734253,\n\n\n\n\n\n   (float)1.963623, (float)2.275757, (float)2.585327, (float)2.865234,\n   (float)1.887451, (float)2.105469, (float)2.331787, (float)2.587402,\n   (float)2.120117, (float)2.443359, (float)2.733887, (float)2.941406,\n   (float)1.506348, (float)1.766968, (float)2.400513, (float)2.851807,\n   (float)1.664551, (float)1.981079, (float)2.375732, (float)2.774414,\n   (float)1.720703, (float)1.978882, (float)2.391479, (float)2.640991,\n   (float)1.483398, (float)1.814819, (float)2.434448, (float)2.722290,\n   (float)1.769043, (float)2.136597, (float)2.563721, (float)2.774414,\n   (float)1.810791, (float)2.049316, (float)2.373901, (float)2.613647,\n   (float)1.788330, (float)2.005981, (float)2.359131, (float)2.723145,\n   (float)1.785156, (float)1.993164, (float)2.399780, (float)2.832520,\n   (float)1.695313, (float)2.022949, (float)2.522583, (float)2.745117,\n   (float)1.584106, (float)1.965576, (float)2.299927, (float)2.715576,\n   (float)1.894897, (float)2.249878, (float)2.655884, (float)2.897705,\n   (float)1.720581, (float)1.995728, (float)2.299438, (float)2.557007,\n   (float)1.619385, (float)2.173950, (float)2.574219, (float)2.787964,\n   (float)1.883179, (float)2.220459, (float)2.474365, (float)2.825073,\n   (float)1.447632, (float)2.045044, (float)2.555542, (float)2.744873,\n   (float)1.502686, (float)2.156616, (float)2.653320, (float)2.846558,\n   (float)1.711548, (float)1.944092, (float)2.282959, (float)2.685791,\n   (float)1.499756, (float)1.867554, (float)2.341064, (float)2.578857,\n   (float)1.916870, (float)2.135132, (float)2.568237, (float)2.826050,\n   (float)1.498047, (float)1.711182, (float)2.223267, (float)2.755127,\n   (float)1.808716, (float)1.997559, (float)2.256470, (float)2.758545,\n   (float)2.088501, (float)2.402710, (float)2.667358, (float)2.890259,\n   (float)1.545044, (float)1.819214, (float)2.324097, (float)2.692993,\n   (float)1.796021, (float)2.012573, (float)2.505737, (float)2.784912,\n   (float)1.786499, (float)2.041748, (float)2.290405, (float)2.650757,\n   (float)1.938232, (float)2.264404, (float)2.529053, (float)2.796143\n   };\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/constants.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       constants.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_CONSTANTS_H\n   #define __iLBC_CONSTANTS_H\n\n   #include \"iLBC_define.h\"\n\n\n   /* ULP bit allocation */\n\n\n\n\n\n\n   extern const iLBC_ULP_Inst_t ULP_20msTbl;\n   extern const iLBC_ULP_Inst_t ULP_30msTbl;\n\n   /* high pass filters */\n\n   extern float hpi_zero_coefsTbl[];\n   extern float hpi_pole_coefsTbl[];\n   extern float hpo_zero_coefsTbl[];\n   extern float hpo_pole_coefsTbl[];\n\n   /* low pass filters */\n   extern float lpFilt_coefsTbl[];\n\n   /* LPC analysis and quantization */\n\n   extern float lpc_winTbl[];\n   extern float lpc_asymwinTbl[];\n   extern float lpc_lagwinTbl[];\n   extern float lsfCbTbl[];\n   extern float lsfmeanTbl[];\n   extern int   dim_lsfCbTbl[];\n   extern int   size_lsfCbTbl[];\n   extern float lsf_weightTbl_30ms[];\n   extern float lsf_weightTbl_20ms[];\n\n   /* state quantization tables */\n\n   extern float state_sq3Tbl[];\n   extern float state_frgqTbl[];\n\n   /* gain quantization tables */\n\n   extern float gain_sq3Tbl[];\n   extern float gain_sq4Tbl[];\n   extern float gain_sq5Tbl[];\n\n   /* adaptive codebook definitions */\n\n   extern int search_rangeTbl[5][CB_NSTAGES];\n   extern int memLfTbl[];\n   extern int stMemLTbl;\n   extern float cbfiltersTbl[CB_FILTERLEN];\n\n   /* enhancer definitions */\n\n   extern float polyphaserTbl[];\n   extern float enh_plocsTbl[];\n\n\n\n\n\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/createCB.c",
    "content": "\n\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       createCB.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n\n\n\n\n   #include \"iLBC_define.h\"\n   #include \"constants.h\"\n   #include <string.h>\n   #include <math.h>\n\n   /*----------------------------------------------------------------*\n    *  Construct an additional codebook vector by filtering the\n    *  initial codebook buffer. This vector is then used to expand\n    *  the codebook with an additional section.\n    *---------------------------------------------------------------*/\n\n   void filteredCBvecs(\n       float *cbvectors,   /* (o) Codebook vectors for the\n                                  higher section */\n       float *mem,         /* (i) Buffer to create codebook\n                                  vector from */\n       int lMem        /* (i) Length of buffer */\n   ){\n       int j, k;\n       float *pp, *pp1;\n       float tempbuff2[CB_MEML+CB_FILTERLEN];\n       float *pos;\n\n       memset(tempbuff2, 0, (CB_HALFFILTERLEN-1)*sizeof(float));\n       memcpy(&tempbuff2[CB_HALFFILTERLEN-1], mem, lMem*sizeof(float));\n       memset(&tempbuff2[lMem+CB_HALFFILTERLEN-1], 0,\n           (CB_HALFFILTERLEN+1)*sizeof(float));\n\n       /* Create codebook vector for higher section by filtering */\n\n       /* do filtering */\n       pos=cbvectors;\n       memset(pos, 0, lMem*sizeof(float));\n       for (k=0; k<lMem; k++) {\n           pp=&tempbuff2[k];\n           pp1=&cbfiltersTbl[CB_FILTERLEN-1];\n           for (j=0;j<CB_FILTERLEN;j++) {\n               (*pos)+=(*pp++)*(*pp1--);\n           }\n           pos++;\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  Search the augmented part of the codebook to find the best\n    *  measure.\n    *----------------------------------------------------------------*/\n\n\n\n\n\n\n   void searchAugmentedCB(\n       int low,        /* (i) Start index for the search */\n       int high,           /* (i) End index for the search */\n       int stage,          /* (i) Current stage */\n       int startIndex,     /* (i) Codebook index for the first\n                                  aug vector */\n       float *target,      /* (i) Target vector for encoding */\n       float *buffer,      /* (i) Pointer to the end of the buffer for\n                                  augmented codebook construction */\n       float *max_measure, /* (i/o) Currently maximum measure */\n       int *best_index,/* (o) Currently the best index */\n       float *gain,    /* (o) Currently the best gain */\n       float *energy,      /* (o) Energy of augmented codebook\n                                  vectors */\n       float *invenergy/* (o) Inv energy of augmented codebook\n                                  vectors */\n   ) {\n       int icount, ilow, j, tmpIndex;\n       float *pp, *ppo, *ppi, *ppe, crossDot, alfa;\n       float weighted, measure, nrjRecursive;\n       float ftmp;\n\n       /* Compute the energy for the first (low-5)\n          noninterpolated samples */\n       nrjRecursive = (float) 0.0;\n       pp = buffer - low + 1;\n       for (j=0; j<(low-5); j++) {\n           nrjRecursive += ( (*pp)*(*pp) );\n           pp++;\n       }\n       ppe = buffer - low;\n\n\n       for (icount=low; icount<=high; icount++) {\n\n           /* Index of the codebook vector used for retrieving\n              energy values */\n           tmpIndex = startIndex+icount-20;\n\n           ilow = icount-4;\n\n           /* Update the energy recursively to save complexity */\n           nrjRecursive = nrjRecursive + (*ppe)*(*ppe);\n           ppe--;\n           energy[tmpIndex] = nrjRecursive;\n\n           /* Compute cross dot product for the first (low-5)\n              samples */\n\n\n\n\n\n           crossDot = (float) 0.0;\n           pp = buffer-icount;\n           for (j=0; j<ilow; j++) {\n               crossDot += target[j]*(*pp++);\n           }\n\n           /* interpolation */\n           alfa = (float) 0.2;\n           ppo = buffer-4;\n           ppi = buffer-icount-4;\n           for (j=ilow; j<icount; j++) {\n               weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi);\n               ppo++;\n               ppi++;\n               energy[tmpIndex] += weighted*weighted;\n               crossDot += target[j]*weighted;\n               alfa += (float)0.2;\n           }\n\n           /* Compute energy and cross dot product for the\n              remaining samples */\n           pp = buffer - icount;\n           for (j=icount; j<SUBL; j++) {\n               energy[tmpIndex] += (*pp)*(*pp);\n               crossDot += target[j]*(*pp++);\n           }\n\n           if (energy[tmpIndex]>0.0) {\n               invenergy[tmpIndex]=(float)1.0/(energy[tmpIndex]+EPS);\n           } else {\n               invenergy[tmpIndex] = (float) 0.0;\n           }\n\n           if (stage==0) {\n               measure = (float)-10000000.0;\n\n               if (crossDot > 0.0) {\n                   measure = crossDot*crossDot*invenergy[tmpIndex];\n               }\n           }\n           else {\n               measure = crossDot*crossDot*invenergy[tmpIndex];\n           }\n\n           /* check if measure is better */\n           ftmp = crossDot*invenergy[tmpIndex];\n\n           if ((measure>*max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {\n\n\n\n\n\n               *best_index = tmpIndex;\n               *max_measure = measure;\n               *gain = ftmp;\n           }\n       }\n   }\n\n\n   /*----------------------------------------------------------------*\n    *  Recreate a specific codebook vector from the augmented part.\n    *\n    *----------------------------------------------------------------*/\n\n   void createAugmentedVec(\n       int index,      /* (i) Index for the augmented vector\n                              to be created */\n       float *buffer,  /* (i) Pointer to the end of the buffer for\n                              augmented codebook construction */\n       float *cbVec/* (o) The construced codebook vector */\n   ) {\n       int ilow, j;\n       float *pp, *ppo, *ppi, alfa, alfa1, weighted;\n\n       ilow = index-5;\n\n       /* copy the first noninterpolated part */\n\n       pp = buffer-index;\n       memcpy(cbVec,pp,sizeof(float)*index);\n\n       /* interpolation */\n\n       alfa1 = (float)0.2;\n       alfa = 0.0;\n       ppo = buffer-5;\n       ppi = buffer-index-5;\n       for (j=ilow; j<index; j++) {\n           weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi);\n           ppo++;\n           ppi++;\n           cbVec[j] = weighted;\n           alfa += alfa1;\n       }\n\n       /* copy the second noninterpolated part */\n\n       pp = buffer - index;\n       memcpy(cbVec+index,pp,sizeof(float)*(SUBL-index));\n\n\n\n\n\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/createCB.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       createCB.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_CREATECB_H\n   #define __iLBC_CREATECB_H\n\n   void filteredCBvecs(\n       float *cbvectors,   /* (o) Codebook vector for the\n                                  higher section */\n\n\n\n\n\n       float *mem,         /* (i) Buffer to create codebook\n                                  vectors from */\n       int lMem        /* (i) Length of buffer */\n   );\n\n   void searchAugmentedCB(\n       int low,        /* (i) Start index for the search */\n       int high,           /* (i) End index for the search */\n       int stage,          /* (i) Current stage */\n       int startIndex,     /* (i) CB index for the first\n                                  augmented vector */\n       float *target,      /* (i) Target vector for encoding */\n       float *buffer,      /* (i) Pointer to the end of the\n                                  buffer for augmented codebook\n                                  construction */\n       float *max_measure, /* (i/o) Currently maximum measure */\n       int *best_index,/* (o) Currently the best index */\n       float *gain,    /* (o) Currently the best gain */\n       float *energy,      /* (o) Energy of augmented\n                                  codebook vectors */\n       float *invenergy/* (o) Inv energy of aug codebook\n                                  vectors */\n   );\n\n   void createAugmentedVec(\n       int index,          /* (i) Index for the aug vector\n                                  to be created */\n       float *buffer,      /* (i) Pointer to the end of the\n                                  buffer for augmented codebook\n                                  construction */\n       float *cbVec    /* (o) The construced codebook vector */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/doCPLC.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       doCPLC.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <math.h>\n   #include <string.h>\n   #include <stdio.h>\n\n\n\n\n\n   #include \"iLBC_define.h\"\n\n   /*----------------------------------------------------------------*\n    *  Compute cross correlation and pitch gain for pitch prediction\n    *  of last subframe at given lag.\n    *---------------------------------------------------------------*/\n\n   void compCorr(\n       float *cc,      /* (o) cross correlation coefficient */\n       float *gc,      /* (o) gain */\n       float *pm,\n       float *buffer,  /* (i) signal buffer */\n       int lag,    /* (i) pitch lag */\n       int bLen,       /* (i) length of buffer */\n       int sRange      /* (i) correlation search length */\n   ){\n       int i;\n       float ftmp1, ftmp2, ftmp3;\n\n       /* Guard against getting outside buffer */\n       if ((bLen-sRange-lag)<0) {\n           sRange=bLen-lag;\n       }\n\n       ftmp1 = 0.0;\n       ftmp2 = 0.0;\n       ftmp3 = 0.0;\n       for (i=0; i<sRange; i++) {\n           ftmp1 += buffer[bLen-sRange+i] *\n               buffer[bLen-sRange+i-lag];\n           ftmp2 += buffer[bLen-sRange+i-lag] *\n                   buffer[bLen-sRange+i-lag];\n           ftmp3 += buffer[bLen-sRange+i] *\n                   buffer[bLen-sRange+i];\n       }\n\n       if (ftmp2 > 0.0) {\n           *cc = ftmp1*ftmp1/ftmp2;\n           *gc = (float)fabs(ftmp1/ftmp2);\n           *pm=(float)fabs(ftmp1)/\n               ((float)sqrt(ftmp2)*(float)sqrt(ftmp3));\n       }\n       else {\n           *cc = 0.0;\n           *gc = 0.0;\n           *pm=0.0;\n       }\n   }\n\n\n\n\n\n   /*----------------------------------------------------------------*\n    *  Packet loss concealment routine. Conceals a residual signal\n    *  and LP parameters. If no packet loss, update state.\n    *---------------------------------------------------------------*/\n\n   void doThePLC(\n       float *PLCresidual, /* (o) concealed residual */\n       float *PLClpc,      /* (o) concealed LP parameters */\n       int PLI,        /* (i) packet loss indicator\n                                  0 - no PL, 1 = PL */\n       float *decresidual, /* (i) decoded residual */\n       float *lpc,         /* (i) decoded LPC (only used for no PL) */\n       int inlag,          /* (i) pitch lag */\n       iLBC_Dec_Inst_t *iLBCdec_inst\n                           /* (i/o) decoder instance */\n   ){\n       int lag=20, randlag;\n       float gain, maxcc;\n       float use_gain;\n       float gain_comp, maxcc_comp, per, max_per=0;\n       int i, pick, use_lag;\n       float ftmp, randvec[BLOCKL_MAX], pitchfact, energy;\n\n       /* Packet Loss */\n\n       if (PLI == 1) {\n\n           iLBCdec_inst->consPLICount += 1;\n\n           /* if previous frame not lost,\n              determine pitch pred. gain */\n\n           if (iLBCdec_inst->prevPLI != 1) {\n\n               /* Search around the previous lag to find the\n                  best pitch period */\n\n               lag=inlag-3;\n               compCorr(&maxcc, &gain, &max_per,\n                   iLBCdec_inst->prevResidual,\n                   lag, iLBCdec_inst->blockl, 60);\n               for (i=inlag-2;i<=inlag+3;i++) {\n                   compCorr(&maxcc_comp, &gain_comp, &per,\n                       iLBCdec_inst->prevResidual,\n                       i, iLBCdec_inst->blockl, 60);\n\n                   if (maxcc_comp>maxcc) {\n                       maxcc=maxcc_comp;\n\n\n\n\n\n                       gain=gain_comp;\n                       lag=i;\n                       max_per=per;\n                   }\n               }\n\n           }\n\n           /* previous frame lost, use recorded lag and periodicity */\n\n           else {\n               lag=iLBCdec_inst->prevLag;\n               max_per=iLBCdec_inst->per;\n           }\n\n           /* downscaling */\n\n           use_gain=1.0;\n           if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>320)\n               use_gain=(float)0.9;\n           else if (iLBCdec_inst->consPLICount*\n                           iLBCdec_inst->blockl>2*320)\n               use_gain=(float)0.7;\n           else if (iLBCdec_inst->consPLICount*\n                           iLBCdec_inst->blockl>3*320)\n               use_gain=(float)0.5;\n           else if (iLBCdec_inst->consPLICount*\n                           iLBCdec_inst->blockl>4*320)\n               use_gain=(float)0.0;\n\n           /* mix noise and pitch repeatition */\n           ftmp=(float)sqrt(max_per);\n           if (ftmp>(float)0.7)\n               pitchfact=(float)1.0;\n           else if (ftmp>(float)0.4)\n               pitchfact=(ftmp-(float)0.4)/((float)0.7-(float)0.4);\n           else\n               pitchfact=0.0;\n\n\n           /* avoid repetition of same pitch cycle */\n           use_lag=lag;\n           if (lag<80) {\n               use_lag=2*lag;\n           }\n\n           /* compute concealed residual */\n\n\n\n\n\n\n           energy = 0.0;\n           for (i=0; i<iLBCdec_inst->blockl; i++) {\n\n               /* noise component */\n\n               iLBCdec_inst->seed=(iLBCdec_inst->seed*69069L+1) &\n                   (0x80000000L-1);\n               randlag = 50 + ((signed long) iLBCdec_inst->seed)%70;\n               pick = i - randlag;\n\n               if (pick < 0) {\n                   randvec[i] =\n                       iLBCdec_inst->prevResidual[\n                                   iLBCdec_inst->blockl+pick];\n               } else {\n                   randvec[i] =  randvec[pick];\n               }\n\n               /* pitch repeatition component */\n               pick = i - use_lag;\n\n               if (pick < 0) {\n                   PLCresidual[i] =\n                       iLBCdec_inst->prevResidual[\n                                   iLBCdec_inst->blockl+pick];\n               } else {\n                   PLCresidual[i] = PLCresidual[pick];\n               }\n\n               /* mix random and periodicity component */\n\n               if (i<80)\n                   PLCresidual[i] = use_gain*(pitchfact *\n                               PLCresidual[i] +\n                               ((float)1.0 - pitchfact) * randvec[i]);\n               else if (i<160)\n                   PLCresidual[i] = (float)0.95*use_gain*(pitchfact *\n                               PLCresidual[i] +\n                               ((float)1.0 - pitchfact) * randvec[i]);\n               else\n                   PLCresidual[i] = (float)0.9*use_gain*(pitchfact *\n                               PLCresidual[i] +\n                               ((float)1.0 - pitchfact) * randvec[i]);\n\n               energy += PLCresidual[i] * PLCresidual[i];\n           }\n\n           /* less than 30 dB, use only noise */\n\n\n\n\n\n\n           if (sqrt(energy/(float)iLBCdec_inst->blockl) < 30.0) {\n               gain=0.0;\n               for (i=0; i<iLBCdec_inst->blockl; i++) {\n                   PLCresidual[i] = randvec[i];\n               }\n           }\n\n           /* use old LPC */\n\n           memcpy(PLClpc,iLBCdec_inst->prevLpc,\n               (LPC_FILTERORDER+1)*sizeof(float));\n\n       }\n\n       /* no packet loss, copy input */\n\n       else {\n           memcpy(PLCresidual, decresidual,\n               iLBCdec_inst->blockl*sizeof(float));\n           memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float));\n           iLBCdec_inst->consPLICount = 0;\n       }\n\n       /* update state */\n\n       if (PLI) {\n           iLBCdec_inst->prevLag = lag;\n           iLBCdec_inst->per=max_per;\n       }\n\n       iLBCdec_inst->prevPLI = PLI;\n       memcpy(iLBCdec_inst->prevLpc, PLClpc,\n           (LPC_FILTERORDER+1)*sizeof(float));\n       memcpy(iLBCdec_inst->prevResidual, PLCresidual,\n           iLBCdec_inst->blockl*sizeof(float));\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/doCPLC.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       doCPLC.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_DOLPC_H\n   #define __iLBC_DOLPC_H\n\n   void doThePLC(\n       float *PLCresidual, /* (o) concealed residual */\n       float *PLClpc,      /* (o) concealed LP parameters */\n       int PLI,        /* (i) packet loss indicator\n                                  0 - no PL, 1 = PL */\n       float *decresidual, /* (i) decoded residual */\n       float *lpc,         /* (i) decoded LPC (only used for no PL) */\n       int inlag,          /* (i) pitch lag */\n       iLBC_Dec_Inst_t *iLBCdec_inst\n                           /* (i/o) decoder instance */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/enhancer.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       enhancer.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <math.h>\n   #include <string.h>\n   #include \"iLBC_define.h\"\n   #include \"constants.h\"\n   #include \"filter.h\"\n\n   /*----------------------------------------------------------------*\n    * Find index in array such that the array element with said\n    * index is the element of said array closest to \"value\"\n    * according to the squared-error criterion\n    *---------------------------------------------------------------*/\n\n   void NearestNeighbor(\n\n\n\n\n\n       int   *index,   /* (o) index of array element closest\n                              to value */\n       float *array,   /* (i) data array */\n       float value,/* (i) value */\n       int arlength/* (i) dimension of data array */\n   ){\n       int i;\n       float bestcrit,crit;\n\n       crit=array[0]-value;\n       bestcrit=crit*crit;\n       *index=0;\n       for (i=1; i<arlength; i++) {\n           crit=array[i]-value;\n           crit=crit*crit;\n\n           if (crit<bestcrit) {\n               bestcrit=crit;\n               *index=i;\n           }\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    * compute cross correlation between sequences\n    *---------------------------------------------------------------*/\n\n   void mycorr1(\n       float* corr,    /* (o) correlation of seq1 and seq2 */\n       float* seq1,    /* (i) first sequence */\n       int dim1,           /* (i) dimension first seq1 */\n       const float *seq2,  /* (i) second sequence */\n       int dim2        /* (i) dimension seq2 */\n   ){\n       int i,j;\n\n       for (i=0; i<=dim1-dim2; i++) {\n           corr[i]=0.0;\n           for (j=0; j<dim2; j++) {\n               corr[i] += seq1[i+j] * seq2[j];\n           }\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    * upsample finite array assuming zeros outside bounds\n    *---------------------------------------------------------------*/\n\n\n\n\n\n\n   void enh_upsample(\n       float* useq1,   /* (o) upsampled output sequence */\n       float* seq1,/* (i) unupsampled sequence */\n       int dim1,       /* (i) dimension seq1 */\n       int hfl         /* (i) polyphase filter length=2*hfl+1 */\n   ){\n       float *pu,*ps;\n       int i,j,k,q,filterlength,hfl2;\n       const float *polyp[ENH_UPS0]; /* pointers to\n                                        polyphase columns */\n       const float *pp;\n\n       /* define pointers for filter */\n\n       filterlength=2*hfl+1;\n\n       if ( filterlength > dim1 ) {\n           hfl2=(int) (dim1/2);\n           for (j=0; j<ENH_UPS0; j++) {\n               polyp[j]=polyphaserTbl+j*filterlength+hfl-hfl2;\n           }\n           hfl=hfl2;\n           filterlength=2*hfl+1;\n       }\n       else {\n           for (j=0; j<ENH_UPS0; j++) {\n               polyp[j]=polyphaserTbl+j*filterlength;\n           }\n       }\n\n       /* filtering: filter overhangs left side of sequence */\n\n       pu=useq1;\n       for (i=hfl; i<filterlength; i++) {\n           for (j=0; j<ENH_UPS0; j++) {\n               *pu=0.0;\n               pp = polyp[j];\n               ps = seq1+i;\n               for (k=0; k<=i; k++) {\n                   *pu += *ps-- * *pp++;\n               }\n               pu++;\n           }\n       }\n\n       /* filtering: simple convolution=inner products */\n\n       for (i=filterlength; i<dim1; i++) {\n\n\n\n\n\n           for (j=0;j<ENH_UPS0; j++){\n               *pu=0.0;\n               pp = polyp[j];\n               ps = seq1+i;\n               for (k=0; k<filterlength; k++) {\n                   *pu += *ps-- * *pp++;\n               }\n               pu++;\n           }\n       }\n\n       /* filtering: filter overhangs right side of sequence */\n\n       for (q=1; q<=hfl; q++) {\n           for (j=0; j<ENH_UPS0; j++) {\n               *pu=0.0;\n               pp = polyp[j]+q;\n               ps = seq1+dim1-1;\n               for (k=0; k<filterlength-q; k++) {\n                   *pu += *ps-- * *pp++;\n               }\n               pu++;\n           }\n       }\n   }\n\n\n   /*----------------------------------------------------------------*\n    * find segment starting near idata+estSegPos that has highest\n    * correlation with idata+centerStartPos through\n    * idata+centerStartPos+ENH_BLOCKL-1 segment is found at a\n    * resolution of ENH_UPSO times the original of the original\n    * sampling rate\n    *---------------------------------------------------------------*/\n\n   void refiner(\n       float *seg,         /* (o) segment array */\n       float *updStartPos, /* (o) updated start point */\n       float* idata,       /* (i) original data buffer */\n       int idatal,         /* (i) dimension of idata */\n       int centerStartPos, /* (i) beginning center segment */\n       float estSegPos,/* (i) estimated beginning other segment */\n       float period    /* (i) estimated pitch period */\n   ){\n       int estSegPosRounded,searchSegStartPos,searchSegEndPos,corrdim;\n       int tloc,tloc2,i,st,en,fraction;\n       float vect[ENH_VECTL],corrVec[ENH_CORRDIM],maxv;\n       float corrVecUps[ENH_CORRDIM*ENH_UPS0];\n\n       (void)period;\n\n\n\n       /* defining array bounds */\n\n       estSegPosRounded=(int)(estSegPos - 0.5);\n\n       searchSegStartPos=estSegPosRounded-ENH_SLOP;\n\n       if (searchSegStartPos<0) {\n           searchSegStartPos=0;\n       }\n       searchSegEndPos=estSegPosRounded+ENH_SLOP;\n\n       if (searchSegEndPos+ENH_BLOCKL >= idatal) {\n           searchSegEndPos=idatal-ENH_BLOCKL-1;\n       }\n       corrdim=searchSegEndPos-searchSegStartPos+1;\n\n       /* compute upsampled correlation (corr33) and find\n          location of max */\n\n       mycorr1(corrVec,idata+searchSegStartPos,\n           corrdim+ENH_BLOCKL-1,idata+centerStartPos,ENH_BLOCKL);\n       enh_upsample(corrVecUps,corrVec,corrdim,ENH_FL0);\n       tloc=0; maxv=corrVecUps[0];\n       for (i=1; i<ENH_UPS0*corrdim; i++) {\n\n           if (corrVecUps[i]>maxv) {\n               tloc=i;\n               maxv=corrVecUps[i];\n           }\n       }\n\n       /* make vector can be upsampled without ever running outside\n          bounds */\n\n       *updStartPos= (float)searchSegStartPos +\n           (float)tloc/(float)ENH_UPS0+(float)1.0;\n       tloc2=(int)(tloc/ENH_UPS0);\n\n       if (tloc>tloc2*ENH_UPS0) {\n           tloc2++;\n       }\n       st=searchSegStartPos+tloc2-ENH_FL0;\n\n       if (st<0) {\n           memset(vect,0,-st*sizeof(float));\n           memcpy(&vect[-st],idata, (ENH_VECTL+st)*sizeof(float));\n       }\n       else {\n\n\n\n\n\n           en=st+ENH_VECTL;\n\n           if (en>idatal) {\n               memcpy(vect, &idata[st],\n                   (ENH_VECTL-(en-idatal))*sizeof(float));\n               memset(&vect[ENH_VECTL-(en-idatal)], 0,\n                   (en-idatal)*sizeof(float));\n           }\n           else {\n               memcpy(vect, &idata[st], ENH_VECTL*sizeof(float));\n           }\n       }\n       fraction=tloc2*ENH_UPS0-tloc;\n\n       /* compute the segment (this is actually a convolution) */\n\n       mycorr1(seg,vect,ENH_VECTL,polyphaserTbl+(2*ENH_FL0+1)*fraction,\n           2*ENH_FL0+1);\n   }\n\n   /*----------------------------------------------------------------*\n    * find the smoothed output data\n    *---------------------------------------------------------------*/\n\n   void smath(\n       float *odata,   /* (o) smoothed output */\n       float *sseq,/* (i) said second sequence of waveforms */\n       int hl,         /* (i) 2*hl+1 is sseq dimension */\n       float alpha0/* (i) max smoothing energy fraction */\n   ){\n       int i,k;\n       float w00,w10,w11,A,B,C,*psseq,err,errs;\n       float surround[BLOCKL_MAX]; /* shape contributed by other than\n                                      current */\n       float wt[2*ENH_HL+1];       /* waveform weighting to get\n                                      surround shape */\n       float denom;\n\n       /* create shape of contribution from all waveforms except the\n          current one */\n\n       for (i=1; i<=2*hl+1; i++) {\n           wt[i-1] = (float)0.5*(1 - (float)cos(2*PI*i/(2*hl+2)));\n       }\n       wt[hl]=0.0; /* for clarity, not used */\n       for (i=0; i<ENH_BLOCKL; i++) {\n           surround[i]=sseq[i]*wt[0];\n       }\n\n\n\n\n\n       for (k=1; k<hl; k++) {\n           psseq=sseq+k*ENH_BLOCKL;\n           for(i=0;i<ENH_BLOCKL; i++) {\n               surround[i]+=psseq[i]*wt[k];\n           }\n       }\n       for (k=hl+1; k<=2*hl; k++) {\n           psseq=sseq+k*ENH_BLOCKL;\n           for(i=0;i<ENH_BLOCKL; i++) {\n               surround[i]+=psseq[i]*wt[k];\n           }\n       }\n\n       /* compute some inner products */\n\n       w00 = w10 = w11 = 0.0;\n       psseq=sseq+hl*ENH_BLOCKL; /* current block  */\n       for (i=0; i<ENH_BLOCKL;i++) {\n           w00+=psseq[i]*psseq[i];\n           w11+=surround[i]*surround[i];\n           w10+=surround[i]*psseq[i];\n       }\n\n       if (fabs(w11) < 1.0) {\n           w11=1.0;\n       }\n       C = (float)sqrt( w00/w11);\n\n       /* first try enhancement without power-constraint */\n\n       errs=0.0;\n       psseq=sseq+hl*ENH_BLOCKL;\n       for (i=0; i<ENH_BLOCKL; i++) {\n           odata[i]=C*surround[i];\n           err=psseq[i]-odata[i];\n           errs+=err*err;\n       }\n\n       /* if constraint violated by first try, add constraint */\n\n       if (errs > alpha0 * w00) {\n           if ( w00 < 1) {\n               w00=1;\n           }\n           denom = (w11*w00-w10*w10)/(w00*w00);\n\n           if (denom > 0.0001) { /* eliminates numerical problems\n                                    for if smooth */\n\n\n\n\n\n               A = (float)sqrt( (alpha0- alpha0*alpha0/4)/denom);\n               B = -alpha0/2 - A * w10/w00;\n               B = B+1;\n           }\n           else { /* essentially no difference between cycles;\n                     smoothing not needed */\n               A= 0.0;\n               B= 1.0;\n           }\n\n           /* create smoothed sequence */\n\n           psseq=sseq+hl*ENH_BLOCKL;\n           for (i=0; i<ENH_BLOCKL; i++) {\n               odata[i]=A*surround[i]+B*psseq[i];\n           }\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    * get the pitch-synchronous sample sequence\n    *---------------------------------------------------------------*/\n\n   void getsseq(\n       float *sseq,    /* (o) the pitch-synchronous sequence */\n       float *idata,       /* (i) original data */\n       int idatal,         /* (i) dimension of data */\n       int centerStartPos, /* (i) where current block starts */\n       float *period,      /* (i) rough-pitch-period array */\n       float *plocs,       /* (i) where periods of period array\n                                  are taken */\n       int periodl,    /* (i) dimension period array */\n       int hl              /* (i) 2*hl+1 is the number of sequences */\n   ){\n       int i,centerEndPos,q;\n       float blockStartPos[2*ENH_HL+1];\n       int lagBlock[2*ENH_HL+1];\n       float plocs2[ENH_PLOCSL];\n       float *psseq;\n\n       centerEndPos=centerStartPos+ENH_BLOCKL-1;\n\n       /* present */\n\n       NearestNeighbor(lagBlock+hl,plocs,\n           (float)0.5*(centerStartPos+centerEndPos),periodl);\n\n       blockStartPos[hl]=(float)centerStartPos;\n\n\n\n\n\n       psseq=sseq+ENH_BLOCKL*hl;\n       memcpy(psseq, idata+centerStartPos, ENH_BLOCKL*sizeof(float));\n\n       /* past */\n\n       for (q=hl-1; q>=0; q--) {\n           blockStartPos[q]=blockStartPos[q+1]-period[lagBlock[q+1]];\n           NearestNeighbor(lagBlock+q,plocs,\n               blockStartPos[q]+\n               ENH_BLOCKL_HALF-period[lagBlock[q+1]], periodl);\n\n\n           if (blockStartPos[q]-ENH_OVERHANG>=0) {\n               refiner(sseq+q*ENH_BLOCKL, blockStartPos+q, idata,\n                   idatal, centerStartPos, blockStartPos[q],\n                   period[lagBlock[q+1]]);\n           } else {\n               psseq=sseq+q*ENH_BLOCKL;\n               memset(psseq, 0, ENH_BLOCKL*sizeof(float));\n           }\n       }\n\n       /* future */\n\n       for (i=0; i<periodl; i++) {\n           plocs2[i]=plocs[i]-period[i];\n       }\n       for (q=hl+1; q<=2*hl; q++) {\n           NearestNeighbor(lagBlock+q,plocs2,\n               blockStartPos[q-1]+ENH_BLOCKL_HALF,periodl);\n\n           blockStartPos[q]=blockStartPos[q-1]+period[lagBlock[q]];\n           if (blockStartPos[q]+ENH_BLOCKL+ENH_OVERHANG<idatal) {\n               refiner(sseq+ENH_BLOCKL*q, blockStartPos+q, idata,\n                   idatal, centerStartPos, blockStartPos[q],\n                   period[lagBlock[q]]);\n           }\n           else {\n               psseq=sseq+q*ENH_BLOCKL;\n               memset(psseq, 0, ENH_BLOCKL*sizeof(float));\n           }\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    * perform enhancement on idata+centerStartPos through\n    * idata+centerStartPos+ENH_BLOCKL-1\n    *---------------------------------------------------------------*/\n\n\n\n\n\n   void enhancer(\n       float *odata,       /* (o) smoothed block, dimension blockl */\n       float *idata,       /* (i) data buffer used for enhancing */\n       int idatal,         /* (i) dimension idata */\n       int centerStartPos, /* (i) first sample current block\n                                  within idata */\n       float alpha0,       /* (i) max correction-energy-fraction\n                                 (in [0,1]) */\n       float *period,      /* (i) pitch period array */\n       float *plocs,       /* (i) locations where period array\n                                  values valid */\n       int periodl         /* (i) dimension of period and plocs */\n   ){\n       float sseq[(2*ENH_HL+1)*ENH_BLOCKL];\n\n       /* get said second sequence of segments */\n\n       getsseq(sseq,idata,idatal,centerStartPos,period,\n           plocs,periodl,ENH_HL);\n\n       /* compute the smoothed output from said second sequence */\n\n       smath(odata,sseq,ENH_HL,alpha0);\n\n   }\n\n   /*----------------------------------------------------------------*\n    * cross correlation\n    *---------------------------------------------------------------*/\n\n   float xCorrCoef(\n       float *target,      /* (i) first array */\n       float *regressor,   /* (i) second array */\n       int subl        /* (i) dimension arrays */\n   ){\n       int i;\n       float ftmp1, ftmp2;\n\n       ftmp1 = 0.0;\n       ftmp2 = 0.0;\n       for (i=0; i<subl; i++) {\n           ftmp1 += target[i]*regressor[i];\n           ftmp2 += regressor[i]*regressor[i];\n       }\n\n       if (ftmp1 > 0.0) {\n           return (float)(ftmp1*ftmp1/ftmp2);\n       }\n\n\n\n\n\n       else {\n           return (float)0.0;\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    * interface for enhancer\n    *---------------------------------------------------------------*/\n\n   int enhancerInterface(\n       float *out,                     /* (o) enhanced signal */\n       float *in,                      /* (i) unenhanced signal */\n       iLBC_Dec_Inst_t *iLBCdec_inst   /* (i) buffers etc */\n   ){\n       float *enh_buf, *enh_period;\n       int iblock, isample;\n       int lag=0, ilag, i, ioffset;\n       float cc, maxcc;\n       float ftmp1, ftmp2;\n       float *inPtr, *enh_bufPtr1, *enh_bufPtr2;\n       float plc_pred[ENH_BLOCKL];\n\n       float lpState[6], downsampled[(ENH_NBLOCKS*ENH_BLOCKL+120)/2];\n       int inLen=ENH_NBLOCKS*ENH_BLOCKL+120;\n       int start, plc_blockl, inlag;\n\n       enh_buf=iLBCdec_inst->enh_buf;\n       enh_period=iLBCdec_inst->enh_period;\n\n       memmove(enh_buf, &enh_buf[iLBCdec_inst->blockl],\n           (ENH_BUFL-iLBCdec_inst->blockl)*sizeof(float));\n\n       memcpy(&enh_buf[ENH_BUFL-iLBCdec_inst->blockl], in,\n           iLBCdec_inst->blockl*sizeof(float));\n\n       if (iLBCdec_inst->mode==30)\n           plc_blockl=ENH_BLOCKL;\n       else\n           plc_blockl=40;\n\n       /* when 20 ms frame, move processing one block */\n       ioffset=0;\n       if (iLBCdec_inst->mode==20) ioffset=1;\n\n       i=3-ioffset;\n       memmove(enh_period, &enh_period[i],\n           (ENH_NBLOCKS_TOT-i)*sizeof(float));\n\n\n\n\n\n\n       /* Set state information to the 6 samples right before\n          the samples to be downsampled. */\n\n       memcpy(lpState,\n           enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-126,\n           6*sizeof(float));\n\n       /* Down sample a factor 2 to save computations */\n\n       DownSample(enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-120,\n                   lpFilt_coefsTbl, inLen-ioffset*ENH_BLOCKL,\n                   lpState, downsampled);\n\n       /* Estimate the pitch in the down sampled domain. */\n       for (iblock = 0; iblock<ENH_NBLOCKS-ioffset; iblock++) {\n\n           lag = 10;\n           maxcc = xCorrCoef(downsampled+60+iblock*\n               ENH_BLOCKL_HALF, downsampled+60+iblock*\n               ENH_BLOCKL_HALF-lag, ENH_BLOCKL_HALF);\n           for (ilag=11; ilag<60; ilag++) {\n               cc = xCorrCoef(downsampled+60+iblock*\n                   ENH_BLOCKL_HALF, downsampled+60+iblock*\n                   ENH_BLOCKL_HALF-ilag, ENH_BLOCKL_HALF);\n\n               if (cc > maxcc) {\n                   maxcc = cc;\n                   lag = ilag;\n               }\n           }\n\n           /* Store the estimated lag in the non-downsampled domain */\n           enh_period[iblock+ENH_NBLOCKS_EXTRA+ioffset] = (float)lag*2;\n\n\n       }\n\n\n       /* PLC was performed on the previous packet */\n       if (iLBCdec_inst->prev_enh_pl==1) {\n\n           inlag=(int)enh_period[ENH_NBLOCKS_EXTRA+ioffset];\n\n           lag = inlag-1;\n           maxcc = xCorrCoef(in, in+lag, plc_blockl);\n           for (ilag=inlag; ilag<=inlag+1; ilag++) {\n               cc = xCorrCoef(in, in+ilag, plc_blockl);\n\n\n\n\n\n\n               if (cc > maxcc) {\n                   maxcc = cc;\n                   lag = ilag;\n               }\n           }\n\n           enh_period[ENH_NBLOCKS_EXTRA+ioffset-1]=(float)lag;\n\n           /* compute new concealed residual for the old lookahead,\n              mix the forward PLC with a backward PLC from\n              the new frame */\n\n           inPtr=&in[lag-1];\n\n           enh_bufPtr1=&plc_pred[plc_blockl-1];\n\n           if (lag>plc_blockl) {\n               start=plc_blockl;\n           } else {\n               start=lag;\n           }\n\n           for (isample = start; isample>0; isample--) {\n               *enh_bufPtr1-- = *inPtr--;\n           }\n\n           enh_bufPtr2=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl];\n           for (isample = (plc_blockl-1-lag); isample>=0; isample--) {\n               *enh_bufPtr1-- = *enh_bufPtr2--;\n           }\n\n           /* limit energy change */\n           ftmp2=0.0;\n           ftmp1=0.0;\n           for (i=0;i<plc_blockl;i++) {\n               ftmp2+=enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl-i]*\n                   enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl-i];\n               ftmp1+=plc_pred[i]*plc_pred[i];\n           }\n           ftmp1=(float)sqrt(ftmp1/(float)plc_blockl);\n           ftmp2=(float)sqrt(ftmp2/(float)plc_blockl);\n           if (ftmp1>(float)2.0*ftmp2 && ftmp1>0.0) {\n               for (i=0;i<plc_blockl-10;i++) {\n                   plc_pred[i]*=(float)2.0*ftmp2/ftmp1;\n               }\n               for (i=plc_blockl-10;i<plc_blockl;i++) {\n                   plc_pred[i]*=(float)(i-plc_blockl+10)*\n                       ((float)1.0-(float)2.0*ftmp2/ftmp1)/(float)(10)+\n\n\n\n\n\n                       (float)2.0*ftmp2/ftmp1;\n               }\n           }\n\n           enh_bufPtr1=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl];\n           for (i=0; i<plc_blockl; i++) {\n               ftmp1 = (float) (i+1) / (float) (plc_blockl+1);\n               *enh_bufPtr1 *= ftmp1;\n               *enh_bufPtr1 += ((float)1.0-ftmp1)*\n                                   plc_pred[plc_blockl-1-i];\n               enh_bufPtr1--;\n           }\n       }\n\n       if (iLBCdec_inst->mode==20) {\n           /* Enhancer with 40 samples delay */\n           for (iblock = 0; iblock<2; iblock++) {\n               enhancer(out+iblock*ENH_BLOCKL, enh_buf,\n                   ENH_BUFL, (5+iblock)*ENH_BLOCKL+40,\n                   ENH_ALPHA0, enh_period, enh_plocsTbl,\n                       ENH_NBLOCKS_TOT);\n           }\n       } else if (iLBCdec_inst->mode==30) {\n           /* Enhancer with 80 samples delay */\n           for (iblock = 0; iblock<3; iblock++) {\n               enhancer(out+iblock*ENH_BLOCKL, enh_buf,\n                   ENH_BUFL, (4+iblock)*ENH_BLOCKL,\n                   ENH_ALPHA0, enh_period, enh_plocsTbl,\n                       ENH_NBLOCKS_TOT);\n           }\n       }\n\n       return (lag*2);\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/enhancer.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       enhancer.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n\n\n\n\n   ******************************************************************/\n\n   #ifndef __ENHANCER_H\n   #define __ENHANCER_H\n\n   #include \"iLBC_define.h\"\n\n   float xCorrCoef(\n       float *target,      /* (i) first array */\n       float *regressor,   /* (i) second array */\n       int subl        /* (i) dimension arrays */\n   );\n\n   int enhancerInterface(\n       float *out,         /* (o) the enhanced recidual signal */\n       float *in,          /* (i) the recidual signal to enhance */\n       iLBC_Dec_Inst_t *iLBCdec_inst\n                           /* (i/o) the decoder state structure */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/filter.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       filter.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include \"iLBC_define.h\"\n\n   /*----------------------------------------------------------------*\n    *  all-pole filter\n    *---------------------------------------------------------------*/\n\n   void AllPoleFilter(\n       float *InOut,   /* (i/o) on entrance InOut[-orderCoef] to\n                              InOut[-1] contain the state of the\n                              filter (delayed samples). InOut[0] to\n                              InOut[lengthInOut-1] contain the filter\n                              input, on en exit InOut[-orderCoef] to\n                              InOut[-1] is unchanged and InOut[0] to\n                              InOut[lengthInOut-1] contain filtered\n                              samples */\n       float *Coef,/* (i) filter coefficients, Coef[0] is assumed\n                              to be 1.0 */\n       int lengthInOut,/* (i) number of input/output samples */\n       int orderCoef   /* (i) number of filter coefficients */\n   ){\n       int n,k;\n\n       for(n=0;n<lengthInOut;n++){\n           for(k=1;k<=orderCoef;k++){\n               *InOut -= Coef[k]*InOut[-k];\n\n\n\n\n\n           }\n           InOut++;\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  all-zero filter\n    *---------------------------------------------------------------*/\n\n   void AllZeroFilter(\n       float *In,      /* (i) In[0] to In[lengthInOut-1] contain\n                              filter input samples */\n       float *Coef,/* (i) filter coefficients (Coef[0] is assumed\n                              to be 1.0) */\n       int lengthInOut,/* (i) number of input/output samples */\n       int orderCoef,  /* (i) number of filter coefficients */\n       float *Out      /* (i/o) on entrance Out[-orderCoef] to Out[-1]\n                              contain the filter state, on exit Out[0]\n                              to Out[lengthInOut-1] contain filtered\n                              samples */\n   ){\n       int n,k;\n\n       for(n=0;n<lengthInOut;n++){\n           *Out = Coef[0]*In[0];\n           for(k=1;k<=orderCoef;k++){\n               *Out += Coef[k]*In[-k];\n           }\n           Out++;\n           In++;\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  pole-zero filter\n    *---------------------------------------------------------------*/\n\n   void ZeroPoleFilter(\n       float *In,      /* (i) In[0] to In[lengthInOut-1] contain\n                              filter input samples In[-orderCoef] to\n                              In[-1] contain state of all-zero\n                              section */\n       float *ZeroCoef,/* (i) filter coefficients for all-zero\n                              section (ZeroCoef[0] is assumed to\n                              be 1.0) */\n       float *PoleCoef,/* (i) filter coefficients for all-pole section\n                              (ZeroCoef[0] is assumed to be 1.0) */\n       int lengthInOut,/* (i) number of input/output samples */\n\n\n\n\n\n       int orderCoef,  /* (i) number of filter coefficients */\n       float *Out      /* (i/o) on entrance Out[-orderCoef] to Out[-1]\n                              contain state of all-pole section. On\n                              exit Out[0] to Out[lengthInOut-1]\n                              contain filtered samples */\n   ){\n       AllZeroFilter(In,ZeroCoef,lengthInOut,orderCoef,Out);\n       AllPoleFilter(Out,PoleCoef,lengthInOut,orderCoef);\n   }\n\n   /*----------------------------------------------------------------*\n    * downsample (LP filter and decimation)\n    *---------------------------------------------------------------*/\n\n   void DownSample (\n       float  *In,     /* (i) input samples */\n       float  *Coef,   /* (i) filter coefficients */\n       int lengthIn,   /* (i) number of input samples */\n       float  *state,  /* (i) filter state */\n       float  *Out     /* (o) downsampled output */\n   ){\n       float   o;\n       float *Out_ptr = Out;\n       float *Coef_ptr, *In_ptr;\n       float *state_ptr;\n       int i, j, stop;\n\n       /* LP filter and decimate at the same time */\n\n       for (i = DELAY_DS; i < lengthIn; i+=FACTOR_DS)\n       {\n           Coef_ptr = &Coef[0];\n           In_ptr = &In[i];\n           state_ptr = &state[FILTERORDER_DS-2];\n\n           o = (float)0.0;\n\n           stop = (i < FILTERORDER_DS) ? i + 1 : FILTERORDER_DS;\n\n           for (j = 0; j < stop; j++)\n           {\n               o += *Coef_ptr++ * (*In_ptr--);\n           }\n           for (j = i + 1; j < FILTERORDER_DS; j++)\n           {\n               o += *Coef_ptr++ * (*state_ptr--);\n           }\n\n\n\n\n\n\n           *Out_ptr++ = o;\n       }\n\n       /* Get the last part (use zeros as input for the future) */\n\n       for (i=(lengthIn+FACTOR_DS); i<(lengthIn+DELAY_DS);\n               i+=FACTOR_DS) {\n\n           o=(float)0.0;\n\n           if (i<lengthIn) {\n               Coef_ptr = &Coef[0];\n               In_ptr = &In[i];\n               for (j=0; j<FILTERORDER_DS; j++) {\n                       o += *Coef_ptr++ * (*Out_ptr--);\n               }\n           } else {\n               Coef_ptr = &Coef[i-lengthIn];\n               In_ptr = &In[lengthIn-1];\n               for (j=0; j<FILTERORDER_DS-(i-lengthIn); j++) {\n                       o += *Coef_ptr++ * (*In_ptr--);\n               }\n           }\n           *Out_ptr++ = o;\n       }\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/filter.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       filter.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n\n\n\n\n\n   #ifndef __iLBC_FILTER_H\n   #define __iLBC_FILTER_H\n\n   void AllPoleFilter(\n       float *InOut,   /* (i/o) on entrance InOut[-orderCoef] to\n                              InOut[-1] contain the state of the\n                              filter (delayed samples). InOut[0] to\n                              InOut[lengthInOut-1] contain the filter\n                              input, on en exit InOut[-orderCoef] to\n                              InOut[-1] is unchanged and InOut[0] to\n                              InOut[lengthInOut-1] contain filtered\n                              samples */\n       float *Coef,/* (i) filter coefficients, Coef[0] is assumed\n                              to be 1.0 */\n       int lengthInOut,/* (i) number of input/output samples */\n       int orderCoef   /* (i) number of filter coefficients */\n   );\n\n   void AllZeroFilter(\n       float *In,      /* (i) In[0] to In[lengthInOut-1] contain\n                              filter input samples */\n       float *Coef,/* (i) filter coefficients (Coef[0] is assumed\n                              to be 1.0) */\n       int lengthInOut,/* (i) number of input/output samples */\n       int orderCoef,  /* (i) number of filter coefficients */\n       float *Out      /* (i/o) on entrance Out[-orderCoef] to Out[-1]\n                              contain the filter state, on exit Out[0]\n                              to Out[lengthInOut-1] contain filtered\n                              samples */\n   );\n\n   void ZeroPoleFilter(\n       float *In,      /* (i) In[0] to In[lengthInOut-1] contain filter\n                              input samples In[-orderCoef] to In[-1]\n                              contain state of all-zero section */\n       float *ZeroCoef,/* (i) filter coefficients for all-zero\n                              section (ZeroCoef[0] is assumed to\n                              be 1.0) */\n       float *PoleCoef,/* (i) filter coefficients for all-pole section\n                              (ZeroCoef[0] is assumed to be 1.0) */\n       int lengthInOut,/* (i) number of input/output samples */\n       int orderCoef,  /* (i) number of filter coefficients */\n       float *Out      /* (i/o) on entrance Out[-orderCoef] to Out[-1]\n                              contain state of all-pole section. On\n                              exit Out[0] to Out[lengthInOut-1]\n                              contain filtered samples */\n   );\n\n\n\n\n\n\n   void DownSample (\n       float  *In,     /* (i) input samples */\n       float  *Coef,   /* (i) filter coefficients */\n       int lengthIn,   /* (i) number of input samples */\n       float  *state,  /* (i) filter state */\n       float  *Out     /* (o) downsampled output */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/gainquant.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n\n\n\n\n\n       gainquant.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <string.h>\n   #include <math.h>\n   #include \"constants.h\"\n   #include \"filter.h\"\n\n   /*----------------------------------------------------------------*\n    *  quantizer for the gain in the gain-shape coding of residual\n    *---------------------------------------------------------------*/\n\n   float gainquant(/* (o) quantized gain value */\n       float in,       /* (i) gain value */\n       float maxIn,/* (i) maximum of gain value */\n       int cblen,      /* (i) number of quantization indices */\n       int *index      /* (o) quantization index */\n   ){\n       int i, tindex;\n       float minmeasure,measure, *cb, scale;\n\n       /* ensure a lower bound on the scaling factor */\n\n       scale=maxIn;\n\n       if (scale<0.1) {\n           scale=(float)0.1;\n       }\n\n       /* select the quantization table */\n\n       if (cblen == 8) {\n           cb = gain_sq3Tbl;\n       } else if (cblen == 16) {\n           cb = gain_sq4Tbl;\n       } else  {\n           cb = gain_sq5Tbl;\n       }\n\n       /* select the best index in the quantization table */\n\n       minmeasure=10000000.0;\n       tindex=0;\n       for (i=0; i<cblen; i++) {\n\n\n\n\n\n           measure=(in-scale*cb[i])*(in-scale*cb[i]);\n\n           if (measure<minmeasure) {\n               tindex=i;\n               minmeasure=measure;\n           }\n       }\n       *index=tindex;\n\n       /* return the quantized value */\n\n       return scale*cb[tindex];\n   }\n\n   /*----------------------------------------------------------------*\n    *  decoder for quantized gains in the gain-shape coding of\n    *  residual\n    *---------------------------------------------------------------*/\n\n   float gaindequant(  /* (o) quantized gain value */\n       int index,      /* (i) quantization index */\n       float maxIn,/* (i) maximum of unquantized gain */\n       int cblen       /* (i) number of quantization indices */\n   ){\n       float scale;\n\n       /* obtain correct scale factor */\n\n       scale=(float)fabs(maxIn);\n\n       if (scale<0.1) {\n           scale=(float)0.1;\n       }\n\n       /* select the quantization table and return the decoded value */\n\n       if (cblen==8) {\n           return scale*gain_sq3Tbl[index];\n       } else if (cblen==16) {\n           return scale*gain_sq4Tbl[index];\n       }\n       else if (cblen==32) {\n           return scale*gain_sq5Tbl[index];\n       }\n\n       return 0.0;\n   }\n\n\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/gainquant.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       gainquant.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_GAINQUANT_H\n   #define __iLBC_GAINQUANT_H\n\n   float gainquant(/* (o) quantized gain value */\n       float in,       /* (i) gain value */\n       float maxIn,/* (i) maximum of gain value */\n       int cblen,      /* (i) number of quantization indices */\n       int *index      /* (o) quantization index */\n   );\n\n   float gaindequant(  /* (o) quantized gain value */\n       int index,      /* (i) quantization index */\n       float maxIn,/* (i) maximum of unquantized gain */\n       int cblen       /* (i) number of quantization indices */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/getCBvec.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       getCBvec.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include \"iLBC_define.h\"\n   #include \"constants.h\"\n   #include <string.h>\n\n   /*----------------------------------------------------------------*\n    *  Construct codebook vector for given index.\n    *---------------------------------------------------------------*/\n\n   void getCBvec(\n\n\n\n\n\n       float *cbvec,   /* (o) Constructed codebook vector */\n       float *mem,     /* (i) Codebook buffer */\n       int index,      /* (i) Codebook index */\n       int lMem,       /* (i) Length of codebook buffer */\n       int cbveclen/* (i) Codebook vector length */\n   ){\n       int j, k, n, memInd, sFilt;\n       float tmpbuf[CB_MEML];\n       int base_size;\n       int ilow, ihigh;\n       float alfa, alfa1;\n\n       /* Determine size of codebook sections */\n\n       base_size=lMem-cbveclen+1;\n\n       if (cbveclen==SUBL) {\n           base_size+=cbveclen/2;\n       }\n\n       /* No filter -> First codebook section */\n\n       if (index<lMem-cbveclen+1) {\n\n           /* first non-interpolated vectors */\n\n           k=index+cbveclen;\n           /* get vector */\n           memcpy(cbvec, mem+lMem-k, cbveclen*sizeof(float));\n\n       } else if (index < base_size) {\n\n           k=2*(index-(lMem-cbveclen+1))+cbveclen;\n\n           ihigh=k/2;\n           ilow=ihigh-5;\n\n           /* Copy first noninterpolated part */\n\n           memcpy(cbvec, mem+lMem-k/2, ilow*sizeof(float));\n\n           /* interpolation */\n\n           alfa1=(float)0.2;\n           alfa=0.0;\n           for (j=ilow; j<ihigh; j++) {\n               cbvec[j]=((float)1.0-alfa)*mem[lMem-k/2+j]+\n                   alfa*mem[lMem-k+j];\n\n\n\n\n\n               alfa+=alfa1;\n           }\n\n           /* Copy second noninterpolated part */\n\n           memcpy(cbvec+ihigh, mem+lMem-k+ihigh,\n               (cbveclen-ihigh)*sizeof(float));\n\n       }\n\n       /* Higher codebook section based on filtering */\n\n       else {\n\n           /* first non-interpolated vectors */\n\n           if (index-base_size<lMem-cbveclen+1) {\n               float tempbuff2[CB_MEML+CB_FILTERLEN+1];\n               float *pos;\n               float *pp, *pp1;\n\n               memset(tempbuff2, 0,\n                   CB_HALFFILTERLEN*sizeof(float));\n               memcpy(&tempbuff2[CB_HALFFILTERLEN], mem,\n                   lMem*sizeof(float));\n               memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0,\n                   (CB_HALFFILTERLEN+1)*sizeof(float));\n\n               k=index-base_size+cbveclen;\n               sFilt=lMem-k;\n               memInd=sFilt+1-CB_HALFFILTERLEN;\n\n               /* do filtering */\n               pos=cbvec;\n               memset(pos, 0, cbveclen*sizeof(float));\n               for (n=0; n<cbveclen; n++) {\n                   pp=&tempbuff2[memInd+n+CB_HALFFILTERLEN];\n                   pp1=&cbfiltersTbl[CB_FILTERLEN-1];\n                   for (j=0; j<CB_FILTERLEN; j++) {\n                       (*pos)+=(*pp++)*(*pp1--);\n                   }\n                   pos++;\n               }\n           }\n\n           /* interpolated vectors */\n\n           else {\n\n\n\n\n\n               float tempbuff2[CB_MEML+CB_FILTERLEN+1];\n\n               float *pos;\n               float *pp, *pp1;\n               int i;\n\n               memset(tempbuff2, 0,\n                   CB_HALFFILTERLEN*sizeof(float));\n               memcpy(&tempbuff2[CB_HALFFILTERLEN], mem,\n                   lMem*sizeof(float));\n               memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0,\n                   (CB_HALFFILTERLEN+1)*sizeof(float));\n\n               k=2*(index-base_size-\n                   (lMem-cbveclen+1))+cbveclen;\n               sFilt=lMem-k;\n               memInd=sFilt+1-CB_HALFFILTERLEN;\n\n               /* do filtering */\n               pos=&tmpbuf[sFilt];\n               memset(pos, 0, k*sizeof(float));\n               for (i=0; i<k; i++) {\n                   pp=&tempbuff2[memInd+i+CB_HALFFILTERLEN];\n                   pp1=&cbfiltersTbl[CB_FILTERLEN-1];\n                   for (j=0; j<CB_FILTERLEN; j++) {\n                       (*pos)+=(*pp++)*(*pp1--);\n                   }\n                   pos++;\n               }\n\n               ihigh=k/2;\n               ilow=ihigh-5;\n\n               /* Copy first noninterpolated part */\n\n               memcpy(cbvec, tmpbuf+lMem-k/2,\n                   ilow*sizeof(float));\n\n               /* interpolation */\n\n               alfa1=(float)0.2;\n               alfa=0.0;\n               for (j=ilow; j<ihigh; j++) {\n                   cbvec[j]=((float)1.0-alfa)*\n                       tmpbuf[lMem-k/2+j]+alfa*tmpbuf[lMem-k+j];\n                   alfa+=alfa1;\n               }\n\n\n\n\n\n\n               /* Copy second noninterpolated part */\n\n               memcpy(cbvec+ihigh, tmpbuf+lMem-k+ihigh,\n                   (cbveclen-ihigh)*sizeof(float));\n           }\n       }\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/getCBvec.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       getCBvec.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_GETCBVEC_H\n   #define __iLBC_GETCBVEC_H\n\n   void getCBvec(\n       float *cbvec,   /* (o) Constructed codebook vector */\n       float *mem,     /* (i) Codebook buffer */\n       int index,      /* (i) Codebook index */\n       int lMem,       /* (i) Length of codebook buffer */\n       int cbveclen/* (i) Codebook vector length */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/helpfun.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       helpfun.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <math.h>\n\n   #include \"iLBC_define.h\"\n   #include \"constants.h\"\n\n   /*----------------------------------------------------------------*\n    *  calculation of auto correlation\n    *---------------------------------------------------------------*/\n\n   void autocorr(\n       float *r,       /* (o) autocorrelation vector */\n       const float *x, /* (i) data vector */\n       int N,          /* (i) length of data vector */\n       int order       /* largest lag for calculated\n                          autocorrelations */\n   ){\n       int     lag, n;\n       float   sum;\n\n       for (lag = 0; lag <= order; lag++) {\n           sum = 0;\n           for (n = 0; n < N - lag; n++) {\n               sum += x[n] * x[n+lag];\n           }\n           r[lag] = sum;\n       }\n\n\n\n\n\n   }\n\n   /*----------------------------------------------------------------*\n    *  window multiplication\n    *---------------------------------------------------------------*/\n\n   void window(\n       float *z,       /* (o) the windowed data */\n       const float *x, /* (i) the original data vector */\n       const float *y, /* (i) the window */\n       int N           /* (i) length of all vectors */\n   ){\n       int     i;\n\n       for (i = 0; i < N; i++) {\n           z[i] = x[i] * y[i];\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  levinson-durbin solution for lpc coefficients\n    *---------------------------------------------------------------*/\n\n   void levdurb(\n       float *a,       /* (o) lpc coefficient vector starting\n                              with 1.0 */\n       float *k,       /* (o) reflection coefficients */\n       float *r,       /* (i) autocorrelation vector */\n       int order       /* (i) order of lpc filter */\n   ){\n       float  sum, alpha;\n       int     m, m_h, i;\n\n       a[0] = 1.0;\n\n       if (r[0] < EPS) { /* if r[0] <= 0, set LPC coeff. to zero */\n           for (i = 0; i < order; i++) {\n               k[i] = 0;\n               a[i+1] = 0;\n           }\n       } else {\n           a[1] = k[0] = -r[1]/r[0];\n           alpha = r[0] + r[1] * k[0];\n           for (m = 1; m < order; m++){\n               sum = r[m + 1];\n               for (i = 0; i < m; i++){\n                   sum += a[i+1] * r[m - i];\n               }\n\n\n\n\n\n               k[m] = -sum / alpha;\n               alpha += k[m] * sum;\n               m_h = (m + 1) >> 1;\n               for (i = 0; i < m_h; i++){\n                   sum = a[i+1] + k[m] * a[m - i];\n                   a[m - i] += k[m] * a[i+1];\n                   a[i+1] = sum;\n               }\n               a[m+1] = k[m];\n           }\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  interpolation between vectors\n    *---------------------------------------------------------------*/\n\n   void interpolate(\n       float *out,      /* (o) the interpolated vector */\n       float *in1,     /* (i) the first vector for the\n                              interpolation */\n       float *in2,     /* (i) the second vector for the\n                              interpolation */\n       float coef,      /* (i) interpolation weights */\n       int length      /* (i) length of all vectors */\n   ){\n       int i;\n       float invcoef;\n\n       invcoef = (float)1.0 - coef;\n       for (i = 0; i < length; i++) {\n           out[i] = coef * in1[i] + invcoef * in2[i];\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  lpc bandwidth expansion\n    *---------------------------------------------------------------*/\n\n   void bwexpand(\n       float *out,      /* (o) the bandwidth expanded lpc\n                              coefficients */\n       float *in,      /* (i) the lpc coefficients before bandwidth\n                              expansion */\n       float coef,     /* (i) the bandwidth expansion factor */\n       int length      /* (i) the length of lpc coefficient vectors */\n   ){\n       int i;\n\n\n\n\n\n       float  chirp;\n\n       chirp = coef;\n\n       out[0] = in[0];\n       for (i = 1; i < length; i++) {\n           out[i] = chirp * in[i];\n           chirp *= coef;\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  vector quantization\n    *---------------------------------------------------------------*/\n\n   void vq(\n       float *Xq,      /* (o) the quantized vector */\n       int *index,     /* (o) the quantization index */\n       const float *CB,/* (i) the vector quantization codebook */\n       float *X,       /* (i) the vector to quantize */\n       int n_cb,       /* (i) the number of vectors in the codebook */\n       int dim         /* (i) the dimension of all vectors */\n   ){\n       int     i, j;\n       int     pos, minindex;\n       float   dist, tmp, mindist;\n\n       pos = 0;\n       mindist = FLOAT_MAX;\n       minindex = 0;\n       for (j = 0; j < n_cb; j++) {\n           dist = X[0] - CB[pos];\n           dist *= dist;\n           for (i = 1; i < dim; i++) {\n               tmp = X[i] - CB[pos + i];\n               dist += tmp*tmp;\n           }\n\n           if (dist < mindist) {\n               mindist = dist;\n               minindex = j;\n           }\n           pos += dim;\n       }\n       for (i = 0; i < dim; i++) {\n           Xq[i] = CB[minindex*dim + i];\n       }\n       *index = minindex;\n\n\n\n\n\n   }\n\n   /*----------------------------------------------------------------*\n    *  split vector quantization\n    *---------------------------------------------------------------*/\n\n   void SplitVQ(\n       float *qX,      /* (o) the quantized vector */\n       int *index,     /* (o) a vector of indexes for all vector\n                              codebooks in the split */\n       float *X,       /* (i) the vector to quantize */\n       const float *CB,/* (i) the quantizer codebook */\n       int nsplit,     /* the number of vector splits */\n       const int *dim, /* the dimension of X and qX */\n       const int *cbsize /* the number of vectors in the codebook */\n   ){\n       int    cb_pos, X_pos, i;\n\n       cb_pos = 0;\n       X_pos= 0;\n       for (i = 0; i < nsplit; i++) {\n           vq(qX + X_pos, index + i, CB + cb_pos, X + X_pos,\n               cbsize[i], dim[i]);\n           X_pos += dim[i];\n           cb_pos += dim[i] * cbsize[i];\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  scalar quantization\n    *---------------------------------------------------------------*/\n\n   void sort_sq(\n       float *xq,      /* (o) the quantized value */\n       int *index,     /* (o) the quantization index */\n       float x,    /* (i) the value to quantize */\n       const float *cb,/* (i) the quantization codebook */\n       int cb_size      /* (i) the size of the quantization codebook */\n   ){\n       int i;\n\n       if (x <= cb[0]) {\n           *index = 0;\n           *xq = cb[0];\n       } else {\n           i = 0;\n           while ((x > cb[i]) && i < cb_size - 1) {\n               i++;\n\n\n\n\n\n           }\n\n           if (x > ((cb[i] + cb[i - 1])/2)) {\n               *index = i;\n               *xq = cb[i];\n           } else {\n               *index = i - 1;\n               *xq = cb[i - 1];\n           }\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  check for stability of lsf coefficients\n    *---------------------------------------------------------------*/\n\n   int LSF_check(    /* (o) 1 for stable lsf vectors and 0 for\n                              nonstable ones */\n       float *lsf,     /* (i) a table of lsf vectors */\n       int dim,    /* (i) the dimension of each lsf vector */\n       int NoAn    /* (i) the number of lsf vectors in the\n                              table */\n   ){\n       int k,n,m, Nit=2, change=0,pos;\n       //float tmp;\n       static float eps=(float)0.039; /* 50 Hz */\n       static float eps2=(float)0.0195;\n       static float maxlsf=(float)3.14; /* 4000 Hz */\n       static float minlsf=(float)0.01; /* 0 Hz */\n\n       /* LSF separation check*/\n\n       for (n=0; n<Nit; n++) { /* Run through a couple of times */\n           for (m=0; m<NoAn; m++) { /* Number of analyses per frame */\n               for (k=0; k<(dim-1); k++) {\n                   pos=m*dim+k;\n\n                   if ((lsf[pos+1]-lsf[pos])<eps) {\n\n                       if (lsf[pos+1]<lsf[pos]) {\n                           //tmp=lsf[pos+1];\n                           lsf[pos+1]= lsf[pos]+eps2;\n                           lsf[pos]= lsf[pos+1]-eps2;\n                       } else {\n                           lsf[pos]-=eps2;\n                           lsf[pos+1]+=eps2;\n                       }\n                       change=1;\n\n\n\n\n\n                   }\n\n                   if (lsf[pos]<minlsf) {\n                       lsf[pos]=minlsf;\n                       change=1;\n                   }\n\n                   if (lsf[pos]>maxlsf) {\n                       lsf[pos]=maxlsf;\n                       change=1;\n                   }\n               }\n           }\n       }\n\n       return change;\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/helpfun.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       helpfun.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_HELPFUN_H\n   #define __iLBC_HELPFUN_H\n\n   void autocorr(\n       float *r,       /* (o) autocorrelation vector */\n       const float *x, /* (i) data vector */\n       int N,          /* (i) length of data vector */\n       int order       /* largest lag for calculated\n                          autocorrelations */\n   );\n\n   void window(\n       float *z,       /* (o) the windowed data */\n       const float *x, /* (i) the original data vector */\n       const float *y, /* (i) the window */\n       int N           /* (i) length of all vectors */\n   );\n\n   void levdurb(\n       float *a,       /* (o) lpc coefficient vector starting\n                              with 1.0 */\n       float *k,       /* (o) reflection coefficients */\n       float *r,       /* (i) autocorrelation vector */\n       int order       /* (i) order of lpc filter */\n   );\n\n   void interpolate(\n\n\n\n\n\n       float *out,     /* (o) the interpolated vector */\n       float *in1,     /* (i) the first vector for the\n                              interpolation */\n       float *in2,     /* (i) the second vector for the\n                              interpolation */\n       float coef,     /* (i) interpolation weights */\n       int length      /* (i) length of all vectors */\n   );\n\n   void bwexpand(\n       float *out,     /* (o) the bandwidth expanded lpc\n                              coefficients */\n       float *in,      /* (i) the lpc coefficients before bandwidth\n                              expansion */\n       float coef,     /* (i) the bandwidth expansion factor */\n       int length      /* (i) the length of lpc coefficient vectors */\n   );\n\n   void vq(\n       float *Xq,      /* (o) the quantized vector */\n       int *index,     /* (o) the quantization index */\n       const float *CB,/* (i) the vector quantization codebook */\n       float *X,       /* (i) the vector to quantize */\n       int n_cb,       /* (i) the number of vectors in the codebook */\n       int dim         /* (i) the dimension of all vectors */\n   );\n\n   void SplitVQ(\n       float *qX,      /* (o) the quantized vector */\n       int *index,     /* (o) a vector of indexes for all vector\n                              codebooks in the split */\n       float *X,       /* (i) the vector to quantize */\n       const float *CB,/* (i) the quantizer codebook */\n       int nsplit,     /* the number of vector splits */\n       const int *dim, /* the dimension of X and qX */\n       const int *cbsize /* the number of vectors in the codebook */\n   );\n\n\n   void sort_sq(\n       float *xq,      /* (o) the quantized value */\n       int *index,     /* (o) the quantization index */\n       float x,    /* (i) the value to quantize */\n       const float *cb,/* (i) the quantization codebook */\n       int cb_size     /* (i) the size of the quantization codebook */\n   );\n\n   int LSF_check(      /* (o) 1 for stable lsf vectors and 0 for\n\n\n\n\n\n                              nonstable ones */\n       float *lsf,     /* (i) a table of lsf vectors */\n       int dim,    /* (i) the dimension of each lsf vector */\n       int NoAn    /* (i) the number of lsf vectors in the\n                              table */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/hpInput.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n\n\n\n\n       hpInput.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include \"constants.h\"\n\n   /*----------------------------------------------------------------*\n    *  Input high-pass filter\n    *---------------------------------------------------------------*/\n\n   void hpInput(\n       float *In,  /* (i) vector to filter */\n       int len,    /* (i) length of vector to filter */\n       float *Out, /* (o) the resulting filtered vector */\n       float *mem  /* (i/o) the filter state */\n   ){\n       int i;\n       float *pi, *po;\n\n       /* all-zero section*/\n\n       pi = &In[0];\n       po = &Out[0];\n       for (i=0; i<len; i++) {\n           *po = hpi_zero_coefsTbl[0] * (*pi);\n           *po += hpi_zero_coefsTbl[1] * mem[0];\n           *po += hpi_zero_coefsTbl[2] * mem[1];\n\n           mem[1] = mem[0];\n           mem[0] = *pi;\n           po++;\n           pi++;\n\n       }\n\n       /* all-pole section*/\n\n       po = &Out[0];\n       for (i=0; i<len; i++) {\n           *po -= hpi_pole_coefsTbl[1] * mem[2];\n           *po -= hpi_pole_coefsTbl[2] * mem[3];\n\n           mem[3] = mem[2];\n           mem[2] = *po;\n           po++;\n\n\n\n\n\n       }\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/hpInput.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       hpInput.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_HPINPUT_H\n   #define __iLBC_HPINPUT_H\n\n   void hpInput(\n       float *In,  /* (i) vector to filter */\n       int len,    /* (i) length of vector to filter */\n       float *Out, /* (o) the resulting filtered vector */\n       float *mem  /* (i/o) the filter state */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/hpOutput.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       hpOutput.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include \"constants.h\"\n\n   /*----------------------------------------------------------------*\n    *  Output high-pass filter\n    *---------------------------------------------------------------*/\n\n   void hpOutput(\n\n\n\n\n\n       float *In,  /* (i) vector to filter */\n       int len,/* (i) length of vector to filter */\n       float *Out, /* (o) the resulting filtered vector */\n       float *mem  /* (i/o) the filter state */\n   ){\n       int i;\n       float *pi, *po;\n\n       /* all-zero section*/\n\n       pi = &In[0];\n       po = &Out[0];\n       for (i=0; i<len; i++) {\n           *po = hpo_zero_coefsTbl[0] * (*pi);\n           *po += hpo_zero_coefsTbl[1] * mem[0];\n           *po += hpo_zero_coefsTbl[2] * mem[1];\n\n           mem[1] = mem[0];\n           mem[0] = *pi;\n           po++;\n           pi++;\n\n       }\n\n       /* all-pole section*/\n\n       po = &Out[0];\n       for (i=0; i<len; i++) {\n           *po -= hpo_pole_coefsTbl[1] * mem[2];\n           *po -= hpo_pole_coefsTbl[2] * mem[3];\n\n           mem[3] = mem[2];\n           mem[2] = *po;\n           po++;\n       }\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/hpOutput.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       hpOutput.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_HPOUTPUT_H\n   #define __iLBC_HPOUTPUT_H\n\n   void hpOutput(\n       float *In,  /* (i) vector to filter */\n       int len,/* (i) length of vector to filter */\n       float *Out, /* (o) the resulting filtered vector */\n       float *mem  /* (i/o) the filter state */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/iCBConstruct.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       iCBConstruct.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <math.h>\n\n   #include \"iLBC_define.h\"\n   #include \"gainquant.h\"\n   #include \"getCBvec.h\"\n\n   /*----------------------------------------------------------------*\n    *  Convert the codebook indexes to make the search easier\n    *---------------------------------------------------------------*/\n\n\n\n\n\n\n   void index_conv_enc(\n       int *index          /* (i/o) Codebook indexes */\n   ){\n       int k;\n\n       for (k=1; k<CB_NSTAGES; k++) {\n\n           if ((index[k]>=108)&&(index[k]<172)) {\n               index[k]-=64;\n           } else if (index[k]>=236) {\n               index[k]-=128;\n           } else {\n               /* ERROR */\n           }\n       }\n   }\n\n   void index_conv_dec(\n       int *index          /* (i/o) Codebook indexes */\n   ){\n       int k;\n\n       for (k=1; k<CB_NSTAGES; k++) {\n\n           if ((index[k]>=44)&&(index[k]<108)) {\n               index[k]+=64;\n           } else if ((index[k]>=108)&&(index[k]<128)) {\n               index[k]+=128;\n           } else {\n               /* ERROR */\n           }\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  Construct decoded vector from codebook and gains.\n    *---------------------------------------------------------------*/\n\n   void iCBConstruct(\n       float *decvector,   /* (o) Decoded vector */\n       int *index,         /* (i) Codebook indices */\n       int *gain_index,/* (i) Gain quantization indices */\n       float *mem,         /* (i) Buffer for codevector construction */\n       int lMem,           /* (i) Length of buffer */\n       int veclen,         /* (i) Length of vector */\n       int nStages         /* (i) Number of codebook stages */\n   ){\n       int j,k;\n\n\n\n\n\n       float gain[CB_NSTAGES];\n       float cbvec[SUBL];\n\n       /* gain de-quantization */\n\n       gain[0] = gaindequant(gain_index[0], 1.0, 32);\n       if (nStages > 1) {\n           gain[1] = gaindequant(gain_index[1],\n               (float)fabs(gain[0]), 16);\n       }\n       if (nStages > 2) {\n           gain[2] = gaindequant(gain_index[2],\n               (float)fabs(gain[1]), 8);\n       }\n\n       /* codebook vector construction and construction of\n       total vector */\n\n       getCBvec(cbvec, mem, index[0], lMem, veclen);\n       for (j=0;j<veclen;j++){\n           decvector[j] = gain[0]*cbvec[j];\n       }\n       if (nStages > 1) {\n           for (k=1; k<nStages; k++) {\n               getCBvec(cbvec, mem, index[k], lMem, veclen);\n               for (j=0;j<veclen;j++) {\n                   decvector[j] += gain[k]*cbvec[j];\n               }\n           }\n       }\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/iCBConstruct.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       iCBConstruct.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n\n\n\n\n\n   ******************************************************************/\n\n   #ifndef __iLBC_ICBCONSTRUCT_H\n   #define __iLBC_ICBCONSTRUCT_H\n\n   void index_conv_enc(\n       int *index          /* (i/o) Codebook indexes */\n   );\n\n   void index_conv_dec(\n       int *index          /* (i/o) Codebook indexes */\n   );\n\n   void iCBConstruct(\n       float *decvector,   /* (o) Decoded vector */\n       int *index,         /* (i) Codebook indices */\n       int *gain_index,/* (i) Gain quantization indices */\n       float *mem,         /* (i) Buffer for codevector construction */\n       int lMem,           /* (i) Length of buffer */\n       int veclen,         /* (i) Length of vector */\n       int nStages         /* (i) Number of codebook stages */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/iCBSearch.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       iCBSearch.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <math.h>\n   #include <string.h>\n\n   #include \"iLBC_define.h\"\n   #include \"gainquant.h\"\n   #include \"createCB.h\"\n   #include \"filter.h\"\n   #include \"constants.h\"\n\n   /*----------------------------------------------------------------*\n    *  Search routine for codebook encoding and gain quantization.\n    *---------------------------------------------------------------*/\n\n   void iCBSearch(\n       iLBC_Enc_Inst_t *iLBCenc_inst,\n                           /* (i) the encoder state structure */\n       int *index,         /* (o) Codebook indices */\n       int *gain_index,/* (o) Gain quantization indices */\n\n\n\n\n\n       float *intarget,/* (i) Target vector for encoding */\n       float *mem,         /* (i) Buffer for codebook construction */\n       int lMem,           /* (i) Length of buffer */\n       int lTarget,    /* (i) Length of vector */\n       int nStages,    /* (i) Number of codebook stages */\n       float *weightDenum, /* (i) weighting filter coefficients */\n       float *weightState, /* (i) weighting filter state */\n       int block           /* (i) the sub-block number */\n   ){\n       int i, j, icount, stage, best_index, range, counter;\n       float max_measure, gain, measure, crossDot, ftmp;\n       float gains[CB_NSTAGES];\n       float target[SUBL];\n       int base_index, sInd, eInd, base_size;\n       int sIndAug=0, eIndAug=0;\n       float buf[CB_MEML+SUBL+2*LPC_FILTERORDER];\n       float invenergy[CB_EXPAND*128], energy[CB_EXPAND*128];\n       float *pp, *ppi=0, *ppo=0, *ppe=0;\n       float cbvectors[CB_MEML];\n       float tene, cene, cvec[SUBL];\n       float aug_vec[SUBL];\n\n       memset(cvec,0,SUBL*sizeof(float));\n\n       /* Determine size of codebook sections */\n\n       base_size=lMem-lTarget+1;\n\n       if (lTarget==SUBL) {\n           base_size=lMem-lTarget+1+lTarget/2;\n       }\n\n       /* setup buffer for weighting */\n\n       memcpy(buf,weightState,sizeof(float)*LPC_FILTERORDER);\n       memcpy(buf+LPC_FILTERORDER,mem,lMem*sizeof(float));\n       memcpy(buf+LPC_FILTERORDER+lMem,intarget,lTarget*sizeof(float));\n\n       /* weighting */\n\n       AllPoleFilter(buf+LPC_FILTERORDER, weightDenum,\n           lMem+lTarget, LPC_FILTERORDER);\n\n       /* Construct the codebook and target needed */\n\n       memcpy(target, buf+LPC_FILTERORDER+lMem, lTarget*sizeof(float));\n\n       tene=0.0;\n\n\n\n\n\n       for (i=0; i<lTarget; i++) {\n           tene+=target[i]*target[i];\n       }\n\n       /* Prepare search over one more codebook section. This section\n          is created by filtering the original buffer with a filter. */\n\n       filteredCBvecs(cbvectors, buf+LPC_FILTERORDER, lMem);\n\n       /* The Main Loop over stages */\n\n       for (stage=0; stage<nStages; stage++) {\n\n           range = search_rangeTbl[block][stage];\n\n           /* initialize search measure */\n\n           max_measure = (float)-10000000.0;\n           gain = (float)0.0;\n           best_index = 0;\n\n           /* Compute cross dot product between the target\n              and the CB memory */\n\n           crossDot=0.0;\n           pp=buf+LPC_FILTERORDER+lMem-lTarget;\n           for (j=0; j<lTarget; j++) {\n               crossDot += target[j]*(*pp++);\n           }\n\n           if (stage==0) {\n\n               /* Calculate energy in the first block of\n                 'lTarget' samples. */\n               ppe = energy;\n               ppi = buf+LPC_FILTERORDER+lMem-lTarget-1;\n               ppo = buf+LPC_FILTERORDER+lMem-1;\n\n               *ppe=0.0;\n               pp=buf+LPC_FILTERORDER+lMem-lTarget;\n               for (j=0; j<lTarget; j++) {\n                   *ppe+=(*pp)*(*pp);\n\t\t   ++pp;\n               }\n\n               if (*ppe>0.0) {\n                   invenergy[0] = (float) 1.0 / (*ppe + EPS);\n               } else {\n                   invenergy[0] = (float) 0.0;\n\n\n\n\n\n               }\n               ppe++;\n\n               measure=(float)-10000000.0;\n\n               if (crossDot > 0.0) {\n                      measure = crossDot*crossDot*invenergy[0];\n               }\n           }\n           else {\n               measure = crossDot*crossDot*invenergy[0];\n           }\n\n           /* check if measure is better */\n           ftmp = crossDot*invenergy[0];\n\n           if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {\n               best_index = 0;\n               max_measure = measure;\n               gain = ftmp;\n           }\n\n           /* loop over the main first codebook section,\n              full search */\n\n           for (icount=1; icount<range; icount++) {\n\n               /* calculate measure */\n\n               crossDot=0.0;\n               pp = buf+LPC_FILTERORDER+lMem-lTarget-icount;\n\n               for (j=0; j<lTarget; j++) {\n                   crossDot += target[j]*(*pp++);\n               }\n\n               if (stage==0) {\n                   *ppe++ = energy[icount-1] + (*ppi)*(*ppi) -\n                       (*ppo)*(*ppo);\n                   ppo--;\n                   ppi--;\n\n                   if (energy[icount]>0.0) {\n                       invenergy[icount] =\n                           (float)1.0/(energy[icount]+EPS);\n                   } else {\n                       invenergy[icount] = (float) 0.0;\n                   }\n\n\n\n\n\n                   measure=(float)-10000000.0;\n\n                   if (crossDot > 0.0) {\n                       measure = crossDot*crossDot*invenergy[icount];\n                   }\n               }\n               else {\n                   measure = crossDot*crossDot*invenergy[icount];\n               }\n\n               /* check if measure is better */\n               ftmp = crossDot*invenergy[icount];\n\n               if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {\n                   best_index = icount;\n                   max_measure = measure;\n                   gain = ftmp;\n               }\n           }\n\n           /* Loop over augmented part in the first codebook\n            * section, full search.\n            * The vectors are interpolated.\n            */\n\n           if (lTarget==SUBL) {\n\n               /* Search for best possible cb vector and\n                  compute the CB-vectors' energy. */\n               searchAugmentedCB(20, 39, stage, base_size-lTarget/2,\n                   target, buf+LPC_FILTERORDER+lMem,\n                   &max_measure, &best_index, &gain, energy,\n                   invenergy);\n           }\n\n           /* set search range for following codebook sections */\n\n           base_index=best_index;\n\n           /* unrestricted search */\n\n#\t   if CB_RESRANGE == -1\n           //if (CB_RESRANGE == -1) {\n               sInd=0;\n               eInd=range-1;\n               sIndAug=20;\n               eIndAug=39;\n           //}\n\n#\t   else\n\n           /* restricted search around best index from first\n           codebook section */\n\n           //else {\n               /* Initialize search indices */\n               sIndAug=0;\n               eIndAug=0;\n               sInd=base_index-CB_RESRANGE/2;\n               eInd=sInd+CB_RESRANGE;\n\n               if (lTarget==SUBL) {\n\n                   if (sInd<0) {\n\n                       sIndAug = 40 + sInd;\n                       eIndAug = 39;\n                       sInd=0;\n\n                   } else if ( base_index < (base_size-20) ) {\n\n                       if (eInd > range) {\n                           sInd -= (eInd-range);\n                           eInd = range;\n                       }\n                   } else { /* base_index >= (base_size-20) */\n\n                       if (sInd < (base_size-20)) {\n                           sIndAug = 20;\n                           sInd = 0;\n                           eInd = 0;\n                           eIndAug = 19 + CB_RESRANGE;\n\n                           if(eIndAug > 39) {\n                               eInd = eIndAug-39;\n                               eIndAug = 39;\n                           }\n                       } else {\n                           sIndAug = 20 + sInd - (base_size-20);\n                           eIndAug = 39;\n                           sInd = 0;\n                           eInd = CB_RESRANGE - (eIndAug-sIndAug+1);\n                       }\n                   }\n\n               } else { /* lTarget = 22 or 23 */\n\n                   if (sInd < 0) {\n                       eInd -= sInd;\n\n\n\n\n\n                       sInd = 0;\n                   }\n\n                   if(eInd > range) {\n                       sInd -= (eInd - range);\n                       eInd = range;\n                   }\n               }\n\n           //}\n#\t   endif /* CB_RESRANGE == -1 */\n\n\n           /* search of higher codebook section */\n\n           /* index search range */\n           counter = sInd;\n           sInd += base_size;\n           eInd += base_size;\n\n\n           if (stage==0) {\n               ppe = energy+base_size;\n               *ppe=0.0;\n\n               pp=cbvectors+lMem-lTarget;\n               for (j=0; j<lTarget; j++) {\n                   *ppe+=(*pp)*(*pp);\n\t\t   ++pp;\n               }\n\n               ppi = cbvectors + lMem - 1 - lTarget;\n               ppo = cbvectors + lMem - 1;\n\n               for (j=0; j<(range-1); j++) {\n                   *(ppe+1) = *ppe + (*ppi)*(*ppi) - (*ppo)*(*ppo);\n                   ppo--;\n                   ppi--;\n                   ppe++;\n               }\n           }\n\n           /* loop over search range */\n\n           for (icount=sInd; icount<eInd; icount++) {\n\n               /* calculate measure */\n\n               crossDot=0.0;\n               pp=cbvectors + lMem - (counter++) - lTarget;\n\n               for (j=0;j<lTarget;j++) {\n\n\n\n\n\n                   crossDot += target[j]*(*pp++);\n               }\n\n               if (energy[icount]>0.0) {\n                   invenergy[icount] =(float)1.0/(energy[icount]+EPS);\n               } else {\n                   invenergy[icount] =(float)0.0;\n               }\n\n               if (stage==0) {\n\n                   measure=(float)-10000000.0;\n\n                   if (crossDot > 0.0) {\n                       measure = crossDot*crossDot*\n                           invenergy[icount];\n                   }\n               }\n               else {\n                   measure = crossDot*crossDot*invenergy[icount];\n               }\n\n               /* check if measure is better */\n               ftmp = crossDot*invenergy[icount];\n\n               if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {\n                   best_index = icount;\n                   max_measure = measure;\n                   gain = ftmp;\n               }\n           }\n\n           /* Search the augmented CB inside the limited range. */\n\n           if ((lTarget==SUBL)&&(sIndAug!=0)) {\n               searchAugmentedCB(sIndAug, eIndAug, stage,\n                   2*base_size-20, target, cbvectors+lMem,\n                   &max_measure, &best_index, &gain, energy,\n                   invenergy);\n           }\n\n           /* record best index */\n\n           index[stage] = best_index;\n\n           /* gain quantization */\n\n           if (stage==0){\n\n\n\n\n\n\n               if (gain<0.0){\n                   gain = 0.0;\n               }\n\n               if (gain>CB_MAXGAIN) {\n                   gain = (float)CB_MAXGAIN;\n               }\n               gain = gainquant(gain, 1.0, 32, &gain_index[stage]);\n           }\n           else {\n               if (stage==1) {\n                   gain = gainquant(gain, (float)fabs(gains[stage-1]),\n                       16, &gain_index[stage]);\n               } else {\n                   gain = gainquant(gain, (float)fabs(gains[stage-1]),\n                       8, &gain_index[stage]);\n               }\n           }\n\n           /* Extract the best (according to measure)\n              codebook vector */\n\n           if (lTarget==(STATE_LEN-iLBCenc_inst->state_short_len)) {\n\n               if (index[stage]<base_size) {\n                   pp=buf+LPC_FILTERORDER+lMem-lTarget-index[stage];\n               } else {\n                   pp=cbvectors+lMem-lTarget-\n                       index[stage]+base_size;\n               }\n           } else {\n\n               if (index[stage]<base_size) {\n                   if (index[stage]<(base_size-20)) {\n                       pp=buf+LPC_FILTERORDER+lMem-\n                           lTarget-index[stage];\n                   } else {\n                       createAugmentedVec(index[stage]-base_size+40,\n                               buf+LPC_FILTERORDER+lMem,aug_vec);\n                       pp=aug_vec;\n                   }\n               } else {\n                   int filterno, position;\n\n                   filterno=index[stage]/base_size;\n                   position=index[stage]-filterno*base_size;\n\n\n\n\n\n\n\n                   if (position<(base_size-20)) {\n                       pp=cbvectors+filterno*lMem-lTarget-\n                           index[stage]+filterno*base_size;\n                   } else {\n                       createAugmentedVec(\n                           index[stage]-(filterno+1)*base_size+40,\n                           cbvectors+filterno*lMem,aug_vec);\n                       pp=aug_vec;\n                   }\n               }\n           }\n\n           /* Subtract the best codebook vector, according\n              to measure, from the target vector */\n\n           for (j=0;j<lTarget;j++) {\n               cvec[j] += gain*(*pp);\n               target[j] -= gain*(*pp++);\n           }\n\n           /* record quantized gain */\n\n           gains[stage]=gain;\n\n       }/* end of Main Loop. for (stage=0;... */\n\n       /* Gain adjustment for energy matching */\n       cene=0.0;\n       for (i=0; i<lTarget; i++) {\n           cene+=cvec[i]*cvec[i];\n       }\n       j=gain_index[0];\n\n       for (i=gain_index[0]; i<32; i++) {\n           ftmp=cene*gain_sq5Tbl[i]*gain_sq5Tbl[i];\n\n           if ((ftmp<(tene*gains[0]*gains[0])) &&\n               (gain_sq5Tbl[j]<(2.0*gains[0]))) {\n               j=i;\n           }\n       }\n       gain_index[0]=j;\n   }\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/iCBSearch.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       iCBSearch.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_ICBSEARCH_H\n   #define __iLBC_ICBSEARCH_H\n\n\n\n\n\n\n   void iCBSearch(\n       iLBC_Enc_Inst_t *iLBCenc_inst,\n                           /* (i) the encoder state structure */\n       int *index,         /* (o) Codebook indices */\n       int *gain_index,/* (o) Gain quantization indices */\n       float *intarget,/* (i) Target vector for encoding */\n       float *mem,         /* (i) Buffer for codebook construction */\n       int lMem,           /* (i) Length of buffer */\n       int lTarget,    /* (i) Length of vector */\n       int nStages,    /* (i) Number of codebook stages */\n       float *weightDenum, /* (i) weighting filter coefficients */\n       float *weightState, /* (i) weighting filter state */\n       int block           /* (i) the sub-block number */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/iLBC_decode.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       iLBC_decode.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <math.h>\n   #include <stdlib.h>\n\n   #include \"iLBC_define.h\"\n   #include \"StateConstructW.h\"\n   #include \"LPCdecode.h\"\n   #include \"iCBConstruct.h\"\n   #include \"doCPLC.h\"\n   #include \"helpfun.h\"\n   #include \"constants.h\"\n   #include \"packing.h\"\n   #include \"string.h\"\n   #include \"enhancer.h\"\n   #include \"hpOutput.h\"\n   #include \"syntFilter.h\"\n\n   /*----------------------------------------------------------------*\n    *  Initiation of decoder instance.\n    *---------------------------------------------------------------*/\n\n   short initDecode(                   /* (o) Number of decoded\n                                              samples */\n       iLBC_Dec_Inst_t *iLBCdec_inst,  /* (i/o) Decoder instance */\n       int mode,                       /* (i) frame size mode */\n       int use_enhancer                /* (i) 1 to use enhancer\n                                              0 to run without\n                                                enhancer */\n   ){\n       int i;\n\n       iLBCdec_inst->mode = mode;\n\n\n\n\n\n       if (mode==30) {\n           iLBCdec_inst->blockl = BLOCKL_30MS;\n           iLBCdec_inst->nsub = NSUB_30MS;\n           iLBCdec_inst->nasub = NASUB_30MS;\n           iLBCdec_inst->lpc_n = LPC_N_30MS;\n           iLBCdec_inst->no_of_bytes = NO_OF_BYTES_30MS;\n           iLBCdec_inst->no_of_words = NO_OF_WORDS_30MS;\n           iLBCdec_inst->state_short_len=STATE_SHORT_LEN_30MS;\n           /* ULP init */\n           iLBCdec_inst->ULP_inst=&ULP_30msTbl;\n       }\n       else if (mode==20) {\n           iLBCdec_inst->blockl = BLOCKL_20MS;\n           iLBCdec_inst->nsub = NSUB_20MS;\n           iLBCdec_inst->nasub = NASUB_20MS;\n           iLBCdec_inst->lpc_n = LPC_N_20MS;\n           iLBCdec_inst->no_of_bytes = NO_OF_BYTES_20MS;\n           iLBCdec_inst->no_of_words = NO_OF_WORDS_20MS;\n           iLBCdec_inst->state_short_len=STATE_SHORT_LEN_20MS;\n           /* ULP init */\n           iLBCdec_inst->ULP_inst=&ULP_20msTbl;\n       }\n       else {\n           exit(2);\n       }\n\n       memset(iLBCdec_inst->syntMem, 0,\n           LPC_FILTERORDER*sizeof(float));\n       memcpy((*iLBCdec_inst).lsfdeqold, lsfmeanTbl,\n           LPC_FILTERORDER*sizeof(float));\n\n       memset(iLBCdec_inst->old_syntdenum, 0,\n           ((LPC_FILTERORDER + 1)*NSUB_MAX)*sizeof(float));\n       for (i=0; i<NSUB_MAX; i++)\n           iLBCdec_inst->old_syntdenum[i*(LPC_FILTERORDER+1)]=1.0;\n\n       iLBCdec_inst->last_lag = 20;\n\n       iLBCdec_inst->prevLag = 120;\n       iLBCdec_inst->per = 0.0;\n       iLBCdec_inst->consPLICount = 0;\n       iLBCdec_inst->prevPLI = 0;\n       iLBCdec_inst->prevLpc[0] = 1.0;\n       memset(iLBCdec_inst->prevLpc+1,0,\n           LPC_FILTERORDER*sizeof(float));\n       memset(iLBCdec_inst->prevResidual, 0, BLOCKL_MAX*sizeof(float));\n       iLBCdec_inst->seed=777;\n\n\n\n\n\n\n       memset(iLBCdec_inst->hpomem, 0, 4*sizeof(float));\n\n       iLBCdec_inst->use_enhancer = use_enhancer;\n       memset(iLBCdec_inst->enh_buf, 0, ENH_BUFL*sizeof(float));\n       for (i=0;i<ENH_NBLOCKS_TOT;i++)\n           iLBCdec_inst->enh_period[i]=(float)40.0;\n\n       iLBCdec_inst->prev_enh_pl = 0;\n\n       return (short)(iLBCdec_inst->blockl);\n   }\n\n   /*----------------------------------------------------------------*\n    *  frame residual decoder function (subrutine to iLBC_decode)\n    *---------------------------------------------------------------*/\n\n   void Decode(\n       iLBC_Dec_Inst_t *iLBCdec_inst,  /* (i/o) the decoder state\n                                                structure */\n       float *decresidual,             /* (o) decoded residual frame */\n       int start,                      /* (i) location of start\n                                              state */\n       int idxForMax,                  /* (i) codebook index for the\n                                              maximum value */\n       int *idxVec,                /* (i) codebook indexes for the\n                                              samples  in the start\n                                              state */\n       float *syntdenum,               /* (i) the decoded synthesis\n                                              filter coefficients */\n       int *cb_index,                  /* (i) the indexes for the\n                                              adaptive codebook */\n       int *gain_index,            /* (i) the indexes for the\n                                              corresponding gains */\n       int *extra_cb_index,        /* (i) the indexes for the\n                                              adaptive codebook part\n                                              of start state */\n       int *extra_gain_index,          /* (i) the indexes for the\n                                              corresponding gains */\n       int state_first                 /* (i) 1 if non adaptive part\n                                              of start state comes\n                                              first 0 if that part\n                                              comes last */\n   ){\n       float reverseDecresidual[BLOCKL_MAX], mem[CB_MEML];\n       int k, meml_gotten, Nfor, Nback, i;\n       int diff, start_pos;\n       int subcount, subframe;\n\n\n\n\n\n\n       diff = STATE_LEN - iLBCdec_inst->state_short_len;\n\n       if (state_first == 1) {\n           start_pos = (start-1)*SUBL;\n       } else {\n           start_pos = (start-1)*SUBL + diff;\n       }\n\n       /* decode scalar part of start state */\n\n       StateConstructW(idxForMax, idxVec,\n           &syntdenum[(start-1)*(LPC_FILTERORDER+1)],\n           &decresidual[start_pos], iLBCdec_inst->state_short_len);\n\n\n       if (state_first) { /* put adaptive part in the end */\n\n           /* setup memory */\n\n           memset(mem, 0,\n               (CB_MEML-iLBCdec_inst->state_short_len)*sizeof(float));\n           memcpy(mem+CB_MEML-iLBCdec_inst->state_short_len,\n               decresidual+start_pos,\n               iLBCdec_inst->state_short_len*sizeof(float));\n\n           /* construct decoded vector */\n\n           iCBConstruct(\n               &decresidual[start_pos+iLBCdec_inst->state_short_len],\n               extra_cb_index, extra_gain_index, mem+CB_MEML-stMemLTbl,\n               stMemLTbl, diff, CB_NSTAGES);\n\n       }\n       else {/* put adaptive part in the beginning */\n\n           /* create reversed vectors for prediction */\n\n           for (k=0; k<diff; k++) {\n               reverseDecresidual[k] =\n                   decresidual[(start+1)*SUBL-1-\n                           (k+iLBCdec_inst->state_short_len)];\n           }\n\n           /* setup memory */\n\n           meml_gotten = iLBCdec_inst->state_short_len;\n           for (k=0; k<meml_gotten; k++){\n               mem[CB_MEML-1-k] = decresidual[start_pos + k];\n\n\n\n\n\n           }\n           memset(mem, 0, (CB_MEML-k)*sizeof(float));\n\n           /* construct decoded vector */\n\n           iCBConstruct(reverseDecresidual, extra_cb_index,\n               extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl,\n               diff, CB_NSTAGES);\n\n           /* get decoded residual from reversed vector */\n\n           for (k=0; k<diff; k++) {\n               decresidual[start_pos-1-k] = reverseDecresidual[k];\n           }\n       }\n\n       /* counter for predicted sub-frames */\n\n       subcount=0;\n\n       /* forward prediction of sub-frames */\n\n       Nfor = iLBCdec_inst->nsub-start-1;\n\n       if ( Nfor > 0 ){\n\n           /* setup memory */\n\n           memset(mem, 0, (CB_MEML-STATE_LEN)*sizeof(float));\n           memcpy(mem+CB_MEML-STATE_LEN, decresidual+(start-1)*SUBL,\n               STATE_LEN*sizeof(float));\n\n           /* loop over sub-frames to encode */\n\n           for (subframe=0; subframe<Nfor; subframe++) {\n\n               /* construct decoded vector */\n\n               iCBConstruct(&decresidual[(start+1+subframe)*SUBL],\n                   cb_index+subcount*CB_NSTAGES,\n                   gain_index+subcount*CB_NSTAGES,\n                   mem+CB_MEML-memLfTbl[subcount],\n                   memLfTbl[subcount], SUBL, CB_NSTAGES);\n\n               /* update memory */\n\n               memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float));\n               memcpy(mem+CB_MEML-SUBL,\n\n\n\n\n\n                   &decresidual[(start+1+subframe)*SUBL],\n                   SUBL*sizeof(float));\n\n               subcount++;\n\n           }\n\n       }\n\n       /* backward prediction of sub-frames */\n\n       Nback = start-1;\n\n       if ( Nback > 0 ) {\n\n           /* setup memory */\n\n           meml_gotten = SUBL*(iLBCdec_inst->nsub+1-start);\n\n           if ( meml_gotten > CB_MEML ) {\n               meml_gotten=CB_MEML;\n           }\n           for (k=0; k<meml_gotten; k++) {\n               mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k];\n           }\n           memset(mem, 0, (CB_MEML-k)*sizeof(float));\n\n           /* loop over subframes to decode */\n\n           for (subframe=0; subframe<Nback; subframe++) {\n\n               /* construct decoded vector */\n\n               iCBConstruct(&reverseDecresidual[subframe*SUBL],\n                   cb_index+subcount*CB_NSTAGES,\n                   gain_index+subcount*CB_NSTAGES,\n                   mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount],\n                   SUBL, CB_NSTAGES);\n\n               /* update memory */\n\n               memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float));\n               memcpy(mem+CB_MEML-SUBL,\n                   &reverseDecresidual[subframe*SUBL],\n                   SUBL*sizeof(float));\n\n               subcount++;\n           }\n\n\n\n\n\n           /* get decoded residual from reversed vector */\n\n           for (i=0; i<SUBL*Nback; i++)\n               decresidual[SUBL*Nback - i - 1] =\n               reverseDecresidual[i];\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  main decoder function\n    *---------------------------------------------------------------*/\n\n   void iLBC_decode(\n       float *decblock,            /* (o) decoded signal block */\n       unsigned char *bytes,           /* (i) encoded signal bits */\n       iLBC_Dec_Inst_t *iLBCdec_inst,  /* (i/o) the decoder state\n                                                structure */\n       int mode                    /* (i) 0: bad packet, PLC,\n                                              1: normal */\n   ){\n       float data[BLOCKL_MAX];\n       float lsfdeq[LPC_FILTERORDER*LPC_N_MAX];\n       float PLCresidual[BLOCKL_MAX], PLClpc[LPC_FILTERORDER + 1];\n       float zeros[BLOCKL_MAX], one[LPC_FILTERORDER + 1];\n       int k, i, start, idxForMax, pos, lastpart, ulp;\n       int lag, ilag;\n       float cc, maxcc;\n       int idxVec[STATE_LEN];\n       int gain_index[NASUB_MAX*CB_NSTAGES],\n           extra_gain_index[CB_NSTAGES];\n       int cb_index[CB_NSTAGES*NASUB_MAX], extra_cb_index[CB_NSTAGES];\n       int lsf_i[LSF_NSPLIT*LPC_N_MAX];\n       int state_first;\n       int last_bit;\n       unsigned char *pbytes;\n       float weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];\n       int order_plus_one;\n       float syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)];\n       float decresidual[BLOCKL_MAX];\n\n       if (mode>0) { /* the data are good */\n\n           /* decode data */\n\n           pbytes=bytes;\n           pos=0;\n\n\n\n\n\n\n           /* Set everything to zero before decoding */\n\n           for (k=0; k<LSF_NSPLIT*LPC_N_MAX; k++) {\n               lsf_i[k]=0;\n           }\n           start=0;\n           state_first=0;\n           idxForMax=0;\n           for (k=0; k<iLBCdec_inst->state_short_len; k++) {\n               idxVec[k]=0;\n           }\n           for (k=0; k<CB_NSTAGES; k++) {\n               extra_cb_index[k]=0;\n           }\n           for (k=0; k<CB_NSTAGES; k++) {\n               extra_gain_index[k]=0;\n           }\n           for (i=0; i<iLBCdec_inst->nasub; i++) {\n               for (k=0; k<CB_NSTAGES; k++) {\n                   cb_index[i*CB_NSTAGES+k]=0;\n               }\n           }\n           for (i=0; i<iLBCdec_inst->nasub; i++) {\n               for (k=0; k<CB_NSTAGES; k++) {\n                   gain_index[i*CB_NSTAGES+k]=0;\n               }\n           }\n\n           /* loop over ULP classes */\n\n           for (ulp=0; ulp<3; ulp++) {\n\n               /* LSF */\n               for (k=0; k<LSF_NSPLIT*iLBCdec_inst->lpc_n; k++){\n                   unpack( &pbytes, &lastpart,\n                       iLBCdec_inst->ULP_inst->lsf_bits[k][ulp], &pos);\n                   packcombine(&lsf_i[k], lastpart,\n                       iLBCdec_inst->ULP_inst->lsf_bits[k][ulp]);\n               }\n\n               /* Start block info */\n\n               unpack( &pbytes, &lastpart,\n                   iLBCdec_inst->ULP_inst->start_bits[ulp], &pos);\n               packcombine(&start, lastpart,\n                   iLBCdec_inst->ULP_inst->start_bits[ulp]);\n\n               unpack( &pbytes, &lastpart,\n\n\n\n\n\n                   iLBCdec_inst->ULP_inst->startfirst_bits[ulp], &pos);\n               packcombine(&state_first, lastpart,\n                   iLBCdec_inst->ULP_inst->startfirst_bits[ulp]);\n\n               unpack( &pbytes, &lastpart,\n                   iLBCdec_inst->ULP_inst->scale_bits[ulp], &pos);\n               packcombine(&idxForMax, lastpart,\n                   iLBCdec_inst->ULP_inst->scale_bits[ulp]);\n\n               for (k=0; k<iLBCdec_inst->state_short_len; k++) {\n                   unpack( &pbytes, &lastpart,\n                       iLBCdec_inst->ULP_inst->state_bits[ulp], &pos);\n                   packcombine(idxVec+k, lastpart,\n                       iLBCdec_inst->ULP_inst->state_bits[ulp]);\n               }\n\n               /* 23/22 (20ms/30ms) sample block */\n\n               for (k=0; k<CB_NSTAGES; k++) {\n                   unpack( &pbytes, &lastpart,\n                       iLBCdec_inst->ULP_inst->extra_cb_index[k][ulp],\n                       &pos);\n                   packcombine(extra_cb_index+k, lastpart,\n                       iLBCdec_inst->ULP_inst->extra_cb_index[k][ulp]);\n               }\n               for (k=0; k<CB_NSTAGES; k++) {\n                   unpack( &pbytes, &lastpart,\n                       iLBCdec_inst->ULP_inst->extra_cb_gain[k][ulp],\n                       &pos);\n                   packcombine(extra_gain_index+k, lastpart,\n                       iLBCdec_inst->ULP_inst->extra_cb_gain[k][ulp]);\n               }\n\n               /* The two/four (20ms/30ms) 40 sample sub-blocks */\n\n               for (i=0; i<iLBCdec_inst->nasub; i++) {\n                   for (k=0; k<CB_NSTAGES; k++) {\n                       unpack( &pbytes, &lastpart,\n                       iLBCdec_inst->ULP_inst->cb_index[i][k][ulp],\n                           &pos);\n                       packcombine(cb_index+i*CB_NSTAGES+k, lastpart,\n                       iLBCdec_inst->ULP_inst->cb_index[i][k][ulp]);\n                   }\n               }\n\n               for (i=0; i<iLBCdec_inst->nasub; i++) {\n                   for (k=0; k<CB_NSTAGES; k++) {\n                       unpack( &pbytes, &lastpart,\n\n\n\n\n\n                       iLBCdec_inst->ULP_inst->cb_gain[i][k][ulp],\n                           &pos);\n                       packcombine(gain_index+i*CB_NSTAGES+k, lastpart,\n                           iLBCdec_inst->ULP_inst->cb_gain[i][k][ulp]);\n                   }\n               }\n           }\n           /* Extract last bit. If it is 1 this indicates an\n              empty/lost frame */\n           unpack( &pbytes, &last_bit, 1, &pos);\n\n           /* Check for bit errors or empty/lost frames */\n           if (start<1)\n               mode = 0;\n           if (iLBCdec_inst->mode==20 && start>3)\n               mode = 0;\n           if (iLBCdec_inst->mode==30 && start>5)\n               mode = 0;\n           if (last_bit==1)\n               mode = 0;\n\n           if (mode==1) { /* No bit errors was detected,\n                             continue decoding */\n\n               /* adjust index */\n               index_conv_dec(cb_index);\n\n               /* decode the lsf */\n\n               SimplelsfDEQ(lsfdeq, lsf_i, iLBCdec_inst->lpc_n);\n               LSF_check(lsfdeq, LPC_FILTERORDER,\n                   iLBCdec_inst->lpc_n);\n               DecoderInterpolateLSF(syntdenum, weightdenum,\n                   lsfdeq, LPC_FILTERORDER, iLBCdec_inst);\n\n               Decode(iLBCdec_inst, decresidual, start, idxForMax,\n                   idxVec, syntdenum, cb_index, gain_index,\n                   extra_cb_index, extra_gain_index,\n                   state_first);\n\n               /* preparing the plc for a future loss! */\n\n               doThePLC(PLCresidual, PLClpc, 0, decresidual,\n                   syntdenum +\n                   (LPC_FILTERORDER + 1)*(iLBCdec_inst->nsub - 1),\n                   (*iLBCdec_inst).last_lag, iLBCdec_inst);\n\n\n\n\n\n\n\n               memcpy(decresidual, PLCresidual,\n                   iLBCdec_inst->blockl*sizeof(float));\n           }\n\n       }\n\n       if (mode == 0) {\n           /* the data is bad (either a PLC call\n            * was made or a severe bit error was detected)\n            */\n\n           /* packet loss conceal */\n\n           memset(zeros, 0, BLOCKL_MAX*sizeof(float));\n\n           one[0] = 1;\n           memset(one+1, 0, LPC_FILTERORDER*sizeof(float));\n\n           start=0;\n\n           doThePLC(PLCresidual, PLClpc, 1, zeros, one,\n               (*iLBCdec_inst).last_lag, iLBCdec_inst);\n           memcpy(decresidual, PLCresidual,\n               iLBCdec_inst->blockl*sizeof(float));\n\n           order_plus_one = LPC_FILTERORDER + 1;\n           for (i = 0; i < iLBCdec_inst->nsub; i++) {\n               memcpy(syntdenum+(i*order_plus_one), PLClpc,\n                   order_plus_one*sizeof(float));\n           }\n       }\n\n       if (iLBCdec_inst->use_enhancer == 1) {\n\n           /* post filtering */\n\n           iLBCdec_inst->last_lag =\n               enhancerInterface(data, decresidual, iLBCdec_inst);\n\n           /* synthesis filtering */\n\n           if (iLBCdec_inst->mode==20) {\n               /* Enhancer has 40 samples delay */\n               i=0;\n               syntFilter(data + i*SUBL,\n                   iLBCdec_inst->old_syntdenum +\n                   (i+iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1),\n                   SUBL, iLBCdec_inst->syntMem);\n\n\n\n\n\n               for (i=1; i < iLBCdec_inst->nsub; i++) {\n                   syntFilter(data + i*SUBL,\n                       syntdenum + (i-1)*(LPC_FILTERORDER+1),\n                       SUBL, iLBCdec_inst->syntMem);\n               }\n           } else if (iLBCdec_inst->mode==30) {\n               /* Enhancer has 80 samples delay */\n               for (i=0; i < 2; i++) {\n                   syntFilter(data + i*SUBL,\n                       iLBCdec_inst->old_syntdenum +\n                       (i+iLBCdec_inst->nsub-2)*(LPC_FILTERORDER+1),\n                       SUBL, iLBCdec_inst->syntMem);\n               }\n               for (i=2; i < iLBCdec_inst->nsub; i++) {\n                   syntFilter(data + i*SUBL,\n                       syntdenum + (i-2)*(LPC_FILTERORDER+1), SUBL,\n                       iLBCdec_inst->syntMem);\n               }\n           }\n\n       } else {\n\n           /* Find last lag */\n           lag = 20;\n           maxcc = xCorrCoef(&decresidual[BLOCKL_MAX-ENH_BLOCKL],\n               &decresidual[BLOCKL_MAX-ENH_BLOCKL-lag], ENH_BLOCKL);\n\n           for (ilag=21; ilag<120; ilag++) {\n               cc = xCorrCoef(&decresidual[BLOCKL_MAX-ENH_BLOCKL],\n                   &decresidual[BLOCKL_MAX-ENH_BLOCKL-ilag],\n                   ENH_BLOCKL);\n\n               if (cc > maxcc) {\n                   maxcc = cc;\n                   lag = ilag;\n               }\n           }\n           iLBCdec_inst->last_lag = lag;\n\n           /* copy data and run synthesis filter */\n\n           memcpy(data, decresidual,\n               iLBCdec_inst->blockl*sizeof(float));\n           for (i=0; i < iLBCdec_inst->nsub; i++) {\n               syntFilter(data + i*SUBL,\n                   syntdenum + i*(LPC_FILTERORDER+1), SUBL,\n                   iLBCdec_inst->syntMem);\n           }\n\n\n\n\n\n       }\n\n       /* high pass filtering on output if desired, otherwise\n          copy to out */\n\n       hpOutput(data, iLBCdec_inst->blockl,\n                   decblock,iLBCdec_inst->hpomem);\n\n       /* memcpy(decblock,data,iLBCdec_inst->blockl*sizeof(float));*/\n\n       memcpy(iLBCdec_inst->old_syntdenum, syntdenum,\n\n           iLBCdec_inst->nsub*(LPC_FILTERORDER+1)*sizeof(float));\n\n       iLBCdec_inst->prev_enh_pl=0;\n\n       if (mode==0) { /* PLC was used */\n           iLBCdec_inst->prev_enh_pl=1;\n       }\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/iLBC_decode.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       iLBC_decode.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_ILBCDECODE_H\n   #define __iLBC_ILBCDECODE_H\n\n   #include \"iLBC_define.h\"\n\n   short initDecode(                   /* (o) Number of decoded\n                                              samples */\n       iLBC_Dec_Inst_t *iLBCdec_inst,  /* (i/o) Decoder instance */\n       int mode,                       /* (i) frame size mode */\n       int use_enhancer                /* (i) 1 to use enhancer\n                                              0 to run without\n                                                enhancer */\n   );\n\n   void iLBC_decode(\n       float *decblock,            /* (o) decoded signal block */\n       unsigned char *bytes,           /* (i) encoded signal bits */\n       iLBC_Dec_Inst_t *iLBCdec_inst,  /* (i/o) the decoder state\n                                                structure */\n       int mode                    /* (i) 0: bad packet, PLC,\n                                              1: normal */\n\n\n\n\n\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/iLBC_define.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       iLBC_define.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n   #include <string.h>\n\n   #ifndef __iLBC_ILBCDEFINE_H\n   #define __iLBC_ILBCDEFINE_H\n\n   /* general codec settings */\n\n   #define FS                      (float)8000.0\n   #define BLOCKL_20MS             160\n   #define BLOCKL_30MS             240\n   #define BLOCKL_MAX              240\n   #define NSUB_20MS               4\n   #define NSUB_30MS               6\n   #define NSUB_MAX            6\n   #define NASUB_20MS              2\n\n\n\n\n\n   #define NASUB_30MS              4\n   #define NASUB_MAX               4\n   #define SUBL                40\n   #define STATE_LEN               80\n   #define STATE_SHORT_LEN_30MS    58\n   #define STATE_SHORT_LEN_20MS    57\n\n   /* LPC settings */\n\n   #define LPC_FILTERORDER         10\n   #define LPC_CHIRP_SYNTDENUM     (float)0.9025\n   #define LPC_CHIRP_WEIGHTDENUM   (float)0.4222\n   #define LPC_LOOKBACK        60\n   #define LPC_N_20MS              1\n   #define LPC_N_30MS              2\n   #define LPC_N_MAX               2\n   #define LPC_ASYMDIFF        20\n   #define LPC_BW                  (float)60.0\n   #define LPC_WN                  (float)1.0001\n   #define LSF_NSPLIT              3\n   #define LSF_NUMBER_OF_STEPS     4\n   #define LPC_HALFORDER           (LPC_FILTERORDER/2)\n\n   /* cb settings */\n\n   #define CB_NSTAGES              3\n   #define CB_EXPAND               2\n   #define CB_MEML                 147\n   #define CB_FILTERLEN        2*4\n   #define CB_HALFFILTERLEN    4\n   #define CB_RESRANGE             34\n   #define CB_MAXGAIN              (float)1.3\n\n   /* enhancer */\n\n   #define ENH_BLOCKL              80  /* block length */\n   #define ENH_BLOCKL_HALF         (ENH_BLOCKL/2)\n   #define ENH_HL                  3   /* 2*ENH_HL+1 is number blocks\n                                          in said second sequence */\n   #define ENH_SLOP            2   /* max difference estimated and\n                                          correct pitch period */\n   #define ENH_PLOCSL              20  /* pitch-estimates and pitch-\n                                          locations buffer length */\n   #define ENH_OVERHANG        2\n   #define ENH_UPS0            4   /* upsampling rate */\n   #define ENH_FL0                 3   /* 2*FLO+1 is the length of\n                                          each filter */\n   #define ENH_VECTL               (ENH_BLOCKL+2*ENH_FL0)\n\n\n\n\n\n   #define ENH_CORRDIM             (2*ENH_SLOP+1)\n   #define ENH_NBLOCKS             (BLOCKL_MAX/ENH_BLOCKL)\n   #define ENH_NBLOCKS_EXTRA       5\n   #define ENH_NBLOCKS_TOT         8   /* ENH_NBLOCKS +\n                                          ENH_NBLOCKS_EXTRA */\n   #define ENH_BUFL            (ENH_NBLOCKS_TOT)*ENH_BLOCKL\n   #define ENH_ALPHA0              (float)0.05\n\n   /* Down sampling */\n\n   #define FILTERORDER_DS          7\n   #define DELAY_DS            3\n   #define FACTOR_DS               2\n\n   /* bit stream defs */\n\n   #define NO_OF_BYTES_20MS    38\n   #define NO_OF_BYTES_30MS    50\n   #define NO_OF_WORDS_20MS    19\n   #define NO_OF_WORDS_30MS    25\n   #define STATE_BITS              3\n   #define BYTE_LEN            8\n   #define ULP_CLASSES             3\n\n   /* help parameters */\n\n   #define FLOAT_MAX               (float)1.0e37\n   #define EPS                     (float)2.220446049250313e-016\n   #define PI                      (float)3.14159265358979323846\n   #define MIN_SAMPLE              -32768\n   #define MAX_SAMPLE              32767\n   #define TWO_PI                  (float)6.283185307\n   #define PI2                     (float)0.159154943\n\n   /* type definition encoder instance */\n   typedef struct iLBC_ULP_Inst_t_ {\n       int lsf_bits[6][ULP_CLASSES+2];\n       int start_bits[ULP_CLASSES+2];\n       int startfirst_bits[ULP_CLASSES+2];\n       int scale_bits[ULP_CLASSES+2];\n       int state_bits[ULP_CLASSES+2];\n       int extra_cb_index[CB_NSTAGES][ULP_CLASSES+2];\n       int extra_cb_gain[CB_NSTAGES][ULP_CLASSES+2];\n       int cb_index[NSUB_MAX][CB_NSTAGES][ULP_CLASSES+2];\n       int cb_gain[NSUB_MAX][CB_NSTAGES][ULP_CLASSES+2];\n   } iLBC_ULP_Inst_t;\n\n   /* type definition encoder instance */\n\n\n\n\n\n   typedef struct iLBC_Enc_Inst_t_ {\n\n       /* flag for frame size mode */\n       int mode;\n\n       /* basic parameters for different frame sizes */\n       int blockl;\n       int nsub;\n       int nasub;\n       int no_of_bytes, no_of_words;\n       int lpc_n;\n       int state_short_len;\n       const iLBC_ULP_Inst_t *ULP_inst;\n\n       /* analysis filter state */\n       float anaMem[LPC_FILTERORDER];\n\n       /* old lsf parameters for interpolation */\n       float lsfold[LPC_FILTERORDER];\n       float lsfdeqold[LPC_FILTERORDER];\n\n       /* signal buffer for LP analysis */\n       float lpc_buffer[LPC_LOOKBACK + BLOCKL_MAX];\n\n       /* state of input HP filter */\n       float hpimem[4];\n\n   } iLBC_Enc_Inst_t;\n\n   /* type definition decoder instance */\n   typedef struct iLBC_Dec_Inst_t_ {\n\n       /* flag for frame size mode */\n       int mode;\n\n       /* basic parameters for different frame sizes */\n       int blockl;\n       int nsub;\n       int nasub;\n       int no_of_bytes, no_of_words;\n       int lpc_n;\n       int state_short_len;\n       const iLBC_ULP_Inst_t *ULP_inst;\n\n       /* synthesis filter state */\n       float syntMem[LPC_FILTERORDER];\n\n       /* old LSF for interpolation */\n\n\n\n\n\n       float lsfdeqold[LPC_FILTERORDER];\n\n       /* pitch lag estimated in enhancer and used in PLC */\n       int last_lag;\n\n       /* PLC state information */\n       int prevLag, consPLICount, prevPLI, prev_enh_pl;\n       float prevLpc[LPC_FILTERORDER+1];\n       float prevResidual[NSUB_MAX*SUBL];\n       float per;\n       unsigned long seed;\n\n       /* previous synthesis filter parameters */\n       float old_syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];\n\n       /* state of output HP filter */\n       float hpomem[4];\n\n       /* enhancer state information */\n       int use_enhancer;\n       float enh_buf[ENH_BUFL];\n       float enh_period[ENH_NBLOCKS_TOT];\n\n   } iLBC_Dec_Inst_t;\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/iLBC_encode.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       iLBC_encode.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <math.h>\n   #include <stdlib.h>\n   #include <string.h>\n\n   #include \"iLBC_define.h\"\n   #include \"LPCencode.h\"\n   #include \"FrameClassify.h\"\n   #include \"StateSearchW.h\"\n   #include \"StateConstructW.h\"\n   #include \"helpfun.h\"\n   #include \"constants.h\"\n   #include \"packing.h\"\n   #include \"iCBSearch.h\"\n   #include \"iCBConstruct.h\"\n   #include \"hpInput.h\"\n   #include \"anaFilter.h\"\n   #include \"syntFilter.h\"\n\n   /*----------------------------------------------------------------*\n    *  Initiation of encoder instance.\n    *---------------------------------------------------------------*/\n\n   short initEncode(                   /* (o) Number of bytes\n                                              encoded */\n       iLBC_Enc_Inst_t *iLBCenc_inst,  /* (i/o) Encoder instance */\n       int mode                    /* (i) frame size mode */\n   ){\n       iLBCenc_inst->mode = mode;\n       if (mode==30) {\n           iLBCenc_inst->blockl = BLOCKL_30MS;\n           iLBCenc_inst->nsub = NSUB_30MS;\n           iLBCenc_inst->nasub = NASUB_30MS;\n           iLBCenc_inst->lpc_n = LPC_N_30MS;\n           iLBCenc_inst->no_of_bytes = NO_OF_BYTES_30MS;\n           iLBCenc_inst->no_of_words = NO_OF_WORDS_30MS;\n\n\n\n\n\n           iLBCenc_inst->state_short_len=STATE_SHORT_LEN_30MS;\n           /* ULP init */\n           iLBCenc_inst->ULP_inst=&ULP_30msTbl;\n       }\n       else if (mode==20) {\n           iLBCenc_inst->blockl = BLOCKL_20MS;\n           iLBCenc_inst->nsub = NSUB_20MS;\n           iLBCenc_inst->nasub = NASUB_20MS;\n           iLBCenc_inst->lpc_n = LPC_N_20MS;\n           iLBCenc_inst->no_of_bytes = NO_OF_BYTES_20MS;\n           iLBCenc_inst->no_of_words = NO_OF_WORDS_20MS;\n           iLBCenc_inst->state_short_len=STATE_SHORT_LEN_20MS;\n           /* ULP init */\n           iLBCenc_inst->ULP_inst=&ULP_20msTbl;\n       }\n       else {\n           exit(2);\n       }\n\n       memset((*iLBCenc_inst).anaMem, 0,\n           LPC_FILTERORDER*sizeof(float));\n       memcpy((*iLBCenc_inst).lsfold, lsfmeanTbl,\n           LPC_FILTERORDER*sizeof(float));\n       memcpy((*iLBCenc_inst).lsfdeqold, lsfmeanTbl,\n           LPC_FILTERORDER*sizeof(float));\n       memset((*iLBCenc_inst).lpc_buffer, 0,\n           (LPC_LOOKBACK+BLOCKL_MAX)*sizeof(float));\n       memset((*iLBCenc_inst).hpimem, 0, 4*sizeof(float));\n\n       return (short)(iLBCenc_inst->no_of_bytes);\n   }\n\n   /*----------------------------------------------------------------*\n    *  main encoder function\n    *---------------------------------------------------------------*/\n\n   void iLBC_encode(\n       unsigned char *bytes,           /* (o) encoded data bits iLBC */\n       float *block,                   /* (o) speech vector to\n                                              encode */\n       iLBC_Enc_Inst_t *iLBCenc_inst   /* (i/o) the general encoder\n                                              state */\n   ){\n\n       float data[BLOCKL_MAX];\n       float residual[BLOCKL_MAX], reverseResidual[BLOCKL_MAX];\n\n       int start, idxForMax, idxVec[STATE_LEN];\n\n\n\n\n\n       float reverseDecresidual[BLOCKL_MAX], mem[CB_MEML];\n       int n, k, meml_gotten, Nfor, Nback, i, pos;\n       int gain_index[CB_NSTAGES*NASUB_MAX],\n           extra_gain_index[CB_NSTAGES];\n       int cb_index[CB_NSTAGES*NASUB_MAX],extra_cb_index[CB_NSTAGES];\n       int lsf_i[LSF_NSPLIT*LPC_N_MAX];\n       unsigned char *pbytes;\n       int diff, start_pos, state_first;\n       float en1, en2;\n       int index, ulp, firstpart;\n       int subcount, subframe;\n       float weightState[LPC_FILTERORDER];\n       float syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)];\n       float weightdenum[NSUB_MAX*(LPC_FILTERORDER+1)];\n       float decresidual[BLOCKL_MAX];\n\n       /* high pass filtering of input signal if such is not done\n              prior to calling this function */\n\n       hpInput(block, iLBCenc_inst->blockl,\n                   data, (*iLBCenc_inst).hpimem);\n\n       /* otherwise simply copy */\n\n       /*memcpy(data,block,iLBCenc_inst->blockl*sizeof(float));*/\n\n       /* LPC of hp filtered input data */\n\n       LPCencode(syntdenum, weightdenum, lsf_i, data, iLBCenc_inst);\n\n\n       /* inverse filter to get residual */\n\n       for (n=0; n<iLBCenc_inst->nsub; n++) {\n           anaFilter(&data[n*SUBL], &syntdenum[n*(LPC_FILTERORDER+1)],\n               SUBL, &residual[n*SUBL], iLBCenc_inst->anaMem);\n       }\n\n       /* find state location */\n\n       start = FrameClassify(iLBCenc_inst, residual);\n\n       /* check if state should be in first or last part of the\n       two subframes */\n\n       diff = STATE_LEN - iLBCenc_inst->state_short_len;\n       en1 = 0;\n       index = (start-1)*SUBL;\n\n\n\n\n\n       for (i = 0; i < iLBCenc_inst->state_short_len; i++) {\n           en1 += residual[index+i]*residual[index+i];\n       }\n       en2 = 0;\n       index = (start-1)*SUBL+diff;\n       for (i = 0; i < iLBCenc_inst->state_short_len; i++) {\n           en2 += residual[index+i]*residual[index+i];\n       }\n\n\n       if (en1 > en2) {\n           state_first = 1;\n           start_pos = (start-1)*SUBL;\n       } else {\n           state_first = 0;\n           start_pos = (start-1)*SUBL + diff;\n       }\n\n       /* scalar quantization of state */\n\n       StateSearchW(iLBCenc_inst, &residual[start_pos],\n           &syntdenum[(start-1)*(LPC_FILTERORDER+1)],\n           &weightdenum[(start-1)*(LPC_FILTERORDER+1)], &idxForMax,\n           idxVec, iLBCenc_inst->state_short_len, state_first);\n\n       StateConstructW(idxForMax, idxVec,\n           &syntdenum[(start-1)*(LPC_FILTERORDER+1)],\n           &decresidual[start_pos], iLBCenc_inst->state_short_len);\n\n       /* predictive quantization in state */\n\n       if (state_first) { /* put adaptive part in the end */\n\n           /* setup memory */\n\n           memset(mem, 0,\n               (CB_MEML-iLBCenc_inst->state_short_len)*sizeof(float));\n           memcpy(mem+CB_MEML-iLBCenc_inst->state_short_len,\n               decresidual+start_pos,\n               iLBCenc_inst->state_short_len*sizeof(float));\n           memset(weightState, 0, LPC_FILTERORDER*sizeof(float));\n\n           /* encode sub-frames */\n\n           iCBSearch(iLBCenc_inst, extra_cb_index, extra_gain_index,\n               &residual[start_pos+iLBCenc_inst->state_short_len],\n               mem+CB_MEML-stMemLTbl,\n               stMemLTbl, diff, CB_NSTAGES,\n\n\n\n\n\n               &weightdenum[start*(LPC_FILTERORDER+1)],\n               weightState, 0);\n\n           /* construct decoded vector */\n\n           iCBConstruct(\n               &decresidual[start_pos+iLBCenc_inst->state_short_len],\n               extra_cb_index, extra_gain_index,\n               mem+CB_MEML-stMemLTbl,\n               stMemLTbl, diff, CB_NSTAGES);\n\n       }\n       else { /* put adaptive part in the beginning */\n\n           /* create reversed vectors for prediction */\n\n           for (k=0; k<diff; k++) {\n               reverseResidual[k] = residual[(start+1)*SUBL-1\n                   -(k+iLBCenc_inst->state_short_len)];\n           }\n\n           /* setup memory */\n\n           meml_gotten = iLBCenc_inst->state_short_len;\n           for (k=0; k<meml_gotten; k++) {\n               mem[CB_MEML-1-k] = decresidual[start_pos + k];\n           }\n           memset(mem, 0, (CB_MEML-k)*sizeof(float));\n           memset(weightState, 0, LPC_FILTERORDER*sizeof(float));\n\n           /* encode sub-frames */\n\n           iCBSearch(iLBCenc_inst, extra_cb_index, extra_gain_index,\n               reverseResidual, mem+CB_MEML-stMemLTbl, stMemLTbl,\n               diff, CB_NSTAGES,\n               &weightdenum[(start-1)*(LPC_FILTERORDER+1)],\n               weightState, 0);\n\n           /* construct decoded vector */\n\n           iCBConstruct(reverseDecresidual, extra_cb_index,\n               extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl,\n               diff, CB_NSTAGES);\n\n           /* get decoded residual from reversed vector */\n\n           for (k=0; k<diff; k++) {\n               decresidual[start_pos-1-k] = reverseDecresidual[k];\n\n\n\n\n\n           }\n       }\n\n       /* counter for predicted sub-frames */\n\n       subcount=0;\n\n       /* forward prediction of sub-frames */\n\n       Nfor = iLBCenc_inst->nsub-start-1;\n\n\n       if ( Nfor > 0 ) {\n\n           /* setup memory */\n\n           memset(mem, 0, (CB_MEML-STATE_LEN)*sizeof(float));\n           memcpy(mem+CB_MEML-STATE_LEN, decresidual+(start-1)*SUBL,\n               STATE_LEN*sizeof(float));\n           memset(weightState, 0, LPC_FILTERORDER*sizeof(float));\n\n           /* loop over sub-frames to encode */\n\n           for (subframe=0; subframe<Nfor; subframe++) {\n\n               /* encode sub-frame */\n\n               iCBSearch(iLBCenc_inst, cb_index+subcount*CB_NSTAGES,\n                   gain_index+subcount*CB_NSTAGES,\n                   &residual[(start+1+subframe)*SUBL],\n                   mem+CB_MEML-memLfTbl[subcount],\n                   memLfTbl[subcount], SUBL, CB_NSTAGES,\n                   &weightdenum[(start+1+subframe)*\n                               (LPC_FILTERORDER+1)],\n                   weightState, subcount+1);\n\n               /* construct decoded vector */\n\n               iCBConstruct(&decresidual[(start+1+subframe)*SUBL],\n                   cb_index+subcount*CB_NSTAGES,\n                   gain_index+subcount*CB_NSTAGES,\n                   mem+CB_MEML-memLfTbl[subcount],\n                   memLfTbl[subcount], SUBL, CB_NSTAGES);\n\n               /* update memory */\n\n               memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float));\n               memcpy(mem+CB_MEML-SUBL,\n\n\n\n\n\n                   &decresidual[(start+1+subframe)*SUBL],\n                   SUBL*sizeof(float));\n               memset(weightState, 0, LPC_FILTERORDER*sizeof(float));\n\n               subcount++;\n           }\n       }\n\n\n       /* backward prediction of sub-frames */\n\n       Nback = start-1;\n\n\n       if ( Nback > 0 ) {\n\n           /* create reverse order vectors */\n\n           for (n=0; n<Nback; n++) {\n               for (k=0; k<SUBL; k++) {\n                   reverseResidual[n*SUBL+k] =\n                       residual[(start-1)*SUBL-1-n*SUBL-k];\n                   reverseDecresidual[n*SUBL+k] =\n                       decresidual[(start-1)*SUBL-1-n*SUBL-k];\n               }\n           }\n\n           /* setup memory */\n\n           meml_gotten = SUBL*(iLBCenc_inst->nsub+1-start);\n\n\n           if ( meml_gotten > CB_MEML ) {\n               meml_gotten=CB_MEML;\n           }\n           for (k=0; k<meml_gotten; k++) {\n               mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k];\n           }\n           memset(mem, 0, (CB_MEML-k)*sizeof(float));\n           memset(weightState, 0, LPC_FILTERORDER*sizeof(float));\n\n           /* loop over sub-frames to encode */\n\n           for (subframe=0; subframe<Nback; subframe++) {\n\n               /* encode sub-frame */\n\n               iCBSearch(iLBCenc_inst, cb_index+subcount*CB_NSTAGES,\n\n\n\n\n\n                   gain_index+subcount*CB_NSTAGES,\n                   &reverseResidual[subframe*SUBL],\n                   mem+CB_MEML-memLfTbl[subcount],\n                   memLfTbl[subcount], SUBL, CB_NSTAGES,\n                   &weightdenum[(start-2-subframe)*\n                               (LPC_FILTERORDER+1)],\n                   weightState, subcount+1);\n\n               /* construct decoded vector */\n\n               iCBConstruct(&reverseDecresidual[subframe*SUBL],\n                   cb_index+subcount*CB_NSTAGES,\n                   gain_index+subcount*CB_NSTAGES,\n                   mem+CB_MEML-memLfTbl[subcount],\n                   memLfTbl[subcount], SUBL, CB_NSTAGES);\n\n               /* update memory */\n\n               memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float));\n               memcpy(mem+CB_MEML-SUBL,\n                   &reverseDecresidual[subframe*SUBL],\n                   SUBL*sizeof(float));\n               memset(weightState, 0, LPC_FILTERORDER*sizeof(float));\n\n               subcount++;\n\n           }\n\n           /* get decoded residual from reversed vector */\n\n           for (i=0; i<SUBL*Nback; i++) {\n               decresidual[SUBL*Nback - i - 1] =\n                   reverseDecresidual[i];\n           }\n       }\n       /* end encoding part */\n\n       /* adjust index */\n       index_conv_enc(cb_index);\n\n       /* pack bytes */\n\n       pbytes=bytes;\n       pos=0;\n\n       /* loop over the 3 ULP classes */\n\n       for (ulp=0; ulp<3; ulp++) {\n\n\n\n\n\n\n           /* LSF */\n           for (k=0; k<LSF_NSPLIT*iLBCenc_inst->lpc_n; k++) {\n               packsplit(&lsf_i[k], &firstpart, &lsf_i[k],\n                   iLBCenc_inst->ULP_inst->lsf_bits[k][ulp],\n                   iLBCenc_inst->ULP_inst->lsf_bits[k][ulp]+\n                   iLBCenc_inst->ULP_inst->lsf_bits[k][ulp+1]+\n                   iLBCenc_inst->ULP_inst->lsf_bits[k][ulp+2]);\n               dopack( &pbytes, firstpart,\n                   iLBCenc_inst->ULP_inst->lsf_bits[k][ulp], &pos);\n           }\n\n           /* Start block info */\n\n           packsplit(&start, &firstpart, &start,\n               iLBCenc_inst->ULP_inst->start_bits[ulp],\n               iLBCenc_inst->ULP_inst->start_bits[ulp]+\n               iLBCenc_inst->ULP_inst->start_bits[ulp+1]+\n               iLBCenc_inst->ULP_inst->start_bits[ulp+2]);\n           dopack( &pbytes, firstpart,\n               iLBCenc_inst->ULP_inst->start_bits[ulp], &pos);\n\n           packsplit(&state_first, &firstpart, &state_first,\n               iLBCenc_inst->ULP_inst->startfirst_bits[ulp],\n               iLBCenc_inst->ULP_inst->startfirst_bits[ulp]+\n               iLBCenc_inst->ULP_inst->startfirst_bits[ulp+1]+\n               iLBCenc_inst->ULP_inst->startfirst_bits[ulp+2]);\n           dopack( &pbytes, firstpart,\n               iLBCenc_inst->ULP_inst->startfirst_bits[ulp], &pos);\n\n           packsplit(&idxForMax, &firstpart, &idxForMax,\n               iLBCenc_inst->ULP_inst->scale_bits[ulp],\n               iLBCenc_inst->ULP_inst->scale_bits[ulp]+\n               iLBCenc_inst->ULP_inst->scale_bits[ulp+1]+\n               iLBCenc_inst->ULP_inst->scale_bits[ulp+2]);\n           dopack( &pbytes, firstpart,\n               iLBCenc_inst->ULP_inst->scale_bits[ulp], &pos);\n\n           for (k=0; k<iLBCenc_inst->state_short_len; k++) {\n               packsplit(idxVec+k, &firstpart, idxVec+k,\n                   iLBCenc_inst->ULP_inst->state_bits[ulp],\n                   iLBCenc_inst->ULP_inst->state_bits[ulp]+\n                   iLBCenc_inst->ULP_inst->state_bits[ulp+1]+\n                   iLBCenc_inst->ULP_inst->state_bits[ulp+2]);\n               dopack( &pbytes, firstpart,\n                   iLBCenc_inst->ULP_inst->state_bits[ulp], &pos);\n           }\n\n\n\n\n\n\n           /* 23/22 (20ms/30ms) sample block */\n\n           for (k=0;k<CB_NSTAGES;k++) {\n               packsplit(extra_cb_index+k, &firstpart,\n                   extra_cb_index+k,\n                   iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp],\n                   iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp]+\n                   iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp+1]+\n                   iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp+2]);\n               dopack( &pbytes, firstpart,\n                   iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp],\n                   &pos);\n           }\n\n           for (k=0;k<CB_NSTAGES;k++) {\n               packsplit(extra_gain_index+k, &firstpart,\n                   extra_gain_index+k,\n                   iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp],\n                   iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp]+\n                   iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp+1]+\n                   iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp+2]);\n               dopack( &pbytes, firstpart,\n                   iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp],\n                   &pos);\n           }\n\n           /* The two/four (20ms/30ms) 40 sample sub-blocks */\n\n           for (i=0; i<iLBCenc_inst->nasub; i++) {\n               for (k=0; k<CB_NSTAGES; k++) {\n                   packsplit(cb_index+i*CB_NSTAGES+k, &firstpart,\n                       cb_index+i*CB_NSTAGES+k,\n                       iLBCenc_inst->ULP_inst->cb_index[i][k][ulp],\n                       iLBCenc_inst->ULP_inst->cb_index[i][k][ulp]+\n                       iLBCenc_inst->ULP_inst->cb_index[i][k][ulp+1]+\n                       iLBCenc_inst->ULP_inst->cb_index[i][k][ulp+2]);\n                   dopack( &pbytes, firstpart,\n                       iLBCenc_inst->ULP_inst->cb_index[i][k][ulp],\n                       &pos);\n               }\n           }\n\n           for (i=0; i<iLBCenc_inst->nasub; i++) {\n               for (k=0; k<CB_NSTAGES; k++) {\n                   packsplit(gain_index+i*CB_NSTAGES+k, &firstpart,\n                       gain_index+i*CB_NSTAGES+k,\n                       iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp],\n                       iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp]+\n\n\n\n\n\n                       iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp+1]+\n                       iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp+2]);\n                   dopack( &pbytes, firstpart,\n                       iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp],\n                       &pos);\n               }\n           }\n       }\n\n       /* set the last bit to zero (otherwise the decoder\n          will treat it as a lost frame) */\n       dopack( &pbytes, 0, 1, &pos);\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/iLBC_encode.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       iLBC_encode.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_ILBCENCODE_H\n   #define __iLBC_ILBCENCODE_H\n\n   #include \"iLBC_define.h\"\n\n   short initEncode(                   /* (o) Number of bytes\n                                              encoded */\n       iLBC_Enc_Inst_t *iLBCenc_inst,  /* (i/o) Encoder instance */\n       int mode                    /* (i) frame size mode */\n   );\n\n   void iLBC_encode(\n\n       unsigned char *bytes,           /* (o) encoded data bits iLBC */\n       float *block,                   /* (o) speech vector to\n                                              encode */\n       iLBC_Enc_Inst_t *iLBCenc_inst   /* (i/o) the general encoder\n                                              state */\n   );\n\n   #endif\n\n\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/iLBC_test.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       iLBC_test.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <math.h>\n   #include <stdlib.h>\n   #include <stdio.h>\n   #include <string.h>\n   #include \"iLBC_define.h\"\n   #include \"iLBC_encode.h\"\n   #include \"iLBC_decode.h\"\n\n   /* Runtime statistics */\n   #include <time.h>\n\n   #define ILBCNOOFWORDS_MAX   (NO_OF_BYTES_30MS/2)\n\n   /*----------------------------------------------------------------*\n    *  Encoder interface function\n\n\n\n\n\n    *---------------------------------------------------------------*/\n\n   short encode(   /* (o) Number of bytes encoded */\n       iLBC_Enc_Inst_t *iLBCenc_inst,\n                                   /* (i/o) Encoder instance */\n       short *encoded_data,    /* (o) The encoded bytes */\n       short *data                 /* (i) The signal block to encode*/\n   ){\n       float block[BLOCKL_MAX];\n       int k;\n\n       /* convert signal to float */\n\n       for (k=0; k<iLBCenc_inst->blockl; k++)\n           block[k] = (float)data[k];\n\n       /* do the actual encoding */\n\n       iLBC_encode((unsigned char *)encoded_data, block, iLBCenc_inst);\n\n\n       return (iLBCenc_inst->no_of_bytes);\n   }\n\n   /*----------------------------------------------------------------*\n    *  Decoder interface function\n    *---------------------------------------------------------------*/\n\n   short decode(       /* (o) Number of decoded samples */\n       iLBC_Dec_Inst_t *iLBCdec_inst,  /* (i/o) Decoder instance */\n       short *decoded_data,        /* (o) Decoded signal block*/\n       short *encoded_data,        /* (i) Encoded bytes */\n       short mode                       /* (i) 0=PL, 1=Normal */\n   ){\n       int k;\n       float decblock[BLOCKL_MAX], dtmp;\n\n       /* check if mode is valid */\n\n       if (mode<0 || mode>1) {\n           printf(\"\\nERROR - Wrong mode - 0, 1 allowed\\n\"); exit(3);}\n\n       /* do actual decoding of block */\n\n       iLBC_decode(decblock, (unsigned char *)encoded_data,\n           iLBCdec_inst, mode);\n\n       /* convert to short */\n\n\n\n\n\n       for (k=0; k<iLBCdec_inst->blockl; k++){\n           dtmp=decblock[k];\n\n           if (dtmp<MIN_SAMPLE)\n               dtmp=MIN_SAMPLE;\n           else if (dtmp>MAX_SAMPLE)\n               dtmp=MAX_SAMPLE;\n           decoded_data[k] = (short) dtmp;\n       }\n\n       return (iLBCdec_inst->blockl);\n   }\n\n   /*---------------------------------------------------------------*\n    *  Main program to test iLBC encoding and decoding\n    *\n    *  Usage:\n    *    exefile_name.exe <infile> <bytefile> <outfile> <channel>\n    *\n    *    <infile>   : Input file, speech for encoder (16-bit pcm file)\n    *    <bytefile> : Bit stream output from the encoder\n    *    <outfile>  : Output file, decoded speech (16-bit pcm file)\n    *    <channel>  : Bit error file, optional (16-bit)\n    *                     1 - Packet received correctly\n    *                     0 - Packet Lost\n    *\n    *--------------------------------------------------------------*/\n\n   int main(int argc, char* argv[])\n   {\n\n       /* Runtime statistics */\n\n       float starttime;\n       float runtime;\n       float outtime;\n\n       FILE *ifileid,*efileid,*ofileid, *cfileid;\n       short data[BLOCKL_MAX];\n       short encoded_data[ILBCNOOFWORDS_MAX], decoded_data[BLOCKL_MAX];\n       int len;\n       short pli, mode;\n       int blockcount = 0;\n       int packetlosscount = 0;\n\n       /* Create structs */\n       iLBC_Enc_Inst_t Enc_Inst;\n       iLBC_Dec_Inst_t Dec_Inst;\n\n\n\n\n\n       /* get arguments and open files */\n\n       if ((argc!=5) && (argc!=6)) {\n           fprintf(stderr,\n           \"\\n*-----------------------------------------------*\\n\");\n           fprintf(stderr,\n           \"   %s <20,30> input encoded decoded (channel)\\n\\n\",\n               argv[0]);\n           fprintf(stderr,\n           \"   mode    : Frame size for the encoding/decoding\\n\");\n           fprintf(stderr,\n           \"                 20 - 20 ms\\n\");\n           fprintf(stderr,\n           \"                 30 - 30 ms\\n\");\n           fprintf(stderr,\n           \"   input   : Speech for encoder (16-bit pcm file)\\n\");\n           fprintf(stderr,\n           \"   encoded : Encoded bit stream\\n\");\n           fprintf(stderr,\n           \"   decoded : Decoded speech (16-bit pcm file)\\n\");\n           fprintf(stderr,\n           \"   channel : Packet loss pattern, optional (16-bit)\\n\");\n           fprintf(stderr,\n           \"                  1 - Packet received correctly\\n\");\n           fprintf(stderr,\n           \"                  0 - Packet Lost\\n\");\n           fprintf(stderr,\n           \"*-----------------------------------------------*\\n\\n\");\n           exit(1);\n       }\n       mode=atoi(argv[1]);\n       if (mode != 20 && mode != 30) {\n           fprintf(stderr,\"Wrong mode %s, must be 20, or 30\\n\",\n               argv[1]);\n           exit(2);\n       }\n       if ( (ifileid=fopen(argv[2],\"rb\")) == NULL) {\n           fprintf(stderr,\"Cannot open input file %s\\n\", argv[2]);\n           exit(2);}\n       if ( (efileid=fopen(argv[3],\"wb\")) == NULL) {\n           fprintf(stderr, \"Cannot open encoded file %s\\n\",\n               argv[3]); exit(1);}\n       if ( (ofileid=fopen(argv[4],\"wb\")) == NULL) {\n           fprintf(stderr, \"Cannot open decoded file %s\\n\",\n               argv[4]); exit(1);}\n       if (argc==6) {\n           if( (cfileid=fopen(argv[5],\"rb\")) == NULL) {\n               fprintf(stderr, \"Cannot open channel file %s\\n\",\n\n\n\n\n\n                   argv[5]);\n               exit(1);\n           }\n       } else {\n           cfileid=NULL;\n       }\n\n       /* print info */\n\n       fprintf(stderr, \"\\n\");\n       fprintf(stderr,\n           \"*---------------------------------------------------*\\n\");\n       fprintf(stderr,\n           \"*                                                   *\\n\");\n       fprintf(stderr,\n           \"*      iLBC test program                            *\\n\");\n       fprintf(stderr,\n           \"*                                                   *\\n\");\n       fprintf(stderr,\n           \"*                                                   *\\n\");\n       fprintf(stderr,\n           \"*---------------------------------------------------*\\n\");\n       fprintf(stderr,\"\\nMode           : %2d ms\\n\", mode);\n       fprintf(stderr,\"Input file     : %s\\n\", argv[2]);\n       fprintf(stderr,\"Encoded file   : %s\\n\", argv[3]);\n       fprintf(stderr,\"Output file    : %s\\n\", argv[4]);\n       if (argc==6) {\n           fprintf(stderr,\"Channel file   : %s\\n\", argv[5]);\n       }\n       fprintf(stderr,\"\\n\");\n\n       /* Initialization */\n\n       initEncode(&Enc_Inst, mode);\n       initDecode(&Dec_Inst, mode, 1);\n\n       /* Runtime statistics */\n\n       starttime=clock()/(float)CLOCKS_PER_SEC;\n\n       /* loop over input blocks */\n\n       while (fread(data,sizeof(short),Enc_Inst.blockl,ifileid)==\n               (size_t)Enc_Inst.blockl) {\n\n           blockcount++;\n\n           /* encoding */\n\n\n\n\n\n           fprintf(stderr, \"--- Encoding block %i --- \",blockcount);\n           len=encode(&Enc_Inst, encoded_data, data);\n           fprintf(stderr, \"\\r\");\n\n           /* write byte file */\n\n           fwrite(encoded_data, sizeof(unsigned char), len, efileid);\n\n           /* get channel data if provided */\n           if (argc==6) {\n               if (fread(&pli, sizeof(short), 1, cfileid)) {\n                   if ((pli!=0)&&(pli!=1)) {\n                       fprintf(stderr, \"Error in channel file\\n\");\n                       exit(0);\n                   }\n                   if (pli==0) {\n                       /* Packet loss -> remove info from frame */\n                       memset(encoded_data, 0,\n                           sizeof(short)*ILBCNOOFWORDS_MAX);\n                       packetlosscount++;\n                   }\n               } else {\n                   fprintf(stderr, \"Error. Channel file too short\\n\");\n                   exit(0);\n               }\n           } else {\n               pli=1;\n           }\n\n           /* decoding */\n\n           fprintf(stderr, \"--- Decoding block %i --- \",blockcount);\n\n           len=decode(&Dec_Inst, decoded_data, encoded_data, pli);\n           fprintf(stderr, \"\\r\");\n\n           /* write output file */\n\n           fwrite(decoded_data,sizeof(short),len,ofileid);\n       }\n\n       /* Runtime statistics */\n\n       runtime = (float)(clock()/(float)CLOCKS_PER_SEC-starttime);\n       outtime = (float)((float)blockcount*(float)mode/1000.0);\n       printf(\"\\n\\nLength of speech file: %.1f s\\n\", outtime);\n       printf(\"Packet loss          : %.1f%%\\n\",\n           100.0*(float)packetlosscount/(float)blockcount);\n\n\n\n\n\n       printf(\"Time to run iLBC     :\");\n       printf(\" %.1f s (%.1f %% of realtime)\\n\\n\", runtime,\n           (100*runtime/outtime));\n\n       /* close files */\n\n       fclose(ifileid);  fclose(efileid); fclose(ofileid);\n       if (argc==6) {\n           fclose(cfileid);\n       }\n       return(0);\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/lsf.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       lsf.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <string.h>\n\n\n\n\n\n   #include <math.h>\n\n   #include \"iLBC_define.h\"\n\n   /*----------------------------------------------------------------*\n    *  conversion from lpc coefficients to lsf coefficients\n    *---------------------------------------------------------------*/\n\n   void a2lsf(\n       float *freq,/* (o) lsf coefficients */\n       float *a    /* (i) lpc coefficients */\n   ){\n       float steps[LSF_NUMBER_OF_STEPS] =\n           {(float)0.00635, (float)0.003175, (float)0.0015875,\n           (float)0.00079375};\n       float step;\n       int step_idx;\n       int lsp_index;\n       float p[LPC_HALFORDER];\n       float q[LPC_HALFORDER];\n       float p_pre[LPC_HALFORDER];\n       float q_pre[LPC_HALFORDER];\n       float old_p, old_q, *old;\n       float *pq_coef;\n       float omega, old_omega;\n       int i;\n       float hlp, hlp1, hlp2, hlp3, hlp4, hlp5;\n\n       for (i=0; i<LPC_HALFORDER; i++) {\n           p[i] = (float)-1.0 * (a[i + 1] + a[LPC_FILTERORDER - i]);\n           q[i] = a[LPC_FILTERORDER - i] - a[i + 1];\n       }\n\n       p_pre[0] = (float)-1.0 - p[0];\n       p_pre[1] = - p_pre[0] - p[1];\n       p_pre[2] = - p_pre[1] - p[2];\n       p_pre[3] = - p_pre[2] - p[3];\n       p_pre[4] = - p_pre[3] - p[4];\n       p_pre[4] = p_pre[4] / 2;\n\n       q_pre[0] = (float)1.0 - q[0];\n       q_pre[1] = q_pre[0] - q[1];\n       q_pre[2] = q_pre[1] - q[2];\n       q_pre[3] = q_pre[2] - q[3];\n       q_pre[4] = q_pre[3] - q[4];\n       q_pre[4] = q_pre[4] / 2;\n\n       omega = 0.0;\n\n\n\n\n\n       old_omega = 0.0;\n\n       old_p = FLOAT_MAX;\n       old_q = FLOAT_MAX;\n\n       /* Here we loop through lsp_index to find all the\n          LPC_FILTERORDER roots for omega. */\n\n       for (lsp_index = 0; lsp_index<LPC_FILTERORDER; lsp_index++) {\n\n           /* Depending on lsp_index being even or odd, we\n           alternatively solve the roots for the two LSP equations. */\n\n\n           if ((lsp_index & 0x1) == 0) {\n               pq_coef = p_pre;\n               old = &old_p;\n           } else {\n               pq_coef = q_pre;\n               old = &old_q;\n           }\n\n           /* Start with low resolution grid */\n\n           for (step_idx = 0, step = steps[step_idx];\n               step_idx < LSF_NUMBER_OF_STEPS;){\n\n               /*  cos(10piw) + pq(0)cos(8piw) + pq(1)cos(6piw) +\n               pq(2)cos(4piw) + pq(3)cod(2piw) + pq(4) */\n\n               hlp = (float)cos(omega * TWO_PI);\n               hlp1 = (float)2.0 * hlp + pq_coef[0];\n               hlp2 = (float)2.0 * hlp * hlp1 - (float)1.0 +\n                   pq_coef[1];\n               hlp3 = (float)2.0 * hlp * hlp2 - hlp1 + pq_coef[2];\n               hlp4 = (float)2.0 * hlp * hlp3 - hlp2 + pq_coef[3];\n               hlp5 = hlp * hlp4 - hlp3 + pq_coef[4];\n\n\n               if (((hlp5 * (*old)) <= 0.0) || (omega >= 0.5)){\n\n                   if (step_idx == (LSF_NUMBER_OF_STEPS - 1)){\n\n                       if (fabs(hlp5) >= fabs(*old)) {\n                           freq[lsp_index] = omega - step;\n                       } else {\n                           freq[lsp_index] = omega;\n                       }\n\n\n\n\n\n\n\n                       if ((*old) >= 0.0){\n                           *old = (float)-1.0 * FLOAT_MAX;\n                       } else {\n                           *old = FLOAT_MAX;\n                       }\n\n                       omega = old_omega;\n                       step_idx = 0;\n\n                       step_idx = LSF_NUMBER_OF_STEPS;\n                   } else {\n\n                       if (step_idx == 0) {\n                           old_omega = omega;\n                       }\n\n                       step_idx++;\n                       omega -= steps[step_idx];\n\n                       /* Go back one grid step */\n\n                       step = steps[step_idx];\n                   }\n               } else {\n\n               /* increment omega until they are of different sign,\n               and we know there is at least one root between omega\n               and old_omega */\n                   *old = hlp5;\n                   omega += step;\n               }\n           }\n       }\n\n       for (i = 0; i<LPC_FILTERORDER; i++) {\n           freq[i] = freq[i] * TWO_PI;\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  conversion from lsf coefficients to lpc coefficients\n    *---------------------------------------------------------------*/\n\n   void lsf2a(\n       float *a_coef,  /* (o) lpc coefficients */\n       float *freq     /* (i) lsf coefficients */\n\n\n\n\n\n   ){\n       int i, j;\n       float hlp;\n       float p[LPC_HALFORDER], q[LPC_HALFORDER];\n       float a[LPC_HALFORDER + 1], a1[LPC_HALFORDER],\n           a2[LPC_HALFORDER];\n       float b[LPC_HALFORDER + 1], b1[LPC_HALFORDER],\n           b2[LPC_HALFORDER];\n\n       for (i=0; i<LPC_FILTERORDER; i++) {\n           freq[i] = freq[i] * PI2;\n       }\n\n       /* Check input for ill-conditioned cases.  This part is not\n       found in the TIA standard.  It involves the following 2 IF\n       blocks.  If \"freq\" is judged ill-conditioned, then we first\n       modify freq[0] and freq[LPC_HALFORDER-1] (normally\n       LPC_HALFORDER = 10 for LPC applications), then we adjust\n       the other \"freq\" values slightly */\n\n\n       if ((freq[0] <= 0.0) || (freq[LPC_FILTERORDER - 1] >= 0.5)){\n\n\n           if (freq[0] <= 0.0) {\n               freq[0] = (float)0.022;\n           }\n\n\n           if (freq[LPC_FILTERORDER - 1] >= 0.5) {\n               freq[LPC_FILTERORDER - 1] = (float)0.499;\n           }\n\n           hlp = (freq[LPC_FILTERORDER - 1] - freq[0]) /\n               (float) (LPC_FILTERORDER - 1);\n\n           for (i=1; i<LPC_FILTERORDER; i++) {\n               freq[i] = freq[i - 1] + hlp;\n           }\n       }\n\n       memset(a1, 0, LPC_HALFORDER*sizeof(float));\n       memset(a2, 0, LPC_HALFORDER*sizeof(float));\n       memset(b1, 0, LPC_HALFORDER*sizeof(float));\n       memset(b2, 0, LPC_HALFORDER*sizeof(float));\n       memset(a, 0, (LPC_HALFORDER+1)*sizeof(float));\n       memset(b, 0, (LPC_HALFORDER+1)*sizeof(float));\n\n\n\n\n\n\n       /* p[i] and q[i] compute cos(2*pi*omega_{2j}) and\n       cos(2*pi*omega_{2j-1} in eqs. 4.2.2.2-1 and 4.2.2.2-2.\n       Note that for this code p[i] specifies the coefficients\n       used in .Q_A(z) while q[i] specifies the coefficients used\n       in .P_A(z) */\n\n       for (i=0; i<LPC_HALFORDER; i++) {\n           p[i] = (float)cos(TWO_PI * freq[2 * i]);\n           q[i] = (float)cos(TWO_PI * freq[2 * i + 1]);\n       }\n\n       a[0] = 0.25;\n       b[0] = 0.25;\n\n       for (i= 0; i<LPC_HALFORDER; i++) {\n           a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i];\n           b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i];\n           a2[i] = a1[i];\n           a1[i] = a[i];\n           b2[i] = b1[i];\n           b1[i] = b[i];\n       }\n\n       for (j=0; j<LPC_FILTERORDER; j++) {\n\n           if (j == 0) {\n               a[0] = 0.25;\n               b[0] = -0.25;\n           } else {\n               a[0] = b[0] = 0.0;\n           }\n\n           for (i=0; i<LPC_HALFORDER; i++) {\n               a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i];\n               b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i];\n               a2[i] = a1[i];\n               a1[i] = a[i];\n               b2[i] = b1[i];\n               b1[i] = b[i];\n           }\n\n           a_coef[j + 1] = 2 * (a[LPC_HALFORDER] + b[LPC_HALFORDER]);\n       }\n\n       a_coef[0] = 1.0;\n   }\n\n\n\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/lsf.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       lsf.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_LSF_H\n   #define __iLBC_LSF_H\n\n   void a2lsf(\n       float *freq,/* (o) lsf coefficients */\n       float *a    /* (i) lpc coefficients */\n   );\n\n   void lsf2a(\n       float *a_coef,  /* (o) lpc coefficients */\n       float *freq     /* (i) lsf coefficients */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/packing.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       packing.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include <math.h>\n   #include <stdlib.h>\n\n   #include \"iLBC_define.h\"\n   #include \"constants.h\"\n   #include \"helpfun.h\"\n   #include \"string.h\"\n\n   /*----------------------------------------------------------------*\n    *  splitting an integer into first most significant bits and\n    *  remaining least significant bits\n    *---------------------------------------------------------------*/\n\n   void packsplit(\n       int *index,                 /* (i) the value to split */\n       int *firstpart,             /* (o) the value specified by most\n                                          significant bits */\n       int *rest,                  /* (o) the value specified by least\n                                          significant bits */\n\n\n\n\n\n       int bitno_firstpart,    /* (i) number of bits in most\n                                          significant part */\n       int bitno_total             /* (i) number of bits in full range\n                                          of value */\n   ){\n       int bitno_rest = bitno_total-bitno_firstpart;\n\n       *firstpart = *index>>(bitno_rest);\n       *rest = *index-(*firstpart<<(bitno_rest));\n   }\n\n   /*----------------------------------------------------------------*\n    *  combining a value corresponding to msb's with a value\n    *  corresponding to lsb's\n    *---------------------------------------------------------------*/\n\n   void packcombine(\n       int *index,                 /* (i/o) the msb value in the\n                                          combined value out */\n       int rest,                   /* (i) the lsb value */\n       int bitno_rest              /* (i) the number of bits in the\n                                          lsb part */\n   ){\n       *index = *index<<bitno_rest;\n       *index += rest;\n   }\n\n   /*----------------------------------------------------------------*\n    *  packing of bits into bitstream, i.e., vector of bytes\n    *---------------------------------------------------------------*/\n\n   void dopack(\n       unsigned char **bitstream,  /* (i/o) on entrance pointer to\n                                          place in bitstream to pack\n                                          new data, on exit pointer\n                                          to place in bitstream to\n                                          pack future data */\n       int index,                  /* (i) the value to pack */\n       int bitno,                  /* (i) the number of bits that the\n                                          value will fit within */\n       int *pos                /* (i/o) write position in the\n                                          current byte */\n   ){\n       int posLeft;\n\n       /* Clear the bits before starting in a new byte */\n\n       if ((*pos)==0) {\n\n\n\n\n\n           **bitstream=0;\n       }\n\n       while (bitno>0) {\n\n           /* Jump to the next byte if end of this byte is reached*/\n\n           if (*pos==8) {\n               *pos=0;\n               (*bitstream)++;\n               **bitstream=0;\n           }\n\n           posLeft=8-(*pos);\n\n           /* Insert index into the bitstream */\n\n           if (bitno <= posLeft) {\n               **bitstream |= (unsigned char)(index<<(posLeft-bitno));\n               *pos+=bitno;\n               bitno=0;\n           } else {\n               **bitstream |= (unsigned char)(index>>(bitno-posLeft));\n\n               *pos=8;\n               index-=((index>>(bitno-posLeft))<<(bitno-posLeft));\n\n               bitno-=posLeft;\n           }\n       }\n   }\n\n   /*----------------------------------------------------------------*\n    *  unpacking of bits from bitstream, i.e., vector of bytes\n    *---------------------------------------------------------------*/\n\n   void unpack(\n       unsigned char **bitstream,  /* (i/o) on entrance pointer to\n                                          place in bitstream to\n                                          unpack new data from, on\n                                          exit pointer to place in\n                                          bitstream to unpack future\n                                          data from */\n       int *index,                 /* (o) resulting value */\n       int bitno,                  /* (i) number of bits used to\n                                          represent the value */\n       int *pos                /* (i/o) read position in the\n                                          current byte */\n\n\n\n\n\n   ){\n       int BitsLeft;\n\n       *index=0;\n\n       while (bitno>0) {\n\n           /* move forward in bitstream when the end of the\n              byte is reached */\n\n           if (*pos==8) {\n               *pos=0;\n               (*bitstream)++;\n           }\n\n           BitsLeft=8-(*pos);\n\n           /* Extract bits to index */\n\n           if (BitsLeft>=bitno) {\n               *index+=((((**bitstream)<<(*pos)) & 0xFF)>>(8-bitno));\n\n               *pos+=bitno;\n               bitno=0;\n           } else {\n\n               if ((8-bitno)>0) {\n                   *index+=((((**bitstream)<<(*pos)) & 0xFF)>>\n                       (8-bitno));\n                   *pos=8;\n               } else {\n                   *index+=(((int)(((**bitstream)<<(*pos)) & 0xFF))<<\n                       (bitno-8));\n                   *pos=8;\n               }\n               bitno-=BitsLeft;\n           }\n       }\n   }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/packing.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       packing.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __PACKING_H\n   #define __PACKING_H\n\n   void packsplit(\n       int *index,                 /* (i) the value to split */\n       int *firstpart,             /* (o) the value specified by most\n                                          significant bits */\n       int *rest,                  /* (o) the value specified by least\n                                          significant bits */\n       int bitno_firstpart,    /* (i) number of bits in most\n                                          significant part */\n       int bitno_total             /* (i) number of bits in full range\n                                          of value */\n   );\n\n   void packcombine(\n       int *index,                 /* (i/o) the msb value in the\n                                          combined value out */\n       int rest,                   /* (i) the lsb value */\n       int bitno_rest              /* (i) the number of bits in the\n                                          lsb part */\n   );\n\n   void dopack(\n       unsigned char **bitstream,  /* (i/o) on entrance pointer to\n                                          place in bitstream to pack\n                                          new data, on exit pointer\n                                          to place in bitstream to\n                                          pack future data */\n       int index,                  /* (i) the value to pack */\n       int bitno,                  /* (i) the number of bits that the\n                                          value will fit within */\n       int *pos                /* (i/o) write position in the\n                                          current byte */\n   );\n\n\n\n\n\n   void unpack(\n       unsigned char **bitstream,  /* (i/o) on entrance pointer to\n                                          place in bitstream to\n                                          unpack new data from, on\n                                          exit pointer to place in\n                                          bitstream to unpack future\n                                          data from */\n       int *index,                 /* (o) resulting value */\n       int bitno,                  /* (i) number of bits used to\n                                          represent the value */\n       int *pos                /* (i/o) read position in the\n                                          current byte */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/syntFilter.c",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       syntFilter.c\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #include \"iLBC_define.h\"\n\n   /*----------------------------------------------------------------*\n    *  LP synthesis filter.\n    *---------------------------------------------------------------*/\n\n   void syntFilter(\n       float *Out,     /* (i/o) Signal to be filtered */\n       float *a,       /* (i) LP parameters */\n       int len,    /* (i) Length of signal */\n\n\n\n\n\n       float *mem      /* (i/o) Filter state */\n   ){\n       int i, j;\n       float *po, *pi, *pa, *pm;\n\n       po=Out;\n\n       /* Filter first part using memory from past */\n\n       for (i=0; i<LPC_FILTERORDER; i++) {\n           pi=&Out[i-1];\n           pa=&a[1];\n           pm=&mem[LPC_FILTERORDER-1];\n           for (j=1; j<=i; j++) {\n               *po-=(*pa++)*(*pi--);\n           }\n           for (j=i+1; j<LPC_FILTERORDER+1; j++) {\n               *po-=(*pa++)*(*pm--);\n           }\n           po++;\n       }\n\n       /* Filter last part where the state is entirely in\n          the output vector */\n\n       for (i=LPC_FILTERORDER; i<len; i++) {\n           pi=&Out[i-1];\n           pa=&a[1];\n           for (j=1; j<LPC_FILTERORDER+1; j++) {\n               *po-=(*pa++)*(*pi--);\n           }\n           po++;\n       }\n\n       /* Update state vector */\n\n       memcpy(mem, &Out[len-LPC_FILTERORDER],\n           LPC_FILTERORDER*sizeof(float));\n   }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/ilbc/syntFilter.h",
    "content": "\n   /******************************************************************\n\n       iLBC Speech Coder ANSI-C Source Code\n\n       syntFilter.h\n\n       Copyright (C) The Internet Society (2004).\n       All Rights Reserved.\n\n   ******************************************************************/\n\n   #ifndef __iLBC_SYNTFILTER_H\n   #define __iLBC_SYNTFILTER_H\n\n   void syntFilter(\n       float *Out,     /* (i/o) Signal to be filtered */\n       float *a,       /* (i) LP parameters */\n       int len,    /* (i) Length of signal */\n       float *mem      /* (i/o) Filter state */\n   );\n\n   #endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/milenage/milenage.c",
    "content": "/*-------------------------------------------------------------------\n *          Example algorithms f1, f1*, f2, f3, f4, f5, f5*\n *-------------------------------------------------------------------\n *\n *  A sample implementation of the example 3GPP authentication and\n *  key agreement functions f1, f1*, f2, f3, f4, f5 and f5*.  This is\n *  a byte-oriented implementation of the functions, and of the block\n *  cipher kernel function Rijndael.\n *\n *  This has been coded for clarity, not necessarily for efficiency.\n *\n *  The functions f2, f3, f4 and f5 share the same inputs and have\n *  been coded together as a single function.  f1, f1* and f5* are\n *  all coded separately.\n *\n *-----------------------------------------------------------------*/\n\n#include \"milenage.h\"\n#include \"rijndael.h\"\n\n/*--------------------------- prototypes --------------------------*/\n\n\n\n/*-------------------------------------------------------------------\n *                            Algorithm f1\n *-------------------------------------------------------------------\n *\n *  Computes network authentication code MAC-A from key K, random\n *  challenge RAND, sequence number SQN and authentication management\n *  field AMF.\n *\n *-----------------------------------------------------------------*/\n\nvoid f1    ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], \n             u8 mac_a[8], u8 op[16] )\n{\n  u8 op_c[16];\n  u8 temp[16];\n  u8 in1[16];\n  u8 out1[16];\n  u8 rijndaelInput[16];\n  u8 i;\n\n  RijndaelKeySchedule( k );\n\n  ComputeOPc( op_c, op );\n\n  for (i=0; i<16; i++)\n    rijndaelInput[i] = rand[i] ^ op_c[i];\n  RijndaelEncrypt( rijndaelInput, temp );\n\n  for (i=0; i<6; i++)\n  {\n    in1[i]    = sqn[i];\n    in1[i+8]  = sqn[i];\n  }\n  for (i=0; i<2; i++)\n  {\n    in1[i+6]  = amf[i];\n    in1[i+14] = amf[i];\n  }\n\n  /* XOR op_c and in1, rotate by r1=64, and XOR *\n   * on the constant c1 (which is all zeroes)   */\n\n  for (i=0; i<16; i++)\n    rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i];\n\n  /* XOR on the value temp computed before */\n\n  for (i=0; i<16; i++)\n    rijndaelInput[i] ^= temp[i];\n  \n  RijndaelEncrypt( rijndaelInput, out1 );\n  for (i=0; i<16; i++)\n    out1[i] ^= op_c[i];\n\n  for (i=0; i<8; i++)\n    mac_a[i] = out1[i];\n\n  return;\n} /* end of function f1 */\n\n\n  \n/*-------------------------------------------------------------------\n *                            Algorithms f2-f5\n *-------------------------------------------------------------------\n *\n *  Takes key K and random challenge RAND, and returns response RES,\n *  confidentiality key CK, integrity key IK and anonymity key AK.\n *\n *-----------------------------------------------------------------*/\n\nvoid f2345 ( u8 k[16], u8 rand[16],\n             u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6], u8 op[16] )\n{\n  u8 op_c[16];\n  u8 temp[16];\n  u8 out[16];\n  u8 rijndaelInput[16];\n  u8 i;\n\n  RijndaelKeySchedule( k );\n\n  ComputeOPc( op_c, op );\n\n  for (i=0; i<16; i++)\n    rijndaelInput[i] = rand[i] ^ op_c[i];\n  RijndaelEncrypt( rijndaelInput, temp );\n\n  /* To obtain output block OUT2: XOR OPc and TEMP,    *\n   * rotate by r2=0, and XOR on the constant c2 (which *\n   * is all zeroes except that the last bit is 1).     */\n\n  for (i=0; i<16; i++)\n    rijndaelInput[i] = temp[i] ^ op_c[i];\n  rijndaelInput[15] ^= 1;\n\n  RijndaelEncrypt( rijndaelInput, out );\n  for (i=0; i<16; i++)\n    out[i] ^= op_c[i];\n\n  for (i=0; i<8; i++)\n    res[i] = out[i+8];\n  for (i=0; i<6; i++)\n    ak[i]  = out[i];\n\n  /* To obtain output block OUT3: XOR OPc and TEMP,        *\n   * rotate by r3=32, and XOR on the constant c3 (which    *\n   * is all zeroes except that the next to last bit is 1). */\n\n  for (i=0; i<16; i++)\n    rijndaelInput[(i+12) % 16] = temp[i] ^ op_c[i];\n  rijndaelInput[15] ^= 2;\n\n  RijndaelEncrypt( rijndaelInput, out );\n  for (i=0; i<16; i++)\n    out[i] ^= op_c[i];\n\n  for (i=0; i<16; i++)\n    ck[i] = out[i];\n\n  /* To obtain output block OUT4: XOR OPc and TEMP,         *\n   * rotate by r4=64, and XOR on the constant c4 (which     *\n   * is all zeroes except that the 2nd from last bit is 1). */\n\n  for (i=0; i<16; i++)\n    rijndaelInput[(i+8) % 16] = temp[i] ^ op_c[i];\n  rijndaelInput[15] ^= 4;\n\n  RijndaelEncrypt( rijndaelInput, out );\n  for (i=0; i<16; i++)\n    out[i] ^= op_c[i];\n\n  for (i=0; i<16; i++)\n    ik[i] = out[i];\n\n  return;\n} /* end of function f2345 */\n\n  \n/*-------------------------------------------------------------------\n *                            Algorithm f1*\n *-------------------------------------------------------------------\n *\n *  Computes resynch authentication code MAC-S from key K, random\n *  challenge RAND, sequence number SQN and authentication management\n *  field AMF.\n *\n *-----------------------------------------------------------------*/\n\nvoid f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], \n             u8 mac_s[8], u8 op[16] )\n{\n  u8 op_c[16];\n  u8 temp[16];\n  u8 in1[16];\n  u8 out1[16];\n  u8 rijndaelInput[16];\n  u8 i;\n\n  RijndaelKeySchedule( k );\n\n  ComputeOPc( op_c, op );\n\n  for (i=0; i<16; i++)\n    rijndaelInput[i] = rand[i] ^ op_c[i];\n  RijndaelEncrypt( rijndaelInput, temp );\n\n  for (i=0; i<6; i++)\n  {\n    in1[i]    = sqn[i];\n    in1[i+8]  = sqn[i];\n  }\n  for (i=0; i<2; i++)\n  {\n    in1[i+6]  = amf[i];\n    in1[i+14] = amf[i];\n  }\n\n  /* XOR op_c and in1, rotate by r1=64, and XOR *\n   * on the constant c1 (which is all zeroes)   */\n\n  for (i=0; i<16; i++)\n    rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i];\n\n  /* XOR on the value temp computed before */\n\n  for (i=0; i<16; i++)\n    rijndaelInput[i] ^= temp[i];\n  \n  RijndaelEncrypt( rijndaelInput, out1 );\n  for (i=0; i<16; i++)\n    out1[i] ^= op_c[i];\n\n  for (i=0; i<8; i++)\n    mac_s[i] = out1[i+8];\n\n  return;\n} /* end of function f1star */\n\n  \n/*-------------------------------------------------------------------\n *                            Algorithm f5*\n *-------------------------------------------------------------------\n *\n *  Takes key K and random challenge RAND, and returns resynch\n *  anonymity key AK.\n *\n *-----------------------------------------------------------------*/\n\nvoid f5star( u8 k[16], u8 rand[16],\n             u8 ak[6], u8 op[16] )\n{\n  u8 op_c[16];\n  u8 temp[16];\n  u8 out[16];\n  u8 rijndaelInput[16];\n  u8 i;\n\n  RijndaelKeySchedule( k );\n\n  ComputeOPc( op_c, op );\n\n  for (i=0; i<16; i++)\n    rijndaelInput[i] = rand[i] ^ op_c[i];\n  RijndaelEncrypt( rijndaelInput, temp );\n\n  /* To obtain output block OUT5: XOR OPc and TEMP,         *\n   * rotate by r5=96, and XOR on the constant c5 (which     *\n   * is all zeroes except that the 3rd from last bit is 1). */\n\n  for (i=0; i<16; i++)\n    rijndaelInput[(i+4) % 16] = temp[i] ^ op_c[i];\n  rijndaelInput[15] ^= 8;\n\n  RijndaelEncrypt( rijndaelInput, out );\n  for (i=0; i<16; i++)\n    out[i] ^= op_c[i];\n\n  for (i=0; i<6; i++)\n    ak[i] = out[i];\n\n  return;\n} /* end of function f5star */\n\n  \n/*-------------------------------------------------------------------\n *  Function to compute OPc from OP and K.  Assumes key schedule has\n    already been performed.\n *-----------------------------------------------------------------*/\n\nvoid ComputeOPc( u8 op_c[16], u8 op[16] )\n{\n  u8 i;\n  \n  RijndaelEncrypt( op, op_c );\n  for (i=0; i<16; i++)\n    op_c[i] ^= op[i];\n\n  return;\n} /* end of function ComputeOPc */\n"
  },
  {
    "path": "deps/pjsip/third_party/milenage/milenage.h",
    "content": "/*-------------------------------------------------------------------\n *          Example algorithms f1, f1*, f2, f3, f4, f5, f5*\n *-------------------------------------------------------------------\n *\n *  A sample implementation of the example 3GPP authentication and\n *  key agreement functions f1, f1*, f2, f3, f4, f5 and f5*.  This is\n *  a byte-oriented implementation of the functions, and of the block\n *  cipher kernel function Rijndael.\n *\n *  This has been coded for clarity, not necessarily for efficiency.\n *\n *  The functions f2, f3, f4 and f5 share the same inputs and have\n *  been coded together as a single function.  f1, f1* and f5* are\n *  all coded separately.\n *\n *-----------------------------------------------------------------*/\n\n#ifndef MILENAGE_H\n#define MILENAGE_H\n\ntypedef unsigned char u8;\n\n\nvoid f1    ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],\n             u8 mac_a[8], u8 op[16] );\nvoid f2345 ( u8 k[16], u8 rand[16],\n             u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6], u8 op[16] );\nvoid f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],\n             u8 mac_s[8], u8 op[16] );\nvoid f5star( u8 k[16], u8 rand[16],\n             u8 ak[6], u8 op[16] );\nvoid ComputeOPc( u8 op_c[16], u8 op[16] );\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/milenage/rijndael.c",
    "content": "/*-------------------------------------------------------------------\n *                      Rijndael Implementation\n *-------------------------------------------------------------------\n *\n *  A sample 32-bit orientated implementation of Rijndael, the\n *  suggested kernel for the example 3GPP authentication and key\n *  agreement functions.\n *\n *  This implementation draws on the description in section 5.2 of\n *  the AES proposal and also on the implementation by\n *  Dr B. R. Gladman <brg@gladman.uk.net> 9th October 2000.\n *  It uses a number of large (4k) lookup tables to implement the\n *  algorithm in an efficient manner.\n *\n *  Note: in this implementation the State is stored in four 32-bit\n *  words, one per column of the State, with the top byte of the\n *  column being the _least_ significant byte of the word.\n *\n*-----------------------------------------------------------------*/\n\n#include <pj/types.h>\n\n#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN != 0\n#\tdefine LITTLE_ENDIAN\t/* For INTEL architecture */\n#endif\n\ntypedef unsigned char   u8;\ntypedef unsigned int\t u32;\n\n/* Circular byte rotates of 32 bit values */\n\n#define rot1(x) ((x <<  8) | (x >> 24))\n#define rot2(x) ((x << 16) | (x >> 16))\n#define rot3(x) ((x << 24) | (x >>  8))\n\n/* Extract a byte from a 32-bit u32 */\n\n#define byte0(x)    ((u8)(x))\n#define byte1(x)    ((u8)(x >>  8))\n#define byte2(x)    ((u8)(x >> 16))\n#define byte3(x)    ((u8)(x >> 24))\n\n\n/* Put or get a 32 bit u32 (v) in machine order from a byte\t*\n * address in (x)                                           */\n\n#ifdef  LITTLE_ENDIAN\n\n#define u32_in(x)     (*(u32*)(x))\n#define u32_out(x,y)  (*(u32*)(x) = y)\n\n#else\n\n/* Invert byte order in a 32 bit variable */\n\n__inline u32 byte_swap(const u32 x)\n{\n    return rot1(x) & 0x00ff00ff | rot3(x) & 0xff00ff00;\n}\n__inline u32 u32_in(const u8 x[])\n{\n  return byte_swap(*(u32*)x);\n};\n__inline void u32_out(u8 x[], const u32 v) \n{\n  *(u32*)x = byte_swap(v);\n};\n\n#endif\n\n/*--------------- The lookup tables ----------------------------*/\n\nstatic u32 rnd_con[10] = \n{ \n 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36\n};\n\nstatic u32 ft_tab[4][256] = \n{\n {\n 0xA56363C6,0x847C7CF8,0x997777EE,0x8D7B7BF6,0x0DF2F2FF,0xBD6B6BD6,0xB16F6FDE,0x54C5C591,\n 0x50303060,0x03010102,0xA96767CE,0x7D2B2B56,0x19FEFEE7,0x62D7D7B5,0xE6ABAB4D,0x9A7676EC,\n 0x45CACA8F,0x9D82821F,0x40C9C989,0x877D7DFA,0x15FAFAEF,0xEB5959B2,0xC947478E,0x0BF0F0FB,\n 0xECADAD41,0x67D4D4B3,0xFDA2A25F,0xEAAFAF45,0xBF9C9C23,0xF7A4A453,0x967272E4,0x5BC0C09B,\n 0xC2B7B775,0x1CFDFDE1,0xAE93933D,0x6A26264C,0x5A36366C,0x413F3F7E,0x02F7F7F5,0x4FCCCC83,\n 0x5C343468,0xF4A5A551,0x34E5E5D1,0x08F1F1F9,0x937171E2,0x73D8D8AB,0x53313162,0x3F15152A,\n 0x0C040408,0x52C7C795,0x65232346,0x5EC3C39D,0x28181830,0xA1969637,0x0F05050A,0xB59A9A2F,\n 0x0907070E,0x36121224,0x9B80801B,0x3DE2E2DF,0x26EBEBCD,0x6927274E,0xCDB2B27F,0x9F7575EA,\n 0x1B090912,0x9E83831D,0x742C2C58,0x2E1A1A34,0x2D1B1B36,0xB26E6EDC,0xEE5A5AB4,0xFBA0A05B,\n 0xF65252A4,0x4D3B3B76,0x61D6D6B7,0xCEB3B37D,0x7B292952,0x3EE3E3DD,0x712F2F5E,0x97848413,\n 0xF55353A6,0x68D1D1B9,0000000000,0x2CEDEDC1,0x60202040,0x1FFCFCE3,0xC8B1B179,0xED5B5BB6,\n 0xBE6A6AD4,0x46CBCB8D,0xD9BEBE67,0x4B393972,0xDE4A4A94,0xD44C4C98,0xE85858B0,0x4ACFCF85,\n 0x6BD0D0BB,0x2AEFEFC5,0xE5AAAA4F,0x16FBFBED,0xC5434386,0xD74D4D9A,0x55333366,0x94858511,\n 0xCF45458A,0x10F9F9E9,0x06020204,0x817F7FFE,0xF05050A0,0x443C3C78,0xBA9F9F25,0xE3A8A84B,\n 0xF35151A2,0xFEA3A35D,0xC0404080,0x8A8F8F05,0xAD92923F,0xBC9D9D21,0x48383870,0x04F5F5F1,\n 0xDFBCBC63,0xC1B6B677,0x75DADAAF,0x63212142,0x30101020,0x1AFFFFE5,0x0EF3F3FD,0x6DD2D2BF,\n 0x4CCDCD81,0x140C0C18,0x35131326,0x2FECECC3,0xE15F5FBE,0xA2979735,0xCC444488,0x3917172E,\n 0x57C4C493,0xF2A7A755,0x827E7EFC,0x473D3D7A,0xAC6464C8,0xE75D5DBA,0x2B191932,0x957373E6,\n 0xA06060C0,0x98818119,0xD14F4F9E,0x7FDCDCA3,0x66222244,0x7E2A2A54,0xAB90903B,0x8388880B,\n 0xCA46468C,0x29EEEEC7,0xD3B8B86B,0x3C141428,0x79DEDEA7,0xE25E5EBC,0x1D0B0B16,0x76DBDBAD,\n 0x3BE0E0DB,0x56323264,0x4E3A3A74,0x1E0A0A14,0xDB494992,0x0A06060C,0x6C242448,0xE45C5CB8,\n 0x5DC2C29F,0x6ED3D3BD,0xEFACAC43,0xA66262C4,0xA8919139,0xA4959531,0x37E4E4D3,0x8B7979F2,\n 0x32E7E7D5,0x43C8C88B,0x5937376E,0xB76D6DDA,0x8C8D8D01,0x64D5D5B1,0xD24E4E9C,0xE0A9A949,\n 0xB46C6CD8,0xFA5656AC,0x07F4F4F3,0x25EAEACF,0xAF6565CA,0x8E7A7AF4,0xE9AEAE47,0x18080810,\n 0xD5BABA6F,0x887878F0,0x6F25254A,0x722E2E5C,0x241C1C38,0xF1A6A657,0xC7B4B473,0x51C6C697,\n 0x23E8E8CB,0x7CDDDDA1,0x9C7474E8,0x211F1F3E,0xDD4B4B96,0xDCBDBD61,0x868B8B0D,0x858A8A0F,\n 0x907070E0,0x423E3E7C,0xC4B5B571,0xAA6666CC,0xD8484890,0x05030306,0x01F6F6F7,0x120E0E1C,\n 0xA36161C2,0x5F35356A,0xF95757AE,0xD0B9B969,0x91868617,0x58C1C199,0x271D1D3A,0xB99E9E27,\n 0x38E1E1D9,0x13F8F8EB,0xB398982B,0x33111122,0xBB6969D2,0x70D9D9A9,0x898E8E07,0xA7949433,\n 0xB69B9B2D,0x221E1E3C,0x92878715,0x20E9E9C9,0x49CECE87,0xFF5555AA,0x78282850,0x7ADFDFA5,\n 0x8F8C8C03,0xF8A1A159,0x80898909,0x170D0D1A,0xDABFBF65,0x31E6E6D7,0xC6424284,0xB86868D0,\n 0xC3414182,0xB0999929,0x772D2D5A,0x110F0F1E,0xCBB0B07B,0xFC5454A8,0xD6BBBB6D,0x3A16162C \n },\n {\n 0x6363C6A5,0x7C7CF884,0x7777EE99,0x7B7BF68D,0xF2F2FF0D,0x6B6BD6BD,0x6F6FDEB1,0xC5C59154,\n 0x30306050,0x01010203,0x6767CEA9,0x2B2B567D,0xFEFEE719,0xD7D7B562,0xABAB4DE6,0x7676EC9A,\n 0xCACA8F45,0x82821F9D,0xC9C98940,0x7D7DFA87,0xFAFAEF15,0x5959B2EB,0x47478EC9,0xF0F0FB0B,\n 0xADAD41EC,0xD4D4B367,0xA2A25FFD,0xAFAF45EA,0x9C9C23BF,0xA4A453F7,0x7272E496,0xC0C09B5B,\n 0xB7B775C2,0xFDFDE11C,0x93933DAE,0x26264C6A,0x36366C5A,0x3F3F7E41,0xF7F7F502,0xCCCC834F,\n 0x3434685C,0xA5A551F4,0xE5E5D134,0xF1F1F908,0x7171E293,0xD8D8AB73,0x31316253,0x15152A3F,\n 0x0404080C,0xC7C79552,0x23234665,0xC3C39D5E,0x18183028,0x969637A1,0x05050A0F,0x9A9A2FB5,\n 0x07070E09,0x12122436,0x80801B9B,0xE2E2DF3D,0xEBEBCD26,0x27274E69,0xB2B27FCD,0x7575EA9F,\n 0x0909121B,0x83831D9E,0x2C2C5874,0x1A1A342E,0x1B1B362D,0x6E6EDCB2,0x5A5AB4EE,0xA0A05BFB,\n 0x5252A4F6,0x3B3B764D,0xD6D6B761,0xB3B37DCE,0x2929527B,0xE3E3DD3E,0x2F2F5E71,0x84841397,\n 0x5353A6F5,0xD1D1B968,0000000000,0xEDEDC12C,0x20204060,0xFCFCE31F,0xB1B179C8,0x5B5BB6ED,\n 0x6A6AD4BE,0xCBCB8D46,0xBEBE67D9,0x3939724B,0x4A4A94DE,0x4C4C98D4,0x5858B0E8,0xCFCF854A,\n 0xD0D0BB6B,0xEFEFC52A,0xAAAA4FE5,0xFBFBED16,0x434386C5,0x4D4D9AD7,0x33336655,0x85851194,\n 0x45458ACF,0xF9F9E910,0x02020406,0x7F7FFE81,0x5050A0F0,0x3C3C7844,0x9F9F25BA,0xA8A84BE3,\n 0x5151A2F3,0xA3A35DFE,0x404080C0,0x8F8F058A,0x92923FAD,0x9D9D21BC,0x38387048,0xF5F5F104,\n 0xBCBC63DF,0xB6B677C1,0xDADAAF75,0x21214263,0x10102030,0xFFFFE51A,0xF3F3FD0E,0xD2D2BF6D,\n 0xCDCD814C,0x0C0C1814,0x13132635,0xECECC32F,0x5F5FBEE1,0x979735A2,0x444488CC,0x17172E39,\n 0xC4C49357,0xA7A755F2,0x7E7EFC82,0x3D3D7A47,0x6464C8AC,0x5D5DBAE7,0x1919322B,0x7373E695,\n 0x6060C0A0,0x81811998,0x4F4F9ED1,0xDCDCA37F,0x22224466,0x2A2A547E,0x90903BAB,0x88880B83,\n 0x46468CCA,0xEEEEC729,0xB8B86BD3,0x1414283C,0xDEDEA779,0x5E5EBCE2,0x0B0B161D,0xDBDBAD76,\n 0xE0E0DB3B,0x32326456,0x3A3A744E,0x0A0A141E,0x494992DB,0x06060C0A,0x2424486C,0x5C5CB8E4,\n 0xC2C29F5D,0xD3D3BD6E,0xACAC43EF,0x6262C4A6,0x919139A8,0x959531A4,0xE4E4D337,0x7979F28B,\n 0xE7E7D532,0xC8C88B43,0x37376E59,0x6D6DDAB7,0x8D8D018C,0xD5D5B164,0x4E4E9CD2,0xA9A949E0,\n 0x6C6CD8B4,0x5656ACFA,0xF4F4F307,0xEAEACF25,0x6565CAAF,0x7A7AF48E,0xAEAE47E9,0x08081018,\n 0xBABA6FD5,0x7878F088,0x25254A6F,0x2E2E5C72,0x1C1C3824,0xA6A657F1,0xB4B473C7,0xC6C69751,\n 0xE8E8CB23,0xDDDDA17C,0x7474E89C,0x1F1F3E21,0x4B4B96DD,0xBDBD61DC,0x8B8B0D86,0x8A8A0F85,\n 0x7070E090,0x3E3E7C42,0xB5B571C4,0x6666CCAA,0x484890D8,0x03030605,0xF6F6F701,0x0E0E1C12,\n 0x6161C2A3,0x35356A5F,0x5757AEF9,0xB9B969D0,0x86861791,0xC1C19958,0x1D1D3A27,0x9E9E27B9,\n 0xE1E1D938,0xF8F8EB13,0x98982BB3,0x11112233,0x6969D2BB,0xD9D9A970,0x8E8E0789,0x949433A7,\n 0x9B9B2DB6,0x1E1E3C22,0x87871592,0xE9E9C920,0xCECE8749,0x5555AAFF,0x28285078,0xDFDFA57A,\n 0x8C8C038F,0xA1A159F8,0x89890980,0x0D0D1A17,0xBFBF65DA,0xE6E6D731,0x424284C6,0x6868D0B8,\n 0x414182C3,0x999929B0,0x2D2D5A77,0x0F0F1E11,0xB0B07BCB,0x5454A8FC,0xBBBB6DD6,0x16162C3A \n },\n {\n 0x63C6A563,0x7CF8847C,0x77EE9977,0x7BF68D7B,0xF2FF0DF2,0x6BD6BD6B,0x6FDEB16F,0xC59154C5,\n 0x30605030,0x01020301,0x67CEA967,0x2B567D2B,0xFEE719FE,0xD7B562D7,0xAB4DE6AB,0x76EC9A76,\n 0xCA8F45CA,0x821F9D82,0xC98940C9,0x7DFA877D,0xFAEF15FA,0x59B2EB59,0x478EC947,0xF0FB0BF0,\n 0xAD41ECAD,0xD4B367D4,0xA25FFDA2,0xAF45EAAF,0x9C23BF9C,0xA453F7A4,0x72E49672,0xC09B5BC0,\n 0xB775C2B7,0xFDE11CFD,0x933DAE93,0x264C6A26,0x366C5A36,0x3F7E413F,0xF7F502F7,0xCC834FCC,\n 0x34685C34,0xA551F4A5,0xE5D134E5,0xF1F908F1,0x71E29371,0xD8AB73D8,0x31625331,0x152A3F15,\n 0x04080C04,0xC79552C7,0x23466523,0xC39D5EC3,0x18302818,0x9637A196,0x050A0F05,0x9A2FB59A,\n 0x070E0907,0x12243612,0x801B9B80,0xE2DF3DE2,0xEBCD26EB,0x274E6927,0xB27FCDB2,0x75EA9F75,\n 0x09121B09,0x831D9E83,0x2C58742C,0x1A342E1A,0x1B362D1B,0x6EDCB26E,0x5AB4EE5A,0xA05BFBA0,\n 0x52A4F652,0x3B764D3B,0xD6B761D6,0xB37DCEB3,0x29527B29,0xE3DD3EE3,0x2F5E712F,0x84139784,\n 0x53A6F553,0xD1B968D1,0000000000,0xEDC12CED,0x20406020,0xFCE31FFC,0xB179C8B1,0x5BB6ED5B,\n 0x6AD4BE6A,0xCB8D46CB,0xBE67D9BE,0x39724B39,0x4A94DE4A,0x4C98D44C,0x58B0E858,0xCF854ACF,\n 0xD0BB6BD0,0xEFC52AEF,0xAA4FE5AA,0xFBED16FB,0x4386C543,0x4D9AD74D,0x33665533,0x85119485,\n 0x458ACF45,0xF9E910F9,0x02040602,0x7FFE817F,0x50A0F050,0x3C78443C,0x9F25BA9F,0xA84BE3A8,\n 0x51A2F351,0xA35DFEA3,0x4080C040,0x8F058A8F,0x923FAD92,0x9D21BC9D,0x38704838,0xF5F104F5,\n 0xBC63DFBC,0xB677C1B6,0xDAAF75DA,0x21426321,0x10203010,0xFFE51AFF,0xF3FD0EF3,0xD2BF6DD2,\n 0xCD814CCD,0x0C18140C,0x13263513,0xECC32FEC,0x5FBEE15F,0x9735A297,0x4488CC44,0x172E3917,\n 0xC49357C4,0xA755F2A7,0x7EFC827E,0x3D7A473D,0x64C8AC64,0x5DBAE75D,0x19322B19,0x73E69573,\n 0x60C0A060,0x81199881,0x4F9ED14F,0xDCA37FDC,0x22446622,0x2A547E2A,0x903BAB90,0x880B8388,\n 0x468CCA46,0xEEC729EE,0xB86BD3B8,0x14283C14,0xDEA779DE,0x5EBCE25E,0x0B161D0B,0xDBAD76DB,\n 0xE0DB3BE0,0x32645632,0x3A744E3A,0x0A141E0A,0x4992DB49,0x060C0A06,0x24486C24,0x5CB8E45C,\n 0xC29F5DC2,0xD3BD6ED3,0xAC43EFAC,0x62C4A662,0x9139A891,0x9531A495,0xE4D337E4,0x79F28B79,\n 0xE7D532E7,0xC88B43C8,0x376E5937,0x6DDAB76D,0x8D018C8D,0xD5B164D5,0x4E9CD24E,0xA949E0A9,\n 0x6CD8B46C,0x56ACFA56,0xF4F307F4,0xEACF25EA,0x65CAAF65,0x7AF48E7A,0xAE47E9AE,0x08101808,\n 0xBA6FD5BA,0x78F08878,0x254A6F25,0x2E5C722E,0x1C38241C,0xA657F1A6,0xB473C7B4,0xC69751C6,\n 0xE8CB23E8,0xDDA17CDD,0x74E89C74,0x1F3E211F,0x4B96DD4B,0xBD61DCBD,0x8B0D868B,0x8A0F858A,\n 0x70E09070,0x3E7C423E,0xB571C4B5,0x66CCAA66,0x4890D848,0x03060503,0xF6F701F6,0x0E1C120E,\n 0x61C2A361,0x356A5F35,0x57AEF957,0xB969D0B9,0x86179186,0xC19958C1,0x1D3A271D,0x9E27B99E,\n 0xE1D938E1,0xF8EB13F8,0x982BB398,0x11223311,0x69D2BB69,0xD9A970D9,0x8E07898E,0x9433A794,\n 0x9B2DB69B,0x1E3C221E,0x87159287,0xE9C920E9,0xCE8749CE,0x55AAFF55,0x28507828,0xDFA57ADF,\n 0x8C038F8C,0xA159F8A1,0x89098089,0x0D1A170D,0xBF65DABF,0xE6D731E6,0x4284C642,0x68D0B868,\n 0x4182C341,0x9929B099,0x2D5A772D,0x0F1E110F,0xB07BCBB0,0x54A8FC54,0xBB6DD6BB,0x162C3A16 \n },\n {\n 0xC6A56363,0xF8847C7C,0xEE997777,0xF68D7B7B,0xFF0DF2F2,0xD6BD6B6B,0xDEB16F6F,0x9154C5C5,\n 0x60503030,0x02030101,0xCEA96767,0x567D2B2B,0xE719FEFE,0xB562D7D7,0x4DE6ABAB,0xEC9A7676,\n 0x8F45CACA,0x1F9D8282,0x8940C9C9,0xFA877D7D,0xEF15FAFA,0xB2EB5959,0x8EC94747,0xFB0BF0F0,\n 0x41ECADAD,0xB367D4D4,0x5FFDA2A2,0x45EAAFAF,0x23BF9C9C,0x53F7A4A4,0xE4967272,0x9B5BC0C0,\n 0x75C2B7B7,0xE11CFDFD,0x3DAE9393,0x4C6A2626,0x6C5A3636,0x7E413F3F,0xF502F7F7,0x834FCCCC,\n 0x685C3434,0x51F4A5A5,0xD134E5E5,0xF908F1F1,0xE2937171,0xAB73D8D8,0x62533131,0x2A3F1515,\n 0x080C0404,0x9552C7C7,0x46652323,0x9D5EC3C3,0x30281818,0x37A19696,0x0A0F0505,0x2FB59A9A,\n 0x0E090707,0x24361212,0x1B9B8080,0xDF3DE2E2,0xCD26EBEB,0x4E692727,0x7FCDB2B2,0xEA9F7575,\n 0x121B0909,0x1D9E8383,0x58742C2C,0x342E1A1A,0x362D1B1B,0xDCB26E6E,0xB4EE5A5A,0x5BFBA0A0,\n 0xA4F65252,0x764D3B3B,0xB761D6D6,0x7DCEB3B3,0x527B2929,0xDD3EE3E3,0x5E712F2F,0x13978484,\n 0xA6F55353,0xB968D1D1,0000000000,0xC12CEDED,0x40602020,0xE31FFCFC,0x79C8B1B1,0xB6ED5B5B,\n 0xD4BE6A6A,0x8D46CBCB,0x67D9BEBE,0x724B3939,0x94DE4A4A,0x98D44C4C,0xB0E85858,0x854ACFCF,\n 0xBB6BD0D0,0xC52AEFEF,0x4FE5AAAA,0xED16FBFB,0x86C54343,0x9AD74D4D,0x66553333,0x11948585,\n 0x8ACF4545,0xE910F9F9,0x04060202,0xFE817F7F,0xA0F05050,0x78443C3C,0x25BA9F9F,0x4BE3A8A8,\n 0xA2F35151,0x5DFEA3A3,0x80C04040,0x058A8F8F,0x3FAD9292,0x21BC9D9D,0x70483838,0xF104F5F5,\n 0x63DFBCBC,0x77C1B6B6,0xAF75DADA,0x42632121,0x20301010,0xE51AFFFF,0xFD0EF3F3,0xBF6DD2D2,\n 0x814CCDCD,0x18140C0C,0x26351313,0xC32FECEC,0xBEE15F5F,0x35A29797,0x88CC4444,0x2E391717,\n 0x9357C4C4,0x55F2A7A7,0xFC827E7E,0x7A473D3D,0xC8AC6464,0xBAE75D5D,0x322B1919,0xE6957373,\n 0xC0A06060,0x19988181,0x9ED14F4F,0xA37FDCDC,0x44662222,0x547E2A2A,0x3BAB9090,0x0B838888,\n 0x8CCA4646,0xC729EEEE,0x6BD3B8B8,0x283C1414,0xA779DEDE,0xBCE25E5E,0x161D0B0B,0xAD76DBDB,\n 0xDB3BE0E0,0x64563232,0x744E3A3A,0x141E0A0A,0x92DB4949,0x0C0A0606,0x486C2424,0xB8E45C5C,\n 0x9F5DC2C2,0xBD6ED3D3,0x43EFACAC,0xC4A66262,0x39A89191,0x31A49595,0xD337E4E4,0xF28B7979,\n 0xD532E7E7,0x8B43C8C8,0x6E593737,0xDAB76D6D,0x018C8D8D,0xB164D5D5,0x9CD24E4E,0x49E0A9A9,\n 0xD8B46C6C,0xACFA5656,0xF307F4F4,0xCF25EAEA,0xCAAF6565,0xF48E7A7A,0x47E9AEAE,0x10180808,\n 0x6FD5BABA,0xF0887878,0x4A6F2525,0x5C722E2E,0x38241C1C,0x57F1A6A6,0x73C7B4B4,0x9751C6C6,\n 0xCB23E8E8,0xA17CDDDD,0xE89C7474,0x3E211F1F,0x96DD4B4B,0x61DCBDBD,0x0D868B8B,0x0F858A8A,\n 0xE0907070,0x7C423E3E,0x71C4B5B5,0xCCAA6666,0x90D84848,0x06050303,0xF701F6F6,0x1C120E0E,\n 0xC2A36161,0x6A5F3535,0xAEF95757,0x69D0B9B9,0x17918686,0x9958C1C1,0x3A271D1D,0x27B99E9E,\n 0xD938E1E1,0xEB13F8F8,0x2BB39898,0x22331111,0xD2BB6969,0xA970D9D9,0x07898E8E,0x33A79494,\n 0x2DB69B9B,0x3C221E1E,0x15928787,0xC920E9E9,0x8749CECE,0xAAFF5555,0x50782828,0xA57ADFDF,\n 0x038F8C8C,0x59F8A1A1,0x09808989,0x1A170D0D,0x65DABFBF,0xD731E6E6,0x84C64242,0xD0B86868,\n 0x82C34141,0x29B09999,0x5A772D2D,0x1E110F0F,0x7BCBB0B0,0xA8FC5454,0x6DD6BBBB,0x2C3A1616 \n } \n};\n\nstatic u32 fl_tab[4][256] = \n{\n {\n 0x00000063,0x0000007C,0x00000077,0x0000007B,0x000000F2,0x0000006B,0x0000006F,0x000000C5,\n 0x00000030,0x00000001,0x00000067,0x0000002B,0x000000FE,0x000000D7,0x000000AB,0x00000076,\n 0x000000CA,0x00000082,0x000000C9,0x0000007D,0x000000FA,0x00000059,0x00000047,0x000000F0,\n 0x000000AD,0x000000D4,0x000000A2,0x000000AF,0x0000009C,0x000000A4,0x00000072,0x000000C0,\n 0x000000B7,0x000000FD,0x00000093,0x00000026,0x00000036,0x0000003F,0x000000F7,0x000000CC,\n 0x00000034,0x000000A5,0x000000E5,0x000000F1,0x00000071,0x000000D8,0x00000031,0x00000015,\n 0x00000004,0x000000C7,0x00000023,0x000000C3,0x00000018,0x00000096,0x00000005,0x0000009A,\n 0x00000007,0x00000012,0x00000080,0x000000E2,0x000000EB,0x00000027,0x000000B2,0x00000075,\n 0x00000009,0x00000083,0x0000002C,0x0000001A,0x0000001B,0x0000006E,0x0000005A,0x000000A0,\n 0x00000052,0x0000003B,0x000000D6,0x000000B3,0x00000029,0x000000E3,0x0000002F,0x00000084,\n 0x00000053,0x000000D1,0x00000000,0x000000ED,0x00000020,0x000000FC,0x000000B1,0x0000005B,\n 0x0000006A,0x000000CB,0x000000BE,0x00000039,0x0000004A,0x0000004C,0x00000058,0x000000CF,\n 0x000000D0,0x000000EF,0x000000AA,0x000000FB,0x00000043,0x0000004D,0x00000033,0x00000085,\n 0x00000045,0x000000F9,0x00000002,0x0000007F,0x00000050,0x0000003C,0x0000009F,0x000000A8,\n 0x00000051,0x000000A3,0x00000040,0x0000008F,0x00000092,0x0000009D,0x00000038,0x000000F5,\n 0x000000BC,0x000000B6,0x000000DA,0x00000021,0x00000010,0x000000FF,0x000000F3,0x000000D2,\n 0x000000CD,0x0000000C,0x00000013,0x000000EC,0x0000005F,0x00000097,0x00000044,0x00000017,\n 0x000000C4,0x000000A7,0x0000007E,0x0000003D,0x00000064,0x0000005D,0x00000019,0x00000073,\n 0x00000060,0x00000081,0x0000004F,0x000000DC,0x00000022,0x0000002A,0x00000090,0x00000088,\n 0x00000046,0x000000EE,0x000000B8,0x00000014,0x000000DE,0x0000005E,0x0000000B,0x000000DB,\n 0x000000E0,0x00000032,0x0000003A,0x0000000A,0x00000049,0x00000006,0x00000024,0x0000005C,\n 0x000000C2,0x000000D3,0x000000AC,0x00000062,0x00000091,0x00000095,0x000000E4,0x00000079,\n 0x000000E7,0x000000C8,0x00000037,0x0000006D,0x0000008D,0x000000D5,0x0000004E,0x000000A9,\n 0x0000006C,0x00000056,0x000000F4,0x000000EA,0x00000065,0x0000007A,0x000000AE,0x00000008,\n 0x000000BA,0x00000078,0x00000025,0x0000002E,0x0000001C,0x000000A6,0x000000B4,0x000000C6,\n 0x000000E8,0x000000DD,0x00000074,0x0000001F,0x0000004B,0x000000BD,0x0000008B,0x0000008A,\n 0x00000070,0x0000003E,0x000000B5,0x00000066,0x00000048,0x00000003,0x000000F6,0x0000000E,\n 0x00000061,0x00000035,0x00000057,0x000000B9,0x00000086,0x000000C1,0x0000001D,0x0000009E,\n 0x000000E1,0x000000F8,0x00000098,0x00000011,0x00000069,0x000000D9,0x0000008E,0x00000094,\n 0x0000009B,0x0000001E,0x00000087,0x000000E9,0x000000CE,0x00000055,0x00000028,0x000000DF,\n 0x0000008C,0x000000A1,0x00000089,0x0000000D,0x000000BF,0x000000E6,0x00000042,0x00000068,\n 0x00000041,0x00000099,0x0000002D,0x0000000F,0x000000B0,0x00000054,0x000000BB,0x00000016 \n },\n {\n 0x00006300,0x00007C00,0x00007700,0x00007B00,0x0000F200,0x00006B00,0x00006F00,0x0000C500,\n 0x00003000,0x00000100,0x00006700,0x00002B00,0x0000FE00,0x0000D700,0x0000AB00,0x00007600,\n 0x0000CA00,0x00008200,0x0000C900,0x00007D00,0x0000FA00,0x00005900,0x00004700,0x0000F000,\n 0x0000AD00,0x0000D400,0x0000A200,0x0000AF00,0x00009C00,0x0000A400,0x00007200,0x0000C000,\n 0x0000B700,0x0000FD00,0x00009300,0x00002600,0x00003600,0x00003F00,0x0000F700,0x0000CC00,\n 0x00003400,0x0000A500,0x0000E500,0x0000F100,0x00007100,0x0000D800,0x00003100,0x00001500,\n 0x00000400,0x0000C700,0x00002300,0x0000C300,0x00001800,0x00009600,0x00000500,0x00009A00,\n 0x00000700,0x00001200,0x00008000,0x0000E200,0x0000EB00,0x00002700,0x0000B200,0x00007500,\n 0x00000900,0x00008300,0x00002C00,0x00001A00,0x00001B00,0x00006E00,0x00005A00,0x0000A000,\n 0x00005200,0x00003B00,0x0000D600,0x0000B300,0x00002900,0x0000E300,0x00002F00,0x00008400,\n 0x00005300,0x0000D100,0000000000,0x0000ED00,0x00002000,0x0000FC00,0x0000B100,0x00005B00,\n 0x00006A00,0x0000CB00,0x0000BE00,0x00003900,0x00004A00,0x00004C00,0x00005800,0x0000CF00,\n 0x0000D000,0x0000EF00,0x0000AA00,0x0000FB00,0x00004300,0x00004D00,0x00003300,0x00008500,\n 0x00004500,0x0000F900,0x00000200,0x00007F00,0x00005000,0x00003C00,0x00009F00,0x0000A800,\n 0x00005100,0x0000A300,0x00004000,0x00008F00,0x00009200,0x00009D00,0x00003800,0x0000F500,\n 0x0000BC00,0x0000B600,0x0000DA00,0x00002100,0x00001000,0x0000FF00,0x0000F300,0x0000D200,\n 0x0000CD00,0x00000C00,0x00001300,0x0000EC00,0x00005F00,0x00009700,0x00004400,0x00001700,\n 0x0000C400,0x0000A700,0x00007E00,0x00003D00,0x00006400,0x00005D00,0x00001900,0x00007300,\n 0x00006000,0x00008100,0x00004F00,0x0000DC00,0x00002200,0x00002A00,0x00009000,0x00008800,\n 0x00004600,0x0000EE00,0x0000B800,0x00001400,0x0000DE00,0x00005E00,0x00000B00,0x0000DB00,\n 0x0000E000,0x00003200,0x00003A00,0x00000A00,0x00004900,0x00000600,0x00002400,0x00005C00,\n 0x0000C200,0x0000D300,0x0000AC00,0x00006200,0x00009100,0x00009500,0x0000E400,0x00007900,\n 0x0000E700,0x0000C800,0x00003700,0x00006D00,0x00008D00,0x0000D500,0x00004E00,0x0000A900,\n 0x00006C00,0x00005600,0x0000F400,0x0000EA00,0x00006500,0x00007A00,0x0000AE00,0x00000800,\n 0x0000BA00,0x00007800,0x00002500,0x00002E00,0x00001C00,0x0000A600,0x0000B400,0x0000C600,\n 0x0000E800,0x0000DD00,0x00007400,0x00001F00,0x00004B00,0x0000BD00,0x00008B00,0x00008A00,\n 0x00007000,0x00003E00,0x0000B500,0x00006600,0x00004800,0x00000300,0x0000F600,0x00000E00,\n 0x00006100,0x00003500,0x00005700,0x0000B900,0x00008600,0x0000C100,0x00001D00,0x00009E00,\n 0x0000E100,0x0000F800,0x00009800,0x00001100,0x00006900,0x0000D900,0x00008E00,0x00009400,\n 0x00009B00,0x00001E00,0x00008700,0x0000E900,0x0000CE00,0x00005500,0x00002800,0x0000DF00,\n 0x00008C00,0x0000A100,0x00008900,0x00000D00,0x0000BF00,0x0000E600,0x00004200,0x00006800,\n 0x00004100,0x00009900,0x00002D00,0x00000F00,0x0000B000,0x00005400,0x0000BB00,0x00001600 \n },\n {\n 0x00630000,0x007C0000,0x00770000,0x007B0000,0x00F20000,0x006B0000,0x006F0000,0x00C50000,\n 0x00300000,0x00010000,0x00670000,0x002B0000,0x00FE0000,0x00D70000,0x00AB0000,0x00760000,\n 0x00CA0000,0x00820000,0x00C90000,0x007D0000,0x00FA0000,0x00590000,0x00470000,0x00F00000,\n 0x00AD0000,0x00D40000,0x00A20000,0x00AF0000,0x009C0000,0x00A40000,0x00720000,0x00C00000,\n 0x00B70000,0x00FD0000,0x00930000,0x00260000,0x00360000,0x003F0000,0x00F70000,0x00CC0000,\n 0x00340000,0x00A50000,0x00E50000,0x00F10000,0x00710000,0x00D80000,0x00310000,0x00150000,\n 0x00040000,0x00C70000,0x00230000,0x00C30000,0x00180000,0x00960000,0x00050000,0x009A0000,\n 0x00070000,0x00120000,0x00800000,0x00E20000,0x00EB0000,0x00270000,0x00B20000,0x00750000,\n 0x00090000,0x00830000,0x002C0000,0x001A0000,0x001B0000,0x006E0000,0x005A0000,0x00A00000,\n 0x00520000,0x003B0000,0x00D60000,0x00B30000,0x00290000,0x00E30000,0x002F0000,0x00840000,\n 0x00530000,0x00D10000,0000000000,0x00ED0000,0x00200000,0x00FC0000,0x00B10000,0x005B0000,\n 0x006A0000,0x00CB0000,0x00BE0000,0x00390000,0x004A0000,0x004C0000,0x00580000,0x00CF0000,\n 0x00D00000,0x00EF0000,0x00AA0000,0x00FB0000,0x00430000,0x004D0000,0x00330000,0x00850000,\n 0x00450000,0x00F90000,0x00020000,0x007F0000,0x00500000,0x003C0000,0x009F0000,0x00A80000,\n 0x00510000,0x00A30000,0x00400000,0x008F0000,0x00920000,0x009D0000,0x00380000,0x00F50000,\n 0x00BC0000,0x00B60000,0x00DA0000,0x00210000,0x00100000,0x00FF0000,0x00F30000,0x00D20000,\n 0x00CD0000,0x000C0000,0x00130000,0x00EC0000,0x005F0000,0x00970000,0x00440000,0x00170000,\n 0x00C40000,0x00A70000,0x007E0000,0x003D0000,0x00640000,0x005D0000,0x00190000,0x00730000,\n 0x00600000,0x00810000,0x004F0000,0x00DC0000,0x00220000,0x002A0000,0x00900000,0x00880000,\n 0x00460000,0x00EE0000,0x00B80000,0x00140000,0x00DE0000,0x005E0000,0x000B0000,0x00DB0000,\n 0x00E00000,0x00320000,0x003A0000,0x000A0000,0x00490000,0x00060000,0x00240000,0x005C0000,\n 0x00C20000,0x00D30000,0x00AC0000,0x00620000,0x00910000,0x00950000,0x00E40000,0x00790000,\n 0x00E70000,0x00C80000,0x00370000,0x006D0000,0x008D0000,0x00D50000,0x004E0000,0x00A90000,\n 0x006C0000,0x00560000,0x00F40000,0x00EA0000,0x00650000,0x007A0000,0x00AE0000,0x00080000,\n 0x00BA0000,0x00780000,0x00250000,0x002E0000,0x001C0000,0x00A60000,0x00B40000,0x00C60000,\n 0x00E80000,0x00DD0000,0x00740000,0x001F0000,0x004B0000,0x00BD0000,0x008B0000,0x008A0000,\n 0x00700000,0x003E0000,0x00B50000,0x00660000,0x00480000,0x00030000,0x00F60000,0x000E0000,\n 0x00610000,0x00350000,0x00570000,0x00B90000,0x00860000,0x00C10000,0x001D0000,0x009E0000,\n 0x00E10000,0x00F80000,0x00980000,0x00110000,0x00690000,0x00D90000,0x008E0000,0x00940000,\n 0x009B0000,0x001E0000,0x00870000,0x00E90000,0x00CE0000,0x00550000,0x00280000,0x00DF0000,\n 0x008C0000,0x00A10000,0x00890000,0x000D0000,0x00BF0000,0x00E60000,0x00420000,0x00680000,\n 0x00410000,0x00990000,0x002D0000,0x000F0000,0x00B00000,0x00540000,0x00BB0000,0x00160000 \n },\n {\n 0x63000000,0x7C000000,0x77000000,0x7B000000,0xF2000000,0x6B000000,0x6F000000,0xC5000000,\n 0x30000000,0x01000000,0x67000000,0x2B000000,0xFE000000,0xD7000000,0xAB000000,0x76000000,\n 0xCA000000,0x82000000,0xC9000000,0x7D000000,0xFA000000,0x59000000,0x47000000,0xF0000000,\n 0xAD000000,0xD4000000,0xA2000000,0xAF000000,0x9C000000,0xA4000000,0x72000000,0xC0000000,\n 0xB7000000,0xFD000000,0x93000000,0x26000000,0x36000000,0x3F000000,0xF7000000,0xCC000000,\n 0x34000000,0xA5000000,0xE5000000,0xF1000000,0x71000000,0xD8000000,0x31000000,0x15000000,\n 0x04000000,0xC7000000,0x23000000,0xC3000000,0x18000000,0x96000000,0x05000000,0x9A000000,\n 0x07000000,0x12000000,0x80000000,0xE2000000,0xEB000000,0x27000000,0xB2000000,0x75000000,\n 0x09000000,0x83000000,0x2C000000,0x1A000000,0x1B000000,0x6E000000,0x5A000000,0xA0000000,\n 0x52000000,0x3B000000,0xD6000000,0xB3000000,0x29000000,0xE3000000,0x2F000000,0x84000000,\n 0x53000000,0xD1000000,0000000000,0xED000000,0x20000000,0xFC000000,0xB1000000,0x5B000000,\n 0x6A000000,0xCB000000,0xBE000000,0x39000000,0x4A000000,0x4C000000,0x58000000,0xCF000000,\n 0xD0000000,0xEF000000,0xAA000000,0xFB000000,0x43000000,0x4D000000,0x33000000,0x85000000,\n 0x45000000,0xF9000000,0x02000000,0x7F000000,0x50000000,0x3C000000,0x9F000000,0xA8000000,\n 0x51000000,0xA3000000,0x40000000,0x8F000000,0x92000000,0x9D000000,0x38000000,0xF5000000,\n 0xBC000000,0xB6000000,0xDA000000,0x21000000,0x10000000,0xFF000000,0xF3000000,0xD2000000,\n 0xCD000000,0x0C000000,0x13000000,0xEC000000,0x5F000000,0x97000000,0x44000000,0x17000000,\n 0xC4000000,0xA7000000,0x7E000000,0x3D000000,0x64000000,0x5D000000,0x19000000,0x73000000,\n 0x60000000,0x81000000,0x4F000000,0xDC000000,0x22000000,0x2A000000,0x90000000,0x88000000,\n 0x46000000,0xEE000000,0xB8000000,0x14000000,0xDE000000,0x5E000000,0x0B000000,0xDB000000,\n 0xE0000000,0x32000000,0x3A000000,0x0A000000,0x49000000,0x06000000,0x24000000,0x5C000000,\n 0xC2000000,0xD3000000,0xAC000000,0x62000000,0x91000000,0x95000000,0xE4000000,0x79000000,\n 0xE7000000,0xC8000000,0x37000000,0x6D000000,0x8D000000,0xD5000000,0x4E000000,0xA9000000,\n 0x6C000000,0x56000000,0xF4000000,0xEA000000,0x65000000,0x7A000000,0xAE000000,0x08000000,\n 0xBA000000,0x78000000,0x25000000,0x2E000000,0x1C000000,0xA6000000,0xB4000000,0xC6000000,\n 0xE8000000,0xDD000000,0x74000000,0x1F000000,0x4B000000,0xBD000000,0x8B000000,0x8A000000,\n 0x70000000,0x3E000000,0xB5000000,0x66000000,0x48000000,0x03000000,0xF6000000,0x0E000000,\n 0x61000000,0x35000000,0x57000000,0xB9000000,0x86000000,0xC1000000,0x1D000000,0x9E000000,\n 0xE1000000,0xF8000000,0x98000000,0x11000000,0x69000000,0xD9000000,0x8E000000,0x94000000,\n 0x9B000000,0x1E000000,0x87000000,0xE9000000,0xCE000000,0x55000000,0x28000000,0xDF000000,\n 0x8C000000,0xA1000000,0x89000000,0x0D000000,0xBF000000,0xE6000000,0x42000000,0x68000000,\n 0x41000000,0x99000000,0x2D000000,0x0F000000,0xB0000000,0x54000000,0xBB000000,0x16000000 \n } \n};\n\n/*----------------- The workspace ------------------------------*/\n\nstatic u32 Ekey[44];\t/* The expanded key */\n\n/*------ The round Function.  4 table lookups and 4 Exors ------*/\n#define f_rnd(x, n)                     \\\n  ( ft_tab[0][byte0(x[n])]              \\\n  ^ ft_tab[1][byte1(x[(n + 1) & 3])]    \\\n  ^ ft_tab[2][byte2(x[(n + 2) & 3])]    \\\n  ^ ft_tab[3][byte3(x[(n + 3) & 3])] )\n\n#define f_round(bo, bi, k)          \\\n    bo[0] = f_rnd(bi, 0) ^ k[0];    \\\n    bo[1] = f_rnd(bi, 1) ^ k[1];    \\\n    bo[2] = f_rnd(bi, 2) ^ k[2];    \\\n    bo[3] = f_rnd(bi, 3) ^ k[3];    \\\n    k += 4\n\n/*--- The S Box lookup used in constructing the Key schedule ---*/\n#define ls_box(x)       \\\n (  fl_tab[0][byte0(x)] \\\n  ^ fl_tab[1][byte1(x)] \\\n  ^ fl_tab[2][byte2(x)] \\\n  ^ fl_tab[3][byte3(x)] )\n\n/*------------ The last round function (no MixColumn) ----------*/\n#define lf_rnd(x, n)                    \\\n  ( fl_tab[0][byte0(x[n])]              \\\n  ^ fl_tab[1][byte1(x[(n + 1) & 3])]    \\\n  ^ fl_tab[2][byte2(x[(n + 2) & 3])]    \\\n  ^ fl_tab[3][byte3(x[(n + 3) & 3])] )\n\n\n/*-----------------------------------------------------------\n * RijndaelKeySchedule\n *   Initialise the key schedule from a supplied key\n */\nvoid RijndaelKeySchedule(u8 key[16])\n{\n    u32  t;\n    u32  *ek=Ekey,\t    /* pointer to the expanded key   */\n         *rc=rnd_con;   /* pointer to the round constant */\n\n    Ekey[0] = u32_in(key     );\n    Ekey[1] = u32_in(key +  4);\n    Ekey[2] = u32_in(key +  8);\n    Ekey[3] = u32_in(key + 12);\n\n\twhile(ek < Ekey + 40)\n    {\n\t\tt = rot3(ek[3]);\n        ek[4] = ek[0] ^ ls_box(t) ^ *rc++;\n        ek[5] = ek[1] ^ ek[4];\n        ek[6] = ek[2] ^ ek[5];\n        ek[7] = ek[3] ^ ek[6];\n        ek += 4;\n    }\n}\n\n/*-----------------------------------------------------------\n * RijndaelEncrypt\n *   Encrypt an input block\n */\nvoid RijndaelEncrypt(u8 in[16], u8 out[16])\n{\n    u32    b0[4], b1[4], *kp = Ekey;\n\n    b0[0] = u32_in(in     ) ^ *kp++;\n    b0[1] = u32_in(in +  4) ^ *kp++;\n    b0[2] = u32_in(in +  8) ^ *kp++;\n    b0[3] = u32_in(in + 12) ^ *kp++;\n\n    f_round(b1, b0, kp); \n    f_round(b0, b1, kp);\n    f_round(b1, b0, kp); \n    f_round(b0, b1, kp);\n    f_round(b1, b0, kp); \n    f_round(b0, b1, kp);\n    f_round(b1, b0, kp); \n    f_round(b0, b1, kp);\n    f_round(b1, b0, kp); \n\n    u32_out(out,      lf_rnd(b1, 0) ^ kp[0]); \n    u32_out(out +  4, lf_rnd(b1, 1) ^ kp[1]);\n    u32_out(out +  8, lf_rnd(b1, 2) ^ kp[2]); \n    u32_out(out + 12, lf_rnd(b1, 3) ^ kp[3]);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/milenage/rijndael.h",
    "content": "/*-------------------------------------------------------------------\n *          Example algorithms f1, f1*, f2, f3, f4, f5, f5*\n *-------------------------------------------------------------------\n *\n *  A sample implementation of the example 3GPP authentication and\n *  key agreement functions f1, f1*, f2, f3, f4, f5 and f5*.  This is\n *  a byte-oriented implementation of the functions, and of the block\n *  cipher kernel function Rijndael.\n *\n *  This has been coded for clarity, not necessarily for efficiency.\n *\n *  The functions f2, f3, f4 and f5 share the same inputs and have\n *  been coded together as a single function.  f1, f1* and f5* are\n *  all coded separately.\n *\n *-----------------------------------------------------------------*/\n\n#ifndef RIJNDAEL_H\n#define RIJNDAEL_H\n\n\nvoid RijndaelKeySchedule( u8 key[16] );\nvoid RijndaelEncrypt( u8 input[16], u8 output[16] );\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/mp3/BladeMP3EncDLL.h",
    "content": "/*\n * Blade Type of DLL Interface for Lame encoder\n *\n * Copyright (c) 1999-2002 A.L. Faber\n * Based on bladedll.h version 1.0 written by Jukka Poikolainen\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n * \n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n * \n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA  02111-1307, USA.\n */\n\n//#define _BLADEDLL 1\n\n#ifndef ___BLADEDLL_H_INCLUDED___\n#define ___BLADEDLL_H_INCLUDED___\n\n#ifdef __GNUC__\n//#define ATTRIBUTE_PACKED\t__attribute__((packed))\n#define ATTRIBUTE_PACKED\n#else\n#define ATTRIBUTE_PACKED\n#pragma pack(push)\n#pragma pack(1)\n#endif\n\n#ifdef\t__cplusplus\nextern \"C\" {\n#endif\n\n/* encoding formats */\n\n#define\t\tBE_CONFIG_MP3\t\t\t0\t\t\t\t\t\t\t\t\t\t\n#define\t\tBE_CONFIG_LAME\t\t\t256\t\t\n\n/* type definitions */\n\ntypedef\t\tunsigned long\t\t\tHBE_STREAM;\ntypedef\t\tHBE_STREAM\t\t\t\t*PHBE_STREAM;\ntypedef\t\tunsigned long\t\t\tBE_ERR;\n\n/* error codes */\n\n#define\t\tBE_ERR_SUCCESSFUL\t\t\t\t\t0x00000000\n#define\t\tBE_ERR_INVALID_FORMAT\t\t\t\t0x00000001\n#define\t\tBE_ERR_INVALID_FORMAT_PARAMETERS\t0x00000002\n#define\t\tBE_ERR_NO_MORE_HANDLES\t\t\t\t0x00000003\n#define\t\tBE_ERR_INVALID_HANDLE\t\t\t\t0x00000004\n#define\t\tBE_ERR_BUFFER_TOO_SMALL\t\t\t\t0x00000005\n\n/* other constants */\n\n#define\t\tBE_MAX_HOMEPAGE\t\t\t128\n\n/* format specific variables */\n\n#define\t\tBE_MP3_MODE_STEREO\t\t0\n#define\t\tBE_MP3_MODE_JSTEREO\t\t1\n#define\t\tBE_MP3_MODE_DUALCHANNEL\t2\n#define\t\tBE_MP3_MODE_MONO\t\t3\n\n\n\n#define\t\tMPEG1\t1\n#define\t\tMPEG2\t0\n\n#ifdef _BLADEDLL\n#undef FLOAT\n\t#include <Windows.h>\n#endif\n\n#define CURRENT_STRUCT_VERSION 1\n#define CURRENT_STRUCT_SIZE sizeof(BE_CONFIG)\t// is currently 331 bytes\n\n\ntypedef enum\n{\n\tVBR_METHOD_NONE\t\t\t= -1,\n\tVBR_METHOD_DEFAULT\t\t=  0,\n\tVBR_METHOD_OLD\t\t\t=  1,\n\tVBR_METHOD_NEW\t\t\t=  2,\n\tVBR_METHOD_MTRH\t\t\t=  3,\n\tVBR_METHOD_ABR\t\t\t=  4\n} VBRMETHOD;\n\ntypedef enum \n{\n\tLQP_NOPRESET\t\t\t=-1,\n\n\t// QUALITY PRESETS\n\tLQP_NORMAL_QUALITY\t\t= 0,\n\tLQP_LOW_QUALITY\t\t\t= 1,\n\tLQP_HIGH_QUALITY\t\t= 2,\n\tLQP_VOICE_QUALITY\t\t= 3,\n\tLQP_R3MIX\t\t\t\t= 4,\n\tLQP_VERYHIGH_QUALITY\t= 5,\n\tLQP_STANDARD\t\t\t= 6,\n\tLQP_FAST_STANDARD\t\t= 7,\n\tLQP_EXTREME\t\t\t\t= 8,\n\tLQP_FAST_EXTREME\t\t= 9,\n\tLQP_INSANE\t\t\t\t= 10,\n\tLQP_ABR\t\t\t\t\t= 11,\n\tLQP_CBR\t\t\t\t\t= 12,\n\tLQP_MEDIUM\t\t\t\t= 13,\n\tLQP_FAST_MEDIUM\t\t\t= 14,\n\n\t// NEW PRESET VALUES\n\tLQP_PHONE\t=1000,\n\tLQP_SW\t\t=2000,\n\tLQP_AM\t\t=3000,\n\tLQP_FM\t\t=4000,\n\tLQP_VOICE\t=5000,\n\tLQP_RADIO\t=6000,\n\tLQP_TAPE\t=7000,\n\tLQP_HIFI\t=8000,\n\tLQP_CD\t\t=9000,\n\tLQP_STUDIO\t=10000\n\n} LAME_QUALITY_PRESET;\n\n\n\ntypedef struct\t{\n\tunsigned long\tdwConfig;\t\t\t// BE_CONFIG_XXXXX\n\t\t\t\t\t\t\t\t// Currently only BE_CONFIG_MP3 is supported\n\tunion\t{\n\n\t\tstruct\t{\n\n\t\t\tunsigned long\tdwSampleRate;\t\t// 48000, 44100 and 32000 allowed\n\t\t\tunsigned char\tbyMode;\t\t\t// BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO\n\t\t\tunsigned short\twBitrate;\t\t// 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 and 320 allowed\n\t\t\tint\tbPrivate;\t\t\n\t\t\tint\tbCRC;\n\t\t\tint\tbCopyright;\n\t\t\tint\tbOriginal;\n\n\t\t\t} mp3;\t\t\t\t\t// BE_CONFIG_MP3\n\n\t\t\tstruct\n\t\t\t{\n\t\t\t// STRUCTURE INFORMATION\n\t\t\tunsigned long\t\t\tdwStructVersion;\t\n\t\t\tunsigned long\t\t\tdwStructSize;\n\n\t\t\t// BASIC ENCODER SETTINGS\n\t\t\tunsigned long\t\t\tdwSampleRate;\t\t// SAMPLERATE OF INPUT FILE\n\t\t\tunsigned long\t\t\tdwReSampleRate;\t\t// DOWNSAMPLERATE, 0=ENCODER DECIDES  \n\t\t\tlong\t\t\tnMode;\t\t\t\t// BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO\n\t\t\tunsigned long\t\t\tdwBitrate;\t\t\t// CBR bitrate, VBR min bitrate\n\t\t\tunsigned long\t\t\tdwMaxBitrate;\t\t// CBR ignored, VBR Max bitrate\n\t\t\tlong\t\t\tnPreset;\t\t\t// Quality preset, use one of the settings of the LAME_QUALITY_PRESET enum\n\t\t\tunsigned long\t\t\tdwMpegVersion;\t\t// FUTURE USE, MPEG-1 OR MPEG-2\n\t\t\tunsigned long\t\t\tdwPsyModel;\t\t\t// FUTURE USE, SET TO 0\n\t\t\tunsigned long\t\t\tdwEmphasis;\t\t\t// FUTURE USE, SET TO 0\n\n\t\t\t// BIT STREAM SETTINGS\n\t\t\tint\t\t\tbPrivate;\t\t\t// Set Private Bit (TRUE/FALSE)\n\t\t\tint\t\t\tbCRC;\t\t\t\t// Insert CRC (TRUE/FALSE)\n\t\t\tint\t\t\tbCopyright;\t\t\t// Set Copyright Bit (TRUE/FALSE)\n\t\t\tint\t\t\tbOriginal;\t\t\t// Set Original Bit (TRUE/FALSE)\n\t\t\t\n\t\t\t// VBR STUFF\n\t\t\tint\t\t\tbWriteVBRHeader;\t// WRITE XING VBR HEADER (TRUE/FALSE)\n\t\t\tint\t\t\tbEnableVBR;\t\t\t// USE VBR ENCODING (TRUE/FALSE)\n\t\t\tint\t\t\t\tnVBRQuality;\t\t// VBR QUALITY 0..9\n\t\t\tunsigned long\t\t\tdwVbrAbr_bps;\t\t// Use ABR in stead of nVBRQuality\n\t\t\tVBRMETHOD\t\tnVbrMethod;\n\t\t\tint\t\t\tbNoRes;\t\t\t\t// Disable Bit resorvoir (TRUE/FALSE)\n\n\t\t\t// MISC SETTINGS\n\t\t\tint\t\t\tbStrictIso;\t\t\t// Use strict ISO encoding rules (TRUE/FALSE)\n\t\t\tunsigned short\t\t\tnQuality;\t\t\t// Quality Setting, HIGH unsigned char should be NOT LOW byte, otherwhise quality=5\n\n\t\t\t// FUTURE USE, SET TO 0, align strucutre to 331 bytes\n\t\t\tunsigned char\t\t\tbtReserved[255-4*sizeof(unsigned long) - sizeof( unsigned short )];\n\n\t\t\t} LHV1;\t\t\t\t\t// LAME header version 1\n\n\t\tstruct\t{\n\n\t\t\tunsigned long\tdwSampleRate;\n\t\t\tunsigned char\tbyMode;\n\t\t\tunsigned short\twBitrate;\n\t\t\tunsigned char\tbyEncodingMethod;\n\n\t\t} aac;\n\n\t} format;\n\t\t\n} BE_CONFIG, *PBE_CONFIG ATTRIBUTE_PACKED;\n\n\ntypedef struct\t{\n\n\t// BladeEnc DLL Version number\n\n\tunsigned char\tbyDLLMajorVersion;\n\tunsigned char\tbyDLLMinorVersion;\n\n\t// BladeEnc Engine Version Number\n\n\tunsigned char\tbyMajorVersion;\n\tunsigned char\tbyMinorVersion;\n\n\t// DLL Release date\n\n\tunsigned char\tbyDay;\n\tunsigned char\tbyMonth;\n\tunsigned short\twYear;\n\n\t// BladeEnc\tHomepage URL\n\n\tchar\tzHomepage[BE_MAX_HOMEPAGE + 1];\t\n\n\tunsigned char\tbyAlphaLevel;\n\tunsigned char\tbyBetaLevel;\n\tunsigned char\tbyMMXEnabled;\n\n\tunsigned char\tbtReserved[125];\n\n\n} BE_VERSION, *PBE_VERSION ATTRIBUTE_PACKED;\n\n#ifndef _BLADEDLL\n\ntypedef unsigned long\t(*BEINITSTREAM)\t\t\t(PBE_CONFIG, unsigned long *, unsigned long *, PHBE_STREAM);\ntypedef unsigned long\t(*BEENCODECHUNK)\t\t(HBE_STREAM, unsigned long, short *, unsigned char *, unsigned long *);\n\n// added for floating point audio  -- DSPguru, jd\ntypedef unsigned long\t(*BEENCODECHUNKFLOATS16NI)\t(HBE_STREAM, unsigned long, float *, float *, unsigned char *, unsigned long *);\ntypedef unsigned long\t(*BEDEINITSTREAM)\t\t\t(HBE_STREAM, unsigned char *, unsigned long *);\ntypedef unsigned long\t(*BECLOSESTREAM)\t\t\t(HBE_STREAM);\ntypedef void\t(*BEVERSION)\t\t\t\t(PBE_VERSION);\ntypedef unsigned long\t(*BEWRITEVBRHEADER)\t\t\t(const char*);\ntypedef unsigned long\t(*BEWRITEINFOTAG)\t\t\t(HBE_STREAM, const char * );\n\n#define\tTEXT_BEINITSTREAM\t\t\t\t\"beInitStream\"\n#define\tTEXT_BEENCODECHUNK\t\t\t\t\"beEncodeChunk\"\n#define\tTEXT_BEENCODECHUNKFLOATS16NI\t\"beEncodeChunkFloatS16NI\"\n#define\tTEXT_BEDEINITSTREAM\t\t\t\t\"beDeinitStream\"\n#define\tTEXT_BECLOSESTREAM\t\t\t\t\"beCloseStream\"\n#define\tTEXT_BEVERSION\t\t\t\t\t\"beVersion\"\n#define\tTEXT_BEWRITEVBRHEADER\t\t\t\"beWriteVBRHeader\"\n#define\tTEXT_BEFLUSHNOGAP\t\t\t\t\"beFlushNoGap\"\n#define\tTEXT_BEWRITEINFOTAG\t\t\t\t\"beWriteInfoTag\"\n\n\n#else\n\n__declspec(dllexport) unsigned long\tbeInitStream(PBE_CONFIG pbeConfig, Punsigned long dwSamples, Punsigned long dwBufferSize, PHBE_STREAM phbeStream);\n__declspec(dllexport) unsigned long\tbeEncodeChunk(HBE_STREAM hbeStream, unsigned long nSamples, PSHORT pSamples, Punsigned char pOutput, Punsigned long pdwOutput);\n\n// added for floating point audio  -- DSPguru, jd\n__declspec(dllexport) unsigned long\tbeEncodeChunkFloatS16NI(HBE_STREAM hbeStream, unsigned long nSamples, PFLOAT buffer_l, PFLOAT buffer_r, Punsigned char pOutput, Punsigned long pdwOutput);\n__declspec(dllexport) unsigned long\tbeDeinitStream(HBE_STREAM hbeStream, Punsigned char pOutput, Punsigned long pdwOutput);\n__declspec(dllexport) unsigned long\tbeCloseStream(HBE_STREAM hbeStream);\n__declspec(dllexport) VOID\t\tbeVersion(PBE_VERSION pbeVersion);\n__declspec(dllexport) unsigned long\tbeWriteVBRHeader(LPCSTR lpszFileName);\n__declspec(dllexport) unsigned long\tbeFlushNoGap(HBE_STREAM hbeStream, Punsigned char pOutput, Punsigned long pdwOutput);\n__declspec(dllexport) unsigned long\tbeWriteInfoTag( HBE_STREAM hbeStream, LPCSTR lpszFileName );\n\n#endif\n\n#ifndef __GNUC__\n#pragma pack(pop)\n#endif\n\n#ifdef\t__cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/mp3/mp3_port.h",
    "content": "/* $Id: mp3_port.h 1177 2007-04-09 07:06:08Z bennylp $ */\n/* \n * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * Contributed by:\n *  Toni < buldozer at aufbix dot org >\n */\n\n#ifndef __PJMEDIA_MP3_PORT_H__\n#define __PJMEDIA_MP3_PORT_H__\n\n\n/**\n * @file mp3_port.h\n * @brief MP3 writer\n */\n#include <pjmedia/port.h>\n\n/**\n * @defgroup PJMEDIA_MP3_FILE_REC MP3 Audio File Writer (Recorder)\n * @ingroup PJMEDIA_PORT\n * @brief MP3 Audio File Writer (Recorder)\n * @{\n *\n * This section describes MP3 file writer. Currently it only works on Windows\n * using BladeEncDLL of the LAME MP3 encoder. <b>Note that the LAME_ENC.DLL \n * file must exist in the PATH so that the encoder can work properly.</b>\n *\n * The MP3 file writer is created with #pjmedia_mp3_writer_port_create() which\n * among other things specifies the desired file name and audio properties.\n * It then takes PCM input when #pjmedia_port_put_frame() is called and encode\n * the PCM input into MP3 streams before writing it to the .mp3 file.\n */\n\n\nPJ_BEGIN_DECL\n\n\n/**\n * This structure contains encoding options that can be specified during\n * MP3 writer port creation. Application should always zero the structure\n * before setting some value to make sure that default options will be used.\n */\ntypedef struct pjmedia_mp3_encoder_option\n{\n    /** Specify whether variable bit rate should be used. Variable bitrate\n     *  would normally produce better quality at the expense of probably\n     *  larger file.\n     */\n    pj_bool_t\tvbr;\n\n    /** Target bitrate, in bps. If VBR is enabled, this settings specifies \n     *  the  average bit-rate requested, and will make the encoder ignore \n     *  the quality setting. For CBR, this specifies the actual bitrate,\n     *  and if this option is zero, it will be set to the sampling rate\n     *  multiplied by number of channels.\n     */\n    unsigned\tbit_rate;\n\n    /** Encoding quality, 0-9, with 0 is the highest quality. For VBR, the \n     *  quality setting will only take effect when bit_rate setting is zero.\n     */\n    unsigned\tquality;\n\n} pjmedia_mp3_encoder_option;\n\n\n/**\n * Create a media port to record PCM media to a MP3 file. After the port\n * is created, application can call #pjmedia_port_put_frame() to feed the\n * port with PCM frames. The port then will encode the PCM frame into MP3\n * stream, and store it to MP3 file specified in the argument.\n *\n * When application has finished with writing MP3 file, it must destroy the\n * media port with #pjmedia_port_destroy() so that the MP3 file can be\n * closed properly.\n *\n * @param pool\t\t    Pool to create memory buffers for this port.\n * @param filename\t    File name.\n * @param clock_rate\t    The sampling rate.\n * @param channel_count\t    Number of channels.\n * @param samples_per_frame Number of samples per frame.\n * @param bits_per_sample   Number of bits per sample (eg 16).\n * @param option\t    Optional option to set encoding parameters.\n * @param p_port\t    Pointer to receive the file port instance.\n *\n * @return\t\t    PJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_mp3_writer_port_create(pj_pool_t *pool,\n\t\t\t       const char *filename,\n\t\t\t       unsigned clock_rate,\n\t\t\t       unsigned channel_count,\n\t\t\t       unsigned samples_per_frame,\n\t\t\t       unsigned bits_per_sample,\n\t\t\t       const pjmedia_mp3_encoder_option *option,\n\t\t\t       pjmedia_port **p_port );\n\n/**\n * Register the callback to be called when the file writing has reached\n * certain size. Application can use this callback, for example, to limit\n * the size of the output file.\n *\n * @param port\t\tThe file writer port.\n * @param pos\t\tThe file position on which the callback will be called.\n * @param user_data\tUser data to be specified in the callback, and will be\n *\t\t\tgiven on the callback.\n * @param cb\t\tCallback to be called. If the callback returns non-\n *\t\t\tPJ_SUCCESS, the writing will stop. Note that if \n *\t\t\tapplication destroys the port in the callback, it must\n *\t\t\treturn non-PJ_SUCCESS here.\n *\n * @return\t\tPJ_SUCCESS on success.\n */\nPJ_DECL(pj_status_t) \npjmedia_mp3_writer_port_set_cb( pjmedia_port *port,\n\t\t\t\tpj_size_t pos,\n\t\t\t\tvoid *user_data,\n\t\t\t\tpj_status_t (*cb)(pjmedia_port *port,\n\t\t\t\t\t\t\tvoid *usr_data));\n\n\n/**\n * @}\n */\n\n\nPJ_END_DECL\n\n#endif\t/* __PJMEDIA_MP3_PORT_H__ */\n\n"
  },
  {
    "path": "deps/pjsip/third_party/mp3/mp3_writer.c",
    "content": "/* $Id: mp3_writer.c 4483 2013-04-19 09:52:02Z ming $ */\n/* \n * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n\n/*\n * Contributed by:\n *  Toni < buldozer at aufbix dot org >\n */\n#include \"mp3_port.h\"\n#include <pjmedia/errno.h>\n#include <pj/assert.h>\n#include <pj/file_access.h>\n#include <pj/file_io.h>\n#include <pj/log.h>\n#include <pj/pool.h>\n#include <pj/string.h>\n#include <pj/unicode.h>\n\n\n/* Include BladeDLL declarations */\n#include \"BladeMP3EncDLL.h\"\n\n\n#define THIS_FILE\t    \"mp3_writer.c\"\n#define SIGNATURE\t    PJMEDIA_SIG_CLASS_PORT_AUD('M','W')\n#define BYTES_PER_SAMPLE    2\n\nstatic struct BladeDLL\n{\n    void\t\t*hModule;\n    int\t\t\t refCount;\n    BEINITSTREAM\t beInitStream;\n    BEENCODECHUNK\t beEncodeChunk;\n    BEDEINITSTREAM\t beDeinitStream;\n    BECLOSESTREAM\t beCloseStream;\n    BEVERSION\t\t beVersion;\n    BEWRITEVBRHEADER\t beWriteVBRHeader;\n    BEWRITEINFOTAG\t beWriteInfoTag;\n} BladeDLL;\n\n\nstruct mp3_file_port\n{\n    pjmedia_port    base;\n    pj_size_t\t    total;\n    pj_oshandle_t   fd;\n    pj_size_t\t    cb_size;\n    pj_status_t\t   (*cb)(pjmedia_port*, void*);\n\n    unsigned\t    silence_duration;\n\n    pj_str_t\t\t\tmp3_filename;\n    pjmedia_mp3_encoder_option  mp3_option;\n    unsigned\t\t        mp3_samples_per_frame;\n    pj_int16_t\t\t       *mp3_sample_buf;\n    unsigned\t\t\tmp3_sample_pos;\n    HBE_STREAM\t\t        mp3_stream;\n    unsigned char\t       *mp3_buf;\n};\n\n\nstatic pj_status_t file_put_frame(pjmedia_port *this_port, \n\t\t\t\t  const pjmedia_frame *frame);\nstatic pj_status_t file_get_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame);\nstatic pj_status_t file_on_destroy(pjmedia_port *this_port);\n\n\n#if defined(PJ_WIN32) || defined(_WIN32) || defined(WIN32)\n\n#include <windows.h>\n#define DLL_NAME    PJ_T(\"LAME_ENC.DLL\")\n\n/*\n * Load BladeEncoder DLL.\n */\nstatic pj_status_t init_blade_dll(void)\n{\n    if (BladeDLL.refCount == 0) {\n\t#define GET_PROC(type, name)  \\\n\t    BladeDLL.name = (type)GetProcAddress(BladeDLL.hModule, PJ_T(#name)); \\\n\t    if (BladeDLL.name == NULL) { \\\n\t\tPJ_LOG(1,(THIS_FILE, \"Unable to find %s in %s\", #name, DLL_NAME)); \\\n\t\treturn PJ_RETURN_OS_ERROR(GetLastError()); \\\n\t    }\n\n\tBE_VERSION beVersion;\n\tBladeDLL.hModule = (void*)LoadLibrary(DLL_NAME);\n\tif (BladeDLL.hModule == NULL) {\n\t    pj_status_t status = PJ_RETURN_OS_ERROR(GetLastError());\n\t    char errmsg[PJ_ERR_MSG_SIZE];\n\n\t    pj_strerror(status, errmsg, sizeof(errmsg));\n\t    PJ_LOG(1,(THIS_FILE, \"Unable to load %s: %s\", DLL_NAME, errmsg));\n\t    return status;\n\t}\n\n\tGET_PROC(BEINITSTREAM, beInitStream);\n\tGET_PROC(BEENCODECHUNK, beEncodeChunk);\n\tGET_PROC(BEDEINITSTREAM, beDeinitStream);\n\tGET_PROC(BECLOSESTREAM, beCloseStream);\n\tGET_PROC(BEVERSION, beVersion);\n\tGET_PROC(BEWRITEVBRHEADER, beWriteVBRHeader);\n\tGET_PROC(BEWRITEINFOTAG, beWriteInfoTag);\n\n\t#undef GET_PROC\n\n\tBladeDLL.beVersion(&beVersion);\n\tPJ_LOG(4,(THIS_FILE, \"%s encoder v%d.%d loaded (%s)\", DLL_NAME,\n\t\t  beVersion.byMajorVersion, beVersion.byMinorVersion,\n\t\t  beVersion.zHomepage));\n    }\n    ++BladeDLL.refCount;\n    return PJ_SUCCESS;\n}\n\n/*\n * Decrement the reference counter of the DLL.\n */\nstatic void deinit_blade_dll()\n{\n    --BladeDLL.refCount;\n    if (BladeDLL.refCount == 0 && BladeDLL.hModule) {\n\tFreeLibrary(BladeDLL.hModule);\n\tBladeDLL.hModule = NULL;\n\tPJ_LOG(4,(THIS_FILE, \"%s unloaded\", DLL_NAME));\n    }\n}\n\n#else\n\nstatic pj_status_t init_blade_dll(void)\n{\n    PJ_LOG(1,(THIS_FILE, \"Error: MP3 writer port only works on Windows for now\"));\n    return PJ_ENOTSUP;\n}\n\nstatic void deinit_blade_dll()\n{\n}\n#endif\n\n\n\n/*\n * Initialize MP3 encoder.\n */\nstatic pj_status_t init_mp3_encoder(struct mp3_file_port *fport,\n\t\t\t\t    pj_pool_t *pool)\n{\n    BE_CONFIG LConfig;\n    unsigned  long InSamples;\n    unsigned  long OutBuffSize;\n    long MP3Err;\n\n    /*\n     * Initialize encoder configuration.\n     */\n    pj_bzero(&LConfig, sizeof(BE_CONFIG));\n    LConfig.dwConfig = BE_CONFIG_LAME;\n    LConfig.format.LHV1.dwStructVersion = 1;\n    LConfig.format.LHV1.dwStructSize = sizeof(BE_CONFIG);\n    LConfig.format.LHV1.dwSampleRate = PJMEDIA_PIA_SRATE(&fport->base.info);\n    LConfig.format.LHV1.dwReSampleRate = 0;\n\n    if (PJMEDIA_PIA_CCNT(&fport->base.info)==1)\n\tLConfig.format.LHV1.nMode = BE_MP3_MODE_MONO;\n    else if (PJMEDIA_PIA_CCNT(&fport->base.info)==2)\n\tLConfig.format.LHV1.nMode = BE_MP3_MODE_STEREO;\n    else\n\treturn PJMEDIA_ENCCHANNEL;\n\n    LConfig.format.LHV1.dwBitrate = fport->mp3_option.bit_rate / 1000;\n    LConfig.format.LHV1.nPreset = LQP_NOPRESET;\n    LConfig.format.LHV1.bCopyright = 0;\n    LConfig.format.LHV1.bCRC = 1;\n    LConfig.format.LHV1.bOriginal = 1;\n    LConfig.format.LHV1.bPrivate = 0;\n\n    if (!fport->mp3_option.vbr) {\n\tLConfig.format.LHV1.nVbrMethod = VBR_METHOD_NONE;\n\tLConfig.format.LHV1.bWriteVBRHeader = 0;\n\tLConfig.format.LHV1.bEnableVBR = 0;\n    } else {\n\tLConfig.format.LHV1.nVbrMethod = VBR_METHOD_DEFAULT;\n\tLConfig.format.LHV1.bWriteVBRHeader = 1;\n\tLConfig.format.LHV1.dwVbrAbr_bps = fport->mp3_option.bit_rate;\n\tLConfig.format.LHV1.nVBRQuality =  (pj_uint16_t)\n\t\t\t\t\t   fport->mp3_option.quality;\n\tLConfig.format.LHV1.bEnableVBR = 1;\n    }\n\n    LConfig.format.LHV1.nQuality = (pj_uint16_t) \n\t\t\t\t   (((0-fport->mp3_option.quality-1)<<8) | \n\t\t\t\t    fport->mp3_option.quality);\n\n    /*\n     * Init MP3 stream.\n     */\n    InSamples = 0;\n    MP3Err = BladeDLL.beInitStream(&LConfig, &InSamples, &OutBuffSize,\n\t\t\t\t   &fport->mp3_stream);\n    if (MP3Err != BE_ERR_SUCCESSFUL) \n\treturn PJMEDIA_ERROR;\n\n    /*\n     * Allocate sample buffer.\n     */\n    fport->mp3_samples_per_frame = (unsigned)InSamples;\n    fport->mp3_sample_buf = pj_pool_alloc(pool, fport->mp3_samples_per_frame * 2);\n    if (!fport->mp3_sample_buf)\n\treturn PJ_ENOMEM;\n\n    /*\n     * Allocate encoded MP3 buffer.\n     */\n    fport->mp3_buf = pj_pool_alloc(pool, (pj_size_t)OutBuffSize);\n    if (fport->mp3_buf == NULL)\n\treturn PJ_ENOMEM;\n\n    \n    return PJ_SUCCESS;\n}\n\n\n/*\n * Create MP3 file writer port.\n */\nPJ_DEF(pj_status_t) \npjmedia_mp3_writer_port_create( pj_pool_t *pool,\n\t\t\t\tconst char *filename,\n\t\t\t\tunsigned sampling_rate,\n\t\t\t\tunsigned channel_count,\n\t\t\t\tunsigned samples_per_frame,\n\t\t\t\tunsigned bits_per_sample,\n\t\t\t\tconst pjmedia_mp3_encoder_option *param_option,\n\t\t\t\tpjmedia_port **p_port )\n{\n    struct mp3_file_port *fport;\n    pj_status_t status;\n\n    status = init_blade_dll();\n    if (status != PJ_SUCCESS)\n\treturn status;\n\n    /* Check arguments. */\n    PJ_ASSERT_RETURN(pool && filename && p_port, PJ_EINVAL);\n\n    /* Only supports 16bits per sample for now. */\n    PJ_ASSERT_RETURN(bits_per_sample == 16, PJ_EINVAL);\n\n    /* Create file port instance. */\n    fport = pj_pool_zalloc(pool, sizeof(struct mp3_file_port));\n    PJ_ASSERT_RETURN(fport != NULL, PJ_ENOMEM);\n\n    /* Initialize port info. */\n    pj_strdup2_with_null(pool, &fport->mp3_filename, filename);\n    pjmedia_port_info_init(&fport->base.info, &fport->mp3_filename, SIGNATURE,\n\t\t\t   sampling_rate, channel_count, bits_per_sample,\n\t\t\t   samples_per_frame);\n\n    fport->base.get_frame = &file_get_frame;\n    fport->base.put_frame = &file_put_frame;\n    fport->base.on_destroy = &file_on_destroy;\n\n\n    /* Open file in write and read mode.\n     * We need the read mode because we'll modify the WAVE header once\n     * the recording has completed.\n     */\n    status = pj_file_open(pool, filename, PJ_O_WRONLY, &fport->fd);\n    if (status != PJ_SUCCESS) {\n\tdeinit_blade_dll();\n\treturn status;\n    }\n\n    /* Copy and initialize option with default settings */\n    if (param_option) {\n\tpj_memcpy(&fport->mp3_option, param_option, \n\t\t   sizeof(pjmedia_mp3_encoder_option));\n    } else {\n\tpj_bzero(&fport->mp3_option, sizeof(pjmedia_mp3_encoder_option));\n\tfport->mp3_option.vbr = PJ_TRUE;\n    }\n\n    /* Calculate bitrate if it's not specified, only if it's not VBR. */\n    if (fport->mp3_option.bit_rate == 0 && !fport->mp3_option.vbr) \n\tfport->mp3_option.bit_rate = sampling_rate * channel_count;\n\n    /* Set default quality if it's not specified */\n    if (fport->mp3_option.quality == 0) \n\tfport->mp3_option.quality = 2;\n\n    /* Init mp3 encoder */\n    status = init_mp3_encoder(fport, pool);\n    if (status != PJ_SUCCESS) {\n\tpj_file_close(fport->fd);\n\tdeinit_blade_dll();\n\treturn status;\n    }\n\n    /* Done. */\n    *p_port = &fport->base;\n\n    PJ_LOG(4,(THIS_FILE, \n\t      \"MP3 file writer '%.*s' created: samp.rate=%dKHz, \"\n\t      \"bitrate=%dkbps%s, quality=%d\",\n\t      (int)fport->base.info.name.slen,\n\t      fport->base.info.name.ptr,\n\t\t  PJMEDIA_PIA_SRATE(&fport->base.info),\n\t      fport->mp3_option.bit_rate/1000,\n\t      (fport->mp3_option.vbr ? \" (VBR)\" : \"\"),\n\t      fport->mp3_option.quality));\n\n    return PJ_SUCCESS;\n}\n\n\n\n/*\n * Register callback.\n */\nPJ_DEF(pj_status_t) \npjmedia_mp3_writer_port_set_cb( pjmedia_port *port,\n\t\t\t\tpj_size_t pos,\n\t\t\t\tvoid *user_data,\n\t\t\t        pj_status_t (*cb)(pjmedia_port *port,\n\t\t\t\t\t\t  void *usr_data))\n{\n    struct mp3_file_port *fport;\n\n    /* Sanity check */\n    PJ_ASSERT_RETURN(port && cb, PJ_EINVAL);\n\n    /* Check that this is really a writer port */\n    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVALIDOP);\n\n    fport = (struct mp3_file_port*) port;\n\n    fport->cb_size = pos;\n    fport->base.port_data.pdata = user_data;\n    fport->cb = cb;\n\n    return PJ_SUCCESS;\n\n}\n\n\n/*\n * Put a frame into the buffer. When the buffer is full, flush the buffer\n * to the file.\n */\nstatic pj_status_t file_put_frame(pjmedia_port *this_port, \n\t\t\t\t  const pjmedia_frame *frame)\n{\n    struct mp3_file_port *fport = (struct mp3_file_port *)this_port;\n    unsigned long MP3Err;\n    pj_ssize_t\tbytes;\n    pj_status_t status;\n    unsigned long WriteSize;\n\n    /* Record silence if input is no-frame */\n    if (frame->type == PJMEDIA_FRAME_TYPE_NONE || frame->size == 0) {\n\tunsigned samples_left = PJMEDIA_PIA_SPF(&fport->base.info);\n\tunsigned samples_copied = 0;\n\n\t/* Only want to record at most 1 second of silence */\n\tif (fport->silence_duration >= PJMEDIA_PIA_SRATE(&fport->base.info))\n\t    return PJ_SUCCESS;\n\n\twhile (samples_left) {\n\t    unsigned samples_needed = fport->mp3_samples_per_frame -\n\t\t\t\t      fport->mp3_sample_pos;\n\t    if (samples_needed > samples_left)\n\t\tsamples_needed = samples_left;\n\n\t    pjmedia_zero_samples(fport->mp3_sample_buf + fport->mp3_sample_pos,\n\t\t\t\t samples_needed);\n\t    fport->mp3_sample_pos += samples_needed;\n\t    samples_left -= samples_needed;\n\t    samples_copied += samples_needed;\n\n\t    /* Encode if we have full frame */\n\t    if (fport->mp3_sample_pos == fport->mp3_samples_per_frame) {\n\t\t\n\t\t/* Clear position */\n\t\tfport->mp3_sample_pos = 0;\n\n\t\t/* Encode ! */\n\t\tMP3Err = BladeDLL.beEncodeChunk(fport->mp3_stream,\n\t\t\t\t\t\tfport->mp3_samples_per_frame,\n\t\t\t\t\t\tfport->mp3_sample_buf, \n\t\t\t\t\t\tfport->mp3_buf, \n\t\t\t\t\t\t&WriteSize);\n\t\tif (MP3Err != BE_ERR_SUCCESSFUL)\n\t\t    return PJMEDIA_ERROR;\n\n\t\t/* Write the chunk */\n\t\tbytes = WriteSize;\n\t\tstatus = pj_file_write(fport->fd, fport->mp3_buf, &bytes);\n\t\tif (status != PJ_SUCCESS)\n\t\t    return status;\n\n\t\t/* Increment total written. */\n\t\tfport->total += bytes;\n\t    }\n\t}\n\n\tfport->silence_duration += PJMEDIA_PIA_SPF(&fport->base.info);\n\n    }\n    /* If encoder is expecting different sample size, then we need to\n     * buffer the samples.\n     */\n    else if (fport->mp3_samples_per_frame != \n\t     PJMEDIA_PIA_SPF(&fport->base.info)) \n    {\n\tunsigned samples_left = frame->size / 2;\n\tunsigned samples_copied = 0;\n\tconst pj_int16_t *src_samples = frame->buf;\n\n\tfport->silence_duration = 0;\n\n\twhile (samples_left) {\n\t    unsigned samples_needed = fport->mp3_samples_per_frame -\n\t\t\t\t      fport->mp3_sample_pos;\n\t    if (samples_needed > samples_left)\n\t\tsamples_needed = samples_left;\n\n\t    pjmedia_copy_samples(fport->mp3_sample_buf + fport->mp3_sample_pos,\n\t\t\t\t src_samples + samples_copied,\n\t\t\t\t samples_needed);\n\t    fport->mp3_sample_pos += samples_needed;\n\t    samples_left -= samples_needed;\n\t    samples_copied += samples_needed;\n\n\t    /* Encode if we have full frame */\n\t    if (fport->mp3_sample_pos == fport->mp3_samples_per_frame) {\n\t\t\n\t\t/* Clear position */\n\t\tfport->mp3_sample_pos = 0;\n\n\t\t/* Encode ! */\n\t\tMP3Err = BladeDLL.beEncodeChunk(fport->mp3_stream,\n\t\t\t\t\t\tfport->mp3_samples_per_frame,\n\t\t\t\t\t\tfport->mp3_sample_buf, \n\t\t\t\t\t\tfport->mp3_buf, \n\t\t\t\t\t\t&WriteSize);\n\t\tif (MP3Err != BE_ERR_SUCCESSFUL)\n\t\t    return PJMEDIA_ERROR;\n\n\t\t/* Write the chunk */\n\t\tbytes = WriteSize;\n\t\tstatus = pj_file_write(fport->fd, fport->mp3_buf, &bytes);\n\t\tif (status != PJ_SUCCESS)\n\t\t    return status;\n\n\t\t/* Increment total written. */\n\t\tfport->total += bytes;\n\t    }\n\t}\n\n    } else {\n\n\tfport->silence_duration = 0;\n\n\t/* Encode ! */\n\tMP3Err = BladeDLL.beEncodeChunk(fport->mp3_stream,\n\t\t\t\t\tfport->mp3_samples_per_frame,\n\t\t\t\t\tframe->buf, \n\t\t\t\t\tfport->mp3_buf, \n\t\t\t\t\t&WriteSize);\n\tif (MP3Err != BE_ERR_SUCCESSFUL)\n\t    return PJMEDIA_ERROR;\n\n\t/* Write the chunk */\n\tbytes = WriteSize;\n\tstatus = pj_file_write(fport->fd, fport->mp3_buf, &bytes);\n\tif (status != PJ_SUCCESS)\n\t    return status;\n\n\t/* Increment total written. */\n\tfport->total += bytes;\n    }\n\n    /* Increment total written, and check if we need to call callback */\n    \n    if (fport->cb && fport->total >= fport->cb_size) {\n\tpj_status_t (*cb)(pjmedia_port*, void*);\n\tpj_status_t status;\n\n\tcb = fport->cb;\n\tfport->cb = NULL;\n\n\tstatus = (*cb)(this_port, this_port->port_data.pdata);\n\treturn status;\n    }\n\n    return PJ_SUCCESS;\n}\n\n/*\n * Get frame, basicy is a no-op operation.\n */\nstatic pj_status_t file_get_frame(pjmedia_port *this_port, \n\t\t\t\t  pjmedia_frame *frame)\n{\n    PJ_UNUSED_ARG(this_port);\n    PJ_UNUSED_ARG(frame);\n    return PJ_EINVALIDOP;\n}\n\n\n/*\n * Close the port, modify file header with updated file length.\n */\nstatic pj_status_t file_on_destroy(pjmedia_port *this_port)\n{\n    struct mp3_file_port *fport = (struct mp3_file_port*)this_port;\n    pj_status_t status;\n    unsigned long WriteSize;\n    unsigned long MP3Err;\n\n\n    /* Close encoder */\n    MP3Err = BladeDLL.beDeinitStream(fport->mp3_stream, fport->mp3_buf, \n\t\t\t\t     &WriteSize);\n    if (MP3Err == BE_ERR_SUCCESSFUL) {\n\tpj_ssize_t bytes = WriteSize;\n\tstatus = pj_file_write(fport->fd, fport->mp3_buf, &bytes);\n    }\n\n    /* Close file */\n    status = pj_file_close(fport->fd);\n\n    /* Write additional VBR header */\n    if (fport->mp3_option.vbr) {\n\tMP3Err = BladeDLL.beWriteVBRHeader(fport->mp3_filename.ptr);\n    }\n\n\n    /* Decrement DLL reference counter */\n    deinit_blade_dll();\n\n    /* Done. */\n    return PJ_SUCCESS;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/.gitignore",
    "content": "Makefile\nMakefile.in\naclocal.m4\nautom4te.cache\n*.kdevelop.pcs\n*.kdevses\ncompile\nconfig.guess\nconfig.h\nconfig.h.in\nconfig.log\nconfig.status\nconfig.sub\nconfigure\ndepcomp\ninstall-sh\n.deps\n.libs\n*.la\ntestcelt\nlibtool\nltmain.sh\nmissing\nstamp-h1\n*.sw\n*.o\n*.lo\n*~\ntests/*test\ntools/celtdec\ntools/celtenc\ncelt.pc\ncelt.spec\ncelt/dump_modes/dump_modes\n*.vcxproj.user\nopus.sdf\nopus.suo\nversion.h\ncelt/Debug\ncelt/Release\ncelt/x64\nsilk/Debug\nsilk/Release\nsilk/x64\nsilk/fixed/Debug\nsilk/fixed/Release\nsilk/fixed/x64\nsilk/float/Debug\nsilk/float/Release\nsilk/float/x64\nsrc/Debug\nsrc/Release\nsrc/x64\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/AUTHORS",
    "content": "Jean-Marc Valin (jmvalin@jmvalin.ca)\nKoen Vos (koenvos74@gmail.com)\nTimothy Terriberry (tterribe@xiph.org)\nKarsten Vandborg Sorensen (karsten.vandborg.sorensen@skype.net)\nSoren Skak Jensen (ssjensen@gn.com)\nGregory Maxwell (greg@xiph.org)\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/COPYING",
    "content": "Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic,\n                    Jean-Marc Valin, Timothy B. Terriberry,\n                    CSIRO, Gregory Maxwell, Mark Borgerding,\n                    Erik de Castro Lopo\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n- Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\nOR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nOpus is subject to the royalty-free patent licenses which are\nspecified at:\n\nXiph.Org Foundation:\nhttps://datatracker.ietf.org/ipr/1524/\n\nMicrosoft Corporation:\nhttps://datatracker.ietf.org/ipr/1914/\n\nBroadcom Corporation:\nhttps://datatracker.ietf.org/ipr/1526/\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/ChangeLog",
    "content": ""
  },
  {
    "path": "deps/pjsip/third_party/opus/INSTALL",
    "content": "Installation Instructions\n*************************\n\nCopyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,\nInc.\n\n   Copying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.  This file is offered as-is,\nwithout warranty of any kind.\n\nBasic Installation\n==================\n\n   Briefly, the shell command `./configure && make && make install'\nshould configure, build, and install this package.  The following\nmore-detailed instructions are generic; see the `README' file for\ninstructions specific to this package.  Some packages provide this\n`INSTALL' file but do not implement all of the features documented\nbelow.  The lack of an optional feature in a given package is not\nnecessarily a bug.  More recommendations for GNU packages can be found\nin *note Makefile Conventions: (standards)Makefile Conventions.\n\n   The `configure' shell script attempts to guess correct values for\nvarious system-dependent variables used during compilation.  It uses\nthose values to create a `Makefile' in each directory of the package.\nIt may also create one or more `.h' files containing system-dependent\ndefinitions.  Finally, it creates a shell script `config.status' that\nyou can run in the future to recreate the current configuration, and a\nfile `config.log' containing compiler output (useful mainly for\ndebugging `configure').\n\n   It can also use an optional file (typically called `config.cache'\nand enabled with `--cache-file=config.cache' or simply `-C') that saves\nthe results of its tests to speed up reconfiguring.  Caching is\ndisabled by default to prevent problems with accidental use of stale\ncache files.\n\n   If you need to do unusual things to compile the package, please try\nto figure out how `configure' could check whether to do them, and mail\ndiffs or instructions to the address given in the `README' so they can\nbe considered for the next release.  If you are using the cache, and at\nsome point `config.cache' contains results you don't want to keep, you\nmay remove or edit it.\n\n   The file `configure.ac' (or `configure.in') is used to create\n`configure' by a program called `autoconf'.  You need `configure.ac' if\nyou want to change it or regenerate `configure' using a newer version\nof `autoconf'.\n\n   The simplest way to compile this package is:\n\n  1. `cd' to the directory containing the package's source code and type\n     `./configure' to configure the package for your system.\n\n     Running `configure' might take a while.  While running, it prints\n     some messages telling which features it is checking for.\n\n  2. Type `make' to compile the package.\n\n  3. Optionally, type `make check' to run any self-tests that come with\n     the package, generally using the just-built uninstalled binaries.\n\n  4. Type `make install' to install the programs and any data files and\n     documentation.  When installing into a prefix owned by root, it is\n     recommended that the package be configured and built as a regular\n     user, and only the `make install' phase executed with root\n     privileges.\n\n  5. Optionally, type `make installcheck' to repeat any self-tests, but\n     this time using the binaries in their final installed location.\n     This target does not install anything.  Running this target as a\n     regular user, particularly if the prior `make install' required\n     root privileges, verifies that the installation completed\n     correctly.\n\n  6. You can remove the program binaries and object files from the\n     source code directory by typing `make clean'.  To also remove the\n     files that `configure' created (so you can compile the package for\n     a different kind of computer), type `make distclean'.  There is\n     also a `make maintainer-clean' target, but that is intended mainly\n     for the package's developers.  If you use it, you may have to get\n     all sorts of other programs in order to regenerate files that came\n     with the distribution.\n\n  7. Often, you can also type `make uninstall' to remove the installed\n     files again.  In practice, not all packages have tested that\n     uninstallation works correctly, even though it is required by the\n     GNU Coding Standards.\n\n  8. Some packages, particularly those that use Automake, provide `make\n     distcheck', which can by used by developers to test that all other\n     targets like `make install' and `make uninstall' work correctly.\n     This target is generally not run by end users.\n\nCompilers and Options\n=====================\n\n   Some systems require unusual options for compilation or linking that\nthe `configure' script does not know about.  Run `./configure --help'\nfor details on some of the pertinent environment variables.\n\n   You can give `configure' initial values for configuration parameters\nby setting variables in the command line or in the environment.  Here\nis an example:\n\n     ./configure CC=c99 CFLAGS=-g LIBS=-lposix\n\n   *Note Defining Variables::, for more details.\n\nCompiling For Multiple Architectures\n====================================\n\n   You can compile the package for more than one kind of computer at the\nsame time, by placing the object files for each architecture in their\nown directory.  To do this, you can use GNU `make'.  `cd' to the\ndirectory where you want the object files and executables to go and run\nthe `configure' script.  `configure' automatically checks for the\nsource code in the directory that `configure' is in and in `..'.  This\nis known as a \"VPATH\" build.\n\n   With a non-GNU `make', it is safer to compile the package for one\narchitecture at a time in the source code directory.  After you have\ninstalled the package for one architecture, use `make distclean' before\nreconfiguring for another architecture.\n\n   On MacOS X 10.5 and later systems, you can create libraries and\nexecutables that work on multiple system types--known as \"fat\" or\n\"universal\" binaries--by specifying multiple `-arch' options to the\ncompiler but only a single `-arch' option to the preprocessor.  Like\nthis:\n\n     ./configure CC=\"gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64\" \\\n                 CXX=\"g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64\" \\\n                 CPP=\"gcc -E\" CXXCPP=\"g++ -E\"\n\n   This is not guaranteed to produce working output in all cases, you\nmay have to build one architecture at a time and combine the results\nusing the `lipo' tool if you have problems.\n\nInstallation Names\n==================\n\n   By default, `make install' installs the package's commands under\n`/usr/local/bin', include files under `/usr/local/include', etc.  You\ncan specify an installation prefix other than `/usr/local' by giving\n`configure' the option `--prefix=PREFIX', where PREFIX must be an\nabsolute file name.\n\n   You can specify separate installation prefixes for\narchitecture-specific files and architecture-independent files.  If you\npass the option `--exec-prefix=PREFIX' to `configure', the package uses\nPREFIX as the prefix for installing programs and libraries.\nDocumentation and other data files still use the regular prefix.\n\n   In addition, if you use an unusual directory layout you can give\noptions like `--bindir=DIR' to specify different values for particular\nkinds of files.  Run `configure --help' for a list of the directories\nyou can set and what kinds of files go in them.  In general, the\ndefault for these options is expressed in terms of `${prefix}', so that\nspecifying just `--prefix' will affect all of the other directory\nspecifications that were not explicitly provided.\n\n   The most portable way to affect installation locations is to pass the\ncorrect locations to `configure'; however, many packages provide one or\nboth of the following shortcuts of passing variable assignments to the\n`make install' command line to change installation locations without\nhaving to reconfigure or recompile.\n\n   The first method involves providing an override variable for each\naffected directory.  For example, `make install\nprefix=/alternate/directory' will choose an alternate location for all\ndirectory configuration variables that were expressed in terms of\n`${prefix}'.  Any directories that were specified during `configure',\nbut not in terms of `${prefix}', must each be overridden at install\ntime for the entire installation to be relocated.  The approach of\nmakefile variable overrides for each directory variable is required by\nthe GNU Coding Standards, and ideally causes no recompilation.\nHowever, some platforms have known limitations with the semantics of\nshared libraries that end up requiring recompilation when using this\nmethod, particularly noticeable in packages that use GNU Libtool.\n\n   The second method involves providing the `DESTDIR' variable.  For\nexample, `make install DESTDIR=/alternate/directory' will prepend\n`/alternate/directory' before all installation names.  The approach of\n`DESTDIR' overrides is not required by the GNU Coding Standards, and\ndoes not work on platforms that have drive letters.  On the other hand,\nit does better at avoiding recompilation issues, and works well even\nwhen some directory options were not specified in terms of `${prefix}'\nat `configure' time.\n\nOptional Features\n=================\n\n   If the package supports it, you can cause programs to be installed\nwith an extra prefix or suffix on their names by giving `configure' the\noption `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.\n\n   Some packages pay attention to `--enable-FEATURE' options to\n`configure', where FEATURE indicates an optional part of the package.\nThey may also pay attention to `--with-PACKAGE' options, where PACKAGE\nis something like `gnu-as' or `x' (for the X Window System).  The\n`README' should mention any `--enable-' and `--with-' options that the\npackage recognizes.\n\n   For packages that use the X Window System, `configure' can usually\nfind the X include and library files automatically, but if it doesn't,\nyou can use the `configure' options `--x-includes=DIR' and\n`--x-libraries=DIR' to specify their locations.\n\n   Some packages offer the ability to configure how verbose the\nexecution of `make' will be.  For these packages, running `./configure\n--enable-silent-rules' sets the default to minimal output, which can be\noverridden with `make V=1'; while running `./configure\n--disable-silent-rules' sets the default to verbose, which can be\noverridden with `make V=0'.\n\nParticular systems\n==================\n\n   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU\nCC is not installed, it is recommended to use the following options in\norder to use an ANSI C compiler:\n\n     ./configure CC=\"cc -Ae -D_XOPEN_SOURCE=500\"\n\nand if that doesn't work, install pre-built binaries of GCC for HP-UX.\n\n   HP-UX `make' updates targets which have the same time stamps as\ntheir prerequisites, which makes it generally unusable when shipped\ngenerated files such as `configure' are involved.  Use GNU `make'\ninstead.\n\n   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot\nparse its `<wchar.h>' header file.  The option `-nodtk' can be used as\na workaround.  If GNU CC is not installed, it is therefore recommended\nto try\n\n     ./configure CC=\"cc\"\n\nand if that doesn't work, try\n\n     ./configure CC=\"cc -nodtk\"\n\n   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This\ndirectory contains several dysfunctional programs; working variants of\nthese programs are available in `/usr/bin'.  So, if you need `/usr/ucb'\nin your `PATH', put it _after_ `/usr/bin'.\n\n   On Haiku, software installed for all users goes in `/boot/common',\nnot `/usr/local'.  It is recommended to use the following options:\n\n     ./configure --prefix=/boot/common\n\nSpecifying the System Type\n==========================\n\n   There may be some features `configure' cannot figure out\nautomatically, but needs to determine by the type of machine the package\nwill run on.  Usually, assuming the package is built to be run on the\n_same_ architectures, `configure' can figure that out, but if it prints\na message saying it cannot guess the machine type, give it the\n`--build=TYPE' option.  TYPE can either be a short name for the system\ntype, such as `sun4', or a canonical name which has the form:\n\n     CPU-COMPANY-SYSTEM\n\nwhere SYSTEM can have one of these forms:\n\n     OS\n     KERNEL-OS\n\n   See the file `config.sub' for the possible values of each field.  If\n`config.sub' isn't included in this package, then this package doesn't\nneed to know the machine type.\n\n   If you are _building_ compiler tools for cross-compiling, you should\nuse the option `--target=TYPE' to select the type of system they will\nproduce code for.\n\n   If you want to _use_ a cross compiler, that generates code for a\nplatform different from the build platform, you should specify the\n\"host\" platform (i.e., that on which the generated programs will\neventually be run) with `--host=TYPE'.\n\nSharing Defaults\n================\n\n   If you want to set default values for `configure' scripts to share,\nyou can create a site shell script called `config.site' that gives\ndefault values for variables like `CC', `cache_file', and `prefix'.\n`configure' looks for `PREFIX/share/config.site' if it exists, then\n`PREFIX/etc/config.site' if it exists.  Or, you can set the\n`CONFIG_SITE' environment variable to the location of the site script.\nA warning: not all `configure' scripts look for a site script.\n\nDefining Variables\n==================\n\n   Variables not defined in a site shell script can be set in the\nenvironment passed to `configure'.  However, some packages may run\nconfigure again during the build, and the customized values of these\nvariables may be lost.  In order to avoid this problem, you should set\nthem in the `configure' command line, using `VAR=value'.  For example:\n\n     ./configure CC=/usr/local2/bin/gcc\n\ncauses the specified `gcc' to be used as the C compiler (unless it is\noverridden in the site shell script).\n\nUnfortunately, this technique does not work for `CONFIG_SHELL' due to\nan Autoconf limitation.  Until the limitation is lifted, you can use\nthis workaround:\n\n     CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash\n\n`configure' Invocation\n======================\n\n   `configure' recognizes the following options to control how it\noperates.\n\n`--help'\n`-h'\n     Print a summary of all of the options to `configure', and exit.\n\n`--help=short'\n`--help=recursive'\n     Print a summary of the options unique to this package's\n     `configure', and exit.  The `short' variant lists options used\n     only in the top level, while the `recursive' variant lists options\n     also present in any nested packages.\n\n`--version'\n`-V'\n     Print the version of Autoconf used to generate the `configure'\n     script, and exit.\n\n`--cache-file=FILE'\n     Enable the cache: use and save the results of the tests in FILE,\n     traditionally `config.cache'.  FILE defaults to `/dev/null' to\n     disable caching.\n\n`--config-cache'\n`-C'\n     Alias for `--cache-file=config.cache'.\n\n`--quiet'\n`--silent'\n`-q'\n     Do not print messages saying which checks are being made.  To\n     suppress all normal output, redirect it to `/dev/null' (any error\n     messages will still be shown).\n\n`--srcdir=DIR'\n     Look for the package's source code in directory DIR.  Usually\n     `configure' can determine that directory automatically.\n\n`--prefix=DIR'\n     Use DIR as the installation prefix.  *note Installation Names::\n     for more details, including other options available for fine-tuning\n     the installation locations.\n\n`--no-create'\n`-n'\n     Run the configure checks, but stop before creating any output\n     files.\n\n`configure' also accepts some other, not widely useful, options.  Run\n`configure --help' for more details.\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/Makefile.am",
    "content": "# Provide the full test output for failed tests when using the parallel\n# test suite (which is enabled by default with automake 1.13+).\nexport VERBOSE = yes\n\nAUTOMAKE_OPTIONS = subdir-objects\nACLOCAL_AMFLAGS = -I m4\n\nlib_LTLIBRARIES = libopus.la\n\nDIST_SUBDIRS = doc\n\nAM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/celt -I$(top_srcdir)/silk \\\n              -I$(top_srcdir)/silk/float -I$(top_srcdir)/silk/fixed $(NE10_CFLAGS)\n\ninclude celt_sources.mk\ninclude silk_sources.mk\ninclude opus_sources.mk\n\nif FIXED_POINT\nSILK_SOURCES += $(SILK_SOURCES_FIXED)\nif HAVE_SSE4_1\nSILK_SOURCES += $(SILK_SOURCES_SSE4_1) $(SILK_SOURCES_FIXED_SSE4_1)\nendif\nelse\nSILK_SOURCES += $(SILK_SOURCES_FLOAT)\nif HAVE_SSE4_1\nSILK_SOURCES += $(SILK_SOURCES_SSE4_1)\nendif\nendif\n\nif DISABLE_FLOAT_API\nelse\nOPUS_SOURCES += $(OPUS_SOURCES_FLOAT)\nendif\n\nif HAVE_SSE\nCELT_SOURCES += $(CELT_SOURCES_SSE)\nendif\nif HAVE_SSE2\nCELT_SOURCES += $(CELT_SOURCES_SSE2)\nendif\nif HAVE_SSE4_1\nCELT_SOURCES += $(CELT_SOURCES_SSE4_1)\nendif\n\nif CPU_ARM\nCELT_SOURCES += $(CELT_SOURCES_ARM)\nSILK_SOURCES += $(SILK_SOURCES_ARM)\n\nif OPUS_ARM_NEON_INTR\nCELT_SOURCES += $(CELT_SOURCES_ARM_NEON_INTR)\nendif\n\nif HAVE_ARM_NE10\nCELT_SOURCES += $(CELT_SOURCES_ARM_NE10)\nendif\n\nif OPUS_ARM_EXTERNAL_ASM\nnoinst_LTLIBRARIES = libarmasm.la\nlibarmasm_la_SOURCES = $(CELT_SOURCES_ARM_ASM:.s=-gnu.S)\nBUILT_SOURCES = $(CELT_SOURCES_ARM_ASM:.s=-gnu.S) \\\n $(CELT_AM_SOURCES_ARM_ASM:.s.in=.s) \\\n $(CELT_AM_SOURCES_ARM_ASM:.s.in=-gnu.S)\nendif\nendif\n\nCLEANFILES = $(CELT_SOURCES_ARM_ASM:.s=-gnu.S) \\\n $(CELT_AM_SOURCES_ARM_ASM:.s.in=-gnu.S)\n\ninclude celt_headers.mk\ninclude silk_headers.mk\ninclude opus_headers.mk\n\nlibopus_la_SOURCES = $(CELT_SOURCES) $(SILK_SOURCES) $(OPUS_SOURCES)\nlibopus_la_LDFLAGS = -no-undefined -version-info @OPUS_LT_CURRENT@:@OPUS_LT_REVISION@:@OPUS_LT_AGE@\nlibopus_la_LIBADD = $(NE10_LIBS) $(LIBM)\nif OPUS_ARM_EXTERNAL_ASM\nlibopus_la_LIBADD += libarmasm.la\nendif\n\npkginclude_HEADERS = include/opus.h include/opus_multistream.h include/opus_types.h include/opus_defines.h\n\nnoinst_HEADERS = $(OPUS_HEAD) $(SILK_HEAD) $(CELT_HEAD)\n\nif EXTRA_PROGRAMS\nnoinst_PROGRAMS = opus_demo repacketizer_demo opus_compare tests/test_opus_api tests/test_opus_encode tests/test_opus_decode tests/test_opus_padding celt/tests/test_unit_cwrs32 celt/tests/test_unit_dft celt/tests/test_unit_entropy celt/tests/test_unit_laplace celt/tests/test_unit_mathops celt/tests/test_unit_mdct celt/tests/test_unit_rotation celt/tests/test_unit_types\n\nTESTS = celt/tests/test_unit_types celt/tests/test_unit_mathops celt/tests/test_unit_entropy celt/tests/test_unit_laplace celt/tests/test_unit_dft celt/tests/test_unit_mdct celt/tests/test_unit_rotation celt/tests/test_unit_cwrs32 tests/test_opus_api tests/test_opus_decode tests/test_opus_encode tests/test_opus_padding\n\nopus_demo_SOURCES = src/opus_demo.c\n\nopus_demo_LDADD = libopus.la $(NE10_LIBS) $(LIBM)\n\nrepacketizer_demo_SOURCES = src/repacketizer_demo.c\n\nrepacketizer_demo_LDADD = libopus.la $(NE10_LIBS) $(LIBM)\n\nopus_compare_SOURCES = src/opus_compare.c\nopus_compare_LDADD = $(LIBM)\n\ntests_test_opus_api_SOURCES = tests/test_opus_api.c tests/test_opus_common.h\ntests_test_opus_api_LDADD = libopus.la $(NE10_LIBS) $(LIBM)\n\ntests_test_opus_encode_SOURCES = tests/test_opus_encode.c tests/test_opus_common.h\ntests_test_opus_encode_LDADD = libopus.la $(NE10_LIBS) $(LIBM)\n\ntests_test_opus_decode_SOURCES = tests/test_opus_decode.c tests/test_opus_common.h\ntests_test_opus_decode_LDADD = libopus.la $(NE10_LIBS) $(LIBM)\n\ntests_test_opus_padding_SOURCES = tests/test_opus_padding.c tests/test_opus_common.h\ntests_test_opus_padding_LDADD = libopus.la $(NE10_LIBS) $(LIBM)\n\ncelt_tests_test_unit_cwrs32_SOURCES = celt/tests/test_unit_cwrs32.c\ncelt_tests_test_unit_cwrs32_LDADD = $(LIBM)\n\ncelt_tests_test_unit_dft_SOURCES = celt/tests/test_unit_dft.c\ncelt_tests_test_unit_dft_LDADD = $(NE10_LIBS) $(LIBM)\nif OPUS_ARM_EXTERNAL_ASM\ncelt_tests_test_unit_dft_LDADD += libarmasm.la\nendif\n\ncelt_tests_test_unit_entropy_SOURCES = celt/tests/test_unit_entropy.c\ncelt_tests_test_unit_entropy_LDADD = $(LIBM)\n\ncelt_tests_test_unit_laplace_SOURCES = celt/tests/test_unit_laplace.c\ncelt_tests_test_unit_laplace_LDADD = $(LIBM)\n\ncelt_tests_test_unit_mathops_SOURCES = celt/tests/test_unit_mathops.c\ncelt_tests_test_unit_mathops_LDADD = $(NE10_LIBS) $(LIBM)\nif OPUS_ARM_EXTERNAL_ASM\ncelt_tests_test_unit_mathops_LDADD += libarmasm.la\nendif\n\ncelt_tests_test_unit_mdct_SOURCES = celt/tests/test_unit_mdct.c\ncelt_tests_test_unit_mdct_LDADD = $(NE10_LIBS) $(LIBM)\nif OPUS_ARM_EXTERNAL_ASM\ncelt_tests_test_unit_mdct_LDADD += libarmasm.la\nendif\n\ncelt_tests_test_unit_rotation_SOURCES = celt/tests/test_unit_rotation.c\ncelt_tests_test_unit_rotation_LDADD = $(NE10_LIBS) $(LIBM)\nif OPUS_ARM_EXTERNAL_ASM\ncelt_tests_test_unit_rotation_LDADD += libarmasm.la\nendif\n\ncelt_tests_test_unit_types_SOURCES = celt/tests/test_unit_types.c\ncelt_tests_test_unit_types_LDADD = $(LIBM)\nendif\n\nif CUSTOM_MODES\npkginclude_HEADERS += include/opus_custom.h\nif EXTRA_PROGRAMS\nnoinst_PROGRAMS += opus_custom_demo\nopus_custom_demo_SOURCES = celt/opus_custom_demo.c\nopus_custom_demo_LDADD = libopus.la $(LIBM)\nendif\nendif\n\nEXTRA_DIST = version.mk \\\n             opus.pc.in \\\n             opus-uninstalled.pc.in \\\n             opus.m4 \\\n             Makefile.mips \\\n             Makefile.unix \\\n             tests/run_vectors.sh \\\n             celt/arm/arm2gnu.pl \\\n             celt/arm/celt_pitch_xcorr_arm.s \\\n             win32/VS2010/silk_float.vcxproj \\\n             win32/VS2010/celt.vcxproj.filters \\\n             win32/VS2010/opus.vcxproj \\\n             win32/VS2010/silk_common.vcxproj.filters \\\n             win32/VS2010/silk_float.vcxproj.filters \\\n             win32/VS2010/test_opus_encode.vcxproj.filters \\\n             win32/VS2010/silk_common.vcxproj \\\n             win32/VS2010/test_opus_encode.vcxproj \\\n             win32/VS2010/opus_demo.vcxproj \\\n             win32/VS2010/test_opus_api.vcxproj.filters \\\n             win32/VS2010/test_opus_api.vcxproj \\\n             win32/VS2010/test_opus_decode.vcxproj.filters \\\n             win32/VS2010/silk_fixed.vcxproj.filters \\\n             win32/VS2010/opus_demo.vcxproj.filters \\\n             win32/VS2010/silk_fixed.vcxproj \\\n             win32/VS2010/opus.vcxproj.filters \\\n             win32/VS2010/test_opus_decode.vcxproj \\\n             win32/VS2010/celt.vcxproj \\\n             win32/VS2010/opus.sln \\\n             win32/genversion.bat \\\n             win32/config.h\n\npkgconfigdir = $(libdir)/pkgconfig\npkgconfig_DATA = opus.pc\n\nm4datadir = $(datadir)/aclocal\nm4data_DATA = opus.m4\n\n# Targets to build and install just the library without the docs\nopus check-opus install-opus: export NO_DOXYGEN = 1\n\nopus: all\ncheck-opus: check\ninstall-opus: install\n\n\n# Or just the docs\ndocs:\n\t( cd doc && $(MAKE) $(AM_MAKEFLAGS) )\n\ninstall-docs:\n\t( cd doc && $(MAKE) $(AM_MAKEFLAGS) install )\n\n\n# Or everything (by default)\nall-local:\n\t@[ -n \"$(NO_DOXYGEN)\" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) )\n\ninstall-data-local:\n\t@[ -n \"$(NO_DOXYGEN)\" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) install )\n\nclean-local:\n\t-( cd doc && $(MAKE) $(AM_MAKEFLAGS) clean )\n\nuninstall-local:\n\t( cd doc && $(MAKE) $(AM_MAKEFLAGS) uninstall )\n\n\n# We check this every time make is run, with configure.ac being touched to\n# trigger an update of the build system files if update_version changes the\n# current PACKAGE_VERSION (or if package_version was modified manually by a\n# user with either AUTO_UPDATE=no or no update_version script present - the\n# latter being the normal case for tarball releases).\n#\n# We can't just add the package_version file to CONFIGURE_DEPENDENCIES since\n# simply running autoconf will not actually regenerate configure for us when\n# the content of that file changes (due to autoconf dependency checking not\n# knowing about that without us creating yet another file for it to include).\n#\n# The MAKECMDGOALS check is a gnu-make'ism, but will degrade 'gracefully' for\n# makes that don't support it.  The only loss of functionality is not forcing\n# an update of package_version for `make dist` if AUTO_UPDATE=no, but that is\n# unlikely to be a real problem for any real user.\n$(top_srcdir)/configure.ac: force\n\t@case \"$(MAKECMDGOALS)\" in \\\n\t    dist-hook)                             exit 0       ;; \\\n\t    dist-* | dist | distcheck | distclean) _arg=release ;; \\\n\tesac; \\\n\tif ! $(top_srcdir)/update_version $$_arg 2> /dev/null; then \\\n\t    if [ ! -e $(top_srcdir)/package_version ]; then \\\n\t\techo 'PACKAGE_VERSION=\"unknown\"' > $(top_srcdir)/package_version; \\\n\t    fi; \\\n\t    . $(top_srcdir)/package_version || exit 1; \\\n\t    [ \"$(PACKAGE_VERSION)\" != \"$$PACKAGE_VERSION\" ] || exit 0; \\\n\tfi; \\\n\ttouch $@\n\nforce:\n\n# Create a minimal package_version file when make dist is run.\ndist-hook:\n\techo 'PACKAGE_VERSION=\"$(PACKAGE_VERSION)\"' > $(top_distdir)/package_version\n\n\n.PHONY: opus check-opus install-opus docs install-docs\n\n# automake doesn't do dependency tracking for asm files, that I can tell\n$(CELT_SOURCES_ARM_ASM:%.s=%-gnu.S): celt/arm/armopts-gnu.S\n$(CELT_SOURCES_ARM_ASM:%.s=%-gnu.S): $(top_srcdir)/celt/arm/arm2gnu.pl\n\n# convert ARM asm to GNU as format\n%-gnu.S: $(top_srcdir)/%.s\n\t$(top_srcdir)/celt/arm/arm2gnu.pl @ARM2GNU_PARAMS@ < $< > $@\n# For autoconf-modified sources (e.g., armopts.s)\n%-gnu.S: %.s\n\t$(top_srcdir)/celt/arm/arm2gnu.pl @ARM2GNU_PARAMS@ < $< > $@\n\nOPT_UNIT_TEST_OBJ = $(celt_tests_test_unit_mathops_SOURCES:.c=.o) \\\n                    $(celt_tests_test_unit_rotation_SOURCES:.c=.o) \\\n                    $(celt_tests_test_unit_mdct_SOURCES:.c=.o) \\\n                    $(celt_tests_test_unit_dft_SOURCES:.c=.o)\n\nif HAVE_SSE\nSSE_OBJ = $(CELT_SOURCES_SSE:.c=.lo)\n$(SSE_OBJ) $(OPT_UNIT_TEST_OBJ): CFLAGS += $(OPUS_X86_SSE_CFLAGS)\nendif\n\nif HAVE_SSE2\nSSE2_OBJ = $(CELT_SOURCES_SSE2:.c=.lo)\n$(SSE2_OBJ) $(OPT_UNIT_TEST_OBJ): CFLAGS += $(OPUS_X86_SSE2_CFLAGS)\nendif\n\nif HAVE_SSE4_1\nSSE4_1_OBJ = $(CELT_SOURCES_SSE4_1:.c=.lo) \\\n             $(SILK_SOURCES_SSE4_1:.c=.lo) \\\n             $(SILK_SOURCES_FIXED_SSE4_1:.c=.lo)\n$(SSE4_1_OBJ) $(OPT_UNIT_TEST_OBJ): CFLAGS += $(OPUS_X86_SSE4_1_CFLAGS)\nendif\n\nif OPUS_ARM_NEON_INTR\nCELT_ARM_NEON_INTR_OBJ = $(CELT_SOURCES_ARM_NEON_INTR:.c=.lo)\n$(CELT_ARM_NEON_INTR_OBJ) $(OPT_UNIT_TEST_OBJ): CFLAGS += \\\n $(OPUS_ARM_NEON_INTR_CFLAGS)  $(NE10_CFLAGS)\nendif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/Makefile.mips",
    "content": "#################### COMPILE OPTIONS #######################\n\n# Uncomment this for fixed-point build\nFIXED_POINT=1\n\n# It is strongly recommended to uncomment one of these\n# VAR_ARRAYS: Use C99 variable-length arrays for stack allocation\n# USE_ALLOCA: Use alloca() for stack allocation\n# If none is defined, then the fallback is a non-threadsafe global array\nCFLAGS := -DUSE_ALLOCA $(CFLAGS)\n#CFLAGS := -DVAR_ARRAYS $(CFLAGS)\n\n# These options affect performance\n# HAVE_LRINTF: Use C99 intrinsics to speed up float-to-int conversion\n#CFLAGS := -DHAVE_LRINTF $(CFLAGS)\n\n###################### END OF OPTIONS ######################\n\n-include package_version\n\ninclude silk_sources.mk\ninclude celt_sources.mk\ninclude opus_sources.mk\n\nifdef FIXED_POINT\nSILK_SOURCES += $(SILK_SOURCES_FIXED)\nelse\nSILK_SOURCES += $(SILK_SOURCES_FLOAT)\nOPUS_SOURCES += $(OPUS_SOURCES_FLOAT)\nendif\n\nEXESUFFIX =\nLIBPREFIX = lib\nLIBSUFFIX = .a\nOBJSUFFIX = .o\n\nCC     = $(TOOLCHAIN_PREFIX)cc$(TOOLCHAIN_SUFFIX)\nAR     = $(TOOLCHAIN_PREFIX)ar\nRANLIB = $(TOOLCHAIN_PREFIX)ranlib\nCP     = $(TOOLCHAIN_PREFIX)cp\n\ncppflags-from-defines   = $(addprefix -D,$(1))\ncppflags-from-includes  = $(addprefix -I,$(1))\nldflags-from-ldlibdirs  = $(addprefix -L,$(1))\nldlibs-from-libs        = $(addprefix -l,$(1))\n\nWARNINGS = -Wall -W -Wstrict-prototypes -Wextra -Wcast-align -Wnested-externs -Wshadow\n\nCFLAGS  += -mips32r2 -mno-mips16 -std=gnu99 -O2 -g $(WARNINGS) -DENABLE_ASSERTIONS -DMIPSr1_ASM -DOPUS_BUILD -mdspr2 -march=74kc -mtune=74kc -mmt -mgp32\n\nCINCLUDES = include silk celt\n\nifdef FIXED_POINT\nCFLAGS += -DFIXED_POINT=1 -DDISABLE_FLOAT_API\nCINCLUDES += silk/fixed\nelse\nCINCLUDES += silk/float\nendif\n\n\nLIBS = m\n\nLDLIBDIRS = ./\n\nCFLAGS  += $(call cppflags-from-defines,$(CDEFINES))\nCFLAGS  += $(call cppflags-from-includes,$(CINCLUDES))\nLDFLAGS += $(call ldflags-from-ldlibdirs,$(LDLIBDIRS))\nLDLIBS  += $(call ldlibs-from-libs,$(LIBS))\n\nCOMPILE.c.cmdline   = $(CC) -c $(CFLAGS) -o $@ $<\nLINK.o              = $(CC) $(LDPREFLAGS) $(LDFLAGS)\nLINK.o.cmdline      = $(LINK.o) $^ $(LDLIBS) -o $@$(EXESUFFIX)\n\nARCHIVE.cmdline     = $(AR) $(ARFLAGS) $@ $^ && $(RANLIB) $@\n\n%$(OBJSUFFIX):%.c\n\t$(COMPILE.c.cmdline)\n\n%$(OBJSUFFIX):%.cpp\n\t$(COMPILE.cpp.cmdline)\n\n# Directives\n\n\n# Variable definitions\nLIB_NAME = opus\nTARGET = $(LIBPREFIX)$(LIB_NAME)$(LIBSUFFIX)\n\nSRCS_C = $(SILK_SOURCES) $(CELT_SOURCES) $(OPUS_SOURCES)\n\nOBJS := $(patsubst %.c,%$(OBJSUFFIX),$(SRCS_C))\n\nOPUSDEMO_SRCS_C = src/opus_demo.c\nOPUSDEMO_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(OPUSDEMO_SRCS_C))\n\nTESTOPUSAPI_SRCS_C = tests/test_opus_api.c\nTESTOPUSAPI_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSAPI_SRCS_C))\n\nTESTOPUSDECODE_SRCS_C = tests/test_opus_decode.c\nTESTOPUSDECODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSDECODE_SRCS_C))\n\nTESTOPUSENCODE_SRCS_C = tests/test_opus_encode.c\nTESTOPUSENCODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSENCODE_SRCS_C))\n\nTESTOPUSPADDING_SRCS_C = tests/test_opus_padding.c\nTESTOPUSPADDING_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSPADDING_SRCS_C))\n\nOPUSCOMPARE_SRCS_C = src/opus_compare.c\nOPUSCOMPARE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(OPUSCOMPARE_SRCS_C))\n\nTESTS := test_opus_api test_opus_decode test_opus_encode test_opus_padding\n\n# Rules\nall: lib opus_demo opus_compare $(TESTS)\n\nlib: $(TARGET)\n\ncheck: all\n\tfor test in $(TESTS); do ./$$test; done\n\n$(TARGET): $(OBJS)\n\t$(ARCHIVE.cmdline)\n\nopus_demo$(EXESUFFIX): $(OPUSDEMO_OBJS) $(TARGET)\n\t$(LINK.o.cmdline)\n\ntest_opus_api$(EXESUFFIX): $(TESTOPUSAPI_OBJS) $(TARGET)\n\t$(LINK.o.cmdline)\n\ntest_opus_decode$(EXESUFFIX): $(TESTOPUSDECODE_OBJS) $(TARGET)\n\t$(LINK.o.cmdline)\n\ntest_opus_encode$(EXESUFFIX): $(TESTOPUSENCODE_OBJS) $(TARGET)\n\t$(LINK.o.cmdline)\n\ntest_opus_padding$(EXESUFFIX): $(TESTOPUSPADDING_OBJS) $(TARGET)\n\t$(LINK.o.cmdline)\n\nopus_compare$(EXESUFFIX): $(OPUSCOMPARE_OBJS)\n\t$(LINK.o.cmdline)\n\ncelt/celt.o: CFLAGS += -DPACKAGE_VERSION='$(PACKAGE_VERSION)'\ncelt/celt.o: package_version\n\npackage_version: force\n\t@if [ -x ./update_version ]; then \\\n\t\t./update_version || true; \\\n\telif [ ! -e ./package_version ]; then \\\n\t\techo 'PACKAGE_VERSION=\"unknown\"' > ./package_version; \\\n\tfi\n\nforce:\n\nclean:\n\trm -f opus_demo$(EXESUFFIX) opus_compare$(EXESUFFIX) $(TARGET) \\\n                test_opus_api$(EXESUFFIX) test_opus_decode$(EXESUFFIX) \\\n                test_opus_encode$(EXESUFFIX) test_opus_padding$(EXESUFFIX) \\\n\t\t$(OBJS) $(OPUSDEMO_OBJS) $(OPUSCOMPARE_OBJS) $(TESTOPUSAPI_OBJS) \\\n                $(TESTOPUSDECODE_OBJS) $(TESTOPUSENCODE_OBJS) $(TESTOPUSPADDING_OBJS)\n\n.PHONY: all lib clean force check\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/Makefile.unix",
    "content": "#################### COMPILE OPTIONS #######################\n\n# Uncomment this for fixed-point build\n#FIXED_POINT=1\n\n# It is strongly recommended to uncomment one of these\n# VAR_ARRAYS: Use C99 variable-length arrays for stack allocation\n# USE_ALLOCA: Use alloca() for stack allocation\n# If none is defined, then the fallback is a non-threadsafe global array\nCFLAGS := -DUSE_ALLOCA $(CFLAGS)\n#CFLAGS := -DVAR_ARRAYS $(CFLAGS)\n\n# These options affect performance\n# HAVE_LRINTF: Use C99 intrinsics to speed up float-to-int conversion\n#CFLAGS := -DHAVE_LRINTF $(CFLAGS)\n\n###################### END OF OPTIONS ######################\n\n-include package_version\n\ninclude silk_sources.mk\ninclude celt_sources.mk\ninclude opus_sources.mk\n\nifdef FIXED_POINT\nSILK_SOURCES += $(SILK_SOURCES_FIXED)\nelse\nSILK_SOURCES += $(SILK_SOURCES_FLOAT)\nOPUS_SOURCES += $(OPUS_SOURCES_FLOAT)\nendif\n\nEXESUFFIX =\nLIBPREFIX = lib\nLIBSUFFIX = .a\nOBJSUFFIX = .o\n\nCC     = $(TOOLCHAIN_PREFIX)cc$(TOOLCHAIN_SUFFIX)\nAR     = $(TOOLCHAIN_PREFIX)ar\nRANLIB = $(TOOLCHAIN_PREFIX)ranlib\nCP     = $(TOOLCHAIN_PREFIX)cp\n\ncppflags-from-defines   = $(addprefix -D,$(1))\ncppflags-from-includes  = $(addprefix -I,$(1))\nldflags-from-ldlibdirs  = $(addprefix -L,$(1))\nldlibs-from-libs        = $(addprefix -l,$(1))\n\nWARNINGS = -Wall -W -Wstrict-prototypes -Wextra -Wcast-align -Wnested-externs -Wshadow\nCFLAGS  += -O2 -g $(WARNINGS) -DOPUS_BUILD\nCINCLUDES = include silk celt\n\nifdef FIXED_POINT\nCFLAGS += -DFIXED_POINT=1 -DDISABLE_FLOAT_API\nCINCLUDES += silk/fixed\nelse\nCINCLUDES += silk/float\nendif\n\n\nLIBS = m\n\nLDLIBDIRS = ./\n\nCFLAGS  += $(call cppflags-from-defines,$(CDEFINES))\nCFLAGS  += $(call cppflags-from-includes,$(CINCLUDES))\nLDFLAGS += $(call ldflags-from-ldlibdirs,$(LDLIBDIRS))\nLDLIBS  += $(call ldlibs-from-libs,$(LIBS))\n\nCOMPILE.c.cmdline   = $(CC) -c $(CFLAGS) -o $@ $<\nLINK.o              = $(CC) $(LDPREFLAGS) $(LDFLAGS)\nLINK.o.cmdline      = $(LINK.o) $^ $(LDLIBS) -o $@$(EXESUFFIX)\n\nARCHIVE.cmdline     = $(AR) $(ARFLAGS) $@ $^ && $(RANLIB) $@\n\n%$(OBJSUFFIX):%.c\n\t$(COMPILE.c.cmdline)\n\n%$(OBJSUFFIX):%.cpp\n\t$(COMPILE.cpp.cmdline)\n\n# Directives\n\n\n# Variable definitions\nLIB_NAME = opus\nTARGET = $(LIBPREFIX)$(LIB_NAME)$(LIBSUFFIX)\n\nSRCS_C = $(SILK_SOURCES) $(CELT_SOURCES) $(OPUS_SOURCES)\n\nOBJS := $(patsubst %.c,%$(OBJSUFFIX),$(SRCS_C))\n\nOPUSDEMO_SRCS_C = src/opus_demo.c\nOPUSDEMO_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(OPUSDEMO_SRCS_C))\n\nTESTOPUSAPI_SRCS_C = tests/test_opus_api.c\nTESTOPUSAPI_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSAPI_SRCS_C))\n\nTESTOPUSDECODE_SRCS_C = tests/test_opus_decode.c\nTESTOPUSDECODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSDECODE_SRCS_C))\n\nTESTOPUSENCODE_SRCS_C = tests/test_opus_encode.c\nTESTOPUSENCODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSENCODE_SRCS_C))\n\nTESTOPUSPADDING_SRCS_C = tests/test_opus_padding.c\nTESTOPUSPADDING_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSPADDING_SRCS_C))\n\nOPUSCOMPARE_SRCS_C = src/opus_compare.c\nOPUSCOMPARE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(OPUSCOMPARE_SRCS_C))\n\nTESTS := test_opus_api test_opus_decode test_opus_encode test_opus_padding\n\n# Rules\nall: lib opus_demo opus_compare $(TESTS)\n\nlib: $(TARGET)\n\ncheck: all\n\tfor test in $(TESTS); do ./$$test; done\n\n$(TARGET): $(OBJS)\n\t$(ARCHIVE.cmdline)\n\nopus_demo$(EXESUFFIX): $(OPUSDEMO_OBJS) $(TARGET)\n\t$(LINK.o.cmdline)\n\ntest_opus_api$(EXESUFFIX): $(TESTOPUSAPI_OBJS) $(TARGET)\n\t$(LINK.o.cmdline)\n\ntest_opus_decode$(EXESUFFIX): $(TESTOPUSDECODE_OBJS) $(TARGET)\n\t$(LINK.o.cmdline)\n\ntest_opus_encode$(EXESUFFIX): $(TESTOPUSENCODE_OBJS) $(TARGET)\n\t$(LINK.o.cmdline)\n\ntest_opus_padding$(EXESUFFIX): $(TESTOPUSPADDING_OBJS) $(TARGET)\n\t$(LINK.o.cmdline)\n\nopus_compare$(EXESUFFIX): $(OPUSCOMPARE_OBJS)\n\t$(LINK.o.cmdline)\n\ncelt/celt.o: CFLAGS += -DPACKAGE_VERSION='$(PACKAGE_VERSION)'\ncelt/celt.o: package_version\n\npackage_version: force\n\t@if [ -x ./update_version ]; then \\\n\t\t./update_version || true; \\\n\telif [ ! -e ./package_version ]; then \\\n\t\techo 'PACKAGE_VERSION=\"unknown\"' > ./package_version; \\\n\tfi\n\nforce:\n\nclean:\n\trm -f opus_demo$(EXESUFFIX) opus_compare$(EXESUFFIX) $(TARGET) \\\n                test_opus_api$(EXESUFFIX) test_opus_decode$(EXESUFFIX) \\\n                test_opus_encode$(EXESUFFIX) test_opus_padding$(EXESUFFIX) \\\n\t\t$(OBJS) $(OPUSDEMO_OBJS) $(OPUSCOMPARE_OBJS) $(TESTOPUSAPI_OBJS) \\\n                $(TESTOPUSDECODE_OBJS) $(TESTOPUSENCODE_OBJS) $(TESTOPUSPADDING_OBJS)\n\n.PHONY: all lib clean force check\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/NEWS",
    "content": ""
  },
  {
    "path": "deps/pjsip/third_party/opus/README",
    "content": "== Opus audio codec ==\n\nOpus is a codec for interactive speech and audio transmission over the Internet.\n\n  Opus can handle a wide range of interactive audio applications, including\nVoice over IP, videoconferencing, in-game  chat, and even remote live music\nperformances. It can scale from low bit-rate narrowband speech to very high\nquality stereo music.\n\n  Opus, when coupled with an appropriate container format, is also suitable\nfor non-realtime  stored-file applications such as music distribution, game\nsoundtracks, portable music players, jukeboxes, and other applications that\nhave historically used high latency formats such as MP3, AAC, or Vorbis.\n\n                    Opus is specified by IETF RFC 6716:\n                    https://tools.ietf.org/html/rfc6716\n\n  The Opus format and this implementation of it are subject to the royalty-\nfree patent and copyright licenses specified in the file COPYING.\n\nThis package implements a shared library for encoding and decoding raw Opus\nbitstreams. Raw Opus bitstreams should be used over RTP according to\n https://tools.ietf.org/html/rfc7587\n\nThe package also includes a number of test  tools used for testing the\ncorrect operation of the library. The bitstreams read/written by these\ntools should not be used for Opus file distribution: They include\nadditional debugging data and cannot support seeking.\n\nOpus stored in files should use the Ogg encapsulation for Opus which is\ndescribed at:\n https://wiki.xiph.org/OggOpus\n\nAn opus-tools package is available which provides encoding and decoding of\nOgg encapsulated Opus files and includes a number of useful features.\n\nOpus-tools can be found at:\n https://git.xiph.org/?p=opus-tools.git\nor on the main Opus website:\n https://opus-codec.org/\n\n== Compiling libopus ==\n\nTo build from a distribution tarball, you only need to do the following:\n\n% ./configure\n% make\n\nTo build from the git repository, the following steps are necessary:\n\n1) Clone the repository:\n\n% git clone https://git.xiph.org/opus.git\n% cd opus\n\n2) Compiling the source\n\n% ./autogen.sh\n% ./configure\n% make\n\n3) Install the codec libraries (optional)\n\n% sudo make install\n\nOnce you have compiled the codec, there will be a opus_demo executable\nin the top directory.\n\nUsage: opus_demo [-e] <application> <sampling rate (Hz)> <channels (1/2)>\n         <bits per second> [options] <input> <output>\n       opus_demo -d <sampling rate (Hz)> <channels (1/2)> [options]\n         <input> <output>\n\nmode: voip | audio | restricted-lowdelay\noptions:\n  -e                : only runs the encoder (output the bit-stream)\n  -d                : only runs the decoder (reads the bit-stream as input)\n  -cbr              : enable constant bitrate; default: variable bitrate\n  -cvbr             : enable constrained variable bitrate; default:\n                      unconstrained\n  -bandwidth <NB|MB|WB|SWB|FB>\n                    : audio bandwidth (from narrowband to fullband);\n                      default: sampling rate\n  -framesize <2.5|5|10|20|40|60>\n                    : frame size in ms; default: 20\n  -max_payload <bytes>\n                    : maximum payload size in bytes, default: 1024\n  -complexity <comp>\n                    : complexity, 0 (lowest) ... 10 (highest); default: 10\n  -inbandfec        : enable SILK inband FEC\n  -forcemono        : force mono encoding, even for stereo input\n  -dtx              : enable SILK DTX\n  -loss <perc>      : simulate packet loss, in percent (0-100); default: 0\n\ninput and output are little-endian signed 16-bit PCM files or opus\nbitstreams with simple opus_demo proprietary framing.\n\n== Testing ==\n\nThis package includes a collection of automated unit and system tests\nwhich SHOULD be run after compiling the package especially the first\ntime it is run on a new platform.\n\nTo run the integrated tests:\n% make check\n\nThere is also collection of standard test vectors which are not\nincluded in this package for size reasons but can be obtained from:\nhttps://opus-codec.org/testvectors/opus_testvectors.tar.gz\n\nTo run compare the code to these test vectors:\n\n% curl -O https://opus-codec.org/testvectors/opus_testvectors.tar.gz\n% tar -zxf opus_testvectors.tar.gz\n% ./tests/run_vectors.sh ./ opus_testvectors 48000\n\n== Portability notes ==\n\nThis implementation uses floating-point by default but can be compiled to\nuse only fixed-point arithmetic by setting --enable-fixed-point (if using\nautoconf) or by defining the FIXED_POINT macro (if building manually).\nThe fixed point implementation has somewhat lower audio quality and is\nslower on platforms with fast FPUs, it is normally only used in embedded\nenvironments.\n\nThe implementation can be compiled with either a C89 or a C99 compiler.\nWhile it does not rely on any _undefined behavior_ as defined by C89 or\nC99, it relies on common _implementation-defined behavior_ for two's\ncomplement architectures:\n\no Right shifts of negative values are consistent with two's\n  complement arithmetic, so that a>>b is equivalent to\n  floor(a/(2^b)),\n\no For conversion to a signed integer of N bits, the value is reduced\n  modulo 2^N to be within range of the type,\n\no The result of integer division of a negative value is truncated\n  towards zero, and\n\no The compiler provides a 64-bit integer type (a C99 requirement\n  which is supported by most C89 compilers).\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/_kiss_fft_guts.h",
    "content": "/*Copyright (c) 2003-2004, Mark Borgerding\n\n  All rights reserved.\n\n  Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n       this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright notice,\n       this list of conditions and the following disclaimer in the\n       documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n  POSSIBILITY OF SUCH DAMAGE.*/\n\n#ifndef KISS_FFT_GUTS_H\n#define KISS_FFT_GUTS_H\n\n#define MIN(a,b) ((a)<(b) ? (a):(b))\n#define MAX(a,b) ((a)>(b) ? (a):(b))\n\n/* kiss_fft.h\n   defines kiss_fft_scalar as either short or a float type\n   and defines\n   typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */\n#include \"kiss_fft.h\"\n\n/*\n  Explanation of macros dealing with complex math:\n\n   C_MUL(m,a,b)         : m = a*b\n   C_FIXDIV( c , div )  : if a fixed point impl., c /= div. noop otherwise\n   C_SUB( res, a,b)     : res = a - b\n   C_SUBFROM( res , a)  : res -= a\n   C_ADDTO( res , a)    : res += a\n * */\n#ifdef FIXED_POINT\n#include \"arch.h\"\n\n\n#define SAMP_MAX 2147483647\n#define TWID_MAX 32767\n#define TRIG_UPSCALE 1\n\n#define SAMP_MIN -SAMP_MAX\n\n\n#   define S_MUL(a,b) MULT16_32_Q15(b, a)\n\n#   define C_MUL(m,a,b) \\\n      do{ (m).r = SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \\\n          (m).i = ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0)\n\n#   define C_MULC(m,a,b) \\\n      do{ (m).r = ADD32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \\\n          (m).i = SUB32(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0)\n\n#   define C_MULBYSCALAR( c, s ) \\\n      do{ (c).r =  S_MUL( (c).r , s ) ;\\\n          (c).i =  S_MUL( (c).i , s ) ; }while(0)\n\n#   define DIVSCALAR(x,k) \\\n        (x) = S_MUL(  x, (TWID_MAX-((k)>>1))/(k)+1 )\n\n#   define C_FIXDIV(c,div) \\\n        do {    DIVSCALAR( (c).r , div);  \\\n                DIVSCALAR( (c).i  , div); }while (0)\n\n#define  C_ADD( res, a,b)\\\n    do {(res).r=ADD32((a).r,(b).r);  (res).i=ADD32((a).i,(b).i); \\\n    }while(0)\n#define  C_SUB( res, a,b)\\\n    do {(res).r=SUB32((a).r,(b).r);  (res).i=SUB32((a).i,(b).i); \\\n    }while(0)\n#define C_ADDTO( res , a)\\\n    do {(res).r = ADD32((res).r, (a).r);  (res).i = ADD32((res).i,(a).i);\\\n    }while(0)\n\n#define C_SUBFROM( res , a)\\\n    do {(res).r = ADD32((res).r,(a).r);  (res).i = SUB32((res).i,(a).i); \\\n    }while(0)\n\n#if defined(OPUS_ARM_INLINE_ASM)\n#include \"arm/kiss_fft_armv4.h\"\n#endif\n\n#if defined(OPUS_ARM_INLINE_EDSP)\n#include \"arm/kiss_fft_armv5e.h\"\n#endif\n#if defined(MIPSr1_ASM)\n#include \"mips/kiss_fft_mipsr1.h\"\n#endif\n\n#else  /* not FIXED_POINT*/\n\n#   define S_MUL(a,b) ( (a)*(b) )\n#define C_MUL(m,a,b) \\\n    do{ (m).r = (a).r*(b).r - (a).i*(b).i;\\\n        (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)\n#define C_MULC(m,a,b) \\\n    do{ (m).r = (a).r*(b).r + (a).i*(b).i;\\\n        (m).i = (a).i*(b).r - (a).r*(b).i; }while(0)\n\n#define C_MUL4(m,a,b) C_MUL(m,a,b)\n\n#   define C_FIXDIV(c,div) /* NOOP */\n#   define C_MULBYSCALAR( c, s ) \\\n    do{ (c).r *= (s);\\\n        (c).i *= (s); }while(0)\n#endif\n\n#ifndef CHECK_OVERFLOW_OP\n#  define CHECK_OVERFLOW_OP(a,op,b) /* noop */\n#endif\n\n#ifndef C_ADD\n#define  C_ADD( res, a,b)\\\n    do { \\\n            CHECK_OVERFLOW_OP((a).r,+,(b).r)\\\n            CHECK_OVERFLOW_OP((a).i,+,(b).i)\\\n            (res).r=(a).r+(b).r;  (res).i=(a).i+(b).i; \\\n    }while(0)\n#define  C_SUB( res, a,b)\\\n    do { \\\n            CHECK_OVERFLOW_OP((a).r,-,(b).r)\\\n            CHECK_OVERFLOW_OP((a).i,-,(b).i)\\\n            (res).r=(a).r-(b).r;  (res).i=(a).i-(b).i; \\\n    }while(0)\n#define C_ADDTO( res , a)\\\n    do { \\\n            CHECK_OVERFLOW_OP((res).r,+,(a).r)\\\n            CHECK_OVERFLOW_OP((res).i,+,(a).i)\\\n            (res).r += (a).r;  (res).i += (a).i;\\\n    }while(0)\n\n#define C_SUBFROM( res , a)\\\n    do {\\\n            CHECK_OVERFLOW_OP((res).r,-,(a).r)\\\n            CHECK_OVERFLOW_OP((res).i,-,(a).i)\\\n            (res).r -= (a).r;  (res).i -= (a).i; \\\n    }while(0)\n#endif /* C_ADD defined */\n\n#ifdef FIXED_POINT\n/*#  define KISS_FFT_COS(phase)  TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase))))\n#  define KISS_FFT_SIN(phase)  TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase))))*/\n#  define KISS_FFT_COS(phase)  floor(.5+TWID_MAX*cos (phase))\n#  define KISS_FFT_SIN(phase)  floor(.5+TWID_MAX*sin (phase))\n#  define HALF_OF(x) ((x)>>1)\n#elif defined(USE_SIMD)\n#  define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )\n#  define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )\n#  define HALF_OF(x) ((x)*_mm_set1_ps(.5f))\n#else\n#  define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)\n#  define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)\n#  define HALF_OF(x) ((x)*.5f)\n#endif\n\n#define  kf_cexp(x,phase) \\\n        do{ \\\n                (x)->r = KISS_FFT_COS(phase);\\\n                (x)->i = KISS_FFT_SIN(phase);\\\n        }while(0)\n\n#define  kf_cexp2(x,phase) \\\n   do{ \\\n      (x)->r = TRIG_UPSCALE*celt_cos_norm((phase));\\\n      (x)->i = TRIG_UPSCALE*celt_cos_norm((phase)-32768);\\\n}while(0)\n\n#endif /* KISS_FFT_GUTS_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arch.h",
    "content": "/* Copyright (c) 2003-2008 Jean-Marc Valin\n   Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/**\n   @file arch.h\n   @brief Various architecture definitions for CELT\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef ARCH_H\n#define ARCH_H\n\n#include \"opus_types.h\"\n#include \"opus_defines.h\"\n\n# if !defined(__GNUC_PREREQ)\n#  if defined(__GNUC__)&&defined(__GNUC_MINOR__)\n#   define __GNUC_PREREQ(_maj,_min) \\\n ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))\n#  else\n#   define __GNUC_PREREQ(_maj,_min) 0\n#  endif\n# endif\n\n#define CELT_SIG_SCALE 32768.f\n\n#define celt_fatal(str) _celt_fatal(str, __FILE__, __LINE__);\n#ifdef ENABLE_ASSERTIONS\n#include <stdio.h>\n#include <stdlib.h>\n#ifdef __GNUC__\n__attribute__((noreturn))\n#endif\nstatic OPUS_INLINE void _celt_fatal(const char *str, const char *file, int line)\n{\n   fprintf (stderr, \"Fatal (internal) error in %s, line %d: %s\\n\", file, line, str);\n   abort();\n}\n#define celt_assert(cond) {if (!(cond)) {celt_fatal(\"assertion failed: \" #cond);}}\n#define celt_assert2(cond, message) {if (!(cond)) {celt_fatal(\"assertion failed: \" #cond \"\\n\" message);}}\n#else\n#define celt_assert(cond)\n#define celt_assert2(cond, message)\n#endif\n\n#define IMUL32(a,b) ((a)*(b))\n\n#define MIN16(a,b) ((a) < (b) ? (a) : (b))   /**< Minimum 16-bit value.   */\n#define MAX16(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum 16-bit value.   */\n#define MIN32(a,b) ((a) < (b) ? (a) : (b))   /**< Minimum 32-bit value.   */\n#define MAX32(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum 32-bit value.   */\n#define IMIN(a,b) ((a) < (b) ? (a) : (b))   /**< Minimum int value.   */\n#define IMAX(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum int value.   */\n#define UADD32(a,b) ((a)+(b))\n#define USUB32(a,b) ((a)-(b))\n\n#define PRINT_MIPS(file)\n\n#ifdef FIXED_POINT\n\ntypedef opus_int16 opus_val16;\ntypedef opus_int32 opus_val32;\n\ntypedef opus_val32 celt_sig;\ntypedef opus_val16 celt_norm;\ntypedef opus_val32 celt_ener;\n\n#define Q15ONE 32767\n\n#define SIG_SHIFT 12\n\n#define NORM_SCALING 16384\n\n#define DB_SHIFT 10\n\n#define EPSILON 1\n#define VERY_SMALL 0\n#define VERY_LARGE16 ((opus_val16)32767)\n#define Q15_ONE ((opus_val16)32767)\n\n#define SCALEIN(a)      (a)\n#define SCALEOUT(a)     (a)\n\n#define ABS16(x) ((x) < 0 ? (-(x)) : (x))\n#define ABS32(x) ((x) < 0 ? (-(x)) : (x))\n\nstatic OPUS_INLINE opus_int16 SAT16(opus_int32 x) {\n   return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x;\n}\n\n#ifdef FIXED_DEBUG\n#include \"fixed_debug.h\"\n#else\n\n#include \"fixed_generic.h\"\n\n#ifdef OPUS_ARM_INLINE_EDSP\n#include \"arm/fixed_armv5e.h\"\n#elif defined (OPUS_ARM_INLINE_ASM)\n#include \"arm/fixed_armv4.h\"\n#elif defined (BFIN_ASM)\n#include \"fixed_bfin.h\"\n#elif defined (TI_C5X_ASM)\n#include \"fixed_c5x.h\"\n#elif defined (TI_C6X_ASM)\n#include \"fixed_c6x.h\"\n#endif\n\n#endif\n\n#else /* FIXED_POINT */\n\ntypedef float opus_val16;\ntypedef float opus_val32;\n\ntypedef float celt_sig;\ntypedef float celt_norm;\ntypedef float celt_ener;\n\n#ifdef FLOAT_APPROX\n/* This code should reliably detect NaN/inf even when -ffast-math is used.\n   Assumes IEEE 754 format. */\nstatic OPUS_INLINE int celt_isnan(float x)\n{\n   union {float f; opus_uint32 i;} in;\n   in.f = x;\n   return ((in.i>>23)&0xFF)==0xFF && (in.i&0x007FFFFF)!=0;\n}\n#else\n#ifdef __FAST_MATH__\n#error Cannot build libopus with -ffast-math unless FLOAT_APPROX is defined. This could result in crashes on extreme (e.g. NaN) input\n#endif\n#define celt_isnan(x) ((x)!=(x))\n#endif\n\n#define Q15ONE 1.0f\n\n#define NORM_SCALING 1.f\n\n#define EPSILON 1e-15f\n#define VERY_SMALL 1e-30f\n#define VERY_LARGE16 1e15f\n#define Q15_ONE ((opus_val16)1.f)\n\n/* This appears to be the same speed as C99's fabsf() but it's more portable. */\n#define ABS16(x) ((float)fabs(x))\n#define ABS32(x) ((float)fabs(x))\n\n#define QCONST16(x,bits) (x)\n#define QCONST32(x,bits) (x)\n\n#define NEG16(x) (-(x))\n#define NEG32(x) (-(x))\n#define EXTRACT16(x) (x)\n#define EXTEND32(x) (x)\n#define SHR16(a,shift) (a)\n#define SHL16(a,shift) (a)\n#define SHR32(a,shift) (a)\n#define SHL32(a,shift) (a)\n#define PSHR32(a,shift) (a)\n#define VSHR32(a,shift) (a)\n\n#define PSHR(a,shift)   (a)\n#define SHR(a,shift)    (a)\n#define SHL(a,shift)    (a)\n#define SATURATE(x,a)   (x)\n#define SATURATE16(x)   (x)\n\n#define ROUND16(a,shift)  (a)\n#define HALF16(x)       (.5f*(x))\n#define HALF32(x)       (.5f*(x))\n\n#define ADD16(a,b) ((a)+(b))\n#define SUB16(a,b) ((a)-(b))\n#define ADD32(a,b) ((a)+(b))\n#define SUB32(a,b) ((a)-(b))\n#define MULT16_16_16(a,b)     ((a)*(b))\n#define MULT16_16(a,b)     ((opus_val32)(a)*(opus_val32)(b))\n#define MAC16_16(c,a,b)     ((c)+(opus_val32)(a)*(opus_val32)(b))\n\n#define MULT16_32_Q15(a,b)     ((a)*(b))\n#define MULT16_32_Q16(a,b)     ((a)*(b))\n\n#define MULT32_32_Q31(a,b)     ((a)*(b))\n\n#define MAC16_32_Q15(c,a,b)     ((c)+(a)*(b))\n#define MAC16_32_Q16(c,a,b)     ((c)+(a)*(b))\n\n#define MULT16_16_Q11_32(a,b)     ((a)*(b))\n#define MULT16_16_Q11(a,b)     ((a)*(b))\n#define MULT16_16_Q13(a,b)     ((a)*(b))\n#define MULT16_16_Q14(a,b)     ((a)*(b))\n#define MULT16_16_Q15(a,b)     ((a)*(b))\n#define MULT16_16_P15(a,b)     ((a)*(b))\n#define MULT16_16_P13(a,b)     ((a)*(b))\n#define MULT16_16_P14(a,b)     ((a)*(b))\n#define MULT16_32_P16(a,b)     ((a)*(b))\n\n#define DIV32_16(a,b)     (((opus_val32)(a))/(opus_val16)(b))\n#define DIV32(a,b)     (((opus_val32)(a))/(opus_val32)(b))\n\n#define SCALEIN(a)      ((a)*CELT_SIG_SCALE)\n#define SCALEOUT(a)     ((a)*(1/CELT_SIG_SCALE))\n\n#define SIG2WORD16(x) (x)\n\n#endif /* !FIXED_POINT */\n\n#ifndef GLOBAL_STACK_SIZE\n#ifdef FIXED_POINT\n#define GLOBAL_STACK_SIZE 100000\n#else\n#define GLOBAL_STACK_SIZE 100000\n#endif\n#endif\n\n#endif /* ARCH_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/arm2gnu.pl",
    "content": "#!/usr/bin/perl\n\n# Copyright (C) 2002-2013 Xiph.org Foundation\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions\n# are met:\n#\n# - Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#\n# - Redistributions in binary form must reproduce the above copyright\n# notice, this list of conditions and the following disclaimer in the\n# documentation and/or other materials provided with the distribution.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nmy $bigend;  # little/big endian\nmy $nxstack;\nmy $apple = 0;\nmy $symprefix = \"\";\n\n$nxstack = 0;\n\neval 'exec /usr/local/bin/perl -S $0 ${1+\"$@\"}'\n    if $running_under_some_shell;\n\nwhile ($ARGV[0] =~ /^-/) {\n    $_ = shift;\n  last if /^--$/;\n    if (/^-n$/) {\n    $nflag++;\n    next;\n    }\n    if (/^--apple$/) {\n        $apple = 1;\n        $symprefix = \"_\";\n        next;\n    }\n    die \"I don't recognize this switch: $_\\\\n\";\n}\n$printit++ unless $nflag;\n\n$\\ = \"\\n\";      # automatically add newline on print\n$n=0;\n\n$thumb = 0;     # ARM mode by default, not Thumb.\n@proc_stack = ();\n\nprintf (\"    .syntax unified\\n\");\n\nLINE:\nwhile (<>) {\n\n    # For ADRLs we need to add a new line after the substituted one.\n    $addPadding = 0;\n\n    # First, we do not dare to touch *anything* inside double quotes, do we?\n    # Second, if you want a dollar character in the string,\n    # insert two of them -- that's how ARM C and assembler treat strings.\n    s/^([A-Za-z_]\\w*)[ \\t]+DCB[ \\t]*\\\"/$1:   .ascii \\\"/   && do { s/\\$\\$/\\$/g; next };\n    s/\\bDCB\\b[ \\t]*\\\"/.ascii \\\"/                          && do { s/\\$\\$/\\$/g; next };\n    s/^(\\S+)\\s+RN\\s+(\\S+)/$1 .req r$2/                    && do { s/\\$\\$/\\$/g; next };\n    # If there's nothing on a line but a comment, don't try to apply any further\n    #  substitutions (this is a cheap hack to avoid mucking up the license header)\n    s/^([ \\t]*);/$1@/                                     && do { s/\\$\\$/\\$/g; next };\n    # If substituted -- leave immediately !\n\n    s/@/,:/;\n    s/;/@/;\n    while ( /@.*'/ ) {\n      s/(@.*)'/$1/g;\n    }\n    s/\\{FALSE\\}/0/g;\n    s/\\{TRUE\\}/1/g;\n    s/\\{(\\w\\w\\w\\w+)\\}/$1/g;\n    s/\\bINCLUDE[ \\t]*([^ \\t\\n]+)/.include \\\"$1\\\"/;\n    s/\\bGET[ \\t]*([^ \\t\\n]+)/.include \\\"${ my $x=$1; $x =~ s|\\.s|-gnu.S|; \\$x }\\\"/;\n    s/\\bIMPORT\\b/.extern/;\n    s/\\bEXPORT\\b\\s*/.global $symprefix/;\n    s/^(\\s+)\\[/$1IF/;\n    s/^(\\s+)\\|/$1ELSE/;\n    s/^(\\s+)\\]/$1ENDIF/;\n    s/IF *:DEF:/ .ifdef/;\n    s/IF *:LNOT: *:DEF:/ .ifndef/;\n    s/ELSE/ .else/;\n    s/ENDIF/ .endif/;\n\n    if( /\\bIF\\b/ ) {\n      s/\\bIF\\b/ .if/;\n      s/=/==/;\n    }\n    if ( $n == 2) {\n        s/\\$/\\\\/g;\n    }\n    if ($n == 1) {\n        s/\\$//g;\n        s/label//g;\n    $n = 2;\n      }\n    if ( /MACRO/ ) {\n      s/MACRO *\\n/.macro/;\n      $n=1;\n    }\n    if ( /\\bMEND\\b/ ) {\n      s/\\bMEND\\b/.endm/;\n      $n=0;\n    }\n\n    # \".rdata\" doesn't work in 'as' version 2.13.2, as it is \".rodata\" there.\n    #\n    if ( /\\bAREA\\b/ ) {\n        my $align;\n        $align = \"2\";\n        if ( /ALIGN=(\\d+)/ ) {\n            $align = $1;\n        }\n        if ( /CODE/ ) {\n            $nxstack = 1;\n        }\n        s/^(.+)CODE(.+)READONLY(.*)/    .text/;\n        s/^(.+)DATA(.+)READONLY(.*)/    .section .rdata/;\n        s/^(.+)\\|\\|\\.data\\|\\|(.+)/    .data/;\n        s/^(.+)\\|\\|\\.bss\\|\\|(.+)/    .bss/;\n        s/$/;   .p2align $align/;\n        # Enable NEON instructions but don't produce a binary that requires\n        # ARMv7. RVCT does not have equivalent directives, so we just do this\n        # for all CODE areas.\n        if ( /.text/ ) {\n            # Separating .arch, .fpu, etc., by semicolons does not work (gas\n            # thinks the semicolon is part of the arch name, even when there's\n            # whitespace separating them). Sadly this means our line numbers\n            # won't match the original source file (we could use the .line\n            # directive, which is documented to be obsolete, but then gdb will\n            # show the wrong line in the translated source file).\n            s/$/;   .arch armv7-a\\n   .fpu neon\\n   .object_arch armv4t/ unless ($apple);\n        }\n    }\n\n    s/\\|\\|\\.constdata\\$(\\d+)\\|\\|/.L_CONST$1/;       # ||.constdata$3||\n    s/\\|\\|\\.bss\\$(\\d+)\\|\\|/.L_BSS$1/;               # ||.bss$2||\n    s/\\|\\|\\.data\\$(\\d+)\\|\\|/.L_DATA$1/;             # ||.data$2||\n    s/\\|\\|([a-zA-Z0-9_]+)\\@([a-zA-Z0-9_]+)\\|\\|/@ $&/;\n    s/^(\\s+)\\%(\\s)/    .space $1/;\n\n    s/\\|(.+)\\.(\\d+)\\|/\\.$1_$2/;                     # |L80.123| -> .L80_123\n    s/\\bCODE32\\b/.code 32/ && do {$thumb = 0};\n    s/\\bCODE16\\b/.code 16/ && do {$thumb = 1};\n    if (/\\bPROC\\b/)\n    {\n        my $prefix;\n        my $proc;\n        /^([A-Za-z_\\.]\\w+)\\b/;\n        $proc = $1;\n        $prefix = \"\";\n        if ($proc)\n        {\n            $prefix = $prefix.sprintf(\"\\t.type\\t%s, %%function; \",$proc) unless ($apple);\n            # Make sure we $prefix isn't empty here (for the $apple case).\n            # We handle mangling the label here, make sure it doesn't match\n            # the label handling below (if $prefix would be empty).\n            $prefix = \"; \";\n            push(@proc_stack, $proc);\n            s/^[A-Za-z_\\.]\\w+/$symprefix$&:/;\n        }\n        $prefix = $prefix.\"\\t.thumb_func; \" if ($thumb);\n        s/\\bPROC\\b/@ $&/;\n        $_ = $prefix.$_;\n    }\n    s/^(\\s*)(S|Q|SH|U|UQ|UH)ASX\\b/$1$2ADDSUBX/;\n    s/^(\\s*)(S|Q|SH|U|UQ|UH)SAX\\b/$1$2SUBADDX/;\n    if (/\\bENDP\\b/)\n    {\n        my $proc;\n        s/\\bENDP\\b/@ $&/;\n        $proc = pop(@proc_stack);\n        $_ = \"\\t.size $proc, .-$proc\".$_ if ($proc && !$apple);\n    }\n    s/\\bSUBT\\b/@ $&/;\n    s/\\bDATA\\b/@ $&/;   # DATA directive is deprecated -- Asm guide, p.7-25\n    s/\\bKEEP\\b/@ $&/;\n    s/\\bEXPORTAS\\b/@ $&/;\n    s/\\|\\|(.)+\\bEQU\\b/@ $&/;\n    s/\\|\\|([\\w\\$]+)\\|\\|/$1/;\n    s/\\bENTRY\\b/@ $&/;\n    s/\\bASSERT\\b/@ $&/;\n    s/\\bGBLL\\b/@ $&/;\n    s/\\bGBLA\\b/@ $&/;\n    s/^\\W+OPT\\b/@ $&/;\n    s/:OR:/|/g;\n    s/:SHL:/<</g;\n    s/:SHR:/>>/g;\n    s/:AND:/&/g;\n    s/:LAND:/&&/g;\n    s/CPSR/cpsr/;\n    s/SPSR/spsr/;\n    s/ALIGN$/.balign 4/;\n    s/ALIGN\\s+([0-9x]+)$/.balign $1/;\n    s/psr_cxsf/psr_all/;\n    s/LTORG/.ltorg/;\n    s/^([A-Za-z_]\\w*)[ \\t]+EQU/ .set $1,/;\n    s/^([A-Za-z_]\\w*)[ \\t]+SETL/ .set $1,/;\n    s/^([A-Za-z_]\\w*)[ \\t]+SETA/ .set $1,/;\n    s/^([A-Za-z_]\\w*)[ \\t]+\\*/ .set $1,/;\n\n    #  {PC} + 0xdeadfeed  -->  . + 0xdeadfeed\n    s/\\{PC\\} \\+/ \\. +/;\n\n    # Single hex constant on the line !\n    #\n    # >>> NOTE <<<\n    #   Double-precision floats in gcc are always mixed-endian, which means\n    #   bytes in two words are little-endian, but words are big-endian.\n    #   So, 0x0000deadfeed0000 would be stored as 0x0000dead at low address\n    #   and 0xfeed0000 at high address.\n    #\n    s/\\bDCFD\\b[ \\t]+0x([a-fA-F0-9]{8})([a-fA-F0-9]{8})/.long 0x$1, 0x$2/;\n    # Only decimal constants on the line, no hex !\n    s/\\bDCFD\\b[ \\t]+([0-9\\.\\-]+)/.double $1/;\n\n    # Single hex constant on the line !\n#    s/\\bDCFS\\b[ \\t]+0x([a-f0-9]{8})([a-f0-9]{8})/.long 0x$1, 0x$2/;\n    # Only decimal constants on the line, no hex !\n#    s/\\bDCFS\\b[ \\t]+([0-9\\.\\-]+)/.double $1/;\n    s/\\bDCFS[ \\t]+0x/.word 0x/;\n    s/\\bDCFS\\b/.float/;\n\n    s/^([A-Za-z_]\\w*)[ \\t]+DCD/$1 .word/;\n    s/\\bDCD\\b/.word/;\n    s/^([A-Za-z_]\\w*)[ \\t]+DCW/$1 .short/;\n    s/\\bDCW\\b/.short/;\n    s/^([A-Za-z_]\\w*)[ \\t]+DCB/$1 .byte/;\n    s/\\bDCB\\b/.byte/;\n    s/^([A-Za-z_]\\w*)[ \\t]+\\%/.comm $1,/;\n    s/^[A-Za-z_\\.]\\w+/$&:/;\n    s/^(\\d+)/$1:/;\n    s/\\%(\\d+)/$1b_or_f/;\n    s/\\%[Bb](\\d+)/$1b/;\n    s/\\%[Ff](\\d+)/$1f/;\n    s/\\%[Ff][Tt](\\d+)/$1f/;\n    s/&([\\dA-Fa-f]+)/0x$1/;\n    if ( /\\b2_[01]+\\b/ ) {\n      s/\\b2_([01]+)\\b/conv$1&&&&/g;\n      while ( /[01][01][01][01]&&&&/ ) {\n        s/0000&&&&/&&&&0/g;\n        s/0001&&&&/&&&&1/g;\n        s/0010&&&&/&&&&2/g;\n        s/0011&&&&/&&&&3/g;\n        s/0100&&&&/&&&&4/g;\n        s/0101&&&&/&&&&5/g;\n        s/0110&&&&/&&&&6/g;\n        s/0111&&&&/&&&&7/g;\n        s/1000&&&&/&&&&8/g;\n        s/1001&&&&/&&&&9/g;\n        s/1010&&&&/&&&&A/g;\n        s/1011&&&&/&&&&B/g;\n        s/1100&&&&/&&&&C/g;\n        s/1101&&&&/&&&&D/g;\n        s/1110&&&&/&&&&E/g;\n        s/1111&&&&/&&&&F/g;\n      }\n      s/000&&&&/&&&&0/g;\n      s/001&&&&/&&&&1/g;\n      s/010&&&&/&&&&2/g;\n      s/011&&&&/&&&&3/g;\n      s/100&&&&/&&&&4/g;\n      s/101&&&&/&&&&5/g;\n      s/110&&&&/&&&&6/g;\n      s/111&&&&/&&&&7/g;\n      s/00&&&&/&&&&0/g;\n      s/01&&&&/&&&&1/g;\n      s/10&&&&/&&&&2/g;\n      s/11&&&&/&&&&3/g;\n      s/0&&&&/&&&&0/g;\n      s/1&&&&/&&&&1/g;\n      s/conv&&&&/0x/g;\n    }\n\n    if ( /commandline/)\n    {\n        if( /-bigend/)\n        {\n            $bigend=1;\n        }\n    }\n\n    if ( /\\bDCDU\\b/ )\n    {\n        my $cmd=$_;\n        my $value;\n        my $prefix;\n        my $w1;\n        my $w2;\n        my $w3;\n        my $w4;\n\n        s/\\s+DCDU\\b/@ $&/;\n\n        $cmd =~ /\\bDCDU\\b\\s+0x(\\d+)/;\n        $value = $1;\n        $value =~ /(\\w\\w)(\\w\\w)(\\w\\w)(\\w\\w)/;\n        $w1 = $1;\n        $w2 = $2;\n        $w3 = $3;\n        $w4 = $4;\n\n        if( $bigend ne \"\")\n        {\n            # big endian\n            $prefix = \"\\t.byte\\t0x\".$w1.\";\".\n                      \"\\t.byte\\t0x\".$w2.\";\".\n                      \"\\t.byte\\t0x\".$w3.\";\".\n                      \"\\t.byte\\t0x\".$w4.\"; \";\n        }\n        else\n        {\n            # little endian\n            $prefix = \"\\t.byte\\t0x\".$w4.\";\".\n                      \"\\t.byte\\t0x\".$w3.\";\".\n                      \"\\t.byte\\t0x\".$w2.\";\".\n                      \"\\t.byte\\t0x\".$w1.\"; \";\n        }\n        $_=$prefix.$_;\n    }\n\n    if ( /\\badrl\\b/i )\n    {\n        s/\\badrl\\s+(\\w+)\\s*,\\s*(\\w+)/ldr $1,=$2/i;\n        $addPadding = 1;\n    }\n    s/\\bEND\\b/@ END/;\n} continue {\n    printf (\"%s\", $_) if $printit;\n    if ($addPadding != 0)\n    {\n        printf (\"   mov r0,r0\\n\");\n        $addPadding = 0;\n    }\n}\n#If we had a code section, mark that this object doesn't need an executable\n# stack.\nif ($nxstack && !$apple) {\n    printf (\"    .section\\t.note.GNU-stack,\\\"\\\",\\%\\%progbits\\n\");\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/arm_celt_map.c",
    "content": "/* Copyright (c) 2010 Xiph.Org Foundation\n * Copyright (c) 2013 Parrot */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"pitch.h\"\n#include \"kiss_fft.h\"\n#include \"mdct.h\"\n\n#if defined(OPUS_HAVE_RTCD)\n\n# if defined(FIXED_POINT)\nopus_val32 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,\n    const opus_val16 *, opus_val32 *, int , int) = {\n  celt_pitch_xcorr_c,               /* ARMv4 */\n  MAY_HAVE_EDSP(celt_pitch_xcorr),  /* EDSP */\n  MAY_HAVE_MEDIA(celt_pitch_xcorr), /* Media */\n  MAY_HAVE_NEON(celt_pitch_xcorr)   /* NEON */\n};\n# else /* !FIXED_POINT */\n#  if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\nvoid (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,\n    const opus_val16 *, opus_val32 *, int, int) = {\n  celt_pitch_xcorr_c,              /* ARMv4 */\n  celt_pitch_xcorr_c,              /* EDSP */\n  celt_pitch_xcorr_c,              /* Media */\n  celt_pitch_xcorr_float_neon      /* Neon */\n};\n#  endif\n# endif /* FIXED_POINT */\n\n# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\n#  if defined(HAVE_ARM_NE10)\n#   if defined(CUSTOM_MODES)\nint (*const OPUS_FFT_ALLOC_ARCH_IMPL[OPUS_ARCHMASK+1])(kiss_fft_state *st) = {\n   opus_fft_alloc_arch_c,        /* ARMv4 */\n   opus_fft_alloc_arch_c,        /* EDSP */\n   opus_fft_alloc_arch_c,        /* Media */\n   opus_fft_alloc_arm_neon       /* Neon with NE10 library support */\n};\n\nvoid (*const OPUS_FFT_FREE_ARCH_IMPL[OPUS_ARCHMASK+1])(kiss_fft_state *st) = {\n   opus_fft_free_arch_c,         /* ARMv4 */\n   opus_fft_free_arch_c,         /* EDSP */\n   opus_fft_free_arch_c,         /* Media */\n   opus_fft_free_arm_neon        /* Neon with NE10 */\n};\n#   endif /* CUSTOM_MODES */\n\nvoid (*const OPUS_FFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,\n                                        const kiss_fft_cpx *fin,\n                                        kiss_fft_cpx *fout) = {\n   opus_fft_c,                   /* ARMv4 */\n   opus_fft_c,                   /* EDSP */\n   opus_fft_c,                   /* Media */\n   opus_fft_neon                 /* Neon with NE10 */\n};\n\nvoid (*const OPUS_IFFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,\n                                         const kiss_fft_cpx *fin,\n                                         kiss_fft_cpx *fout) = {\n   opus_ifft_c,                   /* ARMv4 */\n   opus_ifft_c,                   /* EDSP */\n   opus_ifft_c,                   /* Media */\n   opus_ifft_neon                 /* Neon with NE10 */\n};\n\nvoid (*const CLT_MDCT_FORWARD_IMPL[OPUS_ARCHMASK+1])(const mdct_lookup *l,\n                                                     kiss_fft_scalar *in,\n                                                     kiss_fft_scalar * OPUS_RESTRICT out,\n                                                     const opus_val16 *window,\n                                                     int overlap, int shift,\n                                                     int stride, int arch) = {\n   clt_mdct_forward_c,           /* ARMv4 */\n   clt_mdct_forward_c,           /* EDSP */\n   clt_mdct_forward_c,           /* Media */\n   clt_mdct_forward_neon         /* Neon with NE10 */\n};\n\nvoid (*const CLT_MDCT_BACKWARD_IMPL[OPUS_ARCHMASK+1])(const mdct_lookup *l,\n                                                      kiss_fft_scalar *in,\n                                                      kiss_fft_scalar * OPUS_RESTRICT out,\n                                                      const opus_val16 *window,\n                                                      int overlap, int shift,\n                                                      int stride, int arch) = {\n   clt_mdct_backward_c,           /* ARMv4 */\n   clt_mdct_backward_c,           /* EDSP */\n   clt_mdct_backward_c,           /* Media */\n   clt_mdct_backward_neon         /* Neon with NE10 */\n};\n\n#  endif /* HAVE_ARM_NE10 */\n# endif /* OPUS_ARM_MAY_HAVE_NEON_INTR */\n\n#endif /* OPUS_HAVE_RTCD */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/armcpu.c",
    "content": "/* Copyright (c) 2010 Xiph.Org Foundation\n * Copyright (c) 2013 Parrot */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/* Original code from libtheora modified to suit to Opus */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#ifdef OPUS_HAVE_RTCD\n\n#include \"armcpu.h\"\n#include \"cpu_support.h\"\n#include \"os_support.h\"\n#include \"opus_types.h\"\n\n#define OPUS_CPU_ARM_V4    (1)\n#define OPUS_CPU_ARM_EDSP  (1<<1)\n#define OPUS_CPU_ARM_MEDIA (1<<2)\n#define OPUS_CPU_ARM_NEON  (1<<3)\n\n#if defined(_MSC_VER)\n/*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/\n# define WIN32_LEAN_AND_MEAN\n# define WIN32_EXTRA_LEAN\n# include <windows.h>\n\nstatic OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){\n  opus_uint32 flags;\n  flags=0;\n  /* MSVC has no OPUS_INLINE __asm support for ARM, but it does let you __emit\n   * instructions via their assembled hex code.\n   * All of these instructions should be essentially nops. */\n# if defined(OPUS_ARM_MAY_HAVE_EDSP)\n  __try{\n    /*PLD [r13]*/\n    __emit(0xF5DDF000);\n    flags|=OPUS_CPU_ARM_EDSP;\n  }\n  __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){\n    /*Ignore exception.*/\n  }\n#  if defined(OPUS_ARM_MAY_HAVE_MEDIA)\n  __try{\n    /*SHADD8 r3,r3,r3*/\n    __emit(0xE6333F93);\n    flags|=OPUS_CPU_ARM_MEDIA;\n  }\n  __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){\n    /*Ignore exception.*/\n  }\n#   if defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\n  __try{\n    /*VORR q0,q0,q0*/\n    __emit(0xF2200150);\n    flags|=OPUS_CPU_ARM_NEON;\n  }\n  __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){\n    /*Ignore exception.*/\n  }\n#   endif\n#  endif\n# endif\n  return flags;\n}\n\n#elif defined(__linux__)\n/* Linux based */\nopus_uint32 opus_cpu_capabilities(void)\n{\n  opus_uint32 flags = 0;\n  FILE *cpuinfo;\n\n  /* Reading /proc/self/auxv would be easier, but that doesn't work reliably on\n   * Android */\n  cpuinfo = fopen(\"/proc/cpuinfo\", \"r\");\n\n  if(cpuinfo != NULL)\n  {\n    /* 512 should be enough for anybody (it's even enough for all the flags that\n     * x86 has accumulated... so far). */\n    char buf[512];\n\n    while(fgets(buf, 512, cpuinfo) != NULL)\n    {\n# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\n      /* Search for edsp and neon flag */\n      if(memcmp(buf, \"Features\", 8) == 0)\n      {\n        char *p;\n#  if defined(OPUS_ARM_MAY_HAVE_EDSP)\n        p = strstr(buf, \" edsp\");\n        if(p != NULL && (p[5] == ' ' || p[5] == '\\n'))\n          flags |= OPUS_CPU_ARM_EDSP;\n#  endif\n\n#  if defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\n        p = strstr(buf, \" neon\");\n        if(p != NULL && (p[5] == ' ' || p[5] == '\\n'))\n          flags |= OPUS_CPU_ARM_NEON;\n#  endif\n      }\n# endif\n\n# if defined(OPUS_ARM_MAY_HAVE_MEDIA)\n      /* Search for media capabilities (>= ARMv6) */\n      if(memcmp(buf, \"CPU architecture:\", 17) == 0)\n      {\n        int version;\n        version = atoi(buf+17);\n\n        if(version >= 6)\n          flags |= OPUS_CPU_ARM_MEDIA;\n      }\n# endif\n    }\n\n    fclose(cpuinfo);\n  }\n  return flags;\n}\n#else\n/* The feature registers which can tell us what the processor supports are\n * accessible in priveleged modes only, so we can't have a general user-space\n * detection method like on x86.*/\n# error \"Configured to use ARM asm but no CPU detection method available for \" \\\n   \"your platform.  Reconfigure with --disable-rtcd (or send patches).\"\n#endif\n\nint opus_select_arch(void)\n{\n  opus_uint32 flags = opus_cpu_capabilities();\n  int arch = 0;\n\n  if(!(flags & OPUS_CPU_ARM_EDSP))\n    return arch;\n  arch++;\n\n  if(!(flags & OPUS_CPU_ARM_MEDIA))\n    return arch;\n  arch++;\n\n  if(!(flags & OPUS_CPU_ARM_NEON))\n    return arch;\n  arch++;\n\n  return arch;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/armcpu.h",
    "content": "/* Copyright (c) 2010 Xiph.Org Foundation\n * Copyright (c) 2013 Parrot */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#if !defined(ARMCPU_H)\n# define ARMCPU_H\n\n# if defined(OPUS_ARM_MAY_HAVE_EDSP)\n#  define MAY_HAVE_EDSP(name) name ## _edsp\n# else\n#  define MAY_HAVE_EDSP(name) name ## _c\n# endif\n\n# if defined(OPUS_ARM_MAY_HAVE_MEDIA)\n#  define MAY_HAVE_MEDIA(name) name ## _media\n# else\n#  define MAY_HAVE_MEDIA(name) MAY_HAVE_EDSP(name)\n# endif\n\n# if defined(OPUS_ARM_MAY_HAVE_NEON)\n#  define MAY_HAVE_NEON(name) name ## _neon\n# else\n#  define MAY_HAVE_NEON(name) MAY_HAVE_MEDIA(name)\n# endif\n\n# if defined(OPUS_ARM_PRESUME_EDSP)\n#  define PRESUME_EDSP(name) name ## _edsp\n# else\n#  define PRESUME_EDSP(name) name ## _c\n# endif\n\n# if defined(OPUS_ARM_PRESUME_MEDIA)\n#  define PRESUME_MEDIA(name) name ## _media\n# else\n#  define PRESUME_MEDIA(name) PRESUME_EDSP(name)\n# endif\n\n# if defined(OPUS_ARM_PRESUME_NEON)\n#  define PRESUME_NEON(name) name ## _neon\n# else\n#  define PRESUME_NEON(name) PRESUME_MEDIA(name)\n# endif\n\n# if defined(OPUS_HAVE_RTCD)\nint opus_select_arch(void);\n# endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/armopts.s.in",
    "content": "/* Copyright (C) 2013 Mozilla Corporation */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n; Set the following to 1 if we have EDSP instructions\n;  (LDRD/STRD, etc., ARMv5E and later).\nOPUS_ARM_MAY_HAVE_EDSP  * @OPUS_ARM_MAY_HAVE_EDSP@\n\n; Set the following to 1 if we have ARMv6 media instructions.\nOPUS_ARM_MAY_HAVE_MEDIA * @OPUS_ARM_MAY_HAVE_MEDIA@\n\n; Set the following to 1 if we have NEON (some ARMv7)\nOPUS_ARM_MAY_HAVE_NEON  * @OPUS_ARM_MAY_HAVE_NEON@\n\nEND\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/celt_ne10_fft.c",
    "content": "/* Copyright (c) 2015 Xiph.Org Foundation\n   Written by Viswanath Puttagunta */\n/**\n   @file celt_ne10_fft.c\n   @brief ARM Neon optimizations for fft using NE10 library\n */\n\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef SKIP_CONFIG_H\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#endif\n\n#include <NE10_init.h>\n#include <NE10_dsp.h>\n#include \"os_support.h\"\n#include \"kiss_fft.h\"\n#include \"stack_alloc.h\"\n\n#if !defined(FIXED_POINT)\n# define NE10_FFT_ALLOC_C2C_TYPE_NEON ne10_fft_alloc_c2c_float32_neon\n# define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_float32_t\n# define NE10_FFT_STATE_TYPE_T ne10_fft_state_float32_t\n# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_float32\n# define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_float32_t\n# define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_float32_neon\n#else\n# define NE10_FFT_ALLOC_C2C_TYPE_NEON(nfft) ne10_fft_alloc_c2c_int32_neon(nfft)\n# define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_int32_t\n# define NE10_FFT_STATE_TYPE_T ne10_fft_state_int32_t\n# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32\n# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32\n# define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_int32_t\n# define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_int32_neon\n#endif\n\n#if defined(CUSTOM_MODES)\n\n/* nfft lengths in NE10 that support scaled fft */\n# define NE10_FFTSCALED_SUPPORT_MAX 4\nstatic const int ne10_fft_scaled_support[NE10_FFTSCALED_SUPPORT_MAX] = {\n   480, 240, 120, 60\n};\n\nint opus_fft_alloc_arm_neon(kiss_fft_state *st)\n{\n   int i;\n   size_t memneeded = sizeof(struct arch_fft_state);\n\n   st->arch_fft = (arch_fft_state *)opus_alloc(memneeded);\n   if (!st->arch_fft)\n      return -1;\n\n   for (i = 0; i < NE10_FFTSCALED_SUPPORT_MAX; i++) {\n      if(st->nfft == ne10_fft_scaled_support[i])\n         break;\n   }\n   if (i == NE10_FFTSCALED_SUPPORT_MAX) {\n      /* This nfft length (scaled fft) is not supported in NE10 */\n      st->arch_fft->is_supported = 0;\n      st->arch_fft->priv = NULL;\n   }\n   else {\n      st->arch_fft->is_supported = 1;\n      st->arch_fft->priv = (void *)NE10_FFT_ALLOC_C2C_TYPE_NEON(st->nfft);\n      if (st->arch_fft->priv == NULL) {\n         return -1;\n      }\n   }\n   return 0;\n}\n\nvoid opus_fft_free_arm_neon(kiss_fft_state *st)\n{\n   NE10_FFT_CFG_TYPE_T cfg;\n\n   if (!st->arch_fft)\n      return;\n\n   cfg = (NE10_FFT_CFG_TYPE_T)st->arch_fft->priv;\n   if (cfg)\n      NE10_FFT_DESTROY_C2C_TYPE(cfg);\n   opus_free(st->arch_fft);\n}\n#endif\n\nvoid opus_fft_neon(const kiss_fft_state *st,\n                   const kiss_fft_cpx *fin,\n                   kiss_fft_cpx *fout)\n{\n   NE10_FFT_STATE_TYPE_T state;\n   NE10_FFT_CFG_TYPE_T cfg = &state;\n   VARDECL(NE10_FFT_CPX_TYPE_T, buffer);\n   SAVE_STACK;\n   ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T);\n\n   if (!st->arch_fft->is_supported) {\n      /* This nfft length (scaled fft) not supported in NE10 */\n      opus_fft_c(st, fin, fout);\n   }\n   else {\n      memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T));\n      state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0];\n#if !defined(FIXED_POINT)\n      state.is_forward_scaled = 1;\n\n      NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,\n                                (NE10_FFT_CPX_TYPE_T *)fin,\n                                cfg, 0);\n#else\n      NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,\n                                (NE10_FFT_CPX_TYPE_T *)fin,\n                                cfg, 0, 1);\n#endif\n   }\n   RESTORE_STACK;\n}\n\nvoid opus_ifft_neon(const kiss_fft_state *st,\n                    const kiss_fft_cpx *fin,\n                    kiss_fft_cpx *fout)\n{\n   NE10_FFT_STATE_TYPE_T state;\n   NE10_FFT_CFG_TYPE_T cfg = &state;\n   VARDECL(NE10_FFT_CPX_TYPE_T, buffer);\n   SAVE_STACK;\n   ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T);\n\n   if (!st->arch_fft->is_supported) {\n      /* This nfft length (scaled fft) not supported in NE10 */\n      opus_ifft_c(st, fin, fout);\n   }\n   else {\n      memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T));\n      state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0];\n#if !defined(FIXED_POINT)\n      state.is_backward_scaled = 0;\n\n      NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,\n                                (NE10_FFT_CPX_TYPE_T *)fin,\n                                cfg, 1);\n#else\n      NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,\n                                (NE10_FFT_CPX_TYPE_T *)fin,\n                                cfg, 1, 0);\n#endif\n   }\n   RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/celt_ne10_mdct.c",
    "content": "/* Copyright (c) 2015 Xiph.Org Foundation\n   Written by Viswanath Puttagunta */\n/**\n   @file celt_ne10_mdct.c\n   @brief ARM Neon optimizations for mdct using NE10 library\n */\n\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef SKIP_CONFIG_H\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#endif\n\n#include \"kiss_fft.h\"\n#include \"_kiss_fft_guts.h\"\n#include \"mdct.h\"\n#include \"stack_alloc.h\"\n\nvoid clt_mdct_forward_neon(const mdct_lookup *l,\n                           kiss_fft_scalar *in,\n                           kiss_fft_scalar * OPUS_RESTRICT out,\n                           const opus_val16 *window,\n                           int overlap, int shift, int stride, int arch)\n{\n   int i;\n   int N, N2, N4;\n   VARDECL(kiss_fft_scalar, f);\n   VARDECL(kiss_fft_cpx, f2);\n   const kiss_fft_state *st = l->kfft[shift];\n   const kiss_twiddle_scalar *trig;\n\n   SAVE_STACK;\n\n   N = l->n;\n   trig = l->trig;\n   for (i=0;i<shift;i++)\n   {\n      N >>= 1;\n      trig += N;\n   }\n   N2 = N>>1;\n   N4 = N>>2;\n\n   ALLOC(f, N2, kiss_fft_scalar);\n   ALLOC(f2, N4, kiss_fft_cpx);\n\n   /* Consider the input to be composed of four blocks: [a, b, c, d] */\n   /* Window, shuffle, fold */\n   {\n      /* Temp pointers to make it really clear to the compiler what we're doing */\n      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);\n      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);\n      kiss_fft_scalar * OPUS_RESTRICT yp = f;\n      const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);\n      const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;\n      for(i=0;i<((overlap+3)>>2);i++)\n      {\n         /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/\n         *yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2);\n         *yp++ = MULT16_32_Q15(*wp1, *xp1)    - MULT16_32_Q15(*wp2, xp2[-N2]);\n         xp1+=2;\n         xp2-=2;\n         wp1+=2;\n         wp2-=2;\n      }\n      wp1 = window;\n      wp2 = window+overlap-1;\n      for(;i<N4-((overlap+3)>>2);i++)\n      {\n         /* Real part arranged as a-bR, Imag part arranged as -c-dR */\n         *yp++ = *xp2;\n         *yp++ = *xp1;\n         xp1+=2;\n         xp2-=2;\n      }\n      for(;i<N4;i++)\n      {\n         /* Real part arranged as a-bR, Imag part arranged as -c-dR */\n         *yp++ =  -MULT16_32_Q15(*wp1, xp1[-N2]) + MULT16_32_Q15(*wp2, *xp2);\n         *yp++ = MULT16_32_Q15(*wp2, *xp1)     + MULT16_32_Q15(*wp1, xp2[N2]);\n         xp1+=2;\n         xp2-=2;\n         wp1+=2;\n         wp2-=2;\n      }\n   }\n   /* Pre-rotation */\n   {\n      kiss_fft_scalar * OPUS_RESTRICT yp = f;\n      const kiss_twiddle_scalar *t = &trig[0];\n      for(i=0;i<N4;i++)\n      {\n         kiss_fft_cpx yc;\n         kiss_twiddle_scalar t0, t1;\n         kiss_fft_scalar re, im, yr, yi;\n         t0 = t[i];\n         t1 = t[N4+i];\n         re = *yp++;\n         im = *yp++;\n         yr = S_MUL(re,t0)  -  S_MUL(im,t1);\n         yi = S_MUL(im,t0)  +  S_MUL(re,t1);\n         yc.r = yr;\n         yc.i = yi;\n         f2[i] = yc;\n      }\n   }\n\n   opus_fft(st, f2, (kiss_fft_cpx *)f, arch);\n\n   /* Post-rotate */\n   {\n      /* Temp pointers to make it really clear to the compiler what we're doing */\n      const kiss_fft_cpx * OPUS_RESTRICT fp = (kiss_fft_cpx *)f;\n      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;\n      kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);\n      const kiss_twiddle_scalar *t = &trig[0];\n      /* Temp pointers to make it really clear to the compiler what we're doing */\n      for(i=0;i<N4;i++)\n      {\n         kiss_fft_scalar yr, yi;\n         yr = S_MUL(fp->i,t[N4+i]) - S_MUL(fp->r,t[i]);\n         yi = S_MUL(fp->r,t[N4+i]) + S_MUL(fp->i,t[i]);\n         *yp1 = yr;\n         *yp2 = yi;\n         fp++;\n         yp1 += 2*stride;\n         yp2 -= 2*stride;\n      }\n   }\n   RESTORE_STACK;\n}\n\nvoid clt_mdct_backward_neon(const mdct_lookup *l,\n                            kiss_fft_scalar *in,\n                            kiss_fft_scalar * OPUS_RESTRICT out,\n                            const opus_val16 * OPUS_RESTRICT window,\n                            int overlap, int shift, int stride, int arch)\n{\n   int i;\n   int N, N2, N4;\n   VARDECL(kiss_fft_scalar, f);\n   const kiss_twiddle_scalar *trig;\n   const kiss_fft_state *st = l->kfft[shift];\n\n   N = l->n;\n   trig = l->trig;\n   for (i=0;i<shift;i++)\n   {\n      N >>= 1;\n      trig += N;\n   }\n   N2 = N>>1;\n   N4 = N>>2;\n\n   ALLOC(f, N2, kiss_fft_scalar);\n\n   /* Pre-rotate */\n   {\n      /* Temp pointers to make it really clear to the compiler what we're doing */\n      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;\n      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);\n      kiss_fft_scalar * OPUS_RESTRICT yp = f;\n      const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0];\n      for(i=0;i<N4;i++)\n      {\n         kiss_fft_scalar yr, yi;\n         yr = S_MUL(*xp2, t[i]) + S_MUL(*xp1, t[N4+i]);\n         yi = S_MUL(*xp1, t[i]) - S_MUL(*xp2, t[N4+i]);\n         yp[2*i] = yr;\n         yp[2*i+1] = yi;\n         xp1+=2*stride;\n         xp2-=2*stride;\n      }\n   }\n\n   opus_ifft(st, (kiss_fft_cpx *)f, (kiss_fft_cpx*)(out+(overlap>>1)), arch);\n\n   /* Post-rotate and de-shuffle from both ends of the buffer at once to make\n      it in-place. */\n   {\n      kiss_fft_scalar * yp0 = out+(overlap>>1);\n      kiss_fft_scalar * yp1 = out+(overlap>>1)+N2-2;\n      const kiss_twiddle_scalar *t = &trig[0];\n      /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the\n         middle pair will be computed twice. */\n      for(i=0;i<(N4+1)>>1;i++)\n      {\n         kiss_fft_scalar re, im, yr, yi;\n         kiss_twiddle_scalar t0, t1;\n         re = yp0[0];\n         im = yp0[1];\n         t0 = t[i];\n         t1 = t[N4+i];\n         /* We'd scale up by 2 here, but instead it's done when mixing the windows */\n         yr = S_MUL(re,t0) + S_MUL(im,t1);\n         yi = S_MUL(re,t1) - S_MUL(im,t0);\n         re = yp1[0];\n         im = yp1[1];\n         yp0[0] = yr;\n         yp1[1] = yi;\n\n         t0 = t[(N4-i-1)];\n         t1 = t[(N2-i-1)];\n         /* We'd scale up by 2 here, but instead it's done when mixing the windows */\n         yr = S_MUL(re,t0) + S_MUL(im,t1);\n         yi = S_MUL(re,t1) - S_MUL(im,t0);\n         yp1[0] = yr;\n         yp0[1] = yi;\n         yp0 += 2;\n         yp1 -= 2;\n      }\n   }\n\n   /* Mirror on both sides for TDAC */\n   {\n      kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;\n      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;\n      const opus_val16 * OPUS_RESTRICT wp1 = window;\n      const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;\n\n      for(i = 0; i < overlap/2; i++)\n      {\n         kiss_fft_scalar x1, x2;\n         x1 = *xp1;\n         x2 = *yp1;\n         *yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1);\n         *xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1);\n         wp1++;\n         wp2--;\n      }\n   }\n   RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/celt_neon_intr.c",
    "content": "/* Copyright (c) 2014-2015 Xiph.Org Foundation\n   Written by Viswanath Puttagunta */\n/**\n   @file celt_neon_intr.c\n   @brief ARM Neon Intrinsic optimizations for celt\n */\n\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <arm_neon.h>\n#include \"../pitch.h\"\n\n#if !defined(FIXED_POINT)\n/*\n * Function: xcorr_kernel_neon_float\n * ---------------------------------\n * Computes 4 correlation values and stores them in sum[4]\n */\nstatic void xcorr_kernel_neon_float(const float32_t *x, const float32_t *y,\n      float32_t sum[4], int len) {\n   float32x4_t YY[3];\n   float32x4_t YEXT[3];\n   float32x4_t XX[2];\n   float32x2_t XX_2;\n   float32x4_t SUMM;\n   const float32_t *xi = x;\n   const float32_t *yi = y;\n\n   celt_assert(len>0);\n\n   YY[0] = vld1q_f32(yi);\n   SUMM = vdupq_n_f32(0);\n\n   /* Consume 8 elements in x vector and 12 elements in y\n    * vector. However, the 12'th element never really gets\n    * touched in this loop. So, if len == 8, then we only\n    * must access y[0] to y[10]. y[11] must not be accessed\n    * hence make sure len > 8 and not len >= 8\n    */\n   while (len > 8) {\n      yi += 4;\n      YY[1] = vld1q_f32(yi);\n      yi += 4;\n      YY[2] = vld1q_f32(yi);\n\n      XX[0] = vld1q_f32(xi);\n      xi += 4;\n      XX[1] = vld1q_f32(xi);\n      xi += 4;\n\n      SUMM = vmlaq_lane_f32(SUMM, YY[0], vget_low_f32(XX[0]), 0);\n      YEXT[0] = vextq_f32(YY[0], YY[1], 1);\n      SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[0]), 1);\n      YEXT[1] = vextq_f32(YY[0], YY[1], 2);\n      SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[0]), 0);\n      YEXT[2] = vextq_f32(YY[0], YY[1], 3);\n      SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[0]), 1);\n\n      SUMM = vmlaq_lane_f32(SUMM, YY[1], vget_low_f32(XX[1]), 0);\n      YEXT[0] = vextq_f32(YY[1], YY[2], 1);\n      SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[1]), 1);\n      YEXT[1] = vextq_f32(YY[1], YY[2], 2);\n      SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[1]), 0);\n      YEXT[2] = vextq_f32(YY[1], YY[2], 3);\n      SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[1]), 1);\n\n      YY[0] = YY[2];\n      len -= 8;\n   }\n\n   /* Consume 4 elements in x vector and 8 elements in y\n    * vector. However, the 8'th element in y never really gets\n    * touched in this loop. So, if len == 4, then we only\n    * must access y[0] to y[6]. y[7] must not be accessed\n    * hence make sure len>4 and not len>=4\n    */\n   if (len > 4) {\n      yi += 4;\n      YY[1] = vld1q_f32(yi);\n\n      XX[0] = vld1q_f32(xi);\n      xi += 4;\n\n      SUMM = vmlaq_lane_f32(SUMM, YY[0], vget_low_f32(XX[0]), 0);\n      YEXT[0] = vextq_f32(YY[0], YY[1], 1);\n      SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[0]), 1);\n      YEXT[1] = vextq_f32(YY[0], YY[1], 2);\n      SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[0]), 0);\n      YEXT[2] = vextq_f32(YY[0], YY[1], 3);\n      SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[0]), 1);\n\n      YY[0] = YY[1];\n      len -= 4;\n   }\n\n   while (--len > 0) {\n      XX_2 = vld1_dup_f32(xi++);\n      SUMM = vmlaq_lane_f32(SUMM, YY[0], XX_2, 0);\n      YY[0]= vld1q_f32(++yi);\n   }\n\n   XX_2 = vld1_dup_f32(xi);\n   SUMM = vmlaq_lane_f32(SUMM, YY[0], XX_2, 0);\n\n   vst1q_f32(sum, SUMM);\n}\n\n/*\n * Function: xcorr_kernel_neon_float_process1\n * ---------------------------------\n * Computes single correlation values and stores in *sum\n */\nstatic void xcorr_kernel_neon_float_process1(const float32_t *x,\n      const float32_t *y, float32_t *sum, int len) {\n   float32x4_t XX[4];\n   float32x4_t YY[4];\n   float32x2_t XX_2;\n   float32x2_t YY_2;\n   float32x4_t SUMM;\n   float32x2_t SUMM_2[2];\n   const float32_t *xi = x;\n   const float32_t *yi = y;\n\n   SUMM = vdupq_n_f32(0);\n\n   /* Work on 16 values per iteration */\n   while (len >= 16) {\n      XX[0] = vld1q_f32(xi);\n      xi += 4;\n      XX[1] = vld1q_f32(xi);\n      xi += 4;\n      XX[2] = vld1q_f32(xi);\n      xi += 4;\n      XX[3] = vld1q_f32(xi);\n      xi += 4;\n\n      YY[0] = vld1q_f32(yi);\n      yi += 4;\n      YY[1] = vld1q_f32(yi);\n      yi += 4;\n      YY[2] = vld1q_f32(yi);\n      yi += 4;\n      YY[3] = vld1q_f32(yi);\n      yi += 4;\n\n      SUMM = vmlaq_f32(SUMM, YY[0], XX[0]);\n      SUMM = vmlaq_f32(SUMM, YY[1], XX[1]);\n      SUMM = vmlaq_f32(SUMM, YY[2], XX[2]);\n      SUMM = vmlaq_f32(SUMM, YY[3], XX[3]);\n      len -= 16;\n   }\n\n   /* Work on 8 values */\n   if (len >= 8) {\n      XX[0] = vld1q_f32(xi);\n      xi += 4;\n      XX[1] = vld1q_f32(xi);\n      xi += 4;\n\n      YY[0] = vld1q_f32(yi);\n      yi += 4;\n      YY[1] = vld1q_f32(yi);\n      yi += 4;\n\n      SUMM = vmlaq_f32(SUMM, YY[0], XX[0]);\n      SUMM = vmlaq_f32(SUMM, YY[1], XX[1]);\n      len -= 8;\n   }\n\n   /* Work on 4 values */\n   if (len >= 4) {\n      XX[0] = vld1q_f32(xi);\n      xi += 4;\n      YY[0] = vld1q_f32(yi);\n      yi += 4;\n      SUMM = vmlaq_f32(SUMM, YY[0], XX[0]);\n      len -= 4;\n   }\n\n   /* Start accumulating results */\n   SUMM_2[0] = vget_low_f32(SUMM);\n   if (len >= 2) {\n      /* While at it, consume 2 more values if available */\n      XX_2 = vld1_f32(xi);\n      xi += 2;\n      YY_2 = vld1_f32(yi);\n      yi += 2;\n      SUMM_2[0] = vmla_f32(SUMM_2[0], YY_2, XX_2);\n      len -= 2;\n   }\n   SUMM_2[1] = vget_high_f32(SUMM);\n   SUMM_2[0] = vadd_f32(SUMM_2[0], SUMM_2[1]);\n   SUMM_2[0] = vpadd_f32(SUMM_2[0], SUMM_2[0]);\n   /* Ok, now we have result accumulated in SUMM_2[0].0 */\n\n   if (len > 0) {\n      /* Case when you have one value left */\n      XX_2 = vld1_dup_f32(xi);\n      YY_2 = vld1_dup_f32(yi);\n      SUMM_2[0] = vmla_f32(SUMM_2[0], XX_2, YY_2);\n   }\n\n   vst1_lane_f32(sum, SUMM_2[0], 0);\n}\n\nvoid celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,\n                        opus_val32 *xcorr, int len, int max_pitch) {\n   int i;\n   celt_assert(max_pitch > 0);\n   celt_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);\n\n   for (i = 0; i < (max_pitch-3); i += 4) {\n      xcorr_kernel_neon_float((const float32_t *)_x, (const float32_t *)_y+i,\n            (float32_t *)xcorr+i, len);\n   }\n\n   /* In case max_pitch isn't multiple of 4\n    * compute single correlation value per iteration\n    */\n   for (; i < max_pitch; i++) {\n      xcorr_kernel_neon_float_process1((const float32_t *)_x,\n            (const float32_t *)_y+i, (float32_t *)xcorr+i, len);\n   }\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/celt_pitch_xcorr_arm-gnu.S",
    "content": "    .syntax unified\n@ Copyright (c) 2007-2008 CSIRO\n@ Copyright (c) 2007-2009 Xiph.Org Foundation\n@ Copyright (c) 2013      Parrot\n@ Written by Aurélien Zanelli\n@\n@ Redistribution and use in source and binary forms, with or without\n@ modification, are permitted provided that the following conditions\n@ are met:\n@\n@ - Redistributions of source code must retain the above copyright\n@ notice, this list of conditions and the following disclaimer.\n@\n@ - Redistributions in binary form must reproduce the above copyright\n@ notice, this list of conditions and the following disclaimer in the\n@ documentation and/or other materials provided with the distribution.\n@\n@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n@ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n@ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n@ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n@ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n@ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n@ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n@ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n    .text;   .p2align 2;   .arch armv7-a\n   .fpu neon\n   .object_arch armv4t\n\n  .include \"celt/arm/armopts-gnu.S\"\n\n .if OPUS_ARM_MAY_HAVE_EDSP\n  .global celt_pitch_xcorr_edsp\n .endif\n\n .if OPUS_ARM_MAY_HAVE_NEON\n  .global celt_pitch_xcorr_neon\n .endif\n\n .if OPUS_ARM_MAY_HAVE_NEON\n\n@ Compute sum[k]=sum(x[j]*y[j+k],j=0...len-1), k=0...3\n; xcorr_kernel_neon: @ PROC\nxcorr_kernel_neon_start:\n  @ input:\n  @   r3     = int         len\n  @   r4     = opus_val16 *x\n  @   r5     = opus_val16 *y\n  @   q0     = opus_val32  sum[4]\n  @ output:\n  @   q0     = opus_val32  sum[4]\n  @ preserved: r0-r3, r6-r11, d2, q4-q7, q9-q15\n  @ internal usage:\n  @   r12 = int j\n  @   d3  = y_3|y_2|y_1|y_0\n  @   q2  = y_B|y_A|y_9|y_8|y_7|y_6|y_5|y_4\n  @   q3  = x_7|x_6|x_5|x_4|x_3|x_2|x_1|x_0\n  @   q8  = scratch\n  @\n  @ Load y[0...3]\n  @ This requires len>0 to always be valid (which we assert in the C code).\n  VLD1.16      {d5}, [r5]!\n  SUBS         r12, r3, #8\n  BLE xcorr_kernel_neon_process4\n@ Process 8 samples at a time.\n@ This loop loads one y value more than we actually need. Therefore we have to\n@ stop as soon as there are 8 or fewer samples left (instead of 7), to avoid\n@ reading past the end of the array.\nxcorr_kernel_neon_process8:\n  @ This loop has 19 total instructions (10 cycles to issue, minimum), with\n  @ - 2 cycles of ARM insrtuctions,\n  @ - 10 cycles of load/store/byte permute instructions, and\n  @ - 9 cycles of data processing instructions.\n  @ On a Cortex A8, we dual-issue the maximum amount (9 cycles) between the\n  @ latter two categories, meaning the whole loop should run in 10 cycles per\n  @ iteration, barring cache misses.\n  @\n  @ Load x[0...7]\n  VLD1.16      {d6, d7}, [r4]!\n  @ Unlike VMOV, VAND is a data processsing instruction (and doesn't get\n  @ assembled to VMOV, like VORR would), so it dual-issues with the prior VLD1.\n  VAND         d3, d5, d5\n  SUBS         r12, r12, #8\n  @ Load y[4...11]\n  VLD1.16      {d4, d5}, [r5]!\n  VMLAL.S16    q0, d3, d6[0]\n  VEXT.16      d16, d3, d4, #1\n  VMLAL.S16    q0, d4, d7[0]\n  VEXT.16      d17, d4, d5, #1\n  VMLAL.S16    q0, d16, d6[1]\n  VEXT.16      d16, d3, d4, #2\n  VMLAL.S16    q0, d17, d7[1]\n  VEXT.16      d17, d4, d5, #2\n  VMLAL.S16    q0, d16, d6[2]\n  VEXT.16      d16, d3, d4, #3\n  VMLAL.S16    q0, d17, d7[2]\n  VEXT.16      d17, d4, d5, #3\n  VMLAL.S16    q0, d16, d6[3]\n  VMLAL.S16    q0, d17, d7[3]\n  BGT xcorr_kernel_neon_process8\n@ Process 4 samples here if we have > 4 left (still reading one extra y value).\nxcorr_kernel_neon_process4:\n  ADDS         r12, r12, #4\n  BLE xcorr_kernel_neon_process2\n  @ Load x[0...3]\n  VLD1.16      d6, [r4]!\n  @ Use VAND since it's a data processing instruction again.\n  VAND         d4, d5, d5\n  SUB          r12, r12, #4\n  @ Load y[4...7]\n  VLD1.16      d5, [r5]!\n  VMLAL.S16    q0, d4, d6[0]\n  VEXT.16      d16, d4, d5, #1\n  VMLAL.S16    q0, d16, d6[1]\n  VEXT.16      d16, d4, d5, #2\n  VMLAL.S16    q0, d16, d6[2]\n  VEXT.16      d16, d4, d5, #3\n  VMLAL.S16    q0, d16, d6[3]\n@ Process 2 samples here if we have > 2 left (still reading one extra y value).\nxcorr_kernel_neon_process2:\n  ADDS         r12, r12, #2\n  BLE xcorr_kernel_neon_process1\n  @ Load x[0...1]\n  VLD2.16      {d6[],d7[]}, [r4]!\n  @ Use VAND since it's a data processing instruction again.\n  VAND         d4, d5, d5\n  SUB          r12, r12, #2\n  @ Load y[4...5]\n  VLD1.32      {d5[]}, [r5]!\n  VMLAL.S16    q0, d4, d6\n  VEXT.16      d16, d4, d5, #1\n  @ Replace bottom copy of {y5,y4} in d5 with {y3,y2} from d4, using VSRI\n  @ instead of VEXT, since it's a data-processing instruction.\n  VSRI.64      d5, d4, #32\n  VMLAL.S16    q0, d16, d7\n@ Process 1 sample using the extra y value we loaded above.\nxcorr_kernel_neon_process1:\n  @ Load next *x\n  VLD1.16      {d6[]}, [r4]!\n  ADDS         r12, r12, #1\n  @ y[0...3] are left in d5 from prior iteration(s) (if any)\n  VMLAL.S16    q0, d5, d6\n  MOVLE        pc, lr\n@ Now process 1 last sample, not reading ahead.\n  @ Load last *y\n  VLD1.16      {d4[]}, [r5]!\n  VSRI.64      d4, d5, #16\n  @ Load last *x\n  VLD1.16      {d6[]}, [r4]!\n  VMLAL.S16    q0, d4, d6\n  MOV          pc, lr\n\t.size xcorr_kernel_neon, .-xcorr_kernel_neon  @ ENDP\n\n@ opus_val32 celt_pitch_xcorr_neon(opus_val16 *_x, opus_val16 *_y,\n@  opus_val32 *xcorr, int len, int max_pitch)\n; celt_pitch_xcorr_neon: @ PROC\n  @ input:\n  @   r0  = opus_val16 *_x\n  @   r1  = opus_val16 *_y\n  @   r2  = opus_val32 *xcorr\n  @   r3  = int         len\n  @ output:\n  @   r0  = int         maxcorr\n  @ internal usage:\n  @   r4  = opus_val16 *x (for xcorr_kernel_neon())\n  @   r5  = opus_val16 *y (for xcorr_kernel_neon())\n  @   r6  = int         max_pitch\n  @   r12 = int         j\n  @   q15 = int         maxcorr[4] (q15 is not used by xcorr_kernel_neon())\n  STMFD        sp!, {r4-r6, lr}\n  LDR          r6, [sp, #16]\n  VMOV.S32     q15, #1\n  @ if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done\n  SUBS         r6, r6, #4\n  BLT celt_pitch_xcorr_neon_process4_done\ncelt_pitch_xcorr_neon_process4:\n  @ xcorr_kernel_neon parameters:\n  @ r3 = len, r4 = _x, r5 = _y, q0 = {0, 0, 0, 0}\n  MOV          r4, r0\n  MOV          r5, r1\n  VEOR         q0, q0, q0\n  @ xcorr_kernel_neon only modifies r4, r5, r12, and q0...q3.\n  @ So we don't save/restore any other registers.\n  BL xcorr_kernel_neon_start\n  SUBS         r6, r6, #4\n  VST1.32      {q0}, [r2]!\n  @ _y += 4\n  ADD          r1, r1, #8\n  VMAX.S32     q15, q15, q0\n  @ if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done\n  BGE celt_pitch_xcorr_neon_process4\n@ We have less than 4 sums left to compute.\ncelt_pitch_xcorr_neon_process4_done:\n  ADDS         r6, r6, #4\n  @ Reduce maxcorr to a single value\n  VMAX.S32     d30, d30, d31\n  VPMAX.S32    d30, d30, d30\n  @ if (max_pitch <= 0) goto celt_pitch_xcorr_neon_done\n  BLE celt_pitch_xcorr_neon_done\n@ Now compute each remaining sum one at a time.\ncelt_pitch_xcorr_neon_process_remaining:\n  MOV          r4, r0\n  MOV          r5, r1\n  VMOV.I32     q0, #0\n  SUBS         r12, r3, #8\n  BLT celt_pitch_xcorr_neon_process_remaining4\n@ Sum terms 8 at a time.\ncelt_pitch_xcorr_neon_process_remaining_loop8:\n  @ Load x[0...7]\n  VLD1.16      {q1}, [r4]!\n  @ Load y[0...7]\n  VLD1.16      {q2}, [r5]!\n  SUBS         r12, r12, #8\n  VMLAL.S16    q0, d4, d2\n  VMLAL.S16    q0, d5, d3\n  BGE celt_pitch_xcorr_neon_process_remaining_loop8\n@ Sum terms 4 at a time.\ncelt_pitch_xcorr_neon_process_remaining4:\n  ADDS         r12, r12, #4\n  BLT celt_pitch_xcorr_neon_process_remaining4_done\n  @ Load x[0...3]\n  VLD1.16      {d2}, [r4]!\n  @ Load y[0...3]\n  VLD1.16      {d3}, [r5]!\n  SUB          r12, r12, #4\n  VMLAL.S16    q0, d3, d2\ncelt_pitch_xcorr_neon_process_remaining4_done:\n  @ Reduce the sum to a single value.\n  VADD.S32     d0, d0, d1\n  VPADDL.S32   d0, d0\n  ADDS         r12, r12, #4\n  BLE celt_pitch_xcorr_neon_process_remaining_loop_done\n@ Sum terms 1 at a time.\ncelt_pitch_xcorr_neon_process_remaining_loop1:\n  VLD1.16      {d2[]}, [r4]!\n  VLD1.16      {d3[]}, [r5]!\n  SUBS         r12, r12, #1\n  VMLAL.S16    q0, d2, d3\n  BGT celt_pitch_xcorr_neon_process_remaining_loop1\ncelt_pitch_xcorr_neon_process_remaining_loop_done:\n  VST1.32      {d0[0]}, [r2]!\n  VMAX.S32     d30, d30, d0\n  SUBS         r6, r6, #1\n  @ _y++\n  ADD          r1, r1, #2\n  @ if (--max_pitch > 0) goto celt_pitch_xcorr_neon_process_remaining\n  BGT celt_pitch_xcorr_neon_process_remaining\ncelt_pitch_xcorr_neon_done:\n  VMOV.32      r0, d30[0]\n  LDMFD        sp!, {r4-r6, pc}\n\t.size celt_pitch_xcorr_neon, .-celt_pitch_xcorr_neon  @ ENDP\n\n .endif\n\n .if OPUS_ARM_MAY_HAVE_EDSP\n\n@ This will get used on ARMv7 devices without NEON, so it has been optimized\n@ to take advantage of dual-issuing where possible.\n; xcorr_kernel_edsp: @ PROC\nxcorr_kernel_edsp_start:\n  @ input:\n  @   r3      = int         len\n  @   r4      = opus_val16 *_x (must be 32-bit aligned)\n  @   r5      = opus_val16 *_y (must be 32-bit aligned)\n  @   r6...r9 = opus_val32  sum[4]\n  @ output:\n  @   r6...r9 = opus_val32  sum[4]\n  @ preserved: r0-r5\n  @ internal usage\n  @   r2      = int         j\n  @   r12,r14 = opus_val16  x[4]\n  @   r10,r11 = opus_val16  y[4]\n  STMFD        sp!, {r2,r4,r5,lr}\n  LDR          r10, [r5], #4      @ Load y[0...1]\n  SUBS         r2, r3, #4         @ j = len-4\n  LDR          r11, [r5], #4      @ Load y[2...3]\n  BLE xcorr_kernel_edsp_process4_done\n  LDR          r12, [r4], #4      @ Load x[0...1]\n  @ Stall\nxcorr_kernel_edsp_process4:\n  @ The multiplies must issue from pipeline 0, and can't dual-issue with each\n  @ other. Every other instruction here dual-issues with a multiply, and is\n  @ thus \"free\". There should be no stalls in the body of the loop.\n  SMLABB       r6, r12, r10, r6   @ sum[0] = MAC16_16(sum[0],x_0,y_0)\n  LDR          r14, [r4], #4      @ Load x[2...3]\n  SMLABT       r7, r12, r10, r7   @ sum[1] = MAC16_16(sum[1],x_0,y_1)\n  SUBS         r2, r2, #4         @ j-=4\n  SMLABB       r8, r12, r11, r8   @ sum[2] = MAC16_16(sum[2],x_0,y_2)\n  SMLABT       r9, r12, r11, r9   @ sum[3] = MAC16_16(sum[3],x_0,y_3)\n  SMLATT       r6, r12, r10, r6   @ sum[0] = MAC16_16(sum[0],x_1,y_1)\n  LDR          r10, [r5], #4      @ Load y[4...5]\n  SMLATB       r7, r12, r11, r7   @ sum[1] = MAC16_16(sum[1],x_1,y_2)\n  SMLATT       r8, r12, r11, r8   @ sum[2] = MAC16_16(sum[2],x_1,y_3)\n  SMLATB       r9, r12, r10, r9   @ sum[3] = MAC16_16(sum[3],x_1,y_4)\n  LDRGT        r12, [r4], #4      @ Load x[0...1]\n  SMLABB       r6, r14, r11, r6   @ sum[0] = MAC16_16(sum[0],x_2,y_2)\n  SMLABT       r7, r14, r11, r7   @ sum[1] = MAC16_16(sum[1],x_2,y_3)\n  SMLABB       r8, r14, r10, r8   @ sum[2] = MAC16_16(sum[2],x_2,y_4)\n  SMLABT       r9, r14, r10, r9   @ sum[3] = MAC16_16(sum[3],x_2,y_5)\n  SMLATT       r6, r14, r11, r6   @ sum[0] = MAC16_16(sum[0],x_3,y_3)\n  LDR          r11, [r5], #4      @ Load y[6...7]\n  SMLATB       r7, r14, r10, r7   @ sum[1] = MAC16_16(sum[1],x_3,y_4)\n  SMLATT       r8, r14, r10, r8   @ sum[2] = MAC16_16(sum[2],x_3,y_5)\n  SMLATB       r9, r14, r11, r9   @ sum[3] = MAC16_16(sum[3],x_3,y_6)\n  BGT xcorr_kernel_edsp_process4\nxcorr_kernel_edsp_process4_done:\n  ADDS         r2, r2, #4\n  BLE xcorr_kernel_edsp_done\n  LDRH         r12, [r4], #2      @ r12 = *x++\n  SUBS         r2, r2, #1         @ j--\n  @ Stall\n  SMLABB       r6, r12, r10, r6   @ sum[0] = MAC16_16(sum[0],x,y_0)\n  LDRHGT       r14, [r4], #2      @ r14 = *x++\n  SMLABT       r7, r12, r10, r7   @ sum[1] = MAC16_16(sum[1],x,y_1)\n  SMLABB       r8, r12, r11, r8   @ sum[2] = MAC16_16(sum[2],x,y_2)\n  SMLABT       r9, r12, r11, r9   @ sum[3] = MAC16_16(sum[3],x,y_3)\n  BLE xcorr_kernel_edsp_done\n  SMLABT       r6, r14, r10, r6   @ sum[0] = MAC16_16(sum[0],x,y_1)\n  SUBS         r2, r2, #1         @ j--\n  SMLABB       r7, r14, r11, r7   @ sum[1] = MAC16_16(sum[1],x,y_2)\n  LDRH         r10, [r5], #2      @ r10 = y_4 = *y++\n  SMLABT       r8, r14, r11, r8   @ sum[2] = MAC16_16(sum[2],x,y_3)\n  LDRHGT       r12, [r4], #2      @ r12 = *x++\n  SMLABB       r9, r14, r10, r9   @ sum[3] = MAC16_16(sum[3],x,y_4)\n  BLE xcorr_kernel_edsp_done\n  SMLABB       r6, r12, r11, r6   @ sum[0] = MAC16_16(sum[0],tmp,y_2)\n  CMP          r2, #1             @ j--\n  SMLABT       r7, r12, r11, r7   @ sum[1] = MAC16_16(sum[1],tmp,y_3)\n  LDRH         r2, [r5], #2       @ r2 = y_5 = *y++\n  SMLABB       r8, r12, r10, r8   @ sum[2] = MAC16_16(sum[2],tmp,y_4)\n  LDRHGT       r14, [r4]          @ r14 = *x\n  SMLABB       r9, r12, r2, r9    @ sum[3] = MAC16_16(sum[3],tmp,y_5)\n  BLE xcorr_kernel_edsp_done\n  SMLABT       r6, r14, r11, r6   @ sum[0] = MAC16_16(sum[0],tmp,y_3)\n  LDRH         r11, [r5]          @ r11 = y_6 = *y\n  SMLABB       r7, r14, r10, r7   @ sum[1] = MAC16_16(sum[1],tmp,y_4)\n  SMLABB       r8, r14, r2, r8    @ sum[2] = MAC16_16(sum[2],tmp,y_5)\n  SMLABB       r9, r14, r11, r9   @ sum[3] = MAC16_16(sum[3],tmp,y_6)\nxcorr_kernel_edsp_done:\n  LDMFD        sp!, {r2,r4,r5,pc}\n\t.size xcorr_kernel_edsp, .-xcorr_kernel_edsp  @ ENDP\n\n; celt_pitch_xcorr_edsp: @ PROC\n  @ input:\n  @   r0  = opus_val16 *_x (must be 32-bit aligned)\n  @   r1  = opus_val16 *_y (only needs to be 16-bit aligned)\n  @   r2  = opus_val32 *xcorr\n  @   r3  = int         len\n  @ output:\n  @   r0  = maxcorr\n  @ internal usage\n  @   r4  = opus_val16 *x\n  @   r5  = opus_val16 *y\n  @   r6  = opus_val32  sum0\n  @   r7  = opus_val32  sum1\n  @   r8  = opus_val32  sum2\n  @   r9  = opus_val32  sum3\n  @   r1  = int         max_pitch\n  @   r12 = int         j\n  STMFD        sp!, {r4-r11, lr}\n  MOV          r5, r1\n  LDR          r1, [sp, #36]\n  MOV          r4, r0\n  TST          r5, #3\n  @ maxcorr = 1\n  MOV          r0, #1\n  BEQ          celt_pitch_xcorr_edsp_process1u_done\n@ Compute one sum at the start to make y 32-bit aligned.\n  SUBS         r12, r3, #4\n  @ r14 = sum = 0\n  MOV          r14, #0\n  LDRH         r8, [r5], #2\n  BLE celt_pitch_xcorr_edsp_process1u_loop4_done\n  LDR          r6, [r4], #4\n  MOV          r8, r8, LSL #16\ncelt_pitch_xcorr_edsp_process1u_loop4:\n  LDR          r9, [r5], #4\n  SMLABT       r14, r6, r8, r14     @ sum = MAC16_16(sum, x_0, y_0)\n  LDR          r7, [r4], #4\n  SMLATB       r14, r6, r9, r14     @ sum = MAC16_16(sum, x_1, y_1)\n  LDR          r8, [r5], #4\n  SMLABT       r14, r7, r9, r14     @ sum = MAC16_16(sum, x_2, y_2)\n  SUBS         r12, r12, #4         @ j-=4\n  SMLATB       r14, r7, r8, r14     @ sum = MAC16_16(sum, x_3, y_3)\n  LDRGT        r6, [r4], #4\n  BGT celt_pitch_xcorr_edsp_process1u_loop4\n  MOV          r8, r8, LSR #16\ncelt_pitch_xcorr_edsp_process1u_loop4_done:\n  ADDS         r12, r12, #4\ncelt_pitch_xcorr_edsp_process1u_loop1:\n  LDRHGE       r6, [r4], #2\n  @ Stall\n  SMLABBGE     r14, r6, r8, r14    @ sum = MAC16_16(sum, *x, *y)\n  SUBSGE       r12, r12, #1\n  LDRHGT       r8, [r5], #2\n  BGT celt_pitch_xcorr_edsp_process1u_loop1\n  @ Restore _x\n  SUB          r4, r4, r3, LSL #1\n  @ Restore and advance _y\n  SUB          r5, r5, r3, LSL #1\n  @ maxcorr = max(maxcorr, sum)\n  CMP          r0, r14\n  ADD          r5, r5, #2\n  MOVLT        r0, r14\n  SUBS         r1, r1, #1\n  @ xcorr[i] = sum\n  STR          r14, [r2], #4\n  BLE celt_pitch_xcorr_edsp_done\ncelt_pitch_xcorr_edsp_process1u_done:\n  @ if (max_pitch < 4) goto celt_pitch_xcorr_edsp_process2\n  SUBS         r1, r1, #4\n  BLT celt_pitch_xcorr_edsp_process2\ncelt_pitch_xcorr_edsp_process4:\n  @ xcorr_kernel_edsp parameters:\n  @ r3 = len, r4 = _x, r5 = _y, r6...r9 = sum[4] = {0, 0, 0, 0}\n  MOV          r6, #0\n  MOV          r7, #0\n  MOV          r8, #0\n  MOV          r9, #0\n  BL xcorr_kernel_edsp_start  @ xcorr_kernel_edsp(_x, _y+i, xcorr+i, len)\n  @ maxcorr = max(maxcorr, sum0, sum1, sum2, sum3)\n  CMP          r0, r6\n  @ _y+=4\n  ADD          r5, r5, #8\n  MOVLT        r0, r6\n  CMP          r0, r7\n  MOVLT        r0, r7\n  CMP          r0, r8\n  MOVLT        r0, r8\n  CMP          r0, r9\n  MOVLT        r0, r9\n  STMIA        r2!, {r6-r9}\n  SUBS         r1, r1, #4\n  BGE celt_pitch_xcorr_edsp_process4\ncelt_pitch_xcorr_edsp_process2:\n  ADDS         r1, r1, #2\n  BLT celt_pitch_xcorr_edsp_process1a\n  SUBS         r12, r3, #4\n  @ {r10, r11} = {sum0, sum1} = {0, 0}\n  MOV          r10, #0\n  MOV          r11, #0\n  LDR          r8, [r5], #4\n  BLE celt_pitch_xcorr_edsp_process2_loop_done\n  LDR          r6, [r4], #4\n  LDR          r9, [r5], #4\ncelt_pitch_xcorr_edsp_process2_loop4:\n  SMLABB       r10, r6, r8, r10     @ sum0 = MAC16_16(sum0, x_0, y_0)\n  LDR          r7, [r4], #4\n  SMLABT       r11, r6, r8, r11     @ sum1 = MAC16_16(sum1, x_0, y_1)\n  SUBS         r12, r12, #4         @ j-=4\n  SMLATT       r10, r6, r8, r10     @ sum0 = MAC16_16(sum0, x_1, y_1)\n  LDR          r8, [r5], #4\n  SMLATB       r11, r6, r9, r11     @ sum1 = MAC16_16(sum1, x_1, y_2)\n  LDRGT        r6, [r4], #4\n  SMLABB       r10, r7, r9, r10     @ sum0 = MAC16_16(sum0, x_2, y_2)\n  SMLABT       r11, r7, r9, r11     @ sum1 = MAC16_16(sum1, x_2, y_3)\n  SMLATT       r10, r7, r9, r10     @ sum0 = MAC16_16(sum0, x_3, y_3)\n  LDRGT        r9, [r5], #4\n  SMLATB       r11, r7, r8, r11     @ sum1 = MAC16_16(sum1, x_3, y_4)\n  BGT celt_pitch_xcorr_edsp_process2_loop4\ncelt_pitch_xcorr_edsp_process2_loop_done:\n  ADDS         r12, r12, #2\n  BLE  celt_pitch_xcorr_edsp_process2_1\n  LDR          r6, [r4], #4\n  @ Stall\n  SMLABB       r10, r6, r8, r10     @ sum0 = MAC16_16(sum0, x_0, y_0)\n  LDR          r9, [r5], #4\n  SMLABT       r11, r6, r8, r11     @ sum1 = MAC16_16(sum1, x_0, y_1)\n  SUB          r12, r12, #2\n  SMLATT       r10, r6, r8, r10     @ sum0 = MAC16_16(sum0, x_1, y_1)\n  MOV          r8, r9\n  SMLATB       r11, r6, r9, r11     @ sum1 = MAC16_16(sum1, x_1, y_2)\ncelt_pitch_xcorr_edsp_process2_1:\n  LDRH         r6, [r4], #2\n  ADDS         r12, r12, #1\n  @ Stall\n  SMLABB       r10, r6, r8, r10     @ sum0 = MAC16_16(sum0, x_0, y_0)\n  LDRHGT       r7, [r4], #2\n  SMLABT       r11, r6, r8, r11     @ sum1 = MAC16_16(sum1, x_0, y_1)\n  BLE celt_pitch_xcorr_edsp_process2_done\n  LDRH         r9, [r5], #2\n  SMLABT       r10, r7, r8, r10     @ sum0 = MAC16_16(sum0, x_0, y_1)\n  SMLABB       r11, r7, r9, r11     @ sum1 = MAC16_16(sum1, x_0, y_2)\ncelt_pitch_xcorr_edsp_process2_done:\n  @ Restore _x\n  SUB          r4, r4, r3, LSL #1\n  @ Restore and advance _y\n  SUB          r5, r5, r3, LSL #1\n  @ maxcorr = max(maxcorr, sum0)\n  CMP          r0, r10\n  ADD          r5, r5, #2\n  MOVLT        r0, r10\n  SUB          r1, r1, #2\n  @ maxcorr = max(maxcorr, sum1)\n  CMP          r0, r11\n  @ xcorr[i] = sum\n  STR          r10, [r2], #4\n  MOVLT        r0, r11\n  STR          r11, [r2], #4\ncelt_pitch_xcorr_edsp_process1a:\n  ADDS         r1, r1, #1\n  BLT celt_pitch_xcorr_edsp_done\n  SUBS         r12, r3, #4\n  @ r14 = sum = 0\n  MOV          r14, #0\n  BLT celt_pitch_xcorr_edsp_process1a_loop_done\n  LDR          r6, [r4], #4\n  LDR          r8, [r5], #4\n  LDR          r7, [r4], #4\n  LDR          r9, [r5], #4\ncelt_pitch_xcorr_edsp_process1a_loop4:\n  SMLABB       r14, r6, r8, r14     @ sum = MAC16_16(sum, x_0, y_0)\n  SUBS         r12, r12, #4         @ j-=4\n  SMLATT       r14, r6, r8, r14     @ sum = MAC16_16(sum, x_1, y_1)\n  LDRGE        r6, [r4], #4\n  SMLABB       r14, r7, r9, r14     @ sum = MAC16_16(sum, x_2, y_2)\n  LDRGE        r8, [r5], #4\n  SMLATT       r14, r7, r9, r14     @ sum = MAC16_16(sum, x_3, y_3)\n  LDRGE        r7, [r4], #4\n  LDRGE        r9, [r5], #4\n  BGE celt_pitch_xcorr_edsp_process1a_loop4\ncelt_pitch_xcorr_edsp_process1a_loop_done:\n  ADDS         r12, r12, #2\n  LDRGE        r6, [r4], #4\n  LDRGE        r8, [r5], #4\n  @ Stall\n  SMLABBGE     r14, r6, r8, r14     @ sum = MAC16_16(sum, x_0, y_0)\n  SUBGE        r12, r12, #2\n  SMLATTGE     r14, r6, r8, r14     @ sum = MAC16_16(sum, x_1, y_1)\n  ADDS         r12, r12, #1\n  LDRHGE       r6, [r4], #2\n  LDRHGE       r8, [r5], #2\n  @ Stall\n  SMLABBGE     r14, r6, r8, r14     @ sum = MAC16_16(sum, *x, *y)\n  @ maxcorr = max(maxcorr, sum)\n  CMP          r0, r14\n  @ xcorr[i] = sum\n  STR          r14, [r2], #4\n  MOVLT        r0, r14\ncelt_pitch_xcorr_edsp_done:\n  LDMFD        sp!, {r4-r11, pc}\n\t.size celt_pitch_xcorr_edsp, .-celt_pitch_xcorr_edsp  @ ENDP\n\n .endif\n\n@ END:\n    .section\t.note.GNU-stack,\"\",%progbits\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/celt_pitch_xcorr_arm.s",
    "content": "; Copyright (c) 2007-2008 CSIRO\n; Copyright (c) 2007-2009 Xiph.Org Foundation\n; Copyright (c) 2013      Parrot\n; Written by Aurélien Zanelli\n;\n; Redistribution and use in source and binary forms, with or without\n; modification, are permitted provided that the following conditions\n; are met:\n;\n; - Redistributions of source code must retain the above copyright\n; notice, this list of conditions and the following disclaimer.\n;\n; - Redistributions in binary form must reproduce the above copyright\n; notice, this list of conditions and the following disclaimer in the\n; documentation and/or other materials provided with the distribution.\n;\n; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n; OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n  AREA  |.text|, CODE, READONLY\n\n  GET    celt/arm/armopts.s\n\nIF OPUS_ARM_MAY_HAVE_EDSP\n  EXPORT celt_pitch_xcorr_edsp\nENDIF\n\nIF OPUS_ARM_MAY_HAVE_NEON\n  EXPORT celt_pitch_xcorr_neon\nENDIF\n\nIF OPUS_ARM_MAY_HAVE_NEON\n\n; Compute sum[k]=sum(x[j]*y[j+k],j=0...len-1), k=0...3\nxcorr_kernel_neon PROC\nxcorr_kernel_neon_start\n  ; input:\n  ;   r3     = int         len\n  ;   r4     = opus_val16 *x\n  ;   r5     = opus_val16 *y\n  ;   q0     = opus_val32  sum[4]\n  ; output:\n  ;   q0     = opus_val32  sum[4]\n  ; preserved: r0-r3, r6-r11, d2, q4-q7, q9-q15\n  ; internal usage:\n  ;   r12 = int j\n  ;   d3  = y_3|y_2|y_1|y_0\n  ;   q2  = y_B|y_A|y_9|y_8|y_7|y_6|y_5|y_4\n  ;   q3  = x_7|x_6|x_5|x_4|x_3|x_2|x_1|x_0\n  ;   q8  = scratch\n  ;\n  ; Load y[0...3]\n  ; This requires len>0 to always be valid (which we assert in the C code).\n  VLD1.16      {d5}, [r5]!\n  SUBS         r12, r3, #8\n  BLE xcorr_kernel_neon_process4\n; Process 8 samples at a time.\n; This loop loads one y value more than we actually need. Therefore we have to\n; stop as soon as there are 8 or fewer samples left (instead of 7), to avoid\n; reading past the end of the array.\nxcorr_kernel_neon_process8\n  ; This loop has 19 total instructions (10 cycles to issue, minimum), with\n  ; - 2 cycles of ARM insrtuctions,\n  ; - 10 cycles of load/store/byte permute instructions, and\n  ; - 9 cycles of data processing instructions.\n  ; On a Cortex A8, we dual-issue the maximum amount (9 cycles) between the\n  ; latter two categories, meaning the whole loop should run in 10 cycles per\n  ; iteration, barring cache misses.\n  ;\n  ; Load x[0...7]\n  VLD1.16      {d6, d7}, [r4]!\n  ; Unlike VMOV, VAND is a data processsing instruction (and doesn't get\n  ; assembled to VMOV, like VORR would), so it dual-issues with the prior VLD1.\n  VAND         d3, d5, d5\n  SUBS         r12, r12, #8\n  ; Load y[4...11]\n  VLD1.16      {d4, d5}, [r5]!\n  VMLAL.S16    q0, d3, d6[0]\n  VEXT.16      d16, d3, d4, #1\n  VMLAL.S16    q0, d4, d7[0]\n  VEXT.16      d17, d4, d5, #1\n  VMLAL.S16    q0, d16, d6[1]\n  VEXT.16      d16, d3, d4, #2\n  VMLAL.S16    q0, d17, d7[1]\n  VEXT.16      d17, d4, d5, #2\n  VMLAL.S16    q0, d16, d6[2]\n  VEXT.16      d16, d3, d4, #3\n  VMLAL.S16    q0, d17, d7[2]\n  VEXT.16      d17, d4, d5, #3\n  VMLAL.S16    q0, d16, d6[3]\n  VMLAL.S16    q0, d17, d7[3]\n  BGT xcorr_kernel_neon_process8\n; Process 4 samples here if we have > 4 left (still reading one extra y value).\nxcorr_kernel_neon_process4\n  ADDS         r12, r12, #4\n  BLE xcorr_kernel_neon_process2\n  ; Load x[0...3]\n  VLD1.16      d6, [r4]!\n  ; Use VAND since it's a data processing instruction again.\n  VAND         d4, d5, d5\n  SUB          r12, r12, #4\n  ; Load y[4...7]\n  VLD1.16      d5, [r5]!\n  VMLAL.S16    q0, d4, d6[0]\n  VEXT.16      d16, d4, d5, #1\n  VMLAL.S16    q0, d16, d6[1]\n  VEXT.16      d16, d4, d5, #2\n  VMLAL.S16    q0, d16, d6[2]\n  VEXT.16      d16, d4, d5, #3\n  VMLAL.S16    q0, d16, d6[3]\n; Process 2 samples here if we have > 2 left (still reading one extra y value).\nxcorr_kernel_neon_process2\n  ADDS         r12, r12, #2\n  BLE xcorr_kernel_neon_process1\n  ; Load x[0...1]\n  VLD2.16      {d6[],d7[]}, [r4]!\n  ; Use VAND since it's a data processing instruction again.\n  VAND         d4, d5, d5\n  SUB          r12, r12, #2\n  ; Load y[4...5]\n  VLD1.32      {d5[]}, [r5]!\n  VMLAL.S16    q0, d4, d6\n  VEXT.16      d16, d4, d5, #1\n  ; Replace bottom copy of {y5,y4} in d5 with {y3,y2} from d4, using VSRI\n  ; instead of VEXT, since it's a data-processing instruction.\n  VSRI.64      d5, d4, #32\n  VMLAL.S16    q0, d16, d7\n; Process 1 sample using the extra y value we loaded above.\nxcorr_kernel_neon_process1\n  ; Load next *x\n  VLD1.16      {d6[]}, [r4]!\n  ADDS         r12, r12, #1\n  ; y[0...3] are left in d5 from prior iteration(s) (if any)\n  VMLAL.S16    q0, d5, d6\n  MOVLE        pc, lr\n; Now process 1 last sample, not reading ahead.\n  ; Load last *y\n  VLD1.16      {d4[]}, [r5]!\n  VSRI.64      d4, d5, #16\n  ; Load last *x\n  VLD1.16      {d6[]}, [r4]!\n  VMLAL.S16    q0, d4, d6\n  MOV          pc, lr\n  ENDP\n\n; opus_val32 celt_pitch_xcorr_neon(opus_val16 *_x, opus_val16 *_y,\n;  opus_val32 *xcorr, int len, int max_pitch)\ncelt_pitch_xcorr_neon PROC\n  ; input:\n  ;   r0  = opus_val16 *_x\n  ;   r1  = opus_val16 *_y\n  ;   r2  = opus_val32 *xcorr\n  ;   r3  = int         len\n  ; output:\n  ;   r0  = int         maxcorr\n  ; internal usage:\n  ;   r4  = opus_val16 *x (for xcorr_kernel_neon())\n  ;   r5  = opus_val16 *y (for xcorr_kernel_neon())\n  ;   r6  = int         max_pitch\n  ;   r12 = int         j\n  ;   q15 = int         maxcorr[4] (q15 is not used by xcorr_kernel_neon())\n  STMFD        sp!, {r4-r6, lr}\n  LDR          r6, [sp, #16]\n  VMOV.S32     q15, #1\n  ; if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done\n  SUBS         r6, r6, #4\n  BLT celt_pitch_xcorr_neon_process4_done\ncelt_pitch_xcorr_neon_process4\n  ; xcorr_kernel_neon parameters:\n  ; r3 = len, r4 = _x, r5 = _y, q0 = {0, 0, 0, 0}\n  MOV          r4, r0\n  MOV          r5, r1\n  VEOR         q0, q0, q0\n  ; xcorr_kernel_neon only modifies r4, r5, r12, and q0...q3.\n  ; So we don't save/restore any other registers.\n  BL xcorr_kernel_neon_start\n  SUBS         r6, r6, #4\n  VST1.32      {q0}, [r2]!\n  ; _y += 4\n  ADD          r1, r1, #8\n  VMAX.S32     q15, q15, q0\n  ; if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done\n  BGE celt_pitch_xcorr_neon_process4\n; We have less than 4 sums left to compute.\ncelt_pitch_xcorr_neon_process4_done\n  ADDS         r6, r6, #4\n  ; Reduce maxcorr to a single value\n  VMAX.S32     d30, d30, d31\n  VPMAX.S32    d30, d30, d30\n  ; if (max_pitch <= 0) goto celt_pitch_xcorr_neon_done\n  BLE celt_pitch_xcorr_neon_done\n; Now compute each remaining sum one at a time.\ncelt_pitch_xcorr_neon_process_remaining\n  MOV          r4, r0\n  MOV          r5, r1\n  VMOV.I32     q0, #0\n  SUBS         r12, r3, #8\n  BLT celt_pitch_xcorr_neon_process_remaining4\n; Sum terms 8 at a time.\ncelt_pitch_xcorr_neon_process_remaining_loop8\n  ; Load x[0...7]\n  VLD1.16      {q1}, [r4]!\n  ; Load y[0...7]\n  VLD1.16      {q2}, [r5]!\n  SUBS         r12, r12, #8\n  VMLAL.S16    q0, d4, d2\n  VMLAL.S16    q0, d5, d3\n  BGE celt_pitch_xcorr_neon_process_remaining_loop8\n; Sum terms 4 at a time.\ncelt_pitch_xcorr_neon_process_remaining4\n  ADDS         r12, r12, #4\n  BLT celt_pitch_xcorr_neon_process_remaining4_done\n  ; Load x[0...3]\n  VLD1.16      {d2}, [r4]!\n  ; Load y[0...3]\n  VLD1.16      {d3}, [r5]!\n  SUB          r12, r12, #4\n  VMLAL.S16    q0, d3, d2\ncelt_pitch_xcorr_neon_process_remaining4_done\n  ; Reduce the sum to a single value.\n  VADD.S32     d0, d0, d1\n  VPADDL.S32   d0, d0\n  ADDS         r12, r12, #4\n  BLE celt_pitch_xcorr_neon_process_remaining_loop_done\n; Sum terms 1 at a time.\ncelt_pitch_xcorr_neon_process_remaining_loop1\n  VLD1.16      {d2[]}, [r4]!\n  VLD1.16      {d3[]}, [r5]!\n  SUBS         r12, r12, #1\n  VMLAL.S16    q0, d2, d3\n  BGT celt_pitch_xcorr_neon_process_remaining_loop1\ncelt_pitch_xcorr_neon_process_remaining_loop_done\n  VST1.32      {d0[0]}, [r2]!\n  VMAX.S32     d30, d30, d0\n  SUBS         r6, r6, #1\n  ; _y++\n  ADD          r1, r1, #2\n  ; if (--max_pitch > 0) goto celt_pitch_xcorr_neon_process_remaining\n  BGT celt_pitch_xcorr_neon_process_remaining\ncelt_pitch_xcorr_neon_done\n  VMOV.32      r0, d30[0]\n  LDMFD        sp!, {r4-r6, pc}\n  ENDP\n\nENDIF\n\nIF OPUS_ARM_MAY_HAVE_EDSP\n\n; This will get used on ARMv7 devices without NEON, so it has been optimized\n; to take advantage of dual-issuing where possible.\nxcorr_kernel_edsp PROC\nxcorr_kernel_edsp_start\n  ; input:\n  ;   r3      = int         len\n  ;   r4      = opus_val16 *_x (must be 32-bit aligned)\n  ;   r5      = opus_val16 *_y (must be 32-bit aligned)\n  ;   r6...r9 = opus_val32  sum[4]\n  ; output:\n  ;   r6...r9 = opus_val32  sum[4]\n  ; preserved: r0-r5\n  ; internal usage\n  ;   r2      = int         j\n  ;   r12,r14 = opus_val16  x[4]\n  ;   r10,r11 = opus_val16  y[4]\n  STMFD        sp!, {r2,r4,r5,lr}\n  LDR          r10, [r5], #4      ; Load y[0...1]\n  SUBS         r2, r3, #4         ; j = len-4\n  LDR          r11, [r5], #4      ; Load y[2...3]\n  BLE xcorr_kernel_edsp_process4_done\n  LDR          r12, [r4], #4      ; Load x[0...1]\n  ; Stall\nxcorr_kernel_edsp_process4\n  ; The multiplies must issue from pipeline 0, and can't dual-issue with each\n  ; other. Every other instruction here dual-issues with a multiply, and is\n  ; thus \"free\". There should be no stalls in the body of the loop.\n  SMLABB       r6, r12, r10, r6   ; sum[0] = MAC16_16(sum[0],x_0,y_0)\n  LDR          r14, [r4], #4      ; Load x[2...3]\n  SMLABT       r7, r12, r10, r7   ; sum[1] = MAC16_16(sum[1],x_0,y_1)\n  SUBS         r2, r2, #4         ; j-=4\n  SMLABB       r8, r12, r11, r8   ; sum[2] = MAC16_16(sum[2],x_0,y_2)\n  SMLABT       r9, r12, r11, r9   ; sum[3] = MAC16_16(sum[3],x_0,y_3)\n  SMLATT       r6, r12, r10, r6   ; sum[0] = MAC16_16(sum[0],x_1,y_1)\n  LDR          r10, [r5], #4      ; Load y[4...5]\n  SMLATB       r7, r12, r11, r7   ; sum[1] = MAC16_16(sum[1],x_1,y_2)\n  SMLATT       r8, r12, r11, r8   ; sum[2] = MAC16_16(sum[2],x_1,y_3)\n  SMLATB       r9, r12, r10, r9   ; sum[3] = MAC16_16(sum[3],x_1,y_4)\n  LDRGT        r12, [r4], #4      ; Load x[0...1]\n  SMLABB       r6, r14, r11, r6   ; sum[0] = MAC16_16(sum[0],x_2,y_2)\n  SMLABT       r7, r14, r11, r7   ; sum[1] = MAC16_16(sum[1],x_2,y_3)\n  SMLABB       r8, r14, r10, r8   ; sum[2] = MAC16_16(sum[2],x_2,y_4)\n  SMLABT       r9, r14, r10, r9   ; sum[3] = MAC16_16(sum[3],x_2,y_5)\n  SMLATT       r6, r14, r11, r6   ; sum[0] = MAC16_16(sum[0],x_3,y_3)\n  LDR          r11, [r5], #4      ; Load y[6...7]\n  SMLATB       r7, r14, r10, r7   ; sum[1] = MAC16_16(sum[1],x_3,y_4)\n  SMLATT       r8, r14, r10, r8   ; sum[2] = MAC16_16(sum[2],x_3,y_5)\n  SMLATB       r9, r14, r11, r9   ; sum[3] = MAC16_16(sum[3],x_3,y_6)\n  BGT xcorr_kernel_edsp_process4\nxcorr_kernel_edsp_process4_done\n  ADDS         r2, r2, #4\n  BLE xcorr_kernel_edsp_done\n  LDRH         r12, [r4], #2      ; r12 = *x++\n  SUBS         r2, r2, #1         ; j--\n  ; Stall\n  SMLABB       r6, r12, r10, r6   ; sum[0] = MAC16_16(sum[0],x,y_0)\n  LDRHGT       r14, [r4], #2      ; r14 = *x++\n  SMLABT       r7, r12, r10, r7   ; sum[1] = MAC16_16(sum[1],x,y_1)\n  SMLABB       r8, r12, r11, r8   ; sum[2] = MAC16_16(sum[2],x,y_2)\n  SMLABT       r9, r12, r11, r9   ; sum[3] = MAC16_16(sum[3],x,y_3)\n  BLE xcorr_kernel_edsp_done\n  SMLABT       r6, r14, r10, r6   ; sum[0] = MAC16_16(sum[0],x,y_1)\n  SUBS         r2, r2, #1         ; j--\n  SMLABB       r7, r14, r11, r7   ; sum[1] = MAC16_16(sum[1],x,y_2)\n  LDRH         r10, [r5], #2      ; r10 = y_4 = *y++\n  SMLABT       r8, r14, r11, r8   ; sum[2] = MAC16_16(sum[2],x,y_3)\n  LDRHGT       r12, [r4], #2      ; r12 = *x++\n  SMLABB       r9, r14, r10, r9   ; sum[3] = MAC16_16(sum[3],x,y_4)\n  BLE xcorr_kernel_edsp_done\n  SMLABB       r6, r12, r11, r6   ; sum[0] = MAC16_16(sum[0],tmp,y_2)\n  CMP          r2, #1             ; j--\n  SMLABT       r7, r12, r11, r7   ; sum[1] = MAC16_16(sum[1],tmp,y_3)\n  LDRH         r2, [r5], #2       ; r2 = y_5 = *y++\n  SMLABB       r8, r12, r10, r8   ; sum[2] = MAC16_16(sum[2],tmp,y_4)\n  LDRHGT       r14, [r4]          ; r14 = *x\n  SMLABB       r9, r12, r2, r9    ; sum[3] = MAC16_16(sum[3],tmp,y_5)\n  BLE xcorr_kernel_edsp_done\n  SMLABT       r6, r14, r11, r6   ; sum[0] = MAC16_16(sum[0],tmp,y_3)\n  LDRH         r11, [r5]          ; r11 = y_6 = *y\n  SMLABB       r7, r14, r10, r7   ; sum[1] = MAC16_16(sum[1],tmp,y_4)\n  SMLABB       r8, r14, r2, r8    ; sum[2] = MAC16_16(sum[2],tmp,y_5)\n  SMLABB       r9, r14, r11, r9   ; sum[3] = MAC16_16(sum[3],tmp,y_6)\nxcorr_kernel_edsp_done\n  LDMFD        sp!, {r2,r4,r5,pc}\n  ENDP\n\ncelt_pitch_xcorr_edsp PROC\n  ; input:\n  ;   r0  = opus_val16 *_x (must be 32-bit aligned)\n  ;   r1  = opus_val16 *_y (only needs to be 16-bit aligned)\n  ;   r2  = opus_val32 *xcorr\n  ;   r3  = int         len\n  ; output:\n  ;   r0  = maxcorr\n  ; internal usage\n  ;   r4  = opus_val16 *x\n  ;   r5  = opus_val16 *y\n  ;   r6  = opus_val32  sum0\n  ;   r7  = opus_val32  sum1\n  ;   r8  = opus_val32  sum2\n  ;   r9  = opus_val32  sum3\n  ;   r1  = int         max_pitch\n  ;   r12 = int         j\n  STMFD        sp!, {r4-r11, lr}\n  MOV          r5, r1\n  LDR          r1, [sp, #36]\n  MOV          r4, r0\n  TST          r5, #3\n  ; maxcorr = 1\n  MOV          r0, #1\n  BEQ          celt_pitch_xcorr_edsp_process1u_done\n; Compute one sum at the start to make y 32-bit aligned.\n  SUBS         r12, r3, #4\n  ; r14 = sum = 0\n  MOV          r14, #0\n  LDRH         r8, [r5], #2\n  BLE celt_pitch_xcorr_edsp_process1u_loop4_done\n  LDR          r6, [r4], #4\n  MOV          r8, r8, LSL #16\ncelt_pitch_xcorr_edsp_process1u_loop4\n  LDR          r9, [r5], #4\n  SMLABT       r14, r6, r8, r14     ; sum = MAC16_16(sum, x_0, y_0)\n  LDR          r7, [r4], #4\n  SMLATB       r14, r6, r9, r14     ; sum = MAC16_16(sum, x_1, y_1)\n  LDR          r8, [r5], #4\n  SMLABT       r14, r7, r9, r14     ; sum = MAC16_16(sum, x_2, y_2)\n  SUBS         r12, r12, #4         ; j-=4\n  SMLATB       r14, r7, r8, r14     ; sum = MAC16_16(sum, x_3, y_3)\n  LDRGT        r6, [r4], #4\n  BGT celt_pitch_xcorr_edsp_process1u_loop4\n  MOV          r8, r8, LSR #16\ncelt_pitch_xcorr_edsp_process1u_loop4_done\n  ADDS         r12, r12, #4\ncelt_pitch_xcorr_edsp_process1u_loop1\n  LDRHGE       r6, [r4], #2\n  ; Stall\n  SMLABBGE     r14, r6, r8, r14    ; sum = MAC16_16(sum, *x, *y)\n  SUBSGE       r12, r12, #1\n  LDRHGT       r8, [r5], #2\n  BGT celt_pitch_xcorr_edsp_process1u_loop1\n  ; Restore _x\n  SUB          r4, r4, r3, LSL #1\n  ; Restore and advance _y\n  SUB          r5, r5, r3, LSL #1\n  ; maxcorr = max(maxcorr, sum)\n  CMP          r0, r14\n  ADD          r5, r5, #2\n  MOVLT        r0, r14\n  SUBS         r1, r1, #1\n  ; xcorr[i] = sum\n  STR          r14, [r2], #4\n  BLE celt_pitch_xcorr_edsp_done\ncelt_pitch_xcorr_edsp_process1u_done\n  ; if (max_pitch < 4) goto celt_pitch_xcorr_edsp_process2\n  SUBS         r1, r1, #4\n  BLT celt_pitch_xcorr_edsp_process2\ncelt_pitch_xcorr_edsp_process4\n  ; xcorr_kernel_edsp parameters:\n  ; r3 = len, r4 = _x, r5 = _y, r6...r9 = sum[4] = {0, 0, 0, 0}\n  MOV          r6, #0\n  MOV          r7, #0\n  MOV          r8, #0\n  MOV          r9, #0\n  BL xcorr_kernel_edsp_start  ; xcorr_kernel_edsp(_x, _y+i, xcorr+i, len)\n  ; maxcorr = max(maxcorr, sum0, sum1, sum2, sum3)\n  CMP          r0, r6\n  ; _y+=4\n  ADD          r5, r5, #8\n  MOVLT        r0, r6\n  CMP          r0, r7\n  MOVLT        r0, r7\n  CMP          r0, r8\n  MOVLT        r0, r8\n  CMP          r0, r9\n  MOVLT        r0, r9\n  STMIA        r2!, {r6-r9}\n  SUBS         r1, r1, #4\n  BGE celt_pitch_xcorr_edsp_process4\ncelt_pitch_xcorr_edsp_process2\n  ADDS         r1, r1, #2\n  BLT celt_pitch_xcorr_edsp_process1a\n  SUBS         r12, r3, #4\n  ; {r10, r11} = {sum0, sum1} = {0, 0}\n  MOV          r10, #0\n  MOV          r11, #0\n  LDR          r8, [r5], #4\n  BLE celt_pitch_xcorr_edsp_process2_loop_done\n  LDR          r6, [r4], #4\n  LDR          r9, [r5], #4\ncelt_pitch_xcorr_edsp_process2_loop4\n  SMLABB       r10, r6, r8, r10     ; sum0 = MAC16_16(sum0, x_0, y_0)\n  LDR          r7, [r4], #4\n  SMLABT       r11, r6, r8, r11     ; sum1 = MAC16_16(sum1, x_0, y_1)\n  SUBS         r12, r12, #4         ; j-=4\n  SMLATT       r10, r6, r8, r10     ; sum0 = MAC16_16(sum0, x_1, y_1)\n  LDR          r8, [r5], #4\n  SMLATB       r11, r6, r9, r11     ; sum1 = MAC16_16(sum1, x_1, y_2)\n  LDRGT        r6, [r4], #4\n  SMLABB       r10, r7, r9, r10     ; sum0 = MAC16_16(sum0, x_2, y_2)\n  SMLABT       r11, r7, r9, r11     ; sum1 = MAC16_16(sum1, x_2, y_3)\n  SMLATT       r10, r7, r9, r10     ; sum0 = MAC16_16(sum0, x_3, y_3)\n  LDRGT        r9, [r5], #4\n  SMLATB       r11, r7, r8, r11     ; sum1 = MAC16_16(sum1, x_3, y_4)\n  BGT celt_pitch_xcorr_edsp_process2_loop4\ncelt_pitch_xcorr_edsp_process2_loop_done\n  ADDS         r12, r12, #2\n  BLE  celt_pitch_xcorr_edsp_process2_1\n  LDR          r6, [r4], #4\n  ; Stall\n  SMLABB       r10, r6, r8, r10     ; sum0 = MAC16_16(sum0, x_0, y_0)\n  LDR          r9, [r5], #4\n  SMLABT       r11, r6, r8, r11     ; sum1 = MAC16_16(sum1, x_0, y_1)\n  SUB          r12, r12, #2\n  SMLATT       r10, r6, r8, r10     ; sum0 = MAC16_16(sum0, x_1, y_1)\n  MOV          r8, r9\n  SMLATB       r11, r6, r9, r11     ; sum1 = MAC16_16(sum1, x_1, y_2)\ncelt_pitch_xcorr_edsp_process2_1\n  LDRH         r6, [r4], #2\n  ADDS         r12, r12, #1\n  ; Stall\n  SMLABB       r10, r6, r8, r10     ; sum0 = MAC16_16(sum0, x_0, y_0)\n  LDRHGT       r7, [r4], #2\n  SMLABT       r11, r6, r8, r11     ; sum1 = MAC16_16(sum1, x_0, y_1)\n  BLE celt_pitch_xcorr_edsp_process2_done\n  LDRH         r9, [r5], #2\n  SMLABT       r10, r7, r8, r10     ; sum0 = MAC16_16(sum0, x_0, y_1)\n  SMLABB       r11, r7, r9, r11     ; sum1 = MAC16_16(sum1, x_0, y_2)\ncelt_pitch_xcorr_edsp_process2_done\n  ; Restore _x\n  SUB          r4, r4, r3, LSL #1\n  ; Restore and advance _y\n  SUB          r5, r5, r3, LSL #1\n  ; maxcorr = max(maxcorr, sum0)\n  CMP          r0, r10\n  ADD          r5, r5, #2\n  MOVLT        r0, r10\n  SUB          r1, r1, #2\n  ; maxcorr = max(maxcorr, sum1)\n  CMP          r0, r11\n  ; xcorr[i] = sum\n  STR          r10, [r2], #4\n  MOVLT        r0, r11\n  STR          r11, [r2], #4\ncelt_pitch_xcorr_edsp_process1a\n  ADDS         r1, r1, #1\n  BLT celt_pitch_xcorr_edsp_done\n  SUBS         r12, r3, #4\n  ; r14 = sum = 0\n  MOV          r14, #0\n  BLT celt_pitch_xcorr_edsp_process1a_loop_done\n  LDR          r6, [r4], #4\n  LDR          r8, [r5], #4\n  LDR          r7, [r4], #4\n  LDR          r9, [r5], #4\ncelt_pitch_xcorr_edsp_process1a_loop4\n  SMLABB       r14, r6, r8, r14     ; sum = MAC16_16(sum, x_0, y_0)\n  SUBS         r12, r12, #4         ; j-=4\n  SMLATT       r14, r6, r8, r14     ; sum = MAC16_16(sum, x_1, y_1)\n  LDRGE        r6, [r4], #4\n  SMLABB       r14, r7, r9, r14     ; sum = MAC16_16(sum, x_2, y_2)\n  LDRGE        r8, [r5], #4\n  SMLATT       r14, r7, r9, r14     ; sum = MAC16_16(sum, x_3, y_3)\n  LDRGE        r7, [r4], #4\n  LDRGE        r9, [r5], #4\n  BGE celt_pitch_xcorr_edsp_process1a_loop4\ncelt_pitch_xcorr_edsp_process1a_loop_done\n  ADDS         r12, r12, #2\n  LDRGE        r6, [r4], #4\n  LDRGE        r8, [r5], #4\n  ; Stall\n  SMLABBGE     r14, r6, r8, r14     ; sum = MAC16_16(sum, x_0, y_0)\n  SUBGE        r12, r12, #2\n  SMLATTGE     r14, r6, r8, r14     ; sum = MAC16_16(sum, x_1, y_1)\n  ADDS         r12, r12, #1\n  LDRHGE       r6, [r4], #2\n  LDRHGE       r8, [r5], #2\n  ; Stall\n  SMLABBGE     r14, r6, r8, r14     ; sum = MAC16_16(sum, *x, *y)\n  ; maxcorr = max(maxcorr, sum)\n  CMP          r0, r14\n  ; xcorr[i] = sum\n  STR          r14, [r2], #4\n  MOVLT        r0, r14\ncelt_pitch_xcorr_edsp_done\n  LDMFD        sp!, {r4-r11, pc}\n  ENDP\n\nENDIF\n\nEND\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/fft_arm.h",
    "content": "/* Copyright (c) 2015 Xiph.Org Foundation\n   Written by Viswanath Puttagunta */\n/**\n   @file fft_arm.h\n   @brief ARM Neon Intrinsic optimizations for fft using NE10 library\n */\n\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\n#if !defined(FFT_ARM_H)\n#define FFT_ARM_H\n\n#include \"config.h\"\n#include \"kiss_fft.h\"\n\n#if defined(HAVE_ARM_NE10)\n\nint opus_fft_alloc_arm_neon(kiss_fft_state *st);\nvoid opus_fft_free_arm_neon(kiss_fft_state *st);\n\nvoid opus_fft_neon(const kiss_fft_state *st,\n                   const kiss_fft_cpx *fin,\n                   kiss_fft_cpx *fout);\n\nvoid opus_ifft_neon(const kiss_fft_state *st,\n                    const kiss_fft_cpx *fin,\n                    kiss_fft_cpx *fout);\n\n#if !defined(OPUS_HAVE_RTCD)\n#define OVERRIDE_OPUS_FFT (1)\n\n#define opus_fft_alloc_arch(_st, arch) \\\n   ((void)(arch), opus_fft_alloc_arm_neon(_st))\n\n#define opus_fft_free_arch(_st, arch) \\\n   ((void)(arch), opus_fft_free_arm_neon(_st))\n\n#define opus_fft(_st, _fin, _fout, arch) \\\n   ((void)(arch), opus_fft_neon(_st, _fin, _fout))\n\n#define opus_ifft(_st, _fin, _fout, arch) \\\n   ((void)(arch), opus_ifft_neon(_st, _fin, _fout))\n\n#endif /* OPUS_HAVE_RTCD */\n\n#endif /* HAVE_ARM_NE10 */\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/fixed_armv4.h",
    "content": "/* Copyright (C) 2013 Xiph.Org Foundation and contributors */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef FIXED_ARMv4_H\n#define FIXED_ARMv4_H\n\n/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */\n#undef MULT16_32_Q16\nstatic OPUS_INLINE opus_val32 MULT16_32_Q16_armv4(opus_val16 a, opus_val32 b)\n{\n  unsigned rd_lo;\n  int rd_hi;\n  __asm__(\n      \"#MULT16_32_Q16\\n\\t\"\n      \"smull %0, %1, %2, %3\\n\\t\"\n      : \"=&r\"(rd_lo), \"=&r\"(rd_hi)\n      : \"%r\"(b),\"r\"(a<<16)\n  );\n  return rd_hi;\n}\n#define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv4(a, b))\n\n\n/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */\n#undef MULT16_32_Q15\nstatic OPUS_INLINE opus_val32 MULT16_32_Q15_armv4(opus_val16 a, opus_val32 b)\n{\n  unsigned rd_lo;\n  int rd_hi;\n  __asm__(\n      \"#MULT16_32_Q15\\n\\t\"\n      \"smull %0, %1, %2, %3\\n\\t\"\n      : \"=&r\"(rd_lo), \"=&r\"(rd_hi)\n      : \"%r\"(b), \"r\"(a<<16)\n  );\n  /*We intentionally don't OR in the high bit of rd_lo for speed.*/\n  return rd_hi<<1;\n}\n#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv4(a, b))\n\n\n/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add.\n    b must fit in 31 bits.\n    Result fits in 32 bits. */\n#undef MAC16_32_Q15\n#define MAC16_32_Q15(c, a, b) ADD32(c, MULT16_32_Q15(a, b))\n\n/** 16x32 multiply, followed by a 16-bit shift right and 32-bit add.\n    Result fits in 32 bits. */\n#undef MAC16_32_Q16\n#define MAC16_32_Q16(c, a, b) ADD32(c, MULT16_32_Q16(a, b))\n\n/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */\n#undef MULT32_32_Q31\n#define MULT32_32_Q31(a,b) (opus_val32)((((opus_int64)(a)) * ((opus_int64)(b)))>>31)\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/fixed_armv5e.h",
    "content": "/* Copyright (C) 2007-2009 Xiph.Org Foundation\n   Copyright (C) 2003-2008 Jean-Marc Valin\n   Copyright (C) 2007-2008 CSIRO\n   Copyright (C) 2013      Parrot */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef FIXED_ARMv5E_H\n#define FIXED_ARMv5E_H\n\n#include \"fixed_armv4.h\"\n\n/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */\n#undef MULT16_32_Q16\nstatic OPUS_INLINE opus_val32 MULT16_32_Q16_armv5e(opus_val16 a, opus_val32 b)\n{\n  int res;\n  __asm__(\n      \"#MULT16_32_Q16\\n\\t\"\n      \"smulwb %0, %1, %2\\n\\t\"\n      : \"=r\"(res)\n      : \"r\"(b),\"r\"(a)\n  );\n  return res;\n}\n#define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv5e(a, b))\n\n\n/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */\n#undef MULT16_32_Q15\nstatic OPUS_INLINE opus_val32 MULT16_32_Q15_armv5e(opus_val16 a, opus_val32 b)\n{\n  int res;\n  __asm__(\n      \"#MULT16_32_Q15\\n\\t\"\n      \"smulwb %0, %1, %2\\n\\t\"\n      : \"=r\"(res)\n      : \"r\"(b), \"r\"(a)\n  );\n  return res<<1;\n}\n#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv5e(a, b))\n\n\n/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add.\n    b must fit in 31 bits.\n    Result fits in 32 bits. */\n#undef MAC16_32_Q15\nstatic OPUS_INLINE opus_val32 MAC16_32_Q15_armv5e(opus_val32 c, opus_val16 a,\n opus_val32 b)\n{\n  int res;\n  __asm__(\n      \"#MAC16_32_Q15\\n\\t\"\n      \"smlawb %0, %1, %2, %3;\\n\"\n      : \"=r\"(res)\n      : \"r\"(b<<1), \"r\"(a), \"r\"(c)\n  );\n  return res;\n}\n#define MAC16_32_Q15(c, a, b) (MAC16_32_Q15_armv5e(c, a, b))\n\n/** 16x32 multiply, followed by a 16-bit shift right and 32-bit add.\n    Result fits in 32 bits. */\n#undef MAC16_32_Q16\nstatic OPUS_INLINE opus_val32 MAC16_32_Q16_armv5e(opus_val32 c, opus_val16 a,\n opus_val32 b)\n{\n  int res;\n  __asm__(\n      \"#MAC16_32_Q16\\n\\t\"\n      \"smlawb %0, %1, %2, %3;\\n\"\n      : \"=r\"(res)\n      : \"r\"(b), \"r\"(a), \"r\"(c)\n  );\n  return res;\n}\n#define MAC16_32_Q16(c, a, b) (MAC16_32_Q16_armv5e(c, a, b))\n\n/** 16x16 multiply-add where the result fits in 32 bits */\n#undef MAC16_16\nstatic OPUS_INLINE opus_val32 MAC16_16_armv5e(opus_val32 c, opus_val16 a,\n opus_val16 b)\n{\n  int res;\n  __asm__(\n      \"#MAC16_16\\n\\t\"\n      \"smlabb %0, %1, %2, %3;\\n\"\n      : \"=r\"(res)\n      : \"r\"(a), \"r\"(b), \"r\"(c)\n  );\n  return res;\n}\n#define MAC16_16(c, a, b) (MAC16_16_armv5e(c, a, b))\n\n/** 16x16 multiplication where the result fits in 32 bits */\n#undef MULT16_16\nstatic OPUS_INLINE opus_val32 MULT16_16_armv5e(opus_val16 a, opus_val16 b)\n{\n  int res;\n  __asm__(\n      \"#MULT16_16\\n\\t\"\n      \"smulbb %0, %1, %2;\\n\"\n      : \"=r\"(res)\n      : \"r\"(a), \"r\"(b)\n  );\n  return res;\n}\n#define MULT16_16(a, b) (MULT16_16_armv5e(a, b))\n\n#ifdef OPUS_ARM_INLINE_MEDIA\n\n#undef SIG2WORD16\nstatic OPUS_INLINE opus_val16 SIG2WORD16_armv6(opus_val32 x)\n{\n   celt_sig res;\n   __asm__(\n       \"#SIG2WORD16\\n\\t\"\n       \"ssat %0, #16, %1, ASR #12\\n\\t\"\n       : \"=r\"(res)\n       : \"r\"(x+2048)\n   );\n   return EXTRACT16(res);\n}\n#define SIG2WORD16(x) (SIG2WORD16_armv6(x))\n\n#endif /* OPUS_ARM_INLINE_MEDIA */\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/kiss_fft_armv4.h",
    "content": "/*Copyright (c) 2013, Xiph.Org Foundation and contributors.\n\n  All rights reserved.\n\n  Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n       this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright notice,\n       this list of conditions and the following disclaimer in the\n       documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n  POSSIBILITY OF SUCH DAMAGE.*/\n\n#ifndef KISS_FFT_ARMv4_H\n#define KISS_FFT_ARMv4_H\n\n#if !defined(KISS_FFT_GUTS_H)\n#error \"This file should only be included from _kiss_fft_guts.h\"\n#endif\n\n#ifdef FIXED_POINT\n\n#undef C_MUL\n#define C_MUL(m,a,b) \\\n    do{ \\\n       int br__; \\\n       int bi__; \\\n       int tt__; \\\n        __asm__ __volatile__( \\\n            \"#C_MUL\\n\\t\" \\\n            \"ldrsh %[br], [%[bp], #0]\\n\\t\" \\\n            \"ldm %[ap], {r0,r1}\\n\\t\" \\\n            \"ldrsh %[bi], [%[bp], #2]\\n\\t\" \\\n            \"smull %[tt], %[mi], r1, %[br]\\n\\t\" \\\n            \"smlal %[tt], %[mi], r0, %[bi]\\n\\t\" \\\n            \"rsb %[bi], %[bi], #0\\n\\t\" \\\n            \"smull %[br], %[mr], r0, %[br]\\n\\t\" \\\n            \"mov %[tt], %[tt], lsr #15\\n\\t\" \\\n            \"smlal %[br], %[mr], r1, %[bi]\\n\\t\" \\\n            \"orr %[mi], %[tt], %[mi], lsl #17\\n\\t\" \\\n            \"mov %[br], %[br], lsr #15\\n\\t\" \\\n            \"orr %[mr], %[br], %[mr], lsl #17\\n\\t\" \\\n            : [mr]\"=r\"((m).r), [mi]\"=r\"((m).i), \\\n              [br]\"=&r\"(br__), [bi]\"=r\"(bi__), [tt]\"=r\"(tt__) \\\n            : [ap]\"r\"(&(a)), [bp]\"r\"(&(b)) \\\n            : \"r0\", \"r1\" \\\n        ); \\\n    } \\\n    while(0)\n\n#undef C_MUL4\n#define C_MUL4(m,a,b) \\\n    do{ \\\n       int br__; \\\n       int bi__; \\\n       int tt__; \\\n        __asm__ __volatile__( \\\n            \"#C_MUL4\\n\\t\" \\\n            \"ldrsh %[br], [%[bp], #0]\\n\\t\" \\\n            \"ldm %[ap], {r0,r1}\\n\\t\" \\\n            \"ldrsh %[bi], [%[bp], #2]\\n\\t\" \\\n            \"smull %[tt], %[mi], r1, %[br]\\n\\t\" \\\n            \"smlal %[tt], %[mi], r0, %[bi]\\n\\t\" \\\n            \"rsb %[bi], %[bi], #0\\n\\t\" \\\n            \"smull %[br], %[mr], r0, %[br]\\n\\t\" \\\n            \"mov %[tt], %[tt], lsr #17\\n\\t\" \\\n            \"smlal %[br], %[mr], r1, %[bi]\\n\\t\" \\\n            \"orr %[mi], %[tt], %[mi], lsl #15\\n\\t\" \\\n            \"mov %[br], %[br], lsr #17\\n\\t\" \\\n            \"orr %[mr], %[br], %[mr], lsl #15\\n\\t\" \\\n            : [mr]\"=r\"((m).r), [mi]\"=r\"((m).i), \\\n              [br]\"=&r\"(br__), [bi]\"=r\"(bi__), [tt]\"=r\"(tt__) \\\n            : [ap]\"r\"(&(a)), [bp]\"r\"(&(b)) \\\n            : \"r0\", \"r1\" \\\n        ); \\\n    } \\\n    while(0)\n\n#undef C_MULC\n#define C_MULC(m,a,b) \\\n    do{ \\\n       int br__; \\\n       int bi__; \\\n       int tt__; \\\n        __asm__ __volatile__( \\\n            \"#C_MULC\\n\\t\" \\\n            \"ldrsh %[br], [%[bp], #0]\\n\\t\" \\\n            \"ldm %[ap], {r0,r1}\\n\\t\" \\\n            \"ldrsh %[bi], [%[bp], #2]\\n\\t\" \\\n            \"smull %[tt], %[mr], r0, %[br]\\n\\t\" \\\n            \"smlal %[tt], %[mr], r1, %[bi]\\n\\t\" \\\n            \"rsb %[bi], %[bi], #0\\n\\t\" \\\n            \"smull %[br], %[mi], r1, %[br]\\n\\t\" \\\n            \"mov %[tt], %[tt], lsr #15\\n\\t\" \\\n            \"smlal %[br], %[mi], r0, %[bi]\\n\\t\" \\\n            \"orr %[mr], %[tt], %[mr], lsl #17\\n\\t\" \\\n            \"mov %[br], %[br], lsr #15\\n\\t\" \\\n            \"orr %[mi], %[br], %[mi], lsl #17\\n\\t\" \\\n            : [mr]\"=r\"((m).r), [mi]\"=r\"((m).i), \\\n              [br]\"=&r\"(br__), [bi]\"=r\"(bi__), [tt]\"=r\"(tt__) \\\n            : [ap]\"r\"(&(a)), [bp]\"r\"(&(b)) \\\n            : \"r0\", \"r1\" \\\n        ); \\\n    } \\\n    while(0)\n\n#endif /* FIXED_POINT */\n\n#endif /* KISS_FFT_ARMv4_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/kiss_fft_armv5e.h",
    "content": "/*Copyright (c) 2013, Xiph.Org Foundation and contributors.\n\n  All rights reserved.\n\n  Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n       this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright notice,\n       this list of conditions and the following disclaimer in the\n       documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n  POSSIBILITY OF SUCH DAMAGE.*/\n\n#ifndef KISS_FFT_ARMv5E_H\n#define KISS_FFT_ARMv5E_H\n\n#if !defined(KISS_FFT_GUTS_H)\n#error \"This file should only be included from _kiss_fft_guts.h\"\n#endif\n\n#ifdef FIXED_POINT\n\n#if defined(__thumb__)||defined(__thumb2__)\n#define LDRD_CONS \"Q\"\n#else\n#define LDRD_CONS \"Uq\"\n#endif\n\n#undef C_MUL\n#define C_MUL(m,a,b) \\\n    do{ \\\n        int mr1__; \\\n        int mr2__; \\\n        int mi__; \\\n        long long aval__; \\\n        int bval__; \\\n        __asm__( \\\n            \"#C_MUL\\n\\t\" \\\n            \"ldrd %[aval], %H[aval], %[ap]\\n\\t\" \\\n            \"ldr %[bval], %[bp]\\n\\t\" \\\n            \"smulwb %[mi], %H[aval], %[bval]\\n\\t\" \\\n            \"smulwb %[mr1], %[aval], %[bval]\\n\\t\" \\\n            \"smulwt %[mr2], %H[aval], %[bval]\\n\\t\" \\\n            \"smlawt %[mi], %[aval], %[bval], %[mi]\\n\\t\" \\\n            : [mr1]\"=r\"(mr1__), [mr2]\"=r\"(mr2__), [mi]\"=r\"(mi__), \\\n              [aval]\"=&r\"(aval__), [bval]\"=r\"(bval__) \\\n            : [ap]LDRD_CONS(a), [bp]\"m\"(b) \\\n        ); \\\n        (m).r = SHL32(SUB32(mr1__, mr2__), 1); \\\n        (m).i = SHL32(mi__, 1); \\\n    } \\\n    while(0)\n\n#undef C_MUL4\n#define C_MUL4(m,a,b) \\\n    do{ \\\n        int mr1__; \\\n        int mr2__; \\\n        int mi__; \\\n        long long aval__; \\\n        int bval__; \\\n        __asm__( \\\n            \"#C_MUL4\\n\\t\" \\\n            \"ldrd %[aval], %H[aval], %[ap]\\n\\t\" \\\n            \"ldr %[bval], %[bp]\\n\\t\" \\\n            \"smulwb %[mi], %H[aval], %[bval]\\n\\t\" \\\n            \"smulwb %[mr1], %[aval], %[bval]\\n\\t\" \\\n            \"smulwt %[mr2], %H[aval], %[bval]\\n\\t\" \\\n            \"smlawt %[mi], %[aval], %[bval], %[mi]\\n\\t\" \\\n            : [mr1]\"=r\"(mr1__), [mr2]\"=r\"(mr2__), [mi]\"=r\"(mi__), \\\n              [aval]\"=&r\"(aval__), [bval]\"=r\"(bval__) \\\n            : [ap]LDRD_CONS(a), [bp]\"m\"(b) \\\n        ); \\\n        (m).r = SHR32(SUB32(mr1__, mr2__), 1); \\\n        (m).i = SHR32(mi__, 1); \\\n    } \\\n    while(0)\n\n#undef C_MULC\n#define C_MULC(m,a,b) \\\n    do{ \\\n        int mr__; \\\n        int mi1__; \\\n        int mi2__; \\\n        long long aval__; \\\n        int bval__; \\\n        __asm__( \\\n            \"#C_MULC\\n\\t\" \\\n            \"ldrd %[aval], %H[aval], %[ap]\\n\\t\" \\\n            \"ldr %[bval], %[bp]\\n\\t\" \\\n            \"smulwb %[mr], %[aval], %[bval]\\n\\t\" \\\n            \"smulwb %[mi1], %H[aval], %[bval]\\n\\t\" \\\n            \"smulwt %[mi2], %[aval], %[bval]\\n\\t\" \\\n            \"smlawt %[mr], %H[aval], %[bval], %[mr]\\n\\t\" \\\n            : [mr]\"=r\"(mr__), [mi1]\"=r\"(mi1__), [mi2]\"=r\"(mi2__), \\\n              [aval]\"=&r\"(aval__), [bval]\"=r\"(bval__) \\\n            : [ap]LDRD_CONS(a), [bp]\"m\"(b) \\\n        ); \\\n        (m).r = SHL32(mr__, 1); \\\n        (m).i = SHL32(SUB32(mi1__, mi2__), 1); \\\n    } \\\n    while(0)\n\n#endif /* FIXED_POINT */\n\n#endif /* KISS_FFT_GUTS_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/mdct_arm.h",
    "content": "/* Copyright (c) 2015 Xiph.Org Foundation\n   Written by Viswanath Puttagunta */\n/**\n   @file arm_mdct.h\n   @brief ARM Neon Intrinsic optimizations for mdct using NE10 library\n */\n\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#if !defined(MDCT_ARM_H)\n#define MDCT_ARM_H\n\n#include \"config.h\"\n#include \"mdct.h\"\n\n#if defined(HAVE_ARM_NE10)\n/** Compute a forward MDCT and scale by 4/N, trashes the input array */\nvoid clt_mdct_forward_neon(const mdct_lookup *l, kiss_fft_scalar *in,\n                           kiss_fft_scalar * OPUS_RESTRICT out,\n                           const opus_val16 *window, int overlap,\n                           int shift, int stride, int arch);\n\nvoid clt_mdct_backward_neon(const mdct_lookup *l, kiss_fft_scalar *in,\n                            kiss_fft_scalar * OPUS_RESTRICT out,\n                            const opus_val16 *window, int overlap,\n                            int shift, int stride, int arch);\n\n#if !defined(OPUS_HAVE_RTCD)\n#define OVERRIDE_OPUS_MDCT (1)\n#define clt_mdct_forward(_l, _in, _out, _window, _int, _shift, _stride, _arch) \\\n      clt_mdct_forward_neon(_l, _in, _out, _window, _int, _shift, _stride, _arch)\n#define clt_mdct_backward(_l, _in, _out, _window, _int, _shift, _stride, _arch) \\\n      clt_mdct_backward_neon(_l, _in, _out, _window, _int, _shift, _stride, _arch)\n#endif /* OPUS_HAVE_RTCD */\n#endif /* HAVE_ARM_NE10 */\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/arm/pitch_arm.h",
    "content": "/* Copyright (c) 2010 Xiph.Org Foundation\n * Copyright (c) 2013 Parrot */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#if !defined(PITCH_ARM_H)\n# define PITCH_ARM_H\n\n# include \"armcpu.h\"\n\n# if defined(FIXED_POINT)\n\n#  if defined(OPUS_ARM_MAY_HAVE_NEON)\nopus_val32 celt_pitch_xcorr_neon(const opus_val16 *_x, const opus_val16 *_y,\n    opus_val32 *xcorr, int len, int max_pitch);\n#  endif\n\n#  if defined(OPUS_ARM_MAY_HAVE_MEDIA)\n#   define celt_pitch_xcorr_media MAY_HAVE_EDSP(celt_pitch_xcorr)\n#  endif\n\n#  if defined(OPUS_ARM_MAY_HAVE_EDSP)\nopus_val32 celt_pitch_xcorr_edsp(const opus_val16 *_x, const opus_val16 *_y,\n    opus_val32 *xcorr, int len, int max_pitch);\n#  endif\n\n#  if !defined(OPUS_HAVE_RTCD)\n#   define OVERRIDE_PITCH_XCORR (1)\n#   define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \\\n  ((void)(arch),PRESUME_NEON(celt_pitch_xcorr)(_x, _y, xcorr, len, max_pitch))\n#  endif\n\n#else /* Start !FIXED_POINT */\n/* Float case */\n#if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\nvoid celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,\n                                 opus_val32 *xcorr, int len, int max_pitch);\n#if !defined(OPUS_HAVE_RTCD) || defined(OPUS_ARM_PRESUME_NEON_INTR)\n#define OVERRIDE_PITCH_XCORR (1)\n#   define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \\\n   ((void)(arch),celt_pitch_xcorr_float_neon(_x, _y, xcorr, len, max_pitch))\n#endif\n#endif\n\n#endif /* end !FIXED_POINT */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/bands.c",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Copyright (c) 2008-2009 Gregory Maxwell\n   Written by Jean-Marc Valin and Gregory Maxwell */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <math.h>\n#include \"bands.h\"\n#include \"modes.h\"\n#include \"vq.h\"\n#include \"cwrs.h\"\n#include \"stack_alloc.h\"\n#include \"os_support.h\"\n#include \"mathops.h\"\n#include \"rate.h\"\n#include \"quant_bands.h\"\n#include \"pitch.h\"\n\nint hysteresis_decision(opus_val16 val, const opus_val16 *thresholds, const opus_val16 *hysteresis, int N, int prev)\n{\n   int i;\n   for (i=0;i<N;i++)\n   {\n      if (val < thresholds[i])\n         break;\n   }\n   if (i>prev && val < thresholds[prev]+hysteresis[prev])\n      i=prev;\n   if (i<prev && val > thresholds[prev-1]-hysteresis[prev-1])\n      i=prev;\n   return i;\n}\n\nopus_uint32 celt_lcg_rand(opus_uint32 seed)\n{\n   return 1664525 * seed + 1013904223;\n}\n\n/* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness\n   with this approximation is important because it has an impact on the bit allocation */\nstatic opus_int16 bitexact_cos(opus_int16 x)\n{\n   opus_int32 tmp;\n   opus_int16 x2;\n   tmp = (4096+((opus_int32)(x)*(x)))>>13;\n   celt_assert(tmp<=32767);\n   x2 = tmp;\n   x2 = (32767-x2) + FRAC_MUL16(x2, (-7651 + FRAC_MUL16(x2, (8277 + FRAC_MUL16(-626, x2)))));\n   celt_assert(x2<=32766);\n   return 1+x2;\n}\n\nstatic int bitexact_log2tan(int isin,int icos)\n{\n   int lc;\n   int ls;\n   lc=EC_ILOG(icos);\n   ls=EC_ILOG(isin);\n   icos<<=15-lc;\n   isin<<=15-ls;\n   return (ls-lc)*(1<<11)\n         +FRAC_MUL16(isin, FRAC_MUL16(isin, -2597) + 7932)\n         -FRAC_MUL16(icos, FRAC_MUL16(icos, -2597) + 7932);\n}\n\n#ifdef FIXED_POINT\n/* Compute the amplitude (sqrt energy) in each of the bands */\nvoid compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM)\n{\n   int i, c, N;\n   const opus_int16 *eBands = m->eBands;\n   N = m->shortMdctSize<<LM;\n   c=0; do {\n      for (i=0;i<end;i++)\n      {\n         int j;\n         opus_val32 maxval=0;\n         opus_val32 sum = 0;\n\n         maxval = celt_maxabs32(&X[c*N+(eBands[i]<<LM)], (eBands[i+1]-eBands[i])<<LM);\n         if (maxval > 0)\n         {\n            int shift = celt_ilog2(maxval) - 14 + (((m->logN[i]>>BITRES)+LM+1)>>1);\n            j=eBands[i]<<LM;\n            if (shift>0)\n            {\n               do {\n                  sum = MAC16_16(sum, EXTRACT16(SHR32(X[j+c*N],shift)),\n                        EXTRACT16(SHR32(X[j+c*N],shift)));\n               } while (++j<eBands[i+1]<<LM);\n            } else {\n               do {\n                  sum = MAC16_16(sum, EXTRACT16(SHL32(X[j+c*N],-shift)),\n                        EXTRACT16(SHL32(X[j+c*N],-shift)));\n               } while (++j<eBands[i+1]<<LM);\n            }\n            /* We're adding one here to ensure the normalized band isn't larger than unity norm */\n            bandE[i+c*m->nbEBands] = EPSILON+VSHR32(EXTEND32(celt_sqrt(sum)),-shift);\n         } else {\n            bandE[i+c*m->nbEBands] = EPSILON;\n         }\n         /*printf (\"%f \", bandE[i+c*m->nbEBands]);*/\n      }\n   } while (++c<C);\n   /*printf (\"\\n\");*/\n}\n\n/* Normalise each band such that the energy is one. */\nvoid normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M)\n{\n   int i, c, N;\n   const opus_int16 *eBands = m->eBands;\n   N = M*m->shortMdctSize;\n   c=0; do {\n      i=0; do {\n         opus_val16 g;\n         int j,shift;\n         opus_val16 E;\n         shift = celt_zlog2(bandE[i+c*m->nbEBands])-13;\n         E = VSHR32(bandE[i+c*m->nbEBands], shift);\n         g = EXTRACT16(celt_rcp(SHL32(E,3)));\n         j=M*eBands[i]; do {\n            X[j+c*N] = MULT16_16_Q15(VSHR32(freq[j+c*N],shift-1),g);\n         } while (++j<M*eBands[i+1]);\n      } while (++i<end);\n   } while (++c<C);\n}\n\n#else /* FIXED_POINT */\n/* Compute the amplitude (sqrt energy) in each of the bands */\nvoid compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM)\n{\n   int i, c, N;\n   const opus_int16 *eBands = m->eBands;\n   N = m->shortMdctSize<<LM;\n   c=0; do {\n      for (i=0;i<end;i++)\n      {\n         opus_val32 sum;\n         sum = 1e-27f + celt_inner_prod_c(&X[c*N+(eBands[i]<<LM)], &X[c*N+(eBands[i]<<LM)], (eBands[i+1]-eBands[i])<<LM);\n         bandE[i+c*m->nbEBands] = celt_sqrt(sum);\n         /*printf (\"%f \", bandE[i+c*m->nbEBands]);*/\n      }\n   } while (++c<C);\n   /*printf (\"\\n\");*/\n}\n\n/* Normalise each band such that the energy is one. */\nvoid normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M)\n{\n   int i, c, N;\n   const opus_int16 *eBands = m->eBands;\n   N = M*m->shortMdctSize;\n   c=0; do {\n      for (i=0;i<end;i++)\n      {\n         int j;\n         opus_val16 g = 1.f/(1e-27f+bandE[i+c*m->nbEBands]);\n         for (j=M*eBands[i];j<M*eBands[i+1];j++)\n            X[j+c*N] = freq[j+c*N]*g;\n      }\n   } while (++c<C);\n}\n\n#endif /* FIXED_POINT */\n\n/* De-normalise the energy to produce the synthesis from the unit-energy bands */\nvoid denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,\n      celt_sig * OPUS_RESTRICT freq, const opus_val16 *bandLogE, int start,\n      int end, int M, int downsample, int silence)\n{\n   int i, N;\n   int bound;\n   celt_sig * OPUS_RESTRICT f;\n   const celt_norm * OPUS_RESTRICT x;\n   const opus_int16 *eBands = m->eBands;\n   N = M*m->shortMdctSize;\n   bound = M*eBands[end];\n   if (downsample!=1)\n      bound = IMIN(bound, N/downsample);\n   if (silence)\n   {\n      bound = 0;\n      start = end = 0;\n   }\n   f = freq;\n   x = X+M*eBands[start];\n   for (i=0;i<M*eBands[start];i++)\n      *f++ = 0;\n   for (i=start;i<end;i++)\n   {\n      int j, band_end;\n      opus_val16 g;\n      opus_val16 lg;\n#ifdef FIXED_POINT\n      int shift;\n#endif\n      j=M*eBands[i];\n      band_end = M*eBands[i+1];\n      lg = ADD16(bandLogE[i], SHL16((opus_val16)eMeans[i],6));\n#ifndef FIXED_POINT\n      g = celt_exp2(lg);\n#else\n      /* Handle the integer part of the log energy */\n      shift = 16-(lg>>DB_SHIFT);\n      if (shift>31)\n      {\n         shift=0;\n         g=0;\n      } else {\n         /* Handle the fractional part. */\n         g = celt_exp2_frac(lg&((1<<DB_SHIFT)-1));\n      }\n      /* Handle extreme gains with negative shift. */\n      if (shift<0)\n      {\n         /* For shift < -2 we'd be likely to overflow, so we're capping\n               the gain here. This shouldn't happen unless the bitstream is\n               already corrupted. */\n         if (shift < -2)\n         {\n            g = 32767;\n            shift = -2;\n         }\n         do {\n            *f++ = SHL32(MULT16_16(*x++, g), -shift);\n         } while (++j<band_end);\n      } else\n#endif\n         /* Be careful of the fixed-point \"else\" just above when changing this code */\n         do {\n            *f++ = SHR32(MULT16_16(*x++, g), shift);\n         } while (++j<band_end);\n   }\n   celt_assert(start <= end);\n   OPUS_CLEAR(&freq[bound], N-bound);\n}\n\n/* This prevents energy collapse for transients with multiple short MDCTs */\nvoid anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size,\n      int start, int end, const opus_val16 *logE, const opus_val16 *prev1logE,\n      const opus_val16 *prev2logE, const int *pulses, opus_uint32 seed, int arch)\n{\n   int c, i, j, k;\n   for (i=start;i<end;i++)\n   {\n      int N0;\n      opus_val16 thresh, sqrt_1;\n      int depth;\n#ifdef FIXED_POINT\n      int shift;\n      opus_val32 thresh32;\n#endif\n\n      N0 = m->eBands[i+1]-m->eBands[i];\n      /* depth in 1/8 bits */\n      celt_assert(pulses[i]>=0);\n      depth = celt_udiv(1+pulses[i], (m->eBands[i+1]-m->eBands[i]))>>LM;\n\n#ifdef FIXED_POINT\n      thresh32 = SHR32(celt_exp2(-SHL16(depth, 10-BITRES)),1);\n      thresh = MULT16_32_Q15(QCONST16(0.5f, 15), MIN32(32767,thresh32));\n      {\n         opus_val32 t;\n         t = N0<<LM;\n         shift = celt_ilog2(t)>>1;\n         t = SHL32(t, (7-shift)<<1);\n         sqrt_1 = celt_rsqrt_norm(t);\n      }\n#else\n      thresh = .5f*celt_exp2(-.125f*depth);\n      sqrt_1 = celt_rsqrt(N0<<LM);\n#endif\n\n      c=0; do\n      {\n         celt_norm *X;\n         opus_val16 prev1;\n         opus_val16 prev2;\n         opus_val32 Ediff;\n         opus_val16 r;\n         int renormalize=0;\n         prev1 = prev1logE[c*m->nbEBands+i];\n         prev2 = prev2logE[c*m->nbEBands+i];\n         if (C==1)\n         {\n            prev1 = MAX16(prev1,prev1logE[m->nbEBands+i]);\n            prev2 = MAX16(prev2,prev2logE[m->nbEBands+i]);\n         }\n         Ediff = EXTEND32(logE[c*m->nbEBands+i])-EXTEND32(MIN16(prev1,prev2));\n         Ediff = MAX32(0, Ediff);\n\n#ifdef FIXED_POINT\n         if (Ediff < 16384)\n         {\n            opus_val32 r32 = SHR32(celt_exp2(-EXTRACT16(Ediff)),1);\n            r = 2*MIN16(16383,r32);\n         } else {\n            r = 0;\n         }\n         if (LM==3)\n            r = MULT16_16_Q14(23170, MIN32(23169, r));\n         r = SHR16(MIN16(thresh, r),1);\n         r = SHR32(MULT16_16_Q15(sqrt_1, r),shift);\n#else\n         /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because\n            short blocks don't have the same energy as long */\n         r = 2.f*celt_exp2(-Ediff);\n         if (LM==3)\n            r *= 1.41421356f;\n         r = MIN16(thresh, r);\n         r = r*sqrt_1;\n#endif\n         X = X_+c*size+(m->eBands[i]<<LM);\n         for (k=0;k<1<<LM;k++)\n         {\n            /* Detect collapse */\n            if (!(collapse_masks[i*C+c]&1<<k))\n            {\n               /* Fill with noise */\n               for (j=0;j<N0;j++)\n               {\n                  seed = celt_lcg_rand(seed);\n                  X[(j<<LM)+k] = (seed&0x8000 ? r : -r);\n               }\n               renormalize = 1;\n            }\n         }\n         /* We just added some energy, so we need to renormalise */\n         if (renormalize)\n            renormalise_vector(X, N0<<LM, Q15ONE, arch);\n      } while (++c<C);\n   }\n}\n\nstatic void intensity_stereo(const CELTMode *m, celt_norm * OPUS_RESTRICT X, const celt_norm * OPUS_RESTRICT Y, const celt_ener *bandE, int bandID, int N)\n{\n   int i = bandID;\n   int j;\n   opus_val16 a1, a2;\n   opus_val16 left, right;\n   opus_val16 norm;\n#ifdef FIXED_POINT\n   int shift = celt_zlog2(MAX32(bandE[i], bandE[i+m->nbEBands]))-13;\n#endif\n   left = VSHR32(bandE[i],shift);\n   right = VSHR32(bandE[i+m->nbEBands],shift);\n   norm = EPSILON + celt_sqrt(EPSILON+MULT16_16(left,left)+MULT16_16(right,right));\n   a1 = DIV32_16(SHL32(EXTEND32(left),14),norm);\n   a2 = DIV32_16(SHL32(EXTEND32(right),14),norm);\n   for (j=0;j<N;j++)\n   {\n      celt_norm r, l;\n      l = X[j];\n      r = Y[j];\n      X[j] = EXTRACT16(SHR32(MAC16_16(MULT16_16(a1, l), a2, r), 14));\n      /* Side is not encoded, no need to calculate */\n   }\n}\n\nstatic void stereo_split(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT Y, int N)\n{\n   int j;\n   for (j=0;j<N;j++)\n   {\n      opus_val32 r, l;\n      l = MULT16_16(QCONST16(.70710678f, 15), X[j]);\n      r = MULT16_16(QCONST16(.70710678f, 15), Y[j]);\n      X[j] = EXTRACT16(SHR32(ADD32(l, r), 15));\n      Y[j] = EXTRACT16(SHR32(SUB32(r, l), 15));\n   }\n}\n\nstatic void stereo_merge(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT Y, opus_val16 mid, int N, int arch)\n{\n   int j;\n   opus_val32 xp=0, side=0;\n   opus_val32 El, Er;\n   opus_val16 mid2;\n#ifdef FIXED_POINT\n   int kl, kr;\n#endif\n   opus_val32 t, lgain, rgain;\n\n   /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */\n   dual_inner_prod(Y, X, Y, N, &xp, &side, arch);\n   /* Compensating for the mid normalization */\n   xp = MULT16_32_Q15(mid, xp);\n   /* mid and side are in Q15, not Q14 like X and Y */\n   mid2 = SHR32(mid, 1);\n   El = MULT16_16(mid2, mid2) + side - 2*xp;\n   Er = MULT16_16(mid2, mid2) + side + 2*xp;\n   if (Er < QCONST32(6e-4f, 28) || El < QCONST32(6e-4f, 28))\n   {\n      OPUS_COPY(Y, X, N);\n      return;\n   }\n\n#ifdef FIXED_POINT\n   kl = celt_ilog2(El)>>1;\n   kr = celt_ilog2(Er)>>1;\n#endif\n   t = VSHR32(El, (kl-7)<<1);\n   lgain = celt_rsqrt_norm(t);\n   t = VSHR32(Er, (kr-7)<<1);\n   rgain = celt_rsqrt_norm(t);\n\n#ifdef FIXED_POINT\n   if (kl < 7)\n      kl = 7;\n   if (kr < 7)\n      kr = 7;\n#endif\n\n   for (j=0;j<N;j++)\n   {\n      celt_norm r, l;\n      /* Apply mid scaling (side is already scaled) */\n      l = MULT16_16_P15(mid, X[j]);\n      r = Y[j];\n      X[j] = EXTRACT16(PSHR32(MULT16_16(lgain, SUB16(l,r)), kl+1));\n      Y[j] = EXTRACT16(PSHR32(MULT16_16(rgain, ADD16(l,r)), kr+1));\n   }\n}\n\n/* Decide whether we should spread the pulses in the current frame */\nint spreading_decision(const CELTMode *m, const celt_norm *X, int *average,\n      int last_decision, int *hf_average, int *tapset_decision, int update_hf,\n      int end, int C, int M)\n{\n   int i, c, N0;\n   int sum = 0, nbBands=0;\n   const opus_int16 * OPUS_RESTRICT eBands = m->eBands;\n   int decision;\n   int hf_sum=0;\n\n   celt_assert(end>0);\n\n   N0 = M*m->shortMdctSize;\n\n   if (M*(eBands[end]-eBands[end-1]) <= 8)\n      return SPREAD_NONE;\n   c=0; do {\n      for (i=0;i<end;i++)\n      {\n         int j, N, tmp=0;\n         int tcount[3] = {0,0,0};\n         const celt_norm * OPUS_RESTRICT x = X+M*eBands[i]+c*N0;\n         N = M*(eBands[i+1]-eBands[i]);\n         if (N<=8)\n            continue;\n         /* Compute rough CDF of |x[j]| */\n         for (j=0;j<N;j++)\n         {\n            opus_val32 x2N; /* Q13 */\n\n            x2N = MULT16_16(MULT16_16_Q15(x[j], x[j]), N);\n            if (x2N < QCONST16(0.25f,13))\n               tcount[0]++;\n            if (x2N < QCONST16(0.0625f,13))\n               tcount[1]++;\n            if (x2N < QCONST16(0.015625f,13))\n               tcount[2]++;\n         }\n\n         /* Only include four last bands (8 kHz and up) */\n         if (i>m->nbEBands-4)\n            hf_sum += celt_udiv(32*(tcount[1]+tcount[0]), N);\n         tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N);\n         sum += tmp*256;\n         nbBands++;\n      }\n   } while (++c<C);\n\n   if (update_hf)\n   {\n      if (hf_sum)\n         hf_sum = celt_udiv(hf_sum, C*(4-m->nbEBands+end));\n      *hf_average = (*hf_average+hf_sum)>>1;\n      hf_sum = *hf_average;\n      if (*tapset_decision==2)\n         hf_sum += 4;\n      else if (*tapset_decision==0)\n         hf_sum -= 4;\n      if (hf_sum > 22)\n         *tapset_decision=2;\n      else if (hf_sum > 18)\n         *tapset_decision=1;\n      else\n         *tapset_decision=0;\n   }\n   /*printf(\"%d %d %d\\n\", hf_sum, *hf_average, *tapset_decision);*/\n   celt_assert(nbBands>0); /* end has to be non-zero */\n   celt_assert(sum>=0);\n   sum = celt_udiv(sum, nbBands);\n   /* Recursive averaging */\n   sum = (sum+*average)>>1;\n   *average = sum;\n   /* Hysteresis */\n   sum = (3*sum + (((3-last_decision)<<7) + 64) + 2)>>2;\n   if (sum < 80)\n   {\n      decision = SPREAD_AGGRESSIVE;\n   } else if (sum < 256)\n   {\n      decision = SPREAD_NORMAL;\n   } else if (sum < 384)\n   {\n      decision = SPREAD_LIGHT;\n   } else {\n      decision = SPREAD_NONE;\n   }\n#ifdef FUZZING\n   decision = rand()&0x3;\n   *tapset_decision=rand()%3;\n#endif\n   return decision;\n}\n\n/* Indexing table for converting from natural Hadamard to ordery Hadamard\n   This is essentially a bit-reversed Gray, on top of which we've added\n   an inversion of the order because we want the DC at the end rather than\n   the beginning. The lines are for N=2, 4, 8, 16 */\nstatic const int ordery_table[] = {\n       1,  0,\n       3,  0,  2,  1,\n       7,  0,  4,  3,  6,  1,  5,  2,\n      15,  0,  8,  7, 12,  3, 11,  4, 14,  1,  9,  6, 13,  2, 10,  5,\n};\n\nstatic void deinterleave_hadamard(celt_norm *X, int N0, int stride, int hadamard)\n{\n   int i,j;\n   VARDECL(celt_norm, tmp);\n   int N;\n   SAVE_STACK;\n   N = N0*stride;\n   ALLOC(tmp, N, celt_norm);\n   celt_assert(stride>0);\n   if (hadamard)\n   {\n      const int *ordery = ordery_table+stride-2;\n      for (i=0;i<stride;i++)\n      {\n         for (j=0;j<N0;j++)\n            tmp[ordery[i]*N0+j] = X[j*stride+i];\n      }\n   } else {\n      for (i=0;i<stride;i++)\n         for (j=0;j<N0;j++)\n            tmp[i*N0+j] = X[j*stride+i];\n   }\n   OPUS_COPY(X, tmp, N);\n   RESTORE_STACK;\n}\n\nstatic void interleave_hadamard(celt_norm *X, int N0, int stride, int hadamard)\n{\n   int i,j;\n   VARDECL(celt_norm, tmp);\n   int N;\n   SAVE_STACK;\n   N = N0*stride;\n   ALLOC(tmp, N, celt_norm);\n   if (hadamard)\n   {\n      const int *ordery = ordery_table+stride-2;\n      for (i=0;i<stride;i++)\n         for (j=0;j<N0;j++)\n            tmp[j*stride+i] = X[ordery[i]*N0+j];\n   } else {\n      for (i=0;i<stride;i++)\n         for (j=0;j<N0;j++)\n            tmp[j*stride+i] = X[i*N0+j];\n   }\n   OPUS_COPY(X, tmp, N);\n   RESTORE_STACK;\n}\n\nvoid haar1(celt_norm *X, int N0, int stride)\n{\n   int i, j;\n   N0 >>= 1;\n   for (i=0;i<stride;i++)\n      for (j=0;j<N0;j++)\n      {\n         opus_val32 tmp1, tmp2;\n         tmp1 = MULT16_16(QCONST16(.70710678f,15), X[stride*2*j+i]);\n         tmp2 = MULT16_16(QCONST16(.70710678f,15), X[stride*(2*j+1)+i]);\n         X[stride*2*j+i] = EXTRACT16(PSHR32(ADD32(tmp1, tmp2), 15));\n         X[stride*(2*j+1)+i] = EXTRACT16(PSHR32(SUB32(tmp1, tmp2), 15));\n      }\n}\n\nstatic int compute_qn(int N, int b, int offset, int pulse_cap, int stereo)\n{\n   static const opus_int16 exp2_table8[8] =\n      {16384, 17866, 19483, 21247, 23170, 25267, 27554, 30048};\n   int qn, qb;\n   int N2 = 2*N-1;\n   if (stereo && N==2)\n      N2--;\n   /* The upper limit ensures that in a stereo split with itheta==16384, we'll\n       always have enough bits left over to code at least one pulse in the\n       side; otherwise it would collapse, since it doesn't get folded. */\n   qb = celt_sudiv(b+N2*offset, N2);\n   qb = IMIN(b-pulse_cap-(4<<BITRES), qb);\n\n   qb = IMIN(8<<BITRES, qb);\n\n   if (qb<(1<<BITRES>>1)) {\n      qn = 1;\n   } else {\n      qn = exp2_table8[qb&0x7]>>(14-(qb>>BITRES));\n      qn = (qn+1)>>1<<1;\n   }\n   celt_assert(qn <= 256);\n   return qn;\n}\n\nstruct band_ctx {\n   int encode;\n   const CELTMode *m;\n   int i;\n   int intensity;\n   int spread;\n   int tf_change;\n   ec_ctx *ec;\n   opus_int32 remaining_bits;\n   const celt_ener *bandE;\n   opus_uint32 seed;\n   int arch;\n};\n\nstruct split_ctx {\n   int inv;\n   int imid;\n   int iside;\n   int delta;\n   int itheta;\n   int qalloc;\n};\n\nstatic void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx,\n      celt_norm *X, celt_norm *Y, int N, int *b, int B, int B0,\n      int LM,\n      int stereo, int *fill)\n{\n   int qn;\n   int itheta=0;\n   int delta;\n   int imid, iside;\n   int qalloc;\n   int pulse_cap;\n   int offset;\n   opus_int32 tell;\n   int inv=0;\n   int encode;\n   const CELTMode *m;\n   int i;\n   int intensity;\n   ec_ctx *ec;\n   const celt_ener *bandE;\n\n   encode = ctx->encode;\n   m = ctx->m;\n   i = ctx->i;\n   intensity = ctx->intensity;\n   ec = ctx->ec;\n   bandE = ctx->bandE;\n\n   /* Decide on the resolution to give to the split parameter theta */\n   pulse_cap = m->logN[i]+LM*(1<<BITRES);\n   offset = (pulse_cap>>1) - (stereo&&N==2 ? QTHETA_OFFSET_TWOPHASE : QTHETA_OFFSET);\n   qn = compute_qn(N, *b, offset, pulse_cap, stereo);\n   if (stereo && i>=intensity)\n      qn = 1;\n   if (encode)\n   {\n      /* theta is the atan() of the ratio between the (normalized)\n         side and mid. With just that parameter, we can re-scale both\n         mid and side because we know that 1) they have unit norm and\n         2) they are orthogonal. */\n      itheta = stereo_itheta(X, Y, stereo, N, ctx->arch);\n   }\n   tell = ec_tell_frac(ec);\n   if (qn!=1)\n   {\n      if (encode)\n         itheta = (itheta*qn+8192)>>14;\n\n      /* Entropy coding of the angle. We use a uniform pdf for the\n         time split, a step for stereo, and a triangular one for the rest. */\n      if (stereo && N>2)\n      {\n         int p0 = 3;\n         int x = itheta;\n         int x0 = qn/2;\n         int ft = p0*(x0+1) + x0;\n         /* Use a probability of p0 up to itheta=8192 and then use 1 after */\n         if (encode)\n         {\n            ec_encode(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft);\n         } else {\n            int fs;\n            fs=ec_decode(ec,ft);\n            if (fs<(x0+1)*p0)\n               x=fs/p0;\n            else\n               x=x0+1+(fs-(x0+1)*p0);\n            ec_dec_update(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft);\n            itheta = x;\n         }\n      } else if (B0>1 || stereo) {\n         /* Uniform pdf */\n         if (encode)\n            ec_enc_uint(ec, itheta, qn+1);\n         else\n            itheta = ec_dec_uint(ec, qn+1);\n      } else {\n         int fs=1, ft;\n         ft = ((qn>>1)+1)*((qn>>1)+1);\n         if (encode)\n         {\n            int fl;\n\n            fs = itheta <= (qn>>1) ? itheta + 1 : qn + 1 - itheta;\n            fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 :\n             ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);\n\n            ec_encode(ec, fl, fl+fs, ft);\n         } else {\n            /* Triangular pdf */\n            int fl=0;\n            int fm;\n            fm = ec_decode(ec, ft);\n\n            if (fm < ((qn>>1)*((qn>>1) + 1)>>1))\n            {\n               itheta = (isqrt32(8*(opus_uint32)fm + 1) - 1)>>1;\n               fs = itheta + 1;\n               fl = itheta*(itheta + 1)>>1;\n            }\n            else\n            {\n               itheta = (2*(qn + 1)\n                - isqrt32(8*(opus_uint32)(ft - fm - 1) + 1))>>1;\n               fs = qn + 1 - itheta;\n               fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);\n            }\n\n            ec_dec_update(ec, fl, fl+fs, ft);\n         }\n      }\n      celt_assert(itheta>=0);\n      itheta = celt_udiv((opus_int32)itheta*16384, qn);\n      if (encode && stereo)\n      {\n         if (itheta==0)\n            intensity_stereo(m, X, Y, bandE, i, N);\n         else\n            stereo_split(X, Y, N);\n      }\n      /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate.\n               Let's do that at higher complexity */\n   } else if (stereo) {\n      if (encode)\n      {\n         inv = itheta > 8192;\n         if (inv)\n         {\n            int j;\n            for (j=0;j<N;j++)\n               Y[j] = -Y[j];\n         }\n         intensity_stereo(m, X, Y, bandE, i, N);\n      }\n      if (*b>2<<BITRES && ctx->remaining_bits > 2<<BITRES)\n      {\n         if (encode)\n            ec_enc_bit_logp(ec, inv, 2);\n         else\n            inv = ec_dec_bit_logp(ec, 2);\n      } else\n         inv = 0;\n      itheta = 0;\n   }\n   qalloc = ec_tell_frac(ec) - tell;\n   *b -= qalloc;\n\n   if (itheta == 0)\n   {\n      imid = 32767;\n      iside = 0;\n      *fill &= (1<<B)-1;\n      delta = -16384;\n   } else if (itheta == 16384)\n   {\n      imid = 0;\n      iside = 32767;\n      *fill &= ((1<<B)-1)<<B;\n      delta = 16384;\n   } else {\n      imid = bitexact_cos((opus_int16)itheta);\n      iside = bitexact_cos((opus_int16)(16384-itheta));\n      /* This is the mid vs side allocation that minimizes squared error\n         in that band. */\n      delta = FRAC_MUL16((N-1)<<7,bitexact_log2tan(iside,imid));\n   }\n\n   sctx->inv = inv;\n   sctx->imid = imid;\n   sctx->iside = iside;\n   sctx->delta = delta;\n   sctx->itheta = itheta;\n   sctx->qalloc = qalloc;\n}\nstatic unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b,\n      celt_norm *lowband_out)\n{\n#ifdef RESYNTH\n   int resynth = 1;\n#else\n   int resynth = !ctx->encode;\n#endif\n   int c;\n   int stereo;\n   celt_norm *x = X;\n   int encode;\n   ec_ctx *ec;\n\n   encode = ctx->encode;\n   ec = ctx->ec;\n\n   stereo = Y != NULL;\n   c=0; do {\n      int sign=0;\n      if (ctx->remaining_bits>=1<<BITRES)\n      {\n         if (encode)\n         {\n            sign = x[0]<0;\n            ec_enc_bits(ec, sign, 1);\n         } else {\n            sign = ec_dec_bits(ec, 1);\n         }\n         ctx->remaining_bits -= 1<<BITRES;\n         b-=1<<BITRES;\n      }\n      if (resynth)\n         x[0] = sign ? -NORM_SCALING : NORM_SCALING;\n      x = Y;\n   } while (++c<1+stereo);\n   if (lowband_out)\n      lowband_out[0] = SHR16(X[0],4);\n   return 1;\n}\n\n/* This function is responsible for encoding and decoding a mono partition.\n   It can split the band in two and transmit the energy difference with\n   the two half-bands. It can be called recursively so bands can end up being\n   split in 8 parts. */\nstatic unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,\n      int N, int b, int B, celt_norm *lowband,\n      int LM,\n      opus_val16 gain, int fill)\n{\n   const unsigned char *cache;\n   int q;\n   int curr_bits;\n   int imid=0, iside=0;\n   int B0=B;\n   opus_val16 mid=0, side=0;\n   unsigned cm=0;\n#ifdef RESYNTH\n   int resynth = 1;\n#else\n   int resynth = !ctx->encode;\n#endif\n   celt_norm *Y=NULL;\n   int encode;\n   const CELTMode *m;\n   int i;\n   int spread;\n   ec_ctx *ec;\n\n   encode = ctx->encode;\n   m = ctx->m;\n   i = ctx->i;\n   spread = ctx->spread;\n   ec = ctx->ec;\n\n   /* If we need 1.5 more bit than we can produce, split the band in two. */\n   cache = m->cache.bits + m->cache.index[(LM+1)*m->nbEBands+i];\n   if (LM != -1 && b > cache[cache[0]]+12 && N>2)\n   {\n      int mbits, sbits, delta;\n      int itheta;\n      int qalloc;\n      struct split_ctx sctx;\n      celt_norm *next_lowband2=NULL;\n      opus_int32 rebalance;\n\n      N >>= 1;\n      Y = X+N;\n      LM -= 1;\n      if (B==1)\n         fill = (fill&1)|(fill<<1);\n      B = (B+1)>>1;\n\n      compute_theta(ctx, &sctx, X, Y, N, &b, B, B0,\n            LM, 0, &fill);\n      imid = sctx.imid;\n      iside = sctx.iside;\n      delta = sctx.delta;\n      itheta = sctx.itheta;\n      qalloc = sctx.qalloc;\n#ifdef FIXED_POINT\n      mid = imid;\n      side = iside;\n#else\n      mid = (1.f/32768)*imid;\n      side = (1.f/32768)*iside;\n#endif\n\n      /* Give more bits to low-energy MDCTs than they would otherwise deserve */\n      if (B0>1 && (itheta&0x3fff))\n      {\n         if (itheta > 8192)\n            /* Rough approximation for pre-echo masking */\n            delta -= delta>>(4-LM);\n         else\n            /* Corresponds to a forward-masking slope of 1.5 dB per 10 ms */\n            delta = IMIN(0, delta + (N<<BITRES>>(5-LM)));\n      }\n      mbits = IMAX(0, IMIN(b, (b-delta)/2));\n      sbits = b-mbits;\n      ctx->remaining_bits -= qalloc;\n\n      if (lowband)\n         next_lowband2 = lowband+N; /* >32-bit split case */\n\n      rebalance = ctx->remaining_bits;\n      if (mbits >= sbits)\n      {\n         cm = quant_partition(ctx, X, N, mbits, B,\n               lowband, LM,\n               MULT16_16_P15(gain,mid), fill);\n         rebalance = mbits - (rebalance-ctx->remaining_bits);\n         if (rebalance > 3<<BITRES && itheta!=0)\n            sbits += rebalance - (3<<BITRES);\n         cm |= quant_partition(ctx, Y, N, sbits, B,\n               next_lowband2, LM,\n               MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);\n      } else {\n         cm = quant_partition(ctx, Y, N, sbits, B,\n               next_lowband2, LM,\n               MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);\n         rebalance = sbits - (rebalance-ctx->remaining_bits);\n         if (rebalance > 3<<BITRES && itheta!=16384)\n            mbits += rebalance - (3<<BITRES);\n         cm |= quant_partition(ctx, X, N, mbits, B,\n               lowband, LM,\n               MULT16_16_P15(gain,mid), fill);\n      }\n   } else {\n      /* This is the basic no-split case */\n      q = bits2pulses(m, i, LM, b);\n      curr_bits = pulses2bits(m, i, LM, q);\n      ctx->remaining_bits -= curr_bits;\n\n      /* Ensures we can never bust the budget */\n      while (ctx->remaining_bits < 0 && q > 0)\n      {\n         ctx->remaining_bits += curr_bits;\n         q--;\n         curr_bits = pulses2bits(m, i, LM, q);\n         ctx->remaining_bits -= curr_bits;\n      }\n\n      if (q!=0)\n      {\n         int K = get_pulses(q);\n\n         /* Finally do the actual quantization */\n         if (encode)\n         {\n            cm = alg_quant(X, N, K, spread, B, ec\n#ifdef RESYNTH\n                 , gain\n#endif\n                 );\n         } else {\n            cm = alg_unquant(X, N, K, spread, B, ec, gain);\n         }\n      } else {\n         /* If there's no pulse, fill the band anyway */\n         int j;\n         if (resynth)\n         {\n            unsigned cm_mask;\n            /* B can be as large as 16, so this shift might overflow an int on a\n               16-bit platform; use a long to get defined behavior.*/\n            cm_mask = (unsigned)(1UL<<B)-1;\n            fill &= cm_mask;\n            if (!fill)\n            {\n               OPUS_CLEAR(X, N);\n            } else {\n               if (lowband == NULL)\n               {\n                  /* Noise */\n                  for (j=0;j<N;j++)\n                  {\n                     ctx->seed = celt_lcg_rand(ctx->seed);\n                     X[j] = (celt_norm)((opus_int32)ctx->seed>>20);\n                  }\n                  cm = cm_mask;\n               } else {\n                  /* Folded spectrum */\n                  for (j=0;j<N;j++)\n                  {\n                     opus_val16 tmp;\n                     ctx->seed = celt_lcg_rand(ctx->seed);\n                     /* About 48 dB below the \"normal\" folding level */\n                     tmp = QCONST16(1.0f/256, 10);\n                     tmp = (ctx->seed)&0x8000 ? tmp : -tmp;\n                     X[j] = lowband[j]+tmp;\n                  }\n                  cm = fill;\n               }\n               renormalise_vector(X, N, gain, ctx->arch);\n            }\n         }\n      }\n   }\n\n   return cm;\n}\n\n\n/* This function is responsible for encoding and decoding a band for the mono case. */\nstatic unsigned quant_band(struct band_ctx *ctx, celt_norm *X,\n      int N, int b, int B, celt_norm *lowband,\n      int LM, celt_norm *lowband_out,\n      opus_val16 gain, celt_norm *lowband_scratch, int fill)\n{\n   int N0=N;\n   int N_B=N;\n   int N_B0;\n   int B0=B;\n   int time_divide=0;\n   int recombine=0;\n   int longBlocks;\n   unsigned cm=0;\n#ifdef RESYNTH\n   int resynth = 1;\n#else\n   int resynth = !ctx->encode;\n#endif\n   int k;\n   int encode;\n   int tf_change;\n\n   encode = ctx->encode;\n   tf_change = ctx->tf_change;\n\n   longBlocks = B0==1;\n\n   N_B = celt_udiv(N_B, B);\n\n   /* Special case for one sample */\n   if (N==1)\n   {\n      return quant_band_n1(ctx, X, NULL, b, lowband_out);\n   }\n\n   if (tf_change>0)\n      recombine = tf_change;\n   /* Band recombining to increase frequency resolution */\n\n   if (lowband_scratch && lowband && (recombine || ((N_B&1) == 0 && tf_change<0) || B0>1))\n   {\n      OPUS_COPY(lowband_scratch, lowband, N);\n      lowband = lowband_scratch;\n   }\n\n   for (k=0;k<recombine;k++)\n   {\n      static const unsigned char bit_interleave_table[16]={\n            0,1,1,1,2,3,3,3,2,3,3,3,2,3,3,3\n      };\n      if (encode)\n         haar1(X, N>>k, 1<<k);\n      if (lowband)\n         haar1(lowband, N>>k, 1<<k);\n      fill = bit_interleave_table[fill&0xF]|bit_interleave_table[fill>>4]<<2;\n   }\n   B>>=recombine;\n   N_B<<=recombine;\n\n   /* Increasing the time resolution */\n   while ((N_B&1) == 0 && tf_change<0)\n   {\n      if (encode)\n         haar1(X, N_B, B);\n      if (lowband)\n         haar1(lowband, N_B, B);\n      fill |= fill<<B;\n      B <<= 1;\n      N_B >>= 1;\n      time_divide++;\n      tf_change++;\n   }\n   B0=B;\n   N_B0 = N_B;\n\n   /* Reorganize the samples in time order instead of frequency order */\n   if (B0>1)\n   {\n      if (encode)\n         deinterleave_hadamard(X, N_B>>recombine, B0<<recombine, longBlocks);\n      if (lowband)\n         deinterleave_hadamard(lowband, N_B>>recombine, B0<<recombine, longBlocks);\n   }\n\n   cm = quant_partition(ctx, X, N, b, B, lowband,\n         LM, gain, fill);\n\n   /* This code is used by the decoder and by the resynthesis-enabled encoder */\n   if (resynth)\n   {\n      /* Undo the sample reorganization going from time order to frequency order */\n      if (B0>1)\n         interleave_hadamard(X, N_B>>recombine, B0<<recombine, longBlocks);\n\n      /* Undo time-freq changes that we did earlier */\n      N_B = N_B0;\n      B = B0;\n      for (k=0;k<time_divide;k++)\n      {\n         B >>= 1;\n         N_B <<= 1;\n         cm |= cm>>B;\n         haar1(X, N_B, B);\n      }\n\n      for (k=0;k<recombine;k++)\n      {\n         static const unsigned char bit_deinterleave_table[16]={\n               0x00,0x03,0x0C,0x0F,0x30,0x33,0x3C,0x3F,\n               0xC0,0xC3,0xCC,0xCF,0xF0,0xF3,0xFC,0xFF\n         };\n         cm = bit_deinterleave_table[cm];\n         haar1(X, N0>>k, 1<<k);\n      }\n      B<<=recombine;\n\n      /* Scale output for later folding */\n      if (lowband_out)\n      {\n         int j;\n         opus_val16 n;\n         n = celt_sqrt(SHL32(EXTEND32(N0),22));\n         for (j=0;j<N0;j++)\n            lowband_out[j] = MULT16_16_Q15(n,X[j]);\n      }\n      cm &= (1<<B)-1;\n   }\n   return cm;\n}\n\n\n/* This function is responsible for encoding and decoding a band for the stereo case. */\nstatic unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm *Y,\n      int N, int b, int B, celt_norm *lowband,\n      int LM, celt_norm *lowband_out,\n      celt_norm *lowband_scratch, int fill)\n{\n   int imid=0, iside=0;\n   int inv = 0;\n   opus_val16 mid=0, side=0;\n   unsigned cm=0;\n#ifdef RESYNTH\n   int resynth = 1;\n#else\n   int resynth = !ctx->encode;\n#endif\n   int mbits, sbits, delta;\n   int itheta;\n   int qalloc;\n   struct split_ctx sctx;\n   int orig_fill;\n   int encode;\n   ec_ctx *ec;\n\n   encode = ctx->encode;\n   ec = ctx->ec;\n\n   /* Special case for one sample */\n   if (N==1)\n   {\n      return quant_band_n1(ctx, X, Y, b, lowband_out);\n   }\n\n   orig_fill = fill;\n\n   compute_theta(ctx, &sctx, X, Y, N, &b, B, B,\n         LM, 1, &fill);\n   inv = sctx.inv;\n   imid = sctx.imid;\n   iside = sctx.iside;\n   delta = sctx.delta;\n   itheta = sctx.itheta;\n   qalloc = sctx.qalloc;\n#ifdef FIXED_POINT\n   mid = imid;\n   side = iside;\n#else\n   mid = (1.f/32768)*imid;\n   side = (1.f/32768)*iside;\n#endif\n\n   /* This is a special case for N=2 that only works for stereo and takes\n      advantage of the fact that mid and side are orthogonal to encode\n      the side with just one bit. */\n   if (N==2)\n   {\n      int c;\n      int sign=0;\n      celt_norm *x2, *y2;\n      mbits = b;\n      sbits = 0;\n      /* Only need one bit for the side. */\n      if (itheta != 0 && itheta != 16384)\n         sbits = 1<<BITRES;\n      mbits -= sbits;\n      c = itheta > 8192;\n      ctx->remaining_bits -= qalloc+sbits;\n\n      x2 = c ? Y : X;\n      y2 = c ? X : Y;\n      if (sbits)\n      {\n         if (encode)\n         {\n            /* Here we only need to encode a sign for the side. */\n            sign = x2[0]*y2[1] - x2[1]*y2[0] < 0;\n            ec_enc_bits(ec, sign, 1);\n         } else {\n            sign = ec_dec_bits(ec, 1);\n         }\n      }\n      sign = 1-2*sign;\n      /* We use orig_fill here because we want to fold the side, but if\n         itheta==16384, we'll have cleared the low bits of fill. */\n      cm = quant_band(ctx, x2, N, mbits, B, lowband,\n            LM, lowband_out, Q15ONE, lowband_scratch, orig_fill);\n      /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse),\n         and there's no need to worry about mixing with the other channel. */\n      y2[0] = -sign*x2[1];\n      y2[1] = sign*x2[0];\n      if (resynth)\n      {\n         celt_norm tmp;\n         X[0] = MULT16_16_Q15(mid, X[0]);\n         X[1] = MULT16_16_Q15(mid, X[1]);\n         Y[0] = MULT16_16_Q15(side, Y[0]);\n         Y[1] = MULT16_16_Q15(side, Y[1]);\n         tmp = X[0];\n         X[0] = SUB16(tmp,Y[0]);\n         Y[0] = ADD16(tmp,Y[0]);\n         tmp = X[1];\n         X[1] = SUB16(tmp,Y[1]);\n         Y[1] = ADD16(tmp,Y[1]);\n      }\n   } else {\n      /* \"Normal\" split code */\n      opus_int32 rebalance;\n\n      mbits = IMAX(0, IMIN(b, (b-delta)/2));\n      sbits = b-mbits;\n      ctx->remaining_bits -= qalloc;\n\n      rebalance = ctx->remaining_bits;\n      if (mbits >= sbits)\n      {\n         /* In stereo mode, we do not apply a scaling to the mid because we need the normalized\n            mid for folding later. */\n         cm = quant_band(ctx, X, N, mbits, B,\n               lowband, LM, lowband_out,\n               Q15ONE, lowband_scratch, fill);\n         rebalance = mbits - (rebalance-ctx->remaining_bits);\n         if (rebalance > 3<<BITRES && itheta!=0)\n            sbits += rebalance - (3<<BITRES);\n\n         /* For a stereo split, the high bits of fill are always zero, so no\n            folding will be done to the side. */\n         cm |= quant_band(ctx, Y, N, sbits, B,\n               NULL, LM, NULL,\n               side, NULL, fill>>B);\n      } else {\n         /* For a stereo split, the high bits of fill are always zero, so no\n            folding will be done to the side. */\n         cm = quant_band(ctx, Y, N, sbits, B,\n               NULL, LM, NULL,\n               side, NULL, fill>>B);\n         rebalance = sbits - (rebalance-ctx->remaining_bits);\n         if (rebalance > 3<<BITRES && itheta!=16384)\n            mbits += rebalance - (3<<BITRES);\n         /* In stereo mode, we do not apply a scaling to the mid because we need the normalized\n            mid for folding later. */\n         cm |= quant_band(ctx, X, N, mbits, B,\n               lowband, LM, lowband_out,\n               Q15ONE, lowband_scratch, fill);\n      }\n   }\n\n\n   /* This code is used by the decoder and by the resynthesis-enabled encoder */\n   if (resynth)\n   {\n      if (N!=2)\n         stereo_merge(X, Y, mid, N, ctx->arch);\n      if (inv)\n      {\n         int j;\n         for (j=0;j<N;j++)\n            Y[j] = -Y[j];\n      }\n   }\n   return cm;\n}\n\n\nvoid quant_all_bands(int encode, const CELTMode *m, int start, int end,\n      celt_norm *X_, celt_norm *Y_, unsigned char *collapse_masks,\n      const celt_ener *bandE, int *pulses, int shortBlocks, int spread,\n      int dual_stereo, int intensity, int *tf_res, opus_int32 total_bits,\n      opus_int32 balance, ec_ctx *ec, int LM, int codedBands,\n      opus_uint32 *seed, int arch)\n{\n   int i;\n   opus_int32 remaining_bits;\n   const opus_int16 * OPUS_RESTRICT eBands = m->eBands;\n   celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2;\n   VARDECL(celt_norm, _norm);\n   celt_norm *lowband_scratch;\n   int B;\n   int M;\n   int lowband_offset;\n   int update_lowband = 1;\n   int C = Y_ != NULL ? 2 : 1;\n   int norm_offset;\n#ifdef RESYNTH\n   int resynth = 1;\n#else\n   int resynth = !encode;\n#endif\n   struct band_ctx ctx;\n   SAVE_STACK;\n\n   M = 1<<LM;\n   B = shortBlocks ? M : 1;\n   norm_offset = M*eBands[start];\n   /* No need to allocate norm for the last band because we don't need an\n      output in that band. */\n   ALLOC(_norm, C*(M*eBands[m->nbEBands-1]-norm_offset), celt_norm);\n   norm = _norm;\n   norm2 = norm + M*eBands[m->nbEBands-1]-norm_offset;\n   /* We can use the last band as scratch space because we don't need that\n      scratch space for the last band. */\n   lowband_scratch = X_+M*eBands[m->nbEBands-1];\n\n   lowband_offset = 0;\n   ctx.bandE = bandE;\n   ctx.ec = ec;\n   ctx.encode = encode;\n   ctx.intensity = intensity;\n   ctx.m = m;\n   ctx.seed = *seed;\n   ctx.spread = spread;\n   ctx.arch = arch;\n   for (i=start;i<end;i++)\n   {\n      opus_int32 tell;\n      int b;\n      int N;\n      opus_int32 curr_balance;\n      int effective_lowband=-1;\n      celt_norm * OPUS_RESTRICT X, * OPUS_RESTRICT Y;\n      int tf_change=0;\n      unsigned x_cm;\n      unsigned y_cm;\n      int last;\n\n      ctx.i = i;\n      last = (i==end-1);\n\n      X = X_+M*eBands[i];\n      if (Y_!=NULL)\n         Y = Y_+M*eBands[i];\n      else\n         Y = NULL;\n      N = M*eBands[i+1]-M*eBands[i];\n      tell = ec_tell_frac(ec);\n\n      /* Compute how many bits we want to allocate to this band */\n      if (i != start)\n         balance -= tell;\n      remaining_bits = total_bits-tell-1;\n      ctx.remaining_bits = remaining_bits;\n      if (i <= codedBands-1)\n      {\n         curr_balance = celt_sudiv(balance, IMIN(3, codedBands-i));\n         b = IMAX(0, IMIN(16383, IMIN(remaining_bits+1,pulses[i]+curr_balance)));\n      } else {\n         b = 0;\n      }\n\n      if (resynth && M*eBands[i]-N >= M*eBands[start] && (update_lowband || lowband_offset==0))\n            lowband_offset = i;\n\n      tf_change = tf_res[i];\n      ctx.tf_change = tf_change;\n      if (i>=m->effEBands)\n      {\n         X=norm;\n         if (Y_!=NULL)\n            Y = norm;\n         lowband_scratch = NULL;\n      }\n      if (i==end-1)\n         lowband_scratch = NULL;\n\n      /* Get a conservative estimate of the collapse_mask's for the bands we're\n         going to be folding from. */\n      if (lowband_offset != 0 && (spread!=SPREAD_AGGRESSIVE || B>1 || tf_change<0))\n      {\n         int fold_start;\n         int fold_end;\n         int fold_i;\n         /* This ensures we never repeat spectral content within one band */\n         effective_lowband = IMAX(0, M*eBands[lowband_offset]-norm_offset-N);\n         fold_start = lowband_offset;\n         while(M*eBands[--fold_start] > effective_lowband+norm_offset);\n         fold_end = lowband_offset-1;\n         while(M*eBands[++fold_end] < effective_lowband+norm_offset+N);\n         x_cm = y_cm = 0;\n         fold_i = fold_start; do {\n           x_cm |= collapse_masks[fold_i*C+0];\n           y_cm |= collapse_masks[fold_i*C+C-1];\n         } while (++fold_i<fold_end);\n      }\n      /* Otherwise, we'll be using the LCG to fold, so all blocks will (almost\n         always) be non-zero. */\n      else\n         x_cm = y_cm = (1<<B)-1;\n\n      if (dual_stereo && i==intensity)\n      {\n         int j;\n\n         /* Switch off dual stereo to do intensity. */\n         dual_stereo = 0;\n         if (resynth)\n            for (j=0;j<M*eBands[i]-norm_offset;j++)\n               norm[j] = HALF32(norm[j]+norm2[j]);\n      }\n      if (dual_stereo)\n      {\n         x_cm = quant_band(&ctx, X, N, b/2, B,\n               effective_lowband != -1 ? norm+effective_lowband : NULL, LM,\n               last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm);\n         y_cm = quant_band(&ctx, Y, N, b/2, B,\n               effective_lowband != -1 ? norm2+effective_lowband : NULL, LM,\n               last?NULL:norm2+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, y_cm);\n      } else {\n         if (Y!=NULL)\n         {\n            x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,\n                  effective_lowband != -1 ? norm+effective_lowband : NULL, LM,\n                        last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, x_cm|y_cm);\n         } else {\n            x_cm = quant_band(&ctx, X, N, b, B,\n                  effective_lowband != -1 ? norm+effective_lowband : NULL, LM,\n                        last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm|y_cm);\n         }\n         y_cm = x_cm;\n      }\n      collapse_masks[i*C+0] = (unsigned char)x_cm;\n      collapse_masks[i*C+C-1] = (unsigned char)y_cm;\n      balance += pulses[i] + tell;\n\n      /* Update the folding position only as long as we have 1 bit/sample depth. */\n      update_lowband = b>(N<<BITRES);\n   }\n   *seed = ctx.seed;\n\n   RESTORE_STACK;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/bands.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Copyright (c) 2008-2009 Gregory Maxwell\n   Written by Jean-Marc Valin and Gregory Maxwell */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef BANDS_H\n#define BANDS_H\n\n#include \"arch.h\"\n#include \"modes.h\"\n#include \"entenc.h\"\n#include \"entdec.h\"\n#include \"rate.h\"\n\n/** Compute the amplitude (sqrt energy) in each of the bands\n * @param m Mode data\n * @param X Spectrum\n * @param bandE Square root of the energy for each band (returned)\n */\nvoid compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM);\n\n/*void compute_noise_energies(const CELTMode *m, const celt_sig *X, const opus_val16 *tonality, celt_ener *bandE);*/\n\n/** Normalise each band of X such that the energy in each band is\n    equal to 1\n * @param m Mode data\n * @param X Spectrum (returned normalised)\n * @param bandE Square root of the energy for each band\n */\nvoid normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M);\n\n/** Denormalise each band of X to restore full amplitude\n * @param m Mode data\n * @param X Spectrum (returned de-normalised)\n * @param bandE Square root of the energy for each band\n */\nvoid denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,\n      celt_sig * OPUS_RESTRICT freq, const opus_val16 *bandE, int start,\n      int end, int M, int downsample, int silence);\n\n#define SPREAD_NONE       (0)\n#define SPREAD_LIGHT      (1)\n#define SPREAD_NORMAL     (2)\n#define SPREAD_AGGRESSIVE (3)\n\nint spreading_decision(const CELTMode *m, const celt_norm *X, int *average,\n      int last_decision, int *hf_average, int *tapset_decision, int update_hf,\n      int end, int C, int M);\n\n#ifdef MEASURE_NORM_MSE\nvoid measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, float *bandE0, int M, int N, int C);\n#endif\n\nvoid haar1(celt_norm *X, int N0, int stride);\n\n/** Quantisation/encoding of the residual spectrum\n * @param encode flag that indicates whether we're encoding (1) or decoding (0)\n * @param m Mode data\n * @param start First band to process\n * @param end Last band to process + 1\n * @param X Residual (normalised)\n * @param Y Residual (normalised) for second channel (or NULL for mono)\n * @param collapse_masks Anti-collapse tracking mask\n * @param bandE Square root of the energy for each band\n * @param pulses Bit allocation (per band) for PVQ\n * @param shortBlocks Zero for long blocks, non-zero for short blocks\n * @param spread Amount of spreading to use\n * @param dual_stereo Zero for MS stereo, non-zero for dual stereo\n * @param intensity First band to use intensity stereo\n * @param tf_res Time-frequency resolution change\n * @param total_bits Total number of bits that can be used for the frame (including the ones already spent)\n * @param balance Number of unallocated bits\n * @param en Entropy coder state\n * @param LM log2() of the number of 2.5 subframes in the frame\n * @param codedBands Last band to receive bits + 1\n * @param seed Random generator seed\n * @param arch Run-time architecture (see opus_select_arch())\n */\nvoid quant_all_bands(int encode, const CELTMode *m, int start, int end,\n      celt_norm * X, celt_norm * Y, unsigned char *collapse_masks,\n      const celt_ener *bandE, int *pulses, int shortBlocks, int spread,\n      int dual_stereo, int intensity, int *tf_res, opus_int32 total_bits,\n      opus_int32 balance, ec_ctx *ec, int M, int codedBands, opus_uint32 *seed,\n      int arch);\n\nvoid anti_collapse(const CELTMode *m, celt_norm *X_,\n      unsigned char *collapse_masks, int LM, int C, int size, int start,\n      int end, const opus_val16 *logE, const opus_val16 *prev1logE,\n      const opus_val16 *prev2logE, const int *pulses, opus_uint32 seed,\n      int arch);\n\nopus_uint32 celt_lcg_rand(opus_uint32 seed);\n\nint hysteresis_decision(opus_val16 val, const opus_val16 *thresholds, const opus_val16 *hysteresis, int N, int prev);\n\n#endif /* BANDS_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/celt.c",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2010 Xiph.Org Foundation\n   Copyright (c) 2008 Gregory Maxwell\n   Written by Jean-Marc Valin and Gregory Maxwell */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#define CELT_C\n\n#include \"os_support.h\"\n#include \"mdct.h\"\n#include <math.h>\n#include \"celt.h\"\n#include \"pitch.h\"\n#include \"bands.h\"\n#include \"modes.h\"\n#include \"entcode.h\"\n#include \"quant_bands.h\"\n#include \"rate.h\"\n#include \"stack_alloc.h\"\n#include \"mathops.h\"\n#include \"float_cast.h\"\n#include <stdarg.h>\n#include \"celt_lpc.h\"\n#include \"vq.h\"\n\n#ifndef PACKAGE_VERSION\n#define PACKAGE_VERSION \"unknown\"\n#endif\n\n#if defined(MIPSr1_ASM)\n#include \"mips/celt_mipsr1.h\"\n#endif\n\n\nint resampling_factor(opus_int32 rate)\n{\n   int ret;\n   switch (rate)\n   {\n   case 48000:\n      ret = 1;\n      break;\n   case 24000:\n      ret = 2;\n      break;\n   case 16000:\n      ret = 3;\n      break;\n   case 12000:\n      ret = 4;\n      break;\n   case 8000:\n      ret = 6;\n      break;\n   default:\n#ifndef CUSTOM_MODES\n      celt_assert(0);\n#endif\n      ret = 0;\n      break;\n   }\n   return ret;\n}\n\n#if !defined(OVERRIDE_COMB_FILTER_CONST) || defined(NON_STATIC_COMB_FILTER_CONST_C)\n/* This version should be faster on ARM */\n#ifdef OPUS_ARM_ASM\n#ifndef NON_STATIC_COMB_FILTER_CONST_C\nstatic\n#endif\nvoid comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,\n      opus_val16 g10, opus_val16 g11, opus_val16 g12)\n{\n   opus_val32 x0, x1, x2, x3, x4;\n   int i;\n   x4 = SHL32(x[-T-2], 1);\n   x3 = SHL32(x[-T-1], 1);\n   x2 = SHL32(x[-T], 1);\n   x1 = SHL32(x[-T+1], 1);\n   for (i=0;i<N-4;i+=5)\n   {\n      opus_val32 t;\n      x0=SHL32(x[i-T+2],1);\n      t = MAC16_32_Q16(x[i], g10, x2);\n      t = MAC16_32_Q16(t, g11, ADD32(x1,x3));\n      t = MAC16_32_Q16(t, g12, ADD32(x0,x4));\n      y[i] = t;\n      x4=SHL32(x[i-T+3],1);\n      t = MAC16_32_Q16(x[i+1], g10, x1);\n      t = MAC16_32_Q16(t, g11, ADD32(x0,x2));\n      t = MAC16_32_Q16(t, g12, ADD32(x4,x3));\n      y[i+1] = t;\n      x3=SHL32(x[i-T+4],1);\n      t = MAC16_32_Q16(x[i+2], g10, x0);\n      t = MAC16_32_Q16(t, g11, ADD32(x4,x1));\n      t = MAC16_32_Q16(t, g12, ADD32(x3,x2));\n      y[i+2] = t;\n      x2=SHL32(x[i-T+5],1);\n      t = MAC16_32_Q16(x[i+3], g10, x4);\n      t = MAC16_32_Q16(t, g11, ADD32(x3,x0));\n      t = MAC16_32_Q16(t, g12, ADD32(x2,x1));\n      y[i+3] = t;\n      x1=SHL32(x[i-T+6],1);\n      t = MAC16_32_Q16(x[i+4], g10, x3);\n      t = MAC16_32_Q16(t, g11, ADD32(x2,x4));\n      t = MAC16_32_Q16(t, g12, ADD32(x1,x0));\n      y[i+4] = t;\n   }\n#ifdef CUSTOM_MODES\n   for (;i<N;i++)\n   {\n      opus_val32 t;\n      x0=SHL32(x[i-T+2],1);\n      t = MAC16_32_Q16(x[i], g10, x2);\n      t = MAC16_32_Q16(t, g11, ADD32(x1,x3));\n      t = MAC16_32_Q16(t, g12, ADD32(x0,x4));\n      y[i] = t;\n      x4=x3;\n      x3=x2;\n      x2=x1;\n      x1=x0;\n   }\n#endif\n}\n#else\n#ifndef NON_STATIC_COMB_FILTER_CONST_C\nstatic\n#endif\nvoid comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,\n      opus_val16 g10, opus_val16 g11, opus_val16 g12)\n{\n   opus_val32 x0, x1, x2, x3, x4;\n   int i;\n   x4 = x[-T-2];\n   x3 = x[-T-1];\n   x2 = x[-T];\n   x1 = x[-T+1];\n   for (i=0;i<N;i++)\n   {\n      x0=x[i-T+2];\n      y[i] = x[i]\n               + MULT16_32_Q15(g10,x2)\n               + MULT16_32_Q15(g11,ADD32(x1,x3))\n               + MULT16_32_Q15(g12,ADD32(x0,x4));\n      x4=x3;\n      x3=x2;\n      x2=x1;\n      x1=x0;\n   }\n\n}\n#endif\n#endif\n\n#ifndef OVERRIDE_comb_filter\nvoid comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,\n      opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,\n      const opus_val16 *window, int overlap, int arch)\n{\n   int i;\n   /* printf (\"%d %d %f %f\\n\", T0, T1, g0, g1); */\n   opus_val16 g00, g01, g02, g10, g11, g12;\n   opus_val32 x0, x1, x2, x3, x4;\n   static const opus_val16 gains[3][3] = {\n         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},\n         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},\n         {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};\n\n   if (g0==0 && g1==0)\n   {\n      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */\n      if (x!=y)\n         OPUS_MOVE(y, x, N);\n      return;\n   }\n   g00 = MULT16_16_P15(g0, gains[tapset0][0]);\n   g01 = MULT16_16_P15(g0, gains[tapset0][1]);\n   g02 = MULT16_16_P15(g0, gains[tapset0][2]);\n   g10 = MULT16_16_P15(g1, gains[tapset1][0]);\n   g11 = MULT16_16_P15(g1, gains[tapset1][1]);\n   g12 = MULT16_16_P15(g1, gains[tapset1][2]);\n   x1 = x[-T1+1];\n   x2 = x[-T1  ];\n   x3 = x[-T1-1];\n   x4 = x[-T1-2];\n   /* If the filter didn't change, we don't need the overlap */\n   if (g0==g1 && T0==T1 && tapset0==tapset1)\n      overlap=0;\n   for (i=0;i<overlap;i++)\n   {\n      opus_val16 f;\n      x0=x[i-T1+2];\n      f = MULT16_16_Q15(window[i],window[i]);\n      y[i] = x[i]\n               + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g00),x[i-T0])\n               + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))\n               + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))\n               + MULT16_32_Q15(MULT16_16_Q15(f,g10),x2)\n               + MULT16_32_Q15(MULT16_16_Q15(f,g11),ADD32(x1,x3))\n               + MULT16_32_Q15(MULT16_16_Q15(f,g12),ADD32(x0,x4));\n      x4=x3;\n      x3=x2;\n      x2=x1;\n      x1=x0;\n\n   }\n   if (g1==0)\n   {\n      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */\n      if (x!=y)\n         OPUS_MOVE(y+overlap, x+overlap, N-overlap);\n      return;\n   }\n\n   /* Compute the part with the constant filter. */\n   comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);\n}\n#endif /* OVERRIDE_comb_filter */\n\nconst signed char tf_select_table[4][8] = {\n      {0, -1, 0, -1,    0,-1, 0,-1},\n      {0, -1, 0, -2,    1, 0, 1,-1},\n      {0, -2, 0, -3,    2, 0, 1,-1},\n      {0, -2, 0, -3,    3, 0, 1,-1},\n};\n\n\nvoid init_caps(const CELTMode *m,int *cap,int LM,int C)\n{\n   int i;\n   for (i=0;i<m->nbEBands;i++)\n   {\n      int N;\n      N=(m->eBands[i+1]-m->eBands[i])<<LM;\n      cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;\n   }\n}\n\n\n\nconst char *opus_strerror(int error)\n{\n   static const char * const error_strings[8] = {\n      \"success\",\n      \"invalid argument\",\n      \"buffer too small\",\n      \"internal error\",\n      \"corrupted stream\",\n      \"request not implemented\",\n      \"invalid state\",\n      \"memory allocation failed\"\n   };\n   if (error > 0 || error < -7)\n      return \"unknown error\";\n   else\n      return error_strings[-error];\n}\n\nconst char *opus_get_version_string(void)\n{\n    return \"libopus \" PACKAGE_VERSION\n    /* Applications may rely on the presence of this substring in the version\n       string to determine if they have a fixed-point or floating-point build\n       at runtime. */\n#ifdef FIXED_POINT\n          \"-fixed\"\n#endif\n#ifdef FUZZING\n          \"-fuzzing\"\n#endif\n          ;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/celt.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Copyright (c) 2008 Gregory Maxwell\n   Written by Jean-Marc Valin and Gregory Maxwell */\n/**\n  @file celt.h\n  @brief Contains all the functions for encoding and decoding audio\n */\n\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef CELT_H\n#define CELT_H\n\n#include \"opus_types.h\"\n#include \"opus_defines.h\"\n#include \"opus_custom.h\"\n#include \"entenc.h\"\n#include \"entdec.h\"\n#include \"arch.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define CELTEncoder OpusCustomEncoder\n#define CELTDecoder OpusCustomDecoder\n#define CELTMode OpusCustomMode\n\ntypedef struct {\n   int valid;\n   float tonality;\n   float tonality_slope;\n   float noisiness;\n   float activity;\n   float music_prob;\n   int        bandwidth;\n}AnalysisInfo;\n\n#define __celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))\n\n#define __celt_check_analysis_ptr(ptr) ((ptr) + ((ptr) - (const AnalysisInfo*)(ptr)))\n\n/* Encoder/decoder Requests */\n\n/* Expose this option again when variable framesize actually works */\n#define OPUS_FRAMESIZE_VARIABLE              5010 /**< Optimize the frame size dynamically */\n\n\n#define CELT_SET_PREDICTION_REQUEST    10002\n/** Controls the use of interframe prediction.\n    0=Independent frames\n    1=Short term interframe prediction allowed\n    2=Long term prediction allowed\n */\n#define CELT_SET_PREDICTION(x) CELT_SET_PREDICTION_REQUEST, __opus_check_int(x)\n\n#define CELT_SET_INPUT_CLIPPING_REQUEST    10004\n#define CELT_SET_INPUT_CLIPPING(x) CELT_SET_INPUT_CLIPPING_REQUEST, __opus_check_int(x)\n\n#define CELT_GET_AND_CLEAR_ERROR_REQUEST   10007\n#define CELT_GET_AND_CLEAR_ERROR(x) CELT_GET_AND_CLEAR_ERROR_REQUEST, __opus_check_int_ptr(x)\n\n#define CELT_SET_CHANNELS_REQUEST    10008\n#define CELT_SET_CHANNELS(x) CELT_SET_CHANNELS_REQUEST, __opus_check_int(x)\n\n\n/* Internal */\n#define CELT_SET_START_BAND_REQUEST    10010\n#define CELT_SET_START_BAND(x) CELT_SET_START_BAND_REQUEST, __opus_check_int(x)\n\n#define CELT_SET_END_BAND_REQUEST    10012\n#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, __opus_check_int(x)\n\n#define CELT_GET_MODE_REQUEST    10015\n/** Get the CELTMode used by an encoder or decoder */\n#define CELT_GET_MODE(x) CELT_GET_MODE_REQUEST, __celt_check_mode_ptr_ptr(x)\n\n#define CELT_SET_SIGNALLING_REQUEST    10016\n#define CELT_SET_SIGNALLING(x) CELT_SET_SIGNALLING_REQUEST, __opus_check_int(x)\n\n#define CELT_SET_TONALITY_REQUEST    10018\n#define CELT_SET_TONALITY(x) CELT_SET_TONALITY_REQUEST, __opus_check_int(x)\n#define CELT_SET_TONALITY_SLOPE_REQUEST    10020\n#define CELT_SET_TONALITY_SLOPE(x) CELT_SET_TONALITY_SLOPE_REQUEST, __opus_check_int(x)\n\n#define CELT_SET_ANALYSIS_REQUEST    10022\n#define CELT_SET_ANALYSIS(x) CELT_SET_ANALYSIS_REQUEST, __celt_check_analysis_ptr(x)\n\n#define OPUS_SET_LFE_REQUEST    10024\n#define OPUS_SET_LFE(x) OPUS_SET_LFE_REQUEST, __opus_check_int(x)\n\n#define OPUS_SET_ENERGY_MASK_REQUEST    10026\n#define OPUS_SET_ENERGY_MASK(x) OPUS_SET_ENERGY_MASK_REQUEST, __opus_check_val16_ptr(x)\n\n/* Encoder stuff */\n\nint celt_encoder_get_size(int channels);\n\nint celt_encode_with_ec(OpusCustomEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc);\n\nint celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels,\n                      int arch);\n\n\n\n/* Decoder stuff */\n\nint celt_decoder_get_size(int channels);\n\n\nint celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels);\n\nint celt_decode_with_ec(OpusCustomDecoder * OPUS_RESTRICT st, const unsigned char *data,\n      int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum);\n\n#define celt_encoder_ctl opus_custom_encoder_ctl\n#define celt_decoder_ctl opus_custom_decoder_ctl\n\n\n#ifdef CUSTOM_MODES\n#define OPUS_CUSTOM_NOSTATIC\n#else\n#define OPUS_CUSTOM_NOSTATIC static OPUS_INLINE\n#endif\n\nstatic const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0};\n/* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */\nstatic const unsigned char spread_icdf[4] = {25, 23, 2, 0};\n\nstatic const unsigned char tapset_icdf[3]={2,1,0};\n\n#ifdef CUSTOM_MODES\nstatic const unsigned char toOpusTable[20] = {\n      0xE0, 0xE8, 0xF0, 0xF8,\n      0xC0, 0xC8, 0xD0, 0xD8,\n      0xA0, 0xA8, 0xB0, 0xB8,\n      0x00, 0x00, 0x00, 0x00,\n      0x80, 0x88, 0x90, 0x98,\n};\n\nstatic const unsigned char fromOpusTable[16] = {\n      0x80, 0x88, 0x90, 0x98,\n      0x40, 0x48, 0x50, 0x58,\n      0x20, 0x28, 0x30, 0x38,\n      0x00, 0x08, 0x10, 0x18\n};\n\nstatic OPUS_INLINE int toOpus(unsigned char c)\n{\n   int ret=0;\n   if (c<0xA0)\n      ret = toOpusTable[c>>3];\n   if (ret == 0)\n      return -1;\n   else\n      return ret|(c&0x7);\n}\n\nstatic OPUS_INLINE int fromOpus(unsigned char c)\n{\n   if (c<0x80)\n      return -1;\n   else\n      return fromOpusTable[(c>>3)-16] | (c&0x7);\n}\n#endif /* CUSTOM_MODES */\n\n#define COMBFILTER_MAXPERIOD 1024\n#define COMBFILTER_MINPERIOD 15\n\nextern const signed char tf_select_table[4][8];\n\nint resampling_factor(opus_int32 rate);\n\nvoid celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,\n                        int N, int CC, int upsample, const opus_val16 *coef, celt_sig *mem, int clip);\n\nvoid comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,\n      opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,\n      const opus_val16 *window, int overlap, int arch);\n\n#ifdef NON_STATIC_COMB_FILTER_CONST_C\nvoid comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,\n                         opus_val16 g10, opus_val16 g11, opus_val16 g12);\n#endif\n\n#ifndef OVERRIDE_COMB_FILTER_CONST\n# define comb_filter_const(y, x, T, N, g10, g11, g12, arch)\t\t\\\n    ((void)(arch),comb_filter_const_c(y, x, T, N, g10, g11, g12))\n#endif\n\nvoid init_caps(const CELTMode *m,int *cap,int LM,int C);\n\n#ifdef RESYNTH\nvoid deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem);\nvoid celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],\n      opus_val16 *oldBandE, int start, int effEnd, int C, int CC, int isTransient,\n      int LM, int downsample, int silence);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* CELT_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/celt_decoder.c",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2010 Xiph.Org Foundation\n   Copyright (c) 2008 Gregory Maxwell\n   Written by Jean-Marc Valin and Gregory Maxwell */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#define CELT_DECODER_C\n\n#include \"cpu_support.h\"\n#include \"os_support.h\"\n#include \"mdct.h\"\n#include <math.h>\n#include \"celt.h\"\n#include \"pitch.h\"\n#include \"bands.h\"\n#include \"modes.h\"\n#include \"entcode.h\"\n#include \"quant_bands.h\"\n#include \"rate.h\"\n#include \"stack_alloc.h\"\n#include \"mathops.h\"\n#include \"float_cast.h\"\n#include <stdarg.h>\n#include \"celt_lpc.h\"\n#include \"vq.h\"\n\n#if defined(SMALL_FOOTPRINT) && defined(FIXED_POINT)\n#define NORM_ALIASING_HACK\n#endif\n/**********************************************************************/\n/*                                                                    */\n/*                             DECODER                                */\n/*                                                                    */\n/**********************************************************************/\n#define DECODE_BUFFER_SIZE 2048\n\n/** Decoder state\n @brief Decoder state\n */\nstruct OpusCustomDecoder {\n   const OpusCustomMode *mode;\n   int overlap;\n   int channels;\n   int stream_channels;\n\n   int downsample;\n   int start, end;\n   int signalling;\n   int arch;\n\n   /* Everything beyond this point gets cleared on a reset */\n#define DECODER_RESET_START rng\n\n   opus_uint32 rng;\n   int error;\n   int last_pitch_index;\n   int loss_count;\n   int postfilter_period;\n   int postfilter_period_old;\n   opus_val16 postfilter_gain;\n   opus_val16 postfilter_gain_old;\n   int postfilter_tapset;\n   int postfilter_tapset_old;\n\n   celt_sig preemph_memD[2];\n\n   celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */\n   /* opus_val16 lpc[],  Size = channels*LPC_ORDER */\n   /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */\n   /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */\n   /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */\n   /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */\n};\n\nint celt_decoder_get_size(int channels)\n{\n   const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);\n   return opus_custom_decoder_get_size(mode, channels);\n}\n\nOPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int channels)\n{\n   int size = sizeof(struct CELTDecoder)\n            + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig)\n            + channels*LPC_ORDER*sizeof(opus_val16)\n            + 4*2*mode->nbEBands*sizeof(opus_val16);\n   return size;\n}\n\n#ifdef CUSTOM_MODES\nCELTDecoder *opus_custom_decoder_create(const CELTMode *mode, int channels, int *error)\n{\n   int ret;\n   CELTDecoder *st = (CELTDecoder *)opus_alloc(opus_custom_decoder_get_size(mode, channels));\n   ret = opus_custom_decoder_init(st, mode, channels);\n   if (ret != OPUS_OK)\n   {\n      opus_custom_decoder_destroy(st);\n      st = NULL;\n   }\n   if (error)\n      *error = ret;\n   return st;\n}\n#endif /* CUSTOM_MODES */\n\nint celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels)\n{\n   int ret;\n   ret = opus_custom_decoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels);\n   if (ret != OPUS_OK)\n      return ret;\n   st->downsample = resampling_factor(sampling_rate);\n   if (st->downsample==0)\n      return OPUS_BAD_ARG;\n   else\n      return OPUS_OK;\n}\n\nOPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels)\n{\n   if (channels < 0 || channels > 2)\n      return OPUS_BAD_ARG;\n\n   if (st==NULL)\n      return OPUS_ALLOC_FAIL;\n\n   OPUS_CLEAR((char*)st, opus_custom_decoder_get_size(mode, channels));\n\n   st->mode = mode;\n   st->overlap = mode->overlap;\n   st->stream_channels = st->channels = channels;\n\n   st->downsample = 1;\n   st->start = 0;\n   st->end = st->mode->effEBands;\n   st->signalling = 1;\n   st->arch = opus_select_arch();\n\n   st->loss_count = 0;\n\n   opus_custom_decoder_ctl(st, OPUS_RESET_STATE);\n\n   return OPUS_OK;\n}\n\n#ifdef CUSTOM_MODES\nvoid opus_custom_decoder_destroy(CELTDecoder *st)\n{\n   opus_free(st);\n}\n#endif /* CUSTOM_MODES */\n\n\n#ifndef RESYNTH\nstatic\n#endif\nvoid deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef,\n      celt_sig *mem, int accum)\n{\n   int c;\n   int Nd;\n   int apply_downsampling=0;\n   opus_val16 coef0;\n   VARDECL(celt_sig, scratch);\n   SAVE_STACK;\n#ifndef FIXED_POINT\n   (void)accum;\n   celt_assert(accum==0);\n#endif\n   ALLOC(scratch, N, celt_sig);\n   coef0 = coef[0];\n   Nd = N/downsample;\n   c=0; do {\n      int j;\n      celt_sig * OPUS_RESTRICT x;\n      opus_val16  * OPUS_RESTRICT y;\n      celt_sig m = mem[c];\n      x =in[c];\n      y = pcm+c;\n#ifdef CUSTOM_MODES\n      if (coef[1] != 0)\n      {\n         opus_val16 coef1 = coef[1];\n         opus_val16 coef3 = coef[3];\n         for (j=0;j<N;j++)\n         {\n            celt_sig tmp = x[j] + m + VERY_SMALL;\n            m = MULT16_32_Q15(coef0, tmp)\n                          - MULT16_32_Q15(coef1, x[j]);\n            tmp = SHL32(MULT16_32_Q15(coef3, tmp), 2);\n            scratch[j] = tmp;\n         }\n         apply_downsampling=1;\n      } else\n#endif\n      if (downsample>1)\n      {\n         /* Shortcut for the standard (non-custom modes) case */\n         for (j=0;j<N;j++)\n         {\n            celt_sig tmp = x[j] + m + VERY_SMALL;\n            m = MULT16_32_Q15(coef0, tmp);\n            scratch[j] = tmp;\n         }\n         apply_downsampling=1;\n      } else {\n         /* Shortcut for the standard (non-custom modes) case */\n#ifdef FIXED_POINT\n         if (accum)\n         {\n            for (j=0;j<N;j++)\n            {\n               celt_sig tmp = x[j] + m + VERY_SMALL;\n               m = MULT16_32_Q15(coef0, tmp);\n               y[j*C] = SAT16(ADD32(y[j*C], SCALEOUT(SIG2WORD16(tmp))));\n            }\n         } else\n#endif\n         {\n            for (j=0;j<N;j++)\n            {\n               celt_sig tmp = x[j] + m + VERY_SMALL;\n               m = MULT16_32_Q15(coef0, tmp);\n               y[j*C] = SCALEOUT(SIG2WORD16(tmp));\n            }\n         }\n      }\n      mem[c] = m;\n\n      if (apply_downsampling)\n      {\n         /* Perform down-sampling */\n#ifdef FIXED_POINT\n         if (accum)\n         {\n            for (j=0;j<Nd;j++)\n               y[j*C] = SAT16(ADD32(y[j*C], SCALEOUT(SIG2WORD16(scratch[j*downsample]))));\n         } else\n#endif\n         {\n            for (j=0;j<Nd;j++)\n               y[j*C] = SCALEOUT(SIG2WORD16(scratch[j*downsample]));\n         }\n      }\n   } while (++c<C);\n   RESTORE_STACK;\n}\n\n#ifndef RESYNTH\nstatic\n#endif\nvoid celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],\n                    opus_val16 *oldBandE, int start, int effEnd, int C, int CC,\n                    int isTransient, int LM, int downsample,\n                    int silence, int arch)\n{\n   int c, i;\n   int M;\n   int b;\n   int B;\n   int N, NB;\n   int shift;\n   int nbEBands;\n   int overlap;\n   VARDECL(celt_sig, freq);\n   SAVE_STACK;\n\n   overlap = mode->overlap;\n   nbEBands = mode->nbEBands;\n   N = mode->shortMdctSize<<LM;\n   ALLOC(freq, N, celt_sig); /**< Interleaved signal MDCTs */\n   M = 1<<LM;\n\n   if (isTransient)\n   {\n      B = M;\n      NB = mode->shortMdctSize;\n      shift = mode->maxLM;\n   } else {\n      B = 1;\n      NB = mode->shortMdctSize<<LM;\n      shift = mode->maxLM-LM;\n   }\n\n   if (CC==2&&C==1)\n   {\n      /* Copying a mono streams to two channels */\n      celt_sig *freq2;\n      denormalise_bands(mode, X, freq, oldBandE, start, effEnd, M,\n            downsample, silence);\n      /* Store a temporary copy in the output buffer because the IMDCT destroys its input. */\n      freq2 = out_syn[1]+overlap/2;\n      OPUS_COPY(freq2, freq, N);\n      for (b=0;b<B;b++)\n         clt_mdct_backward(&mode->mdct, &freq2[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch);\n      for (b=0;b<B;b++)\n         clt_mdct_backward(&mode->mdct, &freq[b], out_syn[1]+NB*b, mode->window, overlap, shift, B, arch);\n   } else if (CC==1&&C==2)\n   {\n      /* Downmixing a stereo stream to mono */\n      celt_sig *freq2;\n      freq2 = out_syn[0]+overlap/2;\n      denormalise_bands(mode, X, freq, oldBandE, start, effEnd, M,\n            downsample, silence);\n      /* Use the output buffer as temp array before downmixing. */\n      denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M,\n            downsample, silence);\n      for (i=0;i<N;i++)\n         freq[i] = HALF32(ADD32(freq[i],freq2[i]));\n      for (b=0;b<B;b++)\n         clt_mdct_backward(&mode->mdct, &freq[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch);\n   } else {\n      /* Normal case (mono or stereo) */\n      c=0; do {\n         denormalise_bands(mode, X+c*N, freq, oldBandE+c*nbEBands, start, effEnd, M,\n               downsample, silence);\n         for (b=0;b<B;b++)\n            clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B, arch);\n      } while (++c<CC);\n   }\n   RESTORE_STACK;\n}\n\nstatic void tf_decode(int start, int end, int isTransient, int *tf_res, int LM, ec_dec *dec)\n{\n   int i, curr, tf_select;\n   int tf_select_rsv;\n   int tf_changed;\n   int logp;\n   opus_uint32 budget;\n   opus_uint32 tell;\n\n   budget = dec->storage*8;\n   tell = ec_tell(dec);\n   logp = isTransient ? 2 : 4;\n   tf_select_rsv = LM>0 && tell+logp+1<=budget;\n   budget -= tf_select_rsv;\n   tf_changed = curr = 0;\n   for (i=start;i<end;i++)\n   {\n      if (tell+logp<=budget)\n      {\n         curr ^= ec_dec_bit_logp(dec, logp);\n         tell = ec_tell(dec);\n         tf_changed |= curr;\n      }\n      tf_res[i] = curr;\n      logp = isTransient ? 4 : 5;\n   }\n   tf_select = 0;\n   if (tf_select_rsv &&\n     tf_select_table[LM][4*isTransient+0+tf_changed] !=\n     tf_select_table[LM][4*isTransient+2+tf_changed])\n   {\n      tf_select = ec_dec_bit_logp(dec, 1);\n   }\n   for (i=start;i<end;i++)\n   {\n      tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];\n   }\n}\n\n/* The maximum pitch lag to allow in the pitch-based PLC. It's possible to save\n   CPU time in the PLC pitch search by making this smaller than MAX_PERIOD. The\n   current value corresponds to a pitch of 66.67 Hz. */\n#define PLC_PITCH_LAG_MAX (720)\n/* The minimum pitch lag to allow in the pitch-based PLC. This corresponds to a\n   pitch of 480 Hz. */\n#define PLC_PITCH_LAG_MIN (100)\n\nstatic int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch)\n{\n   int pitch_index;\n   VARDECL( opus_val16, lp_pitch_buf );\n   SAVE_STACK;\n   ALLOC( lp_pitch_buf, DECODE_BUFFER_SIZE>>1, opus_val16 );\n   pitch_downsample(decode_mem, lp_pitch_buf,\n         DECODE_BUFFER_SIZE, C, arch);\n   pitch_search(lp_pitch_buf+(PLC_PITCH_LAG_MAX>>1), lp_pitch_buf,\n         DECODE_BUFFER_SIZE-PLC_PITCH_LAG_MAX,\n         PLC_PITCH_LAG_MAX-PLC_PITCH_LAG_MIN, &pitch_index, arch);\n   pitch_index = PLC_PITCH_LAG_MAX-pitch_index;\n   RESTORE_STACK;\n   return pitch_index;\n}\n\nstatic void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)\n{\n   int c;\n   int i;\n   const int C = st->channels;\n   celt_sig *decode_mem[2];\n   celt_sig *out_syn[2];\n   opus_val16 *lpc;\n   opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;\n   const OpusCustomMode *mode;\n   int nbEBands;\n   int overlap;\n   int start;\n   int loss_count;\n   int noise_based;\n   const opus_int16 *eBands;\n   SAVE_STACK;\n\n   mode = st->mode;\n   nbEBands = mode->nbEBands;\n   overlap = mode->overlap;\n   eBands = mode->eBands;\n\n   c=0; do {\n      decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap);\n      out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N;\n   } while (++c<C);\n   lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*C);\n   oldBandE = lpc+C*LPC_ORDER;\n   oldLogE = oldBandE + 2*nbEBands;\n   oldLogE2 = oldLogE + 2*nbEBands;\n   backgroundLogE = oldLogE2  + 2*nbEBands;\n\n   loss_count = st->loss_count;\n   start = st->start;\n   noise_based = loss_count >= 5 || start != 0;\n   if (noise_based)\n   {\n      /* Noise-based PLC/CNG */\n#ifdef NORM_ALIASING_HACK\n      celt_norm *X;\n#else\n      VARDECL(celt_norm, X);\n#endif\n      opus_uint32 seed;\n      int end;\n      int effEnd;\n      opus_val16 decay;\n      end = st->end;\n      effEnd = IMAX(start, IMIN(end, mode->effEBands));\n\n#ifdef NORM_ALIASING_HACK\n      /* This is an ugly hack that breaks aliasing rules and would be easily broken,\n         but it saves almost 4kB of stack. */\n      X = (celt_norm*)(out_syn[C-1]+overlap/2);\n#else\n      ALLOC(X, C*N, celt_norm);   /**< Interleaved normalised MDCTs */\n#endif\n\n      /* Energy decay */\n      decay = loss_count==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT);\n      c=0; do\n      {\n         for (i=start;i<end;i++)\n            oldBandE[c*nbEBands+i] = MAX16(backgroundLogE[c*nbEBands+i], oldBandE[c*nbEBands+i] - decay);\n      } while (++c<C);\n      seed = st->rng;\n      for (c=0;c<C;c++)\n      {\n         for (i=start;i<effEnd;i++)\n         {\n            int j;\n            int boffs;\n            int blen;\n            boffs = N*c+(eBands[i]<<LM);\n            blen = (eBands[i+1]-eBands[i])<<LM;\n            for (j=0;j<blen;j++)\n            {\n               seed = celt_lcg_rand(seed);\n               X[boffs+j] = (celt_norm)((opus_int32)seed>>20);\n            }\n            renormalise_vector(X+boffs, blen, Q15ONE, st->arch);\n         }\n      }\n      st->rng = seed;\n\n      c=0; do {\n         OPUS_MOVE(decode_mem[c], decode_mem[c]+N,\n               DECODE_BUFFER_SIZE-N+(overlap>>1));\n      } while (++c<C);\n\n      celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, C, 0, LM, st->downsample, 0, st->arch);\n   } else {\n      /* Pitch-based PLC */\n      const opus_val16 *window;\n      opus_val16 fade = Q15ONE;\n      int pitch_index;\n      VARDECL(opus_val32, etmp);\n      VARDECL(opus_val16, exc);\n\n      if (loss_count == 0)\n      {\n         st->last_pitch_index = pitch_index = celt_plc_pitch_search(decode_mem, C, st->arch);\n      } else {\n         pitch_index = st->last_pitch_index;\n         fade = QCONST16(.8f,15);\n      }\n\n      ALLOC(etmp, overlap, opus_val32);\n      ALLOC(exc, MAX_PERIOD, opus_val16);\n      window = mode->window;\n      c=0; do {\n         opus_val16 decay;\n         opus_val16 attenuation;\n         opus_val32 S1=0;\n         celt_sig *buf;\n         int extrapolation_offset;\n         int extrapolation_len;\n         int exc_length;\n         int j;\n\n         buf = decode_mem[c];\n         for (i=0;i<MAX_PERIOD;i++) {\n            exc[i] = ROUND16(buf[DECODE_BUFFER_SIZE-MAX_PERIOD+i], SIG_SHIFT);\n         }\n\n         if (loss_count == 0)\n         {\n            opus_val32 ac[LPC_ORDER+1];\n            /* Compute LPC coefficients for the last MAX_PERIOD samples before\n               the first loss so we can work in the excitation-filter domain. */\n            _celt_autocorr(exc, ac, window, overlap,\n                   LPC_ORDER, MAX_PERIOD, st->arch);\n            /* Add a noise floor of -40 dB. */\n#ifdef FIXED_POINT\n            ac[0] += SHR32(ac[0],13);\n#else\n            ac[0] *= 1.0001f;\n#endif\n            /* Use lag windowing to stabilize the Levinson-Durbin recursion. */\n            for (i=1;i<=LPC_ORDER;i++)\n            {\n               /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/\n#ifdef FIXED_POINT\n               ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);\n#else\n               ac[i] -= ac[i]*(0.008f*0.008f)*i*i;\n#endif\n            }\n            _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);\n         }\n         /* We want the excitation for 2 pitch periods in order to look for a\n            decaying signal, but we can't get more than MAX_PERIOD. */\n         exc_length = IMIN(2*pitch_index, MAX_PERIOD);\n         /* Initialize the LPC history with the samples just before the start\n            of the region for which we're computing the excitation. */\n         {\n            opus_val16 lpc_mem[LPC_ORDER];\n            for (i=0;i<LPC_ORDER;i++)\n            {\n               lpc_mem[i] =\n                     ROUND16(buf[DECODE_BUFFER_SIZE-exc_length-1-i], SIG_SHIFT);\n            }\n            /* Compute the excitation for exc_length samples before the loss. */\n            celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER,\n                  exc+MAX_PERIOD-exc_length, exc_length, LPC_ORDER, lpc_mem, st->arch);\n         }\n\n         /* Check if the waveform is decaying, and if so how fast.\n            We do this to avoid adding energy when concealing in a segment\n            with decaying energy. */\n         {\n            opus_val32 E1=1, E2=1;\n            int decay_length;\n#ifdef FIXED_POINT\n            int shift = IMAX(0,2*celt_zlog2(celt_maxabs16(&exc[MAX_PERIOD-exc_length], exc_length))-20);\n#endif\n            decay_length = exc_length>>1;\n            for (i=0;i<decay_length;i++)\n            {\n               opus_val16 e;\n               e = exc[MAX_PERIOD-decay_length+i];\n               E1 += SHR32(MULT16_16(e, e), shift);\n               e = exc[MAX_PERIOD-2*decay_length+i];\n               E2 += SHR32(MULT16_16(e, e), shift);\n            }\n            E1 = MIN32(E1, E2);\n            decay = celt_sqrt(frac_div32(SHR32(E1, 1), E2));\n         }\n\n         /* Move the decoder memory one frame to the left to give us room to\n            add the data for the new frame. We ignore the overlap that extends\n            past the end of the buffer, because we aren't going to use it. */\n         OPUS_MOVE(buf, buf+N, DECODE_BUFFER_SIZE-N);\n\n         /* Extrapolate from the end of the excitation with a period of\n            \"pitch_index\", scaling down each period by an additional factor of\n            \"decay\". */\n         extrapolation_offset = MAX_PERIOD-pitch_index;\n         /* We need to extrapolate enough samples to cover a complete MDCT\n            window (including overlap/2 samples on both sides). */\n         extrapolation_len = N+overlap;\n         /* We also apply fading if this is not the first loss. */\n         attenuation = MULT16_16_Q15(fade, decay);\n         for (i=j=0;i<extrapolation_len;i++,j++)\n         {\n            opus_val16 tmp;\n            if (j >= pitch_index) {\n               j -= pitch_index;\n               attenuation = MULT16_16_Q15(attenuation, decay);\n            }\n            buf[DECODE_BUFFER_SIZE-N+i] =\n                  SHL32(EXTEND32(MULT16_16_Q15(attenuation,\n                        exc[extrapolation_offset+j])), SIG_SHIFT);\n            /* Compute the energy of the previously decoded signal whose\n               excitation we're copying. */\n            tmp = ROUND16(\n                  buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j],\n                  SIG_SHIFT);\n            S1 += SHR32(MULT16_16(tmp, tmp), 8);\n         }\n\n         {\n            opus_val16 lpc_mem[LPC_ORDER];\n            /* Copy the last decoded samples (prior to the overlap region) to\n               synthesis filter memory so we can have a continuous signal. */\n            for (i=0;i<LPC_ORDER;i++)\n               lpc_mem[i] = ROUND16(buf[DECODE_BUFFER_SIZE-N-1-i], SIG_SHIFT);\n            /* Apply the synthesis filter to convert the excitation back into\n               the signal domain. */\n            celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER,\n                  buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER,\n                  lpc_mem, st->arch);\n         }\n\n         /* Check if the synthesis energy is higher than expected, which can\n            happen with the signal changes during our window. If so,\n            attenuate. */\n         {\n            opus_val32 S2=0;\n            for (i=0;i<extrapolation_len;i++)\n            {\n               opus_val16 tmp = ROUND16(buf[DECODE_BUFFER_SIZE-N+i], SIG_SHIFT);\n               S2 += SHR32(MULT16_16(tmp, tmp), 8);\n            }\n            /* This checks for an \"explosion\" in the synthesis. */\n#ifdef FIXED_POINT\n            if (!(S1 > SHR32(S2,2)))\n#else\n            /* The float test is written this way to catch NaNs in the output\n               of the IIR filter at the same time. */\n            if (!(S1 > 0.2f*S2))\n#endif\n            {\n               for (i=0;i<extrapolation_len;i++)\n                  buf[DECODE_BUFFER_SIZE-N+i] = 0;\n            } else if (S1 < S2)\n            {\n               opus_val16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));\n               for (i=0;i<overlap;i++)\n               {\n                  opus_val16 tmp_g = Q15ONE\n                        - MULT16_16_Q15(window[i], Q15ONE-ratio);\n                  buf[DECODE_BUFFER_SIZE-N+i] =\n                        MULT16_32_Q15(tmp_g, buf[DECODE_BUFFER_SIZE-N+i]);\n               }\n               for (i=overlap;i<extrapolation_len;i++)\n               {\n                  buf[DECODE_BUFFER_SIZE-N+i] =\n                        MULT16_32_Q15(ratio, buf[DECODE_BUFFER_SIZE-N+i]);\n               }\n            }\n         }\n\n         /* Apply the pre-filter to the MDCT overlap for the next frame because\n            the post-filter will be re-applied in the decoder after the MDCT\n            overlap. */\n         comb_filter(etmp, buf+DECODE_BUFFER_SIZE,\n              st->postfilter_period, st->postfilter_period, overlap,\n              -st->postfilter_gain, -st->postfilter_gain,\n              st->postfilter_tapset, st->postfilter_tapset, NULL, 0, st->arch);\n\n         /* Simulate TDAC on the concealed audio so that it blends with the\n            MDCT of the next frame. */\n         for (i=0;i<overlap/2;i++)\n         {\n            buf[DECODE_BUFFER_SIZE+i] =\n               MULT16_32_Q15(window[i], etmp[overlap-1-i])\n               + MULT16_32_Q15(window[overlap-i-1], etmp[i]);\n         }\n      } while (++c<C);\n   }\n\n   st->loss_count = loss_count+1;\n\n   RESTORE_STACK;\n}\n\nint celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data,\n      int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum)\n{\n   int c, i, N;\n   int spread_decision;\n   opus_int32 bits;\n   ec_dec _dec;\n#ifdef NORM_ALIASING_HACK\n   celt_norm *X;\n#else\n   VARDECL(celt_norm, X);\n#endif\n   VARDECL(int, fine_quant);\n   VARDECL(int, pulses);\n   VARDECL(int, cap);\n   VARDECL(int, offsets);\n   VARDECL(int, fine_priority);\n   VARDECL(int, tf_res);\n   VARDECL(unsigned char, collapse_masks);\n   celt_sig *decode_mem[2];\n   celt_sig *out_syn[2];\n   opus_val16 *lpc;\n   opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;\n\n   int shortBlocks;\n   int isTransient;\n   int intra_ener;\n   const int CC = st->channels;\n   int LM, M;\n   int start;\n   int end;\n   int effEnd;\n   int codedBands;\n   int alloc_trim;\n   int postfilter_pitch;\n   opus_val16 postfilter_gain;\n   int intensity=0;\n   int dual_stereo=0;\n   opus_int32 total_bits;\n   opus_int32 balance;\n   opus_int32 tell;\n   int dynalloc_logp;\n   int postfilter_tapset;\n   int anti_collapse_rsv;\n   int anti_collapse_on=0;\n   int silence;\n   int C = st->stream_channels;\n   const OpusCustomMode *mode;\n   int nbEBands;\n   int overlap;\n   const opus_int16 *eBands;\n   ALLOC_STACK;\n\n   mode = st->mode;\n   nbEBands = mode->nbEBands;\n   overlap = mode->overlap;\n   eBands = mode->eBands;\n   start = st->start;\n   end = st->end;\n   frame_size *= st->downsample;\n\n   lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*CC);\n   oldBandE = lpc+CC*LPC_ORDER;\n   oldLogE = oldBandE + 2*nbEBands;\n   oldLogE2 = oldLogE + 2*nbEBands;\n   backgroundLogE = oldLogE2  + 2*nbEBands;\n\n#ifdef CUSTOM_MODES\n   if (st->signalling && data!=NULL)\n   {\n      int data0=data[0];\n      /* Convert \"standard mode\" to Opus header */\n      if (mode->Fs==48000 && mode->shortMdctSize==120)\n      {\n         data0 = fromOpus(data0);\n         if (data0<0)\n            return OPUS_INVALID_PACKET;\n      }\n      st->end = end = IMAX(1, mode->effEBands-2*(data0>>5));\n      LM = (data0>>3)&0x3;\n      C = 1 + ((data0>>2)&0x1);\n      data++;\n      len--;\n      if (LM>mode->maxLM)\n         return OPUS_INVALID_PACKET;\n      if (frame_size < mode->shortMdctSize<<LM)\n         return OPUS_BUFFER_TOO_SMALL;\n      else\n         frame_size = mode->shortMdctSize<<LM;\n   } else {\n#else\n   {\n#endif\n      for (LM=0;LM<=mode->maxLM;LM++)\n         if (mode->shortMdctSize<<LM==frame_size)\n            break;\n      if (LM>mode->maxLM)\n         return OPUS_BAD_ARG;\n   }\n   M=1<<LM;\n\n   if (len<0 || len>1275 || pcm==NULL)\n      return OPUS_BAD_ARG;\n\n   N = M*mode->shortMdctSize;\n   c=0; do {\n      decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap);\n      out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N;\n   } while (++c<CC);\n\n   effEnd = end;\n   if (effEnd > mode->effEBands)\n      effEnd = mode->effEBands;\n\n   if (data == NULL || len<=1)\n   {\n      celt_decode_lost(st, N, LM);\n      deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum);\n      RESTORE_STACK;\n      return frame_size/st->downsample;\n   }\n\n   if (dec == NULL)\n   {\n      ec_dec_init(&_dec,(unsigned char*)data,len);\n      dec = &_dec;\n   }\n\n   if (C==1)\n   {\n      for (i=0;i<nbEBands;i++)\n         oldBandE[i]=MAX16(oldBandE[i],oldBandE[nbEBands+i]);\n   }\n\n   total_bits = len*8;\n   tell = ec_tell(dec);\n\n   if (tell >= total_bits)\n      silence = 1;\n   else if (tell==1)\n      silence = ec_dec_bit_logp(dec, 15);\n   else\n      silence = 0;\n   if (silence)\n   {\n      /* Pretend we've read all the remaining bits */\n      tell = len*8;\n      dec->nbits_total+=tell-ec_tell(dec);\n   }\n\n   postfilter_gain = 0;\n   postfilter_pitch = 0;\n   postfilter_tapset = 0;\n   if (start==0 && tell+16 <= total_bits)\n   {\n      if(ec_dec_bit_logp(dec, 1))\n      {\n         int qg, octave;\n         octave = ec_dec_uint(dec, 6);\n         postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave)-1;\n         qg = ec_dec_bits(dec, 3);\n         if (ec_tell(dec)+2<=total_bits)\n            postfilter_tapset = ec_dec_icdf(dec, tapset_icdf, 2);\n         postfilter_gain = QCONST16(.09375f,15)*(qg+1);\n      }\n      tell = ec_tell(dec);\n   }\n\n   if (LM > 0 && tell+3 <= total_bits)\n   {\n      isTransient = ec_dec_bit_logp(dec, 3);\n      tell = ec_tell(dec);\n   }\n   else\n      isTransient = 0;\n\n   if (isTransient)\n      shortBlocks = M;\n   else\n      shortBlocks = 0;\n\n   /* Decode the global flags (first symbols in the stream) */\n   intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0;\n   /* Get band energies */\n   unquant_coarse_energy(mode, start, end, oldBandE,\n         intra_ener, dec, C, LM);\n\n   ALLOC(tf_res, nbEBands, int);\n   tf_decode(start, end, isTransient, tf_res, LM, dec);\n\n   tell = ec_tell(dec);\n   spread_decision = SPREAD_NORMAL;\n   if (tell+4 <= total_bits)\n      spread_decision = ec_dec_icdf(dec, spread_icdf, 5);\n\n   ALLOC(cap, nbEBands, int);\n\n   init_caps(mode,cap,LM,C);\n\n   ALLOC(offsets, nbEBands, int);\n\n   dynalloc_logp = 6;\n   total_bits<<=BITRES;\n   tell = ec_tell_frac(dec);\n   for (i=start;i<end;i++)\n   {\n      int width, quanta;\n      int dynalloc_loop_logp;\n      int boost;\n      width = C*(eBands[i+1]-eBands[i])<<LM;\n      /* quanta is 6 bits, but no more than 1 bit/sample\n         and no less than 1/8 bit/sample */\n      quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));\n      dynalloc_loop_logp = dynalloc_logp;\n      boost = 0;\n      while (tell+(dynalloc_loop_logp<<BITRES) < total_bits && boost < cap[i])\n      {\n         int flag;\n         flag = ec_dec_bit_logp(dec, dynalloc_loop_logp);\n         tell = ec_tell_frac(dec);\n         if (!flag)\n            break;\n         boost += quanta;\n         total_bits -= quanta;\n         dynalloc_loop_logp = 1;\n      }\n      offsets[i] = boost;\n      /* Making dynalloc more likely */\n      if (boost>0)\n         dynalloc_logp = IMAX(2, dynalloc_logp-1);\n   }\n\n   ALLOC(fine_quant, nbEBands, int);\n   alloc_trim = tell+(6<<BITRES) <= total_bits ?\n         ec_dec_icdf(dec, trim_icdf, 7) : 5;\n\n   bits = (((opus_int32)len*8)<<BITRES) - ec_tell_frac(dec) - 1;\n   anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;\n   bits -= anti_collapse_rsv;\n\n   ALLOC(pulses, nbEBands, int);\n   ALLOC(fine_priority, nbEBands, int);\n\n   codedBands = compute_allocation(mode, start, end, offsets, cap,\n         alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,\n         fine_quant, fine_priority, C, LM, dec, 0, 0, 0);\n\n   unquant_fine_energy(mode, start, end, oldBandE, fine_quant, dec, C);\n\n   c=0; do {\n      OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap/2);\n   } while (++c<CC);\n\n   /* Decode fixed codebook */\n   ALLOC(collapse_masks, C*nbEBands, unsigned char);\n\n#ifdef NORM_ALIASING_HACK\n   /* This is an ugly hack that breaks aliasing rules and would be easily broken,\n      but it saves almost 4kB of stack. */\n   X = (celt_norm*)(out_syn[CC-1]+overlap/2);\n#else\n   ALLOC(X, C*N, celt_norm);   /**< Interleaved normalised MDCTs */\n#endif\n\n   quant_all_bands(0, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,\n         NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res,\n         len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, st->arch);\n\n   if (anti_collapse_rsv > 0)\n   {\n      anti_collapse_on = ec_dec_bits(dec, 1);\n   }\n\n   unquant_energy_finalise(mode, start, end, oldBandE,\n         fine_quant, fine_priority, len*8-ec_tell(dec), dec, C);\n\n   if (anti_collapse_on)\n      anti_collapse(mode, X, collapse_masks, LM, C, N,\n            start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng, st->arch);\n\n   if (silence)\n   {\n      for (i=0;i<C*nbEBands;i++)\n         oldBandE[i] = -QCONST16(28.f,DB_SHIFT);\n   }\n\n   celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd,\n                  C, CC, isTransient, LM, st->downsample, silence, st->arch);\n\n   c=0; do {\n      st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD);\n      st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD);\n      comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, mode->shortMdctSize,\n            st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset,\n            mode->window, overlap, st->arch);\n      if (LM!=0)\n         comb_filter(out_syn[c]+mode->shortMdctSize, out_syn[c]+mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-mode->shortMdctSize,\n               st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset,\n               mode->window, overlap, st->arch);\n\n   } while (++c<CC);\n   st->postfilter_period_old = st->postfilter_period;\n   st->postfilter_gain_old = st->postfilter_gain;\n   st->postfilter_tapset_old = st->postfilter_tapset;\n   st->postfilter_period = postfilter_pitch;\n   st->postfilter_gain = postfilter_gain;\n   st->postfilter_tapset = postfilter_tapset;\n   if (LM!=0)\n   {\n      st->postfilter_period_old = st->postfilter_period;\n      st->postfilter_gain_old = st->postfilter_gain;\n      st->postfilter_tapset_old = st->postfilter_tapset;\n   }\n\n   if (C==1)\n      OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands);\n\n   /* In case start or end were to change */\n   if (!isTransient)\n   {\n      opus_val16 max_background_increase;\n      OPUS_COPY(oldLogE2, oldLogE, 2*nbEBands);\n      OPUS_COPY(oldLogE, oldBandE, 2*nbEBands);\n      /* In normal circumstances, we only allow the noise floor to increase by\n         up to 2.4 dB/second, but when we're in DTX, we allow up to 6 dB\n         increase for each update.*/\n      if (st->loss_count < 10)\n         max_background_increase = M*QCONST16(0.001f,DB_SHIFT);\n      else\n         max_background_increase = QCONST16(1.f,DB_SHIFT);\n      for (i=0;i<2*nbEBands;i++)\n         backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]);\n   } else {\n      for (i=0;i<2*nbEBands;i++)\n         oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);\n   }\n   c=0; do\n   {\n      for (i=0;i<start;i++)\n      {\n         oldBandE[c*nbEBands+i]=0;\n         oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);\n      }\n      for (i=end;i<nbEBands;i++)\n      {\n         oldBandE[c*nbEBands+i]=0;\n         oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);\n      }\n   } while (++c<2);\n   st->rng = dec->rng;\n\n   deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum);\n   st->loss_count = 0;\n   RESTORE_STACK;\n   if (ec_tell(dec) > 8*len)\n      return OPUS_INTERNAL_ERROR;\n   if(ec_get_error(dec))\n      st->error = 1;\n   return frame_size/st->downsample;\n}\n\n\n#ifdef CUSTOM_MODES\n\n#ifdef FIXED_POINT\nint opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)\n{\n   return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0);\n}\n\n#ifndef DISABLE_FLOAT_API\nint opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)\n{\n   int j, ret, C, N;\n   VARDECL(opus_int16, out);\n   ALLOC_STACK;\n\n   if (pcm==NULL)\n      return OPUS_BAD_ARG;\n\n   C = st->channels;\n   N = frame_size;\n\n   ALLOC(out, C*N, opus_int16);\n   ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);\n   if (ret>0)\n      for (j=0;j<C*ret;j++)\n         pcm[j]=out[j]*(1.f/32768.f);\n\n   RESTORE_STACK;\n   return ret;\n}\n#endif /* DISABLE_FLOAT_API */\n\n#else\n\nint opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)\n{\n   return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0);\n}\n\nint opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)\n{\n   int j, ret, C, N;\n   VARDECL(celt_sig, out);\n   ALLOC_STACK;\n\n   if (pcm==NULL)\n      return OPUS_BAD_ARG;\n\n   C = st->channels;\n   N = frame_size;\n   ALLOC(out, C*N, celt_sig);\n\n   ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);\n\n   if (ret>0)\n      for (j=0;j<C*ret;j++)\n         pcm[j] = FLOAT2INT16 (out[j]);\n\n   RESTORE_STACK;\n   return ret;\n}\n\n#endif\n#endif /* CUSTOM_MODES */\n\nint opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)\n{\n   va_list ap;\n\n   va_start(ap, request);\n   switch (request)\n   {\n      case CELT_SET_START_BAND_REQUEST:\n      {\n         opus_int32 value = va_arg(ap, opus_int32);\n         if (value<0 || value>=st->mode->nbEBands)\n            goto bad_arg;\n         st->start = value;\n      }\n      break;\n      case CELT_SET_END_BAND_REQUEST:\n      {\n         opus_int32 value = va_arg(ap, opus_int32);\n         if (value<1 || value>st->mode->nbEBands)\n            goto bad_arg;\n         st->end = value;\n      }\n      break;\n      case CELT_SET_CHANNELS_REQUEST:\n      {\n         opus_int32 value = va_arg(ap, opus_int32);\n         if (value<1 || value>2)\n            goto bad_arg;\n         st->stream_channels = value;\n      }\n      break;\n      case CELT_GET_AND_CLEAR_ERROR_REQUEST:\n      {\n         opus_int32 *value = va_arg(ap, opus_int32*);\n         if (value==NULL)\n            goto bad_arg;\n         *value=st->error;\n         st->error = 0;\n      }\n      break;\n      case OPUS_GET_LOOKAHEAD_REQUEST:\n      {\n         opus_int32 *value = va_arg(ap, opus_int32*);\n         if (value==NULL)\n            goto bad_arg;\n         *value = st->overlap/st->downsample;\n      }\n      break;\n      case OPUS_RESET_STATE:\n      {\n         int i;\n         opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2;\n         lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels);\n         oldBandE = lpc+st->channels*LPC_ORDER;\n         oldLogE = oldBandE + 2*st->mode->nbEBands;\n         oldLogE2 = oldLogE + 2*st->mode->nbEBands;\n         OPUS_CLEAR((char*)&st->DECODER_RESET_START,\n               opus_custom_decoder_get_size(st->mode, st->channels)-\n               ((char*)&st->DECODER_RESET_START - (char*)st));\n         for (i=0;i<2*st->mode->nbEBands;i++)\n            oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);\n      }\n      break;\n      case OPUS_GET_PITCH_REQUEST:\n      {\n         opus_int32 *value = va_arg(ap, opus_int32*);\n         if (value==NULL)\n            goto bad_arg;\n         *value = st->postfilter_period;\n      }\n      break;\n      case CELT_GET_MODE_REQUEST:\n      {\n         const CELTMode ** value = va_arg(ap, const CELTMode**);\n         if (value==0)\n            goto bad_arg;\n         *value=st->mode;\n      }\n      break;\n      case CELT_SET_SIGNALLING_REQUEST:\n      {\n         opus_int32 value = va_arg(ap, opus_int32);\n         st->signalling = value;\n      }\n      break;\n      case OPUS_GET_FINAL_RANGE_REQUEST:\n      {\n         opus_uint32 * value = va_arg(ap, opus_uint32 *);\n         if (value==0)\n            goto bad_arg;\n         *value=st->rng;\n      }\n      break;\n      default:\n         goto bad_request;\n   }\n   va_end(ap);\n   return OPUS_OK;\nbad_arg:\n   va_end(ap);\n   return OPUS_BAD_ARG;\nbad_request:\n      va_end(ap);\n  return OPUS_UNIMPLEMENTED;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/celt_encoder.c",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2010 Xiph.Org Foundation\n   Copyright (c) 2008 Gregory Maxwell\n   Written by Jean-Marc Valin and Gregory Maxwell */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#define CELT_ENCODER_C\n\n#include \"cpu_support.h\"\n#include \"os_support.h\"\n#include \"mdct.h\"\n#include <math.h>\n#include \"celt.h\"\n#include \"pitch.h\"\n#include \"bands.h\"\n#include \"modes.h\"\n#include \"entcode.h\"\n#include \"quant_bands.h\"\n#include \"rate.h\"\n#include \"stack_alloc.h\"\n#include \"mathops.h\"\n#include \"float_cast.h\"\n#include <stdarg.h>\n#include \"celt_lpc.h\"\n#include \"vq.h\"\n\n\n/** Encoder state\n @brief Encoder state\n */\nstruct OpusCustomEncoder {\n   const OpusCustomMode *mode;     /**< Mode used by the encoder */\n   int channels;\n   int stream_channels;\n\n   int force_intra;\n   int clip;\n   int disable_pf;\n   int complexity;\n   int upsample;\n   int start, end;\n\n   opus_int32 bitrate;\n   int vbr;\n   int signalling;\n   int constrained_vbr;      /* If zero, VBR can do whatever it likes with the rate */\n   int loss_rate;\n   int lsb_depth;\n   int variable_duration;\n   int lfe;\n   int arch;\n\n   /* Everything beyond this point gets cleared on a reset */\n#define ENCODER_RESET_START rng\n\n   opus_uint32 rng;\n   int spread_decision;\n   opus_val32 delayedIntra;\n   int tonal_average;\n   int lastCodedBands;\n   int hf_average;\n   int tapset_decision;\n\n   int prefilter_period;\n   opus_val16 prefilter_gain;\n   int prefilter_tapset;\n#ifdef RESYNTH\n   int prefilter_period_old;\n   opus_val16 prefilter_gain_old;\n   int prefilter_tapset_old;\n#endif\n   int consec_transient;\n   AnalysisInfo analysis;\n\n   opus_val32 preemph_memE[2];\n   opus_val32 preemph_memD[2];\n\n   /* VBR-related parameters */\n   opus_int32 vbr_reservoir;\n   opus_int32 vbr_drift;\n   opus_int32 vbr_offset;\n   opus_int32 vbr_count;\n   opus_val32 overlap_max;\n   opus_val16 stereo_saving;\n   int intensity;\n   opus_val16 *energy_mask;\n   opus_val16 spec_avg;\n\n#ifdef RESYNTH\n   /* +MAX_PERIOD/2 to make space for overlap */\n   celt_sig syn_mem[2][2*MAX_PERIOD+MAX_PERIOD/2];\n#endif\n\n   celt_sig in_mem[1]; /* Size = channels*mode->overlap */\n   /* celt_sig prefilter_mem[],  Size = channels*COMBFILTER_MAXPERIOD */\n   /* opus_val16 oldBandE[],     Size = channels*mode->nbEBands */\n   /* opus_val16 oldLogE[],      Size = channels*mode->nbEBands */\n   /* opus_val16 oldLogE2[],     Size = channels*mode->nbEBands */\n};\n\nint celt_encoder_get_size(int channels)\n{\n   CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);\n   return opus_custom_encoder_get_size(mode, channels);\n}\n\nOPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int channels)\n{\n   int size = sizeof(struct CELTEncoder)\n         + (channels*mode->overlap-1)*sizeof(celt_sig)    /* celt_sig in_mem[channels*mode->overlap]; */\n         + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig) /* celt_sig prefilter_mem[channels*COMBFILTER_MAXPERIOD]; */\n         + 3*channels*mode->nbEBands*sizeof(opus_val16);  /* opus_val16 oldBandE[channels*mode->nbEBands]; */\n                                                          /* opus_val16 oldLogE[channels*mode->nbEBands]; */\n                                                          /* opus_val16 oldLogE2[channels*mode->nbEBands]; */\n   return size;\n}\n\n#ifdef CUSTOM_MODES\nCELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int *error)\n{\n   int ret;\n   CELTEncoder *st = (CELTEncoder *)opus_alloc(opus_custom_encoder_get_size(mode, channels));\n   /* init will handle the NULL case */\n   ret = opus_custom_encoder_init(st, mode, channels);\n   if (ret != OPUS_OK)\n   {\n      opus_custom_encoder_destroy(st);\n      st = NULL;\n   }\n   if (error)\n      *error = ret;\n   return st;\n}\n#endif /* CUSTOM_MODES */\n\nstatic int opus_custom_encoder_init_arch(CELTEncoder *st, const CELTMode *mode,\n                                         int channels, int arch)\n{\n   if (channels < 0 || channels > 2)\n      return OPUS_BAD_ARG;\n\n   if (st==NULL || mode==NULL)\n      return OPUS_ALLOC_FAIL;\n\n   OPUS_CLEAR((char*)st, opus_custom_encoder_get_size(mode, channels));\n\n   st->mode = mode;\n   st->stream_channels = st->channels = channels;\n\n   st->upsample = 1;\n   st->start = 0;\n   st->end = st->mode->effEBands;\n   st->signalling = 1;\n\n   st->arch = arch;\n\n   st->constrained_vbr = 1;\n   st->clip = 1;\n\n   st->bitrate = OPUS_BITRATE_MAX;\n   st->vbr = 0;\n   st->force_intra  = 0;\n   st->complexity = 5;\n   st->lsb_depth=24;\n\n   opus_custom_encoder_ctl(st, OPUS_RESET_STATE);\n\n   return OPUS_OK;\n}\n\n#ifdef CUSTOM_MODES\nint opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels)\n{\n   return opus_custom_encoder_init_arch(st, mode, channels, opus_select_arch());\n}\n#endif\n\nint celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels,\n                      int arch)\n{\n   int ret;\n   ret = opus_custom_encoder_init_arch(st,\n           opus_custom_mode_create(48000, 960, NULL), channels, arch);\n   if (ret != OPUS_OK)\n      return ret;\n   st->upsample = resampling_factor(sampling_rate);\n   return OPUS_OK;\n}\n\n#ifdef CUSTOM_MODES\nvoid opus_custom_encoder_destroy(CELTEncoder *st)\n{\n   opus_free(st);\n}\n#endif /* CUSTOM_MODES */\n\n\nstatic int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int C,\n                              opus_val16 *tf_estimate, int *tf_chan)\n{\n   int i;\n   VARDECL(opus_val16, tmp);\n   opus_val32 mem0,mem1;\n   int is_transient = 0;\n   opus_int32 mask_metric = 0;\n   int c;\n   opus_val16 tf_max;\n   int len2;\n   /* Table of 6*64/x, trained on real data to minimize the average error */\n   static const unsigned char inv_table[128] = {\n         255,255,156,110, 86, 70, 59, 51, 45, 40, 37, 33, 31, 28, 26, 25,\n          23, 22, 21, 20, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,\n          12, 12, 11, 11, 11, 10, 10, 10,  9,  9,  9,  9,  9,  9,  8,  8,\n           8,  8,  8,  7,  7,  7,  7,  7,  7,  6,  6,  6,  6,  6,  6,  6,\n           6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  5,  5,  5,  5,  5,  5,\n           5,  5,  5,  5,  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n           4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  3,  3,\n           3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  2,\n   };\n   SAVE_STACK;\n   ALLOC(tmp, len, opus_val16);\n\n   len2=len/2;\n   for (c=0;c<C;c++)\n   {\n      opus_val32 mean;\n      opus_int32 unmask=0;\n      opus_val32 norm;\n      opus_val16 maxE;\n      mem0=0;\n      mem1=0;\n      /* High-pass filter: (1 - 2*z^-1 + z^-2) / (1 - z^-1 + .5*z^-2) */\n      for (i=0;i<len;i++)\n      {\n         opus_val32 x,y;\n         x = SHR32(in[i+c*len],SIG_SHIFT);\n         y = ADD32(mem0, x);\n#ifdef FIXED_POINT\n         mem0 = mem1 + y - SHL32(x,1);\n         mem1 = x - SHR32(y,1);\n#else\n         mem0 = mem1 + y - 2*x;\n         mem1 = x - .5f*y;\n#endif\n         tmp[i] = EXTRACT16(SHR32(y,2));\n         /*printf(\"%f \", tmp[i]);*/\n      }\n      /*printf(\"\\n\");*/\n      /* First few samples are bad because we don't propagate the memory */\n      OPUS_CLEAR(tmp, 12);\n\n#ifdef FIXED_POINT\n      /* Normalize tmp to max range */\n      {\n         int shift=0;\n         shift = 14-celt_ilog2(1+celt_maxabs16(tmp, len));\n         if (shift!=0)\n         {\n            for (i=0;i<len;i++)\n               tmp[i] = SHL16(tmp[i], shift);\n         }\n      }\n#endif\n\n      mean=0;\n      mem0=0;\n      /* Grouping by two to reduce complexity */\n      /* Forward pass to compute the post-echo threshold*/\n      for (i=0;i<len2;i++)\n      {\n         opus_val16 x2 = PSHR32(MULT16_16(tmp[2*i],tmp[2*i]) + MULT16_16(tmp[2*i+1],tmp[2*i+1]),16);\n         mean += x2;\n#ifdef FIXED_POINT\n         /* FIXME: Use PSHR16() instead */\n         tmp[i] = mem0 + PSHR32(x2-mem0,4);\n#else\n         tmp[i] = mem0 + MULT16_16_P15(QCONST16(.0625f,15),x2-mem0);\n#endif\n         mem0 = tmp[i];\n      }\n\n      mem0=0;\n      maxE=0;\n      /* Backward pass to compute the pre-echo threshold */\n      for (i=len2-1;i>=0;i--)\n      {\n#ifdef FIXED_POINT\n         /* FIXME: Use PSHR16() instead */\n         tmp[i] = mem0 + PSHR32(tmp[i]-mem0,3);\n#else\n         tmp[i] = mem0 + MULT16_16_P15(QCONST16(0.125f,15),tmp[i]-mem0);\n#endif\n         mem0 = tmp[i];\n         maxE = MAX16(maxE, mem0);\n      }\n      /*for (i=0;i<len2;i++)printf(\"%f \", tmp[i]/mean);printf(\"\\n\");*/\n\n      /* Compute the ratio of the \"frame energy\" over the harmonic mean of the energy.\n         This essentially corresponds to a bitrate-normalized temporal noise-to-mask\n         ratio */\n\n      /* As a compromise with the old transient detector, frame energy is the\n         geometric mean of the energy and half the max */\n#ifdef FIXED_POINT\n      /* Costs two sqrt() to avoid overflows */\n      mean = MULT16_16(celt_sqrt(mean), celt_sqrt(MULT16_16(maxE,len2>>1)));\n#else\n      mean = celt_sqrt(mean * maxE*.5*len2);\n#endif\n      /* Inverse of the mean energy in Q15+6 */\n      norm = SHL32(EXTEND32(len2),6+14)/ADD32(EPSILON,SHR32(mean,1));\n      /* Compute harmonic mean discarding the unreliable boundaries\n         The data is smooth, so we only take 1/4th of the samples */\n      unmask=0;\n      for (i=12;i<len2-5;i+=4)\n      {\n         int id;\n#ifdef FIXED_POINT\n         id = MAX32(0,MIN32(127,MULT16_32_Q15(tmp[i]+EPSILON,norm))); /* Do not round to nearest */\n#else\n         id = (int)MAX32(0,MIN32(127,floor(64*norm*(tmp[i]+EPSILON)))); /* Do not round to nearest */\n#endif\n         unmask += inv_table[id];\n      }\n      /*printf(\"%d\\n\", unmask);*/\n      /* Normalize, compensate for the 1/4th of the sample and the factor of 6 in the inverse table */\n      unmask = 64*unmask*4/(6*(len2-17));\n      if (unmask>mask_metric)\n      {\n         *tf_chan = c;\n         mask_metric = unmask;\n      }\n   }\n   is_transient = mask_metric>200;\n\n   /* Arbitrary metric for VBR boost */\n   tf_max = MAX16(0,celt_sqrt(27*mask_metric)-42);\n   /* *tf_estimate = 1 + MIN16(1, sqrt(MAX16(0, tf_max-30))/20); */\n   *tf_estimate = celt_sqrt(MAX32(0, SHL32(MULT16_16(QCONST16(0.0069,14),MIN16(163,tf_max)),14)-QCONST32(0.139,28)));\n   /*printf(\"%d %f\\n\", tf_max, mask_metric);*/\n   RESTORE_STACK;\n#ifdef FUZZING\n   is_transient = rand()&0x1;\n#endif\n   /*printf(\"%d %f %d\\n\", is_transient, (float)*tf_estimate, tf_max);*/\n   return is_transient;\n}\n\n/* Looks for sudden increases of energy to decide whether we need to patch\n   the transient decision */\nstatic int patch_transient_decision(opus_val16 *newE, opus_val16 *oldE, int nbEBands,\n      int start, int end, int C)\n{\n   int i, c;\n   opus_val32 mean_diff=0;\n   opus_val16 spread_old[26];\n   /* Apply an aggressive (-6 dB/Bark) spreading function to the old frame to\n      avoid false detection caused by irrelevant bands */\n   if (C==1)\n   {\n      spread_old[start] = oldE[start];\n      for (i=start+1;i<end;i++)\n         spread_old[i] = MAX16(spread_old[i-1]-QCONST16(1.0f, DB_SHIFT), oldE[i]);\n   } else {\n      spread_old[start] = MAX16(oldE[start],oldE[start+nbEBands]);\n      for (i=start+1;i<end;i++)\n         spread_old[i] = MAX16(spread_old[i-1]-QCONST16(1.0f, DB_SHIFT),\n                               MAX16(oldE[i],oldE[i+nbEBands]));\n   }\n   for (i=end-2;i>=start;i--)\n      spread_old[i] = MAX16(spread_old[i], spread_old[i+1]-QCONST16(1.0f, DB_SHIFT));\n   /* Compute mean increase */\n   c=0; do {\n      for (i=IMAX(2,start);i<end-1;i++)\n      {\n         opus_val16 x1, x2;\n         x1 = MAX16(0, newE[i + c*nbEBands]);\n         x2 = MAX16(0, spread_old[i]);\n         mean_diff = ADD32(mean_diff, EXTEND32(MAX16(0, SUB16(x1, x2))));\n      }\n   } while (++c<C);\n   mean_diff = DIV32(mean_diff, C*(end-1-IMAX(2,start)));\n   /*printf(\"%f %f %d\\n\", mean_diff, max_diff, count);*/\n   return mean_diff > QCONST16(1.f, DB_SHIFT);\n}\n\n/** Apply window and compute the MDCT for all sub-frames and\n    all channels in a frame */\nstatic void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * OPUS_RESTRICT in,\n                          celt_sig * OPUS_RESTRICT out, int C, int CC, int LM, int upsample,\n                          int arch)\n{\n   const int overlap = mode->overlap;\n   int N;\n   int B;\n   int shift;\n   int i, b, c;\n   if (shortBlocks)\n   {\n      B = shortBlocks;\n      N = mode->shortMdctSize;\n      shift = mode->maxLM;\n   } else {\n      B = 1;\n      N = mode->shortMdctSize<<LM;\n      shift = mode->maxLM-LM;\n   }\n   c=0; do {\n      for (b=0;b<B;b++)\n      {\n         /* Interleaving the sub-frames while doing the MDCTs */\n         clt_mdct_forward(&mode->mdct, in+c*(B*N+overlap)+b*N,\n                          &out[b+c*N*B], mode->window, overlap, shift, B,\n                          arch);\n      }\n   } while (++c<CC);\n   if (CC==2&&C==1)\n   {\n      for (i=0;i<B*N;i++)\n         out[i] = ADD32(HALF32(out[i]), HALF32(out[B*N+i]));\n   }\n   if (upsample != 1)\n   {\n      c=0; do\n      {\n         int bound = B*N/upsample;\n         for (i=0;i<bound;i++)\n            out[c*B*N+i] *= upsample;\n         OPUS_CLEAR(&out[c*B*N+bound], B*N-bound);\n      } while (++c<C);\n   }\n}\n\n\nvoid celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,\n                        int N, int CC, int upsample, const opus_val16 *coef, celt_sig *mem, int clip)\n{\n   int i;\n   opus_val16 coef0;\n   celt_sig m;\n   int Nu;\n\n   coef0 = coef[0];\n   m = *mem;\n\n   /* Fast path for the normal 48kHz case and no clipping */\n   if (coef[1] == 0 && upsample == 1 && !clip)\n   {\n      for (i=0;i<N;i++)\n      {\n         opus_val16 x;\n         x = SCALEIN(pcmp[CC*i]);\n         /* Apply pre-emphasis */\n         inp[i] = SHL32(x, SIG_SHIFT) - m;\n         m = SHR32(MULT16_16(coef0, x), 15-SIG_SHIFT);\n      }\n      *mem = m;\n      return;\n   }\n\n   Nu = N/upsample;\n   if (upsample!=1)\n   {\n      OPUS_CLEAR(inp, N);\n   }\n   for (i=0;i<Nu;i++)\n      inp[i*upsample] = SCALEIN(pcmp[CC*i]);\n\n#ifndef FIXED_POINT\n   if (clip)\n   {\n      /* Clip input to avoid encoding non-portable files */\n      for (i=0;i<Nu;i++)\n         inp[i*upsample] = MAX32(-65536.f, MIN32(65536.f,inp[i*upsample]));\n   }\n#else\n   (void)clip; /* Avoids a warning about clip being unused. */\n#endif\n#ifdef CUSTOM_MODES\n   if (coef[1] != 0)\n   {\n      opus_val16 coef1 = coef[1];\n      opus_val16 coef2 = coef[2];\n      for (i=0;i<N;i++)\n      {\n         celt_sig x, tmp;\n         x = inp[i];\n         /* Apply pre-emphasis */\n         tmp = MULT16_16(coef2, x);\n         inp[i] = tmp + m;\n         m = MULT16_32_Q15(coef1, inp[i]) - MULT16_32_Q15(coef0, tmp);\n      }\n   } else\n#endif\n   {\n      for (i=0;i<N;i++)\n      {\n         opus_val16 x;\n         x = inp[i];\n         /* Apply pre-emphasis */\n         inp[i] = SHL32(x, SIG_SHIFT) - m;\n         m = SHR32(MULT16_16(coef0, x), 15-SIG_SHIFT);\n      }\n   }\n   *mem = m;\n}\n\n\n\nstatic opus_val32 l1_metric(const celt_norm *tmp, int N, int LM, opus_val16 bias)\n{\n   int i;\n   opus_val32 L1;\n   L1 = 0;\n   for (i=0;i<N;i++)\n      L1 += EXTEND32(ABS16(tmp[i]));\n   /* When in doubt, prefer good freq resolution */\n   L1 = MAC16_32_Q15(L1, LM*bias, L1);\n   return L1;\n\n}\n\nstatic int tf_analysis(const CELTMode *m, int len, int isTransient,\n      int *tf_res, int lambda, celt_norm *X, int N0, int LM,\n      int *tf_sum, opus_val16 tf_estimate, int tf_chan)\n{\n   int i;\n   VARDECL(int, metric);\n   int cost0;\n   int cost1;\n   VARDECL(int, path0);\n   VARDECL(int, path1);\n   VARDECL(celt_norm, tmp);\n   VARDECL(celt_norm, tmp_1);\n   int sel;\n   int selcost[2];\n   int tf_select=0;\n   opus_val16 bias;\n\n   SAVE_STACK;\n   bias = MULT16_16_Q14(QCONST16(.04f,15), MAX16(-QCONST16(.25f,14), QCONST16(.5f,14)-tf_estimate));\n   /*printf(\"%f \", bias);*/\n\n   ALLOC(metric, len, int);\n   ALLOC(tmp, (m->eBands[len]-m->eBands[len-1])<<LM, celt_norm);\n   ALLOC(tmp_1, (m->eBands[len]-m->eBands[len-1])<<LM, celt_norm);\n   ALLOC(path0, len, int);\n   ALLOC(path1, len, int);\n\n   *tf_sum = 0;\n   for (i=0;i<len;i++)\n   {\n      int k, N;\n      int narrow;\n      opus_val32 L1, best_L1;\n      int best_level=0;\n      N = (m->eBands[i+1]-m->eBands[i])<<LM;\n      /* band is too narrow to be split down to LM=-1 */\n      narrow = (m->eBands[i+1]-m->eBands[i])==1;\n      OPUS_COPY(tmp, &X[tf_chan*N0 + (m->eBands[i]<<LM)], N);\n      /* Just add the right channel if we're in stereo */\n      /*if (C==2)\n         for (j=0;j<N;j++)\n            tmp[j] = ADD16(SHR16(tmp[j], 1),SHR16(X[N0+j+(m->eBands[i]<<LM)], 1));*/\n      L1 = l1_metric(tmp, N, isTransient ? LM : 0, bias);\n      best_L1 = L1;\n      /* Check the -1 case for transients */\n      if (isTransient && !narrow)\n      {\n         OPUS_COPY(tmp_1, tmp, N);\n         haar1(tmp_1, N>>LM, 1<<LM);\n         L1 = l1_metric(tmp_1, N, LM+1, bias);\n         if (L1<best_L1)\n         {\n            best_L1 = L1;\n            best_level = -1;\n         }\n      }\n      /*printf (\"%f \", L1);*/\n      for (k=0;k<LM+!(isTransient||narrow);k++)\n      {\n         int B;\n\n         if (isTransient)\n            B = (LM-k-1);\n         else\n            B = k+1;\n\n         haar1(tmp, N>>k, 1<<k);\n\n         L1 = l1_metric(tmp, N, B, bias);\n\n         if (L1 < best_L1)\n         {\n            best_L1 = L1;\n            best_level = k+1;\n         }\n      }\n      /*printf (\"%d \", isTransient ? LM-best_level : best_level);*/\n      /* metric is in Q1 to be able to select the mid-point (-0.5) for narrower bands */\n      if (isTransient)\n         metric[i] = 2*best_level;\n      else\n         metric[i] = -2*best_level;\n      *tf_sum += (isTransient ? LM : 0) - metric[i]/2;\n      /* For bands that can't be split to -1, set the metric to the half-way point to avoid\n         biasing the decision */\n      if (narrow && (metric[i]==0 || metric[i]==-2*LM))\n         metric[i]-=1;\n      /*printf(\"%d \", metric[i]);*/\n   }\n   /*printf(\"\\n\");*/\n   /* Search for the optimal tf resolution, including tf_select */\n   tf_select = 0;\n   for (sel=0;sel<2;sel++)\n   {\n      cost0 = 0;\n      cost1 = isTransient ? 0 : lambda;\n      for (i=1;i<len;i++)\n      {\n         int curr0, curr1;\n         curr0 = IMIN(cost0, cost1 + lambda);\n         curr1 = IMIN(cost0 + lambda, cost1);\n         cost0 = curr0 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+0]);\n         cost1 = curr1 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+1]);\n      }\n      cost0 = IMIN(cost0, cost1);\n      selcost[sel]=cost0;\n   }\n   /* For now, we're conservative and only allow tf_select=1 for transients.\n    * If tests confirm it's useful for non-transients, we could allow it. */\n   if (selcost[1]<selcost[0] && isTransient)\n      tf_select=1;\n   cost0 = 0;\n   cost1 = isTransient ? 0 : lambda;\n   /* Viterbi forward pass */\n   for (i=1;i<len;i++)\n   {\n      int curr0, curr1;\n      int from0, from1;\n\n      from0 = cost0;\n      from1 = cost1 + lambda;\n      if (from0 < from1)\n      {\n         curr0 = from0;\n         path0[i]= 0;\n      } else {\n         curr0 = from1;\n         path0[i]= 1;\n      }\n\n      from0 = cost0 + lambda;\n      from1 = cost1;\n      if (from0 < from1)\n      {\n         curr1 = from0;\n         path1[i]= 0;\n      } else {\n         curr1 = from1;\n         path1[i]= 1;\n      }\n      cost0 = curr0 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+0]);\n      cost1 = curr1 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+1]);\n   }\n   tf_res[len-1] = cost0 < cost1 ? 0 : 1;\n   /* Viterbi backward pass to check the decisions */\n   for (i=len-2;i>=0;i--)\n   {\n      if (tf_res[i+1] == 1)\n         tf_res[i] = path1[i+1];\n      else\n         tf_res[i] = path0[i+1];\n   }\n   /*printf(\"%d %f\\n\", *tf_sum, tf_estimate);*/\n   RESTORE_STACK;\n#ifdef FUZZING\n   tf_select = rand()&0x1;\n   tf_res[0] = rand()&0x1;\n   for (i=1;i<len;i++)\n      tf_res[i] = tf_res[i-1] ^ ((rand()&0xF) == 0);\n#endif\n   return tf_select;\n}\n\nstatic void tf_encode(int start, int end, int isTransient, int *tf_res, int LM, int tf_select, ec_enc *enc)\n{\n   int curr, i;\n   int tf_select_rsv;\n   int tf_changed;\n   int logp;\n   opus_uint32 budget;\n   opus_uint32 tell;\n   budget = enc->storage*8;\n   tell = ec_tell(enc);\n   logp = isTransient ? 2 : 4;\n   /* Reserve space to code the tf_select decision. */\n   tf_select_rsv = LM>0 && tell+logp+1 <= budget;\n   budget -= tf_select_rsv;\n   curr = tf_changed = 0;\n   for (i=start;i<end;i++)\n   {\n      if (tell+logp<=budget)\n      {\n         ec_enc_bit_logp(enc, tf_res[i] ^ curr, logp);\n         tell = ec_tell(enc);\n         curr = tf_res[i];\n         tf_changed |= curr;\n      }\n      else\n         tf_res[i] = curr;\n      logp = isTransient ? 4 : 5;\n   }\n   /* Only code tf_select if it would actually make a difference. */\n   if (tf_select_rsv &&\n         tf_select_table[LM][4*isTransient+0+tf_changed]!=\n         tf_select_table[LM][4*isTransient+2+tf_changed])\n      ec_enc_bit_logp(enc, tf_select, 1);\n   else\n      tf_select = 0;\n   for (i=start;i<end;i++)\n      tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];\n   /*for(i=0;i<end;i++)printf(\"%d \", isTransient ? tf_res[i] : LM+tf_res[i]);printf(\"\\n\");*/\n}\n\n\nstatic int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,\n      const opus_val16 *bandLogE, int end, int LM, int C, int N0,\n      AnalysisInfo *analysis, opus_val16 *stereo_saving, opus_val16 tf_estimate,\n      int intensity, opus_val16 surround_trim, int arch)\n{\n   int i;\n   opus_val32 diff=0;\n   int c;\n   int trim_index;\n   opus_val16 trim = QCONST16(5.f, 8);\n   opus_val16 logXC, logXC2;\n   if (C==2)\n   {\n      opus_val16 sum = 0; /* Q10 */\n      opus_val16 minXC; /* Q10 */\n      /* Compute inter-channel correlation for low frequencies */\n      for (i=0;i<8;i++)\n      {\n         opus_val32 partial;\n         partial = celt_inner_prod(&X[m->eBands[i]<<LM], &X[N0+(m->eBands[i]<<LM)],\n               (m->eBands[i+1]-m->eBands[i])<<LM, arch);\n         sum = ADD16(sum, EXTRACT16(SHR32(partial, 18)));\n      }\n      sum = MULT16_16_Q15(QCONST16(1.f/8, 15), sum);\n      sum = MIN16(QCONST16(1.f, 10), ABS16(sum));\n      minXC = sum;\n      for (i=8;i<intensity;i++)\n      {\n         opus_val32 partial;\n         partial = celt_inner_prod(&X[m->eBands[i]<<LM], &X[N0+(m->eBands[i]<<LM)],\n               (m->eBands[i+1]-m->eBands[i])<<LM, arch);\n         minXC = MIN16(minXC, ABS16(EXTRACT16(SHR32(partial, 18))));\n      }\n      minXC = MIN16(QCONST16(1.f, 10), ABS16(minXC));\n      /*printf (\"%f\\n\", sum);*/\n      /* mid-side savings estimations based on the LF average*/\n      logXC = celt_log2(QCONST32(1.001f, 20)-MULT16_16(sum, sum));\n      /* mid-side savings estimations based on min correlation */\n      logXC2 = MAX16(HALF16(logXC), celt_log2(QCONST32(1.001f, 20)-MULT16_16(minXC, minXC)));\n#ifdef FIXED_POINT\n      /* Compensate for Q20 vs Q14 input and convert output to Q8 */\n      logXC = PSHR32(logXC-QCONST16(6.f, DB_SHIFT),DB_SHIFT-8);\n      logXC2 = PSHR32(logXC2-QCONST16(6.f, DB_SHIFT),DB_SHIFT-8);\n#endif\n\n      trim += MAX16(-QCONST16(4.f, 8), MULT16_16_Q15(QCONST16(.75f,15),logXC));\n      *stereo_saving = MIN16(*stereo_saving + QCONST16(0.25f, 8), -HALF16(logXC2));\n   }\n\n   /* Estimate spectral tilt */\n   c=0; do {\n      for (i=0;i<end-1;i++)\n      {\n         diff += bandLogE[i+c*m->nbEBands]*(opus_int32)(2+2*i-end);\n      }\n   } while (++c<C);\n   diff /= C*(end-1);\n   /*printf(\"%f\\n\", diff);*/\n   trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), SHR16(diff+QCONST16(1.f, DB_SHIFT),DB_SHIFT-8)/6 ));\n   trim -= SHR16(surround_trim, DB_SHIFT-8);\n   trim -= 2*SHR16(tf_estimate, 14-8);\n#ifndef DISABLE_FLOAT_API\n   if (analysis->valid)\n   {\n      trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8),\n            (opus_val16)(QCONST16(2.f, 8)*(analysis->tonality_slope+.05f))));\n   }\n#else\n   (void)analysis;\n#endif\n\n#ifdef FIXED_POINT\n   trim_index = PSHR32(trim, 8);\n#else\n   trim_index = (int)floor(.5f+trim);\n#endif\n   trim_index = IMAX(0, IMIN(10, trim_index));\n   /*printf(\"%d\\n\", trim_index);*/\n#ifdef FUZZING\n   trim_index = rand()%11;\n#endif\n   return trim_index;\n}\n\nstatic int stereo_analysis(const CELTMode *m, const celt_norm *X,\n      int LM, int N0)\n{\n   int i;\n   int thetas;\n   opus_val32 sumLR = EPSILON, sumMS = EPSILON;\n\n   /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */\n   for (i=0;i<13;i++)\n   {\n      int j;\n      for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++)\n      {\n         opus_val32 L, R, M, S;\n         /* We cast to 32-bit first because of the -32768 case */\n         L = EXTEND32(X[j]);\n         R = EXTEND32(X[N0+j]);\n         M = ADD32(L, R);\n         S = SUB32(L, R);\n         sumLR = ADD32(sumLR, ADD32(ABS32(L), ABS32(R)));\n         sumMS = ADD32(sumMS, ADD32(ABS32(M), ABS32(S)));\n      }\n   }\n   sumMS = MULT16_32_Q15(QCONST16(0.707107f, 15), sumMS);\n   thetas = 13;\n   /* We don't need thetas for lower bands with LM<=1 */\n   if (LM<=1)\n      thetas -= 8;\n   return MULT16_32_Q15((m->eBands[13]<<(LM+1))+thetas, sumMS)\n         > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR);\n}\n\n#define MSWAP(a,b) do {opus_val16 tmp = a;a=b;b=tmp;} while(0)\nstatic opus_val16 median_of_5(const opus_val16 *x)\n{\n   opus_val16 t0, t1, t2, t3, t4;\n   t2 = x[2];\n   if (x[0] > x[1])\n   {\n      t0 = x[1];\n      t1 = x[0];\n   } else {\n      t0 = x[0];\n      t1 = x[1];\n   }\n   if (x[3] > x[4])\n   {\n      t3 = x[4];\n      t4 = x[3];\n   } else {\n      t3 = x[3];\n      t4 = x[4];\n   }\n   if (t0 > t3)\n   {\n      MSWAP(t0, t3);\n      MSWAP(t1, t4);\n   }\n   if (t2 > t1)\n   {\n      if (t1 < t3)\n         return MIN16(t2, t3);\n      else\n         return MIN16(t4, t1);\n   } else {\n      if (t2 < t3)\n         return MIN16(t1, t3);\n      else\n         return MIN16(t2, t4);\n   }\n}\n\nstatic opus_val16 median_of_3(const opus_val16 *x)\n{\n   opus_val16 t0, t1, t2;\n   if (x[0] > x[1])\n   {\n      t0 = x[1];\n      t1 = x[0];\n   } else {\n      t0 = x[0];\n      t1 = x[1];\n   }\n   t2 = x[2];\n   if (t1 < t2)\n      return t1;\n   else if (t0 < t2)\n      return t2;\n   else\n      return t0;\n}\n\nstatic opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16 *bandLogE2,\n      int nbEBands, int start, int end, int C, int *offsets, int lsb_depth, const opus_int16 *logN,\n      int isTransient, int vbr, int constrained_vbr, const opus_int16 *eBands, int LM,\n      int effectiveBytes, opus_int32 *tot_boost_, int lfe, opus_val16 *surround_dynalloc)\n{\n   int i, c;\n   opus_int32 tot_boost=0;\n   opus_val16 maxDepth;\n   VARDECL(opus_val16, follower);\n   VARDECL(opus_val16, noise_floor);\n   SAVE_STACK;\n   ALLOC(follower, C*nbEBands, opus_val16);\n   ALLOC(noise_floor, C*nbEBands, opus_val16);\n   OPUS_CLEAR(offsets, nbEBands);\n   /* Dynamic allocation code */\n   maxDepth=-QCONST16(31.9f, DB_SHIFT);\n   for (i=0;i<end;i++)\n   {\n      /* Noise floor must take into account eMeans, the depth, the width of the bands\n         and the preemphasis filter (approx. square of bark band ID) */\n      noise_floor[i] = MULT16_16(QCONST16(0.0625f, DB_SHIFT),logN[i])\n            +QCONST16(.5f,DB_SHIFT)+SHL16(9-lsb_depth,DB_SHIFT)-SHL16(eMeans[i],6)\n            +MULT16_16(QCONST16(.0062,DB_SHIFT),(i+5)*(i+5));\n   }\n   c=0;do\n   {\n      for (i=0;i<end;i++)\n         maxDepth = MAX16(maxDepth, bandLogE[c*nbEBands+i]-noise_floor[i]);\n   } while (++c<C);\n   /* Make sure that dynamic allocation can't make us bust the budget */\n   if (effectiveBytes > 50 && LM>=1 && !lfe)\n   {\n      int last=0;\n      c=0;do\n      {\n         opus_val16 offset;\n         opus_val16 tmp;\n         opus_val16 *f;\n         f = &follower[c*nbEBands];\n         f[0] = bandLogE2[c*nbEBands];\n         for (i=1;i<end;i++)\n         {\n            /* The last band to be at least 3 dB higher than the previous one\n               is the last we'll consider. Otherwise, we run into problems on\n               bandlimited signals. */\n            if (bandLogE2[c*nbEBands+i] > bandLogE2[c*nbEBands+i-1]+QCONST16(.5f,DB_SHIFT))\n               last=i;\n            f[i] = MIN16(f[i-1]+QCONST16(1.5f,DB_SHIFT), bandLogE2[c*nbEBands+i]);\n         }\n         for (i=last-1;i>=0;i--)\n            f[i] = MIN16(f[i], MIN16(f[i+1]+QCONST16(2.f,DB_SHIFT), bandLogE2[c*nbEBands+i]));\n\n         /* Combine with a median filter to avoid dynalloc triggering unnecessarily.\n            The \"offset\" value controls how conservative we are -- a higher offset\n            reduces the impact of the median filter and makes dynalloc use more bits. */\n         offset = QCONST16(1.f, DB_SHIFT);\n         for (i=2;i<end-2;i++)\n            f[i] = MAX16(f[i], median_of_5(&bandLogE2[c*nbEBands+i-2])-offset);\n         tmp = median_of_3(&bandLogE2[c*nbEBands])-offset;\n         f[0] = MAX16(f[0], tmp);\n         f[1] = MAX16(f[1], tmp);\n         tmp = median_of_3(&bandLogE2[c*nbEBands+end-3])-offset;\n         f[end-2] = MAX16(f[end-2], tmp);\n         f[end-1] = MAX16(f[end-1], tmp);\n\n         for (i=0;i<end;i++)\n            f[i] = MAX16(f[i], noise_floor[i]);\n      } while (++c<C);\n      if (C==2)\n      {\n         for (i=start;i<end;i++)\n         {\n            /* Consider 24 dB \"cross-talk\" */\n            follower[nbEBands+i] = MAX16(follower[nbEBands+i], follower[         i]-QCONST16(4.f,DB_SHIFT));\n            follower[         i] = MAX16(follower[         i], follower[nbEBands+i]-QCONST16(4.f,DB_SHIFT));\n            follower[i] = HALF16(MAX16(0, bandLogE[i]-follower[i]) + MAX16(0, bandLogE[nbEBands+i]-follower[nbEBands+i]));\n         }\n      } else {\n         for (i=start;i<end;i++)\n         {\n            follower[i] = MAX16(0, bandLogE[i]-follower[i]);\n         }\n      }\n      for (i=start;i<end;i++)\n         follower[i] = MAX16(follower[i], surround_dynalloc[i]);\n      /* For non-transient CBR/CVBR frames, halve the dynalloc contribution */\n      if ((!vbr || constrained_vbr)&&!isTransient)\n      {\n         for (i=start;i<end;i++)\n            follower[i] = HALF16(follower[i]);\n      }\n      for (i=start;i<end;i++)\n      {\n         int width;\n         int boost;\n         int boost_bits;\n\n         if (i<8)\n            follower[i] *= 2;\n         if (i>=12)\n            follower[i] = HALF16(follower[i]);\n         follower[i] = MIN16(follower[i], QCONST16(4, DB_SHIFT));\n\n         width = C*(eBands[i+1]-eBands[i])<<LM;\n         if (width<6)\n         {\n            boost = (int)SHR32(EXTEND32(follower[i]),DB_SHIFT);\n            boost_bits = boost*width<<BITRES;\n         } else if (width > 48) {\n            boost = (int)SHR32(EXTEND32(follower[i])*8,DB_SHIFT);\n            boost_bits = (boost*width<<BITRES)/8;\n         } else {\n            boost = (int)SHR32(EXTEND32(follower[i])*width/6,DB_SHIFT);\n            boost_bits = boost*6<<BITRES;\n         }\n         /* For CBR and non-transient CVBR frames, limit dynalloc to 1/4 of the bits */\n         if ((!vbr || (constrained_vbr&&!isTransient))\n               && (tot_boost+boost_bits)>>BITRES>>3 > effectiveBytes/4)\n         {\n            opus_int32 cap = ((effectiveBytes/4)<<BITRES<<3);\n            offsets[i] = cap-tot_boost;\n            tot_boost = cap;\n            break;\n         } else {\n            offsets[i] = boost;\n            tot_boost += boost_bits;\n         }\n      }\n   }\n   *tot_boost_ = tot_boost;\n   RESTORE_STACK;\n   return maxDepth;\n}\n\n\nstatic int run_prefilter(CELTEncoder *st, celt_sig *in, celt_sig *prefilter_mem, int CC, int N,\n      int prefilter_tapset, int *pitch, opus_val16 *gain, int *qgain, int enabled, int nbAvailableBytes)\n{\n   int c;\n   VARDECL(celt_sig, _pre);\n   celt_sig *pre[2];\n   const CELTMode *mode;\n   int pitch_index;\n   opus_val16 gain1;\n   opus_val16 pf_threshold;\n   int pf_on;\n   int qg;\n   int overlap;\n   SAVE_STACK;\n\n   mode = st->mode;\n   overlap = mode->overlap;\n   ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig);\n\n   pre[0] = _pre;\n   pre[1] = _pre + (N+COMBFILTER_MAXPERIOD);\n\n\n   c=0; do {\n      OPUS_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD);\n      OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+overlap)+overlap, N);\n   } while (++c<CC);\n\n   if (enabled)\n   {\n      VARDECL(opus_val16, pitch_buf);\n      ALLOC(pitch_buf, (COMBFILTER_MAXPERIOD+N)>>1, opus_val16);\n\n      pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC, st->arch);\n      /* Don't search for the fir last 1.5 octave of the range because\n         there's too many false-positives due to short-term correlation */\n      pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N,\n            COMBFILTER_MAXPERIOD-3*COMBFILTER_MINPERIOD, &pitch_index,\n            st->arch);\n      pitch_index = COMBFILTER_MAXPERIOD-pitch_index;\n\n      gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD,\n            N, &pitch_index, st->prefilter_period, st->prefilter_gain, st->arch);\n      if (pitch_index > COMBFILTER_MAXPERIOD-2)\n         pitch_index = COMBFILTER_MAXPERIOD-2;\n      gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1);\n      /*printf(\"%d %d %f %f\\n\", pitch_change, pitch_index, gain1, st->analysis.tonality);*/\n      if (st->loss_rate>2)\n         gain1 = HALF32(gain1);\n      if (st->loss_rate>4)\n         gain1 = HALF32(gain1);\n      if (st->loss_rate>8)\n         gain1 = 0;\n   } else {\n      gain1 = 0;\n      pitch_index = COMBFILTER_MINPERIOD;\n   }\n\n   /* Gain threshold for enabling the prefilter/postfilter */\n   pf_threshold = QCONST16(.2f,15);\n\n   /* Adjusting the threshold based on rate and continuity */\n   if (abs(pitch_index-st->prefilter_period)*10>pitch_index)\n      pf_threshold += QCONST16(.2f,15);\n   if (nbAvailableBytes<25)\n      pf_threshold += QCONST16(.1f,15);\n   if (nbAvailableBytes<35)\n      pf_threshold += QCONST16(.1f,15);\n   if (st->prefilter_gain > QCONST16(.4f,15))\n      pf_threshold -= QCONST16(.1f,15);\n   if (st->prefilter_gain > QCONST16(.55f,15))\n      pf_threshold -= QCONST16(.1f,15);\n\n   /* Hard threshold at 0.2 */\n   pf_threshold = MAX16(pf_threshold, QCONST16(.2f,15));\n   if (gain1<pf_threshold)\n   {\n      gain1 = 0;\n      pf_on = 0;\n      qg = 0;\n   } else {\n      /*This block is not gated by a total bits check only because\n        of the nbAvailableBytes check above.*/\n      if (ABS16(gain1-st->prefilter_gain)<QCONST16(.1f,15))\n         gain1=st->prefilter_gain;\n\n#ifdef FIXED_POINT\n      qg = ((gain1+1536)>>10)/3-1;\n#else\n      qg = (int)floor(.5f+gain1*32/3)-1;\n#endif\n      qg = IMAX(0, IMIN(7, qg));\n      gain1 = QCONST16(0.09375f,15)*(qg+1);\n      pf_on = 1;\n   }\n   /*printf(\"%d %f\\n\", pitch_index, gain1);*/\n\n   c=0; do {\n      int offset = mode->shortMdctSize-overlap;\n      st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);\n      OPUS_COPY(in+c*(N+overlap), st->in_mem+c*(overlap), overlap);\n      if (offset)\n         comb_filter(in+c*(N+overlap)+overlap, pre[c]+COMBFILTER_MAXPERIOD,\n               st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain,\n               st->prefilter_tapset, st->prefilter_tapset, NULL, 0, st->arch);\n\n      comb_filter(in+c*(N+overlap)+overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset,\n            st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1,\n            st->prefilter_tapset, prefilter_tapset, mode->window, overlap, st->arch);\n      OPUS_COPY(st->in_mem+c*(overlap), in+c*(N+overlap)+N, overlap);\n\n      if (N>COMBFILTER_MAXPERIOD)\n      {\n         OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD);\n      } else {\n         OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N);\n         OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N);\n      }\n   } while (++c<CC);\n\n   RESTORE_STACK;\n   *gain = gain1;\n   *pitch = pitch_index;\n   *qgain = qg;\n   return pf_on;\n}\n\nstatic int compute_vbr(const CELTMode *mode, AnalysisInfo *analysis, opus_int32 base_target,\n      int LM, opus_int32 bitrate, int lastCodedBands, int C, int intensity,\n      int constrained_vbr, opus_val16 stereo_saving, int tot_boost,\n      opus_val16 tf_estimate, int pitch_change, opus_val16 maxDepth,\n      int variable_duration, int lfe, int has_surround_mask, opus_val16 surround_masking,\n      opus_val16 temporal_vbr)\n{\n   /* The target rate in 8th bits per frame */\n   opus_int32 target;\n   int coded_bins;\n   int coded_bands;\n   opus_val16 tf_calibration;\n   int nbEBands;\n   const opus_int16 *eBands;\n\n   nbEBands = mode->nbEBands;\n   eBands = mode->eBands;\n\n   coded_bands = lastCodedBands ? lastCodedBands : nbEBands;\n   coded_bins = eBands[coded_bands]<<LM;\n   if (C==2)\n      coded_bins += eBands[IMIN(intensity, coded_bands)]<<LM;\n\n   target = base_target;\n\n   /*printf(\"%f %f %f %f %d %d \", st->analysis.activity, st->analysis.tonality, tf_estimate, st->stereo_saving, tot_boost, coded_bands);*/\n#ifndef DISABLE_FLOAT_API\n   if (analysis->valid && analysis->activity<.4)\n      target -= (opus_int32)((coded_bins<<BITRES)*(.4f-analysis->activity));\n#endif\n   /* Stereo savings */\n   if (C==2)\n   {\n      int coded_stereo_bands;\n      int coded_stereo_dof;\n      opus_val16 max_frac;\n      coded_stereo_bands = IMIN(intensity, coded_bands);\n      coded_stereo_dof = (eBands[coded_stereo_bands]<<LM)-coded_stereo_bands;\n      /* Maximum fraction of the bits we can save if the signal is mono. */\n      max_frac = DIV32_16(MULT16_16(QCONST16(0.8f, 15), coded_stereo_dof), coded_bins);\n      stereo_saving = MIN16(stereo_saving, QCONST16(1.f, 8));\n      /*printf(\"%d %d %d \", coded_stereo_dof, coded_bins, tot_boost);*/\n      target -= (opus_int32)MIN32(MULT16_32_Q15(max_frac,target),\n                      SHR32(MULT16_16(stereo_saving-QCONST16(0.1f,8),(coded_stereo_dof<<BITRES)),8));\n   }\n   /* Boost the rate according to dynalloc (minus the dynalloc average for calibration). */\n   target += tot_boost-(16<<LM);\n   /* Apply transient boost, compensating for average boost. */\n   tf_calibration = variable_duration==OPUS_FRAMESIZE_VARIABLE ?\n                    QCONST16(0.02f,14) : QCONST16(0.04f,14);\n   target += (opus_int32)SHL32(MULT16_32_Q15(tf_estimate-tf_calibration, target),1);\n\n#ifndef DISABLE_FLOAT_API\n   /* Apply tonality boost */\n   if (analysis->valid && !lfe)\n   {\n      opus_int32 tonal_target;\n      float tonal;\n\n      /* Tonality boost (compensating for the average). */\n      tonal = MAX16(0.f,analysis->tonality-.15f)-0.09f;\n      tonal_target = target + (opus_int32)((coded_bins<<BITRES)*1.2f*tonal);\n      if (pitch_change)\n         tonal_target +=  (opus_int32)((coded_bins<<BITRES)*.8f);\n      /*printf(\"%f %f \", analysis->tonality, tonal);*/\n      target = tonal_target;\n   }\n#else\n   (void)analysis;\n   (void)pitch_change;\n#endif\n\n   if (has_surround_mask&&!lfe)\n   {\n      opus_int32 surround_target = target + (opus_int32)SHR32(MULT16_16(surround_masking,coded_bins<<BITRES), DB_SHIFT);\n      /*printf(\"%f %d %d %d %d %d %d \", surround_masking, coded_bins, st->end, st->intensity, surround_target, target, st->bitrate);*/\n      target = IMAX(target/4, surround_target);\n   }\n\n   {\n      opus_int32 floor_depth;\n      int bins;\n      bins = eBands[nbEBands-2]<<LM;\n      /*floor_depth = SHR32(MULT16_16((C*bins<<BITRES),celt_log2(SHL32(MAX16(1,sample_max),13))), DB_SHIFT);*/\n      floor_depth = (opus_int32)SHR32(MULT16_16((C*bins<<BITRES),maxDepth), DB_SHIFT);\n      floor_depth = IMAX(floor_depth, target>>2);\n      target = IMIN(target, floor_depth);\n      /*printf(\"%f %d\\n\", maxDepth, floor_depth);*/\n   }\n\n   if ((!has_surround_mask||lfe) && (constrained_vbr || bitrate<64000))\n   {\n      opus_val16 rate_factor;\n#ifdef FIXED_POINT\n      rate_factor = MAX16(0,(bitrate-32000));\n#else\n      rate_factor = MAX16(0,(1.f/32768)*(bitrate-32000));\n#endif\n      if (constrained_vbr)\n         rate_factor = MIN16(rate_factor, QCONST16(0.67f, 15));\n      target = base_target + (opus_int32)MULT16_32_Q15(rate_factor, target-base_target);\n\n   }\n\n   if (!has_surround_mask && tf_estimate < QCONST16(.2f, 14))\n   {\n      opus_val16 amount;\n      opus_val16 tvbr_factor;\n      amount = MULT16_16_Q15(QCONST16(.0000031f, 30), IMAX(0, IMIN(32000, 96000-bitrate)));\n      tvbr_factor = SHR32(MULT16_16(temporal_vbr, amount), DB_SHIFT);\n      target += (opus_int32)MULT16_32_Q15(tvbr_factor, target);\n   }\n\n   /* Don't allow more than doubling the rate */\n   target = IMIN(2*base_target, target);\n\n   return target;\n}\n\nint celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)\n{\n   int i, c, N;\n   opus_int32 bits;\n   ec_enc _enc;\n   VARDECL(celt_sig, in);\n   VARDECL(celt_sig, freq);\n   VARDECL(celt_norm, X);\n   VARDECL(celt_ener, bandE);\n   VARDECL(opus_val16, bandLogE);\n   VARDECL(opus_val16, bandLogE2);\n   VARDECL(int, fine_quant);\n   VARDECL(opus_val16, error);\n   VARDECL(int, pulses);\n   VARDECL(int, cap);\n   VARDECL(int, offsets);\n   VARDECL(int, fine_priority);\n   VARDECL(int, tf_res);\n   VARDECL(unsigned char, collapse_masks);\n   celt_sig *prefilter_mem;\n   opus_val16 *oldBandE, *oldLogE, *oldLogE2;\n   int shortBlocks=0;\n   int isTransient=0;\n   const int CC = st->channels;\n   const int C = st->stream_channels;\n   int LM, M;\n   int tf_select;\n   int nbFilledBytes, nbAvailableBytes;\n   int start;\n   int end;\n   int effEnd;\n   int codedBands;\n   int tf_sum;\n   int alloc_trim;\n   int pitch_index=COMBFILTER_MINPERIOD;\n   opus_val16 gain1 = 0;\n   int dual_stereo=0;\n   int effectiveBytes;\n   int dynalloc_logp;\n   opus_int32 vbr_rate;\n   opus_int32 total_bits;\n   opus_int32 total_boost;\n   opus_int32 balance;\n   opus_int32 tell;\n   int prefilter_tapset=0;\n   int pf_on;\n   int anti_collapse_rsv;\n   int anti_collapse_on=0;\n   int silence=0;\n   int tf_chan = 0;\n   opus_val16 tf_estimate;\n   int pitch_change=0;\n   opus_int32 tot_boost;\n   opus_val32 sample_max;\n   opus_val16 maxDepth;\n   const OpusCustomMode *mode;\n   int nbEBands;\n   int overlap;\n   const opus_int16 *eBands;\n   int secondMdct;\n   int signalBandwidth;\n   int transient_got_disabled=0;\n   opus_val16 surround_masking=0;\n   opus_val16 temporal_vbr=0;\n   opus_val16 surround_trim = 0;\n   opus_int32 equiv_rate = 510000;\n   VARDECL(opus_val16, surround_dynalloc);\n   ALLOC_STACK;\n\n   mode = st->mode;\n   nbEBands = mode->nbEBands;\n   overlap = mode->overlap;\n   eBands = mode->eBands;\n   start = st->start;\n   end = st->end;\n   tf_estimate = 0;\n   if (nbCompressedBytes<2 || pcm==NULL)\n   {\n      RESTORE_STACK;\n      return OPUS_BAD_ARG;\n   }\n\n   frame_size *= st->upsample;\n   for (LM=0;LM<=mode->maxLM;LM++)\n      if (mode->shortMdctSize<<LM==frame_size)\n         break;\n   if (LM>mode->maxLM)\n   {\n      RESTORE_STACK;\n      return OPUS_BAD_ARG;\n   }\n   M=1<<LM;\n   N = M*mode->shortMdctSize;\n\n   prefilter_mem = st->in_mem+CC*(overlap);\n   oldBandE = (opus_val16*)(st->in_mem+CC*(overlap+COMBFILTER_MAXPERIOD));\n   oldLogE = oldBandE + CC*nbEBands;\n   oldLogE2 = oldLogE + CC*nbEBands;\n\n   if (enc==NULL)\n   {\n      tell=1;\n      nbFilledBytes=0;\n   } else {\n      tell=ec_tell(enc);\n      nbFilledBytes=(tell+4)>>3;\n   }\n\n#ifdef CUSTOM_MODES\n   if (st->signalling && enc==NULL)\n   {\n      int tmp = (mode->effEBands-end)>>1;\n      end = st->end = IMAX(1, mode->effEBands-tmp);\n      compressed[0] = tmp<<5;\n      compressed[0] |= LM<<3;\n      compressed[0] |= (C==2)<<2;\n      /* Convert \"standard mode\" to Opus header */\n      if (mode->Fs==48000 && mode->shortMdctSize==120)\n      {\n         int c0 = toOpus(compressed[0]);\n         if (c0<0)\n         {\n            RESTORE_STACK;\n            return OPUS_BAD_ARG;\n         }\n         compressed[0] = c0;\n      }\n      compressed++;\n      nbCompressedBytes--;\n   }\n#else\n   celt_assert(st->signalling==0);\n#endif\n\n   /* Can't produce more than 1275 output bytes */\n   nbCompressedBytes = IMIN(nbCompressedBytes,1275);\n   nbAvailableBytes = nbCompressedBytes - nbFilledBytes;\n\n   if (st->vbr && st->bitrate!=OPUS_BITRATE_MAX)\n   {\n      opus_int32 den=mode->Fs>>BITRES;\n      vbr_rate=(st->bitrate*frame_size+(den>>1))/den;\n#ifdef CUSTOM_MODES\n      if (st->signalling)\n         vbr_rate -= 8<<BITRES;\n#endif\n      effectiveBytes = vbr_rate>>(3+BITRES);\n   } else {\n      opus_int32 tmp;\n      vbr_rate = 0;\n      tmp = st->bitrate*frame_size;\n      if (tell>1)\n         tmp += tell;\n      if (st->bitrate!=OPUS_BITRATE_MAX)\n         nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes,\n               (tmp+4*mode->Fs)/(8*mode->Fs)-!!st->signalling));\n      effectiveBytes = nbCompressedBytes;\n   }\n   if (st->bitrate != OPUS_BITRATE_MAX)\n      equiv_rate = st->bitrate - (40*C+20)*((400>>LM) - 50);\n\n   if (enc==NULL)\n   {\n      ec_enc_init(&_enc, compressed, nbCompressedBytes);\n      enc = &_enc;\n   }\n\n   if (vbr_rate>0)\n   {\n      /* Computes the max bit-rate allowed in VBR mode to avoid violating the\n          target rate and buffering.\n         We must do this up front so that bust-prevention logic triggers\n          correctly if we don't have enough bits. */\n      if (st->constrained_vbr)\n      {\n         opus_int32 vbr_bound;\n         opus_int32 max_allowed;\n         /* We could use any multiple of vbr_rate as bound (depending on the\n             delay).\n            This is clamped to ensure we use at least two bytes if the encoder\n             was entirely empty, but to allow 0 in hybrid mode. */\n         vbr_bound = vbr_rate;\n         max_allowed = IMIN(IMAX(tell==1?2:0,\n               (vbr_rate+vbr_bound-st->vbr_reservoir)>>(BITRES+3)),\n               nbAvailableBytes);\n         if(max_allowed < nbAvailableBytes)\n         {\n            nbCompressedBytes = nbFilledBytes+max_allowed;\n            nbAvailableBytes = max_allowed;\n            ec_enc_shrink(enc, nbCompressedBytes);\n         }\n      }\n   }\n   total_bits = nbCompressedBytes*8;\n\n   effEnd = end;\n   if (effEnd > mode->effEBands)\n      effEnd = mode->effEBands;\n\n   ALLOC(in, CC*(N+overlap), celt_sig);\n\n   sample_max=MAX32(st->overlap_max, celt_maxabs16(pcm, C*(N-overlap)/st->upsample));\n   st->overlap_max=celt_maxabs16(pcm+C*(N-overlap)/st->upsample, C*overlap/st->upsample);\n   sample_max=MAX32(sample_max, st->overlap_max);\n#ifdef FIXED_POINT\n   silence = (sample_max==0);\n#else\n   silence = (sample_max <= (opus_val16)1/(1<<st->lsb_depth));\n#endif\n#ifdef FUZZING\n   if ((rand()&0x3F)==0)\n      silence = 1;\n#endif\n   if (tell==1)\n      ec_enc_bit_logp(enc, silence, 15);\n   else\n      silence=0;\n   if (silence)\n   {\n      /*In VBR mode there is no need to send more than the minimum. */\n      if (vbr_rate>0)\n      {\n         effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2);\n         total_bits=nbCompressedBytes*8;\n         nbAvailableBytes=2;\n         ec_enc_shrink(enc, nbCompressedBytes);\n      }\n      /* Pretend we've filled all the remaining bits with zeros\n            (that's what the initialiser did anyway) */\n      tell = nbCompressedBytes*8;\n      enc->nbits_total+=tell-ec_tell(enc);\n   }\n   c=0; do {\n      int need_clip=0;\n#ifndef FIXED_POINT\n      need_clip = st->clip && sample_max>65536.f;\n#endif\n      celt_preemphasis(pcm+c, in+c*(N+overlap)+overlap, N, CC, st->upsample,\n                  mode->preemph, st->preemph_memE+c, need_clip);\n   } while (++c<CC);\n\n\n\n   /* Find pitch period and gain */\n   {\n      int enabled;\n      int qg;\n      enabled = ((st->lfe&&nbAvailableBytes>3) || nbAvailableBytes>12*C) && start==0 && !silence && !st->disable_pf\n            && st->complexity >= 5 && !(st->consec_transient && LM!=3 && st->variable_duration==OPUS_FRAMESIZE_VARIABLE);\n\n      prefilter_tapset = st->tapset_decision;\n      pf_on = run_prefilter(st, in, prefilter_mem, CC, N, prefilter_tapset, &pitch_index, &gain1, &qg, enabled, nbAvailableBytes);\n      if ((gain1 > QCONST16(.4f,15) || st->prefilter_gain > QCONST16(.4f,15)) && (!st->analysis.valid || st->analysis.tonality > .3)\n            && (pitch_index > 1.26*st->prefilter_period || pitch_index < .79*st->prefilter_period))\n         pitch_change = 1;\n      if (pf_on==0)\n      {\n         if(start==0 && tell+16<=total_bits)\n            ec_enc_bit_logp(enc, 0, 1);\n      } else {\n         /*This block is not gated by a total bits check only because\n           of the nbAvailableBytes check above.*/\n         int octave;\n         ec_enc_bit_logp(enc, 1, 1);\n         pitch_index += 1;\n         octave = EC_ILOG(pitch_index)-5;\n         ec_enc_uint(enc, octave, 6);\n         ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);\n         pitch_index -= 1;\n         ec_enc_bits(enc, qg, 3);\n         ec_enc_icdf(enc, prefilter_tapset, tapset_icdf, 2);\n      }\n   }\n\n   isTransient = 0;\n   shortBlocks = 0;\n   if (st->complexity >= 1 && !st->lfe)\n   {\n      isTransient = transient_analysis(in, N+overlap, CC,\n            &tf_estimate, &tf_chan);\n   }\n   if (LM>0 && ec_tell(enc)+3<=total_bits)\n   {\n      if (isTransient)\n         shortBlocks = M;\n   } else {\n      isTransient = 0;\n      transient_got_disabled=1;\n   }\n\n   ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */\n   ALLOC(bandE,nbEBands*CC, celt_ener);\n   ALLOC(bandLogE,nbEBands*CC, opus_val16);\n\n   secondMdct = shortBlocks && st->complexity>=8;\n   ALLOC(bandLogE2, C*nbEBands, opus_val16);\n   if (secondMdct)\n   {\n      compute_mdcts(mode, 0, in, freq, C, CC, LM, st->upsample, st->arch);\n      compute_band_energies(mode, freq, bandE, effEnd, C, LM);\n      amp2Log2(mode, effEnd, end, bandE, bandLogE2, C);\n      for (i=0;i<C*nbEBands;i++)\n         bandLogE2[i] += HALF16(SHL16(LM, DB_SHIFT));\n   }\n\n   compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample, st->arch);\n   if (CC==2&&C==1)\n      tf_chan = 0;\n   compute_band_energies(mode, freq, bandE, effEnd, C, LM);\n\n   if (st->lfe)\n   {\n      for (i=2;i<end;i++)\n      {\n         bandE[i] = IMIN(bandE[i], MULT16_32_Q15(QCONST16(1e-4f,15),bandE[0]));\n         bandE[i] = MAX32(bandE[i], EPSILON);\n      }\n   }\n   amp2Log2(mode, effEnd, end, bandE, bandLogE, C);\n\n   ALLOC(surround_dynalloc, C*nbEBands, opus_val16);\n   OPUS_CLEAR(surround_dynalloc, end);\n   /* This computes how much masking takes place between surround channels */\n   if (start==0&&st->energy_mask&&!st->lfe)\n   {\n      int mask_end;\n      int midband;\n      int count_dynalloc;\n      opus_val32 mask_avg=0;\n      opus_val32 diff=0;\n      int count=0;\n      mask_end = IMAX(2,st->lastCodedBands);\n      for (c=0;c<C;c++)\n      {\n         for(i=0;i<mask_end;i++)\n         {\n            opus_val16 mask;\n            mask = MAX16(MIN16(st->energy_mask[nbEBands*c+i],\n                   QCONST16(.25f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT));\n            if (mask > 0)\n               mask = HALF16(mask);\n            mask_avg += MULT16_16(mask, eBands[i+1]-eBands[i]);\n            count += eBands[i+1]-eBands[i];\n            diff += MULT16_16(mask, 1+2*i-mask_end);\n         }\n      }\n      celt_assert(count>0);\n      mask_avg = DIV32_16(mask_avg,count);\n      mask_avg += QCONST16(.2f, DB_SHIFT);\n      diff = diff*6/(C*(mask_end-1)*(mask_end+1)*mask_end);\n      /* Again, being conservative */\n      diff = HALF32(diff);\n      diff = MAX32(MIN32(diff, QCONST32(.031f, DB_SHIFT)), -QCONST32(.031f, DB_SHIFT));\n      /* Find the band that's in the middle of the coded spectrum */\n      for (midband=0;eBands[midband+1] < eBands[mask_end]/2;midband++);\n      count_dynalloc=0;\n      for(i=0;i<mask_end;i++)\n      {\n         opus_val32 lin;\n         opus_val16 unmask;\n         lin = mask_avg + diff*(i-midband);\n         if (C==2)\n            unmask = MAX16(st->energy_mask[i], st->energy_mask[nbEBands+i]);\n         else\n            unmask = st->energy_mask[i];\n         unmask = MIN16(unmask, QCONST16(.0f, DB_SHIFT));\n         unmask -= lin;\n         if (unmask > QCONST16(.25f, DB_SHIFT))\n         {\n            surround_dynalloc[i] = unmask - QCONST16(.25f, DB_SHIFT);\n            count_dynalloc++;\n         }\n      }\n      if (count_dynalloc>=3)\n      {\n         /* If we need dynalloc in many bands, it's probably because our\n            initial masking rate was too low. */\n         mask_avg += QCONST16(.25f, DB_SHIFT);\n         if (mask_avg>0)\n         {\n            /* Something went really wrong in the original calculations,\n               disabling masking. */\n            mask_avg = 0;\n            diff = 0;\n            OPUS_CLEAR(surround_dynalloc, mask_end);\n         } else {\n            for(i=0;i<mask_end;i++)\n               surround_dynalloc[i] = MAX16(0, surround_dynalloc[i]-QCONST16(.25f, DB_SHIFT));\n         }\n      }\n      mask_avg += QCONST16(.2f, DB_SHIFT);\n      /* Convert to 1/64th units used for the trim */\n      surround_trim = 64*diff;\n      /*printf(\"%d %d \", mask_avg, surround_trim);*/\n      surround_masking = mask_avg;\n   }\n   /* Temporal VBR (but not for LFE) */\n   if (!st->lfe)\n   {\n      opus_val16 follow=-QCONST16(10.0f,DB_SHIFT);\n      opus_val32 frame_avg=0;\n      opus_val16 offset = shortBlocks?HALF16(SHL16(LM, DB_SHIFT)):0;\n      for(i=start;i<end;i++)\n      {\n         follow = MAX16(follow-QCONST16(1.f, DB_SHIFT), bandLogE[i]-offset);\n         if (C==2)\n            follow = MAX16(follow, bandLogE[i+nbEBands]-offset);\n         frame_avg += follow;\n      }\n      frame_avg /= (end-start);\n      temporal_vbr = SUB16(frame_avg,st->spec_avg);\n      temporal_vbr = MIN16(QCONST16(3.f, DB_SHIFT), MAX16(-QCONST16(1.5f, DB_SHIFT), temporal_vbr));\n      st->spec_avg += MULT16_16_Q15(QCONST16(.02f, 15), temporal_vbr);\n   }\n   /*for (i=0;i<21;i++)\n      printf(\"%f \", bandLogE[i]);\n   printf(\"\\n\");*/\n\n   if (!secondMdct)\n   {\n      OPUS_COPY(bandLogE2, bandLogE, C*nbEBands);\n   }\n\n   /* Last chance to catch any transient we might have missed in the\n      time-domain analysis */\n   if (LM>0 && ec_tell(enc)+3<=total_bits && !isTransient && st->complexity>=5 && !st->lfe)\n   {\n      if (patch_transient_decision(bandLogE, oldBandE, nbEBands, start, end, C))\n      {\n         isTransient = 1;\n         shortBlocks = M;\n         compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample, st->arch);\n         compute_band_energies(mode, freq, bandE, effEnd, C, LM);\n         amp2Log2(mode, effEnd, end, bandE, bandLogE, C);\n         /* Compensate for the scaling of short vs long mdcts */\n         for (i=0;i<C*nbEBands;i++)\n            bandLogE2[i] += HALF16(SHL16(LM, DB_SHIFT));\n         tf_estimate = QCONST16(.2f,14);\n      }\n   }\n\n   if (LM>0 && ec_tell(enc)+3<=total_bits)\n      ec_enc_bit_logp(enc, isTransient, 3);\n\n   ALLOC(X, C*N, celt_norm);         /**< Interleaved normalised MDCTs */\n\n   /* Band normalisation */\n   normalise_bands(mode, freq, X, bandE, effEnd, C, M);\n\n   ALLOC(tf_res, nbEBands, int);\n   /* Disable variable tf resolution for hybrid and at very low bitrate */\n   if (effectiveBytes>=15*C && start==0 && st->complexity>=2 && !st->lfe)\n   {\n      int lambda;\n      if (effectiveBytes<40)\n         lambda = 12;\n      else if (effectiveBytes<60)\n         lambda = 6;\n      else if (effectiveBytes<100)\n         lambda = 4;\n      else\n         lambda = 3;\n      lambda*=2;\n      tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, &tf_sum, tf_estimate, tf_chan);\n      for (i=effEnd;i<end;i++)\n         tf_res[i] = tf_res[effEnd-1];\n   } else {\n      tf_sum = 0;\n      for (i=0;i<end;i++)\n         tf_res[i] = isTransient;\n      tf_select=0;\n   }\n\n   ALLOC(error, C*nbEBands, opus_val16);\n   quant_coarse_energy(mode, start, end, effEnd, bandLogE,\n         oldBandE, total_bits, error, enc,\n         C, LM, nbAvailableBytes, st->force_intra,\n         &st->delayedIntra, st->complexity >= 4, st->loss_rate, st->lfe);\n\n   tf_encode(start, end, isTransient, tf_res, LM, tf_select, enc);\n\n   if (ec_tell(enc)+4<=total_bits)\n   {\n      if (st->lfe)\n      {\n         st->tapset_decision = 0;\n         st->spread_decision = SPREAD_NORMAL;\n      } else if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C || start != 0)\n      {\n         if (st->complexity == 0)\n            st->spread_decision = SPREAD_NONE;\n         else\n            st->spread_decision = SPREAD_NORMAL;\n      } else {\n         /* Disable new spreading+tapset estimator until we can show it works\n            better than the old one. So far it seems like spreading_decision()\n            works best. */\n#if 0\n         if (st->analysis.valid)\n         {\n            static const opus_val16 spread_thresholds[3] = {-QCONST16(.6f, 15), -QCONST16(.2f, 15), -QCONST16(.07f, 15)};\n            static const opus_val16 spread_histeresis[3] = {QCONST16(.15f, 15), QCONST16(.07f, 15), QCONST16(.02f, 15)};\n            static const opus_val16 tapset_thresholds[2] = {QCONST16(.0f, 15), QCONST16(.15f, 15)};\n            static const opus_val16 tapset_histeresis[2] = {QCONST16(.1f, 15), QCONST16(.05f, 15)};\n            st->spread_decision = hysteresis_decision(-st->analysis.tonality, spread_thresholds, spread_histeresis, 3, st->spread_decision);\n            st->tapset_decision = hysteresis_decision(st->analysis.tonality_slope, tapset_thresholds, tapset_histeresis, 2, st->tapset_decision);\n         } else\n#endif\n         {\n            st->spread_decision = spreading_decision(mode, X,\n                  &st->tonal_average, st->spread_decision, &st->hf_average,\n                  &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M);\n         }\n         /*printf(\"%d %d\\n\", st->tapset_decision, st->spread_decision);*/\n         /*printf(\"%f %d %f %d\\n\\n\", st->analysis.tonality, st->spread_decision, st->analysis.tonality_slope, st->tapset_decision);*/\n      }\n      ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5);\n   }\n\n   ALLOC(offsets, nbEBands, int);\n\n   maxDepth = dynalloc_analysis(bandLogE, bandLogE2, nbEBands, start, end, C, offsets,\n         st->lsb_depth, mode->logN, isTransient, st->vbr, st->constrained_vbr,\n         eBands, LM, effectiveBytes, &tot_boost, st->lfe, surround_dynalloc);\n   /* For LFE, everything interesting is in the first band */\n   if (st->lfe)\n      offsets[0] = IMIN(8, effectiveBytes/3);\n   ALLOC(cap, nbEBands, int);\n   init_caps(mode,cap,LM,C);\n\n   dynalloc_logp = 6;\n   total_bits<<=BITRES;\n   total_boost = 0;\n   tell = ec_tell_frac(enc);\n   for (i=start;i<end;i++)\n   {\n      int width, quanta;\n      int dynalloc_loop_logp;\n      int boost;\n      int j;\n      width = C*(eBands[i+1]-eBands[i])<<LM;\n      /* quanta is 6 bits, but no more than 1 bit/sample\n         and no less than 1/8 bit/sample */\n      quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));\n      dynalloc_loop_logp = dynalloc_logp;\n      boost = 0;\n      for (j = 0; tell+(dynalloc_loop_logp<<BITRES) < total_bits-total_boost\n            && boost < cap[i]; j++)\n      {\n         int flag;\n         flag = j<offsets[i];\n         ec_enc_bit_logp(enc, flag, dynalloc_loop_logp);\n         tell = ec_tell_frac(enc);\n         if (!flag)\n            break;\n         boost += quanta;\n         total_boost += quanta;\n         dynalloc_loop_logp = 1;\n      }\n      /* Making dynalloc more likely */\n      if (j)\n         dynalloc_logp = IMAX(2, dynalloc_logp-1);\n      offsets[i] = boost;\n   }\n\n   if (C==2)\n   {\n      static const opus_val16 intensity_thresholds[21]=\n      /* 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19  20  off*/\n        {  1, 2, 3, 4, 5, 6, 7, 8,16,24,36,44,50,56,62,67,72,79,88,106,134};\n      static const opus_val16 intensity_histeresis[21]=\n        {  1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 5, 6,  8, 8};\n\n      /* Always use MS for 2.5 ms frames until we can do a better analysis */\n      if (LM!=0)\n         dual_stereo = stereo_analysis(mode, X, LM, N);\n\n      st->intensity = hysteresis_decision((opus_val16)(equiv_rate/1000),\n            intensity_thresholds, intensity_histeresis, 21, st->intensity);\n      st->intensity = IMIN(end,IMAX(start, st->intensity));\n   }\n\n   alloc_trim = 5;\n   if (tell+(6<<BITRES) <= total_bits - total_boost)\n   {\n      if (st->lfe)\n         alloc_trim = 5;\n      else\n         alloc_trim = alloc_trim_analysis(mode, X, bandLogE,\n            end, LM, C, N, &st->analysis, &st->stereo_saving, tf_estimate,\n            st->intensity, surround_trim, st->arch);\n      ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);\n      tell = ec_tell_frac(enc);\n   }\n\n   /* Variable bitrate */\n   if (vbr_rate>0)\n   {\n     opus_val16 alpha;\n     opus_int32 delta;\n     /* The target rate in 8th bits per frame */\n     opus_int32 target, base_target;\n     opus_int32 min_allowed;\n     int lm_diff = mode->maxLM - LM;\n\n     /* Don't attempt to use more than 510 kb/s, even for frames smaller than 20 ms.\n        The CELT allocator will just not be able to use more than that anyway. */\n     nbCompressedBytes = IMIN(nbCompressedBytes,1275>>(3-LM));\n     base_target = vbr_rate - ((40*C+20)<<BITRES);\n\n     if (st->constrained_vbr)\n        base_target += (st->vbr_offset>>lm_diff);\n\n     target = compute_vbr(mode, &st->analysis, base_target, LM, equiv_rate,\n           st->lastCodedBands, C, st->intensity, st->constrained_vbr,\n           st->stereo_saving, tot_boost, tf_estimate, pitch_change, maxDepth,\n           st->variable_duration, st->lfe, st->energy_mask!=NULL, surround_masking,\n           temporal_vbr);\n\n     /* The current offset is removed from the target and the space used\n        so far is added*/\n     target=target+tell;\n     /* In VBR mode the frame size must not be reduced so much that it would\n         result in the encoder running out of bits.\n        The margin of 2 bytes ensures that none of the bust-prevention logic\n         in the decoder will have triggered so far. */\n     min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2 - nbFilledBytes;\n\n     nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3);\n     nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes);\n     nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes) - nbFilledBytes;\n\n     /* By how much did we \"miss\" the target on that frame */\n     delta = target - vbr_rate;\n\n     target=nbAvailableBytes<<(BITRES+3);\n\n     /*If the frame is silent we don't adjust our drift, otherwise\n       the encoder will shoot to very high rates after hitting a\n       span of silence, but we do allow the bitres to refill.\n       This means that we'll undershoot our target in CVBR/VBR modes\n       on files with lots of silence. */\n     if(silence)\n     {\n       nbAvailableBytes = 2;\n       target = 2*8<<BITRES;\n       delta = 0;\n     }\n\n     if (st->vbr_count < 970)\n     {\n        st->vbr_count++;\n        alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16));\n     } else\n        alpha = QCONST16(.001f,15);\n     /* How many bits have we used in excess of what we're allowed */\n     if (st->constrained_vbr)\n        st->vbr_reservoir += target - vbr_rate;\n     /*printf (\"%d\\n\", st->vbr_reservoir);*/\n\n     /* Compute the offset we need to apply in order to reach the target */\n     if (st->constrained_vbr)\n     {\n        st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,(delta*(1<<lm_diff))-st->vbr_offset-st->vbr_drift);\n        st->vbr_offset = -st->vbr_drift;\n     }\n     /*printf (\"%d\\n\", st->vbr_drift);*/\n\n     if (st->constrained_vbr && st->vbr_reservoir < 0)\n     {\n        /* We're under the min value -- increase rate */\n        int adjust = (-st->vbr_reservoir)/(8<<BITRES);\n        /* Unless we're just coding silence */\n        nbAvailableBytes += silence?0:adjust;\n        st->vbr_reservoir = 0;\n        /*printf (\"+%d\\n\", adjust);*/\n     }\n     nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes);\n     /*printf(\"%d\\n\", nbCompressedBytes*50*8);*/\n     /* This moves the raw bits to take into account the new compressed size */\n     ec_enc_shrink(enc, nbCompressedBytes);\n   }\n\n   /* Bit allocation */\n   ALLOC(fine_quant, nbEBands, int);\n   ALLOC(pulses, nbEBands, int);\n   ALLOC(fine_priority, nbEBands, int);\n\n   /* bits =           packet size                    - where we are - safety*/\n   bits = (((opus_int32)nbCompressedBytes*8)<<BITRES) - ec_tell_frac(enc) - 1;\n   anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;\n   bits -= anti_collapse_rsv;\n   signalBandwidth = end-1;\n#ifndef DISABLE_FLOAT_API\n   if (st->analysis.valid)\n   {\n      int min_bandwidth;\n      if (equiv_rate < (opus_int32)32000*C)\n         min_bandwidth = 13;\n      else if (equiv_rate < (opus_int32)48000*C)\n         min_bandwidth = 16;\n      else if (equiv_rate < (opus_int32)60000*C)\n         min_bandwidth = 18;\n      else  if (equiv_rate < (opus_int32)80000*C)\n         min_bandwidth = 19;\n      else\n         min_bandwidth = 20;\n      signalBandwidth = IMAX(st->analysis.bandwidth, min_bandwidth);\n   }\n#endif\n   if (st->lfe)\n      signalBandwidth = 1;\n   codedBands = compute_allocation(mode, start, end, offsets, cap,\n         alloc_trim, &st->intensity, &dual_stereo, bits, &balance, pulses,\n         fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands, signalBandwidth);\n   if (st->lastCodedBands)\n      st->lastCodedBands = IMIN(st->lastCodedBands+1,IMAX(st->lastCodedBands-1,codedBands));\n   else\n      st->lastCodedBands = codedBands;\n\n   quant_fine_energy(mode, start, end, oldBandE, error, fine_quant, enc, C);\n\n   /* Residual quantisation */\n   ALLOC(collapse_masks, C*nbEBands, unsigned char);\n   quant_all_bands(1, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,\n         bandE, pulses, shortBlocks, st->spread_decision,\n         dual_stereo, st->intensity, tf_res, nbCompressedBytes*(8<<BITRES)-anti_collapse_rsv,\n         balance, enc, LM, codedBands, &st->rng, st->arch);\n\n   if (anti_collapse_rsv > 0)\n   {\n      anti_collapse_on = st->consec_transient<2;\n#ifdef FUZZING\n      anti_collapse_on = rand()&0x1;\n#endif\n      ec_enc_bits(enc, anti_collapse_on, 1);\n   }\n   quant_energy_finalise(mode, start, end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C);\n\n   if (silence)\n   {\n      for (i=0;i<C*nbEBands;i++)\n         oldBandE[i] = -QCONST16(28.f,DB_SHIFT);\n   }\n\n#ifdef RESYNTH\n   /* Re-synthesis of the coded audio if required */\n   {\n      celt_sig *out_mem[2];\n\n      if (anti_collapse_on)\n      {\n         anti_collapse(mode, X, collapse_masks, LM, C, N,\n               start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);\n      }\n\n      c=0; do {\n         OPUS_MOVE(st->syn_mem[c], st->syn_mem[c]+N, 2*MAX_PERIOD-N+overlap/2);\n      } while (++c<CC);\n\n      c=0; do {\n         out_mem[c] = st->syn_mem[c]+2*MAX_PERIOD-N;\n      } while (++c<CC);\n\n      celt_synthesis(mode, X, out_mem, oldBandE, start, effEnd,\n                     C, CC, isTransient, LM, st->upsample, silence, st->arch);\n\n      c=0; do {\n         st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);\n         st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD);\n         comb_filter(out_mem[c], out_mem[c], st->prefilter_period_old, st->prefilter_period, mode->shortMdctSize,\n               st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset,\n               mode->window, overlap);\n         if (LM!=0)\n            comb_filter(out_mem[c]+mode->shortMdctSize, out_mem[c]+mode->shortMdctSize, st->prefilter_period, pitch_index, N-mode->shortMdctSize,\n                  st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset,\n                  mode->window, overlap);\n      } while (++c<CC);\n\n      /* We reuse freq[] as scratch space for the de-emphasis */\n      deemphasis(out_mem, (opus_val16*)pcm, N, CC, st->upsample, mode->preemph, st->preemph_memD);\n      st->prefilter_period_old = st->prefilter_period;\n      st->prefilter_gain_old = st->prefilter_gain;\n      st->prefilter_tapset_old = st->prefilter_tapset;\n   }\n#endif\n\n   st->prefilter_period = pitch_index;\n   st->prefilter_gain = gain1;\n   st->prefilter_tapset = prefilter_tapset;\n#ifdef RESYNTH\n   if (LM!=0)\n   {\n      st->prefilter_period_old = st->prefilter_period;\n      st->prefilter_gain_old = st->prefilter_gain;\n      st->prefilter_tapset_old = st->prefilter_tapset;\n   }\n#endif\n\n   if (CC==2&&C==1) {\n      OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands);\n   }\n\n   if (!isTransient)\n   {\n      OPUS_COPY(oldLogE2, oldLogE, CC*nbEBands);\n      OPUS_COPY(oldLogE, oldBandE, CC*nbEBands);\n   } else {\n      for (i=0;i<CC*nbEBands;i++)\n         oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);\n   }\n   /* In case start or end were to change */\n   c=0; do\n   {\n      for (i=0;i<start;i++)\n      {\n         oldBandE[c*nbEBands+i]=0;\n         oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);\n      }\n      for (i=end;i<nbEBands;i++)\n      {\n         oldBandE[c*nbEBands+i]=0;\n         oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);\n      }\n   } while (++c<CC);\n\n   if (isTransient || transient_got_disabled)\n      st->consec_transient++;\n   else\n      st->consec_transient=0;\n   st->rng = enc->rng;\n\n   /* If there's any room left (can only happen for very high rates),\n      it's already filled with zeros */\n   ec_enc_done(enc);\n\n#ifdef CUSTOM_MODES\n   if (st->signalling)\n      nbCompressedBytes++;\n#endif\n\n   RESTORE_STACK;\n   if (ec_get_error(enc))\n      return OPUS_INTERNAL_ERROR;\n   else\n      return nbCompressedBytes;\n}\n\n\n#ifdef CUSTOM_MODES\n\n#ifdef FIXED_POINT\nint opus_custom_encode(CELTEncoder * OPUS_RESTRICT st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)\n{\n   return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);\n}\n\n#ifndef DISABLE_FLOAT_API\nint opus_custom_encode_float(CELTEncoder * OPUS_RESTRICT st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)\n{\n   int j, ret, C, N;\n   VARDECL(opus_int16, in);\n   ALLOC_STACK;\n\n   if (pcm==NULL)\n      return OPUS_BAD_ARG;\n\n   C = st->channels;\n   N = frame_size;\n   ALLOC(in, C*N, opus_int16);\n\n   for (j=0;j<C*N;j++)\n     in[j] = FLOAT2INT16(pcm[j]);\n\n   ret=celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, NULL);\n#ifdef RESYNTH\n   for (j=0;j<C*N;j++)\n      ((float*)pcm)[j]=in[j]*(1.f/32768.f);\n#endif\n   RESTORE_STACK;\n   return ret;\n}\n#endif /* DISABLE_FLOAT_API */\n#else\n\nint opus_custom_encode(CELTEncoder * OPUS_RESTRICT st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)\n{\n   int j, ret, C, N;\n   VARDECL(celt_sig, in);\n   ALLOC_STACK;\n\n   if (pcm==NULL)\n      return OPUS_BAD_ARG;\n\n   C=st->channels;\n   N=frame_size;\n   ALLOC(in, C*N, celt_sig);\n   for (j=0;j<C*N;j++) {\n     in[j] = SCALEOUT(pcm[j]);\n   }\n\n   ret = celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, NULL);\n#ifdef RESYNTH\n   for (j=0;j<C*N;j++)\n      ((opus_int16*)pcm)[j] = FLOAT2INT16(in[j]);\n#endif\n   RESTORE_STACK;\n   return ret;\n}\n\nint opus_custom_encode_float(CELTEncoder * OPUS_RESTRICT st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)\n{\n   return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);\n}\n\n#endif\n\n#endif /* CUSTOM_MODES */\n\nint opus_custom_encoder_ctl(CELTEncoder * OPUS_RESTRICT st, int request, ...)\n{\n   va_list ap;\n\n   va_start(ap, request);\n   switch (request)\n   {\n      case OPUS_SET_COMPLEXITY_REQUEST:\n      {\n         int value = va_arg(ap, opus_int32);\n         if (value<0 || value>10)\n            goto bad_arg;\n         st->complexity = value;\n      }\n      break;\n      case CELT_SET_START_BAND_REQUEST:\n      {\n         opus_int32 value = va_arg(ap, opus_int32);\n         if (value<0 || value>=st->mode->nbEBands)\n            goto bad_arg;\n         st->start = value;\n      }\n      break;\n      case CELT_SET_END_BAND_REQUEST:\n      {\n         opus_int32 value = va_arg(ap, opus_int32);\n         if (value<1 || value>st->mode->nbEBands)\n            goto bad_arg;\n         st->end = value;\n      }\n      break;\n      case CELT_SET_PREDICTION_REQUEST:\n      {\n         int value = va_arg(ap, opus_int32);\n         if (value<0 || value>2)\n            goto bad_arg;\n         st->disable_pf = value<=1;\n         st->force_intra = value==0;\n      }\n      break;\n      case OPUS_SET_PACKET_LOSS_PERC_REQUEST:\n      {\n         int value = va_arg(ap, opus_int32);\n         if (value<0 || value>100)\n            goto bad_arg;\n         st->loss_rate = value;\n      }\n      break;\n      case OPUS_SET_VBR_CONSTRAINT_REQUEST:\n      {\n         opus_int32 value = va_arg(ap, opus_int32);\n         st->constrained_vbr = value;\n      }\n      break;\n      case OPUS_SET_VBR_REQUEST:\n      {\n         opus_int32 value = va_arg(ap, opus_int32);\n         st->vbr = value;\n      }\n      break;\n      case OPUS_SET_BITRATE_REQUEST:\n      {\n         opus_int32 value = va_arg(ap, opus_int32);\n         if (value<=500 && value!=OPUS_BITRATE_MAX)\n            goto bad_arg;\n         value = IMIN(value, 260000*st->channels);\n         st->bitrate = value;\n      }\n      break;\n      case CELT_SET_CHANNELS_REQUEST:\n      {\n         opus_int32 value = va_arg(ap, opus_int32);\n         if (value<1 || value>2)\n            goto bad_arg;\n         st->stream_channels = value;\n      }\n      break;\n      case OPUS_SET_LSB_DEPTH_REQUEST:\n      {\n          opus_int32 value = va_arg(ap, opus_int32);\n          if (value<8 || value>24)\n             goto bad_arg;\n          st->lsb_depth=value;\n      }\n      break;\n      case OPUS_GET_LSB_DEPTH_REQUEST:\n      {\n          opus_int32 *value = va_arg(ap, opus_int32*);\n          *value=st->lsb_depth;\n      }\n      break;\n      case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:\n      {\n          opus_int32 value = va_arg(ap, opus_int32);\n          st->variable_duration = value;\n      }\n      break;\n      case OPUS_RESET_STATE:\n      {\n         int i;\n         opus_val16 *oldBandE, *oldLogE, *oldLogE2;\n         oldBandE = (opus_val16*)(st->in_mem+st->channels*(st->mode->overlap+COMBFILTER_MAXPERIOD));\n         oldLogE = oldBandE + st->channels*st->mode->nbEBands;\n         oldLogE2 = oldLogE + st->channels*st->mode->nbEBands;\n         OPUS_CLEAR((char*)&st->ENCODER_RESET_START,\n               opus_custom_encoder_get_size(st->mode, st->channels)-\n               ((char*)&st->ENCODER_RESET_START - (char*)st));\n         for (i=0;i<st->channels*st->mode->nbEBands;i++)\n            oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);\n         st->vbr_offset = 0;\n         st->delayedIntra = 1;\n         st->spread_decision = SPREAD_NORMAL;\n         st->tonal_average = 256;\n         st->hf_average = 0;\n         st->tapset_decision = 0;\n      }\n      break;\n#ifdef CUSTOM_MODES\n      case CELT_SET_INPUT_CLIPPING_REQUEST:\n      {\n         opus_int32 value = va_arg(ap, opus_int32);\n         st->clip = value;\n      }\n      break;\n#endif\n      case CELT_SET_SIGNALLING_REQUEST:\n      {\n         opus_int32 value = va_arg(ap, opus_int32);\n         st->signalling = value;\n      }\n      break;\n      case CELT_SET_ANALYSIS_REQUEST:\n      {\n         AnalysisInfo *info = va_arg(ap, AnalysisInfo *);\n         if (info)\n            OPUS_COPY(&st->analysis, info, 1);\n      }\n      break;\n      case CELT_GET_MODE_REQUEST:\n      {\n         const CELTMode ** value = va_arg(ap, const CELTMode**);\n         if (value==0)\n            goto bad_arg;\n         *value=st->mode;\n      }\n      break;\n      case OPUS_GET_FINAL_RANGE_REQUEST:\n      {\n         opus_uint32 * value = va_arg(ap, opus_uint32 *);\n         if (value==0)\n            goto bad_arg;\n         *value=st->rng;\n      }\n      break;\n      case OPUS_SET_LFE_REQUEST:\n      {\n          opus_int32 value = va_arg(ap, opus_int32);\n          st->lfe = value;\n      }\n      break;\n      case OPUS_SET_ENERGY_MASK_REQUEST:\n      {\n          opus_val16 *value = va_arg(ap, opus_val16*);\n          st->energy_mask = value;\n      }\n      break;\n      default:\n         goto bad_request;\n   }\n   va_end(ap);\n   return OPUS_OK;\nbad_arg:\n   va_end(ap);\n   return OPUS_BAD_ARG;\nbad_request:\n   va_end(ap);\n   return OPUS_UNIMPLEMENTED;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/celt_lpc.c",
    "content": "/* Copyright (c) 2009-2010 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"celt_lpc.h\"\n#include \"stack_alloc.h\"\n#include \"mathops.h\"\n#include \"pitch.h\"\n\nvoid _celt_lpc(\n      opus_val16       *_lpc, /* out: [0...p-1] LPC coefficients      */\nconst opus_val32 *ac,  /* in:  [0...p] autocorrelation values  */\nint          p\n)\n{\n   int i, j;\n   opus_val32 r;\n   opus_val32 error = ac[0];\n#ifdef FIXED_POINT\n   opus_val32 lpc[LPC_ORDER];\n#else\n   float *lpc = _lpc;\n#endif\n\n   for (i = 0; i < p; i++)\n      lpc[i] = 0;\n   if (ac[0] != 0)\n   {\n      for (i = 0; i < p; i++) {\n         /* Sum up this iteration's reflection coefficient */\n         opus_val32 rr = 0;\n         for (j = 0; j < i; j++)\n            rr += MULT32_32_Q31(lpc[j],ac[i - j]);\n         rr += SHR32(ac[i + 1],3);\n         r = -frac_div32(SHL32(rr,3), error);\n         /*  Update LPC coefficients and total error */\n         lpc[i] = SHR32(r,3);\n         for (j = 0; j < (i+1)>>1; j++)\n         {\n            opus_val32 tmp1, tmp2;\n            tmp1 = lpc[j];\n            tmp2 = lpc[i-1-j];\n            lpc[j]     = tmp1 + MULT32_32_Q31(r,tmp2);\n            lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1);\n         }\n\n         error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error);\n         /* Bail out once we get 30 dB gain */\n#ifdef FIXED_POINT\n         if (error<SHR32(ac[0],10))\n            break;\n#else\n         if (error<.001f*ac[0])\n            break;\n#endif\n      }\n   }\n#ifdef FIXED_POINT\n   for (i=0;i<p;i++)\n      _lpc[i] = ROUND16(lpc[i],16);\n#endif\n}\n\n\nvoid celt_fir_c(\n         const opus_val16 *_x,\n         const opus_val16 *num,\n         opus_val16 *_y,\n         int N,\n         int ord,\n         opus_val16 *mem,\n         int arch)\n{\n   int i,j;\n   VARDECL(opus_val16, rnum);\n   VARDECL(opus_val16, x);\n   SAVE_STACK;\n\n   ALLOC(rnum, ord, opus_val16);\n   ALLOC(x, N+ord, opus_val16);\n   for(i=0;i<ord;i++)\n      rnum[i] = num[ord-i-1];\n   for(i=0;i<ord;i++)\n      x[i] = mem[ord-i-1];\n   for (i=0;i<N;i++)\n      x[i+ord]=_x[i];\n   for(i=0;i<ord;i++)\n      mem[i] = _x[N-i-1];\n#ifdef SMALL_FOOTPRINT\n   (void)arch;\n   for (i=0;i<N;i++)\n   {\n      opus_val32 sum = SHL32(EXTEND32(_x[i]), SIG_SHIFT);\n      for (j=0;j<ord;j++)\n      {\n         sum = MAC16_16(sum,rnum[j],x[i+j]);\n      }\n      _y[i] = SATURATE16(PSHR32(sum, SIG_SHIFT));\n   }\n#else\n   for (i=0;i<N-3;i+=4)\n   {\n      opus_val32 sum[4]={0,0,0,0};\n      xcorr_kernel(rnum, x+i, sum, ord, arch);\n      _y[i  ] = SATURATE16(ADD32(EXTEND32(_x[i  ]), PSHR32(sum[0], SIG_SHIFT)));\n      _y[i+1] = SATURATE16(ADD32(EXTEND32(_x[i+1]), PSHR32(sum[1], SIG_SHIFT)));\n      _y[i+2] = SATURATE16(ADD32(EXTEND32(_x[i+2]), PSHR32(sum[2], SIG_SHIFT)));\n      _y[i+3] = SATURATE16(ADD32(EXTEND32(_x[i+3]), PSHR32(sum[3], SIG_SHIFT)));\n   }\n   for (;i<N;i++)\n   {\n      opus_val32 sum = 0;\n      for (j=0;j<ord;j++)\n         sum = MAC16_16(sum,rnum[j],x[i+j]);\n      _y[i] = SATURATE16(ADD32(EXTEND32(_x[i]), PSHR32(sum, SIG_SHIFT)));\n   }\n#endif\n   RESTORE_STACK;\n}\n\nvoid celt_iir(const opus_val32 *_x,\n         const opus_val16 *den,\n         opus_val32 *_y,\n         int N,\n         int ord,\n         opus_val16 *mem,\n         int arch)\n{\n#ifdef SMALL_FOOTPRINT\n   int i,j;\n   (void)arch;\n   for (i=0;i<N;i++)\n   {\n      opus_val32 sum = _x[i];\n      for (j=0;j<ord;j++)\n      {\n         sum -= MULT16_16(den[j],mem[j]);\n      }\n      for (j=ord-1;j>=1;j--)\n      {\n         mem[j]=mem[j-1];\n      }\n      mem[0] = ROUND16(sum,SIG_SHIFT);\n      _y[i] = sum;\n   }\n#else\n   int i,j;\n   VARDECL(opus_val16, rden);\n   VARDECL(opus_val16, y);\n   SAVE_STACK;\n\n   celt_assert((ord&3)==0);\n   ALLOC(rden, ord, opus_val16);\n   ALLOC(y, N+ord, opus_val16);\n   for(i=0;i<ord;i++)\n      rden[i] = den[ord-i-1];\n   for(i=0;i<ord;i++)\n      y[i] = -mem[ord-i-1];\n   for(;i<N+ord;i++)\n      y[i]=0;\n   for (i=0;i<N-3;i+=4)\n   {\n      /* Unroll by 4 as if it were an FIR filter */\n      opus_val32 sum[4];\n      sum[0]=_x[i];\n      sum[1]=_x[i+1];\n      sum[2]=_x[i+2];\n      sum[3]=_x[i+3];\n      xcorr_kernel(rden, y+i, sum, ord, arch);\n\n      /* Patch up the result to compensate for the fact that this is an IIR */\n      y[i+ord  ] = -ROUND16(sum[0],SIG_SHIFT);\n      _y[i  ] = sum[0];\n      sum[1] = MAC16_16(sum[1], y[i+ord  ], den[0]);\n      y[i+ord+1] = -ROUND16(sum[1],SIG_SHIFT);\n      _y[i+1] = sum[1];\n      sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);\n      sum[2] = MAC16_16(sum[2], y[i+ord  ], den[1]);\n      y[i+ord+2] = -ROUND16(sum[2],SIG_SHIFT);\n      _y[i+2] = sum[2];\n\n      sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);\n      sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);\n      sum[3] = MAC16_16(sum[3], y[i+ord  ], den[2]);\n      y[i+ord+3] = -ROUND16(sum[3],SIG_SHIFT);\n      _y[i+3] = sum[3];\n   }\n   for (;i<N;i++)\n   {\n      opus_val32 sum = _x[i];\n      for (j=0;j<ord;j++)\n         sum -= MULT16_16(rden[j],y[i+j]);\n      y[i+ord] = ROUND16(sum,SIG_SHIFT);\n      _y[i] = sum;\n   }\n   for(i=0;i<ord;i++)\n      mem[i] = _y[N-i-1];\n   RESTORE_STACK;\n#endif\n}\n\nint _celt_autocorr(\n                   const opus_val16 *x,   /*  in: [0...n-1] samples x   */\n                   opus_val32       *ac,  /* out: [0...lag-1] ac values */\n                   const opus_val16       *window,\n                   int          overlap,\n                   int          lag,\n                   int          n,\n                   int          arch\n                  )\n{\n   opus_val32 d;\n   int i, k;\n   int fastN=n-lag;\n   int shift;\n   const opus_val16 *xptr;\n   VARDECL(opus_val16, xx);\n   SAVE_STACK;\n   ALLOC(xx, n, opus_val16);\n   celt_assert(n>0);\n   celt_assert(overlap>=0);\n   if (overlap == 0)\n   {\n      xptr = x;\n   } else {\n      for (i=0;i<n;i++)\n         xx[i] = x[i];\n      for (i=0;i<overlap;i++)\n      {\n         xx[i] = MULT16_16_Q15(x[i],window[i]);\n         xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]);\n      }\n      xptr = xx;\n   }\n   shift=0;\n#ifdef FIXED_POINT\n   {\n      opus_val32 ac0;\n      ac0 = 1+(n<<7);\n      if (n&1) ac0 += SHR32(MULT16_16(xptr[0],xptr[0]),9);\n      for(i=(n&1);i<n;i+=2)\n      {\n         ac0 += SHR32(MULT16_16(xptr[i],xptr[i]),9);\n         ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),9);\n      }\n\n      shift = celt_ilog2(ac0)-30+10;\n      shift = (shift)/2;\n      if (shift>0)\n      {\n         for(i=0;i<n;i++)\n            xx[i] = PSHR32(xptr[i], shift);\n         xptr = xx;\n      } else\n         shift = 0;\n   }\n#endif\n   celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1, arch);\n   for (k=0;k<=lag;k++)\n   {\n      for (i = k+fastN, d = 0; i < n; i++)\n         d = MAC16_16(d, xptr[i], xptr[i-k]);\n      ac[k] += d;\n   }\n#ifdef FIXED_POINT\n   shift = 2*shift;\n   if (shift<=0)\n      ac[0] += SHL32((opus_int32)1, -shift);\n   if (ac[0] < 268435456)\n   {\n      int shift2 = 29 - EC_ILOG(ac[0]);\n      for (i=0;i<=lag;i++)\n         ac[i] = SHL32(ac[i], shift2);\n      shift -= shift2;\n   } else if (ac[0] >= 536870912)\n   {\n      int shift2=1;\n      if (ac[0] >= 1073741824)\n         shift2++;\n      for (i=0;i<=lag;i++)\n         ac[i] = SHR32(ac[i], shift2);\n      shift += shift2;\n   }\n#endif\n\n   RESTORE_STACK;\n   return shift;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/celt_lpc.h",
    "content": "/* Copyright (c) 2009-2010 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef PLC_H\n#define PLC_H\n\n#include \"arch.h\"\n#include \"cpu_support.h\"\n\n#if defined(OPUS_X86_MAY_HAVE_SSE4_1)\n#include \"x86/celt_lpc_sse.h\"\n#endif\n\n#define LPC_ORDER 24\n\nvoid _celt_lpc(opus_val16 *_lpc, const opus_val32 *ac, int p);\n\nvoid celt_fir_c(\n         const opus_val16 *x,\n         const opus_val16 *num,\n         opus_val16 *y,\n         int N,\n         int ord,\n         opus_val16 *mem,\n         int arch);\n\n#if !defined(OVERRIDE_CELT_FIR)\n#define celt_fir(x, num, y, N, ord, mem, arch) \\\n    (celt_fir_c(x, num, y, N, ord, mem, arch))\n#endif\n\nvoid celt_iir(const opus_val32 *x,\n         const opus_val16 *den,\n         opus_val32 *y,\n         int N,\n         int ord,\n         opus_val16 *mem,\n         int arch);\n\nint _celt_autocorr(const opus_val16 *x, opus_val32 *ac,\n         const opus_val16 *window, int overlap, int lag, int n, int arch);\n\n#endif /* PLC_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/cpu_support.h",
    "content": "/* Copyright (c) 2010 Xiph.Org Foundation\n * Copyright (c) 2013 Parrot */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef CPU_SUPPORT_H\n#define CPU_SUPPORT_H\n\n#include \"opus_types.h\"\n#include \"opus_defines.h\"\n\n#if defined(OPUS_HAVE_RTCD) && \\\n  (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))\n#include \"arm/armcpu.h\"\n\n/* We currently support 4 ARM variants:\n * arch[0] -> ARMv4\n * arch[1] -> ARMv5E\n * arch[2] -> ARMv6\n * arch[3] -> NEON\n */\n#define OPUS_ARCHMASK 3\n\n#elif (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(OPUS_X86_PRESUME_SSE)) || \\\n  (defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2)) || \\\n  (defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)) || \\\n  (defined(OPUS_X86_MAY_HAVE_AVX) && !defined(OPUS_X86_PRESUME_AVX))\n\n#include \"x86/x86cpu.h\"\n/* We currently support 5 x86 variants:\n * arch[0] -> non-sse\n * arch[1] -> sse\n * arch[2] -> sse2\n * arch[3] -> sse4.1\n * arch[4] -> avx\n */\n#define OPUS_ARCHMASK 7\nint opus_select_arch(void);\n\n#else\n#define OPUS_ARCHMASK 0\n\nstatic OPUS_INLINE int opus_select_arch(void)\n{\n  return 0;\n}\n#endif\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/cwrs.c",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Copyright (c) 2007-2009 Timothy B. Terriberry\n   Written by Timothy B. Terriberry and Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"os_support.h\"\n#include \"cwrs.h\"\n#include \"mathops.h\"\n#include \"arch.h\"\n\n#ifdef CUSTOM_MODES\n\n/*Guaranteed to return a conservatively large estimate of the binary logarithm\n   with frac bits of fractional precision.\n  Tested for all possible 32-bit inputs with frac=4, where the maximum\n   overestimation is 0.06254243 bits.*/\nint log2_frac(opus_uint32 val, int frac)\n{\n  int l;\n  l=EC_ILOG(val);\n  if(val&(val-1)){\n    /*This is (val>>l-16), but guaranteed to round up, even if adding a bias\n       before the shift would cause overflow (e.g., for 0xFFFFxxxx).\n       Doesn't work for val=0, but that case fails the test above.*/\n    if(l>16)val=((val-1)>>(l-16))+1;\n    else val<<=16-l;\n    l=(l-1)<<frac;\n    /*Note that we always need one iteration, since the rounding up above means\n       that we might need to adjust the integer part of the logarithm.*/\n    do{\n      int b;\n      b=(int)(val>>16);\n      l+=b<<frac;\n      val=(val+b)>>b;\n      val=(val*val+0x7FFF)>>15;\n    }\n    while(frac-->0);\n    /*If val is not exactly 0x8000, then we have to round up the remainder.*/\n    return l+(val>0x8000);\n  }\n  /*Exact powers of two require no rounding.*/\n  else return (l-1)<<frac;\n}\n#endif\n\n/*Although derived separately, the pulse vector coding scheme is equivalent to\n   a Pyramid Vector Quantizer \\cite{Fis86}.\n  Some additional notes about an early version appear at\n   http://people.xiph.org/~tterribe/notes/cwrs.html, but the codebook ordering\n   and the definitions of some terms have evolved since that was written.\n\n  The conversion from a pulse vector to an integer index (encoding) and back\n   (decoding) is governed by two related functions, V(N,K) and U(N,K).\n\n  V(N,K) = the number of combinations, with replacement, of N items, taken K\n   at a time, when a sign bit is added to each item taken at least once (i.e.,\n   the number of N-dimensional unit pulse vectors with K pulses).\n  One way to compute this is via\n    V(N,K) = K>0 ? sum(k=1...K,2**k*choose(N,k)*choose(K-1,k-1)) : 1,\n   where choose() is the binomial function.\n  A table of values for N<10 and K<10 looks like:\n  V[10][10] = {\n    {1,  0,   0,    0,    0,     0,     0,      0,      0,       0},\n    {1,  2,   2,    2,    2,     2,     2,      2,      2,       2},\n    {1,  4,   8,   12,   16,    20,    24,     28,     32,      36},\n    {1,  6,  18,   38,   66,   102,   146,    198,    258,     326},\n    {1,  8,  32,   88,  192,   360,   608,    952,   1408,    1992},\n    {1, 10,  50,  170,  450,  1002,  1970,   3530,   5890,    9290},\n    {1, 12,  72,  292,  912,  2364,  5336,  10836,  20256,   35436},\n    {1, 14,  98,  462, 1666,  4942, 12642,  28814,  59906,  115598},\n    {1, 16, 128,  688, 2816,  9424, 27008,  68464, 157184,  332688},\n    {1, 18, 162,  978, 4482, 16722, 53154, 148626, 374274,  864146}\n  };\n\n  U(N,K) = the number of such combinations wherein N-1 objects are taken at\n   most K-1 at a time.\n  This is given by\n    U(N,K) = sum(k=0...K-1,V(N-1,k))\n           = K>0 ? (V(N-1,K-1) + V(N,K-1))/2 : 0.\n  The latter expression also makes clear that U(N,K) is half the number of such\n   combinations wherein the first object is taken at least once.\n  Although it may not be clear from either of these definitions, U(N,K) is the\n   natural function to work with when enumerating the pulse vector codebooks,\n   not V(N,K).\n  U(N,K) is not well-defined for N=0, but with the extension\n    U(0,K) = K>0 ? 0 : 1,\n   the function becomes symmetric: U(N,K) = U(K,N), with a similar table:\n  U[10][10] = {\n    {1, 0,  0,   0,    0,    0,     0,     0,      0,      0},\n    {0, 1,  1,   1,    1,    1,     1,     1,      1,      1},\n    {0, 1,  3,   5,    7,    9,    11,    13,     15,     17},\n    {0, 1,  5,  13,   25,   41,    61,    85,    113,    145},\n    {0, 1,  7,  25,   63,  129,   231,   377,    575,    833},\n    {0, 1,  9,  41,  129,  321,   681,  1289,   2241,   3649},\n    {0, 1, 11,  61,  231,  681,  1683,  3653,   7183,  13073},\n    {0, 1, 13,  85,  377, 1289,  3653,  8989,  19825,  40081},\n    {0, 1, 15, 113,  575, 2241,  7183, 19825,  48639, 108545},\n    {0, 1, 17, 145,  833, 3649, 13073, 40081, 108545, 265729}\n  };\n\n  With this extension, V(N,K) may be written in terms of U(N,K):\n    V(N,K) = U(N,K) + U(N,K+1)\n   for all N>=0, K>=0.\n  Thus U(N,K+1) represents the number of combinations where the first element\n   is positive or zero, and U(N,K) represents the number of combinations where\n   it is negative.\n  With a large enough table of U(N,K) values, we could write O(N) encoding\n   and O(min(N*log(K),N+K)) decoding routines, but such a table would be\n   prohibitively large for small embedded devices (K may be as large as 32767\n   for small N, and N may be as large as 200).\n\n  Both functions obey the same recurrence relation:\n    V(N,K) = V(N-1,K) + V(N,K-1) + V(N-1,K-1),\n    U(N,K) = U(N-1,K) + U(N,K-1) + U(N-1,K-1),\n   for all N>0, K>0, with different initial conditions at N=0 or K=0.\n  This allows us to construct a row of one of the tables above given the\n   previous row or the next row.\n  Thus we can derive O(NK) encoding and decoding routines with O(K) memory\n   using only addition and subtraction.\n\n  When encoding, we build up from the U(2,K) row and work our way forwards.\n  When decoding, we need to start at the U(N,K) row and work our way backwards,\n   which requires a means of computing U(N,K).\n  U(N,K) may be computed from two previous values with the same N:\n    U(N,K) = ((2*N-1)*U(N,K-1) - U(N,K-2))/(K-1) + U(N,K-2)\n   for all N>1, and since U(N,K) is symmetric, a similar relation holds for two\n   previous values with the same K:\n    U(N,K>1) = ((2*K-1)*U(N-1,K) - U(N-2,K))/(N-1) + U(N-2,K)\n   for all K>1.\n  This allows us to construct an arbitrary row of the U(N,K) table by starting\n   with the first two values, which are constants.\n  This saves roughly 2/3 the work in our O(NK) decoding routine, but costs O(K)\n   multiplications.\n  Similar relations can be derived for V(N,K), but are not used here.\n\n  For N>0 and K>0, U(N,K) and V(N,K) take on the form of an (N-1)-degree\n   polynomial for fixed N.\n  The first few are\n    U(1,K) = 1,\n    U(2,K) = 2*K-1,\n    U(3,K) = (2*K-2)*K+1,\n    U(4,K) = (((4*K-6)*K+8)*K-3)/3,\n    U(5,K) = ((((2*K-4)*K+10)*K-8)*K+3)/3,\n   and\n    V(1,K) = 2,\n    V(2,K) = 4*K,\n    V(3,K) = 4*K*K+2,\n    V(4,K) = 8*(K*K+2)*K/3,\n    V(5,K) = ((4*K*K+20)*K*K+6)/3,\n   for all K>0.\n  This allows us to derive O(N) encoding and O(N*log(K)) decoding routines for\n   small N (and indeed decoding is also O(N) for N<3).\n\n  @ARTICLE{Fis86,\n    author=\"Thomas R. Fischer\",\n    title=\"A Pyramid Vector Quantizer\",\n    journal=\"IEEE Transactions on Information Theory\",\n    volume=\"IT-32\",\n    number=4,\n    pages=\"568--583\",\n    month=Jul,\n    year=1986\n  }*/\n\n#if !defined(SMALL_FOOTPRINT)\n\n/*U(N,K) = U(K,N) := N>0?K>0?U(N-1,K)+U(N,K-1)+U(N-1,K-1):0:K>0?1:0*/\n# define CELT_PVQ_U(_n,_k) (CELT_PVQ_U_ROW[IMIN(_n,_k)][IMAX(_n,_k)])\n/*V(N,K) := U(N,K)+U(N,K+1) = the number of PVQ codewords for a band of size N\n   with K pulses allocated to it.*/\n# define CELT_PVQ_V(_n,_k) (CELT_PVQ_U(_n,_k)+CELT_PVQ_U(_n,(_k)+1))\n\n/*For each V(N,K) supported, we will access element U(min(N,K+1),max(N,K+1)).\n  Thus, the number of entries in row I is the larger of the maximum number of\n   pulses we will ever allocate for a given N=I (K=128, or however many fit in\n   32 bits, whichever is smaller), plus one, and the maximum N for which\n   K=I-1 pulses fit in 32 bits.\n  The largest band size in an Opus Custom mode is 208.\n  Otherwise, we can limit things to the set of N which can be achieved by\n   splitting a band from a standard Opus mode: 176, 144, 96, 88, 72, 64, 48,\n   44, 36, 32, 24, 22, 18, 16, 8, 4, 2).*/\n#if defined(CUSTOM_MODES)\nstatic const opus_uint32 CELT_PVQ_U_DATA[1488]={\n#else\nstatic const opus_uint32 CELT_PVQ_U_DATA[1272]={\n#endif\n  /*N=0, K=0...176:*/\n  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n#if defined(CUSTOM_MODES)\n  /*...208:*/\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0,\n#endif\n  /*N=1, K=1...176:*/\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n#if defined(CUSTOM_MODES)\n  /*...208:*/\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1,\n#endif\n  /*N=2, K=2...176:*/\n  3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41,\n  43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79,\n  81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113,\n  115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143,\n  145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173,\n  175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203,\n  205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233,\n  235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263,\n  265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293,\n  295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319, 321, 323,\n  325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351,\n#if defined(CUSTOM_MODES)\n  /*...208:*/\n  353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 377, 379, 381,\n  383, 385, 387, 389, 391, 393, 395, 397, 399, 401, 403, 405, 407, 409, 411,\n  413, 415,\n#endif\n  /*N=3, K=3...176:*/\n  13, 25, 41, 61, 85, 113, 145, 181, 221, 265, 313, 365, 421, 481, 545, 613,\n  685, 761, 841, 925, 1013, 1105, 1201, 1301, 1405, 1513, 1625, 1741, 1861,\n  1985, 2113, 2245, 2381, 2521, 2665, 2813, 2965, 3121, 3281, 3445, 3613, 3785,\n  3961, 4141, 4325, 4513, 4705, 4901, 5101, 5305, 5513, 5725, 5941, 6161, 6385,\n  6613, 6845, 7081, 7321, 7565, 7813, 8065, 8321, 8581, 8845, 9113, 9385, 9661,\n  9941, 10225, 10513, 10805, 11101, 11401, 11705, 12013, 12325, 12641, 12961,\n  13285, 13613, 13945, 14281, 14621, 14965, 15313, 15665, 16021, 16381, 16745,\n  17113, 17485, 17861, 18241, 18625, 19013, 19405, 19801, 20201, 20605, 21013,\n  21425, 21841, 22261, 22685, 23113, 23545, 23981, 24421, 24865, 25313, 25765,\n  26221, 26681, 27145, 27613, 28085, 28561, 29041, 29525, 30013, 30505, 31001,\n  31501, 32005, 32513, 33025, 33541, 34061, 34585, 35113, 35645, 36181, 36721,\n  37265, 37813, 38365, 38921, 39481, 40045, 40613, 41185, 41761, 42341, 42925,\n  43513, 44105, 44701, 45301, 45905, 46513, 47125, 47741, 48361, 48985, 49613,\n  50245, 50881, 51521, 52165, 52813, 53465, 54121, 54781, 55445, 56113, 56785,\n  57461, 58141, 58825, 59513, 60205, 60901, 61601,\n#if defined(CUSTOM_MODES)\n  /*...208:*/\n  62305, 63013, 63725, 64441, 65161, 65885, 66613, 67345, 68081, 68821, 69565,\n  70313, 71065, 71821, 72581, 73345, 74113, 74885, 75661, 76441, 77225, 78013,\n  78805, 79601, 80401, 81205, 82013, 82825, 83641, 84461, 85285, 86113,\n#endif\n  /*N=4, K=4...176:*/\n  63, 129, 231, 377, 575, 833, 1159, 1561, 2047, 2625, 3303, 4089, 4991, 6017,\n  7175, 8473, 9919, 11521, 13287, 15225, 17343, 19649, 22151, 24857, 27775,\n  30913, 34279, 37881, 41727, 45825, 50183, 54809, 59711, 64897, 70375, 76153,\n  82239, 88641, 95367, 102425, 109823, 117569, 125671, 134137, 142975, 152193,\n  161799, 171801, 182207, 193025, 204263, 215929, 228031, 240577, 253575,\n  267033, 280959, 295361, 310247, 325625, 341503, 357889, 374791, 392217,\n  410175, 428673, 447719, 467321, 487487, 508225, 529543, 551449, 573951,\n  597057, 620775, 645113, 670079, 695681, 721927, 748825, 776383, 804609,\n  833511, 863097, 893375, 924353, 956039, 988441, 1021567, 1055425, 1090023,\n  1125369, 1161471, 1198337, 1235975, 1274393, 1313599, 1353601, 1394407,\n  1436025, 1478463, 1521729, 1565831, 1610777, 1656575, 1703233, 1750759,\n  1799161, 1848447, 1898625, 1949703, 2001689, 2054591, 2108417, 2163175,\n  2218873, 2275519, 2333121, 2391687, 2451225, 2511743, 2573249, 2635751,\n  2699257, 2763775, 2829313, 2895879, 2963481, 3032127, 3101825, 3172583,\n  3244409, 3317311, 3391297, 3466375, 3542553, 3619839, 3698241, 3777767,\n  3858425, 3940223, 4023169, 4107271, 4192537, 4278975, 4366593, 4455399,\n  4545401, 4636607, 4729025, 4822663, 4917529, 5013631, 5110977, 5209575,\n  5309433, 5410559, 5512961, 5616647, 5721625, 5827903, 5935489, 6044391,\n  6154617, 6266175, 6379073, 6493319, 6608921, 6725887, 6844225, 6963943,\n  7085049, 7207551,\n#if defined(CUSTOM_MODES)\n  /*...208:*/\n  7331457, 7456775, 7583513, 7711679, 7841281, 7972327, 8104825, 8238783,\n  8374209, 8511111, 8649497, 8789375, 8930753, 9073639, 9218041, 9363967,\n  9511425, 9660423, 9810969, 9963071, 10116737, 10271975, 10428793, 10587199,\n  10747201, 10908807, 11072025, 11236863, 11403329, 11571431, 11741177,\n  11912575,\n#endif\n  /*N=5, K=5...176:*/\n  321, 681, 1289, 2241, 3649, 5641, 8361, 11969, 16641, 22569, 29961, 39041,\n  50049, 63241, 78889, 97281, 118721, 143529, 172041, 204609, 241601, 283401,\n  330409, 383041, 441729, 506921, 579081, 658689, 746241, 842249, 947241,\n  1061761, 1186369, 1321641, 1468169, 1626561, 1797441, 1981449, 2179241,\n  2391489, 2618881, 2862121, 3121929, 3399041, 3694209, 4008201, 4341801,\n  4695809, 5071041, 5468329, 5888521, 6332481, 6801089, 7295241, 7815849,\n  8363841, 8940161, 9545769, 10181641, 10848769, 11548161, 12280841, 13047849,\n  13850241, 14689089, 15565481, 16480521, 17435329, 18431041, 19468809,\n  20549801, 21675201, 22846209, 24064041, 25329929, 26645121, 28010881,\n  29428489, 30899241, 32424449, 34005441, 35643561, 37340169, 39096641,\n  40914369, 42794761, 44739241, 46749249, 48826241, 50971689, 53187081,\n  55473921, 57833729, 60268041, 62778409, 65366401, 68033601, 70781609,\n  73612041, 76526529, 79526721, 82614281, 85790889, 89058241, 92418049,\n  95872041, 99421961, 103069569, 106816641, 110664969, 114616361, 118672641,\n  122835649, 127107241, 131489289, 135983681, 140592321, 145317129, 150160041,\n  155123009, 160208001, 165417001, 170752009, 176215041, 181808129, 187533321,\n  193392681, 199388289, 205522241, 211796649, 218213641, 224775361, 231483969,\n  238341641, 245350569, 252512961, 259831041, 267307049, 274943241, 282741889,\n  290705281, 298835721, 307135529, 315607041, 324252609, 333074601, 342075401,\n  351257409, 360623041, 370174729, 379914921, 389846081, 399970689, 410291241,\n  420810249, 431530241, 442453761, 453583369, 464921641, 476471169, 488234561,\n  500214441, 512413449, 524834241, 537479489, 550351881, 563454121, 576788929,\n  590359041, 604167209, 618216201, 632508801,\n#if defined(CUSTOM_MODES)\n  /*...208:*/\n  647047809, 661836041, 676876329, 692171521, 707724481, 723538089, 739615241,\n  755958849, 772571841, 789457161, 806617769, 824056641, 841776769, 859781161,\n  878072841, 896654849, 915530241, 934702089, 954173481, 973947521, 994027329,\n  1014416041, 1035116809, 1056132801, 1077467201, 1099123209, 1121104041,\n  1143412929, 1166053121, 1189027881, 1212340489, 1235994241,\n#endif\n  /*N=6, K=6...96:*/\n  1683, 3653, 7183, 13073, 22363, 36365, 56695, 85305, 124515, 177045, 246047,\n  335137, 448427, 590557, 766727, 982729, 1244979, 1560549, 1937199, 2383409,\n  2908411, 3522221, 4235671, 5060441, 6009091, 7095093, 8332863, 9737793,\n  11326283, 13115773, 15124775, 17372905, 19880915, 22670725, 25765455,\n  29189457, 32968347, 37129037, 41699767, 46710137, 52191139, 58175189,\n  64696159, 71789409, 79491819, 87841821, 96879431, 106646281, 117185651,\n  128542501, 140763503, 153897073, 167993403, 183104493, 199284183, 216588185,\n  235074115, 254801525, 275831935, 298228865, 322057867, 347386557, 374284647,\n  402823977, 433078547, 465124549, 499040399, 534906769, 572806619, 612825229,\n  655050231, 699571641, 746481891, 795875861, 847850911, 902506913, 959946283,\n  1020274013, 1083597703, 1150027593, 1219676595, 1292660325, 1369097135,\n  1449108145, 1532817275, 1620351277, 1711839767, 1807415257, 1907213187,\n  2011371957, 2120032959,\n#if defined(CUSTOM_MODES)\n  /*...109:*/\n  2233340609U, 2351442379U, 2474488829U, 2602633639U, 2736033641U, 2874848851U,\n  3019242501U, 3169381071U, 3325434321U, 3487575323U, 3655980493U, 3830829623U,\n  4012305913U,\n#endif\n  /*N=7, K=7...54*/\n  8989, 19825, 40081, 75517, 134245, 227305, 369305, 579125, 880685, 1303777,\n  1884961, 2668525, 3707509, 5064793, 6814249, 9041957, 11847485, 15345233,\n  19665841, 24957661, 31388293, 39146185, 48442297, 59511829, 72616013,\n  88043969, 106114625, 127178701, 151620757, 179861305, 212358985, 249612805,\n  292164445, 340600625, 395555537, 457713341, 527810725, 606639529, 695049433,\n  793950709, 904317037, 1027188385, 1163673953, 1314955181, 1482288821,\n  1667010073, 1870535785, 2094367717,\n#if defined(CUSTOM_MODES)\n  /*...60:*/\n  2340095869U, 2609401873U, 2904062449U, 3225952925U, 3577050821U, 3959439497U,\n#endif\n  /*N=8, K=8...37*/\n  48639, 108545, 224143, 433905, 795455, 1392065, 2340495, 3800305, 5984767,\n  9173505, 13726991, 20103025, 28875327, 40754369, 56610575, 77500017,\n  104692735, 139703809, 184327311, 240673265, 311207743, 398796225, 506750351,\n  638878193, 799538175, 993696769, 1226990095, 1505789553, 1837271615,\n  2229491905U,\n#if defined(CUSTOM_MODES)\n  /*...40:*/\n  2691463695U, 3233240945U, 3866006015U,\n#endif\n  /*N=9, K=9...28:*/\n  265729, 598417, 1256465, 2485825, 4673345, 8405905, 14546705, 24331777,\n  39490049, 62390545, 96220561, 145198913, 214828609, 312193553, 446304145,\n  628496897, 872893441, 1196924561, 1621925137, 2173806145U,\n#if defined(CUSTOM_MODES)\n  /*...29:*/\n  2883810113U,\n#endif\n  /*N=10, K=10...24:*/\n  1462563, 3317445, 7059735, 14218905, 27298155, 50250765, 89129247, 152951073,\n  254831667, 413442773, 654862247, 1014889769, 1541911931, 2300409629U,\n  3375210671U,\n  /*N=11, K=11...19:*/\n  8097453, 18474633, 39753273, 81270333, 158819253, 298199265, 540279585,\n  948062325, 1616336765,\n#if defined(CUSTOM_MODES)\n  /*...20:*/\n  2684641785U,\n#endif\n  /*N=12, K=12...18:*/\n  45046719, 103274625, 224298231, 464387817, 921406335, 1759885185,\n  3248227095U,\n  /*N=13, K=13...16:*/\n  251595969, 579168825, 1267854873, 2653649025U,\n  /*N=14, K=14:*/\n  1409933619\n};\n\n#if defined(CUSTOM_MODES)\nstatic const opus_uint32 *const CELT_PVQ_U_ROW[15]={\n  CELT_PVQ_U_DATA+   0,CELT_PVQ_U_DATA+ 208,CELT_PVQ_U_DATA+ 415,\n  CELT_PVQ_U_DATA+ 621,CELT_PVQ_U_DATA+ 826,CELT_PVQ_U_DATA+1030,\n  CELT_PVQ_U_DATA+1233,CELT_PVQ_U_DATA+1336,CELT_PVQ_U_DATA+1389,\n  CELT_PVQ_U_DATA+1421,CELT_PVQ_U_DATA+1441,CELT_PVQ_U_DATA+1455,\n  CELT_PVQ_U_DATA+1464,CELT_PVQ_U_DATA+1470,CELT_PVQ_U_DATA+1473\n};\n#else\nstatic const opus_uint32 *const CELT_PVQ_U_ROW[15]={\n  CELT_PVQ_U_DATA+   0,CELT_PVQ_U_DATA+ 176,CELT_PVQ_U_DATA+ 351,\n  CELT_PVQ_U_DATA+ 525,CELT_PVQ_U_DATA+ 698,CELT_PVQ_U_DATA+ 870,\n  CELT_PVQ_U_DATA+1041,CELT_PVQ_U_DATA+1131,CELT_PVQ_U_DATA+1178,\n  CELT_PVQ_U_DATA+1207,CELT_PVQ_U_DATA+1226,CELT_PVQ_U_DATA+1240,\n  CELT_PVQ_U_DATA+1248,CELT_PVQ_U_DATA+1254,CELT_PVQ_U_DATA+1257\n};\n#endif\n\n#if defined(CUSTOM_MODES)\nvoid get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){\n  int k;\n  /*_maxk==0 => there's nothing to do.*/\n  celt_assert(_maxk>0);\n  _bits[0]=0;\n  for(k=1;k<=_maxk;k++)_bits[k]=log2_frac(CELT_PVQ_V(_n,k),_frac);\n}\n#endif\n\nstatic opus_uint32 icwrs(int _n,const int *_y){\n  opus_uint32 i;\n  int         j;\n  int         k;\n  celt_assert(_n>=2);\n  j=_n-1;\n  i=_y[j]<0;\n  k=abs(_y[j]);\n  do{\n    j--;\n    i+=CELT_PVQ_U(_n-j,k);\n    k+=abs(_y[j]);\n    if(_y[j]<0)i+=CELT_PVQ_U(_n-j,k+1);\n  }\n  while(j>0);\n  return i;\n}\n\nvoid encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){\n  celt_assert(_k>0);\n  ec_enc_uint(_enc,icwrs(_n,_y),CELT_PVQ_V(_n,_k));\n}\n\nstatic opus_val32 cwrsi(int _n,int _k,opus_uint32 _i,int *_y){\n  opus_uint32 p;\n  int         s;\n  int         k0;\n  opus_int16  val;\n  opus_val32  yy=0;\n  celt_assert(_k>0);\n  celt_assert(_n>1);\n  while(_n>2){\n    opus_uint32 q;\n    /*Lots of pulses case:*/\n    if(_k>=_n){\n      const opus_uint32 *row;\n      row=CELT_PVQ_U_ROW[_n];\n      /*Are the pulses in this dimension negative?*/\n      p=row[_k+1];\n      s=-(_i>=p);\n      _i-=p&s;\n      /*Count how many pulses were placed in this dimension.*/\n      k0=_k;\n      q=row[_n];\n      if(q>_i){\n        celt_assert(p>q);\n        _k=_n;\n        do p=CELT_PVQ_U_ROW[--_k][_n];\n        while(p>_i);\n      }\n      else for(p=row[_k];p>_i;p=row[_k])_k--;\n      _i-=p;\n      val=(k0-_k+s)^s;\n      *_y++=val;\n      yy=MAC16_16(yy,val,val);\n    }\n    /*Lots of dimensions case:*/\n    else{\n      /*Are there any pulses in this dimension at all?*/\n      p=CELT_PVQ_U_ROW[_k][_n];\n      q=CELT_PVQ_U_ROW[_k+1][_n];\n      if(p<=_i&&_i<q){\n        _i-=p;\n        *_y++=0;\n      }\n      else{\n        /*Are the pulses in this dimension negative?*/\n        s=-(_i>=q);\n        _i-=q&s;\n        /*Count how many pulses were placed in this dimension.*/\n        k0=_k;\n        do p=CELT_PVQ_U_ROW[--_k][_n];\n        while(p>_i);\n        _i-=p;\n        val=(k0-_k+s)^s;\n        *_y++=val;\n        yy=MAC16_16(yy,val,val);\n      }\n    }\n    _n--;\n  }\n  /*_n==2*/\n  p=2*_k+1;\n  s=-(_i>=p);\n  _i-=p&s;\n  k0=_k;\n  _k=(_i+1)>>1;\n  if(_k)_i-=2*_k-1;\n  val=(k0-_k+s)^s;\n  *_y++=val;\n  yy=MAC16_16(yy,val,val);\n  /*_n==1*/\n  s=-(int)_i;\n  val=(_k+s)^s;\n  *_y=val;\n  yy=MAC16_16(yy,val,val);\n  return yy;\n}\n\nopus_val32 decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){\n  return cwrsi(_n,_k,ec_dec_uint(_dec,CELT_PVQ_V(_n,_k)),_y);\n}\n\n#else /* SMALL_FOOTPRINT */\n\n/*Computes the next row/column of any recurrence that obeys the relation\n   u[i][j]=u[i-1][j]+u[i][j-1]+u[i-1][j-1].\n  _ui0 is the base case for the new row/column.*/\nstatic OPUS_INLINE void unext(opus_uint32 *_ui,unsigned _len,opus_uint32 _ui0){\n  opus_uint32 ui1;\n  unsigned      j;\n  /*This do-while will overrun the array if we don't have storage for at least\n     2 values.*/\n  j=1; do {\n    ui1=UADD32(UADD32(_ui[j],_ui[j-1]),_ui0);\n    _ui[j-1]=_ui0;\n    _ui0=ui1;\n  } while (++j<_len);\n  _ui[j-1]=_ui0;\n}\n\n/*Computes the previous row/column of any recurrence that obeys the relation\n   u[i-1][j]=u[i][j]-u[i][j-1]-u[i-1][j-1].\n  _ui0 is the base case for the new row/column.*/\nstatic OPUS_INLINE void uprev(opus_uint32 *_ui,unsigned _n,opus_uint32 _ui0){\n  opus_uint32 ui1;\n  unsigned      j;\n  /*This do-while will overrun the array if we don't have storage for at least\n     2 values.*/\n  j=1; do {\n    ui1=USUB32(USUB32(_ui[j],_ui[j-1]),_ui0);\n    _ui[j-1]=_ui0;\n    _ui0=ui1;\n  } while (++j<_n);\n  _ui[j-1]=_ui0;\n}\n\n/*Compute V(_n,_k), as well as U(_n,0..._k+1).\n  _u: On exit, _u[i] contains U(_n,i) for i in [0..._k+1].*/\nstatic opus_uint32 ncwrs_urow(unsigned _n,unsigned _k,opus_uint32 *_u){\n  opus_uint32 um2;\n  unsigned      len;\n  unsigned      k;\n  len=_k+2;\n  /*We require storage at least 3 values (e.g., _k>0).*/\n  celt_assert(len>=3);\n  _u[0]=0;\n  _u[1]=um2=1;\n  /*If _n==0, _u[0] should be 1 and the rest should be 0.*/\n  /*If _n==1, _u[i] should be 1 for i>1.*/\n  celt_assert(_n>=2);\n  /*If _k==0, the following do-while loop will overflow the buffer.*/\n  celt_assert(_k>0);\n  k=2;\n  do _u[k]=(k<<1)-1;\n  while(++k<len);\n  for(k=2;k<_n;k++)unext(_u+1,_k+1,1);\n  return _u[_k]+_u[_k+1];\n}\n\n/*Returns the _i'th combination of _k elements chosen from a set of size _n\n   with associated sign bits.\n  _y: Returns the vector of pulses.\n  _u: Must contain entries [0..._k+1] of row _n of U() on input.\n      Its contents will be destructively modified.*/\nstatic opus_val32 cwrsi(int _n,int _k,opus_uint32 _i,int *_y,opus_uint32 *_u){\n  int j;\n  opus_int16 val;\n  opus_val32 yy=0;\n  celt_assert(_n>0);\n  j=0;\n  do{\n    opus_uint32 p;\n    int           s;\n    int           yj;\n    p=_u[_k+1];\n    s=-(_i>=p);\n    _i-=p&s;\n    yj=_k;\n    p=_u[_k];\n    while(p>_i)p=_u[--_k];\n    _i-=p;\n    yj-=_k;\n    val=(yj+s)^s;\n    _y[j]=val;\n    yy=MAC16_16(yy,val,val);\n    uprev(_u,_k+2,0);\n  }\n  while(++j<_n);\n  return yy;\n}\n\n/*Returns the index of the given combination of K elements chosen from a set\n   of size 1 with associated sign bits.\n  _y: The vector of pulses, whose sum of absolute values is K.\n  _k: Returns K.*/\nstatic OPUS_INLINE opus_uint32 icwrs1(const int *_y,int *_k){\n  *_k=abs(_y[0]);\n  return _y[0]<0;\n}\n\n/*Returns the index of the given combination of K elements chosen from a set\n   of size _n with associated sign bits.\n  _y:  The vector of pulses, whose sum of absolute values must be _k.\n  _nc: Returns V(_n,_k).*/\nstatic OPUS_INLINE opus_uint32 icwrs(int _n,int _k,opus_uint32 *_nc,const int *_y,\n opus_uint32 *_u){\n  opus_uint32 i;\n  int         j;\n  int         k;\n  /*We can't unroll the first two iterations of the loop unless _n>=2.*/\n  celt_assert(_n>=2);\n  _u[0]=0;\n  for(k=1;k<=_k+1;k++)_u[k]=(k<<1)-1;\n  i=icwrs1(_y+_n-1,&k);\n  j=_n-2;\n  i+=_u[k];\n  k+=abs(_y[j]);\n  if(_y[j]<0)i+=_u[k+1];\n  while(j-->0){\n    unext(_u,_k+2,0);\n    i+=_u[k];\n    k+=abs(_y[j]);\n    if(_y[j]<0)i+=_u[k+1];\n  }\n  *_nc=_u[k]+_u[k+1];\n  return i;\n}\n\n#ifdef CUSTOM_MODES\nvoid get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){\n  int k;\n  /*_maxk==0 => there's nothing to do.*/\n  celt_assert(_maxk>0);\n  _bits[0]=0;\n  if (_n==1)\n  {\n    for (k=1;k<=_maxk;k++)\n      _bits[k] = 1<<_frac;\n  }\n  else {\n    VARDECL(opus_uint32,u);\n    SAVE_STACK;\n    ALLOC(u,_maxk+2U,opus_uint32);\n    ncwrs_urow(_n,_maxk,u);\n    for(k=1;k<=_maxk;k++)\n      _bits[k]=log2_frac(u[k]+u[k+1],_frac);\n    RESTORE_STACK;\n  }\n}\n#endif /* CUSTOM_MODES */\n\nvoid encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){\n  opus_uint32 i;\n  VARDECL(opus_uint32,u);\n  opus_uint32 nc;\n  SAVE_STACK;\n  celt_assert(_k>0);\n  ALLOC(u,_k+2U,opus_uint32);\n  i=icwrs(_n,_k,&nc,_y,u);\n  ec_enc_uint(_enc,i,nc);\n  RESTORE_STACK;\n}\n\nopus_val32 decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){\n  VARDECL(opus_uint32,u);\n  int ret;\n  SAVE_STACK;\n  celt_assert(_k>0);\n  ALLOC(u,_k+2U,opus_uint32);\n  ret = cwrsi(_n,_k,ec_dec_uint(_dec,ncwrs_urow(_n,_k,u)),_y,u);\n  RESTORE_STACK;\n  return ret;\n}\n\n#endif /* SMALL_FOOTPRINT */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/cwrs.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Copyright (c) 2007-2009 Timothy B. Terriberry\n   Written by Timothy B. Terriberry and Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef CWRS_H\n#define CWRS_H\n\n#include \"arch.h\"\n#include \"stack_alloc.h\"\n#include \"entenc.h\"\n#include \"entdec.h\"\n\n#ifdef CUSTOM_MODES\nint log2_frac(opus_uint32 val, int frac);\n#endif\n\nvoid get_required_bits(opus_int16 *bits, int N, int K, int frac);\n\nvoid encode_pulses(const int *_y, int N, int K, ec_enc *enc);\n\nopus_val32 decode_pulses(int *_y, int N, int K, ec_dec *dec);\n\n#endif /* CWRS_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/ecintrin.h",
    "content": "/* Copyright (c) 2003-2008 Timothy B. Terriberry\n   Copyright (c) 2008 Xiph.Org Foundation */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/*Some common macros for potential platform-specific optimization.*/\n#include \"opus_types.h\"\n#include <math.h>\n#include <limits.h>\n#include \"arch.h\"\n#if !defined(_ecintrin_H)\n# define _ecintrin_H (1)\n\n/*Some specific platforms may have optimized intrinsic or OPUS_INLINE assembly\n   versions of these functions which can substantially improve performance.\n  We define macros for them to allow easy incorporation of these non-ANSI\n   features.*/\n\n/*Modern gcc (4.x) can compile the naive versions of min and max with cmov if\n   given an appropriate architecture, but the branchless bit-twiddling versions\n   are just as fast, and do not require any special target architecture.\n  Earlier gcc versions (3.x) compiled both code to the same assembly\n   instructions, because of the way they represented ((_b)>(_a)) internally.*/\n# define EC_MINI(_a,_b)      ((_a)+(((_b)-(_a))&-((_b)<(_a))))\n\n/*Count leading zeros.\n  This macro should only be used for implementing ec_ilog(), if it is defined.\n  All other code should use EC_ILOG() instead.*/\n#if defined(_MSC_VER) && (_MSC_VER >= 1400)\n# include <intrin.h>\n/*In _DEBUG mode this is not an intrinsic by default.*/\n# pragma intrinsic(_BitScanReverse)\n\nstatic __inline int ec_bsr(unsigned long _x){\n  unsigned long ret;\n  _BitScanReverse(&ret,_x);\n  return (int)ret;\n}\n# define EC_CLZ0    (1)\n# define EC_CLZ(_x) (-ec_bsr(_x))\n#elif defined(ENABLE_TI_DSPLIB)\n# include \"dsplib.h\"\n# define EC_CLZ0    (31)\n# define EC_CLZ(_x) (_lnorm(_x))\n#elif __GNUC_PREREQ(3,4)\n# if INT_MAX>=2147483647\n#  define EC_CLZ0    ((int)sizeof(unsigned)*CHAR_BIT)\n#  define EC_CLZ(_x) (__builtin_clz(_x))\n# elif LONG_MAX>=2147483647L\n#  define EC_CLZ0    ((int)sizeof(unsigned long)*CHAR_BIT)\n#  define EC_CLZ(_x) (__builtin_clzl(_x))\n# endif\n#endif\n\n#if defined(EC_CLZ)\n/*Note that __builtin_clz is not defined when _x==0, according to the gcc\n   documentation (and that of the BSR instruction that implements it on x86).\n  The majority of the time we can never pass it zero.\n  When we need to, it can be special cased.*/\n# define EC_ILOG(_x) (EC_CLZ0-EC_CLZ(_x))\n#else\nint ec_ilog(opus_uint32 _v);\n# define EC_ILOG(_x) (ec_ilog(_x))\n#endif\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/entcode.c",
    "content": "/* Copyright (c) 2001-2011 Timothy B. Terriberry\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"entcode.h\"\n#include \"arch.h\"\n\n#if !defined(EC_CLZ)\n/*This is a fallback for systems where we don't know how to access\n   a BSR or CLZ instruction (see ecintrin.h).\n  If you are optimizing Opus on a new platform and it has a native CLZ or\n   BZR (e.g. cell, MIPS, x86, etc) then making it available to Opus will be\n   an easy performance win.*/\nint ec_ilog(opus_uint32 _v){\n  /*On a Pentium M, this branchless version tested as the fastest on\n     1,000,000,000 random 32-bit integers, edging out a similar version with\n     branches, and a 256-entry LUT version.*/\n  int ret;\n  int m;\n  ret=!!_v;\n  m=!!(_v&0xFFFF0000)<<4;\n  _v>>=m;\n  ret|=m;\n  m=!!(_v&0xFF00)<<3;\n  _v>>=m;\n  ret|=m;\n  m=!!(_v&0xF0)<<2;\n  _v>>=m;\n  ret|=m;\n  m=!!(_v&0xC)<<1;\n  _v>>=m;\n  ret|=m;\n  ret+=!!(_v&0x2);\n  return ret;\n}\n#endif\n\n#if 1\n/* This is a faster version of ec_tell_frac() that takes advantage\n   of the low (1/8 bit) resolution to use just a linear function\n   followed by a lookup to determine the exact transition thresholds. */\nopus_uint32 ec_tell_frac(ec_ctx *_this){\n  static const unsigned correction[8] =\n    {35733, 38967, 42495, 46340,\n     50535, 55109, 60097, 65535};\n  opus_uint32 nbits;\n  opus_uint32 r;\n  int         l;\n  unsigned    b;\n  nbits=_this->nbits_total<<BITRES;\n  l=EC_ILOG(_this->rng);\n  r=_this->rng>>(l-16);\n  b = (r>>12)-8;\n  b += r>correction[b];\n  l = (l<<3)+b;\n  return nbits-l;\n}\n#else\nopus_uint32 ec_tell_frac(ec_ctx *_this){\n  opus_uint32 nbits;\n  opus_uint32 r;\n  int         l;\n  int         i;\n  /*To handle the non-integral number of bits still left in the encoder/decoder\n     state, we compute the worst-case number of bits of val that must be\n     encoded to ensure that the value is inside the range for any possible\n     subsequent bits.\n    The computation here is independent of val itself (the decoder does not\n     even track that value), even though the real number of bits used after\n     ec_enc_done() may be 1 smaller if rng is a power of two and the\n     corresponding trailing bits of val are all zeros.\n    If we did try to track that special case, then coding a value with a\n     probability of 1/(1<<n) might sometimes appear to use more than n bits.\n    This may help explain the surprising result that a newly initialized\n     encoder or decoder claims to have used 1 bit.*/\n  nbits=_this->nbits_total<<BITRES;\n  l=EC_ILOG(_this->rng);\n  r=_this->rng>>(l-16);\n  for(i=BITRES;i-->0;){\n    int b;\n    r=r*r>>15;\n    b=(int)(r>>16);\n    l=l<<1|b;\n    r>>=b;\n  }\n  return nbits-l;\n}\n#endif\n\n#ifdef USE_SMALL_DIV_TABLE\n/* Result of 2^32/(2*i+1), except for i=0. */\nconst opus_uint32 SMALL_DIV_TABLE[129] = {\n   0xFFFFFFFF, 0x55555555, 0x33333333, 0x24924924,\n   0x1C71C71C, 0x1745D174, 0x13B13B13, 0x11111111,\n   0x0F0F0F0F, 0x0D79435E, 0x0C30C30C, 0x0B21642C,\n   0x0A3D70A3, 0x097B425E, 0x08D3DCB0, 0x08421084,\n   0x07C1F07C, 0x07507507, 0x06EB3E45, 0x06906906,\n   0x063E7063, 0x05F417D0, 0x05B05B05, 0x0572620A,\n   0x05397829, 0x05050505, 0x04D4873E, 0x04A7904A,\n   0x047DC11F, 0x0456C797, 0x04325C53, 0x04104104,\n   0x03F03F03, 0x03D22635, 0x03B5CC0E, 0x039B0AD1,\n   0x0381C0E0, 0x0369D036, 0x03531DEC, 0x033D91D2,\n   0x0329161F, 0x03159721, 0x03030303, 0x02F14990,\n   0x02E05C0B, 0x02D02D02, 0x02C0B02C, 0x02B1DA46,\n   0x02A3A0FD, 0x0295FAD4, 0x0288DF0C, 0x027C4597,\n   0x02702702, 0x02647C69, 0x02593F69, 0x024E6A17,\n   0x0243F6F0, 0x0239E0D5, 0x02302302, 0x0226B902,\n   0x021D9EAD, 0x0214D021, 0x020C49BA, 0x02040810,\n   0x01FC07F0, 0x01F44659, 0x01ECC07B, 0x01E573AC,\n   0x01DE5D6E, 0x01D77B65, 0x01D0CB58, 0x01CA4B30,\n   0x01C3F8F0, 0x01BDD2B8, 0x01B7D6C3, 0x01B20364,\n   0x01AC5701, 0x01A6D01A, 0x01A16D3F, 0x019C2D14,\n   0x01970E4F, 0x01920FB4, 0x018D3018, 0x01886E5F,\n   0x0183C977, 0x017F405F, 0x017AD220, 0x01767DCE,\n   0x01724287, 0x016E1F76, 0x016A13CD, 0x01661EC6,\n   0x01623FA7, 0x015E75BB, 0x015AC056, 0x01571ED3,\n   0x01539094, 0x01501501, 0x014CAB88, 0x0149539E,\n   0x01460CBC, 0x0142D662, 0x013FB013, 0x013C995A,\n   0x013991C2, 0x013698DF, 0x0133AE45, 0x0130D190,\n   0x012E025C, 0x012B404A, 0x01288B01, 0x0125E227,\n   0x01234567, 0x0120B470, 0x011E2EF3, 0x011BB4A4,\n   0x01194538, 0x0116E068, 0x011485F0, 0x0112358E,\n   0x010FEF01, 0x010DB20A, 0x010B7E6E, 0x010953F3,\n   0x01073260, 0x0105197F, 0x0103091B, 0x01010101\n};\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/entcode.h",
    "content": "/* Copyright (c) 2001-2011 Timothy B. Terriberry\n   Copyright (c) 2008-2009 Xiph.Org Foundation */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#include \"opus_types.h\"\n#include \"opus_defines.h\"\n\n#if !defined(_entcode_H)\n# define _entcode_H (1)\n# include <limits.h>\n# include <stddef.h>\n# include \"ecintrin.h\"\n\nextern const opus_uint32 SMALL_DIV_TABLE[129];\n\n#ifdef OPUS_ARM_ASM\n#define USE_SMALL_DIV_TABLE\n#endif\n\n/*OPT: ec_window must be at least 32 bits, but if you have fast arithmetic on a\n   larger type, you can speed up the decoder by using it here.*/\ntypedef opus_uint32           ec_window;\ntypedef struct ec_ctx         ec_ctx;\ntypedef struct ec_ctx         ec_enc;\ntypedef struct ec_ctx         ec_dec;\n\n# define EC_WINDOW_SIZE ((int)sizeof(ec_window)*CHAR_BIT)\n\n/*The number of bits to use for the range-coded part of unsigned integers.*/\n# define EC_UINT_BITS   (8)\n\n/*The resolution of fractional-precision bit usage measurements, i.e.,\n   3 => 1/8th bits.*/\n# define BITRES 3\n\n/*The entropy encoder/decoder context.\n  We use the same structure for both, so that common functions like ec_tell()\n   can be used on either one.*/\nstruct ec_ctx{\n   /*Buffered input/output.*/\n   unsigned char *buf;\n   /*The size of the buffer.*/\n   opus_uint32    storage;\n   /*The offset at which the last byte containing raw bits was read/written.*/\n   opus_uint32    end_offs;\n   /*Bits that will be read from/written at the end.*/\n   ec_window      end_window;\n   /*Number of valid bits in end_window.*/\n   int            nend_bits;\n   /*The total number of whole bits read/written.\n     This does not include partial bits currently in the range coder.*/\n   int            nbits_total;\n   /*The offset at which the next range coder byte will be read/written.*/\n   opus_uint32    offs;\n   /*The number of values in the current range.*/\n   opus_uint32    rng;\n   /*In the decoder: the difference between the top of the current range and\n      the input value, minus one.\n     In the encoder: the low end of the current range.*/\n   opus_uint32    val;\n   /*In the decoder: the saved normalization factor from ec_decode().\n     In the encoder: the number of oustanding carry propagating symbols.*/\n   opus_uint32    ext;\n   /*A buffered input/output symbol, awaiting carry propagation.*/\n   int            rem;\n   /*Nonzero if an error occurred.*/\n   int            error;\n};\n\nstatic OPUS_INLINE opus_uint32 ec_range_bytes(ec_ctx *_this){\n  return _this->offs;\n}\n\nstatic OPUS_INLINE unsigned char *ec_get_buffer(ec_ctx *_this){\n  return _this->buf;\n}\n\nstatic OPUS_INLINE int ec_get_error(ec_ctx *_this){\n  return _this->error;\n}\n\n/*Returns the number of bits \"used\" by the encoded or decoded symbols so far.\n  This same number can be computed in either the encoder or the decoder, and is\n   suitable for making coding decisions.\n  Return: The number of bits.\n          This will always be slightly larger than the exact value (e.g., all\n           rounding error is in the positive direction).*/\nstatic OPUS_INLINE int ec_tell(ec_ctx *_this){\n  return _this->nbits_total-EC_ILOG(_this->rng);\n}\n\n/*Returns the number of bits \"used\" by the encoded or decoded symbols so far.\n  This same number can be computed in either the encoder or the decoder, and is\n   suitable for making coding decisions.\n  Return: The number of bits scaled by 2**BITRES.\n          This will always be slightly larger than the exact value (e.g., all\n           rounding error is in the positive direction).*/\nopus_uint32 ec_tell_frac(ec_ctx *_this);\n\n/* Tested exhaustively for all n and for 1<=d<=256 */\nstatic OPUS_INLINE opus_uint32 celt_udiv(opus_uint32 n, opus_uint32 d) {\n   celt_assert(d>0);\n#ifdef USE_SMALL_DIV_TABLE\n   if (d>256)\n      return n/d;\n   else {\n      opus_uint32 t, q;\n      t = EC_ILOG(d&-d);\n      q = (opus_uint64)SMALL_DIV_TABLE[d>>t]*(n>>(t-1))>>32;\n      return q+(n-q*d >= d);\n   }\n#else\n   return n/d;\n#endif\n}\n\nstatic OPUS_INLINE opus_int32 celt_sudiv(opus_int32 n, opus_int32 d) {\n   celt_assert(d>0);\n#ifdef USE_SMALL_DIV_TABLE\n   if (n<0)\n      return -(opus_int32)celt_udiv(-n, d);\n   else\n      return celt_udiv(n, d);\n#else\n   return n/d;\n#endif\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/entdec.c",
    "content": "/* Copyright (c) 2001-2011 Timothy B. Terriberry\n   Copyright (c) 2008-2009 Xiph.Org Foundation */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stddef.h>\n#include \"os_support.h\"\n#include \"arch.h\"\n#include \"entdec.h\"\n#include \"mfrngcod.h\"\n\n/*A range decoder.\n  This is an entropy decoder based upon \\cite{Mar79}, which is itself a\n   rediscovery of the FIFO arithmetic code introduced by \\cite{Pas76}.\n  It is very similar to arithmetic encoding, except that encoding is done with\n   digits in any base, instead of with bits, and so it is faster when using\n   larger bases (i.e.: a byte).\n  The author claims an average waste of $\\frac{1}{2}\\log_b(2b)$ bits, where $b$\n   is the base, longer than the theoretical optimum, but to my knowledge there\n   is no published justification for this claim.\n  This only seems true when using near-infinite precision arithmetic so that\n   the process is carried out with no rounding errors.\n\n  An excellent description of implementation details is available at\n   http://www.arturocampos.com/ac_range.html\n  A recent work \\cite{MNW98} which proposes several changes to arithmetic\n   encoding for efficiency actually re-discovers many of the principles\n   behind range encoding, and presents a good theoretical analysis of them.\n\n  End of stream is handled by writing out the smallest number of bits that\n   ensures that the stream will be correctly decoded regardless of the value of\n   any subsequent bits.\n  ec_tell() can be used to determine how many bits were needed to decode\n   all the symbols thus far; other data can be packed in the remaining bits of\n   the input buffer.\n  @PHDTHESIS{Pas76,\n    author=\"Richard Clark Pasco\",\n    title=\"Source coding algorithms for fast data compression\",\n    school=\"Dept. of Electrical Engineering, Stanford University\",\n    address=\"Stanford, CA\",\n    month=May,\n    year=1976\n  }\n  @INPROCEEDINGS{Mar79,\n   author=\"Martin, G.N.N.\",\n   title=\"Range encoding: an algorithm for removing redundancy from a digitised\n    message\",\n   booktitle=\"Video & Data Recording Conference\",\n   year=1979,\n   address=\"Southampton\",\n   month=Jul\n  }\n  @ARTICLE{MNW98,\n   author=\"Alistair Moffat and Radford Neal and Ian H. Witten\",\n   title=\"Arithmetic Coding Revisited\",\n   journal=\"{ACM} Transactions on Information Systems\",\n   year=1998,\n   volume=16,\n   number=3,\n   pages=\"256--294\",\n   month=Jul,\n   URL=\"http://www.stanford.edu/class/ee398a/handouts/papers/Moffat98ArithmCoding.pdf\"\n  }*/\n\nstatic int ec_read_byte(ec_dec *_this){\n  return _this->offs<_this->storage?_this->buf[_this->offs++]:0;\n}\n\nstatic int ec_read_byte_from_end(ec_dec *_this){\n  return _this->end_offs<_this->storage?\n   _this->buf[_this->storage-++(_this->end_offs)]:0;\n}\n\n/*Normalizes the contents of val and rng so that rng lies entirely in the\n   high-order symbol.*/\nstatic void ec_dec_normalize(ec_dec *_this){\n  /*If the range is too small, rescale it and input some bits.*/\n  while(_this->rng<=EC_CODE_BOT){\n    int sym;\n    _this->nbits_total+=EC_SYM_BITS;\n    _this->rng<<=EC_SYM_BITS;\n    /*Use up the remaining bits from our last symbol.*/\n    sym=_this->rem;\n    /*Read the next value from the input.*/\n    _this->rem=ec_read_byte(_this);\n    /*Take the rest of the bits we need from this new symbol.*/\n    sym=(sym<<EC_SYM_BITS|_this->rem)>>(EC_SYM_BITS-EC_CODE_EXTRA);\n    /*And subtract them from val, capped to be less than EC_CODE_TOP.*/\n    _this->val=((_this->val<<EC_SYM_BITS)+(EC_SYM_MAX&~sym))&(EC_CODE_TOP-1);\n  }\n}\n\nvoid ec_dec_init(ec_dec *_this,unsigned char *_buf,opus_uint32 _storage){\n  _this->buf=_buf;\n  _this->storage=_storage;\n  _this->end_offs=0;\n  _this->end_window=0;\n  _this->nend_bits=0;\n  /*This is the offset from which ec_tell() will subtract partial bits.\n    The final value after the ec_dec_normalize() call will be the same as in\n     the encoder, but we have to compensate for the bits that are added there.*/\n  _this->nbits_total=EC_CODE_BITS+1\n   -((EC_CODE_BITS-EC_CODE_EXTRA)/EC_SYM_BITS)*EC_SYM_BITS;\n  _this->offs=0;\n  _this->rng=1U<<EC_CODE_EXTRA;\n  _this->rem=ec_read_byte(_this);\n  _this->val=_this->rng-1-(_this->rem>>(EC_SYM_BITS-EC_CODE_EXTRA));\n  _this->error=0;\n  /*Normalize the interval.*/\n  ec_dec_normalize(_this);\n}\n\nunsigned ec_decode(ec_dec *_this,unsigned _ft){\n  unsigned s;\n  _this->ext=celt_udiv(_this->rng,_ft);\n  s=(unsigned)(_this->val/_this->ext);\n  return _ft-EC_MINI(s+1,_ft);\n}\n\nunsigned ec_decode_bin(ec_dec *_this,unsigned _bits){\n   unsigned s;\n   _this->ext=_this->rng>>_bits;\n   s=(unsigned)(_this->val/_this->ext);\n   return (1U<<_bits)-EC_MINI(s+1U,1U<<_bits);\n}\n\nvoid ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){\n  opus_uint32 s;\n  s=IMUL32(_this->ext,_ft-_fh);\n  _this->val-=s;\n  _this->rng=_fl>0?IMUL32(_this->ext,_fh-_fl):_this->rng-s;\n  ec_dec_normalize(_this);\n}\n\n/*The probability of having a \"one\" is 1/(1<<_logp).*/\nint ec_dec_bit_logp(ec_dec *_this,unsigned _logp){\n  opus_uint32 r;\n  opus_uint32 d;\n  opus_uint32 s;\n  int         ret;\n  r=_this->rng;\n  d=_this->val;\n  s=r>>_logp;\n  ret=d<s;\n  if(!ret)_this->val=d-s;\n  _this->rng=ret?s:r-s;\n  ec_dec_normalize(_this);\n  return ret;\n}\n\nint ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb){\n  opus_uint32 r;\n  opus_uint32 d;\n  opus_uint32 s;\n  opus_uint32 t;\n  int         ret;\n  s=_this->rng;\n  d=_this->val;\n  r=s>>_ftb;\n  ret=-1;\n  do{\n    t=s;\n    s=IMUL32(r,_icdf[++ret]);\n  }\n  while(d<s);\n  _this->val=d-s;\n  _this->rng=t-s;\n  ec_dec_normalize(_this);\n  return ret;\n}\n\nopus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft){\n  unsigned ft;\n  unsigned s;\n  int      ftb;\n  /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/\n  celt_assert(_ft>1);\n  _ft--;\n  ftb=EC_ILOG(_ft);\n  if(ftb>EC_UINT_BITS){\n    opus_uint32 t;\n    ftb-=EC_UINT_BITS;\n    ft=(unsigned)(_ft>>ftb)+1;\n    s=ec_decode(_this,ft);\n    ec_dec_update(_this,s,s+1,ft);\n    t=(opus_uint32)s<<ftb|ec_dec_bits(_this,ftb);\n    if(t<=_ft)return t;\n    _this->error=1;\n    return _ft;\n  }\n  else{\n    _ft++;\n    s=ec_decode(_this,(unsigned)_ft);\n    ec_dec_update(_this,s,s+1,(unsigned)_ft);\n    return s;\n  }\n}\n\nopus_uint32 ec_dec_bits(ec_dec *_this,unsigned _bits){\n  ec_window   window;\n  int         available;\n  opus_uint32 ret;\n  window=_this->end_window;\n  available=_this->nend_bits;\n  if((unsigned)available<_bits){\n    do{\n      window|=(ec_window)ec_read_byte_from_end(_this)<<available;\n      available+=EC_SYM_BITS;\n    }\n    while(available<=EC_WINDOW_SIZE-EC_SYM_BITS);\n  }\n  ret=(opus_uint32)window&(((opus_uint32)1<<_bits)-1U);\n  window>>=_bits;\n  available-=_bits;\n  _this->end_window=window;\n  _this->nend_bits=available;\n  _this->nbits_total+=_bits;\n  return ret;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/entdec.h",
    "content": "/* Copyright (c) 2001-2011 Timothy B. Terriberry\n   Copyright (c) 2008-2009 Xiph.Org Foundation */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#if !defined(_entdec_H)\n# define _entdec_H (1)\n# include <limits.h>\n# include \"entcode.h\"\n\n/*Initializes the decoder.\n  _buf: The input buffer to use.\n  Return: 0 on success, or a negative value on error.*/\nvoid ec_dec_init(ec_dec *_this,unsigned char *_buf,opus_uint32 _storage);\n\n/*Calculates the cumulative frequency for the next symbol.\n  This can then be fed into the probability model to determine what that\n   symbol is, and the additional frequency information required to advance to\n   the next symbol.\n  This function cannot be called more than once without a corresponding call to\n   ec_dec_update(), or decoding will not proceed correctly.\n  _ft: The total frequency of the symbols in the alphabet the next symbol was\n        encoded with.\n  Return: A cumulative frequency representing the encoded symbol.\n          If the cumulative frequency of all the symbols before the one that\n           was encoded was fl, and the cumulative frequency of all the symbols\n           up to and including the one encoded is fh, then the returned value\n           will fall in the range [fl,fh).*/\nunsigned ec_decode(ec_dec *_this,unsigned _ft);\n\n/*Equivalent to ec_decode() with _ft==1<<_bits.*/\nunsigned ec_decode_bin(ec_dec *_this,unsigned _bits);\n\n/*Advance the decoder past the next symbol using the frequency information the\n   symbol was encoded with.\n  Exactly one call to ec_decode() must have been made so that all necessary\n   intermediate calculations are performed.\n  _fl:  The cumulative frequency of all symbols that come before the symbol\n         decoded.\n  _fh:  The cumulative frequency of all symbols up to and including the symbol\n         decoded.\n        Together with _fl, this defines the range [_fl,_fh) in which the value\n         returned above must fall.\n  _ft:  The total frequency of the symbols in the alphabet the symbol decoded\n         was encoded in.\n        This must be the same as passed to the preceding call to ec_decode().*/\nvoid ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft);\n\n/* Decode a bit that has a 1/(1<<_logp) probability of being a one */\nint ec_dec_bit_logp(ec_dec *_this,unsigned _logp);\n\n/*Decodes a symbol given an \"inverse\" CDF table.\n  No call to ec_dec_update() is necessary after this call.\n  _icdf: The \"inverse\" CDF, such that symbol s falls in the range\n          [s>0?ft-_icdf[s-1]:0,ft-_icdf[s]), where ft=1<<_ftb.\n         The values must be monotonically non-increasing, and the last value\n          must be 0.\n  _ftb: The number of bits of precision in the cumulative distribution.\n  Return: The decoded symbol s.*/\nint ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb);\n\n/*Extracts a raw unsigned integer with a non-power-of-2 range from the stream.\n  The bits must have been encoded with ec_enc_uint().\n  No call to ec_dec_update() is necessary after this call.\n  _ft: The number of integers that can be decoded (one more than the max).\n       This must be at least one, and no more than 2**32-1.\n  Return: The decoded bits.*/\nopus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft);\n\n/*Extracts a sequence of raw bits from the stream.\n  The bits must have been encoded with ec_enc_bits().\n  No call to ec_dec_update() is necessary after this call.\n  _ftb: The number of bits to extract.\n        This must be between 0 and 25, inclusive.\n  Return: The decoded bits.*/\nopus_uint32 ec_dec_bits(ec_dec *_this,unsigned _ftb);\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/entenc.c",
    "content": "/* Copyright (c) 2001-2011 Timothy B. Terriberry\n   Copyright (c) 2008-2009 Xiph.Org Foundation */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#if defined(HAVE_CONFIG_H)\n# include \"config.h\"\n#endif\n#include \"os_support.h\"\n#include \"arch.h\"\n#include \"entenc.h\"\n#include \"mfrngcod.h\"\n\n/*A range encoder.\n  See entdec.c and the references for implementation details \\cite{Mar79,MNW98}.\n\n  @INPROCEEDINGS{Mar79,\n   author=\"Martin, G.N.N.\",\n   title=\"Range encoding: an algorithm for removing redundancy from a digitised\n    message\",\n   booktitle=\"Video \\& Data Recording Conference\",\n   year=1979,\n   address=\"Southampton\",\n   month=Jul\n  }\n  @ARTICLE{MNW98,\n   author=\"Alistair Moffat and Radford Neal and Ian H. Witten\",\n   title=\"Arithmetic Coding Revisited\",\n   journal=\"{ACM} Transactions on Information Systems\",\n   year=1998,\n   volume=16,\n   number=3,\n   pages=\"256--294\",\n   month=Jul,\n   URL=\"http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf\"\n  }*/\n\nstatic int ec_write_byte(ec_enc *_this,unsigned _value){\n  if(_this->offs+_this->end_offs>=_this->storage)return -1;\n  _this->buf[_this->offs++]=(unsigned char)_value;\n  return 0;\n}\n\nstatic int ec_write_byte_at_end(ec_enc *_this,unsigned _value){\n  if(_this->offs+_this->end_offs>=_this->storage)return -1;\n  _this->buf[_this->storage-++(_this->end_offs)]=(unsigned char)_value;\n  return 0;\n}\n\n/*Outputs a symbol, with a carry bit.\n  If there is a potential to propagate a carry over several symbols, they are\n   buffered until it can be determined whether or not an actual carry will\n   occur.\n  If the counter for the buffered symbols overflows, then the stream becomes\n   undecodable.\n  This gives a theoretical limit of a few billion symbols in a single packet on\n   32-bit systems.\n  The alternative is to truncate the range in order to force a carry, but\n   requires similar carry tracking in the decoder, needlessly slowing it down.*/\nstatic void ec_enc_carry_out(ec_enc *_this,int _c){\n  if(_c!=EC_SYM_MAX){\n    /*No further carry propagation possible, flush buffer.*/\n    int carry;\n    carry=_c>>EC_SYM_BITS;\n    /*Don't output a byte on the first write.\n      This compare should be taken care of by branch-prediction thereafter.*/\n    if(_this->rem>=0)_this->error|=ec_write_byte(_this,_this->rem+carry);\n    if(_this->ext>0){\n      unsigned sym;\n      sym=(EC_SYM_MAX+carry)&EC_SYM_MAX;\n      do _this->error|=ec_write_byte(_this,sym);\n      while(--(_this->ext)>0);\n    }\n    _this->rem=_c&EC_SYM_MAX;\n  }\n  else _this->ext++;\n}\n\nstatic OPUS_INLINE void ec_enc_normalize(ec_enc *_this){\n  /*If the range is too small, output some bits and rescale it.*/\n  while(_this->rng<=EC_CODE_BOT){\n    ec_enc_carry_out(_this,(int)(_this->val>>EC_CODE_SHIFT));\n    /*Move the next-to-high-order symbol into the high-order position.*/\n    _this->val=(_this->val<<EC_SYM_BITS)&(EC_CODE_TOP-1);\n    _this->rng<<=EC_SYM_BITS;\n    _this->nbits_total+=EC_SYM_BITS;\n  }\n}\n\nvoid ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size){\n  _this->buf=_buf;\n  _this->end_offs=0;\n  _this->end_window=0;\n  _this->nend_bits=0;\n  /*This is the offset from which ec_tell() will subtract partial bits.*/\n  _this->nbits_total=EC_CODE_BITS+1;\n  _this->offs=0;\n  _this->rng=EC_CODE_TOP;\n  _this->rem=-1;\n  _this->val=0;\n  _this->ext=0;\n  _this->storage=_size;\n  _this->error=0;\n}\n\nvoid ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){\n  opus_uint32 r;\n  r=celt_udiv(_this->rng,_ft);\n  if(_fl>0){\n    _this->val+=_this->rng-IMUL32(r,(_ft-_fl));\n    _this->rng=IMUL32(r,(_fh-_fl));\n  }\n  else _this->rng-=IMUL32(r,(_ft-_fh));\n  ec_enc_normalize(_this);\n}\n\nvoid ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){\n  opus_uint32 r;\n  r=_this->rng>>_bits;\n  if(_fl>0){\n    _this->val+=_this->rng-IMUL32(r,((1U<<_bits)-_fl));\n    _this->rng=IMUL32(r,(_fh-_fl));\n  }\n  else _this->rng-=IMUL32(r,((1U<<_bits)-_fh));\n  ec_enc_normalize(_this);\n}\n\n/*The probability of having a \"one\" is 1/(1<<_logp).*/\nvoid ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){\n  opus_uint32 r;\n  opus_uint32 s;\n  opus_uint32 l;\n  r=_this->rng;\n  l=_this->val;\n  s=r>>_logp;\n  r-=s;\n  if(_val)_this->val=l+r;\n  _this->rng=_val?s:r;\n  ec_enc_normalize(_this);\n}\n\nvoid ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){\n  opus_uint32 r;\n  r=_this->rng>>_ftb;\n  if(_s>0){\n    _this->val+=_this->rng-IMUL32(r,_icdf[_s-1]);\n    _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]);\n  }\n  else _this->rng-=IMUL32(r,_icdf[_s]);\n  ec_enc_normalize(_this);\n}\n\nvoid ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft){\n  unsigned  ft;\n  unsigned  fl;\n  int       ftb;\n  /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/\n  celt_assert(_ft>1);\n  _ft--;\n  ftb=EC_ILOG(_ft);\n  if(ftb>EC_UINT_BITS){\n    ftb-=EC_UINT_BITS;\n    ft=(_ft>>ftb)+1;\n    fl=(unsigned)(_fl>>ftb);\n    ec_encode(_this,fl,fl+1,ft);\n    ec_enc_bits(_this,_fl&(((opus_uint32)1<<ftb)-1U),ftb);\n  }\n  else ec_encode(_this,_fl,_fl+1,_ft+1);\n}\n\nvoid ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _bits){\n  ec_window window;\n  int       used;\n  window=_this->end_window;\n  used=_this->nend_bits;\n  celt_assert(_bits>0);\n  if(used+_bits>EC_WINDOW_SIZE){\n    do{\n      _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);\n      window>>=EC_SYM_BITS;\n      used-=EC_SYM_BITS;\n    }\n    while(used>=EC_SYM_BITS);\n  }\n  window|=(ec_window)_fl<<used;\n  used+=_bits;\n  _this->end_window=window;\n  _this->nend_bits=used;\n  _this->nbits_total+=_bits;\n}\n\nvoid ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits){\n  int      shift;\n  unsigned mask;\n  celt_assert(_nbits<=EC_SYM_BITS);\n  shift=EC_SYM_BITS-_nbits;\n  mask=((1<<_nbits)-1)<<shift;\n  if(_this->offs>0){\n    /*The first byte has been finalized.*/\n    _this->buf[0]=(unsigned char)((_this->buf[0]&~mask)|_val<<shift);\n  }\n  else if(_this->rem>=0){\n    /*The first byte is still awaiting carry propagation.*/\n    _this->rem=(_this->rem&~mask)|_val<<shift;\n  }\n  else if(_this->rng<=(EC_CODE_TOP>>_nbits)){\n    /*The renormalization loop has never been run.*/\n    _this->val=(_this->val&~((opus_uint32)mask<<EC_CODE_SHIFT))|\n     (opus_uint32)_val<<(EC_CODE_SHIFT+shift);\n  }\n  /*The encoder hasn't even encoded _nbits of data yet.*/\n  else _this->error=-1;\n}\n\nvoid ec_enc_shrink(ec_enc *_this,opus_uint32 _size){\n  celt_assert(_this->offs+_this->end_offs<=_size);\n  OPUS_MOVE(_this->buf+_size-_this->end_offs,\n   _this->buf+_this->storage-_this->end_offs,_this->end_offs);\n  _this->storage=_size;\n}\n\nvoid ec_enc_done(ec_enc *_this){\n  ec_window   window;\n  int         used;\n  opus_uint32 msk;\n  opus_uint32 end;\n  int         l;\n  /*We output the minimum number of bits that ensures that the symbols encoded\n     thus far will be decoded correctly regardless of the bits that follow.*/\n  l=EC_CODE_BITS-EC_ILOG(_this->rng);\n  msk=(EC_CODE_TOP-1)>>l;\n  end=(_this->val+msk)&~msk;\n  if((end|msk)>=_this->val+_this->rng){\n    l++;\n    msk>>=1;\n    end=(_this->val+msk)&~msk;\n  }\n  while(l>0){\n    ec_enc_carry_out(_this,(int)(end>>EC_CODE_SHIFT));\n    end=(end<<EC_SYM_BITS)&(EC_CODE_TOP-1);\n    l-=EC_SYM_BITS;\n  }\n  /*If we have a buffered byte flush it into the output buffer.*/\n  if(_this->rem>=0||_this->ext>0)ec_enc_carry_out(_this,0);\n  /*If we have buffered extra bits, flush them as well.*/\n  window=_this->end_window;\n  used=_this->nend_bits;\n  while(used>=EC_SYM_BITS){\n    _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);\n    window>>=EC_SYM_BITS;\n    used-=EC_SYM_BITS;\n  }\n  /*Clear any excess space and add any remaining extra bits to the last byte.*/\n  if(!_this->error){\n    OPUS_CLEAR(_this->buf+_this->offs,\n     _this->storage-_this->offs-_this->end_offs);\n    if(used>0){\n      /*If there's no range coder data at all, give up.*/\n      if(_this->end_offs>=_this->storage)_this->error=-1;\n      else{\n        l=-l;\n        /*If we've busted, don't add too many extra bits to the last byte; it\n           would corrupt the range coder data, and that's more important.*/\n        if(_this->offs+_this->end_offs>=_this->storage&&l<used){\n          window&=(1<<l)-1;\n          _this->error=-1;\n        }\n        _this->buf[_this->storage-_this->end_offs-1]|=(unsigned char)window;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/entenc.h",
    "content": "/* Copyright (c) 2001-2011 Timothy B. Terriberry\n   Copyright (c) 2008-2009 Xiph.Org Foundation */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#if !defined(_entenc_H)\n# define _entenc_H (1)\n# include <stddef.h>\n# include \"entcode.h\"\n\n/*Initializes the encoder.\n  _buf:  The buffer to store output bytes in.\n  _size: The size of the buffer, in chars.*/\nvoid ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size);\n/*Encodes a symbol given its frequency information.\n  The frequency information must be discernable by the decoder, assuming it\n   has read only the previous symbols from the stream.\n  It is allowable to change the frequency information, or even the entire\n   source alphabet, so long as the decoder can tell from the context of the\n   previously encoded information that it is supposed to do so as well.\n  _fl: The cumulative frequency of all symbols that come before the one to be\n        encoded.\n  _fh: The cumulative frequency of all symbols up to and including the one to\n        be encoded.\n       Together with _fl, this defines the range [_fl,_fh) in which the\n        decoded value will fall.\n  _ft: The sum of the frequencies of all the symbols*/\nvoid ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft);\n\n/*Equivalent to ec_encode() with _ft==1<<_bits.*/\nvoid ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits);\n\n/* Encode a bit that has a 1/(1<<_logp) probability of being a one */\nvoid ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp);\n\n/*Encodes a symbol given an \"inverse\" CDF table.\n  _s:    The index of the symbol to encode.\n  _icdf: The \"inverse\" CDF, such that symbol _s falls in the range\n          [_s>0?ft-_icdf[_s-1]:0,ft-_icdf[_s]), where ft=1<<_ftb.\n         The values must be monotonically non-increasing, and the last value\n          must be 0.\n  _ftb: The number of bits of precision in the cumulative distribution.*/\nvoid ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb);\n\n/*Encodes a raw unsigned integer in the stream.\n  _fl: The integer to encode.\n  _ft: The number of integers that can be encoded (one more than the max).\n       This must be at least one, and no more than 2**32-1.*/\nvoid ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft);\n\n/*Encodes a sequence of raw bits in the stream.\n  _fl:  The bits to encode.\n  _ftb: The number of bits to encode.\n        This must be between 1 and 25, inclusive.*/\nvoid ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _ftb);\n\n/*Overwrites a few bits at the very start of an existing stream, after they\n   have already been encoded.\n  This makes it possible to have a few flags up front, where it is easy for\n   decoders to access them without parsing the whole stream, even if their\n   values are not determined until late in the encoding process, without having\n   to buffer all the intermediate symbols in the encoder.\n  In order for this to work, at least _nbits bits must have already been\n   encoded using probabilities that are an exact power of two.\n  The encoder can verify the number of encoded bits is sufficient, but cannot\n   check this latter condition.\n  _val:   The bits to encode (in the least _nbits significant bits).\n          They will be decoded in order from most-significant to least.\n  _nbits: The number of bits to overwrite.\n          This must be no more than 8.*/\nvoid ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits);\n\n/*Compacts the data to fit in the target size.\n  This moves up the raw bits at the end of the current buffer so they are at\n   the end of the new buffer size.\n  The caller must ensure that the amount of data that's already been written\n   will fit in the new size.\n  _size: The number of bytes in the new buffer.\n         This must be large enough to contain the bits already written, and\n          must be no larger than the existing size.*/\nvoid ec_enc_shrink(ec_enc *_this,opus_uint32 _size);\n\n/*Indicates that there are no more symbols to encode.\n  All reamining output bytes are flushed to the output buffer.\n  ec_enc_init() must be called before the encoder can be used again.*/\nvoid ec_enc_done(ec_enc *_this);\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/fixed_debug.h",
    "content": "/* Copyright (C) 2003-2008 Jean-Marc Valin\n   Copyright (C) 2007-2012 Xiph.Org Foundation */\n/**\n   @file fixed_debug.h\n   @brief Fixed-point operations with debugging\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef FIXED_DEBUG_H\n#define FIXED_DEBUG_H\n\n#include <stdio.h>\n#include \"opus_defines.h\"\n\n#ifdef CELT_C\nOPUS_EXPORT opus_int64 celt_mips=0;\n#else\nextern opus_int64 celt_mips;\n#endif\n\n#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))\n#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL32(MULT16_16(SHR32((a),16),SHR((b),16)),1), SHR32(MULT16_16SU(SHR32((a),16),((b)&0x0000ffff)),15)), SHR32(MULT16_16SU(SHR32((b),16),((a)&0x0000ffff)),15))\n\n/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */\n#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16))\n\n#define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16)\n\n#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))\n#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))\n\n#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)\n#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)\n#define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1))\n\n#define SHR(a,b) SHR32(a,b)\n#define PSHR(a,b) PSHR32(a,b)\n\nstatic OPUS_INLINE short NEG16(int x)\n{\n   int res;\n   if (!VERIFY_SHORT(x))\n   {\n      fprintf (stderr, \"NEG16: input is not short: %d\\n\", (int)x);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = -x;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"NEG16: output is not short: %d\\n\", (int)res);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips++;\n   return res;\n}\nstatic OPUS_INLINE int NEG32(opus_int64 x)\n{\n   opus_int64 res;\n   if (!VERIFY_INT(x))\n   {\n      fprintf (stderr, \"NEG16: input is not int: %d\\n\", (int)x);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = -x;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"NEG16: output is not int: %d\\n\", (int)res);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=2;\n   return res;\n}\n\n#define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__)\nstatic OPUS_INLINE short EXTRACT16_(int x, char *file, int line)\n{\n   int res;\n   if (!VERIFY_SHORT(x))\n   {\n      fprintf (stderr, \"EXTRACT16: input is not short: %d in %s: line %d\\n\", x, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = x;\n   celt_mips++;\n   return res;\n}\n\n#define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__)\nstatic OPUS_INLINE int EXTEND32_(int x, char *file, int line)\n{\n   int res;\n   if (!VERIFY_SHORT(x))\n   {\n      fprintf (stderr, \"EXTEND32: input is not short: %d in %s: line %d\\n\", x, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = x;\n   celt_mips++;\n   return res;\n}\n\n#define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__)\nstatic OPUS_INLINE short SHR16_(int a, int shift, char *file, int line)\n{\n   int res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))\n   {\n      fprintf (stderr, \"SHR16: inputs are not short: %d >> %d in %s: line %d\\n\", a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = a>>shift;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"SHR16: output is not short: %d in %s: line %d\\n\", res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips++;\n   return res;\n}\n#define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__)\nstatic OPUS_INLINE short SHL16_(int a, int shift, char *file, int line)\n{\n   int res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))\n   {\n      fprintf (stderr, \"SHL16: inputs are not short: %d %d in %s: line %d\\n\", a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = a<<shift;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"SHL16: output is not short: %d in %s: line %d\\n\", res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips++;\n   return res;\n}\n\nstatic OPUS_INLINE int SHR32(opus_int64 a, int shift)\n{\n   opus_int64  res;\n   if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))\n   {\n      fprintf (stderr, \"SHR32: inputs are not int: %d %d\\n\", (int)a, shift);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = a>>shift;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"SHR32: output is not int: %d\\n\", (int)res);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=2;\n   return res;\n}\n#define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__)\nstatic OPUS_INLINE int SHL32_(opus_int64 a, int shift, char *file, int line)\n{\n   opus_int64  res;\n   if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))\n   {\n      fprintf (stderr, \"SHL32: inputs are not int: %lld %d in %s: line %d\\n\", a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = a<<shift;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"SHL32: output is not int: %lld<<%d = %lld in %s: line %d\\n\", a, shift, res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=2;\n   return res;\n}\n\n#define PSHR32(a,shift) (celt_mips--,SHR32(ADD32((a),(((opus_val32)(1)<<((shift))>>1))),shift))\n#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))\n\n#define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a))))\n#define HALF16(x)  (SHR16(x,1))\n#define HALF32(x)  (SHR32(x,1))\n\n//#define SHR(a,shift) ((a) >> (shift))\n//#define SHL(a,shift) ((a) << (shift))\n\n#define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__)\nstatic OPUS_INLINE short ADD16_(int a, int b, char *file, int line)\n{\n   int res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"ADD16: inputs are not short: %d %d in %s: line %d\\n\", a, b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = a+b;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"ADD16: output is not short: %d+%d=%d in %s: line %d\\n\", a,b,res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips++;\n   return res;\n}\n\n#define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__)\nstatic OPUS_INLINE short SUB16_(int a, int b, char *file, int line)\n{\n   int res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"SUB16: inputs are not short: %d %d in %s: line %d\\n\", a, b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = a-b;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"SUB16: output is not short: %d in %s: line %d\\n\", res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips++;\n   return res;\n}\n\n#define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__)\nstatic OPUS_INLINE int ADD32_(opus_int64 a, opus_int64 b, char *file, int line)\n{\n   opus_int64 res;\n   if (!VERIFY_INT(a) || !VERIFY_INT(b))\n   {\n      fprintf (stderr, \"ADD32: inputs are not int: %d %d in %s: line %d\\n\", (int)a, (int)b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = a+b;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"ADD32: output is not int: %d in %s: line %d\\n\", (int)res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=2;\n   return res;\n}\n\n#define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__)\nstatic OPUS_INLINE int SUB32_(opus_int64 a, opus_int64 b, char *file, int line)\n{\n   opus_int64 res;\n   if (!VERIFY_INT(a) || !VERIFY_INT(b))\n   {\n      fprintf (stderr, \"SUB32: inputs are not int: %d %d in %s: line %d\\n\", (int)a, (int)b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = a-b;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"SUB32: output is not int: %d in %s: line %d\\n\", (int)res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=2;\n   return res;\n}\n\n#undef UADD32\n#define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__)\nstatic OPUS_INLINE unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int line)\n{\n   opus_uint64 res;\n   if (!VERIFY_UINT(a) || !VERIFY_UINT(b))\n   {\n      fprintf (stderr, \"UADD32: inputs are not uint32: %llu %llu in %s: line %d\\n\", a, b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = a+b;\n   if (!VERIFY_UINT(res))\n   {\n      fprintf (stderr, \"UADD32: output is not uint32: %llu in %s: line %d\\n\", res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=2;\n   return res;\n}\n\n#undef USUB32\n#define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__)\nstatic OPUS_INLINE unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int line)\n{\n   opus_uint64 res;\n   if (!VERIFY_UINT(a) || !VERIFY_UINT(b))\n   {\n      fprintf (stderr, \"USUB32: inputs are not uint32: %llu %llu in %s: line %d\\n\", a, b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   if (a<b)\n   {\n      fprintf (stderr, \"USUB32: inputs underflow: %llu < %llu in %s: line %d\\n\", a, b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = a-b;\n   if (!VERIFY_UINT(res))\n   {\n      fprintf (stderr, \"USUB32: output is not uint32: %llu - %llu = %llu in %s: line %d\\n\", a, b, res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=2;\n   return res;\n}\n\n/* result fits in 16 bits */\nstatic OPUS_INLINE short MULT16_16_16(int a, int b)\n{\n   int res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_16: inputs are not short: %d %d\\n\", a, b);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = a*b;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"MULT16_16_16: output is not short: %d\\n\", res);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips++;\n   return res;\n}\n\n#define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__)\nstatic OPUS_INLINE int MULT16_16_(int a, int b, char *file, int line)\n{\n   opus_int64 res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16: inputs are not short: %d %d in %s: line %d\\n\", a, b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = ((opus_int64)a)*b;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"MULT16_16: output is not int: %d in %s: line %d\\n\", (int)res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips++;\n   return res;\n}\n\n#define MAC16_16(c,a,b)     (celt_mips-=2,ADD32((c),MULT16_16((a),(b))))\n\n#define MULT16_32_QX(a, b, Q) MULT16_32_QX_(a, b, Q, __FILE__, __LINE__)\nstatic OPUS_INLINE int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int line)\n{\n   opus_int64 res;\n   if (!VERIFY_SHORT(a) || !VERIFY_INT(b))\n   {\n      fprintf (stderr, \"MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\\n\", Q, (int)a, (int)b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   if (ABS32(b)>=((opus_val32)(1)<<(15+Q)))\n   {\n      fprintf (stderr, \"MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\\n\", Q, (int)a, (int)b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = (((opus_int64)a)*(opus_int64)b) >> Q;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\\n\", Q, (int)a, (int)b,(int)res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   if (Q==15)\n      celt_mips+=3;\n   else\n      celt_mips+=4;\n   return res;\n}\n\n#define MULT16_32_PX(a, b, Q) MULT16_32_PX_(a, b, Q, __FILE__, __LINE__)\nstatic OPUS_INLINE int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line)\n{\n   opus_int64 res;\n   if (!VERIFY_SHORT(a) || !VERIFY_INT(b))\n   {\n      fprintf (stderr, \"MULT16_32_P%d: inputs are not short+int: %d %d in %s: line %d\\n\\n\", Q, (int)a, (int)b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   if (ABS32(b)>=((opus_int64)(1)<<(15+Q)))\n   {\n      fprintf (stderr, \"MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\\n\\n\", Q, (int)a, (int)b,file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = ((((opus_int64)a)*(opus_int64)b) + (((opus_val32)(1)<<Q)>>1))>> Q;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"MULT16_32_P%d: output is not int: %d*%d=%d in %s: line %d\\n\\n\", Q, (int)a, (int)b,(int)res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   if (Q==15)\n      celt_mips+=4;\n   else\n      celt_mips+=5;\n   return res;\n}\n\n#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)\n#define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b))))\n#define MAC16_32_Q16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q16((a),(b))))\n\nstatic OPUS_INLINE int SATURATE(int a, int b)\n{\n   if (a>b)\n      a=b;\n   if (a<-b)\n      a = -b;\n   celt_mips+=3;\n   return a;\n}\n\nstatic OPUS_INLINE opus_int16 SATURATE16(opus_int32 a)\n{\n   celt_mips+=3;\n   if (a>32767)\n      return 32767;\n   else if (a<-32768)\n      return -32768;\n   else return a;\n}\n\nstatic OPUS_INLINE int MULT16_16_Q11_32(int a, int b)\n{\n   opus_int64 res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_Q11: inputs are not short: %d %d\\n\", a, b);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = ((opus_int64)a)*b;\n   res >>= 11;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"MULT16_16_Q11: output is not short: %d*%d=%d\\n\", (int)a, (int)b, (int)res);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=3;\n   return res;\n}\nstatic OPUS_INLINE short MULT16_16_Q13(int a, int b)\n{\n   opus_int64 res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_Q13: inputs are not short: %d %d\\n\", a, b);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = ((opus_int64)a)*b;\n   res >>= 13;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"MULT16_16_Q13: output is not short: %d*%d=%d\\n\", a, b, (int)res);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=3;\n   return res;\n}\nstatic OPUS_INLINE short MULT16_16_Q14(int a, int b)\n{\n   opus_int64 res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_Q14: inputs are not short: %d %d\\n\", a, b);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = ((opus_int64)a)*b;\n   res >>= 14;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"MULT16_16_Q14: output is not short: %d\\n\", (int)res);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=3;\n   return res;\n}\n\n#define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__)\nstatic OPUS_INLINE short MULT16_16_Q15_(int a, int b, char *file, int line)\n{\n   opus_int64 res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\\n\", a, b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = ((opus_int64)a)*b;\n   res >>= 15;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"MULT16_16_Q15: output is not short: %d in %s: line %d\\n\", (int)res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=1;\n   return res;\n}\n\nstatic OPUS_INLINE short MULT16_16_P13(int a, int b)\n{\n   opus_int64 res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_P13: inputs are not short: %d %d\\n\", a, b);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = ((opus_int64)a)*b;\n   res += 4096;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"MULT16_16_P13: overflow: %d*%d=%d\\n\", a, b, (int)res);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res >>= 13;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"MULT16_16_P13: output is not short: %d*%d=%d\\n\", a, b, (int)res);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=4;\n   return res;\n}\nstatic OPUS_INLINE short MULT16_16_P14(int a, int b)\n{\n   opus_int64 res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_P14: inputs are not short: %d %d\\n\", a, b);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = ((opus_int64)a)*b;\n   res += 8192;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"MULT16_16_P14: overflow: %d*%d=%d\\n\", a, b, (int)res);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res >>= 14;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"MULT16_16_P14: output is not short: %d*%d=%d\\n\", a, b, (int)res);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=4;\n   return res;\n}\nstatic OPUS_INLINE short MULT16_16_P15(int a, int b)\n{\n   opus_int64 res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_P15: inputs are not short: %d %d\\n\", a, b);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = ((opus_int64)a)*b;\n   res += 16384;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"MULT16_16_P15: overflow: %d*%d=%d\\n\", a, b, (int)res);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res >>= 15;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"MULT16_16_P15: output is not short: %d*%d=%d\\n\", a, b, (int)res);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=2;\n   return res;\n}\n\n#define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__)\n\nstatic OPUS_INLINE int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line)\n{\n   opus_int64 res;\n   if (b==0)\n   {\n      fprintf(stderr, \"DIV32_16: divide by zero: %d/%d in %s: line %d\\n\", (int)a, (int)b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n      return 0;\n   }\n   if (!VERIFY_INT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"DIV32_16: inputs are not int/short: %d %d in %s: line %d\\n\", (int)a, (int)b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = a/b;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"DIV32_16: output is not short: %d / %d = %d in %s: line %d\\n\", (int)a,(int)b,(int)res, file, line);\n      if (res>32767)\n         res = 32767;\n      if (res<-32768)\n         res = -32768;\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=35;\n   return res;\n}\n\n#define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__)\nstatic OPUS_INLINE int DIV32_(opus_int64 a, opus_int64 b, char *file, int line)\n{\n   opus_int64 res;\n   if (b==0)\n   {\n      fprintf(stderr, \"DIV32: divide by zero: %d/%d in %s: line %d\\n\", (int)a, (int)b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n      return 0;\n   }\n\n   if (!VERIFY_INT(a) || !VERIFY_INT(b))\n   {\n      fprintf (stderr, \"DIV32: inputs are not int/short: %d %d in %s: line %d\\n\", (int)a, (int)b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   res = a/b;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"DIV32: output is not int: %d in %s: line %d\\n\", (int)res, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n      celt_assert(0);\n#endif\n   }\n   celt_mips+=70;\n   return res;\n}\n\nstatic OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x)\n{\n   x = PSHR32(x, SIG_SHIFT);\n   x = MAX32(x, -32768);\n   x = MIN32(x, 32767);\n   return EXTRACT16(x);\n}\n#define SIG2WORD16(x) (SIG2WORD16_generic(x))\n\n\n#undef PRINT_MIPS\n#define PRINT_MIPS(file) do {fprintf (file, \"total complexity = %llu MIPS\\n\", celt_mips);} while (0);\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/fixed_generic.h",
    "content": "/* Copyright (C) 2007-2009 Xiph.Org Foundation\n   Copyright (C) 2003-2008 Jean-Marc Valin\n   Copyright (C) 2007-2008 CSIRO */\n/**\n   @file fixed_generic.h\n   @brief Generic fixed-point operations\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef FIXED_GENERIC_H\n#define FIXED_GENERIC_H\n\n/** Multiply a 16-bit signed value by a 16-bit unsigned value. The result is a 32-bit signed value */\n#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))\n\n/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */\n#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16))\n\n/** 16x32 multiplication, followed by a 16-bit shift right (round-to-nearest). Results fits in 32 bits */\n#define MULT16_32_P16(a,b) ADD32(MULT16_16((a),SHR((b),16)), PSHR(MULT16_16SU((a),((b)&0x0000ffff)),16))\n\n/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */\n#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15))\n\n/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */\n#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL(MULT16_16(SHR((a),16),SHR((b),16)),1), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),15)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),15))\n\n/** Compile-time conversion of float constant to 16-bit value */\n#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))\n\n/** Compile-time conversion of float constant to 32-bit value */\n#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))\n\n/** Negate a 16-bit value */\n#define NEG16(x) (-(x))\n/** Negate a 32-bit value */\n#define NEG32(x) (-(x))\n\n/** Change a 32-bit value into a 16-bit value. The value is assumed to fit in 16-bit, otherwise the result is undefined */\n#define EXTRACT16(x) ((opus_val16)(x))\n/** Change a 16-bit value into a 32-bit value */\n#define EXTEND32(x) ((opus_val32)(x))\n\n/** Arithmetic shift-right of a 16-bit value */\n#define SHR16(a,shift) ((a) >> (shift))\n/** Arithmetic shift-left of a 16-bit value */\n#define SHL16(a,shift) ((opus_int16)((opus_uint16)(a)<<(shift)))\n/** Arithmetic shift-right of a 32-bit value */\n#define SHR32(a,shift) ((a) >> (shift))\n/** Arithmetic shift-left of a 32-bit value */\n#define SHL32(a,shift) ((opus_int32)((opus_uint32)(a)<<(shift)))\n\n/** 32-bit arithmetic shift right with rounding-to-nearest instead of rounding down */\n#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift))\n/** 32-bit arithmetic shift right where the argument can be negative */\n#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))\n\n/** \"RAW\" macros, should not be used outside of this header file */\n#define SHR(a,shift) ((a) >> (shift))\n#define SHL(a,shift) SHL32(a,shift)\n#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))\n#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))\n\n#define SATURATE16(x) (EXTRACT16((x)>32767 ? 32767 : (x)<-32768 ? -32768 : (x)))\n\n/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */\n#define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a))))\n/** Divide by two */\n#define HALF16(x)  (SHR16(x,1))\n#define HALF32(x)  (SHR32(x,1))\n\n/** Add two 16-bit values */\n#define ADD16(a,b) ((opus_val16)((opus_val16)(a)+(opus_val16)(b)))\n/** Subtract two 16-bit values */\n#define SUB16(a,b) ((opus_val16)(a)-(opus_val16)(b))\n/** Add two 32-bit values */\n#define ADD32(a,b) ((opus_val32)(a)+(opus_val32)(b))\n/** Subtract two 32-bit values */\n#define SUB32(a,b) ((opus_val32)(a)-(opus_val32)(b))\n\n/** 16x16 multiplication where the result fits in 16 bits */\n#define MULT16_16_16(a,b)     ((((opus_val16)(a))*((opus_val16)(b))))\n\n/* (opus_val32)(opus_val16) gives TI compiler a hint that it's 16x16->32 multiply */\n/** 16x16 multiplication where the result fits in 32 bits */\n#define MULT16_16(a,b)     (((opus_val32)(opus_val16)(a))*((opus_val32)(opus_val16)(b)))\n\n/** 16x16 multiply-add where the result fits in 32 bits */\n#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))\n/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add.\n    b must fit in 31 bits.\n    Result fits in 32 bits. */\n#define MAC16_32_Q15(c,a,b) ADD32((c),ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))\n\n/** 16x32 multiplication, followed by a 16-bit shift right and 32-bit add.\n    Results fits in 32 bits */\n#define MAC16_32_Q16(c,a,b) ADD32((c),ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16)))\n\n#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))\n#define MULT16_16_Q11(a,b) (SHR(MULT16_16((a),(b)),11))\n#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))\n#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))\n#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))\n\n#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13))\n#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14))\n#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15))\n\n/** Divide a 32-bit value by a 16-bit value. Result fits in 16 bits */\n#define DIV32_16(a,b) ((opus_val16)(((opus_val32)(a))/((opus_val16)(b))))\n\n/** Divide a 32-bit value by a 32-bit value. Result fits in 32 bits */\n#define DIV32(a,b) (((opus_val32)(a))/((opus_val32)(b)))\n\n#if defined(MIPSr1_ASM)\n#include \"mips/fixed_generic_mipsr1.h\"\n#endif\n\nstatic OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x)\n{\n   x = PSHR32(x, SIG_SHIFT);\n   x = MAX32(x, -32768);\n   x = MIN32(x, 32767);\n   return EXTRACT16(x);\n}\n#define SIG2WORD16(x) (SIG2WORD16_generic(x))\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/float_cast.h",
    "content": "/* Copyright (C) 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com> */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/* Version 1.1 */\n\n#ifndef FLOAT_CAST_H\n#define FLOAT_CAST_H\n\n\n#include \"arch.h\"\n\n/*============================================================================\n**      On Intel Pentium processors (especially PIII and probably P4), converting\n**      from float to int is very slow. To meet the C specs, the code produced by\n**      most C compilers targeting Pentium needs to change the FPU rounding mode\n**      before the float to int conversion is performed.\n**\n**      Changing the FPU rounding mode causes the FPU pipeline to be flushed. It\n**      is this flushing of the pipeline which is so slow.\n**\n**      Fortunately the ISO C99 specifications define the functions lrint, lrintf,\n**      llrint and llrintf which fix this problem as a side effect.\n**\n**      On Unix-like systems, the configure process should have detected the\n**      presence of these functions. If they weren't found we have to replace them\n**      here with a standard C cast.\n*/\n\n/*\n**      The C99 prototypes for lrint and lrintf are as follows:\n**\n**              long int lrintf (float x) ;\n**              long int lrint  (double x) ;\n*/\n\n/*      The presence of the required functions are detected during the configure\n**      process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in\n**      the config.h file.\n*/\n\n#if (HAVE_LRINTF)\n\n/*      These defines enable functionality introduced with the 1999 ISO C\n**      standard. They must be defined before the inclusion of math.h to\n**      engage them. If optimisation is enabled, these functions will be\n**      inlined. With optimisation switched off, you have to link in the\n**      maths library using -lm.\n*/\n\n#define _ISOC9X_SOURCE 1\n#define _ISOC99_SOURCE 1\n\n#define __USE_ISOC9X 1\n#define __USE_ISOC99 1\n\n#include <math.h>\n#define float2int(x) lrintf(x)\n\n#elif (defined(HAVE_LRINT))\n\n#define _ISOC9X_SOURCE 1\n#define _ISOC99_SOURCE 1\n\n#define __USE_ISOC9X 1\n#define __USE_ISOC99 1\n\n#include <math.h>\n#define float2int(x) lrint(x)\n\n#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_X64)\n        #include <xmmintrin.h>\n\n        __inline long int float2int(float value)\n        {\n                return _mm_cvtss_si32(_mm_load_ss(&value));\n        }\n#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_IX86)\n        #include <math.h>\n\n        /*      Win32 doesn't seem to have these functions.\n        **      Therefore implement OPUS_INLINE versions of these functions here.\n        */\n\n        __inline long int\n        float2int (float flt)\n        {       int intgr;\n\n                _asm\n                {       fld flt\n                        fistp intgr\n                } ;\n\n                return intgr ;\n        }\n\n#else\n\n#if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L)\n        /* supported by gcc in C99 mode, but not by all other compilers */\n        #warning \"Don't have the functions lrint() and lrintf ().\"\n        #warning \"Replacing these functions with a standard C cast.\"\n#endif /* __STDC_VERSION__ >= 199901L */\n        #include <math.h>\n        #define float2int(flt) ((int)(floor(.5+flt)))\n#endif\n\n#ifndef DISABLE_FLOAT_API\nstatic OPUS_INLINE opus_int16 FLOAT2INT16(float x)\n{\n   x = x*CELT_SIG_SCALE;\n   x = MAX32(x, -32768);\n   x = MIN32(x, 32767);\n   return (opus_int16)float2int(x);\n}\n#endif /* DISABLE_FLOAT_API */\n\n#endif /* FLOAT_CAST_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/kiss_fft.c",
    "content": "/*Copyright (c) 2003-2004, Mark Borgerding\n  Lots of modifications by Jean-Marc Valin\n  Copyright (c) 2005-2007, Xiph.Org Foundation\n  Copyright (c) 2008,      Xiph.Org Foundation, CSIRO\n\n  All rights reserved.\n\n  Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n       this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright notice,\n       this list of conditions and the following disclaimer in the\n       documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n  POSSIBILITY OF SUCH DAMAGE.*/\n\n/* This code is originally from Mark Borgerding's KISS-FFT but has been\n   heavily modified to better suit Opus */\n\n#ifndef SKIP_CONFIG_H\n#  ifdef HAVE_CONFIG_H\n#    include \"config.h\"\n#  endif\n#endif\n\n#include \"_kiss_fft_guts.h\"\n#include \"arch.h\"\n#include \"os_support.h\"\n#include \"mathops.h\"\n#include \"stack_alloc.h\"\n\n/* The guts header contains all the multiplication and addition macros that are defined for\n   complex numbers.  It also delares the kf_ internal functions.\n*/\n\nstatic void kf_bfly2(\n                     kiss_fft_cpx * Fout,\n                     int m,\n                     int N\n                    )\n{\n   kiss_fft_cpx * Fout2;\n   int i;\n   (void)m;\n#ifdef CUSTOM_MODES\n   if (m==1)\n   {\n      celt_assert(m==1);\n      for (i=0;i<N;i++)\n      {\n         kiss_fft_cpx t;\n         Fout2 = Fout + 1;\n         t = *Fout2;\n         C_SUB( *Fout2 ,  *Fout , t );\n         C_ADDTO( *Fout ,  t );\n         Fout += 2;\n      }\n   } else\n#endif\n   {\n      opus_val16 tw;\n      tw = QCONST16(0.7071067812f, 15);\n      /* We know that m==4 here because the radix-2 is just after a radix-4 */\n      celt_assert(m==4);\n      for (i=0;i<N;i++)\n      {\n         kiss_fft_cpx t;\n         Fout2 = Fout + 4;\n         t = Fout2[0];\n         C_SUB( Fout2[0] ,  Fout[0] , t );\n         C_ADDTO( Fout[0] ,  t );\n\n         t.r = S_MUL(Fout2[1].r+Fout2[1].i, tw);\n         t.i = S_MUL(Fout2[1].i-Fout2[1].r, tw);\n         C_SUB( Fout2[1] ,  Fout[1] , t );\n         C_ADDTO( Fout[1] ,  t );\n\n         t.r = Fout2[2].i;\n         t.i = -Fout2[2].r;\n         C_SUB( Fout2[2] ,  Fout[2] , t );\n         C_ADDTO( Fout[2] ,  t );\n\n         t.r = S_MUL(Fout2[3].i-Fout2[3].r, tw);\n         t.i = S_MUL(-Fout2[3].i-Fout2[3].r, tw);\n         C_SUB( Fout2[3] ,  Fout[3] , t );\n         C_ADDTO( Fout[3] ,  t );\n         Fout += 8;\n      }\n   }\n}\n\nstatic void kf_bfly4(\n                     kiss_fft_cpx * Fout,\n                     const size_t fstride,\n                     const kiss_fft_state *st,\n                     int m,\n                     int N,\n                     int mm\n                    )\n{\n   int i;\n\n   if (m==1)\n   {\n      /* Degenerate case where all the twiddles are 1. */\n      for (i=0;i<N;i++)\n      {\n         kiss_fft_cpx scratch0, scratch1;\n\n         C_SUB( scratch0 , *Fout, Fout[2] );\n         C_ADDTO(*Fout, Fout[2]);\n         C_ADD( scratch1 , Fout[1] , Fout[3] );\n         C_SUB( Fout[2], *Fout, scratch1 );\n         C_ADDTO( *Fout , scratch1 );\n         C_SUB( scratch1 , Fout[1] , Fout[3] );\n\n         Fout[1].r = scratch0.r + scratch1.i;\n         Fout[1].i = scratch0.i - scratch1.r;\n         Fout[3].r = scratch0.r - scratch1.i;\n         Fout[3].i = scratch0.i + scratch1.r;\n         Fout+=4;\n      }\n   } else {\n      int j;\n      kiss_fft_cpx scratch[6];\n      const kiss_twiddle_cpx *tw1,*tw2,*tw3;\n      const int m2=2*m;\n      const int m3=3*m;\n      kiss_fft_cpx * Fout_beg = Fout;\n      for (i=0;i<N;i++)\n      {\n         Fout = Fout_beg + i*mm;\n         tw3 = tw2 = tw1 = st->twiddles;\n         /* m is guaranteed to be a multiple of 4. */\n         for (j=0;j<m;j++)\n         {\n            C_MUL(scratch[0],Fout[m] , *tw1 );\n            C_MUL(scratch[1],Fout[m2] , *tw2 );\n            C_MUL(scratch[2],Fout[m3] , *tw3 );\n\n            C_SUB( scratch[5] , *Fout, scratch[1] );\n            C_ADDTO(*Fout, scratch[1]);\n            C_ADD( scratch[3] , scratch[0] , scratch[2] );\n            C_SUB( scratch[4] , scratch[0] , scratch[2] );\n            C_SUB( Fout[m2], *Fout, scratch[3] );\n            tw1 += fstride;\n            tw2 += fstride*2;\n            tw3 += fstride*3;\n            C_ADDTO( *Fout , scratch[3] );\n\n            Fout[m].r = scratch[5].r + scratch[4].i;\n            Fout[m].i = scratch[5].i - scratch[4].r;\n            Fout[m3].r = scratch[5].r - scratch[4].i;\n            Fout[m3].i = scratch[5].i + scratch[4].r;\n            ++Fout;\n         }\n      }\n   }\n}\n\n\n#ifndef RADIX_TWO_ONLY\n\nstatic void kf_bfly3(\n                     kiss_fft_cpx * Fout,\n                     const size_t fstride,\n                     const kiss_fft_state *st,\n                     int m,\n                     int N,\n                     int mm\n                    )\n{\n   int i;\n   size_t k;\n   const size_t m2 = 2*m;\n   const kiss_twiddle_cpx *tw1,*tw2;\n   kiss_fft_cpx scratch[5];\n   kiss_twiddle_cpx epi3;\n\n   kiss_fft_cpx * Fout_beg = Fout;\n#ifdef FIXED_POINT\n   epi3.r = -16384;\n   epi3.i = -28378;\n#else\n   epi3 = st->twiddles[fstride*m];\n#endif\n   for (i=0;i<N;i++)\n   {\n      Fout = Fout_beg + i*mm;\n      tw1=tw2=st->twiddles;\n      /* For non-custom modes, m is guaranteed to be a multiple of 4. */\n      k=m;\n      do {\n\n         C_MUL(scratch[1],Fout[m] , *tw1);\n         C_MUL(scratch[2],Fout[m2] , *tw2);\n\n         C_ADD(scratch[3],scratch[1],scratch[2]);\n         C_SUB(scratch[0],scratch[1],scratch[2]);\n         tw1 += fstride;\n         tw2 += fstride*2;\n\n         Fout[m].r = Fout->r - HALF_OF(scratch[3].r);\n         Fout[m].i = Fout->i - HALF_OF(scratch[3].i);\n\n         C_MULBYSCALAR( scratch[0] , epi3.i );\n\n         C_ADDTO(*Fout,scratch[3]);\n\n         Fout[m2].r = Fout[m].r + scratch[0].i;\n         Fout[m2].i = Fout[m].i - scratch[0].r;\n\n         Fout[m].r -= scratch[0].i;\n         Fout[m].i += scratch[0].r;\n\n         ++Fout;\n      } while(--k);\n   }\n}\n\n\n#ifndef OVERRIDE_kf_bfly5\nstatic void kf_bfly5(\n                     kiss_fft_cpx * Fout,\n                     const size_t fstride,\n                     const kiss_fft_state *st,\n                     int m,\n                     int N,\n                     int mm\n                    )\n{\n   kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;\n   int i, u;\n   kiss_fft_cpx scratch[13];\n   const kiss_twiddle_cpx *tw;\n   kiss_twiddle_cpx ya,yb;\n   kiss_fft_cpx * Fout_beg = Fout;\n\n#ifdef FIXED_POINT\n   ya.r = 10126;\n   ya.i = -31164;\n   yb.r = -26510;\n   yb.i = -19261;\n#else\n   ya = st->twiddles[fstride*m];\n   yb = st->twiddles[fstride*2*m];\n#endif\n   tw=st->twiddles;\n\n   for (i=0;i<N;i++)\n   {\n      Fout = Fout_beg + i*mm;\n      Fout0=Fout;\n      Fout1=Fout0+m;\n      Fout2=Fout0+2*m;\n      Fout3=Fout0+3*m;\n      Fout4=Fout0+4*m;\n\n      /* For non-custom modes, m is guaranteed to be a multiple of 4. */\n      for ( u=0; u<m; ++u ) {\n         scratch[0] = *Fout0;\n\n         C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);\n         C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);\n         C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);\n         C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);\n\n         C_ADD( scratch[7],scratch[1],scratch[4]);\n         C_SUB( scratch[10],scratch[1],scratch[4]);\n         C_ADD( scratch[8],scratch[2],scratch[3]);\n         C_SUB( scratch[9],scratch[2],scratch[3]);\n\n         Fout0->r += scratch[7].r + scratch[8].r;\n         Fout0->i += scratch[7].i + scratch[8].i;\n\n         scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);\n         scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);\n\n         scratch[6].r =  S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);\n         scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);\n\n         C_SUB(*Fout1,scratch[5],scratch[6]);\n         C_ADD(*Fout4,scratch[5],scratch[6]);\n\n         scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);\n         scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);\n         scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);\n         scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);\n\n         C_ADD(*Fout2,scratch[11],scratch[12]);\n         C_SUB(*Fout3,scratch[11],scratch[12]);\n\n         ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;\n      }\n   }\n}\n#endif /* OVERRIDE_kf_bfly5 */\n\n\n#endif\n\n\n#ifdef CUSTOM_MODES\n\nstatic\nvoid compute_bitrev_table(\n         int Fout,\n         opus_int16 *f,\n         const size_t fstride,\n         int in_stride,\n         opus_int16 * factors,\n         const kiss_fft_state *st\n            )\n{\n   const int p=*factors++; /* the radix  */\n   const int m=*factors++; /* stage's fft length/p */\n\n    /*printf (\"fft %d %d %d %d %d %d\\n\", p*m, m, p, s2, fstride*in_stride, N);*/\n   if (m==1)\n   {\n      int j;\n      for (j=0;j<p;j++)\n      {\n         *f = Fout+j;\n         f += fstride*in_stride;\n      }\n   } else {\n      int j;\n      for (j=0;j<p;j++)\n      {\n         compute_bitrev_table( Fout , f, fstride*p, in_stride, factors,st);\n         f += fstride*in_stride;\n         Fout += m;\n      }\n   }\n}\n\n/*  facbuf is populated by p1,m1,p2,m2, ...\n    where\n    p[i] * m[i] = m[i-1]\n    m0 = n                  */\nstatic\nint kf_factor(int n,opus_int16 * facbuf)\n{\n    int p=4;\n    int i;\n    int stages=0;\n    int nbak = n;\n\n    /*factor out powers of 4, powers of 2, then any remaining primes */\n    do {\n        while (n % p) {\n            switch (p) {\n                case 4: p = 2; break;\n                case 2: p = 3; break;\n                default: p += 2; break;\n            }\n            if (p>32000 || (opus_int32)p*(opus_int32)p > n)\n                p = n;          /* no more factors, skip to end */\n        }\n        n /= p;\n#ifdef RADIX_TWO_ONLY\n        if (p!=2 && p != 4)\n#else\n        if (p>5)\n#endif\n        {\n           return 0;\n        }\n        facbuf[2*stages] = p;\n        if (p==2 && stages > 1)\n        {\n           facbuf[2*stages] = 4;\n           facbuf[2] = 2;\n        }\n        stages++;\n    } while (n > 1);\n    n = nbak;\n    /* Reverse the order to get the radix 4 at the end, so we can use the\n       fast degenerate case. It turns out that reversing the order also\n       improves the noise behaviour. */\n    for (i=0;i<stages/2;i++)\n    {\n       int tmp;\n       tmp = facbuf[2*i];\n       facbuf[2*i] = facbuf[2*(stages-i-1)];\n       facbuf[2*(stages-i-1)] = tmp;\n    }\n    for (i=0;i<stages;i++)\n    {\n        n /= facbuf[2*i];\n        facbuf[2*i+1] = n;\n    }\n    return 1;\n}\n\nstatic void compute_twiddles(kiss_twiddle_cpx *twiddles, int nfft)\n{\n   int i;\n#ifdef FIXED_POINT\n   for (i=0;i<nfft;++i) {\n      opus_val32 phase = -i;\n      kf_cexp2(twiddles+i, DIV32(SHL32(phase,17),nfft));\n   }\n#else\n   for (i=0;i<nfft;++i) {\n      const double pi=3.14159265358979323846264338327;\n      double phase = ( -2*pi /nfft ) * i;\n      kf_cexp(twiddles+i, phase );\n   }\n#endif\n}\n\nint opus_fft_alloc_arch_c(kiss_fft_state *st) {\n   (void)st;\n   return 0;\n}\n\n/*\n *\n * Allocates all necessary storage space for the fft and ifft.\n * The return value is a contiguous block of memory.  As such,\n * It can be freed with free().\n * */\nkiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem,\n                                        const kiss_fft_state *base, int arch)\n{\n    kiss_fft_state *st=NULL;\n    size_t memneeded = sizeof(struct kiss_fft_state); /* twiddle factors*/\n\n    if ( lenmem==NULL ) {\n        st = ( kiss_fft_state*)KISS_FFT_MALLOC( memneeded );\n    }else{\n        if (mem != NULL && *lenmem >= memneeded)\n            st = (kiss_fft_state*)mem;\n        *lenmem = memneeded;\n    }\n    if (st) {\n        opus_int16 *bitrev;\n        kiss_twiddle_cpx *twiddles;\n\n        st->nfft=nfft;\n#ifdef FIXED_POINT\n        st->scale_shift = celt_ilog2(st->nfft);\n        if (st->nfft == 1<<st->scale_shift)\n           st->scale = Q15ONE;\n        else\n           st->scale = (1073741824+st->nfft/2)/st->nfft>>(15-st->scale_shift);\n#else\n        st->scale = 1.f/nfft;\n#endif\n        if (base != NULL)\n        {\n           st->twiddles = base->twiddles;\n           st->shift = 0;\n           while (st->shift < 32 && nfft<<st->shift != base->nfft)\n              st->shift++;\n           if (st->shift>=32)\n              goto fail;\n        } else {\n           st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft);\n           compute_twiddles(twiddles, nfft);\n           st->shift = -1;\n        }\n        if (!kf_factor(nfft,st->factors))\n        {\n           goto fail;\n        }\n\n        /* bitrev */\n        st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft);\n        if (st->bitrev==NULL)\n            goto fail;\n        compute_bitrev_table(0, bitrev, 1,1, st->factors,st);\n\n        /* Initialize architecture specific fft parameters */\n        if (opus_fft_alloc_arch(st, arch))\n            goto fail;\n    }\n    return st;\nfail:\n    opus_fft_free(st, arch);\n    return NULL;\n}\n\nkiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem, int arch)\n{\n   return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL, arch);\n}\n\nvoid opus_fft_free_arch_c(kiss_fft_state *st) {\n   (void)st;\n}\n\nvoid opus_fft_free(const kiss_fft_state *cfg, int arch)\n{\n   if (cfg)\n   {\n      opus_fft_free_arch((kiss_fft_state *)cfg, arch);\n      opus_free((opus_int16*)cfg->bitrev);\n      if (cfg->shift < 0)\n         opus_free((kiss_twiddle_cpx*)cfg->twiddles);\n      opus_free((kiss_fft_state*)cfg);\n   }\n}\n\n#endif /* CUSTOM_MODES */\n\nvoid opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout)\n{\n    int m2, m;\n    int p;\n    int L;\n    int fstride[MAXFACTORS];\n    int i;\n    int shift;\n\n    /* st->shift can be -1 */\n    shift = st->shift>0 ? st->shift : 0;\n\n    fstride[0] = 1;\n    L=0;\n    do {\n       p = st->factors[2*L];\n       m = st->factors[2*L+1];\n       fstride[L+1] = fstride[L]*p;\n       L++;\n    } while(m!=1);\n    m = st->factors[2*L-1];\n    for (i=L-1;i>=0;i--)\n    {\n       if (i!=0)\n          m2 = st->factors[2*i-1];\n       else\n          m2 = 1;\n       switch (st->factors[2*i])\n       {\n       case 2:\n          kf_bfly2(fout, m, fstride[i]);\n          break;\n       case 4:\n          kf_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2);\n          break;\n #ifndef RADIX_TWO_ONLY\n       case 3:\n          kf_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2);\n          break;\n       case 5:\n          kf_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2);\n          break;\n #endif\n       }\n       m = m2;\n    }\n}\n\nvoid opus_fft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)\n{\n   int i;\n   opus_val16 scale;\n#ifdef FIXED_POINT\n   /* Allows us to scale with MULT16_32_Q16(), which is faster than\n      MULT16_32_Q15() on ARM. */\n   int scale_shift = st->scale_shift-1;\n#endif\n   scale = st->scale;\n\n   celt_assert2 (fin != fout, \"In-place FFT not supported\");\n   /* Bit-reverse the input */\n   for (i=0;i<st->nfft;i++)\n   {\n      kiss_fft_cpx x = fin[i];\n      fout[st->bitrev[i]].r = SHR32(MULT16_32_Q16(scale, x.r), scale_shift);\n      fout[st->bitrev[i]].i = SHR32(MULT16_32_Q16(scale, x.i), scale_shift);\n   }\n   opus_fft_impl(st, fout);\n}\n\n\nvoid opus_ifft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)\n{\n   int i;\n   celt_assert2 (fin != fout, \"In-place FFT not supported\");\n   /* Bit-reverse the input */\n   for (i=0;i<st->nfft;i++)\n      fout[st->bitrev[i]] = fin[i];\n   for (i=0;i<st->nfft;i++)\n      fout[i].i = -fout[i].i;\n   opus_fft_impl(st, fout);\n   for (i=0;i<st->nfft;i++)\n      fout[i].i = -fout[i].i;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/kiss_fft.h",
    "content": "/*Copyright (c) 2003-2004, Mark Borgerding\n  Lots of modifications by Jean-Marc Valin\n  Copyright (c) 2005-2007, Xiph.Org Foundation\n  Copyright (c) 2008,      Xiph.Org Foundation, CSIRO\n\n  All rights reserved.\n\n  Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n       this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright notice,\n       this list of conditions and the following disclaimer in the\n       documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n  POSSIBILITY OF SUCH DAMAGE.*/\n\n#ifndef KISS_FFT_H\n#define KISS_FFT_H\n\n#include <stdlib.h>\n#include <math.h>\n#include \"arch.h\"\n#include \"cpu_support.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifdef USE_SIMD\n# include <xmmintrin.h>\n# define kiss_fft_scalar __m128\n#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes)\n#else\n#define KISS_FFT_MALLOC opus_alloc\n#endif\n\n#ifdef FIXED_POINT\n#include \"arch.h\"\n\n#  define kiss_fft_scalar opus_int32\n#  define kiss_twiddle_scalar opus_int16\n\n\n#else\n# ifndef kiss_fft_scalar\n/*  default is float */\n#   define kiss_fft_scalar float\n#   define kiss_twiddle_scalar float\n#   define KF_SUFFIX _celt_single\n# endif\n#endif\n\ntypedef struct {\n    kiss_fft_scalar r;\n    kiss_fft_scalar i;\n}kiss_fft_cpx;\n\ntypedef struct {\n   kiss_twiddle_scalar r;\n   kiss_twiddle_scalar i;\n}kiss_twiddle_cpx;\n\n#define MAXFACTORS 8\n/* e.g. an fft of length 128 has 4 factors\n as far as kissfft is concerned\n 4*4*4*2\n */\n\ntypedef struct arch_fft_state{\n   int is_supported;\n   void *priv;\n} arch_fft_state;\n\ntypedef struct kiss_fft_state{\n    int nfft;\n    opus_val16 scale;\n#ifdef FIXED_POINT\n    int scale_shift;\n#endif\n    int shift;\n    opus_int16 factors[2*MAXFACTORS];\n    const opus_int16 *bitrev;\n    const kiss_twiddle_cpx *twiddles;\n    arch_fft_state *arch_fft;\n} kiss_fft_state;\n\n#if defined(HAVE_ARM_NE10)\n#include \"arm/fft_arm.h\"\n#endif\n\n/*typedef struct kiss_fft_state* kiss_fft_cfg;*/\n\n/**\n *  opus_fft_alloc\n *\n *  Initialize a FFT (or IFFT) algorithm's cfg/state buffer.\n *\n *  typical usage:      kiss_fft_cfg mycfg=opus_fft_alloc(1024,0,NULL,NULL);\n *\n *  The return value from fft_alloc is a cfg buffer used internally\n *  by the fft routine or NULL.\n *\n *  If lenmem is NULL, then opus_fft_alloc will allocate a cfg buffer using malloc.\n *  The returned value should be free()d when done to avoid memory leaks.\n *\n *  The state can be placed in a user supplied buffer 'mem':\n *  If lenmem is not NULL and mem is not NULL and *lenmem is large enough,\n *      then the function places the cfg in mem and the size used in *lenmem\n *      and returns mem.\n *\n *  If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),\n *      then the function returns NULL and places the minimum cfg\n *      buffer size in *lenmem.\n * */\n\nkiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base, int arch);\n\nkiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem, int arch);\n\n/**\n * opus_fft(cfg,in_out_buf)\n *\n * Perform an FFT on a complex input buffer.\n * for a forward FFT,\n * fin should be  f[0] , f[1] , ... ,f[nfft-1]\n * fout will be   F[0] , F[1] , ... ,F[nfft-1]\n * Note that each element is complex and can be accessed like\n    f[k].r and f[k].i\n * */\nvoid opus_fft_c(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);\nvoid opus_ifft_c(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);\n\nvoid opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout);\nvoid opus_ifft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout);\n\nvoid opus_fft_free(const kiss_fft_state *cfg, int arch);\n\n\nvoid opus_fft_free_arch_c(kiss_fft_state *st);\nint opus_fft_alloc_arch_c(kiss_fft_state *st);\n\n#if !defined(OVERRIDE_OPUS_FFT)\n/* Is run-time CPU detection enabled on this platform? */\n#if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10))\n\nextern int (*const OPUS_FFT_ALLOC_ARCH_IMPL[OPUS_ARCHMASK+1])(\n kiss_fft_state *st);\n\n#define opus_fft_alloc_arch(_st, arch) \\\n         ((*OPUS_FFT_ALLOC_ARCH_IMPL[(arch)&OPUS_ARCHMASK])(_st))\n\nextern void (*const OPUS_FFT_FREE_ARCH_IMPL[OPUS_ARCHMASK+1])(\n kiss_fft_state *st);\n#define opus_fft_free_arch(_st, arch) \\\n         ((*OPUS_FFT_FREE_ARCH_IMPL[(arch)&OPUS_ARCHMASK])(_st))\n\nextern void (*const OPUS_FFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,\n const kiss_fft_cpx *fin, kiss_fft_cpx *fout);\n#define opus_fft(_cfg, _fin, _fout, arch) \\\n   ((*OPUS_FFT[(arch)&OPUS_ARCHMASK])(_cfg, _fin, _fout))\n\nextern void (*const OPUS_IFFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,\n const kiss_fft_cpx *fin, kiss_fft_cpx *fout);\n#define opus_ifft(_cfg, _fin, _fout, arch) \\\n   ((*OPUS_IFFT[(arch)&OPUS_ARCHMASK])(_cfg, _fin, _fout))\n\n#else /* else for if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10)) */\n\n#define opus_fft_alloc_arch(_st, arch) \\\n         ((void)(arch), opus_fft_alloc_arch_c(_st))\n\n#define opus_fft_free_arch(_st, arch) \\\n         ((void)(arch), opus_fft_free_arch_c(_st))\n\n#define opus_fft(_cfg, _fin, _fout, arch) \\\n         ((void)(arch), opus_fft_c(_cfg, _fin, _fout))\n\n#define opus_ifft(_cfg, _fin, _fout, arch) \\\n         ((void)(arch), opus_ifft_c(_cfg, _fin, _fout))\n\n#endif /* end if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10)) */\n#endif /* end if !defined(OVERRIDE_OPUS_FFT) */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/laplace.c",
    "content": "/* Copyright (c) 2007 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"laplace.h\"\n#include \"mathops.h\"\n\n/* The minimum probability of an energy delta (out of 32768). */\n#define LAPLACE_LOG_MINP (0)\n#define LAPLACE_MINP (1<<LAPLACE_LOG_MINP)\n/* The minimum number of guaranteed representable energy deltas (in one\n    direction). */\n#define LAPLACE_NMIN (16)\n\n/* When called, decay is positive and at most 11456. */\nstatic unsigned ec_laplace_get_freq1(unsigned fs0, int decay)\n{\n   unsigned ft;\n   ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN) - fs0;\n   return ft*(opus_int32)(16384-decay)>>15;\n}\n\nvoid ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay)\n{\n   unsigned fl;\n   int val = *value;\n   fl = 0;\n   if (val)\n   {\n      int s;\n      int i;\n      s = -(val<0);\n      val = (val+s)^s;\n      fl = fs;\n      fs = ec_laplace_get_freq1(fs, decay);\n      /* Search the decaying part of the PDF.*/\n      for (i=1; fs > 0 && i < val; i++)\n      {\n         fs *= 2;\n         fl += fs+2*LAPLACE_MINP;\n         fs = (fs*(opus_int32)decay)>>15;\n      }\n      /* Everything beyond that has probability LAPLACE_MINP. */\n      if (!fs)\n      {\n         int di;\n         int ndi_max;\n         ndi_max = (32768-fl+LAPLACE_MINP-1)>>LAPLACE_LOG_MINP;\n         ndi_max = (ndi_max-s)>>1;\n         di = IMIN(val - i, ndi_max - 1);\n         fl += (2*di+1+s)*LAPLACE_MINP;\n         fs = IMIN(LAPLACE_MINP, 32768-fl);\n         *value = (i+di+s)^s;\n      }\n      else\n      {\n         fs += LAPLACE_MINP;\n         fl += fs&~s;\n      }\n      celt_assert(fl+fs<=32768);\n      celt_assert(fs>0);\n   }\n   ec_encode_bin(enc, fl, fl+fs, 15);\n}\n\nint ec_laplace_decode(ec_dec *dec, unsigned fs, int decay)\n{\n   int val=0;\n   unsigned fl;\n   unsigned fm;\n   fm = ec_decode_bin(dec, 15);\n   fl = 0;\n   if (fm >= fs)\n   {\n      val++;\n      fl = fs;\n      fs = ec_laplace_get_freq1(fs, decay)+LAPLACE_MINP;\n      /* Search the decaying part of the PDF.*/\n      while(fs > LAPLACE_MINP && fm >= fl+2*fs)\n      {\n         fs *= 2;\n         fl += fs;\n         fs = ((fs-2*LAPLACE_MINP)*(opus_int32)decay)>>15;\n         fs += LAPLACE_MINP;\n         val++;\n      }\n      /* Everything beyond that has probability LAPLACE_MINP. */\n      if (fs <= LAPLACE_MINP)\n      {\n         int di;\n         di = (fm-fl)>>(LAPLACE_LOG_MINP+1);\n         val += di;\n         fl += 2*di*LAPLACE_MINP;\n      }\n      if (fm < fl+fs)\n         val = -val;\n      else\n         fl += fs;\n   }\n   celt_assert(fl<32768);\n   celt_assert(fs>0);\n   celt_assert(fl<=fm);\n   celt_assert(fm<IMIN(fl+fs,32768));\n   ec_dec_update(dec, fl, IMIN(fl+fs,32768), 32768);\n   return val;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/laplace.h",
    "content": "/* Copyright (c) 2007 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#include \"entenc.h\"\n#include \"entdec.h\"\n\n/** Encode a value that is assumed to be the realisation of a\n    Laplace-distributed random process\n @param enc Entropy encoder state\n @param value Value to encode\n @param fs Probability of 0, multiplied by 32768\n @param decay Probability of the value +/- 1, multiplied by 16384\n*/\nvoid ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay);\n\n/** Decode a value that is assumed to be the realisation of a\n    Laplace-distributed random process\n @param dec Entropy decoder state\n @param fs Probability of 0, multiplied by 32768\n @param decay Probability of the value +/- 1, multiplied by 16384\n @return Value decoded\n */\nint ec_laplace_decode(ec_dec *dec, unsigned fs, int decay);\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/mathops.c",
    "content": "/* Copyright (c) 2002-2008 Jean-Marc Valin\n   Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/**\n   @file mathops.h\n   @brief Various math functions\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"mathops.h\"\n\n/*Compute floor(sqrt(_val)) with exact arithmetic.\n  This has been tested on all possible 32-bit inputs.*/\nunsigned isqrt32(opus_uint32 _val){\n  unsigned b;\n  unsigned g;\n  int      bshift;\n  /*Uses the second method from\n     http://www.azillionmonkeys.com/qed/sqroot.html\n    The main idea is to search for the largest binary digit b such that\n     (g+b)*(g+b) <= _val, and add it to the solution g.*/\n  g=0;\n  bshift=(EC_ILOG(_val)-1)>>1;\n  b=1U<<bshift;\n  do{\n    opus_uint32 t;\n    t=(((opus_uint32)g<<1)+b)<<bshift;\n    if(t<=_val){\n      g+=b;\n      _val-=t;\n    }\n    b>>=1;\n    bshift--;\n  }\n  while(bshift>=0);\n  return g;\n}\n\n#ifdef FIXED_POINT\n\nopus_val32 frac_div32(opus_val32 a, opus_val32 b)\n{\n   opus_val16 rcp;\n   opus_val32 result, rem;\n   int shift = celt_ilog2(b)-29;\n   a = VSHR32(a,shift);\n   b = VSHR32(b,shift);\n   /* 16-bit reciprocal */\n   rcp = ROUND16(celt_rcp(ROUND16(b,16)),3);\n   result = MULT16_32_Q15(rcp, a);\n   rem = PSHR32(a,2)-MULT32_32_Q31(result, b);\n   result = ADD32(result, SHL32(MULT16_32_Q15(rcp, rem),2));\n   if (result >= 536870912)       /*  2^29 */\n      return 2147483647;          /*  2^31 - 1 */\n   else if (result <= -536870912) /* -2^29 */\n      return -2147483647;         /* -2^31 */\n   else\n      return SHL32(result, 2);\n}\n\n/** Reciprocal sqrt approximation in the range [0.25,1) (Q16 in, Q14 out) */\nopus_val16 celt_rsqrt_norm(opus_val32 x)\n{\n   opus_val16 n;\n   opus_val16 r;\n   opus_val16 r2;\n   opus_val16 y;\n   /* Range of n is [-16384,32767] ([-0.5,1) in Q15). */\n   n = x-32768;\n   /* Get a rough initial guess for the root.\n      The optimal minimax quadratic approximation (using relative error) is\n       r = 1.437799046117536+n*(-0.823394375837328+n*0.4096419668459485).\n      Coefficients here, and the final result r, are Q14.*/\n   r = ADD16(23557, MULT16_16_Q15(n, ADD16(-13490, MULT16_16_Q15(n, 6713))));\n   /* We want y = x*r*r-1 in Q15, but x is 32-bit Q16 and r is Q14.\n      We can compute the result from n and r using Q15 multiplies with some\n       adjustment, carefully done to avoid overflow.\n      Range of y is [-1564,1594]. */\n   r2 = MULT16_16_Q15(r, r);\n   y = SHL16(SUB16(ADD16(MULT16_16_Q15(r2, n), r2), 16384), 1);\n   /* Apply a 2nd-order Householder iteration: r += r*y*(y*0.375-0.5).\n      This yields the Q14 reciprocal square root of the Q16 x, with a maximum\n       relative error of 1.04956E-4, a (relative) RMSE of 2.80979E-5, and a\n       peak absolute error of 2.26591/16384. */\n   return ADD16(r, MULT16_16_Q15(r, MULT16_16_Q15(y,\n              SUB16(MULT16_16_Q15(y, 12288), 16384))));\n}\n\n/** Sqrt approximation (QX input, QX/2 output) */\nopus_val32 celt_sqrt(opus_val32 x)\n{\n   int k;\n   opus_val16 n;\n   opus_val32 rt;\n   static const opus_val16 C[5] = {23175, 11561, -3011, 1699, -664};\n   if (x==0)\n      return 0;\n   else if (x>=1073741824)\n      return 32767;\n   k = (celt_ilog2(x)>>1)-7;\n   x = VSHR32(x, 2*k);\n   n = x-32768;\n   rt = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2],\n              MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, (C[4])))))))));\n   rt = VSHR32(rt,7-k);\n   return rt;\n}\n\n#define L1 32767\n#define L2 -7651\n#define L3 8277\n#define L4 -626\n\nstatic OPUS_INLINE opus_val16 _celt_cos_pi_2(opus_val16 x)\n{\n   opus_val16 x2;\n\n   x2 = MULT16_16_P15(x,x);\n   return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2\n                                                                                ))))))));\n}\n\n#undef L1\n#undef L2\n#undef L3\n#undef L4\n\nopus_val16 celt_cos_norm(opus_val32 x)\n{\n   x = x&0x0001ffff;\n   if (x>SHL32(EXTEND32(1), 16))\n      x = SUB32(SHL32(EXTEND32(1), 17),x);\n   if (x&0x00007fff)\n   {\n      if (x<SHL32(EXTEND32(1), 15))\n      {\n         return _celt_cos_pi_2(EXTRACT16(x));\n      } else {\n         return NEG32(_celt_cos_pi_2(EXTRACT16(65536-x)));\n      }\n   } else {\n      if (x&0x0000ffff)\n         return 0;\n      else if (x&0x0001ffff)\n         return -32767;\n      else\n         return 32767;\n   }\n}\n\n/** Reciprocal approximation (Q15 input, Q16 output) */\nopus_val32 celt_rcp(opus_val32 x)\n{\n   int i;\n   opus_val16 n;\n   opus_val16 r;\n   celt_assert2(x>0, \"celt_rcp() only defined for positive values\");\n   i = celt_ilog2(x);\n   /* n is Q15 with range [0,1). */\n   n = VSHR32(x,i-15)-32768;\n   /* Start with a linear approximation:\n      r = 1.8823529411764706-0.9411764705882353*n.\n      The coefficients and the result are Q14 in the range [15420,30840].*/\n   r = ADD16(30840, MULT16_16_Q15(-15420, n));\n   /* Perform two Newton iterations:\n      r -= r*((r*n)-1.Q15)\n         = r*((r*n)+(r-1.Q15)). */\n   r = SUB16(r, MULT16_16_Q15(r,\n             ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768))));\n   /* We subtract an extra 1 in the second iteration to avoid overflow; it also\n       neatly compensates for truncation error in the rest of the process. */\n   r = SUB16(r, ADD16(1, MULT16_16_Q15(r,\n             ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768)))));\n   /* r is now the Q15 solution to 2/(n+1), with a maximum relative error\n       of 7.05346E-5, a (relative) RMSE of 2.14418E-5, and a peak absolute\n       error of 1.24665/32768. */\n   return VSHR32(EXTEND32(r),i-16);\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/mathops.h",
    "content": "/* Copyright (c) 2002-2008 Jean-Marc Valin\n   Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/**\n   @file mathops.h\n   @brief Various math functions\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef MATHOPS_H\n#define MATHOPS_H\n\n#include \"arch.h\"\n#include \"entcode.h\"\n#include \"os_support.h\"\n\n/* Multiplies two 16-bit fractional values. Bit-exactness of this macro is important */\n#define FRAC_MUL16(a,b) ((16384+((opus_int32)(opus_int16)(a)*(opus_int16)(b)))>>15)\n\nunsigned isqrt32(opus_uint32 _val);\n\n#ifndef OVERRIDE_CELT_MAXABS16\nstatic OPUS_INLINE opus_val32 celt_maxabs16(const opus_val16 *x, int len)\n{\n   int i;\n   opus_val16 maxval = 0;\n   opus_val16 minval = 0;\n   for (i=0;i<len;i++)\n   {\n      maxval = MAX16(maxval, x[i]);\n      minval = MIN16(minval, x[i]);\n   }\n   return MAX32(EXTEND32(maxval),-EXTEND32(minval));\n}\n#endif\n\n#ifndef OVERRIDE_CELT_MAXABS32\n#ifdef FIXED_POINT\nstatic OPUS_INLINE opus_val32 celt_maxabs32(const opus_val32 *x, int len)\n{\n   int i;\n   opus_val32 maxval = 0;\n   opus_val32 minval = 0;\n   for (i=0;i<len;i++)\n   {\n      maxval = MAX32(maxval, x[i]);\n      minval = MIN32(minval, x[i]);\n   }\n   return MAX32(maxval, -minval);\n}\n#else\n#define celt_maxabs32(x,len) celt_maxabs16(x,len)\n#endif\n#endif\n\n\n#ifndef FIXED_POINT\n\n#define PI 3.141592653f\n#define celt_sqrt(x) ((float)sqrt(x))\n#define celt_rsqrt(x) (1.f/celt_sqrt(x))\n#define celt_rsqrt_norm(x) (celt_rsqrt(x))\n#define celt_cos_norm(x) ((float)cos((.5f*PI)*(x)))\n#define celt_rcp(x) (1.f/(x))\n#define celt_div(a,b) ((a)/(b))\n#define frac_div32(a,b) ((float)(a)/(b))\n\n#ifdef FLOAT_APPROX\n\n/* Note: This assumes radix-2 floating point with the exponent at bits 23..30 and an offset of 127\n         denorm, +/- inf and NaN are *not* handled */\n\n/** Base-2 log approximation (log2(x)). */\nstatic OPUS_INLINE float celt_log2(float x)\n{\n   int integer;\n   float frac;\n   union {\n      float f;\n      opus_uint32 i;\n   } in;\n   in.f = x;\n   integer = (in.i>>23)-127;\n   in.i -= integer<<23;\n   frac = in.f - 1.5f;\n   frac = -0.41445418f + frac*(0.95909232f\n          + frac*(-0.33951290f + frac*0.16541097f));\n   return 1+integer+frac;\n}\n\n/** Base-2 exponential approximation (2^x). */\nstatic OPUS_INLINE float celt_exp2(float x)\n{\n   int integer;\n   float frac;\n   union {\n      float f;\n      opus_uint32 i;\n   } res;\n   integer = floor(x);\n   if (integer < -50)\n      return 0;\n   frac = x-integer;\n   /* K0 = 1, K1 = log(2), K2 = 3-4*log(2), K3 = 3*log(2) - 2 */\n   res.f = 0.99992522f + frac * (0.69583354f\n           + frac * (0.22606716f + 0.078024523f*frac));\n   res.i = (res.i + (integer<<23)) & 0x7fffffff;\n   return res.f;\n}\n\n#else\n#define celt_log2(x) ((float)(1.442695040888963387*log(x)))\n#define celt_exp2(x) ((float)exp(0.6931471805599453094*(x)))\n#endif\n\n#endif\n\n#ifdef FIXED_POINT\n\n#include \"os_support.h\"\n\n#ifndef OVERRIDE_CELT_ILOG2\n/** Integer log in base2. Undefined for zero and negative numbers */\nstatic OPUS_INLINE opus_int16 celt_ilog2(opus_int32 x)\n{\n   celt_assert2(x>0, \"celt_ilog2() only defined for strictly positive numbers\");\n   return EC_ILOG(x)-1;\n}\n#endif\n\n\n/** Integer log in base2. Defined for zero, but not for negative numbers */\nstatic OPUS_INLINE opus_int16 celt_zlog2(opus_val32 x)\n{\n   return x <= 0 ? 0 : celt_ilog2(x);\n}\n\nopus_val16 celt_rsqrt_norm(opus_val32 x);\n\nopus_val32 celt_sqrt(opus_val32 x);\n\nopus_val16 celt_cos_norm(opus_val32 x);\n\n/** Base-2 logarithm approximation (log2(x)). (Q14 input, Q10 output) */\nstatic OPUS_INLINE opus_val16 celt_log2(opus_val32 x)\n{\n   int i;\n   opus_val16 n, frac;\n   /* -0.41509302963303146, 0.9609890551383969, -0.31836011537636605,\n       0.15530808010959576, -0.08556153059057618 */\n   static const opus_val16 C[5] = {-6801+(1<<(13-DB_SHIFT)), 15746, -5217, 2545, -1401};\n   if (x==0)\n      return -32767;\n   i = celt_ilog2(x);\n   n = VSHR32(x,i-15)-32768-16384;\n   frac = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2], MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, C[4]))))))));\n   return SHL16(i-13,DB_SHIFT)+SHR16(frac,14-DB_SHIFT);\n}\n\n/*\n K0 = 1\n K1 = log(2)\n K2 = 3-4*log(2)\n K3 = 3*log(2) - 2\n*/\n#define D0 16383\n#define D1 22804\n#define D2 14819\n#define D3 10204\n\nstatic OPUS_INLINE opus_val32 celt_exp2_frac(opus_val16 x)\n{\n   opus_val16 frac;\n   frac = SHL16(x, 4);\n   return ADD16(D0, MULT16_16_Q15(frac, ADD16(D1, MULT16_16_Q15(frac, ADD16(D2 , MULT16_16_Q15(D3,frac))))));\n}\n/** Base-2 exponential approximation (2^x). (Q10 input, Q16 output) */\nstatic OPUS_INLINE opus_val32 celt_exp2(opus_val16 x)\n{\n   int integer;\n   opus_val16 frac;\n   integer = SHR16(x,10);\n   if (integer>14)\n      return 0x7f000000;\n   else if (integer < -15)\n      return 0;\n   frac = celt_exp2_frac(x-SHL16(integer,10));\n   return VSHR32(EXTEND32(frac), -integer-2);\n}\n\nopus_val32 celt_rcp(opus_val32 x);\n\n#define celt_div(a,b) MULT32_32_Q31((opus_val32)(a),celt_rcp(b))\n\nopus_val32 frac_div32(opus_val32 a, opus_val32 b);\n\n#define M1 32767\n#define M2 -21\n#define M3 -11943\n#define M4 4936\n\n/* Atan approximation using a 4th order polynomial. Input is in Q15 format\n   and normalized by pi/4. Output is in Q15 format */\nstatic OPUS_INLINE opus_val16 celt_atan01(opus_val16 x)\n{\n   return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));\n}\n\n#undef M1\n#undef M2\n#undef M3\n#undef M4\n\n/* atan2() approximation valid for positive input values */\nstatic OPUS_INLINE opus_val16 celt_atan2p(opus_val16 y, opus_val16 x)\n{\n   if (y < x)\n   {\n      opus_val32 arg;\n      arg = celt_div(SHL32(EXTEND32(y),15),x);\n      if (arg >= 32767)\n         arg = 32767;\n      return SHR16(celt_atan01(EXTRACT16(arg)),1);\n   } else {\n      opus_val32 arg;\n      arg = celt_div(SHL32(EXTEND32(x),15),y);\n      if (arg >= 32767)\n         arg = 32767;\n      return 25736-SHR16(celt_atan01(EXTRACT16(arg)),1);\n   }\n}\n\n#endif /* FIXED_POINT */\n#endif /* MATHOPS_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/mdct.c",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2008 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/* This is a simple MDCT implementation that uses a N/4 complex FFT\n   to do most of the work. It should be relatively straightforward to\n   plug in pretty much and FFT here.\n\n   This replaces the Vorbis FFT (and uses the exact same API), which\n   was a bit too messy and that was ending up duplicating code\n   (might as well use the same FFT everywhere).\n\n   The algorithm is similar to (and inspired from) Fabrice Bellard's\n   MDCT implementation in FFMPEG, but has differences in signs, ordering\n   and scaling in many places.\n*/\n\n#ifndef SKIP_CONFIG_H\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#endif\n\n#include \"mdct.h\"\n#include \"kiss_fft.h\"\n#include \"_kiss_fft_guts.h\"\n#include <math.h>\n#include \"os_support.h\"\n#include \"mathops.h\"\n#include \"stack_alloc.h\"\n\n#if defined(MIPSr1_ASM)\n#include \"mips/mdct_mipsr1.h\"\n#endif\n\n\n#ifdef CUSTOM_MODES\n\nint clt_mdct_init(mdct_lookup *l,int N, int maxshift, int arch)\n{\n   int i;\n   kiss_twiddle_scalar *trig;\n   int shift;\n   int N2=N>>1;\n   l->n = N;\n   l->maxshift = maxshift;\n   for (i=0;i<=maxshift;i++)\n   {\n      if (i==0)\n         l->kfft[i] = opus_fft_alloc(N>>2>>i, 0, 0, arch);\n      else\n         l->kfft[i] = opus_fft_alloc_twiddles(N>>2>>i, 0, 0, l->kfft[0], arch);\n#ifndef ENABLE_TI_DSPLIB55\n      if (l->kfft[i]==NULL)\n         return 0;\n#endif\n   }\n   l->trig = trig = (kiss_twiddle_scalar*)opus_alloc((N-(N2>>maxshift))*sizeof(kiss_twiddle_scalar));\n   if (l->trig==NULL)\n     return 0;\n   for (shift=0;shift<=maxshift;shift++)\n   {\n      /* We have enough points that sine isn't necessary */\n#if defined(FIXED_POINT)\n#if 1\n      for (i=0;i<N2;i++)\n         trig[i] = TRIG_UPSCALE*celt_cos_norm(DIV32(ADD32(SHL32(EXTEND32(i),17),N2+16384),N));\n#else\n      for (i=0;i<N2;i++)\n         trig[i] = (kiss_twiddle_scalar)MAX32(-32767,MIN32(32767,floor(.5+32768*cos(2*M_PI*(i+.125)/N))));\n#endif\n#else\n      for (i=0;i<N2;i++)\n         trig[i] = (kiss_twiddle_scalar)cos(2*PI*(i+.125)/N);\n#endif\n      trig += N2;\n      N2 >>= 1;\n      N >>= 1;\n   }\n   return 1;\n}\n\nvoid clt_mdct_clear(mdct_lookup *l, int arch)\n{\n   int i;\n   for (i=0;i<=l->maxshift;i++)\n      opus_fft_free(l->kfft[i], arch);\n   opus_free((kiss_twiddle_scalar*)l->trig);\n}\n\n#endif /* CUSTOM_MODES */\n\n/* Forward MDCT trashes the input array */\n#ifndef OVERRIDE_clt_mdct_forward\nvoid clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,\n      const opus_val16 *window, int overlap, int shift, int stride, int arch)\n{\n   int i;\n   int N, N2, N4;\n   VARDECL(kiss_fft_scalar, f);\n   VARDECL(kiss_fft_cpx, f2);\n   const kiss_fft_state *st = l->kfft[shift];\n   const kiss_twiddle_scalar *trig;\n   opus_val16 scale;\n#ifdef FIXED_POINT\n   /* Allows us to scale with MULT16_32_Q16(), which is faster than\n      MULT16_32_Q15() on ARM. */\n   int scale_shift = st->scale_shift-1;\n#endif\n   SAVE_STACK;\n   (void)arch;\n   scale = st->scale;\n\n   N = l->n;\n   trig = l->trig;\n   for (i=0;i<shift;i++)\n   {\n      N >>= 1;\n      trig += N;\n   }\n   N2 = N>>1;\n   N4 = N>>2;\n\n   ALLOC(f, N2, kiss_fft_scalar);\n   ALLOC(f2, N4, kiss_fft_cpx);\n\n   /* Consider the input to be composed of four blocks: [a, b, c, d] */\n   /* Window, shuffle, fold */\n   {\n      /* Temp pointers to make it really clear to the compiler what we're doing */\n      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);\n      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);\n      kiss_fft_scalar * OPUS_RESTRICT yp = f;\n      const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);\n      const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;\n      for(i=0;i<((overlap+3)>>2);i++)\n      {\n         /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/\n         *yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2);\n         *yp++ = MULT16_32_Q15(*wp1, *xp1)    - MULT16_32_Q15(*wp2, xp2[-N2]);\n         xp1+=2;\n         xp2-=2;\n         wp1+=2;\n         wp2-=2;\n      }\n      wp1 = window;\n      wp2 = window+overlap-1;\n      for(;i<N4-((overlap+3)>>2);i++)\n      {\n         /* Real part arranged as a-bR, Imag part arranged as -c-dR */\n         *yp++ = *xp2;\n         *yp++ = *xp1;\n         xp1+=2;\n         xp2-=2;\n      }\n      for(;i<N4;i++)\n      {\n         /* Real part arranged as a-bR, Imag part arranged as -c-dR */\n         *yp++ =  -MULT16_32_Q15(*wp1, xp1[-N2]) + MULT16_32_Q15(*wp2, *xp2);\n         *yp++ = MULT16_32_Q15(*wp2, *xp1)     + MULT16_32_Q15(*wp1, xp2[N2]);\n         xp1+=2;\n         xp2-=2;\n         wp1+=2;\n         wp2-=2;\n      }\n   }\n   /* Pre-rotation */\n   {\n      kiss_fft_scalar * OPUS_RESTRICT yp = f;\n      const kiss_twiddle_scalar *t = &trig[0];\n      for(i=0;i<N4;i++)\n      {\n         kiss_fft_cpx yc;\n         kiss_twiddle_scalar t0, t1;\n         kiss_fft_scalar re, im, yr, yi;\n         t0 = t[i];\n         t1 = t[N4+i];\n         re = *yp++;\n         im = *yp++;\n         yr = S_MUL(re,t0)  -  S_MUL(im,t1);\n         yi = S_MUL(im,t0)  +  S_MUL(re,t1);\n         yc.r = yr;\n         yc.i = yi;\n         yc.r = PSHR32(MULT16_32_Q16(scale, yc.r), scale_shift);\n         yc.i = PSHR32(MULT16_32_Q16(scale, yc.i), scale_shift);\n         f2[st->bitrev[i]] = yc;\n      }\n   }\n\n   /* N/4 complex FFT, does not downscale anymore */\n   opus_fft_impl(st, f2);\n\n   /* Post-rotate */\n   {\n      /* Temp pointers to make it really clear to the compiler what we're doing */\n      const kiss_fft_cpx * OPUS_RESTRICT fp = f2;\n      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;\n      kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);\n      const kiss_twiddle_scalar *t = &trig[0];\n      /* Temp pointers to make it really clear to the compiler what we're doing */\n      for(i=0;i<N4;i++)\n      {\n         kiss_fft_scalar yr, yi;\n         yr = S_MUL(fp->i,t[N4+i]) - S_MUL(fp->r,t[i]);\n         yi = S_MUL(fp->r,t[N4+i]) + S_MUL(fp->i,t[i]);\n         *yp1 = yr;\n         *yp2 = yi;\n         fp++;\n         yp1 += 2*stride;\n         yp2 -= 2*stride;\n      }\n   }\n   RESTORE_STACK;\n}\n#endif /* OVERRIDE_clt_mdct_forward */\n\n#ifndef OVERRIDE_clt_mdct_backward\nvoid clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,\n      const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch)\n{\n   int i;\n   int N, N2, N4;\n   const kiss_twiddle_scalar *trig;\n   (void) arch;\n\n   N = l->n;\n   trig = l->trig;\n   for (i=0;i<shift;i++)\n   {\n      N >>= 1;\n      trig += N;\n   }\n   N2 = N>>1;\n   N4 = N>>2;\n\n   /* Pre-rotate */\n   {\n      /* Temp pointers to make it really clear to the compiler what we're doing */\n      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;\n      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);\n      kiss_fft_scalar * OPUS_RESTRICT yp = out+(overlap>>1);\n      const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0];\n      const opus_int16 * OPUS_RESTRICT bitrev = l->kfft[shift]->bitrev;\n      for(i=0;i<N4;i++)\n      {\n         int rev;\n         kiss_fft_scalar yr, yi;\n         rev = *bitrev++;\n         yr = S_MUL(*xp2, t[i]) + S_MUL(*xp1, t[N4+i]);\n         yi = S_MUL(*xp1, t[i]) - S_MUL(*xp2, t[N4+i]);\n         /* We swap real and imag because we use an FFT instead of an IFFT. */\n         yp[2*rev+1] = yr;\n         yp[2*rev] = yi;\n         /* Storing the pre-rotation directly in the bitrev order. */\n         xp1+=2*stride;\n         xp2-=2*stride;\n      }\n   }\n\n   opus_fft_impl(l->kfft[shift], (kiss_fft_cpx*)(out+(overlap>>1)));\n\n   /* Post-rotate and de-shuffle from both ends of the buffer at once to make\n      it in-place. */\n   {\n      kiss_fft_scalar * yp0 = out+(overlap>>1);\n      kiss_fft_scalar * yp1 = out+(overlap>>1)+N2-2;\n      const kiss_twiddle_scalar *t = &trig[0];\n      /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the\n         middle pair will be computed twice. */\n      for(i=0;i<(N4+1)>>1;i++)\n      {\n         kiss_fft_scalar re, im, yr, yi;\n         kiss_twiddle_scalar t0, t1;\n         /* We swap real and imag because we're using an FFT instead of an IFFT. */\n         re = yp0[1];\n         im = yp0[0];\n         t0 = t[i];\n         t1 = t[N4+i];\n         /* We'd scale up by 2 here, but instead it's done when mixing the windows */\n         yr = S_MUL(re,t0) + S_MUL(im,t1);\n         yi = S_MUL(re,t1) - S_MUL(im,t0);\n         /* We swap real and imag because we're using an FFT instead of an IFFT. */\n         re = yp1[1];\n         im = yp1[0];\n         yp0[0] = yr;\n         yp1[1] = yi;\n\n         t0 = t[(N4-i-1)];\n         t1 = t[(N2-i-1)];\n         /* We'd scale up by 2 here, but instead it's done when mixing the windows */\n         yr = S_MUL(re,t0) + S_MUL(im,t1);\n         yi = S_MUL(re,t1) - S_MUL(im,t0);\n         yp1[0] = yr;\n         yp0[1] = yi;\n         yp0 += 2;\n         yp1 -= 2;\n      }\n   }\n\n   /* Mirror on both sides for TDAC */\n   {\n      kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;\n      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;\n      const opus_val16 * OPUS_RESTRICT wp1 = window;\n      const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;\n\n      for(i = 0; i < overlap/2; i++)\n      {\n         kiss_fft_scalar x1, x2;\n         x1 = *xp1;\n         x2 = *yp1;\n         *yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1);\n         *xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1);\n         wp1++;\n         wp2--;\n      }\n   }\n}\n#endif /* OVERRIDE_clt_mdct_backward */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/mdct.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2008 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/* This is a simple MDCT implementation that uses a N/4 complex FFT\n   to do most of the work. It should be relatively straightforward to\n   plug in pretty much and FFT here.\n\n   This replaces the Vorbis FFT (and uses the exact same API), which\n   was a bit too messy and that was ending up duplicating code\n   (might as well use the same FFT everywhere).\n\n   The algorithm is similar to (and inspired from) Fabrice Bellard's\n   MDCT implementation in FFMPEG, but has differences in signs, ordering\n   and scaling in many places.\n*/\n\n#ifndef MDCT_H\n#define MDCT_H\n\n#include \"opus_defines.h\"\n#include \"kiss_fft.h\"\n#include \"arch.h\"\n\ntypedef struct {\n   int n;\n   int maxshift;\n   const kiss_fft_state *kfft[4];\n   const kiss_twiddle_scalar * OPUS_RESTRICT trig;\n} mdct_lookup;\n\n#if defined(HAVE_ARM_NE10)\n#include \"arm/mdct_arm.h\"\n#endif\n\n\nint clt_mdct_init(mdct_lookup *l,int N, int maxshift, int arch);\nvoid clt_mdct_clear(mdct_lookup *l, int arch);\n\n/** Compute a forward MDCT and scale by 4/N, trashes the input array */\nvoid clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in,\n                        kiss_fft_scalar * OPUS_RESTRICT out,\n                        const opus_val16 *window, int overlap,\n                        int shift, int stride, int arch);\n\n/** Compute a backward MDCT (no scaling) and performs weighted overlap-add\n    (scales implicitly by 1/2) */\nvoid clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in,\n      kiss_fft_scalar * OPUS_RESTRICT out,\n      const opus_val16 * OPUS_RESTRICT window,\n      int overlap, int shift, int stride, int arch);\n\n#if !defined(OVERRIDE_OPUS_MDCT)\n/* Is run-time CPU detection enabled on this platform? */\n#if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10)\n\nextern void (*const CLT_MDCT_FORWARD_IMPL[OPUS_ARCHMASK+1])(\n      const mdct_lookup *l, kiss_fft_scalar *in,\n      kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window,\n      int overlap, int shift, int stride, int arch);\n\n#define clt_mdct_forward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \\\n   ((*CLT_MDCT_FORWARD_IMPL[(arch)&OPUS_ARCHMASK])(_l, _in, _out, \\\n                                                   _window, _overlap, _shift, \\\n                                                   _stride, _arch))\n\nextern void (*const CLT_MDCT_BACKWARD_IMPL[OPUS_ARCHMASK+1])(\n      const mdct_lookup *l, kiss_fft_scalar *in,\n      kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window,\n      int overlap, int shift, int stride, int arch);\n\n#define clt_mdct_backward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \\\n   (*CLT_MDCT_BACKWARD_IMPL[(arch)&OPUS_ARCHMASK])(_l, _in, _out, \\\n                                                   _window, _overlap, _shift, \\\n                                                   _stride, _arch)\n\n#else /* if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10) */\n\n#define clt_mdct_forward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \\\n   clt_mdct_forward_c(_l, _in, _out, _window, _overlap, _shift, _stride, _arch)\n\n#define clt_mdct_backward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \\\n   clt_mdct_backward_c(_l, _in, _out, _window, _overlap, _shift, _stride, _arch)\n\n#endif /* end if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10) && !defined(FIXED_POINT) */\n#endif /* end if !defined(OVERRIDE_OPUS_MDCT) */\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/mfrngcod.h",
    "content": "/* Copyright (c) 2001-2008 Timothy B. Terriberry\n   Copyright (c) 2008-2009 Xiph.Org Foundation */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#if !defined(_mfrngcode_H)\n# define _mfrngcode_H (1)\n# include \"entcode.h\"\n\n/*Constants used by the entropy encoder/decoder.*/\n\n/*The number of bits to output at a time.*/\n# define EC_SYM_BITS   (8)\n/*The total number of bits in each of the state registers.*/\n# define EC_CODE_BITS  (32)\n/*The maximum symbol value.*/\n# define EC_SYM_MAX    ((1U<<EC_SYM_BITS)-1)\n/*Bits to shift by to move a symbol into the high-order position.*/\n# define EC_CODE_SHIFT (EC_CODE_BITS-EC_SYM_BITS-1)\n/*Carry bit of the high-order range symbol.*/\n# define EC_CODE_TOP   (((opus_uint32)1U)<<(EC_CODE_BITS-1))\n/*Low-order bit of the high-order range symbol.*/\n# define EC_CODE_BOT   (EC_CODE_TOP>>EC_SYM_BITS)\n/*The number of bits available for the last, partial symbol in the code field.*/\n# define EC_CODE_EXTRA ((EC_CODE_BITS-2)%EC_SYM_BITS+1)\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/mips/celt_mipsr1.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2010 Xiph.Org Foundation\n   Copyright (c) 2008 Gregory Maxwell\n   Written by Jean-Marc Valin and Gregory Maxwell */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef __CELT_MIPSR1_H__\n#define __CELT_MIPSR1_H__\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#define CELT_C\n\n#include \"os_support.h\"\n#include \"mdct.h\"\n#include <math.h>\n#include \"celt.h\"\n#include \"pitch.h\"\n#include \"bands.h\"\n#include \"modes.h\"\n#include \"entcode.h\"\n#include \"quant_bands.h\"\n#include \"rate.h\"\n#include \"stack_alloc.h\"\n#include \"mathops.h\"\n#include \"float_cast.h\"\n#include <stdarg.h>\n#include \"celt_lpc.h\"\n#include \"vq.h\"\n\n#define OVERRIDE_comb_filter\nvoid comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,\n      opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,\n      const opus_val16 *window, int overlap, int arch)\n{\n   int i;\n   opus_val32 x0, x1, x2, x3, x4;\n\n   (void)arch;\n\n   /* printf (\"%d %d %f %f\\n\", T0, T1, g0, g1); */\n   opus_val16 g00, g01, g02, g10, g11, g12;\n   static const opus_val16 gains[3][3] = {\n         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},\n         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},\n         {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};\n\n   if (g0==0 && g1==0)\n   {\n      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */\n      if (x!=y)\n         OPUS_MOVE(y, x, N);\n      return;\n   }\n\n   g00 = MULT16_16_P15(g0, gains[tapset0][0]);\n   g01 = MULT16_16_P15(g0, gains[tapset0][1]);\n   g02 = MULT16_16_P15(g0, gains[tapset0][2]);\n   g10 = MULT16_16_P15(g1, gains[tapset1][0]);\n   g11 = MULT16_16_P15(g1, gains[tapset1][1]);\n   g12 = MULT16_16_P15(g1, gains[tapset1][2]);\n   x1 = x[-T1+1];\n   x2 = x[-T1  ];\n   x3 = x[-T1-1];\n   x4 = x[-T1-2];\n   /* If the filter didn't change, we don't need the overlap */\n   if (g0==g1 && T0==T1 && tapset0==tapset1)\n      overlap=0;\n\n   for (i=0;i<overlap;i++)\n   {\n      opus_val16 f;\n      opus_val32 res;\n      f = MULT16_16_Q15(window[i],window[i]);\n      x0= x[i-T1+2];\n\n      asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" ((int)MULT16_16_Q15((Q15ONE-f),g00)), \"r\" ((int)x[i-T0]));\n\n      asm volatile(\"MADD $ac1, %0, %1\" : : \"r\" ((int)MULT16_16_Q15((Q15ONE-f),g01)), \"r\" ((int)ADD32(x[i-T0-1],x[i-T0+1])));\n      asm volatile(\"MADD $ac1, %0, %1\" : : \"r\" ((int)MULT16_16_Q15((Q15ONE-f),g02)), \"r\" ((int)ADD32(x[i-T0-2],x[i-T0+2])));\n      asm volatile(\"MADD $ac1, %0, %1\" : : \"r\" ((int)MULT16_16_Q15(f,g10)), \"r\" ((int)x2));\n      asm volatile(\"MADD $ac1, %0, %1\" : : \"r\" ((int)MULT16_16_Q15(f,g11)), \"r\" ((int)ADD32(x3,x1)));\n      asm volatile(\"MADD $ac1, %0, %1\" : : \"r\" ((int)MULT16_16_Q15(f,g12)), \"r\" ((int)ADD32(x4,x0)));\n\n      asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (res): \"i\" (15));\n\n      y[i] = x[i] + res;\n\n      x4=x3;\n      x3=x2;\n      x2=x1;\n      x1=x0;\n   }\n\n   x4 = x[i-T1-2];\n   x3 = x[i-T1-1];\n   x2 = x[i-T1];\n   x1 = x[i-T1+1];\n\n   if (g1==0)\n   {\n      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */\n      if (x!=y)\n         OPUS_MOVE(y+overlap, x+overlap, N-overlap);\n      return;\n   }\n\n   for (i=overlap;i<N;i++)\n   {\n      opus_val32 res;\n      x0=x[i-T1+2];\n\n      asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" ((int)g10), \"r\" ((int)x2));\n\n      asm volatile(\"MADD $ac1, %0, %1\" : : \"r\" ((int)g11), \"r\" ((int)ADD32(x3,x1)));\n      asm volatile(\"MADD $ac1, %0, %1\" : : \"r\" ((int)g12), \"r\" ((int)ADD32(x4,x0)));\n      asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (res): \"i\" (15));\n      y[i] = x[i] + res;\n      x4=x3;\n      x3=x2;\n      x2=x1;\n      x1=x0;\n   }\n}\n\n#endif /* __CELT_MIPSR1_H__ */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/mips/fixed_generic_mipsr1.h",
    "content": "/* Copyright (C) 2007-2009 Xiph.Org Foundation\n   Copyright (C) 2003-2008 Jean-Marc Valin\n   Copyright (C) 2007-2008 CSIRO */\n/**\n   @file fixed_generic.h\n   @brief Generic fixed-point operations\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef CELT_FIXED_GENERIC_MIPSR1_H\n#define CELT_FIXED_GENERIC_MIPSR1_H\n\n#undef MULT16_32_Q15_ADD\nstatic inline int MULT16_32_Q15_ADD(int a, int b, int c, int d) {\n    int m;\n    asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" ((int)a), \"r\" ((int)b));\n    asm volatile(\"madd $ac1, %0, %1\" : : \"r\" ((int)c), \"r\" ((int)d));\n    asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (m): \"i\" (15));\n    return m;\n}\n\n#undef MULT16_32_Q15_SUB\nstatic inline int MULT16_32_Q15_SUB(int a, int b, int c, int d) {\n    int m;\n    asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" ((int)a), \"r\" ((int)b));\n    asm volatile(\"msub $ac1, %0, %1\" : : \"r\" ((int)c), \"r\" ((int)d));\n    asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (m): \"i\" (15));\n    return m;\n}\n\n#undef MULT16_16_Q15_ADD\nstatic inline int MULT16_16_Q15_ADD(int a, int b, int c, int d) {\n    int m;\n    asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" ((int)a), \"r\" ((int)b));\n    asm volatile(\"madd $ac1, %0, %1\" : : \"r\" ((int)c), \"r\" ((int)d));\n    asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (m): \"i\" (15));\n    return m;\n}\n\n#undef MULT16_16_Q15_SUB\nstatic inline int MULT16_16_Q15_SUB(int a, int b, int c, int d) {\n    int m;\n    asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" ((int)a), \"r\" ((int)b));\n    asm volatile(\"msub $ac1, %0, %1\" : : \"r\" ((int)c), \"r\" ((int)d));\n    asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (m): \"i\" (15));\n    return m;\n}\n\n\n#undef MULT16_32_Q16\nstatic inline int MULT16_32_Q16(int a, int b)\n{\n    int c;\n    asm volatile(\"MULT $ac1,%0, %1\" : : \"r\" (a), \"r\" (b));\n    asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (c): \"i\" (16));\n    return c;\n}\n\n#undef MULT16_32_P16\nstatic inline int MULT16_32_P16(int a, int b)\n{\n    int c;\n    asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" (a), \"r\" (b));\n    asm volatile(\"EXTR_R.W %0,$ac1, %1\" : \"=r\" (c): \"i\" (16));\n    return c;\n}\n\n#undef MULT16_32_Q15\nstatic inline int MULT16_32_Q15(int a, int b)\n{\n    int c;\n    asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" (a), \"r\" (b));\n    asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (c): \"i\" (15));\n    return c;\n}\n\n#undef MULT32_32_Q31\nstatic inline int MULT32_32_Q31(int a, int b)\n{\n    int r;\n    asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" (a), \"r\" (b));\n    asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (r): \"i\" (31));\n    return r;\n}\n\n#undef PSHR32\nstatic inline int PSHR32(int a, int shift)\n{\n    int r;\n    asm volatile (\"SHRAV_R.W %0, %1, %2\" :\"=r\" (r): \"r\" (a), \"r\" (shift));\n    return r;\n}\n\n#undef MULT16_16_P15\nstatic inline int MULT16_16_P15(int a, int b)\n{\n    int r;\n    asm volatile (\"mul %0, %1, %2\" :\"=r\" (r): \"r\" (a), \"r\" (b));\n    asm volatile (\"SHRA_R.W %0, %1, %2\" : \"+r\" (r):  \"0\" (r), \"i\"(15));\n    return r;\n}\n\n#endif /* CELT_FIXED_GENERIC_MIPSR1_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/mips/kiss_fft_mipsr1.h",
    "content": "/*Copyright (c) 2013, Xiph.Org Foundation and contributors.\n\n  All rights reserved.\n\n  Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n       this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright notice,\n       this list of conditions and the following disclaimer in the\n       documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n  POSSIBILITY OF SUCH DAMAGE.*/\n\n#ifndef KISS_FFT_MIPSR1_H\n#define KISS_FFT_MIPSR1_H\n\n#if !defined(KISS_FFT_GUTS_H)\n#error \"This file should only be included from _kiss_fft_guts.h\"\n#endif\n\n#ifdef FIXED_POINT\n\n#define S_MUL_ADD(a, b, c, d) (S_MUL(a,b)+S_MUL(c,d))\n#define S_MUL_SUB(a, b, c, d) (S_MUL(a,b)-S_MUL(c,d))\n\n#undef S_MUL_ADD\nstatic inline int S_MUL_ADD(int a, int b, int c, int d) {\n    int m;\n    asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" ((int)a), \"r\" ((int)b));\n    asm volatile(\"madd $ac1, %0, %1\" : : \"r\" ((int)c), \"r\" ((int)d));\n    asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (m): \"i\" (15));\n    return m;\n}\n\n#undef S_MUL_SUB\nstatic inline int S_MUL_SUB(int a, int b, int c, int d) {\n    int m;\n    asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" ((int)a), \"r\" ((int)b));\n    asm volatile(\"msub $ac1, %0, %1\" : : \"r\" ((int)c), \"r\" ((int)d));\n    asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (m): \"i\" (15));\n    return m;\n}\n\n#undef C_MUL\n#   define C_MUL(m,a,b) (m=C_MUL_fun(a,b))\nstatic inline kiss_fft_cpx C_MUL_fun(kiss_fft_cpx a, kiss_twiddle_cpx b) {\n    kiss_fft_cpx m;\n\n    asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" ((int)a.r), \"r\" ((int)b.r));\n    asm volatile(\"msub $ac1, %0, %1\" : : \"r\" ((int)a.i), \"r\" ((int)b.i));\n    asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (m.r): \"i\" (15));\n    asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" ((int)a.r), \"r\" ((int)b.i));\n    asm volatile(\"madd $ac1, %0, %1\" : : \"r\" ((int)a.i), \"r\" ((int)b.r));\n    asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (m.i): \"i\" (15));\n\n    return m;\n}\n#undef C_MULC\n#   define C_MULC(m,a,b) (m=C_MULC_fun(a,b))\nstatic inline kiss_fft_cpx C_MULC_fun(kiss_fft_cpx a, kiss_twiddle_cpx b) {\n    kiss_fft_cpx m;\n\n    asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" ((int)a.r), \"r\" ((int)b.r));\n    asm volatile(\"madd $ac1, %0, %1\" : : \"r\" ((int)a.i), \"r\" ((int)b.i));\n    asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (m.r): \"i\" (15));\n    asm volatile(\"MULT $ac1, %0, %1\" : : \"r\" ((int)a.i), \"r\" ((int)b.r));\n    asm volatile(\"msub $ac1, %0, %1\" : : \"r\" ((int)a.r), \"r\" ((int)b.i));\n    asm volatile(\"EXTR.W %0,$ac1, %1\" : \"=r\" (m.i): \"i\" (15));\n\n    return m;\n}\n\n#endif /* FIXED_POINT */\n\n#define OVERRIDE_kf_bfly5\nstatic void kf_bfly5(\n                     kiss_fft_cpx * Fout,\n                     const size_t fstride,\n                     const kiss_fft_state *st,\n                     int m,\n                     int N,\n                     int mm\n                    )\n{\n   kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;\n   int i, u;\n   kiss_fft_cpx scratch[13];\n\n   const kiss_twiddle_cpx *tw;\n   kiss_twiddle_cpx ya,yb;\n   kiss_fft_cpx * Fout_beg = Fout;\n\n#ifdef FIXED_POINT\n   ya.r = 10126;\n   ya.i = -31164;\n   yb.r = -26510;\n   yb.i = -19261;\n#else\n   ya = st->twiddles[fstride*m];\n   yb = st->twiddles[fstride*2*m];\n#endif\n\n   tw=st->twiddles;\n\n   for (i=0;i<N;i++)\n   {\n      Fout = Fout_beg + i*mm;\n      Fout0=Fout;\n      Fout1=Fout0+m;\n      Fout2=Fout0+2*m;\n      Fout3=Fout0+3*m;\n      Fout4=Fout0+4*m;\n\n      /* For non-custom modes, m is guaranteed to be a multiple of 4. */\n      for ( u=0; u<m; ++u ) {\n         scratch[0] = *Fout0;\n\n\n         C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);\n         C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);\n         C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);\n         C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);\n\n         C_ADD( scratch[7],scratch[1],scratch[4]);\n         C_SUB( scratch[10],scratch[1],scratch[4]);\n         C_ADD( scratch[8],scratch[2],scratch[3]);\n         C_SUB( scratch[9],scratch[2],scratch[3]);\n\n         Fout0->r += scratch[7].r + scratch[8].r;\n         Fout0->i += scratch[7].i + scratch[8].i;\n         scratch[5].r = scratch[0].r + S_MUL_ADD(scratch[7].r,ya.r,scratch[8].r,yb.r);\n         scratch[5].i = scratch[0].i + S_MUL_ADD(scratch[7].i,ya.r,scratch[8].i,yb.r);\n\n         scratch[6].r =  S_MUL_ADD(scratch[10].i,ya.i,scratch[9].i,yb.i);\n         scratch[6].i =  -S_MUL_ADD(scratch[10].r,ya.i,scratch[9].r,yb.i);\n\n         C_SUB(*Fout1,scratch[5],scratch[6]);\n         C_ADD(*Fout4,scratch[5],scratch[6]);\n\n         scratch[11].r = scratch[0].r + S_MUL_ADD(scratch[7].r,yb.r,scratch[8].r,ya.r);\n         scratch[11].i = scratch[0].i + S_MUL_ADD(scratch[7].i,yb.r,scratch[8].i,ya.r);\n\n         scratch[12].r =  S_MUL_SUB(scratch[9].i,ya.i,scratch[10].i,yb.i);\n         scratch[12].i =  S_MUL_SUB(scratch[10].r,yb.i,scratch[9].r,ya.i);\n\n         C_ADD(*Fout2,scratch[11],scratch[12]);\n         C_SUB(*Fout3,scratch[11],scratch[12]);\n\n         ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;\n      }\n   }\n}\n\n\n#endif /* KISS_FFT_MIPSR1_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/mips/mdct_mipsr1.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2008 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/* This is a simple MDCT implementation that uses a N/4 complex FFT\n   to do most of the work. It should be relatively straightforward to\n   plug in pretty much and FFT here.\n\n   This replaces the Vorbis FFT (and uses the exact same API), which\n   was a bit too messy and that was ending up duplicating code\n   (might as well use the same FFT everywhere).\n\n   The algorithm is similar to (and inspired from) Fabrice Bellard's\n   MDCT implementation in FFMPEG, but has differences in signs, ordering\n   and scaling in many places.\n*/\n#ifndef __MDCT_MIPSR1_H__\n#define __MDCT_MIPSR1_H__\n\n#ifndef SKIP_CONFIG_H\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#endif\n\n#include \"mdct.h\"\n#include \"kiss_fft.h\"\n#include \"_kiss_fft_guts.h\"\n#include <math.h>\n#include \"os_support.h\"\n#include \"mathops.h\"\n#include \"stack_alloc.h\"\n\n/* Forward MDCT trashes the input array */\n#define OVERRIDE_clt_mdct_forward\nvoid clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,\n      const opus_val16 *window, int overlap, int shift, int stride, int arch)\n{\n   int i;\n   int N, N2, N4;\n   VARDECL(kiss_fft_scalar, f);\n   VARDECL(kiss_fft_cpx, f2);\n   const kiss_fft_state *st = l->kfft[shift];\n   const kiss_twiddle_scalar *trig;\n   opus_val16 scale;\n#ifdef FIXED_POINT\n   /* Allows us to scale with MULT16_32_Q16(), which is faster than\n      MULT16_32_Q15() on ARM. */\n   int scale_shift = st->scale_shift-1;\n#endif\n\n    (void)arch;\n\n   SAVE_STACK;\n   scale = st->scale;\n\n   N = l->n;\n   trig = l->trig;\n   for (i=0;i<shift;i++)\n   {\n      N >>= 1;\n      trig += N;\n   }\n   N2 = N>>1;\n   N4 = N>>2;\n\n   ALLOC(f, N2, kiss_fft_scalar);\n   ALLOC(f2, N4, kiss_fft_cpx);\n\n   /* Consider the input to be composed of four blocks: [a, b, c, d] */\n   /* Window, shuffle, fold */\n   {\n      /* Temp pointers to make it really clear to the compiler what we're doing */\n      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);\n      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);\n      kiss_fft_scalar * OPUS_RESTRICT yp = f;\n      const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);\n      const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;\n      for(i=0;i<((overlap+3)>>2);i++)\n      {\n         /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/\n          *yp++ = S_MUL_ADD(*wp2, xp1[N2],*wp1,*xp2);\n          *yp++ = S_MUL_SUB(*wp1, *xp1,*wp2, xp2[-N2]);\n         xp1+=2;\n         xp2-=2;\n         wp1+=2;\n         wp2-=2;\n      }\n      wp1 = window;\n      wp2 = window+overlap-1;\n      for(;i<N4-((overlap+3)>>2);i++)\n      {\n         /* Real part arranged as a-bR, Imag part arranged as -c-dR */\n         *yp++ = *xp2;\n         *yp++ = *xp1;\n         xp1+=2;\n         xp2-=2;\n      }\n      for(;i<N4;i++)\n      {\n         /* Real part arranged as a-bR, Imag part arranged as -c-dR */\n          *yp++ =  S_MUL_SUB(*wp2, *xp2, *wp1, xp1[-N2]);\n          *yp++ = S_MUL_ADD(*wp2, *xp1, *wp1, xp2[N2]);\n         xp1+=2;\n         xp2-=2;\n         wp1+=2;\n         wp2-=2;\n      }\n   }\n   /* Pre-rotation */\n   {\n      kiss_fft_scalar * OPUS_RESTRICT yp = f;\n      const kiss_twiddle_scalar *t = &trig[0];\n      for(i=0;i<N4;i++)\n      {\n         kiss_fft_cpx yc;\n         kiss_twiddle_scalar t0, t1;\n         kiss_fft_scalar re, im, yr, yi;\n         t0 = t[i];\n         t1 = t[N4+i];\n         re = *yp++;\n         im = *yp++;\n\n         yr = S_MUL_SUB(re,t0,im,t1);\n         yi = S_MUL_ADD(im,t0,re,t1);\n\n         yc.r = yr;\n         yc.i = yi;\n         yc.r = PSHR32(MULT16_32_Q16(scale, yc.r), scale_shift);\n         yc.i = PSHR32(MULT16_32_Q16(scale, yc.i), scale_shift);\n         f2[st->bitrev[i]] = yc;\n      }\n   }\n\n   /* N/4 complex FFT, does not downscale anymore */\n   opus_fft_impl(st, f2);\n\n   /* Post-rotate */\n   {\n      /* Temp pointers to make it really clear to the compiler what we're doing */\n      const kiss_fft_cpx * OPUS_RESTRICT fp = f2;\n      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;\n      kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);\n      const kiss_twiddle_scalar *t = &trig[0];\n      /* Temp pointers to make it really clear to the compiler what we're doing */\n      for(i=0;i<N4;i++)\n      {\n         kiss_fft_scalar yr, yi;\n         yr = S_MUL_SUB(fp->i,t[N4+i] , fp->r,t[i]);\n         yi = S_MUL_ADD(fp->r,t[N4+i] ,fp->i,t[i]);\n         *yp1 = yr;\n         *yp2 = yi;\n         fp++;\n         yp1 += 2*stride;\n         yp2 -= 2*stride;\n      }\n   }\n   RESTORE_STACK;\n}\n\n#define OVERRIDE_clt_mdct_backward\nvoid clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,\n      const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch)\n{\n   int i;\n   int N, N2, N4;\n   const kiss_twiddle_scalar *trig;\n\n    (void)arch;\n\n   N = l->n;\n   trig = l->trig;\n   for (i=0;i<shift;i++)\n   {\n      N >>= 1;\n      trig += N;\n   }\n   N2 = N>>1;\n   N4 = N>>2;\n\n   /* Pre-rotate */\n   {\n      /* Temp pointers to make it really clear to the compiler what we're doing */\n      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;\n      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);\n      kiss_fft_scalar * OPUS_RESTRICT yp = out+(overlap>>1);\n      const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0];\n      const opus_int16 * OPUS_RESTRICT bitrev = l->kfft[shift]->bitrev;\n      for(i=0;i<N4;i++)\n      {\n         int rev;\n         kiss_fft_scalar yr, yi;\n         rev = *bitrev++;\n         yr = S_MUL_ADD(*xp2, t[i] , *xp1, t[N4+i]);\n         yi = S_MUL_SUB(*xp1, t[i] , *xp2, t[N4+i]);\n         /* We swap real and imag because we use an FFT instead of an IFFT. */\n         yp[2*rev+1] = yr;\n         yp[2*rev] = yi;\n         /* Storing the pre-rotation directly in the bitrev order. */\n         xp1+=2*stride;\n         xp2-=2*stride;\n      }\n   }\n\n   opus_fft_impl(l->kfft[shift], (kiss_fft_cpx*)(out+(overlap>>1)));\n\n   /* Post-rotate and de-shuffle from both ends of the buffer at once to make\n      it in-place. */\n   {\n      kiss_fft_scalar * OPUS_RESTRICT yp0 = out+(overlap>>1);\n      kiss_fft_scalar * OPUS_RESTRICT yp1 = out+(overlap>>1)+N2-2;\n      const kiss_twiddle_scalar *t = &trig[0];\n      /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the\n         middle pair will be computed twice. */\n      for(i=0;i<(N4+1)>>1;i++)\n      {\n         kiss_fft_scalar re, im, yr, yi;\n         kiss_twiddle_scalar t0, t1;\n         /* We swap real and imag because we're using an FFT instead of an IFFT. */\n         re = yp0[1];\n         im = yp0[0];\n         t0 = t[i];\n         t1 = t[N4+i];\n         /* We'd scale up by 2 here, but instead it's done when mixing the windows */\n         yr = S_MUL_ADD(re,t0 , im,t1);\n         yi = S_MUL_SUB(re,t1 , im,t0);\n         /* We swap real and imag because we're using an FFT instead of an IFFT. */\n         re = yp1[1];\n         im = yp1[0];\n         yp0[0] = yr;\n         yp1[1] = yi;\n\n         t0 = t[(N4-i-1)];\n         t1 = t[(N2-i-1)];\n         /* We'd scale up by 2 here, but instead it's done when mixing the windows */\n         yr = S_MUL_ADD(re,t0,im,t1);\n         yi = S_MUL_SUB(re,t1,im,t0);\n         yp1[0] = yr;\n         yp0[1] = yi;\n         yp0 += 2;\n         yp1 -= 2;\n      }\n   }\n\n   /* Mirror on both sides for TDAC */\n   {\n      kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;\n      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;\n      const opus_val16 * OPUS_RESTRICT wp1 = window;\n      const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;\n\n      for(i = 0; i < overlap/2; i++)\n      {\n         kiss_fft_scalar x1, x2;\n         x1 = *xp1;\n         x2 = *yp1;\n         *yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1);\n         *xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1);\n         wp1++;\n         wp2--;\n      }\n   }\n}\n#endif /* __MDCT_MIPSR1_H__ */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/mips/pitch_mipsr1.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/**\n   @file pitch.h\n   @brief Pitch analysis\n */\n\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef PITCH_MIPSR1_H\n#define PITCH_MIPSR1_H\n\n#define OVERRIDE_DUAL_INNER_PROD\nstatic inline void dual_inner_prod(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,\n      int N, opus_val32 *xy1, opus_val32 *xy2, int arch)\n{\n   int j;\n   opus_val32 xy01=0;\n   opus_val32 xy02=0;\n\n   (void)arch;\n\n   asm volatile(\"MULT $ac1, $0, $0\");\n   asm volatile(\"MULT $ac2, $0, $0\");\n   /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */\n   for (j=0;j<N;j++)\n   {\n      asm volatile(\"MADD $ac1, %0, %1\" : : \"r\" ((int)x[j]), \"r\" ((int)y01[j]));\n      asm volatile(\"MADD $ac2, %0, %1\" : : \"r\" ((int)x[j]), \"r\" ((int)y02[j]));\n      ++j;\n      asm volatile(\"MADD $ac1, %0, %1\" : : \"r\" ((int)x[j]), \"r\" ((int)y01[j]));\n      asm volatile(\"MADD $ac2, %0, %1\" : : \"r\" ((int)x[j]), \"r\" ((int)y02[j]));\n   }\n   asm volatile (\"mflo %0, $ac1\": \"=r\"(xy01));\n   asm volatile (\"mflo %0, $ac2\": \"=r\"(xy02));\n   *xy1 = xy01;\n   *xy2 = xy02;\n}\n\nstatic inline void xcorr_kernel_mips(const opus_val16 * x,\n      const opus_val16 * y, opus_val32 sum[4], int len)\n{\n   int j;\n   opus_val16 y_0, y_1, y_2, y_3;\n\n    opus_int64 sum_0, sum_1, sum_2, sum_3;\n    sum_0 =  (opus_int64)sum[0];\n    sum_1 =  (opus_int64)sum[1];\n    sum_2 =  (opus_int64)sum[2];\n    sum_3 =  (opus_int64)sum[3];\n\n    y_3=0; /* gcc doesn't realize that y_3 can't be used uninitialized */\n    y_0=*y++;\n    y_1=*y++;\n    y_2=*y++;\n    for (j=0;j<len-3;j+=4)\n    {\n        opus_val16 tmp;\n        tmp = *x++;\n        y_3=*y++;\n\n        sum_0 = __builtin_mips_madd( sum_0, tmp, y_0);\n        sum_1 = __builtin_mips_madd( sum_1, tmp, y_1);\n        sum_2 = __builtin_mips_madd( sum_2, tmp, y_2);\n        sum_3 = __builtin_mips_madd( sum_3, tmp, y_3);\n\n        tmp=*x++;\n        y_0=*y++;\n\n        sum_0 = __builtin_mips_madd( sum_0, tmp, y_1 );\n        sum_1 = __builtin_mips_madd( sum_1, tmp, y_2 );\n        sum_2 = __builtin_mips_madd( sum_2, tmp, y_3);\n        sum_3 = __builtin_mips_madd( sum_3, tmp, y_0);\n\n       tmp=*x++;\n       y_1=*y++;\n\n       sum_0 = __builtin_mips_madd( sum_0, tmp, y_2 );\n       sum_1 = __builtin_mips_madd( sum_1, tmp, y_3 );\n       sum_2 = __builtin_mips_madd( sum_2, tmp, y_0);\n       sum_3 = __builtin_mips_madd( sum_3, tmp, y_1);\n\n\n      tmp=*x++;\n      y_2=*y++;\n\n       sum_0 = __builtin_mips_madd( sum_0, tmp, y_3 );\n       sum_1 = __builtin_mips_madd( sum_1, tmp, y_0 );\n       sum_2 = __builtin_mips_madd( sum_2, tmp, y_1);\n       sum_3 = __builtin_mips_madd( sum_3, tmp, y_2);\n\n   }\n   if (j++<len)\n   {\n      opus_val16 tmp = *x++;\n      y_3=*y++;\n\n       sum_0 = __builtin_mips_madd( sum_0, tmp, y_0 );\n       sum_1 = __builtin_mips_madd( sum_1, tmp, y_1 );\n       sum_2 = __builtin_mips_madd( sum_2, tmp, y_2);\n       sum_3 = __builtin_mips_madd( sum_3, tmp, y_3);\n   }\n\n   if (j++<len)\n   {\n      opus_val16 tmp=*x++;\n      y_0=*y++;\n\n      sum_0 = __builtin_mips_madd( sum_0, tmp, y_1 );\n      sum_1 = __builtin_mips_madd( sum_1, tmp, y_2 );\n      sum_2 = __builtin_mips_madd( sum_2, tmp, y_3);\n      sum_3 = __builtin_mips_madd( sum_3, tmp, y_0);\n   }\n\n   if (j<len)\n   {\n      opus_val16 tmp=*x++;\n      y_1=*y++;\n\n       sum_0 = __builtin_mips_madd( sum_0, tmp, y_2 );\n       sum_1 = __builtin_mips_madd( sum_1, tmp, y_3 );\n       sum_2 = __builtin_mips_madd( sum_2, tmp, y_0);\n       sum_3 = __builtin_mips_madd( sum_3, tmp, y_1);\n\n   }\n\n   sum[0] = (opus_val32)sum_0;\n   sum[1] = (opus_val32)sum_1;\n   sum[2] = (opus_val32)sum_2;\n   sum[3] = (opus_val32)sum_3;\n}\n\n#define OVERRIDE_XCORR_KERNEL\n#define xcorr_kernel(x, y, sum, len, arch) \\\n    ((void)(arch), xcorr_kernel_mips(x, y, sum, len))\n\n#endif /* PITCH_MIPSR1_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/mips/vq_mipsr1.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef __VQ_MIPSR1_H__\n#define __VQ_MIPSR1_H__\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"mathops.h\"\n#include \"arch.h\"\n\nstatic unsigned extract_collapse_mask(int *iy, int N, int B);\nstatic void normalise_residual(int * OPUS_RESTRICT iy, celt_norm * OPUS_RESTRICT X, int N, opus_val32 Ryy, opus_val16 gain);\nstatic void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread);\nstatic void renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch);\n\n#define OVERRIDE_vq_exp_rotation1\nstatic void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s)\n{\n   int i;\n   opus_val16 ms;\n   celt_norm *Xptr;\n   Xptr = X;\n   ms = NEG16(s);\n   for (i=0;i<len-stride;i++)\n   {\n      celt_norm x1, x2;\n      x1 = Xptr[0];\n      x2 = Xptr[stride];\n      Xptr[stride] = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x2),  s, x1), 15));\n      *Xptr++      = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x1), ms, x2), 15));\n   }\n   Xptr = &X[len-2*stride-1];\n   for (i=len-2*stride-1;i>=0;i--)\n   {\n      celt_norm x1, x2;\n      x1 = Xptr[0];\n      x2 = Xptr[stride];\n      Xptr[stride] = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x2),  s, x1), 15));\n      *Xptr--      = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x1), ms, x2), 15));\n   }\n}\n\n#define OVERRIDE_renormalise_vector\n\n#define renormalise_vector(X, N, gain, arch) \\\n (renormalise_vector_mips(X, N, gain, arch))\n\nvoid renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch)\n{\n   int i;\n#ifdef FIXED_POINT\n   int k;\n#endif\n   opus_val32 E = EPSILON;\n   opus_val16 g;\n   opus_val32 t;\n   celt_norm *xptr = X;\n   int X0, X1;\n\n   (void)arch;\n\n   asm volatile(\"mult $ac1, $0, $0\");\n   asm volatile(\"MTLO %0, $ac1\" : :\"r\" (E));\n   /*if(N %4)\n       printf(\"error\");*/\n   for (i=0;i<N-2;i+=2)\n   {\n      X0 = (int)*xptr++;\n      asm volatile(\"MADD $ac1, %0, %1\" : : \"r\" (X0), \"r\" (X0));\n\n      X1 = (int)*xptr++;\n      asm volatile(\"MADD $ac1, %0, %1\" : : \"r\" (X1), \"r\" (X1));\n   }\n\n   for (;i<N;i++)\n   {\n      X0 = (int)*xptr++;\n      asm volatile(\"MADD $ac1, %0, %1\" : : \"r\" (X0), \"r\" (X0));\n   }\n\n   asm volatile(\"MFLO %0, $ac1\" : \"=r\" (E));\n#ifdef FIXED_POINT\n   k = celt_ilog2(E)>>1;\n#endif\n   t = VSHR32(E, 2*(k-7));\n   g = MULT16_16_P15(celt_rsqrt_norm(t),gain);\n\n   xptr = X;\n   for (i=0;i<N;i++)\n   {\n      *xptr = EXTRACT16(PSHR32(MULT16_16(g, *xptr), k+1));\n      xptr++;\n   }\n   /*return celt_sqrt(E);*/\n}\n\n#endif /* __VQ_MIPSR1_H__ */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/modes.c",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Copyright (c) 2008 Gregory Maxwell\n   Written by Jean-Marc Valin and Gregory Maxwell */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"celt.h\"\n#include \"modes.h\"\n#include \"rate.h\"\n#include \"os_support.h\"\n#include \"stack_alloc.h\"\n#include \"quant_bands.h\"\n#include \"cpu_support.h\"\n\nstatic const opus_int16 eband5ms[] = {\n/*0  200 400 600 800  1k 1.2 1.4 1.6  2k 2.4 2.8 3.2  4k 4.8 5.6 6.8  8k 9.6 12k 15.6 */\n  0,  1,  2,  3,  4,  5,  6,  7,  8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100\n};\n\n/* Alternate tuning (partially derived from Vorbis) */\n#define BITALLOC_SIZE 11\n/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */\nstatic const unsigned char band_allocation[] = {\n/*0  200 400 600 800  1k 1.2 1.4 1.6  2k 2.4 2.8 3.2  4k 4.8 5.6 6.8  8k 9.6 12k 15.6 */\n  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n 90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10,  0,  0,  0,  0,  0,  0,  0,  0,\n110,100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12,  0,  0,  0,  0,  0,  0,\n118,110,103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15,  4,  0,  0,  0,  0,\n126,119,112,104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12,  1,  0,  0,\n134,127,120,114,103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10,  1,\n144,137,130,124,113,107,101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15,  1,\n152,145,138,132,123,117,111,105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20,  1,\n162,155,148,142,133,127,121,115,108,102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30,  1,\n172,165,158,152,143,137,131,125,118,112,106,100, 94, 87, 81, 75, 69, 63, 56, 45, 20,\n200,200,200,200,200,200,200,200,198,193,188,183,178,173,168,163,158,153,148,129,104,\n};\n\n#ifndef CUSTOM_MODES_ONLY\n #ifdef FIXED_POINT\n  #include \"static_modes_fixed.h\"\n #else\n  #include \"static_modes_float.h\"\n #endif\n#endif /* CUSTOM_MODES_ONLY */\n\n#ifndef M_PI\n#define M_PI 3.141592653\n#endif\n\n#ifdef CUSTOM_MODES\n\n/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth\n   Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */\n#define BARK_BANDS 25\nstatic const opus_int16 bark_freq[BARK_BANDS+1] = {\n      0,   100,   200,   300,   400,\n    510,   630,   770,   920,  1080,\n   1270,  1480,  1720,  2000,  2320,\n   2700,  3150,  3700,  4400,  5300,\n   6400,  7700,  9500, 12000, 15500,\n  20000};\n\nstatic opus_int16 *compute_ebands(opus_int32 Fs, int frame_size, int res, int *nbEBands)\n{\n   opus_int16 *eBands;\n   int i, j, lin, low, high, nBark, offset=0;\n\n   /* All modes that have 2.5 ms short blocks use the same definition */\n   if (Fs == 400*(opus_int32)frame_size)\n   {\n      *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;\n      eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+1));\n      for (i=0;i<*nbEBands+1;i++)\n         eBands[i] = eband5ms[i];\n      return eBands;\n   }\n   /* Find the number of critical bands supported by our sampling rate */\n   for (nBark=1;nBark<BARK_BANDS;nBark++)\n    if (bark_freq[nBark+1]*2 >= Fs)\n       break;\n\n   /* Find where the linear part ends (i.e. where the spacing is more than min_width */\n   for (lin=0;lin<nBark;lin++)\n      if (bark_freq[lin+1]-bark_freq[lin] >= res)\n         break;\n\n   low = (bark_freq[lin]+res/2)/res;\n   high = nBark-lin;\n   *nbEBands = low+high;\n   eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+2));\n\n   if (eBands==NULL)\n      return NULL;\n\n   /* Linear spacing (min_width) */\n   for (i=0;i<low;i++)\n      eBands[i] = i;\n   if (low>0)\n      offset = eBands[low-1]*res - bark_freq[lin-1];\n   /* Spacing follows critical bands */\n   for (i=0;i<high;i++)\n   {\n      int target = bark_freq[lin+i];\n      /* Round to an even value */\n      eBands[i+low] = (target+offset/2+res)/(2*res)*2;\n      offset = eBands[i+low]*res - target;\n   }\n   /* Enforce the minimum spacing at the boundary */\n   for (i=0;i<*nbEBands;i++)\n      if (eBands[i] < i)\n         eBands[i] = i;\n   /* Round to an even value */\n   eBands[*nbEBands] = (bark_freq[nBark]+res)/(2*res)*2;\n   if (eBands[*nbEBands] > frame_size)\n      eBands[*nbEBands] = frame_size;\n   for (i=1;i<*nbEBands-1;i++)\n   {\n      if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])\n      {\n         eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2;\n      }\n   }\n   /* Remove any empty bands. */\n   for (i=j=0;i<*nbEBands;i++)\n      if(eBands[i+1]>eBands[j])\n         eBands[++j]=eBands[i+1];\n   *nbEBands=j;\n\n   for (i=1;i<*nbEBands;i++)\n   {\n      /* Every band must be smaller than the last band. */\n      celt_assert(eBands[i]-eBands[i-1]<=eBands[*nbEBands]-eBands[*nbEBands-1]);\n      /* Each band must be no larger than twice the size of the previous one. */\n      celt_assert(eBands[i+1]-eBands[i]<=2*(eBands[i]-eBands[i-1]));\n   }\n\n   return eBands;\n}\n\nstatic void compute_allocation_table(CELTMode *mode)\n{\n   int i, j;\n   unsigned char *allocVectors;\n   int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;\n\n   mode->nbAllocVectors = BITALLOC_SIZE;\n   allocVectors = opus_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands));\n   if (allocVectors==NULL)\n      return;\n\n   /* Check for standard mode */\n   if (mode->Fs == 400*(opus_int32)mode->shortMdctSize)\n   {\n      for (i=0;i<BITALLOC_SIZE*mode->nbEBands;i++)\n         allocVectors[i] = band_allocation[i];\n      mode->allocVectors = allocVectors;\n      return;\n   }\n   /* If not the standard mode, interpolate */\n   /* Compute per-codec-band allocation from per-critical-band matrix */\n   for (i=0;i<BITALLOC_SIZE;i++)\n   {\n      for (j=0;j<mode->nbEBands;j++)\n      {\n         int k;\n         for (k=0;k<maxBands;k++)\n         {\n            if (400*(opus_int32)eband5ms[k] > mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize)\n               break;\n         }\n         if (k>maxBands-1)\n            allocVectors[i*mode->nbEBands+j] = band_allocation[i*maxBands + maxBands-1];\n         else {\n            opus_int32 a0, a1;\n            a1 = mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize - 400*(opus_int32)eband5ms[k-1];\n            a0 = 400*(opus_int32)eband5ms[k] - mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize;\n            allocVectors[i*mode->nbEBands+j] = (a0*band_allocation[i*maxBands+k-1]\n                                             + a1*band_allocation[i*maxBands+k])/(a0+a1);\n         }\n      }\n   }\n\n   /*printf (\"\\n\");\n   for (i=0;i<BITALLOC_SIZE;i++)\n   {\n      for (j=0;j<mode->nbEBands;j++)\n         printf (\"%d \", allocVectors[i*mode->nbEBands+j]);\n      printf (\"\\n\");\n   }\n   exit(0);*/\n\n   mode->allocVectors = allocVectors;\n}\n\n#endif /* CUSTOM_MODES */\n\nCELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error)\n{\n   int i;\n#ifdef CUSTOM_MODES\n   CELTMode *mode=NULL;\n   int res;\n   opus_val16 *window;\n   opus_int16 *logN;\n   int LM;\n   int arch = opus_select_arch();\n   ALLOC_STACK;\n#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)\n   if (global_stack==NULL)\n      goto failure;\n#endif\n#endif\n\n#ifndef CUSTOM_MODES_ONLY\n   for (i=0;i<TOTAL_MODES;i++)\n   {\n      int j;\n      for (j=0;j<4;j++)\n      {\n         if (Fs == static_mode_list[i]->Fs &&\n               (frame_size<<j) == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts)\n         {\n            if (error)\n               *error = OPUS_OK;\n            return (CELTMode*)static_mode_list[i];\n         }\n      }\n   }\n#endif /* CUSTOM_MODES_ONLY */\n\n#ifndef CUSTOM_MODES\n   if (error)\n      *error = OPUS_BAD_ARG;\n   return NULL;\n#else\n\n   /* The good thing here is that permutation of the arguments will automatically be invalid */\n\n   if (Fs < 8000 || Fs > 96000)\n   {\n      if (error)\n         *error = OPUS_BAD_ARG;\n      return NULL;\n   }\n   if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0)\n   {\n      if (error)\n         *error = OPUS_BAD_ARG;\n      return NULL;\n   }\n   /* Frames of less than 1ms are not supported. */\n   if ((opus_int32)frame_size*1000 < Fs)\n   {\n      if (error)\n         *error = OPUS_BAD_ARG;\n      return NULL;\n   }\n\n   if ((opus_int32)frame_size*75 >= Fs && (frame_size%16)==0)\n   {\n     LM = 3;\n   } else if ((opus_int32)frame_size*150 >= Fs && (frame_size%8)==0)\n   {\n     LM = 2;\n   } else if ((opus_int32)frame_size*300 >= Fs && (frame_size%4)==0)\n   {\n     LM = 1;\n   } else\n   {\n     LM = 0;\n   }\n\n   /* Shorts longer than 3.3ms are not supported. */\n   if ((opus_int32)(frame_size>>LM)*300 > Fs)\n   {\n      if (error)\n         *error = OPUS_BAD_ARG;\n      return NULL;\n   }\n\n   mode = opus_alloc(sizeof(CELTMode));\n   if (mode==NULL)\n      goto failure;\n   mode->Fs = Fs;\n\n   /* Pre/de-emphasis depends on sampling rate. The \"standard\" pre-emphasis\n      is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should\n      approximate that. */\n   if(Fs < 12000) /* 8 kHz */\n   {\n      mode->preemph[0] =  QCONST16(0.3500061035f, 15);\n      mode->preemph[1] = -QCONST16(0.1799926758f, 15);\n      mode->preemph[2] =  QCONST16(0.2719968125f, SIG_SHIFT); /* exact 1/preemph[3] */\n      mode->preemph[3] =  QCONST16(3.6765136719f, 13);\n   } else if(Fs < 24000) /* 16 kHz */\n   {\n      mode->preemph[0] =  QCONST16(0.6000061035f, 15);\n      mode->preemph[1] = -QCONST16(0.1799926758f, 15);\n      mode->preemph[2] =  QCONST16(0.4424998650f, SIG_SHIFT); /* exact 1/preemph[3] */\n      mode->preemph[3] =  QCONST16(2.2598876953f, 13);\n   } else if(Fs < 40000) /* 32 kHz */\n   {\n      mode->preemph[0] =  QCONST16(0.7799987793f, 15);\n      mode->preemph[1] = -QCONST16(0.1000061035f, 15);\n      mode->preemph[2] =  QCONST16(0.7499771125f, SIG_SHIFT); /* exact 1/preemph[3] */\n      mode->preemph[3] =  QCONST16(1.3333740234f, 13);\n   } else /* 48 kHz */\n   {\n      mode->preemph[0] =  QCONST16(0.8500061035f, 15);\n      mode->preemph[1] =  QCONST16(0.0f, 15);\n      mode->preemph[2] =  QCONST16(1.f, SIG_SHIFT);\n      mode->preemph[3] =  QCONST16(1.f, 13);\n   }\n\n   mode->maxLM = LM;\n   mode->nbShortMdcts = 1<<LM;\n   mode->shortMdctSize = frame_size/mode->nbShortMdcts;\n   res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);\n\n   mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);\n   if (mode->eBands==NULL)\n      goto failure;\n#if !defined(SMALL_FOOTPRINT)\n   /* Make sure we don't allocate a band larger than our PVQ table.\n      208 should be enough, but let's be paranoid. */\n   if ((mode->eBands[mode->nbEBands] - mode->eBands[mode->nbEBands-1])<<LM >\n    208) {\n       goto failure;\n   }\n#endif\n\n   mode->effEBands = mode->nbEBands;\n   while (mode->eBands[mode->effEBands] > mode->shortMdctSize)\n      mode->effEBands--;\n\n   /* Overlap must be divisible by 4 */\n   mode->overlap = ((mode->shortMdctSize>>2)<<2);\n\n   compute_allocation_table(mode);\n   if (mode->allocVectors==NULL)\n      goto failure;\n\n   window = (opus_val16*)opus_alloc(mode->overlap*sizeof(opus_val16));\n   if (window==NULL)\n      goto failure;\n\n#ifndef FIXED_POINT\n   for (i=0;i<mode->overlap;i++)\n      window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap));\n#else\n   for (i=0;i<mode->overlap;i++)\n      window[i] = MIN32(32767,floor(.5+32768.*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap))));\n#endif\n   mode->window = window;\n\n   logN = (opus_int16*)opus_alloc(mode->nbEBands*sizeof(opus_int16));\n   if (logN==NULL)\n      goto failure;\n\n   for (i=0;i<mode->nbEBands;i++)\n      logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);\n   mode->logN = logN;\n\n   compute_pulse_cache(mode, mode->maxLM);\n\n   if (clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts,\n           mode->maxLM, arch) == 0)\n      goto failure;\n\n   if (error)\n      *error = OPUS_OK;\n\n   return mode;\nfailure:\n   if (error)\n      *error = OPUS_ALLOC_FAIL;\n   if (mode!=NULL)\n      opus_custom_mode_destroy(mode);\n   return NULL;\n#endif /* !CUSTOM_MODES */\n}\n\n#ifdef CUSTOM_MODES\nvoid opus_custom_mode_destroy(CELTMode *mode)\n{\n   int arch = opus_select_arch();\n\n   if (mode == NULL)\n      return;\n#ifndef CUSTOM_MODES_ONLY\n   {\n     int i;\n     for (i=0;i<TOTAL_MODES;i++)\n     {\n        if (mode == static_mode_list[i])\n        {\n           return;\n        }\n     }\n   }\n#endif /* CUSTOM_MODES_ONLY */\n   opus_free((opus_int16*)mode->eBands);\n   opus_free((opus_int16*)mode->allocVectors);\n\n   opus_free((opus_val16*)mode->window);\n   opus_free((opus_int16*)mode->logN);\n\n   opus_free((opus_int16*)mode->cache.index);\n   opus_free((unsigned char*)mode->cache.bits);\n   opus_free((unsigned char*)mode->cache.caps);\n   clt_mdct_clear(&mode->mdct, arch);\n\n   opus_free((CELTMode *)mode);\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/modes.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Copyright (c) 2008 Gregory Maxwell\n   Written by Jean-Marc Valin and Gregory Maxwell */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef MODES_H\n#define MODES_H\n\n#include \"opus_types.h\"\n#include \"celt.h\"\n#include \"arch.h\"\n#include \"mdct.h\"\n#include \"entenc.h\"\n#include \"entdec.h\"\n\n#define MAX_PERIOD 1024\n\ntypedef struct {\n   int size;\n   const opus_int16 *index;\n   const unsigned char *bits;\n   const unsigned char *caps;\n} PulseCache;\n\n/** Mode definition (opaque)\n @brief Mode definition\n */\nstruct OpusCustomMode {\n   opus_int32 Fs;\n   int          overlap;\n\n   int          nbEBands;\n   int          effEBands;\n   opus_val16    preemph[4];\n   const opus_int16   *eBands;   /**< Definition for each \"pseudo-critical band\" */\n\n   int         maxLM;\n   int         nbShortMdcts;\n   int         shortMdctSize;\n\n   int          nbAllocVectors; /**< Number of lines in the matrix below */\n   const unsigned char   *allocVectors;   /**< Number of bits in each band for several rates */\n   const opus_int16 *logN;\n\n   const opus_val16 *window;\n   mdct_lookup mdct;\n   PulseCache cache;\n};\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/opus_custom_demo.c",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"opus_custom.h\"\n#include \"arch.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <math.h>\n#include <string.h>\n\n#define MAX_PACKET 1275\n\nint main(int argc, char *argv[])\n{\n   int err;\n   char *inFile, *outFile;\n   FILE *fin, *fout;\n   OpusCustomMode *mode=NULL;\n   OpusCustomEncoder *enc;\n   OpusCustomDecoder *dec;\n   int len;\n   opus_int32 frame_size, channels, rate;\n   int bytes_per_packet;\n   unsigned char data[MAX_PACKET];\n   int complexity;\n#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)\n   int i;\n   double rmsd = 0;\n#endif\n   int count = 0;\n   opus_int32 skip;\n   opus_int16 *in, *out;\n   if (argc != 9 && argc != 8 && argc != 7)\n   {\n      fprintf (stderr, \"Usage: test_opus_custom <rate> <channels> <frame size> \"\n               \" <bytes per packet> [<complexity> [packet loss rate]] \"\n               \"<input> <output>\\n\");\n      return 1;\n   }\n\n   rate = (opus_int32)atol(argv[1]);\n   channels = atoi(argv[2]);\n   frame_size = atoi(argv[3]);\n   mode = opus_custom_mode_create(rate, frame_size, NULL);\n   if (mode == NULL)\n   {\n      fprintf(stderr, \"failed to create a mode\\n\");\n      return 1;\n   }\n\n   bytes_per_packet = atoi(argv[4]);\n   if (bytes_per_packet < 0 || bytes_per_packet > MAX_PACKET)\n   {\n      fprintf (stderr, \"bytes per packet must be between 0 and %d\\n\",\n                        MAX_PACKET);\n      return 1;\n   }\n\n   inFile = argv[argc-2];\n   fin = fopen(inFile, \"rb\");\n   if (!fin)\n   {\n      fprintf (stderr, \"Could not open input file %s\\n\", argv[argc-2]);\n      return 1;\n   }\n   outFile = argv[argc-1];\n   fout = fopen(outFile, \"wb+\");\n   if (!fout)\n   {\n      fprintf (stderr, \"Could not open output file %s\\n\", argv[argc-1]);\n      fclose(fin);\n      return 1;\n   }\n\n   enc = opus_custom_encoder_create(mode, channels, &err);\n   if (err != 0)\n   {\n      fprintf(stderr, \"Failed to create the encoder: %s\\n\", opus_strerror(err));\n      fclose(fin);\n      fclose(fout);\n      return 1;\n   }\n   dec = opus_custom_decoder_create(mode, channels, &err);\n   if (err != 0)\n   {\n      fprintf(stderr, \"Failed to create the decoder: %s\\n\", opus_strerror(err));\n      fclose(fin);\n      fclose(fout);\n      return 1;\n   }\n   opus_custom_decoder_ctl(dec, OPUS_GET_LOOKAHEAD(&skip));\n\n   if (argc>7)\n   {\n      complexity=atoi(argv[5]);\n      opus_custom_encoder_ctl(enc,OPUS_SET_COMPLEXITY(complexity));\n   }\n\n   in = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16));\n   out = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16));\n\n   while (!feof(fin))\n   {\n      int ret;\n      err = fread(in, sizeof(short), frame_size*channels, fin);\n      if (feof(fin))\n         break;\n      len = opus_custom_encode(enc, in, frame_size, data, bytes_per_packet);\n      if (len <= 0)\n         fprintf (stderr, \"opus_custom_encode() failed: %s\\n\", opus_strerror(len));\n\n      /* This is for simulating bit errors */\n#if 0\n      int errors = 0;\n      int eid = 0;\n      /* This simulates random bit error */\n      for (i=0;i<len*8;i++)\n      {\n         if (rand()%atoi(argv[8])==0)\n         {\n            if (i<64)\n            {\n               errors++;\n               eid = i;\n            }\n            data[i/8] ^= 1<<(7-(i%8));\n         }\n      }\n      if (errors == 1)\n         data[eid/8] ^= 1<<(7-(eid%8));\n      else if (errors%2 == 1)\n         data[rand()%8] ^= 1<<rand()%8;\n#endif\n\n#if 1 /* Set to zero to use the encoder's output instead */\n      /* This is to simulate packet loss */\n      if (argc==9 && rand()%1000<atoi(argv[argc-3]))\n      /*if (errors && (errors%2==0))*/\n         ret = opus_custom_decode(dec, NULL, len, out, frame_size);\n      else\n         ret = opus_custom_decode(dec, data, len, out, frame_size);\n      if (ret < 0)\n         fprintf(stderr, \"opus_custom_decode() failed: %s\\n\", opus_strerror(ret));\n#else\n      for (i=0;i<ret*channels;i++)\n         out[i] = in[i];\n#endif\n#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)\n      for (i=0;i<ret*channels;i++)\n      {\n         rmsd += (in[i]-out[i])*1.0*(in[i]-out[i]);\n         /*out[i] -= in[i];*/\n      }\n#endif\n      count++;\n      fwrite(out+skip*channels, sizeof(short), (ret-skip)*channels, fout);\n      skip = 0;\n   }\n   PRINT_MIPS(stderr);\n\n   opus_custom_encoder_destroy(enc);\n   opus_custom_decoder_destroy(dec);\n   fclose(fin);\n   fclose(fout);\n   opus_custom_mode_destroy(mode);\n   free(in);\n   free(out);\n#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)\n   if (rmsd > 0)\n   {\n      rmsd = sqrt(rmsd/(1.0*frame_size*channels*count));\n      fprintf (stderr, \"Error: encoder doesn't match decoder\\n\");\n      fprintf (stderr, \"RMS mismatch is %f\\n\", rmsd);\n      return 1;\n   } else {\n      fprintf (stderr, \"Encoder matches decoder!!\\n\");\n   }\n#endif\n   return 0;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/os_support.h",
    "content": "/* Copyright (C) 2007 Jean-Marc Valin\n\n   File: os_support.h\n   This is the (tiny) OS abstraction layer. Aside from math.h, this is the\n   only place where system headers are allowed.\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef OS_SUPPORT_H\n#define OS_SUPPORT_H\n\n#ifdef CUSTOM_SUPPORT\n#  include \"custom_support.h\"\n#endif\n\n#include \"opus_types.h\"\n#include \"opus_defines.h\"\n\n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n/** Opus wrapper for malloc(). To do your own dynamic allocation, all you need to do is replace this function and opus_free */\n#ifndef OVERRIDE_OPUS_ALLOC\nstatic OPUS_INLINE void *opus_alloc (size_t size)\n{\n   return malloc(size);\n}\n#endif\n\n/** Same as celt_alloc(), except that the area is only needed inside a CELT call (might cause problem with wideband though) */\n#ifndef OVERRIDE_OPUS_ALLOC_SCRATCH\nstatic OPUS_INLINE void *opus_alloc_scratch (size_t size)\n{\n   /* Scratch space doesn't need to be cleared */\n   return opus_alloc(size);\n}\n#endif\n\n/** Opus wrapper for free(). To do your own dynamic allocation, all you need to do is replace this function and opus_alloc */\n#ifndef OVERRIDE_OPUS_FREE\nstatic OPUS_INLINE void opus_free (void *ptr)\n{\n   free(ptr);\n}\n#endif\n\n/** Copy n elements from src to dst. The 0* term provides compile-time type checking  */\n#ifndef OVERRIDE_OPUS_COPY\n#define OPUS_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))\n#endif\n\n/** Copy n elements from src to dst, allowing overlapping regions. The 0* term\n    provides compile-time type checking */\n#ifndef OVERRIDE_OPUS_MOVE\n#define OPUS_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))\n#endif\n\n/** Set n elements of dst to zero */\n#ifndef OVERRIDE_OPUS_CLEAR\n#define OPUS_CLEAR(dst, n) (memset((dst), 0, (n)*sizeof(*(dst))))\n#endif\n\n/*#ifdef __GNUC__\n#pragma GCC poison printf sprintf\n#pragma GCC poison malloc free realloc calloc\n#endif*/\n\n#endif /* OS_SUPPORT_H */\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/pitch.c",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/**\n   @file pitch.c\n   @brief Pitch analysis\n */\n\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"pitch.h\"\n#include \"os_support.h\"\n#include \"modes.h\"\n#include \"stack_alloc.h\"\n#include \"mathops.h\"\n#include \"celt_lpc.h\"\n\nstatic void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len,\n                            int max_pitch, int *best_pitch\n#ifdef FIXED_POINT\n                            , int yshift, opus_val32 maxcorr\n#endif\n                            )\n{\n   int i, j;\n   opus_val32 Syy=1;\n   opus_val16 best_num[2];\n   opus_val32 best_den[2];\n#ifdef FIXED_POINT\n   int xshift;\n\n   xshift = celt_ilog2(maxcorr)-14;\n#endif\n\n   best_num[0] = -1;\n   best_num[1] = -1;\n   best_den[0] = 0;\n   best_den[1] = 0;\n   best_pitch[0] = 0;\n   best_pitch[1] = 1;\n   for (j=0;j<len;j++)\n      Syy = ADD32(Syy, SHR32(MULT16_16(y[j],y[j]), yshift));\n   for (i=0;i<max_pitch;i++)\n   {\n      if (xcorr[i]>0)\n      {\n         opus_val16 num;\n         opus_val32 xcorr16;\n         xcorr16 = EXTRACT16(VSHR32(xcorr[i], xshift));\n#ifndef FIXED_POINT\n         /* Considering the range of xcorr16, this should avoid both underflows\n            and overflows (inf) when squaring xcorr16 */\n         xcorr16 *= 1e-12f;\n#endif\n         num = MULT16_16_Q15(xcorr16,xcorr16);\n         if (MULT16_32_Q15(num,best_den[1]) > MULT16_32_Q15(best_num[1],Syy))\n         {\n            if (MULT16_32_Q15(num,best_den[0]) > MULT16_32_Q15(best_num[0],Syy))\n            {\n               best_num[1] = best_num[0];\n               best_den[1] = best_den[0];\n               best_pitch[1] = best_pitch[0];\n               best_num[0] = num;\n               best_den[0] = Syy;\n               best_pitch[0] = i;\n            } else {\n               best_num[1] = num;\n               best_den[1] = Syy;\n               best_pitch[1] = i;\n            }\n         }\n      }\n      Syy += SHR32(MULT16_16(y[i+len],y[i+len]),yshift) - SHR32(MULT16_16(y[i],y[i]),yshift);\n      Syy = MAX32(1, Syy);\n   }\n}\n\nstatic void celt_fir5(const opus_val16 *x,\n         const opus_val16 *num,\n         opus_val16 *y,\n         int N,\n         opus_val16 *mem)\n{\n   int i;\n   opus_val16 num0, num1, num2, num3, num4;\n   opus_val32 mem0, mem1, mem2, mem3, mem4;\n   num0=num[0];\n   num1=num[1];\n   num2=num[2];\n   num3=num[3];\n   num4=num[4];\n   mem0=mem[0];\n   mem1=mem[1];\n   mem2=mem[2];\n   mem3=mem[3];\n   mem4=mem[4];\n   for (i=0;i<N;i++)\n   {\n      opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);\n      sum = MAC16_16(sum,num0,mem0);\n      sum = MAC16_16(sum,num1,mem1);\n      sum = MAC16_16(sum,num2,mem2);\n      sum = MAC16_16(sum,num3,mem3);\n      sum = MAC16_16(sum,num4,mem4);\n      mem4 = mem3;\n      mem3 = mem2;\n      mem2 = mem1;\n      mem1 = mem0;\n      mem0 = x[i];\n      y[i] = ROUND16(sum, SIG_SHIFT);\n   }\n   mem[0]=mem0;\n   mem[1]=mem1;\n   mem[2]=mem2;\n   mem[3]=mem3;\n   mem[4]=mem4;\n}\n\n\nvoid pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp,\n      int len, int C, int arch)\n{\n   int i;\n   opus_val32 ac[5];\n   opus_val16 tmp=Q15ONE;\n   opus_val16 lpc[4], mem[5]={0,0,0,0,0};\n   opus_val16 lpc2[5];\n   opus_val16 c1 = QCONST16(.8f,15);\n#ifdef FIXED_POINT\n   int shift;\n   opus_val32 maxabs = celt_maxabs32(x[0], len);\n   if (C==2)\n   {\n      opus_val32 maxabs_1 = celt_maxabs32(x[1], len);\n      maxabs = MAX32(maxabs, maxabs_1);\n   }\n   if (maxabs<1)\n      maxabs=1;\n   shift = celt_ilog2(maxabs)-10;\n   if (shift<0)\n      shift=0;\n   if (C==2)\n      shift++;\n#endif\n   for (i=1;i<len>>1;i++)\n      x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), shift);\n   x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), shift);\n   if (C==2)\n   {\n      for (i=1;i<len>>1;i++)\n         x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), shift);\n      x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), shift);\n   }\n\n   _celt_autocorr(x_lp, ac, NULL, 0,\n                  4, len>>1, arch);\n\n   /* Noise floor -40 dB */\n#ifdef FIXED_POINT\n   ac[0] += SHR32(ac[0],13);\n#else\n   ac[0] *= 1.0001f;\n#endif\n   /* Lag windowing */\n   for (i=1;i<=4;i++)\n   {\n      /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/\n#ifdef FIXED_POINT\n      ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);\n#else\n      ac[i] -= ac[i]*(.008f*i)*(.008f*i);\n#endif\n   }\n\n   _celt_lpc(lpc, ac, 4);\n   for (i=0;i<4;i++)\n   {\n      tmp = MULT16_16_Q15(QCONST16(.9f,15), tmp);\n      lpc[i] = MULT16_16_Q15(lpc[i], tmp);\n   }\n   /* Add a zero */\n   lpc2[0] = lpc[0] + QCONST16(.8f,SIG_SHIFT);\n   lpc2[1] = lpc[1] + MULT16_16_Q15(c1,lpc[0]);\n   lpc2[2] = lpc[2] + MULT16_16_Q15(c1,lpc[1]);\n   lpc2[3] = lpc[3] + MULT16_16_Q15(c1,lpc[2]);\n   lpc2[4] = MULT16_16_Q15(c1,lpc[3]);\n   celt_fir5(x_lp, lpc2, x_lp, len>>1, mem);\n}\n\n/* Pure C implementation. */\n#ifdef FIXED_POINT\nopus_val32\n#else\nvoid\n#endif\n#if defined(OVERRIDE_PITCH_XCORR)\ncelt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,\n      opus_val32 *xcorr, int len, int max_pitch)\n#else\ncelt_pitch_xcorr(const opus_val16 *_x, const opus_val16 *_y,\n      opus_val32 *xcorr, int len, int max_pitch, int arch)\n#endif\n{\n\n#if 0 /* This is a simple version of the pitch correlation that should work\n         well on DSPs like Blackfin and TI C5x/C6x */\n   int i, j;\n#ifdef FIXED_POINT\n   opus_val32 maxcorr=1;\n#endif\n#if !defined(OVERRIDE_PITCH_XCORR)\n   (void)arch;\n#endif\n   for (i=0;i<max_pitch;i++)\n   {\n      opus_val32 sum = 0;\n      for (j=0;j<len;j++)\n         sum = MAC16_16(sum, _x[j], _y[i+j]);\n      xcorr[i] = sum;\n#ifdef FIXED_POINT\n      maxcorr = MAX32(maxcorr, sum);\n#endif\n   }\n#ifdef FIXED_POINT\n   return maxcorr;\n#endif\n\n#else /* Unrolled version of the pitch correlation -- runs faster on x86 and ARM */\n   int i;\n   /*The EDSP version requires that max_pitch is at least 1, and that _x is\n      32-bit aligned.\n     Since it's hard to put asserts in assembly, put them here.*/\n#ifdef FIXED_POINT\n   opus_val32 maxcorr=1;\n#endif\n   celt_assert(max_pitch>0);\n   celt_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);\n   for (i=0;i<max_pitch-3;i+=4)\n   {\n      opus_val32 sum[4]={0,0,0,0};\n#if defined(OVERRIDE_PITCH_XCORR)\n      xcorr_kernel_c(_x, _y+i, sum, len);\n#else\n      xcorr_kernel(_x, _y+i, sum, len, arch);\n#endif\n      xcorr[i]=sum[0];\n      xcorr[i+1]=sum[1];\n      xcorr[i+2]=sum[2];\n      xcorr[i+3]=sum[3];\n#ifdef FIXED_POINT\n      sum[0] = MAX32(sum[0], sum[1]);\n      sum[2] = MAX32(sum[2], sum[3]);\n      sum[0] = MAX32(sum[0], sum[2]);\n      maxcorr = MAX32(maxcorr, sum[0]);\n#endif\n   }\n   /* In case max_pitch isn't a multiple of 4, do non-unrolled version. */\n   for (;i<max_pitch;i++)\n   {\n      opus_val32 sum;\n#if defined(OVERRIDE_PITCH_XCORR)\n      sum = celt_inner_prod_c(_x, _y+i, len);\n#else\n      sum = celt_inner_prod(_x, _y+i, len, arch);\n#endif\n      xcorr[i] = sum;\n#ifdef FIXED_POINT\n      maxcorr = MAX32(maxcorr, sum);\n#endif\n   }\n#ifdef FIXED_POINT\n   return maxcorr;\n#endif\n#endif\n}\n\nvoid pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y,\n                  int len, int max_pitch, int *pitch, int arch)\n{\n   int i, j;\n   int lag;\n   int best_pitch[2]={0,0};\n   VARDECL(opus_val16, x_lp4);\n   VARDECL(opus_val16, y_lp4);\n   VARDECL(opus_val32, xcorr);\n#ifdef FIXED_POINT\n   opus_val32 maxcorr;\n   opus_val32 xmax, ymax;\n   int shift=0;\n#endif\n   int offset;\n\n   SAVE_STACK;\n\n   celt_assert(len>0);\n   celt_assert(max_pitch>0);\n   lag = len+max_pitch;\n\n   ALLOC(x_lp4, len>>2, opus_val16);\n   ALLOC(y_lp4, lag>>2, opus_val16);\n   ALLOC(xcorr, max_pitch>>1, opus_val32);\n\n   /* Downsample by 2 again */\n   for (j=0;j<len>>2;j++)\n      x_lp4[j] = x_lp[2*j];\n   for (j=0;j<lag>>2;j++)\n      y_lp4[j] = y[2*j];\n\n#ifdef FIXED_POINT\n   xmax = celt_maxabs16(x_lp4, len>>2);\n   ymax = celt_maxabs16(y_lp4, lag>>2);\n   shift = celt_ilog2(MAX32(1, MAX32(xmax, ymax)))-11;\n   if (shift>0)\n   {\n      for (j=0;j<len>>2;j++)\n         x_lp4[j] = SHR16(x_lp4[j], shift);\n      for (j=0;j<lag>>2;j++)\n         y_lp4[j] = SHR16(y_lp4[j], shift);\n      /* Use double the shift for a MAC */\n      shift *= 2;\n   } else {\n      shift = 0;\n   }\n#endif\n\n   /* Coarse search with 4x decimation */\n\n#ifdef FIXED_POINT\n   maxcorr =\n#endif\n   celt_pitch_xcorr(x_lp4, y_lp4, xcorr, len>>2, max_pitch>>2, arch);\n\n   find_best_pitch(xcorr, y_lp4, len>>2, max_pitch>>2, best_pitch\n#ifdef FIXED_POINT\n                   , 0, maxcorr\n#endif\n                   );\n\n   /* Finer search with 2x decimation */\n#ifdef FIXED_POINT\n   maxcorr=1;\n#endif\n   for (i=0;i<max_pitch>>1;i++)\n   {\n      opus_val32 sum;\n      xcorr[i] = 0;\n      if (abs(i-2*best_pitch[0])>2 && abs(i-2*best_pitch[1])>2)\n         continue;\n#ifdef FIXED_POINT\n      sum = 0;\n      for (j=0;j<len>>1;j++)\n         sum += SHR32(MULT16_16(x_lp[j],y[i+j]), shift);\n#else\n      sum = celt_inner_prod_c(x_lp, y+i, len>>1);\n#endif\n      xcorr[i] = MAX32(-1, sum);\n#ifdef FIXED_POINT\n      maxcorr = MAX32(maxcorr, sum);\n#endif\n   }\n   find_best_pitch(xcorr, y, len>>1, max_pitch>>1, best_pitch\n#ifdef FIXED_POINT\n                   , shift+1, maxcorr\n#endif\n                   );\n\n   /* Refine by pseudo-interpolation */\n   if (best_pitch[0]>0 && best_pitch[0]<(max_pitch>>1)-1)\n   {\n      opus_val32 a, b, c;\n      a = xcorr[best_pitch[0]-1];\n      b = xcorr[best_pitch[0]];\n      c = xcorr[best_pitch[0]+1];\n      if ((c-a) > MULT16_32_Q15(QCONST16(.7f,15),b-a))\n         offset = 1;\n      else if ((a-c) > MULT16_32_Q15(QCONST16(.7f,15),b-c))\n         offset = -1;\n      else\n         offset = 0;\n   } else {\n      offset = 0;\n   }\n   *pitch = 2*best_pitch[0]-offset;\n\n   RESTORE_STACK;\n}\n\nstatic const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2};\nopus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,\n      int N, int *T0_, int prev_period, opus_val16 prev_gain, int arch)\n{\n   int k, i, T, T0;\n   opus_val16 g, g0;\n   opus_val16 pg;\n   opus_val32 xy,xx,yy,xy2;\n   opus_val32 xcorr[3];\n   opus_val32 best_xy, best_yy;\n   int offset;\n   int minperiod0;\n   VARDECL(opus_val32, yy_lookup);\n   SAVE_STACK;\n\n   minperiod0 = minperiod;\n   maxperiod /= 2;\n   minperiod /= 2;\n   *T0_ /= 2;\n   prev_period /= 2;\n   N /= 2;\n   x += maxperiod;\n   if (*T0_>=maxperiod)\n      *T0_=maxperiod-1;\n\n   T = T0 = *T0_;\n   ALLOC(yy_lookup, maxperiod+1, opus_val32);\n   dual_inner_prod(x, x, x-T0, N, &xx, &xy, arch);\n   yy_lookup[0] = xx;\n   yy=xx;\n   for (i=1;i<=maxperiod;i++)\n   {\n      yy = yy+MULT16_16(x[-i],x[-i])-MULT16_16(x[N-i],x[N-i]);\n      yy_lookup[i] = MAX32(0, yy);\n   }\n   yy = yy_lookup[T0];\n   best_xy = xy;\n   best_yy = yy;\n#ifdef FIXED_POINT\n      {\n         opus_val32 x2y2;\n         int sh, t;\n         x2y2 = 1+HALF32(MULT32_32_Q31(xx,yy));\n         sh = celt_ilog2(x2y2)>>1;\n         t = VSHR32(x2y2, 2*(sh-7));\n         g = g0 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);\n      }\n#else\n      g = g0 = xy/celt_sqrt(1+xx*yy);\n#endif\n   /* Look for any pitch at T/k */\n   for (k=2;k<=15;k++)\n   {\n      int T1, T1b;\n      opus_val16 g1;\n      opus_val16 cont=0;\n      opus_val16 thresh;\n      T1 = celt_udiv(2*T0+k, 2*k);\n      if (T1 < minperiod)\n         break;\n      /* Look for another strong correlation at T1b */\n      if (k==2)\n      {\n         if (T1+T0>maxperiod)\n            T1b = T0;\n         else\n            T1b = T0+T1;\n      } else\n      {\n         T1b = celt_udiv(2*second_check[k]*T0+k, 2*k);\n      }\n      dual_inner_prod(x, &x[-T1], &x[-T1b], N, &xy, &xy2, arch);\n      xy += xy2;\n      yy = yy_lookup[T1] + yy_lookup[T1b];\n#ifdef FIXED_POINT\n      {\n         opus_val32 x2y2;\n         int sh, t;\n         x2y2 = 1+MULT32_32_Q31(xx,yy);\n         sh = celt_ilog2(x2y2)>>1;\n         t = VSHR32(x2y2, 2*(sh-7));\n         g1 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);\n      }\n#else\n      g1 = xy/celt_sqrt(1+2.f*xx*1.f*yy);\n#endif\n      if (abs(T1-prev_period)<=1)\n         cont = prev_gain;\n      else if (abs(T1-prev_period)<=2 && 5*k*k < T0)\n         cont = HALF32(prev_gain);\n      else\n         cont = 0;\n      thresh = MAX16(QCONST16(.3f,15), MULT16_16_Q15(QCONST16(.7f,15),g0)-cont);\n      /* Bias against very high pitch (very short period) to avoid false-positives\n         due to short-term correlation */\n      if (T1<3*minperiod)\n         thresh = MAX16(QCONST16(.4f,15), MULT16_16_Q15(QCONST16(.85f,15),g0)-cont);\n      else if (T1<2*minperiod)\n         thresh = MAX16(QCONST16(.5f,15), MULT16_16_Q15(QCONST16(.9f,15),g0)-cont);\n      if (g1 > thresh)\n      {\n         best_xy = xy;\n         best_yy = yy;\n         T = T1;\n         g = g1;\n      }\n   }\n   best_xy = MAX32(0, best_xy);\n   if (best_yy <= best_xy)\n      pg = Q15ONE;\n   else\n      pg = SHR32(frac_div32(best_xy,best_yy+1),16);\n\n   for (k=0;k<3;k++)\n      xcorr[k] = celt_inner_prod(x, x-(T+k-1), N, arch);\n   if ((xcorr[2]-xcorr[0]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[0]))\n      offset = 1;\n   else if ((xcorr[0]-xcorr[2]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[2]))\n      offset = -1;\n   else\n      offset = 0;\n   if (pg > g)\n      pg = g;\n   *T0_ = 2*T+offset;\n\n   if (*T0_<minperiod0)\n      *T0_=minperiod0;\n   RESTORE_STACK;\n   return pg;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/pitch.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/**\n   @file pitch.h\n   @brief Pitch analysis\n */\n\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef PITCH_H\n#define PITCH_H\n\n#include \"modes.h\"\n#include \"cpu_support.h\"\n\n#if (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT)) \\\n  || ((defined(OPUS_X86_MAY_HAVE_SSE4_1) || defined(OPUS_X86_MAY_HAVE_SSE2)) && defined(FIXED_POINT))\n#include \"x86/pitch_sse.h\"\n#endif\n\n#if defined(MIPSr1_ASM)\n#include \"mips/pitch_mipsr1.h\"\n#endif\n\n#if ((defined(OPUS_ARM_ASM) && defined(FIXED_POINT)) \\\n  || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))\n# include \"arm/pitch_arm.h\"\n#endif\n\nvoid pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp,\n      int len, int C, int arch);\n\nvoid pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y,\n                  int len, int max_pitch, int *pitch, int arch);\n\nopus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,\n      int N, int *T0, int prev_period, opus_val16 prev_gain, int arch);\n\n\n/* OPT: This is the kernel you really want to optimize. It gets used a lot\n   by the prefilter and by the PLC. */\nstatic OPUS_INLINE void xcorr_kernel_c(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[4], int len)\n{\n   int j;\n   opus_val16 y_0, y_1, y_2, y_3;\n   celt_assert(len>=3);\n   y_3=0; /* gcc doesn't realize that y_3 can't be used uninitialized */\n   y_0=*y++;\n   y_1=*y++;\n   y_2=*y++;\n   for (j=0;j<len-3;j+=4)\n   {\n      opus_val16 tmp;\n      tmp = *x++;\n      y_3=*y++;\n      sum[0] = MAC16_16(sum[0],tmp,y_0);\n      sum[1] = MAC16_16(sum[1],tmp,y_1);\n      sum[2] = MAC16_16(sum[2],tmp,y_2);\n      sum[3] = MAC16_16(sum[3],tmp,y_3);\n      tmp=*x++;\n      y_0=*y++;\n      sum[0] = MAC16_16(sum[0],tmp,y_1);\n      sum[1] = MAC16_16(sum[1],tmp,y_2);\n      sum[2] = MAC16_16(sum[2],tmp,y_3);\n      sum[3] = MAC16_16(sum[3],tmp,y_0);\n      tmp=*x++;\n      y_1=*y++;\n      sum[0] = MAC16_16(sum[0],tmp,y_2);\n      sum[1] = MAC16_16(sum[1],tmp,y_3);\n      sum[2] = MAC16_16(sum[2],tmp,y_0);\n      sum[3] = MAC16_16(sum[3],tmp,y_1);\n      tmp=*x++;\n      y_2=*y++;\n      sum[0] = MAC16_16(sum[0],tmp,y_3);\n      sum[1] = MAC16_16(sum[1],tmp,y_0);\n      sum[2] = MAC16_16(sum[2],tmp,y_1);\n      sum[3] = MAC16_16(sum[3],tmp,y_2);\n   }\n   if (j++<len)\n   {\n      opus_val16 tmp = *x++;\n      y_3=*y++;\n      sum[0] = MAC16_16(sum[0],tmp,y_0);\n      sum[1] = MAC16_16(sum[1],tmp,y_1);\n      sum[2] = MAC16_16(sum[2],tmp,y_2);\n      sum[3] = MAC16_16(sum[3],tmp,y_3);\n   }\n   if (j++<len)\n   {\n      opus_val16 tmp=*x++;\n      y_0=*y++;\n      sum[0] = MAC16_16(sum[0],tmp,y_1);\n      sum[1] = MAC16_16(sum[1],tmp,y_2);\n      sum[2] = MAC16_16(sum[2],tmp,y_3);\n      sum[3] = MAC16_16(sum[3],tmp,y_0);\n   }\n   if (j<len)\n   {\n      opus_val16 tmp=*x++;\n      y_1=*y++;\n      sum[0] = MAC16_16(sum[0],tmp,y_2);\n      sum[1] = MAC16_16(sum[1],tmp,y_3);\n      sum[2] = MAC16_16(sum[2],tmp,y_0);\n      sum[3] = MAC16_16(sum[3],tmp,y_1);\n   }\n}\n\n#ifndef OVERRIDE_XCORR_KERNEL\n#define xcorr_kernel(x, y, sum, len, arch) \\\n    ((void)(arch),xcorr_kernel_c(x, y, sum, len))\n#endif /* OVERRIDE_XCORR_KERNEL */\n\n\nstatic OPUS_INLINE void dual_inner_prod_c(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,\n      int N, opus_val32 *xy1, opus_val32 *xy2)\n{\n   int i;\n   opus_val32 xy01=0;\n   opus_val32 xy02=0;\n   for (i=0;i<N;i++)\n   {\n      xy01 = MAC16_16(xy01, x[i], y01[i]);\n      xy02 = MAC16_16(xy02, x[i], y02[i]);\n   }\n   *xy1 = xy01;\n   *xy2 = xy02;\n}\n\n#ifndef OVERRIDE_DUAL_INNER_PROD\n# define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) \\\n    ((void)(arch),dual_inner_prod_c(x, y01, y02, N, xy1, xy2))\n#endif\n\n/*We make sure a C version is always available for cases where the overhead of\n  vectorization and passing around an arch flag aren't worth it.*/\nstatic OPUS_INLINE opus_val32 celt_inner_prod_c(const opus_val16 *x,\n      const opus_val16 *y, int N)\n{\n   int i;\n   opus_val32 xy=0;\n   for (i=0;i<N;i++)\n      xy = MAC16_16(xy, x[i], y[i]);\n   return xy;\n}\n\n#if !defined(OVERRIDE_CELT_INNER_PROD)\n# define celt_inner_prod(x, y, N, arch) \\\n    ((void)(arch),celt_inner_prod_c(x, y, N))\n#endif\n\n#ifdef NON_STATIC_COMB_FILTER_CONST_C\nvoid comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,\n     opus_val16 g10, opus_val16 g11, opus_val16 g12);\n#endif\n\n\n#ifdef FIXED_POINT\nopus_val32\n#else\nvoid\n#endif\ncelt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,\n      opus_val32 *xcorr, int len, int max_pitch);\n\n#if !defined(OVERRIDE_PITCH_XCORR)\n/*Is run-time CPU detection enabled on this platform?*/\n# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_ASM) \\\n   || (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) \\\n   && !defined(OPUS_ARM_PRESUME_NEON_INTR)))\nextern\n#  if defined(FIXED_POINT)\nopus_val32\n#  else\nvoid\n#  endif\n(*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,\n      const opus_val16 *, opus_val32 *, int, int);\n\n#  define OVERRIDE_PITCH_XCORR\n#  define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \\\n  ((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \\\n        xcorr, len, max_pitch))\n# else\n\n#ifdef FIXED_POINT\nopus_val32\n#else\nvoid\n#endif\ncelt_pitch_xcorr(const opus_val16 *_x, const opus_val16 *_y,\n      opus_val32 *xcorr, int len, int max_pitch, int arch);\n\n# endif\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/quant_bands.c",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"quant_bands.h\"\n#include \"laplace.h\"\n#include <math.h>\n#include \"os_support.h\"\n#include \"arch.h\"\n#include \"mathops.h\"\n#include \"stack_alloc.h\"\n#include \"rate.h\"\n\n#ifdef FIXED_POINT\n/* Mean energy in each band quantized in Q4 */\nconst signed char eMeans[25] = {\n      103,100, 92, 85, 81,\n       77, 72, 70, 78, 75,\n       73, 71, 78, 74, 69,\n       72, 70, 74, 76, 71,\n       60, 60, 60, 60, 60\n};\n#else\n/* Mean energy in each band quantized in Q4 and converted back to float */\nconst opus_val16 eMeans[25] = {\n      6.437500f, 6.250000f, 5.750000f, 5.312500f, 5.062500f,\n      4.812500f, 4.500000f, 4.375000f, 4.875000f, 4.687500f,\n      4.562500f, 4.437500f, 4.875000f, 4.625000f, 4.312500f,\n      4.500000f, 4.375000f, 4.625000f, 4.750000f, 4.437500f,\n      3.750000f, 3.750000f, 3.750000f, 3.750000f, 3.750000f\n};\n#endif\n/* prediction coefficients: 0.9, 0.8, 0.65, 0.5 */\n#ifdef FIXED_POINT\nstatic const opus_val16 pred_coef[4] = {29440, 26112, 21248, 16384};\nstatic const opus_val16 beta_coef[4] = {30147, 22282, 12124, 6554};\nstatic const opus_val16 beta_intra = 4915;\n#else\nstatic const opus_val16 pred_coef[4] = {29440/32768., 26112/32768., 21248/32768., 16384/32768.};\nstatic const opus_val16 beta_coef[4] = {30147/32768., 22282/32768., 12124/32768., 6554/32768.};\nstatic const opus_val16 beta_intra = 4915/32768.;\n#endif\n\n/*Parameters of the Laplace-like probability models used for the coarse energy.\n  There is one pair of parameters for each frame size, prediction type\n   (inter/intra), and band number.\n  The first number of each pair is the probability of 0, and the second is the\n   decay rate, both in Q8 precision.*/\nstatic const unsigned char e_prob_model[4][2][42] = {\n   /*120 sample frames.*/\n   {\n      /*Inter*/\n      {\n          72, 127,  65, 129,  66, 128,  65, 128,  64, 128,  62, 128,  64, 128,\n          64, 128,  92,  78,  92,  79,  92,  78,  90,  79, 116,  41, 115,  40,\n         114,  40, 132,  26, 132,  26, 145,  17, 161,  12, 176,  10, 177,  11\n      },\n      /*Intra*/\n      {\n          24, 179,  48, 138,  54, 135,  54, 132,  53, 134,  56, 133,  55, 132,\n          55, 132,  61, 114,  70,  96,  74,  88,  75,  88,  87,  74,  89,  66,\n          91,  67, 100,  59, 108,  50, 120,  40, 122,  37,  97,  43,  78,  50\n      }\n   },\n   /*240 sample frames.*/\n   {\n      /*Inter*/\n      {\n          83,  78,  84,  81,  88,  75,  86,  74,  87,  71,  90,  73,  93,  74,\n          93,  74, 109,  40, 114,  36, 117,  34, 117,  34, 143,  17, 145,  18,\n         146,  19, 162,  12, 165,  10, 178,   7, 189,   6, 190,   8, 177,   9\n      },\n      /*Intra*/\n      {\n          23, 178,  54, 115,  63, 102,  66,  98,  69,  99,  74,  89,  71,  91,\n          73,  91,  78,  89,  86,  80,  92,  66,  93,  64, 102,  59, 103,  60,\n         104,  60, 117,  52, 123,  44, 138,  35, 133,  31,  97,  38,  77,  45\n      }\n   },\n   /*480 sample frames.*/\n   {\n      /*Inter*/\n      {\n          61,  90,  93,  60, 105,  42, 107,  41, 110,  45, 116,  38, 113,  38,\n         112,  38, 124,  26, 132,  27, 136,  19, 140,  20, 155,  14, 159,  16,\n         158,  18, 170,  13, 177,  10, 187,   8, 192,   6, 175,   9, 159,  10\n      },\n      /*Intra*/\n      {\n          21, 178,  59, 110,  71,  86,  75,  85,  84,  83,  91,  66,  88,  73,\n          87,  72,  92,  75,  98,  72, 105,  58, 107,  54, 115,  52, 114,  55,\n         112,  56, 129,  51, 132,  40, 150,  33, 140,  29,  98,  35,  77,  42\n      }\n   },\n   /*960 sample frames.*/\n   {\n      /*Inter*/\n      {\n          42, 121,  96,  66, 108,  43, 111,  40, 117,  44, 123,  32, 120,  36,\n         119,  33, 127,  33, 134,  34, 139,  21, 147,  23, 152,  20, 158,  25,\n         154,  26, 166,  21, 173,  16, 184,  13, 184,  10, 150,  13, 139,  15\n      },\n      /*Intra*/\n      {\n          22, 178,  63, 114,  74,  82,  84,  83,  92,  82, 103,  62,  96,  72,\n          96,  67, 101,  73, 107,  72, 113,  55, 118,  52, 125,  52, 118,  52,\n         117,  55, 135,  49, 137,  39, 157,  32, 145,  29,  97,  33,  77,  40\n      }\n   }\n};\n\nstatic const unsigned char small_energy_icdf[3]={2,1,0};\n\nstatic opus_val32 loss_distortion(const opus_val16 *eBands, opus_val16 *oldEBands, int start, int end, int len, int C)\n{\n   int c, i;\n   opus_val32 dist = 0;\n   c=0; do {\n      for (i=start;i<end;i++)\n      {\n         opus_val16 d = SUB16(SHR16(eBands[i+c*len], 3), SHR16(oldEBands[i+c*len], 3));\n         dist = MAC16_16(dist, d,d);\n      }\n   } while (++c<C);\n   return MIN32(200,SHR32(dist,2*DB_SHIFT-6));\n}\n\nstatic int quant_coarse_energy_impl(const CELTMode *m, int start, int end,\n      const opus_val16 *eBands, opus_val16 *oldEBands,\n      opus_int32 budget, opus_int32 tell,\n      const unsigned char *prob_model, opus_val16 *error, ec_enc *enc,\n      int C, int LM, int intra, opus_val16 max_decay, int lfe)\n{\n   int i, c;\n   int badness = 0;\n   opus_val32 prev[2] = {0,0};\n   opus_val16 coef;\n   opus_val16 beta;\n\n   if (tell+3 <= budget)\n      ec_enc_bit_logp(enc, intra, 3);\n   if (intra)\n   {\n      coef = 0;\n      beta = beta_intra;\n   } else {\n      beta = beta_coef[LM];\n      coef = pred_coef[LM];\n   }\n\n   /* Encode at a fixed coarse resolution */\n   for (i=start;i<end;i++)\n   {\n      c=0;\n      do {\n         int bits_left;\n         int qi, qi0;\n         opus_val32 q;\n         opus_val16 x;\n         opus_val32 f, tmp;\n         opus_val16 oldE;\n         opus_val16 decay_bound;\n         x = eBands[i+c*m->nbEBands];\n         oldE = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]);\n#ifdef FIXED_POINT\n         f = SHL32(EXTEND32(x),7) - PSHR32(MULT16_16(coef,oldE), 8) - prev[c];\n         /* Rounding to nearest integer here is really important! */\n         qi = (f+QCONST32(.5f,DB_SHIFT+7))>>(DB_SHIFT+7);\n         decay_bound = EXTRACT16(MAX32(-QCONST16(28.f,DB_SHIFT),\n               SUB32((opus_val32)oldEBands[i+c*m->nbEBands],max_decay)));\n#else\n         f = x-coef*oldE-prev[c];\n         /* Rounding to nearest integer here is really important! */\n         qi = (int)floor(.5f+f);\n         decay_bound = MAX16(-QCONST16(28.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]) - max_decay;\n#endif\n         /* Prevent the energy from going down too quickly (e.g. for bands\n            that have just one bin) */\n         if (qi < 0 && x < decay_bound)\n         {\n            qi += (int)SHR16(SUB16(decay_bound,x), DB_SHIFT);\n            if (qi > 0)\n               qi = 0;\n         }\n         qi0 = qi;\n         /* If we don't have enough bits to encode all the energy, just assume\n             something safe. */\n         tell = ec_tell(enc);\n         bits_left = budget-tell-3*C*(end-i);\n         if (i!=start && bits_left < 30)\n         {\n            if (bits_left < 24)\n               qi = IMIN(1, qi);\n            if (bits_left < 16)\n               qi = IMAX(-1, qi);\n         }\n         if (lfe && i>=2)\n            qi = IMIN(qi, 0);\n         if (budget-tell >= 15)\n         {\n            int pi;\n            pi = 2*IMIN(i,20);\n            ec_laplace_encode(enc, &qi,\n                  prob_model[pi]<<7, prob_model[pi+1]<<6);\n         }\n         else if(budget-tell >= 2)\n         {\n            qi = IMAX(-1, IMIN(qi, 1));\n            ec_enc_icdf(enc, 2*qi^-(qi<0), small_energy_icdf, 2);\n         }\n         else if(budget-tell >= 1)\n         {\n            qi = IMIN(0, qi);\n            ec_enc_bit_logp(enc, -qi, 1);\n         }\n         else\n            qi = -1;\n         error[i+c*m->nbEBands] = PSHR32(f,7) - SHL16(qi,DB_SHIFT);\n         badness += abs(qi0-qi);\n         q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT);\n\n         tmp = PSHR32(MULT16_16(coef,oldE),8) + prev[c] + SHL32(q,7);\n#ifdef FIXED_POINT\n         tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp);\n#endif\n         oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7);\n         prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8));\n      } while (++c < C);\n   }\n   return lfe ? 0 : badness;\n}\n\nvoid quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,\n      const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget,\n      opus_val16 *error, ec_enc *enc, int C, int LM, int nbAvailableBytes,\n      int force_intra, opus_val32 *delayedIntra, int two_pass, int loss_rate, int lfe)\n{\n   int intra;\n   opus_val16 max_decay;\n   VARDECL(opus_val16, oldEBands_intra);\n   VARDECL(opus_val16, error_intra);\n   ec_enc enc_start_state;\n   opus_uint32 tell;\n   int badness1=0;\n   opus_int32 intra_bias;\n   opus_val32 new_distortion;\n   SAVE_STACK;\n\n   intra = force_intra || (!two_pass && *delayedIntra>2*C*(end-start) && nbAvailableBytes > (end-start)*C);\n   intra_bias = (opus_int32)((budget**delayedIntra*loss_rate)/(C*512));\n   new_distortion = loss_distortion(eBands, oldEBands, start, effEnd, m->nbEBands, C);\n\n   tell = ec_tell(enc);\n   if (tell+3 > budget)\n      two_pass = intra = 0;\n\n   max_decay = QCONST16(16.f,DB_SHIFT);\n   if (end-start>10)\n   {\n#ifdef FIXED_POINT\n      max_decay = MIN32(max_decay, SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3));\n#else\n      max_decay = MIN32(max_decay, .125f*nbAvailableBytes);\n#endif\n   }\n   if (lfe)\n      max_decay = QCONST16(3.f,DB_SHIFT);\n   enc_start_state = *enc;\n\n   ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16);\n   ALLOC(error_intra, C*m->nbEBands, opus_val16);\n   OPUS_COPY(oldEBands_intra, oldEBands, C*m->nbEBands);\n\n   if (two_pass || intra)\n   {\n      badness1 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands_intra, budget,\n            tell, e_prob_model[LM][1], error_intra, enc, C, LM, 1, max_decay, lfe);\n   }\n\n   if (!intra)\n   {\n      unsigned char *intra_buf;\n      ec_enc enc_intra_state;\n      opus_int32 tell_intra;\n      opus_uint32 nstart_bytes;\n      opus_uint32 nintra_bytes;\n      opus_uint32 save_bytes;\n      int badness2;\n      VARDECL(unsigned char, intra_bits);\n\n      tell_intra = ec_tell_frac(enc);\n\n      enc_intra_state = *enc;\n\n      nstart_bytes = ec_range_bytes(&enc_start_state);\n      nintra_bytes = ec_range_bytes(&enc_intra_state);\n      intra_buf = ec_get_buffer(&enc_intra_state) + nstart_bytes;\n      save_bytes = nintra_bytes-nstart_bytes;\n      if (save_bytes == 0)\n         save_bytes = ALLOC_NONE;\n      ALLOC(intra_bits, save_bytes, unsigned char);\n      /* Copy bits from intra bit-stream */\n      OPUS_COPY(intra_bits, intra_buf, nintra_bytes - nstart_bytes);\n\n      *enc = enc_start_state;\n\n      badness2 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands, budget,\n            tell, e_prob_model[LM][intra], error, enc, C, LM, 0, max_decay, lfe);\n\n      if (two_pass && (badness1 < badness2 || (badness1 == badness2 && ((opus_int32)ec_tell_frac(enc))+intra_bias > tell_intra)))\n      {\n         *enc = enc_intra_state;\n         /* Copy intra bits to bit-stream */\n         OPUS_COPY(intra_buf, intra_bits, nintra_bytes - nstart_bytes);\n         OPUS_COPY(oldEBands, oldEBands_intra, C*m->nbEBands);\n         OPUS_COPY(error, error_intra, C*m->nbEBands);\n         intra = 1;\n      }\n   } else {\n      OPUS_COPY(oldEBands, oldEBands_intra, C*m->nbEBands);\n      OPUS_COPY(error, error_intra, C*m->nbEBands);\n   }\n\n   if (intra)\n      *delayedIntra = new_distortion;\n   else\n      *delayedIntra = ADD32(MULT16_32_Q15(MULT16_16_Q15(pred_coef[LM], pred_coef[LM]),*delayedIntra),\n            new_distortion);\n\n   RESTORE_STACK;\n}\n\nvoid quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C)\n{\n   int i, c;\n\n   /* Encode finer resolution */\n   for (i=start;i<end;i++)\n   {\n      opus_int16 frac = 1<<fine_quant[i];\n      if (fine_quant[i] <= 0)\n         continue;\n      c=0;\n      do {\n         int q2;\n         opus_val16 offset;\n#ifdef FIXED_POINT\n         /* Has to be without rounding */\n         q2 = (error[i+c*m->nbEBands]+QCONST16(.5f,DB_SHIFT))>>(DB_SHIFT-fine_quant[i]);\n#else\n         q2 = (int)floor((error[i+c*m->nbEBands]+.5f)*frac);\n#endif\n         if (q2 > frac-1)\n            q2 = frac-1;\n         if (q2<0)\n            q2 = 0;\n         ec_enc_bits(enc, q2, fine_quant[i]);\n#ifdef FIXED_POINT\n         offset = SUB16(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+QCONST16(.5f,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));\n#else\n         offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;\n#endif\n         oldEBands[i+c*m->nbEBands] += offset;\n         error[i+c*m->nbEBands] -= offset;\n         /*printf (\"%f \", error[i] - offset);*/\n      } while (++c < C);\n   }\n}\n\nvoid quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C)\n{\n   int i, prio, c;\n\n   /* Use up the remaining bits */\n   for (prio=0;prio<2;prio++)\n   {\n      for (i=start;i<end && bits_left>=C ;i++)\n      {\n         if (fine_quant[i] >= MAX_FINE_BITS || fine_priority[i]!=prio)\n            continue;\n         c=0;\n         do {\n            int q2;\n            opus_val16 offset;\n            q2 = error[i+c*m->nbEBands]<0 ? 0 : 1;\n            ec_enc_bits(enc, q2, 1);\n#ifdef FIXED_POINT\n            offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1);\n#else\n            offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);\n#endif\n            oldEBands[i+c*m->nbEBands] += offset;\n            bits_left--;\n         } while (++c < C);\n      }\n   }\n}\n\nvoid unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM)\n{\n   const unsigned char *prob_model = e_prob_model[LM][intra];\n   int i, c;\n   opus_val32 prev[2] = {0, 0};\n   opus_val16 coef;\n   opus_val16 beta;\n   opus_int32 budget;\n   opus_int32 tell;\n\n   if (intra)\n   {\n      coef = 0;\n      beta = beta_intra;\n   } else {\n      beta = beta_coef[LM];\n      coef = pred_coef[LM];\n   }\n\n   budget = dec->storage*8;\n\n   /* Decode at a fixed coarse resolution */\n   for (i=start;i<end;i++)\n   {\n      c=0;\n      do {\n         int qi;\n         opus_val32 q;\n         opus_val32 tmp;\n         /* It would be better to express this invariant as a\n            test on C at function entry, but that isn't enough\n            to make the static analyzer happy. */\n         celt_assert(c<2);\n         tell = ec_tell(dec);\n         if(budget-tell>=15)\n         {\n            int pi;\n            pi = 2*IMIN(i,20);\n            qi = ec_laplace_decode(dec,\n                  prob_model[pi]<<7, prob_model[pi+1]<<6);\n         }\n         else if(budget-tell>=2)\n         {\n            qi = ec_dec_icdf(dec, small_energy_icdf, 2);\n            qi = (qi>>1)^-(qi&1);\n         }\n         else if(budget-tell>=1)\n         {\n            qi = -ec_dec_bit_logp(dec, 1);\n         }\n         else\n            qi = -1;\n         q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT);\n\n         oldEBands[i+c*m->nbEBands] = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]);\n         tmp = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]),8) + prev[c] + SHL32(q,7);\n#ifdef FIXED_POINT\n         tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp);\n#endif\n         oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7);\n         prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8));\n      } while (++c < C);\n   }\n}\n\nvoid unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C)\n{\n   int i, c;\n   /* Decode finer resolution */\n   for (i=start;i<end;i++)\n   {\n      if (fine_quant[i] <= 0)\n         continue;\n      c=0;\n      do {\n         int q2;\n         opus_val16 offset;\n         q2 = ec_dec_bits(dec, fine_quant[i]);\n#ifdef FIXED_POINT\n         offset = SUB16(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+QCONST16(.5f,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));\n#else\n         offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;\n#endif\n         oldEBands[i+c*m->nbEBands] += offset;\n      } while (++c < C);\n   }\n}\n\nvoid unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant,  int *fine_priority, int bits_left, ec_dec *dec, int C)\n{\n   int i, prio, c;\n\n   /* Use up the remaining bits */\n   for (prio=0;prio<2;prio++)\n   {\n      for (i=start;i<end && bits_left>=C ;i++)\n      {\n         if (fine_quant[i] >= MAX_FINE_BITS || fine_priority[i]!=prio)\n            continue;\n         c=0;\n         do {\n            int q2;\n            opus_val16 offset;\n            q2 = ec_dec_bits(dec, 1);\n#ifdef FIXED_POINT\n            offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1);\n#else\n            offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);\n#endif\n            oldEBands[i+c*m->nbEBands] += offset;\n            bits_left--;\n         } while (++c < C);\n      }\n   }\n}\n\nvoid amp2Log2(const CELTMode *m, int effEnd, int end,\n      celt_ener *bandE, opus_val16 *bandLogE, int C)\n{\n   int c, i;\n   c=0;\n   do {\n      for (i=0;i<effEnd;i++)\n         bandLogE[i+c*m->nbEBands] =\n               celt_log2(SHL32(bandE[i+c*m->nbEBands],2))\n               - SHL16((opus_val16)eMeans[i],6);\n      for (i=effEnd;i<end;i++)\n         bandLogE[c*m->nbEBands+i] = -QCONST16(14.f,DB_SHIFT);\n   } while (++c < C);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/quant_bands.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef QUANT_BANDS\n#define QUANT_BANDS\n\n#include \"arch.h\"\n#include \"modes.h\"\n#include \"entenc.h\"\n#include \"entdec.h\"\n#include \"mathops.h\"\n\n#ifdef FIXED_POINT\nextern const signed char eMeans[25];\n#else\nextern const opus_val16 eMeans[25];\n#endif\n\nvoid amp2Log2(const CELTMode *m, int effEnd, int end,\n      celt_ener *bandE, opus_val16 *bandLogE, int C);\n\nvoid log2Amp(const CELTMode *m, int start, int end,\n      celt_ener *eBands, const opus_val16 *oldEBands, int C);\n\nvoid quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,\n      const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget,\n      opus_val16 *error, ec_enc *enc, int C, int LM,\n      int nbAvailableBytes, int force_intra, opus_val32 *delayedIntra,\n      int two_pass, int loss_rate, int lfe);\n\nvoid quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C);\n\nvoid quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C);\n\nvoid unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM);\n\nvoid unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C);\n\nvoid unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C);\n\n#endif /* QUANT_BANDS */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/rate.c",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <math.h>\n#include \"modes.h\"\n#include \"cwrs.h\"\n#include \"arch.h\"\n#include \"os_support.h\"\n\n#include \"entcode.h\"\n#include \"rate.h\"\n\nstatic const unsigned char LOG2_FRAC_TABLE[24]={\n   0,\n   8,13,\n  16,19,21,23,\n  24,26,27,28,29,30,31,32,\n  32,33,34,34,35,36,36,37,37\n};\n\n#ifdef CUSTOM_MODES\n\n/*Determines if V(N,K) fits in a 32-bit unsigned integer.\n  N and K are themselves limited to 15 bits.*/\nstatic int fits_in32(int _n, int _k)\n{\n   static const opus_int16 maxN[15] = {\n      32767, 32767, 32767, 1476, 283, 109,  60,  40,\n       29,  24,  20,  18,  16,  14,  13};\n   static const opus_int16 maxK[15] = {\n      32767, 32767, 32767, 32767, 1172, 238,  95,  53,\n       36,  27,  22,  18,  16,  15,  13};\n   if (_n>=14)\n   {\n      if (_k>=14)\n         return 0;\n      else\n         return _n <= maxN[_k];\n   } else {\n      return _k <= maxK[_n];\n   }\n}\n\nvoid compute_pulse_cache(CELTMode *m, int LM)\n{\n   int C;\n   int i;\n   int j;\n   int curr=0;\n   int nbEntries=0;\n   int entryN[100], entryK[100], entryI[100];\n   const opus_int16 *eBands = m->eBands;\n   PulseCache *cache = &m->cache;\n   opus_int16 *cindex;\n   unsigned char *bits;\n   unsigned char *cap;\n\n   cindex = (opus_int16 *)opus_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2));\n   cache->index = cindex;\n\n   /* Scan for all unique band sizes */\n   for (i=0;i<=LM+1;i++)\n   {\n      for (j=0;j<m->nbEBands;j++)\n      {\n         int k;\n         int N = (eBands[j+1]-eBands[j])<<i>>1;\n         cindex[i*m->nbEBands+j] = -1;\n         /* Find other bands that have the same size */\n         for (k=0;k<=i;k++)\n         {\n            int n;\n            for (n=0;n<m->nbEBands && (k!=i || n<j);n++)\n            {\n               if (N == (eBands[n+1]-eBands[n])<<k>>1)\n               {\n                  cindex[i*m->nbEBands+j] = cindex[k*m->nbEBands+n];\n                  break;\n               }\n            }\n         }\n         if (cache->index[i*m->nbEBands+j] == -1 && N!=0)\n         {\n            int K;\n            entryN[nbEntries] = N;\n            K = 0;\n            while (fits_in32(N,get_pulses(K+1)) && K<MAX_PSEUDO)\n               K++;\n            entryK[nbEntries] = K;\n            cindex[i*m->nbEBands+j] = curr;\n            entryI[nbEntries] = curr;\n\n            curr += K+1;\n            nbEntries++;\n         }\n      }\n   }\n   bits = (unsigned char *)opus_alloc(sizeof(unsigned char)*curr);\n   cache->bits = bits;\n   cache->size = curr;\n   /* Compute the cache for all unique sizes */\n   for (i=0;i<nbEntries;i++)\n   {\n      unsigned char *ptr = bits+entryI[i];\n      opus_int16 tmp[CELT_MAX_PULSES+1];\n      get_required_bits(tmp, entryN[i], get_pulses(entryK[i]), BITRES);\n      for (j=1;j<=entryK[i];j++)\n         ptr[j] = tmp[get_pulses(j)]-1;\n      ptr[0] = entryK[i];\n   }\n\n   /* Compute the maximum rate for each band at which we'll reliably use as\n       many bits as we ask for. */\n   cache->caps = cap = (unsigned char *)opus_alloc(sizeof(cache->caps[0])*(LM+1)*2*m->nbEBands);\n   for (i=0;i<=LM;i++)\n   {\n      for (C=1;C<=2;C++)\n      {\n         for (j=0;j<m->nbEBands;j++)\n         {\n            int N0;\n            int max_bits;\n            N0 = m->eBands[j+1]-m->eBands[j];\n            /* N=1 bands only have a sign bit and fine bits. */\n            if (N0<<i == 1)\n               max_bits = C*(1+MAX_FINE_BITS)<<BITRES;\n            else\n            {\n               const unsigned char *pcache;\n               opus_int32           num;\n               opus_int32           den;\n               int                  LM0;\n               int                  N;\n               int                  offset;\n               int                  ndof;\n               int                  qb;\n               int                  k;\n               LM0 = 0;\n               /* Even-sized bands bigger than N=2 can be split one more time.\n                  As of commit 44203907 all bands >1 are even, including custom modes.*/\n               if (N0 > 2)\n               {\n                  N0>>=1;\n                  LM0--;\n               }\n               /* N0=1 bands can't be split down to N<2. */\n               else if (N0 <= 1)\n               {\n                  LM0=IMIN(i,1);\n                  N0<<=LM0;\n               }\n               /* Compute the cost for the lowest-level PVQ of a fully split\n                   band. */\n               pcache = bits + cindex[(LM0+1)*m->nbEBands+j];\n               max_bits = pcache[pcache[0]]+1;\n               /* Add in the cost of coding regular splits. */\n               N = N0;\n               for(k=0;k<i-LM0;k++){\n                  max_bits <<= 1;\n                  /* Offset the number of qtheta bits by log2(N)/2\n                      + QTHETA_OFFSET compared to their \"fair share\" of\n                      total/N */\n                  offset = ((m->logN[j]+((LM0+k)<<BITRES))>>1)-QTHETA_OFFSET;\n                  /* The number of qtheta bits we'll allocate if the remainder\n                      is to be max_bits.\n                     The average measured cost for theta is 0.89701 times qb,\n                      approximated here as 459/512. */\n                  num=459*(opus_int32)((2*N-1)*offset+max_bits);\n                  den=((opus_int32)(2*N-1)<<9)-459;\n                  qb = IMIN((num+(den>>1))/den, 57);\n                  celt_assert(qb >= 0);\n                  max_bits += qb;\n                  N <<= 1;\n               }\n               /* Add in the cost of a stereo split, if necessary. */\n               if (C==2)\n               {\n                  max_bits <<= 1;\n                  offset = ((m->logN[j]+(i<<BITRES))>>1)-(N==2?QTHETA_OFFSET_TWOPHASE:QTHETA_OFFSET);\n                  ndof = 2*N-1-(N==2);\n                  /* The average measured cost for theta with the step PDF is\n                      0.95164 times qb, approximated here as 487/512. */\n                  num = (N==2?512:487)*(opus_int32)(max_bits+ndof*offset);\n                  den = ((opus_int32)ndof<<9)-(N==2?512:487);\n                  qb = IMIN((num+(den>>1))/den, (N==2?64:61));\n                  celt_assert(qb >= 0);\n                  max_bits += qb;\n               }\n               /* Add the fine bits we'll use. */\n               /* Compensate for the extra DoF in stereo */\n               ndof = C*N + ((C==2 && N>2) ? 1 : 0);\n               /* Offset the number of fine bits by log2(N)/2 + FINE_OFFSET\n                   compared to their \"fair share\" of total/N */\n               offset = ((m->logN[j] + (i<<BITRES))>>1)-FINE_OFFSET;\n               /* N=2 is the only point that doesn't match the curve */\n               if (N==2)\n                  offset += 1<<BITRES>>2;\n               /* The number of fine bits we'll allocate if the remainder is\n                   to be max_bits. */\n               num = max_bits+ndof*offset;\n               den = (ndof-1)<<BITRES;\n               qb = IMIN((num+(den>>1))/den, MAX_FINE_BITS);\n               celt_assert(qb >= 0);\n               max_bits += C*qb<<BITRES;\n            }\n            max_bits = (4*max_bits/(C*((m->eBands[j+1]-m->eBands[j])<<i)))-64;\n            celt_assert(max_bits >= 0);\n            celt_assert(max_bits < 256);\n            *cap++ = (unsigned char)max_bits;\n         }\n      }\n   }\n}\n\n#endif /* CUSTOM_MODES */\n\n#define ALLOC_STEPS 6\n\nstatic OPUS_INLINE int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start,\n      const int *bits1, const int *bits2, const int *thresh, const int *cap, opus_int32 total, opus_int32 *_balance,\n      int skip_rsv, int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits,\n      int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth)\n{\n   opus_int32 psum;\n   int lo, hi;\n   int i, j;\n   int logM;\n   int stereo;\n   int codedBands=-1;\n   int alloc_floor;\n   opus_int32 left, percoeff;\n   int done;\n   opus_int32 balance;\n   SAVE_STACK;\n\n   alloc_floor = C<<BITRES;\n   stereo = C>1;\n\n   logM = LM<<BITRES;\n   lo = 0;\n   hi = 1<<ALLOC_STEPS;\n   for (i=0;i<ALLOC_STEPS;i++)\n   {\n      int mid = (lo+hi)>>1;\n      psum = 0;\n      done = 0;\n      for (j=end;j-->start;)\n      {\n         int tmp = bits1[j] + (mid*(opus_int32)bits2[j]>>ALLOC_STEPS);\n         if (tmp >= thresh[j] || done)\n         {\n            done = 1;\n            /* Don't allocate more than we can actually use */\n            psum += IMIN(tmp, cap[j]);\n         } else {\n            if (tmp >= alloc_floor)\n               psum += alloc_floor;\n         }\n      }\n      if (psum > total)\n         hi = mid;\n      else\n         lo = mid;\n   }\n   psum = 0;\n   /*printf (\"interp bisection gave %d\\n\", lo);*/\n   done = 0;\n   for (j=end;j-->start;)\n   {\n      int tmp = bits1[j] + (lo*bits2[j]>>ALLOC_STEPS);\n      if (tmp < thresh[j] && !done)\n      {\n         if (tmp >= alloc_floor)\n            tmp = alloc_floor;\n         else\n            tmp = 0;\n      } else\n         done = 1;\n      /* Don't allocate more than we can actually use */\n      tmp = IMIN(tmp, cap[j]);\n      bits[j] = tmp;\n      psum += tmp;\n   }\n\n   /* Decide which bands to skip, working backwards from the end. */\n   for (codedBands=end;;codedBands--)\n   {\n      int band_width;\n      int band_bits;\n      int rem;\n      j = codedBands-1;\n      /* Never skip the first band, nor a band that has been boosted by\n          dynalloc.\n         In the first case, we'd be coding a bit to signal we're going to waste\n          all the other bits.\n         In the second case, we'd be coding a bit to redistribute all the bits\n          we just signaled should be cocentrated in this band. */\n      if (j<=skip_start)\n      {\n         /* Give the bit we reserved to end skipping back. */\n         total += skip_rsv;\n         break;\n      }\n      /*Figure out how many left-over bits we would be adding to this band.\n        This can include bits we've stolen back from higher, skipped bands.*/\n      left = total-psum;\n      percoeff = celt_udiv(left, m->eBands[codedBands]-m->eBands[start]);\n      left -= (m->eBands[codedBands]-m->eBands[start])*percoeff;\n      rem = IMAX(left-(m->eBands[j]-m->eBands[start]),0);\n      band_width = m->eBands[codedBands]-m->eBands[j];\n      band_bits = (int)(bits[j] + percoeff*band_width + rem);\n      /*Only code a skip decision if we're above the threshold for this band.\n        Otherwise it is force-skipped.\n        This ensures that we have enough bits to code the skip flag.*/\n      if (band_bits >= IMAX(thresh[j], alloc_floor+(1<<BITRES)))\n      {\n         if (encode)\n         {\n            /*This if() block is the only part of the allocation function that\n               is not a mandatory part of the bitstream: any bands we choose to\n               skip here must be explicitly signaled.*/\n            /*Choose a threshold with some hysteresis to keep bands from\n               fluctuating in and out.*/\n#ifdef FUZZING\n            if ((rand()&0x1) == 0)\n#else\n            if (codedBands<=start+2 || (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4 && j<=signalBandwidth))\n#endif\n            {\n               ec_enc_bit_logp(ec, 1, 1);\n               break;\n            }\n            ec_enc_bit_logp(ec, 0, 1);\n         } else if (ec_dec_bit_logp(ec, 1)) {\n            break;\n         }\n         /*We used a bit to skip this band.*/\n         psum += 1<<BITRES;\n         band_bits -= 1<<BITRES;\n      }\n      /*Reclaim the bits originally allocated to this band.*/\n      psum -= bits[j]+intensity_rsv;\n      if (intensity_rsv > 0)\n         intensity_rsv = LOG2_FRAC_TABLE[j-start];\n      psum += intensity_rsv;\n      if (band_bits >= alloc_floor)\n      {\n         /*If we have enough for a fine energy bit per channel, use it.*/\n         psum += alloc_floor;\n         bits[j] = alloc_floor;\n      } else {\n         /*Otherwise this band gets nothing at all.*/\n         bits[j] = 0;\n      }\n   }\n\n   celt_assert(codedBands > start);\n   /* Code the intensity and dual stereo parameters. */\n   if (intensity_rsv > 0)\n   {\n      if (encode)\n      {\n         *intensity = IMIN(*intensity, codedBands);\n         ec_enc_uint(ec, *intensity-start, codedBands+1-start);\n      }\n      else\n         *intensity = start+ec_dec_uint(ec, codedBands+1-start);\n   }\n   else\n      *intensity = 0;\n   if (*intensity <= start)\n   {\n      total += dual_stereo_rsv;\n      dual_stereo_rsv = 0;\n   }\n   if (dual_stereo_rsv > 0)\n   {\n      if (encode)\n         ec_enc_bit_logp(ec, *dual_stereo, 1);\n      else\n         *dual_stereo = ec_dec_bit_logp(ec, 1);\n   }\n   else\n      *dual_stereo = 0;\n\n   /* Allocate the remaining bits */\n   left = total-psum;\n   percoeff = celt_udiv(left, m->eBands[codedBands]-m->eBands[start]);\n   left -= (m->eBands[codedBands]-m->eBands[start])*percoeff;\n   for (j=start;j<codedBands;j++)\n      bits[j] += ((int)percoeff*(m->eBands[j+1]-m->eBands[j]));\n   for (j=start;j<codedBands;j++)\n   {\n      int tmp = (int)IMIN(left, m->eBands[j+1]-m->eBands[j]);\n      bits[j] += tmp;\n      left -= tmp;\n   }\n   /*for (j=0;j<end;j++)printf(\"%d \", bits[j]);printf(\"\\n\");*/\n\n   balance = 0;\n   for (j=start;j<codedBands;j++)\n   {\n      int N0, N, den;\n      int offset;\n      int NClogN;\n      opus_int32 excess, bit;\n\n      celt_assert(bits[j] >= 0);\n      N0 = m->eBands[j+1]-m->eBands[j];\n      N=N0<<LM;\n      bit = (opus_int32)bits[j]+balance;\n\n      if (N>1)\n      {\n         excess = MAX32(bit-cap[j],0);\n         bits[j] = bit-excess;\n\n         /* Compensate for the extra DoF in stereo */\n         den=(C*N+ ((C==2 && N>2 && !*dual_stereo && j<*intensity) ? 1 : 0));\n\n         NClogN = den*(m->logN[j] + logM);\n\n         /* Offset for the number of fine bits by log2(N)/2 + FINE_OFFSET\n            compared to their \"fair share\" of total/N */\n         offset = (NClogN>>1)-den*FINE_OFFSET;\n\n         /* N=2 is the only point that doesn't match the curve */\n         if (N==2)\n            offset += den<<BITRES>>2;\n\n         /* Changing the offset for allocating the second and third\n             fine energy bit */\n         if (bits[j] + offset < den*2<<BITRES)\n            offset += NClogN>>2;\n         else if (bits[j] + offset < den*3<<BITRES)\n            offset += NClogN>>3;\n\n         /* Divide with rounding */\n         ebits[j] = IMAX(0, (bits[j] + offset + (den<<(BITRES-1))));\n         ebits[j] = celt_udiv(ebits[j], den)>>BITRES;\n\n         /* Make sure not to bust */\n         if (C*ebits[j] > (bits[j]>>BITRES))\n            ebits[j] = bits[j] >> stereo >> BITRES;\n\n         /* More than that is useless because that's about as far as PVQ can go */\n         ebits[j] = IMIN(ebits[j], MAX_FINE_BITS);\n\n         /* If we rounded down or capped this band, make it a candidate for the\n             final fine energy pass */\n         fine_priority[j] = ebits[j]*(den<<BITRES) >= bits[j]+offset;\n\n         /* Remove the allocated fine bits; the rest are assigned to PVQ */\n         bits[j] -= C*ebits[j]<<BITRES;\n\n      } else {\n         /* For N=1, all bits go to fine energy except for a single sign bit */\n         excess = MAX32(0,bit-(C<<BITRES));\n         bits[j] = bit-excess;\n         ebits[j] = 0;\n         fine_priority[j] = 1;\n      }\n\n      /* Fine energy can't take advantage of the re-balancing in\n          quant_all_bands().\n         Instead, do the re-balancing here.*/\n      if(excess > 0)\n      {\n         int extra_fine;\n         int extra_bits;\n         extra_fine = IMIN(excess>>(stereo+BITRES),MAX_FINE_BITS-ebits[j]);\n         ebits[j] += extra_fine;\n         extra_bits = extra_fine*C<<BITRES;\n         fine_priority[j] = extra_bits >= excess-balance;\n         excess -= extra_bits;\n      }\n      balance = excess;\n\n      celt_assert(bits[j] >= 0);\n      celt_assert(ebits[j] >= 0);\n   }\n   /* Save any remaining bits over the cap for the rebalancing in\n       quant_all_bands(). */\n   *_balance = balance;\n\n   /* The skipped bands use all their bits for fine energy. */\n   for (;j<end;j++)\n   {\n      ebits[j] = bits[j] >> stereo >> BITRES;\n      celt_assert(C*ebits[j]<<BITRES == bits[j]);\n      bits[j] = 0;\n      fine_priority[j] = ebits[j]<1;\n   }\n   RESTORE_STACK;\n   return codedBands;\n}\n\nint compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,\n      opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth)\n{\n   int lo, hi, len, j;\n   int codedBands;\n   int skip_start;\n   int skip_rsv;\n   int intensity_rsv;\n   int dual_stereo_rsv;\n   VARDECL(int, bits1);\n   VARDECL(int, bits2);\n   VARDECL(int, thresh);\n   VARDECL(int, trim_offset);\n   SAVE_STACK;\n\n   total = IMAX(total, 0);\n   len = m->nbEBands;\n   skip_start = start;\n   /* Reserve a bit to signal the end of manually skipped bands. */\n   skip_rsv = total >= 1<<BITRES ? 1<<BITRES : 0;\n   total -= skip_rsv;\n   /* Reserve bits for the intensity and dual stereo parameters. */\n   intensity_rsv = dual_stereo_rsv = 0;\n   if (C==2)\n   {\n      intensity_rsv = LOG2_FRAC_TABLE[end-start];\n      if (intensity_rsv>total)\n         intensity_rsv = 0;\n      else\n      {\n         total -= intensity_rsv;\n         dual_stereo_rsv = total>=1<<BITRES ? 1<<BITRES : 0;\n         total -= dual_stereo_rsv;\n      }\n   }\n   ALLOC(bits1, len, int);\n   ALLOC(bits2, len, int);\n   ALLOC(thresh, len, int);\n   ALLOC(trim_offset, len, int);\n\n   for (j=start;j<end;j++)\n   {\n      /* Below this threshold, we're sure not to allocate any PVQ bits */\n      thresh[j] = IMAX((C)<<BITRES, (3*(m->eBands[j+1]-m->eBands[j])<<LM<<BITRES)>>4);\n      /* Tilt of the allocation curve */\n      trim_offset[j] = C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(end-j-1)\n            *(1<<(LM+BITRES))>>6;\n      /* Giving less resolution to single-coefficient bands because they get\n         more benefit from having one coarse value per coefficient*/\n      if ((m->eBands[j+1]-m->eBands[j])<<LM==1)\n         trim_offset[j] -= C<<BITRES;\n   }\n   lo = 1;\n   hi = m->nbAllocVectors - 1;\n   do\n   {\n      int done = 0;\n      int psum = 0;\n      int mid = (lo+hi) >> 1;\n      for (j=end;j-->start;)\n      {\n         int bitsj;\n         int N = m->eBands[j+1]-m->eBands[j];\n         bitsj = C*N*m->allocVectors[mid*len+j]<<LM>>2;\n         if (bitsj > 0)\n            bitsj = IMAX(0, bitsj + trim_offset[j]);\n         bitsj += offsets[j];\n         if (bitsj >= thresh[j] || done)\n         {\n            done = 1;\n            /* Don't allocate more than we can actually use */\n            psum += IMIN(bitsj, cap[j]);\n         } else {\n            if (bitsj >= C<<BITRES)\n               psum += C<<BITRES;\n         }\n      }\n      if (psum > total)\n         hi = mid - 1;\n      else\n         lo = mid + 1;\n      /*printf (\"lo = %d, hi = %d\\n\", lo, hi);*/\n   }\n   while (lo <= hi);\n   hi = lo--;\n   /*printf (\"interp between %d and %d\\n\", lo, hi);*/\n   for (j=start;j<end;j++)\n   {\n      int bits1j, bits2j;\n      int N = m->eBands[j+1]-m->eBands[j];\n      bits1j = C*N*m->allocVectors[lo*len+j]<<LM>>2;\n      bits2j = hi>=m->nbAllocVectors ?\n            cap[j] : C*N*m->allocVectors[hi*len+j]<<LM>>2;\n      if (bits1j > 0)\n         bits1j = IMAX(0, bits1j + trim_offset[j]);\n      if (bits2j > 0)\n         bits2j = IMAX(0, bits2j + trim_offset[j]);\n      if (lo > 0)\n         bits1j += offsets[j];\n      bits2j += offsets[j];\n      if (offsets[j]>0)\n         skip_start = j;\n      bits2j = IMAX(0,bits2j-bits1j);\n      bits1[j] = bits1j;\n      bits2[j] = bits2j;\n   }\n   codedBands = interp_bits2pulses(m, start, end, skip_start, bits1, bits2, thresh, cap,\n         total, balance, skip_rsv, intensity, intensity_rsv, dual_stereo, dual_stereo_rsv,\n         pulses, ebits, fine_priority, C, LM, ec, encode, prev, signalBandwidth);\n   RESTORE_STACK;\n   return codedBands;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/rate.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef RATE_H\n#define RATE_H\n\n#define MAX_PSEUDO 40\n#define LOG_MAX_PSEUDO 6\n\n#define CELT_MAX_PULSES 128\n\n#define MAX_FINE_BITS 8\n\n#define FINE_OFFSET 21\n#define QTHETA_OFFSET 4\n#define QTHETA_OFFSET_TWOPHASE 16\n\n#include \"cwrs.h\"\n#include \"modes.h\"\n\nvoid compute_pulse_cache(CELTMode *m, int LM);\n\nstatic OPUS_INLINE int get_pulses(int i)\n{\n   return i<8 ? i : (8 + (i&7)) << ((i>>3)-1);\n}\n\nstatic OPUS_INLINE int bits2pulses(const CELTMode *m, int band, int LM, int bits)\n{\n   int i;\n   int lo, hi;\n   const unsigned char *cache;\n\n   LM++;\n   cache = m->cache.bits + m->cache.index[LM*m->nbEBands+band];\n\n   lo = 0;\n   hi = cache[0];\n   bits--;\n   for (i=0;i<LOG_MAX_PSEUDO;i++)\n   {\n      int mid = (lo+hi+1)>>1;\n      /* OPT: Make sure this is implemented with a conditional move */\n      if ((int)cache[mid] >= bits)\n         hi = mid;\n      else\n         lo = mid;\n   }\n   if (bits- (lo == 0 ? -1 : (int)cache[lo]) <= (int)cache[hi]-bits)\n      return lo;\n   else\n      return hi;\n}\n\nstatic OPUS_INLINE int pulses2bits(const CELTMode *m, int band, int LM, int pulses)\n{\n   const unsigned char *cache;\n\n   LM++;\n   cache = m->cache.bits + m->cache.index[LM*m->nbEBands+band];\n   return pulses == 0 ? 0 : cache[pulses]+1;\n}\n\n/** Compute the pulse allocation, i.e. how many pulses will go in each\n  * band.\n @param m mode\n @param offsets Requested increase or decrease in the number of bits for\n                each band\n @param total Number of bands\n @param pulses Number of pulses per band (returned)\n @return Total number of bits allocated\n*/\nint compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero,\n      opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth);\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/stack_alloc.h",
    "content": "/* Copyright (C) 2002-2003 Jean-Marc Valin\n   Copyright (C) 2007-2009 Xiph.Org Foundation */\n/**\n   @file stack_alloc.h\n   @brief Temporary memory allocation on stack\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef STACK_ALLOC_H\n#define STACK_ALLOC_H\n\n#include \"opus_types.h\"\n#include \"opus_defines.h\"\n\n#if (!defined (VAR_ARRAYS) && !defined (USE_ALLOCA) && !defined (NONTHREADSAFE_PSEUDOSTACK))\n#error \"Opus requires one of VAR_ARRAYS, USE_ALLOCA, or NONTHREADSAFE_PSEUDOSTACK be defined to select the temporary allocation mode.\"\n#endif\n\n#ifdef USE_ALLOCA\n# ifdef WIN32\n#  include <malloc.h>\n# else\n#  ifdef HAVE_ALLOCA_H\n#   include <alloca.h>\n#  else\n#   include <stdlib.h>\n#  endif\n# endif\n#endif\n\n/**\n * @def ALIGN(stack, size)\n *\n * Aligns the stack to a 'size' boundary\n *\n * @param stack Stack\n * @param size  New size boundary\n */\n\n/**\n * @def PUSH(stack, size, type)\n *\n * Allocates 'size' elements of type 'type' on the stack\n *\n * @param stack Stack\n * @param size  Number of elements\n * @param type  Type of element\n */\n\n/**\n * @def VARDECL(var)\n *\n * Declare variable on stack\n *\n * @param var Variable to declare\n */\n\n/**\n * @def ALLOC(var, size, type)\n *\n * Allocate 'size' elements of 'type' on stack\n *\n * @param var  Name of variable to allocate\n * @param size Number of elements\n * @param type Type of element\n */\n\n#if defined(VAR_ARRAYS)\n\n#define VARDECL(type, var)\n#define ALLOC(var, size, type) type var[size]\n#define SAVE_STACK\n#define RESTORE_STACK\n#define ALLOC_STACK\n/* C99 does not allow VLAs of size zero */\n#define ALLOC_NONE 1\n\n#elif defined(USE_ALLOCA)\n\n#define VARDECL(type, var) type *var\n\n# ifdef WIN32\n#  define ALLOC(var, size, type) var = ((type*)_alloca(sizeof(type)*(size)))\n# else\n#  define ALLOC(var, size, type) var = ((type*)alloca(sizeof(type)*(size)))\n# endif\n\n#define SAVE_STACK\n#define RESTORE_STACK\n#define ALLOC_STACK\n#define ALLOC_NONE 0\n\n#else\n\n#ifdef CELT_C\nchar *scratch_ptr=0;\nchar *global_stack=0;\n#else\nextern char *global_stack;\nextern char *scratch_ptr;\n#endif /* CELT_C */\n\n#ifdef ENABLE_VALGRIND\n\n#include <valgrind/memcheck.h>\n\n#ifdef CELT_C\nchar *global_stack_top=0;\n#else\nextern char *global_stack_top;\n#endif /* CELT_C */\n\n#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))\n#define PUSH(stack, size, type) (VALGRIND_MAKE_MEM_NOACCESS(stack, global_stack_top-stack),ALIGN((stack),sizeof(type)/sizeof(char)),VALGRIND_MAKE_MEM_UNDEFINED(stack, ((size)*sizeof(type)/sizeof(char))),(stack)+=(2*(size)*sizeof(type)/sizeof(char)),(type*)((stack)-(2*(size)*sizeof(type)/sizeof(char))))\n#define RESTORE_STACK ((global_stack = _saved_stack),VALGRIND_MAKE_MEM_NOACCESS(global_stack, global_stack_top-global_stack))\n#define ALLOC_STACK char *_saved_stack; ((global_stack = (global_stack==0) ? ((global_stack_top=opus_alloc_scratch(GLOBAL_STACK_SIZE*2)+(GLOBAL_STACK_SIZE*2))-(GLOBAL_STACK_SIZE*2)) : global_stack),VALGRIND_MAKE_MEM_NOACCESS(global_stack, global_stack_top-global_stack)); _saved_stack = global_stack;\n\n#else\n\n#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))\n#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)/sizeof(char)),(stack)+=(size)*(sizeof(type)/sizeof(char)),(type*)((stack)-(size)*(sizeof(type)/sizeof(char))))\n#if 0 /* Set this to 1 to instrument pseudostack usage */\n#define RESTORE_STACK (printf(\"%ld %s:%d\\n\", global_stack-scratch_ptr, __FILE__, __LINE__),global_stack = _saved_stack)\n#else\n#define RESTORE_STACK (global_stack = _saved_stack)\n#endif\n#define ALLOC_STACK char *_saved_stack; (global_stack = (global_stack==0) ? (scratch_ptr=opus_alloc_scratch(GLOBAL_STACK_SIZE)) : global_stack); _saved_stack = global_stack;\n\n#endif /* ENABLE_VALGRIND */\n\n#include \"os_support.h\"\n#define VARDECL(type, var) type *var\n#define ALLOC(var, size, type) var = PUSH(global_stack, size, type)\n#define SAVE_STACK char *_saved_stack = global_stack;\n#define ALLOC_NONE 0\n\n#endif /* VAR_ARRAYS */\n\n\n#ifdef ENABLE_VALGRIND\n\n#include <valgrind/memcheck.h>\n#define OPUS_CHECK_ARRAY(ptr, len) VALGRIND_CHECK_MEM_IS_DEFINED(ptr, len*sizeof(*ptr))\n#define OPUS_CHECK_VALUE(value) VALGRIND_CHECK_VALUE_IS_DEFINED(value)\n#define OPUS_CHECK_ARRAY_COND(ptr, len) VALGRIND_CHECK_MEM_IS_DEFINED(ptr, len*sizeof(*ptr))\n#define OPUS_CHECK_VALUE_COND(value) VALGRIND_CHECK_VALUE_IS_DEFINED(value)\n#define OPUS_PRINT_INT(value) do {fprintf(stderr, #value \" = %d at %s:%d\\n\", value, __FILE__, __LINE__);}while(0)\n#define OPUS_FPRINTF fprintf\n\n#else\n\nstatic OPUS_INLINE int _opus_false(void) {return 0;}\n#define OPUS_CHECK_ARRAY(ptr, len) _opus_false()\n#define OPUS_CHECK_VALUE(value) _opus_false()\n#define OPUS_PRINT_INT(value) do{}while(0)\n#define OPUS_FPRINTF (void)\n\n#endif\n\n\n#endif /* STACK_ALLOC_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/static_modes_fixed.h",
    "content": "/* The contents of this file was automatically generated by dump_modes.c\n   with arguments: 48000 960\n   It contains static definitions for some pre-defined modes. */\n#include \"modes.h\"\n#include \"rate.h\"\n\n#ifdef HAVE_ARM_NE10\n#define OVERRIDE_FFT 1\n#include \"static_modes_fixed_arm_ne10.h\"\n#endif\n\n#ifndef DEF_WINDOW120\n#define DEF_WINDOW120\nstatic const opus_val16 window120[120] = {\n2, 20, 55, 108, 178,\n266, 372, 494, 635, 792,\n966, 1157, 1365, 1590, 1831,\n2089, 2362, 2651, 2956, 3276,\n3611, 3961, 4325, 4703, 5094,\n5499, 5916, 6346, 6788, 7241,\n7705, 8179, 8663, 9156, 9657,\n10167, 10684, 11207, 11736, 12271,\n12810, 13353, 13899, 14447, 14997,\n15547, 16098, 16648, 17197, 17744,\n18287, 18827, 19363, 19893, 20418,\n20936, 21447, 21950, 22445, 22931,\n23407, 23874, 24330, 24774, 25208,\n25629, 26039, 26435, 26819, 27190,\n27548, 27893, 28224, 28541, 28845,\n29135, 29411, 29674, 29924, 30160,\n30384, 30594, 30792, 30977, 31151,\n31313, 31463, 31602, 31731, 31849,\n31958, 32057, 32148, 32229, 32303,\n32370, 32429, 32481, 32528, 32568,\n32604, 32634, 32661, 32683, 32701,\n32717, 32729, 32740, 32748, 32754,\n32758, 32762, 32764, 32766, 32767,\n32767, 32767, 32767, 32767, 32767,\n};\n#endif\n\n#ifndef DEF_LOGN400\n#define DEF_LOGN400\nstatic const opus_int16 logN400[21] = {\n0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, };\n#endif\n\n#ifndef DEF_PULSE_CACHE50\n#define DEF_PULSE_CACHE50\nstatic const opus_int16 cache_index50[105] = {\n-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41,\n82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41,\n41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41,\n41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305,\n318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240,\n305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240,\n240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387,\n};\nstatic const unsigned char cache_bits50[392] = {\n40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28,\n31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50,\n51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65,\n66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61,\n64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92,\n94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123,\n124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94,\n97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139,\n142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35,\n28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149,\n153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225,\n229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157,\n166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63,\n86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250,\n25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180,\n185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89,\n110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41,\n74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138,\n163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214,\n228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49,\n90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47,\n87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57,\n106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187,\n224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127,\n182, 234, };\nstatic const unsigned char cache_caps50[168] = {\n224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185,\n178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240,\n240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160,\n160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193, 183, 183, 172,\n138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207,\n204, 204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185,\n185, 185, 193, 193, 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39,\n207, 207, 207, 207, 207, 207, 207, 207, 204, 204, 204, 204, 201, 201, 201,\n188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193, 193, 193,\n193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204,\n204, 204, 204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175,\n140, 66, 40, };\n#endif\n\n#ifndef FFT_TWIDDLES48000_960\n#define FFT_TWIDDLES48000_960\nstatic const kiss_twiddle_cpx fft_twiddles48000_960[480] = {\n{32767, 0}, {32766, -429},\n{32757, -858}, {32743, -1287},\n{32724, -1715}, {32698, -2143},\n{32667, -2570}, {32631, -2998},\n{32588, -3425}, {32541, -3851},\n{32488, -4277}, {32429, -4701},\n{32364, -5125}, {32295, -5548},\n{32219, -5971}, {32138, -6393},\n{32051, -6813}, {31960, -7231},\n{31863, -7650}, {31760, -8067},\n{31652, -8481}, {31539, -8895},\n{31419, -9306}, {31294, -9716},\n{31165, -10126}, {31030, -10532},\n{30889, -10937}, {30743, -11340},\n{30592, -11741}, {30436, -12141},\n{30274, -12540}, {30107, -12935},\n{29936, -13328}, {29758, -13718},\n{29577, -14107}, {29390, -14493},\n{29197, -14875}, {29000, -15257},\n{28797, -15635}, {28590, -16010},\n{28379, -16384}, {28162, -16753},\n{27940, -17119}, {27714, -17484},\n{27482, -17845}, {27246, -18205},\n{27006, -18560}, {26760, -18911},\n{26510, -19260}, {26257, -19606},\n{25997, -19947}, {25734, -20286},\n{25466, -20621}, {25194, -20952},\n{24918, -21281}, {24637, -21605},\n{24353, -21926}, {24063, -22242},\n{23770, -22555}, {23473, -22865},\n{23171, -23171}, {22866, -23472},\n{22557, -23769}, {22244, -24063},\n{21927, -24352}, {21606, -24636},\n{21282, -24917}, {20954, -25194},\n{20622, -25465}, {20288, -25733},\n{19949, -25997}, {19607, -26255},\n{19261, -26509}, {18914, -26760},\n{18561, -27004}, {18205, -27246},\n{17846, -27481}, {17485, -27713},\n{17122, -27940}, {16755, -28162},\n{16385, -28378}, {16012, -28590},\n{15636, -28797}, {15258, -28999},\n{14878, -29197}, {14494, -29389},\n{14108, -29576}, {13720, -29757},\n{13329, -29934}, {12937, -30107},\n{12540, -30274}, {12142, -30435},\n{11744, -30592}, {11342, -30743},\n{10939, -30889}, {10534, -31030},\n{10127, -31164}, {9718, -31294},\n{9307, -31418}, {8895, -31537},\n{8482, -31652}, {8067, -31759},\n{7650, -31862}, {7233, -31960},\n{6815, -32051}, {6393, -32138},\n{5973, -32219}, {5549, -32294},\n{5127, -32364}, {4703, -32429},\n{4278, -32487}, {3852, -32541},\n{3426, -32588}, {2999, -32630},\n{2572, -32667}, {2144, -32698},\n{1716, -32724}, {1287, -32742},\n{860, -32757}, {430, -32766},\n{0, -32767}, {-429, -32766},\n{-858, -32757}, {-1287, -32743},\n{-1715, -32724}, {-2143, -32698},\n{-2570, -32667}, {-2998, -32631},\n{-3425, -32588}, {-3851, -32541},\n{-4277, -32488}, {-4701, -32429},\n{-5125, -32364}, {-5548, -32295},\n{-5971, -32219}, {-6393, -32138},\n{-6813, -32051}, {-7231, -31960},\n{-7650, -31863}, {-8067, -31760},\n{-8481, -31652}, {-8895, -31539},\n{-9306, -31419}, {-9716, -31294},\n{-10126, -31165}, {-10532, -31030},\n{-10937, -30889}, {-11340, -30743},\n{-11741, -30592}, {-12141, -30436},\n{-12540, -30274}, {-12935, -30107},\n{-13328, -29936}, {-13718, -29758},\n{-14107, -29577}, {-14493, -29390},\n{-14875, -29197}, {-15257, -29000},\n{-15635, -28797}, {-16010, -28590},\n{-16384, -28379}, {-16753, -28162},\n{-17119, -27940}, {-17484, -27714},\n{-17845, -27482}, {-18205, -27246},\n{-18560, -27006}, {-18911, -26760},\n{-19260, -26510}, {-19606, -26257},\n{-19947, -25997}, {-20286, -25734},\n{-20621, -25466}, {-20952, -25194},\n{-21281, -24918}, {-21605, -24637},\n{-21926, -24353}, {-22242, -24063},\n{-22555, -23770}, {-22865, -23473},\n{-23171, -23171}, {-23472, -22866},\n{-23769, -22557}, {-24063, -22244},\n{-24352, -21927}, {-24636, -21606},\n{-24917, -21282}, {-25194, -20954},\n{-25465, -20622}, {-25733, -20288},\n{-25997, -19949}, {-26255, -19607},\n{-26509, -19261}, {-26760, -18914},\n{-27004, -18561}, {-27246, -18205},\n{-27481, -17846}, {-27713, -17485},\n{-27940, -17122}, {-28162, -16755},\n{-28378, -16385}, {-28590, -16012},\n{-28797, -15636}, {-28999, -15258},\n{-29197, -14878}, {-29389, -14494},\n{-29576, -14108}, {-29757, -13720},\n{-29934, -13329}, {-30107, -12937},\n{-30274, -12540}, {-30435, -12142},\n{-30592, -11744}, {-30743, -11342},\n{-30889, -10939}, {-31030, -10534},\n{-31164, -10127}, {-31294, -9718},\n{-31418, -9307}, {-31537, -8895},\n{-31652, -8482}, {-31759, -8067},\n{-31862, -7650}, {-31960, -7233},\n{-32051, -6815}, {-32138, -6393},\n{-32219, -5973}, {-32294, -5549},\n{-32364, -5127}, {-32429, -4703},\n{-32487, -4278}, {-32541, -3852},\n{-32588, -3426}, {-32630, -2999},\n{-32667, -2572}, {-32698, -2144},\n{-32724, -1716}, {-32742, -1287},\n{-32757, -860}, {-32766, -430},\n{-32767, 0}, {-32766, 429},\n{-32757, 858}, {-32743, 1287},\n{-32724, 1715}, {-32698, 2143},\n{-32667, 2570}, {-32631, 2998},\n{-32588, 3425}, {-32541, 3851},\n{-32488, 4277}, {-32429, 4701},\n{-32364, 5125}, {-32295, 5548},\n{-32219, 5971}, {-32138, 6393},\n{-32051, 6813}, {-31960, 7231},\n{-31863, 7650}, {-31760, 8067},\n{-31652, 8481}, {-31539, 8895},\n{-31419, 9306}, {-31294, 9716},\n{-31165, 10126}, {-31030, 10532},\n{-30889, 10937}, {-30743, 11340},\n{-30592, 11741}, {-30436, 12141},\n{-30274, 12540}, {-30107, 12935},\n{-29936, 13328}, {-29758, 13718},\n{-29577, 14107}, {-29390, 14493},\n{-29197, 14875}, {-29000, 15257},\n{-28797, 15635}, {-28590, 16010},\n{-28379, 16384}, {-28162, 16753},\n{-27940, 17119}, {-27714, 17484},\n{-27482, 17845}, {-27246, 18205},\n{-27006, 18560}, {-26760, 18911},\n{-26510, 19260}, {-26257, 19606},\n{-25997, 19947}, {-25734, 20286},\n{-25466, 20621}, {-25194, 20952},\n{-24918, 21281}, {-24637, 21605},\n{-24353, 21926}, {-24063, 22242},\n{-23770, 22555}, {-23473, 22865},\n{-23171, 23171}, {-22866, 23472},\n{-22557, 23769}, {-22244, 24063},\n{-21927, 24352}, {-21606, 24636},\n{-21282, 24917}, {-20954, 25194},\n{-20622, 25465}, {-20288, 25733},\n{-19949, 25997}, {-19607, 26255},\n{-19261, 26509}, {-18914, 26760},\n{-18561, 27004}, {-18205, 27246},\n{-17846, 27481}, {-17485, 27713},\n{-17122, 27940}, {-16755, 28162},\n{-16385, 28378}, {-16012, 28590},\n{-15636, 28797}, {-15258, 28999},\n{-14878, 29197}, {-14494, 29389},\n{-14108, 29576}, {-13720, 29757},\n{-13329, 29934}, {-12937, 30107},\n{-12540, 30274}, {-12142, 30435},\n{-11744, 30592}, {-11342, 30743},\n{-10939, 30889}, {-10534, 31030},\n{-10127, 31164}, {-9718, 31294},\n{-9307, 31418}, {-8895, 31537},\n{-8482, 31652}, {-8067, 31759},\n{-7650, 31862}, {-7233, 31960},\n{-6815, 32051}, {-6393, 32138},\n{-5973, 32219}, {-5549, 32294},\n{-5127, 32364}, {-4703, 32429},\n{-4278, 32487}, {-3852, 32541},\n{-3426, 32588}, {-2999, 32630},\n{-2572, 32667}, {-2144, 32698},\n{-1716, 32724}, {-1287, 32742},\n{-860, 32757}, {-430, 32766},\n{0, 32767}, {429, 32766},\n{858, 32757}, {1287, 32743},\n{1715, 32724}, {2143, 32698},\n{2570, 32667}, {2998, 32631},\n{3425, 32588}, {3851, 32541},\n{4277, 32488}, {4701, 32429},\n{5125, 32364}, {5548, 32295},\n{5971, 32219}, {6393, 32138},\n{6813, 32051}, {7231, 31960},\n{7650, 31863}, {8067, 31760},\n{8481, 31652}, {8895, 31539},\n{9306, 31419}, {9716, 31294},\n{10126, 31165}, {10532, 31030},\n{10937, 30889}, {11340, 30743},\n{11741, 30592}, {12141, 30436},\n{12540, 30274}, {12935, 30107},\n{13328, 29936}, {13718, 29758},\n{14107, 29577}, {14493, 29390},\n{14875, 29197}, {15257, 29000},\n{15635, 28797}, {16010, 28590},\n{16384, 28379}, {16753, 28162},\n{17119, 27940}, {17484, 27714},\n{17845, 27482}, {18205, 27246},\n{18560, 27006}, {18911, 26760},\n{19260, 26510}, {19606, 26257},\n{19947, 25997}, {20286, 25734},\n{20621, 25466}, {20952, 25194},\n{21281, 24918}, {21605, 24637},\n{21926, 24353}, {22242, 24063},\n{22555, 23770}, {22865, 23473},\n{23171, 23171}, {23472, 22866},\n{23769, 22557}, {24063, 22244},\n{24352, 21927}, {24636, 21606},\n{24917, 21282}, {25194, 20954},\n{25465, 20622}, {25733, 20288},\n{25997, 19949}, {26255, 19607},\n{26509, 19261}, {26760, 18914},\n{27004, 18561}, {27246, 18205},\n{27481, 17846}, {27713, 17485},\n{27940, 17122}, {28162, 16755},\n{28378, 16385}, {28590, 16012},\n{28797, 15636}, {28999, 15258},\n{29197, 14878}, {29389, 14494},\n{29576, 14108}, {29757, 13720},\n{29934, 13329}, {30107, 12937},\n{30274, 12540}, {30435, 12142},\n{30592, 11744}, {30743, 11342},\n{30889, 10939}, {31030, 10534},\n{31164, 10127}, {31294, 9718},\n{31418, 9307}, {31537, 8895},\n{31652, 8482}, {31759, 8067},\n{31862, 7650}, {31960, 7233},\n{32051, 6815}, {32138, 6393},\n{32219, 5973}, {32294, 5549},\n{32364, 5127}, {32429, 4703},\n{32487, 4278}, {32541, 3852},\n{32588, 3426}, {32630, 2999},\n{32667, 2572}, {32698, 2144},\n{32724, 1716}, {32742, 1287},\n{32757, 860}, {32766, 430},\n};\n#ifndef FFT_BITREV480\n#define FFT_BITREV480\nstatic const opus_int16 fft_bitrev480[480] = {\n0, 96, 192, 288, 384, 32, 128, 224, 320, 416, 64, 160, 256, 352, 448,\n8, 104, 200, 296, 392, 40, 136, 232, 328, 424, 72, 168, 264, 360, 456,\n16, 112, 208, 304, 400, 48, 144, 240, 336, 432, 80, 176, 272, 368, 464,\n24, 120, 216, 312, 408, 56, 152, 248, 344, 440, 88, 184, 280, 376, 472,\n4, 100, 196, 292, 388, 36, 132, 228, 324, 420, 68, 164, 260, 356, 452,\n12, 108, 204, 300, 396, 44, 140, 236, 332, 428, 76, 172, 268, 364, 460,\n20, 116, 212, 308, 404, 52, 148, 244, 340, 436, 84, 180, 276, 372, 468,\n28, 124, 220, 316, 412, 60, 156, 252, 348, 444, 92, 188, 284, 380, 476,\n1, 97, 193, 289, 385, 33, 129, 225, 321, 417, 65, 161, 257, 353, 449,\n9, 105, 201, 297, 393, 41, 137, 233, 329, 425, 73, 169, 265, 361, 457,\n17, 113, 209, 305, 401, 49, 145, 241, 337, 433, 81, 177, 273, 369, 465,\n25, 121, 217, 313, 409, 57, 153, 249, 345, 441, 89, 185, 281, 377, 473,\n5, 101, 197, 293, 389, 37, 133, 229, 325, 421, 69, 165, 261, 357, 453,\n13, 109, 205, 301, 397, 45, 141, 237, 333, 429, 77, 173, 269, 365, 461,\n21, 117, 213, 309, 405, 53, 149, 245, 341, 437, 85, 181, 277, 373, 469,\n29, 125, 221, 317, 413, 61, 157, 253, 349, 445, 93, 189, 285, 381, 477,\n2, 98, 194, 290, 386, 34, 130, 226, 322, 418, 66, 162, 258, 354, 450,\n10, 106, 202, 298, 394, 42, 138, 234, 330, 426, 74, 170, 266, 362, 458,\n18, 114, 210, 306, 402, 50, 146, 242, 338, 434, 82, 178, 274, 370, 466,\n26, 122, 218, 314, 410, 58, 154, 250, 346, 442, 90, 186, 282, 378, 474,\n6, 102, 198, 294, 390, 38, 134, 230, 326, 422, 70, 166, 262, 358, 454,\n14, 110, 206, 302, 398, 46, 142, 238, 334, 430, 78, 174, 270, 366, 462,\n22, 118, 214, 310, 406, 54, 150, 246, 342, 438, 86, 182, 278, 374, 470,\n30, 126, 222, 318, 414, 62, 158, 254, 350, 446, 94, 190, 286, 382, 478,\n3, 99, 195, 291, 387, 35, 131, 227, 323, 419, 67, 163, 259, 355, 451,\n11, 107, 203, 299, 395, 43, 139, 235, 331, 427, 75, 171, 267, 363, 459,\n19, 115, 211, 307, 403, 51, 147, 243, 339, 435, 83, 179, 275, 371, 467,\n27, 123, 219, 315, 411, 59, 155, 251, 347, 443, 91, 187, 283, 379, 475,\n7, 103, 199, 295, 391, 39, 135, 231, 327, 423, 71, 167, 263, 359, 455,\n15, 111, 207, 303, 399, 47, 143, 239, 335, 431, 79, 175, 271, 367, 463,\n23, 119, 215, 311, 407, 55, 151, 247, 343, 439, 87, 183, 279, 375, 471,\n31, 127, 223, 319, 415, 63, 159, 255, 351, 447, 95, 191, 287, 383, 479,\n};\n#endif\n\n#ifndef FFT_BITREV240\n#define FFT_BITREV240\nstatic const opus_int16 fft_bitrev240[240] = {\n0, 48, 96, 144, 192, 16, 64, 112, 160, 208, 32, 80, 128, 176, 224,\n4, 52, 100, 148, 196, 20, 68, 116, 164, 212, 36, 84, 132, 180, 228,\n8, 56, 104, 152, 200, 24, 72, 120, 168, 216, 40, 88, 136, 184, 232,\n12, 60, 108, 156, 204, 28, 76, 124, 172, 220, 44, 92, 140, 188, 236,\n1, 49, 97, 145, 193, 17, 65, 113, 161, 209, 33, 81, 129, 177, 225,\n5, 53, 101, 149, 197, 21, 69, 117, 165, 213, 37, 85, 133, 181, 229,\n9, 57, 105, 153, 201, 25, 73, 121, 169, 217, 41, 89, 137, 185, 233,\n13, 61, 109, 157, 205, 29, 77, 125, 173, 221, 45, 93, 141, 189, 237,\n2, 50, 98, 146, 194, 18, 66, 114, 162, 210, 34, 82, 130, 178, 226,\n6, 54, 102, 150, 198, 22, 70, 118, 166, 214, 38, 86, 134, 182, 230,\n10, 58, 106, 154, 202, 26, 74, 122, 170, 218, 42, 90, 138, 186, 234,\n14, 62, 110, 158, 206, 30, 78, 126, 174, 222, 46, 94, 142, 190, 238,\n3, 51, 99, 147, 195, 19, 67, 115, 163, 211, 35, 83, 131, 179, 227,\n7, 55, 103, 151, 199, 23, 71, 119, 167, 215, 39, 87, 135, 183, 231,\n11, 59, 107, 155, 203, 27, 75, 123, 171, 219, 43, 91, 139, 187, 235,\n15, 63, 111, 159, 207, 31, 79, 127, 175, 223, 47, 95, 143, 191, 239,\n};\n#endif\n\n#ifndef FFT_BITREV120\n#define FFT_BITREV120\nstatic const opus_int16 fft_bitrev120[120] = {\n0, 24, 48, 72, 96, 8, 32, 56, 80, 104, 16, 40, 64, 88, 112,\n4, 28, 52, 76, 100, 12, 36, 60, 84, 108, 20, 44, 68, 92, 116,\n1, 25, 49, 73, 97, 9, 33, 57, 81, 105, 17, 41, 65, 89, 113,\n5, 29, 53, 77, 101, 13, 37, 61, 85, 109, 21, 45, 69, 93, 117,\n2, 26, 50, 74, 98, 10, 34, 58, 82, 106, 18, 42, 66, 90, 114,\n6, 30, 54, 78, 102, 14, 38, 62, 86, 110, 22, 46, 70, 94, 118,\n3, 27, 51, 75, 99, 11, 35, 59, 83, 107, 19, 43, 67, 91, 115,\n7, 31, 55, 79, 103, 15, 39, 63, 87, 111, 23, 47, 71, 95, 119,\n};\n#endif\n\n#ifndef FFT_BITREV60\n#define FFT_BITREV60\nstatic const opus_int16 fft_bitrev60[60] = {\n0, 12, 24, 36, 48, 4, 16, 28, 40, 52, 8, 20, 32, 44, 56,\n1, 13, 25, 37, 49, 5, 17, 29, 41, 53, 9, 21, 33, 45, 57,\n2, 14, 26, 38, 50, 6, 18, 30, 42, 54, 10, 22, 34, 46, 58,\n3, 15, 27, 39, 51, 7, 19, 31, 43, 55, 11, 23, 35, 47, 59,\n};\n#endif\n\n#ifndef FFT_STATE48000_960_0\n#define FFT_STATE48000_960_0\nstatic const kiss_fft_state fft_state48000_960_0 = {\n480,    /* nfft */\n17476,    /* scale */\n8,      /* scale_shift */\n-1,     /* shift */\n{5, 96, 3, 32, 4, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, },    /* factors */\nfft_bitrev480,  /* bitrev */\nfft_twiddles48000_960,  /* bitrev */\n#ifdef OVERRIDE_FFT\n(arch_fft_state *)&cfg_arch_480,\n#else\nNULL,\n#endif\n};\n#endif\n\n#ifndef FFT_STATE48000_960_1\n#define FFT_STATE48000_960_1\nstatic const kiss_fft_state fft_state48000_960_1 = {\n240,    /* nfft */\n17476,    /* scale */\n7,      /* scale_shift */\n1,      /* shift */\n{5, 48, 3, 16, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, },    /* factors */\nfft_bitrev240,  /* bitrev */\nfft_twiddles48000_960,  /* bitrev */\n#ifdef OVERRIDE_FFT\n(arch_fft_state *)&cfg_arch_240,\n#else\nNULL,\n#endif\n};\n#endif\n\n#ifndef FFT_STATE48000_960_2\n#define FFT_STATE48000_960_2\nstatic const kiss_fft_state fft_state48000_960_2 = {\n120,    /* nfft */\n17476,    /* scale */\n6,      /* scale_shift */\n2,      /* shift */\n{5, 24, 3, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, },    /* factors */\nfft_bitrev120,  /* bitrev */\nfft_twiddles48000_960,  /* bitrev */\n#ifdef OVERRIDE_FFT\n(arch_fft_state *)&cfg_arch_120,\n#else\nNULL,\n#endif\n};\n#endif\n\n#ifndef FFT_STATE48000_960_3\n#define FFT_STATE48000_960_3\nstatic const kiss_fft_state fft_state48000_960_3 = {\n60,     /* nfft */\n17476,    /* scale */\n5,      /* scale_shift */\n3,      /* shift */\n{5, 12, 3, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },    /* factors */\nfft_bitrev60,   /* bitrev */\nfft_twiddles48000_960,  /* bitrev */\n#ifdef OVERRIDE_FFT\n(arch_fft_state *)&cfg_arch_60,\n#else\nNULL,\n#endif\n};\n#endif\n\n#endif\n\n#ifndef MDCT_TWIDDLES960\n#define MDCT_TWIDDLES960\nstatic const opus_val16 mdct_twiddles960[1800] = {\n32767, 32767, 32767, 32766, 32765,\n32763, 32761, 32759, 32756, 32753,\n32750, 32746, 32742, 32738, 32733,\n32728, 32722, 32717, 32710, 32704,\n32697, 32690, 32682, 32674, 32666,\n32657, 32648, 32639, 32629, 32619,\n32609, 32598, 32587, 32576, 32564,\n32552, 32539, 32526, 32513, 32500,\n32486, 32472, 32457, 32442, 32427,\n32411, 32395, 32379, 32362, 32345,\n32328, 32310, 32292, 32274, 32255,\n32236, 32217, 32197, 32177, 32157,\n32136, 32115, 32093, 32071, 32049,\n32027, 32004, 31981, 31957, 31933,\n31909, 31884, 31859, 31834, 31809,\n31783, 31756, 31730, 31703, 31676,\n31648, 31620, 31592, 31563, 31534,\n31505, 31475, 31445, 31415, 31384,\n31353, 31322, 31290, 31258, 31226,\n31193, 31160, 31127, 31093, 31059,\n31025, 30990, 30955, 30920, 30884,\n30848, 30812, 30775, 30738, 30701,\n30663, 30625, 30587, 30548, 30509,\n30470, 30430, 30390, 30350, 30309,\n30269, 30227, 30186, 30144, 30102,\n30059, 30016, 29973, 29930, 29886,\n29842, 29797, 29752, 29707, 29662,\n29616, 29570, 29524, 29477, 29430,\n29383, 29335, 29287, 29239, 29190,\n29142, 29092, 29043, 28993, 28943,\n28892, 28842, 28791, 28739, 28688,\n28636, 28583, 28531, 28478, 28425,\n28371, 28317, 28263, 28209, 28154,\n28099, 28044, 27988, 27932, 27876,\n27820, 27763, 27706, 27648, 27591,\n27533, 27474, 27416, 27357, 27298,\n27238, 27178, 27118, 27058, 26997,\n26936, 26875, 26814, 26752, 26690,\n26628, 26565, 26502, 26439, 26375,\n26312, 26247, 26183, 26119, 26054,\n25988, 25923, 25857, 25791, 25725,\n25658, 25592, 25524, 25457, 25389,\n25322, 25253, 25185, 25116, 25047,\n24978, 24908, 24838, 24768, 24698,\n24627, 24557, 24485, 24414, 24342,\n24270, 24198, 24126, 24053, 23980,\n23907, 23834, 23760, 23686, 23612,\n23537, 23462, 23387, 23312, 23237,\n23161, 23085, 23009, 22932, 22856,\n22779, 22701, 22624, 22546, 22468,\n22390, 22312, 22233, 22154, 22075,\n21996, 21916, 21836, 21756, 21676,\n21595, 21515, 21434, 21352, 21271,\n21189, 21107, 21025, 20943, 20860,\n20777, 20694, 20611, 20528, 20444,\n20360, 20276, 20192, 20107, 20022,\n19937, 19852, 19767, 19681, 19595,\n19509, 19423, 19336, 19250, 19163,\n19076, 18988, 18901, 18813, 18725,\n18637, 18549, 18460, 18372, 18283,\n18194, 18104, 18015, 17925, 17835,\n17745, 17655, 17565, 17474, 17383,\n17292, 17201, 17110, 17018, 16927,\n16835, 16743, 16650, 16558, 16465,\n16372, 16279, 16186, 16093, 15999,\n15906, 15812, 15718, 15624, 15529,\n15435, 15340, 15245, 15150, 15055,\n14960, 14864, 14769, 14673, 14577,\n14481, 14385, 14288, 14192, 14095,\n13998, 13901, 13804, 13706, 13609,\n13511, 13414, 13316, 13218, 13119,\n13021, 12923, 12824, 12725, 12626,\n12527, 12428, 12329, 12230, 12130,\n12030, 11930, 11831, 11730, 11630,\n11530, 11430, 11329, 11228, 11128,\n11027, 10926, 10824, 10723, 10622,\n10520, 10419, 10317, 10215, 10113,\n10011, 9909, 9807, 9704, 9602,\n9499, 9397, 9294, 9191, 9088,\n8985, 8882, 8778, 8675, 8572,\n8468, 8364, 8261, 8157, 8053,\n7949, 7845, 7741, 7637, 7532,\n7428, 7323, 7219, 7114, 7009,\n6905, 6800, 6695, 6590, 6485,\n6380, 6274, 6169, 6064, 5958,\n5853, 5747, 5642, 5536, 5430,\n5325, 5219, 5113, 5007, 4901,\n4795, 4689, 4583, 4476, 4370,\n4264, 4157, 4051, 3945, 3838,\n3732, 3625, 3518, 3412, 3305,\n3198, 3092, 2985, 2878, 2771,\n2664, 2558, 2451, 2344, 2237,\n2130, 2023, 1916, 1809, 1702,\n1594, 1487, 1380, 1273, 1166,\n1059, 952, 844, 737, 630,\n523, 416, 308, 201, 94,\n-13, -121, -228, -335, -442,\n-550, -657, -764, -871, -978,\n-1086, -1193, -1300, -1407, -1514,\n-1621, -1728, -1835, -1942, -2049,\n-2157, -2263, -2370, -2477, -2584,\n-2691, -2798, -2905, -3012, -3118,\n-3225, -3332, -3439, -3545, -3652,\n-3758, -3865, -3971, -4078, -4184,\n-4290, -4397, -4503, -4609, -4715,\n-4821, -4927, -5033, -5139, -5245,\n-5351, -5457, -5562, -5668, -5774,\n-5879, -5985, -6090, -6195, -6301,\n-6406, -6511, -6616, -6721, -6826,\n-6931, -7036, -7140, -7245, -7349,\n-7454, -7558, -7663, -7767, -7871,\n-7975, -8079, -8183, -8287, -8390,\n-8494, -8597, -8701, -8804, -8907,\n-9011, -9114, -9217, -9319, -9422,\n-9525, -9627, -9730, -9832, -9934,\n-10037, -10139, -10241, -10342, -10444,\n-10546, -10647, -10748, -10850, -10951,\n-11052, -11153, -11253, -11354, -11455,\n-11555, -11655, -11756, -11856, -11955,\n-12055, -12155, -12254, -12354, -12453,\n-12552, -12651, -12750, -12849, -12947,\n-13046, -13144, -13242, -13340, -13438,\n-13536, -13633, -13731, -13828, -13925,\n-14022, -14119, -14216, -14312, -14409,\n-14505, -14601, -14697, -14793, -14888,\n-14984, -15079, -15174, -15269, -15364,\n-15459, -15553, -15647, -15741, -15835,\n-15929, -16023, -16116, -16210, -16303,\n-16396, -16488, -16581, -16673, -16766,\n-16858, -16949, -17041, -17133, -17224,\n-17315, -17406, -17497, -17587, -17678,\n-17768, -17858, -17948, -18037, -18127,\n-18216, -18305, -18394, -18483, -18571,\n-18659, -18747, -18835, -18923, -19010,\n-19098, -19185, -19271, -19358, -19444,\n-19531, -19617, -19702, -19788, -19873,\n-19959, -20043, -20128, -20213, -20297,\n-20381, -20465, -20549, -20632, -20715,\n-20798, -20881, -20963, -21046, -21128,\n-21210, -21291, -21373, -21454, -21535,\n-21616, -21696, -21776, -21856, -21936,\n-22016, -22095, -22174, -22253, -22331,\n-22410, -22488, -22566, -22643, -22721,\n-22798, -22875, -22951, -23028, -23104,\n-23180, -23256, -23331, -23406, -23481,\n-23556, -23630, -23704, -23778, -23852,\n-23925, -23998, -24071, -24144, -24216,\n-24288, -24360, -24432, -24503, -24574,\n-24645, -24716, -24786, -24856, -24926,\n-24995, -25064, -25133, -25202, -25270,\n-25339, -25406, -25474, -25541, -25608,\n-25675, -25742, -25808, -25874, -25939,\n-26005, -26070, -26135, -26199, -26264,\n-26327, -26391, -26455, -26518, -26581,\n-26643, -26705, -26767, -26829, -26891,\n-26952, -27013, -27073, -27133, -27193,\n-27253, -27312, -27372, -27430, -27489,\n-27547, -27605, -27663, -27720, -27777,\n-27834, -27890, -27946, -28002, -28058,\n-28113, -28168, -28223, -28277, -28331,\n-28385, -28438, -28491, -28544, -28596,\n-28649, -28701, -28752, -28803, -28854,\n-28905, -28955, -29006, -29055, -29105,\n-29154, -29203, -29251, -29299, -29347,\n-29395, -29442, -29489, -29535, -29582,\n-29628, -29673, -29719, -29764, -29808,\n-29853, -29897, -29941, -29984, -30027,\n-30070, -30112, -30154, -30196, -30238,\n-30279, -30320, -30360, -30400, -30440,\n-30480, -30519, -30558, -30596, -30635,\n-30672, -30710, -30747, -30784, -30821,\n-30857, -30893, -30929, -30964, -30999,\n-31033, -31068, -31102, -31135, -31168,\n-31201, -31234, -31266, -31298, -31330,\n-31361, -31392, -31422, -31453, -31483,\n-31512, -31541, -31570, -31599, -31627,\n-31655, -31682, -31710, -31737, -31763,\n-31789, -31815, -31841, -31866, -31891,\n-31915, -31939, -31963, -31986, -32010,\n-32032, -32055, -32077, -32099, -32120,\n-32141, -32162, -32182, -32202, -32222,\n-32241, -32260, -32279, -32297, -32315,\n-32333, -32350, -32367, -32383, -32399,\n-32415, -32431, -32446, -32461, -32475,\n-32489, -32503, -32517, -32530, -32542,\n-32555, -32567, -32579, -32590, -32601,\n-32612, -32622, -32632, -32641, -32651,\n-32659, -32668, -32676, -32684, -32692,\n-32699, -32706, -32712, -32718, -32724,\n-32729, -32734, -32739, -32743, -32747,\n-32751, -32754, -32757, -32760, -32762,\n-32764, -32765, -32767, -32767, -32767,\n32767, 32767, 32765, 32761, 32756,\n32750, 32742, 32732, 32722, 32710,\n32696, 32681, 32665, 32647, 32628,\n32608, 32586, 32562, 32538, 32512,\n32484, 32455, 32425, 32393, 32360,\n32326, 32290, 32253, 32214, 32174,\n32133, 32090, 32046, 32001, 31954,\n31906, 31856, 31805, 31753, 31700,\n31645, 31588, 31530, 31471, 31411,\n31349, 31286, 31222, 31156, 31089,\n31020, 30951, 30880, 30807, 30733,\n30658, 30582, 30504, 30425, 30345,\n30263, 30181, 30096, 30011, 29924,\n29836, 29747, 29656, 29564, 29471,\n29377, 29281, 29184, 29086, 28987,\n28886, 28784, 28681, 28577, 28471,\n28365, 28257, 28147, 28037, 27925,\n27812, 27698, 27583, 27467, 27349,\n27231, 27111, 26990, 26868, 26744,\n26620, 26494, 26367, 26239, 26110,\n25980, 25849, 25717, 25583, 25449,\n25313, 25176, 25038, 24900, 24760,\n24619, 24477, 24333, 24189, 24044,\n23898, 23751, 23602, 23453, 23303,\n23152, 22999, 22846, 22692, 22537,\n22380, 22223, 22065, 21906, 21746,\n21585, 21423, 21261, 21097, 20933,\n20767, 20601, 20434, 20265, 20096,\n19927, 19756, 19584, 19412, 19239,\n19065, 18890, 18714, 18538, 18361,\n18183, 18004, 17824, 17644, 17463,\n17281, 17098, 16915, 16731, 16546,\n16361, 16175, 15988, 15800, 15612,\n15423, 15234, 15043, 14852, 14661,\n14469, 14276, 14083, 13889, 13694,\n13499, 13303, 13107, 12910, 12713,\n12515, 12317, 12118, 11918, 11718,\n11517, 11316, 11115, 10913, 10710,\n10508, 10304, 10100, 9896, 9691,\n9486, 9281, 9075, 8869, 8662,\n8455, 8248, 8040, 7832, 7623,\n7415, 7206, 6996, 6787, 6577,\n6366, 6156, 5945, 5734, 5523,\n5311, 5100, 4888, 4675, 4463,\n4251, 4038, 3825, 3612, 3399,\n3185, 2972, 2758, 2544, 2330,\n2116, 1902, 1688, 1474, 1260,\n1045, 831, 617, 402, 188,\n-27, -241, -456, -670, -885,\n-1099, -1313, -1528, -1742, -1956,\n-2170, -2384, -2598, -2811, -3025,\n-3239, -3452, -3665, -3878, -4091,\n-4304, -4516, -4728, -4941, -5153,\n-5364, -5576, -5787, -5998, -6209,\n-6419, -6629, -6839, -7049, -7258,\n-7467, -7676, -7884, -8092, -8300,\n-8507, -8714, -8920, -9127, -9332,\n-9538, -9743, -9947, -10151, -10355,\n-10558, -10761, -10963, -11165, -11367,\n-11568, -11768, -11968, -12167, -12366,\n-12565, -12762, -12960, -13156, -13352,\n-13548, -13743, -13937, -14131, -14324,\n-14517, -14709, -14900, -15091, -15281,\n-15470, -15659, -15847, -16035, -16221,\n-16407, -16593, -16777, -16961, -17144,\n-17326, -17508, -17689, -17869, -18049,\n-18227, -18405, -18582, -18758, -18934,\n-19108, -19282, -19455, -19627, -19799,\n-19969, -20139, -20308, -20475, -20642,\n-20809, -20974, -21138, -21301, -21464,\n-21626, -21786, -21946, -22105, -22263,\n-22420, -22575, -22730, -22884, -23037,\n-23189, -23340, -23490, -23640, -23788,\n-23935, -24080, -24225, -24369, -24512,\n-24654, -24795, -24934, -25073, -25211,\n-25347, -25482, -25617, -25750, -25882,\n-26013, -26143, -26272, -26399, -26526,\n-26651, -26775, -26898, -27020, -27141,\n-27260, -27379, -27496, -27612, -27727,\n-27841, -27953, -28065, -28175, -28284,\n-28391, -28498, -28603, -28707, -28810,\n-28911, -29012, -29111, -29209, -29305,\n-29401, -29495, -29587, -29679, -29769,\n-29858, -29946, -30032, -30118, -30201,\n-30284, -30365, -30445, -30524, -30601,\n-30677, -30752, -30825, -30897, -30968,\n-31038, -31106, -31172, -31238, -31302,\n-31365, -31426, -31486, -31545, -31602,\n-31658, -31713, -31766, -31818, -31869,\n-31918, -31966, -32012, -32058, -32101,\n-32144, -32185, -32224, -32262, -32299,\n-32335, -32369, -32401, -32433, -32463,\n-32491, -32518, -32544, -32568, -32591,\n-32613, -32633, -32652, -32669, -32685,\n-32700, -32713, -32724, -32735, -32744,\n-32751, -32757, -32762, -32766, -32767,\n32767, 32764, 32755, 32741, 32720,\n32694, 32663, 32626, 32583, 32535,\n32481, 32421, 32356, 32286, 32209,\n32128, 32041, 31948, 31850, 31747,\n31638, 31523, 31403, 31278, 31148,\n31012, 30871, 30724, 30572, 30415,\n30253, 30086, 29913, 29736, 29553,\n29365, 29172, 28974, 28771, 28564,\n28351, 28134, 27911, 27684, 27452,\n27216, 26975, 26729, 26478, 26223,\n25964, 25700, 25432, 25159, 24882,\n24601, 24315, 24026, 23732, 23434,\n23133, 22827, 22517, 22204, 21886,\n21565, 21240, 20912, 20580, 20244,\n19905, 19563, 19217, 18868, 18516,\n18160, 17802, 17440, 17075, 16708,\n16338, 15964, 15588, 15210, 14829,\n14445, 14059, 13670, 13279, 12886,\n12490, 12093, 11693, 11291, 10888,\n10482, 10075, 9666, 9255, 8843,\n8429, 8014, 7597, 7180, 6760,\n6340, 5919, 5496, 5073, 4649,\n4224, 3798, 3372, 2945, 2517,\n2090, 1661, 1233, 804, 375,\n-54, -483, -911, -1340, -1768,\n-2197, -2624, -3052, -3479, -3905,\n-4330, -4755, -5179, -5602, -6024,\n-6445, -6865, -7284, -7702, -8118,\n-8533, -8946, -9358, -9768, -10177,\n-10584, -10989, -11392, -11793, -12192,\n-12589, -12984, -13377, -13767, -14155,\n-14541, -14924, -15305, -15683, -16058,\n-16430, -16800, -17167, -17531, -17892,\n-18249, -18604, -18956, -19304, -19649,\n-19990, -20329, -20663, -20994, -21322,\n-21646, -21966, -22282, -22595, -22904,\n-23208, -23509, -23806, -24099, -24387,\n-24672, -24952, -25228, -25499, -25766,\n-26029, -26288, -26541, -26791, -27035,\n-27275, -27511, -27741, -27967, -28188,\n-28405, -28616, -28823, -29024, -29221,\n-29412, -29599, -29780, -29957, -30128,\n-30294, -30455, -30611, -30761, -30906,\n-31046, -31181, -31310, -31434, -31552,\n-31665, -31773, -31875, -31972, -32063,\n-32149, -32229, -32304, -32373, -32437,\n-32495, -32547, -32594, -32635, -32671,\n-32701, -32726, -32745, -32758, -32766,\n32767, 32754, 32717, 32658, 32577,\n32473, 32348, 32200, 32029, 31837,\n31624, 31388, 31131, 30853, 30553,\n30232, 29891, 29530, 29148, 28746,\n28324, 27883, 27423, 26944, 26447,\n25931, 25398, 24847, 24279, 23695,\n23095, 22478, 21846, 21199, 20538,\n19863, 19174, 18472, 17757, 17030,\n16291, 15541, 14781, 14010, 13230,\n12441, 11643, 10837, 10024, 9204,\n8377, 7545, 6708, 5866, 5020,\n4171, 3319, 2464, 1608, 751,\n-107, -965, -1822, -2678, -3532,\n-4383, -5232, -6077, -6918, -7754,\n-8585, -9409, -10228, -11039, -11843,\n-12639, -13426, -14204, -14972, -15730,\n-16477, -17213, -17937, -18648, -19347,\n-20033, -20705, -21363, -22006, -22634,\n-23246, -23843, -24423, -24986, -25533,\n-26062, -26573, -27066, -27540, -27995,\n-28431, -28848, -29245, -29622, -29979,\n-30315, -30630, -30924, -31197, -31449,\n-31679, -31887, -32074, -32239, -32381,\n-32501, -32600, -32675, -32729, -32759,\n};\n#endif\n\nstatic const CELTMode mode48000_960_120 = {\n48000,  /* Fs */\n120,    /* overlap */\n21,     /* nbEBands */\n21,     /* effEBands */\n{27853, 0, 4096, 8192, },       /* preemph */\neband5ms,       /* eBands */\n3,      /* maxLM */\n8,      /* nbShortMdcts */\n120,    /* shortMdctSize */\n11,     /* nbAllocVectors */\nband_allocation,        /* allocVectors */\nlogN400,        /* logN */\nwindow120,      /* window */\n{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960},    /* mdct */\n{392, cache_index50, cache_bits50, cache_caps50},       /* cache */\n};\n\n/* List of all the available modes */\n#define TOTAL_MODES 1\nstatic const CELTMode * const static_mode_list[TOTAL_MODES] = {\n&mode48000_960_120,\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/static_modes_fixed_arm_ne10.h",
    "content": "/* The contents of this file was automatically generated by\n * dump_mode_arm_ne10.c with arguments: 48000 960\n * It contains static definitions for some pre-defined modes. */\n#include <NE10_init.h>\n\n#ifndef NE10_FFT_PARAMS48000_960\n#define NE10_FFT_PARAMS48000_960\nstatic const ne10_int32_t ne10_factors_480[64] = {\n4, 40, 4, 30, 2, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, };\nstatic const ne10_int32_t ne10_factors_240[64] = {\n3, 20, 4, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, };\nstatic const ne10_int32_t ne10_factors_120[64] = {\n3, 10, 2, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, };\nstatic const ne10_int32_t ne10_factors_60[64] = {\n2, 5, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, };\nstatic const ne10_fft_cpx_int32_t ne10_twiddles_480[480] = {\n{0,0}, {2147483647,0}, {2147483647,0},\n{2147483647,0}, {1961823921,-873460313}, {1436946998,-1595891394},\n{2147483647,0}, {1436946998,-1595891394}, {-224473265,-2135719496},\n{2147483647,0}, {663608871,-2042378339}, {-1737350854,-1262259096},\n{2147483647,0}, {-224473265,-2135719496}, {-2100555935,446487152},\n{2147483647,0}, {2100555974,-446486968}, {1961823921,-873460313},\n{1737350743,-1262259248}, {1436946998,-1595891394}, {1073741769,-1859775424},\n{663608871,-2042378339}, {224473078,-2135719516}, {-224473265,-2135719496},\n{-663609049,-2042378281}, {-1073741932,-1859775330}, {-1436947137,-1595891268},\n{-1737350854,-1262259096}, {-1961823997,-873460141}, {-2100556013,-446486785},\n{2147483647,0}, {2144540595,-112390613}, {2135719506,-224473172},\n{2121044558,-335940465}, {2100555974,-446486968}, {2074309912,-555809682},\n{2042378310,-663608960}, {2004848691,-769589332}, {1961823921,-873460313},\n{1913421927,-974937199}, {1859775377,-1073741851}, {1801031311,-1169603450},\n{1737350743,-1262259248}, {1668908218,-1351455280}, {1595891331,-1436947067},\n{1518500216,-1518500282}, {1436946998,-1595891394}, {1351455207,-1668908277},\n{1262259172,-1737350799}, {1169603371,-1801031362}, {1073741769,-1859775424},\n{974937230,-1913421912}, {873460227,-1961823959}, {769589125,-2004848771},\n{663608871,-2042378339}, {555809715,-2074309903}, {446486876,-2100555994},\n{335940246,-2121044593}, {224473078,-2135719516}, {112390647,-2144540593},\n{2147483647,0}, {2135719506,-224473172}, {2100555974,-446486968},\n{2042378310,-663608960}, {1961823921,-873460313}, {1859775377,-1073741851},\n{1737350743,-1262259248}, {1595891331,-1436947067}, {1436946998,-1595891394},\n{1262259172,-1737350799}, {1073741769,-1859775424}, {873460227,-1961823959},\n{663608871,-2042378339}, {446486876,-2100555994}, {224473078,-2135719516},\n{-94,-2147483647}, {-224473265,-2135719496}, {-446487060,-2100555955},\n{-663609049,-2042378281}, {-873460398,-1961823883}, {-1073741932,-1859775330},\n{-1262259116,-1737350839}, {-1436947137,-1595891268}, {-1595891628,-1436946738},\n{-1737350854,-1262259096}, {-1859775343,-1073741910}, {-1961823997,-873460141},\n{-2042378447,-663608538}, {-2100556013,-446486785}, {-2135719499,-224473240},\n{2147483647,0}, {2121044558,-335940465}, {2042378310,-663608960},\n{1913421927,-974937199}, {1737350743,-1262259248}, {1518500216,-1518500282},\n{1262259172,-1737350799}, {974937230,-1913421912}, {663608871,-2042378339},\n{335940246,-2121044593}, {-94,-2147483647}, {-335940431,-2121044564},\n{-663609049,-2042378281}, {-974937397,-1913421827}, {-1262259116,-1737350839},\n{-1518500258,-1518500240}, {-1737350854,-1262259096}, {-1913422071,-974936918},\n{-2042378447,-663608538}, {-2121044568,-335940406}, {-2147483647,188},\n{-2121044509,335940777}, {-2042378331,663608895}, {-1913421900,974937252},\n{-1737350633,1262259400}, {-1518499993,1518500506}, {-1262258813,1737351059},\n{-974936606,1913422229}, {-663609179,2042378239}, {-335940566,2121044542},\n{2147483647,0}, {2147299667,-28109693}, {2146747758,-56214570},\n{2145828015,-84309815}, {2144540595,-112390613}, {2142885719,-140452154},\n{2140863671,-168489630}, {2138474797,-196498235}, {2135719506,-224473172},\n{2132598271,-252409646}, {2129111626,-280302871}, {2125260168,-308148068},\n{2121044558,-335940465}, {2116465518,-363675300}, {2111523833,-391347822},\n{2106220349,-418953288}, {2100555974,-446486968}, {2094531681,-473944146},\n{2088148500,-501320115}, {2081407525,-528610186}, {2074309912,-555809682},\n{2066856885,-582913912}, {2059049696,-609918325}, {2050889698,-636818231},\n{2042378310,-663608960}, {2033516972,-690285983}, {2024307180,-716844791},\n{2014750533,-743280770}, {2004848691,-769589332}, {1994603329,-795766029},\n{1984016179,-821806435}, {1973089077,-847706028}, {1961823921,-873460313},\n{1950222618,-899064934}, {1938287127,-924515564}, {1926019520,-949807783},\n{1913421927,-974937199}, {1900496481,-999899565}, {1887245364,-1024690661},\n{1873670877,-1049306180}, {1859775377,-1073741851}, {1845561215,-1097993541},\n{1831030826,-1122057097}, {1816186632,-1145928502}, {1801031311,-1169603450},\n{1785567394,-1193077993}, {1769797456,-1216348214}, {1753724345,-1239409914},\n{1737350743,-1262259248}, {1720679456,-1284892300}, {1703713340,-1307305194},\n{1686455222,-1329494189}, {1668908218,-1351455280}, {1651075255,-1373184807},\n{1632959307,-1394679144}, {1614563642,-1415934412}, {1595891331,-1436947067},\n{1576945572,-1457713510}, {1557729613,-1478230181}, {1538246655,-1498493658},\n{1518500216,-1518500282}, {1498493590,-1538246721}, {1478230113,-1557729677},\n{1457713441,-1576945636}, {1436946998,-1595891394}, {1415934341,-1614563704},\n{1394679073,-1632959368}, {1373184735,-1651075315}, {1351455207,-1668908277},\n{1329494115,-1686455280}, {1307305120,-1703713397}, {1284892225,-1720679512},\n{1262259172,-1737350799}, {1239409837,-1753724400}, {1216348136,-1769797510},\n{1193077915,-1785567446}, {1169603371,-1801031362}, {1145928423,-1816186682},\n{1122057017,-1831030875}, {1097993571,-1845561197}, {1073741769,-1859775424},\n{1049305987,-1873670985}, {1024690635,-1887245378}, {999899482,-1900496524},\n{974937230,-1913421912}, {949807699,-1926019561}, {924515422,-1938287195},\n{899064965,-1950222603}, {873460227,-1961823959}, {847705824,-1973089164},\n{821806407,-1984016190}, {795765941,-1994603364}, {769589125,-2004848771},\n{743280682,-2014750566}, {716844642,-2024307233}, {690286016,-2033516961},\n{663608871,-2042378339}, {636818019,-2050889764}, {609918296,-2059049705},\n{582913822,-2066856911}, {555809715,-2074309903}, {528610126,-2081407540},\n{501319962,-2088148536}, {473944148,-2094531680}, {446486876,-2100555994},\n{418953102,-2106220386}, {391347792,-2111523838}, {363675176,-2116465540},\n{335940246,-2121044593}, {308148006,-2125260177}, {280302715,-2129111646},\n{252409648,-2132598271}, {224473078,-2135719516}, {196498046,-2138474814},\n{168489600,-2140863674}, {140452029,-2142885728}, {112390647,-2144540593},\n{84309753,-2145828017}, {56214412,-2146747762}, {28109695,-2147299667},\n{2147483647,0}, {2146747758,-56214570}, {2144540595,-112390613},\n{2140863671,-168489630}, {2135719506,-224473172}, {2129111626,-280302871},\n{2121044558,-335940465}, {2111523833,-391347822}, {2100555974,-446486968},\n{2088148500,-501320115}, {2074309912,-555809682}, {2059049696,-609918325},\n{2042378310,-663608960}, {2024307180,-716844791}, {2004848691,-769589332},\n{1984016179,-821806435}, {1961823921,-873460313}, {1938287127,-924515564},\n{1913421927,-974937199}, {1887245364,-1024690661}, {1859775377,-1073741851},\n{1831030826,-1122057097}, {1801031311,-1169603450}, {1769797456,-1216348214},\n{1737350743,-1262259248}, {1703713340,-1307305194}, {1668908218,-1351455280},\n{1632959307,-1394679144}, {1595891331,-1436947067}, {1557729613,-1478230181},\n{1518500216,-1518500282}, {1478230113,-1557729677}, {1436946998,-1595891394},\n{1394679073,-1632959368}, {1351455207,-1668908277}, {1307305120,-1703713397},\n{1262259172,-1737350799}, {1216348136,-1769797510}, {1169603371,-1801031362},\n{1122057017,-1831030875}, {1073741769,-1859775424}, {1024690635,-1887245378},\n{974937230,-1913421912}, {924515422,-1938287195}, {873460227,-1961823959},\n{821806407,-1984016190}, {769589125,-2004848771}, {716844642,-2024307233},\n{663608871,-2042378339}, {609918296,-2059049705}, {555809715,-2074309903},\n{501319962,-2088148536}, {446486876,-2100555994}, {391347792,-2111523838},\n{335940246,-2121044593}, {280302715,-2129111646}, {224473078,-2135719516},\n{168489600,-2140863674}, {112390647,-2144540593}, {56214412,-2146747762},\n{-94,-2147483647}, {-56214600,-2146747757}, {-112390835,-2144540584},\n{-168489787,-2140863659}, {-224473265,-2135719496}, {-280302901,-2129111622},\n{-335940431,-2121044564}, {-391347977,-2111523804}, {-446487060,-2100555955},\n{-501320144,-2088148493}, {-555809896,-2074309855}, {-609918476,-2059049651},\n{-663609049,-2042378281}, {-716844819,-2024307170}, {-769589300,-2004848703},\n{-821806581,-1984016118}, {-873460398,-1961823883}, {-924515591,-1938287114},\n{-974937397,-1913421827}, {-1024690575,-1887245411}, {-1073741932,-1859775330},\n{-1122057395,-1831030643}, {-1169603421,-1801031330}, {-1216348291,-1769797403},\n{-1262259116,-1737350839}, {-1307305268,-1703713283}, {-1351455453,-1668908078},\n{-1394679021,-1632959413}, {-1436947137,-1595891268}, {-1478230435,-1557729372},\n{-1518500258,-1518500240}, {-1557729742,-1478230045}, {-1595891628,-1436946738},\n{-1632959429,-1394679001}, {-1668908417,-1351455035}, {-1703713298,-1307305248},\n{-1737350854,-1262259096}, {-1769797708,-1216347848}, {-1801031344,-1169603400},\n{-1831030924,-1122056937}, {-1859775343,-1073741910}, {-1887245423,-1024690552},\n{-1913422071,-974936918}, {-1938287125,-924515568}, {-1961823997,-873460141},\n{-1984016324,-821806084}, {-2004848713,-769589276}, {-2024307264,-716844553},\n{-2042378447,-663608538}, {-2059049731,-609918206}, {-2074309994,-555809377},\n{-2088148499,-501320119}, {-2100556013,-446486785}, {-2111523902,-391347448},\n{-2121044568,-335940406}, {-2129111659,-280302621}, {-2135719499,-224473240},\n{-2140863681,-168489506}, {-2144540612,-112390298}, {-2146747758,-56214574},\n{2147483647,0}, {2145828015,-84309815}, {2140863671,-168489630},\n{2132598271,-252409646}, {2121044558,-335940465}, {2106220349,-418953288},\n{2088148500,-501320115}, {2066856885,-582913912}, {2042378310,-663608960},\n{2014750533,-743280770}, {1984016179,-821806435}, {1950222618,-899064934},\n{1913421927,-974937199}, {1873670877,-1049306180}, {1831030826,-1122057097},\n{1785567394,-1193077993}, {1737350743,-1262259248}, {1686455222,-1329494189},\n{1632959307,-1394679144}, {1576945572,-1457713510}, {1518500216,-1518500282},\n{1457713441,-1576945636}, {1394679073,-1632959368}, {1329494115,-1686455280},\n{1262259172,-1737350799}, {1193077915,-1785567446}, {1122057017,-1831030875},\n{1049305987,-1873670985}, {974937230,-1913421912}, {899064965,-1950222603},\n{821806407,-1984016190}, {743280682,-2014750566}, {663608871,-2042378339},\n{582913822,-2066856911}, {501319962,-2088148536}, {418953102,-2106220386},\n{335940246,-2121044593}, {252409648,-2132598271}, {168489600,-2140863674},\n{84309753,-2145828017}, {-94,-2147483647}, {-84309940,-2145828010},\n{-168489787,-2140863659}, {-252409834,-2132598249}, {-335940431,-2121044564},\n{-418953286,-2106220349}, {-501320144,-2088148493}, {-582914003,-2066856860},\n{-663609049,-2042378281}, {-743280858,-2014750501}, {-821806581,-1984016118},\n{-899065136,-1950222525}, {-974937397,-1913421827}, {-1049306374,-1873670768},\n{-1122057395,-1831030643}, {-1193078284,-1785567199}, {-1262259116,-1737350839},\n{-1329494061,-1686455323}, {-1394679021,-1632959413}, {-1457713485,-1576945595},\n{-1518500258,-1518500240}, {-1576945613,-1457713466}, {-1632959429,-1394679001},\n{-1686455338,-1329494041}, {-1737350854,-1262259096}, {-1785567498,-1193077837},\n{-1831030924,-1122056937}, {-1873671031,-1049305905}, {-1913422071,-974936918},\n{-1950222750,-899064648}, {-1984016324,-821806084}, {-2014750687,-743280354},\n{-2042378447,-663608538}, {-2066856867,-582913978}, {-2088148499,-501320119},\n{-2106220354,-418953261}, {-2121044568,-335940406}, {-2132598282,-252409555},\n{-2140863681,-168489506}, {-2145828021,-84309659}, {-2147483647,188},\n{-2145828006,84310034}, {-2140863651,168489881}, {-2132598237,252409928},\n{-2121044509,335940777}, {-2106220281,418953629}, {-2088148411,501320484},\n{-2066856765,582914339}, {-2042378331,663608895}, {-2014750557,743280706},\n{-1984016181,821806431}, {-1950222593,899064989}, {-1913421900,974937252},\n{-1873670848,1049306232}, {-1831030728,1122057257}, {-1785567289,1193078149},\n{-1737350633,1262259400}, {-1686455106,1329494336}, {-1632959185,1394679287},\n{-1576945358,1457713742}, {-1518499993,1518500506}, {-1457713209,1576945850},\n{-1394678735,1632959656}, {-1329493766,1686455555}, {-1262258813,1737351059},\n{-1193077546,1785567692}, {-1122056638,1831031107}, {-1049305599,1873671202},\n{-974936606,1913422229}, {-899064330,1950222896}, {-821805761,1984016458},\n{-743280025,2014750808}, {-663609179,2042378239}, {-582914134,2066856823},\n{-501320277,2088148461}, {-418953420,2106220322}, {-335940566,2121044542},\n{-252409716,2132598263}, {-168489668,2140863668}, {-84309821,2145828015},\n};\nstatic const ne10_fft_cpx_int32_t ne10_twiddles_240[240] = {\n{0,0}, {2147483647,0}, {2147483647,0},\n{2147483647,0}, {1961823921,-873460313}, {1436946998,-1595891394},\n{2147483647,0}, {1436946998,-1595891394}, {-224473265,-2135719496},\n{2147483647,0}, {663608871,-2042378339}, {-1737350854,-1262259096},\n{2147483647,0}, {-224473265,-2135719496}, {-2100555935,446487152},\n{2147483647,0}, {2135719506,-224473172}, {2100555974,-446486968},\n{2042378310,-663608960}, {1961823921,-873460313}, {1859775377,-1073741851},\n{1737350743,-1262259248}, {1595891331,-1436947067}, {1436946998,-1595891394},\n{1262259172,-1737350799}, {1073741769,-1859775424}, {873460227,-1961823959},\n{663608871,-2042378339}, {446486876,-2100555994}, {224473078,-2135719516},\n{2147483647,0}, {2100555974,-446486968}, {1961823921,-873460313},\n{1737350743,-1262259248}, {1436946998,-1595891394}, {1073741769,-1859775424},\n{663608871,-2042378339}, {224473078,-2135719516}, {-224473265,-2135719496},\n{-663609049,-2042378281}, {-1073741932,-1859775330}, {-1436947137,-1595891268},\n{-1737350854,-1262259096}, {-1961823997,-873460141}, {-2100556013,-446486785},\n{2147483647,0}, {2042378310,-663608960}, {1737350743,-1262259248},\n{1262259172,-1737350799}, {663608871,-2042378339}, {-94,-2147483647},\n{-663609049,-2042378281}, {-1262259116,-1737350839}, {-1737350854,-1262259096},\n{-2042378447,-663608538}, {-2147483647,188}, {-2042378331,663608895},\n{-1737350633,1262259400}, {-1262258813,1737351059}, {-663609179,2042378239},\n{2147483647,0}, {2146747758,-56214570}, {2144540595,-112390613},\n{2140863671,-168489630}, {2135719506,-224473172}, {2129111626,-280302871},\n{2121044558,-335940465}, {2111523833,-391347822}, {2100555974,-446486968},\n{2088148500,-501320115}, {2074309912,-555809682}, {2059049696,-609918325},\n{2042378310,-663608960}, {2024307180,-716844791}, {2004848691,-769589332},\n{1984016179,-821806435}, {1961823921,-873460313}, {1938287127,-924515564},\n{1913421927,-974937199}, {1887245364,-1024690661}, {1859775377,-1073741851},\n{1831030826,-1122057097}, {1801031311,-1169603450}, {1769797456,-1216348214},\n{1737350743,-1262259248}, {1703713340,-1307305194}, {1668908218,-1351455280},\n{1632959307,-1394679144}, {1595891331,-1436947067}, {1557729613,-1478230181},\n{1518500216,-1518500282}, {1478230113,-1557729677}, {1436946998,-1595891394},\n{1394679073,-1632959368}, {1351455207,-1668908277}, {1307305120,-1703713397},\n{1262259172,-1737350799}, {1216348136,-1769797510}, {1169603371,-1801031362},\n{1122057017,-1831030875}, {1073741769,-1859775424}, {1024690635,-1887245378},\n{974937230,-1913421912}, {924515422,-1938287195}, {873460227,-1961823959},\n{821806407,-1984016190}, {769589125,-2004848771}, {716844642,-2024307233},\n{663608871,-2042378339}, {609918296,-2059049705}, {555809715,-2074309903},\n{501319962,-2088148536}, {446486876,-2100555994}, {391347792,-2111523838},\n{335940246,-2121044593}, {280302715,-2129111646}, {224473078,-2135719516},\n{168489600,-2140863674}, {112390647,-2144540593}, {56214412,-2146747762},\n{2147483647,0}, {2144540595,-112390613}, {2135719506,-224473172},\n{2121044558,-335940465}, {2100555974,-446486968}, {2074309912,-555809682},\n{2042378310,-663608960}, {2004848691,-769589332}, {1961823921,-873460313},\n{1913421927,-974937199}, {1859775377,-1073741851}, {1801031311,-1169603450},\n{1737350743,-1262259248}, {1668908218,-1351455280}, {1595891331,-1436947067},\n{1518500216,-1518500282}, {1436946998,-1595891394}, {1351455207,-1668908277},\n{1262259172,-1737350799}, {1169603371,-1801031362}, {1073741769,-1859775424},\n{974937230,-1913421912}, {873460227,-1961823959}, {769589125,-2004848771},\n{663608871,-2042378339}, {555809715,-2074309903}, {446486876,-2100555994},\n{335940246,-2121044593}, {224473078,-2135719516}, {112390647,-2144540593},\n{-94,-2147483647}, {-112390835,-2144540584}, {-224473265,-2135719496},\n{-335940431,-2121044564}, {-446487060,-2100555955}, {-555809896,-2074309855},\n{-663609049,-2042378281}, {-769589300,-2004848703}, {-873460398,-1961823883},\n{-974937397,-1913421827}, {-1073741932,-1859775330}, {-1169603421,-1801031330},\n{-1262259116,-1737350839}, {-1351455453,-1668908078}, {-1436947137,-1595891268},\n{-1518500258,-1518500240}, {-1595891628,-1436946738}, {-1668908417,-1351455035},\n{-1737350854,-1262259096}, {-1801031344,-1169603400}, {-1859775343,-1073741910},\n{-1913422071,-974936918}, {-1961823997,-873460141}, {-2004848713,-769589276},\n{-2042378447,-663608538}, {-2074309994,-555809377}, {-2100556013,-446486785},\n{-2121044568,-335940406}, {-2135719499,-224473240}, {-2144540612,-112390298},\n{2147483647,0}, {2140863671,-168489630}, {2121044558,-335940465},\n{2088148500,-501320115}, {2042378310,-663608960}, {1984016179,-821806435},\n{1913421927,-974937199}, {1831030826,-1122057097}, {1737350743,-1262259248},\n{1632959307,-1394679144}, {1518500216,-1518500282}, {1394679073,-1632959368},\n{1262259172,-1737350799}, {1122057017,-1831030875}, {974937230,-1913421912},\n{821806407,-1984016190}, {663608871,-2042378339}, {501319962,-2088148536},\n{335940246,-2121044593}, {168489600,-2140863674}, {-94,-2147483647},\n{-168489787,-2140863659}, {-335940431,-2121044564}, {-501320144,-2088148493},\n{-663609049,-2042378281}, {-821806581,-1984016118}, {-974937397,-1913421827},\n{-1122057395,-1831030643}, {-1262259116,-1737350839}, {-1394679021,-1632959413},\n{-1518500258,-1518500240}, {-1632959429,-1394679001}, {-1737350854,-1262259096},\n{-1831030924,-1122056937}, {-1913422071,-974936918}, {-1984016324,-821806084},\n{-2042378447,-663608538}, {-2088148499,-501320119}, {-2121044568,-335940406},\n{-2140863681,-168489506}, {-2147483647,188}, {-2140863651,168489881},\n{-2121044509,335940777}, {-2088148411,501320484}, {-2042378331,663608895},\n{-1984016181,821806431}, {-1913421900,974937252}, {-1831030728,1122057257},\n{-1737350633,1262259400}, {-1632959185,1394679287}, {-1518499993,1518500506},\n{-1394678735,1632959656}, {-1262258813,1737351059}, {-1122056638,1831031107},\n{-974936606,1913422229}, {-821805761,1984016458}, {-663609179,2042378239},\n{-501320277,2088148461}, {-335940566,2121044542}, {-168489668,2140863668},\n};\nstatic const ne10_fft_cpx_int32_t ne10_twiddles_120[120] = {\n{0,0}, {2147483647,0}, {2147483647,0},\n{2147483647,0}, {1961823921,-873460313}, {1436946998,-1595891394},\n{2147483647,0}, {1436946998,-1595891394}, {-224473265,-2135719496},\n{2147483647,0}, {663608871,-2042378339}, {-1737350854,-1262259096},\n{2147483647,0}, {-224473265,-2135719496}, {-2100555935,446487152},\n{2147483647,0}, {2100555974,-446486968}, {1961823921,-873460313},\n{1737350743,-1262259248}, {1436946998,-1595891394}, {1073741769,-1859775424},\n{663608871,-2042378339}, {224473078,-2135719516}, {-224473265,-2135719496},\n{-663609049,-2042378281}, {-1073741932,-1859775330}, {-1436947137,-1595891268},\n{-1737350854,-1262259096}, {-1961823997,-873460141}, {-2100556013,-446486785},\n{2147483647,0}, {2144540595,-112390613}, {2135719506,-224473172},\n{2121044558,-335940465}, {2100555974,-446486968}, {2074309912,-555809682},\n{2042378310,-663608960}, {2004848691,-769589332}, {1961823921,-873460313},\n{1913421927,-974937199}, {1859775377,-1073741851}, {1801031311,-1169603450},\n{1737350743,-1262259248}, {1668908218,-1351455280}, {1595891331,-1436947067},\n{1518500216,-1518500282}, {1436946998,-1595891394}, {1351455207,-1668908277},\n{1262259172,-1737350799}, {1169603371,-1801031362}, {1073741769,-1859775424},\n{974937230,-1913421912}, {873460227,-1961823959}, {769589125,-2004848771},\n{663608871,-2042378339}, {555809715,-2074309903}, {446486876,-2100555994},\n{335940246,-2121044593}, {224473078,-2135719516}, {112390647,-2144540593},\n{2147483647,0}, {2135719506,-224473172}, {2100555974,-446486968},\n{2042378310,-663608960}, {1961823921,-873460313}, {1859775377,-1073741851},\n{1737350743,-1262259248}, {1595891331,-1436947067}, {1436946998,-1595891394},\n{1262259172,-1737350799}, {1073741769,-1859775424}, {873460227,-1961823959},\n{663608871,-2042378339}, {446486876,-2100555994}, {224473078,-2135719516},\n{-94,-2147483647}, {-224473265,-2135719496}, {-446487060,-2100555955},\n{-663609049,-2042378281}, {-873460398,-1961823883}, {-1073741932,-1859775330},\n{-1262259116,-1737350839}, {-1436947137,-1595891268}, {-1595891628,-1436946738},\n{-1737350854,-1262259096}, {-1859775343,-1073741910}, {-1961823997,-873460141},\n{-2042378447,-663608538}, {-2100556013,-446486785}, {-2135719499,-224473240},\n{2147483647,0}, {2121044558,-335940465}, {2042378310,-663608960},\n{1913421927,-974937199}, {1737350743,-1262259248}, {1518500216,-1518500282},\n{1262259172,-1737350799}, {974937230,-1913421912}, {663608871,-2042378339},\n{335940246,-2121044593}, {-94,-2147483647}, {-335940431,-2121044564},\n{-663609049,-2042378281}, {-974937397,-1913421827}, {-1262259116,-1737350839},\n{-1518500258,-1518500240}, {-1737350854,-1262259096}, {-1913422071,-974936918},\n{-2042378447,-663608538}, {-2121044568,-335940406}, {-2147483647,188},\n{-2121044509,335940777}, {-2042378331,663608895}, {-1913421900,974937252},\n{-1737350633,1262259400}, {-1518499993,1518500506}, {-1262258813,1737351059},\n{-974936606,1913422229}, {-663609179,2042378239}, {-335940566,2121044542},\n};\nstatic const ne10_fft_cpx_int32_t ne10_twiddles_60[60] = {\n{0,0}, {2147483647,0}, {2147483647,0},\n{2147483647,0}, {1961823921,-873460313}, {1436946998,-1595891394},\n{2147483647,0}, {1436946998,-1595891394}, {-224473265,-2135719496},\n{2147483647,0}, {663608871,-2042378339}, {-1737350854,-1262259096},\n{2147483647,0}, {-224473265,-2135719496}, {-2100555935,446487152},\n{2147483647,0}, {2135719506,-224473172}, {2100555974,-446486968},\n{2042378310,-663608960}, {1961823921,-873460313}, {1859775377,-1073741851},\n{1737350743,-1262259248}, {1595891331,-1436947067}, {1436946998,-1595891394},\n{1262259172,-1737350799}, {1073741769,-1859775424}, {873460227,-1961823959},\n{663608871,-2042378339}, {446486876,-2100555994}, {224473078,-2135719516},\n{2147483647,0}, {2100555974,-446486968}, {1961823921,-873460313},\n{1737350743,-1262259248}, {1436946998,-1595891394}, {1073741769,-1859775424},\n{663608871,-2042378339}, {224473078,-2135719516}, {-224473265,-2135719496},\n{-663609049,-2042378281}, {-1073741932,-1859775330}, {-1436947137,-1595891268},\n{-1737350854,-1262259096}, {-1961823997,-873460141}, {-2100556013,-446486785},\n{2147483647,0}, {2042378310,-663608960}, {1737350743,-1262259248},\n{1262259172,-1737350799}, {663608871,-2042378339}, {-94,-2147483647},\n{-663609049,-2042378281}, {-1262259116,-1737350839}, {-1737350854,-1262259096},\n{-2042378447,-663608538}, {-2147483647,188}, {-2042378331,663608895},\n{-1737350633,1262259400}, {-1262258813,1737351059}, {-663609179,2042378239},\n};\nstatic const ne10_fft_state_int32_t ne10_fft_state_int32_t_480 = {\n120,\n(ne10_int32_t *)ne10_factors_480,\n(ne10_fft_cpx_int32_t *)ne10_twiddles_480,\nNULL,\n(ne10_fft_cpx_int32_t *)&ne10_twiddles_480[120],\n};\nstatic const arch_fft_state cfg_arch_480 = {\n1,\n(void *)&ne10_fft_state_int32_t_480,\n};\n\nstatic const ne10_fft_state_int32_t ne10_fft_state_int32_t_240 = {\n60,\n(ne10_int32_t *)ne10_factors_240,\n(ne10_fft_cpx_int32_t *)ne10_twiddles_240,\nNULL,\n(ne10_fft_cpx_int32_t *)&ne10_twiddles_240[60],\n};\nstatic const arch_fft_state cfg_arch_240 = {\n1,\n(void *)&ne10_fft_state_int32_t_240,\n};\n\nstatic const ne10_fft_state_int32_t ne10_fft_state_int32_t_120 = {\n30,\n(ne10_int32_t *)ne10_factors_120,\n(ne10_fft_cpx_int32_t *)ne10_twiddles_120,\nNULL,\n(ne10_fft_cpx_int32_t *)&ne10_twiddles_120[30],\n};\nstatic const arch_fft_state cfg_arch_120 = {\n1,\n(void *)&ne10_fft_state_int32_t_120,\n};\n\nstatic const ne10_fft_state_int32_t ne10_fft_state_int32_t_60 = {\n15,\n(ne10_int32_t *)ne10_factors_60,\n(ne10_fft_cpx_int32_t *)ne10_twiddles_60,\nNULL,\n(ne10_fft_cpx_int32_t *)&ne10_twiddles_60[15],\n};\nstatic const arch_fft_state cfg_arch_60 = {\n1,\n(void *)&ne10_fft_state_int32_t_60,\n};\n\n#endif  /* end NE10_FFT_PARAMS48000_960 */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/static_modes_float.h",
    "content": "/* The contents of this file was automatically generated by dump_modes.c\n   with arguments: 48000 960\n   It contains static definitions for some pre-defined modes. */\n#include \"modes.h\"\n#include \"rate.h\"\n\n#ifdef HAVE_ARM_NE10\n#define OVERRIDE_FFT 1\n#include \"static_modes_float_arm_ne10.h\"\n#endif\n\n#ifndef DEF_WINDOW120\n#define DEF_WINDOW120\nstatic const opus_val16 window120[120] = {\n6.7286966e-05f, 0.00060551348f, 0.0016815970f, 0.0032947962f, 0.0054439943f,\n0.0081276923f, 0.011344001f, 0.015090633f, 0.019364886f, 0.024163635f,\n0.029483315f, 0.035319905f, 0.041668911f, 0.048525347f, 0.055883718f,\n0.063737999f, 0.072081616f, 0.080907428f, 0.090207705f, 0.099974111f,\n0.11019769f, 0.12086883f, 0.13197729f, 0.14351214f, 0.15546177f,\n0.16781389f, 0.18055550f, 0.19367290f, 0.20715171f, 0.22097682f,\n0.23513243f, 0.24960208f, 0.26436860f, 0.27941419f, 0.29472040f,\n0.31026818f, 0.32603788f, 0.34200931f, 0.35816177f, 0.37447407f,\n0.39092462f, 0.40749142f, 0.42415215f, 0.44088423f, 0.45766484f,\n0.47447104f, 0.49127978f, 0.50806798f, 0.52481261f, 0.54149077f,\n0.55807973f, 0.57455701f, 0.59090049f, 0.60708841f, 0.62309951f,\n0.63891306f, 0.65450896f, 0.66986776f, 0.68497077f, 0.69980010f,\n0.71433873f, 0.72857055f, 0.74248043f, 0.75605424f, 0.76927895f,\n0.78214257f, 0.79463430f, 0.80674445f, 0.81846456f, 0.82978733f,\n0.84070669f, 0.85121779f, 0.86131698f, 0.87100183f, 0.88027111f,\n0.88912479f, 0.89756398f, 0.90559094f, 0.91320904f, 0.92042270f,\n0.92723738f, 0.93365955f, 0.93969656f, 0.94535671f, 0.95064907f,\n0.95558353f, 0.96017067f, 0.96442171f, 0.96834849f, 0.97196334f,\n0.97527906f, 0.97830883f, 0.98106616f, 0.98356480f, 0.98581869f,\n0.98784191f, 0.98964856f, 0.99125274f, 0.99266849f, 0.99390969f,\n0.99499004f, 0.99592297f, 0.99672162f, 0.99739874f, 0.99796667f,\n0.99843728f, 0.99882195f, 0.99913147f, 0.99937606f, 0.99956527f,\n0.99970802f, 0.99981248f, 0.99988613f, 0.99993565f, 0.99996697f,\n0.99998518f, 0.99999457f, 0.99999859f, 0.99999982f, 1.0000000f,\n};\n#endif\n\n#ifndef DEF_LOGN400\n#define DEF_LOGN400\nstatic const opus_int16 logN400[21] = {\n0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, };\n#endif\n\n#ifndef DEF_PULSE_CACHE50\n#define DEF_PULSE_CACHE50\nstatic const opus_int16 cache_index50[105] = {\n-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41,\n82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41,\n41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41,\n41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305,\n318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240,\n305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240,\n240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387,\n};\nstatic const unsigned char cache_bits50[392] = {\n40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28,\n31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50,\n51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65,\n66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61,\n64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92,\n94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123,\n124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94,\n97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139,\n142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35,\n28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149,\n153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225,\n229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157,\n166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63,\n86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250,\n25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180,\n185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89,\n110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41,\n74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138,\n163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214,\n228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49,\n90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47,\n87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57,\n106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187,\n224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127,\n182, 234, };\nstatic const unsigned char cache_caps50[168] = {\n224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185,\n178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240,\n240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160,\n160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193, 183, 183, 172,\n138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207,\n204, 204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185,\n185, 185, 193, 193, 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39,\n207, 207, 207, 207, 207, 207, 207, 207, 204, 204, 204, 204, 201, 201, 201,\n188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193, 193, 193,\n193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204,\n204, 204, 204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175,\n140, 66, 40, };\n#endif\n\n#ifndef FFT_TWIDDLES48000_960\n#define FFT_TWIDDLES48000_960\nstatic const kiss_twiddle_cpx fft_twiddles48000_960[480] = {\n{1.0000000f, -0.0000000f}, {0.99991433f, -0.013089596f},\n{0.99965732f, -0.026176948f}, {0.99922904f, -0.039259816f},\n{0.99862953f, -0.052335956f}, {0.99785892f, -0.065403129f},\n{0.99691733f, -0.078459096f}, {0.99580493f, -0.091501619f},\n{0.99452190f, -0.10452846f}, {0.99306846f, -0.11753740f},\n{0.99144486f, -0.13052619f}, {0.98965139f, -0.14349262f},\n{0.98768834f, -0.15643447f}, {0.98555606f, -0.16934950f},\n{0.98325491f, -0.18223553f}, {0.98078528f, -0.19509032f},\n{0.97814760f, -0.20791169f}, {0.97534232f, -0.22069744f},\n{0.97236992f, -0.23344536f}, {0.96923091f, -0.24615329f},\n{0.96592583f, -0.25881905f}, {0.96245524f, -0.27144045f},\n{0.95881973f, -0.28401534f}, {0.95501994f, -0.29654157f},\n{0.95105652f, -0.30901699f}, {0.94693013f, -0.32143947f},\n{0.94264149f, -0.33380686f}, {0.93819134f, -0.34611706f},\n{0.93358043f, -0.35836795f}, {0.92880955f, -0.37055744f},\n{0.92387953f, -0.38268343f}, {0.91879121f, -0.39474386f},\n{0.91354546f, -0.40673664f}, {0.90814317f, -0.41865974f},\n{0.90258528f, -0.43051110f}, {0.89687274f, -0.44228869f},\n{0.89100652f, -0.45399050f}, {0.88498764f, -0.46561452f},\n{0.87881711f, -0.47715876f}, {0.87249601f, -0.48862124f},\n{0.86602540f, -0.50000000f}, {0.85940641f, -0.51129309f},\n{0.85264016f, -0.52249856f}, {0.84572782f, -0.53361452f},\n{0.83867057f, -0.54463904f}, {0.83146961f, -0.55557023f},\n{0.82412619f, -0.56640624f}, {0.81664156f, -0.57714519f},\n{0.80901699f, -0.58778525f}, {0.80125381f, -0.59832460f},\n{0.79335334f, -0.60876143f}, {0.78531693f, -0.61909395f},\n{0.77714596f, -0.62932039f}, {0.76884183f, -0.63943900f},\n{0.76040597f, -0.64944805f}, {0.75183981f, -0.65934582f},\n{0.74314483f, -0.66913061f}, {0.73432251f, -0.67880075f},\n{0.72537437f, -0.68835458f}, {0.71630194f, -0.69779046f},\n{0.70710678f, -0.70710678f}, {0.69779046f, -0.71630194f},\n{0.68835458f, -0.72537437f}, {0.67880075f, -0.73432251f},\n{0.66913061f, -0.74314483f}, {0.65934582f, -0.75183981f},\n{0.64944805f, -0.76040597f}, {0.63943900f, -0.76884183f},\n{0.62932039f, -0.77714596f}, {0.61909395f, -0.78531693f},\n{0.60876143f, -0.79335334f}, {0.59832460f, -0.80125381f},\n{0.58778525f, -0.80901699f}, {0.57714519f, -0.81664156f},\n{0.56640624f, -0.82412619f}, {0.55557023f, -0.83146961f},\n{0.54463904f, -0.83867057f}, {0.53361452f, -0.84572782f},\n{0.52249856f, -0.85264016f}, {0.51129309f, -0.85940641f},\n{0.50000000f, -0.86602540f}, {0.48862124f, -0.87249601f},\n{0.47715876f, -0.87881711f}, {0.46561452f, -0.88498764f},\n{0.45399050f, -0.89100652f}, {0.44228869f, -0.89687274f},\n{0.43051110f, -0.90258528f}, {0.41865974f, -0.90814317f},\n{0.40673664f, -0.91354546f}, {0.39474386f, -0.91879121f},\n{0.38268343f, -0.92387953f}, {0.37055744f, -0.92880955f},\n{0.35836795f, -0.93358043f}, {0.34611706f, -0.93819134f},\n{0.33380686f, -0.94264149f}, {0.32143947f, -0.94693013f},\n{0.30901699f, -0.95105652f}, {0.29654157f, -0.95501994f},\n{0.28401534f, -0.95881973f}, {0.27144045f, -0.96245524f},\n{0.25881905f, -0.96592583f}, {0.24615329f, -0.96923091f},\n{0.23344536f, -0.97236992f}, {0.22069744f, -0.97534232f},\n{0.20791169f, -0.97814760f}, {0.19509032f, -0.98078528f},\n{0.18223553f, -0.98325491f}, {0.16934950f, -0.98555606f},\n{0.15643447f, -0.98768834f}, {0.14349262f, -0.98965139f},\n{0.13052619f, -0.99144486f}, {0.11753740f, -0.99306846f},\n{0.10452846f, -0.99452190f}, {0.091501619f, -0.99580493f},\n{0.078459096f, -0.99691733f}, {0.065403129f, -0.99785892f},\n{0.052335956f, -0.99862953f}, {0.039259816f, -0.99922904f},\n{0.026176948f, -0.99965732f}, {0.013089596f, -0.99991433f},\n{6.1230318e-17f, -1.0000000f}, {-0.013089596f, -0.99991433f},\n{-0.026176948f, -0.99965732f}, {-0.039259816f, -0.99922904f},\n{-0.052335956f, -0.99862953f}, {-0.065403129f, -0.99785892f},\n{-0.078459096f, -0.99691733f}, {-0.091501619f, -0.99580493f},\n{-0.10452846f, -0.99452190f}, {-0.11753740f, -0.99306846f},\n{-0.13052619f, -0.99144486f}, {-0.14349262f, -0.98965139f},\n{-0.15643447f, -0.98768834f}, {-0.16934950f, -0.98555606f},\n{-0.18223553f, -0.98325491f}, {-0.19509032f, -0.98078528f},\n{-0.20791169f, -0.97814760f}, {-0.22069744f, -0.97534232f},\n{-0.23344536f, -0.97236992f}, {-0.24615329f, -0.96923091f},\n{-0.25881905f, -0.96592583f}, {-0.27144045f, -0.96245524f},\n{-0.28401534f, -0.95881973f}, {-0.29654157f, -0.95501994f},\n{-0.30901699f, -0.95105652f}, {-0.32143947f, -0.94693013f},\n{-0.33380686f, -0.94264149f}, {-0.34611706f, -0.93819134f},\n{-0.35836795f, -0.93358043f}, {-0.37055744f, -0.92880955f},\n{-0.38268343f, -0.92387953f}, {-0.39474386f, -0.91879121f},\n{-0.40673664f, -0.91354546f}, {-0.41865974f, -0.90814317f},\n{-0.43051110f, -0.90258528f}, {-0.44228869f, -0.89687274f},\n{-0.45399050f, -0.89100652f}, {-0.46561452f, -0.88498764f},\n{-0.47715876f, -0.87881711f}, {-0.48862124f, -0.87249601f},\n{-0.50000000f, -0.86602540f}, {-0.51129309f, -0.85940641f},\n{-0.52249856f, -0.85264016f}, {-0.53361452f, -0.84572782f},\n{-0.54463904f, -0.83867057f}, {-0.55557023f, -0.83146961f},\n{-0.56640624f, -0.82412619f}, {-0.57714519f, -0.81664156f},\n{-0.58778525f, -0.80901699f}, {-0.59832460f, -0.80125381f},\n{-0.60876143f, -0.79335334f}, {-0.61909395f, -0.78531693f},\n{-0.62932039f, -0.77714596f}, {-0.63943900f, -0.76884183f},\n{-0.64944805f, -0.76040597f}, {-0.65934582f, -0.75183981f},\n{-0.66913061f, -0.74314483f}, {-0.67880075f, -0.73432251f},\n{-0.68835458f, -0.72537437f}, {-0.69779046f, -0.71630194f},\n{-0.70710678f, -0.70710678f}, {-0.71630194f, -0.69779046f},\n{-0.72537437f, -0.68835458f}, {-0.73432251f, -0.67880075f},\n{-0.74314483f, -0.66913061f}, {-0.75183981f, -0.65934582f},\n{-0.76040597f, -0.64944805f}, {-0.76884183f, -0.63943900f},\n{-0.77714596f, -0.62932039f}, {-0.78531693f, -0.61909395f},\n{-0.79335334f, -0.60876143f}, {-0.80125381f, -0.59832460f},\n{-0.80901699f, -0.58778525f}, {-0.81664156f, -0.57714519f},\n{-0.82412619f, -0.56640624f}, {-0.83146961f, -0.55557023f},\n{-0.83867057f, -0.54463904f}, {-0.84572782f, -0.53361452f},\n{-0.85264016f, -0.52249856f}, {-0.85940641f, -0.51129309f},\n{-0.86602540f, -0.50000000f}, {-0.87249601f, -0.48862124f},\n{-0.87881711f, -0.47715876f}, {-0.88498764f, -0.46561452f},\n{-0.89100652f, -0.45399050f}, {-0.89687274f, -0.44228869f},\n{-0.90258528f, -0.43051110f}, {-0.90814317f, -0.41865974f},\n{-0.91354546f, -0.40673664f}, {-0.91879121f, -0.39474386f},\n{-0.92387953f, -0.38268343f}, {-0.92880955f, -0.37055744f},\n{-0.93358043f, -0.35836795f}, {-0.93819134f, -0.34611706f},\n{-0.94264149f, -0.33380686f}, {-0.94693013f, -0.32143947f},\n{-0.95105652f, -0.30901699f}, {-0.95501994f, -0.29654157f},\n{-0.95881973f, -0.28401534f}, {-0.96245524f, -0.27144045f},\n{-0.96592583f, -0.25881905f}, {-0.96923091f, -0.24615329f},\n{-0.97236992f, -0.23344536f}, {-0.97534232f, -0.22069744f},\n{-0.97814760f, -0.20791169f}, {-0.98078528f, -0.19509032f},\n{-0.98325491f, -0.18223553f}, {-0.98555606f, -0.16934950f},\n{-0.98768834f, -0.15643447f}, {-0.98965139f, -0.14349262f},\n{-0.99144486f, -0.13052619f}, {-0.99306846f, -0.11753740f},\n{-0.99452190f, -0.10452846f}, {-0.99580493f, -0.091501619f},\n{-0.99691733f, -0.078459096f}, {-0.99785892f, -0.065403129f},\n{-0.99862953f, -0.052335956f}, {-0.99922904f, -0.039259816f},\n{-0.99965732f, -0.026176948f}, {-0.99991433f, -0.013089596f},\n{-1.0000000f, -1.2246064e-16f}, {-0.99991433f, 0.013089596f},\n{-0.99965732f, 0.026176948f}, {-0.99922904f, 0.039259816f},\n{-0.99862953f, 0.052335956f}, {-0.99785892f, 0.065403129f},\n{-0.99691733f, 0.078459096f}, {-0.99580493f, 0.091501619f},\n{-0.99452190f, 0.10452846f}, {-0.99306846f, 0.11753740f},\n{-0.99144486f, 0.13052619f}, {-0.98965139f, 0.14349262f},\n{-0.98768834f, 0.15643447f}, {-0.98555606f, 0.16934950f},\n{-0.98325491f, 0.18223553f}, {-0.98078528f, 0.19509032f},\n{-0.97814760f, 0.20791169f}, {-0.97534232f, 0.22069744f},\n{-0.97236992f, 0.23344536f}, {-0.96923091f, 0.24615329f},\n{-0.96592583f, 0.25881905f}, {-0.96245524f, 0.27144045f},\n{-0.95881973f, 0.28401534f}, {-0.95501994f, 0.29654157f},\n{-0.95105652f, 0.30901699f}, {-0.94693013f, 0.32143947f},\n{-0.94264149f, 0.33380686f}, {-0.93819134f, 0.34611706f},\n{-0.93358043f, 0.35836795f}, {-0.92880955f, 0.37055744f},\n{-0.92387953f, 0.38268343f}, {-0.91879121f, 0.39474386f},\n{-0.91354546f, 0.40673664f}, {-0.90814317f, 0.41865974f},\n{-0.90258528f, 0.43051110f}, {-0.89687274f, 0.44228869f},\n{-0.89100652f, 0.45399050f}, {-0.88498764f, 0.46561452f},\n{-0.87881711f, 0.47715876f}, {-0.87249601f, 0.48862124f},\n{-0.86602540f, 0.50000000f}, {-0.85940641f, 0.51129309f},\n{-0.85264016f, 0.52249856f}, {-0.84572782f, 0.53361452f},\n{-0.83867057f, 0.54463904f}, {-0.83146961f, 0.55557023f},\n{-0.82412619f, 0.56640624f}, {-0.81664156f, 0.57714519f},\n{-0.80901699f, 0.58778525f}, {-0.80125381f, 0.59832460f},\n{-0.79335334f, 0.60876143f}, {-0.78531693f, 0.61909395f},\n{-0.77714596f, 0.62932039f}, {-0.76884183f, 0.63943900f},\n{-0.76040597f, 0.64944805f}, {-0.75183981f, 0.65934582f},\n{-0.74314483f, 0.66913061f}, {-0.73432251f, 0.67880075f},\n{-0.72537437f, 0.68835458f}, {-0.71630194f, 0.69779046f},\n{-0.70710678f, 0.70710678f}, {-0.69779046f, 0.71630194f},\n{-0.68835458f, 0.72537437f}, {-0.67880075f, 0.73432251f},\n{-0.66913061f, 0.74314483f}, {-0.65934582f, 0.75183981f},\n{-0.64944805f, 0.76040597f}, {-0.63943900f, 0.76884183f},\n{-0.62932039f, 0.77714596f}, {-0.61909395f, 0.78531693f},\n{-0.60876143f, 0.79335334f}, {-0.59832460f, 0.80125381f},\n{-0.58778525f, 0.80901699f}, {-0.57714519f, 0.81664156f},\n{-0.56640624f, 0.82412619f}, {-0.55557023f, 0.83146961f},\n{-0.54463904f, 0.83867057f}, {-0.53361452f, 0.84572782f},\n{-0.52249856f, 0.85264016f}, {-0.51129309f, 0.85940641f},\n{-0.50000000f, 0.86602540f}, {-0.48862124f, 0.87249601f},\n{-0.47715876f, 0.87881711f}, {-0.46561452f, 0.88498764f},\n{-0.45399050f, 0.89100652f}, {-0.44228869f, 0.89687274f},\n{-0.43051110f, 0.90258528f}, {-0.41865974f, 0.90814317f},\n{-0.40673664f, 0.91354546f}, {-0.39474386f, 0.91879121f},\n{-0.38268343f, 0.92387953f}, {-0.37055744f, 0.92880955f},\n{-0.35836795f, 0.93358043f}, {-0.34611706f, 0.93819134f},\n{-0.33380686f, 0.94264149f}, {-0.32143947f, 0.94693013f},\n{-0.30901699f, 0.95105652f}, {-0.29654157f, 0.95501994f},\n{-0.28401534f, 0.95881973f}, {-0.27144045f, 0.96245524f},\n{-0.25881905f, 0.96592583f}, {-0.24615329f, 0.96923091f},\n{-0.23344536f, 0.97236992f}, {-0.22069744f, 0.97534232f},\n{-0.20791169f, 0.97814760f}, {-0.19509032f, 0.98078528f},\n{-0.18223553f, 0.98325491f}, {-0.16934950f, 0.98555606f},\n{-0.15643447f, 0.98768834f}, {-0.14349262f, 0.98965139f},\n{-0.13052619f, 0.99144486f}, {-0.11753740f, 0.99306846f},\n{-0.10452846f, 0.99452190f}, {-0.091501619f, 0.99580493f},\n{-0.078459096f, 0.99691733f}, {-0.065403129f, 0.99785892f},\n{-0.052335956f, 0.99862953f}, {-0.039259816f, 0.99922904f},\n{-0.026176948f, 0.99965732f}, {-0.013089596f, 0.99991433f},\n{-1.8369095e-16f, 1.0000000f}, {0.013089596f, 0.99991433f},\n{0.026176948f, 0.99965732f}, {0.039259816f, 0.99922904f},\n{0.052335956f, 0.99862953f}, {0.065403129f, 0.99785892f},\n{0.078459096f, 0.99691733f}, {0.091501619f, 0.99580493f},\n{0.10452846f, 0.99452190f}, {0.11753740f, 0.99306846f},\n{0.13052619f, 0.99144486f}, {0.14349262f, 0.98965139f},\n{0.15643447f, 0.98768834f}, {0.16934950f, 0.98555606f},\n{0.18223553f, 0.98325491f}, {0.19509032f, 0.98078528f},\n{0.20791169f, 0.97814760f}, {0.22069744f, 0.97534232f},\n{0.23344536f, 0.97236992f}, {0.24615329f, 0.96923091f},\n{0.25881905f, 0.96592583f}, {0.27144045f, 0.96245524f},\n{0.28401534f, 0.95881973f}, {0.29654157f, 0.95501994f},\n{0.30901699f, 0.95105652f}, {0.32143947f, 0.94693013f},\n{0.33380686f, 0.94264149f}, {0.34611706f, 0.93819134f},\n{0.35836795f, 0.93358043f}, {0.37055744f, 0.92880955f},\n{0.38268343f, 0.92387953f}, {0.39474386f, 0.91879121f},\n{0.40673664f, 0.91354546f}, {0.41865974f, 0.90814317f},\n{0.43051110f, 0.90258528f}, {0.44228869f, 0.89687274f},\n{0.45399050f, 0.89100652f}, {0.46561452f, 0.88498764f},\n{0.47715876f, 0.87881711f}, {0.48862124f, 0.87249601f},\n{0.50000000f, 0.86602540f}, {0.51129309f, 0.85940641f},\n{0.52249856f, 0.85264016f}, {0.53361452f, 0.84572782f},\n{0.54463904f, 0.83867057f}, {0.55557023f, 0.83146961f},\n{0.56640624f, 0.82412619f}, {0.57714519f, 0.81664156f},\n{0.58778525f, 0.80901699f}, {0.59832460f, 0.80125381f},\n{0.60876143f, 0.79335334f}, {0.61909395f, 0.78531693f},\n{0.62932039f, 0.77714596f}, {0.63943900f, 0.76884183f},\n{0.64944805f, 0.76040597f}, {0.65934582f, 0.75183981f},\n{0.66913061f, 0.74314483f}, {0.67880075f, 0.73432251f},\n{0.68835458f, 0.72537437f}, {0.69779046f, 0.71630194f},\n{0.70710678f, 0.70710678f}, {0.71630194f, 0.69779046f},\n{0.72537437f, 0.68835458f}, {0.73432251f, 0.67880075f},\n{0.74314483f, 0.66913061f}, {0.75183981f, 0.65934582f},\n{0.76040597f, 0.64944805f}, {0.76884183f, 0.63943900f},\n{0.77714596f, 0.62932039f}, {0.78531693f, 0.61909395f},\n{0.79335334f, 0.60876143f}, {0.80125381f, 0.59832460f},\n{0.80901699f, 0.58778525f}, {0.81664156f, 0.57714519f},\n{0.82412619f, 0.56640624f}, {0.83146961f, 0.55557023f},\n{0.83867057f, 0.54463904f}, {0.84572782f, 0.53361452f},\n{0.85264016f, 0.52249856f}, {0.85940641f, 0.51129309f},\n{0.86602540f, 0.50000000f}, {0.87249601f, 0.48862124f},\n{0.87881711f, 0.47715876f}, {0.88498764f, 0.46561452f},\n{0.89100652f, 0.45399050f}, {0.89687274f, 0.44228869f},\n{0.90258528f, 0.43051110f}, {0.90814317f, 0.41865974f},\n{0.91354546f, 0.40673664f}, {0.91879121f, 0.39474386f},\n{0.92387953f, 0.38268343f}, {0.92880955f, 0.37055744f},\n{0.93358043f, 0.35836795f}, {0.93819134f, 0.34611706f},\n{0.94264149f, 0.33380686f}, {0.94693013f, 0.32143947f},\n{0.95105652f, 0.30901699f}, {0.95501994f, 0.29654157f},\n{0.95881973f, 0.28401534f}, {0.96245524f, 0.27144045f},\n{0.96592583f, 0.25881905f}, {0.96923091f, 0.24615329f},\n{0.97236992f, 0.23344536f}, {0.97534232f, 0.22069744f},\n{0.97814760f, 0.20791169f}, {0.98078528f, 0.19509032f},\n{0.98325491f, 0.18223553f}, {0.98555606f, 0.16934950f},\n{0.98768834f, 0.15643447f}, {0.98965139f, 0.14349262f},\n{0.99144486f, 0.13052619f}, {0.99306846f, 0.11753740f},\n{0.99452190f, 0.10452846f}, {0.99580493f, 0.091501619f},\n{0.99691733f, 0.078459096f}, {0.99785892f, 0.065403129f},\n{0.99862953f, 0.052335956f}, {0.99922904f, 0.039259816f},\n{0.99965732f, 0.026176948f}, {0.99991433f, 0.013089596f},\n};\n#ifndef FFT_BITREV480\n#define FFT_BITREV480\nstatic const opus_int16 fft_bitrev480[480] = {\n0, 96, 192, 288, 384, 32, 128, 224, 320, 416, 64, 160, 256, 352, 448,\n8, 104, 200, 296, 392, 40, 136, 232, 328, 424, 72, 168, 264, 360, 456,\n16, 112, 208, 304, 400, 48, 144, 240, 336, 432, 80, 176, 272, 368, 464,\n24, 120, 216, 312, 408, 56, 152, 248, 344, 440, 88, 184, 280, 376, 472,\n4, 100, 196, 292, 388, 36, 132, 228, 324, 420, 68, 164, 260, 356, 452,\n12, 108, 204, 300, 396, 44, 140, 236, 332, 428, 76, 172, 268, 364, 460,\n20, 116, 212, 308, 404, 52, 148, 244, 340, 436, 84, 180, 276, 372, 468,\n28, 124, 220, 316, 412, 60, 156, 252, 348, 444, 92, 188, 284, 380, 476,\n1, 97, 193, 289, 385, 33, 129, 225, 321, 417, 65, 161, 257, 353, 449,\n9, 105, 201, 297, 393, 41, 137, 233, 329, 425, 73, 169, 265, 361, 457,\n17, 113, 209, 305, 401, 49, 145, 241, 337, 433, 81, 177, 273, 369, 465,\n25, 121, 217, 313, 409, 57, 153, 249, 345, 441, 89, 185, 281, 377, 473,\n5, 101, 197, 293, 389, 37, 133, 229, 325, 421, 69, 165, 261, 357, 453,\n13, 109, 205, 301, 397, 45, 141, 237, 333, 429, 77, 173, 269, 365, 461,\n21, 117, 213, 309, 405, 53, 149, 245, 341, 437, 85, 181, 277, 373, 469,\n29, 125, 221, 317, 413, 61, 157, 253, 349, 445, 93, 189, 285, 381, 477,\n2, 98, 194, 290, 386, 34, 130, 226, 322, 418, 66, 162, 258, 354, 450,\n10, 106, 202, 298, 394, 42, 138, 234, 330, 426, 74, 170, 266, 362, 458,\n18, 114, 210, 306, 402, 50, 146, 242, 338, 434, 82, 178, 274, 370, 466,\n26, 122, 218, 314, 410, 58, 154, 250, 346, 442, 90, 186, 282, 378, 474,\n6, 102, 198, 294, 390, 38, 134, 230, 326, 422, 70, 166, 262, 358, 454,\n14, 110, 206, 302, 398, 46, 142, 238, 334, 430, 78, 174, 270, 366, 462,\n22, 118, 214, 310, 406, 54, 150, 246, 342, 438, 86, 182, 278, 374, 470,\n30, 126, 222, 318, 414, 62, 158, 254, 350, 446, 94, 190, 286, 382, 478,\n3, 99, 195, 291, 387, 35, 131, 227, 323, 419, 67, 163, 259, 355, 451,\n11, 107, 203, 299, 395, 43, 139, 235, 331, 427, 75, 171, 267, 363, 459,\n19, 115, 211, 307, 403, 51, 147, 243, 339, 435, 83, 179, 275, 371, 467,\n27, 123, 219, 315, 411, 59, 155, 251, 347, 443, 91, 187, 283, 379, 475,\n7, 103, 199, 295, 391, 39, 135, 231, 327, 423, 71, 167, 263, 359, 455,\n15, 111, 207, 303, 399, 47, 143, 239, 335, 431, 79, 175, 271, 367, 463,\n23, 119, 215, 311, 407, 55, 151, 247, 343, 439, 87, 183, 279, 375, 471,\n31, 127, 223, 319, 415, 63, 159, 255, 351, 447, 95, 191, 287, 383, 479,\n};\n#endif\n\n#ifndef FFT_BITREV240\n#define FFT_BITREV240\nstatic const opus_int16 fft_bitrev240[240] = {\n0, 48, 96, 144, 192, 16, 64, 112, 160, 208, 32, 80, 128, 176, 224,\n4, 52, 100, 148, 196, 20, 68, 116, 164, 212, 36, 84, 132, 180, 228,\n8, 56, 104, 152, 200, 24, 72, 120, 168, 216, 40, 88, 136, 184, 232,\n12, 60, 108, 156, 204, 28, 76, 124, 172, 220, 44, 92, 140, 188, 236,\n1, 49, 97, 145, 193, 17, 65, 113, 161, 209, 33, 81, 129, 177, 225,\n5, 53, 101, 149, 197, 21, 69, 117, 165, 213, 37, 85, 133, 181, 229,\n9, 57, 105, 153, 201, 25, 73, 121, 169, 217, 41, 89, 137, 185, 233,\n13, 61, 109, 157, 205, 29, 77, 125, 173, 221, 45, 93, 141, 189, 237,\n2, 50, 98, 146, 194, 18, 66, 114, 162, 210, 34, 82, 130, 178, 226,\n6, 54, 102, 150, 198, 22, 70, 118, 166, 214, 38, 86, 134, 182, 230,\n10, 58, 106, 154, 202, 26, 74, 122, 170, 218, 42, 90, 138, 186, 234,\n14, 62, 110, 158, 206, 30, 78, 126, 174, 222, 46, 94, 142, 190, 238,\n3, 51, 99, 147, 195, 19, 67, 115, 163, 211, 35, 83, 131, 179, 227,\n7, 55, 103, 151, 199, 23, 71, 119, 167, 215, 39, 87, 135, 183, 231,\n11, 59, 107, 155, 203, 27, 75, 123, 171, 219, 43, 91, 139, 187, 235,\n15, 63, 111, 159, 207, 31, 79, 127, 175, 223, 47, 95, 143, 191, 239,\n};\n#endif\n\n#ifndef FFT_BITREV120\n#define FFT_BITREV120\nstatic const opus_int16 fft_bitrev120[120] = {\n0, 24, 48, 72, 96, 8, 32, 56, 80, 104, 16, 40, 64, 88, 112,\n4, 28, 52, 76, 100, 12, 36, 60, 84, 108, 20, 44, 68, 92, 116,\n1, 25, 49, 73, 97, 9, 33, 57, 81, 105, 17, 41, 65, 89, 113,\n5, 29, 53, 77, 101, 13, 37, 61, 85, 109, 21, 45, 69, 93, 117,\n2, 26, 50, 74, 98, 10, 34, 58, 82, 106, 18, 42, 66, 90, 114,\n6, 30, 54, 78, 102, 14, 38, 62, 86, 110, 22, 46, 70, 94, 118,\n3, 27, 51, 75, 99, 11, 35, 59, 83, 107, 19, 43, 67, 91, 115,\n7, 31, 55, 79, 103, 15, 39, 63, 87, 111, 23, 47, 71, 95, 119,\n};\n#endif\n\n#ifndef FFT_BITREV60\n#define FFT_BITREV60\nstatic const opus_int16 fft_bitrev60[60] = {\n0, 12, 24, 36, 48, 4, 16, 28, 40, 52, 8, 20, 32, 44, 56,\n1, 13, 25, 37, 49, 5, 17, 29, 41, 53, 9, 21, 33, 45, 57,\n2, 14, 26, 38, 50, 6, 18, 30, 42, 54, 10, 22, 34, 46, 58,\n3, 15, 27, 39, 51, 7, 19, 31, 43, 55, 11, 23, 35, 47, 59,\n};\n#endif\n\n#ifndef FFT_STATE48000_960_0\n#define FFT_STATE48000_960_0\nstatic const kiss_fft_state fft_state48000_960_0 = {\n480,    /* nfft */\n0.002083333f,   /* scale */\n-1,     /* shift */\n{5, 96, 3, 32, 4, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, },   /* factors */\nfft_bitrev480,  /* bitrev */\nfft_twiddles48000_960,  /* bitrev */\n#ifdef OVERRIDE_FFT\n(arch_fft_state *)&cfg_arch_480,\n#else\nNULL,\n#endif\n};\n#endif\n\n#ifndef FFT_STATE48000_960_1\n#define FFT_STATE48000_960_1\nstatic const kiss_fft_state fft_state48000_960_1 = {\n240,    /* nfft */\n0.004166667f,   /* scale */\n1,      /* shift */\n{5, 48, 3, 16, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, },    /* factors */\nfft_bitrev240,  /* bitrev */\nfft_twiddles48000_960,  /* bitrev */\n#ifdef OVERRIDE_FFT\n(arch_fft_state *)&cfg_arch_240,\n#else\nNULL,\n#endif\n};\n#endif\n\n#ifndef FFT_STATE48000_960_2\n#define FFT_STATE48000_960_2\nstatic const kiss_fft_state fft_state48000_960_2 = {\n120,    /* nfft */\n0.008333333f,   /* scale */\n2,      /* shift */\n{5, 24, 3, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, },    /* factors */\nfft_bitrev120,  /* bitrev */\nfft_twiddles48000_960,  /* bitrev */\n#ifdef OVERRIDE_FFT\n(arch_fft_state *)&cfg_arch_120,\n#else\nNULL,\n#endif\n};\n#endif\n\n#ifndef FFT_STATE48000_960_3\n#define FFT_STATE48000_960_3\nstatic const kiss_fft_state fft_state48000_960_3 = {\n60,     /* nfft */\n0.016666667f,   /* scale */\n3,      /* shift */\n{5, 12, 3, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },    /* factors */\nfft_bitrev60,   /* bitrev */\nfft_twiddles48000_960,  /* bitrev */\n#ifdef OVERRIDE_FFT\n(arch_fft_state *)&cfg_arch_60,\n#else\nNULL,\n#endif\n};\n#endif\n\n#endif\n\n#ifndef MDCT_TWIDDLES960\n#define MDCT_TWIDDLES960\nstatic const opus_val16 mdct_twiddles960[1800] = {\n0.99999994f, 0.99999321f, 0.99997580f, 0.99994773f, 0.99990886f,\n0.99985933f, 0.99979913f, 0.99972820f, 0.99964654f, 0.99955416f,\n0.99945110f, 0.99933738f, 0.99921292f, 0.99907774f, 0.99893188f,\n0.99877530f, 0.99860805f, 0.99843007f, 0.99824142f, 0.99804211f,\n0.99783206f, 0.99761140f, 0.99737996f, 0.99713790f, 0.99688518f,\n0.99662173f, 0.99634761f, 0.99606287f, 0.99576741f, 0.99546129f,\n0.99514455f, 0.99481714f, 0.99447906f, 0.99413031f, 0.99377096f,\n0.99340093f, 0.99302030f, 0.99262899f, 0.99222708f, 0.99181455f,\n0.99139136f, 0.99095762f, 0.99051321f, 0.99005818f, 0.98959261f,\n0.98911643f, 0.98862964f, 0.98813224f, 0.98762429f, 0.98710573f,\n0.98657662f, 0.98603696f, 0.98548669f, 0.98492593f, 0.98435456f,\n0.98377270f, 0.98318028f, 0.98257732f, 0.98196387f, 0.98133987f,\n0.98070538f, 0.98006040f, 0.97940493f, 0.97873890f, 0.97806245f,\n0.97737551f, 0.97667813f, 0.97597027f, 0.97525197f, 0.97452319f,\n0.97378403f, 0.97303438f, 0.97227436f, 0.97150391f, 0.97072303f,\n0.96993178f, 0.96913016f, 0.96831810f, 0.96749574f, 0.96666300f,\n0.96581990f, 0.96496642f, 0.96410263f, 0.96322852f, 0.96234411f,\n0.96144938f, 0.96054435f, 0.95962906f, 0.95870346f, 0.95776761f,\n0.95682150f, 0.95586514f, 0.95489854f, 0.95392174f, 0.95293468f,\n0.95193744f, 0.95093000f, 0.94991243f, 0.94888461f, 0.94784665f,\n0.94679856f, 0.94574034f, 0.94467193f, 0.94359344f, 0.94250488f,\n0.94140619f, 0.94029742f, 0.93917859f, 0.93804967f, 0.93691075f,\n0.93576175f, 0.93460274f, 0.93343377f, 0.93225473f, 0.93106574f,\n0.92986679f, 0.92865789f, 0.92743903f, 0.92621022f, 0.92497152f,\n0.92372292f, 0.92246443f, 0.92119598f, 0.91991776f, 0.91862965f,\n0.91733170f, 0.91602397f, 0.91470635f, 0.91337901f, 0.91204184f,\n0.91069490f, 0.90933824f, 0.90797186f, 0.90659571f, 0.90520984f,\n0.90381432f, 0.90240908f, 0.90099424f, 0.89956969f, 0.89813554f,\n0.89669174f, 0.89523834f, 0.89377540f, 0.89230281f, 0.89082074f,\n0.88932908f, 0.88782793f, 0.88631725f, 0.88479710f, 0.88326746f,\n0.88172835f, 0.88017982f, 0.87862182f, 0.87705445f, 0.87547767f,\n0.87389153f, 0.87229604f, 0.87069118f, 0.86907703f, 0.86745358f,\n0.86582077f, 0.86417878f, 0.86252749f, 0.86086690f, 0.85919720f,\n0.85751826f, 0.85583007f, 0.85413277f, 0.85242635f, 0.85071075f,\n0.84898609f, 0.84725231f, 0.84550947f, 0.84375757f, 0.84199661f,\n0.84022665f, 0.83844769f, 0.83665979f, 0.83486289f, 0.83305705f,\n0.83124226f, 0.82941860f, 0.82758605f, 0.82574469f, 0.82389444f,\n0.82203537f, 0.82016748f, 0.81829083f, 0.81640542f, 0.81451124f,\n0.81260836f, 0.81069672f, 0.80877650f, 0.80684757f, 0.80490994f,\n0.80296379f, 0.80100900f, 0.79904562f, 0.79707366f, 0.79509324f,\n0.79310423f, 0.79110676f, 0.78910083f, 0.78708643f, 0.78506362f,\n0.78303236f, 0.78099275f, 0.77894479f, 0.77688843f, 0.77482378f,\n0.77275085f, 0.77066964f, 0.76858020f, 0.76648247f, 0.76437658f,\n0.76226246f, 0.76014024f, 0.75800985f, 0.75587130f, 0.75372469f,\n0.75157005f, 0.74940729f, 0.74723655f, 0.74505776f, 0.74287105f,\n0.74067634f, 0.73847371f, 0.73626316f, 0.73404479f, 0.73181850f,\n0.72958434f, 0.72734243f, 0.72509271f, 0.72283524f, 0.72057003f,\n0.71829706f, 0.71601641f, 0.71372813f, 0.71143216f, 0.70912862f,\n0.70681745f, 0.70449871f, 0.70217246f, 0.69983864f, 0.69749737f,\n0.69514859f, 0.69279242f, 0.69042879f, 0.68805778f, 0.68567938f,\n0.68329364f, 0.68090063f, 0.67850029f, 0.67609268f, 0.67367786f,\n0.67125577f, 0.66882652f, 0.66639012f, 0.66394657f, 0.66149592f,\n0.65903819f, 0.65657341f, 0.65410155f, 0.65162271f, 0.64913690f,\n0.64664418f, 0.64414448f, 0.64163786f, 0.63912445f, 0.63660413f,\n0.63407701f, 0.63154310f, 0.62900239f, 0.62645501f, 0.62390089f,\n0.62134010f, 0.61877263f, 0.61619854f, 0.61361790f, 0.61103064f,\n0.60843682f, 0.60583651f, 0.60322970f, 0.60061646f, 0.59799677f,\n0.59537065f, 0.59273821f, 0.59009939f, 0.58745426f, 0.58480281f,\n0.58214509f, 0.57948118f, 0.57681108f, 0.57413477f, 0.57145232f,\n0.56876373f, 0.56606907f, 0.56336832f, 0.56066155f, 0.55794877f,\n0.55523002f, 0.55250537f, 0.54977477f, 0.54703826f, 0.54429591f,\n0.54154772f, 0.53879374f, 0.53603399f, 0.53326851f, 0.53049731f,\n0.52772039f, 0.52493787f, 0.52214974f, 0.51935595f, 0.51655668f,\n0.51375180f, 0.51094145f, 0.50812566f, 0.50530440f, 0.50247771f,\n0.49964568f, 0.49680826f, 0.49396557f, 0.49111754f, 0.48826426f,\n0.48540577f, 0.48254207f, 0.47967321f, 0.47679919f, 0.47392011f,\n0.47103590f, 0.46814668f, 0.46525243f, 0.46235323f, 0.45944905f,\n0.45653993f, 0.45362595f, 0.45070711f, 0.44778344f, 0.44485497f,\n0.44192174f, 0.43898380f, 0.43604112f, 0.43309379f, 0.43014181f,\n0.42718524f, 0.42422408f, 0.42125839f, 0.41828820f, 0.41531351f,\n0.41233435f, 0.40935081f, 0.40636289f, 0.40337059f, 0.40037400f,\n0.39737311f, 0.39436796f, 0.39135858f, 0.38834500f, 0.38532731f,\n0.38230544f, 0.37927949f, 0.37624949f, 0.37321547f, 0.37017745f,\n0.36713544f, 0.36408952f, 0.36103970f, 0.35798600f, 0.35492846f,\n0.35186714f, 0.34880206f, 0.34573323f, 0.34266070f, 0.33958447f,\n0.33650464f, 0.33342120f, 0.33033419f, 0.32724363f, 0.32414958f,\n0.32105204f, 0.31795108f, 0.31484672f, 0.31173897f, 0.30862790f,\n0.30551350f, 0.30239585f, 0.29927495f, 0.29615086f, 0.29302359f,\n0.28989318f, 0.28675964f, 0.28362307f, 0.28048345f, 0.27734083f,\n0.27419522f, 0.27104670f, 0.26789525f, 0.26474094f, 0.26158381f,\n0.25842386f, 0.25526115f, 0.25209570f, 0.24892756f, 0.24575676f,\n0.24258332f, 0.23940729f, 0.23622867f, 0.23304754f, 0.22986393f,\n0.22667783f, 0.22348931f, 0.22029841f, 0.21710514f, 0.21390954f,\n0.21071166f, 0.20751151f, 0.20430915f, 0.20110460f, 0.19789790f,\n0.19468907f, 0.19147816f, 0.18826519f, 0.18505022f, 0.18183327f,\n0.17861435f, 0.17539354f, 0.17217083f, 0.16894630f, 0.16571994f,\n0.16249183f, 0.15926196f, 0.15603039f, 0.15279715f, 0.14956227f,\n0.14632578f, 0.14308774f, 0.13984816f, 0.13660708f, 0.13336454f,\n0.13012058f, 0.12687522f, 0.12362850f, 0.12038045f, 0.11713112f,\n0.11388054f, 0.11062872f, 0.10737573f, 0.10412160f, 0.10086634f,\n0.097609997f, 0.094352618f, 0.091094226f, 0.087834857f, 0.084574550f,\n0.081313334f, 0.078051247f, 0.074788325f, 0.071524605f, 0.068260118f,\n0.064994894f, 0.061728980f, 0.058462404f, 0.055195201f, 0.051927410f,\n0.048659060f, 0.045390189f, 0.042120833f, 0.038851023f, 0.035580799f,\n0.032310195f, 0.029039243f, 0.025767982f, 0.022496443f, 0.019224664f,\n0.015952680f, 0.012680525f, 0.0094082337f, 0.0061358409f, 0.0028633832f,\n-0.00040910527f, -0.0036815894f, -0.0069540343f, -0.010226404f, -0.013498665f,\n-0.016770782f, -0.020042717f, -0.023314439f, -0.026585912f, -0.029857099f,\n-0.033127967f, -0.036398482f, -0.039668605f, -0.042938303f, -0.046207540f,\n-0.049476285f, -0.052744497f, -0.056012146f, -0.059279196f, -0.062545612f,\n-0.065811358f, -0.069076397f, -0.072340697f, -0.075604223f, -0.078866936f,\n-0.082128808f, -0.085389800f, -0.088649876f, -0.091909006f, -0.095167145f,\n-0.098424271f, -0.10168034f, -0.10493532f, -0.10818918f, -0.11144188f,\n-0.11469338f, -0.11794366f, -0.12119267f, -0.12444039f, -0.12768677f,\n-0.13093179f, -0.13417540f, -0.13741758f, -0.14065829f, -0.14389749f,\n-0.14713514f, -0.15037122f, -0.15360570f, -0.15683852f, -0.16006967f,\n-0.16329910f, -0.16652679f, -0.16975269f, -0.17297678f, -0.17619900f,\n-0.17941935f, -0.18263777f, -0.18585424f, -0.18906870f, -0.19228116f,\n-0.19549155f, -0.19869985f, -0.20190603f, -0.20511003f, -0.20831184f,\n-0.21151142f, -0.21470875f, -0.21790376f, -0.22109644f, -0.22428675f,\n-0.22747467f, -0.23066014f, -0.23384315f, -0.23702365f, -0.24020162f,\n-0.24337701f, -0.24654980f, -0.24971995f, -0.25288740f, -0.25605217f,\n-0.25921419f, -0.26237345f, -0.26552987f, -0.26868346f, -0.27183419f,\n-0.27498198f, -0.27812684f, -0.28126872f, -0.28440759f, -0.28754342f,\n-0.29067615f, -0.29380578f, -0.29693225f, -0.30005556f, -0.30317566f,\n-0.30629250f, -0.30940607f, -0.31251630f, -0.31562322f, -0.31872672f,\n-0.32182685f, -0.32492352f, -0.32801670f, -0.33110636f, -0.33419248f,\n-0.33727503f, -0.34035397f, -0.34342924f, -0.34650084f, -0.34956875f,\n-0.35263291f, -0.35569328f, -0.35874987f, -0.36180258f, -0.36485144f,\n-0.36789638f, -0.37093741f, -0.37397444f, -0.37700745f, -0.38003644f,\n-0.38306138f, -0.38608220f, -0.38909888f, -0.39211139f, -0.39511973f,\n-0.39812380f, -0.40112361f, -0.40411916f, -0.40711036f, -0.41009718f,\n-0.41307965f, -0.41605768f, -0.41903123f, -0.42200032f, -0.42496487f,\n-0.42792490f, -0.43088034f, -0.43383113f, -0.43677729f, -0.43971881f,\n-0.44265559f, -0.44558764f, -0.44851488f, -0.45143735f, -0.45435500f,\n-0.45726776f, -0.46017563f, -0.46307856f, -0.46597654f, -0.46886954f,\n-0.47175750f, -0.47464043f, -0.47751826f, -0.48039100f, -0.48325855f,\n-0.48612097f, -0.48897815f, -0.49183011f, -0.49467680f, -0.49751821f,\n-0.50035429f, -0.50318497f, -0.50601029f, -0.50883019f, -0.51164466f,\n-0.51445359f, -0.51725709f, -0.52005500f, -0.52284735f, -0.52563411f,\n-0.52841520f, -0.53119069f, -0.53396046f, -0.53672451f, -0.53948283f,\n-0.54223537f, -0.54498214f, -0.54772300f, -0.55045801f, -0.55318713f,\n-0.55591035f, -0.55862761f, -0.56133890f, -0.56404412f, -0.56674337f,\n-0.56943649f, -0.57212353f, -0.57480448f, -0.57747924f, -0.58014780f,\n-0.58281022f, -0.58546633f, -0.58811617f, -0.59075975f, -0.59339696f,\n-0.59602785f, -0.59865236f, -0.60127044f, -0.60388207f, -0.60648727f,\n-0.60908598f, -0.61167812f, -0.61426371f, -0.61684275f, -0.61941516f,\n-0.62198097f, -0.62454009f, -0.62709254f, -0.62963831f, -0.63217729f,\n-0.63470948f, -0.63723493f, -0.63975352f, -0.64226526f, -0.64477009f,\n-0.64726806f, -0.64975911f, -0.65224314f, -0.65472025f, -0.65719032f,\n-0.65965337f, -0.66210932f, -0.66455823f, -0.66700000f, -0.66943461f,\n-0.67186207f, -0.67428231f, -0.67669535f, -0.67910111f, -0.68149966f,\n-0.68389088f, -0.68627477f, -0.68865126f, -0.69102043f, -0.69338220f,\n-0.69573659f, -0.69808346f, -0.70042288f, -0.70275480f, -0.70507920f,\n-0.70739603f, -0.70970529f, -0.71200693f, -0.71430099f, -0.71658736f,\n-0.71886611f, -0.72113711f, -0.72340041f, -0.72565591f, -0.72790372f,\n-0.73014367f, -0.73237586f, -0.73460019f, -0.73681659f, -0.73902518f,\n-0.74122584f, -0.74341851f, -0.74560326f, -0.74778003f, -0.74994880f,\n-0.75210953f, -0.75426215f, -0.75640678f, -0.75854325f, -0.76067162f,\n-0.76279181f, -0.76490390f, -0.76700771f, -0.76910341f, -0.77119076f,\n-0.77326995f, -0.77534080f, -0.77740335f, -0.77945763f, -0.78150350f,\n-0.78354102f, -0.78557014f, -0.78759086f, -0.78960317f, -0.79160696f,\n-0.79360235f, -0.79558921f, -0.79756755f, -0.79953730f, -0.80149853f,\n-0.80345118f, -0.80539525f, -0.80733067f, -0.80925739f, -0.81117553f,\n-0.81308490f, -0.81498563f, -0.81687760f, -0.81876087f, -0.82063532f,\n-0.82250100f, -0.82435787f, -0.82620591f, -0.82804507f, -0.82987541f,\n-0.83169687f, -0.83350939f, -0.83531296f, -0.83710766f, -0.83889335f,\n-0.84067005f, -0.84243774f, -0.84419644f, -0.84594607f, -0.84768665f,\n-0.84941816f, -0.85114056f, -0.85285389f, -0.85455805f, -0.85625303f,\n-0.85793889f, -0.85961550f, -0.86128294f, -0.86294121f, -0.86459017f,\n-0.86622989f, -0.86786032f, -0.86948150f, -0.87109333f, -0.87269586f,\n-0.87428904f, -0.87587279f, -0.87744725f, -0.87901229f, -0.88056785f,\n-0.88211405f, -0.88365078f, -0.88517809f, -0.88669586f, -0.88820416f,\n-0.88970292f, -0.89119220f, -0.89267188f, -0.89414203f, -0.89560264f,\n-0.89705360f, -0.89849502f, -0.89992678f, -0.90134889f, -0.90276134f,\n-0.90416414f, -0.90555727f, -0.90694070f, -0.90831441f, -0.90967834f,\n-0.91103262f, -0.91237706f, -0.91371179f, -0.91503674f, -0.91635185f,\n-0.91765714f, -0.91895264f, -0.92023826f, -0.92151409f, -0.92277998f,\n-0.92403603f, -0.92528218f, -0.92651838f, -0.92774469f, -0.92896110f,\n-0.93016750f, -0.93136400f, -0.93255049f, -0.93372697f, -0.93489349f,\n-0.93604994f, -0.93719643f, -0.93833286f, -0.93945926f, -0.94057560f,\n-0.94168180f, -0.94277799f, -0.94386405f, -0.94494003f, -0.94600588f,\n-0.94706154f, -0.94810712f, -0.94914252f, -0.95016778f, -0.95118284f,\n-0.95218778f, -0.95318246f, -0.95416695f, -0.95514119f, -0.95610523f,\n-0.95705903f, -0.95800257f, -0.95893586f, -0.95985889f, -0.96077162f,\n-0.96167403f, -0.96256620f, -0.96344805f, -0.96431959f, -0.96518075f,\n-0.96603161f, -0.96687216f, -0.96770233f, -0.96852213f, -0.96933156f,\n-0.97013056f, -0.97091925f, -0.97169751f, -0.97246534f, -0.97322279f,\n-0.97396982f, -0.97470641f, -0.97543252f, -0.97614825f, -0.97685349f,\n-0.97754824f, -0.97823256f, -0.97890645f, -0.97956979f, -0.98022264f,\n-0.98086500f, -0.98149687f, -0.98211825f, -0.98272908f, -0.98332942f,\n-0.98391914f, -0.98449844f, -0.98506713f, -0.98562527f, -0.98617285f,\n-0.98670989f, -0.98723638f, -0.98775226f, -0.98825759f, -0.98875231f,\n-0.98923647f, -0.98971003f, -0.99017298f, -0.99062532f, -0.99106705f,\n-0.99149817f, -0.99191868f, -0.99232858f, -0.99272782f, -0.99311644f,\n-0.99349445f, -0.99386179f, -0.99421853f, -0.99456459f, -0.99489999f,\n-0.99522477f, -0.99553883f, -0.99584228f, -0.99613506f, -0.99641716f,\n-0.99668860f, -0.99694937f, -0.99719942f, -0.99743885f, -0.99766755f,\n-0.99788558f, -0.99809295f, -0.99828959f, -0.99847561f, -0.99865085f,\n-0.99881548f, -0.99896932f, -0.99911255f, -0.99924499f, -0.99936682f,\n-0.99947786f, -0.99957830f, -0.99966794f, -0.99974692f, -0.99981517f,\n-0.99987274f, -0.99991959f, -0.99995571f, -0.99998116f, -0.99999589f,\n0.99999964f, 0.99997288f, 0.99990326f, 0.99979085f, 0.99963558f,\n0.99943751f, 0.99919659f, 0.99891287f, 0.99858636f, 0.99821711f,\n0.99780506f, 0.99735034f, 0.99685282f, 0.99631262f, 0.99572974f,\n0.99510419f, 0.99443603f, 0.99372530f, 0.99297196f, 0.99217612f,\n0.99133772f, 0.99045694f, 0.98953366f, 0.98856801f, 0.98756003f,\n0.98650974f, 0.98541719f, 0.98428243f, 0.98310548f, 0.98188645f,\n0.98062533f, 0.97932225f, 0.97797716f, 0.97659022f, 0.97516143f,\n0.97369087f, 0.97217858f, 0.97062469f, 0.96902919f, 0.96739221f,\n0.96571374f, 0.96399397f, 0.96223283f, 0.96043050f, 0.95858705f,\n0.95670253f, 0.95477700f, 0.95281059f, 0.95080340f, 0.94875544f,\n0.94666684f, 0.94453770f, 0.94236809f, 0.94015813f, 0.93790787f,\n0.93561745f, 0.93328691f, 0.93091643f, 0.92850608f, 0.92605597f,\n0.92356616f, 0.92103678f, 0.91846794f, 0.91585976f, 0.91321236f,\n0.91052586f, 0.90780038f, 0.90503591f, 0.90223277f, 0.89939094f,\n0.89651060f, 0.89359182f, 0.89063478f, 0.88763964f, 0.88460642f,\n0.88153529f, 0.87842643f, 0.87527996f, 0.87209594f, 0.86887461f,\n0.86561602f, 0.86232042f, 0.85898781f, 0.85561842f, 0.85221243f,\n0.84876984f, 0.84529096f, 0.84177583f, 0.83822471f, 0.83463764f,\n0.83101481f, 0.82735640f, 0.82366252f, 0.81993335f, 0.81616908f,\n0.81236988f, 0.80853581f, 0.80466717f, 0.80076402f, 0.79682660f,\n0.79285502f, 0.78884947f, 0.78481019f, 0.78073722f, 0.77663082f,\n0.77249116f, 0.76831841f, 0.76411277f, 0.75987434f, 0.75560343f,\n0.75130010f, 0.74696463f, 0.74259710f, 0.73819780f, 0.73376691f,\n0.72930455f, 0.72481096f, 0.72028631f, 0.71573079f, 0.71114463f,\n0.70652801f, 0.70188117f, 0.69720417f, 0.69249737f, 0.68776089f,\n0.68299496f, 0.67819971f, 0.67337549f, 0.66852236f, 0.66364062f,\n0.65873051f, 0.65379208f, 0.64882571f, 0.64383155f, 0.63880974f,\n0.63376063f, 0.62868434f, 0.62358117f, 0.61845124f, 0.61329484f,\n0.60811216f, 0.60290343f, 0.59766883f, 0.59240872f, 0.58712316f,\n0.58181250f, 0.57647687f, 0.57111657f, 0.56573176f, 0.56032276f,\n0.55488980f, 0.54943299f, 0.54395270f, 0.53844911f, 0.53292239f,\n0.52737290f, 0.52180082f, 0.51620632f, 0.51058978f, 0.50495136f,\n0.49929130f, 0.49360985f, 0.48790723f, 0.48218375f, 0.47643960f,\n0.47067502f, 0.46489030f, 0.45908567f, 0.45326138f, 0.44741765f,\n0.44155475f, 0.43567297f, 0.42977250f, 0.42385364f, 0.41791660f,\n0.41196167f, 0.40598908f, 0.39999911f, 0.39399201f, 0.38796803f,\n0.38192743f, 0.37587047f, 0.36979741f, 0.36370850f, 0.35760403f,\n0.35148421f, 0.34534934f, 0.33919969f, 0.33303553f, 0.32685706f,\n0.32066461f, 0.31445843f, 0.30823877f, 0.30200592f, 0.29576012f,\n0.28950164f, 0.28323078f, 0.27694780f, 0.27065292f, 0.26434645f,\n0.25802869f, 0.25169984f, 0.24536023f, 0.23901010f, 0.23264973f,\n0.22627939f, 0.21989937f, 0.21350993f, 0.20711134f, 0.20070387f,\n0.19428782f, 0.18786344f, 0.18143101f, 0.17499080f, 0.16854310f,\n0.16208819f, 0.15562633f, 0.14915779f, 0.14268288f, 0.13620184f,\n0.12971498f, 0.12322257f, 0.11672486f, 0.11022217f, 0.10371475f,\n0.097202882f, 0.090686858f, 0.084166944f, 0.077643424f, 0.071116582f,\n0.064586692f, 0.058054037f, 0.051518895f, 0.044981543f, 0.038442269f,\n0.031901345f, 0.025359053f, 0.018815678f, 0.012271495f, 0.0057267868f,\n-0.00081816671f, -0.0073630852f, -0.013907688f, -0.020451695f, -0.026994826f,\n-0.033536803f, -0.040077340f, -0.046616159f, -0.053152986f, -0.059687532f,\n-0.066219524f, -0.072748676f, -0.079274714f, -0.085797355f, -0.092316322f,\n-0.098831341f, -0.10534211f, -0.11184838f, -0.11834986f, -0.12484626f,\n-0.13133731f, -0.13782275f, -0.14430228f, -0.15077563f, -0.15724251f,\n-0.16370267f, -0.17015581f, -0.17660165f, -0.18303993f, -0.18947038f,\n-0.19589271f, -0.20230664f, -0.20871192f, -0.21510825f, -0.22149536f,\n-0.22787298f, -0.23424086f, -0.24059868f, -0.24694622f, -0.25328314f,\n-0.25960925f, -0.26592422f, -0.27222782f, -0.27851975f, -0.28479972f,\n-0.29106751f, -0.29732284f, -0.30356544f, -0.30979502f, -0.31601134f,\n-0.32221413f, -0.32840309f, -0.33457801f, -0.34073856f, -0.34688455f,\n-0.35301566f, -0.35913166f, -0.36523229f, -0.37131724f, -0.37738630f,\n-0.38343921f, -0.38947567f, -0.39549544f, -0.40149832f, -0.40748394f,\n-0.41345215f, -0.41940263f, -0.42533514f, -0.43124944f, -0.43714526f,\n-0.44302234f, -0.44888046f, -0.45471936f, -0.46053877f, -0.46633846f,\n-0.47211814f, -0.47787762f, -0.48361665f, -0.48933494f, -0.49503228f,\n-0.50070840f, -0.50636309f, -0.51199609f, -0.51760709f, -0.52319598f,\n-0.52876246f, -0.53430629f, -0.53982723f, -0.54532504f, -0.55079949f,\n-0.55625033f, -0.56167740f, -0.56708032f, -0.57245898f, -0.57781315f,\n-0.58314258f, -0.58844697f, -0.59372622f, -0.59897995f, -0.60420811f,\n-0.60941035f, -0.61458647f, -0.61973625f, -0.62485951f, -0.62995601f,\n-0.63502556f, -0.64006782f, -0.64508271f, -0.65007001f, -0.65502942f,\n-0.65996075f, -0.66486382f, -0.66973841f, -0.67458433f, -0.67940134f,\n-0.68418926f, -0.68894786f, -0.69367695f, -0.69837630f, -0.70304573f,\n-0.70768511f, -0.71229410f, -0.71687263f, -0.72142041f, -0.72593731f,\n-0.73042315f, -0.73487765f, -0.73930067f, -0.74369204f, -0.74805158f,\n-0.75237900f, -0.75667429f, -0.76093709f, -0.76516730f, -0.76936477f,\n-0.77352923f, -0.77766061f, -0.78175867f, -0.78582323f, -0.78985411f,\n-0.79385114f, -0.79781419f, -0.80174309f, -0.80563760f, -0.80949765f,\n-0.81332302f, -0.81711352f, -0.82086903f, -0.82458937f, -0.82827437f,\n-0.83192390f, -0.83553779f, -0.83911592f, -0.84265804f, -0.84616417f,\n-0.84963393f, -0.85306740f, -0.85646427f, -0.85982448f, -0.86314780f,\n-0.86643422f, -0.86968350f, -0.87289548f, -0.87607014f, -0.87920725f,\n-0.88230664f, -0.88536829f, -0.88839203f, -0.89137769f, -0.89432514f,\n-0.89723432f, -0.90010506f, -0.90293723f, -0.90573072f, -0.90848541f,\n-0.91120118f, -0.91387796f, -0.91651553f, -0.91911387f, -0.92167282f,\n-0.92419231f, -0.92667222f, -0.92911243f, -0.93151283f, -0.93387336f,\n-0.93619382f, -0.93847424f, -0.94071442f, -0.94291431f, -0.94507378f,\n-0.94719279f, -0.94927126f, -0.95130903f, -0.95330608f, -0.95526224f,\n-0.95717752f, -0.95905179f, -0.96088499f, -0.96267700f, -0.96442777f,\n-0.96613729f, -0.96780539f, -0.96943200f, -0.97101706f, -0.97256058f,\n-0.97406244f, -0.97552258f, -0.97694093f, -0.97831738f, -0.97965199f,\n-0.98094457f, -0.98219514f, -0.98340368f, -0.98457009f, -0.98569429f,\n-0.98677629f, -0.98781598f, -0.98881340f, -0.98976845f, -0.99068111f,\n-0.99155134f, -0.99237907f, -0.99316430f, -0.99390697f, -0.99460709f,\n-0.99526459f, -0.99587947f, -0.99645168f, -0.99698120f, -0.99746799f,\n-0.99791211f, -0.99831343f, -0.99867201f, -0.99898779f, -0.99926084f,\n-0.99949104f, -0.99967843f, -0.99982297f, -0.99992472f, -0.99998361f,\n0.99999869f, 0.99989158f, 0.99961317f, 0.99916345f, 0.99854255f,\n0.99775058f, 0.99678761f, 0.99565387f, 0.99434954f, 0.99287480f,\n0.99122995f, 0.98941529f, 0.98743105f, 0.98527765f, 0.98295540f,\n0.98046476f, 0.97780609f, 0.97497988f, 0.97198665f, 0.96882683f,\n0.96550101f, 0.96200979f, 0.95835376f, 0.95453346f, 0.95054960f,\n0.94640291f, 0.94209403f, 0.93762374f, 0.93299282f, 0.92820197f,\n0.92325211f, 0.91814411f, 0.91287869f, 0.90745693f, 0.90187967f,\n0.89614785f, 0.89026248f, 0.88422459f, 0.87803519f, 0.87169534f,\n0.86520612f, 0.85856867f, 0.85178405f, 0.84485358f, 0.83777827f,\n0.83055943f, 0.82319832f, 0.81569612f, 0.80805415f, 0.80027372f,\n0.79235619f, 0.78430289f, 0.77611518f, 0.76779449f, 0.75934225f,\n0.75075996f, 0.74204898f, 0.73321080f, 0.72424710f, 0.71515924f,\n0.70594883f, 0.69661748f, 0.68716675f, 0.67759830f, 0.66791373f,\n0.65811473f, 0.64820296f, 0.63818014f, 0.62804794f, 0.61780810f,\n0.60746247f, 0.59701276f, 0.58646071f, 0.57580817f, 0.56505698f,\n0.55420899f, 0.54326600f, 0.53222996f, 0.52110273f, 0.50988621f,\n0.49858227f, 0.48719296f, 0.47572014f, 0.46416581f, 0.45253196f,\n0.44082057f, 0.42903364f, 0.41717321f, 0.40524128f, 0.39323992f,\n0.38117120f, 0.36903715f, 0.35683987f, 0.34458145f, 0.33226398f,\n0.31988961f, 0.30746040f, 0.29497850f, 0.28244606f, 0.26986524f,\n0.25723818f, 0.24456702f, 0.23185398f, 0.21910121f, 0.20631088f,\n0.19348522f, 0.18062639f, 0.16773662f, 0.15481812f, 0.14187308f,\n0.12890373f, 0.11591230f, 0.10290100f, 0.089872077f, 0.076827750f,\n0.063770257f, 0.050701842f, 0.037624735f, 0.024541186f, 0.011453429f,\n-0.0016362892f, -0.014725727f, -0.027812643f, -0.040894791f, -0.053969935f,\n-0.067035832f, -0.080090240f, -0.093130924f, -0.10615565f, -0.11916219f,\n-0.13214831f, -0.14511178f, -0.15805040f, -0.17096193f, -0.18384418f,\n-0.19669491f, -0.20951195f, -0.22229309f, -0.23503613f, -0.24773891f,\n-0.26039925f, -0.27301496f, -0.28558388f, -0.29810387f, -0.31057280f,\n-0.32298848f, -0.33534884f, -0.34765175f, -0.35989508f, -0.37207675f,\n-0.38419467f, -0.39624676f, -0.40823093f, -0.42014518f, -0.43198743f,\n-0.44375566f, -0.45544785f, -0.46706200f, -0.47859612f, -0.49004826f,\n-0.50141639f, -0.51269865f, -0.52389306f, -0.53499764f, -0.54601061f,\n-0.55693001f, -0.56775403f, -0.57848072f, -0.58910829f, -0.59963489f,\n-0.61005878f, -0.62037814f, -0.63059121f, -0.64069623f, -0.65069145f,\n-0.66057515f, -0.67034572f, -0.68000144f, -0.68954057f, -0.69896162f,\n-0.70826286f, -0.71744281f, -0.72649974f, -0.73543227f, -0.74423873f,\n-0.75291771f, -0.76146764f, -0.76988715f, -0.77817470f, -0.78632891f,\n-0.79434842f, -0.80223179f, -0.80997771f, -0.81758487f, -0.82505190f,\n-0.83237761f, -0.83956063f, -0.84659988f, -0.85349399f, -0.86024189f,\n-0.86684239f, -0.87329435f, -0.87959671f, -0.88574833f, -0.89174819f,\n-0.89759529f, -0.90328854f, -0.90882701f, -0.91420978f, -0.91943592f,\n-0.92450452f, -0.92941469f, -0.93416560f, -0.93875647f, -0.94318646f,\n-0.94745487f, -0.95156091f, -0.95550388f, -0.95928317f, -0.96289814f,\n-0.96634805f, -0.96963239f, -0.97275060f, -0.97570217f, -0.97848648f,\n-0.98110318f, -0.98355180f, -0.98583186f, -0.98794299f, -0.98988485f,\n-0.99165714f, -0.99325943f, -0.99469161f, -0.99595332f, -0.99704438f,\n-0.99796462f, -0.99871385f, -0.99929196f, -0.99969882f, -0.99993443f,\n0.99999464f, 0.99956632f, 0.99845290f, 0.99665523f, 0.99417448f,\n0.99101239f, 0.98717111f, 0.98265326f, 0.97746199f, 0.97160077f,\n0.96507365f, 0.95788515f, 0.95004016f, 0.94154406f, 0.93240267f,\n0.92262226f, 0.91220951f, 0.90117162f, 0.88951606f, 0.87725091f,\n0.86438453f, 0.85092574f, 0.83688372f, 0.82226819f, 0.80708915f,\n0.79135692f, 0.77508235f, 0.75827658f, 0.74095112f, 0.72311783f,\n0.70478898f, 0.68597710f, 0.66669506f, 0.64695615f, 0.62677377f,\n0.60616189f, 0.58513457f, 0.56370622f, 0.54189157f, 0.51970547f,\n0.49716324f, 0.47428027f, 0.45107225f, 0.42755505f, 0.40374488f,\n0.37965798f, 0.35531086f, 0.33072025f, 0.30590299f, 0.28087607f,\n0.25565663f, 0.23026201f, 0.20470956f, 0.17901683f, 0.15320139f,\n0.12728097f, 0.10127331f, 0.075196236f, 0.049067631f, 0.022905400f,\n-0.0032725304f, -0.029448219f, -0.055603724f, -0.081721120f, -0.10778251f,\n-0.13377003f, -0.15966587f, -0.18545228f, -0.21111161f, -0.23662624f,\n-0.26197869f, -0.28715160f, -0.31212771f, -0.33688989f, -0.36142120f,\n-0.38570482f, -0.40972409f, -0.43346253f, -0.45690393f, -0.48003218f,\n-0.50283146f, -0.52528608f, -0.54738069f, -0.56910020f, -0.59042966f,\n-0.61135447f, -0.63186026f, -0.65193301f, -0.67155898f, -0.69072473f,\n-0.70941705f, -0.72762316f, -0.74533063f, -0.76252723f, -0.77920127f,\n-0.79534131f, -0.81093621f, -0.82597536f, -0.84044844f, -0.85434550f,\n-0.86765707f, -0.88037395f, -0.89248747f, -0.90398932f, -0.91487163f,\n-0.92512697f, -0.93474823f, -0.94372886f, -0.95206273f, -0.95974404f,\n-0.96676767f, -0.97312868f, -0.97882277f, -0.98384601f, -0.98819500f,\n-0.99186671f, -0.99485862f, -0.99716878f, -0.99879545f, -0.99973762f,\n};\n#endif\n\nstatic const CELTMode mode48000_960_120 = {\n48000,  /* Fs */\n120,    /* overlap */\n21,     /* nbEBands */\n21,     /* effEBands */\n{0.85000610f, 0.0000000f, 1.0000000f, 1.0000000f, },    /* preemph */\neband5ms,       /* eBands */\n3,      /* maxLM */\n8,      /* nbShortMdcts */\n120,    /* shortMdctSize */\n11,     /* nbAllocVectors */\nband_allocation,        /* allocVectors */\nlogN400,        /* logN */\nwindow120,      /* window */\n{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960},    /* mdct */\n{392, cache_index50, cache_bits50, cache_caps50},       /* cache */\n};\n\n/* List of all the available modes */\n#define TOTAL_MODES 1\nstatic const CELTMode * const static_mode_list[TOTAL_MODES] = {\n&mode48000_960_120,\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/static_modes_float_arm_ne10.h",
    "content": "/* The contents of this file was automatically generated by\n * dump_mode_arm_ne10.c with arguments: 48000 960\n * It contains static definitions for some pre-defined modes. */\n#include <NE10_init.h>\n\n#ifndef NE10_FFT_PARAMS48000_960\n#define NE10_FFT_PARAMS48000_960\nstatic const ne10_int32_t ne10_factors_480[64] = {\n4, 40, 4, 30, 2, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, };\nstatic const ne10_int32_t ne10_factors_240[64] = {\n3, 20, 4, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, };\nstatic const ne10_int32_t ne10_factors_120[64] = {\n3, 10, 2, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, };\nstatic const ne10_int32_t ne10_factors_60[64] = {\n2, 5, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, };\nstatic const ne10_fft_cpx_float32_t ne10_twiddles_480[480] = {\n{1.0000000f,0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f},\n{1.0000000f,-0.0000000f}, {0.91354543f,-0.40673664f}, {0.66913056f,-0.74314487f},\n{1.0000000f,-0.0000000f}, {0.66913056f,-0.74314487f}, {-0.10452851f,-0.99452192f},\n{1.0000000f,-0.0000000f}, {0.30901697f,-0.95105654f}, {-0.80901700f,-0.58778518f},\n{1.0000000f,-0.0000000f}, {-0.10452851f,-0.99452192f}, {-0.97814757f,0.20791179f},\n{1.0000000f,-0.0000000f}, {0.97814763f,-0.20791170f}, {0.91354543f,-0.40673664f},\n{0.80901700f,-0.58778524f}, {0.66913056f,-0.74314487f}, {0.49999997f,-0.86602545f},\n{0.30901697f,-0.95105654f}, {0.10452842f,-0.99452192f}, {-0.10452851f,-0.99452192f},\n{-0.30901703f,-0.95105648f}, {-0.50000006f,-0.86602533f}, {-0.66913068f,-0.74314475f},\n{-0.80901700f,-0.58778518f}, {-0.91354549f,-0.40673658f}, {-0.97814763f,-0.20791161f},\n{1.0000000f,-0.0000000f}, {0.99862951f,-0.052335959f}, {0.99452192f,-0.10452846f},\n{0.98768836f,-0.15643448f}, {0.97814763f,-0.20791170f}, {0.96592581f,-0.25881904f},\n{0.95105648f,-0.30901700f}, {0.93358040f,-0.35836795f}, {0.91354543f,-0.40673664f},\n{0.89100653f,-0.45399052f}, {0.86602545f,-0.50000000f}, {0.83867055f,-0.54463905f},\n{0.80901700f,-0.58778524f}, {0.77714598f,-0.62932038f}, {0.74314475f,-0.66913062f},\n{0.70710677f,-0.70710683f}, {0.66913056f,-0.74314487f}, {0.62932038f,-0.77714598f},\n{0.58778524f,-0.80901700f}, {0.54463899f,-0.83867055f}, {0.49999997f,-0.86602545f},\n{0.45399052f,-0.89100653f}, {0.40673661f,-0.91354549f}, {0.35836786f,-0.93358046f},\n{0.30901697f,-0.95105654f}, {0.25881907f,-0.96592581f}, {0.20791166f,-0.97814763f},\n{0.15643437f,-0.98768836f}, {0.10452842f,-0.99452192f}, {0.052335974f,-0.99862951f},\n{1.0000000f,-0.0000000f}, {0.99452192f,-0.10452846f}, {0.97814763f,-0.20791170f},\n{0.95105648f,-0.30901700f}, {0.91354543f,-0.40673664f}, {0.86602545f,-0.50000000f},\n{0.80901700f,-0.58778524f}, {0.74314475f,-0.66913062f}, {0.66913056f,-0.74314487f},\n{0.58778524f,-0.80901700f}, {0.49999997f,-0.86602545f}, {0.40673661f,-0.91354549f},\n{0.30901697f,-0.95105654f}, {0.20791166f,-0.97814763f}, {0.10452842f,-0.99452192f},\n{-4.3711388e-08f,-1.0000000f}, {-0.10452851f,-0.99452192f}, {-0.20791174f,-0.97814757f},\n{-0.30901703f,-0.95105648f}, {-0.40673670f,-0.91354543f}, {-0.50000006f,-0.86602533f},\n{-0.58778518f,-0.80901700f}, {-0.66913068f,-0.74314475f}, {-0.74314493f,-0.66913044f},\n{-0.80901700f,-0.58778518f}, {-0.86602539f,-0.50000006f}, {-0.91354549f,-0.40673658f},\n{-0.95105654f,-0.30901679f}, {-0.97814763f,-0.20791161f}, {-0.99452192f,-0.10452849f},\n{1.0000000f,-0.0000000f}, {0.98768836f,-0.15643448f}, {0.95105648f,-0.30901700f},\n{0.89100653f,-0.45399052f}, {0.80901700f,-0.58778524f}, {0.70710677f,-0.70710683f},\n{0.58778524f,-0.80901700f}, {0.45399052f,-0.89100653f}, {0.30901697f,-0.95105654f},\n{0.15643437f,-0.98768836f}, {-4.3711388e-08f,-1.0000000f}, {-0.15643445f,-0.98768836f},\n{-0.30901703f,-0.95105648f}, {-0.45399061f,-0.89100647f}, {-0.58778518f,-0.80901700f},\n{-0.70710677f,-0.70710677f}, {-0.80901700f,-0.58778518f}, {-0.89100659f,-0.45399037f},\n{-0.95105654f,-0.30901679f}, {-0.98768836f,-0.15643445f}, {-1.0000000f,8.7422777e-08f},\n{-0.98768830f,0.15643461f}, {-0.95105654f,0.30901697f}, {-0.89100653f,0.45399055f},\n{-0.80901694f,0.58778536f}, {-0.70710665f,0.70710689f}, {-0.58778507f,0.80901712f},\n{-0.45399022f,0.89100665f}, {-0.30901709f,0.95105648f}, {-0.15643452f,0.98768830f},\n{1.0000000f,-0.0000000f}, {0.99991435f,-0.013089596f}, {0.99965733f,-0.026176950f},\n{0.99922901f,-0.039259817f}, {0.99862951f,-0.052335959f}, {0.99785894f,-0.065403134f},\n{0.99691731f,-0.078459099f}, {0.99580491f,-0.091501623f}, {0.99452192f,-0.10452846f},\n{0.99306846f,-0.11753740f}, {0.99144489f,-0.13052620f}, {0.98965138f,-0.14349262f},\n{0.98768836f,-0.15643448f}, {0.98555607f,-0.16934951f}, {0.98325491f,-0.18223552f},\n{0.98078525f,-0.19509032f}, {0.97814763f,-0.20791170f}, {0.97534233f,-0.22069745f},\n{0.97236991f,-0.23344538f}, {0.96923089f,-0.24615330f}, {0.96592581f,-0.25881904f},\n{0.96245521f,-0.27144045f}, {0.95881975f,-0.28401536f}, {0.95501995f,-0.29654160f},\n{0.95105648f,-0.30901700f}, {0.94693011f,-0.32143945f}, {0.94264150f,-0.33380687f},\n{0.93819129f,-0.34611708f}, {0.93358040f,-0.35836795f}, {0.92880952f,-0.37055743f},\n{0.92387956f,-0.38268346f}, {0.91879117f,-0.39474389f}, {0.91354543f,-0.40673664f},\n{0.90814316f,-0.41865975f}, {0.90258527f,-0.43051112f}, {0.89687270f,-0.44228873f},\n{0.89100653f,-0.45399052f}, {0.88498765f,-0.46561453f}, {0.87881708f,-0.47715878f},\n{0.87249601f,-0.48862126f}, {0.86602545f,-0.50000000f}, {0.85940641f,-0.51129311f},\n{0.85264015f,-0.52249855f}, {0.84572786f,-0.53361452f}, {0.83867055f,-0.54463905f},\n{0.83146960f,-0.55557024f}, {0.82412618f,-0.56640625f}, {0.81664151f,-0.57714522f},\n{0.80901700f,-0.58778524f}, {0.80125380f,-0.59832460f}, {0.79335332f,-0.60876143f},\n{0.78531694f,-0.61909395f}, {0.77714598f,-0.62932038f}, {0.76884180f,-0.63943899f},\n{0.76040596f,-0.64944810f}, {0.75183982f,-0.65934587f}, {0.74314475f,-0.66913062f},\n{0.73432249f,-0.67880076f}, {0.72537434f,-0.68835455f}, {0.71630192f,-0.69779050f},\n{0.70710677f,-0.70710683f}, {0.69779044f,-0.71630198f}, {0.68835455f,-0.72537440f},\n{0.67880070f,-0.73432255f}, {0.66913056f,-0.74314487f}, {0.65934581f,-0.75183982f},\n{0.64944804f,-0.76040596f}, {0.63943899f,-0.76884186f}, {0.62932038f,-0.77714598f},\n{0.61909395f,-0.78531694f}, {0.60876137f,-0.79335338f}, {0.59832460f,-0.80125386f},\n{0.58778524f,-0.80901700f}, {0.57714516f,-0.81664151f}, {0.56640625f,-0.82412618f},\n{0.55557019f,-0.83146960f}, {0.54463899f,-0.83867055f}, {0.53361452f,-0.84572786f},\n{0.52249849f,-0.85264015f}, {0.51129311f,-0.85940641f}, {0.49999997f,-0.86602545f},\n{0.48862118f,-0.87249601f}, {0.47715876f,-0.87881708f}, {0.46561447f,-0.88498765f},\n{0.45399052f,-0.89100653f}, {0.44228867f,-0.89687276f}, {0.43051103f,-0.90258533f},\n{0.41865975f,-0.90814316f}, {0.40673661f,-0.91354549f}, {0.39474380f,-0.91879129f},\n{0.38268343f,-0.92387956f}, {0.37055740f,-0.92880958f}, {0.35836786f,-0.93358046f},\n{0.34611705f,-0.93819135f}, {0.33380681f,-0.94264150f}, {0.32143947f,-0.94693011f},\n{0.30901697f,-0.95105654f}, {0.29654151f,-0.95501995f}, {0.28401533f,-0.95881975f},\n{0.27144039f,-0.96245527f}, {0.25881907f,-0.96592581f}, {0.24615327f,-0.96923089f},\n{0.23344530f,-0.97236991f}, {0.22069745f,-0.97534233f}, {0.20791166f,-0.97814763f},\n{0.19509023f,-0.98078531f}, {0.18223552f,-0.98325491f}, {0.16934945f,-0.98555607f},\n{0.15643437f,-0.98768836f}, {0.14349259f,-0.98965138f}, {0.13052613f,-0.99144489f},\n{0.11753740f,-0.99306846f}, {0.10452842f,-0.99452192f}, {0.091501534f,-0.99580491f},\n{0.078459084f,-0.99691731f}, {0.065403074f,-0.99785894f}, {0.052335974f,-0.99862951f},\n{0.039259788f,-0.99922901f}, {0.026176875f,-0.99965733f}, {0.013089597f,-0.99991435f},\n{1.0000000f,-0.0000000f}, {0.99965733f,-0.026176950f}, {0.99862951f,-0.052335959f},\n{0.99691731f,-0.078459099f}, {0.99452192f,-0.10452846f}, {0.99144489f,-0.13052620f},\n{0.98768836f,-0.15643448f}, {0.98325491f,-0.18223552f}, {0.97814763f,-0.20791170f},\n{0.97236991f,-0.23344538f}, {0.96592581f,-0.25881904f}, {0.95881975f,-0.28401536f},\n{0.95105648f,-0.30901700f}, {0.94264150f,-0.33380687f}, {0.93358040f,-0.35836795f},\n{0.92387956f,-0.38268346f}, {0.91354543f,-0.40673664f}, {0.90258527f,-0.43051112f},\n{0.89100653f,-0.45399052f}, {0.87881708f,-0.47715878f}, {0.86602545f,-0.50000000f},\n{0.85264015f,-0.52249855f}, {0.83867055f,-0.54463905f}, {0.82412618f,-0.56640625f},\n{0.80901700f,-0.58778524f}, {0.79335332f,-0.60876143f}, {0.77714598f,-0.62932038f},\n{0.76040596f,-0.64944810f}, {0.74314475f,-0.66913062f}, {0.72537434f,-0.68835455f},\n{0.70710677f,-0.70710683f}, {0.68835455f,-0.72537440f}, {0.66913056f,-0.74314487f},\n{0.64944804f,-0.76040596f}, {0.62932038f,-0.77714598f}, {0.60876137f,-0.79335338f},\n{0.58778524f,-0.80901700f}, {0.56640625f,-0.82412618f}, {0.54463899f,-0.83867055f},\n{0.52249849f,-0.85264015f}, {0.49999997f,-0.86602545f}, {0.47715876f,-0.87881708f},\n{0.45399052f,-0.89100653f}, {0.43051103f,-0.90258533f}, {0.40673661f,-0.91354549f},\n{0.38268343f,-0.92387956f}, {0.35836786f,-0.93358046f}, {0.33380681f,-0.94264150f},\n{0.30901697f,-0.95105654f}, {0.28401533f,-0.95881975f}, {0.25881907f,-0.96592581f},\n{0.23344530f,-0.97236991f}, {0.20791166f,-0.97814763f}, {0.18223552f,-0.98325491f},\n{0.15643437f,-0.98768836f}, {0.13052613f,-0.99144489f}, {0.10452842f,-0.99452192f},\n{0.078459084f,-0.99691731f}, {0.052335974f,-0.99862951f}, {0.026176875f,-0.99965733f},\n{-4.3711388e-08f,-1.0000000f}, {-0.026176963f,-0.99965733f}, {-0.052336060f,-0.99862951f},\n{-0.078459173f,-0.99691731f}, {-0.10452851f,-0.99452192f}, {-0.13052621f,-0.99144489f},\n{-0.15643445f,-0.98768836f}, {-0.18223560f,-0.98325491f}, {-0.20791174f,-0.97814757f},\n{-0.23344538f,-0.97236991f}, {-0.25881916f,-0.96592581f}, {-0.28401542f,-0.95881969f},\n{-0.30901703f,-0.95105648f}, {-0.33380687f,-0.94264150f}, {-0.35836795f,-0.93358040f},\n{-0.38268352f,-0.92387950f}, {-0.40673670f,-0.91354543f}, {-0.43051112f,-0.90258527f},\n{-0.45399061f,-0.89100647f}, {-0.47715873f,-0.87881708f}, {-0.50000006f,-0.86602533f},\n{-0.52249867f,-0.85264009f}, {-0.54463905f,-0.83867055f}, {-0.56640631f,-0.82412612f},\n{-0.58778518f,-0.80901700f}, {-0.60876143f,-0.79335332f}, {-0.62932050f,-0.77714586f},\n{-0.64944804f,-0.76040596f}, {-0.66913068f,-0.74314475f}, {-0.68835467f,-0.72537428f},\n{-0.70710677f,-0.70710677f}, {-0.72537446f,-0.68835449f}, {-0.74314493f,-0.66913044f},\n{-0.76040596f,-0.64944804f}, {-0.77714604f,-0.62932026f}, {-0.79335332f,-0.60876143f},\n{-0.80901700f,-0.58778518f}, {-0.82412624f,-0.56640613f}, {-0.83867055f,-0.54463899f},\n{-0.85264021f,-0.52249849f}, {-0.86602539f,-0.50000006f}, {-0.87881714f,-0.47715873f},\n{-0.89100659f,-0.45399037f}, {-0.90258527f,-0.43051112f}, {-0.91354549f,-0.40673658f},\n{-0.92387956f,-0.38268328f}, {-0.93358040f,-0.35836792f}, {-0.94264150f,-0.33380675f},\n{-0.95105654f,-0.30901679f}, {-0.95881975f,-0.28401530f}, {-0.96592587f,-0.25881892f},\n{-0.97236991f,-0.23344538f}, {-0.97814763f,-0.20791161f}, {-0.98325491f,-0.18223536f},\n{-0.98768836f,-0.15643445f}, {-0.99144489f,-0.13052608f}, {-0.99452192f,-0.10452849f},\n{-0.99691737f,-0.078459039f}, {-0.99862957f,-0.052335810f}, {-0.99965733f,-0.026176952f},\n{1.0000000f,-0.0000000f}, {0.99922901f,-0.039259817f}, {0.99691731f,-0.078459099f},\n{0.99306846f,-0.11753740f}, {0.98768836f,-0.15643448f}, {0.98078525f,-0.19509032f},\n{0.97236991f,-0.23344538f}, {0.96245521f,-0.27144045f}, {0.95105648f,-0.30901700f},\n{0.93819129f,-0.34611708f}, {0.92387956f,-0.38268346f}, {0.90814316f,-0.41865975f},\n{0.89100653f,-0.45399052f}, {0.87249601f,-0.48862126f}, {0.85264015f,-0.52249855f},\n{0.83146960f,-0.55557024f}, {0.80901700f,-0.58778524f}, {0.78531694f,-0.61909395f},\n{0.76040596f,-0.64944810f}, {0.73432249f,-0.67880076f}, {0.70710677f,-0.70710683f},\n{0.67880070f,-0.73432255f}, {0.64944804f,-0.76040596f}, {0.61909395f,-0.78531694f},\n{0.58778524f,-0.80901700f}, {0.55557019f,-0.83146960f}, {0.52249849f,-0.85264015f},\n{0.48862118f,-0.87249601f}, {0.45399052f,-0.89100653f}, {0.41865975f,-0.90814316f},\n{0.38268343f,-0.92387956f}, {0.34611705f,-0.93819135f}, {0.30901697f,-0.95105654f},\n{0.27144039f,-0.96245527f}, {0.23344530f,-0.97236991f}, {0.19509023f,-0.98078531f},\n{0.15643437f,-0.98768836f}, {0.11753740f,-0.99306846f}, {0.078459084f,-0.99691731f},\n{0.039259788f,-0.99922901f}, {-4.3711388e-08f,-1.0000000f}, {-0.039259877f,-0.99922901f},\n{-0.078459173f,-0.99691731f}, {-0.11753749f,-0.99306846f}, {-0.15643445f,-0.98768836f},\n{-0.19509032f,-0.98078525f}, {-0.23344538f,-0.97236991f}, {-0.27144048f,-0.96245521f},\n{-0.30901703f,-0.95105648f}, {-0.34611711f,-0.93819129f}, {-0.38268352f,-0.92387950f},\n{-0.41865984f,-0.90814310f}, {-0.45399061f,-0.89100647f}, {-0.48862135f,-0.87249595f},\n{-0.52249867f,-0.85264009f}, {-0.55557036f,-0.83146954f}, {-0.58778518f,-0.80901700f},\n{-0.61909389f,-0.78531694f}, {-0.64944804f,-0.76040596f}, {-0.67880076f,-0.73432249f},\n{-0.70710677f,-0.70710677f}, {-0.73432249f,-0.67880070f}, {-0.76040596f,-0.64944804f},\n{-0.78531694f,-0.61909389f}, {-0.80901700f,-0.58778518f}, {-0.83146966f,-0.55557019f},\n{-0.85264021f,-0.52249849f}, {-0.87249607f,-0.48862115f}, {-0.89100659f,-0.45399037f},\n{-0.90814322f,-0.41865960f}, {-0.92387956f,-0.38268328f}, {-0.93819135f,-0.34611690f},\n{-0.95105654f,-0.30901679f}, {-0.96245521f,-0.27144048f}, {-0.97236991f,-0.23344538f},\n{-0.98078531f,-0.19509031f}, {-0.98768836f,-0.15643445f}, {-0.99306846f,-0.11753736f},\n{-0.99691737f,-0.078459039f}, {-0.99922901f,-0.039259743f}, {-1.0000000f,8.7422777e-08f},\n{-0.99922901f,0.039259918f}, {-0.99691731f,0.078459218f}, {-0.99306846f,0.11753753f},\n{-0.98768830f,0.15643461f}, {-0.98078525f,0.19509049f}, {-0.97236985f,0.23344554f},\n{-0.96245515f,0.27144065f}, {-0.95105654f,0.30901697f}, {-0.93819135f,0.34611705f},\n{-0.92387956f,0.38268346f}, {-0.90814316f,0.41865975f}, {-0.89100653f,0.45399055f},\n{-0.87249601f,0.48862129f}, {-0.85264015f,0.52249861f}, {-0.83146960f,0.55557030f},\n{-0.80901694f,0.58778536f}, {-0.78531688f,0.61909401f}, {-0.76040590f,0.64944816f},\n{-0.73432243f,0.67880082f}, {-0.70710665f,0.70710689f}, {-0.67880058f,0.73432261f},\n{-0.64944792f,0.76040608f}, {-0.61909378f,0.78531706f}, {-0.58778507f,0.80901712f},\n{-0.55557001f,0.83146977f}, {-0.52249837f,0.85264033f}, {-0.48862100f,0.87249613f},\n{-0.45399022f,0.89100665f}, {-0.41865945f,0.90814328f}, {-0.38268313f,0.92387968f},\n{-0.34611672f,0.93819147f}, {-0.30901709f,0.95105648f}, {-0.27144054f,0.96245521f},\n{-0.23344545f,0.97236991f}, {-0.19509038f,0.98078525f}, {-0.15643452f,0.98768830f},\n{-0.11753743f,0.99306846f}, {-0.078459114f,0.99691731f}, {-0.039259821f,0.99922901f},\n};\nstatic const ne10_fft_cpx_float32_t ne10_twiddles_240[240] = {\n{1.0000000f,0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f},\n{1.0000000f,-0.0000000f}, {0.91354543f,-0.40673664f}, {0.66913056f,-0.74314487f},\n{1.0000000f,-0.0000000f}, {0.66913056f,-0.74314487f}, {-0.10452851f,-0.99452192f},\n{1.0000000f,-0.0000000f}, {0.30901697f,-0.95105654f}, {-0.80901700f,-0.58778518f},\n{1.0000000f,-0.0000000f}, {-0.10452851f,-0.99452192f}, {-0.97814757f,0.20791179f},\n{1.0000000f,-0.0000000f}, {0.99452192f,-0.10452846f}, {0.97814763f,-0.20791170f},\n{0.95105648f,-0.30901700f}, {0.91354543f,-0.40673664f}, {0.86602545f,-0.50000000f},\n{0.80901700f,-0.58778524f}, {0.74314475f,-0.66913062f}, {0.66913056f,-0.74314487f},\n{0.58778524f,-0.80901700f}, {0.49999997f,-0.86602545f}, {0.40673661f,-0.91354549f},\n{0.30901697f,-0.95105654f}, {0.20791166f,-0.97814763f}, {0.10452842f,-0.99452192f},\n{1.0000000f,-0.0000000f}, {0.97814763f,-0.20791170f}, {0.91354543f,-0.40673664f},\n{0.80901700f,-0.58778524f}, {0.66913056f,-0.74314487f}, {0.49999997f,-0.86602545f},\n{0.30901697f,-0.95105654f}, {0.10452842f,-0.99452192f}, {-0.10452851f,-0.99452192f},\n{-0.30901703f,-0.95105648f}, {-0.50000006f,-0.86602533f}, {-0.66913068f,-0.74314475f},\n{-0.80901700f,-0.58778518f}, {-0.91354549f,-0.40673658f}, {-0.97814763f,-0.20791161f},\n{1.0000000f,-0.0000000f}, {0.95105648f,-0.30901700f}, {0.80901700f,-0.58778524f},\n{0.58778524f,-0.80901700f}, {0.30901697f,-0.95105654f}, {-4.3711388e-08f,-1.0000000f},\n{-0.30901703f,-0.95105648f}, {-0.58778518f,-0.80901700f}, {-0.80901700f,-0.58778518f},\n{-0.95105654f,-0.30901679f}, {-1.0000000f,8.7422777e-08f}, {-0.95105654f,0.30901697f},\n{-0.80901694f,0.58778536f}, {-0.58778507f,0.80901712f}, {-0.30901709f,0.95105648f},\n{1.0000000f,-0.0000000f}, {0.99965733f,-0.026176950f}, {0.99862951f,-0.052335959f},\n{0.99691731f,-0.078459099f}, {0.99452192f,-0.10452846f}, {0.99144489f,-0.13052620f},\n{0.98768836f,-0.15643448f}, {0.98325491f,-0.18223552f}, {0.97814763f,-0.20791170f},\n{0.97236991f,-0.23344538f}, {0.96592581f,-0.25881904f}, {0.95881975f,-0.28401536f},\n{0.95105648f,-0.30901700f}, {0.94264150f,-0.33380687f}, {0.93358040f,-0.35836795f},\n{0.92387956f,-0.38268346f}, {0.91354543f,-0.40673664f}, {0.90258527f,-0.43051112f},\n{0.89100653f,-0.45399052f}, {0.87881708f,-0.47715878f}, {0.86602545f,-0.50000000f},\n{0.85264015f,-0.52249855f}, {0.83867055f,-0.54463905f}, {0.82412618f,-0.56640625f},\n{0.80901700f,-0.58778524f}, {0.79335332f,-0.60876143f}, {0.77714598f,-0.62932038f},\n{0.76040596f,-0.64944810f}, {0.74314475f,-0.66913062f}, {0.72537434f,-0.68835455f},\n{0.70710677f,-0.70710683f}, {0.68835455f,-0.72537440f}, {0.66913056f,-0.74314487f},\n{0.64944804f,-0.76040596f}, {0.62932038f,-0.77714598f}, {0.60876137f,-0.79335338f},\n{0.58778524f,-0.80901700f}, {0.56640625f,-0.82412618f}, {0.54463899f,-0.83867055f},\n{0.52249849f,-0.85264015f}, {0.49999997f,-0.86602545f}, {0.47715876f,-0.87881708f},\n{0.45399052f,-0.89100653f}, {0.43051103f,-0.90258533f}, {0.40673661f,-0.91354549f},\n{0.38268343f,-0.92387956f}, {0.35836786f,-0.93358046f}, {0.33380681f,-0.94264150f},\n{0.30901697f,-0.95105654f}, {0.28401533f,-0.95881975f}, {0.25881907f,-0.96592581f},\n{0.23344530f,-0.97236991f}, {0.20791166f,-0.97814763f}, {0.18223552f,-0.98325491f},\n{0.15643437f,-0.98768836f}, {0.13052613f,-0.99144489f}, {0.10452842f,-0.99452192f},\n{0.078459084f,-0.99691731f}, {0.052335974f,-0.99862951f}, {0.026176875f,-0.99965733f},\n{1.0000000f,-0.0000000f}, {0.99862951f,-0.052335959f}, {0.99452192f,-0.10452846f},\n{0.98768836f,-0.15643448f}, {0.97814763f,-0.20791170f}, {0.96592581f,-0.25881904f},\n{0.95105648f,-0.30901700f}, {0.93358040f,-0.35836795f}, {0.91354543f,-0.40673664f},\n{0.89100653f,-0.45399052f}, {0.86602545f,-0.50000000f}, {0.83867055f,-0.54463905f},\n{0.80901700f,-0.58778524f}, {0.77714598f,-0.62932038f}, {0.74314475f,-0.66913062f},\n{0.70710677f,-0.70710683f}, {0.66913056f,-0.74314487f}, {0.62932038f,-0.77714598f},\n{0.58778524f,-0.80901700f}, {0.54463899f,-0.83867055f}, {0.49999997f,-0.86602545f},\n{0.45399052f,-0.89100653f}, {0.40673661f,-0.91354549f}, {0.35836786f,-0.93358046f},\n{0.30901697f,-0.95105654f}, {0.25881907f,-0.96592581f}, {0.20791166f,-0.97814763f},\n{0.15643437f,-0.98768836f}, {0.10452842f,-0.99452192f}, {0.052335974f,-0.99862951f},\n{-4.3711388e-08f,-1.0000000f}, {-0.052336060f,-0.99862951f}, {-0.10452851f,-0.99452192f},\n{-0.15643445f,-0.98768836f}, {-0.20791174f,-0.97814757f}, {-0.25881916f,-0.96592581f},\n{-0.30901703f,-0.95105648f}, {-0.35836795f,-0.93358040f}, {-0.40673670f,-0.91354543f},\n{-0.45399061f,-0.89100647f}, {-0.50000006f,-0.86602533f}, {-0.54463905f,-0.83867055f},\n{-0.58778518f,-0.80901700f}, {-0.62932050f,-0.77714586f}, {-0.66913068f,-0.74314475f},\n{-0.70710677f,-0.70710677f}, {-0.74314493f,-0.66913044f}, {-0.77714604f,-0.62932026f},\n{-0.80901700f,-0.58778518f}, {-0.83867055f,-0.54463899f}, {-0.86602539f,-0.50000006f},\n{-0.89100659f,-0.45399037f}, {-0.91354549f,-0.40673658f}, {-0.93358040f,-0.35836792f},\n{-0.95105654f,-0.30901679f}, {-0.96592587f,-0.25881892f}, {-0.97814763f,-0.20791161f},\n{-0.98768836f,-0.15643445f}, {-0.99452192f,-0.10452849f}, {-0.99862957f,-0.052335810f},\n{1.0000000f,-0.0000000f}, {0.99691731f,-0.078459099f}, {0.98768836f,-0.15643448f},\n{0.97236991f,-0.23344538f}, {0.95105648f,-0.30901700f}, {0.92387956f,-0.38268346f},\n{0.89100653f,-0.45399052f}, {0.85264015f,-0.52249855f}, {0.80901700f,-0.58778524f},\n{0.76040596f,-0.64944810f}, {0.70710677f,-0.70710683f}, {0.64944804f,-0.76040596f},\n{0.58778524f,-0.80901700f}, {0.52249849f,-0.85264015f}, {0.45399052f,-0.89100653f},\n{0.38268343f,-0.92387956f}, {0.30901697f,-0.95105654f}, {0.23344530f,-0.97236991f},\n{0.15643437f,-0.98768836f}, {0.078459084f,-0.99691731f}, {-4.3711388e-08f,-1.0000000f},\n{-0.078459173f,-0.99691731f}, {-0.15643445f,-0.98768836f}, {-0.23344538f,-0.97236991f},\n{-0.30901703f,-0.95105648f}, {-0.38268352f,-0.92387950f}, {-0.45399061f,-0.89100647f},\n{-0.52249867f,-0.85264009f}, {-0.58778518f,-0.80901700f}, {-0.64944804f,-0.76040596f},\n{-0.70710677f,-0.70710677f}, {-0.76040596f,-0.64944804f}, {-0.80901700f,-0.58778518f},\n{-0.85264021f,-0.52249849f}, {-0.89100659f,-0.45399037f}, {-0.92387956f,-0.38268328f},\n{-0.95105654f,-0.30901679f}, {-0.97236991f,-0.23344538f}, {-0.98768836f,-0.15643445f},\n{-0.99691737f,-0.078459039f}, {-1.0000000f,8.7422777e-08f}, {-0.99691731f,0.078459218f},\n{-0.98768830f,0.15643461f}, {-0.97236985f,0.23344554f}, {-0.95105654f,0.30901697f},\n{-0.92387956f,0.38268346f}, {-0.89100653f,0.45399055f}, {-0.85264015f,0.52249861f},\n{-0.80901694f,0.58778536f}, {-0.76040590f,0.64944816f}, {-0.70710665f,0.70710689f},\n{-0.64944792f,0.76040608f}, {-0.58778507f,0.80901712f}, {-0.52249837f,0.85264033f},\n{-0.45399022f,0.89100665f}, {-0.38268313f,0.92387968f}, {-0.30901709f,0.95105648f},\n{-0.23344545f,0.97236991f}, {-0.15643452f,0.98768830f}, {-0.078459114f,0.99691731f},\n};\nstatic const ne10_fft_cpx_float32_t ne10_twiddles_120[120] = {\n{1.0000000f,0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f},\n{1.0000000f,-0.0000000f}, {0.91354543f,-0.40673664f}, {0.66913056f,-0.74314487f},\n{1.0000000f,-0.0000000f}, {0.66913056f,-0.74314487f}, {-0.10452851f,-0.99452192f},\n{1.0000000f,-0.0000000f}, {0.30901697f,-0.95105654f}, {-0.80901700f,-0.58778518f},\n{1.0000000f,-0.0000000f}, {-0.10452851f,-0.99452192f}, {-0.97814757f,0.20791179f},\n{1.0000000f,-0.0000000f}, {0.97814763f,-0.20791170f}, {0.91354543f,-0.40673664f},\n{0.80901700f,-0.58778524f}, {0.66913056f,-0.74314487f}, {0.49999997f,-0.86602545f},\n{0.30901697f,-0.95105654f}, {0.10452842f,-0.99452192f}, {-0.10452851f,-0.99452192f},\n{-0.30901703f,-0.95105648f}, {-0.50000006f,-0.86602533f}, {-0.66913068f,-0.74314475f},\n{-0.80901700f,-0.58778518f}, {-0.91354549f,-0.40673658f}, {-0.97814763f,-0.20791161f},\n{1.0000000f,-0.0000000f}, {0.99862951f,-0.052335959f}, {0.99452192f,-0.10452846f},\n{0.98768836f,-0.15643448f}, {0.97814763f,-0.20791170f}, {0.96592581f,-0.25881904f},\n{0.95105648f,-0.30901700f}, {0.93358040f,-0.35836795f}, {0.91354543f,-0.40673664f},\n{0.89100653f,-0.45399052f}, {0.86602545f,-0.50000000f}, {0.83867055f,-0.54463905f},\n{0.80901700f,-0.58778524f}, {0.77714598f,-0.62932038f}, {0.74314475f,-0.66913062f},\n{0.70710677f,-0.70710683f}, {0.66913056f,-0.74314487f}, {0.62932038f,-0.77714598f},\n{0.58778524f,-0.80901700f}, {0.54463899f,-0.83867055f}, {0.49999997f,-0.86602545f},\n{0.45399052f,-0.89100653f}, {0.40673661f,-0.91354549f}, {0.35836786f,-0.93358046f},\n{0.30901697f,-0.95105654f}, {0.25881907f,-0.96592581f}, {0.20791166f,-0.97814763f},\n{0.15643437f,-0.98768836f}, {0.10452842f,-0.99452192f}, {0.052335974f,-0.99862951f},\n{1.0000000f,-0.0000000f}, {0.99452192f,-0.10452846f}, {0.97814763f,-0.20791170f},\n{0.95105648f,-0.30901700f}, {0.91354543f,-0.40673664f}, {0.86602545f,-0.50000000f},\n{0.80901700f,-0.58778524f}, {0.74314475f,-0.66913062f}, {0.66913056f,-0.74314487f},\n{0.58778524f,-0.80901700f}, {0.49999997f,-0.86602545f}, {0.40673661f,-0.91354549f},\n{0.30901697f,-0.95105654f}, {0.20791166f,-0.97814763f}, {0.10452842f,-0.99452192f},\n{-4.3711388e-08f,-1.0000000f}, {-0.10452851f,-0.99452192f}, {-0.20791174f,-0.97814757f},\n{-0.30901703f,-0.95105648f}, {-0.40673670f,-0.91354543f}, {-0.50000006f,-0.86602533f},\n{-0.58778518f,-0.80901700f}, {-0.66913068f,-0.74314475f}, {-0.74314493f,-0.66913044f},\n{-0.80901700f,-0.58778518f}, {-0.86602539f,-0.50000006f}, {-0.91354549f,-0.40673658f},\n{-0.95105654f,-0.30901679f}, {-0.97814763f,-0.20791161f}, {-0.99452192f,-0.10452849f},\n{1.0000000f,-0.0000000f}, {0.98768836f,-0.15643448f}, {0.95105648f,-0.30901700f},\n{0.89100653f,-0.45399052f}, {0.80901700f,-0.58778524f}, {0.70710677f,-0.70710683f},\n{0.58778524f,-0.80901700f}, {0.45399052f,-0.89100653f}, {0.30901697f,-0.95105654f},\n{0.15643437f,-0.98768836f}, {-4.3711388e-08f,-1.0000000f}, {-0.15643445f,-0.98768836f},\n{-0.30901703f,-0.95105648f}, {-0.45399061f,-0.89100647f}, {-0.58778518f,-0.80901700f},\n{-0.70710677f,-0.70710677f}, {-0.80901700f,-0.58778518f}, {-0.89100659f,-0.45399037f},\n{-0.95105654f,-0.30901679f}, {-0.98768836f,-0.15643445f}, {-1.0000000f,8.7422777e-08f},\n{-0.98768830f,0.15643461f}, {-0.95105654f,0.30901697f}, {-0.89100653f,0.45399055f},\n{-0.80901694f,0.58778536f}, {-0.70710665f,0.70710689f}, {-0.58778507f,0.80901712f},\n{-0.45399022f,0.89100665f}, {-0.30901709f,0.95105648f}, {-0.15643452f,0.98768830f},\n};\nstatic const ne10_fft_cpx_float32_t ne10_twiddles_60[60] = {\n{1.0000000f,0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f},\n{1.0000000f,-0.0000000f}, {0.91354543f,-0.40673664f}, {0.66913056f,-0.74314487f},\n{1.0000000f,-0.0000000f}, {0.66913056f,-0.74314487f}, {-0.10452851f,-0.99452192f},\n{1.0000000f,-0.0000000f}, {0.30901697f,-0.95105654f}, {-0.80901700f,-0.58778518f},\n{1.0000000f,-0.0000000f}, {-0.10452851f,-0.99452192f}, {-0.97814757f,0.20791179f},\n{1.0000000f,-0.0000000f}, {0.99452192f,-0.10452846f}, {0.97814763f,-0.20791170f},\n{0.95105648f,-0.30901700f}, {0.91354543f,-0.40673664f}, {0.86602545f,-0.50000000f},\n{0.80901700f,-0.58778524f}, {0.74314475f,-0.66913062f}, {0.66913056f,-0.74314487f},\n{0.58778524f,-0.80901700f}, {0.49999997f,-0.86602545f}, {0.40673661f,-0.91354549f},\n{0.30901697f,-0.95105654f}, {0.20791166f,-0.97814763f}, {0.10452842f,-0.99452192f},\n{1.0000000f,-0.0000000f}, {0.97814763f,-0.20791170f}, {0.91354543f,-0.40673664f},\n{0.80901700f,-0.58778524f}, {0.66913056f,-0.74314487f}, {0.49999997f,-0.86602545f},\n{0.30901697f,-0.95105654f}, {0.10452842f,-0.99452192f}, {-0.10452851f,-0.99452192f},\n{-0.30901703f,-0.95105648f}, {-0.50000006f,-0.86602533f}, {-0.66913068f,-0.74314475f},\n{-0.80901700f,-0.58778518f}, {-0.91354549f,-0.40673658f}, {-0.97814763f,-0.20791161f},\n{1.0000000f,-0.0000000f}, {0.95105648f,-0.30901700f}, {0.80901700f,-0.58778524f},\n{0.58778524f,-0.80901700f}, {0.30901697f,-0.95105654f}, {-4.3711388e-08f,-1.0000000f},\n{-0.30901703f,-0.95105648f}, {-0.58778518f,-0.80901700f}, {-0.80901700f,-0.58778518f},\n{-0.95105654f,-0.30901679f}, {-1.0000000f,8.7422777e-08f}, {-0.95105654f,0.30901697f},\n{-0.80901694f,0.58778536f}, {-0.58778507f,0.80901712f}, {-0.30901709f,0.95105648f},\n};\nstatic const ne10_fft_state_float32_t ne10_fft_state_float32_t_480 = {\n120,\n(ne10_int32_t *)ne10_factors_480,\n(ne10_fft_cpx_float32_t *)ne10_twiddles_480,\nNULL,\n(ne10_fft_cpx_float32_t *)&ne10_twiddles_480[120],\n/* is_forward_scaled = true */\n(ne10_int32_t) 1,\n/* is_backward_scaled = false */\n(ne10_int32_t) 0,\n};\nstatic const arch_fft_state cfg_arch_480 = {\n1,\n(void *)&ne10_fft_state_float32_t_480,\n};\n\nstatic const ne10_fft_state_float32_t ne10_fft_state_float32_t_240 = {\n60,\n(ne10_int32_t *)ne10_factors_240,\n(ne10_fft_cpx_float32_t *)ne10_twiddles_240,\nNULL,\n(ne10_fft_cpx_float32_t *)&ne10_twiddles_240[60],\n/* is_forward_scaled = true */\n(ne10_int32_t) 1,\n/* is_backward_scaled = false */\n(ne10_int32_t) 0,\n};\nstatic const arch_fft_state cfg_arch_240 = {\n1,\n(void *)&ne10_fft_state_float32_t_240,\n};\n\nstatic const ne10_fft_state_float32_t ne10_fft_state_float32_t_120 = {\n30,\n(ne10_int32_t *)ne10_factors_120,\n(ne10_fft_cpx_float32_t *)ne10_twiddles_120,\nNULL,\n(ne10_fft_cpx_float32_t *)&ne10_twiddles_120[30],\n/* is_forward_scaled = true */\n(ne10_int32_t) 1,\n/* is_backward_scaled = false */\n(ne10_int32_t) 0,\n};\nstatic const arch_fft_state cfg_arch_120 = {\n1,\n(void *)&ne10_fft_state_float32_t_120,\n};\n\nstatic const ne10_fft_state_float32_t ne10_fft_state_float32_t_60 = {\n15,\n(ne10_int32_t *)ne10_factors_60,\n(ne10_fft_cpx_float32_t *)ne10_twiddles_60,\nNULL,\n(ne10_fft_cpx_float32_t *)&ne10_twiddles_60[15],\n/* is_forward_scaled = true */\n(ne10_int32_t) 1,\n/* is_backward_scaled = false */\n(ne10_int32_t) 0,\n};\nstatic const arch_fft_state cfg_arch_60 = {\n1,\n(void *)&ne10_fft_state_float32_t_60,\n};\n\n#endif  /* end NE10_FFT_PARAMS48000_960 */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/tests/test_unit_cwrs32.c",
    "content": "/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,\n                           Gregory Maxwell\n   Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdio.h>\n#include <string.h>\n\n#ifndef CUSTOM_MODES\n#define CUSTOM_MODES\n#else\n#define TEST_CUSTOM_MODES\n#endif\n\n#define CELT_C\n#include \"stack_alloc.h\"\n#include \"entenc.c\"\n#include \"entdec.c\"\n#include \"entcode.c\"\n#include \"cwrs.c\"\n#include \"mathops.c\"\n#include \"rate.h\"\n\n#define NMAX (240)\n#define KMAX (128)\n\n#ifdef TEST_CUSTOM_MODES\n\n#define NDIMS (44)\nstatic const int pn[NDIMS]={\n   2,   3,   4,   5,   6,   7,   8,   9,  10,\n  11,  12,  13,  14,  15,  16,  18,  20,  22,\n  24,  26,  28,  30,  32,  36,  40,  44,  48,\n  52,  56,  60,  64,  72,  80,  88,  96, 104,\n 112, 120, 128, 144, 160, 176, 192, 208\n};\nstatic const int pkmax[NDIMS]={\n 128, 128, 128, 128,  88,  52,  36,  26,  22,\n  18,  16,  15,  13,  12,  12,  11,  10,   9,\n   9,   8,   8,   7,   7,   7,   7,   6,   6,\n   6,   6,   6,   5,   5,   5,   5,   5,   5,\n   4,   4,   4,   4,   4,   4,   4,   4\n};\n\n#else /* TEST_CUSTOM_MODES */\n\n#define NDIMS (22)\nstatic const int pn[NDIMS]={\n   2,   3,   4,   6,   8,   9,  11,  12,  16,\n  18,  22,  24,  32,  36,  44,  48,  64,  72,\n  88,  96, 144, 176\n};\nstatic const int pkmax[NDIMS]={\n 128, 128, 128,  88,  36,  26,  18,  16,  12,\n  11,   9,   9,   7,   7,   6,   6,   5,   5,\n   5,   5,   4,   4\n};\n\n#endif\n\nint main(void){\n  int t;\n  int n;\n  ALLOC_STACK;\n  for(t=0;t<NDIMS;t++){\n    int pseudo;\n    n=pn[t];\n    for(pseudo=1;pseudo<41;pseudo++)\n    {\n      int k;\n#if defined(SMALL_FOOTPRINT)\n      opus_uint32 uu[KMAX+2U];\n#endif\n      opus_uint32 inc;\n      opus_uint32 nc;\n      opus_uint32 i;\n      k=get_pulses(pseudo);\n      if (k>pkmax[t])break;\n      printf(\"Testing CWRS with N=%i, K=%i...\\n\",n,k);\n#if defined(SMALL_FOOTPRINT)\n      nc=ncwrs_urow(n,k,uu);\n#else\n      nc=CELT_PVQ_V(n,k);\n#endif\n      inc=nc/20000;\n      if(inc<1)inc=1;\n      for(i=0;i<nc;i+=inc){\n#if defined(SMALL_FOOTPRINT)\n        opus_uint32 u[KMAX+2U];\n#endif\n        int         y[NMAX];\n        int         sy;\n        opus_uint32 v;\n        opus_uint32 ii;\n        int         j;\n#if defined(SMALL_FOOTPRINT)\n        memcpy(u,uu,(k+2U)*sizeof(*u));\n        cwrsi(n,k,i,y,u);\n#else\n        cwrsi(n,k,i,y);\n#endif\n        sy=0;\n        for(j=0;j<n;j++)sy+=abs(y[j]);\n        if(sy!=k){\n          fprintf(stderr,\"N=%d Pulse count mismatch in cwrsi (%d!=%d).\\n\",\n           n,sy,k);\n          return 99;\n        }\n        /*printf(\"%6u of %u:\",i,nc);\n        for(j=0;j<n;j++)printf(\" %+3i\",y[j]);\n        printf(\" ->\");*/\n#if defined(SMALL_FOOTPRINT)\n        ii=icwrs(n,k,&v,y,u);\n#else\n        ii=icwrs(n,y);\n        v=CELT_PVQ_V(n,k);\n#endif\n        if(ii!=i){\n          fprintf(stderr,\"Combination-index mismatch (%lu!=%lu).\\n\",\n           (long)ii,(long)i);\n          return 1;\n        }\n        if(v!=nc){\n          fprintf(stderr,\"Combination count mismatch (%lu!=%lu).\\n\",\n           (long)v,(long)nc);\n          return 2;\n        }\n        /*printf(\" %6u\\n\",i);*/\n      }\n      /*printf(\"\\n\");*/\n    }\n  }\n  return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/tests/test_unit_dft.c",
    "content": "/* Copyright (c) 2008 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#define SKIP_CONFIG_H\n\n#ifndef CUSTOM_MODES\n#define CUSTOM_MODES\n#endif\n\n#include <stdio.h>\n\n#define CELT_C\n#define TEST_UNIT_DFT_C\n#include \"stack_alloc.h\"\n#include \"kiss_fft.h\"\n#include \"kiss_fft.c\"\n#include \"mathops.c\"\n#include \"entcode.c\"\n\n#if defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)\n# include \"x86/x86cpu.c\"\n#elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\n# include \"arm/armcpu.c\"\n# include \"celt_lpc.c\"\n# include \"pitch.c\"\n# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\n#  include \"arm/celt_neon_intr.c\"\n#  if defined(HAVE_ARM_NE10)\n#   include \"mdct.c\"\n#   include \"arm/celt_ne10_fft.c\"\n#   include \"arm/celt_ne10_mdct.c\"\n#  endif\n# endif\n# include \"arm/arm_celt_map.c\"\n#endif\n\n#ifndef M_PI\n#define M_PI 3.141592653\n#endif\n\nint ret = 0;\n\nvoid check(kiss_fft_cpx  * in,kiss_fft_cpx  * out,int nfft,int isinverse)\n{\n    int bin,k;\n    double errpow=0,sigpow=0, snr;\n\n    for (bin=0;bin<nfft;++bin) {\n        double ansr = 0;\n        double ansi = 0;\n        double difr;\n        double difi;\n\n        for (k=0;k<nfft;++k) {\n            double phase = -2*M_PI*bin*k/nfft;\n            double re = cos(phase);\n            double im = sin(phase);\n            if (isinverse)\n                im = -im;\n\n            if (!isinverse)\n            {\n               re /= nfft;\n               im /= nfft;\n            }\n\n            ansr += in[k].r * re - in[k].i * im;\n            ansi += in[k].r * im + in[k].i * re;\n        }\n        /*printf (\"%d %d \", (int)ansr, (int)ansi);*/\n        difr = ansr - out[bin].r;\n        difi = ansi - out[bin].i;\n        errpow += difr*difr + difi*difi;\n        sigpow += ansr*ansr+ansi*ansi;\n    }\n    snr = 10*log10(sigpow/errpow);\n    printf(\"nfft=%d inverse=%d,snr = %f\\n\",nfft,isinverse,snr );\n    if (snr<60) {\n       printf( \"** poor snr: %f ** \\n\", snr);\n       ret = 1;\n    }\n}\n\nvoid test1d(int nfft,int isinverse,int arch)\n{\n    size_t buflen = sizeof(kiss_fft_cpx)*nfft;\n\n    kiss_fft_cpx  * in = (kiss_fft_cpx*)malloc(buflen);\n    kiss_fft_cpx  * out= (kiss_fft_cpx*)malloc(buflen);\n    kiss_fft_state *cfg = opus_fft_alloc(nfft,0,0,arch);\n    int k;\n\n    for (k=0;k<nfft;++k) {\n        in[k].r = (rand() % 32767) - 16384;\n        in[k].i = (rand() % 32767) - 16384;\n    }\n\n    for (k=0;k<nfft;++k) {\n       in[k].r *= 32768;\n       in[k].i *= 32768;\n    }\n\n    if (isinverse)\n    {\n       for (k=0;k<nfft;++k) {\n          in[k].r /= nfft;\n          in[k].i /= nfft;\n       }\n    }\n\n    /*for (k=0;k<nfft;++k) printf(\"%d %d \", in[k].r, in[k].i);printf(\"\\n\");*/\n\n    if (isinverse)\n       opus_ifft(cfg,in,out, arch);\n    else\n       opus_fft(cfg,in,out, arch);\n\n    /*for (k=0;k<nfft;++k) printf(\"%d %d \", out[k].r, out[k].i);printf(\"\\n\");*/\n\n    check(in,out,nfft,isinverse);\n\n    free(in);\n    free(out);\n    opus_fft_free(cfg, arch);\n}\n\nint main(int argc,char ** argv)\n{\n    ALLOC_STACK;\n    int arch = opus_select_arch();\n\n    if (argc>1) {\n        int k;\n        for (k=1;k<argc;++k) {\n            test1d(atoi(argv[k]),0,arch);\n            test1d(atoi(argv[k]),1,arch);\n        }\n    }else{\n        test1d(32,0,arch);\n        test1d(32,1,arch);\n        test1d(128,0,arch);\n        test1d(128,1,arch);\n        test1d(256,0,arch);\n        test1d(256,1,arch);\n#ifndef RADIX_TWO_ONLY\n        test1d(36,0,arch);\n        test1d(36,1,arch);\n        test1d(50,0,arch);\n        test1d(50,1,arch);\n        test1d(60,0,arch);\n        test1d(60,1,arch);\n        test1d(120,0,arch);\n        test1d(120,1,arch);\n        test1d(240,0,arch);\n        test1d(240,1,arch);\n        test1d(480,0,arch);\n        test1d(480,1,arch);\n#endif\n    }\n    return ret;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/tests/test_unit_entropy.c",
    "content": "/* Copyright (c) 2007-2011 Xiph.Org Foundation, Mozilla Corporation,\n                           Gregory Maxwell\n   Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdlib.h>\n#include <stdio.h>\n#include <math.h>\n#include <time.h>\n#include \"entcode.h\"\n#include \"entenc.h\"\n#include \"entdec.h\"\n#include <string.h>\n\n#include \"entenc.c\"\n#include \"entdec.c\"\n#include \"entcode.c\"\n\n#ifndef M_LOG2E\n# define M_LOG2E    1.4426950408889634074\n#endif\n#define DATA_SIZE 10000000\n#define DATA_SIZE2 10000\n\nint main(int _argc,char **_argv){\n  ec_enc         enc;\n  ec_dec         dec;\n  long           nbits;\n  long           nbits2;\n  double         entropy;\n  int            ft;\n  int            ftb;\n  int            sz;\n  int            i;\n  int            ret;\n  unsigned int   sym;\n  unsigned int   seed;\n  unsigned char *ptr;\n  const char    *env_seed;\n  ret=0;\n  entropy=0;\n  if (_argc > 2) {\n    fprintf(stderr, \"Usage: %s [<seed>]\\n\", _argv[0]);\n    return 1;\n  }\n  env_seed = getenv(\"SEED\");\n  if (_argc > 1)\n    seed = atoi(_argv[1]);\n  else if (env_seed)\n    seed = atoi(env_seed);\n  else\n    seed = time(NULL);\n  /*Testing encoding of raw bit values.*/\n  ptr = (unsigned char *)malloc(DATA_SIZE);\n  ec_enc_init(&enc,ptr, DATA_SIZE);\n  for(ft=2;ft<1024;ft++){\n    for(i=0;i<ft;i++){\n      entropy+=log(ft)*M_LOG2E;\n      ec_enc_uint(&enc,i,ft);\n    }\n  }\n  /*Testing encoding of raw bit values.*/\n  for(ftb=1;ftb<16;ftb++){\n    for(i=0;i<(1<<ftb);i++){\n      entropy+=ftb;\n      nbits=ec_tell(&enc);\n      ec_enc_bits(&enc,i,ftb);\n      nbits2=ec_tell(&enc);\n      if(nbits2-nbits!=ftb){\n        fprintf(stderr,\"Used %li bits to encode %i bits directly.\\n\",\n         nbits2-nbits,ftb);\n        ret=-1;\n      }\n    }\n  }\n  nbits=ec_tell_frac(&enc);\n  ec_enc_done(&enc);\n  fprintf(stderr,\n   \"Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\\n\",\n   entropy,ldexp(nbits,-3),100*(nbits-ldexp(entropy,3))/nbits);\n  fprintf(stderr,\"Packed to %li bytes.\\n\",(long)ec_range_bytes(&enc));\n  ec_dec_init(&dec,ptr,DATA_SIZE);\n  for(ft=2;ft<1024;ft++){\n    for(i=0;i<ft;i++){\n      sym=ec_dec_uint(&dec,ft);\n      if(sym!=(unsigned)i){\n        fprintf(stderr,\"Decoded %i instead of %i with ft of %i.\\n\",sym,i,ft);\n        ret=-1;\n      }\n    }\n  }\n  for(ftb=1;ftb<16;ftb++){\n    for(i=0;i<(1<<ftb);i++){\n      sym=ec_dec_bits(&dec,ftb);\n      if(sym!=(unsigned)i){\n        fprintf(stderr,\"Decoded %i instead of %i with ftb of %i.\\n\",sym,i,ftb);\n        ret=-1;\n      }\n    }\n  }\n  nbits2=ec_tell_frac(&dec);\n  if(nbits!=nbits2){\n    fprintf(stderr,\n     \"Reported number of bits used was %0.2lf, should be %0.2lf.\\n\",\n     ldexp(nbits2,-3),ldexp(nbits,-3));\n    ret=-1;\n  }\n  /*Testing an encoder bust prefers range coder data over raw bits.\n    This isn't a general guarantee, will only work for data that is buffered in\n     the encoder state and not yet stored in the user buffer, and should never\n     get used in practice.\n    It's mostly here for code coverage completeness.*/\n  /*Start with a 16-bit buffer.*/\n  ec_enc_init(&enc,ptr,2);\n  /*Write 7 raw bits.*/\n  ec_enc_bits(&enc,0x55,7);\n  /*Write 12.3 bits of range coder data.*/\n  ec_enc_uint(&enc,1,2);\n  ec_enc_uint(&enc,1,3);\n  ec_enc_uint(&enc,1,4);\n  ec_enc_uint(&enc,1,5);\n  ec_enc_uint(&enc,2,6);\n  ec_enc_uint(&enc,6,7);\n  ec_enc_done(&enc);\n  ec_dec_init(&dec,ptr,2);\n  if(!enc.error\n   /*The raw bits should have been overwritten by the range coder data.*/\n   ||ec_dec_bits(&dec,7)!=0x05\n   /*And all the range coder data should have been encoded correctly.*/\n   ||ec_dec_uint(&dec,2)!=1\n   ||ec_dec_uint(&dec,3)!=1\n   ||ec_dec_uint(&dec,4)!=1\n   ||ec_dec_uint(&dec,5)!=1\n   ||ec_dec_uint(&dec,6)!=2\n   ||ec_dec_uint(&dec,7)!=6){\n    fprintf(stderr,\"Encoder bust overwrote range coder data with raw bits.\\n\");\n    ret=-1;\n  }\n  srand(seed);\n  fprintf(stderr,\"Testing random streams... Random seed: %u (%.4X)\\n\", seed, rand() % 65536);\n  for(i=0;i<409600;i++){\n    unsigned *data;\n    unsigned *tell;\n    unsigned tell_bits;\n    int       j;\n    int zeros;\n    ft=rand()/((RAND_MAX>>(rand()%11U))+1U)+10;\n    sz=rand()/((RAND_MAX>>(rand()%9U))+1U);\n    data=(unsigned *)malloc(sz*sizeof(*data));\n    tell=(unsigned *)malloc((sz+1)*sizeof(*tell));\n    ec_enc_init(&enc,ptr,DATA_SIZE2);\n    zeros = rand()%13==0;\n    tell[0]=ec_tell_frac(&enc);\n    for(j=0;j<sz;j++){\n      if (zeros)\n        data[j]=0;\n      else\n        data[j]=rand()%ft;\n      ec_enc_uint(&enc,data[j],ft);\n      tell[j+1]=ec_tell_frac(&enc);\n    }\n    if (rand()%2==0)\n      while(ec_tell(&enc)%8 != 0)\n        ec_enc_uint(&enc, rand()%2, 2);\n    tell_bits = ec_tell(&enc);\n    ec_enc_done(&enc);\n    if(tell_bits!=(unsigned)ec_tell(&enc)){\n      fprintf(stderr,\"ec_tell() changed after ec_enc_done(): %i instead of %i (Random seed: %u)\\n\",\n       ec_tell(&enc),tell_bits,seed);\n      ret=-1;\n    }\n    if ((tell_bits+7)/8 < ec_range_bytes(&enc))\n    {\n      fprintf (stderr, \"ec_tell() lied, there's %i bytes instead of %d (Random seed: %u)\\n\",\n               ec_range_bytes(&enc), (tell_bits+7)/8,seed);\n      ret=-1;\n    }\n    ec_dec_init(&dec,ptr,DATA_SIZE2);\n    if(ec_tell_frac(&dec)!=tell[0]){\n      fprintf(stderr,\n       \"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\\n\",\n       0,ec_tell_frac(&dec),tell[0],seed);\n    }\n    for(j=0;j<sz;j++){\n      sym=ec_dec_uint(&dec,ft);\n      if(sym!=data[j]){\n        fprintf(stderr,\n         \"Decoded %i instead of %i with ft of %i at position %i of %i (Random seed: %u).\\n\",\n         sym,data[j],ft,j,sz,seed);\n        ret=-1;\n      }\n      if(ec_tell_frac(&dec)!=tell[j+1]){\n        fprintf(stderr,\n         \"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\\n\",\n         j+1,ec_tell_frac(&dec),tell[j+1],seed);\n      }\n    }\n    free(tell);\n    free(data);\n  }\n  /*Test compatibility between multiple different encode/decode routines.*/\n  for(i=0;i<409600;i++){\n    unsigned *logp1;\n    unsigned *data;\n    unsigned *tell;\n    unsigned *enc_method;\n    int       j;\n    sz=rand()/((RAND_MAX>>(rand()%9U))+1U);\n    logp1=(unsigned *)malloc(sz*sizeof(*logp1));\n    data=(unsigned *)malloc(sz*sizeof(*data));\n    tell=(unsigned *)malloc((sz+1)*sizeof(*tell));\n    enc_method=(unsigned *)malloc(sz*sizeof(*enc_method));\n    ec_enc_init(&enc,ptr,DATA_SIZE2);\n    tell[0]=ec_tell_frac(&enc);\n    for(j=0;j<sz;j++){\n      data[j]=rand()/((RAND_MAX>>1)+1);\n      logp1[j]=(rand()%15)+1;\n      enc_method[j]=rand()/((RAND_MAX>>2)+1);\n      switch(enc_method[j]){\n        case 0:{\n          ec_encode(&enc,data[j]?(1<<logp1[j])-1:0,\n           (1<<logp1[j])-(data[j]?0:1),1<<logp1[j]);\n        }break;\n        case 1:{\n          ec_encode_bin(&enc,data[j]?(1<<logp1[j])-1:0,\n           (1<<logp1[j])-(data[j]?0:1),logp1[j]);\n        }break;\n        case 2:{\n          ec_enc_bit_logp(&enc,data[j],logp1[j]);\n        }break;\n        case 3:{\n          unsigned char icdf[2];\n          icdf[0]=1;\n          icdf[1]=0;\n          ec_enc_icdf(&enc,data[j],icdf,logp1[j]);\n        }break;\n      }\n      tell[j+1]=ec_tell_frac(&enc);\n    }\n    ec_enc_done(&enc);\n    if((ec_tell(&enc)+7U)/8U<ec_range_bytes(&enc)){\n      fprintf(stderr,\"tell() lied, there's %i bytes instead of %d (Random seed: %u)\\n\",\n       ec_range_bytes(&enc),(ec_tell(&enc)+7)/8,seed);\n      ret=-1;\n    }\n    ec_dec_init(&dec,ptr,DATA_SIZE2);\n    if(ec_tell_frac(&dec)!=tell[0]){\n      fprintf(stderr,\n       \"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\\n\",\n       0,ec_tell_frac(&dec),tell[0],seed);\n    }\n    for(j=0;j<sz;j++){\n      int fs;\n      int dec_method;\n      dec_method=rand()/((RAND_MAX>>2)+1);\n      switch(dec_method){\n        case 0:{\n          fs=ec_decode(&dec,1<<logp1[j]);\n          sym=fs>=(1<<logp1[j])-1;\n          ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,\n           (1<<logp1[j])-(sym?0:1),1<<logp1[j]);\n        }break;\n        case 1:{\n          fs=ec_decode_bin(&dec,logp1[j]);\n          sym=fs>=(1<<logp1[j])-1;\n          ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,\n           (1<<logp1[j])-(sym?0:1),1<<logp1[j]);\n        }break;\n        case 2:{\n          sym=ec_dec_bit_logp(&dec,logp1[j]);\n        }break;\n        case 3:{\n          unsigned char icdf[2];\n          icdf[0]=1;\n          icdf[1]=0;\n          sym=ec_dec_icdf(&dec,icdf,logp1[j]);\n        }break;\n      }\n      if(sym!=data[j]){\n        fprintf(stderr,\n         \"Decoded %i instead of %i with logp1 of %i at position %i of %i (Random seed: %u).\\n\",\n         sym,data[j],logp1[j],j,sz,seed);\n        fprintf(stderr,\"Encoding method: %i, decoding method: %i\\n\",\n         enc_method[j],dec_method);\n        ret=-1;\n      }\n      if(ec_tell_frac(&dec)!=tell[j+1]){\n        fprintf(stderr,\n         \"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\\n\",\n         j+1,ec_tell_frac(&dec),tell[j+1],seed);\n      }\n    }\n    free(enc_method);\n    free(tell);\n    free(data);\n    free(logp1);\n  }\n  ec_enc_init(&enc,ptr,DATA_SIZE2);\n  ec_enc_bit_logp(&enc,0,1);\n  ec_enc_bit_logp(&enc,0,1);\n  ec_enc_bit_logp(&enc,0,1);\n  ec_enc_bit_logp(&enc,0,1);\n  ec_enc_bit_logp(&enc,0,2);\n  ec_enc_patch_initial_bits(&enc,3,2);\n  if(enc.error){\n    fprintf(stderr,\"patch_initial_bits failed\");\n    ret=-1;\n  }\n  ec_enc_patch_initial_bits(&enc,0,5);\n  if(!enc.error){\n    fprintf(stderr,\"patch_initial_bits didn't fail when it should have\");\n    ret=-1;\n  }\n  ec_enc_done(&enc);\n  if(ec_range_bytes(&enc)!=1||ptr[0]!=192){\n    fprintf(stderr,\"Got %d when expecting 192 for patch_initial_bits\",ptr[0]);\n    ret=-1;\n  }\n  ec_enc_init(&enc,ptr,DATA_SIZE2);\n  ec_enc_bit_logp(&enc,0,1);\n  ec_enc_bit_logp(&enc,0,1);\n  ec_enc_bit_logp(&enc,1,6);\n  ec_enc_bit_logp(&enc,0,2);\n  ec_enc_patch_initial_bits(&enc,0,2);\n  if(enc.error){\n    fprintf(stderr,\"patch_initial_bits failed\");\n    ret=-1;\n  }\n  ec_enc_done(&enc);\n  if(ec_range_bytes(&enc)!=2||ptr[0]!=63){\n    fprintf(stderr,\"Got %d when expecting 63 for patch_initial_bits\",ptr[0]);\n    ret=-1;\n  }\n  ec_enc_init(&enc,ptr,2);\n  ec_enc_bit_logp(&enc,0,2);\n  for(i=0;i<48;i++){\n    ec_enc_bits(&enc,0,1);\n  }\n  ec_enc_done(&enc);\n  if(!enc.error){\n    fprintf(stderr,\"Raw bits overfill didn't fail when it should have\");\n    ret=-1;\n  }\n  ec_enc_init(&enc,ptr,2);\n  for(i=0;i<17;i++){\n    ec_enc_bits(&enc,0,1);\n  }\n  ec_enc_done(&enc);\n  if(!enc.error){\n    fprintf(stderr,\"17 raw bits encoded in two bytes\");\n    ret=-1;\n  }\n  free(ptr);\n  return ret;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/tests/test_unit_laplace.c",
    "content": "/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation\n   Written by Jean-Marc Valin and Timothy B. Terriberry */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include \"laplace.h\"\n#define CELT_C\n#include \"stack_alloc.h\"\n\n#include \"entenc.c\"\n#include \"entdec.c\"\n#include \"entcode.c\"\n#include \"laplace.c\"\n\n#define DATA_SIZE 40000\n\nint ec_laplace_get_start_freq(int decay)\n{\n   opus_uint32 ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN+1);\n   int fs = (ft*(16384-decay))/(16384+decay);\n   return fs+LAPLACE_MINP;\n}\n\nint main(void)\n{\n   int i;\n   int ret = 0;\n   ec_enc enc;\n   ec_dec dec;\n   unsigned char *ptr;\n   int val[10000], decay[10000];\n   ALLOC_STACK;\n   ptr = (unsigned char *)malloc(DATA_SIZE);\n   ec_enc_init(&enc,ptr,DATA_SIZE);\n\n   val[0] = 3; decay[0] = 6000;\n   val[1] = 0; decay[1] = 5800;\n   val[2] = -1; decay[2] = 5600;\n   for (i=3;i<10000;i++)\n   {\n      val[i] = rand()%15-7;\n      decay[i] = rand()%11000+5000;\n   }\n   for (i=0;i<10000;i++)\n      ec_laplace_encode(&enc, &val[i],\n            ec_laplace_get_start_freq(decay[i]), decay[i]);\n\n   ec_enc_done(&enc);\n\n   ec_dec_init(&dec,ec_get_buffer(&enc),ec_range_bytes(&enc));\n\n   for (i=0;i<10000;i++)\n   {\n      int d = ec_laplace_decode(&dec,\n            ec_laplace_get_start_freq(decay[i]), decay[i]);\n      if (d != val[i])\n      {\n         fprintf (stderr, \"Got %d instead of %d\\n\", d, val[i]);\n         ret = 1;\n      }\n   }\n\n   free(ptr);\n   return ret;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/tests/test_unit_mathops.c",
    "content": "/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,\n                           Gregory Maxwell\n   Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#ifndef CUSTOM_MODES\n#define CUSTOM_MODES\n#endif\n\n#define CELT_C\n\n#include <stdio.h>\n#include <math.h>\n#include \"mathops.c\"\n#include \"entenc.c\"\n#include \"entdec.c\"\n#include \"entcode.c\"\n#include \"bands.c\"\n#include \"quant_bands.c\"\n#include \"laplace.c\"\n#include \"vq.c\"\n#include \"cwrs.c\"\n#include \"pitch.c\"\n#include \"celt_lpc.c\"\n#include \"celt.c\"\n\n#if defined(OPUS_X86_MAY_HAVE_SSE) || defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)\n# if defined(OPUS_X86_MAY_HAVE_SSE)\n#  include \"x86/pitch_sse.c\"\n# endif\n# if defined(OPUS_X86_MAY_HAVE_SSE2)\n#  include \"x86/pitch_sse2.c\"\n# endif\n# if defined(OPUS_X86_MAY_HAVE_SSE4_1)\n#  include \"x86/pitch_sse4_1.c\"\n#  include \"x86/celt_lpc_sse.c\"\n# endif\n# include \"x86/x86_celt_map.c\"\n#elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\n# include \"arm/armcpu.c\"\n# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\n#  include \"arm/celt_neon_intr.c\"\n#  if defined(HAVE_ARM_NE10)\n#   include \"kiss_fft.c\"\n#   include \"mdct.c\"\n#   include \"arm/celt_ne10_fft.c\"\n#   include \"arm/celt_ne10_mdct.c\"\n#  endif\n# endif\n# include \"arm/arm_celt_map.c\"\n#endif\n\n#ifdef FIXED_POINT\n#define WORD \"%d\"\n#else\n#define WORD \"%f\"\n#endif\n\nint ret = 0;\n\nvoid testdiv(void)\n{\n   opus_int32 i;\n   for (i=1;i<=327670;i++)\n   {\n      double prod;\n      opus_val32 val;\n      val = celt_rcp(i);\n#ifdef FIXED_POINT\n      prod = (1./32768./65526.)*val*i;\n#else\n      prod = val*i;\n#endif\n      if (fabs(prod-1) > .00025)\n      {\n         fprintf (stderr, \"div failed: 1/%d=\"WORD\" (product = %f)\\n\", i, val, prod);\n         ret = 1;\n      }\n   }\n}\n\nvoid testsqrt(void)\n{\n   opus_int32 i;\n   for (i=1;i<=1000000000;i++)\n   {\n      double ratio;\n      opus_val16 val;\n      val = celt_sqrt(i);\n      ratio = val/sqrt(i);\n      if (fabs(ratio - 1) > .0005 && fabs(val-sqrt(i)) > 2)\n      {\n         fprintf (stderr, \"sqrt failed: sqrt(%d)=\"WORD\" (ratio = %f)\\n\", i, val, ratio);\n         ret = 1;\n      }\n      i+= i>>10;\n   }\n}\n\nvoid testbitexactcos(void)\n{\n   int i;\n   opus_int32 min_d,max_d,last,chk;\n   chk=max_d=0;\n   last=min_d=32767;\n   for(i=64;i<=16320;i++)\n   {\n      opus_int32 d;\n      opus_int32 q=bitexact_cos(i);\n      chk ^= q*i;\n      d = last - q;\n      if (d>max_d)max_d=d;\n      if (d<min_d)min_d=d;\n      last = q;\n   }\n   if ((chk!=89408644)||(max_d!=5)||(min_d!=0)||(bitexact_cos(64)!=32767)||\n       (bitexact_cos(16320)!=200)||(bitexact_cos(8192)!=23171))\n   {\n      fprintf (stderr, \"bitexact_cos failed\\n\");\n      ret = 1;\n   }\n}\n\nvoid testbitexactlog2tan(void)\n{\n   int i,fail;\n   opus_int32 min_d,max_d,last,chk;\n   fail=chk=max_d=0;\n   last=min_d=15059;\n   for(i=64;i<8193;i++)\n   {\n      opus_int32 d;\n      opus_int32 mid=bitexact_cos(i);\n      opus_int32 side=bitexact_cos(16384-i);\n      opus_int32 q=bitexact_log2tan(mid,side);\n      chk ^= q*i;\n      d = last - q;\n      if (q!=-1*bitexact_log2tan(side,mid))\n        fail = 1;\n      if (d>max_d)max_d=d;\n      if (d<min_d)min_d=d;\n      last = q;\n   }\n   if ((chk!=15821257)||(max_d!=61)||(min_d!=-2)||fail||\n       (bitexact_log2tan(32767,200)!=15059)||(bitexact_log2tan(30274,12540)!=2611)||\n       (bitexact_log2tan(23171,23171)!=0))\n   {\n      fprintf (stderr, \"bitexact_log2tan failed\\n\");\n      ret = 1;\n   }\n}\n\n#ifndef FIXED_POINT\nvoid testlog2(void)\n{\n   float x;\n   for (x=0.001;x<1677700.0;x+=(x/8.0))\n   {\n      float error = fabs((1.442695040888963387*log(x))-celt_log2(x));\n      if (error>0.0009)\n      {\n         fprintf (stderr, \"celt_log2 failed: fabs((1.442695040888963387*log(x))-celt_log2(x))>0.001 (x = %f, error = %f)\\n\", x,error);\n         ret = 1;\n      }\n   }\n}\n\nvoid testexp2(void)\n{\n   float x;\n   for (x=-11.0;x<24.0;x+=0.0007)\n   {\n      float error = fabs(x-(1.442695040888963387*log(celt_exp2(x))));\n      if (error>0.0002)\n      {\n         fprintf (stderr, \"celt_exp2 failed: fabs(x-(1.442695040888963387*log(celt_exp2(x))))>0.0005 (x = %f, error = %f)\\n\", x,error);\n         ret = 1;\n      }\n   }\n}\n\nvoid testexp2log2(void)\n{\n   float x;\n   for (x=-11.0;x<24.0;x+=0.0007)\n   {\n      float error = fabs(x-(celt_log2(celt_exp2(x))));\n      if (error>0.001)\n      {\n         fprintf (stderr, \"celt_log2/celt_exp2 failed: fabs(x-(celt_log2(celt_exp2(x))))>0.001 (x = %f, error = %f)\\n\", x,error);\n         ret = 1;\n      }\n   }\n}\n#else\nvoid testlog2(void)\n{\n   opus_val32 x;\n   for (x=8;x<1073741824;x+=(x>>3))\n   {\n      float error = fabs((1.442695040888963387*log(x/16384.0))-celt_log2(x)/1024.0);\n      if (error>0.003)\n      {\n         fprintf (stderr, \"celt_log2 failed: x = %ld, error = %f\\n\", (long)x,error);\n         ret = 1;\n      }\n   }\n}\n\nvoid testexp2(void)\n{\n   opus_val16 x;\n   for (x=-32768;x<15360;x++)\n   {\n      float error1 = fabs(x/1024.0-(1.442695040888963387*log(celt_exp2(x)/65536.0)));\n      float error2 = fabs(exp(0.6931471805599453094*x/1024.0)-celt_exp2(x)/65536.0);\n      if (error1>0.0002&&error2>0.00004)\n      {\n         fprintf (stderr, \"celt_exp2 failed: x = \"WORD\", error1 = %f, error2 = %f\\n\", x,error1,error2);\n         ret = 1;\n      }\n   }\n}\n\nvoid testexp2log2(void)\n{\n   opus_val32 x;\n   for (x=8;x<65536;x+=(x>>3))\n   {\n      float error = fabs(x-0.25*celt_exp2(celt_log2(x)))/16384;\n      if (error>0.004)\n      {\n         fprintf (stderr, \"celt_log2/celt_exp2 failed: fabs(x-(celt_exp2(celt_log2(x))))>0.001 (x = %ld, error = %f)\\n\", (long)x,error);\n         ret = 1;\n      }\n   }\n}\n\nvoid testilog2(void)\n{\n   opus_val32 x;\n   for (x=1;x<=268435455;x+=127)\n   {\n      opus_val32 lg;\n      opus_val32 y;\n\n      lg = celt_ilog2(x);\n      if (lg<0 || lg>=31)\n      {\n         printf(\"celt_ilog2 failed: 0<=celt_ilog2(x)<31 (x = %d, celt_ilog2(x) = %d)\\n\",x,lg);\n         ret = 1;\n      }\n      y = 1<<lg;\n\n      if (x<y || (x>>1)>=y)\n      {\n         printf(\"celt_ilog2 failed: 2**celt_ilog2(x)<=x<2**(celt_ilog2(x)+1) (x = %d, 2**celt_ilog2(x) = %d)\\n\",x,y);\n         ret = 1;\n      }\n   }\n}\n#endif\n\nint main(void)\n{\n   testbitexactcos();\n   testbitexactlog2tan();\n   testdiv();\n   testsqrt();\n   testlog2();\n   testexp2();\n   testexp2log2();\n#ifdef FIXED_POINT\n   testilog2();\n#endif\n   return ret;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/tests/test_unit_mdct.c",
    "content": "/* Copyright (c) 2008-2011 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#define SKIP_CONFIG_H\n\n#ifndef CUSTOM_MODES\n#define CUSTOM_MODES\n#endif\n\n#include <stdio.h>\n\n#define CELT_C\n#include \"mdct.h\"\n#include \"stack_alloc.h\"\n\n#include \"kiss_fft.c\"\n#include \"mdct.c\"\n#include \"mathops.c\"\n#include \"entcode.c\"\n\n#if defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)\n# include \"x86/x86cpu.c\"\n#elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\n# include \"arm/armcpu.c\"\n# include \"pitch.c\"\n# include \"celt_lpc.c\"\n# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\n#  include \"arm/celt_neon_intr.c\"\n#  if defined(HAVE_ARM_NE10)\n#   include \"arm/celt_ne10_fft.c\"\n#   include \"arm/celt_ne10_mdct.c\"\n#  endif\n# endif\n# include \"arm/arm_celt_map.c\"\n#endif\n\n#ifndef M_PI\n#define M_PI 3.141592653\n#endif\n\nint ret = 0;\nvoid check(kiss_fft_scalar  * in,kiss_fft_scalar  * out,int nfft,int isinverse)\n{\n    int bin,k;\n    double errpow=0,sigpow=0;\n    double snr;\n    for (bin=0;bin<nfft/2;++bin) {\n        double ansr = 0;\n        double difr;\n\n        for (k=0;k<nfft;++k) {\n           double phase = 2*M_PI*(k+.5+.25*nfft)*(bin+.5)/nfft;\n           double re = cos(phase);\n\n           re /= nfft/4;\n\n           ansr += in[k] * re;\n        }\n        /*printf (\"%f %f\\n\", ansr, out[bin]);*/\n        difr = ansr - out[bin];\n        errpow += difr*difr;\n        sigpow += ansr*ansr;\n    }\n    snr = 10*log10(sigpow/errpow);\n    printf(\"nfft=%d inverse=%d,snr = %f\\n\",nfft,isinverse,snr );\n    if (snr<60) {\n       printf( \"** poor snr: %f **\\n\", snr);\n       ret = 1;\n    }\n}\n\nvoid check_inv(kiss_fft_scalar  * in,kiss_fft_scalar  * out,int nfft,int isinverse)\n{\n   int bin,k;\n   double errpow=0,sigpow=0;\n   double snr;\n   for (bin=0;bin<nfft;++bin) {\n      double ansr = 0;\n      double difr;\n\n      for (k=0;k<nfft/2;++k) {\n         double phase = 2*M_PI*(bin+.5+.25*nfft)*(k+.5)/nfft;\n         double re = cos(phase);\n\n         /*re *= 2;*/\n\n         ansr += in[k] * re;\n      }\n      /*printf (\"%f %f\\n\", ansr, out[bin]);*/\n      difr = ansr - out[bin];\n      errpow += difr*difr;\n      sigpow += ansr*ansr;\n   }\n   snr = 10*log10(sigpow/errpow);\n   printf(\"nfft=%d inverse=%d,snr = %f\\n\",nfft,isinverse,snr );\n   if (snr<60) {\n      printf( \"** poor snr: %f **\\n\", snr);\n      ret = 1;\n   }\n}\n\n\nvoid test1d(int nfft,int isinverse,int arch)\n{\n    mdct_lookup cfg;\n    size_t buflen = sizeof(kiss_fft_scalar)*nfft;\n\n    kiss_fft_scalar  * in = (kiss_fft_scalar*)malloc(buflen);\n    kiss_fft_scalar  * in_copy = (kiss_fft_scalar*)malloc(buflen);\n    kiss_fft_scalar  * out= (kiss_fft_scalar*)malloc(buflen);\n    opus_val16  * window= (opus_val16*)malloc(sizeof(opus_val16)*nfft/2);\n    int k;\n\n    clt_mdct_init(&cfg, nfft, 0, arch);\n    for (k=0;k<nfft;++k) {\n        in[k] = (rand() % 32768) - 16384;\n    }\n\n    for (k=0;k<nfft/2;++k) {\n       window[k] = Q15ONE;\n    }\n    for (k=0;k<nfft;++k) {\n       in[k] *= 32768;\n    }\n\n    if (isinverse)\n    {\n       for (k=0;k<nfft;++k) {\n          in[k] /= nfft;\n       }\n    }\n\n    for (k=0;k<nfft;++k)\n       in_copy[k] = in[k];\n    /*for (k=0;k<nfft;++k) printf(\"%d %d \", in[k].r, in[k].i);printf(\"\\n\");*/\n\n    if (isinverse)\n    {\n       for (k=0;k<nfft;++k)\n          out[k] = 0;\n       clt_mdct_backward(&cfg,in,out, window, nfft/2, 0, 1, arch);\n       /* apply TDAC because clt_mdct_backward() no longer does that */\n       for (k=0;k<nfft/4;++k)\n          out[nfft-k-1] = out[nfft/2+k];\n       check_inv(in,out,nfft,isinverse);\n    } else {\n       clt_mdct_forward(&cfg,in,out,window, nfft/2, 0, 1, arch);\n       check(in_copy,out,nfft,isinverse);\n    }\n    /*for (k=0;k<nfft;++k) printf(\"%d %d \", out[k].r, out[k].i);printf(\"\\n\");*/\n\n\n    free(in);\n    free(in_copy);\n    free(out);\n    free(window);\n    clt_mdct_clear(&cfg, arch);\n}\n\nint main(int argc,char ** argv)\n{\n    ALLOC_STACK;\n    int arch = opus_select_arch();\n\n    if (argc>1) {\n        int k;\n        for (k=1;k<argc;++k) {\n            test1d(atoi(argv[k]),0,arch);\n            test1d(atoi(argv[k]),1,arch);\n        }\n    }else{\n        test1d(32,0,arch);\n        test1d(32,1,arch);\n        test1d(256,0,arch);\n        test1d(256,1,arch);\n        test1d(512,0,arch);\n        test1d(512,1,arch);\n        test1d(1024,0,arch);\n        test1d(1024,1,arch);\n        test1d(2048,0,arch);\n        test1d(2048,1,arch);\n#ifndef RADIX_TWO_ONLY\n        test1d(36,0,arch);\n        test1d(36,1,arch);\n        test1d(40,0,arch);\n        test1d(40,1,arch);\n        test1d(60,0,arch);\n        test1d(60,1,arch);\n        test1d(120,0,arch);\n        test1d(120,1,arch);\n        test1d(240,0,arch);\n        test1d(240,1,arch);\n        test1d(480,0,arch);\n        test1d(480,1,arch);\n        test1d(960,0,arch);\n        test1d(960,1,arch);\n        test1d(1920,0,arch);\n        test1d(1920,1,arch);\n#endif\n    }\n    return ret;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/tests/test_unit_rotation.c",
    "content": "/* Copyright (c) 2008-2011 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#ifndef CUSTOM_MODES\n#define CUSTOM_MODES\n#endif\n\n#define CELT_C\n\n#include <stdio.h>\n#include <stdlib.h>\n#include \"vq.c\"\n#include \"cwrs.c\"\n#include \"entcode.c\"\n#include \"entenc.c\"\n#include \"entdec.c\"\n#include \"mathops.c\"\n#include \"bands.h\"\n#include \"pitch.c\"\n#include \"celt_lpc.c\"\n#include \"celt.c\"\n#include <math.h>\n\n#if defined(OPUS_X86_MAY_HAVE_SSE) || defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)\n# if defined(OPUS_X86_MAY_HAVE_SSE)\n#  include \"x86/pitch_sse.c\"\n# endif\n# if defined(OPUS_X86_MAY_HAVE_SSE2)\n#  include \"x86/pitch_sse2.c\"\n# endif\n# if defined(OPUS_X86_MAY_HAVE_SSE4_1)\n#  include \"x86/pitch_sse4_1.c\"\n#  include \"x86/celt_lpc_sse.c\"\n# endif\n# include \"x86/x86_celt_map.c\"\n#elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\n# include \"arm/armcpu.c\"\n# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)\n#  include \"arm/celt_neon_intr.c\"\n#  if defined(HAVE_ARM_NE10)\n#   include \"kiss_fft.c\"\n#   include \"mdct.c\"\n#   include \"arm/celt_ne10_fft.c\"\n#   include \"arm/celt_ne10_mdct.c\"\n#  endif\n# endif\n# include \"arm/arm_celt_map.c\"\n#endif\n\n#define MAX_SIZE 100\n\nint ret=0;\nvoid test_rotation(int N, int K)\n{\n   int i;\n   double err = 0, ener = 0, snr, snr0;\n   opus_val16 x0[MAX_SIZE];\n   opus_val16 x1[MAX_SIZE];\n   for (i=0;i<N;i++)\n      x1[i] = x0[i] = rand()%32767-16384;\n   exp_rotation(x1, N, 1, 1, K, SPREAD_NORMAL);\n   for (i=0;i<N;i++)\n   {\n      err += (x0[i]-(double)x1[i])*(x0[i]-(double)x1[i]);\n      ener += x0[i]*(double)x0[i];\n   }\n   snr0 = 20*log10(ener/err);\n   err = ener = 0;\n   exp_rotation(x1, N, -1, 1, K, SPREAD_NORMAL);\n   for (i=0;i<N;i++)\n   {\n      err += (x0[i]-(double)x1[i])*(x0[i]-(double)x1[i]);\n      ener += x0[i]*(double)x0[i];\n   }\n   snr = 20*log10(ener/err);\n   printf (\"SNR for size %d (%d pulses) is %f (was %f without inverse)\\n\", N, K, snr, snr0);\n   if (snr < 60 || snr0 > 20)\n   {\n      fprintf(stderr, \"FAIL!\\n\");\n      ret = 1;\n   }\n}\n\nint main(void)\n{\n   ALLOC_STACK;\n   test_rotation(15, 3);\n   test_rotation(23, 5);\n   test_rotation(50, 3);\n   test_rotation(80, 1);\n   return ret;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/tests/test_unit_types.c",
    "content": "/* Copyright (c) 2008-2011 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"opus_types.h\"\n#include <stdio.h>\n\nint main(void)\n{\n   opus_int16 i = 1;\n   i <<= 14;\n   if (i>>14 != 1)\n   {\n      fprintf(stderr, \"opus_int16 isn't 16 bits\\n\");\n      return 1;\n   }\n   if (sizeof(opus_int16)*2 != sizeof(opus_int32))\n   {\n      fprintf(stderr, \"16*2 != 32\\n\");\n      return 1;\n   }\n   return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/vq.c",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"mathops.h\"\n#include \"cwrs.h\"\n#include \"vq.h\"\n#include \"arch.h\"\n#include \"os_support.h\"\n#include \"bands.h\"\n#include \"rate.h\"\n#include \"pitch.h\"\n\n#ifndef OVERRIDE_vq_exp_rotation1\nstatic void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s)\n{\n   int i;\n   opus_val16 ms;\n   celt_norm *Xptr;\n   Xptr = X;\n   ms = NEG16(s);\n   for (i=0;i<len-stride;i++)\n   {\n      celt_norm x1, x2;\n      x1 = Xptr[0];\n      x2 = Xptr[stride];\n      Xptr[stride] = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x2),  s, x1), 15));\n      *Xptr++      = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x1), ms, x2), 15));\n   }\n   Xptr = &X[len-2*stride-1];\n   for (i=len-2*stride-1;i>=0;i--)\n   {\n      celt_norm x1, x2;\n      x1 = Xptr[0];\n      x2 = Xptr[stride];\n      Xptr[stride] = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x2),  s, x1), 15));\n      *Xptr--      = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x1), ms, x2), 15));\n   }\n}\n#endif /* OVERRIDE_vq_exp_rotation1 */\n\nstatic void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread)\n{\n   static const int SPREAD_FACTOR[3]={15,10,5};\n   int i;\n   opus_val16 c, s;\n   opus_val16 gain, theta;\n   int stride2=0;\n   int factor;\n\n   if (2*K>=len || spread==SPREAD_NONE)\n      return;\n   factor = SPREAD_FACTOR[spread-1];\n\n   gain = celt_div((opus_val32)MULT16_16(Q15_ONE,len),(opus_val32)(len+factor*K));\n   theta = HALF16(MULT16_16_Q15(gain,gain));\n\n   c = celt_cos_norm(EXTEND32(theta));\n   s = celt_cos_norm(EXTEND32(SUB16(Q15ONE,theta))); /*  sin(theta) */\n\n   if (len>=8*stride)\n   {\n      stride2 = 1;\n      /* This is just a simple (equivalent) way of computing sqrt(len/stride) with rounding.\n         It's basically incrementing long as (stride2+0.5)^2 < len/stride. */\n      while ((stride2*stride2+stride2)*stride + (stride>>2) < len)\n         stride2++;\n   }\n   /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for\n      extract_collapse_mask().*/\n   len = celt_udiv(len, stride);\n   for (i=0;i<stride;i++)\n   {\n      if (dir < 0)\n      {\n         if (stride2)\n            exp_rotation1(X+i*len, len, stride2, s, c);\n         exp_rotation1(X+i*len, len, 1, c, s);\n      } else {\n         exp_rotation1(X+i*len, len, 1, c, -s);\n         if (stride2)\n            exp_rotation1(X+i*len, len, stride2, s, -c);\n      }\n   }\n}\n\n/** Takes the pitch vector and the decoded residual vector, computes the gain\n    that will give ||p+g*y||=1 and mixes the residual with the pitch. */\nstatic void normalise_residual(int * OPUS_RESTRICT iy, celt_norm * OPUS_RESTRICT X,\n      int N, opus_val32 Ryy, opus_val16 gain)\n{\n   int i;\n#ifdef FIXED_POINT\n   int k;\n#endif\n   opus_val32 t;\n   opus_val16 g;\n\n#ifdef FIXED_POINT\n   k = celt_ilog2(Ryy)>>1;\n#endif\n   t = VSHR32(Ryy, 2*(k-7));\n   g = MULT16_16_P15(celt_rsqrt_norm(t),gain);\n\n   i=0;\n   do\n      X[i] = EXTRACT16(PSHR32(MULT16_16(g, iy[i]), k+1));\n   while (++i < N);\n}\n\nstatic unsigned extract_collapse_mask(int *iy, int N, int B)\n{\n   unsigned collapse_mask;\n   int N0;\n   int i;\n   if (B<=1)\n      return 1;\n   /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for\n      exp_rotation().*/\n   N0 = celt_udiv(N, B);\n   collapse_mask = 0;\n   i=0; do {\n      int j;\n      unsigned tmp=0;\n      j=0; do {\n         tmp |= iy[i*N0+j];\n      } while (++j<N0);\n      collapse_mask |= (tmp!=0)<<i;\n   } while (++i<B);\n   return collapse_mask;\n}\n\nunsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc\n#ifdef RESYNTH\n   , opus_val16 gain\n#endif\n   )\n{\n   VARDECL(celt_norm, y);\n   VARDECL(int, iy);\n   VARDECL(opus_val16, signx);\n   int i, j;\n   opus_val16 s;\n   int pulsesLeft;\n   opus_val32 sum;\n   opus_val32 xy;\n   opus_val16 yy;\n   unsigned collapse_mask;\n   SAVE_STACK;\n\n   celt_assert2(K>0, \"alg_quant() needs at least one pulse\");\n   celt_assert2(N>1, \"alg_quant() needs at least two dimensions\");\n\n   ALLOC(y, N, celt_norm);\n   ALLOC(iy, N, int);\n   ALLOC(signx, N, opus_val16);\n\n   exp_rotation(X, N, 1, B, K, spread);\n\n   /* Get rid of the sign */\n   sum = 0;\n   j=0; do {\n      if (X[j]>0)\n         signx[j]=1;\n      else {\n         signx[j]=-1;\n         X[j]=-X[j];\n      }\n      iy[j] = 0;\n      y[j] = 0;\n   } while (++j<N);\n\n   xy = yy = 0;\n\n   pulsesLeft = K;\n\n   /* Do a pre-search by projecting on the pyramid */\n   if (K > (N>>1))\n   {\n      opus_val16 rcp;\n      j=0; do {\n         sum += X[j];\n      }  while (++j<N);\n\n      /* If X is too small, just replace it with a pulse at 0 */\n#ifdef FIXED_POINT\n      if (sum <= K)\n#else\n      /* Prevents infinities and NaNs from causing too many pulses\n         to be allocated. 64 is an approximation of infinity here. */\n      if (!(sum > EPSILON && sum < 64))\n#endif\n      {\n         X[0] = QCONST16(1.f,14);\n         j=1; do\n            X[j]=0;\n         while (++j<N);\n         sum = QCONST16(1.f,14);\n      }\n      rcp = EXTRACT16(MULT16_32_Q16(K-1, celt_rcp(sum)));\n      j=0; do {\n#ifdef FIXED_POINT\n         /* It's really important to round *towards zero* here */\n         iy[j] = MULT16_16_Q15(X[j],rcp);\n#else\n         iy[j] = (int)floor(rcp*X[j]);\n#endif\n         y[j] = (celt_norm)iy[j];\n         yy = MAC16_16(yy, y[j],y[j]);\n         xy = MAC16_16(xy, X[j],y[j]);\n         y[j] *= 2;\n         pulsesLeft -= iy[j];\n      }  while (++j<N);\n   }\n   celt_assert2(pulsesLeft>=1, \"Allocated too many pulses in the quick pass\");\n\n   /* This should never happen, but just in case it does (e.g. on silence)\n      we fill the first bin with pulses. */\n#ifdef FIXED_POINT_DEBUG\n   celt_assert2(pulsesLeft<=N+3, \"Not enough pulses in the quick pass\");\n#endif\n   if (pulsesLeft > N+3)\n   {\n      opus_val16 tmp = (opus_val16)pulsesLeft;\n      yy = MAC16_16(yy, tmp, tmp);\n      yy = MAC16_16(yy, tmp, y[0]);\n      iy[0] += pulsesLeft;\n      pulsesLeft=0;\n   }\n\n   s = 1;\n   for (i=0;i<pulsesLeft;i++)\n   {\n      int best_id;\n      opus_val32 best_num = -VERY_LARGE16;\n      opus_val16 best_den = 0;\n#ifdef FIXED_POINT\n      int rshift;\n#endif\n#ifdef FIXED_POINT\n      rshift = 1+celt_ilog2(K-pulsesLeft+i+1);\n#endif\n      best_id = 0;\n      /* The squared magnitude term gets added anyway, so we might as well\n         add it outside the loop */\n      yy = ADD32(yy, 1);\n      j=0;\n      do {\n         opus_val16 Rxy, Ryy;\n         /* Temporary sums of the new pulse(s) */\n         Rxy = EXTRACT16(SHR32(ADD32(xy, EXTEND32(X[j])),rshift));\n         /* We're multiplying y[j] by two so we don't have to do it here */\n         Ryy = ADD16(yy, y[j]);\n\n         /* Approximate score: we maximise Rxy/sqrt(Ryy) (we're guaranteed that\n            Rxy is positive because the sign is pre-computed) */\n         Rxy = MULT16_16_Q15(Rxy,Rxy);\n         /* The idea is to check for num/den >= best_num/best_den, but that way\n            we can do it without any division */\n         /* OPT: Make sure to use conditional moves here */\n         if (MULT16_16(best_den, Rxy) > MULT16_16(Ryy, best_num))\n         {\n            best_den = Ryy;\n            best_num = Rxy;\n            best_id = j;\n         }\n      } while (++j<N);\n\n      /* Updating the sums of the new pulse(s) */\n      xy = ADD32(xy, EXTEND32(X[best_id]));\n      /* We're multiplying y[j] by two so we don't have to do it here */\n      yy = ADD16(yy, y[best_id]);\n\n      /* Only now that we've made the final choice, update y/iy */\n      /* Multiplying y[j] by 2 so we don't have to do it everywhere else */\n      y[best_id] += 2*s;\n      iy[best_id]++;\n   }\n\n   /* Put the original sign back */\n   j=0;\n   do {\n      X[j] = MULT16_16(signx[j],X[j]);\n      if (signx[j] < 0)\n         iy[j] = -iy[j];\n   } while (++j<N);\n   encode_pulses(iy, N, K, enc);\n\n#ifdef RESYNTH\n   normalise_residual(iy, X, N, yy, gain);\n   exp_rotation(X, N, -1, B, K, spread);\n#endif\n\n   collapse_mask = extract_collapse_mask(iy, N, B);\n   RESTORE_STACK;\n   return collapse_mask;\n}\n\n/** Decode pulse vector and combine the result with the pitch vector to produce\n    the final normalised signal in the current band. */\nunsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B,\n      ec_dec *dec, opus_val16 gain)\n{\n   opus_val32 Ryy;\n   unsigned collapse_mask;\n   VARDECL(int, iy);\n   SAVE_STACK;\n\n   celt_assert2(K>0, \"alg_unquant() needs at least one pulse\");\n   celt_assert2(N>1, \"alg_unquant() needs at least two dimensions\");\n   ALLOC(iy, N, int);\n   Ryy = decode_pulses(iy, N, K, dec);\n   normalise_residual(iy, X, N, Ryy, gain);\n   exp_rotation(X, N, -1, B, K, spread);\n   collapse_mask = extract_collapse_mask(iy, N, B);\n   RESTORE_STACK;\n   return collapse_mask;\n}\n\n#ifndef OVERRIDE_renormalise_vector\nvoid renormalise_vector(celt_norm *X, int N, opus_val16 gain, int arch)\n{\n   int i;\n#ifdef FIXED_POINT\n   int k;\n#endif\n   opus_val32 E;\n   opus_val16 g;\n   opus_val32 t;\n   celt_norm *xptr;\n   E = EPSILON + celt_inner_prod(X, X, N, arch);\n#ifdef FIXED_POINT\n   k = celt_ilog2(E)>>1;\n#endif\n   t = VSHR32(E, 2*(k-7));\n   g = MULT16_16_P15(celt_rsqrt_norm(t),gain);\n\n   xptr = X;\n   for (i=0;i<N;i++)\n   {\n      *xptr = EXTRACT16(PSHR32(MULT16_16(g, *xptr), k+1));\n      xptr++;\n   }\n   /*return celt_sqrt(E);*/\n}\n#endif /* OVERRIDE_renormalise_vector */\n\nint stereo_itheta(const celt_norm *X, const celt_norm *Y, int stereo, int N, int arch)\n{\n   int i;\n   int itheta;\n   opus_val16 mid, side;\n   opus_val32 Emid, Eside;\n\n   Emid = Eside = EPSILON;\n   if (stereo)\n   {\n      for (i=0;i<N;i++)\n      {\n         celt_norm m, s;\n         m = ADD16(SHR16(X[i],1),SHR16(Y[i],1));\n         s = SUB16(SHR16(X[i],1),SHR16(Y[i],1));\n         Emid = MAC16_16(Emid, m, m);\n         Eside = MAC16_16(Eside, s, s);\n      }\n   } else {\n      Emid += celt_inner_prod(X, X, N, arch);\n      Eside += celt_inner_prod(Y, Y, N, arch);\n   }\n   mid = celt_sqrt(Emid);\n   side = celt_sqrt(Eside);\n#ifdef FIXED_POINT\n   /* 0.63662 = 2/pi */\n   itheta = MULT16_16_Q15(QCONST16(0.63662f,15),celt_atan2p(side, mid));\n#else\n   itheta = (int)floor(.5f+16384*0.63662f*atan2(side,mid));\n#endif\n\n   return itheta;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/vq.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/**\n   @file vq.h\n   @brief Vector quantisation of the residual\n */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef VQ_H\n#define VQ_H\n\n#include \"entenc.h\"\n#include \"entdec.h\"\n#include \"modes.h\"\n\n#if defined(MIPSr1_ASM)\n#include \"mips/vq_mipsr1.h\"\n#endif\n\n\n/** Algebraic pulse-vector quantiser. The signal x is replaced by the sum of\n  * the pitch and a combination of pulses such that its norm is still equal\n  * to 1. This is the function that will typically require the most CPU.\n * @param X Residual signal to quantise/encode (returns quantised version)\n * @param N Number of samples to encode\n * @param K Number of pulses to use\n * @param enc Entropy encoder state\n * @ret A mask indicating which blocks in the band received pulses\n*/\nunsigned alg_quant(celt_norm *X, int N, int K, int spread, int B,\n      ec_enc *enc\n#ifdef RESYNTH\n      , opus_val16 gain\n#endif\n      );\n\n/** Algebraic pulse decoder\n * @param X Decoded normalised spectrum (returned)\n * @param N Number of samples to decode\n * @param K Number of pulses to use\n * @param dec Entropy decoder state\n * @ret A mask indicating which blocks in the band received pulses\n */\nunsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B,\n      ec_dec *dec, opus_val16 gain);\n\nvoid renormalise_vector(celt_norm *X, int N, opus_val16 gain, int arch);\n\nint stereo_itheta(const celt_norm *X, const celt_norm *Y, int stereo, int N, int arch);\n\n#endif /* VQ_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/x86/celt_lpc_sse.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <xmmintrin.h>\n#include <emmintrin.h>\n#include <smmintrin.h>\n#include \"celt_lpc.h\"\n#include \"stack_alloc.h\"\n#include \"mathops.h\"\n#include \"pitch.h\"\n#include \"x86cpu.h\"\n\n#if defined(FIXED_POINT)\n\nvoid celt_fir_sse4_1(const opus_val16 *_x,\n         const opus_val16 *num,\n         opus_val16 *_y,\n         int N,\n         int ord,\n         opus_val16 *mem,\n         int arch)\n{\n    int i,j;\n    VARDECL(opus_val16, rnum);\n    VARDECL(opus_val16, x);\n\n    __m128i vecNoA;\n    opus_int32 noA ;\n    SAVE_STACK;\n\n   ALLOC(rnum, ord, opus_val16);\n   ALLOC(x, N+ord, opus_val16);\n   for(i=0;i<ord;i++)\n      rnum[i] = num[ord-i-1];\n   for(i=0;i<ord;i++)\n      x[i] = mem[ord-i-1];\n\n   for (i=0;i<N-7;i+=8)\n   {\n       x[i+ord  ]=_x[i  ];\n       x[i+ord+1]=_x[i+1];\n       x[i+ord+2]=_x[i+2];\n       x[i+ord+3]=_x[i+3];\n       x[i+ord+4]=_x[i+4];\n       x[i+ord+5]=_x[i+5];\n       x[i+ord+6]=_x[i+6];\n       x[i+ord+7]=_x[i+7];\n   }\n\n   for (;i<N-3;i+=4)\n   {\n       x[i+ord  ]=_x[i  ];\n       x[i+ord+1]=_x[i+1];\n       x[i+ord+2]=_x[i+2];\n       x[i+ord+3]=_x[i+3];\n   }\n\n   for (;i<N;i++)\n         x[i+ord]=_x[i];\n\n   for(i=0;i<ord;i++)\n      mem[i] = _x[N-i-1];\n#ifdef SMALL_FOOTPRINT\n   for (i=0;i<N;i++)\n   {\n      opus_val32 sum = SHL32(EXTEND32(_x[i]), SIG_SHIFT);\n      for (j=0;j<ord;j++)\n      {\n         sum = MAC16_16(sum,rnum[j],x[i+j]);\n      }\n      _y[i] = SATURATE16(PSHR32(sum, SIG_SHIFT));\n   }\n#else\n   noA = EXTEND32(1) << SIG_SHIFT >> 1;\n   vecNoA = _mm_set_epi32(noA, noA, noA, noA);\n\n   for (i=0;i<N-3;i+=4)\n   {\n      opus_val32 sums[4] = {0};\n      __m128i vecSum, vecX;\n\n      xcorr_kernel(rnum, x+i, sums, ord, arch);\n\n      vecSum = _mm_loadu_si128((__m128i *)sums);\n      vecSum = _mm_add_epi32(vecSum, vecNoA);\n      vecSum = _mm_srai_epi32(vecSum, SIG_SHIFT);\n      vecX = OP_CVTEPI16_EPI32_M64(_x + i);\n      vecSum = _mm_add_epi32(vecSum, vecX);\n      vecSum = _mm_packs_epi32(vecSum, vecSum);\n      _mm_storel_epi64((__m128i *)(_y + i), vecSum);\n   }\n   for (;i<N;i++)\n   {\n      opus_val32 sum = 0;\n      for (j=0;j<ord;j++)\n         sum = MAC16_16(sum, rnum[j], x[i + j]);\n      _y[i] = SATURATE16(ADD32(EXTEND32(_x[i]), PSHR32(sum, SIG_SHIFT)));\n   }\n\n#endif\n   RESTORE_STACK;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/x86/celt_lpc_sse.h",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef CELT_LPC_SSE_H\n#define CELT_LPC_SSE_H\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#if defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT)\n#define OVERRIDE_CELT_FIR\n\nvoid celt_fir_sse4_1(\n         const opus_val16 *x,\n         const opus_val16 *num,\n         opus_val16 *y,\n         int N,\n         int ord,\n         opus_val16 *mem,\n         int arch);\n\n#if defined(OPUS_X86_PRESUME_SSE4_1)\n#define celt_fir(x, num, y, N, ord, mem, arch) \\\n    ((void)arch, celt_fir_sse4_1(x, num, y, N, ord, mem, arch))\n\n#else\n\nextern void (*const CELT_FIR_IMPL[OPUS_ARCHMASK + 1])(\n         const opus_val16 *x,\n         const opus_val16 *num,\n         opus_val16 *y,\n         int N,\n         int ord,\n         opus_val16 *mem,\n         int arch);\n\n#  define celt_fir(x, num, y, N, ord, mem, arch) \\\n    ((*CELT_FIR_IMPL[(arch) & OPUS_ARCHMASK])(x, num, y, N, ord, mem, arch))\n\n#endif\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/x86/pitch_sse.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"macros.h\"\n#include \"celt_lpc.h\"\n#include \"stack_alloc.h\"\n#include \"mathops.h\"\n#include \"pitch.h\"\n\n#if defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT)\n\n#include <xmmintrin.h>\n#include \"arch.h\"\n\nvoid xcorr_kernel_sse(const opus_val16 *x, const opus_val16 *y, opus_val32 sum[4], int len)\n{\n   int j;\n   __m128 xsum1, xsum2;\n   xsum1 = _mm_loadu_ps(sum);\n   xsum2 = _mm_setzero_ps();\n\n   for (j = 0; j < len-3; j += 4)\n   {\n      __m128 x0 = _mm_loadu_ps(x+j);\n      __m128 yj = _mm_loadu_ps(y+j);\n      __m128 y3 = _mm_loadu_ps(y+j+3);\n\n      xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0x00),yj));\n      xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0x55),\n                                          _mm_shuffle_ps(yj,y3,0x49)));\n      xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0xaa),\n                                          _mm_shuffle_ps(yj,y3,0x9e)));\n      xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0xff),y3));\n   }\n   if (j < len)\n   {\n      xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j)));\n      if (++j < len)\n      {\n         xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j)));\n         if (++j < len)\n         {\n            xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j)));\n         }\n      }\n   }\n   _mm_storeu_ps(sum,_mm_add_ps(xsum1,xsum2));\n}\n\n\nvoid dual_inner_prod_sse(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,\n      int N, opus_val32 *xy1, opus_val32 *xy2)\n{\n   int i;\n   __m128 xsum1, xsum2;\n   xsum1 = _mm_setzero_ps();\n   xsum2 = _mm_setzero_ps();\n   for (i=0;i<N-3;i+=4)\n   {\n      __m128 xi = _mm_loadu_ps(x+i);\n      __m128 y1i = _mm_loadu_ps(y01+i);\n      __m128 y2i = _mm_loadu_ps(y02+i);\n      xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(xi, y1i));\n      xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(xi, y2i));\n   }\n   /* Horizontal sum */\n   xsum1 = _mm_add_ps(xsum1, _mm_movehl_ps(xsum1, xsum1));\n   xsum1 = _mm_add_ss(xsum1, _mm_shuffle_ps(xsum1, xsum1, 0x55));\n   _mm_store_ss(xy1, xsum1);\n   xsum2 = _mm_add_ps(xsum2, _mm_movehl_ps(xsum2, xsum2));\n   xsum2 = _mm_add_ss(xsum2, _mm_shuffle_ps(xsum2, xsum2, 0x55));\n   _mm_store_ss(xy2, xsum2);\n   for (;i<N;i++)\n   {\n      *xy1 = MAC16_16(*xy1, x[i], y01[i]);\n      *xy2 = MAC16_16(*xy2, x[i], y02[i]);\n   }\n}\n\nopus_val32 celt_inner_prod_sse(const opus_val16 *x, const opus_val16 *y,\n      int N)\n{\n   int i;\n   float xy;\n   __m128 sum;\n   sum = _mm_setzero_ps();\n   /* FIXME: We should probably go 8-way and use 2 sums. */\n   for (i=0;i<N-3;i+=4)\n   {\n      __m128 xi = _mm_loadu_ps(x+i);\n      __m128 yi = _mm_loadu_ps(y+i);\n      sum = _mm_add_ps(sum,_mm_mul_ps(xi, yi));\n   }\n   /* Horizontal sum */\n   sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));\n   sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));\n   _mm_store_ss(&xy, sum);\n   for (;i<N;i++)\n   {\n      xy = MAC16_16(xy, x[i], y[i]);\n   }\n   return xy;\n}\n\nvoid comb_filter_const_sse(opus_val32 *y, opus_val32 *x, int T, int N,\n      opus_val16 g10, opus_val16 g11, opus_val16 g12)\n{\n   int i;\n   __m128 x0v;\n   __m128 g10v, g11v, g12v;\n   g10v = _mm_load1_ps(&g10);\n   g11v = _mm_load1_ps(&g11);\n   g12v = _mm_load1_ps(&g12);\n   x0v = _mm_loadu_ps(&x[-T-2]);\n   for (i=0;i<N-3;i+=4)\n   {\n      __m128 yi, yi2, x1v, x2v, x3v, x4v;\n      const opus_val32 *xp = &x[i-T-2];\n      yi = _mm_loadu_ps(x+i);\n      x4v = _mm_loadu_ps(xp+4);\n#if 0\n      /* Slower version with all loads */\n      x1v = _mm_loadu_ps(xp+1);\n      x2v = _mm_loadu_ps(xp+2);\n      x3v = _mm_loadu_ps(xp+3);\n#else\n      x2v = _mm_shuffle_ps(x0v, x4v, 0x4e);\n      x1v = _mm_shuffle_ps(x0v, x2v, 0x99);\n      x3v = _mm_shuffle_ps(x2v, x4v, 0x99);\n#endif\n\n      yi = _mm_add_ps(yi, _mm_mul_ps(g10v,x2v));\n#if 0 /* Set to 1 to make it bit-exact with the non-SSE version */\n      yi = _mm_add_ps(yi, _mm_mul_ps(g11v,_mm_add_ps(x3v,x1v)));\n      yi = _mm_add_ps(yi, _mm_mul_ps(g12v,_mm_add_ps(x4v,x0v)));\n#else\n      /* Use partial sums */\n      yi2 = _mm_add_ps(_mm_mul_ps(g11v,_mm_add_ps(x3v,x1v)),\n                       _mm_mul_ps(g12v,_mm_add_ps(x4v,x0v)));\n      yi = _mm_add_ps(yi, yi2);\n#endif\n      x0v=x4v;\n      _mm_storeu_ps(y+i, yi);\n   }\n#ifdef CUSTOM_MODES\n   for (;i<N;i++)\n   {\n      y[i] = x[i]\n               + MULT16_32_Q15(g10,x[i-T])\n               + MULT16_32_Q15(g11,ADD32(x[i-T+1],x[i-T-1]))\n               + MULT16_32_Q15(g12,ADD32(x[i-T+2],x[i-T-2]));\n   }\n#endif\n}\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/x86/pitch_sse.h",
    "content": "/* Copyright (c) 2013 Jean-Marc Valin and John Ridges\n   Copyright (c) 2014, Cisco Systems, INC MingXiang WeiZhou MinPeng YanWang*/\n/**\n   @file pitch_sse.h\n   @brief Pitch analysis\n */\n\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef PITCH_SSE_H\n#define PITCH_SSE_H\n\n#if defined(HAVE_CONFIG_H)\n#include \"config.h\"\n#endif\n\n#if defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT)\nvoid xcorr_kernel_sse4_1(\n                    const opus_int16 *x,\n                    const opus_int16 *y,\n                    opus_val32       sum[4],\n                    int              len);\n#endif\n\n#if defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT)\nvoid xcorr_kernel_sse(\n                    const opus_val16 *x,\n                    const opus_val16 *y,\n                    opus_val32       sum[4],\n                    int              len);\n#endif\n\n#if defined(OPUS_X86_PRESUME_SSE4_1) && defined(FIXED_POINT)\n#define OVERRIDE_XCORR_KERNEL\n#define xcorr_kernel(x, y, sum, len, arch) \\\n    ((void)arch, xcorr_kernel_sse4_1(x, y, sum, len))\n\n#elif defined(OPUS_X86_PRESUME_SSE) && !defined(FIXED_POINT)\n#define OVERRIDE_XCORR_KERNEL\n#define xcorr_kernel(x, y, sum, len, arch) \\\n    ((void)arch, xcorr_kernel_sse(x, y, sum, len))\n\n#elif (defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT)) || (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT))\n\nextern void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(\n                    const opus_val16 *x,\n                    const opus_val16 *y,\n                    opus_val32       sum[4],\n                    int              len);\n\n#define OVERRIDE_XCORR_KERNEL\n#define xcorr_kernel(x, y, sum, len, arch) \\\n    ((*XCORR_KERNEL_IMPL[(arch) & OPUS_ARCHMASK])(x, y, sum, len))\n\n#endif\n\n#if defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT)\nopus_val32 celt_inner_prod_sse4_1(\n    const opus_int16 *x,\n    const opus_int16 *y,\n    int               N);\n#endif\n\n#if defined(OPUS_X86_MAY_HAVE_SSE2) && defined(FIXED_POINT)\nopus_val32 celt_inner_prod_sse2(\n    const opus_int16 *x,\n    const opus_int16 *y,\n    int               N);\n#endif\n\n#if defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(FIXED_POINT)\nopus_val32 celt_inner_prod_sse(\n    const opus_val16 *x,\n    const opus_val16 *y,\n    int               N);\n#endif\n\n\n#if defined(OPUS_X86_PRESUME_SSE4_1) && defined(FIXED_POINT)\n#define OVERRIDE_CELT_INNER_PROD\n#define celt_inner_prod(x, y, N, arch) \\\n\t((void)arch, celt_inner_prod_sse4_1(x, y, N))\n\n#elif defined(OPUS_X86_PRESUME_SSE2) && defined(FIXED_POINT) && !defined(OPUS_X86_MAY_HAVE_SSE4_1)\n#define OVERRIDE_CELT_INNER_PROD\n#define celt_inner_prod(x, y, N, arch) \\\n\t((void)arch, celt_inner_prod_sse2(x, y, N))\n\n#elif defined(OPUS_X86_PRESUME_SSE) && !defined(FIXED_POINT)\n#define OVERRIDE_CELT_INNER_PROD\n#define celt_inner_prod(x, y, N, arch) \\\n\t((void)arch, celt_inner_prod_sse(x, y, N))\n\n\n#elif ((defined(OPUS_X86_MAY_HAVE_SSE4_1) || defined(OPUS_X86_MAY_HAVE_SSE2)) && defined(FIXED_POINT)) || \\\n\t(defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT))\n\nextern opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(\n                    const opus_val16 *x,\n                    const opus_val16 *y,\n                    int               N);\n\n#define OVERRIDE_CELT_INNER_PROD\n#define celt_inner_prod(x, y, N, arch) \\\n    ((*CELT_INNER_PROD_IMPL[(arch) & OPUS_ARCHMASK])(x, y, N))\n\n#endif\n\n#if defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT)\n\n#define OVERRIDE_DUAL_INNER_PROD\n#define OVERRIDE_COMB_FILTER_CONST\n\n#undef dual_inner_prod\n#undef comb_filter_const\n\nvoid dual_inner_prod_sse(const opus_val16 *x,\n\tconst opus_val16 *y01,\n\tconst opus_val16 *y02,\n\tint               N,\n\topus_val32       *xy1,\n\topus_val32       *xy2);\n\nvoid comb_filter_const_sse(opus_val32 *y,\n\topus_val32 *x,\n\tint         T,\n\tint         N,\n\topus_val16  g10,\n\topus_val16  g11,\n\topus_val16  g12);\n\n\n#if defined(OPUS_X86_PRESUME_SSE)\n# define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) \\\n    ((void)(arch),dual_inner_prod_sse(x, y01, y02, N, xy1, xy2))\n\n# define comb_filter_const(y, x, T, N, g10, g11, g12, arch) \\\n    ((void)(arch),comb_filter_const_sse(y, x, T, N, g10, g11, g12))\n#else\n\nextern void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(\n              const opus_val16 *x,\n              const opus_val16 *y01,\n              const opus_val16 *y02,\n              int               N,\n              opus_val32       *xy1,\n              opus_val32       *xy2);\n\n#define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch)\t\t\t\\\n    ((*DUAL_INNER_PROD_IMPL[(arch) & OPUS_ARCHMASK])(x, y01, y02, N, xy1, xy2))\n\nextern void (*const COMB_FILTER_CONST_IMPL[OPUS_ARCHMASK + 1])(\n              opus_val32 *y,\n              opus_val32 *x,\n              int         T,\n              int         N,\n              opus_val16  g10,\n              opus_val16  g11,\n              opus_val16  g12);\n\n#define comb_filter_const(y, x, T, N, g10, g11, g12, arch)\t\t\t\t\\\n    ((*COMB_FILTER_CONST_IMPL[(arch) & OPUS_ARCHMASK])(y, x, T, N, g10, g11, g12))\n\n#define NON_STATIC_COMB_FILTER_CONST_C\n\n#endif\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/x86/pitch_sse2.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <xmmintrin.h>\n#include <emmintrin.h>\n\n#include \"macros.h\"\n#include \"celt_lpc.h\"\n#include \"stack_alloc.h\"\n#include \"mathops.h\"\n#include \"pitch.h\"\n\n#if defined(OPUS_X86_MAY_HAVE_SSE2) && defined(FIXED_POINT)\nopus_val32 celt_inner_prod_sse2(const opus_val16 *x, const opus_val16 *y,\n      int N)\n{\n    opus_int  i, dataSize16;\n    opus_int32 sum;\n\n    __m128i inVec1_76543210, inVec1_FEDCBA98, acc1;\n    __m128i inVec2_76543210, inVec2_FEDCBA98, acc2;\n\n    sum = 0;\n    dataSize16 = N & ~15;\n\n    acc1 = _mm_setzero_si128();\n    acc2 = _mm_setzero_si128();\n\n    for (i=0;i<dataSize16;i+=16)\n    {\n        inVec1_76543210 = _mm_loadu_si128((__m128i *)(&x[i + 0]));\n        inVec2_76543210 = _mm_loadu_si128((__m128i *)(&y[i + 0]));\n\n        inVec1_FEDCBA98 = _mm_loadu_si128((__m128i *)(&x[i + 8]));\n        inVec2_FEDCBA98 = _mm_loadu_si128((__m128i *)(&y[i + 8]));\n\n        inVec1_76543210 = _mm_madd_epi16(inVec1_76543210, inVec2_76543210);\n        inVec1_FEDCBA98 = _mm_madd_epi16(inVec1_FEDCBA98, inVec2_FEDCBA98);\n\n        acc1 = _mm_add_epi32(acc1, inVec1_76543210);\n        acc2 = _mm_add_epi32(acc2, inVec1_FEDCBA98);\n    }\n\n    acc1 = _mm_add_epi32( acc1, acc2 );\n\n    if (N - i >= 8)\n    {\n        inVec1_76543210 = _mm_loadu_si128((__m128i *)(&x[i + 0]));\n        inVec2_76543210 = _mm_loadu_si128((__m128i *)(&y[i + 0]));\n\n        inVec1_76543210 = _mm_madd_epi16(inVec1_76543210, inVec2_76543210);\n\n        acc1 = _mm_add_epi32(acc1, inVec1_76543210);\n        i += 8;\n    }\n\n    acc1 = _mm_add_epi32(acc1, _mm_unpackhi_epi64( acc1, acc1));\n    acc1 = _mm_add_epi32(acc1, _mm_shufflelo_epi16( acc1, 0x0E));\n    sum += _mm_cvtsi128_si32(acc1);\n\n    for (;i<N;i++) {\n        sum = silk_SMLABB(sum, x[i], y[i]);\n    }\n\n    return sum;\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/x86/pitch_sse4_1.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <xmmintrin.h>\n#include <emmintrin.h>\n\n#include \"macros.h\"\n#include \"celt_lpc.h\"\n#include \"stack_alloc.h\"\n#include \"mathops.h\"\n#include \"pitch.h\"\n\n#if defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT)\n#include <smmintrin.h>\n#include \"x86cpu.h\"\n\nopus_val32 celt_inner_prod_sse4_1(const opus_val16 *x, const opus_val16 *y,\n      int N)\n{\n    opus_int  i, dataSize16;\n    opus_int32 sum;\n    __m128i inVec1_76543210, inVec1_FEDCBA98, acc1;\n    __m128i inVec2_76543210, inVec2_FEDCBA98, acc2;\n    __m128i inVec1_3210, inVec2_3210;\n\n    sum = 0;\n    dataSize16 = N & ~15;\n\n    acc1 = _mm_setzero_si128();\n    acc2 = _mm_setzero_si128();\n\n    for (i=0;i<dataSize16;i+=16) {\n        inVec1_76543210 = _mm_loadu_si128((__m128i *)(&x[i + 0]));\n        inVec2_76543210 = _mm_loadu_si128((__m128i *)(&y[i + 0]));\n\n        inVec1_FEDCBA98 = _mm_loadu_si128((__m128i *)(&x[i + 8]));\n        inVec2_FEDCBA98 = _mm_loadu_si128((__m128i *)(&y[i + 8]));\n\n        inVec1_76543210 = _mm_madd_epi16(inVec1_76543210, inVec2_76543210);\n        inVec1_FEDCBA98 = _mm_madd_epi16(inVec1_FEDCBA98, inVec2_FEDCBA98);\n\n        acc1 = _mm_add_epi32(acc1, inVec1_76543210);\n        acc2 = _mm_add_epi32(acc2, inVec1_FEDCBA98);\n    }\n\n    acc1 = _mm_add_epi32(acc1, acc2);\n\n    if (N - i >= 8)\n    {\n        inVec1_76543210 = _mm_loadu_si128((__m128i *)(&x[i + 0]));\n        inVec2_76543210 = _mm_loadu_si128((__m128i *)(&y[i + 0]));\n\n        inVec1_76543210 = _mm_madd_epi16(inVec1_76543210, inVec2_76543210);\n\n        acc1 = _mm_add_epi32(acc1, inVec1_76543210);\n        i += 8;\n    }\n\n    if (N - i >= 4)\n    {\n        inVec1_3210 = OP_CVTEPI16_EPI32_M64(&x[i + 0]);\n        inVec2_3210 = OP_CVTEPI16_EPI32_M64(&y[i + 0]);\n\n        inVec1_3210 = _mm_mullo_epi32(inVec1_3210, inVec2_3210);\n\n        acc1 = _mm_add_epi32(acc1, inVec1_3210);\n        i += 4;\n    }\n\n    acc1 = _mm_add_epi32(acc1, _mm_unpackhi_epi64(acc1, acc1));\n    acc1 = _mm_add_epi32(acc1, _mm_shufflelo_epi16(acc1, 0x0E));\n\n    sum += _mm_cvtsi128_si32(acc1);\n\n    for (;i<N;i++)\n    {\n        sum = silk_SMLABB(sum, x[i], y[i]);\n    }\n\n    return sum;\n}\n\nvoid xcorr_kernel_sse4_1(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[ 4 ], int len)\n{\n    int j;\n\n    __m128i vecX, vecX0, vecX1, vecX2, vecX3;\n    __m128i vecY0, vecY1, vecY2, vecY3;\n    __m128i sum0, sum1, sum2, sum3, vecSum;\n    __m128i initSum;\n\n    celt_assert(len >= 3);\n\n    sum0 = _mm_setzero_si128();\n    sum1 = _mm_setzero_si128();\n    sum2 = _mm_setzero_si128();\n    sum3 = _mm_setzero_si128();\n\n    for (j=0;j<(len-7);j+=8)\n    {\n        vecX = _mm_loadu_si128((__m128i *)(&x[j + 0]));\n        vecY0 = _mm_loadu_si128((__m128i *)(&y[j + 0]));\n        vecY1 = _mm_loadu_si128((__m128i *)(&y[j + 1]));\n        vecY2 = _mm_loadu_si128((__m128i *)(&y[j + 2]));\n        vecY3 = _mm_loadu_si128((__m128i *)(&y[j + 3]));\n\n        sum0 = _mm_add_epi32(sum0, _mm_madd_epi16(vecX, vecY0));\n        sum1 = _mm_add_epi32(sum1, _mm_madd_epi16(vecX, vecY1));\n        sum2 = _mm_add_epi32(sum2, _mm_madd_epi16(vecX, vecY2));\n        sum3 = _mm_add_epi32(sum3, _mm_madd_epi16(vecX, vecY3));\n    }\n\n    sum0 = _mm_add_epi32(sum0, _mm_unpackhi_epi64( sum0, sum0));\n    sum0 = _mm_add_epi32(sum0, _mm_shufflelo_epi16( sum0, 0x0E));\n\n    sum1 = _mm_add_epi32(sum1, _mm_unpackhi_epi64( sum1, sum1));\n    sum1 = _mm_add_epi32(sum1, _mm_shufflelo_epi16( sum1, 0x0E));\n\n    sum2 = _mm_add_epi32(sum2, _mm_unpackhi_epi64( sum2, sum2));\n    sum2 = _mm_add_epi32(sum2, _mm_shufflelo_epi16( sum2, 0x0E));\n\n    sum3 = _mm_add_epi32(sum3, _mm_unpackhi_epi64( sum3, sum3));\n    sum3 = _mm_add_epi32(sum3, _mm_shufflelo_epi16( sum3, 0x0E));\n\n    vecSum = _mm_unpacklo_epi64(_mm_unpacklo_epi32(sum0, sum1),\n          _mm_unpacklo_epi32(sum2, sum3));\n\n    for (;j<(len-3);j+=4)\n    {\n        vecX = OP_CVTEPI16_EPI32_M64(&x[j + 0]);\n        vecX0 = _mm_shuffle_epi32(vecX, 0x00);\n        vecX1 = _mm_shuffle_epi32(vecX, 0x55);\n        vecX2 = _mm_shuffle_epi32(vecX, 0xaa);\n        vecX3 = _mm_shuffle_epi32(vecX, 0xff);\n\n        vecY0 = OP_CVTEPI16_EPI32_M64(&y[j + 0]);\n        vecY1 = OP_CVTEPI16_EPI32_M64(&y[j + 1]);\n        vecY2 = OP_CVTEPI16_EPI32_M64(&y[j + 2]);\n        vecY3 = OP_CVTEPI16_EPI32_M64(&y[j + 3]);\n\n        sum0 = _mm_mullo_epi32(vecX0, vecY0);\n        sum1 = _mm_mullo_epi32(vecX1, vecY1);\n        sum2 = _mm_mullo_epi32(vecX2, vecY2);\n        sum3 = _mm_mullo_epi32(vecX3, vecY3);\n\n        sum0 = _mm_add_epi32(sum0, sum1);\n        sum2 = _mm_add_epi32(sum2, sum3);\n        vecSum = _mm_add_epi32(vecSum, sum0);\n        vecSum = _mm_add_epi32(vecSum, sum2);\n    }\n\n    for (;j<len;j++)\n    {\n        vecX = OP_CVTEPI16_EPI32_M64(&x[j + 0]);\n        vecX0 = _mm_shuffle_epi32(vecX, 0x00);\n\n        vecY0 = OP_CVTEPI16_EPI32_M64(&y[j + 0]);\n\n        sum0 = _mm_mullo_epi32(vecX0, vecY0);\n        vecSum = _mm_add_epi32(vecSum, sum0);\n    }\n\n    initSum = _mm_loadu_si128((__m128i *)(&sum[0]));\n    initSum = _mm_add_epi32(initSum, vecSum);\n    _mm_storeu_si128((__m128i *)sum, initSum);\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/x86/x86_celt_map.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#if defined(HAVE_CONFIG_H)\n#include \"config.h\"\n#endif\n\n#include \"x86/x86cpu.h\"\n#include \"celt_lpc.h\"\n#include \"pitch.h\"\n#include \"pitch_sse.h\"\n\n#if defined(OPUS_HAVE_RTCD)\n\n# if defined(FIXED_POINT)\n\n#if defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)\n\nvoid (*const CELT_FIR_IMPL[OPUS_ARCHMASK + 1])(\n         const opus_val16 *x,\n         const opus_val16 *num,\n         opus_val16       *y,\n         int              N,\n         int              ord,\n         opus_val16       *mem,\n         int              arch\n) = {\n  celt_fir_c,                /* non-sse */\n  celt_fir_c,\n  celt_fir_c,\n  MAY_HAVE_SSE4_1(celt_fir), /* sse4.1  */\n  MAY_HAVE_SSE4_1(celt_fir)  /* avx  */\n};\n\nvoid (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(\n         const opus_val16 *x,\n         const opus_val16 *y,\n         opus_val32       sum[4],\n         int              len\n) = {\n  xcorr_kernel_c,                /* non-sse */\n  xcorr_kernel_c,\n  xcorr_kernel_c,\n  MAY_HAVE_SSE4_1(xcorr_kernel), /* sse4.1  */\n  MAY_HAVE_SSE4_1(xcorr_kernel)  /* avx  */\n};\n\n#endif\n\n#if (defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)) ||  \\\n\t(!defined(OPUS_X86_MAY_HAVE_SSE_4_1) && defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2))\n\nopus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(\n         const opus_val16 *x,\n         const opus_val16 *y,\n         int              N\n) = {\n  celt_inner_prod_c,                /* non-sse */\n  celt_inner_prod_c,\n  MAY_HAVE_SSE2(celt_inner_prod),\n  MAY_HAVE_SSE4_1(celt_inner_prod), /* sse4.1  */\n  MAY_HAVE_SSE4_1(celt_inner_prod)  /* avx  */\n};\n\n#endif\n\n# else\n\n#if defined(OPUS_X86_MAY_HAVE_SSE) && !defined(OPUS_X86_PRESUME_SSE)\n\nvoid (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(\n         const opus_val16 *x,\n         const opus_val16 *y,\n         opus_val32       sum[4],\n         int              len\n) = {\n  xcorr_kernel_c,                /* non-sse */\n  MAY_HAVE_SSE(xcorr_kernel),\n  MAY_HAVE_SSE(xcorr_kernel),\n  MAY_HAVE_SSE(xcorr_kernel),\n  MAY_HAVE_SSE(xcorr_kernel)\n};\n\nopus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(\n         const opus_val16 *x,\n         const opus_val16 *y,\n         int              N\n) = {\n  celt_inner_prod_c,                /* non-sse */\n  MAY_HAVE_SSE(celt_inner_prod),\n  MAY_HAVE_SSE(celt_inner_prod),\n  MAY_HAVE_SSE(celt_inner_prod),\n  MAY_HAVE_SSE(celt_inner_prod)\n};\n\nvoid (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(\n                    const opus_val16 *x,\n                    const opus_val16 *y01,\n                    const opus_val16 *y02,\n                    int               N,\n                    opus_val32       *xy1,\n                    opus_val32       *xy2\n) = {\n  dual_inner_prod_c,                /* non-sse */\n  MAY_HAVE_SSE(dual_inner_prod),\n  MAY_HAVE_SSE(dual_inner_prod),\n  MAY_HAVE_SSE(dual_inner_prod),\n  MAY_HAVE_SSE(dual_inner_prod)\n};\n\nvoid (*const COMB_FILTER_CONST_IMPL[OPUS_ARCHMASK + 1])(\n              opus_val32 *y,\n              opus_val32 *x,\n              int         T,\n              int         N,\n              opus_val16  g10,\n              opus_val16  g11,\n              opus_val16  g12\n) = {\n  comb_filter_const_c,                /* non-sse */\n  MAY_HAVE_SSE(comb_filter_const),\n  MAY_HAVE_SSE(comb_filter_const),\n  MAY_HAVE_SSE(comb_filter_const),\n  MAY_HAVE_SSE(comb_filter_const)\n};\n\n\n#endif\n\n#endif\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/x86/x86cpu.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"cpu_support.h\"\n#include \"macros.h\"\n#include \"main.h\"\n#include \"pitch.h\"\n#include \"x86cpu.h\"\n\n#if (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(OPUS_X86_PRESUME_SSE)) || \\\n  (defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2)) || \\\n  (defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)) || \\\n  (defined(OPUS_X86_MAY_HAVE_AVX) && !defined(OPUS_X86_PRESUME_AVX))\n\n\n#if defined(_MSC_VER)\n\n#include <intrin.h>\nstatic _inline void cpuid(unsigned int CPUInfo[4], unsigned int InfoType)\n{\n\t__cpuid((int*)CPUInfo, InfoType);\n}\n\n#else\n\n#if defined(CPU_INFO_BY_C)\n#include <cpuid.h>\n#endif\n\nstatic void cpuid(unsigned int CPUInfo[4], unsigned int InfoType)\n{\n#if defined(CPU_INFO_BY_ASM)\n#if defined(__i386__) && defined(__PIC__)\n/* %ebx is PIC register in 32-bit, so mustn't clobber it. */\n    __asm__ __volatile__ (\n        \"xchg %%ebx, %1\\n\"\n        \"cpuid\\n\"\n        \"xchg %%ebx, %1\\n\":\n        \"=a\" (CPUInfo[0]),\n        \"=r\" (CPUInfo[1]),\n        \"=c\" (CPUInfo[2]),\n        \"=d\" (CPUInfo[3]) :\n        \"0\" (InfoType)\n    );\n#else\n    __asm__ __volatile__ (\n        \"cpuid\":\n        \"=a\" (CPUInfo[0]),\n        \"=b\" (CPUInfo[1]),\n        \"=c\" (CPUInfo[2]),\n        \"=d\" (CPUInfo[3]) :\n        \"0\" (InfoType)\n    );\n#endif\n#elif defined(CPU_INFO_BY_C)\n    __get_cpuid(InfoType, &(CPUInfo[0]), &(CPUInfo[1]), &(CPUInfo[2]), &(CPUInfo[3]));\n#endif\n}\n\n#endif\n\ntypedef struct CPU_Feature{\n    /*  SIMD: 128-bit */\n    int HW_SSE;\n    int HW_SSE2;\n    int HW_SSE41;\n    /*  SIMD: 256-bit */\n    int HW_AVX;\n} CPU_Feature;\n\nstatic void opus_cpu_feature_check(CPU_Feature *cpu_feature)\n{\n    unsigned int info[4] = {0};\n    unsigned int nIds = 0;\n\n    cpuid(info, 0);\n    nIds = info[0];\n\n    if (nIds >= 1){\n        cpuid(info, 1);\n        cpu_feature->HW_SSE = (info[3] & (1 << 25)) != 0;\n        cpu_feature->HW_SSE2 = (info[3] & (1 << 26)) != 0;\n        cpu_feature->HW_SSE41 = (info[2] & (1 << 19)) != 0;\n        cpu_feature->HW_AVX = (info[2] & (1 << 28)) != 0;\n    }\n    else {\n        cpu_feature->HW_SSE = 0;\n        cpu_feature->HW_SSE2 = 0;\n        cpu_feature->HW_SSE41 = 0;\n        cpu_feature->HW_AVX = 0;\n    }\n}\n\nint opus_select_arch(void)\n{\n    CPU_Feature cpu_feature;\n    int arch;\n\n    opus_cpu_feature_check(&cpu_feature);\n\n    arch = 0;\n    if (!cpu_feature.HW_SSE)\n    {\n       return arch;\n    }\n    arch++;\n\n    if (!cpu_feature.HW_SSE2)\n    {\n       return arch;\n    }\n    arch++;\n\n    if (!cpu_feature.HW_SSE41)\n    {\n        return arch;\n    }\n    arch++;\n\n    if (!cpu_feature.HW_AVX)\n    {\n        return arch;\n    }\n    arch++;\n\n    return arch;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt/x86/x86cpu.h",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#if !defined(X86CPU_H)\n# define X86CPU_H\n\n# if defined(OPUS_X86_MAY_HAVE_SSE)\n#  define MAY_HAVE_SSE(name) name ## _sse\n# else\n#  define MAY_HAVE_SSE(name) name ## _c\n# endif\n\n# if defined(OPUS_X86_MAY_HAVE_SSE2)\n#  define MAY_HAVE_SSE2(name) name ## _sse2\n# else\n#  define MAY_HAVE_SSE2(name) name ## _c\n# endif\n\n# if defined(OPUS_X86_MAY_HAVE_SSE4_1)\n#  define MAY_HAVE_SSE4_1(name) name ## _sse4_1\n# else\n#  define MAY_HAVE_SSE4_1(name) name ## _c\n# endif\n\n# if defined(OPUS_X86_MAY_HAVE_AVX)\n#  define MAY_HAVE_AVX(name) name ## _avx\n# else\n#  define MAY_HAVE_AVX(name) name ## _c\n# endif\n\n# if defined(OPUS_HAVE_RTCD)\nint opus_select_arch(void);\n# endif\n\n/*gcc appears to emit MOVDQA's to load the argument of an _mm_cvtepi8_epi32()\n  or _mm_cvtepi16_epi32() when optimizations are disabled, even though the\n  actual PMOVSXWD instruction takes an m32 or m64. Unlike a normal memory\n  reference, these require 16-byte alignment and load a full 16 bytes (instead\n  of 4 or 8), possibly reading out of bounds.\n\n  We can insert an explicit MOVD or MOVQ using _mm_cvtsi32_si128() or\n  _mm_loadl_epi64(), which should have the same semantics as an m32 or m64\n  reference in the PMOVSXWD instruction itself, but gcc is not smart enough to\n  optimize this out when optimizations ARE enabled.\n\n  Clang, in contrast, requires us to do this always for _mm_cvtepi8_epi32\n  (which is fair, since technically the compiler is always allowed to do the\n  dereference before invoking the function implementing the intrinsic).\n  However, it is smart enough to eliminate the extra MOVD instruction.\n  For _mm_cvtepi16_epi32, it does the right thing, though does *not* optimize out\n  the extra MOVQ if it's specified explicitly */\n\n# if defined(__clang__) || !defined(__OPTIMIZE__)\n#  define OP_CVTEPI8_EPI32_M32(x) \\\n (_mm_cvtepi8_epi32(_mm_cvtsi32_si128(*(int *)(x))))\n# else\n#  define OP_CVTEPI8_EPI32_M32(x) \\\n (_mm_cvtepi8_epi32(*(__m128i *)(x)))\n#endif\n\n# if !defined(__OPTIMIZE__)\n#  define OP_CVTEPI16_EPI32_M64(x) \\\n (_mm_cvtepi16_epi32(_mm_loadl_epi64((__m128i *)(x))))\n# else\n#  define OP_CVTEPI16_EPI32_M64(x) \\\n (_mm_cvtepi16_epi32(*(__m128i *)(x)))\n# endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt_headers.mk",
    "content": "CELT_HEAD = \\\ncelt/arch.h \\\ncelt/bands.h \\\ncelt/celt.h \\\ncelt/cpu_support.h \\\ninclude/opus_types.h \\\ninclude/opus_defines.h \\\ninclude/opus_custom.h \\\ncelt/cwrs.h \\\ncelt/ecintrin.h \\\ncelt/entcode.h \\\ncelt/entdec.h \\\ncelt/entenc.h \\\ncelt/fixed_debug.h \\\ncelt/fixed_generic.h \\\ncelt/float_cast.h \\\ncelt/_kiss_fft_guts.h \\\ncelt/kiss_fft.h \\\ncelt/laplace.h \\\ncelt/mathops.h \\\ncelt/mdct.h \\\ncelt/mfrngcod.h \\\ncelt/modes.h \\\ncelt/os_support.h \\\ncelt/pitch.h \\\ncelt/celt_lpc.h \\\ncelt/x86/celt_lpc_sse.h \\\ncelt/quant_bands.h \\\ncelt/rate.h \\\ncelt/stack_alloc.h \\\ncelt/vq.h \\\ncelt/static_modes_float.h \\\ncelt/static_modes_fixed.h \\\ncelt/static_modes_float_arm_ne10.h \\\ncelt/static_modes_fixed_arm_ne10.h \\\ncelt/arm/armcpu.h \\\ncelt/arm/fixed_armv4.h \\\ncelt/arm/fixed_armv5e.h \\\ncelt/arm/kiss_fft_armv4.h \\\ncelt/arm/kiss_fft_armv5e.h \\\ncelt/arm/pitch_arm.h \\\ncelt/arm/fft_arm.h \\\ncelt/arm/mdct_arm.h \\\ncelt/mips/celt_mipsr1.h \\\ncelt/mips/fixed_generic_mipsr1.h \\\ncelt/mips/kiss_fft_mipsr1.h \\\ncelt/mips/mdct_mipsr1.h \\\ncelt/mips/pitch_mipsr1.h \\\ncelt/mips/vq_mipsr1.h \\\ncelt/x86/pitch_sse.h \\\ncelt/x86/x86cpu.h\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/celt_sources.mk",
    "content": "CELT_SOURCES = celt/bands.c \\\ncelt/celt.c \\\ncelt/celt_encoder.c \\\ncelt/celt_decoder.c \\\ncelt/cwrs.c \\\ncelt/entcode.c \\\ncelt/entdec.c \\\ncelt/entenc.c \\\ncelt/kiss_fft.c \\\ncelt/laplace.c \\\ncelt/mathops.c \\\ncelt/mdct.c \\\ncelt/modes.c \\\ncelt/pitch.c \\\ncelt/celt_lpc.c \\\ncelt/quant_bands.c \\\ncelt/rate.c \\\ncelt/vq.c\n\nCELT_SOURCES_SSE = celt/x86/x86cpu.c \\\ncelt/x86/x86_celt_map.c \\\ncelt/x86/pitch_sse.c\n\nCELT_SOURCES_SSE2 = celt/x86/pitch_sse2.c\n\nCELT_SOURCES_SSE4_1 = celt/x86/celt_lpc_sse.c \\\ncelt/x86/pitch_sse4_1.c\n\nCELT_SOURCES_ARM = \\\ncelt/arm/armcpu.c \\\ncelt/arm/arm_celt_map.c\n\nCELT_SOURCES_ARM_ASM = \\\ncelt/arm/celt_pitch_xcorr_arm.s\n\nCELT_AM_SOURCES_ARM_ASM = \\\ncelt/arm/armopts.s.in\n\nCELT_SOURCES_ARM_NEON_INTR = \\\ncelt/arm/celt_neon_intr.c\n\nCELT_SOURCES_ARM_NE10= \\\ncelt/arm/celt_ne10_fft.c \\\ncelt/arm/celt_ne10_mdct.c\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/configure.ac",
    "content": "dnl Process this file with autoconf to produce a configure script. -*-m4-*-\n\ndnl The package_version file will be automatically synced to the git revision\ndnl by the update_version script when configured in the repository, but will\ndnl remain constant in tarball releases unless it is manually edited.\nm4_define([CURRENT_VERSION],\n          m4_esyscmd([ ./update_version 2>/dev/null || true\n                       if test -e package_version; then\n                           . ./package_version\n                           printf \"$PACKAGE_VERSION\"\n                       else\n                           printf \"unknown\"\n                       fi ]))\n\nAC_INIT([opus],[CURRENT_VERSION],[opus@xiph.org])\n\nAC_CONFIG_SRCDIR(src/opus_encoder.c)\nAC_CONFIG_MACRO_DIR([m4])\n\ndnl enable silent rules on automake 1.11 and later\nm4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])\n\n# For libtool.\ndnl Please update these for releases.\nOPUS_LT_CURRENT=5\nOPUS_LT_REVISION=2\nOPUS_LT_AGE=5\n\nAC_SUBST(OPUS_LT_CURRENT)\nAC_SUBST(OPUS_LT_REVISION)\nAC_SUBST(OPUS_LT_AGE)\n\nAM_INIT_AUTOMAKE([no-define])\nAM_MAINTAINER_MODE([enable])\n\nAC_CANONICAL_HOST\nAC_MINGW32\nAM_PROG_LIBTOOL\nAM_PROG_CC_C_O\n\nAC_PROG_CC_C99\nAC_C_CONST\nAC_C_INLINE\n\nAM_PROG_AS\n\nAC_DEFINE([OPUS_BUILD], [], [This is a build of OPUS])\n\n#Use a hacked up version of autoconf's AC_C_RESTRICT because it's not\n#strong enough a test to detect old buggy versions of GCC (e.g. 2.95.3)\n#Note: Both this and the test for variable-size arrays below are also\n#      done by AC_PROG_CC_C99, but not thoroughly enough apparently.\nAC_CACHE_CHECK([for C/C++ restrict keyword], ac_cv_c_restrict,\n  [ac_cv_c_restrict=no\n   # The order here caters to the fact that C++ does not require restrict.\n   for ac_kw in __restrict __restrict__ _Restrict restrict; do\n     AC_COMPILE_IFELSE([AC_LANG_PROGRAM(\n      [[typedef int * int_ptr;\n        int foo (int_ptr $ac_kw ip, int * $ac_kw baz[]) {\n        return ip[0];\n       }]],\n      [[int s[1];\n        int * $ac_kw t = s;\n        t[0] = 0;\n        return foo(t, (void *)0)]])],\n      [ac_cv_c_restrict=$ac_kw])\n     test \"$ac_cv_c_restrict\" != no && break\n   done\n  ])\n\nAH_VERBATIM([restrict],\n[/* Define to the equivalent of the C99 'restrict' keyword, or to\n   nothing if this is not supported.  Do not define if restrict is\n   supported directly.  */\n#undef restrict\n/* Work around a bug in Sun C++: it does not support _Restrict or\n   __restrict__, even though the corresponding Sun C compiler ends up with\n   \"#define restrict _Restrict\" or \"#define restrict __restrict__\" in the\n   previous line.  Perhaps some future version of Sun C++ will work with\n   restrict; if so, hopefully it defines __RESTRICT like Sun C does.  */\n#if defined __SUNPRO_CC && !defined __RESTRICT\n# define _Restrict\n# define __restrict__\n#endif])\n\ncase $ac_cv_c_restrict in\n   restrict) ;;\n   no) AC_DEFINE([restrict], []) ;;\n   *)  AC_DEFINE_UNQUOTED([restrict], [$ac_cv_c_restrict]) ;;\nesac\n\nAC_MSG_CHECKING(for C99 variable-size arrays)\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM([],\n                   [[static int x; char a[++x]; a[sizeof a - 1] = 0; int N; return a[0];]])],\n    [ has_var_arrays=yes\n      use_alloca=\"no (using var arrays)\"\n      AC_DEFINE([VAR_ARRAYS], [1], [Use C99 variable-size arrays])\n    ],[\n      has_var_arrays=no\n    ])\nAC_MSG_RESULT([$has_var_arrays])\n\nAS_IF([test \"$has_var_arrays\" = \"no\"],\n  [\n   AC_CHECK_HEADERS([alloca.h])\n   AC_MSG_CHECKING(for alloca)\n   AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <alloca.h>]],\n                                      [[int foo=10; int *array = alloca(foo);]])],\n     [ use_alloca=yes;\n       AC_DEFINE([USE_ALLOCA], [], [Make use of alloca])\n     ],[\n       use_alloca=no\n     ])\n   AC_MSG_RESULT([$use_alloca])\n  ])\n\nLT_LIB_M\n\nAC_ARG_ENABLE([fixed-point],\n    [AS_HELP_STRING([--enable-fixed-point],\n                    [compile without floating point (for machines without a fast enough FPU)])],,\n    [enable_fixed_point=no])\n\nAS_IF([test \"$enable_fixed_point\" = \"yes\"],[\n  enable_float=\"no\"\n  AC_DEFINE([FIXED_POINT], [1], [Compile as fixed-point (for machines without a fast enough FPU)])\n  PC_BUILD=\"fixed-point\"\n],[\n  enable_float=\"yes\";\n  PC_BUILD=\"floating-point\"\n])\n\nAM_CONDITIONAL([FIXED_POINT], [test \"$enable_fixed_point\" = \"yes\"])\n\nAC_ARG_ENABLE([fixed-point-debug],\n    [AS_HELP_STRING([--enable-fixed-point-debug], [debug fixed-point implementation])],,\n    [enable_fixed_point_debug=no])\n\nAS_IF([test \"$enable_fixed_point_debug\" = \"yes\"],[\n  AC_DEFINE([FIXED_DEBUG], [1], [Debug fixed-point implementation])\n])\n\nAC_ARG_ENABLE([float_api],\n    [AS_HELP_STRING([--disable-float-api],\n                    [compile without the floating point API (for machines with no float library)])],,\n    [enable_float_api=yes])\n\nAM_CONDITIONAL([DISABLE_FLOAT_API], [test \"$enable_float_api\" = \"no\"])\n\nAS_IF([test \"$enable_float_api\" = \"no\"],[\n  AC_DEFINE([DISABLE_FLOAT_API], [1], [Do not build the float API])\n])\n\nAC_ARG_ENABLE([custom-modes],\n    [AS_HELP_STRING([--enable-custom-modes], [enable non-Opus modes, e.g. 44.1 kHz & 2^n frames])],,\n    [enable_custom_modes=no])\n\nAS_IF([test \"$enable_custom_modes\" = \"yes\"],[\n  AC_DEFINE([CUSTOM_MODES], [1], [Custom modes])\n  PC_BUILD=\"$PC_BUILD, custom modes\"\n])\n\nAM_CONDITIONAL([CUSTOM_MODES], [test \"$enable_custom_modes\" = \"yes\"])\n\nhas_float_approx=no\n#case \"$host_cpu\" in\n#i[[3456]]86 | x86_64 | powerpc64 | powerpc32 | ia64)\n#  has_float_approx=yes\n#  ;;\n#esac\n\nAC_ARG_ENABLE([float-approx],\n    [AS_HELP_STRING([--enable-float-approx], [enable fast approximations for floating point])],\n    [if test \"$enable_float_approx\" = \"yes\"; then\n       AC_WARN([Floating point approximations are not supported on all platforms.])\n     fi\n    ],\n    [enable_float_approx=$has_float_approx])\n\nAS_IF([test \"$enable_float_approx\" = \"yes\"],[\n  AC_DEFINE([FLOAT_APPROX], [1], [Float approximations])\n])\n\nAC_ARG_ENABLE([asm],\n    [AS_HELP_STRING([--disable-asm], [Disable assembly optimizations])],,\n    [enable_asm=yes])\n\nAC_ARG_ENABLE([rtcd],\n    [AS_HELP_STRING([--disable-rtcd], [Disable run-time CPU capabilities detection])],,\n    [enable_rtcd=yes])\n\nAC_ARG_ENABLE([intrinsics],\n    [AS_HELP_STRING([--enable-intrinsics], [Enable intrinsics optimizations for ARM(float) X86(fixed)])],,\n    [enable_intrinsics=no])\n\nrtcd_support=no\ncpu_arm=no\n\nAS_IF([test x\"${enable_asm}\" = x\"yes\"],[\n    inline_optimization=\"No inline ASM for your platform, please send patches\"\n    case $host_cpu in\n      arm*)\n        dnl Currently we only have asm for fixed-point\n        AS_IF([test \"$enable_float\" != \"yes\"],[\n            cpu_arm=yes\n            AC_DEFINE([OPUS_ARM_ASM], [],  [Make use of ARM asm optimization])\n            AS_GCC_INLINE_ASSEMBLY(\n                [inline_optimization=\"ARM\"],\n                [inline_optimization=\"disabled\"]\n            )\n            AS_ASM_ARM_EDSP([OPUS_ARM_INLINE_EDSP=1],[OPUS_ARM_INLINE_EDSP=0])\n            AS_ASM_ARM_MEDIA([OPUS_ARM_INLINE_MEDIA=1],\n                [OPUS_ARM_INLINE_MEDIA=0])\n            AS_ASM_ARM_NEON([OPUS_ARM_INLINE_NEON=1],[OPUS_ARM_INLINE_NEON=0])\n            AS_IF([test x\"$inline_optimization\" = x\"ARM\"],[\n                AM_CONDITIONAL([OPUS_ARM_INLINE_ASM],[true])\n                AC_DEFINE([OPUS_ARM_INLINE_ASM], 1,\n                    [Use generic ARMv4 inline asm optimizations])\n                AS_IF([test x\"$OPUS_ARM_INLINE_EDSP\" = x\"1\"],[\n                    AC_DEFINE([OPUS_ARM_INLINE_EDSP], [1],\n                        [Use ARMv5E inline asm optimizations])\n                    inline_optimization=\"$inline_optimization (EDSP)\"\n                ])\n                AS_IF([test x\"$OPUS_ARM_INLINE_MEDIA\" = x\"1\"],[\n                    AC_DEFINE([OPUS_ARM_INLINE_MEDIA], [1],\n                        [Use ARMv6 inline asm optimizations])\n                    inline_optimization=\"$inline_optimization (Media)\"\n                ])\n                AS_IF([test x\"$OPUS_ARM_INLINE_NEON\" = x\"1\"],[\n                    AC_DEFINE([OPUS_ARM_INLINE_NEON], 1,\n                        [Use ARM NEON inline asm optimizations])\n                    inline_optimization=\"$inline_optimization (NEON)\"\n                ])\n            ])\n            dnl We need Perl to translate RVCT-syntax asm to gas syntax.\n            AC_CHECK_PROG([HAVE_PERL], perl, yes, no)\n            AS_IF([test x\"$HAVE_PERL\" = x\"yes\"],[\n                AM_CONDITIONAL([OPUS_ARM_EXTERNAL_ASM],[true])\n                asm_optimization=\"ARM\"\n                AS_IF([test x\"$OPUS_ARM_INLINE_EDSP\" = x\"1\"], [\n                    OPUS_ARM_PRESUME_EDSP=1\n                    OPUS_ARM_MAY_HAVE_EDSP=1\n                ],\n                [\n                    OPUS_ARM_PRESUME_EDSP=0\n                    OPUS_ARM_MAY_HAVE_EDSP=0\n                ])\n                AS_IF([test x\"$OPUS_ARM_INLINE_MEDIA\" = x\"1\"], [\n                    OPUS_ARM_PRESUME_MEDIA=1\n                    OPUS_ARM_MAY_HAVE_MEDIA=1\n                ],\n                [\n                    OPUS_ARM_PRESUME_MEDIA=0\n                    OPUS_ARM_MAY_HAVE_MEDIA=0\n                ])\n                AS_IF([test x\"$OPUS_ARM_INLINE_NEON\" = x\"1\"], [\n                    OPUS_ARM_PRESUME_NEON=1\n                    OPUS_ARM_MAY_HAVE_NEON=1\n                ],\n                [\n                    OPUS_ARM_PRESUME_NEON=0\n                    OPUS_ARM_MAY_HAVE_NEON=0\n                ])\n                AS_IF([test x\"$enable_rtcd\" = x\"yes\"],[\n                    AS_IF([test x\"$OPUS_ARM_MAY_HAVE_EDSP\" != x\"1\"],[\n                        AC_MSG_NOTICE(\n                          [Trying to force-enable armv5e EDSP instructions...])\n                        AS_ASM_ARM_EDSP_FORCE([OPUS_ARM_MAY_HAVE_EDSP=1])\n                    ])\n                    AS_IF([test x\"$OPUS_ARM_MAY_HAVE_MEDIA\" != x\"1\"],[\n                        AC_MSG_NOTICE(\n                          [Trying to force-enable ARMv6 media instructions...])\n                        AS_ASM_ARM_MEDIA_FORCE([OPUS_ARM_MAY_HAVE_MEDIA=1])\n                    ])\n                    AS_IF([test x\"$OPUS_ARM_MAY_HAVE_NEON\" != x\"1\"],[\n                        AC_MSG_NOTICE(\n                          [Trying to force-enable NEON instructions...])\n                        AS_ASM_ARM_NEON_FORCE([OPUS_ARM_MAY_HAVE_NEON=1])\n                    ])\n                ])\n                rtcd_support=\n                AS_IF([test x\"$OPUS_ARM_MAY_HAVE_EDSP\" = x\"1\"],[\n                    AC_DEFINE(OPUS_ARM_MAY_HAVE_EDSP, 1,\n                        [Define if assembler supports EDSP instructions])\n                    AS_IF([test x\"$OPUS_ARM_PRESUME_EDSP\" = x\"1\"],[\n                        AC_DEFINE(OPUS_ARM_PRESUME_EDSP, 1,\n                          [Define if binary requires EDSP instruction support])\n                        asm_optimization=\"$asm_optimization (EDSP)\"\n                    ],\n                        [rtcd_support=\"$rtcd_support (EDSP)\"]\n                    )\n                ])\n                AC_SUBST(OPUS_ARM_MAY_HAVE_EDSP)\n                AS_IF([test x\"$OPUS_ARM_MAY_HAVE_MEDIA\" = x\"1\"],[\n                    AC_DEFINE(OPUS_ARM_MAY_HAVE_MEDIA, 1,\n                      [Define if assembler supports ARMv6 media instructions])\n                    AS_IF([test x\"$OPUS_ARM_PRESUME_MEDIA\" = x\"1\"],[\n                        AC_DEFINE(OPUS_ARM_PRESUME_MEDIA, 1,\n                          [Define if binary requires ARMv6 media instruction support])\n                        asm_optimization=\"$asm_optimization (Media)\"\n                    ],\n                        [rtcd_support=\"$rtcd_support (Media)\"]\n                    )\n                ])\n                AC_SUBST(OPUS_ARM_MAY_HAVE_MEDIA)\n                AS_IF([test x\"$OPUS_ARM_MAY_HAVE_NEON\" = x\"1\"],[\n                    AC_DEFINE(OPUS_ARM_MAY_HAVE_NEON, 1,\n                      [Define if compiler supports NEON instructions])\n                    AS_IF([test x\"$OPUS_ARM_PRESUME_NEON\" = x\"1\"], [\n                        AC_DEFINE(OPUS_ARM_PRESUME_NEON, 1,\n                          [Define if binary requires NEON instruction support])\n                        asm_optimization=\"$asm_optimization (NEON)\"\n                    ],\n                        [rtcd_support=\"$rtcd_support (NEON)\"]\n                    )\n                ])\n                AC_SUBST(OPUS_ARM_MAY_HAVE_NEON)\n                dnl Make sure turning on RTCD gets us at least one\n                dnl instruction set.\n                AS_IF([test x\"$rtcd_support\" != x\"\"],\n                    [rtcd_support=ARM\"$rtcd_support\"],\n                    [rtcd_support=\"no\"]\n                )\n                AC_MSG_CHECKING([for apple style tools])\n                AC_PREPROC_IFELSE([AC_LANG_PROGRAM([\n#ifndef __APPLE__\n#error 1\n#endif],[])],\n                    [AC_MSG_RESULT([yes]); ARM2GNU_PARAMS=\"--apple\"],\n                    [AC_MSG_RESULT([no]); ARM2GNU_PARAMS=\"\"])\n                AC_SUBST(ARM2GNU_PARAMS)\n            ],\n            [\n                AC_MSG_WARN(\n                  [*** ARM assembly requires perl -- disabling optimizations])\n                asm_optimization=\"(missing perl dependency for ARM)\"\n            ])\n        ])\n        ;;\n    esac\n],[\n   inline_optimization=\"disabled\"\n   asm_optimization=\"disabled\"\n])\n\nAM_CONDITIONAL([OPUS_ARM_INLINE_ASM],\n    [test x\"${inline_optimization%% *}\" = x\"ARM\"])\nAM_CONDITIONAL([OPUS_ARM_EXTERNAL_ASM],\n    [test x\"${asm_optimization%% *}\" = x\"ARM\"])\n\nAM_CONDITIONAL([HAVE_SSE], [false])\nAM_CONDITIONAL([HAVE_SSE2], [false])\nAM_CONDITIONAL([HAVE_SSE4_1], [false])\nAM_CONDITIONAL([HAVE_AVX], [false])\n\nm4_define([DEFAULT_X86_SSE_CFLAGS], [-msse])\nm4_define([DEFAULT_X86_SSE2_CFLAGS], [-msse2])\nm4_define([DEFAULT_X86_SSE4_1_CFLAGS], [-msse4.1])\nm4_define([DEFAULT_X86_AVX_CFLAGS], [-mavx])\nm4_define([DEFAULT_ARM_NEON_INTR_CFLAGS], [-mfpu=neon])\n# With GCC on ARM32 softfp architectures (e.g. Android, or older Ubuntu) you need to specify\n# -mfloat-abi=softfp for -mfpu=neon to work.  However, on ARM32 hardfp architectures (e.g. newer Ubuntu),\n# this option will break things.\n\n# As a heuristic, if host matches arm*eabi* but not arm*hf*, it's probably soft-float.\nm4_define([DEFAULT_ARM_NEON_SOFTFP_INTR_CFLAGS], [-mfpu=neon -mfloat-abi=softfp])\n\nAS_CASE([$host],\n\t[arm*hf*], [AS_VAR_SET([RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS], \"DEFAULT_ARM_NEON_INTR_CFLAGS\")],\n\t[arm*eabi*], [AS_VAR_SET([RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS], \"DEFAULT_ARM_NEON_SOFTFP_INTR_CFLAGS\")],\n\t[AS_VAR_SET([RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS], \"DEFAULT_ARM_NEON_INTR_CFLAGS\")])\n\nAC_ARG_VAR([X86_SSE_CFLAGS], [C compiler flags to compile SSE intrinsics @<:@default=]DEFAULT_X86_SSE_CFLAGS[@:>@])\nAC_ARG_VAR([X86_SSE2_CFLAGS], [C compiler flags to compile SSE2 intrinsics @<:@default=]DEFAULT_X86_SSE2_CFLAGS[@:>@])\nAC_ARG_VAR([X86_SSE4_1_CFLAGS], [C compiler flags to compile SSE4.1 intrinsics @<:@default=]DEFAULT_X86_SSE4_1_CFLAGS[@:>@])\nAC_ARG_VAR([X86_AVX_CFLAGS], [C compiler flags to compile AVX intrinsics @<:@default=]DEFAULT_X86_AVX_CFLAGS[@:>@])\nAC_ARG_VAR([ARM_NEON_INTR_CFLAGS], [C compiler flags to compile ARM NEON intrinsics @<:@default=]DEFAULT_ARM_NEON_INTR_CFLAGS / DEFAULT_ARM_NEON_SOFTFP_INTR_CFLAGS[@:>@])\n\nAS_VAR_SET_IF([X86_SSE_CFLAGS], [], [AS_VAR_SET([X86_SSE_CFLAGS], \"DEFAULT_X86_SSE_CFLAGS\")])\nAS_VAR_SET_IF([X86_SSE2_CFLAGS], [], [AS_VAR_SET([X86_SSE2_CFLAGS], \"DEFAULT_X86_SSE2_CFLAGS\")])\nAS_VAR_SET_IF([X86_SSE4_1_CFLAGS], [], [AS_VAR_SET([X86_SSE4_1_CFLAGS], \"DEFAULT_X86_SSE4_1_CFLAGS\")])\nAS_VAR_SET_IF([X86_AVX_CFLAGS], [], [AS_VAR_SET([X86_AVX_CFLAGS], \"DEFAULT_X86_AVX_CFLAGS\")])\nAS_VAR_SET_IF([ARM_NEON_INTR_CFLAGS], [], [AS_VAR_SET([ARM_NEON_INTR_CFLAGS], [\"$RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS\"])])\n\nAC_DEFUN([OPUS_PATH_NE10],\n   [\n      AC_ARG_WITH(NE10,\n                  AC_HELP_STRING([--with-NE10=PFX],[Prefix where libNE10 is installed (optional)]),\n                  NE10_prefix=\"$withval\", NE10_prefix=\"\")\n      AC_ARG_WITH(NE10-libraries,\n                  AC_HELP_STRING([--with-NE10-libraries=DIR],\n                        [Directory where libNE10 library is installed (optional)]),\n                  NE10_libraries=\"$withval\", NE10_libraries=\"\")\n      AC_ARG_WITH(NE10-includes,\n                  AC_HELP_STRING([--with-NE10-includes=DIR],\n                                 [Directory where libNE10 header files are installed (optional)]),\n                  NE10_includes=\"$withval\", NE10_includes=\"\")\n\n      if test \"x$NE10_libraries\" != \"x\" ; then\n         NE10_LIBS=\"-L$NE10_libraries\"\n      elif test \"x$NE10_prefix\" = \"xno\" || test \"x$NE10_prefix\" = \"xyes\" ; then\n         NE10_LIBS=\"\"\n      elif test \"x$NE10_prefix\" != \"x\" ; then\n         NE10_LIBS=\"-L$NE10_prefix/lib\"\n      elif test \"x$prefix\" != \"xNONE\" ; then\n         NE10_LIBS=\"-L$prefix/lib\"\n      fi\n\n      if test \"x$NE10_prefix\" != \"xno\" ; then\n         NE10_LIBS=\"$NE10_LIBS -lNE10\"\n      fi\n\n      if test \"x$NE10_includes\" != \"x\" ; then\n         NE10_CFLAGS=\"-I$NE10_includes\"\n      elif test \"x$NE10_prefix\" = \"xno\" || test \"x$NE10_prefix\" = \"xyes\" ; then\n         NE10_CFLAGS=\"\"\n      elif test \"x$ogg_prefix\" != \"x\" ; then\n         NE10_CFLAGS=\"-I$NE10_prefix/include\"\n      elif test \"x$prefix\" != \"xNONE\"; then\n         NE10_CFLAGS=\"-I$prefix/include\"\n      fi\n\n      AC_MSG_CHECKING(for NE10)\n      save_CFLAGS=\"$CFLAGS\"; CFLAGS=\"$NE10_CFLAGS\"\n      save_LIBS=\"$LIBS\"; LIBS=\"$NE10_LIBS $LIBM\"\n      AC_LINK_IFELSE(\n         [\n            AC_LANG_PROGRAM(\n               [[#include <NE10_init.h>\n               ]],\n               [[\n                  ne10_fft_cfg_float32_t cfg;\n                  cfg = ne10_fft_alloc_c2c_float32_neon(480);\n               ]]\n            )\n         ],[\n            HAVE_ARM_NE10=1\n            AC_MSG_RESULT([yes])\n         ],[\n            HAVE_ARM_NE10=0\n            AC_MSG_RESULT([no])\n            NE10_CFLAGS=\"\"\n            NE10_LIBS=\"\"\n         ]\n      )\n      CFLAGS=\"$save_CFLAGS\"; LIBS=\"$save_LIBS\"\n      #Now we know if libNE10 is installed or not\n      AS_IF([test x\"$HAVE_ARM_NE10\" = x\"1\"],\n         [\n            AC_DEFINE([HAVE_ARM_NE10], 1, [NE10 library is installed on host. Make sure it is on target!])\n            AC_SUBST(HAVE_ARM_NE10)\n            AC_SUBST(NE10_CFLAGS)\n            AC_SUBST(NE10_LIBS)\n         ]\n      )\n   ]\n)\n\nAS_IF([test x\"$enable_intrinsics\" = x\"yes\"],[\n   intrinsics_support=\"\"\n   AS_CASE([$host_cpu],\n   [arm*],\n   [\n      cpu_arm=yes\n      OPUS_CHECK_INTRINSICS(\n         [ARM Neon],\n         [$ARM_NEON_INTR_CFLAGS],\n         [OPUS_ARM_MAY_HAVE_NEON_INTR],\n         [OPUS_ARM_PRESUME_NEON_INTR],\n         [[#include <arm_neon.h>\n         ]],\n         [[\n            static float32x4_t A0, A1, SUMM;\n            SUMM = vmlaq_f32(SUMM, A0, A1);\n         ]]\n      )\n      AS_IF([test x\"$OPUS_ARM_MAY_HAVE_NEON_INTR\" = x\"1\" && test x\"$OPUS_ARM_PRESUME_NEON_INTR\" != x\"1\"],\n          [\n             OPUS_ARM_NEON_INTR_CFLAGS=\"$ARM_NEON_INTR_CFLAGS\"\n             AC_SUBST([OPUS_ARM_NEON_INTR_CFLAGS])\n          ]\n      )\n\n      AS_IF([test x\"$OPUS_ARM_MAY_HAVE_NEON_INTR\" = x\"1\"],\n      [\n         AC_DEFINE([OPUS_ARM_MAY_HAVE_NEON_INTR], 1, [Compiler supports ARMv7 Neon Intrinsics])\n         intrinsics_support=\"$intrinsics_support (Neon_Intrinsics)\"\n\n         AS_IF([test x\"enable_rtcd\" != x\"\" && test x\"$OPUS_ARM_PRESUME_NEON_INTR\" != x\"1\"],\n            [rtcd_support=\"$rtcd_support (ARMv7_Neon_Intrinsics)\"])\n\n         AS_IF([test x\"$OPUS_ARM_PRESUME_NEON_INTR\" = x\"1\"],\n            [AC_DEFINE([OPUS_ARM_PRESUME_NEON_INTR], 1, [Define if binary requires NEON intrinsics support])])\n\n         OPUS_PATH_NE10()\n         AS_IF([test x\"$NE10_LIBS\" != x\"\"],\n         [\n              intrinsics_support=\"$intrinsics_support (NE10)\"\n              AS_IF([test x\"enable_rtcd\" != x\"\" \\\n               && test x\"$OPUS_ARM_PRESUME_NEON_INTR\" != x\"1\"],\n                 [rtcd_support=\"$rtcd_support (NE10)\"])\n         ])\n\n         AS_IF([test x\"$rtcd_support\" = x\"\"],\n            [rtcd_support=no])\n\n         AS_IF([test x\"$intrinsics_support\" = x\"\"],\n            [intrinsics_support=no],\n            [intrinsics_support=\"arm$intrinsics_support\"])\n      ],\n      [\n         AC_MSG_WARN([Compiler does not support ARM intrinsics])\n         intrinsics_support=no\n      ])\n   ],\n   [i?86|x86_64],\n   [\n      OPUS_CHECK_INTRINSICS(\n         [SSE],\n         [$X86_SSE_CFLAGS],\n         [OPUS_X86_MAY_HAVE_SSE],\n         [OPUS_X86_PRESUME_SSE],\n         [[#include <xmmintrin.h>\n         ]],\n         [[\n             static __m128 mtest;\n             mtest = _mm_setzero_ps();\n         ]]\n      )\n      AS_IF([test x\"$OPUS_X86_MAY_HAVE_SSE\" = x\"1\" && test x\"$OPUS_X86_PRESUME_SSE\" != x\"1\"],\n          [\n             OPUS_X86_SSE_CFLAGS=\"$X86_SSE_CFLAGS\"\n             AC_SUBST([OPUS_X86_SSE_CFLAGS])\n          ]\n      )\n      OPUS_CHECK_INTRINSICS(\n         [SSE2],\n         [$X86_SSE2_CFLAGS],\n         [OPUS_X86_MAY_HAVE_SSE2],\n         [OPUS_X86_PRESUME_SSE2],\n         [[#include <emmintrin.h>\n         ]],\n         [[\n             static __m128i mtest;\n             mtest = _mm_setzero_si128();\n         ]]\n      )\n      AS_IF([test x\"$OPUS_X86_MAY_HAVE_SSE2\" = x\"1\" && test x\"$OPUS_X86_PRESUME_SSE2\" != x\"1\"],\n          [\n             OPUS_X86_SSE2_CFLAGS=\"$X86_SSE2_CFLAGS\"\n             AC_SUBST([OPUS_X86_SSE2_CFLAGS])\n          ]\n      )\n      OPUS_CHECK_INTRINSICS(\n         [SSE4.1],\n         [$X86_SSE4_1_CFLAGS],\n         [OPUS_X86_MAY_HAVE_SSE4_1],\n         [OPUS_X86_PRESUME_SSE4_1],\n         [[#include <smmintrin.h>\n         ]],\n         [[\n            static __m128i mtest;\n            mtest = _mm_setzero_si128();\n            mtest = _mm_cmpeq_epi64(mtest, mtest);\n         ]]\n      )\n      AS_IF([test x\"$OPUS_X86_MAY_HAVE_SSE4_1\" = x\"1\" && test x\"$OPUS_X86_PRESUME_SSE4_1\" != x\"1\"],\n          [\n             OPUS_X86_SSE4_1_CFLAGS=\"$X86_SSE4_1_CFLAGS\"\n             AC_SUBST([OPUS_X86_SSE4_1_CFLAGS])\n          ]\n      )\n      OPUS_CHECK_INTRINSICS(\n         [AVX],\n         [$X86_AVX_CFLAGS],\n         [OPUS_X86_MAY_HAVE_AVX],\n         [OPUS_X86_PRESUME_AVX],\n         [[#include <immintrin.h>\n         ]],\n         [[\n            static __m256 mtest;\n            mtest = _mm256_setzero_ps();\n         ]]\n      )\n      AS_IF([test x\"$OPUS_X86_MAY_HAVE_AVX\" = x\"1\" && test x\"$OPUS_X86_PRESUME_AVX\" != x\"1\"],\n          [\n             OPUS_X86_AVX_CFLAGS=\"$X86_AVX_CFLAGS\"\n             AC_SUBST([OPUS_X86_AVX_CFLAGS])\n          ]\n      )\n         AS_IF([test x\"$rtcd_support\" = x\"no\"], [rtcd_support=\"\"])\n         AS_IF([test x\"$OPUS_X86_MAY_HAVE_SSE\" = x\"1\"],\n         [\n            AC_DEFINE([OPUS_X86_MAY_HAVE_SSE], 1, [Compiler supports X86 SSE Intrinsics])\n            intrinsics_support=\"$intrinsics_support SSE\"\n\n            AS_IF([test x\"$OPUS_X86_PRESUME_SSE\" = x\"1\"],\n               [AC_DEFINE([OPUS_X86_PRESUME_SSE], 1, [Define if binary requires SSE intrinsics support])],\n               [rtcd_support=\"$rtcd_support SSE\"])\n         ],\n         [\n            AC_MSG_WARN([Compiler does not support SSE intrinsics])\n         ])\n\n         AS_IF([test x\"$OPUS_X86_MAY_HAVE_SSE2\" = x\"1\"],\n         [\n            AC_DEFINE([OPUS_X86_MAY_HAVE_SSE2], 1, [Compiler supports X86 SSE2 Intrinsics])\n            intrinsics_support=\"$intrinsics_support SSE2\"\n\n            AS_IF([test x\"$OPUS_X86_PRESUME_SSE2\" = x\"1\"],\n               [AC_DEFINE([OPUS_X86_PRESUME_SSE2], 1, [Define if binary requires SSE2 intrinsics support])],\n               [rtcd_support=\"$rtcd_support SSE2\"])\n         ],\n         [\n            AC_MSG_WARN([Compiler does not support SSE2 intrinsics])\n         ])\n\n         AS_IF([test x\"$OPUS_X86_MAY_HAVE_SSE4_1\" = x\"1\"],\n         [\n            AC_DEFINE([OPUS_X86_MAY_HAVE_SSE4_1], 1, [Compiler supports X86 SSE4.1 Intrinsics])\n            intrinsics_support=\"$intrinsics_support SSE4.1\"\n\n            AS_IF([test x\"$OPUS_X86_PRESUME_SSE4_1\" = x\"1\"],\n               [AC_DEFINE([OPUS_X86_PRESUME_SSE4_1], 1, [Define if binary requires SSE4.1 intrinsics support])],\n               [rtcd_support=\"$rtcd_support SSE4.1\"])\n         ],\n         [\n            AC_MSG_WARN([Compiler does not support SSE4.1 intrinsics])\n         ])\n         AS_IF([test x\"$OPUS_X86_MAY_HAVE_AVX\" = x\"1\"],\n         [\n            AC_DEFINE([OPUS_X86_MAY_HAVE_AVX], 1, [Compiler supports X86 AVX Intrinsics])\n            intrinsics_support=\"$intrinsics_support AVX\"\n\n            AS_IF([test x\"$OPUS_X86_PRESUME_AVX\" = x\"1\"],\n               [AC_DEFINE([OPUS_X86_PRESUME_AVX], 1, [Define if binary requires AVX intrinsics support])],\n               [rtcd_support=\"$rtcd_support AVX\"])\n         ],\n         [\n            AC_MSG_WARN([Compiler does not support AVX intrinsics])\n         ])\n\n         AS_IF([test x\"$intrinsics_support\" = x\"\"],\n            [intrinsics_support=no],\n            [intrinsics_support=\"x86$intrinsics_support\"]\n         )\n         AS_IF([test x\"$rtcd_support\" = x\"\"],\n            [rtcd_support=no],\n            [rtcd_support=\"x86$rtcd_support\"],\n        )\n\n    AS_IF([test x\"$enable_rtcd\" = x\"yes\" && test x\"$rtcd_support\" != x\"\"],[\n            get_cpuid_by_asm=\"no\"\n            AC_MSG_CHECKING([How to get X86 CPU Info])\n            AC_LINK_IFELSE([AC_LANG_PROGRAM([[\n                 #include <stdio.h>\n            ]],[[\n                 unsigned int CPUInfo0;\n                 unsigned int CPUInfo1;\n                 unsigned int CPUInfo2;\n                 unsigned int CPUInfo3;\n                 unsigned int InfoType;\n                 __asm__ __volatile__ (\n                 \"cpuid\":\n                 \"=a\" (CPUInfo0),\n                 \"=b\" (CPUInfo1),\n                 \"=c\" (CPUInfo2),\n                 \"=d\" (CPUInfo3) :\n                 \"a\" (InfoType), \"c\" (0)\n                );\n            ]])],\n            [get_cpuid_by_asm=\"yes\"\n             AC_MSG_RESULT([Inline Assembly])\n\t\t\t AC_DEFINE([CPU_INFO_BY_ASM], [1], [Get CPU Info by asm method])],\n             [AC_LINK_IFELSE([AC_LANG_PROGRAM([[\n                 #include <cpuid.h>\n            ]],[[\n                 unsigned int CPUInfo0;\n                 unsigned int CPUInfo1;\n                 unsigned int CPUInfo2;\n                 unsigned int CPUInfo3;\n                 unsigned int InfoType;\n                 __get_cpuid(InfoType, &CPUInfo0, &CPUInfo1, &CPUInfo2, &CPUInfo3);\n            ]])],\n            [AC_MSG_RESULT([C method])\n\t\t\t AC_DEFINE([CPU_INFO_BY_C], [1], [Get CPU Info by c method])],\n            [AC_MSG_ERROR([no supported Get CPU Info method, please disable intrinsics])])])])\n   ],\n   [\n      AC_MSG_WARN([No intrinsics support for your architecture])\n      intrinsics_support=\"no\"\n   ])\n],\n[\n   intrinsics_support=\"no\"\n])\n\nAM_CONDITIONAL([CPU_ARM], [test \"$cpu_arm\" = \"yes\"])\nAM_CONDITIONAL([OPUS_ARM_NEON_INTR],\n    [test x\"$OPUS_ARM_MAY_HAVE_NEON_INTR\" = x\"1\"])\nAM_CONDITIONAL([HAVE_ARM_NE10],\n    [test x\"$HAVE_ARM_NE10\" = x\"1\"])\nAM_CONDITIONAL([HAVE_SSE],\n    [test x\"$OPUS_X86_MAY_HAVE_SSE\" = x\"1\"])\nAM_CONDITIONAL([HAVE_SSE2],\n    [test x\"$OPUS_X86_MAY_HAVE_SSE2\" = x\"1\"])\nAM_CONDITIONAL([HAVE_SSE4_1],\n    [test x\"$OPUS_X86_MAY_HAVE_SSE4_1\" = x\"1\"])\nAM_CONDITIONAL([HAVE_AVX],\n    [test x\"$OPUS_X86_MAY_HAVE_AVX\" = x\"1\"])\n\nAS_IF([test x\"$enable_rtcd\" = x\"yes\"],[\n    AS_IF([test x\"$rtcd_support\" != x\"no\"],[\n        AC_DEFINE([OPUS_HAVE_RTCD], [1],\n            [Use run-time CPU capabilities detection])\n        OPUS_HAVE_RTCD=1\n        AC_SUBST(OPUS_HAVE_RTCD)\n    ])\n],[\n    rtcd_support=\"disabled\"\n])\n\nAC_ARG_ENABLE([assertions],\n    [AS_HELP_STRING([--enable-assertions],[enable additional software error checking])],,\n    [enable_assertions=no])\n\nAS_IF([test \"$enable_assertions\" = \"yes\"], [\n  AC_DEFINE([ENABLE_ASSERTIONS], [1], [Assertions])\n])\n\nAC_ARG_ENABLE([fuzzing],\n    [AS_HELP_STRING([--enable-fuzzing],[causes the encoder to make random decisions])],,\n    [enable_fuzzing=no])\n\nAS_IF([test \"$enable_fuzzing\" = \"yes\"], [\n  AC_DEFINE([FUZZING], [1], [Fuzzing])\n])\n\nAC_ARG_ENABLE([doc],\n    [AS_HELP_STRING([--disable-doc], [Do not build API documentation])],,\n    [enable_doc=yes])\n\nAS_IF([test \"$enable_doc\" = \"yes\"], [\n  AC_CHECK_PROG(HAVE_DOXYGEN, [doxygen], [yes], [no])\n],[\n  HAVE_DOXYGEN=no\n])\n\nAM_CONDITIONAL([HAVE_DOXYGEN], [test \"$HAVE_DOXYGEN\" = \"yes\"])\n\nAC_ARG_ENABLE([extra-programs],\n    [AS_HELP_STRING([--disable-extra-programs], [Do not build extra programs (demo and tests)])],,\n    [enable_extra_programs=yes])\n\nAM_CONDITIONAL([EXTRA_PROGRAMS], [test \"$enable_extra_programs\" = \"yes\"])\n\n\nsaved_CFLAGS=\"$CFLAGS\"\nCFLAGS=\"$CFLAGS -fvisibility=hidden\"\nAC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden])\nAC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])],\n    [ AC_MSG_RESULT([yes]) ],\n    [ AC_MSG_RESULT([no])\n      CFLAGS=\"$saved_CFLAGS\"\n    ])\n\nCFLAGS=\"$CFLAGS -W\"\n\nwarn_CFLAGS=\"-Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes\"\nsaved_CFLAGS=\"$CFLAGS\"\nCFLAGS=\"$CFLAGS $warn_CFLAGS\"\nAC_MSG_CHECKING([if ${CC} supports ${warn_CFLAGS}])\nAC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])],\n    [ AC_MSG_RESULT([yes]) ],\n    [ AC_MSG_RESULT([no])\n      CFLAGS=\"$saved_CFLAGS\"\n    ])\n\nsaved_LIBS=\"$LIBS\"\nLIBS=\"$LIBS $LIBM\"\nAC_CHECK_FUNCS([lrintf])\nAC_CHECK_FUNCS([lrint])\nLIBS=\"$saved_LIBS\"\n\nAC_CHECK_FUNCS([__malloc_hook])\n\nAC_SUBST([PC_BUILD])\n\nAC_CONFIG_FILES([\n    Makefile\n    opus.pc\n    opus-uninstalled.pc\n    celt/arm/armopts.s\n    doc/Makefile\n    doc/Doxyfile\n])\nAC_CONFIG_HEADERS([config.h])\n\nAC_OUTPUT\n\nAC_MSG_NOTICE([\n------------------------------------------------------------------------\n  $PACKAGE_NAME $PACKAGE_VERSION:  Automatic configuration OK.\n\n    Compiler support:\n\n      C99 var arrays: ................ ${has_var_arrays}\n      C99 lrintf: .................... ${ac_cv_func_lrintf}\n      Use alloca: .................... ${use_alloca}\n\n    General configuration:\n\n      Floating point support: ........ ${enable_float}\n      Fast float approximations: ..... ${enable_float_approx}\n      Fixed point debugging: ......... ${enable_fixed_point_debug}\n      Inline Assembly Optimizations: . ${inline_optimization}\n      External Assembly Optimizations: ${asm_optimization}\n      Intrinsics Optimizations.......: ${intrinsics_support}\n      Run-time CPU detection: ........ ${rtcd_support}\n      Custom modes: .................. ${enable_custom_modes}\n      Assertion checking: ............ ${enable_assertions}\n      Fuzzing: ....................... ${enable_fuzzing}\n\n      API documentation: ............. ${enable_doc}\n      Extra programs: ................ ${enable_extra_programs}\n------------------------------------------------------------------------\n\n Type \"make; make install\" to compile and install\n Type \"make check\" to run the test suite\n])\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/doc/Doxyfile.in",
    "content": "# Doxyfile 1.7.4\n\n# This file describes the settings to be used by the documentation system\n# doxygen (www.doxygen.org) for a project.\n#\n# All text after a hash (#) is considered a comment and will be ignored.\n# The format is:\n#       TAG = value [value, ...]\n# For lists items can also be appended using:\n#       TAG += value [value, ...]\n# Values that contain spaces should be placed between quotes (\" \").\n\n#---------------------------------------------------------------------------\n# Project related configuration options\n#---------------------------------------------------------------------------\n\n# This tag specifies the encoding used for all characters in the config file\n# that follow. The default is UTF-8 which is also the encoding used for all\n# text before the first occurrence of this tag. Doxygen uses libiconv (or the\n# iconv built into libc) for the transcoding. See\n# http://www.gnu.org/software/libiconv for the list of possible encodings.\n\nDOXYFILE_ENCODING      = UTF-8\n\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded\n# by quotes) that should identify the project.\n\nPROJECT_NAME           = Opus\n\n# The PROJECT_NUMBER tag can be used to enter a project or revision number.\n# This could be handy for archiving the generated documentation or\n# if some version control system is used.\n\nPROJECT_NUMBER         = @VERSION@\n\n# Using the PROJECT_BRIEF tag one can provide an optional one line description\n# for a project that appears at the top of each page and should give viewer\n# a quick idea about the purpose of the project. Keep the description short.\n\nPROJECT_BRIEF          = \"Opus audio codec (RFC 6716): API and operations manual\"\n\n# With the PROJECT_LOGO tag one can specify an logo or icon that is\n# included in the documentation. The maximum height of the logo should not\n# exceed 55 pixels and the maximum width should not exceed 200 pixels.\n# Doxygen will copy the logo to the output directory.\n\nPROJECT_LOGO           =\n\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)\n# base path where the generated documentation will be put.\n# If a relative path is entered, it will be relative to the location\n# where doxygen was started. If left blank the current directory will be used.\n\nOUTPUT_DIRECTORY       =\n\n# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create\n# 4096 sub-directories (in 2 levels) under the output directory of each output\n# format and will distribute the generated files over these directories.\n# Enabling this option can be useful when feeding doxygen a huge amount of\n# source files, where putting all generated files in the same directory would\n# otherwise cause performance problems for the file system.\n\nCREATE_SUBDIRS         = NO\n\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all\n# documentation generated by doxygen is written. Doxygen will use this\n# information to generate all constant output in the proper language.\n# The default language is English, other supported languages are:\n# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,\n# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,\n# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English\n# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,\n# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,\n# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.\n\nOUTPUT_LANGUAGE        = English\n\n# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will\n# include brief member descriptions after the members that are listed in\n# the file and class documentation (similar to JavaDoc).\n# Set to NO to disable this.\n\nBRIEF_MEMBER_DESC      = YES\n\n# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend\n# the brief description of a member or function before the detailed description.\n# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the\n# brief descriptions will be completely suppressed.\n\nREPEAT_BRIEF           = YES\n\n# This tag implements a quasi-intelligent brief description abbreviator\n# that is used to form the text in various listings. Each string\n# in this list, if found as the leading text of the brief description, will be\n# stripped from the text and the result after processing the whole list, is\n# used as the annotated text. Otherwise, the brief description is used as-is.\n# If left blank, the following values are used (\"$name\" is automatically\n# replaced with the name of the entity): \"The $name class\" \"The $name widget\"\n# \"The $name file\" \"is\" \"provides\" \"specifies\" \"contains\"\n# \"represents\" \"a\" \"an\" \"the\"\n\nABBREVIATE_BRIEF       =\n\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then\n# Doxygen will generate a detailed section even if there is only a brief\n# description.\n\nALWAYS_DETAILED_SEC    = NO\n\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all\n# inherited members of a class in the documentation of that class as if those\n# members were ordinary class members. Constructors, destructors and assignment\n# operators of the base classes will not be shown.\n\nINLINE_INHERITED_MEMB  = NO\n\n# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full\n# path before files name in the file list and in the header files. If set\n# to NO the shortest path that makes the file name unique will be used.\n\nFULL_PATH_NAMES        = NO\n\n# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag\n# can be used to strip a user-defined part of the path. Stripping is\n# only done if one of the specified strings matches the left-hand part of\n# the path. The tag can be used to show relative paths in the file list.\n# If left blank the directory from which doxygen is run is used as the\n# path to strip.\n\nSTRIP_FROM_PATH        =\n\n# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of\n# the path mentioned in the documentation of a class, which tells\n# the reader which header file to include in order to use a class.\n# If left blank only the name of the header file containing the class\n# definition is used. Otherwise one should specify the include paths that\n# are normally passed to the compiler using the -I flag.\n\nSTRIP_FROM_INC_PATH    =\n\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter\n# (but less readable) file names. This can be useful if your file system\n# doesn't support long names like on DOS, Mac, or CD-ROM.\n\nSHORT_NAMES            = NO\n\n# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen\n# will interpret the first line (until the first dot) of a JavaDoc-style\n# comment as the brief description. If set to NO, the JavaDoc\n# comments will behave just like regular Qt-style comments\n# (thus requiring an explicit @brief command for a brief description.)\n\nJAVADOC_AUTOBRIEF      = YES\n\n# If the QT_AUTOBRIEF tag is set to YES then Doxygen will\n# interpret the first line (until the first dot) of a Qt-style\n# comment as the brief description. If set to NO, the comments\n# will behave just like regular Qt-style comments (thus requiring\n# an explicit \\brief command for a brief description.)\n\nQT_AUTOBRIEF           = NO\n\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen\n# treat a multi-line C++ special comment block (i.e. a block of //! or ///\n# comments) as a brief description. This used to be the default behaviour.\n# The new default is to treat a multi-line C++ comment block as a detailed\n# description. Set this tag to YES if you prefer the old behaviour instead.\n\nMULTILINE_CPP_IS_BRIEF = NO\n\n# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented\n# member inherits the documentation from any documented member that it\n# re-implements.\n\nINHERIT_DOCS           = YES\n\n# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce\n# a new page for each member. If set to NO, the documentation of a member will\n# be part of the file/class/namespace that contains it.\n\nSEPARATE_MEMBER_PAGES  = NO\n\n# The TAB_SIZE tag can be used to set the number of spaces in a tab.\n# Doxygen uses this value to replace tabs by spaces in code fragments.\n\nTAB_SIZE               = 8\n\n# This tag can be used to specify a number of aliases that acts\n# as commands in the documentation. An alias has the form \"name=value\".\n# For example adding \"sideeffect=\\par Side Effects:\\n\" will allow you to\n# put the command \\sideeffect (or @sideeffect) in the documentation, which\n# will result in a user-defined paragraph with heading \"Side Effects:\".\n# You can put \\n's in the value part of an alias to insert newlines.\n\nALIASES                =\n\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C\n# sources only. Doxygen will then generate output that is more tailored for C.\n# For instance, some of the names that are used will be different. The list\n# of all members will be omitted, etc.\n\nOPTIMIZE_OUTPUT_FOR_C  = YES\n\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java\n# sources only. Doxygen will then generate output that is more tailored for\n# Java. For instance, namespaces will be presented as packages, qualified\n# scopes will look different, etc.\n\nOPTIMIZE_OUTPUT_JAVA   = NO\n\n# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran\n# sources only. Doxygen will then generate output that is more tailored for\n# Fortran.\n\nOPTIMIZE_FOR_FORTRAN   = NO\n\n# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL\n# sources. Doxygen will then generate output that is tailored for\n# VHDL.\n\nOPTIMIZE_OUTPUT_VHDL   = NO\n\n# Doxygen selects the parser to use depending on the extension of the files it\n# parses. With this tag you can assign which parser to use for a given extension.\n# Doxygen has a built-in mapping, but you can override or extend it using this\n# tag. The format is ext=language, where ext is a file extension, and language\n# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,\n# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make\n# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C\n# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions\n# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.\n\nEXTENSION_MAPPING      =\n\n# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want\n# to include (a tag file for) the STL sources as input, then you should\n# set this tag to YES in order to let doxygen match functions declarations and\n# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.\n# func(std::string) {}). This also makes the inheritance and collaboration\n# diagrams that involve STL classes more complete and accurate.\n\nBUILTIN_STL_SUPPORT    = NO\n\n# If you use Microsoft's C++/CLI language, you should set this option to YES to\n# enable parsing support.\n\nCPP_CLI_SUPPORT        = NO\n\n# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.\n# Doxygen will parse them like normal C++ but will assume all classes use public\n# instead of private inheritance when no explicit protection keyword is present.\n\nSIP_SUPPORT            = NO\n\n# For Microsoft's IDL there are propget and propput attributes to indicate getter\n# and setter methods for a property. Setting this option to YES (the default)\n# will make doxygen replace the get and set methods by a property in the\n# documentation. This will only work if the methods are indeed getting or\n# setting a simple type. If this is not the case, or you want to show the\n# methods anyway, you should set this option to NO.\n\nIDL_PROPERTY_SUPPORT   = YES\n\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC\n# tag is set to YES, then doxygen will reuse the documentation of the first\n# member in the group (if any) for the other members of the group. By default\n# all members of a group must be documented explicitly.\n\nDISTRIBUTE_GROUP_DOC   = NO\n\n# Set the SUBGROUPING tag to YES (the default) to allow class member groups of\n# the same type (for instance a group of public functions) to be put as a\n# subgroup of that type (e.g. under the Public Functions section). Set it to\n# NO to prevent subgrouping. Alternatively, this can be done per class using\n# the \\nosubgrouping command.\n\nSUBGROUPING            = YES\n\n# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and\n# unions are shown inside the group in which they are included (e.g. using\n# @ingroup) instead of on a separate page (for HTML and Man pages) or\n# section (for LaTeX and RTF).\n\nINLINE_GROUPED_CLASSES = NO\n\n# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum\n# is documented as struct, union, or enum with the name of the typedef. So\n# typedef struct TypeS {} TypeT, will appear in the documentation as a struct\n# with name TypeT. When disabled the typedef will appear as a member of a file,\n# namespace, or class. And the struct will be named TypeS. This can typically\n# be useful for C code in case the coding convention dictates that all compound\n# types are typedef'ed and only the typedef is referenced, never the tag name.\n\nTYPEDEF_HIDES_STRUCT   = NO\n\n# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to\n# determine which symbols to keep in memory and which to flush to disk.\n# When the cache is full, less often used symbols will be written to disk.\n# For small to medium size projects (<1000 input files) the default value is\n# probably good enough. For larger projects a too small cache size can cause\n# doxygen to be busy swapping symbols to and from disk most of the time\n# causing a significant performance penalty.\n# If the system has enough physical memory increasing the cache will improve the\n# performance by keeping more symbols in memory. Note that the value works on\n# a logarithmic scale so increasing the size by one will roughly double the\n# memory usage. The cache size is given by this formula:\n# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,\n# corresponding to a cache size of 2^16 = 65536 symbols\n\nSYMBOL_CACHE_SIZE      = 0\n\n#---------------------------------------------------------------------------\n# Build related configuration options\n#---------------------------------------------------------------------------\n\n# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in\n# documentation are documented, even if no documentation was available.\n# Private class members and static file members will be hidden unless\n# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES\n\nEXTRACT_ALL            = YES\n\n# If the EXTRACT_PRIVATE tag is set to YES all private members of a class\n# will be included in the documentation.\n\nEXTRACT_PRIVATE        = NO\n\n# If the EXTRACT_STATIC tag is set to YES all static members of a file\n# will be included in the documentation.\n\nEXTRACT_STATIC         = NO\n\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)\n# defined locally in source files will be included in the documentation.\n# If set to NO only classes defined in header files are included.\n\nEXTRACT_LOCAL_CLASSES  = YES\n\n# This flag is only useful for Objective-C code. When set to YES local\n# methods, which are defined in the implementation section but not in\n# the interface are included in the documentation.\n# If set to NO (the default) only methods in the interface are included.\n\nEXTRACT_LOCAL_METHODS  = NO\n\n# If this flag is set to YES, the members of anonymous namespaces will be\n# extracted and appear in the documentation as a namespace called\n# 'anonymous_namespace{file}', where file will be replaced with the base\n# name of the file that contains the anonymous namespace. By default\n# anonymous namespaces are hidden.\n\nEXTRACT_ANON_NSPACES   = NO\n\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all\n# undocumented members of documented classes, files or namespaces.\n# If set to NO (the default) these members will be included in the\n# various overviews, but no documentation section is generated.\n# This option has no effect if EXTRACT_ALL is enabled.\n\nHIDE_UNDOC_MEMBERS     = NO\n\n# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all\n# undocumented classes that are normally visible in the class hierarchy.\n# If set to NO (the default) these classes will be included in the various\n# overviews. This option has no effect if EXTRACT_ALL is enabled.\n\nHIDE_UNDOC_CLASSES     = NO\n\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all\n# friend (class|struct|union) declarations.\n# If set to NO (the default) these declarations will be included in the\n# documentation.\n\nHIDE_FRIEND_COMPOUNDS  = NO\n\n# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any\n# documentation blocks found inside the body of a function.\n# If set to NO (the default) these blocks will be appended to the\n# function's detailed documentation block.\n\nHIDE_IN_BODY_DOCS      = NO\n\n# The INTERNAL_DOCS tag determines if documentation\n# that is typed after a \\internal command is included. If the tag is set\n# to NO (the default) then the documentation will be excluded.\n# Set it to YES to include the internal documentation.\n\nINTERNAL_DOCS          = NO\n\n# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate\n# file names in lower-case letters. If set to YES upper-case letters are also\n# allowed. This is useful if you have classes or files whose names only differ\n# in case and if your file system supports case sensitive file names. Windows\n# and Mac users are advised to set this option to NO.\n\nCASE_SENSE_NAMES       = YES\n\n# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen\n# will show members with their full class and namespace scopes in the\n# documentation. If set to YES the scope will be hidden.\n\nHIDE_SCOPE_NAMES       = NO\n\n# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen\n# will put a list of the files that are included by a file in the documentation\n# of that file.\n\nSHOW_INCLUDE_FILES     = YES\n\n# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen\n# will list include files with double quotes in the documentation\n# rather than with sharp brackets.\n\nFORCE_LOCAL_INCLUDES   = NO\n\n# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]\n# is inserted in the documentation for inline members.\n\nINLINE_INFO            = YES\n\n# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen\n# will sort the (detailed) documentation of file and class members\n# alphabetically by member name. If set to NO the members will appear in\n# declaration order.\n\nSORT_MEMBER_DOCS       = YES\n\n# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the\n# brief documentation of file, namespace and class members alphabetically\n# by member name. If set to NO (the default) the members will appear in\n# declaration order.\n\nSORT_BRIEF_DOCS        = NO\n\n# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen\n# will sort the (brief and detailed) documentation of class members so that\n# constructors and destructors are listed first. If set to NO (the default)\n# the constructors will appear in the respective orders defined by\n# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.\n# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO\n# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.\n\nSORT_MEMBERS_CTORS_1ST = NO\n\n# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the\n# hierarchy of group names into alphabetical order. If set to NO (the default)\n# the group names will appear in their defined order.\n\nSORT_GROUP_NAMES       = NO\n\n# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be\n# sorted by fully-qualified names, including namespaces. If set to\n# NO (the default), the class list will be sorted only by class name,\n# not including the namespace part.\n# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.\n# Note: This option applies only to the class list, not to the\n# alphabetical list.\n\nSORT_BY_SCOPE_NAME     = NO\n\n# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to\n# do proper type resolution of all parameters of a function it will reject a\n# match between the prototype and the implementation of a member function even\n# if there is only one candidate or it is obvious which candidate to choose\n# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen\n# will still accept a match between prototype and implementation in such cases.\n\nSTRICT_PROTO_MATCHING  = NO\n\n# The GENERATE_TODOLIST tag can be used to enable (YES) or\n# disable (NO) the todo list. This list is created by putting \\todo\n# commands in the documentation.\n\nGENERATE_TODOLIST      = YES\n\n# The GENERATE_TESTLIST tag can be used to enable (YES) or\n# disable (NO) the test list. This list is created by putting \\test\n# commands in the documentation.\n\nGENERATE_TESTLIST      = YES\n\n# The GENERATE_BUGLIST tag can be used to enable (YES) or\n# disable (NO) the bug list. This list is created by putting \\bug\n# commands in the documentation.\n\nGENERATE_BUGLIST       = YES\n\n# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or\n# disable (NO) the deprecated list. This list is created by putting\n# \\deprecated commands in the documentation.\n\nGENERATE_DEPRECATEDLIST= YES\n\n# The ENABLED_SECTIONS tag can be used to enable conditional\n# documentation sections, marked by \\if sectionname ... \\endif.\n\nENABLED_SECTIONS       =\n\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines\n# the initial value of a variable or macro consists of for it to appear in\n# the documentation. If the initializer consists of more lines than specified\n# here it will be hidden. Use a value of 0 to hide initializers completely.\n# The appearance of the initializer of individual variables and macros in the\n# documentation can be controlled using \\showinitializer or \\hideinitializer\n# command in the documentation regardless of this setting.\n\nMAX_INITIALIZER_LINES  = 30\n\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated\n# at the bottom of the documentation of classes and structs. If set to YES the\n# list will mention the files that were used to generate the documentation.\n\nSHOW_USED_FILES        = YES\n\n# If the sources in your project are distributed over multiple directories\n# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy\n# in the documentation. The default is NO.\n\nSHOW_DIRECTORIES       = NO\n\n# Set the SHOW_FILES tag to NO to disable the generation of the Files page.\n# This will remove the Files entry from the Quick Index and from the\n# Folder Tree View (if specified). The default is YES.\n\nSHOW_FILES             = YES\n\n# Set the SHOW_NAMESPACES tag to NO to disable the generation of the\n# Namespaces page.\n# This will remove the Namespaces entry from the Quick Index\n# and from the Folder Tree View (if specified). The default is YES.\n\nSHOW_NAMESPACES        = YES\n\n# The FILE_VERSION_FILTER tag can be used to specify a program or script that\n# doxygen should invoke to get the current version for each file (typically from\n# the version control system). Doxygen will invoke the program by executing (via\n# popen()) the command <command> <input-file>, where <command> is the value of\n# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file\n# provided by doxygen. Whatever the program writes to standard output\n# is used as the file version. See the manual for examples.\n\nFILE_VERSION_FILTER    =\n\n# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed\n# by doxygen. The layout file controls the global structure of the generated\n# output files in an output format independent way. The create the layout file\n# that represents doxygen's defaults, run doxygen with the -l option.\n# You can optionally specify a file name after the option, if omitted\n# DoxygenLayout.xml will be used as the name of the layout file.\n\nLAYOUT_FILE            =\n\n#---------------------------------------------------------------------------\n# configuration options related to warning and progress messages\n#---------------------------------------------------------------------------\n\n# The QUIET tag can be used to turn on/off the messages that are generated\n# by doxygen. Possible values are YES and NO. If left blank NO is used.\n\nQUIET                  = YES\n\n# The WARNINGS tag can be used to turn on/off the warning messages that are\n# generated by doxygen. Possible values are YES and NO. If left blank\n# NO is used.\n\nWARNINGS               = YES\n\n# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings\n# for undocumented members. If EXTRACT_ALL is set to YES then this flag will\n# automatically be disabled.\n\nWARN_IF_UNDOCUMENTED   = YES\n\n# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for\n# potential errors in the documentation, such as not documenting some\n# parameters in a documented function, or documenting parameters that\n# don't exist or using markup commands wrongly.\n\nWARN_IF_DOC_ERROR      = YES\n\n# The WARN_NO_PARAMDOC option can be enabled to get warnings for\n# functions that are documented, but have no documentation for their parameters\n# or return value. If set to NO (the default) doxygen will only warn about\n# wrong or incomplete parameter documentation, but not about the absence of\n# documentation.\n\nWARN_NO_PARAMDOC       = NO\n\n# The WARN_FORMAT tag determines the format of the warning messages that\n# doxygen can produce. The string should contain the $file, $line, and $text\n# tags, which will be replaced by the file and line number from which the\n# warning originated and the warning text. Optionally the format may contain\n# $version, which will be replaced by the version of the file (if it could\n# be obtained via FILE_VERSION_FILTER)\n\nWARN_FORMAT            = \"$file:$line: $text\"\n\n# The WARN_LOGFILE tag can be used to specify a file to which warning\n# and error messages should be written. If left blank the output is written\n# to stderr.\n\nWARN_LOGFILE           =\n\n#---------------------------------------------------------------------------\n# configuration options related to the input files\n#---------------------------------------------------------------------------\n\n# The INPUT tag can be used to specify the files and/or directories that contain\n# documented source files. You may enter file names like \"myfile.cpp\" or\n# directories like \"/usr/src/myproject\". Separate the files or directories\n# with spaces.\n\nINPUT                  = @top_srcdir@/include/opus.h \\\n                         @top_srcdir@/include/opus_types.h   \\\n                         @top_srcdir@/include/opus_defines.h \\\n                         @top_srcdir@/include/opus_multistream.h \\\n                         @top_srcdir@/include/opus_custom.h\n\n# This tag can be used to specify the character encoding of the source files\n# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is\n# also the default input encoding. Doxygen uses libiconv (or the iconv built\n# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for\n# the list of possible encodings.\n\nINPUT_ENCODING         = UTF-8\n\n# If the value of the INPUT tag contains directories, you can use the\n# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp\n# and *.h) to filter out the source-files in the directories. If left\n# blank the following patterns are tested:\n# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh\n# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py\n# *.f90 *.f *.for *.vhd *.vhdl\n\nFILE_PATTERNS          =\n\n# The RECURSIVE tag can be used to turn specify whether or not subdirectories\n# should be searched for input files as well. Possible values are YES and NO.\n# If left blank NO is used.\n\nRECURSIVE              = NO\n\n# The EXCLUDE tag can be used to specify files and/or directories that should\n# excluded from the INPUT source files. This way you can easily exclude a\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\n\nEXCLUDE                =\n\n# The EXCLUDE_SYMLINKS tag can be used select whether or not files or\n# directories that are symbolic links (a Unix file system feature) are excluded\n# from the input.\n\nEXCLUDE_SYMLINKS       = NO\n\n# If the value of the INPUT tag contains directories, you can use the\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude\n# certain files from those directories. Note that the wildcards are matched\n# against the file with absolute path, so to exclude all test directories\n# for example use the pattern */test/*\n\nEXCLUDE_PATTERNS       =\n\n# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names\n# (namespaces, classes, functions, etc.) that should be excluded from the\n# output. The symbol name can be a fully qualified name, a word, or if the\n# wildcard * is used, a substring. Examples: ANamespace, AClass,\n# AClass::ANamespace, ANamespace::*Test\n\nEXCLUDE_SYMBOLS        =\n\n# The EXAMPLE_PATH tag can be used to specify one or more files or\n# directories that contain example code fragments that are included (see\n# the \\include command).\n\nEXAMPLE_PATH           =\n\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp\n# and *.h) to filter out the source-files in the directories. If left\n# blank all files are included.\n\nEXAMPLE_PATTERNS       =\n\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be\n# searched for input files to be used with the \\include or \\dontinclude\n# commands irrespective of the value of the RECURSIVE tag.\n# Possible values are YES and NO. If left blank NO is used.\n\nEXAMPLE_RECURSIVE      = NO\n\n# The IMAGE_PATH tag can be used to specify one or more files or\n# directories that contain image that are included in the documentation (see\n# the \\image command).\n\nIMAGE_PATH             =\n\n# The INPUT_FILTER tag can be used to specify a program that doxygen should\n# invoke to filter for each input file. Doxygen will invoke the filter program\n# by executing (via popen()) the command <filter> <input-file>, where <filter>\n# is the value of the INPUT_FILTER tag, and <input-file> is the name of an\n# input file. Doxygen will then use the output that the filter program writes\n# to standard output.\n# If FILTER_PATTERNS is specified, this tag will be\n# ignored.\n\nINPUT_FILTER           =\n\n# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern\n# basis.\n# Doxygen will compare the file name with each pattern and apply the\n# filter if there is a match.\n# The filters are a list of the form:\n# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further\n# info on how filters are used. If FILTER_PATTERNS is empty or if\n# non of the patterns match the file name, INPUT_FILTER is applied.\n\nFILTER_PATTERNS        =\n\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using\n# INPUT_FILTER) will be used to filter the input files when producing source\n# files to browse (i.e. when SOURCE_BROWSER is set to YES).\n\nFILTER_SOURCE_FILES    = NO\n\n# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file\n# pattern. A pattern will override the setting for FILTER_PATTERN (if any)\n# and it is also possible to disable source filtering for a specific pattern\n# using *.ext= (so without naming a filter). This option only has effect when\n# FILTER_SOURCE_FILES is enabled.\n\nFILTER_SOURCE_PATTERNS =\n\n#---------------------------------------------------------------------------\n# configuration options related to source browsing\n#---------------------------------------------------------------------------\n\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will\n# be generated. Documented entities will be cross-referenced with these sources.\n# Note: To get rid of all source code in the generated output, make sure also\n# VERBATIM_HEADERS is set to NO.\n\nSOURCE_BROWSER         = NO\n\n# Setting the INLINE_SOURCES tag to YES will include the body\n# of functions and classes directly in the documentation.\n\nINLINE_SOURCES         = NO\n\n# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct\n# doxygen to hide any special comment blocks from generated source code\n# fragments. Normal C and C++ comments will always remain visible.\n\nSTRIP_CODE_COMMENTS    = YES\n\n# If the REFERENCED_BY_RELATION tag is set to YES\n# then for each documented function all documented\n# functions referencing it will be listed.\n\nREFERENCED_BY_RELATION = NO\n\n# If the REFERENCES_RELATION tag is set to YES\n# then for each documented function all documented entities\n# called/used by that function will be listed.\n\nREFERENCES_RELATION    = NO\n\n# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)\n# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from\n# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will\n# link to the source code.\n# Otherwise they will link to the documentation.\n\nREFERENCES_LINK_SOURCE = YES\n\n# If the USE_HTAGS tag is set to YES then the references to source code\n# will point to the HTML generated by the htags(1) tool instead of doxygen\n# built-in source browser. The htags tool is part of GNU's global source\n# tagging system (see http://www.gnu.org/software/global/global.html). You\n# will need version 4.8.6 or higher.\n\nUSE_HTAGS              = NO\n\n# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen\n# will generate a verbatim copy of the header file for each class for\n# which an include is specified. Set to NO to disable this.\n\nVERBATIM_HEADERS       = YES\n\n#---------------------------------------------------------------------------\n# configuration options related to the alphabetical class index\n#---------------------------------------------------------------------------\n\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index\n# of all compounds will be generated. Enable this if the project\n# contains a lot of classes, structs, unions or interfaces.\n\nALPHABETICAL_INDEX     = NO\n\n# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then\n# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns\n# in which this list will be split (can be a number in the range [1..20])\n\nCOLS_IN_ALPHA_INDEX    = 5\n\n# In case all classes in a project start with a common prefix, all\n# classes will be put under the same header in the alphabetical index.\n# The IGNORE_PREFIX tag can be used to specify one or more prefixes that\n# should be ignored while generating the index headers.\n\nIGNORE_PREFIX          =\n\n#---------------------------------------------------------------------------\n# configuration options related to the HTML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_HTML tag is set to YES (the default) Doxygen will\n# generate HTML output.\n\nGENERATE_HTML          = YES\n\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be\n# put in front of it. If left blank `html' will be used as the default path.\n\nHTML_OUTPUT            = html\n\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for\n# each generated HTML page (for example: .htm,.php,.asp). If it is left blank\n# doxygen will generate files with .html extension.\n\nHTML_FILE_EXTENSION    = .html\n\n# The HTML_HEADER tag can be used to specify a personal HTML header for\n# each generated HTML page. If it is left blank doxygen will generate a\n# standard header. Note that when using a custom header you are responsible\n# for the proper inclusion of any scripts and style sheets that doxygen\n# needs, which is dependent on the configuration options used.\n# It is advised to generate a default header using \"doxygen -w html\n# header.html footer.html stylesheet.css YourConfigFile\" and then modify\n# that header. Note that the header is subject to change so you typically\n# have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW!\n\nHTML_HEADER            = @top_srcdir@/doc/header.html\n\n# The HTML_FOOTER tag can be used to specify a personal HTML footer for\n# each generated HTML page. If it is left blank doxygen will generate a\n# standard footer.\n\nHTML_FOOTER            = @top_srcdir@/doc/footer.html\n\n# If the HTML_TIMESTAMP tag is set to YES then the generated HTML documentation will contain the timesstamp.\n\nHTML_TIMESTAMP         = NO\n\n# The HTML_STYLESHEET tag can be used to specify a user-defined cascading\n# style sheet that is used by each HTML page. It can be used to\n# fine-tune the look of the HTML output. If the tag is left blank doxygen\n# will generate a default style sheet. Note that doxygen will try to copy\n# the style sheet file to the HTML output directory, so don't put your own\n# stylesheet in the HTML output directory as well, or it will be erased!\n\nHTML_STYLESHEET        = @top_srcdir@/doc/customdoxygen.css\n\n# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the HTML output directory. Note\n# that these files will be copied to the base HTML output directory. Use the\n# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these\n# files. In the HTML_STYLESHEET file, use the file name only. Also note that\n# the files will be copied as-is; there are no commands or markers available.\n\nHTML_EXTRA_FILES       = @top_srcdir@/doc/opus_logo.svg\n\n# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.\n# Doxygen will adjust the colors in the stylesheet and background images\n# according to this color. Hue is specified as an angle on a colorwheel,\n# see http://en.wikipedia.org/wiki/Hue for more information.\n# For instance the value 0 represents red, 60 is yellow, 120 is green,\n# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.\n# The allowed range is 0 to 359.\n\nHTML_COLORSTYLE_HUE    = 220\n\n# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of\n# the colors in the HTML output. For a value of 0 the output will use\n# grayscales only. A value of 255 will produce the most vivid colors.\n\nHTML_COLORSTYLE_SAT    = 0\n\n# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to\n# the luminance component of the colors in the HTML output. Values below\n# 100 gradually make the output lighter, whereas values above 100 make\n# the output darker. The value divided by 100 is the actual gamma applied,\n# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,\n# and 100 does not change the gamma.\n\nHTML_COLORSTYLE_GAMMA  = 80\n\n# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML\n# page will contain the date and time when the page was generated. Setting\n# this to NO can help when comparing the output of multiple runs.\n\nHTML_TIMESTAMP         = YES\n\n# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,\n# files or namespaces will be aligned in HTML using tables. If set to\n# NO a bullet list will be used.\n\nHTML_ALIGN_MEMBERS     = YES\n\n# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML\n# documentation will contain sections that can be hidden and shown after the\n# page has loaded. For this to work a browser that supports\n# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox\n# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).\n\nHTML_DYNAMIC_SECTIONS  = NO\n\n# If the GENERATE_DOCSET tag is set to YES, additional index files\n# will be generated that can be used as input for Apple's Xcode 3\n# integrated development environment, introduced with OSX 10.5 (Leopard).\n# To create a documentation set, doxygen will generate a Makefile in the\n# HTML output directory. Running make will produce the docset in that\n# directory and running \"make install\" will install the docset in\n# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find\n# it at startup.\n# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html\n# for more information.\n\nGENERATE_DOCSET        = NO\n\n# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the\n# feed. A documentation feed provides an umbrella under which multiple\n# documentation sets from a single provider (such as a company or product suite)\n# can be grouped.\n\nDOCSET_FEEDNAME        = \"Doxygen generated docs\"\n\n# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that\n# should uniquely identify the documentation set bundle. This should be a\n# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen\n# will append .docset to the name.\n\nDOCSET_BUNDLE_ID       = org.doxygen.Project\n\n# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify\n# the documentation publisher. This should be a reverse domain-name style\n# string, e.g. com.mycompany.MyDocSet.documentation.\n\nDOCSET_PUBLISHER_ID    = org.doxygen.Publisher\n\n# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.\n\nDOCSET_PUBLISHER_NAME  = Publisher\n\n# If the GENERATE_HTMLHELP tag is set to YES, additional index files\n# will be generated that can be used as input for tools like the\n# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)\n# of the generated HTML documentation.\n\nGENERATE_HTMLHELP      = NO\n\n# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can\n# be used to specify the file name of the resulting .chm file. You\n# can add a path in front of the file if the result should not be\n# written to the html output directory.\n\nCHM_FILE               =\n\n# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can\n# be used to specify the location (absolute path including file name) of\n# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run\n# the HTML help compiler on the generated index.hhp.\n\nHHC_LOCATION           =\n\n# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag\n# controls if a separate .chi index file is generated (YES) or that\n# it should be included in the master .chm file (NO).\n\nGENERATE_CHI           = NO\n\n# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING\n# is used to encode HtmlHelp index (hhk), content (hhc) and project file\n# content.\n\nCHM_INDEX_ENCODING     =\n\n# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag\n# controls whether a binary table of contents is generated (YES) or a\n# normal table of contents (NO) in the .chm file.\n\nBINARY_TOC             = NO\n\n# The TOC_EXPAND flag can be set to YES to add extra items for group members\n# to the contents of the HTML help documentation and to the tree view.\n\nTOC_EXPAND             = NO\n\n# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and\n# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated\n# that can be used as input for Qt's qhelpgenerator to generate a\n# Qt Compressed Help (.qch) of the generated HTML documentation.\n\nGENERATE_QHP           = NO\n\n# If the QHG_LOCATION tag is specified, the QCH_FILE tag can\n# be used to specify the file name of the resulting .qch file.\n# The path specified is relative to the HTML output folder.\n\nQCH_FILE               =\n\n# The QHP_NAMESPACE tag specifies the namespace to use when generating\n# Qt Help Project output. For more information please see\n# http://doc.trolltech.com/qthelpproject.html#namespace\n\nQHP_NAMESPACE          = org.doxygen.Project\n\n# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating\n# Qt Help Project output. For more information please see\n# http://doc.trolltech.com/qthelpproject.html#virtual-folders\n\nQHP_VIRTUAL_FOLDER     = doc\n\n# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to\n# add. For more information please see\n# http://doc.trolltech.com/qthelpproject.html#custom-filters\n\nQHP_CUST_FILTER_NAME   =\n\n# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the\n# custom filter to add. For more information please see\n# <a href=\"http://doc.trolltech.com/qthelpproject.html#custom-filters\">\n# Qt Help Project / Custom Filters</a>.\n\nQHP_CUST_FILTER_ATTRS  =\n\n# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this\n# project's\n# filter section matches.\n# <a href=\"http://doc.trolltech.com/qthelpproject.html#filter-attributes\">\n# Qt Help Project / Filter Attributes</a>.\n\nQHP_SECT_FILTER_ATTRS  =\n\n# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can\n# be used to specify the location of Qt's qhelpgenerator.\n# If non-empty doxygen will try to run qhelpgenerator on the generated\n# .qhp file.\n\nQHG_LOCATION           =\n\n# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files\n#  will be generated, which together with the HTML files, form an Eclipse help\n# plugin. To install this plugin and make it available under the help contents\n# menu in Eclipse, the contents of the directory containing the HTML and XML\n# files needs to be copied into the plugins directory of eclipse. The name of\n# the directory within the plugins directory should be the same as\n# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before\n# the help appears.\n\nGENERATE_ECLIPSEHELP   = NO\n\n# A unique identifier for the eclipse help plugin. When installing the plugin\n# the directory name containing the HTML and XML files should also have\n# this name.\n\nECLIPSE_DOC_ID         = org.doxygen.Project\n\n# The DISABLE_INDEX tag can be used to turn on/off the condensed index at\n# top of each HTML page. The value NO (the default) enables the index and\n# the value YES disables it.\n\nDISABLE_INDEX          = NO\n\n# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values\n# (range [0,1..20]) that doxygen will group on one line in the generated HTML\n# documentation. Note that a value of 0 will completely suppress the enum\n# values from appearing in the overview section.\n\nENUM_VALUES_PER_LINE   = 4\n\n# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index\n# structure should be generated to display hierarchical information.\n# If the tag value is set to YES, a side panel will be generated\n# containing a tree-like index structure (just like the one that\n# is generated for HTML Help). For this to work a browser that supports\n# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).\n# Windows users are probably better off using the HTML help feature.\n\nGENERATE_TREEVIEW      = NO\n\n# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,\n# and Class Hierarchy pages using a tree view instead of an ordered list.\n\nUSE_INLINE_TREES       = NO\n\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be\n# used to set the initial width (in pixels) of the frame in which the tree\n# is shown.\n\nTREEVIEW_WIDTH         = 250\n\n# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open\n# links to external symbols imported via tag files in a separate window.\n\nEXT_LINKS_IN_WINDOW    = NO\n\n# Use this tag to change the font size of Latex formulas included\n# as images in the HTML documentation. The default is 10. Note that\n# when you change the font size after a successful doxygen run you need\n# to manually remove any form_*.png images from the HTML output directory\n# to force them to be regenerated.\n\nFORMULA_FONTSIZE       = 10\n\n# Use the FORMULA_TRANPARENT tag to determine whether or not the images\n# generated for formulas are transparent PNGs. Transparent PNGs are\n# not supported properly for IE 6.0, but are supported on all modern browsers.\n# Note that when changing this option you need to delete any form_*.png files\n# in the HTML output before the changes have effect.\n\nFORMULA_TRANSPARENT    = YES\n\n# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax\n# (see http://www.mathjax.org) which uses client side Javascript for the\n# rendering instead of using prerendered bitmaps. Use this if you do not\n# have LaTeX installed or if you want to formulas look prettier in the HTML\n# output. When enabled you also need to install MathJax separately and\n# configure the path to it using the MATHJAX_RELPATH option.\n\nUSE_MATHJAX            = NO\n\n# When MathJax is enabled you need to specify the location relative to the\n# HTML output directory using the MATHJAX_RELPATH option. The destination\n# directory should contain the MathJax.js script. For instance, if the mathjax\n# directory is located at the same level as the HTML output directory, then\n# MATHJAX_RELPATH should be ../mathjax. The default value points to the\n# mathjax.org site, so you can quickly see the result without installing\n# MathJax, but it is strongly recommended to install a local copy of MathJax\n# before deployment.\n\nMATHJAX_RELPATH        = http://www.mathjax.org/mathjax\n\n# When the SEARCHENGINE tag is enabled doxygen will generate a search box\n# for the HTML output. The underlying search engine uses javascript\n# and DHTML and should work on any modern browser. Note that when using\n# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets\n# (GENERATE_DOCSET) there is already a search function so this one should\n# typically be disabled. For large projects the javascript based search engine\n# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.\n\nSEARCHENGINE           = YES\n\n# When the SERVER_BASED_SEARCH tag is enabled the search engine will be\n# implemented using a PHP enabled web server instead of at the web client\n# using Javascript. Doxygen will generate the search PHP script and index\n# file to put on the web server. The advantage of the server\n# based approach is that it scales better to large projects and allows\n# full text search. The disadvantages are that it is more difficult to setup\n# and does not have live searching capabilities.\n\nSERVER_BASED_SEARCH    = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to the LaTeX output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will\n# generate Latex output.\n\nGENERATE_LATEX         = YES\n\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be\n# put in front of it. If left blank `latex' will be used as the default path.\n\nLATEX_OUTPUT           = latex\n\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be\n# invoked. If left blank `latex' will be used as the default command name.\n# Note that when enabling USE_PDFLATEX this option is only used for\n# generating bitmaps for formulas in the HTML output, but not in the\n# Makefile that is written to the output directory.\n\nLATEX_CMD_NAME         = latex\n\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to\n# generate index for LaTeX. If left blank `makeindex' will be used as the\n# default command name.\n\nMAKEINDEX_CMD_NAME     = makeindex\n\n# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact\n# LaTeX documents. This may be useful for small projects and may help to\n# save some trees in general.\n\nCOMPACT_LATEX          = NO\n\n# The PAPER_TYPE tag can be used to set the paper type that is used\n# by the printer. Possible values are: a4, letter, legal and\n# executive. If left blank a4wide will be used.\n\nPAPER_TYPE             = letter\n\n# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX\n# packages that should be included in the LaTeX output.\n\nEXTRA_PACKAGES         =\n\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for\n# the generated latex document. The header should contain everything until\n# the first chapter. If it is left blank doxygen will generate a\n# standard header. Notice: only use this tag if you know what you are doing!\n\nLATEX_HEADER           =\n\n# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for\n# the generated latex document. The footer should contain everything after\n# the last chapter. If it is left blank doxygen will generate a\n# standard footer. Notice: only use this tag if you know what you are doing!\n\nLATEX_FOOTER           =\n\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated\n# is prepared for conversion to pdf (using ps2pdf). The pdf file will\n# contain links (just like the HTML output) instead of page references\n# This makes the output suitable for online browsing using a pdf viewer.\n\nPDF_HYPERLINKS         = YES\n\n# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of\n# plain latex in the generated Makefile. Set this option to YES to get a\n# higher quality PDF documentation.\n\nUSE_PDFLATEX           = YES\n\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\\\batchmode.\n# command to the generated LaTeX files. This will instruct LaTeX to keep\n# running if errors occur, instead of asking the user for help.\n# This option is also used when generating formulas in HTML.\n\nLATEX_BATCHMODE        = NO\n\n# If LATEX_HIDE_INDICES is set to YES then doxygen will not\n# include the index chapters (such as File Index, Compound Index, etc.)\n# in the output.\n\nLATEX_HIDE_INDICES     = NO\n\n# If LATEX_SOURCE_CODE is set to YES then doxygen will include\n# source code with syntax highlighting in the LaTeX output.\n# Note that which sources are shown also depends on other settings\n# such as SOURCE_BROWSER.\n\nLATEX_SOURCE_CODE      = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to the RTF output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output\n# The RTF output is optimized for Word 97 and may not look very pretty with\n# other RTF readers or editors.\n\nGENERATE_RTF           = NO\n\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be\n# put in front of it. If left blank `rtf' will be used as the default path.\n\nRTF_OUTPUT             = rtf\n\n# If the COMPACT_RTF tag is set to YES Doxygen generates more compact\n# RTF documents. This may be useful for small projects and may help to\n# save some trees in general.\n\nCOMPACT_RTF            = NO\n\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated\n# will contain hyperlink fields. The RTF file will\n# contain links (just like the HTML output) instead of page references.\n# This makes the output suitable for online browsing using WORD or other\n# programs which support those fields.\n# Note: wordpad (write) and others do not support links.\n\nRTF_HYPERLINKS         = NO\n\n# Load stylesheet definitions from file. Syntax is similar to doxygen's\n# config file, i.e. a series of assignments. You only have to provide\n# replacements, missing definitions are set to their default value.\n\nRTF_STYLESHEET_FILE    =\n\n# Set optional variables used in the generation of an rtf document.\n# Syntax is similar to doxygen's config file.\n\nRTF_EXTENSIONS_FILE    =\n\n#---------------------------------------------------------------------------\n# configuration options related to the man page output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_MAN tag is set to YES (the default) Doxygen will\n# generate man pages\n\nGENERATE_MAN           = YES\n\n# The MAN_OUTPUT tag is used to specify where the man pages will be put.\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be\n# put in front of it. If left blank `man' will be used as the default path.\n\nMAN_OUTPUT             = man\n\n# The MAN_EXTENSION tag determines the extension that is added to\n# the generated man pages (default is the subroutine's section .3)\n\nMAN_EXTENSION          = .3\n\n# If the MAN_LINKS tag is set to YES and Doxygen generates man output,\n# then it will generate one additional man file for each entity\n# documented in the real man page(s). These additional files\n# only source the real man page, but without them the man command\n# would be unable to find the correct page. The default is NO.\n\nMAN_LINKS              = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to the XML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_XML tag is set to YES Doxygen will\n# generate an XML file that captures the structure of\n# the code including all documentation.\n\nGENERATE_XML           = NO\n\n# The XML_OUTPUT tag is used to specify where the XML pages will be put.\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be\n# put in front of it. If left blank `xml' will be used as the default path.\n\nXML_OUTPUT             = xml\n\n# The XML_SCHEMA tag can be used to specify an XML schema,\n# which can be used by a validating XML parser to check the\n# syntax of the XML files.\n\nXML_SCHEMA             =\n\n# The XML_DTD tag can be used to specify an XML DTD,\n# which can be used by a validating XML parser to check the\n# syntax of the XML files.\n\nXML_DTD                =\n\n# If the XML_PROGRAMLISTING tag is set to YES Doxygen will\n# dump the program listings (including syntax highlighting\n# and cross-referencing information) to the XML output. Note that\n# enabling this will significantly increase the size of the XML output.\n\nXML_PROGRAMLISTING     = YES\n\n#---------------------------------------------------------------------------\n# configuration options for the AutoGen Definitions output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will\n# generate an AutoGen Definitions (see autogen.sf.net) file\n# that captures the structure of the code including all\n# documentation. Note that this feature is still experimental\n# and incomplete at the moment.\n\nGENERATE_AUTOGEN_DEF   = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to the Perl module output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_PERLMOD tag is set to YES Doxygen will\n# generate a Perl module file that captures the structure of\n# the code including all documentation. Note that this\n# feature is still experimental and incomplete at the\n# moment.\n\nGENERATE_PERLMOD       = NO\n\n# If the PERLMOD_LATEX tag is set to YES Doxygen will generate\n# the necessary Makefile rules, Perl scripts and LaTeX code to be able\n# to generate PDF and DVI output from the Perl module output.\n\nPERLMOD_LATEX          = NO\n\n# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be\n# nicely formatted so it can be parsed by a human reader.\n# This is useful\n# if you want to understand what is going on.\n# On the other hand, if this\n# tag is set to NO the size of the Perl module output will be much smaller\n# and Perl will parse it just the same.\n\nPERLMOD_PRETTY         = YES\n\n# The names of the make variables in the generated doxyrules.make file\n# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.\n# This is useful so different doxyrules.make files included by the same\n# Makefile don't overwrite each other's variables.\n\nPERLMOD_MAKEVAR_PREFIX =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the preprocessor\n#---------------------------------------------------------------------------\n\n# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will\n# evaluate all C-preprocessor directives found in the sources and include\n# files.\n\nENABLE_PREPROCESSING   = YES\n\n# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro\n# names in the source code. If set to NO (the default) only conditional\n# compilation will be performed. Macro expansion can be done in a controlled\n# way by setting EXPAND_ONLY_PREDEF to YES.\n\nMACRO_EXPANSION        = YES\n\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES\n# then the macro expansion is limited to the macros specified with the\n# PREDEFINED and EXPAND_AS_DEFINED tags.\n\nEXPAND_ONLY_PREDEF     = YES\n\n# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files\n# pointed to by INCLUDE_PATH will be searched when a #include is found.\n\nSEARCH_INCLUDES        = YES\n\n# The INCLUDE_PATH tag can be used to specify one or more directories that\n# contain include files that are not input files but should be processed by\n# the preprocessor.\n\nINCLUDE_PATH           =\n\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard\n# patterns (like *.h and *.hpp) to filter out the header-files in the\n# directories. If left blank, the patterns specified with FILE_PATTERNS will\n# be used.\n\nINCLUDE_FILE_PATTERNS  =\n\n# The PREDEFINED tag can be used to specify one or more macro names that\n# are defined before the preprocessor is started (similar to the -D option of\n# gcc). The argument of the tag is a list of macros of the form: name\n# or name=definition (no spaces). If the definition and the = are\n# omitted =1 is assumed. To prevent a macro definition from being\n# undefined via #undef or recursively expanded use the := operator\n# instead of the = operator.\n\nPREDEFINED             = OPUS_EXPORT= OPUS_CUSTOM_EXPORT= OPUS_CUSTOM_EXPORT_STATIC= OPUS_WARN_UNUSED_RESULT= OPUS_ARG_NONNULL(_x)=\n\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then\n# this tag can be used to specify a list of macro names that should be expanded.\n# The macro definition that is found in the sources will be used.\n# Use the PREDEFINED tag if you want to use a different macro definition that\n# overrules the definition found in the source code.\n\nEXPAND_AS_DEFINED      =\n\n# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then\n# doxygen's preprocessor will remove all references to function-like macros\n# that are alone on a line, have an all uppercase name, and do not end with a\n# semicolon, because these will confuse the parser if not removed.\n\nSKIP_FUNCTION_MACROS   = YES\n\n#---------------------------------------------------------------------------\n# Configuration::additions related to external references\n#---------------------------------------------------------------------------\n\n# The TAGFILES option can be used to specify one or more tagfiles.\n# Optionally an initial location of the external documentation\n# can be added for each tagfile. The format of a tag file without\n# this location is as follows:\n#\n# TAGFILES = file1 file2 ...\n# Adding location for the tag files is done as follows:\n#\n# TAGFILES = file1=loc1 \"file2 = loc2\" ...\n# where \"loc1\" and \"loc2\" can be relative or absolute paths or\n# URLs. If a location is present for each tag, the installdox tool\n# does not have to be run to correct the links.\n# Note that each tag file must have a unique name\n# (where the name does NOT include the path)\n# If a tag file is not located in the directory in which doxygen\n# is run, you must also specify the path to the tagfile here.\n\nTAGFILES               =\n\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create\n# a tag file that is based on the input files it reads.\n\nGENERATE_TAGFILE       =\n\n# If the ALLEXTERNALS tag is set to YES all external classes will be listed\n# in the class index. If set to NO only the inherited external classes\n# will be listed.\n\nALLEXTERNALS           = NO\n\n# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed\n# in the modules index. If set to NO, only the current project's groups will\n# be listed.\n\nEXTERNAL_GROUPS        = YES\n\n# The PERL_PATH should be the absolute path and name of the perl script\n# interpreter (i.e. the result of `which perl').\n\nPERL_PATH              = /usr/bin/perl\n\n#---------------------------------------------------------------------------\n# Configuration options related to the dot tool\n#---------------------------------------------------------------------------\n\n# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will\n# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base\n# or super classes. Setting the tag to NO turns the diagrams off. Note that\n# this option also works with HAVE_DOT disabled, but it is recommended to\n# install and use dot, since it yields more powerful graphs.\n\nCLASS_DIAGRAMS         = YES\n\n# You can define message sequence charts within doxygen comments using the \\msc\n# command. Doxygen will then run the mscgen tool (see\n# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the\n# documentation. The MSCGEN_PATH tag allows you to specify the directory where\n# the mscgen tool resides. If left empty the tool is assumed to be found in the\n# default search path.\n\nMSCGEN_PATH            =\n\n# If set to YES, the inheritance and collaboration graphs will hide\n# inheritance and usage relations if the target is undocumented\n# or is not a class.\n\nHIDE_UNDOC_RELATIONS   = YES\n\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is\n# available from the path. This tool is part of Graphviz, a graph visualization\n# toolkit from AT&T and Lucent Bell Labs. The other options in this section\n# have no effect if this option is set to NO (the default)\n\nHAVE_DOT               = NO\n\n# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is\n# allowed to run in parallel. When set to 0 (the default) doxygen will\n# base this on the number of processors available in the system. You can set it\n# explicitly to a value larger than 0 to get control over the balance\n# between CPU load and processing speed.\n\nDOT_NUM_THREADS        = 0\n\n# By default doxygen will write a font called Helvetica to the output\n# directory and reference it in all dot files that doxygen generates.\n# When you want a differently looking font you can specify the font name\n# using DOT_FONTNAME. You need to make sure dot is able to find the font,\n# which can be done by putting it in a standard location or by setting the\n# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory\n# containing the font.\n\nDOT_FONTNAME           = Helvetica\n\n# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.\n# The default size is 10pt.\n\nDOT_FONTSIZE           = 10\n\n# By default doxygen will tell dot to use the output directory to look for the\n# FreeSans.ttf font (which doxygen will put there itself). If you specify a\n# different font using DOT_FONTNAME you can set the path where dot\n# can find it using this tag.\n\nDOT_FONTPATH           =\n\n# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen\n# will generate a graph for each documented class showing the direct and\n# indirect inheritance relations. Setting this tag to YES will force the\n# the CLASS_DIAGRAMS tag to NO.\n\nCLASS_GRAPH            = YES\n\n# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen\n# will generate a graph for each documented class showing the direct and\n# indirect implementation dependencies (inheritance, containment, and\n# class references variables) of the class with other documented classes.\n\nCOLLABORATION_GRAPH    = YES\n\n# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen\n# will generate a graph for groups, showing the direct groups dependencies\n\nGROUP_GRAPHS           = YES\n\n# If the UML_LOOK tag is set to YES doxygen will generate inheritance and\n# collaboration diagrams in a style similar to the OMG's Unified Modeling\n# Language.\n\nUML_LOOK               = NO\n\n# If set to YES, the inheritance and collaboration graphs will show the\n# relations between templates and their instances.\n\nTEMPLATE_RELATIONS     = NO\n\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT\n# tags are set to YES then doxygen will generate a graph for each documented\n# file showing the direct and indirect include dependencies of the file with\n# other documented files.\n\nINCLUDE_GRAPH          = YES\n\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and\n# HAVE_DOT tags are set to YES then doxygen will generate a graph for each\n# documented header file showing the documented files that directly or\n# indirectly include this file.\n\nINCLUDED_BY_GRAPH      = YES\n\n# If the CALL_GRAPH and HAVE_DOT options are set to YES then\n# doxygen will generate a call dependency graph for every global function\n# or class method. Note that enabling this option will significantly increase\n# the time of a run. So in most cases it will be better to enable call graphs\n# for selected functions only using the \\callgraph command.\n\nCALL_GRAPH             = NO\n\n# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then\n# doxygen will generate a caller dependency graph for every global function\n# or class method. Note that enabling this option will significantly increase\n# the time of a run. So in most cases it will be better to enable caller\n# graphs for selected functions only using the \\callergraph command.\n\nCALLER_GRAPH           = NO\n\n# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen\n# will generate a graphical hierarchy of all classes instead of a textual one.\n\nGRAPHICAL_HIERARCHY    = YES\n\n# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES\n# then doxygen will show the dependencies a directory has on other directories\n# in a graphical way. The dependency relations are determined by the #include\n# relations between the files in the directories.\n\nDIRECTORY_GRAPH        = YES\n\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images\n# generated by dot. Possible values are svg, png, jpg, or gif.\n# If left blank png will be used.\n\nDOT_IMAGE_FORMAT       = png\n\n# The tag DOT_PATH can be used to specify the path where the dot tool can be\n# found. If left blank, it is assumed the dot tool can be found in the path.\n\nDOT_PATH               =\n\n# The DOTFILE_DIRS tag can be used to specify one or more directories that\n# contain dot files that are included in the documentation (see the\n# \\dotfile command).\n\nDOTFILE_DIRS           =\n\n# The MSCFILE_DIRS tag can be used to specify one or more directories that\n# contain msc files that are included in the documentation (see the\n# \\mscfile command).\n\nMSCFILE_DIRS           =\n\n# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of\n# nodes that will be shown in the graph. If the number of nodes in a graph\n# becomes larger than this value, doxygen will truncate the graph, which is\n# visualized by representing a node as a red box. Note that doxygen if the\n# number of direct children of the root node in a graph is already larger than\n# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note\n# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.\n\nDOT_GRAPH_MAX_NODES    = 50\n\n# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the\n# graphs generated by dot. A depth value of 3 means that only nodes reachable\n# from the root by following a path via at most 3 edges will be shown. Nodes\n# that lay further from the root node will be omitted. Note that setting this\n# option to 1 or 2 may greatly reduce the computation time needed for large\n# code bases. Also note that the size of a graph can be further restricted by\n# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.\n\nMAX_DOT_GRAPH_DEPTH    = 0\n\n# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent\n# background. This is disabled by default, because dot on Windows does not\n# seem to support this out of the box. Warning: Depending on the platform used,\n# enabling this option may lead to badly anti-aliased labels on the edges of\n# a graph (i.e. they become hard to read).\n\nDOT_TRANSPARENT        = NO\n\n# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output\n# files in one run (i.e. multiple -o and -T options on the command line). This\n# makes dot run faster, but since only newer versions of dot (>1.8.10)\n# support this, this feature is disabled by default.\n\nDOT_MULTI_TARGETS      = NO\n\n# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will\n# generate a legend page explaining the meaning of the various boxes and\n# arrows in the dot generated graphs.\n\nGENERATE_LEGEND        = YES\n\n# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will\n# remove the intermediate dot files that are used to generate\n# the various graphs.\n\nDOT_CLEANUP            = YES\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/doc/Makefile.am",
    "content": "## Process this file with automake to produce Makefile.in\n\nDOCINPUTS = $(top_srcdir)/include/opus.h \\\n            $(top_srcdir)/include/opus_multistream.h \\\n            $(top_srcdir)/include/opus_defines.h \\\n            $(top_srcdir)/include/opus_types.h \\\n            $(top_srcdir)/include/opus_custom.h \\\n            $(top_srcdir)/doc/header.html \\\n            $(top_srcdir)/doc/footer.html \\\n            $(top_srcdir)/doc/customdoxygen.css\n\nEXTRA_DIST = customdoxygen.css Doxyfile.in footer.html header.html \\\n             opus_logo.svg trivial_example.c\n\n\nif HAVE_DOXYGEN\n\nall-local: doxygen-build.stamp\n\ndoxygen-build.stamp: Doxyfile $(DOCINPUTS)\n\tdoxygen\n\ttouch $@\n\ninstall-data-local:\n\t$(INSTALL) -d $(DESTDIR)$(docdir)/html/search\n\tfor f in `find html -type f \\! -name \"installdox\"`; do\t\\\n\t\t$(INSTALL_DATA) $$f $(DESTDIR)$(docdir)/$$f;\t\\\n\tdone\n\n\t$(INSTALL) -d $(DESTDIR)$(mandir)/man3\n\tcd man && find man3 -type f -name opus_*.3 \\\n\t\t  -exec $(INSTALL_DATA) \\{} $(DESTDIR)$(mandir)/man3 \\;\n\nclean-local:\n\t$(RM) -r html\n\t$(RM) -r latex\n\t$(RM) -r man\n\t$(RM) doxygen-build.stamp\n\nuninstall-local:\n\t$(RM) -r $(DESTDIR)$(docdir)/html\n\t$(RM) $(DESTDIR)$(mandir)/man3/opus_*.3 $(DESTDIR)$(mandir)/man3/opus.h.3\n\nendif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/doc/TODO",
    "content": "define audio bandwidth as frequency range\n\nrepeat padding recommendation\n\nptime: refer to RFC\n\nOpus does not provide any confidentiality or integrity protection\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/doc/customdoxygen.css",
    "content": "/* The standard CSS for doxygen */\n\nbody, table, div, p, dl {\n        font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;\n        font-size: 13px;\n        line-height: 1.3;\n}\n\n/* @group Heading Levels */\n\nh1 {\n        font-size: 150%;\n}\n\n.title {\n        font-size: 150%;\n        font-weight: bold;\n        margin: 10px 2px;\n}\n\nh2 {\n        font-size: 120%;\n}\n\nh3 {\n        font-size: 100%;\n}\n\ndt {\n        font-weight: bold;\n}\n\ndiv.multicol {\n        -moz-column-gap: 1em;\n        -webkit-column-gap: 1em;\n        -moz-column-count: 3;\n        -webkit-column-count: 3;\n}\n\np.startli, p.startdd, p.starttd {\n        margin-top: 2px;\n}\n\np.endli {\n        margin-bottom: 0px;\n}\n\np.enddd {\n        margin-bottom: 4px;\n}\n\np.endtd {\n        margin-bottom: 2px;\n}\n\n/* @end */\n\ncaption {\n        font-weight: bold;\n}\n\nspan.legend {\n        font-size: 70%;\n        text-align: center;\n}\n\nh3.version {\n        font-size: 90%;\n        text-align: center;\n}\n\ndiv.qindex, div.navtab{\n        background-color: #F1F1F1;\n        border: 1px solid #BDBDBD;\n        text-align: center;\n}\n\ndiv.qindex, div.navpath {\n        width: 100%;\n        line-height: 140%;\n}\n\ndiv.navtab {\n        margin-right: 15px;\n}\n\n/* @group Link Styling */\n\na {\n        color: #646464;\n        font-weight: normal;\n        text-decoration: none;\n}\n\n.contents a:visited {\n        color: #747474;\n}\n\na:hover {\n        text-decoration: underline;\n}\n\na.qindex {\n        font-weight: bold;\n}\n\na.qindexHL {\n        font-weight: bold;\n        background-color: #B8B8B8;\n        color: #ffffff;\n        border: 1px double #A8A8A8;\n}\n\n.contents a.qindexHL:visited {\n        color: #ffffff;\n}\n\na.el {\n        font-weight: bold;\n}\n\na.elRef {\n}\n\na.code, a.code:visited {\n        color: #4665A2;\n}\n\na.codeRef, a.codeRef:visited {\n        color: #4665A2;\n}\n\n/* @end */\n\ndl.el {\n        margin-left: -1cm;\n}\n\n.fragment {\n        font-family: monospace, fixed;\n        font-size: 105%;\n}\n\npre.fragment {\n        border: 1px solid #D5D5D5;\n        background-color: #FCFCFC;\n        padding: 4px 6px;\n        margin: 4px 8px 4px 2px;\n        overflow: auto;\n        word-wrap: break-word;\n        font-size:  9pt;\n        line-height: 125%;\n}\n\ndiv.ah {\n        background-color: black;\n        font-weight: bold;\n        color: #ffffff;\n        margin-bottom: 3px;\n        margin-top: 3px;\n        padding: 0.2em;\n        border: solid thin #333;\n        border-radius: 0.5em;\n        -webkit-border-radius: .5em;\n        -moz-border-radius: .5em;\n        box-shadow: 2px 2px 3px #999;\n        -webkit-box-shadow: 2px 2px 3px #999;\n        -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;\n        background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));\n        background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);\n}\n\ndiv.groupHeader {\n        margin-left: 16px;\n        margin-top: 12px;\n        font-weight: bold;\n}\n\ndiv.groupText {\n        margin-left: 16px;\n        font-style: italic;\n}\n\nbody {\n        background-color: white;\n        color: black;\n        margin: 0;\n}\n\ndiv.contents {\n        margin-top: 10px;\n        margin-left: 8px;\n        margin-right: 8px;\n}\n\ntd.indexkey {\n        background-color: #F1F1F1;\n        font-weight: bold;\n        border: 1px solid #D5D5D5;\n        margin: 2px 0px 2px 0;\n        padding: 2px 10px;\n        white-space: nowrap;\n        vertical-align: top;\n}\n\ntd.indexvalue {\n        background-color: #F1F1F1;\n        border: 1px solid #D5D5D5;\n        padding: 2px 10px;\n        margin: 2px 0px;\n}\n\ntr.memlist {\n        background-color: #F2F2F2;\n}\n\np.formulaDsp {\n        text-align: center;\n}\n\nimg.formulaDsp {\n\n}\n\nimg.formulaInl {\n        vertical-align: middle;\n}\n\ndiv.center {\n        text-align: center;\n        margin-top: 0px;\n        margin-bottom: 0px;\n        padding: 0px;\n}\n\ndiv.center img {\n        border: 0px;\n}\n\naddress.footer {\n        text-align: right;\n        padding-right: 12px;\n}\n\nimg.footer {\n        border: 0px;\n        vertical-align: middle;\n}\n\n/* @group Code Colorization */\n\nspan.keyword {\n        color: #008000\n}\n\nspan.keywordtype {\n        color: #604020\n}\n\nspan.keywordflow {\n        color: #e08000\n}\n\nspan.comment {\n        color: #800000\n}\n\nspan.preprocessor {\n        color: #806020\n}\n\nspan.stringliteral {\n        color: #002080\n}\n\nspan.charliteral {\n        color: #008080\n}\n\nspan.vhdldigit {\n        color: #ff00ff\n}\n\nspan.vhdlchar {\n        color: #000000\n}\n\nspan.vhdlkeyword {\n        color: #700070\n}\n\nspan.vhdllogic {\n        color: #ff0000\n}\n\nblockquote {\n        background-color: #F9F9F9;\n        border-left: 2px solid #B8B8B8;\n        margin: 0 24px 0 4px;\n        padding: 0 12px 0 16px;\n}\n\n/* @end */\n\n/*\n.search {\n        color: #003399;\n        font-weight: bold;\n}\n\nform.search {\n        margin-bottom: 0px;\n        margin-top: 0px;\n}\n\ninput.search {\n        font-size: 75%;\n        color: #000080;\n        font-weight: normal;\n        background-color: #e8eef2;\n}\n*/\n\ntd.tiny {\n        font-size: 75%;\n}\n\n.dirtab {\n        padding: 4px;\n        border-collapse: collapse;\n        border: 1px solid #BDBDBD;\n}\n\nth.dirtab {\n        background: #F1F1F1;\n        font-weight: bold;\n}\n\nhr {\n        height: 0px;\n        border: none;\n        border-top: 1px solid #7A7A7A;\n}\n\nhr.footer {\n        height: 1px;\n}\n\n/* @group Member Descriptions */\n\ntable.memberdecls {\n        border-spacing: 0px;\n        padding: 0px;\n}\n\n.mdescLeft, .mdescRight,\n.memItemLeft, .memItemRight,\n.memTemplItemLeft, .memTemplItemRight, .memTemplParams {\n        background-color: #FAFAFA;\n        border: none;\n        margin: 4px;\n        padding: 1px 0 0 8px;\n}\n\n.mdescLeft, .mdescRight {\n        padding: 0px 8px 4px 8px;\n        color: #555;\n}\n\n.memItemLeft, .memItemRight, .memTemplParams {\n        border-top: 1px solid #D5D5D5;\n}\n\n.memItemLeft, .memTemplItemLeft {\n        white-space: nowrap;\n}\n\n.memItemRight {\n        width: 100%;\n}\n\n.memTemplParams {\n        color: #747474;\n        white-space: nowrap;\n}\n\n/* @end */\n\n/* @group Member Details */\n\n/* Styles for detailed member documentation */\n\n.memtemplate {\n        font-size: 80%;\n        color: #747474;\n        font-weight: normal;\n        margin-left: 9px;\n}\n\n.memnav {\n        background-color: #F1F1F1;\n        border: 1px solid #BDBDBD;\n        text-align: center;\n        margin: 2px;\n        margin-right: 15px;\n        padding: 2px;\n}\n\n.mempage {\n        width: 100%;\n}\n\n.memitem {\n        padding: 0;\n        margin-bottom: 10px;\n        margin-right: 5px;\n}\n\n.memname {\n        white-space: nowrap;\n        font-weight: bold;\n        margin-left: 6px;\n}\n\n.memproto, dl.reflist dt {\n        border-top: 1px solid #C0C0C0;\n        border-left: 1px solid #C0C0C0;\n        border-right: 1px solid #C0C0C0;\n        padding: 6px 0px 6px 0px;\n        color: #3D3D3D;\n        font-weight: bold;\n        text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);\n        /* opera specific markup */\n        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);\n        border-top-right-radius: 8px;\n        border-top-left-radius: 8px;\n        /* firefox specific markup */\n        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;\n        -moz-border-radius-topright: 8px;\n        -moz-border-radius-topleft: 8px;\n        /* webkit specific markup */\n        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);\n        -webkit-border-top-right-radius: 8px;\n        -webkit-border-top-left-radius: 8px;\n        background-image:url('nav_f.png');\n        background-repeat:repeat-x;\n        background-color: #EAEAEA;\n\n}\n\n.memdoc, dl.reflist dd {\n        border-bottom: 1px solid #C0C0C0;\n        border-left: 1px solid #C0C0C0;\n        border-right: 1px solid #C0C0C0;\n        padding: 2px 5px;\n        background-color: #FCFCFC;\n        border-top-width: 0;\n        /* opera specific markup */\n        border-bottom-left-radius: 8px;\n        border-bottom-right-radius: 8px;\n        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);\n        /* firefox specific markup */\n        -moz-border-radius-bottomleft: 8px;\n        -moz-border-radius-bottomright: 8px;\n        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;\n        background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F9F9F9 95%, #F2F2F2);\n        /* webkit specific markup */\n        -webkit-border-bottom-left-radius: 8px;\n        -webkit-border-bottom-right-radius: 8px;\n        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);\n        background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F9F9F9), to(#F2F2F2));\n}\n\ndl.reflist dt {\n        padding: 5px;\n}\n\ndl.reflist dd {\n        margin: 0px 0px 10px 0px;\n        padding: 5px;\n}\n\n.paramkey {\n        text-align: right;\n}\n\n.paramtype {\n        white-space: nowrap;\n}\n\n.paramname {\n        color: #602020;\n        white-space: nowrap;\n}\n.paramname em {\n        font-style: normal;\n}\n\n.params, .retval, .exception, .tparams {\n        border-spacing: 6px 2px;\n}\n\n.params .paramname, .retval .paramname {\n        font-weight: bold;\n        vertical-align: top;\n}\n\n.params .paramtype {\n        font-style: italic;\n        vertical-align: top;\n}\n\n.params .paramdir {\n        font-family: \"courier new\",courier,monospace;\n        vertical-align: top;\n}\n\n\n\n\n/* @end */\n\n/* @group Directory (tree) */\n\n/* for the tree view */\n\n.ftvtree {\n        font-family: sans-serif;\n        margin: 0px;\n}\n\n/* these are for tree view when used as main index */\n\n.directory {\n        font-size: 9pt;\n        font-weight: bold;\n        margin: 5px;\n}\n\n.directory h3 {\n        margin: 0px;\n        margin-top: 1em;\n        font-size: 11pt;\n}\n\n/*\nThe following two styles can be used to replace the root node title\nwith an image of your choice.  Simply uncomment the next two styles,\nspecify the name of your image and be sure to set 'height' to the\nproper pixel height of your image.\n*/\n\n/*\n.directory h3.swap {\n        height: 61px;\n        background-repeat: no-repeat;\n        background-image: url(\"yourimage.gif\");\n}\n.directory h3.swap span {\n        display: none;\n}\n*/\n\n.directory > h3 {\n        margin-top: 0;\n}\n\n.directory p {\n        margin: 0px;\n        white-space: nowrap;\n}\n\n.directory div {\n        display: none;\n        margin: 0px;\n}\n\n.directory img {\n        vertical-align: -30%;\n}\n\n/* these are for tree view when not used as main index */\n\n.directory-alt {\n        font-size: 100%;\n        font-weight: bold;\n}\n\n.directory-alt h3 {\n        margin: 0px;\n        margin-top: 1em;\n        font-size: 11pt;\n}\n\n.directory-alt > h3 {\n        margin-top: 0;\n}\n\n.directory-alt p {\n        margin: 0px;\n        white-space: nowrap;\n}\n\n.directory-alt div {\n        display: none;\n        margin: 0px;\n}\n\n.directory-alt img {\n        vertical-align: -30%;\n}\n\n/* @end */\n\ndiv.dynheader {\n        margin-top: 8px;\n}\n\naddress {\n        font-style: normal;\n        color: #464646;\n}\n\ntable.doxtable {\n        border-collapse:collapse;\n        margin-top: 4px;\n        margin-bottom: 4px;\n}\n\ntable.doxtable td, table.doxtable th {\n        border: 1px solid #4A4A4A;\n        padding: 3px 7px 2px;\n}\n\ntable.doxtable th {\n        background-color: #5B5B5B;\n        color: #FFFFFF;\n        font-size: 110%;\n        padding-bottom: 4px;\n        padding-top: 5px;\n}\n\ntable.fieldtable {\n        width: 100%;\n        margin-bottom: 10px;\n        border: 1px solid #C0C0C0;\n        border-spacing: 0px;\n        -moz-border-radius: 4px;\n        -webkit-border-radius: 4px;\n        border-radius: 4px;\n        -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;\n        -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);\n        box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);\n}\n\n.fieldtable td, .fieldtable th {\n        padding: 3px 7px 2px;\n}\n\n.fieldtable td.fieldtype, .fieldtable td.fieldname {\n        white-space: nowrap;\n        border-right: 1px solid #C0C0C0;\n        border-bottom: 1px solid #C0C0C0;\n        vertical-align: top;\n}\n\n.fieldtable td.fielddoc {\n        border-bottom: 1px solid #C0C0C0;\n        width: 100%;\n}\n\n.fieldtable tr:last-child td {\n        border-bottom: none;\n}\n\n.fieldtable th {\n        background-image:url('nav_f.png');\n        background-repeat:repeat-x;\n        background-color: #EAEAEA;\n        font-size: 90%;\n        color: #3D3D3D;\n        padding-bottom: 4px;\n        padding-top: 5px;\n        text-align:left;\n        -moz-border-radius-topleft: 4px;\n        -moz-border-radius-topright: 4px;\n        -webkit-border-top-left-radius: 4px;\n        -webkit-border-top-right-radius: 4px;\n        border-top-left-radius: 4px;\n        border-top-right-radius: 4px;\n        border-bottom: 1px solid #C0C0C0;\n}\n\n\n.tabsearch {\n        top: 0px;\n        left: 10px;\n        height: 36px;\n        background-image: url('tab_b.png');\n        z-index: 101;\n        overflow: hidden;\n        font-size: 13px;\n}\n\n.navpath ul\n{\n        font-size: 11px;\n        background-image:url('tab_b.png');\n        background-repeat:repeat-x;\n        height:30px;\n        line-height:30px;\n        color:#ABABAB;\n        border:solid 1px #D3D3D3;\n        overflow:hidden;\n        margin:0px;\n        padding:0px;\n}\n\n.navpath li\n{\n        list-style-type:none;\n        float:left;\n        padding-left:10px;\n        padding-right:15px;\n        background-image:url('bc_s.png');\n        background-repeat:no-repeat;\n        background-position:right;\n        color:#595959;\n}\n\n.navpath li.navelem a\n{\n        height:32px;\n        display:block;\n        text-decoration: none;\n        outline: none;\n}\n\n.navpath li.navelem a:hover\n{\n        color:#929292;\n}\n\n.navpath li.footer\n{\n        list-style-type:none;\n        float:right;\n        padding-left:10px;\n        padding-right:15px;\n        background-image:none;\n        background-repeat:no-repeat;\n        background-position:right;\n        color:#595959;\n        font-size: 8pt;\n}\n\n\ndiv.summary\n{\n        float: right;\n        font-size: 8pt;\n        padding-right: 5px;\n        width: 50%;\n        text-align: right;\n}\n\ndiv.summary a\n{\n        white-space: nowrap;\n}\n\ndiv.ingroups\n{\n        margin-left: 5px;\n        font-size: 8pt;\n        padding-left: 5px;\n        width: 50%;\n        text-align: left;\n}\n\ndiv.ingroups a\n{\n        white-space: nowrap;\n}\n\ndiv.header\n{\n        background-image:url('nav_h.png');\n        background-repeat:repeat-x;\n        background-color: #FAFAFA;\n        margin:  0px;\n        border-bottom: 1px solid #D5D5D5;\n}\n\ndiv.headertitle\n{\n        padding: 5px 5px 5px 7px;\n}\n\ndl\n{\n        padding: 0 0 0 10px;\n}\n\n/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */\ndl.section\n{\n        border-left:4px solid;\n        padding: 0 0 0 6px;\n}\n\ndl.note\n{\n        border-color: #D0C000;\n}\n\ndl.warning, dl.attention\n{\n        border-color: #FF0000;\n}\n\ndl.pre, dl.post, dl.invariant\n{\n        border-color: #00D000;\n}\n\ndl.deprecated\n{\n        border-color: #505050;\n}\n\ndl.todo\n{\n        border-color: #00C0E0;\n}\n\ndl.test\n{\n        border-color: #3030E0;\n}\n\ndl.bug\n{\n        border-color: #C08050;\n}\n\ndl.section dd {\n        margin-bottom: 6px;\n}\n\n\n#projectlogo\n{\n        text-align: center;\n        vertical-align: bottom;\n        border-collapse: separate;\n}\n\n#projectlogo img\n{\n        border: 0px none;\n}\n\n#projectname\n{\n        font: 300% Tahoma, Arial,sans-serif;\n        margin: 0px;\n        padding: 2px 0px;\n}\n\n#projectbrief\n{\n        font: 120% Tahoma, Arial,sans-serif;\n        margin: 0px;\n        padding: 0px;\n}\n\n#projectnumber\n{\n        font: 100% Tahoma, Arial,sans-serif;\n        margin: 0px;\n        padding: 0px;\n}\n\n#titlearea\n{\n        padding: 0px;\n        margin: 0px;\n        width: 100%;\n        border-bottom: 1px solid #848484;\n}\n\n.image\n{\n        text-align: center;\n}\n\n.dotgraph\n{\n        text-align: center;\n}\n\n.mscgraph\n{\n        text-align: center;\n}\n\n.caption\n{\n        font-weight: bold;\n}\n\ndiv.zoom\n{\n        border: 1px solid #AFAFAF;\n}\n\ndl.citelist {\n        margin-bottom:50px;\n}\n\ndl.citelist dt {\n        color:#545454;\n        float:left;\n        font-weight:bold;\n        margin-right:10px;\n        padding:5px;\n}\n\ndl.citelist dd {\n        margin:2px 0;\n        padding:5px 0;\n}\n\ndiv.toc {\n        padding: 14px 25px;\n        background-color: #F7F7F7;\n        border: 1px solid #E3E3E3;\n        border-radius: 7px 7px 7px 7px;\n        float: right;\n        height: auto;\n        margin: 0 20px 10px 10px;\n        width: 200px;\n}\n\ndiv.toc li {\n        background: url(\"bdwn.png\") no-repeat scroll 0 5px transparent;\n        font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;\n        margin-top: 5px;\n        padding-left: 10px;\n        padding-top: 2px;\n}\n\ndiv.toc h3 {\n        font: bold 12px/1.2 Arial,FreeSans,sans-serif;\n        color: #747474;\n        border-bottom: 0 none;\n        margin: 0;\n}\n\ndiv.toc ul {\n        list-style: none outside none;\n        border: medium none;\n        padding: 0px;\n}\n\ndiv.toc li.level1 {\n        margin-left: 0px;\n}\n\ndiv.toc li.level2 {\n        margin-left: 15px;\n}\n\ndiv.toc li.level3 {\n        margin-left: 30px;\n}\n\ndiv.toc li.level4 {\n        margin-left: 45px;\n}\n\n\n@media print\n{\n  #top { display: none; }\n  #side-nav { display: none; }\n  #nav-path { display: none; }\n  body { overflow:visible; }\n  h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }\n  .summary { display: none; }\n  .memitem { page-break-inside: avoid; }\n  #doc-content\n  {\n    margin-left:0 !important;\n    height:auto !important;\n    width:auto !important;\n    overflow:inherit;\n    display:inline;\n  }\n  pre.fragment\n  {\n    overflow: visible;\n    text-wrap: unrestricted;\n    white-space: -moz-pre-wrap; /* Moz */\n    white-space: -pre-wrap; /* Opera 4-6 */\n    white-space: -o-pre-wrap; /* Opera 7 */\n    white-space: pre-wrap; /* CSS3  */\n    word-wrap: break-word; /* IE 5.5+ */\n  }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/doc/footer.html",
    "content": "<!--BEGIN GENERATE_TREEVIEW-->\n    <li class=\"footer\">$generatedby\n    <a href=\"http://www.doxygen.org/index.html\">\n    <img class=\"footer\" src=\"doxygen.png\" alt=\"doxygen\"/></a> $doxygenversion </li>\n   </ul>\n </div>\n<!--END GENERATE_TREEVIEW-->\n<!--BEGIN !GENERATE_TREEVIEW-->\n<hr class=\"footer\"/>\n<table width=\"100%\"><tbody><tr><td>\nFor more information visit the <a href=\"http://opus-codec.org\">Opus Website</a>.\n</td><td><address class=\"footer\"><small>\n&copy;$year<br/>\n$generatedby <a href=\"http://www.doxygen.org/index.html\">\n<!--<img class=\"footer\" src=\"$relpath$doxygen.png\" alt=\"doxygen\"/>-->doxygen\n</a> $doxygenversion\n</small></address></tr></tbody></table>\n<!--END !GENERATE_TREEVIEW-->\n</body>\n</html>\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/doc/header.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=9\"/>\n<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->\n<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->\n<link href=\"$relpath$tabs.css\" rel=\"stylesheet\" type=\"text/css\"/>\n<link href=\"$relpath$customdoxygen.css\" rel=\"stylesheet\" type=\"text/css\" />\n$treeview\n$search\n$mathjax\n</head>\n<body>\n<div id=\"top\"><!-- do not remove this div! -->\n\n<!--BEGIN TITLEAREA-->\n<div id=\"titlearea\">\n<table cellspacing=\"0\" cellpadding=\"0\">\n <tbody>\n <tr style=\"height: 64px;\">\n  <!--BEGIN PROJECT_LOGO-->\n  <td id=\"projectlogo\"><img alt=\"Logo\" src=\"$relpath$$projectlogo\"/></td>\n  <!--END PROJECT_LOGO-->\n  <!--BEGIN PROJECT_NAME-->\n  <td style=\"padding-left: 0.5em;\">\n  <div id=\"projectname\"><img src=\"opus_logo.svg\" width=112 height=64 alt=\"Opus\"/><!--$projectname--></div>\n  </td>\n  <td><table style=\"padding-left: 0.5em;\" cellspacing=\"0\" cellpadding=\"0\"><tbody>\n   <tr><td>\n   <!--BEGIN PROJECT_BRIEF--><div id=\"projectbrief\">$projectbrief</div><!--END PROJECT_BRIEF-->\n   </td></tr>\n  <td><!--BEGIN PROJECT_NUMBER--><span id=\"projectnumber\">$projectnumber</span><!--END PROJECT_NUMBER-->\n   </td></tr>\n   </table>\n  </td>\n  <!--END PROJECT_NAME-->\n  <!--BEGIN !PROJECT_NAME-->\n   <!--BEGIN PROJECT_BRIEF-->\n    <td style=\"padding-left: 0.5em;\">\n    <div id=\"projectbrief\">$projectbrief</div>\n    </td>\n   <!--END PROJECT_BRIEF-->\n  <!--END !PROJECT_NAME-->\n  <!--BEGIN DISABLE_INDEX-->\n   <!--BEGIN SEARCHENGINE-->\n   <td>$searchbox</td>\n   <!--END SEARCHENGINE-->\n  <!--END DISABLE_INDEX-->\n </tr>\n </tbody>\n</table>\n</div>\n<!--END TITLEAREA-->\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/doc/trivial_example.c",
    "content": "/* Copyright (c) 2013 Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/* This is meant to be a simple example of encoding and decoding audio\n   using Opus. It should make it easy to understand how the Opus API\n   works. For more information, see the full API documentation at:\n   http://www.opus-codec.org/docs/ */\n\n#include <stdlib.h>\n#include <errno.h>\n#include <string.h>\n#include <opus.h>\n#include <stdio.h>\n\n/*The frame size is hardcoded for this sample code but it doesn't have to be*/\n#define FRAME_SIZE 960\n#define SAMPLE_RATE 48000\n#define CHANNELS 2\n#define APPLICATION OPUS_APPLICATION_AUDIO\n#define BITRATE 64000\n\n#define MAX_FRAME_SIZE 6*960\n#define MAX_PACKET_SIZE (3*1276)\n\nint main(int argc, char **argv)\n{\n   char *inFile;\n   FILE *fin;\n   char *outFile;\n   FILE *fout;\n   opus_int16 in[FRAME_SIZE*CHANNELS];\n   opus_int16 out[MAX_FRAME_SIZE*CHANNELS];\n   unsigned char cbits[MAX_PACKET_SIZE];\n   int nbBytes;\n   /*Holds the state of the encoder and decoder */\n   OpusEncoder *encoder;\n   OpusDecoder *decoder;\n   int err;\n\n   if (argc != 3)\n   {\n      fprintf(stderr, \"usage: trivial_example input.pcm output.pcm\\n\");\n      fprintf(stderr, \"input and output are 16-bit little-endian raw files\\n\");\n      return EXIT_FAILURE;\n   }\n\n   /*Create a new encoder state */\n   encoder = opus_encoder_create(SAMPLE_RATE, CHANNELS, APPLICATION, &err);\n   if (err<0)\n   {\n      fprintf(stderr, \"failed to create an encoder: %s\\n\", opus_strerror(err));\n      return EXIT_FAILURE;\n   }\n   /* Set the desired bit-rate. You can also set other parameters if needed.\n      The Opus library is designed to have good defaults, so only set\n      parameters you know you need. Doing otherwise is likely to result\n      in worse quality, but better. */\n   err = opus_encoder_ctl(encoder, OPUS_SET_BITRATE(BITRATE));\n   if (err<0)\n   {\n      fprintf(stderr, \"failed to set bitrate: %s\\n\", opus_strerror(err));\n      return EXIT_FAILURE;\n   }\n   inFile = argv[1];\n   fin = fopen(inFile, \"r\");\n   if (fin==NULL)\n   {\n      fprintf(stderr, \"failed to open input file: %s\\n\", strerror(errno));\n      return EXIT_FAILURE;\n   }\n\n\n   /* Create a new decoder state. */\n   decoder = opus_decoder_create(SAMPLE_RATE, CHANNELS, &err);\n   if (err<0)\n   {\n      fprintf(stderr, \"failed to create decoder: %s\\n\", opus_strerror(err));\n      return EXIT_FAILURE;\n   }\n   outFile = argv[2];\n   fout = fopen(outFile, \"w\");\n   if (fout==NULL)\n   {\n      fprintf(stderr, \"failed to open output file: %s\\n\", strerror(errno));\n      return EXIT_FAILURE;\n   }\n\n   while (1)\n   {\n      int i;\n      unsigned char pcm_bytes[MAX_FRAME_SIZE*CHANNELS*2];\n      int frame_size;\n\n      /* Read a 16 bits/sample audio frame. */\n      fread(pcm_bytes, sizeof(short)*CHANNELS, FRAME_SIZE, fin);\n      if (feof(fin))\n         break;\n      /* Convert from little-endian ordering. */\n      for (i=0;i<CHANNELS*FRAME_SIZE;i++)\n         in[i]=pcm_bytes[2*i+1]<<8|pcm_bytes[2*i];\n\n      /* Encode the frame. */\n      nbBytes = opus_encode(encoder, in, FRAME_SIZE, cbits, MAX_PACKET_SIZE);\n      if (nbBytes<0)\n      {\n         fprintf(stderr, \"encode failed: %s\\n\", opus_strerror(nbBytes));\n         return EXIT_FAILURE;\n      }\n\n\n      /* Decode the data. In this example, frame_size will be constant because\n         the encoder is using a constant frame size. However, that may not\n         be the case for all encoders, so the decoder must always check\n         the frame size returned. */\n      frame_size = opus_decode(decoder, cbits, nbBytes, out, MAX_FRAME_SIZE, 0);\n      if (frame_size<0)\n      {\n         fprintf(stderr, \"decoder failed: %s\\n\", opus_strerror(frame_size));\n         return EXIT_FAILURE;\n      }\n\n      /* Convert to little-endian ordering. */\n      for(i=0;i<CHANNELS*frame_size;i++)\n      {\n         pcm_bytes[2*i]=out[i]&0xFF;\n         pcm_bytes[2*i+1]=(out[i]>>8)&0xFF;\n      }\n      /* Write the decoded audio to file. */\n      fwrite(pcm_bytes, sizeof(short), frame_size*CHANNELS, fout);\n   }\n   /*Destroy the encoder state*/\n   opus_encoder_destroy(encoder);\n   opus_decoder_destroy(decoder);\n   fclose(fin);\n   fclose(fout);\n   return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/include/opus.h",
    "content": "/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited\n   Written by Jean-Marc Valin and Koen Vos */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/**\n * @file opus.h\n * @brief Opus reference implementation API\n */\n\n#ifndef OPUS_H\n#define OPUS_H\n\n#include \"opus_types.h\"\n#include \"opus_defines.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * @mainpage Opus\n *\n * The Opus codec is designed for interactive speech and audio transmission over the Internet.\n * It is designed by the IETF Codec Working Group and incorporates technology from\n * Skype's SILK codec and Xiph.Org's CELT codec.\n *\n * The Opus codec is designed to handle a wide range of interactive audio applications,\n * including Voice over IP, videoconferencing, in-game chat, and even remote live music\n * performances. It can scale from low bit-rate narrowband speech to very high quality\n * stereo music. Its main features are:\n\n * @li Sampling rates from 8 to 48 kHz\n * @li Bit-rates from 6 kb/s to 510 kb/s\n * @li Support for both constant bit-rate (CBR) and variable bit-rate (VBR)\n * @li Audio bandwidth from narrowband to full-band\n * @li Support for speech and music\n * @li Support for mono and stereo\n * @li Support for multichannel (up to 255 channels)\n * @li Frame sizes from 2.5 ms to 60 ms\n * @li Good loss robustness and packet loss concealment (PLC)\n * @li Floating point and fixed-point implementation\n *\n * Documentation sections:\n * @li @ref opus_encoder\n * @li @ref opus_decoder\n * @li @ref opus_repacketizer\n * @li @ref opus_multistream\n * @li @ref opus_libinfo\n * @li @ref opus_custom\n */\n\n/** @defgroup opus_encoder Opus Encoder\n  * @{\n  *\n  * @brief This page describes the process and functions used to encode Opus.\n  *\n  * Since Opus is a stateful codec, the encoding process starts with creating an encoder\n  * state. This can be done with:\n  *\n  * @code\n  * int          error;\n  * OpusEncoder *enc;\n  * enc = opus_encoder_create(Fs, channels, application, &error);\n  * @endcode\n  *\n  * From this point, @c enc can be used for encoding an audio stream. An encoder state\n  * @b must @b not be used for more than one stream at the same time. Similarly, the encoder\n  * state @b must @b not be re-initialized for each frame.\n  *\n  * While opus_encoder_create() allocates memory for the state, it's also possible\n  * to initialize pre-allocated memory:\n  *\n  * @code\n  * int          size;\n  * int          error;\n  * OpusEncoder *enc;\n  * size = opus_encoder_get_size(channels);\n  * enc = malloc(size);\n  * error = opus_encoder_init(enc, Fs, channels, application);\n  * @endcode\n  *\n  * where opus_encoder_get_size() returns the required size for the encoder state. Note that\n  * future versions of this code may change the size, so no assuptions should be made about it.\n  *\n  * The encoder state is always continuous in memory and only a shallow copy is sufficient\n  * to copy it (e.g. memcpy())\n  *\n  * It is possible to change some of the encoder's settings using the opus_encoder_ctl()\n  * interface. All these settings already default to the recommended value, so they should\n  * only be changed when necessary. The most common settings one may want to change are:\n  *\n  * @code\n  * opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate));\n  * opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));\n  * opus_encoder_ctl(enc, OPUS_SET_SIGNAL(signal_type));\n  * @endcode\n  *\n  * where\n  *\n  * @arg bitrate is in bits per second (b/s)\n  * @arg complexity is a value from 1 to 10, where 1 is the lowest complexity and 10 is the highest\n  * @arg signal_type is either OPUS_AUTO (default), OPUS_SIGNAL_VOICE, or OPUS_SIGNAL_MUSIC\n  *\n  * See @ref opus_encoderctls and @ref opus_genericctls for a complete list of parameters that can be set or queried. Most parameters can be set or changed at any time during a stream.\n  *\n  * To encode a frame, opus_encode() or opus_encode_float() must be called with exactly one frame (2.5, 5, 10, 20, 40 or 60 ms) of audio data:\n  * @code\n  * len = opus_encode(enc, audio_frame, frame_size, packet, max_packet);\n  * @endcode\n  *\n  * where\n  * <ul>\n  * <li>audio_frame is the audio data in opus_int16 (or float for opus_encode_float())</li>\n  * <li>frame_size is the duration of the frame in samples (per channel)</li>\n  * <li>packet is the byte array to which the compressed data is written</li>\n  * <li>max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended).\n  *     Do not use max_packet to control VBR target bitrate, instead use the #OPUS_SET_BITRATE CTL.</li>\n  * </ul>\n  *\n  * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet.\n  * The return value <b>can be negative</b>, which indicates that an error has occurred. If the return value\n  * is 1 byte, then the packet does not need to be transmitted (DTX).\n  *\n  * Once the encoder state if no longer needed, it can be destroyed with\n  *\n  * @code\n  * opus_encoder_destroy(enc);\n  * @endcode\n  *\n  * If the encoder was created with opus_encoder_init() rather than opus_encoder_create(),\n  * then no action is required aside from potentially freeing the memory that was manually\n  * allocated for it (calling free(enc) for the example above)\n  *\n  */\n\n/** Opus encoder state.\n  * This contains the complete state of an Opus encoder.\n  * It is position independent and can be freely copied.\n  * @see opus_encoder_create,opus_encoder_init\n  */\ntypedef struct OpusEncoder OpusEncoder;\n\n/** Gets the size of an <code>OpusEncoder</code> structure.\n  * @param[in] channels <tt>int</tt>: Number of channels.\n  *                                   This must be 1 or 2.\n  * @returns The size in bytes.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels);\n\n/**\n */\n\n/** Allocates and initializes an encoder state.\n * There are three coding modes:\n *\n * @ref OPUS_APPLICATION_VOIP gives best quality at a given bitrate for voice\n *    signals. It enhances the  input signal by high-pass filtering and\n *    emphasizing formants and harmonics. Optionally  it includes in-band\n *    forward error correction to protect against packet loss. Use this\n *    mode for typical VoIP applications. Because of the enhancement,\n *    even at high bitrates the output may sound different from the input.\n *\n * @ref OPUS_APPLICATION_AUDIO gives best quality at a given bitrate for most\n *    non-voice signals like music. Use this mode for music and mixed\n *    (music/voice) content, broadcast, and applications requiring less\n *    than 15 ms of coding delay.\n *\n * @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that\n *    disables the speech-optimized mode in exchange for slightly reduced delay.\n *    This mode can only be set on an newly initialized or freshly reset encoder\n *    because it changes the codec delay.\n *\n * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution).\n * @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz)\n *                                     This must be one of 8000, 12000, 16000,\n *                                     24000, or 48000.\n * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal\n * @param [in] application <tt>int</tt>: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY)\n * @param [out] error <tt>int*</tt>: @ref opus_errorcodes\n * @note Regardless of the sampling rate and number channels selected, the Opus encoder\n * can switch to a lower audio bandwidth or number of channels if the bitrate\n * selected is too low. This also means that it is safe to always use 48 kHz stereo input\n * and let the encoder optimize the encoding.\n */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create(\n    opus_int32 Fs,\n    int channels,\n    int application,\n    int *error\n);\n\n/** Initializes a previously allocated encoder state\n  * The memory pointed to by st must be at least the size returned by opus_encoder_get_size().\n  * This is intended for applications which use their own allocator instead of malloc.\n  * @see opus_encoder_create(),opus_encoder_get_size()\n  * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.\n  * @param [in] st <tt>OpusEncoder*</tt>: Encoder state\n  * @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz)\n *                                      This must be one of 8000, 12000, 16000,\n *                                      24000, or 48000.\n  * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal\n  * @param [in] application <tt>int</tt>: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY)\n  * @retval #OPUS_OK Success or @ref opus_errorcodes\n  */\nOPUS_EXPORT int opus_encoder_init(\n    OpusEncoder *st,\n    opus_int32 Fs,\n    int channels,\n    int application\n) OPUS_ARG_NONNULL(1);\n\n/** Encodes an Opus frame.\n  * @param [in] st <tt>OpusEncoder*</tt>: Encoder state\n  * @param [in] pcm <tt>opus_int16*</tt>: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16)\n  * @param [in] frame_size <tt>int</tt>: Number of samples per channel in the\n  *                                      input signal.\n  *                                      This must be an Opus frame size for\n  *                                      the encoder's sampling rate.\n  *                                      For example, at 48 kHz the permitted\n  *                                      values are 120, 240, 480, 960, 1920,\n  *                                      and 2880.\n  *                                      Passing in a duration of less than\n  *                                      10 ms (480 samples at 48 kHz) will\n  *                                      prevent the encoder from using the LPC\n  *                                      or hybrid modes.\n  * @param [out] data <tt>unsigned char*</tt>: Output payload.\n  *                                            This must contain storage for at\n  *                                            least \\a max_data_bytes.\n  * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated\n  *                                                 memory for the output\n  *                                                 payload. This may be\n  *                                                 used to impose an upper limit on\n  *                                                 the instant bitrate, but should\n  *                                                 not be used as the only bitrate\n  *                                                 control. Use #OPUS_SET_BITRATE to\n  *                                                 control the bitrate.\n  * @returns The length of the encoded packet (in bytes) on success or a\n  *          negative error code (see @ref opus_errorcodes) on failure.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode(\n    OpusEncoder *st,\n    const opus_int16 *pcm,\n    int frame_size,\n    unsigned char *data,\n    opus_int32 max_data_bytes\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);\n\n/** Encodes an Opus frame from floating point input.\n  * @param [in] st <tt>OpusEncoder*</tt>: Encoder state\n  * @param [in] pcm <tt>float*</tt>: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0.\n  *          Samples with a range beyond +/-1.0 are supported but will\n  *          be clipped by decoders using the integer API and should\n  *          only be used if it is known that the far end supports\n  *          extended dynamic range.\n  *          length is frame_size*channels*sizeof(float)\n  * @param [in] frame_size <tt>int</tt>: Number of samples per channel in the\n  *                                      input signal.\n  *                                      This must be an Opus frame size for\n  *                                      the encoder's sampling rate.\n  *                                      For example, at 48 kHz the permitted\n  *                                      values are 120, 240, 480, 960, 1920,\n  *                                      and 2880.\n  *                                      Passing in a duration of less than\n  *                                      10 ms (480 samples at 48 kHz) will\n  *                                      prevent the encoder from using the LPC\n  *                                      or hybrid modes.\n  * @param [out] data <tt>unsigned char*</tt>: Output payload.\n  *                                            This must contain storage for at\n  *                                            least \\a max_data_bytes.\n  * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated\n  *                                                 memory for the output\n  *                                                 payload. This may be\n  *                                                 used to impose an upper limit on\n  *                                                 the instant bitrate, but should\n  *                                                 not be used as the only bitrate\n  *                                                 control. Use #OPUS_SET_BITRATE to\n  *                                                 control the bitrate.\n  * @returns The length of the encoded packet (in bytes) on success or a\n  *          negative error code (see @ref opus_errorcodes) on failure.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float(\n    OpusEncoder *st,\n    const float *pcm,\n    int frame_size,\n    unsigned char *data,\n    opus_int32 max_data_bytes\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);\n\n/** Frees an <code>OpusEncoder</code> allocated by opus_encoder_create().\n  * @param[in] st <tt>OpusEncoder*</tt>: State to be freed.\n  */\nOPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st);\n\n/** Perform a CTL function on an Opus encoder.\n  *\n  * Generally the request and subsequent arguments are generated\n  * by a convenience macro.\n  * @param st <tt>OpusEncoder*</tt>: Encoder state.\n  * @param request This and all remaining parameters should be replaced by one\n  *                of the convenience macros in @ref opus_genericctls or\n  *                @ref opus_encoderctls.\n  * @see opus_genericctls\n  * @see opus_encoderctls\n  */\nOPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);\n/**@}*/\n\n/** @defgroup opus_decoder Opus Decoder\n  * @{\n  *\n  * @brief This page describes the process and functions used to decode Opus.\n  *\n  * The decoding process also starts with creating a decoder\n  * state. This can be done with:\n  * @code\n  * int          error;\n  * OpusDecoder *dec;\n  * dec = opus_decoder_create(Fs, channels, &error);\n  * @endcode\n  * where\n  * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000\n  * @li channels is the number of channels (1 or 2)\n  * @li error will hold the error code in case of failure (or #OPUS_OK on success)\n  * @li the return value is a newly created decoder state to be used for decoding\n  *\n  * While opus_decoder_create() allocates memory for the state, it's also possible\n  * to initialize pre-allocated memory:\n  * @code\n  * int          size;\n  * int          error;\n  * OpusDecoder *dec;\n  * size = opus_decoder_get_size(channels);\n  * dec = malloc(size);\n  * error = opus_decoder_init(dec, Fs, channels);\n  * @endcode\n  * where opus_decoder_get_size() returns the required size for the decoder state. Note that\n  * future versions of this code may change the size, so no assuptions should be made about it.\n  *\n  * The decoder state is always continuous in memory and only a shallow copy is sufficient\n  * to copy it (e.g. memcpy())\n  *\n  * To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data:\n  * @code\n  * frame_size = opus_decode(dec, packet, len, decoded, max_size, 0);\n  * @endcode\n  * where\n  *\n  * @li packet is the byte array containing the compressed data\n  * @li len is the exact number of bytes contained in the packet\n  * @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float())\n  * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array\n  *\n  * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet.\n  * If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio\n  * buffer is too small to hold the decoded audio.\n  *\n  * Opus is a stateful codec with overlapping blocks and as a result Opus\n  * packets are not coded independently of each other. Packets must be\n  * passed into the decoder serially and in the correct order for a correct\n  * decode. Lost packets can be replaced with loss concealment by calling\n  * the decoder with a null pointer and zero length for the missing packet.\n  *\n  * A single codec state may only be accessed from a single thread at\n  * a time and any required locking must be performed by the caller. Separate\n  * streams must be decoded with separate decoder states and can be decoded\n  * in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK\n  * defined.\n  *\n  */\n\n/** Opus decoder state.\n  * This contains the complete state of an Opus decoder.\n  * It is position independent and can be freely copied.\n  * @see opus_decoder_create,opus_decoder_init\n  */\ntypedef struct OpusDecoder OpusDecoder;\n\n/** Gets the size of an <code>OpusDecoder</code> structure.\n  * @param [in] channels <tt>int</tt>: Number of channels.\n  *                                    This must be 1 or 2.\n  * @returns The size in bytes.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels);\n\n/** Allocates and initializes a decoder state.\n  * @param [in] Fs <tt>opus_int32</tt>: Sample rate to decode at (Hz).\n  *                                     This must be one of 8000, 12000, 16000,\n  *                                     24000, or 48000.\n  * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode\n  * @param [out] error <tt>int*</tt>: #OPUS_OK Success or @ref opus_errorcodes\n  *\n  * Internally Opus stores data at 48000 Hz, so that should be the default\n  * value for Fs. However, the decoder can efficiently decode to buffers\n  * at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use\n  * data at the full sample rate, or knows the compressed data doesn't\n  * use the full frequency range, it can request decoding at a reduced\n  * rate. Likewise, the decoder is capable of filling in either mono or\n  * interleaved stereo pcm buffers, at the caller's request.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create(\n    opus_int32 Fs,\n    int channels,\n    int *error\n);\n\n/** Initializes a previously allocated decoder state.\n  * The state must be at least the size returned by opus_decoder_get_size().\n  * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size\n  * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.\n  * @param [in] st <tt>OpusDecoder*</tt>: Decoder state.\n  * @param [in] Fs <tt>opus_int32</tt>: Sampling rate to decode to (Hz).\n  *                                     This must be one of 8000, 12000, 16000,\n  *                                     24000, or 48000.\n  * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode\n  * @retval #OPUS_OK Success or @ref opus_errorcodes\n  */\nOPUS_EXPORT int opus_decoder_init(\n    OpusDecoder *st,\n    opus_int32 Fs,\n    int channels\n) OPUS_ARG_NONNULL(1);\n\n/** Decode an Opus packet.\n  * @param [in] st <tt>OpusDecoder*</tt>: Decoder state\n  * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss\n  * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload*\n  * @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length\n  *  is frame_size*channels*sizeof(opus_int16)\n  * @param [in] frame_size Number of samples per channel of available space in \\a pcm.\n  *  If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will\n  *  not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),\n  *  then frame_size needs to be exactly the duration of audio that is missing, otherwise the\n  *  decoder will not be in the optimal state to decode the next incoming packet. For the PLC and\n  *  FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.\n  * @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be\n  *  decoded. If no such data is available, the frame is decoded as if it were lost.\n  * @returns Number of decoded samples or @ref opus_errorcodes\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode(\n    OpusDecoder *st,\n    const unsigned char *data,\n    opus_int32 len,\n    opus_int16 *pcm,\n    int frame_size,\n    int decode_fec\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);\n\n/** Decode an Opus packet with floating point output.\n  * @param [in] st <tt>OpusDecoder*</tt>: Decoder state\n  * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss\n  * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload\n  * @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length\n  *  is frame_size*channels*sizeof(float)\n  * @param [in] frame_size Number of samples per channel of available space in \\a pcm.\n  *  If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will\n  *  not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),\n  *  then frame_size needs to be exactly the duration of audio that is missing, otherwise the\n  *  decoder will not be in the optimal state to decode the next incoming packet. For the PLC and\n  *  FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.\n  * @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be\n  *  decoded. If no such data is available the frame is decoded as if it were lost.\n  * @returns Number of decoded samples or @ref opus_errorcodes\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float(\n    OpusDecoder *st,\n    const unsigned char *data,\n    opus_int32 len,\n    float *pcm,\n    int frame_size,\n    int decode_fec\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);\n\n/** Perform a CTL function on an Opus decoder.\n  *\n  * Generally the request and subsequent arguments are generated\n  * by a convenience macro.\n  * @param st <tt>OpusDecoder*</tt>: Decoder state.\n  * @param request This and all remaining parameters should be replaced by one\n  *                of the convenience macros in @ref opus_genericctls or\n  *                @ref opus_decoderctls.\n  * @see opus_genericctls\n  * @see opus_decoderctls\n  */\nOPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);\n\n/** Frees an <code>OpusDecoder</code> allocated by opus_decoder_create().\n  * @param[in] st <tt>OpusDecoder*</tt>: State to be freed.\n  */\nOPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st);\n\n/** Parse an opus packet into one or more frames.\n  * Opus_decode will perform this operation internally so most applications do\n  * not need to use this function.\n  * This function does not copy the frames, the returned pointers are pointers into\n  * the input packet.\n  * @param [in] data <tt>char*</tt>: Opus packet to be parsed\n  * @param [in] len <tt>opus_int32</tt>: size of data\n  * @param [out] out_toc <tt>char*</tt>: TOC pointer\n  * @param [out] frames <tt>char*[48]</tt> encapsulated frames\n  * @param [out] size <tt>opus_int16[48]</tt> sizes of the encapsulated frames\n  * @param [out] payload_offset <tt>int*</tt>: returns the position of the payload within the packet (in bytes)\n  * @returns number of frames\n  */\nOPUS_EXPORT int opus_packet_parse(\n   const unsigned char *data,\n   opus_int32 len,\n   unsigned char *out_toc,\n   const unsigned char *frames[48],\n   opus_int16 size[48],\n   int *payload_offset\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);\n\n/** Gets the bandwidth of an Opus packet.\n  * @param [in] data <tt>char*</tt>: Opus packet\n  * @retval OPUS_BANDWIDTH_NARROWBAND Narrowband (4kHz bandpass)\n  * @retval OPUS_BANDWIDTH_MEDIUMBAND Mediumband (6kHz bandpass)\n  * @retval OPUS_BANDWIDTH_WIDEBAND Wideband (8kHz bandpass)\n  * @retval OPUS_BANDWIDTH_SUPERWIDEBAND Superwideband (12kHz bandpass)\n  * @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass)\n  * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_bandwidth(const unsigned char *data) OPUS_ARG_NONNULL(1);\n\n/** Gets the number of samples per frame from an Opus packet.\n  * @param [in] data <tt>char*</tt>: Opus packet.\n  *                                  This must contain at least one byte of\n  *                                  data.\n  * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz.\n  *                                     This must be a multiple of 400, or\n  *                                     inaccurate results will be returned.\n  * @returns Number of samples per frame.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) OPUS_ARG_NONNULL(1);\n\n/** Gets the number of channels from an Opus packet.\n  * @param [in] data <tt>char*</tt>: Opus packet\n  * @returns Number of channels\n  * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsigned char *data) OPUS_ARG_NONNULL(1);\n\n/** Gets the number of frames in an Opus packet.\n  * @param [in] packet <tt>char*</tt>: Opus packet\n  * @param [in] len <tt>opus_int32</tt>: Length of packet\n  * @returns Number of frames\n  * @retval OPUS_BAD_ARG Insufficient data was passed to the function\n  * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1);\n\n/** Gets the number of samples of an Opus packet.\n  * @param [in] packet <tt>char*</tt>: Opus packet\n  * @param [in] len <tt>opus_int32</tt>: Length of packet\n  * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz.\n  *                                     This must be a multiple of 400, or\n  *                                     inaccurate results will be returned.\n  * @returns Number of samples\n  * @retval OPUS_BAD_ARG Insufficient data was passed to the function\n  * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1);\n\n/** Gets the number of samples of an Opus packet.\n  * @param [in] dec <tt>OpusDecoder*</tt>: Decoder state\n  * @param [in] packet <tt>char*</tt>: Opus packet\n  * @param [in] len <tt>opus_int32</tt>: Length of packet\n  * @returns Number of samples\n  * @retval OPUS_BAD_ARG Insufficient data was passed to the function\n  * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);\n\n/** Applies soft-clipping to bring a float signal within the [-1,1] range. If\n  * the signal is already in that range, nothing is done. If there are values\n  * outside of [-1,1], then the signal is clipped as smoothly as possible to\n  * both fit in the range and avoid creating excessive distortion in the\n  * process.\n  * @param [in,out] pcm <tt>float*</tt>: Input PCM and modified PCM\n  * @param [in] frame_size <tt>int</tt> Number of samples per channel to process\n  * @param [in] channels <tt>int</tt>: Number of channels\n  * @param [in,out] softclip_mem <tt>float*</tt>: State memory for the soft clipping process (one float per channel, initialized to zero)\n  */\nOPUS_EXPORT void opus_pcm_soft_clip(float *pcm, int frame_size, int channels, float *softclip_mem);\n\n\n/**@}*/\n\n/** @defgroup opus_repacketizer Repacketizer\n  * @{\n  *\n  * The repacketizer can be used to merge multiple Opus packets into a single\n  * packet or alternatively to split Opus packets that have previously been\n  * merged. Splitting valid Opus packets is always guaranteed to succeed,\n  * whereas merging valid packets only succeeds if all frames have the same\n  * mode, bandwidth, and frame size, and when the total duration of the merged\n  * packet is no more than 120 ms. The 120 ms limit comes from the\n  * specification and limits decoder memory requirements at a point where\n  * framing overhead becomes negligible.\n  *\n  * The repacketizer currently only operates on elementary Opus\n  * streams. It will not manipualte multistream packets successfully, except in\n  * the degenerate case where they consist of data from a single stream.\n  *\n  * The repacketizing process starts with creating a repacketizer state, either\n  * by calling opus_repacketizer_create() or by allocating the memory yourself,\n  * e.g.,\n  * @code\n  * OpusRepacketizer *rp;\n  * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size());\n  * if (rp != NULL)\n  *     opus_repacketizer_init(rp);\n  * @endcode\n  *\n  * Then the application should submit packets with opus_repacketizer_cat(),\n  * extract new packets with opus_repacketizer_out() or\n  * opus_repacketizer_out_range(), and then reset the state for the next set of\n  * input packets via opus_repacketizer_init().\n  *\n  * For example, to split a sequence of packets into individual frames:\n  * @code\n  * unsigned char *data;\n  * int len;\n  * while (get_next_packet(&data, &len))\n  * {\n  *   unsigned char out[1276];\n  *   opus_int32 out_len;\n  *   int nb_frames;\n  *   int err;\n  *   int i;\n  *   err = opus_repacketizer_cat(rp, data, len);\n  *   if (err != OPUS_OK)\n  *   {\n  *     release_packet(data);\n  *     return err;\n  *   }\n  *   nb_frames = opus_repacketizer_get_nb_frames(rp);\n  *   for (i = 0; i < nb_frames; i++)\n  *   {\n  *     out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out));\n  *     if (out_len < 0)\n  *     {\n  *        release_packet(data);\n  *        return (int)out_len;\n  *     }\n  *     output_next_packet(out, out_len);\n  *   }\n  *   opus_repacketizer_init(rp);\n  *   release_packet(data);\n  * }\n  * @endcode\n  *\n  * Alternatively, to combine a sequence of frames into packets that each\n  * contain up to <code>TARGET_DURATION_MS</code> milliseconds of data:\n  * @code\n  * // The maximum number of packets with duration TARGET_DURATION_MS occurs\n  * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5)\n  * // packets.\n  * unsigned char *data[(TARGET_DURATION_MS*2/5)+1];\n  * opus_int32 len[(TARGET_DURATION_MS*2/5)+1];\n  * int nb_packets;\n  * unsigned char out[1277*(TARGET_DURATION_MS*2/2)];\n  * opus_int32 out_len;\n  * int prev_toc;\n  * nb_packets = 0;\n  * while (get_next_packet(data+nb_packets, len+nb_packets))\n  * {\n  *   int nb_frames;\n  *   int err;\n  *   nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]);\n  *   if (nb_frames < 1)\n  *   {\n  *     release_packets(data, nb_packets+1);\n  *     return nb_frames;\n  *   }\n  *   nb_frames += opus_repacketizer_get_nb_frames(rp);\n  *   // If adding the next packet would exceed our target, or it has an\n  *   // incompatible TOC sequence, output the packets we already have before\n  *   // submitting it.\n  *   // N.B., The nb_packets > 0 check ensures we've submitted at least one\n  *   // packet since the last call to opus_repacketizer_init(). Otherwise a\n  *   // single packet longer than TARGET_DURATION_MS would cause us to try to\n  *   // output an (invalid) empty packet. It also ensures that prev_toc has\n  *   // been set to a valid value. Additionally, len[nb_packets] > 0 is\n  *   // guaranteed by the call to opus_packet_get_nb_frames() above, so the\n  *   // reference to data[nb_packets][0] should be valid.\n  *   if (nb_packets > 0 && (\n  *       ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) ||\n  *       opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames >\n  *       TARGET_DURATION_MS*48))\n  *   {\n  *     out_len = opus_repacketizer_out(rp, out, sizeof(out));\n  *     if (out_len < 0)\n  *     {\n  *        release_packets(data, nb_packets+1);\n  *        return (int)out_len;\n  *     }\n  *     output_next_packet(out, out_len);\n  *     opus_repacketizer_init(rp);\n  *     release_packets(data, nb_packets);\n  *     data[0] = data[nb_packets];\n  *     len[0] = len[nb_packets];\n  *     nb_packets = 0;\n  *   }\n  *   err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]);\n  *   if (err != OPUS_OK)\n  *   {\n  *     release_packets(data, nb_packets+1);\n  *     return err;\n  *   }\n  *   prev_toc = data[nb_packets][0];\n  *   nb_packets++;\n  * }\n  * // Output the final, partial packet.\n  * if (nb_packets > 0)\n  * {\n  *   out_len = opus_repacketizer_out(rp, out, sizeof(out));\n  *   release_packets(data, nb_packets);\n  *   if (out_len < 0)\n  *     return (int)out_len;\n  *   output_next_packet(out, out_len);\n  * }\n  * @endcode\n  *\n  * An alternate way of merging packets is to simply call opus_repacketizer_cat()\n  * unconditionally until it fails. At that point, the merged packet can be\n  * obtained with opus_repacketizer_out() and the input packet for which\n  * opus_repacketizer_cat() needs to be re-added to a newly reinitialized\n  * repacketizer state.\n  */\n\ntypedef struct OpusRepacketizer OpusRepacketizer;\n\n/** Gets the size of an <code>OpusRepacketizer</code> structure.\n  * @returns The size in bytes.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void);\n\n/** (Re)initializes a previously allocated repacketizer state.\n  * The state must be at least the size returned by opus_repacketizer_get_size().\n  * This can be used for applications which use their own allocator instead of\n  * malloc().\n  * It must also be called to reset the queue of packets waiting to be\n  * repacketized, which is necessary if the maximum packet duration of 120 ms\n  * is reached or if you wish to submit packets with a different Opus\n  * configuration (coding mode, audio bandwidth, frame size, or channel count).\n  * Failure to do so will prevent a new packet from being added with\n  * opus_repacketizer_cat().\n  * @see opus_repacketizer_create\n  * @see opus_repacketizer_get_size\n  * @see opus_repacketizer_cat\n  * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to\n  *                                       (re)initialize.\n  * @returns A pointer to the same repacketizer state that was passed in.\n  */\nOPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1);\n\n/** Allocates memory and initializes the new repacketizer with\n * opus_repacketizer_init().\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void);\n\n/** Frees an <code>OpusRepacketizer</code> allocated by\n  * opus_repacketizer_create().\n  * @param[in] rp <tt>OpusRepacketizer*</tt>: State to be freed.\n  */\nOPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp);\n\n/** Add a packet to the current repacketizer state.\n  * This packet must match the configuration of any packets already submitted\n  * for repacketization since the last call to opus_repacketizer_init().\n  * This means that it must have the same coding mode, audio bandwidth, frame\n  * size, and channel count.\n  * This can be checked in advance by examining the top 6 bits of the first\n  * byte of the packet, and ensuring they match the top 6 bits of the first\n  * byte of any previously submitted packet.\n  * The total duration of audio in the repacketizer state also must not exceed\n  * 120 ms, the maximum duration of a single packet, after adding this packet.\n  *\n  * The contents of the current repacketizer state can be extracted into new\n  * packets using opus_repacketizer_out() or opus_repacketizer_out_range().\n  *\n  * In order to add a packet with a different configuration or to add more\n  * audio beyond 120 ms, you must clear the repacketizer state by calling\n  * opus_repacketizer_init().\n  * If a packet is too large to add to the current repacketizer state, no part\n  * of it is added, even if it contains multiple frames, some of which might\n  * fit.\n  * If you wish to be able to add parts of such packets, you should first use\n  * another repacketizer to split the packet into pieces and add them\n  * individually.\n  * @see opus_repacketizer_out_range\n  * @see opus_repacketizer_out\n  * @see opus_repacketizer_init\n  * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to which to\n  *                                       add the packet.\n  * @param[in] data <tt>const unsigned char*</tt>: The packet data.\n  *                                                The application must ensure\n  *                                                this pointer remains valid\n  *                                                until the next call to\n  *                                                opus_repacketizer_init() or\n  *                                                opus_repacketizer_destroy().\n  * @param len <tt>opus_int32</tt>: The number of bytes in the packet data.\n  * @returns An error code indicating whether or not the operation succeeded.\n  * @retval #OPUS_OK The packet's contents have been added to the repacketizer\n  *                  state.\n  * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence,\n  *                              the packet's TOC sequence was not compatible\n  *                              with previously submitted packets (because\n  *                              the coding mode, audio bandwidth, frame size,\n  *                              or channel count did not match), or adding\n  *                              this packet would increase the total amount of\n  *                              audio stored in the repacketizer state to more\n  *                              than 120 ms.\n  */\nOPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);\n\n\n/** Construct a new packet from data previously submitted to the repacketizer\n  * state via opus_repacketizer_cat().\n  * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to\n  *                                       construct the new packet.\n  * @param begin <tt>int</tt>: The index of the first frame in the current\n  *                            repacketizer state to include in the output.\n  * @param end <tt>int</tt>: One past the index of the last frame in the\n  *                          current repacketizer state to include in the\n  *                          output.\n  * @param[out] data <tt>const unsigned char*</tt>: The buffer in which to\n  *                                                 store the output packet.\n  * @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in\n  *                                    the output buffer. In order to guarantee\n  *                                    success, this should be at least\n  *                                    <code>1276</code> for a single frame,\n  *                                    or for multiple frames,\n  *                                    <code>1277*(end-begin)</code>.\n  *                                    However, <code>1*(end-begin)</code> plus\n  *                                    the size of all packet data submitted to\n  *                                    the repacketizer since the last call to\n  *                                    opus_repacketizer_init() or\n  *                                    opus_repacketizer_create() is also\n  *                                    sufficient, and possibly much smaller.\n  * @returns The total size of the output packet on success, or an error code\n  *          on failure.\n  * @retval #OPUS_BAD_ARG <code>[begin,end)</code> was an invalid range of\n  *                       frames (begin < 0, begin >= end, or end >\n  *                       opus_repacketizer_get_nb_frames()).\n  * @retval #OPUS_BUFFER_TOO_SMALL \\a maxlen was insufficient to contain the\n  *                                complete output packet.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);\n\n/** Return the total number of frames contained in packet data submitted to\n  * the repacketizer state so far via opus_repacketizer_cat() since the last\n  * call to opus_repacketizer_init() or opus_repacketizer_create().\n  * This defines the valid range of packets that can be extracted with\n  * opus_repacketizer_out_range() or opus_repacketizer_out().\n  * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state containing the\n  *                                       frames.\n  * @returns The total number of frames contained in the packet data submitted\n  *          to the repacketizer state.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1);\n\n/** Construct a new packet from data previously submitted to the repacketizer\n  * state via opus_repacketizer_cat().\n  * This is a convenience routine that returns all the data submitted so far\n  * in a single packet.\n  * It is equivalent to calling\n  * @code\n  * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp),\n  *                             data, maxlen)\n  * @endcode\n  * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to\n  *                                       construct the new packet.\n  * @param[out] data <tt>const unsigned char*</tt>: The buffer in which to\n  *                                                 store the output packet.\n  * @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in\n  *                                    the output buffer. In order to guarantee\n  *                                    success, this should be at least\n  *                                    <code>1277*opus_repacketizer_get_nb_frames(rp)</code>.\n  *                                    However,\n  *                                    <code>1*opus_repacketizer_get_nb_frames(rp)</code>\n  *                                    plus the size of all packet data\n  *                                    submitted to the repacketizer since the\n  *                                    last call to opus_repacketizer_init() or\n  *                                    opus_repacketizer_create() is also\n  *                                    sufficient, and possibly much smaller.\n  * @returns The total size of the output packet on success, or an error code\n  *          on failure.\n  * @retval #OPUS_BUFFER_TOO_SMALL \\a maxlen was insufficient to contain the\n  *                                complete output packet.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1);\n\n/** Pads a given Opus packet to a larger size (possibly changing the TOC sequence).\n  * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the\n  *                                                   packet to pad.\n  * @param len <tt>opus_int32</tt>: The size of the packet.\n  *                                 This must be at least 1.\n  * @param new_len <tt>opus_int32</tt>: The desired size of the packet after padding.\n  *                                 This must be at least as large as len.\n  * @returns an error code\n  * @retval #OPUS_OK \\a on success.\n  * @retval #OPUS_BAD_ARG \\a len was less than 1 or new_len was less than len.\n  * @retval #OPUS_INVALID_PACKET \\a data did not contain a valid Opus packet.\n  */\nOPUS_EXPORT int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len);\n\n/** Remove all padding from a given Opus packet and rewrite the TOC sequence to\n  * minimize space usage.\n  * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the\n  *                                                   packet to strip.\n  * @param len <tt>opus_int32</tt>: The size of the packet.\n  *                                 This must be at least 1.\n  * @returns The new size of the output packet on success, or an error code\n  *          on failure.\n  * @retval #OPUS_BAD_ARG \\a len was less than 1.\n  * @retval #OPUS_INVALID_PACKET \\a data did not contain a valid Opus packet.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len);\n\n/** Pads a given Opus multi-stream packet to a larger size (possibly changing the TOC sequence).\n  * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the\n  *                                                   packet to pad.\n  * @param len <tt>opus_int32</tt>: The size of the packet.\n  *                                 This must be at least 1.\n  * @param new_len <tt>opus_int32</tt>: The desired size of the packet after padding.\n  *                                 This must be at least 1.\n  * @param nb_streams <tt>opus_int32</tt>: The number of streams (not channels) in the packet.\n  *                                 This must be at least as large as len.\n  * @returns an error code\n  * @retval #OPUS_OK \\a on success.\n  * @retval #OPUS_BAD_ARG \\a len was less than 1.\n  * @retval #OPUS_INVALID_PACKET \\a data did not contain a valid Opus packet.\n  */\nOPUS_EXPORT int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams);\n\n/** Remove all padding from a given Opus multi-stream packet and rewrite the TOC sequence to\n  * minimize space usage.\n  * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the\n  *                                                   packet to strip.\n  * @param len <tt>opus_int32</tt>: The size of the packet.\n  *                                 This must be at least 1.\n  * @param nb_streams <tt>opus_int32</tt>: The number of streams (not channels) in the packet.\n  *                                 This must be at least 1.\n  * @returns The new size of the output packet on success, or an error code\n  *          on failure.\n  * @retval #OPUS_BAD_ARG \\a len was less than 1 or new_len was less than len.\n  * @retval #OPUS_INVALID_PACKET \\a data did not contain a valid Opus packet.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, int nb_streams);\n\n/**@}*/\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* OPUS_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/include/opus_custom.h",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Copyright (c) 2008-2012 Gregory Maxwell\n   Written by Jean-Marc Valin and Gregory Maxwell */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/**\n  @file opus_custom.h\n  @brief Opus-Custom reference implementation API\n */\n\n#ifndef OPUS_CUSTOM_H\n#define OPUS_CUSTOM_H\n\n#include \"opus_defines.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifdef CUSTOM_MODES\n# define OPUS_CUSTOM_EXPORT OPUS_EXPORT\n# define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT\n#else\n# define OPUS_CUSTOM_EXPORT\n# ifdef OPUS_BUILD\n#  define OPUS_CUSTOM_EXPORT_STATIC static OPUS_INLINE\n# else\n#  define OPUS_CUSTOM_EXPORT_STATIC\n# endif\n#endif\n\n/** @defgroup opus_custom Opus Custom\n  * @{\n  *  Opus Custom is an optional part of the Opus specification and\n  * reference implementation which uses a distinct API from the regular\n  * API and supports frame sizes that are not normally supported.\\ Use\n  * of Opus Custom is discouraged for all but very special applications\n  * for which a frame size different from 2.5, 5, 10, or 20 ms is needed\n  * (for either complexity or latency reasons) and where interoperability\n  * is less important.\n  *\n  * In addition to the interoperability limitations the use of Opus custom\n  * disables a substantial chunk of the codec and generally lowers the\n  * quality available at a given bitrate. Normally when an application needs\n  * a different frame size from the codec it should buffer to match the\n  * sizes but this adds a small amount of delay which may be important\n  * in some very low latency applications. Some transports (especially\n  * constant rate RF transports) may also work best with frames of\n  * particular durations.\n  *\n  * Libopus only supports custom modes if they are enabled at compile time.\n  *\n  * The Opus Custom API is similar to the regular API but the\n  * @ref opus_encoder_create and @ref opus_decoder_create calls take\n  * an additional mode parameter which is a structure produced by\n  * a call to @ref opus_custom_mode_create. Both the encoder and decoder\n  * must create a mode using the same sample rate (fs) and frame size\n  * (frame size) so these parameters must either be signaled out of band\n  * or fixed in a particular implementation.\n  *\n  * Similar to regular Opus the custom modes support on the fly frame size\n  * switching, but the sizes available depend on the particular frame size in\n  * use. For some initial frame sizes on a single on the fly size is available.\n  */\n\n/** Contains the state of an encoder. One encoder state is needed\n    for each stream. It is initialized once at the beginning of the\n    stream. Do *not* re-initialize the state for every frame.\n   @brief Encoder state\n */\ntypedef struct OpusCustomEncoder OpusCustomEncoder;\n\n/** State of the decoder. One decoder state is needed for each stream.\n    It is initialized once at the beginning of the stream. Do *not*\n    re-initialize the state for every frame.\n   @brief Decoder state\n */\ntypedef struct OpusCustomDecoder OpusCustomDecoder;\n\n/** The mode contains all the information necessary to create an\n    encoder. Both the encoder and decoder need to be initialized\n    with exactly the same mode, otherwise the output will be\n    corrupted.\n   @brief Mode configuration\n */\ntypedef struct OpusCustomMode OpusCustomMode;\n\n/** Creates a new mode struct. This will be passed to an encoder or\n  * decoder. The mode MUST NOT BE DESTROYED until the encoders and\n  * decoders that use it are destroyed as well.\n  * @param [in] Fs <tt>int</tt>: Sampling rate (8000 to 96000 Hz)\n  * @param [in] frame_size <tt>int</tt>: Number of samples (per channel) to encode in each\n  *        packet (64 - 1024, prime factorization must contain zero or more 2s, 3s, or 5s and no other primes)\n  * @param [out] error <tt>int*</tt>: Returned error code (if NULL, no error will be returned)\n  * @return A newly created mode\n  */\nOPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error);\n\n/** Destroys a mode struct. Only call this after all encoders and\n  * decoders using this mode are destroyed as well.\n  * @param [in] mode <tt>OpusCustomMode*</tt>: Mode to be freed.\n  */\nOPUS_CUSTOM_EXPORT void opus_custom_mode_destroy(OpusCustomMode *mode);\n\n\n#if !defined(OPUS_BUILD) || defined(CELT_ENCODER_C)\n\n/* Encoder */\n/** Gets the size of an OpusCustomEncoder structure.\n  * @param [in] mode <tt>OpusCustomMode *</tt>: Mode configuration\n  * @param [in] channels <tt>int</tt>: Number of channels\n  * @returns size\n  */\nOPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_encoder_get_size(\n    const OpusCustomMode *mode,\n    int channels\n) OPUS_ARG_NONNULL(1);\n\n# ifdef CUSTOM_MODES\n/** Initializes a previously allocated encoder state\n  * The memory pointed to by st must be the size returned by opus_custom_encoder_get_size.\n  * This is intended for applications which use their own allocator instead of malloc.\n  * @see opus_custom_encoder_create(),opus_custom_encoder_get_size()\n  * To reset a previously initialized state use the OPUS_RESET_STATE CTL.\n  * @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state\n  * @param [in] mode <tt>OpusCustomMode *</tt>: Contains all the information about the characteristics of\n  *  the stream (must be the same characteristics as used for the\n  *  decoder)\n  * @param [in] channels <tt>int</tt>: Number of channels\n  * @return OPUS_OK Success or @ref opus_errorcodes\n  */\nOPUS_CUSTOM_EXPORT int opus_custom_encoder_init(\n    OpusCustomEncoder *st,\n    const OpusCustomMode *mode,\n    int channels\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);\n# endif\n#endif\n\n\n/** Creates a new encoder state. Each stream needs its own encoder\n  * state (can't be shared across simultaneous streams).\n  * @param [in] mode <tt>OpusCustomMode*</tt>: Contains all the information about the characteristics of\n  *  the stream (must be the same characteristics as used for the\n  *  decoder)\n  * @param [in] channels <tt>int</tt>: Number of channels\n  * @param [out] error <tt>int*</tt>: Returns an error code\n  * @return Newly created encoder state.\n*/\nOPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encoder_create(\n    const OpusCustomMode *mode,\n    int channels,\n    int *error\n) OPUS_ARG_NONNULL(1);\n\n\n/** Destroys a an encoder state.\n  * @param[in] st <tt>OpusCustomEncoder*</tt>: State to be freed.\n  */\nOPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st);\n\n/** Encodes a frame of audio.\n  * @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state\n  * @param [in] pcm <tt>float*</tt>: PCM audio in float format, with a normal range of +/-1.0.\n  *          Samples with a range beyond +/-1.0 are supported but will\n  *          be clipped by decoders using the integer API and should\n  *          only be used if it is known that the far end supports\n  *          extended dynamic range. There must be exactly\n  *          frame_size samples per channel.\n  * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal\n  * @param [out] compressed <tt>char *</tt>: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long.\n  * @param [in] maxCompressedBytes <tt>int</tt>: Maximum number of bytes to use for compressing the frame\n  *          (can change from one frame to another)\n  * @return Number of bytes written to \"compressed\".\n  *       If negative, an error has occurred (see error codes). It is IMPORTANT that\n  *       the length returned be somehow transmitted to the decoder. Otherwise, no\n  *       decoding is possible.\n  */\nOPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode_float(\n    OpusCustomEncoder *st,\n    const float *pcm,\n    int frame_size,\n    unsigned char *compressed,\n    int maxCompressedBytes\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);\n\n/** Encodes a frame of audio.\n  * @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state\n  * @param [in] pcm <tt>opus_int16*</tt>: PCM audio in signed 16-bit format (native endian).\n  *          There must be exactly frame_size samples per channel.\n  * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal\n  * @param [out] compressed <tt>char *</tt>: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long.\n  * @param [in] maxCompressedBytes <tt>int</tt>: Maximum number of bytes to use for compressing the frame\n  *          (can change from one frame to another)\n  * @return Number of bytes written to \"compressed\".\n  *       If negative, an error has occurred (see error codes). It is IMPORTANT that\n  *       the length returned be somehow transmitted to the decoder. Otherwise, no\n  *       decoding is possible.\n */\nOPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode(\n    OpusCustomEncoder *st,\n    const opus_int16 *pcm,\n    int frame_size,\n    unsigned char *compressed,\n    int maxCompressedBytes\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);\n\n/** Perform a CTL function on an Opus custom encoder.\n  *\n  * Generally the request and subsequent arguments are generated\n  * by a convenience macro.\n  * @see opus_encoderctls\n  */\nOPUS_CUSTOM_EXPORT int opus_custom_encoder_ctl(OpusCustomEncoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1);\n\n\n#if !defined(OPUS_BUILD) || defined(CELT_DECODER_C)\n/* Decoder */\n\n/** Gets the size of an OpusCustomDecoder structure.\n  * @param [in] mode <tt>OpusCustomMode *</tt>: Mode configuration\n  * @param [in] channels <tt>int</tt>: Number of channels\n  * @returns size\n  */\nOPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_decoder_get_size(\n    const OpusCustomMode *mode,\n    int channels\n) OPUS_ARG_NONNULL(1);\n\n/** Initializes a previously allocated decoder state\n  * The memory pointed to by st must be the size returned by opus_custom_decoder_get_size.\n  * This is intended for applications which use their own allocator instead of malloc.\n  * @see opus_custom_decoder_create(),opus_custom_decoder_get_size()\n  * To reset a previously initialized state use the OPUS_RESET_STATE CTL.\n  * @param [in] st <tt>OpusCustomDecoder*</tt>: Decoder state\n  * @param [in] mode <tt>OpusCustomMode *</tt>: Contains all the information about the characteristics of\n  *  the stream (must be the same characteristics as used for the\n  *  encoder)\n  * @param [in] channels <tt>int</tt>: Number of channels\n  * @return OPUS_OK Success or @ref opus_errorcodes\n  */\nOPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_init(\n    OpusCustomDecoder *st,\n    const OpusCustomMode *mode,\n    int channels\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);\n\n#endif\n\n\n/** Creates a new decoder state. Each stream needs its own decoder state (can't\n  * be shared across simultaneous streams).\n  * @param [in] mode <tt>OpusCustomMode</tt>: Contains all the information about the characteristics of the\n  *          stream (must be the same characteristics as used for the encoder)\n  * @param [in] channels <tt>int</tt>: Number of channels\n  * @param [out] error <tt>int*</tt>: Returns an error code\n  * @return Newly created decoder state.\n  */\nOPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decoder_create(\n    const OpusCustomMode *mode,\n    int channels,\n    int *error\n) OPUS_ARG_NONNULL(1);\n\n/** Destroys a an decoder state.\n  * @param[in] st <tt>OpusCustomDecoder*</tt>: State to be freed.\n  */\nOPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st);\n\n/** Decode an opus custom frame with floating point output\n  * @param [in] st <tt>OpusCustomDecoder*</tt>: Decoder state\n  * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss\n  * @param [in] len <tt>int</tt>: Number of bytes in payload\n  * @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length\n  *  is frame_size*channels*sizeof(float)\n  * @param [in] frame_size Number of samples per channel of available space in *pcm.\n  * @returns Number of decoded samples or @ref opus_errorcodes\n  */\nOPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode_float(\n    OpusCustomDecoder *st,\n    const unsigned char *data,\n    int len,\n    float *pcm,\n    int frame_size\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);\n\n/** Decode an opus custom frame\n  * @param [in] st <tt>OpusCustomDecoder*</tt>: Decoder state\n  * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss\n  * @param [in] len <tt>int</tt>: Number of bytes in payload\n  * @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length\n  *  is frame_size*channels*sizeof(opus_int16)\n  * @param [in] frame_size Number of samples per channel of available space in *pcm.\n  * @returns Number of decoded samples or @ref opus_errorcodes\n  */\nOPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode(\n    OpusCustomDecoder *st,\n    const unsigned char *data,\n    int len,\n    opus_int16 *pcm,\n    int frame_size\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);\n\n/** Perform a CTL function on an Opus custom decoder.\n  *\n  * Generally the request and subsequent arguments are generated\n  * by a convenience macro.\n  * @see opus_genericctls\n  */\nOPUS_CUSTOM_EXPORT int opus_custom_decoder_ctl(OpusCustomDecoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1);\n\n/**@}*/\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* OPUS_CUSTOM_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/include/opus_defines.h",
    "content": "/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited\n   Written by Jean-Marc Valin and Koen Vos */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/**\n * @file opus_defines.h\n * @brief Opus reference implementation constants\n */\n\n#ifndef OPUS_DEFINES_H\n#define OPUS_DEFINES_H\n\n#include \"opus_types.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** @defgroup opus_errorcodes Error codes\n * @{\n */\n/** No error @hideinitializer*/\n#define OPUS_OK                0\n/** One or more invalid/out of range arguments @hideinitializer*/\n#define OPUS_BAD_ARG          -1\n/** Not enough bytes allocated in the buffer @hideinitializer*/\n#define OPUS_BUFFER_TOO_SMALL -2\n/** An internal error was detected @hideinitializer*/\n#define OPUS_INTERNAL_ERROR   -3\n/** The compressed data passed is corrupted @hideinitializer*/\n#define OPUS_INVALID_PACKET   -4\n/** Invalid/unsupported request number @hideinitializer*/\n#define OPUS_UNIMPLEMENTED    -5\n/** An encoder or decoder structure is invalid or already freed @hideinitializer*/\n#define OPUS_INVALID_STATE    -6\n/** Memory allocation has failed @hideinitializer*/\n#define OPUS_ALLOC_FAIL       -7\n/**@}*/\n\n/** @cond OPUS_INTERNAL_DOC */\n/**Export control for opus functions */\n\n#ifndef OPUS_EXPORT\n# if defined(WIN32)\n#  ifdef OPUS_BUILD\n#   define OPUS_EXPORT __declspec(dllexport)\n#  else\n#   define OPUS_EXPORT\n#  endif\n# elif defined(__GNUC__) && defined(OPUS_BUILD)\n#  define OPUS_EXPORT __attribute__ ((visibility (\"default\")))\n# else\n#  define OPUS_EXPORT\n# endif\n#endif\n\n# if !defined(OPUS_GNUC_PREREQ)\n#  if defined(__GNUC__)&&defined(__GNUC_MINOR__)\n#   define OPUS_GNUC_PREREQ(_maj,_min) \\\n ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))\n#  else\n#   define OPUS_GNUC_PREREQ(_maj,_min) 0\n#  endif\n# endif\n\n#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )\n# if OPUS_GNUC_PREREQ(3,0)\n#  define OPUS_RESTRICT __restrict__\n# elif (defined(_MSC_VER) && _MSC_VER >= 1400)\n#  define OPUS_RESTRICT __restrict\n# else\n#  define OPUS_RESTRICT\n# endif\n#else\n# define OPUS_RESTRICT restrict\n#endif\n\n#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )\n# if OPUS_GNUC_PREREQ(2,7)\n#  define OPUS_INLINE __inline__\n# elif (defined(_MSC_VER))\n#  define OPUS_INLINE __inline\n# else\n#  define OPUS_INLINE\n# endif\n#else\n# define OPUS_INLINE inline\n#endif\n\n/**Warning attributes for opus functions\n  * NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out\n  * some paranoid null checks. */\n#if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4)\n# define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__))\n#else\n# define OPUS_WARN_UNUSED_RESULT\n#endif\n#if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4)\n# define OPUS_ARG_NONNULL(_x)  __attribute__ ((__nonnull__(_x)))\n#else\n# define OPUS_ARG_NONNULL(_x)\n#endif\n\n/** These are the actual Encoder CTL ID numbers.\n  * They should not be used directly by applications.\n  * In general, SETs should be even and GETs should be odd.*/\n#define OPUS_SET_APPLICATION_REQUEST         4000\n#define OPUS_GET_APPLICATION_REQUEST         4001\n#define OPUS_SET_BITRATE_REQUEST             4002\n#define OPUS_GET_BITRATE_REQUEST             4003\n#define OPUS_SET_MAX_BANDWIDTH_REQUEST       4004\n#define OPUS_GET_MAX_BANDWIDTH_REQUEST       4005\n#define OPUS_SET_VBR_REQUEST                 4006\n#define OPUS_GET_VBR_REQUEST                 4007\n#define OPUS_SET_BANDWIDTH_REQUEST           4008\n#define OPUS_GET_BANDWIDTH_REQUEST           4009\n#define OPUS_SET_COMPLEXITY_REQUEST          4010\n#define OPUS_GET_COMPLEXITY_REQUEST          4011\n#define OPUS_SET_INBAND_FEC_REQUEST          4012\n#define OPUS_GET_INBAND_FEC_REQUEST          4013\n#define OPUS_SET_PACKET_LOSS_PERC_REQUEST    4014\n#define OPUS_GET_PACKET_LOSS_PERC_REQUEST    4015\n#define OPUS_SET_DTX_REQUEST                 4016\n#define OPUS_GET_DTX_REQUEST                 4017\n#define OPUS_SET_VBR_CONSTRAINT_REQUEST      4020\n#define OPUS_GET_VBR_CONSTRAINT_REQUEST      4021\n#define OPUS_SET_FORCE_CHANNELS_REQUEST      4022\n#define OPUS_GET_FORCE_CHANNELS_REQUEST      4023\n#define OPUS_SET_SIGNAL_REQUEST              4024\n#define OPUS_GET_SIGNAL_REQUEST              4025\n#define OPUS_GET_LOOKAHEAD_REQUEST           4027\n/* #define OPUS_RESET_STATE 4028 */\n#define OPUS_GET_SAMPLE_RATE_REQUEST         4029\n#define OPUS_GET_FINAL_RANGE_REQUEST         4031\n#define OPUS_GET_PITCH_REQUEST               4033\n#define OPUS_SET_GAIN_REQUEST                4034\n#define OPUS_GET_GAIN_REQUEST                4045 /* Should have been 4035 */\n#define OPUS_SET_LSB_DEPTH_REQUEST           4036\n#define OPUS_GET_LSB_DEPTH_REQUEST           4037\n#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039\n#define OPUS_SET_EXPERT_FRAME_DURATION_REQUEST 4040\n#define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041\n#define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042\n#define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043\n\n/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */\n\n/* Macros to trigger compilation errors when the wrong types are provided to a CTL */\n#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))\n#define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))\n#define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr)))\n#define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr)))\n/** @endcond */\n\n/** @defgroup opus_ctlvalues Pre-defined values for CTL interface\n  * @see opus_genericctls, opus_encoderctls\n  * @{\n  */\n/* Values for the various encoder CTLs */\n#define OPUS_AUTO                           -1000 /**<Auto/default setting @hideinitializer*/\n#define OPUS_BITRATE_MAX                       -1 /**<Maximum bitrate @hideinitializer*/\n\n/** Best for most VoIP/videoconference applications where listening quality and intelligibility matter most\n * @hideinitializer */\n#define OPUS_APPLICATION_VOIP                2048\n/** Best for broadcast/high-fidelity application where the decoded audio should be as close as possible to the input\n * @hideinitializer */\n#define OPUS_APPLICATION_AUDIO               2049\n/** Only use when lowest-achievable latency is what matters most. Voice-optimized modes cannot be used.\n * @hideinitializer */\n#define OPUS_APPLICATION_RESTRICTED_LOWDELAY 2051\n\n#define OPUS_SIGNAL_VOICE                    3001 /**< Signal being encoded is voice */\n#define OPUS_SIGNAL_MUSIC                    3002 /**< Signal being encoded is music */\n#define OPUS_BANDWIDTH_NARROWBAND            1101 /**< 4 kHz bandpass @hideinitializer*/\n#define OPUS_BANDWIDTH_MEDIUMBAND            1102 /**< 6 kHz bandpass @hideinitializer*/\n#define OPUS_BANDWIDTH_WIDEBAND              1103 /**< 8 kHz bandpass @hideinitializer*/\n#define OPUS_BANDWIDTH_SUPERWIDEBAND         1104 /**<12 kHz bandpass @hideinitializer*/\n#define OPUS_BANDWIDTH_FULLBAND              1105 /**<20 kHz bandpass @hideinitializer*/\n\n#define OPUS_FRAMESIZE_ARG                   5000 /**< Select frame size from the argument (default) */\n#define OPUS_FRAMESIZE_2_5_MS                5001 /**< Use 2.5 ms frames */\n#define OPUS_FRAMESIZE_5_MS                  5002 /**< Use 5 ms frames */\n#define OPUS_FRAMESIZE_10_MS                 5003 /**< Use 10 ms frames */\n#define OPUS_FRAMESIZE_20_MS                 5004 /**< Use 20 ms frames */\n#define OPUS_FRAMESIZE_40_MS                 5005 /**< Use 40 ms frames */\n#define OPUS_FRAMESIZE_60_MS                 5006 /**< Use 60 ms frames */\n\n/**@}*/\n\n\n/** @defgroup opus_encoderctls Encoder related CTLs\n  *\n  * These are convenience macros for use with the \\c opus_encode_ctl\n  * interface. They are used to generate the appropriate series of\n  * arguments for that call, passing the correct type, size and so\n  * on as expected for each particular request.\n  *\n  * Some usage examples:\n  *\n  * @code\n  * int ret;\n  * ret = opus_encoder_ctl(enc_ctx, OPUS_SET_BANDWIDTH(OPUS_AUTO));\n  * if (ret != OPUS_OK) return ret;\n  *\n  * opus_int32 rate;\n  * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&rate));\n  *\n  * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE);\n  * @endcode\n  *\n  * @see opus_genericctls, opus_encoder\n  * @{\n  */\n\n/** Configures the encoder's computational complexity.\n  * The supported range is 0-10 inclusive with 10 representing the highest complexity.\n  * @see OPUS_GET_COMPLEXITY\n  * @param[in] x <tt>opus_int32</tt>: Allowed values: 0-10, inclusive.\n  *\n  * @hideinitializer */\n#define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x)\n/** Gets the encoder's complexity configuration.\n  * @see OPUS_SET_COMPLEXITY\n  * @param[out] x <tt>opus_int32 *</tt>: Returns a value in the range 0-10,\n  *                                      inclusive.\n  * @hideinitializer */\n#define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x)\n\n/** Configures the bitrate in the encoder.\n  * Rates from 500 to 512000 bits per second are meaningful, as well as the\n  * special values #OPUS_AUTO and #OPUS_BITRATE_MAX.\n  * The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much\n  * rate as it can, which is useful for controlling the rate by adjusting the\n  * output buffer size.\n  * @see OPUS_GET_BITRATE\n  * @param[in] x <tt>opus_int32</tt>: Bitrate in bits per second. The default\n  *                                   is determined based on the number of\n  *                                   channels and the input sampling rate.\n  * @hideinitializer */\n#define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x)\n/** Gets the encoder's bitrate configuration.\n  * @see OPUS_SET_BITRATE\n  * @param[out] x <tt>opus_int32 *</tt>: Returns the bitrate in bits per second.\n  *                                      The default is determined based on the\n  *                                      number of channels and the input\n  *                                      sampling rate.\n  * @hideinitializer */\n#define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x)\n\n/** Enables or disables variable bitrate (VBR) in the encoder.\n  * The configured bitrate may not be met exactly because frames must\n  * be an integer number of bytes in length.\n  * @see OPUS_GET_VBR\n  * @see OPUS_SET_VBR_CONSTRAINT\n  * @param[in] x <tt>opus_int32</tt>: Allowed values:\n  * <dl>\n  * <dt>0</dt><dd>Hard CBR. For LPC/hybrid modes at very low bit-rate, this can\n  *               cause noticeable quality degradation.</dd>\n  * <dt>1</dt><dd>VBR (default). The exact type of VBR is controlled by\n  *               #OPUS_SET_VBR_CONSTRAINT.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x)\n/** Determine if variable bitrate (VBR) is enabled in the encoder.\n  * @see OPUS_SET_VBR\n  * @see OPUS_GET_VBR_CONSTRAINT\n  * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:\n  * <dl>\n  * <dt>0</dt><dd>Hard CBR.</dd>\n  * <dt>1</dt><dd>VBR (default). The exact type of VBR may be retrieved via\n  *               #OPUS_GET_VBR_CONSTRAINT.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x)\n\n/** Enables or disables constrained VBR in the encoder.\n  * This setting is ignored when the encoder is in CBR mode.\n  * @warning Only the MDCT mode of Opus currently heeds the constraint.\n  *  Speech mode ignores it completely, hybrid mode may fail to obey it\n  *  if the LPC layer uses more bitrate than the constraint would have\n  *  permitted.\n  * @see OPUS_GET_VBR_CONSTRAINT\n  * @see OPUS_SET_VBR\n  * @param[in] x <tt>opus_int32</tt>: Allowed values:\n  * <dl>\n  * <dt>0</dt><dd>Unconstrained VBR.</dd>\n  * <dt>1</dt><dd>Constrained VBR (default). This creates a maximum of one\n  *               frame of buffering delay assuming a transport with a\n  *               serialization speed of the nominal bitrate.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x)\n/** Determine if constrained VBR is enabled in the encoder.\n  * @see OPUS_SET_VBR_CONSTRAINT\n  * @see OPUS_GET_VBR\n  * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:\n  * <dl>\n  * <dt>0</dt><dd>Unconstrained VBR.</dd>\n  * <dt>1</dt><dd>Constrained VBR (default).</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x)\n\n/** Configures mono/stereo forcing in the encoder.\n  * This can force the encoder to produce packets encoded as either mono or\n  * stereo, regardless of the format of the input audio. This is useful when\n  * the caller knows that the input signal is currently a mono source embedded\n  * in a stereo stream.\n  * @see OPUS_GET_FORCE_CHANNELS\n  * @param[in] x <tt>opus_int32</tt>: Allowed values:\n  * <dl>\n  * <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd>\n  * <dt>1</dt>         <dd>Forced mono</dd>\n  * <dt>2</dt>         <dd>Forced stereo</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x)\n/** Gets the encoder's forced channel configuration.\n  * @see OPUS_SET_FORCE_CHANNELS\n  * @param[out] x <tt>opus_int32 *</tt>:\n  * <dl>\n  * <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd>\n  * <dt>1</dt>         <dd>Forced mono</dd>\n  * <dt>2</dt>         <dd>Forced stereo</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x)\n\n/** Configures the maximum bandpass that the encoder will select automatically.\n  * Applications should normally use this instead of #OPUS_SET_BANDWIDTH\n  * (leaving that set to the default, #OPUS_AUTO). This allows the\n  * application to set an upper bound based on the type of input it is\n  * providing, but still gives the encoder the freedom to reduce the bandpass\n  * when the bitrate becomes too low, for better overall quality.\n  * @see OPUS_GET_MAX_BANDWIDTH\n  * @param[in] x <tt>opus_int32</tt>: Allowed values:\n  * <dl>\n  * <dt>OPUS_BANDWIDTH_NARROWBAND</dt>    <dd>4 kHz passband</dd>\n  * <dt>OPUS_BANDWIDTH_MEDIUMBAND</dt>    <dd>6 kHz passband</dd>\n  * <dt>OPUS_BANDWIDTH_WIDEBAND</dt>      <dd>8 kHz passband</dd>\n  * <dt>OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>\n  * <dt>OPUS_BANDWIDTH_FULLBAND</dt>     <dd>20 kHz passband (default)</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x)\n\n/** Gets the encoder's configured maximum allowed bandpass.\n  * @see OPUS_SET_MAX_BANDWIDTH\n  * @param[out] x <tt>opus_int32 *</tt>: Allowed values:\n  * <dl>\n  * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt>    <dd>4 kHz passband</dd>\n  * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt>    <dd>6 kHz passband</dd>\n  * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt>      <dd>8 kHz passband</dd>\n  * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>\n  * <dt>#OPUS_BANDWIDTH_FULLBAND</dt>     <dd>20 kHz passband (default)</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)\n\n/** Sets the encoder's bandpass to a specific value.\n  * This prevents the encoder from automatically selecting the bandpass based\n  * on the available bitrate. If an application knows the bandpass of the input\n  * audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH\n  * instead, which still gives the encoder the freedom to reduce the bandpass\n  * when the bitrate becomes too low, for better overall quality.\n  * @see OPUS_GET_BANDWIDTH\n  * @param[in] x <tt>opus_int32</tt>: Allowed values:\n  * <dl>\n  * <dt>#OPUS_AUTO</dt>                    <dd>(default)</dd>\n  * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt>    <dd>4 kHz passband</dd>\n  * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt>    <dd>6 kHz passband</dd>\n  * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt>      <dd>8 kHz passband</dd>\n  * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>\n  * <dt>#OPUS_BANDWIDTH_FULLBAND</dt>     <dd>20 kHz passband</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x)\n\n/** Configures the type of signal being encoded.\n  * This is a hint which helps the encoder's mode selection.\n  * @see OPUS_GET_SIGNAL\n  * @param[in] x <tt>opus_int32</tt>: Allowed values:\n  * <dl>\n  * <dt>#OPUS_AUTO</dt>        <dd>(default)</dd>\n  * <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd>\n  * <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x)\n/** Gets the encoder's configured signal type.\n  * @see OPUS_SET_SIGNAL\n  * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:\n  * <dl>\n  * <dt>#OPUS_AUTO</dt>        <dd>(default)</dd>\n  * <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd>\n  * <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x)\n\n\n/** Configures the encoder's intended application.\n  * The initial value is a mandatory argument to the encoder_create function.\n  * @see OPUS_GET_APPLICATION\n  * @param[in] x <tt>opus_int32</tt>: Returns one of the following values:\n  * <dl>\n  * <dt>#OPUS_APPLICATION_VOIP</dt>\n  * <dd>Process signal for improved speech intelligibility.</dd>\n  * <dt>#OPUS_APPLICATION_AUDIO</dt>\n  * <dd>Favor faithfulness to the original input.</dd>\n  * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>\n  * <dd>Configure the minimum possible coding delay by disabling certain modes\n  * of operation.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x)\n/** Gets the encoder's configured application.\n  * @see OPUS_SET_APPLICATION\n  * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:\n  * <dl>\n  * <dt>#OPUS_APPLICATION_VOIP</dt>\n  * <dd>Process signal for improved speech intelligibility.</dd>\n  * <dt>#OPUS_APPLICATION_AUDIO</dt>\n  * <dd>Favor faithfulness to the original input.</dd>\n  * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>\n  * <dd>Configure the minimum possible coding delay by disabling certain modes\n  * of operation.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x)\n\n/** Gets the total samples of delay added by the entire codec.\n  * This can be queried by the encoder and then the provided number of samples can be\n  * skipped on from the start of the decoder's output to provide time aligned input\n  * and output. From the perspective of a decoding application the real data begins this many\n  * samples late.\n  *\n  * The decoder contribution to this delay is identical for all decoders, but the\n  * encoder portion of the delay may vary from implementation to implementation,\n  * version to version, or even depend on the encoder's initial configuration.\n  * Applications needing delay compensation should call this CTL rather than\n  * hard-coding a value.\n  * @param[out] x <tt>opus_int32 *</tt>:   Number of lookahead samples\n  * @hideinitializer */\n#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x)\n\n/** Configures the encoder's use of inband forward error correction (FEC).\n  * @note This is only applicable to the LPC layer\n  * @see OPUS_GET_INBAND_FEC\n  * @param[in] x <tt>opus_int32</tt>: Allowed values:\n  * <dl>\n  * <dt>0</dt><dd>Disable inband FEC (default).</dd>\n  * <dt>1</dt><dd>Enable inband FEC.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x)\n/** Gets encoder's configured use of inband forward error correction.\n  * @see OPUS_SET_INBAND_FEC\n  * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:\n  * <dl>\n  * <dt>0</dt><dd>Inband FEC disabled (default).</dd>\n  * <dt>1</dt><dd>Inband FEC enabled.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x)\n\n/** Configures the encoder's expected packet loss percentage.\n  * Higher values trigger progressively more loss resistant behavior in the encoder\n  * at the expense of quality at a given bitrate in the absence of packet loss, but\n  * greater quality under loss.\n  * @see OPUS_GET_PACKET_LOSS_PERC\n  * @param[in] x <tt>opus_int32</tt>:   Loss percentage in the range 0-100, inclusive (default: 0).\n  * @hideinitializer */\n#define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x)\n/** Gets the encoder's configured packet loss percentage.\n  * @see OPUS_SET_PACKET_LOSS_PERC\n  * @param[out] x <tt>opus_int32 *</tt>: Returns the configured loss percentage\n  *                                      in the range 0-100, inclusive (default: 0).\n  * @hideinitializer */\n#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x)\n\n/** Configures the encoder's use of discontinuous transmission (DTX).\n  * @note This is only applicable to the LPC layer\n  * @see OPUS_GET_DTX\n  * @param[in] x <tt>opus_int32</tt>: Allowed values:\n  * <dl>\n  * <dt>0</dt><dd>Disable DTX (default).</dd>\n  * <dt>1</dt><dd>Enabled DTX.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x)\n/** Gets encoder's configured use of discontinuous transmission.\n  * @see OPUS_SET_DTX\n  * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:\n  * <dl>\n  * <dt>0</dt><dd>DTX disabled (default).</dd>\n  * <dt>1</dt><dd>DTX enabled.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x)\n/** Configures the depth of signal being encoded.\n  *\n  * This is a hint which helps the encoder identify silence and near-silence.\n  * It represents the number of significant bits of linear intensity below\n  * which the signal contains ignorable quantization or other noise.\n  *\n  * For example, OPUS_SET_LSB_DEPTH(14) would be an appropriate setting\n  * for G.711 u-law input. OPUS_SET_LSB_DEPTH(16) would be appropriate\n  * for 16-bit linear pcm input with opus_encode_float().\n  *\n  * When using opus_encode() instead of opus_encode_float(), or when libopus\n  * is compiled for fixed-point, the encoder uses the minimum of the value\n  * set here and the value 16.\n  *\n  * @see OPUS_GET_LSB_DEPTH\n  * @param[in] x <tt>opus_int32</tt>: Input precision in bits, between 8 and 24\n  *                                   (default: 24).\n  * @hideinitializer */\n#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x)\n/** Gets the encoder's configured signal depth.\n  * @see OPUS_SET_LSB_DEPTH\n  * @param[out] x <tt>opus_int32 *</tt>: Input precision in bits, between 8 and\n  *                                      24 (default: 24).\n  * @hideinitializer */\n#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x)\n\n/** Configures the encoder's use of variable duration frames.\n  * When variable duration is enabled, the encoder is free to use a shorter frame\n  * size than the one requested in the opus_encode*() call.\n  * It is then the user's responsibility\n  * to verify how much audio was encoded by checking the ToC byte of the encoded\n  * packet. The part of the audio that was not encoded needs to be resent to the\n  * encoder for the next call. Do not use this option unless you <b>really</b>\n  * know what you are doing.\n  * @see OPUS_GET_EXPERT_FRAME_DURATION\n  * @param[in] x <tt>opus_int32</tt>: Allowed values:\n  * <dl>\n  * <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>\n  * <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>\n  * <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd>\n  * <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>\n  * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>\n  * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>\n  * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>\n  * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x)\n/** Gets the encoder's configured use of variable duration frames.\n  * @see OPUS_SET_EXPERT_FRAME_DURATION\n  * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:\n  * <dl>\n  * <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>\n  * <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>\n  * <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd>\n  * <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>\n  * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>\n  * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>\n  * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>\n  * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x)\n\n/** If set to 1, disables almost all use of prediction, making frames almost\n  * completely independent. This reduces quality.\n  * @see OPUS_GET_PREDICTION_DISABLED\n  * @param[in] x <tt>opus_int32</tt>: Allowed values:\n  * <dl>\n  * <dt>0</dt><dd>Enable prediction (default).</dd>\n  * <dt>1</dt><dd>Disable prediction.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x)\n/** Gets the encoder's configured prediction status.\n  * @see OPUS_SET_PREDICTION_DISABLED\n  * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:\n  * <dl>\n  * <dt>0</dt><dd>Prediction enabled (default).</dd>\n  * <dt>1</dt><dd>Prediction disabled.</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x)\n\n/**@}*/\n\n/** @defgroup opus_genericctls Generic CTLs\n  *\n  * These macros are used with the \\c opus_decoder_ctl and\n  * \\c opus_encoder_ctl calls to generate a particular\n  * request.\n  *\n  * When called on an \\c OpusDecoder they apply to that\n  * particular decoder instance. When called on an\n  * \\c OpusEncoder they apply to the corresponding setting\n  * on that encoder instance, if present.\n  *\n  * Some usage examples:\n  *\n  * @code\n  * int ret;\n  * opus_int32 pitch;\n  * ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch));\n  * if (ret == OPUS_OK) return ret;\n  *\n  * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE);\n  * opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE);\n  *\n  * opus_int32 enc_bw, dec_bw;\n  * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw));\n  * opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw));\n  * if (enc_bw != dec_bw) {\n  *   printf(\"packet bandwidth mismatch!\\n\");\n  * }\n  * @endcode\n  *\n  * @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls\n  * @{\n  */\n\n/** Resets the codec state to be equivalent to a freshly initialized state.\n  * This should be called when switching streams in order to prevent\n  * the back to back decoding from giving different results from\n  * one at a time decoding.\n  * @hideinitializer */\n#define OPUS_RESET_STATE 4028\n\n/** Gets the final state of the codec's entropy coder.\n  * This is used for testing purposes,\n  * The encoder and decoder state should be identical after coding a payload\n  * (assuming no data corruption or software bugs)\n  *\n  * @param[out] x <tt>opus_uint32 *</tt>: Entropy coder state\n  *\n  * @hideinitializer */\n#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x)\n\n/** Gets the encoder's configured bandpass or the decoder's last bandpass.\n  * @see OPUS_SET_BANDWIDTH\n  * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:\n  * <dl>\n  * <dt>#OPUS_AUTO</dt>                    <dd>(default)</dd>\n  * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt>    <dd>4 kHz passband</dd>\n  * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt>    <dd>6 kHz passband</dd>\n  * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt>      <dd>8 kHz passband</dd>\n  * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>\n  * <dt>#OPUS_BANDWIDTH_FULLBAND</dt>     <dd>20 kHz passband</dd>\n  * </dl>\n  * @hideinitializer */\n#define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)\n\n/** Gets the sampling rate the encoder or decoder was initialized with.\n  * This simply returns the <code>Fs</code> value passed to opus_encoder_init()\n  * or opus_decoder_init().\n  * @param[out] x <tt>opus_int32 *</tt>: Sampling rate of encoder or decoder.\n  * @hideinitializer\n  */\n#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x)\n\n/**@}*/\n\n/** @defgroup opus_decoderctls Decoder related CTLs\n  * @see opus_genericctls, opus_encoderctls, opus_decoder\n  * @{\n  */\n\n/** Configures decoder gain adjustment.\n  * Scales the decoded output by a factor specified in Q8 dB units.\n  * This has a maximum range of -32768 to 32767 inclusive, and returns\n  * OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment.\n  * This setting survives decoder reset.\n  *\n  * gain = pow(10, x/(20.0*256))\n  *\n  * @param[in] x <tt>opus_int32</tt>:   Amount to scale PCM signal by in Q8 dB units.\n  * @hideinitializer */\n#define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x)\n/** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN\n  *\n  * @param[out] x <tt>opus_int32 *</tt>: Amount to scale PCM signal by in Q8 dB units.\n  * @hideinitializer */\n#define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x)\n\n/** Gets the duration (in samples) of the last packet successfully decoded or concealed.\n  * @param[out] x <tt>opus_int32 *</tt>: Number of samples (at current sampling rate).\n  * @hideinitializer */\n#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x)\n\n/** Gets the pitch of the last decoded frame, if available.\n  * This can be used for any post-processing algorithm requiring the use of pitch,\n  * e.g. time stretching/shortening. If the last frame was not voiced, or if the\n  * pitch was not coded in the frame, then zero is returned.\n  *\n  * This CTL is only implemented for decoder instances.\n  *\n  * @param[out] x <tt>opus_int32 *</tt>: pitch period at 48 kHz (or 0 if not available)\n  *\n  * @hideinitializer */\n#define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x)\n\n/**@}*/\n\n/** @defgroup opus_libinfo Opus library information functions\n  * @{\n  */\n\n/** Converts an opus error code into a human readable string.\n  *\n  * @param[in] error <tt>int</tt>: Error number\n  * @returns Error string\n  */\nOPUS_EXPORT const char *opus_strerror(int error);\n\n/** Gets the libopus version string.\n  *\n  * Applications may look for the substring \"-fixed\" in the version string to\n  * determine whether they have a fixed-point or floating-point build at\n  * runtime.\n  *\n  * @returns Version string\n  */\nOPUS_EXPORT const char *opus_get_version_string(void);\n/**@}*/\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* OPUS_DEFINES_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/include/opus_multistream.h",
    "content": "/* Copyright (c) 2011 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/**\n * @file opus_multistream.h\n * @brief Opus reference implementation multistream API\n */\n\n#ifndef OPUS_MULTISTREAM_H\n#define OPUS_MULTISTREAM_H\n\n#include \"opus.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** @cond OPUS_INTERNAL_DOC */\n\n/** Macros to trigger compilation errors when the wrong types are provided to a\n  * CTL. */\n/**@{*/\n#define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr)))\n#define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr)))\n/**@}*/\n\n/** These are the actual encoder and decoder CTL ID numbers.\n  * They should not be used directly by applications.\n  * In general, SETs should be even and GETs should be odd.*/\n/**@{*/\n#define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120\n#define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122\n/**@}*/\n\n/** @endcond */\n\n/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs\n  *\n  * These are convenience macros that are specific to the\n  * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl()\n  * interface.\n  * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and\n  * @ref opus_decoderctls may be applied to a multistream encoder or decoder as\n  * well.\n  * In addition, you may retrieve the encoder or decoder state for an specific\n  * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or\n  * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually.\n  */\n/**@{*/\n\n/** Gets the encoder state for an individual stream of a multistream encoder.\n  * @param[in] x <tt>opus_int32</tt>: The index of the stream whose encoder you\n  *                                   wish to retrieve.\n  *                                   This must be non-negative and less than\n  *                                   the <code>streams</code> parameter used\n  *                                   to initialize the encoder.\n  * @param[out] y <tt>OpusEncoder**</tt>: Returns a pointer to the given\n  *                                       encoder state.\n  * @retval OPUS_BAD_ARG The index of the requested stream was out of range.\n  * @hideinitializer\n  */\n#define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y)\n\n/** Gets the decoder state for an individual stream of a multistream decoder.\n  * @param[in] x <tt>opus_int32</tt>: The index of the stream whose decoder you\n  *                                   wish to retrieve.\n  *                                   This must be non-negative and less than\n  *                                   the <code>streams</code> parameter used\n  *                                   to initialize the decoder.\n  * @param[out] y <tt>OpusDecoder**</tt>: Returns a pointer to the given\n  *                                       decoder state.\n  * @retval OPUS_BAD_ARG The index of the requested stream was out of range.\n  * @hideinitializer\n  */\n#define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y)\n\n/**@}*/\n\n/** @defgroup opus_multistream Opus Multistream API\n  * @{\n  *\n  * The multistream API allows individual Opus streams to be combined into a\n  * single packet, enabling support for up to 255 channels. Unlike an\n  * elementary Opus stream, the encoder and decoder must negotiate the channel\n  * configuration before the decoder can successfully interpret the data in the\n  * packets produced by the encoder. Some basic information, such as packet\n  * duration, can be computed without any special negotiation.\n  *\n  * The format for multistream Opus packets is defined in the\n  * <a href=\"https://tools.ietf.org/html/draft-ietf-codec-oggopus\">Ogg\n  * encapsulation specification</a> and is based on the self-delimited Opus\n  * framing described in Appendix B of <a href=\"https://tools.ietf.org/html/rfc6716\">RFC 6716</a>.\n  * Normal Opus packets are just a degenerate case of multistream Opus packets,\n  * and can be encoded or decoded with the multistream API by setting\n  * <code>streams</code> to <code>1</code> when initializing the encoder or\n  * decoder.\n  *\n  * Multistream Opus streams can contain up to 255 elementary Opus streams.\n  * These may be either \"uncoupled\" or \"coupled\", indicating that the decoder\n  * is configured to decode them to either 1 or 2 channels, respectively.\n  * The streams are ordered so that all coupled streams appear at the\n  * beginning.\n  *\n  * A <code>mapping</code> table defines which decoded channel <code>i</code>\n  * should be used for each input/output (I/O) channel <code>j</code>. This table is\n  * typically provided as an unsigned char array.\n  * Let <code>i = mapping[j]</code> be the index for I/O channel <code>j</code>.\n  * If <code>i < 2*coupled_streams</code>, then I/O channel <code>j</code> is\n  * encoded as the left channel of stream <code>(i/2)</code> if <code>i</code>\n  * is even, or  as the right channel of stream <code>(i/2)</code> if\n  * <code>i</code> is odd. Otherwise, I/O channel <code>j</code> is encoded as\n  * mono in stream <code>(i - coupled_streams)</code>, unless it has the special\n  * value 255, in which case it is omitted from the encoding entirely (the\n  * decoder will reproduce it as silence). Each value <code>i</code> must either\n  * be the special value 255 or be less than <code>streams + coupled_streams</code>.\n  *\n  * The output channels specified by the encoder\n  * should use the\n  * <a href=\"https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810004.3.9\">Vorbis\n  * channel ordering</a>. A decoder may wish to apply an additional permutation\n  * to the mapping the encoder used to achieve a different output channel\n  * order (e.g. for outputing in WAV order).\n  *\n  * Each multistream packet contains an Opus packet for each stream, and all of\n  * the Opus packets in a single multistream packet must have the same\n  * duration. Therefore the duration of a multistream packet can be extracted\n  * from the TOC sequence of the first stream, which is located at the\n  * beginning of the packet, just like an elementary Opus stream:\n  *\n  * @code\n  * int nb_samples;\n  * int nb_frames;\n  * nb_frames = opus_packet_get_nb_frames(data, len);\n  * if (nb_frames < 1)\n  *   return nb_frames;\n  * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames;\n  * @endcode\n  *\n  * The general encoding and decoding process proceeds exactly the same as in\n  * the normal @ref opus_encoder and @ref opus_decoder APIs.\n  * See their documentation for an overview of how to use the corresponding\n  * multistream functions.\n  */\n\n/** Opus multistream encoder state.\n  * This contains the complete state of a multistream Opus encoder.\n  * It is position independent and can be freely copied.\n  * @see opus_multistream_encoder_create\n  * @see opus_multistream_encoder_init\n  */\ntypedef struct OpusMSEncoder OpusMSEncoder;\n\n/** Opus multistream decoder state.\n  * This contains the complete state of a multistream Opus decoder.\n  * It is position independent and can be freely copied.\n  * @see opus_multistream_decoder_create\n  * @see opus_multistream_decoder_init\n  */\ntypedef struct OpusMSDecoder OpusMSDecoder;\n\n/**\\name Multistream encoder functions */\n/**@{*/\n\n/** Gets the size of an OpusMSEncoder structure.\n  * @param streams <tt>int</tt>: The total number of streams to encode from the\n  *                              input.\n  *                              This must be no more than 255.\n  * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams\n  *                                      to encode.\n  *                                      This must be no larger than the total\n  *                                      number of streams.\n  *                                      Additionally, The total number of\n  *                                      encoded channels (<code>streams +\n  *                                      coupled_streams</code>) must be no\n  *                                      more than 255.\n  * @returns The size in bytes on success, or a negative error code\n  *          (see @ref opus_errorcodes) on error.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size(\n      int streams,\n      int coupled_streams\n);\n\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_surround_encoder_get_size(\n      int channels,\n      int mapping_family\n);\n\n\n/** Allocates and initializes a multistream encoder state.\n  * Call opus_multistream_encoder_destroy() to release\n  * this object when finished.\n  * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).\n  *                                This must be one of 8000, 12000, 16000,\n  *                                24000, or 48000.\n  * @param channels <tt>int</tt>: Number of channels in the input signal.\n  *                               This must be at most 255.\n  *                               It may be greater than the number of\n  *                               coded channels (<code>streams +\n  *                               coupled_streams</code>).\n  * @param streams <tt>int</tt>: The total number of streams to encode from the\n  *                              input.\n  *                              This must be no more than the number of channels.\n  * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams\n  *                                      to encode.\n  *                                      This must be no larger than the total\n  *                                      number of streams.\n  *                                      Additionally, The total number of\n  *                                      encoded channels (<code>streams +\n  *                                      coupled_streams</code>) must be no\n  *                                      more than the number of input channels.\n  * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from\n  *                    encoded channels to input channels, as described in\n  *                    @ref opus_multistream. As an extra constraint, the\n  *                    multistream encoder does not allow encoding coupled\n  *                    streams for which one channel is unused since this\n  *                    is never a good idea.\n  * @param application <tt>int</tt>: The target encoder application.\n  *                                  This must be one of the following:\n  * <dl>\n  * <dt>#OPUS_APPLICATION_VOIP</dt>\n  * <dd>Process signal for improved speech intelligibility.</dd>\n  * <dt>#OPUS_APPLICATION_AUDIO</dt>\n  * <dd>Favor faithfulness to the original input.</dd>\n  * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>\n  * <dd>Configure the minimum possible coding delay by disabling certain modes\n  * of operation.</dd>\n  * </dl>\n  * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error\n  *                                   code (see @ref opus_errorcodes) on\n  *                                   failure.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create(\n      opus_int32 Fs,\n      int channels,\n      int streams,\n      int coupled_streams,\n      const unsigned char *mapping,\n      int application,\n      int *error\n) OPUS_ARG_NONNULL(5);\n\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_surround_encoder_create(\n      opus_int32 Fs,\n      int channels,\n      int mapping_family,\n      int *streams,\n      int *coupled_streams,\n      unsigned char *mapping,\n      int application,\n      int *error\n) OPUS_ARG_NONNULL(5);\n\n/** Initialize a previously allocated multistream encoder state.\n  * The memory pointed to by \\a st must be at least the size returned by\n  * opus_multistream_encoder_get_size().\n  * This is intended for applications which use their own allocator instead of\n  * malloc.\n  * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.\n  * @see opus_multistream_encoder_create\n  * @see opus_multistream_encoder_get_size\n  * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.\n  * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).\n  *                                This must be one of 8000, 12000, 16000,\n  *                                24000, or 48000.\n  * @param channels <tt>int</tt>: Number of channels in the input signal.\n  *                               This must be at most 255.\n  *                               It may be greater than the number of\n  *                               coded channels (<code>streams +\n  *                               coupled_streams</code>).\n  * @param streams <tt>int</tt>: The total number of streams to encode from the\n  *                              input.\n  *                              This must be no more than the number of channels.\n  * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams\n  *                                      to encode.\n  *                                      This must be no larger than the total\n  *                                      number of streams.\n  *                                      Additionally, The total number of\n  *                                      encoded channels (<code>streams +\n  *                                      coupled_streams</code>) must be no\n  *                                      more than the number of input channels.\n  * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from\n  *                    encoded channels to input channels, as described in\n  *                    @ref opus_multistream. As an extra constraint, the\n  *                    multistream encoder does not allow encoding coupled\n  *                    streams for which one channel is unused since this\n  *                    is never a good idea.\n  * @param application <tt>int</tt>: The target encoder application.\n  *                                  This must be one of the following:\n  * <dl>\n  * <dt>#OPUS_APPLICATION_VOIP</dt>\n  * <dd>Process signal for improved speech intelligibility.</dd>\n  * <dt>#OPUS_APPLICATION_AUDIO</dt>\n  * <dd>Favor faithfulness to the original input.</dd>\n  * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>\n  * <dd>Configure the minimum possible coding delay by disabling certain modes\n  * of operation.</dd>\n  * </dl>\n  * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)\n  *          on failure.\n  */\nOPUS_EXPORT int opus_multistream_encoder_init(\n      OpusMSEncoder *st,\n      opus_int32 Fs,\n      int channels,\n      int streams,\n      int coupled_streams,\n      const unsigned char *mapping,\n      int application\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);\n\nOPUS_EXPORT int opus_multistream_surround_encoder_init(\n      OpusMSEncoder *st,\n      opus_int32 Fs,\n      int channels,\n      int mapping_family,\n      int *streams,\n      int *coupled_streams,\n      unsigned char *mapping,\n      int application\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);\n\n/** Encodes a multistream Opus frame.\n  * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.\n  * @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved\n  *                                            samples.\n  *                                            This must contain\n  *                                            <code>frame_size*channels</code>\n  *                                            samples.\n  * @param frame_size <tt>int</tt>: Number of samples per channel in the input\n  *                                 signal.\n  *                                 This must be an Opus frame size for the\n  *                                 encoder's sampling rate.\n  *                                 For example, at 48 kHz the permitted values\n  *                                 are 120, 240, 480, 960, 1920, and 2880.\n  *                                 Passing in a duration of less than 10 ms\n  *                                 (480 samples at 48 kHz) will prevent the\n  *                                 encoder from using the LPC or hybrid modes.\n  * @param[out] data <tt>unsigned char*</tt>: Output payload.\n  *                                           This must contain storage for at\n  *                                           least \\a max_data_bytes.\n  * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated\n  *                                                 memory for the output\n  *                                                 payload. This may be\n  *                                                 used to impose an upper limit on\n  *                                                 the instant bitrate, but should\n  *                                                 not be used as the only bitrate\n  *                                                 control. Use #OPUS_SET_BITRATE to\n  *                                                 control the bitrate.\n  * @returns The length of the encoded packet (in bytes) on success or a\n  *          negative error code (see @ref opus_errorcodes) on failure.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode(\n    OpusMSEncoder *st,\n    const opus_int16 *pcm,\n    int frame_size,\n    unsigned char *data,\n    opus_int32 max_data_bytes\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);\n\n/** Encodes a multistream Opus frame from floating point input.\n  * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.\n  * @param[in] pcm <tt>const float*</tt>: The input signal as interleaved\n  *                                       samples with a normal range of\n  *                                       +/-1.0.\n  *                                       Samples with a range beyond +/-1.0\n  *                                       are supported but will be clipped by\n  *                                       decoders using the integer API and\n  *                                       should only be used if it is known\n  *                                       that the far end supports extended\n  *                                       dynamic range.\n  *                                       This must contain\n  *                                       <code>frame_size*channels</code>\n  *                                       samples.\n  * @param frame_size <tt>int</tt>: Number of samples per channel in the input\n  *                                 signal.\n  *                                 This must be an Opus frame size for the\n  *                                 encoder's sampling rate.\n  *                                 For example, at 48 kHz the permitted values\n  *                                 are 120, 240, 480, 960, 1920, and 2880.\n  *                                 Passing in a duration of less than 10 ms\n  *                                 (480 samples at 48 kHz) will prevent the\n  *                                 encoder from using the LPC or hybrid modes.\n  * @param[out] data <tt>unsigned char*</tt>: Output payload.\n  *                                           This must contain storage for at\n  *                                           least \\a max_data_bytes.\n  * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated\n  *                                                 memory for the output\n  *                                                 payload. This may be\n  *                                                 used to impose an upper limit on\n  *                                                 the instant bitrate, but should\n  *                                                 not be used as the only bitrate\n  *                                                 control. Use #OPUS_SET_BITRATE to\n  *                                                 control the bitrate.\n  * @returns The length of the encoded packet (in bytes) on success or a\n  *          negative error code (see @ref opus_errorcodes) on failure.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float(\n      OpusMSEncoder *st,\n      const float *pcm,\n      int frame_size,\n      unsigned char *data,\n      opus_int32 max_data_bytes\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);\n\n/** Frees an <code>OpusMSEncoder</code> allocated by\n  * opus_multistream_encoder_create().\n  * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to be freed.\n  */\nOPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st);\n\n/** Perform a CTL function on a multistream Opus encoder.\n  *\n  * Generally the request and subsequent arguments are generated by a\n  * convenience macro.\n  * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.\n  * @param request This and all remaining parameters should be replaced by one\n  *                of the convenience macros in @ref opus_genericctls,\n  *                @ref opus_encoderctls, or @ref opus_multistream_ctls.\n  * @see opus_genericctls\n  * @see opus_encoderctls\n  * @see opus_multistream_ctls\n  */\nOPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);\n\n/**@}*/\n\n/**\\name Multistream decoder functions */\n/**@{*/\n\n/** Gets the size of an <code>OpusMSDecoder</code> structure.\n  * @param streams <tt>int</tt>: The total number of streams coded in the\n  *                              input.\n  *                              This must be no more than 255.\n  * @param coupled_streams <tt>int</tt>: Number streams to decode as coupled\n  *                                      (2 channel) streams.\n  *                                      This must be no larger than the total\n  *                                      number of streams.\n  *                                      Additionally, The total number of\n  *                                      coded channels (<code>streams +\n  *                                      coupled_streams</code>) must be no\n  *                                      more than 255.\n  * @returns The size in bytes on success, or a negative error code\n  *          (see @ref opus_errorcodes) on error.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size(\n      int streams,\n      int coupled_streams\n);\n\n/** Allocates and initializes a multistream decoder state.\n  * Call opus_multistream_decoder_destroy() to release\n  * this object when finished.\n  * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).\n  *                                This must be one of 8000, 12000, 16000,\n  *                                24000, or 48000.\n  * @param channels <tt>int</tt>: Number of channels to output.\n  *                               This must be at most 255.\n  *                               It may be different from the number of coded\n  *                               channels (<code>streams +\n  *                               coupled_streams</code>).\n  * @param streams <tt>int</tt>: The total number of streams coded in the\n  *                              input.\n  *                              This must be no more than 255.\n  * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled\n  *                                      (2 channel) streams.\n  *                                      This must be no larger than the total\n  *                                      number of streams.\n  *                                      Additionally, The total number of\n  *                                      coded channels (<code>streams +\n  *                                      coupled_streams</code>) must be no\n  *                                      more than 255.\n  * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from\n  *                    coded channels to output channels, as described in\n  *                    @ref opus_multistream.\n  * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error\n  *                                   code (see @ref opus_errorcodes) on\n  *                                   failure.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create(\n      opus_int32 Fs,\n      int channels,\n      int streams,\n      int coupled_streams,\n      const unsigned char *mapping,\n      int *error\n) OPUS_ARG_NONNULL(5);\n\n/** Intialize a previously allocated decoder state object.\n  * The memory pointed to by \\a st must be at least the size returned by\n  * opus_multistream_encoder_get_size().\n  * This is intended for applications which use their own allocator instead of\n  * malloc.\n  * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.\n  * @see opus_multistream_decoder_create\n  * @see opus_multistream_deocder_get_size\n  * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.\n  * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).\n  *                                This must be one of 8000, 12000, 16000,\n  *                                24000, or 48000.\n  * @param channels <tt>int</tt>: Number of channels to output.\n  *                               This must be at most 255.\n  *                               It may be different from the number of coded\n  *                               channels (<code>streams +\n  *                               coupled_streams</code>).\n  * @param streams <tt>int</tt>: The total number of streams coded in the\n  *                              input.\n  *                              This must be no more than 255.\n  * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled\n  *                                      (2 channel) streams.\n  *                                      This must be no larger than the total\n  *                                      number of streams.\n  *                                      Additionally, The total number of\n  *                                      coded channels (<code>streams +\n  *                                      coupled_streams</code>) must be no\n  *                                      more than 255.\n  * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from\n  *                    coded channels to output channels, as described in\n  *                    @ref opus_multistream.\n  * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)\n  *          on failure.\n  */\nOPUS_EXPORT int opus_multistream_decoder_init(\n      OpusMSDecoder *st,\n      opus_int32 Fs,\n      int channels,\n      int streams,\n      int coupled_streams,\n      const unsigned char *mapping\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);\n\n/** Decode a multistream Opus packet.\n  * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.\n  * @param[in] data <tt>const unsigned char*</tt>: Input payload.\n  *                                                Use a <code>NULL</code>\n  *                                                pointer to indicate packet\n  *                                                loss.\n  * @param len <tt>opus_int32</tt>: Number of bytes in payload.\n  * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved\n  *                                       samples.\n  *                                       This must contain room for\n  *                                       <code>frame_size*channels</code>\n  *                                       samples.\n  * @param frame_size <tt>int</tt>: The number of samples per channel of\n  *                                 available space in \\a pcm.\n  *                                 If this is less than the maximum packet duration\n  *                                 (120 ms; 5760 for 48kHz), this function will not be capable\n  *                                 of decoding some packets. In the case of PLC (data==NULL)\n  *                                 or FEC (decode_fec=1), then frame_size needs to be exactly\n  *                                 the duration of audio that is missing, otherwise the\n  *                                 decoder will not be in the optimal state to decode the\n  *                                 next incoming packet. For the PLC and FEC cases, frame_size\n  *                                 <b>must</b> be a multiple of 2.5 ms.\n  * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band\n  *                                 forward error correction data be decoded.\n  *                                 If no such data is available, the frame is\n  *                                 decoded as if it were lost.\n  * @returns Number of samples decoded on success or a negative error code\n  *          (see @ref opus_errorcodes) on failure.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode(\n    OpusMSDecoder *st,\n    const unsigned char *data,\n    opus_int32 len,\n    opus_int16 *pcm,\n    int frame_size,\n    int decode_fec\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);\n\n/** Decode a multistream Opus packet with floating point output.\n  * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.\n  * @param[in] data <tt>const unsigned char*</tt>: Input payload.\n  *                                                Use a <code>NULL</code>\n  *                                                pointer to indicate packet\n  *                                                loss.\n  * @param len <tt>opus_int32</tt>: Number of bytes in payload.\n  * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved\n  *                                       samples.\n  *                                       This must contain room for\n  *                                       <code>frame_size*channels</code>\n  *                                       samples.\n  * @param frame_size <tt>int</tt>: The number of samples per channel of\n  *                                 available space in \\a pcm.\n  *                                 If this is less than the maximum packet duration\n  *                                 (120 ms; 5760 for 48kHz), this function will not be capable\n  *                                 of decoding some packets. In the case of PLC (data==NULL)\n  *                                 or FEC (decode_fec=1), then frame_size needs to be exactly\n  *                                 the duration of audio that is missing, otherwise the\n  *                                 decoder will not be in the optimal state to decode the\n  *                                 next incoming packet. For the PLC and FEC cases, frame_size\n  *                                 <b>must</b> be a multiple of 2.5 ms.\n  * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band\n  *                                 forward error correction data be decoded.\n  *                                 If no such data is available, the frame is\n  *                                 decoded as if it were lost.\n  * @returns Number of samples decoded on success or a negative error code\n  *          (see @ref opus_errorcodes) on failure.\n  */\nOPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float(\n    OpusMSDecoder *st,\n    const unsigned char *data,\n    opus_int32 len,\n    float *pcm,\n    int frame_size,\n    int decode_fec\n) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);\n\n/** Perform a CTL function on a multistream Opus decoder.\n  *\n  * Generally the request and subsequent arguments are generated by a\n  * convenience macro.\n  * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.\n  * @param request This and all remaining parameters should be replaced by one\n  *                of the convenience macros in @ref opus_genericctls,\n  *                @ref opus_decoderctls, or @ref opus_multistream_ctls.\n  * @see opus_genericctls\n  * @see opus_decoderctls\n  * @see opus_multistream_ctls\n  */\nOPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);\n\n/** Frees an <code>OpusMSDecoder</code> allocated by\n  * opus_multistream_decoder_create().\n  * @param st <tt>OpusMSDecoder</tt>: Multistream decoder state to be freed.\n  */\nOPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st);\n\n/**@}*/\n\n/**@}*/\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* OPUS_MULTISTREAM_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/include/opus_types.h",
    "content": "/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */\n/* Modified by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n/* opus_types.h based on ogg_types.h from libogg */\n\n/**\n   @file opus_types.h\n   @brief Opus reference implementation types\n*/\n#ifndef OPUS_TYPES_H\n#define OPUS_TYPES_H\n\n/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */\n#if (defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H))\n#include <stdint.h>\n\n   typedef int16_t opus_int16;\n   typedef uint16_t opus_uint16;\n   typedef int32_t opus_int32;\n   typedef uint32_t opus_uint32;\n#elif defined(_WIN32)\n\n#  if defined(__CYGWIN__)\n#    include <_G_config.h>\n     typedef _G_int32_t opus_int32;\n     typedef _G_uint32_t opus_uint32;\n     typedef _G_int16 opus_int16;\n     typedef _G_uint16 opus_uint16;\n#  elif defined(__MINGW32__)\n     typedef short opus_int16;\n     typedef unsigned short opus_uint16;\n     typedef int opus_int32;\n     typedef unsigned int opus_uint32;\n#  elif defined(__MWERKS__)\n     typedef int opus_int32;\n     typedef unsigned int opus_uint32;\n     typedef short opus_int16;\n     typedef unsigned short opus_uint16;\n#  else\n     /* MSVC/Borland */\n     typedef __int32 opus_int32;\n     typedef unsigned __int32 opus_uint32;\n     typedef __int16 opus_int16;\n     typedef unsigned __int16 opus_uint16;\n#  endif\n\n#elif defined(__MACOS__)\n\n#  include <sys/types.h>\n   typedef SInt16 opus_int16;\n   typedef UInt16 opus_uint16;\n   typedef SInt32 opus_int32;\n   typedef UInt32 opus_uint32;\n\n#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */\n\n#  include <sys/types.h>\n   typedef int16_t opus_int16;\n   typedef u_int16_t opus_uint16;\n   typedef int32_t opus_int32;\n   typedef u_int32_t opus_uint32;\n\n#elif defined(__BEOS__)\n\n   /* Be */\n#  include <inttypes.h>\n   typedef int16 opus_int16;\n   typedef u_int16 opus_uint16;\n   typedef int32_t opus_int32;\n   typedef u_int32_t opus_uint32;\n\n#elif defined (__EMX__)\n\n   /* OS/2 GCC */\n   typedef short opus_int16;\n   typedef unsigned short opus_uint16;\n   typedef int opus_int32;\n   typedef unsigned int opus_uint32;\n\n#elif defined (DJGPP)\n\n   /* DJGPP */\n   typedef short opus_int16;\n   typedef unsigned short opus_uint16;\n   typedef int opus_int32;\n   typedef unsigned int opus_uint32;\n\n#elif defined(R5900)\n\n   /* PS2 EE */\n   typedef int opus_int32;\n   typedef unsigned opus_uint32;\n   typedef short opus_int16;\n   typedef unsigned short opus_uint16;\n\n#elif defined(__SYMBIAN32__)\n\n   /* Symbian GCC */\n   typedef signed short opus_int16;\n   typedef unsigned short opus_uint16;\n   typedef signed int opus_int32;\n   typedef unsigned int opus_uint32;\n\n#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)\n\n   typedef short opus_int16;\n   typedef unsigned short opus_uint16;\n   typedef long opus_int32;\n   typedef unsigned long opus_uint32;\n\n#elif defined(CONFIG_TI_C6X)\n\n   typedef short opus_int16;\n   typedef unsigned short opus_uint16;\n   typedef int opus_int32;\n   typedef unsigned int opus_uint32;\n\n#else\n\n   /* Give up, take a reasonable guess */\n   typedef short opus_int16;\n   typedef unsigned short opus_uint16;\n   typedef int opus_int32;\n   typedef unsigned int opus_uint32;\n\n#endif\n\n#define opus_int         int                     /* used for counters etc; at least 16 bits */\n#define opus_int64       long long\n#define opus_int8        signed char\n\n#define opus_uint        unsigned int            /* used for counters etc; at least 16 bits */\n#define opus_uint64      unsigned long long\n#define opus_uint8       unsigned char\n\n#endif  /* OPUS_TYPES_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/m4/as-gcc-inline-assembly.m4",
    "content": "dnl as-gcc-inline-assembly.m4 0.1.0\n\ndnl autostars m4 macro for detection of gcc inline assembly\n\ndnl David Schleef <ds@schleef.org>\n\ndnl AS_COMPILER_FLAG(ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED])\ndnl Tries to compile with the given CFLAGS.\ndnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags,\ndnl and ACTION-IF-NOT-ACCEPTED otherwise.\n\nAC_DEFUN([AS_GCC_INLINE_ASSEMBLY],\n[\n  AC_MSG_CHECKING([if compiler supports gcc-style inline assembly])\n\n  AC_TRY_COMPILE([], [\n#ifdef __GNUC_MINOR__\n#if (__GNUC__ * 1000 + __GNUC_MINOR__) < 3004\n#error GCC before 3.4 has critical bugs compiling inline assembly\n#endif\n#endif\n__asm__ (\"\"::) ], [flag_ok=yes], [flag_ok=no])\n\n  if test \"X$flag_ok\" = Xyes ; then\n    $1\n    true\n  else\n    $2\n    true\n  fi\n  AC_MSG_RESULT([$flag_ok])\n])\n\nAC_DEFUN([AS_ASM_ARM_NEON],\n[\n  AC_MSG_CHECKING([if assembler supports NEON instructions on ARM])\n\n  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[__asm__(\"vorr d0,d0,d0\")])],\n                    [AC_MSG_RESULT([yes])\n                     $1],\n                    [AC_MSG_RESULT([no])\n                     $2])\n])\n\nAC_DEFUN([AS_ASM_ARM_NEON_FORCE],\n[\n  AC_MSG_CHECKING([if assembler supports NEON instructions on ARM])\n\n  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[__asm__(\".arch armv7-a\\n.fpu neon\\n.object_arch armv4t\\nvorr d0,d0,d0\")])],\n                    [AC_MSG_RESULT([yes])\n                     $1],\n                    [AC_MSG_RESULT([no])\n                     $2])\n])\n\nAC_DEFUN([AS_ASM_ARM_MEDIA],\n[\n  AC_MSG_CHECKING([if assembler supports ARMv6 media instructions on ARM])\n\n  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[__asm__(\"shadd8 r3,r3,r3\")])],\n                    [AC_MSG_RESULT([yes])\n                     $1],\n                    [AC_MSG_RESULT([no])\n                     $2])\n])\n\nAC_DEFUN([AS_ASM_ARM_MEDIA_FORCE],\n[\n  AC_MSG_CHECKING([if assembler supports ARMv6 media instructions on ARM])\n\n  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[__asm__(\".arch armv6\\n.object_arch armv4t\\nshadd8 r3,r3,r3\")])],\n                    [AC_MSG_RESULT([yes])\n                     $1],\n                    [AC_MSG_RESULT([no])\n                     $2])\n])\n\nAC_DEFUN([AS_ASM_ARM_EDSP],\n[\n  AC_MSG_CHECKING([if assembler supports EDSP instructions on ARM])\n\n  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[__asm__(\"qadd r3,r3,r3\")])],\n                    [AC_MSG_RESULT([yes])\n                     $1],\n                    [AC_MSG_RESULT([no])\n                     $2])\n])\n\nAC_DEFUN([AS_ASM_ARM_EDSP_FORCE],\n[\n  AC_MSG_CHECKING([if assembler supports EDSP instructions on ARM])\n\n  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[__asm__(\".arch armv5te\\n.object_arch armv4t\\nqadd r3,r3,r3\")])],\n                    [AC_MSG_RESULT([yes])\n                     $1],\n                    [AC_MSG_RESULT([no])\n                     $2])\n])\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/m4/libtool.m4",
    "content": "# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-\n#\n#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,\n#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software\n#                 Foundation, Inc.\n#   Written by Gordon Matzigkeit, 1996\n#\n# This file is free software; the Free Software Foundation gives\n# unlimited permission to copy and/or distribute it, with or without\n# modifications, as long as this notice is preserved.\n\nm4_define([_LT_COPYING], [dnl\n#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,\n#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software\n#                 Foundation, Inc.\n#   Written by Gordon Matzigkeit, 1996\n#\n#   This file is part of GNU Libtool.\n#\n# GNU Libtool is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# As a special exception to the GNU General Public License,\n# if you distribute this file as part of a program or library that\n# is built using GNU Libtool, you may include this file under the\n# same distribution terms that you use for the rest of that program.\n#\n# GNU Libtool is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GNU Libtool; see the file COPYING.  If not, a copy\n# can be downloaded from http://www.gnu.org/licenses/gpl.html, or\n# obtained by writing to the Free Software Foundation, Inc.,\n# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n])\n\n# serial 57 LT_INIT\n\n\n# LT_PREREQ(VERSION)\n# ------------------\n# Complain and exit if this libtool version is less that VERSION.\nm4_defun([LT_PREREQ],\n[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,\n       [m4_default([$3],\n\t\t   [m4_fatal([Libtool version $1 or higher is required],\n\t\t             63)])],\n       [$2])])\n\n\n# _LT_CHECK_BUILDDIR\n# ------------------\n# Complain if the absolute build directory name contains unusual characters\nm4_defun([_LT_CHECK_BUILDDIR],\n[case `pwd` in\n  *\\ * | *\\\t*)\n    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;\nesac\n])\n\n\n# LT_INIT([OPTIONS])\n# ------------------\nAC_DEFUN([LT_INIT],\n[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT\nAC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl\nAC_BEFORE([$0], [LT_LANG])dnl\nAC_BEFORE([$0], [LT_OUTPUT])dnl\nAC_BEFORE([$0], [LTDL_INIT])dnl\nm4_require([_LT_CHECK_BUILDDIR])dnl\n\ndnl Autoconf doesn't catch unexpanded LT_ macros by default:\nm4_pattern_forbid([^_?LT_[A-Z_]+$])dnl\nm4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl\ndnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4\ndnl unless we require an AC_DEFUNed macro:\nAC_REQUIRE([LTOPTIONS_VERSION])dnl\nAC_REQUIRE([LTSUGAR_VERSION])dnl\nAC_REQUIRE([LTVERSION_VERSION])dnl\nAC_REQUIRE([LTOBSOLETE_VERSION])dnl\nm4_require([_LT_PROG_LTMAIN])dnl\n\n_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])\n\ndnl Parse OPTIONS\n_LT_SET_OPTIONS([$0], [$1])\n\n# This can be used to rebuild libtool when needed\nLIBTOOL_DEPS=\"$ltmain\"\n\n# Always use our own libtool.\nLIBTOOL='$(SHELL) $(top_builddir)/libtool'\nAC_SUBST(LIBTOOL)dnl\n\n_LT_SETUP\n\n# Only expand once:\nm4_define([LT_INIT])\n])# LT_INIT\n\n# Old names:\nAU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])\nAU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_PROG_LIBTOOL], [])\ndnl AC_DEFUN([AM_PROG_LIBTOOL], [])\n\n\n# _LT_CC_BASENAME(CC)\n# -------------------\n# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.\nm4_defun([_LT_CC_BASENAME],\n[for cc_temp in $1\"\"; do\n  case $cc_temp in\n    compile | *[[\\\\/]]compile | ccache | *[[\\\\/]]ccache ) ;;\n    distcc | *[[\\\\/]]distcc | purify | *[[\\\\/]]purify ) ;;\n    \\-*) ;;\n    *) break;;\n  esac\ndone\ncc_basename=`$ECHO \"$cc_temp\" | $SED \"s%.*/%%; s%^$host_alias-%%\"`\n])\n\n\n# _LT_FILEUTILS_DEFAULTS\n# ----------------------\n# It is okay to use these file commands and assume they have been set\n# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.\nm4_defun([_LT_FILEUTILS_DEFAULTS],\n[: ${CP=\"cp -f\"}\n: ${MV=\"mv -f\"}\n: ${RM=\"rm -f\"}\n])# _LT_FILEUTILS_DEFAULTS\n\n\n# _LT_SETUP\n# ---------\nm4_defun([_LT_SETUP],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\nAC_REQUIRE([AC_CANONICAL_BUILD])dnl\nAC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl\nAC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl\n\n_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl\ndnl\n_LT_DECL([], [host_alias], [0], [The host system])dnl\n_LT_DECL([], [host], [0])dnl\n_LT_DECL([], [host_os], [0])dnl\ndnl\n_LT_DECL([], [build_alias], [0], [The build system])dnl\n_LT_DECL([], [build], [0])dnl\n_LT_DECL([], [build_os], [0])dnl\ndnl\nAC_REQUIRE([AC_PROG_CC])dnl\nAC_REQUIRE([LT_PATH_LD])dnl\nAC_REQUIRE([LT_PATH_NM])dnl\ndnl\nAC_REQUIRE([AC_PROG_LN_S])dnl\ntest -z \"$LN_S\" && LN_S=\"ln -s\"\n_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl\ndnl\nAC_REQUIRE([LT_CMD_MAX_LEN])dnl\n_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally \"o\")])dnl\n_LT_DECL([], [exeext], [0], [Executable file suffix (normally \"\")])dnl\ndnl\nm4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_CHECK_SHELL_FEATURES])dnl\nm4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl\nm4_require([_LT_CMD_RELOAD])dnl\nm4_require([_LT_CHECK_MAGIC_METHOD])dnl\nm4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl\nm4_require([_LT_CMD_OLD_ARCHIVE])dnl\nm4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl\nm4_require([_LT_WITH_SYSROOT])dnl\n\n_LT_CONFIG_LIBTOOL_INIT([\n# See if we are running on zsh, and set the options which allow our\n# commands through without removal of \\ escapes INIT.\nif test -n \"\\${ZSH_VERSION+set}\" ; then\n   setopt NO_GLOB_SUBST\nfi\n])\nif test -n \"${ZSH_VERSION+set}\" ; then\n   setopt NO_GLOB_SUBST\nfi\n\n_LT_CHECK_OBJDIR\n\nm4_require([_LT_TAG_COMPILER])dnl\n\ncase $host_os in\naix3*)\n  # AIX sometimes has problems with the GCC collect2 program.  For some\n  # reason, if we set the COLLECT_NAMES environment variable, the problems\n  # vanish in a puff of smoke.\n  if test \"X${COLLECT_NAMES+set}\" != Xset; then\n    COLLECT_NAMES=\n    export COLLECT_NAMES\n  fi\n  ;;\nesac\n\n# Global variables:\nofile=libtool\ncan_build_shared=yes\n\n# All known linkers require a `.a' archive for static linking (except MSVC,\n# which needs '.lib').\nlibext=a\n\nwith_gnu_ld=\"$lt_cv_prog_gnu_ld\"\n\nold_CC=\"$CC\"\nold_CFLAGS=\"$CFLAGS\"\n\n# Set sane defaults for various variables\ntest -z \"$CC\" && CC=cc\ntest -z \"$LTCC\" && LTCC=$CC\ntest -z \"$LTCFLAGS\" && LTCFLAGS=$CFLAGS\ntest -z \"$LD\" && LD=ld\ntest -z \"$ac_objext\" && ac_objext=o\n\n_LT_CC_BASENAME([$compiler])\n\n# Only perform the check for file, if the check method requires it\ntest -z \"$MAGIC_CMD\" && MAGIC_CMD=file\ncase $deplibs_check_method in\nfile_magic*)\n  if test \"$file_magic_cmd\" = '$MAGIC_CMD'; then\n    _LT_PATH_MAGIC\n  fi\n  ;;\nesac\n\n# Use C for the default configuration in the libtool script\nLT_SUPPORTED_TAG([CC])\n_LT_LANG_C_CONFIG\n_LT_LANG_DEFAULT_CONFIG\n_LT_CONFIG_COMMANDS\n])# _LT_SETUP\n\n\n# _LT_PREPARE_SED_QUOTE_VARS\n# --------------------------\n# Define a few sed substitution that help us do robust quoting.\nm4_defun([_LT_PREPARE_SED_QUOTE_VARS],\n[# Backslashify metacharacters that are still active within\n# double-quoted strings.\nsed_quote_subst='s/\\([[\"`$\\\\]]\\)/\\\\\\1/g'\n\n# Same as above, but do not quote variable references.\ndouble_quote_subst='s/\\([[\"`\\\\]]\\)/\\\\\\1/g'\n\n# Sed substitution to delay expansion of an escaped shell variable in a\n# double_quote_subst'ed string.\ndelay_variable_subst='s/\\\\\\\\\\\\\\\\\\\\\\$/\\\\\\\\\\\\$/g'\n\n# Sed substitution to delay expansion of an escaped single quote.\ndelay_single_quote_subst='s/'\\''/'\\'\\\\\\\\\\\\\\'\\''/g'\n\n# Sed substitution to avoid accidental globbing in evaled expressions\nno_glob_subst='s/\\*/\\\\\\*/g'\n])\n\n# _LT_PROG_LTMAIN\n# ---------------\n# Note that this code is called both from `configure', and `config.status'\n# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,\n# `config.status' has no value for ac_aux_dir unless we are using Automake,\n# so we pass a copy along to make sure it has a sensible value anyway.\nm4_defun([_LT_PROG_LTMAIN],\n[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl\n_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])\nltmain=\"$ac_aux_dir/ltmain.sh\"\n])# _LT_PROG_LTMAIN\n\n\n## ------------------------------------- ##\n## Accumulate code for creating libtool. ##\n## ------------------------------------- ##\n\n# So that we can recreate a full libtool script including additional\n# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS\n# in macros and then make a single call at the end using the `libtool'\n# label.\n\n\n# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])\n# ----------------------------------------\n# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.\nm4_define([_LT_CONFIG_LIBTOOL_INIT],\n[m4_ifval([$1],\n          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],\n                     [$1\n])])])\n\n# Initialize.\nm4_define([_LT_OUTPUT_LIBTOOL_INIT])\n\n\n# _LT_CONFIG_LIBTOOL([COMMANDS])\n# ------------------------------\n# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.\nm4_define([_LT_CONFIG_LIBTOOL],\n[m4_ifval([$1],\n          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],\n                     [$1\n])])])\n\n# Initialize.\nm4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])\n\n\n# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])\n# -----------------------------------------------------\nm4_defun([_LT_CONFIG_SAVE_COMMANDS],\n[_LT_CONFIG_LIBTOOL([$1])\n_LT_CONFIG_LIBTOOL_INIT([$2])\n])\n\n\n# _LT_FORMAT_COMMENT([COMMENT])\n# -----------------------------\n# Add leading comment marks to the start of each line, and a trailing\n# full-stop to the whole comment if one is not present already.\nm4_define([_LT_FORMAT_COMMENT],\n[m4_ifval([$1], [\nm4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],\n              [['`$\\]], [\\\\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])\n)])\n\n\n\n## ------------------------ ##\n## FIXME: Eliminate VARNAME ##\n## ------------------------ ##\n\n\n# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])\n# -------------------------------------------------------------------\n# CONFIGNAME is the name given to the value in the libtool script.\n# VARNAME is the (base) name used in the configure script.\n# VALUE may be 0, 1 or 2 for a computed quote escaped value based on\n# VARNAME.  Any other value will be used directly.\nm4_define([_LT_DECL],\n[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],\n    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],\n\t[m4_ifval([$1], [$1], [$2])])\n    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])\n    m4_ifval([$4],\n\t[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])\n    lt_dict_add_subkey([lt_decl_dict], [$2],\n\t[tagged?], [m4_ifval([$5], [yes], [no])])])\n])\n\n\n# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])\n# --------------------------------------------------------\nm4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])\n\n\n# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])\n# ------------------------------------------------\nm4_define([lt_decl_tag_varnames],\n[_lt_decl_filter([tagged?], [yes], $@)])\n\n\n# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])\n# ---------------------------------------------------------\nm4_define([_lt_decl_filter],\n[m4_case([$#],\n  [0], [m4_fatal([$0: too few arguments: $#])],\n  [1], [m4_fatal([$0: too few arguments: $#: $1])],\n  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],\n  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],\n  [lt_dict_filter([lt_decl_dict], $@)])[]dnl\n])\n\n\n# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])\n# --------------------------------------------------\nm4_define([lt_decl_quote_varnames],\n[_lt_decl_filter([value], [1], $@)])\n\n\n# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])\n# ---------------------------------------------------\nm4_define([lt_decl_dquote_varnames],\n[_lt_decl_filter([value], [2], $@)])\n\n\n# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])\n# ---------------------------------------------------\nm4_define([lt_decl_varnames_tagged],\n[m4_assert([$# <= 2])dnl\n_$0(m4_quote(m4_default([$1], [[, ]])),\n    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),\n    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])\nm4_define([_lt_decl_varnames_tagged],\n[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])\n\n\n# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])\n# ------------------------------------------------\nm4_define([lt_decl_all_varnames],\n[_$0(m4_quote(m4_default([$1], [[, ]])),\n     m4_if([$2], [],\n\t   m4_quote(lt_decl_varnames),\n\tm4_quote(m4_shift($@))))[]dnl\n])\nm4_define([_lt_decl_all_varnames],\n[lt_join($@, lt_decl_varnames_tagged([$1],\n\t\t\tlt_decl_tag_varnames([[, ]], m4_shift($@))))dnl\n])\n\n\n# _LT_CONFIG_STATUS_DECLARE([VARNAME])\n# ------------------------------------\n# Quote a variable value, and forward it to `config.status' so that its\n# declaration there will have the same value as in `configure'.  VARNAME\n# must have a single quote delimited value for this to work.\nm4_define([_LT_CONFIG_STATUS_DECLARE],\n[$1='`$ECHO \"$][$1\" | $SED \"$delay_single_quote_subst\"`'])\n\n\n# _LT_CONFIG_STATUS_DECLARATIONS\n# ------------------------------\n# We delimit libtool config variables with single quotes, so when\n# we write them to config.status, we have to be sure to quote all\n# embedded single quotes properly.  In configure, this macro expands\n# each variable declared with _LT_DECL (and _LT_TAGDECL) into:\n#\n#    <var>='`$ECHO \"$<var>\" | $SED \"$delay_single_quote_subst\"`'\nm4_defun([_LT_CONFIG_STATUS_DECLARATIONS],\n[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),\n    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])\n\n\n# _LT_LIBTOOL_TAGS\n# ----------------\n# Output comment and list of tags supported by the script\nm4_defun([_LT_LIBTOOL_TAGS],\n[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl\navailable_tags=\"_LT_TAGS\"dnl\n])\n\n\n# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])\n# -----------------------------------\n# Extract the dictionary values for VARNAME (optionally with TAG) and\n# expand to a commented shell variable setting:\n#\n#    # Some comment about what VAR is for.\n#    visible_name=$lt_internal_name\nm4_define([_LT_LIBTOOL_DECLARE],\n[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],\n\t\t\t\t\t   [description])))[]dnl\nm4_pushdef([_libtool_name],\n    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl\nm4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),\n    [0], [_libtool_name=[$]$1],\n    [1], [_libtool_name=$lt_[]$1],\n    [2], [_libtool_name=$lt_[]$1],\n    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl\nm4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl\n])\n\n\n# _LT_LIBTOOL_CONFIG_VARS\n# -----------------------\n# Produce commented declarations of non-tagged libtool config variables\n# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'\n# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG\n# section) are produced by _LT_LIBTOOL_TAG_VARS.\nm4_defun([_LT_LIBTOOL_CONFIG_VARS],\n[m4_foreach([_lt_var],\n    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),\n    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])\n\n\n# _LT_LIBTOOL_TAG_VARS(TAG)\n# -------------------------\nm4_define([_LT_LIBTOOL_TAG_VARS],\n[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),\n    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])\n\n\n# _LT_TAGVAR(VARNAME, [TAGNAME])\n# ------------------------------\nm4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])\n\n\n# _LT_CONFIG_COMMANDS\n# -------------------\n# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of\n# variables for single and double quote escaping we saved from calls\n# to _LT_DECL, we can put quote escaped variables declarations\n# into `config.status', and then the shell code to quote escape them in\n# for loops in `config.status'.  Finally, any additional code accumulated\n# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.\nm4_defun([_LT_CONFIG_COMMANDS],\n[AC_PROVIDE_IFELSE([LT_OUTPUT],\n\tdnl If the libtool generation code has been placed in $CONFIG_LT,\n\tdnl instead of duplicating it all over again into config.status,\n\tdnl then we will have config.status run $CONFIG_LT later, so it\n\tdnl needs to know what name is stored there:\n        [AC_CONFIG_COMMANDS([libtool],\n            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],\n    dnl If the libtool generation code is destined for config.status,\n    dnl expand the accumulated commands and init code now:\n    [AC_CONFIG_COMMANDS([libtool],\n        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])\n])#_LT_CONFIG_COMMANDS\n\n\n# Initialize.\nm4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],\n[\n\n# The HP-UX ksh and POSIX shell print the target directory to stdout\n# if CDPATH is set.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\nsed_quote_subst='$sed_quote_subst'\ndouble_quote_subst='$double_quote_subst'\ndelay_variable_subst='$delay_variable_subst'\n_LT_CONFIG_STATUS_DECLARATIONS\nLTCC='$LTCC'\nLTCFLAGS='$LTCFLAGS'\ncompiler='$compiler_DEFAULT'\n\n# A function that is used when there is no print builtin or printf.\nfunc_fallback_echo ()\n{\n  eval 'cat <<_LTECHO_EOF\n\\$[]1\n_LTECHO_EOF'\n}\n\n# Quote evaled strings.\nfor var in lt_decl_all_varnames([[ \\\n]], lt_decl_quote_varnames); do\n    case \\`eval \\\\\\\\\\$ECHO \\\\\\\\\"\"\\\\\\\\\\$\\$var\"\\\\\\\\\"\\` in\n    *[[\\\\\\\\\\\\\\`\\\\\"\\\\\\$]]*)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\`\\\\\\$ECHO \\\\\"\\\\\\$\\$var\\\\\" | \\\\\\$SED \\\\\"\\\\\\$sed_quote_subst\\\\\"\\\\\\`\\\\\\\\\\\\\"\"\n      ;;\n    *)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\$\\$var\\\\\\\\\\\\\"\"\n      ;;\n    esac\ndone\n\n# Double-quote double-evaled strings.\nfor var in lt_decl_all_varnames([[ \\\n]], lt_decl_dquote_varnames); do\n    case \\`eval \\\\\\\\\\$ECHO \\\\\\\\\"\"\\\\\\\\\\$\\$var\"\\\\\\\\\"\\` in\n    *[[\\\\\\\\\\\\\\`\\\\\"\\\\\\$]]*)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\`\\\\\\$ECHO \\\\\"\\\\\\$\\$var\\\\\" | \\\\\\$SED -e \\\\\"\\\\\\$double_quote_subst\\\\\" -e \\\\\"\\\\\\$sed_quote_subst\\\\\" -e \\\\\"\\\\\\$delay_variable_subst\\\\\"\\\\\\`\\\\\\\\\\\\\"\"\n      ;;\n    *)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\$\\$var\\\\\\\\\\\\\"\"\n      ;;\n    esac\ndone\n\n_LT_OUTPUT_LIBTOOL_INIT\n])\n\n# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])\n# ------------------------------------\n# Generate a child script FILE with all initialization necessary to\n# reuse the environment learned by the parent script, and make the\n# file executable.  If COMMENT is supplied, it is inserted after the\n# `#!' sequence but before initialization text begins.  After this\n# macro, additional text can be appended to FILE to form the body of\n# the child script.  The macro ends with non-zero status if the\n# file could not be fully written (such as if the disk is full).\nm4_ifdef([AS_INIT_GENERATED],\n[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],\n[m4_defun([_LT_GENERATED_FILE_INIT],\n[m4_require([AS_PREPARE])]dnl\n[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl\n[lt_write_fail=0\ncat >$1 <<_ASEOF || lt_write_fail=1\n#! $SHELL\n# Generated by $as_me.\n$2\nSHELL=\\${CONFIG_SHELL-$SHELL}\nexport SHELL\n_ASEOF\ncat >>$1 <<\\_ASEOF || lt_write_fail=1\nAS_SHELL_SANITIZE\n_AS_PREPARE\nexec AS_MESSAGE_FD>&1\n_ASEOF\ntest $lt_write_fail = 0 && chmod +x $1[]dnl\nm4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT\n\n# LT_OUTPUT\n# ---------\n# This macro allows early generation of the libtool script (before\n# AC_OUTPUT is called), incase it is used in configure for compilation\n# tests.\nAC_DEFUN([LT_OUTPUT],\n[: ${CONFIG_LT=./config.lt}\nAC_MSG_NOTICE([creating $CONFIG_LT])\n_LT_GENERATED_FILE_INIT([\"$CONFIG_LT\"],\n[# Run this file to recreate a libtool stub with the current configuration.])\n\ncat >>\"$CONFIG_LT\" <<\\_LTEOF\nlt_cl_silent=false\nexec AS_MESSAGE_LOG_FD>>config.log\n{\n  echo\n  AS_BOX([Running $as_me.])\n} >&AS_MESSAGE_LOG_FD\n\nlt_cl_help=\"\\\n\\`$as_me' creates a local libtool stub from the current configuration,\nfor use in further configure time tests before the real libtool is\ngenerated.\n\nUsage: $[0] [[OPTIONS]]\n\n  -h, --help      print this help, then exit\n  -V, --version   print version number, then exit\n  -q, --quiet     do not print progress messages\n  -d, --debug     don't remove temporary files\n\nReport bugs to <bug-libtool@gnu.org>.\"\n\nlt_cl_version=\"\\\nm4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl\nm4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])\nconfigured by $[0], generated by m4_PACKAGE_STRING.\n\nCopyright (C) 2011 Free Software Foundation, Inc.\nThis config.lt script is free software; the Free Software Foundation\ngives unlimited permision to copy, distribute and modify it.\"\n\nwhile test $[#] != 0\ndo\n  case $[1] in\n    --version | --v* | -V )\n      echo \"$lt_cl_version\"; exit 0 ;;\n    --help | --h* | -h )\n      echo \"$lt_cl_help\"; exit 0 ;;\n    --debug | --d* | -d )\n      debug=: ;;\n    --quiet | --q* | --silent | --s* | -q )\n      lt_cl_silent=: ;;\n\n    -*) AC_MSG_ERROR([unrecognized option: $[1]\nTry \\`$[0] --help' for more information.]) ;;\n\n    *) AC_MSG_ERROR([unrecognized argument: $[1]\nTry \\`$[0] --help' for more information.]) ;;\n  esac\n  shift\ndone\n\nif $lt_cl_silent; then\n  exec AS_MESSAGE_FD>/dev/null\nfi\n_LTEOF\n\ncat >>\"$CONFIG_LT\" <<_LTEOF\n_LT_OUTPUT_LIBTOOL_COMMANDS_INIT\n_LTEOF\n\ncat >>\"$CONFIG_LT\" <<\\_LTEOF\nAC_MSG_NOTICE([creating $ofile])\n_LT_OUTPUT_LIBTOOL_COMMANDS\nAS_EXIT(0)\n_LTEOF\nchmod +x \"$CONFIG_LT\"\n\n# configure is writing to config.log, but config.lt does its own redirection,\n# appending to config.log, which fails on DOS, as config.log is still kept\n# open by configure.  Here we exec the FD to /dev/null, effectively closing\n# config.log, so it can be properly (re)opened and appended to by config.lt.\nlt_cl_success=:\ntest \"$silent\" = yes &&\n  lt_config_lt_args=\"$lt_config_lt_args --quiet\"\nexec AS_MESSAGE_LOG_FD>/dev/null\n$SHELL \"$CONFIG_LT\" $lt_config_lt_args || lt_cl_success=false\nexec AS_MESSAGE_LOG_FD>>config.log\n$lt_cl_success || AS_EXIT(1)\n])# LT_OUTPUT\n\n\n# _LT_CONFIG(TAG)\n# ---------------\n# If TAG is the built-in tag, create an initial libtool script with a\n# default configuration from the untagged config vars.  Otherwise add code\n# to config.status for appending the configuration named by TAG from the\n# matching tagged config vars.\nm4_defun([_LT_CONFIG],\n[m4_require([_LT_FILEUTILS_DEFAULTS])dnl\n_LT_CONFIG_SAVE_COMMANDS([\n  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl\n  m4_if(_LT_TAG, [C], [\n    # See if we are running on zsh, and set the options which allow our\n    # commands through without removal of \\ escapes.\n    if test -n \"${ZSH_VERSION+set}\" ; then\n      setopt NO_GLOB_SUBST\n    fi\n\n    cfgfile=\"${ofile}T\"\n    trap \"$RM \\\"$cfgfile\\\"; exit 1\" 1 2 15\n    $RM \"$cfgfile\"\n\n    cat <<_LT_EOF >> \"$cfgfile\"\n#! $SHELL\n\n# `$ECHO \"$ofile\" | sed 's%^.*/%%'` - Provide generalized library-building support services.\n# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION\n# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:\n# NOTE: Changes made to this file will be lost: look at ltmain.sh.\n#\n_LT_COPYING\n_LT_LIBTOOL_TAGS\n\n# ### BEGIN LIBTOOL CONFIG\n_LT_LIBTOOL_CONFIG_VARS\n_LT_LIBTOOL_TAG_VARS\n# ### END LIBTOOL CONFIG\n\n_LT_EOF\n\n  case $host_os in\n  aix3*)\n    cat <<\\_LT_EOF >> \"$cfgfile\"\n# AIX sometimes has problems with the GCC collect2 program.  For some\n# reason, if we set the COLLECT_NAMES environment variable, the problems\n# vanish in a puff of smoke.\nif test \"X${COLLECT_NAMES+set}\" != Xset; then\n  COLLECT_NAMES=\n  export COLLECT_NAMES\nfi\n_LT_EOF\n    ;;\n  esac\n\n  _LT_PROG_LTMAIN\n\n  # We use sed instead of cat because bash on DJGPP gets confused if\n  # if finds mixed CR/LF and LF-only lines.  Since sed operates in\n  # text mode, it properly converts lines to CR/LF.  This bash problem\n  # is reportedly fixed, but why not run on old versions too?\n  sed '$q' \"$ltmain\" >> \"$cfgfile\" \\\n     || (rm -f \"$cfgfile\"; exit 1)\n\n  _LT_PROG_REPLACE_SHELLFNS\n\n   mv -f \"$cfgfile\" \"$ofile\" ||\n    (rm -f \"$ofile\" && cp \"$cfgfile\" \"$ofile\" && rm -f \"$cfgfile\")\n  chmod +x \"$ofile\"\n],\n[cat <<_LT_EOF >> \"$ofile\"\n\ndnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded\ndnl in a comment (ie after a #).\n# ### BEGIN LIBTOOL TAG CONFIG: $1\n_LT_LIBTOOL_TAG_VARS(_LT_TAG)\n# ### END LIBTOOL TAG CONFIG: $1\n_LT_EOF\n])dnl /m4_if\n],\n[m4_if([$1], [], [\n    PACKAGE='$PACKAGE'\n    VERSION='$VERSION'\n    TIMESTAMP='$TIMESTAMP'\n    RM='$RM'\n    ofile='$ofile'], [])\n])dnl /_LT_CONFIG_SAVE_COMMANDS\n])# _LT_CONFIG\n\n\n# LT_SUPPORTED_TAG(TAG)\n# ---------------------\n# Trace this macro to discover what tags are supported by the libtool\n# --tag option, using:\n#    autoconf --trace 'LT_SUPPORTED_TAG:$1'\nAC_DEFUN([LT_SUPPORTED_TAG], [])\n\n\n# C support is built-in for now\nm4_define([_LT_LANG_C_enabled], [])\nm4_define([_LT_TAGS], [])\n\n\n# LT_LANG(LANG)\n# -------------\n# Enable libtool support for the given language if not already enabled.\nAC_DEFUN([LT_LANG],\n[AC_BEFORE([$0], [LT_OUTPUT])dnl\nm4_case([$1],\n  [C],\t\t\t[_LT_LANG(C)],\n  [C++],\t\t[_LT_LANG(CXX)],\n  [Go],\t\t\t[_LT_LANG(GO)],\n  [Java],\t\t[_LT_LANG(GCJ)],\n  [Fortran 77],\t\t[_LT_LANG(F77)],\n  [Fortran],\t\t[_LT_LANG(FC)],\n  [Windows Resource],\t[_LT_LANG(RC)],\n  [m4_ifdef([_LT_LANG_]$1[_CONFIG],\n    [_LT_LANG($1)],\n    [m4_fatal([$0: unsupported language: \"$1\"])])])dnl\n])# LT_LANG\n\n\n# _LT_LANG(LANGNAME)\n# ------------------\nm4_defun([_LT_LANG],\n[m4_ifdef([_LT_LANG_]$1[_enabled], [],\n  [LT_SUPPORTED_TAG([$1])dnl\n  m4_append([_LT_TAGS], [$1 ])dnl\n  m4_define([_LT_LANG_]$1[_enabled], [])dnl\n  _LT_LANG_$1_CONFIG($1)])dnl\n])# _LT_LANG\n\n\nm4_ifndef([AC_PROG_GO], [\n############################################################\n# NOTE: This macro has been submitted for inclusion into   #\n#  GNU Autoconf as AC_PROG_GO.  When it is available in    #\n#  a released version of Autoconf we should remove this    #\n#  macro and use it instead.                               #\n############################################################\nm4_defun([AC_PROG_GO],\n[AC_LANG_PUSH(Go)dnl\nAC_ARG_VAR([GOC],     [Go compiler command])dnl\nAC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl\n_AC_ARG_VAR_LDFLAGS()dnl\nAC_CHECK_TOOL(GOC, gccgo)\nif test -z \"$GOC\"; then\n  if test -n \"$ac_tool_prefix\"; then\n    AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])\n  fi\nfi\nif test -z \"$GOC\"; then\n  AC_CHECK_PROG(GOC, gccgo, gccgo, false)\nfi\n])#m4_defun\n])#m4_ifndef\n\n\n# _LT_LANG_DEFAULT_CONFIG\n# -----------------------\nm4_defun([_LT_LANG_DEFAULT_CONFIG],\n[AC_PROVIDE_IFELSE([AC_PROG_CXX],\n  [LT_LANG(CXX)],\n  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])\n\nAC_PROVIDE_IFELSE([AC_PROG_F77],\n  [LT_LANG(F77)],\n  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])\n\nAC_PROVIDE_IFELSE([AC_PROG_FC],\n  [LT_LANG(FC)],\n  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])\n\ndnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal\ndnl pulling things in needlessly.\nAC_PROVIDE_IFELSE([AC_PROG_GCJ],\n  [LT_LANG(GCJ)],\n  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],\n    [LT_LANG(GCJ)],\n    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],\n      [LT_LANG(GCJ)],\n      [m4_ifdef([AC_PROG_GCJ],\n\t[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])\n       m4_ifdef([A][M_PROG_GCJ],\n\t[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])\n       m4_ifdef([LT_PROG_GCJ],\n\t[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])\n\nAC_PROVIDE_IFELSE([AC_PROG_GO],\n  [LT_LANG(GO)],\n  [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])\n\nAC_PROVIDE_IFELSE([LT_PROG_RC],\n  [LT_LANG(RC)],\n  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])\n])# _LT_LANG_DEFAULT_CONFIG\n\n# Obsolete macros:\nAU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])\nAU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])\nAU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])\nAU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])\nAU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_CXX], [])\ndnl AC_DEFUN([AC_LIBTOOL_F77], [])\ndnl AC_DEFUN([AC_LIBTOOL_FC], [])\ndnl AC_DEFUN([AC_LIBTOOL_GCJ], [])\ndnl AC_DEFUN([AC_LIBTOOL_RC], [])\n\n\n# _LT_TAG_COMPILER\n# ----------------\nm4_defun([_LT_TAG_COMPILER],\n[AC_REQUIRE([AC_PROG_CC])dnl\n\n_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl\n_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl\n_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl\n_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl\n\n# If no C compiler was specified, use CC.\nLTCC=${LTCC-\"$CC\"}\n\n# If no C compiler flags were specified, use CFLAGS.\nLTCFLAGS=${LTCFLAGS-\"$CFLAGS\"}\n\n# Allow CC to be a program name with arguments.\ncompiler=$CC\n])# _LT_TAG_COMPILER\n\n\n# _LT_COMPILER_BOILERPLATE\n# ------------------------\n# Check for compiler boilerplate output or warnings with\n# the simple compiler test code.\nm4_defun([_LT_COMPILER_BOILERPLATE],\n[m4_require([_LT_DECL_SED])dnl\nac_outfile=conftest.$ac_objext\necho \"$lt_simple_compile_test_code\" >conftest.$ac_ext\neval \"$ac_compile\" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err\n_lt_compiler_boilerplate=`cat conftest.err`\n$RM conftest*\n])# _LT_COMPILER_BOILERPLATE\n\n\n# _LT_LINKER_BOILERPLATE\n# ----------------------\n# Check for linker boilerplate output or warnings with\n# the simple link test code.\nm4_defun([_LT_LINKER_BOILERPLATE],\n[m4_require([_LT_DECL_SED])dnl\nac_outfile=conftest.$ac_objext\necho \"$lt_simple_link_test_code\" >conftest.$ac_ext\neval \"$ac_link\" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err\n_lt_linker_boilerplate=`cat conftest.err`\n$RM -r conftest*\n])# _LT_LINKER_BOILERPLATE\n\n# _LT_REQUIRED_DARWIN_CHECKS\n# -------------------------\nm4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[\n  case $host_os in\n    rhapsody* | darwin*)\n    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])\n    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])\n    AC_CHECK_TOOL([LIPO], [lipo], [:])\n    AC_CHECK_TOOL([OTOOL], [otool], [:])\n    AC_CHECK_TOOL([OTOOL64], [otool64], [:])\n    _LT_DECL([], [DSYMUTIL], [1],\n      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])\n    _LT_DECL([], [NMEDIT], [1],\n      [Tool to change global to local symbols on Mac OS X])\n    _LT_DECL([], [LIPO], [1],\n      [Tool to manipulate fat objects and archives on Mac OS X])\n    _LT_DECL([], [OTOOL], [1],\n      [ldd/readelf like tool for Mach-O binaries on Mac OS X])\n    _LT_DECL([], [OTOOL64], [1],\n      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])\n\n    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],\n      [lt_cv_apple_cc_single_mod=no\n      if test -z \"${LT_MULTI_MODULE}\"; then\n\t# By default we will add the -single_module flag. You can override\n\t# by either setting the environment variable LT_MULTI_MODULE\n\t# non-empty at configure time, or by adding -multi_module to the\n\t# link flags.\n\trm -rf libconftest.dylib*\n\techo \"int foo(void){return 1;}\" > conftest.c\n\techo \"$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \\\n-dynamiclib -Wl,-single_module conftest.c\" >&AS_MESSAGE_LOG_FD\n\t$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \\\n\t  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err\n        _lt_result=$?\n\t# If there is a non-empty error log, and \"single_module\"\n\t# appears in it, assume the flag caused a linker warning\n        if test -s conftest.err && $GREP single_module conftest.err; then\n\t  cat conftest.err >&AS_MESSAGE_LOG_FD\n\t# Otherwise, if the output was created with a 0 exit code from\n\t# the compiler, it worked.\n\telif test -f libconftest.dylib && test $_lt_result -eq 0; then\n\t  lt_cv_apple_cc_single_mod=yes\n\telse\n\t  cat conftest.err >&AS_MESSAGE_LOG_FD\n\tfi\n\trm -rf libconftest.dylib*\n\trm -f conftest.*\n      fi])\n\n    AC_CACHE_CHECK([for -exported_symbols_list linker flag],\n      [lt_cv_ld_exported_symbols_list],\n      [lt_cv_ld_exported_symbols_list=no\n      save_LDFLAGS=$LDFLAGS\n      echo \"_main\" > conftest.sym\n      LDFLAGS=\"$LDFLAGS -Wl,-exported_symbols_list,conftest.sym\"\n      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],\n\t[lt_cv_ld_exported_symbols_list=yes],\n\t[lt_cv_ld_exported_symbols_list=no])\n\tLDFLAGS=\"$save_LDFLAGS\"\n    ])\n\n    AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],\n      [lt_cv_ld_force_load=no\n      cat > conftest.c << _LT_EOF\nint forced_loaded() { return 2;}\n_LT_EOF\n      echo \"$LTCC $LTCFLAGS -c -o conftest.o conftest.c\" >&AS_MESSAGE_LOG_FD\n      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD\n      echo \"$AR cru libconftest.a conftest.o\" >&AS_MESSAGE_LOG_FD\n      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD\n      echo \"$RANLIB libconftest.a\" >&AS_MESSAGE_LOG_FD\n      $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD\n      cat > conftest.c << _LT_EOF\nint main() { return 0;}\n_LT_EOF\n      echo \"$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a\" >&AS_MESSAGE_LOG_FD\n      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err\n      _lt_result=$?\n      if test -s conftest.err && $GREP force_load conftest.err; then\n\tcat conftest.err >&AS_MESSAGE_LOG_FD\n      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then\n\tlt_cv_ld_force_load=yes\n      else\n\tcat conftest.err >&AS_MESSAGE_LOG_FD\n      fi\n        rm -f conftest.err libconftest.a conftest conftest.c\n        rm -rf conftest.dSYM\n    ])\n    case $host_os in\n    rhapsody* | darwin1.[[012]])\n      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;\n    darwin1.*)\n      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;\n    darwin*) # darwin 5.x on\n      # if running on 10.5 or later, the deployment target defaults\n      # to the OS version, if on x86, and 10.4, the deployment\n      # target defaults to 10.4. Don't you love it?\n      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in\n\t10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)\n\t  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;\n\t10.[[012]]*)\n\t  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;\n\t10.*)\n\t  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;\n      esac\n    ;;\n  esac\n    if test \"$lt_cv_apple_cc_single_mod\" = \"yes\"; then\n      _lt_dar_single_mod='$single_module'\n    fi\n    if test \"$lt_cv_ld_exported_symbols_list\" = \"yes\"; then\n      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'\n    else\n      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'\n    fi\n    if test \"$DSYMUTIL\" != \":\" && test \"$lt_cv_ld_force_load\" = \"no\"; then\n      _lt_dsymutil='~$DSYMUTIL $lib || :'\n    else\n      _lt_dsymutil=\n    fi\n    ;;\n  esac\n])\n\n\n# _LT_DARWIN_LINKER_FEATURES([TAG])\n# ---------------------------------\n# Checks for linker and compiler features on darwin\nm4_defun([_LT_DARWIN_LINKER_FEATURES],\n[\n  m4_require([_LT_REQUIRED_DARWIN_CHECKS])\n  _LT_TAGVAR(archive_cmds_need_lc, $1)=no\n  _LT_TAGVAR(hardcode_direct, $1)=no\n  _LT_TAGVAR(hardcode_automatic, $1)=yes\n  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported\n  if test \"$lt_cv_ld_force_load\" = \"yes\"; then\n    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience ${wl}-force_load,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"`'\n    m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],\n                  [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])\n  else\n    _LT_TAGVAR(whole_archive_flag_spec, $1)=''\n  fi\n  _LT_TAGVAR(link_all_deplibs, $1)=yes\n  _LT_TAGVAR(allow_undefined_flag, $1)=\"$_lt_dar_allow_undefined\"\n  case $cc_basename in\n     ifort*) _lt_dar_can_shared=yes ;;\n     *) _lt_dar_can_shared=$GCC ;;\n  esac\n  if test \"$_lt_dar_can_shared\" = \"yes\"; then\n    output_verbose_link_cmd=func_echo_all\n    _LT_TAGVAR(archive_cmds, $1)=\"\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\$libobjs \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring $_lt_dar_single_mod${_lt_dsymutil}\"\n    _LT_TAGVAR(module_cmds, $1)=\"\\$CC \\$allow_undefined_flag -o \\$lib -bundle \\$libobjs \\$deplibs \\$compiler_flags${_lt_dsymutil}\"\n    _LT_TAGVAR(archive_expsym_cmds, $1)=\"sed 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\$libobjs \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}\"\n    _LT_TAGVAR(module_expsym_cmds, $1)=\"sed -e 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC \\$allow_undefined_flag -o \\$lib -bundle \\$libobjs \\$deplibs \\$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}\"\n    m4_if([$1], [CXX],\n[   if test \"$lt_cv_apple_cc_single_mod\" != \"yes\"; then\n      _LT_TAGVAR(archive_cmds, $1)=\"\\$CC -r -keep_private_externs -nostdlib -o \\${lib}-master.o \\$libobjs~\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\${lib}-master.o \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring${_lt_dsymutil}\"\n      _LT_TAGVAR(archive_expsym_cmds, $1)=\"sed 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC -r -keep_private_externs -nostdlib -o \\${lib}-master.o \\$libobjs~\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\${lib}-master.o \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring${_lt_dar_export_syms}${_lt_dsymutil}\"\n    fi\n],[])\n  else\n  _LT_TAGVAR(ld_shlibs, $1)=no\n  fi\n])\n\n# _LT_SYS_MODULE_PATH_AIX([TAGNAME])\n# ----------------------------------\n# Links a minimal program and checks the executable\n# for the system default hardcoded library path. In most cases,\n# this is /usr/lib:/lib, but when the MPI compilers are used\n# the location of the communication and MPI libs are included too.\n# If we don't find anything, use the default library path according\n# to the aix ld manual.\n# Store the results from the different compilers for each TAGNAME.\n# Allow to override them for all tags through lt_cv_aix_libpath.\nm4_defun([_LT_SYS_MODULE_PATH_AIX],\n[m4_require([_LT_DECL_SED])dnl\nif test \"${lt_cv_aix_libpath+set}\" = set; then\n  aix_libpath=$lt_cv_aix_libpath\nelse\n  AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],\n  [AC_LINK_IFELSE([AC_LANG_PROGRAM],[\n  lt_aix_libpath_sed='[\n      /Import File Strings/,/^$/ {\n\t  /^0/ {\n\t      s/^0  *\\([^ ]*\\) *$/\\1/\n\t      p\n\t  }\n      }]'\n  _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n  # Check for a 64-bit object if we didn't find anything.\n  if test -z \"$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])\"; then\n    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n  fi],[])\n  if test -z \"$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])\"; then\n    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=\"/usr/lib:/lib\"\n  fi\n  ])\n  aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])\nfi\n])# _LT_SYS_MODULE_PATH_AIX\n\n\n# _LT_SHELL_INIT(ARG)\n# -------------------\nm4_define([_LT_SHELL_INIT],\n[m4_divert_text([M4SH-INIT], [$1\n])])# _LT_SHELL_INIT\n\n\n\n# _LT_PROG_ECHO_BACKSLASH\n# -----------------------\n# Find how we can fake an echo command that does not interpret backslash.\n# In particular, with Autoconf 2.60 or later we add some code to the start\n# of the generated configure script which will find a shell with a builtin\n# printf (which we can use as an echo command).\nm4_defun([_LT_PROG_ECHO_BACKSLASH],\n[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\nECHO=$ECHO$ECHO$ECHO$ECHO$ECHO\nECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO\n\nAC_MSG_CHECKING([how to print strings])\n# Test print first, because it will be a builtin if present.\nif test \"X`( print -r -- -n ) 2>/dev/null`\" = X-n && \\\n   test \"X`print -r -- $ECHO 2>/dev/null`\" = \"X$ECHO\"; then\n  ECHO='print -r --'\nelif test \"X`printf %s $ECHO 2>/dev/null`\" = \"X$ECHO\"; then\n  ECHO='printf %s\\n'\nelse\n  # Use this function as a fallback that always works.\n  func_fallback_echo ()\n  {\n    eval 'cat <<_LTECHO_EOF\n$[]1\n_LTECHO_EOF'\n  }\n  ECHO='func_fallback_echo'\nfi\n\n# func_echo_all arg...\n# Invoke $ECHO with all args, space-separated.\nfunc_echo_all ()\n{\n    $ECHO \"$*\" \n}\n\ncase \"$ECHO\" in\n  printf*) AC_MSG_RESULT([printf]) ;;\n  print*) AC_MSG_RESULT([print -r]) ;;\n  *) AC_MSG_RESULT([cat]) ;;\nesac\n\nm4_ifdef([_AS_DETECT_SUGGESTED],\n[_AS_DETECT_SUGGESTED([\n  test -n \"${ZSH_VERSION+set}${BASH_VERSION+set}\" || (\n    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\n    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO\n    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO\n    PATH=/empty FPATH=/empty; export PATH FPATH\n    test \"X`printf %s $ECHO`\" = \"X$ECHO\" \\\n      || test \"X`print -r -- $ECHO`\" = \"X$ECHO\" )])])\n\n_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])\n_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])\n])# _LT_PROG_ECHO_BACKSLASH\n\n\n# _LT_WITH_SYSROOT\n# ----------------\nAC_DEFUN([_LT_WITH_SYSROOT],\n[AC_MSG_CHECKING([for sysroot])\nAC_ARG_WITH([sysroot],\n[  --with-sysroot[=DIR] Search for dependent libraries within DIR\n                        (or the compiler's sysroot if not specified).],\n[], [with_sysroot=no])\n\ndnl lt_sysroot will always be passed unquoted.  We quote it here\ndnl in case the user passed a directory name.\nlt_sysroot=\ncase ${with_sysroot} in #(\n yes)\n   if test \"$GCC\" = yes; then\n     lt_sysroot=`$CC --print-sysroot 2>/dev/null`\n   fi\n   ;; #(\n /*)\n   lt_sysroot=`echo \"$with_sysroot\" | sed -e \"$sed_quote_subst\"`\n   ;; #(\n no|'')\n   ;; #(\n *)\n   AC_MSG_RESULT([${with_sysroot}])\n   AC_MSG_ERROR([The sysroot must be an absolute path.])\n   ;;\nesac\n\n AC_MSG_RESULT([${lt_sysroot:-no}])\n_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl\n[dependent libraries, and in which our libraries should be installed.])])\n\n# _LT_ENABLE_LOCK\n# ---------------\nm4_defun([_LT_ENABLE_LOCK],\n[AC_ARG_ENABLE([libtool-lock],\n  [AS_HELP_STRING([--disable-libtool-lock],\n    [avoid locking (might break parallel builds)])])\ntest \"x$enable_libtool_lock\" != xno && enable_libtool_lock=yes\n\n# Some flags need to be propagated to the compiler or linker for good\n# libtool support.\ncase $host in\nia64-*-hpux*)\n  # Find out which ABI we are using.\n  echo 'int i;' > conftest.$ac_ext\n  if AC_TRY_EVAL(ac_compile); then\n    case `/usr/bin/file conftest.$ac_objext` in\n      *ELF-32*)\n\tHPUX_IA64_MODE=\"32\"\n\t;;\n      *ELF-64*)\n\tHPUX_IA64_MODE=\"64\"\n\t;;\n    esac\n  fi\n  rm -rf conftest*\n  ;;\n*-*-irix6*)\n  # Find out which ABI we are using.\n  echo '[#]line '$LINENO' \"configure\"' > conftest.$ac_ext\n  if AC_TRY_EVAL(ac_compile); then\n    if test \"$lt_cv_prog_gnu_ld\" = yes; then\n      case `/usr/bin/file conftest.$ac_objext` in\n\t*32-bit*)\n\t  LD=\"${LD-ld} -melf32bsmip\"\n\t  ;;\n\t*N32*)\n\t  LD=\"${LD-ld} -melf32bmipn32\"\n\t  ;;\n\t*64-bit*)\n\t  LD=\"${LD-ld} -melf64bmip\"\n\t;;\n      esac\n    else\n      case `/usr/bin/file conftest.$ac_objext` in\n\t*32-bit*)\n\t  LD=\"${LD-ld} -32\"\n\t  ;;\n\t*N32*)\n\t  LD=\"${LD-ld} -n32\"\n\t  ;;\n\t*64-bit*)\n\t  LD=\"${LD-ld} -64\"\n\t  ;;\n      esac\n    fi\n  fi\n  rm -rf conftest*\n  ;;\n\nx86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \\\ns390*-*linux*|s390*-*tpf*|sparc*-*linux*)\n  # Find out which ABI we are using.\n  echo 'int i;' > conftest.$ac_ext\n  if AC_TRY_EVAL(ac_compile); then\n    case `/usr/bin/file conftest.o` in\n      *32-bit*)\n\tcase $host in\n\t  x86_64-*kfreebsd*-gnu)\n\t    LD=\"${LD-ld} -m elf_i386_fbsd\"\n\t    ;;\n\t  x86_64-*linux*)\n\t    LD=\"${LD-ld} -m elf_i386\"\n\t    ;;\n\t  powerpc64le-*linux*)\n\t    LD=\"${LD-ld} -m elf32lppclinux\"\n\t    ;;\n\t  powerpc64-*linux*)\n\t    LD=\"${LD-ld} -m elf32ppclinux\"\n\t    ;;\n\t  s390x-*linux*)\n\t    LD=\"${LD-ld} -m elf_s390\"\n\t    ;;\n\t  sparc64-*linux*)\n\t    LD=\"${LD-ld} -m elf32_sparc\"\n\t    ;;\n\tesac\n\t;;\n      *64-bit*)\n\tcase $host in\n\t  x86_64-*kfreebsd*-gnu)\n\t    LD=\"${LD-ld} -m elf_x86_64_fbsd\"\n\t    ;;\n\t  x86_64-*linux*)\n\t    LD=\"${LD-ld} -m elf_x86_64\"\n\t    ;;\n\t  powerpcle-*linux*)\n\t    LD=\"${LD-ld} -m elf64lppc\"\n\t    ;;\n\t  powerpc-*linux*)\n\t    LD=\"${LD-ld} -m elf64ppc\"\n\t    ;;\n\t  s390*-*linux*|s390*-*tpf*)\n\t    LD=\"${LD-ld} -m elf64_s390\"\n\t    ;;\n\t  sparc*-*linux*)\n\t    LD=\"${LD-ld} -m elf64_sparc\"\n\t    ;;\n\tesac\n\t;;\n    esac\n  fi\n  rm -rf conftest*\n  ;;\n\n*-*-sco3.2v5*)\n  # On SCO OpenServer 5, we need -belf to get full-featured binaries.\n  SAVE_CFLAGS=\"$CFLAGS\"\n  CFLAGS=\"$CFLAGS -belf\"\n  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,\n    [AC_LANG_PUSH(C)\n     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])\n     AC_LANG_POP])\n  if test x\"$lt_cv_cc_needs_belf\" != x\"yes\"; then\n    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf\n    CFLAGS=\"$SAVE_CFLAGS\"\n  fi\n  ;;\n*-*solaris*)\n  # Find out which ABI we are using.\n  echo 'int i;' > conftest.$ac_ext\n  if AC_TRY_EVAL(ac_compile); then\n    case `/usr/bin/file conftest.o` in\n    *64-bit*)\n      case $lt_cv_prog_gnu_ld in\n      yes*)\n        case $host in\n        i?86-*-solaris*)\n          LD=\"${LD-ld} -m elf_x86_64\"\n          ;;\n        sparc*-*-solaris*)\n          LD=\"${LD-ld} -m elf64_sparc\"\n          ;;\n        esac\n        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.\n        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then\n          LD=\"${LD-ld}_sol2\"\n        fi\n        ;;\n      *)\n\tif ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then\n\t  LD=\"${LD-ld} -64\"\n\tfi\n\t;;\n      esac\n      ;;\n    esac\n  fi\n  rm -rf conftest*\n  ;;\nesac\n\nneed_locks=\"$enable_libtool_lock\"\n])# _LT_ENABLE_LOCK\n\n\n# _LT_PROG_AR\n# -----------\nm4_defun([_LT_PROG_AR],\n[AC_CHECK_TOOLS(AR, [ar], false)\n: ${AR=ar}\n: ${AR_FLAGS=cru}\n_LT_DECL([], [AR], [1], [The archiver])\n_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])\n\nAC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],\n  [lt_cv_ar_at_file=no\n   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],\n     [echo conftest.$ac_objext > conftest.lst\n      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'\n      AC_TRY_EVAL([lt_ar_try])\n      if test \"$ac_status\" -eq 0; then\n\t# Ensure the archiver fails upon bogus file names.\n\trm -f conftest.$ac_objext libconftest.a\n\tAC_TRY_EVAL([lt_ar_try])\n\tif test \"$ac_status\" -ne 0; then\n          lt_cv_ar_at_file=@\n        fi\n      fi\n      rm -f conftest.* libconftest.a\n     ])\n  ])\n\nif test \"x$lt_cv_ar_at_file\" = xno; then\n  archiver_list_spec=\nelse\n  archiver_list_spec=$lt_cv_ar_at_file\nfi\n_LT_DECL([], [archiver_list_spec], [1],\n  [How to feed a file listing to the archiver])\n])# _LT_PROG_AR\n\n\n# _LT_CMD_OLD_ARCHIVE\n# -------------------\nm4_defun([_LT_CMD_OLD_ARCHIVE],\n[_LT_PROG_AR\n\nAC_CHECK_TOOL(STRIP, strip, :)\ntest -z \"$STRIP\" && STRIP=:\n_LT_DECL([], [STRIP], [1], [A symbol stripping program])\n\nAC_CHECK_TOOL(RANLIB, ranlib, :)\ntest -z \"$RANLIB\" && RANLIB=:\n_LT_DECL([], [RANLIB], [1],\n    [Commands used to install an old-style archive])\n\n# Determine commands to create old-style static archives.\nold_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'\nold_postinstall_cmds='chmod 644 $oldlib'\nold_postuninstall_cmds=\n\nif test -n \"$RANLIB\"; then\n  case $host_os in\n  openbsd*)\n    old_postinstall_cmds=\"$old_postinstall_cmds~\\$RANLIB -t \\$tool_oldlib\"\n    ;;\n  *)\n    old_postinstall_cmds=\"$old_postinstall_cmds~\\$RANLIB \\$tool_oldlib\"\n    ;;\n  esac\n  old_archive_cmds=\"$old_archive_cmds~\\$RANLIB \\$tool_oldlib\"\nfi\n\ncase $host_os in\n  darwin*)\n    lock_old_archive_extraction=yes ;;\n  *)\n    lock_old_archive_extraction=no ;;\nesac\n_LT_DECL([], [old_postinstall_cmds], [2])\n_LT_DECL([], [old_postuninstall_cmds], [2])\n_LT_TAGDECL([], [old_archive_cmds], [2],\n    [Commands used to build an old-style archive])\n_LT_DECL([], [lock_old_archive_extraction], [0],\n    [Whether to use a lock for old archive extraction])\n])# _LT_CMD_OLD_ARCHIVE\n\n\n# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,\n#\t\t[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])\n# ----------------------------------------------------------------\n# Check whether the given compiler option works\nAC_DEFUN([_LT_COMPILER_OPTION],\n[m4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_DECL_SED])dnl\nAC_CACHE_CHECK([$1], [$2],\n  [$2=no\n   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n   lt_compiler_flag=\"$3\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   # The option is referenced via a variable to avoid confusing sed.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [[^ ]]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:$LINENO: $lt_compile\\\"\" >&AS_MESSAGE_LOG_FD)\n   (eval \"$lt_compile\" 2>conftest.err)\n   ac_status=$?\n   cat conftest.err >&AS_MESSAGE_LOG_FD\n   echo \"$as_me:$LINENO: \\$? = $ac_status\" >&AS_MESSAGE_LOG_FD\n   if (exit $ac_status) && test -s \"$ac_outfile\"; then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings other than the usual output.\n     $ECHO \"$_lt_compiler_boilerplate\" | $SED '/^$/d' >conftest.exp\n     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then\n       $2=yes\n     fi\n   fi\n   $RM conftest*\n])\n\nif test x\"[$]$2\" = xyes; then\n    m4_if([$5], , :, [$5])\nelse\n    m4_if([$6], , :, [$6])\nfi\n])# _LT_COMPILER_OPTION\n\n# Old name:\nAU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])\n\n\n# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,\n#                  [ACTION-SUCCESS], [ACTION-FAILURE])\n# ----------------------------------------------------\n# Check whether the given linker option works\nAC_DEFUN([_LT_LINKER_OPTION],\n[m4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_DECL_SED])dnl\nAC_CACHE_CHECK([$1], [$2],\n  [$2=no\n   save_LDFLAGS=\"$LDFLAGS\"\n   LDFLAGS=\"$LDFLAGS $3\"\n   echo \"$lt_simple_link_test_code\" > conftest.$ac_ext\n   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then\n     # The linker can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     if test -s conftest.err; then\n       # Append any errors to the config.log.\n       cat conftest.err 1>&AS_MESSAGE_LOG_FD\n       $ECHO \"$_lt_linker_boilerplate\" | $SED '/^$/d' > conftest.exp\n       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n       if diff conftest.exp conftest.er2 >/dev/null; then\n         $2=yes\n       fi\n     else\n       $2=yes\n     fi\n   fi\n   $RM -r conftest*\n   LDFLAGS=\"$save_LDFLAGS\"\n])\n\nif test x\"[$]$2\" = xyes; then\n    m4_if([$4], , :, [$4])\nelse\n    m4_if([$5], , :, [$5])\nfi\n])# _LT_LINKER_OPTION\n\n# Old name:\nAU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])\n\n\n# LT_CMD_MAX_LEN\n#---------------\nAC_DEFUN([LT_CMD_MAX_LEN],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\n# find the maximum length of command line arguments\nAC_MSG_CHECKING([the maximum length of command line arguments])\nAC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl\n  i=0\n  teststring=\"ABCD\"\n\n  case $build_os in\n  msdosdjgpp*)\n    # On DJGPP, this test can blow up pretty badly due to problems in libc\n    # (any single argument exceeding 2000 bytes causes a buffer overrun\n    # during glob expansion).  Even if it were fixed, the result of this\n    # check would be larger than it should be.\n    lt_cv_sys_max_cmd_len=12288;    # 12K is about right\n    ;;\n\n  gnu*)\n    # Under GNU Hurd, this test is not required because there is\n    # no limit to the length of command line arguments.\n    # Libtool will interpret -1 as no limit whatsoever\n    lt_cv_sys_max_cmd_len=-1;\n    ;;\n\n  cygwin* | mingw* | cegcc*)\n    # On Win9x/ME, this test blows up -- it succeeds, but takes\n    # about 5 minutes as the teststring grows exponentially.\n    # Worse, since 9x/ME are not pre-emptively multitasking,\n    # you end up with a \"frozen\" computer, even though with patience\n    # the test eventually succeeds (with a max line length of 256k).\n    # Instead, let's just punt: use the minimum linelength reported by\n    # all of the supported platforms: 8192 (on NT/2K/XP).\n    lt_cv_sys_max_cmd_len=8192;\n    ;;\n\n  mint*)\n    # On MiNT this can take a long time and run out of memory.\n    lt_cv_sys_max_cmd_len=8192;\n    ;;\n\n  amigaos*)\n    # On AmigaOS with pdksh, this test takes hours, literally.\n    # So we just punt and use a minimum line length of 8192.\n    lt_cv_sys_max_cmd_len=8192;\n    ;;\n\n  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)\n    # This has been around since 386BSD, at least.  Likely further.\n    if test -x /sbin/sysctl; then\n      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`\n    elif test -x /usr/sbin/sysctl; then\n      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`\n    else\n      lt_cv_sys_max_cmd_len=65536\t# usable default for all BSDs\n    fi\n    # And add a safety zone\n    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\/ 4`\n    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\* 3`\n    ;;\n\n  interix*)\n    # We know the value 262144 and hardcode it with a safety zone (like BSD)\n    lt_cv_sys_max_cmd_len=196608\n    ;;\n\n  os2*)\n    # The test takes a long time on OS/2.\n    lt_cv_sys_max_cmd_len=8192\n    ;;\n\n  osf*)\n    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure\n    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not\n    # nice to cause kernel panics so lets avoid the loop below.\n    # First set a reasonable default.\n    lt_cv_sys_max_cmd_len=16384\n    #\n    if test -x /sbin/sysconfig; then\n      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in\n        *1*) lt_cv_sys_max_cmd_len=-1 ;;\n      esac\n    fi\n    ;;\n  sco3.2v5*)\n    lt_cv_sys_max_cmd_len=102400\n    ;;\n  sysv5* | sco5v6* | sysv4.2uw2*)\n    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`\n    if test -n \"$kargmax\"; then\n      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[\t ]]//'`\n    else\n      lt_cv_sys_max_cmd_len=32768\n    fi\n    ;;\n  *)\n    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`\n    if test -n \"$lt_cv_sys_max_cmd_len\"; then\n      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\/ 4`\n      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\* 3`\n    else\n      # Make teststring a little bigger before we do anything with it.\n      # a 1K string should be a reasonable start.\n      for i in 1 2 3 4 5 6 7 8 ; do\n        teststring=$teststring$teststring\n      done\n      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}\n      # If test is not a shell built-in, we'll probably end up computing a\n      # maximum length that is only half of the actual maximum length, but\n      # we can't tell.\n      while { test \"X\"`env echo \"$teststring$teststring\" 2>/dev/null` \\\n\t         = \"X$teststring$teststring\"; } >/dev/null 2>&1 &&\n\t      test $i != 17 # 1/2 MB should be enough\n      do\n        i=`expr $i + 1`\n        teststring=$teststring$teststring\n      done\n      # Only check the string length outside the loop.\n      lt_cv_sys_max_cmd_len=`expr \"X$teststring\" : \".*\" 2>&1`\n      teststring=\n      # Add a significant safety factor because C++ compilers can tack on\n      # massive amounts of additional arguments before passing them to the\n      # linker.  It appears as though 1/2 is a usable value.\n      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\/ 2`\n    fi\n    ;;\n  esac\n])\nif test -n $lt_cv_sys_max_cmd_len ; then\n  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)\nelse\n  AC_MSG_RESULT(none)\nfi\nmax_cmd_len=$lt_cv_sys_max_cmd_len\n_LT_DECL([], [max_cmd_len], [0],\n    [What is the maximum length of a command?])\n])# LT_CMD_MAX_LEN\n\n# Old name:\nAU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])\n\n\n# _LT_HEADER_DLFCN\n# ----------------\nm4_defun([_LT_HEADER_DLFCN],\n[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl\n])# _LT_HEADER_DLFCN\n\n\n# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,\n#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)\n# ----------------------------------------------------------------\nm4_defun([_LT_TRY_DLOPEN_SELF],\n[m4_require([_LT_HEADER_DLFCN])dnl\nif test \"$cross_compiling\" = yes; then :\n  [$4]\nelse\n  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2\n  lt_status=$lt_dlunknown\n  cat > conftest.$ac_ext <<_LT_EOF\n[#line $LINENO \"configure\"\n#include \"confdefs.h\"\n\n#if HAVE_DLFCN_H\n#include <dlfcn.h>\n#endif\n\n#include <stdio.h>\n\n#ifdef RTLD_GLOBAL\n#  define LT_DLGLOBAL\t\tRTLD_GLOBAL\n#else\n#  ifdef DL_GLOBAL\n#    define LT_DLGLOBAL\t\tDL_GLOBAL\n#  else\n#    define LT_DLGLOBAL\t\t0\n#  endif\n#endif\n\n/* We may have to define LT_DLLAZY_OR_NOW in the command line if we\n   find out it does not work in some platform. */\n#ifndef LT_DLLAZY_OR_NOW\n#  ifdef RTLD_LAZY\n#    define LT_DLLAZY_OR_NOW\t\tRTLD_LAZY\n#  else\n#    ifdef DL_LAZY\n#      define LT_DLLAZY_OR_NOW\t\tDL_LAZY\n#    else\n#      ifdef RTLD_NOW\n#        define LT_DLLAZY_OR_NOW\tRTLD_NOW\n#      else\n#        ifdef DL_NOW\n#          define LT_DLLAZY_OR_NOW\tDL_NOW\n#        else\n#          define LT_DLLAZY_OR_NOW\t0\n#        endif\n#      endif\n#    endif\n#  endif\n#endif\n\n/* When -fvisbility=hidden is used, assume the code has been annotated\n   correspondingly for the symbols needed.  */\n#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))\nint fnord () __attribute__((visibility(\"default\")));\n#endif\n\nint fnord () { return 42; }\nint main ()\n{\n  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);\n  int status = $lt_dlunknown;\n\n  if (self)\n    {\n      if (dlsym (self,\"fnord\"))       status = $lt_dlno_uscore;\n      else\n        {\n\t  if (dlsym( self,\"_fnord\"))  status = $lt_dlneed_uscore;\n          else puts (dlerror ());\n\t}\n      /* dlclose (self); */\n    }\n  else\n    puts (dlerror ());\n\n  return status;\n}]\n_LT_EOF\n  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then\n    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null\n    lt_status=$?\n    case x$lt_status in\n      x$lt_dlno_uscore) $1 ;;\n      x$lt_dlneed_uscore) $2 ;;\n      x$lt_dlunknown|x*) $3 ;;\n    esac\n  else :\n    # compilation failed\n    $3\n  fi\nfi\nrm -fr conftest*\n])# _LT_TRY_DLOPEN_SELF\n\n\n# LT_SYS_DLOPEN_SELF\n# ------------------\nAC_DEFUN([LT_SYS_DLOPEN_SELF],\n[m4_require([_LT_HEADER_DLFCN])dnl\nif test \"x$enable_dlopen\" != xyes; then\n  enable_dlopen=unknown\n  enable_dlopen_self=unknown\n  enable_dlopen_self_static=unknown\nelse\n  lt_cv_dlopen=no\n  lt_cv_dlopen_libs=\n\n  case $host_os in\n  beos*)\n    lt_cv_dlopen=\"load_add_on\"\n    lt_cv_dlopen_libs=\n    lt_cv_dlopen_self=yes\n    ;;\n\n  mingw* | pw32* | cegcc*)\n    lt_cv_dlopen=\"LoadLibrary\"\n    lt_cv_dlopen_libs=\n    ;;\n\n  cygwin*)\n    lt_cv_dlopen=\"dlopen\"\n    lt_cv_dlopen_libs=\n    ;;\n\n  darwin*)\n  # if libdl is installed we need to link against it\n    AC_CHECK_LIB([dl], [dlopen],\n\t\t[lt_cv_dlopen=\"dlopen\" lt_cv_dlopen_libs=\"-ldl\"],[\n    lt_cv_dlopen=\"dyld\"\n    lt_cv_dlopen_libs=\n    lt_cv_dlopen_self=yes\n    ])\n    ;;\n\n  *)\n    AC_CHECK_FUNC([shl_load],\n\t  [lt_cv_dlopen=\"shl_load\"],\n      [AC_CHECK_LIB([dld], [shl_load],\n\t    [lt_cv_dlopen=\"shl_load\" lt_cv_dlopen_libs=\"-ldld\"],\n\t[AC_CHECK_FUNC([dlopen],\n\t      [lt_cv_dlopen=\"dlopen\"],\n\t  [AC_CHECK_LIB([dl], [dlopen],\n\t\t[lt_cv_dlopen=\"dlopen\" lt_cv_dlopen_libs=\"-ldl\"],\n\t    [AC_CHECK_LIB([svld], [dlopen],\n\t\t  [lt_cv_dlopen=\"dlopen\" lt_cv_dlopen_libs=\"-lsvld\"],\n\t      [AC_CHECK_LIB([dld], [dld_link],\n\t\t    [lt_cv_dlopen=\"dld_link\" lt_cv_dlopen_libs=\"-ldld\"])\n\t      ])\n\t    ])\n\t  ])\n\t])\n      ])\n    ;;\n  esac\n\n  if test \"x$lt_cv_dlopen\" != xno; then\n    enable_dlopen=yes\n  else\n    enable_dlopen=no\n  fi\n\n  case $lt_cv_dlopen in\n  dlopen)\n    save_CPPFLAGS=\"$CPPFLAGS\"\n    test \"x$ac_cv_header_dlfcn_h\" = xyes && CPPFLAGS=\"$CPPFLAGS -DHAVE_DLFCN_H\"\n\n    save_LDFLAGS=\"$LDFLAGS\"\n    wl=$lt_prog_compiler_wl eval LDFLAGS=\\\"\\$LDFLAGS $export_dynamic_flag_spec\\\"\n\n    save_LIBS=\"$LIBS\"\n    LIBS=\"$lt_cv_dlopen_libs $LIBS\"\n\n    AC_CACHE_CHECK([whether a program can dlopen itself],\n\t  lt_cv_dlopen_self, [dnl\n\t  _LT_TRY_DLOPEN_SELF(\n\t    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,\n\t    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)\n    ])\n\n    if test \"x$lt_cv_dlopen_self\" = xyes; then\n      wl=$lt_prog_compiler_wl eval LDFLAGS=\\\"\\$LDFLAGS $lt_prog_compiler_static\\\"\n      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],\n\t  lt_cv_dlopen_self_static, [dnl\n\t  _LT_TRY_DLOPEN_SELF(\n\t    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,\n\t    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)\n      ])\n    fi\n\n    CPPFLAGS=\"$save_CPPFLAGS\"\n    LDFLAGS=\"$save_LDFLAGS\"\n    LIBS=\"$save_LIBS\"\n    ;;\n  esac\n\n  case $lt_cv_dlopen_self in\n  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;\n  *) enable_dlopen_self=unknown ;;\n  esac\n\n  case $lt_cv_dlopen_self_static in\n  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;\n  *) enable_dlopen_self_static=unknown ;;\n  esac\nfi\n_LT_DECL([dlopen_support], [enable_dlopen], [0],\n\t [Whether dlopen is supported])\n_LT_DECL([dlopen_self], [enable_dlopen_self], [0],\n\t [Whether dlopen of programs is supported])\n_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],\n\t [Whether dlopen of statically linked programs is supported])\n])# LT_SYS_DLOPEN_SELF\n\n# Old name:\nAU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])\n\n\n# _LT_COMPILER_C_O([TAGNAME])\n# ---------------------------\n# Check to see if options -c and -o are simultaneously supported by compiler.\n# This macro does not hard code the compiler like AC_PROG_CC_C_O.\nm4_defun([_LT_COMPILER_C_O],\n[m4_require([_LT_DECL_SED])dnl\nm4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_TAG_COMPILER])dnl\nAC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],\n  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],\n  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no\n   $RM -r conftest 2>/dev/null\n   mkdir conftest\n   cd conftest\n   mkdir out\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n   lt_compiler_flag=\"-o out/conftest2.$ac_objext\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [[^ ]]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:$LINENO: $lt_compile\\\"\" >&AS_MESSAGE_LOG_FD)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&AS_MESSAGE_LOG_FD\n   echo \"$as_me:$LINENO: \\$? = $ac_status\" >&AS_MESSAGE_LOG_FD\n   if (exit $ac_status) && test -s out/conftest2.$ac_objext\n   then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     $ECHO \"$_lt_compiler_boilerplate\" | $SED '/^$/d' > out/conftest.exp\n     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2\n     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then\n       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes\n     fi\n   fi\n   chmod u+w . 2>&AS_MESSAGE_LOG_FD\n   $RM conftest*\n   # SGI C++ compiler will create directory out/ii_files/ for\n   # template instantiation\n   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files\n   $RM out/* && rmdir out\n   cd ..\n   $RM -r conftest\n   $RM conftest*\n])\n_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],\n\t[Does compiler simultaneously support -c and -o options?])\n])# _LT_COMPILER_C_O\n\n\n# _LT_COMPILER_FILE_LOCKS([TAGNAME])\n# ----------------------------------\n# Check to see if we can do hard links to lock some files if needed\nm4_defun([_LT_COMPILER_FILE_LOCKS],\n[m4_require([_LT_ENABLE_LOCK])dnl\nm4_require([_LT_FILEUTILS_DEFAULTS])dnl\n_LT_COMPILER_C_O([$1])\n\nhard_links=\"nottested\"\nif test \"$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)\" = no && test \"$need_locks\" != no; then\n  # do not overwrite the value of need_locks provided by the user\n  AC_MSG_CHECKING([if we can lock with hard links])\n  hard_links=yes\n  $RM conftest*\n  ln conftest.a conftest.b 2>/dev/null && hard_links=no\n  touch conftest.a\n  ln conftest.a conftest.b 2>&5 || hard_links=no\n  ln conftest.a conftest.b 2>/dev/null && hard_links=no\n  AC_MSG_RESULT([$hard_links])\n  if test \"$hard_links\" = no; then\n    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])\n    need_locks=warn\n  fi\nelse\n  need_locks=no\nfi\n_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])\n])# _LT_COMPILER_FILE_LOCKS\n\n\n# _LT_CHECK_OBJDIR\n# ----------------\nm4_defun([_LT_CHECK_OBJDIR],\n[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],\n[rm -f .libs 2>/dev/null\nmkdir .libs 2>/dev/null\nif test -d .libs; then\n  lt_cv_objdir=.libs\nelse\n  # MS-DOS does not allow filenames that begin with a dot.\n  lt_cv_objdir=_libs\nfi\nrmdir .libs 2>/dev/null])\nobjdir=$lt_cv_objdir\n_LT_DECL([], [objdir], [0],\n         [The name of the directory that contains temporary libtool files])dnl\nm4_pattern_allow([LT_OBJDIR])dnl\nAC_DEFINE_UNQUOTED(LT_OBJDIR, \"$lt_cv_objdir/\",\n  [Define to the sub-directory in which libtool stores uninstalled libraries.])\n])# _LT_CHECK_OBJDIR\n\n\n# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])\n# --------------------------------------\n# Check hardcoding attributes.\nm4_defun([_LT_LINKER_HARDCODE_LIBPATH],\n[AC_MSG_CHECKING([how to hardcode library paths into programs])\n_LT_TAGVAR(hardcode_action, $1)=\nif test -n \"$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\" ||\n   test -n \"$_LT_TAGVAR(runpath_var, $1)\" ||\n   test \"X$_LT_TAGVAR(hardcode_automatic, $1)\" = \"Xyes\" ; then\n\n  # We can hardcode non-existent directories.\n  if test \"$_LT_TAGVAR(hardcode_direct, $1)\" != no &&\n     # If the only mechanism to avoid hardcoding is shlibpath_var, we\n     # have to relink, otherwise we might link with an installed library\n     # when we should be linking with a yet-to-be-installed one\n     ## test \"$_LT_TAGVAR(hardcode_shlibpath_var, $1)\" != no &&\n     test \"$_LT_TAGVAR(hardcode_minus_L, $1)\" != no; then\n    # Linking always hardcodes the temporary library directory.\n    _LT_TAGVAR(hardcode_action, $1)=relink\n  else\n    # We can link without hardcoding, and we can hardcode nonexisting dirs.\n    _LT_TAGVAR(hardcode_action, $1)=immediate\n  fi\nelse\n  # We cannot hardcode anything, or else we can only hardcode existing\n  # directories.\n  _LT_TAGVAR(hardcode_action, $1)=unsupported\nfi\nAC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])\n\nif test \"$_LT_TAGVAR(hardcode_action, $1)\" = relink ||\n   test \"$_LT_TAGVAR(inherit_rpath, $1)\" = yes; then\n  # Fast installation is not supported\n  enable_fast_install=no\nelif test \"$shlibpath_overrides_runpath\" = yes ||\n     test \"$enable_shared\" = no; then\n  # Fast installation is not necessary\n  enable_fast_install=needless\nfi\n_LT_TAGDECL([], [hardcode_action], [0],\n    [How to hardcode a shared library path into an executable])\n])# _LT_LINKER_HARDCODE_LIBPATH\n\n\n# _LT_CMD_STRIPLIB\n# ----------------\nm4_defun([_LT_CMD_STRIPLIB],\n[m4_require([_LT_DECL_EGREP])\nstriplib=\nold_striplib=\nAC_MSG_CHECKING([whether stripping libraries is possible])\nif test -n \"$STRIP\" && $STRIP -V 2>&1 | $GREP \"GNU strip\" >/dev/null; then\n  test -z \"$old_striplib\" && old_striplib=\"$STRIP --strip-debug\"\n  test -z \"$striplib\" && striplib=\"$STRIP --strip-unneeded\"\n  AC_MSG_RESULT([yes])\nelse\n# FIXME - insert some real tests, host_os isn't really good enough\n  case $host_os in\n  darwin*)\n    if test -n \"$STRIP\" ; then\n      striplib=\"$STRIP -x\"\n      old_striplib=\"$STRIP -S\"\n      AC_MSG_RESULT([yes])\n    else\n      AC_MSG_RESULT([no])\n    fi\n    ;;\n  *)\n    AC_MSG_RESULT([no])\n    ;;\n  esac\nfi\n_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])\n_LT_DECL([], [striplib], [1])\n])# _LT_CMD_STRIPLIB\n\n\n# _LT_SYS_DYNAMIC_LINKER([TAG])\n# -----------------------------\n# PORTME Fill in your ld.so characteristics\nm4_defun([_LT_SYS_DYNAMIC_LINKER],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\nm4_require([_LT_DECL_EGREP])dnl\nm4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_DECL_OBJDUMP])dnl\nm4_require([_LT_DECL_SED])dnl\nm4_require([_LT_CHECK_SHELL_FEATURES])dnl\nAC_MSG_CHECKING([dynamic linker characteristics])\nm4_if([$1],\n\t[], [\nif test \"$GCC\" = yes; then\n  case $host_os in\n    darwin*) lt_awk_arg=\"/^libraries:/,/LR/\" ;;\n    *) lt_awk_arg=\"/^libraries:/\" ;;\n  esac\n  case $host_os in\n    mingw* | cegcc*) lt_sed_strip_eq=\"s,=\\([[A-Za-z]]:\\),\\1,g\" ;;\n    *) lt_sed_strip_eq=\"s,=/,/,g\" ;;\n  esac\n  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e \"s/^libraries://\" -e $lt_sed_strip_eq`\n  case $lt_search_path_spec in\n  *\\;*)\n    # if the path contains \";\" then we assume it to be the separator\n    # otherwise default to the standard path separator (i.e. \":\") - it is\n    # assumed that no part of a normal pathname contains \";\" but that should\n    # okay in the real world where \";\" in dirpaths is itself problematic.\n    lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $SED 's/;/ /g'`\n    ;;\n  *)\n    lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $SED \"s/$PATH_SEPARATOR/ /g\"`\n    ;;\n  esac\n  # Ok, now we have the path, separated by spaces, we can step through it\n  # and add multilib dir if necessary.\n  lt_tmp_lt_search_path_spec=\n  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`\n  for lt_sys_path in $lt_search_path_spec; do\n    if test -d \"$lt_sys_path/$lt_multi_os_dir\"; then\n      lt_tmp_lt_search_path_spec=\"$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir\"\n    else\n      test -d \"$lt_sys_path\" && \\\n\tlt_tmp_lt_search_path_spec=\"$lt_tmp_lt_search_path_spec $lt_sys_path\"\n    fi\n  done\n  lt_search_path_spec=`$ECHO \"$lt_tmp_lt_search_path_spec\" | awk '\nBEGIN {RS=\" \"; FS=\"/|\\n\";} {\n  lt_foo=\"\";\n  lt_count=0;\n  for (lt_i = NF; lt_i > 0; lt_i--) {\n    if ($lt_i != \"\" && $lt_i != \".\") {\n      if ($lt_i == \"..\") {\n        lt_count++;\n      } else {\n        if (lt_count == 0) {\n          lt_foo=\"/\" $lt_i lt_foo;\n        } else {\n          lt_count--;\n        }\n      }\n    }\n  }\n  if (lt_foo != \"\") { lt_freq[[lt_foo]]++; }\n  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }\n}'`\n  # AWK program above erroneously prepends '/' to C:/dos/paths\n  # for these hosts.\n  case $host_os in\n    mingw* | cegcc*) lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" |\\\n      $SED 's,/\\([[A-Za-z]]:\\),\\1,g'` ;;\n  esac\n  sys_lib_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $lt_NL2SP`\nelse\n  sys_lib_search_path_spec=\"/lib /usr/lib /usr/local/lib\"\nfi])\nlibrary_names_spec=\nlibname_spec='lib$name'\nsoname_spec=\nshrext_cmds=\".so\"\npostinstall_cmds=\npostuninstall_cmds=\nfinish_cmds=\nfinish_eval=\nshlibpath_var=\nshlibpath_overrides_runpath=unknown\nversion_type=none\ndynamic_linker=\"$host_os ld.so\"\nsys_lib_dlsearch_path_spec=\"/lib /usr/lib\"\nneed_lib_prefix=unknown\nhardcode_into_libs=no\n\n# when you set need_version to no, make sure it does not cause -set_version\n# flags to be left without arguments\nneed_version=unknown\n\ncase $host_os in\naix3*)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'\n  shlibpath_var=LIBPATH\n\n  # AIX 3 has no versioning support, so we append a major version to the name.\n  soname_spec='${libname}${release}${shared_ext}$major'\n  ;;\n\naix[[4-9]]*)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  need_lib_prefix=no\n  need_version=no\n  hardcode_into_libs=yes\n  if test \"$host_cpu\" = ia64; then\n    # AIX 5 supports IA64\n    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'\n    shlibpath_var=LD_LIBRARY_PATH\n  else\n    # With GCC up to 2.95.x, collect2 would create an import file\n    # for dependence libraries.  The import file would start with\n    # the line `#! .'.  This would cause the generated library to\n    # depend on `.', always an invalid library.  This was fixed in\n    # development snapshots of GCC prior to 3.0.\n    case $host_os in\n      aix4 | aix4.[[01]] | aix4.[[01]].*)\n      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'\n\t   echo ' yes '\n\t   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then\n\t:\n      else\n\tcan_build_shared=no\n      fi\n      ;;\n    esac\n    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct\n    # soname into executable. Probably we can add versioning support to\n    # collect2, so additional links can be useful in future.\n    if test \"$aix_use_runtimelinking\" = yes; then\n      # If using run time linking (on AIX 4.2 or later) use lib<name>.so\n      # instead of lib<name>.a to let people know that these are not\n      # typical AIX shared libraries.\n      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    else\n      # We preserve .a as extension for shared libraries through AIX4.2\n      # and later when we are not doing run time linking.\n      library_names_spec='${libname}${release}.a $libname.a'\n      soname_spec='${libname}${release}${shared_ext}$major'\n    fi\n    shlibpath_var=LIBPATH\n  fi\n  ;;\n\namigaos*)\n  case $host_cpu in\n  powerpc)\n    # Since July 2007 AmigaOS4 officially supports .so libraries.\n    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    ;;\n  m68k)\n    library_names_spec='$libname.ixlibrary $libname.a'\n    # Create ${libname}_ixlibrary.a entries in /sys/libs.\n    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all \"$lib\" | $SED '\\''s%^.*/\\([[^/]]*\\)\\.ixlibrary$%\\1%'\\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show \"cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a\"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'\n    ;;\n  esac\n  ;;\n\nbeos*)\n  library_names_spec='${libname}${shared_ext}'\n  dynamic_linker=\"$host_os ld.so\"\n  shlibpath_var=LIBRARY_PATH\n  ;;\n\nbsdi[[45]]*)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  sys_lib_search_path_spec=\"/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib\"\n  sys_lib_dlsearch_path_spec=\"/shlib /usr/lib /usr/local/lib\"\n  # the default ld.so.conf also contains /usr/contrib/lib and\n  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow\n  # libtool to hard-code these into programs\n  ;;\n\ncygwin* | mingw* | pw32* | cegcc*)\n  version_type=windows\n  shrext_cmds=\".dll\"\n  need_version=no\n  need_lib_prefix=no\n\n  case $GCC,$cc_basename in\n  yes,*)\n    # gcc\n    library_names_spec='$libname.dll.a'\n    # DLL is installed to $(libdir)/../bin by postinstall_cmds\n    postinstall_cmds='base_file=`basename \\${file}`~\n      dlpath=`$SHELL 2>&1 -c '\\''. $dir/'\\''\\${base_file}'\\''i; echo \\$dlname'\\''`~\n      dldir=$destdir/`dirname \\$dlpath`~\n      test -d \\$dldir || mkdir -p \\$dldir~\n      $install_prog $dir/$dlname \\$dldir/$dlname~\n      chmod a+x \\$dldir/$dlname~\n      if test -n '\\''$stripme'\\'' && test -n '\\''$striplib'\\''; then\n        eval '\\''$striplib \\$dldir/$dlname'\\'' || exit \\$?;\n      fi'\n    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\\''. $file; echo \\$dlname'\\''`~\n      dlpath=$dir/\\$dldll~\n       $RM \\$dlpath'\n    shlibpath_overrides_runpath=yes\n\n    case $host_os in\n    cygwin*)\n      # Cygwin DLLs use 'cyg' prefix rather than 'lib'\n      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'\nm4_if([$1], [],[\n      sys_lib_search_path_spec=\"$sys_lib_search_path_spec /usr/lib/w32api\"])\n      ;;\n    mingw* | cegcc*)\n      # MinGW DLLs use traditional 'lib' prefix\n      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'\n      ;;\n    pw32*)\n      # pw32 DLLs use 'pw' prefix rather than 'lib'\n      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'\n      ;;\n    esac\n    dynamic_linker='Win32 ld.exe'\n    ;;\n\n  *,cl*)\n    # Native MSVC\n    libname_spec='$name'\n    soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'\n    library_names_spec='${libname}.dll.lib'\n\n    case $build_os in\n    mingw*)\n      sys_lib_search_path_spec=\n      lt_save_ifs=$IFS\n      IFS=';'\n      for lt_path in $LIB\n      do\n        IFS=$lt_save_ifs\n        # Let DOS variable expansion print the short 8.3 style file name.\n        lt_path=`cd \"$lt_path\" 2>/dev/null && cmd //C \"for %i in (\".\") do @echo %~si\"`\n        sys_lib_search_path_spec=\"$sys_lib_search_path_spec $lt_path\"\n      done\n      IFS=$lt_save_ifs\n      # Convert to MSYS style.\n      sys_lib_search_path_spec=`$ECHO \"$sys_lib_search_path_spec\" | sed -e 's|\\\\\\\\|/|g' -e 's| \\\\([[a-zA-Z]]\\\\):| /\\\\1|g' -e 's|^ ||'`\n      ;;\n    cygwin*)\n      # Convert to unix form, then to dos form, then back to unix form\n      # but this time dos style (no spaces!) so that the unix form looks\n      # like /cygdrive/c/PROGRA~1:/cygdr...\n      sys_lib_search_path_spec=`cygpath --path --unix \"$LIB\"`\n      sys_lib_search_path_spec=`cygpath --path --dos \"$sys_lib_search_path_spec\" 2>/dev/null`\n      sys_lib_search_path_spec=`cygpath --path --unix \"$sys_lib_search_path_spec\" | $SED -e \"s/$PATH_SEPARATOR/ /g\"`\n      ;;\n    *)\n      sys_lib_search_path_spec=\"$LIB\"\n      if $ECHO \"$sys_lib_search_path_spec\" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then\n        # It is most probably a Windows format PATH.\n        sys_lib_search_path_spec=`$ECHO \"$sys_lib_search_path_spec\" | $SED -e 's/;/ /g'`\n      else\n        sys_lib_search_path_spec=`$ECHO \"$sys_lib_search_path_spec\" | $SED -e \"s/$PATH_SEPARATOR/ /g\"`\n      fi\n      # FIXME: find the short name or the path components, as spaces are\n      # common. (e.g. \"Program Files\" -> \"PROGRA~1\")\n      ;;\n    esac\n\n    # DLL is installed to $(libdir)/../bin by postinstall_cmds\n    postinstall_cmds='base_file=`basename \\${file}`~\n      dlpath=`$SHELL 2>&1 -c '\\''. $dir/'\\''\\${base_file}'\\''i; echo \\$dlname'\\''`~\n      dldir=$destdir/`dirname \\$dlpath`~\n      test -d \\$dldir || mkdir -p \\$dldir~\n      $install_prog $dir/$dlname \\$dldir/$dlname'\n    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\\''. $file; echo \\$dlname'\\''`~\n      dlpath=$dir/\\$dldll~\n       $RM \\$dlpath'\n    shlibpath_overrides_runpath=yes\n    dynamic_linker='Win32 link.exe'\n    ;;\n\n  *)\n    # Assume MSVC wrapper\n    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'\n    dynamic_linker='Win32 ld.exe'\n    ;;\n  esac\n  # FIXME: first we should search . and the directory the executable is in\n  shlibpath_var=PATH\n  ;;\n\ndarwin* | rhapsody*)\n  dynamic_linker=\"$host_os dyld\"\n  version_type=darwin\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'\n  soname_spec='${libname}${release}${major}$shared_ext'\n  shlibpath_overrides_runpath=yes\n  shlibpath_var=DYLD_LIBRARY_PATH\n  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'\nm4_if([$1], [],[\n  sys_lib_search_path_spec=\"$sys_lib_search_path_spec /usr/local/lib\"])\n  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'\n  ;;\n\ndgux*)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  ;;\n\nfreebsd* | dragonfly*)\n  # DragonFly does not have aout.  When/if they implement a new\n  # versioning mechanism, adjust this.\n  if test -x /usr/bin/objformat; then\n    objformat=`/usr/bin/objformat`\n  else\n    case $host_os in\n    freebsd[[23]].*) objformat=aout ;;\n    *) objformat=elf ;;\n    esac\n  fi\n  version_type=freebsd-$objformat\n  case $version_type in\n    freebsd-elf*)\n      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'\n      need_version=no\n      need_lib_prefix=no\n      ;;\n    freebsd-*)\n      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'\n      need_version=yes\n      ;;\n  esac\n  shlibpath_var=LD_LIBRARY_PATH\n  case $host_os in\n  freebsd2.*)\n    shlibpath_overrides_runpath=yes\n    ;;\n  freebsd3.[[01]]* | freebsdelf3.[[01]]*)\n    shlibpath_overrides_runpath=yes\n    hardcode_into_libs=yes\n    ;;\n  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \\\n  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)\n    shlibpath_overrides_runpath=no\n    hardcode_into_libs=yes\n    ;;\n  *) # from 4.6 on, and DragonFly\n    shlibpath_overrides_runpath=yes\n    hardcode_into_libs=yes\n    ;;\n  esac\n  ;;\n\ngnu*)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  ;;\n\nhaiku*)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  need_lib_prefix=no\n  need_version=no\n  dynamic_linker=\"$host_os runtime_loader\"\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'\n  hardcode_into_libs=yes\n  ;;\n\nhpux9* | hpux10* | hpux11*)\n  # Give a soname corresponding to the major version so that dld.sl refuses to\n  # link against other versions.\n  version_type=sunos\n  need_lib_prefix=no\n  need_version=no\n  case $host_cpu in\n  ia64*)\n    shrext_cmds='.so'\n    hardcode_into_libs=yes\n    dynamic_linker=\"$host_os dld.so\"\n    shlibpath_var=LD_LIBRARY_PATH\n    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    if test \"X$HPUX_IA64_MODE\" = X32; then\n      sys_lib_search_path_spec=\"/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib\"\n    else\n      sys_lib_search_path_spec=\"/usr/lib/hpux64 /usr/local/lib/hpux64\"\n    fi\n    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec\n    ;;\n  hppa*64*)\n    shrext_cmds='.sl'\n    hardcode_into_libs=yes\n    dynamic_linker=\"$host_os dld.sl\"\n    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH\n    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    sys_lib_search_path_spec=\"/usr/lib/pa20_64 /usr/ccs/lib/pa20_64\"\n    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec\n    ;;\n  *)\n    shrext_cmds='.sl'\n    dynamic_linker=\"$host_os dld.sl\"\n    shlibpath_var=SHLIB_PATH\n    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    ;;\n  esac\n  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...\n  postinstall_cmds='chmod 555 $lib'\n  # or fails outright, so override atomically:\n  install_override_mode=555\n  ;;\n\ninterix[[3-9]]*)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  ;;\n\nirix5* | irix6* | nonstopux*)\n  case $host_os in\n    nonstopux*) version_type=nonstopux ;;\n    *)\n\tif test \"$lt_cv_prog_gnu_ld\" = yes; then\n\t\tversion_type=linux # correct to gnu/linux during the next big refactor\n\telse\n\t\tversion_type=irix\n\tfi ;;\n  esac\n  need_lib_prefix=no\n  need_version=no\n  soname_spec='${libname}${release}${shared_ext}$major'\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'\n  case $host_os in\n  irix5* | nonstopux*)\n    libsuff= shlibsuff=\n    ;;\n  *)\n    case $LD in # libtool.m4 will add one of these switches to LD\n    *-32|*\"-32 \"|*-melf32bsmip|*\"-melf32bsmip \")\n      libsuff= shlibsuff= libmagic=32-bit;;\n    *-n32|*\"-n32 \"|*-melf32bmipn32|*\"-melf32bmipn32 \")\n      libsuff=32 shlibsuff=N32 libmagic=N32;;\n    *-64|*\"-64 \"|*-melf64bmip|*\"-melf64bmip \")\n      libsuff=64 shlibsuff=64 libmagic=64-bit;;\n    *) libsuff= shlibsuff= libmagic=never-match;;\n    esac\n    ;;\n  esac\n  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH\n  shlibpath_overrides_runpath=no\n  sys_lib_search_path_spec=\"/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}\"\n  sys_lib_dlsearch_path_spec=\"/usr/lib${libsuff} /lib${libsuff}\"\n  hardcode_into_libs=yes\n  ;;\n\n# No shared lib support for Linux oldld, aout, or coff.\nlinux*oldld* | linux*aout* | linux*coff*)\n  dynamic_linker=no\n  ;;\n\n# This must be glibc/ELF.\nlinux* | k*bsd*-gnu | kopensolaris*-gnu)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -n $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n\n  # Some binutils ld are patched to set DT_RUNPATH\n  AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],\n    [lt_cv_shlibpath_overrides_runpath=no\n    save_LDFLAGS=$LDFLAGS\n    save_libdir=$libdir\n    eval \"libdir=/foo; wl=\\\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\\\"; \\\n\t LDFLAGS=\\\"\\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\\\"\"\n    AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],\n      [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep \"RUNPATH.*$libdir\" >/dev/null],\n\t [lt_cv_shlibpath_overrides_runpath=yes])])\n    LDFLAGS=$save_LDFLAGS\n    libdir=$save_libdir\n    ])\n  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath\n\n  # This implies no fast_install, which is unacceptable.\n  # Some rework will be needed to allow for fast_install\n  # before this can be enabled.\n  hardcode_into_libs=yes\n\n  # Add ABI-specific directories to the system library path.\n  sys_lib_dlsearch_path_spec=\"/lib64 /usr/lib64 /lib /usr/lib\"\n\n  # Append ld.so.conf contents to the search path\n  if test -f /etc/ld.so.conf; then\n    lt_ld_extra=`awk '/^include / { system(sprintf(\"cd /etc; cat %s 2>/dev/null\", \\[$]2)); skip = 1; } { if (!skip) print \\[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[\t ]*hwcap[\t ]/d;s/[:,\t]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/\"//g;/^$/d' | tr '\\n' ' '`\n    sys_lib_dlsearch_path_spec=\"$sys_lib_dlsearch_path_spec $lt_ld_extra\"\n\n  fi\n\n  # We used to test for /lib/ld.so.1 and disable shared libraries on\n  # powerpc, because MkLinux only supported shared libraries with the\n  # GNU dynamic linker.  Since this was broken with cross compilers,\n  # most powerpc-linux boxes support dynamic linking these days and\n  # people can always --disable-shared, the test was removed, and we\n  # assume the GNU/Linux dynamic linker is in use.\n  dynamic_linker='GNU/Linux ld.so'\n  ;;\n\nnetbsd*)\n  version_type=sunos\n  need_lib_prefix=no\n  need_version=no\n  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n    finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -m $libdir'\n    dynamic_linker='NetBSD (a.out) ld.so'\n  else\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    dynamic_linker='NetBSD ld.elf_so'\n  fi\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  ;;\n\nnewsos6)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  ;;\n\n*nto* | *qnx*)\n  version_type=qnx\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  dynamic_linker='ldqnx.so'\n  ;;\n\nopenbsd*)\n  version_type=sunos\n  sys_lib_dlsearch_path_spec=\"/usr/lib\"\n  need_lib_prefix=no\n  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.\n  case $host_os in\n    openbsd3.3 | openbsd3.3.*)\tneed_version=yes ;;\n    *)\t\t\t\tneed_version=no  ;;\n  esac\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -m $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  if test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n    case $host_os in\n      openbsd2.[[89]] | openbsd2.[[89]].*)\n\tshlibpath_overrides_runpath=no\n\t;;\n      *)\n\tshlibpath_overrides_runpath=yes\n\t;;\n      esac\n  else\n    shlibpath_overrides_runpath=yes\n  fi\n  ;;\n\nos2*)\n  libname_spec='$name'\n  shrext_cmds=\".dll\"\n  need_lib_prefix=no\n  library_names_spec='$libname${shared_ext} $libname.a'\n  dynamic_linker='OS/2 ld.exe'\n  shlibpath_var=LIBPATH\n  ;;\n\nosf3* | osf4* | osf5*)\n  version_type=osf\n  need_lib_prefix=no\n  need_version=no\n  soname_spec='${libname}${release}${shared_ext}$major'\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  sys_lib_search_path_spec=\"/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib\"\n  sys_lib_dlsearch_path_spec=\"$sys_lib_search_path_spec\"\n  ;;\n\nrdos*)\n  dynamic_linker=no\n  ;;\n\nsolaris*)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  # ldd complains unless libraries are executable\n  postinstall_cmds='chmod +x $lib'\n  ;;\n\nsunos4*)\n  version_type=sunos\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n  finish_cmds='PATH=\"\\$PATH:/usr/etc\" ldconfig $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  if test \"$with_gnu_ld\" = yes; then\n    need_lib_prefix=no\n  fi\n  need_version=yes\n  ;;\n\nsysv4 | sysv4.3*)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  case $host_vendor in\n    sni)\n      shlibpath_overrides_runpath=no\n      need_lib_prefix=no\n      runpath_var=LD_RUN_PATH\n      ;;\n    siemens)\n      need_lib_prefix=no\n      ;;\n    motorola)\n      need_lib_prefix=no\n      need_version=no\n      shlibpath_overrides_runpath=no\n      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'\n      ;;\n  esac\n  ;;\n\nsysv4*MP*)\n  if test -d /usr/nec ;then\n    version_type=linux # correct to gnu/linux during the next big refactor\n    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'\n    soname_spec='$libname${shared_ext}.$major'\n    shlibpath_var=LD_LIBRARY_PATH\n  fi\n  ;;\n\nsysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)\n  version_type=freebsd-elf\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  if test \"$with_gnu_ld\" = yes; then\n    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'\n  else\n    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'\n    case $host_os in\n      sco3.2v5*)\n        sys_lib_search_path_spec=\"$sys_lib_search_path_spec /lib\"\n\t;;\n    esac\n  fi\n  sys_lib_dlsearch_path_spec='/usr/lib'\n  ;;\n\ntpf*)\n  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.\n  version_type=linux # correct to gnu/linux during the next big refactor\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  ;;\n\nuts4*)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  ;;\n\n*)\n  dynamic_linker=no\n  ;;\nesac\nAC_MSG_RESULT([$dynamic_linker])\ntest \"$dynamic_linker\" = no && can_build_shared=no\n\nvariables_saved_for_relink=\"PATH $shlibpath_var $runpath_var\"\nif test \"$GCC\" = yes; then\n  variables_saved_for_relink=\"$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH\"\nfi\n\nif test \"${lt_cv_sys_lib_search_path_spec+set}\" = set; then\n  sys_lib_search_path_spec=\"$lt_cv_sys_lib_search_path_spec\"\nfi\nif test \"${lt_cv_sys_lib_dlsearch_path_spec+set}\" = set; then\n  sys_lib_dlsearch_path_spec=\"$lt_cv_sys_lib_dlsearch_path_spec\"\nfi\n\n_LT_DECL([], [variables_saved_for_relink], [1],\n    [Variables whose values should be saved in libtool wrapper scripts and\n    restored at link time])\n_LT_DECL([], [need_lib_prefix], [0],\n    [Do we need the \"lib\" prefix for modules?])\n_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])\n_LT_DECL([], [version_type], [0], [Library versioning type])\n_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])\n_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])\n_LT_DECL([], [shlibpath_overrides_runpath], [0],\n    [Is shlibpath searched before the hard-coded library search path?])\n_LT_DECL([], [libname_spec], [1], [Format of library name prefix])\n_LT_DECL([], [library_names_spec], [1],\n    [[List of archive names.  First name is the real one, the rest are links.\n    The last name is the one that the linker finds with -lNAME]])\n_LT_DECL([], [soname_spec], [1],\n    [[The coded name of the library, if different from the real name]])\n_LT_DECL([], [install_override_mode], [1],\n    [Permission mode override for installation of shared libraries])\n_LT_DECL([], [postinstall_cmds], [2],\n    [Command to use after installation of a shared archive])\n_LT_DECL([], [postuninstall_cmds], [2],\n    [Command to use after uninstallation of a shared archive])\n_LT_DECL([], [finish_cmds], [2],\n    [Commands used to finish a libtool library installation in a directory])\n_LT_DECL([], [finish_eval], [1],\n    [[As \"finish_cmds\", except a single script fragment to be evaled but\n    not shown]])\n_LT_DECL([], [hardcode_into_libs], [0],\n    [Whether we should hardcode library paths into libraries])\n_LT_DECL([], [sys_lib_search_path_spec], [2],\n    [Compile-time system search path for libraries])\n_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],\n    [Run-time system search path for libraries])\n])# _LT_SYS_DYNAMIC_LINKER\n\n\n# _LT_PATH_TOOL_PREFIX(TOOL)\n# --------------------------\n# find a file program which can recognize shared library\nAC_DEFUN([_LT_PATH_TOOL_PREFIX],\n[m4_require([_LT_DECL_EGREP])dnl\nAC_MSG_CHECKING([for $1])\nAC_CACHE_VAL(lt_cv_path_MAGIC_CMD,\n[case $MAGIC_CMD in\n[[\\\\/*] |  ?:[\\\\/]*])\n  lt_cv_path_MAGIC_CMD=\"$MAGIC_CMD\" # Let the user override the test with a path.\n  ;;\n*)\n  lt_save_MAGIC_CMD=\"$MAGIC_CMD\"\n  lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\ndnl $ac_dummy forces splitting on constant user-supplied paths.\ndnl POSIX.2 word splitting is done only on the output of word expansions,\ndnl not every word.  This closes a longstanding sh security hole.\n  ac_dummy=\"m4_if([$2], , $PATH, [$2])\"\n  for ac_dir in $ac_dummy; do\n    IFS=\"$lt_save_ifs\"\n    test -z \"$ac_dir\" && ac_dir=.\n    if test -f $ac_dir/$1; then\n      lt_cv_path_MAGIC_CMD=\"$ac_dir/$1\"\n      if test -n \"$file_magic_test_file\"; then\n\tcase $deplibs_check_method in\n\t\"file_magic \"*)\n\t  file_magic_regex=`expr \"$deplibs_check_method\" : \"file_magic \\(.*\\)\"`\n\t  MAGIC_CMD=\"$lt_cv_path_MAGIC_CMD\"\n\t  if eval $file_magic_cmd \\$file_magic_test_file 2> /dev/null |\n\t    $EGREP \"$file_magic_regex\" > /dev/null; then\n\t    :\n\t  else\n\t    cat <<_LT_EOF 1>&2\n\n*** Warning: the command libtool uses to detect shared libraries,\n*** $file_magic_cmd, produces output that libtool cannot recognize.\n*** The result is that libtool may fail to recognize shared libraries\n*** as such.  This will affect the creation of libtool libraries that\n*** depend on shared libraries, but programs linked with such libtool\n*** libraries will work regardless of this problem.  Nevertheless, you\n*** may want to report the problem to your system manager and/or to\n*** bug-libtool@gnu.org\n\n_LT_EOF\n\t  fi ;;\n\tesac\n      fi\n      break\n    fi\n  done\n  IFS=\"$lt_save_ifs\"\n  MAGIC_CMD=\"$lt_save_MAGIC_CMD\"\n  ;;\nesac])\nMAGIC_CMD=\"$lt_cv_path_MAGIC_CMD\"\nif test -n \"$MAGIC_CMD\"; then\n  AC_MSG_RESULT($MAGIC_CMD)\nelse\n  AC_MSG_RESULT(no)\nfi\n_LT_DECL([], [MAGIC_CMD], [0],\n\t [Used to examine libraries when file_magic_cmd begins with \"file\"])dnl\n])# _LT_PATH_TOOL_PREFIX\n\n# Old name:\nAU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])\n\n\n# _LT_PATH_MAGIC\n# --------------\n# find a file program which can recognize a shared library\nm4_defun([_LT_PATH_MAGIC],\n[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)\nif test -z \"$lt_cv_path_MAGIC_CMD\"; then\n  if test -n \"$ac_tool_prefix\"; then\n    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)\n  else\n    MAGIC_CMD=:\n  fi\nfi\n])# _LT_PATH_MAGIC\n\n\n# LT_PATH_LD\n# ----------\n# find the pathname to the GNU or non-GNU linker\nAC_DEFUN([LT_PATH_LD],\n[AC_REQUIRE([AC_PROG_CC])dnl\nAC_REQUIRE([AC_CANONICAL_HOST])dnl\nAC_REQUIRE([AC_CANONICAL_BUILD])dnl\nm4_require([_LT_DECL_SED])dnl\nm4_require([_LT_DECL_EGREP])dnl\nm4_require([_LT_PROG_ECHO_BACKSLASH])dnl\n\nAC_ARG_WITH([gnu-ld],\n    [AS_HELP_STRING([--with-gnu-ld],\n\t[assume the C compiler uses GNU ld @<:@default=no@:>@])],\n    [test \"$withval\" = no || with_gnu_ld=yes],\n    [with_gnu_ld=no])dnl\n\nac_prog=ld\nif test \"$GCC\" = yes; then\n  # Check if gcc -print-prog-name=ld gives a path.\n  AC_MSG_CHECKING([for ld used by $CC])\n  case $host in\n  *-*-mingw*)\n    # gcc leaves a trailing carriage return which upsets mingw\n    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\\015'` ;;\n  *)\n    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;\n  esac\n  case $ac_prog in\n    # Accept absolute paths.\n    [[\\\\/]]* | ?:[[\\\\/]]*)\n      re_direlt='/[[^/]][[^/]]*/\\.\\./'\n      # Canonicalize the pathname of ld\n      ac_prog=`$ECHO \"$ac_prog\"| $SED 's%\\\\\\\\%/%g'`\n      while $ECHO \"$ac_prog\" | $GREP \"$re_direlt\" > /dev/null 2>&1; do\n\tac_prog=`$ECHO $ac_prog| $SED \"s%$re_direlt%/%\"`\n      done\n      test -z \"$LD\" && LD=\"$ac_prog\"\n      ;;\n  \"\")\n    # If it fails, then pretend we aren't using GCC.\n    ac_prog=ld\n    ;;\n  *)\n    # If it is relative, then search for the first ld in PATH.\n    with_gnu_ld=unknown\n    ;;\n  esac\nelif test \"$with_gnu_ld\" = yes; then\n  AC_MSG_CHECKING([for GNU ld])\nelse\n  AC_MSG_CHECKING([for non-GNU ld])\nfi\nAC_CACHE_VAL(lt_cv_path_LD,\n[if test -z \"$LD\"; then\n  lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n  for ac_dir in $PATH; do\n    IFS=\"$lt_save_ifs\"\n    test -z \"$ac_dir\" && ac_dir=.\n    if test -f \"$ac_dir/$ac_prog\" || test -f \"$ac_dir/$ac_prog$ac_exeext\"; then\n      lt_cv_path_LD=\"$ac_dir/$ac_prog\"\n      # Check to see if the program is GNU ld.  I'd rather use --version,\n      # but apparently some variants of GNU ld only accept -v.\n      # Break only if it was the GNU/non-GNU ld that we prefer.\n      case `\"$lt_cv_path_LD\" -v 2>&1 </dev/null` in\n      *GNU* | *'with BFD'*)\n\ttest \"$with_gnu_ld\" != no && break\n\t;;\n      *)\n\ttest \"$with_gnu_ld\" != yes && break\n\t;;\n      esac\n    fi\n  done\n  IFS=\"$lt_save_ifs\"\nelse\n  lt_cv_path_LD=\"$LD\" # Let the user override the test with a path.\nfi])\nLD=\"$lt_cv_path_LD\"\nif test -n \"$LD\"; then\n  AC_MSG_RESULT($LD)\nelse\n  AC_MSG_RESULT(no)\nfi\ntest -z \"$LD\" && AC_MSG_ERROR([no acceptable ld found in \\$PATH])\n_LT_PATH_LD_GNU\nAC_SUBST([LD])\n\n_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])\n])# LT_PATH_LD\n\n# Old names:\nAU_ALIAS([AM_PROG_LD], [LT_PATH_LD])\nAU_ALIAS([AC_PROG_LD], [LT_PATH_LD])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AM_PROG_LD], [])\ndnl AC_DEFUN([AC_PROG_LD], [])\n\n\n# _LT_PATH_LD_GNU\n#- --------------\nm4_defun([_LT_PATH_LD_GNU],\n[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,\n[# I'd rather use --version here, but apparently some GNU lds only accept -v.\ncase `$LD -v 2>&1 </dev/null` in\n*GNU* | *'with BFD'*)\n  lt_cv_prog_gnu_ld=yes\n  ;;\n*)\n  lt_cv_prog_gnu_ld=no\n  ;;\nesac])\nwith_gnu_ld=$lt_cv_prog_gnu_ld\n])# _LT_PATH_LD_GNU\n\n\n# _LT_CMD_RELOAD\n# --------------\n# find reload flag for linker\n#   -- PORTME Some linkers may need a different reload flag.\nm4_defun([_LT_CMD_RELOAD],\n[AC_CACHE_CHECK([for $LD option to reload object files],\n  lt_cv_ld_reload_flag,\n  [lt_cv_ld_reload_flag='-r'])\nreload_flag=$lt_cv_ld_reload_flag\ncase $reload_flag in\n\"\" | \" \"*) ;;\n*) reload_flag=\" $reload_flag\" ;;\nesac\nreload_cmds='$LD$reload_flag -o $output$reload_objs'\ncase $host_os in\n  cygwin* | mingw* | pw32* | cegcc*)\n    if test \"$GCC\" != yes; then\n      reload_cmds=false\n    fi\n    ;;\n  darwin*)\n    if test \"$GCC\" = yes; then\n      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'\n    else\n      reload_cmds='$LD$reload_flag -o $output$reload_objs'\n    fi\n    ;;\nesac\n_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl\n_LT_TAGDECL([], [reload_cmds], [2])dnl\n])# _LT_CMD_RELOAD\n\n\n# _LT_CHECK_MAGIC_METHOD\n# ----------------------\n# how to check for library dependencies\n#  -- PORTME fill in with the dynamic library characteristics\nm4_defun([_LT_CHECK_MAGIC_METHOD],\n[m4_require([_LT_DECL_EGREP])\nm4_require([_LT_DECL_OBJDUMP])\nAC_CACHE_CHECK([how to recognize dependent libraries],\nlt_cv_deplibs_check_method,\n[lt_cv_file_magic_cmd='$MAGIC_CMD'\nlt_cv_file_magic_test_file=\nlt_cv_deplibs_check_method='unknown'\n# Need to set the preceding variable on all platforms that support\n# interlibrary dependencies.\n# 'none' -- dependencies not supported.\n# `unknown' -- same as none, but documents that we really don't know.\n# 'pass_all' -- all dependencies passed with no checks.\n# 'test_compile' -- check by making test program.\n# 'file_magic [[regex]]' -- check by looking for files in library path\n# which responds to the $file_magic_cmd with a given extended regex.\n# If you have `file' or equivalent on your system and you're not sure\n# whether `pass_all' will *always* work, you probably want this one.\n\ncase $host_os in\naix[[4-9]]*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nbeos*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nbsdi[[45]]*)\n  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'\n  lt_cv_file_magic_cmd='/usr/bin/file -L'\n  lt_cv_file_magic_test_file=/shlib/libc.so\n  ;;\n\ncygwin*)\n  # func_win32_libid is a shell function defined in ltmain.sh\n  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'\n  lt_cv_file_magic_cmd='func_win32_libid'\n  ;;\n\nmingw* | pw32*)\n  # Base MSYS/MinGW do not provide the 'file' command needed by\n  # func_win32_libid shell function, so use a weaker test based on 'objdump',\n  # unless we find 'file', for example because we are cross-compiling.\n  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.\n  if ( test \"$lt_cv_nm_interface\" = \"BSD nm\" && file / ) >/dev/null 2>&1; then\n    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'\n    lt_cv_file_magic_cmd='func_win32_libid'\n  else\n    # Keep this pattern in sync with the one in func_win32_libid.\n    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'\n    lt_cv_file_magic_cmd='$OBJDUMP -f'\n  fi\n  ;;\n\ncegcc*)\n  # use the weaker test based on 'objdump'. See mingw*.\n  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'\n  lt_cv_file_magic_cmd='$OBJDUMP -f'\n  ;;\n\ndarwin* | rhapsody*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nfreebsd* | dragonfly*)\n  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then\n    case $host_cpu in\n    i*86 )\n      # Not sure whether the presence of OpenBSD here was a mistake.\n      # Let's accept both of them until this is cleared up.\n      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'\n      lt_cv_file_magic_cmd=/usr/bin/file\n      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`\n      ;;\n    esac\n  else\n    lt_cv_deplibs_check_method=pass_all\n  fi\n  ;;\n\ngnu*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nhaiku*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nhpux10.20* | hpux11*)\n  lt_cv_file_magic_cmd=/usr/bin/file\n  case $host_cpu in\n  ia64*)\n    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'\n    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so\n    ;;\n  hppa*64*)\n    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\\.[0-9]']\n    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl\n    ;;\n  *)\n    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\\.[[0-9]]) shared library'\n    lt_cv_file_magic_test_file=/usr/lib/libc.sl\n    ;;\n  esac\n  ;;\n\ninterix[[3-9]]*)\n  # PIC code is broken on Interix 3.x, that's why |\\.a not |_pic\\.a here\n  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\\.so|\\.a)$'\n  ;;\n\nirix5* | irix6* | nonstopux*)\n  case $LD in\n  *-32|*\"-32 \") libmagic=32-bit;;\n  *-n32|*\"-n32 \") libmagic=N32;;\n  *-64|*\"-64 \") libmagic=64-bit;;\n  *) libmagic=never-match;;\n  esac\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\n# This must be glibc/ELF.\nlinux* | k*bsd*-gnu | kopensolaris*-gnu)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nnetbsd*)\n  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then\n    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\\.so\\.[[0-9]]+\\.[[0-9]]+|_pic\\.a)$'\n  else\n    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\\.so|_pic\\.a)$'\n  fi\n  ;;\n\nnewos6*)\n  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'\n  lt_cv_file_magic_cmd=/usr/bin/file\n  lt_cv_file_magic_test_file=/usr/lib/libnls.so\n  ;;\n\n*nto* | *qnx*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nopenbsd*)\n  if test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\\.so\\.[[0-9]]+\\.[[0-9]]+|\\.so|_pic\\.a)$'\n  else\n    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\\.so\\.[[0-9]]+\\.[[0-9]]+|_pic\\.a)$'\n  fi\n  ;;\n\nosf3* | osf4* | osf5*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nrdos*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nsolaris*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nsysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nsysv4 | sysv4.3*)\n  case $host_vendor in\n  motorola)\n    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'\n    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`\n    ;;\n  ncr)\n    lt_cv_deplibs_check_method=pass_all\n    ;;\n  sequent)\n    lt_cv_file_magic_cmd='/bin/file'\n    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'\n    ;;\n  sni)\n    lt_cv_file_magic_cmd='/bin/file'\n    lt_cv_deplibs_check_method=\"file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib\"\n    lt_cv_file_magic_test_file=/lib/libc.so\n    ;;\n  siemens)\n    lt_cv_deplibs_check_method=pass_all\n    ;;\n  pc)\n    lt_cv_deplibs_check_method=pass_all\n    ;;\n  esac\n  ;;\n\ntpf*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\nesac\n])\n\nfile_magic_glob=\nwant_nocaseglob=no\nif test \"$build\" = \"$host\"; then\n  case $host_os in\n  mingw* | pw32*)\n    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then\n      want_nocaseglob=yes\n    else\n      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e \"s/\\(..\\)/s\\/[[\\1]]\\/[[\\1]]\\/g;/g\"`\n    fi\n    ;;\n  esac\nfi\n\nfile_magic_cmd=$lt_cv_file_magic_cmd\ndeplibs_check_method=$lt_cv_deplibs_check_method\ntest -z \"$deplibs_check_method\" && deplibs_check_method=unknown\n\n_LT_DECL([], [deplibs_check_method], [1],\n    [Method to check whether dependent libraries are shared objects])\n_LT_DECL([], [file_magic_cmd], [1],\n    [Command to use when deplibs_check_method = \"file_magic\"])\n_LT_DECL([], [file_magic_glob], [1],\n    [How to find potential files when deplibs_check_method = \"file_magic\"])\n_LT_DECL([], [want_nocaseglob], [1],\n    [Find potential files using nocaseglob when deplibs_check_method = \"file_magic\"])\n])# _LT_CHECK_MAGIC_METHOD\n\n\n# LT_PATH_NM\n# ----------\n# find the pathname to a BSD- or MS-compatible name lister\nAC_DEFUN([LT_PATH_NM],\n[AC_REQUIRE([AC_PROG_CC])dnl\nAC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,\n[if test -n \"$NM\"; then\n  # Let the user override the test.\n  lt_cv_path_NM=\"$NM\"\nelse\n  lt_nm_to_check=\"${ac_tool_prefix}nm\"\n  if test -n \"$ac_tool_prefix\" && test \"$build\" = \"$host\"; then\n    lt_nm_to_check=\"$lt_nm_to_check nm\"\n  fi\n  for lt_tmp_nm in $lt_nm_to_check; do\n    lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do\n      IFS=\"$lt_save_ifs\"\n      test -z \"$ac_dir\" && ac_dir=.\n      tmp_nm=\"$ac_dir/$lt_tmp_nm\"\n      if test -f \"$tmp_nm\" || test -f \"$tmp_nm$ac_exeext\" ; then\n\t# Check to see if the nm accepts a BSD-compat flag.\n\t# Adding the `sed 1q' prevents false positives on HP-UX, which says:\n\t#   nm: unknown option \"B\" ignored\n\t# Tru64's nm complains that /dev/null is an invalid object file\n\tcase `\"$tmp_nm\" -B /dev/null 2>&1 | sed '1q'` in\n\t*/dev/null* | *'Invalid file or object type'*)\n\t  lt_cv_path_NM=\"$tmp_nm -B\"\n\t  break\n\t  ;;\n\t*)\n\t  case `\"$tmp_nm\" -p /dev/null 2>&1 | sed '1q'` in\n\t  */dev/null*)\n\t    lt_cv_path_NM=\"$tmp_nm -p\"\n\t    break\n\t    ;;\n\t  *)\n\t    lt_cv_path_NM=${lt_cv_path_NM=\"$tmp_nm\"} # keep the first match, but\n\t    continue # so that we can try to find one that supports BSD flags\n\t    ;;\n\t  esac\n\t  ;;\n\tesac\n      fi\n    done\n    IFS=\"$lt_save_ifs\"\n  done\n  : ${lt_cv_path_NM=no}\nfi])\nif test \"$lt_cv_path_NM\" != \"no\"; then\n  NM=\"$lt_cv_path_NM\"\nelse\n  # Didn't find any BSD compatible name lister, look for dumpbin.\n  if test -n \"$DUMPBIN\"; then :\n    # Let the user override the test.\n  else\n    AC_CHECK_TOOLS(DUMPBIN, [dumpbin \"link -dump\"], :)\n    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in\n    *COFF*)\n      DUMPBIN=\"$DUMPBIN -symbols\"\n      ;;\n    *)\n      DUMPBIN=:\n      ;;\n    esac\n  fi\n  AC_SUBST([DUMPBIN])\n  if test \"$DUMPBIN\" != \":\"; then\n    NM=\"$DUMPBIN\"\n  fi\nfi\ntest -z \"$NM\" && NM=nm\nAC_SUBST([NM])\n_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl\n\nAC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],\n  [lt_cv_nm_interface=\"BSD nm\"\n  echo \"int some_variable = 0;\" > conftest.$ac_ext\n  (eval echo \"\\\"\\$as_me:$LINENO: $ac_compile\\\"\" >&AS_MESSAGE_LOG_FD)\n  (eval \"$ac_compile\" 2>conftest.err)\n  cat conftest.err >&AS_MESSAGE_LOG_FD\n  (eval echo \"\\\"\\$as_me:$LINENO: $NM \\\\\\\"conftest.$ac_objext\\\\\\\"\\\"\" >&AS_MESSAGE_LOG_FD)\n  (eval \"$NM \\\"conftest.$ac_objext\\\"\" 2>conftest.err > conftest.out)\n  cat conftest.err >&AS_MESSAGE_LOG_FD\n  (eval echo \"\\\"\\$as_me:$LINENO: output\\\"\" >&AS_MESSAGE_LOG_FD)\n  cat conftest.out >&AS_MESSAGE_LOG_FD\n  if $GREP 'External.*some_variable' conftest.out > /dev/null; then\n    lt_cv_nm_interface=\"MS dumpbin\"\n  fi\n  rm -f conftest*])\n])# LT_PATH_NM\n\n# Old names:\nAU_ALIAS([AM_PROG_NM], [LT_PATH_NM])\nAU_ALIAS([AC_PROG_NM], [LT_PATH_NM])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AM_PROG_NM], [])\ndnl AC_DEFUN([AC_PROG_NM], [])\n\n# _LT_CHECK_SHAREDLIB_FROM_LINKLIB\n# --------------------------------\n# how to determine the name of the shared library\n# associated with a specific link library.\n#  -- PORTME fill in with the dynamic library characteristics\nm4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],\n[m4_require([_LT_DECL_EGREP])\nm4_require([_LT_DECL_OBJDUMP])\nm4_require([_LT_DECL_DLLTOOL])\nAC_CACHE_CHECK([how to associate runtime and link libraries],\nlt_cv_sharedlib_from_linklib_cmd,\n[lt_cv_sharedlib_from_linklib_cmd='unknown'\n\ncase $host_os in\ncygwin* | mingw* | pw32* | cegcc*)\n  # two different shell functions defined in ltmain.sh\n  # decide which to use based on capabilities of $DLLTOOL\n  case `$DLLTOOL --help 2>&1` in\n  *--identify-strict*)\n    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib\n    ;;\n  *)\n    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback\n    ;;\n  esac\n  ;;\n*)\n  # fallback: assume linklib IS sharedlib\n  lt_cv_sharedlib_from_linklib_cmd=\"$ECHO\"\n  ;;\nesac\n])\nsharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd\ntest -z \"$sharedlib_from_linklib_cmd\" && sharedlib_from_linklib_cmd=$ECHO\n\n_LT_DECL([], [sharedlib_from_linklib_cmd], [1],\n    [Command to associate shared and link libraries])\n])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB\n\n\n# _LT_PATH_MANIFEST_TOOL\n# ----------------------\n# locate the manifest tool\nm4_defun([_LT_PATH_MANIFEST_TOOL],\n[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)\ntest -z \"$MANIFEST_TOOL\" && MANIFEST_TOOL=mt\nAC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],\n  [lt_cv_path_mainfest_tool=no\n  echo \"$as_me:$LINENO: $MANIFEST_TOOL '-?'\" >&AS_MESSAGE_LOG_FD\n  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out\n  cat conftest.err >&AS_MESSAGE_LOG_FD\n  if $GREP 'Manifest Tool' conftest.out > /dev/null; then\n    lt_cv_path_mainfest_tool=yes\n  fi\n  rm -f conftest*])\nif test \"x$lt_cv_path_mainfest_tool\" != xyes; then\n  MANIFEST_TOOL=:\nfi\n_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl\n])# _LT_PATH_MANIFEST_TOOL\n\n\n# LT_LIB_M\n# --------\n# check for math library\nAC_DEFUN([LT_LIB_M],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\nLIBM=\ncase $host in\n*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)\n  # These system don't have libm, or don't need it\n  ;;\n*-ncr-sysv4.3*)\n  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=\"-lmw\")\n  AC_CHECK_LIB(m, cos, LIBM=\"$LIBM -lm\")\n  ;;\n*)\n  AC_CHECK_LIB(m, cos, LIBM=\"-lm\")\n  ;;\nesac\nAC_SUBST([LIBM])\n])# LT_LIB_M\n\n# Old name:\nAU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_CHECK_LIBM], [])\n\n\n# _LT_COMPILER_NO_RTTI([TAGNAME])\n# -------------------------------\nm4_defun([_LT_COMPILER_NO_RTTI],\n[m4_require([_LT_TAG_COMPILER])dnl\n\n_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=\n\nif test \"$GCC\" = yes; then\n  case $cc_basename in\n  nvcc*)\n    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;\n  *)\n    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;\n  esac\n\n  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],\n    lt_cv_prog_compiler_rtti_exceptions,\n    [-fno-rtti -fno-exceptions], [],\n    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=\"$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions\"])\nfi\n_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],\n\t[Compiler flag to turn off builtin functions])\n])# _LT_COMPILER_NO_RTTI\n\n\n# _LT_CMD_GLOBAL_SYMBOLS\n# ----------------------\nm4_defun([_LT_CMD_GLOBAL_SYMBOLS],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\nAC_REQUIRE([AC_PROG_CC])dnl\nAC_REQUIRE([AC_PROG_AWK])dnl\nAC_REQUIRE([LT_PATH_NM])dnl\nAC_REQUIRE([LT_PATH_LD])dnl\nm4_require([_LT_DECL_SED])dnl\nm4_require([_LT_DECL_EGREP])dnl\nm4_require([_LT_TAG_COMPILER])dnl\n\n# Check for command to grab the raw symbol name followed by C symbol from nm.\nAC_MSG_CHECKING([command to parse $NM output from $compiler object])\nAC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],\n[\n# These are sane defaults that work on at least a few old systems.\n# [They come from Ultrix.  What could be older than Ultrix?!! ;)]\n\n# Character class describing NM global symbol codes.\nsymcode='[[BCDEGRST]]'\n\n# Regexp to match symbols that can be accessed directly from C.\nsympat='\\([[_A-Za-z]][[_A-Za-z0-9]]*\\)'\n\n# Define system-specific variables.\ncase $host_os in\naix*)\n  symcode='[[BCDT]]'\n  ;;\ncygwin* | mingw* | pw32* | cegcc*)\n  symcode='[[ABCDGISTW]]'\n  ;;\nhpux*)\n  if test \"$host_cpu\" = ia64; then\n    symcode='[[ABCDEGRST]]'\n  fi\n  ;;\nirix* | nonstopux*)\n  symcode='[[BCDEGRST]]'\n  ;;\nosf*)\n  symcode='[[BCDEGQRST]]'\n  ;;\nsolaris*)\n  symcode='[[BDRT]]'\n  ;;\nsco3.2v5*)\n  symcode='[[DT]]'\n  ;;\nsysv4.2uw2*)\n  symcode='[[DT]]'\n  ;;\nsysv5* | sco5v6* | unixware* | OpenUNIX*)\n  symcode='[[ABDT]]'\n  ;;\nsysv4)\n  symcode='[[DFNSTU]]'\n  ;;\nesac\n\n# If we're using GNU nm, then use its standard symbol codes.\ncase `$NM -V 2>&1` in\n*GNU* | *'with BFD'*)\n  symcode='[[ABCDGIRSTW]]' ;;\nesac\n\n# Transform an extracted symbol line into a proper C declaration.\n# Some systems (esp. on ia64) link data and code symbols differently,\n# so use this general approach.\nlt_cv_sys_global_symbol_to_cdecl=\"sed -n -e 's/^T .* \\(.*\\)$/extern int \\1();/p' -e 's/^$symcode* .* \\(.*\\)$/extern char \\1;/p'\"\n\n# Transform an extracted symbol line into symbol name and symbol address\nlt_cv_sys_global_symbol_to_c_name_address=\"sed -n -e 's/^: \\([[^ ]]*\\)[[ ]]*$/  {\\\\\\\"\\1\\\\\\\", (void *) 0},/p' -e 's/^$symcode* \\([[^ ]]*\\) \\([[^ ]]*\\)$/  {\\\"\\2\\\", (void *) \\&\\2},/p'\"\nlt_cv_sys_global_symbol_to_c_name_address_lib_prefix=\"sed -n -e 's/^: \\([[^ ]]*\\)[[ ]]*$/  {\\\\\\\"\\1\\\\\\\", (void *) 0},/p' -e 's/^$symcode* \\([[^ ]]*\\) \\(lib[[^ ]]*\\)$/  {\\\"\\2\\\", (void *) \\&\\2},/p' -e 's/^$symcode* \\([[^ ]]*\\) \\([[^ ]]*\\)$/  {\\\"lib\\2\\\", (void *) \\&\\2},/p'\"\n\n# Handle CRLF in mingw tool chain\nopt_cr=\ncase $build_os in\nmingw*)\n  opt_cr=`$ECHO 'x\\{0,1\\}' | tr x '\\015'` # option cr in regexp\n  ;;\nesac\n\n# Try without a prefix underscore, then with it.\nfor ac_symprfx in \"\" \"_\"; do\n\n  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.\n  symxfrm=\"\\\\1 $ac_symprfx\\\\2 \\\\2\"\n\n  # Write the raw and C identifiers.\n  if test \"$lt_cv_nm_interface\" = \"MS dumpbin\"; then\n    # Fake it for dumpbin and say T for any non-static function\n    # and D for any global variable.\n    # Also find C++ and __fastcall symbols from MSVC++,\n    # which start with @ or ?.\n    lt_cv_sys_global_symbol_pipe=\"$AWK ['\"\\\n\"     {last_section=section; section=\\$ 3};\"\\\n\"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};\"\\\n\"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};\"\\\n\"     \\$ 0!~/External *\\|/{next};\"\\\n\"     / 0+ UNDEF /{next}; / UNDEF \\([^|]\\)*()/{next};\"\\\n\"     {if(hide[section]) next};\"\\\n\"     {f=0}; \\$ 0~/\\(\\).*\\|/{f=1}; {printf f ? \\\"T \\\" : \\\"D \\\"};\"\\\n\"     {split(\\$ 0, a, /\\||\\r/); split(a[2], s)};\"\\\n\"     s[1]~/^[@?]/{print s[1], s[1]; next};\"\\\n\"     s[1]~prfx {split(s[1],t,\\\"@\\\"); print t[1], substr(t[1],length(prfx))}\"\\\n\"     ' prfx=^$ac_symprfx]\"\n  else\n    lt_cv_sys_global_symbol_pipe=\"sed -n -e 's/^.*[[\t ]]\\($symcode$symcode*\\)[[\t ]][[\t ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'\"\n  fi\n  lt_cv_sys_global_symbol_pipe=\"$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'\"\n\n  # Check to see that the pipe works correctly.\n  pipe_works=no\n\n  rm -f conftest*\n  cat > conftest.$ac_ext <<_LT_EOF\n#ifdef __cplusplus\nextern \"C\" {\n#endif\nchar nm_test_var;\nvoid nm_test_func(void);\nvoid nm_test_func(void){}\n#ifdef __cplusplus\n}\n#endif\nint main(){nm_test_var='a';nm_test_func();return(0);}\n_LT_EOF\n\n  if AC_TRY_EVAL(ac_compile); then\n    # Now try to grab the symbols.\n    nlist=conftest.nm\n    if AC_TRY_EVAL(NM conftest.$ac_objext \\| \"$lt_cv_sys_global_symbol_pipe\" \\> $nlist) && test -s \"$nlist\"; then\n      # Try sorting and uniquifying the output.\n      if sort \"$nlist\" | uniq > \"$nlist\"T; then\n\tmv -f \"$nlist\"T \"$nlist\"\n      else\n\trm -f \"$nlist\"T\n      fi\n\n      # Make sure that we snagged all the symbols we need.\n      if $GREP ' nm_test_var$' \"$nlist\" >/dev/null; then\n\tif $GREP ' nm_test_func$' \"$nlist\" >/dev/null; then\n\t  cat <<_LT_EOF > conftest.$ac_ext\n/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */\n#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)\n/* DATA imports from DLLs on WIN32 con't be const, because runtime\n   relocations are performed -- see ld's documentation on pseudo-relocs.  */\n# define LT@&t@_DLSYM_CONST\n#elif defined(__osf__)\n/* This system does not cope well with relocations in const data.  */\n# define LT@&t@_DLSYM_CONST\n#else\n# define LT@&t@_DLSYM_CONST const\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n_LT_EOF\n\t  # Now generate the symbol file.\n\t  eval \"$lt_cv_sys_global_symbol_to_cdecl\"' < \"$nlist\" | $GREP -v main >> conftest.$ac_ext'\n\n\t  cat <<_LT_EOF >> conftest.$ac_ext\n\n/* The mapping between symbol names and symbols.  */\nLT@&t@_DLSYM_CONST struct {\n  const char *name;\n  void       *address;\n}\nlt__PROGRAM__LTX_preloaded_symbols[[]] =\n{\n  { \"@PROGRAM@\", (void *) 0 },\n_LT_EOF\n\t  $SED \"s/^$symcode$symcode* \\(.*\\) \\(.*\\)$/  {\\\"\\2\\\", (void *) \\&\\2},/\" < \"$nlist\" | $GREP -v main >> conftest.$ac_ext\n\t  cat <<\\_LT_EOF >> conftest.$ac_ext\n  {0, (void *) 0}\n};\n\n/* This works around a problem in FreeBSD linker */\n#ifdef FREEBSD_WORKAROUND\nstatic const void *lt_preloaded_setup() {\n  return lt__PROGRAM__LTX_preloaded_symbols;\n}\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n_LT_EOF\n\t  # Now try linking the two files.\n\t  mv conftest.$ac_objext conftstm.$ac_objext\n\t  lt_globsym_save_LIBS=$LIBS\n\t  lt_globsym_save_CFLAGS=$CFLAGS\n\t  LIBS=\"conftstm.$ac_objext\"\n\t  CFLAGS=\"$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)\"\n\t  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then\n\t    pipe_works=yes\n\t  fi\n\t  LIBS=$lt_globsym_save_LIBS\n\t  CFLAGS=$lt_globsym_save_CFLAGS\n\telse\n\t  echo \"cannot find nm_test_func in $nlist\" >&AS_MESSAGE_LOG_FD\n\tfi\n      else\n\techo \"cannot find nm_test_var in $nlist\" >&AS_MESSAGE_LOG_FD\n      fi\n    else\n      echo \"cannot run $lt_cv_sys_global_symbol_pipe\" >&AS_MESSAGE_LOG_FD\n    fi\n  else\n    echo \"$progname: failed program was:\" >&AS_MESSAGE_LOG_FD\n    cat conftest.$ac_ext >&5\n  fi\n  rm -rf conftest* conftst*\n\n  # Do not use the global_symbol_pipe unless it works.\n  if test \"$pipe_works\" = yes; then\n    break\n  else\n    lt_cv_sys_global_symbol_pipe=\n  fi\ndone\n])\nif test -z \"$lt_cv_sys_global_symbol_pipe\"; then\n  lt_cv_sys_global_symbol_to_cdecl=\nfi\nif test -z \"$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl\"; then\n  AC_MSG_RESULT(failed)\nelse\n  AC_MSG_RESULT(ok)\nfi\n\n# Response file support.\nif test \"$lt_cv_nm_interface\" = \"MS dumpbin\"; then\n  nm_file_list_spec='@'\nelif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then\n  nm_file_list_spec='@'\nfi\n\n_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],\n    [Take the output of nm and produce a listing of raw symbols and C names])\n_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],\n    [Transform the output of nm in a proper C declaration])\n_LT_DECL([global_symbol_to_c_name_address],\n    [lt_cv_sys_global_symbol_to_c_name_address], [1],\n    [Transform the output of nm in a C name address pair])\n_LT_DECL([global_symbol_to_c_name_address_lib_prefix],\n    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],\n    [Transform the output of nm in a C name address pair when lib prefix is needed])\n_LT_DECL([], [nm_file_list_spec], [1],\n    [Specify filename containing input files for $NM])\n]) # _LT_CMD_GLOBAL_SYMBOLS\n\n\n# _LT_COMPILER_PIC([TAGNAME])\n# ---------------------------\nm4_defun([_LT_COMPILER_PIC],\n[m4_require([_LT_TAG_COMPILER])dnl\n_LT_TAGVAR(lt_prog_compiler_wl, $1)=\n_LT_TAGVAR(lt_prog_compiler_pic, $1)=\n_LT_TAGVAR(lt_prog_compiler_static, $1)=\n\nm4_if([$1], [CXX], [\n  # C++ specific cases for pic, static, wl, etc.\n  if test \"$GXX\" = yes; then\n    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'\n\n    case $host_os in\n    aix*)\n      # All AIX code is PIC.\n      if test \"$host_cpu\" = ia64; then\n\t# AIX 5 now supports IA64 processor\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n        ;;\n      m68k)\n            # FIXME: we need at least 68020 code to build shared libraries, but\n            # adding the `-m68020' flag to GCC prevents building anything better,\n            # like `-m68040'.\n            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'\n        ;;\n      esac\n      ;;\n\n    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)\n      # PIC is the default for these OSes.\n      ;;\n    mingw* | cygwin* | os2* | pw32* | cegcc*)\n      # This hack is so that the source file can tell whether it is being\n      # built for inclusion in a dll (and should export symbols for example).\n      # Although the cygwin gcc ignores -fPIC, still need this for old-style\n      # (--disable-auto-import) libraries\n      m4_if([$1], [GCJ], [],\n\t[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])\n      ;;\n    darwin* | rhapsody*)\n      # PIC is the default on this platform\n      # Common symbols not allowed in MH_DYLIB files\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'\n      ;;\n    *djgpp*)\n      # DJGPP does not support shared libraries at all\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)=\n      ;;\n    haiku*)\n      # PIC is the default for Haiku.\n      # The \"-static\" flag exists, but is broken.\n      _LT_TAGVAR(lt_prog_compiler_static, $1)=\n      ;;\n    interix[[3-9]]*)\n      # Interix 3.x gcc -fpic/-fPIC options generate broken code.\n      # Instead, we relocate shared libraries at runtime.\n      ;;\n    sysv4*MP*)\n      if test -d /usr/nec; then\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic\n      fi\n      ;;\n    hpux*)\n      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit\n      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag\n      # sets the default TLS model and affects inlining.\n      case $host_cpu in\n      hppa*64*)\n\t;;\n      *)\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n\t;;\n      esac\n      ;;\n    *qnx* | *nto*)\n      # QNX uses GNU C++, but need to define -shared option too, otherwise\n      # it will coredump.\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'\n      ;;\n    *)\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n      ;;\n    esac\n  else\n    case $host_os in\n      aix[[4-9]]*)\n\t# All AIX code is PIC.\n\tif test \"$host_cpu\" = ia64; then\n\t  # AIX 5 now supports IA64 processor\n\t  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\telse\n\t  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'\n\tfi\n\t;;\n      chorus*)\n\tcase $cc_basename in\n\tcxch68*)\n\t  # Green Hills C++ Compiler\n\t  # _LT_TAGVAR(lt_prog_compiler_static, $1)=\"--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a\"\n\t  ;;\n\tesac\n\t;;\n      mingw* | cygwin* | os2* | pw32* | cegcc*)\n\t# This hack is so that the source file can tell whether it is being\n\t# built for inclusion in a dll (and should export symbols for example).\n\tm4_if([$1], [GCJ], [],\n\t  [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])\n\t;;\n      dgux*)\n\tcase $cc_basename in\n\t  ec++*)\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t    ;;\n\t  ghcx*)\n\t    # Green Hills C++ Compiler\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      freebsd* | dragonfly*)\n\t# FreeBSD uses GNU C++\n\t;;\n      hpux9* | hpux10* | hpux11*)\n\tcase $cc_basename in\n\t  CC*)\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'\n\t    if test \"$host_cpu\" != ia64; then\n\t      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'\n\t    fi\n\t    ;;\n\t  aCC*)\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'\n\t    case $host_cpu in\n\t    hppa*64*|ia64*)\n\t      # +Z the default\n\t      ;;\n\t    *)\n\t      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'\n\t      ;;\n\t    esac\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      interix*)\n\t# This is c89, which is MS Visual C++ (no shared libs)\n\t# Anyone wants to do a port?\n\t;;\n      irix5* | irix6* | nonstopux*)\n\tcase $cc_basename in\n\t  CC*)\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n\t    # CC pic flag -KPIC is the default.\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      linux* | k*bsd*-gnu | kopensolaris*-gnu)\n\tcase $cc_basename in\n\t  KCC*)\n\t    # KAI C++ Compiler\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n\t    ;;\n\t  ecpc* )\n\t    # old Intel C++ for x86_64 which still supported -KPIC.\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'\n\t    ;;\n\t  icpc* )\n\t    # Intel C++, used to be incompatible with GCC.\n\t    # ICC 10 doesn't accept -KPIC any more.\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'\n\t    ;;\n\t  pgCC* | pgcpp*)\n\t    # Portland Group C++ compiler\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t    ;;\n\t  cxx*)\n\t    # Compaq C++\n\t    # Make sure the PIC flag is empty.  It appears that all Alpha\n\t    # Linux and Compaq Tru64 Unix objects are PIC.\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)=\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n\t    ;;\n\t  xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)\n\t    # IBM XL 8.0, 9.0 on PPC and BlueGene\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'\n\t    ;;\n\t  *)\n\t    case `$CC -V 2>&1 | sed 5q` in\n\t    *Sun\\ C*)\n\t      # Sun C++ 5.9\n\t      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '\n\t      ;;\n\t    esac\n\t    ;;\n\tesac\n\t;;\n      lynxos*)\n\t;;\n      m88k*)\n\t;;\n      mvs*)\n\tcase $cc_basename in\n\t  cxx*)\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      netbsd*)\n\t;;\n      *qnx* | *nto*)\n        # QNX uses GNU C++, but need to define -shared option too, otherwise\n        # it will coredump.\n        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'\n        ;;\n      osf3* | osf4* | osf5*)\n\tcase $cc_basename in\n\t  KCC*)\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'\n\t    ;;\n\t  RCC*)\n\t    # Rational C++ 2.4.1\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'\n\t    ;;\n\t  cxx*)\n\t    # Digital/Compaq C++\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    # Make sure the PIC flag is empty.  It appears that all Alpha\n\t    # Linux and Compaq Tru64 Unix objects are PIC.\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)=\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      psos*)\n\t;;\n      solaris*)\n\tcase $cc_basename in\n\t  CC* | sunCC*)\n\t    # Sun C++ 4.2, 5.x and Centerline C++\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '\n\t    ;;\n\t  gcx*)\n\t    # Green Hills C++ Compiler\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      sunos4*)\n\tcase $cc_basename in\n\t  CC*)\n\t    # Sun C++ 4.x\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t    ;;\n\t  lcc*)\n\t    # Lucid\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)\n\tcase $cc_basename in\n\t  CC*)\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t    ;;\n\tesac\n\t;;\n      tandem*)\n\tcase $cc_basename in\n\t  NCC*)\n\t    # NonStop-UX NCC 3.20\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      vxworks*)\n\t;;\n      *)\n\t_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no\n\t;;\n    esac\n  fi\n],\n[\n  if test \"$GCC\" = yes; then\n    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'\n\n    case $host_os in\n      aix*)\n      # All AIX code is PIC.\n      if test \"$host_cpu\" = ia64; then\n\t# AIX 5 now supports IA64 processor\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n        ;;\n      m68k)\n            # FIXME: we need at least 68020 code to build shared libraries, but\n            # adding the `-m68020' flag to GCC prevents building anything better,\n            # like `-m68040'.\n            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'\n        ;;\n      esac\n      ;;\n\n    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)\n      # PIC is the default for these OSes.\n      ;;\n\n    mingw* | cygwin* | pw32* | os2* | cegcc*)\n      # This hack is so that the source file can tell whether it is being\n      # built for inclusion in a dll (and should export symbols for example).\n      # Although the cygwin gcc ignores -fPIC, still need this for old-style\n      # (--disable-auto-import) libraries\n      m4_if([$1], [GCJ], [],\n\t[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])\n      ;;\n\n    darwin* | rhapsody*)\n      # PIC is the default on this platform\n      # Common symbols not allowed in MH_DYLIB files\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'\n      ;;\n\n    haiku*)\n      # PIC is the default for Haiku.\n      # The \"-static\" flag exists, but is broken.\n      _LT_TAGVAR(lt_prog_compiler_static, $1)=\n      ;;\n\n    hpux*)\n      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit\n      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag\n      # sets the default TLS model and affects inlining.\n      case $host_cpu in\n      hppa*64*)\n\t# +Z the default\n\t;;\n      *)\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n\t;;\n      esac\n      ;;\n\n    interix[[3-9]]*)\n      # Interix 3.x gcc -fpic/-fPIC options generate broken code.\n      # Instead, we relocate shared libraries at runtime.\n      ;;\n\n    msdosdjgpp*)\n      # Just because we use GCC doesn't mean we suddenly get shared libraries\n      # on systems that don't support them.\n      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no\n      enable_shared=no\n      ;;\n\n    *nto* | *qnx*)\n      # QNX uses GNU C++, but need to define -shared option too, otherwise\n      # it will coredump.\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec; then\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic\n      fi\n      ;;\n\n    *)\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n      ;;\n    esac\n\n    case $cc_basename in\n    nvcc*) # Cuda Compiler Driver 2.2\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '\n      if test -n \"$_LT_TAGVAR(lt_prog_compiler_pic, $1)\"; then\n        _LT_TAGVAR(lt_prog_compiler_pic, $1)=\"-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)\"\n      fi\n      ;;\n    esac\n  else\n    # PORTME Check for flag to pass linker flags through the system compiler.\n    case $host_os in\n    aix*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      if test \"$host_cpu\" = ia64; then\n\t# AIX 5 now supports IA64 processor\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      else\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'\n      fi\n      ;;\n\n    mingw* | cygwin* | pw32* | os2* | cegcc*)\n      # This hack is so that the source file can tell whether it is being\n      # built for inclusion in a dll (and should export symbols for example).\n      m4_if([$1], [GCJ], [],\n\t[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])\n      ;;\n\n    hpux9* | hpux10* | hpux11*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but\n      # not for PA HP-UX.\n      case $host_cpu in\n      hppa*64*|ia64*)\n\t# +Z the default\n\t;;\n      *)\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'\n\t;;\n      esac\n      # Is there a better lt_prog_compiler_static that works with the bundled CC?\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'\n      ;;\n\n    irix5* | irix6* | nonstopux*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      # PIC (with -KPIC) is the default.\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n      ;;\n\n    linux* | k*bsd*-gnu | kopensolaris*-gnu)\n      case $cc_basename in\n      # old Intel for x86_64 which still supported -KPIC.\n      ecc*)\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'\n        ;;\n      # icc used to be incompatible with GCC.\n      # ICC 10 doesn't accept -KPIC any more.\n      icc* | ifort*)\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'\n        ;;\n      # Lahey Fortran 8.1.\n      lf95*)\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'\n\t;;\n      nagfor*)\n\t# NAG Fortran compiler\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t;;\n      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)\n        # Portland Group compilers (*not* the Pentium gcc compiler,\n\t# which looks to be a dead project)\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n        ;;\n      ccc*)\n        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n        # All Alpha code is PIC.\n        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n        ;;\n      xl* | bgxl* | bgf* | mpixl*)\n\t# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'\n\t;;\n      *)\n\tcase `$CC -V 2>&1 | sed 5q` in\n\t*Sun\\ Ceres\\ Fortran* | *Sun*Fortran*\\ [[1-7]].* | *Sun*Fortran*\\ 8.[[0-3]]*)\n\t  # Sun Fortran 8.3 passes all unrecognized flags to the linker\n\t  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''\n\t  ;;\n\t*Sun\\ F* | *Sun*Fortran*)\n\t  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '\n\t  ;;\n\t*Sun\\ C*)\n\t  # Sun C 5.9\n\t  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t  ;;\n        *Intel*\\ [[CF]]*Compiler*)\n\t  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n\t  _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'\n\t  ;;\n\t*Portland\\ Group*)\n\t  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'\n\t  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t  ;;\n\tesac\n\t;;\n      esac\n      ;;\n\n    newsos6)\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      ;;\n\n    *nto* | *qnx*)\n      # QNX uses GNU C++, but need to define -shared option too, otherwise\n      # it will coredump.\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'\n      ;;\n\n    osf3* | osf4* | osf5*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      # All OSF/1 code is PIC.\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n      ;;\n\n    rdos*)\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n      ;;\n\n    solaris*)\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      case $cc_basename in\n      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;\n      *)\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;\n      esac\n      ;;\n\n    sunos4*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      ;;\n\n    sysv4 | sysv4.2uw2* | sysv4.3*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec ;then\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      fi\n      ;;\n\n    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      ;;\n\n    unicos*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no\n      ;;\n\n    uts4*)\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      ;;\n\n    *)\n      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no\n      ;;\n    esac\n  fi\n])\ncase $host_os in\n  # For platforms which do not support PIC, -DPIC is meaningless:\n  *djgpp*)\n    _LT_TAGVAR(lt_prog_compiler_pic, $1)=\n    ;;\n  *)\n    _LT_TAGVAR(lt_prog_compiler_pic, $1)=\"$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])\"\n    ;;\nesac\n\nAC_CACHE_CHECK([for $compiler option to produce PIC],\n  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],\n  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])\n_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)\n\n#\n# Check to make sure the PIC flag actually works.\n#\nif test -n \"$_LT_TAGVAR(lt_prog_compiler_pic, $1)\"; then\n  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],\n    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],\n    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],\n    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in\n     \"\" | \" \"*) ;;\n     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=\" $_LT_TAGVAR(lt_prog_compiler_pic, $1)\" ;;\n     esac],\n    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=\n     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])\nfi\n_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],\n\t[Additional compiler flags for building library objects])\n\n_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],\n\t[How to pass a linker flag through the compiler])\n#\n# Check to make sure the static flag actually works.\n#\nwl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\\\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\\\"\n_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],\n  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),\n  $lt_tmp_static_flag,\n  [],\n  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])\n_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],\n\t[Compiler flag to prevent dynamic linking])\n])# _LT_COMPILER_PIC\n\n\n# _LT_LINKER_SHLIBS([TAGNAME])\n# ----------------------------\n# See if the linker supports building shared libraries.\nm4_defun([_LT_LINKER_SHLIBS],\n[AC_REQUIRE([LT_PATH_LD])dnl\nAC_REQUIRE([LT_PATH_NM])dnl\nm4_require([_LT_PATH_MANIFEST_TOOL])dnl\nm4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_DECL_EGREP])dnl\nm4_require([_LT_DECL_SED])dnl\nm4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl\nm4_require([_LT_TAG_COMPILER])dnl\nAC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])\nm4_if([$1], [CXX], [\n  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\\''s/.* //'\\'' | sort | uniq > $export_symbols'\n  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']\n  case $host_os in\n  aix[[4-9]]*)\n    # If we're using GNU nm, then we don't want the \"-C\" option.\n    # -C means demangle to AIX nm, but means don't demangle with GNU nm\n    # Also, AIX nm treats weak defined symbols like other global defined\n    # symbols, whereas GNU nm marks them as \"W\".\n    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then\n      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\") || (\\$ 2 == \"W\")) && ([substr](\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n    else\n      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\")) && ([substr](\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n    fi\n    ;;\n  pw32*)\n    _LT_TAGVAR(export_symbols_cmds, $1)=\"$ltdll_cmds\"\n    ;;\n  cygwin* | mingw* | cegcc*)\n    case $cc_basename in\n    cl*)\n      _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'\n      ;;\n    *)\n      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\\([[^ ]]*\\)/\\1 DATA/;s/^.*[[ ]]__nm__\\([[^ ]]*\\)[[ ]][[^ ]]*/\\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\\'' | sort | uniq > $export_symbols'\n      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']\n      ;;\n    esac\n    ;;\n  *)\n    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\\''s/.* //'\\'' | sort | uniq > $export_symbols'\n    ;;\n  esac\n], [\n  runpath_var=\n  _LT_TAGVAR(allow_undefined_flag, $1)=\n  _LT_TAGVAR(always_export_symbols, $1)=no\n  _LT_TAGVAR(archive_cmds, $1)=\n  _LT_TAGVAR(archive_expsym_cmds, $1)=\n  _LT_TAGVAR(compiler_needs_object, $1)=no\n  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no\n  _LT_TAGVAR(export_dynamic_flag_spec, $1)=\n  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\\''s/.* //'\\'' | sort | uniq > $export_symbols'\n  _LT_TAGVAR(hardcode_automatic, $1)=no\n  _LT_TAGVAR(hardcode_direct, $1)=no\n  _LT_TAGVAR(hardcode_direct_absolute, $1)=no\n  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=\n  _LT_TAGVAR(hardcode_libdir_separator, $1)=\n  _LT_TAGVAR(hardcode_minus_L, $1)=no\n  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported\n  _LT_TAGVAR(inherit_rpath, $1)=no\n  _LT_TAGVAR(link_all_deplibs, $1)=unknown\n  _LT_TAGVAR(module_cmds, $1)=\n  _LT_TAGVAR(module_expsym_cmds, $1)=\n  _LT_TAGVAR(old_archive_from_new_cmds, $1)=\n  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=\n  _LT_TAGVAR(thread_safe_flag_spec, $1)=\n  _LT_TAGVAR(whole_archive_flag_spec, $1)=\n  # include_expsyms should be a list of space-separated symbols to be *always*\n  # included in the symbol list\n  _LT_TAGVAR(include_expsyms, $1)=\n  # exclude_expsyms can be an extended regexp of symbols to exclude\n  # it will be wrapped by ` (' and `)$', so one must not match beginning or\n  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',\n  # as well as any symbol that contains `d'.\n  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']\n  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out\n  # platforms (ab)use it in PIC code, but their linkers get confused if\n  # the symbol is explicitly referenced.  Since portable code cannot\n  # rely on this symbol name, it's probably fine to never include it in\n  # preloaded symbol tables.\n  # Exclude shared library initialization/finalization symbols.\ndnl Note also adjust exclude_expsyms for C++ above.\n  extract_expsyms_cmds=\n\n  case $host_os in\n  cygwin* | mingw* | pw32* | cegcc*)\n    # FIXME: the MSVC++ port hasn't been tested in a loooong time\n    # When not using gcc, we currently assume that we are using\n    # Microsoft Visual C++.\n    if test \"$GCC\" != yes; then\n      with_gnu_ld=no\n    fi\n    ;;\n  interix*)\n    # we just hope/assume this is gcc and not c89 (= MSVC++)\n    with_gnu_ld=yes\n    ;;\n  openbsd*)\n    with_gnu_ld=no\n    ;;\n  esac\n\n  _LT_TAGVAR(ld_shlibs, $1)=yes\n\n  # On some targets, GNU ld is compatible enough with the native linker\n  # that we're better off using the native interface for both.\n  lt_use_gnu_ld_interface=no\n  if test \"$with_gnu_ld\" = yes; then\n    case $host_os in\n      aix*)\n\t# The AIX port of GNU ld has always aspired to compatibility\n\t# with the native linker.  However, as the warning in the GNU ld\n\t# block says, versions before 2.19.5* couldn't really create working\n\t# shared libraries, regardless of the interface used.\n\tcase `$LD -v 2>&1` in\n\t  *\\ \\(GNU\\ Binutils\\)\\ 2.19.5*) ;;\n\t  *\\ \\(GNU\\ Binutils\\)\\ 2.[[2-9]]*) ;;\n\t  *\\ \\(GNU\\ Binutils\\)\\ [[3-9]]*) ;;\n\t  *)\n\t    lt_use_gnu_ld_interface=yes\n\t    ;;\n\tesac\n\t;;\n      *)\n\tlt_use_gnu_ld_interface=yes\n\t;;\n    esac\n  fi\n\n  if test \"$lt_use_gnu_ld_interface\" = yes; then\n    # If archive_cmds runs LD, not CC, wlarc should be empty\n    wlarc='${wl}'\n\n    # Set some defaults for GNU ld with shared library support. These\n    # are reset later if shared libraries are not supported. Putting them\n    # here allows them to be overridden if necessary.\n    runpath_var=LD_RUN_PATH\n    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'\n    # ancient GNU ld didn't support --whole-archive et. al.\n    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then\n      _LT_TAGVAR(whole_archive_flag_spec, $1)=\"$wlarc\"'--whole-archive$convenience '\"$wlarc\"'--no-whole-archive'\n    else\n      _LT_TAGVAR(whole_archive_flag_spec, $1)=\n    fi\n    supports_anon_versioning=no\n    case `$LD -v 2>&1` in\n      *GNU\\ gold*) supports_anon_versioning=yes ;;\n      *\\ [[01]].* | *\\ 2.[[0-9]].* | *\\ 2.10.*) ;; # catch versions < 2.11\n      *\\ 2.11.93.0.2\\ *) supports_anon_versioning=yes ;; # RH7.3 ...\n      *\\ 2.11.92.0.12\\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...\n      *\\ 2.11.*) ;; # other 2.11 versions\n      *) supports_anon_versioning=yes ;;\n    esac\n\n    # See if GNU ld supports shared libraries.\n    case $host_os in\n    aix[[3-9]]*)\n      # On AIX/PPC, the GNU linker is very broken\n      if test \"$host_cpu\" != ia64; then\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: the GNU linker, at least up to release 2.19, is reported\n*** to be unable to reliably create shared libraries on AIX.\n*** Therefore, libtool is disabling shared libraries support.  If you\n*** really care for shared libraries, you may want to install binutils\n*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.\n*** You will then need to restart the configuration process.\n\n_LT_EOF\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n            _LT_TAGVAR(archive_expsym_cmds, $1)=''\n        ;;\n      m68k)\n            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO \"#define NAME $libname\" > $output_objdir/a2ixlibrary.data~$ECHO \"#define LIBRARY_ID 1\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define VERSION $major\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define REVISION $revision\" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'\n            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n            _LT_TAGVAR(hardcode_minus_L, $1)=yes\n        ;;\n      esac\n      ;;\n\n    beos*)\n      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t_LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n\t# Joseph Beckenbach <jrb3@best.com> says some releases of gcc\n\t# support --undefined.  This deserves some investigation.  FIXME\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n      else\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n      fi\n      ;;\n\n    cygwin* | mingw* | pw32* | cegcc*)\n      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,\n      # as there is no search path for DLLs.\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'\n      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n      _LT_TAGVAR(always_export_symbols, $1)=no\n      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes\n      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\\([[^ ]]*\\)/\\1 DATA/;s/^.*[[ ]]__nm__\\([[^ ]]*\\)[[ ]][[^ ]]*/\\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\\'' | sort | uniq > $export_symbols'\n      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']\n\n      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then\n        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n\t# If the export-symbols file already is a .def file (1st line\n\t# is EXPORTS), use it as is; otherwise, prepend...\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t  cp $export_symbols $output_objdir/$soname.def;\n\telse\n\t  echo EXPORTS > $output_objdir/$soname.def;\n\t  cat $export_symbols >> $output_objdir/$soname.def;\n\tfi~\n\t$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n      else\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n      fi\n      ;;\n\n    haiku*)\n      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n      _LT_TAGVAR(link_all_deplibs, $1)=yes\n      ;;\n\n    interix[[3-9]]*)\n      _LT_TAGVAR(hardcode_direct, $1)=no\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.\n      # Instead, shared libraries are loaded at an image base (0x10000000 by\n      # default) and relocated if they conflict, which is a slow very memory\n      # consuming and fragmenting process.  To avoid this, we pick a random,\n      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link\n      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.\n      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n      _LT_TAGVAR(archive_expsym_cmds, $1)='sed \"s,^,_,\" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n      ;;\n\n    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)\n      tmp_diet=no\n      if test \"$host_os\" = linux-dietlibc; then\n\tcase $cc_basename in\n\t  diet\\ *) tmp_diet=yes;;\t# linux-dietlibc with static linking (!diet-dyn)\n\tesac\n      fi\n      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \\\n\t && test \"$tmp_diet\" = no\n      then\n\ttmp_addflag=' $pic_flag'\n\ttmp_sharedflag='-shared'\n\tcase $cc_basename,$host_cpu in\n        pgcc*)\t\t\t\t# Portland Group C compiler\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  tmp_addflag=' $pic_flag'\n\t  ;;\n\tpgf77* | pgf90* | pgf95* | pgfortran*)\n\t\t\t\t\t# Portland Group f77 and f90 compilers\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  tmp_addflag=' $pic_flag -Mnomain' ;;\n\tecc*,ia64* | icc*,ia64*)\t# Intel C compiler on ia64\n\t  tmp_addflag=' -i_dynamic' ;;\n\tefc*,ia64* | ifort*,ia64*)\t# Intel Fortran compiler on ia64\n\t  tmp_addflag=' -i_dynamic -nofor_main' ;;\n\tifc* | ifort*)\t\t\t# Intel Fortran compiler\n\t  tmp_addflag=' -nofor_main' ;;\n\tlf95*)\t\t\t\t# Lahey Fortran 8.1\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)=\n\t  tmp_sharedflag='--shared' ;;\n\txl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)\n\t  tmp_sharedflag='-qmkshrobj'\n\t  tmp_addflag= ;;\n\tnvcc*)\t# Cuda Compiler Driver 2.2\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  _LT_TAGVAR(compiler_needs_object, $1)=yes\n\t  ;;\n\tesac\n\tcase `$CC -V 2>&1 | sed 5q` in\n\t*Sun\\ C*)\t\t\t# Sun C 5.9\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\\\"\\\"; do test -z \\\"$conv\\\" || new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  _LT_TAGVAR(compiler_needs_object, $1)=yes\n\t  tmp_sharedflag='-G' ;;\n\t*Sun\\ F*)\t\t\t# Sun Fortran 8.3\n\t  tmp_sharedflag='-G' ;;\n\tesac\n\t_LT_TAGVAR(archive_cmds, $1)='$CC '\"$tmp_sharedflag\"\"$tmp_addflag\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\n        if test \"x$supports_anon_versioning\" = xyes; then\n          _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $output_objdir/$libname.ver~\n\t    cat $export_symbols | sed -e \"s/\\(.*\\)/\\1;/\" >> $output_objdir/$libname.ver~\n\t    echo \"local: *; };\" >> $output_objdir/$libname.ver~\n\t    $CC '\"$tmp_sharedflag\"\"$tmp_addflag\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'\n        fi\n\n\tcase $cc_basename in\n\txlf* | bgf* | bgxlf* | mpixlf*)\n\t  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n\t  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'\n\t  if test \"x$supports_anon_versioning\" = xyes; then\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $output_objdir/$libname.ver~\n\t      cat $export_symbols | sed -e \"s/\\(.*\\)/\\1;/\" >> $output_objdir/$libname.ver~\n\t      echo \"local: *; };\" >> $output_objdir/$libname.ver~\n\t      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'\n\t  fi\n\t  ;;\n\tesac\n      else\n        _LT_TAGVAR(ld_shlibs, $1)=no\n      fi\n      ;;\n\n    netbsd*)\n      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n\t_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'\n\twlarc=\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      fi\n      ;;\n\n    solaris*)\n      if $LD -v 2>&1 | $GREP 'BFD 2\\.8' > /dev/null; then\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: The releases 2.8.* of the GNU linker cannot reliably\n*** create shared libraries on Solaris systems.  Therefore, libtool\n*** is disabling shared libraries support.  We urge you to upgrade GNU\n*** binutils to release 2.9.1 or newer.  Another option is to modify\n*** your PATH or compiler configuration so that the native linker is\n*** used, and then restart.\n\n_LT_EOF\n      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      else\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n      fi\n      ;;\n\n    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)\n      case `$LD -v 2>&1` in\n        *\\ [[01]].* | *\\ 2.[[0-9]].* | *\\ 2.1[[0-5]].*)\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not\n*** reliably create shared libraries on SCO systems.  Therefore, libtool\n*** is disabling shared libraries support.  We urge you to upgrade GNU\n*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify\n*** your PATH or compiler configuration so that the native linker is\n*** used, and then restart.\n\n_LT_EOF\n\t;;\n\t*)\n\t  # For security reasons, it is highly recommended that you always\n\t  # use absolute paths for naming shared libraries, and exclude the\n\t  # DT_RUNPATH tag from executables and libraries.  But doing so\n\t  # requires that you compile everything twice, which is a pain.\n\t  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\t  else\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t  fi\n\t;;\n      esac\n      ;;\n\n    sunos4*)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n      wlarc=\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    *)\n      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      else\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n      fi\n      ;;\n    esac\n\n    if test \"$_LT_TAGVAR(ld_shlibs, $1)\" = no; then\n      runpath_var=\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)=\n      _LT_TAGVAR(whole_archive_flag_spec, $1)=\n    fi\n  else\n    # PORTME fill in a description of your system's linker (not GNU ld)\n    case $host_os in\n    aix3*)\n      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n      _LT_TAGVAR(always_export_symbols, $1)=yes\n      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'\n      # Note: this linker hardcodes the directories in LIBPATH if there\n      # are no directories specified by -L.\n      _LT_TAGVAR(hardcode_minus_L, $1)=yes\n      if test \"$GCC\" = yes && test -z \"$lt_prog_compiler_static\"; then\n\t# Neither direct hardcoding nor static linking is supported with a\n\t# broken collect2.\n\t_LT_TAGVAR(hardcode_direct, $1)=unsupported\n      fi\n      ;;\n\n    aix[[4-9]]*)\n      if test \"$host_cpu\" = ia64; then\n\t# On IA64, the linker does run time linking by default, so we don't\n\t# have to do anything special.\n\taix_use_runtimelinking=no\n\texp_sym_flag='-Bexport'\n\tno_entry_flag=\"\"\n      else\n\t# If we're using GNU nm, then we don't want the \"-C\" option.\n\t# -C means demangle to AIX nm, but means don't demangle with GNU nm\n\t# Also, AIX nm treats weak defined symbols like other global\n\t# defined symbols, whereas GNU nm marks them as \"W\".\n\tif $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then\n\t  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\") || (\\$ 2 == \"W\")) && ([substr](\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n\telse\n\t  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\")) && ([substr](\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n\tfi\n\taix_use_runtimelinking=no\n\n\t# Test if we are trying to use run time linking or normal\n\t# AIX style linking. If -brtl is somewhere in LDFLAGS, we\n\t# need to do runtime linking.\n\tcase $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)\n\t  for ld_flag in $LDFLAGS; do\n\t  if (test $ld_flag = \"-brtl\" || test $ld_flag = \"-Wl,-brtl\"); then\n\t    aix_use_runtimelinking=yes\n\t    break\n\t  fi\n\t  done\n\t  ;;\n\tesac\n\n\texp_sym_flag='-bexport'\n\tno_entry_flag='-bnoentry'\n      fi\n\n      # When large executables or shared objects are built, AIX ld can\n      # have problems creating the table of contents.  If linking a library\n      # or program results in \"error TOC overflow\" add -mminimal-toc to\n      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not\n      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.\n\n      _LT_TAGVAR(archive_cmds, $1)=''\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'\n      _LT_TAGVAR(link_all_deplibs, $1)=yes\n      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'\n\n      if test \"$GCC\" = yes; then\n\tcase $host_os in aix4.[[012]]|aix4.[[012]].*)\n\t# We only want to do this on AIX 4.2 and lower, the check\n\t# below for broken collect2 doesn't work under 4.3+\n\t  collect2name=`${CC} -print-prog-name=collect2`\n\t  if test -f \"$collect2name\" &&\n\t   strings \"$collect2name\" | $GREP resolve_lib_name >/dev/null\n\t  then\n\t  # We have reworked collect2\n\t  :\n\t  else\n\t  # We have old collect2\n\t  _LT_TAGVAR(hardcode_direct, $1)=unsupported\n\t  # It fails to find uninstalled libraries when the uninstalled\n\t  # path is not listed in the libpath.  Setting hardcode_minus_L\n\t  # to unsupported forces relinking\n\t  _LT_TAGVAR(hardcode_minus_L, $1)=yes\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n\t  _LT_TAGVAR(hardcode_libdir_separator, $1)=\n\t  fi\n\t  ;;\n\tesac\n\tshared_flag='-shared'\n\tif test \"$aix_use_runtimelinking\" = yes; then\n\t  shared_flag=\"$shared_flag \"'${wl}-G'\n\tfi\n      else\n\t# not using gcc\n\tif test \"$host_cpu\" = ia64; then\n\t# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release\n\t# chokes on -Wl,-G. The following line is correct:\n\t  shared_flag='-G'\n\telse\n\t  if test \"$aix_use_runtimelinking\" = yes; then\n\t    shared_flag='${wl}-G'\n\t  else\n\t    shared_flag='${wl}-bM:SRE'\n\t  fi\n\tfi\n      fi\n\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'\n      # It seems that -bexpall does not export symbols beginning with\n      # underscore (_), so it is better to generate a list of symbols to export.\n      _LT_TAGVAR(always_export_symbols, $1)=yes\n      if test \"$aix_use_runtimelinking\" = yes; then\n\t# Warning - without using the other runtime loading flags (-brtl),\n\t# -berok will link without error, but may produce a broken library.\n\t_LT_TAGVAR(allow_undefined_flag, $1)='-berok'\n        # Determine the default libpath from the value encoded in an\n        # empty executable.\n        _LT_SYS_MODULE_PATH_AIX([$1])\n        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags `if test \"x${allow_undefined_flag}\" != \"x\"; then func_echo_all \"${wl}${allow_undefined_flag}\"; else :; fi` '\"\\${wl}$exp_sym_flag:\\$export_symbols $shared_flag\"\n      else\n\tif test \"$host_cpu\" = ia64; then\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=\"-z nodefs\"\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags ${wl}${allow_undefined_flag} '\"\\${wl}$exp_sym_flag:\\$export_symbols\"\n\telse\n\t # Determine the default libpath from the value encoded in an\n\t # empty executable.\n\t _LT_SYS_MODULE_PATH_AIX([$1])\n\t _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n\t  # Warning - without using the other run time loading flags,\n\t  # -berok will link without error, but may produce a broken library.\n\t  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'\n\t  if test \"$with_gnu_ld\" = yes; then\n\t    # We only use this code for GNU lds that support --whole-archive.\n\t    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'\n\t  else\n\t    # Exported symbols can be pulled into shared objects from archives\n\t    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'\n\t  fi\n\t  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes\n\t  # This is similar to how AIX traditionally builds its shared libraries.\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'\n\tfi\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n            _LT_TAGVAR(archive_expsym_cmds, $1)=''\n        ;;\n      m68k)\n            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO \"#define NAME $libname\" > $output_objdir/a2ixlibrary.data~$ECHO \"#define LIBRARY_ID 1\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define VERSION $major\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define REVISION $revision\" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'\n            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n            _LT_TAGVAR(hardcode_minus_L, $1)=yes\n        ;;\n      esac\n      ;;\n\n    bsdi[[45]]*)\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic\n      ;;\n\n    cygwin* | mingw* | pw32* | cegcc*)\n      # When not using gcc, we currently assume that we are using\n      # Microsoft Visual C++.\n      # hardcode_libdir_flag_spec is actually meaningless, as there is\n      # no search path for DLLs.\n      case $cc_basename in\n      cl*)\n\t# Native MSVC\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '\n\t_LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n\t_LT_TAGVAR(always_export_symbols, $1)=yes\n\t_LT_TAGVAR(file_list_spec, $1)='@'\n\t# Tell ltmain to make .lib files, not .a files.\n\tlibext=lib\n\t# Tell ltmain to make .dll files, not .so files.\n\tshrext_cmds=\".dll\"\n\t# FIXME: Setting linknames here is a bad hack.\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t    sed -n -e 's/\\\\\\\\\\\\\\(.*\\\\\\\\\\\\\\)/-link\\\\\\ -EXPORT:\\\\\\\\\\\\\\1/' -e '1\\\\\\!p' < $export_symbols > $output_objdir/$soname.exp;\n\t  else\n\t    sed -e 's/\\\\\\\\\\\\\\(.*\\\\\\\\\\\\\\)/-link\\\\\\ -EXPORT:\\\\\\\\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;\n\t  fi~\n\t  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs \"@$tool_output_objdir$soname.exp\" -Wl,-DLL,-IMPLIB:\"$tool_output_objdir$libname.dll.lib\"~\n\t  linknames='\n\t# The linker will not automatically build a static lib if we build a DLL.\n\t# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'\n\t_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes\n\t_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'\n\t_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\\([[^ ]]*\\)/\\1,DATA/'\\'' | $SED -e '\\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\\'' | sort | uniq > $export_symbols'\n\t# Don't use ranlib\n\t_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'\n\t_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile=\"@OUTPUT@\"~\n\t  lt_tool_outputfile=\"@TOOL_OUTPUT@\"~\n\t  case $lt_outputfile in\n\t    *.exe|*.EXE) ;;\n\t    *)\n\t      lt_outputfile=\"$lt_outputfile.exe\"\n\t      lt_tool_outputfile=\"$lt_tool_outputfile.exe\"\n\t      ;;\n\t  esac~\n\t  if test \"$MANIFEST_TOOL\" != \":\" && test -f \"$lt_outputfile.manifest\"; then\n\t    $MANIFEST_TOOL -manifest \"$lt_tool_outputfile.manifest\" -outputresource:\"$lt_tool_outputfile\" || exit 1;\n\t    $RM \"$lt_outputfile.manifest\";\n\t  fi'\n\t;;\n      *)\n\t# Assume MSVC wrapper\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '\n\t_LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n\t# Tell ltmain to make .lib files, not .a files.\n\tlibext=lib\n\t# Tell ltmain to make .dll files, not .so files.\n\tshrext_cmds=\".dll\"\n\t# FIXME: Setting linknames here is a bad hack.\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all \"$deplibs\" | $SED '\\''s/ -lc$//'\\''` -link -dll~linknames='\n\t# The linker will automatically build a .lib file if we build a DLL.\n\t_LT_TAGVAR(old_archive_from_new_cmds, $1)='true'\n\t# FIXME: Should let the user specify the lib program.\n\t_LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'\n\t_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes\n\t;;\n      esac\n      ;;\n\n    darwin* | rhapsody*)\n      _LT_DARWIN_LINKER_FEATURES($1)\n      ;;\n\n    dgux*)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor\n    # support.  Future versions do this automatically, but an explicit c++rt0.o\n    # does not break anything, and helps significantly (at the cost of a little\n    # extra space).\n    freebsd2.2*)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    # Unfortunately, older versions of FreeBSD 2 do not have this feature.\n    freebsd2.*)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_minus_L, $1)=yes\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.\n    freebsd* | dragonfly*)\n      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    hpux9*)\n      if test \"$GCC\" = yes; then\n\t_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n      fi\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n\n      # hardcode_minus_L: Not really in the search PATH,\n      # but as the default location of the library.\n      _LT_TAGVAR(hardcode_minus_L, $1)=yes\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n      ;;\n\n    hpux10*)\n      if test \"$GCC\" = yes && test \"$with_gnu_ld\" = no; then\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'\n      fi\n      if test \"$with_gnu_ld\" = no; then\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'\n\t_LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\t_LT_TAGVAR(hardcode_direct, $1)=yes\n\t_LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n\t_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n\t# hardcode_minus_L: Not really in the search PATH,\n\t# but as the default location of the library.\n\t_LT_TAGVAR(hardcode_minus_L, $1)=yes\n      fi\n      ;;\n\n    hpux11*)\n      if test \"$GCC\" = yes && test \"$with_gnu_ld\" = no; then\n\tcase $host_cpu in\n\thppa*64*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tia64*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tesac\n      else\n\tcase $host_cpu in\n\thppa*64*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tia64*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\tm4_if($1, [], [\n\t  # Older versions of the 11.00 compiler do not understand -b yet\n\t  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)\n\t  _LT_LINKER_OPTION([if $CC understands -b],\n\t    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],\n\t    [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],\n\t    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],\n\t  [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])\n\t  ;;\n\tesac\n      fi\n      if test \"$with_gnu_ld\" = no; then\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'\n\t_LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\n\tcase $host_cpu in\n\thppa*64*|ia64*)\n\t  _LT_TAGVAR(hardcode_direct, $1)=no\n\t  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\t  ;;\n\t*)\n\t  _LT_TAGVAR(hardcode_direct, $1)=yes\n\t  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n\t  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n\n\t  # hardcode_minus_L: Not really in the search PATH,\n\t  # but as the default location of the library.\n\t  _LT_TAGVAR(hardcode_minus_L, $1)=yes\n\t  ;;\n\tesac\n      fi\n      ;;\n\n    irix5* | irix6* | nonstopux*)\n      if test \"$GCC\" = yes; then\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t# Try to use the -exported_symbol ld option, if it does not\n\t# work, assume that -exports_file does not work either and\n\t# implicitly export all symbols.\n\t# This should be the same for all languages, so no per-tag cache variable.\n\tAC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],\n\t  [lt_cv_irix_exported_symbol],\n\t  [save_LDFLAGS=\"$LDFLAGS\"\n\t   LDFLAGS=\"$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null\"\n\t   AC_LINK_IFELSE(\n\t     [AC_LANG_SOURCE(\n\t        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],\n\t\t\t      [C++], [[int foo (void) { return 0; }]],\n\t\t\t      [Fortran 77], [[\n      subroutine foo\n      end]],\n\t\t\t      [Fortran], [[\n      subroutine foo\n      end]])])],\n\t      [lt_cv_irix_exported_symbol=yes],\n\t      [lt_cv_irix_exported_symbol=no])\n           LDFLAGS=\"$save_LDFLAGS\"])\n\tif test \"$lt_cv_irix_exported_symbol\" = yes; then\n          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'\n\tfi\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'\n      fi\n      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n      _LT_TAGVAR(inherit_rpath, $1)=yes\n      _LT_TAGVAR(link_all_deplibs, $1)=yes\n      ;;\n\n    netbsd*)\n      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n\t_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF\n      fi\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    newsos6)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    *nto* | *qnx*)\n      ;;\n\n    openbsd*)\n      if test -f /usr/libexec/ld.so; then\n\t_LT_TAGVAR(hardcode_direct, $1)=yes\n\t_LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\t_LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n\tif test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n\telse\n\t  case $host_os in\n\t   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)\n\t     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n\t     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n\t     ;;\n\t   *)\n\t     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'\n\t     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t     ;;\n\t  esac\n\tfi\n      else\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n      fi\n      ;;\n\n    os2*)\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n      _LT_TAGVAR(hardcode_minus_L, $1)=yes\n      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n      _LT_TAGVAR(archive_cmds, $1)='$ECHO \"LIBRARY $libname INITINSTANCE\" > $output_objdir/$libname.def~$ECHO \"DESCRIPTION \\\"$libname\\\"\" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo \" SINGLE NONSHARED\" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'\n      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'\n      ;;\n\n    osf3*)\n      if test \"$GCC\" = yes; then\n\t_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\\*'\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n      else\n\t_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \\*'\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib'\n      fi\n      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n      ;;\n\n    osf4* | osf5*)\t# as osf3* with the addition of -msym flag\n      if test \"$GCC\" = yes; then\n\t_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\\*'\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n      else\n\t_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \\*'\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf \"%s %s\\\\n\" -exported_symbol \"\\$i\" >> $lib.exp; done; printf \"%s\\\\n\" \"-hidden\">> $lib.exp~\n\t$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n \"$verstring\" && $ECHO \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'\n\n\t# Both c and cxx compiler support -rpath directly\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'\n      fi\n      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n      ;;\n\n    solaris*)\n      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'\n      if test \"$GCC\" = yes; then\n\twlarc='${wl}'\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'\n      else\n\tcase `$CC -V 2>&1` in\n\t*\"Compilers 5.0\"*)\n\t  wlarc=''\n\t  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'\n\t  ;;\n\t*)\n\t  wlarc='${wl}'\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'\n\t  ;;\n\tesac\n      fi\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      case $host_os in\n      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;\n      *)\n\t# The compiler driver will combine and reorder linker options,\n\t# but understands `-z linker_flag'.  GCC discards it without `$wl',\n\t# but is careful enough not to reorder.\n\t# Supported since Solaris 2.6 (maybe 2.5.1?)\n\tif test \"$GCC\" = yes; then\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'\n\telse\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'\n\tfi\n\t;;\n      esac\n      _LT_TAGVAR(link_all_deplibs, $1)=yes\n      ;;\n\n    sunos4*)\n      if test \"x$host_vendor\" = xsequent; then\n\t# Use $CC to link under sequent, because it throws in some extra .o\n\t# files that make .init and .fini sections work.\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'\n      fi\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_minus_L, $1)=yes\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    sysv4)\n      case $host_vendor in\n\tsni)\n\t  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???\n\t;;\n\tsiemens)\n\t  ## LD is ld it makes a PLAMLIB\n\t  ## CC just makes a GrossModule.\n\t  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'\n\t  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'\n\t  _LT_TAGVAR(hardcode_direct, $1)=no\n        ;;\n\tmotorola)\n\t  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie\n\t;;\n      esac\n      runpath_var='LD_RUN_PATH'\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    sysv4.3*)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec; then\n\t_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t_LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\trunpath_var=LD_RUN_PATH\n\thardcode_runpath_var=yes\n\t_LT_TAGVAR(ld_shlibs, $1)=yes\n      fi\n      ;;\n\n    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)\n      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'\n      _LT_TAGVAR(archive_cmds_need_lc, $1)=no\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      runpath_var='LD_RUN_PATH'\n\n      if test \"$GCC\" = yes; then\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      fi\n      ;;\n\n    sysv5* | sco3.2v5* | sco5v6*)\n      # Note: We can NOT use -z defs as we might desire, because we do not\n      # link with -lc, and that would cause any symbols used from libc to\n      # always be unresolved, which means just about no library would\n      # ever link correctly.  If we're not using GNU ld we use -z text\n      # though, which does catch some bad symbols but isn't as heavy-handed\n      # as -z defs.\n      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'\n      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'\n      _LT_TAGVAR(archive_cmds_need_lc, $1)=no\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'\n      _LT_TAGVAR(link_all_deplibs, $1)=yes\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'\n      runpath_var='LD_RUN_PATH'\n\n      if test \"$GCC\" = yes; then\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      fi\n      ;;\n\n    uts4*)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    *)\n      _LT_TAGVAR(ld_shlibs, $1)=no\n      ;;\n    esac\n\n    if test x$host_vendor = xsni; then\n      case $host in\n      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)\n\t_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'\n\t;;\n      esac\n    fi\n  fi\n])\nAC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])\ntest \"$_LT_TAGVAR(ld_shlibs, $1)\" = no && can_build_shared=no\n\n_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld\n\n_LT_DECL([], [libext], [0], [Old archive suffix (normally \"a\")])dnl\n_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally \".so\")])dnl\n_LT_DECL([], [extract_expsyms_cmds], [2],\n    [The commands to extract the exported symbol list from a shared archive])\n\n#\n# Do we need to explicitly link libc?\n#\ncase \"x$_LT_TAGVAR(archive_cmds_need_lc, $1)\" in\nx|xyes)\n  # Assume -lc should be added\n  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes\n\n  if test \"$enable_shared\" = yes && test \"$GCC\" = yes; then\n    case $_LT_TAGVAR(archive_cmds, $1) in\n    *'~'*)\n      # FIXME: we may have to deal with multi-command sequences.\n      ;;\n    '$CC '*)\n      # Test whether the compiler implicitly links with -lc since on some\n      # systems, -lgcc has to come before -lc. If gcc already passes -lc\n      # to ld, don't add -lc before -lgcc.\n      AC_CACHE_CHECK([whether -lc should be explicitly linked in],\n\t[lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),\n\t[$RM conftest*\n\techo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n\tif AC_TRY_EVAL(ac_compile) 2>conftest.err; then\n\t  soname=conftest\n\t  lib=conftest\n\t  libobjs=conftest.$ac_objext\n\t  deplibs=\n\t  wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)\n\t  pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)\n\t  compiler_flags=-v\n\t  linker_flags=-v\n\t  verstring=\n\t  output_objdir=.\n\t  libname=conftest\n\t  lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=\n\t  if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\\>\\&1 \\| $GREP \\\" -lc \\\" \\>/dev/null 2\\>\\&1)\n\t  then\n\t    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n\t  else\n\t    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes\n\t  fi\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag\n\telse\n\t  cat conftest.err 1>&5\n\tfi\n\t$RM conftest*\n\t])\n      _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)\n      ;;\n    esac\n  fi\n  ;;\nesac\n\n_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],\n    [Whether or not to add -lc for building shared libraries])\n_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],\n    [enable_shared_with_static_runtimes], [0],\n    [Whether or not to disallow shared libs when runtime libs are static])\n_LT_TAGDECL([], [export_dynamic_flag_spec], [1],\n    [Compiler flag to allow reflexive dlopens])\n_LT_TAGDECL([], [whole_archive_flag_spec], [1],\n    [Compiler flag to generate shared objects directly from archives])\n_LT_TAGDECL([], [compiler_needs_object], [1],\n    [Whether the compiler copes with passing no objects directly])\n_LT_TAGDECL([], [old_archive_from_new_cmds], [2],\n    [Create an old-style archive from a shared archive])\n_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],\n    [Create a temporary old-style archive to link instead of a shared archive])\n_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])\n_LT_TAGDECL([], [archive_expsym_cmds], [2])\n_LT_TAGDECL([], [module_cmds], [2],\n    [Commands used to build a loadable module if different from building\n    a shared archive.])\n_LT_TAGDECL([], [module_expsym_cmds], [2])\n_LT_TAGDECL([], [with_gnu_ld], [1],\n    [Whether we are building with GNU ld or not])\n_LT_TAGDECL([], [allow_undefined_flag], [1],\n    [Flag that allows shared libraries with undefined symbols to be built])\n_LT_TAGDECL([], [no_undefined_flag], [1],\n    [Flag that enforces no undefined symbols])\n_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],\n    [Flag to hardcode $libdir into a binary during linking.\n    This must work even if $libdir does not exist])\n_LT_TAGDECL([], [hardcode_libdir_separator], [1],\n    [Whether we need a single \"-rpath\" flag with a separated argument])\n_LT_TAGDECL([], [hardcode_direct], [0],\n    [Set to \"yes\" if using DIR/libNAME${shared_ext} during linking hardcodes\n    DIR into the resulting binary])\n_LT_TAGDECL([], [hardcode_direct_absolute], [0],\n    [Set to \"yes\" if using DIR/libNAME${shared_ext} during linking hardcodes\n    DIR into the resulting binary and the resulting library dependency is\n    \"absolute\", i.e impossible to change by setting ${shlibpath_var} if the\n    library is relocated])\n_LT_TAGDECL([], [hardcode_minus_L], [0],\n    [Set to \"yes\" if using the -LDIR flag during linking hardcodes DIR\n    into the resulting binary])\n_LT_TAGDECL([], [hardcode_shlibpath_var], [0],\n    [Set to \"yes\" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR\n    into the resulting binary])\n_LT_TAGDECL([], [hardcode_automatic], [0],\n    [Set to \"yes\" if building a shared library automatically hardcodes DIR\n    into the library and all subsequent libraries and executables linked\n    against it])\n_LT_TAGDECL([], [inherit_rpath], [0],\n    [Set to yes if linker adds runtime paths of dependent libraries\n    to runtime path list])\n_LT_TAGDECL([], [link_all_deplibs], [0],\n    [Whether libtool must link a program against all its dependency libraries])\n_LT_TAGDECL([], [always_export_symbols], [0],\n    [Set to \"yes\" if exported symbols are required])\n_LT_TAGDECL([], [export_symbols_cmds], [2],\n    [The commands to list exported symbols])\n_LT_TAGDECL([], [exclude_expsyms], [1],\n    [Symbols that should not be listed in the preloaded symbols])\n_LT_TAGDECL([], [include_expsyms], [1],\n    [Symbols that must always be exported])\n_LT_TAGDECL([], [prelink_cmds], [2],\n    [Commands necessary for linking programs (against libraries) with templates])\n_LT_TAGDECL([], [postlink_cmds], [2],\n    [Commands necessary for finishing linking programs])\n_LT_TAGDECL([], [file_list_spec], [1],\n    [Specify filename containing input files])\ndnl FIXME: Not yet implemented\ndnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],\ndnl    [Compiler flag to generate thread safe objects])\n])# _LT_LINKER_SHLIBS\n\n\n# _LT_LANG_C_CONFIG([TAG])\n# ------------------------\n# Ensure that the configuration variables for a C compiler are suitably\n# defined.  These variables are subsequently used by _LT_CONFIG to write\n# the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_C_CONFIG],\n[m4_require([_LT_DECL_EGREP])dnl\nlt_save_CC=\"$CC\"\nAC_LANG_PUSH(C)\n\n# Source file extension for C test sources.\nac_ext=c\n\n# Object file extension for compiled C test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# Code to be used in simple compile tests\nlt_simple_compile_test_code=\"int some_variable = 0;\"\n\n# Code to be used in simple link tests\nlt_simple_link_test_code='int main(){return(0);}'\n\n_LT_TAG_COMPILER\n# Save the default compiler, since it gets overwritten when the other\n# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.\ncompiler_DEFAULT=$CC\n\n# save warnings/boilerplate of simple test code\n_LT_COMPILER_BOILERPLATE\n_LT_LINKER_BOILERPLATE\n\n## CAVEAT EMPTOR:\n## There is no encapsulation within the following macros, do not change\n## the running order or otherwise move them around unless you know exactly\n## what you are doing...\nif test -n \"$compiler\"; then\n  _LT_COMPILER_NO_RTTI($1)\n  _LT_COMPILER_PIC($1)\n  _LT_COMPILER_C_O($1)\n  _LT_COMPILER_FILE_LOCKS($1)\n  _LT_LINKER_SHLIBS($1)\n  _LT_SYS_DYNAMIC_LINKER($1)\n  _LT_LINKER_HARDCODE_LIBPATH($1)\n  LT_SYS_DLOPEN_SELF\n  _LT_CMD_STRIPLIB\n\n  # Report which library types will actually be built\n  AC_MSG_CHECKING([if libtool supports shared libraries])\n  AC_MSG_RESULT([$can_build_shared])\n\n  AC_MSG_CHECKING([whether to build shared libraries])\n  test \"$can_build_shared\" = \"no\" && enable_shared=no\n\n  # On AIX, shared libraries and static libraries use the same namespace, and\n  # are all built from PIC.\n  case $host_os in\n  aix3*)\n    test \"$enable_shared\" = yes && enable_static=no\n    if test -n \"$RANLIB\"; then\n      archive_cmds=\"$archive_cmds~\\$RANLIB \\$lib\"\n      postinstall_cmds='$RANLIB $lib'\n    fi\n    ;;\n\n  aix[[4-9]]*)\n    if test \"$host_cpu\" != ia64 && test \"$aix_use_runtimelinking\" = no ; then\n      test \"$enable_shared\" = yes && enable_static=no\n    fi\n    ;;\n  esac\n  AC_MSG_RESULT([$enable_shared])\n\n  AC_MSG_CHECKING([whether to build static libraries])\n  # Make sure either enable_shared or enable_static is yes.\n  test \"$enable_shared\" = yes || enable_static=yes\n  AC_MSG_RESULT([$enable_static])\n\n  _LT_CONFIG($1)\nfi\nAC_LANG_POP\nCC=\"$lt_save_CC\"\n])# _LT_LANG_C_CONFIG\n\n\n# _LT_LANG_CXX_CONFIG([TAG])\n# --------------------------\n# Ensure that the configuration variables for a C++ compiler are suitably\n# defined.  These variables are subsequently used by _LT_CONFIG to write\n# the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_CXX_CONFIG],\n[m4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_DECL_EGREP])dnl\nm4_require([_LT_PATH_MANIFEST_TOOL])dnl\nif test -n \"$CXX\" && ( test \"X$CXX\" != \"Xno\" &&\n    ( (test \"X$CXX\" = \"Xg++\" && `g++ -v >/dev/null 2>&1` ) ||\n    (test \"X$CXX\" != \"Xg++\"))) ; then\n  AC_PROG_CXXCPP\nelse\n  _lt_caught_CXX_error=yes\nfi\n\nAC_LANG_PUSH(C++)\n_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n_LT_TAGVAR(allow_undefined_flag, $1)=\n_LT_TAGVAR(always_export_symbols, $1)=no\n_LT_TAGVAR(archive_expsym_cmds, $1)=\n_LT_TAGVAR(compiler_needs_object, $1)=no\n_LT_TAGVAR(export_dynamic_flag_spec, $1)=\n_LT_TAGVAR(hardcode_direct, $1)=no\n_LT_TAGVAR(hardcode_direct_absolute, $1)=no\n_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=\n_LT_TAGVAR(hardcode_libdir_separator, $1)=\n_LT_TAGVAR(hardcode_minus_L, $1)=no\n_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported\n_LT_TAGVAR(hardcode_automatic, $1)=no\n_LT_TAGVAR(inherit_rpath, $1)=no\n_LT_TAGVAR(module_cmds, $1)=\n_LT_TAGVAR(module_expsym_cmds, $1)=\n_LT_TAGVAR(link_all_deplibs, $1)=unknown\n_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds\n_LT_TAGVAR(reload_flag, $1)=$reload_flag\n_LT_TAGVAR(reload_cmds, $1)=$reload_cmds\n_LT_TAGVAR(no_undefined_flag, $1)=\n_LT_TAGVAR(whole_archive_flag_spec, $1)=\n_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no\n\n# Source file extension for C++ test sources.\nac_ext=cpp\n\n# Object file extension for compiled C++ test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# No sense in running all these tests if we already determined that\n# the CXX compiler isn't working.  Some variables (like enable_shared)\n# are currently assumed to apply to all compilers on this platform,\n# and will be corrupted by setting them based on a non-working compiler.\nif test \"$_lt_caught_CXX_error\" != yes; then\n  # Code to be used in simple compile tests\n  lt_simple_compile_test_code=\"int some_variable = 0;\"\n\n  # Code to be used in simple link tests\n  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'\n\n  # ltmain only uses $CC for tagged configurations so make sure $CC is set.\n  _LT_TAG_COMPILER\n\n  # save warnings/boilerplate of simple test code\n  _LT_COMPILER_BOILERPLATE\n  _LT_LINKER_BOILERPLATE\n\n  # Allow CC to be a program name with arguments.\n  lt_save_CC=$CC\n  lt_save_CFLAGS=$CFLAGS\n  lt_save_LD=$LD\n  lt_save_GCC=$GCC\n  GCC=$GXX\n  lt_save_with_gnu_ld=$with_gnu_ld\n  lt_save_path_LD=$lt_cv_path_LD\n  if test -n \"${lt_cv_prog_gnu_ldcxx+set}\"; then\n    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx\n  else\n    $as_unset lt_cv_prog_gnu_ld\n  fi\n  if test -n \"${lt_cv_path_LDCXX+set}\"; then\n    lt_cv_path_LD=$lt_cv_path_LDCXX\n  else\n    $as_unset lt_cv_path_LD\n  fi\n  test -z \"${LDCXX+set}\" || LD=$LDCXX\n  CC=${CXX-\"c++\"}\n  CFLAGS=$CXXFLAGS\n  compiler=$CC\n  _LT_TAGVAR(compiler, $1)=$CC\n  _LT_CC_BASENAME([$compiler])\n\n  if test -n \"$compiler\"; then\n    # We don't want -fno-exception when compiling C++ code, so set the\n    # no_builtin_flag separately\n    if test \"$GXX\" = yes; then\n      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'\n    else\n      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=\n    fi\n\n    if test \"$GXX\" = yes; then\n      # Set up default GNU C++ configuration\n\n      LT_PATH_LD\n\n      # Check if GNU C++ uses GNU ld as the underlying linker, since the\n      # archiving commands below assume that GNU ld is being used.\n      if test \"$with_gnu_ld\" = yes; then\n        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'\n        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\n        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'\n\n        # If archive_cmds runs LD, not CC, wlarc should be empty\n        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to\n        #     investigate it a little bit more. (MM)\n        wlarc='${wl}'\n\n        # ancient GNU ld didn't support --whole-archive et. al.\n        if eval \"`$CC -print-prog-name=ld` --help 2>&1\" |\n\t  $GREP 'no-whole-archive' > /dev/null; then\n          _LT_TAGVAR(whole_archive_flag_spec, $1)=\"$wlarc\"'--whole-archive$convenience '\"$wlarc\"'--no-whole-archive'\n        else\n          _LT_TAGVAR(whole_archive_flag_spec, $1)=\n        fi\n      else\n        with_gnu_ld=no\n        wlarc=\n\n        # A generic and very simple default shared library creation\n        # command for GNU C++ for the case where it uses the native\n        # linker, instead of GNU ld.  If possible, this setting should\n        # overridden to take advantage of the native linker features on\n        # the platform it is being used on.\n        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'\n      fi\n\n      # Commands to make compiler produce verbose output that lists\n      # what \"hidden\" libraries, object files and flags are used when\n      # linking a shared library.\n      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v \"^Configured with:\" | $GREP \"\\-L\"'\n\n    else\n      GXX=no\n      with_gnu_ld=no\n      wlarc=\n    fi\n\n    # PORTME: fill in a description of your system's C++ link characteristics\n    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])\n    _LT_TAGVAR(ld_shlibs, $1)=yes\n    case $host_os in\n      aix3*)\n        # FIXME: insert proper C++ library support\n        _LT_TAGVAR(ld_shlibs, $1)=no\n        ;;\n      aix[[4-9]]*)\n        if test \"$host_cpu\" = ia64; then\n          # On IA64, the linker does run time linking by default, so we don't\n          # have to do anything special.\n          aix_use_runtimelinking=no\n          exp_sym_flag='-Bexport'\n          no_entry_flag=\"\"\n        else\n          aix_use_runtimelinking=no\n\n          # Test if we are trying to use run time linking or normal\n          # AIX style linking. If -brtl is somewhere in LDFLAGS, we\n          # need to do runtime linking.\n          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)\n\t    for ld_flag in $LDFLAGS; do\n\t      case $ld_flag in\n\t      *-brtl*)\n\t        aix_use_runtimelinking=yes\n\t        break\n\t        ;;\n\t      esac\n\t    done\n\t    ;;\n          esac\n\n          exp_sym_flag='-bexport'\n          no_entry_flag='-bnoentry'\n        fi\n\n        # When large executables or shared objects are built, AIX ld can\n        # have problems creating the table of contents.  If linking a library\n        # or program results in \"error TOC overflow\" add -mminimal-toc to\n        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not\n        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.\n\n        _LT_TAGVAR(archive_cmds, $1)=''\n        _LT_TAGVAR(hardcode_direct, $1)=yes\n        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'\n        _LT_TAGVAR(link_all_deplibs, $1)=yes\n        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'\n\n        if test \"$GXX\" = yes; then\n          case $host_os in aix4.[[012]]|aix4.[[012]].*)\n          # We only want to do this on AIX 4.2 and lower, the check\n          # below for broken collect2 doesn't work under 4.3+\n\t  collect2name=`${CC} -print-prog-name=collect2`\n\t  if test -f \"$collect2name\" &&\n\t     strings \"$collect2name\" | $GREP resolve_lib_name >/dev/null\n\t  then\n\t    # We have reworked collect2\n\t    :\n\t  else\n\t    # We have old collect2\n\t    _LT_TAGVAR(hardcode_direct, $1)=unsupported\n\t    # It fails to find uninstalled libraries when the uninstalled\n\t    # path is not listed in the libpath.  Setting hardcode_minus_L\n\t    # to unsupported forces relinking\n\t    _LT_TAGVAR(hardcode_minus_L, $1)=yes\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n\t    _LT_TAGVAR(hardcode_libdir_separator, $1)=\n\t  fi\n          esac\n          shared_flag='-shared'\n\t  if test \"$aix_use_runtimelinking\" = yes; then\n\t    shared_flag=\"$shared_flag \"'${wl}-G'\n\t  fi\n        else\n          # not using gcc\n          if test \"$host_cpu\" = ia64; then\n\t  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release\n\t  # chokes on -Wl,-G. The following line is correct:\n\t  shared_flag='-G'\n          else\n\t    if test \"$aix_use_runtimelinking\" = yes; then\n\t      shared_flag='${wl}-G'\n\t    else\n\t      shared_flag='${wl}-bM:SRE'\n\t    fi\n          fi\n        fi\n\n        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'\n        # It seems that -bexpall does not export symbols beginning with\n        # underscore (_), so it is better to generate a list of symbols to\n\t# export.\n        _LT_TAGVAR(always_export_symbols, $1)=yes\n        if test \"$aix_use_runtimelinking\" = yes; then\n          # Warning - without using the other runtime loading flags (-brtl),\n          # -berok will link without error, but may produce a broken library.\n          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'\n          # Determine the default libpath from the value encoded in an empty\n          # executable.\n          _LT_SYS_MODULE_PATH_AIX([$1])\n          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n\n          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags `if test \"x${allow_undefined_flag}\" != \"x\"; then func_echo_all \"${wl}${allow_undefined_flag}\"; else :; fi` '\"\\${wl}$exp_sym_flag:\\$export_symbols $shared_flag\"\n        else\n          if test \"$host_cpu\" = ia64; then\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'\n\t    _LT_TAGVAR(allow_undefined_flag, $1)=\"-z nodefs\"\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags ${wl}${allow_undefined_flag} '\"\\${wl}$exp_sym_flag:\\$export_symbols\"\n          else\n\t    # Determine the default libpath from the value encoded in an\n\t    # empty executable.\n\t    _LT_SYS_MODULE_PATH_AIX([$1])\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n\t    # Warning - without using the other run time loading flags,\n\t    # -berok will link without error, but may produce a broken library.\n\t    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'\n\t    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'\n\t    if test \"$with_gnu_ld\" = yes; then\n\t      # We only use this code for GNU lds that support --whole-archive.\n\t      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'\n\t    else\n\t      # Exported symbols can be pulled into shared objects from archives\n\t      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'\n\t    fi\n\t    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes\n\t    # This is similar to how AIX traditionally builds its shared\n\t    # libraries.\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'\n          fi\n        fi\n        ;;\n\n      beos*)\n\tif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n\t  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc\n\t  # support --undefined.  This deserves some investigation.  FIXME\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\telse\n\t  _LT_TAGVAR(ld_shlibs, $1)=no\n\tfi\n\t;;\n\n      chorus*)\n        case $cc_basename in\n          *)\n\t  # FIXME: insert proper C++ library support\n\t  _LT_TAGVAR(ld_shlibs, $1)=no\n\t  ;;\n        esac\n        ;;\n\n      cygwin* | mingw* | pw32* | cegcc*)\n\tcase $GXX,$cc_basename in\n\t,cl* | no,cl*)\n\t  # Native MSVC\n\t  # hardcode_libdir_flag_spec is actually meaningless, as there is\n\t  # no search path for DLLs.\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n\t  _LT_TAGVAR(always_export_symbols, $1)=yes\n\t  _LT_TAGVAR(file_list_spec, $1)='@'\n\t  # Tell ltmain to make .lib files, not .a files.\n\t  libext=lib\n\t  # Tell ltmain to make .dll files, not .so files.\n\t  shrext_cmds=\".dll\"\n\t  # FIXME: Setting linknames here is a bad hack.\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t      $SED -n -e 's/\\\\\\\\\\\\\\(.*\\\\\\\\\\\\\\)/-link\\\\\\ -EXPORT:\\\\\\\\\\\\\\1/' -e '1\\\\\\!p' < $export_symbols > $output_objdir/$soname.exp;\n\t    else\n\t      $SED -e 's/\\\\\\\\\\\\\\(.*\\\\\\\\\\\\\\)/-link\\\\\\ -EXPORT:\\\\\\\\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;\n\t    fi~\n\t    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs \"@$tool_output_objdir$soname.exp\" -Wl,-DLL,-IMPLIB:\"$tool_output_objdir$libname.dll.lib\"~\n\t    linknames='\n\t  # The linker will not automatically build a static lib if we build a DLL.\n\t  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'\n\t  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes\n\t  # Don't use ranlib\n\t  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'\n\t  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile=\"@OUTPUT@\"~\n\t    lt_tool_outputfile=\"@TOOL_OUTPUT@\"~\n\t    case $lt_outputfile in\n\t      *.exe|*.EXE) ;;\n\t      *)\n\t\tlt_outputfile=\"$lt_outputfile.exe\"\n\t\tlt_tool_outputfile=\"$lt_tool_outputfile.exe\"\n\t\t;;\n\t    esac~\n\t    func_to_tool_file \"$lt_outputfile\"~\n\t    if test \"$MANIFEST_TOOL\" != \":\" && test -f \"$lt_outputfile.manifest\"; then\n\t      $MANIFEST_TOOL -manifest \"$lt_tool_outputfile.manifest\" -outputresource:\"$lt_tool_outputfile\" || exit 1;\n\t      $RM \"$lt_outputfile.manifest\";\n\t    fi'\n\t  ;;\n\t*)\n\t  # g++\n\t  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,\n\t  # as there is no search path for DLLs.\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n\t  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n\t  _LT_TAGVAR(always_export_symbols, $1)=no\n\t  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes\n\n\t  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n\t    # If the export-symbols file already is a .def file (1st line\n\t    # is EXPORTS), use it as is; otherwise, prepend...\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t      cp $export_symbols $output_objdir/$soname.def;\n\t    else\n\t      echo EXPORTS > $output_objdir/$soname.def;\n\t      cat $export_symbols >> $output_objdir/$soname.def;\n\t    fi~\n\t    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n\t  else\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t  fi\n\t  ;;\n\tesac\n\t;;\n      darwin* | rhapsody*)\n        _LT_DARWIN_LINKER_FEATURES($1)\n\t;;\n\n      dgux*)\n        case $cc_basename in\n          ec++*)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          ghcx*)\n\t    # Green Hills C++ Compiler\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          *)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n        esac\n        ;;\n\n      freebsd2.*)\n        # C++ shared libraries reported to be fairly broken before\n\t# switch to ELF\n        _LT_TAGVAR(ld_shlibs, $1)=no\n        ;;\n\n      freebsd-elf*)\n        _LT_TAGVAR(archive_cmds_need_lc, $1)=no\n        ;;\n\n      freebsd* | dragonfly*)\n        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF\n        # conventions\n        _LT_TAGVAR(ld_shlibs, $1)=yes\n        ;;\n\n      gnu*)\n        ;;\n\n      haiku*)\n        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n        _LT_TAGVAR(link_all_deplibs, $1)=yes\n        ;;\n\n      hpux9*)\n        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'\n        _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n        _LT_TAGVAR(hardcode_direct, $1)=yes\n        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,\n\t\t\t\t             # but as the default\n\t\t\t\t             # location of the library.\n\n        case $cc_basename in\n          CC*)\n            # FIXME: insert proper C++ library support\n            _LT_TAGVAR(ld_shlibs, $1)=no\n            ;;\n          aCC*)\n            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n            # Commands to make compiler produce verbose output that lists\n            # what \"hidden\" libraries, object files and flags are used when\n            # linking a shared library.\n            #\n            # There doesn't appear to be a way to prevent this compiler from\n            # explicitly linking system object files so we need to strip them\n            # from the output so that they don't get included in the library\n            # dependencies.\n            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP \"\\-L\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; func_echo_all \"$list\"'\n            ;;\n          *)\n            if test \"$GXX\" = yes; then\n              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n            else\n              # FIXME: insert proper C++ library support\n              _LT_TAGVAR(ld_shlibs, $1)=no\n            fi\n            ;;\n        esac\n        ;;\n\n      hpux10*|hpux11*)\n        if test $with_gnu_ld = no; then\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'\n\t  _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\n          case $host_cpu in\n            hppa*64*|ia64*)\n              ;;\n            *)\n\t      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n              ;;\n          esac\n        fi\n        case $host_cpu in\n          hppa*64*|ia64*)\n            _LT_TAGVAR(hardcode_direct, $1)=no\n            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n            ;;\n          *)\n            _LT_TAGVAR(hardcode_direct, $1)=yes\n            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,\n\t\t\t\t\t         # but as the default\n\t\t\t\t\t         # location of the library.\n            ;;\n        esac\n\n        case $cc_basename in\n          CC*)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          aCC*)\n\t    case $host_cpu in\n\t      hppa*64*)\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t        ;;\n\t      ia64*)\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t        ;;\n\t      *)\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t        ;;\n\t    esac\n\t    # Commands to make compiler produce verbose output that lists\n\t    # what \"hidden\" libraries, object files and flags are used when\n\t    # linking a shared library.\n\t    #\n\t    # There doesn't appear to be a way to prevent this compiler from\n\t    # explicitly linking system object files so we need to strip them\n\t    # from the output so that they don't get included in the library\n\t    # dependencies.\n\t    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP \"\\-L\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; func_echo_all \"$list\"'\n\t    ;;\n          *)\n\t    if test \"$GXX\" = yes; then\n\t      if test $with_gnu_ld = no; then\n\t        case $host_cpu in\n\t          hppa*64*)\n\t            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t            ;;\n\t          ia64*)\n\t            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t            ;;\n\t          *)\n\t            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t            ;;\n\t        esac\n\t      fi\n\t    else\n\t      # FIXME: insert proper C++ library support\n\t      _LT_TAGVAR(ld_shlibs, $1)=no\n\t    fi\n\t    ;;\n        esac\n        ;;\n\n      interix[[3-9]]*)\n\t_LT_TAGVAR(hardcode_direct, $1)=no\n\t_LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n\t# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.\n\t# Instead, shared libraries are loaded at an image base (0x10000000 by\n\t# default) and relocated if they conflict, which is a slow very memory\n\t# consuming and fragmenting process.  To avoid this, we pick a random,\n\t# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link\n\t# time.  Moving up from 0x10000000 also allows more sbrk(2) space.\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='sed \"s,^,_,\" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n\t;;\n      irix5* | irix6*)\n        case $cc_basename in\n          CC*)\n\t    # SGI C++\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib'\n\n\t    # Archives containing C++ object files must be created using\n\t    # \"CC -ar\", where \"CC\" is the IRIX C++ compiler.  This is\n\t    # necessary to make sure instantiated templates are included\n\t    # in the archive.\n\t    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'\n\t    ;;\n          *)\n\t    if test \"$GXX\" = yes; then\n\t      if test \"$with_gnu_ld\" = no; then\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t      else\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` -o $lib'\n\t      fi\n\t    fi\n\t    _LT_TAGVAR(link_all_deplibs, $1)=yes\n\t    ;;\n        esac\n        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n        _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n        _LT_TAGVAR(inherit_rpath, $1)=yes\n        ;;\n\n      linux* | k*bsd*-gnu | kopensolaris*-gnu)\n        case $cc_basename in\n          KCC*)\n\t    # Kuck and Associates, Inc. (KAI) C++ Compiler\n\n\t    # KCC will only create a shared library if the output file\n\t    # ends with \".so\" (or \".sl\" for HP-UX), so rename the library\n\t    # to its proper name (with version) after linking.\n\t    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\\''s/\\([[^()0-9A-Za-z{}]]\\)/\\\\\\\\\\1/g'\\''`; templib=`echo $lib | $SED -e \"s/\\${tempext}\\..*/.so/\"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \\$templib; mv \\$templib $lib'\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\\''s/\\([[^()0-9A-Za-z{}]]\\)/\\\\\\\\\\1/g'\\''`; templib=`echo $lib | $SED -e \"s/\\${tempext}\\..*/.so/\"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \\$templib ${wl}-retain-symbols-file,$export_symbols; mv \\$templib $lib'\n\t    # Commands to make compiler produce verbose output that lists\n\t    # what \"hidden\" libraries, object files and flags are used when\n\t    # linking a shared library.\n\t    #\n\t    # There doesn't appear to be a way to prevent this compiler from\n\t    # explicitly linking system object files so we need to strip them\n\t    # from the output so that they don't get included in the library\n\t    # dependencies.\n\t    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP \"ld\"`; rm -f libconftest$shared_ext; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; func_echo_all \"$list\"'\n\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'\n\n\t    # Archives containing C++ object files must be created using\n\t    # \"CC -Bstatic\", where \"CC\" is the KAI C++ compiler.\n\t    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'\n\t    ;;\n\t  icpc* | ecpc* )\n\t    # Intel C++\n\t    with_gnu_ld=yes\n\t    # version 8.0 and above of icpc choke on multiply defined symbols\n\t    # if we add $predep_objects and $postdep_objects, however 7.1 and\n\t    # earlier do not add the objects themselves.\n\t    case `$CC -V 2>&1` in\n\t      *\"Version 7.\"*)\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\t\t;;\n\t      *)  # Version 8.0 or newer\n\t        tmp_idyn=\n\t        case $host_cpu in\n\t\t  ia64*) tmp_idyn=' -i_dynamic';;\n\t\tesac\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'\"$tmp_idyn\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'\"$tmp_idyn\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\t\t;;\n\t    esac\n\t    _LT_TAGVAR(archive_cmds_need_lc, $1)=no\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'\n\t    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'\n\t    ;;\n          pgCC* | pgcpp*)\n            # Portland Group C++ compiler\n\t    case `$CC -V` in\n\t    *pgCC\\ [[1-5]].* | *pgcpp\\ [[1-5]].*)\n\t      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~\n\t\trm -rf $tpldir~\n\t\t$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~\n\t\tcompile_command=\"$compile_command `find $tpldir -name \\*.o | sort | $NL2SP`\"'\n\t      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~\n\t\trm -rf $tpldir~\n\t\t$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~\n\t\t$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \\*.o | sort | $NL2SP`~\n\t\t$RANLIB $oldlib'\n\t      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~\n\t\trm -rf $tpldir~\n\t\t$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~\n\t\t$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \\*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'\n\t      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~\n\t\trm -rf $tpldir~\n\t\t$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~\n\t\t$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \\*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'\n\t      ;;\n\t    *) # Version 6 and above use weak symbols\n\t      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'\n\t      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'\n\t      ;;\n\t    esac\n\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'\n\t    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'\n\t    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n            ;;\n\t  cxx*)\n\t    # Compaq C++\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'\n\n\t    runpath_var=LD_RUN_PATH\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'\n\t    _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\n\t    # Commands to make compiler produce verbose output that lists\n\t    # what \"hidden\" libraries, object files and flags are used when\n\t    # linking a shared library.\n\t    #\n\t    # There doesn't appear to be a way to prevent this compiler from\n\t    # explicitly linking system object files so we need to strip them\n\t    # from the output so that they don't get included in the library\n\t    # dependencies.\n\t    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP \"ld\"`; templist=`func_echo_all \"$templist\" | $SED \"s/\\(^.*ld.*\\)\\( .*ld .*$\\)/\\1/\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; func_echo_all \"X$list\" | $Xsed'\n\t    ;;\n\t  xl* | mpixl* | bgxl*)\n\t    # IBM XL 8.0 on PPC, with GNU ld\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n\t    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t    if test \"x$supports_anon_versioning\" = xyes; then\n\t      _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $output_objdir/$libname.ver~\n\t\tcat $export_symbols | sed -e \"s/\\(.*\\)/\\1;/\" >> $output_objdir/$libname.ver~\n\t\techo \"local: *; };\" >> $output_objdir/$libname.ver~\n\t\t$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'\n\t    fi\n\t    ;;\n\t  *)\n\t    case `$CC -V 2>&1 | sed 5q` in\n\t    *Sun\\ C*)\n\t      # Sun C++ 5.9\n\t      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'\n\t      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'\n\t      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n\t      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\\\"\\\"; do test -z \\\"$conv\\\" || new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t      _LT_TAGVAR(compiler_needs_object, $1)=yes\n\n\t      # Not sure whether something based on\n\t      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1\n\t      # would be better.\n\t      output_verbose_link_cmd='func_echo_all'\n\n\t      # Archives containing C++ object files must be created using\n\t      # \"CC -xar\", where \"CC\" is the Sun C++ compiler.  This is\n\t      # necessary to make sure instantiated templates are included\n\t      # in the archive.\n\t      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'\n\t      ;;\n\t    esac\n\t    ;;\n\tesac\n\t;;\n\n      lynxos*)\n        # FIXME: insert proper C++ library support\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n\t;;\n\n      m88k*)\n        # FIXME: insert proper C++ library support\n        _LT_TAGVAR(ld_shlibs, $1)=no\n\t;;\n\n      mvs*)\n        case $cc_basename in\n          cxx*)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n\t  *)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n\tesac\n\t;;\n\n      netbsd*)\n        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n\t  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'\n\t  wlarc=\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n\t  _LT_TAGVAR(hardcode_direct, $1)=yes\n\t  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\tfi\n\t# Workaround some broken pre-1.5 toolchains\n\toutput_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e \"s:-lgcc -lc -lgcc::\"'\n\t;;\n\n      *nto* | *qnx*)\n        _LT_TAGVAR(ld_shlibs, $1)=yes\n\t;;\n\n      openbsd2*)\n        # C++ shared libraries are fairly broken\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n\t;;\n\n      openbsd*)\n\tif test -f /usr/libexec/ld.so; then\n\t  _LT_TAGVAR(hardcode_direct, $1)=yes\n\t  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\t  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t  if test -z \"`echo __ELF__ | $CC -E - | grep __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'\n\t    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n\t    _LT_TAGVAR(whole_archive_flag_spec, $1)=\"$wlarc\"'--whole-archive$convenience '\"$wlarc\"'--no-whole-archive'\n\t  fi\n\t  output_verbose_link_cmd=func_echo_all\n\telse\n\t  _LT_TAGVAR(ld_shlibs, $1)=no\n\tfi\n\t;;\n\n      osf3* | osf4* | osf5*)\n        case $cc_basename in\n          KCC*)\n\t    # Kuck and Associates, Inc. (KAI) C++ Compiler\n\n\t    # KCC will only create a shared library if the output file\n\t    # ends with \".so\" (or \".sl\" for HP-UX), so rename the library\n\t    # to its proper name (with version) after linking.\n\t    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\\''s/\\([[^()0-9A-Za-z{}]]\\)/\\\\\\\\\\1/g'\\''`; templib=`echo \"$lib\" | $SED -e \"s/\\${tempext}\\..*/.so/\"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \\$templib; mv \\$templib $lib'\n\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t    _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\n\t    # Archives containing C++ object files must be created using\n\t    # the KAI C++ compiler.\n\t    case $host in\n\t      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;\n\t      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;\n\t    esac\n\t    ;;\n          RCC*)\n\t    # Rational C++ 2.4.1\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          cxx*)\n\t    case $host in\n\t      osf3*)\n\t        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\\*'\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib'\n\t        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n\t\t;;\n\t      *)\n\t        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \\*'\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib'\n\t        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf \"%s %s\\\\n\" -exported_symbol \"\\$i\" >> $lib.exp; done~\n\t          echo \"-hidden\">> $lib.exp~\n\t          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n \"$verstring\" && $ECHO \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib~\n\t          $RM $lib.exp'\n\t        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'\n\t\t;;\n\t    esac\n\n\t    _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\n\t    # Commands to make compiler produce verbose output that lists\n\t    # what \"hidden\" libraries, object files and flags are used when\n\t    # linking a shared library.\n\t    #\n\t    # There doesn't appear to be a way to prevent this compiler from\n\t    # explicitly linking system object files so we need to strip them\n\t    # from the output so that they don't get included in the library\n\t    # dependencies.\n\t    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP \"ld\" | $GREP -v \"ld:\"`; templist=`func_echo_all \"$templist\" | $SED \"s/\\(^.*ld.*\\)\\( .*ld.*$\\)/\\1/\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; func_echo_all \"$list\"'\n\t    ;;\n\t  *)\n\t    if test \"$GXX\" = yes && test \"$with_gnu_ld\" = no; then\n\t      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\\*'\n\t      case $host in\n\t        osf3*)\n\t          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t\t  ;;\n\t        *)\n\t          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t\t  ;;\n\t      esac\n\n\t      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n\t      _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\n\t      # Commands to make compiler produce verbose output that lists\n\t      # what \"hidden\" libraries, object files and flags are used when\n\t      # linking a shared library.\n\t      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v \"^Configured with:\" | $GREP \"\\-L\"'\n\n\t    else\n\t      # FIXME: insert proper C++ library support\n\t      _LT_TAGVAR(ld_shlibs, $1)=no\n\t    fi\n\t    ;;\n        esac\n        ;;\n\n      psos*)\n        # FIXME: insert proper C++ library support\n        _LT_TAGVAR(ld_shlibs, $1)=no\n        ;;\n\n      sunos4*)\n        case $cc_basename in\n          CC*)\n\t    # Sun C++ 4.x\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          lcc*)\n\t    # Lucid\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          *)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n        esac\n        ;;\n\n      solaris*)\n        case $cc_basename in\n          CC* | sunCC*)\n\t    # Sun C++ 4.2, 5.x and Centerline C++\n            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes\n\t    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'\n\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n\t    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\t    case $host_os in\n\t      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;\n\t      *)\n\t\t# The compiler driver will combine and reorder linker options,\n\t\t# but understands `-z linker_flag'.\n\t        # Supported since Solaris 2.6 (maybe 2.5.1?)\n\t\t_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'\n\t        ;;\n\t    esac\n\t    _LT_TAGVAR(link_all_deplibs, $1)=yes\n\n\t    output_verbose_link_cmd='func_echo_all'\n\n\t    # Archives containing C++ object files must be created using\n\t    # \"CC -xar\", where \"CC\" is the Sun C++ compiler.  This is\n\t    # necessary to make sure instantiated templates are included\n\t    # in the archive.\n\t    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'\n\t    ;;\n          gcx*)\n\t    # Green Hills C++ Compiler\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'\n\n\t    # The C++ compiler must be used to create the archive.\n\t    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'\n\t    ;;\n          *)\n\t    # GNU C++ compiler with Solaris linker\n\t    if test \"$GXX\" = yes && test \"$with_gnu_ld\" = no; then\n\t      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'\n\t      if $CC --version | $GREP -v '^2\\.7' > /dev/null; then\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'\n\t        _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t\t  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'\n\n\t        # Commands to make compiler produce verbose output that lists\n\t        # what \"hidden\" libraries, object files and flags are used when\n\t        # linking a shared library.\n\t        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v \"^Configured with:\" | $GREP \"\\-L\"'\n\t      else\n\t        # g++ 2.7 appears to require `-G' NOT `-shared' on this\n\t        # platform.\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'\n\t        _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t\t  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'\n\n\t        # Commands to make compiler produce verbose output that lists\n\t        # what \"hidden\" libraries, object files and flags are used when\n\t        # linking a shared library.\n\t        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v \"^Configured with:\" | $GREP \"\\-L\"'\n\t      fi\n\n\t      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'\n\t      case $host_os in\n\t\tsolaris2.[[0-5]] | solaris2.[[0-5]].*) ;;\n\t\t*)\n\t\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'\n\t\t  ;;\n\t      esac\n\t    fi\n\t    ;;\n        esac\n        ;;\n\n    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)\n      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'\n      _LT_TAGVAR(archive_cmds_need_lc, $1)=no\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      runpath_var='LD_RUN_PATH'\n\n      case $cc_basename in\n        CC*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n      esac\n      ;;\n\n      sysv5* | sco3.2v5* | sco5v6*)\n\t# Note: We can NOT use -z defs as we might desire, because we do not\n\t# link with -lc, and that would cause any symbols used from libc to\n\t# always be unresolved, which means just about no library would\n\t# ever link correctly.  If we're not using GNU ld we use -z text\n\t# though, which does catch some bad symbols but isn't as heavy-handed\n\t# as -z defs.\n\t_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'\n\t_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'\n\t_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n\t_LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'\n\t_LT_TAGVAR(hardcode_libdir_separator, $1)=':'\n\t_LT_TAGVAR(link_all_deplibs, $1)=yes\n\t_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'\n\trunpath_var='LD_RUN_PATH'\n\n\tcase $cc_basename in\n          CC*)\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~\n\t      '\"$_LT_TAGVAR(old_archive_cmds, $1)\"\n\t    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~\n\t      '\"$_LT_TAGVAR(reload_cmds, $1)\"\n\t    ;;\n\t  *)\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t    ;;\n\tesac\n      ;;\n\n      tandem*)\n        case $cc_basename in\n          NCC*)\n\t    # NonStop-UX NCC 3.20\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          *)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n        esac\n        ;;\n\n      vxworks*)\n        # FIXME: insert proper C++ library support\n        _LT_TAGVAR(ld_shlibs, $1)=no\n        ;;\n\n      *)\n        # FIXME: insert proper C++ library support\n        _LT_TAGVAR(ld_shlibs, $1)=no\n        ;;\n    esac\n\n    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])\n    test \"$_LT_TAGVAR(ld_shlibs, $1)\" = no && can_build_shared=no\n\n    _LT_TAGVAR(GCC, $1)=\"$GXX\"\n    _LT_TAGVAR(LD, $1)=\"$LD\"\n\n    ## CAVEAT EMPTOR:\n    ## There is no encapsulation within the following macros, do not change\n    ## the running order or otherwise move them around unless you know exactly\n    ## what you are doing...\n    _LT_SYS_HIDDEN_LIBDEPS($1)\n    _LT_COMPILER_PIC($1)\n    _LT_COMPILER_C_O($1)\n    _LT_COMPILER_FILE_LOCKS($1)\n    _LT_LINKER_SHLIBS($1)\n    _LT_SYS_DYNAMIC_LINKER($1)\n    _LT_LINKER_HARDCODE_LIBPATH($1)\n\n    _LT_CONFIG($1)\n  fi # test -n \"$compiler\"\n\n  CC=$lt_save_CC\n  CFLAGS=$lt_save_CFLAGS\n  LDCXX=$LD\n  LD=$lt_save_LD\n  GCC=$lt_save_GCC\n  with_gnu_ld=$lt_save_with_gnu_ld\n  lt_cv_path_LDCXX=$lt_cv_path_LD\n  lt_cv_path_LD=$lt_save_path_LD\n  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld\n  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld\nfi # test \"$_lt_caught_CXX_error\" != yes\n\nAC_LANG_POP\n])# _LT_LANG_CXX_CONFIG\n\n\n# _LT_FUNC_STRIPNAME_CNF\n# ----------------------\n# func_stripname_cnf prefix suffix name\n# strip PREFIX and SUFFIX off of NAME.\n# PREFIX and SUFFIX must not contain globbing or regex special\n# characters, hashes, percent signs, but SUFFIX may contain a leading\n# dot (in which case that matches only a dot).\n#\n# This function is identical to the (non-XSI) version of func_stripname,\n# except this one can be used by m4 code that may be executed by configure,\n# rather than the libtool script.\nm4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl\nAC_REQUIRE([_LT_DECL_SED])\nAC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])\nfunc_stripname_cnf ()\n{\n  case ${2} in\n  .*) func_stripname_result=`$ECHO \"${3}\" | $SED \"s%^${1}%%; s%\\\\\\\\${2}\\$%%\"`;;\n  *)  func_stripname_result=`$ECHO \"${3}\" | $SED \"s%^${1}%%; s%${2}\\$%%\"`;;\n  esac\n} # func_stripname_cnf\n])# _LT_FUNC_STRIPNAME_CNF\n\n# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])\n# ---------------------------------\n# Figure out \"hidden\" library dependencies from verbose\n# compiler output when linking a shared library.\n# Parse the compiler output and extract the necessary\n# objects, libraries and library flags.\nm4_defun([_LT_SYS_HIDDEN_LIBDEPS],\n[m4_require([_LT_FILEUTILS_DEFAULTS])dnl\nAC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl\n# Dependencies to place before and after the object being linked:\n_LT_TAGVAR(predep_objects, $1)=\n_LT_TAGVAR(postdep_objects, $1)=\n_LT_TAGVAR(predeps, $1)=\n_LT_TAGVAR(postdeps, $1)=\n_LT_TAGVAR(compiler_lib_search_path, $1)=\n\ndnl we can't use the lt_simple_compile_test_code here,\ndnl because it contains code intended for an executable,\ndnl not a library.  It's possible we should let each\ndnl tag define a new lt_????_link_test_code variable,\ndnl but it's only used here...\nm4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF\nint a;\nvoid foo (void) { a = 0; }\n_LT_EOF\n], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF\nclass Foo\n{\npublic:\n  Foo (void) { a = 0; }\nprivate:\n  int a;\n};\n_LT_EOF\n], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF\n      subroutine foo\n      implicit none\n      integer*4 a\n      a=0\n      return\n      end\n_LT_EOF\n], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF\n      subroutine foo\n      implicit none\n      integer a\n      a=0\n      return\n      end\n_LT_EOF\n], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF\npublic class foo {\n  private int a;\n  public void bar (void) {\n    a = 0;\n  }\n};\n_LT_EOF\n], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF\npackage foo\nfunc foo() {\n}\n_LT_EOF\n])\n\n_lt_libdeps_save_CFLAGS=$CFLAGS\ncase \"$CC $CFLAGS \" in #(\n*\\ -flto*\\ *) CFLAGS=\"$CFLAGS -fno-lto\" ;;\n*\\ -fwhopr*\\ *) CFLAGS=\"$CFLAGS -fno-whopr\" ;;\n*\\ -fuse-linker-plugin*\\ *) CFLAGS=\"$CFLAGS -fno-use-linker-plugin\" ;;\nesac\n\ndnl Parse the compiler output and extract the necessary\ndnl objects, libraries and library flags.\nif AC_TRY_EVAL(ac_compile); then\n  # Parse the compiler output and extract the necessary\n  # objects, libraries and library flags.\n\n  # Sentinel used to keep track of whether or not we are before\n  # the conftest object file.\n  pre_test_object_deps_done=no\n\n  for p in `eval \"$output_verbose_link_cmd\"`; do\n    case ${prev}${p} in\n\n    -L* | -R* | -l*)\n       # Some compilers place space between \"-{L,R}\" and the path.\n       # Remove the space.\n       if test $p = \"-L\" ||\n          test $p = \"-R\"; then\n\t prev=$p\n\t continue\n       fi\n\n       # Expand the sysroot to ease extracting the directories later.\n       if test -z \"$prev\"; then\n         case $p in\n         -L*) func_stripname_cnf '-L' '' \"$p\"; prev=-L; p=$func_stripname_result ;;\n         -R*) func_stripname_cnf '-R' '' \"$p\"; prev=-R; p=$func_stripname_result ;;\n         -l*) func_stripname_cnf '-l' '' \"$p\"; prev=-l; p=$func_stripname_result ;;\n         esac\n       fi\n       case $p in\n       =*) func_stripname_cnf '=' '' \"$p\"; p=$lt_sysroot$func_stripname_result ;;\n       esac\n       if test \"$pre_test_object_deps_done\" = no; then\n\t case ${prev} in\n\t -L | -R)\n\t   # Internal compiler library paths should come after those\n\t   # provided the user.  The postdeps already come after the\n\t   # user supplied libs so there is no need to process them.\n\t   if test -z \"$_LT_TAGVAR(compiler_lib_search_path, $1)\"; then\n\t     _LT_TAGVAR(compiler_lib_search_path, $1)=\"${prev}${p}\"\n\t   else\n\t     _LT_TAGVAR(compiler_lib_search_path, $1)=\"${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}\"\n\t   fi\n\t   ;;\n\t # The \"-l\" case would never come before the object being\n\t # linked, so don't bother handling this case.\n\t esac\n       else\n\t if test -z \"$_LT_TAGVAR(postdeps, $1)\"; then\n\t   _LT_TAGVAR(postdeps, $1)=\"${prev}${p}\"\n\t else\n\t   _LT_TAGVAR(postdeps, $1)=\"${_LT_TAGVAR(postdeps, $1)} ${prev}${p}\"\n\t fi\n       fi\n       prev=\n       ;;\n\n    *.lto.$objext) ;; # Ignore GCC LTO objects\n    *.$objext)\n       # This assumes that the test object file only shows up\n       # once in the compiler output.\n       if test \"$p\" = \"conftest.$objext\"; then\n\t pre_test_object_deps_done=yes\n\t continue\n       fi\n\n       if test \"$pre_test_object_deps_done\" = no; then\n\t if test -z \"$_LT_TAGVAR(predep_objects, $1)\"; then\n\t   _LT_TAGVAR(predep_objects, $1)=\"$p\"\n\t else\n\t   _LT_TAGVAR(predep_objects, $1)=\"$_LT_TAGVAR(predep_objects, $1) $p\"\n\t fi\n       else\n\t if test -z \"$_LT_TAGVAR(postdep_objects, $1)\"; then\n\t   _LT_TAGVAR(postdep_objects, $1)=\"$p\"\n\t else\n\t   _LT_TAGVAR(postdep_objects, $1)=\"$_LT_TAGVAR(postdep_objects, $1) $p\"\n\t fi\n       fi\n       ;;\n\n    *) ;; # Ignore the rest.\n\n    esac\n  done\n\n  # Clean up.\n  rm -f a.out a.exe\nelse\n  echo \"libtool.m4: error: problem compiling $1 test program\"\nfi\n\n$RM -f confest.$objext\nCFLAGS=$_lt_libdeps_save_CFLAGS\n\n# PORTME: override above test on systems where it is broken\nm4_if([$1], [CXX],\n[case $host_os in\ninterix[[3-9]]*)\n  # Interix 3.5 installs completely hosed .la files for C++, so rather than\n  # hack all around it, let's just trust \"g++\" to DTRT.\n  _LT_TAGVAR(predep_objects,$1)=\n  _LT_TAGVAR(postdep_objects,$1)=\n  _LT_TAGVAR(postdeps,$1)=\n  ;;\n\nlinux*)\n  case `$CC -V 2>&1 | sed 5q` in\n  *Sun\\ C*)\n    # Sun C++ 5.9\n\n    # The more standards-conforming stlport4 library is\n    # incompatible with the Cstd library. Avoid specifying\n    # it if it's in CXXFLAGS. Ignore libCrun as\n    # -library=stlport4 depends on it.\n    case \" $CXX $CXXFLAGS \" in\n    *\" -library=stlport4 \"*)\n      solaris_use_stlport4=yes\n      ;;\n    esac\n\n    if test \"$solaris_use_stlport4\" != yes; then\n      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'\n    fi\n    ;;\n  esac\n  ;;\n\nsolaris*)\n  case $cc_basename in\n  CC* | sunCC*)\n    # The more standards-conforming stlport4 library is\n    # incompatible with the Cstd library. Avoid specifying\n    # it if it's in CXXFLAGS. Ignore libCrun as\n    # -library=stlport4 depends on it.\n    case \" $CXX $CXXFLAGS \" in\n    *\" -library=stlport4 \"*)\n      solaris_use_stlport4=yes\n      ;;\n    esac\n\n    # Adding this requires a known-good setup of shared libraries for\n    # Sun compiler versions before 5.6, else PIC objects from an old\n    # archive will be linked into the output, leading to subtle bugs.\n    if test \"$solaris_use_stlport4\" != yes; then\n      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'\n    fi\n    ;;\n  esac\n  ;;\nesac\n])\n\ncase \" $_LT_TAGVAR(postdeps, $1) \" in\n*\" -lc \"*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;\nesac\n _LT_TAGVAR(compiler_lib_search_dirs, $1)=\nif test -n \"${_LT_TAGVAR(compiler_lib_search_path, $1)}\"; then\n _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo \" ${_LT_TAGVAR(compiler_lib_search_path, $1)}\" | ${SED} -e 's! -L! !g' -e 's!^ !!'`\nfi\n_LT_TAGDECL([], [compiler_lib_search_dirs], [1],\n    [The directories searched by this compiler when creating a shared library])\n_LT_TAGDECL([], [predep_objects], [1],\n    [Dependencies to place before and after the objects being linked to\n    create a shared library])\n_LT_TAGDECL([], [postdep_objects], [1])\n_LT_TAGDECL([], [predeps], [1])\n_LT_TAGDECL([], [postdeps], [1])\n_LT_TAGDECL([], [compiler_lib_search_path], [1],\n    [The library search path used internally by the compiler when linking\n    a shared library])\n])# _LT_SYS_HIDDEN_LIBDEPS\n\n\n# _LT_LANG_F77_CONFIG([TAG])\n# --------------------------\n# Ensure that the configuration variables for a Fortran 77 compiler are\n# suitably defined.  These variables are subsequently used by _LT_CONFIG\n# to write the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_F77_CONFIG],\n[AC_LANG_PUSH(Fortran 77)\nif test -z \"$F77\" || test \"X$F77\" = \"Xno\"; then\n  _lt_disable_F77=yes\nfi\n\n_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n_LT_TAGVAR(allow_undefined_flag, $1)=\n_LT_TAGVAR(always_export_symbols, $1)=no\n_LT_TAGVAR(archive_expsym_cmds, $1)=\n_LT_TAGVAR(export_dynamic_flag_spec, $1)=\n_LT_TAGVAR(hardcode_direct, $1)=no\n_LT_TAGVAR(hardcode_direct_absolute, $1)=no\n_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=\n_LT_TAGVAR(hardcode_libdir_separator, $1)=\n_LT_TAGVAR(hardcode_minus_L, $1)=no\n_LT_TAGVAR(hardcode_automatic, $1)=no\n_LT_TAGVAR(inherit_rpath, $1)=no\n_LT_TAGVAR(module_cmds, $1)=\n_LT_TAGVAR(module_expsym_cmds, $1)=\n_LT_TAGVAR(link_all_deplibs, $1)=unknown\n_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds\n_LT_TAGVAR(reload_flag, $1)=$reload_flag\n_LT_TAGVAR(reload_cmds, $1)=$reload_cmds\n_LT_TAGVAR(no_undefined_flag, $1)=\n_LT_TAGVAR(whole_archive_flag_spec, $1)=\n_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no\n\n# Source file extension for f77 test sources.\nac_ext=f\n\n# Object file extension for compiled f77 test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# No sense in running all these tests if we already determined that\n# the F77 compiler isn't working.  Some variables (like enable_shared)\n# are currently assumed to apply to all compilers on this platform,\n# and will be corrupted by setting them based on a non-working compiler.\nif test \"$_lt_disable_F77\" != yes; then\n  # Code to be used in simple compile tests\n  lt_simple_compile_test_code=\"\\\n      subroutine t\n      return\n      end\n\"\n\n  # Code to be used in simple link tests\n  lt_simple_link_test_code=\"\\\n      program t\n      end\n\"\n\n  # ltmain only uses $CC for tagged configurations so make sure $CC is set.\n  _LT_TAG_COMPILER\n\n  # save warnings/boilerplate of simple test code\n  _LT_COMPILER_BOILERPLATE\n  _LT_LINKER_BOILERPLATE\n\n  # Allow CC to be a program name with arguments.\n  lt_save_CC=\"$CC\"\n  lt_save_GCC=$GCC\n  lt_save_CFLAGS=$CFLAGS\n  CC=${F77-\"f77\"}\n  CFLAGS=$FFLAGS\n  compiler=$CC\n  _LT_TAGVAR(compiler, $1)=$CC\n  _LT_CC_BASENAME([$compiler])\n  GCC=$G77\n  if test -n \"$compiler\"; then\n    AC_MSG_CHECKING([if libtool supports shared libraries])\n    AC_MSG_RESULT([$can_build_shared])\n\n    AC_MSG_CHECKING([whether to build shared libraries])\n    test \"$can_build_shared\" = \"no\" && enable_shared=no\n\n    # On AIX, shared libraries and static libraries use the same namespace, and\n    # are all built from PIC.\n    case $host_os in\n      aix3*)\n        test \"$enable_shared\" = yes && enable_static=no\n        if test -n \"$RANLIB\"; then\n          archive_cmds=\"$archive_cmds~\\$RANLIB \\$lib\"\n          postinstall_cmds='$RANLIB $lib'\n        fi\n        ;;\n      aix[[4-9]]*)\n\tif test \"$host_cpu\" != ia64 && test \"$aix_use_runtimelinking\" = no ; then\n\t  test \"$enable_shared\" = yes && enable_static=no\n\tfi\n        ;;\n    esac\n    AC_MSG_RESULT([$enable_shared])\n\n    AC_MSG_CHECKING([whether to build static libraries])\n    # Make sure either enable_shared or enable_static is yes.\n    test \"$enable_shared\" = yes || enable_static=yes\n    AC_MSG_RESULT([$enable_static])\n\n    _LT_TAGVAR(GCC, $1)=\"$G77\"\n    _LT_TAGVAR(LD, $1)=\"$LD\"\n\n    ## CAVEAT EMPTOR:\n    ## There is no encapsulation within the following macros, do not change\n    ## the running order or otherwise move them around unless you know exactly\n    ## what you are doing...\n    _LT_COMPILER_PIC($1)\n    _LT_COMPILER_C_O($1)\n    _LT_COMPILER_FILE_LOCKS($1)\n    _LT_LINKER_SHLIBS($1)\n    _LT_SYS_DYNAMIC_LINKER($1)\n    _LT_LINKER_HARDCODE_LIBPATH($1)\n\n    _LT_CONFIG($1)\n  fi # test -n \"$compiler\"\n\n  GCC=$lt_save_GCC\n  CC=\"$lt_save_CC\"\n  CFLAGS=\"$lt_save_CFLAGS\"\nfi # test \"$_lt_disable_F77\" != yes\n\nAC_LANG_POP\n])# _LT_LANG_F77_CONFIG\n\n\n# _LT_LANG_FC_CONFIG([TAG])\n# -------------------------\n# Ensure that the configuration variables for a Fortran compiler are\n# suitably defined.  These variables are subsequently used by _LT_CONFIG\n# to write the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_FC_CONFIG],\n[AC_LANG_PUSH(Fortran)\n\nif test -z \"$FC\" || test \"X$FC\" = \"Xno\"; then\n  _lt_disable_FC=yes\nfi\n\n_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n_LT_TAGVAR(allow_undefined_flag, $1)=\n_LT_TAGVAR(always_export_symbols, $1)=no\n_LT_TAGVAR(archive_expsym_cmds, $1)=\n_LT_TAGVAR(export_dynamic_flag_spec, $1)=\n_LT_TAGVAR(hardcode_direct, $1)=no\n_LT_TAGVAR(hardcode_direct_absolute, $1)=no\n_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=\n_LT_TAGVAR(hardcode_libdir_separator, $1)=\n_LT_TAGVAR(hardcode_minus_L, $1)=no\n_LT_TAGVAR(hardcode_automatic, $1)=no\n_LT_TAGVAR(inherit_rpath, $1)=no\n_LT_TAGVAR(module_cmds, $1)=\n_LT_TAGVAR(module_expsym_cmds, $1)=\n_LT_TAGVAR(link_all_deplibs, $1)=unknown\n_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds\n_LT_TAGVAR(reload_flag, $1)=$reload_flag\n_LT_TAGVAR(reload_cmds, $1)=$reload_cmds\n_LT_TAGVAR(no_undefined_flag, $1)=\n_LT_TAGVAR(whole_archive_flag_spec, $1)=\n_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no\n\n# Source file extension for fc test sources.\nac_ext=${ac_fc_srcext-f}\n\n# Object file extension for compiled fc test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# No sense in running all these tests if we already determined that\n# the FC compiler isn't working.  Some variables (like enable_shared)\n# are currently assumed to apply to all compilers on this platform,\n# and will be corrupted by setting them based on a non-working compiler.\nif test \"$_lt_disable_FC\" != yes; then\n  # Code to be used in simple compile tests\n  lt_simple_compile_test_code=\"\\\n      subroutine t\n      return\n      end\n\"\n\n  # Code to be used in simple link tests\n  lt_simple_link_test_code=\"\\\n      program t\n      end\n\"\n\n  # ltmain only uses $CC for tagged configurations so make sure $CC is set.\n  _LT_TAG_COMPILER\n\n  # save warnings/boilerplate of simple test code\n  _LT_COMPILER_BOILERPLATE\n  _LT_LINKER_BOILERPLATE\n\n  # Allow CC to be a program name with arguments.\n  lt_save_CC=\"$CC\"\n  lt_save_GCC=$GCC\n  lt_save_CFLAGS=$CFLAGS\n  CC=${FC-\"f95\"}\n  CFLAGS=$FCFLAGS\n  compiler=$CC\n  GCC=$ac_cv_fc_compiler_gnu\n\n  _LT_TAGVAR(compiler, $1)=$CC\n  _LT_CC_BASENAME([$compiler])\n\n  if test -n \"$compiler\"; then\n    AC_MSG_CHECKING([if libtool supports shared libraries])\n    AC_MSG_RESULT([$can_build_shared])\n\n    AC_MSG_CHECKING([whether to build shared libraries])\n    test \"$can_build_shared\" = \"no\" && enable_shared=no\n\n    # On AIX, shared libraries and static libraries use the same namespace, and\n    # are all built from PIC.\n    case $host_os in\n      aix3*)\n        test \"$enable_shared\" = yes && enable_static=no\n        if test -n \"$RANLIB\"; then\n          archive_cmds=\"$archive_cmds~\\$RANLIB \\$lib\"\n          postinstall_cmds='$RANLIB $lib'\n        fi\n        ;;\n      aix[[4-9]]*)\n\tif test \"$host_cpu\" != ia64 && test \"$aix_use_runtimelinking\" = no ; then\n\t  test \"$enable_shared\" = yes && enable_static=no\n\tfi\n        ;;\n    esac\n    AC_MSG_RESULT([$enable_shared])\n\n    AC_MSG_CHECKING([whether to build static libraries])\n    # Make sure either enable_shared or enable_static is yes.\n    test \"$enable_shared\" = yes || enable_static=yes\n    AC_MSG_RESULT([$enable_static])\n\n    _LT_TAGVAR(GCC, $1)=\"$ac_cv_fc_compiler_gnu\"\n    _LT_TAGVAR(LD, $1)=\"$LD\"\n\n    ## CAVEAT EMPTOR:\n    ## There is no encapsulation within the following macros, do not change\n    ## the running order or otherwise move them around unless you know exactly\n    ## what you are doing...\n    _LT_SYS_HIDDEN_LIBDEPS($1)\n    _LT_COMPILER_PIC($1)\n    _LT_COMPILER_C_O($1)\n    _LT_COMPILER_FILE_LOCKS($1)\n    _LT_LINKER_SHLIBS($1)\n    _LT_SYS_DYNAMIC_LINKER($1)\n    _LT_LINKER_HARDCODE_LIBPATH($1)\n\n    _LT_CONFIG($1)\n  fi # test -n \"$compiler\"\n\n  GCC=$lt_save_GCC\n  CC=$lt_save_CC\n  CFLAGS=$lt_save_CFLAGS\nfi # test \"$_lt_disable_FC\" != yes\n\nAC_LANG_POP\n])# _LT_LANG_FC_CONFIG\n\n\n# _LT_LANG_GCJ_CONFIG([TAG])\n# --------------------------\n# Ensure that the configuration variables for the GNU Java Compiler compiler\n# are suitably defined.  These variables are subsequently used by _LT_CONFIG\n# to write the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_GCJ_CONFIG],\n[AC_REQUIRE([LT_PROG_GCJ])dnl\nAC_LANG_SAVE\n\n# Source file extension for Java test sources.\nac_ext=java\n\n# Object file extension for compiled Java test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# Code to be used in simple compile tests\nlt_simple_compile_test_code=\"class foo {}\"\n\n# Code to be used in simple link tests\nlt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'\n\n# ltmain only uses $CC for tagged configurations so make sure $CC is set.\n_LT_TAG_COMPILER\n\n# save warnings/boilerplate of simple test code\n_LT_COMPILER_BOILERPLATE\n_LT_LINKER_BOILERPLATE\n\n# Allow CC to be a program name with arguments.\nlt_save_CC=$CC\nlt_save_CFLAGS=$CFLAGS\nlt_save_GCC=$GCC\nGCC=yes\nCC=${GCJ-\"gcj\"}\nCFLAGS=$GCJFLAGS\ncompiler=$CC\n_LT_TAGVAR(compiler, $1)=$CC\n_LT_TAGVAR(LD, $1)=\"$LD\"\n_LT_CC_BASENAME([$compiler])\n\n# GCJ did not exist at the time GCC didn't implicitly link libc in.\n_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n\n_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds\n_LT_TAGVAR(reload_flag, $1)=$reload_flag\n_LT_TAGVAR(reload_cmds, $1)=$reload_cmds\n\n## CAVEAT EMPTOR:\n## There is no encapsulation within the following macros, do not change\n## the running order or otherwise move them around unless you know exactly\n## what you are doing...\nif test -n \"$compiler\"; then\n  _LT_COMPILER_NO_RTTI($1)\n  _LT_COMPILER_PIC($1)\n  _LT_COMPILER_C_O($1)\n  _LT_COMPILER_FILE_LOCKS($1)\n  _LT_LINKER_SHLIBS($1)\n  _LT_LINKER_HARDCODE_LIBPATH($1)\n\n  _LT_CONFIG($1)\nfi\n\nAC_LANG_RESTORE\n\nGCC=$lt_save_GCC\nCC=$lt_save_CC\nCFLAGS=$lt_save_CFLAGS\n])# _LT_LANG_GCJ_CONFIG\n\n\n# _LT_LANG_GO_CONFIG([TAG])\n# --------------------------\n# Ensure that the configuration variables for the GNU Go compiler\n# are suitably defined.  These variables are subsequently used by _LT_CONFIG\n# to write the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_GO_CONFIG],\n[AC_REQUIRE([LT_PROG_GO])dnl\nAC_LANG_SAVE\n\n# Source file extension for Go test sources.\nac_ext=go\n\n# Object file extension for compiled Go test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# Code to be used in simple compile tests\nlt_simple_compile_test_code=\"package main; func main() { }\"\n\n# Code to be used in simple link tests\nlt_simple_link_test_code='package main; func main() { }'\n\n# ltmain only uses $CC for tagged configurations so make sure $CC is set.\n_LT_TAG_COMPILER\n\n# save warnings/boilerplate of simple test code\n_LT_COMPILER_BOILERPLATE\n_LT_LINKER_BOILERPLATE\n\n# Allow CC to be a program name with arguments.\nlt_save_CC=$CC\nlt_save_CFLAGS=$CFLAGS\nlt_save_GCC=$GCC\nGCC=yes\nCC=${GOC-\"gccgo\"}\nCFLAGS=$GOFLAGS\ncompiler=$CC\n_LT_TAGVAR(compiler, $1)=$CC\n_LT_TAGVAR(LD, $1)=\"$LD\"\n_LT_CC_BASENAME([$compiler])\n\n# Go did not exist at the time GCC didn't implicitly link libc in.\n_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n\n_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds\n_LT_TAGVAR(reload_flag, $1)=$reload_flag\n_LT_TAGVAR(reload_cmds, $1)=$reload_cmds\n\n## CAVEAT EMPTOR:\n## There is no encapsulation within the following macros, do not change\n## the running order or otherwise move them around unless you know exactly\n## what you are doing...\nif test -n \"$compiler\"; then\n  _LT_COMPILER_NO_RTTI($1)\n  _LT_COMPILER_PIC($1)\n  _LT_COMPILER_C_O($1)\n  _LT_COMPILER_FILE_LOCKS($1)\n  _LT_LINKER_SHLIBS($1)\n  _LT_LINKER_HARDCODE_LIBPATH($1)\n\n  _LT_CONFIG($1)\nfi\n\nAC_LANG_RESTORE\n\nGCC=$lt_save_GCC\nCC=$lt_save_CC\nCFLAGS=$lt_save_CFLAGS\n])# _LT_LANG_GO_CONFIG\n\n\n# _LT_LANG_RC_CONFIG([TAG])\n# -------------------------\n# Ensure that the configuration variables for the Windows resource compiler\n# are suitably defined.  These variables are subsequently used by _LT_CONFIG\n# to write the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_RC_CONFIG],\n[AC_REQUIRE([LT_PROG_RC])dnl\nAC_LANG_SAVE\n\n# Source file extension for RC test sources.\nac_ext=rc\n\n# Object file extension for compiled RC test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# Code to be used in simple compile tests\nlt_simple_compile_test_code='sample MENU { MENUITEM \"&Soup\", 100, CHECKED }'\n\n# Code to be used in simple link tests\nlt_simple_link_test_code=\"$lt_simple_compile_test_code\"\n\n# ltmain only uses $CC for tagged configurations so make sure $CC is set.\n_LT_TAG_COMPILER\n\n# save warnings/boilerplate of simple test code\n_LT_COMPILER_BOILERPLATE\n_LT_LINKER_BOILERPLATE\n\n# Allow CC to be a program name with arguments.\nlt_save_CC=\"$CC\"\nlt_save_CFLAGS=$CFLAGS\nlt_save_GCC=$GCC\nGCC=\nCC=${RC-\"windres\"}\nCFLAGS=\ncompiler=$CC\n_LT_TAGVAR(compiler, $1)=$CC\n_LT_CC_BASENAME([$compiler])\n_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes\n\nif test -n \"$compiler\"; then\n  :\n  _LT_CONFIG($1)\nfi\n\nGCC=$lt_save_GCC\nAC_LANG_RESTORE\nCC=$lt_save_CC\nCFLAGS=$lt_save_CFLAGS\n])# _LT_LANG_RC_CONFIG\n\n\n# LT_PROG_GCJ\n# -----------\nAC_DEFUN([LT_PROG_GCJ],\n[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],\n  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],\n    [AC_CHECK_TOOL(GCJ, gcj,)\n      test \"x${GCJFLAGS+set}\" = xset || GCJFLAGS=\"-g -O2\"\n      AC_SUBST(GCJFLAGS)])])[]dnl\n])\n\n# Old name:\nAU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([LT_AC_PROG_GCJ], [])\n\n\n# LT_PROG_GO\n# ----------\nAC_DEFUN([LT_PROG_GO],\n[AC_CHECK_TOOL(GOC, gccgo,)\n])\n\n\n# LT_PROG_RC\n# ----------\nAC_DEFUN([LT_PROG_RC],\n[AC_CHECK_TOOL(RC, windres,)\n])\n\n# Old name:\nAU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([LT_AC_PROG_RC], [])\n\n\n# _LT_DECL_EGREP\n# --------------\n# If we don't have a new enough Autoconf to choose the best grep\n# available, choose the one first in the user's PATH.\nm4_defun([_LT_DECL_EGREP],\n[AC_REQUIRE([AC_PROG_EGREP])dnl\nAC_REQUIRE([AC_PROG_FGREP])dnl\ntest -z \"$GREP\" && GREP=grep\n_LT_DECL([], [GREP], [1], [A grep program that handles long lines])\n_LT_DECL([], [EGREP], [1], [An ERE matcher])\n_LT_DECL([], [FGREP], [1], [A literal string matcher])\ndnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too\nAC_SUBST([GREP])\n])\n\n\n# _LT_DECL_OBJDUMP\n# --------------\n# If we don't have a new enough Autoconf to choose the best objdump\n# available, choose the one first in the user's PATH.\nm4_defun([_LT_DECL_OBJDUMP],\n[AC_CHECK_TOOL(OBJDUMP, objdump, false)\ntest -z \"$OBJDUMP\" && OBJDUMP=objdump\n_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])\nAC_SUBST([OBJDUMP])\n])\n\n# _LT_DECL_DLLTOOL\n# ----------------\n# Ensure DLLTOOL variable is set.\nm4_defun([_LT_DECL_DLLTOOL],\n[AC_CHECK_TOOL(DLLTOOL, dlltool, false)\ntest -z \"$DLLTOOL\" && DLLTOOL=dlltool\n_LT_DECL([], [DLLTOOL], [1], [DLL creation program])\nAC_SUBST([DLLTOOL])\n])\n\n# _LT_DECL_SED\n# ------------\n# Check for a fully-functional sed program, that truncates\n# as few characters as possible.  Prefer GNU sed if found.\nm4_defun([_LT_DECL_SED],\n[AC_PROG_SED\ntest -z \"$SED\" && SED=sed\nXsed=\"$SED -e 1s/^X//\"\n_LT_DECL([], [SED], [1], [A sed program that does not truncate output])\n_LT_DECL([], [Xsed], [\"\\$SED -e 1s/^X//\"],\n    [Sed that helps us avoid accidentally triggering echo(1) options like -n])\n])# _LT_DECL_SED\n\nm4_ifndef([AC_PROG_SED], [\n############################################################\n# NOTE: This macro has been submitted for inclusion into   #\n#  GNU Autoconf as AC_PROG_SED.  When it is available in   #\n#  a released version of Autoconf we should remove this    #\n#  macro and use it instead.                               #\n############################################################\n\nm4_defun([AC_PROG_SED],\n[AC_MSG_CHECKING([for a sed that does not truncate output])\nAC_CACHE_VAL(lt_cv_path_SED,\n[# Loop through the user's path and test for sed and gsed.\n# Then use that list of sed's as ones to test for truncation.\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  for lt_ac_prog in sed gsed; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      if $as_executable_p \"$as_dir/$lt_ac_prog$ac_exec_ext\"; then\n        lt_ac_sed_list=\"$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext\"\n      fi\n    done\n  done\ndone\nIFS=$as_save_IFS\nlt_ac_max=0\nlt_ac_count=0\n# Add /usr/xpg4/bin/sed as it is typically found on Solaris\n# along with /bin/sed that truncates output.\nfor lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do\n  test ! -f $lt_ac_sed && continue\n  cat /dev/null > conftest.in\n  lt_ac_count=0\n  echo $ECHO_N \"0123456789$ECHO_C\" >conftest.in\n  # Check for GNU sed and select it if it is found.\n  if \"$lt_ac_sed\" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then\n    lt_cv_path_SED=$lt_ac_sed\n    break\n  fi\n  while true; do\n    cat conftest.in conftest.in >conftest.tmp\n    mv conftest.tmp conftest.in\n    cp conftest.in conftest.nl\n    echo >>conftest.nl\n    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break\n    cmp -s conftest.out conftest.nl || break\n    # 10000 chars as input seems more than enough\n    test $lt_ac_count -gt 10 && break\n    lt_ac_count=`expr $lt_ac_count + 1`\n    if test $lt_ac_count -gt $lt_ac_max; then\n      lt_ac_max=$lt_ac_count\n      lt_cv_path_SED=$lt_ac_sed\n    fi\n  done\ndone\n])\nSED=$lt_cv_path_SED\nAC_SUBST([SED])\nAC_MSG_RESULT([$SED])\n])#AC_PROG_SED\n])#m4_ifndef\n\n# Old name:\nAU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([LT_AC_PROG_SED], [])\n\n\n# _LT_CHECK_SHELL_FEATURES\n# ------------------------\n# Find out whether the shell is Bourne or XSI compatible,\n# or has some other useful features.\nm4_defun([_LT_CHECK_SHELL_FEATURES],\n[AC_MSG_CHECKING([whether the shell understands some XSI constructs])\n# Try some XSI features\nxsi_shell=no\n( _lt_dummy=\"a/b/c\"\n  test \"${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}\"${_lt_dummy%\"$_lt_dummy\"}, \\\n      = c,a/b,b/c, \\\n    && eval 'test $(( 1 + 1 )) -eq 2 \\\n    && test \"${#_lt_dummy}\" -eq 5' ) >/dev/null 2>&1 \\\n  && xsi_shell=yes\nAC_MSG_RESULT([$xsi_shell])\n_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])\n\nAC_MSG_CHECKING([whether the shell understands \"+=\"])\nlt_shell_append=no\n( foo=bar; set foo baz; eval \"$[1]+=\\$[2]\" && test \"$foo\" = barbaz ) \\\n    >/dev/null 2>&1 \\\n  && lt_shell_append=yes\nAC_MSG_RESULT([$lt_shell_append])\n_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])\n\nif ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then\n  lt_unset=unset\nelse\n  lt_unset=false\nfi\n_LT_DECL([], [lt_unset], [0], [whether the shell understands \"unset\"])dnl\n\n# test EBCDIC or ASCII\ncase `echo X|tr X '\\101'` in\n A) # ASCII based system\n    # \\n is not interpreted correctly by Solaris 8 /usr/ucb/tr\n  lt_SP2NL='tr \\040 \\012'\n  lt_NL2SP='tr \\015\\012 \\040\\040'\n  ;;\n *) # EBCDIC based system\n  lt_SP2NL='tr \\100 \\n'\n  lt_NL2SP='tr \\r\\n \\100\\100'\n  ;;\nesac\n_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl\n_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl\n])# _LT_CHECK_SHELL_FEATURES\n\n\n# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)\n# ------------------------------------------------------\n# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and\n# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.\nm4_defun([_LT_PROG_FUNCTION_REPLACE],\n[dnl {\nsed -e '/^$1 ()$/,/^} # $1 /c\\\n$1 ()\\\n{\\\nm4_bpatsubsts([$2], [$], [\\\\], [^\\([\t ]\\)], [\\\\\\1])\n} # Extended-shell $1 implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n])\n\n\n# _LT_PROG_REPLACE_SHELLFNS\n# -------------------------\n# Replace existing portable implementations of several shell functions with\n# equivalent extended shell implementations where those features are available..\nm4_defun([_LT_PROG_REPLACE_SHELLFNS],\n[if test x\"$xsi_shell\" = xyes; then\n  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl\n    case ${1} in\n      */*) func_dirname_result=\"${1%/*}${2}\" ;;\n      *  ) func_dirname_result=\"${3}\" ;;\n    esac])\n\n  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl\n    func_basename_result=\"${1##*/}\"])\n\n  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl\n    case ${1} in\n      */*) func_dirname_result=\"${1%/*}${2}\" ;;\n      *  ) func_dirname_result=\"${3}\" ;;\n    esac\n    func_basename_result=\"${1##*/}\"])\n\n  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl\n    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\n    # positional parameters, so assign one to ordinary parameter first.\n    func_stripname_result=${3}\n    func_stripname_result=${func_stripname_result#\"${1}\"}\n    func_stripname_result=${func_stripname_result%\"${2}\"}])\n\n  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl\n    func_split_long_opt_name=${1%%=*}\n    func_split_long_opt_arg=${1#*=}])\n\n  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl\n    func_split_short_opt_arg=${1#??}\n    func_split_short_opt_name=${1%\"$func_split_short_opt_arg\"}])\n\n  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl\n    case ${1} in\n      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\n      *)    func_lo2o_result=${1} ;;\n    esac])\n\n  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])\n\n  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])\n\n  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])\nfi\n\nif test x\"$lt_shell_append\" = xyes; then\n  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval \"${1}+=\\\\${2}\"])\n\n  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl\n    func_quote_for_eval \"${2}\"\ndnl m4 expansion turns \\\\\\\\ into \\\\, and then the shell eval turns that into \\\n    eval \"${1}+=\\\\\\\\ \\\\$func_quote_for_eval_result\"])\n\n  # Save a `func_append' function call where possible by direct use of '+='\n  sed -e 's%func_append \\([[a-zA-Z_]]\\{1,\\}\\) \"%\\1+=\"%g' $cfgfile > $cfgfile.tmp \\\n    && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n      || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\n  test 0 -eq $? || _lt_function_replace_fail=:\nelse\n  # Save a `func_append' function call even when '+=' is not available\n  sed -e 's%func_append \\([[a-zA-Z_]]\\{1,\\}\\) \"%\\1=\"$\\1%g' $cfgfile > $cfgfile.tmp \\\n    && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n      || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\n  test 0 -eq $? || _lt_function_replace_fail=:\nfi\n\nif test x\"$_lt_function_replace_fail\" = x\":\"; then\n  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])\nfi\n])\n\n# _LT_PATH_CONVERSION_FUNCTIONS\n# -----------------------------\n# Determine which file name conversion functions should be used by\n# func_to_host_file (and, implicitly, by func_to_host_path).  These are needed\n# for certain cross-compile configurations and native mingw.\nm4_defun([_LT_PATH_CONVERSION_FUNCTIONS],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\nAC_REQUIRE([AC_CANONICAL_BUILD])dnl\nAC_MSG_CHECKING([how to convert $build file names to $host format])\nAC_CACHE_VAL(lt_cv_to_host_file_cmd,\n[case $host in\n  *-*-mingw* )\n    case $build in\n      *-*-mingw* ) # actually msys\n        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32\n        ;;\n      *-*-cygwin* )\n        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32\n        ;;\n      * ) # otherwise, assume *nix\n        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32\n        ;;\n    esac\n    ;;\n  *-*-cygwin* )\n    case $build in\n      *-*-mingw* ) # actually msys\n        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin\n        ;;\n      *-*-cygwin* )\n        lt_cv_to_host_file_cmd=func_convert_file_noop\n        ;;\n      * ) # otherwise, assume *nix\n        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin\n        ;;\n    esac\n    ;;\n  * ) # unhandled hosts (and \"normal\" native builds)\n    lt_cv_to_host_file_cmd=func_convert_file_noop\n    ;;\nesac\n])\nto_host_file_cmd=$lt_cv_to_host_file_cmd\nAC_MSG_RESULT([$lt_cv_to_host_file_cmd])\n_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],\n         [0], [convert $build file names to $host format])dnl\n\nAC_MSG_CHECKING([how to convert $build file names to toolchain format])\nAC_CACHE_VAL(lt_cv_to_tool_file_cmd,\n[#assume ordinary cross tools, or native build.\nlt_cv_to_tool_file_cmd=func_convert_file_noop\ncase $host in\n  *-*-mingw* )\n    case $build in\n      *-*-mingw* ) # actually msys\n        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32\n        ;;\n    esac\n    ;;\nesac\n])\nto_tool_file_cmd=$lt_cv_to_tool_file_cmd\nAC_MSG_RESULT([$lt_cv_to_tool_file_cmd])\n_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],\n         [0], [convert $build files to toolchain format])dnl\n])# _LT_PATH_CONVERSION_FUNCTIONS\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/m4/ltoptions.m4",
    "content": "# Helper functions for option handling.                    -*- Autoconf -*-\n#\n#   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,\n#   Inc.\n#   Written by Gary V. Vaughan, 2004\n#\n# This file is free software; the Free Software Foundation gives\n# unlimited permission to copy and/or distribute it, with or without\n# modifications, as long as this notice is preserved.\n\n# serial 7 ltoptions.m4\n\n# This is to help aclocal find these macros, as it can't see m4_define.\nAC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])\n\n\n# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)\n# ------------------------------------------\nm4_define([_LT_MANGLE_OPTION],\n[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])\n\n\n# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)\n# ---------------------------------------\n# Set option OPTION-NAME for macro MACRO-NAME, and if there is a\n# matching handler defined, dispatch to it.  Other OPTION-NAMEs are\n# saved as a flag.\nm4_define([_LT_SET_OPTION],\n[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl\nm4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),\n        _LT_MANGLE_DEFUN([$1], [$2]),\n    [m4_warning([Unknown $1 option `$2'])])[]dnl\n])\n\n\n# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])\n# ------------------------------------------------------------\n# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.\nm4_define([_LT_IF_OPTION],\n[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])\n\n\n# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)\n# -------------------------------------------------------\n# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME\n# are set.\nm4_define([_LT_UNLESS_OPTIONS],\n[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),\n\t    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),\n\t\t      [m4_define([$0_found])])])[]dnl\nm4_ifdef([$0_found], [m4_undefine([$0_found])], [$3\n])[]dnl\n])\n\n\n# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)\n# ----------------------------------------\n# OPTION-LIST is a space-separated list of Libtool options associated\n# with MACRO-NAME.  If any OPTION has a matching handler declared with\n# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about\n# the unknown option and exit.\nm4_defun([_LT_SET_OPTIONS],\n[# Set options\nm4_foreach([_LT_Option], m4_split(m4_normalize([$2])),\n    [_LT_SET_OPTION([$1], _LT_Option)])\n\nm4_if([$1],[LT_INIT],[\n  dnl\n  dnl Simply set some default values (i.e off) if boolean options were not\n  dnl specified:\n  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no\n  ])\n  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no\n  ])\n  dnl\n  dnl If no reference was made to various pairs of opposing options, then\n  dnl we run the default mode handler for the pair.  For example, if neither\n  dnl `shared' nor `disable-shared' was passed, we enable building of shared\n  dnl archives by default:\n  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])\n  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])\n  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])\n  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],\n  \t\t   [_LT_ENABLE_FAST_INSTALL])\n  ])\n])# _LT_SET_OPTIONS\n\n\n## --------------------------------- ##\n## Macros to handle LT_INIT options. ##\n## --------------------------------- ##\n\n# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)\n# -----------------------------------------\nm4_define([_LT_MANGLE_DEFUN],\n[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])\n\n\n# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)\n# -----------------------------------------------\nm4_define([LT_OPTION_DEFINE],\n[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl\n])# LT_OPTION_DEFINE\n\n\n# dlopen\n# ------\nLT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes\n])\n\nAU_DEFUN([AC_LIBTOOL_DLOPEN],\n[_LT_SET_OPTION([LT_INIT], [dlopen])\nAC_DIAGNOSE([obsolete],\n[$0: Remove this warning and the call to _LT_SET_OPTION when you\nput the `dlopen' option into LT_INIT's first parameter.])\n])\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])\n\n\n# win32-dll\n# ---------\n# Declare package support for building win32 dll's.\nLT_OPTION_DEFINE([LT_INIT], [win32-dll],\n[enable_win32_dll=yes\n\ncase $host in\n*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)\n  AC_CHECK_TOOL(AS, as, false)\n  AC_CHECK_TOOL(DLLTOOL, dlltool, false)\n  AC_CHECK_TOOL(OBJDUMP, objdump, false)\n  ;;\nesac\n\ntest -z \"$AS\" && AS=as\n_LT_DECL([], [AS],      [1], [Assembler program])dnl\n\ntest -z \"$DLLTOOL\" && DLLTOOL=dlltool\n_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl\n\ntest -z \"$OBJDUMP\" && OBJDUMP=objdump\n_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl\n])# win32-dll\n\nAU_DEFUN([AC_LIBTOOL_WIN32_DLL],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\n_LT_SET_OPTION([LT_INIT], [win32-dll])\nAC_DIAGNOSE([obsolete],\n[$0: Remove this warning and the call to _LT_SET_OPTION when you\nput the `win32-dll' option into LT_INIT's first parameter.])\n])\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])\n\n\n# _LT_ENABLE_SHARED([DEFAULT])\n# ----------------------------\n# implement the --enable-shared flag, and supports the `shared' and\n# `disable-shared' LT_INIT options.\n# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.\nm4_define([_LT_ENABLE_SHARED],\n[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl\nAC_ARG_ENABLE([shared],\n    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],\n\t[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],\n    [p=${PACKAGE-default}\n    case $enableval in\n    yes) enable_shared=yes ;;\n    no) enable_shared=no ;;\n    *)\n      enable_shared=no\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for pkg in $enableval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$pkg\" = \"X$p\"; then\n\t  enable_shared=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac],\n    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)\n\n    _LT_DECL([build_libtool_libs], [enable_shared], [0],\n\t[Whether or not to build shared libraries])\n])# _LT_ENABLE_SHARED\n\nLT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])\nLT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])\n\n# Old names:\nAC_DEFUN([AC_ENABLE_SHARED],\n[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])\n])\n\nAC_DEFUN([AC_DISABLE_SHARED],\n[_LT_SET_OPTION([LT_INIT], [disable-shared])\n])\n\nAU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])\nAU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AM_ENABLE_SHARED], [])\ndnl AC_DEFUN([AM_DISABLE_SHARED], [])\n\n\n\n# _LT_ENABLE_STATIC([DEFAULT])\n# ----------------------------\n# implement the --enable-static flag, and support the `static' and\n# `disable-static' LT_INIT options.\n# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.\nm4_define([_LT_ENABLE_STATIC],\n[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl\nAC_ARG_ENABLE([static],\n    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],\n\t[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],\n    [p=${PACKAGE-default}\n    case $enableval in\n    yes) enable_static=yes ;;\n    no) enable_static=no ;;\n    *)\n     enable_static=no\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for pkg in $enableval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$pkg\" = \"X$p\"; then\n\t  enable_static=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac],\n    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)\n\n    _LT_DECL([build_old_libs], [enable_static], [0],\n\t[Whether or not to build static libraries])\n])# _LT_ENABLE_STATIC\n\nLT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])\nLT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])\n\n# Old names:\nAC_DEFUN([AC_ENABLE_STATIC],\n[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])\n])\n\nAC_DEFUN([AC_DISABLE_STATIC],\n[_LT_SET_OPTION([LT_INIT], [disable-static])\n])\n\nAU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])\nAU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AM_ENABLE_STATIC], [])\ndnl AC_DEFUN([AM_DISABLE_STATIC], [])\n\n\n\n# _LT_ENABLE_FAST_INSTALL([DEFAULT])\n# ----------------------------------\n# implement the --enable-fast-install flag, and support the `fast-install'\n# and `disable-fast-install' LT_INIT options.\n# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.\nm4_define([_LT_ENABLE_FAST_INSTALL],\n[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl\nAC_ARG_ENABLE([fast-install],\n    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],\n    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],\n    [p=${PACKAGE-default}\n    case $enableval in\n    yes) enable_fast_install=yes ;;\n    no) enable_fast_install=no ;;\n    *)\n      enable_fast_install=no\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for pkg in $enableval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$pkg\" = \"X$p\"; then\n\t  enable_fast_install=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac],\n    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)\n\n_LT_DECL([fast_install], [enable_fast_install], [0],\n\t [Whether or not to optimize for fast installation])dnl\n])# _LT_ENABLE_FAST_INSTALL\n\nLT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])\nLT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])\n\n# Old names:\nAU_DEFUN([AC_ENABLE_FAST_INSTALL],\n[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])\nAC_DIAGNOSE([obsolete],\n[$0: Remove this warning and the call to _LT_SET_OPTION when you put\nthe `fast-install' option into LT_INIT's first parameter.])\n])\n\nAU_DEFUN([AC_DISABLE_FAST_INSTALL],\n[_LT_SET_OPTION([LT_INIT], [disable-fast-install])\nAC_DIAGNOSE([obsolete],\n[$0: Remove this warning and the call to _LT_SET_OPTION when you put\nthe `disable-fast-install' option into LT_INIT's first parameter.])\n])\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])\ndnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])\n\n\n# _LT_WITH_PIC([MODE])\n# --------------------\n# implement the --with-pic flag, and support the `pic-only' and `no-pic'\n# LT_INIT options.\n# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.\nm4_define([_LT_WITH_PIC],\n[AC_ARG_WITH([pic],\n    [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],\n\t[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],\n    [lt_p=${PACKAGE-default}\n    case $withval in\n    yes|no) pic_mode=$withval ;;\n    *)\n      pic_mode=default\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for lt_pkg in $withval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$lt_pkg\" = \"X$lt_p\"; then\n\t  pic_mode=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac],\n    [pic_mode=default])\n\ntest -z \"$pic_mode\" && pic_mode=m4_default([$1], [default])\n\n_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl\n])# _LT_WITH_PIC\n\nLT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])\nLT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])\n\n# Old name:\nAU_DEFUN([AC_LIBTOOL_PICMODE],\n[_LT_SET_OPTION([LT_INIT], [pic-only])\nAC_DIAGNOSE([obsolete],\n[$0: Remove this warning and the call to _LT_SET_OPTION when you\nput the `pic-only' option into LT_INIT's first parameter.])\n])\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])\n\n## ----------------- ##\n## LTDL_INIT Options ##\n## ----------------- ##\n\nm4_define([_LTDL_MODE], [])\nLT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],\n\t\t [m4_define([_LTDL_MODE], [nonrecursive])])\nLT_OPTION_DEFINE([LTDL_INIT], [recursive],\n\t\t [m4_define([_LTDL_MODE], [recursive])])\nLT_OPTION_DEFINE([LTDL_INIT], [subproject],\n\t\t [m4_define([_LTDL_MODE], [subproject])])\n\nm4_define([_LTDL_TYPE], [])\nLT_OPTION_DEFINE([LTDL_INIT], [installable],\n\t\t [m4_define([_LTDL_TYPE], [installable])])\nLT_OPTION_DEFINE([LTDL_INIT], [convenience],\n\t\t [m4_define([_LTDL_TYPE], [convenience])])\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/m4/ltsugar.m4",
    "content": "# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-\n#\n# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.\n# Written by Gary V. Vaughan, 2004\n#\n# This file is free software; the Free Software Foundation gives\n# unlimited permission to copy and/or distribute it, with or without\n# modifications, as long as this notice is preserved.\n\n# serial 6 ltsugar.m4\n\n# This is to help aclocal find these macros, as it can't see m4_define.\nAC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])\n\n\n# lt_join(SEP, ARG1, [ARG2...])\n# -----------------------------\n# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their\n# associated separator.\n# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier\n# versions in m4sugar had bugs.\nm4_define([lt_join],\n[m4_if([$#], [1], [],\n       [$#], [2], [[$2]],\n       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])\nm4_define([_lt_join],\n[m4_if([$#$2], [2], [],\n       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])\n\n\n# lt_car(LIST)\n# lt_cdr(LIST)\n# ------------\n# Manipulate m4 lists.\n# These macros are necessary as long as will still need to support\n# Autoconf-2.59 which quotes differently.\nm4_define([lt_car], [[$1]])\nm4_define([lt_cdr],\n[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],\n       [$#], 1, [],\n       [m4_dquote(m4_shift($@))])])\nm4_define([lt_unquote], $1)\n\n\n# lt_append(MACRO-NAME, STRING, [SEPARATOR])\n# ------------------------------------------\n# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.\n# Note that neither SEPARATOR nor STRING are expanded; they are appended\n# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).\n# No SEPARATOR is output if MACRO-NAME was previously undefined (different\n# than defined and empty).\n#\n# This macro is needed until we can rely on Autoconf 2.62, since earlier\n# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.\nm4_define([lt_append],\n[m4_define([$1],\n\t   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])\n\n\n\n# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])\n# ----------------------------------------------------------\n# Produce a SEP delimited list of all paired combinations of elements of\n# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list\n# has the form PREFIXmINFIXSUFFIXn.\n# Needed until we can rely on m4_combine added in Autoconf 2.62.\nm4_define([lt_combine],\n[m4_if(m4_eval([$# > 3]), [1],\n       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl\n[[m4_foreach([_Lt_prefix], [$2],\n\t     [m4_foreach([_Lt_suffix],\n\t\t]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,\n\t[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])\n\n\n# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])\n# -----------------------------------------------------------------------\n# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited\n# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.\nm4_define([lt_if_append_uniq],\n[m4_ifdef([$1],\n\t  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],\n\t\t [lt_append([$1], [$2], [$3])$4],\n\t\t [$5])],\n\t  [lt_append([$1], [$2], [$3])$4])])\n\n\n# lt_dict_add(DICT, KEY, VALUE)\n# -----------------------------\nm4_define([lt_dict_add],\n[m4_define([$1($2)], [$3])])\n\n\n# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)\n# --------------------------------------------\nm4_define([lt_dict_add_subkey],\n[m4_define([$1($2:$3)], [$4])])\n\n\n# lt_dict_fetch(DICT, KEY, [SUBKEY])\n# ----------------------------------\nm4_define([lt_dict_fetch],\n[m4_ifval([$3],\n\tm4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),\n    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])\n\n\n# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])\n# -----------------------------------------------------------------\nm4_define([lt_if_dict_fetch],\n[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],\n\t[$5],\n    [$6])])\n\n\n# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])\n# --------------------------------------------------------------\nm4_define([lt_dict_filter],\n[m4_if([$5], [], [],\n  [lt_join(m4_quote(m4_default([$4], [[, ]])),\n           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),\n\t\t      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl\n])\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/m4/ltversion.m4",
    "content": "# ltversion.m4 -- version numbers\t\t\t-*- Autoconf -*-\n#\n#   Copyright (C) 2004 Free Software Foundation, Inc.\n#   Written by Scott James Remnant, 2004\n#\n# This file is free software; the Free Software Foundation gives\n# unlimited permission to copy and/or distribute it, with or without\n# modifications, as long as this notice is preserved.\n\n# @configure_input@\n\n# serial 3337 ltversion.m4\n# This file is part of GNU Libtool\n\nm4_define([LT_PACKAGE_VERSION], [2.4.2])\nm4_define([LT_PACKAGE_REVISION], [1.3337])\n\nAC_DEFUN([LTVERSION_VERSION],\n[macro_version='2.4.2'\nmacro_revision='1.3337'\n_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])\n_LT_DECL(, macro_revision, 0)\n])\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/m4/lt~obsolete.m4",
    "content": "# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-\n#\n#   Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.\n#   Written by Scott James Remnant, 2004.\n#\n# This file is free software; the Free Software Foundation gives\n# unlimited permission to copy and/or distribute it, with or without\n# modifications, as long as this notice is preserved.\n\n# serial 5 lt~obsolete.m4\n\n# These exist entirely to fool aclocal when bootstrapping libtool.\n#\n# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)\n# which have later been changed to m4_define as they aren't part of the\n# exported API, or moved to Autoconf or Automake where they belong.\n#\n# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN\n# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us\n# using a macro with the same name in our local m4/libtool.m4 it'll\n# pull the old libtool.m4 in (it doesn't see our shiny new m4_define\n# and doesn't know about Autoconf macros at all.)\n#\n# So we provide this file, which has a silly filename so it's always\n# included after everything else.  This provides aclocal with the\n# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything\n# because those macros already exist, or will be overwritten later.\n# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. \n#\n# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.\n# Yes, that means every name once taken will need to remain here until\n# we give up compatibility with versions before 1.7, at which point\n# we need to keep only those names which we still refer to.\n\n# This is to help aclocal find these macros, as it can't see m4_define.\nAC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])\n\nm4_ifndef([AC_LIBTOOL_LINKER_OPTION],\t[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])\nm4_ifndef([AC_PROG_EGREP],\t\t[AC_DEFUN([AC_PROG_EGREP])])\nm4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],\t[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])\nm4_ifndef([_LT_AC_SHELL_INIT],\t\t[AC_DEFUN([_LT_AC_SHELL_INIT])])\nm4_ifndef([_LT_AC_SYS_LIBPATH_AIX],\t[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])\nm4_ifndef([_LT_PROG_LTMAIN],\t\t[AC_DEFUN([_LT_PROG_LTMAIN])])\nm4_ifndef([_LT_AC_TAGVAR],\t\t[AC_DEFUN([_LT_AC_TAGVAR])])\nm4_ifndef([AC_LTDL_ENABLE_INSTALL],\t[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])\nm4_ifndef([AC_LTDL_PREOPEN],\t\t[AC_DEFUN([AC_LTDL_PREOPEN])])\nm4_ifndef([_LT_AC_SYS_COMPILER],\t[AC_DEFUN([_LT_AC_SYS_COMPILER])])\nm4_ifndef([_LT_AC_LOCK],\t\t[AC_DEFUN([_LT_AC_LOCK])])\nm4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],\t[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])\nm4_ifndef([_LT_AC_TRY_DLOPEN_SELF],\t[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])\nm4_ifndef([AC_LIBTOOL_PROG_CC_C_O],\t[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])\nm4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])\nm4_ifndef([AC_LIBTOOL_OBJDIR],\t\t[AC_DEFUN([AC_LIBTOOL_OBJDIR])])\nm4_ifndef([AC_LTDL_OBJDIR],\t\t[AC_DEFUN([AC_LTDL_OBJDIR])])\nm4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])\nm4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],\t[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])\nm4_ifndef([AC_PATH_MAGIC],\t\t[AC_DEFUN([AC_PATH_MAGIC])])\nm4_ifndef([AC_PROG_LD_GNU],\t\t[AC_DEFUN([AC_PROG_LD_GNU])])\nm4_ifndef([AC_PROG_LD_RELOAD_FLAG],\t[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])\nm4_ifndef([AC_DEPLIBS_CHECK_METHOD],\t[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])\nm4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])\nm4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])\nm4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])\nm4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],\t[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])\nm4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],\t[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])\nm4_ifndef([LT_AC_PROG_EGREP],\t\t[AC_DEFUN([LT_AC_PROG_EGREP])])\nm4_ifndef([LT_AC_PROG_SED],\t\t[AC_DEFUN([LT_AC_PROG_SED])])\nm4_ifndef([_LT_CC_BASENAME],\t\t[AC_DEFUN([_LT_CC_BASENAME])])\nm4_ifndef([_LT_COMPILER_BOILERPLATE],\t[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])\nm4_ifndef([_LT_LINKER_BOILERPLATE],\t[AC_DEFUN([_LT_LINKER_BOILERPLATE])])\nm4_ifndef([_AC_PROG_LIBTOOL],\t\t[AC_DEFUN([_AC_PROG_LIBTOOL])])\nm4_ifndef([AC_LIBTOOL_SETUP],\t\t[AC_DEFUN([AC_LIBTOOL_SETUP])])\nm4_ifndef([_LT_AC_CHECK_DLFCN],\t\t[AC_DEFUN([_LT_AC_CHECK_DLFCN])])\nm4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],\t[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])\nm4_ifndef([_LT_AC_TAGCONFIG],\t\t[AC_DEFUN([_LT_AC_TAGCONFIG])])\nm4_ifndef([AC_DISABLE_FAST_INSTALL],\t[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])\nm4_ifndef([_LT_AC_LANG_CXX],\t\t[AC_DEFUN([_LT_AC_LANG_CXX])])\nm4_ifndef([_LT_AC_LANG_F77],\t\t[AC_DEFUN([_LT_AC_LANG_F77])])\nm4_ifndef([_LT_AC_LANG_GCJ],\t\t[AC_DEFUN([_LT_AC_LANG_GCJ])])\nm4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],\t[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])\nm4_ifndef([_LT_AC_LANG_C_CONFIG],\t[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])\nm4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],\t[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])\nm4_ifndef([_LT_AC_LANG_CXX_CONFIG],\t[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])\nm4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],\t[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])\nm4_ifndef([_LT_AC_LANG_F77_CONFIG],\t[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])\nm4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],\t[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])\nm4_ifndef([_LT_AC_LANG_GCJ_CONFIG],\t[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])\nm4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],\t[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])\nm4_ifndef([_LT_AC_LANG_RC_CONFIG],\t[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])\nm4_ifndef([AC_LIBTOOL_CONFIG],\t\t[AC_DEFUN([AC_LIBTOOL_CONFIG])])\nm4_ifndef([_LT_AC_FILE_LTDLL_C],\t[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])\nm4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],\t[AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])\nm4_ifndef([_LT_AC_PROG_CXXCPP],\t\t[AC_DEFUN([_LT_AC_PROG_CXXCPP])])\nm4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],\t[AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])\nm4_ifndef([_LT_PROG_ECHO_BACKSLASH],\t[AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])\nm4_ifndef([_LT_PROG_F77],\t\t[AC_DEFUN([_LT_PROG_F77])])\nm4_ifndef([_LT_PROG_FC],\t\t[AC_DEFUN([_LT_PROG_FC])])\nm4_ifndef([_LT_PROG_CXX],\t\t[AC_DEFUN([_LT_PROG_CXX])])\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/m4/opus-intrinsics.m4",
    "content": "dnl opus-intrinsics.m4\ndnl macro for testing for support for compiler intrinsics, either by default or with a compiler flag\n\ndnl OPUS_CHECK_INTRINSICS(NAME-OF-INTRINSICS, COMPILER-FLAG-FOR-INTRINSICS, VAR-IF-PRESENT, VAR-IF-DEFAULT, TEST-PROGRAM-HEADER, TEST-PROGRAM-BODY)\nAC_DEFUN([OPUS_CHECK_INTRINSICS],\n[\n   AC_MSG_CHECKING([if compiler supports $1 intrinsics])\n   AC_LINK_IFELSE(\n     [AC_LANG_PROGRAM($5, $6)],\n     [\n        $3=1\n        $4=1\n        AC_MSG_RESULT([yes])\n      ],[\n        $4=0\n        AC_MSG_RESULT([no])\n        AC_MSG_CHECKING([if compiler supports $1 intrinsics with $2])\n        save_CFLAGS=\"$CFLAGS\"; CFLAGS=\"$2 $CFLAGS\"\n        AC_LINK_IFELSE([AC_LANG_PROGRAM($5, $6)],\n        [\n           AC_MSG_RESULT([yes])\n           $3=1\n        ],[\n           AC_MSG_RESULT([no])\n           $3=0\n        ])\n        CFLAGS=\"$save_CFLAGS\"\n     ])\n])\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/opus-uninstalled.pc.in",
    "content": "# Opus codec reference implementation uninstalled pkg-config file\n\nlibdir=${pcfiledir}/.libs\nincludedir=${pcfiledir}\n\nName: opus uninstalled\nDescription: Opus IETF audio codec (not installed, @PC_BUILD@)\nVersion: @VERSION@\nRequires:\nConflicts:\nLibs: ${libdir}/libopus.a @LIBM@\nCflags: -I${pcfiledir}/@top_srcdir@/include\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/opus.m4",
    "content": "# Configure paths for libopus\n# Gregory Maxwell <greg@xiph.org> 08-30-2012\n# Shamelessly stolen from Jack Moffitt (libogg) who\n# Shamelessly stole from Owen Taylor and Manish Singh\n\ndnl XIPH_PATH_OPUS([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])\ndnl Test for libopus, and define OPUS_CFLAGS and OPUS_LIBS\ndnl\nAC_DEFUN([XIPH_PATH_OPUS],\n[dnl\ndnl Get the cflags and libraries\ndnl\nAC_ARG_WITH(opus,AC_HELP_STRING([--with-opus=PFX],[Prefix where opus is installed (optional)]), opus_prefix=\"$withval\", opus_prefix=\"\")\nAC_ARG_WITH(opus-libraries,AC_HELP_STRING([--with-opus-libraries=DIR],[Directory where the opus library is installed (optional)]), opus_libraries=\"$withval\", opus_libraries=\"\")\nAC_ARG_WITH(opus-includes,AC_HELP_STRING([--with-opus-includes=DIR],[Directory where the opus header files are installed (optional)]), opus_includes=\"$withval\", opus_includes=\"\")\nAC_ARG_ENABLE(opustest,AC_HELP_STRING([--disable-opustest],[Do not try to compile and run a test opus program]),, enable_opustest=yes)\n\n  if test \"x$opus_libraries\" != \"x\" ; then\n    OPUS_LIBS=\"-L$opus_libraries\"\n  elif test \"x$opus_prefix\" = \"xno\" || test \"x$opus_prefix\" = \"xyes\" ; then\n    OPUS_LIBS=\"\"\n  elif test \"x$opus_prefix\" != \"x\" ; then\n    OPUS_LIBS=\"-L$opus_prefix/lib\"\n  elif test \"x$prefix\" != \"xNONE\" ; then\n    OPUS_LIBS=\"-L$prefix/lib\"\n  fi\n\n  if test \"x$opus_prefix\" != \"xno\" ; then\n    OPUS_LIBS=\"$OPUS_LIBS -lopus\"\n  fi\n\n  if test \"x$opus_includes\" != \"x\" ; then\n    OPUS_CFLAGS=\"-I$opus_includes\"\n  elif test \"x$opus_prefix\" = \"xno\" || test \"x$opus_prefix\" = \"xyes\" ; then\n    OPUS_CFLAGS=\"\"\n  elif test \"x$opus_prefix\" != \"x\" ; then\n    OPUS_CFLAGS=\"-I$opus_prefix/include\"\n  elif test \"x$prefix\" != \"xNONE\"; then\n    OPUS_CFLAGS=\"-I$prefix/include\"\n  fi\n\n  AC_MSG_CHECKING(for Opus)\n  if test \"x$opus_prefix\" = \"xno\" ; then\n    no_opus=\"disabled\"\n    enable_opustest=\"no\"\n  else\n    no_opus=\"\"\n  fi\n\n\n  if test \"x$enable_opustest\" = \"xyes\" ; then\n    ac_save_CFLAGS=\"$CFLAGS\"\n    ac_save_LIBS=\"$LIBS\"\n    CFLAGS=\"$CFLAGS $OPUS_CFLAGS\"\n    LIBS=\"$LIBS $OPUS_LIBS\"\ndnl\ndnl Now check if the installed Opus is sufficiently new.\ndnl\n      rm -f conf.opustest\n      AC_TRY_RUN([\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <opus.h>\n\nint main ()\n{\n  system(\"touch conf.opustest\");\n  return 0;\n}\n\n],, no_opus=yes,[echo $ac_n \"cross compiling; assumed OK... $ac_c\"])\n       CFLAGS=\"$ac_save_CFLAGS\"\n       LIBS=\"$ac_save_LIBS\"\n  fi\n\n  if test \"x$no_opus\" = \"xdisabled\" ; then\n     AC_MSG_RESULT(no)\n     ifelse([$2], , :, [$2])\n  elif test \"x$no_opus\" = \"x\" ; then\n     AC_MSG_RESULT(yes)\n     ifelse([$1], , :, [$1])\n  else\n     AC_MSG_RESULT(no)\n     if test -f conf.opustest ; then\n       :\n     else\n       echo \"*** Could not run Opus test program, checking why...\"\n       CFLAGS=\"$CFLAGS $OPUS_CFLAGS\"\n       LIBS=\"$LIBS $OPUS_LIBS\"\n       AC_TRY_LINK([\n#include <stdio.h>\n#include <opus.h>\n],     [ return 0; ],\n       [ echo \"*** The test program compiled, but did not run. This usually means\"\n       echo \"*** that the run-time linker is not finding Opus or finding the wrong\"\n       echo \"*** version of Opus. If it is not finding Opus, you'll need to set your\"\n       echo \"*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point\"\n       echo \"*** to the installed location  Also, make sure you have run ldconfig if that\"\n       echo \"*** is required on your system\"\n       echo \"***\"\n       echo \"*** If you have an old version installed, it is best to remove it, although\"\n       echo \"*** you may also be able to get things to work by modifying LD_LIBRARY_PATH\"],\n       [ echo \"*** The test program failed to compile or link. See the file config.log for the\"\n       echo \"*** exact error that occurred. This usually means Opus was incorrectly installed\"\n       echo \"*** or that you have moved Opus since it was installed.\" ])\n       CFLAGS=\"$ac_save_CFLAGS\"\n       LIBS=\"$ac_save_LIBS\"\n     fi\n     OPUS_CFLAGS=\"\"\n     OPUS_LIBS=\"\"\n     ifelse([$2], , :, [$2])\n  fi\n  AC_SUBST(OPUS_CFLAGS)\n  AC_SUBST(OPUS_LIBS)\n  rm -f conf.opustest\n])\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/opus.pc.in",
    "content": "# Opus codec reference implementation pkg-config file\n\nprefix=@prefix@\nexec_prefix=@exec_prefix@\nlibdir=@libdir@\nincludedir=@includedir@\n\nName: Opus\nDescription: Opus IETF audio codec (@PC_BUILD@ build)\nURL: http://opus-codec.org/\nVersion: @VERSION@\nRequires:\nConflicts:\nLibs: -L${libdir} -lopus\nLibs.private: @LIBM@\nCflags: -I${includedir}/opus\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/opus_headers.mk",
    "content": "OPUS_HEAD = \\\ninclude/opus.h \\\ninclude/opus_multistream.h \\\nsrc/opus_private.h \\\nsrc/analysis.h \\\nsrc/mlp.h \\\nsrc/tansig_table.h\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/opus_sources.mk",
    "content": "OPUS_SOURCES = src/opus.c \\\nsrc/opus_decoder.c \\\nsrc/opus_encoder.c \\\nsrc/opus_multistream.c \\\nsrc/opus_multistream_encoder.c \\\nsrc/opus_multistream_decoder.c \\\nsrc/repacketizer.c\n\nOPUS_SOURCES_FLOAT = \\\nsrc/analysis.c \\\nsrc/mlp.c \\\nsrc/mlp_data.c\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/package_version",
    "content": "PACKAGE_VERSION=\"1.1.2\"\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/A2NLSF.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n/* Conversion between prediction filter coefficients and NLSFs  */\n/* Requires the order to be an even number                      */\n/* A piecewise linear approximation maps LSF <-> cos(LSF)       */\n/* Therefore the result is not accurate NLSFs, but the two      */\n/* functions are accurate inverses of each other                */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n#include \"tables.h\"\n\n/* Number of binary divisions, when not in low complexity mode */\n#define BIN_DIV_STEPS_A2NLSF_FIX      3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */\n#define MAX_ITERATIONS_A2NLSF_FIX    30\n\n/* Helper function for A2NLSF(..)                    */\n/* Transforms polynomials from cos(n*f) to cos(f)^n  */\nstatic OPUS_INLINE void silk_A2NLSF_trans_poly(\n    opus_int32          *p,                     /* I/O    Polynomial                                */\n    const opus_int      dd                      /* I      Polynomial order (= filter order / 2 )    */\n)\n{\n    opus_int k, n;\n\n    for( k = 2; k <= dd; k++ ) {\n        for( n = dd; n > k; n-- ) {\n            p[ n - 2 ] -= p[ n ];\n        }\n        p[ k - 2 ] -= silk_LSHIFT( p[ k ], 1 );\n    }\n}\n/* Helper function for A2NLSF(..) */\n/* Polynomial evaluation          */\nstatic OPUS_INLINE opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in Q16     */\n    opus_int32          *p,                     /* I    Polynomial, Q16                         */\n    const opus_int32    x,                      /* I    Evaluation point, Q12                   */\n    const opus_int      dd                      /* I    Order                                   */\n)\n{\n    opus_int   n;\n    opus_int32 x_Q16, y32;\n\n    y32 = p[ dd ];                                  /* Q16 */\n    x_Q16 = silk_LSHIFT( x, 4 );\n\n    if ( opus_likely( 8 == dd ) )\n    {\n        y32 = silk_SMLAWW( p[ 7 ], y32, x_Q16 );\n        y32 = silk_SMLAWW( p[ 6 ], y32, x_Q16 );\n        y32 = silk_SMLAWW( p[ 5 ], y32, x_Q16 );\n        y32 = silk_SMLAWW( p[ 4 ], y32, x_Q16 );\n        y32 = silk_SMLAWW( p[ 3 ], y32, x_Q16 );\n        y32 = silk_SMLAWW( p[ 2 ], y32, x_Q16 );\n        y32 = silk_SMLAWW( p[ 1 ], y32, x_Q16 );\n        y32 = silk_SMLAWW( p[ 0 ], y32, x_Q16 );\n    }\n    else\n    {\n        for( n = dd - 1; n >= 0; n-- ) {\n            y32 = silk_SMLAWW( p[ n ], y32, x_Q16 );    /* Q16 */\n        }\n    }\n    return y32;\n}\n\nstatic OPUS_INLINE void silk_A2NLSF_init(\n     const opus_int32    *a_Q16,\n     opus_int32          *P,\n     opus_int32          *Q,\n     const opus_int      dd\n)\n{\n    opus_int k;\n\n    /* Convert filter coefs to even and odd polynomials */\n    P[dd] = silk_LSHIFT( 1, 16 );\n    Q[dd] = silk_LSHIFT( 1, 16 );\n    for( k = 0; k < dd; k++ ) {\n        P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ];    /* Q16 */\n        Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ];    /* Q16 */\n    }\n\n    /* Divide out zeros as we have that for even filter orders, */\n    /* z =  1 is always a root in Q, and                        */\n    /* z = -1 is always a root in P                             */\n    for( k = dd; k > 0; k-- ) {\n        P[ k - 1 ] -= P[ k ];\n        Q[ k - 1 ] += Q[ k ];\n    }\n\n    /* Transform polynomials from cos(n*f) to cos(f)^n */\n    silk_A2NLSF_trans_poly( P, dd );\n    silk_A2NLSF_trans_poly( Q, dd );\n}\n\n/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients      */\n/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */\nvoid silk_A2NLSF(\n    opus_int16                  *NLSF,              /* O    Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */\n    opus_int32                  *a_Q16,             /* I/O  Monic whitening filter coefficients in Q16 [d]              */\n    const opus_int              d                   /* I    Filter order (must be even)                                 */\n)\n{\n    opus_int      i, k, m, dd, root_ix, ffrac;\n    opus_int32 xlo, xhi, xmid;\n    opus_int32 ylo, yhi, ymid, thr;\n    opus_int32 nom, den;\n    opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ];\n    opus_int32 Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];\n    opus_int32 *PQ[ 2 ];\n    opus_int32 *p;\n\n    /* Store pointers to array */\n    PQ[ 0 ] = P;\n    PQ[ 1 ] = Q;\n\n    dd = silk_RSHIFT( d, 1 );\n\n    silk_A2NLSF_init( a_Q16, P, Q, dd );\n\n    /* Find roots, alternating between P and Q */\n    p = P;                          /* Pointer to polynomial */\n\n    xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/\n    ylo = silk_A2NLSF_eval_poly( p, xlo, dd );\n\n    if( ylo < 0 ) {\n        /* Set the first NLSF to zero and move on to the next */\n        NLSF[ 0 ] = 0;\n        p = Q;                      /* Pointer to polynomial */\n        ylo = silk_A2NLSF_eval_poly( p, xlo, dd );\n        root_ix = 1;                /* Index of current root */\n    } else {\n        root_ix = 0;                /* Index of current root */\n    }\n    k = 1;                          /* Loop counter */\n    i = 0;                          /* Counter for bandwidth expansions applied */\n    thr = 0;\n    while( 1 ) {\n        /* Evaluate polynomial */\n        xhi = silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */\n        yhi = silk_A2NLSF_eval_poly( p, xhi, dd );\n\n        /* Detect zero crossing */\n        if( ( ylo <= 0 && yhi >= thr ) || ( ylo >= 0 && yhi <= -thr ) ) {\n            if( yhi == 0 ) {\n                /* If the root lies exactly at the end of the current       */\n                /* interval, look for the next root in the next interval    */\n                thr = 1;\n            } else {\n                thr = 0;\n            }\n            /* Binary division */\n            ffrac = -256;\n            for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) {\n                /* Evaluate polynomial */\n                xmid = silk_RSHIFT_ROUND( xlo + xhi, 1 );\n                ymid = silk_A2NLSF_eval_poly( p, xmid, dd );\n\n                /* Detect zero crossing */\n                if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) {\n                    /* Reduce frequency */\n                    xhi = xmid;\n                    yhi = ymid;\n                } else {\n                    /* Increase frequency */\n                    xlo = xmid;\n                    ylo = ymid;\n                    ffrac = silk_ADD_RSHIFT( ffrac, 128, m );\n                }\n            }\n\n            /* Interpolate */\n            if( silk_abs( ylo ) < 65536 ) {\n                /* Avoid dividing by zero */\n                den = ylo - yhi;\n                nom = silk_LSHIFT( ylo, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) + silk_RSHIFT( den, 1 );\n                if( den != 0 ) {\n                    ffrac += silk_DIV32( nom, den );\n                }\n            } else {\n                /* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */\n                ffrac += silk_DIV32( ylo, silk_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) );\n            }\n            NLSF[ root_ix ] = (opus_int16)silk_min_32( silk_LSHIFT( (opus_int32)k, 8 ) + ffrac, silk_int16_MAX );\n\n            silk_assert( NLSF[ root_ix ] >= 0 );\n\n            root_ix++;        /* Next root */\n            if( root_ix >= d ) {\n                /* Found all roots */\n                break;\n            }\n            /* Alternate pointer to polynomial */\n            p = PQ[ root_ix & 1 ];\n\n            /* Evaluate polynomial */\n            xlo = silk_LSFCosTab_FIX_Q12[ k - 1 ]; /* Q12*/\n            ylo = silk_LSHIFT( 1 - ( root_ix & 2 ), 12 );\n        } else {\n            /* Increment loop counter */\n            k++;\n            xlo = xhi;\n            ylo = yhi;\n            thr = 0;\n\n            if( k > LSF_COS_TAB_SZ_FIX ) {\n                i++;\n                if( i > MAX_ITERATIONS_A2NLSF_FIX ) {\n                    /* Set NLSFs to white spectrum and exit */\n                    NLSF[ 0 ] = (opus_int16)silk_DIV32_16( 1 << 15, d + 1 );\n                    for( k = 1; k < d; k++ ) {\n                        NLSF[ k ] = (opus_int16)silk_SMULBB( k + 1, NLSF[ 0 ] );\n                    }\n                    return;\n                }\n\n                /* Error: Apply progressively more bandwidth expansion and run again */\n                silk_bwexpander_32( a_Q16, d, 65536 - silk_SMULBB( 10 + i, i ) ); /* 10_Q16 = 0.00015*/\n\n                silk_A2NLSF_init( a_Q16, P, Q, dd );\n                p = P;                            /* Pointer to polynomial */\n                xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/\n                ylo = silk_A2NLSF_eval_poly( p, xlo, dd );\n                if( ylo < 0 ) {\n                    /* Set the first NLSF to zero and move on to the next */\n                    NLSF[ 0 ] = 0;\n                    p = Q;                        /* Pointer to polynomial */\n                    ylo = silk_A2NLSF_eval_poly( p, xlo, dd );\n                    root_ix = 1;                  /* Index of current root */\n                } else {\n                    root_ix = 0;                  /* Index of current root */\n                }\n                k = 1;                            /* Reset loop counter */\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/API.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_API_H\n#define SILK_API_H\n\n#include \"control.h\"\n#include \"typedef.h\"\n#include \"errors.h\"\n#include \"entenc.h\"\n#include \"entdec.h\"\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n#define SILK_MAX_FRAMES_PER_PACKET  3\n\n/* Struct for TOC (Table of Contents) */\ntypedef struct {\n    opus_int    VADFlag;                                /* Voice activity for packet                            */\n    opus_int    VADFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* Voice activity for each frame in packet              */\n    opus_int    inbandFECFlag;                          /* Flag indicating if packet contains in-band FEC       */\n} silk_TOC_struct;\n\n/****************************************/\n/* Encoder functions                    */\n/****************************************/\n\n/***********************************************/\n/* Get size in bytes of the Silk encoder state */\n/***********************************************/\nopus_int silk_Get_Encoder_Size(                         /* O    Returns error code                              */\n    opus_int                        *encSizeBytes       /* O    Number of bytes in SILK encoder state           */\n);\n\n/*************************/\n/* Init or reset encoder */\n/*************************/\nopus_int silk_InitEncoder(                              /* O    Returns error code                              */\n    void                            *encState,          /* I/O  State                                           */\n    int                              arch,              /* I    Run-time architecture                           */\n    silk_EncControlStruct           *encStatus          /* O    Encoder Status                                  */\n);\n\n/**************************/\n/* Encode frame with Silk */\n/**************************/\n/* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what                     */\n/* encControl->payloadSize_ms is set to                                                                         */\nopus_int silk_Encode(                                   /* O    Returns error code                              */\n    void                            *encState,          /* I/O  State                                           */\n    silk_EncControlStruct           *encControl,        /* I    Control status                                  */\n    const opus_int16                *samplesIn,         /* I    Speech sample input vector                      */\n    opus_int                        nSamplesIn,         /* I    Number of samples in input vector               */\n    ec_enc                          *psRangeEnc,        /* I/O  Compressor data structure                       */\n    opus_int32                      *nBytesOut,         /* I/O  Number of bytes in payload (input: Max bytes)   */\n    const opus_int                  prefillFlag         /* I    Flag to indicate prefilling buffers no coding   */\n);\n\n/****************************************/\n/* Decoder functions                    */\n/****************************************/\n\n/***********************************************/\n/* Get size in bytes of the Silk decoder state */\n/***********************************************/\nopus_int silk_Get_Decoder_Size(                         /* O    Returns error code                              */\n    opus_int                        *decSizeBytes       /* O    Number of bytes in SILK decoder state           */\n);\n\n/*************************/\n/* Init or Reset decoder */\n/*************************/\nopus_int silk_InitDecoder(                              /* O    Returns error code                              */\n    void                            *decState           /* I/O  State                                           */\n);\n\n/******************/\n/* Decode a frame */\n/******************/\nopus_int silk_Decode(                                   /* O    Returns error code                              */\n    void*                           decState,           /* I/O  State                                           */\n    silk_DecControlStruct*          decControl,         /* I/O  Control Structure                               */\n    opus_int                        lostFlag,           /* I    0: no loss, 1 loss, 2 decode fec                */\n    opus_int                        newPacketFlag,      /* I    Indicates first decoder call for this packet    */\n    ec_dec                          *psRangeDec,        /* I/O  Compressor data structure                       */\n    opus_int16                      *samplesOut,        /* O    Decoded output speech vector                    */\n    opus_int32                      *nSamplesOut,       /* O    Number of samples decoded                       */\n    int                             arch                /* I    Run-time architecture                           */\n);\n\n#if 0\n/**************************************/\n/* Get table of contents for a packet */\n/**************************************/\nopus_int silk_get_TOC(\n    const opus_uint8                *payload,           /* I    Payload data                                */\n    const opus_int                  nBytesIn,           /* I    Number of input bytes                       */\n    const opus_int                  nFramesPerPayload,  /* I    Number of SILK frames per payload           */\n    silk_TOC_struct                 *Silk_TOC           /* O    Type of content                             */\n);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/CNG.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"stack_alloc.h\"\n\n/* Generates excitation for CNG LPC synthesis */\nstatic OPUS_INLINE void silk_CNG_exc(\n    opus_int32                       exc_Q10[],          /* O    CNG excitation signal Q10                   */\n    opus_int32                       exc_buf_Q14[],      /* I    Random samples buffer Q10                   */\n    opus_int32                       Gain_Q16,           /* I    Gain to apply                               */\n    opus_int                         length,             /* I    Length                                      */\n    opus_int32                       *rand_seed          /* I/O  Seed to random index generator              */\n)\n{\n    opus_int32 seed;\n    opus_int   i, idx, exc_mask;\n\n    exc_mask = CNG_BUF_MASK_MAX;\n    while( exc_mask > length ) {\n        exc_mask = silk_RSHIFT( exc_mask, 1 );\n    }\n\n    seed = *rand_seed;\n    for( i = 0; i < length; i++ ) {\n        seed = silk_RAND( seed );\n        idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask );\n        silk_assert( idx >= 0 );\n        silk_assert( idx <= CNG_BUF_MASK_MAX );\n        exc_Q10[ i ] = (opus_int16)silk_SAT16( silk_SMULWW( exc_buf_Q14[ idx ], Gain_Q16 >> 4 ) );\n    }\n    *rand_seed = seed;\n}\n\nvoid silk_CNG_Reset(\n    silk_decoder_state          *psDec                          /* I/O  Decoder state                               */\n)\n{\n    opus_int i, NLSF_step_Q15, NLSF_acc_Q15;\n\n    NLSF_step_Q15 = silk_DIV32_16( silk_int16_MAX, psDec->LPC_order + 1 );\n    NLSF_acc_Q15 = 0;\n    for( i = 0; i < psDec->LPC_order; i++ ) {\n        NLSF_acc_Q15 += NLSF_step_Q15;\n        psDec->sCNG.CNG_smth_NLSF_Q15[ i ] = NLSF_acc_Q15;\n    }\n    psDec->sCNG.CNG_smth_Gain_Q16 = 0;\n    psDec->sCNG.rand_seed = 3176576;\n}\n\n/* Updates CNG estimate, and applies the CNG when packet was lost   */\nvoid silk_CNG(\n    silk_decoder_state          *psDec,                         /* I/O  Decoder state                               */\n    silk_decoder_control        *psDecCtrl,                     /* I/O  Decoder control                             */\n    opus_int16                  frame[],                        /* I/O  Signal                                      */\n    opus_int                    length                          /* I    Length of residual                          */\n)\n{\n    opus_int   i, subfr;\n    opus_int32 sum_Q6, max_Gain_Q16, gain_Q16;\n    opus_int16 A_Q12[ MAX_LPC_ORDER ];\n    silk_CNG_struct *psCNG = &psDec->sCNG;\n    SAVE_STACK;\n\n    if( psDec->fs_kHz != psCNG->fs_kHz ) {\n        /* Reset state */\n        silk_CNG_Reset( psDec );\n\n        psCNG->fs_kHz = psDec->fs_kHz;\n    }\n    if( psDec->lossCnt == 0 && psDec->prevSignalType == TYPE_NO_VOICE_ACTIVITY ) {\n        /* Update CNG parameters */\n\n        /* Smoothing of LSF's  */\n        for( i = 0; i < psDec->LPC_order; i++ ) {\n            psCNG->CNG_smth_NLSF_Q15[ i ] += silk_SMULWB( (opus_int32)psDec->prevNLSF_Q15[ i ] - (opus_int32)psCNG->CNG_smth_NLSF_Q15[ i ], CNG_NLSF_SMTH_Q16 );\n        }\n        /* Find the subframe with the highest gain */\n        max_Gain_Q16 = 0;\n        subfr        = 0;\n        for( i = 0; i < psDec->nb_subfr; i++ ) {\n            if( psDecCtrl->Gains_Q16[ i ] > max_Gain_Q16 ) {\n                max_Gain_Q16 = psDecCtrl->Gains_Q16[ i ];\n                subfr        = i;\n            }\n        }\n        /* Update CNG excitation buffer with excitation from this subframe */\n        silk_memmove( &psCNG->CNG_exc_buf_Q14[ psDec->subfr_length ], psCNG->CNG_exc_buf_Q14, ( psDec->nb_subfr - 1 ) * psDec->subfr_length * sizeof( opus_int32 ) );\n        silk_memcpy(   psCNG->CNG_exc_buf_Q14, &psDec->exc_Q14[ subfr * psDec->subfr_length ], psDec->subfr_length * sizeof( opus_int32 ) );\n\n        /* Smooth gains */\n        for( i = 0; i < psDec->nb_subfr; i++ ) {\n            psCNG->CNG_smth_Gain_Q16 += silk_SMULWB( psDecCtrl->Gains_Q16[ i ] - psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_Q16 );\n        }\n    }\n\n    /* Add CNG when packet is lost or during DTX */\n    if( psDec->lossCnt ) {\n        VARDECL( opus_int32, CNG_sig_Q10 );\n        ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 );\n\n        /* Generate CNG excitation */\n        gain_Q16 = silk_SMULWW( psDec->sPLC.randScale_Q14, psDec->sPLC.prevGain_Q16[1] );\n        if( gain_Q16 >= (1 << 21) || psCNG->CNG_smth_Gain_Q16 > (1 << 23) ) {\n            gain_Q16 = silk_SMULTT( gain_Q16, gain_Q16 );\n            gain_Q16 = silk_SUB_LSHIFT32(silk_SMULTT( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );\n            gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 16 );\n        } else {\n            gain_Q16 = silk_SMULWW( gain_Q16, gain_Q16 );\n            gain_Q16 = silk_SUB_LSHIFT32(silk_SMULWW( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );\n            gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 );\n        }\n        silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, gain_Q16, length, &psCNG->rand_seed );\n\n        /* Convert CNG NLSF to filter representation */\n        silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order );\n\n        /* Generate CNG signal, by synthesis filtering */\n        silk_memcpy( CNG_sig_Q10, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) );\n        for( i = 0; i < length; i++ ) {\n            silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );\n            /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n            sum_Q6 = silk_RSHIFT( psDec->LPC_order, 1 );\n            sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i -  1 ], A_Q12[ 0 ] );\n            sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i -  2 ], A_Q12[ 1 ] );\n            sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i -  3 ], A_Q12[ 2 ] );\n            sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i -  4 ], A_Q12[ 3 ] );\n            sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i -  5 ], A_Q12[ 4 ] );\n            sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i -  6 ], A_Q12[ 5 ] );\n            sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i -  7 ], A_Q12[ 6 ] );\n            sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i -  8 ], A_Q12[ 7 ] );\n            sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i -  9 ], A_Q12[ 8 ] );\n            sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] );\n            if( psDec->LPC_order == 16 ) {\n                sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] );\n                sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] );\n                sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] );\n                sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] );\n                sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] );\n                sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] );\n            }\n\n            /* Update states */\n            CNG_sig_Q10[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q10[ MAX_LPC_ORDER + i ], sum_Q6, 4 );\n\n            frame[ i ] = silk_ADD_SAT16( frame[ i ], silk_RSHIFT_ROUND( CNG_sig_Q10[ MAX_LPC_ORDER + i ], 10 ) );\n        }\n        silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q10[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );\n    } else {\n        silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order *  sizeof( opus_int32 ) );\n    }\n    RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/HP_variable_cutoff.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#ifdef FIXED_POINT\n#include \"main_FIX.h\"\n#else\n#include \"main_FLP.h\"\n#endif\n#include \"tuning_parameters.h\"\n\n/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */\nvoid silk_HP_variable_cutoff(\n    silk_encoder_state_Fxx          state_Fxx[]                         /* I/O  Encoder states                              */\n)\n{\n   opus_int   quality_Q15;\n   opus_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7;\n   silk_encoder_state *psEncC1 = &state_Fxx[ 0 ].sCmn;\n\n   /* Adaptive cutoff frequency: estimate low end of pitch frequency range */\n   if( psEncC1->prevSignalType == TYPE_VOICED ) {\n      /* difference, in log domain */\n      pitch_freq_Hz_Q16 = silk_DIV32_16( silk_LSHIFT( silk_MUL( psEncC1->fs_kHz, 1000 ), 16 ), psEncC1->prevLag );\n      pitch_freq_log_Q7 = silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 );\n\n      /* adjustment based on quality */\n      quality_Q15 = psEncC1->input_quality_bands_Q15[ 0 ];\n      pitch_freq_log_Q7 = silk_SMLAWB( pitch_freq_log_Q7, silk_SMULWB( silk_LSHIFT( -quality_Q15, 2 ), quality_Q15 ),\n            pitch_freq_log_Q7 - ( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ) ) );\n\n      /* delta_freq = pitch_freq_log - psEnc->variable_HP_smth1; */\n      delta_freq_Q7 = pitch_freq_log_Q7 - silk_RSHIFT( psEncC1->variable_HP_smth1_Q15, 8 );\n      if( delta_freq_Q7 < 0 ) {\n         /* less smoothing for decreasing pitch frequency, to track something close to the minimum */\n         delta_freq_Q7 = silk_MUL( delta_freq_Q7, 3 );\n      }\n\n      /* limit delta, to reduce impact of outliers in pitch estimation */\n      delta_freq_Q7 = silk_LIMIT_32( delta_freq_Q7, -SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ), SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ) );\n\n      /* update smoother */\n      psEncC1->variable_HP_smth1_Q15 = silk_SMLAWB( psEncC1->variable_HP_smth1_Q15,\n            silk_SMULBB( psEncC1->speech_activity_Q8, delta_freq_Q7 ), SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF1, 16 ) );\n\n      /* limit frequency range */\n      psEncC1->variable_HP_smth1_Q15 = silk_LIMIT_32( psEncC1->variable_HP_smth1_Q15,\n            silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ),\n            silk_LSHIFT( silk_lin2log( VARIABLE_HP_MAX_CUTOFF_HZ ), 8 ) );\n   }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/Inlines.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n/*! \\file silk_Inlines.h\n *  \\brief silk_Inlines.h defines OPUS_INLINE signal processing functions.\n */\n\n#ifndef SILK_FIX_INLINES_H\n#define SILK_FIX_INLINES_H\n\n#ifdef  __cplusplus\nextern \"C\"\n{\n#endif\n\n/* count leading zeros of opus_int64 */\nstatic OPUS_INLINE opus_int32 silk_CLZ64( opus_int64 in )\n{\n    opus_int32 in_upper;\n\n    in_upper = (opus_int32)silk_RSHIFT64(in, 32);\n    if (in_upper == 0) {\n        /* Search in the lower 32 bits */\n        return 32 + silk_CLZ32( (opus_int32) in );\n    } else {\n        /* Search in the upper 32 bits */\n        return silk_CLZ32( in_upper );\n    }\n}\n\n/* get number of leading zeros and fractional part (the bits right after the leading one */\nstatic OPUS_INLINE void silk_CLZ_FRAC(\n    opus_int32 in,            /* I  input                               */\n    opus_int32 *lz,           /* O  number of leading zeros             */\n    opus_int32 *frac_Q7       /* O  the 7 bits right after the leading one */\n)\n{\n    opus_int32 lzeros = silk_CLZ32(in);\n\n    * lz = lzeros;\n    * frac_Q7 = silk_ROR32(in, 24 - lzeros) & 0x7f;\n}\n\n/* Approximation of square root                                          */\n/* Accuracy: < +/- 10%  for output values > 15                           */\n/*           < +/- 2.5% for output values > 120                          */\nstatic OPUS_INLINE opus_int32 silk_SQRT_APPROX( opus_int32 x )\n{\n    opus_int32 y, lz, frac_Q7;\n\n    if( x <= 0 ) {\n        return 0;\n    }\n\n    silk_CLZ_FRAC(x, &lz, &frac_Q7);\n\n    if( lz & 1 ) {\n        y = 32768;\n    } else {\n        y = 46214;        /* 46214 = sqrt(2) * 32768 */\n    }\n\n    /* get scaling right */\n    y >>= silk_RSHIFT(lz, 1);\n\n    /* increment using fractional part of input */\n    y = silk_SMLAWB(y, y, silk_SMULBB(213, frac_Q7));\n\n    return y;\n}\n\n/* Divide two int32 values and return result as int32 in a given Q-domain */\nstatic OPUS_INLINE opus_int32 silk_DIV32_varQ(   /* O    returns a good approximation of \"(a32 << Qres) / b32\" */\n    const opus_int32     a32,               /* I    numerator (Q0)                  */\n    const opus_int32     b32,               /* I    denominator (Q0)                */\n    const opus_int       Qres               /* I    Q-domain of result (>= 0)       */\n)\n{\n    opus_int   a_headrm, b_headrm, lshift;\n    opus_int32 b32_inv, a32_nrm, b32_nrm, result;\n\n    silk_assert( b32 != 0 );\n    silk_assert( Qres >= 0 );\n\n    /* Compute number of bits head room and normalize inputs */\n    a_headrm = silk_CLZ32( silk_abs(a32) ) - 1;\n    a32_nrm = silk_LSHIFT(a32, a_headrm);                                       /* Q: a_headrm                  */\n    b_headrm = silk_CLZ32( silk_abs(b32) ) - 1;\n    b32_nrm = silk_LSHIFT(b32, b_headrm);                                       /* Q: b_headrm                  */\n\n    /* Inverse of b32, with 14 bits of precision */\n    b32_inv = silk_DIV32_16( silk_int32_MAX >> 2, silk_RSHIFT(b32_nrm, 16) );   /* Q: 29 + 16 - b_headrm        */\n\n    /* First approximation */\n    result = silk_SMULWB(a32_nrm, b32_inv);                                     /* Q: 29 + a_headrm - b_headrm  */\n\n    /* Compute residual by subtracting product of denominator and first approximation */\n    /* It's OK to overflow because the final value of a32_nrm should always be small */\n    a32_nrm = silk_SUB32_ovflw(a32_nrm, silk_LSHIFT_ovflw( silk_SMMUL(b32_nrm, result), 3 ));  /* Q: a_headrm   */\n\n    /* Refinement */\n    result = silk_SMLAWB(result, a32_nrm, b32_inv);                             /* Q: 29 + a_headrm - b_headrm  */\n\n    /* Convert to Qres domain */\n    lshift = 29 + a_headrm - b_headrm - Qres;\n    if( lshift < 0 ) {\n        return silk_LSHIFT_SAT32(result, -lshift);\n    } else {\n        if( lshift < 32){\n            return silk_RSHIFT(result, lshift);\n        } else {\n            /* Avoid undefined result */\n            return 0;\n        }\n    }\n}\n\n/* Invert int32 value and return result as int32 in a given Q-domain */\nstatic OPUS_INLINE opus_int32 silk_INVERSE32_varQ(   /* O    returns a good approximation of \"(1 << Qres) / b32\" */\n    const opus_int32     b32,                   /* I    denominator (Q0)                */\n    const opus_int       Qres                   /* I    Q-domain of result (> 0)        */\n)\n{\n    opus_int   b_headrm, lshift;\n    opus_int32 b32_inv, b32_nrm, err_Q32, result;\n\n    silk_assert( b32 != 0 );\n    silk_assert( Qres > 0 );\n\n    /* Compute number of bits head room and normalize input */\n    b_headrm = silk_CLZ32( silk_abs(b32) ) - 1;\n    b32_nrm = silk_LSHIFT(b32, b_headrm);                                       /* Q: b_headrm                */\n\n    /* Inverse of b32, with 14 bits of precision */\n    b32_inv = silk_DIV32_16( silk_int32_MAX >> 2, silk_RSHIFT(b32_nrm, 16) );   /* Q: 29 + 16 - b_headrm    */\n\n    /* First approximation */\n    result = silk_LSHIFT(b32_inv, 16);                                          /* Q: 61 - b_headrm            */\n\n    /* Compute residual by subtracting product of denominator and first approximation from one */\n    err_Q32 = silk_LSHIFT( ((opus_int32)1<<29) - silk_SMULWB(b32_nrm, b32_inv), 3 );        /* Q32                        */\n\n    /* Refinement */\n    result = silk_SMLAWW(result, err_Q32, b32_inv);                             /* Q: 61 - b_headrm            */\n\n    /* Convert to Qres domain */\n    lshift = 61 - b_headrm - Qres;\n    if( lshift <= 0 ) {\n        return silk_LSHIFT_SAT32(result, -lshift);\n    } else {\n        if( lshift < 32){\n            return silk_RSHIFT(result, lshift);\n        }else{\n            /* Avoid undefined result */\n            return 0;\n        }\n    }\n}\n\n#ifdef  __cplusplus\n}\n#endif\n\n#endif /* SILK_FIX_INLINES_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/LPC_analysis_filter.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n#include \"celt_lpc.h\"\n\n/*******************************************/\n/* LPC analysis filter                     */\n/* NB! State is kept internally and the    */\n/* filter always starts with zero state    */\n/* first d output samples are set to zero  */\n/*******************************************/\n\nvoid silk_LPC_analysis_filter(\n    opus_int16                  *out,               /* O    Output signal                                               */\n    const opus_int16            *in,                /* I    Input signal                                                */\n    const opus_int16            *B,                 /* I    MA prediction coefficients, Q12 [order]                     */\n    const opus_int32            len,                /* I    Signal length                                               */\n    const opus_int32            d,                  /* I    Filter order                                                */\n    int                         arch                /* I    Run-time architecture                                       */\n)\n{\n    opus_int   j;\n#ifdef FIXED_POINT\n    opus_int16 mem[SILK_MAX_ORDER_LPC];\n    opus_int16 num[SILK_MAX_ORDER_LPC];\n#else\n    int ix;\n    opus_int32       out32_Q12, out32;\n    const opus_int16 *in_ptr;\n#endif\n\n    silk_assert( d >= 6 );\n    silk_assert( (d & 1) == 0 );\n    silk_assert( d <= len );\n\n#ifdef FIXED_POINT\n    silk_assert( d <= SILK_MAX_ORDER_LPC );\n    for ( j = 0; j < d; j++ ) {\n        num[ j ] = -B[ j ];\n    }\n    for (j=0;j<d;j++) {\n        mem[ j ] = in[ d - j - 1 ];\n    }\n    celt_fir( in + d, num, out + d, len - d, d, mem, arch );\n    for ( j = 0; j < d; j++ ) {\n        out[ j ] = 0;\n    }\n#else\n    (void)arch;\n    for( ix = d; ix < len; ix++ ) {\n        in_ptr = &in[ ix - 1 ];\n\n        out32_Q12 = silk_SMULBB( in_ptr[  0 ], B[ 0 ] );\n        /* Allowing wrap around so that two wraps can cancel each other. The rare\n           cases where the result wraps around can only be triggered by invalid streams*/\n        out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -1 ], B[ 1 ] );\n        out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -2 ], B[ 2 ] );\n        out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -3 ], B[ 3 ] );\n        out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -4 ], B[ 4 ] );\n        out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -5 ], B[ 5 ] );\n        for( j = 6; j < d; j += 2 ) {\n            out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -j     ], B[ j     ] );\n            out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -j - 1 ], B[ j + 1 ] );\n        }\n\n        /* Subtract prediction */\n        out32_Q12 = silk_SUB32_ovflw( silk_LSHIFT( (opus_int32)in_ptr[ 1 ], 12 ), out32_Q12 );\n\n        /* Scale to Q0 */\n        out32 = silk_RSHIFT_ROUND( out32_Q12, 12 );\n\n        /* Saturate output */\n        out[ ix ] = (opus_int16)silk_SAT16( out32 );\n    }\n\n    /* Set first d output samples to zero */\n    silk_memset( out, 0, d * sizeof( opus_int16 ) );\n#endif\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/LPC_inv_pred_gain.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n\n#define QA                          24\n#define A_LIMIT                     SILK_FIX_CONST( 0.99975, QA )\n\n#define MUL32_FRAC_Q(a32, b32, Q)   ((opus_int32)(silk_RSHIFT_ROUND64(silk_SMULL(a32, b32), Q)))\n\n/* Compute inverse of LPC prediction gain, and                          */\n/* test if LPC coefficients are stable (all poles within unit circle)   */\nstatic opus_int32 LPC_inverse_pred_gain_QA(                 /* O   Returns inverse prediction gain in energy domain, Q30    */\n    opus_int32           A_QA[ 2 ][ SILK_MAX_ORDER_LPC ],   /* I   Prediction coefficients                                  */\n    const opus_int       order                              /* I   Prediction order                                         */\n)\n{\n    opus_int   k, n, mult2Q;\n    opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp_QA;\n    opus_int32 *Aold_QA, *Anew_QA;\n\n    Anew_QA = A_QA[ order & 1 ];\n\n    invGain_Q30 = (opus_int32)1 << 30;\n    for( k = order - 1; k > 0; k-- ) {\n        /* Check for stability */\n        if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) {\n            return 0;\n        }\n\n        /* Set RC equal to negated AR coef */\n        rc_Q31 = -silk_LSHIFT( Anew_QA[ k ], 31 - QA );\n\n        /* rc_mult1_Q30 range: [ 1 : 2^30 ] */\n        rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );\n        silk_assert( rc_mult1_Q30 > ( 1 << 15 ) );                   /* reduce A_LIMIT if fails */\n        silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) );\n\n        /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */\n        mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );\n        rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );\n\n        /* Update inverse gain */\n        /* invGain_Q30 range: [ 0 : 2^30 ] */\n        invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );\n        silk_assert( invGain_Q30 >= 0           );\n        silk_assert( invGain_Q30 <= ( 1 << 30 ) );\n\n        /* Swap pointers */\n        Aold_QA = Anew_QA;\n        Anew_QA = A_QA[ k & 1 ];\n\n        /* Update AR coefficient */\n        for( n = 0; n < k; n++ ) {\n            tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( Aold_QA[ k - n - 1 ], rc_Q31, 31 );\n            Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q );\n        }\n    }\n\n    /* Check for stability */\n    if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) {\n        return 0;\n    }\n\n    /* Set RC equal to negated AR coef */\n    rc_Q31 = -silk_LSHIFT( Anew_QA[ 0 ], 31 - QA );\n\n    /* Range: [ 1 : 2^30 ] */\n    rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );\n\n    /* Update inverse gain */\n    /* Range: [ 0 : 2^30 ] */\n    invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );\n    silk_assert( invGain_Q30 >= 0     );\n    silk_assert( invGain_Q30 <= 1<<30 );\n\n    return invGain_Q30;\n}\n\n/* For input in Q12 domain */\nopus_int32 silk_LPC_inverse_pred_gain(              /* O   Returns inverse prediction gain in energy domain, Q30        */\n    const opus_int16            *A_Q12,             /* I   Prediction coefficients, Q12 [order]                         */\n    const opus_int              order               /* I   Prediction order                                             */\n)\n{\n    opus_int   k;\n    opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ];\n    opus_int32 *Anew_QA;\n    opus_int32 DC_resp = 0;\n\n    Anew_QA = Atmp_QA[ order & 1 ];\n\n    /* Increase Q domain of the AR coefficients */\n    for( k = 0; k < order; k++ ) {\n        DC_resp += (opus_int32)A_Q12[ k ];\n        Anew_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 );\n    }\n    /* If the DC is unstable, we don't even need to do the full calculations */\n    if( DC_resp >= 4096 ) {\n        return 0;\n    }\n    return LPC_inverse_pred_gain_QA( Atmp_QA, order );\n}\n\n#ifdef FIXED_POINT\n\n/* For input in Q24 domain */\nopus_int32 silk_LPC_inverse_pred_gain_Q24(          /* O    Returns inverse prediction gain in energy domain, Q30       */\n    const opus_int32            *A_Q24,             /* I    Prediction coefficients [order]                             */\n    const opus_int              order               /* I    Prediction order                                            */\n)\n{\n    opus_int   k;\n    opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ];\n    opus_int32 *Anew_QA;\n\n    Anew_QA = Atmp_QA[ order & 1 ];\n\n    /* Increase Q domain of the AR coefficients */\n    for( k = 0; k < order; k++ ) {\n        Anew_QA[ k ] = silk_RSHIFT32( A_Q24[ k ], 24 - QA );\n    }\n\n    return LPC_inverse_pred_gain_QA( Atmp_QA, order );\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/LP_variable_cutoff.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/*\n    Elliptic/Cauer filters designed with 0.1 dB passband ripple,\n    80 dB minimum stopband attenuation, and\n    [0.95 : 0.15 : 0.35] normalized cut off frequencies.\n*/\n\n#include \"main.h\"\n\n/* Helper function, interpolates the filter taps */\nstatic OPUS_INLINE void silk_LP_interpolate_filter_taps(\n    opus_int32           B_Q28[ TRANSITION_NB ],\n    opus_int32           A_Q28[ TRANSITION_NA ],\n    const opus_int       ind,\n    const opus_int32     fac_Q16\n)\n{\n    opus_int nb, na;\n\n    if( ind < TRANSITION_INT_NUM - 1 ) {\n        if( fac_Q16 > 0 ) {\n            if( fac_Q16 < 32768 ) { /* fac_Q16 is in range of a 16-bit int */\n                /* Piece-wise linear interpolation of B and A */\n                for( nb = 0; nb < TRANSITION_NB; nb++ ) {\n                    B_Q28[ nb ] = silk_SMLAWB(\n                        silk_Transition_LP_B_Q28[ ind     ][ nb ],\n                        silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -\n                        silk_Transition_LP_B_Q28[ ind     ][ nb ],\n                        fac_Q16 );\n                }\n                for( na = 0; na < TRANSITION_NA; na++ ) {\n                    A_Q28[ na ] = silk_SMLAWB(\n                        silk_Transition_LP_A_Q28[ ind     ][ na ],\n                        silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -\n                        silk_Transition_LP_A_Q28[ ind     ][ na ],\n                        fac_Q16 );\n                }\n            } else { /* ( fac_Q16 - ( 1 << 16 ) ) is in range of a 16-bit int */\n                silk_assert( fac_Q16 - ( 1 << 16 ) == silk_SAT16( fac_Q16 - ( 1 << 16 ) ) );\n                /* Piece-wise linear interpolation of B and A */\n                for( nb = 0; nb < TRANSITION_NB; nb++ ) {\n                    B_Q28[ nb ] = silk_SMLAWB(\n                        silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],\n                        silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -\n                        silk_Transition_LP_B_Q28[ ind     ][ nb ],\n                        fac_Q16 - ( (opus_int32)1 << 16 ) );\n                }\n                for( na = 0; na < TRANSITION_NA; na++ ) {\n                    A_Q28[ na ] = silk_SMLAWB(\n                        silk_Transition_LP_A_Q28[ ind + 1 ][ na ],\n                        silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -\n                        silk_Transition_LP_A_Q28[ ind     ][ na ],\n                        fac_Q16 - ( (opus_int32)1 << 16 ) );\n                }\n            }\n        } else {\n            silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( opus_int32 ) );\n            silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( opus_int32 ) );\n        }\n    } else {\n        silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( opus_int32 ) );\n        silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( opus_int32 ) );\n    }\n}\n\n/* Low-pass filter with variable cutoff frequency based on  */\n/* piece-wise linear interpolation between elliptic filters */\n/* Start by setting psEncC->mode <> 0;                      */\n/* Deactivate by setting psEncC->mode = 0;                  */\nvoid silk_LP_variable_cutoff(\n    silk_LP_state               *psLP,                          /* I/O  LP filter state                             */\n    opus_int16                  *frame,                         /* I/O  Low-pass filtered output signal             */\n    const opus_int              frame_length                    /* I    Frame length                                */\n)\n{\n    opus_int32   B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0;\n    opus_int     ind = 0;\n\n    silk_assert( psLP->transition_frame_no >= 0 && psLP->transition_frame_no <= TRANSITION_FRAMES );\n\n    /* Run filter if needed */\n    if( psLP->mode != 0 ) {\n        /* Calculate index and interpolation factor for interpolation */\n#if( TRANSITION_INT_STEPS == 64 )\n        fac_Q16 = silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 - 6 );\n#else\n        fac_Q16 = silk_DIV32_16( silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 ), TRANSITION_FRAMES );\n#endif\n        ind      = silk_RSHIFT( fac_Q16, 16 );\n        fac_Q16 -= silk_LSHIFT( ind, 16 );\n\n        silk_assert( ind >= 0 );\n        silk_assert( ind < TRANSITION_INT_NUM );\n\n        /* Interpolate filter coefficients */\n        silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 );\n\n        /* Update transition frame number for next frame */\n        psLP->transition_frame_no = silk_LIMIT( psLP->transition_frame_no + psLP->mode, 0, TRANSITION_FRAMES );\n\n        /* ARMA low-pass filtering */\n        silk_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 );\n        silk_biquad_alt( frame, B_Q28, A_Q28, psLP->In_LP_State, frame, frame_length, 1);\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/MacroCount.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SIGPROCFIX_API_MACROCOUNT_H\n#define SIGPROCFIX_API_MACROCOUNT_H\n#include <stdio.h>\n\n#ifdef    silk_MACRO_COUNT\n#define varDefine opus_int64 ops_count = 0;\n\nextern opus_int64 ops_count;\n\nstatic OPUS_INLINE opus_int64 silk_SaveCount(){\n    return(ops_count);\n}\n\nstatic OPUS_INLINE opus_int64 silk_SaveResetCount(){\n    opus_int64 ret;\n\n    ret = ops_count;\n    ops_count = 0;\n    return(ret);\n}\n\nstatic OPUS_INLINE silk_PrintCount(){\n    printf(\"ops_count = %d \\n \", (opus_int32)ops_count);\n}\n\n#undef silk_MUL\nstatic OPUS_INLINE opus_int32 silk_MUL(opus_int32 a32, opus_int32 b32){\n    opus_int32 ret;\n    ops_count += 4;\n    ret = a32 * b32;\n    return ret;\n}\n\n#undef silk_MUL_uint\nstatic OPUS_INLINE opus_uint32 silk_MUL_uint(opus_uint32 a32, opus_uint32 b32){\n    opus_uint32 ret;\n    ops_count += 4;\n    ret = a32 * b32;\n    return ret;\n}\n#undef silk_MLA\nstatic OPUS_INLINE opus_int32 silk_MLA(opus_int32 a32, opus_int32 b32, opus_int32 c32){\n    opus_int32 ret;\n    ops_count += 4;\n    ret = a32 + b32 * c32;\n    return ret;\n}\n\n#undef silk_MLA_uint\nstatic OPUS_INLINE opus_int32 silk_MLA_uint(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32){\n    opus_uint32 ret;\n    ops_count += 4;\n    ret = a32 + b32 * c32;\n    return ret;\n}\n\n#undef silk_SMULWB\nstatic OPUS_INLINE opus_int32 silk_SMULWB(opus_int32 a32, opus_int32 b32){\n    opus_int32 ret;\n    ops_count += 5;\n    ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16);\n    return ret;\n}\n#undef    silk_SMLAWB\nstatic OPUS_INLINE opus_int32 silk_SMLAWB(opus_int32 a32, opus_int32 b32, opus_int32 c32){\n    opus_int32 ret;\n    ops_count += 5;\n    ret = ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16)));\n    return ret;\n}\n\n#undef silk_SMULWT\nstatic OPUS_INLINE opus_int32 silk_SMULWT(opus_int32 a32, opus_int32 b32){\n    opus_int32 ret;\n    ops_count += 4;\n    ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16);\n    return ret;\n}\n#undef silk_SMLAWT\nstatic OPUS_INLINE opus_int32 silk_SMLAWT(opus_int32 a32, opus_int32 b32, opus_int32 c32){\n    opus_int32 ret;\n    ops_count += 4;\n    ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16));\n    return ret;\n}\n\n#undef silk_SMULBB\nstatic OPUS_INLINE opus_int32 silk_SMULBB(opus_int32 a32, opus_int32 b32){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = (opus_int32)((opus_int16)a32) * (opus_int32)((opus_int16)b32);\n    return ret;\n}\n#undef silk_SMLABB\nstatic OPUS_INLINE opus_int32 silk_SMLABB(opus_int32 a32, opus_int32 b32, opus_int32 c32){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32);\n    return ret;\n}\n\n#undef silk_SMULBT\nstatic OPUS_INLINE opus_int32 silk_SMULBT(opus_int32 a32, opus_int32 b32 ){\n    opus_int32 ret;\n    ops_count += 4;\n    ret = ((opus_int32)((opus_int16)a32)) * (b32 >> 16);\n    return ret;\n}\n\n#undef silk_SMLABT\nstatic OPUS_INLINE opus_int32 silk_SMLABT(opus_int32 a32, opus_int32 b32, opus_int32 c32){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16);\n    return ret;\n}\n\n#undef silk_SMULTT\nstatic OPUS_INLINE opus_int32 silk_SMULTT(opus_int32 a32, opus_int32 b32){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = (a32 >> 16) * (b32 >> 16);\n    return ret;\n}\n\n#undef    silk_SMLATT\nstatic OPUS_INLINE opus_int32 silk_SMLATT(opus_int32 a32, opus_int32 b32, opus_int32 c32){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = a32 + (b32 >> 16) * (c32 >> 16);\n    return ret;\n}\n\n\n/* multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode)*/\n#undef    silk_MLA_ovflw\n#define silk_MLA_ovflw silk_MLA\n\n#undef silk_SMLABB_ovflw\n#define silk_SMLABB_ovflw silk_SMLABB\n\n#undef silk_SMLABT_ovflw\n#define silk_SMLABT_ovflw silk_SMLABT\n\n#undef silk_SMLATT_ovflw\n#define silk_SMLATT_ovflw silk_SMLATT\n\n#undef silk_SMLAWB_ovflw\n#define silk_SMLAWB_ovflw silk_SMLAWB\n\n#undef silk_SMLAWT_ovflw\n#define silk_SMLAWT_ovflw silk_SMLAWT\n\n#undef silk_SMULL\nstatic OPUS_INLINE opus_int64 silk_SMULL(opus_int32 a32, opus_int32 b32){\n    opus_int64 ret;\n    ops_count += 8;\n    ret = ((opus_int64)(a32) * /*(opus_int64)*/(b32));\n    return ret;\n}\n\n#undef    silk_SMLAL\nstatic OPUS_INLINE opus_int64 silk_SMLAL(opus_int64 a64, opus_int32 b32, opus_int32 c32){\n    opus_int64 ret;\n    ops_count += 8;\n    ret = a64 + ((opus_int64)(b32) * /*(opus_int64)*/(c32));\n    return ret;\n}\n#undef    silk_SMLALBB\nstatic OPUS_INLINE opus_int64 silk_SMLALBB(opus_int64 a64, opus_int16 b16, opus_int16 c16){\n    opus_int64 ret;\n    ops_count += 4;\n    ret = a64 + ((opus_int64)(b16) * /*(opus_int64)*/(c16));\n    return ret;\n}\n\n#undef    SigProcFIX_CLZ16\nstatic OPUS_INLINE opus_int32 SigProcFIX_CLZ16(opus_int16 in16)\n{\n    opus_int32 out32 = 0;\n    ops_count += 10;\n    if( in16 == 0 ) {\n        return 16;\n    }\n    /* test nibbles */\n    if( in16 & 0xFF00 ) {\n        if( in16 & 0xF000 ) {\n            in16 >>= 12;\n        } else {\n            out32 += 4;\n            in16 >>= 8;\n        }\n    } else {\n        if( in16 & 0xFFF0 ) {\n            out32 += 8;\n            in16 >>= 4;\n        } else {\n            out32 += 12;\n        }\n    }\n    /* test bits and return */\n    if( in16 & 0xC ) {\n        if( in16 & 0x8 )\n            return out32 + 0;\n        else\n            return out32 + 1;\n    } else {\n        if( in16 & 0xE )\n            return out32 + 2;\n        else\n            return out32 + 3;\n    }\n}\n\n#undef SigProcFIX_CLZ32\nstatic OPUS_INLINE opus_int32 SigProcFIX_CLZ32(opus_int32 in32)\n{\n    /* test highest 16 bits and convert to opus_int16 */\n    ops_count += 2;\n    if( in32 & 0xFFFF0000 ) {\n        return SigProcFIX_CLZ16((opus_int16)(in32 >> 16));\n    } else {\n        return SigProcFIX_CLZ16((opus_int16)in32) + 16;\n    }\n}\n\n#undef silk_DIV32\nstatic OPUS_INLINE opus_int32 silk_DIV32(opus_int32 a32, opus_int32 b32){\n    ops_count += 64;\n    return a32 / b32;\n}\n\n#undef silk_DIV32_16\nstatic OPUS_INLINE opus_int32 silk_DIV32_16(opus_int32 a32, opus_int32 b32){\n    ops_count += 32;\n    return a32 / b32;\n}\n\n#undef silk_SAT8\nstatic OPUS_INLINE opus_int8 silk_SAT8(opus_int64 a){\n    opus_int8 tmp;\n    ops_count += 1;\n    tmp = (opus_int8)((a) > silk_int8_MAX ? silk_int8_MAX  : \\\n                    ((a) < silk_int8_MIN ? silk_int8_MIN  : (a)));\n    return(tmp);\n}\n\n#undef silk_SAT16\nstatic OPUS_INLINE opus_int16 silk_SAT16(opus_int64 a){\n    opus_int16 tmp;\n    ops_count += 1;\n    tmp = (opus_int16)((a) > silk_int16_MAX ? silk_int16_MAX  : \\\n                     ((a) < silk_int16_MIN ? silk_int16_MIN  : (a)));\n    return(tmp);\n}\n#undef silk_SAT32\nstatic OPUS_INLINE opus_int32 silk_SAT32(opus_int64 a){\n    opus_int32 tmp;\n    ops_count += 1;\n    tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX  : \\\n                     ((a) < silk_int32_MIN ? silk_int32_MIN  : (a)));\n    return(tmp);\n}\n#undef silk_POS_SAT32\nstatic OPUS_INLINE opus_int32 silk_POS_SAT32(opus_int64 a){\n    opus_int32 tmp;\n    ops_count += 1;\n    tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX : (a));\n    return(tmp);\n}\n\n#undef silk_ADD_POS_SAT8\nstatic OPUS_INLINE opus_int8 silk_ADD_POS_SAT8(opus_int64 a, opus_int64 b){\n    opus_int8 tmp;\n    ops_count += 1;\n    tmp = (opus_int8)((((a)+(b)) & 0x80) ? silk_int8_MAX  : ((a)+(b)));\n    return(tmp);\n}\n#undef silk_ADD_POS_SAT16\nstatic OPUS_INLINE opus_int16 silk_ADD_POS_SAT16(opus_int64 a, opus_int64 b){\n    opus_int16 tmp;\n    ops_count += 1;\n    tmp = (opus_int16)((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b)));\n    return(tmp);\n}\n\n#undef silk_ADD_POS_SAT32\nstatic OPUS_INLINE opus_int32 silk_ADD_POS_SAT32(opus_int64 a, opus_int64 b){\n    opus_int32 tmp;\n    ops_count += 1;\n    tmp = (opus_int32)((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b)));\n    return(tmp);\n}\n\n#undef silk_ADD_POS_SAT64\nstatic OPUS_INLINE opus_int64 silk_ADD_POS_SAT64(opus_int64 a, opus_int64 b){\n    opus_int64 tmp;\n    ops_count += 1;\n    tmp = ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)));\n    return(tmp);\n}\n\n#undef    silk_LSHIFT8\nstatic OPUS_INLINE opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){\n    opus_int8 ret;\n    ops_count += 1;\n    ret = a << shift;\n    return ret;\n}\n#undef    silk_LSHIFT16\nstatic OPUS_INLINE opus_int16 silk_LSHIFT16(opus_int16 a, opus_int32 shift){\n    opus_int16 ret;\n    ops_count += 1;\n    ret = a << shift;\n    return ret;\n}\n#undef    silk_LSHIFT32\nstatic OPUS_INLINE opus_int32 silk_LSHIFT32(opus_int32 a, opus_int32 shift){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = a << shift;\n    return ret;\n}\n#undef    silk_LSHIFT64\nstatic OPUS_INLINE opus_int64 silk_LSHIFT64(opus_int64 a, opus_int shift){\n    ops_count += 1;\n    return a << shift;\n}\n\n#undef    silk_LSHIFT_ovflw\nstatic OPUS_INLINE opus_int32 silk_LSHIFT_ovflw(opus_int32 a, opus_int32 shift){\n    ops_count += 1;\n    return a << shift;\n}\n\n#undef    silk_LSHIFT_uint\nstatic OPUS_INLINE opus_uint32 silk_LSHIFT_uint(opus_uint32 a, opus_int32 shift){\n    opus_uint32 ret;\n    ops_count += 1;\n    ret = a << shift;\n    return ret;\n}\n\n#undef    silk_RSHIFT8\nstatic OPUS_INLINE opus_int8 silk_RSHIFT8(opus_int8 a, opus_int32 shift){\n    ops_count += 1;\n    return a >> shift;\n}\n#undef    silk_RSHIFT16\nstatic OPUS_INLINE opus_int16 silk_RSHIFT16(opus_int16 a, opus_int32 shift){\n    ops_count += 1;\n    return a >> shift;\n}\n#undef    silk_RSHIFT32\nstatic OPUS_INLINE opus_int32 silk_RSHIFT32(opus_int32 a, opus_int32 shift){\n    ops_count += 1;\n    return a >> shift;\n}\n#undef    silk_RSHIFT64\nstatic OPUS_INLINE opus_int64 silk_RSHIFT64(opus_int64 a, opus_int64 shift){\n    ops_count += 1;\n    return a >> shift;\n}\n\n#undef    silk_RSHIFT_uint\nstatic OPUS_INLINE opus_uint32 silk_RSHIFT_uint(opus_uint32 a, opus_int32 shift){\n    ops_count += 1;\n    return a >> shift;\n}\n\n#undef    silk_ADD_LSHIFT\nstatic OPUS_INLINE opus_int32 silk_ADD_LSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = a + (b << shift);\n    return ret;                /* shift >= 0*/\n}\n#undef    silk_ADD_LSHIFT32\nstatic OPUS_INLINE opus_int32 silk_ADD_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = a + (b << shift);\n    return ret;                /* shift >= 0*/\n}\n#undef    silk_ADD_LSHIFT_uint\nstatic OPUS_INLINE opus_uint32 silk_ADD_LSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){\n    opus_uint32 ret;\n    ops_count += 1;\n    ret = a + (b << shift);\n    return ret;                /* shift >= 0*/\n}\n#undef    silk_ADD_RSHIFT\nstatic OPUS_INLINE opus_int32 silk_ADD_RSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = a + (b >> shift);\n    return ret;                /* shift  > 0*/\n}\n#undef    silk_ADD_RSHIFT32\nstatic OPUS_INLINE opus_int32 silk_ADD_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = a + (b >> shift);\n    return ret;                /* shift  > 0*/\n}\n#undef    silk_ADD_RSHIFT_uint\nstatic OPUS_INLINE opus_uint32 silk_ADD_RSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){\n    opus_uint32 ret;\n    ops_count += 1;\n    ret = a + (b >> shift);\n    return ret;                /* shift  > 0*/\n}\n#undef    silk_SUB_LSHIFT32\nstatic OPUS_INLINE opus_int32 silk_SUB_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = a - (b << shift);\n    return ret;                /* shift >= 0*/\n}\n#undef    silk_SUB_RSHIFT32\nstatic OPUS_INLINE opus_int32 silk_SUB_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = a - (b >> shift);\n    return ret;                /* shift  > 0*/\n}\n\n#undef    silk_RSHIFT_ROUND\nstatic OPUS_INLINE opus_int32 silk_RSHIFT_ROUND(opus_int32 a, opus_int32 shift){\n    opus_int32 ret;\n    ops_count += 3;\n    ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;\n    return ret;\n}\n\n#undef    silk_RSHIFT_ROUND64\nstatic OPUS_INLINE opus_int64 silk_RSHIFT_ROUND64(opus_int64 a, opus_int32 shift){\n    opus_int64 ret;\n    ops_count += 6;\n    ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;\n    return ret;\n}\n\n#undef    silk_abs_int64\nstatic OPUS_INLINE opus_int64 silk_abs_int64(opus_int64 a){\n    ops_count += 1;\n    return (((a) >  0)  ? (a) : -(a));            /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN*/\n}\n\n#undef    silk_abs_int32\nstatic OPUS_INLINE opus_int32 silk_abs_int32(opus_int32 a){\n    ops_count += 1;\n    return silk_abs(a);\n}\n\n\n#undef silk_min\nstatic silk_min(a, b){\n    ops_count += 1;\n    return (((a) < (b)) ? (a) :  (b));\n}\n#undef silk_max\nstatic silk_max(a, b){\n    ops_count += 1;\n    return (((a) > (b)) ? (a) :  (b));\n}\n#undef silk_sign\nstatic silk_sign(a){\n    ops_count += 1;\n    return ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 ));\n}\n\n#undef    silk_ADD16\nstatic OPUS_INLINE opus_int16 silk_ADD16(opus_int16 a, opus_int16 b){\n    opus_int16 ret;\n    ops_count += 1;\n    ret = a + b;\n    return ret;\n}\n\n#undef    silk_ADD32\nstatic OPUS_INLINE opus_int32 silk_ADD32(opus_int32 a, opus_int32 b){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = a + b;\n    return ret;\n}\n\n#undef    silk_ADD64\nstatic OPUS_INLINE opus_int64 silk_ADD64(opus_int64 a, opus_int64 b){\n    opus_int64 ret;\n    ops_count += 2;\n    ret = a + b;\n    return ret;\n}\n\n#undef    silk_SUB16\nstatic OPUS_INLINE opus_int16 silk_SUB16(opus_int16 a, opus_int16 b){\n    opus_int16 ret;\n    ops_count += 1;\n    ret = a - b;\n    return ret;\n}\n\n#undef    silk_SUB32\nstatic OPUS_INLINE opus_int32 silk_SUB32(opus_int32 a, opus_int32 b){\n    opus_int32 ret;\n    ops_count += 1;\n    ret = a - b;\n    return ret;\n}\n\n#undef    silk_SUB64\nstatic OPUS_INLINE opus_int64 silk_SUB64(opus_int64 a, opus_int64 b){\n    opus_int64 ret;\n    ops_count += 2;\n    ret = a - b;\n    return ret;\n}\n\n#undef silk_ADD_SAT16\nstatic OPUS_INLINE opus_int16 silk_ADD_SAT16( opus_int16 a16, opus_int16 b16 ) {\n    opus_int16 res;\n    /* Nb will be counted in AKP_add32 and silk_SAT16*/\n    res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) );\n    return res;\n}\n\n#undef silk_ADD_SAT32\nstatic OPUS_INLINE opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){\n    opus_int32 res;\n    ops_count += 1;\n    res =    ((((a32) + (b32)) & 0x80000000) == 0 ?                                    \\\n            ((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) :    \\\n            ((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) );\n    return res;\n}\n\n#undef silk_ADD_SAT64\nstatic OPUS_INLINE opus_int64 silk_ADD_SAT64( opus_int64 a64, opus_int64 b64 ) {\n    opus_int64 res;\n    ops_count += 1;\n    res =    ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ?                                \\\n            ((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) :    \\\n            ((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a64)+(b64)) );\n    return res;\n}\n\n#undef silk_SUB_SAT16\nstatic OPUS_INLINE opus_int16 silk_SUB_SAT16( opus_int16 a16, opus_int16 b16 ) {\n    opus_int16 res;\n    silk_assert(0);\n    /* Nb will be counted in sub-macros*/\n    res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) );\n    return res;\n}\n\n#undef silk_SUB_SAT32\nstatic OPUS_INLINE opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) {\n    opus_int32 res;\n    ops_count += 1;\n    res =     ((((a32)-(b32)) & 0x80000000) == 0 ?                                            \\\n            (( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) :    \\\n            ((((a32)^0x80000000) & (b32)  & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) );\n    return res;\n}\n\n#undef silk_SUB_SAT64\nstatic OPUS_INLINE opus_int64 silk_SUB_SAT64( opus_int64 a64, opus_int64 b64 ) {\n    opus_int64 res;\n    ops_count += 1;\n    res =    ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ?                                                        \\\n            (( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) :    \\\n            ((((a64)^0x8000000000000000LL) & (b64)  & 0x8000000000000000LL) ? silk_int64_MAX : (a64)-(b64)) );\n\n    return res;\n}\n\n#undef    silk_SMULWW\nstatic OPUS_INLINE opus_int32 silk_SMULWW(opus_int32 a32, opus_int32 b32){\n    opus_int32 ret;\n    /* Nb will be counted in sub-macros*/\n    ret = silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16));\n    return ret;\n}\n\n#undef    silk_SMLAWW\nstatic OPUS_INLINE opus_int32 silk_SMLAWW(opus_int32 a32, opus_int32 b32, opus_int32 c32){\n    opus_int32 ret;\n    /* Nb will be counted in sub-macros*/\n    ret = silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16));\n    return ret;\n}\n\n#undef    silk_min_int\nstatic OPUS_INLINE opus_int silk_min_int(opus_int a, opus_int b)\n{\n    ops_count += 1;\n    return (((a) < (b)) ? (a) : (b));\n}\n\n#undef    silk_min_16\nstatic OPUS_INLINE opus_int16 silk_min_16(opus_int16 a, opus_int16 b)\n{\n    ops_count += 1;\n    return (((a) < (b)) ? (a) : (b));\n}\n#undef    silk_min_32\nstatic OPUS_INLINE opus_int32 silk_min_32(opus_int32 a, opus_int32 b)\n{\n    ops_count += 1;\n    return (((a) < (b)) ? (a) : (b));\n}\n#undef    silk_min_64\nstatic OPUS_INLINE opus_int64 silk_min_64(opus_int64 a, opus_int64 b)\n{\n    ops_count += 1;\n    return (((a) < (b)) ? (a) : (b));\n}\n\n/* silk_min() versions with typecast in the function call */\n#undef    silk_max_int\nstatic OPUS_INLINE opus_int silk_max_int(opus_int a, opus_int b)\n{\n    ops_count += 1;\n    return (((a) > (b)) ? (a) : (b));\n}\n#undef    silk_max_16\nstatic OPUS_INLINE opus_int16 silk_max_16(opus_int16 a, opus_int16 b)\n{\n    ops_count += 1;\n    return (((a) > (b)) ? (a) : (b));\n}\n#undef    silk_max_32\nstatic OPUS_INLINE opus_int32 silk_max_32(opus_int32 a, opus_int32 b)\n{\n    ops_count += 1;\n    return (((a) > (b)) ? (a) : (b));\n}\n\n#undef    silk_max_64\nstatic OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b)\n{\n    ops_count += 1;\n    return (((a) > (b)) ? (a) : (b));\n}\n\n\n#undef silk_LIMIT_int\nstatic OPUS_INLINE opus_int silk_LIMIT_int(opus_int a, opus_int limit1, opus_int limit2)\n{\n    opus_int ret;\n    ops_count += 6;\n\n    ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \\\n        : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a))));\n\n    return(ret);\n}\n\n#undef silk_LIMIT_16\nstatic OPUS_INLINE opus_int16 silk_LIMIT_16(opus_int16 a, opus_int16 limit1, opus_int16 limit2)\n{\n    opus_int16 ret;\n    ops_count += 6;\n\n    ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \\\n        : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a))));\n\nreturn(ret);\n}\n\n\n#undef silk_LIMIT_32\nstatic OPUS_INLINE opus_int silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2)\n{\n    opus_int32 ret;\n    ops_count += 6;\n\n    ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \\\n        : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a))));\n    return(ret);\n}\n\n#else\n#define varDefine\n#define silk_SaveCount()\n\n#endif\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/MacroDebug.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nCopyright (C) 2012 Xiph.Org Foundation\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef MACRO_DEBUG_H\n#define MACRO_DEBUG_H\n\n/* Redefine macro functions with extensive assertion in DEBUG mode.\n   As functions can't be undefined, this file can't work with SigProcFIX_MacroCount.h */\n\n#if ( defined (FIXED_DEBUG) || ( 0 && defined (_DEBUG) ) ) && !defined (silk_MACRO_COUNT)\n\n#undef silk_ADD16\n#define silk_ADD16(a,b) silk_ADD16_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int16 silk_ADD16_(opus_int16 a, opus_int16 b, char *file, int line){\n    opus_int16 ret;\n\n    ret = a + b;\n    if ( ret != silk_ADD_SAT16( a, b ) )\n    {\n        fprintf (stderr, \"silk_ADD16(%d, %d) in %s: line %d\\n\", a, b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_ADD32\n#define silk_ADD32(a,b) silk_ADD32_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_ADD32_(opus_int32 a, opus_int32 b, char *file, int line){\n    opus_int32 ret;\n\n    ret = a + b;\n    if ( ret != silk_ADD_SAT32( a, b ) )\n    {\n        fprintf (stderr, \"silk_ADD32(%d, %d) in %s: line %d\\n\", a, b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_ADD64\n#define silk_ADD64(a,b) silk_ADD64_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int64 silk_ADD64_(opus_int64 a, opus_int64 b, char *file, int line){\n    opus_int64 ret;\n\n    ret = a + b;\n    if ( ret != silk_ADD_SAT64( a, b ) )\n    {\n        fprintf (stderr, \"silk_ADD64(%lld, %lld) in %s: line %d\\n\", (long long)a, (long long)b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_SUB16\n#define silk_SUB16(a,b) silk_SUB16_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int16 silk_SUB16_(opus_int16 a, opus_int16 b, char *file, int line){\n    opus_int16 ret;\n\n    ret = a - b;\n    if ( ret != silk_SUB_SAT16( a, b ) )\n    {\n        fprintf (stderr, \"silk_SUB16(%d, %d) in %s: line %d\\n\", a, b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_SUB32\n#define silk_SUB32(a,b) silk_SUB32_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_SUB32_(opus_int32 a, opus_int32 b, char *file, int line){\n    opus_int32 ret;\n\n    ret = a - b;\n    if ( ret != silk_SUB_SAT32( a, b ) )\n    {\n        fprintf (stderr, \"silk_SUB32(%d, %d) in %s: line %d\\n\", a, b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_SUB64\n#define silk_SUB64(a,b) silk_SUB64_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int64 silk_SUB64_(opus_int64 a, opus_int64 b, char *file, int line){\n    opus_int64 ret;\n\n    ret = a - b;\n    if ( ret != silk_SUB_SAT64( a, b ) )\n    {\n        fprintf (stderr, \"silk_SUB64(%lld, %lld) in %s: line %d\\n\", (long long)a, (long long)b, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_ADD_SAT16\n#define silk_ADD_SAT16(a,b) silk_ADD_SAT16_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int16 silk_ADD_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line) {\n    opus_int16 res;\n    res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) );\n    if ( res != silk_SAT16( (opus_int32)a16 + (opus_int32)b16 ) )\n    {\n        fprintf (stderr, \"silk_ADD_SAT16(%d, %d) in %s: line %d\\n\", a16, b16, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return res;\n}\n\n#undef silk_ADD_SAT32\n#define silk_ADD_SAT32(a,b) silk_ADD_SAT32_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_ADD_SAT32_(opus_int32 a32, opus_int32 b32, char *file, int line){\n    opus_int32 res;\n    res =   ((((opus_uint32)(a32) + (opus_uint32)(b32)) & 0x80000000) == 0 ?       \\\n            ((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \\\n            ((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) );\n    if ( res != silk_SAT32( (opus_int64)a32 + (opus_int64)b32 ) )\n    {\n        fprintf (stderr, \"silk_ADD_SAT32(%d, %d) in %s: line %d\\n\", a32, b32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return res;\n}\n\n#undef silk_ADD_SAT64\n#define silk_ADD_SAT64(a,b) silk_ADD_SAT64_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int64 silk_ADD_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line) {\n    opus_int64 res;\n    int        fail = 0;\n    res =   ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ?                                 \\\n            ((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) : \\\n            ((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a64)+(b64)) );\n    if( res != a64 + b64 ) {\n        /* Check that we saturated to the correct extreme value */\n        if ( !(( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) ||\n               ( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) ) )\n        {\n            fail = 1;\n        }\n    } else {\n        /* Saturation not necessary */\n        fail = res != a64 + b64;\n    }\n    if ( fail )\n    {\n        fprintf (stderr, \"silk_ADD_SAT64(%lld, %lld) in %s: line %d\\n\", (long long)a64, (long long)b64, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return res;\n}\n\n#undef silk_SUB_SAT16\n#define silk_SUB_SAT16(a,b) silk_SUB_SAT16_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int16 silk_SUB_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line ) {\n    opus_int16 res;\n    res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) );\n    if ( res != silk_SAT16( (opus_int32)a16 - (opus_int32)b16 ) )\n    {\n        fprintf (stderr, \"silk_SUB_SAT16(%d, %d) in %s: line %d\\n\", a16, b16, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return res;\n}\n\n#undef silk_SUB_SAT32\n#define silk_SUB_SAT32(a,b) silk_SUB_SAT32_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_SUB_SAT32_( opus_int32 a32, opus_int32 b32, char *file, int line ) {\n    opus_int32 res;\n    res =   ((((opus_uint32)(a32)-(opus_uint32)(b32)) & 0x80000000) == 0 ?                \\\n            (( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \\\n            ((((a32)^0x80000000) & (b32)  & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) );\n    if ( res != silk_SAT32( (opus_int64)a32 - (opus_int64)b32 ) )\n    {\n        fprintf (stderr, \"silk_SUB_SAT32(%d, %d) in %s: line %d\\n\", a32, b32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return res;\n}\n\n#undef silk_SUB_SAT64\n#define silk_SUB_SAT64(a,b) silk_SUB_SAT64_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int64 silk_SUB_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line ) {\n    opus_int64 res;\n    int        fail = 0;\n    res =   ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ?                                                    \\\n            (( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) : \\\n            ((((a64)^0x8000000000000000LL) & (b64)  & 0x8000000000000000LL) ? silk_int64_MAX : (a64)-(b64)) );\n    if( res != a64 - b64 ) {\n        /* Check that we saturated to the correct extreme value */\n        if( !(( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) ||\n              ( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) ))\n        {\n            fail = 1;\n        }\n    } else {\n        /* Saturation not necessary */\n        fail = res != a64 - b64;\n    }\n    if ( fail )\n    {\n        fprintf (stderr, \"silk_SUB_SAT64(%lld, %lld) in %s: line %d\\n\", (long long)a64, (long long)b64, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return res;\n}\n\n#undef silk_MUL\n#define silk_MUL(a,b) silk_MUL_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_MUL_(opus_int32 a32, opus_int32 b32, char *file, int line){\n    opus_int32 ret;\n    opus_int64 ret64;\n    ret = a32 * b32;\n    ret64 = (opus_int64)a32 * (opus_int64)b32;\n    if ( (opus_int64)ret != ret64 )\n    {\n        fprintf (stderr, \"silk_MUL(%d, %d) in %s: line %d\\n\", a32, b32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_MUL_uint\n#define silk_MUL_uint(a,b) silk_MUL_uint_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_uint32 silk_MUL_uint_(opus_uint32 a32, opus_uint32 b32, char *file, int line){\n    opus_uint32 ret;\n    ret = a32 * b32;\n    if ( (opus_uint64)ret != (opus_uint64)a32 * (opus_uint64)b32 )\n    {\n        fprintf (stderr, \"silk_MUL_uint(%u, %u) in %s: line %d\\n\", a32, b32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_MLA\n#define silk_MLA(a,b,c) silk_MLA_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_MLA_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){\n    opus_int32 ret;\n    ret = a32 + b32 * c32;\n    if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 )\n    {\n        fprintf (stderr, \"silk_MLA(%d, %d, %d) in %s: line %d\\n\", a32, b32, c32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_MLA_uint\n#define silk_MLA_uint(a,b,c) silk_MLA_uint_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_MLA_uint_(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32, char *file, int line){\n    opus_uint32 ret;\n    ret = a32 + b32 * c32;\n    if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 )\n    {\n        fprintf (stderr, \"silk_MLA_uint(%d, %d, %d) in %s: line %d\\n\", a32, b32, c32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_SMULWB\n#define silk_SMULWB(a,b) silk_SMULWB_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_SMULWB_(opus_int32 a32, opus_int32 b32, char *file, int line){\n    opus_int32 ret;\n    ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16);\n    if ( (opus_int64)ret != ((opus_int64)a32 * (opus_int16)b32) >> 16 )\n    {\n        fprintf (stderr, \"silk_SMULWB(%d, %d) in %s: line %d\\n\", a32, b32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_SMLAWB\n#define silk_SMLAWB(a,b,c) silk_SMLAWB_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_SMLAWB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){\n    opus_int32 ret;\n    ret = silk_ADD32( a32, silk_SMULWB( b32, c32 ) );\n    if ( silk_ADD32( a32, silk_SMULWB( b32, c32 ) ) != silk_ADD_SAT32( a32, silk_SMULWB( b32, c32 ) ) )\n    {\n        fprintf (stderr, \"silk_SMLAWB(%d, %d, %d) in %s: line %d\\n\", a32, b32, c32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_SMULWT\n#define silk_SMULWT(a,b) silk_SMULWT_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_SMULWT_(opus_int32 a32, opus_int32 b32, char *file, int line){\n    opus_int32 ret;\n    ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16);\n    if ( (opus_int64)ret != ((opus_int64)a32 * (b32 >> 16)) >> 16 )\n    {\n        fprintf (stderr, \"silk_SMULWT(%d, %d) in %s: line %d\\n\", a32, b32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_SMLAWT\n#define silk_SMLAWT(a,b,c) silk_SMLAWT_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_SMLAWT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){\n    opus_int32 ret;\n    ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16));\n    if ( (opus_int64)ret != (opus_int64)a32 + (((opus_int64)b32 * (c32 >> 16)) >> 16) )\n    {\n        fprintf (stderr, \"silk_SMLAWT(%d, %d, %d) in %s: line %d\\n\", a32, b32, c32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_SMULL\n#define silk_SMULL(a,b) silk_SMULL_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int64 silk_SMULL_(opus_int64 a64, opus_int64 b64, char *file, int line){\n    opus_int64 ret64;\n    int        fail = 0;\n    ret64 = a64 * b64;\n    if( b64 != 0 ) {\n        fail = a64 != (ret64 / b64);\n    } else if( a64 != 0 ) {\n        fail = b64 != (ret64 / a64);\n    }\n    if ( fail )\n    {\n        fprintf (stderr, \"silk_SMULL(%lld, %lld) in %s: line %d\\n\", (long long)a64, (long long)b64, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret64;\n}\n\n/* no checking needed for silk_SMULBB */\n#undef silk_SMLABB\n#define silk_SMLABB(a,b,c) silk_SMLABB_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_SMLABB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){\n    opus_int32 ret;\n    ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32);\n    if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int16)c32 )\n    {\n        fprintf (stderr, \"silk_SMLABB(%d, %d, %d) in %s: line %d\\n\", a32, b32, c32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n/* no checking needed for silk_SMULBT */\n#undef silk_SMLABT\n#define silk_SMLABT(a,b,c) silk_SMLABT_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_SMLABT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){\n    opus_int32 ret;\n    ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16);\n    if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (c32 >> 16) )\n    {\n        fprintf (stderr, \"silk_SMLABT(%d, %d, %d) in %s: line %d\\n\", a32, b32, c32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n/* no checking needed for silk_SMULTT */\n#undef silk_SMLATT\n#define silk_SMLATT(a,b,c) silk_SMLATT_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_SMLATT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){\n    opus_int32 ret;\n    ret = a32 + (b32 >> 16) * (c32 >> 16);\n    if ( (opus_int64)ret != (opus_int64)a32 + (b32 >> 16) * (c32 >> 16) )\n    {\n        fprintf (stderr, \"silk_SMLATT(%d, %d, %d) in %s: line %d\\n\", a32, b32, c32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_SMULWW\n#define silk_SMULWW(a,b) silk_SMULWW_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_SMULWW_(opus_int32 a32, opus_int32 b32, char *file, int line){\n    opus_int32 ret, tmp1, tmp2;\n    opus_int64 ret64;\n    int        fail = 0;\n\n    ret  = silk_SMULWB( a32, b32 );\n    tmp1 = silk_RSHIFT_ROUND( b32, 16 );\n    tmp2 = silk_MUL( a32, tmp1 );\n\n    fail |= (opus_int64)tmp2 != (opus_int64) a32 * (opus_int64) tmp1;\n\n    tmp1 = ret;\n    ret  = silk_ADD32( tmp1, tmp2 );\n    fail |= silk_ADD32( tmp1, tmp2 ) != silk_ADD_SAT32( tmp1, tmp2 );\n\n    ret64 = silk_RSHIFT64( silk_SMULL( a32, b32 ), 16 );\n    fail |= (opus_int64)ret != ret64;\n\n    if ( fail )\n    {\n        fprintf (stderr, \"silk_SMULWT(%d, %d) in %s: line %d\\n\", a32, b32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n\n    return ret;\n}\n\n#undef silk_SMLAWW\n#define silk_SMLAWW(a,b,c) silk_SMLAWW_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_SMLAWW_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){\n    opus_int32 ret, tmp;\n\n    tmp = silk_SMULWW( b32, c32 );\n    ret = silk_ADD32( a32, tmp );\n    if ( ret != silk_ADD_SAT32( a32, tmp ) )\n    {\n        fprintf (stderr, \"silk_SMLAWW(%d, %d, %d) in %s: line %d\\n\", a32, b32, c32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */\n#undef  silk_MLA_ovflw\n#define silk_MLA_ovflw(a32, b32, c32)    ((a32) + ((b32) * (c32)))\n#undef  silk_SMLABB_ovflw\n#define silk_SMLABB_ovflw(a32, b32, c32)    ((a32) + ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32)))\n\n/* no checking needed for silk_SMULL\n   no checking needed for silk_SMLAL\n   no checking needed for silk_SMLALBB\n   no checking needed for SigProcFIX_CLZ16\n   no checking needed for SigProcFIX_CLZ32*/\n\n#undef silk_DIV32\n#define silk_DIV32(a,b) silk_DIV32_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_DIV32_(opus_int32 a32, opus_int32 b32, char *file, int line){\n    if ( b32 == 0 )\n    {\n        fprintf (stderr, \"silk_DIV32(%d, %d) in %s: line %d\\n\", a32, b32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return a32 / b32;\n}\n\n#undef silk_DIV32_16\n#define silk_DIV32_16(a,b) silk_DIV32_16_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, char *file, int line){\n    int fail = 0;\n    fail |= b32 == 0;\n    fail |= b32 > silk_int16_MAX;\n    fail |= b32 < silk_int16_MIN;\n    if ( fail )\n    {\n        fprintf (stderr, \"silk_DIV32_16(%d, %d) in %s: line %d\\n\", a32, b32, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return a32 / b32;\n}\n\n/* no checking needed for silk_SAT8\n   no checking needed for silk_SAT16\n   no checking needed for silk_SAT32\n   no checking needed for silk_POS_SAT32\n   no checking needed for silk_ADD_POS_SAT8\n   no checking needed for silk_ADD_POS_SAT16\n   no checking needed for silk_ADD_POS_SAT32\n   no checking needed for silk_ADD_POS_SAT64 */\n\n#undef silk_LSHIFT8\n#define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int8 silk_LSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){\n    opus_int8 ret;\n    int       fail = 0;\n    ret = a << shift;\n    fail |= shift < 0;\n    fail |= shift >= 8;\n    fail |= (opus_int64)ret != ((opus_int64)a) << shift;\n    if ( fail )\n    {\n        fprintf (stderr, \"silk_LSHIFT8(%d, %d) in %s: line %d\\n\", a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_LSHIFT16\n#define silk_LSHIFT16(a,b) silk_LSHIFT16_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int16 silk_LSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){\n    opus_int16 ret;\n    int        fail = 0;\n    ret = a << shift;\n    fail |= shift < 0;\n    fail |= shift >= 16;\n    fail |= (opus_int64)ret != ((opus_int64)a) << shift;\n    if ( fail )\n    {\n        fprintf (stderr, \"silk_LSHIFT16(%d, %d) in %s: line %d\\n\", a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_LSHIFT32\n#define silk_LSHIFT32(a,b) silk_LSHIFT32_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_LSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){\n    opus_int32 ret;\n    int        fail = 0;\n    ret = a << shift;\n    fail |= shift < 0;\n    fail |= shift >= 32;\n    fail |= (opus_int64)ret != ((opus_int64)a) << shift;\n    if ( fail )\n    {\n        fprintf (stderr, \"silk_LSHIFT32(%d, %d) in %s: line %d\\n\", a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_LSHIFT64\n#define silk_LSHIFT64(a,b) silk_LSHIFT64_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int64 silk_LSHIFT64_(opus_int64 a, opus_int shift, char *file, int line){\n    opus_int64 ret;\n    int        fail = 0;\n    ret = a << shift;\n    fail |= shift < 0;\n    fail |= shift >= 64;\n    fail |= (ret>>shift) != ((opus_int64)a);\n    if ( fail )\n    {\n        fprintf (stderr, \"silk_LSHIFT64(%lld, %d) in %s: line %d\\n\", (long long)a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_LSHIFT_ovflw\n#define silk_LSHIFT_ovflw(a,b) silk_LSHIFT_ovflw_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_LSHIFT_ovflw_(opus_int32 a, opus_int32 shift, char *file, int line){\n    if ( (shift < 0) || (shift >= 32) ) /* no check for overflow */\n    {\n        fprintf (stderr, \"silk_LSHIFT_ovflw(%d, %d) in %s: line %d\\n\", a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return a << shift;\n}\n\n#undef silk_LSHIFT_uint\n#define silk_LSHIFT_uint(a,b) silk_LSHIFT_uint_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_uint32 silk_LSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){\n    opus_uint32 ret;\n    ret = a << shift;\n    if ( (shift < 0) || ((opus_int64)ret != ((opus_int64)a) << shift))\n    {\n        fprintf (stderr, \"silk_LSHIFT_uint(%u, %d) in %s: line %d\\n\", a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_RSHIFT8\n#define silk_RSHITF8(a,b) silk_RSHIFT8_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int8 silk_RSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){\n    if ( (shift < 0) || (shift>=8) )\n    {\n        fprintf (stderr, \"silk_RSHITF8(%d, %d) in %s: line %d\\n\", a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return a >> shift;\n}\n\n#undef silk_RSHIFT16\n#define silk_RSHITF16(a,b) silk_RSHIFT16_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int16 silk_RSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){\n    if ( (shift < 0) || (shift>=16) )\n    {\n        fprintf (stderr, \"silk_RSHITF16(%d, %d) in %s: line %d\\n\", a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return a >> shift;\n}\n\n#undef silk_RSHIFT32\n#define silk_RSHIFT32(a,b) silk_RSHIFT32_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_RSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){\n    if ( (shift < 0) || (shift>=32) )\n    {\n        fprintf (stderr, \"silk_RSHITF32(%d, %d) in %s: line %d\\n\", a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return a >> shift;\n}\n\n#undef silk_RSHIFT64\n#define silk_RSHIFT64(a,b) silk_RSHIFT64_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int64 silk_RSHIFT64_(opus_int64 a, opus_int64 shift, char *file, int line){\n    if ( (shift < 0) || (shift>=64) )\n    {\n        fprintf (stderr, \"silk_RSHITF64(%lld, %lld) in %s: line %d\\n\", (long long)a, (long long)shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return a >> shift;\n}\n\n#undef silk_RSHIFT_uint\n#define silk_RSHIFT_uint(a,b) silk_RSHIFT_uint_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_uint32 silk_RSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){\n    if ( (shift < 0) || (shift>32) )\n    {\n        fprintf (stderr, \"silk_RSHIFT_uint(%u, %d) in %s: line %d\\n\", a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return a >> shift;\n}\n\n#undef silk_ADD_LSHIFT\n#define silk_ADD_LSHIFT(a,b,c) silk_ADD_LSHIFT_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE int silk_ADD_LSHIFT_(int a, int b, int shift, char *file, int line){\n    opus_int16 ret;\n    ret = a + (b << shift);\n    if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) )\n    {\n        fprintf (stderr, \"silk_ADD_LSHIFT(%d, %d, %d) in %s: line %d\\n\", a, b, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;                /* shift >= 0 */\n}\n\n#undef silk_ADD_LSHIFT32\n#define silk_ADD_LSHIFT32(a,b,c) silk_ADD_LSHIFT32_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_ADD_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){\n    opus_int32 ret;\n    ret = a + (b << shift);\n    if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) )\n    {\n        fprintf (stderr, \"silk_ADD_LSHIFT32(%d, %d, %d) in %s: line %d\\n\", a, b, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;                /* shift >= 0 */\n}\n\n#undef silk_ADD_LSHIFT_uint\n#define silk_ADD_LSHIFT_uint(a,b,c) silk_ADD_LSHIFT_uint_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_uint32 silk_ADD_LSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){\n    opus_uint32 ret;\n    ret = a + (b << shift);\n    if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) )\n    {\n        fprintf (stderr, \"silk_ADD_LSHIFT_uint(%u, %u, %d) in %s: line %d\\n\", a, b, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;                /* shift >= 0 */\n}\n\n#undef silk_ADD_RSHIFT\n#define silk_ADD_RSHIFT(a,b,c) silk_ADD_RSHIFT_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE int silk_ADD_RSHIFT_(int a, int b, int shift, char *file, int line){\n    opus_int16 ret;\n    ret = a + (b >> shift);\n    if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) )\n    {\n        fprintf (stderr, \"silk_ADD_RSHIFT(%d, %d, %d) in %s: line %d\\n\", a, b, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;                /* shift  > 0 */\n}\n\n#undef silk_ADD_RSHIFT32\n#define silk_ADD_RSHIFT32(a,b,c) silk_ADD_RSHIFT32_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_ADD_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){\n    opus_int32 ret;\n    ret = a + (b >> shift);\n    if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) )\n    {\n        fprintf (stderr, \"silk_ADD_RSHIFT32(%d, %d, %d) in %s: line %d\\n\", a, b, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;                /* shift  > 0 */\n}\n\n#undef silk_ADD_RSHIFT_uint\n#define silk_ADD_RSHIFT_uint(a,b,c) silk_ADD_RSHIFT_uint_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_uint32 silk_ADD_RSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){\n    opus_uint32 ret;\n    ret = a + (b >> shift);\n    if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) )\n    {\n        fprintf (stderr, \"silk_ADD_RSHIFT_uint(%u, %u, %d) in %s: line %d\\n\", a, b, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;                /* shift  > 0 */\n}\n\n#undef silk_SUB_LSHIFT32\n#define silk_SUB_LSHIFT32(a,b,c) silk_SUB_LSHIFT32_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_SUB_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){\n    opus_int32 ret;\n    ret = a - (b << shift);\n    if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) << shift)) )\n    {\n        fprintf (stderr, \"silk_SUB_LSHIFT32(%d, %d, %d) in %s: line %d\\n\", a, b, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;                /* shift >= 0 */\n}\n\n#undef silk_SUB_RSHIFT32\n#define silk_SUB_RSHIFT32(a,b,c) silk_SUB_RSHIFT32_((a), (b), (c), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_SUB_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){\n    opus_int32 ret;\n    ret = a - (b >> shift);\n    if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) >> shift)) )\n    {\n        fprintf (stderr, \"silk_SUB_RSHIFT32(%d, %d, %d) in %s: line %d\\n\", a, b, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;                /* shift  > 0 */\n}\n\n#undef silk_RSHIFT_ROUND\n#define silk_RSHIFT_ROUND(a,b) silk_RSHIFT_ROUND_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_RSHIFT_ROUND_(opus_int32 a, opus_int32 shift, char *file, int line){\n    opus_int32 ret;\n    ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;\n    /* the marco definition can't handle a shift of zero */\n    if ( (shift <= 0) || (shift>31) || ((opus_int64)ret != ((opus_int64)a + ((opus_int64)1 << (shift - 1))) >> shift) )\n    {\n        fprintf (stderr, \"silk_RSHIFT_ROUND(%d, %d) in %s: line %d\\n\", a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return ret;\n}\n\n#undef silk_RSHIFT_ROUND64\n#define silk_RSHIFT_ROUND64(a,b) silk_RSHIFT_ROUND64_((a), (b), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int64 silk_RSHIFT_ROUND64_(opus_int64 a, opus_int32 shift, char *file, int line){\n    opus_int64 ret;\n    /* the marco definition can't handle a shift of zero */\n    if ( (shift <= 0) || (shift>=64) )\n    {\n        fprintf (stderr, \"silk_RSHIFT_ROUND64(%lld, %d) in %s: line %d\\n\", (long long)a, shift, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;\n    return ret;\n}\n\n/* silk_abs is used on floats also, so doesn't work... */\n/*#undef silk_abs\nstatic OPUS_INLINE opus_int32 silk_abs(opus_int32 a){\n    silk_assert(a != 0x80000000);\n    return (((a) >  0)  ? (a) : -(a));            // Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN\n}*/\n\n#undef silk_abs_int64\n#define silk_abs_int64(a) silk_abs_int64_((a), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int64 silk_abs_int64_(opus_int64 a, char *file, int line){\n    if ( a == silk_int64_MIN )\n    {\n        fprintf (stderr, \"silk_abs_int64(%lld) in %s: line %d\\n\", (long long)a, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return (((a) >  0)  ? (a) : -(a));            /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN */\n}\n\n#undef silk_abs_int32\n#define silk_abs_int32(a) silk_abs_int32_((a), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_abs_int32_(opus_int32 a, char *file, int line){\n    if ( a == silk_int32_MIN )\n    {\n        fprintf (stderr, \"silk_abs_int32(%d) in %s: line %d\\n\", a, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return silk_abs(a);\n}\n\n#undef silk_CHECK_FIT8\n#define silk_CHECK_FIT8(a) silk_CHECK_FIT8_((a), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int8 silk_CHECK_FIT8_( opus_int64 a, char *file, int line ){\n    opus_int8 ret;\n    ret = (opus_int8)a;\n    if ( (opus_int64)ret != a )\n    {\n        fprintf (stderr, \"silk_CHECK_FIT8(%lld) in %s: line %d\\n\", (long long)a, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return( ret );\n}\n\n#undef silk_CHECK_FIT16\n#define silk_CHECK_FIT16(a) silk_CHECK_FIT16_((a), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int16 silk_CHECK_FIT16_( opus_int64 a, char *file, int line ){\n    opus_int16 ret;\n    ret = (opus_int16)a;\n    if ( (opus_int64)ret != a )\n    {\n        fprintf (stderr, \"silk_CHECK_FIT16(%lld) in %s: line %d\\n\", (long long)a, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return( ret );\n}\n\n#undef silk_CHECK_FIT32\n#define silk_CHECK_FIT32(a) silk_CHECK_FIT32_((a), __FILE__, __LINE__)\nstatic OPUS_INLINE opus_int32 silk_CHECK_FIT32_( opus_int64 a, char *file, int line ){\n    opus_int32 ret;\n    ret = (opus_int32)a;\n    if ( (opus_int64)ret != a )\n    {\n        fprintf (stderr, \"silk_CHECK_FIT32(%lld) in %s: line %d\\n\", (long long)a, file, line);\n#ifdef FIXED_DEBUG_ASSERT\n        silk_assert( 0 );\n#endif\n    }\n    return( ret );\n}\n\n/* no checking for silk_NSHIFT_MUL_32_32\n   no checking for silk_NSHIFT_MUL_16_16\n   no checking needed for silk_min\n   no checking needed for silk_max\n   no checking needed for silk_sign\n*/\n\n#endif\n#endif /* MACRO_DEBUG_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/NLSF2A.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* conversion between prediction filter coefficients and LSFs   */\n/* order should be even                                         */\n/* a piecewise linear approximation maps LSF <-> cos(LSF)       */\n/* therefore the result is not accurate LSFs, but the two       */\n/* functions are accurate inverses of each other                */\n\n#include \"SigProc_FIX.h\"\n#include \"tables.h\"\n\n#define QA      16\n\n/* helper function for NLSF2A(..) */\nstatic OPUS_INLINE void silk_NLSF2A_find_poly(\n    opus_int32          *out,      /* O    intermediate polynomial, QA [dd+1]        */\n    const opus_int32    *cLSF,     /* I    vector of interleaved 2*cos(LSFs), QA [d] */\n    opus_int            dd         /* I    polynomial order (= 1/2 * filter order)   */\n)\n{\n    opus_int   k, n;\n    opus_int32 ftmp;\n\n    out[0] = silk_LSHIFT( 1, QA );\n    out[1] = -cLSF[0];\n    for( k = 1; k < dd; k++ ) {\n        ftmp = cLSF[2*k];            /* QA*/\n        out[k+1] = silk_LSHIFT( out[k-1], 1 ) - (opus_int32)silk_RSHIFT_ROUND64( silk_SMULL( ftmp, out[k] ), QA );\n        for( n = k; n > 1; n-- ) {\n            out[n] += out[n-2] - (opus_int32)silk_RSHIFT_ROUND64( silk_SMULL( ftmp, out[n-1] ), QA );\n        }\n        out[1] -= ftmp;\n    }\n}\n\n/* compute whitening filter coefficients from normalized line spectral frequencies */\nvoid silk_NLSF2A(\n    opus_int16                  *a_Q12,             /* O    monic whitening filter coefficients in Q12,  [ d ]          */\n    const opus_int16            *NLSF,              /* I    normalized line spectral frequencies in Q15, [ d ]          */\n    const opus_int              d                   /* I    filter order (should be even)                               */\n)\n{\n    /* This ordering was found to maximize quality. It improves numerical accuracy of\n       silk_NLSF2A_find_poly() compared to \"standard\" ordering. */\n    static const unsigned char ordering16[16] = {\n      0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1\n    };\n    static const unsigned char ordering10[10] = {\n      0, 9, 6, 3, 4, 5, 8, 1, 2, 7\n    };\n    const unsigned char *ordering;\n    opus_int   k, i, dd;\n    opus_int32 cos_LSF_QA[ SILK_MAX_ORDER_LPC ];\n    opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];\n    opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta;\n    opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ];\n    opus_int32 maxabs, absval, idx=0, sc_Q16;\n\n    silk_assert( LSF_COS_TAB_SZ_FIX == 128 );\n    silk_assert( d==10||d==16 );\n\n    /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */\n    ordering = d == 16 ? ordering16 : ordering10;\n    for( k = 0; k < d; k++ ) {\n        silk_assert(NLSF[k] >= 0 );\n\n        /* f_int on a scale 0-127 (rounded down) */\n        f_int = silk_RSHIFT( NLSF[k], 15 - 7 );\n\n        /* f_frac, range: 0..255 */\n        f_frac = NLSF[k] - silk_LSHIFT( f_int, 15 - 7 );\n\n        silk_assert(f_int >= 0);\n        silk_assert(f_int < LSF_COS_TAB_SZ_FIX );\n\n        /* Read start and end value from table */\n        cos_val = silk_LSFCosTab_FIX_Q12[ f_int ];                /* Q12 */\n        delta   = silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val;  /* Q12, with a range of 0..200 */\n\n        /* Linear interpolation */\n        cos_LSF_QA[ordering[k]] = silk_RSHIFT_ROUND( silk_LSHIFT( cos_val, 8 ) + silk_MUL( delta, f_frac ), 20 - QA ); /* QA */\n    }\n\n    dd = silk_RSHIFT( d, 1 );\n\n    /* generate even and odd polynomials using convolution */\n    silk_NLSF2A_find_poly( P, &cos_LSF_QA[ 0 ], dd );\n    silk_NLSF2A_find_poly( Q, &cos_LSF_QA[ 1 ], dd );\n\n    /* convert even and odd polynomials to opus_int32 Q12 filter coefs */\n    for( k = 0; k < dd; k++ ) {\n        Ptmp = P[ k+1 ] + P[ k ];\n        Qtmp = Q[ k+1 ] - Q[ k ];\n\n        /* the Ptmp and Qtmp values at this stage need to fit in int32 */\n        a32_QA1[ k ]     = -Qtmp - Ptmp;        /* QA+1 */\n        a32_QA1[ d-k-1 ] =  Qtmp - Ptmp;        /* QA+1 */\n    }\n\n    /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */\n    for( i = 0; i < 10; i++ ) {\n        /* Find maximum absolute value and its index */\n        maxabs = 0;\n        for( k = 0; k < d; k++ ) {\n            absval = silk_abs( a32_QA1[k] );\n            if( absval > maxabs ) {\n                maxabs = absval;\n                idx    = k;\n            }\n        }\n        maxabs = silk_RSHIFT_ROUND( maxabs, QA + 1 - 12 );                                          /* QA+1 -> Q12 */\n\n        if( maxabs > silk_int16_MAX ) {\n            /* Reduce magnitude of prediction coefficients */\n            maxabs = silk_min( maxabs, 163838 );  /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */\n            sc_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ),\n                                        silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) );\n            silk_bwexpander_32( a32_QA1, d, sc_Q16 );\n        } else {\n            break;\n        }\n    }\n\n    if( i == 10 ) {\n        /* Reached the last iteration, clip the coefficients */\n        for( k = 0; k < d; k++ ) {\n            a_Q12[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) );  /* QA+1 -> Q12 */\n            a32_QA1[ k ] = silk_LSHIFT( (opus_int32)a_Q12[ k ], QA + 1 - 12 );\n        }\n    } else {\n        for( k = 0; k < d; k++ ) {\n            a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 );                /* QA+1 -> Q12 */\n        }\n    }\n\n    for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {\n        if( silk_LPC_inverse_pred_gain( a_Q12, d ) < SILK_FIX_CONST( 1.0 / MAX_PREDICTION_POWER_GAIN, 30 ) ) {\n            /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion   */\n            /* on the unscaled coefficients, convert to Q12 and measure again                   */\n            silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) );\n            for( k = 0; k < d; k++ ) {\n                a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 );            /* QA+1 -> Q12 */\n            }\n        } else {\n            break;\n        }\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/NLSF_VQ.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Compute quantization errors for an LPC_order element input vector for a VQ codebook */\nvoid silk_NLSF_VQ(\n    opus_int32                  err_Q26[],                      /* O    Quantization errors [K]                     */\n    const opus_int16            in_Q15[],                       /* I    Input vectors to be quantized [LPC_order]   */\n    const opus_uint8            pCB_Q8[],                       /* I    Codebook vectors [K*LPC_order]              */\n    const opus_int              K,                              /* I    Number of codebook vectors                  */\n    const opus_int              LPC_order                       /* I    Number of LPCs                              */\n)\n{\n    opus_int        i, m;\n    opus_int32      diff_Q15, sum_error_Q30, sum_error_Q26;\n\n    silk_assert( LPC_order <= 16 );\n    silk_assert( ( LPC_order & 1 ) == 0 );\n\n    /* Loop over codebook */\n    for( i = 0; i < K; i++ ) {\n        sum_error_Q26 = 0;\n        for( m = 0; m < LPC_order; m += 2 ) {\n            /* Compute weighted squared quantization error for index m */\n            diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/\n            sum_error_Q30 = silk_SMULBB( diff_Q15, diff_Q15 );\n\n            /* Compute weighted squared quantization error for index m + 1 */\n            diff_Q15 = silk_SUB_LSHIFT32( in_Q15[m + 1], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/\n            sum_error_Q30 = silk_SMLABB( sum_error_Q30, diff_Q15, diff_Q15 );\n\n            sum_error_Q26 = silk_ADD_RSHIFT32( sum_error_Q26, sum_error_Q30, 4 );\n\n            silk_assert( sum_error_Q26 >= 0 );\n            silk_assert( sum_error_Q30 >= 0 );\n        }\n        err_Q26[ i ] = sum_error_Q26;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/NLSF_VQ_weights_laroia.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"define.h\"\n#include \"SigProc_FIX.h\"\n\n/*\nR. Laroia, N. Phamdo and N. Farvardin, \"Robust and Efficient Quantization of Speech LSP\nParameters Using Structured Vector Quantization\", Proc. IEEE Int. Conf. Acoust., Speech,\nSignal Processing, pp. 641-644, 1991.\n*/\n\n/* Laroia low complexity NLSF weights */\nvoid silk_NLSF_VQ_weights_laroia(\n    opus_int16                  *pNLSFW_Q_OUT,      /* O     Pointer to input vector weights [D]                        */\n    const opus_int16            *pNLSF_Q15,         /* I     Pointer to input vector         [D]                        */\n    const opus_int              D                   /* I     Input vector dimension (even)                              */\n)\n{\n    opus_int   k;\n    opus_int32 tmp1_int, tmp2_int;\n\n    silk_assert( D > 0 );\n    silk_assert( ( D & 1 ) == 0 );\n\n    /* First value */\n    tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 );\n    tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int );\n    tmp2_int = silk_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], 1 );\n    tmp2_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp2_int );\n    pNLSFW_Q_OUT[ 0 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX );\n    silk_assert( pNLSFW_Q_OUT[ 0 ] > 0 );\n\n    /* Main loop */\n    for( k = 1; k < D - 1; k += 2 ) {\n        tmp1_int = silk_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], 1 );\n        tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int );\n        pNLSFW_Q_OUT[ k ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX );\n        silk_assert( pNLSFW_Q_OUT[ k ] > 0 );\n\n        tmp2_int = silk_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], 1 );\n        tmp2_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp2_int );\n        pNLSFW_Q_OUT[ k + 1 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX );\n        silk_assert( pNLSFW_Q_OUT[ k + 1 ] > 0 );\n    }\n\n    /* Last value */\n    tmp1_int = silk_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], 1 );\n    tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int );\n    pNLSFW_Q_OUT[ D - 1 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX );\n    silk_assert( pNLSFW_Q_OUT[ D - 1 ] > 0 );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/NLSF_decode.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Predictive dequantizer for NLSF residuals */\nstatic OPUS_INLINE void silk_NLSF_residual_dequant(               /* O    Returns RD value in Q30                     */\n          opus_int16         x_Q10[],                        /* O    Output [ order ]                            */\n    const opus_int8          indices[],                      /* I    Quantization indices [ order ]              */\n    const opus_uint8         pred_coef_Q8[],                 /* I    Backward predictor coefs [ order ]          */\n    const opus_int           quant_step_size_Q16,            /* I    Quantization step size                      */\n    const opus_int16         order                           /* I    Number of input values                      */\n)\n{\n    opus_int     i, out_Q10, pred_Q10;\n\n    out_Q10 = 0;\n    for( i = order-1; i >= 0; i-- ) {\n        pred_Q10 = silk_RSHIFT( silk_SMULBB( out_Q10, (opus_int16)pred_coef_Q8[ i ] ), 8 );\n        out_Q10  = silk_LSHIFT( indices[ i ], 10 );\n        if( out_Q10 > 0 ) {\n            out_Q10 = silk_SUB16( out_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );\n        } else if( out_Q10 < 0 ) {\n            out_Q10 = silk_ADD16( out_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );\n        }\n        out_Q10  = silk_SMLAWB( pred_Q10, (opus_int32)out_Q10, quant_step_size_Q16 );\n        x_Q10[ i ] = out_Q10;\n    }\n}\n\n\n/***********************/\n/* NLSF vector decoder */\n/***********************/\nvoid silk_NLSF_decode(\n          opus_int16            *pNLSF_Q15,                     /* O    Quantized NLSF vector [ LPC_ORDER ]         */\n          opus_int8             *NLSFIndices,                   /* I    Codebook path vector [ LPC_ORDER + 1 ]      */\n    const silk_NLSF_CB_struct   *psNLSF_CB                      /* I    Codebook object                             */\n)\n{\n    opus_int         i;\n    opus_uint8       pred_Q8[  MAX_LPC_ORDER ];\n    opus_int16       ec_ix[    MAX_LPC_ORDER ];\n    opus_int16       res_Q10[  MAX_LPC_ORDER ];\n    opus_int16       W_tmp_QW[ MAX_LPC_ORDER ];\n    opus_int32       W_tmp_Q9, NLSF_Q15_tmp;\n    const opus_uint8 *pCB_element;\n\n    /* Decode first stage */\n    pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ];\n    for( i = 0; i < psNLSF_CB->order; i++ ) {\n        pNLSF_Q15[ i ] = silk_LSHIFT( (opus_int16)pCB_element[ i ], 7 );\n    }\n\n    /* Unpack entropy table indices and predictor for current CB1 index */\n    silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] );\n\n    /* Predictive residual dequantizer */\n    silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order );\n\n    /* Weights from codebook vector */\n    silk_NLSF_VQ_weights_laroia( W_tmp_QW, pNLSF_Q15, psNLSF_CB->order );\n\n    /* Apply inverse square-rooted weights and add to output */\n    for( i = 0; i < psNLSF_CB->order; i++ ) {\n        W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) );\n        NLSF_Q15_tmp = silk_ADD32( pNLSF_Q15[ i ], silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), W_tmp_Q9 ) );\n        pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 );\n    }\n\n    /* NLSF stabilization */\n    silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/NLSF_del_dec_quant.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Delayed-decision quantizer for NLSF residuals */\nopus_int32 silk_NLSF_del_dec_quant(                             /* O    Returns RD value in Q25                     */\n    opus_int8                   indices[],                      /* O    Quantization indices [ order ]              */\n    const opus_int16            x_Q10[],                        /* I    Input [ order ]                             */\n    const opus_int16            w_Q5[],                         /* I    Weights [ order ]                           */\n    const opus_uint8            pred_coef_Q8[],                 /* I    Backward predictor coefs [ order ]          */\n    const opus_int16            ec_ix[],                        /* I    Indices to entropy coding tables [ order ]  */\n    const opus_uint8            ec_rates_Q5[],                  /* I    Rates []                                    */\n    const opus_int              quant_step_size_Q16,            /* I    Quantization step size                      */\n    const opus_int16            inv_quant_step_size_Q6,         /* I    Inverse quantization step size              */\n    const opus_int32            mu_Q20,                         /* I    R/D tradeoff                                */\n    const opus_int16            order                           /* I    Number of input values                      */\n)\n{\n    opus_int         i, j, nStates, ind_tmp, ind_min_max, ind_max_min, in_Q10, res_Q10;\n    opus_int         pred_Q10, diff_Q10, out0_Q10, out1_Q10, rate0_Q5, rate1_Q5;\n    opus_int32       RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25, pred_coef_Q16;\n    opus_int         ind_sort[         NLSF_QUANT_DEL_DEC_STATES ];\n    opus_int8        ind[              NLSF_QUANT_DEL_DEC_STATES ][ MAX_LPC_ORDER ];\n    opus_int16       prev_out_Q10[ 2 * NLSF_QUANT_DEL_DEC_STATES ];\n    opus_int32       RD_Q25[       2 * NLSF_QUANT_DEL_DEC_STATES ];\n    opus_int32       RD_min_Q25[       NLSF_QUANT_DEL_DEC_STATES ];\n    opus_int32       RD_max_Q25[       NLSF_QUANT_DEL_DEC_STATES ];\n    const opus_uint8 *rates_Q5;\n\n    opus_int out0_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];\n    opus_int out1_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];\n\n    for (i = -NLSF_QUANT_MAX_AMPLITUDE_EXT; i <= NLSF_QUANT_MAX_AMPLITUDE_EXT-1; i++)\n    {\n        out0_Q10 = silk_LSHIFT( i, 10 );\n        out1_Q10 = silk_ADD16( out0_Q10, 1024 );\n        if( i > 0 ) {\n            out0_Q10 = silk_SUB16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );\n            out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );\n        } else if( i == 0 ) {\n            out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );\n        } else if( i == -1 ) {\n            out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );\n        } else {\n            out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );\n            out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );\n        }\n        out0_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_SMULWB( (opus_int32)out0_Q10, quant_step_size_Q16 );\n        out1_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_SMULWB( (opus_int32)out1_Q10, quant_step_size_Q16 );\n    }\n\n    silk_assert( (NLSF_QUANT_DEL_DEC_STATES & (NLSF_QUANT_DEL_DEC_STATES-1)) == 0 );     /* must be power of two */\n\n    nStates = 1;\n    RD_Q25[ 0 ] = 0;\n    prev_out_Q10[ 0 ] = 0;\n    for( i = order - 1; ; i-- ) {\n        rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ];\n        pred_coef_Q16 = silk_LSHIFT( (opus_int32)pred_coef_Q8[ i ], 8 );\n        in_Q10 = x_Q10[ i ];\n        for( j = 0; j < nStates; j++ ) {\n            pred_Q10 = silk_SMULWB( pred_coef_Q16, prev_out_Q10[ j ] );\n            res_Q10  = silk_SUB16( in_Q10, pred_Q10 );\n            ind_tmp  = silk_SMULWB( (opus_int32)inv_quant_step_size_Q6, res_Q10 );\n            ind_tmp  = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 );\n            ind[ j ][ i ] = (opus_int8)ind_tmp;\n\n            /* compute outputs for ind_tmp and ind_tmp + 1 */\n            out0_Q10 = out0_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];\n            out1_Q10 = out1_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];\n\n            out0_Q10  = silk_ADD16( out0_Q10, pred_Q10 );\n            out1_Q10  = silk_ADD16( out1_Q10, pred_Q10 );\n            prev_out_Q10[ j           ] = out0_Q10;\n            prev_out_Q10[ j + nStates ] = out1_Q10;\n\n            /* compute RD for ind_tmp and ind_tmp + 1 */\n            if( ind_tmp + 1 >= NLSF_QUANT_MAX_AMPLITUDE ) {\n                if( ind_tmp + 1 == NLSF_QUANT_MAX_AMPLITUDE ) {\n                    rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ];\n                    rate1_Q5 = 280;\n                } else {\n                    rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, 43, ind_tmp );\n                    rate1_Q5 = silk_ADD16( rate0_Q5, 43 );\n                }\n            } else if( ind_tmp <= -NLSF_QUANT_MAX_AMPLITUDE ) {\n                if( ind_tmp == -NLSF_QUANT_MAX_AMPLITUDE ) {\n                    rate0_Q5 = 280;\n                    rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];\n                } else {\n                    rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, -43, ind_tmp );\n                    rate1_Q5 = silk_SUB16( rate0_Q5, 43 );\n                }\n            } else {\n                rate0_Q5 = rates_Q5[ ind_tmp +     NLSF_QUANT_MAX_AMPLITUDE ];\n                rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];\n            }\n            RD_tmp_Q25            = RD_Q25[ j ];\n            diff_Q10              = silk_SUB16( in_Q10, out0_Q10 );\n            RD_Q25[ j ]           = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate0_Q5 );\n            diff_Q10              = silk_SUB16( in_Q10, out1_Q10 );\n            RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 );\n        }\n\n        if( nStates <= ( NLSF_QUANT_DEL_DEC_STATES >> 1 ) ) {\n            /* double number of states and copy */\n            for( j = 0; j < nStates; j++ ) {\n                ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1;\n            }\n            nStates = silk_LSHIFT( nStates, 1 );\n            for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {\n                ind[ j ][ i ] = ind[ j - nStates ][ i ];\n            }\n        } else if( i > 0 ) {\n            /* sort lower and upper half of RD_Q25, pairwise */\n            for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {\n                if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) {\n                    RD_max_Q25[ j ]                         = RD_Q25[ j ];\n                    RD_min_Q25[ j ]                         = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];\n                    RD_Q25[ j ]                             = RD_min_Q25[ j ];\n                    RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] = RD_max_Q25[ j ];\n                    /* swap prev_out values */\n                    out0_Q10 = prev_out_Q10[ j ];\n                    prev_out_Q10[ j ] = prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ];\n                    prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ] = out0_Q10;\n                    ind_sort[ j ] = j + NLSF_QUANT_DEL_DEC_STATES;\n                } else {\n                    RD_min_Q25[ j ] = RD_Q25[ j ];\n                    RD_max_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];\n                    ind_sort[ j ] = j;\n                }\n            }\n            /* compare the highest RD values of the winning half with the lowest one in the losing half, and copy if necessary */\n            /* afterwards ind_sort[] will contain the indices of the NLSF_QUANT_DEL_DEC_STATES winning RD values */\n            while( 1 ) {\n                min_max_Q25 = silk_int32_MAX;\n                max_min_Q25 = 0;\n                ind_min_max = 0;\n                ind_max_min = 0;\n                for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {\n                    if( min_max_Q25 > RD_max_Q25[ j ] ) {\n                        min_max_Q25 = RD_max_Q25[ j ];\n                        ind_min_max = j;\n                    }\n                    if( max_min_Q25 < RD_min_Q25[ j ] ) {\n                        max_min_Q25 = RD_min_Q25[ j ];\n                        ind_max_min = j;\n                    }\n                }\n                if( min_max_Q25 >= max_min_Q25 ) {\n                    break;\n                }\n                /* copy ind_min_max to ind_max_min */\n                ind_sort[     ind_max_min ] = ind_sort[     ind_min_max ] ^ NLSF_QUANT_DEL_DEC_STATES;\n                RD_Q25[       ind_max_min ] = RD_Q25[       ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];\n                prev_out_Q10[ ind_max_min ] = prev_out_Q10[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];\n                RD_min_Q25[   ind_max_min ] = 0;\n                RD_max_Q25[   ind_min_max ] = silk_int32_MAX;\n                silk_memcpy( ind[ ind_max_min ], ind[ ind_min_max ], MAX_LPC_ORDER * sizeof( opus_int8 ) );\n            }\n            /* increment index if it comes from the upper half */\n            for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {\n                ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 );\n            }\n        } else {  /* i == 0 */\n            break;\n        }\n    }\n\n    /* last sample: find winner, copy indices and return RD value */\n    ind_tmp = 0;\n    min_Q25 = silk_int32_MAX;\n    for( j = 0; j < 2 * NLSF_QUANT_DEL_DEC_STATES; j++ ) {\n        if( min_Q25 > RD_Q25[ j ] ) {\n            min_Q25 = RD_Q25[ j ];\n            ind_tmp = j;\n        }\n    }\n    for( j = 0; j < order; j++ ) {\n        indices[ j ] = ind[ ind_tmp & ( NLSF_QUANT_DEL_DEC_STATES - 1 ) ][ j ];\n        silk_assert( indices[ j ] >= -NLSF_QUANT_MAX_AMPLITUDE_EXT );\n        silk_assert( indices[ j ] <=  NLSF_QUANT_MAX_AMPLITUDE_EXT );\n    }\n    indices[ 0 ] += silk_RSHIFT( ind_tmp, NLSF_QUANT_DEL_DEC_STATES_LOG2 );\n    silk_assert( indices[ 0 ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT );\n    silk_assert( min_Q25 >= 0 );\n    return min_Q25;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/NLSF_encode.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"stack_alloc.h\"\n\n/***********************/\n/* NLSF vector encoder */\n/***********************/\nopus_int32 silk_NLSF_encode(                                    /* O    Returns RD value in Q25                     */\n          opus_int8             *NLSFIndices,                   /* I    Codebook path vector [ LPC_ORDER + 1 ]      */\n          opus_int16            *pNLSF_Q15,                     /* I/O  Quantized NLSF vector [ LPC_ORDER ]         */\n    const silk_NLSF_CB_struct   *psNLSF_CB,                     /* I    Codebook object                             */\n    const opus_int16            *pW_QW,                         /* I    NLSF weight vector [ LPC_ORDER ]            */\n    const opus_int              NLSF_mu_Q20,                    /* I    Rate weight for the RD optimization         */\n    const opus_int              nSurvivors,                     /* I    Max survivors after first stage             */\n    const opus_int              signalType                      /* I    Signal type: 0/1/2                          */\n)\n{\n    opus_int         i, s, ind1, bestIndex, prob_Q8, bits_q7;\n    opus_int32       W_tmp_Q9;\n    VARDECL( opus_int32, err_Q26 );\n    VARDECL( opus_int32, RD_Q25 );\n    VARDECL( opus_int, tempIndices1 );\n    VARDECL( opus_int8, tempIndices2 );\n    opus_int16       res_Q15[      MAX_LPC_ORDER ];\n    opus_int16       res_Q10[      MAX_LPC_ORDER ];\n    opus_int16       NLSF_tmp_Q15[ MAX_LPC_ORDER ];\n    opus_int16       W_tmp_QW[     MAX_LPC_ORDER ];\n    opus_int16       W_adj_Q5[     MAX_LPC_ORDER ];\n    opus_uint8       pred_Q8[      MAX_LPC_ORDER ];\n    opus_int16       ec_ix[        MAX_LPC_ORDER ];\n    const opus_uint8 *pCB_element, *iCDF_ptr;\n    SAVE_STACK;\n\n    silk_assert( nSurvivors <= NLSF_VQ_MAX_SURVIVORS );\n    silk_assert( signalType >= 0 && signalType <= 2 );\n    silk_assert( NLSF_mu_Q20 <= 32767 && NLSF_mu_Q20 >= 0 );\n\n    /* NLSF stabilization */\n    silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order );\n\n    /* First stage: VQ */\n    ALLOC( err_Q26, psNLSF_CB->nVectors, opus_int32 );\n    silk_NLSF_VQ( err_Q26, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->nVectors, psNLSF_CB->order );\n\n    /* Sort the quantization errors */\n    ALLOC( tempIndices1, nSurvivors, opus_int );\n    silk_insertion_sort_increasing( err_Q26, tempIndices1, psNLSF_CB->nVectors, nSurvivors );\n\n    ALLOC( RD_Q25, nSurvivors, opus_int32 );\n    ALLOC( tempIndices2, nSurvivors * MAX_LPC_ORDER, opus_int8 );\n\n    /* Loop over survivors */\n    for( s = 0; s < nSurvivors; s++ ) {\n        ind1 = tempIndices1[ s ];\n\n        /* Residual after first stage */\n        pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ ind1 * psNLSF_CB->order ];\n        for( i = 0; i < psNLSF_CB->order; i++ ) {\n            NLSF_tmp_Q15[ i ] = silk_LSHIFT16( (opus_int16)pCB_element[ i ], 7 );\n            res_Q15[ i ] = pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ];\n        }\n\n        /* Weights from codebook vector */\n        silk_NLSF_VQ_weights_laroia( W_tmp_QW, NLSF_tmp_Q15, psNLSF_CB->order );\n\n        /* Apply square-rooted weights */\n        for( i = 0; i < psNLSF_CB->order; i++ ) {\n            W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) );\n            res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( res_Q15[ i ], W_tmp_Q9 ), 14 );\n        }\n\n        /* Modify input weights accordingly */\n        for( i = 0; i < psNLSF_CB->order; i++ ) {\n            W_adj_Q5[ i ] = silk_DIV32_16( silk_LSHIFT( (opus_int32)pW_QW[ i ], 5 ), W_tmp_QW[ i ] );\n        }\n\n        /* Unpack entropy table indices and predictor for current CB1 index */\n        silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, ind1 );\n\n        /* Trellis quantizer */\n        RD_Q25[ s ] = silk_NLSF_del_dec_quant( &tempIndices2[ s * MAX_LPC_ORDER ], res_Q10, W_adj_Q5, pred_Q8, ec_ix,\n            psNLSF_CB->ec_Rates_Q5, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->invQuantStepSize_Q6, NLSF_mu_Q20, psNLSF_CB->order );\n\n        /* Add rate for first stage */\n        iCDF_ptr = &psNLSF_CB->CB1_iCDF[ ( signalType >> 1 ) * psNLSF_CB->nVectors ];\n        if( ind1 == 0 ) {\n            prob_Q8 = 256 - iCDF_ptr[ ind1 ];\n        } else {\n            prob_Q8 = iCDF_ptr[ ind1 - 1 ] - iCDF_ptr[ ind1 ];\n        }\n        bits_q7 = ( 8 << 7 ) - silk_lin2log( prob_Q8 );\n        RD_Q25[ s ] = silk_SMLABB( RD_Q25[ s ], bits_q7, silk_RSHIFT( NLSF_mu_Q20, 2 ) );\n    }\n\n    /* Find the lowest rate-distortion error */\n    silk_insertion_sort_increasing( RD_Q25, &bestIndex, nSurvivors, 1 );\n\n    NLSFIndices[ 0 ] = (opus_int8)tempIndices1[ bestIndex ];\n    silk_memcpy( &NLSFIndices[ 1 ], &tempIndices2[ bestIndex * MAX_LPC_ORDER ], psNLSF_CB->order * sizeof( opus_int8 ) );\n\n    /* Decode */\n    silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB );\n\n    RESTORE_STACK;\n    return RD_Q25[ 0 ];\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/NLSF_stabilize.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* NLSF stabilizer:                                         */\n/*                                                          */\n/* - Moves NLSFs further apart if they are too close        */\n/* - Moves NLSFs away from borders if they are too close    */\n/* - High effort to achieve a modification with minimum     */\n/*     Euclidean distance to input vector                   */\n/* - Output are sorted NLSF coefficients                    */\n/*                                                          */\n\n#include \"SigProc_FIX.h\"\n\n/* Constant Definitions */\n#define MAX_LOOPS        20\n\n/* NLSF stabilizer, for a single input data vector */\nvoid silk_NLSF_stabilize(\n          opus_int16            *NLSF_Q15,          /* I/O   Unstable/stabilized normalized LSF vector in Q15 [L]       */\n    const opus_int16            *NDeltaMin_Q15,     /* I     Min distance vector, NDeltaMin_Q15[L] must be >= 1 [L+1]   */\n    const opus_int              L                   /* I     Number of NLSF parameters in the input vector              */\n)\n{\n    opus_int   i, I=0, k, loops;\n    opus_int16 center_freq_Q15;\n    opus_int32 diff_Q15, min_diff_Q15, min_center_Q15, max_center_Q15;\n\n    /* This is necessary to ensure an output within range of a opus_int16 */\n    silk_assert( NDeltaMin_Q15[L] >= 1 );\n\n    for( loops = 0; loops < MAX_LOOPS; loops++ ) {\n        /**************************/\n        /* Find smallest distance */\n        /**************************/\n        /* First element */\n        min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0];\n        I = 0;\n        /* Middle elements */\n        for( i = 1; i <= L-1; i++ ) {\n            diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] );\n            if( diff_Q15 < min_diff_Q15 ) {\n                min_diff_Q15 = diff_Q15;\n                I = i;\n            }\n        }\n        /* Last element */\n        diff_Q15 = ( 1 << 15 ) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] );\n        if( diff_Q15 < min_diff_Q15 ) {\n            min_diff_Q15 = diff_Q15;\n            I = L;\n        }\n\n        /***************************************************/\n        /* Now check if the smallest distance non-negative */\n        /***************************************************/\n        if( min_diff_Q15 >= 0 ) {\n            return;\n        }\n\n        if( I == 0 ) {\n            /* Move away from lower limit */\n            NLSF_Q15[0] = NDeltaMin_Q15[0];\n\n        } else if( I == L) {\n            /* Move away from higher limit */\n            NLSF_Q15[L-1] = ( 1 << 15 ) - NDeltaMin_Q15[L];\n\n        } else {\n            /* Find the lower extreme for the location of the current center frequency */\n            min_center_Q15 = 0;\n            for( k = 0; k < I; k++ ) {\n                min_center_Q15 += NDeltaMin_Q15[k];\n            }\n            min_center_Q15 += silk_RSHIFT( NDeltaMin_Q15[I], 1 );\n\n            /* Find the upper extreme for the location of the current center frequency */\n            max_center_Q15 = 1 << 15;\n            for( k = L; k > I; k-- ) {\n                max_center_Q15 -= NDeltaMin_Q15[k];\n            }\n            max_center_Q15 -= silk_RSHIFT( NDeltaMin_Q15[I], 1 );\n\n            /* Move apart, sorted by value, keeping the same center frequency */\n            center_freq_Q15 = (opus_int16)silk_LIMIT_32( silk_RSHIFT_ROUND( (opus_int32)NLSF_Q15[I-1] + (opus_int32)NLSF_Q15[I], 1 ),\n                min_center_Q15, max_center_Q15 );\n            NLSF_Q15[I-1] = center_freq_Q15 - silk_RSHIFT( NDeltaMin_Q15[I], 1 );\n            NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I];\n        }\n    }\n\n    /* Safe and simple fall back method, which is less ideal than the above */\n    if( loops == MAX_LOOPS )\n    {\n        /* Insertion sort (fast for already almost sorted arrays):   */\n        /* Best case:  O(n)   for an already sorted array            */\n        /* Worst case: O(n^2) for an inversely sorted array          */\n        silk_insertion_sort_increasing_all_values_int16( &NLSF_Q15[0], L );\n\n        /* First NLSF should be no less than NDeltaMin[0] */\n        NLSF_Q15[0] = silk_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] );\n\n        /* Keep delta_min distance between the NLSFs */\n        for( i = 1; i < L; i++ )\n            NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] );\n\n        /* Last NLSF should be no higher than 1 - NDeltaMin[L] */\n        NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] );\n\n        /* Keep NDeltaMin distance between the NLSFs */\n        for( i = L-2; i >= 0; i-- )\n            NLSF_Q15[i] = silk_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/NLSF_unpack.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Unpack predictor values and indices for entropy coding tables */\nvoid silk_NLSF_unpack(\n          opus_int16            ec_ix[],                        /* O    Indices to entropy tables [ LPC_ORDER ]     */\n          opus_uint8            pred_Q8[],                      /* O    LSF predictor [ LPC_ORDER ]                 */\n    const silk_NLSF_CB_struct   *psNLSF_CB,                     /* I    Codebook object                             */\n    const opus_int              CB1_index                       /* I    Index of vector in first LSF codebook       */\n)\n{\n    opus_int   i;\n    opus_uint8 entry;\n    const opus_uint8 *ec_sel_ptr;\n\n    ec_sel_ptr = &psNLSF_CB->ec_sel[ CB1_index * psNLSF_CB->order / 2 ];\n    for( i = 0; i < psNLSF_CB->order; i += 2 ) {\n        entry = *ec_sel_ptr++;\n        ec_ix  [ i     ] = silk_SMULBB( silk_RSHIFT( entry, 1 ) & 7, 2 * NLSF_QUANT_MAX_AMPLITUDE + 1 );\n        pred_Q8[ i     ] = psNLSF_CB->pred_Q8[ i + ( entry & 1 ) * ( psNLSF_CB->order - 1 ) ];\n        ec_ix  [ i + 1 ] = silk_SMULBB( silk_RSHIFT( entry, 5 ) & 7, 2 * NLSF_QUANT_MAX_AMPLITUDE + 1 );\n        pred_Q8[ i + 1 ] = psNLSF_CB->pred_Q8[ i + ( silk_RSHIFT( entry, 4 ) & 1 ) * ( psNLSF_CB->order - 1 ) + 1 ];\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/NSQ.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"stack_alloc.h\"\n\nstatic OPUS_INLINE void silk_nsq_scale_states(\n    const silk_encoder_state *psEncC,           /* I    Encoder State                   */\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */\n    const opus_int32    x_Q3[],                 /* I    input in Q3                     */\n    opus_int32          x_sc_Q10[],             /* O    input scaled with 1/Gain        */\n    const opus_int16    sLTP[],                 /* I    re-whitened LTP state in Q0     */\n    opus_int32          sLTP_Q15[],             /* O    LTP state matching scaled input */\n    opus_int            subfr,                  /* I    subframe number                 */\n    const opus_int      LTP_scale_Q14,          /* I                                    */\n    const opus_int32    Gains_Q16[ MAX_NB_SUBFR ], /* I                                 */\n    const opus_int      pitchL[ MAX_NB_SUBFR ], /* I    Pitch lag                       */\n    const opus_int      signal_type             /* I    Signal type                     */\n);\n\n#if !defined(OPUS_X86_MAY_HAVE_SSE4_1)\nstatic OPUS_INLINE void silk_noise_shape_quantizer(\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */\n    opus_int            signalType,             /* I    Signal type                     */\n    const opus_int32    x_sc_Q10[],             /* I                                    */\n    opus_int8           pulses[],               /* O                                    */\n    opus_int16          xq[],                   /* O                                    */\n    opus_int32          sLTP_Q15[],             /* I/O  LTP state                       */\n    const opus_int16    a_Q12[],                /* I    Short term prediction coefs     */\n    const opus_int16    b_Q14[],                /* I    Long term prediction coefs      */\n    const opus_int16    AR_shp_Q13[],           /* I    Noise shaping AR coefs          */\n    opus_int            lag,                    /* I    Pitch lag                       */\n    opus_int32          HarmShapeFIRPacked_Q14, /* I                                    */\n    opus_int            Tilt_Q14,               /* I    Spectral tilt                   */\n    opus_int32          LF_shp_Q14,             /* I                                    */\n    opus_int32          Gain_Q16,               /* I                                    */\n    opus_int            Lambda_Q10,             /* I                                    */\n    opus_int            offset_Q10,             /* I                                    */\n    opus_int            length,                 /* I    Input length                    */\n    opus_int            shapingLPCOrder,        /* I    Noise shaping AR filter order   */\n    opus_int            predictLPCOrder         /* I    Prediction filter order         */\n);\n#endif\n\nvoid silk_NSQ_c\n(\n    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */\n    silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */\n    SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */\n    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */\n    opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */\n    const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */\n    const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */\n    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */\n    const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */\n    const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */\n    const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */\n    const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */\n    const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */\n    const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */\n    const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */\n)\n{\n    opus_int            k, lag, start_idx, LSF_interpolation_flag;\n    const opus_int16    *A_Q12, *B_Q14, *AR_shp_Q13;\n    opus_int16          *pxq;\n    VARDECL( opus_int32, sLTP_Q15 );\n    VARDECL( opus_int16, sLTP );\n    opus_int32          HarmShapeFIRPacked_Q14;\n    opus_int            offset_Q10;\n    VARDECL( opus_int32, x_sc_Q10 );\n    SAVE_STACK;\n\n    NSQ->rand_seed = psIndices->Seed;\n\n    /* Set unvoiced lag to the previous one, overwrite later for voiced */\n    lag = NSQ->lagPrev;\n\n    silk_assert( NSQ->prev_gain_Q16 != 0 );\n\n    offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];\n\n    if( psIndices->NLSFInterpCoef_Q2 == 4 ) {\n        LSF_interpolation_flag = 0;\n    } else {\n        LSF_interpolation_flag = 1;\n    }\n\n    ALLOC( sLTP_Q15,\n           psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );\n    ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );\n    ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );\n    /* Set up pointers to start of sub frame */\n    NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;\n    NSQ->sLTP_buf_idx     = psEncC->ltp_mem_length;\n    pxq                   = &NSQ->xq[ psEncC->ltp_mem_length ];\n    for( k = 0; k < psEncC->nb_subfr; k++ ) {\n        A_Q12      = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];\n        B_Q14      = &LTPCoef_Q14[ k * LTP_ORDER ];\n        AR_shp_Q13 = &AR2_Q13[     k * MAX_SHAPE_LPC_ORDER ];\n\n        /* Noise shape parameters */\n        silk_assert( HarmShapeGain_Q14[ k ] >= 0 );\n        HarmShapeFIRPacked_Q14  =                          silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );\n        HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );\n\n        NSQ->rewhite_flag = 0;\n        if( psIndices->signalType == TYPE_VOICED ) {\n            /* Voiced */\n            lag = pitchL[ k ];\n\n            /* Re-whitening */\n            if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {\n                /* Rewhiten with new A coefs */\n                start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;\n                silk_assert( start_idx > 0 );\n\n                silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],\n                    A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );\n\n                NSQ->rewhite_flag = 1;\n                NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;\n            }\n        }\n\n        silk_nsq_scale_states( psEncC, NSQ, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );\n\n        silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,\n            AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,\n            offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder );\n\n        x_Q3   += psEncC->subfr_length;\n        pulses += psEncC->subfr_length;\n        pxq    += psEncC->subfr_length;\n    }\n\n    /* Update lagPrev for next frame */\n    NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];\n\n    /* Save quantized speech and noise shaping signals */\n    /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int16 ) ) */\n    silk_memmove( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );\n    silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );\n    RESTORE_STACK;\n}\n\n/***********************************/\n/* silk_noise_shape_quantizer  */\n/***********************************/\n\n#if !defined(OPUS_X86_MAY_HAVE_SSE4_1)\nstatic OPUS_INLINE\n#endif\nvoid silk_noise_shape_quantizer(\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */\n    opus_int            signalType,             /* I    Signal type                     */\n    const opus_int32    x_sc_Q10[],             /* I                                    */\n    opus_int8           pulses[],               /* O                                    */\n    opus_int16          xq[],                   /* O                                    */\n    opus_int32          sLTP_Q15[],             /* I/O  LTP state                       */\n    const opus_int16    a_Q12[],                /* I    Short term prediction coefs     */\n    const opus_int16    b_Q14[],                /* I    Long term prediction coefs      */\n    const opus_int16    AR_shp_Q13[],           /* I    Noise shaping AR coefs          */\n    opus_int            lag,                    /* I    Pitch lag                       */\n    opus_int32          HarmShapeFIRPacked_Q14, /* I                                    */\n    opus_int            Tilt_Q14,               /* I    Spectral tilt                   */\n    opus_int32          LF_shp_Q14,             /* I                                    */\n    opus_int32          Gain_Q16,               /* I                                    */\n    opus_int            Lambda_Q10,             /* I                                    */\n    opus_int            offset_Q10,             /* I                                    */\n    opus_int            length,                 /* I    Input length                    */\n    opus_int            shapingLPCOrder,        /* I    Noise shaping AR filter order   */\n    opus_int            predictLPCOrder         /* I    Prediction filter order         */\n)\n{\n    opus_int     i, j;\n    opus_int32   LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13;\n    opus_int32   n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20;\n    opus_int32   exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;\n    opus_int32   tmp1, tmp2, sLF_AR_shp_Q14;\n    opus_int32   *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;\n\n    shp_lag_ptr  = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];\n    pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];\n    Gain_Q10     = silk_RSHIFT( Gain_Q16, 6 );\n\n    /* Set up short term AR state */\n    psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];\n\n    for( i = 0; i < length; i++ ) {\n        /* Generate dither */\n        NSQ->rand_seed = silk_RAND( NSQ->rand_seed );\n\n        /* Short-term prediction */\n        silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );\n        /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n        LPC_pred_Q10 = silk_RSHIFT( predictLPCOrder, 1 );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[  0 ], a_Q12[ 0 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -3 ], a_Q12[ 3 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], a_Q12[ 4 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -5 ], a_Q12[ 5 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], a_Q12[ 6 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] );\n        if( predictLPCOrder == 16 ) {\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -10 ], a_Q12[ 10 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -11 ], a_Q12[ 11 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -12 ], a_Q12[ 12 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -13 ], a_Q12[ 13 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -14 ], a_Q12[ 14 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -15 ], a_Q12[ 15 ] );\n        }\n\n        /* Long-term prediction */\n        if( signalType == TYPE_VOICED ) {\n            /* Unrolled loop */\n            /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n            LTP_pred_Q13 = 2;\n            LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[  0 ], b_Q14[ 0 ] );\n            LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );\n            LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );\n            LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );\n            LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );\n            pred_lag_ptr++;\n        } else {\n            LTP_pred_Q13 = 0;\n        }\n\n        /* Noise shape feedback */\n        silk_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */\n        tmp2 = psLPC_Q14[ 0 ];\n        tmp1 = NSQ->sAR2_Q14[ 0 ];\n        NSQ->sAR2_Q14[ 0 ] = tmp2;\n        n_AR_Q12 = silk_RSHIFT( shapingLPCOrder, 1 );\n        n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp2, AR_shp_Q13[ 0 ] );\n        for( j = 2; j < shapingLPCOrder; j += 2 ) {\n            tmp2 = NSQ->sAR2_Q14[ j - 1 ];\n            NSQ->sAR2_Q14[ j - 1 ] = tmp1;\n            n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp1, AR_shp_Q13[ j - 1 ] );\n            tmp1 = NSQ->sAR2_Q14[ j + 0 ];\n            NSQ->sAR2_Q14[ j + 0 ] = tmp2;\n            n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp2, AR_shp_Q13[ j ] );\n        }\n        NSQ->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;\n        n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );\n\n        n_AR_Q12 = silk_LSHIFT32( n_AR_Q12, 1 );                                /* Q11 -> Q12 */\n        n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 );\n\n        n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 );\n        n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 );\n\n        silk_assert( lag > 0 || signalType != TYPE_VOICED );\n\n        /* Combine prediction and noise shaping signals */\n        tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 );        /* Q12 */\n        tmp1 = silk_SUB32( tmp1, n_LF_Q12 );                                    /* Q12 */\n        if( lag > 0 ) {\n            /* Symmetric, packed FIR coefficients */\n            n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );\n            n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ],                      HarmShapeFIRPacked_Q14 );\n            n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 );\n            shp_lag_ptr++;\n\n            tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 );                       /* Q13 */\n            tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 );                          /* Q13 */\n            tmp1 = silk_RSHIFT_ROUND( tmp1, 3 );                                /* Q10 */\n        } else {\n            tmp1 = silk_RSHIFT_ROUND( tmp1, 2 );                                /* Q10 */\n        }\n\n        r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 );                              /* residual error Q10 */\n\n        /* Flip sign depending on dither */\n        if ( NSQ->rand_seed < 0 ) {\n           r_Q10 = -r_Q10;\n        }\n        r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );\n\n        /* Find two quantization level candidates and measure their rate-distortion */\n        q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );\n        q1_Q0 = silk_RSHIFT( q1_Q10, 10 );\n        if( q1_Q0 > 0 ) {\n            q1_Q10  = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );\n            q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );\n            q2_Q10  = silk_ADD32( q1_Q10, 1024 );\n            rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 );\n            rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );\n        } else if( q1_Q0 == 0 ) {\n            q1_Q10  = offset_Q10;\n            q2_Q10  = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );\n            rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 );\n            rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );\n        } else if( q1_Q0 == -1 ) {\n            q2_Q10  = offset_Q10;\n            q1_Q10  = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );\n            rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 );\n            rd2_Q20 = silk_SMULBB(  q2_Q10, Lambda_Q10 );\n        } else {            /* Q1_Q0 < -1 */\n            q1_Q10  = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );\n            q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );\n            q2_Q10  = silk_ADD32( q1_Q10, 1024 );\n            rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 );\n            rd2_Q20 = silk_SMULBB( -q2_Q10, Lambda_Q10 );\n        }\n        rr_Q10  = silk_SUB32( r_Q10, q1_Q10 );\n        rd1_Q20 = silk_SMLABB( rd1_Q20, rr_Q10, rr_Q10 );\n        rr_Q10  = silk_SUB32( r_Q10, q2_Q10 );\n        rd2_Q20 = silk_SMLABB( rd2_Q20, rr_Q10, rr_Q10 );\n\n        if( rd2_Q20 < rd1_Q20 ) {\n            q1_Q10 = q2_Q10;\n        }\n\n        pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 );\n\n        /* Excitation */\n        exc_Q14 = silk_LSHIFT( q1_Q10, 4 );\n        if ( NSQ->rand_seed < 0 ) {\n           exc_Q14 = -exc_Q14;\n        }\n\n        /* Add predictions */\n        LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 );\n        xq_Q14      = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 );\n\n        /* Scale XQ back to normal level before saving */\n        xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q14, Gain_Q10 ), 8 ) );\n\n        /* Update states */\n        psLPC_Q14++;\n        *psLPC_Q14 = xq_Q14;\n        sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, n_AR_Q12, 2 );\n        NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14;\n\n        NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 );\n        sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 );\n        NSQ->sLTP_shp_buf_idx++;\n        NSQ->sLTP_buf_idx++;\n\n        /* Make dither dependent on quantized signal */\n        NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] );\n    }\n\n    /* Update LPC synth buffer */\n    silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );\n}\n\nstatic OPUS_INLINE void silk_nsq_scale_states(\n    const silk_encoder_state *psEncC,           /* I    Encoder State                   */\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */\n    const opus_int32    x_Q3[],                 /* I    input in Q3                     */\n    opus_int32          x_sc_Q10[],             /* O    input scaled with 1/Gain        */\n    const opus_int16    sLTP[],                 /* I    re-whitened LTP state in Q0     */\n    opus_int32          sLTP_Q15[],             /* O    LTP state matching scaled input */\n    opus_int            subfr,                  /* I    subframe number                 */\n    const opus_int      LTP_scale_Q14,          /* I                                    */\n    const opus_int32    Gains_Q16[ MAX_NB_SUBFR ], /* I                                 */\n    const opus_int      pitchL[ MAX_NB_SUBFR ], /* I    Pitch lag                       */\n    const opus_int      signal_type             /* I    Signal type                     */\n)\n{\n    opus_int   i, lag;\n    opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;\n\n    lag          = pitchL[ subfr ];\n    inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );\n    silk_assert( inv_gain_Q31 != 0 );\n\n    /* Calculate gain adjustment factor */\n    if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {\n        gain_adj_Q16 =  silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );\n    } else {\n        gain_adj_Q16 = (opus_int32)1 << 16;\n    }\n\n    /* Scale input */\n    inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );\n    for( i = 0; i < psEncC->subfr_length; i++ ) {\n        x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );\n    }\n\n    /* Save inverse gain */\n    NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];\n\n    /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */\n    if( NSQ->rewhite_flag ) {\n        if( subfr == 0 ) {\n            /* Do LTP downscaling */\n            inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );\n        }\n        for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {\n            silk_assert( i < MAX_FRAME_LENGTH );\n            sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );\n        }\n    }\n\n    /* Adjust for changing gain */\n    if( gain_adj_Q16 != (opus_int32)1 << 16 ) {\n        /* Scale long-term shaping state */\n        for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {\n            NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );\n        }\n\n        /* Scale long-term prediction state */\n        if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {\n            for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {\n                sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );\n            }\n        }\n\n        NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 );\n\n        /* Scale short-term prediction and shaping states */\n        for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {\n            NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );\n        }\n        for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {\n            NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );\n        }\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/NSQ_del_dec.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"stack_alloc.h\"\n\ntypedef struct {\n    opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];\n    opus_int32 RandState[ DECISION_DELAY ];\n    opus_int32 Q_Q10[     DECISION_DELAY ];\n    opus_int32 Xq_Q14[    DECISION_DELAY ];\n    opus_int32 Pred_Q15[  DECISION_DELAY ];\n    opus_int32 Shape_Q14[ DECISION_DELAY ];\n    opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];\n    opus_int32 LF_AR_Q14;\n    opus_int32 Seed;\n    opus_int32 SeedInit;\n    opus_int32 RD_Q10;\n} NSQ_del_dec_struct;\n\ntypedef struct {\n    opus_int32 Q_Q10;\n    opus_int32 RD_Q10;\n    opus_int32 xq_Q14;\n    opus_int32 LF_AR_Q14;\n    opus_int32 sLTP_shp_Q14;\n    opus_int32 LPC_exc_Q14;\n} NSQ_sample_struct;\n\ntypedef NSQ_sample_struct  NSQ_sample_pair[ 2 ];\n\n#if defined(MIPSr1_ASM)\n#include \"mips/NSQ_del_dec_mipsr1.h\"\n#endif\nstatic OPUS_INLINE void silk_nsq_del_dec_scale_states(\n    const silk_encoder_state *psEncC,               /* I    Encoder State                       */\n    silk_nsq_state      *NSQ,                       /* I/O  NSQ state                           */\n    NSQ_del_dec_struct  psDelDec[],                 /* I/O  Delayed decision states             */\n    const opus_int32    x_Q3[],                     /* I    Input in Q3                         */\n    opus_int32          x_sc_Q10[],                 /* O    Input scaled with 1/Gain in Q10     */\n    const opus_int16    sLTP[],                     /* I    Re-whitened LTP state in Q0         */\n    opus_int32          sLTP_Q15[],                 /* O    LTP state matching scaled input     */\n    opus_int            subfr,                      /* I    Subframe number                     */\n    opus_int            nStatesDelayedDecision,     /* I    Number of del dec states            */\n    const opus_int      LTP_scale_Q14,              /* I    LTP state scaling                   */\n    const opus_int32    Gains_Q16[ MAX_NB_SUBFR ],  /* I                                        */\n    const opus_int      pitchL[ MAX_NB_SUBFR ],     /* I    Pitch lag                           */\n    const opus_int      signal_type,                /* I    Signal type                         */\n    const opus_int      decisionDelay               /* I    Decision delay                      */\n);\n\n/******************************************/\n/* Noise shape quantizer for one subframe */\n/******************************************/\nstatic OPUS_INLINE void silk_noise_shape_quantizer_del_dec(\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                           */\n    NSQ_del_dec_struct  psDelDec[],             /* I/O  Delayed decision states             */\n    opus_int            signalType,             /* I    Signal type                         */\n    const opus_int32    x_Q10[],                /* I                                        */\n    opus_int8           pulses[],               /* O                                        */\n    opus_int16          xq[],                   /* O                                        */\n    opus_int32          sLTP_Q15[],             /* I/O  LTP filter state                    */\n    opus_int32          delayedGain_Q10[],      /* I/O  Gain delay buffer                   */\n    const opus_int16    a_Q12[],                /* I    Short term prediction coefs         */\n    const opus_int16    b_Q14[],                /* I    Long term prediction coefs          */\n    const opus_int16    AR_shp_Q13[],           /* I    Noise shaping coefs                 */\n    opus_int            lag,                    /* I    Pitch lag                           */\n    opus_int32          HarmShapeFIRPacked_Q14, /* I                                        */\n    opus_int            Tilt_Q14,               /* I    Spectral tilt                       */\n    opus_int32          LF_shp_Q14,             /* I                                        */\n    opus_int32          Gain_Q16,               /* I                                        */\n    opus_int            Lambda_Q10,             /* I                                        */\n    opus_int            offset_Q10,             /* I                                        */\n    opus_int            length,                 /* I    Input length                        */\n    opus_int            subfr,                  /* I    Subframe number                     */\n    opus_int            shapingLPCOrder,        /* I    Shaping LPC filter order            */\n    opus_int            predictLPCOrder,        /* I    Prediction filter order             */\n    opus_int            warping_Q16,            /* I                                        */\n    opus_int            nStatesDelayedDecision, /* I    Number of states in decision tree   */\n    opus_int            *smpl_buf_idx,          /* I    Index to newest samples in buffers  */\n    opus_int            decisionDelay           /* I                                        */\n);\n\nvoid silk_NSQ_del_dec_c(\n    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */\n    silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */\n    SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */\n    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */\n    opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */\n    const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */\n    const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */\n    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */\n    const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */\n    const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */\n    const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */\n    const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */\n    const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */\n    const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */\n    const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */\n)\n{\n    opus_int            i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;\n    opus_int            last_smple_idx, smpl_buf_idx, decisionDelay;\n    const opus_int16    *A_Q12, *B_Q14, *AR_shp_Q13;\n    opus_int16          *pxq;\n    VARDECL( opus_int32, sLTP_Q15 );\n    VARDECL( opus_int16, sLTP );\n    opus_int32          HarmShapeFIRPacked_Q14;\n    opus_int            offset_Q10;\n    opus_int32          RDmin_Q10, Gain_Q10;\n    VARDECL( opus_int32, x_sc_Q10 );\n    VARDECL( opus_int32, delayedGain_Q10 );\n    VARDECL( NSQ_del_dec_struct, psDelDec );\n    NSQ_del_dec_struct  *psDD;\n    SAVE_STACK;\n\n    /* Set unvoiced lag to the previous one, overwrite later for voiced */\n    lag = NSQ->lagPrev;\n\n    silk_assert( NSQ->prev_gain_Q16 != 0 );\n\n    /* Initialize delayed decision states */\n    ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct );\n    silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );\n    for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {\n        psDD                 = &psDelDec[ k ];\n        psDD->Seed           = ( k + psIndices->Seed ) & 3;\n        psDD->SeedInit       = psDD->Seed;\n        psDD->RD_Q10         = 0;\n        psDD->LF_AR_Q14      = NSQ->sLF_AR_shp_Q14;\n        psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ];\n        silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );\n        silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );\n    }\n\n    offset_Q10   = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];\n    smpl_buf_idx = 0; /* index of oldest samples */\n\n    decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );\n\n    /* For voiced frames limit the decision delay to lower than the pitch lag */\n    if( psIndices->signalType == TYPE_VOICED ) {\n        for( k = 0; k < psEncC->nb_subfr; k++ ) {\n            decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 );\n        }\n    } else {\n        if( lag > 0 ) {\n            decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );\n        }\n    }\n\n    if( psIndices->NLSFInterpCoef_Q2 == 4 ) {\n        LSF_interpolation_flag = 0;\n    } else {\n        LSF_interpolation_flag = 1;\n    }\n\n    ALLOC( sLTP_Q15,\n           psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );\n    ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );\n    ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );\n    ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );\n    /* Set up pointers to start of sub frame */\n    pxq                   = &NSQ->xq[ psEncC->ltp_mem_length ];\n    NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;\n    NSQ->sLTP_buf_idx     = psEncC->ltp_mem_length;\n    subfr = 0;\n    for( k = 0; k < psEncC->nb_subfr; k++ ) {\n        A_Q12      = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];\n        B_Q14      = &LTPCoef_Q14[ k * LTP_ORDER           ];\n        AR_shp_Q13 = &AR2_Q13[     k * MAX_SHAPE_LPC_ORDER ];\n\n        /* Noise shape parameters */\n        silk_assert( HarmShapeGain_Q14[ k ] >= 0 );\n        HarmShapeFIRPacked_Q14  =                          silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );\n        HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );\n\n        NSQ->rewhite_flag = 0;\n        if( psIndices->signalType == TYPE_VOICED ) {\n            /* Voiced */\n            lag = pitchL[ k ];\n\n            /* Re-whitening */\n            if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {\n                if( k == 2 ) {\n                    /* RESET DELAYED DECISIONS */\n                    /* Find winner */\n                    RDmin_Q10 = psDelDec[ 0 ].RD_Q10;\n                    Winner_ind = 0;\n                    for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {\n                        if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {\n                            RDmin_Q10 = psDelDec[ i ].RD_Q10;\n                            Winner_ind = i;\n                        }\n                    }\n                    for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {\n                        if( i != Winner_ind ) {\n                            psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 );\n                            silk_assert( psDelDec[ i ].RD_Q10 >= 0 );\n                        }\n                    }\n\n                    /* Copy final part of signals from winner state to output and long-term filter states */\n                    psDD = &psDelDec[ Winner_ind ];\n                    last_smple_idx = smpl_buf_idx + decisionDelay;\n                    for( i = 0; i < decisionDelay; i++ ) {\n                        last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;\n                        pulses[   i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );\n                        pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(\n                            silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );\n                        NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];\n                    }\n\n                    subfr = 0;\n                }\n\n                /* Rewhiten with new A coefs */\n                start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;\n                silk_assert( start_idx > 0 );\n\n                silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],\n                    A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );\n\n                NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;\n                NSQ->rewhite_flag = 1;\n            }\n        }\n\n        silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k,\n            psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );\n\n        silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,\n            delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],\n            Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,\n            psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );\n\n        x_Q3   += psEncC->subfr_length;\n        pulses += psEncC->subfr_length;\n        pxq    += psEncC->subfr_length;\n    }\n\n    /* Find winner */\n    RDmin_Q10 = psDelDec[ 0 ].RD_Q10;\n    Winner_ind = 0;\n    for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {\n        if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {\n            RDmin_Q10 = psDelDec[ k ].RD_Q10;\n            Winner_ind = k;\n        }\n    }\n\n    /* Copy final part of signals from winner state to output and long-term filter states */\n    psDD = &psDelDec[ Winner_ind ];\n    psIndices->Seed = psDD->SeedInit;\n    last_smple_idx = smpl_buf_idx + decisionDelay;\n    Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );\n    for( i = 0; i < decisionDelay; i++ ) {\n        last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;\n        pulses[   i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );\n        pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(\n            silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );\n        NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];\n    }\n    silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );\n    silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );\n\n    /* Update states */\n    NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14;\n    NSQ->lagPrev        = pitchL[ psEncC->nb_subfr - 1 ];\n\n    /* Save quantized speech signal */\n    /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */\n    silk_memmove( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );\n    silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );\n    RESTORE_STACK;\n}\n\n/******************************************/\n/* Noise shape quantizer for one subframe */\n/******************************************/\n#ifndef OVERRIDE_silk_noise_shape_quantizer_del_dec\nstatic OPUS_INLINE void silk_noise_shape_quantizer_del_dec(\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                           */\n    NSQ_del_dec_struct  psDelDec[],             /* I/O  Delayed decision states             */\n    opus_int            signalType,             /* I    Signal type                         */\n    const opus_int32    x_Q10[],                /* I                                        */\n    opus_int8           pulses[],               /* O                                        */\n    opus_int16          xq[],                   /* O                                        */\n    opus_int32          sLTP_Q15[],             /* I/O  LTP filter state                    */\n    opus_int32          delayedGain_Q10[],      /* I/O  Gain delay buffer                   */\n    const opus_int16    a_Q12[],                /* I    Short term prediction coefs         */\n    const opus_int16    b_Q14[],                /* I    Long term prediction coefs          */\n    const opus_int16    AR_shp_Q13[],           /* I    Noise shaping coefs                 */\n    opus_int            lag,                    /* I    Pitch lag                           */\n    opus_int32          HarmShapeFIRPacked_Q14, /* I                                        */\n    opus_int            Tilt_Q14,               /* I    Spectral tilt                       */\n    opus_int32          LF_shp_Q14,             /* I                                        */\n    opus_int32          Gain_Q16,               /* I                                        */\n    opus_int            Lambda_Q10,             /* I                                        */\n    opus_int            offset_Q10,             /* I                                        */\n    opus_int            length,                 /* I    Input length                        */\n    opus_int            subfr,                  /* I    Subframe number                     */\n    opus_int            shapingLPCOrder,        /* I    Shaping LPC filter order            */\n    opus_int            predictLPCOrder,        /* I    Prediction filter order             */\n    opus_int            warping_Q16,            /* I                                        */\n    opus_int            nStatesDelayedDecision, /* I    Number of states in decision tree   */\n    opus_int            *smpl_buf_idx,          /* I    Index to newest samples in buffers  */\n    opus_int            decisionDelay           /* I                                        */\n)\n{\n    opus_int     i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;\n    opus_int32   Winner_rand_state;\n    opus_int32   LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;\n    opus_int32   n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;\n    opus_int32   q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;\n    opus_int32   tmp1, tmp2, sLF_AR_shp_Q14;\n    opus_int32   *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;\n    VARDECL( NSQ_sample_pair, psSampleState );\n    NSQ_del_dec_struct *psDD;\n    NSQ_sample_struct  *psSS;\n    SAVE_STACK;\n\n    silk_assert( nStatesDelayedDecision > 0 );\n    ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );\n\n    shp_lag_ptr  = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];\n    pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];\n    Gain_Q10     = silk_RSHIFT( Gain_Q16, 6 );\n\n    for( i = 0; i < length; i++ ) {\n        /* Perform common calculations used in all states */\n\n        /* Long-term prediction */\n        if( signalType == TYPE_VOICED ) {\n            /* Unrolled loop */\n            /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n            LTP_pred_Q14 = 2;\n            LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[  0 ], b_Q14[ 0 ] );\n            LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );\n            LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );\n            LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );\n            LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );\n            LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 );                          /* Q13 -> Q14 */\n            pred_lag_ptr++;\n        } else {\n            LTP_pred_Q14 = 0;\n        }\n\n        /* Long-term shaping */\n        if( lag > 0 ) {\n            /* Symmetric, packed FIR coefficients */\n            n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );\n            n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ],                      HarmShapeFIRPacked_Q14 );\n            n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 );            /* Q12 -> Q14 */\n            shp_lag_ptr++;\n        } else {\n            n_LTP_Q14 = 0;\n        }\n\n        for( k = 0; k < nStatesDelayedDecision; k++ ) {\n            /* Delayed decision state */\n            psDD = &psDelDec[ k ];\n\n            /* Sample state */\n            psSS = psSampleState[ k ];\n\n            /* Generate dither */\n            psDD->Seed = silk_RAND( psDD->Seed );\n\n            /* Pointer used in short term prediction and shaping */\n            psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];\n            /* Short-term prediction */\n            silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );\n            /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n            LPC_pred_Q14 = silk_RSHIFT( predictLPCOrder, 1 );\n            LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[  0 ], a_Q12[ 0 ] );\n            LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -1 ], a_Q12[ 1 ] );\n            LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -2 ], a_Q12[ 2 ] );\n            LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -3 ], a_Q12[ 3 ] );\n            LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -4 ], a_Q12[ 4 ] );\n            LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -5 ], a_Q12[ 5 ] );\n            LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -6 ], a_Q12[ 6 ] );\n            LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -7 ], a_Q12[ 7 ] );\n            LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -8 ], a_Q12[ 8 ] );\n            LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -9 ], a_Q12[ 9 ] );\n            if( predictLPCOrder == 16 ) {\n                LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -10 ], a_Q12[ 10 ] );\n                LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -11 ], a_Q12[ 11 ] );\n                LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -12 ], a_Q12[ 12 ] );\n                LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -13 ], a_Q12[ 13 ] );\n                LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -14 ], a_Q12[ 14 ] );\n                LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -15 ], a_Q12[ 15 ] );\n            }\n            LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 );                              /* Q10 -> Q14 */\n\n            /* Noise shape feedback */\n            silk_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */\n            /* Output of lowpass section */\n            tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );\n            /* Output of allpass section */\n            tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );\n            psDD->sAR2_Q14[ 0 ] = tmp2;\n            n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 );\n            n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] );\n            /* Loop over allpass sections */\n            for( j = 2; j < shapingLPCOrder; j += 2 ) {\n                /* Output of allpass section */\n                tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 );\n                psDD->sAR2_Q14[ j - 1 ] = tmp1;\n                n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] );\n                /* Output of allpass section */\n                tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 );\n                psDD->sAR2_Q14[ j + 0 ] = tmp2;\n                n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] );\n            }\n            psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;\n            n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );\n\n            n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 );                                      /* Q11 -> Q12 */\n            n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 );              /* Q12 */\n            n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 );                                      /* Q12 -> Q14 */\n\n            n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 );     /* Q12 */\n            n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 );            /* Q12 */\n            n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 );                                      /* Q12 -> Q14 */\n\n            /* Input minus prediction plus noise feedback                       */\n            /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP  */\n            tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 );                                    /* Q14 */\n            tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 );                               /* Q13 */\n            tmp1 = silk_SUB32( tmp2, tmp1 );                                            /* Q13 */\n            tmp1 = silk_RSHIFT_ROUND( tmp1, 4 );                                        /* Q10 */\n\n            r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 );                                     /* residual error Q10 */\n\n            /* Flip sign depending on dither */\n            if ( psDD->Seed < 0 ) {\n                r_Q10 = -r_Q10;\n            }\n            r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );\n\n            /* Find two quantization level candidates and measure their rate-distortion */\n            q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );\n            q1_Q0 = silk_RSHIFT( q1_Q10, 10 );\n            if( q1_Q0 > 0 ) {\n                q1_Q10  = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );\n                q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );\n                q2_Q10  = silk_ADD32( q1_Q10, 1024 );\n                rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );\n                rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );\n            } else if( q1_Q0 == 0 ) {\n                q1_Q10  = offset_Q10;\n                q2_Q10  = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );\n                rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );\n                rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );\n            } else if( q1_Q0 == -1 ) {\n                q2_Q10  = offset_Q10;\n                q1_Q10  = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );\n                rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );\n                rd2_Q10 = silk_SMULBB(  q2_Q10, Lambda_Q10 );\n            } else {            /* q1_Q0 < -1 */\n                q1_Q10  = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );\n                q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );\n                q2_Q10  = silk_ADD32( q1_Q10, 1024 );\n                rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );\n                rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );\n            }\n            rr_Q10  = silk_SUB32( r_Q10, q1_Q10 );\n            rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );\n            rr_Q10  = silk_SUB32( r_Q10, q2_Q10 );\n            rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );\n\n            if( rd1_Q10 < rd2_Q10 ) {\n                psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );\n                psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );\n                psSS[ 0 ].Q_Q10  = q1_Q10;\n                psSS[ 1 ].Q_Q10  = q2_Q10;\n            } else {\n                psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );\n                psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );\n                psSS[ 0 ].Q_Q10  = q2_Q10;\n                psSS[ 1 ].Q_Q10  = q1_Q10;\n            }\n\n            /* Update states for best quantization */\n\n            /* Quantized excitation */\n            exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );\n            if ( psDD->Seed < 0 ) {\n                exc_Q14 = -exc_Q14;\n            }\n\n            /* Add predictions */\n            LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );\n            xq_Q14      = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );\n\n            /* Update states */\n            sLF_AR_shp_Q14         = silk_SUB32( xq_Q14, n_AR_Q14 );\n            psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );\n            psSS[ 0 ].LF_AR_Q14    = sLF_AR_shp_Q14;\n            psSS[ 0 ].LPC_exc_Q14  = LPC_exc_Q14;\n            psSS[ 0 ].xq_Q14       = xq_Q14;\n\n            /* Update states for second best quantization */\n\n            /* Quantized excitation */\n            exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );\n            if ( psDD->Seed < 0 ) {\n                exc_Q14 = -exc_Q14;\n            }\n\n\n            /* Add predictions */\n            LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );\n            xq_Q14      = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );\n\n            /* Update states */\n            sLF_AR_shp_Q14         = silk_SUB32( xq_Q14, n_AR_Q14 );\n            psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );\n            psSS[ 1 ].LF_AR_Q14    = sLF_AR_shp_Q14;\n            psSS[ 1 ].LPC_exc_Q14  = LPC_exc_Q14;\n            psSS[ 1 ].xq_Q14       = xq_Q14;\n        }\n\n        *smpl_buf_idx  = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK;                   /* Index to newest samples              */\n        last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK;       /* Index to decisionDelay old samples   */\n\n        /* Find winner */\n        RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;\n        Winner_ind = 0;\n        for( k = 1; k < nStatesDelayedDecision; k++ ) {\n            if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {\n                RDmin_Q10  = psSampleState[ k ][ 0 ].RD_Q10;\n                Winner_ind = k;\n            }\n        }\n\n        /* Increase RD values of expired states */\n        Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];\n        for( k = 0; k < nStatesDelayedDecision; k++ ) {\n            if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {\n                psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );\n                psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );\n                silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );\n            }\n        }\n\n        /* Find worst in first set and best in second set */\n        RDmax_Q10  = psSampleState[ 0 ][ 0 ].RD_Q10;\n        RDmin_Q10  = psSampleState[ 0 ][ 1 ].RD_Q10;\n        RDmax_ind = 0;\n        RDmin_ind = 0;\n        for( k = 1; k < nStatesDelayedDecision; k++ ) {\n            /* find worst in first set */\n            if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {\n                RDmax_Q10  = psSampleState[ k ][ 0 ].RD_Q10;\n                RDmax_ind = k;\n            }\n            /* find best in second set */\n            if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {\n                RDmin_Q10  = psSampleState[ k ][ 1 ].RD_Q10;\n                RDmin_ind = k;\n            }\n        }\n\n        /* Replace a state if best from second set outperforms worst in first set */\n        if( RDmin_Q10 < RDmax_Q10 ) {\n            silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,\n                         ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );\n            silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );\n        }\n\n        /* Write samples from winner to output and long-term filter states */\n        psDD = &psDelDec[ Winner_ind ];\n        if( subfr > 0 || i >= decisionDelay ) {\n            pulses[  i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );\n            xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(\n                silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );\n            NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];\n            sLTP_Q15[          NSQ->sLTP_buf_idx     - decisionDelay ] = psDD->Pred_Q15[  last_smple_idx ];\n        }\n        NSQ->sLTP_shp_buf_idx++;\n        NSQ->sLTP_buf_idx++;\n\n        /* Update states */\n        for( k = 0; k < nStatesDelayedDecision; k++ ) {\n            psDD                                     = &psDelDec[ k ];\n            psSS                                     = &psSampleState[ k ][ 0 ];\n            psDD->LF_AR_Q14                          = psSS->LF_AR_Q14;\n            psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;\n            psDD->Xq_Q14[    *smpl_buf_idx ]         = psSS->xq_Q14;\n            psDD->Q_Q10[     *smpl_buf_idx ]         = psSS->Q_Q10;\n            psDD->Pred_Q15[  *smpl_buf_idx ]         = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );\n            psDD->Shape_Q14[ *smpl_buf_idx ]         = psSS->sLTP_shp_Q14;\n            psDD->Seed                               = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );\n            psDD->RandState[ *smpl_buf_idx ]         = psDD->Seed;\n            psDD->RD_Q10                             = psSS->RD_Q10;\n        }\n        delayedGain_Q10[     *smpl_buf_idx ]         = Gain_Q10;\n    }\n    /* Update LPC states */\n    for( k = 0; k < nStatesDelayedDecision; k++ ) {\n        psDD = &psDelDec[ k ];\n        silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );\n    }\n    RESTORE_STACK;\n}\n#endif /* OVERRIDE_silk_noise_shape_quantizer_del_dec */\n\nstatic OPUS_INLINE void silk_nsq_del_dec_scale_states(\n    const silk_encoder_state *psEncC,               /* I    Encoder State                       */\n    silk_nsq_state      *NSQ,                       /* I/O  NSQ state                           */\n    NSQ_del_dec_struct  psDelDec[],                 /* I/O  Delayed decision states             */\n    const opus_int32    x_Q3[],                     /* I    Input in Q3                         */\n    opus_int32          x_sc_Q10[],                 /* O    Input scaled with 1/Gain in Q10     */\n    const opus_int16    sLTP[],                     /* I    Re-whitened LTP state in Q0         */\n    opus_int32          sLTP_Q15[],                 /* O    LTP state matching scaled input     */\n    opus_int            subfr,                      /* I    Subframe number                     */\n    opus_int            nStatesDelayedDecision,     /* I    Number of del dec states            */\n    const opus_int      LTP_scale_Q14,              /* I    LTP state scaling                   */\n    const opus_int32    Gains_Q16[ MAX_NB_SUBFR ],  /* I                                        */\n    const opus_int      pitchL[ MAX_NB_SUBFR ],     /* I    Pitch lag                           */\n    const opus_int      signal_type,                /* I    Signal type                         */\n    const opus_int      decisionDelay               /* I    Decision delay                      */\n)\n{\n    opus_int            i, k, lag;\n    opus_int32          gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;\n    NSQ_del_dec_struct  *psDD;\n\n    lag          = pitchL[ subfr ];\n    inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );\n    silk_assert( inv_gain_Q31 != 0 );\n\n    /* Calculate gain adjustment factor */\n    if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {\n        gain_adj_Q16 =  silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );\n    } else {\n        gain_adj_Q16 = (opus_int32)1 << 16;\n    }\n\n    /* Scale input */\n    inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );\n    for( i = 0; i < psEncC->subfr_length; i++ ) {\n        x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );\n    }\n\n    /* Save inverse gain */\n    NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];\n\n    /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */\n    if( NSQ->rewhite_flag ) {\n        if( subfr == 0 ) {\n            /* Do LTP downscaling */\n            inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );\n        }\n        for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {\n            silk_assert( i < MAX_FRAME_LENGTH );\n            sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );\n        }\n    }\n\n    /* Adjust for changing gain */\n    if( gain_adj_Q16 != (opus_int32)1 << 16 ) {\n        /* Scale long-term shaping state */\n        for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {\n            NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );\n        }\n\n        /* Scale long-term prediction state */\n        if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {\n            for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {\n                sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );\n            }\n        }\n\n        for( k = 0; k < nStatesDelayedDecision; k++ ) {\n            psDD = &psDelDec[ k ];\n\n            /* Scale scalar states */\n            psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 );\n\n            /* Scale short-term prediction and shaping states */\n            for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {\n                psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] );\n            }\n            for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {\n                psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] );\n            }\n            for( i = 0; i < DECISION_DELAY; i++ ) {\n                psDD->Pred_Q15[  i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[  i ] );\n                psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/PLC.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"stack_alloc.h\"\n#include \"PLC.h\"\n\n#define NB_ATT 2\nstatic const opus_int16 HARM_ATT_Q15[NB_ATT]              = { 32440, 31130 }; /* 0.99, 0.95 */\nstatic const opus_int16 PLC_RAND_ATTENUATE_V_Q15[NB_ATT]  = { 31130, 26214 }; /* 0.95, 0.8 */\nstatic const opus_int16 PLC_RAND_ATTENUATE_UV_Q15[NB_ATT] = { 32440, 29491 }; /* 0.99, 0.9 */\n\nstatic OPUS_INLINE void silk_PLC_update(\n    silk_decoder_state                  *psDec,             /* I/O Decoder state        */\n    silk_decoder_control                *psDecCtrl          /* I/O Decoder control      */\n);\n\nstatic OPUS_INLINE void silk_PLC_conceal(\n    silk_decoder_state                  *psDec,             /* I/O Decoder state        */\n    silk_decoder_control                *psDecCtrl,         /* I/O Decoder control      */\n    opus_int16                          frame[],            /* O LPC residual signal    */\n    int                                 arch                /* I  Run-time architecture */\n);\n\n\nvoid silk_PLC_Reset(\n    silk_decoder_state                  *psDec              /* I/O Decoder state        */\n)\n{\n    psDec->sPLC.pitchL_Q8 = silk_LSHIFT( psDec->frame_length, 8 - 1 );\n    psDec->sPLC.prevGain_Q16[ 0 ] = SILK_FIX_CONST( 1, 16 );\n    psDec->sPLC.prevGain_Q16[ 1 ] = SILK_FIX_CONST( 1, 16 );\n    psDec->sPLC.subfr_length = 20;\n    psDec->sPLC.nb_subfr = 2;\n}\n\nvoid silk_PLC(\n    silk_decoder_state                  *psDec,             /* I/O Decoder state        */\n    silk_decoder_control                *psDecCtrl,         /* I/O Decoder control      */\n    opus_int16                          frame[],            /* I/O  signal              */\n    opus_int                            lost,               /* I Loss flag              */\n    int                                 arch                /* I Run-time architecture  */\n)\n{\n    /* PLC control function */\n    if( psDec->fs_kHz != psDec->sPLC.fs_kHz ) {\n        silk_PLC_Reset( psDec );\n        psDec->sPLC.fs_kHz = psDec->fs_kHz;\n    }\n\n    if( lost ) {\n        /****************************/\n        /* Generate Signal          */\n        /****************************/\n        silk_PLC_conceal( psDec, psDecCtrl, frame, arch );\n\n        psDec->lossCnt++;\n    } else {\n        /****************************/\n        /* Update state             */\n        /****************************/\n        silk_PLC_update( psDec, psDecCtrl );\n    }\n}\n\n/**************************************************/\n/* Update state of PLC                            */\n/**************************************************/\nstatic OPUS_INLINE void silk_PLC_update(\n    silk_decoder_state                  *psDec,             /* I/O Decoder state        */\n    silk_decoder_control                *psDecCtrl          /* I/O Decoder control      */\n)\n{\n    opus_int32 LTP_Gain_Q14, temp_LTP_Gain_Q14;\n    opus_int   i, j;\n    silk_PLC_struct *psPLC;\n\n    psPLC = &psDec->sPLC;\n\n    /* Update parameters used in case of packet loss */\n    psDec->prevSignalType = psDec->indices.signalType;\n    LTP_Gain_Q14 = 0;\n    if( psDec->indices.signalType == TYPE_VOICED ) {\n        /* Find the parameters for the last subframe which contains a pitch pulse */\n        for( j = 0; j * psDec->subfr_length < psDecCtrl->pitchL[ psDec->nb_subfr - 1 ]; j++ ) {\n            if( j == psDec->nb_subfr ) {\n                break;\n            }\n            temp_LTP_Gain_Q14 = 0;\n            for( i = 0; i < LTP_ORDER; i++ ) {\n                temp_LTP_Gain_Q14 += psDecCtrl->LTPCoef_Q14[ ( psDec->nb_subfr - 1 - j ) * LTP_ORDER  + i ];\n            }\n            if( temp_LTP_Gain_Q14 > LTP_Gain_Q14 ) {\n                LTP_Gain_Q14 = temp_LTP_Gain_Q14;\n                silk_memcpy( psPLC->LTPCoef_Q14,\n                    &psDecCtrl->LTPCoef_Q14[ silk_SMULBB( psDec->nb_subfr - 1 - j, LTP_ORDER ) ],\n                    LTP_ORDER * sizeof( opus_int16 ) );\n\n                psPLC->pitchL_Q8 = silk_LSHIFT( psDecCtrl->pitchL[ psDec->nb_subfr - 1 - j ], 8 );\n            }\n        }\n\n        silk_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( opus_int16 ) );\n        psPLC->LTPCoef_Q14[ LTP_ORDER / 2 ] = LTP_Gain_Q14;\n\n        /* Limit LT coefs */\n        if( LTP_Gain_Q14 < V_PITCH_GAIN_START_MIN_Q14 ) {\n            opus_int   scale_Q10;\n            opus_int32 tmp;\n\n            tmp = silk_LSHIFT( V_PITCH_GAIN_START_MIN_Q14, 10 );\n            scale_Q10 = silk_DIV32( tmp, silk_max( LTP_Gain_Q14, 1 ) );\n            for( i = 0; i < LTP_ORDER; i++ ) {\n                psPLC->LTPCoef_Q14[ i ] = silk_RSHIFT( silk_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q10 ), 10 );\n            }\n        } else if( LTP_Gain_Q14 > V_PITCH_GAIN_START_MAX_Q14 ) {\n            opus_int   scale_Q14;\n            opus_int32 tmp;\n\n            tmp = silk_LSHIFT( V_PITCH_GAIN_START_MAX_Q14, 14 );\n            scale_Q14 = silk_DIV32( tmp, silk_max( LTP_Gain_Q14, 1 ) );\n            for( i = 0; i < LTP_ORDER; i++ ) {\n                psPLC->LTPCoef_Q14[ i ] = silk_RSHIFT( silk_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q14 ), 14 );\n            }\n        }\n    } else {\n        psPLC->pitchL_Q8 = silk_LSHIFT( silk_SMULBB( psDec->fs_kHz, 18 ), 8 );\n        silk_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( opus_int16 ));\n    }\n\n    /* Save LPC coeficients */\n    silk_memcpy( psPLC->prevLPC_Q12, psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) );\n    psPLC->prevLTP_scale_Q14 = psDecCtrl->LTP_scale_Q14;\n\n    /* Save last two gains */\n    silk_memcpy( psPLC->prevGain_Q16, &psDecCtrl->Gains_Q16[ psDec->nb_subfr - 2 ], 2 * sizeof( opus_int32 ) );\n\n    psPLC->subfr_length = psDec->subfr_length;\n    psPLC->nb_subfr = psDec->nb_subfr;\n}\n\nstatic OPUS_INLINE void silk_PLC_energy(opus_int32 *energy1, opus_int *shift1, opus_int32 *energy2, opus_int *shift2,\n      const opus_int32 *exc_Q14, const opus_int32 *prevGain_Q10, int subfr_length, int nb_subfr)\n{\n    int i, k;\n    VARDECL( opus_int16, exc_buf );\n    opus_int16 *exc_buf_ptr;\n    SAVE_STACK;\n    ALLOC( exc_buf, 2*subfr_length, opus_int16 );\n    /* Find random noise component */\n    /* Scale previous excitation signal */\n    exc_buf_ptr = exc_buf;\n    for( k = 0; k < 2; k++ ) {\n        for( i = 0; i < subfr_length; i++ ) {\n            exc_buf_ptr[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT(\n                silk_SMULWW( exc_Q14[ i + ( k + nb_subfr - 2 ) * subfr_length ], prevGain_Q10[ k ] ), 8 ) );\n        }\n        exc_buf_ptr += subfr_length;\n    }\n    /* Find the subframe with lowest energy of the last two and use that as random noise generator */\n    silk_sum_sqr_shift( energy1, shift1, exc_buf,                  subfr_length );\n    silk_sum_sqr_shift( energy2, shift2, &exc_buf[ subfr_length ], subfr_length );\n    RESTORE_STACK;\n}\n\nstatic OPUS_INLINE void silk_PLC_conceal(\n    silk_decoder_state                  *psDec,             /* I/O Decoder state        */\n    silk_decoder_control                *psDecCtrl,         /* I/O Decoder control      */\n    opus_int16                          frame[],            /* O LPC residual signal    */\n    int                                 arch                /* I Run-time architecture  */\n)\n{\n    opus_int   i, j, k;\n    opus_int   lag, idx, sLTP_buf_idx, shift1, shift2;\n    opus_int32 rand_seed, harm_Gain_Q15, rand_Gain_Q15, inv_gain_Q30;\n    opus_int32 energy1, energy2, *rand_ptr, *pred_lag_ptr;\n    opus_int32 LPC_pred_Q10, LTP_pred_Q12;\n    opus_int16 rand_scale_Q14;\n    opus_int16 *B_Q14;\n    opus_int32 *sLPC_Q14_ptr;\n    opus_int16 A_Q12[ MAX_LPC_ORDER ];\n#ifdef SMALL_FOOTPRINT\n    opus_int16 *sLTP;\n#else\n    VARDECL( opus_int16, sLTP );\n#endif\n    VARDECL( opus_int32, sLTP_Q14 );\n    silk_PLC_struct *psPLC = &psDec->sPLC;\n    opus_int32 prevGain_Q10[2];\n    SAVE_STACK;\n\n    ALLOC( sLTP_Q14, psDec->ltp_mem_length + psDec->frame_length, opus_int32 );\n#ifdef SMALL_FOOTPRINT\n    /* Ugly hack that breaks aliasing rules to save stack: put sLTP at the very end of sLTP_Q14. */\n    sLTP = ((opus_int16*)&sLTP_Q14[psDec->ltp_mem_length + psDec->frame_length])-psDec->ltp_mem_length;\n#else\n    ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 );\n#endif\n\n    prevGain_Q10[0] = silk_RSHIFT( psPLC->prevGain_Q16[ 0 ], 6);\n    prevGain_Q10[1] = silk_RSHIFT( psPLC->prevGain_Q16[ 1 ], 6);\n\n    if( psDec->first_frame_after_reset ) {\n       silk_memset( psPLC->prevLPC_Q12, 0, sizeof( psPLC->prevLPC_Q12 ) );\n    }\n\n    silk_PLC_energy(&energy1, &shift1, &energy2, &shift2, psDec->exc_Q14, prevGain_Q10, psDec->subfr_length, psDec->nb_subfr);\n\n    if( silk_RSHIFT( energy1, shift2 ) < silk_RSHIFT( energy2, shift1 ) ) {\n        /* First sub-frame has lowest energy */\n        rand_ptr = &psDec->exc_Q14[ silk_max_int( 0, ( psPLC->nb_subfr - 1 ) * psPLC->subfr_length - RAND_BUF_SIZE ) ];\n    } else {\n        /* Second sub-frame has lowest energy */\n        rand_ptr = &psDec->exc_Q14[ silk_max_int( 0, psPLC->nb_subfr * psPLC->subfr_length - RAND_BUF_SIZE ) ];\n    }\n\n    /* Set up Gain to random noise component */\n    B_Q14          = psPLC->LTPCoef_Q14;\n    rand_scale_Q14 = psPLC->randScale_Q14;\n\n    /* Set up attenuation gains */\n    harm_Gain_Q15 = HARM_ATT_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ];\n    if( psDec->prevSignalType == TYPE_VOICED ) {\n        rand_Gain_Q15 = PLC_RAND_ATTENUATE_V_Q15[  silk_min_int( NB_ATT - 1, psDec->lossCnt ) ];\n    } else {\n        rand_Gain_Q15 = PLC_RAND_ATTENUATE_UV_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ];\n    }\n\n    /* LPC concealment. Apply BWE to previous LPC */\n    silk_bwexpander( psPLC->prevLPC_Q12, psDec->LPC_order, SILK_FIX_CONST( BWE_COEF, 16 ) );\n\n    /* Preload LPC coeficients to array on stack. Gives small performance gain */\n    silk_memcpy( A_Q12, psPLC->prevLPC_Q12, psDec->LPC_order * sizeof( opus_int16 ) );\n\n    /* First Lost frame */\n    if( psDec->lossCnt == 0 ) {\n        rand_scale_Q14 = 1 << 14;\n\n        /* Reduce random noise Gain for voiced frames */\n        if( psDec->prevSignalType == TYPE_VOICED ) {\n            for( i = 0; i < LTP_ORDER; i++ ) {\n                rand_scale_Q14 -= B_Q14[ i ];\n            }\n            rand_scale_Q14 = silk_max_16( 3277, rand_scale_Q14 ); /* 0.2 */\n            rand_scale_Q14 = (opus_int16)silk_RSHIFT( silk_SMULBB( rand_scale_Q14, psPLC->prevLTP_scale_Q14 ), 14 );\n        } else {\n            /* Reduce random noise for unvoiced frames with high LPC gain */\n            opus_int32 invGain_Q30, down_scale_Q30;\n\n            invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order );\n\n            down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 );\n            down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 );\n            down_scale_Q30 = silk_LSHIFT( down_scale_Q30, LOG2_INV_LPC_GAIN_HIGH_THRES );\n\n            rand_Gain_Q15 = silk_RSHIFT( silk_SMULWB( down_scale_Q30, rand_Gain_Q15 ), 14 );\n        }\n    }\n\n    rand_seed    = psPLC->rand_seed;\n    lag          = silk_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 );\n    sLTP_buf_idx = psDec->ltp_mem_length;\n\n    /* Rewhiten LTP state */\n    idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;\n    silk_assert( idx > 0 );\n    silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order, arch );\n    /* Scale LTP state */\n    inv_gain_Q30 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 46 );\n    inv_gain_Q30 = silk_min( inv_gain_Q30, silk_int32_MAX >> 1 );\n    for( i = idx + psDec->LPC_order; i < psDec->ltp_mem_length; i++ ) {\n        sLTP_Q14[ i ] = silk_SMULWB( inv_gain_Q30, sLTP[ i ] );\n    }\n\n    /***************************/\n    /* LTP synthesis filtering */\n    /***************************/\n    for( k = 0; k < psDec->nb_subfr; k++ ) {\n        /* Set up pointer */\n        pred_lag_ptr = &sLTP_Q14[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];\n        for( i = 0; i < psDec->subfr_length; i++ ) {\n            /* Unrolled loop */\n            /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n            LTP_pred_Q12 = 2;\n            LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[  0 ], B_Q14[ 0 ] );\n            LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );\n            LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );\n            LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );\n            LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );\n            pred_lag_ptr++;\n\n            /* Generate LPC excitation */\n            rand_seed = silk_RAND( rand_seed );\n            idx = silk_RSHIFT( rand_seed, 25 ) & RAND_BUF_MASK;\n            sLTP_Q14[ sLTP_buf_idx ] = silk_LSHIFT32( silk_SMLAWB( LTP_pred_Q12, rand_ptr[ idx ], rand_scale_Q14 ), 2 );\n            sLTP_buf_idx++;\n        }\n\n        /* Gradually reduce LTP gain */\n        for( j = 0; j < LTP_ORDER; j++ ) {\n            B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 );\n        }\n        /* Gradually reduce excitation gain */\n        rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );\n\n        /* Slowly increase pitch lag */\n        psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 );\n        psPLC->pitchL_Q8 = silk_min_32( psPLC->pitchL_Q8, silk_LSHIFT( silk_SMULBB( MAX_PITCH_LAG_MS, psDec->fs_kHz ), 8 ) );\n        lag = silk_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 );\n    }\n\n    /***************************/\n    /* LPC synthesis filtering */\n    /***************************/\n    sLPC_Q14_ptr = &sLTP_Q14[ psDec->ltp_mem_length - MAX_LPC_ORDER ];\n\n    /* Copy LPC state */\n    silk_memcpy( sLPC_Q14_ptr, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) );\n\n    silk_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */\n    for( i = 0; i < psDec->frame_length; i++ ) {\n        /* partly unrolled */\n        /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n        LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i -  1 ], A_Q12[ 0 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i -  2 ], A_Q12[ 1 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i -  3 ], A_Q12[ 2 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i -  4 ], A_Q12[ 3 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i -  5 ], A_Q12[ 4 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i -  6 ], A_Q12[ 5 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i -  7 ], A_Q12[ 6 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i -  8 ], A_Q12[ 7 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i -  9 ], A_Q12[ 8 ] );\n        LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] );\n        for( j = 10; j < psDec->LPC_order; j++ ) {\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - j - 1 ], A_Q12[ j ] );\n        }\n\n        /* Add prediction to LPC excitation */\n        sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 );\n\n        /* Scale with Gain */\n        frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) );\n    }\n\n    /* Save LPC state */\n    silk_memcpy( psDec->sLPC_Q14_buf, &sLPC_Q14_ptr[ psDec->frame_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );\n\n    /**************************************/\n    /* Update states                      */\n    /**************************************/\n    psPLC->rand_seed     = rand_seed;\n    psPLC->randScale_Q14 = rand_scale_Q14;\n    for( i = 0; i < MAX_NB_SUBFR; i++ ) {\n        psDecCtrl->pitchL[ i ] = lag;\n    }\n    RESTORE_STACK;\n}\n\n/* Glues concealed frames with new good received frames */\nvoid silk_PLC_glue_frames(\n    silk_decoder_state                  *psDec,             /* I/O decoder state        */\n    opus_int16                          frame[],            /* I/O signal               */\n    opus_int                            length              /* I length of signal       */\n)\n{\n    opus_int   i, energy_shift;\n    opus_int32 energy;\n    silk_PLC_struct *psPLC;\n    psPLC = &psDec->sPLC;\n\n    if( psDec->lossCnt ) {\n        /* Calculate energy in concealed residual */\n        silk_sum_sqr_shift( &psPLC->conc_energy, &psPLC->conc_energy_shift, frame, length );\n\n        psPLC->last_frame_lost = 1;\n    } else {\n        if( psDec->sPLC.last_frame_lost ) {\n            /* Calculate residual in decoded signal if last frame was lost */\n            silk_sum_sqr_shift( &energy, &energy_shift, frame, length );\n\n            /* Normalize energies */\n            if( energy_shift > psPLC->conc_energy_shift ) {\n                psPLC->conc_energy = silk_RSHIFT( psPLC->conc_energy, energy_shift - psPLC->conc_energy_shift );\n            } else if( energy_shift < psPLC->conc_energy_shift ) {\n                energy = silk_RSHIFT( energy, psPLC->conc_energy_shift - energy_shift );\n            }\n\n            /* Fade in the energy difference */\n            if( energy > psPLC->conc_energy ) {\n                opus_int32 frac_Q24, LZ;\n                opus_int32 gain_Q16, slope_Q16;\n\n                LZ = silk_CLZ32( psPLC->conc_energy );\n                LZ = LZ - 1;\n                psPLC->conc_energy = silk_LSHIFT( psPLC->conc_energy, LZ );\n                energy = silk_RSHIFT( energy, silk_max_32( 24 - LZ, 0 ) );\n\n                frac_Q24 = silk_DIV32( psPLC->conc_energy, silk_max( energy, 1 ) );\n\n                gain_Q16 = silk_LSHIFT( silk_SQRT_APPROX( frac_Q24 ), 4 );\n                slope_Q16 = silk_DIV32_16( ( (opus_int32)1 << 16 ) - gain_Q16, length );\n                /* Make slope 4x steeper to avoid missing onsets after DTX */\n                slope_Q16 = silk_LSHIFT( slope_Q16, 2 );\n\n                for( i = 0; i < length; i++ ) {\n                    frame[ i ] = silk_SMULWB( gain_Q16, frame[ i ] );\n                    gain_Q16 += slope_Q16;\n                    if( gain_Q16 > (opus_int32)1 << 16 ) {\n                        break;\n                    }\n                }\n            }\n        }\n        psPLC->last_frame_lost = 0;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/PLC.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_PLC_H\n#define SILK_PLC_H\n\n#include \"main.h\"\n\n#define BWE_COEF                        0.99\n#define V_PITCH_GAIN_START_MIN_Q14      11469               /* 0.7 in Q14               */\n#define V_PITCH_GAIN_START_MAX_Q14      15565               /* 0.95 in Q14              */\n#define MAX_PITCH_LAG_MS                18\n#define RAND_BUF_SIZE                   128\n#define RAND_BUF_MASK                   ( RAND_BUF_SIZE - 1 )\n#define LOG2_INV_LPC_GAIN_HIGH_THRES    3                   /* 2^3 = 8 dB LPC gain      */\n#define LOG2_INV_LPC_GAIN_LOW_THRES     8                   /* 2^8 = 24 dB LPC gain     */\n#define PITCH_DRIFT_FAC_Q16             655                 /* 0.01 in Q16              */\n\nvoid silk_PLC_Reset(\n    silk_decoder_state                  *psDec              /* I/O Decoder state        */\n);\n\nvoid silk_PLC(\n    silk_decoder_state                  *psDec,             /* I/O Decoder state        */\n    silk_decoder_control                *psDecCtrl,         /* I/O Decoder control      */\n    opus_int16                          frame[],            /* I/O  signal              */\n    opus_int                            lost,               /* I Loss flag              */\n    int                                 arch                /* I Run-time architecture  */\n);\n\nvoid silk_PLC_glue_frames(\n    silk_decoder_state                  *psDec,             /* I/O decoder state        */\n    opus_int16                          frame[],            /* I/O signal               */\n    opus_int                            length              /* I length of signal       */\n);\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/SigProc_FIX.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_SIGPROC_FIX_H\n#define SILK_SIGPROC_FIX_H\n\n#ifdef  __cplusplus\nextern \"C\"\n{\n#endif\n\n/*#define silk_MACRO_COUNT */          /* Used to enable WMOPS counting */\n\n#define SILK_MAX_ORDER_LPC            16            /* max order of the LPC analysis in schur() and k2a() */\n\n#include <string.h>                                 /* for memset(), memcpy(), memmove() */\n#include \"typedef.h\"\n#include \"resampler_structs.h\"\n#include \"macros.h\"\n#include \"cpu_support.h\"\n\n#if defined(OPUS_X86_MAY_HAVE_SSE4_1)\n#include \"x86/SigProc_FIX_sse.h\"\n#endif\n\n/********************************************************************/\n/*                    SIGNAL PROCESSING FUNCTIONS                   */\n/********************************************************************/\n\n/*!\n * Initialize/reset the resampler state for a given pair of input/output sampling rates\n*/\nopus_int silk_resampler_init(\n    silk_resampler_state_struct *S,                 /* I/O  Resampler state                                             */\n    opus_int32                  Fs_Hz_in,           /* I    Input sampling rate (Hz)                                    */\n    opus_int32                  Fs_Hz_out,          /* I    Output sampling rate (Hz)                                   */\n    opus_int                    forEnc              /* I    If 1: encoder; if 0: decoder                                */\n);\n\n/*!\n * Resampler: convert from one sampling rate to another\n */\nopus_int silk_resampler(\n    silk_resampler_state_struct *S,                 /* I/O  Resampler state                                             */\n    opus_int16                  out[],              /* O    Output signal                                               */\n    const opus_int16            in[],               /* I    Input signal                                                */\n    opus_int32                  inLen               /* I    Number of input samples                                     */\n);\n\n/*!\n* Downsample 2x, mediocre quality\n*/\nvoid silk_resampler_down2(\n    opus_int32                  *S,                 /* I/O  State vector [ 2 ]                                          */\n    opus_int16                  *out,               /* O    Output signal [ len ]                                       */\n    const opus_int16            *in,                /* I    Input signal [ floor(len/2) ]                               */\n    opus_int32                  inLen               /* I    Number of input samples                                     */\n);\n\n/*!\n * Downsample by a factor 2/3, low quality\n*/\nvoid silk_resampler_down2_3(\n    opus_int32                  *S,                 /* I/O  State vector [ 6 ]                                          */\n    opus_int16                  *out,               /* O    Output signal [ floor(2*inLen/3) ]                          */\n    const opus_int16            *in,                /* I    Input signal [ inLen ]                                      */\n    opus_int32                  inLen               /* I    Number of input samples                                     */\n);\n\n/*!\n * second order ARMA filter;\n * slower than biquad() but uses more precise coefficients\n * can handle (slowly) varying coefficients\n */\nvoid silk_biquad_alt(\n    const opus_int16            *in,                /* I     input signal                                               */\n    const opus_int32            *B_Q28,             /* I     MA coefficients [3]                                        */\n    const opus_int32            *A_Q28,             /* I     AR coefficients [2]                                        */\n    opus_int32                  *S,                 /* I/O   State vector [2]                                           */\n    opus_int16                  *out,               /* O     output signal                                              */\n    const opus_int32            len,                /* I     signal length (must be even)                               */\n    opus_int                    stride              /* I     Operate on interleaved signal if > 1                       */\n);\n\n/* Variable order MA prediction error filter. */\nvoid silk_LPC_analysis_filter(\n    opus_int16                  *out,               /* O    Output signal                                               */\n    const opus_int16            *in,                /* I    Input signal                                                */\n    const opus_int16            *B,                 /* I    MA prediction coefficients, Q12 [order]                     */\n    const opus_int32            len,                /* I    Signal length                                               */\n    const opus_int32            d,                  /* I    Filter order                                                */\n    int                         arch                /* I    Run-time architecture                                       */\n);\n\n/* Chirp (bandwidth expand) LP AR filter */\nvoid silk_bwexpander(\n    opus_int16                  *ar,                /* I/O  AR filter to be expanded (without leading 1)                */\n    const opus_int              d,                  /* I    Length of ar                                                */\n    opus_int32                  chirp_Q16           /* I    Chirp factor (typically in the range 0 to 1)                */\n);\n\n/* Chirp (bandwidth expand) LP AR filter */\nvoid silk_bwexpander_32(\n    opus_int32                  *ar,                /* I/O  AR filter to be expanded (without leading 1)                */\n    const opus_int              d,                  /* I    Length of ar                                                */\n    opus_int32                  chirp_Q16           /* I    Chirp factor in Q16                                         */\n);\n\n/* Compute inverse of LPC prediction gain, and                           */\n/* test if LPC coefficients are stable (all poles within unit circle)    */\nopus_int32 silk_LPC_inverse_pred_gain(              /* O   Returns inverse prediction gain in energy domain, Q30        */\n    const opus_int16            *A_Q12,             /* I   Prediction coefficients, Q12 [order]                         */\n    const opus_int              order               /* I   Prediction order                                             */\n);\n\n/* For input in Q24 domain */\nopus_int32 silk_LPC_inverse_pred_gain_Q24(          /* O    Returns inverse prediction gain in energy domain, Q30       */\n    const opus_int32            *A_Q24,             /* I    Prediction coefficients [order]                             */\n    const opus_int              order               /* I    Prediction order                                            */\n);\n\n/* Split signal in two decimated bands using first-order allpass filters */\nvoid silk_ana_filt_bank_1(\n    const opus_int16            *in,                /* I    Input signal [N]                                            */\n    opus_int32                  *S,                 /* I/O  State vector [2]                                            */\n    opus_int16                  *outL,              /* O    Low band [N/2]                                              */\n    opus_int16                  *outH,              /* O    High band [N/2]                                             */\n    const opus_int32            N                   /* I    Number of input samples                                     */\n);\n\n/********************************************************************/\n/*                        SCALAR FUNCTIONS                          */\n/********************************************************************/\n\n/* Approximation of 128 * log2() (exact inverse of approx 2^() below) */\n/* Convert input to a log scale    */\nopus_int32 silk_lin2log(\n    const opus_int32            inLin               /* I  input in linear scale                                         */\n);\n\n/* Approximation of a sigmoid function */\nopus_int silk_sigm_Q15(\n    opus_int                    in_Q5               /* I                                                                */\n);\n\n/* Approximation of 2^() (exact inverse of approx log2() above) */\n/* Convert input to a linear scale */\nopus_int32 silk_log2lin(\n    const opus_int32            inLog_Q7            /* I  input on log scale                                            */\n);\n\n/* Compute number of bits to right shift the sum of squares of a vector    */\n/* of int16s to make it fit in an int32                                    */\nvoid silk_sum_sqr_shift(\n    opus_int32                  *energy,            /* O   Energy of x, after shifting to the right                     */\n    opus_int                    *shift,             /* O   Number of bits right shift applied to energy                 */\n    const opus_int16            *x,                 /* I   Input vector                                                 */\n    opus_int                    len                 /* I   Length of input vector                                       */\n);\n\n/* Calculates the reflection coefficients from the correlation sequence    */\n/* Faster than schur64(), but much less accurate.                          */\n/* uses SMLAWB(), requiring armv5E and higher.                             */\nopus_int32 silk_schur(                              /* O    Returns residual energy                                     */\n    opus_int16                  *rc_Q15,            /* O    reflection coefficients [order] Q15                         */\n    const opus_int32            *c,                 /* I    correlations [order+1]                                      */\n    const opus_int32            order               /* I    prediction order                                            */\n);\n\n/* Calculates the reflection coefficients from the correlation sequence    */\n/* Slower than schur(), but more accurate.                                 */\n/* Uses SMULL(), available on armv4                                        */\nopus_int32 silk_schur64(                            /* O    returns residual energy                                     */\n    opus_int32                  rc_Q16[],           /* O    Reflection coefficients [order] Q16                         */\n    const opus_int32            c[],                /* I    Correlations [order+1]                                      */\n    opus_int32                  order               /* I    Prediction order                                            */\n);\n\n/* Step up function, converts reflection coefficients to prediction coefficients */\nvoid silk_k2a(\n    opus_int32                  *A_Q24,             /* O    Prediction coefficients [order] Q24                         */\n    const opus_int16            *rc_Q15,            /* I    Reflection coefficients [order] Q15                         */\n    const opus_int32            order               /* I    Prediction order                                            */\n);\n\n/* Step up function, converts reflection coefficients to prediction coefficients */\nvoid silk_k2a_Q16(\n    opus_int32                  *A_Q24,             /* O    Prediction coefficients [order] Q24                         */\n    const opus_int32            *rc_Q16,            /* I    Reflection coefficients [order] Q16                         */\n    const opus_int32            order               /* I    Prediction order                                            */\n);\n\n/* Apply sine window to signal vector.                              */\n/* Window types:                                                    */\n/*    1 -> sine window from 0 to pi/2                               */\n/*    2 -> sine window from pi/2 to pi                              */\n/* every other sample of window is linearly interpolated, for speed */\nvoid silk_apply_sine_window(\n    opus_int16                  px_win[],           /* O    Pointer to windowed signal                                  */\n    const opus_int16            px[],               /* I    Pointer to input signal                                     */\n    const opus_int              win_type,           /* I    Selects a window type                                       */\n    const opus_int              length              /* I    Window length, multiple of 4                                */\n);\n\n/* Compute autocorrelation */\nvoid silk_autocorr(\n    opus_int32                  *results,           /* O    Result (length correlationCount)                            */\n    opus_int                    *scale,             /* O    Scaling of the correlation vector                           */\n    const opus_int16            *inputData,         /* I    Input data to correlate                                     */\n    const opus_int              inputDataSize,      /* I    Length of input                                             */\n    const opus_int              correlationCount,   /* I    Number of correlation taps to compute                       */\n    int                         arch                /* I    Run-time architecture                                       */\n);\n\nvoid silk_decode_pitch(\n    opus_int16                  lagIndex,           /* I                                                                */\n    opus_int8                   contourIndex,       /* O                                                                */\n    opus_int                    pitch_lags[],       /* O    4 pitch values                                              */\n    const opus_int              Fs_kHz,             /* I    sampling frequency (kHz)                                    */\n    const opus_int              nb_subfr            /* I    number of sub frames                                        */\n);\n\nopus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0 voiced, 1 unvoiced                      */\n    const opus_int16            *frame,             /* I    Signal of length PE_FRAME_LENGTH_MS*Fs_kHz                  */\n    opus_int                    *pitch_out,         /* O    4 pitch lag values                                          */\n    opus_int16                  *lagIndex,          /* O    Lag Index                                                   */\n    opus_int8                   *contourIndex,      /* O    Pitch contour Index                                         */\n    opus_int                    *LTPCorr_Q15,       /* I/O  Normalized correlation; input: value from previous frame    */\n    opus_int                    prevLag,            /* I    Last lag of previous frame; set to zero is unvoiced         */\n    const opus_int32            search_thres1_Q16,  /* I    First stage threshold for lag candidates 0 - 1              */\n    const opus_int              search_thres2_Q13,  /* I    Final threshold for lag candidates 0 - 1                    */\n    const opus_int              Fs_kHz,             /* I    Sample frequency (kHz)                                      */\n    const opus_int              complexity,         /* I    Complexity setting, 0-2, where 2 is highest                 */\n    const opus_int              nb_subfr,           /* I    number of 5 ms subframes                                    */\n    int                         arch                /* I    Run-time architecture                                       */\n);\n\n/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients      */\n/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */\nvoid silk_A2NLSF(\n    opus_int16                  *NLSF,              /* O    Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */\n    opus_int32                  *a_Q16,             /* I/O  Monic whitening filter coefficients in Q16 [d]              */\n    const opus_int              d                   /* I    Filter order (must be even)                                 */\n);\n\n/* compute whitening filter coefficients from normalized line spectral frequencies */\nvoid silk_NLSF2A(\n    opus_int16                  *a_Q12,             /* O    monic whitening filter coefficients in Q12,  [ d ]          */\n    const opus_int16            *NLSF,              /* I    normalized line spectral frequencies in Q15, [ d ]          */\n    const opus_int              d                   /* I    filter order (should be even)                               */\n);\n\nvoid silk_insertion_sort_increasing(\n    opus_int32                  *a,                 /* I/O   Unsorted / Sorted vector                                   */\n    opus_int                    *idx,               /* O     Index vector for the sorted elements                       */\n    const opus_int              L,                  /* I     Vector length                                              */\n    const opus_int              K                   /* I     Number of correctly sorted positions                       */\n);\n\nvoid silk_insertion_sort_decreasing_int16(\n    opus_int16                  *a,                 /* I/O   Unsorted / Sorted vector                                   */\n    opus_int                    *idx,               /* O     Index vector for the sorted elements                       */\n    const opus_int              L,                  /* I     Vector length                                              */\n    const opus_int              K                   /* I     Number of correctly sorted positions                       */\n);\n\nvoid silk_insertion_sort_increasing_all_values_int16(\n     opus_int16                 *a,                 /* I/O   Unsorted / Sorted vector                                   */\n     const opus_int             L                   /* I     Vector length                                              */\n);\n\n/* NLSF stabilizer, for a single input data vector */\nvoid silk_NLSF_stabilize(\n          opus_int16            *NLSF_Q15,          /* I/O   Unstable/stabilized normalized LSF vector in Q15 [L]       */\n    const opus_int16            *NDeltaMin_Q15,     /* I     Min distance vector, NDeltaMin_Q15[L] must be >= 1 [L+1]   */\n    const opus_int              L                   /* I     Number of NLSF parameters in the input vector              */\n);\n\n/* Laroia low complexity NLSF weights */\nvoid silk_NLSF_VQ_weights_laroia(\n    opus_int16                  *pNLSFW_Q_OUT,      /* O     Pointer to input vector weights [D]                        */\n    const opus_int16            *pNLSF_Q15,         /* I     Pointer to input vector         [D]                        */\n    const opus_int              D                   /* I     Input vector dimension (even)                              */\n);\n\n/* Compute reflection coefficients from input signal */\nvoid silk_burg_modified_c(\n    opus_int32                  *res_nrg,           /* O    Residual energy                                             */\n    opus_int                    *res_nrg_Q,         /* O    Residual energy Q value                                     */\n    opus_int32                  A_Q16[],            /* O    Prediction coefficients (length order)                      */\n    const opus_int16            x[],                /* I    Input signal, length: nb_subfr * ( D + subfr_length )       */\n    const opus_int32            minInvGain_Q30,     /* I    Inverse of max prediction gain                              */\n    const opus_int              subfr_length,       /* I    Input signal subframe length (incl. D preceding samples)    */\n    const opus_int              nb_subfr,           /* I    Number of subframes stacked in x                            */\n    const opus_int              D,                  /* I    Order                                                       */\n    int                         arch                /* I    Run-time architecture                                       */\n);\n\n/* Copy and multiply a vector by a constant */\nvoid silk_scale_copy_vector16(\n    opus_int16                  *data_out,\n    const opus_int16            *data_in,\n    opus_int32                  gain_Q16,           /* I    Gain in Q16                                                 */\n    const opus_int              dataSize            /* I    Length                                                      */\n);\n\n/* Some for the LTP related function requires Q26 to work.*/\nvoid silk_scale_vector32_Q26_lshift_18(\n    opus_int32                  *data1,             /* I/O  Q0/Q18                                                      */\n    opus_int32                  gain_Q26,           /* I    Q26                                                         */\n    opus_int                    dataSize            /* I    length                                                      */\n);\n\n/********************************************************************/\n/*                        INLINE ARM MATH                           */\n/********************************************************************/\n\n/*    return sum( inVec1[i] * inVec2[i] ) */\n\nopus_int32 silk_inner_prod_aligned(\n    const opus_int16 *const     inVec1,             /*    I input vector 1                                              */\n    const opus_int16 *const     inVec2,             /*    I input vector 2                                              */\n    const opus_int              len,                /*    I vector lengths                                              */\n    int                         arch                /*    I Run-time architecture                                       */\n);\n\n\nopus_int32 silk_inner_prod_aligned_scale(\n    const opus_int16 *const     inVec1,             /*    I input vector 1                                              */\n    const opus_int16 *const     inVec2,             /*    I input vector 2                                              */\n    const opus_int              scale,              /*    I number of bits to shift                                     */\n    const opus_int              len                 /*    I vector lengths                                              */\n);\n\nopus_int64 silk_inner_prod16_aligned_64_c(\n    const opus_int16            *inVec1,            /*    I input vector 1                                              */\n    const opus_int16            *inVec2,            /*    I input vector 2                                              */\n    const opus_int              len                 /*    I vector lengths                                              */\n);\n\n/********************************************************************/\n/*                                MACROS                            */\n/********************************************************************/\n\n/* Rotate a32 right by 'rot' bits. Negative rot values result in rotating\n   left. Output is 32bit int.\n   Note: contemporary compilers recognize the C expression below and\n   compile it into a 'ror' instruction if available. No need for OPUS_INLINE ASM! */\nstatic OPUS_INLINE opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )\n{\n    opus_uint32 x = (opus_uint32) a32;\n    opus_uint32 r = (opus_uint32) rot;\n    opus_uint32 m = (opus_uint32) -rot;\n    if( rot == 0 ) {\n        return a32;\n    } else if( rot < 0 ) {\n        return (opus_int32) ((x << m) | (x >> (32 - m)));\n    } else {\n        return (opus_int32) ((x << (32 - r)) | (x >> r));\n    }\n}\n\n/* Allocate opus_int16 aligned to 4-byte memory address */\n#if EMBEDDED_ARM\n#define silk_DWORD_ALIGN __attribute__((aligned(4)))\n#else\n#define silk_DWORD_ALIGN\n#endif\n\n/* Useful Macros that can be adjusted to other platforms */\n#define silk_memcpy(dest, src, size)        memcpy((dest), (src), (size))\n#define silk_memset(dest, src, size)        memset((dest), (src), (size))\n#define silk_memmove(dest, src, size)       memmove((dest), (src), (size))\n\n/* Fixed point macros */\n\n/* (a32 * b32) output have to be 32bit int */\n#define silk_MUL(a32, b32)                  ((a32) * (b32))\n\n/* (a32 * b32) output have to be 32bit uint */\n#define silk_MUL_uint(a32, b32)             silk_MUL(a32, b32)\n\n/* a32 + (b32 * c32) output have to be 32bit int */\n#define silk_MLA(a32, b32, c32)             silk_ADD32((a32),((b32) * (c32)))\n\n/* a32 + (b32 * c32) output have to be 32bit uint */\n#define silk_MLA_uint(a32, b32, c32)        silk_MLA(a32, b32, c32)\n\n/* ((a32 >> 16)  * (b32 >> 16)) output have to be 32bit int */\n#define silk_SMULTT(a32, b32)               (((a32) >> 16) * ((b32) >> 16))\n\n/* a32 + ((a32 >> 16)  * (b32 >> 16)) output have to be 32bit int */\n#define silk_SMLATT(a32, b32, c32)          silk_ADD32((a32),((b32) >> 16) * ((c32) >> 16))\n\n#define silk_SMLALBB(a64, b16, c16)         silk_ADD64((a64),(opus_int64)((opus_int32)(b16) * (opus_int32)(c16)))\n\n/* (a32 * b32) */\n#define silk_SMULL(a32, b32)                ((opus_int64)(a32) * /*(opus_int64)*/(b32))\n\n/* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour\n   (just standard two's complement implementation-specific behaviour) */\n#define silk_ADD32_ovflw(a, b)              ((opus_int32)((opus_uint32)(a) + (opus_uint32)(b)))\n/* Subtractss two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour\n   (just standard two's complement implementation-specific behaviour) */\n#define silk_SUB32_ovflw(a, b)              ((opus_int32)((opus_uint32)(a) - (opus_uint32)(b)))\n\n/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */\n#define silk_MLA_ovflw(a32, b32, c32)       silk_ADD32_ovflw((a32), (opus_uint32)(b32) * (opus_uint32)(c32))\n#define silk_SMLABB_ovflw(a32, b32, c32)    (silk_ADD32_ovflw((a32) , ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32))))\n\n#define silk_DIV32_16(a32, b16)             ((opus_int32)((a32) / (b16)))\n#define silk_DIV32(a32, b32)                ((opus_int32)((a32) / (b32)))\n\n/* These macros enables checking for overflow in silk_API_Debug.h*/\n#define silk_ADD16(a, b)                    ((a) + (b))\n#define silk_ADD32(a, b)                    ((a) + (b))\n#define silk_ADD64(a, b)                    ((a) + (b))\n\n#define silk_SUB16(a, b)                    ((a) - (b))\n#define silk_SUB32(a, b)                    ((a) - (b))\n#define silk_SUB64(a, b)                    ((a) - (b))\n\n#define silk_SAT8(a)                        ((a) > silk_int8_MAX ? silk_int8_MAX  :       \\\n                                            ((a) < silk_int8_MIN ? silk_int8_MIN  : (a)))\n#define silk_SAT16(a)                       ((a) > silk_int16_MAX ? silk_int16_MAX :      \\\n                                            ((a) < silk_int16_MIN ? silk_int16_MIN : (a)))\n#define silk_SAT32(a)                       ((a) > silk_int32_MAX ? silk_int32_MAX :      \\\n                                            ((a) < silk_int32_MIN ? silk_int32_MIN : (a)))\n\n#define silk_CHECK_FIT8(a)                  (a)\n#define silk_CHECK_FIT16(a)                 (a)\n#define silk_CHECK_FIT32(a)                 (a)\n\n#define silk_ADD_SAT16(a, b)                (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a), (b) ) )\n#define silk_ADD_SAT64(a, b)                ((((a) + (b)) & 0x8000000000000000LL) == 0 ?                            \\\n                                            ((((a) & (b)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a)+(b)) : \\\n                                            ((((a) | (b)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a)+(b)) )\n\n#define silk_SUB_SAT16(a, b)                (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a), (b) ) )\n#define silk_SUB_SAT64(a, b)                ((((a)-(b)) & 0x8000000000000000LL) == 0 ?                                               \\\n                                            (( (a) & ((b)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a)-(b)) : \\\n                                            ((((a)^0x8000000000000000LL) & (b)  & 0x8000000000000000LL) ? silk_int64_MAX : (a)-(b)) )\n\n/* Saturation for positive input values */\n#define silk_POS_SAT32(a)                   ((a) > silk_int32_MAX ? silk_int32_MAX : (a))\n\n/* Add with saturation for positive input values */\n#define silk_ADD_POS_SAT8(a, b)             ((((a)+(b)) & 0x80)                 ? silk_int8_MAX  : ((a)+(b)))\n#define silk_ADD_POS_SAT16(a, b)            ((((a)+(b)) & 0x8000)               ? silk_int16_MAX : ((a)+(b)))\n#define silk_ADD_POS_SAT32(a, b)            ((((a)+(b)) & 0x80000000)           ? silk_int32_MAX : ((a)+(b)))\n#define silk_ADD_POS_SAT64(a, b)            ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)))\n\n#define silk_LSHIFT8(a, shift)              ((opus_int8)((opus_uint8)(a)<<(shift)))         /* shift >= 0, shift < 8  */\n#define silk_LSHIFT16(a, shift)             ((opus_int16)((opus_uint16)(a)<<(shift)))       /* shift >= 0, shift < 16 */\n#define silk_LSHIFT32(a, shift)             ((opus_int32)((opus_uint32)(a)<<(shift)))       /* shift >= 0, shift < 32 */\n#define silk_LSHIFT64(a, shift)             ((opus_int64)((opus_uint64)(a)<<(shift)))       /* shift >= 0, shift < 64 */\n#define silk_LSHIFT(a, shift)               silk_LSHIFT32(a, shift)                         /* shift >= 0, shift < 32 */\n\n#define silk_RSHIFT8(a, shift)              ((a)>>(shift))                                  /* shift >= 0, shift < 8  */\n#define silk_RSHIFT16(a, shift)             ((a)>>(shift))                                  /* shift >= 0, shift < 16 */\n#define silk_RSHIFT32(a, shift)             ((a)>>(shift))                                  /* shift >= 0, shift < 32 */\n#define silk_RSHIFT64(a, shift)             ((a)>>(shift))                                  /* shift >= 0, shift < 64 */\n#define silk_RSHIFT(a, shift)               silk_RSHIFT32(a, shift)                         /* shift >= 0, shift < 32 */\n\n/* saturates before shifting */\n#define silk_LSHIFT_SAT32(a, shift)         (silk_LSHIFT32( silk_LIMIT( (a), silk_RSHIFT32( silk_int32_MIN, (shift) ), \\\n                                                    silk_RSHIFT32( silk_int32_MAX, (shift) ) ), (shift) ))\n\n#define silk_LSHIFT_ovflw(a, shift)         ((opus_int32)((opus_uint32)(a) << (shift)))     /* shift >= 0, allowed to overflow */\n#define silk_LSHIFT_uint(a, shift)          ((a) << (shift))                                /* shift >= 0 */\n#define silk_RSHIFT_uint(a, shift)          ((a) >> (shift))                                /* shift >= 0 */\n\n#define silk_ADD_LSHIFT(a, b, shift)        ((a) + silk_LSHIFT((b), (shift)))               /* shift >= 0 */\n#define silk_ADD_LSHIFT32(a, b, shift)      silk_ADD32((a), silk_LSHIFT32((b), (shift)))    /* shift >= 0 */\n#define silk_ADD_LSHIFT_uint(a, b, shift)   ((a) + silk_LSHIFT_uint((b), (shift)))          /* shift >= 0 */\n#define silk_ADD_RSHIFT(a, b, shift)        ((a) + silk_RSHIFT((b), (shift)))               /* shift >= 0 */\n#define silk_ADD_RSHIFT32(a, b, shift)      silk_ADD32((a), silk_RSHIFT32((b), (shift)))    /* shift >= 0 */\n#define silk_ADD_RSHIFT_uint(a, b, shift)   ((a) + silk_RSHIFT_uint((b), (shift)))          /* shift >= 0 */\n#define silk_SUB_LSHIFT32(a, b, shift)      silk_SUB32((a), silk_LSHIFT32((b), (shift)))    /* shift >= 0 */\n#define silk_SUB_RSHIFT32(a, b, shift)      silk_SUB32((a), silk_RSHIFT32((b), (shift)))    /* shift >= 0 */\n\n/* Requires that shift > 0 */\n#define silk_RSHIFT_ROUND(a, shift)         ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1)\n#define silk_RSHIFT_ROUND64(a, shift)       ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1)\n\n/* Number of rightshift required to fit the multiplication */\n#define silk_NSHIFT_MUL_32_32(a, b)         ( -(31- (32-silk_CLZ32(silk_abs(a)) + (32-silk_CLZ32(silk_abs(b))))) )\n#define silk_NSHIFT_MUL_16_16(a, b)         ( -(15- (16-silk_CLZ16(silk_abs(a)) + (16-silk_CLZ16(silk_abs(b))))) )\n\n\n#define silk_min(a, b)                      (((a) < (b)) ? (a) : (b))\n#define silk_max(a, b)                      (((a) > (b)) ? (a) : (b))\n\n/* Macro to convert floating-point constants to fixed-point */\n#define SILK_FIX_CONST( C, Q )              ((opus_int32)((C) * ((opus_int64)1 << (Q)) + 0.5))\n\n/* silk_min() versions with typecast in the function call */\nstatic OPUS_INLINE opus_int silk_min_int(opus_int a, opus_int b)\n{\n    return (((a) < (b)) ? (a) : (b));\n}\nstatic OPUS_INLINE opus_int16 silk_min_16(opus_int16 a, opus_int16 b)\n{\n    return (((a) < (b)) ? (a) : (b));\n}\nstatic OPUS_INLINE opus_int32 silk_min_32(opus_int32 a, opus_int32 b)\n{\n    return (((a) < (b)) ? (a) : (b));\n}\nstatic OPUS_INLINE opus_int64 silk_min_64(opus_int64 a, opus_int64 b)\n{\n    return (((a) < (b)) ? (a) : (b));\n}\n\n/* silk_min() versions with typecast in the function call */\nstatic OPUS_INLINE opus_int silk_max_int(opus_int a, opus_int b)\n{\n    return (((a) > (b)) ? (a) : (b));\n}\nstatic OPUS_INLINE opus_int16 silk_max_16(opus_int16 a, opus_int16 b)\n{\n    return (((a) > (b)) ? (a) : (b));\n}\nstatic OPUS_INLINE opus_int32 silk_max_32(opus_int32 a, opus_int32 b)\n{\n    return (((a) > (b)) ? (a) : (b));\n}\nstatic OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b)\n{\n    return (((a) > (b)) ? (a) : (b));\n}\n\n#define silk_LIMIT( a, limit1, limit2)      ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \\\n                                                                 : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a))))\n\n#define silk_LIMIT_int                      silk_LIMIT\n#define silk_LIMIT_16                       silk_LIMIT\n#define silk_LIMIT_32                       silk_LIMIT\n\n#define silk_abs(a)                         (((a) >  0)  ? (a) : -(a))            /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN */\n#define silk_abs_int(a)                     (((a) ^ ((a) >> (8 * sizeof(a) - 1))) - ((a) >> (8 * sizeof(a) - 1)))\n#define silk_abs_int32(a)                   (((a) ^ ((a) >> 31)) - ((a) >> 31))\n#define silk_abs_int64(a)                   (((a) >  0)  ? (a) : -(a))\n\n#define silk_sign(a)                        ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 ))\n\n/* PSEUDO-RANDOM GENERATOR                                                          */\n/* Make sure to store the result as the seed for the next call (also in between     */\n/* frames), otherwise result won't be random at all. When only using some of the    */\n/* bits, take the most significant bits by right-shifting.                          */\n#define silk_RAND(seed)                     (silk_MLA_ovflw(907633515, (seed), 196314165))\n\n/*  Add some multiplication functions that can be easily mapped to ARM. */\n\n/*    silk_SMMUL: Signed top word multiply.\n          ARMv6        2 instruction cycles.\n          ARMv3M+      3 instruction cycles. use SMULL and ignore LSB registers.(except xM)*/\n/*#define silk_SMMUL(a32, b32)                (opus_int32)silk_RSHIFT(silk_SMLAL(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)), 16)*/\n/* the following seems faster on x86 */\n#define silk_SMMUL(a32, b32)                (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32)\n\n#if !defined(OPUS_X86_MAY_HAVE_SSE4_1)\n#define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \\\n    ((void)(arch), silk_burg_modified_c(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch))\n\n#define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \\\n    ((void)(arch),silk_inner_prod16_aligned_64_c(inVec1, inVec2, len))\n#endif\n\n#include \"Inlines.h\"\n#include \"MacroCount.h\"\n#include \"MacroDebug.h\"\n\n#ifdef OPUS_ARM_INLINE_ASM\n#include \"arm/SigProc_FIX_armv4.h\"\n#endif\n\n#ifdef OPUS_ARM_INLINE_EDSP\n#include \"arm/SigProc_FIX_armv5e.h\"\n#endif\n\n#if defined(MIPSr1_ASM)\n#include \"mips/sigproc_fix_mipsr1.h\"\n#endif\n\n\n#ifdef  __cplusplus\n}\n#endif\n\n#endif /* SILK_SIGPROC_FIX_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/VAD.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"stack_alloc.h\"\n\n/* Silk VAD noise level estimation */\n# if !defined(OPUS_X86_MAY_HAVE_SSE4_1)\nstatic OPUS_INLINE void silk_VAD_GetNoiseLevels(\n    const opus_int32             pX[ VAD_N_BANDS ], /* I    subband energies                            */\n    silk_VAD_state              *psSilk_VAD         /* I/O  Pointer to Silk VAD state                   */\n);\n#endif\n\n/**********************************/\n/* Initialization of the Silk VAD */\n/**********************************/\nopus_int silk_VAD_Init(                                         /* O    Return value, 0 if success                  */\n    silk_VAD_state              *psSilk_VAD                     /* I/O  Pointer to Silk VAD state                   */\n)\n{\n    opus_int b, ret = 0;\n\n    /* reset state memory */\n    silk_memset( psSilk_VAD, 0, sizeof( silk_VAD_state ) );\n\n    /* init noise levels */\n    /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */\n    for( b = 0; b < VAD_N_BANDS; b++ ) {\n        psSilk_VAD->NoiseLevelBias[ b ] = silk_max_32( silk_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 );\n    }\n\n    /* Initialize state */\n    for( b = 0; b < VAD_N_BANDS; b++ ) {\n        psSilk_VAD->NL[ b ]     = silk_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] );\n        psSilk_VAD->inv_NL[ b ] = silk_DIV32( silk_int32_MAX, psSilk_VAD->NL[ b ] );\n    }\n    psSilk_VAD->counter = 15;\n\n    /* init smoothed energy-to-noise ratio*/\n    for( b = 0; b < VAD_N_BANDS; b++ ) {\n        psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256;       /* 100 * 256 --> 20 dB SNR */\n    }\n\n    return( ret );\n}\n\n/* Weighting factors for tilt measure */\nstatic const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 };\n\n/***************************************/\n/* Get the speech activity level in Q8 */\n/***************************************/\nopus_int silk_VAD_GetSA_Q8_c(                                   /* O    Return value, 0 if success                  */\n    silk_encoder_state          *psEncC,                        /* I/O  Encoder state                               */\n    const opus_int16            pIn[]                           /* I    PCM input                                   */\n)\n{\n    opus_int   SA_Q15, pSNR_dB_Q7, input_tilt;\n    opus_int   decimated_framelength1, decimated_framelength2;\n    opus_int   decimated_framelength;\n    opus_int   dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;\n    opus_int32 sumSquared, smooth_coef_Q16;\n    opus_int16 HPstateTmp;\n    VARDECL( opus_int16, X );\n    opus_int32 Xnrg[ VAD_N_BANDS ];\n    opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];\n    opus_int32 speech_nrg, x_tmp;\n    opus_int   X_offset[ VAD_N_BANDS ];\n    opus_int   ret = 0;\n    silk_VAD_state *psSilk_VAD = &psEncC->sVAD;\n    SAVE_STACK;\n\n    /* Safety checks */\n    silk_assert( VAD_N_BANDS == 4 );\n    silk_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );\n    silk_assert( psEncC->frame_length <= 512 );\n    silk_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );\n\n    /***********************/\n    /* Filter and Decimate */\n    /***********************/\n    decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );\n    decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );\n    decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 );\n    /* Decimate into 4 bands:\n       0       L      3L       L              3L                             5L\n               -      --       -              --                             --\n               8       8       2               4                              4\n\n       [0-1 kHz| temp. |1-2 kHz|    2-4 kHz    |            4-8 kHz           |\n\n       They're arranged to allow the minimal ( frame_length / 4 ) extra\n       scratch space during the downsampling process */\n    X_offset[ 0 ] = 0;\n    X_offset[ 1 ] = decimated_framelength + decimated_framelength2;\n    X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;\n    X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;\n    ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );\n\n    /* 0-8 kHz to 0-4 kHz and 4-8 kHz */\n    silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[  0 ],\n        X, &X[ X_offset[ 3 ] ], psEncC->frame_length );\n\n    /* 0-4 kHz to 0-2 kHz and 2-4 kHz */\n    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],\n        X, &X[ X_offset[ 2 ] ], decimated_framelength1 );\n\n    /* 0-2 kHz to 0-1 kHz and 1-2 kHz */\n    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],\n        X, &X[ X_offset[ 1 ] ], decimated_framelength2 );\n\n    /*********************************************/\n    /* HP filter on lowest band (differentiator) */\n    /*********************************************/\n    X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );\n    HPstateTmp = X[ decimated_framelength - 1 ];\n    for( i = decimated_framelength - 1; i > 0; i-- ) {\n        X[ i - 1 ]  = silk_RSHIFT( X[ i - 1 ], 1 );\n        X[ i ]     -= X[ i - 1 ];\n    }\n    X[ 0 ] -= psSilk_VAD->HPstate;\n    psSilk_VAD->HPstate = HPstateTmp;\n\n    /*************************************/\n    /* Calculate the energy in each band */\n    /*************************************/\n    for( b = 0; b < VAD_N_BANDS; b++ ) {\n        /* Find the decimated framelength in the non-uniformly divided bands */\n        decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );\n\n        /* Split length into subframe lengths */\n        dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );\n        dec_subframe_offset = 0;\n\n        /* Compute energy per sub-frame */\n        /* initialize with summed energy of last subframe */\n        Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];\n        for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {\n            sumSquared = 0;\n            for( i = 0; i < dec_subframe_length; i++ ) {\n                /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2.            */\n                /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128)  */\n                x_tmp = silk_RSHIFT(\n                    X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );\n                sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );\n\n                /* Safety check */\n                silk_assert( sumSquared >= 0 );\n            }\n\n            /* Add/saturate summed energy of current subframe */\n            if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {\n                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );\n            } else {\n                /* Look-ahead subframe */\n                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );\n            }\n\n            dec_subframe_offset += dec_subframe_length;\n        }\n        psSilk_VAD->XnrgSubfr[ b ] = sumSquared;\n    }\n\n    /********************/\n    /* Noise estimation */\n    /********************/\n    silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );\n\n    /***********************************************/\n    /* Signal-plus-noise to noise ratio estimation */\n    /***********************************************/\n    sumSquared = 0;\n    input_tilt = 0;\n    for( b = 0; b < VAD_N_BANDS; b++ ) {\n        speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];\n        if( speech_nrg > 0 ) {\n            /* Divide, with sufficient resolution */\n            if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {\n                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );\n            } else {\n                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );\n            }\n\n            /* Convert to log domain */\n            SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;\n\n            /* Sum-of-squares */\n            sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 );          /* Q14 */\n\n            /* Tilt measure */\n            if( speech_nrg < ( (opus_int32)1 << 20 ) ) {\n                /* Scale down SNR value for small subband speech energies */\n                SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );\n            }\n            input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );\n        } else {\n            NrgToNoiseRatio_Q8[ b ] = 256;\n        }\n    }\n\n    /* Mean-of-squares */\n    sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */\n\n    /* Root-mean-square approximation, scale to dBs, and write to output pointer */\n    pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */\n\n    /*********************************/\n    /* Speech Probability Estimation */\n    /*********************************/\n    SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );\n\n    /**************************/\n    /* Frequency Tilt Measure */\n    /**************************/\n    psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 );\n\n    /**************************************************/\n    /* Scale the sigmoid output based on power levels */\n    /**************************************************/\n    speech_nrg = 0;\n    for( b = 0; b < VAD_N_BANDS; b++ ) {\n        /* Accumulate signal-without-noise energies, higher frequency bands have more weight */\n        speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );\n    }\n\n    /* Power scaling */\n    if( speech_nrg <= 0 ) {\n        SA_Q15 = silk_RSHIFT( SA_Q15, 1 );\n    } else if( speech_nrg < 32768 ) {\n        if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {\n            speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 16 );\n        } else {\n            speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 15 );\n        }\n\n        /* square-root */\n        speech_nrg = silk_SQRT_APPROX( speech_nrg );\n        SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 );\n    }\n\n    /* Copy the resulting speech activity in Q8 */\n    psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX );\n\n    /***********************************/\n    /* Energy Level and SNR estimation */\n    /***********************************/\n    /* Smoothing coefficient */\n    smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) );\n\n    if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {\n        smooth_coef_Q16 >>= 1;\n    }\n\n    for( b = 0; b < VAD_N_BANDS; b++ ) {\n        /* compute smoothed energy-to-noise ratio per band */\n        psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],\n            NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );\n\n        /* signal to noise ratio in dB per band */\n        SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );\n        /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */\n        psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );\n    }\n\n    RESTORE_STACK;\n    return( ret );\n}\n\n/**************************/\n/* Noise level estimation */\n/**************************/\n# if  !defined(OPUS_X86_MAY_HAVE_SSE4_1)\nstatic OPUS_INLINE\n#endif\nvoid silk_VAD_GetNoiseLevels(\n    const opus_int32            pX[ VAD_N_BANDS ],  /* I    subband energies                            */\n    silk_VAD_state              *psSilk_VAD         /* I/O  Pointer to Silk VAD state                   */\n)\n{\n    opus_int   k;\n    opus_int32 nl, nrg, inv_nrg;\n    opus_int   coef, min_coef;\n\n    /* Initially faster smoothing */\n    if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */\n        min_coef = silk_DIV32_16( silk_int16_MAX, silk_RSHIFT( psSilk_VAD->counter, 4 ) + 1 );\n    } else {\n        min_coef = 0;\n    }\n\n    for( k = 0; k < VAD_N_BANDS; k++ ) {\n        /* Get old noise level estimate for current band */\n        nl = psSilk_VAD->NL[ k ];\n        silk_assert( nl >= 0 );\n\n        /* Add bias */\n        nrg = silk_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] );\n        silk_assert( nrg > 0 );\n\n        /* Invert energies */\n        inv_nrg = silk_DIV32( silk_int32_MAX, nrg );\n        silk_assert( inv_nrg >= 0 );\n\n        /* Less update when subband energy is high */\n        if( nrg > silk_LSHIFT( nl, 3 ) ) {\n            coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3;\n        } else if( nrg < nl ) {\n            coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16;\n        } else {\n            coef = silk_SMULWB( silk_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 );\n        }\n\n        /* Initially faster smoothing */\n        coef = silk_max_int( coef, min_coef );\n\n        /* Smooth inverse energies */\n        psSilk_VAD->inv_NL[ k ] = silk_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef );\n        silk_assert( psSilk_VAD->inv_NL[ k ] >= 0 );\n\n        /* Compute noise level by inverting again */\n        nl = silk_DIV32( silk_int32_MAX, psSilk_VAD->inv_NL[ k ] );\n        silk_assert( nl >= 0 );\n\n        /* Limit noise levels (guarantee 7 bits of head room) */\n        nl = silk_min( nl, 0x00FFFFFF );\n\n        /* Store as part of state */\n        psSilk_VAD->NL[ k ] = nl;\n    }\n\n    /* Increment frame counter */\n    psSilk_VAD->counter++;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/VQ_WMat_EC.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */\nvoid silk_VQ_WMat_EC_c(\n    opus_int8                   *ind,                           /* O    index of best codebook vector               */\n    opus_int32                  *rate_dist_Q14,                 /* O    best weighted quant error + mu * rate       */\n    opus_int                    *gain_Q7,                       /* O    sum of absolute LTP coefficients            */\n    const opus_int16            *in_Q14,                        /* I    input vector to be quantized                */\n    const opus_int32            *W_Q18,                         /* I    weighting matrix                            */\n    const opus_int8             *cb_Q7,                         /* I    codebook                                    */\n    const opus_uint8            *cb_gain_Q7,                    /* I    codebook effective gain                     */\n    const opus_uint8            *cl_Q5,                         /* I    code length for each codebook vector        */\n    const opus_int              mu_Q9,                          /* I    tradeoff betw. weighted error and rate      */\n    const opus_int32            max_gain_Q7,                    /* I    maximum sum of absolute LTP coefficients    */\n    opus_int                    L                               /* I    number of vectors in codebook               */\n)\n{\n    opus_int   k, gain_tmp_Q7;\n    const opus_int8 *cb_row_Q7;\n    opus_int16 diff_Q14[ 5 ];\n    opus_int32 sum1_Q14, sum2_Q16;\n\n    /* Loop over codebook */\n    *rate_dist_Q14 = silk_int32_MAX;\n    cb_row_Q7 = cb_Q7;\n    for( k = 0; k < L; k++ ) {\n        gain_tmp_Q7 = cb_gain_Q7[k];\n\n        diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 );\n        diff_Q14[ 1 ] = in_Q14[ 1 ] - silk_LSHIFT( cb_row_Q7[ 1 ], 7 );\n        diff_Q14[ 2 ] = in_Q14[ 2 ] - silk_LSHIFT( cb_row_Q7[ 2 ], 7 );\n        diff_Q14[ 3 ] = in_Q14[ 3 ] - silk_LSHIFT( cb_row_Q7[ 3 ], 7 );\n        diff_Q14[ 4 ] = in_Q14[ 4 ] - silk_LSHIFT( cb_row_Q7[ 4 ], 7 );\n\n        /* Weighted rate */\n        sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] );\n\n        /* Penalty for too large gain */\n        sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 );\n\n        silk_assert( sum1_Q14 >= 0 );\n\n        /* first row of W_Q18 */\n        sum2_Q16 = silk_SMULWB(           W_Q18[  1 ], diff_Q14[ 1 ] );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  2 ], diff_Q14[ 2 ] );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  3 ], diff_Q14[ 3 ] );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  4 ], diff_Q14[ 4 ] );\n        sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  0 ], diff_Q14[ 0 ] );\n        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 0 ] );\n\n        /* second row of W_Q18 */\n        sum2_Q16 = silk_SMULWB(           W_Q18[  7 ], diff_Q14[ 2 ] );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  8 ], diff_Q14[ 3 ] );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  9 ], diff_Q14[ 4 ] );\n        sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  6 ], diff_Q14[ 1 ] );\n        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 1 ] );\n\n        /* third row of W_Q18 */\n        sum2_Q16 = silk_SMULWB(           W_Q18[ 13 ], diff_Q14[ 3 ] );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] );\n        sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] );\n        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 2 ] );\n\n        /* fourth row of W_Q18 */\n        sum2_Q16 = silk_SMULWB(           W_Q18[ 19 ], diff_Q14[ 4 ] );\n        sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] );\n        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 3 ] );\n\n        /* last row of W_Q18 */\n        sum2_Q16 = silk_SMULWB(           W_Q18[ 24 ], diff_Q14[ 4 ] );\n        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 4 ] );\n\n        silk_assert( sum1_Q14 >= 0 );\n\n        /* find best */\n        if( sum1_Q14 < *rate_dist_Q14 ) {\n            *rate_dist_Q14 = sum1_Q14;\n            *ind = (opus_int8)k;\n            *gain_Q7 = gain_tmp_Q7;\n        }\n\n        /* Go to next cbk vector */\n        cb_row_Q7 += LTP_ORDER;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/ana_filt_bank_1.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n\n/* Coefficients for 2-band filter bank based on first-order allpass filters */\nstatic opus_int16 A_fb1_20 = 5394 << 1;\nstatic opus_int16 A_fb1_21 = -24290; /* (opus_int16)(20623 << 1) */\n\n/* Split signal into two decimated bands using first-order allpass filters */\nvoid silk_ana_filt_bank_1(\n    const opus_int16            *in,                /* I    Input signal [N]                                            */\n    opus_int32                  *S,                 /* I/O  State vector [2]                                            */\n    opus_int16                  *outL,              /* O    Low band [N/2]                                              */\n    opus_int16                  *outH,              /* O    High band [N/2]                                             */\n    const opus_int32            N                   /* I    Number of input samples                                     */\n)\n{\n    opus_int      k, N2 = silk_RSHIFT( N, 1 );\n    opus_int32    in32, X, Y, out_1, out_2;\n\n    /* Internal variables and state are in Q10 format */\n    for( k = 0; k < N2; k++ ) {\n        /* Convert to Q10 */\n        in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 );\n\n        /* All-pass section for even input sample */\n        Y      = silk_SUB32( in32, S[ 0 ] );\n        X      = silk_SMLAWB( Y, Y, A_fb1_21 );\n        out_1  = silk_ADD32( S[ 0 ], X );\n        S[ 0 ] = silk_ADD32( in32, X );\n\n        /* Convert to Q10 */\n        in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 );\n\n        /* All-pass section for odd input sample, and add to output of previous section */\n        Y      = silk_SUB32( in32, S[ 1 ] );\n        X      = silk_SMULWB( Y, A_fb1_20 );\n        out_2  = silk_ADD32( S[ 1 ], X );\n        S[ 1 ] = silk_ADD32( in32, X );\n\n        /* Add/subtract, convert back to int16 and store to output */\n        outL[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_ADD32( out_2, out_1 ), 11 ) );\n        outH[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SUB32( out_2, out_1 ), 11 ) );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/arm/SigProc_FIX_armv4.h",
    "content": "/***********************************************************************\nCopyright (C) 2013 Xiph.Org Foundation and contributors\nCopyright (c) 2013       Parrot\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_SIGPROC_FIX_ARMv4_H\n#define SILK_SIGPROC_FIX_ARMv4_H\n\n#undef silk_MLA\nstatic OPUS_INLINE opus_int32 silk_MLA_armv4(opus_int32 a, opus_int32 b,\n opus_int32 c)\n{\n  opus_int32 res;\n  __asm__(\n      \"#silk_MLA\\n\\t\"\n      \"mla %0, %1, %2, %3\\n\\t\"\n      : \"=&r\"(res)\n      : \"r\"(b), \"r\"(c), \"r\"(a)\n  );\n  return res;\n}\n#define silk_MLA(a, b, c) (silk_MLA_armv4(a, b, c))\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/arm/SigProc_FIX_armv5e.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nCopyright (c) 2013       Parrot\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_SIGPROC_FIX_ARMv5E_H\n#define SILK_SIGPROC_FIX_ARMv5E_H\n\n#undef silk_SMULTT\nstatic OPUS_INLINE opus_int32 silk_SMULTT_armv5e(opus_int32 a, opus_int32 b)\n{\n  opus_int32 res;\n  __asm__(\n      \"#silk_SMULTT\\n\\t\"\n      \"smultt %0, %1, %2\\n\\t\"\n      : \"=r\"(res)\n      : \"%r\"(a), \"r\"(b)\n  );\n  return res;\n}\n#define silk_SMULTT(a, b) (silk_SMULTT_armv5e(a, b))\n\n#undef silk_SMLATT\nstatic OPUS_INLINE opus_int32 silk_SMLATT_armv5e(opus_int32 a, opus_int32 b,\n opus_int32 c)\n{\n  opus_int32 res;\n  __asm__(\n      \"#silk_SMLATT\\n\\t\"\n      \"smlatt %0, %1, %2, %3\\n\\t\"\n      : \"=r\"(res)\n      : \"%r\"(b), \"r\"(c), \"r\"(a)\n  );\n  return res;\n}\n#define silk_SMLATT(a, b, c) (silk_SMLATT_armv5e(a, b, c))\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/arm/macros_armv4.h",
    "content": "/***********************************************************************\nCopyright (C) 2013 Xiph.Org Foundation and contributors.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_MACROS_ARMv4_H\n#define SILK_MACROS_ARMv4_H\n\n/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */\n#undef silk_SMULWB\nstatic OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b)\n{\n  unsigned rd_lo;\n  int rd_hi;\n  __asm__(\n      \"#silk_SMULWB\\n\\t\"\n      \"smull %0, %1, %2, %3\\n\\t\"\n      : \"=&r\"(rd_lo), \"=&r\"(rd_hi)\n      : \"%r\"(a), \"r\"(b<<16)\n  );\n  return rd_hi;\n}\n#define silk_SMULWB(a, b) (silk_SMULWB_armv4(a, b))\n\n/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */\n#undef silk_SMLAWB\n#define silk_SMLAWB(a, b, c) ((a) + silk_SMULWB(b, c))\n\n/* (a32 * (b32 >> 16)) >> 16 */\n#undef silk_SMULWT\nstatic OPUS_INLINE opus_int32 silk_SMULWT_armv4(opus_int32 a, opus_int32 b)\n{\n  unsigned rd_lo;\n  int rd_hi;\n  __asm__(\n      \"#silk_SMULWT\\n\\t\"\n      \"smull %0, %1, %2, %3\\n\\t\"\n      : \"=&r\"(rd_lo), \"=&r\"(rd_hi)\n      : \"%r\"(a), \"r\"(b&~0xFFFF)\n  );\n  return rd_hi;\n}\n#define silk_SMULWT(a, b) (silk_SMULWT_armv4(a, b))\n\n/* a32 + (b32 * (c32 >> 16)) >> 16 */\n#undef silk_SMLAWT\n#define silk_SMLAWT(a, b, c) ((a) + silk_SMULWT(b, c))\n\n/* (a32 * b32) >> 16 */\n#undef silk_SMULWW\nstatic OPUS_INLINE opus_int32 silk_SMULWW_armv4(opus_int32 a, opus_int32 b)\n{\n  unsigned rd_lo;\n  int rd_hi;\n  __asm__(\n    \"#silk_SMULWW\\n\\t\"\n    \"smull %0, %1, %2, %3\\n\\t\"\n    : \"=&r\"(rd_lo), \"=&r\"(rd_hi)\n    : \"%r\"(a), \"r\"(b)\n  );\n  return (rd_hi<<16)+(rd_lo>>16);\n}\n#define silk_SMULWW(a, b) (silk_SMULWW_armv4(a, b))\n\n#undef silk_SMLAWW\nstatic OPUS_INLINE opus_int32 silk_SMLAWW_armv4(opus_int32 a, opus_int32 b,\n opus_int32 c)\n{\n  unsigned rd_lo;\n  int rd_hi;\n  __asm__(\n    \"#silk_SMLAWW\\n\\t\"\n    \"smull %0, %1, %2, %3\\n\\t\"\n    : \"=&r\"(rd_lo), \"=&r\"(rd_hi)\n    : \"%r\"(b), \"r\"(c)\n  );\n  return a+(rd_hi<<16)+(rd_lo>>16);\n}\n#define silk_SMLAWW(a, b, c) (silk_SMLAWW_armv4(a, b, c))\n\n#endif /* SILK_MACROS_ARMv4_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/arm/macros_armv5e.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nCopyright (c) 2013       Parrot\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_MACROS_ARMv5E_H\n#define SILK_MACROS_ARMv5E_H\n\n/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */\n#undef silk_SMULWB\nstatic OPUS_INLINE opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b)\n{\n  int res;\n  __asm__(\n      \"#silk_SMULWB\\n\\t\"\n      \"smulwb %0, %1, %2\\n\\t\"\n      : \"=r\"(res)\n      : \"r\"(a), \"r\"(b)\n  );\n  return res;\n}\n#define silk_SMULWB(a, b) (silk_SMULWB_armv5e(a, b))\n\n/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */\n#undef silk_SMLAWB\nstatic OPUS_INLINE opus_int32 silk_SMLAWB_armv5e(opus_int32 a, opus_int32 b,\n opus_int16 c)\n{\n  int res;\n  __asm__(\n      \"#silk_SMLAWB\\n\\t\"\n      \"smlawb %0, %1, %2, %3\\n\\t\"\n      : \"=r\"(res)\n      : \"r\"(b), \"r\"(c), \"r\"(a)\n  );\n  return res;\n}\n#define silk_SMLAWB(a, b, c) (silk_SMLAWB_armv5e(a, b, c))\n\n/* (a32 * (b32 >> 16)) >> 16 */\n#undef silk_SMULWT\nstatic OPUS_INLINE opus_int32 silk_SMULWT_armv5e(opus_int32 a, opus_int32 b)\n{\n  int res;\n  __asm__(\n      \"#silk_SMULWT\\n\\t\"\n      \"smulwt %0, %1, %2\\n\\t\"\n      : \"=r\"(res)\n      : \"r\"(a), \"r\"(b)\n  );\n  return res;\n}\n#define silk_SMULWT(a, b) (silk_SMULWT_armv5e(a, b))\n\n/* a32 + (b32 * (c32 >> 16)) >> 16 */\n#undef silk_SMLAWT\nstatic OPUS_INLINE opus_int32 silk_SMLAWT_armv5e(opus_int32 a, opus_int32 b,\n opus_int32 c)\n{\n  int res;\n  __asm__(\n      \"#silk_SMLAWT\\n\\t\"\n      \"smlawt %0, %1, %2, %3\\n\\t\"\n      : \"=r\"(res)\n      : \"r\"(b), \"r\"(c), \"r\"(a)\n  );\n  return res;\n}\n#define silk_SMLAWT(a, b, c) (silk_SMLAWT_armv5e(a, b, c))\n\n/* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */\n#undef silk_SMULBB\nstatic OPUS_INLINE opus_int32 silk_SMULBB_armv5e(opus_int32 a, opus_int32 b)\n{\n  int res;\n  __asm__(\n      \"#silk_SMULBB\\n\\t\"\n      \"smulbb %0, %1, %2\\n\\t\"\n      : \"=r\"(res)\n      : \"%r\"(a), \"r\"(b)\n  );\n  return res;\n}\n#define silk_SMULBB(a, b) (silk_SMULBB_armv5e(a, b))\n\n/* a32 + (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)) output have to be 32bit int */\n#undef silk_SMLABB\nstatic OPUS_INLINE opus_int32 silk_SMLABB_armv5e(opus_int32 a, opus_int32 b,\n opus_int32 c)\n{\n  int res;\n  __asm__(\n      \"#silk_SMLABB\\n\\t\"\n      \"smlabb %0, %1, %2, %3\\n\\t\"\n      : \"=r\"(res)\n      : \"%r\"(b), \"r\"(c), \"r\"(a)\n  );\n  return res;\n}\n#define silk_SMLABB(a, b, c) (silk_SMLABB_armv5e(a, b, c))\n\n/* (opus_int32)((opus_int16)(a32)) * (b32 >> 16) */\n#undef silk_SMULBT\nstatic OPUS_INLINE opus_int32 silk_SMULBT_armv5e(opus_int32 a, opus_int32 b)\n{\n  int res;\n  __asm__(\n      \"#silk_SMULBT\\n\\t\"\n      \"smulbt %0, %1, %2\\n\\t\"\n      : \"=r\"(res)\n      : \"r\"(a), \"r\"(b)\n  );\n  return res;\n}\n#define silk_SMULBT(a, b) (silk_SMULBT_armv5e(a, b))\n\n/* a32 + (opus_int32)((opus_int16)(b32)) * (c32 >> 16) */\n#undef silk_SMLABT\nstatic OPUS_INLINE opus_int32 silk_SMLABT_armv5e(opus_int32 a, opus_int32 b,\n opus_int32 c)\n{\n  int res;\n  __asm__(\n      \"#silk_SMLABT\\n\\t\"\n      \"smlabt %0, %1, %2, %3\\n\\t\"\n      : \"=r\"(res)\n      : \"r\"(b), \"r\"(c), \"r\"(a)\n  );\n  return res;\n}\n#define silk_SMLABT(a, b, c) (silk_SMLABT_armv5e(a, b, c))\n\n/* add/subtract with output saturated */\n#undef silk_ADD_SAT32\nstatic OPUS_INLINE opus_int32 silk_ADD_SAT32_armv5e(opus_int32 a, opus_int32 b)\n{\n  int res;\n  __asm__(\n      \"#silk_ADD_SAT32\\n\\t\"\n      \"qadd %0, %1, %2\\n\\t\"\n      : \"=r\"(res)\n      : \"%r\"(a), \"r\"(b)\n  );\n  return res;\n}\n#define silk_ADD_SAT32(a, b) (silk_ADD_SAT32_armv5e(a, b))\n\n#undef silk_SUB_SAT32\nstatic OPUS_INLINE opus_int32 silk_SUB_SAT32_armv5e(opus_int32 a, opus_int32 b)\n{\n  int res;\n  __asm__(\n      \"#silk_SUB_SAT32\\n\\t\"\n      \"qsub %0, %1, %2\\n\\t\"\n      : \"=r\"(res)\n      : \"r\"(a), \"r\"(b)\n  );\n  return res;\n}\n#define silk_SUB_SAT32(a, b) (silk_SUB_SAT32_armv5e(a, b))\n\n#undef silk_CLZ16\nstatic OPUS_INLINE opus_int32 silk_CLZ16_armv5(opus_int16 in16)\n{\n  int res;\n  __asm__(\n      \"#silk_CLZ16\\n\\t\"\n      \"clz %0, %1;\\n\"\n      : \"=r\"(res)\n      : \"r\"(in16<<16|0x8000)\n  );\n  return res;\n}\n#define silk_CLZ16(in16) (silk_CLZ16_armv5(in16))\n\n#undef silk_CLZ32\nstatic OPUS_INLINE opus_int32 silk_CLZ32_armv5(opus_int32 in32)\n{\n  int res;\n  __asm__(\n      \"#silk_CLZ32\\n\\t\"\n      \"clz %0, %1\\n\\t\"\n      : \"=r\"(res)\n      : \"r\"(in32)\n  );\n  return res;\n}\n#define silk_CLZ32(in32) (silk_CLZ32_armv5(in32))\n\n#endif /* SILK_MACROS_ARMv5E_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/biquad_alt.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n/*                                                                      *\n * silk_biquad_alt.c                                              *\n *                                                                      *\n * Second order ARMA filter                                             *\n * Can handle slowly varying filter coefficients                        *\n *                                                                      */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n\n/* Second order ARMA filter, alternative implementation */\nvoid silk_biquad_alt(\n    const opus_int16            *in,                /* I     input signal                                               */\n    const opus_int32            *B_Q28,             /* I     MA coefficients [3]                                        */\n    const opus_int32            *A_Q28,             /* I     AR coefficients [2]                                        */\n    opus_int32                  *S,                 /* I/O   State vector [2]                                           */\n    opus_int16                  *out,               /* O     output signal                                              */\n    const opus_int32            len,                /* I     signal length (must be even)                               */\n    opus_int                    stride              /* I     Operate on interleaved signal if > 1                       */\n)\n{\n    /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */\n    opus_int   k;\n    opus_int32 inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14;\n\n    /* Negate A_Q28 values and split in two parts */\n    A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF;        /* lower part */\n    A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 );      /* upper part */\n    A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF;        /* lower part */\n    A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 );      /* upper part */\n\n    for( k = 0; k < len; k++ ) {\n        /* S[ 0 ], S[ 1 ]: Q12 */\n        inval = in[ k * stride ];\n        out32_Q14 = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 );\n\n        S[ 0 ] = S[1] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A0_L_Q28 ), 14 );\n        S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 );\n        S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval);\n\n        S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A1_L_Q28 ), 14 );\n        S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 );\n        S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval );\n\n        /* Scale back to Q0 and saturate */\n        out[ k * stride ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/bwexpander.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n\n/* Chirp (bandwidth expand) LP AR filter */\nvoid silk_bwexpander(\n    opus_int16                  *ar,                /* I/O  AR filter to be expanded (without leading 1)                */\n    const opus_int              d,                  /* I    Length of ar                                                */\n    opus_int32                  chirp_Q16           /* I    Chirp factor (typically in the range 0 to 1)                */\n)\n{\n    opus_int   i;\n    opus_int32 chirp_minus_one_Q16 = chirp_Q16 - 65536;\n\n    /* NB: Dont use silk_SMULWB, instead of silk_RSHIFT_ROUND( silk_MUL(), 16 ), below.  */\n    /* Bias in silk_SMULWB can lead to unstable filters                                */\n    for( i = 0; i < d - 1; i++ ) {\n        ar[ i ]    = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ i ]             ), 16 );\n        chirp_Q16 +=            silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );\n    }\n    ar[ d - 1 ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ d - 1 ] ), 16 );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/bwexpander_32.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n\n/* Chirp (bandwidth expand) LP AR filter */\nvoid silk_bwexpander_32(\n    opus_int32                  *ar,                /* I/O  AR filter to be expanded (without leading 1)                */\n    const opus_int              d,                  /* I    Length of ar                                                */\n    opus_int32                  chirp_Q16           /* I    Chirp factor in Q16                                         */\n)\n{\n    opus_int   i;\n    opus_int32 chirp_minus_one_Q16 = chirp_Q16 - 65536;\n\n    for( i = 0; i < d - 1; i++ ) {\n        ar[ i ]    = silk_SMULWW( chirp_Q16, ar[ i ] );\n        chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );\n    }\n    ar[ d - 1 ] = silk_SMULWW( chirp_Q16, ar[ d - 1 ] );\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/check_control_input.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"control.h\"\n#include \"errors.h\"\n\n/* Check encoder control struct */\nopus_int check_control_input(\n    silk_EncControlStruct        *encControl                    /* I    Control structure                           */\n)\n{\n    silk_assert( encControl != NULL );\n\n    if( ( ( encControl->API_sampleRate            !=  8000 ) &&\n          ( encControl->API_sampleRate            != 12000 ) &&\n          ( encControl->API_sampleRate            != 16000 ) &&\n          ( encControl->API_sampleRate            != 24000 ) &&\n          ( encControl->API_sampleRate            != 32000 ) &&\n          ( encControl->API_sampleRate            != 44100 ) &&\n          ( encControl->API_sampleRate            != 48000 ) ) ||\n        ( ( encControl->desiredInternalSampleRate !=  8000 ) &&\n          ( encControl->desiredInternalSampleRate != 12000 ) &&\n          ( encControl->desiredInternalSampleRate != 16000 ) ) ||\n        ( ( encControl->maxInternalSampleRate     !=  8000 ) &&\n          ( encControl->maxInternalSampleRate     != 12000 ) &&\n          ( encControl->maxInternalSampleRate     != 16000 ) ) ||\n        ( ( encControl->minInternalSampleRate     !=  8000 ) &&\n          ( encControl->minInternalSampleRate     != 12000 ) &&\n          ( encControl->minInternalSampleRate     != 16000 ) ) ||\n          ( encControl->minInternalSampleRate > encControl->desiredInternalSampleRate ) ||\n          ( encControl->maxInternalSampleRate < encControl->desiredInternalSampleRate ) ||\n          ( encControl->minInternalSampleRate > encControl->maxInternalSampleRate ) ) {\n        silk_assert( 0 );\n        return SILK_ENC_FS_NOT_SUPPORTED;\n    }\n    if( encControl->payloadSize_ms != 10 &&\n        encControl->payloadSize_ms != 20 &&\n        encControl->payloadSize_ms != 40 &&\n        encControl->payloadSize_ms != 60 ) {\n        silk_assert( 0 );\n        return SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;\n    }\n    if( encControl->packetLossPercentage < 0 || encControl->packetLossPercentage > 100 ) {\n        silk_assert( 0 );\n        return SILK_ENC_INVALID_LOSS_RATE;\n    }\n    if( encControl->useDTX < 0 || encControl->useDTX > 1 ) {\n        silk_assert( 0 );\n        return SILK_ENC_INVALID_DTX_SETTING;\n    }\n    if( encControl->useCBR < 0 || encControl->useCBR > 1 ) {\n        silk_assert( 0 );\n        return SILK_ENC_INVALID_CBR_SETTING;\n    }\n    if( encControl->useInBandFEC < 0 || encControl->useInBandFEC > 1 ) {\n        silk_assert( 0 );\n        return SILK_ENC_INVALID_INBAND_FEC_SETTING;\n    }\n    if( encControl->nChannelsAPI < 1 || encControl->nChannelsAPI > ENCODER_NUM_CHANNELS ) {\n        silk_assert( 0 );\n        return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;\n    }\n    if( encControl->nChannelsInternal < 1 || encControl->nChannelsInternal > ENCODER_NUM_CHANNELS ) {\n        silk_assert( 0 );\n        return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;\n    }\n    if( encControl->nChannelsInternal > encControl->nChannelsAPI ) {\n        silk_assert( 0 );\n        return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;\n    }\n    if( encControl->complexity < 0 || encControl->complexity > 10 ) {\n        silk_assert( 0 );\n        return SILK_ENC_INVALID_COMPLEXITY_SETTING;\n    }\n\n    return SILK_NO_ERROR;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/code_signs.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/*#define silk_enc_map(a)                ((a) > 0 ? 1 : 0)*/\n/*#define silk_dec_map(a)                ((a) > 0 ? 1 : -1)*/\n/* shifting avoids if-statement */\n#define silk_enc_map(a)                  ( silk_RSHIFT( (a), 15 ) + 1 )\n#define silk_dec_map(a)                  ( silk_LSHIFT( (a),  1 ) - 1 )\n\n/* Encodes signs of excitation */\nvoid silk_encode_signs(\n    ec_enc                      *psRangeEnc,                        /* I/O  Compressor data structure                   */\n    const opus_int8             pulses[],                           /* I    pulse signal                                */\n    opus_int                    length,                             /* I    length of input                             */\n    const opus_int              signalType,                         /* I    Signal type                                 */\n    const opus_int              quantOffsetType,                    /* I    Quantization offset type                    */\n    const opus_int              sum_pulses[ MAX_NB_SHELL_BLOCKS ]   /* I    Sum of absolute pulses per block            */\n)\n{\n    opus_int         i, j, p;\n    opus_uint8       icdf[ 2 ];\n    const opus_int8  *q_ptr;\n    const opus_uint8 *icdf_ptr;\n\n    icdf[ 1 ] = 0;\n    q_ptr = pulses;\n    i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) );\n    icdf_ptr = &silk_sign_iCDF[ i ];\n    length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH );\n    for( i = 0; i < length; i++ ) {\n        p = sum_pulses[ i ];\n        if( p > 0 ) {\n            icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ];\n            for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) {\n                if( q_ptr[ j ] != 0 ) {\n                    ec_enc_icdf( psRangeEnc, silk_enc_map( q_ptr[ j ]), icdf, 8 );\n                }\n            }\n        }\n        q_ptr += SHELL_CODEC_FRAME_LENGTH;\n    }\n}\n\n/* Decodes signs of excitation */\nvoid silk_decode_signs(\n    ec_dec                      *psRangeDec,                        /* I/O  Compressor data structure                   */\n    opus_int16                  pulses[],                           /* I/O  pulse signal                                */\n    opus_int                    length,                             /* I    length of input                             */\n    const opus_int              signalType,                         /* I    Signal type                                 */\n    const opus_int              quantOffsetType,                    /* I    Quantization offset type                    */\n    const opus_int              sum_pulses[ MAX_NB_SHELL_BLOCKS ]   /* I    Sum of absolute pulses per block            */\n)\n{\n    opus_int         i, j, p;\n    opus_uint8       icdf[ 2 ];\n    opus_int16       *q_ptr;\n    const opus_uint8 *icdf_ptr;\n\n    icdf[ 1 ] = 0;\n    q_ptr = pulses;\n    i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) );\n    icdf_ptr = &silk_sign_iCDF[ i ];\n    length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH );\n    for( i = 0; i < length; i++ ) {\n        p = sum_pulses[ i ];\n        if( p > 0 ) {\n            icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ];\n            for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) {\n                if( q_ptr[ j ] > 0 ) {\n                    /* attach sign */\n#if 0\n                    /* conditional implementation */\n                    if( ec_dec_icdf( psRangeDec, icdf, 8 ) == 0 ) {\n                        q_ptr[ j ] = -q_ptr[ j ];\n                    }\n#else\n                    /* implementation with shift, subtraction, multiplication */\n                    q_ptr[ j ] *= silk_dec_map( ec_dec_icdf( psRangeDec, icdf, 8 ) );\n#endif\n                }\n            }\n        }\n        q_ptr += SHELL_CODEC_FRAME_LENGTH;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/control.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_CONTROL_H\n#define SILK_CONTROL_H\n\n#include \"typedef.h\"\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/* Decoder API flags */\n#define FLAG_DECODE_NORMAL                      0\n#define FLAG_PACKET_LOST                        1\n#define FLAG_DECODE_LBRR                        2\n\n/***********************************************/\n/* Structure for controlling encoder operation */\n/***********************************************/\ntypedef struct {\n    /* I:   Number of channels; 1/2                                                         */\n    opus_int32 nChannelsAPI;\n\n    /* I:   Number of channels; 1/2                                                         */\n    opus_int32 nChannelsInternal;\n\n    /* I:   Input signal sampling rate in Hertz; 8000/12000/16000/24000/32000/44100/48000   */\n    opus_int32 API_sampleRate;\n\n    /* I:   Maximum internal sampling rate in Hertz; 8000/12000/16000                       */\n    opus_int32 maxInternalSampleRate;\n\n    /* I:   Minimum internal sampling rate in Hertz; 8000/12000/16000                       */\n    opus_int32 minInternalSampleRate;\n\n    /* I:   Soft request for internal sampling rate in Hertz; 8000/12000/16000              */\n    opus_int32 desiredInternalSampleRate;\n\n    /* I:   Number of samples per packet in milliseconds; 10/20/40/60                       */\n    opus_int payloadSize_ms;\n\n    /* I:   Bitrate during active speech in bits/second; internally limited                 */\n    opus_int32 bitRate;\n\n    /* I:   Uplink packet loss in percent (0-100)                                           */\n    opus_int packetLossPercentage;\n\n    /* I:   Complexity mode; 0 is lowest, 10 is highest complexity                          */\n    opus_int complexity;\n\n    /* I:   Flag to enable in-band Forward Error Correction (FEC); 0/1                      */\n    opus_int useInBandFEC;\n\n    /* I:   Flag to enable discontinuous transmission (DTX); 0/1                            */\n    opus_int useDTX;\n\n    /* I:   Flag to use constant bitrate                                                    */\n    opus_int useCBR;\n\n    /* I:   Maximum number of bits allowed for the frame                                    */\n    opus_int maxBits;\n\n    /* I:   Causes a smooth downmix to mono                                                 */\n    opus_int toMono;\n\n    /* I:   Opus encoder is allowing us to switch bandwidth                                 */\n    opus_int opusCanSwitch;\n\n    /* I: Make frames as independent as possible (but still use LPC)                        */\n    opus_int reducedDependency;\n\n    /* O:   Internal sampling rate used, in Hertz; 8000/12000/16000                         */\n    opus_int32 internalSampleRate;\n\n    /* O: Flag that bandwidth switching is allowed (because low voice activity)             */\n    opus_int allowBandwidthSwitch;\n\n    /* O:   Flag that SILK runs in WB mode without variable LP filter (use for switching between WB/SWB/FB) */\n    opus_int inWBmodeWithoutVariableLP;\n\n    /* O:   Stereo width */\n    opus_int stereoWidth_Q14;\n\n    /* O:   Tells the Opus encoder we're ready to switch                                    */\n    opus_int switchReady;\n\n} silk_EncControlStruct;\n\n/**************************************************************************/\n/* Structure for controlling decoder operation and reading decoder status */\n/**************************************************************************/\ntypedef struct {\n    /* I:   Number of channels; 1/2                                                         */\n    opus_int32 nChannelsAPI;\n\n    /* I:   Number of channels; 1/2                                                         */\n    opus_int32 nChannelsInternal;\n\n    /* I:   Output signal sampling rate in Hertz; 8000/12000/16000/24000/32000/44100/48000  */\n    opus_int32 API_sampleRate;\n\n    /* I:   Internal sampling rate used, in Hertz; 8000/12000/16000                         */\n    opus_int32 internalSampleRate;\n\n    /* I:   Number of samples per packet in milliseconds; 10/20/40/60                       */\n    opus_int payloadSize_ms;\n\n    /* O:   Pitch lag of previous frame (0 if unvoiced), measured in samples at 48 kHz      */\n    opus_int prevPitchLag;\n} silk_DecControlStruct;\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/control_SNR.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"tuning_parameters.h\"\n\n/* Control SNR of redidual quantizer */\nopus_int silk_control_SNR(\n    silk_encoder_state          *psEncC,                        /* I/O  Pointer to Silk encoder state               */\n    opus_int32                  TargetRate_bps                  /* I    Target max bitrate (bps)                    */\n)\n{\n    opus_int k, ret = SILK_NO_ERROR;\n    opus_int32 frac_Q6;\n    const opus_int32 *rateTable;\n\n    /* Set bitrate/coding quality */\n    TargetRate_bps = silk_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS );\n    if( TargetRate_bps != psEncC->TargetRate_bps ) {\n        psEncC->TargetRate_bps = TargetRate_bps;\n\n        /* If new TargetRate_bps, translate to SNR_dB value */\n        if( psEncC->fs_kHz == 8 ) {\n            rateTable = silk_TargetRate_table_NB;\n        } else if( psEncC->fs_kHz == 12 ) {\n            rateTable = silk_TargetRate_table_MB;\n        } else {\n            rateTable = silk_TargetRate_table_WB;\n        }\n\n        /* Reduce bitrate for 10 ms modes in these calculations */\n        if( psEncC->nb_subfr == 2 ) {\n            TargetRate_bps -= REDUCE_BITRATE_10_MS_BPS;\n        }\n\n        /* Find bitrate interval in table and interpolate */\n        for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) {\n            if( TargetRate_bps <= rateTable[ k ] ) {\n                frac_Q6 = silk_DIV32( silk_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ),\n                                                 rateTable[ k ] - rateTable[ k - 1 ] );\n                psEncC->SNR_dB_Q7 = silk_LSHIFT( silk_SNR_table_Q1[ k - 1 ], 6 ) + silk_MUL( frac_Q6, silk_SNR_table_Q1[ k ] - silk_SNR_table_Q1[ k - 1 ] );\n                break;\n            }\n        }\n    }\n\n    return ret;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/control_audio_bandwidth.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"tuning_parameters.h\"\n\n/* Control internal sampling rate */\nopus_int silk_control_audio_bandwidth(\n    silk_encoder_state          *psEncC,                        /* I/O  Pointer to Silk encoder state               */\n    silk_EncControlStruct       *encControl                     /* I    Control structure                           */\n)\n{\n    opus_int   fs_kHz;\n    opus_int32 fs_Hz;\n\n    fs_kHz = psEncC->fs_kHz;\n    fs_Hz = silk_SMULBB( fs_kHz, 1000 );\n    if( fs_Hz == 0 ) {\n        /* Encoder has just been initialized */\n        fs_Hz  = silk_min( psEncC->desiredInternal_fs_Hz, psEncC->API_fs_Hz );\n        fs_kHz = silk_DIV32_16( fs_Hz, 1000 );\n    } else if( fs_Hz > psEncC->API_fs_Hz || fs_Hz > psEncC->maxInternal_fs_Hz || fs_Hz < psEncC->minInternal_fs_Hz ) {\n        /* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */\n        fs_Hz  = psEncC->API_fs_Hz;\n        fs_Hz  = silk_min( fs_Hz, psEncC->maxInternal_fs_Hz );\n        fs_Hz  = silk_max( fs_Hz, psEncC->minInternal_fs_Hz );\n        fs_kHz = silk_DIV32_16( fs_Hz, 1000 );\n    } else {\n        /* State machine for the internal sampling rate switching */\n        if( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES ) {\n            /* Stop transition phase */\n            psEncC->sLP.mode = 0;\n        }\n        if( psEncC->allow_bandwidth_switch || encControl->opusCanSwitch ) {\n            /* Check if we should switch down */\n            if( silk_SMULBB( psEncC->fs_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz )\n            {\n                /* Switch down */\n                if( psEncC->sLP.mode == 0 ) {\n                    /* New transition */\n                    psEncC->sLP.transition_frame_no = TRANSITION_FRAMES;\n\n                    /* Reset transition filter state */\n                    silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) );\n                }\n                if( encControl->opusCanSwitch ) {\n                    /* Stop transition phase */\n                    psEncC->sLP.mode = 0;\n\n                    /* Switch to a lower sample frequency */\n                    fs_kHz = psEncC->fs_kHz == 16 ? 12 : 8;\n                } else {\n                   if( psEncC->sLP.transition_frame_no <= 0 ) {\n                       encControl->switchReady = 1;\n                       /* Make room for redundancy */\n                       encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );\n                   } else {\n                       /* Direction: down (at double speed) */\n                       psEncC->sLP.mode = -2;\n                   }\n                }\n            }\n            else\n            /* Check if we should switch up */\n            if( silk_SMULBB( psEncC->fs_kHz, 1000 ) < psEncC->desiredInternal_fs_Hz )\n            {\n                /* Switch up */\n                if( encControl->opusCanSwitch ) {\n                    /* Switch to a higher sample frequency */\n                    fs_kHz = psEncC->fs_kHz == 8 ? 12 : 16;\n\n                    /* New transition */\n                    psEncC->sLP.transition_frame_no = 0;\n\n                    /* Reset transition filter state */\n                    silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) );\n\n                    /* Direction: up */\n                    psEncC->sLP.mode = 1;\n                } else {\n                   if( psEncC->sLP.mode == 0 ) {\n                       encControl->switchReady = 1;\n                       /* Make room for redundancy */\n                       encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );\n                   } else {\n                       /* Direction: up */\n                       psEncC->sLP.mode = 1;\n                   }\n                }\n            } else {\n               if (psEncC->sLP.mode<0)\n                  psEncC->sLP.mode = 1;\n            }\n        }\n    }\n\n    return fs_kHz;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/control_codec.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#ifdef FIXED_POINT\n#include \"main_FIX.h\"\n#define silk_encoder_state_Fxx      silk_encoder_state_FIX\n#else\n#include \"main_FLP.h\"\n#define silk_encoder_state_Fxx      silk_encoder_state_FLP\n#endif\n#include \"stack_alloc.h\"\n#include \"tuning_parameters.h\"\n#include \"pitch_est_defines.h\"\n\nstatic opus_int silk_setup_resamplers(\n    silk_encoder_state_Fxx          *psEnc,             /* I/O                      */\n    opus_int                        fs_kHz              /* I                        */\n);\n\nstatic opus_int silk_setup_fs(\n    silk_encoder_state_Fxx          *psEnc,             /* I/O                      */\n    opus_int                        fs_kHz,             /* I                        */\n    opus_int                        PacketSize_ms       /* I                        */\n);\n\nstatic opus_int silk_setup_complexity(\n    silk_encoder_state              *psEncC,            /* I/O                      */\n    opus_int                        Complexity          /* I                        */\n);\n\nstatic OPUS_INLINE opus_int silk_setup_LBRR(\n    silk_encoder_state              *psEncC,            /* I/O                      */\n    const opus_int32                TargetRate_bps      /* I                        */\n);\n\n\n/* Control encoder */\nopus_int silk_control_encoder(\n    silk_encoder_state_Fxx          *psEnc,                                 /* I/O  Pointer to Silk encoder state                                               */\n    silk_EncControlStruct           *encControl,                            /* I    Control structure                                                           */\n    const opus_int32                TargetRate_bps,                         /* I    Target max bitrate (bps)                                                    */\n    const opus_int                  allow_bw_switch,                        /* I    Flag to allow switching audio bandwidth                                     */\n    const opus_int                  channelNb,                              /* I    Channel number                                                              */\n    const opus_int                  force_fs_kHz\n)\n{\n    opus_int   fs_kHz, ret = 0;\n\n    psEnc->sCmn.useDTX                 = encControl->useDTX;\n    psEnc->sCmn.useCBR                 = encControl->useCBR;\n    psEnc->sCmn.API_fs_Hz              = encControl->API_sampleRate;\n    psEnc->sCmn.maxInternal_fs_Hz      = encControl->maxInternalSampleRate;\n    psEnc->sCmn.minInternal_fs_Hz      = encControl->minInternalSampleRate;\n    psEnc->sCmn.desiredInternal_fs_Hz  = encControl->desiredInternalSampleRate;\n    psEnc->sCmn.useInBandFEC           = encControl->useInBandFEC;\n    psEnc->sCmn.nChannelsAPI           = encControl->nChannelsAPI;\n    psEnc->sCmn.nChannelsInternal      = encControl->nChannelsInternal;\n    psEnc->sCmn.allow_bandwidth_switch = allow_bw_switch;\n    psEnc->sCmn.channelNb              = channelNb;\n\n    if( psEnc->sCmn.controlled_since_last_payload != 0 && psEnc->sCmn.prefillFlag == 0 ) {\n        if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) {\n            /* Change in API sampling rate in the middle of encoding a packet */\n            ret += silk_setup_resamplers( psEnc, psEnc->sCmn.fs_kHz );\n        }\n        return ret;\n    }\n\n    /* Beyond this point we know that there are no previously coded frames in the payload buffer */\n\n    /********************************************/\n    /* Determine internal sampling rate         */\n    /********************************************/\n    fs_kHz = silk_control_audio_bandwidth( &psEnc->sCmn, encControl );\n    if( force_fs_kHz ) {\n       fs_kHz = force_fs_kHz;\n    }\n    /********************************************/\n    /* Prepare resampler and buffered data      */\n    /********************************************/\n    ret += silk_setup_resamplers( psEnc, fs_kHz );\n\n    /********************************************/\n    /* Set internal sampling frequency          */\n    /********************************************/\n    ret += silk_setup_fs( psEnc, fs_kHz, encControl->payloadSize_ms );\n\n    /********************************************/\n    /* Set encoding complexity                  */\n    /********************************************/\n    ret += silk_setup_complexity( &psEnc->sCmn, encControl->complexity  );\n\n    /********************************************/\n    /* Set packet loss rate measured by farend  */\n    /********************************************/\n    psEnc->sCmn.PacketLoss_perc = encControl->packetLossPercentage;\n\n    /********************************************/\n    /* Set LBRR usage                           */\n    /********************************************/\n    ret += silk_setup_LBRR( &psEnc->sCmn, TargetRate_bps );\n\n    psEnc->sCmn.controlled_since_last_payload = 1;\n\n    return ret;\n}\n\nstatic opus_int silk_setup_resamplers(\n    silk_encoder_state_Fxx          *psEnc,             /* I/O                      */\n    opus_int                         fs_kHz              /* I                        */\n)\n{\n    opus_int   ret = SILK_NO_ERROR;\n    SAVE_STACK;\n\n    if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz )\n    {\n        if( psEnc->sCmn.fs_kHz == 0 ) {\n            /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */\n            ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000, 1 );\n        } else {\n            VARDECL( opus_int16, x_buf_API_fs_Hz );\n            VARDECL( silk_resampler_state_struct, temp_resampler_state );\n#ifdef FIXED_POINT\n            opus_int16 *x_bufFIX = psEnc->x_buf;\n#else\n            VARDECL( opus_int16, x_bufFIX );\n            opus_int32 new_buf_samples;\n#endif\n            opus_int32 api_buf_samples;\n            opus_int32 old_buf_samples;\n            opus_int32 buf_length_ms;\n\n            buf_length_ms = silk_LSHIFT( psEnc->sCmn.nb_subfr * 5, 1 ) + LA_SHAPE_MS;\n            old_buf_samples = buf_length_ms * psEnc->sCmn.fs_kHz;\n\n#ifndef FIXED_POINT\n            new_buf_samples = buf_length_ms * fs_kHz;\n            ALLOC( x_bufFIX, silk_max( old_buf_samples, new_buf_samples ),\n                   opus_int16 );\n            silk_float2short_array( x_bufFIX, psEnc->x_buf, old_buf_samples );\n#endif\n\n            /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */\n            ALLOC( temp_resampler_state, 1, silk_resampler_state_struct );\n            ret += silk_resampler_init( temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 );\n\n            /* Calculate number of samples to temporarily upsample */\n            api_buf_samples = buf_length_ms * silk_DIV32_16( psEnc->sCmn.API_fs_Hz, 1000 );\n\n            /* Temporary resampling of x_buf data to API_fs_Hz */\n            ALLOC( x_buf_API_fs_Hz, api_buf_samples, opus_int16 );\n            ret += silk_resampler( temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, old_buf_samples );\n\n            /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */\n            ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, silk_SMULBB( fs_kHz, 1000 ), 1 );\n\n            /* Correct resampler state by resampling buffered data from API_fs_Hz to fs_kHz */\n            ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, api_buf_samples );\n\n#ifndef FIXED_POINT\n            silk_short2float_array( psEnc->x_buf, x_bufFIX, new_buf_samples);\n#endif\n        }\n    }\n\n    psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz;\n\n    RESTORE_STACK;\n    return ret;\n}\n\nstatic opus_int silk_setup_fs(\n    silk_encoder_state_Fxx          *psEnc,             /* I/O                      */\n    opus_int                        fs_kHz,             /* I                        */\n    opus_int                        PacketSize_ms       /* I                        */\n)\n{\n    opus_int ret = SILK_NO_ERROR;\n\n    /* Set packet size */\n    if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) {\n        if( ( PacketSize_ms !=  10 ) &&\n            ( PacketSize_ms !=  20 ) &&\n            ( PacketSize_ms !=  40 ) &&\n            ( PacketSize_ms !=  60 ) ) {\n            ret = SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;\n        }\n        if( PacketSize_ms <= 10 ) {\n            psEnc->sCmn.nFramesPerPacket = 1;\n            psEnc->sCmn.nb_subfr = PacketSize_ms == 10 ? 2 : 1;\n            psEnc->sCmn.frame_length = silk_SMULBB( PacketSize_ms, fs_kHz );\n            psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );\n            if( psEnc->sCmn.fs_kHz == 8 ) {\n                psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF;\n            } else {\n                psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF;\n            }\n        } else {\n            psEnc->sCmn.nFramesPerPacket = silk_DIV32_16( PacketSize_ms, MAX_FRAME_LENGTH_MS );\n            psEnc->sCmn.nb_subfr = MAX_NB_SUBFR;\n            psEnc->sCmn.frame_length = silk_SMULBB( 20, fs_kHz );\n            psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );\n            if( psEnc->sCmn.fs_kHz == 8 ) {\n                psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF;\n            } else {\n                psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF;\n            }\n        }\n        psEnc->sCmn.PacketSize_ms  = PacketSize_ms;\n        psEnc->sCmn.TargetRate_bps = 0;         /* trigger new SNR computation */\n    }\n\n    /* Set internal sampling frequency */\n    silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );\n    silk_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 );\n    if( psEnc->sCmn.fs_kHz != fs_kHz ) {\n        /* reset part of the state */\n        silk_memset( &psEnc->sShape,               0, sizeof( psEnc->sShape ) );\n        silk_memset( &psEnc->sPrefilt,             0, sizeof( psEnc->sPrefilt ) );\n        silk_memset( &psEnc->sCmn.sNSQ,            0, sizeof( psEnc->sCmn.sNSQ ) );\n        silk_memset( psEnc->sCmn.prev_NLSFq_Q15,   0, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );\n        silk_memset( &psEnc->sCmn.sLP.In_LP_State, 0, sizeof( psEnc->sCmn.sLP.In_LP_State ) );\n        psEnc->sCmn.inputBufIx                  = 0;\n        psEnc->sCmn.nFramesEncoded              = 0;\n        psEnc->sCmn.TargetRate_bps              = 0;     /* trigger new SNR computation */\n\n        /* Initialize non-zero parameters */\n        psEnc->sCmn.prevLag                     = 100;\n        psEnc->sCmn.first_frame_after_reset     = 1;\n        psEnc->sPrefilt.lagPrev                 = 100;\n        psEnc->sShape.LastGainIndex             = 10;\n        psEnc->sCmn.sNSQ.lagPrev                = 100;\n        psEnc->sCmn.sNSQ.prev_gain_Q16          = 65536;\n        psEnc->sCmn.prevSignalType              = TYPE_NO_VOICE_ACTIVITY;\n\n        psEnc->sCmn.fs_kHz = fs_kHz;\n        if( psEnc->sCmn.fs_kHz == 8 ) {\n            if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {\n                psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF;\n            } else {\n                psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF;\n            }\n        } else {\n            if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {\n                psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF;\n            } else {\n                psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF;\n            }\n        }\n        if( psEnc->sCmn.fs_kHz == 8 || psEnc->sCmn.fs_kHz == 12 ) {\n            psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER;\n            psEnc->sCmn.psNLSF_CB  = &silk_NLSF_CB_NB_MB;\n        } else {\n            psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER;\n            psEnc->sCmn.psNLSF_CB  = &silk_NLSF_CB_WB;\n        }\n        psEnc->sCmn.subfr_length   = SUB_FRAME_LENGTH_MS * fs_kHz;\n        psEnc->sCmn.frame_length   = silk_SMULBB( psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr );\n        psEnc->sCmn.ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz );\n        psEnc->sCmn.la_pitch       = silk_SMULBB( LA_PITCH_MS, fs_kHz );\n        psEnc->sCmn.max_pitch_lag  = silk_SMULBB( 18, fs_kHz );\n        if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {\n            psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );\n        } else {\n            psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );\n        }\n        if( psEnc->sCmn.fs_kHz == 16 ) {\n            psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_WB, 9 );\n            psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform8_iCDF;\n        } else if( psEnc->sCmn.fs_kHz == 12 ) {\n            psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_MB, 9 );\n            psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform6_iCDF;\n        } else {\n            psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_NB, 9 );\n            psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform4_iCDF;\n        }\n    }\n\n    /* Check that settings are valid */\n    silk_assert( ( psEnc->sCmn.subfr_length * psEnc->sCmn.nb_subfr ) == psEnc->sCmn.frame_length );\n\n    return ret;\n}\n\nstatic opus_int silk_setup_complexity(\n    silk_encoder_state              *psEncC,            /* I/O                      */\n    opus_int                        Complexity          /* I                        */\n)\n{\n    opus_int ret = 0;\n\n    /* Set encoding complexity */\n    silk_assert( Complexity >= 0 && Complexity <= 10 );\n    if( Complexity < 2 ) {\n        psEncC->pitchEstimationComplexity       = SILK_PE_MIN_COMPLEX;\n        psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.8, 16 );\n        psEncC->pitchEstimationLPCOrder         = 6;\n        psEncC->shapingLPCOrder                 = 8;\n        psEncC->la_shape                        = 3 * psEncC->fs_kHz;\n        psEncC->nStatesDelayedDecision          = 1;\n        psEncC->useInterpolatedNLSFs            = 0;\n        psEncC->LTPQuantLowComplexity           = 1;\n        psEncC->NLSF_MSVQ_Survivors             = 2;\n        psEncC->warping_Q16                     = 0;\n    } else if( Complexity < 4 ) {\n        psEncC->pitchEstimationComplexity       = SILK_PE_MID_COMPLEX;\n        psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.76, 16 );\n        psEncC->pitchEstimationLPCOrder         = 8;\n        psEncC->shapingLPCOrder                 = 10;\n        psEncC->la_shape                        = 5 * psEncC->fs_kHz;\n        psEncC->nStatesDelayedDecision          = 1;\n        psEncC->useInterpolatedNLSFs            = 0;\n        psEncC->LTPQuantLowComplexity           = 0;\n        psEncC->NLSF_MSVQ_Survivors             = 4;\n        psEncC->warping_Q16                     = 0;\n    } else if( Complexity < 6 ) {\n        psEncC->pitchEstimationComplexity       = SILK_PE_MID_COMPLEX;\n        psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.74, 16 );\n        psEncC->pitchEstimationLPCOrder         = 10;\n        psEncC->shapingLPCOrder                 = 12;\n        psEncC->la_shape                        = 5 * psEncC->fs_kHz;\n        psEncC->nStatesDelayedDecision          = 2;\n        psEncC->useInterpolatedNLSFs            = 1;\n        psEncC->LTPQuantLowComplexity           = 0;\n        psEncC->NLSF_MSVQ_Survivors             = 8;\n        psEncC->warping_Q16                     = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );\n    } else if( Complexity < 8 ) {\n        psEncC->pitchEstimationComplexity       = SILK_PE_MID_COMPLEX;\n        psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.72, 16 );\n        psEncC->pitchEstimationLPCOrder         = 12;\n        psEncC->shapingLPCOrder                 = 14;\n        psEncC->la_shape                        = 5 * psEncC->fs_kHz;\n        psEncC->nStatesDelayedDecision          = 3;\n        psEncC->useInterpolatedNLSFs            = 1;\n        psEncC->LTPQuantLowComplexity           = 0;\n        psEncC->NLSF_MSVQ_Survivors             = 16;\n        psEncC->warping_Q16                     = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );\n    } else {\n        psEncC->pitchEstimationComplexity       = SILK_PE_MAX_COMPLEX;\n        psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.7, 16 );\n        psEncC->pitchEstimationLPCOrder         = 16;\n        psEncC->shapingLPCOrder                 = 16;\n        psEncC->la_shape                        = 5 * psEncC->fs_kHz;\n        psEncC->nStatesDelayedDecision          = MAX_DEL_DEC_STATES;\n        psEncC->useInterpolatedNLSFs            = 1;\n        psEncC->LTPQuantLowComplexity           = 0;\n        psEncC->NLSF_MSVQ_Survivors             = 32;\n        psEncC->warping_Q16                     = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );\n    }\n\n    /* Do not allow higher pitch estimation LPC order than predict LPC order */\n    psEncC->pitchEstimationLPCOrder = silk_min_int( psEncC->pitchEstimationLPCOrder, psEncC->predictLPCOrder );\n    psEncC->shapeWinLength          = SUB_FRAME_LENGTH_MS * psEncC->fs_kHz + 2 * psEncC->la_shape;\n    psEncC->Complexity              = Complexity;\n\n    silk_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER );\n    silk_assert( psEncC->shapingLPCOrder         <= MAX_SHAPE_LPC_ORDER      );\n    silk_assert( psEncC->nStatesDelayedDecision  <= MAX_DEL_DEC_STATES       );\n    silk_assert( psEncC->warping_Q16             <= 32767                    );\n    silk_assert( psEncC->la_shape                <= LA_SHAPE_MAX             );\n    silk_assert( psEncC->shapeWinLength          <= SHAPE_LPC_WIN_MAX        );\n    silk_assert( psEncC->NLSF_MSVQ_Survivors     <= NLSF_VQ_MAX_SURVIVORS    );\n\n    return ret;\n}\n\nstatic OPUS_INLINE opus_int silk_setup_LBRR(\n    silk_encoder_state          *psEncC,            /* I/O                      */\n    const opus_int32            TargetRate_bps      /* I                        */\n)\n{\n    opus_int   LBRR_in_previous_packet, ret = SILK_NO_ERROR;\n    opus_int32 LBRR_rate_thres_bps;\n\n    LBRR_in_previous_packet = psEncC->LBRR_enabled;\n    psEncC->LBRR_enabled = 0;\n    if( psEncC->useInBandFEC && psEncC->PacketLoss_perc > 0 ) {\n        if( psEncC->fs_kHz == 8 ) {\n            LBRR_rate_thres_bps = LBRR_NB_MIN_RATE_BPS;\n        } else if( psEncC->fs_kHz == 12 ) {\n            LBRR_rate_thres_bps = LBRR_MB_MIN_RATE_BPS;\n        } else {\n            LBRR_rate_thres_bps = LBRR_WB_MIN_RATE_BPS;\n        }\n        LBRR_rate_thres_bps = silk_SMULWB( silk_MUL( LBRR_rate_thres_bps, 125 - silk_min( psEncC->PacketLoss_perc, 25 ) ), SILK_FIX_CONST( 0.01, 16 ) );\n\n        if( TargetRate_bps > LBRR_rate_thres_bps ) {\n            /* Set gain increase for coding LBRR excitation */\n            if( LBRR_in_previous_packet == 0 ) {\n                /* Previous packet did not have LBRR, and was therefore coded at a higher bitrate */\n                psEncC->LBRR_GainIncreases = 7;\n            } else {\n                psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 );\n            }\n            psEncC->LBRR_enabled = 1;\n        }\n    }\n\n    return ret;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/debug.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"debug.h\"\n#include \"SigProc_FIX.h\"\n\n#if SILK_TIC_TOC\n\n#ifdef _WIN32\n\n#if (defined(_WIN32) || defined(_WINCE))\n#include <windows.h>    /* timer */\n#else   /* Linux or Mac*/\n#include <sys/time.h>\n#endif\n\nunsigned long silk_GetHighResolutionTime(void) /* O  time in usec*/\n{\n    /* Returns a time counter in microsec   */\n    /* the resolution is platform dependent */\n    /* but is typically 1.62 us resolution  */\n    LARGE_INTEGER lpPerformanceCount;\n    LARGE_INTEGER lpFrequency;\n    QueryPerformanceCounter(&lpPerformanceCount);\n    QueryPerformanceFrequency(&lpFrequency);\n    return (unsigned long)((1000000*(lpPerformanceCount.QuadPart)) / lpFrequency.QuadPart);\n}\n#else   /* Linux or Mac*/\nunsigned long GetHighResolutionTime(void) /* O  time in usec*/\n{\n    struct timeval tv;\n    gettimeofday(&tv, 0);\n    return((tv.tv_sec*1000000)+(tv.tv_usec));\n}\n#endif\n\nint           silk_Timer_nTimers = 0;\nint           silk_Timer_depth_ctr = 0;\nchar          silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN];\n#ifdef WIN32\nLARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX];\n#else\nunsigned long silk_Timer_start[silk_NUM_TIMERS_MAX];\n#endif\nunsigned int  silk_Timer_cnt[silk_NUM_TIMERS_MAX];\nopus_int64     silk_Timer_min[silk_NUM_TIMERS_MAX];\nopus_int64     silk_Timer_sum[silk_NUM_TIMERS_MAX];\nopus_int64     silk_Timer_max[silk_NUM_TIMERS_MAX];\nopus_int64     silk_Timer_depth[silk_NUM_TIMERS_MAX];\n\n#ifdef WIN32\nvoid silk_TimerSave(char *file_name)\n{\n    if( silk_Timer_nTimers > 0 )\n    {\n        int k;\n        FILE *fp;\n        LARGE_INTEGER lpFrequency;\n        LARGE_INTEGER lpPerformanceCount1, lpPerformanceCount2;\n        int del = 0x7FFFFFFF;\n        double avg, sum_avg;\n        /* estimate overhead of calling performance counters */\n        for( k = 0; k < 1000; k++ ) {\n            QueryPerformanceCounter(&lpPerformanceCount1);\n            QueryPerformanceCounter(&lpPerformanceCount2);\n            lpPerformanceCount2.QuadPart -= lpPerformanceCount1.QuadPart;\n            if( (int)lpPerformanceCount2.LowPart < del )\n                del = lpPerformanceCount2.LowPart;\n        }\n        QueryPerformanceFrequency(&lpFrequency);\n        /* print results to file */\n        sum_avg = 0.0f;\n        for( k = 0; k < silk_Timer_nTimers; k++ ) {\n            if (silk_Timer_depth[k] == 0) {\n                sum_avg += (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart * silk_Timer_cnt[k];\n            }\n        }\n        fp = fopen(file_name, \"w\");\n        fprintf(fp, \"                                min         avg     %%         max      count\\n\");\n        for( k = 0; k < silk_Timer_nTimers; k++ ) {\n            if (silk_Timer_depth[k] == 0) {\n                fprintf(fp, \"%-28s\", silk_Timer_tags[k]);\n            } else if (silk_Timer_depth[k] == 1) {\n                fprintf(fp, \" %-27s\", silk_Timer_tags[k]);\n            } else if (silk_Timer_depth[k] == 2) {\n                fprintf(fp, \"  %-26s\", silk_Timer_tags[k]);\n            } else if (silk_Timer_depth[k] == 3) {\n                fprintf(fp, \"   %-25s\", silk_Timer_tags[k]);\n            } else {\n                fprintf(fp, \"    %-24s\", silk_Timer_tags[k]);\n            }\n            avg = (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart;\n            fprintf(fp, \"%8.2f\", (1e6 * (silk_max_64(silk_Timer_min[k] - del, 0))) / lpFrequency.QuadPart);\n            fprintf(fp, \"%12.2f %6.2f\", avg, 100.0 * avg / sum_avg * silk_Timer_cnt[k]);\n            fprintf(fp, \"%12.2f\", (1e6 * (silk_max_64(silk_Timer_max[k] - del, 0))) / lpFrequency.QuadPart);\n            fprintf(fp, \"%10d\\n\", silk_Timer_cnt[k]);\n        }\n        fprintf(fp, \"                                microseconds\\n\");\n        fclose(fp);\n    }\n}\n#else\nvoid silk_TimerSave(char *file_name)\n{\n    if( silk_Timer_nTimers > 0 )\n    {\n        int k;\n        FILE *fp;\n        /* print results to file */\n        fp = fopen(file_name, \"w\");\n        fprintf(fp, \"                                min         avg         max      count\\n\");\n        for( k = 0; k < silk_Timer_nTimers; k++ )\n        {\n            if (silk_Timer_depth[k] == 0) {\n                fprintf(fp, \"%-28s\", silk_Timer_tags[k]);\n            } else if (silk_Timer_depth[k] == 1) {\n                fprintf(fp, \" %-27s\", silk_Timer_tags[k]);\n            } else if (silk_Timer_depth[k] == 2) {\n                fprintf(fp, \"  %-26s\", silk_Timer_tags[k]);\n            } else if (silk_Timer_depth[k] == 3) {\n                fprintf(fp, \"   %-25s\", silk_Timer_tags[k]);\n            } else {\n                fprintf(fp, \"    %-24s\", silk_Timer_tags[k]);\n            }\n            fprintf(fp, \"%d \", silk_Timer_min[k]);\n            fprintf(fp, \"%f \", (double)silk_Timer_sum[k] / (double)silk_Timer_cnt[k]);\n            fprintf(fp, \"%d \", silk_Timer_max[k]);\n            fprintf(fp, \"%10d\\n\", silk_Timer_cnt[k]);\n        }\n        fprintf(fp, \"                                microseconds\\n\");\n        fclose(fp);\n    }\n}\n#endif\n\n#endif /* SILK_TIC_TOC */\n\n#if SILK_DEBUG\nFILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ];\nint silk_debug_store_count = 0;\n#endif /* SILK_DEBUG */\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/debug.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_DEBUG_H\n#define SILK_DEBUG_H\n\n#include \"typedef.h\"\n#include <stdio.h>      /* file writing */\n#include <string.h>     /* strcpy, strcmp */\n\n#ifdef  __cplusplus\nextern \"C\"\n{\n#endif\n\nunsigned long GetHighResolutionTime(void); /* O  time in usec*/\n\n/* make SILK_DEBUG dependent on compiler's _DEBUG */\n#if defined _WIN32\n    #ifdef _DEBUG\n        #define SILK_DEBUG  1\n    #else\n        #define SILK_DEBUG  0\n    #endif\n\n    /* overrule the above */\n    #if 0\n    /*  #define NO_ASSERTS*/\n    #undef  SILK_DEBUG\n    #define SILK_DEBUG  1\n    #endif\n#else\n    #define SILK_DEBUG  0\n#endif\n\n/* Flag for using timers */\n#define SILK_TIC_TOC    0\n\n\n#if SILK_TIC_TOC\n\n#if (defined(_WIN32) || defined(_WINCE))\n#include <windows.h>    /* timer */\n#else   /* Linux or Mac*/\n#include <sys/time.h>\n#endif\n\n/*********************************/\n/* timer functions for profiling */\n/*********************************/\n/* example:                                                         */\n/*                                                                  */\n/* TIC(LPC)                                                         */\n/* do_LPC(in_vec, order, acoef);    // do LPC analysis              */\n/* TOC(LPC)                                                         */\n/*                                                                  */\n/* and call the following just before exiting (from main)           */\n/*                                                                  */\n/* silk_TimerSave(\"silk_TimingData.txt\");                           */\n/*                                                                  */\n/* results are now in silk_TimingData.txt                           */\n\nvoid silk_TimerSave(char *file_name);\n\n/* max number of timers (in different locations) */\n#define silk_NUM_TIMERS_MAX                  50\n/* max length of name tags in TIC(..), TOC(..) */\n#define silk_NUM_TIMERS_MAX_TAG_LEN          30\n\nextern int           silk_Timer_nTimers;\nextern int           silk_Timer_depth_ctr;\nextern char          silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN];\n#ifdef _WIN32\nextern LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX];\n#else\nextern unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX];\n#endif\nextern unsigned int  silk_Timer_cnt[silk_NUM_TIMERS_MAX];\nextern opus_int64    silk_Timer_sum[silk_NUM_TIMERS_MAX];\nextern opus_int64    silk_Timer_max[silk_NUM_TIMERS_MAX];\nextern opus_int64    silk_Timer_min[silk_NUM_TIMERS_MAX];\nextern opus_int64    silk_Timer_depth[silk_NUM_TIMERS_MAX];\n\n/* WARNING: TIC()/TOC can measure only up to 0.1 seconds at a time */\n#ifdef _WIN32\n#define TIC(TAG_NAME) {                                     \\\n    static int init = 0;                                    \\\n    static int ID = -1;                                     \\\n    if( init == 0 )                                         \\\n    {                                                       \\\n        int k;                                              \\\n        init = 1;                                           \\\n        for( k = 0; k < silk_Timer_nTimers; k++ ) {         \\\n            if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \\\n                ID = k;                                     \\\n                break;                                      \\\n            }                                               \\\n        }                                                   \\\n        if (ID == -1) {                                     \\\n            ID = silk_Timer_nTimers;                        \\\n            silk_Timer_nTimers++;                           \\\n            silk_Timer_depth[ID] = silk_Timer_depth_ctr;    \\\n            strcpy(silk_Timer_tags[ID], #TAG_NAME);         \\\n            silk_Timer_cnt[ID] = 0;                         \\\n            silk_Timer_sum[ID] = 0;                         \\\n            silk_Timer_min[ID] = 0xFFFFFFFF;                \\\n            silk_Timer_max[ID] = 0;                         \\\n        }                                                   \\\n    }                                                       \\\n    silk_Timer_depth_ctr++;                                 \\\n    QueryPerformanceCounter(&silk_Timer_start[ID]);         \\\n}\n#else\n#define TIC(TAG_NAME) {                                     \\\n    static int init = 0;                                    \\\n    static int ID = -1;                                     \\\n    if( init == 0 )                                         \\\n    {                                                       \\\n        int k;                                              \\\n        init = 1;                                           \\\n        for( k = 0; k < silk_Timer_nTimers; k++ ) {         \\\n        if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) {  \\\n                ID = k;                                     \\\n                break;                                      \\\n            }                                               \\\n        }                                                   \\\n        if (ID == -1) {                                     \\\n            ID = silk_Timer_nTimers;                        \\\n            silk_Timer_nTimers++;                           \\\n            silk_Timer_depth[ID] = silk_Timer_depth_ctr;    \\\n            strcpy(silk_Timer_tags[ID], #TAG_NAME);         \\\n            silk_Timer_cnt[ID] = 0;                         \\\n            silk_Timer_sum[ID] = 0;                         \\\n            silk_Timer_min[ID] = 0xFFFFFFFF;                \\\n            silk_Timer_max[ID] = 0;                         \\\n        }                                                   \\\n    }                                                       \\\n    silk_Timer_depth_ctr++;                                 \\\n    silk_Timer_start[ID] = GetHighResolutionTime();         \\\n}\n#endif\n\n#ifdef _WIN32\n#define TOC(TAG_NAME) {                                             \\\n    LARGE_INTEGER lpPerformanceCount;                               \\\n    static int init = 0;                                            \\\n    static int ID = 0;                                              \\\n    if( init == 0 )                                                 \\\n    {                                                               \\\n        int k;                                                      \\\n        init = 1;                                                   \\\n        for( k = 0; k < silk_Timer_nTimers; k++ ) {                 \\\n            if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) {      \\\n                ID = k;                                             \\\n                break;                                              \\\n            }                                                       \\\n        }                                                           \\\n    }                                                               \\\n    QueryPerformanceCounter(&lpPerformanceCount);                   \\\n    lpPerformanceCount.QuadPart -= silk_Timer_start[ID].QuadPart;   \\\n    if((lpPerformanceCount.QuadPart < 100000000) &&                 \\\n        (lpPerformanceCount.QuadPart >= 0)) {                       \\\n        silk_Timer_cnt[ID]++;                                       \\\n        silk_Timer_sum[ID] += lpPerformanceCount.QuadPart;          \\\n        if( lpPerformanceCount.QuadPart > silk_Timer_max[ID] )      \\\n            silk_Timer_max[ID] = lpPerformanceCount.QuadPart;       \\\n        if( lpPerformanceCount.QuadPart < silk_Timer_min[ID] )      \\\n            silk_Timer_min[ID] = lpPerformanceCount.QuadPart;       \\\n    }                                                               \\\n    silk_Timer_depth_ctr--;                                         \\\n}\n#else\n#define TOC(TAG_NAME) {                                             \\\n    unsigned long endTime;                                          \\\n    static int init = 0;                                            \\\n    static int ID = 0;                                              \\\n    if( init == 0 )                                                 \\\n    {                                                               \\\n        int k;                                                      \\\n        init = 1;                                                   \\\n        for( k = 0; k < silk_Timer_nTimers; k++ ) {                 \\\n            if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) {      \\\n                ID = k;                                             \\\n                break;                                              \\\n            }                                                       \\\n        }                                                           \\\n    }                                                               \\\n    endTime = GetHighResolutionTime();                              \\\n    endTime -= silk_Timer_start[ID];                                \\\n    if((endTime < 100000000) &&                                     \\\n        (endTime >= 0)) {                                           \\\n        silk_Timer_cnt[ID]++;                                       \\\n        silk_Timer_sum[ID] += endTime;                              \\\n        if( endTime > silk_Timer_max[ID] )                          \\\n            silk_Timer_max[ID] = endTime;                           \\\n        if( endTime < silk_Timer_min[ID] )                          \\\n            silk_Timer_min[ID] = endTime;                           \\\n    }                                                               \\\n        silk_Timer_depth_ctr--;                                     \\\n}\n#endif\n\n#else /* SILK_TIC_TOC */\n\n/* define macros as empty strings */\n#define TIC(TAG_NAME)\n#define TOC(TAG_NAME)\n#define silk_TimerSave(FILE_NAME)\n\n#endif /* SILK_TIC_TOC */\n\n\n#if SILK_DEBUG\n/************************************/\n/* write data to file for debugging */\n/************************************/\n/* Example: DEBUG_STORE_DATA(testfile.pcm, &RIN[0], 160*sizeof(opus_int16)); */\n\n#define silk_NUM_STORES_MAX                                  100\nextern FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ];\nextern int silk_debug_store_count;\n\n/* Faster way of storing the data */\n#define DEBUG_STORE_DATA( FILE_NAME, DATA_PTR, N_BYTES ) {          \\\n    static opus_int init = 0, cnt = 0;                              \\\n    static FILE **fp;                                               \\\n    if (init == 0) {                                                \\\n        init = 1;                                                   \\\n        cnt = silk_debug_store_count++;                             \\\n        silk_debug_store_fp[ cnt ] = fopen(#FILE_NAME, \"wb\");       \\\n    }                                                               \\\n    fwrite((DATA_PTR), (N_BYTES), 1, silk_debug_store_fp[ cnt ]);   \\\n}\n\n/* Call this at the end of main() */\n#define SILK_DEBUG_STORE_CLOSE_FILES {                              \\\n    opus_int i;                                                     \\\n    for( i = 0; i < silk_debug_store_count; i++ ) {                 \\\n        fclose( silk_debug_store_fp[ i ] );                         \\\n    }                                                               \\\n}\n\n#else /* SILK_DEBUG */\n\n/* define macros as empty strings */\n#define DEBUG_STORE_DATA(FILE_NAME, DATA_PTR, N_BYTES)\n#define SILK_DEBUG_STORE_CLOSE_FILES\n\n#endif /* SILK_DEBUG */\n\n#ifdef  __cplusplus\n}\n#endif\n\n#endif /* SILK_DEBUG_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/dec_API.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#include \"API.h\"\n#include \"main.h\"\n#include \"stack_alloc.h\"\n#include \"os_support.h\"\n\n/************************/\n/* Decoder Super Struct */\n/************************/\ntypedef struct {\n    silk_decoder_state          channel_state[ DECODER_NUM_CHANNELS ];\n    stereo_dec_state                sStereo;\n    opus_int                         nChannelsAPI;\n    opus_int                         nChannelsInternal;\n    opus_int                         prev_decode_only_middle;\n} silk_decoder;\n\n/*********************/\n/* Decoder functions */\n/*********************/\n\nopus_int silk_Get_Decoder_Size(                         /* O    Returns error code                              */\n    opus_int                        *decSizeBytes       /* O    Number of bytes in SILK decoder state           */\n)\n{\n    opus_int ret = SILK_NO_ERROR;\n\n    *decSizeBytes = sizeof( silk_decoder );\n\n    return ret;\n}\n\n/* Reset decoder state */\nopus_int silk_InitDecoder(                              /* O    Returns error code                              */\n    void                            *decState           /* I/O  State                                           */\n)\n{\n    opus_int n, ret = SILK_NO_ERROR;\n    silk_decoder_state *channel_state = ((silk_decoder *)decState)->channel_state;\n\n    for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) {\n        ret  = silk_init_decoder( &channel_state[ n ] );\n    }\n    silk_memset(&((silk_decoder *)decState)->sStereo, 0, sizeof(((silk_decoder *)decState)->sStereo));\n    /* Not strictly needed, but it's cleaner that way */\n    ((silk_decoder *)decState)->prev_decode_only_middle = 0;\n\n    return ret;\n}\n\n/* Decode a frame */\nopus_int silk_Decode(                                   /* O    Returns error code                              */\n    void*                           decState,           /* I/O  State                                           */\n    silk_DecControlStruct*          decControl,         /* I/O  Control Structure                               */\n    opus_int                        lostFlag,           /* I    0: no loss, 1 loss, 2 decode fec                */\n    opus_int                        newPacketFlag,      /* I    Indicates first decoder call for this packet    */\n    ec_dec                          *psRangeDec,        /* I/O  Compressor data structure                       */\n    opus_int16                      *samplesOut,        /* O    Decoded output speech vector                    */\n    opus_int32                      *nSamplesOut,       /* O    Number of samples decoded                       */\n    int                             arch                /* I    Run-time architecture                           */\n)\n{\n    opus_int   i, n, decode_only_middle = 0, ret = SILK_NO_ERROR;\n    opus_int32 nSamplesOutDec, LBRR_symbol;\n    opus_int16 *samplesOut1_tmp[ 2 ];\n    VARDECL( opus_int16, samplesOut1_tmp_storage1 );\n    VARDECL( opus_int16, samplesOut1_tmp_storage2 );\n    VARDECL( opus_int16, samplesOut2_tmp );\n    opus_int32 MS_pred_Q13[ 2 ] = { 0 };\n    opus_int16 *resample_out_ptr;\n    silk_decoder *psDec = ( silk_decoder * )decState;\n    silk_decoder_state *channel_state = psDec->channel_state;\n    opus_int has_side;\n    opus_int stereo_to_mono;\n    int delay_stack_alloc;\n    SAVE_STACK;\n\n    silk_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 );\n\n    /**********************************/\n    /* Test if first frame in payload */\n    /**********************************/\n    if( newPacketFlag ) {\n        for( n = 0; n < decControl->nChannelsInternal; n++ ) {\n            channel_state[ n ].nFramesDecoded = 0;  /* Used to count frames in packet */\n        }\n    }\n\n    /* If Mono -> Stereo transition in bitstream: init state of second channel */\n    if( decControl->nChannelsInternal > psDec->nChannelsInternal ) {\n        ret += silk_init_decoder( &channel_state[ 1 ] );\n    }\n\n    stereo_to_mono = decControl->nChannelsInternal == 1 && psDec->nChannelsInternal == 2 &&\n                     ( decControl->internalSampleRate == 1000*channel_state[ 0 ].fs_kHz );\n\n    if( channel_state[ 0 ].nFramesDecoded == 0 ) {\n        for( n = 0; n < decControl->nChannelsInternal; n++ ) {\n            opus_int fs_kHz_dec;\n            if( decControl->payloadSize_ms == 0 ) {\n                /* Assuming packet loss, use 10 ms */\n                channel_state[ n ].nFramesPerPacket = 1;\n                channel_state[ n ].nb_subfr = 2;\n            } else if( decControl->payloadSize_ms == 10 ) {\n                channel_state[ n ].nFramesPerPacket = 1;\n                channel_state[ n ].nb_subfr = 2;\n            } else if( decControl->payloadSize_ms == 20 ) {\n                channel_state[ n ].nFramesPerPacket = 1;\n                channel_state[ n ].nb_subfr = 4;\n            } else if( decControl->payloadSize_ms == 40 ) {\n                channel_state[ n ].nFramesPerPacket = 2;\n                channel_state[ n ].nb_subfr = 4;\n            } else if( decControl->payloadSize_ms == 60 ) {\n                channel_state[ n ].nFramesPerPacket = 3;\n                channel_state[ n ].nb_subfr = 4;\n            } else {\n                silk_assert( 0 );\n                RESTORE_STACK;\n                return SILK_DEC_INVALID_FRAME_SIZE;\n            }\n            fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1;\n            if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) {\n                silk_assert( 0 );\n                RESTORE_STACK;\n                return SILK_DEC_INVALID_SAMPLING_FREQUENCY;\n            }\n            ret += silk_decoder_set_fs( &channel_state[ n ], fs_kHz_dec, decControl->API_sampleRate );\n        }\n    }\n\n    if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 && ( psDec->nChannelsAPI == 1 || psDec->nChannelsInternal == 1 ) ) {\n        silk_memset( psDec->sStereo.pred_prev_Q13, 0, sizeof( psDec->sStereo.pred_prev_Q13 ) );\n        silk_memset( psDec->sStereo.sSide, 0, sizeof( psDec->sStereo.sSide ) );\n        silk_memcpy( &channel_state[ 1 ].resampler_state, &channel_state[ 0 ].resampler_state, sizeof( silk_resampler_state_struct ) );\n    }\n    psDec->nChannelsAPI      = decControl->nChannelsAPI;\n    psDec->nChannelsInternal = decControl->nChannelsInternal;\n\n    if( decControl->API_sampleRate > (opus_int32)MAX_API_FS_KHZ * 1000 || decControl->API_sampleRate < 8000 ) {\n        ret = SILK_DEC_INVALID_SAMPLING_FREQUENCY;\n        RESTORE_STACK;\n        return( ret );\n    }\n\n    if( lostFlag != FLAG_PACKET_LOST && channel_state[ 0 ].nFramesDecoded == 0 ) {\n        /* First decoder call for this payload */\n        /* Decode VAD flags and LBRR flag */\n        for( n = 0; n < decControl->nChannelsInternal; n++ ) {\n            for( i = 0; i < channel_state[ n ].nFramesPerPacket; i++ ) {\n                channel_state[ n ].VAD_flags[ i ] = ec_dec_bit_logp(psRangeDec, 1);\n            }\n            channel_state[ n ].LBRR_flag = ec_dec_bit_logp(psRangeDec, 1);\n        }\n        /* Decode LBRR flags */\n        for( n = 0; n < decControl->nChannelsInternal; n++ ) {\n            silk_memset( channel_state[ n ].LBRR_flags, 0, sizeof( channel_state[ n ].LBRR_flags ) );\n            if( channel_state[ n ].LBRR_flag ) {\n                if( channel_state[ n ].nFramesPerPacket == 1 ) {\n                    channel_state[ n ].LBRR_flags[ 0 ] = 1;\n                } else {\n                    LBRR_symbol = ec_dec_icdf( psRangeDec, silk_LBRR_flags_iCDF_ptr[ channel_state[ n ].nFramesPerPacket - 2 ], 8 ) + 1;\n                    for( i = 0; i < channel_state[ n ].nFramesPerPacket; i++ ) {\n                        channel_state[ n ].LBRR_flags[ i ] = silk_RSHIFT( LBRR_symbol, i ) & 1;\n                    }\n                }\n            }\n        }\n\n        if( lostFlag == FLAG_DECODE_NORMAL ) {\n            /* Regular decoding: skip all LBRR data */\n            for( i = 0; i < channel_state[ 0 ].nFramesPerPacket; i++ ) {\n                for( n = 0; n < decControl->nChannelsInternal; n++ ) {\n                    if( channel_state[ n ].LBRR_flags[ i ] ) {\n                        opus_int16 pulses[ MAX_FRAME_LENGTH ];\n                        opus_int condCoding;\n\n                        if( decControl->nChannelsInternal == 2 && n == 0 ) {\n                            silk_stereo_decode_pred( psRangeDec, MS_pred_Q13 );\n                            if( channel_state[ 1 ].LBRR_flags[ i ] == 0 ) {\n                                silk_stereo_decode_mid_only( psRangeDec, &decode_only_middle );\n                            }\n                        }\n                        /* Use conditional coding if previous frame available */\n                        if( i > 0 && channel_state[ n ].LBRR_flags[ i - 1 ] ) {\n                            condCoding = CODE_CONDITIONALLY;\n                        } else {\n                            condCoding = CODE_INDEPENDENTLY;\n                        }\n                        silk_decode_indices( &channel_state[ n ], psRangeDec, i, 1, condCoding );\n                        silk_decode_pulses( psRangeDec, pulses, channel_state[ n ].indices.signalType,\n                            channel_state[ n ].indices.quantOffsetType, channel_state[ n ].frame_length );\n                    }\n                }\n            }\n        }\n    }\n\n    /* Get MS predictor index */\n    if( decControl->nChannelsInternal == 2 ) {\n        if(   lostFlag == FLAG_DECODE_NORMAL ||\n            ( lostFlag == FLAG_DECODE_LBRR && channel_state[ 0 ].LBRR_flags[ channel_state[ 0 ].nFramesDecoded ] == 1 ) )\n        {\n            silk_stereo_decode_pred( psRangeDec, MS_pred_Q13 );\n            /* For LBRR data, decode mid-only flag only if side-channel's LBRR flag is false */\n            if( ( lostFlag == FLAG_DECODE_NORMAL && channel_state[ 1 ].VAD_flags[ channel_state[ 0 ].nFramesDecoded ] == 0 ) ||\n                ( lostFlag == FLAG_DECODE_LBRR && channel_state[ 1 ].LBRR_flags[ channel_state[ 0 ].nFramesDecoded ] == 0 ) )\n            {\n                silk_stereo_decode_mid_only( psRangeDec, &decode_only_middle );\n            } else {\n                decode_only_middle = 0;\n            }\n        } else {\n            for( n = 0; n < 2; n++ ) {\n                MS_pred_Q13[ n ] = psDec->sStereo.pred_prev_Q13[ n ];\n            }\n        }\n    }\n\n    /* Reset side channel decoder prediction memory for first frame with side coding */\n    if( decControl->nChannelsInternal == 2 && decode_only_middle == 0 && psDec->prev_decode_only_middle == 1 ) {\n        silk_memset( psDec->channel_state[ 1 ].outBuf, 0, sizeof(psDec->channel_state[ 1 ].outBuf) );\n        silk_memset( psDec->channel_state[ 1 ].sLPC_Q14_buf, 0, sizeof(psDec->channel_state[ 1 ].sLPC_Q14_buf) );\n        psDec->channel_state[ 1 ].lagPrev        = 100;\n        psDec->channel_state[ 1 ].LastGainIndex  = 10;\n        psDec->channel_state[ 1 ].prevSignalType = TYPE_NO_VOICE_ACTIVITY;\n        psDec->channel_state[ 1 ].first_frame_after_reset = 1;\n    }\n\n    /* Check if the temp buffer fits into the output PCM buffer. If it fits,\n       we can delay allocating the temp buffer until after the SILK peak stack\n       usage. We need to use a < and not a <= because of the two extra samples. */\n    delay_stack_alloc = decControl->internalSampleRate*decControl->nChannelsInternal\n          < decControl->API_sampleRate*decControl->nChannelsAPI;\n    ALLOC( samplesOut1_tmp_storage1, delay_stack_alloc ? ALLOC_NONE\n           : decControl->nChannelsInternal*(channel_state[ 0 ].frame_length + 2 ),\n           opus_int16 );\n    if ( delay_stack_alloc )\n    {\n       samplesOut1_tmp[ 0 ] = samplesOut;\n       samplesOut1_tmp[ 1 ] = samplesOut + channel_state[ 0 ].frame_length + 2;\n    } else {\n       samplesOut1_tmp[ 0 ] = samplesOut1_tmp_storage1;\n       samplesOut1_tmp[ 1 ] = samplesOut1_tmp_storage1 + channel_state[ 0 ].frame_length + 2;\n    }\n\n    if( lostFlag == FLAG_DECODE_NORMAL ) {\n        has_side = !decode_only_middle;\n    } else {\n        has_side = !psDec->prev_decode_only_middle\n              || (decControl->nChannelsInternal == 2 && lostFlag == FLAG_DECODE_LBRR && channel_state[1].LBRR_flags[ channel_state[1].nFramesDecoded ] == 1 );\n    }\n    /* Call decoder for one frame */\n    for( n = 0; n < decControl->nChannelsInternal; n++ ) {\n        if( n == 0 || has_side ) {\n            opus_int FrameIndex;\n            opus_int condCoding;\n\n            FrameIndex = channel_state[ 0 ].nFramesDecoded - n;\n            /* Use independent coding if no previous frame available */\n            if( FrameIndex <= 0 ) {\n                condCoding = CODE_INDEPENDENTLY;\n            } else if( lostFlag == FLAG_DECODE_LBRR ) {\n                condCoding = channel_state[ n ].LBRR_flags[ FrameIndex - 1 ] ? CODE_CONDITIONALLY : CODE_INDEPENDENTLY;\n            } else if( n > 0 && psDec->prev_decode_only_middle ) {\n                /* If we skipped a side frame in this packet, we don't\n                   need LTP scaling; the LTP state is well-defined. */\n                condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING;\n            } else {\n                condCoding = CODE_CONDITIONALLY;\n            }\n            ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding, arch);\n        } else {\n            silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) );\n        }\n        channel_state[ n ].nFramesDecoded++;\n    }\n\n    if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 ) {\n        /* Convert Mid/Side to Left/Right */\n        silk_stereo_MS_to_LR( &psDec->sStereo, samplesOut1_tmp[ 0 ], samplesOut1_tmp[ 1 ], MS_pred_Q13, channel_state[ 0 ].fs_kHz, nSamplesOutDec );\n    } else {\n        /* Buffering */\n        silk_memcpy( samplesOut1_tmp[ 0 ], psDec->sStereo.sMid, 2 * sizeof( opus_int16 ) );\n        silk_memcpy( psDec->sStereo.sMid, &samplesOut1_tmp[ 0 ][ nSamplesOutDec ], 2 * sizeof( opus_int16 ) );\n    }\n\n    /* Number of output samples */\n    *nSamplesOut = silk_DIV32( nSamplesOutDec * decControl->API_sampleRate, silk_SMULBB( channel_state[ 0 ].fs_kHz, 1000 ) );\n\n    /* Set up pointers to temp buffers */\n    ALLOC( samplesOut2_tmp,\n           decControl->nChannelsAPI == 2 ? *nSamplesOut : ALLOC_NONE, opus_int16 );\n    if( decControl->nChannelsAPI == 2 ) {\n        resample_out_ptr = samplesOut2_tmp;\n    } else {\n        resample_out_ptr = samplesOut;\n    }\n\n    ALLOC( samplesOut1_tmp_storage2, delay_stack_alloc\n           ? decControl->nChannelsInternal*(channel_state[ 0 ].frame_length + 2 )\n           : ALLOC_NONE,\n           opus_int16 );\n    if ( delay_stack_alloc ) {\n       OPUS_COPY(samplesOut1_tmp_storage2, samplesOut, decControl->nChannelsInternal*(channel_state[ 0 ].frame_length + 2));\n       samplesOut1_tmp[ 0 ] = samplesOut1_tmp_storage2;\n       samplesOut1_tmp[ 1 ] = samplesOut1_tmp_storage2 + channel_state[ 0 ].frame_length + 2;\n    }\n    for( n = 0; n < silk_min( decControl->nChannelsAPI, decControl->nChannelsInternal ); n++ ) {\n\n        /* Resample decoded signal to API_sampleRate */\n        ret += silk_resampler( &channel_state[ n ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ n ][ 1 ], nSamplesOutDec );\n\n        /* Interleave if stereo output and stereo stream */\n        if( decControl->nChannelsAPI == 2 ) {\n            for( i = 0; i < *nSamplesOut; i++ ) {\n                samplesOut[ n + 2 * i ] = resample_out_ptr[ i ];\n            }\n        }\n    }\n\n    /* Create two channel output from mono stream */\n    if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 1 ) {\n        if ( stereo_to_mono ){\n            /* Resample right channel for newly collapsed stereo just in case\n               we weren't doing collapsing when switching to mono */\n            ret += silk_resampler( &channel_state[ 1 ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ 0 ][ 1 ], nSamplesOutDec );\n\n            for( i = 0; i < *nSamplesOut; i++ ) {\n                samplesOut[ 1 + 2 * i ] = resample_out_ptr[ i ];\n            }\n        } else {\n            for( i = 0; i < *nSamplesOut; i++ ) {\n                samplesOut[ 1 + 2 * i ] = samplesOut[ 0 + 2 * i ];\n            }\n        }\n    }\n\n    /* Export pitch lag, measured at 48 kHz sampling rate */\n    if( channel_state[ 0 ].prevSignalType == TYPE_VOICED ) {\n        int mult_tab[ 3 ] = { 6, 4, 3 };\n        decControl->prevPitchLag = channel_state[ 0 ].lagPrev * mult_tab[ ( channel_state[ 0 ].fs_kHz - 8 ) >> 2 ];\n    } else {\n        decControl->prevPitchLag = 0;\n    }\n\n    if( lostFlag == FLAG_PACKET_LOST ) {\n       /* On packet loss, remove the gain clamping to prevent having the energy \"bounce back\"\n          if we lose packets when the energy is going down */\n       for ( i = 0; i < psDec->nChannelsInternal; i++ )\n          psDec->channel_state[ i ].LastGainIndex = 10;\n    } else {\n       psDec->prev_decode_only_middle = decode_only_middle;\n    }\n    RESTORE_STACK;\n    return ret;\n}\n\n#if 0\n/* Getting table of contents for a packet */\nopus_int silk_get_TOC(\n    const opus_uint8                *payload,           /* I    Payload data                                */\n    const opus_int                  nBytesIn,           /* I    Number of input bytes                       */\n    const opus_int                  nFramesPerPayload,  /* I    Number of SILK frames per payload           */\n    silk_TOC_struct                 *Silk_TOC           /* O    Type of content                             */\n)\n{\n    opus_int i, flags, ret = SILK_NO_ERROR;\n\n    if( nBytesIn < 1 ) {\n        return -1;\n    }\n    if( nFramesPerPayload < 0 || nFramesPerPayload > 3 ) {\n        return -1;\n    }\n\n    silk_memset( Silk_TOC, 0, sizeof( *Silk_TOC ) );\n\n    /* For stereo, extract the flags for the mid channel */\n    flags = silk_RSHIFT( payload[ 0 ], 7 - nFramesPerPayload ) & ( silk_LSHIFT( 1, nFramesPerPayload + 1 ) - 1 );\n\n    Silk_TOC->inbandFECFlag = flags & 1;\n    for( i = nFramesPerPayload - 1; i >= 0 ; i-- ) {\n        flags = silk_RSHIFT( flags, 1 );\n        Silk_TOC->VADFlags[ i ] = flags & 1;\n        Silk_TOC->VADFlag |= flags & 1;\n    }\n\n    return ret;\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/decode_core.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"stack_alloc.h\"\n\n/**********************************************************/\n/* Core decoder. Performs inverse NSQ operation LTP + LPC */\n/**********************************************************/\nvoid silk_decode_core(\n    silk_decoder_state          *psDec,                         /* I/O  Decoder state                               */\n    silk_decoder_control        *psDecCtrl,                     /* I    Decoder control                             */\n    opus_int16                  xq[],                           /* O    Decoded speech                              */\n    const opus_int16            pulses[ MAX_FRAME_LENGTH ],     /* I    Pulse signal                                */\n    int                         arch                            /* I    Run-time architecture                       */\n)\n{\n    opus_int   i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType;\n    opus_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ];\n    VARDECL( opus_int16, sLTP );\n    VARDECL( opus_int32, sLTP_Q15 );\n    opus_int32 LTP_pred_Q13, LPC_pred_Q10, Gain_Q10, inv_gain_Q31, gain_adj_Q16, rand_seed, offset_Q10;\n    opus_int32 *pred_lag_ptr, *pexc_Q14, *pres_Q14;\n    VARDECL( opus_int32, res_Q14 );\n    VARDECL( opus_int32, sLPC_Q14 );\n    SAVE_STACK;\n\n    silk_assert( psDec->prev_gain_Q16 != 0 );\n\n    ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 );\n    ALLOC( sLTP_Q15, psDec->ltp_mem_length + psDec->frame_length, opus_int32 );\n    ALLOC( res_Q14, psDec->subfr_length, opus_int32 );\n    ALLOC( sLPC_Q14, psDec->subfr_length + MAX_LPC_ORDER, opus_int32 );\n\n    offset_Q10 = silk_Quantization_Offsets_Q10[ psDec->indices.signalType >> 1 ][ psDec->indices.quantOffsetType ];\n\n    if( psDec->indices.NLSFInterpCoef_Q2 < 1 << 2 ) {\n        NLSF_interpolation_flag = 1;\n    } else {\n        NLSF_interpolation_flag = 0;\n    }\n\n    /* Decode excitation */\n    rand_seed = psDec->indices.Seed;\n    for( i = 0; i < psDec->frame_length; i++ ) {\n        rand_seed = silk_RAND( rand_seed );\n        psDec->exc_Q14[ i ] = silk_LSHIFT( (opus_int32)pulses[ i ], 14 );\n        if( psDec->exc_Q14[ i ] > 0 ) {\n            psDec->exc_Q14[ i ] -= QUANT_LEVEL_ADJUST_Q10 << 4;\n        } else\n        if( psDec->exc_Q14[ i ] < 0 ) {\n            psDec->exc_Q14[ i ] += QUANT_LEVEL_ADJUST_Q10 << 4;\n        }\n        psDec->exc_Q14[ i ] += offset_Q10 << 4;\n        if( rand_seed < 0 ) {\n           psDec->exc_Q14[ i ] = -psDec->exc_Q14[ i ];\n        }\n\n        rand_seed = silk_ADD32_ovflw( rand_seed, pulses[ i ] );\n    }\n\n    /* Copy LPC state */\n    silk_memcpy( sLPC_Q14, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) );\n\n    pexc_Q14 = psDec->exc_Q14;\n    pxq      = xq;\n    sLTP_buf_idx = psDec->ltp_mem_length;\n    /* Loop over subframes */\n    for( k = 0; k < psDec->nb_subfr; k++ ) {\n        pres_Q14 = res_Q14;\n        A_Q12 = psDecCtrl->PredCoef_Q12[ k >> 1 ];\n\n        /* Preload LPC coeficients to array on stack. Gives small performance gain */\n        silk_memcpy( A_Q12_tmp, A_Q12, psDec->LPC_order * sizeof( opus_int16 ) );\n        B_Q14        = &psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER ];\n        signalType   = psDec->indices.signalType;\n\n        Gain_Q10     = silk_RSHIFT( psDecCtrl->Gains_Q16[ k ], 6 );\n        inv_gain_Q31 = silk_INVERSE32_varQ( psDecCtrl->Gains_Q16[ k ], 47 );\n\n        /* Calculate gain adjustment factor */\n        if( psDecCtrl->Gains_Q16[ k ] != psDec->prev_gain_Q16 ) {\n            gain_adj_Q16 =  silk_DIV32_varQ( psDec->prev_gain_Q16, psDecCtrl->Gains_Q16[ k ], 16 );\n\n            /* Scale short term state */\n            for( i = 0; i < MAX_LPC_ORDER; i++ ) {\n                sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, sLPC_Q14[ i ] );\n            }\n        } else {\n            gain_adj_Q16 = (opus_int32)1 << 16;\n        }\n\n        /* Save inv_gain */\n        silk_assert( inv_gain_Q31 != 0 );\n        psDec->prev_gain_Q16 = psDecCtrl->Gains_Q16[ k ];\n\n        /* Avoid abrupt transition from voiced PLC to unvoiced normal decoding */\n        if( psDec->lossCnt && psDec->prevSignalType == TYPE_VOICED &&\n            psDec->indices.signalType != TYPE_VOICED && k < MAX_NB_SUBFR/2 ) {\n\n            silk_memset( B_Q14, 0, LTP_ORDER * sizeof( opus_int16 ) );\n            B_Q14[ LTP_ORDER/2 ] = SILK_FIX_CONST( 0.25, 14 );\n\n            signalType = TYPE_VOICED;\n            psDecCtrl->pitchL[ k ] = psDec->lagPrev;\n        }\n\n        if( signalType == TYPE_VOICED ) {\n            /* Voiced */\n            lag = psDecCtrl->pitchL[ k ];\n\n            /* Re-whitening */\n            if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) {\n                /* Rewhiten with new A coefs */\n                start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;\n                silk_assert( start_idx > 0 );\n\n                if( k == 2 ) {\n                    silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) );\n                }\n\n                silk_LPC_analysis_filter( &sLTP[ start_idx ], &psDec->outBuf[ start_idx + k * psDec->subfr_length ],\n                    A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order, arch );\n\n                /* After rewhitening the LTP state is unscaled */\n                if( k == 0 ) {\n                    /* Do LTP downscaling to reduce inter-packet dependency */\n                    inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, psDecCtrl->LTP_scale_Q14 ), 2 );\n                }\n                for( i = 0; i < lag + LTP_ORDER/2; i++ ) {\n                    sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWB( inv_gain_Q31, sLTP[ psDec->ltp_mem_length - i - 1 ] );\n                }\n            } else {\n                /* Update LTP state when Gain changes */\n                if( gain_adj_Q16 != (opus_int32)1 << 16 ) {\n                    for( i = 0; i < lag + LTP_ORDER/2; i++ ) {\n                        sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ sLTP_buf_idx - i - 1 ] );\n                    }\n                }\n            }\n        }\n\n        /* Long-term prediction */\n        if( signalType == TYPE_VOICED ) {\n            /* Set up pointer */\n            pred_lag_ptr = &sLTP_Q15[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];\n            for( i = 0; i < psDec->subfr_length; i++ ) {\n                /* Unrolled loop */\n                /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n                LTP_pred_Q13 = 2;\n                LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[  0 ], B_Q14[ 0 ] );\n                LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );\n                LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );\n                LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );\n                LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );\n                pred_lag_ptr++;\n\n                /* Generate LPC excitation */\n                pres_Q14[ i ] = silk_ADD_LSHIFT32( pexc_Q14[ i ], LTP_pred_Q13, 1 );\n\n                /* Update states */\n                sLTP_Q15[ sLTP_buf_idx ] = silk_LSHIFT( pres_Q14[ i ], 1 );\n                sLTP_buf_idx++;\n            }\n        } else {\n            pres_Q14 = pexc_Q14;\n        }\n\n        for( i = 0; i < psDec->subfr_length; i++ ) {\n            /* Short-term prediction */\n            silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );\n            /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n            LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  1 ], A_Q12_tmp[ 0 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  2 ], A_Q12_tmp[ 1 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  3 ], A_Q12_tmp[ 2 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  4 ], A_Q12_tmp[ 3 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  5 ], A_Q12_tmp[ 4 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  6 ], A_Q12_tmp[ 5 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  7 ], A_Q12_tmp[ 6 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  8 ], A_Q12_tmp[ 7 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  9 ], A_Q12_tmp[ 8 ] );\n            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] );\n            if( psDec->LPC_order == 16 ) {\n                LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 11 ], A_Q12_tmp[ 10 ] );\n                LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 12 ], A_Q12_tmp[ 11 ] );\n                LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 13 ], A_Q12_tmp[ 12 ] );\n                LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 14 ], A_Q12_tmp[ 13 ] );\n                LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 15 ], A_Q12_tmp[ 14 ] );\n                LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 16 ], A_Q12_tmp[ 15 ] );\n            }\n\n            /* Add prediction to LPC excitation */\n            sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( pres_Q14[ i ], LPC_pred_Q10, 4 );\n\n            /* Scale with gain */\n            pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) );\n        }\n\n        /* DEBUG_STORE_DATA( dec.pcm, pxq, psDec->subfr_length * sizeof( opus_int16 ) ) */\n\n        /* Update LPC filter state */\n        silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );\n        pexc_Q14 += psDec->subfr_length;\n        pxq      += psDec->subfr_length;\n    }\n\n    /* Save LPC state */\n    silk_memcpy( psDec->sLPC_Q14_buf, sLPC_Q14, MAX_LPC_ORDER * sizeof( opus_int32 ) );\n    RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/decode_frame.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"stack_alloc.h\"\n#include \"PLC.h\"\n\n/****************/\n/* Decode frame */\n/****************/\nopus_int silk_decode_frame(\n    silk_decoder_state          *psDec,                         /* I/O  Pointer to Silk decoder state               */\n    ec_dec                      *psRangeDec,                    /* I/O  Compressor data structure                   */\n    opus_int16                  pOut[],                         /* O    Pointer to output speech frame              */\n    opus_int32                  *pN,                            /* O    Pointer to size of output frame             */\n    opus_int                    lostFlag,                       /* I    0: no loss, 1 loss, 2 decode fec            */\n    opus_int                    condCoding,                     /* I    The type of conditional coding to use       */\n    int                         arch                            /* I    Run-time architecture                       */\n)\n{\n    VARDECL( silk_decoder_control, psDecCtrl );\n    opus_int         L, mv_len, ret = 0;\n    SAVE_STACK;\n\n    L = psDec->frame_length;\n    ALLOC( psDecCtrl, 1, silk_decoder_control );\n    psDecCtrl->LTP_scale_Q14 = 0;\n\n    /* Safety checks */\n    silk_assert( L > 0 && L <= MAX_FRAME_LENGTH );\n\n    if(   lostFlag == FLAG_DECODE_NORMAL ||\n        ( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) )\n    {\n        VARDECL( opus_int16, pulses );\n        ALLOC( pulses, (L + SHELL_CODEC_FRAME_LENGTH - 1) &\n                       ~(SHELL_CODEC_FRAME_LENGTH - 1), opus_int16 );\n        /*********************************************/\n        /* Decode quantization indices of side info  */\n        /*********************************************/\n        silk_decode_indices( psDec, psRangeDec, psDec->nFramesDecoded, lostFlag, condCoding );\n\n        /*********************************************/\n        /* Decode quantization indices of excitation */\n        /*********************************************/\n        silk_decode_pulses( psRangeDec, pulses, psDec->indices.signalType,\n                psDec->indices.quantOffsetType, psDec->frame_length );\n\n        /********************************************/\n        /* Decode parameters and pulse signal       */\n        /********************************************/\n        silk_decode_parameters( psDec, psDecCtrl, condCoding );\n\n        /********************************************************/\n        /* Run inverse NSQ                                      */\n        /********************************************************/\n        silk_decode_core( psDec, psDecCtrl, pOut, pulses, arch );\n\n        /********************************************************/\n        /* Update PLC state                                     */\n        /********************************************************/\n        silk_PLC( psDec, psDecCtrl, pOut, 0, arch );\n\n        psDec->lossCnt = 0;\n        psDec->prevSignalType = psDec->indices.signalType;\n        silk_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 );\n\n        /* A frame has been decoded without errors */\n        psDec->first_frame_after_reset = 0;\n    } else {\n        /* Handle packet loss by extrapolation */\n        silk_PLC( psDec, psDecCtrl, pOut, 1, arch );\n    }\n\n    /*************************/\n    /* Update output buffer. */\n    /*************************/\n    silk_assert( psDec->ltp_mem_length >= psDec->frame_length );\n    mv_len = psDec->ltp_mem_length - psDec->frame_length;\n    silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) );\n    silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) );\n\n    /************************************************/\n    /* Comfort noise generation / estimation        */\n    /************************************************/\n    silk_CNG( psDec, psDecCtrl, pOut, L );\n\n    /****************************************************************/\n    /* Ensure smooth connection of extrapolated and good frames     */\n    /****************************************************************/\n    silk_PLC_glue_frames( psDec, pOut, L );\n\n    /* Update some decoder state variables */\n    psDec->lagPrev = psDecCtrl->pitchL[ psDec->nb_subfr - 1 ];\n\n    /* Set output frame length */\n    *pN = L;\n\n    RESTORE_STACK;\n    return ret;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/decode_indices.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Decode side-information parameters from payload */\nvoid silk_decode_indices(\n    silk_decoder_state          *psDec,                         /* I/O  State                                       */\n    ec_dec                      *psRangeDec,                    /* I/O  Compressor data structure                   */\n    opus_int                    FrameIndex,                     /* I    Frame number                                */\n    opus_int                    decode_LBRR,                    /* I    Flag indicating LBRR data is being decoded  */\n    opus_int                    condCoding                      /* I    The type of conditional coding to use       */\n)\n{\n    opus_int   i, k, Ix;\n    opus_int   decode_absolute_lagIndex, delta_lagIndex;\n    opus_int16 ec_ix[ MAX_LPC_ORDER ];\n    opus_uint8 pred_Q8[ MAX_LPC_ORDER ];\n\n    /*******************************************/\n    /* Decode signal type and quantizer offset */\n    /*******************************************/\n    if( decode_LBRR || psDec->VAD_flags[ FrameIndex ] ) {\n        Ix = ec_dec_icdf( psRangeDec, silk_type_offset_VAD_iCDF, 8 ) + 2;\n    } else {\n        Ix = ec_dec_icdf( psRangeDec, silk_type_offset_no_VAD_iCDF, 8 );\n    }\n    psDec->indices.signalType      = (opus_int8)silk_RSHIFT( Ix, 1 );\n    psDec->indices.quantOffsetType = (opus_int8)( Ix & 1 );\n\n    /****************/\n    /* Decode gains */\n    /****************/\n    /* First subframe */\n    if( condCoding == CODE_CONDITIONALLY ) {\n        /* Conditional coding */\n        psDec->indices.GainsIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_delta_gain_iCDF, 8 );\n    } else {\n        /* Independent coding, in two stages: MSB bits followed by 3 LSBs */\n        psDec->indices.GainsIndices[ 0 ]  = (opus_int8)silk_LSHIFT( ec_dec_icdf( psRangeDec, silk_gain_iCDF[ psDec->indices.signalType ], 8 ), 3 );\n        psDec->indices.GainsIndices[ 0 ] += (opus_int8)ec_dec_icdf( psRangeDec, silk_uniform8_iCDF, 8 );\n    }\n\n    /* Remaining subframes */\n    for( i = 1; i < psDec->nb_subfr; i++ ) {\n        psDec->indices.GainsIndices[ i ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_delta_gain_iCDF, 8 );\n    }\n\n    /**********************/\n    /* Decode LSF Indices */\n    /**********************/\n    psDec->indices.NLSFIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->CB1_iCDF[ ( psDec->indices.signalType >> 1 ) * psDec->psNLSF_CB->nVectors ], 8 );\n    silk_NLSF_unpack( ec_ix, pred_Q8, psDec->psNLSF_CB, psDec->indices.NLSFIndices[ 0 ] );\n    silk_assert( psDec->psNLSF_CB->order == psDec->LPC_order );\n    for( i = 0; i < psDec->psNLSF_CB->order; i++ ) {\n        Ix = ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );\n        if( Ix == 0 ) {\n            Ix -= ec_dec_icdf( psRangeDec, silk_NLSF_EXT_iCDF, 8 );\n        } else if( Ix == 2 * NLSF_QUANT_MAX_AMPLITUDE ) {\n            Ix += ec_dec_icdf( psRangeDec, silk_NLSF_EXT_iCDF, 8 );\n        }\n        psDec->indices.NLSFIndices[ i+1 ] = (opus_int8)( Ix - NLSF_QUANT_MAX_AMPLITUDE );\n    }\n\n    /* Decode LSF interpolation factor */\n    if( psDec->nb_subfr == MAX_NB_SUBFR ) {\n        psDec->indices.NLSFInterpCoef_Q2 = (opus_int8)ec_dec_icdf( psRangeDec, silk_NLSF_interpolation_factor_iCDF, 8 );\n    } else {\n        psDec->indices.NLSFInterpCoef_Q2 = 4;\n    }\n\n    if( psDec->indices.signalType == TYPE_VOICED )\n    {\n        /*********************/\n        /* Decode pitch lags */\n        /*********************/\n        /* Get lag index */\n        decode_absolute_lagIndex = 1;\n        if( condCoding == CODE_CONDITIONALLY && psDec->ec_prevSignalType == TYPE_VOICED ) {\n            /* Decode Delta index */\n            delta_lagIndex = (opus_int16)ec_dec_icdf( psRangeDec, silk_pitch_delta_iCDF, 8 );\n            if( delta_lagIndex > 0 ) {\n                delta_lagIndex = delta_lagIndex - 9;\n                psDec->indices.lagIndex = (opus_int16)( psDec->ec_prevLagIndex + delta_lagIndex );\n                decode_absolute_lagIndex = 0;\n            }\n        }\n        if( decode_absolute_lagIndex ) {\n            /* Absolute decoding */\n            psDec->indices.lagIndex  = (opus_int16)ec_dec_icdf( psRangeDec, silk_pitch_lag_iCDF, 8 ) * silk_RSHIFT( psDec->fs_kHz, 1 );\n            psDec->indices.lagIndex += (opus_int16)ec_dec_icdf( psRangeDec, psDec->pitch_lag_low_bits_iCDF, 8 );\n        }\n        psDec->ec_prevLagIndex = psDec->indices.lagIndex;\n\n        /* Get countour index */\n        psDec->indices.contourIndex = (opus_int8)ec_dec_icdf( psRangeDec, psDec->pitch_contour_iCDF, 8 );\n\n        /********************/\n        /* Decode LTP gains */\n        /********************/\n        /* Decode PERIndex value */\n        psDec->indices.PERIndex = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTP_per_index_iCDF, 8 );\n\n        for( k = 0; k < psDec->nb_subfr; k++ ) {\n            psDec->indices.LTPIndex[ k ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTP_gain_iCDF_ptrs[ psDec->indices.PERIndex ], 8 );\n        }\n\n        /**********************/\n        /* Decode LTP scaling */\n        /**********************/\n        if( condCoding == CODE_INDEPENDENTLY ) {\n            psDec->indices.LTP_scaleIndex = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTPscale_iCDF, 8 );\n        } else {\n            psDec->indices.LTP_scaleIndex = 0;\n        }\n    }\n    psDec->ec_prevSignalType = psDec->indices.signalType;\n\n    /***************/\n    /* Decode seed */\n    /***************/\n    psDec->indices.Seed = (opus_int8)ec_dec_icdf( psRangeDec, silk_uniform4_iCDF, 8 );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/decode_parameters.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Decode parameters from payload */\nvoid silk_decode_parameters(\n    silk_decoder_state          *psDec,                         /* I/O  State                                       */\n    silk_decoder_control        *psDecCtrl,                     /* I/O  Decoder control                             */\n    opus_int                    condCoding                      /* I    The type of conditional coding to use       */\n)\n{\n    opus_int   i, k, Ix;\n    opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], pNLSF0_Q15[ MAX_LPC_ORDER ];\n    const opus_int8 *cbk_ptr_Q7;\n\n    /* Dequant Gains */\n    silk_gains_dequant( psDecCtrl->Gains_Q16, psDec->indices.GainsIndices,\n        &psDec->LastGainIndex, condCoding == CODE_CONDITIONALLY, psDec->nb_subfr );\n\n    /****************/\n    /* Decode NLSFs */\n    /****************/\n    silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB );\n\n    /* Convert NLSF parameters to AR prediction filter coefficients */\n    silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order );\n\n    /* If just reset, e.g., because internal Fs changed, do not allow interpolation */\n    /* improves the case of packet loss in the first frame after a switch           */\n    if( psDec->first_frame_after_reset == 1 ) {\n        psDec->indices.NLSFInterpCoef_Q2 = 4;\n    }\n\n    if( psDec->indices.NLSFInterpCoef_Q2 < 4 ) {\n        /* Calculation of the interpolated NLSF0 vector from the interpolation factor, */\n        /* the previous NLSF1, and the current NLSF1                                   */\n        for( i = 0; i < psDec->LPC_order; i++ ) {\n            pNLSF0_Q15[ i ] = psDec->prevNLSF_Q15[ i ] + silk_RSHIFT( silk_MUL( psDec->indices.NLSFInterpCoef_Q2,\n                pNLSF_Q15[ i ] - psDec->prevNLSF_Q15[ i ] ), 2 );\n        }\n\n        /* Convert NLSF parameters to AR prediction filter coefficients */\n        silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order );\n    } else {\n        /* Copy LPC coefficients for first half from second half */\n        silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) );\n    }\n\n    silk_memcpy( psDec->prevNLSF_Q15, pNLSF_Q15, psDec->LPC_order * sizeof( opus_int16 ) );\n\n    /* After a packet loss do BWE of LPC coefs */\n    if( psDec->lossCnt ) {\n        silk_bwexpander( psDecCtrl->PredCoef_Q12[ 0 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 );\n        silk_bwexpander( psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 );\n    }\n\n    if( psDec->indices.signalType == TYPE_VOICED ) {\n        /*********************/\n        /* Decode pitch lags */\n        /*********************/\n\n        /* Decode pitch values */\n        silk_decode_pitch( psDec->indices.lagIndex, psDec->indices.contourIndex, psDecCtrl->pitchL, psDec->fs_kHz, psDec->nb_subfr );\n\n        /* Decode Codebook Index */\n        cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ psDec->indices.PERIndex ]; /* set pointer to start of codebook */\n\n        for( k = 0; k < psDec->nb_subfr; k++ ) {\n            Ix = psDec->indices.LTPIndex[ k ];\n            for( i = 0; i < LTP_ORDER; i++ ) {\n                psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER + i ] = silk_LSHIFT( cbk_ptr_Q7[ Ix * LTP_ORDER + i ], 7 );\n            }\n        }\n\n        /**********************/\n        /* Decode LTP scaling */\n        /**********************/\n        Ix = psDec->indices.LTP_scaleIndex;\n        psDecCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ Ix ];\n    } else {\n        silk_memset( psDecCtrl->pitchL,      0,             psDec->nb_subfr * sizeof( opus_int   ) );\n        silk_memset( psDecCtrl->LTPCoef_Q14, 0, LTP_ORDER * psDec->nb_subfr * sizeof( opus_int16 ) );\n        psDec->indices.PERIndex  = 0;\n        psDecCtrl->LTP_scale_Q14 = 0;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/decode_pitch.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/***********************************************************\n* Pitch analyser function\n********************************************************** */\n#include \"SigProc_FIX.h\"\n#include \"pitch_est_defines.h\"\n\nvoid silk_decode_pitch(\n    opus_int16                  lagIndex,           /* I                                                                */\n    opus_int8                   contourIndex,       /* O                                                                */\n    opus_int                    pitch_lags[],       /* O    4 pitch values                                              */\n    const opus_int              Fs_kHz,             /* I    sampling frequency (kHz)                                    */\n    const opus_int              nb_subfr            /* I    number of sub frames                                        */\n)\n{\n    opus_int   lag, k, min_lag, max_lag, cbk_size;\n    const opus_int8 *Lag_CB_ptr;\n\n    if( Fs_kHz == 8 ) {\n        if( nb_subfr == PE_MAX_NB_SUBFR ) {\n            Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];\n            cbk_size   = PE_NB_CBKS_STAGE2_EXT;\n        } else {\n            silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );\n            Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];\n            cbk_size   = PE_NB_CBKS_STAGE2_10MS;\n        }\n    } else {\n        if( nb_subfr == PE_MAX_NB_SUBFR ) {\n            Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];\n            cbk_size   = PE_NB_CBKS_STAGE3_MAX;\n        } else {\n            silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );\n            Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];\n            cbk_size   = PE_NB_CBKS_STAGE3_10MS;\n        }\n    }\n\n    min_lag = silk_SMULBB( PE_MIN_LAG_MS, Fs_kHz );\n    max_lag = silk_SMULBB( PE_MAX_LAG_MS, Fs_kHz );\n    lag = min_lag + lagIndex;\n\n    for( k = 0; k < nb_subfr; k++ ) {\n        pitch_lags[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, contourIndex, cbk_size );\n        pitch_lags[ k ] = silk_LIMIT( pitch_lags[ k ], min_lag, max_lag );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/decode_pulses.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/*********************************************/\n/* Decode quantization indices of excitation */\n/*********************************************/\nvoid silk_decode_pulses(\n    ec_dec                      *psRangeDec,                    /* I/O  Compressor data structure                   */\n    opus_int16                  pulses[],                       /* O    Excitation signal                           */\n    const opus_int              signalType,                     /* I    Sigtype                                     */\n    const opus_int              quantOffsetType,                /* I    quantOffsetType                             */\n    const opus_int              frame_length                    /* I    Frame length                                */\n)\n{\n    opus_int   i, j, k, iter, abs_q, nLS, RateLevelIndex;\n    opus_int   sum_pulses[ MAX_NB_SHELL_BLOCKS ], nLshifts[ MAX_NB_SHELL_BLOCKS ];\n    opus_int16 *pulses_ptr;\n    const opus_uint8 *cdf_ptr;\n\n    /*********************/\n    /* Decode rate level */\n    /*********************/\n    RateLevelIndex = ec_dec_icdf( psRangeDec, silk_rate_levels_iCDF[ signalType >> 1 ], 8 );\n\n    /* Calculate number of shell blocks */\n    silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH );\n    iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH );\n    if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) {\n        silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */\n        iter++;\n    }\n\n    /***************************************************/\n    /* Sum-Weighted-Pulses Decoding                    */\n    /***************************************************/\n    cdf_ptr = silk_pulses_per_block_iCDF[ RateLevelIndex ];\n    for( i = 0; i < iter; i++ ) {\n        nLshifts[ i ] = 0;\n        sum_pulses[ i ] = ec_dec_icdf( psRangeDec, cdf_ptr, 8 );\n\n        /* LSB indication */\n        while( sum_pulses[ i ] == SILK_MAX_PULSES + 1 ) {\n            nLshifts[ i ]++;\n            /* When we've already got 10 LSBs, we shift the table to not allow (SILK_MAX_PULSES + 1) */\n            sum_pulses[ i ] = ec_dec_icdf( psRangeDec,\n                    silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1] + ( nLshifts[ i ] == 10 ), 8 );\n        }\n    }\n\n    /***************************************************/\n    /* Shell decoding                                  */\n    /***************************************************/\n    for( i = 0; i < iter; i++ ) {\n        if( sum_pulses[ i ] > 0 ) {\n            silk_shell_decoder( &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], psRangeDec, sum_pulses[ i ] );\n        } else {\n            silk_memset( &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof( pulses[0] ) );\n        }\n    }\n\n    /***************************************************/\n    /* LSB Decoding                                    */\n    /***************************************************/\n    for( i = 0; i < iter; i++ ) {\n        if( nLshifts[ i ] > 0 ) {\n            nLS = nLshifts[ i ];\n            pulses_ptr = &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ];\n            for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {\n                abs_q = pulses_ptr[ k ];\n                for( j = 0; j < nLS; j++ ) {\n                    abs_q = silk_LSHIFT( abs_q, 1 );\n                    abs_q += ec_dec_icdf( psRangeDec, silk_lsb_iCDF, 8 );\n                }\n                pulses_ptr[ k ] = abs_q;\n            }\n            /* Mark the number of pulses non-zero for sign decoding. */\n            sum_pulses[ i ] |= nLS << 5;\n        }\n    }\n\n    /****************************************/\n    /* Decode and add signs to pulse signal */\n    /****************************************/\n    silk_decode_signs( psRangeDec, pulses, frame_length, signalType, quantOffsetType, sum_pulses );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/decoder_set_fs.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Set decoder sampling rate */\nopus_int silk_decoder_set_fs(\n    silk_decoder_state          *psDec,                         /* I/O  Decoder state pointer                       */\n    opus_int                    fs_kHz,                         /* I    Sampling frequency (kHz)                    */\n    opus_int32                  fs_API_Hz                       /* I    API Sampling frequency (Hz)                 */\n)\n{\n    opus_int frame_length, ret = 0;\n\n    silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );\n    silk_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 );\n\n    /* New (sub)frame length */\n    psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz );\n    frame_length = silk_SMULBB( psDec->nb_subfr, psDec->subfr_length );\n\n    /* Initialize resampler when switching internal or external sampling frequency */\n    if( psDec->fs_kHz != fs_kHz || psDec->fs_API_hz != fs_API_Hz ) {\n        /* Initialize the resampler for dec_API.c preparing resampling from fs_kHz to API_fs_Hz */\n        ret += silk_resampler_init( &psDec->resampler_state, silk_SMULBB( fs_kHz, 1000 ), fs_API_Hz, 0 );\n\n        psDec->fs_API_hz = fs_API_Hz;\n    }\n\n    if( psDec->fs_kHz != fs_kHz || frame_length != psDec->frame_length ) {\n        if( fs_kHz == 8 ) {\n            if( psDec->nb_subfr == MAX_NB_SUBFR ) {\n                psDec->pitch_contour_iCDF = silk_pitch_contour_NB_iCDF;\n            } else {\n                psDec->pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF;\n            }\n        } else {\n            if( psDec->nb_subfr == MAX_NB_SUBFR ) {\n                psDec->pitch_contour_iCDF = silk_pitch_contour_iCDF;\n            } else {\n                psDec->pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF;\n            }\n        }\n        if( psDec->fs_kHz != fs_kHz ) {\n            psDec->ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz );\n            if( fs_kHz == 8 || fs_kHz == 12 ) {\n                psDec->LPC_order = MIN_LPC_ORDER;\n                psDec->psNLSF_CB = &silk_NLSF_CB_NB_MB;\n            } else {\n                psDec->LPC_order = MAX_LPC_ORDER;\n                psDec->psNLSF_CB = &silk_NLSF_CB_WB;\n            }\n            if( fs_kHz == 16 ) {\n                psDec->pitch_lag_low_bits_iCDF = silk_uniform8_iCDF;\n            } else if( fs_kHz == 12 ) {\n                psDec->pitch_lag_low_bits_iCDF = silk_uniform6_iCDF;\n            } else if( fs_kHz == 8 ) {\n                psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF;\n            } else {\n                /* unsupported sampling rate */\n                silk_assert( 0 );\n            }\n            psDec->first_frame_after_reset = 1;\n            psDec->lagPrev                 = 100;\n            psDec->LastGainIndex           = 10;\n            psDec->prevSignalType          = TYPE_NO_VOICE_ACTIVITY;\n            silk_memset( psDec->outBuf, 0, sizeof(psDec->outBuf));\n            silk_memset( psDec->sLPC_Q14_buf, 0, sizeof(psDec->sLPC_Q14_buf) );\n        }\n\n        psDec->fs_kHz       = fs_kHz;\n        psDec->frame_length = frame_length;\n    }\n\n    /* Check that settings are valid */\n    silk_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH );\n\n    return ret;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/define.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_DEFINE_H\n#define SILK_DEFINE_H\n\n#include \"errors.h\"\n#include \"typedef.h\"\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/* Max number of encoder channels (1/2) */\n#define ENCODER_NUM_CHANNELS                    2\n/* Number of decoder channels (1/2) */\n#define DECODER_NUM_CHANNELS                    2\n\n#define MAX_FRAMES_PER_PACKET                   3\n\n/* Limits on bitrate */\n#define MIN_TARGET_RATE_BPS                     5000\n#define MAX_TARGET_RATE_BPS                     80000\n#define TARGET_RATE_TAB_SZ                      8\n\n/* LBRR thresholds */\n#define LBRR_NB_MIN_RATE_BPS                    12000\n#define LBRR_MB_MIN_RATE_BPS                    14000\n#define LBRR_WB_MIN_RATE_BPS                    16000\n\n/* DTX settings */\n#define NB_SPEECH_FRAMES_BEFORE_DTX             10      /* eq 200 ms */\n#define MAX_CONSECUTIVE_DTX                     20      /* eq 400 ms */\n\n/* Maximum sampling frequency */\n#define MAX_FS_KHZ                              16\n#define MAX_API_FS_KHZ                          48\n\n/* Signal types */\n#define TYPE_NO_VOICE_ACTIVITY                  0\n#define TYPE_UNVOICED                           1\n#define TYPE_VOICED                             2\n\n/* Conditional coding types */\n#define CODE_INDEPENDENTLY                      0\n#define CODE_INDEPENDENTLY_NO_LTP_SCALING       1\n#define CODE_CONDITIONALLY                      2\n\n/* Settings for stereo processing */\n#define STEREO_QUANT_TAB_SIZE                   16\n#define STEREO_QUANT_SUB_STEPS                  5\n#define STEREO_INTERP_LEN_MS                    8       /* must be even */\n#define STEREO_RATIO_SMOOTH_COEF                0.01    /* smoothing coef for signal norms and stereo width */\n\n/* Range of pitch lag estimates */\n#define PITCH_EST_MIN_LAG_MS                    2       /* 2 ms -> 500 Hz */\n#define PITCH_EST_MAX_LAG_MS                    18      /* 18 ms -> 56 Hz */\n\n/* Maximum number of subframes */\n#define MAX_NB_SUBFR                            4\n\n/* Number of samples per frame */\n#define LTP_MEM_LENGTH_MS                       20\n#define SUB_FRAME_LENGTH_MS                     5\n#define MAX_SUB_FRAME_LENGTH                    ( SUB_FRAME_LENGTH_MS * MAX_FS_KHZ )\n#define MAX_FRAME_LENGTH_MS                     ( SUB_FRAME_LENGTH_MS * MAX_NB_SUBFR )\n#define MAX_FRAME_LENGTH                        ( MAX_FRAME_LENGTH_MS * MAX_FS_KHZ )\n\n/* Milliseconds of lookahead for pitch analysis */\n#define LA_PITCH_MS                             2\n#define LA_PITCH_MAX                            ( LA_PITCH_MS * MAX_FS_KHZ )\n\n/* Order of LPC used in find pitch */\n#define MAX_FIND_PITCH_LPC_ORDER                16\n\n/* Length of LPC window used in find pitch */\n#define FIND_PITCH_LPC_WIN_MS                   ( 20 + (LA_PITCH_MS << 1) )\n#define FIND_PITCH_LPC_WIN_MS_2_SF              ( 10 + (LA_PITCH_MS << 1) )\n#define FIND_PITCH_LPC_WIN_MAX                  ( FIND_PITCH_LPC_WIN_MS * MAX_FS_KHZ )\n\n/* Milliseconds of lookahead for noise shape analysis */\n#define LA_SHAPE_MS                             5\n#define LA_SHAPE_MAX                            ( LA_SHAPE_MS * MAX_FS_KHZ )\n\n/* Maximum length of LPC window used in noise shape analysis */\n#define SHAPE_LPC_WIN_MAX                       ( 15 * MAX_FS_KHZ )\n\n/* dB level of lowest gain quantization level */\n#define MIN_QGAIN_DB                            2\n/* dB level of highest gain quantization level */\n#define MAX_QGAIN_DB                            88\n/* Number of gain quantization levels */\n#define N_LEVELS_QGAIN                          64\n/* Max increase in gain quantization index */\n#define MAX_DELTA_GAIN_QUANT                    36\n/* Max decrease in gain quantization index */\n#define MIN_DELTA_GAIN_QUANT                    -4\n\n/* Quantization offsets (multiples of 4) */\n#define OFFSET_VL_Q10                           32\n#define OFFSET_VH_Q10                           100\n#define OFFSET_UVL_Q10                          100\n#define OFFSET_UVH_Q10                          240\n\n#define QUANT_LEVEL_ADJUST_Q10                  80\n\n/* Maximum numbers of iterations used to stabilize an LPC vector */\n#define MAX_LPC_STABILIZE_ITERATIONS            16\n#define MAX_PREDICTION_POWER_GAIN               1e4f\n#define MAX_PREDICTION_POWER_GAIN_AFTER_RESET   1e2f\n\n#define MAX_LPC_ORDER                           16\n#define MIN_LPC_ORDER                           10\n\n/* Find Pred Coef defines */\n#define LTP_ORDER                               5\n\n/* LTP quantization settings */\n#define NB_LTP_CBKS                             3\n\n/* Flag to use harmonic noise shaping */\n#define USE_HARM_SHAPING                        1\n\n/* Max LPC order of noise shaping filters */\n#define MAX_SHAPE_LPC_ORDER                     16\n\n#define HARM_SHAPE_FIR_TAPS                     3\n\n/* Maximum number of delayed decision states */\n#define MAX_DEL_DEC_STATES                      4\n\n#define LTP_BUF_LENGTH                          512\n#define LTP_MASK                                ( LTP_BUF_LENGTH - 1 )\n\n#define DECISION_DELAY                          32\n#define DECISION_DELAY_MASK                     ( DECISION_DELAY - 1 )\n\n/* Number of subframes for excitation entropy coding */\n#define SHELL_CODEC_FRAME_LENGTH                16\n#define LOG2_SHELL_CODEC_FRAME_LENGTH           4\n#define MAX_NB_SHELL_BLOCKS                     ( MAX_FRAME_LENGTH / SHELL_CODEC_FRAME_LENGTH )\n\n/* Number of rate levels, for entropy coding of excitation */\n#define N_RATE_LEVELS                           10\n\n/* Maximum sum of pulses per shell coding frame */\n#define SILK_MAX_PULSES                         16\n\n#define MAX_MATRIX_SIZE                         MAX_LPC_ORDER /* Max of LPC Order and LTP order */\n\n#if( MAX_LPC_ORDER > DECISION_DELAY )\n# define NSQ_LPC_BUF_LENGTH                     MAX_LPC_ORDER\n#else\n# define NSQ_LPC_BUF_LENGTH                     DECISION_DELAY\n#endif\n\n/***************************/\n/* Voice activity detector */\n/***************************/\n#define VAD_N_BANDS                             4\n\n#define VAD_INTERNAL_SUBFRAMES_LOG2             2\n#define VAD_INTERNAL_SUBFRAMES                  ( 1 << VAD_INTERNAL_SUBFRAMES_LOG2 )\n\n#define VAD_NOISE_LEVEL_SMOOTH_COEF_Q16         1024    /* Must be <  4096 */\n#define VAD_NOISE_LEVELS_BIAS                   50\n\n/* Sigmoid settings */\n#define VAD_NEGATIVE_OFFSET_Q5                  128     /* sigmoid is 0 at -128 */\n#define VAD_SNR_FACTOR_Q16                      45000\n\n/* smoothing for SNR measurement */\n#define VAD_SNR_SMOOTH_COEF_Q18                 4096\n\n/* Size of the piecewise linear cosine approximation table for the LSFs */\n#define LSF_COS_TAB_SZ_FIX                      128\n\n/******************/\n/* NLSF quantizer */\n/******************/\n#define NLSF_W_Q                                2\n#define NLSF_VQ_MAX_VECTORS                     32\n#define NLSF_VQ_MAX_SURVIVORS                   32\n#define NLSF_QUANT_MAX_AMPLITUDE                4\n#define NLSF_QUANT_MAX_AMPLITUDE_EXT            10\n#define NLSF_QUANT_LEVEL_ADJ                    0.1\n#define NLSF_QUANT_DEL_DEC_STATES_LOG2          2\n#define NLSF_QUANT_DEL_DEC_STATES               ( 1 << NLSF_QUANT_DEL_DEC_STATES_LOG2 )\n\n/* Transition filtering for mode switching */\n#define TRANSITION_TIME_MS                      5120    /* 5120 = 64 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 64*(20*4)*/\n#define TRANSITION_NB                           3       /* Hardcoded in tables */\n#define TRANSITION_NA                           2       /* Hardcoded in tables */\n#define TRANSITION_INT_NUM                      5       /* Hardcoded in tables */\n#define TRANSITION_FRAMES                       ( TRANSITION_TIME_MS / MAX_FRAME_LENGTH_MS )\n#define TRANSITION_INT_STEPS                    ( TRANSITION_FRAMES  / ( TRANSITION_INT_NUM - 1 ) )\n\n/* BWE factors to apply after packet loss */\n#define BWE_AFTER_LOSS_Q16                      63570\n\n/* Defines for CN generation */\n#define CNG_BUF_MASK_MAX                        255     /* 2^floor(log2(MAX_FRAME_LENGTH))-1    */\n#define CNG_GAIN_SMTH_Q16                       4634    /* 0.25^(1/4)                           */\n#define CNG_NLSF_SMTH_Q16                       16348   /* 0.25                                 */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/enc_API.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#include \"define.h\"\n#include \"API.h\"\n#include \"control.h\"\n#include \"typedef.h\"\n#include \"stack_alloc.h\"\n#include \"structs.h\"\n#include \"tuning_parameters.h\"\n#ifdef FIXED_POINT\n#include \"main_FIX.h\"\n#else\n#include \"main_FLP.h\"\n#endif\n\n/***************************************/\n/* Read control structure from encoder */\n/***************************************/\nstatic opus_int silk_QueryEncoder(                      /* O    Returns error code                              */\n    const void                      *encState,          /* I    State                                           */\n    silk_EncControlStruct           *encStatus          /* O    Encoder Status                                  */\n);\n\n/****************************************/\n/* Encoder functions                    */\n/****************************************/\n\nopus_int silk_Get_Encoder_Size(                         /* O    Returns error code                              */\n    opus_int                        *encSizeBytes       /* O    Number of bytes in SILK encoder state           */\n)\n{\n    opus_int ret = SILK_NO_ERROR;\n\n    *encSizeBytes = sizeof( silk_encoder );\n\n    return ret;\n}\n\n/*************************/\n/* Init or Reset encoder */\n/*************************/\nopus_int silk_InitEncoder(                              /* O    Returns error code                              */\n    void                            *encState,          /* I/O  State                                           */\n    int                              arch,              /* I    Run-time architecture                           */\n    silk_EncControlStruct           *encStatus          /* O    Encoder Status                                  */\n)\n{\n    silk_encoder *psEnc;\n    opus_int n, ret = SILK_NO_ERROR;\n\n    psEnc = (silk_encoder *)encState;\n\n    /* Reset encoder */\n    silk_memset( psEnc, 0, sizeof( silk_encoder ) );\n    for( n = 0; n < ENCODER_NUM_CHANNELS; n++ ) {\n        if( ret += silk_init_encoder( &psEnc->state_Fxx[ n ], arch ) ) {\n            silk_assert( 0 );\n        }\n    }\n\n    psEnc->nChannelsAPI = 1;\n    psEnc->nChannelsInternal = 1;\n\n    /* Read control structure */\n    if( ret += silk_QueryEncoder( encState, encStatus ) ) {\n        silk_assert( 0 );\n    }\n\n    return ret;\n}\n\n/***************************************/\n/* Read control structure from encoder */\n/***************************************/\nstatic opus_int silk_QueryEncoder(                      /* O    Returns error code                              */\n    const void                      *encState,          /* I    State                                           */\n    silk_EncControlStruct           *encStatus          /* O    Encoder Status                                  */\n)\n{\n    opus_int ret = SILK_NO_ERROR;\n    silk_encoder_state_Fxx *state_Fxx;\n    silk_encoder *psEnc = (silk_encoder *)encState;\n\n    state_Fxx = psEnc->state_Fxx;\n\n    encStatus->nChannelsAPI              = psEnc->nChannelsAPI;\n    encStatus->nChannelsInternal         = psEnc->nChannelsInternal;\n    encStatus->API_sampleRate            = state_Fxx[ 0 ].sCmn.API_fs_Hz;\n    encStatus->maxInternalSampleRate     = state_Fxx[ 0 ].sCmn.maxInternal_fs_Hz;\n    encStatus->minInternalSampleRate     = state_Fxx[ 0 ].sCmn.minInternal_fs_Hz;\n    encStatus->desiredInternalSampleRate = state_Fxx[ 0 ].sCmn.desiredInternal_fs_Hz;\n    encStatus->payloadSize_ms            = state_Fxx[ 0 ].sCmn.PacketSize_ms;\n    encStatus->bitRate                   = state_Fxx[ 0 ].sCmn.TargetRate_bps;\n    encStatus->packetLossPercentage      = state_Fxx[ 0 ].sCmn.PacketLoss_perc;\n    encStatus->complexity                = state_Fxx[ 0 ].sCmn.Complexity;\n    encStatus->useInBandFEC              = state_Fxx[ 0 ].sCmn.useInBandFEC;\n    encStatus->useDTX                    = state_Fxx[ 0 ].sCmn.useDTX;\n    encStatus->useCBR                    = state_Fxx[ 0 ].sCmn.useCBR;\n    encStatus->internalSampleRate        = silk_SMULBB( state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );\n    encStatus->allowBandwidthSwitch      = state_Fxx[ 0 ].sCmn.allow_bandwidth_switch;\n    encStatus->inWBmodeWithoutVariableLP = state_Fxx[ 0 ].sCmn.fs_kHz == 16 && state_Fxx[ 0 ].sCmn.sLP.mode == 0;\n\n    return ret;\n}\n\n\n/**************************/\n/* Encode frame with Silk */\n/**************************/\n/* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what                     */\n/* encControl->payloadSize_ms is set to                                                                         */\nopus_int silk_Encode(                                   /* O    Returns error code                              */\n    void                            *encState,          /* I/O  State                                           */\n    silk_EncControlStruct           *encControl,        /* I    Control status                                  */\n    const opus_int16                *samplesIn,         /* I    Speech sample input vector                      */\n    opus_int                        nSamplesIn,         /* I    Number of samples in input vector               */\n    ec_enc                          *psRangeEnc,        /* I/O  Compressor data structure                       */\n    opus_int32                      *nBytesOut,         /* I/O  Number of bytes in payload (input: Max bytes)   */\n    const opus_int                  prefillFlag         /* I    Flag to indicate prefilling buffers no coding   */\n)\n{\n    opus_int   n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0;\n    opus_int   nSamplesToBuffer, nSamplesToBufferMax, nBlocksOf10ms;\n    opus_int   nSamplesFromInput = 0, nSamplesFromInputMax;\n    opus_int   speech_act_thr_for_switch_Q8;\n    opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum;\n    silk_encoder *psEnc = ( silk_encoder * )encState;\n    VARDECL( opus_int16, buf );\n    opus_int transition, curr_block, tot_blocks;\n    SAVE_STACK;\n\n    if (encControl->reducedDependency)\n    {\n       psEnc->state_Fxx[0].sCmn.first_frame_after_reset = 1;\n       psEnc->state_Fxx[1].sCmn.first_frame_after_reset = 1;\n    }\n    psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0;\n\n    /* Check values in encoder control structure */\n    if( ( ret = check_control_input( encControl ) ) != 0 ) {\n        silk_assert( 0 );\n        RESTORE_STACK;\n        return ret;\n    }\n\n    encControl->switchReady = 0;\n\n    if( encControl->nChannelsInternal > psEnc->nChannelsInternal ) {\n        /* Mono -> Stereo transition: init state of second channel and stereo state */\n        ret += silk_init_encoder( &psEnc->state_Fxx[ 1 ], psEnc->state_Fxx[ 0 ].sCmn.arch );\n        silk_memset( psEnc->sStereo.pred_prev_Q13, 0, sizeof( psEnc->sStereo.pred_prev_Q13 ) );\n        silk_memset( psEnc->sStereo.sSide, 0, sizeof( psEnc->sStereo.sSide ) );\n        psEnc->sStereo.mid_side_amp_Q0[ 0 ] = 0;\n        psEnc->sStereo.mid_side_amp_Q0[ 1 ] = 1;\n        psEnc->sStereo.mid_side_amp_Q0[ 2 ] = 0;\n        psEnc->sStereo.mid_side_amp_Q0[ 3 ] = 1;\n        psEnc->sStereo.width_prev_Q14 = 0;\n        psEnc->sStereo.smth_width_Q14 = SILK_FIX_CONST( 1, 14 );\n        if( psEnc->nChannelsAPI == 2 ) {\n            silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof( silk_resampler_state_struct ) );\n            silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.In_HP_State,     &psEnc->state_Fxx[ 0 ].sCmn.In_HP_State,     sizeof( psEnc->state_Fxx[ 1 ].sCmn.In_HP_State ) );\n        }\n    }\n\n    transition = (encControl->payloadSize_ms != psEnc->state_Fxx[ 0 ].sCmn.PacketSize_ms) || (psEnc->nChannelsInternal != encControl->nChannelsInternal);\n\n    psEnc->nChannelsAPI = encControl->nChannelsAPI;\n    psEnc->nChannelsInternal = encControl->nChannelsInternal;\n\n    nBlocksOf10ms = silk_DIV32( 100 * nSamplesIn, encControl->API_sampleRate );\n    tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1;\n    curr_block = 0;\n    if( prefillFlag ) {\n        /* Only accept input length of 10 ms */\n        if( nBlocksOf10ms != 1 ) {\n            silk_assert( 0 );\n            RESTORE_STACK;\n            return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;\n        }\n        /* Reset Encoder */\n        for( n = 0; n < encControl->nChannelsInternal; n++ ) {\n            ret = silk_init_encoder( &psEnc->state_Fxx[ n ], psEnc->state_Fxx[ n ].sCmn.arch );\n            silk_assert( !ret );\n        }\n        tmp_payloadSize_ms = encControl->payloadSize_ms;\n        encControl->payloadSize_ms = 10;\n        tmp_complexity = encControl->complexity;\n        encControl->complexity = 0;\n        for( n = 0; n < encControl->nChannelsInternal; n++ ) {\n            psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;\n            psEnc->state_Fxx[ n ].sCmn.prefillFlag = 1;\n        }\n    } else {\n        /* Only accept input lengths that are a multiple of 10 ms */\n        if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) {\n            silk_assert( 0 );\n            RESTORE_STACK;\n            return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;\n        }\n        /* Make sure no more than one packet can be produced */\n        if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) {\n            silk_assert( 0 );\n            RESTORE_STACK;\n            return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;\n        }\n    }\n\n    TargetRate_bps = silk_RSHIFT32( encControl->bitRate, encControl->nChannelsInternal - 1 );\n    for( n = 0; n < encControl->nChannelsInternal; n++ ) {\n        /* Force the side channel to the same rate as the mid */\n        opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0;\n        if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) {\n            silk_assert( 0 );\n            RESTORE_STACK;\n            return ret;\n        }\n        if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) {\n            for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {\n                psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] = 0;\n            }\n        }\n        psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX;\n    }\n    silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );\n\n    /* Input buffering/resampling and encoding */\n    nSamplesToBufferMax =\n        10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz;\n    nSamplesFromInputMax =\n        silk_DIV32_16( nSamplesToBufferMax *\n                           psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz,\n                       psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );\n    ALLOC( buf, nSamplesFromInputMax, opus_int16 );\n    while( 1 ) {\n        nSamplesToBuffer  = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx;\n        nSamplesToBuffer  = silk_min( nSamplesToBuffer, nSamplesToBufferMax );\n        nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );\n        /* Resample and write to buffer */\n        if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) {\n            opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;\n            for( n = 0; n < nSamplesFromInput; n++ ) {\n                buf[ n ] = samplesIn[ 2 * n ];\n            }\n            /* Making sure to start both resamplers from the same state when switching from mono to stereo */\n            if( psEnc->nPrevChannelsInternal == 1 && id==0 ) {\n               silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state));\n            }\n\n            ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,\n                &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );\n            psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;\n\n            nSamplesToBuffer  = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx;\n            nSamplesToBuffer  = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );\n            for( n = 0; n < nSamplesFromInput; n++ ) {\n                buf[ n ] = samplesIn[ 2 * n + 1 ];\n            }\n            ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,\n                &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );\n\n            psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer;\n        } else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) {\n            /* Combine left and right channels before resampling */\n            for( n = 0; n < nSamplesFromInput; n++ ) {\n                sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ];\n                buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum,  1 );\n            }\n            ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,\n                &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );\n            /* On the first mono frame, average the results for the two resampler states  */\n            if( psEnc->nPrevChannelsInternal == 2 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 ) {\n               ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,\n                   &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );\n               for( n = 0; n < psEnc->state_Fxx[ 0 ].sCmn.frame_length; n++ ) {\n                  psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] =\n                        silk_RSHIFT(psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ]\n                                  + psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1);\n               }\n            }\n            psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;\n        } else {\n            silk_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );\n            silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16));\n            ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,\n                &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );\n            psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;\n        }\n\n        samplesIn  += nSamplesFromInput * encControl->nChannelsAPI;\n        nSamplesIn -= nSamplesFromInput;\n\n        /* Default */\n        psEnc->allowBandwidthSwitch = 0;\n\n        /* Silk encoder */\n        if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) {\n            /* Enough data in input buffer, so encode */\n            silk_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length );\n            silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length );\n\n            /* Deal with LBRR data */\n            if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) {\n                /* Create space at start of payload for VAD and FEC flags */\n                opus_uint8 iCDF[ 2 ] = { 0, 0 };\n                iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );\n                ec_enc_icdf( psRangeEnc, 0, iCDF, 8 );\n\n                /* Encode any LBRR data from previous packet */\n                /* Encode LBRR flags */\n                for( n = 0; n < encControl->nChannelsInternal; n++ ) {\n                    LBRR_symbol = 0;\n                    for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {\n                        LBRR_symbol |= silk_LSHIFT( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ], i );\n                    }\n                    psEnc->state_Fxx[ n ].sCmn.LBRR_flag = LBRR_symbol > 0 ? 1 : 0;\n                    if( LBRR_symbol && psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket > 1 ) {\n                        ec_enc_icdf( psRangeEnc, LBRR_symbol - 1, silk_LBRR_flags_iCDF_ptr[ psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket - 2 ], 8 );\n                    }\n                }\n\n                /* Code LBRR indices and excitation signals */\n                for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {\n                    for( n = 0; n < encControl->nChannelsInternal; n++ ) {\n                        if( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] ) {\n                            opus_int condCoding;\n\n                            if( encControl->nChannelsInternal == 2 && n == 0 ) {\n                                silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ i ] );\n                                /* For LBRR data there's no need to code the mid-only flag if the side-channel LBRR flag is set */\n                                if( psEnc->state_Fxx[ 1 ].sCmn.LBRR_flags[ i ] == 0 ) {\n                                    silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ i ] );\n                                }\n                            }\n                            /* Use conditional coding if previous frame available */\n                            if( i > 0 && psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i - 1 ] ) {\n                                condCoding = CODE_CONDITIONALLY;\n                            } else {\n                                condCoding = CODE_INDEPENDENTLY;\n                            }\n                            silk_encode_indices( &psEnc->state_Fxx[ n ].sCmn, psRangeEnc, i, 1, condCoding );\n                            silk_encode_pulses( psRangeEnc, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].signalType, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].quantOffsetType,\n                                psEnc->state_Fxx[ n ].sCmn.pulses_LBRR[ i ], psEnc->state_Fxx[ n ].sCmn.frame_length );\n                        }\n                    }\n                }\n\n                /* Reset LBRR flags */\n                for( n = 0; n < encControl->nChannelsInternal; n++ ) {\n                    silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) );\n                }\n\n                psEnc->nBitsUsedLBRR = ec_tell( psRangeEnc );\n            }\n\n            silk_HP_variable_cutoff( psEnc->state_Fxx );\n\n            /* Total target bits for packet */\n            nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );\n            /* Subtract bits used for LBRR */\n            if( !prefillFlag ) {\n                nBits -= psEnc->nBitsUsedLBRR;\n            }\n            /* Divide by number of uncoded frames left in packet */\n            nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket );\n            /* Convert to bits/second */\n            if( encControl->payloadSize_ms == 10 ) {\n                TargetRate_bps = silk_SMULBB( nBits, 100 );\n            } else {\n                TargetRate_bps = silk_SMULBB( nBits, 50 );\n            }\n            /* Subtract fraction of bits in excess of target in previous frames and packets */\n            TargetRate_bps -= silk_DIV32_16( silk_MUL( psEnc->nBitsExceeded, 1000 ), BITRESERVOIR_DECAY_TIME_MS );\n            if( !prefillFlag && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded > 0 ) {\n                /* Compare actual vs target bits so far in this packet */\n                opus_int32 bitsBalance = ec_tell( psRangeEnc ) - psEnc->nBitsUsedLBRR - nBits * psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;\n                TargetRate_bps -= silk_DIV32_16( silk_MUL( bitsBalance, 1000 ), BITRESERVOIR_DECAY_TIME_MS );\n            }\n            /* Never exceed input bitrate */\n            TargetRate_bps = silk_LIMIT( TargetRate_bps, encControl->bitRate, 5000 );\n\n            /* Convert Left/Right to Mid/Side */\n            if( encControl->nChannelsInternal == 2 ) {\n                silk_stereo_LR_to_MS( &psEnc->sStereo, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ 2 ], &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ 2 ],\n                    psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], &psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ],\n                    MStargetRates_bps, TargetRate_bps, psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8, encControl->toMono,\n                    psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, psEnc->state_Fxx[ 0 ].sCmn.frame_length );\n                if( psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {\n                    /* Reset side channel encoder memory for first frame with side coding */\n                    if( psEnc->prev_decode_only_middle == 1 ) {\n                        silk_memset( &psEnc->state_Fxx[ 1 ].sShape,               0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) );\n                        silk_memset( &psEnc->state_Fxx[ 1 ].sPrefilt,             0, sizeof( psEnc->state_Fxx[ 1 ].sPrefilt ) );\n                        silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ,            0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) );\n                        silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15,   0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) );\n                        silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) );\n                        psEnc->state_Fxx[ 1 ].sCmn.prevLag                 = 100;\n                        psEnc->state_Fxx[ 1 ].sCmn.sNSQ.lagPrev            = 100;\n                        psEnc->state_Fxx[ 1 ].sShape.LastGainIndex         = 10;\n                        psEnc->state_Fxx[ 1 ].sCmn.prevSignalType          = TYPE_NO_VOICE_ACTIVITY;\n                        psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16      = 65536;\n                        psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1;\n                    }\n                    silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ] );\n                } else {\n                    psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0;\n                }\n                if( !prefillFlag ) {\n                    silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );\n                    if( psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {\n                        silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );\n                    }\n                }\n            } else {\n                /* Buffering */\n                silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) );\n                silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) );\n            }\n            silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ] );\n\n            /* Encode */\n            for( n = 0; n < encControl->nChannelsInternal; n++ ) {\n                opus_int maxBits, useCBR;\n\n                /* Handling rate constraints */\n                maxBits = encControl->maxBits;\n                if( tot_blocks == 2 && curr_block == 0 ) {\n                    maxBits = maxBits * 3 / 5;\n                } else if( tot_blocks == 3 ) {\n                    if( curr_block == 0 ) {\n                        maxBits = maxBits * 2 / 5;\n                    } else if( curr_block == 1 ) {\n                        maxBits = maxBits * 3 / 4;\n                    }\n                }\n                useCBR = encControl->useCBR && curr_block == tot_blocks - 1;\n\n                if( encControl->nChannelsInternal == 1 ) {\n                    channelRate_bps = TargetRate_bps;\n                } else {\n                    channelRate_bps = MStargetRates_bps[ n ];\n                    if( n == 0 && MStargetRates_bps[ 1 ] > 0 ) {\n                        useCBR = 0;\n                        /* Give mid up to 1/2 of the max bits for that frame */\n                        maxBits -= encControl->maxBits / ( tot_blocks * 2 );\n                    }\n                }\n\n                if( channelRate_bps > 0 ) {\n                    opus_int condCoding;\n\n                    silk_control_SNR( &psEnc->state_Fxx[ n ].sCmn, channelRate_bps );\n\n                    /* Use independent coding if no previous frame available */\n                    if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - n <= 0 ) {\n                        condCoding = CODE_INDEPENDENTLY;\n                    } else if( n > 0 && psEnc->prev_decode_only_middle ) {\n                        /* If we skipped a side frame in this packet, we don't\n                           need LTP scaling; the LTP state is well-defined. */\n                        condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING;\n                    } else {\n                        condCoding = CODE_CONDITIONALLY;\n                    }\n                    if( ( ret = silk_encode_frame_Fxx( &psEnc->state_Fxx[ n ], nBytesOut, psRangeEnc, condCoding, maxBits, useCBR ) ) != 0 ) {\n                        silk_assert( 0 );\n                    }\n                }\n                psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;\n                psEnc->state_Fxx[ n ].sCmn.inputBufIx = 0;\n                psEnc->state_Fxx[ n ].sCmn.nFramesEncoded++;\n            }\n            psEnc->prev_decode_only_middle = psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - 1 ];\n\n            /* Insert VAD and FEC flags at beginning of bitstream */\n            if( *nBytesOut > 0 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket) {\n                flags = 0;\n                for( n = 0; n < encControl->nChannelsInternal; n++ ) {\n                    for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {\n                        flags  = silk_LSHIFT( flags, 1 );\n                        flags |= psEnc->state_Fxx[ n ].sCmn.VAD_flags[ i ];\n                    }\n                    flags  = silk_LSHIFT( flags, 1 );\n                    flags |= psEnc->state_Fxx[ n ].sCmn.LBRR_flag;\n                }\n                if( !prefillFlag ) {\n                    ec_enc_patch_initial_bits( psRangeEnc, flags, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );\n                }\n\n                /* Return zero bytes if all channels DTXed */\n                if( psEnc->state_Fxx[ 0 ].sCmn.inDTX && ( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inDTX ) ) {\n                    *nBytesOut = 0;\n                }\n\n                psEnc->nBitsExceeded += *nBytesOut * 8;\n                psEnc->nBitsExceeded -= silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );\n                psEnc->nBitsExceeded  = silk_LIMIT( psEnc->nBitsExceeded, 0, 10000 );\n\n                /* Update flag indicating if bandwidth switching is allowed */\n                speech_act_thr_for_switch_Q8 = silk_SMLAWB( SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ),\n                    SILK_FIX_CONST( ( 1 - SPEECH_ACTIVITY_DTX_THRES ) / MAX_BANDWIDTH_SWITCH_DELAY_MS, 16 + 8 ), psEnc->timeSinceSwitchAllowed_ms );\n                if( psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 ) {\n                    psEnc->allowBandwidthSwitch = 1;\n                    psEnc->timeSinceSwitchAllowed_ms = 0;\n                } else {\n                    psEnc->allowBandwidthSwitch = 0;\n                    psEnc->timeSinceSwitchAllowed_ms += encControl->payloadSize_ms;\n                }\n            }\n\n            if( nSamplesIn == 0 ) {\n                break;\n            }\n        } else {\n            break;\n        }\n        curr_block++;\n    }\n\n    psEnc->nPrevChannelsInternal = encControl->nChannelsInternal;\n\n    encControl->allowBandwidthSwitch = psEnc->allowBandwidthSwitch;\n    encControl->inWBmodeWithoutVariableLP = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == 16 && psEnc->state_Fxx[ 0 ].sCmn.sLP.mode == 0;\n    encControl->internalSampleRate = silk_SMULBB( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );\n    encControl->stereoWidth_Q14 = encControl->toMono ? 0 : psEnc->sStereo.smth_width_Q14;\n    if( prefillFlag ) {\n        encControl->payloadSize_ms = tmp_payloadSize_ms;\n        encControl->complexity = tmp_complexity;\n        for( n = 0; n < encControl->nChannelsInternal; n++ ) {\n            psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;\n            psEnc->state_Fxx[ n ].sCmn.prefillFlag = 0;\n        }\n    }\n\n    RESTORE_STACK;\n    return ret;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/encode_indices.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Encode side-information parameters to payload */\nvoid silk_encode_indices(\n    silk_encoder_state          *psEncC,                        /* I/O  Encoder state                               */\n    ec_enc                      *psRangeEnc,                    /* I/O  Compressor data structure                   */\n    opus_int                    FrameIndex,                     /* I    Frame number                                */\n    opus_int                    encode_LBRR,                    /* I    Flag indicating LBRR data is being encoded  */\n    opus_int                    condCoding                      /* I    The type of conditional coding to use       */\n)\n{\n    opus_int   i, k, typeOffset;\n    opus_int   encode_absolute_lagIndex, delta_lagIndex;\n    opus_int16 ec_ix[ MAX_LPC_ORDER ];\n    opus_uint8 pred_Q8[ MAX_LPC_ORDER ];\n    const SideInfoIndices *psIndices;\n\n    if( encode_LBRR ) {\n         psIndices = &psEncC->indices_LBRR[ FrameIndex ];\n    } else {\n         psIndices = &psEncC->indices;\n    }\n\n    /*******************************************/\n    /* Encode signal type and quantizer offset */\n    /*******************************************/\n    typeOffset = 2 * psIndices->signalType + psIndices->quantOffsetType;\n    silk_assert( typeOffset >= 0 && typeOffset < 6 );\n    silk_assert( encode_LBRR == 0 || typeOffset >= 2 );\n    if( encode_LBRR || typeOffset >= 2 ) {\n        ec_enc_icdf( psRangeEnc, typeOffset - 2, silk_type_offset_VAD_iCDF, 8 );\n    } else {\n        ec_enc_icdf( psRangeEnc, typeOffset, silk_type_offset_no_VAD_iCDF, 8 );\n    }\n\n    /****************/\n    /* Encode gains */\n    /****************/\n    /* first subframe */\n    if( condCoding == CODE_CONDITIONALLY ) {\n        /* conditional coding */\n        silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 );\n        ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ], silk_delta_gain_iCDF, 8 );\n    } else {\n        /* independent coding, in two stages: MSB bits followed by 3 LSBs */\n        silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < N_LEVELS_QGAIN );\n        ec_enc_icdf( psRangeEnc, silk_RSHIFT( psIndices->GainsIndices[ 0 ], 3 ), silk_gain_iCDF[ psIndices->signalType ], 8 );\n        ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ] & 7, silk_uniform8_iCDF, 8 );\n    }\n\n    /* remaining subframes */\n    for( i = 1; i < psEncC->nb_subfr; i++ ) {\n        silk_assert( psIndices->GainsIndices[ i ] >= 0 && psIndices->GainsIndices[ i ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 );\n        ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ i ], silk_delta_gain_iCDF, 8 );\n    }\n\n    /****************/\n    /* Encode NLSFs */\n    /****************/\n    ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ 0 ], &psEncC->psNLSF_CB->CB1_iCDF[ ( psIndices->signalType >> 1 ) * psEncC->psNLSF_CB->nVectors ], 8 );\n    silk_NLSF_unpack( ec_ix, pred_Q8, psEncC->psNLSF_CB, psIndices->NLSFIndices[ 0 ] );\n    silk_assert( psEncC->psNLSF_CB->order == psEncC->predictLPCOrder );\n    for( i = 0; i < psEncC->psNLSF_CB->order; i++ ) {\n        if( psIndices->NLSFIndices[ i+1 ] >= NLSF_QUANT_MAX_AMPLITUDE ) {\n            ec_enc_icdf( psRangeEnc, 2 * NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );\n            ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 );\n        } else if( psIndices->NLSFIndices[ i+1 ] <= -NLSF_QUANT_MAX_AMPLITUDE ) {\n            ec_enc_icdf( psRangeEnc, 0, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );\n            ec_enc_icdf( psRangeEnc, -psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 );\n        } else {\n            ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] + NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );\n        }\n    }\n\n    /* Encode NLSF interpolation factor */\n    if( psEncC->nb_subfr == MAX_NB_SUBFR ) {\n        silk_assert( psIndices->NLSFInterpCoef_Q2 >= 0 && psIndices->NLSFInterpCoef_Q2 < 5 );\n        ec_enc_icdf( psRangeEnc, psIndices->NLSFInterpCoef_Q2, silk_NLSF_interpolation_factor_iCDF, 8 );\n    }\n\n    if( psIndices->signalType == TYPE_VOICED )\n    {\n        /*********************/\n        /* Encode pitch lags */\n        /*********************/\n        /* lag index */\n        encode_absolute_lagIndex = 1;\n        if( condCoding == CODE_CONDITIONALLY && psEncC->ec_prevSignalType == TYPE_VOICED ) {\n            /* Delta Encoding */\n            delta_lagIndex = psIndices->lagIndex - psEncC->ec_prevLagIndex;\n            if( delta_lagIndex < -8 || delta_lagIndex > 11 ) {\n                delta_lagIndex = 0;\n            } else {\n                delta_lagIndex = delta_lagIndex + 9;\n                encode_absolute_lagIndex = 0; /* Only use delta */\n            }\n            silk_assert( delta_lagIndex >= 0 && delta_lagIndex < 21 );\n            ec_enc_icdf( psRangeEnc, delta_lagIndex, silk_pitch_delta_iCDF, 8 );\n        }\n        if( encode_absolute_lagIndex ) {\n            /* Absolute encoding */\n            opus_int32 pitch_high_bits, pitch_low_bits;\n            pitch_high_bits = silk_DIV32_16( psIndices->lagIndex, silk_RSHIFT( psEncC->fs_kHz, 1 ) );\n            pitch_low_bits = psIndices->lagIndex - silk_SMULBB( pitch_high_bits, silk_RSHIFT( psEncC->fs_kHz, 1 ) );\n            silk_assert( pitch_low_bits < psEncC->fs_kHz / 2 );\n            silk_assert( pitch_high_bits < 32 );\n            ec_enc_icdf( psRangeEnc, pitch_high_bits, silk_pitch_lag_iCDF, 8 );\n            ec_enc_icdf( psRangeEnc, pitch_low_bits, psEncC->pitch_lag_low_bits_iCDF, 8 );\n        }\n        psEncC->ec_prevLagIndex = psIndices->lagIndex;\n\n        /* Countour index */\n        silk_assert(   psIndices->contourIndex  >= 0 );\n        silk_assert( ( psIndices->contourIndex < 34 && psEncC->fs_kHz  > 8 && psEncC->nb_subfr == 4 ) ||\n                    ( psIndices->contourIndex < 11 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 4 ) ||\n                    ( psIndices->contourIndex < 12 && psEncC->fs_kHz  > 8 && psEncC->nb_subfr == 2 ) ||\n                    ( psIndices->contourIndex <  3 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 2 ) );\n        ec_enc_icdf( psRangeEnc, psIndices->contourIndex, psEncC->pitch_contour_iCDF, 8 );\n\n        /********************/\n        /* Encode LTP gains */\n        /********************/\n        /* PERIndex value */\n        silk_assert( psIndices->PERIndex >= 0 && psIndices->PERIndex < 3 );\n        ec_enc_icdf( psRangeEnc, psIndices->PERIndex, silk_LTP_per_index_iCDF, 8 );\n\n        /* Codebook Indices */\n        for( k = 0; k < psEncC->nb_subfr; k++ ) {\n            silk_assert( psIndices->LTPIndex[ k ] >= 0 && psIndices->LTPIndex[ k ] < ( 8 << psIndices->PERIndex ) );\n            ec_enc_icdf( psRangeEnc, psIndices->LTPIndex[ k ], silk_LTP_gain_iCDF_ptrs[ psIndices->PERIndex ], 8 );\n        }\n\n        /**********************/\n        /* Encode LTP scaling */\n        /**********************/\n        if( condCoding == CODE_INDEPENDENTLY ) {\n            silk_assert( psIndices->LTP_scaleIndex >= 0 && psIndices->LTP_scaleIndex < 3 );\n            ec_enc_icdf( psRangeEnc, psIndices->LTP_scaleIndex, silk_LTPscale_iCDF, 8 );\n        }\n        silk_assert( !condCoding || psIndices->LTP_scaleIndex == 0 );\n    }\n\n    psEncC->ec_prevSignalType = psIndices->signalType;\n\n    /***************/\n    /* Encode seed */\n    /***************/\n    silk_assert( psIndices->Seed >= 0 && psIndices->Seed < 4 );\n    ec_enc_icdf( psRangeEnc, psIndices->Seed, silk_uniform4_iCDF, 8 );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/encode_pulses.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"stack_alloc.h\"\n\n/*********************************************/\n/* Encode quantization indices of excitation */\n/*********************************************/\n\nstatic OPUS_INLINE opus_int combine_and_check(    /* return ok                           */\n    opus_int         *pulses_comb,           /* O                                   */\n    const opus_int   *pulses_in,             /* I                                   */\n    opus_int         max_pulses,             /* I    max value for sum of pulses    */\n    opus_int         len                     /* I    number of output values        */\n)\n{\n    opus_int k, sum;\n\n    for( k = 0; k < len; k++ ) {\n        sum = pulses_in[ 2 * k ] + pulses_in[ 2 * k + 1 ];\n        if( sum > max_pulses ) {\n            return 1;\n        }\n        pulses_comb[ k ] = sum;\n    }\n\n    return 0;\n}\n\n/* Encode quantization indices of excitation */\nvoid silk_encode_pulses(\n    ec_enc                      *psRangeEnc,                    /* I/O  compressor data structure                   */\n    const opus_int              signalType,                     /* I    Signal type                                 */\n    const opus_int              quantOffsetType,                /* I    quantOffsetType                             */\n    opus_int8                   pulses[],                       /* I    quantization indices                        */\n    const opus_int              frame_length                    /* I    Frame length                                */\n)\n{\n    opus_int   i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0;\n    opus_int32 abs_q, minSumBits_Q5, sumBits_Q5;\n    VARDECL( opus_int, abs_pulses );\n    VARDECL( opus_int, sum_pulses );\n    VARDECL( opus_int, nRshifts );\n    opus_int   pulses_comb[ 8 ];\n    opus_int   *abs_pulses_ptr;\n    const opus_int8 *pulses_ptr;\n    const opus_uint8 *cdf_ptr;\n    const opus_uint8 *nBits_ptr;\n    SAVE_STACK;\n\n    silk_memset( pulses_comb, 0, 8 * sizeof( opus_int ) ); /* Fixing Valgrind reported problem*/\n\n    /****************************/\n    /* Prepare for shell coding */\n    /****************************/\n    /* Calculate number of shell blocks */\n    silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH );\n    iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH );\n    if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) {\n        silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */\n        iter++;\n        silk_memset( &pulses[ frame_length ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof(opus_int8));\n    }\n\n    /* Take the absolute value of the pulses */\n    ALLOC( abs_pulses, iter * SHELL_CODEC_FRAME_LENGTH, opus_int );\n    silk_assert( !( SHELL_CODEC_FRAME_LENGTH & 3 ) );\n    for( i = 0; i < iter * SHELL_CODEC_FRAME_LENGTH; i+=4 ) {\n        abs_pulses[i+0] = ( opus_int )silk_abs( pulses[ i + 0 ] );\n        abs_pulses[i+1] = ( opus_int )silk_abs( pulses[ i + 1 ] );\n        abs_pulses[i+2] = ( opus_int )silk_abs( pulses[ i + 2 ] );\n        abs_pulses[i+3] = ( opus_int )silk_abs( pulses[ i + 3 ] );\n    }\n\n    /* Calc sum pulses per shell code frame */\n    ALLOC( sum_pulses, iter, opus_int );\n    ALLOC( nRshifts, iter, opus_int );\n    abs_pulses_ptr = abs_pulses;\n    for( i = 0; i < iter; i++ ) {\n        nRshifts[ i ] = 0;\n\n        while( 1 ) {\n            /* 1+1 -> 2 */\n            scale_down = combine_and_check( pulses_comb, abs_pulses_ptr, silk_max_pulses_table[ 0 ], 8 );\n            /* 2+2 -> 4 */\n            scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 1 ], 4 );\n            /* 4+4 -> 8 */\n            scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 2 ], 2 );\n            /* 8+8 -> 16 */\n            scale_down += combine_and_check( &sum_pulses[ i ], pulses_comb, silk_max_pulses_table[ 3 ], 1 );\n\n            if( scale_down ) {\n                /* We need to downscale the quantization signal */\n                nRshifts[ i ]++;\n                for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {\n                    abs_pulses_ptr[ k ] = silk_RSHIFT( abs_pulses_ptr[ k ], 1 );\n                }\n            } else {\n                /* Jump out of while(1) loop and go to next shell coding frame */\n                break;\n            }\n        }\n        abs_pulses_ptr += SHELL_CODEC_FRAME_LENGTH;\n    }\n\n    /**************/\n    /* Rate level */\n    /**************/\n    /* find rate level that leads to fewest bits for coding of pulses per block info */\n    minSumBits_Q5 = silk_int32_MAX;\n    for( k = 0; k < N_RATE_LEVELS - 1; k++ ) {\n        nBits_ptr  = silk_pulses_per_block_BITS_Q5[ k ];\n        sumBits_Q5 = silk_rate_levels_BITS_Q5[ signalType >> 1 ][ k ];\n        for( i = 0; i < iter; i++ ) {\n            if( nRshifts[ i ] > 0 ) {\n                sumBits_Q5 += nBits_ptr[ SILK_MAX_PULSES + 1 ];\n            } else {\n                sumBits_Q5 += nBits_ptr[ sum_pulses[ i ] ];\n            }\n        }\n        if( sumBits_Q5 < minSumBits_Q5 ) {\n            minSumBits_Q5 = sumBits_Q5;\n            RateLevelIndex = k;\n        }\n    }\n    ec_enc_icdf( psRangeEnc, RateLevelIndex, silk_rate_levels_iCDF[ signalType >> 1 ], 8 );\n\n    /***************************************************/\n    /* Sum-Weighted-Pulses Encoding                    */\n    /***************************************************/\n    cdf_ptr = silk_pulses_per_block_iCDF[ RateLevelIndex ];\n    for( i = 0; i < iter; i++ ) {\n        if( nRshifts[ i ] == 0 ) {\n            ec_enc_icdf( psRangeEnc, sum_pulses[ i ], cdf_ptr, 8 );\n        } else {\n            ec_enc_icdf( psRangeEnc, SILK_MAX_PULSES + 1, cdf_ptr, 8 );\n            for( k = 0; k < nRshifts[ i ] - 1; k++ ) {\n                ec_enc_icdf( psRangeEnc, SILK_MAX_PULSES + 1, silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 );\n            }\n            ec_enc_icdf( psRangeEnc, sum_pulses[ i ], silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 );\n        }\n    }\n\n    /******************/\n    /* Shell Encoding */\n    /******************/\n    for( i = 0; i < iter; i++ ) {\n        if( sum_pulses[ i ] > 0 ) {\n            silk_shell_encoder( psRangeEnc, &abs_pulses[ i * SHELL_CODEC_FRAME_LENGTH ] );\n        }\n    }\n\n    /****************/\n    /* LSB Encoding */\n    /****************/\n    for( i = 0; i < iter; i++ ) {\n        if( nRshifts[ i ] > 0 ) {\n            pulses_ptr = &pulses[ i * SHELL_CODEC_FRAME_LENGTH ];\n            nLS = nRshifts[ i ] - 1;\n            for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {\n                abs_q = (opus_int8)silk_abs( pulses_ptr[ k ] );\n                for( j = nLS; j > 0; j-- ) {\n                    bit = silk_RSHIFT( abs_q, j ) & 1;\n                    ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 );\n                }\n                bit = abs_q & 1;\n                ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 );\n            }\n        }\n    }\n\n    /****************/\n    /* Encode signs */\n    /****************/\n    silk_encode_signs( psRangeEnc, pulses, frame_length, signalType, quantOffsetType, sum_pulses );\n    RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/errors.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_ERRORS_H\n#define SILK_ERRORS_H\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/******************/\n/* Error messages */\n/******************/\n#define SILK_NO_ERROR                               0\n\n/**************************/\n/* Encoder error messages */\n/**************************/\n\n/* Input length is not a multiple of 10 ms, or length is longer than the packet length */\n#define SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES        -101\n\n/* Sampling frequency not 8000, 12000 or 16000 Hertz */\n#define SILK_ENC_FS_NOT_SUPPORTED                   -102\n\n/* Packet size not 10, 20, 40, or 60 ms */\n#define SILK_ENC_PACKET_SIZE_NOT_SUPPORTED          -103\n\n/* Allocated payload buffer too short */\n#define SILK_ENC_PAYLOAD_BUF_TOO_SHORT              -104\n\n/* Loss rate not between 0 and 100 percent */\n#define SILK_ENC_INVALID_LOSS_RATE                  -105\n\n/* Complexity setting not valid, use 0...10 */\n#define SILK_ENC_INVALID_COMPLEXITY_SETTING         -106\n\n/* Inband FEC setting not valid, use 0 or 1 */\n#define SILK_ENC_INVALID_INBAND_FEC_SETTING         -107\n\n/* DTX setting not valid, use 0 or 1 */\n#define SILK_ENC_INVALID_DTX_SETTING                -108\n\n/* CBR setting not valid, use 0 or 1 */\n#define SILK_ENC_INVALID_CBR_SETTING                -109\n\n/* Internal encoder error */\n#define SILK_ENC_INTERNAL_ERROR                     -110\n\n/* Internal encoder error */\n#define SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR   -111\n\n/**************************/\n/* Decoder error messages */\n/**************************/\n\n/* Output sampling frequency lower than internal decoded sampling frequency */\n#define SILK_DEC_INVALID_SAMPLING_FREQUENCY         -200\n\n/* Payload size exceeded the maximum allowed 1024 bytes */\n#define SILK_DEC_PAYLOAD_TOO_LARGE                  -201\n\n/* Payload has bit errors */\n#define SILK_DEC_PAYLOAD_ERROR                      -202\n\n/* Payload has bit errors */\n#define SILK_DEC_INVALID_FRAME_SIZE                 -203\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/LTP_analysis_filter_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n\nvoid silk_LTP_analysis_filter_FIX(\n    opus_int16                      *LTP_res,                               /* O    LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length )  */\n    const opus_int16                *x,                                     /* I    Pointer to input signal with at least max( pitchL ) preceding samples       */\n    const opus_int16                LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I    LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe                   */\n    const opus_int                  pitchL[ MAX_NB_SUBFR ],                 /* I    Pitch lag, one for each subframe                                            */\n    const opus_int32                invGains_Q16[ MAX_NB_SUBFR ],           /* I    Inverse quantization gains, one for each subframe                           */\n    const opus_int                  subfr_length,                           /* I    Length of each subframe                                                     */\n    const opus_int                  nb_subfr,                               /* I    Number of subframes                                                         */\n    const opus_int                  pre_length                              /* I    Length of the preceding samples starting at &x[0] for each subframe         */\n)\n{\n    const opus_int16 *x_ptr, *x_lag_ptr;\n    opus_int16   Btmp_Q14[ LTP_ORDER ];\n    opus_int16   *LTP_res_ptr;\n    opus_int     k, i;\n    opus_int32   LTP_est;\n\n    x_ptr = x;\n    LTP_res_ptr = LTP_res;\n    for( k = 0; k < nb_subfr; k++ ) {\n\n        x_lag_ptr = x_ptr - pitchL[ k ];\n\n        Btmp_Q14[ 0 ] = LTPCoef_Q14[ k * LTP_ORDER ];\n        Btmp_Q14[ 1 ] = LTPCoef_Q14[ k * LTP_ORDER + 1 ];\n        Btmp_Q14[ 2 ] = LTPCoef_Q14[ k * LTP_ORDER + 2 ];\n        Btmp_Q14[ 3 ] = LTPCoef_Q14[ k * LTP_ORDER + 3 ];\n        Btmp_Q14[ 4 ] = LTPCoef_Q14[ k * LTP_ORDER + 4 ];\n\n        /* LTP analysis FIR filter */\n        for( i = 0; i < subfr_length + pre_length; i++ ) {\n            LTP_res_ptr[ i ] = x_ptr[ i ];\n\n            /* Long-term prediction */\n            LTP_est = silk_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] );\n            LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 1 ], Btmp_Q14[ 1 ] );\n            LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 0 ], Btmp_Q14[ 2 ] );\n            LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -1 ], Btmp_Q14[ 3 ] );\n            LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -2 ], Btmp_Q14[ 4 ] );\n\n            LTP_est = silk_RSHIFT_ROUND( LTP_est, 14 ); /* round and -> Q0*/\n\n            /* Subtract long-term prediction */\n            LTP_res_ptr[ i ] = (opus_int16)silk_SAT16( (opus_int32)x_ptr[ i ] - LTP_est );\n\n            /* Scale residual */\n            LTP_res_ptr[ i ] = silk_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] );\n\n            x_lag_ptr++;\n        }\n\n        /* Update pointers */\n        LTP_res_ptr += subfr_length + pre_length;\n        x_ptr       += subfr_length;\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/LTP_scale_ctrl_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n\n/* Calculation of LTP state scaling */\nvoid silk_LTP_scale_ctrl_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  encoder state                                                               */\n    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  encoder control                                                             */\n    opus_int                        condCoding                              /* I    The type of conditional coding to use                                       */\n)\n{\n    opus_int round_loss;\n\n    if( condCoding == CODE_INDEPENDENTLY ) {\n        /* Only scale if first frame in packet */\n        round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;\n        psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT(\n            silk_SMULWB( silk_SMULBB( round_loss, psEncCtrl->LTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 );\n    } else {\n        /* Default is minimum scaling */\n        psEnc->sCmn.indices.LTP_scaleIndex = 0;\n    }\n    psEncCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ];\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/apply_sine_window_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n\n/* Apply sine window to signal vector.                                      */\n/* Window types:                                                            */\n/*    1 -> sine window from 0 to pi/2                                       */\n/*    2 -> sine window from pi/2 to pi                                      */\n/* Every other sample is linearly interpolated, for speed.                  */\n/* Window length must be between 16 and 120 (incl) and a multiple of 4.     */\n\n/* Matlab code for table:\n   for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\\n'); end\n*/\nstatic const opus_int16 freq_table_Q16[ 27 ] = {\n   12111,    9804,    8235,    7100,    6239,    5565,    5022,    4575,    4202,\n    3885,    3612,    3375,    3167,    2984,    2820,    2674,    2542,    2422,\n    2313,    2214,    2123,    2038,    1961,    1889,    1822,    1760,    1702,\n};\n\nvoid silk_apply_sine_window(\n    opus_int16                  px_win[],           /* O    Pointer to windowed signal                                  */\n    const opus_int16            px[],               /* I    Pointer to input signal                                     */\n    const opus_int              win_type,           /* I    Selects a window type                                       */\n    const opus_int              length              /* I    Window length, multiple of 4                                */\n)\n{\n    opus_int   k, f_Q16, c_Q16;\n    opus_int32 S0_Q16, S1_Q16;\n\n    silk_assert( win_type == 1 || win_type == 2 );\n\n    /* Length must be in a range from 16 to 120 and a multiple of 4 */\n    silk_assert( length >= 16 && length <= 120 );\n    silk_assert( ( length & 3 ) == 0 );\n\n    /* Frequency */\n    k = ( length >> 2 ) - 4;\n    silk_assert( k >= 0 && k <= 26 );\n    f_Q16 = (opus_int)freq_table_Q16[ k ];\n\n    /* Factor used for cosine approximation */\n    c_Q16 = silk_SMULWB( (opus_int32)f_Q16, -f_Q16 );\n    silk_assert( c_Q16 >= -32768 );\n\n    /* initialize state */\n    if( win_type == 1 ) {\n        /* start from 0 */\n        S0_Q16 = 0;\n        /* approximation of sin(f) */\n        S1_Q16 = f_Q16 + silk_RSHIFT( length, 3 );\n    } else {\n        /* start from 1 */\n        S0_Q16 = ( (opus_int32)1 << 16 );\n        /* approximation of cos(f) */\n        S1_Q16 = ( (opus_int32)1 << 16 ) + silk_RSHIFT( c_Q16, 1 ) + silk_RSHIFT( length, 4 );\n    }\n\n    /* Uses the recursive equation:   sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f)    */\n    /* 4 samples at a time */\n    for( k = 0; k < length; k += 4 ) {\n        px_win[ k ]     = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] );\n        px_win[ k + 1 ] = (opus_int16)silk_SMULWB( S1_Q16, px[ k + 1] );\n        S0_Q16 = silk_SMULWB( S1_Q16, c_Q16 ) + silk_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1;\n        S0_Q16 = silk_min( S0_Q16, ( (opus_int32)1 << 16 ) );\n\n        px_win[ k + 2 ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] );\n        px_win[ k + 3 ] = (opus_int16)silk_SMULWB( S0_Q16, px[ k + 3 ] );\n        S1_Q16 = silk_SMULWB( S0_Q16, c_Q16 ) + silk_LSHIFT( S0_Q16, 1 ) - S1_Q16;\n        S1_Q16 = silk_min( S1_Q16, ( (opus_int32)1 << 16 ) );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/autocorr_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n#include \"celt_lpc.h\"\n\n/* Compute autocorrelation */\nvoid silk_autocorr(\n    opus_int32                  *results,           /* O    Result (length correlationCount)                            */\n    opus_int                    *scale,             /* O    Scaling of the correlation vector                           */\n    const opus_int16            *inputData,         /* I    Input data to correlate                                     */\n    const opus_int              inputDataSize,      /* I    Length of input                                             */\n    const opus_int              correlationCount,   /* I    Number of correlation taps to compute                       */\n    int                         arch                /* I    Run-time architecture                                       */\n)\n{\n    opus_int   corrCount;\n    corrCount = silk_min_int( inputDataSize, correlationCount );\n    *scale = _celt_autocorr(inputData, results, NULL, 0, corrCount-1, inputDataSize, arch);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/burg_modified_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n#include \"define.h\"\n#include \"tuning_parameters.h\"\n#include \"pitch.h\"\n\n#define MAX_FRAME_SIZE              384             /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */\n\n#define QA                          25\n#define N_BITS_HEAD_ROOM            2\n#define MIN_RSHIFTS                 -16\n#define MAX_RSHIFTS                 (32 - QA)\n\n/* Compute reflection coefficients from input signal */\nvoid silk_burg_modified_c(\n    opus_int32                  *res_nrg,           /* O    Residual energy                                             */\n    opus_int                    *res_nrg_Q,         /* O    Residual energy Q value                                     */\n    opus_int32                  A_Q16[],            /* O    Prediction coefficients (length order)                      */\n    const opus_int16            x[],                /* I    Input signal, length: nb_subfr * ( D + subfr_length )       */\n    const opus_int32            minInvGain_Q30,     /* I    Inverse of max prediction gain                              */\n    const opus_int              subfr_length,       /* I    Input signal subframe length (incl. D preceding samples)    */\n    const opus_int              nb_subfr,           /* I    Number of subframes stacked in x                            */\n    const opus_int              D,                  /* I    Order                                                       */\n    int                         arch                /* I    Run-time architecture                                       */\n)\n{\n    opus_int         k, n, s, lz, rshifts, reached_max_gain;\n    opus_int32       C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;\n    const opus_int16 *x_ptr;\n    opus_int32       C_first_row[ SILK_MAX_ORDER_LPC ];\n    opus_int32       C_last_row[  SILK_MAX_ORDER_LPC ];\n    opus_int32       Af_QA[       SILK_MAX_ORDER_LPC ];\n    opus_int32       CAf[ SILK_MAX_ORDER_LPC + 1 ];\n    opus_int32       CAb[ SILK_MAX_ORDER_LPC + 1 ];\n    opus_int32       xcorr[ SILK_MAX_ORDER_LPC ];\n    opus_int64       C0_64;\n\n    silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );\n\n    /* Compute autocorrelations, added over subframes */\n    C0_64 = silk_inner_prod16_aligned_64( x, x, subfr_length*nb_subfr, arch );\n    lz = silk_CLZ64(C0_64);\n    rshifts = 32 + 1 + N_BITS_HEAD_ROOM - lz;\n    if (rshifts > MAX_RSHIFTS) rshifts = MAX_RSHIFTS;\n    if (rshifts < MIN_RSHIFTS) rshifts = MIN_RSHIFTS;\n\n    if (rshifts > 0) {\n        C0 = (opus_int32)silk_RSHIFT64(C0_64, rshifts );\n    } else {\n        C0 = silk_LSHIFT32((opus_int32)C0_64, -rshifts );\n    }\n\n    CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1;                                /* Q(-rshifts) */\n    silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );\n    if( rshifts > 0 ) {\n        for( s = 0; s < nb_subfr; s++ ) {\n            x_ptr = x + s * subfr_length;\n            for( n = 1; n < D + 1; n++ ) {\n                C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64(\n                    silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts );\n            }\n        }\n    } else {\n        for( s = 0; s < nb_subfr; s++ ) {\n            int i;\n            opus_int32 d;\n            x_ptr = x + s * subfr_length;\n            celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch );\n            for( n = 1; n < D + 1; n++ ) {\n               for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ )\n                  d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] );\n               xcorr[ n - 1 ] += d;\n            }\n            for( n = 1; n < D + 1; n++ ) {\n                C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts );\n            }\n        }\n    }\n    silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );\n\n    /* Initialize */\n    CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1;                                /* Q(-rshifts) */\n\n    invGain_Q30 = (opus_int32)1 << 30;\n    reached_max_gain = 0;\n    for( n = 0; n < D; n++ ) {\n        /* Update first row of correlation matrix (without first element) */\n        /* Update last row of correlation matrix (without last element, stored in reversed order) */\n        /* Update C * Af */\n        /* Update C * flipud(Af) (stored in reversed order) */\n        if( rshifts > -2 ) {\n            for( s = 0; s < nb_subfr; s++ ) {\n                x_ptr = x + s * subfr_length;\n                x1  = -silk_LSHIFT32( (opus_int32)x_ptr[ n ],                    16 - rshifts );        /* Q(16-rshifts) */\n                x2  = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts );        /* Q(16-rshifts) */\n                tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ],                    QA - 16 );             /* Q(QA-16) */\n                tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 );             /* Q(QA-16) */\n                for( k = 0; k < n; k++ ) {\n                    C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ]            ); /* Q( -rshifts ) */\n                    C_last_row[ k ]  = silk_SMLAWB( C_last_row[ k ],  x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */\n                    Atmp_QA = Af_QA[ k ];\n                    tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ]            );                 /* Q(QA-16) */\n                    tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] );                 /* Q(QA-16) */\n                }\n                tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts );                                       /* Q(16-rshifts) */\n                tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts );                                       /* Q(16-rshifts) */\n                for( k = 0; k <= n; k++ ) {\n                    CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ]                    );        /* Q( -rshift ) */\n                    CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] );        /* Q( -rshift ) */\n                }\n            }\n        } else {\n            for( s = 0; s < nb_subfr; s++ ) {\n                x_ptr = x + s * subfr_length;\n                x1  = -silk_LSHIFT32( (opus_int32)x_ptr[ n ],                    -rshifts );            /* Q( -rshifts ) */\n                x2  = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts );            /* Q( -rshifts ) */\n                tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ],                    17 );                  /* Q17 */\n                tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 );                  /* Q17 */\n                for( k = 0; k < n; k++ ) {\n                    C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ]            ); /* Q( -rshifts ) */\n                    C_last_row[ k ]  = silk_MLA( C_last_row[ k ],  x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */\n                    Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 );                                   /* Q17 */\n                    tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ],            Atmp1 );                      /* Q17 */\n                    tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 );                      /* Q17 */\n                }\n                tmp1 = -tmp1;                                                                           /* Q17 */\n                tmp2 = -tmp2;                                                                           /* Q17 */\n                for( k = 0; k <= n; k++ ) {\n                    CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1,\n                        silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) );                    /* Q( -rshift ) */\n                    CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2,\n                        silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */\n                }\n            }\n        }\n\n        /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */\n        tmp1 = C_first_row[ n ];                                                                        /* Q( -rshifts ) */\n        tmp2 = C_last_row[ n ];                                                                         /* Q( -rshifts ) */\n        num  = 0;                                                                                       /* Q( -rshifts ) */\n        nrg  = silk_ADD32( CAb[ 0 ], CAf[ 0 ] );                                                        /* Q( 1-rshifts ) */\n        for( k = 0; k < n; k++ ) {\n            Atmp_QA = Af_QA[ k ];\n            lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1;\n            lz = silk_min( 32 - QA, lz );\n            Atmp1 = silk_LSHIFT32( Atmp_QA, lz );                                                       /* Q( QA + lz ) */\n\n            tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[  n - k - 1 ], Atmp1 ), 32 - QA - lz );  /* Q( -rshifts ) */\n            tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz );  /* Q( -rshifts ) */\n            num  = silk_ADD_LSHIFT32( num,  silk_SMMUL( CAb[ n - k ],             Atmp1 ), 32 - QA - lz );  /* Q( -rshifts ) */\n            nrg  = silk_ADD_LSHIFT32( nrg,  silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),\n                                                                                Atmp1 ), 32 - QA - lz );    /* Q( 1-rshifts ) */\n        }\n        CAf[ n + 1 ] = tmp1;                                                                            /* Q( -rshifts ) */\n        CAb[ n + 1 ] = tmp2;                                                                            /* Q( -rshifts ) */\n        num = silk_ADD32( num, tmp2 );                                                                  /* Q( -rshifts ) */\n        num = silk_LSHIFT32( -num, 1 );                                                                 /* Q( 1-rshifts ) */\n\n        /* Calculate the next order reflection (parcor) coefficient */\n        if( silk_abs( num ) < nrg ) {\n            rc_Q31 = silk_DIV32_varQ( num, nrg, 31 );\n        } else {\n            rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN;\n        }\n\n        /* Update inverse prediction gain */\n        tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );\n        tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 );\n        if( tmp1 <= minInvGain_Q30 ) {\n            /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */\n            tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 );            /* Q30 */\n            rc_Q31 = silk_SQRT_APPROX( tmp2 );                                                  /* Q15 */\n            /* Newton-Raphson iteration */\n            rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 );                   /* Q15 */\n            rc_Q31 = silk_LSHIFT32( rc_Q31, 16 );                                               /* Q31 */\n            if( num < 0 ) {\n                /* Ensure adjusted reflection coefficients has the original sign */\n                rc_Q31 = -rc_Q31;\n            }\n            invGain_Q30 = minInvGain_Q30;\n            reached_max_gain = 1;\n        } else {\n            invGain_Q30 = tmp1;\n        }\n\n        /* Update the AR coefficients */\n        for( k = 0; k < (n + 1) >> 1; k++ ) {\n            tmp1 = Af_QA[ k ];                                                                  /* QA */\n            tmp2 = Af_QA[ n - k - 1 ];                                                          /* QA */\n            Af_QA[ k ]         = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 );      /* QA */\n            Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 );      /* QA */\n        }\n        Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA );                                          /* QA */\n\n        if( reached_max_gain ) {\n            /* Reached max prediction gain; set remaining coefficients to zero and exit loop */\n            for( k = n + 1; k < D; k++ ) {\n                Af_QA[ k ] = 0;\n            }\n            break;\n        }\n\n        /* Update C * Af and C * Ab */\n        for( k = 0; k <= n + 1; k++ ) {\n            tmp1 = CAf[ k ];                                                                    /* Q( -rshifts ) */\n            tmp2 = CAb[ n - k + 1 ];                                                            /* Q( -rshifts ) */\n            CAf[ k ]         = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 );        /* Q( -rshifts ) */\n            CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 );        /* Q( -rshifts ) */\n        }\n    }\n\n    if( reached_max_gain ) {\n        for( k = 0; k < D; k++ ) {\n            /* Scale coefficients */\n            A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );\n        }\n        /* Subtract energy of preceding samples from C0 */\n        if( rshifts > 0 ) {\n            for( s = 0; s < nb_subfr; s++ ) {\n                x_ptr = x + s * subfr_length;\n                C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts );\n            }\n        } else {\n            for( s = 0; s < nb_subfr; s++ ) {\n                x_ptr = x + s * subfr_length;\n                C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch), -rshifts);\n            }\n        }\n        /* Approximate residual energy */\n        *res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 );\n        *res_nrg_Q = -rshifts;\n    } else {\n        /* Return residual energy */\n        nrg  = CAf[ 0 ];                                                                            /* Q( -rshifts ) */\n        tmp1 = (opus_int32)1 << 16;                                                                             /* Q16 */\n        for( k = 0; k < D; k++ ) {\n            Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );                                       /* Q16 */\n            nrg  = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 );                                         /* Q( -rshifts ) */\n            tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 );                                               /* Q16 */\n            A_Q16[ k ] = -Atmp1;\n        }\n        *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */\n        *res_nrg_Q = -rshifts;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/corrMatrix_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/**********************************************************************\n * Correlation Matrix Computations for LS estimate.\n **********************************************************************/\n\n#include \"main_FIX.h\"\n\n/* Calculates correlation vector X'*t */\nvoid silk_corrVector_FIX(\n    const opus_int16                *x,                                     /* I    x vector [L + order - 1] used to form data matrix X                         */\n    const opus_int16                *t,                                     /* I    Target vector [L]                                                           */\n    const opus_int                  L,                                      /* I    Length of vectors                                                           */\n    const opus_int                  order,                                  /* I    Max lag for correlation                                                     */\n    opus_int32                      *Xt,                                    /* O    Pointer to X'*t correlation vector [order]                                  */\n    const opus_int                  rshifts,                                /* I    Right shifts of correlations                                                */\n    int                             arch                                    /* I    Run-time architecture                                                       */\n)\n{\n    opus_int         lag, i;\n    const opus_int16 *ptr1, *ptr2;\n    opus_int32       inner_prod;\n\n    ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */\n    ptr2 = t;\n    /* Calculate X'*t */\n    if( rshifts > 0 ) {\n        /* Right shifting used */\n        for( lag = 0; lag < order; lag++ ) {\n            inner_prod = 0;\n            for( i = 0; i < L; i++ ) {\n                inner_prod += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );\n            }\n            Xt[ lag ] = inner_prod; /* X[:,lag]'*t */\n            ptr1--; /* Go to next column of X */\n        }\n    } else {\n        silk_assert( rshifts == 0 );\n        for( lag = 0; lag < order; lag++ ) {\n            Xt[ lag ] = silk_inner_prod_aligned( ptr1, ptr2, L, arch ); /* X[:,lag]'*t */\n            ptr1--; /* Go to next column of X */\n        }\n    }\n}\n\n/* Calculates correlation matrix X'*X */\nvoid silk_corrMatrix_FIX(\n    const opus_int16                *x,                                     /* I    x vector [L + order - 1] used to form data matrix X                         */\n    const opus_int                  L,                                      /* I    Length of vectors                                                           */\n    const opus_int                  order,                                  /* I    Max lag for correlation                                                     */\n    const opus_int                  head_room,                              /* I    Desired headroom                                                            */\n    opus_int32                      *XX,                                    /* O    Pointer to X'*X correlation matrix [ order x order ]                        */\n    opus_int                        *rshifts,                               /* I/O  Right shifts of correlations                                                */\n    int                             arch                                    /* I    Run-time architecture                                                       */\n)\n{\n    opus_int         i, j, lag, rshifts_local, head_room_rshifts;\n    opus_int32       energy;\n    const opus_int16 *ptr1, *ptr2;\n\n    /* Calculate energy to find shift used to fit in 32 bits */\n    silk_sum_sqr_shift( &energy, &rshifts_local, x, L + order - 1 );\n    /* Add shifts to get the desired head room */\n    head_room_rshifts = silk_max( head_room - silk_CLZ32( energy ), 0 );\n\n    energy = silk_RSHIFT32( energy, head_room_rshifts );\n    rshifts_local += head_room_rshifts;\n\n    /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */\n    /* Remove contribution of first order - 1 samples */\n    for( i = 0; i < order - 1; i++ ) {\n        energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), rshifts_local );\n    }\n    if( rshifts_local < *rshifts ) {\n        /* Adjust energy */\n        energy = silk_RSHIFT32( energy, *rshifts - rshifts_local );\n        rshifts_local = *rshifts;\n    }\n\n    /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */\n    /* Fill out the diagonal of the correlation matrix */\n    matrix_ptr( XX, 0, 0, order ) = energy;\n    ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */\n    for( j = 1; j < order; j++ ) {\n        energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), rshifts_local ) );\n        energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), rshifts_local ) );\n        matrix_ptr( XX, j, j, order ) = energy;\n    }\n\n    ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */\n    /* Calculate the remaining elements of the correlation matrix */\n    if( rshifts_local > 0 ) {\n        /* Right shifting used */\n        for( lag = 1; lag < order; lag++ ) {\n            /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */\n            energy = 0;\n            for( i = 0; i < L; i++ ) {\n                energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts_local );\n            }\n            /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */\n            matrix_ptr( XX, lag, 0, order ) = energy;\n            matrix_ptr( XX, 0, lag, order ) = energy;\n            for( j = 1; j < ( order - lag ); j++ ) {\n                energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), rshifts_local ) );\n                energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), rshifts_local ) );\n                matrix_ptr( XX, lag + j, j, order ) = energy;\n                matrix_ptr( XX, j, lag + j, order ) = energy;\n            }\n            ptr2--; /* Update pointer to first sample of next column (lag) in X */\n        }\n    } else {\n        for( lag = 1; lag < order; lag++ ) {\n            /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */\n            energy = silk_inner_prod_aligned( ptr1, ptr2, L, arch );\n            matrix_ptr( XX, lag, 0, order ) = energy;\n            matrix_ptr( XX, 0, lag, order ) = energy;\n            /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */\n            for( j = 1; j < ( order - lag ); j++ ) {\n                energy = silk_SUB32( energy, silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) );\n                energy = silk_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] );\n                matrix_ptr( XX, lag + j, j, order ) = energy;\n                matrix_ptr( XX, j, lag + j, order ) = energy;\n            }\n            ptr2--;/* Update pointer to first sample of next column (lag) in X */\n        }\n    }\n    *rshifts = rshifts_local;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/encode_frame_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n#include \"stack_alloc.h\"\n#include \"tuning_parameters.h\"\n\n/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate           */\nstatic OPUS_INLINE void silk_LBRR_encode_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */\n    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Pointer to Silk FIX encoder control struct                                  */\n    const opus_int32                xfw_Q3[],                               /* I    Input signal                                                                */\n    opus_int                        condCoding                              /* I    The type of conditional coding used so far for this frame                   */\n);\n\nvoid silk_encode_do_VAD_FIX(\n    silk_encoder_state_FIX          *psEnc                                  /* I/O  Pointer to Silk FIX encoder state                                           */\n)\n{\n    /****************************/\n    /* Voice Activity Detection */\n    /****************************/\n    silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );\n\n    /**************************************************/\n    /* Convert speech activity into VAD and DTX flags */\n    /**************************************************/\n    if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {\n        psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;\n        psEnc->sCmn.noSpeechCounter++;\n        if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) {\n            psEnc->sCmn.inDTX = 0;\n        } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {\n            psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;\n            psEnc->sCmn.inDTX           = 0;\n        }\n        psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;\n    } else {\n        psEnc->sCmn.noSpeechCounter    = 0;\n        psEnc->sCmn.inDTX              = 0;\n        psEnc->sCmn.indices.signalType = TYPE_UNVOICED;\n        psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;\n    }\n}\n\n/****************/\n/* Encode frame */\n/****************/\nopus_int silk_encode_frame_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */\n    opus_int32                      *pnBytesOut,                            /* O    Pointer to number of payload bytes;                                         */\n    ec_enc                          *psRangeEnc,                            /* I/O  compressor data structure                                                   */\n    opus_int                        condCoding,                             /* I    The type of conditional coding to use                                       */\n    opus_int                        maxBits,                                /* I    If > 0: maximum number of output bits                                       */\n    opus_int                        useCBR                                  /* I    Flag to force constant-bitrate operation                                    */\n)\n{\n    silk_encoder_control_FIX sEncCtrl;\n    opus_int     i, iter, maxIter, found_upper, found_lower, ret = 0;\n    opus_int16   *x_frame;\n    ec_enc       sRangeEnc_copy, sRangeEnc_copy2;\n    silk_nsq_state sNSQ_copy, sNSQ_copy2;\n    opus_int32   seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;\n    opus_int32   gainsID, gainsID_lower, gainsID_upper;\n    opus_int16   gainMult_Q8;\n    opus_int16   ec_prevLagIndex_copy;\n    opus_int     ec_prevSignalType_copy;\n    opus_int8    LastGainIndex_copy2;\n    SAVE_STACK;\n\n    /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */\n    LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;\n\n    psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;\n\n    /**************************************************************/\n    /* Set up Input Pointers, and insert frame in input buffer   */\n    /*************************************************************/\n    /* start of frame to encode */\n    x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;\n\n    /***************************************/\n    /* Ensure smooth bandwidth transitions */\n    /***************************************/\n    silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );\n\n    /*******************************************/\n    /* Copy new frame to front of input buffer */\n    /*******************************************/\n    silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );\n\n    if( !psEnc->sCmn.prefillFlag ) {\n        VARDECL( opus_int32, xfw_Q3 );\n        VARDECL( opus_int16, res_pitch );\n        VARDECL( opus_uint8, ec_buf_copy );\n        opus_int16 *res_pitch_frame;\n\n        ALLOC( res_pitch,\n               psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length\n                   + psEnc->sCmn.ltp_mem_length, opus_int16 );\n        /* start of pitch LPC residual frame */\n        res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length;\n\n        /*****************************************/\n        /* Find pitch lags, initial LPC analysis */\n        /*****************************************/\n        silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch );\n\n        /************************/\n        /* Noise shape analysis */\n        /************************/\n        silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch );\n\n        /***************************************************/\n        /* Find linear prediction coefficients (LPC + LTP) */\n        /***************************************************/\n        silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );\n\n        /****************************************/\n        /* Process gains                        */\n        /****************************************/\n        silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding );\n\n        /*****************************************/\n        /* Prefiltering for noise shaper         */\n        /*****************************************/\n        ALLOC( xfw_Q3, psEnc->sCmn.frame_length, opus_int32 );\n        silk_prefilter_FIX( psEnc, &sEncCtrl, xfw_Q3, x_frame );\n\n        /****************************************/\n        /* Low Bitrate Redundant Encoding       */\n        /****************************************/\n        silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw_Q3, condCoding );\n\n        /* Loop over quantizer and entropy coding to control bitrate */\n        maxIter = 6;\n        gainMult_Q8 = SILK_FIX_CONST( 1, 8 );\n        found_lower = 0;\n        found_upper = 0;\n        gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );\n        gainsID_lower = -1;\n        gainsID_upper = -1;\n        /* Copy part of the input state */\n        silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );\n        silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );\n        seed_copy = psEnc->sCmn.indices.Seed;\n        ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;\n        ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;\n        ALLOC( ec_buf_copy, 1275, opus_uint8 );\n        for( iter = 0; ; iter++ ) {\n            if( gainsID == gainsID_lower ) {\n                nBits = nBits_lower;\n            } else if( gainsID == gainsID_upper ) {\n                nBits = nBits_upper;\n            } else {\n                /* Restore part of the input state */\n                if( iter > 0 ) {\n                    silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );\n                    silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );\n                    psEnc->sCmn.indices.Seed = seed_copy;\n                    psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;\n                    psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;\n                }\n\n                /*****************************************/\n                /* Noise shaping quantization            */\n                /*****************************************/\n                if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {\n                    silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses,\n                           sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,\n                           sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,\n                           psEnc->sCmn.arch );\n                } else {\n                    silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses,\n                            sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,\n                            sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,\n                            psEnc->sCmn.arch);\n                }\n\n                /****************************************/\n                /* Encode Parameters                    */\n                /****************************************/\n                silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );\n\n                /****************************************/\n                /* Encode Excitation Signal             */\n                /****************************************/\n                silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,\n                    psEnc->sCmn.pulses, psEnc->sCmn.frame_length );\n\n                nBits = ec_tell( psRangeEnc );\n\n                if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {\n                    break;\n                }\n            }\n\n            if( iter == maxIter ) {\n                if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {\n                    /* Restore output state from earlier iteration that did meet the bitrate budget */\n                    silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );\n                    silk_assert( sRangeEnc_copy2.offs <= 1275 );\n                    silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );\n                    silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );\n                    psEnc->sShape.LastGainIndex = LastGainIndex_copy2;\n                }\n                break;\n            }\n\n            if( nBits > maxBits ) {\n                if( found_lower == 0 && iter >= 2 ) {\n                    /* Adjust the quantizer's rate/distortion tradeoff and discard previous \"upper\" results */\n                    sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 );\n                    found_upper = 0;\n                    gainsID_upper = -1;\n                } else {\n                    found_upper = 1;\n                    nBits_upper = nBits;\n                    gainMult_upper = gainMult_Q8;\n                    gainsID_upper = gainsID;\n                }\n            } else if( nBits < maxBits - 5 ) {\n                found_lower = 1;\n                nBits_lower = nBits;\n                gainMult_lower = gainMult_Q8;\n                if( gainsID != gainsID_lower ) {\n                    gainsID_lower = gainsID;\n                    /* Copy part of the output state */\n                    silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );\n                    silk_assert( psRangeEnc->offs <= 1275 );\n                    silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );\n                    silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );\n                    LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;\n                }\n            } else {\n                /* Within 5 bits of budget: close enough */\n                break;\n            }\n\n            if( ( found_lower & found_upper ) == 0 ) {\n                /* Adjust gain according to high-rate rate/distortion curve */\n                opus_int32 gain_factor_Q16;\n                gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );\n                gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) );\n                if( nBits > maxBits ) {\n                    gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) );\n                }\n                gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );\n            } else {\n                /* Adjust gain by interpolating */\n                gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower );\n                /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */\n                if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {\n                    gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );\n                } else\n                if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {\n                    gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );\n                }\n            }\n\n            for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\n                sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 );\n            }\n\n            /* Quantize gains */\n            psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;\n            silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16,\n                  &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );\n\n            /* Unique identifier of gains vector */\n            gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );\n        }\n    }\n\n    /* Update input buffer */\n    silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],\n        ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) );\n\n    /* Exit without entropy coding */\n    if( psEnc->sCmn.prefillFlag ) {\n        /* No payload */\n        *pnBytesOut = 0;\n        RESTORE_STACK;\n        return ret;\n    }\n\n    /* Parameters needed for next frame */\n    psEnc->sCmn.prevLag        = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];\n    psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;\n\n    /****************************************/\n    /* Finalize payload                     */\n    /****************************************/\n    psEnc->sCmn.first_frame_after_reset = 0;\n    /* Payload size */\n    *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );\n\n    RESTORE_STACK;\n    return ret;\n}\n\n/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate  */\nstatic OPUS_INLINE void silk_LBRR_encode_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */\n    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Pointer to Silk FIX encoder control struct                                  */\n    const opus_int32                xfw_Q3[],                               /* I    Input signal                                                                */\n    opus_int                        condCoding                              /* I    The type of conditional coding used so far for this frame                   */\n)\n{\n    opus_int32   TempGains_Q16[ MAX_NB_SUBFR ];\n    SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];\n    silk_nsq_state sNSQ_LBRR;\n\n    /*******************************************/\n    /* Control use of inband LBRR              */\n    /*******************************************/\n    if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {\n        psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;\n\n        /* Copy noise shaping quantizer state and quantization indices from regular encoding */\n        silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );\n        silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );\n\n        /* Save original gains */\n        silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );\n\n        if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {\n            /* First frame in packet or previous frame not LBRR coded */\n            psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;\n\n            /* Increase Gains to get target LBRR rate */\n            psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;\n            psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );\n        }\n\n        /* Decode to get gains in sync with decoder         */\n        /* Overwrite unquantized gains with quantized gains */\n        silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,\n            &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );\n\n        /*****************************************/\n        /* Noise shaping quantization            */\n        /*****************************************/\n        if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {\n            silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3,\n                psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,\n                psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,\n                psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );\n        } else {\n            silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3,\n                psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,\n                psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,\n                psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );\n        }\n\n        /* Restore original gains */\n        silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/find_LPC_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n#include \"stack_alloc.h\"\n#include \"tuning_parameters.h\"\n\n/* Finds LPC vector from correlations, and converts to NLSF */\nvoid silk_find_LPC_FIX(\n    silk_encoder_state              *psEncC,                                /* I/O  Encoder state                                                               */\n    opus_int16                      NLSF_Q15[],                             /* O    NLSFs                                                                       */\n    const opus_int16                x[],                                    /* I    Input signal                                                                */\n    const opus_int32                minInvGain_Q30                          /* I    Inverse of max prediction gain                                              */\n)\n{\n    opus_int     k, subfr_length;\n    opus_int32   a_Q16[ MAX_LPC_ORDER ];\n    opus_int     isInterpLower, shift;\n    opus_int32   res_nrg0, res_nrg1;\n    opus_int     rshift0, rshift1;\n\n    /* Used only for LSF interpolation */\n    opus_int32   a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg;\n    opus_int     res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q;\n    opus_int16   a_tmp_Q12[ MAX_LPC_ORDER ];\n    opus_int16   NLSF0_Q15[ MAX_LPC_ORDER ];\n    SAVE_STACK;\n\n    subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;\n\n    /* Default: no interpolation */\n    psEncC->indices.NLSFInterpCoef_Q2 = 4;\n\n    /* Burg AR analysis for the full frame */\n    silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, minInvGain_Q30, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder, psEncC->arch );\n\n    if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {\n        VARDECL( opus_int16, LPC_res );\n\n        /* Optimal solution for last 10 ms */\n        silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + 2 * subfr_length, minInvGain_Q30, subfr_length, 2, psEncC->predictLPCOrder, psEncC->arch );\n\n        /* subtract residual energy here, as that's easier than adding it to the    */\n        /* residual energy of the first 10 ms in each iteration of the search below */\n        shift = res_tmp_nrg_Q - res_nrg_Q;\n        if( shift >= 0 ) {\n            if( shift < 32 ) {\n                res_nrg = res_nrg - silk_RSHIFT( res_tmp_nrg, shift );\n            }\n        } else {\n            silk_assert( shift > -32 );\n            res_nrg   = silk_RSHIFT( res_nrg, -shift ) - res_tmp_nrg;\n            res_nrg_Q = res_tmp_nrg_Q;\n        }\n\n        /* Convert to NLSFs */\n        silk_A2NLSF( NLSF_Q15, a_tmp_Q16, psEncC->predictLPCOrder );\n\n        ALLOC( LPC_res, 2 * subfr_length, opus_int16 );\n\n        /* Search over interpolation indices to find the one with lowest residual energy */\n        for( k = 3; k >= 0; k-- ) {\n            /* Interpolate NLSFs for first half */\n            silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );\n\n            /* Convert to LPC for residual energy evaluation */\n            silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder );\n\n            /* Calculate residual energy with NLSF interpolation */\n            silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder, psEncC->arch );\n\n            silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + psEncC->predictLPCOrder,                subfr_length - psEncC->predictLPCOrder );\n            silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder );\n\n            /* Add subframe energies from first half frame */\n            shift = rshift0 - rshift1;\n            if( shift >= 0 ) {\n                res_nrg1         = silk_RSHIFT( res_nrg1, shift );\n                res_nrg_interp_Q = -rshift0;\n            } else {\n                res_nrg0         = silk_RSHIFT( res_nrg0, -shift );\n                res_nrg_interp_Q = -rshift1;\n            }\n            res_nrg_interp = silk_ADD32( res_nrg0, res_nrg1 );\n\n            /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */\n            shift = res_nrg_interp_Q - res_nrg_Q;\n            if( shift >= 0 ) {\n                if( silk_RSHIFT( res_nrg_interp, shift ) < res_nrg ) {\n                    isInterpLower = silk_TRUE;\n                } else {\n                    isInterpLower = silk_FALSE;\n                }\n            } else {\n                if( -shift < 32 ) {\n                    if( res_nrg_interp < silk_RSHIFT( res_nrg, -shift ) ) {\n                        isInterpLower = silk_TRUE;\n                    } else {\n                        isInterpLower = silk_FALSE;\n                    }\n                } else {\n                    isInterpLower = silk_FALSE;\n                }\n            }\n\n            /* Determine whether current interpolated NLSFs are best so far */\n            if( isInterpLower == silk_TRUE ) {\n                /* Interpolation has lower residual energy */\n                res_nrg   = res_nrg_interp;\n                res_nrg_Q = res_nrg_interp_Q;\n                psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k;\n            }\n        }\n    }\n\n    if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) {\n        /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */\n        silk_A2NLSF( NLSF_Q15, a_Q16, psEncC->predictLPCOrder );\n    }\n\n    silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );\n    RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/find_LTP_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n#include \"tuning_parameters.h\"\n\n/* Head room for correlations */\n#define LTP_CORRS_HEAD_ROOM                             2\n\nvoid silk_fit_LTP(\n    opus_int32 LTP_coefs_Q16[ LTP_ORDER ],\n    opus_int16 LTP_coefs_Q14[ LTP_ORDER ]\n);\n\nvoid silk_find_LTP_FIX(\n    opus_int16                      b_Q14[ MAX_NB_SUBFR * LTP_ORDER ],      /* O    LTP coefs                                                                   */\n    opus_int32                      WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O    Weight for LTP quantization                                           */\n    opus_int                        *LTPredCodGain_Q7,                      /* O    LTP coding gain                                                             */\n    const opus_int16                r_lpc[],                                /* I    residual signal after LPC signal + state for first 10 ms                    */\n    const opus_int                  lag[ MAX_NB_SUBFR ],                    /* I    LTP lags                                                                    */\n    const opus_int32                Wght_Q15[ MAX_NB_SUBFR ],               /* I    weights                                                                     */\n    const opus_int                  subfr_length,                           /* I    subframe length                                                             */\n    const opus_int                  nb_subfr,                               /* I    number of subframes                                                         */\n    const opus_int                  mem_offset,                             /* I    number of samples in LTP memory                                             */\n    opus_int                        corr_rshifts[ MAX_NB_SUBFR ],           /* O    right shifts applied to correlations                                        */\n    int                             arch                                    /* I    Run-time architecture                                                       */\n)\n{\n    opus_int   i, k, lshift;\n    const opus_int16 *r_ptr, *lag_ptr;\n    opus_int16 *b_Q14_ptr;\n\n    opus_int32 regu;\n    opus_int32 *WLTP_ptr;\n    opus_int32 b_Q16[ LTP_ORDER ], delta_b_Q14[ LTP_ORDER ], d_Q14[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], g_Q26;\n    opus_int32 w[ MAX_NB_SUBFR ], WLTP_max, max_abs_d_Q14, max_w_bits;\n\n    opus_int32 temp32, denom32;\n    opus_int   extra_shifts;\n    opus_int   rr_shifts, maxRshifts, maxRshifts_wxtra, LZs;\n    opus_int32 LPC_res_nrg, LPC_LTP_res_nrg, div_Q16;\n    opus_int32 Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ];\n    opus_int32 wd, m_Q12;\n\n    b_Q14_ptr = b_Q14;\n    WLTP_ptr  = WLTP;\n    r_ptr     = &r_lpc[ mem_offset ];\n    for( k = 0; k < nb_subfr; k++ ) {\n        lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );\n\n        silk_sum_sqr_shift( &rr[ k ], &rr_shifts, r_ptr, subfr_length ); /* rr[ k ] in Q( -rr_shifts ) */\n\n        /* Assure headroom */\n        LZs = silk_CLZ32( rr[k] );\n        if( LZs < LTP_CORRS_HEAD_ROOM ) {\n            rr[ k ] = silk_RSHIFT_ROUND( rr[ k ], LTP_CORRS_HEAD_ROOM - LZs );\n            rr_shifts += ( LTP_CORRS_HEAD_ROOM - LZs );\n        }\n        corr_rshifts[ k ] = rr_shifts;\n        silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, LTP_CORRS_HEAD_ROOM, WLTP_ptr, &corr_rshifts[ k ], arch );  /* WLTP_fix_ptr in Q( -corr_rshifts[ k ] ) */\n\n        /* The correlation vector always has lower max abs value than rr and/or RR so head room is assured */\n        silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr, corr_rshifts[ k ], arch );  /* Rr_fix_ptr   in Q( -corr_rshifts[ k ] ) */\n        if( corr_rshifts[ k ] > rr_shifts ) {\n            rr[ k ] = silk_RSHIFT( rr[ k ], corr_rshifts[ k ] - rr_shifts ); /* rr[ k ] in Q( -corr_rshifts[ k ] ) */\n        }\n        silk_assert( rr[ k ] >= 0 );\n\n        regu = 1;\n        regu = silk_SMLAWB( regu, rr[ k ], SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );\n        regu = silk_SMLAWB( regu, matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );\n        regu = silk_SMLAWB( regu, matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );\n        silk_regularize_correlations_FIX( WLTP_ptr, &rr[k], regu, LTP_ORDER );\n\n        silk_solve_LDL_FIX( WLTP_ptr, LTP_ORDER, Rr, b_Q16 ); /* WLTP_fix_ptr and Rr_fix_ptr both in Q(-corr_rshifts[k]) */\n\n        /* Limit and store in Q14 */\n        silk_fit_LTP( b_Q16, b_Q14_ptr );\n\n        /* Calculate residual energy */\n        nrg[ k ] = silk_residual_energy16_covar_FIX( b_Q14_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER, 14 ); /* nrg_fix in Q( -corr_rshifts[ k ] ) */\n\n        /* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */\n        extra_shifts = silk_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM );\n        denom32 = silk_LSHIFT_SAT32( silk_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */\n            silk_RSHIFT( silk_SMULWB( (opus_int32)subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts );    /* Q( -corr_rshifts[ k ] + extra_shifts ) */\n        denom32 = silk_max( denom32, 1 );\n        silk_assert( ((opus_int64)Wght_Q15[ k ] << 16 ) < silk_int32_MAX );                       /* Wght always < 0.5 in Q0 */\n        temp32 = silk_DIV32( silk_LSHIFT( (opus_int32)Wght_Q15[ k ], 16 ), denom32 );             /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */\n        temp32 = silk_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 );               /* Q26 */\n\n        /* Limit temp such that the below scaling never wraps around */\n        WLTP_max = 0;\n        for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {\n            WLTP_max = silk_max( WLTP_ptr[ i ], WLTP_max );\n        }\n        lshift = silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */\n        silk_assert( 26 - 18 + lshift >= 0 );\n        if( 26 - 18 + lshift < 31 ) {\n            temp32 = silk_min_32( temp32, silk_LSHIFT( (opus_int32)1, 26 - 18 + lshift ) );\n        }\n\n        silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */\n\n        w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER/2, LTP_ORDER/2, LTP_ORDER ); /* w in Q( 18 - corr_rshifts[ k ] ) */\n        silk_assert( w[k] >= 0 );\n\n        r_ptr     += subfr_length;\n        b_Q14_ptr += LTP_ORDER;\n        WLTP_ptr  += LTP_ORDER * LTP_ORDER;\n    }\n\n    maxRshifts = 0;\n    for( k = 0; k < nb_subfr; k++ ) {\n        maxRshifts = silk_max_int( corr_rshifts[ k ], maxRshifts );\n    }\n\n    /* Compute LTP coding gain */\n    if( LTPredCodGain_Q7 != NULL ) {\n        LPC_LTP_res_nrg = 0;\n        LPC_res_nrg     = 0;\n        silk_assert( LTP_CORRS_HEAD_ROOM >= 2 ); /* Check that no overflow will happen when adding */\n        for( k = 0; k < nb_subfr; k++ ) {\n            LPC_res_nrg     = silk_ADD32( LPC_res_nrg,     silk_RSHIFT( silk_ADD32( silk_SMULWB(  rr[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */\n            LPC_LTP_res_nrg = silk_ADD32( LPC_LTP_res_nrg, silk_RSHIFT( silk_ADD32( silk_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */\n        }\n        LPC_LTP_res_nrg = silk_max( LPC_LTP_res_nrg, 1 ); /* avoid division by zero */\n\n        div_Q16 = silk_DIV32_varQ( LPC_res_nrg, LPC_LTP_res_nrg, 16 );\n        *LTPredCodGain_Q7 = ( opus_int )silk_SMULBB( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) );\n\n        silk_assert( *LTPredCodGain_Q7 == ( opus_int )silk_SAT16( silk_MUL( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) ) ) );\n    }\n\n    /* smoothing */\n    /* d = sum( B, 1 ); */\n    b_Q14_ptr = b_Q14;\n    for( k = 0; k < nb_subfr; k++ ) {\n        d_Q14[ k ] = 0;\n        for( i = 0; i < LTP_ORDER; i++ ) {\n            d_Q14[ k ] += b_Q14_ptr[ i ];\n        }\n        b_Q14_ptr += LTP_ORDER;\n    }\n\n    /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */\n\n    /* Find maximum absolute value of d_Q14 and the bits used by w in Q0 */\n    max_abs_d_Q14 = 0;\n    max_w_bits    = 0;\n    for( k = 0; k < nb_subfr; k++ ) {\n        max_abs_d_Q14 = silk_max_32( max_abs_d_Q14, silk_abs( d_Q14[ k ] ) );\n        /* w[ k ] is in Q( 18 - corr_rshifts[ k ] ) */\n        /* Find bits needed in Q( 18 - maxRshifts ) */\n        max_w_bits = silk_max_32( max_w_bits, 32 - silk_CLZ32( w[ k ] ) + corr_rshifts[ k ] - maxRshifts );\n    }\n\n    /* max_abs_d_Q14 = (5 << 15); worst case, i.e. LTP_ORDER * -silk_int16_MIN */\n    silk_assert( max_abs_d_Q14 <= ( 5 << 15 ) );\n\n    /* How many bits is needed for w*d' in Q( 18 - maxRshifts ) in the worst case, of all d_Q14's being equal to max_abs_d_Q14 */\n    extra_shifts = max_w_bits + 32 - silk_CLZ32( max_abs_d_Q14 ) - 14;\n\n    /* Subtract what we got available; bits in output var plus maxRshifts */\n    extra_shifts -= ( 32 - 1 - 2 + maxRshifts ); /* Keep sign bit free as well as 2 bits for accumulation */\n    extra_shifts = silk_max_int( extra_shifts, 0 );\n\n    maxRshifts_wxtra = maxRshifts + extra_shifts;\n\n    temp32 = silk_RSHIFT( 262, maxRshifts + extra_shifts ) + 1; /* 1e-3f in Q( 18 - (maxRshifts + extra_shifts) ) */\n    wd = 0;\n    for( k = 0; k < nb_subfr; k++ ) {\n        /* w has at least 2 bits of headroom so no overflow should happen */\n        temp32 = silk_ADD32( temp32,                     silk_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ) );                      /* Q( 18 - maxRshifts_wxtra ) */\n        wd     = silk_ADD32( wd, silk_LSHIFT( silk_SMULWW( silk_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ), d_Q14[ k ] ), 2 ) ); /* Q( 18 - maxRshifts_wxtra ) */\n    }\n    m_Q12 = silk_DIV32_varQ( wd, temp32, 12 );\n\n    b_Q14_ptr = b_Q14;\n    for( k = 0; k < nb_subfr; k++ ) {\n        /* w_fix[ k ] from Q( 18 - corr_rshifts[ k ] ) to Q( 16 ) */\n        if( 2 - corr_rshifts[k] > 0 ) {\n            temp32 = silk_RSHIFT( w[ k ], 2 - corr_rshifts[ k ] );\n        } else {\n            temp32 = silk_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 );\n        }\n\n        g_Q26 = silk_MUL(\n            silk_DIV32(\n                SILK_FIX_CONST( LTP_SMOOTHING, 26 ),\n                silk_RSHIFT( SILK_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ),                          /* Q10 */\n            silk_LSHIFT_SAT32( silk_SUB_SAT32( (opus_int32)m_Q12, silk_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) );    /* Q16 */\n\n        temp32 = 0;\n        for( i = 0; i < LTP_ORDER; i++ ) {\n            delta_b_Q14[ i ] = silk_max_16( b_Q14_ptr[ i ], 1638 );     /* 1638_Q14 = 0.1_Q0 */\n            temp32 += delta_b_Q14[ i ];                                 /* Q14 */\n        }\n        temp32 = silk_DIV32( g_Q26, temp32 );                           /* Q14 -> Q12 */\n        for( i = 0; i < LTP_ORDER; i++ ) {\n            b_Q14_ptr[ i ] = silk_LIMIT_32( (opus_int32)b_Q14_ptr[ i ] + silk_SMULWB( silk_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 );\n        }\n        b_Q14_ptr += LTP_ORDER;\n    }\n}\n\nvoid silk_fit_LTP(\n    opus_int32 LTP_coefs_Q16[ LTP_ORDER ],\n    opus_int16 LTP_coefs_Q14[ LTP_ORDER ]\n)\n{\n    opus_int i;\n\n    for( i = 0; i < LTP_ORDER; i++ ) {\n        LTP_coefs_Q14[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/find_pitch_lags_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n#include \"stack_alloc.h\"\n#include \"tuning_parameters.h\"\n\n/* Find pitch lags */\nvoid silk_find_pitch_lags_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  encoder state                                                               */\n    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  encoder control                                                             */\n    opus_int16                      res[],                                  /* O    residual                                                                    */\n    const opus_int16                x[],                                    /* I    Speech signal                                                               */\n    int                             arch                                    /* I    Run-time architecture                                                       */\n)\n{\n    opus_int   buf_len, i, scale;\n    opus_int32 thrhld_Q13, res_nrg;\n    const opus_int16 *x_buf, *x_buf_ptr;\n    VARDECL( opus_int16, Wsig );\n    opus_int16 *Wsig_ptr;\n    opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];\n    opus_int16 rc_Q15[    MAX_FIND_PITCH_LPC_ORDER ];\n    opus_int32 A_Q24[     MAX_FIND_PITCH_LPC_ORDER ];\n    opus_int16 A_Q12[     MAX_FIND_PITCH_LPC_ORDER ];\n    SAVE_STACK;\n\n    /******************************************/\n    /* Set up buffer lengths etc based on Fs  */\n    /******************************************/\n    buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;\n\n    /* Safety check */\n    silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );\n\n    x_buf = x - psEnc->sCmn.ltp_mem_length;\n\n    /*************************************/\n    /* Estimate LPC AR coefficients      */\n    /*************************************/\n\n    /* Calculate windowed signal */\n\n    ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 );\n\n    /* First LA_LTP samples */\n    x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length;\n    Wsig_ptr  = Wsig;\n    silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch );\n\n    /* Middle un - windowed samples */\n    Wsig_ptr  += psEnc->sCmn.la_pitch;\n    x_buf_ptr += psEnc->sCmn.la_pitch;\n    silk_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) );\n\n    /* Last LA_LTP samples */\n    Wsig_ptr  += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );\n    x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );\n    silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch );\n\n    /* Calculate autocorrelation sequence */\n    silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1, arch );\n\n    /* Add white noise, as fraction of energy */\n    auto_corr[ 0 ] = silk_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1;\n\n    /* Calculate the reflection coefficients using schur */\n    res_nrg = silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );\n\n    /* Prediction gain */\n    psEncCtrl->predGain_Q16 = silk_DIV32_varQ( auto_corr[ 0 ], silk_max_int( res_nrg, 1 ), 16 );\n\n    /* Convert reflection coefficients to prediction coefficients */\n    silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder );\n\n    /* Convert From 32 bit Q24 to 16 bit Q12 coefs */\n    for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) {\n        A_Q12[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( A_Q24[ i ], 12 ) );\n    }\n\n    /* Do BWE */\n    silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) );\n\n    /*****************************************/\n    /* LPC analysis filtering                */\n    /*****************************************/\n    silk_LPC_analysis_filter( res, x_buf, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.arch );\n\n    if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) {\n        /* Threshold for pitch estimator */\n        thrhld_Q13 = SILK_FIX_CONST( 0.6, 13 );\n        thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.004, 13 ), psEnc->sCmn.pitchEstimationLPCOrder );\n        thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1,   21  ), psEnc->sCmn.speech_activity_Q8 );\n        thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.15,  13 ), silk_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) );\n        thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1,   14 ), psEnc->sCmn.input_tilt_Q15 );\n        thrhld_Q13 = silk_SAT16(  thrhld_Q13 );\n\n        /*****************************************/\n        /* Call pitch estimator                  */\n        /*****************************************/\n        if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex,\n                &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16,\n                (opus_int)thrhld_Q13, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr,\n                psEnc->sCmn.arch) == 0 )\n        {\n            psEnc->sCmn.indices.signalType = TYPE_VOICED;\n        } else {\n            psEnc->sCmn.indices.signalType = TYPE_UNVOICED;\n        }\n    } else {\n        silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) );\n        psEnc->sCmn.indices.lagIndex = 0;\n        psEnc->sCmn.indices.contourIndex = 0;\n        psEnc->LTPCorr_Q15 = 0;\n    }\n    RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/find_pred_coefs_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n#include \"stack_alloc.h\"\n\nvoid silk_find_pred_coefs_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  encoder state                                                               */\n    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  encoder control                                                             */\n    const opus_int16                res_pitch[],                            /* I    Residual from pitch analysis                                                */\n    const opus_int16                x[],                                    /* I    Speech signal                                                               */\n    opus_int                        condCoding                              /* I    The type of conditional coding to use                                       */\n)\n{\n    opus_int         i;\n    opus_int32       invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ], Wght_Q15[ MAX_NB_SUBFR ];\n    opus_int16       NLSF_Q15[ MAX_LPC_ORDER ];\n    const opus_int16 *x_ptr;\n    opus_int16       *x_pre_ptr;\n    VARDECL( opus_int16, LPC_in_pre );\n    opus_int32       tmp, min_gain_Q16, minInvGain_Q30;\n    opus_int         LTP_corrs_rshift[ MAX_NB_SUBFR ];\n    SAVE_STACK;\n\n    /* weighting for weighted least squares */\n    min_gain_Q16 = silk_int32_MAX >> 6;\n    for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\n        min_gain_Q16 = silk_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] );\n    }\n    for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\n        /* Divide to Q16 */\n        silk_assert( psEncCtrl->Gains_Q16[ i ] > 0 );\n        /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */\n        invGains_Q16[ i ] = silk_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 );\n\n        /* Ensure Wght_Q15 a minimum value 1 */\n        invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 363 );\n\n        /* Square the inverted gains */\n        silk_assert( invGains_Q16[ i ] == silk_SAT16( invGains_Q16[ i ] ) );\n        tmp = silk_SMULWB( invGains_Q16[ i ], invGains_Q16[ i ] );\n        Wght_Q15[ i ] = silk_RSHIFT( tmp, 1 );\n\n        /* Invert the inverted and normalized gains */\n        local_gains[ i ] = silk_DIV32( ( (opus_int32)1 << 16 ), invGains_Q16[ i ] );\n    }\n\n    ALLOC( LPC_in_pre,\n           psEnc->sCmn.nb_subfr * psEnc->sCmn.predictLPCOrder\n               + psEnc->sCmn.frame_length, opus_int16 );\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        VARDECL( opus_int32, WLTP );\n\n        /**********/\n        /* VOICED */\n        /**********/\n        silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );\n\n        ALLOC( WLTP, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 );\n\n        /* LTP analysis */\n        silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7,\n            res_pitch, psEncCtrl->pitchL, Wght_Q15, psEnc->sCmn.subfr_length,\n            psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length, LTP_corrs_rshift, psEnc->sCmn.arch );\n\n        /* Quantize LTP gain parameters */\n        silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,\n            &psEnc->sCmn.sum_log_gain_Q7, WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr,\n            psEnc->sCmn.arch);\n\n        /* Control LTP scaling */\n        silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl, condCoding );\n\n        /* Create LTP residual */\n        silk_LTP_analysis_filter_FIX( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef_Q14,\n            psEncCtrl->pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );\n\n    } else {\n        /************/\n        /* UNVOICED */\n        /************/\n        /* Create signal with prepended subframes, scaled by inverse gains */\n        x_ptr     = x - psEnc->sCmn.predictLPCOrder;\n        x_pre_ptr = LPC_in_pre;\n        for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\n            silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ],\n                psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );\n            x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;\n            x_ptr     += psEnc->sCmn.subfr_length;\n        }\n\n        silk_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( opus_int16 ) );\n        psEncCtrl->LTPredCodGain_Q7 = 0;\n        psEnc->sCmn.sum_log_gain_Q7 = 0;\n    }\n\n    /* Limit on total predictive coding gain */\n    if( psEnc->sCmn.first_frame_after_reset ) {\n        minInvGain_Q30 = SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET, 30 );\n    } else {\n        minInvGain_Q30 = silk_log2lin( silk_SMLAWB( 16 << 7, (opus_int32)psEncCtrl->LTPredCodGain_Q7, SILK_FIX_CONST( 1.0 / 3, 16 ) ) );      /* Q16 */\n        minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30,\n            silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ),\n                silk_SMLAWB( SILK_FIX_CONST( 0.25, 18 ), SILK_FIX_CONST( 0.75, 18 ), psEncCtrl->coding_quality_Q14 ) ), 14 );\n    }\n\n    /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */\n    silk_find_LPC_FIX( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain_Q30 );\n\n    /* Quantize LSFs */\n    silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );\n\n    /* Calculate residual energy using quantized LPC coefficients */\n    silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains,\n        psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder, psEnc->sCmn.arch );\n\n    /* Copy to prediction struct for use in next frame for interpolation */\n    silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );\n    RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/k2a_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n\n/* Step up function, converts reflection coefficients to prediction coefficients */\nvoid silk_k2a(\n    opus_int32                  *A_Q24,             /* O    Prediction coefficients [order] Q24                         */\n    const opus_int16            *rc_Q15,            /* I    Reflection coefficients [order] Q15                         */\n    const opus_int32            order               /* I    Prediction order                                            */\n)\n{\n    opus_int   k, n;\n    opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];\n\n    for( k = 0; k < order; k++ ) {\n        for( n = 0; n < k; n++ ) {\n            Atmp[ n ] = A_Q24[ n ];\n        }\n        for( n = 0; n < k; n++ ) {\n            A_Q24[ n ] = silk_SMLAWB( A_Q24[ n ], silk_LSHIFT( Atmp[ k - n - 1 ], 1 ), rc_Q15[ k ] );\n        }\n        A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/k2a_Q16_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n\n/* Step up function, converts reflection coefficients to prediction coefficients */\nvoid silk_k2a_Q16(\n    opus_int32                  *A_Q24,             /* O    Prediction coefficients [order] Q24                         */\n    const opus_int32            *rc_Q16,            /* I    Reflection coefficients [order] Q16                         */\n    const opus_int32            order               /* I    Prediction order                                            */\n)\n{\n    opus_int   k, n;\n    opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];\n\n    for( k = 0; k < order; k++ ) {\n        for( n = 0; n < k; n++ ) {\n            Atmp[ n ] = A_Q24[ n ];\n        }\n        for( n = 0; n < k; n++ ) {\n            A_Q24[ n ] = silk_SMLAWW( A_Q24[ n ], Atmp[ k - n - 1 ], rc_Q16[ k ] );\n        }\n        A_Q24[ k ] = -silk_LSHIFT( rc_Q16[ k ], 8 );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/main_FIX.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_MAIN_FIX_H\n#define SILK_MAIN_FIX_H\n\n#include \"SigProc_FIX.h\"\n#include \"structs_FIX.h\"\n#include \"control.h\"\n#include \"main.h\"\n#include \"PLC.h\"\n#include \"debug.h\"\n#include \"entenc.h\"\n\n#ifndef FORCE_CPP_BUILD\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n#endif\n\n#define silk_encoder_state_Fxx      silk_encoder_state_FIX\n#define silk_encode_do_VAD_Fxx      silk_encode_do_VAD_FIX\n#define silk_encode_frame_Fxx       silk_encode_frame_FIX\n\n/*********************/\n/* Encoder Functions */\n/*********************/\n\n/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */\nvoid silk_HP_variable_cutoff(\n    silk_encoder_state_Fxx          state_Fxx[]                             /* I/O  Encoder states                                                              */\n);\n\n/* Encoder main function */\nvoid silk_encode_do_VAD_FIX(\n    silk_encoder_state_FIX          *psEnc                                  /* I/O  Pointer to Silk FIX encoder state                                           */\n);\n\n/* Encoder main function */\nopus_int silk_encode_frame_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */\n    opus_int32                      *pnBytesOut,                            /* O    Pointer to number of payload bytes;                                         */\n    ec_enc                          *psRangeEnc,                            /* I/O  compressor data structure                                                   */\n    opus_int                        condCoding,                             /* I    The type of conditional coding to use                                       */\n    opus_int                        maxBits,                                /* I    If > 0: maximum number of output bits                                       */\n    opus_int                        useCBR                                  /* I    Flag to force constant-bitrate operation                                    */\n);\n\n/* Initializes the Silk encoder state */\nopus_int silk_init_encoder(\n    silk_encoder_state_Fxx          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */\n    int                              arch                                   /* I    Run-time architecture                                                       */\n);\n\n/* Control the Silk encoder */\nopus_int silk_control_encoder(\n    silk_encoder_state_Fxx          *psEnc,                                 /* I/O  Pointer to Silk encoder state                                               */\n    silk_EncControlStruct           *encControl,                            /* I    Control structure                                                           */\n    const opus_int32                TargetRate_bps,                         /* I    Target max bitrate (bps)                                                    */\n    const opus_int                  allow_bw_switch,                        /* I    Flag to allow switching audio bandwidth                                     */\n    const opus_int                  channelNb,                              /* I    Channel number                                                              */\n    const opus_int                  force_fs_kHz\n);\n\n/****************/\n/* Prefiltering */\n/****************/\nvoid silk_prefilter_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Encoder state                                                               */\n    const silk_encoder_control_FIX  *psEncCtrl,                             /* I    Encoder control                                                             */\n    opus_int32                      xw_Q10[],                               /* O    Weighted signal                                                             */\n    const opus_int16                x[]                                     /* I    Speech signal                                                               */\n);\n\nvoid silk_warped_LPC_analysis_filter_FIX_c(\n          opus_int32            state[],                    /* I/O  State [order + 1]                   */\n          opus_int32            res_Q2[],                   /* O    Residual signal [length]            */\n    const opus_int16            coef_Q13[],                 /* I    Coefficients [order]                */\n    const opus_int16            input[],                    /* I    Input signal [length]               */\n    const opus_int16            lambda_Q16,                 /* I    Warping factor                      */\n    const opus_int              length,                     /* I    Length of input signal              */\n    const opus_int              order                       /* I    Filter order (even)                 */\n);\n\n\n/**************************/\n/* Noise shaping analysis */\n/**************************/\n/* Compute noise shaping coefficients and initial gain values */\nvoid silk_noise_shape_analysis_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Encoder state FIX                                                           */\n    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Encoder control FIX                                                         */\n    const opus_int16                *pitch_res,                             /* I    LPC residual from pitch analysis                                            */\n    const opus_int16                *x,                                     /* I    Input signal [ frame_length + la_shape ]                                    */\n    int                              arch                                   /* I    Run-time architecture                                                       */\n);\n\n/* Autocorrelations for a warped frequency axis */\nvoid silk_warped_autocorrelation_FIX(\n          opus_int32                *corr,                                  /* O    Result [order + 1]                                                          */\n          opus_int                  *scale,                                 /* O    Scaling of the correlation vector                                           */\n    const opus_int16                *input,                                 /* I    Input data to correlate                                                     */\n    const opus_int                  warping_Q16,                            /* I    Warping coefficient                                                         */\n    const opus_int                  length,                                 /* I    Length of input                                                             */\n    const opus_int                  order                                   /* I    Correlation order (even)                                                    */\n);\n\n/* Calculation of LTP state scaling */\nvoid silk_LTP_scale_ctrl_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  encoder state                                                               */\n    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  encoder control                                                             */\n    opus_int                        condCoding                              /* I    The type of conditional coding to use                                       */\n);\n\n/**********************************************/\n/* Prediction Analysis                        */\n/**********************************************/\n/* Find pitch lags */\nvoid silk_find_pitch_lags_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  encoder state                                                               */\n    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  encoder control                                                             */\n    opus_int16                      res[],                                  /* O    residual                                                                    */\n    const opus_int16                x[],                                    /* I    Speech signal                                                               */\n    int                             arch                                    /* I    Run-time architecture                                                       */\n);\n\n/* Find LPC and LTP coefficients */\nvoid silk_find_pred_coefs_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  encoder state                                                               */\n    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  encoder control                                                             */\n    const opus_int16                res_pitch[],                            /* I    Residual from pitch analysis                                                */\n    const opus_int16                x[],                                    /* I    Speech signal                                                               */\n    opus_int                        condCoding                              /* I    The type of conditional coding to use                                       */\n);\n\n/* LPC analysis */\nvoid silk_find_LPC_FIX(\n    silk_encoder_state              *psEncC,                                /* I/O  Encoder state                                                               */\n    opus_int16                      NLSF_Q15[],                             /* O    NLSFs                                                                       */\n    const opus_int16                x[],                                    /* I    Input signal                                                                */\n    const opus_int32                minInvGain_Q30                          /* I    Inverse of max prediction gain                                              */\n);\n\n/* LTP analysis */\nvoid silk_find_LTP_FIX(\n    opus_int16                      b_Q14[ MAX_NB_SUBFR * LTP_ORDER ],      /* O    LTP coefs                                                                   */\n    opus_int32                      WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O    Weight for LTP quantization                                           */\n    opus_int                        *LTPredCodGain_Q7,                      /* O    LTP coding gain                                                             */\n    const opus_int16                r_lpc[],                                /* I    residual signal after LPC signal + state for first 10 ms                    */\n    const opus_int                  lag[ MAX_NB_SUBFR ],                    /* I    LTP lags                                                                    */\n    const opus_int32                Wght_Q15[ MAX_NB_SUBFR ],               /* I    weights                                                                     */\n    const opus_int                  subfr_length,                           /* I    subframe length                                                             */\n    const opus_int                  nb_subfr,                               /* I    number of subframes                                                         */\n    const opus_int                  mem_offset,                             /* I    number of samples in LTP memory                                             */\n    opus_int                        corr_rshifts[ MAX_NB_SUBFR ],           /* O    right shifts applied to correlations                                        */\n    int                             arch                                    /* I    Run-time architecture                                                       */\n);\n\nvoid silk_LTP_analysis_filter_FIX(\n    opus_int16                      *LTP_res,                               /* O    LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length )  */\n    const opus_int16                *x,                                     /* I    Pointer to input signal with at least max( pitchL ) preceding samples       */\n    const opus_int16                LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I    LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe                   */\n    const opus_int                  pitchL[ MAX_NB_SUBFR ],                 /* I    Pitch lag, one for each subframe                                            */\n    const opus_int32                invGains_Q16[ MAX_NB_SUBFR ],           /* I    Inverse quantization gains, one for each subframe                           */\n    const opus_int                  subfr_length,                           /* I    Length of each subframe                                                     */\n    const opus_int                  nb_subfr,                               /* I    Number of subframes                                                         */\n    const opus_int                  pre_length                              /* I    Length of the preceding samples starting at &x[0] for each subframe         */\n);\n\n/* Calculates residual energies of input subframes where all subframes have LPC_order   */\n/* of preceding samples                                                                 */\nvoid silk_residual_energy_FIX(\n          opus_int32                nrgs[ MAX_NB_SUBFR ],                   /* O    Residual energy per subframe                                                */\n          opus_int                  nrgsQ[ MAX_NB_SUBFR ],                  /* O    Q value per subframe                                                        */\n    const opus_int16                x[],                                    /* I    Input signal                                                                */\n          opus_int16                a_Q12[ 2 ][ MAX_LPC_ORDER ],            /* I    AR coefs for each frame half                                                */\n    const opus_int32                gains[ MAX_NB_SUBFR ],                  /* I    Quantization gains                                                          */\n    const opus_int                  subfr_length,                           /* I    Subframe length                                                             */\n    const opus_int                  nb_subfr,                               /* I    Number of subframes                                                         */\n    const opus_int                  LPC_order,                              /* I    LPC order                                                                   */\n    int                             arch                                    /* I    Run-time architecture                                                       */\n);\n\n/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */\nopus_int32 silk_residual_energy16_covar_FIX(\n    const opus_int16                *c,                                     /* I    Prediction vector                                                           */\n    const opus_int32                *wXX,                                   /* I    Correlation matrix                                                          */\n    const opus_int32                *wXx,                                   /* I    Correlation vector                                                          */\n    opus_int32                      wxx,                                    /* I    Signal energy                                                               */\n    opus_int                        D,                                      /* I    Dimension                                                                   */\n    opus_int                        cQ                                      /* I    Q value for c vector 0 - 15                                                 */\n);\n\n/* Processing of gains */\nvoid silk_process_gains_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Encoder state                                                               */\n    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Encoder control                                                             */\n    opus_int                        condCoding                              /* I    The type of conditional coding to use                                       */\n);\n\n/******************/\n/* Linear Algebra */\n/******************/\n/* Calculates correlation matrix X'*X */\nvoid silk_corrMatrix_FIX(\n    const opus_int16                *x,                                     /* I    x vector [L + order - 1] used to form data matrix X                         */\n    const opus_int                  L,                                      /* I    Length of vectors                                                           */\n    const opus_int                  order,                                  /* I    Max lag for correlation                                                     */\n    const opus_int                  head_room,                              /* I    Desired headroom                                                            */\n    opus_int32                      *XX,                                    /* O    Pointer to X'*X correlation matrix [ order x order ]                        */\n    opus_int                        *rshifts,                               /* I/O  Right shifts of correlations                                                */\n    int                              arch                                   /* I    Run-time architecture                                                       */\n);\n\n/* Calculates correlation vector X'*t */\nvoid silk_corrVector_FIX(\n    const opus_int16                *x,                                     /* I    x vector [L + order - 1] used to form data matrix X                         */\n    const opus_int16                *t,                                     /* I    Target vector [L]                                                           */\n    const opus_int                  L,                                      /* I    Length of vectors                                                           */\n    const opus_int                  order,                                  /* I    Max lag for correlation                                                     */\n    opus_int32                      *Xt,                                    /* O    Pointer to X'*t correlation vector [order]                                  */\n    const opus_int                  rshifts,                                /* I    Right shifts of correlations                                                */\n    int                             arch                                    /* I    Run-time architecture                                                       */\n);\n\n/* Add noise to matrix diagonal */\nvoid silk_regularize_correlations_FIX(\n    opus_int32                      *XX,                                    /* I/O  Correlation matrices                                                        */\n    opus_int32                      *xx,                                    /* I/O  Correlation values                                                          */\n    opus_int32                      noise,                                  /* I    Noise to add                                                                */\n    opus_int                        D                                       /* I    Dimension of XX                                                             */\n);\n\n/* Solves Ax = b, assuming A is symmetric */\nvoid silk_solve_LDL_FIX(\n    opus_int32                      *A,                                     /* I    Pointer to symetric square matrix A                                         */\n    opus_int                        M,                                      /* I    Size of matrix                                                              */\n    const opus_int32                *b,                                     /* I    Pointer to b vector                                                         */\n    opus_int32                      *x_Q16                                  /* O    Pointer to x solution vector                                                */\n);\n\n#ifndef FORCE_CPP_BUILD\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n#endif /* FORCE_CPP_BUILD */\n#endif /* SILK_MAIN_FIX_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n\n/**************************************************************/\n/* Compute noise shaping coefficients and initial gain values */\n/**************************************************************/\n#define OVERRIDE_silk_noise_shape_analysis_FIX\n\nvoid silk_noise_shape_analysis_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Encoder state FIX                                                           */\n    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Encoder control FIX                                                         */\n    const opus_int16                *pitch_res,                             /* I    LPC residual from pitch analysis                                            */\n    const opus_int16                *x,                                     /* I    Input signal [ frame_length + la_shape ]                                    */\n    int                              arch                                   /* I    Run-time architecture                                                       */\n)\n{\n    silk_shape_state_FIX *psShapeSt = &psEnc->sShape;\n    opus_int     k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;\n    opus_int32   SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;\n    opus_int32   nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;\n    opus_int32   delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;\n    opus_int32   auto_corr[     MAX_SHAPE_LPC_ORDER + 1 ];\n    opus_int32   refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];\n    opus_int32   AR1_Q24[       MAX_SHAPE_LPC_ORDER ];\n    opus_int32   AR2_Q24[       MAX_SHAPE_LPC_ORDER ];\n    VARDECL( opus_int16, x_windowed );\n    const opus_int16 *x_ptr, *pitch_res_ptr;\n    SAVE_STACK;\n\n    /* Point to start of first LPC analysis block */\n    x_ptr = x - psEnc->sCmn.la_shape;\n\n    /****************/\n    /* GAIN CONTROL */\n    /****************/\n    SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;\n\n    /* Input quality is the average of the quality in the lowest two VAD bands */\n    psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ]\n        + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );\n\n    /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */\n    psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -\n        SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 );\n\n    /* Reduce coding SNR during low speech activity */\n    if( psEnc->sCmn.useCBR == 0 ) {\n        b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;\n        b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 );\n        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,\n            silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ),                                       /* Q11*/\n            silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) );     /* Q12*/\n    }\n\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /* Reduce gains for periodic signals */\n        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );\n    } else {\n        /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */\n        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,\n            silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),\n            SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );\n    }\n\n    /*************************/\n    /* SPARSENESS PROCESSING */\n    /*************************/\n    /* Set quantizer offset */\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /* Initially set to 0; may be overruled in process_gains(..) */\n        psEnc->sCmn.indices.quantOffsetType = 0;\n        psEncCtrl->sparseness_Q8 = 0;\n    } else {\n        /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */\n        nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );\n        energy_variation_Q7 = 0;\n        log_energy_prev_Q7  = 0;\n        pitch_res_ptr = pitch_res;\n        for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {\n            silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );\n            nrg += silk_RSHIFT( nSamples, scale );           /* Q(-scale)*/\n\n            log_energy_Q7 = silk_lin2log( nrg );\n            if( k > 0 ) {\n                energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 );\n            }\n            log_energy_prev_Q7 = log_energy_Q7;\n            pitch_res_ptr += nSamples;\n        }\n\n        psEncCtrl->sparseness_Q8 = silk_RSHIFT( silk_sigm_Q15( silk_SMULWB( energy_variation_Q7 -\n            SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 );\n\n        /* Set quantization offset depending on sparseness measure */\n        if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) {\n            psEnc->sCmn.indices.quantOffsetType = 0;\n        } else {\n            psEnc->sCmn.indices.quantOffsetType = 1;\n        }\n\n        /* Increase coding SNR for sparse signals */\n        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SILK_FIX_CONST( 0.5, 8 ) );\n    }\n\n    /*******************************/\n    /* Control bandwidth expansion */\n    /*******************************/\n    /* More BWE for signals with high prediction gain */\n    strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );\n    BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),\n        silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );\n    delta_Q16  = silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - silk_SMULBB( 3, psEncCtrl->coding_quality_Q14 ),\n        SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) );\n    BWExp1_Q16 = silk_SUB32( BWExp1_Q16, delta_Q16 );\n    BWExp2_Q16 = silk_ADD32( BWExp2_Q16, delta_Q16 );\n    /* BWExp1 will be applied after BWExp2, so make it relative */\n    BWExp1_Q16 = silk_DIV32_16( silk_LSHIFT( BWExp1_Q16, 14 ), silk_RSHIFT( BWExp2_Q16, 2 ) );\n\n    if( psEnc->sCmn.warping_Q16 > 0 ) {\n        /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */\n        warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );\n    } else {\n        warping_Q16 = 0;\n    }\n\n    /********************************************/\n    /* Compute noise shaping AR coefs and gains */\n    /********************************************/\n    ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 );\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        /* Apply window: sine slope followed by flat part followed by cosine slope */\n        opus_int shift, slope_part, flat_part;\n        flat_part = psEnc->sCmn.fs_kHz * 3;\n        slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );\n\n        silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );\n        shift = slope_part;\n        silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );\n        shift += flat_part;\n        silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );\n\n        /* Update pointer: next LPC analysis block */\n        x_ptr += psEnc->sCmn.subfr_length;\n\n        if( psEnc->sCmn.warping_Q16 > 0 ) {\n            /* Calculate warped auto correlation */\n            silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );\n        } else {\n            /* Calculate regular auto correlation */\n            silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );\n        }\n\n        /* Add white noise, as a fraction of energy */\n        auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ),\n            SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );\n\n        /* Calculate the reflection coefficients using schur */\n        nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );\n        silk_assert( nrg >= 0 );\n\n        /* Convert reflection coefficients to prediction coefficients */\n        silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );\n\n        Qnrg = -scale;          /* range: -12...30*/\n        silk_assert( Qnrg >= -12 );\n        silk_assert( Qnrg <=  30 );\n\n        /* Make sure that Qnrg is an even number */\n        if( Qnrg & 1 ) {\n            Qnrg -= 1;\n            nrg >>= 1;\n        }\n\n        tmp32 = silk_SQRT_APPROX( nrg );\n        Qnrg >>= 1;             /* range: -6...15*/\n\n        psEncCtrl->Gains_Q16[ k ] = (silk_LSHIFT32( silk_LIMIT( (tmp32), silk_RSHIFT32( silk_int32_MIN, (16 - Qnrg) ), \\\n                            silk_RSHIFT32( silk_int32_MAX, (16 - Qnrg) ) ), (16 - Qnrg) ));\n\n        if( psEnc->sCmn.warping_Q16 > 0 ) {\n            /* Adjust gain for warping */\n            gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );\n            silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );\n            if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) {\n               psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;\n            } else {\n               psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );\n            }\n        }\n\n        /* Bandwidth expansion for synthesis filter shaping */\n        silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );\n\n        /* Compute noise shaping filter coefficients */\n        silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) );\n\n        /* Bandwidth expansion for analysis filter shaping */\n        silk_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) );\n        silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );\n\n        /* Ratio of prediction gains, in energy domain */\n        pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder );\n        nrg         = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder );\n\n        /*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/\n        pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );\n        psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 );\n\n        /* Convert to monic warped prediction coefficients and limit absolute values */\n        limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );\n\n        /* Convert from Q24 to Q13 and store in int16 */\n        for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {\n            psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) );\n            psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) );\n        }\n    }\n\n    /*****************/\n    /* Gain tweaking */\n    /*****************/\n    /* Increase gains during low speech activity and put lower limit on gains */\n    gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );\n    gain_add_Q16  = silk_log2lin(  silk_SMLAWB(  SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) );\n    silk_assert( gain_mult_Q16 > 0 );\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );\n        silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );\n        psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );\n    }\n\n    gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + silk_RSHIFT_ROUND( silk_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ),\n        psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 );\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        psEncCtrl->GainsPre_Q14[ k ] = silk_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] );\n    }\n\n    /************************************************/\n    /* Control low-frequency shaping and noise tilt */\n    /************************************************/\n    /* Less low frequency shaping for noisy inputs */\n    strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),\n        SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );\n    strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */\n        /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/\n        opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );\n        for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n            b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] );\n            /* Pack two coefficients in one int32 */\n            psEncCtrl->LF_shp_Q14[ k ]  = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 );\n            psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );\n        }\n        silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/\n        Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) -\n            silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ),\n                silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );\n    } else {\n        b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/\n        /* Pack two coefficients in one int32 */\n        psEncCtrl->LF_shp_Q14[ 0 ]  = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 -\n            silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );\n        psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );\n        for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {\n            psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];\n        }\n        Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );\n    }\n\n    /****************************/\n    /* HARMONIC SHAPING CONTROL */\n    /****************************/\n    /* Control boosting of harmonic frequencies */\n    HarmBoost_Q16 = silk_SMULWB( silk_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ),\n        psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) );\n\n    /* More harmonic boost for noisy input signals */\n    HarmBoost_Q16 = silk_SMLAWB( HarmBoost_Q16,\n        SILK_FIX_CONST( 1.0, 16 ) - silk_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) );\n\n    if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /* More harmonic noise shaping for high bitrates or noisy input */\n        HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),\n                SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),\n                psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );\n\n        /* Less harmonic noise shaping for less periodic signals */\n        HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ),\n            silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );\n    } else {\n        HarmShapeGain_Q16 = 0;\n    }\n\n    /*************************/\n    /* Smooth over subframes */\n    /*************************/\n    for( k = 0; k < MAX_NB_SUBFR; k++ ) {\n        psShapeSt->HarmBoost_smth_Q16 =\n            silk_SMLAWB( psShapeSt->HarmBoost_smth_Q16,     HarmBoost_Q16     - psShapeSt->HarmBoost_smth_Q16,     SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );\n        psShapeSt->HarmShapeGain_smth_Q16 =\n            silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );\n        psShapeSt->Tilt_smth_Q16 =\n            silk_SMLAWB( psShapeSt->Tilt_smth_Q16,          Tilt_Q16          - psShapeSt->Tilt_smth_Q16,          SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );\n\n        psEncCtrl->HarmBoost_Q14[ k ]     = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16,     2 );\n        psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );\n        psEncCtrl->Tilt_Q14[ k ]          = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16,          2 );\n    }\n    RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/mips/prefilter_FIX_mipsr1.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n#ifndef __PREFILTER_FIX_MIPSR1_H__\n#define __PREFILTER_FIX_MIPSR1_H__\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n#include \"stack_alloc.h\"\n#include \"tuning_parameters.h\"\n\n#define OVERRIDE_silk_warped_LPC_analysis_filter_FIX\nvoid silk_warped_LPC_analysis_filter_FIX(\n          opus_int32            state[],                    /* I/O  State [order + 1]                   */\n          opus_int32            res_Q2[],                   /* O    Residual signal [length]            */\n    const opus_int16            coef_Q13[],                 /* I    Coefficients [order]                */\n    const opus_int16            input[],                    /* I    Input signal [length]               */\n    const opus_int16            lambda_Q16,                 /* I    Warping factor                      */\n    const opus_int              length,                     /* I    Length of input signal              */\n    const opus_int              order,                      /* I    Filter order (even)                 */\n               int              arch\n)\n{\n    opus_int     n, i;\n    opus_int32   acc_Q11, acc_Q22, tmp1, tmp2, tmp3, tmp4;\n    opus_int32   state_cur, state_next;\n\n    (void)arch;\n\n    /* Order must be even */\n    /* Length must be even */\n\n    silk_assert( ( order & 1 ) == 0 );\n    silk_assert( ( length & 1 ) == 0 );\n\n    for( n = 0; n < length; n+=2 ) {\n        /* Output of lowpass section */\n        tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );\n        state_cur = silk_LSHIFT( input[ n ], 14 );\n        /* Output of allpass section */\n        tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );\n        state_next = tmp2;\n        acc_Q11 = silk_RSHIFT( order, 1 );\n        acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );\n\n\n        /* Output of lowpass section */\n        tmp4 = silk_SMLAWB( state_cur, state_next, lambda_Q16 );\n        state[ 0 ] = silk_LSHIFT( input[ n+1 ], 14 );\n        /* Output of allpass section */\n        tmp3 = silk_SMLAWB( state_next, tmp1 - tmp4, lambda_Q16 );\n        state[ 1 ] = tmp4;\n        acc_Q22 = silk_RSHIFT( order, 1 );\n        acc_Q22 = silk_SMLAWB( acc_Q22, tmp4, coef_Q13[ 0 ] );\n\n        /* Loop over allpass sections */\n        for( i = 2; i < order; i += 2 ) {\n            /* Output of allpass section */\n            tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );\n            state_cur = tmp1;\n            acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );\n            /* Output of allpass section */\n            tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );\n            state_next = tmp2;\n            acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );\n\n\n            /* Output of allpass section */\n            tmp4 = silk_SMLAWB( state_cur, state_next - tmp3, lambda_Q16 );\n            state[ i ] = tmp3;\n            acc_Q22 = silk_SMLAWB( acc_Q22, tmp3, coef_Q13[ i - 1 ] );\n            /* Output of allpass section */\n            tmp3 = silk_SMLAWB( state_next, tmp1 - tmp4, lambda_Q16 );\n            state[ i + 1 ] = tmp4;\n            acc_Q22 = silk_SMLAWB( acc_Q22, tmp4, coef_Q13[ i ] );\n        }\n        acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );\n        res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );\n\n        state[ order ] = tmp3;\n        acc_Q22 = silk_SMLAWB( acc_Q22, tmp3, coef_Q13[ order - 1 ] );\n        res_Q2[ n+1 ] = silk_LSHIFT( (opus_int32)input[ n+1 ], 2 ) - silk_RSHIFT_ROUND( acc_Q22, 9 );\n    }\n}\n\n\n\n/* Prefilter for finding Quantizer input signal */\n#define OVERRIDE_silk_prefilt_FIX\nstatic inline void silk_prefilt_FIX(\n    silk_prefilter_state_FIX    *P,                         /* I/O  state                               */\n    opus_int32                  st_res_Q12[],               /* I    short term residual signal          */\n    opus_int32                  xw_Q3[],                    /* O    prefiltered signal                  */\n    opus_int32                  HarmShapeFIRPacked_Q12,     /* I    Harmonic shaping coeficients        */\n    opus_int                    Tilt_Q14,                   /* I    Tilt shaping coeficient             */\n    opus_int32                  LF_shp_Q14,                 /* I    Low-frequancy shaping coeficients   */\n    opus_int                    lag,                        /* I    Lag for harmonic shaping            */\n    opus_int                    length                      /* I    Length of signals                   */\n)\n{\n    opus_int   i, idx, LTP_shp_buf_idx;\n    opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;\n    opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;\n    opus_int16 *LTP_shp_buf;\n\n    /* To speed up use temp variables instead of using the struct */\n    LTP_shp_buf     = P->sLTP_shp;\n    LTP_shp_buf_idx = P->sLTP_shp_buf_idx;\n    sLF_AR_shp_Q12  = P->sLF_AR_shp_Q12;\n    sLF_MA_shp_Q12  = P->sLF_MA_shp_Q12;\n\n    if( lag > 0 ) {\n        for( i = 0; i < length; i++ ) {\n            /* unrolled loop */\n            silk_assert( HARM_SHAPE_FIR_TAPS == 3 );\n            idx = lag + LTP_shp_buf_idx;\n            n_LTP_Q12 = silk_SMULBB(            LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );\n            n_LTP_Q12 = silk_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2    ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );\n            n_LTP_Q12 = silk_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );\n\n            n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );\n            n_LF_Q10   = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );\n\n            sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );\n            sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12,  silk_LSHIFT( n_LF_Q10,   2 ) );\n\n            LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;\n            LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );\n\n            xw_Q3[i] = silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 9 );\n        }\n    }\n    else\n    {\n        for( i = 0; i < length; i++ ) {\n\n            n_LTP_Q12 = 0;\n\n            n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );\n            n_LF_Q10   = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );\n\n            sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );\n            sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12,  silk_LSHIFT( n_LF_Q10,   2 ) );\n\n            LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;\n            LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );\n\n            xw_Q3[i] = silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 9 );\n        }\n    }\n\n    /* Copy temp variable back to state */\n    P->sLF_AR_shp_Q12   = sLF_AR_shp_Q12;\n    P->sLF_MA_shp_Q12   = sLF_MA_shp_Q12;\n    P->sLTP_shp_buf_idx = LTP_shp_buf_idx;\n}\n\n#endif /* __PREFILTER_FIX_MIPSR1_H__ */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__\n#define __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n\n#undef QC\n#define QC  10\n\n#undef QS\n#define QS  14\n\n/* Autocorrelations for a warped frequency axis */\n#define OVERRIDE_silk_warped_autocorrelation_FIX\nvoid silk_warped_autocorrelation_FIX(\n          opus_int32                *corr,                                  /* O    Result [order + 1]                                                          */\n          opus_int                  *scale,                                 /* O    Scaling of the correlation vector                                           */\n    const opus_int16                *input,                                 /* I    Input data to correlate                                                     */\n    const opus_int                  warping_Q16,                            /* I    Warping coefficient                                                         */\n    const opus_int                  length,                                 /* I    Length of input                                                             */\n    const opus_int                  order                                   /* I    Correlation order (even)                                                    */\n)\n{\n    opus_int   n, i, lsh;\n    opus_int32 tmp1_QS=0, tmp2_QS=0, tmp3_QS=0, tmp4_QS=0, tmp5_QS=0, tmp6_QS=0, tmp7_QS=0, tmp8_QS=0, start_1=0, start_2=0, start_3=0;\n    opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };\n    opus_int64 corr_QC[  MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };\n    opus_int64 temp64;\n\n    opus_int32 val;\n    val = 2 * QS - QC;\n\n    /* Order must be even */\n    silk_assert( ( order & 1 ) == 0 );\n    silk_assert( 2 * QS - QC >= 0 );\n\n    /* Loop over samples */\n    for( n = 0; n < length; n=n+4 ) {\n\n        tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );\n        start_1 = tmp1_QS;\n        tmp3_QS = silk_LSHIFT32( (opus_int32)input[ n+1], QS );\n        start_2 = tmp3_QS;\n        tmp5_QS = silk_LSHIFT32( (opus_int32)input[ n+2], QS );\n        start_3 = tmp5_QS;\n        tmp7_QS = silk_LSHIFT32( (opus_int32)input[ n+3], QS );\n\n        /* Loop over allpass sections */\n        for( i = 0; i < order; i += 2 ) {\n            /* Output of allpass section */\n            tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );\n            corr_QC[  i ] = __builtin_mips_madd( corr_QC[  i ], tmp1_QS,  start_1);\n\n            tmp4_QS = silk_SMLAWB( tmp1_QS, tmp2_QS - tmp3_QS, warping_Q16 );\n            corr_QC[  i ] = __builtin_mips_madd( corr_QC[  i ], tmp3_QS,  start_2);\n\n            tmp6_QS = silk_SMLAWB( tmp3_QS, tmp4_QS - tmp5_QS, warping_Q16 );\n            corr_QC[  i ] = __builtin_mips_madd( corr_QC[  i ], tmp5_QS,  start_3);\n\n            tmp8_QS = silk_SMLAWB( tmp5_QS, tmp6_QS - tmp7_QS, warping_Q16 );\n            state_QS[ i ]  = tmp7_QS;\n            corr_QC[  i ] = __builtin_mips_madd( corr_QC[  i ], tmp7_QS, state_QS[0]);\n\n            /* Output of allpass section */\n            tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );\n            corr_QC[  i+1 ] = __builtin_mips_madd( corr_QC[  i+1 ], tmp2_QS,  start_1);\n\n            tmp3_QS = silk_SMLAWB( tmp2_QS, tmp1_QS - tmp4_QS, warping_Q16 );\n            corr_QC[  i+1 ] = __builtin_mips_madd( corr_QC[  i+1 ], tmp4_QS,  start_2);\n\n            tmp5_QS = silk_SMLAWB( tmp4_QS, tmp3_QS - tmp6_QS, warping_Q16 );\n            corr_QC[  i+1 ] = __builtin_mips_madd( corr_QC[  i+1 ], tmp6_QS,  start_3);\n\n            tmp7_QS = silk_SMLAWB( tmp6_QS, tmp5_QS - tmp8_QS, warping_Q16 );\n            state_QS[ i + 1 ]  = tmp8_QS;\n            corr_QC[  i+1 ] = __builtin_mips_madd( corr_QC[  i+1 ], tmp8_QS,  state_QS[ 0 ]);\n\n        }\n        state_QS[ order ] = tmp7_QS;\n\n        corr_QC[  order ] = __builtin_mips_madd( corr_QC[  order ], tmp1_QS,  start_1);\n        corr_QC[  order ] = __builtin_mips_madd( corr_QC[  order ], tmp3_QS,  start_2);\n        corr_QC[  order ] = __builtin_mips_madd( corr_QC[  order ], tmp5_QS,  start_3);\n        corr_QC[  order ] = __builtin_mips_madd( corr_QC[  order ], tmp7_QS,  state_QS[ 0 ]);\n    }\n\n    for(;n< length; n++ ) {\n\n        tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );\n\n        /* Loop over allpass sections */\n        for( i = 0; i < order; i += 2 ) {\n\n            /* Output of allpass section */\n            tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );\n            state_QS[ i ] = tmp1_QS;\n            corr_QC[  i ] = __builtin_mips_madd( corr_QC[  i ], tmp1_QS,   state_QS[ 0 ]);\n\n            /* Output of allpass section */\n            tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );\n            state_QS[ i + 1 ]  = tmp2_QS;\n            corr_QC[  i+1 ] = __builtin_mips_madd( corr_QC[  i+1 ], tmp2_QS,   state_QS[ 0 ]);\n        }\n        state_QS[ order ] = tmp1_QS;\n        corr_QC[  order ] = __builtin_mips_madd( corr_QC[  order ], tmp1_QS,   state_QS[ 0 ]);\n    }\n\n    temp64 =  corr_QC[ 0 ];\n    temp64 = __builtin_mips_shilo(temp64, val);\n\n    lsh = silk_CLZ64( temp64 ) - 35;\n    lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );\n    *scale = -( QC + lsh );\n    silk_assert( *scale >= -30 && *scale <= 12 );\n    if( lsh >= 0 ) {\n        for( i = 0; i < order + 1; i++ ) {\n            temp64 = corr_QC[ i ];\n            //temp64 = __builtin_mips_shilo(temp64, val);\n            temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val);\n            corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) );\n        }\n    } else {\n        for( i = 0; i < order + 1; i++ ) {\n            temp64 = corr_QC[ i ];\n            //temp64 = __builtin_mips_shilo(temp64, val);\n            temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val);\n            corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) );\n        }\n    }\n\n     corr_QC[ 0 ] = __builtin_mips_shilo(corr_QC[ 0 ], val);\n\n     silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/\n}\n#endif /* __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__ */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/noise_shape_analysis_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n#include \"stack_alloc.h\"\n#include \"tuning_parameters.h\"\n\n/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a   */\n/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */\n/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */\n/* coefficient in an array of coefficients, for monic filters.                                    */\nstatic OPUS_INLINE opus_int32 warped_gain( /* gain in Q16*/\n    const opus_int32     *coefs_Q24,\n    opus_int             lambda_Q16,\n    opus_int             order\n) {\n    opus_int   i;\n    opus_int32 gain_Q24;\n\n    lambda_Q16 = -lambda_Q16;\n    gain_Q24 = coefs_Q24[ order - 1 ];\n    for( i = order - 2; i >= 0; i-- ) {\n        gain_Q24 = silk_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 );\n    }\n    gain_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 );\n    return silk_INVERSE32_varQ( gain_Q24, 40 );\n}\n\n/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum     */\n/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */\nstatic OPUS_INLINE void limit_warped_coefs(\n    opus_int32           *coefs_syn_Q24,\n    opus_int32           *coefs_ana_Q24,\n    opus_int             lambda_Q16,\n    opus_int32           limit_Q24,\n    opus_int             order\n) {\n    opus_int   i, iter, ind = 0;\n    opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_syn_Q16, gain_ana_Q16;\n    opus_int32 nom_Q16, den_Q24;\n\n    /* Convert to monic coefficients */\n    lambda_Q16 = -lambda_Q16;\n    for( i = order - 1; i > 0; i-- ) {\n        coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );\n        coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );\n    }\n    lambda_Q16 = -lambda_Q16;\n    nom_Q16  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16,        lambda_Q16 );\n    den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );\n    gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );\n    den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );\n    gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );\n    for( i = 0; i < order; i++ ) {\n        coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );\n        coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );\n    }\n\n    for( iter = 0; iter < 10; iter++ ) {\n        /* Find maximum absolute value */\n        maxabs_Q24 = -1;\n        for( i = 0; i < order; i++ ) {\n            tmp = silk_max( silk_abs_int32( coefs_syn_Q24[ i ] ), silk_abs_int32( coefs_ana_Q24[ i ] ) );\n            if( tmp > maxabs_Q24 ) {\n                maxabs_Q24 = tmp;\n                ind = i;\n            }\n        }\n        if( maxabs_Q24 <= limit_Q24 ) {\n            /* Coefficients are within range - done */\n            return;\n        }\n\n        /* Convert back to true warped coefficients */\n        for( i = 1; i < order; i++ ) {\n            coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );\n            coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );\n        }\n        gain_syn_Q16 = silk_INVERSE32_varQ( gain_syn_Q16, 32 );\n        gain_ana_Q16 = silk_INVERSE32_varQ( gain_ana_Q16, 32 );\n        for( i = 0; i < order; i++ ) {\n            coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );\n            coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );\n        }\n\n        /* Apply bandwidth expansion */\n        chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ(\n            silk_SMULWB( maxabs_Q24 - limit_Q24, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ),\n            silk_MUL( maxabs_Q24, ind + 1 ), 22 );\n        silk_bwexpander_32( coefs_syn_Q24, order, chirp_Q16 );\n        silk_bwexpander_32( coefs_ana_Q24, order, chirp_Q16 );\n\n        /* Convert to monic warped coefficients */\n        lambda_Q16 = -lambda_Q16;\n        for( i = order - 1; i > 0; i-- ) {\n            coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );\n            coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );\n        }\n        lambda_Q16 = -lambda_Q16;\n        nom_Q16  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16,        lambda_Q16 );\n        den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );\n        gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );\n        den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );\n        gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );\n        for( i = 0; i < order; i++ ) {\n            coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );\n            coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );\n        }\n    }\n    silk_assert( 0 );\n}\n\n#if defined(MIPSr1_ASM)\n#include \"mips/noise_shape_analysis_FIX_mipsr1.h\"\n#endif\n\n/**************************************************************/\n/* Compute noise shaping coefficients and initial gain values */\n/**************************************************************/\n#ifndef OVERRIDE_silk_noise_shape_analysis_FIX\nvoid silk_noise_shape_analysis_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Encoder state FIX                                                           */\n    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Encoder control FIX                                                         */\n    const opus_int16                *pitch_res,                             /* I    LPC residual from pitch analysis                                            */\n    const opus_int16                *x,                                     /* I    Input signal [ frame_length + la_shape ]                                    */\n    int                              arch                                   /* I    Run-time architecture                                                       */\n)\n{\n    silk_shape_state_FIX *psShapeSt = &psEnc->sShape;\n    opus_int     k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;\n    opus_int32   SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;\n    opus_int32   nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;\n    opus_int32   delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;\n    opus_int32   auto_corr[     MAX_SHAPE_LPC_ORDER + 1 ];\n    opus_int32   refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];\n    opus_int32   AR1_Q24[       MAX_SHAPE_LPC_ORDER ];\n    opus_int32   AR2_Q24[       MAX_SHAPE_LPC_ORDER ];\n    VARDECL( opus_int16, x_windowed );\n    const opus_int16 *x_ptr, *pitch_res_ptr;\n    SAVE_STACK;\n\n    /* Point to start of first LPC analysis block */\n    x_ptr = x - psEnc->sCmn.la_shape;\n\n    /****************/\n    /* GAIN CONTROL */\n    /****************/\n    SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;\n\n    /* Input quality is the average of the quality in the lowest two VAD bands */\n    psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ]\n        + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );\n\n    /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */\n    psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -\n        SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 );\n\n    /* Reduce coding SNR during low speech activity */\n    if( psEnc->sCmn.useCBR == 0 ) {\n        b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;\n        b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 );\n        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,\n            silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ),                                       /* Q11*/\n            silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) );     /* Q12*/\n    }\n\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /* Reduce gains for periodic signals */\n        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );\n    } else {\n        /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */\n        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,\n            silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),\n            SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );\n    }\n\n    /*************************/\n    /* SPARSENESS PROCESSING */\n    /*************************/\n    /* Set quantizer offset */\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /* Initially set to 0; may be overruled in process_gains(..) */\n        psEnc->sCmn.indices.quantOffsetType = 0;\n        psEncCtrl->sparseness_Q8 = 0;\n    } else {\n        /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */\n        nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );\n        energy_variation_Q7 = 0;\n        log_energy_prev_Q7  = 0;\n        pitch_res_ptr = pitch_res;\n        for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {\n            silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );\n            nrg += silk_RSHIFT( nSamples, scale );           /* Q(-scale)*/\n\n            log_energy_Q7 = silk_lin2log( nrg );\n            if( k > 0 ) {\n                energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 );\n            }\n            log_energy_prev_Q7 = log_energy_Q7;\n            pitch_res_ptr += nSamples;\n        }\n\n        psEncCtrl->sparseness_Q8 = silk_RSHIFT( silk_sigm_Q15( silk_SMULWB( energy_variation_Q7 -\n            SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 );\n\n        /* Set quantization offset depending on sparseness measure */\n        if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) {\n            psEnc->sCmn.indices.quantOffsetType = 0;\n        } else {\n            psEnc->sCmn.indices.quantOffsetType = 1;\n        }\n\n        /* Increase coding SNR for sparse signals */\n        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SILK_FIX_CONST( 0.5, 8 ) );\n    }\n\n    /*******************************/\n    /* Control bandwidth expansion */\n    /*******************************/\n    /* More BWE for signals with high prediction gain */\n    strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );\n    BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),\n        silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );\n    delta_Q16  = silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - silk_SMULBB( 3, psEncCtrl->coding_quality_Q14 ),\n        SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) );\n    BWExp1_Q16 = silk_SUB32( BWExp1_Q16, delta_Q16 );\n    BWExp2_Q16 = silk_ADD32( BWExp2_Q16, delta_Q16 );\n    /* BWExp1 will be applied after BWExp2, so make it relative */\n    BWExp1_Q16 = silk_DIV32_16( silk_LSHIFT( BWExp1_Q16, 14 ), silk_RSHIFT( BWExp2_Q16, 2 ) );\n\n    if( psEnc->sCmn.warping_Q16 > 0 ) {\n        /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */\n        warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );\n    } else {\n        warping_Q16 = 0;\n    }\n\n    /********************************************/\n    /* Compute noise shaping AR coefs and gains */\n    /********************************************/\n    ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 );\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        /* Apply window: sine slope followed by flat part followed by cosine slope */\n        opus_int shift, slope_part, flat_part;\n        flat_part = psEnc->sCmn.fs_kHz * 3;\n        slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );\n\n        silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );\n        shift = slope_part;\n        silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );\n        shift += flat_part;\n        silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );\n\n        /* Update pointer: next LPC analysis block */\n        x_ptr += psEnc->sCmn.subfr_length;\n\n        if( psEnc->sCmn.warping_Q16 > 0 ) {\n            /* Calculate warped auto correlation */\n            silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );\n        } else {\n            /* Calculate regular auto correlation */\n            silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );\n        }\n\n        /* Add white noise, as a fraction of energy */\n        auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ),\n            SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );\n\n        /* Calculate the reflection coefficients using schur */\n        nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );\n        silk_assert( nrg >= 0 );\n\n        /* Convert reflection coefficients to prediction coefficients */\n        silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );\n\n        Qnrg = -scale;          /* range: -12...30*/\n        silk_assert( Qnrg >= -12 );\n        silk_assert( Qnrg <=  30 );\n\n        /* Make sure that Qnrg is an even number */\n        if( Qnrg & 1 ) {\n            Qnrg -= 1;\n            nrg >>= 1;\n        }\n\n        tmp32 = silk_SQRT_APPROX( nrg );\n        Qnrg >>= 1;             /* range: -6...15*/\n\n        psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( tmp32, 16 - Qnrg );\n\n        if( psEnc->sCmn.warping_Q16 > 0 ) {\n            /* Adjust gain for warping */\n            gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );\n            silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );\n            if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) {\n               psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;\n            } else {\n               psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );\n            }\n        }\n\n        /* Bandwidth expansion for synthesis filter shaping */\n        silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );\n\n        /* Compute noise shaping filter coefficients */\n        silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) );\n\n        /* Bandwidth expansion for analysis filter shaping */\n        silk_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) );\n        silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );\n\n        /* Ratio of prediction gains, in energy domain */\n        pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder );\n        nrg         = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder );\n\n        /*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/\n        pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );\n        psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 );\n\n        /* Convert to monic warped prediction coefficients and limit absolute values */\n        limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );\n\n        /* Convert from Q24 to Q13 and store in int16 */\n        for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {\n            psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) );\n            psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) );\n        }\n    }\n\n    /*****************/\n    /* Gain tweaking */\n    /*****************/\n    /* Increase gains during low speech activity and put lower limit on gains */\n    gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );\n    gain_add_Q16  = silk_log2lin(  silk_SMLAWB(  SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) );\n    silk_assert( gain_mult_Q16 > 0 );\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );\n        silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );\n        psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );\n    }\n\n    gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + silk_RSHIFT_ROUND( silk_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ),\n        psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 );\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        psEncCtrl->GainsPre_Q14[ k ] = silk_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] );\n    }\n\n    /************************************************/\n    /* Control low-frequency shaping and noise tilt */\n    /************************************************/\n    /* Less low frequency shaping for noisy inputs */\n    strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),\n        SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );\n    strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */\n        /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/\n        opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );\n        for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n            b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] );\n            /* Pack two coefficients in one int32 */\n            psEncCtrl->LF_shp_Q14[ k ]  = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 );\n            psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );\n        }\n        silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/\n        Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) -\n            silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ),\n                silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );\n    } else {\n        b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/\n        /* Pack two coefficients in one int32 */\n        psEncCtrl->LF_shp_Q14[ 0 ]  = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 -\n            silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );\n        psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );\n        for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {\n            psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];\n        }\n        Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );\n    }\n\n    /****************************/\n    /* HARMONIC SHAPING CONTROL */\n    /****************************/\n    /* Control boosting of harmonic frequencies */\n    HarmBoost_Q16 = silk_SMULWB( silk_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ),\n        psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) );\n\n    /* More harmonic boost for noisy input signals */\n    HarmBoost_Q16 = silk_SMLAWB( HarmBoost_Q16,\n        SILK_FIX_CONST( 1.0, 16 ) - silk_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) );\n\n    if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /* More harmonic noise shaping for high bitrates or noisy input */\n        HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),\n                SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),\n                psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );\n\n        /* Less harmonic noise shaping for less periodic signals */\n        HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ),\n            silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );\n    } else {\n        HarmShapeGain_Q16 = 0;\n    }\n\n    /*************************/\n    /* Smooth over subframes */\n    /*************************/\n    for( k = 0; k < MAX_NB_SUBFR; k++ ) {\n        psShapeSt->HarmBoost_smth_Q16 =\n            silk_SMLAWB( psShapeSt->HarmBoost_smth_Q16,     HarmBoost_Q16     - psShapeSt->HarmBoost_smth_Q16,     SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );\n        psShapeSt->HarmShapeGain_smth_Q16 =\n            silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );\n        psShapeSt->Tilt_smth_Q16 =\n            silk_SMLAWB( psShapeSt->Tilt_smth_Q16,          Tilt_Q16          - psShapeSt->Tilt_smth_Q16,          SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );\n\n        psEncCtrl->HarmBoost_Q14[ k ]     = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16,     2 );\n        psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );\n        psEncCtrl->Tilt_Q14[ k ]          = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16,          2 );\n    }\n    RESTORE_STACK;\n}\n#endif /* OVERRIDE_silk_noise_shape_analysis_FIX */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/pitch_analysis_core_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/***********************************************************\n* Pitch analyser function\n********************************************************** */\n#include \"SigProc_FIX.h\"\n#include \"pitch_est_defines.h\"\n#include \"stack_alloc.h\"\n#include \"debug.h\"\n#include \"pitch.h\"\n\n#define SCRATCH_SIZE    22\n#define SF_LENGTH_4KHZ  ( PE_SUBFR_LENGTH_MS * 4 )\n#define SF_LENGTH_8KHZ  ( PE_SUBFR_LENGTH_MS * 8 )\n#define MIN_LAG_4KHZ    ( PE_MIN_LAG_MS * 4 )\n#define MIN_LAG_8KHZ    ( PE_MIN_LAG_MS * 8 )\n#define MAX_LAG_4KHZ    ( PE_MAX_LAG_MS * 4 )\n#define MAX_LAG_8KHZ    ( PE_MAX_LAG_MS * 8 - 1 )\n#define CSTRIDE_4KHZ    ( MAX_LAG_4KHZ + 1 - MIN_LAG_4KHZ )\n#define CSTRIDE_8KHZ    ( MAX_LAG_8KHZ + 3 - ( MIN_LAG_8KHZ - 2 ) )\n#define D_COMP_MIN      ( MIN_LAG_8KHZ - 3 )\n#define D_COMP_MAX      ( MAX_LAG_8KHZ + 4 )\n#define D_COMP_STRIDE   ( D_COMP_MAX - D_COMP_MIN )\n\ntypedef opus_int32 silk_pe_stage3_vals[ PE_NB_STAGE3_LAGS ];\n\n/************************************************************/\n/* Internally used functions                                */\n/************************************************************/\nstatic void silk_P_Ana_calc_corr_st3(\n    silk_pe_stage3_vals cross_corr_st3[],              /* O 3 DIM correlation array */\n    const opus_int16  frame[],                         /* I vector to correlate         */\n    opus_int          start_lag,                       /* I lag offset to search around */\n    opus_int          sf_length,                       /* I length of a 5 ms subframe   */\n    opus_int          nb_subfr,                        /* I number of subframes         */\n    opus_int          complexity,                      /* I Complexity setting          */\n    int               arch                             /* I Run-time architecture       */\n);\n\nstatic void silk_P_Ana_calc_energy_st3(\n    silk_pe_stage3_vals energies_st3[],                /* O 3 DIM energy array */\n    const opus_int16  frame[],                         /* I vector to calc energy in    */\n    opus_int          start_lag,                       /* I lag offset to search around */\n    opus_int          sf_length,                       /* I length of one 5 ms subframe */\n    opus_int          nb_subfr,                        /* I number of subframes         */\n    opus_int          complexity,                      /* I Complexity setting          */\n    int               arch                             /* I Run-time architecture       */\n);\n\n/*************************************************************/\n/*      FIXED POINT CORE PITCH ANALYSIS FUNCTION             */\n/*************************************************************/\nopus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0 voiced, 1 unvoiced                      */\n    const opus_int16            *frame,             /* I    Signal of length PE_FRAME_LENGTH_MS*Fs_kHz                  */\n    opus_int                    *pitch_out,         /* O    4 pitch lag values                                          */\n    opus_int16                  *lagIndex,          /* O    Lag Index                                                   */\n    opus_int8                   *contourIndex,      /* O    Pitch contour Index                                         */\n    opus_int                    *LTPCorr_Q15,       /* I/O  Normalized correlation; input: value from previous frame    */\n    opus_int                    prevLag,            /* I    Last lag of previous frame; set to zero is unvoiced         */\n    const opus_int32            search_thres1_Q16,  /* I    First stage threshold for lag candidates 0 - 1              */\n    const opus_int              search_thres2_Q13,  /* I    Final threshold for lag candidates 0 - 1                    */\n    const opus_int              Fs_kHz,             /* I    Sample frequency (kHz)                                      */\n    const opus_int              complexity,         /* I    Complexity setting, 0-2, where 2 is highest                 */\n    const opus_int              nb_subfr,           /* I    number of 5 ms subframes                                    */\n    int                         arch                /* I    Run-time architecture                                       */\n)\n{\n    VARDECL( opus_int16, frame_8kHz );\n    VARDECL( opus_int16, frame_4kHz );\n    opus_int32 filt_state[ 6 ];\n    const opus_int16 *input_frame_ptr;\n    opus_int   i, k, d, j;\n    VARDECL( opus_int16, C );\n    VARDECL( opus_int32, xcorr32 );\n    const opus_int16 *target_ptr, *basis_ptr;\n    opus_int32 cross_corr, normalizer, energy, shift, energy_basis, energy_target;\n    opus_int   d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp;\n    VARDECL( opus_int16, d_comp );\n    opus_int32 sum, threshold, lag_counter;\n    opus_int   CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new;\n    opus_int32 CC[ PE_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new;\n    VARDECL( silk_pe_stage3_vals, energies_st3 );\n    VARDECL( silk_pe_stage3_vals, cross_corr_st3 );\n    opus_int   frame_length, frame_length_8kHz, frame_length_4kHz;\n    opus_int   sf_length;\n    opus_int   min_lag;\n    opus_int   max_lag;\n    opus_int32 contour_bias_Q15, diff;\n    opus_int   nb_cbk_search, cbk_size;\n    opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q13;\n    const opus_int8 *Lag_CB_ptr;\n    SAVE_STACK;\n    /* Check for valid sampling frequency */\n    silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );\n\n    /* Check for valid complexity setting */\n    silk_assert( complexity >= SILK_PE_MIN_COMPLEX );\n    silk_assert( complexity <= SILK_PE_MAX_COMPLEX );\n\n    silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) );\n    silk_assert( search_thres2_Q13 >= 0 && search_thres2_Q13 <= (1<<13) );\n\n    /* Set up frame lengths max / min lag for the sampling frequency */\n    frame_length      = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;\n    frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;\n    frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;\n    sf_length         = PE_SUBFR_LENGTH_MS * Fs_kHz;\n    min_lag           = PE_MIN_LAG_MS * Fs_kHz;\n    max_lag           = PE_MAX_LAG_MS * Fs_kHz - 1;\n\n    /* Resample from input sampled at Fs_kHz to 8 kHz */\n    ALLOC( frame_8kHz, frame_length_8kHz, opus_int16 );\n    if( Fs_kHz == 16 ) {\n        silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );\n        silk_resampler_down2( filt_state, frame_8kHz, frame, frame_length );\n    } else if( Fs_kHz == 12 ) {\n        silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );\n        silk_resampler_down2_3( filt_state, frame_8kHz, frame, frame_length );\n    } else {\n        silk_assert( Fs_kHz == 8 );\n        silk_memcpy( frame_8kHz, frame, frame_length_8kHz * sizeof(opus_int16) );\n    }\n\n    /* Decimate again to 4 kHz */\n    silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */\n    ALLOC( frame_4kHz, frame_length_4kHz, opus_int16 );\n    silk_resampler_down2( filt_state, frame_4kHz, frame_8kHz, frame_length_8kHz );\n\n    /* Low-pass filter */\n    for( i = frame_length_4kHz - 1; i > 0; i-- ) {\n        frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );\n    }\n\n    /*******************************************************************************\n    ** Scale 4 kHz signal down to prevent correlations measures from overflowing\n    ** find scaling as max scaling for each 8kHz(?) subframe\n    *******************************************************************************/\n\n    /* Inner product is calculated with different lengths, so scale for the worst case */\n    silk_sum_sqr_shift( &energy, &shift, frame_4kHz, frame_length_4kHz );\n    if( shift > 0 ) {\n        shift = silk_RSHIFT( shift, 1 );\n        for( i = 0; i < frame_length_4kHz; i++ ) {\n            frame_4kHz[ i ] = silk_RSHIFT( frame_4kHz[ i ], shift );\n        }\n    }\n\n    /******************************************************************************\n    * FIRST STAGE, operating in 4 khz\n    ******************************************************************************/\n    ALLOC( C, nb_subfr * CSTRIDE_8KHZ, opus_int16 );\n    ALLOC( xcorr32, MAX_LAG_4KHZ-MIN_LAG_4KHZ+1, opus_int32 );\n    silk_memset( C, 0, (nb_subfr >> 1) * CSTRIDE_4KHZ * sizeof( opus_int16 ) );\n    target_ptr = &frame_4kHz[ silk_LSHIFT( SF_LENGTH_4KHZ, 2 ) ];\n    for( k = 0; k < nb_subfr >> 1; k++ ) {\n        /* Check that we are within range of the array */\n        silk_assert( target_ptr >= frame_4kHz );\n        silk_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );\n\n        basis_ptr = target_ptr - MIN_LAG_4KHZ;\n\n        /* Check that we are within range of the array */\n        silk_assert( basis_ptr >= frame_4kHz );\n        silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );\n\n        celt_pitch_xcorr( target_ptr, target_ptr - MAX_LAG_4KHZ, xcorr32, SF_LENGTH_8KHZ, MAX_LAG_4KHZ - MIN_LAG_4KHZ + 1, arch );\n\n        /* Calculate first vector products before loop */\n        cross_corr = xcorr32[ MAX_LAG_4KHZ - MIN_LAG_4KHZ ];\n        normalizer = silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch );\n        normalizer = silk_ADD32( normalizer, silk_inner_prod_aligned( basis_ptr,  basis_ptr, SF_LENGTH_8KHZ, arch ) );\n        normalizer = silk_ADD32( normalizer, silk_SMULBB( SF_LENGTH_8KHZ, 4000 ) );\n\n        matrix_ptr( C, k, 0, CSTRIDE_4KHZ ) =\n            (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 );                      /* Q13 */\n\n        /* From now on normalizer is computed recursively */\n        for( d = MIN_LAG_4KHZ + 1; d <= MAX_LAG_4KHZ; d++ ) {\n            basis_ptr--;\n\n            /* Check that we are within range of the array */\n            silk_assert( basis_ptr >= frame_4kHz );\n            silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );\n\n            cross_corr = xcorr32[ MAX_LAG_4KHZ - d ];\n\n            /* Add contribution of new sample and remove contribution from oldest sample */\n            normalizer = silk_ADD32( normalizer,\n                silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) -\n                silk_SMULBB( basis_ptr[ SF_LENGTH_8KHZ ], basis_ptr[ SF_LENGTH_8KHZ ] ) );\n\n            matrix_ptr( C, k, d - MIN_LAG_4KHZ, CSTRIDE_4KHZ) =\n                (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 );                  /* Q13 */\n        }\n        /* Update target pointer */\n        target_ptr += SF_LENGTH_8KHZ;\n    }\n\n    /* Combine two subframes into single correlation measure and apply short-lag bias */\n    if( nb_subfr == PE_MAX_NB_SUBFR ) {\n        for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) {\n            sum = (opus_int32)matrix_ptr( C, 0, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ )\n                + (opus_int32)matrix_ptr( C, 1, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ );               /* Q14 */\n            sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) );                                /* Q14 */\n            C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum;                                            /* Q14 */\n        }\n    } else {\n        /* Only short-lag bias */\n        for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) {\n            sum = silk_LSHIFT( (opus_int32)C[ i - MIN_LAG_4KHZ ], 1 );                          /* Q14 */\n            sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) );                                /* Q14 */\n            C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum;                                            /* Q14 */\n        }\n    }\n\n    /* Sort */\n    length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 );\n    silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );\n    silk_insertion_sort_decreasing_int16( C, d_srch, CSTRIDE_4KHZ,\n                                          length_d_srch );\n\n    /* Escape if correlation is very low already here */\n    Cmax = (opus_int)C[ 0 ];                                                    /* Q14 */\n    if( Cmax < SILK_FIX_CONST( 0.2, 14 ) ) {\n        silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );\n        *LTPCorr_Q15  = 0;\n        *lagIndex     = 0;\n        *contourIndex = 0;\n        RESTORE_STACK;\n        return 1;\n    }\n\n    threshold = silk_SMULWB( search_thres1_Q16, Cmax );\n    for( i = 0; i < length_d_srch; i++ ) {\n        /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */\n        if( C[ i ] > threshold ) {\n            d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + MIN_LAG_4KHZ, 1 );\n        } else {\n            length_d_srch = i;\n            break;\n        }\n    }\n    silk_assert( length_d_srch > 0 );\n\n    ALLOC( d_comp, D_COMP_STRIDE, opus_int16 );\n    for( i = D_COMP_MIN; i < D_COMP_MAX; i++ ) {\n        d_comp[ i - D_COMP_MIN ] = 0;\n    }\n    for( i = 0; i < length_d_srch; i++ ) {\n        d_comp[ d_srch[ i ] - D_COMP_MIN ] = 1;\n    }\n\n    /* Convolution */\n    for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) {\n        d_comp[ i - D_COMP_MIN ] +=\n            d_comp[ i - 1 - D_COMP_MIN ] + d_comp[ i - 2 - D_COMP_MIN ];\n    }\n\n    length_d_srch = 0;\n    for( i = MIN_LAG_8KHZ; i < MAX_LAG_8KHZ + 1; i++ ) {\n        if( d_comp[ i + 1 - D_COMP_MIN ] > 0 ) {\n            d_srch[ length_d_srch ] = i;\n            length_d_srch++;\n        }\n    }\n\n    /* Convolution */\n    for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) {\n        d_comp[ i - D_COMP_MIN ] += d_comp[ i - 1 - D_COMP_MIN ]\n            + d_comp[ i - 2 - D_COMP_MIN ] + d_comp[ i - 3 - D_COMP_MIN ];\n    }\n\n    length_d_comp = 0;\n    for( i = MIN_LAG_8KHZ; i < D_COMP_MAX; i++ ) {\n        if( d_comp[ i - D_COMP_MIN ] > 0 ) {\n            d_comp[ length_d_comp ] = i - 2;\n            length_d_comp++;\n        }\n    }\n\n    /**********************************************************************************\n    ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation\n    *************************************************************************************/\n\n    /******************************************************************************\n    ** Scale signal down to avoid correlations measures from overflowing\n    *******************************************************************************/\n    /* find scaling as max scaling for each subframe */\n    silk_sum_sqr_shift( &energy, &shift, frame_8kHz, frame_length_8kHz );\n    if( shift > 0 ) {\n        shift = silk_RSHIFT( shift, 1 );\n        for( i = 0; i < frame_length_8kHz; i++ ) {\n            frame_8kHz[ i ] = silk_RSHIFT( frame_8kHz[ i ], shift );\n        }\n    }\n\n    /*********************************************************************************\n    * Find energy of each subframe projected onto its history, for a range of delays\n    *********************************************************************************/\n    silk_memset( C, 0, nb_subfr * CSTRIDE_8KHZ * sizeof( opus_int16 ) );\n\n    target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ];\n    for( k = 0; k < nb_subfr; k++ ) {\n\n        /* Check that we are within range of the array */\n        silk_assert( target_ptr >= frame_8kHz );\n        silk_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );\n\n        energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch ), 1 );\n        for( j = 0; j < length_d_comp; j++ ) {\n            d = d_comp[ j ];\n            basis_ptr = target_ptr - d;\n\n            /* Check that we are within range of the array */\n            silk_assert( basis_ptr >= frame_8kHz );\n            silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );\n\n            cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, SF_LENGTH_8KHZ, arch );\n            if( cross_corr > 0 ) {\n                energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch );\n                matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) =\n                    (opus_int16)silk_DIV32_varQ( cross_corr,\n                                                 silk_ADD32( energy_target,\n                                                             energy_basis ),\n                                                 13 + 1 );                                      /* Q13 */\n            } else {\n                matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = 0;\n            }\n        }\n        target_ptr += SF_LENGTH_8KHZ;\n    }\n\n    /* search over lag range and lags codebook */\n    /* scale factor for lag codebook, as a function of center lag */\n\n    CCmax   = silk_int32_MIN;\n    CCmax_b = silk_int32_MIN;\n\n    CBimax = 0; /* To avoid returning undefined lag values */\n    lag = -1;   /* To check if lag with strong enough correlation has been found */\n\n    if( prevLag > 0 ) {\n        if( Fs_kHz == 12 ) {\n            prevLag = silk_DIV32_16( silk_LSHIFT( prevLag, 1 ), 3 );\n        } else if( Fs_kHz == 16 ) {\n            prevLag = silk_RSHIFT( prevLag, 1 );\n        }\n        prevLag_log2_Q7 = silk_lin2log( (opus_int32)prevLag );\n    } else {\n        prevLag_log2_Q7 = 0;\n    }\n    silk_assert( search_thres2_Q13 == silk_SAT16( search_thres2_Q13 ) );\n    /* Set up stage 2 codebook based on number of subframes */\n    if( nb_subfr == PE_MAX_NB_SUBFR ) {\n        cbk_size   = PE_NB_CBKS_STAGE2_EXT;\n        Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];\n        if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) {\n            /* If input is 8 khz use a larger codebook here because it is last stage */\n            nb_cbk_search = PE_NB_CBKS_STAGE2_EXT;\n        } else {\n            nb_cbk_search = PE_NB_CBKS_STAGE2;\n        }\n    } else {\n        cbk_size       = PE_NB_CBKS_STAGE2_10MS;\n        Lag_CB_ptr     = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];\n        nb_cbk_search  = PE_NB_CBKS_STAGE2_10MS;\n    }\n\n    for( k = 0; k < length_d_srch; k++ ) {\n        d = d_srch[ k ];\n        for( j = 0; j < nb_cbk_search; j++ ) {\n            CC[ j ] = 0;\n            for( i = 0; i < nb_subfr; i++ ) {\n                opus_int d_subfr;\n                /* Try all codebooks */\n                d_subfr = d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size );\n                CC[ j ] = CC[ j ]\n                    + (opus_int32)matrix_ptr( C, i,\n                                              d_subfr - ( MIN_LAG_8KHZ - 2 ),\n                                              CSTRIDE_8KHZ );\n            }\n        }\n        /* Find best codebook */\n        CCmax_new = silk_int32_MIN;\n        CBimax_new = 0;\n        for( i = 0; i < nb_cbk_search; i++ ) {\n            if( CC[ i ] > CCmax_new ) {\n                CCmax_new = CC[ i ];\n                CBimax_new = i;\n            }\n        }\n\n        /* Bias towards shorter lags */\n        lag_log2_Q7 = silk_lin2log( d ); /* Q7 */\n        silk_assert( lag_log2_Q7 == silk_SAT16( lag_log2_Q7 ) );\n        silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) ) );\n        CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ), lag_log2_Q7 ), 7 ); /* Q13 */\n\n        /* Bias towards previous lag */\n        silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) ) );\n        if( prevLag > 0 ) {\n            delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7;\n            silk_assert( delta_lag_log2_sqr_Q7 == silk_SAT16( delta_lag_log2_sqr_Q7 ) );\n            delta_lag_log2_sqr_Q7 = silk_RSHIFT( silk_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 );\n            prev_lag_bias_Q13 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ), *LTPCorr_Q15 ), 15 ); /* Q13 */\n            prev_lag_bias_Q13 = silk_DIV32( silk_MUL( prev_lag_bias_Q13, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + SILK_FIX_CONST( 0.5, 7 ) );\n            CCmax_new_b -= prev_lag_bias_Q13; /* Q13 */\n        }\n\n        if( CCmax_new_b > CCmax_b                                   &&  /* Find maximum biased correlation                  */\n            CCmax_new > silk_SMULBB( nb_subfr, search_thres2_Q13 )  &&  /* Correlation needs to be high enough to be voiced */\n            silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= MIN_LAG_8KHZ      /* Lag must be in range                             */\n         ) {\n            CCmax_b = CCmax_new_b;\n            CCmax   = CCmax_new;\n            lag     = d;\n            CBimax  = CBimax_new;\n        }\n    }\n\n    if( lag == -1 ) {\n        /* No suitable candidate found */\n        silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );\n        *LTPCorr_Q15  = 0;\n        *lagIndex     = 0;\n        *contourIndex = 0;\n        RESTORE_STACK;\n        return 1;\n    }\n\n    /* Output normalized correlation */\n    *LTPCorr_Q15 = (opus_int)silk_LSHIFT( silk_DIV32_16( CCmax, nb_subfr ), 2 );\n    silk_assert( *LTPCorr_Q15 >= 0 );\n\n    if( Fs_kHz > 8 ) {\n        VARDECL( opus_int16, scratch_mem );\n        /***************************************************************************/\n        /* Scale input signal down to avoid correlations measures from overflowing */\n        /***************************************************************************/\n        /* find scaling as max scaling for each subframe */\n        silk_sum_sqr_shift( &energy, &shift, frame, frame_length );\n        ALLOC( scratch_mem, shift > 0 ? frame_length : ALLOC_NONE, opus_int16 );\n        if( shift > 0 ) {\n            /* Move signal to scratch mem because the input signal should be unchanged */\n            shift = silk_RSHIFT( shift, 1 );\n            for( i = 0; i < frame_length; i++ ) {\n                scratch_mem[ i ] = silk_RSHIFT( frame[ i ], shift );\n            }\n            input_frame_ptr = scratch_mem;\n        } else {\n            input_frame_ptr = frame;\n        }\n\n        /* Search in original signal */\n\n        CBimax_old = CBimax;\n        /* Compensate for decimation */\n        silk_assert( lag == silk_SAT16( lag ) );\n        if( Fs_kHz == 12 ) {\n            lag = silk_RSHIFT( silk_SMULBB( lag, 3 ), 1 );\n        } else if( Fs_kHz == 16 ) {\n            lag = silk_LSHIFT( lag, 1 );\n        } else {\n            lag = silk_SMULBB( lag, 3 );\n        }\n\n        lag = silk_LIMIT_int( lag, min_lag, max_lag );\n        start_lag = silk_max_int( lag - 2, min_lag );\n        end_lag   = silk_min_int( lag + 2, max_lag );\n        lag_new   = lag;                                    /* to avoid undefined lag */\n        CBimax    = 0;                                      /* to avoid undefined lag */\n\n        CCmax = silk_int32_MIN;\n        /* pitch lags according to second stage */\n        for( k = 0; k < nb_subfr; k++ ) {\n            pitch_out[ k ] = lag + 2 * silk_CB_lags_stage2[ k ][ CBimax_old ];\n        }\n\n        /* Set up codebook parameters according to complexity setting and frame length */\n        if( nb_subfr == PE_MAX_NB_SUBFR ) {\n            nb_cbk_search   = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];\n            cbk_size        = PE_NB_CBKS_STAGE3_MAX;\n            Lag_CB_ptr      = &silk_CB_lags_stage3[ 0 ][ 0 ];\n        } else {\n            nb_cbk_search   = PE_NB_CBKS_STAGE3_10MS;\n            cbk_size        = PE_NB_CBKS_STAGE3_10MS;\n            Lag_CB_ptr      = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];\n        }\n\n        /* Calculate the correlations and energies needed in stage 3 */\n        ALLOC( energies_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );\n        ALLOC( cross_corr_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );\n        silk_P_Ana_calc_corr_st3(  cross_corr_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity, arch );\n        silk_P_Ana_calc_energy_st3( energies_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity, arch );\n\n        lag_counter = 0;\n        silk_assert( lag == silk_SAT16( lag ) );\n        contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag );\n\n        target_ptr = &input_frame_ptr[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];\n        energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, nb_subfr * sf_length, arch ), 1 );\n        for( d = start_lag; d <= end_lag; d++ ) {\n            for( j = 0; j < nb_cbk_search; j++ ) {\n                cross_corr = 0;\n                energy     = energy_target;\n                for( k = 0; k < nb_subfr; k++ ) {\n                    cross_corr = silk_ADD32( cross_corr,\n                        matrix_ptr( cross_corr_st3, k, j,\n                                    nb_cbk_search )[ lag_counter ] );\n                    energy     = silk_ADD32( energy,\n                        matrix_ptr( energies_st3, k, j,\n                                    nb_cbk_search )[ lag_counter ] );\n                    silk_assert( energy >= 0 );\n                }\n                if( cross_corr > 0 ) {\n                    CCmax_new = silk_DIV32_varQ( cross_corr, energy, 13 + 1 );          /* Q13 */\n                    /* Reduce depending on flatness of contour */\n                    diff = silk_int16_MAX - silk_MUL( contour_bias_Q15, j );            /* Q15 */\n                    silk_assert( diff == silk_SAT16( diff ) );\n                    CCmax_new = silk_SMULWB( CCmax_new, diff );                         /* Q14 */\n                } else {\n                    CCmax_new = 0;\n                }\n\n                if( CCmax_new > CCmax && ( d + silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) {\n                    CCmax   = CCmax_new;\n                    lag_new = d;\n                    CBimax  = j;\n                }\n            }\n            lag_counter++;\n        }\n\n        for( k = 0; k < nb_subfr; k++ ) {\n            pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );\n            pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz );\n        }\n        *lagIndex = (opus_int16)( lag_new - min_lag);\n        *contourIndex = (opus_int8)CBimax;\n    } else {        /* Fs_kHz == 8 */\n        /* Save Lags */\n        for( k = 0; k < nb_subfr; k++ ) {\n            pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );\n            pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], MIN_LAG_8KHZ, PE_MAX_LAG_MS * 8 );\n        }\n        *lagIndex = (opus_int16)( lag - MIN_LAG_8KHZ );\n        *contourIndex = (opus_int8)CBimax;\n    }\n    silk_assert( *lagIndex >= 0 );\n    /* return as voiced */\n    RESTORE_STACK;\n    return 0;\n}\n\n/***********************************************************************\n * Calculates the correlations used in stage 3 search. In order to cover\n * the whole lag codebook for all the searched offset lags (lag +- 2),\n * the following correlations are needed in each sub frame:\n *\n * sf1: lag range [-8,...,7] total 16 correlations\n * sf2: lag range [-4,...,4] total 9 correlations\n * sf3: lag range [-3,....4] total 8 correltions\n * sf4: lag range [-6,....8] total 15 correlations\n *\n * In total 48 correlations. The direct implementation computed in worst\n * case 4*12*5 = 240 correlations, but more likely around 120.\n ***********************************************************************/\nstatic void silk_P_Ana_calc_corr_st3(\n    silk_pe_stage3_vals cross_corr_st3[],              /* O 3 DIM correlation array */\n    const opus_int16  frame[],                         /* I vector to correlate         */\n    opus_int          start_lag,                       /* I lag offset to search around */\n    opus_int          sf_length,                       /* I length of a 5 ms subframe   */\n    opus_int          nb_subfr,                        /* I number of subframes         */\n    opus_int          complexity,                      /* I Complexity setting          */\n    int               arch                             /* I Run-time architecture       */\n)\n{\n    const opus_int16 *target_ptr;\n    opus_int   i, j, k, lag_counter, lag_low, lag_high;\n    opus_int   nb_cbk_search, delta, idx, cbk_size;\n    VARDECL( opus_int32, scratch_mem );\n    VARDECL( opus_int32, xcorr32 );\n    const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;\n    SAVE_STACK;\n\n    silk_assert( complexity >= SILK_PE_MIN_COMPLEX );\n    silk_assert( complexity <= SILK_PE_MAX_COMPLEX );\n\n    if( nb_subfr == PE_MAX_NB_SUBFR ) {\n        Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];\n        Lag_CB_ptr    = &silk_CB_lags_stage3[ 0 ][ 0 ];\n        nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];\n        cbk_size      = PE_NB_CBKS_STAGE3_MAX;\n    } else {\n        silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);\n        Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];\n        Lag_CB_ptr    = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];\n        nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;\n        cbk_size      = PE_NB_CBKS_STAGE3_10MS;\n    }\n    ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 );\n    ALLOC( xcorr32, SCRATCH_SIZE, opus_int32 );\n\n    target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */\n    for( k = 0; k < nb_subfr; k++ ) {\n        lag_counter = 0;\n\n        /* Calculate the correlations for each subframe */\n        lag_low  = matrix_ptr( Lag_range_ptr, k, 0, 2 );\n        lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 );\n        silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);\n        celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr32, sf_length, lag_high - lag_low + 1, arch );\n        for( j = lag_low; j <= lag_high; j++ ) {\n            silk_assert( lag_counter < SCRATCH_SIZE );\n            scratch_mem[ lag_counter ] = xcorr32[ lag_high - j ];\n            lag_counter++;\n        }\n\n        delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );\n        for( i = 0; i < nb_cbk_search; i++ ) {\n            /* Fill out the 3 dim array that stores the correlations for */\n            /* each code_book vector for each start lag */\n            idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;\n            for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {\n                silk_assert( idx + j < SCRATCH_SIZE );\n                silk_assert( idx + j < lag_counter );\n                matrix_ptr( cross_corr_st3, k, i, nb_cbk_search )[ j ] =\n                    scratch_mem[ idx + j ];\n            }\n        }\n        target_ptr += sf_length;\n    }\n    RESTORE_STACK;\n}\n\n/********************************************************************/\n/* Calculate the energies for first two subframes. The energies are */\n/* calculated recursively.                                          */\n/********************************************************************/\nstatic void silk_P_Ana_calc_energy_st3(\n    silk_pe_stage3_vals energies_st3[],                 /* O 3 DIM energy array */\n    const opus_int16  frame[],                          /* I vector to calc energy in    */\n    opus_int          start_lag,                        /* I lag offset to search around */\n    opus_int          sf_length,                        /* I length of one 5 ms subframe */\n    opus_int          nb_subfr,                         /* I number of subframes         */\n    opus_int          complexity,                       /* I Complexity setting          */\n    int               arch                              /* I Run-time architecture       */\n)\n{\n    const opus_int16 *target_ptr, *basis_ptr;\n    opus_int32 energy;\n    opus_int   k, i, j, lag_counter;\n    opus_int   nb_cbk_search, delta, idx, cbk_size, lag_diff;\n    VARDECL( opus_int32, scratch_mem );\n    const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;\n    SAVE_STACK;\n\n    silk_assert( complexity >= SILK_PE_MIN_COMPLEX );\n    silk_assert( complexity <= SILK_PE_MAX_COMPLEX );\n\n    if( nb_subfr == PE_MAX_NB_SUBFR ) {\n        Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];\n        Lag_CB_ptr    = &silk_CB_lags_stage3[ 0 ][ 0 ];\n        nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];\n        cbk_size      = PE_NB_CBKS_STAGE3_MAX;\n    } else {\n        silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);\n        Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];\n        Lag_CB_ptr    = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];\n        nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;\n        cbk_size      = PE_NB_CBKS_STAGE3_10MS;\n    }\n    ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 );\n\n    target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ];\n    for( k = 0; k < nb_subfr; k++ ) {\n        lag_counter = 0;\n\n        /* Calculate the energy for first lag */\n        basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) );\n        energy = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length, arch );\n        silk_assert( energy >= 0 );\n        scratch_mem[ lag_counter ] = energy;\n        lag_counter++;\n\n        lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) -  matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 );\n        for( i = 1; i < lag_diff; i++ ) {\n            /* remove part outside new window */\n            energy -= silk_SMULBB( basis_ptr[ sf_length - i ], basis_ptr[ sf_length - i ] );\n            silk_assert( energy >= 0 );\n\n            /* add part that comes into window */\n            energy = silk_ADD_SAT32( energy, silk_SMULBB( basis_ptr[ -i ], basis_ptr[ -i ] ) );\n            silk_assert( energy >= 0 );\n            silk_assert( lag_counter < SCRATCH_SIZE );\n            scratch_mem[ lag_counter ] = energy;\n            lag_counter++;\n        }\n\n        delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );\n        for( i = 0; i < nb_cbk_search; i++ ) {\n            /* Fill out the 3 dim array that stores the correlations for    */\n            /* each code_book vector for each start lag                     */\n            idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;\n            for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {\n                silk_assert( idx + j < SCRATCH_SIZE );\n                silk_assert( idx + j < lag_counter );\n                matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] =\n                    scratch_mem[ idx + j ];\n                silk_assert(\n                    matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] >= 0 );\n            }\n        }\n        target_ptr += sf_length;\n    }\n    RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/prefilter_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n#include \"stack_alloc.h\"\n#include \"tuning_parameters.h\"\n\n#if defined(MIPSr1_ASM)\n#include \"mips/prefilter_FIX_mipsr1.h\"\n#endif\n\n\n#if !defined(OVERRIDE_silk_warped_LPC_analysis_filter_FIX)\n#define silk_warped_LPC_analysis_filter_FIX(state, res_Q2, coef_Q13, input, lambda_Q16, length, order, arch) \\\n    ((void)(arch),silk_warped_LPC_analysis_filter_FIX_c(state, res_Q2, coef_Q13, input, lambda_Q16, length, order))\n#endif\n\n/* Prefilter for finding Quantizer input signal */\nstatic OPUS_INLINE void silk_prefilt_FIX(\n    silk_prefilter_state_FIX    *P,                         /* I/O  state                               */\n    opus_int32                  st_res_Q12[],               /* I    short term residual signal          */\n    opus_int32                  xw_Q3[],                    /* O    prefiltered signal                  */\n    opus_int32                  HarmShapeFIRPacked_Q12,     /* I    Harmonic shaping coeficients        */\n    opus_int                    Tilt_Q14,                   /* I    Tilt shaping coeficient             */\n    opus_int32                  LF_shp_Q14,                 /* I    Low-frequancy shaping coeficients   */\n    opus_int                    lag,                        /* I    Lag for harmonic shaping            */\n    opus_int                    length                      /* I    Length of signals                   */\n);\n\nvoid silk_warped_LPC_analysis_filter_FIX_c(\n          opus_int32            state[],                    /* I/O  State [order + 1]                   */\n          opus_int32            res_Q2[],                   /* O    Residual signal [length]            */\n    const opus_int16            coef_Q13[],                 /* I    Coefficients [order]                */\n    const opus_int16            input[],                    /* I    Input signal [length]               */\n    const opus_int16            lambda_Q16,                 /* I    Warping factor                      */\n    const opus_int              length,                     /* I    Length of input signal              */\n    const opus_int              order                       /* I    Filter order (even)                 */\n)\n{\n    opus_int     n, i;\n    opus_int32   acc_Q11, tmp1, tmp2;\n\n    /* Order must be even */\n    silk_assert( ( order & 1 ) == 0 );\n\n    for( n = 0; n < length; n++ ) {\n        /* Output of lowpass section */\n        tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );\n        state[ 0 ] = silk_LSHIFT( input[ n ], 14 );\n        /* Output of allpass section */\n        tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );\n        state[ 1 ] = tmp2;\n        acc_Q11 = silk_RSHIFT( order, 1 );\n        acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );\n        /* Loop over allpass sections */\n        for( i = 2; i < order; i += 2 ) {\n            /* Output of allpass section */\n            tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );\n            state[ i ] = tmp1;\n            acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );\n            /* Output of allpass section */\n            tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );\n            state[ i + 1 ] = tmp2;\n            acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );\n        }\n        state[ order ] = tmp1;\n        acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );\n        res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );\n    }\n}\n\nvoid silk_prefilter_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Encoder state                                                               */\n    const silk_encoder_control_FIX  *psEncCtrl,                             /* I    Encoder control                                                             */\n    opus_int32                      xw_Q3[],                                /* O    Weighted signal                                                             */\n    const opus_int16                x[]                                     /* I    Speech signal                                                               */\n)\n{\n    silk_prefilter_state_FIX *P = &psEnc->sPrefilt;\n    opus_int   j, k, lag;\n    opus_int32 tmp_32;\n    const opus_int16 *AR1_shp_Q13;\n    const opus_int16 *px;\n    opus_int32 *pxw_Q3;\n    opus_int   HarmShapeGain_Q12, Tilt_Q14;\n    opus_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14;\n    VARDECL( opus_int32, x_filt_Q12 );\n    VARDECL( opus_int32, st_res_Q2 );\n    opus_int16 B_Q10[ 2 ];\n    SAVE_STACK;\n\n    /* Set up pointers */\n    px  = x;\n    pxw_Q3 = xw_Q3;\n    lag = P->lagPrev;\n    ALLOC( x_filt_Q12, psEnc->sCmn.subfr_length, opus_int32 );\n    ALLOC( st_res_Q2, psEnc->sCmn.subfr_length, opus_int32 );\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        /* Update Variables that change per sub frame */\n        if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n            lag = psEncCtrl->pitchL[ k ];\n        }\n\n        /* Noise shape parameters */\n        HarmShapeGain_Q12 = silk_SMULWB( (opus_int32)psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] );\n        silk_assert( HarmShapeGain_Q12 >= 0 );\n        HarmShapeFIRPacked_Q12  =                          silk_RSHIFT( HarmShapeGain_Q12, 2 );\n        HarmShapeFIRPacked_Q12 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q12, 1 ), 16 );\n        Tilt_Q14    = psEncCtrl->Tilt_Q14[   k ];\n        LF_shp_Q14  = psEncCtrl->LF_shp_Q14[ k ];\n        AR1_shp_Q13 = &psEncCtrl->AR1_Q13[   k * MAX_SHAPE_LPC_ORDER ];\n\n        /* Short term FIR filtering*/\n        silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res_Q2, AR1_shp_Q13, px,\n            psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder, psEnc->sCmn.arch );\n\n        /* Reduce (mainly) low frequencies during harmonic emphasis */\n        B_Q10[ 0 ] = silk_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 4 );\n        tmp_32 = silk_SMLABB( SILK_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 );   /* Q26 */\n        tmp_32 = silk_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) );    /* Q26 */\n        tmp_32 = silk_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] );                                                /* Q24 */\n        tmp_32 = silk_RSHIFT_ROUND( tmp_32, 14 );                                                                     /* Q10 */\n        B_Q10[ 1 ]= silk_SAT16( tmp_32 );\n        x_filt_Q12[ 0 ] = silk_MLA( silk_MUL( st_res_Q2[ 0 ], B_Q10[ 0 ] ), P->sHarmHP_Q2, B_Q10[ 1 ] );\n        for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {\n            x_filt_Q12[ j ] = silk_MLA( silk_MUL( st_res_Q2[ j ], B_Q10[ 0 ] ), st_res_Q2[ j - 1 ], B_Q10[ 1 ] );\n        }\n        P->sHarmHP_Q2 = st_res_Q2[ psEnc->sCmn.subfr_length - 1 ];\n\n        silk_prefilt_FIX( P, x_filt_Q12, pxw_Q3, HarmShapeFIRPacked_Q12, Tilt_Q14, LF_shp_Q14, lag, psEnc->sCmn.subfr_length );\n\n        px  += psEnc->sCmn.subfr_length;\n        pxw_Q3 += psEnc->sCmn.subfr_length;\n    }\n\n    P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ];\n    RESTORE_STACK;\n}\n\n#ifndef OVERRIDE_silk_prefilt_FIX\n/* Prefilter for finding Quantizer input signal */\nstatic OPUS_INLINE void silk_prefilt_FIX(\n    silk_prefilter_state_FIX    *P,                         /* I/O  state                               */\n    opus_int32                  st_res_Q12[],               /* I    short term residual signal          */\n    opus_int32                  xw_Q3[],                    /* O    prefiltered signal                  */\n    opus_int32                  HarmShapeFIRPacked_Q12,     /* I    Harmonic shaping coeficients        */\n    opus_int                    Tilt_Q14,                   /* I    Tilt shaping coeficient             */\n    opus_int32                  LF_shp_Q14,                 /* I    Low-frequancy shaping coeficients   */\n    opus_int                    lag,                        /* I    Lag for harmonic shaping            */\n    opus_int                    length                      /* I    Length of signals                   */\n)\n{\n    opus_int   i, idx, LTP_shp_buf_idx;\n    opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;\n    opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;\n    opus_int16 *LTP_shp_buf;\n\n    /* To speed up use temp variables instead of using the struct */\n    LTP_shp_buf     = P->sLTP_shp;\n    LTP_shp_buf_idx = P->sLTP_shp_buf_idx;\n    sLF_AR_shp_Q12  = P->sLF_AR_shp_Q12;\n    sLF_MA_shp_Q12  = P->sLF_MA_shp_Q12;\n\n    for( i = 0; i < length; i++ ) {\n        if( lag > 0 ) {\n            /* unrolled loop */\n            silk_assert( HARM_SHAPE_FIR_TAPS == 3 );\n            idx = lag + LTP_shp_buf_idx;\n            n_LTP_Q12 = silk_SMULBB(            LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );\n            n_LTP_Q12 = silk_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2    ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );\n            n_LTP_Q12 = silk_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );\n        } else {\n            n_LTP_Q12 = 0;\n        }\n\n        n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );\n        n_LF_Q10   = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );\n\n        sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );\n        sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12,  silk_LSHIFT( n_LF_Q10,   2 ) );\n\n        LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;\n        LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );\n\n        xw_Q3[i] = silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 9 );\n    }\n\n    /* Copy temp variable back to state */\n    P->sLF_AR_shp_Q12   = sLF_AR_shp_Q12;\n    P->sLF_MA_shp_Q12   = sLF_MA_shp_Q12;\n    P->sLTP_shp_buf_idx = LTP_shp_buf_idx;\n}\n#endif /* OVERRIDE_silk_prefilt_FIX */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/process_gains_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n#include \"tuning_parameters.h\"\n\n/* Processing of gains */\nvoid silk_process_gains_FIX(\n    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Encoder state                                                               */\n    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Encoder control                                                             */\n    opus_int                        condCoding                              /* I    The type of conditional coding to use                                       */\n)\n{\n    silk_shape_state_FIX *psShapeSt = &psEnc->sShape;\n    opus_int     k;\n    opus_int32   s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10;\n\n    /* Gain reduction when LTP coding gain is high */\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /*s = -0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */\n        s_Q16 = -silk_sigm_Q15( silk_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SILK_FIX_CONST( 12.0, 7 ), 4 ) );\n        for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n            psEncCtrl->Gains_Q16[ k ] = silk_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 );\n        }\n    }\n\n    /* Limit the quantized signal */\n    /* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */\n    InvMaxSqrVal_Q16 = silk_DIV32_16( silk_log2lin(\n        silk_SMULWB( SILK_FIX_CONST( 21 + 16 / 0.33, 7 ) - psEnc->sCmn.SNR_dB_Q7, SILK_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length );\n\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        /* Soft limit on ratio residual energy and squared gains */\n        ResNrg     = psEncCtrl->ResNrg[ k ];\n        ResNrgPart = silk_SMULWW( ResNrg, InvMaxSqrVal_Q16 );\n        if( psEncCtrl->ResNrgQ[ k ] > 0 ) {\n            ResNrgPart = silk_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] );\n        } else {\n            if( ResNrgPart >= silk_RSHIFT( silk_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) {\n                ResNrgPart = silk_int32_MAX;\n            } else {\n                ResNrgPart = silk_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] );\n            }\n        }\n        gain = psEncCtrl->Gains_Q16[ k ];\n        gain_squared = silk_ADD_SAT32( ResNrgPart, silk_SMMUL( gain, gain ) );\n        if( gain_squared < silk_int16_MAX ) {\n            /* recalculate with higher precision */\n            gain_squared = silk_SMLAWW( silk_LSHIFT( ResNrgPart, 16 ), gain, gain );\n            silk_assert( gain_squared > 0 );\n            gain = silk_SQRT_APPROX( gain_squared );                    /* Q8   */\n            gain = silk_min( gain, silk_int32_MAX >> 8 );\n            psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 8 );   /* Q16  */\n        } else {\n            gain = silk_SQRT_APPROX( gain_squared );                    /* Q0   */\n            gain = silk_min( gain, silk_int32_MAX >> 16 );\n            psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 16 );  /* Q16  */\n        }\n    }\n\n    /* Save unquantized gains and gain Index */\n    silk_memcpy( psEncCtrl->GainsUnq_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );\n    psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex;\n\n    /* Quantize gains */\n    silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16,\n        &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );\n\n    /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        if( psEncCtrl->LTPredCodGain_Q7 + silk_RSHIFT( psEnc->sCmn.input_tilt_Q15, 8 ) > SILK_FIX_CONST( 1.0, 7 ) ) {\n            psEnc->sCmn.indices.quantOffsetType = 0;\n        } else {\n            psEnc->sCmn.indices.quantOffsetType = 1;\n        }\n    }\n\n    /* Quantizer boundary adjustment */\n    quant_offset_Q10 = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ];\n    psEncCtrl->Lambda_Q10 = SILK_FIX_CONST( LAMBDA_OFFSET, 10 )\n                          + silk_SMULBB( SILK_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision )\n                          + silk_SMULWB( SILK_FIX_CONST( LAMBDA_SPEECH_ACT,        18 ), psEnc->sCmn.speech_activity_Q8     )\n                          + silk_SMULWB( SILK_FIX_CONST( LAMBDA_INPUT_QUALITY,     12 ), psEncCtrl->input_quality_Q14       )\n                          + silk_SMULWB( SILK_FIX_CONST( LAMBDA_CODING_QUALITY,    12 ), psEncCtrl->coding_quality_Q14      )\n                          + silk_SMULWB( SILK_FIX_CONST( LAMBDA_QUANT_OFFSET,      16 ), quant_offset_Q10                   );\n\n    silk_assert( psEncCtrl->Lambda_Q10 > 0 );\n    silk_assert( psEncCtrl->Lambda_Q10 < SILK_FIX_CONST( 2, 10 ) );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/regularize_correlations_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n\n/* Add noise to matrix diagonal */\nvoid silk_regularize_correlations_FIX(\n    opus_int32                      *XX,                                    /* I/O  Correlation matrices                                                        */\n    opus_int32                      *xx,                                    /* I/O  Correlation values                                                          */\n    opus_int32                      noise,                                  /* I    Noise to add                                                                */\n    opus_int                        D                                       /* I    Dimension of XX                                                             */\n)\n{\n    opus_int i;\n    for( i = 0; i < D; i++ ) {\n        matrix_ptr( &XX[ 0 ], i, i, D ) = silk_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise );\n    }\n    xx[ 0 ] += noise;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/residual_energy16_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n\n/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */\nopus_int32 silk_residual_energy16_covar_FIX(\n    const opus_int16                *c,                                     /* I    Prediction vector                                                           */\n    const opus_int32                *wXX,                                   /* I    Correlation matrix                                                          */\n    const opus_int32                *wXx,                                   /* I    Correlation vector                                                          */\n    opus_int32                      wxx,                                    /* I    Signal energy                                                               */\n    opus_int                        D,                                      /* I    Dimension                                                                   */\n    opus_int                        cQ                                      /* I    Q value for c vector 0 - 15                                                 */\n)\n{\n    opus_int   i, j, lshifts, Qxtra;\n    opus_int32 c_max, w_max, tmp, tmp2, nrg;\n    opus_int   cn[ MAX_MATRIX_SIZE ];\n    const opus_int32 *pRow;\n\n    /* Safety checks */\n    silk_assert( D >=  0 );\n    silk_assert( D <= 16 );\n    silk_assert( cQ >  0 );\n    silk_assert( cQ < 16 );\n\n    lshifts = 16 - cQ;\n    Qxtra = lshifts;\n\n    c_max = 0;\n    for( i = 0; i < D; i++ ) {\n        c_max = silk_max_32( c_max, silk_abs( (opus_int32)c[ i ] ) );\n    }\n    Qxtra = silk_min_int( Qxtra, silk_CLZ32( c_max ) - 17 );\n\n    w_max = silk_max_32( wXX[ 0 ], wXX[ D * D - 1 ] );\n    Qxtra = silk_min_int( Qxtra, silk_CLZ32( silk_MUL( D, silk_RSHIFT( silk_SMULWB( w_max, c_max ), 4 ) ) ) - 5 );\n    Qxtra = silk_max_int( Qxtra, 0 );\n    for( i = 0; i < D; i++ ) {\n        cn[ i ] = silk_LSHIFT( ( opus_int )c[ i ], Qxtra );\n        silk_assert( silk_abs(cn[i]) <= ( silk_int16_MAX + 1 ) ); /* Check that silk_SMLAWB can be used */\n    }\n    lshifts -= Qxtra;\n\n    /* Compute wxx - 2 * wXx * c */\n    tmp = 0;\n    for( i = 0; i < D; i++ ) {\n        tmp = silk_SMLAWB( tmp, wXx[ i ], cn[ i ] );\n    }\n    nrg = silk_RSHIFT( wxx, 1 + lshifts ) - tmp;                         /* Q: -lshifts - 1 */\n\n    /* Add c' * wXX * c, assuming wXX is symmetric */\n    tmp2 = 0;\n    for( i = 0; i < D; i++ ) {\n        tmp = 0;\n        pRow = &wXX[ i * D ];\n        for( j = i + 1; j < D; j++ ) {\n            tmp = silk_SMLAWB( tmp, pRow[ j ], cn[ j ] );\n        }\n        tmp  = silk_SMLAWB( tmp,  silk_RSHIFT( pRow[ i ], 1 ), cn[ i ] );\n        tmp2 = silk_SMLAWB( tmp2, tmp,                        cn[ i ] );\n    }\n    nrg = silk_ADD_LSHIFT32( nrg, tmp2, lshifts );                       /* Q: -lshifts - 1 */\n\n    /* Keep one bit free always, because we add them for LSF interpolation */\n    if( nrg < 1 ) {\n        nrg = 1;\n    } else if( nrg > silk_RSHIFT( silk_int32_MAX, lshifts + 2 ) ) {\n        nrg = silk_int32_MAX >> 1;\n    } else {\n        nrg = silk_LSHIFT( nrg, lshifts + 1 );                           /* Q0 */\n    }\n    return nrg;\n\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/residual_energy_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n#include \"stack_alloc.h\"\n\n/* Calculates residual energies of input subframes where all subframes have LPC_order   */\n/* of preceding samples                                                                 */\nvoid silk_residual_energy_FIX(\n          opus_int32                nrgs[ MAX_NB_SUBFR ],                   /* O    Residual energy per subframe                                                */\n          opus_int                  nrgsQ[ MAX_NB_SUBFR ],                  /* O    Q value per subframe                                                        */\n    const opus_int16                x[],                                    /* I    Input signal                                                                */\n          opus_int16                a_Q12[ 2 ][ MAX_LPC_ORDER ],            /* I    AR coefs for each frame half                                                */\n    const opus_int32                gains[ MAX_NB_SUBFR ],                  /* I    Quantization gains                                                          */\n    const opus_int                  subfr_length,                           /* I    Subframe length                                                             */\n    const opus_int                  nb_subfr,                               /* I    Number of subframes                                                         */\n    const opus_int                  LPC_order,                              /* I    LPC order                                                                   */\n          int                       arch                                    /* I    Run-time architecture                                                       */\n)\n{\n    opus_int         offset, i, j, rshift, lz1, lz2;\n    opus_int16       *LPC_res_ptr;\n    VARDECL( opus_int16, LPC_res );\n    const opus_int16 *x_ptr;\n    opus_int32       tmp32;\n    SAVE_STACK;\n\n    x_ptr  = x;\n    offset = LPC_order + subfr_length;\n\n    /* Filter input to create the LPC residual for each frame half, and measure subframe energies */\n    ALLOC( LPC_res, ( MAX_NB_SUBFR >> 1 ) * offset, opus_int16 );\n    silk_assert( ( nb_subfr >> 1 ) * ( MAX_NB_SUBFR >> 1 ) == nb_subfr );\n    for( i = 0; i < nb_subfr >> 1; i++ ) {\n        /* Calculate half frame LPC residual signal including preceding samples */\n        silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order, arch );\n\n        /* Point to first subframe of the just calculated LPC residual signal */\n        LPC_res_ptr = LPC_res + LPC_order;\n        for( j = 0; j < ( MAX_NB_SUBFR >> 1 ); j++ ) {\n            /* Measure subframe energy */\n            silk_sum_sqr_shift( &nrgs[ i * ( MAX_NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length );\n\n            /* Set Q values for the measured energy */\n            nrgsQ[ i * ( MAX_NB_SUBFR >> 1 ) + j ] = -rshift;\n\n            /* Move to next subframe */\n            LPC_res_ptr += offset;\n        }\n        /* Move to next frame half */\n        x_ptr += ( MAX_NB_SUBFR >> 1 ) * offset;\n    }\n\n    /* Apply the squared subframe gains */\n    for( i = 0; i < nb_subfr; i++ ) {\n        /* Fully upscale gains and energies */\n        lz1 = silk_CLZ32( nrgs[  i ] ) - 1;\n        lz2 = silk_CLZ32( gains[ i ] ) - 1;\n\n        tmp32 = silk_LSHIFT32( gains[ i ], lz2 );\n\n        /* Find squared gains */\n        tmp32 = silk_SMMUL( tmp32, tmp32 ); /* Q( 2 * lz2 - 32 )*/\n\n        /* Scale energies */\n        nrgs[ i ] = silk_SMMUL( tmp32, silk_LSHIFT32( nrgs[ i ], lz1 ) ); /* Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 )*/\n        nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32;\n    }\n    RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/schur64_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n\n/* Slower than schur(), but more accurate.                              */\n/* Uses SMULL(), available on armv4                                     */\nopus_int32 silk_schur64(                            /* O    returns residual energy                                     */\n    opus_int32                  rc_Q16[],           /* O    Reflection coefficients [order] Q16                         */\n    const opus_int32            c[],                /* I    Correlations [order+1]                                      */\n    opus_int32                  order               /* I    Prediction order                                            */\n)\n{\n    opus_int   k, n;\n    opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];\n    opus_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31;\n\n    silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );\n\n    /* Check for invalid input */\n    if( c[ 0 ] <= 0 ) {\n        silk_memset( rc_Q16, 0, order * sizeof( opus_int32 ) );\n        return 0;\n    }\n\n    for( k = 0; k < order + 1; k++ ) {\n        C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];\n    }\n\n    for( k = 0; k < order; k++ ) {\n        /* Check that we won't be getting an unstable rc, otherwise stop here. */\n        if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) {\n           if ( C[ k + 1 ][ 0 ] > 0 ) {\n              rc_Q16[ k ] = -SILK_FIX_CONST( .99f, 16 );\n           } else {\n              rc_Q16[ k ] = SILK_FIX_CONST( .99f, 16 );\n           }\n           k++;\n           break;\n        }\n\n        /* Get reflection coefficient: divide two Q30 values and get result in Q31 */\n        rc_tmp_Q31 = silk_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 );\n\n        /* Save the output */\n        rc_Q16[ k ] = silk_RSHIFT_ROUND( rc_tmp_Q31, 15 );\n\n        /* Update correlations */\n        for( n = 0; n < order - k; n++ ) {\n            Ctmp1_Q30 = C[ n + k + 1 ][ 0 ];\n            Ctmp2_Q30 = C[ n ][ 1 ];\n\n            /* Multiply and add the highest int32 */\n            C[ n + k + 1 ][ 0 ] = Ctmp1_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp2_Q30, 1 ), rc_tmp_Q31 );\n            C[ n ][ 1 ]         = Ctmp2_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp1_Q30, 1 ), rc_tmp_Q31 );\n        }\n    }\n\n    for(; k < order; k++ ) {\n       rc_Q16[ k ] = 0;\n    }\n\n    return silk_max_32( 1, C[ 0 ][ 1 ] );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/schur_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n\n/* Faster than schur64(), but much less accurate.                       */\n/* uses SMLAWB(), requiring armv5E and higher.                          */\nopus_int32 silk_schur(                              /* O    Returns residual energy                                     */\n    opus_int16                  *rc_Q15,            /* O    reflection coefficients [order] Q15                         */\n    const opus_int32            *c,                 /* I    correlations [order+1]                                      */\n    const opus_int32            order               /* I    prediction order                                            */\n)\n{\n    opus_int        k, n, lz;\n    opus_int32    C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];\n    opus_int32    Ctmp1, Ctmp2, rc_tmp_Q15;\n\n    silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );\n\n    /* Get number of leading zeros */\n    lz = silk_CLZ32( c[ 0 ] );\n\n    /* Copy correlations and adjust level to Q30 */\n    if( lz < 2 ) {\n        /* lz must be 1, so shift one to the right */\n        for( k = 0; k < order + 1; k++ ) {\n            C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 );\n        }\n    } else if( lz > 2 ) {\n        /* Shift to the left */\n        lz -= 2;\n        for( k = 0; k < order + 1; k++ ) {\n            C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz );\n        }\n    } else {\n        /* No need to shift */\n        for( k = 0; k < order + 1; k++ ) {\n            C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];\n        }\n    }\n\n    for( k = 0; k < order; k++ ) {\n        /* Check that we won't be getting an unstable rc, otherwise stop here. */\n        if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) {\n           if ( C[ k + 1 ][ 0 ] > 0 ) {\n              rc_Q15[ k ] = -SILK_FIX_CONST( .99f, 15 );\n           } else {\n              rc_Q15[ k ] = SILK_FIX_CONST( .99f, 15 );\n           }\n           k++;\n           break;\n        }\n\n        /* Get reflection coefficient */\n        rc_tmp_Q15 = -silk_DIV32_16( C[ k + 1 ][ 0 ], silk_max_32( silk_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) );\n\n        /* Clip (shouldn't happen for properly conditioned inputs) */\n        rc_tmp_Q15 = silk_SAT16( rc_tmp_Q15 );\n\n        /* Store */\n        rc_Q15[ k ] = (opus_int16)rc_tmp_Q15;\n\n        /* Update correlations */\n        for( n = 0; n < order - k; n++ ) {\n            Ctmp1 = C[ n + k + 1 ][ 0 ];\n            Ctmp2 = C[ n ][ 1 ];\n            C[ n + k + 1 ][ 0 ] = silk_SMLAWB( Ctmp1, silk_LSHIFT( Ctmp2, 1 ), rc_tmp_Q15 );\n            C[ n ][ 1 ]         = silk_SMLAWB( Ctmp2, silk_LSHIFT( Ctmp1, 1 ), rc_tmp_Q15 );\n        }\n    }\n\n    for(; k < order; k++ ) {\n       rc_Q15[ k ] = 0;\n    }\n\n    /* return residual energy */\n    return silk_max_32( 1, C[ 0 ][ 1 ] );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/solve_LS_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n#include \"stack_alloc.h\"\n#include \"tuning_parameters.h\"\n\n/*****************************/\n/* Internal function headers */\n/*****************************/\n\ntypedef struct {\n    opus_int32 Q36_part;\n    opus_int32 Q48_part;\n} inv_D_t;\n\n/* Factorize square matrix A into LDL form */\nstatic OPUS_INLINE void silk_LDL_factorize_FIX(\n    opus_int32          *A,         /* I/O Pointer to Symetric Square Matrix                            */\n    opus_int            M,          /* I   Size of Matrix                                               */\n    opus_int32          *L_Q16,     /* I/O Pointer to Square Upper triangular Matrix                    */\n    inv_D_t             *inv_D      /* I/O Pointer to vector holding inverted diagonal elements of D    */\n);\n\n/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */\nstatic OPUS_INLINE void silk_LS_SolveFirst_FIX(\n    const opus_int32    *L_Q16,     /* I    Pointer to Lower Triangular Matrix                          */\n    opus_int            M,          /* I    Dim of Matrix equation                                      */\n    const opus_int32    *b,         /* I    b Vector                                                    */\n    opus_int32          *x_Q16      /* O    x Vector                                                    */\n);\n\n/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */\nstatic OPUS_INLINE void silk_LS_SolveLast_FIX(\n    const opus_int32    *L_Q16,     /* I    Pointer to Lower Triangular Matrix                          */\n    const opus_int      M,          /* I    Dim of Matrix equation                                      */\n    const opus_int32    *b,         /* I    b Vector                                                    */\n    opus_int32          *x_Q16      /* O    x Vector                                                    */\n);\n\nstatic OPUS_INLINE void silk_LS_divide_Q16_FIX(\n    opus_int32          T[],        /* I/O  Numenator vector                                            */\n    inv_D_t             *inv_D,     /* I    1 / D vector                                                */\n    opus_int            M           /* I    dimension                                                   */\n);\n\n/* Solves Ax = b, assuming A is symmetric */\nvoid silk_solve_LDL_FIX(\n    opus_int32                      *A,                                     /* I    Pointer to symetric square matrix A                                         */\n    opus_int                        M,                                      /* I    Size of matrix                                                              */\n    const opus_int32                *b,                                     /* I    Pointer to b vector                                                         */\n    opus_int32                      *x_Q16                                  /* O    Pointer to x solution vector                                                */\n)\n{\n    VARDECL( opus_int32, L_Q16 );\n    opus_int32 Y[      MAX_MATRIX_SIZE ];\n    inv_D_t   inv_D[  MAX_MATRIX_SIZE ];\n    SAVE_STACK;\n\n    silk_assert( M <= MAX_MATRIX_SIZE );\n    ALLOC( L_Q16, M * M, opus_int32 );\n\n    /***************************************************\n    Factorize A by LDL such that A = L*D*L',\n    where L is lower triangular with ones on diagonal\n    ****************************************************/\n    silk_LDL_factorize_FIX( A, M, L_Q16, inv_D );\n\n    /****************************************************\n    * substitute D*L'*x = Y. ie:\n    L*D*L'*x = b => L*Y = b <=> Y = inv(L)*b\n    ******************************************************/\n    silk_LS_SolveFirst_FIX( L_Q16, M, b, Y );\n\n    /****************************************************\n    D*L'*x = Y <=> L'*x = inv(D)*Y, because D is\n    diagonal just multiply with 1/d_i\n    ****************************************************/\n    silk_LS_divide_Q16_FIX( Y, inv_D, M );\n\n    /****************************************************\n    x = inv(L') * inv(D) * Y\n    *****************************************************/\n    silk_LS_SolveLast_FIX( L_Q16, M, Y, x_Q16 );\n    RESTORE_STACK;\n}\n\nstatic OPUS_INLINE void silk_LDL_factorize_FIX(\n    opus_int32          *A,         /* I/O Pointer to Symetric Square Matrix                            */\n    opus_int            M,          /* I   Size of Matrix                                               */\n    opus_int32          *L_Q16,     /* I/O Pointer to Square Upper triangular Matrix                    */\n    inv_D_t             *inv_D      /* I/O Pointer to vector holding inverted diagonal elements of D    */\n)\n{\n    opus_int   i, j, k, status, loop_count;\n    const opus_int32 *ptr1, *ptr2;\n    opus_int32 diag_min_value, tmp_32, err;\n    opus_int32 v_Q0[ MAX_MATRIX_SIZE ], D_Q0[ MAX_MATRIX_SIZE ];\n    opus_int32 one_div_diag_Q36, one_div_diag_Q40, one_div_diag_Q48;\n\n    silk_assert( M <= MAX_MATRIX_SIZE );\n\n    status = 1;\n    diag_min_value = silk_max_32( silk_SMMUL( silk_ADD_SAT32( A[ 0 ], A[ silk_SMULBB( M, M ) - 1 ] ), SILK_FIX_CONST( FIND_LTP_COND_FAC, 31 ) ), 1 << 9 );\n    for( loop_count = 0; loop_count < M && status == 1; loop_count++ ) {\n        status = 0;\n        for( j = 0; j < M; j++ ) {\n            ptr1 = matrix_adr( L_Q16, j, 0, M );\n            tmp_32 = 0;\n            for( i = 0; i < j; i++ ) {\n                v_Q0[ i ] = silk_SMULWW(         D_Q0[ i ], ptr1[ i ] ); /* Q0 */\n                tmp_32    = silk_SMLAWW( tmp_32, v_Q0[ i ], ptr1[ i ] ); /* Q0 */\n            }\n            tmp_32 = silk_SUB32( matrix_ptr( A, j, j, M ), tmp_32 );\n\n            if( tmp_32 < diag_min_value ) {\n                tmp_32 = silk_SUB32( silk_SMULBB( loop_count + 1, diag_min_value ), tmp_32 );\n                /* Matrix not positive semi-definite, or ill conditioned */\n                for( i = 0; i < M; i++ ) {\n                    matrix_ptr( A, i, i, M ) = silk_ADD32( matrix_ptr( A, i, i, M ), tmp_32 );\n                }\n                status = 1;\n                break;\n            }\n            D_Q0[ j ] = tmp_32;                         /* always < max(Correlation) */\n\n            /* two-step division */\n            one_div_diag_Q36 = silk_INVERSE32_varQ( tmp_32, 36 );                    /* Q36 */\n            one_div_diag_Q40 = silk_LSHIFT( one_div_diag_Q36, 4 );                   /* Q40 */\n            err = silk_SUB32( (opus_int32)1 << 24, silk_SMULWW( tmp_32, one_div_diag_Q40 ) );     /* Q24 */\n            one_div_diag_Q48 = silk_SMULWW( err, one_div_diag_Q40 );                 /* Q48 */\n\n            /* Save 1/Ds */\n            inv_D[ j ].Q36_part = one_div_diag_Q36;\n            inv_D[ j ].Q48_part = one_div_diag_Q48;\n\n            matrix_ptr( L_Q16, j, j, M ) = 65536; /* 1.0 in Q16 */\n            ptr1 = matrix_adr( A, j, 0, M );\n            ptr2 = matrix_adr( L_Q16, j + 1, 0, M );\n            for( i = j + 1; i < M; i++ ) {\n                tmp_32 = 0;\n                for( k = 0; k < j; k++ ) {\n                    tmp_32 = silk_SMLAWW( tmp_32, v_Q0[ k ], ptr2[ k ] ); /* Q0 */\n                }\n                tmp_32 = silk_SUB32( ptr1[ i ], tmp_32 ); /* always < max(Correlation) */\n\n                /* tmp_32 / D_Q0[j] : Divide to Q16 */\n                matrix_ptr( L_Q16, i, j, M ) = silk_ADD32( silk_SMMUL( tmp_32, one_div_diag_Q48 ),\n                    silk_RSHIFT( silk_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) );\n\n                /* go to next column */\n                ptr2 += M;\n            }\n        }\n    }\n\n    silk_assert( status == 0 );\n}\n\nstatic OPUS_INLINE void silk_LS_divide_Q16_FIX(\n    opus_int32          T[],        /* I/O  Numenator vector                                            */\n    inv_D_t             *inv_D,     /* I    1 / D vector                                                */\n    opus_int            M           /* I    dimension                                                   */\n)\n{\n    opus_int   i;\n    opus_int32 tmp_32;\n    opus_int32 one_div_diag_Q36, one_div_diag_Q48;\n\n    for( i = 0; i < M; i++ ) {\n        one_div_diag_Q36 = inv_D[ i ].Q36_part;\n        one_div_diag_Q48 = inv_D[ i ].Q48_part;\n\n        tmp_32 = T[ i ];\n        T[ i ] = silk_ADD32( silk_SMMUL( tmp_32, one_div_diag_Q48 ), silk_RSHIFT( silk_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) );\n    }\n}\n\n/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */\nstatic OPUS_INLINE void silk_LS_SolveFirst_FIX(\n    const opus_int32    *L_Q16,     /* I    Pointer to Lower Triangular Matrix                          */\n    opus_int            M,          /* I    Dim of Matrix equation                                      */\n    const opus_int32    *b,         /* I    b Vector                                                    */\n    opus_int32          *x_Q16      /* O    x Vector                                                    */\n)\n{\n    opus_int i, j;\n    const opus_int32 *ptr32;\n    opus_int32 tmp_32;\n\n    for( i = 0; i < M; i++ ) {\n        ptr32 = matrix_adr( L_Q16, i, 0, M );\n        tmp_32 = 0;\n        for( j = 0; j < i; j++ ) {\n            tmp_32 = silk_SMLAWW( tmp_32, ptr32[ j ], x_Q16[ j ] );\n        }\n        x_Q16[ i ] = silk_SUB32( b[ i ], tmp_32 );\n    }\n}\n\n/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */\nstatic OPUS_INLINE void silk_LS_SolveLast_FIX(\n    const opus_int32    *L_Q16,     /* I    Pointer to Lower Triangular Matrix                          */\n    const opus_int      M,          /* I    Dim of Matrix equation                                      */\n    const opus_int32    *b,         /* I    b Vector                                                    */\n    opus_int32          *x_Q16      /* O    x Vector                                                    */\n)\n{\n    opus_int i, j;\n    const opus_int32 *ptr32;\n    opus_int32 tmp_32;\n\n    for( i = M - 1; i >= 0; i-- ) {\n        ptr32 = matrix_adr( L_Q16, 0, i, M );\n        tmp_32 = 0;\n        for( j = M - 1; j > i; j-- ) {\n            tmp_32 = silk_SMLAWW( tmp_32, ptr32[ silk_SMULBB( j, M ) ], x_Q16[ j ] );\n        }\n        x_Q16[ i ] = silk_SUB32( b[ i ], tmp_32 );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/structs_FIX.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_STRUCTS_FIX_H\n#define SILK_STRUCTS_FIX_H\n\n#include \"typedef.h\"\n#include \"main.h\"\n#include \"structs.h\"\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/********************************/\n/* Noise shaping analysis state */\n/********************************/\ntypedef struct {\n    opus_int8                   LastGainIndex;\n    opus_int32                  HarmBoost_smth_Q16;\n    opus_int32                  HarmShapeGain_smth_Q16;\n    opus_int32                  Tilt_smth_Q16;\n} silk_shape_state_FIX;\n\n/********************************/\n/* Prefilter state              */\n/********************************/\ntypedef struct {\n    opus_int16                  sLTP_shp[ LTP_BUF_LENGTH ];\n    opus_int32                  sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ];\n    opus_int                    sLTP_shp_buf_idx;\n    opus_int32                  sLF_AR_shp_Q12;\n    opus_int32                  sLF_MA_shp_Q12;\n    opus_int32                  sHarmHP_Q2;\n    opus_int32                  rand_seed;\n    opus_int                    lagPrev;\n} silk_prefilter_state_FIX;\n\n/********************************/\n/* Encoder state FIX            */\n/********************************/\ntypedef struct {\n    silk_encoder_state          sCmn;                                   /* Common struct, shared with floating-point code       */\n    silk_shape_state_FIX        sShape;                                 /* Shape state                                          */\n    silk_prefilter_state_FIX    sPrefilt;                               /* Prefilter State                                      */\n\n    /* Buffer for find pitch and noise shape analysis */\n    silk_DWORD_ALIGN opus_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis  */\n    opus_int                    LTPCorr_Q15;                            /* Normalized correlation from pitch lag estimator      */\n} silk_encoder_state_FIX;\n\n/************************/\n/* Encoder control FIX  */\n/************************/\ntypedef struct {\n    /* Prediction and coding parameters */\n    opus_int32                  Gains_Q16[ MAX_NB_SUBFR ];\n    silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];\n    opus_int16                  LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];\n    opus_int                    LTP_scale_Q14;\n    opus_int                    pitchL[ MAX_NB_SUBFR ];\n\n    /* Noise shaping parameters */\n    /* Testing */\n    silk_DWORD_ALIGN opus_int16 AR1_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];\n    silk_DWORD_ALIGN opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];\n    opus_int32                  LF_shp_Q14[        MAX_NB_SUBFR ];      /* Packs two int16 coefficients per int32 value         */\n    opus_int                    GainsPre_Q14[      MAX_NB_SUBFR ];\n    opus_int                    HarmBoost_Q14[     MAX_NB_SUBFR ];\n    opus_int                    Tilt_Q14[          MAX_NB_SUBFR ];\n    opus_int                    HarmShapeGain_Q14[ MAX_NB_SUBFR ];\n    opus_int                    Lambda_Q10;\n    opus_int                    input_quality_Q14;\n    opus_int                    coding_quality_Q14;\n\n    /* measures */\n    opus_int                    sparseness_Q8;\n    opus_int32                  predGain_Q16;\n    opus_int                    LTPredCodGain_Q7;\n    opus_int32                  ResNrg[ MAX_NB_SUBFR ];                 /* Residual energy per subframe                         */\n    opus_int                    ResNrgQ[ MAX_NB_SUBFR ];                /* Q domain for the residual energy > 0                 */\n\n    /* Parameters for CBR mode */\n    opus_int32                  GainsUnq_Q16[ MAX_NB_SUBFR ];\n    opus_int8                   lastGainIndexPrev;\n} silk_encoder_control_FIX;\n\n/************************/\n/* Encoder Super Struct */\n/************************/\ntypedef struct {\n    silk_encoder_state_FIX      state_Fxx[ ENCODER_NUM_CHANNELS ];\n    stereo_enc_state            sStereo;\n    opus_int32                  nBitsUsedLBRR;\n    opus_int32                  nBitsExceeded;\n    opus_int                    nChannelsAPI;\n    opus_int                    nChannelsInternal;\n    opus_int                    nPrevChannelsInternal;\n    opus_int                    timeSinceSwitchAllowed_ms;\n    opus_int                    allowBandwidthSwitch;\n    opus_int                    prev_decode_only_middle;\n} silk_encoder;\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/vector_ops_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n#include \"pitch.h\"\n\n/* Copy and multiply a vector by a constant */\nvoid silk_scale_copy_vector16(\n    opus_int16                  *data_out,\n    const opus_int16            *data_in,\n    opus_int32                  gain_Q16,           /* I    Gain in Q16                                                 */\n    const opus_int              dataSize            /* I    Length                                                      */\n)\n{\n    opus_int  i;\n    opus_int32 tmp32;\n\n    for( i = 0; i < dataSize; i++ ) {\n        tmp32 = silk_SMULWB( gain_Q16, data_in[ i ] );\n        data_out[ i ] = (opus_int16)silk_CHECK_FIT16( tmp32 );\n    }\n}\n\n/* Multiply a vector by a constant */\nvoid silk_scale_vector32_Q26_lshift_18(\n    opus_int32                  *data1,             /* I/O  Q0/Q18                                                      */\n    opus_int32                  gain_Q26,           /* I    Q26                                                         */\n    opus_int                    dataSize            /* I    length                                                      */\n)\n{\n    opus_int  i;\n\n    for( i = 0; i < dataSize; i++ ) {\n        data1[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_SMULL( data1[ i ], gain_Q26 ), 8 ) );    /* OUTPUT: Q18 */\n    }\n}\n\n/* sum = for(i=0;i<len;i++)inVec1[i]*inVec2[i];      ---        inner product   */\n/* Note for ARM asm:                                                            */\n/*        * inVec1 and inVec2 should be at least 2 byte aligned.                */\n/*        * len should be positive 16bit integer.                               */\n/*        * only when len>6, memory access can be reduced by half.              */\nopus_int32 silk_inner_prod_aligned(\n    const opus_int16 *const     inVec1,             /*    I input vector 1                                              */\n    const opus_int16 *const     inVec2,             /*    I input vector 2                                              */\n    const opus_int              len,                /*    I vector lengths                                              */\n    int                         arch                /*    I Run-time architecture                                       */\n)\n{\n#ifdef FIXED_POINT\n   return celt_inner_prod(inVec1, inVec2, len, arch);\n#else\n    opus_int   i;\n    opus_int32 sum = 0;\n    for( i = 0; i < len; i++ ) {\n        sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] );\n    }\n    return sum;\n#endif\n}\n\nopus_int64 silk_inner_prod16_aligned_64_c(\n    const opus_int16            *inVec1,            /*    I input vector 1                                              */\n    const opus_int16            *inVec2,            /*    I input vector 2                                              */\n    const opus_int              len                 /*    I vector lengths                                              */\n)\n{\n    opus_int   i;\n    opus_int64 sum = 0;\n    for( i = 0; i < len; i++ ) {\n        sum = silk_SMLALBB( sum, inVec1[ i ], inVec2[ i ] );\n    }\n    return sum;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/warped_autocorrelation_FIX.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FIX.h\"\n\n#define QC  10\n#define QS  14\n\n#if defined(MIPSr1_ASM)\n#include \"mips/warped_autocorrelation_FIX_mipsr1.h\"\n#endif\n\n\n#ifndef OVERRIDE_silk_warped_autocorrelation_FIX\n/* Autocorrelations for a warped frequency axis */\nvoid silk_warped_autocorrelation_FIX(\n          opus_int32                *corr,                                  /* O    Result [order + 1]                                                          */\n          opus_int                  *scale,                                 /* O    Scaling of the correlation vector                                           */\n    const opus_int16                *input,                                 /* I    Input data to correlate                                                     */\n    const opus_int                  warping_Q16,                            /* I    Warping coefficient                                                         */\n    const opus_int                  length,                                 /* I    Length of input                                                             */\n    const opus_int                  order                                   /* I    Correlation order (even)                                                    */\n)\n{\n    opus_int   n, i, lsh;\n    opus_int32 tmp1_QS, tmp2_QS;\n    opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };\n    opus_int64 corr_QC[  MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };\n\n    /* Order must be even */\n    silk_assert( ( order & 1 ) == 0 );\n    silk_assert( 2 * QS - QC >= 0 );\n\n    /* Loop over samples */\n    for( n = 0; n < length; n++ ) {\n        tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );\n        /* Loop over allpass sections */\n        for( i = 0; i < order; i += 2 ) {\n            /* Output of allpass section */\n            tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );\n            state_QS[ i ]  = tmp1_QS;\n            corr_QC[  i ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );\n            /* Output of allpass section */\n            tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );\n            state_QS[ i + 1 ]  = tmp2_QS;\n            corr_QC[  i + 1 ] += silk_RSHIFT64( silk_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC );\n        }\n        state_QS[ order ] = tmp1_QS;\n        corr_QC[  order ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );\n    }\n\n    lsh = silk_CLZ64( corr_QC[ 0 ] ) - 35;\n    lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );\n    *scale = -( QC + lsh );\n    silk_assert( *scale >= -30 && *scale <= 12 );\n    if( lsh >= 0 ) {\n        for( i = 0; i < order + 1; i++ ) {\n            corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QC[ i ], lsh ) );\n        }\n    } else {\n        for( i = 0; i < order + 1; i++ ) {\n            corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QC[ i ], -lsh ) );\n        }\n    }\n    silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/\n}\n#endif /* OVERRIDE_silk_warped_autocorrelation_FIX */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/x86/burg_modified_FIX_sse.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <xmmintrin.h>\n#include <emmintrin.h>\n#include <smmintrin.h>\n\n#include \"SigProc_FIX.h\"\n#include \"define.h\"\n#include \"tuning_parameters.h\"\n#include \"pitch.h\"\n#include \"celt/x86/x86cpu.h\"\n\n#define MAX_FRAME_SIZE              384             /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */\n\n#define QA                          25\n#define N_BITS_HEAD_ROOM            2\n#define MIN_RSHIFTS                 -16\n#define MAX_RSHIFTS                 (32 - QA)\n\n/* Compute reflection coefficients from input signal */\nvoid silk_burg_modified_sse4_1(\n    opus_int32                  *res_nrg,           /* O    Residual energy                                             */\n    opus_int                    *res_nrg_Q,         /* O    Residual energy Q value                                     */\n    opus_int32                  A_Q16[],            /* O    Prediction coefficients (length order)                      */\n    const opus_int16            x[],                /* I    Input signal, length: nb_subfr * ( D + subfr_length )       */\n    const opus_int32            minInvGain_Q30,     /* I    Inverse of max prediction gain                              */\n    const opus_int              subfr_length,       /* I    Input signal subframe length (incl. D preceding samples)    */\n    const opus_int              nb_subfr,           /* I    Number of subframes stacked in x                            */\n    const opus_int              D,                  /* I    Order                                                       */\n    int                         arch                /* I    Run-time architecture                                       */\n)\n{\n    opus_int         k, n, s, lz, rshifts, rshifts_extra, reached_max_gain;\n    opus_int32       C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;\n    const opus_int16 *x_ptr;\n    opus_int32       C_first_row[ SILK_MAX_ORDER_LPC ];\n    opus_int32       C_last_row[  SILK_MAX_ORDER_LPC ];\n    opus_int32       Af_QA[       SILK_MAX_ORDER_LPC ];\n    opus_int32       CAf[ SILK_MAX_ORDER_LPC + 1 ];\n    opus_int32       CAb[ SILK_MAX_ORDER_LPC + 1 ];\n    opus_int32       xcorr[ SILK_MAX_ORDER_LPC ];\n\n    __m128i FIRST_3210, LAST_3210, ATMP_3210, TMP1_3210, TMP2_3210, T1_3210, T2_3210, PTR_3210, SUBFR_3210, X1_3210, X2_3210;\n    __m128i CONST1 = _mm_set1_epi32(1);\n\n    silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );\n\n    /* Compute autocorrelations, added over subframes */\n    silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length );\n    if( rshifts > MAX_RSHIFTS ) {\n        C0 = silk_LSHIFT32( C0, rshifts - MAX_RSHIFTS );\n        silk_assert( C0 > 0 );\n        rshifts = MAX_RSHIFTS;\n    } else {\n        lz = silk_CLZ32( C0 ) - 1;\n        rshifts_extra = N_BITS_HEAD_ROOM - lz;\n        if( rshifts_extra > 0 ) {\n            rshifts_extra = silk_min( rshifts_extra, MAX_RSHIFTS - rshifts );\n            C0 = silk_RSHIFT32( C0, rshifts_extra );\n        } else {\n            rshifts_extra = silk_max( rshifts_extra, MIN_RSHIFTS - rshifts );\n            C0 = silk_LSHIFT32( C0, -rshifts_extra );\n        }\n        rshifts += rshifts_extra;\n    }\n    CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1;                                /* Q(-rshifts) */\n    silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );\n    if( rshifts > 0 ) {\n        for( s = 0; s < nb_subfr; s++ ) {\n            x_ptr = x + s * subfr_length;\n            for( n = 1; n < D + 1; n++ ) {\n                C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64(\n                    silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts );\n            }\n        }\n    } else {\n        for( s = 0; s < nb_subfr; s++ ) {\n            int i;\n            opus_int32 d;\n            x_ptr = x + s * subfr_length;\n            celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch );\n            for( n = 1; n < D + 1; n++ ) {\n               for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ )\n                  d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] );\n               xcorr[ n - 1 ] += d;\n            }\n            for( n = 1; n < D + 1; n++ ) {\n                C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts );\n            }\n        }\n    }\n    silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );\n\n    /* Initialize */\n    CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1;                                /* Q(-rshifts) */\n\n    invGain_Q30 = (opus_int32)1 << 30;\n    reached_max_gain = 0;\n    for( n = 0; n < D; n++ ) {\n        /* Update first row of correlation matrix (without first element) */\n        /* Update last row of correlation matrix (without last element, stored in reversed order) */\n        /* Update C * Af */\n        /* Update C * flipud(Af) (stored in reversed order) */\n        if( rshifts > -2 ) {\n            for( s = 0; s < nb_subfr; s++ ) {\n                x_ptr = x + s * subfr_length;\n                x1  = -silk_LSHIFT32( (opus_int32)x_ptr[ n ],                    16 - rshifts );        /* Q(16-rshifts) */\n                x2  = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts );        /* Q(16-rshifts) */\n                tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ],                    QA - 16 );             /* Q(QA-16) */\n                tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 );             /* Q(QA-16) */\n                for( k = 0; k < n; k++ ) {\n                    C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ]            ); /* Q( -rshifts ) */\n                    C_last_row[ k ]  = silk_SMLAWB( C_last_row[ k ],  x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */\n                    Atmp_QA = Af_QA[ k ];\n                    tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ]            );                 /* Q(QA-16) */\n                    tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] );                 /* Q(QA-16) */\n                }\n                tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts );                                       /* Q(16-rshifts) */\n                tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts );                                       /* Q(16-rshifts) */\n                for( k = 0; k <= n; k++ ) {\n                    CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ]                    );        /* Q( -rshift ) */\n                    CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] );        /* Q( -rshift ) */\n                }\n            }\n        } else {\n            for( s = 0; s < nb_subfr; s++ ) {\n                x_ptr = x + s * subfr_length;\n                x1  = -silk_LSHIFT32( (opus_int32)x_ptr[ n ],                    -rshifts );            /* Q( -rshifts ) */\n                x2  = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts );            /* Q( -rshifts ) */\n                tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ],                    17 );                  /* Q17 */\n                tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 );                  /* Q17 */\n\n                X1_3210 = _mm_set1_epi32( x1 );\n                X2_3210 = _mm_set1_epi32( x2 );\n                TMP1_3210 = _mm_setzero_si128();\n                TMP2_3210 = _mm_setzero_si128();\n                for( k = 0; k < n - 3; k += 4 ) {\n                    PTR_3210   = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 1 - 3 ] );\n                    SUBFR_3210 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k ] );\n                    FIRST_3210 = _mm_loadu_si128( (__m128i *)&C_first_row[ k ] );\n                    PTR_3210   = _mm_shuffle_epi32( PTR_3210,  _MM_SHUFFLE( 0, 1, 2, 3 ) );\n                    LAST_3210  = _mm_loadu_si128( (__m128i *)&C_last_row[ k ] );\n                    ATMP_3210  = _mm_loadu_si128( (__m128i *)&Af_QA[ k ] );\n\n                    T1_3210 = _mm_mullo_epi32( PTR_3210, X1_3210 );\n                    T2_3210 = _mm_mullo_epi32( SUBFR_3210, X2_3210 );\n\n                    ATMP_3210 = _mm_srai_epi32( ATMP_3210, 7 );\n                    ATMP_3210 = _mm_add_epi32( ATMP_3210, CONST1 );\n                    ATMP_3210 = _mm_srai_epi32( ATMP_3210, 1 );\n\n                    FIRST_3210 = _mm_add_epi32( FIRST_3210, T1_3210 );\n                    LAST_3210 = _mm_add_epi32( LAST_3210, T2_3210 );\n\n                    PTR_3210   = _mm_mullo_epi32( ATMP_3210, PTR_3210 );\n                    SUBFR_3210   = _mm_mullo_epi32( ATMP_3210, SUBFR_3210 );\n\n                    _mm_storeu_si128( (__m128i *)&C_first_row[ k ], FIRST_3210 );\n                    _mm_storeu_si128( (__m128i *)&C_last_row[ k ], LAST_3210 );\n\n                    TMP1_3210 = _mm_add_epi32( TMP1_3210, PTR_3210 );\n                    TMP2_3210 = _mm_add_epi32( TMP2_3210, SUBFR_3210 );\n                }\n\n                TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_unpackhi_epi64(TMP1_3210, TMP1_3210 ) );\n                TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_unpackhi_epi64(TMP2_3210, TMP2_3210 ) );\n                TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_shufflelo_epi16(TMP1_3210, 0x0E ) );\n                TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_shufflelo_epi16(TMP2_3210, 0x0E ) );\n\n                tmp1 += _mm_cvtsi128_si32( TMP1_3210 );\n                tmp2 += _mm_cvtsi128_si32( TMP2_3210 );\n\n                for( ; k < n; k++ ) {\n                    C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ]            ); /* Q( -rshifts ) */\n                    C_last_row[ k ]  = silk_MLA( C_last_row[ k ],  x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */\n                    Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 );                                   /* Q17 */\n                    tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ],            Atmp1 );                      /* Q17 */\n                    tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 );                      /* Q17 */\n                }\n\n                tmp1 = -tmp1;                /* Q17 */\n                tmp2 = -tmp2;                /* Q17 */\n\n                {\n                    __m128i xmm_tmp1, xmm_tmp2;\n                    __m128i xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1;\n                    __m128i xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1;\n\n                    xmm_tmp1 = _mm_set1_epi32( tmp1 );\n                    xmm_tmp2 = _mm_set1_epi32( tmp2 );\n\n                    for( k = 0; k <= n - 3; k += 4 ) {\n                        xmm_x_ptr_n_k_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 3 ] );\n                        xmm_x_ptr_sub_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k - 1 ] );\n\n                        xmm_x_ptr_n_k_x2x0 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 1, 2, 3 ) );\n\n                        xmm_x_ptr_n_k_x2x0 = _mm_slli_epi32( xmm_x_ptr_n_k_x2x0, -rshifts - 1 );\n                        xmm_x_ptr_sub_x2x0 = _mm_slli_epi32( xmm_x_ptr_sub_x2x0, -rshifts - 1 );\n\n                        /* equal shift right 4 bytes, xmm_x_ptr_n_k_x3x1 = _mm_srli_si128(xmm_x_ptr_n_k_x2x0, 4)*/\n                        xmm_x_ptr_n_k_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );\n                        xmm_x_ptr_sub_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_sub_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );\n\n                        xmm_x_ptr_n_k_x2x0 = _mm_mul_epi32( xmm_x_ptr_n_k_x2x0, xmm_tmp1 );\n                        xmm_x_ptr_n_k_x3x1 = _mm_mul_epi32( xmm_x_ptr_n_k_x3x1, xmm_tmp1 );\n                        xmm_x_ptr_sub_x2x0 = _mm_mul_epi32( xmm_x_ptr_sub_x2x0, xmm_tmp2 );\n                        xmm_x_ptr_sub_x3x1 = _mm_mul_epi32( xmm_x_ptr_sub_x3x1, xmm_tmp2 );\n\n                        xmm_x_ptr_n_k_x2x0 = _mm_srli_epi64( xmm_x_ptr_n_k_x2x0, 16 );\n                        xmm_x_ptr_n_k_x3x1 = _mm_slli_epi64( xmm_x_ptr_n_k_x3x1, 16 );\n                        xmm_x_ptr_sub_x2x0 = _mm_srli_epi64( xmm_x_ptr_sub_x2x0, 16 );\n                        xmm_x_ptr_sub_x3x1 = _mm_slli_epi64( xmm_x_ptr_sub_x3x1, 16 );\n\n                        xmm_x_ptr_n_k_x2x0 = _mm_blend_epi16( xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1, 0xCC );\n                        xmm_x_ptr_sub_x2x0 = _mm_blend_epi16( xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1, 0xCC );\n\n                        X1_3210  = _mm_loadu_si128( (__m128i *)&CAf[ k ] );\n                        PTR_3210 = _mm_loadu_si128( (__m128i *)&CAb[ k ] );\n\n                        X1_3210  = _mm_add_epi32( X1_3210, xmm_x_ptr_n_k_x2x0 );\n                        PTR_3210 = _mm_add_epi32( PTR_3210, xmm_x_ptr_sub_x2x0 );\n\n                        _mm_storeu_si128( (__m128i *)&CAf[ k ], X1_3210 );\n                        _mm_storeu_si128( (__m128i *)&CAb[ k ], PTR_3210 );\n                    }\n\n                    for( ; k <= n; k++ ) {\n                        CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1,\n                            silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) );                    /* Q( -rshift ) */\n                        CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2,\n                            silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */\n                    }\n                }\n            }\n        }\n\n        /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */\n        tmp1 = C_first_row[ n ];                                                                        /* Q( -rshifts ) */\n        tmp2 = C_last_row[ n ];                                                                         /* Q( -rshifts ) */\n        num  = 0;                                                                                       /* Q( -rshifts ) */\n        nrg  = silk_ADD32( CAb[ 0 ], CAf[ 0 ] );                                                        /* Q( 1-rshifts ) */\n        for( k = 0; k < n; k++ ) {\n            Atmp_QA = Af_QA[ k ];\n            lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1;\n            lz = silk_min( 32 - QA, lz );\n            Atmp1 = silk_LSHIFT32( Atmp_QA, lz );                                                       /* Q( QA + lz ) */\n\n            tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[  n - k - 1 ], Atmp1 ), 32 - QA - lz );  /* Q( -rshifts ) */\n            tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz );  /* Q( -rshifts ) */\n            num  = silk_ADD_LSHIFT32( num,  silk_SMMUL( CAb[ n - k ],             Atmp1 ), 32 - QA - lz );  /* Q( -rshifts ) */\n            nrg  = silk_ADD_LSHIFT32( nrg,  silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),\n                                                                                Atmp1 ), 32 - QA - lz );    /* Q( 1-rshifts ) */\n        }\n        CAf[ n + 1 ] = tmp1;                                                                            /* Q( -rshifts ) */\n        CAb[ n + 1 ] = tmp2;                                                                            /* Q( -rshifts ) */\n        num = silk_ADD32( num, tmp2 );                                                                  /* Q( -rshifts ) */\n        num = silk_LSHIFT32( -num, 1 );                                                                 /* Q( 1-rshifts ) */\n\n        /* Calculate the next order reflection (parcor) coefficient */\n        if( silk_abs( num ) < nrg ) {\n            rc_Q31 = silk_DIV32_varQ( num, nrg, 31 );\n        } else {\n            rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN;\n        }\n\n        /* Update inverse prediction gain */\n        tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );\n        tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 );\n        if( tmp1 <= minInvGain_Q30 ) {\n            /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */\n            tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 );            /* Q30 */\n            rc_Q31 = silk_SQRT_APPROX( tmp2 );                                                  /* Q15 */\n            /* Newton-Raphson iteration */\n            rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 );                   /* Q15 */\n            rc_Q31 = silk_LSHIFT32( rc_Q31, 16 );                                               /* Q31 */\n            if( num < 0 ) {\n                /* Ensure adjusted reflection coefficients has the original sign */\n                rc_Q31 = -rc_Q31;\n            }\n            invGain_Q30 = minInvGain_Q30;\n            reached_max_gain = 1;\n        } else {\n            invGain_Q30 = tmp1;\n        }\n\n        /* Update the AR coefficients */\n        for( k = 0; k < (n + 1) >> 1; k++ ) {\n            tmp1 = Af_QA[ k ];                                                                  /* QA */\n            tmp2 = Af_QA[ n - k - 1 ];                                                          /* QA */\n            Af_QA[ k ]         = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 );      /* QA */\n            Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 );      /* QA */\n        }\n        Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA );                                          /* QA */\n\n        if( reached_max_gain ) {\n            /* Reached max prediction gain; set remaining coefficients to zero and exit loop */\n            for( k = n + 1; k < D; k++ ) {\n                Af_QA[ k ] = 0;\n            }\n            break;\n        }\n\n        /* Update C * Af and C * Ab */\n        for( k = 0; k <= n + 1; k++ ) {\n            tmp1 = CAf[ k ];                                                                    /* Q( -rshifts ) */\n            tmp2 = CAb[ n - k + 1 ];                                                            /* Q( -rshifts ) */\n            CAf[ k ]         = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 );        /* Q( -rshifts ) */\n            CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 );        /* Q( -rshifts ) */\n        }\n    }\n\n    if( reached_max_gain ) {\n        for( k = 0; k < D; k++ ) {\n            /* Scale coefficients */\n            A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );\n        }\n        /* Subtract energy of preceding samples from C0 */\n        if( rshifts > 0 ) {\n            for( s = 0; s < nb_subfr; s++ ) {\n                x_ptr = x + s * subfr_length;\n                C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts );\n            }\n        } else {\n            for( s = 0; s < nb_subfr; s++ ) {\n                x_ptr = x + s * subfr_length;\n                C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch ), -rshifts );\n            }\n        }\n        /* Approximate residual energy */\n        *res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 );\n        *res_nrg_Q = -rshifts;\n    } else {\n        /* Return residual energy */\n        nrg  = CAf[ 0 ];                                                                            /* Q( -rshifts ) */\n        tmp1 = (opus_int32)1 << 16;                                                                             /* Q16 */\n        for( k = 0; k < D; k++ ) {\n            Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );                                       /* Q16 */\n            nrg  = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 );                                         /* Q( -rshifts ) */\n            tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 );                                               /* Q16 */\n            A_Q16[ k ] = -Atmp1;\n        }\n        *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */\n        *res_nrg_Q = -rshifts;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/x86/prefilter_FIX_sse.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <xmmintrin.h>\n#include <emmintrin.h>\n#include <smmintrin.h>\n#include \"main.h\"\n#include \"celt/x86/x86cpu.h\"\n\nvoid silk_warped_LPC_analysis_filter_FIX_sse4_1(\n    opus_int32                  state[],                    /* I/O  State [order + 1]                   */\n    opus_int32                  res_Q2[],                   /* O    Residual signal [length]            */\n    const opus_int16            coef_Q13[],                 /* I    Coefficients [order]                */\n    const opus_int16            input[],                    /* I    Input signal [length]               */\n    const opus_int16            lambda_Q16,                 /* I    Warping factor                      */\n    const opus_int              length,                     /* I    Length of input signal              */\n    const opus_int              order                       /* I    Filter order (even)                 */\n)\n{\n    opus_int     n, i;\n    opus_int32   acc_Q11, tmp1, tmp2;\n\n    /* Order must be even */\n    silk_assert( ( order & 1 ) == 0 );\n\n    if (order == 10)\n    {\n        if (0 == lambda_Q16)\n        {\n            __m128i coef_Q13_3210, coef_Q13_7654;\n            __m128i coef_Q13_0123, coef_Q13_4567;\n            __m128i state_0123, state_4567;\n            __m128i xmm_product1, xmm_product2;\n            __m128i xmm_tempa, xmm_tempb;\n\n            register opus_int32 sum;\n            register opus_int32 state_8, state_9, state_a;\n            register opus_int64 coef_Q13_8, coef_Q13_9;\n\n            silk_assert( length > 0 );\n\n            coef_Q13_3210 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 0 ] );\n            coef_Q13_7654 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 4 ] );\n\n            coef_Q13_0123 = _mm_shuffle_epi32( coef_Q13_3210, _MM_SHUFFLE( 0, 1, 2, 3 ) );\n            coef_Q13_4567 = _mm_shuffle_epi32( coef_Q13_7654, _MM_SHUFFLE( 0, 1, 2, 3 ) );\n\n            coef_Q13_8 = (opus_int64) coef_Q13[ 8 ];\n            coef_Q13_9 = (opus_int64) coef_Q13[ 9 ];\n\n            state_0123 = _mm_loadu_si128( (__m128i *)(&state[ 0 ] ) );\n            state_4567 = _mm_loadu_si128( (__m128i *)(&state[ 4 ] ) );\n\n            state_0123 = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) );\n            state_4567 = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) );\n\n            state_8 = state[ 8 ];\n            state_9 = state[ 9 ];\n            state_a = 0;\n\n            for( n = 0; n < length; n++ )\n            {\n                xmm_product1 = _mm_mul_epi32( coef_Q13_0123, state_0123 ); /* 64-bit multiply, only 2 pairs */\n                xmm_product2 = _mm_mul_epi32( coef_Q13_4567, state_4567 );\n\n                xmm_tempa = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) );\n                xmm_tempb = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) );\n\n                xmm_product1 = _mm_srli_epi64( xmm_product1, 16 ); /* >> 16, zero extending works */\n                xmm_product2 = _mm_srli_epi64( xmm_product2, 16 );\n\n                xmm_tempa = _mm_mul_epi32( coef_Q13_3210, xmm_tempa );\n                xmm_tempb = _mm_mul_epi32( coef_Q13_7654, xmm_tempb );\n\n                xmm_tempa = _mm_srli_epi64( xmm_tempa, 16 );\n                xmm_tempb = _mm_srli_epi64( xmm_tempb, 16 );\n\n                xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_product1 );\n                xmm_tempb = _mm_add_epi32( xmm_tempb, xmm_product2 );\n                xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_tempb );\n\n                sum  = (coef_Q13_8 * state_8) >> 16;\n                sum += (coef_Q13_9 * state_9) >> 16;\n\n                xmm_tempa = _mm_add_epi32( xmm_tempa, _mm_shuffle_epi32( xmm_tempa, _MM_SHUFFLE( 0, 0, 0, 2 ) ) );\n                sum += _mm_cvtsi128_si32( xmm_tempa);\n                res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( ( 5 + sum ), 9);\n\n                /* move right */\n                state_a = state_9;\n                state_9 = state_8;\n                state_8 = _mm_cvtsi128_si32( state_4567 );\n                state_4567 = _mm_alignr_epi8( state_0123, state_4567, 4 );\n\n                state_0123 = _mm_alignr_epi8( _mm_cvtsi32_si128( silk_LSHIFT( input[ n ], 14 ) ), state_0123, 4 );\n            }\n\n            _mm_storeu_si128( (__m128i *)( &state[ 0 ] ), _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) ) );\n            _mm_storeu_si128( (__m128i *)( &state[ 4 ] ), _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) ) );\n            state[ 8 ] = state_8;\n            state[ 9 ] = state_9;\n            state[ 10 ] = state_a;\n\n            return;\n        }\n    }\n\n    for( n = 0; n < length; n++ ) {\n        /* Output of lowpass section */\n        tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );\n        state[ 0 ] = silk_LSHIFT( input[ n ], 14 );\n        /* Output of allpass section */\n        tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );\n        state[ 1 ] = tmp2;\n        acc_Q11 = silk_RSHIFT( order, 1 );\n        acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );\n        /* Loop over allpass sections */\n        for( i = 2; i < order; i += 2 ) {\n            /* Output of allpass section */\n            tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );\n            state[ i ] = tmp1;\n            acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );\n            /* Output of allpass section */\n            tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );\n            state[ i + 1 ] = tmp2;\n            acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );\n        }\n        state[ order ] = tmp1;\n        acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );\n        res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/fixed/x86/vector_ops_FIX_sse.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <xmmintrin.h>\n#include <emmintrin.h>\n#include <smmintrin.h>\n#include \"main.h\"\n\n#include \"SigProc_FIX.h\"\n#include \"pitch.h\"\n\nopus_int64 silk_inner_prod16_aligned_64_sse4_1(\n    const opus_int16            *inVec1,            /*    I input vector 1                                              */\n    const opus_int16            *inVec2,            /*    I input vector 2                                              */\n    const opus_int              len                 /*    I vector lengths                                              */\n)\n{\n    opus_int  i, dataSize8;\n    opus_int64 sum;\n\n    __m128i xmm_tempa;\n    __m128i inVec1_76543210, acc1;\n    __m128i inVec2_76543210, acc2;\n\n    sum = 0;\n    dataSize8 = len & ~7;\n\n    acc1 = _mm_setzero_si128();\n    acc2 = _mm_setzero_si128();\n\n    for( i = 0; i < dataSize8; i += 8 ) {\n        inVec1_76543210 = _mm_loadu_si128( (__m128i *)(&inVec1[i + 0] ) );\n        inVec2_76543210 = _mm_loadu_si128( (__m128i *)(&inVec2[i + 0] ) );\n\n        /* only when all 4 operands are -32768 (0x8000), this results in wrap around */\n        inVec1_76543210 = _mm_madd_epi16( inVec1_76543210, inVec2_76543210 );\n\n        xmm_tempa       = _mm_cvtepi32_epi64( inVec1_76543210 );\n        /* equal shift right 8 bytes */\n        inVec1_76543210 = _mm_shuffle_epi32( inVec1_76543210, _MM_SHUFFLE( 0, 0, 3, 2 ) );\n        inVec1_76543210 = _mm_cvtepi32_epi64( inVec1_76543210 );\n\n        acc1 = _mm_add_epi64( acc1, xmm_tempa );\n        acc2 = _mm_add_epi64( acc2, inVec1_76543210 );\n    }\n\n    acc1 = _mm_add_epi64( acc1, acc2 );\n\n    /* equal shift right 8 bytes */\n    acc2 = _mm_shuffle_epi32( acc1, _MM_SHUFFLE( 0, 0, 3, 2 ) );\n    acc1 = _mm_add_epi64( acc1, acc2 );\n\n    _mm_storel_epi64( (__m128i *)&sum, acc1 );\n\n    for( ; i < len; i++ ) {\n        sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] );\n    }\n\n    return sum;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/LPC_analysis_filter_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdlib.h>\n#include \"main_FLP.h\"\n\n/************************************************/\n/* LPC analysis filter                          */\n/* NB! State is kept internally and the         */\n/* filter always starts with zero state         */\n/* first Order output samples are set to zero   */\n/************************************************/\n\n/* 16th order LPC analysis filter, does not write first 16 samples */\nstatic OPUS_INLINE void silk_LPC_analysis_filter16_FLP(\n          silk_float                 r_LPC[],            /* O    LPC residual signal                     */\n    const silk_float                 PredCoef[],         /* I    LPC coefficients                        */\n    const silk_float                 s[],                /* I    Input signal                            */\n    const opus_int                   length              /* I    Length of input signal                  */\n)\n{\n    opus_int   ix;\n    silk_float LPC_pred;\n    const silk_float *s_ptr;\n\n    for( ix = 16; ix < length; ix++ ) {\n        s_ptr = &s[ix - 1];\n\n        /* short-term prediction */\n        LPC_pred = s_ptr[  0 ]  * PredCoef[ 0 ]  +\n                   s_ptr[ -1 ]  * PredCoef[ 1 ]  +\n                   s_ptr[ -2 ]  * PredCoef[ 2 ]  +\n                   s_ptr[ -3 ]  * PredCoef[ 3 ]  +\n                   s_ptr[ -4 ]  * PredCoef[ 4 ]  +\n                   s_ptr[ -5 ]  * PredCoef[ 5 ]  +\n                   s_ptr[ -6 ]  * PredCoef[ 6 ]  +\n                   s_ptr[ -7 ]  * PredCoef[ 7 ]  +\n                   s_ptr[ -8 ]  * PredCoef[ 8 ]  +\n                   s_ptr[ -9 ]  * PredCoef[ 9 ]  +\n                   s_ptr[ -10 ] * PredCoef[ 10 ] +\n                   s_ptr[ -11 ] * PredCoef[ 11 ] +\n                   s_ptr[ -12 ] * PredCoef[ 12 ] +\n                   s_ptr[ -13 ] * PredCoef[ 13 ] +\n                   s_ptr[ -14 ] * PredCoef[ 14 ] +\n                   s_ptr[ -15 ] * PredCoef[ 15 ];\n\n        /* prediction error */\n        r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;\n    }\n}\n\n/* 12th order LPC analysis filter, does not write first 12 samples */\nstatic OPUS_INLINE void silk_LPC_analysis_filter12_FLP(\n          silk_float                 r_LPC[],            /* O    LPC residual signal                     */\n    const silk_float                 PredCoef[],         /* I    LPC coefficients                        */\n    const silk_float                 s[],                /* I    Input signal                            */\n    const opus_int                   length              /* I    Length of input signal                  */\n)\n{\n    opus_int   ix;\n    silk_float LPC_pred;\n    const silk_float *s_ptr;\n\n    for( ix = 12; ix < length; ix++ ) {\n        s_ptr = &s[ix - 1];\n\n        /* short-term prediction */\n        LPC_pred = s_ptr[  0 ]  * PredCoef[ 0 ]  +\n                   s_ptr[ -1 ]  * PredCoef[ 1 ]  +\n                   s_ptr[ -2 ]  * PredCoef[ 2 ]  +\n                   s_ptr[ -3 ]  * PredCoef[ 3 ]  +\n                   s_ptr[ -4 ]  * PredCoef[ 4 ]  +\n                   s_ptr[ -5 ]  * PredCoef[ 5 ]  +\n                   s_ptr[ -6 ]  * PredCoef[ 6 ]  +\n                   s_ptr[ -7 ]  * PredCoef[ 7 ]  +\n                   s_ptr[ -8 ]  * PredCoef[ 8 ]  +\n                   s_ptr[ -9 ]  * PredCoef[ 9 ]  +\n                   s_ptr[ -10 ] * PredCoef[ 10 ] +\n                   s_ptr[ -11 ] * PredCoef[ 11 ];\n\n        /* prediction error */\n        r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;\n    }\n}\n\n/* 10th order LPC analysis filter, does not write first 10 samples */\nstatic OPUS_INLINE void silk_LPC_analysis_filter10_FLP(\n          silk_float                 r_LPC[],            /* O    LPC residual signal                     */\n    const silk_float                 PredCoef[],         /* I    LPC coefficients                        */\n    const silk_float                 s[],                /* I    Input signal                            */\n    const opus_int                   length              /* I    Length of input signal                  */\n)\n{\n    opus_int   ix;\n    silk_float LPC_pred;\n    const silk_float *s_ptr;\n\n    for( ix = 10; ix < length; ix++ ) {\n        s_ptr = &s[ix - 1];\n\n        /* short-term prediction */\n        LPC_pred = s_ptr[  0 ] * PredCoef[ 0 ]  +\n                   s_ptr[ -1 ] * PredCoef[ 1 ]  +\n                   s_ptr[ -2 ] * PredCoef[ 2 ]  +\n                   s_ptr[ -3 ] * PredCoef[ 3 ]  +\n                   s_ptr[ -4 ] * PredCoef[ 4 ]  +\n                   s_ptr[ -5 ] * PredCoef[ 5 ]  +\n                   s_ptr[ -6 ] * PredCoef[ 6 ]  +\n                   s_ptr[ -7 ] * PredCoef[ 7 ]  +\n                   s_ptr[ -8 ] * PredCoef[ 8 ]  +\n                   s_ptr[ -9 ] * PredCoef[ 9 ];\n\n        /* prediction error */\n        r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;\n    }\n}\n\n/* 8th order LPC analysis filter, does not write first 8 samples */\nstatic OPUS_INLINE void silk_LPC_analysis_filter8_FLP(\n          silk_float                 r_LPC[],            /* O    LPC residual signal                     */\n    const silk_float                 PredCoef[],         /* I    LPC coefficients                        */\n    const silk_float                 s[],                /* I    Input signal                            */\n    const opus_int                   length              /* I    Length of input signal                  */\n)\n{\n    opus_int   ix;\n    silk_float LPC_pred;\n    const silk_float *s_ptr;\n\n    for( ix = 8; ix < length; ix++ ) {\n        s_ptr = &s[ix - 1];\n\n        /* short-term prediction */\n        LPC_pred = s_ptr[  0 ] * PredCoef[ 0 ]  +\n                   s_ptr[ -1 ] * PredCoef[ 1 ]  +\n                   s_ptr[ -2 ] * PredCoef[ 2 ]  +\n                   s_ptr[ -3 ] * PredCoef[ 3 ]  +\n                   s_ptr[ -4 ] * PredCoef[ 4 ]  +\n                   s_ptr[ -5 ] * PredCoef[ 5 ]  +\n                   s_ptr[ -6 ] * PredCoef[ 6 ]  +\n                   s_ptr[ -7 ] * PredCoef[ 7 ];\n\n        /* prediction error */\n        r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;\n    }\n}\n\n/* 6th order LPC analysis filter, does not write first 6 samples */\nstatic OPUS_INLINE void silk_LPC_analysis_filter6_FLP(\n          silk_float                 r_LPC[],            /* O    LPC residual signal                     */\n    const silk_float                 PredCoef[],         /* I    LPC coefficients                        */\n    const silk_float                 s[],                /* I    Input signal                            */\n    const opus_int                   length              /* I    Length of input signal                  */\n)\n{\n    opus_int   ix;\n    silk_float LPC_pred;\n    const silk_float *s_ptr;\n\n    for( ix = 6; ix < length; ix++ ) {\n        s_ptr = &s[ix - 1];\n\n        /* short-term prediction */\n        LPC_pred = s_ptr[  0 ] * PredCoef[ 0 ]  +\n                   s_ptr[ -1 ] * PredCoef[ 1 ]  +\n                   s_ptr[ -2 ] * PredCoef[ 2 ]  +\n                   s_ptr[ -3 ] * PredCoef[ 3 ]  +\n                   s_ptr[ -4 ] * PredCoef[ 4 ]  +\n                   s_ptr[ -5 ] * PredCoef[ 5 ];\n\n        /* prediction error */\n        r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;\n    }\n}\n\n/************************************************/\n/* LPC analysis filter                          */\n/* NB! State is kept internally and the         */\n/* filter always starts with zero state         */\n/* first Order output samples are set to zero   */\n/************************************************/\nvoid silk_LPC_analysis_filter_FLP(\n    silk_float                      r_LPC[],                            /* O    LPC residual signal                         */\n    const silk_float                PredCoef[],                         /* I    LPC coefficients                            */\n    const silk_float                s[],                                /* I    Input signal                                */\n    const opus_int                  length,                             /* I    Length of input signal                      */\n    const opus_int                  Order                               /* I    LPC order                                   */\n)\n{\n    silk_assert( Order <= length );\n\n    switch( Order ) {\n        case 6:\n            silk_LPC_analysis_filter6_FLP(  r_LPC, PredCoef, s, length );\n        break;\n\n        case 8:\n            silk_LPC_analysis_filter8_FLP(  r_LPC, PredCoef, s, length );\n        break;\n\n        case 10:\n            silk_LPC_analysis_filter10_FLP( r_LPC, PredCoef, s, length );\n        break;\n\n        case 12:\n            silk_LPC_analysis_filter12_FLP( r_LPC, PredCoef, s, length );\n        break;\n\n        case 16:\n            silk_LPC_analysis_filter16_FLP( r_LPC, PredCoef, s, length );\n        break;\n\n        default:\n            silk_assert( 0 );\n        break;\n    }\n\n    /* Set first Order output samples to zero */\n    silk_memset( r_LPC, 0, Order * sizeof( silk_float ) );\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/LPC_inv_pred_gain_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n#include \"SigProc_FLP.h\"\n\n#define RC_THRESHOLD        0.9999f\n\n/* compute inverse of LPC prediction gain, and                          */\n/* test if LPC coefficients are stable (all poles within unit circle)   */\n/* this code is based on silk_a2k_FLP()                                 */\nsilk_float silk_LPC_inverse_pred_gain_FLP(  /* O    return inverse prediction gain, energy domain               */\n    const silk_float    *A,                 /* I    prediction coefficients [order]                             */\n    opus_int32          order               /* I    prediction order                                            */\n)\n{\n    opus_int   k, n;\n    double     invGain, rc, rc_mult1, rc_mult2;\n    silk_float Atmp[ 2 ][ SILK_MAX_ORDER_LPC ];\n    silk_float *Aold, *Anew;\n\n    Anew = Atmp[ order & 1 ];\n    silk_memcpy( Anew, A, order * sizeof(silk_float) );\n\n    invGain = 1.0;\n    for( k = order - 1; k > 0; k-- ) {\n        rc = -Anew[ k ];\n        if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {\n            return 0.0f;\n        }\n        rc_mult1 = 1.0f - rc * rc;\n        rc_mult2 = 1.0f / rc_mult1;\n        invGain *= rc_mult1;\n        /* swap pointers */\n        Aold = Anew;\n        Anew = Atmp[ k & 1 ];\n        for( n = 0; n < k; n++ ) {\n            Anew[ n ] = (silk_float)( ( Aold[ n ] - Aold[ k - n - 1 ] * rc ) * rc_mult2 );\n        }\n    }\n    rc = -Anew[ 0 ];\n    if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {\n        return 0.0f;\n    }\n    rc_mult1 = 1.0f - rc * rc;\n    invGain *= rc_mult1;\n    return (silk_float)invGain;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/LTP_analysis_filter_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n\nvoid silk_LTP_analysis_filter_FLP(\n    silk_float                      *LTP_res,                           /* O    LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */\n    const silk_float                *x,                                 /* I    Input signal, with preceding samples        */\n    const silk_float                B[ LTP_ORDER * MAX_NB_SUBFR ],      /* I    LTP coefficients for each subframe          */\n    const opus_int                  pitchL[   MAX_NB_SUBFR ],           /* I    Pitch lags                                  */\n    const silk_float                invGains[ MAX_NB_SUBFR ],           /* I    Inverse quantization gains                  */\n    const opus_int                  subfr_length,                       /* I    Length of each subframe                     */\n    const opus_int                  nb_subfr,                           /* I    number of subframes                         */\n    const opus_int                  pre_length                          /* I    Preceding samples for each subframe         */\n)\n{\n    const silk_float *x_ptr, *x_lag_ptr;\n    silk_float   Btmp[ LTP_ORDER ];\n    silk_float   *LTP_res_ptr;\n    silk_float   inv_gain;\n    opus_int     k, i, j;\n\n    x_ptr = x;\n    LTP_res_ptr = LTP_res;\n    for( k = 0; k < nb_subfr; k++ ) {\n        x_lag_ptr = x_ptr - pitchL[ k ];\n        inv_gain = invGains[ k ];\n        for( i = 0; i < LTP_ORDER; i++ ) {\n            Btmp[ i ] = B[ k * LTP_ORDER + i ];\n        }\n\n        /* LTP analysis FIR filter */\n        for( i = 0; i < subfr_length + pre_length; i++ ) {\n            LTP_res_ptr[ i ] = x_ptr[ i ];\n            /* Subtract long-term prediction */\n            for( j = 0; j < LTP_ORDER; j++ ) {\n                LTP_res_ptr[ i ] -= Btmp[ j ] * x_lag_ptr[ LTP_ORDER / 2 - j ];\n            }\n            LTP_res_ptr[ i ] *= inv_gain;\n            x_lag_ptr++;\n        }\n\n        /* Update pointers */\n        LTP_res_ptr += subfr_length + pre_length;\n        x_ptr       += subfr_length;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/LTP_scale_ctrl_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n\nvoid silk_LTP_scale_ctrl_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    opus_int                        condCoding                          /* I    The type of conditional coding to use       */\n)\n{\n    opus_int   round_loss;\n\n    if( condCoding == CODE_INDEPENDENTLY ) {\n        /* Only scale if first frame in packet */\n        round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;\n        psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( round_loss * psEncCtrl->LTPredCodGain * 0.1f, 0.0f, 2.0f );\n    } else {\n        /* Default is minimum scaling */\n        psEnc->sCmn.indices.LTP_scaleIndex = 0;\n    }\n\n    psEncCtrl->LTP_scale = (silk_float)silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/SigProc_FLP.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_SIGPROC_FLP_H\n#define SILK_SIGPROC_FLP_H\n\n#include \"SigProc_FIX.h\"\n#include \"float_cast.h\"\n#include <math.h>\n\n#ifdef  __cplusplus\nextern \"C\"\n{\n#endif\n\n/********************************************************************/\n/*                    SIGNAL PROCESSING FUNCTIONS                   */\n/********************************************************************/\n\n/* Chirp (bw expand) LP AR filter */\nvoid silk_bwexpander_FLP(\n    silk_float          *ar,                /* I/O  AR filter to be expanded (without leading 1)                */\n    const opus_int      d,                  /* I    length of ar                                                */\n    const silk_float    chirp               /* I    chirp factor (typically in range (0..1) )                   */\n);\n\n/* compute inverse of LPC prediction gain, and                          */\n/* test if LPC coefficients are stable (all poles within unit circle)   */\n/* this code is based on silk_FLP_a2k()                                 */\nsilk_float silk_LPC_inverse_pred_gain_FLP(  /* O    return inverse prediction gain, energy domain               */\n    const silk_float    *A,                 /* I    prediction coefficients [order]                             */\n    opus_int32          order               /* I    prediction order                                            */\n);\n\nsilk_float silk_schur_FLP(                  /* O    returns residual energy                                     */\n    silk_float          refl_coef[],        /* O    reflection coefficients (length order)                      */\n    const silk_float    auto_corr[],        /* I    autocorrelation sequence (length order+1)                   */\n    opus_int            order               /* I    order                                                       */\n);\n\nvoid silk_k2a_FLP(\n    silk_float          *A,                 /* O     prediction coefficients [order]                            */\n    const silk_float    *rc,                /* I     reflection coefficients [order]                            */\n    opus_int32          order               /* I     prediction order                                           */\n);\n\n/* Solve the normal equations using the Levinson-Durbin recursion */\nsilk_float silk_levinsondurbin_FLP(         /* O    prediction error energy                                     */\n    silk_float          A[],                /* O    prediction coefficients [order]                             */\n    const silk_float    corr[],             /* I    input auto-correlations [order + 1]                         */\n    const opus_int      order               /* I    prediction order                                            */\n);\n\n/* compute autocorrelation */\nvoid silk_autocorrelation_FLP(\n    silk_float          *results,           /* O    result (length correlationCount)                            */\n    const silk_float    *inputData,         /* I    input data to correlate                                     */\n    opus_int            inputDataSize,      /* I    length of input                                             */\n    opus_int            correlationCount    /* I    number of correlation taps to compute                       */\n);\n\nopus_int silk_pitch_analysis_core_FLP(      /* O    Voicing estimate: 0 voiced, 1 unvoiced                      */\n    const silk_float    *frame,             /* I    Signal of length PE_FRAME_LENGTH_MS*Fs_kHz                  */\n    opus_int            *pitch_out,         /* O    Pitch lag values [nb_subfr]                                 */\n    opus_int16          *lagIndex,          /* O    Lag Index                                                   */\n    opus_int8           *contourIndex,      /* O    Pitch contour Index                                         */\n    silk_float          *LTPCorr,           /* I/O  Normalized correlation; input: value from previous frame    */\n    opus_int            prevLag,            /* I    Last lag of previous frame; set to zero is unvoiced         */\n    const silk_float    search_thres1,      /* I    First stage threshold for lag candidates 0 - 1              */\n    const silk_float    search_thres2,      /* I    Final threshold for lag candidates 0 - 1                    */\n    const opus_int      Fs_kHz,             /* I    sample frequency (kHz)                                      */\n    const opus_int      complexity,         /* I    Complexity setting, 0-2, where 2 is highest                 */\n    const opus_int      nb_subfr,           /* I    Number of 5 ms subframes                                    */\n    int                 arch                /* I    Run-time architecture                                       */\n);\n\nvoid silk_insertion_sort_decreasing_FLP(\n    silk_float          *a,                 /* I/O  Unsorted / Sorted vector                                    */\n    opus_int            *idx,               /* O    Index vector for the sorted elements                        */\n    const opus_int      L,                  /* I    Vector length                                               */\n    const opus_int      K                   /* I    Number of correctly sorted positions                        */\n);\n\n/* Compute reflection coefficients from input signal */\nsilk_float silk_burg_modified_FLP(          /* O    returns residual energy                                     */\n    silk_float          A[],                /* O    prediction coefficients (length order)                      */\n    const silk_float    x[],                /* I    input signal, length: nb_subfr*(D+L_sub)                    */\n    const silk_float    minInvGain,         /* I    minimum inverse prediction gain                             */\n    const opus_int      subfr_length,       /* I    input signal subframe length (incl. D preceding samples)    */\n    const opus_int      nb_subfr,           /* I    number of subframes stacked in x                            */\n    const opus_int      D                   /* I    order                                                       */\n);\n\n/* multiply a vector by a constant */\nvoid silk_scale_vector_FLP(\n    silk_float          *data1,\n    silk_float          gain,\n    opus_int            dataSize\n);\n\n/* copy and multiply a vector by a constant */\nvoid silk_scale_copy_vector_FLP(\n    silk_float          *data_out,\n    const silk_float    *data_in,\n    silk_float          gain,\n    opus_int            dataSize\n);\n\n/* inner product of two silk_float arrays, with result as double */\ndouble silk_inner_product_FLP(\n    const silk_float    *data1,\n    const silk_float    *data2,\n    opus_int            dataSize\n);\n\n/* sum of squares of a silk_float array, with result as double */\ndouble silk_energy_FLP(\n    const silk_float    *data,\n    opus_int            dataSize\n);\n\n/********************************************************************/\n/*                                MACROS                            */\n/********************************************************************/\n\n#define PI              (3.1415926536f)\n\n#define silk_min_float( a, b )                  (((a) < (b)) ? (a) :  (b))\n#define silk_max_float( a, b )                  (((a) > (b)) ? (a) :  (b))\n#define silk_abs_float( a )                     ((silk_float)fabs(a))\n\n/* sigmoid function */\nstatic OPUS_INLINE silk_float silk_sigmoid( silk_float x )\n{\n    return (silk_float)(1.0 / (1.0 + exp(-x)));\n}\n\n/* floating-point to integer conversion (rounding) */\nstatic OPUS_INLINE opus_int32 silk_float2int( silk_float x )\n{\n    return (opus_int32)float2int( x );\n}\n\n/* floating-point to integer conversion (rounding) */\nstatic OPUS_INLINE void silk_float2short_array(\n    opus_int16       *out,\n    const silk_float *in,\n    opus_int32       length\n)\n{\n    opus_int32 k;\n    for( k = length - 1; k >= 0; k-- ) {\n        out[k] = silk_SAT16( (opus_int32)float2int( in[k] ) );\n    }\n}\n\n/* integer to floating-point conversion */\nstatic OPUS_INLINE void silk_short2float_array(\n    silk_float       *out,\n    const opus_int16 *in,\n    opus_int32       length\n)\n{\n    opus_int32 k;\n    for( k = length - 1; k >= 0; k-- ) {\n        out[k] = (silk_float)in[k];\n    }\n}\n\n/* using log2() helps the fixed-point conversion */\nstatic OPUS_INLINE silk_float silk_log2( double x )\n{\n    return ( silk_float )( 3.32192809488736 * log10( x ) );\n}\n\n#ifdef  __cplusplus\n}\n#endif\n\n#endif /* SILK_SIGPROC_FLP_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/apply_sine_window_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n\n/* Apply sine window to signal vector   */\n/* Window types:                        */\n/*  1 -> sine window from 0 to pi/2     */\n/*  2 -> sine window from pi/2 to pi    */\nvoid silk_apply_sine_window_FLP(\n    silk_float                      px_win[],                           /* O    Pointer to windowed signal                  */\n    const silk_float                px[],                               /* I    Pointer to input signal                     */\n    const opus_int                  win_type,                           /* I    Selects a window type                       */\n    const opus_int                  length                              /* I    Window length, multiple of 4                */\n)\n{\n    opus_int   k;\n    silk_float freq, c, S0, S1;\n\n    silk_assert( win_type == 1 || win_type == 2 );\n\n    /* Length must be multiple of 4 */\n    silk_assert( ( length & 3 ) == 0 );\n\n    freq = PI / ( length + 1 );\n\n    /* Approximation of 2 * cos(f) */\n    c = 2.0f - freq * freq;\n\n    /* Initialize state */\n    if( win_type < 2 ) {\n        /* Start from 0 */\n        S0 = 0.0f;\n        /* Approximation of sin(f) */\n        S1 = freq;\n    } else {\n        /* Start from 1 */\n        S0 = 1.0f;\n        /* Approximation of cos(f) */\n        S1 = 0.5f * c;\n    }\n\n    /* Uses the recursive equation:   sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f)   */\n    /* 4 samples at a time */\n    for( k = 0; k < length; k += 4 ) {\n        px_win[ k + 0 ] = px[ k + 0 ] * 0.5f * ( S0 + S1 );\n        px_win[ k + 1 ] = px[ k + 1 ] * S1;\n        S0 = c * S1 - S0;\n        px_win[ k + 2 ] = px[ k + 2 ] * 0.5f * ( S1 + S0 );\n        px_win[ k + 3 ] = px[ k + 3 ] * S0;\n        S1 = c * S0 - S1;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/autocorrelation_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"typedef.h\"\n#include \"SigProc_FLP.h\"\n\n/* compute autocorrelation */\nvoid silk_autocorrelation_FLP(\n    silk_float          *results,           /* O    result (length correlationCount)                            */\n    const silk_float    *inputData,         /* I    input data to correlate                                     */\n    opus_int            inputDataSize,      /* I    length of input                                             */\n    opus_int            correlationCount    /* I    number of correlation taps to compute                       */\n)\n{\n    opus_int i;\n\n    if( correlationCount > inputDataSize ) {\n        correlationCount = inputDataSize;\n    }\n\n    for( i = 0; i < correlationCount; i++ ) {\n        results[ i ] =  (silk_float)silk_inner_product_FLP( inputData, inputData + i, inputDataSize - i );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/burg_modified_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FLP.h\"\n#include \"tuning_parameters.h\"\n#include \"define.h\"\n\n#define MAX_FRAME_SIZE              384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384*/\n\n/* Compute reflection coefficients from input signal */\nsilk_float silk_burg_modified_FLP(          /* O    returns residual energy                                     */\n    silk_float          A[],                /* O    prediction coefficients (length order)                      */\n    const silk_float    x[],                /* I    input signal, length: nb_subfr*(D+L_sub)                    */\n    const silk_float    minInvGain,         /* I    minimum inverse prediction gain                             */\n    const opus_int      subfr_length,       /* I    input signal subframe length (incl. D preceding samples)    */\n    const opus_int      nb_subfr,           /* I    number of subframes stacked in x                            */\n    const opus_int      D                   /* I    order                                                       */\n)\n{\n    opus_int         k, n, s, reached_max_gain;\n    double           C0, invGain, num, nrg_f, nrg_b, rc, Atmp, tmp1, tmp2;\n    const silk_float *x_ptr;\n    double           C_first_row[ SILK_MAX_ORDER_LPC ], C_last_row[ SILK_MAX_ORDER_LPC ];\n    double           CAf[ SILK_MAX_ORDER_LPC + 1 ], CAb[ SILK_MAX_ORDER_LPC + 1 ];\n    double           Af[ SILK_MAX_ORDER_LPC ];\n\n    silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );\n\n    /* Compute autocorrelations, added over subframes */\n    C0 = silk_energy_FLP( x, nb_subfr * subfr_length );\n    silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( double ) );\n    for( s = 0; s < nb_subfr; s++ ) {\n        x_ptr = x + s * subfr_length;\n        for( n = 1; n < D + 1; n++ ) {\n            C_first_row[ n - 1 ] += silk_inner_product_FLP( x_ptr, x_ptr + n, subfr_length - n );\n        }\n    }\n    silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( double ) );\n\n    /* Initialize */\n    CAb[ 0 ] = CAf[ 0 ] = C0 + FIND_LPC_COND_FAC * C0 + 1e-9f;\n    invGain = 1.0f;\n    reached_max_gain = 0;\n    for( n = 0; n < D; n++ ) {\n        /* Update first row of correlation matrix (without first element) */\n        /* Update last row of correlation matrix (without last element, stored in reversed order) */\n        /* Update C * Af */\n        /* Update C * flipud(Af) (stored in reversed order) */\n        for( s = 0; s < nb_subfr; s++ ) {\n            x_ptr = x + s * subfr_length;\n            tmp1 = x_ptr[ n ];\n            tmp2 = x_ptr[ subfr_length - n - 1 ];\n            for( k = 0; k < n; k++ ) {\n                C_first_row[ k ] -= x_ptr[ n ] * x_ptr[ n - k - 1 ];\n                C_last_row[ k ]  -= x_ptr[ subfr_length - n - 1 ] * x_ptr[ subfr_length - n + k ];\n                Atmp = Af[ k ];\n                tmp1 += x_ptr[ n - k - 1 ] * Atmp;\n                tmp2 += x_ptr[ subfr_length - n + k ] * Atmp;\n            }\n            for( k = 0; k <= n; k++ ) {\n                CAf[ k ] -= tmp1 * x_ptr[ n - k ];\n                CAb[ k ] -= tmp2 * x_ptr[ subfr_length - n + k - 1 ];\n            }\n        }\n        tmp1 = C_first_row[ n ];\n        tmp2 = C_last_row[ n ];\n        for( k = 0; k < n; k++ ) {\n            Atmp = Af[ k ];\n            tmp1 += C_last_row[  n - k - 1 ] * Atmp;\n            tmp2 += C_first_row[ n - k - 1 ] * Atmp;\n        }\n        CAf[ n + 1 ] = tmp1;\n        CAb[ n + 1 ] = tmp2;\n\n        /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */\n        num = CAb[ n + 1 ];\n        nrg_b = CAb[ 0 ];\n        nrg_f = CAf[ 0 ];\n        for( k = 0; k < n; k++ ) {\n            Atmp = Af[ k ];\n            num   += CAb[ n - k ] * Atmp;\n            nrg_b += CAb[ k + 1 ] * Atmp;\n            nrg_f += CAf[ k + 1 ] * Atmp;\n        }\n        silk_assert( nrg_f > 0.0 );\n        silk_assert( nrg_b > 0.0 );\n\n        /* Calculate the next order reflection (parcor) coefficient */\n        rc = -2.0 * num / ( nrg_f + nrg_b );\n        silk_assert( rc > -1.0 && rc < 1.0 );\n\n        /* Update inverse prediction gain */\n        tmp1 = invGain * ( 1.0 - rc * rc );\n        if( tmp1 <= minInvGain ) {\n            /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */\n            rc = sqrt( 1.0 - minInvGain / invGain );\n            if( num > 0 ) {\n                /* Ensure adjusted reflection coefficients has the original sign */\n                rc = -rc;\n            }\n            invGain = minInvGain;\n            reached_max_gain = 1;\n        } else {\n            invGain = tmp1;\n        }\n\n        /* Update the AR coefficients */\n        for( k = 0; k < (n + 1) >> 1; k++ ) {\n            tmp1 = Af[ k ];\n            tmp2 = Af[ n - k - 1 ];\n            Af[ k ]         = tmp1 + rc * tmp2;\n            Af[ n - k - 1 ] = tmp2 + rc * tmp1;\n        }\n        Af[ n ] = rc;\n\n        if( reached_max_gain ) {\n            /* Reached max prediction gain; set remaining coefficients to zero and exit loop */\n            for( k = n + 1; k < D; k++ ) {\n                Af[ k ] = 0.0;\n            }\n            break;\n        }\n\n        /* Update C * Af and C * Ab */\n        for( k = 0; k <= n + 1; k++ ) {\n            tmp1 = CAf[ k ];\n            CAf[ k ]          += rc * CAb[ n - k + 1 ];\n            CAb[ n - k + 1  ] += rc * tmp1;\n        }\n    }\n\n    if( reached_max_gain ) {\n        /* Convert to silk_float */\n        for( k = 0; k < D; k++ ) {\n            A[ k ] = (silk_float)( -Af[ k ] );\n        }\n        /* Subtract energy of preceding samples from C0 */\n        for( s = 0; s < nb_subfr; s++ ) {\n            C0 -= silk_energy_FLP( x + s * subfr_length, D );\n        }\n        /* Approximate residual energy */\n        nrg_f = C0 * invGain;\n    } else {\n        /* Compute residual energy and store coefficients as silk_float */\n        nrg_f = CAf[ 0 ];\n        tmp1 = 1.0;\n        for( k = 0; k < D; k++ ) {\n            Atmp = Af[ k ];\n            nrg_f += CAf[ k + 1 ] * Atmp;\n            tmp1  += Atmp * Atmp;\n            A[ k ] = (silk_float)(-Atmp);\n        }\n        nrg_f -= FIND_LPC_COND_FAC * C0 * tmp1;\n    }\n\n    /* Return residual energy */\n    return (silk_float)nrg_f;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/bwexpander_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FLP.h\"\n\n/* Chirp (bw expand) LP AR filter */\nvoid silk_bwexpander_FLP(\n    silk_float          *ar,                /* I/O  AR filter to be expanded (without leading 1)                */\n    const opus_int      d,                  /* I    length of ar                                                */\n    const silk_float    chirp               /* I    chirp factor (typically in range (0..1) )                   */\n)\n{\n    opus_int   i;\n    silk_float cfac = chirp;\n\n    for( i = 0; i < d - 1; i++ ) {\n        ar[ i ] *=  cfac;\n        cfac    *=  chirp;\n    }\n    ar[ d - 1 ] *=  cfac;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/corrMatrix_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/**********************************************************************\n * Correlation matrix computations for LS estimate.\n **********************************************************************/\n\n#include \"main_FLP.h\"\n\n/* Calculates correlation vector X'*t */\nvoid silk_corrVector_FLP(\n    const silk_float                *x,                                 /* I    x vector [L+order-1] used to create X       */\n    const silk_float                *t,                                 /* I    Target vector [L]                           */\n    const opus_int                  L,                                  /* I    Length of vecors                            */\n    const opus_int                  Order,                              /* I    Max lag for correlation                     */\n    silk_float                      *Xt                                 /* O    X'*t correlation vector [order]             */\n)\n{\n    opus_int lag;\n    const silk_float *ptr1;\n\n    ptr1 = &x[ Order - 1 ];                     /* Points to first sample of column 0 of X: X[:,0] */\n    for( lag = 0; lag < Order; lag++ ) {\n        /* Calculate X[:,lag]'*t */\n        Xt[ lag ] = (silk_float)silk_inner_product_FLP( ptr1, t, L );\n        ptr1--;                                 /* Next column of X */\n    }\n}\n\n/* Calculates correlation matrix X'*X */\nvoid silk_corrMatrix_FLP(\n    const silk_float                *x,                                 /* I    x vector [ L+order-1 ] used to create X     */\n    const opus_int                  L,                                  /* I    Length of vectors                           */\n    const opus_int                  Order,                              /* I    Max lag for correlation                     */\n    silk_float                      *XX                                 /* O    X'*X correlation matrix [order x order]     */\n)\n{\n    opus_int j, lag;\n    double  energy;\n    const silk_float *ptr1, *ptr2;\n\n    ptr1 = &x[ Order - 1 ];                     /* First sample of column 0 of X */\n    energy = silk_energy_FLP( ptr1, L );  /* X[:,0]'*X[:,0] */\n    matrix_ptr( XX, 0, 0, Order ) = ( silk_float )energy;\n    for( j = 1; j < Order; j++ ) {\n        /* Calculate X[:,j]'*X[:,j] */\n        energy += ptr1[ -j ] * ptr1[ -j ] - ptr1[ L - j ] * ptr1[ L - j ];\n        matrix_ptr( XX, j, j, Order ) = ( silk_float )energy;\n    }\n\n    ptr2 = &x[ Order - 2 ];                     /* First sample of column 1 of X */\n    for( lag = 1; lag < Order; lag++ ) {\n        /* Calculate X[:,0]'*X[:,lag] */\n        energy = silk_inner_product_FLP( ptr1, ptr2, L );\n        matrix_ptr( XX, lag, 0, Order ) = ( silk_float )energy;\n        matrix_ptr( XX, 0, lag, Order ) = ( silk_float )energy;\n        /* Calculate X[:,j]'*X[:,j + lag] */\n        for( j = 1; j < ( Order - lag ); j++ ) {\n            energy += ptr1[ -j ] * ptr2[ -j ] - ptr1[ L - j ] * ptr2[ L - j ];\n            matrix_ptr( XX, lag + j, j, Order ) = ( silk_float )energy;\n            matrix_ptr( XX, j, lag + j, Order ) = ( silk_float )energy;\n        }\n        ptr2--;                                 /* Next column of X */\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/encode_frame_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n#include \"tuning_parameters.h\"\n\n/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */\nstatic OPUS_INLINE void silk_LBRR_encode_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    const silk_float                xfw[],                              /* I    Input signal                                */\n    opus_int                        condCoding                          /* I    The type of conditional coding used so far for this frame */\n);\n\nvoid silk_encode_do_VAD_FLP(\n    silk_encoder_state_FLP          *psEnc                              /* I/O  Encoder state FLP                           */\n)\n{\n    /****************************/\n    /* Voice Activity Detection */\n    /****************************/\n    silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );\n\n    /**************************************************/\n    /* Convert speech activity into VAD and DTX flags */\n    /**************************************************/\n    if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {\n        psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;\n        psEnc->sCmn.noSpeechCounter++;\n        if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) {\n            psEnc->sCmn.inDTX = 0;\n        } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {\n            psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;\n            psEnc->sCmn.inDTX           = 0;\n        }\n        psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;\n    } else {\n        psEnc->sCmn.noSpeechCounter    = 0;\n        psEnc->sCmn.inDTX              = 0;\n        psEnc->sCmn.indices.signalType = TYPE_UNVOICED;\n        psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;\n    }\n}\n\n/****************/\n/* Encode frame */\n/****************/\nopus_int silk_encode_frame_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    opus_int32                      *pnBytesOut,                        /* O    Number of payload bytes;                    */\n    ec_enc                          *psRangeEnc,                        /* I/O  compressor data structure                   */\n    opus_int                        condCoding,                         /* I    The type of conditional coding to use       */\n    opus_int                        maxBits,                            /* I    If > 0: maximum number of output bits       */\n    opus_int                        useCBR                              /* I    Flag to force constant-bitrate operation    */\n)\n{\n    silk_encoder_control_FLP sEncCtrl;\n    opus_int     i, iter, maxIter, found_upper, found_lower, ret = 0;\n    silk_float   *x_frame, *res_pitch_frame;\n    silk_float   xfw[ MAX_FRAME_LENGTH ];\n    silk_float   res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];\n    ec_enc       sRangeEnc_copy, sRangeEnc_copy2;\n    silk_nsq_state sNSQ_copy, sNSQ_copy2;\n    opus_int32   seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;\n    opus_int32   gainsID, gainsID_lower, gainsID_upper;\n    opus_int16   gainMult_Q8;\n    opus_int16   ec_prevLagIndex_copy;\n    opus_int     ec_prevSignalType_copy;\n    opus_int8    LastGainIndex_copy2;\n    opus_int32   pGains_Q16[ MAX_NB_SUBFR ];\n    opus_uint8   ec_buf_copy[ 1275 ];\n\n    /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */\n    LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;\n\n    psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;\n\n    /**************************************************************/\n    /* Set up Input Pointers, and insert frame in input buffer    */\n    /**************************************************************/\n    /* pointers aligned with start of frame to encode */\n    x_frame         = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;    /* start of frame to encode */\n    res_pitch_frame = res_pitch    + psEnc->sCmn.ltp_mem_length;    /* start of pitch LPC residual frame */\n\n    /***************************************/\n    /* Ensure smooth bandwidth transitions */\n    /***************************************/\n    silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );\n\n    /*******************************************/\n    /* Copy new frame to front of input buffer */\n    /*******************************************/\n    silk_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );\n\n    /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */\n    for( i = 0; i < 8; i++ ) {\n        x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + i * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( i & 2 ) ) * 1e-6f;\n    }\n\n    if( !psEnc->sCmn.prefillFlag ) {\n        /*****************************************/\n        /* Find pitch lags, initial LPC analysis */\n        /*****************************************/\n        silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch );\n\n        /************************/\n        /* Noise shape analysis */\n        /************************/\n        silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame );\n\n        /***************************************************/\n        /* Find linear prediction coefficients (LPC + LTP) */\n        /***************************************************/\n        silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );\n\n        /****************************************/\n        /* Process gains                        */\n        /****************************************/\n        silk_process_gains_FLP( psEnc, &sEncCtrl, condCoding );\n\n        /*****************************************/\n        /* Prefiltering for noise shaper         */\n        /*****************************************/\n        silk_prefilter_FLP( psEnc, &sEncCtrl, xfw, x_frame );\n\n        /****************************************/\n        /* Low Bitrate Redundant Encoding       */\n        /****************************************/\n        silk_LBRR_encode_FLP( psEnc, &sEncCtrl, xfw, condCoding );\n\n        /* Loop over quantizer and entroy coding to control bitrate */\n        maxIter = 6;\n        gainMult_Q8 = SILK_FIX_CONST( 1, 8 );\n        found_lower = 0;\n        found_upper = 0;\n        gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );\n        gainsID_lower = -1;\n        gainsID_upper = -1;\n        /* Copy part of the input state */\n        silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );\n        silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );\n        seed_copy = psEnc->sCmn.indices.Seed;\n        ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;\n        ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;\n        for( iter = 0; ; iter++ ) {\n            if( gainsID == gainsID_lower ) {\n                nBits = nBits_lower;\n            } else if( gainsID == gainsID_upper ) {\n                nBits = nBits_upper;\n            } else {\n                /* Restore part of the input state */\n                if( iter > 0 ) {\n                    silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );\n                    silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );\n                    psEnc->sCmn.indices.Seed = seed_copy;\n                    psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;\n                    psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;\n                }\n\n                /*****************************************/\n                /* Noise shaping quantization            */\n                /*****************************************/\n                silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw );\n\n                /****************************************/\n                /* Encode Parameters                    */\n                /****************************************/\n                silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );\n\n                /****************************************/\n                /* Encode Excitation Signal             */\n                /****************************************/\n                silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,\n                      psEnc->sCmn.pulses, psEnc->sCmn.frame_length );\n\n                nBits = ec_tell( psRangeEnc );\n\n                if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {\n                    break;\n                }\n            }\n\n            if( iter == maxIter ) {\n                if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {\n                    /* Restore output state from earlier iteration that did meet the bitrate budget */\n                    silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );\n                    silk_assert( sRangeEnc_copy2.offs <= 1275 );\n                    silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );\n                    silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );\n                    psEnc->sShape.LastGainIndex = LastGainIndex_copy2;\n                }\n                break;\n            }\n\n            if( nBits > maxBits ) {\n                if( found_lower == 0 && iter >= 2 ) {\n                    /* Adjust the quantizer's rate/distortion tradeoff and discard previous \"upper\" results */\n                    sEncCtrl.Lambda *= 1.5f;\n                    found_upper = 0;\n                    gainsID_upper = -1;\n                } else {\n                    found_upper = 1;\n                    nBits_upper = nBits;\n                    gainMult_upper = gainMult_Q8;\n                    gainsID_upper = gainsID;\n                }\n            } else if( nBits < maxBits - 5 ) {\n                found_lower = 1;\n                nBits_lower = nBits;\n                gainMult_lower = gainMult_Q8;\n                if( gainsID != gainsID_lower ) {\n                    gainsID_lower = gainsID;\n                    /* Copy part of the output state */\n                    silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );\n                    silk_assert( psRangeEnc->offs <= 1275 );\n                    silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );\n                    silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );\n                    LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;\n                }\n            } else {\n                /* Within 5 bits of budget: close enough */\n                break;\n            }\n\n            if( ( found_lower & found_upper ) == 0 ) {\n                /* Adjust gain according to high-rate rate/distortion curve */\n                opus_int32 gain_factor_Q16;\n                gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );\n                gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) );\n                if( nBits > maxBits ) {\n                    gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) );\n                }\n                gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );\n            } else {\n                /* Adjust gain by interpolating */\n                gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower );\n                /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */\n                if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {\n                    gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );\n                } else\n                if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {\n                    gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );\n                }\n            }\n\n            for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\n                pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 );\n            }\n\n            /* Quantize gains */\n            psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;\n            silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16,\n                  &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );\n\n            /* Unique identifier of gains vector */\n            gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );\n\n            /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */\n            for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\n                sEncCtrl.Gains[ i ] = pGains_Q16[ i ] / 65536.0f;\n            }\n        }\n    }\n\n    /* Update input buffer */\n    silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],\n        ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( silk_float ) );\n\n    /* Exit without entropy coding */\n    if( psEnc->sCmn.prefillFlag ) {\n        /* No payload */\n        *pnBytesOut = 0;\n        return ret;\n    }\n\n    /* Parameters needed for next frame */\n    psEnc->sCmn.prevLag        = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];\n    psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;\n\n    /****************************************/\n    /* Finalize payload                     */\n    /****************************************/\n    psEnc->sCmn.first_frame_after_reset = 0;\n    /* Payload size */\n    *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );\n\n    return ret;\n}\n\n/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate  */\nstatic OPUS_INLINE void silk_LBRR_encode_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    const silk_float                xfw[],                              /* I    Input signal                                */\n    opus_int                        condCoding                          /* I    The type of conditional coding used so far for this frame */\n)\n{\n    opus_int     k;\n    opus_int32   Gains_Q16[ MAX_NB_SUBFR ];\n    silk_float   TempGains[ MAX_NB_SUBFR ];\n    SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];\n    silk_nsq_state sNSQ_LBRR;\n\n    /*******************************************/\n    /* Control use of inband LBRR              */\n    /*******************************************/\n    if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {\n        psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;\n\n        /* Copy noise shaping quantizer state and quantization indices from regular encoding */\n        silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );\n        silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );\n\n        /* Save original gains */\n        silk_memcpy( TempGains, psEncCtrl->Gains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) );\n\n        if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {\n            /* First frame in packet or previous frame not LBRR coded */\n            psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;\n\n            /* Increase Gains to get target LBRR rate */\n            psIndices_LBRR->GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases;\n            psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );\n        }\n\n        /* Decode to get gains in sync with decoder */\n        silk_gains_dequant( Gains_Q16, psIndices_LBRR->GainsIndices,\n            &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );\n\n        /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */\n        for( k = 0; k <  psEnc->sCmn.nb_subfr; k++ ) {\n            psEncCtrl->Gains[ k ] = Gains_Q16[ k ] * ( 1.0f / 65536.0f );\n        }\n\n        /*****************************************/\n        /* Noise shaping quantization            */\n        /*****************************************/\n        silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, psIndices_LBRR, &sNSQ_LBRR,\n            psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], xfw );\n\n        /* Restore original gains */\n        silk_memcpy( psEncCtrl->Gains, TempGains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/energy_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FLP.h\"\n\n/* sum of squares of a silk_float array, with result as double */\ndouble silk_energy_FLP(\n    const silk_float    *data,\n    opus_int            dataSize\n)\n{\n    opus_int  i, dataSize4;\n    double   result;\n\n    /* 4x unrolled loop */\n    result = 0.0;\n    dataSize4 = dataSize & 0xFFFC;\n    for( i = 0; i < dataSize4; i += 4 ) {\n        result += data[ i + 0 ] * (double)data[ i + 0 ] +\n                  data[ i + 1 ] * (double)data[ i + 1 ] +\n                  data[ i + 2 ] * (double)data[ i + 2 ] +\n                  data[ i + 3 ] * (double)data[ i + 3 ];\n    }\n\n    /* add any remaining products */\n    for( ; i < dataSize; i++ ) {\n        result += data[ i ] * (double)data[ i ];\n    }\n\n    silk_assert( result >= 0.0 );\n    return result;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/find_LPC_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"define.h\"\n#include \"main_FLP.h\"\n#include \"tuning_parameters.h\"\n\n/* LPC analysis */\nvoid silk_find_LPC_FLP(\n    silk_encoder_state              *psEncC,                            /* I/O  Encoder state                               */\n    opus_int16                      NLSF_Q15[],                         /* O    NLSFs                                       */\n    const silk_float                x[],                                /* I    Input signal                                */\n    const silk_float                minInvGain                          /* I    Inverse of max prediction gain              */\n)\n{\n    opus_int    k, subfr_length;\n    silk_float  a[ MAX_LPC_ORDER ];\n\n    /* Used only for NLSF interpolation */\n    silk_float  res_nrg, res_nrg_2nd, res_nrg_interp;\n    opus_int16  NLSF0_Q15[ MAX_LPC_ORDER ];\n    silk_float  a_tmp[ MAX_LPC_ORDER ];\n    silk_float  LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ];\n\n    subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;\n\n    /* Default: No interpolation */\n    psEncC->indices.NLSFInterpCoef_Q2 = 4;\n\n    /* Burg AR analysis for the full frame */\n    res_nrg = silk_burg_modified_FLP( a, x, minInvGain, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder );\n\n    if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {\n        /* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than        */\n        /* adding it to the residual energy of the first 10 ms in each iteration of the search below    */\n        res_nrg -= silk_burg_modified_FLP( a_tmp, x + ( MAX_NB_SUBFR / 2 ) * subfr_length, minInvGain, subfr_length, MAX_NB_SUBFR / 2, psEncC->predictLPCOrder );\n\n        /* Convert to NLSFs */\n        silk_A2NLSF_FLP( NLSF_Q15, a_tmp, psEncC->predictLPCOrder );\n\n        /* Search over interpolation indices to find the one with lowest residual energy */\n        res_nrg_2nd = silk_float_MAX;\n        for( k = 3; k >= 0; k-- ) {\n            /* Interpolate NLSFs for first half */\n            silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );\n\n            /* Convert to LPC for residual energy evaluation */\n            silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder );\n\n            /* Calculate residual energy with LSF interpolation */\n            silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, psEncC->predictLPCOrder );\n            res_nrg_interp = (silk_float)(\n                silk_energy_FLP( LPC_res + psEncC->predictLPCOrder,                subfr_length - psEncC->predictLPCOrder ) +\n                silk_energy_FLP( LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ) );\n\n            /* Determine whether current interpolated NLSFs are best so far */\n            if( res_nrg_interp < res_nrg ) {\n                /* Interpolation has lower residual energy */\n                res_nrg = res_nrg_interp;\n                psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k;\n            } else if( res_nrg_interp > res_nrg_2nd ) {\n                /* No reason to continue iterating - residual energies will continue to climb */\n                break;\n            }\n            res_nrg_2nd = res_nrg_interp;\n        }\n    }\n\n    if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) {\n        /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */\n        silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder );\n    }\n\n    silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 ||\n        ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/find_LTP_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n#include \"tuning_parameters.h\"\n\nvoid silk_find_LTP_FLP(\n    silk_float                      b[ MAX_NB_SUBFR * LTP_ORDER ],      /* O    LTP coefs                                   */\n    silk_float                      WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O    Weight for LTP quantization       */\n    silk_float                      *LTPredCodGain,                     /* O    LTP coding gain                             */\n    const silk_float                r_lpc[],                            /* I    LPC residual                                */\n    const opus_int                  lag[  MAX_NB_SUBFR ],               /* I    LTP lags                                    */\n    const silk_float                Wght[ MAX_NB_SUBFR ],               /* I    Weights                                     */\n    const opus_int                  subfr_length,                       /* I    Subframe length                             */\n    const opus_int                  nb_subfr,                           /* I    number of subframes                         */\n    const opus_int                  mem_offset                          /* I    Number of samples in LTP memory             */\n)\n{\n    opus_int   i, k;\n    silk_float *b_ptr, temp, *WLTP_ptr;\n    silk_float LPC_res_nrg, LPC_LTP_res_nrg;\n    silk_float d[ MAX_NB_SUBFR ], m, g, delta_b[ LTP_ORDER ];\n    silk_float w[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], regu;\n    silk_float Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ];\n    const silk_float *r_ptr, *lag_ptr;\n\n    b_ptr    = b;\n    WLTP_ptr = WLTP;\n    r_ptr    = &r_lpc[ mem_offset ];\n    for( k = 0; k < nb_subfr; k++ ) {\n        lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );\n\n        silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, WLTP_ptr );\n        silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr );\n\n        rr[ k ] = ( silk_float )silk_energy_FLP( r_ptr, subfr_length );\n        regu = 1.0f + rr[ k ] +\n            matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ) +\n            matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER );\n        regu *= LTP_DAMPING / 3;\n        silk_regularize_correlations_FLP( WLTP_ptr, &rr[ k ], regu, LTP_ORDER );\n        silk_solve_LDL_FLP( WLTP_ptr, LTP_ORDER, Rr, b_ptr );\n\n        /* Calculate residual energy */\n        nrg[ k ] = silk_residual_energy_covar_FLP( b_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER );\n\n        temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length );\n        silk_scale_vector_FLP( WLTP_ptr, temp, LTP_ORDER * LTP_ORDER );\n        w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER / 2, LTP_ORDER / 2, LTP_ORDER );\n\n        r_ptr    += subfr_length;\n        b_ptr    += LTP_ORDER;\n        WLTP_ptr += LTP_ORDER * LTP_ORDER;\n    }\n\n    /* Compute LTP coding gain */\n    if( LTPredCodGain != NULL ) {\n        LPC_LTP_res_nrg = 1e-6f;\n        LPC_res_nrg     = 0.0f;\n        for( k = 0; k < nb_subfr; k++ ) {\n            LPC_res_nrg     += rr[  k ] * Wght[ k ];\n            LPC_LTP_res_nrg += nrg[ k ] * Wght[ k ];\n        }\n\n        silk_assert( LPC_LTP_res_nrg > 0 );\n        *LTPredCodGain = 3.0f * silk_log2( LPC_res_nrg / LPC_LTP_res_nrg );\n    }\n\n    /* Smoothing */\n    /* d = sum( B, 1 ); */\n    b_ptr = b;\n    for( k = 0; k < nb_subfr; k++ ) {\n        d[ k ] = 0;\n        for( i = 0; i < LTP_ORDER; i++ ) {\n            d[ k ] += b_ptr[ i ];\n        }\n        b_ptr += LTP_ORDER;\n    }\n    /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */\n    temp = 1e-3f;\n    for( k = 0; k < nb_subfr; k++ ) {\n        temp += w[ k ];\n    }\n    m = 0;\n    for( k = 0; k < nb_subfr; k++ ) {\n        m += d[ k ] * w[ k ];\n    }\n    m = m / temp;\n\n    b_ptr = b;\n    for( k = 0; k < nb_subfr; k++ ) {\n        g = LTP_SMOOTHING / ( LTP_SMOOTHING + w[ k ] ) * ( m - d[ k ] );\n        temp = 0;\n        for( i = 0; i < LTP_ORDER; i++ ) {\n            delta_b[ i ] = silk_max_float( b_ptr[ i ], 0.1f );\n            temp += delta_b[ i ];\n        }\n        temp = g / temp;\n        for( i = 0; i < LTP_ORDER; i++ ) {\n            b_ptr[ i ] = b_ptr[ i ] + delta_b[ i ] * temp;\n        }\n        b_ptr += LTP_ORDER;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/find_pitch_lags_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdlib.h>\n#include \"main_FLP.h\"\n#include \"tuning_parameters.h\"\n\nvoid silk_find_pitch_lags_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    silk_float                      res[],                              /* O    Residual                                    */\n    const silk_float                x[],                                /* I    Speech signal                               */\n    int                             arch                                /* I    Run-time architecture                       */\n)\n{\n    opus_int   buf_len;\n    silk_float thrhld, res_nrg;\n    const silk_float *x_buf_ptr, *x_buf;\n    silk_float auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];\n    silk_float A[         MAX_FIND_PITCH_LPC_ORDER ];\n    silk_float refl_coef[ MAX_FIND_PITCH_LPC_ORDER ];\n    silk_float Wsig[      FIND_PITCH_LPC_WIN_MAX ];\n    silk_float *Wsig_ptr;\n\n    /******************************************/\n    /* Set up buffer lengths etc based on Fs  */\n    /******************************************/\n    buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;\n\n    /* Safety check */\n    silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );\n\n    x_buf = x - psEnc->sCmn.ltp_mem_length;\n\n    /******************************************/\n    /* Estimate LPC AR coeficients            */\n    /******************************************/\n\n    /* Calculate windowed signal */\n\n    /* First LA_LTP samples */\n    x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length;\n    Wsig_ptr  = Wsig;\n    silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch );\n\n    /* Middle non-windowed samples */\n    Wsig_ptr  += psEnc->sCmn.la_pitch;\n    x_buf_ptr += psEnc->sCmn.la_pitch;\n    silk_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ) ) * sizeof( silk_float ) );\n\n    /* Last LA_LTP samples */\n    Wsig_ptr  += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 );\n    x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 );\n    silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch );\n\n    /* Calculate autocorrelation sequence */\n    silk_autocorrelation_FLP( auto_corr, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 );\n\n    /* Add white noise, as a fraction of the energy */\n    auto_corr[ 0 ] += auto_corr[ 0 ] * FIND_PITCH_WHITE_NOISE_FRACTION + 1;\n\n    /* Calculate the reflection coefficients using Schur */\n    res_nrg = silk_schur_FLP( refl_coef, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );\n\n    /* Prediction gain */\n    psEncCtrl->predGain = auto_corr[ 0 ] / silk_max_float( res_nrg, 1.0f );\n\n    /* Convert reflection coefficients to prediction coefficients */\n    silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder );\n\n    /* Bandwidth expansion */\n    silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWIDTH_EXPANSION );\n\n    /*****************************************/\n    /* LPC analysis filtering                */\n    /*****************************************/\n    silk_LPC_analysis_filter_FLP( res, A, x_buf, buf_len, psEnc->sCmn.pitchEstimationLPCOrder );\n\n    if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) {\n        /* Threshold for pitch estimator */\n        thrhld  = 0.6f;\n        thrhld -= 0.004f * psEnc->sCmn.pitchEstimationLPCOrder;\n        thrhld -= 0.1f   * psEnc->sCmn.speech_activity_Q8 * ( 1.0f /  256.0f );\n        thrhld -= 0.15f  * (psEnc->sCmn.prevSignalType >> 1);\n        thrhld -= 0.1f   * psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f );\n\n        /*****************************************/\n        /* Call Pitch estimator                  */\n        /*****************************************/\n        if( silk_pitch_analysis_core_FLP( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex,\n            &psEnc->sCmn.indices.contourIndex, &psEnc->LTPCorr, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16 / 65536.0f,\n            thrhld, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr, arch ) == 0 )\n        {\n            psEnc->sCmn.indices.signalType = TYPE_VOICED;\n        } else {\n            psEnc->sCmn.indices.signalType = TYPE_UNVOICED;\n        }\n    } else {\n        silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) );\n        psEnc->sCmn.indices.lagIndex = 0;\n        psEnc->sCmn.indices.contourIndex = 0;\n        psEnc->LTPCorr = 0;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/find_pred_coefs_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n\n/* Find LPC and LTP coefficients */\nvoid silk_find_pred_coefs_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    const silk_float                res_pitch[],                        /* I    Residual from pitch analysis                */\n    const silk_float                x[],                                /* I    Speech signal                               */\n    opus_int                        condCoding                          /* I    The type of conditional coding to use       */\n)\n{\n    opus_int         i;\n    silk_float       WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];\n    silk_float       invGains[ MAX_NB_SUBFR ], Wght[ MAX_NB_SUBFR ];\n    opus_int16       NLSF_Q15[ MAX_LPC_ORDER ];\n    const silk_float *x_ptr;\n    silk_float       *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];\n    silk_float       minInvGain;\n\n    /* Weighting for weighted least squares */\n    for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\n        silk_assert( psEncCtrl->Gains[ i ] > 0.0f );\n        invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ];\n        Wght[ i ]     = invGains[ i ] * invGains[ i ];\n    }\n\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /**********/\n        /* VOICED */\n        /**********/\n        silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );\n\n        /* LTP analysis */\n        silk_find_LTP_FLP( psEncCtrl->LTPCoef, WLTP, &psEncCtrl->LTPredCodGain, res_pitch,\n            psEncCtrl->pitchL, Wght, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length );\n\n        /* Quantize LTP gain parameters */\n        silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,\n            &psEnc->sCmn.sum_log_gain_Q7, WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr,\n            psEnc->sCmn.arch );\n\n        /* Control LTP scaling */\n        silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl, condCoding );\n\n        /* Create LTP residual */\n        silk_LTP_analysis_filter_FLP( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef,\n            psEncCtrl->pitchL, invGains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );\n    } else {\n        /************/\n        /* UNVOICED */\n        /************/\n        /* Create signal with prepended subframes, scaled by inverse gains */\n        x_ptr     = x - psEnc->sCmn.predictLPCOrder;\n        x_pre_ptr = LPC_in_pre;\n        for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\n            silk_scale_copy_vector_FLP( x_pre_ptr, x_ptr, invGains[ i ],\n                psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );\n            x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;\n            x_ptr     += psEnc->sCmn.subfr_length;\n        }\n        silk_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) );\n        psEncCtrl->LTPredCodGain = 0.0f;\n        psEnc->sCmn.sum_log_gain_Q7 = 0;\n    }\n\n    /* Limit on total predictive coding gain */\n    if( psEnc->sCmn.first_frame_after_reset ) {\n        minInvGain = 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET;\n    } else {\n        minInvGain = (silk_float)pow( 2, psEncCtrl->LTPredCodGain / 3 ) /  MAX_PREDICTION_POWER_GAIN;\n        minInvGain /= 0.25f + 0.75f * psEncCtrl->coding_quality;\n    }\n\n    /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */\n    silk_find_LPC_FLP( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain );\n\n    /* Quantize LSFs */\n    silk_process_NLSFs_FLP( &psEnc->sCmn, psEncCtrl->PredCoef, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );\n\n    /* Calculate residual energy using quantized LPC coefficients */\n    silk_residual_energy_FLP( psEncCtrl->ResNrg, LPC_in_pre, psEncCtrl->PredCoef, psEncCtrl->Gains,\n        psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );\n\n    /* Copy to prediction struct for use in next frame for interpolation */\n    silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/inner_product_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FLP.h\"\n\n/* inner product of two silk_float arrays, with result as double */\ndouble silk_inner_product_FLP(\n    const silk_float    *data1,\n    const silk_float    *data2,\n    opus_int            dataSize\n)\n{\n    opus_int  i, dataSize4;\n    double   result;\n\n    /* 4x unrolled loop */\n    result = 0.0;\n    dataSize4 = dataSize & 0xFFFC;\n    for( i = 0; i < dataSize4; i += 4 ) {\n        result += data1[ i + 0 ] * (double)data2[ i + 0 ] +\n                  data1[ i + 1 ] * (double)data2[ i + 1 ] +\n                  data1[ i + 2 ] * (double)data2[ i + 2 ] +\n                  data1[ i + 3 ] * (double)data2[ i + 3 ];\n    }\n\n    /* add any remaining products */\n    for( ; i < dataSize; i++ ) {\n        result += data1[ i ] * (double)data2[ i ];\n    }\n\n    return result;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/k2a_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FLP.h\"\n\n/* step up function, converts reflection coefficients to prediction coefficients */\nvoid silk_k2a_FLP(\n    silk_float          *A,                 /* O     prediction coefficients [order]                            */\n    const silk_float    *rc,                /* I     reflection coefficients [order]                            */\n    opus_int32          order               /* I     prediction order                                           */\n)\n{\n    opus_int   k, n;\n    silk_float Atmp[ SILK_MAX_ORDER_LPC ];\n\n    for( k = 0; k < order; k++ ) {\n        for( n = 0; n < k; n++ ) {\n            Atmp[ n ] = A[ n ];\n        }\n        for( n = 0; n < k; n++ ) {\n            A[ n ] += Atmp[ k - n - 1 ] * rc[ k ];\n        }\n        A[ k ] = -rc[ k ];\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/levinsondurbin_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FLP.h\"\n\n/* Solve the normal equations using the Levinson-Durbin recursion */\nsilk_float silk_levinsondurbin_FLP(         /* O    prediction error energy                                     */\n    silk_float          A[],                /* O    prediction coefficients    [order]                          */\n    const silk_float    corr[],             /* I    input auto-correlations [order + 1]                         */\n    const opus_int      order               /* I    prediction order                                            */\n)\n{\n    opus_int   i, mHalf, m;\n    silk_float min_nrg, nrg, t, km, Atmp1, Atmp2;\n\n    min_nrg = 1e-12f * corr[ 0 ] + 1e-9f;\n    nrg = corr[ 0 ];\n    nrg = silk_max_float(min_nrg, nrg);\n    A[ 0 ] = corr[ 1 ] / nrg;\n    nrg -= A[ 0 ] * corr[ 1 ];\n    nrg = silk_max_float(min_nrg, nrg);\n\n    for( m = 1; m < order; m++ )\n    {\n        t = corr[ m + 1 ];\n        for( i = 0; i < m; i++ ) {\n            t -= A[ i ] * corr[ m - i ];\n        }\n\n        /* reflection coefficient */\n        km = t / nrg;\n\n        /* residual energy */\n        nrg -= km * t;\n        nrg = silk_max_float(min_nrg, nrg);\n\n        mHalf = m >> 1;\n        for( i = 0; i < mHalf; i++ ) {\n            Atmp1 = A[ i ];\n            Atmp2 = A[ m - i - 1 ];\n            A[ m - i - 1 ] -= km * Atmp1;\n            A[ i ]         -= km * Atmp2;\n        }\n        if( m & 1 ) {\n            A[ mHalf ]     -= km * A[ mHalf ];\n        }\n        A[ m ] = km;\n    }\n\n    /* return the residual energy */\n    return nrg;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/main_FLP.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_MAIN_FLP_H\n#define SILK_MAIN_FLP_H\n\n#include \"SigProc_FLP.h\"\n#include \"SigProc_FIX.h\"\n#include \"structs_FLP.h\"\n#include \"main.h\"\n#include \"define.h\"\n#include \"debug.h\"\n#include \"entenc.h\"\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n#define silk_encoder_state_Fxx      silk_encoder_state_FLP\n#define silk_encode_do_VAD_Fxx      silk_encode_do_VAD_FLP\n#define silk_encode_frame_Fxx       silk_encode_frame_FLP\n\n/*********************/\n/* Encoder Functions */\n/*********************/\n\n/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */\nvoid silk_HP_variable_cutoff(\n    silk_encoder_state_Fxx          state_Fxx[]                         /* I/O  Encoder states                              */\n);\n\n/* Encoder main function */\nvoid silk_encode_do_VAD_FLP(\n    silk_encoder_state_FLP          *psEnc                              /* I/O  Encoder state FLP                           */\n);\n\n/* Encoder main function */\nopus_int silk_encode_frame_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    opus_int32                      *pnBytesOut,                        /* O    Number of payload bytes;                    */\n    ec_enc                          *psRangeEnc,                        /* I/O  compressor data structure                   */\n    opus_int                        condCoding,                         /* I    The type of conditional coding to use       */\n    opus_int                        maxBits,                            /* I    If > 0: maximum number of output bits       */\n    opus_int                        useCBR                              /* I    Flag to force constant-bitrate operation    */\n);\n\n/* Initializes the Silk encoder state */\nopus_int silk_init_encoder(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    int                              arch                               /* I    Run-tim architecture                        */\n);\n\n/* Control the Silk encoder */\nopus_int silk_control_encoder(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Pointer to Silk encoder state FLP           */\n    silk_EncControlStruct           *encControl,                        /* I    Control structure                           */\n    const opus_int32                TargetRate_bps,                     /* I    Target max bitrate (bps)                    */\n    const opus_int                  allow_bw_switch,                    /* I    Flag to allow switching audio bandwidth     */\n    const opus_int                  channelNb,                          /* I    Channel number                              */\n    const opus_int                  force_fs_kHz\n);\n\n/****************/\n/* Prefiltering */\n/****************/\nvoid silk_prefilter_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    const silk_encoder_control_FLP  *psEncCtrl,                         /* I    Encoder control FLP                         */\n    silk_float                      xw[],                               /* O    Weighted signal                             */\n    const silk_float                x[]                                 /* I    Speech signal                               */\n);\n\n/**************************/\n/* Noise shaping analysis */\n/**************************/\n/* Compute noise shaping coefficients and initial gain values */\nvoid silk_noise_shape_analysis_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    const silk_float                *pitch_res,                         /* I    LPC residual from pitch analysis            */\n    const silk_float                *x                                  /* I    Input signal [frame_length + la_shape]      */\n);\n\n/* Autocorrelations for a warped frequency axis */\nvoid silk_warped_autocorrelation_FLP(\n    silk_float                      *corr,                              /* O    Result [order + 1]                          */\n    const silk_float                *input,                             /* I    Input data to correlate                     */\n    const silk_float                warping,                            /* I    Warping coefficient                         */\n    const opus_int                  length,                             /* I    Length of input                             */\n    const opus_int                  order                               /* I    Correlation order (even)                    */\n);\n\n/* Calculation of LTP state scaling */\nvoid silk_LTP_scale_ctrl_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    opus_int                        condCoding                          /* I    The type of conditional coding to use       */\n);\n\n/**********************************************/\n/* Prediction Analysis                        */\n/**********************************************/\n/* Find pitch lags */\nvoid silk_find_pitch_lags_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    silk_float                      res[],                              /* O    Residual                                    */\n    const silk_float                x[],                                /* I    Speech signal                               */\n    int                             arch                                /* I    Run-time architecture                       */\n);\n\n/* Find LPC and LTP coefficients */\nvoid silk_find_pred_coefs_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    const silk_float                res_pitch[],                        /* I    Residual from pitch analysis                */\n    const silk_float                x[],                                /* I    Speech signal                               */\n    opus_int                        condCoding                          /* I    The type of conditional coding to use       */\n);\n\n/* LPC analysis */\nvoid silk_find_LPC_FLP(\n    silk_encoder_state              *psEncC,                            /* I/O  Encoder state                               */\n    opus_int16                      NLSF_Q15[],                         /* O    NLSFs                                       */\n    const silk_float                x[],                                /* I    Input signal                                */\n    const silk_float                minInvGain                          /* I    Prediction gain from LTP (dB)               */\n);\n\n/* LTP analysis */\nvoid silk_find_LTP_FLP(\n    silk_float                      b[ MAX_NB_SUBFR * LTP_ORDER ],      /* O    LTP coefs                                   */\n    silk_float                      WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O    Weight for LTP quantization       */\n    silk_float                      *LTPredCodGain,                     /* O    LTP coding gain                             */\n    const silk_float                r_lpc[],                            /* I    LPC residual                                */\n    const opus_int                  lag[  MAX_NB_SUBFR ],               /* I    LTP lags                                    */\n    const silk_float                Wght[ MAX_NB_SUBFR ],               /* I    Weights                                     */\n    const opus_int                  subfr_length,                       /* I    Subframe length                             */\n    const opus_int                  nb_subfr,                           /* I    number of subframes                         */\n    const opus_int                  mem_offset                          /* I    Number of samples in LTP memory             */\n);\n\nvoid silk_LTP_analysis_filter_FLP(\n    silk_float                      *LTP_res,                           /* O    LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */\n    const silk_float                *x,                                 /* I    Input signal, with preceding samples        */\n    const silk_float                B[ LTP_ORDER * MAX_NB_SUBFR ],      /* I    LTP coefficients for each subframe          */\n    const opus_int                  pitchL[   MAX_NB_SUBFR ],           /* I    Pitch lags                                  */\n    const silk_float                invGains[ MAX_NB_SUBFR ],           /* I    Inverse quantization gains                  */\n    const opus_int                  subfr_length,                       /* I    Length of each subframe                     */\n    const opus_int                  nb_subfr,                           /* I    number of subframes                         */\n    const opus_int                  pre_length                          /* I    Preceding samples for each subframe         */\n);\n\n/* Calculates residual energies of input subframes where all subframes have LPC_order   */\n/* of preceding samples                                                                 */\nvoid silk_residual_energy_FLP(\n    silk_float                      nrgs[ MAX_NB_SUBFR ],               /* O    Residual energy per subframe                */\n    const silk_float                x[],                                /* I    Input signal                                */\n    silk_float                      a[ 2 ][ MAX_LPC_ORDER ],            /* I    AR coefs for each frame half                */\n    const silk_float                gains[],                            /* I    Quantization gains                          */\n    const opus_int                  subfr_length,                       /* I    Subframe length                             */\n    const opus_int                  nb_subfr,                           /* I    number of subframes                         */\n    const opus_int                  LPC_order                           /* I    LPC order                                   */\n);\n\n/* 16th order LPC analysis filter */\nvoid silk_LPC_analysis_filter_FLP(\n    silk_float                      r_LPC[],                            /* O    LPC residual signal                         */\n    const silk_float                PredCoef[],                         /* I    LPC coefficients                            */\n    const silk_float                s[],                                /* I    Input signal                                */\n    const opus_int                  length,                             /* I    Length of input signal                      */\n    const opus_int                  Order                               /* I    LPC order                                   */\n);\n\n/* LTP tap quantizer */\nvoid silk_quant_LTP_gains_FLP(\n    silk_float                      B[ MAX_NB_SUBFR * LTP_ORDER ],      /* I/O  (Un-)quantized LTP gains                    */\n    opus_int8                       cbk_index[ MAX_NB_SUBFR ],          /* O    Codebook index                              */\n    opus_int8                       *periodicity_index,                 /* O    Periodicity index                           */\n    opus_int32                      *sum_log_gain_Q7,                   /* I/O  Cumulative max prediction gain  */\n    const silk_float                W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I    Error weights                        */\n    const opus_int                  mu_Q10,                             /* I    Mu value (R/D tradeoff)                     */\n    const opus_int                  lowComplexity,                      /* I    Flag for low complexity                     */\n    const opus_int                  nb_subfr,                           /* I    number of subframes                         */\n    int                             arch                                /* I    Run-time architecture                       */\n);\n\n/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */\nsilk_float silk_residual_energy_covar_FLP(                              /* O    Weighted residual energy                    */\n    const silk_float                *c,                                 /* I    Filter coefficients                         */\n    silk_float                      *wXX,                               /* I/O  Weighted correlation matrix, reg. out       */\n    const silk_float                *wXx,                               /* I    Weighted correlation vector                 */\n    const silk_float                wxx,                                /* I    Weighted correlation value                  */\n    const opus_int                  D                                   /* I    Dimension                                   */\n);\n\n/* Processing of gains */\nvoid silk_process_gains_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    opus_int                        condCoding                          /* I    The type of conditional coding to use       */\n);\n\n/******************/\n/* Linear Algebra */\n/******************/\n/* Calculates correlation matrix X'*X */\nvoid silk_corrMatrix_FLP(\n    const silk_float                *x,                                 /* I    x vector [ L+order-1 ] used to create X     */\n    const opus_int                  L,                                  /* I    Length of vectors                           */\n    const opus_int                  Order,                              /* I    Max lag for correlation                     */\n    silk_float                      *XX                                 /* O    X'*X correlation matrix [order x order]     */\n);\n\n/* Calculates correlation vector X'*t */\nvoid silk_corrVector_FLP(\n    const silk_float                *x,                                 /* I    x vector [L+order-1] used to create X       */\n    const silk_float                *t,                                 /* I    Target vector [L]                           */\n    const opus_int                  L,                                  /* I    Length of vecors                            */\n    const opus_int                  Order,                              /* I    Max lag for correlation                     */\n    silk_float                      *Xt                                 /* O    X'*t correlation vector [order]             */\n);\n\n/* Add noise to matrix diagonal */\nvoid silk_regularize_correlations_FLP(\n    silk_float                      *XX,                                /* I/O  Correlation matrices                        */\n    silk_float                      *xx,                                /* I/O  Correlation values                          */\n    const silk_float                noise,                              /* I    Noise energy to add                         */\n    const opus_int                  D                                   /* I    Dimension of XX                             */\n);\n\n/* Function to solve linear equation Ax = b, where A is an MxM symmetric matrix */\nvoid silk_solve_LDL_FLP(\n    silk_float                      *A,                                 /* I/O  Symmetric square matrix, out: reg.          */\n    const opus_int                  M,                                  /* I    Size of matrix                              */\n    const silk_float                *b,                                 /* I    Pointer to b vector                         */\n    silk_float                      *x                                  /* O    Pointer to x solution vector                */\n);\n\n/* Apply sine window to signal vector.  */\n/* Window types:                        */\n/*  1 -> sine window from 0 to pi/2     */\n/*  2 -> sine window from pi/2 to pi    */\nvoid silk_apply_sine_window_FLP(\n    silk_float                      px_win[],                           /* O    Pointer to windowed signal                  */\n    const silk_float                px[],                               /* I    Pointer to input signal                     */\n    const opus_int                  win_type,                           /* I    Selects a window type                       */\n    const opus_int                  length                              /* I    Window length, multiple of 4                */\n);\n\n/* Wrapper functions. Call flp / fix code */\n\n/* Convert AR filter coefficients to NLSF parameters */\nvoid silk_A2NLSF_FLP(\n    opus_int16                      *NLSF_Q15,                          /* O    NLSF vector      [ LPC_order ]              */\n    const silk_float                *pAR,                               /* I    LPC coefficients [ LPC_order ]              */\n    const opus_int                  LPC_order                           /* I    LPC order                                   */\n);\n\n/* Convert NLSF parameters to AR prediction filter coefficients */\nvoid silk_NLSF2A_FLP(\n    silk_float                      *pAR,                               /* O    LPC coefficients [ LPC_order ]              */\n    const opus_int16                *NLSF_Q15,                          /* I    NLSF vector      [ LPC_order ]              */\n    const opus_int                  LPC_order                           /* I    LPC order                                   */\n);\n\n/* Limit, stabilize, and quantize NLSFs */\nvoid silk_process_NLSFs_FLP(\n    silk_encoder_state              *psEncC,                            /* I/O  Encoder state                               */\n    silk_float                      PredCoef[ 2 ][ MAX_LPC_ORDER ],     /* O    Prediction coefficients                     */\n    opus_int16                      NLSF_Q15[      MAX_LPC_ORDER ],     /* I/O  Normalized LSFs (quant out) (0 - (2^15-1))  */\n    const opus_int16                prev_NLSF_Q15[ MAX_LPC_ORDER ]      /* I    Previous Normalized LSFs (0 - (2^15-1))     */\n);\n\n/* Floating-point Silk NSQ wrapper      */\nvoid silk_NSQ_wrapper_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    SideInfoIndices                 *psIndices,                         /* I/O  Quantization indices                        */\n    silk_nsq_state                  *psNSQ,                             /* I/O  Noise Shaping Quantzation state             */\n    opus_int8                       pulses[],                           /* O    Quantized pulse signal                      */\n    const silk_float                x[]                                 /* I    Prefiltered input signal                    */\n);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/noise_shape_analysis_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n#include \"tuning_parameters.h\"\n\n/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a   */\n/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */\n/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */\n/* coefficient in an array of coefficients, for monic filters.                                    */\nstatic OPUS_INLINE silk_float warped_gain(\n    const silk_float     *coefs,\n    silk_float           lambda,\n    opus_int             order\n) {\n    opus_int   i;\n    silk_float gain;\n\n    lambda = -lambda;\n    gain = coefs[ order - 1 ];\n    for( i = order - 2; i >= 0; i-- ) {\n        gain = lambda * gain + coefs[ i ];\n    }\n    return (silk_float)( 1.0f / ( 1.0f - lambda * gain ) );\n}\n\n/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum     */\n/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */\nstatic OPUS_INLINE void warped_true2monic_coefs(\n    silk_float           *coefs_syn,\n    silk_float           *coefs_ana,\n    silk_float           lambda,\n    silk_float           limit,\n    opus_int             order\n) {\n    opus_int   i, iter, ind = 0;\n    silk_float tmp, maxabs, chirp, gain_syn, gain_ana;\n\n    /* Convert to monic coefficients */\n    for( i = order - 1; i > 0; i-- ) {\n        coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ];\n        coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ];\n    }\n    gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] );\n    gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] );\n    for( i = 0; i < order; i++ ) {\n        coefs_syn[ i ] *= gain_syn;\n        coefs_ana[ i ] *= gain_ana;\n    }\n\n    /* Limit */\n    for( iter = 0; iter < 10; iter++ ) {\n        /* Find maximum absolute value */\n        maxabs = -1.0f;\n        for( i = 0; i < order; i++ ) {\n            tmp = silk_max( silk_abs_float( coefs_syn[ i ] ), silk_abs_float( coefs_ana[ i ] ) );\n            if( tmp > maxabs ) {\n                maxabs = tmp;\n                ind = i;\n            }\n        }\n        if( maxabs <= limit ) {\n            /* Coefficients are within range - done */\n            return;\n        }\n\n        /* Convert back to true warped coefficients */\n        for( i = 1; i < order; i++ ) {\n            coefs_syn[ i - 1 ] += lambda * coefs_syn[ i ];\n            coefs_ana[ i - 1 ] += lambda * coefs_ana[ i ];\n        }\n        gain_syn = 1.0f / gain_syn;\n        gain_ana = 1.0f / gain_ana;\n        for( i = 0; i < order; i++ ) {\n            coefs_syn[ i ] *= gain_syn;\n            coefs_ana[ i ] *= gain_ana;\n        }\n\n        /* Apply bandwidth expansion */\n        chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) );\n        silk_bwexpander_FLP( coefs_syn, order, chirp );\n        silk_bwexpander_FLP( coefs_ana, order, chirp );\n\n        /* Convert to monic warped coefficients */\n        for( i = order - 1; i > 0; i-- ) {\n            coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ];\n            coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ];\n        }\n        gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] );\n        gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] );\n        for( i = 0; i < order; i++ ) {\n            coefs_syn[ i ] *= gain_syn;\n            coefs_ana[ i ] *= gain_ana;\n        }\n    }\n    silk_assert( 0 );\n}\n\n/* Compute noise shaping coefficients and initial gain values */\nvoid silk_noise_shape_analysis_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    const silk_float                *pitch_res,                         /* I    LPC residual from pitch analysis            */\n    const silk_float                *x                                  /* I    Input signal [frame_length + la_shape]      */\n)\n{\n    silk_shape_state_FLP *psShapeSt = &psEnc->sShape;\n    opus_int     k, nSamples;\n    silk_float   SNR_adj_dB, HarmBoost, HarmShapeGain, Tilt;\n    silk_float   nrg, pre_nrg, log_energy, log_energy_prev, energy_variation;\n    silk_float   delta, BWExp1, BWExp2, gain_mult, gain_add, strength, b, warping;\n    silk_float   x_windowed[ SHAPE_LPC_WIN_MAX ];\n    silk_float   auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];\n    const silk_float *x_ptr, *pitch_res_ptr;\n\n    /* Point to start of first LPC analysis block */\n    x_ptr = x - psEnc->sCmn.la_shape;\n\n    /****************/\n    /* GAIN CONTROL */\n    /****************/\n    SNR_adj_dB = psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f );\n\n    /* Input quality is the average of the quality in the lowest two VAD bands */\n    psEncCtrl->input_quality = 0.5f * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ] ) * ( 1.0f / 32768.0f );\n\n    /* Coding quality level, between 0.0 and 1.0 */\n    psEncCtrl->coding_quality = silk_sigmoid( 0.25f * ( SNR_adj_dB - 20.0f ) );\n\n    if( psEnc->sCmn.useCBR == 0 ) {\n        /* Reduce coding SNR during low speech activity */\n        b = 1.0f - psEnc->sCmn.speech_activity_Q8 * ( 1.0f /  256.0f );\n        SNR_adj_dB -= BG_SNR_DECR_dB * psEncCtrl->coding_quality * ( 0.5f + 0.5f * psEncCtrl->input_quality ) * b * b;\n    }\n\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /* Reduce gains for periodic signals */\n        SNR_adj_dB += HARM_SNR_INCR_dB * psEnc->LTPCorr;\n    } else {\n        /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */\n        SNR_adj_dB += ( -0.4f * psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) + 6.0f ) * ( 1.0f - psEncCtrl->input_quality );\n    }\n\n    /*************************/\n    /* SPARSENESS PROCESSING */\n    /*************************/\n    /* Set quantizer offset */\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /* Initially set to 0; may be overruled in process_gains(..) */\n        psEnc->sCmn.indices.quantOffsetType = 0;\n        psEncCtrl->sparseness = 0.0f;\n    } else {\n        /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */\n        nSamples = 2 * psEnc->sCmn.fs_kHz;\n        energy_variation = 0.0f;\n        log_energy_prev  = 0.0f;\n        pitch_res_ptr = pitch_res;\n        for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {\n            nrg = ( silk_float )nSamples + ( silk_float )silk_energy_FLP( pitch_res_ptr, nSamples );\n            log_energy = silk_log2( nrg );\n            if( k > 0 ) {\n                energy_variation += silk_abs_float( log_energy - log_energy_prev );\n            }\n            log_energy_prev = log_energy;\n            pitch_res_ptr += nSamples;\n        }\n        psEncCtrl->sparseness = silk_sigmoid( 0.4f * ( energy_variation - 5.0f ) );\n\n        /* Set quantization offset depending on sparseness measure */\n        if( psEncCtrl->sparseness > SPARSENESS_THRESHOLD_QNT_OFFSET ) {\n            psEnc->sCmn.indices.quantOffsetType = 0;\n        } else {\n            psEnc->sCmn.indices.quantOffsetType = 1;\n        }\n\n        /* Increase coding SNR for sparse signals */\n        SNR_adj_dB += SPARSE_SNR_INCR_dB * ( psEncCtrl->sparseness - 0.5f );\n    }\n\n    /*******************************/\n    /* Control bandwidth expansion */\n    /*******************************/\n    /* More BWE for signals with high prediction gain */\n    strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain;           /* between 0.0 and 1.0 */\n    BWExp1 = BWExp2 = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength );\n    delta  = LOW_RATE_BANDWIDTH_EXPANSION_DELTA * ( 1.0f - 0.75f * psEncCtrl->coding_quality );\n    BWExp1 -= delta;\n    BWExp2 += delta;\n    /* BWExp1 will be applied after BWExp2, so make it relative */\n    BWExp1 /= BWExp2;\n\n    if( psEnc->sCmn.warping_Q16 > 0 ) {\n        /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */\n        warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality;\n    } else {\n        warping = 0.0f;\n    }\n\n    /********************************************/\n    /* Compute noise shaping AR coefs and gains */\n    /********************************************/\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        /* Apply window: sine slope followed by flat part followed by cosine slope */\n        opus_int shift, slope_part, flat_part;\n        flat_part = psEnc->sCmn.fs_kHz * 3;\n        slope_part = ( psEnc->sCmn.shapeWinLength - flat_part ) / 2;\n\n        silk_apply_sine_window_FLP( x_windowed, x_ptr, 1, slope_part );\n        shift = slope_part;\n        silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(silk_float) );\n        shift += flat_part;\n        silk_apply_sine_window_FLP( x_windowed + shift, x_ptr + shift, 2, slope_part );\n\n        /* Update pointer: next LPC analysis block */\n        x_ptr += psEnc->sCmn.subfr_length;\n\n        if( psEnc->sCmn.warping_Q16 > 0 ) {\n            /* Calculate warped auto correlation */\n            silk_warped_autocorrelation_FLP( auto_corr, x_windowed, warping,\n                psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );\n        } else {\n            /* Calculate regular auto correlation */\n            silk_autocorrelation_FLP( auto_corr, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 );\n        }\n\n        /* Add white noise, as a fraction of energy */\n        auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION;\n\n        /* Convert correlations to prediction coefficients, and compute residual energy */\n        nrg = silk_levinsondurbin_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], auto_corr, psEnc->sCmn.shapingLPCOrder );\n        psEncCtrl->Gains[ k ] = ( silk_float )sqrt( nrg );\n\n        if( psEnc->sCmn.warping_Q16 > 0 ) {\n            /* Adjust gain for warping */\n            psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder );\n        }\n\n        /* Bandwidth expansion for synthesis filter shaping */\n        silk_bwexpander_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp2 );\n\n        /* Compute noise shaping filter coefficients */\n        silk_memcpy(\n            &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ],\n            &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ],\n            psEnc->sCmn.shapingLPCOrder * sizeof( silk_float ) );\n\n        /* Bandwidth expansion for analysis filter shaping */\n        silk_bwexpander_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp1 );\n\n        /* Ratio of prediction gains, in energy domain */\n        pre_nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );\n        nrg     = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );\n        psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg );\n\n        /* Convert to monic warped prediction coefficients and limit absolute values */\n        warped_true2monic_coefs( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ],\n            warping, 3.999f, psEnc->sCmn.shapingLPCOrder );\n    }\n\n    /*****************/\n    /* Gain tweaking */\n    /*****************/\n    /* Increase gains during low speech activity */\n    gain_mult = (silk_float)pow( 2.0f, -0.16f * SNR_adj_dB );\n    gain_add  = (silk_float)pow( 2.0f,  0.16f * MIN_QGAIN_DB );\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        psEncCtrl->Gains[ k ] *= gain_mult;\n        psEncCtrl->Gains[ k ] += gain_add;\n    }\n\n    gain_mult = 1.0f + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT;\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        psEncCtrl->GainsPre[ k ] *= gain_mult;\n    }\n\n    /************************************************/\n    /* Control low-frequency shaping and noise tilt */\n    /************************************************/\n    /* Less low frequency shaping for noisy inputs */\n    strength = LOW_FREQ_SHAPING * ( 1.0f + LOW_QUALITY_LOW_FREQ_SHAPING_DECR * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] * ( 1.0f / 32768.0f ) - 1.0f ) );\n    strength *= psEnc->sCmn.speech_activity_Q8 * ( 1.0f /  256.0f );\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */\n        /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/\n        for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n            b = 0.2f / psEnc->sCmn.fs_kHz + 3.0f / psEncCtrl->pitchL[ k ];\n            psEncCtrl->LF_MA_shp[ k ] = -1.0f + b;\n            psEncCtrl->LF_AR_shp[ k ] =  1.0f - b - b * strength;\n        }\n        Tilt = - HP_NOISE_COEF -\n            (1 - HP_NOISE_COEF) * HARM_HP_NOISE_COEF * psEnc->sCmn.speech_activity_Q8 * ( 1.0f /  256.0f );\n    } else {\n        b = 1.3f / psEnc->sCmn.fs_kHz;\n        psEncCtrl->LF_MA_shp[ 0 ] = -1.0f + b;\n        psEncCtrl->LF_AR_shp[ 0 ] =  1.0f - b - b * strength * 0.6f;\n        for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {\n            psEncCtrl->LF_MA_shp[ k ] = psEncCtrl->LF_MA_shp[ 0 ];\n            psEncCtrl->LF_AR_shp[ k ] = psEncCtrl->LF_AR_shp[ 0 ];\n        }\n        Tilt = -HP_NOISE_COEF;\n    }\n\n    /****************************/\n    /* HARMONIC SHAPING CONTROL */\n    /****************************/\n    /* Control boosting of harmonic frequencies */\n    HarmBoost = LOW_RATE_HARMONIC_BOOST * ( 1.0f - psEncCtrl->coding_quality ) * psEnc->LTPCorr;\n\n    /* More harmonic boost for noisy input signals */\n    HarmBoost += LOW_INPUT_QUALITY_HARMONIC_BOOST * ( 1.0f - psEncCtrl->input_quality );\n\n    if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        /* Harmonic noise shaping */\n        HarmShapeGain = HARMONIC_SHAPING;\n\n        /* More harmonic noise shaping for high bitrates or noisy input */\n        HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING *\n            ( 1.0f - ( 1.0f - psEncCtrl->coding_quality ) * psEncCtrl->input_quality );\n\n        /* Less harmonic noise shaping for less periodic signals */\n        HarmShapeGain *= ( silk_float )sqrt( psEnc->LTPCorr );\n    } else {\n        HarmShapeGain = 0.0f;\n    }\n\n    /*************************/\n    /* Smooth over subframes */\n    /*************************/\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        psShapeSt->HarmBoost_smth     += SUBFR_SMTH_COEF * ( HarmBoost - psShapeSt->HarmBoost_smth );\n        psEncCtrl->HarmBoost[ k ]      = psShapeSt->HarmBoost_smth;\n        psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth );\n        psEncCtrl->HarmShapeGain[ k ]  = psShapeSt->HarmShapeGain_smth;\n        psShapeSt->Tilt_smth          += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth );\n        psEncCtrl->Tilt[ k ]           = psShapeSt->Tilt_smth;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/pitch_analysis_core_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/*****************************************************************************\n* Pitch analyser function\n******************************************************************************/\n#include \"SigProc_FLP.h\"\n#include \"SigProc_FIX.h\"\n#include \"pitch_est_defines.h\"\n#include \"pitch.h\"\n\n#define SCRATCH_SIZE        22\n\n/************************************************************/\n/* Internally used functions                                */\n/************************************************************/\nstatic void silk_P_Ana_calc_corr_st3(\n    silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */\n    const silk_float    frame[],            /* I vector to correlate                                            */\n    opus_int            start_lag,          /* I start lag                                                      */\n    opus_int            sf_length,          /* I sub frame length                                               */\n    opus_int            nb_subfr,           /* I number of subframes                                            */\n    opus_int            complexity,         /* I Complexity setting                                             */\n    int                 arch                /* I Run-time architecture                                          */\n);\n\nstatic void silk_P_Ana_calc_energy_st3(\n    silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */\n    const silk_float    frame[],            /* I vector to correlate                                            */\n    opus_int            start_lag,          /* I start lag                                                      */\n    opus_int            sf_length,          /* I sub frame length                                               */\n    opus_int            nb_subfr,           /* I number of subframes                                            */\n    opus_int            complexity          /* I Complexity setting                                             */\n);\n\n/************************************************************/\n/* CORE PITCH ANALYSIS FUNCTION                             */\n/************************************************************/\nopus_int silk_pitch_analysis_core_FLP(      /* O    Voicing estimate: 0 voiced, 1 unvoiced                      */\n    const silk_float    *frame,             /* I    Signal of length PE_FRAME_LENGTH_MS*Fs_kHz                  */\n    opus_int            *pitch_out,         /* O    Pitch lag values [nb_subfr]                                 */\n    opus_int16          *lagIndex,          /* O    Lag Index                                                   */\n    opus_int8           *contourIndex,      /* O    Pitch contour Index                                         */\n    silk_float          *LTPCorr,           /* I/O  Normalized correlation; input: value from previous frame    */\n    opus_int            prevLag,            /* I    Last lag of previous frame; set to zero is unvoiced         */\n    const silk_float    search_thres1,      /* I    First stage threshold for lag candidates 0 - 1              */\n    const silk_float    search_thres2,      /* I    Final threshold for lag candidates 0 - 1                    */\n    const opus_int      Fs_kHz,             /* I    sample frequency (kHz)                                      */\n    const opus_int      complexity,         /* I    Complexity setting, 0-2, where 2 is highest                 */\n    const opus_int      nb_subfr,           /* I    Number of 5 ms subframes                                    */\n    int                 arch                /* I    Run-time architecture                                       */\n)\n{\n    opus_int   i, k, d, j;\n    silk_float frame_8kHz[  PE_MAX_FRAME_LENGTH_MS * 8 ];\n    silk_float frame_4kHz[  PE_MAX_FRAME_LENGTH_MS * 4 ];\n    opus_int16 frame_8_FIX[ PE_MAX_FRAME_LENGTH_MS * 8 ];\n    opus_int16 frame_4_FIX[ PE_MAX_FRAME_LENGTH_MS * 4 ];\n    opus_int32 filt_state[ 6 ];\n    silk_float threshold, contour_bias;\n    silk_float C[ PE_MAX_NB_SUBFR][ (PE_MAX_LAG >> 1) + 5 ];\n    opus_val32 xcorr[ PE_MAX_LAG_MS * 4 - PE_MIN_LAG_MS * 4 + 1 ];\n    silk_float CC[ PE_NB_CBKS_STAGE2_EXT ];\n    const silk_float *target_ptr, *basis_ptr;\n    double    cross_corr, normalizer, energy, energy_tmp;\n    opus_int   d_srch[ PE_D_SRCH_LENGTH ];\n    opus_int16 d_comp[ (PE_MAX_LAG >> 1) + 5 ];\n    opus_int   length_d_srch, length_d_comp;\n    silk_float Cmax, CCmax, CCmax_b, CCmax_new_b, CCmax_new;\n    opus_int   CBimax, CBimax_new, lag, start_lag, end_lag, lag_new;\n    opus_int   cbk_size;\n    silk_float lag_log2, prevLag_log2, delta_lag_log2_sqr;\n    silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];\n    silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];\n    opus_int   lag_counter;\n    opus_int   frame_length, frame_length_8kHz, frame_length_4kHz;\n    opus_int   sf_length, sf_length_8kHz, sf_length_4kHz;\n    opus_int   min_lag, min_lag_8kHz, min_lag_4kHz;\n    opus_int   max_lag, max_lag_8kHz, max_lag_4kHz;\n    opus_int   nb_cbk_search;\n    const opus_int8 *Lag_CB_ptr;\n\n    /* Check for valid sampling frequency */\n    silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );\n\n    /* Check for valid complexity setting */\n    silk_assert( complexity >= SILK_PE_MIN_COMPLEX );\n    silk_assert( complexity <= SILK_PE_MAX_COMPLEX );\n\n    silk_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f );\n    silk_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f );\n\n    /* Set up frame lengths max / min lag for the sampling frequency */\n    frame_length      = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;\n    frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;\n    frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;\n    sf_length         = PE_SUBFR_LENGTH_MS * Fs_kHz;\n    sf_length_4kHz    = PE_SUBFR_LENGTH_MS * 4;\n    sf_length_8kHz    = PE_SUBFR_LENGTH_MS * 8;\n    min_lag           = PE_MIN_LAG_MS * Fs_kHz;\n    min_lag_4kHz      = PE_MIN_LAG_MS * 4;\n    min_lag_8kHz      = PE_MIN_LAG_MS * 8;\n    max_lag           = PE_MAX_LAG_MS * Fs_kHz - 1;\n    max_lag_4kHz      = PE_MAX_LAG_MS * 4;\n    max_lag_8kHz      = PE_MAX_LAG_MS * 8 - 1;\n\n    /* Resample from input sampled at Fs_kHz to 8 kHz */\n    if( Fs_kHz == 16 ) {\n        /* Resample to 16 -> 8 khz */\n        opus_int16 frame_16_FIX[ 16 * PE_MAX_FRAME_LENGTH_MS ];\n        silk_float2short_array( frame_16_FIX, frame, frame_length );\n        silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );\n        silk_resampler_down2( filt_state, frame_8_FIX, frame_16_FIX, frame_length );\n        silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz );\n    } else if( Fs_kHz == 12 ) {\n        /* Resample to 12 -> 8 khz */\n        opus_int16 frame_12_FIX[ 12 * PE_MAX_FRAME_LENGTH_MS ];\n        silk_float2short_array( frame_12_FIX, frame, frame_length );\n        silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );\n        silk_resampler_down2_3( filt_state, frame_8_FIX, frame_12_FIX, frame_length );\n        silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz );\n    } else {\n        silk_assert( Fs_kHz == 8 );\n        silk_float2short_array( frame_8_FIX, frame, frame_length_8kHz );\n    }\n\n    /* Decimate again to 4 kHz */\n    silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );\n    silk_resampler_down2( filt_state, frame_4_FIX, frame_8_FIX, frame_length_8kHz );\n    silk_short2float_array( frame_4kHz, frame_4_FIX, frame_length_4kHz );\n\n    /* Low-pass filter */\n    for( i = frame_length_4kHz - 1; i > 0; i-- ) {\n        frame_4kHz[ i ] += frame_4kHz[ i - 1 ];\n    }\n\n    /******************************************************************************\n    * FIRST STAGE, operating in 4 khz\n    ******************************************************************************/\n    silk_memset(C, 0, sizeof(silk_float) * nb_subfr * ((PE_MAX_LAG >> 1) + 5));\n    target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ];\n    for( k = 0; k < nb_subfr >> 1; k++ ) {\n        /* Check that we are within range of the array */\n        silk_assert( target_ptr >= frame_4kHz );\n        silk_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );\n\n        basis_ptr = target_ptr - min_lag_4kHz;\n\n        /* Check that we are within range of the array */\n        silk_assert( basis_ptr >= frame_4kHz );\n        silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );\n\n        celt_pitch_xcorr( target_ptr, target_ptr-max_lag_4kHz, xcorr, sf_length_8kHz, max_lag_4kHz - min_lag_4kHz + 1, arch );\n\n        /* Calculate first vector products before loop */\n        cross_corr = xcorr[ max_lag_4kHz - min_lag_4kHz ];\n        normalizer = silk_energy_FLP( target_ptr, sf_length_8kHz ) +\n                     silk_energy_FLP( basis_ptr,  sf_length_8kHz ) +\n                     sf_length_8kHz * 4000.0f;\n\n        C[ 0 ][ min_lag_4kHz ] += (silk_float)( 2 * cross_corr / normalizer );\n\n        /* From now on normalizer is computed recursively */\n        for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) {\n            basis_ptr--;\n\n            /* Check that we are within range of the array */\n            silk_assert( basis_ptr >= frame_4kHz );\n            silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );\n\n            cross_corr = xcorr[ max_lag_4kHz - d ];\n\n            /* Add contribution of new sample and remove contribution from oldest sample */\n            normalizer +=\n                basis_ptr[ 0 ] * (double)basis_ptr[ 0 ] -\n                basis_ptr[ sf_length_8kHz ] * (double)basis_ptr[ sf_length_8kHz ];\n            C[ 0 ][ d ] += (silk_float)( 2 * cross_corr / normalizer );\n        }\n        /* Update target pointer */\n        target_ptr += sf_length_8kHz;\n    }\n\n    /* Apply short-lag bias */\n    for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) {\n        C[ 0 ][ i ] -= C[ 0 ][ i ] * i / 4096.0f;\n    }\n\n    /* Sort */\n    length_d_srch = 4 + 2 * complexity;\n    silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );\n    silk_insertion_sort_decreasing_FLP( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch );\n\n    /* Escape if correlation is very low already here */\n    Cmax = C[ 0 ][ min_lag_4kHz ];\n    if( Cmax < 0.2f ) {\n        silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );\n        *LTPCorr      = 0.0f;\n        *lagIndex     = 0;\n        *contourIndex = 0;\n        return 1;\n    }\n\n    threshold = search_thres1 * Cmax;\n    for( i = 0; i < length_d_srch; i++ ) {\n        /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */\n        if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) {\n            d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 );\n        } else {\n            length_d_srch = i;\n            break;\n        }\n    }\n    silk_assert( length_d_srch > 0 );\n\n    for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) {\n        d_comp[ i ] = 0;\n    }\n    for( i = 0; i < length_d_srch; i++ ) {\n        d_comp[ d_srch[ i ] ] = 1;\n    }\n\n    /* Convolution */\n    for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {\n        d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ];\n    }\n\n    length_d_srch = 0;\n    for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) {\n        if( d_comp[ i + 1 ] > 0 ) {\n            d_srch[ length_d_srch ] = i;\n            length_d_srch++;\n        }\n    }\n\n    /* Convolution */\n    for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {\n        d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ];\n    }\n\n    length_d_comp = 0;\n    for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) {\n        if( d_comp[ i ] > 0 ) {\n            d_comp[ length_d_comp ] = (opus_int16)( i - 2 );\n            length_d_comp++;\n        }\n    }\n\n    /**********************************************************************************\n    ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation\n    *************************************************************************************/\n    /*********************************************************************************\n    * Find energy of each subframe projected onto its history, for a range of delays\n    *********************************************************************************/\n    silk_memset( C, 0, PE_MAX_NB_SUBFR*((PE_MAX_LAG >> 1) + 5) * sizeof(silk_float));\n\n    if( Fs_kHz == 8 ) {\n        target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * 8 ];\n    } else {\n        target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ];\n    }\n    for( k = 0; k < nb_subfr; k++ ) {\n        energy_tmp = silk_energy_FLP( target_ptr, sf_length_8kHz ) + 1.0;\n        for( j = 0; j < length_d_comp; j++ ) {\n            d = d_comp[ j ];\n            basis_ptr = target_ptr - d;\n            cross_corr = silk_inner_product_FLP( basis_ptr, target_ptr, sf_length_8kHz );\n            if( cross_corr > 0.0f ) {\n                energy = silk_energy_FLP( basis_ptr, sf_length_8kHz );\n                C[ k ][ d ] = (silk_float)( 2 * cross_corr / ( energy + energy_tmp ) );\n            } else {\n                C[ k ][ d ] = 0.0f;\n            }\n        }\n        target_ptr += sf_length_8kHz;\n    }\n\n    /* search over lag range and lags codebook */\n    /* scale factor for lag codebook, as a function of center lag */\n\n    CCmax   = 0.0f; /* This value doesn't matter */\n    CCmax_b = -1000.0f;\n\n    CBimax = 0; /* To avoid returning undefined lag values */\n    lag = -1;   /* To check if lag with strong enough correlation has been found */\n\n    if( prevLag > 0 ) {\n        if( Fs_kHz == 12 ) {\n            prevLag = silk_LSHIFT( prevLag, 1 ) / 3;\n        } else if( Fs_kHz == 16 ) {\n            prevLag = silk_RSHIFT( prevLag, 1 );\n        }\n        prevLag_log2 = silk_log2( (silk_float)prevLag );\n    } else {\n        prevLag_log2 = 0;\n    }\n\n    /* Set up stage 2 codebook based on number of subframes */\n    if( nb_subfr == PE_MAX_NB_SUBFR ) {\n        cbk_size   = PE_NB_CBKS_STAGE2_EXT;\n        Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];\n        if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) {\n            /* If input is 8 khz use a larger codebook here because it is last stage */\n            nb_cbk_search = PE_NB_CBKS_STAGE2_EXT;\n        } else {\n            nb_cbk_search = PE_NB_CBKS_STAGE2;\n        }\n    } else {\n        cbk_size       = PE_NB_CBKS_STAGE2_10MS;\n        Lag_CB_ptr     = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];\n        nb_cbk_search  = PE_NB_CBKS_STAGE2_10MS;\n    }\n\n    for( k = 0; k < length_d_srch; k++ ) {\n        d = d_srch[ k ];\n        for( j = 0; j < nb_cbk_search; j++ ) {\n            CC[j] = 0.0f;\n            for( i = 0; i < nb_subfr; i++ ) {\n                /* Try all codebooks */\n                CC[ j ] += C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size )];\n            }\n        }\n        /* Find best codebook */\n        CCmax_new  = -1000.0f;\n        CBimax_new = 0;\n        for( i = 0; i < nb_cbk_search; i++ ) {\n            if( CC[ i ] > CCmax_new ) {\n                CCmax_new = CC[ i ];\n                CBimax_new = i;\n            }\n        }\n\n        /* Bias towards shorter lags */\n        lag_log2 = silk_log2( (silk_float)d );\n        CCmax_new_b = CCmax_new - PE_SHORTLAG_BIAS * nb_subfr * lag_log2;\n\n        /* Bias towards previous lag */\n        if( prevLag > 0 ) {\n            delta_lag_log2_sqr = lag_log2 - prevLag_log2;\n            delta_lag_log2_sqr *= delta_lag_log2_sqr;\n            CCmax_new_b -= PE_PREVLAG_BIAS * nb_subfr * (*LTPCorr) * delta_lag_log2_sqr / ( delta_lag_log2_sqr + 0.5f );\n        }\n\n        if( CCmax_new_b > CCmax_b &&                /* Find maximum biased correlation                  */\n            CCmax_new > nb_subfr * search_thres2    /* Correlation needs to be high enough to be voiced */\n        ) {\n            CCmax_b = CCmax_new_b;\n            CCmax   = CCmax_new;\n            lag     = d;\n            CBimax  = CBimax_new;\n        }\n    }\n\n    if( lag == -1 ) {\n        /* No suitable candidate found */\n        silk_memset( pitch_out, 0, PE_MAX_NB_SUBFR * sizeof(opus_int) );\n        *LTPCorr      = 0.0f;\n        *lagIndex     = 0;\n        *contourIndex = 0;\n        return 1;\n    }\n\n    /* Output normalized correlation */\n    *LTPCorr = (silk_float)( CCmax / nb_subfr );\n    silk_assert( *LTPCorr >= 0.0f );\n\n    if( Fs_kHz > 8 ) {\n        /* Search in original signal */\n\n        /* Compensate for decimation */\n        silk_assert( lag == silk_SAT16( lag ) );\n        if( Fs_kHz == 12 ) {\n            lag = silk_RSHIFT_ROUND( silk_SMULBB( lag, 3 ), 1 );\n        } else { /* Fs_kHz == 16 */\n            lag = silk_LSHIFT( lag, 1 );\n        }\n\n        lag = silk_LIMIT_int( lag, min_lag, max_lag );\n        start_lag = silk_max_int( lag - 2, min_lag );\n        end_lag   = silk_min_int( lag + 2, max_lag );\n        lag_new   = lag;                                    /* to avoid undefined lag */\n        CBimax    = 0;                                      /* to avoid undefined lag */\n\n        CCmax = -1000.0f;\n\n        /* Calculate the correlations and energies needed in stage 3 */\n        silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );\n        silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity );\n\n        lag_counter = 0;\n        silk_assert( lag == silk_SAT16( lag ) );\n        contour_bias = PE_FLATCONTOUR_BIAS / lag;\n\n        /* Set up cbk parameters according to complexity setting and frame length */\n        if( nb_subfr == PE_MAX_NB_SUBFR ) {\n            nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];\n            cbk_size      = PE_NB_CBKS_STAGE3_MAX;\n            Lag_CB_ptr    = &silk_CB_lags_stage3[ 0 ][ 0 ];\n        } else {\n            nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;\n            cbk_size      = PE_NB_CBKS_STAGE3_10MS;\n            Lag_CB_ptr    = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];\n        }\n\n        target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];\n        energy_tmp = silk_energy_FLP( target_ptr, nb_subfr * sf_length ) + 1.0;\n        for( d = start_lag; d <= end_lag; d++ ) {\n            for( j = 0; j < nb_cbk_search; j++ ) {\n                cross_corr = 0.0;\n                energy = energy_tmp;\n                for( k = 0; k < nb_subfr; k++ ) {\n                    cross_corr += cross_corr_st3[ k ][ j ][ lag_counter ];\n                    energy     +=   energies_st3[ k ][ j ][ lag_counter ];\n                }\n                if( cross_corr > 0.0 ) {\n                    CCmax_new = (silk_float)( 2 * cross_corr / energy );\n                    /* Reduce depending on flatness of contour */\n                    CCmax_new *= 1.0f - contour_bias * j;\n                } else {\n                    CCmax_new = 0.0f;\n                }\n\n                if( CCmax_new > CCmax && ( d + (opus_int)silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) {\n                    CCmax   = CCmax_new;\n                    lag_new = d;\n                    CBimax  = j;\n                }\n            }\n            lag_counter++;\n        }\n\n        for( k = 0; k < nb_subfr; k++ ) {\n            pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );\n            pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz );\n        }\n        *lagIndex = (opus_int16)( lag_new - min_lag );\n        *contourIndex = (opus_int8)CBimax;\n    } else {        /* Fs_kHz == 8 */\n        /* Save Lags */\n        for( k = 0; k < nb_subfr; k++ ) {\n            pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );\n            pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * 8 );\n        }\n        *lagIndex = (opus_int16)( lag - min_lag_8kHz );\n        *contourIndex = (opus_int8)CBimax;\n    }\n    silk_assert( *lagIndex >= 0 );\n    /* return as voiced */\n    return 0;\n}\n\n/***********************************************************************\n * Calculates the correlations used in stage 3 search. In order to cover\n * the whole lag codebook for all the searched offset lags (lag +- 2),\n * the following correlations are needed in each sub frame:\n *\n * sf1: lag range [-8,...,7] total 16 correlations\n * sf2: lag range [-4,...,4] total 9 correlations\n * sf3: lag range [-3,....4] total 8 correltions\n * sf4: lag range [-6,....8] total 15 correlations\n *\n * In total 48 correlations. The direct implementation computed in worst\n * case 4*12*5 = 240 correlations, but more likely around 120.\n ***********************************************************************/\nstatic void silk_P_Ana_calc_corr_st3(\n    silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */\n    const silk_float    frame[],            /* I vector to correlate                                            */\n    opus_int            start_lag,          /* I start lag                                                      */\n    opus_int            sf_length,          /* I sub frame length                                               */\n    opus_int            nb_subfr,           /* I number of subframes                                            */\n    opus_int            complexity,         /* I Complexity setting                                             */\n    int                 arch                /* I Run-time architecture                                          */\n)\n{\n    const silk_float *target_ptr;\n    opus_int   i, j, k, lag_counter, lag_low, lag_high;\n    opus_int   nb_cbk_search, delta, idx, cbk_size;\n    silk_float scratch_mem[ SCRATCH_SIZE ];\n    opus_val32 xcorr[ SCRATCH_SIZE ];\n    const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;\n\n    silk_assert( complexity >= SILK_PE_MIN_COMPLEX );\n    silk_assert( complexity <= SILK_PE_MAX_COMPLEX );\n\n    if( nb_subfr == PE_MAX_NB_SUBFR ) {\n        Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];\n        Lag_CB_ptr    = &silk_CB_lags_stage3[ 0 ][ 0 ];\n        nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];\n        cbk_size      = PE_NB_CBKS_STAGE3_MAX;\n    } else {\n        silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);\n        Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];\n        Lag_CB_ptr    = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];\n        nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;\n        cbk_size      = PE_NB_CBKS_STAGE3_10MS;\n    }\n\n    target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */\n    for( k = 0; k < nb_subfr; k++ ) {\n        lag_counter = 0;\n\n        /* Calculate the correlations for each subframe */\n        lag_low  = matrix_ptr( Lag_range_ptr, k, 0, 2 );\n        lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 );\n        silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);\n        celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr, sf_length, lag_high - lag_low + 1, arch );\n        for( j = lag_low; j <= lag_high; j++ ) {\n            silk_assert( lag_counter < SCRATCH_SIZE );\n            scratch_mem[ lag_counter ] = xcorr[ lag_high - j ];\n            lag_counter++;\n        }\n\n        delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );\n        for( i = 0; i < nb_cbk_search; i++ ) {\n            /* Fill out the 3 dim array that stores the correlations for */\n            /* each code_book vector for each start lag */\n            idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;\n            for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {\n                silk_assert( idx + j < SCRATCH_SIZE );\n                silk_assert( idx + j < lag_counter );\n                cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];\n            }\n        }\n        target_ptr += sf_length;\n    }\n}\n\n/********************************************************************/\n/* Calculate the energies for first two subframes. The energies are */\n/* calculated recursively.                                          */\n/********************************************************************/\nstatic void silk_P_Ana_calc_energy_st3(\n    silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */\n    const silk_float    frame[],            /* I vector to correlate                                            */\n    opus_int            start_lag,          /* I start lag                                                      */\n    opus_int            sf_length,          /* I sub frame length                                               */\n    opus_int            nb_subfr,           /* I number of subframes                                            */\n    opus_int            complexity          /* I Complexity setting                                             */\n)\n{\n    const silk_float *target_ptr, *basis_ptr;\n    double    energy;\n    opus_int   k, i, j, lag_counter;\n    opus_int   nb_cbk_search, delta, idx, cbk_size, lag_diff;\n    silk_float scratch_mem[ SCRATCH_SIZE ];\n    const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;\n\n    silk_assert( complexity >= SILK_PE_MIN_COMPLEX );\n    silk_assert( complexity <= SILK_PE_MAX_COMPLEX );\n\n    if( nb_subfr == PE_MAX_NB_SUBFR ) {\n        Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];\n        Lag_CB_ptr    = &silk_CB_lags_stage3[ 0 ][ 0 ];\n        nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];\n        cbk_size      = PE_NB_CBKS_STAGE3_MAX;\n    } else {\n        silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);\n        Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];\n        Lag_CB_ptr    = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];\n        nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;\n        cbk_size      = PE_NB_CBKS_STAGE3_10MS;\n    }\n\n    target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ];\n    for( k = 0; k < nb_subfr; k++ ) {\n        lag_counter = 0;\n\n        /* Calculate the energy for first lag */\n        basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) );\n        energy = silk_energy_FLP( basis_ptr, sf_length ) + 1e-3;\n        silk_assert( energy >= 0.0 );\n        scratch_mem[lag_counter] = (silk_float)energy;\n        lag_counter++;\n\n        lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) -  matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 );\n        for( i = 1; i < lag_diff; i++ ) {\n            /* remove part outside new window */\n            energy -= basis_ptr[sf_length - i] * (double)basis_ptr[sf_length - i];\n            silk_assert( energy >= 0.0 );\n\n            /* add part that comes into window */\n            energy += basis_ptr[ -i ] * (double)basis_ptr[ -i ];\n            silk_assert( energy >= 0.0 );\n            silk_assert( lag_counter < SCRATCH_SIZE );\n            scratch_mem[lag_counter] = (silk_float)energy;\n            lag_counter++;\n        }\n\n        delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );\n        for( i = 0; i < nb_cbk_search; i++ ) {\n            /* Fill out the 3 dim array that stores the correlations for    */\n            /* each code_book vector for each start lag                     */\n            idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;\n            for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {\n                silk_assert( idx + j < SCRATCH_SIZE );\n                silk_assert( idx + j < lag_counter );\n                energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];\n                silk_assert( energies_st3[ k ][ i ][ j ] >= 0.0f );\n            }\n        }\n        target_ptr += sf_length;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/prefilter_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n#include \"tuning_parameters.h\"\n\n/*\n* Prefilter for finding Quantizer input signal\n*/\nstatic OPUS_INLINE void silk_prefilt_FLP(\n    silk_prefilter_state_FLP    *P,                 /* I/O state */\n    silk_float                  st_res[],           /* I */\n    silk_float                  xw[],               /* O */\n    silk_float                  *HarmShapeFIR,      /* I */\n    silk_float                  Tilt,               /* I */\n    silk_float                  LF_MA_shp,          /* I */\n    silk_float                  LF_AR_shp,          /* I */\n    opus_int                    lag,                /* I */\n    opus_int                    length              /* I */\n);\n\nstatic void silk_warped_LPC_analysis_filter_FLP(\n          silk_float                 state[],            /* I/O  State [order + 1]                       */\n          silk_float                 res[],              /* O    Residual signal [length]                */\n    const silk_float                 coef[],             /* I    Coefficients [order]                    */\n    const silk_float                 input[],            /* I    Input signal [length]                   */\n    const silk_float                 lambda,             /* I    Warping factor                          */\n    const opus_int                   length,             /* I    Length of input signal                  */\n    const opus_int                   order               /* I    Filter order (even)                     */\n)\n{\n    opus_int     n, i;\n    silk_float   acc, tmp1, tmp2;\n\n    /* Order must be even */\n    silk_assert( ( order & 1 ) == 0 );\n\n    for( n = 0; n < length; n++ ) {\n        /* Output of lowpass section */\n        tmp2 = state[ 0 ] + lambda * state[ 1 ];\n        state[ 0 ] = input[ n ];\n        /* Output of allpass section */\n        tmp1 = state[ 1 ] + lambda * ( state[ 2 ] - tmp2 );\n        state[ 1 ] = tmp2;\n        acc = coef[ 0 ] * tmp2;\n        /* Loop over allpass sections */\n        for( i = 2; i < order; i += 2 ) {\n            /* Output of allpass section */\n            tmp2 = state[ i ] + lambda * ( state[ i + 1 ] - tmp1 );\n            state[ i ] = tmp1;\n            acc += coef[ i - 1 ] * tmp1;\n            /* Output of allpass section */\n            tmp1 = state[ i + 1 ] + lambda * ( state[ i + 2 ] - tmp2 );\n            state[ i + 1 ] = tmp2;\n            acc += coef[ i ] * tmp2;\n        }\n        state[ order ] = tmp1;\n        acc += coef[ order - 1 ] * tmp1;\n        res[ n ] = input[ n ] - acc;\n    }\n}\n\n/*\n* silk_prefilter. Main prefilter function\n*/\nvoid silk_prefilter_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    const silk_encoder_control_FLP  *psEncCtrl,                         /* I    Encoder control FLP                         */\n    silk_float                      xw[],                               /* O    Weighted signal                             */\n    const silk_float                x[]                                 /* I    Speech signal                               */\n)\n{\n    silk_prefilter_state_FLP *P = &psEnc->sPrefilt;\n    opus_int   j, k, lag;\n    silk_float HarmShapeGain, Tilt, LF_MA_shp, LF_AR_shp;\n    silk_float B[ 2 ];\n    const silk_float *AR1_shp;\n    const silk_float *px;\n    silk_float *pxw;\n    silk_float HarmShapeFIR[ 3 ];\n    silk_float st_res[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ];\n\n    /* Set up pointers */\n    px  = x;\n    pxw = xw;\n    lag = P->lagPrev;\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        /* Update Variables that change per sub frame */\n        if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n            lag = psEncCtrl->pitchL[ k ];\n        }\n\n        /* Noise shape parameters */\n        HarmShapeGain = psEncCtrl->HarmShapeGain[ k ] * ( 1.0f - psEncCtrl->HarmBoost[ k ] );\n        HarmShapeFIR[ 0 ] = 0.25f               * HarmShapeGain;\n        HarmShapeFIR[ 1 ] = 32767.0f / 65536.0f * HarmShapeGain;\n        HarmShapeFIR[ 2 ] = 0.25f               * HarmShapeGain;\n        Tilt      =  psEncCtrl->Tilt[ k ];\n        LF_MA_shp =  psEncCtrl->LF_MA_shp[ k ];\n        LF_AR_shp =  psEncCtrl->LF_AR_shp[ k ];\n        AR1_shp   = &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ];\n\n        /* Short term FIR filtering */\n        silk_warped_LPC_analysis_filter_FLP( P->sAR_shp, st_res, AR1_shp, px,\n            (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder );\n\n        /* Reduce (mainly) low frequencies during harmonic emphasis */\n        B[ 0 ] =  psEncCtrl->GainsPre[ k ];\n        B[ 1 ] = -psEncCtrl->GainsPre[ k ] *\n            ( psEncCtrl->HarmBoost[ k ] * HarmShapeGain + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT );\n        pxw[ 0 ] = B[ 0 ] * st_res[ 0 ] + B[ 1 ] * P->sHarmHP;\n        for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {\n            pxw[ j ] = B[ 0 ] * st_res[ j ] + B[ 1 ] * st_res[ j - 1 ];\n        }\n        P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ];\n\n        silk_prefilt_FLP( P, pxw, pxw, HarmShapeFIR, Tilt, LF_MA_shp, LF_AR_shp, lag, psEnc->sCmn.subfr_length );\n\n        px  += psEnc->sCmn.subfr_length;\n        pxw += psEnc->sCmn.subfr_length;\n    }\n    P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ];\n}\n\n/*\n* Prefilter for finding Quantizer input signal\n*/\nstatic OPUS_INLINE void silk_prefilt_FLP(\n    silk_prefilter_state_FLP    *P,                 /* I/O state */\n    silk_float                  st_res[],           /* I */\n    silk_float                  xw[],               /* O */\n    silk_float                  *HarmShapeFIR,      /* I */\n    silk_float                  Tilt,               /* I */\n    silk_float                  LF_MA_shp,          /* I */\n    silk_float                  LF_AR_shp,          /* I */\n    opus_int                    lag,                /* I */\n    opus_int                    length              /* I */\n)\n{\n    opus_int   i;\n    opus_int   idx, LTP_shp_buf_idx;\n    silk_float n_Tilt, n_LF, n_LTP;\n    silk_float sLF_AR_shp, sLF_MA_shp;\n    silk_float *LTP_shp_buf;\n\n    /* To speed up use temp variables instead of using the struct */\n    LTP_shp_buf     = P->sLTP_shp;\n    LTP_shp_buf_idx = P->sLTP_shp_buf_idx;\n    sLF_AR_shp      = P->sLF_AR_shp;\n    sLF_MA_shp      = P->sLF_MA_shp;\n\n    for( i = 0; i < length; i++ ) {\n        if( lag > 0 ) {\n            silk_assert( HARM_SHAPE_FIR_TAPS == 3 );\n            idx = lag + LTP_shp_buf_idx;\n            n_LTP  = LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ] * HarmShapeFIR[ 0 ];\n            n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2    ) & LTP_MASK ] * HarmShapeFIR[ 1 ];\n            n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ] * HarmShapeFIR[ 2 ];\n        } else {\n            n_LTP = 0;\n        }\n\n        n_Tilt = sLF_AR_shp * Tilt;\n        n_LF   = sLF_AR_shp * LF_AR_shp + sLF_MA_shp * LF_MA_shp;\n\n        sLF_AR_shp = st_res[ i ] - n_Tilt;\n        sLF_MA_shp = sLF_AR_shp - n_LF;\n\n        LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;\n        LTP_shp_buf[ LTP_shp_buf_idx ] = sLF_MA_shp;\n\n        xw[ i ] = sLF_MA_shp - n_LTP;\n    }\n    /* Copy temp variable back to state */\n    P->sLF_AR_shp       = sLF_AR_shp;\n    P->sLF_MA_shp       = sLF_MA_shp;\n    P->sLTP_shp_buf_idx = LTP_shp_buf_idx;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/process_gains_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n#include \"tuning_parameters.h\"\n\n/* Processing of gains */\nvoid silk_process_gains_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    opus_int                        condCoding                          /* I    The type of conditional coding to use       */\n)\n{\n    silk_shape_state_FLP *psShapeSt = &psEnc->sShape;\n    opus_int     k;\n    opus_int32   pGains_Q16[ MAX_NB_SUBFR ];\n    silk_float   s, InvMaxSqrVal, gain, quant_offset;\n\n    /* Gain reduction when LTP coding gain is high */\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        s = 1.0f - 0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) );\n        for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n            psEncCtrl->Gains[ k ] *= s;\n        }\n    }\n\n    /* Limit the quantized signal */\n    InvMaxSqrVal = ( silk_float )( pow( 2.0f, 0.33f * ( 21.0f - psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) ) ) / psEnc->sCmn.subfr_length );\n\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        /* Soft limit on ratio residual energy and squared gains */\n        gain = psEncCtrl->Gains[ k ];\n        gain = ( silk_float )sqrt( gain * gain + psEncCtrl->ResNrg[ k ] * InvMaxSqrVal );\n        psEncCtrl->Gains[ k ] = silk_min_float( gain, 32767.0f );\n    }\n\n    /* Prepare gains for noise shaping quantization */\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        pGains_Q16[ k ] = (opus_int32)( psEncCtrl->Gains[ k ] * 65536.0f );\n    }\n\n    /* Save unquantized gains and gain Index */\n    silk_memcpy( psEncCtrl->GainsUnq_Q16, pGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );\n    psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex;\n\n    /* Quantize gains */\n    silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16,\n            &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );\n\n    /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */\n    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\n        psEncCtrl->Gains[ k ] = pGains_Q16[ k ] / 65536.0f;\n    }\n\n    /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */\n    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\n        if( psEncCtrl->LTPredCodGain + psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ) > 1.0f ) {\n            psEnc->sCmn.indices.quantOffsetType = 0;\n        } else {\n            psEnc->sCmn.indices.quantOffsetType = 1;\n        }\n    }\n\n    /* Quantizer boundary adjustment */\n    quant_offset = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ] / 1024.0f;\n    psEncCtrl->Lambda = LAMBDA_OFFSET\n                      + LAMBDA_DELAYED_DECISIONS * psEnc->sCmn.nStatesDelayedDecision\n                      + LAMBDA_SPEECH_ACT        * psEnc->sCmn.speech_activity_Q8 * ( 1.0f /  256.0f )\n                      + LAMBDA_INPUT_QUALITY     * psEncCtrl->input_quality\n                      + LAMBDA_CODING_QUALITY    * psEncCtrl->coding_quality\n                      + LAMBDA_QUANT_OFFSET      * quant_offset;\n\n    silk_assert( psEncCtrl->Lambda > 0.0f );\n    silk_assert( psEncCtrl->Lambda < 2.0f );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/regularize_correlations_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n\n/* Add noise to matrix diagonal */\nvoid silk_regularize_correlations_FLP(\n    silk_float                      *XX,                                /* I/O  Correlation matrices                        */\n    silk_float                      *xx,                                /* I/O  Correlation values                          */\n    const silk_float                noise,                              /* I    Noise energy to add                         */\n    const opus_int                  D                                   /* I    Dimension of XX                             */\n)\n{\n    opus_int i;\n\n    for( i = 0; i < D; i++ ) {\n        matrix_ptr( &XX[ 0 ], i, i, D ) += noise;\n    }\n    xx[ 0 ] += noise;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/residual_energy_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n\n#define MAX_ITERATIONS_RESIDUAL_NRG         10\n#define REGULARIZATION_FACTOR               1e-8f\n\n/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */\nsilk_float silk_residual_energy_covar_FLP(                              /* O    Weighted residual energy                    */\n    const silk_float                *c,                                 /* I    Filter coefficients                         */\n    silk_float                      *wXX,                               /* I/O  Weighted correlation matrix, reg. out       */\n    const silk_float                *wXx,                               /* I    Weighted correlation vector                 */\n    const silk_float                wxx,                                /* I    Weighted correlation value                  */\n    const opus_int                  D                                   /* I    Dimension                                   */\n)\n{\n    opus_int   i, j, k;\n    silk_float tmp, nrg = 0.0f, regularization;\n\n    /* Safety checks */\n    silk_assert( D >= 0 );\n\n    regularization = REGULARIZATION_FACTOR * ( wXX[ 0 ] + wXX[ D * D - 1 ] );\n    for( k = 0; k < MAX_ITERATIONS_RESIDUAL_NRG; k++ ) {\n        nrg = wxx;\n\n        tmp = 0.0f;\n        for( i = 0; i < D; i++ ) {\n            tmp += wXx[ i ] * c[ i ];\n        }\n        nrg -= 2.0f * tmp;\n\n        /* compute c' * wXX * c, assuming wXX is symmetric */\n        for( i = 0; i < D; i++ ) {\n            tmp = 0.0f;\n            for( j = i + 1; j < D; j++ ) {\n                tmp += matrix_c_ptr( wXX, i, j, D ) * c[ j ];\n            }\n            nrg += c[ i ] * ( 2.0f * tmp + matrix_c_ptr( wXX, i, i, D ) * c[ i ] );\n        }\n        if( nrg > 0 ) {\n            break;\n        } else {\n            /* Add white noise */\n            for( i = 0; i < D; i++ ) {\n                matrix_c_ptr( wXX, i, i, D ) +=  regularization;\n            }\n            /* Increase noise for next run */\n            regularization *= 2.0f;\n        }\n    }\n    if( k == MAX_ITERATIONS_RESIDUAL_NRG ) {\n        silk_assert( nrg == 0 );\n        nrg = 1.0f;\n    }\n\n    return nrg;\n}\n\n/* Calculates residual energies of input subframes where all subframes have LPC_order   */\n/* of preceding samples                                                                 */\nvoid silk_residual_energy_FLP(\n    silk_float                      nrgs[ MAX_NB_SUBFR ],               /* O    Residual energy per subframe                */\n    const silk_float                x[],                                /* I    Input signal                                */\n    silk_float                      a[ 2 ][ MAX_LPC_ORDER ],            /* I    AR coefs for each frame half                */\n    const silk_float                gains[],                            /* I    Quantization gains                          */\n    const opus_int                  subfr_length,                       /* I    Subframe length                             */\n    const opus_int                  nb_subfr,                           /* I    number of subframes                         */\n    const opus_int                  LPC_order                           /* I    LPC order                                   */\n)\n{\n    opus_int     shift;\n    silk_float   *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ];\n\n    LPC_res_ptr = LPC_res + LPC_order;\n    shift = LPC_order + subfr_length;\n\n    /* Filter input to create the LPC residual for each frame half, and measure subframe energies */\n    silk_LPC_analysis_filter_FLP( LPC_res, a[ 0 ], x + 0 * shift, 2 * shift, LPC_order );\n    nrgs[ 0 ] = ( silk_float )( gains[ 0 ] * gains[ 0 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) );\n    nrgs[ 1 ] = ( silk_float )( gains[ 1 ] * gains[ 1 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) );\n\n    if( nb_subfr == MAX_NB_SUBFR ) {\n        silk_LPC_analysis_filter_FLP( LPC_res, a[ 1 ], x + 2 * shift, 2 * shift, LPC_order );\n        nrgs[ 2 ] = ( silk_float )( gains[ 2 ] * gains[ 2 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) );\n        nrgs[ 3 ] = ( silk_float )( gains[ 3 ] * gains[ 3 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/scale_copy_vector_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FLP.h\"\n\n/* copy and multiply a vector by a constant */\nvoid silk_scale_copy_vector_FLP(\n    silk_float          *data_out,\n    const silk_float    *data_in,\n    silk_float          gain,\n    opus_int            dataSize\n)\n{\n    opus_int  i, dataSize4;\n\n    /* 4x unrolled loop */\n    dataSize4 = dataSize & 0xFFFC;\n    for( i = 0; i < dataSize4; i += 4 ) {\n        data_out[ i + 0 ] = gain * data_in[ i + 0 ];\n        data_out[ i + 1 ] = gain * data_in[ i + 1 ];\n        data_out[ i + 2 ] = gain * data_in[ i + 2 ];\n        data_out[ i + 3 ] = gain * data_in[ i + 3 ];\n    }\n\n    /* any remaining elements */\n    for( ; i < dataSize; i++ ) {\n        data_out[ i ] = gain * data_in[ i ];\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/scale_vector_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FLP.h\"\n\n/* multiply a vector by a constant */\nvoid silk_scale_vector_FLP(\n    silk_float          *data1,\n    silk_float          gain,\n    opus_int            dataSize\n)\n{\n    opus_int  i, dataSize4;\n\n    /* 4x unrolled loop */\n    dataSize4 = dataSize & 0xFFFC;\n    for( i = 0; i < dataSize4; i += 4 ) {\n        data1[ i + 0 ] *= gain;\n        data1[ i + 1 ] *= gain;\n        data1[ i + 2 ] *= gain;\n        data1[ i + 3 ] *= gain;\n    }\n\n    /* any remaining elements */\n    for( ; i < dataSize; i++ ) {\n        data1[ i ] *= gain;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/schur_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FLP.h\"\n\nsilk_float silk_schur_FLP(                  /* O    returns residual energy                                     */\n    silk_float          refl_coef[],        /* O    reflection coefficients (length order)                      */\n    const silk_float    auto_corr[],        /* I    autocorrelation sequence (length order+1)                   */\n    opus_int            order               /* I    order                                                       */\n)\n{\n    opus_int   k, n;\n    silk_float C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];\n    silk_float Ctmp1, Ctmp2, rc_tmp;\n\n    silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );\n\n    /* Copy correlations */\n    for( k = 0; k < order+1; k++ ) {\n        C[ k ][ 0 ] = C[ k ][ 1 ] = auto_corr[ k ];\n    }\n\n    for( k = 0; k < order; k++ ) {\n        /* Get reflection coefficient */\n        rc_tmp = -C[ k + 1 ][ 0 ] / silk_max_float( C[ 0 ][ 1 ], 1e-9f );\n\n        /* Save the output */\n        refl_coef[ k ] = rc_tmp;\n\n        /* Update correlations */\n        for( n = 0; n < order - k; n++ ) {\n            Ctmp1 = C[ n + k + 1 ][ 0 ];\n            Ctmp2 = C[ n ][ 1 ];\n            C[ n + k + 1 ][ 0 ] = Ctmp1 + Ctmp2 * rc_tmp;\n            C[ n ][ 1 ]         = Ctmp2 + Ctmp1 * rc_tmp;\n        }\n    }\n\n    /* Return residual energy */\n    return C[ 0 ][ 1 ];\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/solve_LS_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n#include \"tuning_parameters.h\"\n\n/**********************************************************************\n * LDL Factorisation. Finds the upper triangular matrix L and the diagonal\n * Matrix D (only the diagonal elements returned in a vector)such that\n * the symmetric matric A is given by A = L*D*L'.\n **********************************************************************/\nstatic OPUS_INLINE void silk_LDL_FLP(\n    silk_float          *A,         /* I/O  Pointer to Symetric Square Matrix                               */\n    opus_int            M,          /* I    Size of Matrix                                                  */\n    silk_float          *L,         /* I/O  Pointer to Square Upper triangular Matrix                       */\n    silk_float          *Dinv       /* I/O  Pointer to vector holding the inverse diagonal elements of D    */\n);\n\n/**********************************************************************\n * Function to solve linear equation Ax = b, when A is a MxM lower\n * triangular matrix, with ones on the diagonal.\n **********************************************************************/\nstatic OPUS_INLINE void silk_SolveWithLowerTriangularWdiagOnes_FLP(\n    const silk_float    *L,         /* I    Pointer to Lower Triangular Matrix                              */\n    opus_int            M,          /* I    Dim of Matrix equation                                          */\n    const silk_float    *b,         /* I    b Vector                                                        */\n    silk_float          *x          /* O    x Vector                                                        */\n);\n\n/**********************************************************************\n * Function to solve linear equation (A^T)x = b, when A is a MxM lower\n * triangular, with ones on the diagonal. (ie then A^T is upper triangular)\n **********************************************************************/\nstatic OPUS_INLINE void silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP(\n    const silk_float    *L,         /* I    Pointer to Lower Triangular Matrix                              */\n    opus_int            M,          /* I    Dim of Matrix equation                                          */\n    const silk_float    *b,         /* I    b Vector                                                        */\n    silk_float          *x          /* O    x Vector                                                        */\n);\n\n/**********************************************************************\n * Function to solve linear equation Ax = b, when A is a MxM\n * symmetric square matrix - using LDL factorisation\n **********************************************************************/\nvoid silk_solve_LDL_FLP(\n    silk_float                      *A,                                 /* I/O  Symmetric square matrix, out: reg.          */\n    const opus_int                  M,                                  /* I    Size of matrix                              */\n    const silk_float                *b,                                 /* I    Pointer to b vector                         */\n    silk_float                      *x                                  /* O    Pointer to x solution vector                */\n)\n{\n    opus_int   i;\n    silk_float L[    MAX_MATRIX_SIZE ][ MAX_MATRIX_SIZE ];\n    silk_float T[    MAX_MATRIX_SIZE ];\n    silk_float Dinv[ MAX_MATRIX_SIZE ]; /* inverse diagonal elements of D*/\n\n    silk_assert( M <= MAX_MATRIX_SIZE );\n\n    /***************************************************\n    Factorize A by LDL such that A = L*D*(L^T),\n    where L is lower triangular with ones on diagonal\n    ****************************************************/\n    silk_LDL_FLP( A, M, &L[ 0 ][ 0 ], Dinv );\n\n    /****************************************************\n    * substitute D*(L^T) = T. ie:\n    L*D*(L^T)*x = b => L*T = b <=> T = inv(L)*b\n    ******************************************************/\n    silk_SolveWithLowerTriangularWdiagOnes_FLP( &L[ 0 ][ 0 ], M, b, T );\n\n    /****************************************************\n    D*(L^T)*x = T <=> (L^T)*x = inv(D)*T, because D is\n    diagonal just multiply with 1/d_i\n    ****************************************************/\n    for( i = 0; i < M; i++ ) {\n        T[ i ] = T[ i ] * Dinv[ i ];\n    }\n    /****************************************************\n    x = inv(L') * inv(D) * T\n    *****************************************************/\n    silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( &L[ 0 ][ 0 ], M, T, x );\n}\n\nstatic OPUS_INLINE void silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP(\n    const silk_float    *L,         /* I    Pointer to Lower Triangular Matrix                              */\n    opus_int            M,          /* I    Dim of Matrix equation                                          */\n    const silk_float    *b,         /* I    b Vector                                                        */\n    silk_float          *x          /* O    x Vector                                                        */\n)\n{\n    opus_int   i, j;\n    silk_float temp;\n    const silk_float *ptr1;\n\n    for( i = M - 1; i >= 0; i-- ) {\n        ptr1 =  matrix_adr( L, 0, i, M );\n        temp = 0;\n        for( j = M - 1; j > i ; j-- ) {\n            temp += ptr1[ j * M ] * x[ j ];\n        }\n        temp = b[ i ] - temp;\n        x[ i ] = temp;\n    }\n}\n\nstatic OPUS_INLINE void silk_SolveWithLowerTriangularWdiagOnes_FLP(\n    const silk_float    *L,         /* I    Pointer to Lower Triangular Matrix                              */\n    opus_int            M,          /* I    Dim of Matrix equation                                          */\n    const silk_float    *b,         /* I    b Vector                                                        */\n    silk_float          *x          /* O    x Vector                                                        */\n)\n{\n    opus_int   i, j;\n    silk_float temp;\n    const silk_float *ptr1;\n\n    for( i = 0; i < M; i++ ) {\n        ptr1 =  matrix_adr( L, i, 0, M );\n        temp = 0;\n        for( j = 0; j < i; j++ ) {\n            temp += ptr1[ j ] * x[ j ];\n        }\n        temp = b[ i ] - temp;\n        x[ i ] = temp;\n    }\n}\n\nstatic OPUS_INLINE void silk_LDL_FLP(\n    silk_float          *A,         /* I/O  Pointer to Symetric Square Matrix                               */\n    opus_int            M,          /* I    Size of Matrix                                                  */\n    silk_float          *L,         /* I/O  Pointer to Square Upper triangular Matrix                       */\n    silk_float          *Dinv       /* I/O  Pointer to vector holding the inverse diagonal elements of D    */\n)\n{\n    opus_int i, j, k, loop_count, err = 1;\n    silk_float *ptr1, *ptr2;\n    double temp, diag_min_value;\n    silk_float v[ MAX_MATRIX_SIZE ], D[ MAX_MATRIX_SIZE ]; /* temp arrays*/\n\n    silk_assert( M <= MAX_MATRIX_SIZE );\n\n    diag_min_value = FIND_LTP_COND_FAC * 0.5f * ( A[ 0 ] + A[ M * M - 1 ] );\n    for( loop_count = 0; loop_count < M && err == 1; loop_count++ ) {\n        err = 0;\n        for( j = 0; j < M; j++ ) {\n            ptr1 = matrix_adr( L, j, 0, M );\n            temp = matrix_ptr( A, j, j, M ); /* element in row j column j*/\n            for( i = 0; i < j; i++ ) {\n                v[ i ] = ptr1[ i ] * D[ i ];\n                temp  -= ptr1[ i ] * v[ i ];\n            }\n            if( temp < diag_min_value ) {\n                /* Badly conditioned matrix: add white noise and run again */\n                temp = ( loop_count + 1 ) * diag_min_value - temp;\n                for( i = 0; i < M; i++ ) {\n                    matrix_ptr( A, i, i, M ) += ( silk_float )temp;\n                }\n                err = 1;\n                break;\n            }\n            D[ j ]    = ( silk_float )temp;\n            Dinv[ j ] = ( silk_float )( 1.0f / temp );\n            matrix_ptr( L, j, j, M ) = 1.0f;\n\n            ptr1 = matrix_adr( A, j, 0, M );\n            ptr2 = matrix_adr( L, j + 1, 0, M);\n            for( i = j + 1; i < M; i++ ) {\n                temp = 0.0;\n                for( k = 0; k < j; k++ ) {\n                    temp += ptr2[ k ] * v[ k ];\n                }\n                matrix_ptr( L, i, j, M ) = ( silk_float )( ( ptr1[ i ] - temp ) * Dinv[ j ] );\n                ptr2 += M; /* go to next column*/\n            }\n        }\n    }\n    silk_assert( err == 0 );\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/sort_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* Insertion sort (fast for already almost sorted arrays):  */\n/* Best case:  O(n)   for an already sorted array           */\n/* Worst case: O(n^2) for an inversely sorted array         */\n\n#include \"typedef.h\"\n#include \"SigProc_FLP.h\"\n\nvoid silk_insertion_sort_decreasing_FLP(\n    silk_float          *a,                 /* I/O  Unsorted / Sorted vector                                    */\n    opus_int            *idx,               /* O    Index vector for the sorted elements                        */\n    const opus_int      L,                  /* I    Vector length                                               */\n    const opus_int      K                   /* I    Number of correctly sorted positions                        */\n)\n{\n    silk_float value;\n    opus_int   i, j;\n\n    /* Safety checks */\n    silk_assert( K >  0 );\n    silk_assert( L >  0 );\n    silk_assert( L >= K );\n\n    /* Write start indices in index vector */\n    for( i = 0; i < K; i++ ) {\n        idx[ i ] = i;\n    }\n\n    /* Sort vector elements by value, decreasing order */\n    for( i = 1; i < K; i++ ) {\n        value = a[ i ];\n        for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) {\n            a[ j + 1 ]   = a[ j ];      /* Shift value */\n            idx[ j + 1 ] = idx[ j ];    /* Shift index */\n        }\n        a[ j + 1 ]   = value;   /* Write value */\n        idx[ j + 1 ] = i;       /* Write index */\n    }\n\n    /* If less than L values are asked check the remaining values,      */\n    /* but only spend CPU to ensure that the K first values are correct */\n    for( i = K; i < L; i++ ) {\n        value = a[ i ];\n        if( value > a[ K - 1 ] ) {\n            for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) {\n                a[ j + 1 ]   = a[ j ];      /* Shift value */\n                idx[ j + 1 ] = idx[ j ];    /* Shift index */\n            }\n            a[ j + 1 ]   = value;   /* Write value */\n            idx[ j + 1 ] = i;       /* Write index */\n        }\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/structs_FLP.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_STRUCTS_FLP_H\n#define SILK_STRUCTS_FLP_H\n\n#include \"typedef.h\"\n#include \"main.h\"\n#include \"structs.h\"\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/********************************/\n/* Noise shaping analysis state */\n/********************************/\ntypedef struct {\n    opus_int8                   LastGainIndex;\n    silk_float                  HarmBoost_smth;\n    silk_float                  HarmShapeGain_smth;\n    silk_float                  Tilt_smth;\n} silk_shape_state_FLP;\n\n/********************************/\n/* Prefilter state              */\n/********************************/\ntypedef struct {\n    silk_float                  sLTP_shp[ LTP_BUF_LENGTH ];\n    silk_float                  sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ];\n    opus_int                    sLTP_shp_buf_idx;\n    silk_float                  sLF_AR_shp;\n    silk_float                  sLF_MA_shp;\n    silk_float                  sHarmHP;\n    opus_int32                  rand_seed;\n    opus_int                    lagPrev;\n} silk_prefilter_state_FLP;\n\n/********************************/\n/* Encoder state FLP            */\n/********************************/\ntypedef struct {\n    silk_encoder_state          sCmn;                               /* Common struct, shared with fixed-point code */\n    silk_shape_state_FLP        sShape;                             /* Noise shaping state */\n    silk_prefilter_state_FLP    sPrefilt;                           /* Prefilter State */\n\n    /* Buffer for find pitch and noise shape analysis */\n    silk_float                  x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */\n    silk_float                  LTPCorr;                            /* Normalized correlation from pitch lag estimator */\n} silk_encoder_state_FLP;\n\n/************************/\n/* Encoder control FLP  */\n/************************/\ntypedef struct {\n    /* Prediction and coding parameters */\n    silk_float                  Gains[ MAX_NB_SUBFR ];\n    silk_float                  PredCoef[ 2 ][ MAX_LPC_ORDER ];     /* holds interpolated and final coefficients */\n    silk_float                  LTPCoef[LTP_ORDER * MAX_NB_SUBFR];\n    silk_float                  LTP_scale;\n    opus_int                    pitchL[ MAX_NB_SUBFR ];\n\n    /* Noise shaping parameters */\n    silk_float                  AR1[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];\n    silk_float                  AR2[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];\n    silk_float                  LF_MA_shp[     MAX_NB_SUBFR ];\n    silk_float                  LF_AR_shp[     MAX_NB_SUBFR ];\n    silk_float                  GainsPre[      MAX_NB_SUBFR ];\n    silk_float                  HarmBoost[     MAX_NB_SUBFR ];\n    silk_float                  Tilt[          MAX_NB_SUBFR ];\n    silk_float                  HarmShapeGain[ MAX_NB_SUBFR ];\n    silk_float                  Lambda;\n    silk_float                  input_quality;\n    silk_float                  coding_quality;\n\n    /* Measures */\n    silk_float                  sparseness;\n    silk_float                  predGain;\n    silk_float                  LTPredCodGain;\n    silk_float                  ResNrg[ MAX_NB_SUBFR ];             /* Residual energy per subframe */\n\n    /* Parameters for CBR mode */\n    opus_int32                  GainsUnq_Q16[ MAX_NB_SUBFR ];\n    opus_int8                   lastGainIndexPrev;\n} silk_encoder_control_FLP;\n\n/************************/\n/* Encoder Super Struct */\n/************************/\ntypedef struct {\n    silk_encoder_state_FLP      state_Fxx[ ENCODER_NUM_CHANNELS ];\n    stereo_enc_state            sStereo;\n    opus_int32                  nBitsUsedLBRR;\n    opus_int32                  nBitsExceeded;\n    opus_int                    nChannelsAPI;\n    opus_int                    nChannelsInternal;\n    opus_int                    nPrevChannelsInternal;\n    opus_int                    timeSinceSwitchAllowed_ms;\n    opus_int                    allowBandwidthSwitch;\n    opus_int                    prev_decode_only_middle;\n} silk_encoder;\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/warped_autocorrelation_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n\n/* Autocorrelations for a warped frequency axis */\nvoid silk_warped_autocorrelation_FLP(\n    silk_float                      *corr,                              /* O    Result [order + 1]                          */\n    const silk_float                *input,                             /* I    Input data to correlate                     */\n    const silk_float                warping,                            /* I    Warping coefficient                         */\n    const opus_int                  length,                             /* I    Length of input                             */\n    const opus_int                  order                               /* I    Correlation order (even)                    */\n)\n{\n    opus_int    n, i;\n    double      tmp1, tmp2;\n    double      state[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };\n    double      C[     MAX_SHAPE_LPC_ORDER + 1 ] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };\n\n    /* Order must be even */\n    silk_assert( ( order & 1 ) == 0 );\n\n    /* Loop over samples */\n    for( n = 0; n < length; n++ ) {\n        tmp1 = input[ n ];\n        /* Loop over allpass sections */\n        for( i = 0; i < order; i += 2 ) {\n            /* Output of allpass section */\n            tmp2 = state[ i ] + warping * ( state[ i + 1 ] - tmp1 );\n            state[ i ] = tmp1;\n            C[ i ] += state[ 0 ] * tmp1;\n            /* Output of allpass section */\n            tmp1 = state[ i + 1 ] + warping * ( state[ i + 2 ] - tmp2 );\n            state[ i + 1 ] = tmp2;\n            C[ i + 1 ] += state[ 0 ] * tmp2;\n        }\n        state[ order ] = tmp1;\n        C[ order ] += state[ 0 ] * tmp1;\n    }\n\n    /* Copy correlations in silk_float output format */\n    for( i = 0; i < order + 1; i++ ) {\n        corr[ i ] = ( silk_float )C[ i ];\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/float/wrappers_FLP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main_FLP.h\"\n\n/* Wrappers. Calls flp / fix code */\n\n/* Convert AR filter coefficients to NLSF parameters */\nvoid silk_A2NLSF_FLP(\n    opus_int16                      *NLSF_Q15,                          /* O    NLSF vector      [ LPC_order ]              */\n    const silk_float                *pAR,                               /* I    LPC coefficients [ LPC_order ]              */\n    const opus_int                  LPC_order                           /* I    LPC order                                   */\n)\n{\n    opus_int   i;\n    opus_int32 a_fix_Q16[ MAX_LPC_ORDER ];\n\n    for( i = 0; i < LPC_order; i++ ) {\n        a_fix_Q16[ i ] = silk_float2int( pAR[ i ] * 65536.0f );\n    }\n\n    silk_A2NLSF( NLSF_Q15, a_fix_Q16, LPC_order );\n}\n\n/* Convert LSF parameters to AR prediction filter coefficients */\nvoid silk_NLSF2A_FLP(\n    silk_float                      *pAR,                               /* O    LPC coefficients [ LPC_order ]              */\n    const opus_int16                *NLSF_Q15,                          /* I    NLSF vector      [ LPC_order ]              */\n    const opus_int                  LPC_order                           /* I    LPC order                                   */\n)\n{\n    opus_int   i;\n    opus_int16 a_fix_Q12[ MAX_LPC_ORDER ];\n\n    silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order );\n\n    for( i = 0; i < LPC_order; i++ ) {\n        pAR[ i ] = ( silk_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f );\n    }\n}\n\n/******************************************/\n/* Floating-point NLSF processing wrapper */\n/******************************************/\nvoid silk_process_NLSFs_FLP(\n    silk_encoder_state              *psEncC,                            /* I/O  Encoder state                               */\n    silk_float                      PredCoef[ 2 ][ MAX_LPC_ORDER ],     /* O    Prediction coefficients                     */\n    opus_int16                      NLSF_Q15[      MAX_LPC_ORDER ],     /* I/O  Normalized LSFs (quant out) (0 - (2^15-1))  */\n    const opus_int16                prev_NLSF_Q15[ MAX_LPC_ORDER ]      /* I    Previous Normalized LSFs (0 - (2^15-1))     */\n)\n{\n    opus_int     i, j;\n    opus_int16   PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];\n\n    silk_process_NLSFs( psEncC, PredCoef_Q12, NLSF_Q15, prev_NLSF_Q15);\n\n    for( j = 0; j < 2; j++ ) {\n        for( i = 0; i < psEncC->predictLPCOrder; i++ ) {\n            PredCoef[ j ][ i ] = ( silk_float )PredCoef_Q12[ j ][ i ] * ( 1.0f / 4096.0f );\n        }\n    }\n}\n\n/****************************************/\n/* Floating-point Silk NSQ wrapper      */\n/****************************************/\nvoid silk_NSQ_wrapper_FLP(\n    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */\n    silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */\n    SideInfoIndices                 *psIndices,                         /* I/O  Quantization indices                        */\n    silk_nsq_state                  *psNSQ,                             /* I/O  Noise Shaping Quantzation state             */\n    opus_int8                       pulses[],                           /* O    Quantized pulse signal                      */\n    const silk_float                x[]                                 /* I    Prefiltered input signal                    */\n)\n{\n    opus_int     i, j;\n    opus_int32   x_Q3[ MAX_FRAME_LENGTH ];\n    opus_int32   Gains_Q16[ MAX_NB_SUBFR ];\n    silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];\n    opus_int16   LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];\n    opus_int     LTP_scale_Q14;\n\n    /* Noise shaping parameters */\n    opus_int16   AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];\n    opus_int32   LF_shp_Q14[ MAX_NB_SUBFR ];         /* Packs two int16 coefficients per int32 value             */\n    opus_int     Lambda_Q10;\n    opus_int     Tilt_Q14[ MAX_NB_SUBFR ];\n    opus_int     HarmShapeGain_Q14[ MAX_NB_SUBFR ];\n\n    /* Convert control struct to fix control struct */\n    /* Noise shape parameters */\n    for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\n        for( j = 0; j < psEnc->sCmn.shapingLPCOrder; j++ ) {\n            AR2_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR2[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f );\n        }\n    }\n\n    for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\n        LF_shp_Q14[ i ] =   silk_LSHIFT32( silk_float2int( psEncCtrl->LF_AR_shp[ i ]     * 16384.0f ), 16 ) |\n                              (opus_uint16)silk_float2int( psEncCtrl->LF_MA_shp[ i ]     * 16384.0f );\n        Tilt_Q14[ i ]   =        (opus_int)silk_float2int( psEncCtrl->Tilt[ i ]          * 16384.0f );\n        HarmShapeGain_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->HarmShapeGain[ i ] * 16384.0f );\n    }\n    Lambda_Q10 = ( opus_int )silk_float2int( psEncCtrl->Lambda * 1024.0f );\n\n    /* prediction and coding parameters */\n    for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {\n        LTPCoef_Q14[ i ] = (opus_int16)silk_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f );\n    }\n\n    for( j = 0; j < 2; j++ ) {\n        for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) {\n            PredCoef_Q12[ j ][ i ] = (opus_int16)silk_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f );\n        }\n    }\n\n    for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\n        Gains_Q16[ i ] = silk_float2int( psEncCtrl->Gains[ i ] * 65536.0f );\n        silk_assert( Gains_Q16[ i ] > 0 );\n    }\n\n    if( psIndices->signalType == TYPE_VOICED ) {\n        LTP_scale_Q14 = silk_LTPScales_table_Q14[ psIndices->LTP_scaleIndex ];\n    } else {\n        LTP_scale_Q14 = 0;\n    }\n\n    /* Convert input to fix */\n    for( i = 0; i < psEnc->sCmn.frame_length; i++ ) {\n        x_Q3[ i ] = silk_float2int( 8.0f * x[ i ] );\n    }\n\n    /* Call NSQ */\n    if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {\n        silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,\n            AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );\n    } else {\n        silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,\n            AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );\n    }\n}\n\n/***********************************************/\n/* Floating-point Silk LTP quantiation wrapper */\n/***********************************************/\nvoid silk_quant_LTP_gains_FLP(\n    silk_float                      B[ MAX_NB_SUBFR * LTP_ORDER ],      /* I/O  (Un-)quantized LTP gains                    */\n    opus_int8                       cbk_index[ MAX_NB_SUBFR ],          /* O    Codebook index                              */\n    opus_int8                       *periodicity_index,                 /* O    Periodicity index                           */\n    opus_int32                      *sum_log_gain_Q7,                   /* I/O  Cumulative max prediction gain  */\n    const silk_float                W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I    Error weights                        */\n    const opus_int                  mu_Q10,                             /* I    Mu value (R/D tradeoff)                     */\n    const opus_int                  lowComplexity,                      /* I    Flag for low complexity                     */\n    const opus_int                  nb_subfr,                           /* I    number of subframes                         */\n    int                             arch                                /* I    Run-time architecture                       */\n)\n{\n    opus_int   i;\n    opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ];\n    opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ];\n\n    for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {\n        B_Q14[ i ] = (opus_int16)silk_float2int( B[ i ] * 16384.0f );\n    }\n    for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) {\n        W_Q18[ i ] = (opus_int32)silk_float2int( W[ i ] * 262144.0f );\n    }\n\n    silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, W_Q18, mu_Q10, lowComplexity, nb_subfr, arch );\n\n    for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {\n        B[ i ] = (silk_float)B_Q14[ i ] * ( 1.0f / 16384.0f );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/gain_quant.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n#define OFFSET                  ( ( MIN_QGAIN_DB * 128 ) / 6 + 16 * 128 )\n#define SCALE_Q16               ( ( 65536 * ( N_LEVELS_QGAIN - 1 ) ) / ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) )\n#define INV_SCALE_Q16           ( ( 65536 * ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( N_LEVELS_QGAIN - 1 ) )\n\n/* Gain scalar quantization with hysteresis, uniform on log scale */\nvoid silk_gains_quant(\n    opus_int8                   ind[ MAX_NB_SUBFR ],            /* O    gain indices                                */\n    opus_int32                  gain_Q16[ MAX_NB_SUBFR ],       /* I/O  gains (quantized out)                       */\n    opus_int8                   *prev_ind,                      /* I/O  last index in previous frame                */\n    const opus_int              conditional,                    /* I    first gain is delta coded if 1              */\n    const opus_int              nb_subfr                        /* I    number of subframes                         */\n)\n{\n    opus_int k, double_step_size_threshold;\n\n    for( k = 0; k < nb_subfr; k++ ) {\n        /* Convert to log scale, scale, floor() */\n        ind[ k ] = silk_SMULWB( SCALE_Q16, silk_lin2log( gain_Q16[ k ] ) - OFFSET );\n\n        /* Round towards previous quantized gain (hysteresis) */\n        if( ind[ k ] < *prev_ind ) {\n            ind[ k ]++;\n        }\n        ind[ k ] = silk_LIMIT_int( ind[ k ], 0, N_LEVELS_QGAIN - 1 );\n\n        /* Compute delta indices and limit */\n        if( k == 0 && conditional == 0 ) {\n            /* Full index */\n            ind[ k ] = silk_LIMIT_int( ind[ k ], *prev_ind + MIN_DELTA_GAIN_QUANT, N_LEVELS_QGAIN - 1 );\n            *prev_ind = ind[ k ];\n        } else {\n            /* Delta index */\n            ind[ k ] = ind[ k ] - *prev_ind;\n\n            /* Double the quantization step size for large gain increases, so that the max gain level can be reached */\n            double_step_size_threshold = 2 * MAX_DELTA_GAIN_QUANT - N_LEVELS_QGAIN + *prev_ind;\n            if( ind[ k ] > double_step_size_threshold ) {\n                ind[ k ] = double_step_size_threshold + silk_RSHIFT( ind[ k ] - double_step_size_threshold + 1, 1 );\n            }\n\n            ind[ k ] = silk_LIMIT_int( ind[ k ], MIN_DELTA_GAIN_QUANT, MAX_DELTA_GAIN_QUANT );\n\n            /* Accumulate deltas */\n            if( ind[ k ] > double_step_size_threshold ) {\n                *prev_ind += silk_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold;\n            } else {\n                *prev_ind += ind[ k ];\n            }\n\n            /* Shift to make non-negative */\n            ind[ k ] -= MIN_DELTA_GAIN_QUANT;\n        }\n\n        /* Scale and convert to linear scale */\n        gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */\n    }\n}\n\n/* Gains scalar dequantization, uniform on log scale */\nvoid silk_gains_dequant(\n    opus_int32                  gain_Q16[ MAX_NB_SUBFR ],       /* O    quantized gains                             */\n    const opus_int8             ind[ MAX_NB_SUBFR ],            /* I    gain indices                                */\n    opus_int8                   *prev_ind,                      /* I/O  last index in previous frame                */\n    const opus_int              conditional,                    /* I    first gain is delta coded if 1              */\n    const opus_int              nb_subfr                        /* I    number of subframes                          */\n)\n{\n    opus_int   k, ind_tmp, double_step_size_threshold;\n\n    for( k = 0; k < nb_subfr; k++ ) {\n        if( k == 0 && conditional == 0 ) {\n            /* Gain index is not allowed to go down more than 16 steps (~21.8 dB) */\n            *prev_ind = silk_max_int( ind[ k ], *prev_ind - 16 );\n        } else {\n            /* Delta index */\n            ind_tmp = ind[ k ] + MIN_DELTA_GAIN_QUANT;\n\n            /* Accumulate deltas */\n            double_step_size_threshold = 2 * MAX_DELTA_GAIN_QUANT - N_LEVELS_QGAIN + *prev_ind;\n            if( ind_tmp > double_step_size_threshold ) {\n                *prev_ind += silk_LSHIFT( ind_tmp, 1 ) - double_step_size_threshold;\n            } else {\n                *prev_ind += ind_tmp;\n            }\n        }\n        *prev_ind = silk_LIMIT_int( *prev_ind, 0, N_LEVELS_QGAIN - 1 );\n\n        /* Scale and convert to linear scale */\n        gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */\n    }\n}\n\n/* Compute unique identifier of gain indices vector */\nopus_int32 silk_gains_ID(                                       /* O    returns unique identifier of gains          */\n    const opus_int8             ind[ MAX_NB_SUBFR ],            /* I    gain indices                                */\n    const opus_int              nb_subfr                        /* I    number of subframes                         */\n)\n{\n    opus_int   k;\n    opus_int32 gainsID;\n\n    gainsID = 0;\n    for( k = 0; k < nb_subfr; k++ ) {\n        gainsID = silk_ADD_LSHIFT32( ind[ k ], gainsID, 8 );\n    }\n\n    return gainsID;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/init_decoder.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/************************/\n/* Init Decoder State   */\n/************************/\nopus_int silk_init_decoder(\n    silk_decoder_state          *psDec                          /* I/O  Decoder state pointer                       */\n)\n{\n    /* Clear the entire encoder state, except anything copied */\n    silk_memset( psDec, 0, sizeof( silk_decoder_state ) );\n\n    /* Used to deactivate LSF interpolation */\n    psDec->first_frame_after_reset = 1;\n    psDec->prev_gain_Q16 = 65536;\n\n    /* Reset CNG state */\n    silk_CNG_Reset( psDec );\n\n    /* Reset PLC state */\n    silk_PLC_Reset( psDec );\n\n    return(0);\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/init_encoder.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#ifdef FIXED_POINT\n#include \"main_FIX.h\"\n#else\n#include \"main_FLP.h\"\n#endif\n#include \"tuning_parameters.h\"\n#include \"cpu_support.h\"\n\n/*********************************/\n/* Initialize Silk Encoder state */\n/*********************************/\nopus_int silk_init_encoder(\n    silk_encoder_state_Fxx          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */\n    int                              arch                                   /* I    Run-time architecture                                                       */\n)\n{\n    opus_int ret = 0;\n\n    /* Clear the entire encoder state */\n    silk_memset( psEnc, 0, sizeof( silk_encoder_state_Fxx ) );\n\n    psEnc->sCmn.arch = arch;\n\n    psEnc->sCmn.variable_HP_smth1_Q15 = silk_LSHIFT( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ), 8 );\n    psEnc->sCmn.variable_HP_smth2_Q15 = psEnc->sCmn.variable_HP_smth1_Q15;\n\n    /* Used to deactivate LSF interpolation, pitch prediction */\n    psEnc->sCmn.first_frame_after_reset = 1;\n\n    /* Initialize Silk VAD */\n    ret += silk_VAD_Init( &psEnc->sCmn.sVAD );\n\n    return  ret;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/inner_prod_aligned.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n\nopus_int32 silk_inner_prod_aligned_scale(\n    const opus_int16 *const     inVec1,             /*    I input vector 1                                              */\n    const opus_int16 *const     inVec2,             /*    I input vector 2                                              */\n    const opus_int              scale,              /*    I number of bits to shift                                     */\n    const opus_int              len                 /*    I vector lengths                                              */\n)\n{\n    opus_int   i;\n    opus_int32 sum = 0;\n    for( i = 0; i < len; i++ ) {\n        sum = silk_ADD_RSHIFT32( sum, silk_SMULBB( inVec1[ i ], inVec2[ i ] ), scale );\n    }\n    return sum;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/interpolate.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Interpolate two vectors */\nvoid silk_interpolate(\n    opus_int16                  xi[ MAX_LPC_ORDER ],            /* O    interpolated vector                         */\n    const opus_int16            x0[ MAX_LPC_ORDER ],            /* I    first vector                                */\n    const opus_int16            x1[ MAX_LPC_ORDER ],            /* I    second vector                               */\n    const opus_int              ifact_Q2,                       /* I    interp. factor, weight on 2nd vector        */\n    const opus_int              d                               /* I    number of parameters                        */\n)\n{\n    opus_int i;\n\n    silk_assert( ifact_Q2 >= 0 );\n    silk_assert( ifact_Q2 <= 4 );\n\n    for( i = 0; i < d; i++ ) {\n        xi[ i ] = (opus_int16)silk_ADD_RSHIFT( x0[ i ], silk_SMULBB( x1[ i ] - x0[ i ], ifact_Q2 ), 2 );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/lin2log.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n/* Approximation of 128 * log2() (very close inverse of silk_log2lin()) */\n/* Convert input to a log scale    */\nopus_int32 silk_lin2log(\n    const opus_int32            inLin               /* I  input in linear scale                                         */\n)\n{\n    opus_int32 lz, frac_Q7;\n\n    silk_CLZ_FRAC( inLin, &lz, &frac_Q7 );\n\n    /* Piece-wise parabolic approximation */\n    return silk_LSHIFT( 31 - lz, 7 ) + silk_SMLAWB( frac_Q7, silk_MUL( frac_Q7, 128 - frac_Q7 ), 179 );\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/log2lin.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n\n/* Approximation of 2^() (very close inverse of silk_lin2log()) */\n/* Convert input to a linear scale    */\nopus_int32 silk_log2lin(\n    const opus_int32            inLog_Q7            /* I  input on log scale                                            */\n)\n{\n    opus_int32 out, frac_Q7;\n\n    if( inLog_Q7 < 0 ) {\n        return 0;\n    } else if ( inLog_Q7 >= 3967 ) {\n        return silk_int32_MAX;\n    }\n\n    out = silk_LSHIFT( 1, silk_RSHIFT( inLog_Q7, 7 ) );\n    frac_Q7 = inLog_Q7 & 0x7F;\n    if( inLog_Q7 < 2048 ) {\n        /* Piece-wise parabolic approximation */\n        out = silk_ADD_RSHIFT32( out, silk_MUL( out, silk_SMLAWB( frac_Q7, silk_SMULBB( frac_Q7, 128 - frac_Q7 ), -174 ) ), 7 );\n    } else {\n        /* Piece-wise parabolic approximation */\n        out = silk_MLA( out, silk_RSHIFT( out, 7 ), silk_SMLAWB( frac_Q7, silk_SMULBB( frac_Q7, 128 - frac_Q7 ), -174 ) );\n    }\n    return out;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/macros.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_MACROS_H\n#define SILK_MACROS_H\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"opus_types.h\"\n#include \"opus_defines.h\"\n\n#if OPUS_GNUC_PREREQ(3, 0)\n#define opus_likely(x)       (__builtin_expect(!!(x), 1))\n#define opus_unlikely(x)     (__builtin_expect(!!(x), 0))\n#else\n#define opus_likely(x)       (!!(x))\n#define opus_unlikely(x)     (!!(x))\n#endif\n\n/* Set this if opus_int64 is a native type of the CPU. */\n#define OPUS_FAST_INT64 (defined(__x86_64__) || defined(__LP64__) || defined(_WIN64))\n\n/* This is an OPUS_INLINE header file for general platform. */\n\n/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */\n#if OPUS_FAST_INT64\n#define silk_SMULWB(a32, b32)            (((a32) * (opus_int64)((opus_int16)(b32))) >> 16)\n#else\n#define silk_SMULWB(a32, b32)            ((((a32) >> 16) * (opus_int32)((opus_int16)(b32))) + ((((a32) & 0x0000FFFF) * (opus_int32)((opus_int16)(b32))) >> 16))\n#endif\n\n/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */\n#if OPUS_FAST_INT64\n#define silk_SMLAWB(a32, b32, c32)       ((a32) + (((b32) * (opus_int64)((opus_int16)(c32))) >> 16))\n#else\n#define silk_SMLAWB(a32, b32, c32)       ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16)))\n#endif\n\n/* (a32 * (b32 >> 16)) >> 16 */\n#define silk_SMULWT(a32, b32)            (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16))\n\n/* a32 + (b32 * (c32 >> 16)) >> 16 */\n#if OPUS_FAST_INT64\n#define silk_SMLAWT(a32, b32, c32)       ((a32) + (((b32) * ((opus_int64)(c32) >> 16)) >> 16))\n#else\n#define silk_SMLAWT(a32, b32, c32)       ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16))\n#endif\n\n/* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */\n#define silk_SMULBB(a32, b32)            ((opus_int32)((opus_int16)(a32)) * (opus_int32)((opus_int16)(b32)))\n\n/* a32 + (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)) output have to be 32bit int */\n#define silk_SMLABB(a32, b32, c32)       ((a32) + ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32)))\n\n/* (opus_int32)((opus_int16)(a32)) * (b32 >> 16) */\n#define silk_SMULBT(a32, b32)            ((opus_int32)((opus_int16)(a32)) * ((b32) >> 16))\n\n/* a32 + (opus_int32)((opus_int16)(b32)) * (c32 >> 16) */\n#define silk_SMLABT(a32, b32, c32)       ((a32) + ((opus_int32)((opus_int16)(b32))) * ((c32) >> 16))\n\n/* a64 + (b32 * c32) */\n#define silk_SMLAL(a64, b32, c32)        (silk_ADD64((a64), ((opus_int64)(b32) * (opus_int64)(c32))))\n\n/* (a32 * b32) >> 16 */\n#if OPUS_FAST_INT64\n#define silk_SMULWW(a32, b32)            (((opus_int64)(a32) * (b32)) >> 16)\n#else\n#define silk_SMULWW(a32, b32)            silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16))\n#endif\n\n/* a32 + ((b32 * c32) >> 16) */\n#if OPUS_FAST_INT64\n#define silk_SMLAWW(a32, b32, c32)       ((a32) + (((opus_int64)(b32) * (c32)) >> 16))\n#else\n#define silk_SMLAWW(a32, b32, c32)       silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16))\n#endif\n\n/* add/subtract with output saturated */\n#define silk_ADD_SAT32(a, b)             ((((opus_uint32)(a) + (opus_uint32)(b)) & 0x80000000) == 0 ?                              \\\n                                        ((((a) & (b)) & 0x80000000) != 0 ? silk_int32_MIN : (a)+(b)) :   \\\n                                        ((((a) | (b)) & 0x80000000) == 0 ? silk_int32_MAX : (a)+(b)) )\n\n#define silk_SUB_SAT32(a, b)             ((((opus_uint32)(a)-(opus_uint32)(b)) & 0x80000000) == 0 ?                                        \\\n                                        (( (a) & ((b)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a)-(b)) :    \\\n                                        ((((a)^0x80000000) & (b)  & 0x80000000) ? silk_int32_MAX : (a)-(b)) )\n\n#if defined(MIPSr1_ASM)\n#include \"mips/macros_mipsr1.h\"\n#endif\n\n#include \"ecintrin.h\"\n#ifndef OVERRIDE_silk_CLZ16\nstatic OPUS_INLINE opus_int32 silk_CLZ16(opus_int16 in16)\n{\n    return 32 - EC_ILOG(in16<<16|0x8000);\n}\n#endif\n\n#ifndef OVERRIDE_silk_CLZ32\nstatic OPUS_INLINE opus_int32 silk_CLZ32(opus_int32 in32)\n{\n    return in32 ? 32 - EC_ILOG(in32) : 32;\n}\n#endif\n\n/* Row based */\n#define matrix_ptr(Matrix_base_adr, row, column, N) \\\n    (*((Matrix_base_adr) + ((row)*(N)+(column))))\n#define matrix_adr(Matrix_base_adr, row, column, N) \\\n      ((Matrix_base_adr) + ((row)*(N)+(column)))\n\n/* Column based */\n#ifndef matrix_c_ptr\n#   define matrix_c_ptr(Matrix_base_adr, row, column, M) \\\n    (*((Matrix_base_adr) + ((row)+(M)*(column))))\n#endif\n\n#ifdef OPUS_ARM_INLINE_ASM\n#include \"arm/macros_armv4.h\"\n#endif\n\n#ifdef OPUS_ARM_INLINE_EDSP\n#include \"arm/macros_armv5e.h\"\n#endif\n\n#endif /* SILK_MACROS_H */\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/main.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_MAIN_H\n#define SILK_MAIN_H\n\n#include \"SigProc_FIX.h\"\n#include \"define.h\"\n#include \"structs.h\"\n#include \"tables.h\"\n#include \"PLC.h\"\n#include \"control.h\"\n#include \"debug.h\"\n#include \"entenc.h\"\n#include \"entdec.h\"\n\n#if defined(OPUS_X86_MAY_HAVE_SSE4_1)\n#include \"x86/main_sse.h\"\n#endif\n\n/* Convert Left/Right stereo signal to adaptive Mid/Side representation */\nvoid silk_stereo_LR_to_MS(\n    stereo_enc_state            *state,                         /* I/O  State                                       */\n    opus_int16                  x1[],                           /* I/O  Left input signal, becomes mid signal       */\n    opus_int16                  x2[],                           /* I/O  Right input signal, becomes side signal     */\n    opus_int8                   ix[ 2 ][ 3 ],                   /* O    Quantization indices                        */\n    opus_int8                   *mid_only_flag,                 /* O    Flag: only mid signal coded                 */\n    opus_int32                  mid_side_rates_bps[],           /* O    Bitrates for mid and side signals           */\n    opus_int32                  total_rate_bps,                 /* I    Total bitrate                               */\n    opus_int                    prev_speech_act_Q8,             /* I    Speech activity level in previous frame     */\n    opus_int                    toMono,                         /* I    Last frame before a stereo->mono transition */\n    opus_int                    fs_kHz,                         /* I    Sample rate (kHz)                           */\n    opus_int                    frame_length                    /* I    Number of samples                           */\n);\n\n/* Convert adaptive Mid/Side representation to Left/Right stereo signal */\nvoid silk_stereo_MS_to_LR(\n    stereo_dec_state            *state,                         /* I/O  State                                       */\n    opus_int16                  x1[],                           /* I/O  Left input signal, becomes mid signal       */\n    opus_int16                  x2[],                           /* I/O  Right input signal, becomes side signal     */\n    const opus_int32            pred_Q13[],                     /* I    Predictors                                  */\n    opus_int                    fs_kHz,                         /* I    Samples rate (kHz)                          */\n    opus_int                    frame_length                    /* I    Number of samples                           */\n);\n\n/* Find least-squares prediction gain for one signal based on another and quantize it */\nopus_int32 silk_stereo_find_predictor(                          /* O    Returns predictor in Q13                    */\n    opus_int32                  *ratio_Q14,                     /* O    Ratio of residual and mid energies          */\n    const opus_int16            x[],                            /* I    Basis signal                                */\n    const opus_int16            y[],                            /* I    Target signal                               */\n    opus_int32                  mid_res_amp_Q0[],               /* I/O  Smoothed mid, residual norms                */\n    opus_int                    length,                         /* I    Number of samples                           */\n    opus_int                    smooth_coef_Q16                 /* I    Smoothing coefficient                       */\n);\n\n/* Quantize mid/side predictors */\nvoid silk_stereo_quant_pred(\n    opus_int32                  pred_Q13[],                     /* I/O  Predictors (out: quantized)                 */\n    opus_int8                   ix[ 2 ][ 3 ]                    /* O    Quantization indices                        */\n);\n\n/* Entropy code the mid/side quantization indices */\nvoid silk_stereo_encode_pred(\n    ec_enc                      *psRangeEnc,                    /* I/O  Compressor data structure                   */\n    opus_int8                   ix[ 2 ][ 3 ]                    /* I    Quantization indices                        */\n);\n\n/* Entropy code the mid-only flag */\nvoid silk_stereo_encode_mid_only(\n    ec_enc                      *psRangeEnc,                    /* I/O  Compressor data structure                   */\n    opus_int8                   mid_only_flag\n);\n\n/* Decode mid/side predictors */\nvoid silk_stereo_decode_pred(\n    ec_dec                      *psRangeDec,                    /* I/O  Compressor data structure                   */\n    opus_int32                  pred_Q13[]                      /* O    Predictors                                  */\n);\n\n/* Decode mid-only flag */\nvoid silk_stereo_decode_mid_only(\n    ec_dec                      *psRangeDec,                    /* I/O  Compressor data structure                   */\n    opus_int                    *decode_only_mid                /* O    Flag that only mid channel has been coded   */\n);\n\n/* Encodes signs of excitation */\nvoid silk_encode_signs(\n    ec_enc                      *psRangeEnc,                        /* I/O  Compressor data structure                   */\n    const opus_int8             pulses[],                           /* I    pulse signal                                */\n    opus_int                    length,                             /* I    length of input                             */\n    const opus_int              signalType,                         /* I    Signal type                                 */\n    const opus_int              quantOffsetType,                    /* I    Quantization offset type                    */\n    const opus_int              sum_pulses[ MAX_NB_SHELL_BLOCKS ]   /* I    Sum of absolute pulses per block            */\n);\n\n/* Decodes signs of excitation */\nvoid silk_decode_signs(\n    ec_dec                      *psRangeDec,                        /* I/O  Compressor data structure                   */\n    opus_int16                  pulses[],                           /* I/O  pulse signal                                */\n    opus_int                    length,                             /* I    length of input                             */\n    const opus_int              signalType,                         /* I    Signal type                                 */\n    const opus_int              quantOffsetType,                    /* I    Quantization offset type                    */\n    const opus_int              sum_pulses[ MAX_NB_SHELL_BLOCKS ]   /* I    Sum of absolute pulses per block            */\n);\n\n/* Check encoder control struct */\nopus_int check_control_input(\n    silk_EncControlStruct        *encControl                    /* I    Control structure                           */\n);\n\n/* Control internal sampling rate */\nopus_int silk_control_audio_bandwidth(\n    silk_encoder_state          *psEncC,                        /* I/O  Pointer to Silk encoder state               */\n    silk_EncControlStruct       *encControl                     /* I    Control structure                           */\n);\n\n/* Control SNR of redidual quantizer */\nopus_int silk_control_SNR(\n    silk_encoder_state          *psEncC,                        /* I/O  Pointer to Silk encoder state               */\n    opus_int32                  TargetRate_bps                  /* I    Target max bitrate (bps)                    */\n);\n\n/***************/\n/* Shell coder */\n/***************/\n\n/* Encode quantization indices of excitation */\nvoid silk_encode_pulses(\n    ec_enc                      *psRangeEnc,                    /* I/O  compressor data structure                   */\n    const opus_int              signalType,                     /* I    Signal type                                 */\n    const opus_int              quantOffsetType,                /* I    quantOffsetType                             */\n    opus_int8                   pulses[],                       /* I    quantization indices                        */\n    const opus_int              frame_length                    /* I    Frame length                                */\n);\n\n/* Shell encoder, operates on one shell code frame of 16 pulses */\nvoid silk_shell_encoder(\n    ec_enc                      *psRangeEnc,                    /* I/O  compressor data structure                   */\n    const opus_int              *pulses0                        /* I    data: nonnegative pulse amplitudes          */\n);\n\n/* Shell decoder, operates on one shell code frame of 16 pulses */\nvoid silk_shell_decoder(\n    opus_int16                  *pulses0,                       /* O    data: nonnegative pulse amplitudes          */\n    ec_dec                      *psRangeDec,                    /* I/O  Compressor data structure                   */\n    const opus_int              pulses4                         /* I    number of pulses per pulse-subframe         */\n);\n\n/* Gain scalar quantization with hysteresis, uniform on log scale */\nvoid silk_gains_quant(\n    opus_int8                   ind[ MAX_NB_SUBFR ],            /* O    gain indices                                */\n    opus_int32                  gain_Q16[ MAX_NB_SUBFR ],       /* I/O  gains (quantized out)                       */\n    opus_int8                   *prev_ind,                      /* I/O  last index in previous frame                */\n    const opus_int              conditional,                    /* I    first gain is delta coded if 1              */\n    const opus_int              nb_subfr                        /* I    number of subframes                         */\n);\n\n/* Gains scalar dequantization, uniform on log scale */\nvoid silk_gains_dequant(\n    opus_int32                  gain_Q16[ MAX_NB_SUBFR ],       /* O    quantized gains                             */\n    const opus_int8             ind[ MAX_NB_SUBFR ],            /* I    gain indices                                */\n    opus_int8                   *prev_ind,                      /* I/O  last index in previous frame                */\n    const opus_int              conditional,                    /* I    first gain is delta coded if 1              */\n    const opus_int              nb_subfr                        /* I    number of subframes                          */\n);\n\n/* Compute unique identifier of gain indices vector */\nopus_int32 silk_gains_ID(                                       /* O    returns unique identifier of gains          */\n    const opus_int8             ind[ MAX_NB_SUBFR ],            /* I    gain indices                                */\n    const opus_int              nb_subfr                        /* I    number of subframes                         */\n);\n\n/* Interpolate two vectors */\nvoid silk_interpolate(\n    opus_int16                  xi[ MAX_LPC_ORDER ],            /* O    interpolated vector                         */\n    const opus_int16            x0[ MAX_LPC_ORDER ],            /* I    first vector                                */\n    const opus_int16            x1[ MAX_LPC_ORDER ],            /* I    second vector                               */\n    const opus_int              ifact_Q2,                       /* I    interp. factor, weight on 2nd vector        */\n    const opus_int              d                               /* I    number of parameters                        */\n);\n\n/* LTP tap quantizer */\nvoid silk_quant_LTP_gains(\n    opus_int16                  B_Q14[ MAX_NB_SUBFR * LTP_ORDER ],          /* I/O  (un)quantized LTP gains         */\n    opus_int8                   cbk_index[ MAX_NB_SUBFR ],                  /* O    Codebook Index                  */\n    opus_int8                   *periodicity_index,                         /* O    Periodicity Index               */\n    opus_int32                  *sum_gain_dB_Q7,                            /* I/O  Cumulative max prediction gain  */\n    const opus_int32            W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ],  /* I    Error Weights in Q18            */\n    opus_int                    mu_Q9,                                      /* I    Mu value (R/D tradeoff)         */\n    opus_int                    lowComplexity,                              /* I    Flag for low complexity         */\n    const opus_int              nb_subfr,                                   /* I    number of subframes             */\n    int                         arch                                        /* I    Run-time architecture           */\n);\n\n/* Entropy constrained matrix-weighted VQ, for a single input data vector */\nvoid silk_VQ_WMat_EC_c(\n    opus_int8                   *ind,                           /* O    index of best codebook vector               */\n    opus_int32                  *rate_dist_Q14,                 /* O    best weighted quant error + mu * rate       */\n    opus_int                    *gain_Q7,                       /* O    sum of absolute LTP coefficients            */\n    const opus_int16            *in_Q14,                        /* I    input vector to be quantized                */\n    const opus_int32            *W_Q18,                         /* I    weighting matrix                            */\n    const opus_int8             *cb_Q7,                         /* I    codebook                                    */\n    const opus_uint8            *cb_gain_Q7,                    /* I    codebook effective gain                     */\n    const opus_uint8            *cl_Q5,                         /* I    code length for each codebook vector        */\n    const opus_int              mu_Q9,                          /* I    tradeoff betw. weighted error and rate      */\n    const opus_int32            max_gain_Q7,                    /* I    maximum sum of absolute LTP coefficients    */\n    opus_int                    L                               /* I    number of vectors in codebook               */\n);\n\n#if !defined(OVERRIDE_silk_VQ_WMat_EC)\n#define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \\\n                          mu_Q9, max_gain_Q7, L, arch) \\\n    ((void)(arch),silk_VQ_WMat_EC_c(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \\\n                          mu_Q9, max_gain_Q7, L))\n#endif\n\n/************************************/\n/* Noise shaping quantization (NSQ) */\n/************************************/\n\nvoid silk_NSQ_c(\n    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */\n    silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */\n    SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */\n    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */\n    opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */\n    const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */\n    const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */\n    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */\n    const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */\n    const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */\n    const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */\n    const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */\n    const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */\n    const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */\n    const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */\n);\n\n#if !defined(OVERRIDE_silk_NSQ)\n#define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \\\n                   HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \\\n    ((void)(arch),silk_NSQ_c(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \\\n                   HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))\n#endif\n\n/* Noise shaping using delayed decision */\nvoid silk_NSQ_del_dec_c(\n    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */\n    silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */\n    SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */\n    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */\n    opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */\n    const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */\n    const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */\n    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */\n    const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */\n    const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */\n    const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */\n    const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */\n    const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */\n    const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */\n    const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */\n);\n\n#if !defined(OVERRIDE_silk_NSQ_del_dec)\n#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \\\n                           HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \\\n    ((void)(arch),silk_NSQ_del_dec_c(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \\\n                           HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))\n#endif\n\n/************/\n/* Silk VAD */\n/************/\n/* Initialize the Silk VAD */\nopus_int silk_VAD_Init(                                         /* O    Return value, 0 if success                  */\n    silk_VAD_state              *psSilk_VAD                     /* I/O  Pointer to Silk VAD state                   */\n);\n\n/* Get speech activity level in Q8 */\nopus_int silk_VAD_GetSA_Q8_c(                                   /* O    Return value, 0 if success                  */\n    silk_encoder_state          *psEncC,                        /* I/O  Encoder state                               */\n    const opus_int16            pIn[]                           /* I    PCM input                                   */\n);\n\n#if !defined(OVERRIDE_silk_VAD_GetSA_Q8)\n#define silk_VAD_GetSA_Q8(psEnC, pIn, arch) ((void)(arch),silk_VAD_GetSA_Q8_c(psEnC, pIn))\n#endif\n\n/* Low-pass filter with variable cutoff frequency based on  */\n/* piece-wise linear interpolation between elliptic filters */\n/* Start by setting transition_frame_no = 1;                */\nvoid silk_LP_variable_cutoff(\n    silk_LP_state               *psLP,                          /* I/O  LP filter state                             */\n    opus_int16                  *frame,                         /* I/O  Low-pass filtered output signal             */\n    const opus_int              frame_length                    /* I    Frame length                                */\n);\n\n/******************/\n/* NLSF Quantizer */\n/******************/\n/* Limit, stabilize, convert and quantize NLSFs */\nvoid silk_process_NLSFs(\n    silk_encoder_state          *psEncC,                            /* I/O  Encoder state                               */\n    opus_int16                  PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ], /* O    Prediction coefficients                     */\n    opus_int16                  pNLSF_Q15[         MAX_LPC_ORDER ], /* I/O  Normalized LSFs (quant out) (0 - (2^15-1))  */\n    const opus_int16            prev_NLSFq_Q15[    MAX_LPC_ORDER ]  /* I    Previous Normalized LSFs (0 - (2^15-1))     */\n);\n\nopus_int32 silk_NLSF_encode(                                    /* O    Returns RD value in Q25                     */\n          opus_int8             *NLSFIndices,                   /* I    Codebook path vector [ LPC_ORDER + 1 ]      */\n          opus_int16            *pNLSF_Q15,                     /* I/O  Quantized NLSF vector [ LPC_ORDER ]         */\n    const silk_NLSF_CB_struct   *psNLSF_CB,                     /* I    Codebook object                             */\n    const opus_int16            *pW_QW,                         /* I    NLSF weight vector [ LPC_ORDER ]            */\n    const opus_int              NLSF_mu_Q20,                    /* I    Rate weight for the RD optimization         */\n    const opus_int              nSurvivors,                     /* I    Max survivors after first stage             */\n    const opus_int              signalType                      /* I    Signal type: 0/1/2                          */\n);\n\n/* Compute quantization errors for an LPC_order element input vector for a VQ codebook */\nvoid silk_NLSF_VQ(\n    opus_int32                  err_Q26[],                      /* O    Quantization errors [K]                     */\n    const opus_int16            in_Q15[],                       /* I    Input vectors to be quantized [LPC_order]   */\n    const opus_uint8            pCB_Q8[],                       /* I    Codebook vectors [K*LPC_order]              */\n    const opus_int              K,                              /* I    Number of codebook vectors                  */\n    const opus_int              LPC_order                       /* I    Number of LPCs                              */\n);\n\n/* Delayed-decision quantizer for NLSF residuals */\nopus_int32 silk_NLSF_del_dec_quant(                             /* O    Returns RD value in Q25                     */\n    opus_int8                   indices[],                      /* O    Quantization indices [ order ]              */\n    const opus_int16            x_Q10[],                        /* I    Input [ order ]                             */\n    const opus_int16            w_Q5[],                         /* I    Weights [ order ]                           */\n    const opus_uint8            pred_coef_Q8[],                 /* I    Backward predictor coefs [ order ]          */\n    const opus_int16            ec_ix[],                        /* I    Indices to entropy coding tables [ order ]  */\n    const opus_uint8            ec_rates_Q5[],                  /* I    Rates []                                    */\n    const opus_int              quant_step_size_Q16,            /* I    Quantization step size                      */\n    const opus_int16            inv_quant_step_size_Q6,         /* I    Inverse quantization step size              */\n    const opus_int32            mu_Q20,                         /* I    R/D tradeoff                                */\n    const opus_int16            order                           /* I    Number of input values                      */\n);\n\n/* Unpack predictor values and indices for entropy coding tables */\nvoid silk_NLSF_unpack(\n          opus_int16            ec_ix[],                        /* O    Indices to entropy tables [ LPC_ORDER ]     */\n          opus_uint8            pred_Q8[],                      /* O    LSF predictor [ LPC_ORDER ]                 */\n    const silk_NLSF_CB_struct   *psNLSF_CB,                     /* I    Codebook object                             */\n    const opus_int              CB1_index                       /* I    Index of vector in first LSF codebook       */\n);\n\n/***********************/\n/* NLSF vector decoder */\n/***********************/\nvoid silk_NLSF_decode(\n          opus_int16            *pNLSF_Q15,                     /* O    Quantized NLSF vector [ LPC_ORDER ]         */\n          opus_int8             *NLSFIndices,                   /* I    Codebook path vector [ LPC_ORDER + 1 ]      */\n    const silk_NLSF_CB_struct   *psNLSF_CB                      /* I    Codebook object                             */\n);\n\n/****************************************************/\n/* Decoder Functions                                */\n/****************************************************/\nopus_int silk_init_decoder(\n    silk_decoder_state          *psDec                          /* I/O  Decoder state pointer                       */\n);\n\n/* Set decoder sampling rate */\nopus_int silk_decoder_set_fs(\n    silk_decoder_state          *psDec,                         /* I/O  Decoder state pointer                       */\n    opus_int                    fs_kHz,                         /* I    Sampling frequency (kHz)                    */\n    opus_int32                  fs_API_Hz                       /* I    API Sampling frequency (Hz)                 */\n);\n\n/****************/\n/* Decode frame */\n/****************/\nopus_int silk_decode_frame(\n    silk_decoder_state          *psDec,                         /* I/O  Pointer to Silk decoder state               */\n    ec_dec                      *psRangeDec,                    /* I/O  Compressor data structure                   */\n    opus_int16                  pOut[],                         /* O    Pointer to output speech frame              */\n    opus_int32                  *pN,                            /* O    Pointer to size of output frame             */\n    opus_int                    lostFlag,                       /* I    0: no loss, 1 loss, 2 decode fec            */\n    opus_int                    condCoding,                     /* I    The type of conditional coding to use       */\n    int                         arch                            /* I    Run-time architecture                       */\n);\n\n/* Decode indices from bitstream */\nvoid silk_decode_indices(\n    silk_decoder_state          *psDec,                         /* I/O  State                                       */\n    ec_dec                      *psRangeDec,                    /* I/O  Compressor data structure                   */\n    opus_int                    FrameIndex,                     /* I    Frame number                                */\n    opus_int                    decode_LBRR,                    /* I    Flag indicating LBRR data is being decoded  */\n    opus_int                    condCoding                      /* I    The type of conditional coding to use       */\n);\n\n/* Decode parameters from payload */\nvoid silk_decode_parameters(\n    silk_decoder_state          *psDec,                         /* I/O  State                                       */\n    silk_decoder_control        *psDecCtrl,                     /* I/O  Decoder control                             */\n    opus_int                    condCoding                      /* I    The type of conditional coding to use       */\n);\n\n/* Core decoder. Performs inverse NSQ operation LTP + LPC */\nvoid silk_decode_core(\n    silk_decoder_state          *psDec,                         /* I/O  Decoder state                               */\n    silk_decoder_control        *psDecCtrl,                     /* I    Decoder control                             */\n    opus_int16                  xq[],                           /* O    Decoded speech                              */\n    const opus_int16            pulses[ MAX_FRAME_LENGTH ],     /* I    Pulse signal                                */\n    int                         arch                            /* I    Run-time architecture                       */\n);\n\n/* Decode quantization indices of excitation (Shell coding) */\nvoid silk_decode_pulses(\n    ec_dec                      *psRangeDec,                    /* I/O  Compressor data structure                   */\n    opus_int16                  pulses[],                       /* O    Excitation signal                           */\n    const opus_int              signalType,                     /* I    Sigtype                                     */\n    const opus_int              quantOffsetType,                /* I    quantOffsetType                             */\n    const opus_int              frame_length                    /* I    Frame length                                */\n);\n\n/******************/\n/* CNG */\n/******************/\n\n/* Reset CNG */\nvoid silk_CNG_Reset(\n    silk_decoder_state          *psDec                          /* I/O  Decoder state                               */\n);\n\n/* Updates CNG estimate, and applies the CNG when packet was lost */\nvoid silk_CNG(\n    silk_decoder_state          *psDec,                         /* I/O  Decoder state                               */\n    silk_decoder_control        *psDecCtrl,                     /* I/O  Decoder control                             */\n    opus_int16                  frame[],                        /* I/O  Signal                                      */\n    opus_int                    length                          /* I    Length of residual                          */\n);\n\n/* Encoding of various parameters */\nvoid silk_encode_indices(\n    silk_encoder_state          *psEncC,                        /* I/O  Encoder state                               */\n    ec_enc                      *psRangeEnc,                    /* I/O  Compressor data structure                   */\n    opus_int                    FrameIndex,                     /* I    Frame number                                */\n    opus_int                    encode_LBRR,                    /* I    Flag indicating LBRR data is being encoded  */\n    opus_int                    condCoding                      /* I    The type of conditional coding to use       */\n);\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/mips/NSQ_del_dec_mipsr1.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef __NSQ_DEL_DEC_MIPSR1_H__\n#define __NSQ_DEL_DEC_MIPSR1_H__\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"stack_alloc.h\"\n\n#define OVERRIDE_silk_noise_shape_quantizer_del_dec\nstatic inline void silk_noise_shape_quantizer_del_dec(\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                           */\n    NSQ_del_dec_struct  psDelDec[],             /* I/O  Delayed decision states             */\n    opus_int            signalType,             /* I    Signal type                         */\n    const opus_int32    x_Q10[],                /* I                                        */\n    opus_int8           pulses[],               /* O                                        */\n    opus_int16          xq[],                   /* O                                        */\n    opus_int32          sLTP_Q15[],             /* I/O  LTP filter state                    */\n    opus_int32          delayedGain_Q10[],      /* I/O  Gain delay buffer                   */\n    const opus_int16    a_Q12[],                /* I    Short term prediction coefs         */\n    const opus_int16    b_Q14[],                /* I    Long term prediction coefs          */\n    const opus_int16    AR_shp_Q13[],           /* I    Noise shaping coefs                 */\n    opus_int            lag,                    /* I    Pitch lag                           */\n    opus_int32          HarmShapeFIRPacked_Q14, /* I                                        */\n    opus_int            Tilt_Q14,               /* I    Spectral tilt                       */\n    opus_int32          LF_shp_Q14,             /* I                                        */\n    opus_int32          Gain_Q16,               /* I                                        */\n    opus_int            Lambda_Q10,             /* I                                        */\n    opus_int            offset_Q10,             /* I                                        */\n    opus_int            length,                 /* I    Input length                        */\n    opus_int            subfr,                  /* I    Subframe number                     */\n    opus_int            shapingLPCOrder,        /* I    Shaping LPC filter order            */\n    opus_int            predictLPCOrder,        /* I    Prediction filter order             */\n    opus_int            warping_Q16,            /* I                                        */\n    opus_int            nStatesDelayedDecision, /* I    Number of states in decision tree   */\n    opus_int            *smpl_buf_idx,          /* I    Index to newest samples in buffers  */\n    opus_int            decisionDelay           /* I                                        */\n)\n{\n    opus_int     i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;\n    opus_int32   Winner_rand_state;\n    opus_int32   LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;\n    opus_int32   n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;\n    opus_int32   q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;\n    opus_int32   tmp1, tmp2, sLF_AR_shp_Q14;\n    opus_int32   *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;\n    NSQ_sample_struct  psSampleState[ MAX_DEL_DEC_STATES ][ 2 ];\n    NSQ_del_dec_struct *psDD;\n    NSQ_sample_struct  *psSS;\n    opus_int16 b_Q14_0, b_Q14_1, b_Q14_2, b_Q14_3, b_Q14_4;\n    opus_int16 a_Q12_0, a_Q12_1, a_Q12_2, a_Q12_3, a_Q12_4, a_Q12_5, a_Q12_6;\n    opus_int16 a_Q12_7, a_Q12_8, a_Q12_9, a_Q12_10, a_Q12_11, a_Q12_12, a_Q12_13;\n    opus_int16 a_Q12_14, a_Q12_15;\n\n    opus_int32 cur, prev, next;\n\n    //Intialize b_Q14 variables\n    b_Q14_0 = b_Q14[ 0 ];\n    b_Q14_1 = b_Q14[ 1 ];\n    b_Q14_2 = b_Q14[ 2 ];\n    b_Q14_3 = b_Q14[ 3 ];\n    b_Q14_4 = b_Q14[ 4 ];\n\n    //Intialize a_Q12 variables\n    a_Q12_0 = a_Q12[0];\n    a_Q12_1 = a_Q12[1];\n    a_Q12_2 = a_Q12[2];\n    a_Q12_3 = a_Q12[3];\n    a_Q12_4 = a_Q12[4];\n    a_Q12_5 = a_Q12[5];\n    a_Q12_6 = a_Q12[6];\n    a_Q12_7 = a_Q12[7];\n    a_Q12_8 = a_Q12[8];\n    a_Q12_9 = a_Q12[9];\n    a_Q12_10 = a_Q12[10];\n    a_Q12_11 = a_Q12[11];\n    a_Q12_12 = a_Q12[12];\n    a_Q12_13 = a_Q12[13];\n    a_Q12_14 = a_Q12[14];\n    a_Q12_15 = a_Q12[15];\n\n    long long temp64;\n\n    silk_assert( nStatesDelayedDecision > 0 );\n\n    shp_lag_ptr  = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];\n    pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];\n    Gain_Q10     = silk_RSHIFT( Gain_Q16, 6 );\n\n    for( i = 0; i < length; i++ ) {\n        /* Perform common calculations used in all states */\n\n        /* Long-term prediction */\n        if( signalType == TYPE_VOICED ) {\n            /* Unrolled loop */\n            /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n            temp64 = __builtin_mips_mult(pred_lag_ptr[ 0 ], b_Q14_0 );\n            temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -1 ], b_Q14_1 );\n            temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -2 ], b_Q14_2 );\n            temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -3 ], b_Q14_3 );\n            temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -4 ], b_Q14_4 );\n            temp64 += 32768;\n            LTP_pred_Q14 = __builtin_mips_extr_w(temp64, 16);\n            LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 );                          /* Q13 -> Q14 */\n            pred_lag_ptr++;\n        } else {\n            LTP_pred_Q14 = 0;\n        }\n\n        /* Long-term shaping */\n        if( lag > 0 ) {\n            /* Symmetric, packed FIR coefficients */\n            n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );\n            n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ],                      HarmShapeFIRPacked_Q14 );\n            n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 );            /* Q12 -> Q14 */\n            shp_lag_ptr++;\n        } else {\n            n_LTP_Q14 = 0;\n        }\n\n        for( k = 0; k < nStatesDelayedDecision; k++ ) {\n            /* Delayed decision state */\n            psDD = &psDelDec[ k ];\n\n            /* Sample state */\n            psSS = psSampleState[ k ];\n\n            /* Generate dither */\n            psDD->Seed = silk_RAND( psDD->Seed );\n\n            /* Pointer used in short term prediction and shaping */\n            psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];\n            /* Short-term prediction */\n            silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );\n            temp64 = __builtin_mips_mult(psLPC_Q14[  0 ], a_Q12_0 );\n            temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -1 ], a_Q12_1 );\n            temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -2 ], a_Q12_2 );\n            temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -3 ], a_Q12_3 );\n            temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -4 ], a_Q12_4 );\n            temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -5 ], a_Q12_5 );\n            temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -6 ], a_Q12_6 );\n            temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -7 ], a_Q12_7 );\n            temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -8 ], a_Q12_8 );\n            temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -9 ], a_Q12_9 );\n            if( predictLPCOrder == 16 ) {\n                temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -10 ], a_Q12_10 );\n                temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -11 ], a_Q12_11 );\n                temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -12 ], a_Q12_12 );\n                temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -13 ], a_Q12_13 );\n                temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -14 ], a_Q12_14 );\n                temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -15 ], a_Q12_15 );\n            }\n            temp64 += 32768;\n            LPC_pred_Q14 = __builtin_mips_extr_w(temp64, 16);\n\n            LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 );                              /* Q10 -> Q14 */\n\n            /* Noise shape feedback */\n            silk_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */\n            /* Output of lowpass section */\n            tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );\n            /* Output of allpass section */\n            tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );\n            psDD->sAR2_Q14[ 0 ] = tmp2;\n\n            temp64 = __builtin_mips_mult(tmp2, AR_shp_Q13[ 0 ] );\n\n            prev = psDD->sAR2_Q14[ 1 ];\n\n            /* Loop over allpass sections */\n            for( j = 2; j < shapingLPCOrder; j += 2 ) {\n                cur = psDD->sAR2_Q14[ j ];\n                next = psDD->sAR2_Q14[ j+1 ];\n                /* Output of allpass section */\n                tmp2 = silk_SMLAWB( prev, cur - tmp1, warping_Q16 );\n                psDD->sAR2_Q14[ j - 1 ] = tmp1;\n                temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ j - 1 ] );\n                temp64 = __builtin_mips_madd( temp64, tmp2, AR_shp_Q13[ j ] );\n                /* Output of allpass section */\n                tmp1 = silk_SMLAWB( cur, next - tmp2, warping_Q16 );\n                psDD->sAR2_Q14[ j + 0 ] = tmp2;\n                prev = next;\n            }\n            psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;\n            temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );\n            temp64 += 32768;\n            n_AR_Q14 = __builtin_mips_extr_w(temp64, 16);\n            n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 );                                      /* Q11 -> Q12 */\n            n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 );              /* Q12 */\n            n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 );                                      /* Q12 -> Q14 */\n\n            n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 );     /* Q12 */\n            n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 );            /* Q12 */\n            n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 );                                      /* Q12 -> Q14 */\n\n            /* Input minus prediction plus noise feedback                       */\n            /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP  */\n            tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 );                                    /* Q14 */\n            tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 );                               /* Q13 */\n            tmp1 = silk_SUB32( tmp2, tmp1 );                                            /* Q13 */\n            tmp1 = silk_RSHIFT_ROUND( tmp1, 4 );                                        /* Q10 */\n\n            r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 );                                     /* residual error Q10 */\n\n            /* Flip sign depending on dither */\n            if ( psDD->Seed < 0 ) {\n                r_Q10 = -r_Q10;\n            }\n            r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );\n\n            /* Find two quantization level candidates and measure their rate-distortion */\n            q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );\n            q1_Q0 = silk_RSHIFT( q1_Q10, 10 );\n            if( q1_Q0 > 0 ) {\n                q1_Q10  = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );\n                q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );\n                q2_Q10  = silk_ADD32( q1_Q10, 1024 );\n                rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );\n                rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );\n            } else if( q1_Q0 == 0 ) {\n                q1_Q10  = offset_Q10;\n                q2_Q10  = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );\n                rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );\n                rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );\n            } else if( q1_Q0 == -1 ) {\n                q2_Q10  = offset_Q10;\n                q1_Q10  = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );\n                rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );\n                rd2_Q10 = silk_SMULBB(  q2_Q10, Lambda_Q10 );\n            } else {            /* q1_Q0 < -1 */\n                q1_Q10  = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );\n                q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );\n                q2_Q10  = silk_ADD32( q1_Q10, 1024 );\n                rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );\n                rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );\n            }\n            rr_Q10  = silk_SUB32( r_Q10, q1_Q10 );\n            rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );\n            rr_Q10  = silk_SUB32( r_Q10, q2_Q10 );\n            rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );\n\n            if( rd1_Q10 < rd2_Q10 ) {\n                psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );\n                psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );\n                psSS[ 0 ].Q_Q10  = q1_Q10;\n                psSS[ 1 ].Q_Q10  = q2_Q10;\n            } else {\n                psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );\n                psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );\n                psSS[ 0 ].Q_Q10  = q2_Q10;\n                psSS[ 1 ].Q_Q10  = q1_Q10;\n            }\n\n            /* Update states for best quantization */\n\n            /* Quantized excitation */\n            exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );\n            if ( psDD->Seed < 0 ) {\n                exc_Q14 = -exc_Q14;\n            }\n\n            /* Add predictions */\n            LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );\n            xq_Q14      = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );\n\n            /* Update states */\n            sLF_AR_shp_Q14         = silk_SUB32( xq_Q14, n_AR_Q14 );\n            psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );\n            psSS[ 0 ].LF_AR_Q14    = sLF_AR_shp_Q14;\n            psSS[ 0 ].LPC_exc_Q14  = LPC_exc_Q14;\n            psSS[ 0 ].xq_Q14       = xq_Q14;\n\n            /* Update states for second best quantization */\n\n            /* Quantized excitation */\n            exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );\n            if ( psDD->Seed < 0 ) {\n                exc_Q14 = -exc_Q14;\n            }\n\n\n            /* Add predictions */\n            LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );\n            xq_Q14      = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );\n\n            /* Update states */\n            sLF_AR_shp_Q14         = silk_SUB32( xq_Q14, n_AR_Q14 );\n            psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );\n            psSS[ 1 ].LF_AR_Q14    = sLF_AR_shp_Q14;\n            psSS[ 1 ].LPC_exc_Q14  = LPC_exc_Q14;\n            psSS[ 1 ].xq_Q14       = xq_Q14;\n        }\n\n        *smpl_buf_idx  = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK;                   /* Index to newest samples              */\n        last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK;       /* Index to decisionDelay old samples   */\n\n        /* Find winner */\n        RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;\n        Winner_ind = 0;\n        for( k = 1; k < nStatesDelayedDecision; k++ ) {\n            if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {\n                RDmin_Q10  = psSampleState[ k ][ 0 ].RD_Q10;\n                Winner_ind = k;\n            }\n        }\n\n        /* Increase RD values of expired states */\n        Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];\n        for( k = 0; k < nStatesDelayedDecision; k++ ) {\n            if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {\n                psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );\n                psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );\n                silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );\n            }\n        }\n\n        /* Find worst in first set and best in second set */\n        RDmax_Q10  = psSampleState[ 0 ][ 0 ].RD_Q10;\n        RDmin_Q10  = psSampleState[ 0 ][ 1 ].RD_Q10;\n        RDmax_ind = 0;\n        RDmin_ind = 0;\n        for( k = 1; k < nStatesDelayedDecision; k++ ) {\n            /* find worst in first set */\n            if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {\n                RDmax_Q10  = psSampleState[ k ][ 0 ].RD_Q10;\n                RDmax_ind = k;\n            }\n            /* find best in second set */\n            if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {\n                RDmin_Q10  = psSampleState[ k ][ 1 ].RD_Q10;\n                RDmin_ind = k;\n            }\n        }\n\n        /* Replace a state if best from second set outperforms worst in first set */\n        if( RDmin_Q10 < RDmax_Q10 ) {\n            silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,\n                         ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );\n            silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );\n        }\n\n        /* Write samples from winner to output and long-term filter states */\n        psDD = &psDelDec[ Winner_ind ];\n        if( subfr > 0 || i >= decisionDelay ) {\n            pulses[  i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );\n            xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(\n                silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );\n            NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];\n            sLTP_Q15[          NSQ->sLTP_buf_idx     - decisionDelay ] = psDD->Pred_Q15[  last_smple_idx ];\n        }\n        NSQ->sLTP_shp_buf_idx++;\n        NSQ->sLTP_buf_idx++;\n\n        /* Update states */\n        for( k = 0; k < nStatesDelayedDecision; k++ ) {\n            psDD                                     = &psDelDec[ k ];\n            psSS                                     = &psSampleState[ k ][ 0 ];\n            psDD->LF_AR_Q14                          = psSS->LF_AR_Q14;\n            psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;\n            psDD->Xq_Q14[    *smpl_buf_idx ]         = psSS->xq_Q14;\n            psDD->Q_Q10[     *smpl_buf_idx ]         = psSS->Q_Q10;\n            psDD->Pred_Q15[  *smpl_buf_idx ]         = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );\n            psDD->Shape_Q14[ *smpl_buf_idx ]         = psSS->sLTP_shp_Q14;\n            psDD->Seed                               = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );\n            psDD->RandState[ *smpl_buf_idx ]         = psDD->Seed;\n            psDD->RD_Q10                             = psSS->RD_Q10;\n        }\n        delayedGain_Q10[     *smpl_buf_idx ]         = Gain_Q10;\n    }\n    /* Update LPC states */\n    for( k = 0; k < nStatesDelayedDecision; k++ ) {\n        psDD = &psDelDec[ k ];\n        silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );\n    }\n}\n\n#endif /* __NSQ_DEL_DEC_MIPSR1_H__ */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/mips/macros_mipsr1.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n\n#ifndef __SILK_MACROS_MIPSR1_H__\n#define __SILK_MACROS_MIPSR1_H__\n\n#define mips_clz(x) __builtin_clz(x)\n\n#undef silk_SMULWB\nstatic inline int silk_SMULWB(int a, int b)\n{\n    long long ac;\n    int c;\n\n    ac = __builtin_mips_mult(a, (opus_int32)(opus_int16)b);\n    c = __builtin_mips_extr_w(ac, 16);\n\n    return c;\n}\n\n#undef silk_SMLAWB\n#define silk_SMLAWB(a32, b32, c32)       ((a32) + silk_SMULWB(b32, c32))\n\n#undef silk_SMULWW\nstatic inline int silk_SMULWW(int a, int b)\n{\n    long long ac;\n    int c;\n\n    ac = __builtin_mips_mult(a, b);\n    c = __builtin_mips_extr_w(ac, 16);\n\n    return c;\n}\n\n#undef silk_SMLAWW\nstatic inline int silk_SMLAWW(int a, int b, int c)\n{\n    long long ac;\n    int res;\n\n    ac = __builtin_mips_mult(b, c);\n    res = __builtin_mips_extr_w(ac, 16);\n    res += a;\n\n    return res;\n}\n\n#define OVERRIDE_silk_CLZ16\nstatic inline opus_int32 silk_CLZ16(opus_int16 in16)\n{\n    int re32;\n    opus_int32 in32 = (opus_int32 )in16;\n    re32 = mips_clz(in32);\n    re32-=16;\n    return re32;\n}\n\n#define OVERRIDE_silk_CLZ32\nstatic inline opus_int32 silk_CLZ32(opus_int32 in32)\n{\n    int re32;\n    re32 = mips_clz(in32);\n    return re32;\n}\n\n#endif /* __SILK_MACROS_MIPSR1_H__ */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/mips/sigproc_fix_mipsr1.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_SIGPROC_FIX_MIPSR1_H\n#define SILK_SIGPROC_FIX_MIPSR1_H\n\n#ifdef  __cplusplus\nextern \"C\"\n{\n#endif\n\n#undef silk_SAT16\nstatic inline short int silk_SAT16(int a)\n{\n    int c;\n    c = __builtin_mips_shll_s_w(a, 16);\n    c = c>>16;\n\n    return c;\n}\n\n#undef silk_LSHIFT_SAT32\nstatic inline int silk_LSHIFT_SAT32(int a, int shift)\n{\n    int r;\n\n    r = __builtin_mips_shll_s_w(a, shift);\n\n    return r;\n}\n\n#undef silk_RSHIFT_ROUND\nstatic inline int silk_RSHIFT_ROUND(int a, int shift)\n{\n    int r;\n\n    r = __builtin_mips_shra_r_w(a, shift);\n    return r;\n}\n\n#endif /* SILK_SIGPROC_FIX_MIPSR1_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/pitch_est_defines.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_PE_DEFINES_H\n#define SILK_PE_DEFINES_H\n\n#include \"SigProc_FIX.h\"\n\n/********************************************************/\n/* Definitions for pitch estimator                      */\n/********************************************************/\n\n#define PE_MAX_FS_KHZ               16 /* Maximum sampling frequency used */\n\n#define PE_MAX_NB_SUBFR             4\n#define PE_SUBFR_LENGTH_MS          5   /* 5 ms */\n\n#define PE_LTP_MEM_LENGTH_MS        ( 4 * PE_SUBFR_LENGTH_MS )\n\n#define PE_MAX_FRAME_LENGTH_MS      ( PE_LTP_MEM_LENGTH_MS + PE_MAX_NB_SUBFR * PE_SUBFR_LENGTH_MS )\n#define PE_MAX_FRAME_LENGTH         ( PE_MAX_FRAME_LENGTH_MS * PE_MAX_FS_KHZ )\n#define PE_MAX_FRAME_LENGTH_ST_1    ( PE_MAX_FRAME_LENGTH >> 2 )\n#define PE_MAX_FRAME_LENGTH_ST_2    ( PE_MAX_FRAME_LENGTH >> 1 )\n\n#define PE_MAX_LAG_MS               18           /* 18 ms -> 56 Hz */\n#define PE_MIN_LAG_MS               2            /* 2 ms -> 500 Hz */\n#define PE_MAX_LAG                  ( PE_MAX_LAG_MS * PE_MAX_FS_KHZ )\n#define PE_MIN_LAG                  ( PE_MIN_LAG_MS * PE_MAX_FS_KHZ )\n\n#define PE_D_SRCH_LENGTH            24\n\n#define PE_NB_STAGE3_LAGS           5\n\n#define PE_NB_CBKS_STAGE2           3\n#define PE_NB_CBKS_STAGE2_EXT       11\n\n#define PE_NB_CBKS_STAGE3_MAX       34\n#define PE_NB_CBKS_STAGE3_MID       24\n#define PE_NB_CBKS_STAGE3_MIN       16\n\n#define PE_NB_CBKS_STAGE3_10MS      12\n#define PE_NB_CBKS_STAGE2_10MS      3\n\n#define PE_SHORTLAG_BIAS            0.2f    /* for logarithmic weighting    */\n#define PE_PREVLAG_BIAS             0.2f    /* for logarithmic weighting    */\n#define PE_FLATCONTOUR_BIAS         0.05f\n\n#define SILK_PE_MIN_COMPLEX         0\n#define SILK_PE_MID_COMPLEX         1\n#define SILK_PE_MAX_COMPLEX         2\n\n/* Tables for 20 ms frames */\nextern const opus_int8 silk_CB_lags_stage2[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE2_EXT ];\nextern const opus_int8 silk_CB_lags_stage3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ];\nextern const opus_int8 silk_Lag_range_stage3[ SILK_PE_MAX_COMPLEX + 1 ] [ PE_MAX_NB_SUBFR ][ 2 ];\nextern const opus_int8 silk_nb_cbk_searchs_stage3[ SILK_PE_MAX_COMPLEX + 1 ];\n\n/* Tables for 10 ms frames */\nextern const opus_int8 silk_CB_lags_stage2_10_ms[ PE_MAX_NB_SUBFR >> 1][ 3 ];\nextern const opus_int8 silk_CB_lags_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ 12 ];\nextern const opus_int8 silk_Lag_range_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ 2 ];\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/pitch_est_tables.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"typedef.h\"\n#include \"pitch_est_defines.h\"\n\nconst opus_int8 silk_CB_lags_stage2_10_ms[ PE_MAX_NB_SUBFR >> 1][ PE_NB_CBKS_STAGE2_10MS ] =\n{\n    {0, 1, 0},\n    {0, 0, 1}\n};\n\nconst opus_int8 silk_CB_lags_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ PE_NB_CBKS_STAGE3_10MS ] =\n{\n    { 0, 0, 1,-1, 1,-1, 2,-2, 2,-2, 3,-3},\n    { 0, 1, 0, 1,-1, 2,-1, 2,-2, 3,-2, 3}\n};\n\nconst opus_int8 silk_Lag_range_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ 2 ] =\n{\n    {-3, 7},\n    {-2, 7}\n};\n\nconst opus_int8 silk_CB_lags_stage2[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE2_EXT ] =\n{\n    {0, 2,-1,-1,-1, 0, 0, 1, 1, 0, 1},\n    {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0},\n    {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0},\n    {0,-1, 2, 1, 0, 1, 1, 0, 0,-1,-1}\n};\n\nconst opus_int8 silk_CB_lags_stage3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ] =\n{\n    {0, 0, 1,-1, 0, 1,-1, 0,-1, 1,-2, 2,-2,-2, 2,-3, 2, 3,-3,-4, 3,-4, 4, 4,-5, 5,-6,-5, 6,-7, 6, 5, 8,-9},\n    {0, 0, 1, 0, 0, 0, 0, 0, 0, 0,-1, 1, 0, 0, 1,-1, 0, 1,-1,-1, 1,-1, 2, 1,-1, 2,-2,-2, 2,-2, 2, 2, 3,-3},\n    {0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1,-1, 1, 0, 0, 2, 1,-1, 2,-1,-1, 2,-1, 2, 2,-1, 3,-2,-2,-2, 3},\n    {0, 1, 0, 0, 1, 0, 1,-1, 2,-1, 2,-1, 2, 3,-2, 3,-2,-2, 4, 4,-3, 5,-3,-4, 6,-4, 6, 5,-5, 8,-6,-5,-7, 9}\n};\n\nconst opus_int8 silk_Lag_range_stage3[ SILK_PE_MAX_COMPLEX + 1 ] [ PE_MAX_NB_SUBFR ][ 2 ] =\n{\n    /* Lags to search for low number of stage3 cbks */\n    {\n        {-5,8},\n        {-1,6},\n        {-1,6},\n        {-4,10}\n    },\n    /* Lags to search for middle number of stage3 cbks */\n    {\n        {-6,10},\n        {-2,6},\n        {-1,6},\n        {-5,10}\n    },\n    /* Lags to search for max number of stage3 cbks */\n    {\n        {-9,12},\n        {-3,7},\n        {-2,7},\n        {-7,13}\n    }\n};\n\nconst opus_int8 silk_nb_cbk_searchs_stage3[ SILK_PE_MAX_COMPLEX + 1 ] =\n{\n    PE_NB_CBKS_STAGE3_MIN,\n    PE_NB_CBKS_STAGE3_MID,\n    PE_NB_CBKS_STAGE3_MAX\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/process_NLSFs.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Limit, stabilize, convert and quantize NLSFs */\nvoid silk_process_NLSFs(\n    silk_encoder_state          *psEncC,                            /* I/O  Encoder state                               */\n    opus_int16                  PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ], /* O    Prediction coefficients                     */\n    opus_int16                  pNLSF_Q15[         MAX_LPC_ORDER ], /* I/O  Normalized LSFs (quant out) (0 - (2^15-1))  */\n    const opus_int16            prev_NLSFq_Q15[    MAX_LPC_ORDER ]  /* I    Previous Normalized LSFs (0 - (2^15-1))     */\n)\n{\n    opus_int     i, doInterpolate;\n    opus_int     NLSF_mu_Q20;\n    opus_int32   i_sqr_Q15;\n    opus_int16   pNLSF0_temp_Q15[ MAX_LPC_ORDER ];\n    opus_int16   pNLSFW_QW[ MAX_LPC_ORDER ];\n    opus_int16   pNLSFW0_temp_QW[ MAX_LPC_ORDER ];\n\n    silk_assert( psEncC->speech_activity_Q8 >=   0 );\n    silk_assert( psEncC->speech_activity_Q8 <= SILK_FIX_CONST( 1.0, 8 ) );\n    silk_assert( psEncC->useInterpolatedNLSFs == 1 || psEncC->indices.NLSFInterpCoef_Q2 == ( 1 << 2 ) );\n\n    /***********************/\n    /* Calculate mu values */\n    /***********************/\n    /* NLSF_mu  = 0.003 - 0.0015 * psEnc->speech_activity; */\n    NLSF_mu_Q20 = silk_SMLAWB( SILK_FIX_CONST( 0.003, 20 ), SILK_FIX_CONST( -0.001, 28 ), psEncC->speech_activity_Q8 );\n    if( psEncC->nb_subfr == 2 ) {\n        /* Multiply by 1.5 for 10 ms packets */\n        NLSF_mu_Q20 = silk_ADD_RSHIFT( NLSF_mu_Q20, NLSF_mu_Q20, 1 );\n    }\n\n    silk_assert( NLSF_mu_Q20 >  0 );\n    silk_assert( NLSF_mu_Q20 <= SILK_FIX_CONST( 0.005, 20 ) );\n\n    /* Calculate NLSF weights */\n    silk_NLSF_VQ_weights_laroia( pNLSFW_QW, pNLSF_Q15, psEncC->predictLPCOrder );\n\n    /* Update NLSF weights for interpolated NLSFs */\n    doInterpolate = ( psEncC->useInterpolatedNLSFs == 1 ) && ( psEncC->indices.NLSFInterpCoef_Q2 < 4 );\n    if( doInterpolate ) {\n        /* Calculate the interpolated NLSF vector for the first half */\n        silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15,\n            psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );\n\n        /* Calculate first half NLSF weights for the interpolated NLSFs */\n        silk_NLSF_VQ_weights_laroia( pNLSFW0_temp_QW, pNLSF0_temp_Q15, psEncC->predictLPCOrder );\n\n        /* Update NLSF weights with contribution from first half */\n        i_sqr_Q15 = silk_LSHIFT( silk_SMULBB( psEncC->indices.NLSFInterpCoef_Q2, psEncC->indices.NLSFInterpCoef_Q2 ), 11 );\n        for( i = 0; i < psEncC->predictLPCOrder; i++ ) {\n            pNLSFW_QW[ i ] = silk_SMLAWB( silk_RSHIFT( pNLSFW_QW[ i ], 1 ), (opus_int32)pNLSFW0_temp_QW[ i ], i_sqr_Q15 );\n            silk_assert( pNLSFW_QW[ i ] >= 1 );\n        }\n    }\n\n    silk_NLSF_encode( psEncC->indices.NLSFIndices, pNLSF_Q15, psEncC->psNLSF_CB, pNLSFW_QW,\n        NLSF_mu_Q20, psEncC->NLSF_MSVQ_Survivors, psEncC->indices.signalType );\n\n    /* Convert quantized NLSFs back to LPC coefficients */\n    silk_NLSF2A( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder );\n\n    if( doInterpolate ) {\n        /* Calculate the interpolated, quantized LSF vector for the first half */\n        silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15,\n            psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );\n\n        /* Convert back to LPC coefficients */\n        silk_NLSF2A( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder );\n\n    } else {\n        /* Copy LPC coefficients for first half from second half */\n        silk_memcpy( PredCoef_Q12[ 0 ], PredCoef_Q12[ 1 ], psEncC->predictLPCOrder * sizeof( opus_int16 ) );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/quant_LTP_gains.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"tuning_parameters.h\"\n\nvoid silk_quant_LTP_gains(\n    opus_int16                  B_Q14[ MAX_NB_SUBFR * LTP_ORDER ],          /* I/O  (un)quantized LTP gains         */\n    opus_int8                   cbk_index[ MAX_NB_SUBFR ],                  /* O    Codebook Index                  */\n    opus_int8                   *periodicity_index,                         /* O    Periodicity Index               */\n    opus_int32                  *sum_log_gain_Q7,                           /* I/O  Cumulative max prediction gain  */\n    const opus_int32            W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ],  /* I    Error Weights in Q18            */\n    opus_int                    mu_Q9,                                      /* I    Mu value (R/D tradeoff)         */\n    opus_int                    lowComplexity,                              /* I    Flag for low complexity         */\n    const opus_int              nb_subfr,                                   /* I    number of subframes             */\n    int                         arch                                        /* I    Run-time architecture           */\n)\n{\n    opus_int             j, k, cbk_size;\n    opus_int8            temp_idx[ MAX_NB_SUBFR ];\n    const opus_uint8     *cl_ptr_Q5;\n    const opus_int8      *cbk_ptr_Q7;\n    const opus_uint8     *cbk_gain_ptr_Q7;\n    const opus_int16     *b_Q14_ptr;\n    const opus_int32     *W_Q18_ptr;\n    opus_int32           rate_dist_Q14_subfr, rate_dist_Q14, min_rate_dist_Q14;\n    opus_int32           sum_log_gain_tmp_Q7, best_sum_log_gain_Q7, max_gain_Q7, gain_Q7;\n\n    /***************************************************/\n    /* iterate over different codebooks with different */\n    /* rates/distortions, and choose best */\n    /***************************************************/\n    min_rate_dist_Q14 = silk_int32_MAX;\n    best_sum_log_gain_Q7 = 0;\n    for( k = 0; k < 3; k++ ) {\n        /* Safety margin for pitch gain control, to take into account factors\n           such as state rescaling/rewhitening. */\n        opus_int32 gain_safety = SILK_FIX_CONST( 0.4, 7 );\n\n        cl_ptr_Q5  = silk_LTP_gain_BITS_Q5_ptrs[ k ];\n        cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[        k ];\n        cbk_gain_ptr_Q7 = silk_LTP_vq_gain_ptrs_Q7[ k ];\n        cbk_size   = silk_LTP_vq_sizes[          k ];\n\n        /* Set up pointer to first subframe */\n        W_Q18_ptr = W_Q18;\n        b_Q14_ptr = B_Q14;\n\n        rate_dist_Q14 = 0;\n        sum_log_gain_tmp_Q7 = *sum_log_gain_Q7;\n        for( j = 0; j < nb_subfr; j++ ) {\n            max_gain_Q7 = silk_log2lin( ( SILK_FIX_CONST( MAX_SUM_LOG_GAIN_DB / 6.0, 7 ) - sum_log_gain_tmp_Q7 )\n                                        + SILK_FIX_CONST( 7, 7 ) ) - gain_safety;\n\n            silk_VQ_WMat_EC(\n                &temp_idx[ j ],         /* O    index of best codebook vector                           */\n                &rate_dist_Q14_subfr,   /* O    best weighted quantization error + mu * rate            */\n                &gain_Q7,               /* O    sum of absolute LTP coefficients                        */\n                b_Q14_ptr,              /* I    input vector to be quantized                            */\n                W_Q18_ptr,              /* I    weighting matrix                                        */\n                cbk_ptr_Q7,             /* I    codebook                                                */\n                cbk_gain_ptr_Q7,        /* I    codebook effective gains                                */\n                cl_ptr_Q5,              /* I    code length for each codebook vector                    */\n                mu_Q9,                  /* I    tradeoff between weighted error and rate                */\n                max_gain_Q7,            /* I    maximum sum of absolute LTP coefficients                */\n                cbk_size,               /* I    number of vectors in codebook                           */\n                arch                    /* I    Run-time architecture                                   */\n            );\n\n            rate_dist_Q14 = silk_ADD_POS_SAT32( rate_dist_Q14, rate_dist_Q14_subfr );\n            sum_log_gain_tmp_Q7 = silk_max(0, sum_log_gain_tmp_Q7\n                                + silk_lin2log( gain_safety + gain_Q7 ) - SILK_FIX_CONST( 7, 7 ));\n\n            b_Q14_ptr += LTP_ORDER;\n            W_Q18_ptr += LTP_ORDER * LTP_ORDER;\n        }\n\n        /* Avoid never finding a codebook */\n        rate_dist_Q14 = silk_min( silk_int32_MAX - 1, rate_dist_Q14 );\n\n        if( rate_dist_Q14 < min_rate_dist_Q14 ) {\n            min_rate_dist_Q14 = rate_dist_Q14;\n            *periodicity_index = (opus_int8)k;\n            silk_memcpy( cbk_index, temp_idx, nb_subfr * sizeof( opus_int8 ) );\n            best_sum_log_gain_Q7 = sum_log_gain_tmp_Q7;\n        }\n\n        /* Break early in low-complexity mode if rate distortion is below threshold */\n        if( lowComplexity && ( rate_dist_Q14 < silk_LTP_gain_middle_avg_RD_Q14 ) ) {\n            break;\n        }\n    }\n\n    cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ *periodicity_index ];\n    for( j = 0; j < nb_subfr; j++ ) {\n        for( k = 0; k < LTP_ORDER; k++ ) {\n            B_Q14[ j * LTP_ORDER + k ] = silk_LSHIFT( cbk_ptr_Q7[ cbk_index[ j ] * LTP_ORDER + k ], 7 );\n        }\n    }\n    *sum_log_gain_Q7 = best_sum_log_gain_Q7;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/resampler.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/*\n * Matrix of resampling methods used:\n *                                 Fs_out (kHz)\n *                        8      12     16     24     48\n *\n *               8        C      UF     U      UF     UF\n *              12        AF     C      UF     U      UF\n * Fs_in (kHz)  16        D      AF     C      UF     UF\n *              24        AF     D      AF     C      U\n *              48        AF     AF     AF     D      C\n *\n * C   -> Copy (no resampling)\n * D   -> Allpass-based 2x downsampling\n * U   -> Allpass-based 2x upsampling\n * UF  -> Allpass-based 2x upsampling followed by FIR interpolation\n * AF  -> AR2 filter followed by FIR interpolation\n */\n\n#include \"resampler_private.h\"\n\n/* Tables with delay compensation values to equalize total delay for different modes */\nstatic const opus_int8 delay_matrix_enc[ 5 ][ 3 ] = {\n/* in  \\ out  8  12  16 */\n/*  8 */   {  6,  0,  3 },\n/* 12 */   {  0,  7,  3 },\n/* 16 */   {  0,  1, 10 },\n/* 24 */   {  0,  2,  6 },\n/* 48 */   { 18, 10, 12 }\n};\n\nstatic const opus_int8 delay_matrix_dec[ 3 ][ 5 ] = {\n/* in  \\ out  8  12  16  24  48 */\n/*  8 */   {  4,  0,  2,  0,  0 },\n/* 12 */   {  0,  9,  4,  7,  4 },\n/* 16 */   {  0,  3, 12,  7,  7 }\n};\n\n/* Simple way to make [8000, 12000, 16000, 24000, 48000] to [0, 1, 2, 3, 4] */\n#define rateID(R) ( ( ( ((R)>>12) - ((R)>16000) ) >> ((R)>24000) ) - 1 )\n\n#define USE_silk_resampler_copy                     (0)\n#define USE_silk_resampler_private_up2_HQ_wrapper   (1)\n#define USE_silk_resampler_private_IIR_FIR          (2)\n#define USE_silk_resampler_private_down_FIR         (3)\n\n/* Initialize/reset the resampler state for a given pair of input/output sampling rates */\nopus_int silk_resampler_init(\n    silk_resampler_state_struct *S,                 /* I/O  Resampler state                                             */\n    opus_int32                  Fs_Hz_in,           /* I    Input sampling rate (Hz)                                    */\n    opus_int32                  Fs_Hz_out,          /* I    Output sampling rate (Hz)                                   */\n    opus_int                    forEnc              /* I    If 1: encoder; if 0: decoder                                */\n)\n{\n    opus_int up2x;\n\n    /* Clear state */\n    silk_memset( S, 0, sizeof( silk_resampler_state_struct ) );\n\n    /* Input checking */\n    if( forEnc ) {\n        if( ( Fs_Hz_in  != 8000 && Fs_Hz_in  != 12000 && Fs_Hz_in  != 16000 && Fs_Hz_in  != 24000 && Fs_Hz_in  != 48000 ) ||\n            ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) {\n            silk_assert( 0 );\n            return -1;\n        }\n        S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];\n    } else {\n        if( ( Fs_Hz_in  != 8000 && Fs_Hz_in  != 12000 && Fs_Hz_in  != 16000 ) ||\n            ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) {\n            silk_assert( 0 );\n            return -1;\n        }\n        S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];\n    }\n\n    S->Fs_in_kHz  = silk_DIV32_16( Fs_Hz_in,  1000 );\n    S->Fs_out_kHz = silk_DIV32_16( Fs_Hz_out, 1000 );\n\n    /* Number of samples processed per batch */\n    S->batchSize = S->Fs_in_kHz * RESAMPLER_MAX_BATCH_SIZE_MS;\n\n    /* Find resampler with the right sampling ratio */\n    up2x = 0;\n    if( Fs_Hz_out > Fs_Hz_in ) {\n        /* Upsample */\n        if( Fs_Hz_out == silk_MUL( Fs_Hz_in, 2 ) ) {                            /* Fs_out : Fs_in = 2 : 1 */\n            /* Special case: directly use 2x upsampler */\n            S->resampler_function = USE_silk_resampler_private_up2_HQ_wrapper;\n        } else {\n            /* Default resampler */\n            S->resampler_function = USE_silk_resampler_private_IIR_FIR;\n            up2x = 1;\n        }\n    } else if ( Fs_Hz_out < Fs_Hz_in ) {\n        /* Downsample */\n         S->resampler_function = USE_silk_resampler_private_down_FIR;\n        if( silk_MUL( Fs_Hz_out, 4 ) == silk_MUL( Fs_Hz_in, 3 ) ) {             /* Fs_out : Fs_in = 3 : 4 */\n            S->FIR_Fracs = 3;\n            S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0;\n            S->Coefs = silk_Resampler_3_4_COEFS;\n        } else if( silk_MUL( Fs_Hz_out, 3 ) == silk_MUL( Fs_Hz_in, 2 ) ) {      /* Fs_out : Fs_in = 2 : 3 */\n            S->FIR_Fracs = 2;\n            S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0;\n            S->Coefs = silk_Resampler_2_3_COEFS;\n        } else if( silk_MUL( Fs_Hz_out, 2 ) == Fs_Hz_in ) {                     /* Fs_out : Fs_in = 1 : 2 */\n            S->FIR_Fracs = 1;\n            S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR1;\n            S->Coefs = silk_Resampler_1_2_COEFS;\n        } else if( silk_MUL( Fs_Hz_out, 3 ) == Fs_Hz_in ) {                     /* Fs_out : Fs_in = 1 : 3 */\n            S->FIR_Fracs = 1;\n            S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2;\n            S->Coefs = silk_Resampler_1_3_COEFS;\n        } else if( silk_MUL( Fs_Hz_out, 4 ) == Fs_Hz_in ) {                     /* Fs_out : Fs_in = 1 : 4 */\n            S->FIR_Fracs = 1;\n            S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2;\n            S->Coefs = silk_Resampler_1_4_COEFS;\n        } else if( silk_MUL( Fs_Hz_out, 6 ) == Fs_Hz_in ) {                     /* Fs_out : Fs_in = 1 : 6 */\n            S->FIR_Fracs = 1;\n            S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2;\n            S->Coefs = silk_Resampler_1_6_COEFS;\n        } else {\n            /* None available */\n            silk_assert( 0 );\n            return -1;\n        }\n    } else {\n        /* Input and output sampling rates are equal: copy */\n        S->resampler_function = USE_silk_resampler_copy;\n    }\n\n    /* Ratio of input/output samples */\n    S->invRatio_Q16 = silk_LSHIFT32( silk_DIV32( silk_LSHIFT32( Fs_Hz_in, 14 + up2x ), Fs_Hz_out ), 2 );\n    /* Make sure the ratio is rounded up */\n    while( silk_SMULWW( S->invRatio_Q16, Fs_Hz_out ) < silk_LSHIFT32( Fs_Hz_in, up2x ) ) {\n        S->invRatio_Q16++;\n    }\n\n    return 0;\n}\n\n/* Resampler: convert from one sampling rate to another */\n/* Input and output sampling rate are at most 48000 Hz  */\nopus_int silk_resampler(\n    silk_resampler_state_struct *S,                 /* I/O  Resampler state                                             */\n    opus_int16                  out[],              /* O    Output signal                                               */\n    const opus_int16            in[],               /* I    Input signal                                                */\n    opus_int32                  inLen               /* I    Number of input samples                                     */\n)\n{\n    opus_int nSamples;\n\n    /* Need at least 1 ms of input data */\n    silk_assert( inLen >= S->Fs_in_kHz );\n    /* Delay can't exceed the 1 ms of buffering */\n    silk_assert( S->inputDelay <= S->Fs_in_kHz );\n\n    nSamples = S->Fs_in_kHz - S->inputDelay;\n\n    /* Copy to delay buffer */\n    silk_memcpy( &S->delayBuf[ S->inputDelay ], in, nSamples * sizeof( opus_int16 ) );\n\n    switch( S->resampler_function ) {\n        case USE_silk_resampler_private_up2_HQ_wrapper:\n            silk_resampler_private_up2_HQ_wrapper( S, out, S->delayBuf, S->Fs_in_kHz );\n            silk_resampler_private_up2_HQ_wrapper( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz );\n            break;\n        case USE_silk_resampler_private_IIR_FIR:\n            silk_resampler_private_IIR_FIR( S, out, S->delayBuf, S->Fs_in_kHz );\n            silk_resampler_private_IIR_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz );\n            break;\n        case USE_silk_resampler_private_down_FIR:\n            silk_resampler_private_down_FIR( S, out, S->delayBuf, S->Fs_in_kHz );\n            silk_resampler_private_down_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz );\n            break;\n        default:\n            silk_memcpy( out, S->delayBuf, S->Fs_in_kHz * sizeof( opus_int16 ) );\n            silk_memcpy( &out[ S->Fs_out_kHz ], &in[ nSamples ], ( inLen - S->Fs_in_kHz ) * sizeof( opus_int16 ) );\n    }\n\n    /* Copy to delay buffer */\n    silk_memcpy( S->delayBuf, &in[ inLen - S->inputDelay ], S->inputDelay * sizeof( opus_int16 ) );\n\n    return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/resampler_down2.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n#include \"resampler_rom.h\"\n\n/* Downsample by a factor 2 */\nvoid silk_resampler_down2(\n    opus_int32                  *S,                 /* I/O  State vector [ 2 ]                                          */\n    opus_int16                  *out,               /* O    Output signal [ floor(len/2) ]                              */\n    const opus_int16            *in,                /* I    Input signal [ len ]                                        */\n    opus_int32                  inLen               /* I    Number of input samples                                     */\n)\n{\n    opus_int32 k, len2 = silk_RSHIFT32( inLen, 1 );\n    opus_int32 in32, out32, Y, X;\n\n    silk_assert( silk_resampler_down2_0 > 0 );\n    silk_assert( silk_resampler_down2_1 < 0 );\n\n    /* Internal variables and state are in Q10 format */\n    for( k = 0; k < len2; k++ ) {\n        /* Convert to Q10 */\n        in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 );\n\n        /* All-pass section for even input sample */\n        Y      = silk_SUB32( in32, S[ 0 ] );\n        X      = silk_SMLAWB( Y, Y, silk_resampler_down2_1 );\n        out32  = silk_ADD32( S[ 0 ], X );\n        S[ 0 ] = silk_ADD32( in32, X );\n\n        /* Convert to Q10 */\n        in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 );\n\n        /* All-pass section for odd input sample, and add to output of previous section */\n        Y      = silk_SUB32( in32, S[ 1 ] );\n        X      = silk_SMULWB( Y, silk_resampler_down2_0 );\n        out32  = silk_ADD32( out32, S[ 1 ] );\n        out32  = silk_ADD32( out32, X );\n        S[ 1 ] = silk_ADD32( in32, X );\n\n        /* Add, convert back to int16 and store to output */\n        out[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32, 11 ) );\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/resampler_down2_3.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n#include \"resampler_private.h\"\n#include \"stack_alloc.h\"\n\n#define ORDER_FIR                   4\n\n/* Downsample by a factor 2/3, low quality */\nvoid silk_resampler_down2_3(\n    opus_int32                  *S,                 /* I/O  State vector [ 6 ]                                          */\n    opus_int16                  *out,               /* O    Output signal [ floor(2*inLen/3) ]                          */\n    const opus_int16            *in,                /* I    Input signal [ inLen ]                                      */\n    opus_int32                  inLen               /* I    Number of input samples                                     */\n)\n{\n    opus_int32 nSamplesIn, counter, res_Q6;\n    VARDECL( opus_int32, buf );\n    opus_int32 *buf_ptr;\n    SAVE_STACK;\n\n    ALLOC( buf, RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR, opus_int32 );\n\n    /* Copy buffered samples to start of buffer */\n    silk_memcpy( buf, S, ORDER_FIR * sizeof( opus_int32 ) );\n\n    /* Iterate over blocks of frameSizeIn input samples */\n    while( 1 ) {\n        nSamplesIn = silk_min( inLen, RESAMPLER_MAX_BATCH_SIZE_IN );\n\n        /* Second-order AR filter (output in Q8) */\n        silk_resampler_private_AR2( &S[ ORDER_FIR ], &buf[ ORDER_FIR ], in,\n            silk_Resampler_2_3_COEFS_LQ, nSamplesIn );\n\n        /* Interpolate filtered signal */\n        buf_ptr = buf;\n        counter = nSamplesIn;\n        while( counter > 2 ) {\n            /* Inner product */\n            res_Q6 = silk_SMULWB(         buf_ptr[ 0 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] );\n            res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] );\n            res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] );\n            res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] );\n\n            /* Scale down, saturate and store in output array */\n            *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );\n\n            res_Q6 = silk_SMULWB(         buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] );\n            res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] );\n            res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] );\n            res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] );\n\n            /* Scale down, saturate and store in output array */\n            *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );\n\n            buf_ptr += 3;\n            counter -= 3;\n        }\n\n        in += nSamplesIn;\n        inLen -= nSamplesIn;\n\n        if( inLen > 0 ) {\n            /* More iterations to do; copy last part of filtered signal to beginning of buffer */\n            silk_memcpy( buf, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) );\n        } else {\n            break;\n        }\n    }\n\n    /* Copy last part of filtered signal to the state for the next call */\n    silk_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) );\n    RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/resampler_private.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_RESAMPLER_PRIVATE_H\n#define SILK_RESAMPLER_PRIVATE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"SigProc_FIX.h\"\n#include \"resampler_structs.h\"\n#include \"resampler_rom.h\"\n\n/* Number of input samples to process in the inner loop */\n#define RESAMPLER_MAX_BATCH_SIZE_MS             10\n#define RESAMPLER_MAX_FS_KHZ                    48\n#define RESAMPLER_MAX_BATCH_SIZE_IN             ( RESAMPLER_MAX_BATCH_SIZE_MS * RESAMPLER_MAX_FS_KHZ )\n\n/* Description: Hybrid IIR/FIR polyphase implementation of resampling */\nvoid silk_resampler_private_IIR_FIR(\n    void                            *SS,            /* I/O  Resampler state             */\n    opus_int16                      out[],          /* O    Output signal               */\n    const opus_int16                in[],           /* I    Input signal                */\n    opus_int32                      inLen           /* I    Number of input samples     */\n);\n\n/* Description: Hybrid IIR/FIR polyphase implementation of resampling */\nvoid silk_resampler_private_down_FIR(\n    void                            *SS,            /* I/O  Resampler state             */\n    opus_int16                      out[],          /* O    Output signal               */\n    const opus_int16                in[],           /* I    Input signal                */\n    opus_int32                      inLen           /* I    Number of input samples     */\n);\n\n/* Upsample by a factor 2, high quality */\nvoid silk_resampler_private_up2_HQ_wrapper(\n    void                            *SS,            /* I/O  Resampler state (unused)    */\n    opus_int16                      *out,           /* O    Output signal [ 2 * len ]   */\n    const opus_int16                *in,            /* I    Input signal [ len ]        */\n    opus_int32                      len             /* I    Number of input samples     */\n);\n\n/* Upsample by a factor 2, high quality */\nvoid silk_resampler_private_up2_HQ(\n    opus_int32                      *S,             /* I/O  Resampler state [ 6 ]       */\n    opus_int16                      *out,           /* O    Output signal [ 2 * len ]   */\n    const opus_int16                *in,            /* I    Input signal [ len ]        */\n    opus_int32                      len             /* I    Number of input samples     */\n);\n\n/* Second order AR filter */\nvoid silk_resampler_private_AR2(\n    opus_int32                      S[],            /* I/O  State vector [ 2 ]          */\n    opus_int32                      out_Q8[],       /* O    Output signal               */\n    const opus_int16                in[],           /* I    Input signal                */\n    const opus_int16                A_Q14[],        /* I    AR coefficients, Q14        */\n    opus_int32                      len             /* I    Signal length               */\n);\n\n#ifdef __cplusplus\n}\n#endif\n#endif /* SILK_RESAMPLER_PRIVATE_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/resampler_private_AR2.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n#include \"resampler_private.h\"\n\n/* Second order AR filter with single delay elements */\nvoid silk_resampler_private_AR2(\n    opus_int32                      S[],            /* I/O  State vector [ 2 ]          */\n    opus_int32                      out_Q8[],       /* O    Output signal               */\n    const opus_int16                in[],           /* I    Input signal                */\n    const opus_int16                A_Q14[],        /* I    AR coefficients, Q14        */\n    opus_int32                      len             /* I    Signal length               */\n)\n{\n    opus_int32    k;\n    opus_int32    out32;\n\n    for( k = 0; k < len; k++ ) {\n        out32       = silk_ADD_LSHIFT32( S[ 0 ], (opus_int32)in[ k ], 8 );\n        out_Q8[ k ] = out32;\n        out32       = silk_LSHIFT( out32, 2 );\n        S[ 0 ]      = silk_SMLAWB( S[ 1 ], out32, A_Q14[ 0 ] );\n        S[ 1 ]      = silk_SMULWB( out32, A_Q14[ 1 ] );\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/resampler_private_IIR_FIR.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n#include \"resampler_private.h\"\n#include \"stack_alloc.h\"\n\nstatic OPUS_INLINE opus_int16 *silk_resampler_private_IIR_FIR_INTERPOL(\n    opus_int16  *out,\n    opus_int16  *buf,\n    opus_int32  max_index_Q16,\n    opus_int32  index_increment_Q16\n)\n{\n    opus_int32 index_Q16, res_Q15;\n    opus_int16 *buf_ptr;\n    opus_int32 table_index;\n\n    /* Interpolate upsampled signal and store in output array */\n    for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {\n        table_index = silk_SMULWB( index_Q16 & 0xFFFF, 12 );\n        buf_ptr = &buf[ index_Q16 >> 16 ];\n\n        res_Q15 = silk_SMULBB(          buf_ptr[ 0 ], silk_resampler_frac_FIR_12[      table_index ][ 0 ] );\n        res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 1 ], silk_resampler_frac_FIR_12[      table_index ][ 1 ] );\n        res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 2 ], silk_resampler_frac_FIR_12[      table_index ][ 2 ] );\n        res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 3 ], silk_resampler_frac_FIR_12[      table_index ][ 3 ] );\n        res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 4 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 3 ] );\n        res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 5 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 2 ] );\n        res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 6 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 1 ] );\n        res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 7 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 0 ] );\n        *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q15, 15 ) );\n    }\n    return out;\n}\n/* Upsample using a combination of allpass-based 2x upsampling and FIR interpolation */\nvoid silk_resampler_private_IIR_FIR(\n    void                            *SS,            /* I/O  Resampler state             */\n    opus_int16                      out[],          /* O    Output signal               */\n    const opus_int16                in[],           /* I    Input signal                */\n    opus_int32                      inLen           /* I    Number of input samples     */\n)\n{\n    silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS;\n    opus_int32 nSamplesIn;\n    opus_int32 max_index_Q16, index_increment_Q16;\n    VARDECL( opus_int16, buf );\n    SAVE_STACK;\n\n    ALLOC( buf, 2 * S->batchSize + RESAMPLER_ORDER_FIR_12, opus_int16 );\n\n    /* Copy buffered samples to start of buffer */\n    silk_memcpy( buf, S->sFIR.i16, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );\n\n    /* Iterate over blocks of frameSizeIn input samples */\n    index_increment_Q16 = S->invRatio_Q16;\n    while( 1 ) {\n        nSamplesIn = silk_min( inLen, S->batchSize );\n\n        /* Upsample 2x */\n        silk_resampler_private_up2_HQ( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_12 ], in, nSamplesIn );\n\n        max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 + 1 );         /* + 1 because 2x upsampling */\n        out = silk_resampler_private_IIR_FIR_INTERPOL( out, buf, max_index_Q16, index_increment_Q16 );\n        in += nSamplesIn;\n        inLen -= nSamplesIn;\n\n        if( inLen > 0 ) {\n            /* More iterations to do; copy last part of filtered signal to beginning of buffer */\n            silk_memcpy( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );\n        } else {\n            break;\n        }\n    }\n\n    /* Copy last part of filtered signal to the state for the next call */\n    silk_memcpy( S->sFIR.i16, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );\n    RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/resampler_private_down_FIR.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n#include \"resampler_private.h\"\n#include \"stack_alloc.h\"\n\nstatic OPUS_INLINE opus_int16 *silk_resampler_private_down_FIR_INTERPOL(\n    opus_int16          *out,\n    opus_int32          *buf,\n    const opus_int16    *FIR_Coefs,\n    opus_int            FIR_Order,\n    opus_int            FIR_Fracs,\n    opus_int32          max_index_Q16,\n    opus_int32          index_increment_Q16\n)\n{\n    opus_int32 index_Q16, res_Q6;\n    opus_int32 *buf_ptr;\n    opus_int32 interpol_ind;\n    const opus_int16 *interpol_ptr;\n\n    switch( FIR_Order ) {\n        case RESAMPLER_DOWN_ORDER_FIR0:\n            for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {\n                /* Integer part gives pointer to buffered input */\n                buf_ptr = buf + silk_RSHIFT( index_Q16, 16 );\n\n                /* Fractional part gives interpolation coefficients */\n                interpol_ind = silk_SMULWB( index_Q16 & 0xFFFF, FIR_Fracs );\n\n                /* Inner product */\n                interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR0 / 2 * interpol_ind ];\n                res_Q6 = silk_SMULWB(         buf_ptr[ 0 ], interpol_ptr[ 0 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], interpol_ptr[ 1 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], interpol_ptr[ 2 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], interpol_ptr[ 3 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], interpol_ptr[ 4 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 5 ], interpol_ptr[ 5 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 6 ], interpol_ptr[ 6 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 7 ], interpol_ptr[ 7 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 8 ], interpol_ptr[ 8 ] );\n                interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR0 / 2 * ( FIR_Fracs - 1 - interpol_ind ) ];\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 17 ], interpol_ptr[ 0 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 16 ], interpol_ptr[ 1 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 15 ], interpol_ptr[ 2 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 14 ], interpol_ptr[ 3 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 13 ], interpol_ptr[ 4 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 12 ], interpol_ptr[ 5 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 11 ], interpol_ptr[ 6 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 10 ], interpol_ptr[ 7 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[  9 ], interpol_ptr[ 8 ] );\n\n                /* Scale down, saturate and store in output array */\n                *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );\n            }\n            break;\n        case RESAMPLER_DOWN_ORDER_FIR1:\n            for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {\n                /* Integer part gives pointer to buffered input */\n                buf_ptr = buf + silk_RSHIFT( index_Q16, 16 );\n\n                /* Inner product */\n                res_Q6 = silk_SMULWB(         silk_ADD32( buf_ptr[  0 ], buf_ptr[ 23 ] ), FIR_Coefs[  0 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  1 ], buf_ptr[ 22 ] ), FIR_Coefs[  1 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  2 ], buf_ptr[ 21 ] ), FIR_Coefs[  2 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  3 ], buf_ptr[ 20 ] ), FIR_Coefs[  3 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  4 ], buf_ptr[ 19 ] ), FIR_Coefs[  4 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  5 ], buf_ptr[ 18 ] ), FIR_Coefs[  5 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  6 ], buf_ptr[ 17 ] ), FIR_Coefs[  6 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  7 ], buf_ptr[ 16 ] ), FIR_Coefs[  7 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  8 ], buf_ptr[ 15 ] ), FIR_Coefs[  8 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  9 ], buf_ptr[ 14 ] ), FIR_Coefs[  9 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 10 ], buf_ptr[ 13 ] ), FIR_Coefs[ 10 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 11 ], buf_ptr[ 12 ] ), FIR_Coefs[ 11 ] );\n\n                /* Scale down, saturate and store in output array */\n                *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );\n            }\n            break;\n        case RESAMPLER_DOWN_ORDER_FIR2:\n            for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {\n                /* Integer part gives pointer to buffered input */\n                buf_ptr = buf + silk_RSHIFT( index_Q16, 16 );\n\n                /* Inner product */\n                res_Q6 = silk_SMULWB(         silk_ADD32( buf_ptr[  0 ], buf_ptr[ 35 ] ), FIR_Coefs[  0 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  1 ], buf_ptr[ 34 ] ), FIR_Coefs[  1 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  2 ], buf_ptr[ 33 ] ), FIR_Coefs[  2 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  3 ], buf_ptr[ 32 ] ), FIR_Coefs[  3 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  4 ], buf_ptr[ 31 ] ), FIR_Coefs[  4 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  5 ], buf_ptr[ 30 ] ), FIR_Coefs[  5 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  6 ], buf_ptr[ 29 ] ), FIR_Coefs[  6 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  7 ], buf_ptr[ 28 ] ), FIR_Coefs[  7 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  8 ], buf_ptr[ 27 ] ), FIR_Coefs[  8 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  9 ], buf_ptr[ 26 ] ), FIR_Coefs[  9 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 10 ], buf_ptr[ 25 ] ), FIR_Coefs[ 10 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 11 ], buf_ptr[ 24 ] ), FIR_Coefs[ 11 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 12 ], buf_ptr[ 23 ] ), FIR_Coefs[ 12 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 13 ], buf_ptr[ 22 ] ), FIR_Coefs[ 13 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 14 ], buf_ptr[ 21 ] ), FIR_Coefs[ 14 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 15 ], buf_ptr[ 20 ] ), FIR_Coefs[ 15 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 16 ], buf_ptr[ 19 ] ), FIR_Coefs[ 16 ] );\n                res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 17 ], buf_ptr[ 18 ] ), FIR_Coefs[ 17 ] );\n\n                /* Scale down, saturate and store in output array */\n                *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );\n            }\n            break;\n        default:\n            silk_assert( 0 );\n    }\n    return out;\n}\n\n/* Resample with a 2nd order AR filter followed by FIR interpolation */\nvoid silk_resampler_private_down_FIR(\n    void                            *SS,            /* I/O  Resampler state             */\n    opus_int16                      out[],          /* O    Output signal               */\n    const opus_int16                in[],           /* I    Input signal                */\n    opus_int32                      inLen           /* I    Number of input samples     */\n)\n{\n    silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS;\n    opus_int32 nSamplesIn;\n    opus_int32 max_index_Q16, index_increment_Q16;\n    VARDECL( opus_int32, buf );\n    const opus_int16 *FIR_Coefs;\n    SAVE_STACK;\n\n    ALLOC( buf, S->batchSize + S->FIR_Order, opus_int32 );\n\n    /* Copy buffered samples to start of buffer */\n    silk_memcpy( buf, S->sFIR.i32, S->FIR_Order * sizeof( opus_int32 ) );\n\n    FIR_Coefs = &S->Coefs[ 2 ];\n\n    /* Iterate over blocks of frameSizeIn input samples */\n    index_increment_Q16 = S->invRatio_Q16;\n    while( 1 ) {\n        nSamplesIn = silk_min( inLen, S->batchSize );\n\n        /* Second-order AR filter (output in Q8) */\n        silk_resampler_private_AR2( S->sIIR, &buf[ S->FIR_Order ], in, S->Coefs, nSamplesIn );\n\n        max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 );\n\n        /* Interpolate filtered signal */\n        out = silk_resampler_private_down_FIR_INTERPOL( out, buf, FIR_Coefs, S->FIR_Order,\n            S->FIR_Fracs, max_index_Q16, index_increment_Q16 );\n\n        in += nSamplesIn;\n        inLen -= nSamplesIn;\n\n        if( inLen > 1 ) {\n            /* More iterations to do; copy last part of filtered signal to beginning of buffer */\n            silk_memcpy( buf, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) );\n        } else {\n            break;\n        }\n    }\n\n    /* Copy last part of filtered signal to the state for the next call */\n    silk_memcpy( S->sFIR.i32, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) );\n    RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/resampler_private_up2_HQ.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n#include \"resampler_private.h\"\n\n/* Upsample by a factor 2, high quality */\n/* Uses 2nd order allpass filters for the 2x upsampling, followed by a      */\n/* notch filter just above Nyquist.                                         */\nvoid silk_resampler_private_up2_HQ(\n    opus_int32                      *S,             /* I/O  Resampler state [ 6 ]       */\n    opus_int16                      *out,           /* O    Output signal [ 2 * len ]   */\n    const opus_int16                *in,            /* I    Input signal [ len ]        */\n    opus_int32                      len             /* I    Number of input samples     */\n)\n{\n    opus_int32 k;\n    opus_int32 in32, out32_1, out32_2, Y, X;\n\n    silk_assert( silk_resampler_up2_hq_0[ 0 ] > 0 );\n    silk_assert( silk_resampler_up2_hq_0[ 1 ] > 0 );\n    silk_assert( silk_resampler_up2_hq_0[ 2 ] < 0 );\n    silk_assert( silk_resampler_up2_hq_1[ 0 ] > 0 );\n    silk_assert( silk_resampler_up2_hq_1[ 1 ] > 0 );\n    silk_assert( silk_resampler_up2_hq_1[ 2 ] < 0 );\n\n    /* Internal variables and state are in Q10 format */\n    for( k = 0; k < len; k++ ) {\n        /* Convert to Q10 */\n        in32 = silk_LSHIFT( (opus_int32)in[ k ], 10 );\n\n        /* First all-pass section for even output sample */\n        Y       = silk_SUB32( in32, S[ 0 ] );\n        X       = silk_SMULWB( Y, silk_resampler_up2_hq_0[ 0 ] );\n        out32_1 = silk_ADD32( S[ 0 ], X );\n        S[ 0 ]  = silk_ADD32( in32, X );\n\n        /* Second all-pass section for even output sample */\n        Y       = silk_SUB32( out32_1, S[ 1 ] );\n        X       = silk_SMULWB( Y, silk_resampler_up2_hq_0[ 1 ] );\n        out32_2 = silk_ADD32( S[ 1 ], X );\n        S[ 1 ]  = silk_ADD32( out32_1, X );\n\n        /* Third all-pass section for even output sample */\n        Y       = silk_SUB32( out32_2, S[ 2 ] );\n        X       = silk_SMLAWB( Y, Y, silk_resampler_up2_hq_0[ 2 ] );\n        out32_1 = silk_ADD32( S[ 2 ], X );\n        S[ 2 ]  = silk_ADD32( out32_2, X );\n\n        /* Apply gain in Q15, convert back to int16 and store to output */\n        out[ 2 * k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32_1, 10 ) );\n\n        /* First all-pass section for odd output sample */\n        Y       = silk_SUB32( in32, S[ 3 ] );\n        X       = silk_SMULWB( Y, silk_resampler_up2_hq_1[ 0 ] );\n        out32_1 = silk_ADD32( S[ 3 ], X );\n        S[ 3 ]  = silk_ADD32( in32, X );\n\n        /* Second all-pass section for odd output sample */\n        Y       = silk_SUB32( out32_1, S[ 4 ] );\n        X       = silk_SMULWB( Y, silk_resampler_up2_hq_1[ 1 ] );\n        out32_2 = silk_ADD32( S[ 4 ], X );\n        S[ 4 ]  = silk_ADD32( out32_1, X );\n\n        /* Third all-pass section for odd output sample */\n        Y       = silk_SUB32( out32_2, S[ 5 ] );\n        X       = silk_SMLAWB( Y, Y, silk_resampler_up2_hq_1[ 2 ] );\n        out32_1 = silk_ADD32( S[ 5 ], X );\n        S[ 5 ]  = silk_ADD32( out32_2, X );\n\n        /* Apply gain in Q15, convert back to int16 and store to output */\n        out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32_1, 10 ) );\n    }\n}\n\nvoid silk_resampler_private_up2_HQ_wrapper(\n    void                            *SS,            /* I/O  Resampler state (unused)    */\n    opus_int16                      *out,           /* O    Output signal [ 2 * len ]   */\n    const opus_int16                *in,            /* I    Input signal [ len ]        */\n    opus_int32                      len             /* I    Number of input samples     */\n)\n{\n    silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS;\n    silk_resampler_private_up2_HQ( S->sIIR, out, in, len );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/resampler_rom.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* Filter coefficients for IIR/FIR polyphase resampling     *\n * Total size: 179 Words (358 Bytes)                        */\n\n#include \"resampler_private.h\"\n\n/* Matlab code for the notch filter coefficients: */\n/* B = [1, 0.147, 1];  A = [1, 0.107, 0.89]; G = 0.93; freqz(G * B, A, 2^14, 16e3); axis([0, 8000, -10, 1]) */\n/* fprintf('\\t%6d, %6d, %6d, %6d\\n', round(B(2)*2^16), round(-A(2)*2^16), round((1-A(3))*2^16), round(G*2^15)) */\n/* const opus_int16 silk_resampler_up2_hq_notch[ 4 ] = { 9634,  -7012,   7209,  30474 }; */\n\n/* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */\nsilk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = {\n    -20694, -13867,\n       -49,     64,     17,   -157,    353,   -496,    163,  11047,  22205,\n       -39,      6,     91,   -170,    186,     23,   -896,   6336,  19928,\n       -19,    -36,    102,    -89,    -24,    328,   -951,   2568,  15909,\n};\n\nsilk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = {\n    -14457, -14019,\n        64,    128,   -122,     36,    310,   -768,    584,   9267,  17733,\n        12,    128,     18,   -142,    288,   -117,   -865,   4123,  14459,\n};\n\nsilk_DWORD_ALIGN const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ] = {\n       616, -14323,\n       -10,     39,     58,    -46,    -84,    120,    184,   -315,   -541,   1284,   5380,   9024,\n};\n\nsilk_DWORD_ALIGN const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {\n     16102, -15162,\n       -13,      0,     20,     26,      5,    -31,    -43,     -4,     65,     90,      7,   -157,   -248,    -44,    593,   1583,   2612,   3271,\n};\n\nsilk_DWORD_ALIGN const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {\n     22500, -15099,\n         3,    -14,    -20,    -15,      2,     25,     37,     25,    -16,    -71,   -107,    -79,     50,    292,    623,    982,   1288,   1464,\n};\n\nsilk_DWORD_ALIGN const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {\n     27540, -15257,\n        17,     12,      8,      1,    -10,    -22,    -30,    -32,    -22,      3,     44,    100,    168,    243,    317,    381,    429,    455,\n};\n\nsilk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = {\n     -2797,  -6507,\n      4697,  10739,\n      1567,   8276,\n};\n\n/* Table with interplation fractions of 1/24, 3/24, 5/24, ... , 23/24 : 23/24 (46 Words) */\nsilk_DWORD_ALIGN const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ] = {\n    {  189,  -600,   617, 30567 },\n    {  117,  -159, -1070, 29704 },\n    {   52,   221, -2392, 28276 },\n    {   -4,   529, -3350, 26341 },\n    {  -48,   758, -3956, 23973 },\n    {  -80,   905, -4235, 21254 },\n    {  -99,   972, -4222, 18278 },\n    { -107,   967, -3957, 15143 },\n    { -103,   896, -3487, 11950 },\n    {  -91,   773, -2865,  8798 },\n    {  -71,   611, -2143,  5784 },\n    {  -46,   425, -1375,  2996 },\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/resampler_rom.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_FIX_RESAMPLER_ROM_H\n#define SILK_FIX_RESAMPLER_ROM_H\n\n#ifdef  __cplusplus\nextern \"C\"\n{\n#endif\n\n#include \"typedef.h\"\n#include \"resampler_structs.h\"\n\n#define RESAMPLER_DOWN_ORDER_FIR0               18\n#define RESAMPLER_DOWN_ORDER_FIR1               24\n#define RESAMPLER_DOWN_ORDER_FIR2               36\n#define RESAMPLER_ORDER_FIR_12                  8\n\n/* Tables for 2x downsampler */\nstatic const opus_int16 silk_resampler_down2_0 = 9872;\nstatic const opus_int16 silk_resampler_down2_1 = 39809 - 65536;\n\n/* Tables for 2x upsampler, high quality */\nstatic const opus_int16 silk_resampler_up2_hq_0[ 3 ] = { 1746, 14986, 39083 - 65536 };\nstatic const opus_int16 silk_resampler_up2_hq_1[ 3 ] = { 6854, 25769, 55542 - 65536 };\n\n/* Tables with IIR and FIR coefficients for fractional downsamplers */\nextern const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ];\nextern const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ];\nextern const opus_int16 silk_Resampler_1_2_COEFS[ 2 +     RESAMPLER_DOWN_ORDER_FIR1 / 2 ];\nextern const opus_int16 silk_Resampler_1_3_COEFS[ 2 +     RESAMPLER_DOWN_ORDER_FIR2 / 2 ];\nextern const opus_int16 silk_Resampler_1_4_COEFS[ 2 +     RESAMPLER_DOWN_ORDER_FIR2 / 2 ];\nextern const opus_int16 silk_Resampler_1_6_COEFS[ 2 +     RESAMPLER_DOWN_ORDER_FIR2 / 2 ];\nextern const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ];\n\n/* Table with interplation fractions of 1/24, 3/24, ..., 23/24 */\nextern const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ];\n\n#ifdef  __cplusplus\n}\n#endif\n\n#endif /* SILK_FIX_RESAMPLER_ROM_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/resampler_structs.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_RESAMPLER_STRUCTS_H\n#define SILK_RESAMPLER_STRUCTS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define SILK_RESAMPLER_MAX_FIR_ORDER                 36\n#define SILK_RESAMPLER_MAX_IIR_ORDER                 6\n\ntypedef struct _silk_resampler_state_struct{\n    opus_int32       sIIR[ SILK_RESAMPLER_MAX_IIR_ORDER ]; /* this must be the first element of this struct */\n    union{\n        opus_int32   i32[ SILK_RESAMPLER_MAX_FIR_ORDER ];\n        opus_int16   i16[ SILK_RESAMPLER_MAX_FIR_ORDER ];\n    }                sFIR;\n    opus_int16       delayBuf[ 48 ];\n    opus_int         resampler_function;\n    opus_int         batchSize;\n    opus_int32       invRatio_Q16;\n    opus_int         FIR_Order;\n    opus_int         FIR_Fracs;\n    opus_int         Fs_in_kHz;\n    opus_int         Fs_out_kHz;\n    opus_int         inputDelay;\n    const opus_int16 *Coefs;\n} silk_resampler_state_struct;\n\n#ifdef __cplusplus\n}\n#endif\n#endif /* SILK_RESAMPLER_STRUCTS_H */\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/shell_coder.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* shell coder; pulse-subframe length is hardcoded */\n\nstatic OPUS_INLINE void combine_pulses(\n    opus_int         *out,   /* O    combined pulses vector [len] */\n    const opus_int   *in,    /* I    input vector       [2 * len] */\n    const opus_int   len     /* I    number of OUTPUT samples     */\n)\n{\n    opus_int k;\n    for( k = 0; k < len; k++ ) {\n        out[ k ] = in[ 2 * k ] + in[ 2 * k + 1 ];\n    }\n}\n\nstatic OPUS_INLINE void encode_split(\n    ec_enc                      *psRangeEnc,    /* I/O  compressor data structure                   */\n    const opus_int              p_child1,       /* I    pulse amplitude of first child subframe     */\n    const opus_int              p,              /* I    pulse amplitude of current subframe         */\n    const opus_uint8            *shell_table    /* I    table of shell cdfs                         */\n)\n{\n    if( p > 0 ) {\n        ec_enc_icdf( psRangeEnc, p_child1, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 );\n    }\n}\n\nstatic OPUS_INLINE void decode_split(\n    opus_int16                  *p_child1,      /* O    pulse amplitude of first child subframe     */\n    opus_int16                  *p_child2,      /* O    pulse amplitude of second child subframe    */\n    ec_dec                      *psRangeDec,    /* I/O  Compressor data structure                   */\n    const opus_int              p,              /* I    pulse amplitude of current subframe         */\n    const opus_uint8            *shell_table    /* I    table of shell cdfs                         */\n)\n{\n    if( p > 0 ) {\n        p_child1[ 0 ] = ec_dec_icdf( psRangeDec, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 );\n        p_child2[ 0 ] = p - p_child1[ 0 ];\n    } else {\n        p_child1[ 0 ] = 0;\n        p_child2[ 0 ] = 0;\n    }\n}\n\n/* Shell encoder, operates on one shell code frame of 16 pulses */\nvoid silk_shell_encoder(\n    ec_enc                      *psRangeEnc,                    /* I/O  compressor data structure                   */\n    const opus_int              *pulses0                        /* I    data: nonnegative pulse amplitudes          */\n)\n{\n    opus_int pulses1[ 8 ], pulses2[ 4 ], pulses3[ 2 ], pulses4[ 1 ];\n\n    /* this function operates on one shell code frame of 16 pulses */\n    silk_assert( SHELL_CODEC_FRAME_LENGTH == 16 );\n\n    /* tree representation per pulse-subframe */\n    combine_pulses( pulses1, pulses0, 8 );\n    combine_pulses( pulses2, pulses1, 4 );\n    combine_pulses( pulses3, pulses2, 2 );\n    combine_pulses( pulses4, pulses3, 1 );\n\n    encode_split( psRangeEnc, pulses3[  0 ], pulses4[ 0 ], silk_shell_code_table3 );\n\n    encode_split( psRangeEnc, pulses2[  0 ], pulses3[ 0 ], silk_shell_code_table2 );\n\n    encode_split( psRangeEnc, pulses1[  0 ], pulses2[ 0 ], silk_shell_code_table1 );\n    encode_split( psRangeEnc, pulses0[  0 ], pulses1[ 0 ], silk_shell_code_table0 );\n    encode_split( psRangeEnc, pulses0[  2 ], pulses1[ 1 ], silk_shell_code_table0 );\n\n    encode_split( psRangeEnc, pulses1[  2 ], pulses2[ 1 ], silk_shell_code_table1 );\n    encode_split( psRangeEnc, pulses0[  4 ], pulses1[ 2 ], silk_shell_code_table0 );\n    encode_split( psRangeEnc, pulses0[  6 ], pulses1[ 3 ], silk_shell_code_table0 );\n\n    encode_split( psRangeEnc, pulses2[  2 ], pulses3[ 1 ], silk_shell_code_table2 );\n\n    encode_split( psRangeEnc, pulses1[  4 ], pulses2[ 2 ], silk_shell_code_table1 );\n    encode_split( psRangeEnc, pulses0[  8 ], pulses1[ 4 ], silk_shell_code_table0 );\n    encode_split( psRangeEnc, pulses0[ 10 ], pulses1[ 5 ], silk_shell_code_table0 );\n\n    encode_split( psRangeEnc, pulses1[  6 ], pulses2[ 3 ], silk_shell_code_table1 );\n    encode_split( psRangeEnc, pulses0[ 12 ], pulses1[ 6 ], silk_shell_code_table0 );\n    encode_split( psRangeEnc, pulses0[ 14 ], pulses1[ 7 ], silk_shell_code_table0 );\n}\n\n\n/* Shell decoder, operates on one shell code frame of 16 pulses */\nvoid silk_shell_decoder(\n    opus_int16                  *pulses0,                       /* O    data: nonnegative pulse amplitudes          */\n    ec_dec                      *psRangeDec,                    /* I/O  Compressor data structure                   */\n    const opus_int              pulses4                         /* I    number of pulses per pulse-subframe         */\n)\n{\n    opus_int16 pulses3[ 2 ], pulses2[ 4 ], pulses1[ 8 ];\n\n    /* this function operates on one shell code frame of 16 pulses */\n    silk_assert( SHELL_CODEC_FRAME_LENGTH == 16 );\n\n    decode_split( &pulses3[  0 ], &pulses3[  1 ], psRangeDec, pulses4,      silk_shell_code_table3 );\n\n    decode_split( &pulses2[  0 ], &pulses2[  1 ], psRangeDec, pulses3[ 0 ], silk_shell_code_table2 );\n\n    decode_split( &pulses1[  0 ], &pulses1[  1 ], psRangeDec, pulses2[ 0 ], silk_shell_code_table1 );\n    decode_split( &pulses0[  0 ], &pulses0[  1 ], psRangeDec, pulses1[ 0 ], silk_shell_code_table0 );\n    decode_split( &pulses0[  2 ], &pulses0[  3 ], psRangeDec, pulses1[ 1 ], silk_shell_code_table0 );\n\n    decode_split( &pulses1[  2 ], &pulses1[  3 ], psRangeDec, pulses2[ 1 ], silk_shell_code_table1 );\n    decode_split( &pulses0[  4 ], &pulses0[  5 ], psRangeDec, pulses1[ 2 ], silk_shell_code_table0 );\n    decode_split( &pulses0[  6 ], &pulses0[  7 ], psRangeDec, pulses1[ 3 ], silk_shell_code_table0 );\n\n    decode_split( &pulses2[  2 ], &pulses2[  3 ], psRangeDec, pulses3[ 1 ], silk_shell_code_table2 );\n\n    decode_split( &pulses1[  4 ], &pulses1[  5 ], psRangeDec, pulses2[ 2 ], silk_shell_code_table1 );\n    decode_split( &pulses0[  8 ], &pulses0[  9 ], psRangeDec, pulses1[ 4 ], silk_shell_code_table0 );\n    decode_split( &pulses0[ 10 ], &pulses0[ 11 ], psRangeDec, pulses1[ 5 ], silk_shell_code_table0 );\n\n    decode_split( &pulses1[  6 ], &pulses1[  7 ], psRangeDec, pulses2[ 3 ], silk_shell_code_table1 );\n    decode_split( &pulses0[ 12 ], &pulses0[ 13 ], psRangeDec, pulses1[ 6 ], silk_shell_code_table0 );\n    decode_split( &pulses0[ 14 ], &pulses0[ 15 ], psRangeDec, pulses1[ 7 ], silk_shell_code_table0 );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/sigm_Q15.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* Approximate sigmoid function */\n\n#include \"SigProc_FIX.h\"\n\n/* fprintf(1, '%d, ', round(1024 * ([1 ./ (1 + exp(-(1:5))), 1] - 1 ./ (1 + exp(-(0:5)))))); */\nstatic const opus_int32 sigm_LUT_slope_Q10[ 6 ] = {\n    237, 153, 73, 30, 12, 7\n};\n/* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp(-(0:5))))); */\nstatic const opus_int32 sigm_LUT_pos_Q15[ 6 ] = {\n    16384, 23955, 28861, 31213, 32178, 32548\n};\n/* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp((0:5))))); */\nstatic const opus_int32 sigm_LUT_neg_Q15[ 6 ] = {\n    16384, 8812, 3906, 1554, 589, 219\n};\n\nopus_int silk_sigm_Q15(\n    opus_int                    in_Q5               /* I                                                                */\n)\n{\n    opus_int ind;\n\n    if( in_Q5 < 0 ) {\n        /* Negative input */\n        in_Q5 = -in_Q5;\n        if( in_Q5 >= 6 * 32 ) {\n            return 0;        /* Clip */\n        } else {\n            /* Linear interpolation of look up table */\n            ind = silk_RSHIFT( in_Q5, 5 );\n            return( sigm_LUT_neg_Q15[ ind ] - silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) );\n        }\n    } else {\n        /* Positive input */\n        if( in_Q5 >= 6 * 32 ) {\n            return 32767;        /* clip */\n        } else {\n            /* Linear interpolation of look up table */\n            ind = silk_RSHIFT( in_Q5, 5 );\n            return( sigm_LUT_pos_Q15[ ind ] + silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) );\n        }\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/sort.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* Insertion sort (fast for already almost sorted arrays):   */\n/* Best case:  O(n)   for an already sorted array            */\n/* Worst case: O(n^2) for an inversely sorted array          */\n/*                                                           */\n/* Shell short:    http://en.wikipedia.org/wiki/Shell_sort   */\n\n#include \"SigProc_FIX.h\"\n\nvoid silk_insertion_sort_increasing(\n    opus_int32           *a,             /* I/O   Unsorted / Sorted vector               */\n    opus_int             *idx,           /* O     Index vector for the sorted elements   */\n    const opus_int       L,              /* I     Vector length                          */\n    const opus_int       K               /* I     Number of correctly sorted positions   */\n)\n{\n    opus_int32    value;\n    opus_int        i, j;\n\n    /* Safety checks */\n    silk_assert( K >  0 );\n    silk_assert( L >  0 );\n    silk_assert( L >= K );\n\n    /* Write start indices in index vector */\n    for( i = 0; i < K; i++ ) {\n        idx[ i ] = i;\n    }\n\n    /* Sort vector elements by value, increasing order */\n    for( i = 1; i < K; i++ ) {\n        value = a[ i ];\n        for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) {\n            a[ j + 1 ]   = a[ j ];       /* Shift value */\n            idx[ j + 1 ] = idx[ j ];     /* Shift index */\n        }\n        a[ j + 1 ]   = value;   /* Write value */\n        idx[ j + 1 ] = i;       /* Write index */\n    }\n\n    /* If less than L values are asked for, check the remaining values, */\n    /* but only spend CPU to ensure that the K first values are correct */\n    for( i = K; i < L; i++ ) {\n        value = a[ i ];\n        if( value < a[ K - 1 ] ) {\n            for( j = K - 2; ( j >= 0 ) && ( value < a[ j ] ); j-- ) {\n                a[ j + 1 ]   = a[ j ];       /* Shift value */\n                idx[ j + 1 ] = idx[ j ];     /* Shift index */\n            }\n            a[ j + 1 ]   = value;   /* Write value */\n            idx[ j + 1 ] = i;       /* Write index */\n        }\n    }\n}\n\n#ifdef FIXED_POINT\n/* This function is only used by the fixed-point build */\nvoid silk_insertion_sort_decreasing_int16(\n    opus_int16                  *a,                 /* I/O   Unsorted / Sorted vector                                   */\n    opus_int                    *idx,               /* O     Index vector for the sorted elements                       */\n    const opus_int              L,                  /* I     Vector length                                              */\n    const opus_int              K                   /* I     Number of correctly sorted positions                       */\n)\n{\n    opus_int i, j;\n    opus_int value;\n\n    /* Safety checks */\n    silk_assert( K >  0 );\n    silk_assert( L >  0 );\n    silk_assert( L >= K );\n\n    /* Write start indices in index vector */\n    for( i = 0; i < K; i++ ) {\n        idx[ i ] = i;\n    }\n\n    /* Sort vector elements by value, decreasing order */\n    for( i = 1; i < K; i++ ) {\n        value = a[ i ];\n        for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) {\n            a[ j + 1 ]   = a[ j ];     /* Shift value */\n            idx[ j + 1 ] = idx[ j ];   /* Shift index */\n        }\n        a[ j + 1 ]   = value;   /* Write value */\n        idx[ j + 1 ] = i;       /* Write index */\n    }\n\n    /* If less than L values are asked for, check the remaining values, */\n    /* but only spend CPU to ensure that the K first values are correct */\n    for( i = K; i < L; i++ ) {\n        value = a[ i ];\n        if( value > a[ K - 1 ] ) {\n            for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) {\n                a[ j + 1 ]   = a[ j ];     /* Shift value */\n                idx[ j + 1 ] = idx[ j ];   /* Shift index */\n            }\n            a[ j + 1 ]   = value;   /* Write value */\n            idx[ j + 1 ] = i;       /* Write index */\n        }\n    }\n}\n#endif\n\nvoid silk_insertion_sort_increasing_all_values_int16(\n     opus_int16                 *a,                 /* I/O   Unsorted / Sorted vector                                   */\n     const opus_int             L                   /* I     Vector length                                              */\n)\n{\n    opus_int    value;\n    opus_int    i, j;\n\n    /* Safety checks */\n    silk_assert( L >  0 );\n\n    /* Sort vector elements by value, increasing order */\n    for( i = 1; i < L; i++ ) {\n        value = a[ i ];\n        for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) {\n            a[ j + 1 ] = a[ j ]; /* Shift value */\n        }\n        a[ j + 1 ] = value; /* Write value */\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/stereo_LR_to_MS.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n#include \"stack_alloc.h\"\n\n/* Convert Left/Right stereo signal to adaptive Mid/Side representation */\nvoid silk_stereo_LR_to_MS(\n    stereo_enc_state            *state,                         /* I/O  State                                       */\n    opus_int16                  x1[],                           /* I/O  Left input signal, becomes mid signal       */\n    opus_int16                  x2[],                           /* I/O  Right input signal, becomes side signal     */\n    opus_int8                   ix[ 2 ][ 3 ],                   /* O    Quantization indices                        */\n    opus_int8                   *mid_only_flag,                 /* O    Flag: only mid signal coded                 */\n    opus_int32                  mid_side_rates_bps[],           /* O    Bitrates for mid and side signals           */\n    opus_int32                  total_rate_bps,                 /* I    Total bitrate                               */\n    opus_int                    prev_speech_act_Q8,             /* I    Speech activity level in previous frame     */\n    opus_int                    toMono,                         /* I    Last frame before a stereo->mono transition */\n    opus_int                    fs_kHz,                         /* I    Sample rate (kHz)                           */\n    opus_int                    frame_length                    /* I    Number of samples                           */\n)\n{\n    opus_int   n, is10msFrame, denom_Q16, delta0_Q13, delta1_Q13;\n    opus_int32 sum, diff, smooth_coef_Q16, pred_Q13[ 2 ], pred0_Q13, pred1_Q13;\n    opus_int32 LP_ratio_Q14, HP_ratio_Q14, frac_Q16, frac_3_Q16, min_mid_rate_bps, width_Q14, w_Q24, deltaw_Q24;\n    VARDECL( opus_int16, side );\n    VARDECL( opus_int16, LP_mid );\n    VARDECL( opus_int16, HP_mid );\n    VARDECL( opus_int16, LP_side );\n    VARDECL( opus_int16, HP_side );\n    opus_int16 *mid = &x1[ -2 ];\n    SAVE_STACK;\n\n    ALLOC( side, frame_length + 2, opus_int16 );\n    /* Convert to basic mid/side signals */\n    for( n = 0; n < frame_length + 2; n++ ) {\n        sum  = x1[ n - 2 ] + (opus_int32)x2[ n - 2 ];\n        diff = x1[ n - 2 ] - (opus_int32)x2[ n - 2 ];\n        mid[  n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 );\n        side[ n ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( diff, 1 ) );\n    }\n\n    /* Buffering */\n    silk_memcpy( mid,  state->sMid,  2 * sizeof( opus_int16 ) );\n    silk_memcpy( side, state->sSide, 2 * sizeof( opus_int16 ) );\n    silk_memcpy( state->sMid,  &mid[  frame_length ], 2 * sizeof( opus_int16 ) );\n    silk_memcpy( state->sSide, &side[ frame_length ], 2 * sizeof( opus_int16 ) );\n\n    /* LP and HP filter mid signal */\n    ALLOC( LP_mid, frame_length, opus_int16 );\n    ALLOC( HP_mid, frame_length, opus_int16 );\n    for( n = 0; n < frame_length; n++ ) {\n        sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 );\n        LP_mid[ n ] = sum;\n        HP_mid[ n ] = mid[ n + 1 ] - sum;\n    }\n\n    /* LP and HP filter side signal */\n    ALLOC( LP_side, frame_length, opus_int16 );\n    ALLOC( HP_side, frame_length, opus_int16 );\n    for( n = 0; n < frame_length; n++ ) {\n        sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + side[ n + 2 ], side[ n + 1 ], 1 ), 2 );\n        LP_side[ n ] = sum;\n        HP_side[ n ] = side[ n + 1 ] - sum;\n    }\n\n    /* Find energies and predictors */\n    is10msFrame = frame_length == 10 * fs_kHz;\n    smooth_coef_Q16 = is10msFrame ?\n        SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF / 2, 16 ) :\n        SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF,     16 );\n    smooth_coef_Q16 = silk_SMULWB( silk_SMULBB( prev_speech_act_Q8, prev_speech_act_Q8 ), smooth_coef_Q16 );\n\n    pred_Q13[ 0 ] = silk_stereo_find_predictor( &LP_ratio_Q14, LP_mid, LP_side, &state->mid_side_amp_Q0[ 0 ], frame_length, smooth_coef_Q16 );\n    pred_Q13[ 1 ] = silk_stereo_find_predictor( &HP_ratio_Q14, HP_mid, HP_side, &state->mid_side_amp_Q0[ 2 ], frame_length, smooth_coef_Q16 );\n    /* Ratio of the norms of residual and mid signals */\n    frac_Q16 = silk_SMLABB( HP_ratio_Q14, LP_ratio_Q14, 3 );\n    frac_Q16 = silk_min( frac_Q16, SILK_FIX_CONST( 1, 16 ) );\n\n    /* Determine bitrate distribution between mid and side, and possibly reduce stereo width */\n    total_rate_bps -= is10msFrame ? 1200 : 600;      /* Subtract approximate bitrate for coding stereo parameters */\n    if( total_rate_bps < 1 ) {\n        total_rate_bps = 1;\n    }\n    min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 900 );\n    silk_assert( min_mid_rate_bps < 32767 );\n    /* Default bitrate distribution: 8 parts for Mid and (5+3*frac) parts for Side. so: mid_rate = ( 8 / ( 13 + 3 * frac ) ) * total_ rate */\n    frac_3_Q16 = silk_MUL( 3, frac_Q16 );\n    mid_side_rates_bps[ 0 ] = silk_DIV32_varQ( total_rate_bps, SILK_FIX_CONST( 8 + 5, 16 ) + frac_3_Q16, 16+3 );\n    /* If Mid bitrate below minimum, reduce stereo width */\n    if( mid_side_rates_bps[ 0 ] < min_mid_rate_bps ) {\n        mid_side_rates_bps[ 0 ] = min_mid_rate_bps;\n        mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ];\n        /* width = 4 * ( 2 * side_rate - min_rate ) / ( ( 1 + 3 * frac ) * min_rate ) */\n        width_Q14 = silk_DIV32_varQ( silk_LSHIFT( mid_side_rates_bps[ 1 ], 1 ) - min_mid_rate_bps,\n            silk_SMULWB( SILK_FIX_CONST( 1, 16 ) + frac_3_Q16, min_mid_rate_bps ), 14+2 );\n        width_Q14 = silk_LIMIT( width_Q14, 0, SILK_FIX_CONST( 1, 14 ) );\n    } else {\n        mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ];\n        width_Q14 = SILK_FIX_CONST( 1, 14 );\n    }\n\n    /* Smoother */\n    state->smth_width_Q14 = (opus_int16)silk_SMLAWB( state->smth_width_Q14, width_Q14 - state->smth_width_Q14, smooth_coef_Q16 );\n\n    /* At very low bitrates or for inputs that are nearly amplitude panned, switch to panned-mono coding */\n    *mid_only_flag = 0;\n    if( toMono ) {\n        /* Last frame before stereo->mono transition; collapse stereo width */\n        width_Q14 = 0;\n        pred_Q13[ 0 ] = 0;\n        pred_Q13[ 1 ] = 0;\n        silk_stereo_quant_pred( pred_Q13, ix );\n    } else if( state->width_prev_Q14 == 0 &&\n        ( 8 * total_rate_bps < 13 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.05, 14 ) ) )\n    {\n        /* Code as panned-mono; previous frame already had zero width */\n        /* Scale down and quantize predictors */\n        pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 );\n        pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 );\n        silk_stereo_quant_pred( pred_Q13, ix );\n        /* Collapse stereo width */\n        width_Q14 = 0;\n        pred_Q13[ 0 ] = 0;\n        pred_Q13[ 1 ] = 0;\n        mid_side_rates_bps[ 0 ] = total_rate_bps;\n        mid_side_rates_bps[ 1 ] = 0;\n        *mid_only_flag = 1;\n    } else if( state->width_prev_Q14 != 0 &&\n        ( 8 * total_rate_bps < 11 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.02, 14 ) ) )\n    {\n        /* Transition to zero-width stereo */\n        /* Scale down and quantize predictors */\n        pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 );\n        pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 );\n        silk_stereo_quant_pred( pred_Q13, ix );\n        /* Collapse stereo width */\n        width_Q14 = 0;\n        pred_Q13[ 0 ] = 0;\n        pred_Q13[ 1 ] = 0;\n    } else if( state->smth_width_Q14 > SILK_FIX_CONST( 0.95, 14 ) ) {\n        /* Full-width stereo coding */\n        silk_stereo_quant_pred( pred_Q13, ix );\n        width_Q14 = SILK_FIX_CONST( 1, 14 );\n    } else {\n        /* Reduced-width stereo coding; scale down and quantize predictors */\n        pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 );\n        pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 );\n        silk_stereo_quant_pred( pred_Q13, ix );\n        width_Q14 = state->smth_width_Q14;\n    }\n\n    /* Make sure to keep on encoding until the tapered output has been transmitted */\n    if( *mid_only_flag == 1 ) {\n        state->silent_side_len += frame_length - STEREO_INTERP_LEN_MS * fs_kHz;\n        if( state->silent_side_len < LA_SHAPE_MS * fs_kHz ) {\n            *mid_only_flag = 0;\n        } else {\n            /* Limit to avoid wrapping around */\n            state->silent_side_len = 10000;\n        }\n    } else {\n        state->silent_side_len = 0;\n    }\n\n    if( *mid_only_flag == 0 && mid_side_rates_bps[ 1 ] < 1 ) {\n        mid_side_rates_bps[ 1 ] = 1;\n        mid_side_rates_bps[ 0 ] = silk_max_int( 1, total_rate_bps - mid_side_rates_bps[ 1 ]);\n    }\n\n    /* Interpolate predictors and subtract prediction from side channel */\n    pred0_Q13  = -state->pred_prev_Q13[ 0 ];\n    pred1_Q13  = -state->pred_prev_Q13[ 1 ];\n    w_Q24      =  silk_LSHIFT( state->width_prev_Q14, 10 );\n    denom_Q16  = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz );\n    delta0_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 );\n    delta1_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 );\n    deltaw_Q24 =  silk_LSHIFT( silk_SMULWB( width_Q14 - state->width_prev_Q14, denom_Q16 ), 10 );\n    for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) {\n        pred0_Q13 += delta0_Q13;\n        pred1_Q13 += delta1_Q13;\n        w_Q24   += deltaw_Q24;\n        sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 );    /* Q11 */\n        sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 );               /* Q8  */\n        sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 );       /* Q8  */\n        x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );\n    }\n\n    pred0_Q13 = -pred_Q13[ 0 ];\n    pred1_Q13 = -pred_Q13[ 1 ];\n    w_Q24     =  silk_LSHIFT( width_Q14, 10 );\n    for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) {\n        sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 );    /* Q11 */\n        sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 );               /* Q8  */\n        sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 );       /* Q8  */\n        x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );\n    }\n    state->pred_prev_Q13[ 0 ] = (opus_int16)pred_Q13[ 0 ];\n    state->pred_prev_Q13[ 1 ] = (opus_int16)pred_Q13[ 1 ];\n    state->width_prev_Q14     = (opus_int16)width_Q14;\n    RESTORE_STACK;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/stereo_MS_to_LR.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Convert adaptive Mid/Side representation to Left/Right stereo signal */\nvoid silk_stereo_MS_to_LR(\n    stereo_dec_state            *state,                         /* I/O  State                                       */\n    opus_int16                  x1[],                           /* I/O  Left input signal, becomes mid signal       */\n    opus_int16                  x2[],                           /* I/O  Right input signal, becomes side signal     */\n    const opus_int32            pred_Q13[],                     /* I    Predictors                                  */\n    opus_int                    fs_kHz,                         /* I    Samples rate (kHz)                          */\n    opus_int                    frame_length                    /* I    Number of samples                           */\n)\n{\n    opus_int   n, denom_Q16, delta0_Q13, delta1_Q13;\n    opus_int32 sum, diff, pred0_Q13, pred1_Q13;\n\n    /* Buffering */\n    silk_memcpy( x1, state->sMid,  2 * sizeof( opus_int16 ) );\n    silk_memcpy( x2, state->sSide, 2 * sizeof( opus_int16 ) );\n    silk_memcpy( state->sMid,  &x1[ frame_length ], 2 * sizeof( opus_int16 ) );\n    silk_memcpy( state->sSide, &x2[ frame_length ], 2 * sizeof( opus_int16 ) );\n\n    /* Interpolate predictors and add prediction to side channel */\n    pred0_Q13  = state->pred_prev_Q13[ 0 ];\n    pred1_Q13  = state->pred_prev_Q13[ 1 ];\n    denom_Q16  = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz );\n    delta0_Q13 = silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 );\n    delta1_Q13 = silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 );\n    for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) {\n        pred0_Q13 += delta0_Q13;\n        pred1_Q13 += delta1_Q13;\n        sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 );       /* Q11 */\n        sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 );         /* Q8  */\n        sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 );        /* Q8  */\n        x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );\n    }\n    pred0_Q13 = pred_Q13[ 0 ];\n    pred1_Q13 = pred_Q13[ 1 ];\n    for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) {\n        sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 );       /* Q11 */\n        sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 );         /* Q8  */\n        sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 );        /* Q8  */\n        x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );\n    }\n    state->pred_prev_Q13[ 0 ] = pred_Q13[ 0 ];\n    state->pred_prev_Q13[ 1 ] = pred_Q13[ 1 ];\n\n    /* Convert to left/right signals */\n    for( n = 0; n < frame_length; n++ ) {\n        sum  = x1[ n + 1 ] + (opus_int32)x2[ n + 1 ];\n        diff = x1[ n + 1 ] - (opus_int32)x2[ n + 1 ];\n        x1[ n + 1 ] = (opus_int16)silk_SAT16( sum );\n        x2[ n + 1 ] = (opus_int16)silk_SAT16( diff );\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/stereo_decode_pred.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Decode mid/side predictors */\nvoid silk_stereo_decode_pred(\n    ec_dec                      *psRangeDec,                    /* I/O  Compressor data structure                   */\n    opus_int32                  pred_Q13[]                      /* O    Predictors                                  */\n)\n{\n    opus_int   n, ix[ 2 ][ 3 ];\n    opus_int32 low_Q13, step_Q13;\n\n    /* Entropy decoding */\n    n = ec_dec_icdf( psRangeDec, silk_stereo_pred_joint_iCDF, 8 );\n    ix[ 0 ][ 2 ] = silk_DIV32_16( n, 5 );\n    ix[ 1 ][ 2 ] = n - 5 * ix[ 0 ][ 2 ];\n    for( n = 0; n < 2; n++ ) {\n        ix[ n ][ 0 ] = ec_dec_icdf( psRangeDec, silk_uniform3_iCDF, 8 );\n        ix[ n ][ 1 ] = ec_dec_icdf( psRangeDec, silk_uniform5_iCDF, 8 );\n    }\n\n    /* Dequantize */\n    for( n = 0; n < 2; n++ ) {\n        ix[ n ][ 0 ] += 3 * ix[ n ][ 2 ];\n        low_Q13 = silk_stereo_pred_quant_Q13[ ix[ n ][ 0 ] ];\n        step_Q13 = silk_SMULWB( silk_stereo_pred_quant_Q13[ ix[ n ][ 0 ] + 1 ] - low_Q13,\n            SILK_FIX_CONST( 0.5 / STEREO_QUANT_SUB_STEPS, 16 ) );\n        pred_Q13[ n ] = silk_SMLABB( low_Q13, step_Q13, 2 * ix[ n ][ 1 ] + 1 );\n    }\n\n    /* Subtract second from first predictor (helps when actually applying these) */\n    pred_Q13[ 0 ] -= pred_Q13[ 1 ];\n}\n\n/* Decode mid-only flag */\nvoid silk_stereo_decode_mid_only(\n    ec_dec                      *psRangeDec,                    /* I/O  Compressor data structure                   */\n    opus_int                    *decode_only_mid                /* O    Flag that only mid channel has been coded   */\n)\n{\n    /* Decode flag that only mid channel is coded */\n    *decode_only_mid = ec_dec_icdf( psRangeDec, silk_stereo_only_code_mid_iCDF, 8 );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/stereo_encode_pred.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Entropy code the mid/side quantization indices */\nvoid silk_stereo_encode_pred(\n    ec_enc                      *psRangeEnc,                    /* I/O  Compressor data structure                   */\n    opus_int8                   ix[ 2 ][ 3 ]                    /* I    Quantization indices                        */\n)\n{\n    opus_int   n;\n\n    /* Entropy coding */\n    n = 5 * ix[ 0 ][ 2 ] + ix[ 1 ][ 2 ];\n    silk_assert( n < 25 );\n    ec_enc_icdf( psRangeEnc, n, silk_stereo_pred_joint_iCDF, 8 );\n    for( n = 0; n < 2; n++ ) {\n        silk_assert( ix[ n ][ 0 ] < 3 );\n        silk_assert( ix[ n ][ 1 ] < STEREO_QUANT_SUB_STEPS );\n        ec_enc_icdf( psRangeEnc, ix[ n ][ 0 ], silk_uniform3_iCDF, 8 );\n        ec_enc_icdf( psRangeEnc, ix[ n ][ 1 ], silk_uniform5_iCDF, 8 );\n    }\n}\n\n/* Entropy code the mid-only flag */\nvoid silk_stereo_encode_mid_only(\n    ec_enc                      *psRangeEnc,                    /* I/O  Compressor data structure                   */\n    opus_int8                   mid_only_flag\n)\n{\n    /* Encode flag that only mid channel is coded */\n    ec_enc_icdf( psRangeEnc, mid_only_flag, silk_stereo_only_code_mid_iCDF, 8 );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/stereo_find_predictor.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Find least-squares prediction gain for one signal based on another and quantize it */\nopus_int32 silk_stereo_find_predictor(                          /* O    Returns predictor in Q13                    */\n    opus_int32                  *ratio_Q14,                     /* O    Ratio of residual and mid energies          */\n    const opus_int16            x[],                            /* I    Basis signal                                */\n    const opus_int16            y[],                            /* I    Target signal                               */\n    opus_int32                  mid_res_amp_Q0[],               /* I/O  Smoothed mid, residual norms                */\n    opus_int                    length,                         /* I    Number of samples                           */\n    opus_int                    smooth_coef_Q16                 /* I    Smoothing coefficient                       */\n)\n{\n    opus_int   scale, scale1, scale2;\n    opus_int32 nrgx, nrgy, corr, pred_Q13, pred2_Q10;\n\n    /* Find  predictor */\n    silk_sum_sqr_shift( &nrgx, &scale1, x, length );\n    silk_sum_sqr_shift( &nrgy, &scale2, y, length );\n    scale = silk_max_int( scale1, scale2 );\n    scale = scale + ( scale & 1 );          /* make even */\n    nrgy = silk_RSHIFT32( nrgy, scale - scale2 );\n    nrgx = silk_RSHIFT32( nrgx, scale - scale1 );\n    nrgx = silk_max_int( nrgx, 1 );\n    corr = silk_inner_prod_aligned_scale( x, y, scale, length );\n    pred_Q13 = silk_DIV32_varQ( corr, nrgx, 13 );\n    pred_Q13 = silk_LIMIT( pred_Q13, -(1 << 14), 1 << 14 );\n    pred2_Q10 = silk_SMULWB( pred_Q13, pred_Q13 );\n\n    /* Faster update for signals with large prediction parameters */\n    smooth_coef_Q16 = (opus_int)silk_max_int( smooth_coef_Q16, silk_abs( pred2_Q10 ) );\n\n    /* Smoothed mid and residual norms */\n    silk_assert( smooth_coef_Q16 < 32768 );\n    scale = silk_RSHIFT( scale, 1 );\n    mid_res_amp_Q0[ 0 ] = silk_SMLAWB( mid_res_amp_Q0[ 0 ], silk_LSHIFT( silk_SQRT_APPROX( nrgx ), scale ) - mid_res_amp_Q0[ 0 ],\n        smooth_coef_Q16 );\n    /* Residual energy = nrgy - 2 * pred * corr + pred^2 * nrgx */\n    nrgy = silk_SUB_LSHIFT32( nrgy, silk_SMULWB( corr, pred_Q13 ), 3 + 1 );\n    nrgy = silk_ADD_LSHIFT32( nrgy, silk_SMULWB( nrgx, pred2_Q10 ), 6 );\n    mid_res_amp_Q0[ 1 ] = silk_SMLAWB( mid_res_amp_Q0[ 1 ], silk_LSHIFT( silk_SQRT_APPROX( nrgy ), scale ) - mid_res_amp_Q0[ 1 ],\n        smooth_coef_Q16 );\n\n    /* Ratio of smoothed residual and mid norms */\n    *ratio_Q14 = silk_DIV32_varQ( mid_res_amp_Q0[ 1 ], silk_max( mid_res_amp_Q0[ 0 ], 1 ), 14 );\n    *ratio_Q14 = silk_LIMIT( *ratio_Q14, 0, 32767 );\n\n    return pred_Q13;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/stereo_quant_pred.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"main.h\"\n\n/* Quantize mid/side predictors */\nvoid silk_stereo_quant_pred(\n    opus_int32                  pred_Q13[],                     /* I/O  Predictors (out: quantized)                 */\n    opus_int8                   ix[ 2 ][ 3 ]                    /* O    Quantization indices                        */\n)\n{\n    opus_int   i, j, n;\n    opus_int32 low_Q13, step_Q13, lvl_Q13, err_min_Q13, err_Q13, quant_pred_Q13 = 0;\n\n    /* Quantize */\n    for( n = 0; n < 2; n++ ) {\n        /* Brute-force search over quantization levels */\n        err_min_Q13 = silk_int32_MAX;\n        for( i = 0; i < STEREO_QUANT_TAB_SIZE - 1; i++ ) {\n            low_Q13 = silk_stereo_pred_quant_Q13[ i ];\n            step_Q13 = silk_SMULWB( silk_stereo_pred_quant_Q13[ i + 1 ] - low_Q13,\n                SILK_FIX_CONST( 0.5 / STEREO_QUANT_SUB_STEPS, 16 ) );\n            for( j = 0; j < STEREO_QUANT_SUB_STEPS; j++ ) {\n                lvl_Q13 = silk_SMLABB( low_Q13, step_Q13, 2 * j + 1 );\n                err_Q13 = silk_abs( pred_Q13[ n ] - lvl_Q13 );\n                if( err_Q13 < err_min_Q13 ) {\n                    err_min_Q13 = err_Q13;\n                    quant_pred_Q13 = lvl_Q13;\n                    ix[ n ][ 0 ] = i;\n                    ix[ n ][ 1 ] = j;\n                } else {\n                    /* Error increasing, so we're past the optimum */\n                    goto done;\n                }\n            }\n        }\n        done:\n        ix[ n ][ 2 ]  = silk_DIV32_16( ix[ n ][ 0 ], 3 );\n        ix[ n ][ 0 ] -= ix[ n ][ 2 ] * 3;\n        pred_Q13[ n ] = quant_pred_Q13;\n    }\n\n    /* Subtract second from first predictor (helps when actually applying these) */\n    pred_Q13[ 0 ] -= pred_Q13[ 1 ];\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/structs.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_STRUCTS_H\n#define SILK_STRUCTS_H\n\n#include \"typedef.h\"\n#include \"SigProc_FIX.h\"\n#include \"define.h\"\n#include \"entenc.h\"\n#include \"entdec.h\"\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/************************************/\n/* Noise shaping quantization state */\n/************************************/\ntypedef struct {\n    opus_int16                  xq[           2 * MAX_FRAME_LENGTH ]; /* Buffer for quantized output signal                             */\n    opus_int32                  sLTP_shp_Q14[ 2 * MAX_FRAME_LENGTH ];\n    opus_int32                  sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];\n    opus_int32                  sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];\n    opus_int32                  sLF_AR_shp_Q14;\n    opus_int                    lagPrev;\n    opus_int                    sLTP_buf_idx;\n    opus_int                    sLTP_shp_buf_idx;\n    opus_int32                  rand_seed;\n    opus_int32                  prev_gain_Q16;\n    opus_int                    rewhite_flag;\n} silk_nsq_state;\n\n/********************************/\n/* VAD state                    */\n/********************************/\ntypedef struct {\n    opus_int32                  AnaState[ 2 ];                  /* Analysis filterbank state: 0-8 kHz                                   */\n    opus_int32                  AnaState1[ 2 ];                 /* Analysis filterbank state: 0-4 kHz                                   */\n    opus_int32                  AnaState2[ 2 ];                 /* Analysis filterbank state: 0-2 kHz                                   */\n    opus_int32                  XnrgSubfr[ VAD_N_BANDS ];       /* Subframe energies                                                    */\n    opus_int32                  NrgRatioSmth_Q8[ VAD_N_BANDS ]; /* Smoothed energy level in each band                                   */\n    opus_int16                  HPstate;                        /* State of differentiator in the lowest band                           */\n    opus_int32                  NL[ VAD_N_BANDS ];              /* Noise energy level in each band                                      */\n    opus_int32                  inv_NL[ VAD_N_BANDS ];          /* Inverse noise energy level in each band                              */\n    opus_int32                  NoiseLevelBias[ VAD_N_BANDS ];  /* Noise level estimator bias/offset                                    */\n    opus_int32                  counter;                        /* Frame counter used in the initial phase                              */\n} silk_VAD_state;\n\n/* Variable cut-off low-pass filter state */\ntypedef struct {\n    opus_int32                   In_LP_State[ 2 ];           /* Low pass filter state */\n    opus_int32                   transition_frame_no;        /* Counter which is mapped to a cut-off frequency */\n    opus_int                     mode;                       /* Operating mode, <0: switch down, >0: switch up; 0: do nothing           */\n} silk_LP_state;\n\n/* Structure containing NLSF codebook */\ntypedef struct {\n    const opus_int16             nVectors;\n    const opus_int16             order;\n    const opus_int16             quantStepSize_Q16;\n    const opus_int16             invQuantStepSize_Q6;\n    const opus_uint8             *CB1_NLSF_Q8;\n    const opus_uint8             *CB1_iCDF;\n    const opus_uint8             *pred_Q8;\n    const opus_uint8             *ec_sel;\n    const opus_uint8             *ec_iCDF;\n    const opus_uint8             *ec_Rates_Q5;\n    const opus_int16             *deltaMin_Q15;\n} silk_NLSF_CB_struct;\n\ntypedef struct {\n    opus_int16                   pred_prev_Q13[ 2 ];\n    opus_int16                   sMid[ 2 ];\n    opus_int16                   sSide[ 2 ];\n    opus_int32                   mid_side_amp_Q0[ 4 ];\n    opus_int16                   smth_width_Q14;\n    opus_int16                   width_prev_Q14;\n    opus_int16                   silent_side_len;\n    opus_int8                    predIx[ MAX_FRAMES_PER_PACKET ][ 2 ][ 3 ];\n    opus_int8                    mid_only_flags[ MAX_FRAMES_PER_PACKET ];\n} stereo_enc_state;\n\ntypedef struct {\n    opus_int16                   pred_prev_Q13[ 2 ];\n    opus_int16                   sMid[ 2 ];\n    opus_int16                   sSide[ 2 ];\n} stereo_dec_state;\n\ntypedef struct {\n    opus_int8                    GainsIndices[ MAX_NB_SUBFR ];\n    opus_int8                    LTPIndex[ MAX_NB_SUBFR ];\n    opus_int8                    NLSFIndices[ MAX_LPC_ORDER + 1 ];\n    opus_int16                   lagIndex;\n    opus_int8                    contourIndex;\n    opus_int8                    signalType;\n    opus_int8                    quantOffsetType;\n    opus_int8                    NLSFInterpCoef_Q2;\n    opus_int8                    PERIndex;\n    opus_int8                    LTP_scaleIndex;\n    opus_int8                    Seed;\n} SideInfoIndices;\n\n/********************************/\n/* Encoder state                */\n/********************************/\ntypedef struct {\n    opus_int32                   In_HP_State[ 2 ];                  /* High pass filter state                                           */\n    opus_int32                   variable_HP_smth1_Q15;             /* State of first smoother                                          */\n    opus_int32                   variable_HP_smth2_Q15;             /* State of second smoother                                         */\n    silk_LP_state                sLP;                               /* Low pass filter state                                            */\n    silk_VAD_state               sVAD;                              /* Voice activity detector state                                    */\n    silk_nsq_state               sNSQ;                              /* Noise Shape Quantizer State                                      */\n    opus_int16                   prev_NLSFq_Q15[ MAX_LPC_ORDER ];   /* Previously quantized NLSF vector                                 */\n    opus_int                     speech_activity_Q8;                /* Speech activity                                                  */\n    opus_int                     allow_bandwidth_switch;            /* Flag indicating that switching of internal bandwidth is allowed  */\n    opus_int8                    LBRRprevLastGainIndex;\n    opus_int8                    prevSignalType;\n    opus_int                     prevLag;\n    opus_int                     pitch_LPC_win_length;\n    opus_int                     max_pitch_lag;                     /* Highest possible pitch lag (samples)                             */\n    opus_int32                   API_fs_Hz;                         /* API sampling frequency (Hz)                                      */\n    opus_int32                   prev_API_fs_Hz;                    /* Previous API sampling frequency (Hz)                             */\n    opus_int                     maxInternal_fs_Hz;                 /* Maximum internal sampling frequency (Hz)                         */\n    opus_int                     minInternal_fs_Hz;                 /* Minimum internal sampling frequency (Hz)                         */\n    opus_int                     desiredInternal_fs_Hz;             /* Soft request for internal sampling frequency (Hz)                */\n    opus_int                     fs_kHz;                            /* Internal sampling frequency (kHz)                                */\n    opus_int                     nb_subfr;                          /* Number of 5 ms subframes in a frame                              */\n    opus_int                     frame_length;                      /* Frame length (samples)                                           */\n    opus_int                     subfr_length;                      /* Subframe length (samples)                                        */\n    opus_int                     ltp_mem_length;                    /* Length of LTP memory                                             */\n    opus_int                     la_pitch;                          /* Look-ahead for pitch analysis (samples)                          */\n    opus_int                     la_shape;                          /* Look-ahead for noise shape analysis (samples)                    */\n    opus_int                     shapeWinLength;                    /* Window length for noise shape analysis (samples)                 */\n    opus_int32                   TargetRate_bps;                    /* Target bitrate (bps)                                             */\n    opus_int                     PacketSize_ms;                     /* Number of milliseconds to put in each packet                     */\n    opus_int                     PacketLoss_perc;                   /* Packet loss rate measured by farend                              */\n    opus_int32                   frameCounter;\n    opus_int                     Complexity;                        /* Complexity setting                                               */\n    opus_int                     nStatesDelayedDecision;            /* Number of states in delayed decision quantization                */\n    opus_int                     useInterpolatedNLSFs;              /* Flag for using NLSF interpolation                                */\n    opus_int                     shapingLPCOrder;                   /* Filter order for noise shaping filters                           */\n    opus_int                     predictLPCOrder;                   /* Filter order for prediction filters                              */\n    opus_int                     pitchEstimationComplexity;         /* Complexity level for pitch estimator                             */\n    opus_int                     pitchEstimationLPCOrder;           /* Whitening filter order for pitch estimator                       */\n    opus_int32                   pitchEstimationThreshold_Q16;      /* Threshold for pitch estimator                                    */\n    opus_int                     LTPQuantLowComplexity;             /* Flag for low complexity LTP quantization                         */\n    opus_int                     mu_LTP_Q9;                         /* Rate-distortion tradeoff in LTP quantization                     */\n    opus_int32                   sum_log_gain_Q7;                   /* Cumulative max prediction gain                                   */\n    opus_int                     NLSF_MSVQ_Survivors;               /* Number of survivors in NLSF MSVQ                                 */\n    opus_int                     first_frame_after_reset;           /* Flag for deactivating NLSF interpolation, pitch prediction       */\n    opus_int                     controlled_since_last_payload;     /* Flag for ensuring codec_control only runs once per packet        */\n    opus_int                     warping_Q16;                       /* Warping parameter for warped noise shaping                       */\n    opus_int                     useCBR;                            /* Flag to enable constant bitrate                                  */\n    opus_int                     prefillFlag;                       /* Flag to indicate that only buffers are prefilled, no coding      */\n    const opus_uint8             *pitch_lag_low_bits_iCDF;          /* Pointer to iCDF table for low bits of pitch lag index            */\n    const opus_uint8             *pitch_contour_iCDF;               /* Pointer to iCDF table for pitch contour index                    */\n    const silk_NLSF_CB_struct    *psNLSF_CB;                        /* Pointer to NLSF codebook                                         */\n    opus_int                     input_quality_bands_Q15[ VAD_N_BANDS ];\n    opus_int                     input_tilt_Q15;\n    opus_int                     SNR_dB_Q7;                         /* Quality setting                                                  */\n\n    opus_int8                    VAD_flags[ MAX_FRAMES_PER_PACKET ];\n    opus_int8                    LBRR_flag;\n    opus_int                     LBRR_flags[ MAX_FRAMES_PER_PACKET ];\n\n    SideInfoIndices              indices;\n    opus_int8                    pulses[ MAX_FRAME_LENGTH ];\n\n    int                          arch;\n\n    /* Input/output buffering */\n    opus_int16                   inputBuf[ MAX_FRAME_LENGTH + 2 ];  /* Buffer containing input signal                                   */\n    opus_int                     inputBufIx;\n    opus_int                     nFramesPerPacket;\n    opus_int                     nFramesEncoded;                    /* Number of frames analyzed in current packet                      */\n\n    opus_int                     nChannelsAPI;\n    opus_int                     nChannelsInternal;\n    opus_int                     channelNb;\n\n    /* Parameters For LTP scaling Control */\n    opus_int                     frames_since_onset;\n\n    /* Specifically for entropy coding */\n    opus_int                     ec_prevSignalType;\n    opus_int16                   ec_prevLagIndex;\n\n    silk_resampler_state_struct resampler_state;\n\n    /* DTX */\n    opus_int                     useDTX;                            /* Flag to enable DTX                                               */\n    opus_int                     inDTX;                             /* Flag to signal DTX period                                        */\n    opus_int                     noSpeechCounter;                   /* Counts concecutive nonactive frames, used by DTX                 */\n\n    /* Inband Low Bitrate Redundancy (LBRR) data */\n    opus_int                     useInBandFEC;                      /* Saves the API setting for query                                  */\n    opus_int                     LBRR_enabled;                      /* Depends on useInBandFRC, bitrate and packet loss rate            */\n    opus_int                     LBRR_GainIncreases;                /* Gains increment for coding LBRR frames                           */\n    SideInfoIndices              indices_LBRR[ MAX_FRAMES_PER_PACKET ];\n    opus_int8                    pulses_LBRR[ MAX_FRAMES_PER_PACKET ][ MAX_FRAME_LENGTH ];\n} silk_encoder_state;\n\n\n/* Struct for Packet Loss Concealment */\ntypedef struct {\n    opus_int32                  pitchL_Q8;                          /* Pitch lag to use for voiced concealment                          */\n    opus_int16                  LTPCoef_Q14[ LTP_ORDER ];           /* LTP coeficients to use for voiced concealment                    */\n    opus_int16                  prevLPC_Q12[ MAX_LPC_ORDER ];\n    opus_int                    last_frame_lost;                    /* Was previous frame lost                                          */\n    opus_int32                  rand_seed;                          /* Seed for unvoiced signal generation                              */\n    opus_int16                  randScale_Q14;                      /* Scaling of unvoiced random signal                                */\n    opus_int32                  conc_energy;\n    opus_int                    conc_energy_shift;\n    opus_int16                  prevLTP_scale_Q14;\n    opus_int32                  prevGain_Q16[ 2 ];\n    opus_int                    fs_kHz;\n    opus_int                    nb_subfr;\n    opus_int                    subfr_length;\n} silk_PLC_struct;\n\n/* Struct for CNG */\ntypedef struct {\n    opus_int32                  CNG_exc_buf_Q14[ MAX_FRAME_LENGTH ];\n    opus_int16                  CNG_smth_NLSF_Q15[ MAX_LPC_ORDER ];\n    opus_int32                  CNG_synth_state[ MAX_LPC_ORDER ];\n    opus_int32                  CNG_smth_Gain_Q16;\n    opus_int32                  rand_seed;\n    opus_int                    fs_kHz;\n} silk_CNG_struct;\n\n/********************************/\n/* Decoder state                */\n/********************************/\ntypedef struct {\n    opus_int32                  prev_gain_Q16;\n    opus_int32                  exc_Q14[ MAX_FRAME_LENGTH ];\n    opus_int32                  sLPC_Q14_buf[ MAX_LPC_ORDER ];\n    opus_int16                  outBuf[ MAX_FRAME_LENGTH + 2 * MAX_SUB_FRAME_LENGTH ];  /* Buffer for output signal                     */\n    opus_int                    lagPrev;                            /* Previous Lag                                                     */\n    opus_int8                   LastGainIndex;                      /* Previous gain index                                              */\n    opus_int                    fs_kHz;                             /* Sampling frequency in kHz                                        */\n    opus_int32                  fs_API_hz;                          /* API sample frequency (Hz)                                        */\n    opus_int                    nb_subfr;                           /* Number of 5 ms subframes in a frame                              */\n    opus_int                    frame_length;                       /* Frame length (samples)                                           */\n    opus_int                    subfr_length;                       /* Subframe length (samples)                                        */\n    opus_int                    ltp_mem_length;                     /* Length of LTP memory                                             */\n    opus_int                    LPC_order;                          /* LPC order                                                        */\n    opus_int16                  prevNLSF_Q15[ MAX_LPC_ORDER ];      /* Used to interpolate LSFs                                         */\n    opus_int                    first_frame_after_reset;            /* Flag for deactivating NLSF interpolation                         */\n    const opus_uint8            *pitch_lag_low_bits_iCDF;           /* Pointer to iCDF table for low bits of pitch lag index            */\n    const opus_uint8            *pitch_contour_iCDF;                /* Pointer to iCDF table for pitch contour index                    */\n\n    /* For buffering payload in case of more frames per packet */\n    opus_int                    nFramesDecoded;\n    opus_int                    nFramesPerPacket;\n\n    /* Specifically for entropy coding */\n    opus_int                    ec_prevSignalType;\n    opus_int16                  ec_prevLagIndex;\n\n    opus_int                    VAD_flags[ MAX_FRAMES_PER_PACKET ];\n    opus_int                    LBRR_flag;\n    opus_int                    LBRR_flags[ MAX_FRAMES_PER_PACKET ];\n\n    silk_resampler_state_struct resampler_state;\n\n    const silk_NLSF_CB_struct   *psNLSF_CB;                         /* Pointer to NLSF codebook                                         */\n\n    /* Quantization indices */\n    SideInfoIndices             indices;\n\n    /* CNG state */\n    silk_CNG_struct             sCNG;\n\n    /* Stuff used for PLC */\n    opus_int                    lossCnt;\n    opus_int                    prevSignalType;\n\n    silk_PLC_struct sPLC;\n\n} silk_decoder_state;\n\n/************************/\n/* Decoder control      */\n/************************/\ntypedef struct {\n    /* Prediction and coding parameters */\n    opus_int                    pitchL[ MAX_NB_SUBFR ];\n    opus_int32                  Gains_Q16[ MAX_NB_SUBFR ];\n    /* Holds interpolated and final coefficients, 4-byte aligned */\n    silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];\n    opus_int16                  LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];\n    opus_int                    LTP_scale_Q14;\n} silk_decoder_control;\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/sum_sqr_shift.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"SigProc_FIX.h\"\n\n/* Compute number of bits to right shift the sum of squares of a vector */\n/* of int16s to make it fit in an int32                                 */\nvoid silk_sum_sqr_shift(\n    opus_int32                  *energy,            /* O   Energy of x, after shifting to the right                     */\n    opus_int                    *shift,             /* O   Number of bits right shift applied to energy                 */\n    const opus_int16            *x,                 /* I   Input vector                                                 */\n    opus_int                    len                 /* I   Length of input vector                                       */\n)\n{\n    opus_int   i, shft;\n    opus_int32 nrg_tmp, nrg;\n\n    nrg  = 0;\n    shft = 0;\n    len--;\n    for( i = 0; i < len; i += 2 ) {\n        nrg = silk_SMLABB_ovflw( nrg, x[ i ], x[ i ] );\n        nrg = silk_SMLABB_ovflw( nrg, x[ i + 1 ], x[ i + 1 ] );\n        if( nrg < 0 ) {\n            /* Scale down */\n            nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 );\n            shft = 2;\n            i+=2;\n            break;\n        }\n    }\n    for( ; i < len; i += 2 ) {\n        nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );\n        nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] );\n        nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, (opus_uint32)nrg_tmp, shft );\n        if( nrg < 0 ) {\n            /* Scale down */\n            nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 );\n            shft += 2;\n        }\n    }\n    if( i == len ) {\n        /* One sample left to process */\n        nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );\n        nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );\n    }\n\n    /* Make sure to have at least one extra leading zero (two leading zeros in total) */\n    if( nrg & 0xC0000000 ) {\n        nrg = silk_RSHIFT_uint( (opus_uint32)nrg, 2 );\n        shft += 2;\n    }\n\n    /* Output arguments */\n    *shift  = shft;\n    *energy = nrg;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/table_LSF_cos.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"tables.h\"\n\n/* Cosine approximation table for LSF conversion */\n/* Q12 values (even) */\nconst opus_int16 silk_LSFCosTab_FIX_Q12[ LSF_COS_TAB_SZ_FIX + 1 ] = {\n            8192,             8190,             8182,             8170,\n            8152,             8130,             8104,             8072,\n            8034,             7994,             7946,             7896,\n            7840,             7778,             7714,             7644,\n            7568,             7490,             7406,             7318,\n            7226,             7128,             7026,             6922,\n            6812,             6698,             6580,             6458,\n            6332,             6204,             6070,             5934,\n            5792,             5648,             5502,             5352,\n            5198,             5040,             4880,             4718,\n            4552,             4382,             4212,             4038,\n            3862,             3684,             3502,             3320,\n            3136,             2948,             2760,             2570,\n            2378,             2186,             1990,             1794,\n            1598,             1400,             1202,             1002,\n             802,              602,              402,              202,\n               0,             -202,             -402,             -602,\n            -802,            -1002,            -1202,            -1400,\n           -1598,            -1794,            -1990,            -2186,\n           -2378,            -2570,            -2760,            -2948,\n           -3136,            -3320,            -3502,            -3684,\n           -3862,            -4038,            -4212,            -4382,\n           -4552,            -4718,            -4880,            -5040,\n           -5198,            -5352,            -5502,            -5648,\n           -5792,            -5934,            -6070,            -6204,\n           -6332,            -6458,            -6580,            -6698,\n           -6812,            -6922,            -7026,            -7128,\n           -7226,            -7318,            -7406,            -7490,\n           -7568,            -7644,            -7714,            -7778,\n           -7840,            -7896,            -7946,            -7994,\n           -8034,            -8072,            -8104,            -8130,\n           -8152,            -8170,            -8182,            -8190,\n           -8192\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/tables.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_TABLES_H\n#define SILK_TABLES_H\n\n#include \"define.h\"\n#include \"structs.h\"\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/* Entropy coding tables (with size in bytes indicated) */\nextern const opus_uint8  silk_gain_iCDF[ 3 ][ N_LEVELS_QGAIN / 8 ];                                 /* 24 */\nextern const opus_uint8  silk_delta_gain_iCDF[ MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ];   /* 41 */\n\nextern const opus_uint8  silk_pitch_lag_iCDF[ 2 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) ];/* 32 */\nextern const opus_uint8  silk_pitch_delta_iCDF[ 21 ];                                               /*  21 */\nextern const opus_uint8  silk_pitch_contour_iCDF[ 34 ];                                             /*  34 */\nextern const opus_uint8  silk_pitch_contour_NB_iCDF[ 11 ];                                          /*  11 */\nextern const opus_uint8  silk_pitch_contour_10_ms_iCDF[ 12 ];                                       /*  12 */\nextern const opus_uint8  silk_pitch_contour_10_ms_NB_iCDF[ 3 ];                                     /*   3 */\n\nextern const opus_uint8  silk_pulses_per_block_iCDF[ N_RATE_LEVELS ][ SILK_MAX_PULSES + 2 ];        /* 180 */\nextern const opus_uint8  silk_pulses_per_block_BITS_Q5[ N_RATE_LEVELS - 1 ][ SILK_MAX_PULSES + 2 ]; /* 162 */\n\nextern const opus_uint8  silk_rate_levels_iCDF[ 2 ][ N_RATE_LEVELS - 1 ];                           /*  18 */\nextern const opus_uint8  silk_rate_levels_BITS_Q5[ 2 ][ N_RATE_LEVELS - 1 ];                        /*  18 */\n\nextern const opus_uint8  silk_max_pulses_table[ 4 ];                                                /*   4 */\n\nextern const opus_uint8  silk_shell_code_table0[ 152 ];                                             /* 152 */\nextern const opus_uint8  silk_shell_code_table1[ 152 ];                                             /* 152 */\nextern const opus_uint8  silk_shell_code_table2[ 152 ];                                             /* 152 */\nextern const opus_uint8  silk_shell_code_table3[ 152 ];                                             /* 152 */\nextern const opus_uint8  silk_shell_code_table_offsets[ SILK_MAX_PULSES + 1 ];                      /*  17 */\n\nextern const opus_uint8  silk_lsb_iCDF[ 2 ];                                                        /*   2 */\n\nextern const opus_uint8  silk_sign_iCDF[ 42 ];                                                      /*  42 */\n\nextern const opus_uint8  silk_uniform3_iCDF[ 3 ];                                                   /*   3 */\nextern const opus_uint8  silk_uniform4_iCDF[ 4 ];                                                   /*   4 */\nextern const opus_uint8  silk_uniform5_iCDF[ 5 ];                                                   /*   5 */\nextern const opus_uint8  silk_uniform6_iCDF[ 6 ];                                                   /*   6 */\nextern const opus_uint8  silk_uniform8_iCDF[ 8 ];                                                   /*   8 */\n\nextern const opus_uint8  silk_NLSF_EXT_iCDF[ 7 ];                                                   /*   7 */\n\nextern const opus_uint8  silk_LTP_per_index_iCDF[ 3 ];                                              /*   3 */\nextern const opus_uint8  * const silk_LTP_gain_iCDF_ptrs[ NB_LTP_CBKS ];                            /*   3 */\nextern const opus_uint8  * const silk_LTP_gain_BITS_Q5_ptrs[ NB_LTP_CBKS ];                         /*   3 */\nextern const opus_int16  silk_LTP_gain_middle_avg_RD_Q14;\nextern const opus_int8   * const silk_LTP_vq_ptrs_Q7[ NB_LTP_CBKS ];                                /* 168 */\nextern const opus_uint8  * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS];\n\nextern const opus_int8   silk_LTP_vq_sizes[ NB_LTP_CBKS ];                                          /*   3 */\n\nextern const opus_uint8  silk_LTPscale_iCDF[ 3 ];                                                   /*   4 */\nextern const opus_int16  silk_LTPScales_table_Q14[ 3 ];                                             /*   6 */\n\nextern const opus_uint8  silk_type_offset_VAD_iCDF[ 4 ];                                            /*   4 */\nextern const opus_uint8  silk_type_offset_no_VAD_iCDF[ 2 ];                                         /*   2 */\n\nextern const opus_int16  silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ];                       /*  32 */\nextern const opus_uint8  silk_stereo_pred_joint_iCDF[ 25 ];                                         /*  25 */\nextern const opus_uint8  silk_stereo_only_code_mid_iCDF[ 2 ];                                       /*   2 */\n\nextern const opus_uint8  * const silk_LBRR_flags_iCDF_ptr[ 2 ];                                     /*  10 */\n\nextern const opus_uint8  silk_NLSF_interpolation_factor_iCDF[ 5 ];                                  /*   5 */\n\nextern const silk_NLSF_CB_struct silk_NLSF_CB_WB;                                                   /* 1040 */\nextern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB;                                                /* 728 */\n\n/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */\nextern const opus_int32  silk_TargetRate_table_NB[  TARGET_RATE_TAB_SZ ];                           /*  32 */\nextern const opus_int32  silk_TargetRate_table_MB[  TARGET_RATE_TAB_SZ ];                           /*  32 */\nextern const opus_int32  silk_TargetRate_table_WB[  TARGET_RATE_TAB_SZ ];                           /*  32 */\nextern const opus_int16  silk_SNR_table_Q1[         TARGET_RATE_TAB_SZ ];                           /*  32 */\n\n/* Quantization offsets */\nextern const opus_int16  silk_Quantization_Offsets_Q10[ 2 ][ 2 ];                                   /*   8 */\n\n/* Interpolation points for filter coefficients used in the bandwidth transition smoother */\nextern const opus_int32  silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NB ];           /*  60 */\nextern const opus_int32  silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NA ];           /*  60 */\n\n/* Rom table with cosine values */\nextern const opus_int16  silk_LSFCosTab_FIX_Q12[ LSF_COS_TAB_SZ_FIX + 1 ];                          /* 258 */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/tables_LTP.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"tables.h\"\n\nconst opus_uint8 silk_LTP_per_index_iCDF[3] = {\n       179,     99,      0\n};\n\nstatic const opus_uint8 silk_LTP_gain_iCDF_0[8] = {\n        71,     56,     43,     30,     21,     12,      6,      0\n};\n\nstatic const opus_uint8 silk_LTP_gain_iCDF_1[16] = {\n       199,    165,    144,    124,    109,     96,     84,     71,\n        61,     51,     42,     32,     23,     15,      8,      0\n};\n\nstatic const opus_uint8 silk_LTP_gain_iCDF_2[32] = {\n       241,    225,    211,    199,    187,    175,    164,    153,\n       142,    132,    123,    114,    105,     96,     88,     80,\n        72,     64,     57,     50,     44,     38,     33,     29,\n        24,     20,     16,     12,      9,      5,      2,      0\n};\n\nconst opus_int16 silk_LTP_gain_middle_avg_RD_Q14 = 12304;\n\nstatic const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = {\n        15,    131,    138,    138,    155,    155,    173,    173\n};\n\nstatic const opus_uint8 silk_LTP_gain_BITS_Q5_1[16] = {\n        69,     93,    115,    118,    131,    138,    141,    138,\n       150,    150,    155,    150,    155,    160,    166,    160\n};\n\nstatic const opus_uint8 silk_LTP_gain_BITS_Q5_2[32] = {\n       131,    128,    134,    141,    141,    141,    145,    145,\n       145,    150,    155,    155,    155,    155,    160,    160,\n       160,    160,    166,    166,    173,    173,    182,    192,\n       182,    192,    192,    192,    205,    192,    205,    224\n};\n\nconst opus_uint8 * const silk_LTP_gain_iCDF_ptrs[NB_LTP_CBKS] = {\n    silk_LTP_gain_iCDF_0,\n    silk_LTP_gain_iCDF_1,\n    silk_LTP_gain_iCDF_2\n};\n\nconst opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[NB_LTP_CBKS] = {\n    silk_LTP_gain_BITS_Q5_0,\n    silk_LTP_gain_BITS_Q5_1,\n    silk_LTP_gain_BITS_Q5_2\n};\n\nstatic const opus_int8 silk_LTP_gain_vq_0[8][5] =\n{\n{\n         4,      6,     24,      7,      5\n},\n{\n         0,      0,      2,      0,      0\n},\n{\n        12,     28,     41,     13,     -4\n},\n{\n        -9,     15,     42,     25,     14\n},\n{\n         1,     -2,     62,     41,     -9\n},\n{\n       -10,     37,     65,     -4,      3\n},\n{\n        -6,      4,     66,      7,     -8\n},\n{\n        16,     14,     38,     -3,     33\n}\n};\n\nstatic const opus_int8 silk_LTP_gain_vq_1[16][5] =\n{\n{\n        13,     22,     39,     23,     12\n},\n{\n        -1,     36,     64,     27,     -6\n},\n{\n        -7,     10,     55,     43,     17\n},\n{\n         1,      1,      8,      1,      1\n},\n{\n         6,    -11,     74,     53,     -9\n},\n{\n       -12,     55,     76,    -12,      8\n},\n{\n        -3,      3,     93,     27,     -4\n},\n{\n        26,     39,     59,      3,     -8\n},\n{\n         2,      0,     77,     11,      9\n},\n{\n        -8,     22,     44,     -6,      7\n},\n{\n        40,      9,     26,      3,      9\n},\n{\n        -7,     20,    101,     -7,      4\n},\n{\n         3,     -8,     42,     26,      0\n},\n{\n       -15,     33,     68,      2,     23\n},\n{\n        -2,     55,     46,     -2,     15\n},\n{\n         3,     -1,     21,     16,     41\n}\n};\n\nstatic const opus_int8 silk_LTP_gain_vq_2[32][5] =\n{\n{\n        -6,     27,     61,     39,      5\n},\n{\n       -11,     42,     88,      4,      1\n},\n{\n        -2,     60,     65,      6,     -4\n},\n{\n        -1,     -5,     73,     56,      1\n},\n{\n        -9,     19,     94,     29,     -9\n},\n{\n         0,     12,     99,      6,      4\n},\n{\n         8,    -19,    102,     46,    -13\n},\n{\n         3,      2,     13,      3,      2\n},\n{\n         9,    -21,     84,     72,    -18\n},\n{\n       -11,     46,    104,    -22,      8\n},\n{\n        18,     38,     48,     23,      0\n},\n{\n       -16,     70,     83,    -21,     11\n},\n{\n         5,    -11,    117,     22,     -8\n},\n{\n        -6,     23,    117,    -12,      3\n},\n{\n         3,     -8,     95,     28,      4\n},\n{\n       -10,     15,     77,     60,    -15\n},\n{\n        -1,      4,    124,      2,     -4\n},\n{\n         3,     38,     84,     24,    -25\n},\n{\n         2,     13,     42,     13,     31\n},\n{\n        21,     -4,     56,     46,     -1\n},\n{\n        -1,     35,     79,    -13,     19\n},\n{\n        -7,     65,     88,     -9,    -14\n},\n{\n        20,      4,     81,     49,    -29\n},\n{\n        20,      0,     75,      3,    -17\n},\n{\n         5,     -9,     44,     92,     -8\n},\n{\n         1,     -3,     22,     69,     31\n},\n{\n        -6,     95,     41,    -12,      5\n},\n{\n        39,     67,     16,     -4,      1\n},\n{\n         0,     -6,    120,     55,    -36\n},\n{\n       -13,     44,    122,      4,    -24\n},\n{\n        81,      5,     11,      3,      7\n},\n{\n         2,      0,      9,     10,     88\n}\n};\n\nconst opus_int8 * const silk_LTP_vq_ptrs_Q7[NB_LTP_CBKS] = {\n    (opus_int8 *)&silk_LTP_gain_vq_0[0][0],\n    (opus_int8 *)&silk_LTP_gain_vq_1[0][0],\n    (opus_int8 *)&silk_LTP_gain_vq_2[0][0]\n};\n\n/* Maximum frequency-dependent response of the pitch taps above,\n   computed as max(abs(freqz(taps))) */\nstatic const opus_uint8 silk_LTP_gain_vq_0_gain[8] = {\n      46,      2,     90,     87,     93,     91,     82,     98\n};\n\nstatic const opus_uint8 silk_LTP_gain_vq_1_gain[16] = {\n     109,    120,    118,     12,    113,    115,    117,    119,\n      99,     59,     87,    111,     63,    111,    112,     80\n};\n\nstatic const opus_uint8 silk_LTP_gain_vq_2_gain[32] = {\n     126,    124,    125,    124,    129,    121,    126,     23,\n     132,    127,    127,    127,    126,    127,    122,    133,\n     130,    134,    101,    118,    119,    145,    126,     86,\n     124,    120,    123,    119,    170,    173,    107,    109\n};\n\nconst opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS] = {\n    &silk_LTP_gain_vq_0_gain[0],\n    &silk_LTP_gain_vq_1_gain[0],\n    &silk_LTP_gain_vq_2_gain[0]\n};\n\nconst opus_int8 silk_LTP_vq_sizes[NB_LTP_CBKS] = {\n    8, 16, 32\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/tables_NLSF_CB_NB_MB.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"tables.h\"\n\nstatic const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = {\n        12,     35,     60,     83,    108,    132,    157,    180,\n       206,    228,     15,     32,     55,     77,    101,    125,\n       151,    175,    201,    225,     19,     42,     66,     89,\n       114,    137,    162,    184,    209,    230,     12,     25,\n        50,     72,     97,    120,    147,    172,    200,    223,\n        26,     44,     69,     90,    114,    135,    159,    180,\n       205,    225,     13,     22,     53,     80,    106,    130,\n       156,    180,    205,    228,     15,     25,     44,     64,\n        90,    115,    142,    168,    196,    222,     19,     24,\n        62,     82,    100,    120,    145,    168,    190,    214,\n        22,     31,     50,     79,    103,    120,    151,    170,\n       203,    227,     21,     29,     45,     65,    106,    124,\n       150,    171,    196,    224,     30,     49,     75,     97,\n       121,    142,    165,    186,    209,    229,     19,     25,\n        52,     70,     93,    116,    143,    166,    192,    219,\n        26,     34,     62,     75,     97,    118,    145,    167,\n       194,    217,     25,     33,     56,     70,     91,    113,\n       143,    165,    196,    223,     21,     34,     51,     72,\n        97,    117,    145,    171,    196,    222,     20,     29,\n        50,     67,     90,    117,    144,    168,    197,    221,\n        22,     31,     48,     66,     95,    117,    146,    168,\n       196,    222,     24,     33,     51,     77,    116,    134,\n       158,    180,    200,    224,     21,     28,     70,     87,\n       106,    124,    149,    170,    194,    217,     26,     33,\n        53,     64,     83,    117,    152,    173,    204,    225,\n        27,     34,     65,     95,    108,    129,    155,    174,\n       210,    225,     20,     26,     72,     99,    113,    131,\n       154,    176,    200,    219,     34,     43,     61,     78,\n        93,    114,    155,    177,    205,    229,     23,     29,\n        54,     97,    124,    138,    163,    179,    209,    229,\n        30,     38,     56,     89,    118,    129,    158,    178,\n       200,    231,     21,     29,     49,     63,     85,    111,\n       142,    163,    193,    222,     27,     48,     77,    103,\n       133,    158,    179,    196,    215,    232,     29,     47,\n        74,     99,    124,    151,    176,    198,    220,    237,\n        33,     42,     61,     76,     93,    121,    155,    174,\n       207,    225,     29,     53,     87,    112,    136,    154,\n       170,    188,    208,    227,     24,     30,     52,     84,\n       131,    150,    166,    186,    203,    229,     37,     48,\n        64,     84,    104,    118,    156,    177,    201,    230\n};\n\nstatic const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = {\n       212,    178,    148,    129,    108,     96,     85,     82,\n        79,     77,     61,     59,     57,     56,     51,     49,\n        48,     45,     42,     41,     40,     38,     36,     34,\n        31,     30,     21,     12,     10,      3,      1,      0,\n       255,    245,    244,    236,    233,    225,    217,    203,\n       190,    176,    175,    161,    149,    136,    125,    114,\n       102,     91,     81,     71,     60,     52,     43,     35,\n        28,     20,     19,     18,     12,     11,      5,      0\n};\n\nstatic const opus_uint8 silk_NLSF_CB2_SELECT_NB_MB[ 160 ] = {\n        16,      0,      0,      0,      0,     99,     66,     36,\n        36,     34,     36,     34,     34,     34,     34,     83,\n        69,     36,     52,     34,    116,    102,     70,     68,\n        68,    176,    102,     68,     68,     34,     65,     85,\n        68,     84,     36,    116,    141,    152,    139,    170,\n       132,    187,    184,    216,    137,    132,    249,    168,\n       185,    139,    104,    102,    100,     68,     68,    178,\n       218,    185,    185,    170,    244,    216,    187,    187,\n       170,    244,    187,    187,    219,    138,    103,    155,\n       184,    185,    137,    116,    183,    155,    152,    136,\n       132,    217,    184,    184,    170,    164,    217,    171,\n       155,    139,    244,    169,    184,    185,    170,    164,\n       216,    223,    218,    138,    214,    143,    188,    218,\n       168,    244,    141,    136,    155,    170,    168,    138,\n       220,    219,    139,    164,    219,    202,    216,    137,\n       168,    186,    246,    185,    139,    116,    185,    219,\n       185,    138,    100,    100,    134,    100,    102,     34,\n        68,     68,    100,     68,    168,    203,    221,    218,\n       168,    167,    154,    136,    104,     70,    164,    246,\n       171,    137,    139,    137,    155,    218,    219,    139\n};\n\nstatic const opus_uint8 silk_NLSF_CB2_iCDF_NB_MB[ 72 ] = {\n       255,    254,    253,    238,     14,      3,      2,      1,\n         0,    255,    254,    252,    218,     35,      3,      2,\n         1,      0,    255,    254,    250,    208,     59,      4,\n         2,      1,      0,    255,    254,    246,    194,     71,\n        10,      2,      1,      0,    255,    252,    236,    183,\n        82,      8,      2,      1,      0,    255,    252,    235,\n       180,     90,     17,      2,      1,      0,    255,    248,\n       224,    171,     97,     30,      4,      1,      0,    255,\n       254,    236,    173,     95,     37,      7,      1,      0\n};\n\nstatic const opus_uint8 silk_NLSF_CB2_BITS_NB_MB_Q5[ 72 ] = {\n       255,    255,    255,    131,      6,    145,    255,    255,\n       255,    255,    255,    236,     93,     15,     96,    255,\n       255,    255,    255,    255,    194,     83,     25,     71,\n       221,    255,    255,    255,    255,    162,     73,     34,\n        66,    162,    255,    255,    255,    210,    126,     73,\n        43,     57,    173,    255,    255,    255,    201,    125,\n        71,     48,     58,    130,    255,    255,    255,    166,\n       110,     73,     57,     62,    104,    210,    255,    255,\n       251,    123,     65,     55,     68,    100,    171,    255\n};\n\nstatic const opus_uint8 silk_NLSF_PRED_NB_MB_Q8[ 18 ] = {\n       179,    138,    140,    148,    151,    149,    153,    151,\n       163,    116,     67,     82,     59,     92,     72,    100,\n        89,     92\n};\n\nstatic const opus_int16 silk_NLSF_DELTA_MIN_NB_MB_Q15[ 11 ] = {\n       250,      3,      6,      3,      3,      3,      4,      3,\n         3,      3,    461\n};\n\nconst silk_NLSF_CB_struct silk_NLSF_CB_NB_MB =\n{\n    32,\n    10,\n    SILK_FIX_CONST( 0.18, 16 ),\n    SILK_FIX_CONST( 1.0 / 0.18, 6 ),\n    silk_NLSF_CB1_NB_MB_Q8,\n    silk_NLSF_CB1_iCDF_NB_MB,\n    silk_NLSF_PRED_NB_MB_Q8,\n    silk_NLSF_CB2_SELECT_NB_MB,\n    silk_NLSF_CB2_iCDF_NB_MB,\n    silk_NLSF_CB2_BITS_NB_MB_Q5,\n    silk_NLSF_DELTA_MIN_NB_MB_Q15,\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/tables_NLSF_CB_WB.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"tables.h\"\n\nstatic const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = {\n         7,     23,     38,     54,     69,     85,    100,    116,\n       131,    147,    162,    178,    193,    208,    223,    239,\n        13,     25,     41,     55,     69,     83,     98,    112,\n       127,    142,    157,    171,    187,    203,    220,    236,\n        15,     21,     34,     51,     61,     78,     92,    106,\n       126,    136,    152,    167,    185,    205,    225,    240,\n        10,     21,     36,     50,     63,     79,     95,    110,\n       126,    141,    157,    173,    189,    205,    221,    237,\n        17,     20,     37,     51,     59,     78,     89,    107,\n       123,    134,    150,    164,    184,    205,    224,    240,\n        10,     15,     32,     51,     67,     81,     96,    112,\n       129,    142,    158,    173,    189,    204,    220,    236,\n         8,     21,     37,     51,     65,     79,     98,    113,\n       126,    138,    155,    168,    179,    192,    209,    218,\n        12,     15,     34,     55,     63,     78,     87,    108,\n       118,    131,    148,    167,    185,    203,    219,    236,\n        16,     19,     32,     36,     56,     79,     91,    108,\n       118,    136,    154,    171,    186,    204,    220,    237,\n        11,     28,     43,     58,     74,     89,    105,    120,\n       135,    150,    165,    180,    196,    211,    226,    241,\n         6,     16,     33,     46,     60,     75,     92,    107,\n       123,    137,    156,    169,    185,    199,    214,    225,\n        11,     19,     30,     44,     57,     74,     89,    105,\n       121,    135,    152,    169,    186,    202,    218,    234,\n        12,     19,     29,     46,     57,     71,     88,    100,\n       120,    132,    148,    165,    182,    199,    216,    233,\n        17,     23,     35,     46,     56,     77,     92,    106,\n       123,    134,    152,    167,    185,    204,    222,    237,\n        14,     17,     45,     53,     63,     75,     89,    107,\n       115,    132,    151,    171,    188,    206,    221,    240,\n         9,     16,     29,     40,     56,     71,     88,    103,\n       119,    137,    154,    171,    189,    205,    222,    237,\n        16,     19,     36,     48,     57,     76,     87,    105,\n       118,    132,    150,    167,    185,    202,    218,    236,\n        12,     17,     29,     54,     71,     81,     94,    104,\n       126,    136,    149,    164,    182,    201,    221,    237,\n        15,     28,     47,     62,     79,     97,    115,    129,\n       142,    155,    168,    180,    194,    208,    223,    238,\n         8,     14,     30,     45,     62,     78,     94,    111,\n       127,    143,    159,    175,    192,    207,    223,    239,\n        17,     30,     49,     62,     79,     92,    107,    119,\n       132,    145,    160,    174,    190,    204,    220,    235,\n        14,     19,     36,     45,     61,     76,     91,    108,\n       121,    138,    154,    172,    189,    205,    222,    238,\n        12,     18,     31,     45,     60,     76,     91,    107,\n       123,    138,    154,    171,    187,    204,    221,    236,\n        13,     17,     31,     43,     53,     70,     83,    103,\n       114,    131,    149,    167,    185,    203,    220,    237,\n        17,     22,     35,     42,     58,     78,     93,    110,\n       125,    139,    155,    170,    188,    206,    224,    240,\n         8,     15,     34,     50,     67,     83,     99,    115,\n       131,    146,    162,    178,    193,    209,    224,    239,\n        13,     16,     41,     66,     73,     86,     95,    111,\n       128,    137,    150,    163,    183,    206,    225,    241,\n        17,     25,     37,     52,     63,     75,     92,    102,\n       119,    132,    144,    160,    175,    191,    212,    231,\n        19,     31,     49,     65,     83,    100,    117,    133,\n       147,    161,    174,    187,    200,    213,    227,    242,\n        18,     31,     52,     68,     88,    103,    117,    126,\n       138,    149,    163,    177,    192,    207,    223,    239,\n        16,     29,     47,     61,     76,     90,    106,    119,\n       133,    147,    161,    176,    193,    209,    224,    240,\n        15,     21,     35,     50,     61,     73,     86,     97,\n       110,    119,    129,    141,    175,    198,    218,    237\n};\n\nstatic const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = {\n       225,    204,    201,    184,    183,    175,    158,    154,\n       153,    135,    119,    115,    113,    110,    109,     99,\n        98,     95,     79,     68,     52,     50,     48,     45,\n        43,     32,     31,     27,     18,     10,      3,      0,\n       255,    251,    235,    230,    212,    201,    196,    182,\n       167,    166,    163,    151,    138,    124,    110,    104,\n        90,     78,     76,     70,     69,     57,     45,     34,\n        24,     21,     11,      6,      5,      4,      3,      0\n};\n\nstatic const opus_uint8 silk_NLSF_CB2_SELECT_WB[ 256 ] = {\n         0,      0,      0,      0,      0,      0,      0,      1,\n       100,    102,    102,     68,     68,     36,     34,     96,\n       164,    107,    158,    185,    180,    185,    139,    102,\n        64,     66,     36,     34,     34,      0,      1,     32,\n       208,    139,    141,    191,    152,    185,    155,    104,\n        96,    171,    104,    166,    102,    102,    102,    132,\n         1,      0,      0,      0,      0,     16,     16,      0,\n        80,    109,     78,    107,    185,    139,    103,    101,\n       208,    212,    141,    139,    173,    153,    123,    103,\n        36,      0,      0,      0,      0,      0,      0,      1,\n        48,      0,      0,      0,      0,      0,      0,     32,\n        68,    135,    123,    119,    119,    103,     69,     98,\n        68,    103,    120,    118,    118,    102,     71,     98,\n       134,    136,    157,    184,    182,    153,    139,    134,\n       208,    168,    248,     75,    189,    143,    121,    107,\n        32,     49,     34,     34,     34,      0,     17,      2,\n       210,    235,    139,    123,    185,    137,    105,    134,\n        98,    135,    104,    182,    100,    183,    171,    134,\n       100,     70,     68,     70,     66,     66,     34,    131,\n        64,    166,    102,     68,     36,      2,      1,      0,\n       134,    166,    102,     68,     34,     34,     66,    132,\n       212,    246,    158,    139,    107,    107,     87,    102,\n       100,    219,    125,    122,    137,    118,    103,    132,\n       114,    135,    137,    105,    171,    106,     50,     34,\n       164,    214,    141,    143,    185,    151,    121,    103,\n       192,     34,      0,      0,      0,      0,      0,      1,\n       208,    109,     74,    187,    134,    249,    159,    137,\n       102,    110,    154,    118,     87,    101,    119,    101,\n         0,      2,      0,     36,     36,     66,     68,     35,\n        96,    164,    102,    100,     36,      0,      2,     33,\n       167,    138,    174,    102,    100,     84,      2,      2,\n       100,    107,    120,    119,     36,    197,     24,      0\n};\n\nstatic const opus_uint8 silk_NLSF_CB2_iCDF_WB[ 72 ] = {\n       255,    254,    253,    244,     12,      3,      2,      1,\n         0,    255,    254,    252,    224,     38,      3,      2,\n         1,      0,    255,    254,    251,    209,     57,      4,\n         2,      1,      0,    255,    254,    244,    195,     69,\n         4,      2,      1,      0,    255,    251,    232,    184,\n        84,      7,      2,      1,      0,    255,    254,    240,\n       186,     86,     14,      2,      1,      0,    255,    254,\n       239,    178,     91,     30,      5,      1,      0,    255,\n       248,    227,    177,    100,     19,      2,      1,      0\n};\n\nstatic const opus_uint8 silk_NLSF_CB2_BITS_WB_Q5[ 72 ] = {\n       255,    255,    255,    156,      4,    154,    255,    255,\n       255,    255,    255,    227,    102,     15,     92,    255,\n       255,    255,    255,    255,    213,     83,     24,     72,\n       236,    255,    255,    255,    255,    150,     76,     33,\n        63,    214,    255,    255,    255,    190,    121,     77,\n        43,     55,    185,    255,    255,    255,    245,    137,\n        71,     43,     59,    139,    255,    255,    255,    255,\n       131,     66,     50,     66,    107,    194,    255,    255,\n       166,    116,     76,     55,     53,    125,    255,    255\n};\n\nstatic const opus_uint8 silk_NLSF_PRED_WB_Q8[ 30 ] = {\n       175,    148,    160,    176,    178,    173,    174,    164,\n       177,    174,    196,    182,    198,    192,    182,     68,\n        62,     66,     60,     72,    117,     85,     90,    118,\n       136,    151,    142,    160,    142,    155\n};\n\nstatic const opus_int16 silk_NLSF_DELTA_MIN_WB_Q15[ 17 ] = {\n       100,      3,     40,      3,      3,      3,      5,     14,\n        14,     10,     11,      3,      8,      9,      7,      3,\n       347\n};\n\nconst silk_NLSF_CB_struct silk_NLSF_CB_WB =\n{\n    32,\n    16,\n    SILK_FIX_CONST( 0.15, 16 ),\n    SILK_FIX_CONST( 1.0 / 0.15, 6 ),\n    silk_NLSF_CB1_WB_Q8,\n    silk_NLSF_CB1_iCDF_WB,\n    silk_NLSF_PRED_WB_Q8,\n    silk_NLSF_CB2_SELECT_WB,\n    silk_NLSF_CB2_iCDF_WB,\n    silk_NLSF_CB2_BITS_WB_Q5,\n    silk_NLSF_DELTA_MIN_WB_Q15,\n};\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/tables_gain.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"tables.h\"\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\nconst opus_uint8 silk_gain_iCDF[ 3 ][ N_LEVELS_QGAIN / 8 ] =\n{\n{\n       224,    112,     44,     15,      3,      2,      1,      0\n},\n{\n       254,    237,    192,    132,     70,     23,      4,      0\n},\n{\n       255,    252,    226,    155,     61,     11,      2,      0\n}\n};\n\nconst opus_uint8 silk_delta_gain_iCDF[ MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ] = {\n       250,    245,    234,    203,     71,     50,     42,     38,\n        35,     33,     31,     29,     28,     27,     26,     25,\n        24,     23,     22,     21,     20,     19,     18,     17,\n        16,     15,     14,     13,     12,     11,     10,      9,\n         8,      7,      6,      5,      4,      3,      2,      1,\n         0\n};\n\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/tables_other.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"structs.h\"\n#include \"define.h\"\n#include \"tables.h\"\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */\nconst opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ] = {\n    0,      8000,   9400,   11500,  13500,  17500,  25000,  MAX_TARGET_RATE_BPS\n};\nconst opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ] = {\n    0,      9000,   12000,  14500,  18500,  24500,  35500,  MAX_TARGET_RATE_BPS\n};\nconst opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ] = {\n    0,      10500,  14000,  17000,  21500,  28500,  42000,  MAX_TARGET_RATE_BPS\n};\nconst opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ] = {\n    18,     29,     38,     40,     46,     52,     62,     84\n};\n\n/* Tables for stereo predictor coding */\nconst opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = {\n    -13732, -10050, -8266, -7526, -6500, -5000, -2950,  -820,\n       820,   2950,  5000,  6500,  7526,  8266, 10050, 13732\n};\nconst opus_uint8  silk_stereo_pred_joint_iCDF[ 25 ] = {\n    249, 247, 246, 245, 244,\n    234, 210, 202, 201, 200,\n    197, 174,  82,  59,  56,\n     55,  54,  46,  22,  12,\n     11,  10,   9,   7,   0\n};\nconst opus_uint8  silk_stereo_only_code_mid_iCDF[ 2 ] = { 64, 0 };\n\n/* Tables for LBRR flags */\nstatic const opus_uint8 silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 };\nstatic const opus_uint8 silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 };\nconst opus_uint8 * const silk_LBRR_flags_iCDF_ptr[ 2 ] = {\n    silk_LBRR_flags_2_iCDF,\n    silk_LBRR_flags_3_iCDF\n};\n\n/* Table for LSB coding */\nconst opus_uint8 silk_lsb_iCDF[ 2 ] = { 120, 0 };\n\n/* Tables for LTPScale */\nconst opus_uint8 silk_LTPscale_iCDF[ 3 ] = { 128, 64, 0 };\n\n/* Tables for signal type and offset coding */\nconst opus_uint8 silk_type_offset_VAD_iCDF[ 4 ] = {\n       232,    158,    10,      0\n};\nconst opus_uint8 silk_type_offset_no_VAD_iCDF[ 2 ] = {\n       230,      0\n};\n\n/* Tables for NLSF interpolation factor */\nconst opus_uint8 silk_NLSF_interpolation_factor_iCDF[ 5 ] = { 243, 221, 192, 181, 0 };\n\n/* Quantization offsets */\nconst opus_int16  silk_Quantization_Offsets_Q10[ 2 ][ 2 ] = {\n    { OFFSET_UVL_Q10, OFFSET_UVH_Q10 }, { OFFSET_VL_Q10, OFFSET_VH_Q10 }\n};\n\n/* Table for LTPScale */\nconst opus_int16 silk_LTPScales_table_Q14[ 3 ] = { 15565, 12288, 8192 };\n\n/* Uniform entropy tables */\nconst opus_uint8 silk_uniform3_iCDF[ 3 ] = { 171, 85, 0 };\nconst opus_uint8 silk_uniform4_iCDF[ 4 ] = { 192, 128, 64, 0 };\nconst opus_uint8 silk_uniform5_iCDF[ 5 ] = { 205, 154, 102, 51, 0 };\nconst opus_uint8 silk_uniform6_iCDF[ 6 ] = { 213, 171, 128, 85, 43, 0 };\nconst opus_uint8 silk_uniform8_iCDF[ 8 ] = { 224, 192, 160, 128, 96, 64, 32, 0 };\n\nconst opus_uint8 silk_NLSF_EXT_iCDF[ 7 ] = { 100, 40, 16, 7, 3, 1, 0 };\n\n/*  Elliptic/Cauer filters designed with 0.1 dB passband ripple,\n        80 dB minimum stopband attenuation, and\n        [0.95 : 0.15 : 0.35] normalized cut off frequencies. */\n\n/* Interpolation points for filter coefficients used in the bandwidth transition smoother */\nconst opus_int32 silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NB ] =\n{\n{    250767114,  501534038,  250767114  },\n{    209867381,  419732057,  209867381  },\n{    170987846,  341967853,  170987846  },\n{    131531482,  263046905,  131531482  },\n{     89306658,  178584282,   89306658  }\n};\n\n/* Interpolation points for filter coefficients used in the bandwidth transition smoother */\nconst opus_int32 silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NA ] =\n{\n{    506393414,  239854379  },\n{    411067935,  169683996  },\n{    306733530,  116694253  },\n{    185807084,   77959395  },\n{     35497197,   57401098  }\n};\n\n#ifdef __cplusplus\n}\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/tables_pitch_lag.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"tables.h\"\n\nconst opus_uint8 silk_pitch_lag_iCDF[ 2 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) ] = {\n       253,    250,    244,    233,    212,    182,    150,    131,\n       120,    110,     98,     85,     72,     60,     49,     40,\n        32,     25,     19,     15,     13,     11,      9,      8,\n         7,      6,      5,      4,      3,      2,      1,      0\n};\n\nconst opus_uint8 silk_pitch_delta_iCDF[21] = {\n       210,    208,    206,    203,    199,    193,    183,    168,\n       142,    104,     74,     52,     37,     27,     20,     14,\n        10,      6,      4,      2,      0\n};\n\nconst opus_uint8 silk_pitch_contour_iCDF[34] = {\n       223,    201,    183,    167,    152,    138,    124,    111,\n        98,     88,     79,     70,     62,     56,     50,     44,\n        39,     35,     31,     27,     24,     21,     18,     16,\n        14,     12,     10,      8,      6,      4,      3,      2,\n         1,      0\n};\n\nconst opus_uint8 silk_pitch_contour_NB_iCDF[11] = {\n       188,    176,    155,    138,    119,     97,     67,     43,\n        26,     10,      0\n};\n\nconst opus_uint8 silk_pitch_contour_10_ms_iCDF[12] = {\n       165,    119,     80,     61,     47,     35,     27,     20,\n        14,      9,      4,      0\n};\n\nconst opus_uint8 silk_pitch_contour_10_ms_NB_iCDF[3] = {\n       113,     63,      0\n};\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/tables_pulses_per_block.c",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"tables.h\"\n\nconst opus_uint8 silk_max_pulses_table[ 4 ] = {\n         8,     10,     12,     16\n};\n\nconst opus_uint8 silk_pulses_per_block_iCDF[ 10 ][ 18 ] = {\n{\n       125,     51,     26,     18,     15,     12,     11,     10,\n         9,      8,      7,      6,      5,      4,      3,      2,\n         1,      0\n},\n{\n       198,    105,     45,     22,     15,     12,     11,     10,\n         9,      8,      7,      6,      5,      4,      3,      2,\n         1,      0\n},\n{\n       213,    162,    116,     83,     59,     43,     32,     24,\n        18,     15,     12,      9,      7,      6,      5,      3,\n         2,      0\n},\n{\n       239,    187,    116,     59,     28,     16,     11,     10,\n         9,      8,      7,      6,      5,      4,      3,      2,\n         1,      0\n},\n{\n       250,    229,    188,    135,     86,     51,     30,     19,\n        13,     10,      8,      6,      5,      4,      3,      2,\n         1,      0\n},\n{\n       249,    235,    213,    185,    156,    128,    103,     83,\n        66,     53,     42,     33,     26,     21,     17,     13,\n        10,      0\n},\n{\n       254,    249,    235,    206,    164,    118,     77,     46,\n        27,     16,     10,      7,      5,      4,      3,      2,\n         1,      0\n},\n{\n       255,    253,    249,    239,    220,    191,    156,    119,\n        85,     57,     37,     23,     15,     10,      6,      4,\n         2,      0\n},\n{\n       255,    253,    251,    246,    237,    223,    203,    179,\n       152,    124,     98,     75,     55,     40,     29,     21,\n        15,      0\n},\n{\n       255,    254,    253,    247,    220,    162,    106,     67,\n        42,     28,     18,     12,      9,      6,      4,      3,\n         2,      0\n}\n};\n\nconst opus_uint8 silk_pulses_per_block_BITS_Q5[ 9 ][ 18 ] = {\n{\n        31,     57,    107,    160,    205,    205,    255,    255,\n       255,    255,    255,    255,    255,    255,    255,    255,\n       255,    255\n},\n{\n        69,     47,     67,    111,    166,    205,    255,    255,\n       255,    255,    255,    255,    255,    255,    255,    255,\n       255,    255\n},\n{\n        82,     74,     79,     95,    109,    128,    145,    160,\n       173,    205,    205,    205,    224,    255,    255,    224,\n       255,    224\n},\n{\n       125,     74,     59,     69,     97,    141,    182,    255,\n       255,    255,    255,    255,    255,    255,    255,    255,\n       255,    255\n},\n{\n       173,    115,     85,     73,     76,     92,    115,    145,\n       173,    205,    224,    224,    255,    255,    255,    255,\n       255,    255\n},\n{\n       166,    134,    113,    102,    101,    102,    107,    118,\n       125,    138,    145,    155,    166,    182,    192,    192,\n       205,    150\n},\n{\n       224,    182,    134,    101,     83,     79,     85,     97,\n       120,    145,    173,    205,    224,    255,    255,    255,\n       255,    255\n},\n{\n       255,    224,    192,    150,    120,    101,     92,     89,\n        93,    102,    118,    134,    160,    182,    192,    224,\n       224,    224\n},\n{\n       255,    224,    224,    182,    155,    134,    118,    109,\n       104,    102,    106,    111,    118,    131,    145,    160,\n       173,    131\n}\n};\n\nconst opus_uint8 silk_rate_levels_iCDF[ 2 ][ 9 ] =\n{\n{\n       241,    190,    178,    132,     87,     74,     41,     14,\n         0\n},\n{\n       223,    193,    157,    140,    106,     57,     39,     18,\n         0\n}\n};\n\nconst opus_uint8 silk_rate_levels_BITS_Q5[ 2 ][ 9 ] =\n{\n{\n       131,     74,    141,     79,     80,    138,     95,    104,\n       134\n},\n{\n        95,     99,     91,    125,     93,     76,    123,    115,\n       123\n}\n};\n\nconst opus_uint8 silk_shell_code_table0[ 152 ] = {\n       128,      0,    214,     42,      0,    235,    128,     21,\n         0,    244,    184,     72,     11,      0,    248,    214,\n       128,     42,      7,      0,    248,    225,    170,     80,\n        25,      5,      0,    251,    236,    198,    126,     54,\n        18,      3,      0,    250,    238,    211,    159,     82,\n        35,     15,      5,      0,    250,    231,    203,    168,\n       128,     88,     53,     25,      6,      0,    252,    238,\n       216,    185,    148,    108,     71,     40,     18,      4,\n         0,    253,    243,    225,    199,    166,    128,     90,\n        57,     31,     13,      3,      0,    254,    246,    233,\n       212,    183,    147,    109,     73,     44,     23,     10,\n         2,      0,    255,    250,    240,    223,    198,    166,\n       128,     90,     58,     33,     16,      6,      1,      0,\n       255,    251,    244,    231,    210,    181,    146,    110,\n        75,     46,     25,     12,      5,      1,      0,    255,\n       253,    248,    238,    221,    196,    164,    128,     92,\n        60,     35,     18,      8,      3,      1,      0,    255,\n       253,    249,    242,    229,    208,    180,    146,    110,\n        76,     48,     27,     14,      7,      3,      1,      0\n};\n\nconst opus_uint8 silk_shell_code_table1[ 152 ] = {\n       129,      0,    207,     50,      0,    236,    129,     20,\n         0,    245,    185,     72,     10,      0,    249,    213,\n       129,     42,      6,      0,    250,    226,    169,     87,\n        27,      4,      0,    251,    233,    194,    130,     62,\n        20,      4,      0,    250,    236,    207,    160,     99,\n        47,     17,      3,      0,    255,    240,    217,    182,\n       131,     81,     41,     11,      1,      0,    255,    254,\n       233,    201,    159,    107,     61,     20,      2,      1,\n         0,    255,    249,    233,    206,    170,    128,     86,\n        50,     23,      7,      1,      0,    255,    250,    238,\n       217,    186,    148,    108,     70,     39,     18,      6,\n         1,      0,    255,    252,    243,    226,    200,    166,\n       128,     90,     56,     30,     13,      4,      1,      0,\n       255,    252,    245,    231,    209,    180,    146,    110,\n        76,     47,     25,     11,      4,      1,      0,    255,\n       253,    248,    237,    219,    194,    163,    128,     93,\n        62,     37,     19,      8,      3,      1,      0,    255,\n       254,    250,    241,    226,    205,    177,    145,    111,\n        79,     51,     30,     15,      6,      2,      1,      0\n};\n\nconst opus_uint8 silk_shell_code_table2[ 152 ] = {\n       129,      0,    203,     54,      0,    234,    129,     23,\n         0,    245,    184,     73,     10,      0,    250,    215,\n       129,     41,      5,      0,    252,    232,    173,     86,\n        24,      3,      0,    253,    240,    200,    129,     56,\n        15,      2,      0,    253,    244,    217,    164,     94,\n        38,     10,      1,      0,    253,    245,    226,    189,\n       132,     71,     27,      7,      1,      0,    253,    246,\n       231,    203,    159,    105,     56,     23,      6,      1,\n         0,    255,    248,    235,    213,    179,    133,     85,\n        47,     19,      5,      1,      0,    255,    254,    243,\n       221,    194,    159,    117,     70,     37,     12,      2,\n         1,      0,    255,    254,    248,    234,    208,    171,\n       128,     85,     48,     22,      8,      2,      1,      0,\n       255,    254,    250,    240,    220,    189,    149,    107,\n        67,     36,     16,      6,      2,      1,      0,    255,\n       254,    251,    243,    227,    201,    166,    128,     90,\n        55,     29,     13,      5,      2,      1,      0,    255,\n       254,    252,    246,    234,    213,    183,    147,    109,\n        73,     43,     22,     10,      4,      2,      1,      0\n};\n\nconst opus_uint8 silk_shell_code_table3[ 152 ] = {\n       130,      0,    200,     58,      0,    231,    130,     26,\n         0,    244,    184,     76,     12,      0,    249,    214,\n       130,     43,      6,      0,    252,    232,    173,     87,\n        24,      3,      0,    253,    241,    203,    131,     56,\n        14,      2,      0,    254,    246,    221,    167,     94,\n        35,      8,      1,      0,    254,    249,    232,    193,\n       130,     65,     23,      5,      1,      0,    255,    251,\n       239,    211,    162,     99,     45,     15,      4,      1,\n         0,    255,    251,    243,    223,    186,    131,     74,\n        33,     11,      3,      1,      0,    255,    252,    245,\n       230,    202,    158,    105,     57,     24,      8,      2,\n         1,      0,    255,    253,    247,    235,    214,    179,\n       132,     84,     44,     19,      7,      2,      1,      0,\n       255,    254,    250,    240,    223,    196,    159,    112,\n        69,     36,     15,      6,      2,      1,      0,    255,\n       254,    253,    245,    231,    209,    176,    136,     93,\n        55,     27,     11,      3,      2,      1,      0,    255,\n       254,    253,    252,    239,    221,    194,    158,    117,\n        76,     42,     18,      4,      3,      2,      1,      0\n};\n\nconst opus_uint8 silk_shell_code_table_offsets[ 17 ] = {\n         0,      0,      2,      5,      9,     14,     20,     27,\n        35,     44,     54,     65,     77,     90,    104,    119,\n       135\n};\n\nconst opus_uint8 silk_sign_iCDF[ 42 ] = {\n       254,     49,     67,     77,     82,     93,     99,\n       198,     11,     18,     24,     31,     36,     45,\n       255,     46,     66,     78,     87,     94,    104,\n       208,     14,     21,     32,     42,     51,     66,\n       255,     94,    104,    109,    112,    115,    118,\n       248,     53,     69,     80,     88,     95,    102\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/tuning_parameters.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_TUNING_PARAMETERS_H\n#define SILK_TUNING_PARAMETERS_H\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/* Decay time for bitreservoir */\n#define BITRESERVOIR_DECAY_TIME_MS                      500\n\n/*******************/\n/* Pitch estimator */\n/*******************/\n\n/* Level of noise floor for whitening filter LPC analysis in pitch analysis */\n#define FIND_PITCH_WHITE_NOISE_FRACTION                 1e-3f\n\n/* Bandwidth expansion for whitening filter in pitch analysis */\n#define FIND_PITCH_BANDWIDTH_EXPANSION                  0.99f\n\n/*********************/\n/* Linear prediction */\n/*********************/\n\n/* LPC analysis regularization */\n#define FIND_LPC_COND_FAC                               1e-5f\n\n/* LTP analysis defines */\n#define FIND_LTP_COND_FAC                               1e-5f\n#define LTP_DAMPING                                     0.05f\n#define LTP_SMOOTHING                                   0.1f\n\n/* LTP quantization settings */\n#define MU_LTP_QUANT_NB                                 0.03f\n#define MU_LTP_QUANT_MB                                 0.025f\n#define MU_LTP_QUANT_WB                                 0.02f\n\n/* Max cumulative LTP gain */\n#define MAX_SUM_LOG_GAIN_DB                             250.0f\n\n/***********************/\n/* High pass filtering */\n/***********************/\n\n/* Smoothing parameters for low end of pitch frequency range estimation */\n#define VARIABLE_HP_SMTH_COEF1                          0.1f\n#define VARIABLE_HP_SMTH_COEF2                          0.015f\n#define VARIABLE_HP_MAX_DELTA_FREQ                      0.4f\n\n/* Min and max cut-off frequency values (-3 dB points) */\n#define VARIABLE_HP_MIN_CUTOFF_HZ                       60\n#define VARIABLE_HP_MAX_CUTOFF_HZ                       100\n\n/***********/\n/* Various */\n/***********/\n\n/* VAD threshold */\n#define SPEECH_ACTIVITY_DTX_THRES                       0.05f\n\n/* Speech Activity LBRR enable threshold */\n#define LBRR_SPEECH_ACTIVITY_THRES                      0.3f\n\n/*************************/\n/* Perceptual parameters */\n/*************************/\n\n/* reduction in coding SNR during low speech activity */\n#define BG_SNR_DECR_dB                                  2.0f\n\n/* factor for reducing quantization noise during voiced speech */\n#define HARM_SNR_INCR_dB                                2.0f\n\n/* factor for reducing quantization noise for unvoiced sparse signals */\n#define SPARSE_SNR_INCR_dB                              2.0f\n\n/* threshold for sparseness measure above which to use lower quantization offset during unvoiced */\n#define SPARSENESS_THRESHOLD_QNT_OFFSET                 0.75f\n\n/* warping control */\n#define WARPING_MULTIPLIER                              0.015f\n\n/* fraction added to first autocorrelation value */\n#define SHAPE_WHITE_NOISE_FRACTION                      5e-5f\n\n/* noise shaping filter chirp factor */\n#define BANDWIDTH_EXPANSION                             0.95f\n\n/* difference between chirp factors for analysis and synthesis noise shaping filters at low bitrates */\n#define LOW_RATE_BANDWIDTH_EXPANSION_DELTA              0.01f\n\n/* extra harmonic boosting (signal shaping) at low bitrates */\n#define LOW_RATE_HARMONIC_BOOST                         0.1f\n\n/* extra harmonic boosting (signal shaping) for noisy input signals */\n#define LOW_INPUT_QUALITY_HARMONIC_BOOST                0.1f\n\n/* harmonic noise shaping */\n#define HARMONIC_SHAPING                                0.3f\n\n/* extra harmonic noise shaping for high bitrates or noisy input */\n#define HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING       0.2f\n\n/* parameter for shaping noise towards higher frequencies */\n#define HP_NOISE_COEF                                   0.25f\n\n/* parameter for shaping noise even more towards higher frequencies during voiced speech */\n#define HARM_HP_NOISE_COEF                              0.35f\n\n/* parameter for applying a high-pass tilt to the input signal */\n#define INPUT_TILT                                      0.05f\n\n/* parameter for extra high-pass tilt to the input signal at high rates */\n#define HIGH_RATE_INPUT_TILT                            0.1f\n\n/* parameter for reducing noise at the very low frequencies */\n#define LOW_FREQ_SHAPING                                4.0f\n\n/* less reduction of noise at the very low frequencies for signals with low SNR at low frequencies */\n#define LOW_QUALITY_LOW_FREQ_SHAPING_DECR               0.5f\n\n/* subframe smoothing coefficient for HarmBoost, HarmShapeGain, Tilt (lower -> more smoothing) */\n#define SUBFR_SMTH_COEF                                 0.4f\n\n/* parameters defining the R/D tradeoff in the residual quantizer */\n#define LAMBDA_OFFSET                                   1.2f\n#define LAMBDA_SPEECH_ACT                               -0.2f\n#define LAMBDA_DELAYED_DECISIONS                        -0.05f\n#define LAMBDA_INPUT_QUALITY                            -0.1f\n#define LAMBDA_CODING_QUALITY                           -0.2f\n#define LAMBDA_QUANT_OFFSET                             0.8f\n\n/* Compensation in bitrate calculations for 10 ms modes */\n#define REDUCE_BITRATE_10_MS_BPS                        2200\n\n/* Maximum time before allowing a bandwidth transition */\n#define MAX_BANDWIDTH_SWITCH_DELAY_MS                   5000\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* SILK_TUNING_PARAMETERS_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/typedef.h",
    "content": "/***********************************************************************\nCopyright (c) 2006-2011, Skype Limited. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n- Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n- Neither the name of Internet Society, IETF or IETF Trust, nor the\nnames of specific contributors, may be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n***********************************************************************/\n\n#ifndef SILK_TYPEDEF_H\n#define SILK_TYPEDEF_H\n\n#include \"opus_types.h\"\n#include \"opus_defines.h\"\n\n#ifndef FIXED_POINT\n# include <float.h>\n# define silk_float      float\n# define silk_float_MAX  FLT_MAX\n#endif\n\n#define silk_int64_MAX   ((opus_int64)0x7FFFFFFFFFFFFFFFLL)   /*  2^63 - 1 */\n#define silk_int64_MIN   ((opus_int64)0x8000000000000000LL)   /* -2^63 */\n#define silk_int32_MAX   0x7FFFFFFF                           /*  2^31 - 1 =  2147483647 */\n#define silk_int32_MIN   ((opus_int32)0x80000000)             /* -2^31     = -2147483648 */\n#define silk_int16_MAX   0x7FFF                               /*  2^15 - 1 =  32767 */\n#define silk_int16_MIN   ((opus_int16)0x8000)                 /* -2^15     = -32768 */\n#define silk_int8_MAX    0x7F                                 /*  2^7 - 1  =  127 */\n#define silk_int8_MIN    ((opus_int8)0x80)                    /* -2^7      = -128 */\n#define silk_uint8_MAX   0xFF                                 /*  2^8 - 1 = 255 */\n\n#define silk_TRUE        1\n#define silk_FALSE       0\n\n/* assertions */\n#if (defined _WIN32 && !defined _WINCE && !defined(__GNUC__) && !defined(NO_ASSERTS))\n# ifndef silk_assert\n#  include <crtdbg.h>      /* ASSERTE() */\n#  define silk_assert(COND)   _ASSERTE(COND)\n# endif\n#else\n# ifdef ENABLE_ASSERTIONS\n#  include <stdio.h>\n#  include <stdlib.h>\n#define silk_fatal(str) _silk_fatal(str, __FILE__, __LINE__);\n#ifdef __GNUC__\n__attribute__((noreturn))\n#endif\nstatic OPUS_INLINE void _silk_fatal(const char *str, const char *file, int line)\n{\n   fprintf (stderr, \"Fatal (internal) error in %s, line %d: %s\\n\", file, line, str);\n   abort();\n}\n#  define silk_assert(COND) {if (!(COND)) {silk_fatal(\"assertion failed: \" #COND);}}\n# else\n#  define silk_assert(COND)\n# endif\n#endif\n\n#endif /* SILK_TYPEDEF_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/x86/NSQ_del_dec_sse.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <xmmintrin.h>\n#include <emmintrin.h>\n#include <smmintrin.h>\n#include \"main.h\"\n#include \"celt/x86/x86cpu.h\"\n\n#include \"stack_alloc.h\"\n\ntypedef struct {\n    opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];\n    opus_int32 RandState[ DECISION_DELAY ];\n    opus_int32 Q_Q10[     DECISION_DELAY ];\n    opus_int32 Xq_Q14[    DECISION_DELAY ];\n    opus_int32 Pred_Q15[  DECISION_DELAY ];\n    opus_int32 Shape_Q14[ DECISION_DELAY ];\n    opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];\n    opus_int32 LF_AR_Q14;\n    opus_int32 Seed;\n    opus_int32 SeedInit;\n    opus_int32 RD_Q10;\n} NSQ_del_dec_struct;\n\ntypedef struct {\n    opus_int32 Q_Q10;\n    opus_int32 RD_Q10;\n    opus_int32 xq_Q14;\n    opus_int32 LF_AR_Q14;\n    opus_int32 sLTP_shp_Q14;\n    opus_int32 LPC_exc_Q14;\n} NSQ_sample_struct;\n\ntypedef NSQ_sample_struct  NSQ_sample_pair[ 2 ];\n\nstatic OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1(\n    const silk_encoder_state *psEncC,               /* I    Encoder State                       */\n    silk_nsq_state      *NSQ,                       /* I/O  NSQ state                           */\n    NSQ_del_dec_struct  psDelDec[],                 /* I/O  Delayed decision states             */\n    const opus_int32    x_Q3[],                     /* I    Input in Q3                         */\n    opus_int32          x_sc_Q10[],                 /* O    Input scaled with 1/Gain in Q10     */\n    const opus_int16    sLTP[],                     /* I    Re-whitened LTP state in Q0         */\n    opus_int32          sLTP_Q15[],                 /* O    LTP state matching scaled input     */\n    opus_int            subfr,                      /* I    Subframe number                     */\n    opus_int            nStatesDelayedDecision,     /* I    Number of del dec states            */\n    const opus_int      LTP_scale_Q14,              /* I    LTP state scaling                   */\n    const opus_int32    Gains_Q16[ MAX_NB_SUBFR ],  /* I                                        */\n    const opus_int      pitchL[ MAX_NB_SUBFR ],     /* I    Pitch lag                           */\n    const opus_int      signal_type,                /* I    Signal type                         */\n    const opus_int      decisionDelay               /* I    Decision delay                      */\n);\n\n/******************************************/\n/* Noise shape quantizer for one subframe */\n/******************************************/\nstatic OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1(\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                           */\n    NSQ_del_dec_struct  psDelDec[],             /* I/O  Delayed decision states             */\n    opus_int            signalType,             /* I    Signal type                         */\n    const opus_int32    x_Q10[],                /* I                                        */\n    opus_int8           pulses[],               /* O                                        */\n    opus_int16          xq[],                   /* O                                        */\n    opus_int32          sLTP_Q15[],             /* I/O  LTP filter state                    */\n    opus_int32          delayedGain_Q10[],      /* I/O  Gain delay buffer                   */\n    const opus_int16    a_Q12[],                /* I    Short term prediction coefs         */\n    const opus_int16    b_Q14[],                /* I    Long term prediction coefs          */\n    const opus_int16    AR_shp_Q13[],           /* I    Noise shaping coefs                 */\n    opus_int            lag,                    /* I    Pitch lag                           */\n    opus_int32          HarmShapeFIRPacked_Q14, /* I                                        */\n    opus_int            Tilt_Q14,               /* I    Spectral tilt                       */\n    opus_int32          LF_shp_Q14,             /* I                                        */\n    opus_int32          Gain_Q16,               /* I                                        */\n    opus_int            Lambda_Q10,             /* I                                        */\n    opus_int            offset_Q10,             /* I                                        */\n    opus_int            length,                 /* I    Input length                        */\n    opus_int            subfr,                  /* I    Subframe number                     */\n    opus_int            shapingLPCOrder,        /* I    Shaping LPC filter order            */\n    opus_int            predictLPCOrder,        /* I    Prediction filter order             */\n    opus_int            warping_Q16,            /* I                                        */\n    opus_int            nStatesDelayedDecision, /* I    Number of states in decision tree   */\n    opus_int            *smpl_buf_idx,          /* I    Index to newest samples in buffers  */\n    opus_int            decisionDelay           /* I                                        */\n);\n\nvoid silk_NSQ_del_dec_sse4_1(\n    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */\n    silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */\n    SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */\n    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */\n    opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */\n    const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */\n    const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */\n    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */\n    const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */\n    const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */\n    const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */\n    const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */\n    const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */\n    const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */\n    const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */\n)\n{\n    opus_int            i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;\n    opus_int            last_smple_idx, smpl_buf_idx, decisionDelay;\n    const opus_int16    *A_Q12, *B_Q14, *AR_shp_Q13;\n    opus_int16          *pxq;\n    VARDECL( opus_int32, sLTP_Q15 );\n    VARDECL( opus_int16, sLTP );\n    opus_int32          HarmShapeFIRPacked_Q14;\n    opus_int            offset_Q10;\n    opus_int32          RDmin_Q10, Gain_Q10;\n    VARDECL( opus_int32, x_sc_Q10 );\n    VARDECL( opus_int32, delayedGain_Q10 );\n    VARDECL( NSQ_del_dec_struct, psDelDec );\n    NSQ_del_dec_struct  *psDD;\n    SAVE_STACK;\n\n    /* Set unvoiced lag to the previous one, overwrite later for voiced */\n    lag = NSQ->lagPrev;\n\n    silk_assert( NSQ->prev_gain_Q16 != 0 );\n\n    /* Initialize delayed decision states */\n    ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct );\n    silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );\n    for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {\n        psDD                 = &psDelDec[ k ];\n        psDD->Seed           = ( k + psIndices->Seed ) & 3;\n        psDD->SeedInit       = psDD->Seed;\n        psDD->RD_Q10         = 0;\n        psDD->LF_AR_Q14      = NSQ->sLF_AR_shp_Q14;\n        psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ];\n        silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );\n        silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );\n    }\n\n    offset_Q10   = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];\n    smpl_buf_idx = 0; /* index of oldest samples */\n\n    decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );\n\n    /* For voiced frames limit the decision delay to lower than the pitch lag */\n    if( psIndices->signalType == TYPE_VOICED ) {\n        for( k = 0; k < psEncC->nb_subfr; k++ ) {\n            decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 );\n        }\n    } else {\n        if( lag > 0 ) {\n            decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );\n        }\n    }\n\n    if( psIndices->NLSFInterpCoef_Q2 == 4 ) {\n        LSF_interpolation_flag = 0;\n    } else {\n        LSF_interpolation_flag = 1;\n    }\n\n    ALLOC( sLTP_Q15,\n           psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );\n    ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );\n    ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );\n    ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );\n    /* Set up pointers to start of sub frame */\n    pxq                   = &NSQ->xq[ psEncC->ltp_mem_length ];\n    NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;\n    NSQ->sLTP_buf_idx     = psEncC->ltp_mem_length;\n    subfr = 0;\n    for( k = 0; k < psEncC->nb_subfr; k++ ) {\n        A_Q12      = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];\n        B_Q14      = &LTPCoef_Q14[ k * LTP_ORDER           ];\n        AR_shp_Q13 = &AR2_Q13[     k * MAX_SHAPE_LPC_ORDER ];\n\n        /* Noise shape parameters */\n        silk_assert( HarmShapeGain_Q14[ k ] >= 0 );\n        HarmShapeFIRPacked_Q14  =                          silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );\n        HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );\n\n        NSQ->rewhite_flag = 0;\n        if( psIndices->signalType == TYPE_VOICED ) {\n            /* Voiced */\n            lag = pitchL[ k ];\n\n            /* Re-whitening */\n            if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {\n                if( k == 2 ) {\n                    /* RESET DELAYED DECISIONS */\n                    /* Find winner */\n                    RDmin_Q10 = psDelDec[ 0 ].RD_Q10;\n                    Winner_ind = 0;\n                    for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {\n                        if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {\n                            RDmin_Q10 = psDelDec[ i ].RD_Q10;\n                            Winner_ind = i;\n                        }\n                    }\n                    for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {\n                        if( i != Winner_ind ) {\n                            psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 );\n                            silk_assert( psDelDec[ i ].RD_Q10 >= 0 );\n                        }\n                    }\n\n                    /* Copy final part of signals from winner state to output and long-term filter states */\n                    psDD = &psDelDec[ Winner_ind ];\n                    last_smple_idx = smpl_buf_idx + decisionDelay;\n                    for( i = 0; i < decisionDelay; i++ ) {\n                        last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;\n                        pulses[   i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );\n                        pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(\n                            silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );\n                        NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];\n                    }\n\n                    subfr = 0;\n                }\n\n                /* Rewhiten with new A coefs */\n                start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;\n                silk_assert( start_idx > 0 );\n\n                silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],\n                    A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );\n\n                NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;\n                NSQ->rewhite_flag = 1;\n            }\n        }\n\n        silk_nsq_del_dec_scale_states_sse4_1( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k,\n            psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );\n\n        silk_noise_shape_quantizer_del_dec_sse4_1( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,\n            delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],\n            Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,\n            psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );\n\n        x_Q3   += psEncC->subfr_length;\n        pulses += psEncC->subfr_length;\n        pxq    += psEncC->subfr_length;\n    }\n\n    /* Find winner */\n    RDmin_Q10 = psDelDec[ 0 ].RD_Q10;\n    Winner_ind = 0;\n    for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {\n        if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {\n            RDmin_Q10 = psDelDec[ k ].RD_Q10;\n            Winner_ind = k;\n        }\n    }\n\n    /* Copy final part of signals from winner state to output and long-term filter states */\n    psDD = &psDelDec[ Winner_ind ];\n    psIndices->Seed = psDD->SeedInit;\n    last_smple_idx = smpl_buf_idx + decisionDelay;\n    Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );\n    for( i = 0; i < decisionDelay; i++ ) {\n        last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;\n        pulses[   i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );\n        pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(\n            silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );\n        NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];\n    }\n    silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );\n    silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );\n\n    /* Update states */\n    NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14;\n    NSQ->lagPrev        = pitchL[ psEncC->nb_subfr - 1 ];\n\n    /* Save quantized speech signal */\n    /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */\n    silk_memmove( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );\n    silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );\n    RESTORE_STACK;\n}\n\n/******************************************/\n/* Noise shape quantizer for one subframe */\n/******************************************/\nstatic OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1(\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                           */\n    NSQ_del_dec_struct  psDelDec[],             /* I/O  Delayed decision states             */\n    opus_int            signalType,             /* I    Signal type                         */\n    const opus_int32    x_Q10[],                /* I                                        */\n    opus_int8           pulses[],               /* O                                        */\n    opus_int16          xq[],                   /* O                                        */\n    opus_int32          sLTP_Q15[],             /* I/O  LTP filter state                    */\n    opus_int32          delayedGain_Q10[],      /* I/O  Gain delay buffer                   */\n    const opus_int16    a_Q12[],                /* I    Short term prediction coefs         */\n    const opus_int16    b_Q14[],                /* I    Long term prediction coefs          */\n    const opus_int16    AR_shp_Q13[],           /* I    Noise shaping coefs                 */\n    opus_int            lag,                    /* I    Pitch lag                           */\n    opus_int32          HarmShapeFIRPacked_Q14, /* I                                        */\n    opus_int            Tilt_Q14,               /* I    Spectral tilt                       */\n    opus_int32          LF_shp_Q14,             /* I                                        */\n    opus_int32          Gain_Q16,               /* I                                        */\n    opus_int            Lambda_Q10,             /* I                                        */\n    opus_int            offset_Q10,             /* I                                        */\n    opus_int            length,                 /* I    Input length                        */\n    opus_int            subfr,                  /* I    Subframe number                     */\n    opus_int            shapingLPCOrder,        /* I    Shaping LPC filter order            */\n    opus_int            predictLPCOrder,        /* I    Prediction filter order             */\n    opus_int            warping_Q16,            /* I                                        */\n    opus_int            nStatesDelayedDecision, /* I    Number of states in decision tree   */\n    opus_int            *smpl_buf_idx,          /* I    Index to newest samples in buffers  */\n    opus_int            decisionDelay           /* I                                        */\n)\n{\n    opus_int     i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;\n    opus_int32   Winner_rand_state;\n    opus_int32   LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;\n    opus_int32   n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;\n    opus_int32   q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;\n    opus_int32   tmp1, tmp2, sLF_AR_shp_Q14;\n    opus_int32   *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;\n    VARDECL( NSQ_sample_pair, psSampleState );\n    NSQ_del_dec_struct *psDD;\n    NSQ_sample_struct  *psSS;\n\n    __m128i a_Q12_0123, a_Q12_4567, a_Q12_89AB, a_Q12_CDEF;\n    __m128i b_Q12_0123, b_sr_Q12_0123;\n    SAVE_STACK;\n\n    silk_assert( nStatesDelayedDecision > 0 );\n    ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );\n\n    shp_lag_ptr  = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];\n    pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];\n    Gain_Q10     = silk_RSHIFT( Gain_Q16, 6 );\n\n    a_Q12_0123 = OP_CVTEPI16_EPI32_M64( a_Q12 );\n    a_Q12_4567 = OP_CVTEPI16_EPI32_M64( a_Q12 + 4 );\n\n    if( opus_likely( predictLPCOrder == 16 ) ) {\n        a_Q12_89AB = OP_CVTEPI16_EPI32_M64( a_Q12 + 8 );\n        a_Q12_CDEF = OP_CVTEPI16_EPI32_M64( a_Q12 + 12 );\n    }\n\n    if( signalType == TYPE_VOICED ){\n        b_Q12_0123 = OP_CVTEPI16_EPI32_M64( b_Q14 );\n        b_sr_Q12_0123 = _mm_shuffle_epi32( b_Q12_0123, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */\n    }\n    for( i = 0; i < length; i++ ) {\n        /* Perform common calculations used in all states */\n\n        /* Long-term prediction */\n        if( signalType == TYPE_VOICED ) {\n            /* Unrolled loop */\n            /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n            LTP_pred_Q14 = 2;\n            {\n                __m128i tmpa, tmpb, pred_lag_ptr_tmp;\n                pred_lag_ptr_tmp    = _mm_loadu_si128( (__m128i *)(&pred_lag_ptr[ -3 ] ) );\n                pred_lag_ptr_tmp    = _mm_shuffle_epi32( pred_lag_ptr_tmp, 0x1B );\n                tmpa                = _mm_mul_epi32( pred_lag_ptr_tmp, b_Q12_0123 );\n                tmpa                = _mm_srli_si128( tmpa, 2 );\n\n                pred_lag_ptr_tmp = _mm_shuffle_epi32( pred_lag_ptr_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) );/* equal shift right 4 bytes */\n                pred_lag_ptr_tmp    = _mm_mul_epi32( pred_lag_ptr_tmp, b_sr_Q12_0123 );\n                pred_lag_ptr_tmp    = _mm_srli_si128( pred_lag_ptr_tmp, 2 );\n                pred_lag_ptr_tmp    = _mm_add_epi32( pred_lag_ptr_tmp, tmpa );\n\n                tmpb = _mm_shuffle_epi32( pred_lag_ptr_tmp, _MM_SHUFFLE( 0, 0, 3, 2 ) );/* equal shift right 8 bytes */\n                pred_lag_ptr_tmp    = _mm_add_epi32( pred_lag_ptr_tmp, tmpb );\n                LTP_pred_Q14        += _mm_cvtsi128_si32( pred_lag_ptr_tmp );\n\n                LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );\n                LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 );                          /* Q13 -> Q14 */\n                pred_lag_ptr++;\n            }\n        } else {\n            LTP_pred_Q14 = 0;\n        }\n\n        /* Long-term shaping */\n        if( lag > 0 ) {\n            /* Symmetric, packed FIR coefficients */\n            n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );\n            n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ],                      HarmShapeFIRPacked_Q14 );\n            n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 );            /* Q12 -> Q14 */\n            shp_lag_ptr++;\n        } else {\n            n_LTP_Q14 = 0;\n        }\n        {\n            __m128i tmpa, tmpb, psLPC_Q14_tmp, a_Q12_tmp;\n\n            for( k = 0; k < nStatesDelayedDecision; k++ ) {\n                /* Delayed decision state */\n                psDD = &psDelDec[ k ];\n\n                /* Sample state */\n                psSS = psSampleState[ k ];\n\n                /* Generate dither */\n                psDD->Seed = silk_RAND( psDD->Seed );\n\n                /* Pointer used in short term prediction and shaping */\n                psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];\n                /* Short-term prediction */\n                silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );\n                /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n                LPC_pred_Q14 = silk_RSHIFT( predictLPCOrder, 1 );\n\n                tmpb = _mm_setzero_si128();\n\n                /* step 1 */\n                psLPC_Q14_tmp   = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -3 ] ) ); /* -3, -2 , -1, 0 */\n                psLPC_Q14_tmp   = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B );      /* 0, -1, -2, -3 */\n                tmpa            = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_0123 );    /* 0, -1, -2, -3 * 0123 -> 0*0, 2*-2 */\n\n                tmpa            = _mm_srli_epi64( tmpa, 16 );\n                tmpb            = _mm_add_epi32( tmpb, tmpa );\n\n                psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */\n                a_Q12_tmp = _mm_shuffle_epi32( a_Q12_0123, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */\n                psLPC_Q14_tmp   = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp ); /* 1*-1, 3*-3 */\n                psLPC_Q14_tmp   = _mm_srli_epi64( psLPC_Q14_tmp, 16 );\n                tmpb            = _mm_add_epi32( tmpb, psLPC_Q14_tmp );\n\n                /* step 2 */\n                psLPC_Q14_tmp   = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -7 ] ) );\n                psLPC_Q14_tmp   = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B );\n                tmpa            = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_4567 );\n                tmpa            = _mm_srli_epi64( tmpa, 16 );\n                tmpb            = _mm_add_epi32( tmpb, tmpa );\n\n                psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */\n                a_Q12_tmp = _mm_shuffle_epi32( a_Q12_4567, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */\n                psLPC_Q14_tmp   = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp );\n                psLPC_Q14_tmp   = _mm_srli_epi64( psLPC_Q14_tmp, 16 );\n                tmpb            = _mm_add_epi32( tmpb, psLPC_Q14_tmp );\n\n                if ( opus_likely( predictLPCOrder == 16 ) )\n                {\n                    /* step 3 */\n                    psLPC_Q14_tmp   = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -11 ] ) );\n                    psLPC_Q14_tmp   = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B );\n                    tmpa            = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_89AB );\n                    tmpa            = _mm_srli_epi64( tmpa, 16 );\n                    tmpb            = _mm_add_epi32( tmpb, tmpa );\n\n                    psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */\n                    a_Q12_tmp = _mm_shuffle_epi32( a_Q12_89AB, _MM_SHUFFLE(0, 3, 2, 1 ) );/* equal shift right 4 bytes */\n                    psLPC_Q14_tmp   = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp );\n                    psLPC_Q14_tmp   = _mm_srli_epi64( psLPC_Q14_tmp, 16 );\n                    tmpb            = _mm_add_epi32( tmpb, psLPC_Q14_tmp );\n\n                    /* setp 4 */\n                    psLPC_Q14_tmp   = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -15 ] ) );\n                    psLPC_Q14_tmp   = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B );\n                    tmpa            = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_CDEF );\n                    tmpa            = _mm_srli_epi64( tmpa, 16 );\n                    tmpb            = _mm_add_epi32( tmpb, tmpa );\n\n                    psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */\n                    a_Q12_tmp = _mm_shuffle_epi32( a_Q12_CDEF, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */\n                    psLPC_Q14_tmp   = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp );\n                    psLPC_Q14_tmp   = _mm_srli_epi64( psLPC_Q14_tmp, 16 );\n                    tmpb            = _mm_add_epi32( tmpb, psLPC_Q14_tmp );\n\n                    /* add at last */\n                    /* equal shift right 8 bytes*/\n                    tmpa            = _mm_shuffle_epi32( tmpb, _MM_SHUFFLE( 0, 0, 3, 2 ) );\n                    tmpb            = _mm_add_epi32( tmpb, tmpa );\n                    LPC_pred_Q14    += _mm_cvtsi128_si32( tmpb );\n                }\n                else\n                {\n                    /* add at last */\n                    tmpa            = _mm_shuffle_epi32( tmpb, _MM_SHUFFLE( 0, 0, 3, 2 ) ); /* equal shift right 8 bytes*/\n                    tmpb            = _mm_add_epi32( tmpb, tmpa );\n                    LPC_pred_Q14    += _mm_cvtsi128_si32( tmpb );\n\n                    LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -8 ], a_Q12[ 8 ] );\n                    LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -9 ], a_Q12[ 9 ] );\n                }\n\n                LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */\n\n                /* Noise shape feedback */\n                silk_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */\n                /* Output of lowpass section */\n                tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );\n                /* Output of allpass section */\n                tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );\n                psDD->sAR2_Q14[ 0 ] = tmp2;\n                n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 );\n                n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] );\n                /* Loop over allpass sections */\n                for( j = 2; j < shapingLPCOrder; j += 2 ) {\n                    /* Output of allpass section */\n                    tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 );\n                    psDD->sAR2_Q14[ j - 1 ] = tmp1;\n                    n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] );\n                    /* Output of allpass section */\n                    tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 );\n                    psDD->sAR2_Q14[ j + 0 ] = tmp2;\n                    n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] );\n                }\n                psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;\n                n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );\n\n                n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 );                                      /* Q11 -> Q12 */\n                n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 );              /* Q12 */\n                n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 );                                      /* Q12 -> Q14 */\n\n                n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 );     /* Q12 */\n                n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 );            /* Q12 */\n                n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 );                                      /* Q12 -> Q14 */\n\n                /* Input minus prediction plus noise feedback                       */\n                /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP  */\n                tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 );                                    /* Q14 */\n                tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 );                               /* Q13 */\n                tmp1 = silk_SUB32( tmp2, tmp1 );                                            /* Q13 */\n                tmp1 = silk_RSHIFT_ROUND( tmp1, 4 );                                        /* Q10 */\n\n                r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 );                                     /* residual error Q10 */\n\n                /* Flip sign depending on dither */\n                if ( psDD->Seed < 0 ) {\n                    r_Q10 = -r_Q10;\n                }\n                r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );\n\n                /* Find two quantization level candidates and measure their rate-distortion */\n                q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );\n                q1_Q0 = silk_RSHIFT( q1_Q10, 10 );\n                if( q1_Q0 > 0 ) {\n                    q1_Q10  = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );\n                    q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );\n                    q2_Q10  = silk_ADD32( q1_Q10, 1024 );\n                    rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );\n                    rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );\n                } else if( q1_Q0 == 0 ) {\n                    q1_Q10  = offset_Q10;\n                    q2_Q10  = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );\n                    rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );\n                    rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );\n                } else if( q1_Q0 == -1 ) {\n                    q2_Q10  = offset_Q10;\n                    q1_Q10  = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );\n                    rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );\n                    rd2_Q10 = silk_SMULBB(  q2_Q10, Lambda_Q10 );\n                } else {            /* q1_Q0 < -1 */\n                    q1_Q10  = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );\n                    q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );\n                    q2_Q10  = silk_ADD32( q1_Q10, 1024 );\n                    rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );\n                    rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );\n                }\n                rr_Q10  = silk_SUB32( r_Q10, q1_Q10 );\n                rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );\n                rr_Q10  = silk_SUB32( r_Q10, q2_Q10 );\n                rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );\n\n                if( rd1_Q10 < rd2_Q10 ) {\n                    psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );\n                    psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );\n                    psSS[ 0 ].Q_Q10  = q1_Q10;\n                    psSS[ 1 ].Q_Q10  = q2_Q10;\n                } else {\n                    psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );\n                    psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );\n                    psSS[ 0 ].Q_Q10  = q2_Q10;\n                    psSS[ 1 ].Q_Q10  = q1_Q10;\n                }\n\n                /* Update states for best quantization */\n\n                /* Quantized excitation */\n                exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );\n                if ( psDD->Seed < 0 ) {\n                    exc_Q14 = -exc_Q14;\n                }\n\n                /* Add predictions */\n                LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );\n                xq_Q14      = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );\n\n                /* Update states */\n                sLF_AR_shp_Q14         = silk_SUB32( xq_Q14, n_AR_Q14 );\n                psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );\n                psSS[ 0 ].LF_AR_Q14    = sLF_AR_shp_Q14;\n                psSS[ 0 ].LPC_exc_Q14  = LPC_exc_Q14;\n                psSS[ 0 ].xq_Q14       = xq_Q14;\n\n                /* Update states for second best quantization */\n\n                /* Quantized excitation */\n                exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );\n                if ( psDD->Seed < 0 ) {\n                    exc_Q14 = -exc_Q14;\n                }\n\n\n                /* Add predictions */\n                LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );\n                xq_Q14      = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );\n\n                /* Update states */\n                sLF_AR_shp_Q14         = silk_SUB32( xq_Q14, n_AR_Q14 );\n                psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );\n                psSS[ 1 ].LF_AR_Q14    = sLF_AR_shp_Q14;\n                psSS[ 1 ].LPC_exc_Q14  = LPC_exc_Q14;\n                psSS[ 1 ].xq_Q14       = xq_Q14;\n            }\n        }\n        *smpl_buf_idx  = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK;                   /* Index to newest samples              */\n        last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK;       /* Index to decisionDelay old samples   */\n\n        /* Find winner */\n        RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;\n        Winner_ind = 0;\n        for( k = 1; k < nStatesDelayedDecision; k++ ) {\n            if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {\n                RDmin_Q10  = psSampleState[ k ][ 0 ].RD_Q10;\n                Winner_ind = k;\n            }\n        }\n\n        /* Increase RD values of expired states */\n        Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];\n        for( k = 0; k < nStatesDelayedDecision; k++ ) {\n            if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {\n                psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );\n                psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );\n                silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );\n            }\n        }\n\n        /* Find worst in first set and best in second set */\n        RDmax_Q10  = psSampleState[ 0 ][ 0 ].RD_Q10;\n        RDmin_Q10  = psSampleState[ 0 ][ 1 ].RD_Q10;\n        RDmax_ind = 0;\n        RDmin_ind = 0;\n        for( k = 1; k < nStatesDelayedDecision; k++ ) {\n            /* find worst in first set */\n            if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {\n                RDmax_Q10  = psSampleState[ k ][ 0 ].RD_Q10;\n                RDmax_ind = k;\n            }\n            /* find best in second set */\n            if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {\n                RDmin_Q10  = psSampleState[ k ][ 1 ].RD_Q10;\n                RDmin_ind = k;\n            }\n        }\n\n        /* Replace a state if best from second set outperforms worst in first set */\n        if( RDmin_Q10 < RDmax_Q10 ) {\n            silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,\n                         ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );\n            silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );\n        }\n\n        /* Write samples from winner to output and long-term filter states */\n        psDD = &psDelDec[ Winner_ind ];\n        if( subfr > 0 || i >= decisionDelay ) {\n            pulses[  i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );\n            xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(\n                silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );\n            NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];\n            sLTP_Q15[          NSQ->sLTP_buf_idx     - decisionDelay ] = psDD->Pred_Q15[  last_smple_idx ];\n        }\n        NSQ->sLTP_shp_buf_idx++;\n        NSQ->sLTP_buf_idx++;\n\n        /* Update states */\n        for( k = 0; k < nStatesDelayedDecision; k++ ) {\n            psDD                                     = &psDelDec[ k ];\n            psSS                                     = &psSampleState[ k ][ 0 ];\n            psDD->LF_AR_Q14                          = psSS->LF_AR_Q14;\n            psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;\n            psDD->Xq_Q14[    *smpl_buf_idx ]         = psSS->xq_Q14;\n            psDD->Q_Q10[     *smpl_buf_idx ]         = psSS->Q_Q10;\n            psDD->Pred_Q15[  *smpl_buf_idx ]         = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );\n            psDD->Shape_Q14[ *smpl_buf_idx ]         = psSS->sLTP_shp_Q14;\n            psDD->Seed                               = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );\n            psDD->RandState[ *smpl_buf_idx ]         = psDD->Seed;\n            psDD->RD_Q10                             = psSS->RD_Q10;\n        }\n        delayedGain_Q10[     *smpl_buf_idx ]         = Gain_Q10;\n    }\n    /* Update LPC states */\n    for( k = 0; k < nStatesDelayedDecision; k++ ) {\n        psDD = &psDelDec[ k ];\n        silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );\n    }\n    RESTORE_STACK;\n}\n\nstatic OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1(\n    const silk_encoder_state *psEncC,               /* I    Encoder State                       */\n    silk_nsq_state      *NSQ,                       /* I/O  NSQ state                           */\n    NSQ_del_dec_struct  psDelDec[],                 /* I/O  Delayed decision states             */\n    const opus_int32    x_Q3[],                     /* I    Input in Q3                         */\n    opus_int32          x_sc_Q10[],                 /* O    Input scaled with 1/Gain in Q10     */\n    const opus_int16    sLTP[],                     /* I    Re-whitened LTP state in Q0         */\n    opus_int32          sLTP_Q15[],                 /* O    LTP state matching scaled input     */\n    opus_int            subfr,                      /* I    Subframe number                     */\n    opus_int            nStatesDelayedDecision,     /* I    Number of del dec states            */\n    const opus_int      LTP_scale_Q14,              /* I    LTP state scaling                   */\n    const opus_int32    Gains_Q16[ MAX_NB_SUBFR ],  /* I                                        */\n    const opus_int      pitchL[ MAX_NB_SUBFR ],     /* I    Pitch lag                           */\n    const opus_int      signal_type,                /* I    Signal type                         */\n    const opus_int      decisionDelay               /* I    Decision delay                      */\n)\n{\n    opus_int            i, k, lag;\n    opus_int32          gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;\n    NSQ_del_dec_struct  *psDD;\n    __m128i xmm_inv_gain_Q23, xmm_x_Q3_x2x0, xmm_x_Q3_x3x1;\n\n    lag          = pitchL[ subfr ];\n    inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );\n\n    silk_assert( inv_gain_Q31 != 0 );\n\n    /* Calculate gain adjustment factor */\n    if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {\n        gain_adj_Q16 =  silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );\n    } else {\n        gain_adj_Q16 = (opus_int32)1 << 16;\n    }\n\n    /* Scale input */\n    inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );\n\n    /* prepare inv_gain_Q23 in packed 4 32-bits */\n    xmm_inv_gain_Q23 = _mm_set1_epi32(inv_gain_Q23);\n\n    for( i = 0; i < psEncC->subfr_length - 3; i += 4 ) {\n        xmm_x_Q3_x2x0 = _mm_loadu_si128( (__m128i *)(&(x_Q3[ i ] ) ) );\n        /* equal shift right 4 bytes*/\n        xmm_x_Q3_x3x1 = _mm_shuffle_epi32( xmm_x_Q3_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );\n\n        xmm_x_Q3_x2x0 = _mm_mul_epi32( xmm_x_Q3_x2x0, xmm_inv_gain_Q23 );\n        xmm_x_Q3_x3x1 = _mm_mul_epi32( xmm_x_Q3_x3x1, xmm_inv_gain_Q23 );\n\n        xmm_x_Q3_x2x0 = _mm_srli_epi64( xmm_x_Q3_x2x0, 16 );\n        xmm_x_Q3_x3x1 = _mm_slli_epi64( xmm_x_Q3_x3x1, 16 );\n\n        xmm_x_Q3_x2x0 = _mm_blend_epi16( xmm_x_Q3_x2x0, xmm_x_Q3_x3x1, 0xCC );\n\n        _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ])), xmm_x_Q3_x2x0 );\n    }\n\n    for( ; i < psEncC->subfr_length; i++ ) {\n        x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );\n    }\n\n    /* Save inverse gain */\n    NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];\n\n    /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */\n    if( NSQ->rewhite_flag ) {\n        if( subfr == 0 ) {\n            /* Do LTP downscaling */\n            inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );\n        }\n        for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {\n            silk_assert( i < MAX_FRAME_LENGTH );\n            sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );\n        }\n    }\n\n    /* Adjust for changing gain */\n    if( gain_adj_Q16 != (opus_int32)1 << 16 ) {\n        /* Scale long-term shaping state */\n        {\n            __m128i xmm_gain_adj_Q16, xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1;\n\n            /* prepare gain_adj_Q16 in packed 4 32-bits */\n            xmm_gain_adj_Q16 = _mm_set1_epi32( gain_adj_Q16 );\n\n            for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 3; i += 4 )\n            {\n                xmm_sLTP_shp_Q14_x2x0 = _mm_loadu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ) );\n                /* equal shift right 4 bytes*/\n                xmm_sLTP_shp_Q14_x3x1 = _mm_shuffle_epi32( xmm_sLTP_shp_Q14_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );\n\n                xmm_sLTP_shp_Q14_x2x0 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x2x0, xmm_gain_adj_Q16 );\n                xmm_sLTP_shp_Q14_x3x1 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x3x1, xmm_gain_adj_Q16 );\n\n                xmm_sLTP_shp_Q14_x2x0 = _mm_srli_epi64( xmm_sLTP_shp_Q14_x2x0, 16 );\n                xmm_sLTP_shp_Q14_x3x1 = _mm_slli_epi64( xmm_sLTP_shp_Q14_x3x1, 16 );\n\n                xmm_sLTP_shp_Q14_x2x0 = _mm_blend_epi16( xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1, 0xCC );\n\n                _mm_storeu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ), xmm_sLTP_shp_Q14_x2x0 );\n            }\n\n            for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {\n                NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );\n            }\n\n            /* Scale long-term prediction state */\n            if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {\n                for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {\n                    sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );\n                }\n            }\n\n            for( k = 0; k < nStatesDelayedDecision; k++ ) {\n                psDD = &psDelDec[ k ];\n\n                /* Scale scalar states */\n                psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 );\n\n                /* Scale short-term prediction and shaping states */\n                for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {\n                    psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] );\n                }\n                for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {\n                    psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] );\n                }\n                for( i = 0; i < DECISION_DELAY; i++ ) {\n                    psDD->Pred_Q15[  i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[  i ] );\n                    psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] );\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/x86/NSQ_sse.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <xmmintrin.h>\n#include <emmintrin.h>\n#include <smmintrin.h>\n#include \"main.h\"\n#include \"celt/x86/x86cpu.h\"\n#include \"stack_alloc.h\"\n\nstatic OPUS_INLINE void silk_nsq_scale_states_sse4_1(\n    const silk_encoder_state *psEncC,           /* I    Encoder State                   */\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */\n    const opus_int32    x_Q3[],                 /* I    input in Q3                     */\n    opus_int32          x_sc_Q10[],             /* O    input scaled with 1/Gain        */\n    const opus_int16    sLTP[],                 /* I    re-whitened LTP state in Q0     */\n    opus_int32          sLTP_Q15[],             /* O    LTP state matching scaled input */\n    opus_int            subfr,                  /* I    subframe number                 */\n    const opus_int      LTP_scale_Q14,          /* I                                    */\n    const opus_int32    Gains_Q16[ MAX_NB_SUBFR ], /* I                                 */\n    const opus_int      pitchL[ MAX_NB_SUBFR ], /* I    Pitch lag                       */\n    const opus_int      signal_type             /* I    Signal type                     */\n);\n\nstatic OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1(\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */\n    opus_int            signalType,             /* I    Signal type                     */\n    const opus_int32    x_sc_Q10[],             /* I                                    */\n    opus_int8           pulses[],               /* O                                    */\n    opus_int16          xq[],                   /* O                                    */\n    opus_int32          sLTP_Q15[],             /* I/O  LTP state                       */\n    const opus_int16    a_Q12[],                /* I    Short term prediction coefs     */\n    const opus_int16    b_Q14[],                /* I    Long term prediction coefs      */\n    const opus_int16    AR_shp_Q13[],           /* I    Noise shaping AR coefs          */\n    opus_int            lag,                    /* I    Pitch lag                       */\n    opus_int32          HarmShapeFIRPacked_Q14, /* I                                    */\n    opus_int            Tilt_Q14,               /* I    Spectral tilt                   */\n    opus_int32          LF_shp_Q14,             /* I                                    */\n    opus_int32          Gain_Q16,               /* I                                    */\n    opus_int            offset_Q10,             /* I                                    */\n    opus_int            length,                 /* I    Input length                    */\n    opus_int32          table[][4]              /* I                                    */\n);\n\nvoid silk_NSQ_sse4_1(\n    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */\n    silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */\n    SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */\n    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */\n    opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */\n    const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */\n    const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */\n    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */\n    const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */\n    const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */\n    const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */\n    const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */\n    const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */\n    const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */\n    const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */\n)\n{\n    opus_int            k, lag, start_idx, LSF_interpolation_flag;\n    const opus_int16    *A_Q12, *B_Q14, *AR_shp_Q13;\n    opus_int16          *pxq;\n    VARDECL( opus_int32, sLTP_Q15 );\n    VARDECL( opus_int16, sLTP );\n    opus_int32          HarmShapeFIRPacked_Q14;\n    opus_int            offset_Q10;\n    VARDECL( opus_int32, x_sc_Q10 );\n\n    opus_int32   table[ 64 ][ 4 ];\n    opus_int32   tmp1;\n    opus_int32   q1_Q10, q2_Q10, rd1_Q20, rd2_Q20;\n\n    SAVE_STACK;\n\n    NSQ->rand_seed = psIndices->Seed;\n\n    /* Set unvoiced lag to the previous one, overwrite later for voiced */\n    lag = NSQ->lagPrev;\n\n    silk_assert( NSQ->prev_gain_Q16 != 0 );\n\n    offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];\n\n    /* 0 */\n    q1_Q10  = offset_Q10;\n    q2_Q10  = offset_Q10 + ( 1024 - QUANT_LEVEL_ADJUST_Q10 );\n    rd1_Q20 = q1_Q10 * Lambda_Q10;\n    rd2_Q20 = q2_Q10 * Lambda_Q10;\n\n    table[ 32 ][ 0 ] = q1_Q10;\n    table[ 32 ][ 1 ] = q2_Q10;\n    table[ 32 ][ 2 ] = 2 * (q1_Q10 - q2_Q10);\n    table[ 32 ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10);\n\n    /* -1 */\n    q1_Q10  = offset_Q10 - ( 1024 - QUANT_LEVEL_ADJUST_Q10 );\n    q2_Q10  = offset_Q10;\n    rd1_Q20 = - q1_Q10 * Lambda_Q10;\n    rd2_Q20 = q2_Q10 * Lambda_Q10;\n\n    table[ 31 ][ 0 ] = q1_Q10;\n    table[ 31 ][ 1 ] = q2_Q10;\n    table[ 31 ][ 2 ] = 2 * (q1_Q10 - q2_Q10);\n    table[ 31 ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10);\n\n    /* > 0 */\n    for (k = 1; k <= 31; k++)\n    {\n        tmp1 = offset_Q10 + silk_LSHIFT( k, 10 );\n\n        q1_Q10  = tmp1 - QUANT_LEVEL_ADJUST_Q10;\n        q2_Q10  = tmp1 - QUANT_LEVEL_ADJUST_Q10 + 1024;\n        rd1_Q20 = q1_Q10 * Lambda_Q10;\n        rd2_Q20 = q2_Q10 * Lambda_Q10;\n\n        table[ 32 + k ][ 0 ] = q1_Q10;\n        table[ 32 + k ][ 1 ] = q2_Q10;\n        table[ 32 + k ][ 2 ] = 2 * (q1_Q10 - q2_Q10);\n        table[ 32 + k ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10);\n    }\n\n    /* < -1 */\n    for (k = -32; k <= -2; k++)\n    {\n        tmp1 = offset_Q10 + silk_LSHIFT( k, 10 );\n\n        q1_Q10  = tmp1 + QUANT_LEVEL_ADJUST_Q10;\n        q2_Q10  = tmp1 + QUANT_LEVEL_ADJUST_Q10 + 1024;\n        rd1_Q20 = - q1_Q10 * Lambda_Q10;\n        rd2_Q20 = - q2_Q10 * Lambda_Q10;\n\n        table[ 32 + k ][ 0 ] = q1_Q10;\n        table[ 32 + k ][ 1 ] = q2_Q10;\n        table[ 32 + k ][ 2 ] = 2 * (q1_Q10 - q2_Q10);\n        table[ 32 + k ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10);\n    }\n\n    if( psIndices->NLSFInterpCoef_Q2 == 4 ) {\n        LSF_interpolation_flag = 0;\n    } else {\n        LSF_interpolation_flag = 1;\n    }\n\n    ALLOC( sLTP_Q15,\n           psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );\n    ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );\n    ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );\n    /* Set up pointers to start of sub frame */\n    NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;\n    NSQ->sLTP_buf_idx     = psEncC->ltp_mem_length;\n    pxq                   = &NSQ->xq[ psEncC->ltp_mem_length ];\n    for( k = 0; k < psEncC->nb_subfr; k++ ) {\n        A_Q12      = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];\n        B_Q14      = &LTPCoef_Q14[ k * LTP_ORDER ];\n        AR_shp_Q13 = &AR2_Q13[     k * MAX_SHAPE_LPC_ORDER ];\n\n        /* Noise shape parameters */\n        silk_assert( HarmShapeGain_Q14[ k ] >= 0 );\n        HarmShapeFIRPacked_Q14  =                          silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );\n        HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );\n\n        NSQ->rewhite_flag = 0;\n        if( psIndices->signalType == TYPE_VOICED ) {\n            /* Voiced */\n            lag = pitchL[ k ];\n\n            /* Re-whitening */\n            if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {\n                /* Rewhiten with new A coefs */\n                start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;\n                silk_assert( start_idx > 0 );\n\n                silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],\n                    A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );\n\n                NSQ->rewhite_flag = 1;\n                NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;\n            }\n        }\n\n        silk_nsq_scale_states_sse4_1( psEncC, NSQ, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );\n\n        if ( opus_likely( ( 10 == psEncC->shapingLPCOrder ) && ( 16 == psEncC->predictLPCOrder) ) )\n        {\n            silk_noise_shape_quantizer_10_16_sse4_1( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,\n                AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ],\n                offset_Q10, psEncC->subfr_length, &(table[32]) );\n        }\n        else\n        {\n            silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,\n                AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,\n                offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder );\n        }\n\n        x_Q3   += psEncC->subfr_length;\n        pulses += psEncC->subfr_length;\n        pxq    += psEncC->subfr_length;\n    }\n\n    /* Update lagPrev for next frame */\n    NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];\n\n    /* Save quantized speech and noise shaping signals */\n    /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int16 ) ) */\n    silk_memmove( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );\n    silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );\n    RESTORE_STACK;\n}\n\n/***********************************/\n/* silk_noise_shape_quantizer_10_16  */\n/***********************************/\nstatic OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1(\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */\n    opus_int            signalType,             /* I    Signal type                     */\n    const opus_int32    x_sc_Q10[],             /* I                                    */\n    opus_int8           pulses[],               /* O                                    */\n    opus_int16          xq[],                   /* O                                    */\n    opus_int32          sLTP_Q15[],             /* I/O  LTP state                       */\n    const opus_int16    a_Q12[],                /* I    Short term prediction coefs     */\n    const opus_int16    b_Q14[],                /* I    Long term prediction coefs      */\n    const opus_int16    AR_shp_Q13[],           /* I    Noise shaping AR coefs          */\n    opus_int            lag,                    /* I    Pitch lag                       */\n    opus_int32          HarmShapeFIRPacked_Q14, /* I                                    */\n    opus_int            Tilt_Q14,               /* I    Spectral tilt                   */\n    opus_int32          LF_shp_Q14,             /* I                                    */\n    opus_int32          Gain_Q16,               /* I                                    */\n    opus_int            offset_Q10,             /* I                                    */\n    opus_int            length,                 /* I    Input length                    */\n    opus_int32          table[][4]              /* I                                    */\n)\n{\n    opus_int     i;\n    opus_int32   LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13;\n    opus_int32   n_LF_Q12, r_Q10, q1_Q0, q1_Q10, q2_Q10;\n    opus_int32   exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;\n    opus_int32   tmp1, tmp2, sLF_AR_shp_Q14;\n    opus_int32   *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;\n\n    __m128i xmm_tempa, xmm_tempb;\n\n    __m128i xmm_one;\n\n    __m128i psLPC_Q14_hi_01234567, psLPC_Q14_hi_89ABCDEF;\n    __m128i psLPC_Q14_lo_01234567, psLPC_Q14_lo_89ABCDEF;\n    __m128i a_Q12_01234567,        a_Q12_89ABCDEF;\n\n    __m128i sAR2_Q14_hi_76543210, sAR2_Q14_lo_76543210;\n    __m128i AR_shp_Q13_76543210;\n\n    shp_lag_ptr  = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];\n    pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];\n    Gain_Q10     = silk_RSHIFT( Gain_Q16, 6 );\n\n    /* Set up short term AR state */\n    psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];\n\n    sLF_AR_shp_Q14 = NSQ->sLF_AR_shp_Q14;\n    xq_Q14         = psLPC_Q14[ 0 ];\n    LTP_pred_Q13   = 0;\n\n    /* load a_Q12 */\n    xmm_one = _mm_set_epi8( 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14 );\n\n    /* load a_Q12[0] - a_Q12[7] */\n    a_Q12_01234567 = _mm_loadu_si128( (__m128i *)(&a_Q12[ 0 ] ) );\n    /* load a_Q12[ 8 ] - a_Q12[ 15 ] */\n    a_Q12_89ABCDEF = _mm_loadu_si128( (__m128i *)(&a_Q12[ 8 ] ) );\n\n    a_Q12_01234567 = _mm_shuffle_epi8( a_Q12_01234567, xmm_one );\n    a_Q12_89ABCDEF = _mm_shuffle_epi8( a_Q12_89ABCDEF, xmm_one );\n\n    /* load AR_shp_Q13 */\n    AR_shp_Q13_76543210 = _mm_loadu_si128( (__m128i *)(&AR_shp_Q13[0] ) );\n\n    /* load psLPC_Q14 */\n    xmm_one = _mm_set_epi8(15, 14, 11, 10, 7, 6, 3, 2, 13, 12, 9, 8, 5, 4, 1, 0 );\n\n    xmm_tempa = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[-16]) );\n    xmm_tempb = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[-12]) );\n\n    xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one );\n    xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one );\n\n    psLPC_Q14_hi_89ABCDEF = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb );\n    psLPC_Q14_lo_89ABCDEF = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb );\n\n    xmm_tempa = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -8 ]) );\n    xmm_tempb = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -4 ]) );\n\n    xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one );\n    xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one );\n\n    psLPC_Q14_hi_01234567 = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb );\n    psLPC_Q14_lo_01234567 = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb );\n\n    /* load sAR2_Q14 */\n    xmm_tempa = _mm_loadu_si128( (__m128i *)(&(NSQ->sAR2_Q14[ 0 ]) ) );\n    xmm_tempb = _mm_loadu_si128( (__m128i *)(&(NSQ->sAR2_Q14[ 4 ]) ) );\n\n    xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one );\n    xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one );\n\n    sAR2_Q14_hi_76543210 = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb );\n    sAR2_Q14_lo_76543210 = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb );\n\n    /* prepare 1 in 8 * 16bit */\n    xmm_one = _mm_set1_epi16(1);\n\n    for( i = 0; i < length; i++ )\n    {\n        /* Short-term prediction */\n        __m128i xmm_hi_07, xmm_hi_8F, xmm_lo_07, xmm_lo_8F;\n\n        /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n        LPC_pred_Q10 = 8; /* silk_RSHIFT( predictLPCOrder, 1 ); */\n\n        /* shift psLPC_Q14 */\n        psLPC_Q14_hi_89ABCDEF = _mm_alignr_epi8( psLPC_Q14_hi_01234567, psLPC_Q14_hi_89ABCDEF, 2 );\n        psLPC_Q14_lo_89ABCDEF = _mm_alignr_epi8( psLPC_Q14_lo_01234567, psLPC_Q14_lo_89ABCDEF, 2 );\n\n        psLPC_Q14_hi_01234567 = _mm_srli_si128( psLPC_Q14_hi_01234567, 2 );\n        psLPC_Q14_lo_01234567 = _mm_srli_si128( psLPC_Q14_lo_01234567, 2 );\n\n        psLPC_Q14_hi_01234567 = _mm_insert_epi16( psLPC_Q14_hi_01234567, (xq_Q14 >> 16), 7 );\n        psLPC_Q14_lo_01234567 = _mm_insert_epi16( psLPC_Q14_lo_01234567, (xq_Q14),       7 );\n\n        /* high part, use pmaddwd, results in 4 32-bit */\n        xmm_hi_07 = _mm_madd_epi16( psLPC_Q14_hi_01234567, a_Q12_01234567 );\n        xmm_hi_8F = _mm_madd_epi16( psLPC_Q14_hi_89ABCDEF, a_Q12_89ABCDEF );\n\n        /* low part, use pmulhw, results in 8 16-bit, note we need simulate unsigned * signed, _mm_srai_epi16(psLPC_Q14_lo_01234567, 15) */\n        xmm_tempa = _mm_cmpgt_epi16( _mm_setzero_si128(), psLPC_Q14_lo_01234567 );\n        xmm_tempb = _mm_cmpgt_epi16( _mm_setzero_si128(), psLPC_Q14_lo_89ABCDEF );\n\n        xmm_tempa = _mm_and_si128( xmm_tempa, a_Q12_01234567 );\n        xmm_tempb = _mm_and_si128( xmm_tempb, a_Q12_89ABCDEF );\n\n        xmm_lo_07 = _mm_mulhi_epi16( psLPC_Q14_lo_01234567, a_Q12_01234567 );\n        xmm_lo_8F = _mm_mulhi_epi16( psLPC_Q14_lo_89ABCDEF, a_Q12_89ABCDEF );\n\n        xmm_lo_07 = _mm_add_epi16( xmm_lo_07, xmm_tempa );\n        xmm_lo_8F = _mm_add_epi16( xmm_lo_8F, xmm_tempb );\n\n        xmm_lo_07 = _mm_madd_epi16( xmm_lo_07, xmm_one );\n        xmm_lo_8F = _mm_madd_epi16( xmm_lo_8F, xmm_one );\n\n        /* accumulate */\n        xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_hi_8F );\n        xmm_lo_07 = _mm_add_epi32( xmm_lo_07, xmm_lo_8F );\n\n        xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_lo_07 );\n\n        xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_unpackhi_epi64(xmm_hi_07, xmm_hi_07 ) );\n        xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_shufflelo_epi16(xmm_hi_07, 0x0E ) );\n\n        LPC_pred_Q10 += _mm_cvtsi128_si32( xmm_hi_07 );\n\n        /* Long-term prediction */\n        if ( opus_likely( signalType == TYPE_VOICED ) ) {\n            /* Unrolled loop */\n            /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */\n            LTP_pred_Q13 = 2;\n            {\n                __m128i b_Q14_3210, b_Q14_0123, pred_lag_ptr_0123;\n\n                b_Q14_3210 = OP_CVTEPI16_EPI32_M64( b_Q14 );\n                b_Q14_0123 = _mm_shuffle_epi32( b_Q14_3210, 0x1B );\n\n                /* loaded: [0] [-1] [-2] [-3] */\n                pred_lag_ptr_0123 = _mm_loadu_si128( (__m128i *)(&pred_lag_ptr[ -3 ] ) );\n                /* shuffle to [-3] [-2] [-1] [0] and to new xmm */\n                xmm_tempa = _mm_shuffle_epi32( pred_lag_ptr_0123, 0x1B );\n                /*64-bit multiply, a[2] * b[-2], a[0] * b[0] */\n                xmm_tempa = _mm_mul_epi32( xmm_tempa, b_Q14_3210 );\n                /* right shift 2 bytes (16 bits), zero extended */\n                xmm_tempa = _mm_srli_si128( xmm_tempa, 2 );\n\n                /* a[1] * b[-1], a[3] * b[-3] */\n                pred_lag_ptr_0123 = _mm_mul_epi32( pred_lag_ptr_0123, b_Q14_0123 );\n                pred_lag_ptr_0123 = _mm_srli_si128( pred_lag_ptr_0123, 2 );\n\n                pred_lag_ptr_0123 = _mm_add_epi32( pred_lag_ptr_0123, xmm_tempa );\n                /* equal shift right 8 bytes*/\n                xmm_tempa = _mm_shuffle_epi32( pred_lag_ptr_0123, _MM_SHUFFLE( 0, 0, 3, 2 ) );\n                xmm_tempa = _mm_add_epi32( xmm_tempa, pred_lag_ptr_0123 );\n\n                LTP_pred_Q13 += _mm_cvtsi128_si32( xmm_tempa );\n\n                LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );\n                pred_lag_ptr++;\n            }\n        }\n\n        /* Noise shape feedback */\n        NSQ->sAR2_Q14[ 9 ] = NSQ->sAR2_Q14[ 8 ];\n        NSQ->sAR2_Q14[ 8 ] = _mm_cvtsi128_si32( _mm_srli_si128(_mm_unpackhi_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 ), 12 ) );\n\n        sAR2_Q14_hi_76543210 = _mm_slli_si128( sAR2_Q14_hi_76543210, 2 );\n        sAR2_Q14_lo_76543210 = _mm_slli_si128( sAR2_Q14_lo_76543210, 2 );\n\n        sAR2_Q14_hi_76543210 = _mm_insert_epi16( sAR2_Q14_hi_76543210, (xq_Q14 >> 16), 0 );\n        sAR2_Q14_lo_76543210 = _mm_insert_epi16( sAR2_Q14_lo_76543210, (xq_Q14),       0 );\n\n        /* high part, use pmaddwd, results in 4 32-bit */\n        xmm_hi_07 = _mm_madd_epi16( sAR2_Q14_hi_76543210, AR_shp_Q13_76543210 );\n\n        /* low part, use pmulhw, results in 8 16-bit, note we need simulate unsigned * signed,_mm_srai_epi16(sAR2_Q14_lo_76543210, 15) */\n        xmm_tempa = _mm_cmpgt_epi16( _mm_setzero_si128(), sAR2_Q14_lo_76543210 );\n        xmm_tempa = _mm_and_si128( xmm_tempa, AR_shp_Q13_76543210 );\n\n        xmm_lo_07 = _mm_mulhi_epi16( sAR2_Q14_lo_76543210, AR_shp_Q13_76543210 );\n        xmm_lo_07 = _mm_add_epi16( xmm_lo_07, xmm_tempa );\n\n        xmm_lo_07 = _mm_madd_epi16( xmm_lo_07, xmm_one );\n\n        /* accumulate */\n        xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_lo_07 );\n\n        xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_unpackhi_epi64(xmm_hi_07, xmm_hi_07 ) );\n        xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_shufflelo_epi16(xmm_hi_07, 0x0E ) );\n\n        n_AR_Q12 = 5 + _mm_cvtsi128_si32( xmm_hi_07 );\n\n        n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sAR2_Q14[ 8 ], AR_shp_Q13[ 8 ] );\n        n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sAR2_Q14[ 9 ], AR_shp_Q13[ 9 ] );\n\n        n_AR_Q12 = silk_LSHIFT32( n_AR_Q12, 1 );                                /* Q11 -> Q12 */\n        n_AR_Q12 = silk_SMLAWB( n_AR_Q12, sLF_AR_shp_Q14, Tilt_Q14 );\n\n        n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 );\n        n_LF_Q12 = silk_SMLAWT( n_LF_Q12, sLF_AR_shp_Q14, LF_shp_Q14 );\n\n        silk_assert( lag > 0 || signalType != TYPE_VOICED );\n\n        /* Combine prediction and noise shaping signals */\n        tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 );        /* Q12 */\n        tmp1 = silk_SUB32( tmp1, n_LF_Q12 );                                    /* Q12 */\n        if( lag > 0 ) {\n            /* Symmetric, packed FIR coefficients */\n            n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );\n            n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ],                      HarmShapeFIRPacked_Q14 );\n            n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 );\n            shp_lag_ptr++;\n\n            tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 );                       /* Q13 */\n            tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 );                          /* Q13 */\n            tmp1 = silk_RSHIFT_ROUND( tmp1, 3 );                                /* Q10 */\n        } else {\n            tmp1 = silk_RSHIFT_ROUND( tmp1, 2 );                                /* Q10 */\n        }\n\n        r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 );                              /* residual error Q10 */\n\n        /* Generate dither */\n        NSQ->rand_seed = silk_RAND( NSQ->rand_seed );\n\n        /* Flip sign depending on dither */\n        tmp2 = -r_Q10;\n        if ( NSQ->rand_seed < 0 ) r_Q10 = tmp2;\n\n        r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );\n\n        /* Find two quantization level candidates and measure their rate-distortion */\n        q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );\n        q1_Q0 = silk_RSHIFT( q1_Q10, 10 );\n\n        q1_Q10 = table[q1_Q0][0];\n        q2_Q10 = table[q1_Q0][1];\n\n        if (r_Q10 * table[q1_Q0][2] - table[q1_Q0][3] < 0)\n        {\n            q1_Q10 = q2_Q10;\n        }\n\n        pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 );\n\n        /* Excitation */\n        exc_Q14 = silk_LSHIFT( q1_Q10, 4 );\n\n        tmp2 = -exc_Q14;\n        if ( NSQ->rand_seed < 0 ) exc_Q14 = tmp2;\n\n        /* Add predictions */\n        LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 );\n        xq_Q14      = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 );\n\n        /* Update states */\n        psLPC_Q14++;\n        *psLPC_Q14 = xq_Q14;\n        sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, n_AR_Q12, 2 );\n\n        NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 );\n        sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 );\n        NSQ->sLTP_shp_buf_idx++;\n        NSQ->sLTP_buf_idx++;\n\n        /* Make dither dependent on quantized signal */\n        NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] );\n    }\n\n    NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14;\n\n    /* Scale XQ back to normal level before saving */\n    psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH ];\n\n    /* write back sAR2_Q14 */\n    xmm_tempa = _mm_unpackhi_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 );\n    xmm_tempb = _mm_unpacklo_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 );\n    _mm_storeu_si128( (__m128i *)(&NSQ->sAR2_Q14[ 4 ]), xmm_tempa );\n    _mm_storeu_si128( (__m128i *)(&NSQ->sAR2_Q14[ 0 ]), xmm_tempb );\n\n    /* xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psLPC_Q14[ i ], Gain_Q10 ), 8 ) ); */\n    {\n        __m128i xmm_Gain_Q10;\n        __m128i xmm_xq_Q14_3210, xmm_xq_Q14_x3x1, xmm_xq_Q14_7654, xmm_xq_Q14_x7x5;\n\n        /* prepare (1 << 7) in packed 4 32-bits */\n        xmm_tempa = _mm_set1_epi32( (1 << 7) );\n\n        /* prepare Gain_Q10 in packed 4 32-bits */\n        xmm_Gain_Q10 = _mm_set1_epi32( Gain_Q10 );\n\n        /* process xq */\n        for (i = 0; i < length - 7; i += 8)\n        {\n            xmm_xq_Q14_3210 = _mm_loadu_si128( (__m128i *)(&(psLPC_Q14[ i + 0 ] ) ) );\n            xmm_xq_Q14_7654 = _mm_loadu_si128( (__m128i *)(&(psLPC_Q14[ i + 4 ] ) ) );\n\n            /* equal shift right 4 bytes*/\n            xmm_xq_Q14_x3x1 = _mm_shuffle_epi32( xmm_xq_Q14_3210, _MM_SHUFFLE( 0, 3, 2, 1 ) );\n            /* equal shift right 4 bytes*/\n            xmm_xq_Q14_x7x5 = _mm_shuffle_epi32( xmm_xq_Q14_7654, _MM_SHUFFLE( 0, 3, 2, 1 ) );\n\n            xmm_xq_Q14_3210 = _mm_mul_epi32( xmm_xq_Q14_3210, xmm_Gain_Q10 );\n            xmm_xq_Q14_x3x1 = _mm_mul_epi32( xmm_xq_Q14_x3x1, xmm_Gain_Q10 );\n            xmm_xq_Q14_7654 = _mm_mul_epi32( xmm_xq_Q14_7654, xmm_Gain_Q10 );\n            xmm_xq_Q14_x7x5 = _mm_mul_epi32( xmm_xq_Q14_x7x5, xmm_Gain_Q10 );\n\n            xmm_xq_Q14_3210 = _mm_srli_epi64( xmm_xq_Q14_3210, 16 );\n            xmm_xq_Q14_x3x1 = _mm_slli_epi64( xmm_xq_Q14_x3x1, 16 );\n            xmm_xq_Q14_7654 = _mm_srli_epi64( xmm_xq_Q14_7654, 16 );\n            xmm_xq_Q14_x7x5 = _mm_slli_epi64( xmm_xq_Q14_x7x5, 16 );\n\n            xmm_xq_Q14_3210 = _mm_blend_epi16( xmm_xq_Q14_3210, xmm_xq_Q14_x3x1, 0xCC );\n            xmm_xq_Q14_7654 = _mm_blend_epi16( xmm_xq_Q14_7654, xmm_xq_Q14_x7x5, 0xCC );\n\n            /* silk_RSHIFT_ROUND(xq, 8) */\n            xmm_xq_Q14_3210 = _mm_add_epi32( xmm_xq_Q14_3210, xmm_tempa );\n            xmm_xq_Q14_7654 = _mm_add_epi32( xmm_xq_Q14_7654, xmm_tempa );\n\n            xmm_xq_Q14_3210 = _mm_srai_epi32( xmm_xq_Q14_3210, 8 );\n            xmm_xq_Q14_7654 = _mm_srai_epi32( xmm_xq_Q14_7654, 8 );\n\n            /* silk_SAT16 */\n            xmm_xq_Q14_3210 = _mm_packs_epi32( xmm_xq_Q14_3210, xmm_xq_Q14_7654 );\n\n            /* save to xq */\n            _mm_storeu_si128( (__m128i *)(&xq[ i ] ), xmm_xq_Q14_3210 );\n        }\n    }\n    for ( ; i < length; i++)\n    {\n        xq[i] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psLPC_Q14[ i ], Gain_Q10 ), 8 ) );\n    }\n\n    /* Update LPC synth buffer */\n    silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );\n}\n\nstatic OPUS_INLINE void silk_nsq_scale_states_sse4_1(\n    const silk_encoder_state *psEncC,           /* I    Encoder State                   */\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */\n    const opus_int32    x_Q3[],                 /* I    input in Q3                     */\n    opus_int32          x_sc_Q10[],             /* O    input scaled with 1/Gain        */\n    const opus_int16    sLTP[],                 /* I    re-whitened LTP state in Q0     */\n    opus_int32          sLTP_Q15[],             /* O    LTP state matching scaled input */\n    opus_int            subfr,                  /* I    subframe number                 */\n    const opus_int      LTP_scale_Q14,          /* I                                    */\n    const opus_int32    Gains_Q16[ MAX_NB_SUBFR ], /* I                                 */\n    const opus_int      pitchL[ MAX_NB_SUBFR ], /* I    Pitch lag                       */\n    const opus_int      signal_type             /* I    Signal type                     */\n)\n{\n    opus_int   i, lag;\n    opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;\n    __m128i xmm_inv_gain_Q23, xmm_x_Q3_x2x0, xmm_x_Q3_x3x1;\n\n    lag          = pitchL[ subfr ];\n    inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );\n    silk_assert( inv_gain_Q31 != 0 );\n\n    /* Calculate gain adjustment factor */\n    if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {\n        gain_adj_Q16 =  silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );\n    } else {\n        gain_adj_Q16 = (opus_int32)1 << 16;\n    }\n\n    /* Scale input */\n    inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );\n\n    /* prepare inv_gain_Q23 in packed 4 32-bits */\n    xmm_inv_gain_Q23 = _mm_set1_epi32(inv_gain_Q23);\n\n    for( i = 0; i < psEncC->subfr_length - 3; i += 4 ) {\n        xmm_x_Q3_x2x0 = _mm_loadu_si128( (__m128i *)(&(x_Q3[ i ] ) ) );\n\n        /* equal shift right 4 bytes*/\n        xmm_x_Q3_x3x1 = _mm_shuffle_epi32( xmm_x_Q3_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );\n\n        xmm_x_Q3_x2x0 = _mm_mul_epi32( xmm_x_Q3_x2x0, xmm_inv_gain_Q23 );\n        xmm_x_Q3_x3x1 = _mm_mul_epi32( xmm_x_Q3_x3x1, xmm_inv_gain_Q23 );\n\n        xmm_x_Q3_x2x0 = _mm_srli_epi64( xmm_x_Q3_x2x0, 16 );\n        xmm_x_Q3_x3x1 = _mm_slli_epi64( xmm_x_Q3_x3x1, 16 );\n\n        xmm_x_Q3_x2x0 = _mm_blend_epi16( xmm_x_Q3_x2x0, xmm_x_Q3_x3x1, 0xCC );\n\n        _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ] ) ), xmm_x_Q3_x2x0 );\n    }\n\n    for( ; i < psEncC->subfr_length; i++ ) {\n        x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );\n    }\n\n    /* Save inverse gain */\n    NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];\n\n    /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */\n    if( NSQ->rewhite_flag ) {\n        if( subfr == 0 ) {\n            /* Do LTP downscaling */\n            inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );\n        }\n        for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {\n            silk_assert( i < MAX_FRAME_LENGTH );\n            sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );\n        }\n    }\n\n    /* Adjust for changing gain */\n    if( gain_adj_Q16 != (opus_int32)1 << 16 ) {\n        /* Scale long-term shaping state */\n        __m128i xmm_gain_adj_Q16, xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1;\n\n        /* prepare gain_adj_Q16 in packed 4 32-bits */\n        xmm_gain_adj_Q16 = _mm_set1_epi32(gain_adj_Q16);\n\n        for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 3; i += 4 )\n        {\n            xmm_sLTP_shp_Q14_x2x0 = _mm_loadu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ) );\n            /* equal shift right 4 bytes*/\n            xmm_sLTP_shp_Q14_x3x1 = _mm_shuffle_epi32( xmm_sLTP_shp_Q14_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );\n\n            xmm_sLTP_shp_Q14_x2x0 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x2x0, xmm_gain_adj_Q16 );\n            xmm_sLTP_shp_Q14_x3x1 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x3x1, xmm_gain_adj_Q16 );\n\n            xmm_sLTP_shp_Q14_x2x0 = _mm_srli_epi64( xmm_sLTP_shp_Q14_x2x0, 16 );\n            xmm_sLTP_shp_Q14_x3x1 = _mm_slli_epi64( xmm_sLTP_shp_Q14_x3x1, 16 );\n\n            xmm_sLTP_shp_Q14_x2x0 = _mm_blend_epi16( xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1, 0xCC );\n\n            _mm_storeu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ), xmm_sLTP_shp_Q14_x2x0 );\n        }\n\n        for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {\n            NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );\n        }\n\n        /* Scale long-term prediction state */\n        if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {\n            for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {\n                sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );\n            }\n        }\n\n        NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 );\n\n        /* Scale short-term prediction and shaping states */\n        for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {\n            NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );\n        }\n        for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {\n            NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );\n        }\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/x86/SigProc_FIX_sse.h",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef SIGPROC_FIX_SSE_H\n#define SIGPROC_FIX_SSE_H\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#if defined(OPUS_X86_MAY_HAVE_SSE4_1)\nvoid silk_burg_modified_sse4_1(\n    opus_int32                  *res_nrg,           /* O    Residual energy                                             */\n    opus_int                    *res_nrg_Q,         /* O    Residual energy Q value                                     */\n    opus_int32                  A_Q16[],            /* O    Prediction coefficients (length order)                      */\n    const opus_int16            x[],                /* I    Input signal, length: nb_subfr * ( D + subfr_length )       */\n    const opus_int32            minInvGain_Q30,     /* I    Inverse of max prediction gain                              */\n    const opus_int              subfr_length,       /* I    Input signal subframe length (incl. D preceding samples)    */\n    const opus_int              nb_subfr,           /* I    Number of subframes stacked in x                            */\n    const opus_int              D,                  /* I    Order                                                       */\n    int                         arch                /* I    Run-time architecture                                       */\n);\n\n#if defined(OPUS_X86_PRESUME_SSE4_1)\n#define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \\\n    ((void)(arch), silk_burg_modified_sse4_1(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch))\n\n#else\n\nextern void (*const SILK_BURG_MODIFIED_IMPL[OPUS_ARCHMASK + 1])(\n    opus_int32                  *res_nrg,           /* O    Residual energy                                             */\n    opus_int                    *res_nrg_Q,         /* O    Residual energy Q value                                     */\n    opus_int32                  A_Q16[],            /* O    Prediction coefficients (length order)                      */\n    const opus_int16            x[],                /* I    Input signal, length: nb_subfr * ( D + subfr_length )       */\n    const opus_int32            minInvGain_Q30,     /* I    Inverse of max prediction gain                              */\n    const opus_int              subfr_length,       /* I    Input signal subframe length (incl. D preceding samples)    */\n    const opus_int              nb_subfr,           /* I    Number of subframes stacked in x                            */\n    const opus_int              D,                  /* I    Order                                                       */\n    int                         arch                /* I    Run-time architecture                                       */);\n\n#  define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \\\n    ((*SILK_BURG_MODIFIED_IMPL[(arch) & OPUS_ARCHMASK])(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch))\n\n#endif\n\nopus_int64 silk_inner_prod16_aligned_64_sse4_1(\n    const opus_int16 *inVec1,\n    const opus_int16 *inVec2,\n    const opus_int   len\n);\n\n\n#if defined(OPUS_X86_PRESUME_SSE4_1)\n\n#define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \\\n    ((void)(arch),silk_inner_prod16_aligned_64_sse4_1(inVec1, inVec2, len))\n\n#else\n\nextern opus_int64 (*const SILK_INNER_PROD16_ALIGNED_64_IMPL[OPUS_ARCHMASK + 1])(\n                    const opus_int16 *inVec1,\n                    const opus_int16 *inVec2,\n                    const opus_int   len);\n\n#  define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \\\n    ((*SILK_INNER_PROD16_ALIGNED_64_IMPL[(arch) & OPUS_ARCHMASK])(inVec1, inVec2, len))\n\n#endif\n#endif\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/x86/VAD_sse.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <xmmintrin.h>\n#include <emmintrin.h>\n#include <smmintrin.h>\n\n#include \"main.h\"\n#include \"stack_alloc.h\"\n\n/* Weighting factors for tilt measure */\nstatic const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 };\n\n/***************************************/\n/* Get the speech activity level in Q8 */\n/***************************************/\nopus_int silk_VAD_GetSA_Q8_sse4_1(                  /* O    Return value, 0 if success                  */\n    silk_encoder_state          *psEncC,            /* I/O  Encoder state                               */\n    const opus_int16            pIn[]               /* I    PCM input                                   */\n)\n{\n    opus_int   SA_Q15, pSNR_dB_Q7, input_tilt;\n    opus_int   decimated_framelength1, decimated_framelength2;\n    opus_int   decimated_framelength;\n    opus_int   dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;\n    opus_int32 sumSquared, smooth_coef_Q16;\n    opus_int16 HPstateTmp;\n    VARDECL( opus_int16, X );\n    opus_int32 Xnrg[ VAD_N_BANDS ];\n    opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];\n    opus_int32 speech_nrg, x_tmp;\n    opus_int   X_offset[ VAD_N_BANDS ];\n    opus_int   ret = 0;\n    silk_VAD_state *psSilk_VAD = &psEncC->sVAD;\n\n    SAVE_STACK;\n\n    /* Safety checks */\n    silk_assert( VAD_N_BANDS == 4 );\n    silk_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );\n    silk_assert( psEncC->frame_length <= 512 );\n    silk_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );\n\n    /***********************/\n    /* Filter and Decimate */\n    /***********************/\n    decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );\n    decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );\n    decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 );\n    /* Decimate into 4 bands:\n       0       L      3L       L              3L                             5L\n               -      --       -              --                             --\n               8       8       2               4                              4\n\n       [0-1 kHz| temp. |1-2 kHz|    2-4 kHz    |            4-8 kHz           |\n\n       They're arranged to allow the minimal ( frame_length / 4 ) extra\n       scratch space during the downsampling process */\n    X_offset[ 0 ] = 0;\n    X_offset[ 1 ] = decimated_framelength + decimated_framelength2;\n    X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;\n    X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;\n    ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );\n\n    /* 0-8 kHz to 0-4 kHz and 4-8 kHz */\n    silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[  0 ],\n        X, &X[ X_offset[ 3 ] ], psEncC->frame_length );\n\n    /* 0-4 kHz to 0-2 kHz and 2-4 kHz */\n    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],\n        X, &X[ X_offset[ 2 ] ], decimated_framelength1 );\n\n    /* 0-2 kHz to 0-1 kHz and 1-2 kHz */\n    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],\n        X, &X[ X_offset[ 1 ] ], decimated_framelength2 );\n\n    /*********************************************/\n    /* HP filter on lowest band (differentiator) */\n    /*********************************************/\n    X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );\n    HPstateTmp = X[ decimated_framelength - 1 ];\n    for( i = decimated_framelength - 1; i > 0; i-- ) {\n        X[ i - 1 ]  = silk_RSHIFT( X[ i - 1 ], 1 );\n        X[ i ]     -= X[ i - 1 ];\n    }\n    X[ 0 ] -= psSilk_VAD->HPstate;\n    psSilk_VAD->HPstate = HPstateTmp;\n\n    /*************************************/\n    /* Calculate the energy in each band */\n    /*************************************/\n    for( b = 0; b < VAD_N_BANDS; b++ ) {\n        /* Find the decimated framelength in the non-uniformly divided bands */\n        decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );\n\n        /* Split length into subframe lengths */\n        dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );\n        dec_subframe_offset = 0;\n\n        /* Compute energy per sub-frame */\n        /* initialize with summed energy of last subframe */\n        Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];\n        for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {\n            __m128i xmm_X, xmm_acc;\n            sumSquared = 0;\n\n            xmm_acc = _mm_setzero_si128();\n\n            for( i = 0; i < dec_subframe_length - 7; i += 8 )\n            {\n                xmm_X   = _mm_loadu_si128( (__m128i *)&(X[ X_offset[ b ] + i + dec_subframe_offset ] ) );\n                xmm_X   = _mm_srai_epi16( xmm_X, 3 );\n                xmm_X   = _mm_madd_epi16( xmm_X, xmm_X );\n                xmm_acc = _mm_add_epi32( xmm_acc, xmm_X );\n            }\n\n            xmm_acc = _mm_add_epi32( xmm_acc, _mm_unpackhi_epi64( xmm_acc, xmm_acc ) );\n            xmm_acc = _mm_add_epi32( xmm_acc, _mm_shufflelo_epi16( xmm_acc, 0x0E ) );\n\n            sumSquared += _mm_cvtsi128_si32( xmm_acc );\n\n            for( ; i < dec_subframe_length; i++ ) {\n                /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2.            */\n                /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128)  */\n                x_tmp = silk_RSHIFT(\n                    X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );\n                sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );\n\n                /* Safety check */\n                silk_assert( sumSquared >= 0 );\n            }\n\n            /* Add/saturate summed energy of current subframe */\n            if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {\n                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );\n            } else {\n                /* Look-ahead subframe */\n                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );\n            }\n\n            dec_subframe_offset += dec_subframe_length;\n        }\n        psSilk_VAD->XnrgSubfr[ b ] = sumSquared;\n    }\n\n    /********************/\n    /* Noise estimation */\n    /********************/\n    silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );\n\n    /***********************************************/\n    /* Signal-plus-noise to noise ratio estimation */\n    /***********************************************/\n    sumSquared = 0;\n    input_tilt = 0;\n    for( b = 0; b < VAD_N_BANDS; b++ ) {\n        speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];\n        if( speech_nrg > 0 ) {\n            /* Divide, with sufficient resolution */\n            if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {\n                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );\n            } else {\n                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );\n            }\n\n            /* Convert to log domain */\n            SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;\n\n            /* Sum-of-squares */\n            sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 );          /* Q14 */\n\n            /* Tilt measure */\n            if( speech_nrg < ( (opus_int32)1 << 20 ) ) {\n                /* Scale down SNR value for small subband speech energies */\n                SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );\n            }\n            input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );\n        } else {\n            NrgToNoiseRatio_Q8[ b ] = 256;\n        }\n    }\n\n    /* Mean-of-squares */\n    sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */\n\n    /* Root-mean-square approximation, scale to dBs, and write to output pointer */\n    pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */\n\n    /*********************************/\n    /* Speech Probability Estimation */\n    /*********************************/\n    SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );\n\n    /**************************/\n    /* Frequency Tilt Measure */\n    /**************************/\n    psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 );\n\n    /**************************************************/\n    /* Scale the sigmoid output based on power levels */\n    /**************************************************/\n    speech_nrg = 0;\n    for( b = 0; b < VAD_N_BANDS; b++ ) {\n        /* Accumulate signal-without-noise energies, higher frequency bands have more weight */\n        speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );\n    }\n\n    /* Power scaling */\n    if( speech_nrg <= 0 ) {\n        SA_Q15 = silk_RSHIFT( SA_Q15, 1 );\n    } else if( speech_nrg < 32768 ) {\n        if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {\n            speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 16 );\n        } else {\n            speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 15 );\n        }\n\n        /* square-root */\n        speech_nrg = silk_SQRT_APPROX( speech_nrg );\n        SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 );\n    }\n\n    /* Copy the resulting speech activity in Q8 */\n    psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX );\n\n    /***********************************/\n    /* Energy Level and SNR estimation */\n    /***********************************/\n    /* Smoothing coefficient */\n    smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) );\n\n    if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {\n        smooth_coef_Q16 >>= 1;\n    }\n\n    for( b = 0; b < VAD_N_BANDS; b++ ) {\n        /* compute smoothed energy-to-noise ratio per band */\n        psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],\n            NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );\n\n        /* signal to noise ratio in dB per band */\n        SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );\n        /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */\n        psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );\n    }\n\n    RESTORE_STACK;\n    return( ret );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/x86/VQ_WMat_EC_sse.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <xmmintrin.h>\n#include <emmintrin.h>\n#include <smmintrin.h>\n#include \"main.h\"\n#include \"celt/x86/x86cpu.h\"\n\n/* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */\nvoid silk_VQ_WMat_EC_sse4_1(\n    opus_int8                   *ind,                           /* O    index of best codebook vector               */\n    opus_int32                  *rate_dist_Q14,                 /* O    best weighted quant error + mu * rate       */\n    opus_int                    *gain_Q7,                       /* O    sum of absolute LTP coefficients            */\n    const opus_int16            *in_Q14,                        /* I    input vector to be quantized                */\n    const opus_int32            *W_Q18,                         /* I    weighting matrix                            */\n    const opus_int8             *cb_Q7,                         /* I    codebook                                    */\n    const opus_uint8            *cb_gain_Q7,                    /* I    codebook effective gain                     */\n    const opus_uint8            *cl_Q5,                         /* I    code length for each codebook vector        */\n    const opus_int              mu_Q9,                          /* I    tradeoff betw. weighted error and rate      */\n    const opus_int32            max_gain_Q7,                    /* I    maximum sum of absolute LTP coefficients    */\n    opus_int                    L                               /* I    number of vectors in codebook               */\n)\n{\n    opus_int   k, gain_tmp_Q7;\n    const opus_int8 *cb_row_Q7;\n    opus_int16 diff_Q14[ 5 ];\n    opus_int32 sum1_Q14, sum2_Q16;\n\n    __m128i C_tmp1, C_tmp2, C_tmp3, C_tmp4, C_tmp5;\n    /* Loop over codebook */\n    *rate_dist_Q14 = silk_int32_MAX;\n    cb_row_Q7 = cb_Q7;\n    for( k = 0; k < L; k++ ) {\n        gain_tmp_Q7 = cb_gain_Q7[k];\n\n        diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 );\n\n        C_tmp1 = OP_CVTEPI16_EPI32_M64( &in_Q14[ 1 ] );\n        C_tmp2 = OP_CVTEPI8_EPI32_M32( &cb_row_Q7[ 1 ] );\n        C_tmp2 = _mm_slli_epi32( C_tmp2, 7 );\n        C_tmp1 = _mm_sub_epi32( C_tmp1, C_tmp2 );\n\n        diff_Q14[ 1 ] = _mm_extract_epi16( C_tmp1, 0 );\n        diff_Q14[ 2 ] = _mm_extract_epi16( C_tmp1, 2 );\n        diff_Q14[ 3 ] = _mm_extract_epi16( C_tmp1, 4 );\n        diff_Q14[ 4 ] = _mm_extract_epi16( C_tmp1, 6 );\n\n        /* Weighted rate */\n        sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] );\n\n        /* Penalty for too large gain */\n        sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 );\n\n        silk_assert( sum1_Q14 >= 0 );\n\n        /* first row of W_Q18 */\n        C_tmp3 = _mm_loadu_si128( (__m128i *)(&W_Q18[ 1 ] ) );\n        C_tmp4 = _mm_mul_epi32( C_tmp3, C_tmp1 );\n        C_tmp4 = _mm_srli_si128( C_tmp4, 2 );\n\n        C_tmp1 = _mm_shuffle_epi32( C_tmp1, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* shift right 4 bytes */\n        C_tmp3 = _mm_shuffle_epi32( C_tmp3, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* shift right 4 bytes */\n\n        C_tmp5 = _mm_mul_epi32( C_tmp3, C_tmp1 );\n        C_tmp5 = _mm_srli_si128( C_tmp5, 2 );\n\n        C_tmp5 = _mm_add_epi32( C_tmp4, C_tmp5 );\n        C_tmp5 = _mm_slli_epi32( C_tmp5, 1 );\n\n        C_tmp5 = _mm_add_epi32( C_tmp5, _mm_shuffle_epi32( C_tmp5, _MM_SHUFFLE( 0, 0, 0, 2 ) ) );\n        sum2_Q16 = _mm_cvtsi128_si32( C_tmp5 );\n\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  0 ], diff_Q14[ 0 ] );\n        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 0 ] );\n\n        /* second row of W_Q18 */\n        sum2_Q16 = silk_SMULWB(           W_Q18[  7 ], diff_Q14[ 2 ] );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  8 ], diff_Q14[ 3 ] );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  9 ], diff_Q14[ 4 ] );\n        sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  6 ], diff_Q14[ 1 ] );\n        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 1 ] );\n\n        /* third row of W_Q18 */\n        sum2_Q16 = silk_SMULWB(           W_Q18[ 13 ], diff_Q14[ 3 ] );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] );\n        sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] );\n        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 2 ] );\n\n        /* fourth row of W_Q18 */\n        sum2_Q16 = silk_SMULWB(           W_Q18[ 19 ], diff_Q14[ 4 ] );\n        sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );\n        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] );\n        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 3 ] );\n\n        /* last row of W_Q18 */\n        sum2_Q16 = silk_SMULWB(           W_Q18[ 24 ], diff_Q14[ 4 ] );\n        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 4 ] );\n\n        silk_assert( sum1_Q14 >= 0 );\n\n        /* find best */\n        if( sum1_Q14 < *rate_dist_Q14 ) {\n            *rate_dist_Q14 = sum1_Q14;\n            *ind = (opus_int8)k;\n            *gain_Q7 = gain_tmp_Q7;\n        }\n\n        /* Go to next cbk vector */\n        cb_row_Q7 += LTP_ORDER;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/x86/main_sse.h",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef MAIN_SSE_H\n#define MAIN_SSE_H\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n# if defined(OPUS_X86_MAY_HAVE_SSE4_1)\n\n#  define OVERRIDE_silk_VQ_WMat_EC\n\nvoid silk_VQ_WMat_EC_sse4_1(\n    opus_int8                   *ind,                           /* O    index of best codebook vector               */\n    opus_int32                  *rate_dist_Q14,                 /* O    best weighted quant error + mu * rate       */\n    opus_int                    *gain_Q7,                       /* O    sum of absolute LTP coefficients            */\n    const opus_int16            *in_Q14,                        /* I    input vector to be quantized                */\n    const opus_int32            *W_Q18,                         /* I    weighting matrix                            */\n    const opus_int8             *cb_Q7,                         /* I    codebook                                    */\n    const opus_uint8            *cb_gain_Q7,                    /* I    codebook effective gain                     */\n    const opus_uint8            *cl_Q5,                         /* I    code length for each codebook vector        */\n    const opus_int              mu_Q9,                          /* I    tradeoff betw. weighted error and rate      */\n    const opus_int32            max_gain_Q7,                    /* I    maximum sum of absolute LTP coefficients    */\n    opus_int                    L                               /* I    number of vectors in codebook               */\n);\n\n#if defined OPUS_X86_PRESUME_SSE4_1\n\n#define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \\\n                          mu_Q9, max_gain_Q7, L, arch) \\\n    ((void)(arch),silk_VQ_WMat_EC_sse4_1(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \\\n                          mu_Q9, max_gain_Q7, L))\n\n#else\n\nextern void (*const SILK_VQ_WMAT_EC_IMPL[OPUS_ARCHMASK + 1])(\n    opus_int8                   *ind,                           /* O    index of best codebook vector               */\n    opus_int32                  *rate_dist_Q14,                 /* O    best weighted quant error + mu * rate       */\n    opus_int                    *gain_Q7,                       /* O    sum of absolute LTP coefficients            */\n    const opus_int16            *in_Q14,                        /* I    input vector to be quantized                */\n    const opus_int32            *W_Q18,                         /* I    weighting matrix                            */\n    const opus_int8             *cb_Q7,                         /* I    codebook                                    */\n    const opus_uint8            *cb_gain_Q7,                    /* I    codebook effective gain                     */\n    const opus_uint8            *cl_Q5,                         /* I    code length for each codebook vector        */\n    const opus_int              mu_Q9,                          /* I    tradeoff betw. weighted error and rate      */\n    const opus_int32            max_gain_Q7,                    /* I    maximum sum of absolute LTP coefficients    */\n    opus_int                    L                               /* I    number of vectors in codebook               */\n);\n\n#  define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \\\n                          mu_Q9, max_gain_Q7, L, arch) \\\n    ((*SILK_VQ_WMAT_EC_IMPL[(arch) & OPUS_ARCHMASK])(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \\\n                          mu_Q9, max_gain_Q7, L))\n\n#endif\n\n#  define OVERRIDE_silk_NSQ\n\nvoid silk_NSQ_sse4_1(\n    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */\n    silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */\n    SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */\n    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */\n    opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */\n    const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */\n    const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */\n    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */\n    const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */\n    const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */\n    const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */\n    const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */\n    const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */\n    const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */\n    const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */\n);\n\n#if defined OPUS_X86_PRESUME_SSE4_1\n\n#define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \\\n                   HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \\\n    ((void)(arch),silk_NSQ_sse4_1(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \\\n                   HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))\n\n#else\n\nextern void (*const SILK_NSQ_IMPL[OPUS_ARCHMASK + 1])(\n    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */\n    silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */\n    SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */\n    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */\n    opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */\n    const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */\n    const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */\n    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */\n    const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */\n    const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */\n    const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */\n    const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */\n    const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */\n    const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */\n    const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */\n);\n\n#  define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \\\n                   HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \\\n    ((*SILK_NSQ_IMPL[(arch) & OPUS_ARCHMASK])(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \\\n                   HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))\n\n#endif\n\n#  define OVERRIDE_silk_NSQ_del_dec\n\nvoid silk_NSQ_del_dec_sse4_1(\n    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */\n    silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */\n    SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */\n    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */\n    opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */\n    const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */\n    const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */\n    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */\n    const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */\n    const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */\n    const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */\n    const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */\n    const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */\n    const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */\n    const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */\n);\n\n#if defined OPUS_X86_PRESUME_SSE4_1\n\n#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \\\n                           HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \\\n    ((void)(arch),silk_NSQ_del_dec_sse4_1(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \\\n                           HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))\n\n#else\n\nextern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(\n    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */\n    silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */\n    SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */\n    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */\n    opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */\n    const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */\n    const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */\n    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */\n    const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */\n    const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */\n    const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */\n    const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */\n    const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */\n    const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */\n    const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */\n);\n\n#  define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \\\n                           HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \\\n    ((*SILK_NSQ_DEL_DEC_IMPL[(arch) & OPUS_ARCHMASK])(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \\\n                           HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))\n\n#endif\n\nvoid silk_noise_shape_quantizer(\n    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */\n    opus_int            signalType,             /* I    Signal type                     */\n    const opus_int32    x_sc_Q10[],             /* I                                    */\n    opus_int8           pulses[],               /* O                                    */\n    opus_int16          xq[],                   /* O                                    */\n    opus_int32          sLTP_Q15[],             /* I/O  LTP state                       */\n    const opus_int16    a_Q12[],                /* I    Short term prediction coefs     */\n    const opus_int16    b_Q14[],                /* I    Long term prediction coefs      */\n    const opus_int16    AR_shp_Q13[],           /* I    Noise shaping AR coefs          */\n    opus_int            lag,                    /* I    Pitch lag                       */\n    opus_int32          HarmShapeFIRPacked_Q14, /* I                                    */\n    opus_int            Tilt_Q14,               /* I    Spectral tilt                   */\n    opus_int32          LF_shp_Q14,             /* I                                    */\n    opus_int32          Gain_Q16,               /* I                                    */\n    opus_int            Lambda_Q10,             /* I                                    */\n    opus_int            offset_Q10,             /* I                                    */\n    opus_int            length,                 /* I    Input length                    */\n    opus_int            shapingLPCOrder,        /* I    Noise shaping AR filter order   */\n    opus_int            predictLPCOrder         /* I    Prediction filter order         */\n);\n\n/**************************/\n/* Noise level estimation */\n/**************************/\nvoid silk_VAD_GetNoiseLevels(\n    const opus_int32            pX[ VAD_N_BANDS ],  /* I    subband energies                            */\n    silk_VAD_state              *psSilk_VAD         /* I/O  Pointer to Silk VAD state                   */\n);\n\n#  define OVERRIDE_silk_VAD_GetSA_Q8\n\nopus_int silk_VAD_GetSA_Q8_sse4_1(\n    silk_encoder_state *psEnC,\n    const opus_int16   pIn[]\n);\n\n#if defined(OPUS_X86_PRESUME_SSE4_1)\n#define silk_VAD_GetSA_Q8(psEnC, pIn, arch) ((void)(arch),silk_VAD_GetSA_Q8_sse4_1(psEnC, pIn))\n\n#else\n\n#  define silk_VAD_GetSA_Q8(psEnC, pIn, arch) \\\n     ((*SILK_VAD_GETSA_Q8_IMPL[(arch) & OPUS_ARCHMASK])(psEnC, pIn))\n\nextern opus_int (*const SILK_VAD_GETSA_Q8_IMPL[OPUS_ARCHMASK + 1])(\n     silk_encoder_state *psEnC,\n     const opus_int16   pIn[]);\n\n#  define OVERRIDE_silk_warped_LPC_analysis_filter_FIX\n\n#endif\n\nvoid silk_warped_LPC_analysis_filter_FIX_sse4_1(\n          opus_int32            state[],                    /* I/O  State [order + 1]                   */\n          opus_int32            res_Q2[],                   /* O    Residual signal [length]            */\n    const opus_int16            coef_Q13[],                 /* I    Coefficients [order]                */\n    const opus_int16            input[],                    /* I    Input signal [length]               */\n    const opus_int16            lambda_Q16,                 /* I    Warping factor                      */\n    const opus_int              length,                     /* I    Length of input signal              */\n    const opus_int              order                       /* I    Filter order (even)                 */\n);\n\n#if defined(OPUS_X86_PRESUME_SSE4_1)\n#define silk_warped_LPC_analysis_filter_FIX(state, res_Q2, coef_Q13, input, lambda_Q16, length, order, arch) \\\n    ((void)(arch),silk_warped_LPC_analysis_filter_FIX_c(state, res_Q2, coef_Q13, input, lambda_Q16, length, order))\n\n#else\n\nextern void (*const SILK_WARPED_LPC_ANALYSIS_FILTER_FIX_IMPL[OPUS_ARCHMASK + 1])(\n          opus_int32            state[],                    /* I/O  State [order + 1]                   */\n          opus_int32            res_Q2[],                   /* O    Residual signal [length]            */\n    const opus_int16            coef_Q13[],                 /* I    Coefficients [order]                */\n    const opus_int16            input[],                    /* I    Input signal [length]               */\n    const opus_int16            lambda_Q16,                 /* I    Warping factor                      */\n    const opus_int              length,                     /* I    Length of input signal              */\n    const opus_int              order                       /* I    Filter order (even)                 */\n);\n\n#  define silk_warped_LPC_analysis_filter_FIX(state, res_Q2, coef_Q13, input, lambda_Q16, length, order, arch) \\\n    ((*SILK_WARPED_LPC_ANALYSIS_FILTER_FIX_IMPL[(arch) & OPUS_ARCHMASK])(state, res_Q2, coef_Q13, input, lambda_Q16, length, order))\n\n#endif\n\n# endif\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk/x86/x86_silk_map.c",
    "content": "/* Copyright (c) 2014, Cisco Systems, INC\n   Written by XiangMingZhu WeiZhou MinPeng YanWang\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#if defined(HAVE_CONFIG_H)\n#include \"config.h\"\n#endif\n\n#include \"celt/x86/x86cpu.h\"\n#include \"structs.h\"\n#include \"SigProc_FIX.h\"\n#include \"pitch.h\"\n#include \"main.h\"\n\n#if !defined(OPUS_X86_PRESUME_SSE4_1)\n\n#if defined(FIXED_POINT)\n\n#include \"fixed/main_FIX.h\"\n\nopus_int64 (*const SILK_INNER_PROD16_ALIGNED_64_IMPL[ OPUS_ARCHMASK + 1 ] )(\n    const opus_int16 *inVec1,\n    const opus_int16 *inVec2,\n    const opus_int   len\n) = {\n  silk_inner_prod16_aligned_64_c,                  /* non-sse */\n  silk_inner_prod16_aligned_64_c,\n  silk_inner_prod16_aligned_64_c,\n  MAY_HAVE_SSE4_1( silk_inner_prod16_aligned_64 ), /* sse4.1 */\n  MAY_HAVE_SSE4_1( silk_inner_prod16_aligned_64 )  /* avx */\n};\n\n#endif\n\nopus_int (*const SILK_VAD_GETSA_Q8_IMPL[ OPUS_ARCHMASK + 1 ] )(\n    silk_encoder_state *psEncC,\n    const opus_int16   pIn[]\n) = {\n  silk_VAD_GetSA_Q8_c,                  /* non-sse */\n  silk_VAD_GetSA_Q8_c,\n  silk_VAD_GetSA_Q8_c,\n  MAY_HAVE_SSE4_1( silk_VAD_GetSA_Q8 ), /* sse4.1 */\n  MAY_HAVE_SSE4_1( silk_VAD_GetSA_Q8 )  /* avx */\n};\n\nvoid (*const SILK_NSQ_IMPL[ OPUS_ARCHMASK + 1 ] )(\n    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */\n    silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */\n    SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */\n    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */\n    opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */\n    const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */\n    const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */\n    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */\n    const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */\n    const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */\n    const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */\n    const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */\n    const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */\n    const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */\n    const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */\n) = {\n  silk_NSQ_c,                  /* non-sse */\n  silk_NSQ_c,\n  silk_NSQ_c,\n  MAY_HAVE_SSE4_1( silk_NSQ ), /* sse4.1 */\n  MAY_HAVE_SSE4_1( silk_NSQ )  /* avx */\n};\n\nvoid (*const SILK_VQ_WMAT_EC_IMPL[ OPUS_ARCHMASK + 1 ] )(\n    opus_int8                   *ind,                           /* O    index of best codebook vector               */\n    opus_int32                  *rate_dist_Q14,                 /* O    best weighted quant error + mu * rate       */\n    opus_int                    *gain_Q7,                       /* O    sum of absolute LTP coefficients            */\n    const opus_int16            *in_Q14,                        /* I    input vector to be quantized                */\n    const opus_int32            *W_Q18,                         /* I    weighting matrix                            */\n    const opus_int8             *cb_Q7,                         /* I    codebook                                    */\n    const opus_uint8            *cb_gain_Q7,                    /* I    codebook effective gain                     */\n    const opus_uint8            *cl_Q5,                         /* I    code length for each codebook vector        */\n    const opus_int              mu_Q9,                          /* I    tradeoff betw. weighted error and rate      */\n    const opus_int32            max_gain_Q7,                    /* I    maximum sum of absolute LTP coefficients    */\n    opus_int                    L                               /* I    number of vectors in codebook               */\n) = {\n  silk_VQ_WMat_EC_c,                  /* non-sse */\n  silk_VQ_WMat_EC_c,\n  silk_VQ_WMat_EC_c,\n  MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ), /* sse4.1 */\n  MAY_HAVE_SSE4_1( silk_VQ_WMat_EC )  /* avx */\n};\n\nvoid (*const SILK_NSQ_DEL_DEC_IMPL[ OPUS_ARCHMASK + 1 ] )(\n    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */\n    silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */\n    SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */\n    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */\n    opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */\n    const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */\n    const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */\n    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */\n    const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */\n    const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */\n    const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */\n    const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */\n    const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */\n    const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */\n    const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */\n) = {\n  silk_NSQ_del_dec_c,                  /* non-sse */\n  silk_NSQ_del_dec_c,\n  silk_NSQ_del_dec_c,\n  MAY_HAVE_SSE4_1( silk_NSQ_del_dec ), /* sse4.1 */\n  MAY_HAVE_SSE4_1( silk_NSQ_del_dec )  /* avx */\n};\n\n#if defined(FIXED_POINT)\n\nvoid (*const SILK_WARPED_LPC_ANALYSIS_FILTER_FIX_IMPL[ OPUS_ARCHMASK + 1 ] )(\n    opus_int32                  state[],                    /* I/O  State [order + 1]                   */\n    opus_int32                  res_Q2[],                   /* O    Residual signal [length]            */\n    const opus_int16            coef_Q13[],                 /* I    Coefficients [order]                */\n    const opus_int16            input[],                    /* I    Input signal [length]               */\n    const opus_int16            lambda_Q16,                 /* I    Warping factor                      */\n    const opus_int              length,                     /* I    Length of input signal              */\n    const opus_int              order                       /* I    Filter order (even)                 */\n) = {\n  silk_warped_LPC_analysis_filter_FIX_c,                  /* non-sse */\n  silk_warped_LPC_analysis_filter_FIX_c,\n  silk_warped_LPC_analysis_filter_FIX_c,\n  MAY_HAVE_SSE4_1( silk_warped_LPC_analysis_filter_FIX ), /* sse4.1 */\n  MAY_HAVE_SSE4_1( silk_warped_LPC_analysis_filter_FIX )  /* avx */\n};\n\nvoid (*const SILK_BURG_MODIFIED_IMPL[ OPUS_ARCHMASK + 1 ] )(\n    opus_int32                  *res_nrg,           /* O    Residual energy                                             */\n    opus_int                    *res_nrg_Q,         /* O    Residual energy Q value                                     */\n    opus_int32                  A_Q16[],            /* O    Prediction coefficients (length order)                      */\n    const opus_int16            x[],                /* I    Input signal, length: nb_subfr * ( D + subfr_length )       */\n    const opus_int32            minInvGain_Q30,     /* I    Inverse of max prediction gain                              */\n    const opus_int              subfr_length,       /* I    Input signal subframe length (incl. D preceding samples)    */\n    const opus_int              nb_subfr,           /* I    Number of subframes stacked in x                            */\n    const opus_int              D,                  /* I    Order                                                       */\n    int                         arch                /* I    Run-time architecture                                       */\n) = {\n  silk_burg_modified_c,                  /* non-sse */\n  silk_burg_modified_c,\n  silk_burg_modified_c,\n  MAY_HAVE_SSE4_1( silk_burg_modified ), /* sse4.1 */\n  MAY_HAVE_SSE4_1( silk_burg_modified )  /* avx */\n};\n\n#endif\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk_headers.mk",
    "content": "SILK_HEAD = \\\nsilk/debug.h \\\nsilk/control.h \\\nsilk/errors.h \\\nsilk/API.h \\\nsilk/typedef.h \\\nsilk/define.h \\\nsilk/main.h \\\nsilk/x86/main_sse.h \\\nsilk/PLC.h \\\nsilk/structs.h \\\nsilk/tables.h \\\nsilk/tuning_parameters.h \\\nsilk/Inlines.h \\\nsilk/MacroCount.h \\\nsilk/MacroDebug.h \\\nsilk/macros.h \\\nsilk/pitch_est_defines.h \\\nsilk/resampler_private.h \\\nsilk/resampler_rom.h \\\nsilk/resampler_structs.h \\\nsilk/SigProc_FIX.h \\\nsilk/x86/SigProc_FIX_sse.h \\\nsilk/arm/macros_armv4.h \\\nsilk/arm/macros_armv5e.h \\\nsilk/arm/SigProc_FIX_armv4.h \\\nsilk/arm/SigProc_FIX_armv5e.h \\\nsilk/fixed/main_FIX.h \\\nsilk/fixed/structs_FIX.h \\\nsilk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h \\\nsilk/fixed/mips/prefilter_FIX_mipsr1.h \\\nsilk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h \\\nsilk/float/main_FLP.h \\\nsilk/float/structs_FLP.h \\\nsilk/float/SigProc_FLP.h \\\nsilk/mips/macros_mipsr1.h \\\nsilk/mips/NSQ_del_dec_mipsr1.h \\\nsilk/mips/sigproc_fix_mipsr1.h\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/silk_sources.mk",
    "content": "SILK_SOURCES = \\\nsilk/CNG.c \\\nsilk/code_signs.c \\\nsilk/init_decoder.c \\\nsilk/decode_core.c \\\nsilk/decode_frame.c \\\nsilk/decode_parameters.c \\\nsilk/decode_indices.c \\\nsilk/decode_pulses.c \\\nsilk/decoder_set_fs.c \\\nsilk/dec_API.c \\\nsilk/enc_API.c \\\nsilk/encode_indices.c \\\nsilk/encode_pulses.c \\\nsilk/gain_quant.c \\\nsilk/interpolate.c \\\nsilk/LP_variable_cutoff.c \\\nsilk/NLSF_decode.c \\\nsilk/NSQ.c \\\nsilk/NSQ_del_dec.c \\\nsilk/PLC.c \\\nsilk/shell_coder.c \\\nsilk/tables_gain.c \\\nsilk/tables_LTP.c \\\nsilk/tables_NLSF_CB_NB_MB.c \\\nsilk/tables_NLSF_CB_WB.c \\\nsilk/tables_other.c \\\nsilk/tables_pitch_lag.c \\\nsilk/tables_pulses_per_block.c \\\nsilk/VAD.c \\\nsilk/control_audio_bandwidth.c \\\nsilk/quant_LTP_gains.c \\\nsilk/VQ_WMat_EC.c \\\nsilk/HP_variable_cutoff.c \\\nsilk/NLSF_encode.c \\\nsilk/NLSF_VQ.c \\\nsilk/NLSF_unpack.c \\\nsilk/NLSF_del_dec_quant.c \\\nsilk/process_NLSFs.c \\\nsilk/stereo_LR_to_MS.c \\\nsilk/stereo_MS_to_LR.c \\\nsilk/check_control_input.c \\\nsilk/control_SNR.c \\\nsilk/init_encoder.c \\\nsilk/control_codec.c \\\nsilk/A2NLSF.c \\\nsilk/ana_filt_bank_1.c \\\nsilk/biquad_alt.c \\\nsilk/bwexpander_32.c \\\nsilk/bwexpander.c \\\nsilk/debug.c \\\nsilk/decode_pitch.c \\\nsilk/inner_prod_aligned.c \\\nsilk/lin2log.c \\\nsilk/log2lin.c \\\nsilk/LPC_analysis_filter.c \\\nsilk/LPC_inv_pred_gain.c \\\nsilk/table_LSF_cos.c \\\nsilk/NLSF2A.c \\\nsilk/NLSF_stabilize.c \\\nsilk/NLSF_VQ_weights_laroia.c \\\nsilk/pitch_est_tables.c \\\nsilk/resampler.c \\\nsilk/resampler_down2_3.c \\\nsilk/resampler_down2.c \\\nsilk/resampler_private_AR2.c \\\nsilk/resampler_private_down_FIR.c \\\nsilk/resampler_private_IIR_FIR.c \\\nsilk/resampler_private_up2_HQ.c \\\nsilk/resampler_rom.c \\\nsilk/sigm_Q15.c \\\nsilk/sort.c \\\nsilk/sum_sqr_shift.c \\\nsilk/stereo_decode_pred.c \\\nsilk/stereo_encode_pred.c \\\nsilk/stereo_find_predictor.c \\\nsilk/stereo_quant_pred.c\n\nSILK_SOURCES_SSE4_1 = silk/x86/NSQ_sse.c \\\nsilk/x86/NSQ_del_dec_sse.c \\\nsilk/x86/x86_silk_map.c \\\nsilk/x86/VAD_sse.c \\\nsilk/x86/VQ_WMat_EC_sse.c\n\nSILK_SOURCES_FIXED = \\\nsilk/fixed/LTP_analysis_filter_FIX.c \\\nsilk/fixed/LTP_scale_ctrl_FIX.c \\\nsilk/fixed/corrMatrix_FIX.c \\\nsilk/fixed/encode_frame_FIX.c \\\nsilk/fixed/find_LPC_FIX.c \\\nsilk/fixed/find_LTP_FIX.c \\\nsilk/fixed/find_pitch_lags_FIX.c \\\nsilk/fixed/find_pred_coefs_FIX.c \\\nsilk/fixed/noise_shape_analysis_FIX.c \\\nsilk/fixed/prefilter_FIX.c \\\nsilk/fixed/process_gains_FIX.c \\\nsilk/fixed/regularize_correlations_FIX.c \\\nsilk/fixed/residual_energy16_FIX.c \\\nsilk/fixed/residual_energy_FIX.c \\\nsilk/fixed/solve_LS_FIX.c \\\nsilk/fixed/warped_autocorrelation_FIX.c \\\nsilk/fixed/apply_sine_window_FIX.c \\\nsilk/fixed/autocorr_FIX.c \\\nsilk/fixed/burg_modified_FIX.c \\\nsilk/fixed/k2a_FIX.c \\\nsilk/fixed/k2a_Q16_FIX.c \\\nsilk/fixed/pitch_analysis_core_FIX.c \\\nsilk/fixed/vector_ops_FIX.c \\\nsilk/fixed/schur64_FIX.c \\\nsilk/fixed/schur_FIX.c\n\nSILK_SOURCES_FIXED_SSE4_1 = silk/fixed/x86/vector_ops_FIX_sse.c \\\nsilk/fixed/x86/burg_modified_FIX_sse.c \\\nsilk/fixed/x86/prefilter_FIX_sse.c\n\nSILK_SOURCES_FLOAT = \\\nsilk/float/apply_sine_window_FLP.c \\\nsilk/float/corrMatrix_FLP.c \\\nsilk/float/encode_frame_FLP.c \\\nsilk/float/find_LPC_FLP.c \\\nsilk/float/find_LTP_FLP.c \\\nsilk/float/find_pitch_lags_FLP.c \\\nsilk/float/find_pred_coefs_FLP.c \\\nsilk/float/LPC_analysis_filter_FLP.c \\\nsilk/float/LTP_analysis_filter_FLP.c \\\nsilk/float/LTP_scale_ctrl_FLP.c \\\nsilk/float/noise_shape_analysis_FLP.c \\\nsilk/float/prefilter_FLP.c \\\nsilk/float/process_gains_FLP.c \\\nsilk/float/regularize_correlations_FLP.c \\\nsilk/float/residual_energy_FLP.c \\\nsilk/float/solve_LS_FLP.c \\\nsilk/float/warped_autocorrelation_FLP.c \\\nsilk/float/wrappers_FLP.c \\\nsilk/float/autocorrelation_FLP.c \\\nsilk/float/burg_modified_FLP.c \\\nsilk/float/bwexpander_FLP.c \\\nsilk/float/energy_FLP.c \\\nsilk/float/inner_product_FLP.c \\\nsilk/float/k2a_FLP.c \\\nsilk/float/levinsondurbin_FLP.c \\\nsilk/float/LPC_inv_pred_gain_FLP.c \\\nsilk/float/pitch_analysis_core_FLP.c \\\nsilk/float/scale_copy_vector_FLP.c \\\nsilk/float/scale_vector_FLP.c \\\nsilk/float/schur_FLP.c \\\nsilk/float/sort_FLP.c\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/analysis.c",
    "content": "/* Copyright (c) 2011 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"kiss_fft.h\"\n#include \"celt.h\"\n#include \"modes.h\"\n#include \"arch.h\"\n#include \"quant_bands.h\"\n#include <stdio.h>\n#include \"analysis.h\"\n#include \"mlp.h\"\n#include \"stack_alloc.h\"\n\n#ifndef M_PI\n#define M_PI 3.141592653\n#endif\n\nstatic const float dct_table[128] = {\n        0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,\n        0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,\n        0.351851f, 0.338330f, 0.311806f, 0.273300f, 0.224292f, 0.166664f, 0.102631f, 0.034654f,\n       -0.034654f,-0.102631f,-0.166664f,-0.224292f,-0.273300f,-0.311806f,-0.338330f,-0.351851f,\n        0.346760f, 0.293969f, 0.196424f, 0.068975f,-0.068975f,-0.196424f,-0.293969f,-0.346760f,\n       -0.346760f,-0.293969f,-0.196424f,-0.068975f, 0.068975f, 0.196424f, 0.293969f, 0.346760f,\n        0.338330f, 0.224292f, 0.034654f,-0.166664f,-0.311806f,-0.351851f,-0.273300f,-0.102631f,\n        0.102631f, 0.273300f, 0.351851f, 0.311806f, 0.166664f,-0.034654f,-0.224292f,-0.338330f,\n        0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f,\n        0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f,\n        0.311806f, 0.034654f,-0.273300f,-0.338330f,-0.102631f, 0.224292f, 0.351851f, 0.166664f,\n       -0.166664f,-0.351851f,-0.224292f, 0.102631f, 0.338330f, 0.273300f,-0.034654f,-0.311806f,\n        0.293969f,-0.068975f,-0.346760f,-0.196424f, 0.196424f, 0.346760f, 0.068975f,-0.293969f,\n       -0.293969f, 0.068975f, 0.346760f, 0.196424f,-0.196424f,-0.346760f,-0.068975f, 0.293969f,\n        0.273300f,-0.166664f,-0.338330f, 0.034654f, 0.351851f, 0.102631f,-0.311806f,-0.224292f,\n        0.224292f, 0.311806f,-0.102631f,-0.351851f,-0.034654f, 0.338330f, 0.166664f,-0.273300f,\n};\n\nstatic const float analysis_window[240] = {\n      0.000043f, 0.000171f, 0.000385f, 0.000685f, 0.001071f, 0.001541f, 0.002098f, 0.002739f,\n      0.003466f, 0.004278f, 0.005174f, 0.006156f, 0.007222f, 0.008373f, 0.009607f, 0.010926f,\n      0.012329f, 0.013815f, 0.015385f, 0.017037f, 0.018772f, 0.020590f, 0.022490f, 0.024472f,\n      0.026535f, 0.028679f, 0.030904f, 0.033210f, 0.035595f, 0.038060f, 0.040604f, 0.043227f,\n      0.045928f, 0.048707f, 0.051564f, 0.054497f, 0.057506f, 0.060591f, 0.063752f, 0.066987f,\n      0.070297f, 0.073680f, 0.077136f, 0.080665f, 0.084265f, 0.087937f, 0.091679f, 0.095492f,\n      0.099373f, 0.103323f, 0.107342f, 0.111427f, 0.115579f, 0.119797f, 0.124080f, 0.128428f,\n      0.132839f, 0.137313f, 0.141849f, 0.146447f, 0.151105f, 0.155823f, 0.160600f, 0.165435f,\n      0.170327f, 0.175276f, 0.180280f, 0.185340f, 0.190453f, 0.195619f, 0.200838f, 0.206107f,\n      0.211427f, 0.216797f, 0.222215f, 0.227680f, 0.233193f, 0.238751f, 0.244353f, 0.250000f,\n      0.255689f, 0.261421f, 0.267193f, 0.273005f, 0.278856f, 0.284744f, 0.290670f, 0.296632f,\n      0.302628f, 0.308658f, 0.314721f, 0.320816f, 0.326941f, 0.333097f, 0.339280f, 0.345492f,\n      0.351729f, 0.357992f, 0.364280f, 0.370590f, 0.376923f, 0.383277f, 0.389651f, 0.396044f,\n      0.402455f, 0.408882f, 0.415325f, 0.421783f, 0.428254f, 0.434737f, 0.441231f, 0.447736f,\n      0.454249f, 0.460770f, 0.467298f, 0.473832f, 0.480370f, 0.486912f, 0.493455f, 0.500000f,\n      0.506545f, 0.513088f, 0.519630f, 0.526168f, 0.532702f, 0.539230f, 0.545751f, 0.552264f,\n      0.558769f, 0.565263f, 0.571746f, 0.578217f, 0.584675f, 0.591118f, 0.597545f, 0.603956f,\n      0.610349f, 0.616723f, 0.623077f, 0.629410f, 0.635720f, 0.642008f, 0.648271f, 0.654508f,\n      0.660720f, 0.666903f, 0.673059f, 0.679184f, 0.685279f, 0.691342f, 0.697372f, 0.703368f,\n      0.709330f, 0.715256f, 0.721144f, 0.726995f, 0.732807f, 0.738579f, 0.744311f, 0.750000f,\n      0.755647f, 0.761249f, 0.766807f, 0.772320f, 0.777785f, 0.783203f, 0.788573f, 0.793893f,\n      0.799162f, 0.804381f, 0.809547f, 0.814660f, 0.819720f, 0.824724f, 0.829673f, 0.834565f,\n      0.839400f, 0.844177f, 0.848895f, 0.853553f, 0.858151f, 0.862687f, 0.867161f, 0.871572f,\n      0.875920f, 0.880203f, 0.884421f, 0.888573f, 0.892658f, 0.896677f, 0.900627f, 0.904508f,\n      0.908321f, 0.912063f, 0.915735f, 0.919335f, 0.922864f, 0.926320f, 0.929703f, 0.933013f,\n      0.936248f, 0.939409f, 0.942494f, 0.945503f, 0.948436f, 0.951293f, 0.954072f, 0.956773f,\n      0.959396f, 0.961940f, 0.964405f, 0.966790f, 0.969096f, 0.971321f, 0.973465f, 0.975528f,\n      0.977510f, 0.979410f, 0.981228f, 0.982963f, 0.984615f, 0.986185f, 0.987671f, 0.989074f,\n      0.990393f, 0.991627f, 0.992778f, 0.993844f, 0.994826f, 0.995722f, 0.996534f, 0.997261f,\n      0.997902f, 0.998459f, 0.998929f, 0.999315f, 0.999615f, 0.999829f, 0.999957f, 1.000000f,\n};\n\nstatic const int tbands[NB_TBANDS+1] = {\n       2,  4,  6,  8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120\n};\n\nstatic const int extra_bands[NB_TOT_BANDS+1] = {\n      1, 2,  4,  6,  8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120, 160, 200\n};\n\n/*static const float tweight[NB_TBANDS+1] = {\n      .3, .4, .5, .6, .7, .8, .9, 1., 1., 1., 1., 1., 1., 1., .8, .7, .6, .5\n};*/\n\n#define NB_TONAL_SKIP_BANDS 9\n\n#define cA 0.43157974f\n#define cB 0.67848403f\n#define cC 0.08595542f\n#define cE ((float)M_PI/2)\nstatic OPUS_INLINE float fast_atan2f(float y, float x) {\n   float x2, y2;\n   /* Should avoid underflow on the values we'll get */\n   if (ABS16(x)+ABS16(y)<1e-9f)\n   {\n      x*=1e12f;\n      y*=1e12f;\n   }\n   x2 = x*x;\n   y2 = y*y;\n   if(x2<y2){\n      float den = (y2 + cB*x2) * (y2 + cC*x2);\n      if (den!=0)\n         return -x*y*(y2 + cA*x2) / den + (y<0 ? -cE : cE);\n      else\n         return (y<0 ? -cE : cE);\n   }else{\n      float den = (x2 + cB*y2) * (x2 + cC*y2);\n      if (den!=0)\n         return  x*y*(x2 + cA*y2) / den + (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);\n      else\n         return (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);\n   }\n}\n\nvoid tonality_analysis_init(TonalityAnalysisState *tonal)\n{\n  /* Initialize reusable fields. */\n  tonal->arch = opus_select_arch();\n  /* Clear remaining fields. */\n  tonality_analysis_reset(tonal);\n}\n\nvoid tonality_analysis_reset(TonalityAnalysisState *tonal)\n{\n  /* Clear non-reusable fields. */\n  char *start = (char*)&tonal->TONALITY_ANALYSIS_RESET_START;\n  OPUS_CLEAR(start, sizeof(TonalityAnalysisState) - (start - (char*)tonal));\n}\n\nvoid tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len)\n{\n   int pos;\n   int curr_lookahead;\n   float psum;\n   int i;\n\n   pos = tonal->read_pos;\n   curr_lookahead = tonal->write_pos-tonal->read_pos;\n   if (curr_lookahead<0)\n      curr_lookahead += DETECT_SIZE;\n\n   if (len > 480 && pos != tonal->write_pos)\n   {\n      pos++;\n      if (pos==DETECT_SIZE)\n         pos=0;\n   }\n   if (pos == tonal->write_pos)\n      pos--;\n   if (pos<0)\n      pos = DETECT_SIZE-1;\n   OPUS_COPY(info_out, &tonal->info[pos], 1);\n   tonal->read_subframe += len/120;\n   while (tonal->read_subframe>=4)\n   {\n      tonal->read_subframe -= 4;\n      tonal->read_pos++;\n   }\n   if (tonal->read_pos>=DETECT_SIZE)\n      tonal->read_pos-=DETECT_SIZE;\n\n   /* Compensate for the delay in the features themselves.\n      FIXME: Need a better estimate the 10 I just made up */\n   curr_lookahead = IMAX(curr_lookahead-10, 0);\n\n   psum=0;\n   /* Summing the probability of transition patterns that involve music at\n      time (DETECT_SIZE-curr_lookahead-1) */\n   for (i=0;i<DETECT_SIZE-curr_lookahead;i++)\n      psum += tonal->pmusic[i];\n   for (;i<DETECT_SIZE;i++)\n      psum += tonal->pspeech[i];\n   psum = psum*tonal->music_confidence + (1-psum)*tonal->speech_confidence;\n   /*printf(\"%f %f %f\\n\", psum, info_out->music_prob, info_out->tonality);*/\n\n   info_out->music_prob = psum;\n}\n\nstatic void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix)\n{\n    int i, b;\n    const kiss_fft_state *kfft;\n    VARDECL(kiss_fft_cpx, in);\n    VARDECL(kiss_fft_cpx, out);\n    int N = 480, N2=240;\n    float * OPUS_RESTRICT A = tonal->angle;\n    float * OPUS_RESTRICT dA = tonal->d_angle;\n    float * OPUS_RESTRICT d2A = tonal->d2_angle;\n    VARDECL(float, tonality);\n    VARDECL(float, noisiness);\n    float band_tonality[NB_TBANDS];\n    float logE[NB_TBANDS];\n    float BFCC[8];\n    float features[25];\n    float frame_tonality;\n    float max_frame_tonality;\n    /*float tw_sum=0;*/\n    float frame_noisiness;\n    const float pi4 = (float)(M_PI*M_PI*M_PI*M_PI);\n    float slope=0;\n    float frame_stationarity;\n    float relativeE;\n    float frame_probs[2];\n    float alpha, alphaE, alphaE2;\n    float frame_loudness;\n    float bandwidth_mask;\n    int bandwidth=0;\n    float maxE = 0;\n    float noise_floor;\n    int remaining;\n    AnalysisInfo *info;\n    SAVE_STACK;\n\n    tonal->last_transition++;\n    alpha = 1.f/IMIN(20, 1+tonal->count);\n    alphaE = 1.f/IMIN(50, 1+tonal->count);\n    alphaE2 = 1.f/IMIN(1000, 1+tonal->count);\n\n    if (tonal->count<4)\n       tonal->music_prob = .5;\n    kfft = celt_mode->mdct.kfft[0];\n    if (tonal->count==0)\n       tonal->mem_fill = 240;\n    downmix(x, &tonal->inmem[tonal->mem_fill], IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, c1, c2, C);\n    if (tonal->mem_fill+len < ANALYSIS_BUF_SIZE)\n    {\n       tonal->mem_fill += len;\n       /* Don't have enough to update the analysis */\n       RESTORE_STACK;\n       return;\n    }\n    info = &tonal->info[tonal->write_pos++];\n    if (tonal->write_pos>=DETECT_SIZE)\n       tonal->write_pos-=DETECT_SIZE;\n\n    ALLOC(in, 480, kiss_fft_cpx);\n    ALLOC(out, 480, kiss_fft_cpx);\n    ALLOC(tonality, 240, float);\n    ALLOC(noisiness, 240, float);\n    for (i=0;i<N2;i++)\n    {\n       float w = analysis_window[i];\n       in[i].r = (kiss_fft_scalar)(w*tonal->inmem[i]);\n       in[i].i = (kiss_fft_scalar)(w*tonal->inmem[N2+i]);\n       in[N-i-1].r = (kiss_fft_scalar)(w*tonal->inmem[N-i-1]);\n       in[N-i-1].i = (kiss_fft_scalar)(w*tonal->inmem[N+N2-i-1]);\n    }\n    OPUS_MOVE(tonal->inmem, tonal->inmem+ANALYSIS_BUF_SIZE-240, 240);\n    remaining = len - (ANALYSIS_BUF_SIZE-tonal->mem_fill);\n    downmix(x, &tonal->inmem[240], remaining, offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C);\n    tonal->mem_fill = 240 + remaining;\n    opus_fft(kfft, in, out, tonal->arch);\n#ifndef FIXED_POINT\n    /* If there's any NaN on the input, the entire output will be NaN, so we only need to check one value. */\n    if (celt_isnan(out[0].r))\n    {\n       info->valid = 0;\n       RESTORE_STACK;\n       return;\n    }\n#endif\n\n    for (i=1;i<N2;i++)\n    {\n       float X1r, X2r, X1i, X2i;\n       float angle, d_angle, d2_angle;\n       float angle2, d_angle2, d2_angle2;\n       float mod1, mod2, avg_mod;\n       X1r = (float)out[i].r+out[N-i].r;\n       X1i = (float)out[i].i-out[N-i].i;\n       X2r = (float)out[i].i+out[N-i].i;\n       X2i = (float)out[N-i].r-out[i].r;\n\n       angle = (float)(.5f/M_PI)*fast_atan2f(X1i, X1r);\n       d_angle = angle - A[i];\n       d2_angle = d_angle - dA[i];\n\n       angle2 = (float)(.5f/M_PI)*fast_atan2f(X2i, X2r);\n       d_angle2 = angle2 - angle;\n       d2_angle2 = d_angle2 - d_angle;\n\n       mod1 = d2_angle - (float)floor(.5+d2_angle);\n       noisiness[i] = ABS16(mod1);\n       mod1 *= mod1;\n       mod1 *= mod1;\n\n       mod2 = d2_angle2 - (float)floor(.5+d2_angle2);\n       noisiness[i] += ABS16(mod2);\n       mod2 *= mod2;\n       mod2 *= mod2;\n\n       avg_mod = .25f*(d2A[i]+2.f*mod1+mod2);\n       tonality[i] = 1.f/(1.f+40.f*16.f*pi4*avg_mod)-.015f;\n\n       A[i] = angle2;\n       dA[i] = d_angle2;\n       d2A[i] = mod2;\n    }\n\n    frame_tonality = 0;\n    max_frame_tonality = 0;\n    /*tw_sum = 0;*/\n    info->activity = 0;\n    frame_noisiness = 0;\n    frame_stationarity = 0;\n    if (!tonal->count)\n    {\n       for (b=0;b<NB_TBANDS;b++)\n       {\n          tonal->lowE[b] = 1e10;\n          tonal->highE[b] = -1e10;\n       }\n    }\n    relativeE = 0;\n    frame_loudness = 0;\n    for (b=0;b<NB_TBANDS;b++)\n    {\n       float E=0, tE=0, nE=0;\n       float L1, L2;\n       float stationarity;\n       for (i=tbands[b];i<tbands[b+1];i++)\n       {\n          float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r\n                     + out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;\n#ifdef FIXED_POINT\n          /* FIXME: It's probably best to change the BFCC filter initial state instead */\n          binE *= 5.55e-17f;\n#endif\n          E += binE;\n          tE += binE*tonality[i];\n          nE += binE*2.f*(.5f-noisiness[i]);\n       }\n#ifndef FIXED_POINT\n       /* Check for extreme band energies that could cause NaNs later. */\n       if (!(E<1e9f) || celt_isnan(E))\n       {\n          info->valid = 0;\n          RESTORE_STACK;\n          return;\n       }\n#endif\n\n       tonal->E[tonal->E_count][b] = E;\n       frame_noisiness += nE/(1e-15f+E);\n\n       frame_loudness += (float)sqrt(E+1e-10f);\n       logE[b] = (float)log(E+1e-10f);\n       tonal->lowE[b] = MIN32(logE[b], tonal->lowE[b]+.01f);\n       tonal->highE[b] = MAX32(logE[b], tonal->highE[b]-.1f);\n       if (tonal->highE[b] < tonal->lowE[b]+1.f)\n       {\n          tonal->highE[b]+=.5f;\n          tonal->lowE[b]-=.5f;\n       }\n       relativeE += (logE[b]-tonal->lowE[b])/(1e-15f+tonal->highE[b]-tonal->lowE[b]);\n\n       L1=L2=0;\n       for (i=0;i<NB_FRAMES;i++)\n       {\n          L1 += (float)sqrt(tonal->E[i][b]);\n          L2 += tonal->E[i][b];\n       }\n\n       stationarity = MIN16(0.99f,L1/(float)sqrt(1e-15+NB_FRAMES*L2));\n       stationarity *= stationarity;\n       stationarity *= stationarity;\n       frame_stationarity += stationarity;\n       /*band_tonality[b] = tE/(1e-15+E)*/;\n       band_tonality[b] = MAX16(tE/(1e-15f+E), stationarity*tonal->prev_band_tonality[b]);\n#if 0\n       if (b>=NB_TONAL_SKIP_BANDS)\n       {\n          frame_tonality += tweight[b]*band_tonality[b];\n          tw_sum += tweight[b];\n       }\n#else\n       frame_tonality += band_tonality[b];\n       if (b>=NB_TBANDS-NB_TONAL_SKIP_BANDS)\n          frame_tonality -= band_tonality[b-NB_TBANDS+NB_TONAL_SKIP_BANDS];\n#endif\n       max_frame_tonality = MAX16(max_frame_tonality, (1.f+.03f*(b-NB_TBANDS))*frame_tonality);\n       slope += band_tonality[b]*(b-8);\n       /*printf(\"%f %f \", band_tonality[b], stationarity);*/\n       tonal->prev_band_tonality[b] = band_tonality[b];\n    }\n\n    bandwidth_mask = 0;\n    bandwidth = 0;\n    maxE = 0;\n    noise_floor = 5.7e-4f/(1<<(IMAX(0,lsb_depth-8)));\n#ifdef FIXED_POINT\n    noise_floor *= 1<<(15+SIG_SHIFT);\n#endif\n    noise_floor *= noise_floor;\n    for (b=0;b<NB_TOT_BANDS;b++)\n    {\n       float E=0;\n       int band_start, band_end;\n       /* Keep a margin of 300 Hz for aliasing */\n       band_start = extra_bands[b];\n       band_end = extra_bands[b+1];\n       for (i=band_start;i<band_end;i++)\n       {\n          float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r\n                     + out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;\n          E += binE;\n       }\n       maxE = MAX32(maxE, E);\n       tonal->meanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E);\n       E = MAX32(E, tonal->meanE[b]);\n       /* Use a simple follower with 13 dB/Bark slope for spreading function */\n       bandwidth_mask = MAX32(.05f*bandwidth_mask, E);\n       /* Consider the band \"active\" only if all these conditions are met:\n          1) less than 10 dB below the simple follower\n          2) less than 90 dB below the peak band (maximal masking possible considering\n             both the ATH and the loudness-dependent slope of the spreading function)\n          3) above the PCM quantization noise floor\n       */\n       if (E>.1*bandwidth_mask && E*1e9f > maxE && E > noise_floor*(band_end-band_start))\n          bandwidth = b;\n    }\n    if (tonal->count<=2)\n       bandwidth = 20;\n    frame_loudness = 20*(float)log10(frame_loudness);\n    tonal->Etracker = MAX32(tonal->Etracker-.03f, frame_loudness);\n    tonal->lowECount *= (1-alphaE);\n    if (frame_loudness < tonal->Etracker-30)\n       tonal->lowECount += alphaE;\n\n    for (i=0;i<8;i++)\n    {\n       float sum=0;\n       for (b=0;b<16;b++)\n          sum += dct_table[i*16+b]*logE[b];\n       BFCC[i] = sum;\n    }\n\n    frame_stationarity /= NB_TBANDS;\n    relativeE /= NB_TBANDS;\n    if (tonal->count<10)\n       relativeE = .5;\n    frame_noisiness /= NB_TBANDS;\n#if 1\n    info->activity = frame_noisiness + (1-frame_noisiness)*relativeE;\n#else\n    info->activity = .5*(1+frame_noisiness-frame_stationarity);\n#endif\n    frame_tonality = (max_frame_tonality/(NB_TBANDS-NB_TONAL_SKIP_BANDS));\n    frame_tonality = MAX16(frame_tonality, tonal->prev_tonality*.8f);\n    tonal->prev_tonality = frame_tonality;\n\n    slope /= 8*8;\n    info->tonality_slope = slope;\n\n    tonal->E_count = (tonal->E_count+1)%NB_FRAMES;\n    tonal->count++;\n    info->tonality = frame_tonality;\n\n    for (i=0;i<4;i++)\n       features[i] = -0.12299f*(BFCC[i]+tonal->mem[i+24]) + 0.49195f*(tonal->mem[i]+tonal->mem[i+16]) + 0.69693f*tonal->mem[i+8] - 1.4349f*tonal->cmean[i];\n\n    for (i=0;i<4;i++)\n       tonal->cmean[i] = (1-alpha)*tonal->cmean[i] + alpha*BFCC[i];\n\n    for (i=0;i<4;i++)\n        features[4+i] = 0.63246f*(BFCC[i]-tonal->mem[i+24]) + 0.31623f*(tonal->mem[i]-tonal->mem[i+16]);\n    for (i=0;i<3;i++)\n        features[8+i] = 0.53452f*(BFCC[i]+tonal->mem[i+24]) - 0.26726f*(tonal->mem[i]+tonal->mem[i+16]) -0.53452f*tonal->mem[i+8];\n\n    if (tonal->count > 5)\n    {\n       for (i=0;i<9;i++)\n          tonal->std[i] = (1-alpha)*tonal->std[i] + alpha*features[i]*features[i];\n    }\n\n    for (i=0;i<8;i++)\n    {\n       tonal->mem[i+24] = tonal->mem[i+16];\n       tonal->mem[i+16] = tonal->mem[i+8];\n       tonal->mem[i+8] = tonal->mem[i];\n       tonal->mem[i] = BFCC[i];\n    }\n    for (i=0;i<9;i++)\n       features[11+i] = (float)sqrt(tonal->std[i]);\n    features[20] = info->tonality;\n    features[21] = info->activity;\n    features[22] = frame_stationarity;\n    features[23] = info->tonality_slope;\n    features[24] = tonal->lowECount;\n\n#ifndef DISABLE_FLOAT_API\n    mlp_process(&net, features, frame_probs);\n    frame_probs[0] = .5f*(frame_probs[0]+1);\n    /* Curve fitting between the MLP probability and the actual probability */\n    frame_probs[0] = .01f + 1.21f*frame_probs[0]*frame_probs[0] - .23f*(float)pow(frame_probs[0], 10);\n    /* Probability of active audio (as opposed to silence) */\n    frame_probs[1] = .5f*frame_probs[1]+.5f;\n    /* Consider that silence has a 50-50 probability. */\n    frame_probs[0] = frame_probs[1]*frame_probs[0] + (1-frame_probs[1])*.5f;\n\n    /*printf(\"%f %f \", frame_probs[0], frame_probs[1]);*/\n    {\n       /* Probability of state transition */\n       float tau;\n       /* Represents independence of the MLP probabilities, where\n          beta=1 means fully independent. */\n       float beta;\n       /* Denormalized probability of speech (p0) and music (p1) after update */\n       float p0, p1;\n       /* Probabilities for \"all speech\" and \"all music\" */\n       float s0, m0;\n       /* Probability sum for renormalisation */\n       float psum;\n       /* Instantaneous probability of speech and music, with beta pre-applied. */\n       float speech0;\n       float music0;\n\n       /* One transition every 3 minutes of active audio */\n       tau = .00005f*frame_probs[1];\n       beta = .05f;\n       if (1) {\n          /* Adapt beta based on how \"unexpected\" the new prob is */\n          float p, q;\n          p = MAX16(.05f,MIN16(.95f,frame_probs[0]));\n          q = MAX16(.05f,MIN16(.95f,tonal->music_prob));\n          beta = .01f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p));\n       }\n       /* p0 and p1 are the probabilities of speech and music at this frame\n          using only information from previous frame and applying the\n          state transition model */\n       p0 = (1-tonal->music_prob)*(1-tau) +    tonal->music_prob *tau;\n       p1 =    tonal->music_prob *(1-tau) + (1-tonal->music_prob)*tau;\n       /* We apply the current probability with exponent beta to work around\n          the fact that the probability estimates aren't independent. */\n       p0 *= (float)pow(1-frame_probs[0], beta);\n       p1 *= (float)pow(frame_probs[0], beta);\n       /* Normalise the probabilities to get the Marokv probability of music. */\n       tonal->music_prob = p1/(p0+p1);\n       info->music_prob = tonal->music_prob;\n\n       /* This chunk of code deals with delayed decision. */\n       psum=1e-20f;\n       /* Instantaneous probability of speech and music, with beta pre-applied. */\n       speech0 = (float)pow(1-frame_probs[0], beta);\n       music0  = (float)pow(frame_probs[0], beta);\n       if (tonal->count==1)\n       {\n          tonal->pspeech[0]=.5;\n          tonal->pmusic [0]=.5;\n       }\n       /* Updated probability of having only speech (s0) or only music (m0),\n          before considering the new observation. */\n       s0 = tonal->pspeech[0] + tonal->pspeech[1];\n       m0 = tonal->pmusic [0] + tonal->pmusic [1];\n       /* Updates s0 and m0 with instantaneous probability. */\n       tonal->pspeech[0] = s0*(1-tau)*speech0;\n       tonal->pmusic [0] = m0*(1-tau)*music0;\n       /* Propagate the transition probabilities */\n       for (i=1;i<DETECT_SIZE-1;i++)\n       {\n          tonal->pspeech[i] = tonal->pspeech[i+1]*speech0;\n          tonal->pmusic [i] = tonal->pmusic [i+1]*music0;\n       }\n       /* Probability that the latest frame is speech, when all the previous ones were music. */\n       tonal->pspeech[DETECT_SIZE-1] = m0*tau*speech0;\n       /* Probability that the latest frame is music, when all the previous ones were speech. */\n       tonal->pmusic [DETECT_SIZE-1] = s0*tau*music0;\n\n       /* Renormalise probabilities to 1 */\n       for (i=0;i<DETECT_SIZE;i++)\n          psum += tonal->pspeech[i] + tonal->pmusic[i];\n       psum = 1.f/psum;\n       for (i=0;i<DETECT_SIZE;i++)\n       {\n          tonal->pspeech[i] *= psum;\n          tonal->pmusic [i] *= psum;\n       }\n       psum = tonal->pmusic[0];\n       for (i=1;i<DETECT_SIZE;i++)\n          psum += tonal->pspeech[i];\n\n       /* Estimate our confidence in the speech/music decisions */\n       if (frame_probs[1]>.75)\n       {\n          if (tonal->music_prob>.9)\n          {\n             float adapt;\n             adapt = 1.f/(++tonal->music_confidence_count);\n             tonal->music_confidence_count = IMIN(tonal->music_confidence_count, 500);\n             tonal->music_confidence += adapt*MAX16(-.2f,frame_probs[0]-tonal->music_confidence);\n          }\n          if (tonal->music_prob<.1)\n          {\n             float adapt;\n             adapt = 1.f/(++tonal->speech_confidence_count);\n             tonal->speech_confidence_count = IMIN(tonal->speech_confidence_count, 500);\n             tonal->speech_confidence += adapt*MIN16(.2f,frame_probs[0]-tonal->speech_confidence);\n          }\n       } else {\n          if (tonal->music_confidence_count==0)\n             tonal->music_confidence = .9f;\n          if (tonal->speech_confidence_count==0)\n             tonal->speech_confidence = .1f;\n       }\n    }\n    if (tonal->last_music != (tonal->music_prob>.5f))\n       tonal->last_transition=0;\n    tonal->last_music = tonal->music_prob>.5f;\n#else\n    info->music_prob = 0;\n#endif\n    /*for (i=0;i<25;i++)\n       printf(\"%f \", features[i]);\n    printf(\"\\n\");*/\n\n    info->bandwidth = bandwidth;\n    /*printf(\"%d %d\\n\", info->bandwidth, info->opus_bandwidth);*/\n    info->noisiness = frame_noisiness;\n    info->valid = 1;\n    RESTORE_STACK;\n}\n\nvoid run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm,\n                 int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs,\n                 int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info)\n{\n   int offset;\n   int pcm_len;\n\n   if (analysis_pcm != NULL)\n   {\n      /* Avoid overflow/wrap-around of the analysis buffer */\n      analysis_frame_size = IMIN((DETECT_SIZE-5)*Fs/100, analysis_frame_size);\n\n      pcm_len = analysis_frame_size - analysis->analysis_offset;\n      offset = analysis->analysis_offset;\n      do {\n         tonality_analysis(analysis, celt_mode, analysis_pcm, IMIN(480, pcm_len), offset, c1, c2, C, lsb_depth, downmix);\n         offset += 480;\n         pcm_len -= 480;\n      } while (pcm_len>0);\n      analysis->analysis_offset = analysis_frame_size;\n\n      analysis->analysis_offset -= frame_size;\n   }\n\n   analysis_info->valid = 0;\n   tonality_get_info(analysis, analysis_info, frame_size);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/analysis.h",
    "content": "/* Copyright (c) 2011 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef ANALYSIS_H\n#define ANALYSIS_H\n\n#include \"celt.h\"\n#include \"opus_private.h\"\n\n#define NB_FRAMES 8\n#define NB_TBANDS 18\n#define NB_TOT_BANDS 21\n#define ANALYSIS_BUF_SIZE 720 /* 15 ms at 48 kHz */\n\n#define DETECT_SIZE 200\n\ntypedef struct {\n   int arch;\n#define TONALITY_ANALYSIS_RESET_START angle\n   float angle[240];\n   float d_angle[240];\n   float d2_angle[240];\n   opus_val32 inmem[ANALYSIS_BUF_SIZE];\n   int   mem_fill;                      /* number of usable samples in the buffer */\n   float prev_band_tonality[NB_TBANDS];\n   float prev_tonality;\n   float E[NB_FRAMES][NB_TBANDS];\n   float lowE[NB_TBANDS];\n   float highE[NB_TBANDS];\n   float meanE[NB_TOT_BANDS];\n   float mem[32];\n   float cmean[8];\n   float std[9];\n   float music_prob;\n   float Etracker;\n   float lowECount;\n   int E_count;\n   int last_music;\n   int last_transition;\n   int count;\n   float subframe_mem[3];\n   int analysis_offset;\n   /** Probability of having speech for time i to DETECT_SIZE-1 (and music before).\n       pspeech[0] is the probability that all frames in the window are speech. */\n   float pspeech[DETECT_SIZE];\n   /** Probability of having music for time i to DETECT_SIZE-1 (and speech before).\n       pmusic[0] is the probability that all frames in the window are music. */\n   float pmusic[DETECT_SIZE];\n   float speech_confidence;\n   float music_confidence;\n   int speech_confidence_count;\n   int music_confidence_count;\n   int write_pos;\n   int read_pos;\n   int read_subframe;\n   AnalysisInfo info[DETECT_SIZE];\n} TonalityAnalysisState;\n\n/** Initialize a TonalityAnalysisState struct.\n *\n * This performs some possibly slow initialization steps which should\n * not be repeated every analysis step. No allocated memory is retained\n * by the state struct, so no cleanup call is required.\n */\nvoid tonality_analysis_init(TonalityAnalysisState *analysis);\n\n/** Reset a TonalityAnalysisState stuct.\n *\n * Call this when there's a discontinuity in the data.\n */\nvoid tonality_analysis_reset(TonalityAnalysisState *analysis);\n\nvoid tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len);\n\nvoid run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm,\n                 int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs,\n                 int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info);\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/mlp.c",
    "content": "/* Copyright (c) 2008-2011 Octasic Inc.\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"opus_types.h\"\n#include \"opus_defines.h\"\n\n#include <math.h>\n#include \"mlp.h\"\n#include \"arch.h\"\n#include \"tansig_table.h\"\n#define MAX_NEURONS 100\n\n#if 0\nstatic OPUS_INLINE opus_val16 tansig_approx(opus_val32 _x) /* Q19 */\n{\n    int i;\n    opus_val16 xx; /* Q11 */\n    /*double x, y;*/\n    opus_val16 dy, yy; /* Q14 */\n    /*x = 1.9073e-06*_x;*/\n    if (_x>=QCONST32(8,19))\n        return QCONST32(1.,14);\n    if (_x<=-QCONST32(8,19))\n        return -QCONST32(1.,14);\n    xx = EXTRACT16(SHR32(_x, 8));\n    /*i = lrint(25*x);*/\n    i = SHR32(ADD32(1024,MULT16_16(25, xx)),11);\n    /*x -= .04*i;*/\n    xx -= EXTRACT16(SHR32(MULT16_16(20972,i),8));\n    /*x = xx*(1./2048);*/\n    /*y = tansig_table[250+i];*/\n    yy = tansig_table[250+i];\n    /*y = yy*(1./16384);*/\n    dy = 16384-MULT16_16_Q14(yy,yy);\n    yy = yy + MULT16_16_Q14(MULT16_16_Q11(xx,dy),(16384 - MULT16_16_Q11(yy,xx)));\n    return yy;\n}\n#else\n/*extern const float tansig_table[501];*/\nstatic OPUS_INLINE float tansig_approx(float x)\n{\n    int i;\n    float y, dy;\n    float sign=1;\n    /* Tests are reversed to catch NaNs */\n    if (!(x<8))\n        return 1;\n    if (!(x>-8))\n        return -1;\n#ifndef FIXED_POINT\n    /* Another check in case of -ffast-math */\n    if (celt_isnan(x))\n       return 0;\n#endif\n    if (x<0)\n    {\n       x=-x;\n       sign=-1;\n    }\n    i = (int)floor(.5f+25*x);\n    x -= .04f*i;\n    y = tansig_table[i];\n    dy = 1-y*y;\n    y = y + x*dy*(1 - y*x);\n    return sign*y;\n}\n#endif\n\n#if 0\nvoid mlp_process(const MLP *m, const opus_val16 *in, opus_val16 *out)\n{\n    int j;\n    opus_val16 hidden[MAX_NEURONS];\n    const opus_val16 *W = m->weights;\n    /* Copy to tmp_in */\n    for (j=0;j<m->topo[1];j++)\n    {\n        int k;\n        opus_val32 sum = SHL32(EXTEND32(*W++),8);\n        for (k=0;k<m->topo[0];k++)\n            sum = MAC16_16(sum, in[k],*W++);\n        hidden[j] = tansig_approx(sum);\n    }\n    for (j=0;j<m->topo[2];j++)\n    {\n        int k;\n        opus_val32 sum = SHL32(EXTEND32(*W++),14);\n        for (k=0;k<m->topo[1];k++)\n            sum = MAC16_16(sum, hidden[k], *W++);\n        out[j] = tansig_approx(EXTRACT16(PSHR32(sum,17)));\n    }\n}\n#else\nvoid mlp_process(const MLP *m, const float *in, float *out)\n{\n    int j;\n    float hidden[MAX_NEURONS];\n    const float *W = m->weights;\n    /* Copy to tmp_in */\n    for (j=0;j<m->topo[1];j++)\n    {\n        int k;\n        float sum = *W++;\n        for (k=0;k<m->topo[0];k++)\n            sum = sum + in[k]**W++;\n        hidden[j] = tansig_approx(sum);\n    }\n    for (j=0;j<m->topo[2];j++)\n    {\n        int k;\n        float sum = *W++;\n        for (k=0;k<m->topo[1];k++)\n            sum = sum + hidden[k]**W++;\n        out[j] = tansig_approx(sum);\n    }\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/mlp.h",
    "content": "/* Copyright (c) 2008-2011 Octasic Inc.\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _MLP_H_\n#define _MLP_H_\n\n#include \"arch.h\"\n\ntypedef struct {\n    int layers;\n    const int *topo;\n    const float *weights;\n} MLP;\n\nextern const MLP net;\n\nvoid mlp_process(const MLP *m, const float *in, float *out);\n\n#endif /* _MLP_H_ */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/mlp_data.c",
    "content": "/* The contents of this file was automatically generated by mlp_train.c\n   It contains multi-layer perceptron (MLP) weights. */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"mlp.h\"\n\n/* RMS error was 0.138320, seed was 1361535663 */\n\nstatic const float weights[422] = {\n\n/* hidden layer */\n-0.0941125f, -0.302976f, -0.603555f, -0.19393f, -0.185983f,\n-0.601617f, -0.0465317f, -0.114563f, -0.103599f, -0.618938f,\n-0.317859f, -0.169949f, -0.0702885f, 0.148065f, 0.409524f,\n0.548432f, 0.367649f, -0.494393f, 0.764306f, -1.83957f,\n0.170849f, 12.786f, -1.08848f, -1.27284f, -16.2606f,\n24.1773f, -5.57454f, -0.17276f, -0.163388f, -0.224421f,\n-0.0948944f, -0.0728695f, -0.26557f, -0.100283f, -0.0515459f,\n-0.146142f, -0.120674f, -0.180655f, 0.12857f, 0.442138f,\n-0.493735f, 0.167767f, 0.206699f, -0.197567f, 0.417999f,\n1.50364f, -0.773341f, -10.0401f, 0.401872f, 2.97966f,\n15.2165f, -1.88905f, -1.19254f, 0.0285397f, -0.00405139f,\n0.0707565f, 0.00825699f, -0.0927269f, -0.010393f, -0.00428882f,\n-0.00489743f, -0.0709731f, -0.00255992f, 0.0395619f, 0.226424f,\n0.0325231f, 0.162175f, -0.100118f, 0.485789f, 0.12697f,\n0.285937f, 0.0155637f, 0.10546f, 3.05558f, 1.15059f,\n-1.00904f, -1.83088f, 3.31766f, -3.42516f, -0.119135f,\n-0.0405654f, 0.00690068f, 0.0179877f, -0.0382487f, 0.00597941f,\n-0.0183611f, 0.00190395f, -0.144322f, -0.0435671f, 0.000990594f,\n0.221087f, 0.142405f, 0.484066f, 0.404395f, 0.511955f,\n-0.237255f, 0.241742f, 0.35045f, -0.699428f, 10.3993f,\n2.6507f, -2.43459f, -4.18838f, 1.05928f, 1.71067f,\n0.00667811f, -0.0721335f, -0.0397346f, 0.0362704f, -0.11496f,\n-0.0235776f, 0.0082161f, -0.0141741f, -0.0329699f, -0.0354253f,\n0.00277404f, -0.290654f, -1.14767f, -0.319157f, -0.686544f,\n0.36897f, 0.478899f, 0.182579f, -0.411069f, 0.881104f,\n-4.60683f, 1.4697f, 0.335845f, -1.81905f, -30.1699f,\n5.55225f, 0.0019508f, -0.123576f, -0.0727332f, -0.0641597f,\n-0.0534458f, -0.108166f, -0.0937368f, -0.0697883f, -0.0275475f,\n-0.192309f, -0.110074f, 0.285375f, -0.405597f, 0.0926724f,\n-0.287881f, -0.851193f, -0.099493f, -0.233764f, -1.2852f,\n1.13611f, 3.12168f, -0.0699f, -1.86216f, 2.65292f,\n-7.31036f, 2.44776f, -0.00111802f, -0.0632786f, -0.0376296f,\n-0.149851f, 0.142963f, 0.184368f, 0.123433f, 0.0756158f,\n0.117312f, 0.0933395f, 0.0692163f, 0.0842592f, 0.0704683f,\n0.0589963f, 0.0942205f, -0.448862f, 0.0262677f, 0.270352f,\n-0.262317f, 0.172586f, 2.00227f, -0.159216f, 0.038422f,\n10.2073f, 4.15536f, -2.3407f, -0.0550265f, 0.00964792f,\n-0.141336f, 0.0274501f, 0.0343921f, -0.0487428f, 0.0950172f,\n-0.00775017f, -0.0372492f, -0.00548121f, -0.0663695f, 0.0960506f,\n-0.200008f, -0.0412827f, 0.58728f, 0.0515787f, 0.337254f,\n0.855024f, 0.668371f, -0.114904f, -3.62962f, -0.467477f,\n-0.215472f, 2.61537f, 0.406117f, -1.36373f, 0.0425394f,\n0.12208f, 0.0934502f, 0.123055f, 0.0340935f, -0.142466f,\n0.035037f, -0.0490666f, 0.0733208f, 0.0576672f, 0.123984f,\n-0.0517194f, -0.253018f, 0.590565f, 0.145849f, 0.315185f,\n0.221534f, -0.149081f, 0.216161f, -0.349575f, 24.5664f,\n-0.994196f, 0.614289f, -18.7905f, -2.83277f, -0.716801f,\n-0.347201f, 0.479515f, -0.246027f, 0.0758683f, 0.137293f,\n-0.17781f, 0.118751f, -0.00108329f, -0.237334f, 0.355732f,\n-0.12991f, -0.0547627f, -0.318576f, -0.325524f, 0.180494f,\n-0.0625604f, 0.141219f, 0.344064f, 0.37658f, -0.591772f,\n5.8427f, -0.38075f, 0.221894f, -1.41934f, -1.87943e+06f,\n1.34114f, 0.0283355f, -0.0447856f, -0.0211466f, -0.0256927f,\n0.0139618f, 0.0207934f, -0.0107666f, 0.0110969f, 0.0586069f,\n-0.0253545f, -0.0328433f, 0.11872f, -0.216943f, 0.145748f,\n0.119808f, -0.0915211f, -0.120647f, -0.0787719f, -0.143644f,\n-0.595116f, -1.152f, -1.25335f, -1.17092f, 4.34023f,\n-975268.f, -1.37033f, -0.0401123f, 0.210602f, -0.136656f,\n0.135962f, -0.0523293f, 0.0444604f, 0.0143928f, 0.00412666f,\n-0.0193003f, 0.218452f, -0.110204f, -2.02563f, 0.918238f,\n-2.45362f, 1.19542f, -0.061362f, -1.92243f, 0.308111f,\n0.49764f, 0.912356f, 0.209272f, -2.34525f, 2.19326f,\n-6.47121f, 1.69771f, -0.725123f, 0.0118929f, 0.0377944f,\n0.0554003f, 0.0226452f, -0.0704421f, -0.0300309f, 0.0122978f,\n-0.0041782f, -0.0686612f, 0.0313115f, 0.039111f, 0.364111f,\n-0.0945548f, 0.0229876f, -0.17414f, 0.329795f, 0.114714f,\n0.30022f, 0.106997f, 0.132355f, 5.79932f, 0.908058f,\n-0.905324f, -3.3561f, 0.190647f, 0.184211f, -0.673648f,\n0.231807f, -0.0586222f, 0.230752f, -0.438277f, 0.245857f,\n-0.17215f, 0.0876383f, -0.720512f, 0.162515f, 0.0170571f,\n0.101781f, 0.388477f, 1.32931f, 1.08548f, -0.936301f,\n-2.36958f, -6.71988f, -3.44376f, 2.13818f, 14.2318f,\n4.91459f, -3.09052f, -9.69191f, -0.768234f, 1.79604f,\n0.0549653f, 0.163399f, 0.0797025f, 0.0343933f, -0.0555876f,\n-0.00505673f, 0.0187258f, 0.0326628f, 0.0231486f, 0.15573f,\n0.0476223f, -0.254824f, 1.60155f, -0.801221f, 2.55496f,\n0.737629f, -1.36249f, -0.695463f, -2.44301f, -1.73188f,\n3.95279f, 1.89068f, 0.486087f, -11.3343f, 3.9416e+06f,\n\n/* output layer */\n-0.381439f, 0.12115f, -0.906927f, 2.93878f, 1.6388f,\n0.882811f, 0.874344f, 1.21726f, -0.874545f, 0.321706f,\n0.785055f, 0.946558f, -0.575066f, -3.46553f, 0.884905f,\n0.0924047f, -9.90712f, 0.391338f, 0.160103f, -2.04954f,\n4.1455f, 0.0684029f, -0.144761f, -0.285282f, 0.379244f,\n-1.1584f, -0.0277241f, -9.85f, -4.82386f, 3.71333f,\n3.87308f, 3.52558f};\n\nstatic const int topo[3] = {25, 15, 2};\n\nconst MLP net = {\n    3,\n    topo,\n    weights\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/opus.c",
    "content": "/* Copyright (c) 2011 Xiph.Org Foundation, Skype Limited\n   Written by Jean-Marc Valin and Koen Vos */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"opus.h\"\n#include \"opus_private.h\"\n\n#ifndef DISABLE_FLOAT_API\nOPUS_EXPORT void opus_pcm_soft_clip(float *_x, int N, int C, float *declip_mem)\n{\n   int c;\n   int i;\n   float *x;\n\n   if (C<1 || N<1 || !_x || !declip_mem) return;\n\n   /* First thing: saturate everything to +/- 2 which is the highest level our\n      non-linearity can handle. At the point where the signal reaches +/-2,\n      the derivative will be zero anyway, so this doesn't introduce any\n      discontinuity in the derivative. */\n   for (i=0;i<N*C;i++)\n      _x[i] = MAX16(-2.f, MIN16(2.f, _x[i]));\n   for (c=0;c<C;c++)\n   {\n      float a;\n      float x0;\n      int curr;\n\n      x = _x+c;\n      a = declip_mem[c];\n      /* Continue applying the non-linearity from the previous frame to avoid\n         any discontinuity. */\n      for (i=0;i<N;i++)\n      {\n         if (x[i*C]*a>=0)\n            break;\n         x[i*C] = x[i*C]+a*x[i*C]*x[i*C];\n      }\n\n      curr=0;\n      x0 = x[0];\n      while(1)\n      {\n         int start, end;\n         float maxval;\n         int special=0;\n         int peak_pos;\n         for (i=curr;i<N;i++)\n         {\n            if (x[i*C]>1 || x[i*C]<-1)\n               break;\n         }\n         if (i==N)\n         {\n            a=0;\n            break;\n         }\n         peak_pos = i;\n         start=end=i;\n         maxval=ABS16(x[i*C]);\n         /* Look for first zero crossing before clipping */\n         while (start>0 && x[i*C]*x[(start-1)*C]>=0)\n            start--;\n         /* Look for first zero crossing after clipping */\n         while (end<N && x[i*C]*x[end*C]>=0)\n         {\n            /* Look for other peaks until the next zero-crossing. */\n            if (ABS16(x[end*C])>maxval)\n            {\n               maxval = ABS16(x[end*C]);\n               peak_pos = end;\n            }\n            end++;\n         }\n         /* Detect the special case where we clip before the first zero crossing */\n         special = (start==0 && x[i*C]*x[0]>=0);\n\n         /* Compute a such that maxval + a*maxval^2 = 1 */\n         a=(maxval-1)/(maxval*maxval);\n         if (x[i*C]>0)\n            a = -a;\n         /* Apply soft clipping */\n         for (i=start;i<end;i++)\n            x[i*C] = x[i*C]+a*x[i*C]*x[i*C];\n\n         if (special && peak_pos>=2)\n         {\n            /* Add a linear ramp from the first sample to the signal peak.\n               This avoids a discontinuity at the beginning of the frame. */\n            float delta;\n            float offset = x0-x[0];\n            delta = offset / peak_pos;\n            for (i=curr;i<peak_pos;i++)\n            {\n               offset -= delta;\n               x[i*C] += offset;\n               x[i*C] = MAX16(-1.f, MIN16(1.f, x[i*C]));\n            }\n         }\n         curr = end;\n         if (curr==N)\n            break;\n      }\n      declip_mem[c] = a;\n   }\n}\n#endif\n\nint encode_size(int size, unsigned char *data)\n{\n   if (size < 252)\n   {\n      data[0] = size;\n      return 1;\n   } else {\n      data[0] = 252+(size&0x3);\n      data[1] = (size-(int)data[0])>>2;\n      return 2;\n   }\n}\n\nstatic int parse_size(const unsigned char *data, opus_int32 len, opus_int16 *size)\n{\n   if (len<1)\n   {\n      *size = -1;\n      return -1;\n   } else if (data[0]<252)\n   {\n      *size = data[0];\n      return 1;\n   } else if (len<2)\n   {\n      *size = -1;\n      return -1;\n   } else {\n      *size = 4*data[1] + data[0];\n      return 2;\n   }\n}\n\nint opus_packet_get_samples_per_frame(const unsigned char *data,\n      opus_int32 Fs)\n{\n   int audiosize;\n   if (data[0]&0x80)\n   {\n      audiosize = ((data[0]>>3)&0x3);\n      audiosize = (Fs<<audiosize)/400;\n   } else if ((data[0]&0x60) == 0x60)\n   {\n      audiosize = (data[0]&0x08) ? Fs/50 : Fs/100;\n   } else {\n      audiosize = ((data[0]>>3)&0x3);\n      if (audiosize == 3)\n         audiosize = Fs*60/1000;\n      else\n         audiosize = (Fs<<audiosize)/100;\n   }\n   return audiosize;\n}\n\nint opus_packet_parse_impl(const unsigned char *data, opus_int32 len,\n      int self_delimited, unsigned char *out_toc,\n      const unsigned char *frames[48], opus_int16 size[48],\n      int *payload_offset, opus_int32 *packet_offset)\n{\n   int i, bytes;\n   int count;\n   int cbr;\n   unsigned char ch, toc;\n   int framesize;\n   opus_int32 last_size;\n   opus_int32 pad = 0;\n   const unsigned char *data0 = data;\n\n   if (size==NULL)\n      return OPUS_BAD_ARG;\n\n   framesize = opus_packet_get_samples_per_frame(data, 48000);\n\n   cbr = 0;\n   toc = *data++;\n   len--;\n   last_size = len;\n   switch (toc&0x3)\n   {\n   /* One frame */\n   case 0:\n      count=1;\n      break;\n   /* Two CBR frames */\n   case 1:\n      count=2;\n      cbr = 1;\n      if (!self_delimited)\n      {\n         if (len&0x1)\n            return OPUS_INVALID_PACKET;\n         last_size = len/2;\n         /* If last_size doesn't fit in size[0], we'll catch it later */\n         size[0] = (opus_int16)last_size;\n      }\n      break;\n   /* Two VBR frames */\n   case 2:\n      count = 2;\n      bytes = parse_size(data, len, size);\n      len -= bytes;\n      if (size[0]<0 || size[0] > len)\n         return OPUS_INVALID_PACKET;\n      data += bytes;\n      last_size = len-size[0];\n      break;\n   /* Multiple CBR/VBR frames (from 0 to 120 ms) */\n   default: /*case 3:*/\n      if (len<1)\n         return OPUS_INVALID_PACKET;\n      /* Number of frames encoded in bits 0 to 5 */\n      ch = *data++;\n      count = ch&0x3F;\n      if (count <= 0 || framesize*count > 5760)\n         return OPUS_INVALID_PACKET;\n      len--;\n      /* Padding flag is bit 6 */\n      if (ch&0x40)\n      {\n         int p;\n         do {\n            int tmp;\n            if (len<=0)\n               return OPUS_INVALID_PACKET;\n            p = *data++;\n            len--;\n            tmp = p==255 ? 254: p;\n            len -= tmp;\n            pad += tmp;\n         } while (p==255);\n      }\n      if (len<0)\n         return OPUS_INVALID_PACKET;\n      /* VBR flag is bit 7 */\n      cbr = !(ch&0x80);\n      if (!cbr)\n      {\n         /* VBR case */\n         last_size = len;\n         for (i=0;i<count-1;i++)\n         {\n            bytes = parse_size(data, len, size+i);\n            len -= bytes;\n            if (size[i]<0 || size[i] > len)\n               return OPUS_INVALID_PACKET;\n            data += bytes;\n            last_size -= bytes+size[i];\n         }\n         if (last_size<0)\n            return OPUS_INVALID_PACKET;\n      } else if (!self_delimited)\n      {\n         /* CBR case */\n         last_size = len/count;\n         if (last_size*count!=len)\n            return OPUS_INVALID_PACKET;\n         for (i=0;i<count-1;i++)\n            size[i] = (opus_int16)last_size;\n      }\n      break;\n   }\n   /* Self-delimited framing has an extra size for the last frame. */\n   if (self_delimited)\n   {\n      bytes = parse_size(data, len, size+count-1);\n      len -= bytes;\n      if (size[count-1]<0 || size[count-1] > len)\n         return OPUS_INVALID_PACKET;\n      data += bytes;\n      /* For CBR packets, apply the size to all the frames. */\n      if (cbr)\n      {\n         if (size[count-1]*count > len)\n            return OPUS_INVALID_PACKET;\n         for (i=0;i<count-1;i++)\n            size[i] = size[count-1];\n      } else if (bytes+size[count-1] > last_size)\n         return OPUS_INVALID_PACKET;\n   } else\n   {\n      /* Because it's not encoded explicitly, it's possible the size of the\n         last packet (or all the packets, for the CBR case) is larger than\n         1275. Reject them here.*/\n      if (last_size > 1275)\n         return OPUS_INVALID_PACKET;\n      size[count-1] = (opus_int16)last_size;\n   }\n\n   if (payload_offset)\n      *payload_offset = (int)(data-data0);\n\n   for (i=0;i<count;i++)\n   {\n      if (frames)\n         frames[i] = data;\n      data += size[i];\n   }\n\n   if (packet_offset)\n      *packet_offset = pad+(opus_int32)(data-data0);\n\n   if (out_toc)\n      *out_toc = toc;\n\n   return count;\n}\n\nint opus_packet_parse(const unsigned char *data, opus_int32 len,\n      unsigned char *out_toc, const unsigned char *frames[48],\n      opus_int16 size[48], int *payload_offset)\n{\n   return opus_packet_parse_impl(data, len, 0, out_toc,\n                                 frames, size, payload_offset, NULL);\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/opus_compare.c",
    "content": "/* Copyright (c) 2011-2012 Xiph.Org Foundation, Mozilla Corporation\n   Written by Jean-Marc Valin and Timothy B. Terriberry */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <math.h>\n#include <string.h>\n\n#define OPUS_PI (3.14159265F)\n\n#define OPUS_COSF(_x)        ((float)cos(_x))\n#define OPUS_SINF(_x)        ((float)sin(_x))\n\nstatic void *check_alloc(void *_ptr){\n  if(_ptr==NULL){\n    fprintf(stderr,\"Out of memory.\\n\");\n    exit(EXIT_FAILURE);\n  }\n  return _ptr;\n}\n\nstatic void *opus_malloc(size_t _size){\n  return check_alloc(malloc(_size));\n}\n\nstatic void *opus_realloc(void *_ptr,size_t _size){\n  return check_alloc(realloc(_ptr,_size));\n}\n\nstatic size_t read_pcm16(float **_samples,FILE *_fin,int _nchannels){\n  unsigned char  buf[1024];\n  float         *samples;\n  size_t         nsamples;\n  size_t         csamples;\n  size_t         xi;\n  size_t         nread;\n  samples=NULL;\n  nsamples=csamples=0;\n  for(;;){\n    nread=fread(buf,2*_nchannels,1024/(2*_nchannels),_fin);\n    if(nread<=0)break;\n    if(nsamples+nread>csamples){\n      do csamples=csamples<<1|1;\n      while(nsamples+nread>csamples);\n      samples=(float *)opus_realloc(samples,\n       _nchannels*csamples*sizeof(*samples));\n    }\n    for(xi=0;xi<nread;xi++){\n      int ci;\n      for(ci=0;ci<_nchannels;ci++){\n        int s;\n        s=buf[2*(xi*_nchannels+ci)+1]<<8|buf[2*(xi*_nchannels+ci)];\n        s=((s&0xFFFF)^0x8000)-0x8000;\n        samples[(nsamples+xi)*_nchannels+ci]=s;\n      }\n    }\n    nsamples+=nread;\n  }\n  *_samples=(float *)opus_realloc(samples,\n   _nchannels*nsamples*sizeof(*samples));\n  return nsamples;\n}\n\nstatic void band_energy(float *_out,float *_ps,const int *_bands,int _nbands,\n const float *_in,int _nchannels,size_t _nframes,int _window_sz,\n int _step,int _downsample){\n  float *window;\n  float *x;\n  float *c;\n  float *s;\n  size_t xi;\n  int    xj;\n  int    ps_sz;\n  window=(float *)opus_malloc((3+_nchannels)*_window_sz*sizeof(*window));\n  c=window+_window_sz;\n  s=c+_window_sz;\n  x=s+_window_sz;\n  ps_sz=_window_sz/2;\n  for(xj=0;xj<_window_sz;xj++){\n    window[xj]=0.5F-0.5F*OPUS_COSF((2*OPUS_PI/(_window_sz-1))*xj);\n  }\n  for(xj=0;xj<_window_sz;xj++){\n    c[xj]=OPUS_COSF((2*OPUS_PI/_window_sz)*xj);\n  }\n  for(xj=0;xj<_window_sz;xj++){\n    s[xj]=OPUS_SINF((2*OPUS_PI/_window_sz)*xj);\n  }\n  for(xi=0;xi<_nframes;xi++){\n    int ci;\n    int xk;\n    int bi;\n    for(ci=0;ci<_nchannels;ci++){\n      for(xk=0;xk<_window_sz;xk++){\n        x[ci*_window_sz+xk]=window[xk]*_in[(xi*_step+xk)*_nchannels+ci];\n      }\n    }\n    for(bi=xj=0;bi<_nbands;bi++){\n      float p[2]={0};\n      for(;xj<_bands[bi+1];xj++){\n        for(ci=0;ci<_nchannels;ci++){\n          float re;\n          float im;\n          int   ti;\n          ti=0;\n          re=im=0;\n          for(xk=0;xk<_window_sz;xk++){\n            re+=c[ti]*x[ci*_window_sz+xk];\n            im-=s[ti]*x[ci*_window_sz+xk];\n            ti+=xj;\n            if(ti>=_window_sz)ti-=_window_sz;\n          }\n          re*=_downsample;\n          im*=_downsample;\n          _ps[(xi*ps_sz+xj)*_nchannels+ci]=re*re+im*im+100000;\n          p[ci]+=_ps[(xi*ps_sz+xj)*_nchannels+ci];\n        }\n      }\n      if(_out){\n        _out[(xi*_nbands+bi)*_nchannels]=p[0]/(_bands[bi+1]-_bands[bi]);\n        if(_nchannels==2){\n          _out[(xi*_nbands+bi)*_nchannels+1]=p[1]/(_bands[bi+1]-_bands[bi]);\n        }\n      }\n    }\n  }\n  free(window);\n}\n\n#define NBANDS (21)\n#define NFREQS (240)\n\n/*Bands on which we compute the pseudo-NMR (Bark-derived\n  CELT bands).*/\nstatic const int BANDS[NBANDS+1]={\n  0,2,4,6,8,10,12,14,16,20,24,28,32,40,48,56,68,80,96,120,156,200\n};\n\n#define TEST_WIN_SIZE (480)\n#define TEST_WIN_STEP (120)\n\nint main(int _argc,const char **_argv){\n  FILE    *fin1;\n  FILE    *fin2;\n  float   *x;\n  float   *y;\n  float   *xb;\n  float   *X;\n  float   *Y;\n  double    err;\n  float    Q;\n  size_t   xlength;\n  size_t   ylength;\n  size_t   nframes;\n  size_t   xi;\n  int      ci;\n  int      xj;\n  int      bi;\n  int      nchannels;\n  unsigned rate;\n  int      downsample;\n  int      ybands;\n  int      yfreqs;\n  int      max_compare;\n  if(_argc<3||_argc>6){\n    fprintf(stderr,\"Usage: %s [-s] [-r rate2] <file1.sw> <file2.sw>\\n\",\n     _argv[0]);\n    return EXIT_FAILURE;\n  }\n  nchannels=1;\n  if(strcmp(_argv[1],\"-s\")==0){\n    nchannels=2;\n    _argv++;\n  }\n  rate=48000;\n  ybands=NBANDS;\n  yfreqs=NFREQS;\n  downsample=1;\n  if(strcmp(_argv[1],\"-r\")==0){\n    rate=atoi(_argv[2]);\n    if(rate!=8000&&rate!=12000&&rate!=16000&&rate!=24000&&rate!=48000){\n      fprintf(stderr,\n       \"Sampling rate must be 8000, 12000, 16000, 24000, or 48000\\n\");\n      return EXIT_FAILURE;\n    }\n    downsample=48000/rate;\n    switch(rate){\n      case  8000:ybands=13;break;\n      case 12000:ybands=15;break;\n      case 16000:ybands=17;break;\n      case 24000:ybands=19;break;\n    }\n    yfreqs=NFREQS/downsample;\n    _argv+=2;\n  }\n  fin1=fopen(_argv[1],\"rb\");\n  if(fin1==NULL){\n    fprintf(stderr,\"Error opening '%s'.\\n\",_argv[1]);\n    return EXIT_FAILURE;\n  }\n  fin2=fopen(_argv[2],\"rb\");\n  if(fin2==NULL){\n    fprintf(stderr,\"Error opening '%s'.\\n\",_argv[2]);\n    fclose(fin1);\n    return EXIT_FAILURE;\n  }\n  /*Read in the data and allocate scratch space.*/\n  xlength=read_pcm16(&x,fin1,2);\n  if(nchannels==1){\n    for(xi=0;xi<xlength;xi++)x[xi]=.5*(x[2*xi]+x[2*xi+1]);\n  }\n  fclose(fin1);\n  ylength=read_pcm16(&y,fin2,nchannels);\n  fclose(fin2);\n  if(xlength!=ylength*downsample){\n    fprintf(stderr,\"Sample counts do not match (%lu!=%lu).\\n\",\n     (unsigned long)xlength,(unsigned long)ylength*downsample);\n    return EXIT_FAILURE;\n  }\n  if(xlength<TEST_WIN_SIZE){\n    fprintf(stderr,\"Insufficient sample data (%lu<%i).\\n\",\n     (unsigned long)xlength,TEST_WIN_SIZE);\n    return EXIT_FAILURE;\n  }\n  nframes=(xlength-TEST_WIN_SIZE+TEST_WIN_STEP)/TEST_WIN_STEP;\n  xb=(float *)opus_malloc(nframes*NBANDS*nchannels*sizeof(*xb));\n  X=(float *)opus_malloc(nframes*NFREQS*nchannels*sizeof(*X));\n  Y=(float *)opus_malloc(nframes*yfreqs*nchannels*sizeof(*Y));\n  /*Compute the per-band spectral energy of the original signal\n     and the error.*/\n  band_energy(xb,X,BANDS,NBANDS,x,nchannels,nframes,\n   TEST_WIN_SIZE,TEST_WIN_STEP,1);\n  free(x);\n  band_energy(NULL,Y,BANDS,ybands,y,nchannels,nframes,\n   TEST_WIN_SIZE/downsample,TEST_WIN_STEP/downsample,downsample);\n  free(y);\n  for(xi=0;xi<nframes;xi++){\n    /*Frequency masking (low to high): 10 dB/Bark slope.*/\n    for(bi=1;bi<NBANDS;bi++){\n      for(ci=0;ci<nchannels;ci++){\n        xb[(xi*NBANDS+bi)*nchannels+ci]+=\n         0.1F*xb[(xi*NBANDS+bi-1)*nchannels+ci];\n      }\n    }\n    /*Frequency masking (high to low): 15 dB/Bark slope.*/\n    for(bi=NBANDS-1;bi-->0;){\n      for(ci=0;ci<nchannels;ci++){\n        xb[(xi*NBANDS+bi)*nchannels+ci]+=\n         0.03F*xb[(xi*NBANDS+bi+1)*nchannels+ci];\n      }\n    }\n    if(xi>0){\n      /*Temporal masking: -3 dB/2.5ms slope.*/\n      for(bi=0;bi<NBANDS;bi++){\n        for(ci=0;ci<nchannels;ci++){\n          xb[(xi*NBANDS+bi)*nchannels+ci]+=\n           0.5F*xb[((xi-1)*NBANDS+bi)*nchannels+ci];\n        }\n      }\n    }\n    /* Allowing some cross-talk */\n    if(nchannels==2){\n      for(bi=0;bi<NBANDS;bi++){\n        float l,r;\n        l=xb[(xi*NBANDS+bi)*nchannels+0];\n        r=xb[(xi*NBANDS+bi)*nchannels+1];\n        xb[(xi*NBANDS+bi)*nchannels+0]+=0.01F*r;\n        xb[(xi*NBANDS+bi)*nchannels+1]+=0.01F*l;\n      }\n    }\n\n    /* Apply masking */\n    for(bi=0;bi<ybands;bi++){\n      for(xj=BANDS[bi];xj<BANDS[bi+1];xj++){\n        for(ci=0;ci<nchannels;ci++){\n          X[(xi*NFREQS+xj)*nchannels+ci]+=\n           0.1F*xb[(xi*NBANDS+bi)*nchannels+ci];\n          Y[(xi*yfreqs+xj)*nchannels+ci]+=\n           0.1F*xb[(xi*NBANDS+bi)*nchannels+ci];\n        }\n      }\n    }\n  }\n\n  /* Average of consecutive frames to make comparison slightly less sensitive */\n  for(bi=0;bi<ybands;bi++){\n    for(xj=BANDS[bi];xj<BANDS[bi+1];xj++){\n      for(ci=0;ci<nchannels;ci++){\n         float xtmp;\n         float ytmp;\n         xtmp = X[xj*nchannels+ci];\n         ytmp = Y[xj*nchannels+ci];\n         for(xi=1;xi<nframes;xi++){\n           float xtmp2;\n           float ytmp2;\n           xtmp2 = X[(xi*NFREQS+xj)*nchannels+ci];\n           ytmp2 = Y[(xi*yfreqs+xj)*nchannels+ci];\n           X[(xi*NFREQS+xj)*nchannels+ci] += xtmp;\n           Y[(xi*yfreqs+xj)*nchannels+ci] += ytmp;\n           xtmp = xtmp2;\n           ytmp = ytmp2;\n         }\n      }\n    }\n  }\n\n  /*If working at a lower sampling rate, don't take into account the last\n     300 Hz to allow for different transition bands.\n    For 12 kHz, we don't skip anything, because the last band already skips\n     400 Hz.*/\n  if(rate==48000)max_compare=BANDS[NBANDS];\n  else if(rate==12000)max_compare=BANDS[ybands];\n  else max_compare=BANDS[ybands]-3;\n  err=0;\n  for(xi=0;xi<nframes;xi++){\n    double Ef;\n    Ef=0;\n    for(bi=0;bi<ybands;bi++){\n      double Eb;\n      Eb=0;\n      for(xj=BANDS[bi];xj<BANDS[bi+1]&&xj<max_compare;xj++){\n        for(ci=0;ci<nchannels;ci++){\n          float re;\n          float im;\n          re=Y[(xi*yfreqs+xj)*nchannels+ci]/X[(xi*NFREQS+xj)*nchannels+ci];\n          im=re-log(re)-1;\n          /*Make comparison less sensitive around the SILK/CELT cross-over to\n            allow for mode freedom in the filters.*/\n          if(xj>=79&&xj<=81)im*=0.1F;\n          if(xj==80)im*=0.1F;\n          Eb+=im;\n        }\n      }\n      Eb /= (BANDS[bi+1]-BANDS[bi])*nchannels;\n      Ef += Eb*Eb;\n    }\n    /*Using a fixed normalization value means we're willing to accept slightly\n       lower quality for lower sampling rates.*/\n    Ef/=NBANDS;\n    Ef*=Ef;\n    err+=Ef*Ef;\n  }\n  err=pow(err/nframes,1.0/16);\n  Q=100*(1-0.5*log(1+err)/log(1.13));\n  if(Q<0){\n    fprintf(stderr,\"Test vector FAILS\\n\");\n    fprintf(stderr,\"Internal weighted error is %f\\n\",err);\n    return EXIT_FAILURE;\n  }\n  else{\n    fprintf(stderr,\"Test vector PASSES\\n\");\n    fprintf(stderr,\n     \"Opus quality metric: %.1f %% (internal weighted error is %f)\\n\",Q,err);\n    return EXIT_SUCCESS;\n  }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/opus_decoder.c",
    "content": "/* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited\n   Written by Jean-Marc Valin and Koen Vos */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifndef OPUS_BUILD\n# error \"OPUS_BUILD _MUST_ be defined to build Opus. This probably means you need other defines as well, as in a config.h. See the included build files for details.\"\n#endif\n\n#if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__) && !defined(OPUS_WILL_BE_SLOW)\n# pragma message \"You appear to be compiling without optimization, if so opus will be very slow.\"\n#endif\n\n#include <stdarg.h>\n#include \"celt.h\"\n#include \"opus.h\"\n#include \"entdec.h\"\n#include \"modes.h\"\n#include \"API.h\"\n#include \"stack_alloc.h\"\n#include \"float_cast.h\"\n#include \"opus_private.h\"\n#include \"os_support.h\"\n#include \"structs.h\"\n#include \"define.h\"\n#include \"mathops.h\"\n#include \"cpu_support.h\"\n\nstruct OpusDecoder {\n   int          celt_dec_offset;\n   int          silk_dec_offset;\n   int          channels;\n   opus_int32   Fs;          /** Sampling rate (at the API level) */\n   silk_DecControlStruct DecControl;\n   int          decode_gain;\n   int          arch;\n\n   /* Everything beyond this point gets cleared on a reset */\n#define OPUS_DECODER_RESET_START stream_channels\n   int          stream_channels;\n\n   int          bandwidth;\n   int          mode;\n   int          prev_mode;\n   int          frame_size;\n   int          prev_redundancy;\n   int          last_packet_duration;\n#ifndef FIXED_POINT\n   opus_val16   softclip_mem[2];\n#endif\n\n   opus_uint32  rangeFinal;\n};\n\n\nint opus_decoder_get_size(int channels)\n{\n   int silkDecSizeBytes, celtDecSizeBytes;\n   int ret;\n   if (channels<1 || channels > 2)\n      return 0;\n   ret = silk_Get_Decoder_Size( &silkDecSizeBytes );\n   if(ret)\n      return 0;\n   silkDecSizeBytes = align(silkDecSizeBytes);\n   celtDecSizeBytes = celt_decoder_get_size(channels);\n   return align(sizeof(OpusDecoder))+silkDecSizeBytes+celtDecSizeBytes;\n}\n\nint opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)\n{\n   void *silk_dec;\n   CELTDecoder *celt_dec;\n   int ret, silkDecSizeBytes;\n\n   if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)\n    || (channels!=1&&channels!=2))\n      return OPUS_BAD_ARG;\n\n   OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));\n   /* Initialize SILK encoder */\n   ret = silk_Get_Decoder_Size(&silkDecSizeBytes);\n   if (ret)\n      return OPUS_INTERNAL_ERROR;\n\n   silkDecSizeBytes = align(silkDecSizeBytes);\n   st->silk_dec_offset = align(sizeof(OpusDecoder));\n   st->celt_dec_offset = st->silk_dec_offset+silkDecSizeBytes;\n   silk_dec = (char*)st+st->silk_dec_offset;\n   celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);\n   st->stream_channels = st->channels = channels;\n\n   st->Fs = Fs;\n   st->DecControl.API_sampleRate = st->Fs;\n   st->DecControl.nChannelsAPI      = st->channels;\n\n   /* Reset decoder */\n   ret = silk_InitDecoder( silk_dec );\n   if(ret)return OPUS_INTERNAL_ERROR;\n\n   /* Initialize CELT decoder */\n   ret = celt_decoder_init(celt_dec, Fs, channels);\n   if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR;\n\n   celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0));\n\n   st->prev_mode = 0;\n   st->frame_size = Fs/400;\n   st->arch = opus_select_arch();\n   return OPUS_OK;\n}\n\nOpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)\n{\n   int ret;\n   OpusDecoder *st;\n   if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)\n    || (channels!=1&&channels!=2))\n   {\n      if (error)\n         *error = OPUS_BAD_ARG;\n      return NULL;\n   }\n   st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels));\n   if (st == NULL)\n   {\n      if (error)\n         *error = OPUS_ALLOC_FAIL;\n      return NULL;\n   }\n   ret = opus_decoder_init(st, Fs, channels);\n   if (error)\n      *error = ret;\n   if (ret != OPUS_OK)\n   {\n      opus_free(st);\n      st = NULL;\n   }\n   return st;\n}\n\nstatic void smooth_fade(const opus_val16 *in1, const opus_val16 *in2,\n      opus_val16 *out, int overlap, int channels,\n      const opus_val16 *window, opus_int32 Fs)\n{\n   int i, c;\n   int inc = 48000/Fs;\n   for (c=0;c<channels;c++)\n   {\n      for (i=0;i<overlap;i++)\n      {\n         opus_val16 w = MULT16_16_Q15(window[i*inc], window[i*inc]);\n         out[i*channels+c] = SHR32(MAC16_16(MULT16_16(w,in2[i*channels+c]),\n                                   Q15ONE-w, in1[i*channels+c]), 15);\n      }\n   }\n}\n\nstatic int opus_packet_get_mode(const unsigned char *data)\n{\n   int mode;\n   if (data[0]&0x80)\n   {\n      mode = MODE_CELT_ONLY;\n   } else if ((data[0]&0x60) == 0x60)\n   {\n      mode = MODE_HYBRID;\n   } else {\n      mode = MODE_SILK_ONLY;\n   }\n   return mode;\n}\n\nstatic int opus_decode_frame(OpusDecoder *st, const unsigned char *data,\n      opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)\n{\n   void *silk_dec;\n   CELTDecoder *celt_dec;\n   int i, silk_ret=0, celt_ret=0;\n   ec_dec dec;\n   opus_int32 silk_frame_size;\n   int pcm_silk_size;\n   VARDECL(opus_int16, pcm_silk);\n   int pcm_transition_silk_size;\n   VARDECL(opus_val16, pcm_transition_silk);\n   int pcm_transition_celt_size;\n   VARDECL(opus_val16, pcm_transition_celt);\n   opus_val16 *pcm_transition=NULL;\n   int redundant_audio_size;\n   VARDECL(opus_val16, redundant_audio);\n\n   int audiosize;\n   int mode;\n   int transition=0;\n   int start_band;\n   int redundancy=0;\n   int redundancy_bytes = 0;\n   int celt_to_silk=0;\n   int c;\n   int F2_5, F5, F10, F20;\n   const opus_val16 *window;\n   opus_uint32 redundant_rng = 0;\n   int celt_accum;\n   ALLOC_STACK;\n\n   silk_dec = (char*)st+st->silk_dec_offset;\n   celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);\n   F20 = st->Fs/50;\n   F10 = F20>>1;\n   F5 = F10>>1;\n   F2_5 = F5>>1;\n   if (frame_size < F2_5)\n   {\n      RESTORE_STACK;\n      return OPUS_BUFFER_TOO_SMALL;\n   }\n   /* Limit frame_size to avoid excessive stack allocations. */\n   frame_size = IMIN(frame_size, st->Fs/25*3);\n   /* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */\n   if (len<=1)\n   {\n      data = NULL;\n      /* In that case, don't conceal more than what the ToC says */\n      frame_size = IMIN(frame_size, st->frame_size);\n   }\n   if (data != NULL)\n   {\n      audiosize = st->frame_size;\n      mode = st->mode;\n      ec_dec_init(&dec,(unsigned char*)data,len);\n   } else {\n      audiosize = frame_size;\n      mode = st->prev_mode;\n\n      if (mode == 0)\n      {\n         /* If we haven't got any packet yet, all we can do is return zeros */\n         for (i=0;i<audiosize*st->channels;i++)\n            pcm[i] = 0;\n         RESTORE_STACK;\n         return audiosize;\n      }\n\n      /* Avoids trying to run the PLC on sizes other than 2.5 (CELT), 5 (CELT),\n         10, or 20 (e.g. 12.5 or 30 ms). */\n      if (audiosize > F20)\n      {\n         do {\n            int ret = opus_decode_frame(st, NULL, 0, pcm, IMIN(audiosize, F20), 0);\n            if (ret<0)\n            {\n               RESTORE_STACK;\n               return ret;\n            }\n            pcm += ret*st->channels;\n            audiosize -= ret;\n         } while (audiosize > 0);\n         RESTORE_STACK;\n         return frame_size;\n      } else if (audiosize < F20)\n      {\n         if (audiosize > F10)\n            audiosize = F10;\n         else if (mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10)\n            audiosize = F5;\n      }\n   }\n\n   /* In fixed-point, we can tell CELT to do the accumulation on top of the\n      SILK PCM buffer. This saves some stack space. */\n#ifdef FIXED_POINT\n   celt_accum = (mode != MODE_CELT_ONLY) && (frame_size >= F10);\n#else\n   celt_accum = 0;\n#endif\n\n   pcm_transition_silk_size = ALLOC_NONE;\n   pcm_transition_celt_size = ALLOC_NONE;\n   if (data!=NULL && st->prev_mode > 0 && (\n       (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy)\n    || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) )\n      )\n   {\n      transition = 1;\n      /* Decide where to allocate the stack memory for pcm_transition */\n      if (mode == MODE_CELT_ONLY)\n         pcm_transition_celt_size = F5*st->channels;\n      else\n         pcm_transition_silk_size = F5*st->channels;\n   }\n   ALLOC(pcm_transition_celt, pcm_transition_celt_size, opus_val16);\n   if (transition && mode == MODE_CELT_ONLY)\n   {\n      pcm_transition = pcm_transition_celt;\n      opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);\n   }\n   if (audiosize > frame_size)\n   {\n      /*fprintf(stderr, \"PCM buffer too small: %d vs %d (mode = %d)\\n\", audiosize, frame_size, mode);*/\n      RESTORE_STACK;\n      return OPUS_BAD_ARG;\n   } else {\n      frame_size = audiosize;\n   }\n\n   /* Don't allocate any memory when in CELT-only mode */\n   pcm_silk_size = (mode != MODE_CELT_ONLY && !celt_accum) ? IMAX(F10, frame_size)*st->channels : ALLOC_NONE;\n   ALLOC(pcm_silk, pcm_silk_size, opus_int16);\n\n   /* SILK processing */\n   if (mode != MODE_CELT_ONLY)\n   {\n      int lost_flag, decoded_samples;\n      opus_int16 *pcm_ptr;\n#ifdef FIXED_POINT\n      if (celt_accum)\n         pcm_ptr = pcm;\n      else\n#endif\n         pcm_ptr = pcm_silk;\n\n      if (st->prev_mode==MODE_CELT_ONLY)\n         silk_InitDecoder( silk_dec );\n\n      /* The SILK PLC cannot produce frames of less than 10 ms */\n      st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs);\n\n      if (data != NULL)\n      {\n        st->DecControl.nChannelsInternal = st->stream_channels;\n        if( mode == MODE_SILK_ONLY ) {\n           if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) {\n              st->DecControl.internalSampleRate = 8000;\n           } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) {\n              st->DecControl.internalSampleRate = 12000;\n           } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) {\n              st->DecControl.internalSampleRate = 16000;\n           } else {\n              st->DecControl.internalSampleRate = 16000;\n              silk_assert( 0 );\n           }\n        } else {\n           /* Hybrid mode */\n           st->DecControl.internalSampleRate = 16000;\n        }\n     }\n\n     lost_flag = data == NULL ? 1 : 2 * decode_fec;\n     decoded_samples = 0;\n     do {\n        /* Call SILK decoder */\n        int first_frame = decoded_samples == 0;\n        silk_ret = silk_Decode( silk_dec, &st->DecControl,\n                                lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size, st->arch );\n        if( silk_ret ) {\n           if (lost_flag) {\n              /* PLC failure should not be fatal */\n              silk_frame_size = frame_size;\n              for (i=0;i<frame_size*st->channels;i++)\n                 pcm_ptr[i] = 0;\n           } else {\n             RESTORE_STACK;\n             return OPUS_INTERNAL_ERROR;\n           }\n        }\n        pcm_ptr += silk_frame_size * st->channels;\n        decoded_samples += silk_frame_size;\n      } while( decoded_samples < frame_size );\n   }\n\n   start_band = 0;\n   if (!decode_fec && mode != MODE_CELT_ONLY && data != NULL\n    && ec_tell(&dec)+17+20*(st->mode == MODE_HYBRID) <= 8*len)\n   {\n      /* Check if we have a redundant 0-8 kHz band */\n      if (mode == MODE_HYBRID)\n         redundancy = ec_dec_bit_logp(&dec, 12);\n      else\n         redundancy = 1;\n      if (redundancy)\n      {\n         celt_to_silk = ec_dec_bit_logp(&dec, 1);\n         /* redundancy_bytes will be at least two, in the non-hybrid\n            case due to the ec_tell() check above */\n         redundancy_bytes = mode==MODE_HYBRID ?\n               (opus_int32)ec_dec_uint(&dec, 256)+2 :\n               len-((ec_tell(&dec)+7)>>3);\n         len -= redundancy_bytes;\n         /* This is a sanity check. It should never happen for a valid\n            packet, so the exact behaviour is not normative. */\n         if (len*8 < ec_tell(&dec))\n         {\n            len = 0;\n            redundancy_bytes = 0;\n            redundancy = 0;\n         }\n         /* Shrink decoder because of raw bits */\n         dec.storage -= redundancy_bytes;\n      }\n   }\n   if (mode != MODE_CELT_ONLY)\n      start_band = 17;\n\n   {\n      int endband=21;\n\n      switch(st->bandwidth)\n      {\n      case OPUS_BANDWIDTH_NARROWBAND:\n         endband = 13;\n         break;\n      case OPUS_BANDWIDTH_MEDIUMBAND:\n      case OPUS_BANDWIDTH_WIDEBAND:\n         endband = 17;\n         break;\n      case OPUS_BANDWIDTH_SUPERWIDEBAND:\n         endband = 19;\n         break;\n      case OPUS_BANDWIDTH_FULLBAND:\n         endband = 21;\n         break;\n      }\n      celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband));\n      celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels));\n   }\n\n   if (redundancy)\n   {\n      transition = 0;\n      pcm_transition_silk_size=ALLOC_NONE;\n   }\n\n   ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16);\n\n   if (transition && mode != MODE_CELT_ONLY)\n   {\n      pcm_transition = pcm_transition_silk;\n      opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);\n   }\n\n   /* Only allocation memory for redundancy if/when needed */\n   redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE;\n   ALLOC(redundant_audio, redundant_audio_size, opus_val16);\n\n   /* 5 ms redundant frame for CELT->SILK*/\n   if (redundancy && celt_to_silk)\n   {\n      celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));\n      celt_decode_with_ec(celt_dec, data+len, redundancy_bytes,\n                          redundant_audio, F5, NULL, 0);\n      celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));\n   }\n\n   /* MUST be after PLC */\n   celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band));\n\n   if (mode != MODE_SILK_ONLY)\n   {\n      int celt_frame_size = IMIN(F20, frame_size);\n      /* Make sure to discard any previous CELT state */\n      if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy)\n         celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);\n      /* Decode CELT */\n      celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data,\n                                     len, pcm, celt_frame_size, &dec, celt_accum);\n   } else {\n      unsigned char silence[2] = {0xFF, 0xFF};\n      if (!celt_accum)\n      {\n         for (i=0;i<frame_size*st->channels;i++)\n            pcm[i] = 0;\n      }\n      /* For hybrid -> SILK transitions, we let the CELT MDCT\n         do a fade-out by decoding a silence frame */\n      if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) )\n      {\n         celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));\n         celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL, celt_accum);\n      }\n   }\n\n   if (mode != MODE_CELT_ONLY && !celt_accum)\n   {\n#ifdef FIXED_POINT\n      for (i=0;i<frame_size*st->channels;i++)\n         pcm[i] = SAT16(ADD32(pcm[i], pcm_silk[i]));\n#else\n      for (i=0;i<frame_size*st->channels;i++)\n         pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]);\n#endif\n   }\n\n   {\n      const CELTMode *celt_mode;\n      celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode));\n      window = celt_mode->window;\n   }\n\n   /* 5 ms redundant frame for SILK->CELT */\n   if (redundancy && !celt_to_silk)\n   {\n      celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);\n      celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));\n\n      celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0);\n      celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));\n      smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5,\n                  pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);\n   }\n   if (redundancy && celt_to_silk)\n   {\n      for (c=0;c<st->channels;c++)\n      {\n         for (i=0;i<F2_5;i++)\n            pcm[st->channels*i+c] = redundant_audio[st->channels*i+c];\n      }\n      smooth_fade(redundant_audio+st->channels*F2_5, pcm+st->channels*F2_5,\n                  pcm+st->channels*F2_5, F2_5, st->channels, window, st->Fs);\n   }\n   if (transition)\n   {\n      if (audiosize >= F5)\n      {\n         for (i=0;i<st->channels*F2_5;i++)\n            pcm[i] = pcm_transition[i];\n         smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5,\n                     pcm+st->channels*F2_5, F2_5,\n                     st->channels, window, st->Fs);\n      } else {\n         /* Not enough time to do a clean transition, but we do it anyway\n            This will not preserve amplitude perfectly and may introduce\n            a bit of temporal aliasing, but it shouldn't be too bad and\n            that's pretty much the best we can do. In any case, generating this\n            transition it pretty silly in the first place */\n         smooth_fade(pcm_transition, pcm,\n                     pcm, F2_5,\n                     st->channels, window, st->Fs);\n      }\n   }\n\n   if(st->decode_gain)\n   {\n      opus_val32 gain;\n      gain = celt_exp2(MULT16_16_P15(QCONST16(6.48814081e-4f, 25), st->decode_gain));\n      for (i=0;i<frame_size*st->channels;i++)\n      {\n         opus_val32 x;\n         x = MULT16_32_P16(pcm[i],gain);\n         pcm[i] = SATURATE(x, 32767);\n      }\n   }\n\n   if (len <= 1)\n      st->rangeFinal = 0;\n   else\n      st->rangeFinal = dec.rng ^ redundant_rng;\n\n   st->prev_mode = mode;\n   st->prev_redundancy = redundancy && !celt_to_silk;\n\n   if (celt_ret>=0)\n   {\n      if (OPUS_CHECK_ARRAY(pcm, audiosize*st->channels))\n         OPUS_PRINT_INT(audiosize);\n   }\n\n   RESTORE_STACK;\n   return celt_ret < 0 ? celt_ret : audiosize;\n\n}\n\nint opus_decode_native(OpusDecoder *st, const unsigned char *data,\n      opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec,\n      int self_delimited, opus_int32 *packet_offset, int soft_clip)\n{\n   int i, nb_samples;\n   int count, offset;\n   unsigned char toc;\n   int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;\n   /* 48 x 2.5 ms = 120 ms */\n   opus_int16 size[48];\n   if (decode_fec<0 || decode_fec>1)\n      return OPUS_BAD_ARG;\n   /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */\n   if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0)\n      return OPUS_BAD_ARG;\n   if (len==0 || data==NULL)\n   {\n      int pcm_count=0;\n      do {\n         int ret;\n         ret = opus_decode_frame(st, NULL, 0, pcm+pcm_count*st->channels, frame_size-pcm_count, 0);\n         if (ret<0)\n            return ret;\n         pcm_count += ret;\n      } while (pcm_count < frame_size);\n      celt_assert(pcm_count == frame_size);\n      if (OPUS_CHECK_ARRAY(pcm, pcm_count*st->channels))\n         OPUS_PRINT_INT(pcm_count);\n      st->last_packet_duration = pcm_count;\n      return pcm_count;\n   } else if (len<0)\n      return OPUS_BAD_ARG;\n\n   packet_mode = opus_packet_get_mode(data);\n   packet_bandwidth = opus_packet_get_bandwidth(data);\n   packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs);\n   packet_stream_channels = opus_packet_get_nb_channels(data);\n\n   count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,\n                                  size, &offset, packet_offset);\n   if (count<0)\n      return count;\n\n   data += offset;\n\n   if (decode_fec)\n   {\n      int duration_copy;\n      int ret;\n      /* If no FEC can be present, run the PLC (recursive call) */\n      if (frame_size < packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY)\n         return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL, soft_clip);\n      /* Otherwise, run the PLC on everything except the size for which we might have FEC */\n      duration_copy = st->last_packet_duration;\n      if (frame_size-packet_frame_size!=0)\n      {\n         ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL, soft_clip);\n         if (ret<0)\n         {\n            st->last_packet_duration = duration_copy;\n            return ret;\n         }\n         celt_assert(ret==frame_size-packet_frame_size);\n      }\n      /* Complete with FEC */\n      st->mode = packet_mode;\n      st->bandwidth = packet_bandwidth;\n      st->frame_size = packet_frame_size;\n      st->stream_channels = packet_stream_channels;\n      ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-packet_frame_size),\n            packet_frame_size, 1);\n      if (ret<0)\n         return ret;\n      else {\n         if (OPUS_CHECK_ARRAY(pcm, frame_size*st->channels))\n            OPUS_PRINT_INT(frame_size);\n         st->last_packet_duration = frame_size;\n         return frame_size;\n      }\n   }\n\n   if (count*packet_frame_size > frame_size)\n      return OPUS_BUFFER_TOO_SMALL;\n\n   /* Update the state as the last step to avoid updating it on an invalid packet */\n   st->mode = packet_mode;\n   st->bandwidth = packet_bandwidth;\n   st->frame_size = packet_frame_size;\n   st->stream_channels = packet_stream_channels;\n\n   nb_samples=0;\n   for (i=0;i<count;i++)\n   {\n      int ret;\n      ret = opus_decode_frame(st, data, size[i], pcm+nb_samples*st->channels, frame_size-nb_samples, 0);\n      if (ret<0)\n         return ret;\n      celt_assert(ret==packet_frame_size);\n      data += size[i];\n      nb_samples += ret;\n   }\n   st->last_packet_duration = nb_samples;\n   if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels))\n      OPUS_PRINT_INT(nb_samples);\n#ifndef FIXED_POINT\n   if (soft_clip)\n      opus_pcm_soft_clip(pcm, nb_samples, st->channels, st->softclip_mem);\n   else\n      st->softclip_mem[0]=st->softclip_mem[1]=0;\n#endif\n   return nb_samples;\n}\n\n#ifdef FIXED_POINT\n\nint opus_decode(OpusDecoder *st, const unsigned char *data,\n      opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)\n{\n   if(frame_size<=0)\n      return OPUS_BAD_ARG;\n   return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0);\n}\n\n#ifndef DISABLE_FLOAT_API\nint opus_decode_float(OpusDecoder *st, const unsigned char *data,\n      opus_int32 len, float *pcm, int frame_size, int decode_fec)\n{\n   VARDECL(opus_int16, out);\n   int ret, i;\n   int nb_samples;\n   ALLOC_STACK;\n\n   if(frame_size<=0)\n   {\n      RESTORE_STACK;\n      return OPUS_BAD_ARG;\n   }\n   if (data != NULL && len > 0 && !decode_fec)\n   {\n      nb_samples = opus_decoder_get_nb_samples(st, data, len);\n      if (nb_samples>0)\n         frame_size = IMIN(frame_size, nb_samples);\n      else\n         return OPUS_INVALID_PACKET;\n   }\n   ALLOC(out, frame_size*st->channels, opus_int16);\n\n   ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0);\n   if (ret > 0)\n   {\n      for (i=0;i<ret*st->channels;i++)\n         pcm[i] = (1.f/32768.f)*(out[i]);\n   }\n   RESTORE_STACK;\n   return ret;\n}\n#endif\n\n\n#else\nint opus_decode(OpusDecoder *st, const unsigned char *data,\n      opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)\n{\n   VARDECL(float, out);\n   int ret, i;\n   int nb_samples;\n   ALLOC_STACK;\n\n   if(frame_size<=0)\n   {\n      RESTORE_STACK;\n      return OPUS_BAD_ARG;\n   }\n\n   if (data != NULL && len > 0 && !decode_fec)\n   {\n      nb_samples = opus_decoder_get_nb_samples(st, data, len);\n      if (nb_samples>0)\n         frame_size = IMIN(frame_size, nb_samples);\n      else\n         return OPUS_INVALID_PACKET;\n   }\n   ALLOC(out, frame_size*st->channels, float);\n\n   ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1);\n   if (ret > 0)\n   {\n      for (i=0;i<ret*st->channels;i++)\n         pcm[i] = FLOAT2INT16(out[i]);\n   }\n   RESTORE_STACK;\n   return ret;\n}\n\nint opus_decode_float(OpusDecoder *st, const unsigned char *data,\n      opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)\n{\n   if(frame_size<=0)\n      return OPUS_BAD_ARG;\n   return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0);\n}\n\n#endif\n\nint opus_decoder_ctl(OpusDecoder *st, int request, ...)\n{\n   int ret = OPUS_OK;\n   va_list ap;\n   void *silk_dec;\n   CELTDecoder *celt_dec;\n\n   silk_dec = (char*)st+st->silk_dec_offset;\n   celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);\n\n\n   va_start(ap, request);\n\n   switch (request)\n   {\n   case OPUS_GET_BANDWIDTH_REQUEST:\n   {\n      opus_int32 *value = va_arg(ap, opus_int32*);\n      if (!value)\n      {\n         goto bad_arg;\n      }\n      *value = st->bandwidth;\n   }\n   break;\n   case OPUS_GET_FINAL_RANGE_REQUEST:\n   {\n      opus_uint32 *value = va_arg(ap, opus_uint32*);\n      if (!value)\n      {\n         goto bad_arg;\n      }\n      *value = st->rangeFinal;\n   }\n   break;\n   case OPUS_RESET_STATE:\n   {\n      OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START,\n            sizeof(OpusDecoder)-\n            ((char*)&st->OPUS_DECODER_RESET_START - (char*)st));\n\n      celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);\n      silk_InitDecoder( silk_dec );\n      st->stream_channels = st->channels;\n      st->frame_size = st->Fs/400;\n   }\n   break;\n   case OPUS_GET_SAMPLE_RATE_REQUEST:\n   {\n      opus_int32 *value = va_arg(ap, opus_int32*);\n      if (!value)\n      {\n         goto bad_arg;\n      }\n      *value = st->Fs;\n   }\n   break;\n   case OPUS_GET_PITCH_REQUEST:\n   {\n      opus_int32 *value = va_arg(ap, opus_int32*);\n      if (!value)\n      {\n         goto bad_arg;\n      }\n      if (st->prev_mode == MODE_CELT_ONLY)\n         celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value));\n      else\n         *value = st->DecControl.prevPitchLag;\n   }\n   break;\n   case OPUS_GET_GAIN_REQUEST:\n   {\n      opus_int32 *value = va_arg(ap, opus_int32*);\n      if (!value)\n      {\n         goto bad_arg;\n      }\n      *value = st->decode_gain;\n   }\n   break;\n   case OPUS_SET_GAIN_REQUEST:\n   {\n       opus_int32 value = va_arg(ap, opus_int32);\n       if (value<-32768 || value>32767)\n       {\n          goto bad_arg;\n       }\n       st->decode_gain = value;\n   }\n   break;\n   case OPUS_GET_LAST_PACKET_DURATION_REQUEST:\n   {\n      opus_uint32 *value = va_arg(ap, opus_uint32*);\n      if (!value)\n      {\n         goto bad_arg;\n      }\n      *value = st->last_packet_duration;\n   }\n   break;\n   default:\n      /*fprintf(stderr, \"unknown opus_decoder_ctl() request: %d\", request);*/\n      ret = OPUS_UNIMPLEMENTED;\n      break;\n   }\n\n   va_end(ap);\n   return ret;\nbad_arg:\n   va_end(ap);\n   return OPUS_BAD_ARG;\n}\n\nvoid opus_decoder_destroy(OpusDecoder *st)\n{\n   opus_free(st);\n}\n\n\nint opus_packet_get_bandwidth(const unsigned char *data)\n{\n   int bandwidth;\n   if (data[0]&0x80)\n   {\n      bandwidth = OPUS_BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3);\n      if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)\n         bandwidth = OPUS_BANDWIDTH_NARROWBAND;\n   } else if ((data[0]&0x60) == 0x60)\n   {\n      bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND :\n                                   OPUS_BANDWIDTH_SUPERWIDEBAND;\n   } else {\n      bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3);\n   }\n   return bandwidth;\n}\n\nint opus_packet_get_nb_channels(const unsigned char *data)\n{\n   return (data[0]&0x4) ? 2 : 1;\n}\n\nint opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len)\n{\n   int count;\n   if (len<1)\n      return OPUS_BAD_ARG;\n   count = packet[0]&0x3;\n   if (count==0)\n      return 1;\n   else if (count!=3)\n      return 2;\n   else if (len<2)\n      return OPUS_INVALID_PACKET;\n   else\n      return packet[1]&0x3F;\n}\n\nint opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len,\n      opus_int32 Fs)\n{\n   int samples;\n   int count = opus_packet_get_nb_frames(packet, len);\n\n   if (count<0)\n      return count;\n\n   samples = count*opus_packet_get_samples_per_frame(packet, Fs);\n   /* Can't have more than 120 ms */\n   if (samples*25 > Fs*3)\n      return OPUS_INVALID_PACKET;\n   else\n      return samples;\n}\n\nint opus_decoder_get_nb_samples(const OpusDecoder *dec,\n      const unsigned char packet[], opus_int32 len)\n{\n   return opus_packet_get_nb_samples(packet, len, dec->Fs);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/opus_demo.c",
    "content": "/* Copyright (c) 2007-2008 CSIRO\n   Copyright (c) 2007-2009 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <math.h>\n#include <string.h>\n#include \"opus.h\"\n#include \"debug.h\"\n#include \"opus_types.h\"\n#include \"opus_private.h\"\n#include \"opus_multistream.h\"\n\n#define MAX_PACKET 1500\n\nvoid print_usage( char* argv[] )\n{\n    fprintf(stderr, \"Usage: %s [-e] <application> <sampling rate (Hz)> <channels (1/2)> \"\n        \"<bits per second>  [options] <input> <output>\\n\", argv[0]);\n    fprintf(stderr, \"       %s -d <sampling rate (Hz)> <channels (1/2)> \"\n        \"[options] <input> <output>\\n\\n\", argv[0]);\n    fprintf(stderr, \"application: voip | audio | restricted-lowdelay\\n\" );\n    fprintf(stderr, \"options:\\n\" );\n    fprintf(stderr, \"-e                   : only runs the encoder (output the bit-stream)\\n\" );\n    fprintf(stderr, \"-d                   : only runs the decoder (reads the bit-stream as input)\\n\" );\n    fprintf(stderr, \"-cbr                 : enable constant bitrate; default: variable bitrate\\n\" );\n    fprintf(stderr, \"-cvbr                : enable constrained variable bitrate; default: unconstrained\\n\" );\n    fprintf(stderr, \"-variable-duration   : enable frames of variable duration (experts only); default: disabled\\n\" );\n    fprintf(stderr, \"-bandwidth <NB|MB|WB|SWB|FB> : audio bandwidth (from narrowband to fullband); default: sampling rate\\n\" );\n    fprintf(stderr, \"-framesize <2.5|5|10|20|40|60> : frame size in ms; default: 20 \\n\" );\n    fprintf(stderr, \"-max_payload <bytes> : maximum payload size in bytes, default: 1024\\n\" );\n    fprintf(stderr, \"-complexity <comp>   : complexity, 0 (lowest) ... 10 (highest); default: 10\\n\" );\n    fprintf(stderr, \"-inbandfec           : enable SILK inband FEC\\n\" );\n    fprintf(stderr, \"-forcemono           : force mono encoding, even for stereo input\\n\" );\n    fprintf(stderr, \"-dtx                 : enable SILK DTX\\n\" );\n    fprintf(stderr, \"-loss <perc>         : simulate packet loss, in percent (0-100); default: 0\\n\" );\n}\n\nstatic void int_to_char(opus_uint32 i, unsigned char ch[4])\n{\n    ch[0] = i>>24;\n    ch[1] = (i>>16)&0xFF;\n    ch[2] = (i>>8)&0xFF;\n    ch[3] = i&0xFF;\n}\n\nstatic opus_uint32 char_to_int(unsigned char ch[4])\n{\n    return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16)\n         | ((opus_uint32)ch[2]<< 8) |  (opus_uint32)ch[3];\n}\n\nstatic void check_encoder_option(int decode_only, const char *opt)\n{\n   if (decode_only)\n   {\n      fprintf(stderr, \"option %s is only for encoding\\n\", opt);\n      exit(EXIT_FAILURE);\n   }\n}\n\nstatic const int silk8_test[][4] = {\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960,   1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480,   1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 2},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 2},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960,   2},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480,   2}\n};\n\nstatic const int silk12_test[][4] = {\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960,   1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480,   1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 2},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 2},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960,   2},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480,   2}\n};\n\nstatic const int silk16_test[][4] = {\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960,   1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480,   1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 2},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 2},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960,   2},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480,   2}\n};\n\nstatic const int hybrid24_test[][4] = {\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2}\n};\n\nstatic const int hybrid48_test[][4] = {\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},\n      {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}\n};\n\nstatic const int celt_test[][4] = {\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 1},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      960, 1},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    960, 1},\n\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 1},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      480, 1},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    480, 1},\n\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 1},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 1},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      240, 1},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    240, 1},\n\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 1},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 1},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      120, 1},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    120, 1},\n\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      960, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    960, 2},\n\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      480, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    480, 2},\n\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      240, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    240, 2},\n\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      120, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    120, 2},\n\n};\n\nstatic const int celt_hq_test[][4] = {\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 2},\n      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 2},\n};\n\n#if 0 /* This is a hack that replaces the normal encoder/decoder with the multistream version */\n#define OpusEncoder OpusMSEncoder\n#define OpusDecoder OpusMSDecoder\n#define opus_encode opus_multistream_encode\n#define opus_decode opus_multistream_decode\n#define opus_encoder_ctl opus_multistream_encoder_ctl\n#define opus_decoder_ctl opus_multistream_decoder_ctl\n#define opus_encoder_create ms_opus_encoder_create\n#define opus_decoder_create ms_opus_decoder_create\n#define opus_encoder_destroy opus_multistream_encoder_destroy\n#define opus_decoder_destroy opus_multistream_decoder_destroy\n\nstatic OpusEncoder *ms_opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)\n{\n   int streams, coupled_streams;\n   unsigned char mapping[256];\n   return (OpusEncoder *)opus_multistream_surround_encoder_create(Fs, channels, 1, &streams, &coupled_streams, mapping, application, error);\n}\nstatic OpusDecoder *ms_opus_decoder_create(opus_int32 Fs, int channels, int *error)\n{\n   int streams;\n   int coupled_streams;\n   unsigned char mapping[256]={0,1};\n   streams = 1;\n   coupled_streams = channels==2;\n   return (OpusDecoder *)opus_multistream_decoder_create(Fs, channels, streams, coupled_streams, mapping, error);\n}\n#endif\n\nint main(int argc, char *argv[])\n{\n    int err;\n    char *inFile, *outFile;\n    FILE *fin, *fout;\n    OpusEncoder *enc=NULL;\n    OpusDecoder *dec=NULL;\n    int args;\n    int len[2];\n    int frame_size, channels;\n    opus_int32 bitrate_bps=0;\n    unsigned char *data[2];\n    unsigned char *fbytes;\n    opus_int32 sampling_rate;\n    int use_vbr;\n    int max_payload_bytes;\n    int complexity;\n    int use_inbandfec;\n    int use_dtx;\n    int forcechannels;\n    int cvbr = 0;\n    int packet_loss_perc;\n    opus_int32 count=0, count_act=0;\n    int k;\n    opus_int32 skip=0;\n    int stop=0;\n    short *in, *out;\n    int application=OPUS_APPLICATION_AUDIO;\n    double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg;\n    double tot_samples=0;\n    opus_uint64 tot_in, tot_out;\n    int bandwidth=OPUS_AUTO;\n    const char *bandwidth_string;\n    int lost = 0, lost_prev = 1;\n    int toggle = 0;\n    opus_uint32 enc_final_range[2];\n    opus_uint32 dec_final_range;\n    int encode_only=0, decode_only=0;\n    int max_frame_size = 48000*2;\n    int curr_read=0;\n    int sweep_bps = 0;\n    int random_framesize=0, newsize=0, delayed_celt=0;\n    int sweep_max=0, sweep_min=0;\n    int random_fec=0;\n    const int (*mode_list)[4]=NULL;\n    int nb_modes_in_list=0;\n    int curr_mode=0;\n    int curr_mode_count=0;\n    int mode_switch_time = 48000;\n    int nb_encoded=0;\n    int remaining=0;\n    int variable_duration=OPUS_FRAMESIZE_ARG;\n    int delayed_decision=0;\n\n    if (argc < 5 )\n    {\n       print_usage( argv );\n       return EXIT_FAILURE;\n    }\n\n    tot_in=tot_out=0;\n    fprintf(stderr, \"%s\\n\", opus_get_version_string());\n\n    args = 1;\n    if (strcmp(argv[args], \"-e\")==0)\n    {\n        encode_only = 1;\n        args++;\n    } else if (strcmp(argv[args], \"-d\")==0)\n    {\n        decode_only = 1;\n        args++;\n    }\n    if (!decode_only && argc < 7 )\n    {\n       print_usage( argv );\n       return EXIT_FAILURE;\n    }\n\n    if (!decode_only)\n    {\n       if (strcmp(argv[args], \"voip\")==0)\n          application = OPUS_APPLICATION_VOIP;\n       else if (strcmp(argv[args], \"restricted-lowdelay\")==0)\n          application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;\n       else if (strcmp(argv[args], \"audio\")!=0) {\n          fprintf(stderr, \"unknown application: %s\\n\", argv[args]);\n          print_usage(argv);\n          return EXIT_FAILURE;\n       }\n       args++;\n    }\n    sampling_rate = (opus_int32)atol(argv[args]);\n    args++;\n\n    if (sampling_rate != 8000 && sampling_rate != 12000\n     && sampling_rate != 16000 && sampling_rate != 24000\n     && sampling_rate != 48000)\n    {\n        fprintf(stderr, \"Supported sampling rates are 8000, 12000, \"\n                \"16000, 24000 and 48000.\\n\");\n        return EXIT_FAILURE;\n    }\n    frame_size = sampling_rate/50;\n\n    channels = atoi(argv[args]);\n    args++;\n\n    if (channels < 1 || channels > 2)\n    {\n        fprintf(stderr, \"Opus_demo supports only 1 or 2 channels.\\n\");\n        return EXIT_FAILURE;\n    }\n\n    if (!decode_only)\n    {\n       bitrate_bps = (opus_int32)atol(argv[args]);\n       args++;\n    }\n\n    /* defaults: */\n    use_vbr = 1;\n    max_payload_bytes = MAX_PACKET;\n    complexity = 10;\n    use_inbandfec = 0;\n    forcechannels = OPUS_AUTO;\n    use_dtx = 0;\n    packet_loss_perc = 0;\n\n    while( args < argc - 2 ) {\n        /* process command line options */\n        if( strcmp( argv[ args ], \"-cbr\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-cbr\");\n            use_vbr = 0;\n            args++;\n        } else if( strcmp( argv[ args ], \"-bandwidth\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-bandwidth\");\n            if (strcmp(argv[ args + 1 ], \"NB\")==0)\n                bandwidth = OPUS_BANDWIDTH_NARROWBAND;\n            else if (strcmp(argv[ args + 1 ], \"MB\")==0)\n                bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;\n            else if (strcmp(argv[ args + 1 ], \"WB\")==0)\n                bandwidth = OPUS_BANDWIDTH_WIDEBAND;\n            else if (strcmp(argv[ args + 1 ], \"SWB\")==0)\n                bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;\n            else if (strcmp(argv[ args + 1 ], \"FB\")==0)\n                bandwidth = OPUS_BANDWIDTH_FULLBAND;\n            else {\n                fprintf(stderr, \"Unknown bandwidth %s. \"\n                                \"Supported are NB, MB, WB, SWB, FB.\\n\",\n                                argv[ args + 1 ]);\n                return EXIT_FAILURE;\n            }\n            args += 2;\n        } else if( strcmp( argv[ args ], \"-framesize\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-framesize\");\n            if (strcmp(argv[ args + 1 ], \"2.5\")==0)\n                frame_size = sampling_rate/400;\n            else if (strcmp(argv[ args + 1 ], \"5\")==0)\n                frame_size = sampling_rate/200;\n            else if (strcmp(argv[ args + 1 ], \"10\")==0)\n                frame_size = sampling_rate/100;\n            else if (strcmp(argv[ args + 1 ], \"20\")==0)\n                frame_size = sampling_rate/50;\n            else if (strcmp(argv[ args + 1 ], \"40\")==0)\n                frame_size = sampling_rate/25;\n            else if (strcmp(argv[ args + 1 ], \"60\")==0)\n                frame_size = 3*sampling_rate/50;\n            else {\n                fprintf(stderr, \"Unsupported frame size: %s ms. \"\n                                \"Supported are 2.5, 5, 10, 20, 40, 60.\\n\",\n                                argv[ args + 1 ]);\n                return EXIT_FAILURE;\n            }\n            args += 2;\n        } else if( strcmp( argv[ args ], \"-max_payload\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-max_payload\");\n            max_payload_bytes = atoi( argv[ args + 1 ] );\n            args += 2;\n        } else if( strcmp( argv[ args ], \"-complexity\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-complexity\");\n            complexity = atoi( argv[ args + 1 ] );\n            args += 2;\n        } else if( strcmp( argv[ args ], \"-inbandfec\" ) == 0 ) {\n            use_inbandfec = 1;\n            args++;\n        } else if( strcmp( argv[ args ], \"-forcemono\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-forcemono\");\n            forcechannels = 1;\n            args++;\n        } else if( strcmp( argv[ args ], \"-cvbr\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-cvbr\");\n            cvbr = 1;\n            args++;\n        } else if( strcmp( argv[ args ], \"-variable-duration\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-variable-duration\");\n            variable_duration = OPUS_FRAMESIZE_VARIABLE;\n            args++;\n        } else if( strcmp( argv[ args ], \"-delayed-decision\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-delayed-decision\");\n            delayed_decision = 1;\n            args++;\n        } else if( strcmp( argv[ args ], \"-dtx\") == 0 ) {\n            check_encoder_option(decode_only, \"-dtx\");\n            use_dtx = 1;\n            args++;\n        } else if( strcmp( argv[ args ], \"-loss\" ) == 0 ) {\n            packet_loss_perc = atoi( argv[ args + 1 ] );\n            args += 2;\n        } else if( strcmp( argv[ args ], \"-sweep\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-sweep\");\n            sweep_bps = atoi( argv[ args + 1 ] );\n            args += 2;\n        } else if( strcmp( argv[ args ], \"-random_framesize\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-random_framesize\");\n            random_framesize = 1;\n            args++;\n        } else if( strcmp( argv[ args ], \"-sweep_max\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-sweep_max\");\n            sweep_max = atoi( argv[ args + 1 ] );\n            args += 2;\n        } else if( strcmp( argv[ args ], \"-random_fec\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-random_fec\");\n            random_fec = 1;\n            args++;\n        } else if( strcmp( argv[ args ], \"-silk8k_test\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-silk8k_test\");\n            mode_list = silk8_test;\n            nb_modes_in_list = 8;\n            args++;\n        } else if( strcmp( argv[ args ], \"-silk12k_test\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-silk12k_test\");\n            mode_list = silk12_test;\n            nb_modes_in_list = 8;\n            args++;\n        } else if( strcmp( argv[ args ], \"-silk16k_test\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-silk16k_test\");\n            mode_list = silk16_test;\n            nb_modes_in_list = 8;\n            args++;\n        } else if( strcmp( argv[ args ], \"-hybrid24k_test\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-hybrid24k_test\");\n            mode_list = hybrid24_test;\n            nb_modes_in_list = 4;\n            args++;\n        } else if( strcmp( argv[ args ], \"-hybrid48k_test\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-hybrid48k_test\");\n            mode_list = hybrid48_test;\n            nb_modes_in_list = 4;\n            args++;\n        } else if( strcmp( argv[ args ], \"-celt_test\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-celt_test\");\n            mode_list = celt_test;\n            nb_modes_in_list = 32;\n            args++;\n        } else if( strcmp( argv[ args ], \"-celt_hq_test\" ) == 0 ) {\n            check_encoder_option(decode_only, \"-celt_hq_test\");\n            mode_list = celt_hq_test;\n            nb_modes_in_list = 4;\n            args++;\n        } else {\n            printf( \"Error: unrecognized setting: %s\\n\\n\", argv[ args ] );\n            print_usage( argv );\n            return EXIT_FAILURE;\n        }\n    }\n\n    if (sweep_max)\n       sweep_min = bitrate_bps;\n\n    if (max_payload_bytes < 0 || max_payload_bytes > MAX_PACKET)\n    {\n        fprintf (stderr, \"max_payload_bytes must be between 0 and %d\\n\",\n                          MAX_PACKET);\n        return EXIT_FAILURE;\n    }\n\n    inFile = argv[argc-2];\n    fin = fopen(inFile, \"rb\");\n    if (!fin)\n    {\n        fprintf (stderr, \"Could not open input file %s\\n\", argv[argc-2]);\n        return EXIT_FAILURE;\n    }\n    if (mode_list)\n    {\n       int size;\n       fseek(fin, 0, SEEK_END);\n       size = ftell(fin);\n       fprintf(stderr, \"File size is %d bytes\\n\", size);\n       fseek(fin, 0, SEEK_SET);\n       mode_switch_time = size/sizeof(short)/channels/nb_modes_in_list;\n       fprintf(stderr, \"Switching mode every %d samples\\n\", mode_switch_time);\n    }\n\n    outFile = argv[argc-1];\n    fout = fopen(outFile, \"wb+\");\n    if (!fout)\n    {\n        fprintf (stderr, \"Could not open output file %s\\n\", argv[argc-1]);\n        fclose(fin);\n        return EXIT_FAILURE;\n    }\n\n    if (!decode_only)\n    {\n       enc = opus_encoder_create(sampling_rate, channels, application, &err);\n       if (err != OPUS_OK)\n       {\n          fprintf(stderr, \"Cannot create encoder: %s\\n\", opus_strerror(err));\n          fclose(fin);\n          fclose(fout);\n          return EXIT_FAILURE;\n       }\n       opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));\n       opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth));\n       opus_encoder_ctl(enc, OPUS_SET_VBR(use_vbr));\n       opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr));\n       opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));\n       opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(use_inbandfec));\n       opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels));\n       opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx));\n       opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));\n\n       opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));\n       opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16));\n       opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));\n    }\n    if (!encode_only)\n    {\n       dec = opus_decoder_create(sampling_rate, channels, &err);\n       if (err != OPUS_OK)\n       {\n          fprintf(stderr, \"Cannot create decoder: %s\\n\", opus_strerror(err));\n          fclose(fin);\n          fclose(fout);\n          return EXIT_FAILURE;\n       }\n    }\n\n\n    switch(bandwidth)\n    {\n    case OPUS_BANDWIDTH_NARROWBAND:\n         bandwidth_string = \"narrowband\";\n         break;\n    case OPUS_BANDWIDTH_MEDIUMBAND:\n         bandwidth_string = \"mediumband\";\n         break;\n    case OPUS_BANDWIDTH_WIDEBAND:\n         bandwidth_string = \"wideband\";\n         break;\n    case OPUS_BANDWIDTH_SUPERWIDEBAND:\n         bandwidth_string = \"superwideband\";\n         break;\n    case OPUS_BANDWIDTH_FULLBAND:\n         bandwidth_string = \"fullband\";\n         break;\n    case OPUS_AUTO:\n         bandwidth_string = \"auto bandwidth\";\n         break;\n    default:\n         bandwidth_string = \"unknown\";\n         break;\n    }\n\n    if (decode_only)\n       fprintf(stderr, \"Decoding with %ld Hz output (%d channels)\\n\",\n                       (long)sampling_rate, channels);\n    else\n       fprintf(stderr, \"Encoding %ld Hz input at %.3f kb/s \"\n                       \"in %s with %d-sample frames.\\n\",\n                       (long)sampling_rate, bitrate_bps*0.001,\n                       bandwidth_string, frame_size);\n\n    in = (short*)malloc(max_frame_size*channels*sizeof(short));\n    out = (short*)malloc(max_frame_size*channels*sizeof(short));\n    fbytes = (unsigned char*)malloc(max_frame_size*channels*sizeof(short));\n    data[0] = (unsigned char*)calloc(max_payload_bytes,sizeof(char));\n    if ( use_inbandfec ) {\n        data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(char));\n    }\n    if(delayed_decision)\n    {\n       if (variable_duration!=OPUS_FRAMESIZE_VARIABLE)\n       {\n          if (frame_size==sampling_rate/400)\n             variable_duration = OPUS_FRAMESIZE_2_5_MS;\n          else if (frame_size==sampling_rate/200)\n             variable_duration = OPUS_FRAMESIZE_5_MS;\n          else if (frame_size==sampling_rate/100)\n             variable_duration = OPUS_FRAMESIZE_10_MS;\n          else if (frame_size==sampling_rate/50)\n             variable_duration = OPUS_FRAMESIZE_20_MS;\n          else if (frame_size==sampling_rate/25)\n             variable_duration = OPUS_FRAMESIZE_40_MS;\n          else\n             variable_duration = OPUS_FRAMESIZE_60_MS;\n          opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));\n       }\n       frame_size = 2*48000;\n    }\n    while (!stop)\n    {\n        if (delayed_celt)\n        {\n            frame_size = newsize;\n            delayed_celt = 0;\n        } else if (random_framesize && rand()%20==0)\n        {\n            newsize = rand()%6;\n            switch(newsize)\n            {\n            case 0: newsize=sampling_rate/400; break;\n            case 1: newsize=sampling_rate/200; break;\n            case 2: newsize=sampling_rate/100; break;\n            case 3: newsize=sampling_rate/50; break;\n            case 4: newsize=sampling_rate/25; break;\n            case 5: newsize=3*sampling_rate/50; break;\n            }\n            while (newsize < sampling_rate/25 && bitrate_bps-abs(sweep_bps) <= 3*12*sampling_rate/newsize)\n               newsize*=2;\n            if (newsize < sampling_rate/100 && frame_size >= sampling_rate/100)\n            {\n                opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));\n                delayed_celt=1;\n            } else {\n                frame_size = newsize;\n            }\n        }\n        if (random_fec && rand()%30==0)\n        {\n           opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rand()%4==0));\n        }\n        if (decode_only)\n        {\n            unsigned char ch[4];\n            err = fread(ch, 1, 4, fin);\n            if (feof(fin))\n                break;\n            len[toggle] = char_to_int(ch);\n            if (len[toggle]>max_payload_bytes || len[toggle]<0)\n            {\n                fprintf(stderr, \"Invalid payload length: %d\\n\",len[toggle]);\n                break;\n            }\n            err = fread(ch, 1, 4, fin);\n            enc_final_range[toggle] = char_to_int(ch);\n            err = fread(data[toggle], 1, len[toggle], fin);\n            if (err<len[toggle])\n            {\n                fprintf(stderr, \"Ran out of input, \"\n                                \"expecting %d bytes got %d\\n\",\n                                len[toggle],err);\n                break;\n            }\n        } else {\n            int i;\n            if (mode_list!=NULL)\n            {\n                opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(mode_list[curr_mode][1]));\n                opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(mode_list[curr_mode][0]));\n                opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(mode_list[curr_mode][3]));\n                frame_size = mode_list[curr_mode][2];\n            }\n            err = fread(fbytes, sizeof(short)*channels, frame_size-remaining, fin);\n            curr_read = err;\n            tot_in += curr_read;\n            for(i=0;i<curr_read*channels;i++)\n            {\n                opus_int32 s;\n                s=fbytes[2*i+1]<<8|fbytes[2*i];\n                s=((s&0xFFFF)^0x8000)-0x8000;\n                in[i+remaining*channels]=s;\n            }\n            if (curr_read+remaining < frame_size)\n            {\n                for (i=(curr_read+remaining)*channels;i<frame_size*channels;i++)\n                   in[i] = 0;\n                if (encode_only || decode_only)\n                   stop = 1;\n            }\n            len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes);\n            nb_encoded = opus_packet_get_samples_per_frame(data[toggle], sampling_rate)*opus_packet_get_nb_frames(data[toggle], len[toggle]);\n            remaining = frame_size-nb_encoded;\n            for(i=0;i<remaining*channels;i++)\n               in[i] = in[nb_encoded*channels+i];\n            if (sweep_bps!=0)\n            {\n               bitrate_bps += sweep_bps;\n               if (sweep_max)\n               {\n                  if (bitrate_bps > sweep_max)\n                     sweep_bps = -sweep_bps;\n                  else if (bitrate_bps < sweep_min)\n                     sweep_bps = -sweep_bps;\n               }\n               /* safety */\n               if (bitrate_bps<1000)\n                  bitrate_bps = 1000;\n               opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));\n            }\n            opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range[toggle]));\n            if (len[toggle] < 0)\n            {\n                fprintf (stderr, \"opus_encode() returned %d\\n\", len[toggle]);\n                fclose(fin);\n                fclose(fout);\n                return EXIT_FAILURE;\n            }\n            curr_mode_count += frame_size;\n            if (curr_mode_count > mode_switch_time && curr_mode < nb_modes_in_list-1)\n            {\n               curr_mode++;\n               curr_mode_count = 0;\n            }\n        }\n\n#if 0 /* This is for testing the padding code, do not enable by default */\n        if (len[toggle]<1275)\n        {\n           int new_len = len[toggle]+rand()%(max_payload_bytes-len[toggle]);\n           if ((err = opus_packet_pad(data[toggle], len[toggle], new_len)) != OPUS_OK)\n           {\n              fprintf(stderr, \"padding failed: %s\\n\", opus_strerror(err));\n              return EXIT_FAILURE;\n           }\n           len[toggle] = new_len;\n        }\n#endif\n        if (encode_only)\n        {\n            unsigned char int_field[4];\n            int_to_char(len[toggle], int_field);\n            if (fwrite(int_field, 1, 4, fout) != 4) {\n               fprintf(stderr, \"Error writing.\\n\");\n               return EXIT_FAILURE;\n            }\n            int_to_char(enc_final_range[toggle], int_field);\n            if (fwrite(int_field, 1, 4, fout) != 4) {\n               fprintf(stderr, \"Error writing.\\n\");\n               return EXIT_FAILURE;\n            }\n            if (fwrite(data[toggle], 1, len[toggle], fout) != (unsigned)len[toggle]) {\n               fprintf(stderr, \"Error writing.\\n\");\n               return EXIT_FAILURE;\n            }\n            tot_samples += nb_encoded;\n        } else {\n            int output_samples;\n            lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc);\n            if (lost)\n               opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));\n            else\n               output_samples = max_frame_size;\n            if( count >= use_inbandfec ) {\n                /* delay by one packet when using in-band FEC */\n                if( use_inbandfec  ) {\n                    if( lost_prev ) {\n                        /* attempt to decode with in-band FEC from next packet */\n                        opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));\n                        output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 1);\n                    } else {\n                        /* regular decode */\n                        output_samples = max_frame_size;\n                        output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, output_samples, 0);\n                    }\n                } else {\n                    output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 0);\n                }\n                if (output_samples>0)\n                {\n                    if (!decode_only && tot_out + output_samples > tot_in)\n                    {\n                       stop=1;\n                       output_samples  = tot_in-tot_out;\n                    }\n                    if (output_samples>skip) {\n                       int i;\n                       for(i=0;i<(output_samples-skip)*channels;i++)\n                       {\n                          short s;\n                          s=out[i+(skip*channels)];\n                          fbytes[2*i]=s&0xFF;\n                          fbytes[2*i+1]=(s>>8)&0xFF;\n                       }\n                       if (fwrite(fbytes, sizeof(short)*channels, output_samples-skip, fout) != (unsigned)(output_samples-skip)){\n                          fprintf(stderr, \"Error writing.\\n\");\n                          return EXIT_FAILURE;\n                       }\n                       tot_out += output_samples-skip;\n                    }\n                    if (output_samples<skip) skip -= output_samples;\n                    else skip = 0;\n                } else {\n                   fprintf(stderr, \"error decoding frame: %s\\n\",\n                                   opus_strerror(output_samples));\n                }\n                tot_samples += output_samples;\n            }\n        }\n\n        if (!encode_only)\n           opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));\n        /* compare final range encoder rng values of encoder and decoder */\n        if( enc_final_range[toggle^use_inbandfec]!=0  && !encode_only\n         && !lost && !lost_prev\n         && dec_final_range != enc_final_range[toggle^use_inbandfec] ) {\n            fprintf (stderr, \"Error: Range coder state mismatch \"\n                             \"between encoder and decoder \"\n                             \"in frame %ld: 0x%8lx vs 0x%8lx\\n\",\n                         (long)count,\n                         (unsigned long)enc_final_range[toggle^use_inbandfec],\n                         (unsigned long)dec_final_range);\n            fclose(fin);\n            fclose(fout);\n            return EXIT_FAILURE;\n        }\n\n        lost_prev = lost;\n        if( count >= use_inbandfec ) {\n            /* count bits */\n            bits += len[toggle]*8;\n            bits_max = ( len[toggle]*8 > bits_max ) ? len[toggle]*8 : bits_max;\n            bits2 += len[toggle]*len[toggle]*64;\n            if (!decode_only)\n            {\n                nrg = 0.0;\n                for ( k = 0; k < frame_size * channels; k++ ) {\n                    nrg += in[ k ] * (double)in[ k ];\n                }\n                nrg /= frame_size * channels;\n                if( nrg > 1e5 ) {\n                    bits_act += len[toggle]*8;\n                    count_act++;\n                }\n            }\n        }\n        count++;\n        toggle = (toggle + use_inbandfec) & 1;\n    }\n\n    /* Print out bitrate statistics */\n    if(decode_only)\n        frame_size = (int)(tot_samples / count);\n    count -= use_inbandfec;\n    fprintf (stderr, \"average bitrate:             %7.3f kb/s\\n\",\n                     1e-3*bits*sampling_rate/tot_samples);\n    fprintf (stderr, \"maximum bitrate:             %7.3f kb/s\\n\",\n                     1e-3*bits_max*sampling_rate/frame_size);\n    if (!decode_only)\n       fprintf (stderr, \"active bitrate:              %7.3f kb/s\\n\",\n               1e-3*bits_act*sampling_rate/(1e-15+frame_size*(double)count_act));\n    fprintf (stderr, \"bitrate standard deviation:  %7.3f kb/s\\n\",\n            1e-3*sqrt(bits2/count - bits*bits/(count*(double)count))*sampling_rate/frame_size);\n    /* Close any files to which intermediate results were stored */\n    SILK_DEBUG_STORE_CLOSE_FILES\n    silk_TimerSave(\"opus_timing.txt\");\n    opus_encoder_destroy(enc);\n    opus_decoder_destroy(dec);\n    free(data[0]);\n    if (use_inbandfec)\n        free(data[1]);\n    fclose(fin);\n    fclose(fout);\n    free(in);\n    free(out);\n    free(fbytes);\n    return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/opus_encoder.c",
    "content": "/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited\n   Written by Jean-Marc Valin and Koen Vos */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdarg.h>\n#include \"celt.h\"\n#include \"entenc.h\"\n#include \"modes.h\"\n#include \"API.h\"\n#include \"stack_alloc.h\"\n#include \"float_cast.h\"\n#include \"opus.h\"\n#include \"arch.h\"\n#include \"pitch.h\"\n#include \"opus_private.h\"\n#include \"os_support.h\"\n#include \"cpu_support.h\"\n#include \"analysis.h\"\n#include \"mathops.h\"\n#include \"tuning_parameters.h\"\n#ifdef FIXED_POINT\n#include \"fixed/structs_FIX.h\"\n#else\n#include \"float/structs_FLP.h\"\n#endif\n\n#define MAX_ENCODER_BUFFER 480\n\ntypedef struct {\n   opus_val32 XX, XY, YY;\n   opus_val16 smoothed_width;\n   opus_val16 max_follower;\n} StereoWidthState;\n\nstruct OpusEncoder {\n    int          celt_enc_offset;\n    int          silk_enc_offset;\n    silk_EncControlStruct silk_mode;\n    int          application;\n    int          channels;\n    int          delay_compensation;\n    int          force_channels;\n    int          signal_type;\n    int          user_bandwidth;\n    int          max_bandwidth;\n    int          user_forced_mode;\n    int          voice_ratio;\n    opus_int32   Fs;\n    int          use_vbr;\n    int          vbr_constraint;\n    int          variable_duration;\n    opus_int32   bitrate_bps;\n    opus_int32   user_bitrate_bps;\n    int          lsb_depth;\n    int          encoder_buffer;\n    int          lfe;\n    int          arch;\n#ifndef DISABLE_FLOAT_API\n    TonalityAnalysisState analysis;\n#endif\n\n#define OPUS_ENCODER_RESET_START stream_channels\n    int          stream_channels;\n    opus_int16   hybrid_stereo_width_Q14;\n    opus_int32   variable_HP_smth2_Q15;\n    opus_val16   prev_HB_gain;\n    opus_val32   hp_mem[4];\n    int          mode;\n    int          prev_mode;\n    int          prev_channels;\n    int          prev_framesize;\n    int          bandwidth;\n    int          silk_bw_switch;\n    /* Sampling rate (at the API level) */\n    int          first;\n    opus_val16 * energy_masking;\n    StereoWidthState width_mem;\n    opus_val16   delay_buffer[MAX_ENCODER_BUFFER*2];\n#ifndef DISABLE_FLOAT_API\n    int          detected_bandwidth;\n#endif\n    opus_uint32  rangeFinal;\n};\n\n/* Transition tables for the voice and music. First column is the\n   middle (memoriless) threshold. The second column is the hysteresis\n   (difference with the middle) */\nstatic const opus_int32 mono_voice_bandwidth_thresholds[8] = {\n        11000, 1000, /* NB<->MB */\n        14000, 1000, /* MB<->WB */\n        17000, 1000, /* WB<->SWB */\n        21000, 2000, /* SWB<->FB */\n};\nstatic const opus_int32 mono_music_bandwidth_thresholds[8] = {\n        12000, 1000, /* NB<->MB */\n        15000, 1000, /* MB<->WB */\n        18000, 2000, /* WB<->SWB */\n        22000, 2000, /* SWB<->FB */\n};\nstatic const opus_int32 stereo_voice_bandwidth_thresholds[8] = {\n        11000, 1000, /* NB<->MB */\n        14000, 1000, /* MB<->WB */\n        21000, 2000, /* WB<->SWB */\n        28000, 2000, /* SWB<->FB */\n};\nstatic const opus_int32 stereo_music_bandwidth_thresholds[8] = {\n        12000, 1000, /* NB<->MB */\n        18000, 2000, /* MB<->WB */\n        21000, 2000, /* WB<->SWB */\n        30000, 2000, /* SWB<->FB */\n};\n/* Threshold bit-rates for switching between mono and stereo */\nstatic const opus_int32 stereo_voice_threshold = 30000;\nstatic const opus_int32 stereo_music_threshold = 30000;\n\n/* Threshold bit-rate for switching between SILK/hybrid and CELT-only */\nstatic const opus_int32 mode_thresholds[2][2] = {\n      /* voice */ /* music */\n      {  64000,      16000}, /* mono */\n      {  36000,      16000}, /* stereo */\n};\n\nint opus_encoder_get_size(int channels)\n{\n    int silkEncSizeBytes, celtEncSizeBytes;\n    int ret;\n    if (channels<1 || channels > 2)\n        return 0;\n    ret = silk_Get_Encoder_Size( &silkEncSizeBytes );\n    if (ret)\n        return 0;\n    silkEncSizeBytes = align(silkEncSizeBytes);\n    celtEncSizeBytes = celt_encoder_get_size(channels);\n    return align(sizeof(OpusEncoder))+silkEncSizeBytes+celtEncSizeBytes;\n}\n\nint opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int application)\n{\n    void *silk_enc;\n    CELTEncoder *celt_enc;\n    int err;\n    int ret, silkEncSizeBytes;\n\n   if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||\n        (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO\n        && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))\n        return OPUS_BAD_ARG;\n\n    OPUS_CLEAR((char*)st, opus_encoder_get_size(channels));\n    /* Create SILK encoder */\n    ret = silk_Get_Encoder_Size( &silkEncSizeBytes );\n    if (ret)\n        return OPUS_BAD_ARG;\n    silkEncSizeBytes = align(silkEncSizeBytes);\n    st->silk_enc_offset = align(sizeof(OpusEncoder));\n    st->celt_enc_offset = st->silk_enc_offset+silkEncSizeBytes;\n    silk_enc = (char*)st+st->silk_enc_offset;\n    celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);\n\n    st->stream_channels = st->channels = channels;\n\n    st->Fs = Fs;\n\n    st->arch = opus_select_arch();\n\n    ret = silk_InitEncoder( silk_enc, st->arch, &st->silk_mode );\n    if(ret)return OPUS_INTERNAL_ERROR;\n\n    /* default SILK parameters */\n    st->silk_mode.nChannelsAPI              = channels;\n    st->silk_mode.nChannelsInternal         = channels;\n    st->silk_mode.API_sampleRate            = st->Fs;\n    st->silk_mode.maxInternalSampleRate     = 16000;\n    st->silk_mode.minInternalSampleRate     = 8000;\n    st->silk_mode.desiredInternalSampleRate = 16000;\n    st->silk_mode.payloadSize_ms            = 20;\n    st->silk_mode.bitRate                   = 25000;\n    st->silk_mode.packetLossPercentage      = 0;\n    st->silk_mode.complexity                = 9;\n    st->silk_mode.useInBandFEC              = 0;\n    st->silk_mode.useDTX                    = 0;\n    st->silk_mode.useCBR                    = 0;\n    st->silk_mode.reducedDependency         = 0;\n\n    /* Create CELT encoder */\n    /* Initialize CELT encoder */\n    err = celt_encoder_init(celt_enc, Fs, channels, st->arch);\n    if(err!=OPUS_OK)return OPUS_INTERNAL_ERROR;\n\n    celt_encoder_ctl(celt_enc, CELT_SET_SIGNALLING(0));\n    celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(st->silk_mode.complexity));\n\n    st->use_vbr = 1;\n    /* Makes constrained VBR the default (safer for real-time use) */\n    st->vbr_constraint = 1;\n    st->user_bitrate_bps = OPUS_AUTO;\n    st->bitrate_bps = 3000+Fs*channels;\n    st->application = application;\n    st->signal_type = OPUS_AUTO;\n    st->user_bandwidth = OPUS_AUTO;\n    st->max_bandwidth = OPUS_BANDWIDTH_FULLBAND;\n    st->force_channels = OPUS_AUTO;\n    st->user_forced_mode = OPUS_AUTO;\n    st->voice_ratio = -1;\n    st->encoder_buffer = st->Fs/100;\n    st->lsb_depth = 24;\n    st->variable_duration = OPUS_FRAMESIZE_ARG;\n\n    /* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead\n       + 1.5 ms for SILK resamplers and stereo prediction) */\n    st->delay_compensation = st->Fs/250;\n\n    st->hybrid_stereo_width_Q14 = 1 << 14;\n    st->prev_HB_gain = Q15ONE;\n    st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );\n    st->first = 1;\n    st->mode = MODE_HYBRID;\n    st->bandwidth = OPUS_BANDWIDTH_FULLBAND;\n\n#ifndef DISABLE_FLOAT_API\n    tonality_analysis_init(&st->analysis);\n#endif\n\n    return OPUS_OK;\n}\n\nstatic unsigned char gen_toc(int mode, int framerate, int bandwidth, int channels)\n{\n   int period;\n   unsigned char toc;\n   period = 0;\n   while (framerate < 400)\n   {\n       framerate <<= 1;\n       period++;\n   }\n   if (mode == MODE_SILK_ONLY)\n   {\n       toc = (bandwidth-OPUS_BANDWIDTH_NARROWBAND)<<5;\n       toc |= (period-2)<<3;\n   } else if (mode == MODE_CELT_ONLY)\n   {\n       int tmp = bandwidth-OPUS_BANDWIDTH_MEDIUMBAND;\n       if (tmp < 0)\n           tmp = 0;\n       toc = 0x80;\n       toc |= tmp << 5;\n       toc |= period<<3;\n   } else /* Hybrid */\n   {\n       toc = 0x60;\n       toc |= (bandwidth-OPUS_BANDWIDTH_SUPERWIDEBAND)<<4;\n       toc |= (period-2)<<3;\n   }\n   toc |= (channels==2)<<2;\n   return toc;\n}\n\n#ifndef FIXED_POINT\nstatic void silk_biquad_float(\n    const opus_val16      *in,            /* I:    Input signal                   */\n    const opus_int32      *B_Q28,         /* I:    MA coefficients [3]            */\n    const opus_int32      *A_Q28,         /* I:    AR coefficients [2]            */\n    opus_val32            *S,             /* I/O:  State vector [2]               */\n    opus_val16            *out,           /* O:    Output signal                  */\n    const opus_int32      len,            /* I:    Signal length (must be even)   */\n    int stride\n)\n{\n    /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */\n    opus_int   k;\n    opus_val32 vout;\n    opus_val32 inval;\n    opus_val32 A[2], B[3];\n\n    A[0] = (opus_val32)(A_Q28[0] * (1.f/((opus_int32)1<<28)));\n    A[1] = (opus_val32)(A_Q28[1] * (1.f/((opus_int32)1<<28)));\n    B[0] = (opus_val32)(B_Q28[0] * (1.f/((opus_int32)1<<28)));\n    B[1] = (opus_val32)(B_Q28[1] * (1.f/((opus_int32)1<<28)));\n    B[2] = (opus_val32)(B_Q28[2] * (1.f/((opus_int32)1<<28)));\n\n    /* Negate A_Q28 values and split in two parts */\n\n    for( k = 0; k < len; k++ ) {\n        /* S[ 0 ], S[ 1 ]: Q12 */\n        inval = in[ k*stride ];\n        vout = S[ 0 ] + B[0]*inval;\n\n        S[ 0 ] = S[1] - vout*A[0] + B[1]*inval;\n\n        S[ 1 ] = - vout*A[1] + B[2]*inval + VERY_SMALL;\n\n        /* Scale back to Q0 and saturate */\n        out[ k*stride ] = vout;\n    }\n}\n#endif\n\nstatic void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)\n{\n   opus_int32 B_Q28[ 3 ], A_Q28[ 2 ];\n   opus_int32 Fc_Q19, r_Q28, r_Q22;\n\n   silk_assert( cutoff_Hz <= silk_int32_MAX / SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ) );\n   Fc_Q19 = silk_DIV32_16( silk_SMULBB( SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ), cutoff_Hz ), Fs/1000 );\n   silk_assert( Fc_Q19 > 0 && Fc_Q19 < 32768 );\n\n   r_Q28 = SILK_FIX_CONST( 1.0, 28 ) - silk_MUL( SILK_FIX_CONST( 0.92, 9 ), Fc_Q19 );\n\n   /* b = r * [ 1; -2; 1 ]; */\n   /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */\n   B_Q28[ 0 ] = r_Q28;\n   B_Q28[ 1 ] = silk_LSHIFT( -r_Q28, 1 );\n   B_Q28[ 2 ] = r_Q28;\n\n   /* -r * ( 2 - Fc * Fc ); */\n   r_Q22  = silk_RSHIFT( r_Q28, 6 );\n   A_Q28[ 0 ] = silk_SMULWW( r_Q22, silk_SMULWW( Fc_Q19, Fc_Q19 ) - SILK_FIX_CONST( 2.0,  22 ) );\n   A_Q28[ 1 ] = silk_SMULWW( r_Q22, r_Q22 );\n\n#ifdef FIXED_POINT\n   silk_biquad_alt( in, B_Q28, A_Q28, hp_mem, out, len, channels );\n   if( channels == 2 ) {\n       silk_biquad_alt( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels );\n   }\n#else\n   silk_biquad_float( in, B_Q28, A_Q28, hp_mem, out, len, channels );\n   if( channels == 2 ) {\n       silk_biquad_float( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels );\n   }\n#endif\n}\n\n#ifdef FIXED_POINT\nstatic void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)\n{\n   int c, i;\n   int shift;\n\n   /* Approximates -round(log2(4.*cutoff_Hz/Fs)) */\n   shift=celt_ilog2(Fs/(cutoff_Hz*3));\n   for (c=0;c<channels;c++)\n   {\n      for (i=0;i<len;i++)\n      {\n         opus_val32 x, tmp, y;\n         x = SHL32(EXTEND32(in[channels*i+c]), 15);\n         /* First stage */\n         tmp = x-hp_mem[2*c];\n         hp_mem[2*c] = hp_mem[2*c] + PSHR32(x - hp_mem[2*c], shift);\n         /* Second stage */\n         y = tmp - hp_mem[2*c+1];\n         hp_mem[2*c+1] = hp_mem[2*c+1] + PSHR32(tmp - hp_mem[2*c+1], shift);\n         out[channels*i+c] = EXTRACT16(SATURATE(PSHR32(y, 15), 32767));\n      }\n   }\n}\n\n#else\nstatic void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)\n{\n   int c, i;\n   float coef;\n\n   coef = 4.0f*cutoff_Hz/Fs;\n   for (c=0;c<channels;c++)\n   {\n      for (i=0;i<len;i++)\n      {\n         opus_val32 x, tmp, y;\n         x = in[channels*i+c];\n         /* First stage */\n         tmp = x-hp_mem[2*c];\n         hp_mem[2*c] = hp_mem[2*c] + coef*(x - hp_mem[2*c]) + VERY_SMALL;\n         /* Second stage */\n         y = tmp - hp_mem[2*c+1];\n         hp_mem[2*c+1] = hp_mem[2*c+1] + coef*(tmp - hp_mem[2*c+1]) + VERY_SMALL;\n         out[channels*i+c] = y;\n      }\n   }\n}\n#endif\n\nstatic void stereo_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, opus_val16 g2,\n        int overlap48, int frame_size, int channels, const opus_val16 *window, opus_int32 Fs)\n{\n    int i;\n    int overlap;\n    int inc;\n    inc = 48000/Fs;\n    overlap=overlap48/inc;\n    g1 = Q15ONE-g1;\n    g2 = Q15ONE-g2;\n    for (i=0;i<overlap;i++)\n    {\n       opus_val32 diff;\n       opus_val16 g, w;\n       w = MULT16_16_Q15(window[i*inc], window[i*inc]);\n       g = SHR32(MAC16_16(MULT16_16(w,g2),\n             Q15ONE-w, g1), 15);\n       diff = EXTRACT16(HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]));\n       diff = MULT16_16_Q15(g, diff);\n       out[i*channels] = out[i*channels] - diff;\n       out[i*channels+1] = out[i*channels+1] + diff;\n    }\n    for (;i<frame_size;i++)\n    {\n       opus_val32 diff;\n       diff = EXTRACT16(HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]));\n       diff = MULT16_16_Q15(g2, diff);\n       out[i*channels] = out[i*channels] - diff;\n       out[i*channels+1] = out[i*channels+1] + diff;\n    }\n}\n\nstatic void gain_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, opus_val16 g2,\n        int overlap48, int frame_size, int channels, const opus_val16 *window, opus_int32 Fs)\n{\n    int i;\n    int inc;\n    int overlap;\n    int c;\n    inc = 48000/Fs;\n    overlap=overlap48/inc;\n    if (channels==1)\n    {\n       for (i=0;i<overlap;i++)\n       {\n          opus_val16 g, w;\n          w = MULT16_16_Q15(window[i*inc], window[i*inc]);\n          g = SHR32(MAC16_16(MULT16_16(w,g2),\n                Q15ONE-w, g1), 15);\n          out[i] = MULT16_16_Q15(g, in[i]);\n       }\n    } else {\n       for (i=0;i<overlap;i++)\n       {\n          opus_val16 g, w;\n          w = MULT16_16_Q15(window[i*inc], window[i*inc]);\n          g = SHR32(MAC16_16(MULT16_16(w,g2),\n                Q15ONE-w, g1), 15);\n          out[i*2] = MULT16_16_Q15(g, in[i*2]);\n          out[i*2+1] = MULT16_16_Q15(g, in[i*2+1]);\n       }\n    }\n    c=0;do {\n       for (i=overlap;i<frame_size;i++)\n       {\n          out[i*channels+c] = MULT16_16_Q15(g2, in[i*channels+c]);\n       }\n    }\n    while (++c<channels);\n}\n\nOpusEncoder *opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)\n{\n   int ret;\n   OpusEncoder *st;\n   if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||\n       (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO\n       && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))\n   {\n      if (error)\n         *error = OPUS_BAD_ARG;\n      return NULL;\n   }\n   st = (OpusEncoder *)opus_alloc(opus_encoder_get_size(channels));\n   if (st == NULL)\n   {\n      if (error)\n         *error = OPUS_ALLOC_FAIL;\n      return NULL;\n   }\n   ret = opus_encoder_init(st, Fs, channels, application);\n   if (error)\n      *error = ret;\n   if (ret != OPUS_OK)\n   {\n      opus_free(st);\n      st = NULL;\n   }\n   return st;\n}\n\nstatic opus_int32 user_bitrate_to_bitrate(OpusEncoder *st, int frame_size, int max_data_bytes)\n{\n  if(!frame_size)frame_size=st->Fs/400;\n  if (st->user_bitrate_bps==OPUS_AUTO)\n    return 60*st->Fs/frame_size + st->Fs*st->channels;\n  else if (st->user_bitrate_bps==OPUS_BITRATE_MAX)\n    return max_data_bytes*8*st->Fs/frame_size;\n  else\n    return st->user_bitrate_bps;\n}\n\n#ifndef DISABLE_FLOAT_API\n/* Don't use more than 60 ms for the frame size analysis */\n#define MAX_DYNAMIC_FRAMESIZE 24\n/* Estimates how much the bitrate will be boosted based on the sub-frame energy */\nstatic float transient_boost(const float *E, const float *E_1, int LM, int maxM)\n{\n   int i;\n   int M;\n   float sumE=0, sumE_1=0;\n   float metric;\n\n   M = IMIN(maxM, (1<<LM)+1);\n   for (i=0;i<M;i++)\n   {\n      sumE += E[i];\n      sumE_1 += E_1[i];\n   }\n   metric = sumE*sumE_1/(M*M);\n   /*if (LM==3)\n      printf(\"%f\\n\", metric);*/\n   /*return metric>10 ? 1 : 0;*/\n   /*return MAX16(0,1-exp(-.25*(metric-2.)));*/\n   return MIN16(1,(float)sqrt(MAX16(0,.05f*(metric-2))));\n}\n\n/* Viterbi decoding trying to find the best frame size combination using look-ahead\n\n   State numbering:\n    0: unused\n    1:  2.5 ms\n    2:  5 ms (#1)\n    3:  5 ms (#2)\n    4: 10 ms (#1)\n    5: 10 ms (#2)\n    6: 10 ms (#3)\n    7: 10 ms (#4)\n    8: 20 ms (#1)\n    9: 20 ms (#2)\n   10: 20 ms (#3)\n   11: 20 ms (#4)\n   12: 20 ms (#5)\n   13: 20 ms (#6)\n   14: 20 ms (#7)\n   15: 20 ms (#8)\n*/\nstatic int transient_viterbi(const float *E, const float *E_1, int N, int frame_cost, int rate)\n{\n   int i;\n   float cost[MAX_DYNAMIC_FRAMESIZE][16];\n   int states[MAX_DYNAMIC_FRAMESIZE][16];\n   float best_cost;\n   int best_state;\n   float factor;\n   /* Take into account that we damp VBR in the 32 kb/s to 64 kb/s range. */\n   if (rate<80)\n      factor=0;\n   else if (rate>160)\n      factor=1;\n   else\n      factor = (rate-80.f)/80.f;\n   /* Makes variable framesize less aggressive at lower bitrates, but I can't\n      find any valid theoretical justification for this (other than it seems\n      to help) */\n   for (i=0;i<16;i++)\n   {\n      /* Impossible state */\n      states[0][i] = -1;\n      cost[0][i] = 1e10;\n   }\n   for (i=0;i<4;i++)\n   {\n      cost[0][1<<i] = (frame_cost + rate*(1<<i))*(1+factor*transient_boost(E, E_1, i, N+1));\n      states[0][1<<i] = i;\n   }\n   for (i=1;i<N;i++)\n   {\n      int j;\n\n      /* Follow continuations */\n      for (j=2;j<16;j++)\n      {\n         cost[i][j] = cost[i-1][j-1];\n         states[i][j] = j-1;\n      }\n\n      /* New frames */\n      for(j=0;j<4;j++)\n      {\n         int k;\n         float min_cost;\n         float curr_cost;\n         states[i][1<<j] = 1;\n         min_cost = cost[i-1][1];\n         for(k=1;k<4;k++)\n         {\n            float tmp = cost[i-1][(1<<(k+1))-1];\n            if (tmp < min_cost)\n            {\n               states[i][1<<j] = (1<<(k+1))-1;\n               min_cost = tmp;\n            }\n         }\n         curr_cost = (frame_cost + rate*(1<<j))*(1+factor*transient_boost(E+i, E_1+i, j, N-i+1));\n         cost[i][1<<j] = min_cost;\n         /* If part of the frame is outside the analysis window, only count part of the cost */\n         if (N-i < (1<<j))\n            cost[i][1<<j] += curr_cost*(float)(N-i)/(1<<j);\n         else\n            cost[i][1<<j] += curr_cost;\n      }\n   }\n\n   best_state=1;\n   best_cost = cost[N-1][1];\n   /* Find best end state (doesn't force a frame to end at N-1) */\n   for (i=2;i<16;i++)\n   {\n      if (cost[N-1][i]<best_cost)\n      {\n         best_cost = cost[N-1][i];\n         best_state = i;\n      }\n   }\n\n   /* Follow transitions back */\n   for (i=N-1;i>=0;i--)\n   {\n      /*printf(\"%d \", best_state);*/\n      best_state = states[i][best_state];\n   }\n   /*printf(\"%d\\n\", best_state);*/\n   return best_state;\n}\n\nstatic int optimize_framesize(const void *x, int len, int C, opus_int32 Fs,\n                int bitrate, opus_val16 tonality, float *mem, int buffering,\n                downmix_func downmix)\n{\n   int N;\n   int i;\n   float e[MAX_DYNAMIC_FRAMESIZE+4];\n   float e_1[MAX_DYNAMIC_FRAMESIZE+3];\n   opus_val32 memx;\n   int bestLM=0;\n   int subframe;\n   int pos;\n   int offset;\n   VARDECL(opus_val32, sub);\n\n   subframe = Fs/400;\n   ALLOC(sub, subframe, opus_val32);\n   e[0]=mem[0];\n   e_1[0]=1.f/(EPSILON+mem[0]);\n   if (buffering)\n   {\n      /* Consider the CELT delay when not in restricted-lowdelay */\n      /* We assume the buffering is between 2.5 and 5 ms */\n      offset = 2*subframe - buffering;\n      celt_assert(offset>=0 && offset <= subframe);\n      len -= offset;\n      e[1]=mem[1];\n      e_1[1]=1.f/(EPSILON+mem[1]);\n      e[2]=mem[2];\n      e_1[2]=1.f/(EPSILON+mem[2]);\n      pos = 3;\n   } else {\n      pos=1;\n      offset=0;\n   }\n   N=IMIN(len/subframe, MAX_DYNAMIC_FRAMESIZE);\n   /* Just silencing a warning, it's really initialized later */\n   memx = 0;\n   for (i=0;i<N;i++)\n   {\n      float tmp;\n      opus_val32 tmpx;\n      int j;\n      tmp=EPSILON;\n\n      downmix(x, sub, subframe, i*subframe+offset, 0, -2, C);\n      if (i==0)\n         memx = sub[0];\n      for (j=0;j<subframe;j++)\n      {\n         tmpx = sub[j];\n         tmp += (tmpx-memx)*(float)(tmpx-memx);\n         memx = tmpx;\n      }\n      e[i+pos] = tmp;\n      e_1[i+pos] = 1.f/tmp;\n   }\n   /* Hack to get 20 ms working with APPLICATION_AUDIO\n      The real problem is that the corresponding memory needs to use 1.5 ms\n      from this frame and 1 ms from the next frame */\n   e[i+pos] = e[i+pos-1];\n   if (buffering)\n      N=IMIN(MAX_DYNAMIC_FRAMESIZE, N+2);\n   bestLM = transient_viterbi(e, e_1, N, (int)((1.f+.5f*tonality)*(60*C+40)), bitrate/400);\n   mem[0] = e[1<<bestLM];\n   if (buffering)\n   {\n      mem[1] = e[(1<<bestLM)+1];\n      mem[2] = e[(1<<bestLM)+2];\n   }\n   return bestLM;\n}\n\n#endif\n\n#ifndef DISABLE_FLOAT_API\n#ifdef FIXED_POINT\n#define PCM2VAL(x) FLOAT2INT16(x)\n#else\n#define PCM2VAL(x) SCALEIN(x)\n#endif\nvoid downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C)\n{\n   const float *x;\n   opus_val32 scale;\n   int j;\n   x = (const float *)_x;\n   for (j=0;j<subframe;j++)\n      sub[j] = PCM2VAL(x[(j+offset)*C+c1]);\n   if (c2>-1)\n   {\n      for (j=0;j<subframe;j++)\n         sub[j] += PCM2VAL(x[(j+offset)*C+c2]);\n   } else if (c2==-2)\n   {\n      int c;\n      for (c=1;c<C;c++)\n      {\n         for (j=0;j<subframe;j++)\n            sub[j] += PCM2VAL(x[(j+offset)*C+c]);\n      }\n   }\n#ifdef FIXED_POINT\n   scale = (1<<SIG_SHIFT);\n#else\n   scale = 1.f;\n#endif\n   if (C==-2)\n      scale /= C;\n   else\n      scale /= 2;\n   for (j=0;j<subframe;j++)\n      sub[j] *= scale;\n}\n#endif\n\nvoid downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C)\n{\n   const opus_int16 *x;\n   opus_val32 scale;\n   int j;\n   x = (const opus_int16 *)_x;\n   for (j=0;j<subframe;j++)\n      sub[j] = x[(j+offset)*C+c1];\n   if (c2>-1)\n   {\n      for (j=0;j<subframe;j++)\n         sub[j] += x[(j+offset)*C+c2];\n   } else if (c2==-2)\n   {\n      int c;\n      for (c=1;c<C;c++)\n      {\n         for (j=0;j<subframe;j++)\n            sub[j] += x[(j+offset)*C+c];\n      }\n   }\n#ifdef FIXED_POINT\n   scale = (1<<SIG_SHIFT);\n#else\n   scale = 1.f/32768;\n#endif\n   if (C==-2)\n      scale /= C;\n   else\n      scale /= 2;\n   for (j=0;j<subframe;j++)\n      sub[j] *= scale;\n}\n\nopus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs)\n{\n   int new_size;\n   if (frame_size<Fs/400)\n      return -1;\n   if (variable_duration == OPUS_FRAMESIZE_ARG)\n      new_size = frame_size;\n   else if (variable_duration == OPUS_FRAMESIZE_VARIABLE)\n      new_size = Fs/50;\n   else if (variable_duration >= OPUS_FRAMESIZE_2_5_MS && variable_duration <= OPUS_FRAMESIZE_60_MS)\n      new_size = IMIN(3*Fs/50, (Fs/400)<<(variable_duration-OPUS_FRAMESIZE_2_5_MS));\n   else\n      return -1;\n   if (new_size>frame_size)\n      return -1;\n   if (400*new_size!=Fs && 200*new_size!=Fs && 100*new_size!=Fs &&\n            50*new_size!=Fs && 25*new_size!=Fs && 50*new_size!=3*Fs)\n      return -1;\n   return new_size;\n}\n\nopus_int32 compute_frame_size(const void *analysis_pcm, int frame_size,\n      int variable_duration, int C, opus_int32 Fs, int bitrate_bps,\n      int delay_compensation, downmix_func downmix\n#ifndef DISABLE_FLOAT_API\n      , float *subframe_mem\n#endif\n      )\n{\n#ifndef DISABLE_FLOAT_API\n   if (variable_duration == OPUS_FRAMESIZE_VARIABLE && frame_size >= Fs/200)\n   {\n      int LM = 3;\n      LM = optimize_framesize(analysis_pcm, frame_size, C, Fs, bitrate_bps,\n            0, subframe_mem, delay_compensation, downmix);\n      while ((Fs/400<<LM)>frame_size)\n         LM--;\n      frame_size = (Fs/400<<LM);\n   } else\n#else\n   (void)analysis_pcm;\n   (void)C;\n   (void)bitrate_bps;\n   (void)delay_compensation;\n   (void)downmix;\n#endif\n   {\n      frame_size = frame_size_select(frame_size, variable_duration, Fs);\n   }\n   if (frame_size<0)\n      return -1;\n   return frame_size;\n}\n\nopus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int32 Fs, StereoWidthState *mem)\n{\n   opus_val16 corr;\n   opus_val16 ldiff;\n   opus_val16 width;\n   opus_val32 xx, xy, yy;\n   opus_val16 sqrt_xx, sqrt_yy;\n   opus_val16 qrrt_xx, qrrt_yy;\n   int frame_rate;\n   int i;\n   opus_val16 short_alpha;\n\n   frame_rate = Fs/frame_size;\n   short_alpha = Q15ONE - 25*Q15ONE/IMAX(50,frame_rate);\n   xx=xy=yy=0;\n   for (i=0;i<frame_size;i+=4)\n   {\n      opus_val32 pxx=0;\n      opus_val32 pxy=0;\n      opus_val32 pyy=0;\n      opus_val16 x, y;\n      x = pcm[2*i];\n      y = pcm[2*i+1];\n      pxx = SHR32(MULT16_16(x,x),2);\n      pxy = SHR32(MULT16_16(x,y),2);\n      pyy = SHR32(MULT16_16(y,y),2);\n      x = pcm[2*i+2];\n      y = pcm[2*i+3];\n      pxx += SHR32(MULT16_16(x,x),2);\n      pxy += SHR32(MULT16_16(x,y),2);\n      pyy += SHR32(MULT16_16(y,y),2);\n      x = pcm[2*i+4];\n      y = pcm[2*i+5];\n      pxx += SHR32(MULT16_16(x,x),2);\n      pxy += SHR32(MULT16_16(x,y),2);\n      pyy += SHR32(MULT16_16(y,y),2);\n      x = pcm[2*i+6];\n      y = pcm[2*i+7];\n      pxx += SHR32(MULT16_16(x,x),2);\n      pxy += SHR32(MULT16_16(x,y),2);\n      pyy += SHR32(MULT16_16(y,y),2);\n\n      xx += SHR32(pxx, 10);\n      xy += SHR32(pxy, 10);\n      yy += SHR32(pyy, 10);\n   }\n   mem->XX += MULT16_32_Q15(short_alpha, xx-mem->XX);\n   mem->XY += MULT16_32_Q15(short_alpha, xy-mem->XY);\n   mem->YY += MULT16_32_Q15(short_alpha, yy-mem->YY);\n   mem->XX = MAX32(0, mem->XX);\n   mem->XY = MAX32(0, mem->XY);\n   mem->YY = MAX32(0, mem->YY);\n   if (MAX32(mem->XX, mem->YY)>QCONST16(8e-4f, 18))\n   {\n      sqrt_xx = celt_sqrt(mem->XX);\n      sqrt_yy = celt_sqrt(mem->YY);\n      qrrt_xx = celt_sqrt(sqrt_xx);\n      qrrt_yy = celt_sqrt(sqrt_yy);\n      /* Inter-channel correlation */\n      mem->XY = MIN32(mem->XY, sqrt_xx*sqrt_yy);\n      corr = SHR32(frac_div32(mem->XY,EPSILON+MULT16_16(sqrt_xx,sqrt_yy)),16);\n      /* Approximate loudness difference */\n      ldiff = Q15ONE*ABS16(qrrt_xx-qrrt_yy)/(EPSILON+qrrt_xx+qrrt_yy);\n      width = MULT16_16_Q15(celt_sqrt(QCONST32(1.f,30)-MULT16_16(corr,corr)), ldiff);\n      /* Smoothing over one second */\n      mem->smoothed_width += (width-mem->smoothed_width)/frame_rate;\n      /* Peak follower */\n      mem->max_follower = MAX16(mem->max_follower-QCONST16(.02f,15)/frame_rate, mem->smoothed_width);\n   } else {\n      width = 0;\n      corr=Q15ONE;\n      ldiff=0;\n   }\n   /*printf(\"%f %f %f %f %f \", corr/(float)Q15ONE, ldiff/(float)Q15ONE, width/(float)Q15ONE, mem->smoothed_width/(float)Q15ONE, mem->max_follower/(float)Q15ONE);*/\n   return EXTRACT16(MIN32(Q15ONE,20*mem->max_follower));\n}\n\nopus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,\n                unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,\n                const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2,\n                int analysis_channels, downmix_func downmix, int float_api)\n{\n    void *silk_enc;\n    CELTEncoder *celt_enc;\n    int i;\n    int ret=0;\n    opus_int32 nBytes;\n    ec_enc enc;\n    int bytes_target;\n    int prefill=0;\n    int start_band = 0;\n    int redundancy = 0;\n    int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */\n    int celt_to_silk = 0;\n    VARDECL(opus_val16, pcm_buf);\n    int nb_compr_bytes;\n    int to_celt = 0;\n    opus_uint32 redundant_rng = 0;\n    int cutoff_Hz, hp_freq_smth1;\n    int voice_est; /* Probability of voice in Q7 */\n    opus_int32 equiv_rate;\n    int delay_compensation;\n    int frame_rate;\n    opus_int32 max_rate; /* Max bitrate we're allowed to use */\n    int curr_bandwidth;\n    opus_val16 HB_gain;\n    opus_int32 max_data_bytes; /* Max number of bytes we're allowed to use */\n    int total_buffer;\n    opus_val16 stereo_width;\n    const CELTMode *celt_mode;\n#ifndef DISABLE_FLOAT_API\n    AnalysisInfo analysis_info;\n    int analysis_read_pos_bak=-1;\n    int analysis_read_subframe_bak=-1;\n#endif\n    VARDECL(opus_val16, tmp_prefill);\n\n    ALLOC_STACK;\n\n    max_data_bytes = IMIN(1276, out_data_bytes);\n\n    st->rangeFinal = 0;\n    if ((!st->variable_duration && 400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs &&\n         50*frame_size != st->Fs &&  25*frame_size != st->Fs &&  50*frame_size != 3*st->Fs)\n         || (400*frame_size < st->Fs)\n         || max_data_bytes<=0\n         )\n    {\n       RESTORE_STACK;\n       return OPUS_BAD_ARG;\n    }\n    silk_enc = (char*)st+st->silk_enc_offset;\n    celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);\n    if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)\n       delay_compensation = 0;\n    else\n       delay_compensation = st->delay_compensation;\n\n    lsb_depth = IMIN(lsb_depth, st->lsb_depth);\n\n    celt_encoder_ctl(celt_enc, CELT_GET_MODE(&celt_mode));\n#ifndef DISABLE_FLOAT_API\n    analysis_info.valid = 0;\n#ifdef FIXED_POINT\n    if (st->silk_mode.complexity >= 10 && st->Fs==48000)\n#else\n    if (st->silk_mode.complexity >= 7 && st->Fs==48000)\n#endif\n    {\n       analysis_read_pos_bak = st->analysis.read_pos;\n       analysis_read_subframe_bak = st->analysis.read_subframe;\n       run_analysis(&st->analysis, celt_mode, analysis_pcm, analysis_size, frame_size,\n             c1, c2, analysis_channels, st->Fs,\n             lsb_depth, downmix, &analysis_info);\n    }\n#else\n    (void)analysis_pcm;\n    (void)analysis_size;\n#endif\n\n    st->voice_ratio = -1;\n\n#ifndef DISABLE_FLOAT_API\n    st->detected_bandwidth = 0;\n    if (analysis_info.valid)\n    {\n       int analysis_bandwidth;\n       if (st->signal_type == OPUS_AUTO)\n          st->voice_ratio = (int)floor(.5+100*(1-analysis_info.music_prob));\n\n       analysis_bandwidth = analysis_info.bandwidth;\n       if (analysis_bandwidth<=12)\n          st->detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND;\n       else if (analysis_bandwidth<=14)\n          st->detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;\n       else if (analysis_bandwidth<=16)\n          st->detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND;\n       else if (analysis_bandwidth<=18)\n          st->detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;\n       else\n          st->detected_bandwidth = OPUS_BANDWIDTH_FULLBAND;\n    }\n#endif\n\n    if (st->channels==2 && st->force_channels!=1)\n       stereo_width = compute_stereo_width(pcm, frame_size, st->Fs, &st->width_mem);\n    else\n       stereo_width = 0;\n    total_buffer = delay_compensation;\n    st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes);\n\n    frame_rate = st->Fs/frame_size;\n    if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8\n       || (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400)))\n    {\n       /*If the space is too low to do something useful, emit 'PLC' frames.*/\n       int tocmode = st->mode;\n       int bw = st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth;\n       if (tocmode==0)\n          tocmode = MODE_SILK_ONLY;\n       if (frame_rate>100)\n          tocmode = MODE_CELT_ONLY;\n       if (frame_rate < 50)\n          tocmode = MODE_SILK_ONLY;\n       if(tocmode==MODE_SILK_ONLY&&bw>OPUS_BANDWIDTH_WIDEBAND)\n          bw=OPUS_BANDWIDTH_WIDEBAND;\n       else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND)\n          bw=OPUS_BANDWIDTH_NARROWBAND;\n       else if (bw<=OPUS_BANDWIDTH_SUPERWIDEBAND)\n          bw=OPUS_BANDWIDTH_SUPERWIDEBAND;\n       data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels);\n       RESTORE_STACK;\n       return 1;\n    }\n    if (!st->use_vbr)\n    {\n       int cbrBytes;\n       cbrBytes = IMIN( (st->bitrate_bps + 4*frame_rate)/(8*frame_rate) , max_data_bytes);\n       st->bitrate_bps = cbrBytes * (8*frame_rate);\n       max_data_bytes = cbrBytes;\n    }\n    max_rate = frame_rate*max_data_bytes*8;\n\n    /* Equivalent 20-ms rate for mode/channel/bandwidth decisions */\n    equiv_rate = st->bitrate_bps - (40*st->channels+20)*(st->Fs/frame_size - 50);\n\n    if (st->signal_type == OPUS_SIGNAL_VOICE)\n       voice_est = 127;\n    else if (st->signal_type == OPUS_SIGNAL_MUSIC)\n       voice_est = 0;\n    else if (st->voice_ratio >= 0)\n    {\n       voice_est = st->voice_ratio*327>>8;\n       /* For AUDIO, never be more than 90% confident of having speech */\n       if (st->application == OPUS_APPLICATION_AUDIO)\n          voice_est = IMIN(voice_est, 115);\n    } else if (st->application == OPUS_APPLICATION_VOIP)\n       voice_est = 115;\n    else\n       voice_est = 48;\n\n    if (st->force_channels!=OPUS_AUTO && st->channels == 2)\n    {\n        st->stream_channels = st->force_channels;\n    } else {\n#ifdef FUZZING\n       /* Random mono/stereo decision */\n       if (st->channels == 2 && (rand()&0x1F)==0)\n          st->stream_channels = 3-st->stream_channels;\n#else\n       /* Rate-dependent mono-stereo decision */\n       if (st->channels == 2)\n       {\n          opus_int32 stereo_threshold;\n          stereo_threshold = stereo_music_threshold + ((voice_est*voice_est*(stereo_voice_threshold-stereo_music_threshold))>>14);\n          if (st->stream_channels == 2)\n             stereo_threshold -= 1000;\n          else\n             stereo_threshold += 1000;\n          st->stream_channels = (equiv_rate > stereo_threshold) ? 2 : 1;\n       } else {\n          st->stream_channels = st->channels;\n       }\n#endif\n    }\n    equiv_rate = st->bitrate_bps - (40*st->stream_channels+20)*(st->Fs/frame_size - 50);\n\n    /* Mode selection depending on application and signal type */\n    if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)\n    {\n       st->mode = MODE_CELT_ONLY;\n    } else if (st->user_forced_mode == OPUS_AUTO)\n    {\n#ifdef FUZZING\n       /* Random mode switching */\n       if ((rand()&0xF)==0)\n       {\n          if ((rand()&0x1)==0)\n             st->mode = MODE_CELT_ONLY;\n          else\n             st->mode = MODE_SILK_ONLY;\n       } else {\n          if (st->prev_mode==MODE_CELT_ONLY)\n             st->mode = MODE_CELT_ONLY;\n          else\n             st->mode = MODE_SILK_ONLY;\n       }\n#else\n       opus_int32 mode_voice, mode_music;\n       opus_int32 threshold;\n\n       /* Interpolate based on stereo width */\n       mode_voice = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[0][0])\n             + MULT16_32_Q15(stereo_width,mode_thresholds[1][0]));\n       mode_music = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[1][1])\n             + MULT16_32_Q15(stereo_width,mode_thresholds[1][1]));\n       /* Interpolate based on speech/music probability */\n       threshold = mode_music + ((voice_est*voice_est*(mode_voice-mode_music))>>14);\n       /* Bias towards SILK for VoIP because of some useful features */\n       if (st->application == OPUS_APPLICATION_VOIP)\n          threshold += 8000;\n\n       /*printf(\"%f %d\\n\", stereo_width/(float)Q15ONE, threshold);*/\n       /* Hysteresis */\n       if (st->prev_mode == MODE_CELT_ONLY)\n           threshold -= 4000;\n       else if (st->prev_mode>0)\n           threshold += 4000;\n\n       st->mode = (equiv_rate >= threshold) ? MODE_CELT_ONLY: MODE_SILK_ONLY;\n\n       /* When FEC is enabled and there's enough packet loss, use SILK */\n       if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4)\n          st->mode = MODE_SILK_ONLY;\n       /* When encoding voice and DTX is enabled, set the encoder to SILK mode (at least for now) */\n       if (st->silk_mode.useDTX && voice_est > 100)\n          st->mode = MODE_SILK_ONLY;\n#endif\n    } else {\n       st->mode = st->user_forced_mode;\n    }\n\n    /* Override the chosen mode to make sure we meet the requested frame size */\n    if (st->mode != MODE_CELT_ONLY && frame_size < st->Fs/100)\n       st->mode = MODE_CELT_ONLY;\n    if (st->lfe)\n       st->mode = MODE_CELT_ONLY;\n    /* If max_data_bytes represents less than 8 kb/s, switch to CELT-only mode */\n    if (max_data_bytes < (frame_rate > 50 ? 12000 : 8000)*frame_size / (st->Fs * 8))\n       st->mode = MODE_CELT_ONLY;\n\n    if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0\n          && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)\n    {\n       /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */\n       st->silk_mode.toMono = 1;\n       st->stream_channels = 2;\n    } else {\n       st->silk_mode.toMono = 0;\n    }\n\n    if (st->prev_mode > 0 &&\n        ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ||\n    (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)))\n    {\n        redundancy = 1;\n        celt_to_silk = (st->mode != MODE_CELT_ONLY);\n        if (!celt_to_silk)\n        {\n            /* Switch to SILK/hybrid if frame size is 10 ms or more*/\n            if (frame_size >= st->Fs/100)\n            {\n                st->mode = st->prev_mode;\n                to_celt = 1;\n            } else {\n                redundancy=0;\n            }\n        }\n    }\n    /* For the first frame at a new SILK bandwidth */\n    if (st->silk_bw_switch)\n    {\n       redundancy = 1;\n       celt_to_silk = 1;\n       st->silk_bw_switch = 0;\n       prefill=1;\n    }\n\n    if (redundancy)\n    {\n       /* Fair share of the max size allowed */\n       redundancy_bytes = IMIN(257, max_data_bytes*(opus_int32)(st->Fs/200)/(frame_size+st->Fs/200));\n       /* For VBR, target the actual bitrate (subject to the limit above) */\n       if (st->use_vbr)\n          redundancy_bytes = IMIN(redundancy_bytes, st->bitrate_bps/1600);\n    }\n\n    if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)\n    {\n        silk_EncControlStruct dummy;\n        silk_InitEncoder( silk_enc, st->arch, &dummy);\n        prefill=1;\n    }\n\n    /* Automatic (rate-dependent) bandwidth selection */\n    if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch)\n    {\n        const opus_int32 *voice_bandwidth_thresholds, *music_bandwidth_thresholds;\n        opus_int32 bandwidth_thresholds[8];\n        int bandwidth = OPUS_BANDWIDTH_FULLBAND;\n        opus_int32 equiv_rate2;\n\n        equiv_rate2 = equiv_rate;\n        if (st->mode != MODE_CELT_ONLY)\n        {\n           /* Adjust the threshold +/- 10% depending on complexity */\n           equiv_rate2 = equiv_rate2 * (45+st->silk_mode.complexity)/50;\n           /* CBR is less efficient by ~1 kb/s */\n           if (!st->use_vbr)\n              equiv_rate2 -= 1000;\n        }\n        if (st->channels==2 && st->force_channels!=1)\n        {\n           voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds;\n           music_bandwidth_thresholds = stereo_music_bandwidth_thresholds;\n        } else {\n           voice_bandwidth_thresholds = mono_voice_bandwidth_thresholds;\n           music_bandwidth_thresholds = mono_music_bandwidth_thresholds;\n        }\n        /* Interpolate bandwidth thresholds depending on voice estimation */\n        for (i=0;i<8;i++)\n        {\n           bandwidth_thresholds[i] = music_bandwidth_thresholds[i]\n                    + ((voice_est*voice_est*(voice_bandwidth_thresholds[i]-music_bandwidth_thresholds[i]))>>14);\n        }\n        do {\n            int threshold, hysteresis;\n            threshold = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)];\n            hysteresis = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)+1];\n            if (!st->first)\n            {\n                if (st->bandwidth >= bandwidth)\n                    threshold -= hysteresis;\n                else\n                    threshold += hysteresis;\n            }\n            if (equiv_rate2 >= threshold)\n                break;\n        } while (--bandwidth>OPUS_BANDWIDTH_NARROWBAND);\n        st->bandwidth = bandwidth;\n        /* Prevents any transition to SWB/FB until the SILK layer has fully\n           switched to WB mode and turned the variable LP filter off */\n        if (!st->first && st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)\n            st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;\n    }\n\n    if (st->bandwidth>st->max_bandwidth)\n       st->bandwidth = st->max_bandwidth;\n\n    if (st->user_bandwidth != OPUS_AUTO)\n        st->bandwidth = st->user_bandwidth;\n\n    /* This prevents us from using hybrid at unsafe CBR/max rates */\n    if (st->mode != MODE_CELT_ONLY && max_rate < 15000)\n    {\n       st->bandwidth = IMIN(st->bandwidth, OPUS_BANDWIDTH_WIDEBAND);\n    }\n\n    /* Prevents Opus from wasting bits on frequencies that are above\n       the Nyquist rate of the input signal */\n    if (st->Fs <= 24000 && st->bandwidth > OPUS_BANDWIDTH_SUPERWIDEBAND)\n        st->bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;\n    if (st->Fs <= 16000 && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)\n        st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;\n    if (st->Fs <= 12000 && st->bandwidth > OPUS_BANDWIDTH_MEDIUMBAND)\n        st->bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;\n    if (st->Fs <= 8000 && st->bandwidth > OPUS_BANDWIDTH_NARROWBAND)\n        st->bandwidth = OPUS_BANDWIDTH_NARROWBAND;\n#ifndef DISABLE_FLOAT_API\n    /* Use detected bandwidth to reduce the encoded bandwidth. */\n    if (st->detected_bandwidth && st->user_bandwidth == OPUS_AUTO)\n    {\n       int min_detected_bandwidth;\n       /* Makes bandwidth detection more conservative just in case the detector\n          gets it wrong when we could have coded a high bandwidth transparently.\n          When operating in SILK/hybrid mode, we don't go below wideband to avoid\n          more complicated switches that require redundancy. */\n       if (equiv_rate <= 18000*st->stream_channels && st->mode == MODE_CELT_ONLY)\n          min_detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND;\n       else if (equiv_rate <= 24000*st->stream_channels && st->mode == MODE_CELT_ONLY)\n          min_detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;\n       else if (equiv_rate <= 30000*st->stream_channels)\n          min_detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND;\n       else if (equiv_rate <= 44000*st->stream_channels)\n          min_detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;\n       else\n          min_detected_bandwidth = OPUS_BANDWIDTH_FULLBAND;\n\n       st->detected_bandwidth = IMAX(st->detected_bandwidth, min_detected_bandwidth);\n       st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth);\n    }\n#endif\n    celt_encoder_ctl(celt_enc, OPUS_SET_LSB_DEPTH(lsb_depth));\n\n    /* CELT mode doesn't support mediumband, use wideband instead */\n    if (st->mode == MODE_CELT_ONLY && st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)\n        st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;\n    if (st->lfe)\n       st->bandwidth = OPUS_BANDWIDTH_NARROWBAND;\n\n    /* Can't support higher than wideband for >20 ms frames */\n    if (frame_size > st->Fs/50 && (st->mode == MODE_CELT_ONLY || st->bandwidth > OPUS_BANDWIDTH_WIDEBAND))\n    {\n       VARDECL(unsigned char, tmp_data);\n       int nb_frames;\n       int bak_mode, bak_bandwidth, bak_channels, bak_to_mono;\n       VARDECL(OpusRepacketizer, rp);\n       opus_int32 bytes_per_frame;\n       opus_int32 repacketize_len;\n\n#ifndef DISABLE_FLOAT_API\n       if (analysis_read_pos_bak!= -1)\n       {\n          st->analysis.read_pos = analysis_read_pos_bak;\n          st->analysis.read_subframe = analysis_read_subframe_bak;\n       }\n#endif\n\n       nb_frames = frame_size > st->Fs/25 ? 3 : 2;\n       bytes_per_frame = IMIN(1276,(out_data_bytes-3)/nb_frames);\n\n       ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char);\n\n       ALLOC(rp, 1, OpusRepacketizer);\n       opus_repacketizer_init(rp);\n\n       bak_mode = st->user_forced_mode;\n       bak_bandwidth = st->user_bandwidth;\n       bak_channels = st->force_channels;\n\n       st->user_forced_mode = st->mode;\n       st->user_bandwidth = st->bandwidth;\n       st->force_channels = st->stream_channels;\n       bak_to_mono = st->silk_mode.toMono;\n\n       if (bak_to_mono)\n          st->force_channels = 1;\n       else\n          st->prev_channels = st->stream_channels;\n       for (i=0;i<nb_frames;i++)\n       {\n          int tmp_len;\n          st->silk_mode.toMono = 0;\n          /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */\n          if (to_celt && i==nb_frames-1)\n             st->user_forced_mode = MODE_CELT_ONLY;\n          tmp_len = opus_encode_native(st, pcm+i*(st->channels*st->Fs/50), st->Fs/50,\n                tmp_data+i*bytes_per_frame, bytes_per_frame, lsb_depth,\n                NULL, 0, c1, c2, analysis_channels, downmix, float_api);\n          if (tmp_len<0)\n          {\n             RESTORE_STACK;\n             return OPUS_INTERNAL_ERROR;\n          }\n          ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len);\n          if (ret<0)\n          {\n             RESTORE_STACK;\n             return OPUS_INTERNAL_ERROR;\n          }\n       }\n       if (st->use_vbr)\n          repacketize_len = out_data_bytes;\n       else\n          repacketize_len = IMIN(3*st->bitrate_bps/(3*8*50/nb_frames), out_data_bytes);\n       ret = opus_repacketizer_out_range_impl(rp, 0, nb_frames, data, repacketize_len, 0, !st->use_vbr);\n       if (ret<0)\n       {\n          RESTORE_STACK;\n          return OPUS_INTERNAL_ERROR;\n       }\n       st->user_forced_mode = bak_mode;\n       st->user_bandwidth = bak_bandwidth;\n       st->force_channels = bak_channels;\n       st->silk_mode.toMono = bak_to_mono;\n       RESTORE_STACK;\n       return ret;\n    }\n    curr_bandwidth = st->bandwidth;\n\n    /* Chooses the appropriate mode for speech\n       *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */\n    if (st->mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND)\n        st->mode = MODE_HYBRID;\n    if (st->mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND)\n        st->mode = MODE_SILK_ONLY;\n\n    /* printf(\"%d %d %d %d\\n\", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */\n    bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;\n\n    data += 1;\n\n    ec_enc_init(&enc, data, max_data_bytes-1);\n\n    ALLOC(pcm_buf, (total_buffer+frame_size)*st->channels, opus_val16);\n    OPUS_COPY(pcm_buf, &st->delay_buffer[(st->encoder_buffer-total_buffer)*st->channels], total_buffer*st->channels);\n\n    if (st->mode == MODE_CELT_ONLY)\n       hp_freq_smth1 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );\n    else\n       hp_freq_smth1 = ((silk_encoder*)silk_enc)->state_Fxx[0].sCmn.variable_HP_smth1_Q15;\n\n    st->variable_HP_smth2_Q15 = silk_SMLAWB( st->variable_HP_smth2_Q15,\n          hp_freq_smth1 - st->variable_HP_smth2_Q15, SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF2, 16 ) );\n\n    /* convert from log scale to Hertz */\n    cutoff_Hz = silk_log2lin( silk_RSHIFT( st->variable_HP_smth2_Q15, 8 ) );\n\n    if (st->application == OPUS_APPLICATION_VOIP)\n    {\n       hp_cutoff(pcm, cutoff_Hz, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);\n    } else {\n       dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);\n    }\n#ifndef FIXED_POINT\n    if (float_api)\n    {\n       opus_val32 sum;\n       sum = celt_inner_prod(&pcm_buf[total_buffer*st->channels], &pcm_buf[total_buffer*st->channels], frame_size*st->channels, st->arch);\n       /* This should filter out both NaNs and ridiculous signals that could\n          cause NaNs further down. */\n       if (!(sum < 1e9f) || celt_isnan(sum))\n       {\n          OPUS_CLEAR(&pcm_buf[total_buffer*st->channels], frame_size*st->channels);\n          st->hp_mem[0] = st->hp_mem[1] = st->hp_mem[2] = st->hp_mem[3] = 0;\n       }\n    }\n#endif\n\n\n    /* SILK processing */\n    HB_gain = Q15ONE;\n    if (st->mode != MODE_CELT_ONLY)\n    {\n        opus_int32 total_bitRate, celt_rate;\n#ifdef FIXED_POINT\n       const opus_int16 *pcm_silk;\n#else\n       VARDECL(opus_int16, pcm_silk);\n       ALLOC(pcm_silk, st->channels*frame_size, opus_int16);\n#endif\n\n        /* Distribute bits between SILK and CELT */\n        total_bitRate = 8 * bytes_target * frame_rate;\n        if( st->mode == MODE_HYBRID ) {\n            int HB_gain_ref;\n            /* Base rate for SILK */\n            st->silk_mode.bitRate = st->stream_channels * ( 5000 + 1000 * ( st->Fs == 100 * frame_size ) );\n            if( curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND ) {\n                /* SILK gets 2/3 of the remaining bits */\n                st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 2 / 3;\n            } else { /* FULLBAND */\n                /* SILK gets 3/5 of the remaining bits */\n                st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 3 / 5;\n            }\n            /* Don't let SILK use more than 80% */\n            if( st->silk_mode.bitRate > total_bitRate * 4/5 ) {\n                st->silk_mode.bitRate = total_bitRate * 4/5;\n            }\n            if (!st->energy_masking)\n            {\n               /* Increasingly attenuate high band when it gets allocated fewer bits */\n               celt_rate = total_bitRate - st->silk_mode.bitRate;\n               HB_gain_ref = (curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND) ? 3000 : 3600;\n               HB_gain = SHL32((opus_val32)celt_rate, 9) / SHR32((opus_val32)celt_rate + st->stream_channels * HB_gain_ref, 6);\n               HB_gain = HB_gain < Q15ONE*6/7 ? HB_gain + Q15ONE/7 : Q15ONE;\n            }\n        } else {\n            /* SILK gets all bits */\n            st->silk_mode.bitRate = total_bitRate;\n        }\n\n        /* Surround masking for SILK */\n        if (st->energy_masking && st->use_vbr && !st->lfe)\n        {\n           opus_val32 mask_sum=0;\n           opus_val16 masking_depth;\n           opus_int32 rate_offset;\n           int c;\n           int end = 17;\n           opus_int16 srate = 16000;\n           if (st->bandwidth == OPUS_BANDWIDTH_NARROWBAND)\n           {\n              end = 13;\n              srate = 8000;\n           } else if (st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)\n           {\n              end = 15;\n              srate = 12000;\n           }\n           for (c=0;c<st->channels;c++)\n           {\n              for(i=0;i<end;i++)\n              {\n                 opus_val16 mask;\n                 mask = MAX16(MIN16(st->energy_masking[21*c+i],\n                        QCONST16(.5f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT));\n                 if (mask > 0)\n                    mask = HALF16(mask);\n                 mask_sum += mask;\n              }\n           }\n           /* Conservative rate reduction, we cut the masking in half */\n           masking_depth = mask_sum / end*st->channels;\n           masking_depth += QCONST16(.2f, DB_SHIFT);\n           rate_offset = (opus_int32)PSHR32(MULT16_16(srate, masking_depth), DB_SHIFT);\n           rate_offset = MAX32(rate_offset, -2*st->silk_mode.bitRate/3);\n           /* Split the rate change between the SILK and CELT part for hybrid. */\n           if (st->bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND || st->bandwidth==OPUS_BANDWIDTH_FULLBAND)\n              st->silk_mode.bitRate += 3*rate_offset/5;\n           else\n              st->silk_mode.bitRate += rate_offset;\n           bytes_target += rate_offset * frame_size / (8 * st->Fs);\n        }\n\n        st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;\n        st->silk_mode.nChannelsAPI = st->channels;\n        st->silk_mode.nChannelsInternal = st->stream_channels;\n        if (curr_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {\n            st->silk_mode.desiredInternalSampleRate = 8000;\n        } else if (curr_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {\n            st->silk_mode.desiredInternalSampleRate = 12000;\n        } else {\n            silk_assert( st->mode == MODE_HYBRID || curr_bandwidth == OPUS_BANDWIDTH_WIDEBAND );\n            st->silk_mode.desiredInternalSampleRate = 16000;\n        }\n        if( st->mode == MODE_HYBRID ) {\n            /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */\n            st->silk_mode.minInternalSampleRate = 16000;\n        } else {\n            st->silk_mode.minInternalSampleRate = 8000;\n        }\n\n        if (st->mode == MODE_SILK_ONLY)\n        {\n           opus_int32 effective_max_rate = max_rate;\n           st->silk_mode.maxInternalSampleRate = 16000;\n           if (frame_rate > 50)\n              effective_max_rate = effective_max_rate*2/3;\n           if (effective_max_rate < 13000)\n           {\n              st->silk_mode.maxInternalSampleRate = 12000;\n              st->silk_mode.desiredInternalSampleRate = IMIN(12000, st->silk_mode.desiredInternalSampleRate);\n           }\n           if (effective_max_rate < 9600)\n           {\n              st->silk_mode.maxInternalSampleRate = 8000;\n              st->silk_mode.desiredInternalSampleRate = IMIN(8000, st->silk_mode.desiredInternalSampleRate);\n           }\n        } else {\n           st->silk_mode.maxInternalSampleRate = 16000;\n        }\n\n        st->silk_mode.useCBR = !st->use_vbr;\n\n        /* Call SILK encoder for the low band */\n        nBytes = IMIN(1275, max_data_bytes-1-redundancy_bytes);\n\n        st->silk_mode.maxBits = nBytes*8;\n        /* Only allow up to 90% of the bits for hybrid mode*/\n        if (st->mode == MODE_HYBRID)\n           st->silk_mode.maxBits = (opus_int32)st->silk_mode.maxBits*9/10;\n        if (st->silk_mode.useCBR)\n        {\n           st->silk_mode.maxBits = (st->silk_mode.bitRate * frame_size / (st->Fs * 8))*8;\n           /* Reduce the initial target to make it easier to reach the CBR rate */\n           st->silk_mode.bitRate = IMAX(1, st->silk_mode.bitRate-2000);\n        }\n\n        if (prefill)\n        {\n            opus_int32 zero=0;\n            int prefill_offset;\n            /* Use a smooth onset for the SILK prefill to avoid the encoder trying to encode\n               a discontinuity. The exact location is what we need to avoid leaving any \"gap\"\n               in the audio when mixing with the redundant CELT frame. Here we can afford to\n               overwrite st->delay_buffer because the only thing that uses it before it gets\n               rewritten is tmp_prefill[] and even then only the part after the ramp really\n               gets used (rather than sent to the encoder and discarded) */\n            prefill_offset = st->channels*(st->encoder_buffer-st->delay_compensation-st->Fs/400);\n            gain_fade(st->delay_buffer+prefill_offset, st->delay_buffer+prefill_offset,\n                  0, Q15ONE, celt_mode->overlap, st->Fs/400, st->channels, celt_mode->window, st->Fs);\n            OPUS_CLEAR(st->delay_buffer, prefill_offset);\n#ifdef FIXED_POINT\n            pcm_silk = st->delay_buffer;\n#else\n            for (i=0;i<st->encoder_buffer*st->channels;i++)\n                pcm_silk[i] = FLOAT2INT16(st->delay_buffer[i]);\n#endif\n            silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, 1 );\n        }\n\n#ifdef FIXED_POINT\n        pcm_silk = pcm_buf+total_buffer*st->channels;\n#else\n        for (i=0;i<frame_size*st->channels;i++)\n            pcm_silk[i] = FLOAT2INT16(pcm_buf[total_buffer*st->channels + i]);\n#endif\n        ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0 );\n        if( ret ) {\n            /*fprintf (stderr, \"SILK encode error: %d\\n\", ret);*/\n            /* Handle error */\n           RESTORE_STACK;\n           return OPUS_INTERNAL_ERROR;\n        }\n        if (nBytes==0)\n        {\n           st->rangeFinal = 0;\n           data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);\n           RESTORE_STACK;\n           return 1;\n        }\n        /* Extract SILK internal bandwidth for signaling in first byte */\n        if( st->mode == MODE_SILK_ONLY ) {\n            if( st->silk_mode.internalSampleRate == 8000 ) {\n               curr_bandwidth = OPUS_BANDWIDTH_NARROWBAND;\n            } else if( st->silk_mode.internalSampleRate == 12000 ) {\n               curr_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;\n            } else if( st->silk_mode.internalSampleRate == 16000 ) {\n               curr_bandwidth = OPUS_BANDWIDTH_WIDEBAND;\n            }\n        } else {\n            silk_assert( st->silk_mode.internalSampleRate == 16000 );\n        }\n\n        st->silk_mode.opusCanSwitch = st->silk_mode.switchReady;\n        /* FIXME: How do we allocate the redundancy for CBR? */\n        if (st->silk_mode.opusCanSwitch)\n        {\n           redundancy = 1;\n           celt_to_silk = 0;\n           st->silk_bw_switch = 1;\n        }\n    }\n\n    /* CELT processing */\n    {\n        int endband=21;\n\n        switch(curr_bandwidth)\n        {\n            case OPUS_BANDWIDTH_NARROWBAND:\n                endband = 13;\n                break;\n            case OPUS_BANDWIDTH_MEDIUMBAND:\n            case OPUS_BANDWIDTH_WIDEBAND:\n                endband = 17;\n                break;\n            case OPUS_BANDWIDTH_SUPERWIDEBAND:\n                endband = 19;\n                break;\n            case OPUS_BANDWIDTH_FULLBAND:\n                endband = 21;\n                break;\n        }\n        celt_encoder_ctl(celt_enc, CELT_SET_END_BAND(endband));\n        celt_encoder_ctl(celt_enc, CELT_SET_CHANNELS(st->stream_channels));\n    }\n    celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));\n    if (st->mode != MODE_SILK_ONLY)\n    {\n        opus_val32 celt_pred=2;\n        celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));\n        /* We may still decide to disable prediction later */\n        if (st->silk_mode.reducedDependency)\n           celt_pred = 0;\n        celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(celt_pred));\n\n        if (st->mode == MODE_HYBRID)\n        {\n            int len;\n\n            len = (ec_tell(&enc)+7)>>3;\n            if (redundancy)\n               len += st->mode == MODE_HYBRID ? 3 : 1;\n            if( st->use_vbr ) {\n                nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs);\n            } else {\n                /* check if SILK used up too much */\n                nb_compr_bytes = len > bytes_target ? len : bytes_target;\n            }\n        } else {\n            if (st->use_vbr)\n            {\n                opus_int32 bonus=0;\n#ifndef DISABLE_FLOAT_API\n                if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != st->Fs/50)\n                {\n                   bonus = (60*st->stream_channels+40)*(st->Fs/frame_size-50);\n                   if (analysis_info.valid)\n                      bonus = (opus_int32)(bonus*(1.f+.5f*analysis_info.tonality));\n                }\n#endif\n                celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1));\n                celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint));\n                celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps+bonus));\n                nb_compr_bytes = max_data_bytes-1-redundancy_bytes;\n            } else {\n                nb_compr_bytes = bytes_target;\n            }\n        }\n\n    } else {\n        nb_compr_bytes = 0;\n    }\n\n    ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_val16);\n    if (st->mode != MODE_SILK_ONLY && st->mode != st->prev_mode && st->prev_mode > 0)\n    {\n       OPUS_COPY(tmp_prefill, &st->delay_buffer[(st->encoder_buffer-total_buffer-st->Fs/400)*st->channels], st->channels*st->Fs/400);\n    }\n\n    if (st->channels*(st->encoder_buffer-(frame_size+total_buffer)) > 0)\n    {\n       OPUS_MOVE(st->delay_buffer, &st->delay_buffer[st->channels*frame_size], st->channels*(st->encoder_buffer-frame_size-total_buffer));\n       OPUS_COPY(&st->delay_buffer[st->channels*(st->encoder_buffer-frame_size-total_buffer)],\n             &pcm_buf[0],\n             (frame_size+total_buffer)*st->channels);\n    } else {\n       OPUS_COPY(st->delay_buffer, &pcm_buf[(frame_size+total_buffer-st->encoder_buffer)*st->channels], st->encoder_buffer*st->channels);\n    }\n    /* gain_fade() and stereo_fade() need to be after the buffer copying\n       because we don't want any of this to affect the SILK part */\n    if( st->prev_HB_gain < Q15ONE || HB_gain < Q15ONE ) {\n       gain_fade(pcm_buf, pcm_buf,\n             st->prev_HB_gain, HB_gain, celt_mode->overlap, frame_size, st->channels, celt_mode->window, st->Fs);\n    }\n    st->prev_HB_gain = HB_gain;\n    if (st->mode != MODE_HYBRID || st->stream_channels==1)\n       st->silk_mode.stereoWidth_Q14 = IMIN((1<<14),2*IMAX(0,equiv_rate-30000));\n    if( !st->energy_masking && st->channels == 2 ) {\n        /* Apply stereo width reduction (at low bitrates) */\n        if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) {\n            opus_val16 g1, g2;\n            g1 = st->hybrid_stereo_width_Q14;\n            g2 = (opus_val16)(st->silk_mode.stereoWidth_Q14);\n#ifdef FIXED_POINT\n            g1 = g1==16384 ? Q15ONE : SHL16(g1,1);\n            g2 = g2==16384 ? Q15ONE : SHL16(g2,1);\n#else\n            g1 *= (1.f/16384);\n            g2 *= (1.f/16384);\n#endif\n            stereo_fade(pcm_buf, pcm_buf, g1, g2, celt_mode->overlap,\n                  frame_size, st->channels, celt_mode->window, st->Fs);\n            st->hybrid_stereo_width_Q14 = st->silk_mode.stereoWidth_Q14;\n        }\n    }\n\n    if ( st->mode != MODE_CELT_ONLY && ec_tell(&enc)+17+20*(st->mode == MODE_HYBRID) <= 8*(max_data_bytes-1))\n    {\n        /* For SILK mode, the redundancy is inferred from the length */\n        if (st->mode == MODE_HYBRID && (redundancy || ec_tell(&enc)+37 <= 8*nb_compr_bytes))\n           ec_enc_bit_logp(&enc, redundancy, 12);\n        if (redundancy)\n        {\n            int max_redundancy;\n            ec_enc_bit_logp(&enc, celt_to_silk, 1);\n            if (st->mode == MODE_HYBRID)\n               max_redundancy = (max_data_bytes-1)-nb_compr_bytes;\n            else\n               max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+7)>>3);\n            /* Target the same bit-rate for redundancy as for the rest,\n               up to a max of 257 bytes */\n            redundancy_bytes = IMIN(max_redundancy, st->bitrate_bps/1600);\n            redundancy_bytes = IMIN(257, IMAX(2, redundancy_bytes));\n            if (st->mode == MODE_HYBRID)\n                ec_enc_uint(&enc, redundancy_bytes-2, 256);\n        }\n    } else {\n        redundancy = 0;\n    }\n\n    if (!redundancy)\n    {\n       st->silk_bw_switch = 0;\n       redundancy_bytes = 0;\n    }\n    if (st->mode != MODE_CELT_ONLY)start_band=17;\n\n    if (st->mode == MODE_SILK_ONLY)\n    {\n        ret = (ec_tell(&enc)+7)>>3;\n        ec_enc_done(&enc);\n        nb_compr_bytes = ret;\n    } else {\n       nb_compr_bytes = IMIN((max_data_bytes-1)-redundancy_bytes, nb_compr_bytes);\n       ec_enc_shrink(&enc, nb_compr_bytes);\n    }\n\n#ifndef DISABLE_FLOAT_API\n    if (redundancy || st->mode != MODE_SILK_ONLY)\n       celt_encoder_ctl(celt_enc, CELT_SET_ANALYSIS(&analysis_info));\n#endif\n\n    /* 5 ms redundant frame for CELT->SILK */\n    if (redundancy && celt_to_silk)\n    {\n        int err;\n        celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));\n        celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));\n        err = celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL);\n        if (err < 0)\n        {\n           RESTORE_STACK;\n           return OPUS_INTERNAL_ERROR;\n        }\n        celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng));\n        celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);\n    }\n\n    celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(start_band));\n\n    if (st->mode != MODE_SILK_ONLY)\n    {\n        if (st->mode != st->prev_mode && st->prev_mode > 0)\n        {\n           unsigned char dummy[2];\n           celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);\n\n           /* Prefilling */\n           celt_encode_with_ec(celt_enc, tmp_prefill, st->Fs/400, dummy, 2, NULL);\n           celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));\n        }\n        /* If false, we already busted the budget and we'll end up with a \"PLC packet\" */\n        if (ec_tell(&enc) <= 8*nb_compr_bytes)\n        {\n           ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);\n           if (ret < 0)\n           {\n              RESTORE_STACK;\n              return OPUS_INTERNAL_ERROR;\n           }\n        }\n    }\n\n    /* 5 ms redundant frame for SILK->CELT */\n    if (redundancy && !celt_to_silk)\n    {\n        int err;\n        unsigned char dummy[2];\n        int N2, N4;\n        N2 = st->Fs/200;\n        N4 = st->Fs/400;\n\n        celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);\n        celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));\n        celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));\n\n        /* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */\n        celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, dummy, 2, NULL);\n\n        err = celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes, NULL);\n        if (err < 0)\n        {\n           RESTORE_STACK;\n           return OPUS_INTERNAL_ERROR;\n        }\n        celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng));\n    }\n\n\n\n    /* Signalling the mode in the first byte */\n    data--;\n    data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);\n\n    st->rangeFinal = enc.rng ^ redundant_rng;\n\n    if (to_celt)\n        st->prev_mode = MODE_CELT_ONLY;\n    else\n        st->prev_mode = st->mode;\n    st->prev_channels = st->stream_channels;\n    st->prev_framesize = frame_size;\n\n    st->first = 0;\n\n    /* In the unlikely case that the SILK encoder busted its target, tell\n       the decoder to call the PLC */\n    if (ec_tell(&enc) > (max_data_bytes-1)*8)\n    {\n       if (max_data_bytes < 2)\n       {\n          RESTORE_STACK;\n          return OPUS_BUFFER_TOO_SMALL;\n       }\n       data[1] = 0;\n       ret = 1;\n       st->rangeFinal = 0;\n    } else if (st->mode==MODE_SILK_ONLY&&!redundancy)\n    {\n       /*When in LPC only mode it's perfectly\n         reasonable to strip off trailing zero bytes as\n         the required range decoder behavior is to\n         fill these in. This can't be done when the MDCT\n         modes are used because the decoder needs to know\n         the actual length for allocation purposes.*/\n       while(ret>2&&data[ret]==0)ret--;\n    }\n    /* Count ToC and redundancy */\n    ret += 1+redundancy_bytes;\n    if (!st->use_vbr)\n    {\n       if (opus_packet_pad(data, ret, max_data_bytes) != OPUS_OK)\n\n       {\n          RESTORE_STACK;\n          return OPUS_INTERNAL_ERROR;\n       }\n       ret = max_data_bytes;\n    }\n    RESTORE_STACK;\n    return ret;\n}\n\n#ifdef FIXED_POINT\n\n#ifndef DISABLE_FLOAT_API\nopus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size,\n      unsigned char *data, opus_int32 max_data_bytes)\n{\n   int i, ret;\n   int frame_size;\n   int delay_compensation;\n   VARDECL(opus_int16, in);\n   ALLOC_STACK;\n\n   if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)\n      delay_compensation = 0;\n   else\n      delay_compensation = st->delay_compensation;\n   frame_size = compute_frame_size(pcm, analysis_frame_size,\n         st->variable_duration, st->channels, st->Fs, st->bitrate_bps,\n         delay_compensation, downmix_float, st->analysis.subframe_mem);\n\n   ALLOC(in, frame_size*st->channels, opus_int16);\n\n   for (i=0;i<frame_size*st->channels;i++)\n      in[i] = FLOAT2INT16(pcm[i]);\n   ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16,\n                            pcm, analysis_frame_size, 0, -2, st->channels, downmix_float, 1);\n   RESTORE_STACK;\n   return ret;\n}\n#endif\n\nopus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size,\n                unsigned char *data, opus_int32 out_data_bytes)\n{\n   int frame_size;\n   int delay_compensation;\n   if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)\n      delay_compensation = 0;\n   else\n      delay_compensation = st->delay_compensation;\n   frame_size = compute_frame_size(pcm, analysis_frame_size,\n         st->variable_duration, st->channels, st->Fs, st->bitrate_bps,\n         delay_compensation, downmix_int\n#ifndef DISABLE_FLOAT_API\n         , st->analysis.subframe_mem\n#endif\n         );\n   return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 16,\n                             pcm, analysis_frame_size, 0, -2, st->channels, downmix_int, 0);\n}\n\n#else\nopus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size,\n      unsigned char *data, opus_int32 max_data_bytes)\n{\n   int i, ret;\n   int frame_size;\n   int delay_compensation;\n   VARDECL(float, in);\n   ALLOC_STACK;\n\n   if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)\n      delay_compensation = 0;\n   else\n      delay_compensation = st->delay_compensation;\n   frame_size = compute_frame_size(pcm, analysis_frame_size,\n         st->variable_duration, st->channels, st->Fs, st->bitrate_bps,\n         delay_compensation, downmix_int, st->analysis.subframe_mem);\n\n   ALLOC(in, frame_size*st->channels, float);\n\n   for (i=0;i<frame_size*st->channels;i++)\n      in[i] = (1.0f/32768)*pcm[i];\n   ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16,\n                            pcm, analysis_frame_size, 0, -2, st->channels, downmix_int, 0);\n   RESTORE_STACK;\n   return ret;\n}\nopus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size,\n                      unsigned char *data, opus_int32 out_data_bytes)\n{\n   int frame_size;\n   int delay_compensation;\n   if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)\n      delay_compensation = 0;\n   else\n      delay_compensation = st->delay_compensation;\n   frame_size = compute_frame_size(pcm, analysis_frame_size,\n         st->variable_duration, st->channels, st->Fs, st->bitrate_bps,\n         delay_compensation, downmix_float, st->analysis.subframe_mem);\n   return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 24,\n                             pcm, analysis_frame_size, 0, -2, st->channels, downmix_float, 1);\n}\n#endif\n\n\nint opus_encoder_ctl(OpusEncoder *st, int request, ...)\n{\n    int ret;\n    CELTEncoder *celt_enc;\n    va_list ap;\n\n    ret = OPUS_OK;\n    va_start(ap, request);\n\n    celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);\n\n    switch (request)\n    {\n        case OPUS_SET_APPLICATION_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if (   (value != OPUS_APPLICATION_VOIP && value != OPUS_APPLICATION_AUDIO\n                 && value != OPUS_APPLICATION_RESTRICTED_LOWDELAY)\n               || (!st->first && st->application != value))\n            {\n               ret = OPUS_BAD_ARG;\n               break;\n            }\n            st->application = value;\n        }\n        break;\n        case OPUS_GET_APPLICATION_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->application;\n        }\n        break;\n        case OPUS_SET_BITRATE_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)\n            {\n                if (value <= 0)\n                    goto bad_arg;\n                else if (value <= 500)\n                    value = 500;\n                else if (value > (opus_int32)300000*st->channels)\n                    value = (opus_int32)300000*st->channels;\n            }\n            st->user_bitrate_bps = value;\n        }\n        break;\n        case OPUS_GET_BITRATE_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = user_bitrate_to_bitrate(st, st->prev_framesize, 1276);\n        }\n        break;\n        case OPUS_SET_FORCE_CHANNELS_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if((value<1 || value>st->channels) && value != OPUS_AUTO)\n            {\n               goto bad_arg;\n            }\n            st->force_channels = value;\n        }\n        break;\n        case OPUS_GET_FORCE_CHANNELS_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->force_channels;\n        }\n        break;\n        case OPUS_SET_MAX_BANDWIDTH_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND)\n            {\n               goto bad_arg;\n            }\n            st->max_bandwidth = value;\n            if (st->max_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {\n                st->silk_mode.maxInternalSampleRate = 8000;\n            } else if (st->max_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {\n                st->silk_mode.maxInternalSampleRate = 12000;\n            } else {\n                st->silk_mode.maxInternalSampleRate = 16000;\n            }\n        }\n        break;\n        case OPUS_GET_MAX_BANDWIDTH_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->max_bandwidth;\n        }\n        break;\n        case OPUS_SET_BANDWIDTH_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if ((value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) && value != OPUS_AUTO)\n            {\n               goto bad_arg;\n            }\n            st->user_bandwidth = value;\n            if (st->user_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {\n                st->silk_mode.maxInternalSampleRate = 8000;\n            } else if (st->user_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {\n                st->silk_mode.maxInternalSampleRate = 12000;\n            } else {\n                st->silk_mode.maxInternalSampleRate = 16000;\n            }\n        }\n        break;\n        case OPUS_GET_BANDWIDTH_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->bandwidth;\n        }\n        break;\n        case OPUS_SET_DTX_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if(value<0 || value>1)\n            {\n               goto bad_arg;\n            }\n            st->silk_mode.useDTX = value;\n        }\n        break;\n        case OPUS_GET_DTX_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->silk_mode.useDTX;\n        }\n        break;\n        case OPUS_SET_COMPLEXITY_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if(value<0 || value>10)\n            {\n               goto bad_arg;\n            }\n            st->silk_mode.complexity = value;\n            celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value));\n        }\n        break;\n        case OPUS_GET_COMPLEXITY_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->silk_mode.complexity;\n        }\n        break;\n        case OPUS_SET_INBAND_FEC_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if(value<0 || value>1)\n            {\n               goto bad_arg;\n            }\n            st->silk_mode.useInBandFEC = value;\n        }\n        break;\n        case OPUS_GET_INBAND_FEC_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->silk_mode.useInBandFEC;\n        }\n        break;\n        case OPUS_SET_PACKET_LOSS_PERC_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if (value < 0 || value > 100)\n            {\n               goto bad_arg;\n            }\n            st->silk_mode.packetLossPercentage = value;\n            celt_encoder_ctl(celt_enc, OPUS_SET_PACKET_LOSS_PERC(value));\n        }\n        break;\n        case OPUS_GET_PACKET_LOSS_PERC_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->silk_mode.packetLossPercentage;\n        }\n        break;\n        case OPUS_SET_VBR_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if(value<0 || value>1)\n            {\n               goto bad_arg;\n            }\n            st->use_vbr = value;\n            st->silk_mode.useCBR = 1-value;\n        }\n        break;\n        case OPUS_GET_VBR_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->use_vbr;\n        }\n        break;\n        case OPUS_SET_VOICE_RATIO_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if (value<-1 || value>100)\n            {\n               goto bad_arg;\n            }\n            st->voice_ratio = value;\n        }\n        break;\n        case OPUS_GET_VOICE_RATIO_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->voice_ratio;\n        }\n        break;\n        case OPUS_SET_VBR_CONSTRAINT_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if(value<0 || value>1)\n            {\n               goto bad_arg;\n            }\n            st->vbr_constraint = value;\n        }\n        break;\n        case OPUS_GET_VBR_CONSTRAINT_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->vbr_constraint;\n        }\n        break;\n        case OPUS_SET_SIGNAL_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if(value!=OPUS_AUTO && value!=OPUS_SIGNAL_VOICE && value!=OPUS_SIGNAL_MUSIC)\n            {\n               goto bad_arg;\n            }\n            st->signal_type = value;\n        }\n        break;\n        case OPUS_GET_SIGNAL_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->signal_type;\n        }\n        break;\n        case OPUS_GET_LOOKAHEAD_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->Fs/400;\n            if (st->application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)\n                *value += st->delay_compensation;\n        }\n        break;\n        case OPUS_GET_SAMPLE_RATE_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->Fs;\n        }\n        break;\n        case OPUS_GET_FINAL_RANGE_REQUEST:\n        {\n            opus_uint32 *value = va_arg(ap, opus_uint32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->rangeFinal;\n        }\n        break;\n        case OPUS_SET_LSB_DEPTH_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if (value<8 || value>24)\n            {\n               goto bad_arg;\n            }\n            st->lsb_depth=value;\n        }\n        break;\n        case OPUS_GET_LSB_DEPTH_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->lsb_depth;\n        }\n        break;\n        case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if (value != OPUS_FRAMESIZE_ARG   && value != OPUS_FRAMESIZE_2_5_MS &&\n                value != OPUS_FRAMESIZE_5_MS  && value != OPUS_FRAMESIZE_10_MS  &&\n                value != OPUS_FRAMESIZE_20_MS && value != OPUS_FRAMESIZE_40_MS  &&\n                value != OPUS_FRAMESIZE_60_MS && value != OPUS_FRAMESIZE_VARIABLE)\n            {\n               goto bad_arg;\n            }\n            st->variable_duration = value;\n            celt_encoder_ctl(celt_enc, OPUS_SET_EXPERT_FRAME_DURATION(value));\n        }\n        break;\n        case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:\n        {\n            opus_int32 *value = va_arg(ap, opus_int32*);\n            if (!value)\n            {\n               goto bad_arg;\n            }\n            *value = st->variable_duration;\n        }\n        break;\n        case OPUS_SET_PREDICTION_DISABLED_REQUEST:\n        {\n           opus_int32 value = va_arg(ap, opus_int32);\n           if (value > 1 || value < 0)\n              goto bad_arg;\n           st->silk_mode.reducedDependency = value;\n        }\n        break;\n        case OPUS_GET_PREDICTION_DISABLED_REQUEST:\n        {\n           opus_int32 *value = va_arg(ap, opus_int32*);\n           if (!value)\n              goto bad_arg;\n           *value = st->silk_mode.reducedDependency;\n        }\n        break;\n        case OPUS_RESET_STATE:\n        {\n           void *silk_enc;\n           silk_EncControlStruct dummy;\n           char *start;\n           silk_enc = (char*)st+st->silk_enc_offset;\n#ifndef DISABLE_FLOAT_API\n           tonality_analysis_reset(&st->analysis);\n#endif\n\n           start = (char*)&st->OPUS_ENCODER_RESET_START;\n           OPUS_CLEAR(start, sizeof(OpusEncoder) - (start - (char*)st));\n\n           celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);\n           silk_InitEncoder( silk_enc, st->arch, &dummy );\n           st->stream_channels = st->channels;\n           st->hybrid_stereo_width_Q14 = 1 << 14;\n           st->prev_HB_gain = Q15ONE;\n           st->first = 1;\n           st->mode = MODE_HYBRID;\n           st->bandwidth = OPUS_BANDWIDTH_FULLBAND;\n           st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );\n        }\n        break;\n        case OPUS_SET_FORCE_MODE_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            if ((value < MODE_SILK_ONLY || value > MODE_CELT_ONLY) && value != OPUS_AUTO)\n            {\n               goto bad_arg;\n            }\n            st->user_forced_mode = value;\n        }\n        break;\n        case OPUS_SET_LFE_REQUEST:\n        {\n            opus_int32 value = va_arg(ap, opus_int32);\n            st->lfe = value;\n            ret = celt_encoder_ctl(celt_enc, OPUS_SET_LFE(value));\n        }\n        break;\n        case OPUS_SET_ENERGY_MASK_REQUEST:\n        {\n            opus_val16 *value = va_arg(ap, opus_val16*);\n            st->energy_masking = value;\n            ret = celt_encoder_ctl(celt_enc, OPUS_SET_ENERGY_MASK(value));\n        }\n        break;\n\n        case CELT_GET_MODE_REQUEST:\n        {\n           const CELTMode ** value = va_arg(ap, const CELTMode**);\n           if (!value)\n           {\n              goto bad_arg;\n           }\n           ret = celt_encoder_ctl(celt_enc, CELT_GET_MODE(value));\n        }\n        break;\n        default:\n            /* fprintf(stderr, \"unknown opus_encoder_ctl() request: %d\", request);*/\n            ret = OPUS_UNIMPLEMENTED;\n            break;\n    }\n    va_end(ap);\n    return ret;\nbad_arg:\n    va_end(ap);\n    return OPUS_BAD_ARG;\n}\n\nvoid opus_encoder_destroy(OpusEncoder *st)\n{\n    opus_free(st);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/opus_multistream.c",
    "content": "/* Copyright (c) 2011 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"opus_multistream.h\"\n#include \"opus.h\"\n#include \"opus_private.h\"\n#include \"stack_alloc.h\"\n#include <stdarg.h>\n#include \"float_cast.h\"\n#include \"os_support.h\"\n\n\nint validate_layout(const ChannelLayout *layout)\n{\n   int i, max_channel;\n\n   max_channel = layout->nb_streams+layout->nb_coupled_streams;\n   if (max_channel>255)\n      return 0;\n   for (i=0;i<layout->nb_channels;i++)\n   {\n      if (layout->mapping[i] >= max_channel && layout->mapping[i] != 255)\n         return 0;\n   }\n   return 1;\n}\n\n\nint get_left_channel(const ChannelLayout *layout, int stream_id, int prev)\n{\n   int i;\n   i = (prev<0) ? 0 : prev+1;\n   for (;i<layout->nb_channels;i++)\n   {\n      if (layout->mapping[i]==stream_id*2)\n         return i;\n   }\n   return -1;\n}\n\nint get_right_channel(const ChannelLayout *layout, int stream_id, int prev)\n{\n   int i;\n   i = (prev<0) ? 0 : prev+1;\n   for (;i<layout->nb_channels;i++)\n   {\n      if (layout->mapping[i]==stream_id*2+1)\n         return i;\n   }\n   return -1;\n}\n\nint get_mono_channel(const ChannelLayout *layout, int stream_id, int prev)\n{\n   int i;\n   i = (prev<0) ? 0 : prev+1;\n   for (;i<layout->nb_channels;i++)\n   {\n      if (layout->mapping[i]==stream_id+layout->nb_coupled_streams)\n         return i;\n   }\n   return -1;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/opus_multistream_decoder.c",
    "content": "/* Copyright (c) 2011 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"opus_multistream.h\"\n#include \"opus.h\"\n#include \"opus_private.h\"\n#include \"stack_alloc.h\"\n#include <stdarg.h>\n#include \"float_cast.h\"\n#include \"os_support.h\"\n\nstruct OpusMSDecoder {\n   ChannelLayout layout;\n   /* Decoder states go here */\n};\n\n\n\n\n/* DECODER */\n\nopus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams)\n{\n   int coupled_size;\n   int mono_size;\n\n   if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;\n   coupled_size = opus_decoder_get_size(2);\n   mono_size = opus_decoder_get_size(1);\n   return align(sizeof(OpusMSDecoder))\n         + nb_coupled_streams * align(coupled_size)\n         + (nb_streams-nb_coupled_streams) * align(mono_size);\n}\n\nint opus_multistream_decoder_init(\n      OpusMSDecoder *st,\n      opus_int32 Fs,\n      int channels,\n      int streams,\n      int coupled_streams,\n      const unsigned char *mapping\n)\n{\n   int coupled_size;\n   int mono_size;\n   int i, ret;\n   char *ptr;\n\n   if ((channels>255) || (channels<1) || (coupled_streams>streams) ||\n       (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))\n      return OPUS_BAD_ARG;\n\n   st->layout.nb_channels = channels;\n   st->layout.nb_streams = streams;\n   st->layout.nb_coupled_streams = coupled_streams;\n\n   for (i=0;i<st->layout.nb_channels;i++)\n      st->layout.mapping[i] = mapping[i];\n   if (!validate_layout(&st->layout))\n      return OPUS_BAD_ARG;\n\n   ptr = (char*)st + align(sizeof(OpusMSDecoder));\n   coupled_size = opus_decoder_get_size(2);\n   mono_size = opus_decoder_get_size(1);\n\n   for (i=0;i<st->layout.nb_coupled_streams;i++)\n   {\n      ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2);\n      if(ret!=OPUS_OK)return ret;\n      ptr += align(coupled_size);\n   }\n   for (;i<st->layout.nb_streams;i++)\n   {\n      ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1);\n      if(ret!=OPUS_OK)return ret;\n      ptr += align(mono_size);\n   }\n   return OPUS_OK;\n}\n\n\nOpusMSDecoder *opus_multistream_decoder_create(\n      opus_int32 Fs,\n      int channels,\n      int streams,\n      int coupled_streams,\n      const unsigned char *mapping,\n      int *error\n)\n{\n   int ret;\n   OpusMSDecoder *st;\n   if ((channels>255) || (channels<1) || (coupled_streams>streams) ||\n       (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))\n   {\n      if (error)\n         *error = OPUS_BAD_ARG;\n      return NULL;\n   }\n   st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams));\n   if (st==NULL)\n   {\n      if (error)\n         *error = OPUS_ALLOC_FAIL;\n      return NULL;\n   }\n   ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping);\n   if (error)\n      *error = ret;\n   if (ret != OPUS_OK)\n   {\n      opus_free(st);\n      st = NULL;\n   }\n   return st;\n}\n\ntypedef void (*opus_copy_channel_out_func)(\n  void *dst,\n  int dst_stride,\n  int dst_channel,\n  const opus_val16 *src,\n  int src_stride,\n  int frame_size\n);\n\nstatic int opus_multistream_packet_validate(const unsigned char *data,\n      opus_int32 len, int nb_streams, opus_int32 Fs)\n{\n   int s;\n   int count;\n   unsigned char toc;\n   opus_int16 size[48];\n   int samples=0;\n   opus_int32 packet_offset;\n\n   for (s=0;s<nb_streams;s++)\n   {\n      int tmp_samples;\n      if (len<=0)\n         return OPUS_INVALID_PACKET;\n      count = opus_packet_parse_impl(data, len, s!=nb_streams-1, &toc, NULL,\n                                     size, NULL, &packet_offset);\n      if (count<0)\n         return count;\n      tmp_samples = opus_packet_get_nb_samples(data, packet_offset, Fs);\n      if (s!=0 && samples != tmp_samples)\n         return OPUS_INVALID_PACKET;\n      samples = tmp_samples;\n      data += packet_offset;\n      len -= packet_offset;\n   }\n   return samples;\n}\n\nstatic int opus_multistream_decode_native(\n      OpusMSDecoder *st,\n      const unsigned char *data,\n      opus_int32 len,\n      void *pcm,\n      opus_copy_channel_out_func copy_channel_out,\n      int frame_size,\n      int decode_fec,\n      int soft_clip\n)\n{\n   opus_int32 Fs;\n   int coupled_size;\n   int mono_size;\n   int s, c;\n   char *ptr;\n   int do_plc=0;\n   VARDECL(opus_val16, buf);\n   ALLOC_STACK;\n\n   /* Limit frame_size to avoid excessive stack allocations. */\n   opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs));\n   frame_size = IMIN(frame_size, Fs/25*3);\n   ALLOC(buf, 2*frame_size, opus_val16);\n   ptr = (char*)st + align(sizeof(OpusMSDecoder));\n   coupled_size = opus_decoder_get_size(2);\n   mono_size = opus_decoder_get_size(1);\n\n   if (len==0)\n      do_plc = 1;\n   if (len < 0)\n   {\n      RESTORE_STACK;\n      return OPUS_BAD_ARG;\n   }\n   if (!do_plc && len < 2*st->layout.nb_streams-1)\n   {\n      RESTORE_STACK;\n      return OPUS_INVALID_PACKET;\n   }\n   if (!do_plc)\n   {\n      int ret = opus_multistream_packet_validate(data, len, st->layout.nb_streams, Fs);\n      if (ret < 0)\n      {\n         RESTORE_STACK;\n         return ret;\n      } else if (ret > frame_size)\n      {\n         RESTORE_STACK;\n         return OPUS_BUFFER_TOO_SMALL;\n      }\n   }\n   for (s=0;s<st->layout.nb_streams;s++)\n   {\n      OpusDecoder *dec;\n      int packet_offset, ret;\n\n      dec = (OpusDecoder*)ptr;\n      ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);\n\n      if (!do_plc && len<=0)\n      {\n         RESTORE_STACK;\n         return OPUS_INTERNAL_ERROR;\n      }\n      packet_offset = 0;\n      ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip);\n      data += packet_offset;\n      len -= packet_offset;\n      if (ret <= 0)\n      {\n         RESTORE_STACK;\n         return ret;\n      }\n      frame_size = ret;\n      if (s < st->layout.nb_coupled_streams)\n      {\n         int chan, prev;\n         prev = -1;\n         /* Copy \"left\" audio to the channel(s) where it belongs */\n         while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)\n         {\n            (*copy_channel_out)(pcm, st->layout.nb_channels, chan,\n               buf, 2, frame_size);\n            prev = chan;\n         }\n         prev = -1;\n         /* Copy \"right\" audio to the channel(s) where it belongs */\n         while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)\n         {\n            (*copy_channel_out)(pcm, st->layout.nb_channels, chan,\n               buf+1, 2, frame_size);\n            prev = chan;\n         }\n      } else {\n         int chan, prev;\n         prev = -1;\n         /* Copy audio to the channel(s) where it belongs */\n         while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)\n         {\n            (*copy_channel_out)(pcm, st->layout.nb_channels, chan,\n               buf, 1, frame_size);\n            prev = chan;\n         }\n      }\n   }\n   /* Handle muted channels */\n   for (c=0;c<st->layout.nb_channels;c++)\n   {\n      if (st->layout.mapping[c] == 255)\n      {\n         (*copy_channel_out)(pcm, st->layout.nb_channels, c,\n            NULL, 0, frame_size);\n      }\n   }\n   RESTORE_STACK;\n   return frame_size;\n}\n\n#if !defined(DISABLE_FLOAT_API)\nstatic void opus_copy_channel_out_float(\n  void *dst,\n  int dst_stride,\n  int dst_channel,\n  const opus_val16 *src,\n  int src_stride,\n  int frame_size\n)\n{\n   float *float_dst;\n   opus_int32 i;\n   float_dst = (float*)dst;\n   if (src != NULL)\n   {\n      for (i=0;i<frame_size;i++)\n#if defined(FIXED_POINT)\n         float_dst[i*dst_stride+dst_channel] = (1/32768.f)*src[i*src_stride];\n#else\n         float_dst[i*dst_stride+dst_channel] = src[i*src_stride];\n#endif\n   }\n   else\n   {\n      for (i=0;i<frame_size;i++)\n         float_dst[i*dst_stride+dst_channel] = 0;\n   }\n}\n#endif\n\nstatic void opus_copy_channel_out_short(\n  void *dst,\n  int dst_stride,\n  int dst_channel,\n  const opus_val16 *src,\n  int src_stride,\n  int frame_size\n)\n{\n   opus_int16 *short_dst;\n   opus_int32 i;\n   short_dst = (opus_int16*)dst;\n   if (src != NULL)\n   {\n      for (i=0;i<frame_size;i++)\n#if defined(FIXED_POINT)\n         short_dst[i*dst_stride+dst_channel] = src[i*src_stride];\n#else\n         short_dst[i*dst_stride+dst_channel] = FLOAT2INT16(src[i*src_stride]);\n#endif\n   }\n   else\n   {\n      for (i=0;i<frame_size;i++)\n         short_dst[i*dst_stride+dst_channel] = 0;\n   }\n}\n\n\n\n#ifdef FIXED_POINT\nint opus_multistream_decode(\n      OpusMSDecoder *st,\n      const unsigned char *data,\n      opus_int32 len,\n      opus_int16 *pcm,\n      int frame_size,\n      int decode_fec\n)\n{\n   return opus_multistream_decode_native(st, data, len,\n       pcm, opus_copy_channel_out_short, frame_size, decode_fec, 0);\n}\n\n#ifndef DISABLE_FLOAT_API\nint opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,\n      opus_int32 len, float *pcm, int frame_size, int decode_fec)\n{\n   return opus_multistream_decode_native(st, data, len,\n       pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0);\n}\n#endif\n\n#else\n\nint opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,\n      opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)\n{\n   return opus_multistream_decode_native(st, data, len,\n       pcm, opus_copy_channel_out_short, frame_size, decode_fec, 1);\n}\n\nint opus_multistream_decode_float(\n      OpusMSDecoder *st,\n      const unsigned char *data,\n      opus_int32 len,\n      float *pcm,\n      int frame_size,\n      int decode_fec\n)\n{\n   return opus_multistream_decode_native(st, data, len,\n       pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0);\n}\n#endif\n\nint opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)\n{\n   va_list ap;\n   int coupled_size, mono_size;\n   char *ptr;\n   int ret = OPUS_OK;\n\n   va_start(ap, request);\n\n   coupled_size = opus_decoder_get_size(2);\n   mono_size = opus_decoder_get_size(1);\n   ptr = (char*)st + align(sizeof(OpusMSDecoder));\n   switch (request)\n   {\n       case OPUS_GET_BANDWIDTH_REQUEST:\n       case OPUS_GET_SAMPLE_RATE_REQUEST:\n       case OPUS_GET_GAIN_REQUEST:\n       case OPUS_GET_LAST_PACKET_DURATION_REQUEST:\n       {\n          OpusDecoder *dec;\n          /* For int32* GET params, just query the first stream */\n          opus_int32 *value = va_arg(ap, opus_int32*);\n          dec = (OpusDecoder*)ptr;\n          ret = opus_decoder_ctl(dec, request, value);\n       }\n       break;\n       case OPUS_GET_FINAL_RANGE_REQUEST:\n       {\n          int s;\n          opus_uint32 *value = va_arg(ap, opus_uint32*);\n          opus_uint32 tmp;\n          if (!value)\n          {\n             goto bad_arg;\n          }\n          *value = 0;\n          for (s=0;s<st->layout.nb_streams;s++)\n          {\n             OpusDecoder *dec;\n             dec = (OpusDecoder*)ptr;\n             if (s < st->layout.nb_coupled_streams)\n                ptr += align(coupled_size);\n             else\n                ptr += align(mono_size);\n             ret = opus_decoder_ctl(dec, request, &tmp);\n             if (ret != OPUS_OK) break;\n             *value ^= tmp;\n          }\n       }\n       break;\n       case OPUS_RESET_STATE:\n       {\n          int s;\n          for (s=0;s<st->layout.nb_streams;s++)\n          {\n             OpusDecoder *dec;\n\n             dec = (OpusDecoder*)ptr;\n             if (s < st->layout.nb_coupled_streams)\n                ptr += align(coupled_size);\n             else\n                ptr += align(mono_size);\n             ret = opus_decoder_ctl(dec, OPUS_RESET_STATE);\n             if (ret != OPUS_OK)\n                break;\n          }\n       }\n       break;\n       case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST:\n       {\n          int s;\n          opus_int32 stream_id;\n          OpusDecoder **value;\n          stream_id = va_arg(ap, opus_int32);\n          if (stream_id<0 || stream_id >= st->layout.nb_streams)\n             ret = OPUS_BAD_ARG;\n          value = va_arg(ap, OpusDecoder**);\n          if (!value)\n          {\n             goto bad_arg;\n          }\n          for (s=0;s<stream_id;s++)\n          {\n             if (s < st->layout.nb_coupled_streams)\n                ptr += align(coupled_size);\n             else\n                ptr += align(mono_size);\n          }\n          *value = (OpusDecoder*)ptr;\n       }\n       break;\n       case OPUS_SET_GAIN_REQUEST:\n       {\n          int s;\n          /* This works for int32 params */\n          opus_int32 value = va_arg(ap, opus_int32);\n          for (s=0;s<st->layout.nb_streams;s++)\n          {\n             OpusDecoder *dec;\n\n             dec = (OpusDecoder*)ptr;\n             if (s < st->layout.nb_coupled_streams)\n                ptr += align(coupled_size);\n             else\n                ptr += align(mono_size);\n             ret = opus_decoder_ctl(dec, request, value);\n             if (ret != OPUS_OK)\n                break;\n          }\n       }\n       break;\n       default:\n          ret = OPUS_UNIMPLEMENTED;\n       break;\n   }\n\n   va_end(ap);\n   return ret;\nbad_arg:\n   va_end(ap);\n   return OPUS_BAD_ARG;\n}\n\n\nvoid opus_multistream_decoder_destroy(OpusMSDecoder *st)\n{\n    opus_free(st);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/opus_multistream_encoder.c",
    "content": "/* Copyright (c) 2011 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"opus_multistream.h\"\n#include \"opus.h\"\n#include \"opus_private.h\"\n#include \"stack_alloc.h\"\n#include <stdarg.h>\n#include \"float_cast.h\"\n#include \"os_support.h\"\n#include \"mathops.h\"\n#include \"mdct.h\"\n#include \"modes.h\"\n#include \"bands.h\"\n#include \"quant_bands.h\"\n#include \"pitch.h\"\n\ntypedef struct {\n   int nb_streams;\n   int nb_coupled_streams;\n   unsigned char mapping[8];\n} VorbisLayout;\n\n/* Index is nb_channel-1*/\nstatic const VorbisLayout vorbis_mappings[8] = {\n      {1, 0, {0}},                      /* 1: mono */\n      {1, 1, {0, 1}},                   /* 2: stereo */\n      {2, 1, {0, 2, 1}},                /* 3: 1-d surround */\n      {2, 2, {0, 1, 2, 3}},             /* 4: quadraphonic surround */\n      {3, 2, {0, 4, 1, 2, 3}},          /* 5: 5-channel surround */\n      {4, 2, {0, 4, 1, 2, 3, 5}},       /* 6: 5.1 surround */\n      {4, 3, {0, 4, 1, 2, 3, 5, 6}},    /* 7: 6.1 surround */\n      {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */\n};\n\ntypedef void (*opus_copy_channel_in_func)(\n  opus_val16 *dst,\n  int dst_stride,\n  const void *src,\n  int src_stride,\n  int src_channel,\n  int frame_size\n);\n\nstruct OpusMSEncoder {\n   ChannelLayout layout;\n   int arch;\n   int lfe_stream;\n   int application;\n   int variable_duration;\n   int surround;\n   opus_int32 bitrate_bps;\n   float subframe_mem[3];\n   /* Encoder states go here */\n   /* then opus_val32 window_mem[channels*120]; */\n   /* then opus_val32 preemph_mem[channels]; */\n};\n\nstatic opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st)\n{\n   int s;\n   char *ptr;\n   int coupled_size, mono_size;\n\n   coupled_size = opus_encoder_get_size(2);\n   mono_size = opus_encoder_get_size(1);\n   ptr = (char*)st + align(sizeof(OpusMSEncoder));\n   for (s=0;s<st->layout.nb_streams;s++)\n   {\n      if (s < st->layout.nb_coupled_streams)\n         ptr += align(coupled_size);\n      else\n         ptr += align(mono_size);\n   }\n   /* void* cast avoids clang -Wcast-align warning */\n   return (opus_val32*)(void*)(ptr+st->layout.nb_channels*120*sizeof(opus_val32));\n}\n\nstatic opus_val32 *ms_get_window_mem(OpusMSEncoder *st)\n{\n   int s;\n   char *ptr;\n   int coupled_size, mono_size;\n\n   coupled_size = opus_encoder_get_size(2);\n   mono_size = opus_encoder_get_size(1);\n   ptr = (char*)st + align(sizeof(OpusMSEncoder));\n   for (s=0;s<st->layout.nb_streams;s++)\n   {\n      if (s < st->layout.nb_coupled_streams)\n         ptr += align(coupled_size);\n      else\n         ptr += align(mono_size);\n   }\n   /* void* cast avoids clang -Wcast-align warning */\n   return (opus_val32*)(void*)ptr;\n}\n\nstatic int validate_encoder_layout(const ChannelLayout *layout)\n{\n   int s;\n   for (s=0;s<layout->nb_streams;s++)\n   {\n      if (s < layout->nb_coupled_streams)\n      {\n         if (get_left_channel(layout, s, -1)==-1)\n            return 0;\n         if (get_right_channel(layout, s, -1)==-1)\n            return 0;\n      } else {\n         if (get_mono_channel(layout, s, -1)==-1)\n            return 0;\n      }\n   }\n   return 1;\n}\n\nstatic void channel_pos(int channels, int pos[8])\n{\n   /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */\n   if (channels==4)\n   {\n      pos[0]=1;\n      pos[1]=3;\n      pos[2]=1;\n      pos[3]=3;\n   } else if (channels==3||channels==5||channels==6)\n   {\n      pos[0]=1;\n      pos[1]=2;\n      pos[2]=3;\n      pos[3]=1;\n      pos[4]=3;\n      pos[5]=0;\n   } else if (channels==7)\n   {\n      pos[0]=1;\n      pos[1]=2;\n      pos[2]=3;\n      pos[3]=1;\n      pos[4]=3;\n      pos[5]=2;\n      pos[6]=0;\n   } else if (channels==8)\n   {\n      pos[0]=1;\n      pos[1]=2;\n      pos[2]=3;\n      pos[3]=1;\n      pos[4]=3;\n      pos[5]=1;\n      pos[6]=3;\n      pos[7]=0;\n   }\n}\n\n#if 1\n/* Computes a rough approximation of log2(2^a + 2^b) */\nstatic opus_val16 logSum(opus_val16 a, opus_val16 b)\n{\n   opus_val16 max;\n   opus_val32 diff;\n   opus_val16 frac;\n   static const opus_val16 diff_table[17] = {\n         QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST16(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT),\n         QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST16(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT),\n         QCONST16(0.0028123f, DB_SHIFT)\n   };\n   int low;\n   if (a>b)\n   {\n      max = a;\n      diff = SUB32(EXTEND32(a),EXTEND32(b));\n   } else {\n      max = b;\n      diff = SUB32(EXTEND32(b),EXTEND32(a));\n   }\n   if (!(diff < QCONST16(8.f, DB_SHIFT)))  /* inverted to catch NaNs */\n      return max;\n#ifdef FIXED_POINT\n   low = SHR32(diff, DB_SHIFT-1);\n   frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT);\n#else\n   low = (int)floor(2*diff);\n   frac = 2*diff - low;\n#endif\n   return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], diff_table[low]));\n}\n#else\nopus_val16 logSum(opus_val16 a, opus_val16 b)\n{\n   return log2(pow(4, a)+ pow(4, b))/2;\n}\n#endif\n\nvoid surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem,\n      int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in, int arch\n)\n{\n   int c;\n   int i;\n   int LM;\n   int pos[8] = {0};\n   int upsample;\n   int frame_size;\n   opus_val16 channel_offset;\n   opus_val32 bandE[21];\n   opus_val16 maskLogE[3][21];\n   VARDECL(opus_val32, in);\n   VARDECL(opus_val16, x);\n   VARDECL(opus_val32, freq);\n   SAVE_STACK;\n\n   upsample = resampling_factor(rate);\n   frame_size = len*upsample;\n\n   for (LM=0;LM<celt_mode->maxLM;LM++)\n      if (celt_mode->shortMdctSize<<LM==frame_size)\n         break;\n\n   ALLOC(in, frame_size+overlap, opus_val32);\n   ALLOC(x, len, opus_val16);\n   ALLOC(freq, frame_size, opus_val32);\n\n   channel_pos(channels, pos);\n\n   for (c=0;c<3;c++)\n      for (i=0;i<21;i++)\n         maskLogE[c][i] = -QCONST16(28.f, DB_SHIFT);\n\n   for (c=0;c<channels;c++)\n   {\n      OPUS_COPY(in, mem+c*overlap, overlap);\n      (*copy_channel_in)(x, 1, pcm, channels, c, len);\n      celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);\n#ifndef FIXED_POINT\n      {\n         opus_val32 sum;\n         sum = celt_inner_prod(in, in, frame_size+overlap, 0);\n         /* This should filter out both NaNs and ridiculous signals that could\n            cause NaNs further down. */\n         if (!(sum < 1e9f) || celt_isnan(sum))\n         {\n            OPUS_CLEAR(in, frame_size+overlap);\n            preemph_mem[c] = 0;\n         }\n      }\n#endif\n      clt_mdct_forward(&celt_mode->mdct, in, freq, celt_mode->window,\n            overlap, celt_mode->maxLM-LM, 1, arch);\n      if (upsample != 1)\n      {\n         int bound = len;\n         for (i=0;i<bound;i++)\n            freq[i] *= upsample;\n         for (;i<frame_size;i++)\n            freq[i] = 0;\n      }\n\n      compute_band_energies(celt_mode, freq, bandE, 21, 1, LM);\n      amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);\n      /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */\n      for (i=1;i<21;i++)\n         bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i-1]-QCONST16(1.f, DB_SHIFT));\n      for (i=19;i>=0;i--)\n         bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i+1]-QCONST16(2.f, DB_SHIFT));\n      if (pos[c]==1)\n      {\n         for (i=0;i<21;i++)\n            maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]);\n      } else if (pos[c]==3)\n      {\n         for (i=0;i<21;i++)\n            maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]);\n      } else if (pos[c]==2)\n      {\n         for (i=0;i<21;i++)\n         {\n            maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));\n            maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));\n         }\n      }\n#if 0\n      for (i=0;i<21;i++)\n         printf(\"%f \", bandLogE[21*c+i]);\n      float sum=0;\n      for (i=0;i<21;i++)\n         sum += bandLogE[21*c+i];\n      printf(\"%f \", sum/21);\n#endif\n      OPUS_COPY(mem+c*overlap, in+frame_size, overlap);\n   }\n   for (i=0;i<21;i++)\n      maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]);\n   channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1)));\n   for (c=0;c<3;c++)\n      for (i=0;i<21;i++)\n         maskLogE[c][i] += channel_offset;\n#if 0\n   for (c=0;c<3;c++)\n   {\n      for (i=0;i<21;i++)\n         printf(\"%f \", maskLogE[c][i]);\n   }\n#endif\n   for (c=0;c<channels;c++)\n   {\n      opus_val16 *mask;\n      if (pos[c]!=0)\n      {\n         mask = &maskLogE[pos[c]-1][0];\n         for (i=0;i<21;i++)\n            bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i];\n      } else {\n         for (i=0;i<21;i++)\n            bandLogE[21*c+i] = 0;\n      }\n#if 0\n      for (i=0;i<21;i++)\n         printf(\"%f \", bandLogE[21*c+i]);\n      printf(\"\\n\");\n#endif\n#if 0\n      float sum=0;\n      for (i=0;i<21;i++)\n         sum += bandLogE[21*c+i];\n      printf(\"%f \", sum/(float)QCONST32(21.f, DB_SHIFT));\n      printf(\"\\n\");\n#endif\n   }\n   RESTORE_STACK;\n}\n\nopus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)\n{\n   int coupled_size;\n   int mono_size;\n\n   if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;\n   coupled_size = opus_encoder_get_size(2);\n   mono_size = opus_encoder_get_size(1);\n   return align(sizeof(OpusMSEncoder))\n        + nb_coupled_streams * align(coupled_size)\n        + (nb_streams-nb_coupled_streams) * align(mono_size);\n}\n\nopus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family)\n{\n   int nb_streams;\n   int nb_coupled_streams;\n   opus_int32 size;\n\n   if (mapping_family==0)\n   {\n      if (channels==1)\n      {\n         nb_streams=1;\n         nb_coupled_streams=0;\n      } else if (channels==2)\n      {\n         nb_streams=1;\n         nb_coupled_streams=1;\n      } else\n         return 0;\n   } else if (mapping_family==1 && channels<=8 && channels>=1)\n   {\n      nb_streams=vorbis_mappings[channels-1].nb_streams;\n      nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;\n   } else if (mapping_family==255)\n   {\n      nb_streams=channels;\n      nb_coupled_streams=0;\n   } else\n      return 0;\n   size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);\n   if (channels>2)\n   {\n      size += channels*(120*sizeof(opus_val32) + sizeof(opus_val32));\n   }\n   return size;\n}\n\n\nstatic int opus_multistream_encoder_init_impl(\n      OpusMSEncoder *st,\n      opus_int32 Fs,\n      int channels,\n      int streams,\n      int coupled_streams,\n      const unsigned char *mapping,\n      int application,\n      int surround\n)\n{\n   int coupled_size;\n   int mono_size;\n   int i, ret;\n   char *ptr;\n\n   if ((channels>255) || (channels<1) || (coupled_streams>streams) ||\n       (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))\n      return OPUS_BAD_ARG;\n\n   st->arch = opus_select_arch();\n   st->layout.nb_channels = channels;\n   st->layout.nb_streams = streams;\n   st->layout.nb_coupled_streams = coupled_streams;\n   st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0;\n   if (!surround)\n      st->lfe_stream = -1;\n   st->bitrate_bps = OPUS_AUTO;\n   st->application = application;\n   st->variable_duration = OPUS_FRAMESIZE_ARG;\n   for (i=0;i<st->layout.nb_channels;i++)\n      st->layout.mapping[i] = mapping[i];\n   if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))\n      return OPUS_BAD_ARG;\n   ptr = (char*)st + align(sizeof(OpusMSEncoder));\n   coupled_size = opus_encoder_get_size(2);\n   mono_size = opus_encoder_get_size(1);\n\n   for (i=0;i<st->layout.nb_coupled_streams;i++)\n   {\n      ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);\n      if(ret!=OPUS_OK)return ret;\n      if (i==st->lfe_stream)\n         opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));\n      ptr += align(coupled_size);\n   }\n   for (;i<st->layout.nb_streams;i++)\n   {\n      ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);\n      if (i==st->lfe_stream)\n         opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));\n      if(ret!=OPUS_OK)return ret;\n      ptr += align(mono_size);\n   }\n   if (surround)\n   {\n      OPUS_CLEAR(ms_get_preemph_mem(st), channels);\n      OPUS_CLEAR(ms_get_window_mem(st), channels*120);\n   }\n   st->surround = surround;\n   return OPUS_OK;\n}\n\nint opus_multistream_encoder_init(\n      OpusMSEncoder *st,\n      opus_int32 Fs,\n      int channels,\n      int streams,\n      int coupled_streams,\n      const unsigned char *mapping,\n      int application\n)\n{\n   return opus_multistream_encoder_init_impl(st, Fs, channels, streams, coupled_streams, mapping, application, 0);\n}\n\nint opus_multistream_surround_encoder_init(\n      OpusMSEncoder *st,\n      opus_int32 Fs,\n      int channels,\n      int mapping_family,\n      int *streams,\n      int *coupled_streams,\n      unsigned char *mapping,\n      int application\n)\n{\n   if ((channels>255) || (channels<1))\n      return OPUS_BAD_ARG;\n   st->lfe_stream = -1;\n   if (mapping_family==0)\n   {\n      if (channels==1)\n      {\n         *streams=1;\n         *coupled_streams=0;\n         mapping[0]=0;\n      } else if (channels==2)\n      {\n         *streams=1;\n         *coupled_streams=1;\n         mapping[0]=0;\n         mapping[1]=1;\n      } else\n         return OPUS_UNIMPLEMENTED;\n   } else if (mapping_family==1 && channels<=8 && channels>=1)\n   {\n      int i;\n      *streams=vorbis_mappings[channels-1].nb_streams;\n      *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;\n      for (i=0;i<channels;i++)\n         mapping[i] = vorbis_mappings[channels-1].mapping[i];\n      if (channels>=6)\n         st->lfe_stream = *streams-1;\n   } else if (mapping_family==255)\n   {\n      int i;\n      *streams=channels;\n      *coupled_streams=0;\n      for(i=0;i<channels;i++)\n         mapping[i] = i;\n   } else\n      return OPUS_UNIMPLEMENTED;\n   return opus_multistream_encoder_init_impl(st, Fs, channels, *streams, *coupled_streams,\n         mapping, application, channels>2&&mapping_family==1);\n}\n\nOpusMSEncoder *opus_multistream_encoder_create(\n      opus_int32 Fs,\n      int channels,\n      int streams,\n      int coupled_streams,\n      const unsigned char *mapping,\n      int application,\n      int *error\n)\n{\n   int ret;\n   OpusMSEncoder *st;\n   if ((channels>255) || (channels<1) || (coupled_streams>streams) ||\n       (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))\n   {\n      if (error)\n         *error = OPUS_BAD_ARG;\n      return NULL;\n   }\n   st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));\n   if (st==NULL)\n   {\n      if (error)\n         *error = OPUS_ALLOC_FAIL;\n      return NULL;\n   }\n   ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);\n   if (ret != OPUS_OK)\n   {\n      opus_free(st);\n      st = NULL;\n   }\n   if (error)\n      *error = ret;\n   return st;\n}\n\nOpusMSEncoder *opus_multistream_surround_encoder_create(\n      opus_int32 Fs,\n      int channels,\n      int mapping_family,\n      int *streams,\n      int *coupled_streams,\n      unsigned char *mapping,\n      int application,\n      int *error\n)\n{\n   int ret;\n   opus_int32 size;\n   OpusMSEncoder *st;\n   if ((channels>255) || (channels<1))\n   {\n      if (error)\n         *error = OPUS_BAD_ARG;\n      return NULL;\n   }\n   size = opus_multistream_surround_encoder_get_size(channels, mapping_family);\n   if (!size)\n   {\n      if (error)\n         *error = OPUS_UNIMPLEMENTED;\n      return NULL;\n   }\n   st = (OpusMSEncoder *)opus_alloc(size);\n   if (st==NULL)\n   {\n      if (error)\n         *error = OPUS_ALLOC_FAIL;\n      return NULL;\n   }\n   ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);\n   if (ret != OPUS_OK)\n   {\n      opus_free(st);\n      st = NULL;\n   }\n   if (error)\n      *error = ret;\n   return st;\n}\n\nstatic opus_int32 surround_rate_allocation(\n      OpusMSEncoder *st,\n      opus_int32 *rate,\n      int frame_size\n      )\n{\n   int i;\n   opus_int32 channel_rate;\n   opus_int32 Fs;\n   char *ptr;\n   int stream_offset;\n   int lfe_offset;\n   int coupled_ratio; /* Q8 */\n   int lfe_ratio;     /* Q8 */\n   opus_int32 rate_sum=0;\n\n   ptr = (char*)st + align(sizeof(OpusMSEncoder));\n   opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));\n\n   if (st->bitrate_bps > st->layout.nb_channels*40000)\n      stream_offset = 20000;\n   else\n      stream_offset = st->bitrate_bps/st->layout.nb_channels/2;\n   stream_offset += 60*(Fs/frame_size-50);\n   /* We start by giving each stream (coupled or uncoupled) the same bitrate.\n      This models the main saving of coupled channels over uncoupled. */\n   /* The LFE stream is an exception to the above and gets fewer bits. */\n   lfe_offset = 3500 + 60*(Fs/frame_size-50);\n   /* Coupled streams get twice the mono rate after the first 20 kb/s. */\n   coupled_ratio = 512;\n   /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */\n   lfe_ratio = 32;\n\n   /* Compute bitrate allocation between streams */\n   if (st->bitrate_bps==OPUS_AUTO)\n   {\n      channel_rate = Fs+60*Fs/frame_size;\n   } else if (st->bitrate_bps==OPUS_BITRATE_MAX)\n   {\n      channel_rate = 300000;\n   } else {\n      int nb_lfe;\n      int nb_uncoupled;\n      int nb_coupled;\n      int total;\n      nb_lfe = (st->lfe_stream!=-1);\n      nb_coupled = st->layout.nb_coupled_streams;\n      nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;\n      total = (nb_uncoupled<<8)         /* mono */\n            + coupled_ratio*nb_coupled /* stereo */\n            + nb_lfe*lfe_ratio;\n      channel_rate = 256*(st->bitrate_bps-lfe_offset*nb_lfe-stream_offset*(nb_coupled+nb_uncoupled))/total;\n   }\n#ifndef FIXED_POINT\n   if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)\n   {\n      opus_int32 bonus;\n      bonus = 60*(Fs/frame_size-50);\n      channel_rate += bonus;\n   }\n#endif\n\n   for (i=0;i<st->layout.nb_streams;i++)\n   {\n      if (i<st->layout.nb_coupled_streams)\n         rate[i] = stream_offset+(channel_rate*coupled_ratio>>8);\n      else if (i!=st->lfe_stream)\n         rate[i] = stream_offset+channel_rate;\n      else\n         rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);\n      rate[i] = IMAX(rate[i], 500);\n      rate_sum += rate[i];\n   }\n   return rate_sum;\n}\n\n/* Max size in case the encoder decides to return three frames */\n#define MS_FRAME_TMP (3*1275+7)\nstatic int opus_multistream_encode_native\n(\n    OpusMSEncoder *st,\n    opus_copy_channel_in_func copy_channel_in,\n    const void *pcm,\n    int analysis_frame_size,\n    unsigned char *data,\n    opus_int32 max_data_bytes,\n    int lsb_depth,\n    downmix_func downmix,\n    int float_api\n)\n{\n   opus_int32 Fs;\n   int coupled_size;\n   int mono_size;\n   int s;\n   char *ptr;\n   int tot_size;\n   VARDECL(opus_val16, buf);\n   VARDECL(opus_val16, bandSMR);\n   unsigned char tmp_data[MS_FRAME_TMP];\n   OpusRepacketizer rp;\n   opus_int32 vbr;\n   const CELTMode *celt_mode;\n   opus_int32 bitrates[256];\n   opus_val16 bandLogE[42];\n   opus_val32 *mem = NULL;\n   opus_val32 *preemph_mem=NULL;\n   int frame_size;\n   opus_int32 rate_sum;\n   opus_int32 smallest_packet;\n   ALLOC_STACK;\n\n   if (st->surround)\n   {\n      preemph_mem = ms_get_preemph_mem(st);\n      mem = ms_get_window_mem(st);\n   }\n\n   ptr = (char*)st + align(sizeof(OpusMSEncoder));\n   opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));\n   opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));\n   opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));\n\n   {\n      opus_int32 delay_compensation;\n      int channels;\n\n      channels = st->layout.nb_streams + st->layout.nb_coupled_streams;\n      opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));\n      delay_compensation -= Fs/400;\n      frame_size = compute_frame_size(pcm, analysis_frame_size,\n            st->variable_duration, channels, Fs, st->bitrate_bps,\n            delay_compensation, downmix\n#ifndef DISABLE_FLOAT_API\n            , st->subframe_mem\n#endif\n            );\n   }\n\n   if (400*frame_size < Fs)\n   {\n      RESTORE_STACK;\n      return OPUS_BAD_ARG;\n   }\n   /* Validate frame_size before using it to allocate stack space.\n      This mirrors the checks in opus_encode[_float](). */\n   if (400*frame_size != Fs && 200*frame_size != Fs &&\n       100*frame_size != Fs &&  50*frame_size != Fs &&\n        25*frame_size != Fs &&  50*frame_size != 3*Fs)\n   {\n      RESTORE_STACK;\n      return OPUS_BAD_ARG;\n   }\n\n   /* Smallest packet the encoder can produce. */\n   smallest_packet = st->layout.nb_streams*2-1;\n   if (max_data_bytes < smallest_packet)\n   {\n      RESTORE_STACK;\n      return OPUS_BUFFER_TOO_SMALL;\n   }\n   ALLOC(buf, 2*frame_size, opus_val16);\n   coupled_size = opus_encoder_get_size(2);\n   mono_size = opus_encoder_get_size(1);\n\n   ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);\n   if (st->surround)\n   {\n      surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in, st->arch);\n   }\n\n   /* Compute bitrate allocation between streams (this could be a lot better) */\n   rate_sum = surround_rate_allocation(st, bitrates, frame_size);\n\n   if (!vbr)\n   {\n      if (st->bitrate_bps == OPUS_AUTO)\n      {\n         max_data_bytes = IMIN(max_data_bytes, 3*rate_sum/(3*8*Fs/frame_size));\n      } else if (st->bitrate_bps != OPUS_BITRATE_MAX)\n      {\n         max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet,\n                          3*st->bitrate_bps/(3*8*Fs/frame_size)));\n      }\n   }\n   ptr = (char*)st + align(sizeof(OpusMSEncoder));\n   for (s=0;s<st->layout.nb_streams;s++)\n   {\n      OpusEncoder *enc;\n      enc = (OpusEncoder*)ptr;\n      if (s < st->layout.nb_coupled_streams)\n         ptr += align(coupled_size);\n      else\n         ptr += align(mono_size);\n      opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));\n      if (st->surround)\n      {\n         opus_int32 equiv_rate;\n         equiv_rate = st->bitrate_bps;\n         if (frame_size*50 < Fs)\n            equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels;\n         if (equiv_rate > 10000*st->layout.nb_channels)\n            opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));\n         else if (equiv_rate > 7000*st->layout.nb_channels)\n            opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));\n         else if (equiv_rate > 5000*st->layout.nb_channels)\n            opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));\n         else\n            opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));\n         if (s < st->layout.nb_coupled_streams)\n         {\n            /* To preserve the spatial image, force stereo CELT on coupled streams */\n            opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));\n            opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));\n         }\n      }\n   }\n\n   ptr = (char*)st + align(sizeof(OpusMSEncoder));\n   /* Counting ToC */\n   tot_size = 0;\n   for (s=0;s<st->layout.nb_streams;s++)\n   {\n      OpusEncoder *enc;\n      int len;\n      int curr_max;\n      int c1, c2;\n\n      opus_repacketizer_init(&rp);\n      enc = (OpusEncoder*)ptr;\n      if (s < st->layout.nb_coupled_streams)\n      {\n         int i;\n         int left, right;\n         left = get_left_channel(&st->layout, s, -1);\n         right = get_right_channel(&st->layout, s, -1);\n         (*copy_channel_in)(buf, 2,\n            pcm, st->layout.nb_channels, left, frame_size);\n         (*copy_channel_in)(buf+1, 2,\n            pcm, st->layout.nb_channels, right, frame_size);\n         ptr += align(coupled_size);\n         if (st->surround)\n         {\n            for (i=0;i<21;i++)\n            {\n               bandLogE[i] = bandSMR[21*left+i];\n               bandLogE[21+i] = bandSMR[21*right+i];\n            }\n         }\n         c1 = left;\n         c2 = right;\n      } else {\n         int i;\n         int chan = get_mono_channel(&st->layout, s, -1);\n         (*copy_channel_in)(buf, 1,\n            pcm, st->layout.nb_channels, chan, frame_size);\n         ptr += align(mono_size);\n         if (st->surround)\n         {\n            for (i=0;i<21;i++)\n               bandLogE[i] = bandSMR[21*chan+i];\n         }\n         c1 = chan;\n         c2 = -1;\n      }\n      if (st->surround)\n         opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));\n      /* number of bytes left (+Toc) */\n      curr_max = max_data_bytes - tot_size;\n      /* Reserve one byte for the last stream and two for the others */\n      curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1);\n      curr_max = IMIN(curr_max,MS_FRAME_TMP);\n      /* Repacketizer will add one or two bytes for self-delimited frames */\n      if (s != st->layout.nb_streams-1) curr_max -=  curr_max>253 ? 2 : 1;\n      if (!vbr && s == st->layout.nb_streams-1)\n         opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size)));\n      len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth,\n            pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api);\n      if (len<0)\n      {\n         RESTORE_STACK;\n         return len;\n      }\n      /* We need to use the repacketizer to add the self-delimiting lengths\n         while taking into account the fact that the encoder can now return\n         more than one frame at a time (e.g. 60 ms CELT-only) */\n      opus_repacketizer_cat(&rp, tmp_data, len);\n      len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp),\n            data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1);\n      data += len;\n      tot_size += len;\n   }\n   /*printf(\"\\n\");*/\n   RESTORE_STACK;\n   return tot_size;\n}\n\n#if !defined(DISABLE_FLOAT_API)\nstatic void opus_copy_channel_in_float(\n  opus_val16 *dst,\n  int dst_stride,\n  const void *src,\n  int src_stride,\n  int src_channel,\n  int frame_size\n)\n{\n   const float *float_src;\n   opus_int32 i;\n   float_src = (const float *)src;\n   for (i=0;i<frame_size;i++)\n#if defined(FIXED_POINT)\n      dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);\n#else\n      dst[i*dst_stride] = float_src[i*src_stride+src_channel];\n#endif\n}\n#endif\n\nstatic void opus_copy_channel_in_short(\n  opus_val16 *dst,\n  int dst_stride,\n  const void *src,\n  int src_stride,\n  int src_channel,\n  int frame_size\n)\n{\n   const opus_int16 *short_src;\n   opus_int32 i;\n   short_src = (const opus_int16 *)src;\n   for (i=0;i<frame_size;i++)\n#if defined(FIXED_POINT)\n      dst[i*dst_stride] = short_src[i*src_stride+src_channel];\n#else\n      dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];\n#endif\n}\n\n\n#ifdef FIXED_POINT\nint opus_multistream_encode(\n    OpusMSEncoder *st,\n    const opus_val16 *pcm,\n    int frame_size,\n    unsigned char *data,\n    opus_int32 max_data_bytes\n)\n{\n   return opus_multistream_encode_native(st, opus_copy_channel_in_short,\n      pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);\n}\n\n#ifndef DISABLE_FLOAT_API\nint opus_multistream_encode_float(\n    OpusMSEncoder *st,\n    const float *pcm,\n    int frame_size,\n    unsigned char *data,\n    opus_int32 max_data_bytes\n)\n{\n   return opus_multistream_encode_native(st, opus_copy_channel_in_float,\n      pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1);\n}\n#endif\n\n#else\n\nint opus_multistream_encode_float\n(\n    OpusMSEncoder *st,\n    const opus_val16 *pcm,\n    int frame_size,\n    unsigned char *data,\n    opus_int32 max_data_bytes\n)\n{\n   return opus_multistream_encode_native(st, opus_copy_channel_in_float,\n      pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1);\n}\n\nint opus_multistream_encode(\n    OpusMSEncoder *st,\n    const opus_int16 *pcm,\n    int frame_size,\n    unsigned char *data,\n    opus_int32 max_data_bytes\n)\n{\n   return opus_multistream_encode_native(st, opus_copy_channel_in_short,\n      pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);\n}\n#endif\n\nint opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)\n{\n   va_list ap;\n   int coupled_size, mono_size;\n   char *ptr;\n   int ret = OPUS_OK;\n\n   va_start(ap, request);\n\n   coupled_size = opus_encoder_get_size(2);\n   mono_size = opus_encoder_get_size(1);\n   ptr = (char*)st + align(sizeof(OpusMSEncoder));\n   switch (request)\n   {\n   case OPUS_SET_BITRATE_REQUEST:\n   {\n      opus_int32 value = va_arg(ap, opus_int32);\n      if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)\n      {\n         goto bad_arg;\n      }\n      st->bitrate_bps = value;\n   }\n   break;\n   case OPUS_GET_BITRATE_REQUEST:\n   {\n      int s;\n      opus_int32 *value = va_arg(ap, opus_int32*);\n      if (!value)\n      {\n         goto bad_arg;\n      }\n      *value = 0;\n      for (s=0;s<st->layout.nb_streams;s++)\n      {\n         opus_int32 rate;\n         OpusEncoder *enc;\n         enc = (OpusEncoder*)ptr;\n         if (s < st->layout.nb_coupled_streams)\n            ptr += align(coupled_size);\n         else\n            ptr += align(mono_size);\n         opus_encoder_ctl(enc, request, &rate);\n         *value += rate;\n      }\n   }\n   break;\n   case OPUS_GET_LSB_DEPTH_REQUEST:\n   case OPUS_GET_VBR_REQUEST:\n   case OPUS_GET_APPLICATION_REQUEST:\n   case OPUS_GET_BANDWIDTH_REQUEST:\n   case OPUS_GET_COMPLEXITY_REQUEST:\n   case OPUS_GET_PACKET_LOSS_PERC_REQUEST:\n   case OPUS_GET_DTX_REQUEST:\n   case OPUS_GET_VOICE_RATIO_REQUEST:\n   case OPUS_GET_VBR_CONSTRAINT_REQUEST:\n   case OPUS_GET_SIGNAL_REQUEST:\n   case OPUS_GET_LOOKAHEAD_REQUEST:\n   case OPUS_GET_SAMPLE_RATE_REQUEST:\n   case OPUS_GET_INBAND_FEC_REQUEST:\n   case OPUS_GET_FORCE_CHANNELS_REQUEST:\n   case OPUS_GET_PREDICTION_DISABLED_REQUEST:\n   {\n      OpusEncoder *enc;\n      /* For int32* GET params, just query the first stream */\n      opus_int32 *value = va_arg(ap, opus_int32*);\n      enc = (OpusEncoder*)ptr;\n      ret = opus_encoder_ctl(enc, request, value);\n   }\n   break;\n   case OPUS_GET_FINAL_RANGE_REQUEST:\n   {\n      int s;\n      opus_uint32 *value = va_arg(ap, opus_uint32*);\n      opus_uint32 tmp;\n      if (!value)\n      {\n         goto bad_arg;\n      }\n      *value=0;\n      for (s=0;s<st->layout.nb_streams;s++)\n      {\n         OpusEncoder *enc;\n         enc = (OpusEncoder*)ptr;\n         if (s < st->layout.nb_coupled_streams)\n            ptr += align(coupled_size);\n         else\n            ptr += align(mono_size);\n         ret = opus_encoder_ctl(enc, request, &tmp);\n         if (ret != OPUS_OK) break;\n         *value ^= tmp;\n      }\n   }\n   break;\n   case OPUS_SET_LSB_DEPTH_REQUEST:\n   case OPUS_SET_COMPLEXITY_REQUEST:\n   case OPUS_SET_VBR_REQUEST:\n   case OPUS_SET_VBR_CONSTRAINT_REQUEST:\n   case OPUS_SET_MAX_BANDWIDTH_REQUEST:\n   case OPUS_SET_BANDWIDTH_REQUEST:\n   case OPUS_SET_SIGNAL_REQUEST:\n   case OPUS_SET_APPLICATION_REQUEST:\n   case OPUS_SET_INBAND_FEC_REQUEST:\n   case OPUS_SET_PACKET_LOSS_PERC_REQUEST:\n   case OPUS_SET_DTX_REQUEST:\n   case OPUS_SET_FORCE_MODE_REQUEST:\n   case OPUS_SET_FORCE_CHANNELS_REQUEST:\n   case OPUS_SET_PREDICTION_DISABLED_REQUEST:\n   {\n      int s;\n      /* This works for int32 params */\n      opus_int32 value = va_arg(ap, opus_int32);\n      for (s=0;s<st->layout.nb_streams;s++)\n      {\n         OpusEncoder *enc;\n\n         enc = (OpusEncoder*)ptr;\n         if (s < st->layout.nb_coupled_streams)\n            ptr += align(coupled_size);\n         else\n            ptr += align(mono_size);\n         ret = opus_encoder_ctl(enc, request, value);\n         if (ret != OPUS_OK)\n            break;\n      }\n   }\n   break;\n   case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:\n   {\n      int s;\n      opus_int32 stream_id;\n      OpusEncoder **value;\n      stream_id = va_arg(ap, opus_int32);\n      if (stream_id<0 || stream_id >= st->layout.nb_streams)\n         ret = OPUS_BAD_ARG;\n      value = va_arg(ap, OpusEncoder**);\n      if (!value)\n      {\n         goto bad_arg;\n      }\n      for (s=0;s<stream_id;s++)\n      {\n         if (s < st->layout.nb_coupled_streams)\n            ptr += align(coupled_size);\n         else\n            ptr += align(mono_size);\n      }\n      *value = (OpusEncoder*)ptr;\n   }\n   break;\n   case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:\n   {\n       opus_int32 value = va_arg(ap, opus_int32);\n       st->variable_duration = value;\n   }\n   break;\n   case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:\n   {\n       opus_int32 *value = va_arg(ap, opus_int32*);\n       if (!value)\n       {\n          goto bad_arg;\n       }\n       *value = st->variable_duration;\n   }\n   break;\n   case OPUS_RESET_STATE:\n   {\n      int s;\n      st->subframe_mem[0] = st->subframe_mem[1] = st->subframe_mem[2] = 0;\n      if (st->surround)\n      {\n         OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);\n         OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120);\n      }\n      for (s=0;s<st->layout.nb_streams;s++)\n      {\n         OpusEncoder *enc;\n         enc = (OpusEncoder*)ptr;\n         if (s < st->layout.nb_coupled_streams)\n            ptr += align(coupled_size);\n         else\n            ptr += align(mono_size);\n         ret = opus_encoder_ctl(enc, OPUS_RESET_STATE);\n         if (ret != OPUS_OK)\n            break;\n      }\n   }\n   break;\n   default:\n      ret = OPUS_UNIMPLEMENTED;\n      break;\n   }\n\n   va_end(ap);\n   return ret;\nbad_arg:\n   va_end(ap);\n   return OPUS_BAD_ARG;\n}\n\nvoid opus_multistream_encoder_destroy(OpusMSEncoder *st)\n{\n    opus_free(st);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/opus_private.h",
    "content": "/* Copyright (c) 2012 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\n#ifndef OPUS_PRIVATE_H\n#define OPUS_PRIVATE_H\n\n#include \"arch.h\"\n#include \"opus.h\"\n#include \"celt.h\"\n\n#include <stddef.h> /* offsetof */\n\nstruct OpusRepacketizer {\n   unsigned char toc;\n   int nb_frames;\n   const unsigned char *frames[48];\n   opus_int16 len[48];\n   int framesize;\n};\n\ntypedef struct ChannelLayout {\n   int nb_channels;\n   int nb_streams;\n   int nb_coupled_streams;\n   unsigned char mapping[256];\n} ChannelLayout;\n\nint validate_layout(const ChannelLayout *layout);\nint get_left_channel(const ChannelLayout *layout, int stream_id, int prev);\nint get_right_channel(const ChannelLayout *layout, int stream_id, int prev);\nint get_mono_channel(const ChannelLayout *layout, int stream_id, int prev);\n\n\n\n#define MODE_SILK_ONLY          1000\n#define MODE_HYBRID             1001\n#define MODE_CELT_ONLY          1002\n\n#define OPUS_SET_VOICE_RATIO_REQUEST         11018\n#define OPUS_GET_VOICE_RATIO_REQUEST         11019\n\n/** Configures the encoder's expected percentage of voice\n  * opposed to music or other signals.\n  *\n  * @note This interface is currently more aspiration than actuality. It's\n  * ultimately expected to bias an automatic signal classifier, but it currently\n  * just shifts the static bitrate to mode mapping around a little bit.\n  *\n  * @param[in] x <tt>int</tt>:   Voice percentage in the range 0-100, inclusive.\n  * @hideinitializer */\n#define OPUS_SET_VOICE_RATIO(x) OPUS_SET_VOICE_RATIO_REQUEST, __opus_check_int(x)\n/** Gets the encoder's configured voice ratio value, @see OPUS_SET_VOICE_RATIO\n  *\n  * @param[out] x <tt>int*</tt>:  Voice percentage in the range 0-100, inclusive.\n  * @hideinitializer */\n#define OPUS_GET_VOICE_RATIO(x) OPUS_GET_VOICE_RATIO_REQUEST, __opus_check_int_ptr(x)\n\n\n#define OPUS_SET_FORCE_MODE_REQUEST    11002\n#define OPUS_SET_FORCE_MODE(x) OPUS_SET_FORCE_MODE_REQUEST, __opus_check_int(x)\n\ntypedef void (*downmix_func)(const void *, opus_val32 *, int, int, int, int, int);\nvoid downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C);\nvoid downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C);\n\nint encode_size(int size, unsigned char *data);\n\nopus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs);\n\nopus_int32 compute_frame_size(const void *analysis_pcm, int frame_size,\n      int variable_duration, int C, opus_int32 Fs, int bitrate_bps,\n      int delay_compensation, downmix_func downmix\n#ifndef DISABLE_FLOAT_API\n      , float *subframe_mem\n#endif\n      );\n\nopus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,\n      unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,\n      const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2,\n      int analysis_channels, downmix_func downmix, int float_api);\n\nint opus_decode_native(OpusDecoder *st, const unsigned char *data, opus_int32 len,\n      opus_val16 *pcm, int frame_size, int decode_fec, int self_delimited,\n      opus_int32 *packet_offset, int soft_clip);\n\n/* Make sure everything is properly aligned. */\nstatic OPUS_INLINE int align(int i)\n{\n    struct foo {char c; union { void* p; opus_int32 i; opus_val32 v; } u;};\n\n    unsigned int alignment = offsetof(struct foo, u);\n\n    /* Optimizing compilers should optimize div and multiply into and\n       for all sensible alignment values. */\n    return ((i + alignment - 1) / alignment) * alignment;\n}\n\nint opus_packet_parse_impl(const unsigned char *data, opus_int32 len,\n      int self_delimited, unsigned char *out_toc,\n      const unsigned char *frames[48], opus_int16 size[48],\n      int *payload_offset, opus_int32 *packet_offset);\n\nopus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end,\n      unsigned char *data, opus_int32 maxlen, int self_delimited, int pad);\n\nint pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len);\n\n#endif /* OPUS_PRIVATE_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/repacketizer.c",
    "content": "/* Copyright (c) 2011 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"opus.h\"\n#include \"opus_private.h\"\n#include \"os_support.h\"\n\n\nint opus_repacketizer_get_size(void)\n{\n   return sizeof(OpusRepacketizer);\n}\n\nOpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp)\n{\n   rp->nb_frames = 0;\n   return rp;\n}\n\nOpusRepacketizer *opus_repacketizer_create(void)\n{\n   OpusRepacketizer *rp;\n   rp=(OpusRepacketizer *)opus_alloc(opus_repacketizer_get_size());\n   if(rp==NULL)return NULL;\n   return opus_repacketizer_init(rp);\n}\n\nvoid opus_repacketizer_destroy(OpusRepacketizer *rp)\n{\n   opus_free(rp);\n}\n\nstatic int opus_repacketizer_cat_impl(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len, int self_delimited)\n{\n   unsigned char tmp_toc;\n   int curr_nb_frames,ret;\n   /* Set of check ToC */\n   if (len<1) return OPUS_INVALID_PACKET;\n   if (rp->nb_frames == 0)\n   {\n      rp->toc = data[0];\n      rp->framesize = opus_packet_get_samples_per_frame(data, 8000);\n   } else if ((rp->toc&0xFC) != (data[0]&0xFC))\n   {\n      /*fprintf(stderr, \"toc mismatch: 0x%x vs 0x%x\\n\", rp->toc, data[0]);*/\n      return OPUS_INVALID_PACKET;\n   }\n   curr_nb_frames = opus_packet_get_nb_frames(data, len);\n   if(curr_nb_frames<1) return OPUS_INVALID_PACKET;\n\n   /* Check the 120 ms maximum packet size */\n   if ((curr_nb_frames+rp->nb_frames)*rp->framesize > 960)\n   {\n      return OPUS_INVALID_PACKET;\n   }\n\n   ret=opus_packet_parse_impl(data, len, self_delimited, &tmp_toc, &rp->frames[rp->nb_frames], &rp->len[rp->nb_frames], NULL, NULL);\n   if(ret<1)return ret;\n\n   rp->nb_frames += curr_nb_frames;\n   return OPUS_OK;\n}\n\nint opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len)\n{\n   return opus_repacketizer_cat_impl(rp, data, len, 0);\n}\n\nint opus_repacketizer_get_nb_frames(OpusRepacketizer *rp)\n{\n   return rp->nb_frames;\n}\n\nopus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end,\n      unsigned char *data, opus_int32 maxlen, int self_delimited, int pad)\n{\n   int i, count;\n   opus_int32 tot_size;\n   opus_int16 *len;\n   const unsigned char **frames;\n   unsigned char * ptr;\n\n   if (begin<0 || begin>=end || end>rp->nb_frames)\n   {\n      /*fprintf(stderr, \"%d %d %d\\n\", begin, end, rp->nb_frames);*/\n      return OPUS_BAD_ARG;\n   }\n   count = end-begin;\n\n   len = rp->len+begin;\n   frames = rp->frames+begin;\n   if (self_delimited)\n      tot_size = 1 + (len[count-1]>=252);\n   else\n      tot_size = 0;\n\n   ptr = data;\n   if (count==1)\n   {\n      /* Code 0 */\n      tot_size += len[0]+1;\n      if (tot_size > maxlen)\n         return OPUS_BUFFER_TOO_SMALL;\n      *ptr++ = rp->toc&0xFC;\n   } else if (count==2)\n   {\n      if (len[1] == len[0])\n      {\n         /* Code 1 */\n         tot_size += 2*len[0]+1;\n         if (tot_size > maxlen)\n            return OPUS_BUFFER_TOO_SMALL;\n         *ptr++ = (rp->toc&0xFC) | 0x1;\n      } else {\n         /* Code 2 */\n         tot_size += len[0]+len[1]+2+(len[0]>=252);\n         if (tot_size > maxlen)\n            return OPUS_BUFFER_TOO_SMALL;\n         *ptr++ = (rp->toc&0xFC) | 0x2;\n         ptr += encode_size(len[0], ptr);\n      }\n   }\n   if (count > 2 || (pad && tot_size < maxlen))\n   {\n      /* Code 3 */\n      int vbr;\n      int pad_amount=0;\n\n      /* Restart the process for the padding case */\n      ptr = data;\n      if (self_delimited)\n         tot_size = 1 + (len[count-1]>=252);\n      else\n         tot_size = 0;\n      vbr = 0;\n      for (i=1;i<count;i++)\n      {\n         if (len[i] != len[0])\n         {\n            vbr=1;\n            break;\n         }\n      }\n      if (vbr)\n      {\n         tot_size += 2;\n         for (i=0;i<count-1;i++)\n            tot_size += 1 + (len[i]>=252) + len[i];\n         tot_size += len[count-1];\n\n         if (tot_size > maxlen)\n            return OPUS_BUFFER_TOO_SMALL;\n         *ptr++ = (rp->toc&0xFC) | 0x3;\n         *ptr++ = count | 0x80;\n      } else {\n         tot_size += count*len[0]+2;\n         if (tot_size > maxlen)\n            return OPUS_BUFFER_TOO_SMALL;\n         *ptr++ = (rp->toc&0xFC) | 0x3;\n         *ptr++ = count;\n      }\n      pad_amount = pad ? (maxlen-tot_size) : 0;\n      if (pad_amount != 0)\n      {\n         int nb_255s;\n         data[1] |= 0x40;\n         nb_255s = (pad_amount-1)/255;\n         for (i=0;i<nb_255s;i++)\n            *ptr++ = 255;\n         *ptr++ = pad_amount-255*nb_255s-1;\n         tot_size += pad_amount;\n      }\n      if (vbr)\n      {\n         for (i=0;i<count-1;i++)\n            ptr += encode_size(len[i], ptr);\n      }\n   }\n   if (self_delimited) {\n      int sdlen = encode_size(len[count-1], ptr);\n      ptr += sdlen;\n   }\n   /* Copy the actual data */\n   for (i=0;i<count;i++)\n   {\n      /* Using OPUS_MOVE() instead of OPUS_COPY() in case we're doing in-place\n         padding from opus_packet_pad or opus_packet_unpad(). */\n      celt_assert(frames[i] + len[i] <= data || ptr <= frames[i]);\n      OPUS_MOVE(ptr, frames[i], len[i]);\n      ptr += len[i];\n   }\n   if (pad)\n   {\n      /* Fill padding with zeros. */\n      while (ptr<data+maxlen)\n         *ptr++=0;\n   }\n   return tot_size;\n}\n\nopus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen)\n{\n   return opus_repacketizer_out_range_impl(rp, begin, end, data, maxlen, 0, 0);\n}\n\nopus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen)\n{\n   return opus_repacketizer_out_range_impl(rp, 0, rp->nb_frames, data, maxlen, 0, 0);\n}\n\nint opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len)\n{\n   OpusRepacketizer rp;\n   opus_int32 ret;\n   if (len < 1)\n      return OPUS_BAD_ARG;\n   if (len==new_len)\n      return OPUS_OK;\n   else if (len > new_len)\n      return OPUS_BAD_ARG;\n   opus_repacketizer_init(&rp);\n   /* Moving payload to the end of the packet so we can do in-place padding */\n   OPUS_MOVE(data+new_len-len, data, len);\n   opus_repacketizer_cat(&rp, data+new_len-len, len);\n   ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, new_len, 0, 1);\n   if (ret > 0)\n      return OPUS_OK;\n   else\n      return ret;\n}\n\nopus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len)\n{\n   OpusRepacketizer rp;\n   opus_int32 ret;\n   if (len < 1)\n      return OPUS_BAD_ARG;\n   opus_repacketizer_init(&rp);\n   ret = opus_repacketizer_cat(&rp, data, len);\n   if (ret < 0)\n      return ret;\n   ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, len, 0, 0);\n   celt_assert(ret > 0 && ret <= len);\n   return ret;\n}\n\nint opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams)\n{\n   int s;\n   int count;\n   unsigned char toc;\n   opus_int16 size[48];\n   opus_int32 packet_offset;\n   opus_int32 amount;\n\n   if (len < 1)\n      return OPUS_BAD_ARG;\n   if (len==new_len)\n      return OPUS_OK;\n   else if (len > new_len)\n      return OPUS_BAD_ARG;\n   amount = new_len - len;\n   /* Seek to last stream */\n   for (s=0;s<nb_streams-1;s++)\n   {\n      if (len<=0)\n         return OPUS_INVALID_PACKET;\n      count = opus_packet_parse_impl(data, len, 1, &toc, NULL,\n                                     size, NULL, &packet_offset);\n      if (count<0)\n         return count;\n      data += packet_offset;\n      len -= packet_offset;\n   }\n   return opus_packet_pad(data, len, len+amount);\n}\n\nopus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, int nb_streams)\n{\n   int s;\n   unsigned char toc;\n   opus_int16 size[48];\n   opus_int32 packet_offset;\n   OpusRepacketizer rp;\n   unsigned char *dst;\n   opus_int32 dst_len;\n\n   if (len < 1)\n      return OPUS_BAD_ARG;\n   dst = data;\n   dst_len = 0;\n   /* Unpad all frames */\n   for (s=0;s<nb_streams;s++)\n   {\n      opus_int32 ret;\n      int self_delimited = s!=nb_streams-1;\n      if (len<=0)\n         return OPUS_INVALID_PACKET;\n      opus_repacketizer_init(&rp);\n      ret = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,\n                                     size, NULL, &packet_offset);\n      if (ret<0)\n         return ret;\n      ret = opus_repacketizer_cat_impl(&rp, data, packet_offset, self_delimited);\n      if (ret < 0)\n         return ret;\n      ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, dst, len, self_delimited, 0);\n      if (ret < 0)\n         return ret;\n      else\n         dst_len += ret;\n      dst += ret;\n      data += packet_offset;\n      len -= packet_offset;\n   }\n   return dst_len;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/repacketizer_demo.c",
    "content": "/* Copyright (c) 2011 Xiph.Org Foundation\n   Written by Jean-Marc Valin */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"opus.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#define MAX_PACKETOUT 32000\n\nvoid usage(char *argv0)\n{\n   fprintf(stderr, \"usage: %s [options] input_file output_file\\n\", argv0);\n}\n\nstatic void int_to_char(opus_uint32 i, unsigned char ch[4])\n{\n    ch[0] = i>>24;\n    ch[1] = (i>>16)&0xFF;\n    ch[2] = (i>>8)&0xFF;\n    ch[3] = i&0xFF;\n}\n\nstatic opus_uint32 char_to_int(unsigned char ch[4])\n{\n    return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16)\n         | ((opus_uint32)ch[2]<< 8) |  (opus_uint32)ch[3];\n}\n\nint main(int argc, char *argv[])\n{\n   int i, eof=0;\n   FILE *fin, *fout;\n   unsigned char packets[48][1500];\n   int len[48];\n   int rng[48];\n   OpusRepacketizer *rp;\n   unsigned char output_packet[MAX_PACKETOUT];\n   int merge = 1, split=0;\n\n   if (argc < 3)\n   {\n      usage(argv[0]);\n      return EXIT_FAILURE;\n   }\n   for (i=1;i<argc-2;i++)\n   {\n      if (strcmp(argv[i], \"-merge\")==0)\n      {\n         merge = atoi(argv[i+1]);\n         if(merge<1)\n         {\n            fprintf(stderr, \"-merge parameter must be at least 1.\\n\");\n            return EXIT_FAILURE;\n         }\n         if(merge>48)\n         {\n            fprintf(stderr, \"-merge parameter must be less than 48.\\n\");\n            return EXIT_FAILURE;\n         }\n         i++;\n      } else if (strcmp(argv[i], \"-split\")==0)\n         split = 1;\n      else\n      {\n         fprintf(stderr, \"Unknown option: %s\\n\", argv[i]);\n         usage(argv[0]);\n         return EXIT_FAILURE;\n      }\n   }\n   fin = fopen(argv[argc-2], \"r\");\n   if(fin==NULL)\n   {\n     fprintf(stderr, \"Error opening input file: %s\\n\", argv[argc-2]);\n     return EXIT_FAILURE;\n   }\n   fout = fopen(argv[argc-1], \"w\");\n   if(fout==NULL)\n   {\n     fprintf(stderr, \"Error opening output file: %s\\n\", argv[argc-1]);\n     fclose(fin);\n     return EXIT_FAILURE;\n   }\n\n   rp = opus_repacketizer_create();\n   while (!eof)\n   {\n      int err;\n      int nb_packets=merge;\n      opus_repacketizer_init(rp);\n      for (i=0;i<nb_packets;i++)\n      {\n         unsigned char ch[4];\n         err = fread(ch, 1, 4, fin);\n         len[i] = char_to_int(ch);\n         /*fprintf(stderr, \"in len = %d\\n\", len[i]);*/\n         if (len[i]>1500 || len[i]<0)\n         {\n             if (feof(fin))\n             {\n                eof = 1;\n             } else {\n                fprintf(stderr, \"Invalid payload length\\n\");\n                fclose(fin);\n                fclose(fout);\n                return EXIT_FAILURE;\n             }\n             break;\n         }\n         err = fread(ch, 1, 4, fin);\n         rng[i] = char_to_int(ch);\n         err = fread(packets[i], 1, len[i], fin);\n         if (feof(fin))\n         {\n            eof = 1;\n            break;\n         }\n         err = opus_repacketizer_cat(rp, packets[i], len[i]);\n         if (err!=OPUS_OK)\n         {\n            fprintf(stderr, \"opus_repacketizer_cat() failed: %s\\n\", opus_strerror(err));\n            break;\n         }\n      }\n      nb_packets = i;\n\n      if (eof)\n         break;\n\n      if (!split)\n      {\n         err = opus_repacketizer_out(rp, output_packet, MAX_PACKETOUT);\n         if (err>0) {\n            unsigned char int_field[4];\n            int_to_char(err, int_field);\n            if(fwrite(int_field, 1, 4, fout)!=4){\n               fprintf(stderr, \"Error writing.\\n\");\n               return EXIT_FAILURE;\n            }\n            int_to_char(rng[nb_packets-1], int_field);\n            if (fwrite(int_field, 1, 4, fout)!=4) {\n               fprintf(stderr, \"Error writing.\\n\");\n               return EXIT_FAILURE;\n            }\n            if (fwrite(output_packet, 1, err, fout)!=(unsigned)err) {\n               fprintf(stderr, \"Error writing.\\n\");\n               return EXIT_FAILURE;\n            }\n            /*fprintf(stderr, \"out len = %d\\n\", err);*/\n         } else {\n            fprintf(stderr, \"opus_repacketizer_out() failed: %s\\n\", opus_strerror(err));\n         }\n      } else {\n         int nb_frames = opus_repacketizer_get_nb_frames(rp);\n         for (i=0;i<nb_frames;i++)\n         {\n            err = opus_repacketizer_out_range(rp, i, i+1, output_packet, MAX_PACKETOUT);\n            if (err>0) {\n               unsigned char int_field[4];\n               int_to_char(err, int_field);\n               if (fwrite(int_field, 1, 4, fout)!=4) {\n                  fprintf(stderr, \"Error writing.\\n\");\n                  return EXIT_FAILURE;\n               }\n               if (i==nb_frames-1)\n                  int_to_char(rng[nb_packets-1], int_field);\n               else\n                  int_to_char(0, int_field);\n               if (fwrite(int_field, 1, 4, fout)!=4) {\n                  fprintf(stderr, \"Error writing.\\n\");\n                  return EXIT_FAILURE;\n               }\n               if (fwrite(output_packet, 1, err, fout)!=(unsigned)err) {\n                  fprintf(stderr, \"Error writing.\\n\");\n                  return EXIT_FAILURE;\n               }\n               /*fprintf(stderr, \"out len = %d\\n\", err);*/\n            } else {\n               fprintf(stderr, \"opus_repacketizer_out() failed: %s\\n\", opus_strerror(err));\n            }\n\n         }\n      }\n   }\n\n   fclose(fin);\n   fclose(fout);\n   return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/src/tansig_table.h",
    "content": "/* This file is auto-generated by gen_tables */\n\nstatic const float tansig_table[201] = {\n0.000000f, 0.039979f, 0.079830f, 0.119427f, 0.158649f,\n0.197375f, 0.235496f, 0.272905f, 0.309507f, 0.345214f,\n0.379949f, 0.413644f, 0.446244f, 0.477700f, 0.507977f,\n0.537050f, 0.564900f, 0.591519f, 0.616909f, 0.641077f,\n0.664037f, 0.685809f, 0.706419f, 0.725897f, 0.744277f,\n0.761594f, 0.777888f, 0.793199f, 0.807569f, 0.821040f,\n0.833655f, 0.845456f, 0.856485f, 0.866784f, 0.876393f,\n0.885352f, 0.893698f, 0.901468f, 0.908698f, 0.915420f,\n0.921669f, 0.927473f, 0.932862f, 0.937863f, 0.942503f,\n0.946806f, 0.950795f, 0.954492f, 0.957917f, 0.961090f,\n0.964028f, 0.966747f, 0.969265f, 0.971594f, 0.973749f,\n0.975743f, 0.977587f, 0.979293f, 0.980869f, 0.982327f,\n0.983675f, 0.984921f, 0.986072f, 0.987136f, 0.988119f,\n0.989027f, 0.989867f, 0.990642f, 0.991359f, 0.992020f,\n0.992631f, 0.993196f, 0.993718f, 0.994199f, 0.994644f,\n0.995055f, 0.995434f, 0.995784f, 0.996108f, 0.996407f,\n0.996682f, 0.996937f, 0.997172f, 0.997389f, 0.997590f,\n0.997775f, 0.997946f, 0.998104f, 0.998249f, 0.998384f,\n0.998508f, 0.998623f, 0.998728f, 0.998826f, 0.998916f,\n0.999000f, 0.999076f, 0.999147f, 0.999213f, 0.999273f,\n0.999329f, 0.999381f, 0.999428f, 0.999472f, 0.999513f,\n0.999550f, 0.999585f, 0.999617f, 0.999646f, 0.999673f,\n0.999699f, 0.999722f, 0.999743f, 0.999763f, 0.999781f,\n0.999798f, 0.999813f, 0.999828f, 0.999841f, 0.999853f,\n0.999865f, 0.999875f, 0.999885f, 0.999893f, 0.999902f,\n0.999909f, 0.999916f, 0.999923f, 0.999929f, 0.999934f,\n0.999939f, 0.999944f, 0.999948f, 0.999952f, 0.999956f,\n0.999959f, 0.999962f, 0.999965f, 0.999968f, 0.999970f,\n0.999973f, 0.999975f, 0.999977f, 0.999978f, 0.999980f,\n0.999982f, 0.999983f, 0.999984f, 0.999986f, 0.999987f,\n0.999988f, 0.999989f, 0.999990f, 0.999990f, 0.999991f,\n0.999992f, 0.999992f, 0.999993f, 0.999994f, 0.999994f,\n0.999994f, 0.999995f, 0.999995f, 0.999996f, 0.999996f,\n0.999996f, 0.999997f, 0.999997f, 0.999997f, 0.999997f,\n0.999997f, 0.999998f, 0.999998f, 0.999998f, 0.999998f,\n0.999998f, 0.999998f, 0.999999f, 0.999999f, 0.999999f,\n0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f,\n0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f,\n1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,\n1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,\n1.000000f,\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/test-driver",
    "content": "#!/bin/sh\n# test-driver - basic testsuite driver script.\n\nscriptversion=2013-07-13.22; # UTC\n\n# Copyright (C) 2011-2014 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2, or (at your option)\n# any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n# As a special exception to the GNU General Public License, if you\n# distribute this file as part of a program that contains a\n# configuration script generated by Autoconf, you may include it under\n# the same distribution terms that you use for the rest of that program.\n\n# This file is maintained in Automake, please report\n# bugs to <bug-automake@gnu.org> or send patches to\n# <automake-patches@gnu.org>.\n\n# Make unconditional expansion of undefined variables an error.  This\n# helps a lot in preventing typo-related bugs.\nset -u\n\nusage_error ()\n{\n  echo \"$0: $*\" >&2\n  print_usage >&2\n  exit 2\n}\n\nprint_usage ()\n{\n  cat <<END\nUsage:\n  test-driver --test-name=NAME --log-file=PATH --trs-file=PATH\n              [--expect-failure={yes|no}] [--color-tests={yes|no}]\n              [--enable-hard-errors={yes|no}] [--]\n              TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]\nThe '--test-name', '--log-file' and '--trs-file' options are mandatory.\nEND\n}\n\ntest_name= # Used for reporting.\nlog_file=  # Where to save the output of the test script.\ntrs_file=  # Where to save the metadata of the test run.\nexpect_failure=no\ncolor_tests=no\nenable_hard_errors=yes\nwhile test $# -gt 0; do\n  case $1 in\n  --help) print_usage; exit $?;;\n  --version) echo \"test-driver $scriptversion\"; exit $?;;\n  --test-name) test_name=$2; shift;;\n  --log-file) log_file=$2; shift;;\n  --trs-file) trs_file=$2; shift;;\n  --color-tests) color_tests=$2; shift;;\n  --expect-failure) expect_failure=$2; shift;;\n  --enable-hard-errors) enable_hard_errors=$2; shift;;\n  --) shift; break;;\n  -*) usage_error \"invalid option: '$1'\";;\n   *) break;;\n  esac\n  shift\ndone\n\nmissing_opts=\ntest x\"$test_name\" = x && missing_opts=\"$missing_opts --test-name\"\ntest x\"$log_file\"  = x && missing_opts=\"$missing_opts --log-file\"\ntest x\"$trs_file\"  = x && missing_opts=\"$missing_opts --trs-file\"\nif test x\"$missing_opts\" != x; then\n  usage_error \"the following mandatory options are missing:$missing_opts\"\nfi\n\nif test $# -eq 0; then\n  usage_error \"missing argument\"\nfi\n\nif test $color_tests = yes; then\n  # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.\n  red='\u001b[0;31m' # Red.\n  grn='\u001b[0;32m' # Green.\n  lgn='\u001b[1;32m' # Light green.\n  blu='\u001b[1;34m' # Blue.\n  mgn='\u001b[0;35m' # Magenta.\n  std='\u001b[m'     # No color.\nelse\n  red= grn= lgn= blu= mgn= std=\nfi\n\ndo_exit='rm -f $log_file $trs_file; (exit $st); exit $st'\ntrap \"st=129; $do_exit\" 1\ntrap \"st=130; $do_exit\" 2\ntrap \"st=141; $do_exit\" 13\ntrap \"st=143; $do_exit\" 15\n\n# Test script is run here.\n\"$@\" >$log_file 2>&1\nestatus=$?\n\nif test $enable_hard_errors = no && test $estatus -eq 99; then\n  tweaked_estatus=1\nelse\n  tweaked_estatus=$estatus\nfi\n\ncase $tweaked_estatus:$expect_failure in\n  0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;\n  0:*)   col=$grn res=PASS  recheck=no  gcopy=no;;\n  77:*)  col=$blu res=SKIP  recheck=no  gcopy=yes;;\n  99:*)  col=$mgn res=ERROR recheck=yes gcopy=yes;;\n  *:yes) col=$lgn res=XFAIL recheck=no  gcopy=yes;;\n  *:*)   col=$red res=FAIL  recheck=yes gcopy=yes;;\nesac\n\n# Report the test outcome and exit status in the logs, so that one can\n# know whether the test passed or failed simply by looking at the '.log'\n# file, without the need of also peaking into the corresponding '.trs'\n# file (automake bug#11814).\necho \"$res $test_name (exit status: $estatus)\" >>$log_file\n\n# Report outcome to console.\necho \"${col}${res}${std}: $test_name\"\n\n# Register the test result, and other relevant metadata.\necho \":test-result: $res\" > $trs_file\necho \":global-test-result: $res\" >> $trs_file\necho \":recheck: $recheck\" >> $trs_file\necho \":copy-in-global-log: $gcopy\" >> $trs_file\n\n# Local Variables:\n# mode: shell-script\n# sh-indentation: 2\n# eval: (add-hook 'write-file-hooks 'time-stamp)\n# time-stamp-start: \"scriptversion=\"\n# time-stamp-format: \"%:y-%02m-%02d.%02H\"\n# time-stamp-time-zone: \"UTC\"\n# time-stamp-end: \"; # UTC\"\n# End:\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/tests/run_vectors.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 2011-2012 Jean-Marc Valin\n#\n#  This file is extracted from RFC6716. Please see that RFC for additional\n#  information.\n#\n#  Redistribution and use in source and binary forms, with or without\n#  modification, are permitted provided that the following conditions\n#  are met:\n#\n#  - Redistributions of source code must retain the above copyright\n#  notice, this list of conditions and the following disclaimer.\n#\n#  - Redistributions in binary form must reproduce the above copyright\n#  notice, this list of conditions and the following disclaimer in the\n#  documentation and/or other materials provided with the distribution.\n#\n#  - Neither the name of Internet Society, IETF or IETF Trust, nor the\n#  names of specific contributors, may be used to endorse or promote\n#  products derived from this software without specific prior written\n#  permission.\n#\n#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n#  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n#  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nrm logs_mono.txt\nrm logs_stereo.txt\n\nif [ \"$#\" -ne \"3\" ]; then\n    echo \"usage: run_vectors.sh <exec path> <vector path> <rate>\"\n    exit 1\nfi\n\nCMD_PATH=$1\nVECTOR_PATH=$2\nRATE=$3\n\n: ${OPUS_DEMO:=$CMD_PATH/opus_demo}\n: ${OPUS_COMPARE:=$CMD_PATH/opus_compare}\n\nif [ -d $VECTOR_PATH ]; then\n    echo Test vectors found in $VECTOR_PATH\nelse\n    echo No test vectors found\n    #Don't make the test fail here because the test vectors\n    #will be distributed separately\n    exit 0\nfi\n\nif [ ! -x $OPUS_COMPARE ]; then\n    echo ERROR: Compare program not found: $OPUS_COMPARE\n    exit 1\nfi\n\nif [ -x $OPUS_DEMO ]; then\n    echo Decoding with $OPUS_DEMO\nelse\n    echo ERROR: Decoder not found: $OPUS_DEMO\n    exit 1\nfi\n\necho \"==============\"\necho Testing mono\necho \"==============\"\necho\n\nfor file in 01 02 03 04 05 06 07 08 09 10 11 12\ndo\n    if [ -e $VECTOR_PATH/testvector$file.bit ]; then\n        echo Testing testvector$file\n    else\n        echo Bitstream file not found: testvector$file.bit\n    fi\n    if $OPUS_DEMO -d $RATE 1 $VECTOR_PATH/testvector$file.bit tmp.out >> logs_mono.txt 2>&1; then\n        echo successfully decoded\n    else\n        echo ERROR: decoding failed\n        exit 1\n    fi\n    $OPUS_COMPARE -r $RATE $VECTOR_PATH/testvector$file.dec tmp.out >> logs_mono.txt 2>&1\n    float_ret=$?\n    if [ \"$float_ret\" -eq \"0\" ]; then\n        echo output matches reference\n    else\n        echo ERROR: output does not match reference\n        exit 1\n    fi\n    echo\ndone\n\necho \"==============\"\necho Testing stereo\necho \"==============\"\necho\n\nfor file in 01 02 03 04 05 06 07 08 09 10 11 12\ndo\n    if [ -e $VECTOR_PATH/testvector$file.bit ]; then\n        echo Testing testvector$file\n    else\n        echo Bitstream file not found: testvector$file\n    fi\n    if $OPUS_DEMO -d $RATE 2 $VECTOR_PATH/testvector$file.bit tmp.out >> logs_stereo.txt 2>&1; then\n        echo successfully decoded\n    else\n        echo ERROR: decoding failed\n        exit 1\n    fi\n    $OPUS_COMPARE -s -r $RATE $VECTOR_PATH/testvector$file.dec tmp.out >> logs_stereo.txt 2>&1\n    float_ret=$?\n    if [ \"$float_ret\" -eq \"0\" ]; then\n        echo output matches reference\n    else\n        echo ERROR: output does not match reference\n        exit 1\n    fi\n    echo\ndone\n\n\n\necho All tests have passed successfully\ngrep quality logs_mono.txt | awk '{sum+=$4}END{print \"Average mono quality is\", sum/NR, \"%\"}'\ngrep quality logs_stereo.txt | awk '{sum+=$4}END{print \"Average stereo quality is\", sum/NR, \"%\"}'\n\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/tests/test_opus_api.c",
    "content": "/* Copyright (c) 2011-2013 Xiph.Org Foundation\n   Written by Gregory Maxwell */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/* This tests the API presented by the libopus system.\n   It does not attempt to extensively exercise the codec internals.\n   The strategy here is to simply the API interface invariants:\n   That sane options are accepted, insane options are rejected,\n   and that nothing blows up. In particular we don't actually test\n   that settings are heeded by the codec (though we do check that\n   get after set returns a sane value when it should). Other\n   tests check the actual codec behavior.\n   In cases where its reasonable to do so we test exhaustively,\n   but its not reasonable to do so in all cases.\n   Although these tests are simple they found several library bugs\n   when they were initially developed. */\n\n/* These tests are more sensitive if compiled with -DVALGRIND and\n   run inside valgrind. Malloc failure testing requires glibc. */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n#include \"arch.h\"\n#include \"opus_multistream.h\"\n#include \"opus.h\"\n#include \"test_opus_common.h\"\n\n#ifdef VALGRIND\n#include <valgrind/memcheck.h>\n#define VG_UNDEF(x,y) VALGRIND_MAKE_MEM_UNDEFINED((x),(y))\n#define VG_CHECK(x,y) VALGRIND_CHECK_MEM_IS_DEFINED((x),(y))\n#else\n#define VG_UNDEF(x,y)\n#define VG_CHECK(x,y)\n#endif\n\n#if defined(HAVE___MALLOC_HOOK)\n#define MALLOC_FAIL\n#include \"os_support.h\"\n#include <malloc.h>\n\nstatic const opus_int32 opus_apps[3] = {OPUS_APPLICATION_VOIP,\n       OPUS_APPLICATION_AUDIO,OPUS_APPLICATION_RESTRICTED_LOWDELAY};\n\nvoid *malloc_hook(__attribute__((unused)) size_t size,\n                  __attribute__((unused)) const void *caller)\n{\n   return 0;\n}\n#endif\n\nstatic const opus_int32 opus_rates[5] = {48000,24000,16000,12000,8000};\n\nopus_int32 test_dec_api(void)\n{\n   opus_uint32 dec_final_range;\n   OpusDecoder *dec;\n   OpusDecoder *dec2;\n   opus_int32 i,j,cfgs;\n   unsigned char packet[1276];\n#ifndef DISABLE_FLOAT_API\n   float fbuf[960*2];\n#endif\n   short sbuf[960*2];\n   int c,err;\n   opus_int32 *nullvalue;\n   nullvalue=0;\n\n   cfgs=0;\n   /*First test invalid configurations which should fail*/\n   fprintf(stdout,\"\\n  Decoder basic API tests\\n\");\n   fprintf(stdout,\"  ---------------------------------------------------\\n\");\n   for(c=0;c<4;c++)\n   {\n      i=opus_decoder_get_size(c);\n      if(((c==1||c==2)&&(i<=2048||i>1<<16))||((c!=1&&c!=2)&&i!=0))test_failed();\n      fprintf(stdout,\"    opus_decoder_get_size(%d)=%d ...............%s OK.\\n\",c,i,i>0?\"\":\"....\");\n      cfgs++;\n   }\n\n   /*Test with unsupported sample rates*/\n   for(c=0;c<4;c++)\n   {\n      for(i=-7;i<=96000;i++)\n      {\n         int fs;\n         if((i==8000||i==12000||i==16000||i==24000||i==48000)&&(c==1||c==2))continue;\n         switch(i)\n         {\n           case(-5):fs=-8000;break;\n           case(-6):fs=INT32_MAX;break;\n           case(-7):fs=INT32_MIN;break;\n           default:fs=i;\n         }\n         err = OPUS_OK;\n         VG_UNDEF(&err,sizeof(err));\n         dec = opus_decoder_create(fs, c, &err);\n         if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();\n         cfgs++;\n         dec = opus_decoder_create(fs, c, 0);\n         if(dec!=NULL)test_failed();\n         cfgs++;\n         dec=malloc(opus_decoder_get_size(2));\n         if(dec==NULL)test_failed();\n         err = opus_decoder_init(dec,fs,c);\n         if(err!=OPUS_BAD_ARG)test_failed();\n         cfgs++;\n         free(dec);\n      }\n   }\n\n   VG_UNDEF(&err,sizeof(err));\n   dec = opus_decoder_create(48000, 2, &err);\n   if(err!=OPUS_OK || dec==NULL)test_failed();\n   VG_CHECK(dec,opus_decoder_get_size(2));\n   cfgs++;\n\n   fprintf(stdout,\"    opus_decoder_create() ........................ OK.\\n\");\n   fprintf(stdout,\"    opus_decoder_init() .......................... OK.\\n\");\n\n   err=opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE((opus_uint32 *)NULL));\n   if(err != OPUS_BAD_ARG)test_failed();\n   VG_UNDEF(&dec_final_range,sizeof(dec_final_range));\n   err=opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));\n   if(err!=OPUS_OK)test_failed();\n   VG_CHECK(&dec_final_range,sizeof(dec_final_range));\n   fprintf(stdout,\"    OPUS_GET_FINAL_RANGE ......................... OK.\\n\");\n   cfgs++;\n\n   err=opus_decoder_ctl(dec,OPUS_UNIMPLEMENTED);\n   if(err!=OPUS_UNIMPLEMENTED)test_failed();\n   fprintf(stdout,\"    OPUS_UNIMPLEMENTED ........................... OK.\\n\");\n   cfgs++;\n\n   err=opus_decoder_ctl(dec, OPUS_GET_BANDWIDTH((opus_int32 *)NULL));\n   if(err != OPUS_BAD_ARG)test_failed();\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_decoder_ctl(dec, OPUS_GET_BANDWIDTH(&i));\n   if(err != OPUS_OK || i!=0)test_failed();\n   fprintf(stdout,\"    OPUS_GET_BANDWIDTH ........................... OK.\\n\");\n   cfgs++;\n\n   err=opus_decoder_ctl(dec, OPUS_GET_SAMPLE_RATE((opus_int32 *)NULL));\n   if(err != OPUS_BAD_ARG)test_failed();\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_decoder_ctl(dec, OPUS_GET_SAMPLE_RATE(&i));\n   if(err != OPUS_OK || i!=48000)test_failed();\n   fprintf(stdout,\"    OPUS_GET_SAMPLE_RATE ......................... OK.\\n\");\n   cfgs++;\n\n   /*GET_PITCH has different execution paths depending on the previously decoded frame.*/\n   err=opus_decoder_ctl(dec, OPUS_GET_PITCH(nullvalue));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_decoder_ctl(dec, OPUS_GET_PITCH(&i));\n   if(err != OPUS_OK || i>0 || i<-1)test_failed();\n   cfgs++;\n   VG_UNDEF(packet,sizeof(packet));\n   packet[0]=63<<2;packet[1]=packet[2]=0;\n   if(opus_decode(dec, packet, 3, sbuf, 960, 0)!=960)test_failed();\n   cfgs++;\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_decoder_ctl(dec, OPUS_GET_PITCH(&i));\n   if(err != OPUS_OK || i>0 || i<-1)test_failed();\n   cfgs++;\n   packet[0]=1;\n   if(opus_decode(dec, packet, 1, sbuf, 960, 0)!=960)test_failed();\n   cfgs++;\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_decoder_ctl(dec, OPUS_GET_PITCH(&i));\n   if(err != OPUS_OK || i>0 || i<-1)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    OPUS_GET_PITCH ............................... OK.\\n\");\n\n   err=opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION((opus_int32 *)NULL));\n   if(err != OPUS_BAD_ARG)test_failed();\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&i));\n   if(err != OPUS_OK || i!=960)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    OPUS_GET_LAST_PACKET_DURATION ................ OK.\\n\");\n\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_decoder_ctl(dec, OPUS_GET_GAIN(&i));\n   VG_CHECK(&i,sizeof(i));\n   if(err != OPUS_OK || i!=0)test_failed();\n   cfgs++;\n   err=opus_decoder_ctl(dec, OPUS_GET_GAIN(nullvalue));\n   if(err != OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   err=opus_decoder_ctl(dec, OPUS_SET_GAIN(-32769));\n   if(err != OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   err=opus_decoder_ctl(dec, OPUS_SET_GAIN(32768));\n   if(err != OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   err=opus_decoder_ctl(dec, OPUS_SET_GAIN(-15));\n   if(err != OPUS_OK)test_failed();\n   cfgs++;\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_decoder_ctl(dec, OPUS_GET_GAIN(&i));\n   VG_CHECK(&i,sizeof(i));\n   if(err != OPUS_OK || i!=-15)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    OPUS_SET_GAIN ................................ OK.\\n\");\n   fprintf(stdout,\"    OPUS_GET_GAIN ................................ OK.\\n\");\n\n   /*Reset the decoder*/\n   dec2=malloc(opus_decoder_get_size(2));\n   memcpy(dec2,dec,opus_decoder_get_size(2));\n   if(opus_decoder_ctl(dec, OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n   if(memcmp(dec2,dec,opus_decoder_get_size(2))==0)test_failed();\n   free(dec2);\n   fprintf(stdout,\"    OPUS_RESET_STATE ............................. OK.\\n\");\n   cfgs++;\n\n   VG_UNDEF(packet,sizeof(packet));\n   packet[0]=0;\n   if(opus_decoder_get_nb_samples(dec,packet,1)!=480)test_failed();\n   if(opus_packet_get_nb_samples(packet,1,48000)!=480)test_failed();\n   if(opus_packet_get_nb_samples(packet,1,96000)!=960)test_failed();\n   if(opus_packet_get_nb_samples(packet,1,32000)!=320)test_failed();\n   if(opus_packet_get_nb_samples(packet,1,8000)!=80)test_failed();\n   packet[0]=3;\n   if(opus_packet_get_nb_samples(packet,1,24000)!=OPUS_INVALID_PACKET)test_failed();\n   packet[0]=(63<<2)|3;\n   packet[1]=63;\n   if(opus_packet_get_nb_samples(packet,0,24000)!=OPUS_BAD_ARG)test_failed();\n   if(opus_packet_get_nb_samples(packet,2,48000)!=OPUS_INVALID_PACKET)test_failed();\n   if(opus_decoder_get_nb_samples(dec,packet,2)!=OPUS_INVALID_PACKET)test_failed();\n   fprintf(stdout,\"    opus_{packet,decoder}_get_nb_samples() ....... OK.\\n\");\n   cfgs+=9;\n\n   if(OPUS_BAD_ARG!=opus_packet_get_nb_frames(packet,0))test_failed();\n   for(i=0;i<256;i++) {\n     int l1res[4]={1,2,2,OPUS_INVALID_PACKET};\n     packet[0]=i;\n     if(l1res[packet[0]&3]!=opus_packet_get_nb_frames(packet,1))test_failed();\n     cfgs++;\n     for(j=0;j<256;j++) {\n       packet[1]=j;\n       if(((packet[0]&3)!=3?l1res[packet[0]&3]:packet[1]&63)!=opus_packet_get_nb_frames(packet,2))test_failed();\n       cfgs++;\n     }\n   }\n   fprintf(stdout,\"    opus_packet_get_nb_frames() .................. OK.\\n\");\n\n   for(i=0;i<256;i++) {\n     int bw;\n     packet[0]=i;\n     bw=packet[0]>>4;\n     bw=OPUS_BANDWIDTH_NARROWBAND+(((((bw&7)*9)&(63-(bw&8)))+2+12*((bw&8)!=0))>>4);\n     if(bw!=opus_packet_get_bandwidth(packet))test_failed();\n     cfgs++;\n   }\n   fprintf(stdout,\"    opus_packet_get_bandwidth() .................. OK.\\n\");\n\n   for(i=0;i<256;i++) {\n     int fp3s,rate;\n     packet[0]=i;\n     fp3s=packet[0]>>3;\n     fp3s=((((3-(fp3s&3))*13&119)+9)>>2)*((fp3s>13)*(3-((fp3s&3)==3))+1)*25;\n     for(rate=0;rate<5;rate++) {\n       if((opus_rates[rate]*3/fp3s)!=opus_packet_get_samples_per_frame(packet,opus_rates[rate]))test_failed();\n       cfgs++;\n     }\n   }\n   fprintf(stdout,\"    opus_packet_get_samples_per_frame() .......... OK.\\n\");\n\n   packet[0]=(63<<2)+3;\n   packet[1]=49;\n   for(j=2;j<51;j++)packet[j]=0;\n   VG_UNDEF(sbuf,sizeof(sbuf));\n   if(opus_decode(dec, packet, 51, sbuf, 960, 0)!=OPUS_INVALID_PACKET)test_failed();\n   cfgs++;\n   packet[0]=(63<<2);\n   packet[1]=packet[2]=0;\n   if(opus_decode(dec, packet, -1, sbuf, 960, 0)!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   if(opus_decode(dec, packet, 3, sbuf, 60, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed();\n   cfgs++;\n   if(opus_decode(dec, packet, 3, sbuf, 480, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed();\n   cfgs++;\n   if(opus_decode(dec, packet, 3, sbuf, 960, 0)!=960)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    opus_decode() ................................ OK.\\n\");\n#ifndef DISABLE_FLOAT_API\n   VG_UNDEF(fbuf,sizeof(fbuf));\n   if(opus_decode_float(dec, packet, 3, fbuf, 960, 0)!=960)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    opus_decode_float() .......................... OK.\\n\");\n#endif\n\n#if 0\n   /*These tests are disabled because the library crashes with null states*/\n   if(opus_decoder_ctl(0,OPUS_RESET_STATE)         !=OPUS_INVALID_STATE)test_failed();\n   if(opus_decoder_init(0,48000,1)                 !=OPUS_INVALID_STATE)test_failed();\n   if(opus_decode(0,packet,1,outbuf,2880,0)        !=OPUS_INVALID_STATE)test_failed();\n   if(opus_decode_float(0,packet,1,0,2880,0)       !=OPUS_INVALID_STATE)test_failed();\n   if(opus_decoder_get_nb_samples(0,packet,1)      !=OPUS_INVALID_STATE)test_failed();\n   if(opus_packet_get_nb_frames(NULL,1)            !=OPUS_BAD_ARG)test_failed();\n   if(opus_packet_get_bandwidth(NULL)              !=OPUS_BAD_ARG)test_failed();\n   if(opus_packet_get_samples_per_frame(NULL,48000)!=OPUS_BAD_ARG)test_failed();\n#endif\n   opus_decoder_destroy(dec);\n   cfgs++;\n   fprintf(stdout,\"                   All decoder interface tests passed\\n\");\n   fprintf(stdout,\"                             (%6d API invocations)\\n\",cfgs);\n   return cfgs;\n}\n\nopus_int32 test_msdec_api(void)\n{\n   opus_uint32 dec_final_range;\n   OpusMSDecoder *dec;\n   OpusDecoder *streamdec;\n   opus_int32 i,j,cfgs;\n   unsigned char packet[1276];\n   unsigned char mapping[256];\n#ifndef DISABLE_FLOAT_API\n   float fbuf[960*2];\n#endif\n   short sbuf[960*2];\n   int a,b,c,err;\n#if 0\n   /*Relevant test not enabled for multistream*/\n   int *nullvalue;\n   nullvalue=0;\n#endif\n\n   mapping[0]=0;\n   mapping[1]=1;\n   for(i=2;i<256;i++)VG_UNDEF(&mapping[i],sizeof(unsigned char));\n\n   cfgs=0;\n   /*First test invalid configurations which should fail*/\n   fprintf(stdout,\"\\n  Multistream decoder basic API tests\\n\");\n   fprintf(stdout,\"  ---------------------------------------------------\\n\");\n   for(a=-1;a<4;a++)\n   {\n      for(b=-1;b<4;b++)\n      {\n         i=opus_multistream_decoder_get_size(a,b);\n         if(((a>0&&b<=a&&b>=0)&&(i<=2048||i>((1<<16)*a)))||((a<1||b>a||b<0)&&i!=0))test_failed();\n         fprintf(stdout,\"    opus_multistream_decoder_get_size(%2d,%2d)=%d %sOK.\\n\",a,b,i,i>0?\"\":\"... \");\n         cfgs++;\n      }\n   }\n\n   /*Test with unsupported sample rates*/\n   for(c=1;c<3;c++)\n   {\n      for(i=-7;i<=96000;i++)\n      {\n         int fs;\n         if((i==8000||i==12000||i==16000||i==24000||i==48000)&&(c==1||c==2))continue;\n         switch(i)\n         {\n           case(-5):fs=-8000;break;\n           case(-6):fs=INT32_MAX;break;\n           case(-7):fs=INT32_MIN;break;\n           default:fs=i;\n         }\n         err = OPUS_OK;\n         VG_UNDEF(&err,sizeof(err));\n         dec = opus_multistream_decoder_create(fs, c, 1, c-1, mapping, &err);\n         if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();\n         cfgs++;\n         dec = opus_multistream_decoder_create(fs, c, 1, c-1, mapping, 0);\n         if(dec!=NULL)test_failed();\n         cfgs++;\n         dec=malloc(opus_multistream_decoder_get_size(1,1));\n         if(dec==NULL)test_failed();\n         err = opus_multistream_decoder_init(dec,fs,c,1,c-1, mapping);\n         if(err!=OPUS_BAD_ARG)test_failed();\n         cfgs++;\n         free(dec);\n      }\n   }\n\n   for(c=0;c<2;c++)\n   {\n      int *ret_err;\n      ret_err = c?0:&err;\n\n      mapping[0]=0;\n      mapping[1]=1;\n      for(i=2;i<256;i++)VG_UNDEF(&mapping[i],sizeof(unsigned char));\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();\n      cfgs++;\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      mapping[0]=mapping[1]=0;\n      dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed();\n      cfgs++;\n      opus_multistream_decoder_destroy(dec);\n      cfgs++;\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      dec = opus_multistream_decoder_create(48000, 1, 4, 1, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed();\n      cfgs++;\n\n      err = opus_multistream_decoder_init(dec,48000, 1, 0, 0, mapping);\n      if(err!=OPUS_BAD_ARG)test_failed();\n      cfgs++;\n\n      err = opus_multistream_decoder_init(dec,48000, 1, 1, -1, mapping);\n      if(err!=OPUS_BAD_ARG)test_failed();\n      cfgs++;\n\n      opus_multistream_decoder_destroy(dec);\n      cfgs++;\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      dec = opus_multistream_decoder_create(48000, 2, 1, 1, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed();\n      cfgs++;\n      opus_multistream_decoder_destroy(dec);\n      cfgs++;\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      dec = opus_multistream_decoder_create(48000, 255, 255, 1, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();\n      cfgs++;\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      dec = opus_multistream_decoder_create(48000, -1, 1, 1, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();\n      cfgs++;\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      dec = opus_multistream_decoder_create(48000, 0, 1, 1, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();\n      cfgs++;\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      dec = opus_multistream_decoder_create(48000, 1, -1, 2, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();\n      cfgs++;\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      dec = opus_multistream_decoder_create(48000, 1, -1, -1, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();\n      cfgs++;\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      dec = opus_multistream_decoder_create(48000, 256, 255, 1, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();\n      cfgs++;\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      dec = opus_multistream_decoder_create(48000, 256, 255, 0, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();\n      cfgs++;\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      mapping[0]=255;\n      mapping[1]=1;\n      mapping[2]=2;\n      dec = opus_multistream_decoder_create(48000, 3, 2, 0, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();\n      cfgs++;\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      mapping[0]=0;\n      mapping[1]=0;\n      mapping[2]=0;\n      dec = opus_multistream_decoder_create(48000, 3, 2, 1, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed();\n      cfgs++;\n      opus_multistream_decoder_destroy(dec);\n      cfgs++;\n\n      VG_UNDEF(ret_err,sizeof(*ret_err));\n      mapping[0]=0;\n      mapping[1]=255;\n      mapping[2]=1;\n      mapping[3]=2;\n      mapping[4]=3;\n      dec = opus_multistream_decoder_create(48001, 5, 4, 1, mapping, ret_err);\n      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}\n      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();\n      cfgs++;\n   }\n\n   VG_UNDEF(&err,sizeof(err));\n   mapping[0]=0;\n   mapping[1]=255;\n   mapping[2]=1;\n   mapping[3]=2;\n   dec = opus_multistream_decoder_create(48000, 4, 2, 1, mapping, &err);\n   VG_CHECK(&err,sizeof(err));\n   if(err!=OPUS_OK || dec==NULL)test_failed();\n   cfgs++;\n\n   fprintf(stdout,\"    opus_multistream_decoder_create() ............ OK.\\n\");\n   fprintf(stdout,\"    opus_multistream_decoder_init() .............. OK.\\n\");\n\n   VG_UNDEF(&dec_final_range,sizeof(dec_final_range));\n   err=opus_multistream_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));\n   if(err!=OPUS_OK)test_failed();\n   VG_CHECK(&dec_final_range,sizeof(dec_final_range));\n   fprintf(stdout,\"    OPUS_GET_FINAL_RANGE ......................... OK.\\n\");\n   cfgs++;\n\n   streamdec=0;\n   VG_UNDEF(&streamdec,sizeof(streamdec));\n   err=opus_multistream_decoder_ctl(dec, OPUS_MULTISTREAM_GET_DECODER_STATE(-1,&streamdec));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   err=opus_multistream_decoder_ctl(dec, OPUS_MULTISTREAM_GET_DECODER_STATE(1,&streamdec));\n   if(err!=OPUS_OK||streamdec==NULL)test_failed();\n   VG_CHECK(streamdec,opus_decoder_get_size(1));\n   cfgs++;\n   err=opus_multistream_decoder_ctl(dec, OPUS_MULTISTREAM_GET_DECODER_STATE(2,&streamdec));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   err=opus_multistream_decoder_ctl(dec, OPUS_MULTISTREAM_GET_DECODER_STATE(0,&streamdec));\n   if(err!=OPUS_OK||streamdec==NULL)test_failed();\n   VG_CHECK(streamdec,opus_decoder_get_size(1));\n   fprintf(stdout,\"    OPUS_MULTISTREAM_GET_DECODER_STATE ........... OK.\\n\");\n   cfgs++;\n\n   for(j=0;j<2;j++)\n   {\n      OpusDecoder *od;\n      err=opus_multistream_decoder_ctl(dec,OPUS_MULTISTREAM_GET_DECODER_STATE(j,&od));\n      if(err != OPUS_OK)test_failed();\n      VG_UNDEF(&i,sizeof(i));\n      err=opus_decoder_ctl(od, OPUS_GET_GAIN(&i));\n      VG_CHECK(&i,sizeof(i));\n      if(err != OPUS_OK || i!=0)test_failed();\n      cfgs++;\n   }\n   err=opus_multistream_decoder_ctl(dec,OPUS_SET_GAIN(15));\n   if(err!=OPUS_OK)test_failed();\n   fprintf(stdout,\"    OPUS_SET_GAIN ................................ OK.\\n\");\n   for(j=0;j<2;j++)\n   {\n      OpusDecoder *od;\n      err=opus_multistream_decoder_ctl(dec,OPUS_MULTISTREAM_GET_DECODER_STATE(j,&od));\n      if(err != OPUS_OK)test_failed();\n      VG_UNDEF(&i,sizeof(i));\n      err=opus_decoder_ctl(od, OPUS_GET_GAIN(&i));\n      VG_CHECK(&i,sizeof(i));\n      if(err != OPUS_OK || i!=15)test_failed();\n      cfgs++;\n   }\n   fprintf(stdout,\"    OPUS_GET_GAIN ................................ OK.\\n\");\n\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_multistream_decoder_ctl(dec, OPUS_GET_BANDWIDTH(&i));\n   if(err != OPUS_OK || i!=0)test_failed();\n   fprintf(stdout,\"    OPUS_GET_BANDWIDTH ........................... OK.\\n\");\n   cfgs++;\n\n   err=opus_multistream_decoder_ctl(dec,OPUS_UNIMPLEMENTED);\n   if(err!=OPUS_UNIMPLEMENTED)test_failed();\n   fprintf(stdout,\"    OPUS_UNIMPLEMENTED ........................... OK.\\n\");\n   cfgs++;\n\n#if 0\n   /*Currently unimplemented for multistream*/\n   /*GET_PITCH has different execution paths depending on the previously decoded frame.*/\n   err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(nullvalue));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(&i));\n   if(err != OPUS_OK || i>0 || i<-1)test_failed();\n   cfgs++;\n   VG_UNDEF(packet,sizeof(packet));\n   packet[0]=63<<2;packet[1]=packet[2]=0;\n   if(opus_multistream_decode(dec, packet, 3, sbuf, 960, 0)!=960)test_failed();\n   cfgs++;\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(&i));\n   if(err != OPUS_OK || i>0 || i<-1)test_failed();\n   cfgs++;\n   packet[0]=1;\n   if(opus_multistream_decode(dec, packet, 1, sbuf, 960, 0)!=960)test_failed();\n   cfgs++;\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(&i));\n   if(err != OPUS_OK || i>0 || i<-1)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    OPUS_GET_PITCH ............................... OK.\\n\");\n#endif\n\n   /*Reset the decoder*/\n   if(opus_multistream_decoder_ctl(dec, OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n   fprintf(stdout,\"    OPUS_RESET_STATE ............................. OK.\\n\");\n   cfgs++;\n\n   opus_multistream_decoder_destroy(dec);\n   cfgs++;\n   VG_UNDEF(&err,sizeof(err));\n   dec = opus_multistream_decoder_create(48000, 2, 1, 1, mapping, &err);\n   if(err!=OPUS_OK || dec==NULL)test_failed();\n   cfgs++;\n\n   packet[0]=(63<<2)+3;\n   packet[1]=49;\n   for(j=2;j<51;j++)packet[j]=0;\n   VG_UNDEF(sbuf,sizeof(sbuf));\n   if(opus_multistream_decode(dec, packet, 51, sbuf, 960, 0)!=OPUS_INVALID_PACKET)test_failed();\n   cfgs++;\n   packet[0]=(63<<2);\n   packet[1]=packet[2]=0;\n   if(opus_multistream_decode(dec, packet, -1, sbuf, 960, 0)!=OPUS_BAD_ARG){printf(\"%d\\n\",opus_multistream_decode(dec, packet, -1, sbuf, 960, 0));test_failed();}\n   cfgs++;\n   if(opus_multistream_decode(dec, packet, 3, sbuf, 60, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed();\n   cfgs++;\n   if(opus_multistream_decode(dec, packet, 3, sbuf, 480, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed();\n   cfgs++;\n   if(opus_multistream_decode(dec, packet, 3, sbuf, 960, 0)!=960)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    opus_multistream_decode() .................... OK.\\n\");\n#ifndef DISABLE_FLOAT_API\n   VG_UNDEF(fbuf,sizeof(fbuf));\n   if(opus_multistream_decode_float(dec, packet, 3, fbuf, 960, 0)!=960)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    opus_multistream_decode_float() .............. OK.\\n\");\n#endif\n\n#if 0\n   /*These tests are disabled because the library crashes with null states*/\n   if(opus_multistream_decoder_ctl(0,OPUS_RESET_STATE)         !=OPUS_INVALID_STATE)test_failed();\n   if(opus_multistream_decoder_init(0,48000,1)                 !=OPUS_INVALID_STATE)test_failed();\n   if(opus_multistream_decode(0,packet,1,outbuf,2880,0)        !=OPUS_INVALID_STATE)test_failed();\n   if(opus_multistream_decode_float(0,packet,1,0,2880,0)       !=OPUS_INVALID_STATE)test_failed();\n   if(opus_multistream_decoder_get_nb_samples(0,packet,1)      !=OPUS_INVALID_STATE)test_failed();\n#endif\n   opus_multistream_decoder_destroy(dec);\n   cfgs++;\n   fprintf(stdout,\"       All multistream decoder interface tests passed\\n\");\n   fprintf(stdout,\"                             (%6d API invocations)\\n\",cfgs);\n   return cfgs;\n}\n\n#ifdef VALGRIND\n#define UNDEFINE_FOR_PARSE  toc=-1; \\\n   frames[0]=(unsigned char *)0; \\\n   frames[1]=(unsigned char *)0; \\\n   payload_offset=-1; \\\n   VG_UNDEF(&toc,sizeof(toc)); \\\n   VG_UNDEF(frames,sizeof(frames));\\\n   VG_UNDEF(&payload_offset,sizeof(payload_offset));\n#else\n#define UNDEFINE_FOR_PARSE  toc=-1; \\\n   frames[0]=(unsigned char *)0; \\\n   frames[1]=(unsigned char *)0; \\\n   payload_offset=-1;\n#endif\n\n/* This test exercises the heck out of the libopus parser.\n   It is much larger than the parser itself in part because\n   it tries to hit a lot of corner cases that could never\n   fail with the libopus code, but might be problematic for\n   other implementations. */\nopus_int32 test_parse(void)\n{\n   opus_int32 i,j,jj,sz;\n   unsigned char packet[1276];\n   opus_int32 cfgs,cfgs_total;\n   unsigned char toc;\n   const unsigned char *frames[48];\n   short size[48];\n   int payload_offset, ret;\n   fprintf(stdout,\"\\n  Packet header parsing tests\\n\");\n   fprintf(stdout,\"  ---------------------------------------------------\\n\");\n   memset(packet,0,sizeof(char)*1276);\n   packet[0]=63<<2;\n   if(opus_packet_parse(packet,1,&toc,frames,0,&payload_offset)!=OPUS_BAD_ARG)test_failed();\n   cfgs_total=cfgs=1;\n   /*code 0*/\n   for(i=0;i<64;i++)\n   {\n      packet[0]=i<<2;\n      UNDEFINE_FOR_PARSE\n      ret=opus_packet_parse(packet,4,&toc,frames,size,&payload_offset);\n      cfgs++;\n      if(ret!=1)test_failed();\n      if(size[0]!=3)test_failed();\n      if(frames[0]!=packet+1)test_failed();\n   }\n   fprintf(stdout,\"    code 0 (%2d cases) ............................ OK.\\n\",cfgs);\n   cfgs_total+=cfgs;cfgs=0;\n\n   /*code 1, two frames of the same size*/\n   for(i=0;i<64;i++)\n   {\n      packet[0]=(i<<2)+1;\n      for(jj=0;jj<=1275*2+3;jj++)\n      {\n         UNDEFINE_FOR_PARSE\n         ret=opus_packet_parse(packet,jj,&toc,frames,size,&payload_offset);\n         cfgs++;\n         if((jj&1)==1 && jj<=2551)\n         {\n            /* Must pass if payload length even (packet length odd) and\n               size<=2551, must fail otherwise. */\n            if(ret!=2)test_failed();\n            if(size[0]!=size[1] || size[0]!=((jj-1)>>1))test_failed();\n            if(frames[0]!=packet+1)test_failed();\n            if(frames[1]!=frames[0]+size[0])test_failed();\n            if((toc>>2)!=i)test_failed();\n         } else if(ret!=OPUS_INVALID_PACKET)test_failed();\n      }\n   }\n   fprintf(stdout,\"    code 1 (%6d cases) ........................ OK.\\n\",cfgs);\n   cfgs_total+=cfgs;cfgs=0;\n\n   for(i=0;i<64;i++)\n   {\n      /*code 2, length code overflow*/\n      packet[0]=(i<<2)+2;\n      UNDEFINE_FOR_PARSE\n      ret=opus_packet_parse(packet,1,&toc,frames,size,&payload_offset);\n      cfgs++;\n      if(ret!=OPUS_INVALID_PACKET)test_failed();\n      packet[1]=252;\n      UNDEFINE_FOR_PARSE\n      ret=opus_packet_parse(packet,2,&toc,frames,size,&payload_offset);\n      cfgs++;\n      if(ret!=OPUS_INVALID_PACKET)test_failed();\n      for(j=0;j<1275;j++)\n      {\n         if(j<252)packet[1]=j;\n         else{packet[1]=252+(j&3);packet[2]=(j-252)>>2;}\n         /*Code 2, one too short*/\n         UNDEFINE_FOR_PARSE\n         ret=opus_packet_parse(packet,j+(j<252?2:3)-1,&toc,frames,size,&payload_offset);\n         cfgs++;\n         if(ret!=OPUS_INVALID_PACKET)test_failed();\n         /*Code 2, one too long*/\n         UNDEFINE_FOR_PARSE\n         ret=opus_packet_parse(packet,j+(j<252?2:3)+1276,&toc,frames,size,&payload_offset);\n         cfgs++;\n         if(ret!=OPUS_INVALID_PACKET)test_failed();\n         /*Code 2, second zero*/\n         UNDEFINE_FOR_PARSE\n         ret=opus_packet_parse(packet,j+(j<252?2:3),&toc,frames,size,&payload_offset);\n         cfgs++;\n         if(ret!=2)test_failed();\n         if(size[0]!=j||size[1]!=0)test_failed();\n         if(frames[1]!=frames[0]+size[0])test_failed();\n         if((toc>>2)!=i)test_failed();\n         /*Code 2, normal*/\n         UNDEFINE_FOR_PARSE\n         ret=opus_packet_parse(packet,(j<<1)+4,&toc,frames,size,&payload_offset);\n         cfgs++;\n         if(ret!=2)test_failed();\n         if(size[0]!=j||size[1]!=(j<<1)+3-j-(j<252?1:2))test_failed();\n         if(frames[1]!=frames[0]+size[0])test_failed();\n         if((toc>>2)!=i)test_failed();\n      }\n   }\n   fprintf(stdout,\"    code 2 (%6d cases) ........................ OK.\\n\",cfgs);\n   cfgs_total+=cfgs;cfgs=0;\n\n   for(i=0;i<64;i++)\n   {\n      packet[0]=(i<<2)+3;\n      /*code 3, length code overflow*/\n      UNDEFINE_FOR_PARSE\n      ret=opus_packet_parse(packet,1,&toc,frames,size,&payload_offset);\n      cfgs++;\n      if(ret!=OPUS_INVALID_PACKET)test_failed();\n   }\n   fprintf(stdout,\"    code 3 m-truncation (%2d cases) ............... OK.\\n\",cfgs);\n   cfgs_total+=cfgs;cfgs=0;\n\n   for(i=0;i<64;i++)\n   {\n      /*code 3, m is zero or 49-63*/\n      packet[0]=(i<<2)+3;\n      for(jj=49;jj<=64;jj++)\n      {\n        packet[1]=0+(jj&63); /*CBR, no padding*/\n        UNDEFINE_FOR_PARSE\n        ret=opus_packet_parse(packet,1275,&toc,frames,size,&payload_offset);\n        cfgs++;\n        if(ret!=OPUS_INVALID_PACKET)test_failed();\n        packet[1]=128+(jj&63); /*VBR, no padding*/\n        UNDEFINE_FOR_PARSE\n        ret=opus_packet_parse(packet,1275,&toc,frames,size,&payload_offset);\n        cfgs++;\n        if(ret!=OPUS_INVALID_PACKET)test_failed();\n        packet[1]=64+(jj&63); /*CBR, padding*/\n        UNDEFINE_FOR_PARSE\n        ret=opus_packet_parse(packet,1275,&toc,frames,size,&payload_offset);\n        cfgs++;\n        if(ret!=OPUS_INVALID_PACKET)test_failed();\n        packet[1]=128+64+(jj&63); /*VBR, padding*/\n        UNDEFINE_FOR_PARSE\n        ret=opus_packet_parse(packet,1275,&toc,frames,size,&payload_offset);\n        cfgs++;\n        if(ret!=OPUS_INVALID_PACKET)test_failed();\n      }\n   }\n   fprintf(stdout,\"    code 3 m=0,49-64 (%2d cases) ................ OK.\\n\",cfgs);\n   cfgs_total+=cfgs;cfgs=0;\n\n   for(i=0;i<64;i++)\n   {\n      packet[0]=(i<<2)+3;\n      /*code 3, m is one, cbr*/\n      packet[1]=1;\n      for(j=0;j<1276;j++)\n      {\n        UNDEFINE_FOR_PARSE\n        ret=opus_packet_parse(packet,j+2,&toc,frames,size,&payload_offset);\n        cfgs++;\n        if(ret!=1)test_failed();\n        if(size[0]!=j)test_failed();\n        if((toc>>2)!=i)test_failed();\n      }\n      UNDEFINE_FOR_PARSE\n      ret=opus_packet_parse(packet,1276+2,&toc,frames,size,&payload_offset);\n      cfgs++;\n      if(ret!=OPUS_INVALID_PACKET)test_failed();\n   }\n   fprintf(stdout,\"    code 3 m=1 CBR (%2d cases) ................. OK.\\n\",cfgs);\n   cfgs_total+=cfgs;cfgs=0;\n\n   for(i=0;i<64;i++)\n   {\n      int frame_samp;\n      /*code 3, m>1 CBR*/\n      packet[0]=(i<<2)+3;\n      frame_samp=opus_packet_get_samples_per_frame(packet,48000);\n      for(j=2;j<49;j++)\n      {\n         packet[1]=j;\n         for(sz=2;sz<((j+2)*1275);sz++)\n         {\n            UNDEFINE_FOR_PARSE\n            ret=opus_packet_parse(packet,sz,&toc,frames,size,&payload_offset);\n            cfgs++;\n            /*Must be <=120ms, must be evenly divisible, can't have frames>1275 bytes*/\n            if(frame_samp*j<=5760 && (sz-2)%j==0 && (sz-2)/j<1276)\n            {\n               if(ret!=j)test_failed();\n               for(jj=1;jj<ret;jj++)if(frames[jj]!=frames[jj-1]+size[jj-1])test_failed();\n               if((toc>>2)!=i)test_failed();\n            } else if(ret!=OPUS_INVALID_PACKET)test_failed();\n         }\n      }\n      /*Super jumbo packets*/\n      packet[1]=5760/frame_samp;\n      UNDEFINE_FOR_PARSE\n      ret=opus_packet_parse(packet,1275*packet[1]+2,&toc,frames,size,&payload_offset);\n      cfgs++;\n      if(ret!=packet[1])test_failed();\n      for(jj=0;jj<ret;jj++)if(size[jj]!=1275)test_failed();\n   }\n   fprintf(stdout,\"    code 3 m=1-48 CBR (%2d cases) .......... OK.\\n\",cfgs);\n   cfgs_total+=cfgs;cfgs=0;\n\n   for(i=0;i<64;i++)\n   {\n      int frame_samp;\n      /*Code 3 VBR, m one*/\n      packet[0]=(i<<2)+3;\n      packet[1]=128+1;\n      frame_samp=opus_packet_get_samples_per_frame(packet,48000);\n      for(jj=0;jj<1276;jj++)\n      {\n         UNDEFINE_FOR_PARSE\n         ret=opus_packet_parse(packet,2+jj,&toc,frames,size,&payload_offset);\n         cfgs++;\n         if(ret!=1)test_failed();\n         if(size[0]!=jj)test_failed();\n         if((toc>>2)!=i)test_failed();\n      }\n      UNDEFINE_FOR_PARSE\n      ret=opus_packet_parse(packet,2+1276,&toc,frames,size,&payload_offset);\n      cfgs++;\n      if(ret!=OPUS_INVALID_PACKET)test_failed();\n      for(j=2;j<49;j++)\n      {\n         packet[1]=128+j;\n         /*Length code overflow*/\n         UNDEFINE_FOR_PARSE\n         ret=opus_packet_parse(packet,2+j-2,&toc,frames,size,&payload_offset);\n         cfgs++;\n         if(ret!=OPUS_INVALID_PACKET)test_failed();\n         packet[2]=252;\n         packet[3]=0;\n         for(jj=4;jj<2+j;jj++)packet[jj]=0;\n         UNDEFINE_FOR_PARSE\n         ret=opus_packet_parse(packet,2+j,&toc,frames,size,&payload_offset);\n         cfgs++;\n         if(ret!=OPUS_INVALID_PACKET)test_failed();\n         /*One byte too short*/\n         for(jj=2;jj<2+j;jj++)packet[jj]=0;\n         UNDEFINE_FOR_PARSE\n         ret=opus_packet_parse(packet,2+j-2,&toc,frames,size,&payload_offset);\n         cfgs++;\n         if(ret!=OPUS_INVALID_PACKET)test_failed();\n         /*One byte too short thanks to length coding*/\n         packet[2]=252;\n         packet[3]=0;\n         for(jj=4;jj<2+j;jj++)packet[jj]=0;\n         UNDEFINE_FOR_PARSE\n         ret=opus_packet_parse(packet,2+j+252-1,&toc,frames,size,&payload_offset);\n         cfgs++;\n         if(ret!=OPUS_INVALID_PACKET)test_failed();\n         /*Most expensive way of coding zeros*/\n         for(jj=2;jj<2+j;jj++)packet[jj]=0;\n         UNDEFINE_FOR_PARSE\n         ret=opus_packet_parse(packet,2+j-1,&toc,frames,size,&payload_offset);\n         cfgs++;\n         if(frame_samp*j<=5760){\n            if(ret!=j)test_failed();\n            for(jj=0;jj<j;jj++)if(size[jj]!=0)test_failed();\n            if((toc>>2)!=i)test_failed();\n         } else if(ret!=OPUS_INVALID_PACKET)test_failed();\n         /*Quasi-CBR use of mode 3*/\n         for(sz=0;sz<8;sz++)\n         {\n            const int tsz[8]={50,201,403,700,1472,5110,20400,61298};\n            int pos=0;\n            int as=(tsz[sz]+i-j-2)/j;\n            for(jj=0;jj<j-1;jj++)\n            {\n              if(as<252){packet[2+pos]=as;pos++;}\n              else{packet[2+pos]=252+(as&3);packet[3+pos]=(as-252)>>2;pos+=2;}\n            }\n            UNDEFINE_FOR_PARSE\n            ret=opus_packet_parse(packet,tsz[sz]+i,&toc,frames,size,&payload_offset);\n            cfgs++;\n            if(frame_samp*j<=5760 && as<1276 && (tsz[sz]+i-2-pos-as*(j-1))<1276){\n               if(ret!=j)test_failed();\n               for(jj=0;jj<j-1;jj++)if(size[jj]!=as)test_failed();\n               if(size[j-1]!=(tsz[sz]+i-2-pos-as*(j-1)))test_failed();\n               if((toc>>2)!=i)test_failed();\n            } else if(ret!=OPUS_INVALID_PACKET)test_failed();\n         }\n      }\n   }\n   fprintf(stdout,\"    code 3 m=1-48 VBR (%2d cases) ............. OK.\\n\",cfgs);\n   cfgs_total+=cfgs;cfgs=0;\n\n   for(i=0;i<64;i++)\n   {\n      packet[0]=(i<<2)+3;\n      /*Padding*/\n      packet[1]=128+1+64;\n      /*Overflow the length coding*/\n      for(jj=2;jj<127;jj++)packet[jj]=255;\n      UNDEFINE_FOR_PARSE\n      ret=opus_packet_parse(packet,127,&toc,frames,size,&payload_offset);\n      cfgs++;\n      if(ret!=OPUS_INVALID_PACKET)test_failed();\n\n      for(sz=0;sz<4;sz++)\n      {\n         const int tsz[4]={0,72,512,1275};\n         for(jj=sz;jj<65025;jj+=11)\n         {\n            int pos;\n            for(pos=0;pos<jj/254;pos++)packet[2+pos]=255;\n            packet[2+pos]=jj%254;\n            pos++;\n            if(sz==0&&i==63)\n            {\n               /*Code more padding than there is room in the packet*/\n               UNDEFINE_FOR_PARSE\n               ret=opus_packet_parse(packet,2+jj+pos-1,&toc,frames,size,&payload_offset);\n               cfgs++;\n               if(ret!=OPUS_INVALID_PACKET)test_failed();\n            }\n            UNDEFINE_FOR_PARSE\n            ret=opus_packet_parse(packet,2+jj+tsz[sz]+i+pos,&toc,frames,size,&payload_offset);\n            cfgs++;\n            if(tsz[sz]+i<1276)\n            {\n               if(ret!=1)test_failed();\n               if(size[0]!=tsz[sz]+i)test_failed();\n               if((toc>>2)!=i)test_failed();\n            } else if (ret!=OPUS_INVALID_PACKET)test_failed();\n         }\n      }\n   }\n   fprintf(stdout,\"    code 3 padding (%2d cases) ............... OK.\\n\",cfgs);\n   cfgs_total+=cfgs;\n   fprintf(stdout,\"    opus_packet_parse ............................ OK.\\n\");\n   fprintf(stdout,\"                      All packet parsing tests passed\\n\");\n   fprintf(stdout,\"                          (%d API invocations)\\n\",cfgs_total);\n   return cfgs_total;\n}\n\n/* This is a helper macro for the encoder tests.\n   The encoder api tests all have a pattern of set-must-fail, set-must-fail,\n   set-must-pass, get-and-compare, set-must-pass, get-and-compare. */\n#define CHECK_SETGET(setcall,getcall,badv,badv2,goodv,goodv2,sok,gok) \\\n   i=(badv);\\\n   if(opus_encoder_ctl(enc,setcall)==OPUS_OK)test_failed();\\\n   i=(badv2);\\\n   if(opus_encoder_ctl(enc,setcall)==OPUS_OK)test_failed();\\\n   j=i=(goodv);\\\n   if(opus_encoder_ctl(enc,setcall)!=OPUS_OK)test_failed();\\\n   i=-12345;\\\n   VG_UNDEF(&i,sizeof(i)); \\\n   err=opus_encoder_ctl(enc,getcall);\\\n   if(err!=OPUS_OK || i!=j)test_failed();\\\n   j=i=(goodv2);\\\n   if(opus_encoder_ctl(enc,setcall)!=OPUS_OK)test_failed();\\\n   fprintf(stdout,sok);\\\n   i=-12345;\\\n   VG_UNDEF(&i,sizeof(i)); \\\n   err=opus_encoder_ctl(enc,getcall);\\\n   if(err!=OPUS_OK || i!=j)test_failed();\\\n   fprintf(stdout,gok);\\\n   cfgs+=6;\n\nopus_int32 test_enc_api(void)\n{\n   opus_uint32 enc_final_range;\n   OpusEncoder *enc;\n   opus_int32 i,j;\n   unsigned char packet[1276];\n#ifndef DISABLE_FLOAT_API\n   float fbuf[960*2];\n#endif\n   short sbuf[960*2];\n   int c,err,cfgs;\n\n   cfgs=0;\n   /*First test invalid configurations which should fail*/\n   fprintf(stdout,\"\\n  Encoder basic API tests\\n\");\n   fprintf(stdout,\"  ---------------------------------------------------\\n\");\n   for(c=0;c<4;c++)\n   {\n      i=opus_encoder_get_size(c);\n      if(((c==1||c==2)&&(i<=2048||i>1<<17))||((c!=1&&c!=2)&&i!=0))test_failed();\n      fprintf(stdout,\"    opus_encoder_get_size(%d)=%d ...............%s OK.\\n\",c,i,i>0?\"\":\"....\");\n      cfgs++;\n   }\n\n   /*Test with unsupported sample rates, channel counts*/\n   for(c=0;c<4;c++)\n   {\n      for(i=-7;i<=96000;i++)\n      {\n         int fs;\n         if((i==8000||i==12000||i==16000||i==24000||i==48000)&&(c==1||c==2))continue;\n         switch(i)\n         {\n           case(-5):fs=-8000;break;\n           case(-6):fs=INT32_MAX;break;\n           case(-7):fs=INT32_MIN;break;\n           default:fs=i;\n         }\n         err = OPUS_OK;\n         VG_UNDEF(&err,sizeof(err));\n         enc = opus_encoder_create(fs, c, OPUS_APPLICATION_VOIP, &err);\n         if(err!=OPUS_BAD_ARG || enc!=NULL)test_failed();\n         cfgs++;\n         enc = opus_encoder_create(fs, c, OPUS_APPLICATION_VOIP, 0);\n         if(enc!=NULL)test_failed();\n         cfgs++;\n         opus_encoder_destroy(enc);\n         enc=malloc(opus_encoder_get_size(2));\n         if(enc==NULL)test_failed();\n         err = opus_encoder_init(enc, fs, c, OPUS_APPLICATION_VOIP);\n         if(err!=OPUS_BAD_ARG)test_failed();\n         cfgs++;\n         free(enc);\n      }\n   }\n\n   enc = opus_encoder_create(48000, 2, OPUS_AUTO, NULL);\n   if(enc!=NULL)test_failed();\n   cfgs++;\n\n   VG_UNDEF(&err,sizeof(err));\n   enc = opus_encoder_create(48000, 2, OPUS_AUTO, &err);\n   if(err!=OPUS_BAD_ARG || enc!=NULL)test_failed();\n   cfgs++;\n\n   VG_UNDEF(&err,sizeof(err));\n   enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_VOIP, NULL);\n   if(enc==NULL)test_failed();\n   opus_encoder_destroy(enc);\n   cfgs++;\n\n   VG_UNDEF(&err,sizeof(err));\n   enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_RESTRICTED_LOWDELAY, &err);\n   if(err!=OPUS_OK || enc==NULL)test_failed();\n   cfgs++;\n   err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD(&i));\n   if(err!=OPUS_OK || i<0 || i>32766)test_failed();\n   cfgs++;\n   opus_encoder_destroy(enc);\n\n   VG_UNDEF(&err,sizeof(err));\n   enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_AUDIO, &err);\n   if(err!=OPUS_OK || enc==NULL)test_failed();\n   cfgs++;\n   err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD(&i));\n   if(err!=OPUS_OK || i<0 || i>32766)test_failed();\n   opus_encoder_destroy(enc);\n   cfgs++;\n\n   VG_UNDEF(&err,sizeof(err));\n   enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_VOIP, &err);\n   if(err!=OPUS_OK || enc==NULL)test_failed();\n   cfgs++;\n\n   fprintf(stdout,\"    opus_encoder_create() ........................ OK.\\n\");\n   fprintf(stdout,\"    opus_encoder_init() .......................... OK.\\n\");\n\n   i=-12345;\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD(&i));\n   if(err!=OPUS_OK || i<0 || i>32766)test_failed();\n   cfgs++;\n   err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    OPUS_GET_LOOKAHEAD ........................... OK.\\n\");\n\n   err=opus_encoder_ctl(enc,OPUS_GET_SAMPLE_RATE(&i));\n   if(err!=OPUS_OK || i!=48000)test_failed();\n   cfgs++;\n   err=opus_encoder_ctl(enc,OPUS_GET_SAMPLE_RATE((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    OPUS_GET_SAMPLE_RATE ......................... OK.\\n\");\n\n   if(opus_encoder_ctl(enc,OPUS_UNIMPLEMENTED)!=OPUS_UNIMPLEMENTED)test_failed();\n   fprintf(stdout,\"    OPUS_UNIMPLEMENTED ........................... OK.\\n\");\n   cfgs++;\n\n   err=opus_encoder_ctl(enc,OPUS_GET_APPLICATION((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_APPLICATION(i),OPUS_GET_APPLICATION(&i),-1,OPUS_AUTO,\n     OPUS_APPLICATION_AUDIO,OPUS_APPLICATION_RESTRICTED_LOWDELAY,\n     \"    OPUS_SET_APPLICATION ......................... OK.\\n\",\n     \"    OPUS_GET_APPLICATION ......................... OK.\\n\")\n\n   err=opus_encoder_ctl(enc,OPUS_GET_BITRATE((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   if(opus_encoder_ctl(enc,OPUS_SET_BITRATE(1073741832))!=OPUS_OK)test_failed();\n   cfgs++;\n   VG_UNDEF(&i,sizeof(i));\n   if(opus_encoder_ctl(enc,OPUS_GET_BITRATE(&i))!=OPUS_OK)test_failed();\n   if(i>700000||i<256000)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_BITRATE(i),OPUS_GET_BITRATE(&i),-12345,0,\n     500,256000,\n     \"    OPUS_SET_BITRATE ............................. OK.\\n\",\n     \"    OPUS_GET_BITRATE ............................. OK.\\n\")\n\n   err=opus_encoder_ctl(enc,OPUS_GET_FORCE_CHANNELS((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_FORCE_CHANNELS(i),OPUS_GET_FORCE_CHANNELS(&i),-1,3,\n     1,OPUS_AUTO,\n     \"    OPUS_SET_FORCE_CHANNELS ...................... OK.\\n\",\n     \"    OPUS_GET_FORCE_CHANNELS ...................... OK.\\n\")\n\n   i=-2;\n   if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))==OPUS_OK)test_failed();\n   cfgs++;\n   i=OPUS_BANDWIDTH_FULLBAND+1;\n   if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))==OPUS_OK)test_failed();\n   cfgs++;\n   i=OPUS_BANDWIDTH_NARROWBAND;\n   if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))!=OPUS_OK)test_failed();\n   cfgs++;\n   i=OPUS_BANDWIDTH_FULLBAND;\n   if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))!=OPUS_OK)test_failed();\n   cfgs++;\n   i=OPUS_BANDWIDTH_WIDEBAND;\n   if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))!=OPUS_OK)test_failed();\n   cfgs++;\n   i=OPUS_BANDWIDTH_MEDIUMBAND;\n   if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))!=OPUS_OK)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    OPUS_SET_BANDWIDTH ........................... OK.\\n\");\n   /*We don't test if the bandwidth has actually changed.\n     because the change may be delayed until the encoder is advanced.*/\n   i=-12345;\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_encoder_ctl(enc,OPUS_GET_BANDWIDTH(&i));\n   if(err!=OPUS_OK || (i!=OPUS_BANDWIDTH_NARROWBAND&&\n      i!=OPUS_BANDWIDTH_MEDIUMBAND&&i!=OPUS_BANDWIDTH_WIDEBAND&&\n      i!=OPUS_BANDWIDTH_FULLBAND&&i!=OPUS_AUTO))test_failed();\n   cfgs++;\n   if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(OPUS_AUTO))!=OPUS_OK)test_failed();\n   cfgs++;\n   err=opus_encoder_ctl(enc,OPUS_GET_BANDWIDTH((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    OPUS_GET_BANDWIDTH ........................... OK.\\n\");\n\n   i=-2;\n   if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))==OPUS_OK)test_failed();\n   cfgs++;\n   i=OPUS_BANDWIDTH_FULLBAND+1;\n   if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))==OPUS_OK)test_failed();\n   cfgs++;\n   i=OPUS_BANDWIDTH_NARROWBAND;\n   if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))!=OPUS_OK)test_failed();\n   cfgs++;\n   i=OPUS_BANDWIDTH_FULLBAND;\n   if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))!=OPUS_OK)test_failed();\n   cfgs++;\n   i=OPUS_BANDWIDTH_WIDEBAND;\n   if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))!=OPUS_OK)test_failed();\n   cfgs++;\n   i=OPUS_BANDWIDTH_MEDIUMBAND;\n   if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))!=OPUS_OK)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    OPUS_SET_MAX_BANDWIDTH ....................... OK.\\n\");\n   /*We don't test if the bandwidth has actually changed.\n     because the change may be delayed until the encoder is advanced.*/\n   i=-12345;\n   VG_UNDEF(&i,sizeof(i));\n   err=opus_encoder_ctl(enc,OPUS_GET_MAX_BANDWIDTH(&i));\n   if(err!=OPUS_OK || (i!=OPUS_BANDWIDTH_NARROWBAND&&\n      i!=OPUS_BANDWIDTH_MEDIUMBAND&&i!=OPUS_BANDWIDTH_WIDEBAND&&\n      i!=OPUS_BANDWIDTH_FULLBAND))test_failed();\n   cfgs++;\n   err=opus_encoder_ctl(enc,OPUS_GET_MAX_BANDWIDTH((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    OPUS_GET_MAX_BANDWIDTH ....................... OK.\\n\");\n\n   err=opus_encoder_ctl(enc,OPUS_GET_DTX((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_DTX(i),OPUS_GET_DTX(&i),-1,2,\n     1,0,\n     \"    OPUS_SET_DTX ................................. OK.\\n\",\n     \"    OPUS_GET_DTX ................................. OK.\\n\")\n\n   err=opus_encoder_ctl(enc,OPUS_GET_COMPLEXITY((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_COMPLEXITY(i),OPUS_GET_COMPLEXITY(&i),-1,11,\n     0,10,\n     \"    OPUS_SET_COMPLEXITY .......................... OK.\\n\",\n     \"    OPUS_GET_COMPLEXITY .......................... OK.\\n\")\n\n   err=opus_encoder_ctl(enc,OPUS_GET_INBAND_FEC((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_INBAND_FEC(i),OPUS_GET_INBAND_FEC(&i),-1,2,\n     1,0,\n     \"    OPUS_SET_INBAND_FEC .......................... OK.\\n\",\n     \"    OPUS_GET_INBAND_FEC .......................... OK.\\n\")\n\n   err=opus_encoder_ctl(enc,OPUS_GET_PACKET_LOSS_PERC((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_PACKET_LOSS_PERC(i),OPUS_GET_PACKET_LOSS_PERC(&i),-1,101,\n     100,0,\n     \"    OPUS_SET_PACKET_LOSS_PERC .................... OK.\\n\",\n     \"    OPUS_GET_PACKET_LOSS_PERC .................... OK.\\n\")\n\n   err=opus_encoder_ctl(enc,OPUS_GET_VBR((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_VBR(i),OPUS_GET_VBR(&i),-1,2,\n     1,0,\n     \"    OPUS_SET_VBR ................................. OK.\\n\",\n     \"    OPUS_GET_VBR ................................. OK.\\n\")\n\n/*   err=opus_encoder_ctl(enc,OPUS_GET_VOICE_RATIO((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_VOICE_RATIO(i),OPUS_GET_VOICE_RATIO(&i),-2,101,\n     0,50,\n     \"    OPUS_SET_VOICE_RATIO ......................... OK.\\n\",\n     \"    OPUS_GET_VOICE_RATIO ......................... OK.\\n\")*/\n\n   err=opus_encoder_ctl(enc,OPUS_GET_VBR_CONSTRAINT((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_VBR_CONSTRAINT(i),OPUS_GET_VBR_CONSTRAINT(&i),-1,2,\n     1,0,\n     \"    OPUS_SET_VBR_CONSTRAINT ...................... OK.\\n\",\n     \"    OPUS_GET_VBR_CONSTRAINT ...................... OK.\\n\")\n\n   err=opus_encoder_ctl(enc,OPUS_GET_SIGNAL((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_SIGNAL(i),OPUS_GET_SIGNAL(&i),-12345,0x7FFFFFFF,\n     OPUS_SIGNAL_MUSIC,OPUS_AUTO,\n     \"    OPUS_SET_SIGNAL .............................. OK.\\n\",\n     \"    OPUS_GET_SIGNAL .............................. OK.\\n\")\n\n   err=opus_encoder_ctl(enc,OPUS_GET_LSB_DEPTH((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_LSB_DEPTH(i),OPUS_GET_LSB_DEPTH(&i),7,25,16,24,\n     \"    OPUS_SET_LSB_DEPTH ........................... OK.\\n\",\n     \"    OPUS_GET_LSB_DEPTH ........................... OK.\\n\")\n\n   err=opus_encoder_ctl(enc,OPUS_GET_PREDICTION_DISABLED(&i));\n   if(i!=0)test_failed();\n   cfgs++;\n   err=opus_encoder_ctl(enc,OPUS_GET_PREDICTION_DISABLED((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_PREDICTION_DISABLED(i),OPUS_GET_PREDICTION_DISABLED(&i),-1,2,1,0,\n     \"    OPUS_SET_PREDICTION_DISABLED ................. OK.\\n\",\n     \"    OPUS_GET_PREDICTION_DISABLED ................. OK.\\n\")\n\n   err=opus_encoder_ctl(enc,OPUS_GET_EXPERT_FRAME_DURATION((opus_int32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_2_5_MS));\n   if(err!=OPUS_OK)test_failed();\n   cfgs++;\n   err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_5_MS));\n   if(err!=OPUS_OK)test_failed();\n   cfgs++;\n   err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_10_MS));\n   if(err!=OPUS_OK)test_failed();\n   cfgs++;\n   err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_20_MS));\n   if(err!=OPUS_OK)test_failed();\n   cfgs++;\n   err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_40_MS));\n   if(err!=OPUS_OK)test_failed();\n   cfgs++;\n   err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_60_MS));\n   if(err!=OPUS_OK)test_failed();\n   cfgs++;\n   CHECK_SETGET(OPUS_SET_EXPERT_FRAME_DURATION(i),OPUS_GET_EXPERT_FRAME_DURATION(&i),0,-1,\n         OPUS_FRAMESIZE_60_MS,OPUS_FRAMESIZE_ARG,\n     \"    OPUS_SET_EXPERT_FRAME_DURATION ............... OK.\\n\",\n     \"    OPUS_GET_EXPERT_FRAME_DURATION ............... OK.\\n\")\n\n   /*OPUS_SET_FORCE_MODE is not tested here because it's not a public API, however the encoder tests use it*/\n\n   err=opus_encoder_ctl(enc,OPUS_GET_FINAL_RANGE((opus_uint32 *)NULL));\n   if(err!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   if(opus_encoder_ctl(enc,OPUS_GET_FINAL_RANGE(&enc_final_range))!=OPUS_OK)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    OPUS_GET_FINAL_RANGE ......................... OK.\\n\");\n\n   /*Reset the encoder*/\n   if(opus_encoder_ctl(enc, OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    OPUS_RESET_STATE ............................. OK.\\n\");\n\n   memset(sbuf,0,sizeof(short)*2*960);\n   VG_UNDEF(packet,sizeof(packet));\n   i=opus_encode(enc, sbuf, 960, packet, sizeof(packet));\n   if(i<1 || (i>(opus_int32)sizeof(packet)))test_failed();\n   VG_CHECK(packet,i);\n   cfgs++;\n   fprintf(stdout,\"    opus_encode() ................................ OK.\\n\");\n#ifndef DISABLE_FLOAT_API\n   memset(fbuf,0,sizeof(float)*2*960);\n   VG_UNDEF(packet,sizeof(packet));\n   i=opus_encode_float(enc, fbuf, 960, packet, sizeof(packet));\n   if(i<1 || (i>(opus_int32)sizeof(packet)))test_failed();\n   VG_CHECK(packet,i);\n   cfgs++;\n   fprintf(stdout,\"    opus_encode_float() .......................... OK.\\n\");\n#endif\n\n#if 0\n   /*These tests are disabled because the library crashes with null states*/\n   if(opus_encoder_ctl(0,OPUS_RESET_STATE)               !=OPUS_INVALID_STATE)test_failed();\n   if(opus_encoder_init(0,48000,1,OPUS_APPLICATION_VOIP) !=OPUS_INVALID_STATE)test_failed();\n   if(opus_encode(0,sbuf,960,packet,sizeof(packet))      !=OPUS_INVALID_STATE)test_failed();\n   if(opus_encode_float(0,fbuf,960,packet,sizeof(packet))!=OPUS_INVALID_STATE)test_failed();\n#endif\n   opus_encoder_destroy(enc);\n   cfgs++;\n   fprintf(stdout,\"                   All encoder interface tests passed\\n\");\n   fprintf(stdout,\"                             (%d API invocations)\\n\",cfgs);\n   return cfgs;\n}\n\n#define max_out (1276*48+48*2+2)\nint test_repacketizer_api(void)\n{\n   int ret,cfgs,i,j,k;\n   OpusRepacketizer *rp;\n   unsigned char *packet;\n   unsigned char *po;\n   cfgs=0;\n   fprintf(stdout,\"\\n  Repacketizer tests\\n\");\n   fprintf(stdout,\"  ---------------------------------------------------\\n\");\n\n   packet=malloc(max_out);\n   if(packet==NULL)test_failed();\n   memset(packet,0,max_out);\n   po=malloc(max_out+256);\n   if(po==NULL)test_failed();\n\n   i=opus_repacketizer_get_size();\n   if(i<=0)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    opus_repacketizer_get_size()=%d ............. OK.\\n\",i);\n\n   rp=malloc(i);\n   rp=opus_repacketizer_init(rp);\n   if(rp==NULL)test_failed();\n   cfgs++;\n   free(rp);\n   fprintf(stdout,\"    opus_repacketizer_init ....................... OK.\\n\");\n\n   rp=opus_repacketizer_create();\n   if(rp==NULL)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    opus_repacketizer_create ..................... OK.\\n\");\n\n   if(opus_repacketizer_get_nb_frames(rp)!=0)test_failed();\n   cfgs++;\n   fprintf(stdout,\"    opus_repacketizer_get_nb_frames .............. OK.\\n\");\n\n   /*Length overflows*/\n   VG_UNDEF(packet,4);\n   if(opus_repacketizer_cat(rp,packet,0)!=OPUS_INVALID_PACKET)test_failed(); /* Zero len */\n   cfgs++;\n   packet[0]=1;\n   if(opus_repacketizer_cat(rp,packet,2)!=OPUS_INVALID_PACKET)test_failed(); /* Odd payload code 1 */\n   cfgs++;\n   packet[0]=2;\n   if(opus_repacketizer_cat(rp,packet,1)!=OPUS_INVALID_PACKET)test_failed(); /* Code 2 overflow one */\n   cfgs++;\n   packet[0]=3;\n   if(opus_repacketizer_cat(rp,packet,1)!=OPUS_INVALID_PACKET)test_failed(); /* Code 3 no count */\n   cfgs++;\n   packet[0]=2;\n   packet[1]=255;\n   if(opus_repacketizer_cat(rp,packet,2)!=OPUS_INVALID_PACKET)test_failed(); /* Code 2 overflow two */\n   cfgs++;\n   packet[0]=2;\n   packet[1]=250;\n   if(opus_repacketizer_cat(rp,packet,251)!=OPUS_INVALID_PACKET)test_failed(); /* Code 2 overflow three */\n   cfgs++;\n   packet[0]=3;\n   packet[1]=0;\n   if(opus_repacketizer_cat(rp,packet,2)!=OPUS_INVALID_PACKET)test_failed(); /* Code 3 m=0 */\n   cfgs++;\n   packet[1]=49;\n   if(opus_repacketizer_cat(rp,packet,100)!=OPUS_INVALID_PACKET)test_failed(); /* Code 3 m=49 */\n   cfgs++;\n   packet[0]=0;\n   if(opus_repacketizer_cat(rp,packet,3)!=OPUS_OK)test_failed();\n   cfgs++;\n   packet[0]=1<<2;\n   if(opus_repacketizer_cat(rp,packet,3)!=OPUS_INVALID_PACKET)test_failed(); /* Change in TOC */\n   cfgs++;\n\n   /* Code 0,1,3 CBR -> Code 0,1,3 CBR */\n   opus_repacketizer_init(rp);\n   for(j=0;j<32;j++)\n   {\n      /* TOC types, test half with stereo */\n      int maxi;\n      packet[0]=((j<<1)+(j&1))<<2;\n      maxi=960/opus_packet_get_samples_per_frame(packet,8000);\n      for(i=1;i<=maxi;i++)\n      {\n         /* Number of CBR frames in the input packets */\n         int maxp;\n         packet[0]=((j<<1)+(j&1))<<2;\n         if(i>1)packet[0]+=i==2?1:3;\n         packet[1]=i>2?i:0;\n         maxp=960/(i*opus_packet_get_samples_per_frame(packet,8000));\n         for(k=0;k<=(1275+75);k+=3)\n         {\n            /*Payload size*/\n            opus_int32 cnt,rcnt;\n            if(k%i!=0)continue; /* Only testing CBR here, payload must be a multiple of the count */\n            for(cnt=0;cnt<maxp+2;cnt++)\n            {\n               if(cnt>0)\n               {\n                  ret=opus_repacketizer_cat(rp,packet,k+(i>2?2:1));\n                  if((cnt<=maxp&&k<=(1275*i))?ret!=OPUS_OK:ret!=OPUS_INVALID_PACKET)test_failed();\n                  cfgs++;\n               }\n               rcnt=k<=(1275*i)?(cnt<maxp?cnt:maxp):0;\n               if(opus_repacketizer_get_nb_frames(rp)!=rcnt*i)test_failed();\n               cfgs++;\n               ret=opus_repacketizer_out_range(rp,0,rcnt*i,po,max_out);\n               if(rcnt>0)\n               {\n                  int len;\n                  len=k*rcnt+((rcnt*i)>2?2:1);\n                  if(ret!=len)test_failed();\n                  if((rcnt*i)<2&&(po[0]&3)!=0)test_failed();                      /* Code 0 */\n                  if((rcnt*i)==2&&(po[0]&3)!=1)test_failed();                     /* Code 1 */\n                  if((rcnt*i)>2&&(((po[0]&3)!=3)||(po[1]!=rcnt*i)))test_failed(); /* Code 3 CBR */\n                  cfgs++;\n                  if(opus_repacketizer_out(rp,po,len)!=len)test_failed();\n                  cfgs++;\n                  if(opus_packet_unpad(po,len)!=len)test_failed();\n                  cfgs++;\n                  if(opus_packet_pad(po,len,len+1)!=OPUS_OK)test_failed();\n                  cfgs++;\n                  if(opus_packet_pad(po,len+1,len+256)!=OPUS_OK)test_failed();\n                  cfgs++;\n                  if(opus_packet_unpad(po,len+256)!=len)test_failed();\n                  cfgs++;\n                  if(opus_multistream_packet_unpad(po,len,1)!=len)test_failed();\n                  cfgs++;\n                  if(opus_multistream_packet_pad(po,len,len+1,1)!=OPUS_OK)test_failed();\n                  cfgs++;\n                  if(opus_multistream_packet_pad(po,len+1,len+256,1)!=OPUS_OK)test_failed();\n                  cfgs++;\n                  if(opus_multistream_packet_unpad(po,len+256,1)!=len)test_failed();\n                  cfgs++;\n                  if(opus_repacketizer_out(rp,po,len-1)!=OPUS_BUFFER_TOO_SMALL)test_failed();\n                  cfgs++;\n                  if(len>1)\n                  {\n                     if(opus_repacketizer_out(rp,po,1)!=OPUS_BUFFER_TOO_SMALL)test_failed();\n                     cfgs++;\n                  }\n                  if(opus_repacketizer_out(rp,po,0)!=OPUS_BUFFER_TOO_SMALL)test_failed();\n                  cfgs++;\n               } else if (ret!=OPUS_BAD_ARG)test_failed();                        /* M must not be 0 */\n            }\n            opus_repacketizer_init(rp);\n         }\n      }\n   }\n\n   /*Change in input count code, CBR out*/\n   opus_repacketizer_init(rp);\n   packet[0]=0;\n   if(opus_repacketizer_cat(rp,packet,5)!=OPUS_OK)test_failed();\n   cfgs++;\n   packet[0]+=1;\n   if(opus_repacketizer_cat(rp,packet,9)!=OPUS_OK)test_failed();\n   cfgs++;\n   i=opus_repacketizer_out(rp,po,max_out);\n   if((i!=(4+8+2))||((po[0]&3)!=3)||((po[1]&63)!=3)||((po[1]>>7)!=0))test_failed();\n   cfgs++;\n   i=opus_repacketizer_out_range(rp,0,1,po,max_out);\n   if(i!=5||(po[0]&3)!=0)test_failed();\n   cfgs++;\n   i=opus_repacketizer_out_range(rp,1,2,po,max_out);\n   if(i!=5||(po[0]&3)!=0)test_failed();\n   cfgs++;\n\n   /*Change in input count code, VBR out*/\n   opus_repacketizer_init(rp);\n   packet[0]=1;\n   if(opus_repacketizer_cat(rp,packet,9)!=OPUS_OK)test_failed();\n   cfgs++;\n   packet[0]=0;\n   if(opus_repacketizer_cat(rp,packet,3)!=OPUS_OK)test_failed();\n   cfgs++;\n   i=opus_repacketizer_out(rp,po,max_out);\n   if((i!=(2+8+2+2))||((po[0]&3)!=3)||((po[1]&63)!=3)||((po[1]>>7)!=1))test_failed();\n   cfgs++;\n\n   /*VBR in, VBR out*/\n   opus_repacketizer_init(rp);\n   packet[0]=2;\n   packet[1]=4;\n   if(opus_repacketizer_cat(rp,packet,8)!=OPUS_OK)test_failed();\n   cfgs++;\n   if(opus_repacketizer_cat(rp,packet,8)!=OPUS_OK)test_failed();\n   cfgs++;\n   i=opus_repacketizer_out(rp,po,max_out);\n   if((i!=(2+1+1+1+4+2+4+2))||((po[0]&3)!=3)||((po[1]&63)!=4)||((po[1]>>7)!=1))test_failed();\n   cfgs++;\n\n   /*VBR in, CBR out*/\n   opus_repacketizer_init(rp);\n   packet[0]=2;\n   packet[1]=4;\n   if(opus_repacketizer_cat(rp,packet,10)!=OPUS_OK)test_failed();\n   cfgs++;\n   if(opus_repacketizer_cat(rp,packet,10)!=OPUS_OK)test_failed();\n   cfgs++;\n   i=opus_repacketizer_out(rp,po,max_out);\n   if((i!=(2+4+4+4+4))||((po[0]&3)!=3)||((po[1]&63)!=4)||((po[1]>>7)!=0))test_failed();\n   cfgs++;\n\n   /*Count 0 in, VBR out*/\n   for(j=0;j<32;j++)\n   {\n      /* TOC types, test half with stereo */\n      int maxi,sum,rcnt;\n      packet[0]=((j<<1)+(j&1))<<2;\n      maxi=960/opus_packet_get_samples_per_frame(packet,8000);\n      sum=0;\n      rcnt=0;\n      opus_repacketizer_init(rp);\n      for(i=1;i<=maxi+2;i++)\n      {\n         int len;\n         ret=opus_repacketizer_cat(rp,packet,i);\n         if(rcnt<maxi)\n         {\n            if(ret!=OPUS_OK)test_failed();\n            rcnt++;\n            sum+=i-1;\n         } else if (ret!=OPUS_INVALID_PACKET)test_failed();\n         cfgs++;\n         len=sum+(rcnt<2?1:rcnt<3?2:2+rcnt-1);\n         if(opus_repacketizer_out(rp,po,max_out)!=len)test_failed();\n         if(rcnt>2&&(po[1]&63)!=rcnt)test_failed();\n         if(rcnt==2&&(po[0]&3)!=2)test_failed();\n         if(rcnt==1&&(po[0]&3)!=0)test_failed();\n         cfgs++;\n         if(opus_repacketizer_out(rp,po,len)!=len)test_failed();\n         cfgs++;\n         if(opus_packet_unpad(po,len)!=len)test_failed();\n         cfgs++;\n         if(opus_packet_pad(po,len,len+1)!=OPUS_OK)test_failed();\n         cfgs++;\n         if(opus_packet_pad(po,len+1,len+256)!=OPUS_OK)test_failed();\n         cfgs++;\n         if(opus_packet_unpad(po,len+256)!=len)test_failed();\n         cfgs++;\n         if(opus_multistream_packet_unpad(po,len,1)!=len)test_failed();\n         cfgs++;\n         if(opus_multistream_packet_pad(po,len,len+1,1)!=OPUS_OK)test_failed();\n         cfgs++;\n         if(opus_multistream_packet_pad(po,len+1,len+256,1)!=OPUS_OK)test_failed();\n         cfgs++;\n         if(opus_multistream_packet_unpad(po,len+256,1)!=len)test_failed();\n         cfgs++;\n         if(opus_repacketizer_out(rp,po,len-1)!=OPUS_BUFFER_TOO_SMALL)test_failed();\n         cfgs++;\n         if(len>1)\n         {\n            if(opus_repacketizer_out(rp,po,1)!=OPUS_BUFFER_TOO_SMALL)test_failed();\n            cfgs++;\n         }\n         if(opus_repacketizer_out(rp,po,0)!=OPUS_BUFFER_TOO_SMALL)test_failed();\n         cfgs++;\n      }\n   }\n\n   po[0]='O';\n   po[1]='p';\n   if(opus_packet_pad(po,4,4)!=OPUS_OK)test_failed();\n   cfgs++;\n   if(opus_multistream_packet_pad(po,4,4,1)!=OPUS_OK)test_failed();\n   cfgs++;\n   if(opus_packet_pad(po,4,5)!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   if(opus_multistream_packet_pad(po,4,5,1)!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   if(opus_packet_pad(po,0,5)!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   if(opus_multistream_packet_pad(po,0,5,1)!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   if(opus_packet_unpad(po,0)!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   if(opus_multistream_packet_unpad(po,0,1)!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   if(opus_packet_unpad(po,4)!=OPUS_INVALID_PACKET)test_failed();\n   cfgs++;\n   if(opus_multistream_packet_unpad(po,4,1)!=OPUS_INVALID_PACKET)test_failed();\n   cfgs++;\n   po[0]=0;\n   po[1]=0;\n   po[2]=0;\n   if(opus_packet_pad(po,5,4)!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n   if(opus_multistream_packet_pad(po,5,4,1)!=OPUS_BAD_ARG)test_failed();\n   cfgs++;\n\n   fprintf(stdout,\"    opus_repacketizer_cat ........................ OK.\\n\");\n   fprintf(stdout,\"    opus_repacketizer_out ........................ OK.\\n\");\n   fprintf(stdout,\"    opus_repacketizer_out_range .................. OK.\\n\");\n   fprintf(stdout,\"    opus_packet_pad .............................. OK.\\n\");\n   fprintf(stdout,\"    opus_packet_unpad ............................ OK.\\n\");\n   fprintf(stdout,\"    opus_multistream_packet_pad .................. OK.\\n\");\n   fprintf(stdout,\"    opus_multistream_packet_unpad ................ OK.\\n\");\n\n   opus_repacketizer_destroy(rp);\n   cfgs++;\n   free(packet);\n   free(po);\n   fprintf(stdout,\"                        All repacketizer tests passed\\n\");\n   fprintf(stdout,\"                            (%7d API invocations)\\n\",cfgs);\n\n   return cfgs;\n}\n\n#ifdef MALLOC_FAIL\n/* GLIBC 2.14 declares __malloc_hook as deprecated, generating a warning\n * under GCC. However, this is the cleanest way to test malloc failure\n * handling in our codebase, and the lack of thread safety isn't an\n * issue here. We therefore disable the warning for this function.\n */\n#if OPUS_GNUC_PREREQ(4,6)\n/* Save the current warning settings */\n#pragma GCC diagnostic push\n#endif\n#pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n\ntypedef void *(*mhook)(size_t __size, __const void *);\n#endif\n\nint test_malloc_fail(void)\n{\n#ifdef MALLOC_FAIL\n   OpusDecoder *dec;\n   OpusEncoder *enc;\n   OpusRepacketizer *rp;\n   unsigned char mapping[256] = {0,1};\n   OpusMSDecoder *msdec;\n   OpusMSEncoder *msenc;\n   int rate,c,app,cfgs,err,useerr;\n   int *ep;\n   mhook orig_malloc;\n   cfgs=0;\n#endif\n   fprintf(stdout,\"\\n  malloc() failure tests\\n\");\n   fprintf(stdout,\"  ---------------------------------------------------\\n\");\n#ifdef MALLOC_FAIL\n   orig_malloc=__malloc_hook;\n   __malloc_hook=malloc_hook;\n   ep=(int *)opus_alloc(sizeof(int));\n   if(ep!=NULL)\n   {\n      if(ep)free(ep);\n      __malloc_hook=orig_malloc;\n#endif\n      fprintf(stdout,\"    opus_decoder_create() ................... SKIPPED.\\n\");\n      fprintf(stdout,\"    opus_encoder_create() ................... SKIPPED.\\n\");\n      fprintf(stdout,\"    opus_repacketizer_create() .............. SKIPPED.\\n\");\n      fprintf(stdout,\"    opus_multistream_decoder_create() ....... SKIPPED.\\n\");\n      fprintf(stdout,\"    opus_multistream_encoder_create() ....... SKIPPED.\\n\");\n      fprintf(stdout,\"(Test only supported with GLIBC and without valgrind)\\n\");\n      return 0;\n#ifdef MALLOC_FAIL\n   }\n   for(useerr=0;useerr<2;useerr++)\n   {\n      ep=useerr?&err:0;\n      for(rate=0;rate<5;rate++)\n      {\n        for(c=1;c<3;c++)\n        {\n           err=1;\n           if(useerr)\n           {\n              VG_UNDEF(&err,sizeof(err));\n           }\n           dec=opus_decoder_create(opus_rates[rate], c, ep);\n           if(dec!=NULL||(useerr&&err!=OPUS_ALLOC_FAIL))\n           {\n              __malloc_hook=orig_malloc;\n              test_failed();\n           }\n           cfgs++;\n           msdec=opus_multistream_decoder_create(opus_rates[rate], c, 1, c-1, mapping, ep);\n           if(msdec!=NULL||(useerr&&err!=OPUS_ALLOC_FAIL))\n           {\n              __malloc_hook=orig_malloc;\n              test_failed();\n           }\n           cfgs++;\n           for(app=0;app<3;app++)\n           {\n              if(useerr)\n              {\n                 VG_UNDEF(&err,sizeof(err));\n              }\n              enc=opus_encoder_create(opus_rates[rate], c, opus_apps[app],ep);\n              if(enc!=NULL||(useerr&&err!=OPUS_ALLOC_FAIL))\n              {\n                 __malloc_hook=orig_malloc;\n                 test_failed();\n              }\n              cfgs++;\n              msenc=opus_multistream_encoder_create(opus_rates[rate], c, 1, c-1, mapping, opus_apps[app],ep);\n              if(msenc!=NULL||(useerr&&err!=OPUS_ALLOC_FAIL))\n              {\n                 __malloc_hook=orig_malloc;\n                 test_failed();\n              }\n              cfgs++;\n           }\n        }\n     }\n   }\n   rp=opus_repacketizer_create();\n   if(rp!=NULL)\n   {\n      __malloc_hook=orig_malloc;\n      test_failed();\n   }\n   cfgs++;\n   __malloc_hook=orig_malloc;\n   fprintf(stdout,\"    opus_decoder_create() ........................ OK.\\n\");\n   fprintf(stdout,\"    opus_encoder_create() ........................ OK.\\n\");\n   fprintf(stdout,\"    opus_repacketizer_create() ................... OK.\\n\");\n   fprintf(stdout,\"    opus_multistream_decoder_create() ............ OK.\\n\");\n   fprintf(stdout,\"    opus_multistream_encoder_create() ............ OK.\\n\");\n   fprintf(stdout,\"                      All malloc failure tests passed\\n\");\n   fprintf(stdout,\"                                 (%2d API invocations)\\n\",cfgs);\n   return cfgs;\n#endif\n}\n\n#ifdef MALLOC_FAIL\n#if __GNUC_PREREQ(4,6)\n#pragma GCC diagnostic pop /* restore -Wdeprecated-declarations */\n#endif\n#endif\n\nint main(int _argc, char **_argv)\n{\n   opus_int32 total;\n   const char * oversion;\n   if(_argc>1)\n   {\n      fprintf(stderr,\"Usage: %s\\n\",_argv[0]);\n      return 1;\n   }\n   iseed=0;\n\n   oversion=opus_get_version_string();\n   if(!oversion)test_failed();\n   fprintf(stderr,\"Testing the %s API deterministically\\n\", oversion);\n   if(opus_strerror(-32768)==NULL)test_failed();\n   if(opus_strerror(32767)==NULL)test_failed();\n   if(strlen(opus_strerror(0))<1)test_failed();\n   total=4;\n\n   total+=test_dec_api();\n   total+=test_msdec_api();\n   total+=test_parse();\n   total+=test_enc_api();\n   total+=test_repacketizer_api();\n   total+=test_malloc_fail();\n\n   fprintf(stderr,\"\\nAll API tests passed.\\nThe libopus API was invoked %d times.\\n\",total);\n\n   return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/tests/test_opus_common.h",
    "content": "/* Copyright (c) 2011 Xiph.Org Foundation\n   Written by Gregory Maxwell */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\nstatic OPUS_INLINE void deb2_impl(unsigned char *_t,unsigned char **_p,int _k,int _x,int _y)\n{\n  int i;\n  if(_x>2){\n     if(_y<3)for(i=0;i<_y;i++)*(--*_p)=_t[i+1];\n  }else{\n     _t[_x]=_t[_x-_y];\n     deb2_impl(_t,_p,_k,_x+1,_y);\n     for(i=_t[_x-_y]+1;i<_k;i++){\n       _t[_x]=i;\n       deb2_impl(_t,_p,_k,_x+1,_x);\n     }\n  }\n}\n\n/*Generates a De Bruijn sequence (k,2) with length k^2*/\nstatic OPUS_INLINE void debruijn2(int _k, unsigned char *_res)\n{\n   unsigned char *p;\n   unsigned char *t;\n   t=malloc(sizeof(unsigned char)*_k*2);\n   memset(t,0,sizeof(unsigned char)*_k*2);\n   p=&_res[_k*_k];\n   deb2_impl(t,&p,_k,1,1);\n   free(t);\n}\n\n/*MWC RNG of George Marsaglia*/\nstatic opus_uint32 Rz, Rw;\nstatic OPUS_INLINE opus_uint32 fast_rand(void)\n{\n  Rz=36969*(Rz&65535)+(Rz>>16);\n  Rw=18000*(Rw&65535)+(Rw>>16);\n  return (Rz<<16)+Rw;\n}\nstatic opus_uint32 iseed;\n\n#ifdef __GNUC__\n__attribute__((noreturn))\n#endif\nstatic OPUS_INLINE void _test_failed(const char *file, int line)\n{\n  fprintf(stderr,\"\\n ***************************************************\\n\");\n  fprintf(stderr,\" ***         A fatal error was detected.         ***\\n\");\n  fprintf(stderr,\" ***************************************************\\n\");\n  fprintf(stderr,\"Please report this failure and include\\n\");\n  fprintf(stderr,\"'make check SEED=%u fails %s at line %d for %s'\\n\",iseed,file,line,opus_get_version_string());\n  fprintf(stderr,\"and any relevant details about your system.\\n\\n\");\n  abort();\n}\n#define test_failed() _test_failed(__FILE__, __LINE__);\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/tests/test_opus_decode.c",
    "content": "/* Copyright (c) 2011-2013 Xiph.Org Foundation\n   Written by Gregory Maxwell */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <limits.h>\n#include <stdint.h>\n#include <math.h>\n#include <string.h>\n#include <time.h>\n#if (!defined WIN32 && !defined _WIN32) || defined(__MINGW32__)\n#include <unistd.h>\n#else\n#include <process.h>\n#define getpid _getpid\n#endif\n#include \"opus.h\"\n#include \"test_opus_common.h\"\n\n#define MAX_PACKET (1500)\n#define MAX_FRAME_SAMP (5760)\n\nint test_decoder_code0(int no_fuzz)\n{\n   static const opus_int32 fsv[5]={48000,24000,16000,12000,8000};\n   int err,skip,plen;\n   int out_samples,fec;\n   int t;\n   opus_int32 i;\n   OpusDecoder *dec[5*2];\n   opus_int32 decsize;\n   OpusDecoder *decbak;\n   opus_uint32 dec_final_range1,dec_final_range2,dec_final_acc;\n   unsigned char *packet;\n   unsigned char modes[4096];\n   short *outbuf_int;\n   short *outbuf;\n\n   dec_final_range1=dec_final_range2=2;\n\n   packet=malloc(sizeof(unsigned char)*MAX_PACKET);\n   if(packet==NULL)test_failed();\n\n   outbuf_int=malloc(sizeof(short)*(MAX_FRAME_SAMP+16)*2);\n   for(i=0;i<(MAX_FRAME_SAMP+16)*2;i++)outbuf_int[i]=32749;\n   outbuf=&outbuf_int[8*2];\n\n   fprintf(stdout,\"  Starting %d decoders...\\n\",5*2);\n   for(t=0;t<5*2;t++)\n   {\n      int fs=fsv[t>>1];\n      int c=(t&1)+1;\n      err=OPUS_INTERNAL_ERROR;\n      dec[t] = opus_decoder_create(fs, c, &err);\n      if(err!=OPUS_OK || dec[t]==NULL)test_failed();\n      fprintf(stdout,\"    opus_decoder_create(%5d,%d) OK. Copy \",fs,c);\n      {\n         OpusDecoder *dec2;\n         /*The opus state structures contain no pointers and can be freely copied*/\n         dec2=(OpusDecoder *)malloc(opus_decoder_get_size(c));\n         if(dec2==NULL)test_failed();\n         memcpy(dec2,dec[t],opus_decoder_get_size(c));\n         memset(dec[t],255,opus_decoder_get_size(c));\n         opus_decoder_destroy(dec[t]);\n         printf(\"OK.\\n\");\n         dec[t]=dec2;\n      }\n   }\n\n   decsize=opus_decoder_get_size(1);\n   decbak=(OpusDecoder *)malloc(decsize);\n   if(decbak==NULL)test_failed();\n\n   for(t=0;t<5*2;t++)\n   {\n      int factor=48000/fsv[t>>1];\n      for(fec=0;fec<2;fec++)\n      {\n         int dur;\n         /*Test PLC on a fresh decoder*/\n         out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, fec);\n         if(out_samples!=120/factor)test_failed();\n         if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();\n         if(dur!=120/factor)test_failed();\n\n         /*Test on a size which isn't a multiple of 2.5ms*/\n         out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor+2, fec);\n         if(out_samples!=OPUS_BAD_ARG)test_failed();\n\n         /*Test null pointer input*/\n         out_samples = opus_decode(dec[t], 0, -1, outbuf, 120/factor, fec);\n         if(out_samples!=120/factor)test_failed();\n         out_samples = opus_decode(dec[t], 0, 1, outbuf, 120/factor, fec);\n         if(out_samples!=120/factor)test_failed();\n         out_samples = opus_decode(dec[t], 0, 10, outbuf, 120/factor, fec);\n         if(out_samples!=120/factor)test_failed();\n         out_samples = opus_decode(dec[t], 0, fast_rand(), outbuf, 120/factor, fec);\n         if(out_samples!=120/factor)test_failed();\n         if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();\n         if(dur!=120/factor)test_failed();\n\n         /*Zero lengths*/\n         out_samples = opus_decode(dec[t], packet, 0, outbuf, 120/factor, fec);\n         if(out_samples!=120/factor)test_failed();\n\n         /*Zero buffer*/\n         outbuf[0]=32749;\n         out_samples = opus_decode(dec[t], packet, 0, outbuf, 0, fec);\n         if(out_samples>0)test_failed();\n         out_samples = opus_decode(dec[t], packet, 0, 0, 0, fec);\n         if(out_samples>0)test_failed();\n         if(outbuf[0]!=32749)test_failed();\n\n         /*Invalid lengths*/\n         out_samples = opus_decode(dec[t], packet, -1, outbuf, MAX_FRAME_SAMP, fec);\n         if(out_samples>=0)test_failed();\n         out_samples = opus_decode(dec[t], packet, INT_MIN, outbuf, MAX_FRAME_SAMP, fec);\n         if(out_samples>=0)test_failed();\n         out_samples = opus_decode(dec[t], packet, -1, outbuf, -1, fec);\n         if(out_samples>=0)test_failed();\n\n         /*Crazy FEC values*/\n         out_samples = opus_decode(dec[t], packet, 1, outbuf, MAX_FRAME_SAMP, fec?-1:2);\n         if(out_samples>=0)test_failed();\n\n         /*Reset the decoder*/\n         if(opus_decoder_ctl(dec[t], OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n      }\n   }\n   fprintf(stdout,\"  dec[all] initial frame PLC OK.\\n\");\n\n   /*Count code 0 tests*/\n   for(i=0;i<64;i++)\n   {\n      int dur;\n      int j,expected[5*2];\n      packet[0]=i<<2;\n      packet[1]=255;\n      packet[2]=255;\n      err=opus_packet_get_nb_channels(packet);\n      if(err!=(i&1)+1)test_failed();\n\n      for(t=0;t<5*2;t++){\n         expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);\n         if(expected[t]>2880)test_failed();\n      }\n\n      for(j=0;j<256;j++)\n      {\n         packet[1]=j;\n         for(t=0;t<5*2;t++)\n         {\n            out_samples = opus_decode(dec[t], packet, 3, outbuf, MAX_FRAME_SAMP, 0);\n            if(out_samples!=expected[t])test_failed();\n            if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();\n            if(dur!=out_samples)test_failed();\n            opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));\n            if(t==0)dec_final_range2=dec_final_range1;\n            else if(dec_final_range1!=dec_final_range2)test_failed();\n         }\n      }\n\n      for(t=0;t<5*2;t++){\n         int factor=48000/fsv[t>>1];\n         /* The PLC is run for 6 frames in order to get better PLC coverage. */\n         for(j=0;j<6;j++)\n         {\n            out_samples = opus_decode(dec[t], 0, 0, outbuf, expected[t], 0);\n            if(out_samples!=expected[t])test_failed();\n            if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();\n            if(dur!=out_samples)test_failed();\n         }\n         /* Run the PLC once at 2.5ms, as a simulation of someone trying to\n            do small drift corrections. */\n         if(expected[t]!=120/factor)\n         {\n            out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, 0);\n            if(out_samples!=120/factor)test_failed();\n            if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();\n            if(dur!=out_samples)test_failed();\n         }\n         out_samples = opus_decode(dec[t], packet, 2, outbuf, expected[t]-1, 0);\n         if(out_samples>0)test_failed();\n      }\n   }\n   fprintf(stdout,\"  dec[all] all 2-byte prefix for length 3 and PLC, all modes (64) OK.\\n\");\n\n   if(no_fuzz)\n   {\n      fprintf(stdout,\"  Skipping many tests which fuzz the decoder as requested.\\n\");\n      free(decbak);\n      for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);\n      printf(\"  Decoders stopped.\\n\");\n\n      err=0;\n      for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749;\n      for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749;\n      if(err)test_failed();\n\n      free(outbuf_int);\n      free(packet);\n      return 0;\n   }\n\n   {\n     /*We only test a subset of the modes here simply because the longer\n       durations end up taking a long time.*/\n      static const int cmodes[4]={16,20,24,28};\n      static const opus_uint32 cres[4]={116290185,2172123586u,2172123586u,2172123586u};\n      static const opus_uint32 lres[3]={3285687739u,1481572662,694350475};\n      static const int lmodes[3]={0,4,8};\n      int mode=fast_rand()%4;\n\n      packet[0]=cmodes[mode]<<3;\n      dec_final_acc=0;\n      t=fast_rand()%10;\n\n      for(i=0;i<65536;i++)\n      {\n         int factor=48000/fsv[t>>1];\n         packet[1]=i>>8;\n         packet[2]=i&255;\n         packet[3]=255;\n         out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);\n         if(out_samples!=120/factor)test_failed();\n         opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));\n         dec_final_acc+=dec_final_range1;\n      }\n      if(dec_final_acc!=cres[mode])test_failed();\n      fprintf(stdout,\"  dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\\n\",t,cmodes[mode]);\n\n      mode=fast_rand()%3;\n      packet[0]=lmodes[mode]<<3;\n      dec_final_acc=0;\n      t=fast_rand()%10;\n      for(i=0;i<65536;i++)\n      {\n         int factor=48000/fsv[t>>1];\n         packet[1]=i>>8;\n         packet[2]=i&255;\n         packet[3]=255;\n         out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);\n         if(out_samples!=480/factor)test_failed();\n         opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));\n         dec_final_acc+=dec_final_range1;\n      }\n      if(dec_final_acc!=lres[mode])test_failed();\n      fprintf(stdout,\"  dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\\n\",t,lmodes[mode]);\n   }\n\n   skip=fast_rand()%7;\n   for(i=0;i<64;i++)\n   {\n      int j,expected[5*2];\n      packet[0]=i<<2;\n      for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);\n      for(j=2+skip;j<1275;j+=4)\n      {\n         int jj;\n         for(jj=0;jj<j;jj++)packet[jj+1]=fast_rand()&255;\n         for(t=0;t<5*2;t++)\n         {\n            out_samples = opus_decode(dec[t], packet, j+1, outbuf, MAX_FRAME_SAMP, 0);\n            if(out_samples!=expected[t])test_failed();\n            opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));\n            if(t==0)dec_final_range2=dec_final_range1;\n            else if(dec_final_range1!=dec_final_range2)test_failed();\n         }\n      }\n   }\n   fprintf(stdout,\"  dec[all] random packets, all modes (64), every 8th size from from %d bytes to maximum OK.\\n\",2+skip);\n\n   debruijn2(64,modes);\n   plen=(fast_rand()%18+3)*8+skip+3;\n   for(i=0;i<4096;i++)\n   {\n      int j,expected[5*2];\n      packet[0]=modes[i]<<2;\n      for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,plen);\n      for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;\n      memcpy(decbak,dec[0],decsize);\n      if(opus_decode(decbak, packet, plen+1, outbuf, expected[0], 1)!=expected[0])test_failed();\n      memcpy(decbak,dec[0],decsize);\n      if(opus_decode(decbak,  0, 0, outbuf, MAX_FRAME_SAMP, 1)<20)test_failed();\n      memcpy(decbak,dec[0],decsize);\n      if(opus_decode(decbak,  0, 0, outbuf, MAX_FRAME_SAMP, 0)<20)test_failed();\n      for(t=0;t<5*2;t++)\n      {\n         int dur;\n         out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);\n         if(out_samples!=expected[t])test_failed();\n         if(t==0)dec_final_range2=dec_final_range1;\n         else if(dec_final_range1!=dec_final_range2)test_failed();\n         if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();\n         if(dur!=out_samples)test_failed();\n      }\n   }\n   fprintf(stdout,\"  dec[all] random packets, all mode pairs (4096), %d bytes/frame OK.\\n\",plen+1);\n\n   plen=(fast_rand()%18+3)*8+skip+3;\n   t=rand()&3;\n   for(i=0;i<4096;i++)\n   {\n      int count,j,expected;\n      packet[0]=modes[i]<<2;\n      expected=opus_decoder_get_nb_samples(dec[t],packet,plen);\n      for(count=0;count<10;count++)\n      {\n         for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;\n         out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);\n         if(out_samples!=expected)test_failed();\n      }\n   }\n   fprintf(stdout,\"  dec[%3d] random packets, all mode pairs (4096)*10, %d bytes/frame OK.\\n\",t,plen+1);\n\n   {\n      int tmodes[1]={25<<2};\n      opus_uint32 tseeds[1]={140441};\n      int tlen[1]={157};\n      opus_int32 tret[1]={480};\n      t=fast_rand()&1;\n      for(i=0;i<1;i++)\n      {\n         int j;\n         packet[0]=tmodes[i];\n         Rw=Rz=tseeds[i];\n         for(j=1;j<tlen[i];j++)packet[j]=fast_rand()&255;\n         out_samples=opus_decode(dec[t], packet, tlen[i], outbuf, MAX_FRAME_SAMP, 0);\n         if(out_samples!=tret[i])test_failed();\n      }\n      fprintf(stdout,\"  dec[%3d] pre-selected random packets OK.\\n\",t);\n   }\n\n   free(decbak);\n   for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);\n   printf(\"  Decoders stopped.\\n\");\n\n   err=0;\n   for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749;\n   for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749;\n   if(err)test_failed();\n\n   free(outbuf_int);\n   free(packet);\n   return 0;\n}\n\n#ifndef DISABLE_FLOAT_API\nvoid test_soft_clip(void)\n{\n   int i,j;\n   float x[1024];\n   float s[8] = {0, 0, 0, 0, 0, 0, 0, 0};\n   fprintf(stdout,\"  Testing opus_pcm_soft_clip... \");\n   for(i=0;i<1024;i++)\n   {\n      for (j=0;j<1024;j++)\n      {\n        x[j]=(i&255)*(1/32.f)-4.f;\n      }\n      opus_pcm_soft_clip(&x[i],1024-i,1,s);\n      for (j=i;j<1024;j++)\n      {\n        if(x[i]>1.f)test_failed();\n        if(x[i]<-1.f)test_failed();\n      }\n   }\n   for(i=1;i<9;i++)\n   {\n      for (j=0;j<1024;j++)\n      {\n        x[j]=(i&255)*(1/32.f)-4.f;\n      }\n      opus_pcm_soft_clip(x,1024/i,i,s);\n      for (j=0;j<(1024/i)*i;j++)\n      {\n        if(x[i]>1.f)test_failed();\n        if(x[i]<-1.f)test_failed();\n      }\n   }\n   opus_pcm_soft_clip(x,0,1,s);\n   opus_pcm_soft_clip(x,1,0,s);\n   opus_pcm_soft_clip(x,1,1,0);\n   opus_pcm_soft_clip(x,1,-1,s);\n   opus_pcm_soft_clip(x,-1,1,s);\n   opus_pcm_soft_clip(0,1,1,s);\n   printf(\"OK.\\n\");\n}\n#endif\n\nint main(int _argc, char **_argv)\n{\n   const char * oversion;\n   const char * env_seed;\n   int env_used;\n\n   if(_argc>2)\n   {\n      fprintf(stderr,\"Usage: %s [<seed>]\\n\",_argv[0]);\n      return 1;\n   }\n\n   env_used=0;\n   env_seed=getenv(\"SEED\");\n   if(_argc>1)iseed=atoi(_argv[1]);\n   else if(env_seed)\n   {\n      iseed=atoi(env_seed);\n      env_used=1;\n   }\n   else iseed=(opus_uint32)time(NULL)^((getpid()&65535)<<16);\n   Rw=Rz=iseed;\n\n   oversion=opus_get_version_string();\n   if(!oversion)test_failed();\n   fprintf(stderr,\"Testing %s decoder. Random seed: %u (%.4X)\\n\", oversion, iseed, fast_rand() % 65535);\n   if(env_used)fprintf(stderr,\"  Random seed set from the environment (SEED=%s).\\n\", env_seed);\n\n   /*Setting TEST_OPUS_NOFUZZ tells the tool not to send garbage data\n     into the decoders. This is helpful because garbage data\n     may cause the decoders to clip, which angers CLANG IOC.*/\n   test_decoder_code0(getenv(\"TEST_OPUS_NOFUZZ\")!=NULL);\n#ifndef DISABLE_FLOAT_API\n   test_soft_clip();\n#endif\n\n   return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/tests/test_opus_encode.c",
    "content": "/* Copyright (c) 2011-2013 Xiph.Org Foundation\n   Written by Gregory Maxwell */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <limits.h>\n#include <stdint.h>\n#include <math.h>\n#include <string.h>\n#include <time.h>\n#if (!defined WIN32 && !defined _WIN32) || defined(__MINGW32__)\n#include <unistd.h>\n#else\n#include <process.h>\n#define getpid _getpid\n#endif\n#include \"opus_multistream.h\"\n#include \"opus.h\"\n#include \"../src/opus_private.h\"\n#include \"test_opus_common.h\"\n\n#define MAX_PACKET (1500)\n#define SAMPLES (48000*30)\n#define SSAMPLES (SAMPLES/3)\n#define MAX_FRAME_SAMP (5760)\n\n#define PI (3.141592653589793238462643f)\n\nvoid generate_music(short *buf, opus_int32 len)\n{\n   opus_int32 a1,b1,a2,b2;\n   opus_int32 c1,c2,d1,d2;\n   opus_int32 i,j;\n   a1=b1=a2=b2=0;\n   c1=c2=d1=d2=0;\n   j=0;\n   /*60ms silence*/\n   for(i=0;i<2880;i++)buf[i*2]=buf[i*2+1]=0;\n   for(i=2880;i<len;i++)\n   {\n     opus_uint32 r;\n     opus_int32 v1,v2;\n     v1=v2=(((j*((j>>12)^((j>>10|j>>12)&26&j>>7)))&128)+128)<<15;\n     r=fast_rand();v1+=r&65535;v1-=r>>16;\n     r=fast_rand();v2+=r&65535;v2-=r>>16;\n     b1=v1-a1+((b1*61+32)>>6);a1=v1;\n     b2=v2-a2+((b2*61+32)>>6);a2=v2;\n     c1=(30*(c1+b1+d1)+32)>>6;d1=b1;\n     c2=(30*(c2+b2+d2)+32)>>6;d2=b2;\n     v1=(c1+128)>>8;\n     v2=(c2+128)>>8;\n     buf[i*2]=v1>32767?32767:(v1<-32768?-32768:v1);\n     buf[i*2+1]=v2>32767?32767:(v2<-32768?-32768:v2);\n     if(i%6==0)j++;\n   }\n}\n\n#if 0\nstatic int save_ctr = 0;\nstatic void int_to_char(opus_uint32 i, unsigned char ch[4])\n{\n    ch[0] = i>>24;\n    ch[1] = (i>>16)&0xFF;\n    ch[2] = (i>>8)&0xFF;\n    ch[3] = i&0xFF;\n}\n\nstatic OPUS_INLINE void save_packet(unsigned char* p, int len, opus_uint32 rng)\n{\n   FILE *fout;\n   unsigned char int_field[4];\n   char name[256];\n   snprintf(name,255,\"test_opus_encode.%llu.%d.bit\",(unsigned long long)iseed,save_ctr);\n   fprintf(stdout,\"writing %d byte packet to %s\\n\",len,name);\n   fout=fopen(name, \"wb+\");\n   if(fout==NULL)test_failed();\n   int_to_char(len, int_field);\n   fwrite(int_field, 1, 4, fout);\n   int_to_char(rng, int_field);\n   fwrite(int_field, 1, 4, fout);\n   fwrite(p, 1, len, fout);\n   fclose(fout);\n   save_ctr++;\n}\n#endif\n\nint run_test1(int no_fuzz)\n{\n   static const int fsizes[6]={960*3,960*2,120,240,480,960};\n   static const char *mstrings[3] = {\"    LP\",\"Hybrid\",\"  MDCT\"};\n   unsigned char mapping[256] = {0,1,255};\n   unsigned char db62[36];\n   opus_int32 i;\n   int rc,j,err;\n   OpusEncoder *enc;\n   OpusMSEncoder *MSenc;\n   OpusDecoder *dec;\n   OpusMSDecoder *MSdec;\n   OpusMSDecoder *MSdec_err;\n   OpusDecoder *dec_err[10];\n   short *inbuf;\n   short *outbuf;\n   short *out2buf;\n   opus_int32 bitrate_bps;\n   unsigned char packet[MAX_PACKET+257];\n   opus_uint32 enc_final_range;\n   opus_uint32 dec_final_range;\n   int fswitch;\n   int fsize;\n   int count;\n\n  /*FIXME: encoder api tests, fs!=48k, mono, VBR*/\n\n   fprintf(stdout,\"  Encode+Decode tests.\\n\");\n\n   enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_VOIP, &err);\n   if(err != OPUS_OK || enc==NULL)test_failed();\n\n   for(i=0;i<2;i++)\n   {\n      int *ret_err;\n      ret_err = i?0:&err;\n      MSenc = opus_multistream_encoder_create(8000, 2, 2, 0, mapping, OPUS_UNIMPLEMENTED, ret_err);\n      if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();\n\n      MSenc = opus_multistream_encoder_create(8000, 0, 1, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);\n      if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();\n\n      MSenc = opus_multistream_encoder_create(44100, 2, 2, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);\n      if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();\n\n      MSenc = opus_multistream_encoder_create(8000, 2, 2, 3, mapping, OPUS_APPLICATION_VOIP, ret_err);\n      if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();\n\n      MSenc = opus_multistream_encoder_create(8000, 2, -1, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);\n      if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();\n\n      MSenc = opus_multistream_encoder_create(8000, 256, 2, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);\n      if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();\n   }\n\n   MSenc = opus_multistream_encoder_create(8000, 2, 2, 0, mapping, OPUS_APPLICATION_AUDIO, &err);\n   if(err != OPUS_OK || MSenc==NULL)test_failed();\n\n   /*Some multistream encoder API tests*/\n   if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_BITRATE(&i))!=OPUS_OK)test_failed();\n   if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_LSB_DEPTH(&i))!=OPUS_OK)test_failed();\n   if(i<16)test_failed();\n\n   {\n      OpusEncoder *tmp_enc;\n      if(opus_multistream_encoder_ctl(MSenc,  OPUS_MULTISTREAM_GET_ENCODER_STATE(1,&tmp_enc))!=OPUS_OK)test_failed();\n      if(opus_encoder_ctl(tmp_enc, OPUS_GET_LSB_DEPTH(&j))!=OPUS_OK)test_failed();\n      if(i!=j)test_failed();\n      if(opus_multistream_encoder_ctl(MSenc,  OPUS_MULTISTREAM_GET_ENCODER_STATE(2,&tmp_enc))!=OPUS_BAD_ARG)test_failed();\n   }\n\n   dec = opus_decoder_create(48000, 2, &err);\n   if(err != OPUS_OK || dec==NULL)test_failed();\n\n   MSdec = opus_multistream_decoder_create(48000, 2, 2, 0, mapping, &err);\n   if(err != OPUS_OK || MSdec==NULL)test_failed();\n\n   MSdec_err = opus_multistream_decoder_create(48000, 3, 2, 0, mapping, &err);\n   if(err != OPUS_OK || MSdec_err==NULL)test_failed();\n\n   dec_err[0]=(OpusDecoder *)malloc(opus_decoder_get_size(2));\n   memcpy(dec_err[0],dec,opus_decoder_get_size(2));\n   dec_err[1] = opus_decoder_create(48000, 1, &err);\n   dec_err[2] = opus_decoder_create(24000, 2, &err);\n   dec_err[3] = opus_decoder_create(24000, 1, &err);\n   dec_err[4] = opus_decoder_create(16000, 2, &err);\n   dec_err[5] = opus_decoder_create(16000, 1, &err);\n   dec_err[6] = opus_decoder_create(12000, 2, &err);\n   dec_err[7] = opus_decoder_create(12000, 1, &err);\n   dec_err[8] = opus_decoder_create(8000, 2, &err);\n   dec_err[9] = opus_decoder_create(8000, 1, &err);\n   for(i=0;i<10;i++)if(dec_err[i]==NULL)test_failed();\n\n   {\n      OpusEncoder *enccpy;\n      /*The opus state structures contain no pointers and can be freely copied*/\n      enccpy=(OpusEncoder *)malloc(opus_encoder_get_size(2));\n      memcpy(enccpy,enc,opus_encoder_get_size(2));\n      memset(enc,255,opus_encoder_get_size(2));\n      opus_encoder_destroy(enc);\n      enc=enccpy;\n   }\n\n   inbuf=(short *)malloc(sizeof(short)*SAMPLES*2);\n   outbuf=(short *)malloc(sizeof(short)*SAMPLES*2);\n   out2buf=(short *)malloc(sizeof(short)*MAX_FRAME_SAMP*3);\n   if(inbuf==NULL || outbuf==NULL || out2buf==NULL)test_failed();\n\n   generate_music(inbuf,SAMPLES);\n\n/*   FILE *foo;\n   foo = fopen(\"foo.sw\", \"wb+\");\n   fwrite(inbuf, 1, SAMPLES*2*2, foo);\n   fclose(foo);*/\n\n   if(opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO))!=OPUS_OK)test_failed();\n   if(opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(-2))!=OPUS_BAD_ARG)test_failed();\n\n   for(rc=0;rc<3;rc++)\n   {\n      if(opus_encoder_ctl(enc, OPUS_SET_VBR(rc<2))!=OPUS_OK)test_failed();\n      if(opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed();\n      if(opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed();\n      if(opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rc==0))!=OPUS_OK)test_failed();\n      for(j=0;j<13;j++)\n      {\n         int rate;\n         int modes[13]={0,0,0,1,1,1,1,2,2,2,2,2,2};\n         int rates[13]={6000,12000,48000,16000,32000,48000,64000,512000,13000,24000,48000,64000,96000};\n         int frame[13]={960*2,960,480,960,960,960,480,960*3,960*3,960,480,240,120};\n         rate=rates[j]+fast_rand()%rates[j];\n         count=i=0;\n         do {\n            int bw,len,out_samples,frame_size;\n            frame_size=frame[j];\n            if((fast_rand()&255)==0)\n            {\n               if(opus_encoder_ctl(enc, OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n               if(opus_decoder_ctl(dec, OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n               if((fast_rand()&1)!=0)\n               {\n                  if(opus_decoder_ctl(dec_err[fast_rand()&1], OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n               }\n            }\n            if((fast_rand()&127)==0)\n            {\n               if(opus_decoder_ctl(dec_err[fast_rand()&1], OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n            }\n            if(fast_rand()%10==0){\n               int complex=fast_rand()%11;\n               if(opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complex))!=OPUS_OK)test_failed();\n            }\n            if(fast_rand()%50==0)opus_decoder_ctl(dec, OPUS_RESET_STATE);\n            if(opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rc==0))!=OPUS_OK)test_failed();\n            if(opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_SILK_ONLY+modes[j]))!=OPUS_OK)test_failed();\n            if(opus_encoder_ctl(enc, OPUS_SET_DTX(fast_rand()&1))!=OPUS_OK)test_failed();\n            if(opus_encoder_ctl(enc, OPUS_SET_BITRATE(rate))!=OPUS_OK)test_failed();\n            if(opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS((rates[j]>=64000?2:1)))!=OPUS_OK)test_failed();\n            if(opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY((count>>2)%11))!=OPUS_OK)test_failed();\n            if(opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC((fast_rand()&15)&(fast_rand()%15)))!=OPUS_OK)test_failed();\n            bw=modes[j]==0?OPUS_BANDWIDTH_NARROWBAND+(fast_rand()%3):\n               modes[j]==1?OPUS_BANDWIDTH_SUPERWIDEBAND+(fast_rand()&1):\n                           OPUS_BANDWIDTH_NARROWBAND+(fast_rand()%5);\n            if(modes[j]==2&&bw==OPUS_BANDWIDTH_MEDIUMBAND)bw+=3;\n            if(opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bw))!=OPUS_OK)test_failed();\n            len = opus_encode(enc, &inbuf[i<<1], frame_size, packet, MAX_PACKET);\n            if(len<0 || len>MAX_PACKET)test_failed();\n            if(opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range))!=OPUS_OK)test_failed();\n            if((fast_rand()&3)==0)\n            {\n               if(opus_packet_pad(packet,len,len+1)!=OPUS_OK)test_failed();\n               len++;\n            }\n            if((fast_rand()&7)==0)\n            {\n               if(opus_packet_pad(packet,len,len+256)!=OPUS_OK)test_failed();\n               len+=256;\n            }\n            if((fast_rand()&3)==0)\n            {\n               len=opus_packet_unpad(packet,len);\n               if(len<1)test_failed();\n            }\n            out_samples = opus_decode(dec, packet, len, &outbuf[i<<1], MAX_FRAME_SAMP, 0);\n            if(out_samples!=frame_size)test_failed();\n            if(opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range))!=OPUS_OK)test_failed();\n            if(enc_final_range!=dec_final_range)test_failed();\n            /*LBRR decode*/\n            out_samples = opus_decode(dec_err[0], packet, len, out2buf, frame_size, (fast_rand()&3)!=0);\n            if(out_samples!=frame_size)test_failed();\n            out_samples = opus_decode(dec_err[1], packet, (fast_rand()&3)==0?0:len, out2buf, MAX_FRAME_SAMP, (fast_rand()&7)!=0);\n            if(out_samples<120)test_failed();\n            i+=frame_size;\n            count++;\n         }while(i<(SSAMPLES-MAX_FRAME_SAMP));\n         fprintf(stdout,\"    Mode %s FB encode %s, %6d bps OK.\\n\",mstrings[modes[j]],rc==0?\" VBR\":rc==1?\"CVBR\":\" CBR\",rate);\n      }\n   }\n\n   if(opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(OPUS_AUTO))!=OPUS_OK)test_failed();\n   if(opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO))!=OPUS_OK)test_failed();\n   if(opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0))!=OPUS_OK)test_failed();\n   if(opus_encoder_ctl(enc, OPUS_SET_DTX(0))!=OPUS_OK)test_failed();\n\n   for(rc=0;rc<3;rc++)\n   {\n      if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_VBR(rc<2))!=OPUS_OK)test_failed();\n      if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed();\n      if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed();\n      if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_INBAND_FEC(rc==0))!=OPUS_OK)test_failed();\n      for(j=0;j<16;j++)\n      {\n         int rate;\n         int modes[16]={0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2};\n         int rates[16]={4000,12000,32000,8000,16000,32000,48000,88000,4000,12000,32000,8000,16000,32000,48000,88000};\n         int frame[16]={160*1,160,80,160,160,80,40,20,160*1,160,80,160,160,80,40,20};\n         if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_INBAND_FEC(rc==0&&j==1))!=OPUS_OK)test_failed();\n         if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_FORCE_MODE(MODE_SILK_ONLY+modes[j]))!=OPUS_OK)test_failed();\n         rate=rates[j]+fast_rand()%rates[j];\n         if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_DTX(fast_rand()&1))!=OPUS_OK)test_failed();\n         if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_BITRATE(rate))!=OPUS_OK)test_failed();\n         count=i=0;\n         do {\n            int pred,len,out_samples,frame_size,loss;\n            if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_PREDICTION_DISABLED(&pred))!=OPUS_OK)test_failed();\n            if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_PREDICTION_DISABLED((int)(fast_rand()&15)<(pred?11:4)))!=OPUS_OK)test_failed();\n            frame_size=frame[j];\n            if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_COMPLEXITY((count>>2)%11))!=OPUS_OK)test_failed();\n            if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_PACKET_LOSS_PERC((fast_rand()&15)&(fast_rand()%15)))!=OPUS_OK)test_failed();\n            if((fast_rand()&255)==0)\n            {\n               if(opus_multistream_encoder_ctl(MSenc, OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n               if(opus_multistream_decoder_ctl(MSdec, OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n               if((fast_rand()&3)!=0)\n               {\n                  if(opus_multistream_decoder_ctl(MSdec_err, OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n               }\n            }\n            if((fast_rand()&255)==0)\n            {\n               if(opus_multistream_decoder_ctl(MSdec_err, OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n            }\n            len = opus_multistream_encode(MSenc, &inbuf[i<<1], frame_size, packet, MAX_PACKET);\n            if(len<0 || len>MAX_PACKET)test_failed();\n            if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_FINAL_RANGE(&enc_final_range))!=OPUS_OK)test_failed();\n            if((fast_rand()&3)==0)\n            {\n               if(opus_multistream_packet_pad(packet,len,len+1,2)!=OPUS_OK)test_failed();\n               len++;\n            }\n            if((fast_rand()&7)==0)\n            {\n               if(opus_multistream_packet_pad(packet,len,len+256,2)!=OPUS_OK)test_failed();\n               len+=256;\n            }\n            if((fast_rand()&3)==0)\n            {\n               len=opus_multistream_packet_unpad(packet,len,2);\n               if(len<1)test_failed();\n            }\n            out_samples = opus_multistream_decode(MSdec, packet, len, out2buf, MAX_FRAME_SAMP, 0);\n            if(out_samples!=frame_size*6)test_failed();\n            if(opus_multistream_decoder_ctl(MSdec, OPUS_GET_FINAL_RANGE(&dec_final_range))!=OPUS_OK)test_failed();\n            if(enc_final_range!=dec_final_range)test_failed();\n            /*LBRR decode*/\n            loss=(fast_rand()&63)==0;\n            out_samples = opus_multistream_decode(MSdec_err, packet, loss?0:len, out2buf, frame_size*6, (fast_rand()&3)!=0);\n            if(out_samples!=(frame_size*6))test_failed();\n            i+=frame_size;\n            count++;\n         }while(i<(SSAMPLES/12-MAX_FRAME_SAMP));\n         fprintf(stdout,\"    Mode %s NB dual-mono MS encode %s, %6d bps OK.\\n\",mstrings[modes[j]],rc==0?\" VBR\":rc==1?\"CVBR\":\" CBR\",rate);\n      }\n   }\n\n   bitrate_bps=512000;\n   fsize=fast_rand()%31;\n   fswitch=100;\n\n   debruijn2(6,db62);\n   count=i=0;\n   do {\n      unsigned char toc;\n      const unsigned char *frames[48];\n      short size[48];\n      int payload_offset;\n      opus_uint32 dec_final_range2;\n      int jj,dec2;\n      int len,out_samples;\n      int frame_size=fsizes[db62[fsize]];\n      opus_int32 offset=i%(SAMPLES-MAX_FRAME_SAMP);\n\n      opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));\n\n      len = opus_encode(enc, &inbuf[offset<<1], frame_size, packet, MAX_PACKET);\n      if(len<0 || len>MAX_PACKET)test_failed();\n      count++;\n\n      opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range));\n\n      out_samples = opus_decode(dec, packet, len, &outbuf[offset<<1], MAX_FRAME_SAMP, 0);\n      if(out_samples!=frame_size)test_failed();\n\n      opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));\n\n      /* compare final range encoder rng values of encoder and decoder */\n      if(dec_final_range!=enc_final_range)test_failed();\n\n      /* We fuzz the packet, but take care not to only corrupt the payload\n         Corrupted headers are tested elsewhere and we need to actually run\n         the decoders in order to compare them. */\n      if(opus_packet_parse(packet,len,&toc,frames,size,&payload_offset)<=0)test_failed();\n      if((fast_rand()&1023)==0)len=0;\n      for(j=(frames[0]-packet);j<len;j++)for(jj=0;jj<8;jj++)packet[j]^=((!no_fuzz)&&((fast_rand()&1023)==0))<<jj;\n      out_samples = opus_decode(dec_err[0], len>0?packet:NULL, len, out2buf, MAX_FRAME_SAMP, 0);\n      if(out_samples<0||out_samples>MAX_FRAME_SAMP)test_failed();\n      if((len>0&&out_samples!=frame_size))test_failed(); /*FIXME use lastframe*/\n\n      opus_decoder_ctl(dec_err[0], OPUS_GET_FINAL_RANGE(&dec_final_range));\n\n      /*randomly select one of the decoders to compare with*/\n      dec2=fast_rand()%9+1;\n      out_samples = opus_decode(dec_err[dec2], len>0?packet:NULL, len, out2buf, MAX_FRAME_SAMP, 0);\n      if(out_samples<0||out_samples>MAX_FRAME_SAMP)test_failed(); /*FIXME, use factor, lastframe for loss*/\n\n      opus_decoder_ctl(dec_err[dec2], OPUS_GET_FINAL_RANGE(&dec_final_range2));\n      if(len>0&&dec_final_range!=dec_final_range2)test_failed();\n\n      fswitch--;\n      if(fswitch<1)\n      {\n        int new_size;\n        fsize=(fsize+1)%36;\n        new_size=fsizes[db62[fsize]];\n        if(new_size==960||new_size==480)fswitch=2880/new_size*(fast_rand()%19+1);\n        else fswitch=(fast_rand()%(2880/new_size))+1;\n      }\n      bitrate_bps=((fast_rand()%508000+4000)+bitrate_bps)>>1;\n      i+=frame_size;\n   }while(i<SAMPLES*4);\n   fprintf(stdout,\"    All framesize pairs switching encode, %d frames OK.\\n\",count);\n\n   if(opus_encoder_ctl(enc, OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n   opus_encoder_destroy(enc);\n   if(opus_multistream_encoder_ctl(MSenc, OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n   opus_multistream_encoder_destroy(MSenc);\n   if(opus_decoder_ctl(dec, OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n   opus_decoder_destroy(dec);\n   if(opus_multistream_decoder_ctl(MSdec, OPUS_RESET_STATE)!=OPUS_OK)test_failed();\n   opus_multistream_decoder_destroy(MSdec);\n   opus_multistream_decoder_destroy(MSdec_err);\n   for(i=0;i<10;i++)opus_decoder_destroy(dec_err[i]);\n   free(inbuf);\n   free(outbuf);\n   free(out2buf);\n   return 0;\n}\n\nint main(int _argc, char **_argv)\n{\n   const char * oversion;\n   const char * env_seed;\n   int env_used;\n\n   if(_argc>2)\n   {\n      fprintf(stderr,\"Usage: %s [<seed>]\\n\",_argv[0]);\n      return 1;\n   }\n\n   env_used=0;\n   env_seed=getenv(\"SEED\");\n   if(_argc>1)iseed=atoi(_argv[1]);\n   else if(env_seed)\n   {\n      iseed=atoi(env_seed);\n      env_used=1;\n   }\n   else iseed=(opus_uint32)time(NULL)^((getpid()&65535)<<16);\n   Rw=Rz=iseed;\n\n   oversion=opus_get_version_string();\n   if(!oversion)test_failed();\n   fprintf(stderr,\"Testing %s encoder. Random seed: %u (%.4X)\\n\", oversion, iseed, fast_rand() % 65535);\n   if(env_used)fprintf(stderr,\"  Random seed set from the environment (SEED=%s).\\n\", env_seed);\n\n   /*Setting TEST_OPUS_NOFUZZ tells the tool not to send garbage data\n     into the decoders. This is helpful because garbage data\n     may cause the decoders to clip, which angers CLANG IOC.*/\n   run_test1(getenv(\"TEST_OPUS_NOFUZZ\")!=NULL);\n\n   fprintf(stderr,\"Tests completed successfully.\\n\");\n\n   return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/tests/test_opus_padding.c",
    "content": "/* Copyright (c) 2012 Xiph.Org Foundation\n   Written by Jüri Aedla and Ralph Giles */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/* Check for overflow in reading the padding length.\n * http://lists.xiph.org/pipermail/opus/2012-November/001834.html\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include \"opus.h\"\n#include \"test_opus_common.h\"\n\n#define PACKETSIZE 16909318\n#define CHANNELS 2\n#define FRAMESIZE 5760\n\nint test_overflow(void)\n{\n  OpusDecoder *decoder;\n  int result;\n  int error;\n\n  unsigned char *in = malloc(PACKETSIZE);\n  opus_int16 *out = malloc(FRAMESIZE*CHANNELS*sizeof(*out));\n\n  fprintf(stderr, \"  Checking for padding overflow... \");\n  if (!in || !out) {\n    fprintf(stderr, \"FAIL (out of memory)\\n\");\n    return -1;\n  }\n  in[0] = 0xff;\n  in[1] = 0x41;\n  memset(in + 2, 0xff, PACKETSIZE - 3);\n  in[PACKETSIZE-1] = 0x0b;\n\n  decoder = opus_decoder_create(48000, CHANNELS, &error);\n  result = opus_decode(decoder, in, PACKETSIZE, out, FRAMESIZE, 0);\n  opus_decoder_destroy(decoder);\n\n  free(in);\n  free(out);\n\n  if (result != OPUS_INVALID_PACKET) {\n    fprintf(stderr, \"FAIL!\\n\");\n    test_failed();\n  }\n\n  fprintf(stderr, \"OK.\\n\");\n\n  return 1;\n}\n\nint main(void)\n{\n  const char *oversion;\n  int tests = 0;;\n\n  iseed = 0;\n  oversion = opus_get_version_string();\n  if (!oversion) test_failed();\n  fprintf(stderr, \"Testing %s padding.\\n\", oversion);\n\n  tests += test_overflow();\n\n  fprintf(stderr, \"All padding tests passed.\\n\");\n\n  return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/version.mk",
    "content": "# static version string; update manually every release.\nPACKAGE_VERSION = \"1.1.2\"\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/celt.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\celt\\bands.c\" />\n    <ClCompile Include=\"..\\..\\celt\\celt.c\" />\n    <ClCompile Include=\"..\\..\\celt\\celt_decoder.c\" />\n    <ClCompile Include=\"..\\..\\celt\\celt_encoder.c\" />\n    <ClCompile Include=\"..\\..\\celt\\celt_lpc.c\" />\n    <ClCompile Include=\"..\\..\\celt\\cwrs.c\" />\n    <ClCompile Include=\"..\\..\\celt\\entcode.c\" />\n    <ClCompile Include=\"..\\..\\celt\\entdec.c\" />\n    <ClCompile Include=\"..\\..\\celt\\entenc.c\" />\n    <ClCompile Include=\"..\\..\\celt\\kiss_fft.c\" />\n    <ClCompile Include=\"..\\..\\celt\\laplace.c\" />\n    <ClCompile Include=\"..\\..\\celt\\mathops.c\" />\n    <ClCompile Include=\"..\\..\\celt\\mdct.c\" />\n    <ClCompile Include=\"..\\..\\celt\\modes.c\" />\n    <ClCompile Include=\"..\\..\\celt\\pitch.c\" />\n    <ClCompile Include=\"..\\..\\celt\\quant_bands.c\" />\n    <ClCompile Include=\"..\\..\\celt\\rate.c\" />\n    <ClCompile Include=\"..\\..\\celt\\vq.c\" />\n    <ClCompile Include=\"..\\..\\celt\\x86\\celt_lpc_sse.c\" />\n    <ClCompile Include=\"..\\..\\celt\\x86\\pitch_sse.c\" />\n    <ClCompile Include=\"..\\..\\celt\\x86\\pitch_sse2.c\" />\n    <ClCompile Include=\"..\\..\\celt\\x86\\pitch_sse4_1.c\" />\n    <ClCompile Include=\"..\\..\\celt\\x86\\x86cpu.c\" />\n    <ClCompile Include=\"..\\..\\celt\\x86\\x86_celt_map.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\celt\\arch.h\" />\n    <ClInclude Include=\"..\\..\\celt\\bands.h\" />\n    <ClInclude Include=\"..\\..\\celt\\celt.h\" />\n    <ClInclude Include=\"..\\..\\celt\\celt_lpc.h\" />\n    <ClInclude Include=\"..\\..\\celt\\cwrs.h\" />\n    <ClInclude Include=\"..\\..\\celt\\ecintrin.h\" />\n    <ClInclude Include=\"..\\..\\celt\\entcode.h\" />\n    <ClInclude Include=\"..\\..\\celt\\entdec.h\" />\n    <ClInclude Include=\"..\\..\\celt\\entenc.h\" />\n    <ClInclude Include=\"..\\..\\celt\\fixed_c5x.h\" />\n    <ClInclude Include=\"..\\..\\celt\\fixed_c6x.h\" />\n    <ClInclude Include=\"..\\..\\celt\\fixed_debug.h\" />\n    <ClInclude Include=\"..\\..\\celt\\fixed_generic.h\" />\n    <ClInclude Include=\"..\\..\\celt\\float_cast.h\" />\n    <ClInclude Include=\"..\\..\\celt\\kiss_fft.h\" />\n    <ClInclude Include=\"..\\..\\celt\\laplace.h\" />\n    <ClInclude Include=\"..\\..\\celt\\mathops.h\" />\n    <ClInclude Include=\"..\\..\\celt\\mdct.h\" />\n    <ClInclude Include=\"..\\..\\celt\\mfrngcod.h\" />\n    <ClInclude Include=\"..\\..\\celt\\modes.h\" />\n    <ClInclude Include=\"..\\..\\celt\\os_support.h\" />\n    <ClInclude Include=\"..\\..\\celt\\pitch.h\" />\n    <ClInclude Include=\"..\\..\\celt\\quant_bands.h\" />\n    <ClInclude Include=\"..\\..\\celt\\rate.h\" />\n    <ClInclude Include=\"..\\..\\celt\\stack_alloc.h\" />\n    <ClInclude Include=\"..\\..\\celt\\static_modes_fixed.h\" />\n    <ClInclude Include=\"..\\..\\celt\\static_modes_float.h\" />\n    <ClInclude Include=\"..\\..\\celt\\vq.h\" />\n    <ClInclude Include=\"..\\..\\celt\\x86\\celt_lpc_sse.h\" />\n    <ClInclude Include=\"..\\..\\celt\\x86\\pitch_sse.h\" />\n    <ClInclude Include=\"..\\..\\celt\\x86\\x86cpu.h\" />\n    <ClInclude Include=\"..\\..\\celt\\_kiss_fft_guts.h\" />\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{245603E3-F580-41A5-9632-B25FE3372CBF}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>celt</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <CustomBuildBeforeTargets>\n    </CustomBuildBeforeTargets>\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\;..\\..\\include;..\\..\\celt;..\\..\\silk;..\\..\\silk\\float;..\\..\\silk\\fixed;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\;..\\..\\include;..\\..\\celt;..\\..\\silk;..\\..\\silk\\float;..\\..\\silk\\fixed;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\;..\\..\\include;..\\..\\celt;..\\..\\silk;..\\..\\silk\\float;..\\..\\silk\\fixed;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\;..\\..\\include;..\\..\\celt;..\\..\\silk;..\\..\\silk\\float;..\\..\\silk\\fixed;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/celt.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\celt\\celt_decoder.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\celt_encoder.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\celt_lpc.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\cwrs.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\entcode.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\entdec.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\entenc.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\kiss_fft.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\laplace.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\mathops.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\mdct.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\modes.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\pitch.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\quant_bands.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\rate.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\vq.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\bands.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\celt.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\x86\\celt_lpc_sse.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\x86\\pitch_sse.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\x86\\pitch_sse2.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\x86\\pitch_sse4_1.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\x86\\x86_celt_map.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\celt\\x86\\x86cpu.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\celt\\cwrs.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\ecintrin.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\entcode.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\entdec.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\entenc.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\fixed_c5x.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\fixed_c6x.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\fixed_debug.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\fixed_generic.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\float_cast.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\kiss_fft.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\laplace.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\mathops.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\mdct.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\mfrngcod.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\modes.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\os_support.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\pitch.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\quant_bands.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\rate.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\stack_alloc.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\static_modes_fixed.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\static_modes_float.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\vq.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\_kiss_fft_guts.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\arch.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\bands.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\celt.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\celt_lpc.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\x86\\celt_lpc_sse.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\x86\\pitch_sse.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\x86\\x86cpu.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/opus.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 11.00\n# Visual Studio 2010\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"opus\", \"opus.vcxproj\", \"{219EC965-228A-1824-174D-96449D05F88A}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"celt\", \"celt.vcxproj\", \"{245603E3-F580-41A5-9632-B25FE3372CBF}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"opus_demo\", \"opus_demo.vcxproj\", \"{016C739D-6389-43BF-8D88-24B2BF6F620F}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{219EC965-228A-1824-174D-96449D05F88A} = {219EC965-228A-1824-174D-96449D05F88A}\n\t\t{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782} = {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}\n\t\t{245603E3-F580-41A5-9632-B25FE3372CBF} = {245603E3-F580-41A5-9632-B25FE3372CBF}\n\t\t{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16} = {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"test_opus_api\", \"test_opus_api.vcxproj\", \"{1D257A17-D254-42E5-82D6-1C87A6EC775A}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{219EC965-228A-1824-174D-96449D05F88A} = {219EC965-228A-1824-174D-96449D05F88A}\n\t\t{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782} = {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}\n\t\t{245603E3-F580-41A5-9632-B25FE3372CBF} = {245603E3-F580-41A5-9632-B25FE3372CBF}\n\t\t{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16} = {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"test_opus_decode\", \"test_opus_decode.vcxproj\", \"{8578322A-1883-486B-B6FA-E0094B65C9F2}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{219EC965-228A-1824-174D-96449D05F88A} = {219EC965-228A-1824-174D-96449D05F88A}\n\t\t{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782} = {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}\n\t\t{245603E3-F580-41A5-9632-B25FE3372CBF} = {245603E3-F580-41A5-9632-B25FE3372CBF}\n\t\t{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16} = {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"test_opus_encode\", \"test_opus_encode.vcxproj\", \"{84DAA768-1A38-4312-BB61-4C78BB59E5B8}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{219EC965-228A-1824-174D-96449D05F88A} = {219EC965-228A-1824-174D-96449D05F88A}\n\t\t{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782} = {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}\n\t\t{245603E3-F580-41A5-9632-B25FE3372CBF} = {245603E3-F580-41A5-9632-B25FE3372CBF}\n\t\t{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16} = {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"silk_float\", \"silk_float.vcxproj\", \"{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"silk_common\", \"silk_common.vcxproj\", \"{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"silk_fixed\", \"silk_fixed.vcxproj\", \"{8484C90D-1561-402F-A91D-2DB10F8C5171}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Win32 = Debug|Win32\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|Win32 = Release|Win32\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{219EC965-228A-1824-174D-96449D05F88A}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{219EC965-228A-1824-174D-96449D05F88A}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{219EC965-228A-1824-174D-96449D05F88A}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{219EC965-228A-1824-174D-96449D05F88A}.Debug|x64.Build.0 = Debug|x64\n\t\t{219EC965-228A-1824-174D-96449D05F88A}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{219EC965-228A-1824-174D-96449D05F88A}.Release|Win32.Build.0 = Release|Win32\n\t\t{219EC965-228A-1824-174D-96449D05F88A}.Release|x64.ActiveCfg = Release|x64\n\t\t{219EC965-228A-1824-174D-96449D05F88A}.Release|x64.Build.0 = Release|x64\n\t\t{245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|x64.Build.0 = Debug|x64\n\t\t{245603E3-F580-41A5-9632-B25FE3372CBF}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{245603E3-F580-41A5-9632-B25FE3372CBF}.Release|Win32.Build.0 = Release|Win32\n\t\t{245603E3-F580-41A5-9632-B25FE3372CBF}.Release|x64.ActiveCfg = Release|x64\n\t\t{245603E3-F580-41A5-9632-B25FE3372CBF}.Release|x64.Build.0 = Release|x64\n\t\t{016C739D-6389-43BF-8D88-24B2BF6F620F}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{016C739D-6389-43BF-8D88-24B2BF6F620F}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{016C739D-6389-43BF-8D88-24B2BF6F620F}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{016C739D-6389-43BF-8D88-24B2BF6F620F}.Debug|x64.Build.0 = Debug|x64\n\t\t{016C739D-6389-43BF-8D88-24B2BF6F620F}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{016C739D-6389-43BF-8D88-24B2BF6F620F}.Release|Win32.Build.0 = Release|Win32\n\t\t{016C739D-6389-43BF-8D88-24B2BF6F620F}.Release|x64.ActiveCfg = Release|x64\n\t\t{016C739D-6389-43BF-8D88-24B2BF6F620F}.Release|x64.Build.0 = Release|x64\n\t\t{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Debug|x64.Build.0 = Debug|x64\n\t\t{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Release|Win32.Build.0 = Release|Win32\n\t\t{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Release|x64.ActiveCfg = Release|x64\n\t\t{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Release|x64.Build.0 = Release|x64\n\t\t{8578322A-1883-486B-B6FA-E0094B65C9F2}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{8578322A-1883-486B-B6FA-E0094B65C9F2}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{8578322A-1883-486B-B6FA-E0094B65C9F2}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{8578322A-1883-486B-B6FA-E0094B65C9F2}.Debug|x64.Build.0 = Debug|x64\n\t\t{8578322A-1883-486B-B6FA-E0094B65C9F2}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{8578322A-1883-486B-B6FA-E0094B65C9F2}.Release|Win32.Build.0 = Release|Win32\n\t\t{8578322A-1883-486B-B6FA-E0094B65C9F2}.Release|x64.ActiveCfg = Release|x64\n\t\t{8578322A-1883-486B-B6FA-E0094B65C9F2}.Release|x64.Build.0 = Release|x64\n\t\t{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Debug|x64.Build.0 = Debug|x64\n\t\t{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Release|Win32.Build.0 = Release|Win32\n\t\t{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Release|x64.ActiveCfg = Release|x64\n\t\t{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Release|x64.Build.0 = Release|x64\n\t\t{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|x64.Build.0 = Debug|x64\n\t\t{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|Win32.Build.0 = Release|Win32\n\t\t{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|x64.ActiveCfg = Release|x64\n\t\t{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|x64.Build.0 = Release|x64\n\t\t{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|x64.Build.0 = Debug|x64\n\t\t{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|Win32.Build.0 = Release|Win32\n\t\t{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|x64.ActiveCfg = Release|x64\n\t\t{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|x64.Build.0 = Release|x64\n\t\t{8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|x64.Build.0 = Debug|x64\n\t\t{8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|Win32.Build.0 = Release|Win32\n\t\t{8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|x64.ActiveCfg = Release|x64\n\t\t{8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/opus.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <Keyword>Win32Proj</Keyword>\n    <ProjectName>opus</ProjectName>\n    <ProjectGuid>{219EC965-228A-1824-174D-96449D05F88A}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildBeforeTargets>\n    </CustomBuildBeforeTargets>\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../../silk;../../celt;../../win32;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Disabled</Optimization>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <TargetMachine>MachineX86</TargetMachine>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <AdditionalLibraryDirectories>$(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../../silk;../../celt;../../win32;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Disabled</Optimization>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <AdditionalLibraryDirectories>$(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../../silk;../../celt;../../win32;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <TargetMachine>MachineX86</TargetMachine>\n      <GenerateDebugInformation>false</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <LinkStatus>false</LinkStatus>\n    </Link>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../../silk;../../celt;../../win32;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>false</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <LinkStatus>false</LinkStatus>\n    </Link>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\celt\\arch.h\" />\n    <ClInclude Include=\"..\\..\\celt\\celt.h\" />\n    <ClInclude Include=\"..\\..\\celt\\entdec.h\" />\n    <ClInclude Include=\"..\\..\\celt\\entenc.h\" />\n    <ClInclude Include=\"..\\..\\celt\\float_cast.h\" />\n    <ClInclude Include=\"..\\..\\celt\\os_support.h\" />\n    <ClInclude Include=\"..\\..\\celt\\stack_alloc.h\" />\n    <ClInclude Include=\"..\\..\\include\\opus.h\" />\n    <ClInclude Include=\"..\\..\\include\\opus_defines.h\" />\n    <ClInclude Include=\"..\\..\\include\\opus_types.h\" />\n    <ClInclude Include=\"..\\..\\include\\opus_multistream.h\" />\n    <ClInclude Include=\"..\\..\\win32\\config.h\" />\n    <ClInclude Include=\"..\\..\\src\\analysis.h\" />\n    <ClInclude Include=\"..\\..\\src\\mlp.h\" />\n    <ClInclude Include=\"..\\..\\src\\opus_private.h\" />\n    <ClInclude Include=\"..\\..\\src\\tansig_table.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\src\\analysis.c\" />\n    <ClCompile Include=\"..\\..\\src\\mlp.c\" />\n    <ClCompile Include=\"..\\..\\src\\mlp_data.c\" />\n    <ClCompile Include=\"..\\..\\src\\opus.c\" />\n    <ClCompile Include=\"..\\..\\src\\opus_compare.c\" />\n    <ClCompile Include=\"..\\..\\src\\opus_decoder.c\" />\n    <ClCompile Include=\"..\\..\\src\\opus_encoder.c\" />\n    <ClCompile Include=\"..\\..\\src\\opus_multistream.c\" />\n    <ClCompile Include=\"..\\..\\src\\opus_multistream_decoder.c\" />\n    <ClCompile Include=\"..\\..\\src\\opus_multistream_encoder.c\" />\n    <ClCompile Include=\"..\\..\\src\\repacketizer.c\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/opus.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\celt\\arch.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\celt.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\entdec.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\entenc.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\float_cast.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\os_support.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\celt\\stack_alloc.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\include\\opus.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\include\\opus_defines.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\include\\opus_types.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\include\\opus_multistream.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\win32\\config.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\src\\analysis.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\src\\mlp.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\src\\opus_private.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\src\\tansig_table.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\src\\opus.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\src\\opus_compare.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\src\\opus_decoder.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\src\\opus_encoder.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\src\\opus_multistream.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\src\\opus_multistream_decoder.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\src\\opus_multistream_encoder.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\src\\repacketizer.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\src\\analysis.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\src\\mlp.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\src\\mlp_data.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/opus_demo.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"celt.vcxproj\">\n      <Project>{245603e3-f580-41a5-9632-b25fe3372cbf}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"opus.vcxproj\">\n      <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"silk_common.vcxproj\">\n      <Project>{c303d2fc-ff97-49b8-9ddd-467b4c9a0b16}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"silk_float.vcxproj\">\n      <Project>{9c4961d2-5ddb-40c7-9be8-ca918dc4e782}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\src\\opus_demo.c\" />\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{016C739D-6389-43BF-8D88-24B2BF6F620F}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>opus_demo</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/opus_demo.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\src\\opus_demo.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/silk_common.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>src_common</RootNamespace>\n    <ProjectName>silk_common</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <CustomBuildBeforeTargets>\n    </CustomBuildBeforeTargets>\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk/float;../../silk;../../win32;../../celt;../../include</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk/float;../../silk;../../win32;../../celt;../../include</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk/float;../../silk;../../win32;../../celt;../../include</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <FloatingPointModel>Fast</FloatingPointModel>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk/float;../../silk;../../win32;../../celt;../../include</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <FloatingPointModel>Fast</FloatingPointModel>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\include\\opus_types.h\" />\n    <ClInclude Include=\"..\\..\\silk\\x86\\main_sse.h\" />\n    <ClInclude Include=\"..\\..\\silk\\x86\\SigProc_FIX_sse.h\" />\n    <ClInclude Include=\"..\\..\\win32\\config.h\" />\n    <ClInclude Include=\"..\\..\\silk\\control.h\" />\n    <ClInclude Include=\"..\\..\\silk\\debug.h\" />\n    <ClInclude Include=\"..\\..\\silk\\define.h\" />\n    <ClInclude Include=\"..\\..\\silk\\errors.h\" />\n    <ClInclude Include=\"..\\..\\silk\\Inlines.h\" />\n    <ClInclude Include=\"..\\..\\silk\\MacroCount.h\" />\n    <ClInclude Include=\"..\\..\\silk\\MacroDebug.h\" />\n    <ClInclude Include=\"..\\..\\silk\\macros.h\" />\n    <ClInclude Include=\"..\\..\\silk\\main.h\" />\n    <ClInclude Include=\"..\\..\\silk\\pitch_est_defines.h\" />\n    <ClInclude Include=\"..\\..\\silk\\PLC.h\" />\n    <ClInclude Include=\"..\\..\\silk\\resampler_private.h\" />\n    <ClInclude Include=\"..\\..\\silk\\resampler_rom.h\" />\n    <ClInclude Include=\"..\\..\\silk\\resampler_structs.h\" />\n    <ClInclude Include=\"..\\..\\silk\\API.h\" />\n    <ClInclude Include=\"..\\..\\silk\\SigProc_FIX.h\" />\n    <ClInclude Include=\"..\\..\\silk\\structs.h\" />\n    <ClInclude Include=\"..\\..\\silk\\tables.h\" />\n    <ClInclude Include=\"..\\..\\silk\\tuning_parameters.h\" />\n    <ClInclude Include=\"..\\..\\silk\\typedef.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\silk\\A2NLSF.c\" />\n    <ClCompile Include=\"..\\..\\silk\\ana_filt_bank_1.c\" />\n    <ClCompile Include=\"..\\..\\silk\\biquad_alt.c\" />\n    <ClCompile Include=\"..\\..\\silk\\bwexpander.c\" />\n    <ClCompile Include=\"..\\..\\silk\\bwexpander_32.c\" />\n    <ClCompile Include=\"..\\..\\silk\\check_control_input.c\" />\n    <ClCompile Include=\"..\\..\\silk\\CNG.c\" />\n    <ClCompile Include=\"..\\..\\silk\\code_signs.c\" />\n    <ClCompile Include=\"..\\..\\silk\\control_audio_bandwidth.c\" />\n    <ClCompile Include=\"..\\..\\silk\\control_codec.c\" />\n    <ClCompile Include=\"..\\..\\silk\\control_SNR.c\" />\n    <ClCompile Include=\"..\\..\\silk\\debug.c\" />\n    <ClCompile Include=\"..\\..\\silk\\decoder_set_fs.c\" />\n    <ClCompile Include=\"..\\..\\silk\\decode_core.c\" />\n    <ClCompile Include=\"..\\..\\silk\\decode_frame.c\" />\n    <ClCompile Include=\"..\\..\\silk\\decode_indices.c\" />\n    <ClCompile Include=\"..\\..\\silk\\decode_parameters.c\" />\n    <ClCompile Include=\"..\\..\\silk\\decode_pitch.c\" />\n    <ClCompile Include=\"..\\..\\silk\\decode_pulses.c\" />\n    <ClCompile Include=\"..\\..\\silk\\dec_API.c\" />\n    <ClCompile Include=\"..\\..\\silk\\encode_indices.c\" />\n    <ClCompile Include=\"..\\..\\silk\\encode_pulses.c\" />\n    <ClCompile Include=\"..\\..\\silk\\enc_API.c\" />\n    <ClCompile Include=\"..\\..\\silk\\gain_quant.c\" />\n    <ClCompile Include=\"..\\..\\silk\\HP_variable_cutoff.c\" />\n    <ClCompile Include=\"..\\..\\silk\\init_decoder.c\" />\n    <ClCompile Include=\"..\\..\\silk\\init_encoder.c\" />\n    <ClCompile Include=\"..\\..\\silk\\inner_prod_aligned.c\" />\n    <ClCompile Include=\"..\\..\\silk\\interpolate.c\" />\n    <ClCompile Include=\"..\\..\\silk\\lin2log.c\" />\n    <ClCompile Include=\"..\\..\\silk\\log2lin.c\" />\n    <ClCompile Include=\"..\\..\\silk\\LPC_analysis_filter.c\" />\n    <ClCompile Include=\"..\\..\\silk\\LPC_inv_pred_gain.c\" />\n    <ClCompile Include=\"..\\..\\silk\\LP_variable_cutoff.c\" />\n    <ClCompile Include=\"..\\..\\silk\\NLSF2A.c\" />\n    <ClCompile Include=\"..\\..\\silk\\NLSF_decode.c\" />\n    <ClCompile Include=\"..\\..\\silk\\NLSF_del_dec_quant.c\" />\n    <ClCompile Include=\"..\\..\\silk\\NLSF_encode.c\" />\n    <ClCompile Include=\"..\\..\\silk\\NLSF_stabilize.c\" />\n    <ClCompile Include=\"..\\..\\silk\\NLSF_unpack.c\" />\n    <ClCompile Include=\"..\\..\\silk\\NLSF_VQ.c\" />\n    <ClCompile Include=\"..\\..\\silk\\NLSF_VQ_weights_laroia.c\" />\n    <ClCompile Include=\"..\\..\\silk\\NSQ.c\" />\n    <ClCompile Include=\"..\\..\\silk\\NSQ_del_dec.c\" />\n    <ClCompile Include=\"..\\..\\silk\\pitch_est_tables.c\" />\n    <ClCompile Include=\"..\\..\\silk\\PLC.c\" />\n    <ClCompile Include=\"..\\..\\silk\\process_NLSFs.c\" />\n    <ClCompile Include=\"..\\..\\silk\\quant_LTP_gains.c\" />\n    <ClCompile Include=\"..\\..\\silk\\resampler.c\" />\n    <ClCompile Include=\"..\\..\\silk\\resampler_down2.c\" />\n    <ClCompile Include=\"..\\..\\silk\\resampler_down2_3.c\" />\n    <ClCompile Include=\"..\\..\\silk\\resampler_private_AR2.c\" />\n    <ClCompile Include=\"..\\..\\silk\\resampler_private_down_FIR.c\" />\n    <ClCompile Include=\"..\\..\\silk\\resampler_private_IIR_FIR.c\" />\n    <ClCompile Include=\"..\\..\\silk\\resampler_private_up2_HQ.c\" />\n    <ClCompile Include=\"..\\..\\silk\\resampler_rom.c\" />\n    <ClCompile Include=\"..\\..\\silk\\shell_coder.c\" />\n    <ClCompile Include=\"..\\..\\silk\\sigm_Q15.c\" />\n    <ClCompile Include=\"..\\..\\silk\\sort.c\" />\n    <ClCompile Include=\"..\\..\\silk\\stereo_decode_pred.c\" />\n    <ClCompile Include=\"..\\..\\silk\\stereo_encode_pred.c\" />\n    <ClCompile Include=\"..\\..\\silk\\stereo_find_predictor.c\" />\n    <ClCompile Include=\"..\\..\\silk\\stereo_LR_to_MS.c\" />\n    <ClCompile Include=\"..\\..\\silk\\stereo_MS_to_LR.c\" />\n    <ClCompile Include=\"..\\..\\silk\\stereo_quant_pred.c\" />\n    <ClCompile Include=\"..\\..\\silk\\sum_sqr_shift.c\" />\n    <ClCompile Include=\"..\\..\\silk\\tables_gain.c\" />\n    <ClCompile Include=\"..\\..\\silk\\tables_LTP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\tables_NLSF_CB_NB_MB.c\" />\n    <ClCompile Include=\"..\\..\\silk\\tables_NLSF_CB_WB.c\" />\n    <ClCompile Include=\"..\\..\\silk\\tables_other.c\" />\n    <ClCompile Include=\"..\\..\\silk\\tables_pitch_lag.c\" />\n    <ClCompile Include=\"..\\..\\silk\\tables_pulses_per_block.c\" />\n    <ClCompile Include=\"..\\..\\silk\\table_LSF_cos.c\" />\n    <ClCompile Include=\"..\\..\\silk\\VAD.c\" />\n    <ClCompile Include=\"..\\..\\silk\\VQ_WMat_EC.c\" />\n    <ClCompile Include=\"..\\..\\silk\\x86\\NSQ_del_dec_sse.c\" />\n    <ClCompile Include=\"..\\..\\silk\\x86\\NSQ_sse.c\" />\n    <ClCompile Include=\"..\\..\\silk\\x86\\VAD_sse.c\" />\n    <ClCompile Include=\"..\\..\\silk\\x86\\VQ_WMat_EC_sse.c\" />\n    <ClCompile Include=\"..\\..\\silk\\x86\\x86_silk_map.c\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/silk_common.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\include\\opus_types.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\win32\\config.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\control.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\debug.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\define.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\errors.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\Inlines.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\MacroCount.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\MacroDebug.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\macros.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\main.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\pitch_est_defines.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\PLC.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\resampler_private.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\resampler_rom.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\resampler_structs.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\API.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\SigProc_FIX.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\structs.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\tables.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\tuning_parameters.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\typedef.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\x86\\main_sse.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\x86\\SigProc_FIX_sse.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\silk\\VQ_WMat_EC.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\A2NLSF.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\ana_filt_bank_1.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\biquad_alt.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\bwexpander.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\bwexpander_32.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\check_control_input.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\CNG.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\code_signs.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\control_audio_bandwidth.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\control_codec.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\control_SNR.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\debug.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\dec_API.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\decode_core.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\decode_frame.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\decode_indices.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\decode_parameters.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\decode_pitch.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\decode_pulses.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\decoder_set_fs.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\enc_API.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\encode_indices.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\encode_pulses.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\gain_quant.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\HP_variable_cutoff.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\init_decoder.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\init_encoder.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\inner_prod_aligned.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\interpolate.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\lin2log.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\log2lin.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\LP_variable_cutoff.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\LPC_analysis_filter.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\LPC_inv_pred_gain.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\NLSF_decode.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\NLSF_del_dec_quant.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\NLSF_encode.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\NLSF_stabilize.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\NLSF_unpack.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\NLSF_VQ.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\NLSF_VQ_weights_laroia.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\NLSF2A.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\NSQ.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\NSQ_del_dec.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\pitch_est_tables.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\PLC.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\process_NLSFs.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\quant_LTP_gains.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\resampler.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\resampler_down2.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\resampler_down2_3.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\resampler_private_AR2.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\resampler_private_down_FIR.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\resampler_private_IIR_FIR.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\resampler_private_up2_HQ.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\resampler_rom.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\shell_coder.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\sigm_Q15.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\sort.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\stereo_decode_pred.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\stereo_encode_pred.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\stereo_find_predictor.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\stereo_LR_to_MS.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\stereo_MS_to_LR.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\stereo_quant_pred.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\sum_sqr_shift.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\table_LSF_cos.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\tables_gain.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\tables_LTP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\tables_NLSF_CB_NB_MB.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\tables_NLSF_CB_WB.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\tables_other.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\tables_pitch_lag.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\tables_pulses_per_block.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\VAD.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\x86\\NSQ_del_dec_sse.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\x86\\NSQ_sse.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\x86\\VAD_sse.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\x86\\VQ_WMat_EC_sse.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\x86\\x86_silk_map.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/silk_fixed.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{8484C90D-1561-402F-A91D-2DB10F8C5171}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>src_FIX</RootNamespace>\n    <ProjectName>silk_fixed</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\include\\opus_types.h\" />\n    <ClInclude Include=\"..\\..\\win32\\config.h\" />\n    <ClInclude Include=\"..\\..\\silk\\SigProc_FIX.h\" />\n    <ClInclude Include=\"..\\..\\silk\\fixed\\main_FIX.h\" />\n    <ClInclude Include=\"..\\..\\silk\\fixed\\structs_FIX.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\apply_sine_window_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\autocorr_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\burg_modified_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\corrMatrix_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\encode_frame_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\find_LPC_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\find_LTP_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\find_pitch_lags_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\find_pred_coefs_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\k2a_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\k2a_Q16_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\LTP_analysis_filter_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\LTP_scale_ctrl_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\noise_shape_analysis_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\pitch_analysis_core_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\prefilter_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\process_gains_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\regularize_correlations_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\residual_energy16_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\residual_energy_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\schur64_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\schur_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\solve_LS_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\vector_ops_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\warped_autocorrelation_FIX.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\x86\\burg_modified_FIX_sse.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\x86\\prefilter_FIX_sse.c\" />\n    <ClCompile Include=\"..\\..\\silk\\fixed\\x86\\vector_ops_FIX_sse.c\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/silk_fixed.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\win32\\config.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\include\\opus_types.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\SigProc_FIX.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\fixed\\main_FIX.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\silk\\fixed\\structs_FIX.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\LTP_scale_ctrl_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\noise_shape_analysis_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\pitch_analysis_core_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\prefilter_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\process_gains_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\regularize_correlations_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\residual_energy_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\residual_energy16_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\schur_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\schur64_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\solve_LS_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\vector_ops_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\warped_autocorrelation_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\apply_sine_window_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\autocorr_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\burg_modified_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\corrMatrix_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\encode_frame_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\find_LPC_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\find_LTP_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\find_pitch_lags_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\find_pred_coefs_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\k2a_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\k2a_Q16_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\LTP_analysis_filter_FIX.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\x86\\burg_modified_FIX_sse.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\x86\\prefilter_FIX_sse.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\fixed\\x86\\vector_ops_FIX_sse.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/silk_float.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>src_FLP</RootNamespace>\n    <ProjectName>silk_float</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <CustomBuildBeforeTargets>Compile</CustomBuildBeforeTargets>\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../../silk/float;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../../silk/float;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../../silk/float;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>../../silk/float;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n    <PreBuildEvent>\n      <Command>\"$(ProjectDir)..\\..\\win32\\genversion.bat\" \"$(ProjectDir)..\\..\\win32\\version.h\" PACKAGE_VERSION</Command>\n      <Message>Generating version.h</Message>\n    </PreBuildEvent>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\include\\opus_types.h\" />\n    <ClInclude Include=\"..\\..\\win32\\config.h\" />\n    <ClInclude Include=\"..\\..\\silk\\float\\main_FLP.h\" />\n    <ClInclude Include=\"..\\..\\silk\\float\\SigProc_FLP.h\" />\n    <ClInclude Include=\"..\\..\\silk\\float\\structs_FLP.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\silk\\float\\apply_sine_window_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\autocorrelation_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\burg_modified_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\bwexpander_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\corrMatrix_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\encode_frame_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\energy_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\find_LPC_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\find_LTP_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\find_pitch_lags_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\find_pred_coefs_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\inner_product_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\k2a_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\levinsondurbin_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\LPC_analysis_filter_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\LPC_inv_pred_gain_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\LTP_analysis_filter_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\LTP_scale_ctrl_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\noise_shape_analysis_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\pitch_analysis_core_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\prefilter_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\process_gains_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\regularize_correlations_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\residual_energy_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\scale_copy_vector_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\scale_vector_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\schur_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\solve_LS_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\sort_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\warped_autocorrelation_FLP.c\" />\n    <ClCompile Include=\"..\\..\\silk\\float\\wrappers_FLP.c\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/silk_float.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\include\\opus_types.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\win32\\config.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"main_FLP.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"SigProc_FLP.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"structs_FLP.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\silk\\float\\scale_vector_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\schur_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\solve_LS_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\sort_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\warped_autocorrelation_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\wrappers_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\apply_sine_window_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\autocorrelation_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\burg_modified_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\bwexpander_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\corrMatrix_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\encode_frame_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\energy_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\find_LPC_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\find_LTP_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\find_pitch_lags_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\find_pred_coefs_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\inner_product_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\k2a_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\levinsondurbin_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\LPC_analysis_filter_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\LPC_inv_pred_gain_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\LTP_analysis_filter_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\LTP_scale_ctrl_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\noise_shape_analysis_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\pitch_analysis_core_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\prefilter_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\process_gains_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\regularize_correlations_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\residual_energy_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\silk\\float\\scale_copy_vector_FLP.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/test_opus_api.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\tests\\test_opus_api.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"celt.vcxproj\">\n      <Project>{245603e3-f580-41a5-9632-b25fe3372cbf}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"opus.vcxproj\">\n      <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"silk_common.vcxproj\">\n      <Project>{c303d2fc-ff97-49b8-9ddd-467b4c9a0b16}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"silk_float.vcxproj\">\n      <Project>{9c4961d2-5ddb-40c7-9be8-ca918dc4e782}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{1D257A17-D254-42E5-82D6-1C87A6EC775A}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>test_opus_api</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/test_opus_api.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\tests\\test_opus_api.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/test_opus_decode.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\tests\\test_opus_decode.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"celt.vcxproj\">\n      <Project>{245603e3-f580-41a5-9632-b25fe3372cbf}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"opus.vcxproj\">\n      <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"silk_common.vcxproj\">\n      <Project>{c303d2fc-ff97-49b8-9ddd-467b4c9a0b16}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"silk_float.vcxproj\">\n      <Project>{9c4961d2-5ddb-40c7-9be8-ca918dc4e782}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{8578322A-1883-486B-B6FA-E0094B65C9F2}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>test_opus_api</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/test_opus_decode.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4a0dd677-931f-4728-afe5-b761149fc7eb}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\tests\\test_opus_decode.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/test_opus_encode.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\tests\\test_opus_encode.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"celt.vcxproj\">\n      <Project>{245603e3-f580-41a5-9632-b25fe3372cbf}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"opus.vcxproj\">\n      <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"silk_common.vcxproj\">\n      <Project>{c303d2fc-ff97-49b8-9ddd-467b4c9a0b16}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"silk_float.vcxproj\">\n      <Project>{9c4961d2-5ddb-40c7-9be8-ca918dc4e782}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{84DAA768-1A38-4312-BB61-4C78BB59E5B8}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>test_opus_api</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)\\$(ProjectName)\\</IntDir>\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <AdditionalIncludeDirectories>..\\..\\silk;..\\..\\celt;..\\;..\\..\\include;</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>\n"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/VS2010/test_opus_encode.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{546c8d9a-103e-4f78-972b-b44e8d3c8aba}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\tests\\test_opus_encode.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "deps/pjsip/third_party/opus/win32/genversion.bat",
    "content": "@echo off\n\nsetlocal enableextensions enabledelayedexpansion\n\nfor /f %%v in ('git --git-dir=\"%~dp0..\\.git\" describe --tags --match \"v*\"') do set version=%%v\n\nif not \"%version%\"==\"\" goto :gotversion\n\nif exist \"%~dp0..\\version.mk\" goto :getversion\n\necho Git cannot be found, nor can version.mk. Generating unknown version.\n\nset version=unknown\n\ngoto :gotversion\n\n:getversion\n\nfor /f \"delims== tokens=2\" %%v in (%~dps0..\\version.mk) do set version=%%v\n\nset version=!version:^\"=!\nset version=!version: =!\n\n:gotversion\n\nset version_out=#define %~2 \"%version%\"\nset version_mk=%~2 = \"%version%\"\n\necho %version_out%> \"%~1_temp\"\n\nif %version%==unknown goto :skipgenerate\n\necho # static version string; update manually every release.> \"%~dp0..\\version.mk\"\necho %version_mk%>> \"%~dp0..\\version.mk\"\n\n:skipgenerate\n\necho n | comp \"%~1_temp\" \"%~1\" > NUL 2> NUL\n\nif not errorlevel 1 goto exit\n\ncopy /y \"%~1_temp\" \"%~1\"\n\n:exit\n\ndel \"%~1_temp\"\n"
  },
  {
    "path": "deps/pjsip/third_party/resample/COPYING",
    "content": "\n                  GNU LESSER GENERAL PUBLIC LICENSE\n                       Version 2.1, February 1999\n\n Copyright (C) 1991, 1999 Free Software Foundation, Inc.\n     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n[This is the first released version of the Lesser GPL.  It also counts\n as the successor of the GNU Library Public License, version 2, hence\n the version number 2.1.]\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicenses are intended to guarantee your freedom to share and change\nfree software--to make sure the software is free for all its users.\n\n  This license, the Lesser General Public License, applies to some\nspecially designated software packages--typically libraries--of the\nFree Software Foundation and other authors who decide to use it.  You\ncan use it too, but we suggest you first think carefully about whether\nthis license or the ordinary General Public License is the better\nstrategy to use in any particular case, based on the explanations\nbelow.\n\n  When we speak of free software, we are referring to freedom of use,\nnot price.  Our General Public Licenses are designed to make sure that\nyou have the freedom to distribute copies of free software (and charge\nfor this service if you wish); that you receive source code or can get\nit if you want it; that you can change the software and use pieces of\nit in new free programs; and that you are informed that you can do\nthese things.\n\n  To protect your rights, we need to make restrictions that forbid\ndistributors to deny you these rights or to ask you to surrender these\nrights.  These restrictions translate to certain responsibilities for\nyou if you distribute copies of the library or if you modify it.\n\n  For example, if you distribute copies of the library, whether gratis\nor for a fee, you must give the recipients all the rights that we gave\nyou.  You must make sure that they, too, receive or can get the source\ncode.  If you link other code with the library, you must provide\ncomplete object files to the recipients, so that they can relink them\nwith the library after making changes to the library and recompiling\nit.  And you must show them these terms so they know their rights.\n\n  We protect your rights with a two-step method: (1) we copyright the\nlibrary, and (2) we offer you this license, which gives you legal\npermission to copy, distribute and/or modify the library.\n\n  To protect each distributor, we want to make it very clear that\nthere is no warranty for the free library.  Also, if the library is\nmodified by someone else and passed on, the recipients should know\nthat what they have is not the original version, so that the original\nauthor's reputation will not be affected by problems that might be\nintroduced by others.\n\n  Finally, software patents pose a constant threat to the existence of\nany free program.  We wish to make sure that a company cannot\neffectively restrict the users of a free program by obtaining a\nrestrictive license from a patent holder.  Therefore, we insist that\nany patent license obtained for a version of the library must be\nconsistent with the full freedom of use specified in this license.\n\n  Most GNU software, including some libraries, is covered by the\nordinary GNU General Public License.  This license, the GNU Lesser\nGeneral Public License, applies to certain designated libraries, and\nis quite different from the ordinary General Public License.  We use\nthis license for certain libraries in order to permit linking those\nlibraries into non-free programs.\n\n  When a program is linked with a library, whether statically or using\na shared library, the combination of the two is legally speaking a\ncombined work, a derivative of the original library.  The ordinary\nGeneral Public License therefore permits such linking only if the\nentire combination fits its criteria of freedom.  The Lesser General\nPublic License permits more lax criteria for linking other code with\nthe library.\n\n  We call this license the \"Lesser\" General Public License because it\ndoes Less to protect the user's freedom than the ordinary General\nPublic License.  It also provides other free software developers Less\nof an advantage over competing non-free programs.  These disadvantages\nare the reason we use the ordinary General Public License for many\nlibraries.  However, the Lesser license provides advantages in certain\nspecial circumstances.\n\n  For example, on rare occasions, there may be a special need to\nencourage the widest possible use of a certain library, so that it becomes\na de-facto standard.  To achieve this, non-free programs must be\nallowed to use the library.  A more frequent case is that a free\nlibrary does the same job as widely used non-free libraries.  In this\ncase, there is little to gain by limiting the free library to free\nsoftware only, so we use the Lesser General Public License.\n\n  In other cases, permission to use a particular library in non-free\nprograms enables a greater number of people to use a large body of\nfree software.  For example, permission to use the GNU C Library in\nnon-free programs enables many more people to use the whole GNU\noperating system, as well as its variant, the GNU/Linux operating\nsystem.\n\n  Although the Lesser General Public License is Less protective of the\nusers' freedom, it does ensure that the user of a program that is\nlinked with the Library has the freedom and the wherewithal to run\nthat program using a modified version of the Library.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.  Pay close attention to the difference between a\n\"work based on the library\" and a \"work that uses the library\".  The\nformer contains code derived from the library, whereas the latter must\nbe combined with the library in order to run.\n\n                  GNU LESSER GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License Agreement applies to any software library or other\nprogram which contains a notice placed by the copyright holder or\nother authorized party saying it may be distributed under the terms of\nthis Lesser General Public License (also called \"this License\").\nEach licensee is addressed as \"you\".\n\n  A \"library\" means a collection of software functions and/or data\nprepared so as to be conveniently linked with application programs\n(which use some of those functions and data) to form executables.\n\n  The \"Library\", below, refers to any such software library or work\nwhich has been distributed under these terms.  A \"work based on the\nLibrary\" means either the Library or any derivative work under\ncopyright law: that is to say, a work containing the Library or a\nportion of it, either verbatim or with modifications and/or translated\nstraightforwardly into another language.  (Hereinafter, translation is\nincluded without limitation in the term \"modification\".)\n\n  \"Source code\" for a work means the preferred form of the work for\nmaking modifications to it.  For a library, complete source code means\nall the source code for all modules it contains, plus any associated\ninterface definition files, plus the scripts used to control\ncompilation\nand installation of the library.\n\n  Activities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning a program using the Library is not restricted, and output from\nsuch a program is covered only if its contents constitute a work based\non the Library (independent of the use of the Library in a tool for\nwriting it).  Whether that is true depends on what the Library does\nand what the program that uses the Library does.\n\n  1. You may copy and distribute verbatim copies of the Library's\ncomplete source code as you receive it, in any medium, provided that\nyou conspicuously and appropriately publish on each copy an\nappropriate copyright notice and disclaimer of warranty; keep intact\nall the notices that refer to this License and to the absence of any\nwarranty; and distribute a copy of this License along with the\nLibrary.\n\n  You may charge a fee for the physical act of transferring a copy,\nand you may at your option offer warranty protection in exchange for a\nfee.\n\n  2. You may modify your copy or copies of the Library or any portion\nof it, thus forming a work based on the Library, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) The modified work must itself be a software library.\n\n    b) You must cause the files modified to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    c) You must cause the whole of the work to be licensed at no\n    charge to all third parties under the terms of this License.\n\n    d) If a facility in the modified Library refers to a function or a\n    table of data to be supplied by an application program that uses\n    the facility, other than as an argument passed when the facility\n    is invoked, then you must make a good faith effort to ensure that,\n    in the event an application does not supply such function or\n    table, the facility still operates, and performs whatever part of\n    its purpose remains meaningful.\n\n    (For example, a function in a library to compute square roots has\n    a purpose that is entirely well-defined independent of the\n    application.  Therefore, Subsection 2d requires that any\n    application-supplied function or table used by this function must\n    be optional: if the application does not supply it, the square\n    root function must still compute square roots.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Library,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Library, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote\nit.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Library.\n\nIn addition, mere aggregation of another work not based on the Library\nwith the Library (or with a work based on the Library) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may opt to apply the terms of the ordinary GNU General Public\nLicense instead of this License to a given copy of the Library.  To do\nthis, you must alter all the notices that refer to this License, so\nthat they refer to the ordinary GNU General Public License, version 2,\ninstead of to this License.  (If a newer version than version 2 of the\nordinary GNU General Public License has appeared, then you can specify\nthat version instead if you wish.)  Do not make any other change in\nthese notices.\n\n  Once this change is made in a given copy, it is irreversible for\nthat copy, so the ordinary GNU General Public License applies to all\nsubsequent copies and derivative works made from that copy.\n\n  This option is useful when you wish to copy part of the code of\nthe Library into a program that is not a library.\n\n  4. You may copy and distribute the Library (or a portion or\nderivative of it, under Section 2) in object code or executable form\nunder the terms of Sections 1 and 2 above provided that you accompany\nit with the complete corresponding machine-readable source code, which\nmust be distributed under the terms of Sections 1 and 2 above on a\nmedium customarily used for software interchange.\n\n  If distribution of object code is made by offering access to copy\nfrom a designated place, then offering equivalent access to copy the\nsource code from the same place satisfies the requirement to\ndistribute the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  5. A program that contains no derivative of any portion of the\nLibrary, but is designed to work with the Library by being compiled or\nlinked with it, is called a \"work that uses the Library\".  Such a\nwork, in isolation, is not a derivative work of the Library, and\ntherefore falls outside the scope of this License.\n\n  However, linking a \"work that uses the Library\" with the Library\ncreates an executable that is a derivative of the Library (because it\ncontains portions of the Library), rather than a \"work that uses the\nlibrary\".  The executable is therefore covered by this License.\nSection 6 states terms for distribution of such executables.\n\n  When a \"work that uses the Library\" uses material from a header file\nthat is part of the Library, the object code for the work may be a\nderivative work of the Library even though the source code is not.\nWhether this is true is especially significant if the work can be\nlinked without the Library, or if the work is itself a library.  The\nthreshold for this to be true is not precisely defined by law.\n\n  If such an object file uses only numerical parameters, data\nstructure layouts and accessors, and small macros and small inline\nfunctions (ten lines or less in length), then the use of the object\nfile is unrestricted, regardless of whether it is legally a derivative\nwork.  (Executables containing this object code plus portions of the\nLibrary will still fall under Section 6.)\n\n  Otherwise, if the work is a derivative of the Library, you may\ndistribute the object code for the work under the terms of Section 6.\nAny executables containing that work also fall under Section 6,\nwhether or not they are linked directly with the Library itself.\n\n  6. As an exception to the Sections above, you may also combine or\nlink a \"work that uses the Library\" with the Library to produce a\nwork containing portions of the Library, and distribute that work\nunder terms of your choice, provided that the terms permit\nmodification of the work for the customer's own use and reverse\nengineering for debugging such modifications.\n\n  You must give prominent notice with each copy of the work that the\nLibrary is used in it and that the Library and its use are covered by\nthis License.  You must supply a copy of this License.  If the work\nduring execution displays copyright notices, you must include the\ncopyright notice for the Library among them, as well as a reference\ndirecting the user to the copy of this License.  Also, you must do one\nof these things:\n\n    a) Accompany the work with the complete corresponding\n    machine-readable source code for the Library including whatever\n    changes were used in the work (which must be distributed under\n    Sections 1 and 2 above); and, if the work is an executable linked\n    with the Library, with the complete machine-readable \"work that\n    uses the Library\", as object code and/or source code, so that the\n    user can modify the Library and then relink to produce a modified\n    executable containing the modified Library.  (It is understood\n    that the user who changes the contents of definitions files in the\n    Library will not necessarily be able to recompile the application\n    to use the modified definitions.)\n\n    b) Use a suitable shared library mechanism for linking with the\n    Library.  A suitable mechanism is one that (1) uses at run time a\n    copy of the library already present on the user's computer system,\n    rather than copying library functions into the executable, and (2)\n    will operate properly with a modified version of the library, if\n    the user installs one, as long as the modified version is\n    interface-compatible with the version that the work was made with.\n\n    c) Accompany the work with a written offer, valid for at\n    least three years, to give the same user the materials\n    specified in Subsection 6a, above, for a charge no more\n    than the cost of performing this distribution.\n\n    d) If distribution of the work is made by offering access to copy\n    from a designated place, offer equivalent access to copy the above\n    specified materials from the same place.\n\n    e) Verify that the user has already received a copy of these\n    materials or that you have already sent this user a copy.\n\n  For an executable, the required form of the \"work that uses the\nLibrary\" must include any data and utility programs needed for\nreproducing the executable from it.  However, as a special exception,\nthe materials to be distributed need not include anything that is\nnormally distributed (in either source or binary form) with the major\ncomponents (compiler, kernel, and so on) of the operating system on\nwhich the executable runs, unless that component itself accompanies\nthe executable.\n\n  It may happen that this requirement contradicts the license\nrestrictions of other proprietary libraries that do not normally\naccompany the operating system.  Such a contradiction means you cannot\nuse both them and the Library together in an executable that you\ndistribute.\n\n  7. You may place library facilities that are a work based on the\nLibrary side-by-side in a single library together with other library\nfacilities not covered by this License, and distribute such a combined\nlibrary, provided that the separate distribution of the work based on\nthe Library and of the other library facilities is otherwise\npermitted, and provided that you do these two things:\n\n    a) Accompany the combined library with a copy of the same work\n    based on the Library, uncombined with any other library\n    facilities.  This must be distributed under the terms of the\n    Sections above.\n\n    b) Give prominent notice with the combined library of the fact\n    that part of it is a work based on the Library, and explaining\n    where to find the accompanying uncombined form of the same work.\n\n  8. You may not copy, modify, sublicense, link with, or distribute\nthe Library except as expressly provided under this License.  Any\nattempt otherwise to copy, modify, sublicense, link with, or\ndistribute the Library is void, and will automatically terminate your\nrights under this License.  However, parties who have received copies,\nor rights, from you under this License will not have their licenses\nterminated so long as such parties remain in full compliance.\n\n  9. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Library or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Library (or any work based on the\nLibrary), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Library or works based on it.\n\n  10. Each time you redistribute the Library (or any work based on the\nLibrary), the recipient automatically receives a license from the\noriginal licensor to copy, distribute, link with or modify the Library\nsubject to these terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties with\nthis License.\n\n  11. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Library at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Library by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Library.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply, and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  12. If the distribution and/or use of the Library is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Library under this License\nmay add an explicit geographical distribution limitation excluding those\ncountries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  13. The Free Software Foundation may publish revised and/or new\nversions of the Lesser General Public License from time to time.\nSuch new versions will be similar in spirit to the present version,\nbut may differ in detail to address new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Library\nspecifies a version number of this License which applies to it and\n\"any later version\", you have the option of following the terms and\nconditions either of that version or of any later version published by\nthe Free Software Foundation.  If the Library does not specify a\nlicense version number, you may choose any version ever published by\nthe Free Software Foundation.\n\n  14. If you wish to incorporate parts of the Library into other free\nprograms whose distribution conditions are incompatible with these,\nwrite to the author to ask for permission.  For software which is\ncopyrighted by the Free Software Foundation, write to the Free\nSoftware Foundation; we sometimes make exceptions for this.  Our\ndecision will be guided by the two goals of preserving the free status\nof all derivatives of our free software and of promoting the sharing\nand reuse of software generally.\n\n                            NO WARRANTY\n\n  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO\nWARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\nEXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\nOTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY\nKIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\nLIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME\nTHE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\nWRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\nAND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU\nFOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR\nCONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\nLIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\nRENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\nFAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF\nSUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n"
  },
  {
    "path": "deps/pjsip/third_party/resample/README.resample",
    "content": "README file for resample-1.x.tgz from the \nDigital Audio Resampling Home Page located at\nhttp://ccrma.stanford.edu/~jos/resample/.\n\nSOFTWARE FOR SAMPLING-RATE CONVERSION AND FIR DIGITAL FILTER DESIGN\n\nFor installation instructions, read the INSTALL file in this directory.\n\nThe resample program \"resamples\" a soundfile to change its sampling\nrate.  For example, it can be used to convert the sampling rate from\n48 kHz (used by DAT machines) to 44.1 kHz (the standard sampling rate\nfor Compact Discs).  The command line for this operation would look\nsomething like\n\n\tresample -by 0.91875 dat.snd cd.snd\n\nor, more simply,\n\n\tresample -to 44100 dat.snd cd.snd\n\nAny reasonable sampling rate can be converted to any other.\n\nThe windowfilter program designs Finite-Impulse-Response (FIR) digital\nfilters by the so-called \"window method.\"  In this method, the ideal\nimpulse response (a sinc function) is \"windowed\" by a Kaiser window (a\npopular window used in spectrum analysis). \n\nThe resample program uses 32-bit fixed-point arithmetic: 16-bits data\nand 16-bits coefficients.  The input soundfile must be 16-bit mono or\nstereo (interleaved) audio data.\n\nSNDLIB\n\nThe program uses elements of Bill Schottstaedt's sndlib sound file\nlibrary.  This means resample can read many different kinds of sound\nfile header (AIFF, WAV, NeXT, IRCAM, etc.).\n\nThe sndlib files used by resample are included in this directory to\nensure stability. The latest version of sndlib should be available as\n\n\tftp://ccrma-ftp.stanford.edu/pub/Lisp/sndlib.tar.gz\n\nSee sndlib.html in the sndlib distribution for documentation of SNDLIB.\n\nCONTENTS of ./src directory\n\nresample.c\tSampling-rate conversion program.\nresample.1\tManual page for resample. Try \"nroff -man resample.1\".\nresamplesubs.c\tSubroutines used by resample.\nresample.h\tConfiguration constants for the sampling rate converter.\nstdefs.h\tMachine-dependent definitions, useful constants and macros.\n\nwindowfilter.c\tProgram for designing FIR digital filters used by resample.\nwindowfilter.1\tManual page for windowfilter.\nfilterkit.c\tLibrary for filter design, application, and file management.\nfilterkit.h\tDeclarations (procedure prototypes) for the filterkit library.\n\nREADME\t\tThis file.\nREADME.deemph   A word about deemphasis filtering.\nLGPL            GNU Lesser General Public License (LGPL)\n\nSNDLIB files:\n    io.c\n    audio.c\n    headers.c\n    sound.c\n    sndlib.h\n    sndlib-strings.h\n\nCOPYING\n\nSNDLIB files are Copyright 2000 by Bill Schottstaedt <bil@ccrma.stanford.edu>.\n\nThe remaining files in this package, unless otherwise noted, are\nCopyright 1994-2006 by Julius O. Smith III <jos@ccrma.stanford.edu>,\nall rights reserved.  Permission to use and copy is granted subject to\nthe terms of the \"GNU Lesser General Public License\" (LGPL) as\npublished by the Free Software Foundation; either version 2.1 of the\nLicense, or any later version.  In addition, we request that a copy of\nany modified files be sent by email to jos@ccrma.stanford.edu so that\nwe may incorporate them into the CCRMA version.\n\n   This library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\nFILTERKIT CONTENTS\n\n\tLpFilter() - Calculates the filter coeffs for a Kaiser-windowed\n\t\tlow-pass filter with a given roll-off frequency.  These\n\t\tcoeffs are stored into a array of doubles.\n\n\twriteFilter() - Writes a filter to a file.\n\n\tmakeFilter() - A section of the original SAIL program.  Calls \n\t\tLpFilter() to create a filter, then scales the double\n\t\tcoeffs into a array of half words.\n\n\treadFilter() - Reads a filter from a file.\n\n\tFilterUp() - Applies a filter to a given sample when up-converting.\n\n\tFilterUD() - Applies a filter to a given sample when up- or down-\n\t\tconverting.  Both are repoductions of the original SAIL\n\t\tprogram.\n\n\tinitZerox() - Initialization routine for the zerox() function.  Must\n\t\tbe called before zerox() is called.  This routine loads\n\t\tthe correct filter so zerox() can use it.\n\n\tzerox() - Given a pointer into a sample, finds a zero-crossing on the\n\t\tinterval [pointer-1:pointer+2] by iteration.\n\n\tQuery() - Ask the user for a yes/no question with prompt, default, \n\t\tand optional help.\n\n\tGetUShort() - Ask the user for a unsigned short with prompt, default,\n\t\tand optional help.\n\n\tGetDouble() -  Ask the user for a double with prompt, default, and\n\t\toptional help.\n\n\tGetString() -  Ask the user for a string with prompt, default, and\n\t\toptional help.\n\n\nFILTER FILE FORMAT\n\n\tFile Name: \"F\" Nmult \"T\" Nhc \".filter\"\n\t\texample: \"F13T8.filter\" and \"F27T8.filter\"\n\n\tStructure of File:\n\t\t\"ScaleFactor\" LpScl\n\t\t\"Length\" Nwing\n\t\t\"Coeffs:\"\n\t\tImp[0]\n\t\tImp[1]\n\t\t  :\n\t\tImp[Nwing-1]\n\t\t\"Differences:\"\n\t\tImpD[0]\n\t\tImpD[1]\n\t\t  :\n\t\tImpD[Nwing-1]\n\t\tEOF\n\n\twhere:\tSomething enclosed in \"\" indicates specific characters in the file.\n\t\tNmult, Nwing, Imp[], and ImpD[] are variables (HWORD)\n\t\tNpc is a conversion constant.\n\t\tEOF is the end of the file.\n\n\tSee writeFilter() and readFilter() in \"filterkit.c\" for more details.\n\n"
  },
  {
    "path": "deps/pjsip/third_party/resample/include/resamplesubs.h",
    "content": "#ifndef __RESAMPLESUBS_H__\n#define __RESAMPLESUBS_H__\n\ntypedef char           RES_BOOL;\ntypedef short          RES_HWORD;\ntypedef int            RES_WORD;\ntypedef unsigned short RES_UHWORD;\ntypedef unsigned int   RES_UWORD;\n\n#ifdef _USRDLL\n#   define DECL(T)  __declspec(dllexport) T\n#else\n#   define DECL(T)  T\n#endif\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\nDECL(int) res_SrcLinear(const RES_HWORD X[], RES_HWORD Y[], \n\t\t        double pFactor, RES_UHWORD nx);\nDECL(int) res_Resample(const RES_HWORD X[], RES_HWORD Y[], double pFactor, \n\t\t       RES_UHWORD nx, RES_BOOL LargeF, RES_BOOL Interp);\nDECL(int) res_GetXOFF(double pFactor, RES_BOOL LargeF);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/resample/src/largefilter.h",
    "content": "/* Included by resamplesubs.c */\n#define LARGE_FILTER_NMULT ((RES_HWORD)65)\n#define LARGE_FILTER_SCALE 14746 /* Unity-gain scale factor */\n#define LARGE_FILTER_NWING 8192 /* Filter table length */\nstatic const RES_HWORD LARGE_FILTER_IMP[] /* Impulse response */ = {\n32767,\n32766,\n32764,\n32761,\n32756,\n32750,\n32743,\n32734,\n32724,\n32713,\n32700,\n32686,\n32671,\n32654,\n32636,\n32617,\n32596,\n32574,\n32551,\n32526,\n32500,\n32473,\n32445,\n32415,\n32383,\n32351,\n32317,\n32282,\n32246,\n32208,\n32169,\n32129,\n32087,\n32044,\n32000,\n31955,\n31908,\n31860,\n31811,\n31760,\n31708,\n31655,\n31601,\n31545,\n31489,\n31431,\n31371,\n31311,\n31249,\n31186,\n31122,\n31056,\n30990,\n30922,\n30853,\n30783,\n30711,\n30639,\n30565,\n30490,\n30414,\n30337,\n30258,\n30179,\n30098,\n30016,\n29933,\n29849,\n29764,\n29677,\n29590,\n29501,\n29411,\n29321,\n29229,\n29136,\n29042,\n28947,\n28851,\n28753,\n28655,\n28556,\n28456,\n28354,\n28252,\n28149,\n28044,\n27939,\n27833,\n27725,\n27617,\n27508,\n27398,\n27287,\n27175,\n27062,\n26948,\n26833,\n26717,\n26601,\n26483,\n26365,\n26246,\n26125,\n26005,\n25883,\n25760,\n25637,\n25512,\n25387,\n25261,\n25135,\n25007,\n24879,\n24750,\n24620,\n24490,\n24358,\n24226,\n24094,\n23960,\n23826,\n23691,\n23556,\n23420,\n23283,\n23146,\n23008,\n22869,\n22730,\n22590,\n22449,\n22308,\n22166,\n22024,\n21881,\n21738,\n21594,\n21449,\n21304,\n21159,\n21013,\n20866,\n20719,\n20572,\n20424,\n20275,\n20127,\n19977,\n19828,\n19678,\n19527,\n19376,\n19225,\n19073,\n18921,\n18769,\n18616,\n18463,\n18310,\n18157,\n18003,\n17849,\n17694,\n17539,\n17384,\n17229,\n17074,\n16918,\n16762,\n16606,\n16450,\n16294,\n16137,\n15980,\n15823,\n15666,\n15509,\n15352,\n15195,\n15037,\n14880,\n14722,\n14564,\n14407,\n14249,\n14091,\n13933,\n13775,\n13618,\n13460,\n13302,\n13144,\n12987,\n12829,\n12671,\n12514,\n12356,\n12199,\n12042,\n11885,\n11728,\n11571,\n11414,\n11257,\n11101,\n10945,\n10789,\n10633,\n10477,\n10322,\n10167,\n10012,\n9857,\n9702,\n9548,\n9394,\n9241,\n9087,\n8934,\n8781,\n8629,\n8477,\n8325,\n8174,\n8023,\n7872,\n7722,\n7572,\n7422,\n7273,\n7124,\n6976,\n6828,\n6681,\n6534,\n6387,\n6241,\n6096,\n5951,\n5806,\n5662,\n5518,\n5375,\n5233,\n5091,\n4949,\n4808,\n4668,\n4528,\n4389,\n4250,\n4112,\n3975,\n3838,\n3702,\n3566,\n3431,\n3297,\n3163,\n3030,\n2898,\n2766,\n2635,\n2505,\n2375,\n2246,\n2118,\n1990,\n1864,\n1738,\n1612,\n1487,\n1364,\n1240,\n1118,\n996,\n875,\n755,\n636,\n517,\n400,\n283,\n166,\n51,\n-63,\n-176,\n-289,\n-401,\n-513,\n-623,\n-733,\n-841,\n-949,\n-1056,\n-1162,\n-1268,\n-1372,\n-1476,\n-1578,\n-1680,\n-1781,\n-1881,\n-1980,\n-2078,\n-2176,\n-2272,\n-2367,\n-2462,\n-2556,\n-2648,\n-2740,\n-2831,\n-2921,\n-3010,\n-3098,\n-3185,\n-3271,\n-3356,\n-3441,\n-3524,\n-3606,\n-3688,\n-3768,\n-3848,\n-3926,\n-4004,\n-4080,\n-4156,\n-4231,\n-4304,\n-4377,\n-4449,\n-4519,\n-4589,\n-4658,\n-4726,\n-4792,\n-4858,\n-4923,\n-4987,\n-5050,\n-5111,\n-5172,\n-5232,\n-5291,\n-5349,\n-5406,\n-5462,\n-5517,\n-5571,\n-5624,\n-5675,\n-5726,\n-5776,\n-5825,\n-5873,\n-5920,\n-5966,\n-6011,\n-6055,\n-6098,\n-6140,\n-6181,\n-6222,\n-6261,\n-6299,\n-6336,\n-6372,\n-6407,\n-6441,\n-6475,\n-6507,\n-6538,\n-6569,\n-6598,\n-6626,\n-6654,\n-6680,\n-6706,\n-6730,\n-6754,\n-6777,\n-6798,\n-6819,\n-6839,\n-6858,\n-6876,\n-6893,\n-6909,\n-6924,\n-6938,\n-6951,\n-6964,\n-6975,\n-6986,\n-6995,\n-7004,\n-7012,\n-7019,\n-7025,\n-7030,\n-7035,\n-7038,\n-7040,\n-7042,\n-7043,\n-7043,\n-7042,\n-7040,\n-7038,\n-7034,\n-7030,\n-7025,\n-7019,\n-7012,\n-7004,\n-6996,\n-6986,\n-6976,\n-6965,\n-6954,\n-6941,\n-6928,\n-6914,\n-6899,\n-6884,\n-6867,\n-6850,\n-6832,\n-6814,\n-6794,\n-6774,\n-6753,\n-6732,\n-6709,\n-6686,\n-6663,\n-6638,\n-6613,\n-6587,\n-6561,\n-6534,\n-6506,\n-6478,\n-6448,\n-6419,\n-6388,\n-6357,\n-6325,\n-6293,\n-6260,\n-6226,\n-6192,\n-6157,\n-6122,\n-6086,\n-6049,\n-6012,\n-5975,\n-5936,\n-5897,\n-5858,\n-5818,\n-5778,\n-5737,\n-5695,\n-5653,\n-5611,\n-5568,\n-5524,\n-5480,\n-5436,\n-5391,\n-5345,\n-5300,\n-5253,\n-5207,\n-5159,\n-5112,\n-5064,\n-5015,\n-4966,\n-4917,\n-4868,\n-4818,\n-4767,\n-4716,\n-4665,\n-4614,\n-4562,\n-4510,\n-4457,\n-4404,\n-4351,\n-4298,\n-4244,\n-4190,\n-4136,\n-4081,\n-4026,\n-3971,\n-3916,\n-3860,\n-3804,\n-3748,\n-3692,\n-3635,\n-3578,\n-3521,\n-3464,\n-3406,\n-3349,\n-3291,\n-3233,\n-3175,\n-3117,\n-3058,\n-3000,\n-2941,\n-2882,\n-2823,\n-2764,\n-2705,\n-2646,\n-2587,\n-2527,\n-2468,\n-2408,\n-2349,\n-2289,\n-2229,\n-2169,\n-2110,\n-2050,\n-1990,\n-1930,\n-1870,\n-1811,\n-1751,\n-1691,\n-1631,\n-1571,\n-1512,\n-1452,\n-1392,\n-1333,\n-1273,\n-1214,\n-1154,\n-1095,\n-1036,\n-977,\n-918,\n-859,\n-800,\n-741,\n-683,\n-624,\n-566,\n-508,\n-450,\n-392,\n-335,\n-277,\n-220,\n-163,\n-106,\n-49,\n6,\n63,\n119,\n175,\n230,\n286,\n341,\n396,\n450,\n505,\n559,\n613,\n667,\n720,\n773,\n826,\n878,\n931,\n983,\n1034,\n1086,\n1137,\n1187,\n1238,\n1288,\n1337,\n1387,\n1436,\n1484,\n1533,\n1581,\n1628,\n1675,\n1722,\n1769,\n1815,\n1861,\n1906,\n1951,\n1996,\n2040,\n2084,\n2127,\n2170,\n2212,\n2255,\n2296,\n2338,\n2378,\n2419,\n2459,\n2498,\n2538,\n2576,\n2615,\n2652,\n2690,\n2727,\n2763,\n2799,\n2834,\n2870,\n2904,\n2938,\n2972,\n3005,\n3038,\n3070,\n3102,\n3133,\n3164,\n3194,\n3224,\n3253,\n3282,\n3310,\n3338,\n3365,\n3392,\n3418,\n3444,\n3469,\n3494,\n3518,\n3542,\n3566,\n3588,\n3611,\n3632,\n3653,\n3674,\n3694,\n3714,\n3733,\n3752,\n3770,\n3788,\n3805,\n3821,\n3837,\n3853,\n3868,\n3882,\n3896,\n3910,\n3923,\n3935,\n3947,\n3958,\n3969,\n3980,\n3989,\n3999,\n4007,\n4016,\n4023,\n4031,\n4037,\n4044,\n4049,\n4054,\n4059,\n4063,\n4067,\n4070,\n4073,\n4075,\n4076,\n4077,\n4078,\n4078,\n4078,\n4077,\n4076,\n4074,\n4071,\n4068,\n4065,\n4061,\n4057,\n4052,\n4047,\n4041,\n4035,\n4028,\n4021,\n4013,\n4005,\n3997,\n3988,\n3978,\n3968,\n3958,\n3947,\n3936,\n3924,\n3912,\n3899,\n3886,\n3872,\n3858,\n3844,\n3829,\n3814,\n3798,\n3782,\n3766,\n3749,\n3731,\n3714,\n3696,\n3677,\n3658,\n3639,\n3619,\n3599,\n3578,\n3558,\n3536,\n3515,\n3493,\n3470,\n3448,\n3425,\n3401,\n3378,\n3353,\n3329,\n3304,\n3279,\n3254,\n3228,\n3202,\n3175,\n3149,\n3122,\n3094,\n3067,\n3039,\n3011,\n2982,\n2953,\n2924,\n2895,\n2865,\n2835,\n2805,\n2775,\n2744,\n2713,\n2682,\n2651,\n2619,\n2587,\n2555,\n2523,\n2490,\n2457,\n2424,\n2391,\n2358,\n2324,\n2290,\n2256,\n2222,\n2188,\n2153,\n2119,\n2084,\n2049,\n2014,\n1978,\n1943,\n1907,\n1872,\n1836,\n1800,\n1764,\n1727,\n1691,\n1655,\n1618,\n1581,\n1545,\n1508,\n1471,\n1434,\n1397,\n1360,\n1322,\n1285,\n1248,\n1210,\n1173,\n1135,\n1098,\n1060,\n1023,\n985,\n947,\n910,\n872,\n834,\n797,\n759,\n721,\n684,\n646,\n608,\n571,\n533,\n496,\n458,\n421,\n383,\n346,\n308,\n271,\n234,\n197,\n160,\n123,\n86,\n49,\n12,\n-23,\n-60,\n-96,\n-133,\n-169,\n-205,\n-241,\n-277,\n-313,\n-348,\n-384,\n-419,\n-455,\n-490,\n-525,\n-559,\n-594,\n-628,\n-663,\n-697,\n-731,\n-765,\n-798,\n-832,\n-865,\n-898,\n-931,\n-963,\n-996,\n-1028,\n-1060,\n-1092,\n-1124,\n-1155,\n-1186,\n-1217,\n-1248,\n-1279,\n-1309,\n-1339,\n-1369,\n-1398,\n-1428,\n-1457,\n-1486,\n-1514,\n-1542,\n-1571,\n-1598,\n-1626,\n-1653,\n-1680,\n-1707,\n-1733,\n-1760,\n-1785,\n-1811,\n-1836,\n-1862,\n-1886,\n-1911,\n-1935,\n-1959,\n-1982,\n-2006,\n-2029,\n-2051,\n-2074,\n-2096,\n-2118,\n-2139,\n-2160,\n-2181,\n-2202,\n-2222,\n-2242,\n-2261,\n-2280,\n-2299,\n-2318,\n-2336,\n-2354,\n-2372,\n-2389,\n-2406,\n-2423,\n-2439,\n-2455,\n-2470,\n-2486,\n-2500,\n-2515,\n-2529,\n-2543,\n-2557,\n-2570,\n-2583,\n-2595,\n-2607,\n-2619,\n-2631,\n-2642,\n-2652,\n-2663,\n-2673,\n-2683,\n-2692,\n-2701,\n-2710,\n-2718,\n-2726,\n-2734,\n-2741,\n-2748,\n-2754,\n-2760,\n-2766,\n-2772,\n-2777,\n-2782,\n-2786,\n-2790,\n-2794,\n-2797,\n-2800,\n-2803,\n-2805,\n-2807,\n-2809,\n-2810,\n-2811,\n-2812,\n-2812,\n-2812,\n-2812,\n-2811,\n-2810,\n-2808,\n-2807,\n-2804,\n-2802,\n-2799,\n-2796,\n-2792,\n-2789,\n-2785,\n-2780,\n-2775,\n-2770,\n-2765,\n-2759,\n-2753,\n-2746,\n-2740,\n-2732,\n-2725,\n-2717,\n-2709,\n-2701,\n-2692,\n-2683,\n-2674,\n-2664,\n-2655,\n-2644,\n-2634,\n-2623,\n-2612,\n-2601,\n-2589,\n-2577,\n-2565,\n-2552,\n-2539,\n-2526,\n-2513,\n-2499,\n-2485,\n-2471,\n-2457,\n-2442,\n-2427,\n-2412,\n-2396,\n-2380,\n-2364,\n-2348,\n-2331,\n-2315,\n-2297,\n-2280,\n-2263,\n-2245,\n-2227,\n-2209,\n-2190,\n-2171,\n-2152,\n-2133,\n-2114,\n-2094,\n-2075,\n-2055,\n-2034,\n-2014,\n-1993,\n-1972,\n-1951,\n-1930,\n-1909,\n-1887,\n-1865,\n-1843,\n-1821,\n-1799,\n-1776,\n-1754,\n-1731,\n-1708,\n-1685,\n-1662,\n-1638,\n-1614,\n-1591,\n-1567,\n-1543,\n-1519,\n-1494,\n-1470,\n-1445,\n-1421,\n-1396,\n-1371,\n-1346,\n-1321,\n-1295,\n-1270,\n-1244,\n-1219,\n-1193,\n-1167,\n-1142,\n-1116,\n-1090,\n-1064,\n-1037,\n-1011,\n-985,\n-958,\n-932,\n-905,\n-879,\n-852,\n-826,\n-799,\n-772,\n-745,\n-719,\n-692,\n-665,\n-638,\n-611,\n-584,\n-557,\n-530,\n-503,\n-476,\n-449,\n-422,\n-395,\n-368,\n-341,\n-314,\n-287,\n-260,\n-234,\n-207,\n-180,\n-153,\n-126,\n-100,\n-73,\n-46,\n-20,\n6,\n32,\n59,\n85,\n111,\n138,\n164,\n190,\n216,\n242,\n268,\n294,\n319,\n345,\n370,\n396,\n421,\n446,\n471,\n496,\n521,\n546,\n571,\n595,\n619,\n644,\n668,\n692,\n716,\n739,\n763,\n787,\n810,\n833,\n856,\n879,\n902,\n924,\n947,\n969,\n991,\n1013,\n1035,\n1056,\n1078,\n1099,\n1120,\n1141,\n1162,\n1182,\n1202,\n1223,\n1243,\n1262,\n1282,\n1301,\n1320,\n1339,\n1358,\n1377,\n1395,\n1413,\n1431,\n1449,\n1467,\n1484,\n1501,\n1518,\n1535,\n1551,\n1567,\n1583,\n1599,\n1615,\n1630,\n1645,\n1660,\n1674,\n1689,\n1703,\n1717,\n1731,\n1744,\n1757,\n1770,\n1783,\n1795,\n1808,\n1820,\n1831,\n1843,\n1854,\n1865,\n1876,\n1886,\n1897,\n1907,\n1916,\n1926,\n1935,\n1944,\n1953,\n1961,\n1970,\n1978,\n1985,\n1993,\n2000,\n2007,\n2014,\n2020,\n2026,\n2032,\n2038,\n2043,\n2048,\n2053,\n2058,\n2062,\n2066,\n2070,\n2073,\n2077,\n2080,\n2083,\n2085,\n2087,\n2089,\n2091,\n2093,\n2094,\n2095,\n2095,\n2096,\n2096,\n2096,\n2096,\n2095,\n2094,\n2093,\n2092,\n2090,\n2088,\n2086,\n2084,\n2081,\n2079,\n2075,\n2072,\n2069,\n2065,\n2061,\n2056,\n2052,\n2047,\n2042,\n2037,\n2031,\n2025,\n2019,\n2013,\n2006,\n2000,\n1993,\n1986,\n1978,\n1971,\n1963,\n1955,\n1946,\n1938,\n1929,\n1920,\n1911,\n1901,\n1892,\n1882,\n1872,\n1862,\n1851,\n1841,\n1830,\n1819,\n1807,\n1796,\n1784,\n1772,\n1760,\n1748,\n1735,\n1723,\n1710,\n1697,\n1684,\n1670,\n1657,\n1643,\n1629,\n1615,\n1601,\n1586,\n1572,\n1557,\n1542,\n1527,\n1512,\n1496,\n1481,\n1465,\n1449,\n1433,\n1417,\n1401,\n1384,\n1368,\n1351,\n1334,\n1317,\n1300,\n1283,\n1265,\n1248,\n1230,\n1212,\n1195,\n1177,\n1159,\n1140,\n1122,\n1104,\n1085,\n1067,\n1048,\n1029,\n1010,\n991,\n972,\n953,\n934,\n915,\n895,\n876,\n856,\n837,\n817,\n797,\n777,\n758,\n738,\n718,\n698,\n678,\n658,\n637,\n617,\n597,\n577,\n556,\n536,\n516,\n495,\n475,\n454,\n434,\n414,\n393,\n373,\n352,\n332,\n311,\n291,\n270,\n250,\n229,\n208,\n188,\n168,\n147,\n127,\n106,\n86,\n65,\n45,\n25,\n5,\n-15,\n-35,\n-55,\n-75,\n-95,\n-115,\n-135,\n-155,\n-175,\n-195,\n-215,\n-234,\n-254,\n-274,\n-293,\n-313,\n-332,\n-351,\n-370,\n-390,\n-409,\n-428,\n-446,\n-465,\n-484,\n-503,\n-521,\n-539,\n-558,\n-576,\n-594,\n-612,\n-630,\n-648,\n-666,\n-683,\n-701,\n-718,\n-735,\n-752,\n-769,\n-786,\n-803,\n-819,\n-836,\n-852,\n-868,\n-885,\n-900,\n-916,\n-932,\n-947,\n-963,\n-978,\n-993,\n-1008,\n-1023,\n-1038,\n-1052,\n-1066,\n-1081,\n-1095,\n-1108,\n-1122,\n-1136,\n-1149,\n-1162,\n-1175,\n-1188,\n-1201,\n-1214,\n-1226,\n-1238,\n-1250,\n-1262,\n-1274,\n-1285,\n-1297,\n-1308,\n-1319,\n-1330,\n-1340,\n-1351,\n-1361,\n-1371,\n-1381,\n-1390,\n-1400,\n-1409,\n-1418,\n-1427,\n-1436,\n-1445,\n-1453,\n-1461,\n-1469,\n-1477,\n-1485,\n-1492,\n-1499,\n-1506,\n-1513,\n-1520,\n-1526,\n-1532,\n-1538,\n-1544,\n-1550,\n-1555,\n-1560,\n-1566,\n-1570,\n-1575,\n-1579,\n-1584,\n-1588,\n-1592,\n-1595,\n-1599,\n-1602,\n-1605,\n-1608,\n-1610,\n-1613,\n-1615,\n-1617,\n-1619,\n-1620,\n-1622,\n-1623,\n-1624,\n-1625,\n-1625,\n-1626,\n-1626,\n-1626,\n-1626,\n-1625,\n-1625,\n-1624,\n-1623,\n-1622,\n-1621,\n-1619,\n-1617,\n-1615,\n-1613,\n-1611,\n-1608,\n-1605,\n-1603,\n-1599,\n-1596,\n-1593,\n-1589,\n-1585,\n-1581,\n-1577,\n-1572,\n-1568,\n-1563,\n-1558,\n-1553,\n-1547,\n-1542,\n-1536,\n-1530,\n-1524,\n-1518,\n-1511,\n-1505,\n-1498,\n-1491,\n-1484,\n-1477,\n-1469,\n-1462,\n-1454,\n-1446,\n-1438,\n-1430,\n-1421,\n-1413,\n-1404,\n-1395,\n-1386,\n-1377,\n-1367,\n-1358,\n-1348,\n-1338,\n-1328,\n-1318,\n-1308,\n-1297,\n-1287,\n-1276,\n-1265,\n-1254,\n-1243,\n-1232,\n-1221,\n-1209,\n-1198,\n-1186,\n-1174,\n-1162,\n-1150,\n-1138,\n-1125,\n-1113,\n-1100,\n-1087,\n-1075,\n-1062,\n-1049,\n-1035,\n-1022,\n-1009,\n-995,\n-982,\n-968,\n-954,\n-941,\n-927,\n-913,\n-898,\n-884,\n-870,\n-856,\n-841,\n-827,\n-812,\n-797,\n-783,\n-768,\n-753,\n-738,\n-723,\n-708,\n-692,\n-677,\n-662,\n-647,\n-631,\n-616,\n-600,\n-585,\n-569,\n-554,\n-538,\n-522,\n-506,\n-491,\n-475,\n-459,\n-443,\n-427,\n-411,\n-395,\n-379,\n-363,\n-347,\n-331,\n-315,\n-299,\n-283,\n-267,\n-251,\n-235,\n-218,\n-202,\n-186,\n-170,\n-154,\n-138,\n-122,\n-106,\n-90,\n-74,\n-58,\n-42,\n-26,\n-10,\n5,\n21,\n37,\n53,\n69,\n85,\n100,\n116,\n132,\n147,\n163,\n179,\n194,\n209,\n225,\n240,\n256,\n271,\n286,\n301,\n316,\n331,\n346,\n361,\n376,\n391,\n405,\n420,\n434,\n449,\n463,\n477,\n492,\n506,\n520,\n534,\n548,\n561,\n575,\n589,\n602,\n615,\n629,\n642,\n655,\n668,\n681,\n694,\n706,\n719,\n731,\n744,\n756,\n768,\n780,\n792,\n804,\n816,\n827,\n839,\n850,\n861,\n872,\n883,\n894,\n905,\n915,\n926,\n936,\n946,\n956,\n966,\n976,\n986,\n995,\n1005,\n1014,\n1023,\n1032,\n1041,\n1049,\n1058,\n1066,\n1075,\n1083,\n1091,\n1099,\n1106,\n1114,\n1121,\n1128,\n1135,\n1142,\n1149,\n1156,\n1162,\n1169,\n1175,\n1181,\n1187,\n1192,\n1198,\n1203,\n1208,\n1214,\n1218,\n1223,\n1228,\n1232,\n1237,\n1241,\n1245,\n1249,\n1252,\n1256,\n1259,\n1262,\n1265,\n1268,\n1271,\n1273,\n1276,\n1278,\n1280,\n1282,\n1284,\n1285,\n1287,\n1288,\n1289,\n1290,\n1291,\n1292,\n1292,\n1292,\n1293,\n1293,\n1292,\n1292,\n1292,\n1291,\n1290,\n1289,\n1288,\n1287,\n1285,\n1284,\n1282,\n1280,\n1278,\n1276,\n1274,\n1271,\n1269,\n1266,\n1263,\n1260,\n1257,\n1253,\n1250,\n1246,\n1242,\n1238,\n1234,\n1230,\n1225,\n1221,\n1216,\n1211,\n1206,\n1201,\n1196,\n1190,\n1185,\n1179,\n1173,\n1167,\n1161,\n1155,\n1149,\n1142,\n1136,\n1129,\n1122,\n1115,\n1108,\n1101,\n1094,\n1086,\n1078,\n1071,\n1063,\n1055,\n1047,\n1039,\n1030,\n1022,\n1013,\n1005,\n996,\n987,\n978,\n969,\n960,\n951,\n941,\n932,\n922,\n913,\n903,\n893,\n883,\n873,\n863,\n853,\n842,\n832,\n821,\n811,\n800,\n789,\n778,\n768,\n757,\n746,\n734,\n723,\n712,\n701,\n689,\n678,\n666,\n654,\n643,\n631,\n619,\n607,\n596,\n584,\n572,\n559,\n547,\n535,\n523,\n511,\n498,\n486,\n474,\n461,\n449,\n436,\n424,\n411,\n399,\n386,\n373,\n361,\n348,\n335,\n322,\n310,\n297,\n284,\n271,\n258,\n246,\n233,\n220,\n207,\n194,\n181,\n168,\n156,\n143,\n130,\n117,\n104,\n91,\n78,\n65,\n53,\n40,\n27,\n14,\n1,\n-10,\n-23,\n-36,\n-48,\n-61,\n-74,\n-86,\n-99,\n-111,\n-124,\n-136,\n-149,\n-161,\n-174,\n-186,\n-198,\n-211,\n-223,\n-235,\n-247,\n-259,\n-271,\n-283,\n-295,\n-307,\n-319,\n-330,\n-342,\n-354,\n-365,\n-377,\n-388,\n-399,\n-411,\n-422,\n-433,\n-444,\n-455,\n-466,\n-477,\n-488,\n-499,\n-509,\n-520,\n-530,\n-541,\n-551,\n-561,\n-571,\n-581,\n-591,\n-601,\n-611,\n-621,\n-631,\n-640,\n-650,\n-659,\n-668,\n-677,\n-686,\n-695,\n-704,\n-713,\n-722,\n-730,\n-739,\n-747,\n-755,\n-763,\n-771,\n-779,\n-787,\n-795,\n-803,\n-810,\n-817,\n-825,\n-832,\n-839,\n-846,\n-853,\n-859,\n-866,\n-873,\n-879,\n-885,\n-891,\n-897,\n-903,\n-909,\n-915,\n-920,\n-926,\n-931,\n-936,\n-941,\n-946,\n-951,\n-955,\n-960,\n-964,\n-969,\n-973,\n-977,\n-981,\n-985,\n-988,\n-992,\n-995,\n-999,\n-1002,\n-1005,\n-1008,\n-1011,\n-1013,\n-1016,\n-1018,\n-1020,\n-1023,\n-1025,\n-1026,\n-1028,\n-1030,\n-1031,\n-1033,\n-1034,\n-1035,\n-1036,\n-1037,\n-1038,\n-1038,\n-1039,\n-1039,\n-1039,\n-1039,\n-1039,\n-1039,\n-1039,\n-1038,\n-1038,\n-1037,\n-1036,\n-1036,\n-1034,\n-1033,\n-1032,\n-1031,\n-1029,\n-1027,\n-1026,\n-1024,\n-1022,\n-1019,\n-1017,\n-1015,\n-1012,\n-1010,\n-1007,\n-1004,\n-1001,\n-998,\n-995,\n-991,\n-988,\n-984,\n-980,\n-977,\n-973,\n-969,\n-965,\n-960,\n-956,\n-951,\n-947,\n-942,\n-937,\n-932,\n-927,\n-922,\n-917,\n-912,\n-906,\n-901,\n-895,\n-889,\n-883,\n-877,\n-871,\n-865,\n-859,\n-853,\n-846,\n-840,\n-833,\n-826,\n-819,\n-812,\n-805,\n-798,\n-791,\n-784,\n-777,\n-769,\n-762,\n-754,\n-746,\n-739,\n-731,\n-723,\n-715,\n-707,\n-699,\n-691,\n-682,\n-674,\n-665,\n-657,\n-648,\n-640,\n-631,\n-622,\n-614,\n-605,\n-596,\n-587,\n-578,\n-569,\n-559,\n-550,\n-541,\n-532,\n-522,\n-513,\n-503,\n-494,\n-484,\n-474,\n-465,\n-455,\n-445,\n-436,\n-426,\n-416,\n-406,\n-396,\n-386,\n-376,\n-366,\n-356,\n-346,\n-336,\n-325,\n-315,\n-305,\n-295,\n-285,\n-274,\n-264,\n-254,\n-243,\n-233,\n-223,\n-212,\n-202,\n-192,\n-181,\n-171,\n-161,\n-150,\n-140,\n-129,\n-119,\n-108,\n-98,\n-88,\n-77,\n-67,\n-57,\n-46,\n-36,\n-25,\n-15,\n-5,\n5,\n15,\n25,\n35,\n46,\n56,\n66,\n76,\n86,\n97,\n107,\n117,\n127,\n137,\n147,\n157,\n167,\n177,\n186,\n196,\n206,\n216,\n225,\n235,\n245,\n254,\n264,\n273,\n283,\n292,\n301,\n311,\n320,\n329,\n338,\n347,\n356,\n365,\n374,\n383,\n392,\n400,\n409,\n418,\n426,\n435,\n443,\n451,\n460,\n468,\n476,\n484,\n492,\n500,\n508,\n515,\n523,\n531,\n538,\n546,\n553,\n560,\n568,\n575,\n582,\n589,\n596,\n602,\n609,\n616,\n622,\n629,\n635,\n642,\n648,\n654,\n660,\n666,\n672,\n678,\n683,\n689,\n694,\n700,\n705,\n710,\n715,\n720,\n725,\n730,\n735,\n739,\n744,\n748,\n753,\n757,\n761,\n765,\n769,\n773,\n777,\n780,\n784,\n787,\n791,\n794,\n797,\n800,\n803,\n806,\n809,\n811,\n814,\n816,\n818,\n821,\n823,\n825,\n827,\n828,\n830,\n832,\n833,\n835,\n836,\n837,\n838,\n839,\n840,\n841,\n841,\n842,\n842,\n843,\n843,\n843,\n843,\n843,\n843,\n843,\n842,\n842,\n841,\n840,\n840,\n839,\n838,\n837,\n835,\n834,\n833,\n831,\n830,\n828,\n826,\n824,\n822,\n820,\n818,\n816,\n813,\n811,\n808,\n806,\n803,\n800,\n797,\n794,\n791,\n788,\n784,\n781,\n777,\n774,\n770,\n766,\n763,\n759,\n755,\n750,\n746,\n742,\n738,\n733,\n729,\n724,\n719,\n714,\n710,\n705,\n700,\n694,\n689,\n684,\n679,\n673,\n668,\n662,\n657,\n651,\n645,\n639,\n633,\n627,\n621,\n615,\n609,\n603,\n596,\n590,\n584,\n577,\n571,\n564,\n557,\n551,\n544,\n537,\n530,\n523,\n516,\n509,\n502,\n495,\n487,\n480,\n473,\n465,\n458,\n450,\n443,\n435,\n428,\n420,\n413,\n405,\n397,\n389,\n381,\n374,\n366,\n358,\n350,\n342,\n334,\n326,\n318,\n310,\n301,\n293,\n285,\n277,\n269,\n260,\n252,\n244,\n236,\n227,\n219,\n211,\n202,\n194,\n185,\n177,\n169,\n160,\n152,\n143,\n135,\n126,\n118,\n110,\n101,\n93,\n84,\n76,\n67,\n59,\n50,\n42,\n34,\n25,\n17,\n8,\n0,\n-7,\n-16,\n-24,\n-32,\n-41,\n-49,\n-57,\n-66,\n-74,\n-82,\n-90,\n-98,\n-106,\n-115,\n-123,\n-131,\n-139,\n-147,\n-155,\n-163,\n-171,\n-179,\n-186,\n-194,\n-202,\n-210,\n-217,\n-225,\n-233,\n-240,\n-248,\n-255,\n-263,\n-270,\n-278,\n-285,\n-292,\n-299,\n-307,\n-314,\n-321,\n-328,\n-335,\n-342,\n-349,\n-356,\n-362,\n-369,\n-376,\n-382,\n-389,\n-396,\n-402,\n-408,\n-415,\n-421,\n-427,\n-433,\n-439,\n-445,\n-451,\n-457,\n-463,\n-469,\n-475,\n-480,\n-486,\n-491,\n-497,\n-502,\n-507,\n-513,\n-518,\n-523,\n-528,\n-533,\n-538,\n-542,\n-547,\n-552,\n-556,\n-561,\n-565,\n-570,\n-574,\n-578,\n-582,\n-586,\n-590,\n-594,\n-598,\n-602,\n-605,\n-609,\n-612,\n-616,\n-619,\n-622,\n-625,\n-629,\n-632,\n-634,\n-637,\n-640,\n-643,\n-645,\n-648,\n-650,\n-653,\n-655,\n-657,\n-659,\n-661,\n-663,\n-665,\n-667,\n-668,\n-670,\n-671,\n-673,\n-674,\n-675,\n-676,\n-678,\n-679,\n-679,\n-680,\n-681,\n-682,\n-682,\n-683,\n-683,\n-683,\n-684,\n-684,\n-684,\n-684,\n-684,\n-684,\n-683,\n-683,\n-682,\n-682,\n-681,\n-681,\n-680,\n-679,\n-678,\n-677,\n-676,\n-675,\n-674,\n-672,\n-671,\n-669,\n-668,\n-666,\n-664,\n-662,\n-661,\n-659,\n-657,\n-654,\n-652,\n-650,\n-648,\n-645,\n-643,\n-640,\n-637,\n-635,\n-632,\n-629,\n-626,\n-623,\n-620,\n-617,\n-613,\n-610,\n-607,\n-603,\n-600,\n-596,\n-593,\n-589,\n-585,\n-581,\n-577,\n-573,\n-569,\n-565,\n-561,\n-557,\n-552,\n-548,\n-544,\n-539,\n-534,\n-530,\n-525,\n-520,\n-516,\n-511,\n-506,\n-501,\n-496,\n-491,\n-486,\n-481,\n-475,\n-470,\n-465,\n-460,\n-454,\n-449,\n-443,\n-438,\n-432,\n-426,\n-421,\n-415,\n-409,\n-403,\n-398,\n-392,\n-386,\n-380,\n-374,\n-368,\n-362,\n-355,\n-349,\n-343,\n-337,\n-331,\n-324,\n-318,\n-312,\n-305,\n-299,\n-292,\n-286,\n-280,\n-273,\n-266,\n-260,\n-253,\n-247,\n-240,\n-234,\n-227,\n-220,\n-213,\n-207,\n-200,\n-193,\n-187,\n-180,\n-173,\n-166,\n-159,\n-153,\n-146,\n-139,\n-132,\n-125,\n-118,\n-112,\n-105,\n-98,\n-91,\n-84,\n-77,\n-70,\n-64,\n-57,\n-50,\n-43,\n-36,\n-29,\n-22,\n-16,\n-9,\n-2,\n4,\n11,\n17,\n24,\n31,\n38,\n44,\n51,\n58,\n64,\n71,\n78,\n84,\n91,\n98,\n104,\n111,\n117,\n124,\n130,\n137,\n143,\n149,\n156,\n162,\n168,\n175,\n181,\n187,\n193,\n199,\n205,\n212,\n218,\n224,\n230,\n236,\n241,\n247,\n253,\n259,\n265,\n270,\n276,\n282,\n287,\n293,\n298,\n304,\n309,\n314,\n320,\n325,\n330,\n335,\n340,\n345,\n350,\n355,\n360,\n365,\n370,\n375,\n380,\n384,\n389,\n393,\n398,\n402,\n407,\n411,\n415,\n419,\n424,\n428,\n432,\n436,\n440,\n443,\n447,\n451,\n455,\n458,\n462,\n465,\n469,\n472,\n475,\n479,\n482,\n485,\n488,\n491,\n494,\n497,\n499,\n502,\n505,\n507,\n510,\n512,\n515,\n517,\n519,\n522,\n524,\n526,\n528,\n530,\n532,\n533,\n535,\n537,\n538,\n540,\n541,\n543,\n544,\n545,\n546,\n548,\n549,\n550,\n550,\n551,\n552,\n553,\n553,\n554,\n554,\n555,\n555,\n555,\n556,\n556,\n556,\n556,\n556,\n556,\n555,\n555,\n555,\n554,\n554,\n553,\n553,\n552,\n551,\n551,\n550,\n549,\n548,\n547,\n546,\n545,\n543,\n542,\n541,\n539,\n538,\n536,\n534,\n533,\n531,\n529,\n527,\n525,\n523,\n521,\n519,\n517,\n514,\n512,\n510,\n507,\n505,\n502,\n500,\n497,\n494,\n492,\n489,\n486,\n483,\n480,\n477,\n474,\n471,\n467,\n464,\n461,\n457,\n454,\n450,\n447,\n443,\n440,\n436,\n432,\n429,\n425,\n421,\n417,\n413,\n409,\n405,\n401,\n397,\n393,\n388,\n384,\n380,\n375,\n371,\n367,\n362,\n358,\n353,\n349,\n344,\n339,\n335,\n330,\n325,\n321,\n316,\n311,\n306,\n301,\n296,\n291,\n286,\n281,\n276,\n271,\n266,\n261,\n256,\n251,\n245,\n240,\n235,\n230,\n225,\n219,\n214,\n209,\n203,\n198,\n193,\n187,\n182,\n176,\n171,\n165,\n160,\n154,\n149,\n144,\n138,\n132,\n127,\n121,\n116,\n110,\n105,\n99,\n94,\n88,\n83,\n77,\n71,\n66,\n60,\n55,\n49,\n44,\n38,\n33,\n27,\n21,\n16,\n10,\n5,\n0,\n-5,\n-11,\n-16,\n-22,\n-27,\n-33,\n-38,\n-43,\n-49,\n-54,\n-60,\n-65,\n-70,\n-76,\n-81,\n-86,\n-92,\n-97,\n-102,\n-107,\n-113,\n-118,\n-123,\n-128,\n-133,\n-138,\n-143,\n-148,\n-153,\n-158,\n-163,\n-168,\n-173,\n-178,\n-183,\n-188,\n-192,\n-197,\n-202,\n-207,\n-211,\n-216,\n-221,\n-225,\n-230,\n-234,\n-239,\n-243,\n-247,\n-252,\n-256,\n-260,\n-265,\n-269,\n-273,\n-277,\n-281,\n-285,\n-289,\n-293,\n-297,\n-301,\n-305,\n-308,\n-312,\n-316,\n-319,\n-323,\n-327,\n-330,\n-334,\n-337,\n-340,\n-344,\n-347,\n-350,\n-353,\n-357,\n-360,\n-363,\n-366,\n-369,\n-372,\n-374,\n-377,\n-380,\n-383,\n-385,\n-388,\n-390,\n-393,\n-395,\n-398,\n-400,\n-402,\n-405,\n-407,\n-409,\n-411,\n-413,\n-415,\n-417,\n-419,\n-420,\n-422,\n-424,\n-425,\n-427,\n-429,\n-430,\n-431,\n-433,\n-434,\n-435,\n-436,\n-438,\n-439,\n-440,\n-441,\n-442,\n-442,\n-443,\n-444,\n-445,\n-445,\n-446,\n-446,\n-447,\n-447,\n-448,\n-448,\n-448,\n-448,\n-449,\n-449,\n-449,\n-449,\n-449,\n-448,\n-448,\n-448,\n-448,\n-447,\n-447,\n-446,\n-446,\n-445,\n-445,\n-444,\n-443,\n-442,\n-442,\n-441,\n-440,\n-439,\n-438,\n-437,\n-435,\n-434,\n-433,\n-432,\n-430,\n-429,\n-427,\n-426,\n-424,\n-423,\n-421,\n-419,\n-418,\n-416,\n-414,\n-412,\n-410,\n-408,\n-406,\n-404,\n-402,\n-400,\n-397,\n-395,\n-393,\n-390,\n-388,\n-385,\n-383,\n-380,\n-378,\n-375,\n-373,\n-370,\n-367,\n-364,\n-361,\n-359,\n-356,\n-353,\n-350,\n-347,\n-344,\n-340,\n-337,\n-334,\n-331,\n-328,\n-324,\n-321,\n-318,\n-314,\n-311,\n-307,\n-304,\n-300,\n-297,\n-293,\n-290,\n-286,\n-282,\n-279,\n-275,\n-271,\n-267,\n-263,\n-260,\n-256,\n-252,\n-248,\n-244,\n-240,\n-236,\n-232,\n-228,\n-224,\n-220,\n-216,\n-212,\n-207,\n-203,\n-199,\n-195,\n-191,\n-186,\n-182,\n-178,\n-174,\n-169,\n-165,\n-161,\n-156,\n-152,\n-148,\n-143,\n-139,\n-134,\n-130,\n-126,\n-121,\n-117,\n-112,\n-108,\n-103,\n-99,\n-95,\n-90,\n-86,\n-81,\n-77,\n-72,\n-68,\n-63,\n-59,\n-54,\n-50,\n-45,\n-41,\n-36,\n-32,\n-27,\n-23,\n-18,\n-14,\n-9,\n-5,\n0,\n3,\n7,\n12,\n16,\n21,\n25,\n29,\n34,\n38,\n43,\n47,\n51,\n56,\n60,\n64,\n69,\n73,\n77,\n81,\n85,\n90,\n94,\n98,\n102,\n106,\n110,\n115,\n119,\n123,\n127,\n131,\n135,\n139,\n143,\n146,\n150,\n154,\n158,\n162,\n166,\n169,\n173,\n177,\n181,\n184,\n188,\n192,\n195,\n199,\n202,\n206,\n209,\n212,\n216,\n219,\n223,\n226,\n229,\n232,\n236,\n239,\n242,\n245,\n248,\n251,\n254,\n257,\n260,\n263,\n266,\n268,\n271,\n274,\n277,\n279,\n282,\n284,\n287,\n289,\n292,\n294,\n297,\n299,\n301,\n304,\n306,\n308,\n310,\n312,\n314,\n316,\n318,\n320,\n322,\n324,\n326,\n328,\n329,\n331,\n333,\n334,\n336,\n337,\n339,\n340,\n341,\n343,\n344,\n345,\n346,\n348,\n349,\n350,\n351,\n352,\n353,\n354,\n354,\n355,\n356,\n357,\n357,\n358,\n358,\n359,\n359,\n360,\n360,\n361,\n361,\n361,\n361,\n362,\n362,\n362,\n362,\n362,\n362,\n362,\n361,\n361,\n361,\n361,\n360,\n360,\n360,\n359,\n359,\n358,\n358,\n357,\n356,\n356,\n355,\n354,\n353,\n352,\n351,\n350,\n349,\n348,\n347,\n346,\n345,\n344,\n343,\n341,\n340,\n339,\n337,\n336,\n334,\n333,\n331,\n330,\n328,\n326,\n324,\n323,\n321,\n319,\n317,\n315,\n313,\n311,\n309,\n307,\n305,\n303,\n301,\n299,\n297,\n294,\n292,\n290,\n288,\n285,\n283,\n280,\n278,\n275,\n273,\n270,\n268,\n265,\n263,\n260,\n257,\n254,\n252,\n249,\n246,\n243,\n240,\n238,\n235,\n232,\n229,\n226,\n223,\n220,\n217,\n214,\n211,\n208,\n204,\n201,\n198,\n195,\n192,\n188,\n185,\n182,\n179,\n175,\n172,\n169,\n165,\n162,\n159,\n155,\n152,\n149,\n145,\n142,\n138,\n135,\n131,\n128,\n124,\n121,\n117,\n114,\n110,\n107,\n103,\n100,\n96,\n93,\n89,\n85,\n82,\n78,\n75,\n71,\n67,\n64,\n60,\n57,\n53,\n49,\n46,\n42,\n39,\n35,\n31,\n28,\n24,\n21,\n17,\n14,\n10,\n6,\n3,\n0,\n-3,\n-7,\n-10,\n-14,\n-18,\n-21,\n-25,\n-28,\n-32,\n-35,\n-39,\n-42,\n-45,\n-49,\n-52,\n-56,\n-59,\n-63,\n-66,\n-69,\n-73,\n-76,\n-79,\n-83,\n-86,\n-89,\n-93,\n-96,\n-99,\n-102,\n-105,\n-109,\n-112,\n-115,\n-118,\n-121,\n-124,\n-127,\n-130,\n-133,\n-136,\n-139,\n-142,\n-145,\n-148,\n-151,\n-154,\n-157,\n-160,\n-162,\n-165,\n-168,\n-171,\n-173,\n-176,\n-179,\n-181,\n-184,\n-186,\n-189,\n-191,\n-194,\n-196,\n-199,\n-201,\n-204,\n-206,\n-208,\n-211,\n-213,\n-215,\n-217,\n-219,\n-221,\n-224,\n-226,\n-228,\n-230,\n-232,\n-234,\n-236,\n-237,\n-239,\n-241,\n-243,\n-245,\n-246,\n-248,\n-250,\n-251,\n-253,\n-254,\n-256,\n-257,\n-259,\n-260,\n-262,\n-263,\n-264,\n-266,\n-267,\n-268,\n-269,\n-270,\n-271,\n-273,\n-274,\n-275,\n-275,\n-276,\n-277,\n-278,\n-279,\n-280,\n-281,\n-281,\n-282,\n-283,\n-283,\n-284,\n-284,\n-285,\n-285,\n-286,\n-286,\n-286,\n-287,\n-287,\n-287,\n-287,\n-288,\n-288,\n-288,\n-288,\n-288,\n-288,\n-288,\n-288,\n-288,\n-288,\n-287,\n-287,\n-287,\n-287,\n-286,\n-286,\n-286,\n-285,\n-285,\n-284,\n-284,\n-283,\n-283,\n-282,\n-281,\n-281,\n-280,\n-279,\n-278,\n-277,\n-277,\n-276,\n-275,\n-274,\n-273,\n-272,\n-271,\n-270,\n-269,\n-267,\n-266,\n-265,\n-264,\n-262,\n-261,\n-260,\n-258,\n-257,\n-256,\n-254,\n-253,\n-251,\n-250,\n-248,\n-247,\n-245,\n-243,\n-242,\n-240,\n-238,\n-236,\n-235,\n-233,\n-231,\n-229,\n-227,\n-225,\n-223,\n-221,\n-219,\n-217,\n-215,\n-213,\n-211,\n-209,\n-207,\n-205,\n-203,\n-201,\n-198,\n-196,\n-194,\n-192,\n-189,\n-187,\n-185,\n-182,\n-180,\n-178,\n-175,\n-173,\n-170,\n-168,\n-165,\n-163,\n-160,\n-158,\n-155,\n-153,\n-150,\n-148,\n-145,\n-142,\n-140,\n-137,\n-135,\n-132,\n-129,\n-127,\n-124,\n-121,\n-118,\n-116,\n-113,\n-110,\n-108,\n-105,\n-102,\n-99,\n-96,\n-94,\n-91,\n-88,\n-85,\n-82,\n-80,\n-77,\n-74,\n-71,\n-68,\n-65,\n-63,\n-60,\n-57,\n-54,\n-51,\n-48,\n-45,\n-42,\n-40,\n-37,\n-34,\n-31,\n-28,\n-25,\n-22,\n-20,\n-17,\n-14,\n-11,\n-8,\n-5,\n-2,\n0,\n2,\n5,\n8,\n11,\n13,\n16,\n19,\n22,\n25,\n27,\n30,\n33,\n36,\n38,\n41,\n44,\n47,\n49,\n52,\n55,\n57,\n60,\n63,\n65,\n68,\n71,\n73,\n76,\n78,\n81,\n83,\n86,\n88,\n91,\n93,\n96,\n98,\n101,\n103,\n106,\n108,\n110,\n113,\n115,\n117,\n120,\n122,\n124,\n127,\n129,\n131,\n133,\n135,\n137,\n140,\n142,\n144,\n146,\n148,\n150,\n152,\n154,\n156,\n158,\n160,\n161,\n163,\n165,\n167,\n169,\n171,\n172,\n174,\n176,\n177,\n179,\n181,\n182,\n184,\n185,\n187,\n188,\n190,\n191,\n193,\n194,\n195,\n197,\n198,\n199,\n201,\n202,\n203,\n204,\n205,\n207,\n208,\n209,\n210,\n211,\n212,\n213,\n214,\n215,\n216,\n216,\n217,\n218,\n219,\n219,\n220,\n221,\n222,\n222,\n223,\n223,\n224,\n224,\n225,\n225,\n226,\n226,\n227,\n227,\n227,\n227,\n228,\n228,\n228,\n228,\n228,\n229,\n229,\n229,\n229,\n229,\n229,\n229,\n229,\n228,\n228,\n228,\n228,\n228,\n228,\n227,\n227,\n227,\n226,\n226,\n225,\n225,\n225,\n224,\n224,\n223,\n222,\n222,\n221,\n221,\n220,\n219,\n218,\n218,\n217,\n216,\n215,\n214,\n214,\n213,\n212,\n211,\n210,\n209,\n208,\n207,\n206,\n205,\n203,\n202,\n201,\n200,\n199,\n197,\n196,\n195,\n194,\n192,\n191,\n190,\n188,\n187,\n185,\n184,\n182,\n181,\n179,\n178,\n176,\n175,\n173,\n172,\n170,\n168,\n167,\n165,\n163,\n162,\n160,\n158,\n156,\n155,\n153,\n151,\n149,\n147,\n146,\n144,\n142,\n140,\n138,\n136,\n134,\n132,\n130,\n128,\n126,\n124,\n122,\n120,\n118,\n116,\n114,\n112,\n110,\n108,\n106,\n104,\n102,\n99,\n97,\n95,\n93,\n91,\n89,\n87,\n84,\n82,\n80,\n78,\n76,\n73,\n71,\n69,\n67,\n64,\n62,\n60,\n58,\n56,\n53,\n51,\n49,\n47,\n44,\n42,\n40,\n38,\n35,\n33,\n31,\n28,\n26,\n24,\n22,\n19,\n17,\n15,\n13,\n10,\n8,\n6,\n4,\n1,\n0,\n-2,\n-4,\n-6,\n-9,\n-11,\n-13,\n-15,\n-17,\n-20,\n-22,\n-24,\n-26,\n-28,\n-30,\n-33,\n-35,\n-37,\n-39,\n-41,\n-43,\n-45,\n-47,\n-49,\n-52,\n-54,\n-56,\n-58,\n-60,\n-62,\n-64,\n-66,\n-68,\n-70,\n-72,\n-74,\n-76,\n-77,\n-79,\n-81,\n-83,\n-85,\n-87,\n-89,\n-90,\n-92,\n-94,\n-96,\n-98,\n-99,\n-101,\n-103,\n-105,\n-106,\n-108,\n-110,\n-111,\n-113,\n-114,\n-116,\n-118,\n-119,\n-121,\n-122,\n-124,\n-125,\n-127,\n-128,\n-130,\n-131,\n-132,\n-134,\n-135,\n-136,\n-138,\n-139,\n-140,\n-142,\n-143,\n-144,\n-145,\n-146,\n-148,\n-149,\n-150,\n-151,\n-152,\n-153,\n-154,\n-155,\n-156,\n-157,\n-158,\n-159,\n-160,\n-161,\n-162,\n-162,\n-163,\n-164,\n-165,\n-166,\n-166,\n-167,\n-168,\n-168,\n-169,\n-170,\n-170,\n-171,\n-171,\n-172,\n-172,\n-173,\n-173,\n-174,\n-174,\n-175,\n-175,\n-175,\n-176,\n-176,\n-176,\n-177,\n-177,\n-177,\n-177,\n-178,\n-178,\n-178,\n-178,\n-178,\n-178,\n-178,\n-178,\n-178,\n-178,\n-178,\n-178,\n-178,\n-178,\n-178,\n-178,\n-177,\n-177,\n-177,\n-177,\n-177,\n-176,\n-176,\n-176,\n-175,\n-175,\n-175,\n-174,\n-174,\n-173,\n-173,\n-172,\n-172,\n-171,\n-171,\n-170,\n-170,\n-169,\n-168,\n-168,\n-167,\n-166,\n-166,\n-165,\n-164,\n-163,\n-163,\n-162,\n-161,\n-160,\n-159,\n-158,\n-158,\n-157,\n-156,\n-155,\n-154,\n-153,\n-152,\n-151,\n-150,\n-149,\n-148,\n-147,\n-145,\n-144,\n-143,\n-142,\n-141,\n-140,\n-139,\n-137,\n-136,\n-135,\n-134,\n-132,\n-131,\n-130,\n-128,\n-127,\n-126,\n-124,\n-123,\n-122,\n-120,\n-119,\n-118,\n-116,\n-115,\n-113,\n-112,\n-110,\n-109,\n-107,\n-106,\n-104,\n-103,\n-101,\n-100,\n-98,\n-97,\n-95,\n-94,\n-92,\n-90,\n-89,\n-87,\n-86,\n-84,\n-82,\n-81,\n-79,\n-77,\n-76,\n-74,\n-72,\n-71,\n-69,\n-67,\n-66,\n-64,\n-62,\n-60,\n-59,\n-57,\n-55,\n-54,\n-52,\n-50,\n-48,\n-47,\n-45,\n-43,\n-41,\n-40,\n-38,\n-36,\n-34,\n-33,\n-31,\n-29,\n-27,\n-25,\n-24,\n-22,\n-20,\n-18,\n-17,\n-15,\n-13,\n-11,\n-10,\n-8,\n-6,\n-4,\n-3,\n-1,\n0,\n2,\n3,\n5,\n7,\n8,\n10,\n12,\n14,\n15,\n17,\n19,\n20,\n22,\n24,\n25,\n27,\n29,\n30,\n32,\n34,\n35,\n37,\n39,\n40,\n42,\n43,\n45,\n47,\n48,\n50,\n51,\n53,\n54,\n56,\n57,\n59,\n60,\n62,\n63,\n65,\n66,\n68,\n69,\n70,\n72,\n73,\n75,\n76,\n77,\n79,\n80,\n81,\n83,\n84,\n85,\n87,\n88,\n89,\n90,\n92,\n93,\n94,\n95,\n96,\n97,\n99,\n100,\n101,\n102,\n103,\n104,\n105,\n106,\n107,\n108,\n109,\n110,\n111,\n112,\n113,\n114,\n115,\n116,\n117,\n117,\n118,\n119,\n120,\n121,\n121,\n122,\n123,\n124,\n124,\n125,\n126,\n126,\n127,\n128,\n128,\n129,\n129,\n130,\n130,\n131,\n131,\n132,\n132,\n133,\n133,\n134,\n134,\n135,\n135,\n135,\n136,\n136,\n136,\n136,\n137,\n137,\n137,\n137,\n138,\n138,\n138,\n138,\n138,\n138,\n138,\n138,\n139,\n139,\n139,\n139,\n139,\n139,\n139,\n138,\n138,\n138,\n138,\n138,\n138,\n138,\n138,\n137,\n137,\n137,\n137,\n136,\n136,\n136,\n136,\n135,\n135,\n134,\n134,\n134,\n133,\n133,\n132,\n132,\n132,\n131,\n131,\n130,\n129,\n129,\n128,\n128,\n127,\n127,\n126,\n125,\n125,\n124,\n123,\n123,\n122,\n121,\n121,\n120,\n119,\n118,\n117,\n117,\n116,\n115,\n114,\n113,\n113,\n112,\n111,\n110,\n109,\n108,\n107,\n106,\n105,\n104,\n103,\n102,\n101,\n100,\n99,\n98,\n97,\n96,\n95,\n94,\n93,\n92,\n91,\n90,\n89,\n87,\n86,\n85,\n84,\n83,\n82,\n81,\n79,\n78,\n77,\n76,\n75,\n73,\n72,\n71,\n70,\n68,\n67,\n66,\n65,\n63,\n62,\n61,\n60,\n58,\n57,\n56,\n54,\n53,\n52,\n50,\n49,\n48,\n47,\n45,\n44,\n43,\n41,\n40,\n39,\n37,\n36,\n34,\n33,\n32,\n30,\n29,\n28,\n26,\n25,\n24,\n22,\n21,\n20,\n18,\n17,\n16,\n14,\n13,\n11,\n10,\n9,\n7,\n6,\n5,\n3,\n2,\n1,\n0,\n-1,\n-2,\n-4,\n-5,\n-6,\n-8,\n-9,\n-10,\n-11,\n-13,\n-14,\n-15,\n-17,\n-18,\n-19,\n-20,\n-22,\n-23,\n-24,\n-26,\n-27,\n-28,\n-29,\n-30,\n-32,\n-33,\n-34,\n-35,\n-37,\n-38,\n-39,\n-40,\n-41,\n-42,\n-44,\n-45,\n-46,\n-47,\n-48,\n-49,\n-50,\n-51,\n-53,\n-54,\n-55,\n-56,\n-57,\n-58,\n-59,\n-60,\n-61,\n-62,\n-63,\n-64,\n-65,\n-66,\n-67,\n-68,\n-69,\n-70,\n-71,\n-71,\n-72,\n-73,\n-74,\n-75,\n-76,\n-77,\n-77,\n-78,\n-79,\n-80,\n-81,\n-81,\n-82,\n-83,\n-84,\n-84,\n-85,\n-86,\n-87,\n-87,\n-88,\n-89,\n-89,\n-90,\n-90,\n-91,\n-92,\n-92,\n-93,\n-93,\n-94,\n-94,\n-95,\n-95,\n-96,\n-96,\n-97,\n-97,\n-98,\n-98,\n-99,\n-99,\n-99,\n-100,\n-100,\n-100,\n-101,\n-101,\n-101,\n-102,\n-102,\n-102,\n-102,\n-103,\n-103,\n-103,\n-103,\n-103,\n-104,\n-104,\n-104,\n-104,\n-104,\n-104,\n-104,\n-105,\n-105,\n-105,\n-105,\n-105,\n-105,\n-105,\n-105,\n-105,\n-105,\n-105,\n-105,\n-104,\n-104,\n-104,\n-104,\n-104,\n-104,\n-104,\n-104,\n-103,\n-103,\n-103,\n-103,\n-103,\n-102,\n-102,\n-102,\n-102,\n-101,\n-101,\n-101,\n-100,\n-100,\n-100,\n-99,\n-99,\n-99,\n-98,\n-98,\n-97,\n-97,\n-97,\n-96,\n-96,\n-95,\n-95,\n-94,\n-94,\n-93,\n-93,\n-92,\n-92,\n-91,\n-90,\n-90,\n-89,\n-89,\n-88,\n-87,\n-87,\n-86,\n-86,\n-85,\n-84,\n-84,\n-83,\n-82,\n-81,\n-81,\n-80,\n-79,\n-79,\n-78,\n-77,\n-76,\n-76,\n-75,\n-74,\n-73,\n-72,\n-72,\n-71,\n-70,\n-69,\n-68,\n-67,\n-67,\n-66,\n-65,\n-64,\n-63,\n-62,\n-61,\n-61,\n-60,\n-59,\n-58,\n-57,\n-56,\n-55,\n-54,\n-53,\n-52,\n-51,\n-50,\n-49,\n-48,\n-48,\n-47,\n-46,\n-45,\n-44,\n-43,\n-42,\n-41,\n-40,\n-39,\n-38,\n-37,\n-36,\n-35,\n-34,\n-33,\n-32,\n-31,\n-30,\n-29,\n-28,\n-27,\n-26,\n-25,\n-24,\n-23,\n-21,\n-20,\n-19,\n-18,\n-17,\n-16,\n-15,\n-14,\n-13,\n-12,\n-11,\n-10,\n-9,\n-8,\n-7,\n-6,\n-5,\n-4,\n-3,\n-2,\n-1,\n0,\n0,\n1,\n2,\n3,\n4,\n5,\n6,\n7,\n8,\n9,\n10,\n11,\n12,\n13,\n14,\n15,\n16,\n17,\n18,\n19,\n20,\n21,\n22,\n22,\n23,\n24,\n25,\n26,\n27,\n28,\n29,\n30,\n31,\n32,\n32,\n33,\n34,\n35,\n36,\n37,\n38,\n38,\n39,\n40,\n41,\n42,\n42,\n43,\n44,\n45,\n46,\n46,\n47,\n48,\n49,\n49,\n50,\n51,\n52,\n52,\n53,\n54,\n54,\n55,\n56,\n56,\n57,\n58,\n58,\n59,\n59,\n60,\n61,\n61,\n62,\n62,\n63,\n64,\n64,\n65,\n65,\n66,\n66,\n67,\n67,\n68,\n68,\n69,\n69,\n69,\n70,\n70,\n71,\n71,\n72,\n72,\n72,\n73,\n73,\n73,\n74,\n74,\n74,\n75,\n75,\n75,\n76,\n76,\n76,\n76,\n77,\n77,\n77,\n77,\n77,\n78,\n78,\n78,\n78,\n78,\n78,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n79,\n78,\n78,\n78,\n78,\n78,\n78,\n77,\n77,\n77,\n77,\n77,\n76,\n76,\n76,\n76,\n75,\n75,\n75,\n74,\n74,\n74,\n74,\n73,\n73,\n72,\n72,\n72,\n71,\n71,\n71,\n70,\n70,\n69,\n69,\n69,\n68,\n68,\n67,\n67,\n66,\n66,\n65,\n65,\n64,\n64,\n63,\n63,\n62,\n62,\n61,\n61,\n60,\n60,\n59,\n59,\n58,\n57,\n57,\n56,\n56,\n55,\n55,\n54,\n53,\n53,\n52,\n51,\n51,\n50,\n50,\n49,\n48,\n48,\n47,\n46,\n46,\n45,\n44,\n44,\n43,\n42,\n41,\n41,\n40,\n39,\n39,\n38,\n37,\n37,\n36,\n35,\n34,\n34,\n33,\n32,\n31,\n31,\n30,\n29,\n28,\n28,\n27,\n26,\n25,\n25,\n24,\n23,\n22,\n22,\n21,\n20,\n19,\n19,\n18,\n17,\n16,\n16,\n15,\n14,\n13,\n12,\n12,\n11,\n10,\n9,\n9,\n8,\n7,\n6,\n6,\n5,\n4,\n3,\n3,\n2,\n1,\n0,\n0,\n0,\n-1,\n-2,\n-2,\n-3,\n-4,\n-5,\n-5,\n-6,\n-7,\n-8,\n-8,\n-9,\n-10,\n-10,\n-11,\n-12,\n-13,\n-13,\n-14,\n-15,\n-15,\n-16,\n-17,\n-17,\n-18,\n-19,\n-19,\n-20,\n-21,\n-21,\n-22,\n-23,\n-23,\n-24,\n-25,\n-25,\n-26,\n-27,\n-27,\n-28,\n-28,\n-29,\n-30,\n-30,\n-31,\n-31,\n-32,\n-33,\n-33,\n-34,\n-34,\n-35,\n-35,\n-36,\n-36,\n-37,\n-37,\n-38,\n-38,\n-39,\n-39,\n-40,\n-40,\n-41,\n-41,\n-42,\n-42,\n-43,\n-43,\n-44,\n-44,\n-45,\n-45,\n-45,\n-46,\n-46,\n-47,\n-47,\n-47,\n-48,\n-48,\n-49,\n-49,\n-49,\n-50,\n-50,\n-50,\n-51,\n-51,\n-51,\n-51,\n-52,\n-52,\n-52,\n-53,\n-53,\n-53,\n-53,\n-54,\n-54,\n-54,\n-54,\n-54,\n-55,\n-55,\n-55,\n-55,\n-55,\n-56,\n-56,\n-56,\n-56,\n-56,\n-56,\n-56,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-57,\n-56,\n-56,\n-56,\n-56,\n-56,\n-56,\n-56,\n-55,\n-55,\n-55,\n-55,\n-55,\n-54,\n-54,\n-54,\n-54,\n-54,\n-53,\n-53,\n-53,\n-53,\n-52,\n-52,\n-52,\n-52,\n-51,\n-51,\n-51,\n-50,\n-50,\n-50,\n-50,\n-49,\n-49,\n-49,\n-48,\n-48,\n-48,\n-47,\n-47,\n-46,\n-46,\n-46,\n-45,\n-45,\n-45,\n-44,\n-44,\n-43,\n-43,\n-43,\n-42,\n-42,\n-41,\n-41,\n-40,\n-40,\n-40,\n-39,\n-39,\n-38,\n-38,\n-37,\n-37,\n-36,\n-36,\n-35,\n-35,\n-35,\n-34,\n-34,\n-33,\n-33,\n-32,\n-32,\n-31,\n-31,\n-30,\n-30,\n-29,\n-29,\n-28,\n-28,\n-27,\n-26,\n-26,\n-25,\n-25,\n-24,\n-24,\n-23,\n-23,\n-22,\n-22,\n-21,\n-21,\n-20,\n-19,\n-19,\n-18,\n-18,\n-17,\n-17,\n-16,\n-16,\n-15,\n-15,\n-14,\n-13,\n-13,\n-12,\n-12,\n-11,\n-11,\n-10,\n-9,\n-9,\n-8,\n-8,\n-7,\n-7,\n-6,\n-6,\n-5,\n-4,\n-4,\n-3,\n-3,\n-2,\n-2,\n-1,\n-1,\n0,\n0,\n0,\n1,\n1,\n2,\n2,\n3,\n3,\n4,\n4,\n5,\n5,\n6,\n7,\n7,\n8,\n8,\n9,\n9,\n10,\n10,\n11,\n11,\n12,\n12,\n13,\n13,\n14,\n14,\n15,\n15,\n16,\n16,\n17,\n17,\n18,\n18,\n18,\n19,\n19,\n20,\n20,\n21,\n21,\n22,\n22,\n22,\n23,\n23,\n24,\n24,\n25,\n25,\n25,\n26,\n26,\n27,\n27,\n27,\n28,\n28,\n28,\n29,\n29,\n30,\n30,\n30,\n31,\n31,\n31,\n32,\n32,\n32,\n33,\n33,\n33,\n33,\n34,\n34,\n34,\n35,\n35,\n35,\n35,\n36,\n36,\n36,\n36,\n37,\n37,\n37,\n37,\n38,\n38,\n38,\n38,\n38,\n39,\n39,\n39,\n39,\n39,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n41,\n41,\n41,\n41,\n41,\n41,\n41,\n41,\n41,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n42,\n41,\n41,\n41,\n41,\n41,\n41,\n41,\n41,\n41,\n41,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n39,\n39,\n39,\n39,\n39,\n38,\n38,\n38,\n38,\n38,\n37,\n37,\n37,\n37,\n37,\n36,\n36,\n36,\n36,\n35,\n35,\n35,\n35,\n34,\n34,\n34,\n34,\n33,\n33,\n33,\n33,\n32,\n32,\n32,\n31,\n31,\n31,\n30,\n30,\n30,\n30,\n29,\n29,\n29,\n28,\n28,\n28,\n27,\n27,\n27,\n26,\n26,\n26,\n25,\n25,\n25,\n24,\n24,\n23,\n23,\n23,\n22,\n22,\n22,\n21,\n21,\n21,\n20,\n20,\n19,\n19,\n19,\n18,\n18,\n18,\n17,\n17,\n16,\n16,\n16,\n15,\n15,\n14,\n14,\n14,\n13,\n13,\n12,\n12,\n12,\n11,\n11,\n10,\n10,\n10,\n9,\n9,\n8,\n8,\n8,\n7,\n7,\n6,\n6,\n6,\n5,\n5,\n4,\n4,\n4,\n3,\n3,\n2,\n2,\n2,\n1,\n1,\n1,\n0,\n0,\n0,\n0,\n0,\n-1,\n-1,\n-2,\n-2,\n-2,\n-3,\n-3,\n-3,\n-4,\n-4,\n-5,\n-5,\n-5,\n-6,\n-6,\n-6,\n-7,\n-7,\n-7,\n-8,\n-8,\n-9,\n-9,\n-9,\n-10,\n-10,\n-10,\n-11,\n-11,\n-11,\n-12,\n-12,\n-12,\n-13,\n-13,\n-13,\n-14,\n-14,\n-14,\n-14,\n-15,\n-15,\n-15,\n-16,\n-16,\n-16,\n-17,\n-17,\n-17,\n-17,\n-18,\n-18,\n-18,\n-19,\n-19,\n-19,\n-19,\n-20,\n-20,\n-20,\n-20,\n-21,\n-21,\n-21,\n-21,\n-21,\n-22,\n-22,\n-22,\n-22,\n-23,\n-23,\n-23,\n-23,\n-23,\n-24,\n-24,\n-24,\n-24,\n-24,\n-25,\n-25,\n-25,\n-25,\n-25,\n-25,\n-26,\n-26,\n-26,\n-26,\n-26,\n-26,\n-26,\n-27,\n-27,\n-27,\n-27,\n-27,\n-27,\n-27,\n-27,\n-27,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-29,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-28,\n-27,\n-27,\n-27,\n-27,\n-27,\n-27,\n-27,\n-27,\n-27,\n-27,\n-26,\n-26,\n-26,\n-26,\n-26,\n-26,\n-26,\n-25,\n-25,\n-25,\n-25,\n-25,\n-25,\n-25,\n-24,\n-24,\n-24,\n-24,\n-24,\n-24,\n-23,\n-23,\n-23,\n-23,\n-23,\n-22,\n-22,\n-22,\n-22,\n-22,\n-21,\n-21,\n-21,\n-21,\n-21,\n-20,\n-20,\n-20,\n-20,\n-20,\n-19,\n-19,\n-19,\n-19,\n-18,\n-18,\n-18,\n-18,\n-17,\n-17,\n-17,\n-17,\n-16,\n-16,\n-16,\n-16,\n-15,\n-15,\n-15,\n-15,\n-14,\n-14,\n-14,\n-14,\n-13,\n-13,\n-13,\n-13,\n-12,\n-12,\n-12,\n-12,\n-11,\n-11,\n-11,\n-11,\n-10,\n-10,\n-10,\n-9,\n-9,\n-9,\n-9,\n-8,\n-8,\n-8,\n-7,\n-7,\n-7,\n-7,\n-6,\n-6,\n-6,\n-6,\n-5,\n-5,\n-5,\n-4,\n-4,\n-4,\n-4,\n-3,\n-3,\n-3,\n-2,\n-2,\n-2,\n-2,\n-1,\n-1,\n-1,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n1,\n1,\n1,\n2,\n2,\n2,\n2,\n3,\n3,\n3,\n3,\n4,\n4,\n4,\n5,\n5,\n5,\n5,\n6,\n6,\n6,\n6,\n6,\n7,\n7,\n7,\n7,\n8,\n8,\n8,\n8,\n9,\n9,\n9,\n9,\n10,\n10,\n10,\n10,\n10,\n11,\n11,\n11,\n11,\n11,\n12,\n12,\n12,\n12,\n12,\n13,\n13,\n13,\n13,\n13,\n14,\n14,\n14,\n14,\n14,\n14,\n15,\n15,\n15,\n15,\n15,\n15,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n17,\n17,\n17,\n17,\n17,\n17,\n17,\n17,\n18,\n18,\n18,\n18,\n18,\n18,\n18,\n18,\n18,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n20,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n19,\n18,\n18,\n18,\n18,\n18,\n18,\n18,\n18,\n18,\n18,\n17,\n17,\n17,\n17,\n17,\n17,\n17,\n17,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n15,\n15,\n15,\n15,\n15,\n15,\n15,\n14,\n14,\n14,\n14,\n14,\n14,\n14,\n13,\n13,\n13,\n13,\n13,\n13,\n12,\n12,\n12,\n12,\n12,\n12,\n11,\n11,\n11,\n11,\n11,\n11,\n10,\n10,\n10,\n10,\n10,\n9,\n9,\n9,\n9,\n9,\n9,\n8,\n8,\n8,\n8,\n8,\n7,\n7,\n7,\n7,\n7,\n7,\n6,\n6,\n6,\n6,\n6,\n5,\n5,\n5,\n5,\n5,\n4,\n4,\n4,\n4,\n4,\n4,\n3,\n3,\n3,\n3,\n3,\n2,\n2,\n2,\n2,\n2,\n2,\n1,\n1,\n1,\n1,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-7,\n-7,\n-7,\n-7,\n-7,\n-7,\n-7,\n-7,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-7,\n-7,\n-7,\n-7,\n-7,\n-7,\n-7,\n-7,\n-7,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n8,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0};\n\nstatic const RES_HWORD LARGE_FILTER_IMPD[] /* Impulse response differences */ = {\n-1,\n-2,\n-3,\n-5,\n-6,\n-7,\n-9,\n-10,\n-11,\n-13,\n-14,\n-15,\n-17,\n-18,\n-19,\n-21,\n-22,\n-23,\n-25,\n-26,\n-27,\n-28,\n-30,\n-32,\n-32,\n-34,\n-35,\n-36,\n-38,\n-39,\n-40,\n-42,\n-43,\n-44,\n-45,\n-47,\n-48,\n-49,\n-51,\n-52,\n-53,\n-54,\n-56,\n-56,\n-58,\n-60,\n-60,\n-62,\n-63,\n-64,\n-66,\n-66,\n-68,\n-69,\n-70,\n-72,\n-72,\n-74,\n-75,\n-76,\n-77,\n-79,\n-79,\n-81,\n-82,\n-83,\n-84,\n-85,\n-87,\n-87,\n-89,\n-90,\n-90,\n-92,\n-93,\n-94,\n-95,\n-96,\n-98,\n-98,\n-99,\n-100,\n-102,\n-102,\n-103,\n-105,\n-105,\n-106,\n-108,\n-108,\n-109,\n-110,\n-111,\n-112,\n-113,\n-114,\n-115,\n-116,\n-116,\n-118,\n-118,\n-119,\n-121,\n-120,\n-122,\n-123,\n-123,\n-125,\n-125,\n-126,\n-126,\n-128,\n-128,\n-129,\n-130,\n-130,\n-132,\n-132,\n-132,\n-134,\n-134,\n-135,\n-135,\n-136,\n-137,\n-137,\n-138,\n-139,\n-139,\n-140,\n-141,\n-141,\n-142,\n-142,\n-143,\n-143,\n-144,\n-145,\n-145,\n-145,\n-146,\n-147,\n-147,\n-147,\n-148,\n-149,\n-148,\n-150,\n-149,\n-150,\n-151,\n-151,\n-151,\n-152,\n-152,\n-152,\n-153,\n-153,\n-153,\n-153,\n-154,\n-154,\n-155,\n-155,\n-155,\n-155,\n-155,\n-156,\n-156,\n-156,\n-156,\n-156,\n-157,\n-157,\n-157,\n-157,\n-157,\n-157,\n-157,\n-158,\n-157,\n-158,\n-158,\n-157,\n-158,\n-158,\n-158,\n-158,\n-157,\n-158,\n-158,\n-158,\n-157,\n-158,\n-158,\n-157,\n-158,\n-157,\n-157,\n-157,\n-157,\n-157,\n-157,\n-157,\n-156,\n-156,\n-156,\n-156,\n-156,\n-155,\n-155,\n-155,\n-155,\n-155,\n-154,\n-154,\n-153,\n-154,\n-153,\n-153,\n-152,\n-152,\n-152,\n-151,\n-151,\n-151,\n-150,\n-150,\n-150,\n-149,\n-149,\n-148,\n-148,\n-147,\n-147,\n-147,\n-146,\n-145,\n-145,\n-145,\n-144,\n-144,\n-143,\n-142,\n-142,\n-142,\n-141,\n-140,\n-140,\n-139,\n-139,\n-138,\n-137,\n-137,\n-136,\n-136,\n-135,\n-134,\n-134,\n-133,\n-132,\n-132,\n-131,\n-130,\n-130,\n-129,\n-128,\n-128,\n-126,\n-126,\n-126,\n-125,\n-123,\n-124,\n-122,\n-122,\n-121,\n-120,\n-119,\n-119,\n-117,\n-117,\n-117,\n-115,\n-114,\n-113,\n-113,\n-112,\n-112,\n-110,\n-110,\n-108,\n-108,\n-107,\n-106,\n-106,\n-104,\n-104,\n-102,\n-102,\n-101,\n-100,\n-99,\n-98,\n-98,\n-96,\n-95,\n-95,\n-94,\n-92,\n-92,\n-91,\n-90,\n-89,\n-88,\n-87,\n-86,\n-85,\n-85,\n-83,\n-82,\n-82,\n-80,\n-80,\n-78,\n-78,\n-76,\n-76,\n-75,\n-73,\n-73,\n-72,\n-70,\n-70,\n-69,\n-68,\n-66,\n-66,\n-65,\n-64,\n-63,\n-61,\n-61,\n-60,\n-59,\n-58,\n-57,\n-56,\n-55,\n-54,\n-53,\n-51,\n-51,\n-50,\n-49,\n-48,\n-47,\n-46,\n-45,\n-44,\n-43,\n-42,\n-41,\n-41,\n-39,\n-38,\n-37,\n-36,\n-35,\n-34,\n-34,\n-32,\n-31,\n-31,\n-29,\n-28,\n-28,\n-26,\n-26,\n-24,\n-24,\n-23,\n-21,\n-21,\n-20,\n-19,\n-18,\n-17,\n-16,\n-15,\n-14,\n-13,\n-13,\n-11,\n-11,\n-9,\n-9,\n-8,\n-7,\n-6,\n-5,\n-5,\n-3,\n-2,\n-2,\n-1,\n0,\n1,\n2,\n2,\n4,\n4,\n5,\n6,\n7,\n8,\n8,\n10,\n10,\n11,\n11,\n13,\n13,\n14,\n15,\n15,\n17,\n17,\n18,\n18,\n20,\n20,\n21,\n21,\n23,\n23,\n23,\n25,\n25,\n26,\n26,\n27,\n28,\n28,\n30,\n29,\n31,\n31,\n32,\n32,\n33,\n34,\n34,\n35,\n35,\n36,\n37,\n37,\n37,\n39,\n39,\n39,\n40,\n40,\n41,\n42,\n42,\n42,\n43,\n44,\n44,\n44,\n45,\n46,\n45,\n47,\n46,\n48,\n47,\n48,\n49,\n49,\n49,\n49,\n50,\n51,\n51,\n51,\n51,\n52,\n52,\n53,\n53,\n53,\n53,\n54,\n54,\n54,\n55,\n55,\n55,\n55,\n56,\n56,\n56,\n56,\n57,\n57,\n57,\n57,\n58,\n57,\n58,\n58,\n58,\n58,\n59,\n58,\n59,\n59,\n59,\n59,\n59,\n59,\n59,\n60,\n59,\n60,\n59,\n60,\n60,\n60,\n59,\n60,\n60,\n60,\n60,\n59,\n60,\n60,\n60,\n60,\n59,\n60,\n60,\n59,\n60,\n59,\n60,\n59,\n59,\n59,\n59,\n59,\n59,\n59,\n58,\n59,\n58,\n58,\n58,\n58,\n57,\n58,\n57,\n57,\n57,\n57,\n55,\n57,\n56,\n56,\n55,\n56,\n55,\n55,\n54,\n55,\n54,\n54,\n54,\n53,\n53,\n53,\n52,\n53,\n52,\n51,\n52,\n51,\n50,\n51,\n50,\n49,\n50,\n49,\n48,\n49,\n48,\n47,\n47,\n47,\n47,\n46,\n46,\n45,\n45,\n45,\n44,\n44,\n43,\n43,\n42,\n43,\n41,\n42,\n40,\n41,\n40,\n39,\n40,\n38,\n39,\n37,\n38,\n37,\n36,\n36,\n35,\n36,\n34,\n34,\n34,\n33,\n33,\n32,\n32,\n31,\n31,\n30,\n30,\n29,\n29,\n28,\n28,\n27,\n27,\n26,\n26,\n25,\n25,\n24,\n24,\n24,\n22,\n23,\n21,\n21,\n21,\n20,\n20,\n19,\n19,\n18,\n18,\n17,\n16,\n16,\n16,\n15,\n14,\n14,\n14,\n13,\n12,\n12,\n11,\n11,\n11,\n9,\n10,\n8,\n9,\n7,\n8,\n6,\n7,\n5,\n5,\n5,\n4,\n4,\n3,\n3,\n2,\n1,\n1,\n1,\n0,\n0,\n-1,\n-1,\n-2,\n-3,\n-3,\n-3,\n-4,\n-4,\n-5,\n-5,\n-6,\n-6,\n-7,\n-7,\n-8,\n-8,\n-8,\n-9,\n-10,\n-10,\n-10,\n-11,\n-11,\n-12,\n-12,\n-13,\n-13,\n-14,\n-14,\n-14,\n-15,\n-15,\n-16,\n-16,\n-16,\n-17,\n-18,\n-17,\n-18,\n-19,\n-19,\n-19,\n-20,\n-20,\n-21,\n-20,\n-22,\n-21,\n-22,\n-23,\n-22,\n-23,\n-24,\n-23,\n-25,\n-24,\n-25,\n-25,\n-25,\n-26,\n-26,\n-27,\n-26,\n-27,\n-28,\n-27,\n-28,\n-28,\n-29,\n-29,\n-29,\n-29,\n-30,\n-30,\n-30,\n-30,\n-31,\n-31,\n-31,\n-31,\n-32,\n-32,\n-32,\n-32,\n-33,\n-33,\n-33,\n-33,\n-33,\n-34,\n-34,\n-34,\n-34,\n-34,\n-35,\n-34,\n-35,\n-35,\n-35,\n-36,\n-35,\n-36,\n-35,\n-36,\n-36,\n-36,\n-37,\n-36,\n-36,\n-37,\n-37,\n-36,\n-37,\n-37,\n-37,\n-37,\n-37,\n-38,\n-37,\n-37,\n-38,\n-37,\n-38,\n-37,\n-38,\n-37,\n-38,\n-38,\n-37,\n-38,\n-38,\n-37,\n-38,\n-38,\n-37,\n-38,\n-38,\n-37,\n-38,\n-37,\n-38,\n-37,\n-38,\n-37,\n-38,\n-37,\n-37,\n-37,\n-37,\n-37,\n-37,\n-37,\n-37,\n-35,\n-37,\n-36,\n-37,\n-36,\n-36,\n-36,\n-36,\n-36,\n-35,\n-36,\n-35,\n-36,\n-35,\n-35,\n-34,\n-35,\n-34,\n-35,\n-34,\n-34,\n-34,\n-33,\n-34,\n-33,\n-33,\n-33,\n-32,\n-33,\n-32,\n-32,\n-32,\n-32,\n-31,\n-31,\n-31,\n-31,\n-31,\n-30,\n-30,\n-30,\n-29,\n-30,\n-29,\n-29,\n-28,\n-28,\n-29,\n-27,\n-28,\n-27,\n-27,\n-27,\n-26,\n-27,\n-25,\n-26,\n-25,\n-26,\n-24,\n-25,\n-24,\n-24,\n-23,\n-24,\n-23,\n-22,\n-23,\n-22,\n-22,\n-21,\n-21,\n-21,\n-21,\n-20,\n-20,\n-19,\n-19,\n-19,\n-19,\n-18,\n-18,\n-18,\n-17,\n-17,\n-17,\n-16,\n-16,\n-15,\n-16,\n-14,\n-15,\n-14,\n-14,\n-14,\n-13,\n-13,\n-12,\n-12,\n-12,\n-12,\n-11,\n-10,\n-11,\n-10,\n-10,\n-9,\n-9,\n-9,\n-8,\n-8,\n-8,\n-7,\n-7,\n-6,\n-6,\n-6,\n-6,\n-5,\n-5,\n-4,\n-4,\n-4,\n-3,\n-3,\n-3,\n-2,\n-2,\n-2,\n-1,\n-1,\n-1,\n0,\n0,\n0,\n1,\n1,\n2,\n1,\n3,\n2,\n3,\n3,\n4,\n3,\n4,\n5,\n5,\n5,\n5,\n6,\n6,\n7,\n6,\n8,\n7,\n8,\n8,\n8,\n9,\n9,\n9,\n10,\n9,\n11,\n10,\n11,\n11,\n11,\n12,\n12,\n12,\n13,\n13,\n13,\n13,\n14,\n14,\n14,\n14,\n15,\n15,\n15,\n16,\n16,\n16,\n16,\n17,\n16,\n18,\n17,\n17,\n18,\n18,\n18,\n19,\n19,\n19,\n19,\n19,\n20,\n19,\n20,\n21,\n20,\n21,\n21,\n21,\n21,\n21,\n22,\n22,\n22,\n22,\n22,\n23,\n22,\n23,\n23,\n23,\n23,\n24,\n24,\n23,\n24,\n24,\n24,\n25,\n24,\n25,\n24,\n25,\n25,\n25,\n25,\n26,\n25,\n26,\n25,\n26,\n26,\n25,\n26,\n26,\n26,\n27,\n26,\n26,\n27,\n26,\n27,\n26,\n27,\n26,\n27,\n27,\n27,\n26,\n27,\n27,\n27,\n27,\n27,\n27,\n27,\n27,\n27,\n27,\n27,\n27,\n27,\n27,\n27,\n27,\n27,\n26,\n27,\n27,\n27,\n27,\n26,\n27,\n27,\n26,\n26,\n26,\n27,\n26,\n26,\n27,\n26,\n26,\n26,\n26,\n26,\n26,\n25,\n26,\n25,\n26,\n25,\n25,\n25,\n25,\n25,\n25,\n25,\n24,\n24,\n25,\n24,\n24,\n24,\n23,\n24,\n24,\n23,\n23,\n23,\n23,\n23,\n22,\n23,\n22,\n22,\n22,\n22,\n21,\n22,\n21,\n21,\n21,\n21,\n20,\n20,\n21,\n20,\n19,\n20,\n19,\n19,\n19,\n19,\n19,\n18,\n18,\n18,\n18,\n18,\n17,\n17,\n17,\n17,\n16,\n16,\n16,\n16,\n16,\n15,\n15,\n15,\n14,\n15,\n14,\n14,\n14,\n13,\n13,\n13,\n13,\n12,\n13,\n12,\n11,\n12,\n11,\n11,\n11,\n10,\n11,\n10,\n9,\n10,\n9,\n9,\n9,\n8,\n9,\n8,\n7,\n8,\n7,\n7,\n7,\n6,\n6,\n6,\n6,\n5,\n5,\n5,\n5,\n4,\n4,\n4,\n3,\n4,\n3,\n3,\n2,\n2,\n2,\n2,\n2,\n1,\n1,\n0,\n1,\n0,\n0,\n0,\n-1,\n-1,\n-1,\n-1,\n-2,\n-2,\n-2,\n-2,\n-3,\n-2,\n-4,\n-3,\n-3,\n-4,\n-4,\n-5,\n-4,\n-5,\n-5,\n-5,\n-6,\n-6,\n-6,\n-6,\n-7,\n-6,\n-7,\n-7,\n-8,\n-7,\n-8,\n-8,\n-9,\n-8,\n-9,\n-9,\n-9,\n-10,\n-9,\n-10,\n-10,\n-10,\n-11,\n-10,\n-11,\n-11,\n-12,\n-11,\n-12,\n-12,\n-12,\n-12,\n-13,\n-12,\n-13,\n-13,\n-13,\n-14,\n-13,\n-14,\n-14,\n-14,\n-14,\n-15,\n-14,\n-15,\n-15,\n-15,\n-15,\n-16,\n-15,\n-16,\n-16,\n-16,\n-16,\n-16,\n-17,\n-16,\n-17,\n-17,\n-17,\n-17,\n-17,\n-18,\n-17,\n-18,\n-18,\n-17,\n-18,\n-18,\n-19,\n-18,\n-18,\n-19,\n-18,\n-19,\n-19,\n-19,\n-19,\n-19,\n-19,\n-19,\n-19,\n-20,\n-19,\n-20,\n-19,\n-20,\n-20,\n-20,\n-19,\n-20,\n-20,\n-20,\n-20,\n-20,\n-21,\n-20,\n-20,\n-20,\n-21,\n-20,\n-20,\n-21,\n-20,\n-21,\n-20,\n-20,\n-21,\n-20,\n-21,\n-20,\n-21,\n-20,\n-21,\n-20,\n-21,\n-21,\n-20,\n-20,\n-21,\n-20,\n-21,\n-20,\n-21,\n-20,\n-20,\n-20,\n-20,\n-20,\n-20,\n-20,\n-20,\n-20,\n-20,\n-20,\n-20,\n-20,\n-20,\n-19,\n-20,\n-20,\n-19,\n-20,\n-19,\n-19,\n-19,\n-20,\n-19,\n-19,\n-18,\n-19,\n-19,\n-19,\n-18,\n-18,\n-19,\n-18,\n-18,\n-18,\n-18,\n-18,\n-18,\n-17,\n-18,\n-17,\n-17,\n-17,\n-17,\n-17,\n-17,\n-16,\n-17,\n-16,\n-16,\n-17,\n-15,\n-16,\n-16,\n-15,\n-16,\n-15,\n-15,\n-15,\n-15,\n-15,\n-14,\n-14,\n-15,\n-14,\n-13,\n-14,\n-14,\n-13,\n-13,\n-13,\n-13,\n-13,\n-13,\n-12,\n-12,\n-12,\n-12,\n-12,\n-11,\n-12,\n-11,\n-11,\n-11,\n-10,\n-11,\n-10,\n-10,\n-10,\n-9,\n-10,\n-9,\n-9,\n-9,\n-9,\n-9,\n-8,\n-8,\n-8,\n-8,\n-8,\n-7,\n-7,\n-7,\n-7,\n-7,\n-6,\n-6,\n-6,\n-6,\n-6,\n-5,\n-5,\n-6,\n-4,\n-5,\n-4,\n-5,\n-4,\n-4,\n-3,\n-4,\n-3,\n-3,\n-3,\n-2,\n-3,\n-2,\n-2,\n-2,\n-1,\n-2,\n-1,\n-1,\n-1,\n0,\n-1,\n0,\n0,\n0,\n1,\n0,\n1,\n1,\n1,\n1,\n2,\n2,\n2,\n2,\n2,\n3,\n3,\n2,\n4,\n3,\n3,\n4,\n4,\n4,\n4,\n5,\n4,\n5,\n5,\n5,\n6,\n5,\n6,\n6,\n6,\n6,\n7,\n6,\n7,\n7,\n7,\n7,\n8,\n7,\n8,\n8,\n8,\n8,\n9,\n8,\n9,\n9,\n9,\n9,\n10,\n9,\n10,\n10,\n10,\n10,\n10,\n11,\n10,\n11,\n11,\n11,\n11,\n11,\n11,\n12,\n11,\n12,\n12,\n12,\n12,\n12,\n13,\n12,\n13,\n13,\n12,\n13,\n13,\n14,\n13,\n13,\n14,\n13,\n14,\n14,\n13,\n14,\n14,\n15,\n14,\n14,\n14,\n15,\n14,\n15,\n15,\n14,\n15,\n15,\n15,\n15,\n15,\n16,\n15,\n15,\n15,\n16,\n15,\n16,\n15,\n16,\n15,\n16,\n16,\n16,\n15,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n17,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n16,\n15,\n16,\n16,\n16,\n16,\n16,\n15,\n16,\n16,\n15,\n16,\n16,\n15,\n15,\n16,\n15,\n16,\n15,\n15,\n15,\n15,\n15,\n15,\n15,\n15,\n15,\n14,\n15,\n14,\n15,\n14,\n14,\n15,\n14,\n14,\n14,\n14,\n13,\n14,\n14,\n13,\n13,\n14,\n13,\n13,\n13,\n13,\n13,\n12,\n13,\n12,\n13,\n12,\n12,\n12,\n12,\n12,\n12,\n11,\n12,\n11,\n11,\n11,\n11,\n11,\n11,\n10,\n11,\n10,\n10,\n10,\n10,\n10,\n10,\n9,\n10,\n9,\n9,\n9,\n9,\n8,\n9,\n8,\n9,\n8,\n8,\n8,\n7,\n8,\n7,\n7,\n7,\n7,\n7,\n7,\n6,\n7,\n6,\n6,\n6,\n5,\n6,\n5,\n5,\n6,\n4,\n5,\n5,\n4,\n5,\n4,\n4,\n4,\n3,\n4,\n3,\n3,\n3,\n3,\n3,\n2,\n3,\n2,\n2,\n2,\n2,\n1,\n2,\n1,\n1,\n1,\n1,\n1,\n0,\n0,\n1,\n0,\n-1,\n0,\n0,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-2,\n-2,\n-2,\n-2,\n-2,\n-3,\n-2,\n-3,\n-3,\n-3,\n-3,\n-4,\n-3,\n-4,\n-4,\n-4,\n-4,\n-4,\n-5,\n-4,\n-5,\n-5,\n-5,\n-5,\n-5,\n-6,\n-5,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-7,\n-6,\n-7,\n-7,\n-7,\n-7,\n-7,\n-7,\n-8,\n-8,\n-7,\n-8,\n-8,\n-8,\n-8,\n-9,\n-8,\n-9,\n-8,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-10,\n-9,\n-10,\n-9,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-11,\n-10,\n-11,\n-10,\n-11,\n-11,\n-11,\n-10,\n-11,\n-11,\n-12,\n-11,\n-11,\n-11,\n-12,\n-11,\n-12,\n-12,\n-11,\n-12,\n-12,\n-12,\n-11,\n-12,\n-12,\n-13,\n-12,\n-12,\n-12,\n-12,\n-13,\n-12,\n-12,\n-13,\n-12,\n-13,\n-12,\n-13,\n-12,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-13,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-13,\n-11,\n-13,\n-13,\n-12,\n-13,\n-13,\n-12,\n-13,\n-12,\n-13,\n-12,\n-13,\n-12,\n-13,\n-12,\n-12,\n-13,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-11,\n-12,\n-12,\n-11,\n-12,\n-11,\n-11,\n-12,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-10,\n-11,\n-10,\n-11,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-9,\n-10,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-8,\n-9,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-7,\n-7,\n-8,\n-7,\n-7,\n-7,\n-7,\n-6,\n-7,\n-7,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-5,\n-6,\n-5,\n-5,\n-5,\n-5,\n-5,\n-4,\n-5,\n-4,\n-5,\n-4,\n-4,\n-4,\n-4,\n-3,\n-4,\n-3,\n-4,\n-3,\n-3,\n-3,\n-3,\n-2,\n-3,\n-2,\n-2,\n-3,\n-2,\n-1,\n-2,\n-2,\n-1,\n-2,\n-1,\n-1,\n-1,\n-1,\n-1,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n1,\n1,\n0,\n2,\n1,\n1,\n1,\n2,\n2,\n1,\n2,\n2,\n3,\n2,\n2,\n3,\n2,\n3,\n3,\n3,\n3,\n3,\n4,\n3,\n4,\n4,\n3,\n4,\n4,\n4,\n5,\n4,\n5,\n4,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n6,\n5,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n6,\n7,\n6,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n7,\n8,\n7,\n8,\n8,\n7,\n8,\n8,\n8,\n8,\n8,\n8,\n9,\n8,\n9,\n8,\n9,\n8,\n9,\n9,\n8,\n9,\n9,\n9,\n9,\n9,\n10,\n9,\n9,\n9,\n10,\n9,\n10,\n9,\n10,\n10,\n9,\n10,\n10,\n9,\n10,\n10,\n10,\n10,\n10,\n10,\n10,\n10,\n10,\n10,\n11,\n10,\n10,\n10,\n10,\n11,\n10,\n10,\n11,\n10,\n10,\n11,\n10,\n10,\n11,\n10,\n10,\n11,\n10,\n11,\n10,\n11,\n10,\n10,\n11,\n10,\n10,\n11,\n10,\n11,\n10,\n10,\n10,\n10,\n10,\n10,\n11,\n10,\n10,\n10,\n10,\n11,\n10,\n10,\n10,\n10,\n10,\n10,\n10,\n10,\n9,\n10,\n10,\n10,\n9,\n10,\n10,\n9,\n10,\n9,\n10,\n9,\n9,\n10,\n9,\n9,\n9,\n9,\n9,\n9,\n9,\n9,\n9,\n8,\n9,\n9,\n8,\n9,\n8,\n8,\n9,\n8,\n8,\n8,\n8,\n8,\n8,\n7,\n8,\n8,\n7,\n8,\n7,\n7,\n8,\n7,\n7,\n7,\n7,\n6,\n7,\n7,\n6,\n7,\n6,\n7,\n6,\n6,\n6,\n6,\n6,\n6,\n5,\n6,\n5,\n6,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n4,\n5,\n4,\n5,\n4,\n4,\n4,\n4,\n4,\n4,\n3,\n4,\n3,\n4,\n3,\n3,\n3,\n3,\n3,\n3,\n2,\n3,\n2,\n2,\n3,\n2,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-3,\n-2,\n-3,\n-2,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-4,\n-3,\n-4,\n-3,\n-4,\n-4,\n-3,\n-4,\n-4,\n-5,\n-4,\n-4,\n-4,\n-5,\n-4,\n-5,\n-5,\n-5,\n-4,\n-5,\n-5,\n-6,\n-5,\n-5,\n-5,\n-6,\n-5,\n-6,\n-5,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-7,\n-6,\n-6,\n-7,\n-6,\n-7,\n-7,\n-6,\n-7,\n-7,\n-7,\n-7,\n-7,\n-7,\n-7,\n-7,\n-8,\n-7,\n-7,\n-8,\n-7,\n-8,\n-7,\n-8,\n-7,\n-8,\n-7,\n-8,\n-8,\n-8,\n-8,\n-7,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-9,\n-8,\n-8,\n-8,\n-8,\n-9,\n-8,\n-8,\n-8,\n-9,\n-8,\n-8,\n-9,\n-8,\n-9,\n-8,\n-8,\n-9,\n-8,\n-9,\n-8,\n-9,\n-8,\n-8,\n-9,\n-8,\n-9,\n-8,\n-9,\n-8,\n-9,\n-8,\n-8,\n-9,\n-8,\n-9,\n-8,\n-7,\n-9,\n-8,\n-8,\n-9,\n-8,\n-8,\n-9,\n-8,\n-8,\n-8,\n-8,\n-8,\n-9,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-8,\n-7,\n-8,\n-8,\n-8,\n-7,\n-8,\n-8,\n-7,\n-8,\n-7,\n-8,\n-7,\n-8,\n-7,\n-7,\n-7,\n-8,\n-7,\n-7,\n-7,\n-7,\n-7,\n-7,\n-7,\n-6,\n-7,\n-7,\n-6,\n-7,\n-7,\n-6,\n-6,\n-7,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-5,\n-6,\n-5,\n-6,\n-5,\n-5,\n-6,\n-5,\n-5,\n-5,\n-5,\n-5,\n-4,\n-5,\n-5,\n-4,\n-5,\n-4,\n-5,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-3,\n-4,\n-3,\n-4,\n-3,\n-3,\n-3,\n-4,\n-3,\n-2,\n-3,\n-3,\n-3,\n-2,\n-3,\n-2,\n-3,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-1,\n-1,\n-2,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n2,\n1,\n2,\n1,\n2,\n2,\n2,\n1,\n2,\n2,\n3,\n2,\n2,\n2,\n3,\n2,\n3,\n3,\n2,\n3,\n3,\n3,\n3,\n3,\n3,\n4,\n3,\n3,\n4,\n3,\n4,\n3,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n5,\n4,\n4,\n5,\n5,\n4,\n5,\n5,\n4,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n6,\n5,\n5,\n5,\n6,\n5,\n6,\n5,\n6,\n6,\n5,\n6,\n6,\n6,\n5,\n6,\n6,\n6,\n6,\n6,\n6,\n7,\n6,\n6,\n6,\n6,\n7,\n6,\n6,\n7,\n6,\n7,\n6,\n6,\n7,\n7,\n6,\n7,\n6,\n7,\n6,\n7,\n7,\n7,\n6,\n7,\n7,\n6,\n7,\n7,\n7,\n7,\n6,\n7,\n7,\n7,\n7,\n7,\n6,\n7,\n7,\n7,\n7,\n7,\n7,\n6,\n7,\n7,\n7,\n7,\n7,\n7,\n6,\n7,\n7,\n6,\n7,\n6,\n7,\n7,\n7,\n6,\n7,\n7,\n6,\n7,\n7,\n6,\n7,\n7,\n6,\n7,\n6,\n7,\n6,\n7,\n6,\n6,\n7,\n6,\n6,\n7,\n6,\n6,\n6,\n6,\n6,\n7,\n6,\n6,\n6,\n6,\n5,\n6,\n6,\n6,\n6,\n5,\n6,\n6,\n5,\n6,\n5,\n6,\n5,\n5,\n6,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n5,\n4,\n5,\n4,\n5,\n4,\n5,\n4,\n4,\n4,\n5,\n4,\n4,\n4,\n4,\n3,\n4,\n4,\n4,\n3,\n4,\n3,\n4,\n3,\n3,\n4,\n3,\n3,\n3,\n3,\n3,\n3,\n2,\n3,\n3,\n2,\n3,\n2,\n3,\n2,\n2,\n3,\n2,\n2,\n2,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n1,\n2,\n1,\n1,\n1,\n2,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-2,\n-2,\n-1,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-3,\n-2,\n-3,\n-2,\n-3,\n-3,\n-2,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-4,\n-3,\n-3,\n-4,\n-3,\n-4,\n-3,\n-4,\n-3,\n-4,\n-4,\n-3,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-5,\n-4,\n-4,\n-5,\n-4,\n-4,\n-5,\n-4,\n-5,\n-4,\n-5,\n-5,\n-4,\n-5,\n-5,\n-4,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-6,\n-5,\n-5,\n-5,\n-5,\n-6,\n-5,\n-5,\n-6,\n-5,\n-5,\n-6,\n-5,\n-6,\n-5,\n-6,\n-5,\n-6,\n-5,\n-5,\n-6,\n-6,\n-5,\n-6,\n-5,\n-6,\n-5,\n-6,\n-5,\n-6,\n-5,\n-6,\n-6,\n-5,\n-6,\n-5,\n-6,\n-5,\n-6,\n-5,\n-6,\n-6,\n-5,\n-6,\n-5,\n-5,\n-5,\n-6,\n-5,\n-6,\n-5,\n-6,\n-5,\n-5,\n-6,\n-5,\n-6,\n-5,\n-5,\n-6,\n-5,\n-5,\n-6,\n-5,\n-5,\n-5,\n-6,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-4,\n-5,\n-5,\n-5,\n-4,\n-5,\n-5,\n-4,\n-5,\n-4,\n-5,\n-4,\n-4,\n-5,\n-4,\n-4,\n-5,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-4,\n-3,\n-4,\n-4,\n-3,\n-4,\n-4,\n-3,\n-4,\n-3,\n-3,\n-4,\n-3,\n-3,\n-3,\n-4,\n-3,\n-3,\n-3,\n-3,\n-3,\n-2,\n-3,\n-3,\n-3,\n-2,\n-3,\n-2,\n-3,\n-2,\n-3,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-1,\n-2,\n-2,\n-1,\n-2,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n1,\n2,\n1,\n1,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n2,\n1,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n3,\n2,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n3,\n4,\n3,\n3,\n4,\n3,\n4,\n3,\n4,\n3,\n4,\n3,\n4,\n4,\n3,\n4,\n4,\n4,\n4,\n3,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n5,\n4,\n4,\n4,\n4,\n5,\n4,\n4,\n4,\n5,\n4,\n4,\n5,\n4,\n4,\n5,\n4,\n5,\n4,\n4,\n5,\n4,\n5,\n4,\n5,\n4,\n4,\n5,\n4,\n5,\n4,\n5,\n4,\n5,\n4,\n5,\n4,\n5,\n4,\n5,\n4,\n5,\n4,\n5,\n4,\n5,\n4,\n5,\n3,\n4,\n5,\n4,\n5,\n4,\n4,\n5,\n4,\n5,\n4,\n4,\n5,\n4,\n4,\n5,\n4,\n4,\n4,\n4,\n5,\n4,\n4,\n4,\n4,\n4,\n5,\n4,\n4,\n4,\n4,\n4,\n4,\n4,\n3,\n4,\n4,\n4,\n4,\n4,\n3,\n4,\n4,\n4,\n3,\n4,\n4,\n3,\n4,\n3,\n4,\n3,\n3,\n4,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n2,\n3,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n1,\n2,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-2,\n-2,\n-2,\n-1,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-3,\n-2,\n-3,\n-2,\n-3,\n-2,\n-3,\n-2,\n-3,\n-2,\n-3,\n-3,\n-3,\n-2,\n-3,\n-3,\n-3,\n-3,\n-2,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-4,\n-3,\n-3,\n-3,\n-3,\n-4,\n-3,\n-3,\n-3,\n-4,\n-3,\n-3,\n-4,\n-3,\n-3,\n-4,\n-3,\n-3,\n-4,\n-3,\n-4,\n-3,\n-4,\n-3,\n-4,\n-3,\n-4,\n-3,\n-4,\n-3,\n-4,\n-3,\n-4,\n-3,\n-4,\n-4,\n-3,\n-4,\n-3,\n-4,\n-4,\n-3,\n-4,\n-3,\n-4,\n-4,\n-3,\n-4,\n-3,\n-4,\n-4,\n-3,\n-4,\n-3,\n-4,\n-3,\n-4,\n-4,\n-3,\n-3,\n-3,\n-4,\n-3,\n-4,\n-4,\n-3,\n-4,\n-3,\n-4,\n-3,\n-4,\n-3,\n-3,\n-4,\n-3,\n-4,\n-3,\n-4,\n-3,\n-3,\n-4,\n-3,\n-3,\n-4,\n-3,\n-3,\n-4,\n-3,\n-3,\n-3,\n-3,\n-4,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-3,\n-2,\n-3,\n-3,\n-3,\n-2,\n-3,\n-3,\n-2,\n-3,\n-2,\n-3,\n-2,\n-3,\n-2,\n-3,\n-2,\n-3,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-1,\n-2,\n-2,\n-2,\n-2,\n-1,\n-2,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n2,\n1,\n1,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n2,\n1,\n2,\n2,\n2,\n1,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n3,\n2,\n2,\n2,\n3,\n2,\n2,\n3,\n2,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n3,\n2,\n3,\n2,\n3,\n3,\n2,\n3,\n3,\n3,\n2,\n3,\n3,\n2,\n3,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n3,\n3,\n3,\n2,\n2,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n2,\n3,\n3,\n2,\n3,\n3,\n2,\n3,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n2,\n3,\n2,\n2,\n3,\n2,\n2,\n3,\n2,\n2,\n2,\n2,\n2,\n3,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n1,\n2,\n2,\n2,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n1,\n1,\n2,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-2,\n-2,\n-1,\n-2,\n-2,\n-1,\n-2,\n-2,\n-2,\n-1,\n-2,\n-2,\n-2,\n-2,\n-1,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-3,\n-1,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-3,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-1,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-1,\n-2,\n-2,\n-2,\n-2,\n-1,\n-2,\n-2,\n-2,\n-1,\n-2,\n-2,\n-1,\n-2,\n-1,\n-2,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n2,\n1,\n1,\n1,\n1,\n1,\n1,\n2,\n1,\n1,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n2,\n1,\n2,\n1,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n2,\n2,\n1,\n2,\n2,\n2,\n1,\n2,\n2,\n2,\n1,\n2,\n2,\n2,\n2,\n1,\n2,\n2,\n2,\n1,\n2,\n2,\n2,\n1,\n2,\n2,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n2,\n1,\n2,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n1,\n2,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n1,\n2,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n1,\n2,\n1,\n1,\n1,\n1,\n1,\n2,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n1,\n0,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n2,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n1,\n0,\n1,\n1,\n0,\n1,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0};\n"
  },
  {
    "path": "deps/pjsip/third_party/resample/src/libresample_dll.c",
    "content": "// libresample_dll.cpp : Defines the entry point for the DLL application.\n//\n#include <windows.h>\n\nBOOL APIENTRY DllMain( HANDLE hModule, \n                       DWORD  ul_reason_for_call, \n                       LPVOID lpReserved\n\t\t\t\t\t )\n{\n    return TRUE;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/resample/src/resample.h",
    "content": "/*\n * The configuration constants below govern\n * the number of bits in the input sample and filter coefficients, the \n * number of bits to the right of the binary-point for fixed-point math, etc.\n *\n */\n\n/* Conversion constants */\n#define Nhc       8\n#define Na        7\n#define Np       (Nhc+Na)\n#define Npc      (1<<Nhc)\n#define Amask    ((1<<Na)-1)\n#define Pmask    ((1<<Np)-1)\n#define Nh       16\n#define Nb       16\n#define Nhxn     14\n#define Nhg      (Nh-Nhxn)\n#define NLpScl   13\n\n/* Description of constants:\n *\n * Npc - is the number of look-up values available for the lowpass filter\n *    between the beginning of its impulse response and the \"cutoff time\"\n *    of the filter.  The cutoff time is defined as the reciprocal of the\n *    lowpass-filter cut off frequence in Hz.  For example, if the\n *    lowpass filter were a sinc function, Npc would be the index of the\n *    impulse-response lookup-table corresponding to the first zero-\n *    crossing of the sinc function.  (The inverse first zero-crossing\n *    time of a sinc function equals its nominal cutoff frequency in Hz.)\n *    Npc must be a power of 2 due to the details of the current\n *    implementation. The default value of 512 is sufficiently high that\n *    using linear interpolation to fill in between the table entries\n *    gives approximately 16-bit accuracy in filter coefficients.\n *\n * Nhc - is log base 2 of Npc.\n *\n * Na - is the number of bits devoted to linear interpolation of the\n *    filter coefficients.\n *\n * Np - is Na + Nhc, the number of bits to the right of the binary point\n *    in the integer \"time\" variable. To the left of the point, it indexes\n *    the input array (X), and to the right, it is interpreted as a number\n *    between 0 and 1 sample of the input X.  Np must be less than 16 in\n *    this implementation.\n *\n * Nh - is the number of bits in the filter coefficients. The sum of Nh and\n *    the number of bits in the input data (typically 16) cannot exceed 32.\n *    Thus Nh should be 16.  The largest filter coefficient should nearly\n *    fill 16 bits (32767).\n *\n * Nb - is the number of bits in the input data. The sum of Nb and Nh cannot\n *    exceed 32.\n *\n * Nhxn - is the number of bits to right shift after multiplying each input\n *    sample times a filter coefficient. It can be as great as Nh and as\n *    small as 0. Nhxn = Nh-2 gives 2 guard bits in the multiply-add\n *    accumulation.  If Nhxn=0, the accumulation will soon overflow 32 bits.\n *\n * Nhg - is the number of guard bits in mpy-add accumulation (equal to Nh-Nhxn)\n *\n * NLpScl - is the number of bits allocated to the unity-gain normalization\n *    factor.  The output of the lowpass filter is multiplied by LpScl and\n *    then right-shifted NLpScl bits. To avoid overflow, we must have \n *    Nb+Nhg+NLpScl < 32.\n */\n\n"
  },
  {
    "path": "deps/pjsip/third_party/resample/src/resamplesubs.c",
    "content": "/* $Id: resamplesubs.c 3085 2010-02-01 11:23:54Z nanang $ */\n/*\n * Digital Audio Resampling Home Page located at\n * http://www-ccrma.stanford.edu/~jos/resample/.\n *\n * SOFTWARE FOR SAMPLING-RATE CONVERSION AND FIR DIGITAL FILTER DESIGN\n *\n * Snippet from the resample.1 man page:\n *\n * HISTORY\n *\n * The first version of this software was written by Julius O. Smith III\n * <jos@ccrma.stanford.edu> at CCRMA <http://www-ccrma.stanford.edu> in\n * 1981.  It was called SRCONV and was written in SAIL for PDP-10\n * compatible machines.  The algorithm was first published in\n *\n * Smith, Julius O. and Phil Gossett. ``A Flexible Sampling-Rate\n * Conversion Method,'' Proceedings (2): 19.4.1-19.4.4, IEEE Conference\n * on Acoustics, Speech, and Signal Processing, San Diego, March 1984.\n *\n * An expanded tutorial based on this paper is available at the Digital\n * Audio Resampling Home Page given above.\n *\n * Circa 1988, the SRCONV program was translated from SAIL to C by\n * Christopher Lee Fraley working with Roger Dannenberg at CMU.\n *\n * Since then, the C version has been maintained by jos.\n *\n * Sndlib support was added 6/99 by John Gibson <jgg9c@virginia.edu>.\n *\n * The resample program is free software distributed in accordance\n * with the Lesser GNU Public License (LGPL).  There is NO warranty; not\n * even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n */\n\n/* PJMEDIA modification:\n *  - remove resample(), just use SrcUp, SrcUD, and SrcLinear directly.\n *  - move FilterUp() and FilterUD() from filterkit.c\n *  - move stddefs.h and resample.h to this file.\n *  - const correctness.\n */\n\n#include <resamplesubs.h>\n#include \"config.h\"\n#include \"stddefs.h\"\n#include \"resample.h\"\n\n\n#ifdef _MSC_VER\n#   pragma warning(push, 3)\n//#   pragma warning(disable: 4245)   // Conversion from uint to ushort\n#   pragma warning(disable: 4244)   // Conversion from double to uint\n#   pragma warning(disable: 4146)   // unary minus operator applied to unsigned type, result still unsigned\n#   pragma warning(disable: 4761)   // integral size mismatch in argument; conversion supplied\n#endif\n\n#if defined(RESAMPLE_HAS_SMALL_FILTER) && RESAMPLE_HAS_SMALL_FILTER!=0\n#   include \"smallfilter.h\"\n#else\n#   define SMALL_FILTER_NMULT\t0\n#   define SMALL_FILTER_SCALE\t0\n#   define SMALL_FILTER_NWING\t0\n#   define SMALL_FILTER_IMP\tNULL\n#   define SMALL_FILTER_IMPD\tNULL\n#endif\n\n#if defined(RESAMPLE_HAS_LARGE_FILTER) && RESAMPLE_HAS_LARGE_FILTER!=0\n#   include \"largefilter.h\"\n#else\n#   define LARGE_FILTER_NMULT\t0\n#   define LARGE_FILTER_SCALE\t0\n#   define LARGE_FILTER_NWING\t0\n#   define LARGE_FILTER_IMP\tNULL\n#   define LARGE_FILTER_IMPD\tNULL\n#endif\n\n\n#undef INLINE\n#define INLINE\n#define HAVE_FILTER 0\n\n#ifndef NULL\n#   define NULL\t0\n#endif\n\n\nstatic INLINE RES_HWORD WordToHword(RES_WORD v, int scl)\n{\n    RES_HWORD out;\n    RES_WORD llsb = (1<<(scl-1));\n    v += llsb;\t\t/* round */\n    v >>= scl;\n    if (v>MAX_HWORD) {\n\tv = MAX_HWORD;\n    } else if (v < MIN_HWORD) {\n\tv = MIN_HWORD;\n    }\n    out = (RES_HWORD) v;\n    return out;\n}\n\n/* Sampling rate conversion using linear interpolation for maximum speed.\n */\nstatic int\n  SrcLinear(const RES_HWORD X[], RES_HWORD Y[], double pFactor, RES_UHWORD nx)\n{\n    RES_HWORD iconst;\n    RES_UWORD time = 0;\n    const RES_HWORD *xp;\n    RES_HWORD *Ystart, *Yend;\n    RES_WORD v,x1,x2;\n\n    double dt;                  /* Step through input signal */\n    RES_UWORD dtb;                  /* Fixed-point version of Dt */\n    //RES_UWORD endTime;              /* When time reaches EndTime, return to user */\n\n    dt = 1.0/pFactor;            /* Output sampling period */\n    dtb = dt*(1<<Np) + 0.5;     /* Fixed-point representation */\n\n    Ystart = Y;\n    Yend = Ystart + (unsigned)(nx * pFactor + 0.5);\n    //endTime = time + (1<<Np)*(RES_WORD)nx;\n\n    // Integer round down in dtb calculation may cause (endTime % dtb > 0),\n    // so it may cause resample write pass the output buffer (Y >= Yend).\n    // while (time < endTime)\n    while (Y < Yend)\n    {\n\ticonst = (time) & Pmask;\n\txp = &X[(time)>>Np];      /* Ptr to current input sample */\n\tx1 = *xp++;\n\tx2 = *xp;\n\tx1 *= ((1<<Np)-iconst);\n\tx2 *= iconst;\n\tv = x1 + x2;\n\t*Y++ = WordToHword(v,Np);   /* Deposit output */\n\ttime += dtb;\t\t    /* Move to next sample by time increment */\n    }\n    return (Y - Ystart);            /* Return number of output samples */\n}\n\nstatic RES_WORD FilterUp(const RES_HWORD Imp[], const RES_HWORD ImpD[],\n\t\t     RES_UHWORD Nwing, RES_BOOL Interp,\n\t\t     const RES_HWORD *Xp, RES_HWORD Ph, RES_HWORD Inc)\n{\n    const RES_HWORD *Hp;\n    const RES_HWORD *Hdp = NULL;\n    const RES_HWORD *End;\n    RES_HWORD a = 0;\n    RES_WORD v, t;\n\n    v=0;\n    Hp = &Imp[Ph>>Na];\n    End = &Imp[Nwing];\n    if (Interp) {\n\tHdp = &ImpD[Ph>>Na];\n\ta = Ph & Amask;\n    }\n    if (Inc == 1)\t\t/* If doing right wing...              */\n    {\t\t\t\t/* ...drop extra coeff, so when Ph is  */\n\tEnd--;\t\t\t/*    0.5, we don't do too many mult's */\n\tif (Ph == 0)\t\t/* If the phase is zero...           */\n\t{\t\t\t/* ...then we've already skipped the */\n\t    Hp += Npc;\t\t/*    first sample, so we must also  */\n\t    Hdp += Npc;\t\t/*    skip ahead in Imp[] and ImpD[] */\n\t}\n    }\n    if (Interp)\n      while (Hp < End) {\n\t  t = *Hp;\t\t/* Get filter coeff */\n\t  t += (((RES_WORD)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */\n\t  Hdp += Npc;\t\t/* Filter coeff differences step */\n\t  t *= *Xp;\t\t/* Mult coeff by input sample */\n\t  if (t & (1<<(Nhxn-1)))  /* Round, if needed */\n\t    t += (1<<(Nhxn-1));\n\t  t >>= Nhxn;\t\t/* Leave some guard bits, but come back some */\n\t  v += t;\t\t\t/* The filter output */\n\t  Hp += Npc;\t\t/* Filter coeff step */\n\n\t  Xp += Inc;\t\t/* Input signal step. NO CHECK ON BOUNDS */\n      }\n    else\n      while (Hp < End) {\n\t  t = *Hp;\t\t/* Get filter coeff */\n\t  t *= *Xp;\t\t/* Mult coeff by input sample */\n\t  if (t & (1<<(Nhxn-1)))  /* Round, if needed */\n\t    t += (1<<(Nhxn-1));\n\t  t >>= Nhxn;\t\t/* Leave some guard bits, but come back some */\n\t  v += t;\t\t\t/* The filter output */\n\t  Hp += Npc;\t\t/* Filter coeff step */\n\t  Xp += Inc;\t\t/* Input signal step. NO CHECK ON BOUNDS */\n      }\n    return(v);\n}\n\n\nstatic RES_WORD FilterUD(const RES_HWORD Imp[], const RES_HWORD ImpD[],\n\t\t     RES_UHWORD Nwing, RES_BOOL Interp,\n\t\t     const RES_HWORD *Xp, RES_HWORD Ph, RES_HWORD Inc, RES_UHWORD dhb)\n{\n    RES_HWORD a;\n    const RES_HWORD *Hp, *Hdp, *End;\n    RES_WORD v, t;\n    RES_UWORD Ho;\n\n    v=0;\n    Ho = (Ph*(RES_UWORD)dhb)>>Np;\n    End = &Imp[Nwing];\n    if (Inc == 1)\t\t/* If doing right wing...              */\n    {\t\t\t\t/* ...drop extra coeff, so when Ph is  */\n\tEnd--;\t\t\t/*    0.5, we don't do too many mult's */\n\tif (Ph == 0)\t\t/* If the phase is zero...           */\n\t  Ho += dhb;\t\t/* ...then we've already skipped the */\n    }\t\t\t\t/*    first sample, so we must also  */\n\t\t\t\t/*    skip ahead in Imp[] and ImpD[] */\n    if (Interp)\n      while ((Hp = &Imp[Ho>>Na]) < End) {\n\t  t = *Hp;\t\t/* Get IR sample */\n\t  Hdp = &ImpD[Ho>>Na];  /* get interp (lower Na) bits from diff table*/\n\t  a = Ho & Amask;\t/* a is logically between 0 and 1 */\n\t  t += (((RES_WORD)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */\n\t  t *= *Xp;\t\t/* Mult coeff by input sample */\n\t  if (t & 1<<(Nhxn-1))\t/* Round, if needed */\n\t    t += 1<<(Nhxn-1);\n\t  t >>= Nhxn;\t\t/* Leave some guard bits, but come back some */\n\t  v += t;\t\t\t/* The filter output */\n\t  Ho += dhb;\t\t/* IR step */\n\t  Xp += Inc;\t\t/* Input signal step. NO CHECK ON BOUNDS */\n      }\n    else\n      while ((Hp = &Imp[Ho>>Na]) < End) {\n\t  t = *Hp;\t\t/* Get IR sample */\n\t  t *= *Xp;\t\t/* Mult coeff by input sample */\n\t  if (t & 1<<(Nhxn-1))\t/* Round, if needed */\n\t    t += 1<<(Nhxn-1);\n\t  t >>= Nhxn;\t\t/* Leave some guard bits, but come back some */\n\t  v += t;\t\t\t/* The filter output */\n\t  Ho += dhb;\t\t/* IR step */\n\t  Xp += Inc;\t\t/* Input signal step. NO CHECK ON BOUNDS */\n      }\n    return(v);\n}\n\n/* Sampling rate up-conversion only subroutine;\n * Slightly faster than down-conversion;\n */\nstatic int SrcUp(const RES_HWORD X[], RES_HWORD Y[], double pFactor,\n\t\t RES_UHWORD nx, RES_UHWORD pNwing, RES_UHWORD pLpScl,\n\t\t const RES_HWORD pImp[], const RES_HWORD pImpD[], RES_BOOL Interp)\n{\n    const RES_HWORD *xp;\n    RES_HWORD *Ystart, *Yend;\n    RES_WORD v;\n\n    double dt;                  /* Step through input signal */\n    RES_UWORD dtb;                  /* Fixed-point version of Dt */\n    RES_UWORD time = 0;\n    //RES_UWORD endTime;              /* When time reaches EndTime, return to user */\n\n    dt = 1.0/pFactor;            /* Output sampling period */\n    dtb = dt*(1<<Np) + 0.5;     /* Fixed-point representation */\n\n    Ystart = Y;\n    Yend = Ystart + (unsigned)(nx * pFactor + 0.5);\n    //endTime = time + (1<<Np)*(RES_WORD)nx;\n\n    // Integer round down in dtb calculation may cause (endTime % dtb > 0),\n    // so it may cause resample write pass the output buffer (Y >= Yend).\n    // while (time < endTime)\n    while (Y < Yend)\n    {\n\txp = &X[time>>Np];      /* Ptr to current input sample */\n\t/* Perform left-wing inner product */\n\tv = 0;\n\tv = FilterUp(pImp, pImpD, pNwing, Interp, xp, (RES_HWORD)(time&Pmask),-1);\n\n\t/* Perform right-wing inner product */\n\tv += FilterUp(pImp, pImpD, pNwing, Interp, xp+1,  (RES_HWORD)((-time)&Pmask),1);\n\n\tv >>= Nhg;\t\t/* Make guard bits */\n\tv *= pLpScl;\t\t/* Normalize for unity filter gain */\n\t*Y++ = WordToHword(v,NLpScl);   /* strip guard bits, deposit output */\n\ttime += dtb;\t\t/* Move to next sample by time increment */\n    }\n    return (Y - Ystart);        /* Return the number of output samples */\n}\n\n\n/* Sampling rate conversion subroutine */\n\nstatic int SrcUD(const RES_HWORD X[], RES_HWORD Y[], double pFactor,\n\t\t RES_UHWORD nx, RES_UHWORD pNwing, RES_UHWORD pLpScl,\n\t\t const RES_HWORD pImp[], const RES_HWORD pImpD[], RES_BOOL Interp)\n{\n    const RES_HWORD *xp;\n    RES_HWORD *Ystart, *Yend;\n    RES_WORD v;\n\n    double dh;                  /* Step through filter impulse response */\n    double dt;                  /* Step through input signal */\n    RES_UWORD time = 0;\n    //RES_UWORD endTime;          /* When time reaches EndTime, return to user */\n    RES_UWORD dhb, dtb;         /* Fixed-point versions of Dh,Dt */\n\n    dt = 1.0/pFactor;            /* Output sampling period */\n    dtb = dt*(1<<Np) + 0.5;     /* Fixed-point representation */\n\n    dh = MIN(Npc, pFactor*Npc);  /* Filter sampling period */\n    dhb = dh*(1<<Na) + 0.5;     /* Fixed-point representation */\n\n    Ystart = Y;\n    Yend = Ystart + (unsigned)(nx * pFactor + 0.5);\n    //endTime = time + (1<<Np)*(RES_WORD)nx;\n\n    // Integer round down in dtb calculation may cause (endTime % dtb > 0),\n    // so it may cause resample write pass the output buffer (Y >= Yend).\n    // while (time < endTime)\n    while (Y < Yend)\n    {\n\txp = &X[time>>Np];\t/* Ptr to current input sample */\n\tv = FilterUD(pImp, pImpD, pNwing, Interp, xp, (RES_HWORD)(time&Pmask),\n\t\t     -1, dhb);\t/* Perform left-wing inner product */\n\tv += FilterUD(pImp, pImpD, pNwing, Interp, xp+1, (RES_HWORD)((-time)&Pmask),\n\t\t      1, dhb);\t/* Perform right-wing inner product */\n\tv >>= Nhg;\t\t/* Make guard bits */\n\tv *= pLpScl;\t\t/* Normalize for unity filter gain */\n\t*Y++ = WordToHword(v,NLpScl);   /* strip guard bits, deposit output */\n\ttime += dtb;\t\t/* Move to next sample by time increment */\n    }\n    return (Y - Ystart);        /* Return the number of output samples */\n}\n\n\nDECL(int) res_SrcLinear(const RES_HWORD X[], RES_HWORD Y[],\n\t\t        double pFactor, RES_UHWORD nx)\n{\n    return SrcLinear(X, Y, pFactor, nx);\n}\n\nDECL(int) res_Resample(const RES_HWORD X[], RES_HWORD Y[], double pFactor,\n\t\t       RES_UHWORD nx, RES_BOOL LargeF, RES_BOOL Interp)\n{\n    if (pFactor >= 1) {\n\n\tif (LargeF)\n\t    return SrcUp(X, Y, pFactor, nx,\n\t\t\t LARGE_FILTER_NWING, LARGE_FILTER_SCALE,\n\t\t\t LARGE_FILTER_IMP, LARGE_FILTER_IMPD, Interp);\n\telse\n\t    return SrcUp(X, Y, pFactor, nx,\n\t\t\t SMALL_FILTER_NWING, SMALL_FILTER_SCALE,\n\t\t\t SMALL_FILTER_IMP, SMALL_FILTER_IMPD, Interp);\n\n    } else {\n\n\tif (LargeF)\n\t    return SrcUD(X, Y, pFactor, nx,\n\t\t\t LARGE_FILTER_NWING, LARGE_FILTER_SCALE * pFactor + 0.5,\n\t\t\t LARGE_FILTER_IMP, LARGE_FILTER_IMPD, Interp);\n\telse\n\t    return SrcUD(X, Y, pFactor, nx,\n\t\t\t SMALL_FILTER_NWING, SMALL_FILTER_SCALE * pFactor + 0.5,\n\t\t\t SMALL_FILTER_IMP, SMALL_FILTER_IMPD, Interp);\n\n    }\n}\n\nDECL(int) res_GetXOFF(double pFactor, RES_BOOL LargeF)\n{\n    if (LargeF)\n\treturn (LARGE_FILTER_NMULT + 1) / 2.0  *\n\t        MAX(1.0, 1.0/pFactor);\n    else\n\treturn (SMALL_FILTER_NMULT + 1) / 2.0  *\n\t\tMAX(1.0, 1.0/pFactor);\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/resample/src/smallfilter.h",
    "content": "/* Included by resamplesubs.c */\n#define SMALL_FILTER_NMULT ((RES_HWORD)13)\n#define SMALL_FILTER_SCALE 13128 /* Unity-gain scale factor */\n#define SMALL_FILTER_NWING 1536 /* Filter table length */\nstatic const RES_HWORD SMALL_FILTER_IMP[] /* Impulse response */ = {\n32767,\n32766,\n32764,\n32760,\n32755,\n32749,\n32741,\n32731,\n32721,\n32708,\n32695,\n32679,\n32663,\n32645,\n32625,\n32604,\n32582,\n32558,\n32533,\n32506,\n32478,\n32448,\n32417,\n32385,\n32351,\n32316,\n32279,\n32241,\n32202,\n32161,\n32119,\n32075,\n32030,\n31984,\n31936,\n31887,\n31836,\n31784,\n31731,\n31676,\n31620,\n31563,\n31504,\n31444,\n31383,\n31320,\n31256,\n31191,\n31124,\n31056,\n30987,\n30916,\n30845,\n30771,\n30697,\n30621,\n30544,\n30466,\n30387,\n30306,\n30224,\n30141,\n30057,\n29971,\n29884,\n29796,\n29707,\n29617,\n29525,\n29433,\n29339,\n29244,\n29148,\n29050,\n28952,\n28852,\n28752,\n28650,\n28547,\n28443,\n28338,\n28232,\n28125,\n28017,\n27908,\n27797,\n27686,\n27574,\n27461,\n27346,\n27231,\n27115,\n26998,\n26879,\n26760,\n26640,\n26519,\n26398,\n26275,\n26151,\n26027,\n25901,\n25775,\n25648,\n25520,\n25391,\n25262,\n25131,\n25000,\n24868,\n24735,\n24602,\n24467,\n24332,\n24197,\n24060,\n23923,\n23785,\n23647,\n23507,\n23368,\n23227,\n23086,\n22944,\n22802,\n22659,\n22515,\n22371,\n22226,\n22081,\n21935,\n21789,\n21642,\n21494,\n21346,\n21198,\n21049,\n20900,\n20750,\n20600,\n20449,\n20298,\n20146,\n19995,\n19842,\n19690,\n19537,\n19383,\n19230,\n19076,\n18922,\n18767,\n18612,\n18457,\n18302,\n18146,\n17990,\n17834,\n17678,\n17521,\n17365,\n17208,\n17051,\n16894,\n16737,\n16579,\n16422,\n16264,\n16106,\n15949,\n15791,\n15633,\n15475,\n15317,\n15159,\n15001,\n14843,\n14685,\n14527,\n14369,\n14212,\n14054,\n13896,\n13739,\n13581,\n13424,\n13266,\n13109,\n12952,\n12795,\n12639,\n12482,\n12326,\n12170,\n12014,\n11858,\n11703,\n11548,\n11393,\n11238,\n11084,\n10929,\n10776,\n10622,\n10469,\n10316,\n10164,\n10011,\n9860,\n9708,\n9557,\n9407,\n9256,\n9106,\n8957,\n8808,\n8659,\n8511,\n8364,\n8216,\n8070,\n7924,\n7778,\n7633,\n7488,\n7344,\n7200,\n7057,\n6914,\n6773,\n6631,\n6490,\n6350,\n6210,\n6071,\n5933,\n5795,\n5658,\n5521,\n5385,\n5250,\n5115,\n4981,\n4848,\n4716,\n4584,\n4452,\n4322,\n4192,\n4063,\n3935,\n3807,\n3680,\n3554,\n3429,\n3304,\n3180,\n3057,\n2935,\n2813,\n2692,\n2572,\n2453,\n2335,\n2217,\n2101,\n1985,\n1870,\n1755,\n1642,\n1529,\n1418,\n1307,\n1197,\n1088,\n979,\n872,\n765,\n660,\n555,\n451,\n348,\n246,\n145,\n44,\n-54,\n-153,\n-250,\n-347,\n-443,\n-537,\n-631,\n-724,\n-816,\n-908,\n-998,\n-1087,\n-1175,\n-1263,\n-1349,\n-1435,\n-1519,\n-1603,\n-1685,\n-1767,\n-1848,\n-1928,\n-2006,\n-2084,\n-2161,\n-2237,\n-2312,\n-2386,\n-2459,\n-2531,\n-2603,\n-2673,\n-2742,\n-2810,\n-2878,\n-2944,\n-3009,\n-3074,\n-3137,\n-3200,\n-3261,\n-3322,\n-3381,\n-3440,\n-3498,\n-3554,\n-3610,\n-3665,\n-3719,\n-3772,\n-3824,\n-3875,\n-3925,\n-3974,\n-4022,\n-4069,\n-4116,\n-4161,\n-4205,\n-4249,\n-4291,\n-4333,\n-4374,\n-4413,\n-4452,\n-4490,\n-4527,\n-4563,\n-4599,\n-4633,\n-4666,\n-4699,\n-4730,\n-4761,\n-4791,\n-4820,\n-4848,\n-4875,\n-4901,\n-4926,\n-4951,\n-4974,\n-4997,\n-5019,\n-5040,\n-5060,\n-5080,\n-5098,\n-5116,\n-5133,\n-5149,\n-5164,\n-5178,\n-5192,\n-5205,\n-5217,\n-5228,\n-5238,\n-5248,\n-5257,\n-5265,\n-5272,\n-5278,\n-5284,\n-5289,\n-5293,\n-5297,\n-5299,\n-5301,\n-5303,\n-5303,\n-5303,\n-5302,\n-5300,\n-5298,\n-5295,\n-5291,\n-5287,\n-5282,\n-5276,\n-5270,\n-5263,\n-5255,\n-5246,\n-5237,\n-5228,\n-5217,\n-5206,\n-5195,\n-5183,\n-5170,\n-5157,\n-5143,\n-5128,\n-5113,\n-5097,\n-5081,\n-5064,\n-5047,\n-5029,\n-5010,\n-4991,\n-4972,\n-4952,\n-4931,\n-4910,\n-4889,\n-4867,\n-4844,\n-4821,\n-4797,\n-4774,\n-4749,\n-4724,\n-4699,\n-4673,\n-4647,\n-4620,\n-4593,\n-4566,\n-4538,\n-4510,\n-4481,\n-4452,\n-4422,\n-4393,\n-4363,\n-4332,\n-4301,\n-4270,\n-4238,\n-4206,\n-4174,\n-4142,\n-4109,\n-4076,\n-4042,\n-4009,\n-3975,\n-3940,\n-3906,\n-3871,\n-3836,\n-3801,\n-3765,\n-3729,\n-3693,\n-3657,\n-3620,\n-3584,\n-3547,\n-3510,\n-3472,\n-3435,\n-3397,\n-3360,\n-3322,\n-3283,\n-3245,\n-3207,\n-3168,\n-3129,\n-3091,\n-3052,\n-3013,\n-2973,\n-2934,\n-2895,\n-2855,\n-2816,\n-2776,\n-2736,\n-2697,\n-2657,\n-2617,\n-2577,\n-2537,\n-2497,\n-2457,\n-2417,\n-2377,\n-2337,\n-2297,\n-2256,\n-2216,\n-2176,\n-2136,\n-2096,\n-2056,\n-2016,\n-1976,\n-1936,\n-1896,\n-1856,\n-1817,\n-1777,\n-1737,\n-1698,\n-1658,\n-1619,\n-1579,\n-1540,\n-1501,\n-1462,\n-1423,\n-1384,\n-1345,\n-1306,\n-1268,\n-1230,\n-1191,\n-1153,\n-1115,\n-1077,\n-1040,\n-1002,\n-965,\n-927,\n-890,\n-854,\n-817,\n-780,\n-744,\n-708,\n-672,\n-636,\n-600,\n-565,\n-530,\n-494,\n-460,\n-425,\n-391,\n-356,\n-322,\n-289,\n-255,\n-222,\n-189,\n-156,\n-123,\n-91,\n-59,\n-27,\n4,\n35,\n66,\n97,\n127,\n158,\n188,\n218,\n247,\n277,\n306,\n334,\n363,\n391,\n419,\n447,\n474,\n501,\n528,\n554,\n581,\n606,\n632,\n657,\n683,\n707,\n732,\n756,\n780,\n803,\n827,\n850,\n872,\n895,\n917,\n939,\n960,\n981,\n1002,\n1023,\n1043,\n1063,\n1082,\n1102,\n1121,\n1139,\n1158,\n1176,\n1194,\n1211,\n1228,\n1245,\n1262,\n1278,\n1294,\n1309,\n1325,\n1340,\n1354,\n1369,\n1383,\n1397,\n1410,\n1423,\n1436,\n1448,\n1461,\n1473,\n1484,\n1496,\n1507,\n1517,\n1528,\n1538,\n1548,\n1557,\n1566,\n1575,\n1584,\n1592,\n1600,\n1608,\n1616,\n1623,\n1630,\n1636,\n1643,\n1649,\n1654,\n1660,\n1665,\n1670,\n1675,\n1679,\n1683,\n1687,\n1690,\n1694,\n1697,\n1700,\n1702,\n1704,\n1706,\n1708,\n1709,\n1711,\n1712,\n1712,\n1713,\n1713,\n1713,\n1713,\n1712,\n1711,\n1710,\n1709,\n1708,\n1706,\n1704,\n1702,\n1700,\n1697,\n1694,\n1691,\n1688,\n1685,\n1681,\n1677,\n1673,\n1669,\n1664,\n1660,\n1655,\n1650,\n1644,\n1639,\n1633,\n1627,\n1621,\n1615,\n1609,\n1602,\n1596,\n1589,\n1582,\n1575,\n1567,\n1560,\n1552,\n1544,\n1536,\n1528,\n1520,\n1511,\n1503,\n1494,\n1485,\n1476,\n1467,\n1458,\n1448,\n1439,\n1429,\n1419,\n1409,\n1399,\n1389,\n1379,\n1368,\n1358,\n1347,\n1337,\n1326,\n1315,\n1304,\n1293,\n1282,\n1271,\n1260,\n1248,\n1237,\n1225,\n1213,\n1202,\n1190,\n1178,\n1166,\n1154,\n1142,\n1130,\n1118,\n1106,\n1094,\n1081,\n1069,\n1057,\n1044,\n1032,\n1019,\n1007,\n994,\n981,\n969,\n956,\n943,\n931,\n918,\n905,\n892,\n879,\n867,\n854,\n841,\n828,\n815,\n802,\n790,\n777,\n764,\n751,\n738,\n725,\n713,\n700,\n687,\n674,\n662,\n649,\n636,\n623,\n611,\n598,\n585,\n573,\n560,\n548,\n535,\n523,\n510,\n498,\n486,\n473,\n461,\n449,\n437,\n425,\n413,\n401,\n389,\n377,\n365,\n353,\n341,\n330,\n318,\n307,\n295,\n284,\n272,\n261,\n250,\n239,\n228,\n217,\n206,\n195,\n184,\n173,\n163,\n152,\n141,\n131,\n121,\n110,\n100,\n90,\n80,\n70,\n60,\n51,\n41,\n31,\n22,\n12,\n3,\n-5,\n-14,\n-23,\n-32,\n-41,\n-50,\n-59,\n-67,\n-76,\n-84,\n-93,\n-101,\n-109,\n-117,\n-125,\n-133,\n-140,\n-148,\n-156,\n-163,\n-170,\n-178,\n-185,\n-192,\n-199,\n-206,\n-212,\n-219,\n-226,\n-232,\n-239,\n-245,\n-251,\n-257,\n-263,\n-269,\n-275,\n-280,\n-286,\n-291,\n-297,\n-302,\n-307,\n-312,\n-317,\n-322,\n-327,\n-332,\n-336,\n-341,\n-345,\n-349,\n-354,\n-358,\n-362,\n-366,\n-369,\n-373,\n-377,\n-380,\n-384,\n-387,\n-390,\n-394,\n-397,\n-400,\n-402,\n-405,\n-408,\n-411,\n-413,\n-416,\n-418,\n-420,\n-422,\n-424,\n-426,\n-428,\n-430,\n-432,\n-433,\n-435,\n-436,\n-438,\n-439,\n-440,\n-442,\n-443,\n-444,\n-445,\n-445,\n-446,\n-447,\n-447,\n-448,\n-448,\n-449,\n-449,\n-449,\n-449,\n-449,\n-449,\n-449,\n-449,\n-449,\n-449,\n-449,\n-448,\n-448,\n-447,\n-447,\n-446,\n-445,\n-444,\n-443,\n-443,\n-442,\n-441,\n-440,\n-438,\n-437,\n-436,\n-435,\n-433,\n-432,\n-430,\n-429,\n-427,\n-426,\n-424,\n-422,\n-420,\n-419,\n-417,\n-415,\n-413,\n-411,\n-409,\n-407,\n-405,\n-403,\n-400,\n-398,\n-396,\n-393,\n-391,\n-389,\n-386,\n-384,\n-381,\n-379,\n-376,\n-374,\n-371,\n-368,\n-366,\n-363,\n-360,\n-357,\n-355,\n-352,\n-349,\n-346,\n-343,\n-340,\n-337,\n-334,\n-331,\n-328,\n-325,\n-322,\n-319,\n-316,\n-313,\n-310,\n-307,\n-304,\n-301,\n-298,\n-294,\n-291,\n-288,\n-285,\n-282,\n-278,\n-275,\n-272,\n-269,\n-265,\n-262,\n-259,\n-256,\n-252,\n-249,\n-246,\n-243,\n-239,\n-236,\n-233,\n-230,\n-226,\n-223,\n-220,\n-217,\n-213,\n-210,\n-207,\n-204,\n-200,\n-197,\n-194,\n-191,\n-187,\n-184,\n-181,\n-178,\n-175,\n-172,\n-168,\n-165,\n-162,\n-159,\n-156,\n-153,\n-150,\n-147,\n-143,\n-140,\n-137,\n-134,\n-131,\n-128,\n-125,\n-122,\n-120,\n-117,\n-114,\n-111,\n-108,\n-105,\n-102,\n-99,\n-97,\n-94,\n-91,\n-88,\n-86,\n-83,\n-80,\n-78,\n-75,\n-72,\n-70,\n-67,\n-65,\n-62,\n-59,\n-57,\n-55,\n-52,\n-50,\n-47,\n-45,\n-43,\n-40,\n-38,\n-36,\n-33,\n-31,\n-29,\n-27,\n-25,\n-22,\n-20,\n-18,\n-16,\n-14,\n-12,\n-10,\n-8,\n-6,\n-4,\n-2,\n0,\n0,\n2,\n4,\n6,\n8,\n9,\n11,\n13,\n14,\n16,\n17,\n19,\n21,\n22,\n24,\n25,\n27,\n28,\n29,\n31,\n32,\n33,\n35,\n36,\n37,\n38,\n40,\n41,\n42,\n43,\n44,\n45,\n46,\n47,\n48,\n49,\n50,\n51,\n52,\n53,\n54,\n55,\n56,\n56,\n57,\n58,\n59,\n59,\n60,\n61,\n62,\n62,\n63,\n63,\n64,\n64,\n65,\n66,\n66,\n66,\n67,\n67,\n68,\n68,\n69,\n69,\n69,\n70,\n70,\n70,\n70,\n71,\n71,\n71,\n71,\n71,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n72,\n71,\n71,\n71,\n71,\n71,\n70,\n70,\n70,\n70,\n69,\n69,\n69,\n69,\n68,\n68,\n68,\n67,\n67,\n67,\n66,\n66,\n66,\n65,\n65,\n64,\n64,\n64,\n63,\n63,\n62,\n62,\n62,\n61,\n61,\n60,\n60,\n59,\n59,\n58,\n58,\n58,\n57,\n57,\n56,\n56,\n55,\n55,\n54,\n54,\n53,\n53,\n52,\n52,\n51,\n51,\n50,\n50,\n49,\n48,\n48,\n47,\n47,\n46,\n46,\n45,\n45,\n44,\n44,\n43,\n43,\n42,\n42,\n41,\n41,\n40,\n39,\n39,\n38,\n38,\n37,\n37,\n36,\n36,\n35,\n35,\n34,\n34,\n33,\n33,\n32,\n32,\n31,\n31,\n30,\n30,\n29,\n29,\n28,\n28,\n27,\n27,\n26,\n26,\n25,\n25,\n24,\n24,\n23,\n23,\n23,\n22,\n22,\n21,\n21,\n20,\n20,\n20,\n19,\n19,\n18,\n18,\n17,\n17,\n17,\n16,\n16,\n15,\n15,\n15,\n14,\n14,\n14,\n13,\n13,\n12,\n12,\n12,\n11,\n11,\n11,\n10,\n10,\n10,\n9,\n9,\n9,\n9,\n8,\n8,\n8,\n7,\n7,\n7,\n7,\n6,\n6,\n6,\n6,\n5,\n5,\n5,\n5,\n4,\n4,\n4,\n4,\n3,\n3,\n3,\n3,\n3,\n2,\n2,\n2,\n2,\n2,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1,\n-1\n};\n\nstatic const RES_HWORD SMALL_FILTER_IMPD[] = {\n-1,\n-2,\n-4,\n-5,\n-6,\n-8,\n-10,\n-10,\n-13,\n-13,\n-16,\n-16,\n-18,\n-20,\n-21,\n-22,\n-24,\n-25,\n-27,\n-28,\n-30,\n-31,\n-32,\n-34,\n-35,\n-37,\n-38,\n-39,\n-41,\n-42,\n-44,\n-45,\n-46,\n-48,\n-49,\n-51,\n-52,\n-53,\n-55,\n-56,\n-57,\n-59,\n-60,\n-61,\n-63,\n-64,\n-65,\n-67,\n-68,\n-69,\n-71,\n-71,\n-74,\n-74,\n-76,\n-77,\n-78,\n-79,\n-81,\n-82,\n-83,\n-84,\n-86,\n-87,\n-88,\n-89,\n-90,\n-92,\n-92,\n-94,\n-95,\n-96,\n-98,\n-98,\n-100,\n-100,\n-102,\n-103,\n-104,\n-105,\n-106,\n-107,\n-108,\n-109,\n-111,\n-111,\n-112,\n-113,\n-115,\n-115,\n-116,\n-117,\n-119,\n-119,\n-120,\n-121,\n-121,\n-123,\n-124,\n-124,\n-126,\n-126,\n-127,\n-128,\n-129,\n-129,\n-131,\n-131,\n-132,\n-133,\n-133,\n-135,\n-135,\n-135,\n-137,\n-137,\n-138,\n-138,\n-140,\n-139,\n-141,\n-141,\n-142,\n-142,\n-143,\n-144,\n-144,\n-145,\n-145,\n-146,\n-146,\n-147,\n-148,\n-148,\n-148,\n-149,\n-149,\n-150,\n-150,\n-151,\n-151,\n-152,\n-151,\n-153,\n-152,\n-153,\n-154,\n-153,\n-154,\n-154,\n-155,\n-155,\n-155,\n-155,\n-156,\n-156,\n-156,\n-156,\n-157,\n-156,\n-157,\n-157,\n-157,\n-157,\n-158,\n-157,\n-158,\n-158,\n-157,\n-158,\n-158,\n-158,\n-158,\n-158,\n-158,\n-158,\n-158,\n-158,\n-158,\n-157,\n-158,\n-158,\n-157,\n-158,\n-157,\n-158,\n-157,\n-157,\n-157,\n-156,\n-157,\n-156,\n-156,\n-156,\n-156,\n-155,\n-155,\n-155,\n-155,\n-154,\n-155,\n-153,\n-154,\n-153,\n-153,\n-152,\n-153,\n-151,\n-152,\n-151,\n-150,\n-151,\n-150,\n-149,\n-149,\n-149,\n-148,\n-147,\n-148,\n-146,\n-146,\n-146,\n-145,\n-145,\n-144,\n-144,\n-143,\n-143,\n-141,\n-142,\n-141,\n-140,\n-140,\n-139,\n-138,\n-138,\n-137,\n-137,\n-136,\n-135,\n-135,\n-134,\n-133,\n-132,\n-132,\n-132,\n-130,\n-130,\n-129,\n-128,\n-128,\n-127,\n-126,\n-125,\n-125,\n-124,\n-123,\n-122,\n-122,\n-121,\n-120,\n-119,\n-118,\n-118,\n-116,\n-116,\n-115,\n-115,\n-113,\n-113,\n-111,\n-111,\n-110,\n-109,\n-109,\n-107,\n-107,\n-105,\n-105,\n-104,\n-103,\n-102,\n-101,\n-101,\n-98,\n-99,\n-97,\n-97,\n-96,\n-94,\n-94,\n-93,\n-92,\n-92,\n-90,\n-89,\n-88,\n-88,\n-86,\n-86,\n-84,\n-84,\n-82,\n-82,\n-81,\n-80,\n-78,\n-78,\n-77,\n-76,\n-75,\n-74,\n-73,\n-72,\n-72,\n-70,\n-69,\n-68,\n-68,\n-66,\n-65,\n-65,\n-63,\n-63,\n-61,\n-61,\n-59,\n-59,\n-58,\n-56,\n-56,\n-55,\n-54,\n-53,\n-52,\n-51,\n-50,\n-49,\n-48,\n-47,\n-47,\n-45,\n-44,\n-44,\n-42,\n-42,\n-41,\n-39,\n-39,\n-38,\n-37,\n-36,\n-36,\n-34,\n-33,\n-33,\n-31,\n-31,\n-30,\n-29,\n-28,\n-27,\n-26,\n-25,\n-25,\n-23,\n-23,\n-22,\n-21,\n-20,\n-20,\n-18,\n-18,\n-17,\n-16,\n-15,\n-14,\n-14,\n-13,\n-12,\n-11,\n-10,\n-10,\n-9,\n-8,\n-7,\n-6,\n-6,\n-5,\n-4,\n-4,\n-2,\n-2,\n-2,\n0,\n0,\n1,\n2,\n2,\n3,\n4,\n4,\n5,\n6,\n6,\n7,\n8,\n9,\n9,\n9,\n11,\n11,\n11,\n12,\n13,\n13,\n14,\n15,\n15,\n16,\n16,\n17,\n17,\n18,\n19,\n19,\n19,\n20,\n21,\n21,\n21,\n22,\n23,\n23,\n24,\n23,\n25,\n25,\n25,\n26,\n26,\n27,\n27,\n27,\n28,\n28,\n29,\n29,\n30,\n29,\n30,\n31,\n31,\n31,\n32,\n32,\n32,\n32,\n33,\n33,\n34,\n33,\n34,\n35,\n34,\n35,\n35,\n35,\n36,\n36,\n36,\n36,\n37,\n36,\n37,\n37,\n38,\n37,\n38,\n37,\n38,\n39,\n38,\n38,\n39,\n39,\n38,\n39,\n39,\n40,\n39,\n39,\n40,\n39,\n40,\n40,\n39,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n41,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n39,\n40,\n40,\n39,\n40,\n39,\n40,\n39,\n39,\n39,\n39,\n39,\n39,\n39,\n38,\n38,\n39,\n38,\n38,\n38,\n37,\n38,\n37,\n38,\n37,\n36,\n37,\n37,\n36,\n36,\n36,\n36,\n36,\n35,\n35,\n36,\n34,\n35,\n34,\n35,\n34,\n33,\n34,\n33,\n33,\n33,\n33,\n32,\n32,\n32,\n31,\n31,\n31,\n31,\n30,\n31,\n30,\n30,\n29,\n30,\n29,\n28,\n29,\n28,\n28,\n28,\n27,\n27,\n27,\n26,\n27,\n25,\n26,\n25,\n26,\n24,\n25,\n24,\n24,\n23,\n24,\n23,\n22,\n23,\n22,\n22,\n21,\n21,\n21,\n21,\n20,\n20,\n19,\n20,\n19,\n18,\n19,\n18,\n18,\n17,\n17,\n17,\n17,\n16,\n16,\n15,\n16,\n15,\n14,\n15,\n14,\n14,\n13,\n13,\n13,\n12,\n13,\n12,\n11,\n12,\n11,\n10,\n11,\n10,\n10,\n9,\n9,\n9,\n9,\n8,\n8,\n8,\n8,\n7,\n7,\n6,\n7,\n6,\n5,\n6,\n5,\n5,\n5,\n4,\n4,\n4,\n3,\n4,\n3,\n3,\n2,\n2,\n2,\n2,\n1,\n2,\n1,\n0,\n1,\n0,\n0,\n0,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-2,\n-2,\n-2,\n-3,\n-3,\n-3,\n-3,\n-3,\n-4,\n-4,\n-4,\n-4,\n-5,\n-4,\n-5,\n-5,\n-6,\n-5,\n-6,\n-6,\n-6,\n-6,\n-6,\n-7,\n-6,\n-7,\n-7,\n-7,\n-8,\n-7,\n-8,\n-8,\n-8,\n-8,\n-8,\n-9,\n-8,\n-9,\n-9,\n-9,\n-9,\n-9,\n-10,\n-9,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-11,\n-10,\n-11,\n-10,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-12,\n-11,\n-12,\n-12,\n-11,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-13,\n-12,\n-12,\n-13,\n-12,\n-13,\n-12,\n-13,\n-13,\n-12,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-12,\n-13,\n-12,\n-13,\n-12,\n-13,\n-12,\n-12,\n-13,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-11,\n-12,\n-11,\n-12,\n-11,\n-12,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-10,\n-11,\n-11,\n-10,\n-10,\n-11,\n-10,\n-10,\n-10,\n-10,\n-10,\n-9,\n-10,\n-10,\n-9,\n-10,\n-9,\n-8,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-8,\n-9,\n-8,\n-9,\n-8,\n-8,\n-8,\n-8,\n-8,\n-7,\n-8,\n-8,\n-7,\n-7,\n-8,\n-7,\n-7,\n-7,\n-7,\n-6,\n-7,\n-7,\n-6,\n-7,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-5,\n-6,\n-5,\n-6,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-4,\n-5,\n-4,\n-4,\n-5,\n-4,\n-4,\n-4,\n-3,\n-4,\n-4,\n-3,\n-4,\n-3,\n-3,\n-4,\n-3,\n-3,\n-2,\n-3,\n-3,\n-3,\n-2,\n-3,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n2,\n1,\n1,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n2,\n2,\n1,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n3,\n2,\n2,\n3,\n2,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n3,\n2,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n2,\n3,\n3,\n2,\n3,\n3,\n2,\n3,\n2,\n3,\n3,\n2,\n2,\n3,\n2,\n3,\n2,\n2,\n3,\n2,\n2,\n3,\n2,\n2,\n2,\n2,\n3,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n0,\n2,\n2,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n1,\n2,\n2,\n1,\n2,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n1,\n2,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n-1,\n-2,\n-4,\n-5,\n-6,\n-8,\n-10,\n-10,\n-13,\n-13,\n-16,\n-16,\n-18,\n-20,\n-21,\n-22,\n-24,\n-25,\n-27,\n-28,\n-30,\n-31,\n-32,\n-34,\n-35,\n-37,\n-38,\n-39,\n-41,\n-42,\n-44,\n-45,\n-46,\n-48,\n-49,\n-51,\n-52,\n-53,\n-55,\n-56,\n-57,\n-59,\n-60,\n-61,\n-63,\n-64,\n-65,\n-67,\n-68,\n-69,\n-71,\n-71,\n-74,\n-74,\n-76,\n-77,\n-78,\n-79,\n-81,\n-82,\n-83,\n-84,\n-86,\n-87,\n-88,\n-89,\n-90,\n-92,\n-92,\n-94,\n-95,\n-96,\n-98,\n-98,\n-100,\n-100,\n-102,\n-103,\n-104,\n-105,\n-106,\n-107,\n-108,\n-109,\n-111,\n-111,\n-112,\n-113,\n-115,\n-115,\n-116,\n-117,\n-119,\n-119,\n-120,\n-121,\n-121,\n-123,\n-124,\n-124,\n-126,\n-126,\n-127,\n-128,\n-129,\n-129,\n-131,\n-131,\n-132,\n-133,\n-133,\n-135,\n-135,\n-135,\n-137,\n-137,\n-138,\n-138,\n-140,\n-139,\n-141,\n-141,\n-142,\n-142,\n-143,\n-144,\n-144,\n-145,\n-145,\n-146,\n-146,\n-147,\n-148,\n-148,\n-148,\n-149,\n-149,\n-150,\n-150,\n-151,\n-151,\n-152,\n-151,\n-153,\n-152,\n-153,\n-154,\n-153,\n-154,\n-154,\n-155,\n-155,\n-155,\n-155,\n-156,\n-156,\n-156,\n-156,\n-157,\n-156,\n-157,\n-157,\n-157,\n-157,\n-158,\n-157,\n-158,\n-158,\n-157,\n-158,\n-158,\n-158,\n-158,\n-158,\n-158,\n-158,\n-158,\n-158,\n-158,\n-157,\n-158,\n-158,\n-157,\n-158,\n-157,\n-158,\n-157,\n-157,\n-157,\n-156,\n-157,\n-156,\n-156,\n-156,\n-156,\n-155,\n-155,\n-155,\n-155,\n-154,\n-155,\n-153,\n-154,\n-153,\n-153,\n-152,\n-153,\n-151,\n-152,\n-151,\n-150,\n-151,\n-150,\n-149,\n-149,\n-149,\n-148,\n-147,\n-148,\n-146,\n-146,\n-146,\n-145,\n-145,\n-144,\n-144,\n-143,\n-143,\n-141,\n-142,\n-141,\n-140,\n-140,\n-139,\n-138,\n-138,\n-137,\n-137,\n-136,\n-135,\n-135,\n-134,\n-133,\n-132,\n-132,\n-132,\n-130,\n-130,\n-129,\n-128,\n-128,\n-127,\n-126,\n-125,\n-125,\n-124,\n-123,\n-122,\n-122,\n-121,\n-120,\n-119,\n-118,\n-118,\n-116,\n-116,\n-115,\n-115,\n-113,\n-113,\n-111,\n-111,\n-110,\n-109,\n-109,\n-107,\n-107,\n-105,\n-105,\n-104,\n-103,\n-102,\n-101,\n-101,\n-98,\n-99,\n-97,\n-97,\n-96,\n-94,\n-94,\n-93,\n-92,\n-92,\n-90,\n-89,\n-88,\n-88,\n-86,\n-86,\n-84,\n-84,\n-82,\n-82,\n-81,\n-80,\n-78,\n-78,\n-77,\n-76,\n-75,\n-74,\n-73,\n-72,\n-72,\n-70,\n-69,\n-68,\n-68,\n-66,\n-65,\n-65,\n-63,\n-63,\n-61,\n-61,\n-59,\n-59,\n-58,\n-56,\n-56,\n-55,\n-54,\n-53,\n-52,\n-51,\n-50,\n-49,\n-48,\n-47,\n-47,\n-45,\n-44,\n-44,\n-42,\n-42,\n-41,\n-39,\n-39,\n-38,\n-37,\n-36,\n-36,\n-34,\n-33,\n-33,\n-31,\n-31,\n-30,\n-29,\n-28,\n-27,\n-26,\n-25,\n-25,\n-23,\n-23,\n-22,\n-21,\n-20,\n-20,\n-18,\n-18,\n-17,\n-16,\n-15,\n-14,\n-14,\n-13,\n-12,\n-11,\n-10,\n-10,\n-9,\n-8,\n-7,\n-6,\n-6,\n-5,\n-4,\n-4,\n-2,\n-2,\n-2,\n0,\n0,\n1,\n2,\n2,\n3,\n4,\n4,\n5,\n6,\n6,\n7,\n8,\n9,\n9,\n9,\n11,\n11,\n11,\n12,\n13,\n13,\n14,\n15,\n15,\n16,\n16,\n17,\n17,\n18,\n19,\n19,\n19,\n20,\n21,\n21,\n21,\n22,\n23,\n23,\n24,\n23,\n25,\n25,\n25,\n26,\n26,\n27,\n27,\n27,\n28,\n28,\n29,\n29,\n30,\n29,\n30,\n31,\n31,\n31,\n32,\n32,\n32,\n32,\n33,\n33,\n34,\n33,\n34,\n35,\n34,\n35,\n35,\n35,\n36,\n36,\n36,\n36,\n37,\n36,\n37,\n37,\n38,\n37,\n38,\n37,\n38,\n39,\n38,\n38,\n39,\n39,\n38,\n39,\n39,\n40,\n39,\n39,\n40,\n39,\n40,\n40,\n39,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n41,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n40,\n39,\n40,\n40,\n39,\n40,\n39,\n40,\n39,\n39,\n39,\n39,\n39,\n39,\n39,\n38,\n38,\n39,\n38,\n38,\n38,\n37,\n38,\n37,\n38,\n37,\n36,\n37,\n37,\n36,\n36,\n36,\n36,\n36,\n35,\n35,\n36,\n34,\n35,\n34,\n35,\n34,\n33,\n34,\n33,\n33,\n33,\n33,\n32,\n32,\n32,\n31,\n31,\n31,\n31,\n30,\n31,\n30,\n30,\n29,\n30,\n29,\n28,\n29,\n28,\n28,\n28,\n27,\n27,\n27,\n26,\n27,\n25,\n26,\n25,\n26,\n24,\n25,\n24,\n24,\n23,\n24,\n23,\n22,\n23,\n22,\n22,\n21,\n21,\n21,\n21,\n20,\n20,\n19,\n20,\n19,\n18,\n19,\n18,\n18,\n17,\n17,\n17,\n17,\n16,\n16,\n15,\n16,\n15,\n14,\n15,\n14,\n14,\n13,\n13,\n13,\n12,\n13,\n12,\n11,\n12,\n11,\n10,\n11,\n10,\n10,\n9,\n9,\n9,\n9,\n8,\n8,\n8,\n8,\n7,\n7,\n6,\n7,\n6,\n5,\n6,\n5,\n5,\n5,\n4,\n4,\n4,\n3,\n4,\n3,\n3,\n2,\n2,\n2,\n2,\n1,\n2,\n1,\n0,\n1,\n0,\n0,\n0,\n-1,\n-1,\n-1,\n-1,\n-1,\n-2,\n-2,\n-2,\n-2,\n-3,\n-3,\n-3,\n-3,\n-3,\n-4,\n-4,\n-4,\n-4,\n-5,\n-4,\n-5,\n-5,\n-6,\n-5,\n-6,\n-6,\n-6,\n-6,\n-6,\n-7,\n-6,\n-7,\n-7,\n-7,\n-8,\n-7,\n-8,\n-8,\n-8,\n-8,\n-8,\n-9,\n-8,\n-9,\n-9,\n-9,\n-9,\n-9,\n-10,\n-9,\n-10,\n-10,\n-10,\n-10,\n-10,\n-10,\n-11,\n-10,\n-11,\n-10,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-12,\n-11,\n-12,\n-12,\n-11,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-13,\n-12,\n-12,\n-13,\n-12,\n-13,\n-12,\n-13,\n-13,\n-12,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-13,\n-12,\n-13,\n-13,\n-12,\n-13,\n-12,\n-13,\n-12,\n-13,\n-12,\n-12,\n-13,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-12,\n-11,\n-12,\n-11,\n-12,\n-11,\n-12,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-11,\n-10,\n-11,\n-11,\n-10,\n-10,\n-11,\n-10,\n-10,\n-10,\n-10,\n-10,\n-9,\n-10,\n-10,\n-9,\n-10,\n-9,\n-8,\n-9,\n-9,\n-9,\n-9,\n-9,\n-9,\n-8,\n-9,\n-8,\n-9,\n-8,\n-8,\n-8,\n-8,\n-8,\n-7,\n-8,\n-8,\n-7,\n-7,\n-8,\n-7,\n-7,\n-7,\n-7,\n-6,\n-7,\n-7,\n-6,\n-7,\n-6,\n-6,\n-6,\n-6,\n-6,\n-6,\n-5,\n-6,\n-5,\n-6,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-5,\n-4,\n-5,\n-4,\n-4,\n-5,\n-4,\n-4,\n-4,\n-3,\n-4,\n-4,\n-3,\n-4,\n-3,\n-3,\n-4,\n-3,\n-3,\n-2,\n-3,\n-3,\n-3,\n-2,\n-3,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-2,\n-1,\n-2,\n-1,\n-2,\n-1,\n-1,\n-2,\n-1,\n-1,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n2,\n1,\n1,\n1,\n2,\n1,\n2,\n1,\n2,\n1,\n2,\n2,\n2,\n1,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n3,\n2,\n2,\n3,\n2,\n2,\n3,\n2,\n3,\n2,\n3,\n2,\n3,\n3,\n2,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n4,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n3,\n3,\n3,\n3,\n2,\n3,\n3,\n3,\n2,\n3,\n3,\n2,\n3,\n3,\n2,\n3,\n2,\n3,\n3,\n2,\n2,\n3,\n2,\n3,\n2,\n2,\n3,\n2,\n2,\n3,\n2,\n2,\n2,\n2,\n3,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n2,\n0,\n2,\n2,\n2,\n2,\n1,\n2,\n2,\n1,\n2,\n1,\n2,\n2,\n1,\n2,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n2,\n1,\n1,\n1,\n2,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n1,\n1,\n0,\n1,\n0,\n1,\n0,\n1,\n1,\n0,\n0,\n1,\n0,\n1,\n0,\n1,\n0,\n0,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n-1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/resample/src/stddefs.h",
    "content": "#ifndef PI\n#define PI (3.14159265358979232846)\n#endif\n\n#ifndef PI2\n#define PI2 (6.28318530717958465692)\n#endif\n\n#define D2R (0.01745329348)          /* (2*pi)/360 */\n#define R2D (57.29577951)            /* 360/(2*pi) */\n\n#ifndef MAX\n#define MAX(x,y) ((x)>(y) ?(x):(y))\n#endif\n#ifndef MIN\n#define MIN(x,y) ((x)<(y) ?(x):(y))\n#endif\n\n#ifndef ABS\n#define ABS(x)   ((x)<0   ?(-(x)):(x))\n#endif\n\n#ifndef SGN\n#define SGN(x)   ((x)<0   ?(-1):((x)==0?(0):(1)))\n#endif\n\n#define MAX_HWORD (32767)\n#define MIN_HWORD (-32768)\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/AUTHORS",
    "content": "Jean-Marc Valin <jean-marc.valin@usherbrooke.ca>\n   All the code except the following\n\nDavid Rowe <david@rowetel.com>\n   lsp.c lsp.h \n   Also ideas and feedback\n\nJohn Francis Edwards\n   wave_out.[ch], some #ifdefs for windows port and MSVC project files\n\nSegher Boessenkool\n   Misc. optimizations (for QMF in particular)\n\nAtsuhiko Yamanaka <ymnk@jcraft.com>:\n   Patch to speexenc.c to add Vorbis comment format\n\nRadim Kolar <hsn@cybermail.net>:\n   Patch to speexenc.c for supporting more input formats\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/COPYING",
    "content": "Copyright 2002-2008 \tXiph.org Foundation\nCopyright 2002-2008 \tJean-Marc Valin\nCopyright 2005-2007\tAnalog Devices Inc.\nCopyright 2005-2008\tCommonwealth Scientific and Industrial Research \n                        Organisation (CSIRO)\nCopyright 1993, 2002, 2006 David Rowe\nCopyright 2003 \t\tEpicGames\nCopyright 1992-1994\tJutta Degener, Carsten Bormann\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n- Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n- Neither the name of the Xiph.org Foundation nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\nCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/include/speex/speex.h",
    "content": "/* Copyright (C) 2002-2006 Jean-Marc Valin*/\n/**\n  @file speex.h\n  @brief Describes the different modes of the codec\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifndef SPEEX_H\n#define SPEEX_H\n/** @defgroup Codec Speex encoder and decoder\n *  This is the Speex codec itself.\n *  @{\n */\n\n#include \"speex/speex_bits.h\"\n#include \"speex/speex_types.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Values allowed for *ctl() requests */\n\n/** Set enhancement on/off (decoder only) */\n#define SPEEX_SET_ENH 0\n/** Get enhancement state (decoder only) */\n#define SPEEX_GET_ENH 1\n\n/*Would be SPEEX_SET_FRAME_SIZE, but it's (currently) invalid*/\n/** Obtain frame size used by encoder/decoder */\n#define SPEEX_GET_FRAME_SIZE 3\n\n/** Set quality value */\n#define SPEEX_SET_QUALITY 4\n/** Get current quality setting */\n/* #define SPEEX_GET_QUALITY 5 -- Doesn't make much sense, does it? */\n\n/** Set sub-mode to use */\n#define SPEEX_SET_MODE 6\n/** Get current sub-mode in use */\n#define SPEEX_GET_MODE 7\n\n/** Set low-band sub-mode to use (wideband only)*/\n#define SPEEX_SET_LOW_MODE 8\n/** Get current low-band mode in use (wideband only)*/\n#define SPEEX_GET_LOW_MODE 9\n\n/** Set high-band sub-mode to use (wideband only)*/\n#define SPEEX_SET_HIGH_MODE 10\n/** Get current high-band mode in use (wideband only)*/\n#define SPEEX_GET_HIGH_MODE 11\n\n/** Set VBR on (1) or off (0) */\n#define SPEEX_SET_VBR 12\n/** Get VBR status (1 for on, 0 for off) */\n#define SPEEX_GET_VBR 13\n\n/** Set quality value for VBR encoding (0-10) */\n#define SPEEX_SET_VBR_QUALITY 14\n/** Get current quality value for VBR encoding (0-10) */\n#define SPEEX_GET_VBR_QUALITY 15\n\n/** Set complexity of the encoder (0-10) */\n#define SPEEX_SET_COMPLEXITY 16\n/** Get current complexity of the encoder (0-10) */\n#define SPEEX_GET_COMPLEXITY 17\n\n/** Set bit-rate used by the encoder (or lower) */\n#define SPEEX_SET_BITRATE 18\n/** Get current bit-rate used by the encoder or decoder */\n#define SPEEX_GET_BITRATE 19\n\n/** Define a handler function for in-band Speex request*/\n#define SPEEX_SET_HANDLER 20\n\n/** Define a handler function for in-band user-defined request*/\n#define SPEEX_SET_USER_HANDLER 22\n\n/** Set sampling rate used in bit-rate computation */\n#define SPEEX_SET_SAMPLING_RATE 24\n/** Get sampling rate used in bit-rate computation */\n#define SPEEX_GET_SAMPLING_RATE 25\n\n/** Reset the encoder/decoder memories to zero*/\n#define SPEEX_RESET_STATE 26\n\n/** Get VBR info (mostly used internally) */\n#define SPEEX_GET_RELATIVE_QUALITY 29\n\n/** Set VAD status (1 for on, 0 for off) */\n#define SPEEX_SET_VAD 30\n\n/** Get VAD status (1 for on, 0 for off) */\n#define SPEEX_GET_VAD 31\n\n/** Set Average Bit-Rate (ABR) to n bits per seconds */\n#define SPEEX_SET_ABR 32\n/** Get Average Bit-Rate (ABR) setting (in bps) */\n#define SPEEX_GET_ABR 33\n\n/** Set DTX status (1 for on, 0 for off) */\n#define SPEEX_SET_DTX 34\n/** Get DTX status (1 for on, 0 for off) */\n#define SPEEX_GET_DTX 35\n\n/** Set submode encoding in each frame (1 for yes, 0 for no, setting to no breaks the standard) */\n#define SPEEX_SET_SUBMODE_ENCODING 36\n/** Get submode encoding in each frame */\n#define SPEEX_GET_SUBMODE_ENCODING 37\n\n/*#define SPEEX_SET_LOOKAHEAD 38*/\n/** Returns the lookahead used by Speex */\n#define SPEEX_GET_LOOKAHEAD 39\n\n/** Sets tuning for packet-loss concealment (expected loss rate) */\n#define SPEEX_SET_PLC_TUNING 40\n/** Gets tuning for PLC */\n#define SPEEX_GET_PLC_TUNING 41\n\n/** Sets the max bit-rate allowed in VBR mode */\n#define SPEEX_SET_VBR_MAX_BITRATE 42\n/** Gets the max bit-rate allowed in VBR mode */\n#define SPEEX_GET_VBR_MAX_BITRATE 43\n\n/** Turn on/off input/output high-pass filtering */\n#define SPEEX_SET_HIGHPASS 44\n/** Get status of input/output high-pass filtering */\n#define SPEEX_GET_HIGHPASS 45\n\n/** Get \"activity level\" of the last decoded frame, i.e.\n    how much damage we cause if we remove the frame */\n#define SPEEX_GET_ACTIVITY 47\n\n\n/* Preserving compatibility:*/\n/** Equivalent to SPEEX_SET_ENH */\n#define SPEEX_SET_PF 0\n/** Equivalent to SPEEX_GET_ENH */\n#define SPEEX_GET_PF 1\n\n\n\n\n/* Values allowed for mode queries */\n/** Query the frame size of a mode */\n#define SPEEX_MODE_FRAME_SIZE 0\n\n/** Query the size of an encoded frame for a particular sub-mode */\n#define SPEEX_SUBMODE_BITS_PER_FRAME 1\n\n\n\n/** Get major Speex version */\n#define SPEEX_LIB_GET_MAJOR_VERSION 1\n/** Get minor Speex version */\n#define SPEEX_LIB_GET_MINOR_VERSION 3\n/** Get micro Speex version */\n#define SPEEX_LIB_GET_MICRO_VERSION 5\n/** Get extra Speex version */\n#define SPEEX_LIB_GET_EXTRA_VERSION 7\n/** Get Speex version string */\n#define SPEEX_LIB_GET_VERSION_STRING 9\n\n/*#define SPEEX_LIB_SET_ALLOC_FUNC 10\n#define SPEEX_LIB_GET_ALLOC_FUNC 11\n#define SPEEX_LIB_SET_FREE_FUNC 12\n#define SPEEX_LIB_GET_FREE_FUNC 13\n\n#define SPEEX_LIB_SET_WARNING_FUNC 14\n#define SPEEX_LIB_GET_WARNING_FUNC 15\n#define SPEEX_LIB_SET_ERROR_FUNC 16\n#define SPEEX_LIB_GET_ERROR_FUNC 17\n*/\n\n/** Number of defined modes in Speex */\n#define SPEEX_NB_MODES 3\n\n/** modeID for the defined narrowband mode */\n#define SPEEX_MODEID_NB 0\n\n/** modeID for the defined wideband mode */\n#define SPEEX_MODEID_WB 1\n\n/** modeID for the defined ultra-wideband mode */\n#define SPEEX_MODEID_UWB 2\n\nstruct SpeexMode;\n\n\n/* Prototypes for mode function pointers */\n\n/** Encoder state initialization function */\ntypedef void *(*encoder_init_func)(const struct SpeexMode *mode);\n\n/** Encoder state destruction function */\ntypedef void (*encoder_destroy_func)(void *st);\n\n/** Main encoding function */\ntypedef int (*encode_func)(void *state, void *in, SpeexBits *bits);\n\n/** Function for controlling the encoder options */\ntypedef int (*encoder_ctl_func)(void *state, int request, void *ptr);\n\n/** Decoder state initialization function */\ntypedef void *(*decoder_init_func)(const struct SpeexMode *mode);\n\n/** Decoder state destruction function */\ntypedef void (*decoder_destroy_func)(void *st);\n\n/** Main decoding function */\ntypedef int  (*decode_func)(void *state, SpeexBits *bits, void *out);\n\n/** Function for controlling the decoder options */\ntypedef int (*decoder_ctl_func)(void *state, int request, void *ptr);\n\n\n/** Query function for a mode */\ntypedef int (*mode_query_func)(const void *mode, int request, void *ptr);\n\n/** Struct defining a Speex mode */ \ntypedef struct SpeexMode {\n   /** Pointer to the low-level mode data */\n   const void *mode;\n\n   /** Pointer to the mode query function */\n   mode_query_func query;\n   \n   /** The name of the mode (you should not rely on this to identify the mode)*/\n   const char *modeName;\n\n   /**ID of the mode*/\n   int modeID;\n\n   /**Version number of the bitstream (incremented every time we break\n    bitstream compatibility*/\n   int bitstream_version;\n\n   /** Pointer to encoder initialization function */\n   encoder_init_func enc_init;\n\n   /** Pointer to encoder destruction function */\n   encoder_destroy_func enc_destroy;\n\n   /** Pointer to frame encoding function */\n   encode_func enc;\n\n   /** Pointer to decoder initialization function */\n   decoder_init_func dec_init;\n\n   /** Pointer to decoder destruction function */\n   decoder_destroy_func dec_destroy;\n\n   /** Pointer to frame decoding function */\n   decode_func dec;\n\n   /** ioctl-like requests for encoder */\n   encoder_ctl_func enc_ctl;\n\n   /** ioctl-like requests for decoder */\n   decoder_ctl_func dec_ctl;\n\n} SpeexMode;\n\n/**\n * Returns a handle to a newly created Speex encoder state structure. For now, \n * the \"mode\" argument can be &nb_mode or &wb_mode . In the future, more modes \n * may be added. Note that for now if you have more than one channels to \n * encode, you need one state per channel.\n *\n * @param mode The mode to use (either speex_nb_mode or speex_wb.mode) \n * @return A newly created encoder state or NULL if state allocation fails\n */\nvoid *speex_encoder_init(const SpeexMode *mode);\n\n/** Frees all resources associated to an existing Speex encoder state. \n * @param state Encoder state to be destroyed */\nvoid speex_encoder_destroy(void *state);\n\n/** Uses an existing encoder state to encode one frame of speech pointed to by\n    \"in\". The encoded bit-stream is saved in \"bits\".\n @param state Encoder state\n @param in Frame that will be encoded with a +-2^15 range. This data MAY be \n        overwritten by the encoder and should be considered uninitialised \n        after the call.\n @param bits Bit-stream where the data will be written\n @return 0 if frame needs not be transmitted (DTX only), 1 otherwise\n */\nint speex_encode(void *state, float *in, SpeexBits *bits);\n\n/** Uses an existing encoder state to encode one frame of speech pointed to by\n    \"in\". The encoded bit-stream is saved in \"bits\".\n @param state Encoder state\n @param in Frame that will be encoded with a +-2^15 range\n @param bits Bit-stream where the data will be written\n @return 0 if frame needs not be transmitted (DTX only), 1 otherwise\n */\nint speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits);\n\n/** Used like the ioctl function to control the encoder parameters\n *\n * @param state Encoder state\n * @param request ioctl-type request (one of the SPEEX_* macros)\n * @param ptr Data exchanged to-from function\n * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter\n */\nint speex_encoder_ctl(void *state, int request, void *ptr);\n\n\n/** Returns a handle to a newly created decoder state structure. For now, \n * the mode argument can be &nb_mode or &wb_mode . In the future, more modes\n * may be added.  Note that for now if you have more than one channels to\n * decode, you need one state per channel.\n *\n * @param mode Speex mode (one of speex_nb_mode or speex_wb_mode)\n * @return A newly created decoder state or NULL if state allocation fails\n */ \nvoid *speex_decoder_init(const SpeexMode *mode);\n\n/** Frees all resources associated to an existing decoder state.\n *\n * @param state State to be destroyed\n */\nvoid speex_decoder_destroy(void *state);\n\n/** Uses an existing decoder state to decode one frame of speech from\n * bit-stream bits. The output speech is saved written to out.\n *\n * @param state Decoder state\n * @param bits Bit-stream from which to decode the frame (NULL if the packet was lost)\n * @param out Where to write the decoded frame\n * @return return status (0 for no error, -1 for end of stream, -2 corrupt stream)\n */\nint speex_decode(void *state, SpeexBits *bits, float *out);\n\n/** Uses an existing decoder state to decode one frame of speech from\n * bit-stream bits. The output speech is saved written to out.\n *\n * @param state Decoder state\n * @param bits Bit-stream from which to decode the frame (NULL if the packet was lost)\n * @param out Where to write the decoded frame\n * @return return status (0 for no error, -1 for end of stream, -2 corrupt stream)\n */\nint speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out);\n\n/** Used like the ioctl function to control the encoder parameters\n *\n * @param state Decoder state\n * @param request ioctl-type request (one of the SPEEX_* macros)\n * @param ptr Data exchanged to-from function\n * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter\n */\nint speex_decoder_ctl(void *state, int request, void *ptr);\n\n\n/** Query function for mode information\n *\n * @param mode Speex mode\n * @param request ioctl-type request (one of the SPEEX_* macros)\n * @param ptr Data exchanged to-from function\n * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter\n */\nint speex_mode_query(const SpeexMode *mode, int request, void *ptr);\n\n/** Functions for controlling the behavior of libspeex\n * @param request ioctl-type request (one of the SPEEX_LIB_* macros)\n * @param ptr Data exchanged to-from function\n * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter\n */\nint speex_lib_ctl(int request, void *ptr);\n\n/** Default narrowband mode */\nextern const SpeexMode speex_nb_mode;\n\n/** Default wideband mode */\nextern const SpeexMode speex_wb_mode;\n\n/** Default \"ultra-wideband\" mode */\nextern const SpeexMode speex_uwb_mode;\n\n/** List of all modes available */\nextern const SpeexMode * const speex_mode_list[SPEEX_NB_MODES];\n\n/** Obtain one of the modes available */\nconst SpeexMode * speex_lib_get_mode (int mode);\n\n#if (!defined(WIN32) && !defined(WIN64))\n/* We actually override the function in the narrowband case so that we can avoid linking in the wideband stuff */\n#define speex_lib_get_mode(mode) ((mode)==SPEEX_MODEID_NB ? &speex_nb_mode : speex_lib_get_mode (mode))\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n/** @}*/\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/include/speex/speex_bits.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin */\n/**\n   @file speex_bits.h\n   @brief Handles bit packing/unpacking\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifndef BITS_H\n#define BITS_H\n/** @defgroup SpeexBits SpeexBits: Bit-stream manipulations\n *  This is the structure that holds the bit-stream when encoding or decoding\n * with Speex. It allows some manipulations as well.\n *  @{\n */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** Bit-packing data structure representing (part of) a bit-stream. */\ntypedef struct SpeexBits {\n   char *chars;   /**< \"raw\" data */\n   int   nbBits;  /**< Total number of bits stored in the stream*/\n   int   charPtr; /**< Position of the byte \"cursor\" */\n   int   bitPtr;  /**< Position of the bit \"cursor\" within the current char */\n   int   owner;   /**< Does the struct \"own\" the \"raw\" buffer (member \"chars\") */\n   int   overflow;/**< Set to one if we try to read past the valid data */\n   int   buf_size;/**< Allocated size for buffer */\n   int   reserved1; /**< Reserved for future use */\n   void *reserved2; /**< Reserved for future use */\n} SpeexBits;\n\n/** Initializes and allocates resources for a SpeexBits struct */\nvoid speex_bits_init(SpeexBits *bits);\n\n/** Initializes SpeexBits struct using a pre-allocated buffer*/\nvoid speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size);\n\n/** Sets the bits in a SpeexBits struct to use data from an existing buffer (for decoding without copying data) */\nvoid speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size);\n\n/** Frees all resources associated to a SpeexBits struct. Right now this does nothing since no resources are allocated, but this could change in the future.*/\nvoid speex_bits_destroy(SpeexBits *bits);\n\n/** Resets bits to initial value (just after initialization, erasing content)*/\nvoid speex_bits_reset(SpeexBits *bits);\n\n/** Rewind the bit-stream to the beginning (ready for read) without erasing the content */\nvoid speex_bits_rewind(SpeexBits *bits);\n\n/** Initializes the bit-stream from the data in an area of memory */\nvoid speex_bits_read_from(SpeexBits *bits, char *bytes, int len);\n\n/** Append bytes to the bit-stream\n * \n * @param bits Bit-stream to operate on\n * @param bytes pointer to the bytes what will be appended\n * @param len Number of bytes of append\n */\nvoid speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len);\n\n/** Write the content of a bit-stream to an area of memory\n * \n * @param bits Bit-stream to operate on\n * @param bytes Memory location where to write the bits\n * @param max_len Maximum number of bytes to write (i.e. size of the \"bytes\" buffer)\n * @return Number of bytes written to the \"bytes\" buffer\n*/\nint speex_bits_write(SpeexBits *bits, char *bytes, int max_len);\n\n/** Like speex_bits_write, but writes only the complete bytes in the stream. Also removes the written bytes from the stream */\nint speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len);\n\n/** Append bits to the bit-stream\n * @param bits Bit-stream to operate on\n * @param data Value to append as integer\n * @param nbBits number of bits to consider in \"data\"\n */\nvoid speex_bits_pack(SpeexBits *bits, int data, int nbBits);\n\n/** Interpret the next bits in the bit-stream as a signed integer\n *\n * @param bits Bit-stream to operate on\n * @param nbBits Number of bits to interpret\n * @return A signed integer represented by the bits read\n */\nint speex_bits_unpack_signed(SpeexBits *bits, int nbBits);\n\n/** Interpret the next bits in the bit-stream as an unsigned integer\n *\n * @param bits Bit-stream to operate on\n * @param nbBits Number of bits to interpret\n * @return An unsigned integer represented by the bits read\n */\nunsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits);\n\n/** Returns the number of bytes in the bit-stream, including the last one even if it is not \"full\"\n *\n * @param bits Bit-stream to operate on\n * @return Number of bytes in the stream\n */\nint speex_bits_nbytes(SpeexBits *bits);\n\n/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position \n * \n * @param bits Bit-stream to operate on\n * @param nbBits Number of bits to look for\n * @return Value of the bits peeked, interpreted as unsigned\n */\nunsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits);\n\n/** Get the value of the next bit in the stream, without modifying the\n * \"cursor\" position \n * \n * @param bits Bit-stream to operate on\n * @return Value of the bit peeked (one bit only)\n */\nint speex_bits_peek(SpeexBits *bits);\n\n/** Advances the position of the \"bit cursor\" in the stream \n *\n * @param bits Bit-stream to operate on\n * @param n Number of bits to advance\n */\nvoid speex_bits_advance(SpeexBits *bits, int n);\n\n/** Returns the number of bits remaining to be read in a stream\n *\n * @param bits Bit-stream to operate on\n * @return Number of bits that can still be read from the stream\n */\nint speex_bits_remaining(SpeexBits *bits);\n\n/** Insert a terminator so that the data can be sent as a packet while auto-detecting \n * the number of frames in each packet \n *\n * @param bits Bit-stream to operate on\n */\nvoid speex_bits_insert_terminator(SpeexBits *bits);\n\n#ifdef __cplusplus\n}\n#endif\n\n/* @} */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/include/speex/speex_buffer.h",
    "content": "/* Copyright (C) 2007 Jean-Marc Valin\n      \n   File: speex_buffer.h\n   This is a very simple ring buffer implementation. It is not thread-safe\n   so you need to do your own locking.\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef SPEEX_BUFFER_H\n#define SPEEX_BUFFER_H\n\n#include \"speex/speex_types.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct SpeexBuffer_;\ntypedef struct SpeexBuffer_ SpeexBuffer;\n\nSpeexBuffer *speex_buffer_init(int size);\n\nvoid speex_buffer_destroy(SpeexBuffer *st);\n\nint speex_buffer_write(SpeexBuffer *st, void *data, int len);\n\nint speex_buffer_writezeros(SpeexBuffer *st, int len);\n\nint speex_buffer_read(SpeexBuffer *st, void *data, int len);\n\nint speex_buffer_get_available(SpeexBuffer *st);\n\nint speex_buffer_resize(SpeexBuffer *st, int len);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/include/speex/speex_callbacks.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin*/\n/**\n  @file speex_callbacks.h\n  @brief Describes callback handling and in-band signalling\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifndef SPEEX_CALLBACKS_H\n#define SPEEX_CALLBACKS_H\n/** @defgroup SpeexCallbacks Various definitions for Speex callbacks supported by the decoder.\n *  @{\n */\n\n#include \"speex.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** Total number of callbacks */\n#define SPEEX_MAX_CALLBACKS 16\n\n/* Describes all the in-band requests */\n\n/*These are 1-bit requests*/\n/** Request for perceptual enhancement (1 for on, 0 for off) */\n#define SPEEX_INBAND_ENH_REQUEST         0\n/** Reserved */\n#define SPEEX_INBAND_RESERVED1           1\n\n/*These are 4-bit requests*/\n/** Request for a mode change */\n#define SPEEX_INBAND_MODE_REQUEST        2\n/** Request for a low mode change */\n#define SPEEX_INBAND_LOW_MODE_REQUEST    3\n/** Request for a high mode change */\n#define SPEEX_INBAND_HIGH_MODE_REQUEST   4\n/** Request for VBR (1 on, 0 off) */\n#define SPEEX_INBAND_VBR_QUALITY_REQUEST 5\n/** Request to be sent acknowledge */\n#define SPEEX_INBAND_ACKNOWLEDGE_REQUEST 6\n/** Request for VBR (1 for on, 0 for off) */\n#define SPEEX_INBAND_VBR_REQUEST         7\n\n/*These are 8-bit requests*/\n/** Send a character in-band */\n#define SPEEX_INBAND_CHAR                8\n/** Intensity stereo information */\n#define SPEEX_INBAND_STEREO              9\n\n/*These are 16-bit requests*/\n/** Transmit max bit-rate allowed */\n#define SPEEX_INBAND_MAX_BITRATE         10\n\n/*These are 32-bit requests*/\n/** Acknowledge packet reception */\n#define SPEEX_INBAND_ACKNOWLEDGE         12\n\n/** Callback function type */\ntypedef int (*speex_callback_func)(SpeexBits *bits, void *state, void *data);\n\n/** Callback information */\ntypedef struct SpeexCallback {\n   int callback_id;             /**< ID associated to the callback */\n   speex_callback_func func;    /**< Callback handler function */\n   void *data;                  /**< Data that will be sent to the handler */\n   void *reserved1;             /**< Reserved for future use */\n   int   reserved2;             /**< Reserved for future use */\n} SpeexCallback;\n\n/** Handle in-band request */\nint speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state);\n\n/** Standard handler for mode request (change mode, no questions asked) */\nint speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data);\n\n/** Standard handler for high mode request (change high mode, no questions asked) */\nint speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data);\n\n/** Standard handler for in-band characters (write to stderr) */\nint speex_std_char_handler(SpeexBits *bits, void *state, void *data);\n\n/** Default handler for user-defined requests: in this case, just ignore */\nint speex_default_user_handler(SpeexBits *bits, void *state, void *data);\n\n\n\n/** Standard handler for low mode request (change low mode, no questions asked) */\nint speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data);\n\n/** Standard handler for VBR request (Set VBR, no questions asked) */\nint speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data);\n\n/** Standard handler for enhancer request (Turn enhancer on/off, no questions asked) */\nint speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data);\n\n/** Standard handler for VBR quality request (Set VBR quality, no questions asked) */\nint speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data);\n\n\n#ifdef __cplusplus\n}\n#endif\n\n/** @} */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/include/speex/speex_config_types.h.in",
    "content": "#ifndef __SPEEX_TYPES_H__\n#define __SPEEX_TYPES_H__\n\n/* these are filled in by configure */\ntypedef @SIZE16@ spx_int16_t;\ntypedef unsigned @SIZE16@ spx_uint16_t;\ntypedef @SIZE32@ spx_int32_t;\ntypedef unsigned @SIZE32@ spx_uint32_t;\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/include/speex/speex_echo.h",
    "content": "/* Copyright (C) Jean-Marc Valin */\n/**\n   @file speex_echo.h\n   @brief Echo cancellation\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef SPEEX_ECHO_H\n#define SPEEX_ECHO_H\n/** @defgroup SpeexEchoState SpeexEchoState: Acoustic echo canceller\n *  This is the acoustic echo canceller module.\n *  @{\n */\n#include \"speex/speex_types.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** Obtain frame size used by the AEC */\n#define SPEEX_ECHO_GET_FRAME_SIZE 3\n\n/** Set sampling rate */\n#define SPEEX_ECHO_SET_SAMPLING_RATE 24\n/** Get sampling rate */\n#define SPEEX_ECHO_GET_SAMPLING_RATE 25\n\n/* Can't set window sizes */\n/** Get size of impulse response (int32) */\n#define SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE 27\n\n/* Can't set window content */\n/** Get impulse response (int32[]) */\n#define SPEEX_ECHO_GET_IMPULSE_RESPONSE 29\n\n/** Internal echo canceller state. Should never be accessed directly. */\nstruct SpeexEchoState_;\n\n/** @class SpeexEchoState\n * This holds the state of the echo canceller. You need one per channel. \n*/\n\n/** Internal echo canceller state. Should never be accessed directly. */\ntypedef struct SpeexEchoState_ SpeexEchoState;\n\n/** Creates a new echo canceller state\n * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms)\n * @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms)\n * @return Newly-created echo canceller state\n */\nSpeexEchoState *speex_echo_state_init(int frame_size, int filter_length);\n\n/** Creates a new multi-channel echo canceller state\n * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms)\n * @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms)\n * @param nb_mic Number of microphone channels\n * @param nb_speakers Number of speaker channels\n * @return Newly-created echo canceller state\n */\nSpeexEchoState *speex_echo_state_init_mc(int frame_size, int filter_length, int nb_mic, int nb_speakers);\n\n/** Destroys an echo canceller state \n * @param st Echo canceller state\n*/\nvoid speex_echo_state_destroy(SpeexEchoState *st);\n\n/** Performs echo cancellation a frame, based on the audio sent to the speaker (no delay is added\n * to playback in this form)\n *\n * @param st Echo canceller state\n * @param rec Signal from the microphone (near end + far end echo)\n * @param play Signal played to the speaker (received from far end)\n * @param out Returns near-end signal with echo removed\n */\nvoid speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out);\n\n/** Performs echo cancellation a frame (deprecated) */\nvoid speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out, spx_int32_t *Yout);\n\n/** Perform echo cancellation using internal playback buffer, which is delayed by two frames\n * to account for the delay introduced by most soundcards (but it could be off!)\n * @param st Echo canceller state\n * @param rec Signal from the microphone (near end + far end echo)\n * @param out Returns near-end signal with echo removed\n*/\nvoid speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out);\n\n/** Let the echo canceller know that a frame was just queued to the soundcard\n * @param st Echo canceller state\n * @param play Signal played to the speaker (received from far end)\n*/\nvoid speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play);\n\n/** Reset the echo canceller to its original state \n * @param st Echo canceller state\n */\nvoid speex_echo_state_reset(SpeexEchoState *st);\n\n/** Used like the ioctl function to control the echo canceller parameters\n *\n * @param st Echo canceller state\n * @param request ioctl-type request (one of the SPEEX_ECHO_* macros)\n * @param ptr Data exchanged to-from function\n * @return 0 if no error, -1 if request in unknown\n */\nint speex_echo_ctl(SpeexEchoState *st, int request, void *ptr);\n\n\n\nstruct SpeexDecorrState_;\n\ntypedef struct SpeexDecorrState_ SpeexDecorrState;\n\n\n/** Create a state for the channel decorrelation algorithm\n    This is useful for multi-channel echo cancellation only \n * @param rate Sampling rate\n * @param channels Number of channels (it's a bit pointless if you don't have at least 2)\n * @param frame_size Size of the frame to process at ones (counting samples *per* channel)\n*/\nSpeexDecorrState *speex_decorrelate_new(int rate, int channels, int frame_size);\n\n/** Remove correlation between the channels by modifying the phase and possibly\n    adding noise in a way that is not (or little) perceptible.\n * @param st Decorrelator state\n * @param in Input audio in interleaved format\n * @param out Result of the decorrelation (out *may* alias in)\n * @param strength How much alteration of the audio to apply from 0 to 100.\n*/\nvoid speex_decorrelate(SpeexDecorrState *st, const spx_int16_t *in, spx_int16_t *out, int strength);\n\n/** Destroy a Decorrelation state \n * @param st State to destroy\n*/\nvoid speex_decorrelate_destroy(SpeexDecorrState *st);\n\n\n#ifdef __cplusplus\n}\n#endif\n\n\n/** @}*/\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/include/speex/speex_header.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin */\n/**\n   @file speex_header.h\n   @brief Describes the Speex header\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n\n#ifndef SPEEX_HEADER_H\n#define SPEEX_HEADER_H\n/** @defgroup SpeexHeader SpeexHeader: Makes it easy to write/parse an Ogg/Speex header\n *  This is the Speex header for the Ogg encapsulation. You don't need that if you just use RTP.\n *  @{\n */\n\n#include \"speex/speex_types.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct SpeexMode;\n\n/** Length of the Speex header identifier */\n#define SPEEX_HEADER_STRING_LENGTH 8\n\n/** Maximum number of characters for encoding the Speex version number in the header */\n#define SPEEX_HEADER_VERSION_LENGTH 20\n\n/** Speex header info for file-based formats */\ntypedef struct SpeexHeader {\n   char speex_string[SPEEX_HEADER_STRING_LENGTH];   /**< Identifies a Speex bit-stream, always set to \"Speex   \" */\n   char speex_version[SPEEX_HEADER_VERSION_LENGTH]; /**< Speex version */ \n   spx_int32_t speex_version_id;       /**< Version for Speex (for checking compatibility) */\n   spx_int32_t header_size;            /**< Total size of the header ( sizeof(SpeexHeader) ) */\n   spx_int32_t rate;                   /**< Sampling rate used */\n   spx_int32_t mode;                   /**< Mode used (0 for narrowband, 1 for wideband) */\n   spx_int32_t mode_bitstream_version; /**< Version ID of the bit-stream */\n   spx_int32_t nb_channels;            /**< Number of channels encoded */\n   spx_int32_t bitrate;                /**< Bit-rate used */\n   spx_int32_t frame_size;             /**< Size of frames */\n   spx_int32_t vbr;                    /**< 1 for a VBR encoding, 0 otherwise */\n   spx_int32_t frames_per_packet;      /**< Number of frames stored per Ogg packet */\n   spx_int32_t extra_headers;          /**< Number of additional headers after the comments */\n   spx_int32_t reserved1;              /**< Reserved for future use, must be zero */\n   spx_int32_t reserved2;              /**< Reserved for future use, must be zero */\n} SpeexHeader;\n\n/** Initializes a SpeexHeader using basic information */\nvoid speex_init_header(SpeexHeader *header, int rate, int nb_channels, const struct SpeexMode *m);\n\n/** Creates the header packet from the header itself (mostly involves endianness conversion) */\nchar *speex_header_to_packet(SpeexHeader *header, int *size);\n\n/** Creates a SpeexHeader from a packet */\nSpeexHeader *speex_packet_to_header(char *packet, int size);\n\n/** Frees the memory allocated by either speex_header_to_packet() or speex_packet_to_header() */\nvoid speex_header_free(void *ptr);\n\n#ifdef __cplusplus\n}\n#endif\n\n/** @} */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/include/speex/speex_jitter.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin */\n/**\n   @file speex_jitter.h\n   @brief Adaptive jitter buffer for Speex\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifndef SPEEX_JITTER_H\n#define SPEEX_JITTER_H\n/** @defgroup JitterBuffer JitterBuffer: Adaptive jitter buffer\n *  This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size\n * to maintain good quality and low latency.\n *  @{\n */\n\n#include \"speex/speex_types.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** Generic adaptive jitter buffer state */\nstruct JitterBuffer_;\n\n/** Generic adaptive jitter buffer state */\ntypedef struct JitterBuffer_ JitterBuffer;\n\n/** Definition of an incoming packet */\ntypedef struct _JitterBufferPacket JitterBufferPacket;\n\n/** Definition of an incoming packet */\nstruct _JitterBufferPacket {\n   char        *data;       /**< Data bytes contained in the packet */\n   spx_uint32_t len;        /**< Length of the packet in bytes */\n   spx_uint32_t timestamp;  /**< Timestamp for the packet */\n   spx_uint32_t span;       /**< Time covered by the packet (same units as timestamp) */\n   spx_uint16_t sequence;   /**< RTP Sequence number if available (0 otherwise) */\n   spx_uint32_t user_data;  /**< Put whatever data you like here (it's ignored by the jitter buffer) */\n};\n\n/** Packet has been retrieved */\n#define JITTER_BUFFER_OK 0\n/** Packet is lost or is late */\n#define JITTER_BUFFER_MISSING 1\n/** A \"fake\" packet is meant to be inserted here to increase buffering */\n#define JITTER_BUFFER_INSERTION 2\n/** There was an error in the jitter buffer */\n#define JITTER_BUFFER_INTERNAL_ERROR -1\n/** Invalid argument */\n#define JITTER_BUFFER_BAD_ARGUMENT -2\n\n\n/** Set minimum amount of extra buffering required (margin) */\n#define JITTER_BUFFER_SET_MARGIN 0\n/** Get minimum amount of extra buffering required (margin) */\n#define JITTER_BUFFER_GET_MARGIN 1\n/* JITTER_BUFFER_SET_AVAILABLE_COUNT wouldn't make sense */\n\n/** Get the amount of available packets currently buffered */\n#define JITTER_BUFFER_GET_AVAILABLE_COUNT 3\n/** Included because of an early misspelling (will remove in next release) */\n#define JITTER_BUFFER_GET_AVALIABLE_COUNT 3\n\n/** Assign a function to destroy unused packet. When setting that, the jitter \n    buffer no longer copies packet data. */\n#define JITTER_BUFFER_SET_DESTROY_CALLBACK 4\n/**  */\n#define JITTER_BUFFER_GET_DESTROY_CALLBACK 5\n\n/** Tell the jitter buffer to only adjust the delay in multiples of the step parameter provided */\n#define JITTER_BUFFER_SET_DELAY_STEP 6\n/**  */\n#define JITTER_BUFFER_GET_DELAY_STEP 7\n\n/** Tell the jitter buffer to only do concealment in multiples of the size parameter provided */\n#define JITTER_BUFFER_SET_CONCEALMENT_SIZE 8\n#define JITTER_BUFFER_GET_CONCEALMENT_SIZE 9\n\n/** Absolute max amount of loss that can be tolerated regardless of the delay. Typical loss \n    should be half of that or less. */\n#define JITTER_BUFFER_SET_MAX_LATE_RATE 10\n#define JITTER_BUFFER_GET_MAX_LATE_RATE 11\n\n/** Equivalent cost of one percent late packet in timestamp units */\n#define JITTER_BUFFER_SET_LATE_COST 12\n#define JITTER_BUFFER_GET_LATE_COST 13\n\n\n/** Initialises jitter buffer \n * \n * @param step_size Starting value for the size of concleanment packets and delay \n       adjustment steps. Can be changed at any time using JITTER_BUFFER_SET_DELAY_STEP\n       and JITTER_BUFFER_GET_CONCEALMENT_SIZE.\n * @return Newly created jitter buffer state\n */\nJitterBuffer *jitter_buffer_init(int step_size);\n\n/** Restores jitter buffer to its original state \n * \n * @param jitter Jitter buffer state\n */\nvoid jitter_buffer_reset(JitterBuffer *jitter);\n\n/** Destroys jitter buffer \n * \n * @param jitter Jitter buffer state\n */\nvoid jitter_buffer_destroy(JitterBuffer *jitter);\n\n/** Put one packet into the jitter buffer\n * \n * @param jitter Jitter buffer state\n * @param packet Incoming packet\n*/\nvoid jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet);\n\n/** Get one packet from the jitter buffer\n * \n * @param jitter Jitter buffer state\n * @param packet Returned packet\n * @param desired_span Number of samples (or units) we wish to get from the buffer (no guarantee)\n * @param current_timestamp Timestamp for the returned packet \n*/\nint jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset);\n\n/** Used right after jitter_buffer_get() to obtain another packet that would have the same timestamp.\n * This is mainly useful for media where a single \"frame\" can be split into several packets.\n * \n * @param jitter Jitter buffer state\n * @param packet Returned packet\n */\nint jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet);\n\n/** Get pointer timestamp of jitter buffer\n * \n * @param jitter Jitter buffer state\n*/\nint jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter);\n\n/** Advance by one tick\n * \n * @param jitter Jitter buffer state\n*/\nvoid jitter_buffer_tick(JitterBuffer *jitter);\n\n/** Telling the jitter buffer about the remaining data in the application buffer\n * @param jitter Jitter buffer state\n * @param rem Amount of data buffered by the application (timestamp units)\n */\nvoid jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem);\n\n/** Used like the ioctl function to control the jitter buffer parameters\n * \n * @param jitter Jitter buffer state\n * @param request ioctl-type request (one of the JITTER_BUFFER_* macros)\n * @param ptr Data exchanged to-from function\n * @return 0 if no error, -1 if request in unknown\n*/\nint jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr);\n\nint jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset);\n\n/* @} */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/include/speex/speex_preprocess.h",
    "content": "/* Copyright (C) 2003 Epic Games\n   Written by Jean-Marc Valin */\n/**\n *  @file speex_preprocess.h\n *  @brief Speex preprocessor. The preprocess can do noise suppression, \n * residual echo suppression (after using the echo canceller), automatic\n * gain control (AGC) and voice activity detection (VAD).\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef SPEEX_PREPROCESS_H\n#define SPEEX_PREPROCESS_H\n/** @defgroup SpeexPreprocessState SpeexPreprocessState: The Speex preprocessor\n *  This is the Speex preprocessor. The preprocess can do noise suppression, \n * residual echo suppression (after using the echo canceller), automatic\n * gain control (AGC) and voice activity detection (VAD).\n *  @{\n */\n\n#include \"speex/speex_types.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n   \n/** State of the preprocessor (one per channel). Should never be accessed directly. */\nstruct SpeexPreprocessState_;\n\n/** State of the preprocessor (one per channel). Should never be accessed directly. */\ntypedef struct SpeexPreprocessState_ SpeexPreprocessState;\n\n\n/** Creates a new preprocessing state. You MUST create one state per channel processed.\n * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms). Must be\n * the same value as that used for the echo canceller for residual echo cancellation to work.\n * @param sampling_rate Sampling rate used for the input.\n * @return Newly created preprocessor state\n*/\nSpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate);\n\n/** Destroys a preprocessor state \n * @param st Preprocessor state to destroy\n*/\nvoid speex_preprocess_state_destroy(SpeexPreprocessState *st);\n\n/** Preprocess a frame \n * @param st Preprocessor state\n * @param x Audio sample vector (in and out). Must be same size as specified in speex_preprocess_state_init().\n * @return Bool value for voice activity (1 for speech, 0 for noise/silence), ONLY if VAD turned on.\n*/\nint speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x);\n\n/** Preprocess a frame (deprecated, use speex_preprocess_run() instead)*/\nint speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo);\n\n/** Update preprocessor state, but do not compute the output\n * @param st Preprocessor state\n * @param x Audio sample vector (in only). Must be same size as specified in speex_preprocess_state_init().\n*/\nvoid speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x);\n\n/** Used like the ioctl function to control the preprocessor parameters \n * @param st Preprocessor state\n * @param request ioctl-type request (one of the SPEEX_PREPROCESS_* macros)\n * @param ptr Data exchanged to-from function\n * @return 0 if no error, -1 if request in unknown\n*/\nint speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr);\n\n\n\n/** Set preprocessor denoiser state */\n#define SPEEX_PREPROCESS_SET_DENOISE 0\n/** Get preprocessor denoiser state */\n#define SPEEX_PREPROCESS_GET_DENOISE 1\n\n/** Set preprocessor Automatic Gain Control state */\n#define SPEEX_PREPROCESS_SET_AGC 2\n/** Get preprocessor Automatic Gain Control state */\n#define SPEEX_PREPROCESS_GET_AGC 3\n\n/** Set preprocessor Voice Activity Detection state */\n#define SPEEX_PREPROCESS_SET_VAD 4\n/** Get preprocessor Voice Activity Detection state */\n#define SPEEX_PREPROCESS_GET_VAD 5\n\n/** Set preprocessor Automatic Gain Control level (float) */\n#define SPEEX_PREPROCESS_SET_AGC_LEVEL 6\n/** Get preprocessor Automatic Gain Control level (float) */\n#define SPEEX_PREPROCESS_GET_AGC_LEVEL 7\n\n/** Set preprocessor dereverb state */\n#define SPEEX_PREPROCESS_SET_DEREVERB 8\n/** Get preprocessor dereverb state */\n#define SPEEX_PREPROCESS_GET_DEREVERB 9\n\n/** Set preprocessor dereverb level */\n#define SPEEX_PREPROCESS_SET_DEREVERB_LEVEL 10\n/** Get preprocessor dereverb level */\n#define SPEEX_PREPROCESS_GET_DEREVERB_LEVEL 11\n\n/** Set preprocessor dereverb decay */\n#define SPEEX_PREPROCESS_SET_DEREVERB_DECAY 12\n/** Get preprocessor dereverb decay */\n#define SPEEX_PREPROCESS_GET_DEREVERB_DECAY 13\n\n/** Set probability required for the VAD to go from silence to voice */\n#define SPEEX_PREPROCESS_SET_PROB_START 14\n/** Get probability required for the VAD to go from silence to voice */\n#define SPEEX_PREPROCESS_GET_PROB_START 15\n\n/** Set probability required for the VAD to stay in the voice state (integer percent) */\n#define SPEEX_PREPROCESS_SET_PROB_CONTINUE 16\n/** Get probability required for the VAD to stay in the voice state (integer percent) */\n#define SPEEX_PREPROCESS_GET_PROB_CONTINUE 17\n\n/** Set maximum attenuation of the noise in dB (negative number) */\n#define SPEEX_PREPROCESS_SET_NOISE_SUPPRESS 18\n/** Get maximum attenuation of the noise in dB (negative number) */\n#define SPEEX_PREPROCESS_GET_NOISE_SUPPRESS 19\n\n/** Set maximum attenuation of the residual echo in dB (negative number) */\n#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS 20\n/** Get maximum attenuation of the residual echo in dB (negative number) */\n#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS 21\n\n/** Set maximum attenuation of the residual echo in dB when near end is active (negative number) */\n#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE 22\n/** Get maximum attenuation of the residual echo in dB when near end is active (negative number) */\n#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE 23\n\n/** Set the corresponding echo canceller state so that residual echo suppression can be performed (NULL for no residual echo suppression) */\n#define SPEEX_PREPROCESS_SET_ECHO_STATE 24\n/** Get the corresponding echo canceller state */\n#define SPEEX_PREPROCESS_GET_ECHO_STATE 25\n\n/** Set maximal gain increase in dB/second (int32) */\n#define SPEEX_PREPROCESS_SET_AGC_INCREMENT 26\n\n/** Get maximal gain increase in dB/second (int32) */\n#define SPEEX_PREPROCESS_GET_AGC_INCREMENT 27\n\n/** Set maximal gain decrease in dB/second (int32) */\n#define SPEEX_PREPROCESS_SET_AGC_DECREMENT 28\n\n/** Get maximal gain decrease in dB/second (int32) */\n#define SPEEX_PREPROCESS_GET_AGC_DECREMENT 29\n\n/** Set maximal gain in dB (int32) */\n#define SPEEX_PREPROCESS_SET_AGC_MAX_GAIN 30\n\n/** Get maximal gain in dB (int32) */\n#define SPEEX_PREPROCESS_GET_AGC_MAX_GAIN 31\n\n/*  Can't set loudness */\n/** Get loudness */\n#define SPEEX_PREPROCESS_GET_AGC_LOUDNESS 33\n\n/*  Can't set gain */\n/** Get current gain (int32 percent) */\n#define SPEEX_PREPROCESS_GET_AGC_GAIN 35\n\n/*  Can't set spectrum size */\n/** Get spectrum size for power spectrum (int32) */\n#define SPEEX_PREPROCESS_GET_PSD_SIZE 37\n\n/*  Can't set power spectrum */\n/** Get power spectrum (int32[] of squared values) */\n#define SPEEX_PREPROCESS_GET_PSD 39\n\n/*  Can't set noise size */\n/** Get spectrum size for noise estimate (int32)  */\n#define SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE 41\n\n/*  Can't set noise estimate */\n/** Get noise estimate (int32[] of squared values) */\n#define SPEEX_PREPROCESS_GET_NOISE_PSD 43\n\n/* Can't set speech probability */\n/** Get speech probability in last frame (int32).  */\n#define SPEEX_PREPROCESS_GET_PROB 45\n\n/** Set preprocessor Automatic Gain Control level (int32) */\n#define SPEEX_PREPROCESS_SET_AGC_TARGET 46\n/** Get preprocessor Automatic Gain Control level (int32) */\n#define SPEEX_PREPROCESS_GET_AGC_TARGET 47\n\n#ifdef __cplusplus\n}\n#endif\n\n/** @}*/\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/include/speex/speex_resampler.h",
    "content": "/* Copyright (C) 2007 Jean-Marc Valin\n      \n   File: speex_resampler.h\n   Resampling code\n      \n   The design goals of this code are:\n      - Very fast algorithm\n      - Low memory requirement\n      - Good *perceptual* quality (and not best SNR)\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\n#ifndef SPEEX_RESAMPLER_H\n#define SPEEX_RESAMPLER_H\n\n#ifdef OUTSIDE_SPEEX\n\n/********* WARNING: MENTAL SANITY ENDS HERE *************/\n\n/* If the resampler is defined outside of Speex, we change the symbol names so that \n   there won't be any clash if linking with Speex later on. */\n\n/* #define RANDOM_PREFIX your software name here */\n#ifndef RANDOM_PREFIX\n#error \"Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes\"\n#endif\n\n#define CAT_PREFIX2(a,b) a ## b\n#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b)\n      \n#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init)\n#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac)\n#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy)\n#define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float)\n#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int)\n#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float)\n#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int)\n#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate)\n#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate)\n#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac)\n#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio)\n#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality)\n#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality)\n#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride)\n#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride)\n#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride)\n#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride)\n#define speex_resampler_get_input_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_latency)\n#define speex_resampler_get_output_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_latency)\n#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros)\n#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)\n#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)\n\n#define spx_int16_t short\n#define spx_int32_t int\n#define spx_uint16_t unsigned short\n#define spx_uint32_t unsigned int\n      \n#else /* OUTSIDE_SPEEX */\n\n#include \"speex/speex_types.h\"\n\n#endif /* OUTSIDE_SPEEX */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define SPEEX_RESAMPLER_QUALITY_MAX 10\n#define SPEEX_RESAMPLER_QUALITY_MIN 0\n#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4\n#define SPEEX_RESAMPLER_QUALITY_VOIP 3\n#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5\n\nenum {\n   RESAMPLER_ERR_SUCCESS         = 0,\n   RESAMPLER_ERR_ALLOC_FAILED    = 1,\n   RESAMPLER_ERR_BAD_STATE       = 2,\n   RESAMPLER_ERR_INVALID_ARG     = 3,\n   RESAMPLER_ERR_PTR_OVERLAP     = 4,\n   \n   RESAMPLER_ERR_MAX_ERROR\n};\n\nstruct SpeexResamplerState_;\ntypedef struct SpeexResamplerState_ SpeexResamplerState;\n\n/** Create a new resampler with integer input and output rates.\n * @param nb_channels Number of channels to be processed\n * @param in_rate Input sampling rate (integer number of Hz).\n * @param out_rate Output sampling rate (integer number of Hz).\n * @param quality Resampling quality between 0 and 10, where 0 has poor quality\n * and 10 has very high quality.\n * @return Newly created resampler state\n * @retval NULL Error: not enough memory\n */\nSpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, \n                                          spx_uint32_t in_rate, \n                                          spx_uint32_t out_rate, \n                                          int quality,\n                                          int *err);\n\n/** Create a new resampler with fractional input/output rates. The sampling \n * rate ratio is an arbitrary rational number with both the numerator and \n * denominator being 32-bit integers.\n * @param nb_channels Number of channels to be processed\n * @param ratio_num Numerator of the sampling rate ratio\n * @param ratio_den Denominator of the sampling rate ratio\n * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).\n * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).\n * @param quality Resampling quality between 0 and 10, where 0 has poor quality\n * and 10 has very high quality.\n * @return Newly created resampler state\n * @retval NULL Error: not enough memory\n */\nSpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, \n                                               spx_uint32_t ratio_num, \n                                               spx_uint32_t ratio_den, \n                                               spx_uint32_t in_rate, \n                                               spx_uint32_t out_rate, \n                                               int quality,\n                                               int *err);\n\n/** Destroy a resampler state.\n * @param st Resampler state\n */\nvoid speex_resampler_destroy(SpeexResamplerState *st);\n\n/** Resample a float array. The input and output buffers must *not* overlap.\n * @param st Resampler state\n * @param channel_index Index of the channel to process for the multi-channel \n * base (0 otherwise)\n * @param in Input buffer\n * @param in_len Number of input samples in the input buffer. Returns the \n * number of samples processed\n * @param out Output buffer\n * @param out_len Size of the output buffer. Returns the number of samples written\n */\nint speex_resampler_process_float(SpeexResamplerState *st, \n                                   spx_uint32_t channel_index, \n                                   const float *in, \n                                   spx_uint32_t *in_len, \n                                   float *out, \n                                   spx_uint32_t *out_len);\n\n/** Resample an int array. The input and output buffers must *not* overlap.\n * @param st Resampler state\n * @param channel_index Index of the channel to process for the multi-channel \n * base (0 otherwise)\n * @param in Input buffer\n * @param in_len Number of input samples in the input buffer. Returns the number\n * of samples processed\n * @param out Output buffer\n * @param out_len Size of the output buffer. Returns the number of samples written\n */\nint speex_resampler_process_int(SpeexResamplerState *st, \n                                 spx_uint32_t channel_index, \n                                 const spx_int16_t *in, \n                                 spx_uint32_t *in_len, \n                                 spx_int16_t *out, \n                                 spx_uint32_t *out_len);\n\n/** Resample an interleaved float array. The input and output buffers must *not* overlap.\n * @param st Resampler state\n * @param in Input buffer\n * @param in_len Number of input samples in the input buffer. Returns the number\n * of samples processed. This is all per-channel.\n * @param out Output buffer\n * @param out_len Size of the output buffer. Returns the number of samples written.\n * This is all per-channel.\n */\nint speex_resampler_process_interleaved_float(SpeexResamplerState *st, \n                                               const float *in, \n                                               spx_uint32_t *in_len, \n                                               float *out, \n                                               spx_uint32_t *out_len);\n\n/** Resample an interleaved int array. The input and output buffers must *not* overlap.\n * @param st Resampler state\n * @param in Input buffer\n * @param in_len Number of input samples in the input buffer. Returns the number\n * of samples processed. This is all per-channel.\n * @param out Output buffer\n * @param out_len Size of the output buffer. Returns the number of samples written.\n * This is all per-channel.\n */\nint speex_resampler_process_interleaved_int(SpeexResamplerState *st, \n                                             const spx_int16_t *in, \n                                             spx_uint32_t *in_len, \n                                             spx_int16_t *out, \n                                             spx_uint32_t *out_len);\n\n/** Set (change) the input/output sampling rates (integer value).\n * @param st Resampler state\n * @param in_rate Input sampling rate (integer number of Hz).\n * @param out_rate Output sampling rate (integer number of Hz).\n */\nint speex_resampler_set_rate(SpeexResamplerState *st, \n                              spx_uint32_t in_rate, \n                              spx_uint32_t out_rate);\n\n/** Get the current input/output sampling rates (integer value).\n * @param st Resampler state\n * @param in_rate Input sampling rate (integer number of Hz) copied.\n * @param out_rate Output sampling rate (integer number of Hz) copied.\n */\nvoid speex_resampler_get_rate(SpeexResamplerState *st, \n                              spx_uint32_t *in_rate, \n                              spx_uint32_t *out_rate);\n\n/** Set (change) the input/output sampling rates and resampling ratio \n * (fractional values in Hz supported).\n * @param st Resampler state\n * @param ratio_num Numerator of the sampling rate ratio\n * @param ratio_den Denominator of the sampling rate ratio\n * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).\n * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).\n */\nint speex_resampler_set_rate_frac(SpeexResamplerState *st, \n                                   spx_uint32_t ratio_num, \n                                   spx_uint32_t ratio_den, \n                                   spx_uint32_t in_rate, \n                                   spx_uint32_t out_rate);\n\n/** Get the current resampling ratio. This will be reduced to the least\n * common denominator.\n * @param st Resampler state\n * @param ratio_num Numerator of the sampling rate ratio copied\n * @param ratio_den Denominator of the sampling rate ratio copied\n */\nvoid speex_resampler_get_ratio(SpeexResamplerState *st, \n                               spx_uint32_t *ratio_num, \n                               spx_uint32_t *ratio_den);\n\n/** Set (change) the conversion quality.\n * @param st Resampler state\n * @param quality Resampling quality between 0 and 10, where 0 has poor \n * quality and 10 has very high quality.\n */\nint speex_resampler_set_quality(SpeexResamplerState *st, \n                                 int quality);\n\n/** Get the conversion quality.\n * @param st Resampler state\n * @param quality Resampling quality between 0 and 10, where 0 has poor \n * quality and 10 has very high quality.\n */\nvoid speex_resampler_get_quality(SpeexResamplerState *st, \n                                 int *quality);\n\n/** Set (change) the input stride.\n * @param st Resampler state\n * @param stride Input stride\n */\nvoid speex_resampler_set_input_stride(SpeexResamplerState *st, \n                                      spx_uint32_t stride);\n\n/** Get the input stride.\n * @param st Resampler state\n * @param stride Input stride copied\n */\nvoid speex_resampler_get_input_stride(SpeexResamplerState *st, \n                                      spx_uint32_t *stride);\n\n/** Set (change) the output stride.\n * @param st Resampler state\n * @param stride Output stride\n */\nvoid speex_resampler_set_output_stride(SpeexResamplerState *st, \n                                      spx_uint32_t stride);\n\n/** Get the output stride.\n * @param st Resampler state copied\n * @param stride Output stride\n */\nvoid speex_resampler_get_output_stride(SpeexResamplerState *st, \n                                      spx_uint32_t *stride);\n\n/** Get the latency in input samples introduced by the resampler.\n * @param st Resampler state\n */\nint speex_resampler_get_input_latency(SpeexResamplerState *st);\n\n/** Get the latency in output samples introduced by the resampler.\n * @param st Resampler state\n */\nint speex_resampler_get_output_latency(SpeexResamplerState *st);\n\n/** Make sure that the first samples to go out of the resamplers don't have \n * leading zeros. This is only useful before starting to use a newly created \n * resampler. It is recommended to use that when resampling an audio file, as\n * it will generate a file with the same length. For real-time processing,\n * it is probably easier not to use this call (so that the output duration\n * is the same for the first frame).\n * @param st Resampler state\n */\nint speex_resampler_skip_zeros(SpeexResamplerState *st);\n\n/** Reset a resampler so a new (unrelated) stream can be processed.\n * @param st Resampler state\n */\nint speex_resampler_reset_mem(SpeexResamplerState *st);\n\n/** Returns the English meaning for an error code\n * @param err Error code\n * @return English string\n */\nconst char *speex_resampler_strerror(int err);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/include/speex/speex_stereo.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin*/\n/**\n   @file speex_stereo.h\n   @brief Describes the handling for intensity stereo\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef STEREO_H\n#define STEREO_H\n/** @defgroup SpeexStereoState SpeexStereoState: Handling Speex stereo files\n *  This describes the Speex intensity stereo encoding/decoding\n *  @{\n */\n\n#include \"speex/speex_types.h\"\n#include \"speex/speex_bits.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** If you access any of these fields directly, I'll personally come and bite you */\ntypedef struct SpeexStereoState {\n   float balance;      /**< Left/right balance info */\n   float e_ratio;      /**< Ratio of energies: E(left+right)/[E(left)+E(right)]  */\n   float smooth_left;  /**< Smoothed left channel gain */\n   float smooth_right; /**< Smoothed right channel gain */\n   float reserved1;    /**< Reserved for future use */\n   float reserved2;    /**< Reserved for future use */\n} SpeexStereoState;\n\n/** Deprecated. Use speex_stereo_state_init() instead. */\n#define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0}\n\n/** Initialise/create a stereo stereo state */\nSpeexStereoState *speex_stereo_state_init();\n\n/** Reset/re-initialise an already allocated stereo state */\nvoid speex_stereo_state_reset(SpeexStereoState *stereo);\n\n/** Destroy a stereo stereo state */\nvoid speex_stereo_state_destroy(SpeexStereoState *stereo);\n\n/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */\nvoid speex_encode_stereo(float *data, int frame_size, SpeexBits *bits);\n\n/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */\nvoid speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits);\n\n/** Transforms a mono frame into a stereo frame using intensity stereo info */\nvoid speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo);\n\n/** Transforms a mono frame into a stereo frame using intensity stereo info */\nvoid speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo);\n\n/** Callback handler for intensity stereo info */\nint speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data);\n\n#ifdef __cplusplus\n}\n#endif\n\n/** @} */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/include/speex/speex_types.h",
    "content": "/* speex_types.h taken from libogg */\n/********************************************************************\n *                                                                  *\n * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *\n * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *\n * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *\n * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *\n *                                                                  *\n * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *\n * by the Xiph.Org Foundation http://www.xiph.org/                  *\n *                                                                  *\n ********************************************************************\n\n function: #ifdef jail to whip a few platforms into the UNIX ideal.\n last mod: $Id: speex_types.h 2002 2008-06-10 14:09:37Z nanang $\n\n ********************************************************************/\n/**\n   @file speex_types.h\n   @brief Speex types\n*/\n#ifndef _SPEEX_TYPES_H\n#define _SPEEX_TYPES_H\n\n#if defined(_WIN32) \n\n#  if defined(__CYGWIN__)\n#    include <_G_config.h>\n     typedef _G_int32_t spx_int32_t;\n     typedef _G_uint32_t spx_uint32_t;\n     typedef _G_int16_t spx_int16_t;\n     typedef _G_uint16_t spx_uint16_t;\n#  elif defined(__MINGW32__)\n     typedef short spx_int16_t;\n     typedef unsigned short spx_uint16_t;\n     typedef int spx_int32_t;\n     typedef unsigned int spx_uint32_t;\n#  elif defined(__MWERKS__)\n     typedef int spx_int32_t;\n     typedef unsigned int spx_uint32_t;\n     typedef short spx_int16_t;\n     typedef unsigned short spx_uint16_t;\n#  else\n     /* MSVC/Borland */\n     typedef __int32 spx_int32_t;\n     typedef unsigned __int32 spx_uint32_t;\n     typedef __int16 spx_int16_t;\n     typedef unsigned __int16 spx_uint16_t;\n#  endif\n\n#elif defined(__MACOS__)\n\n#  include <sys/types.h>\n   typedef SInt16 spx_int16_t;\n   typedef UInt16 spx_uint16_t;\n   typedef SInt32 spx_int32_t;\n   typedef UInt32 spx_uint32_t;\n\n#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */\n\n#  include <sys/types.h>\n   typedef int16_t spx_int16_t;\n   typedef u_int16_t spx_uint16_t;\n   typedef int32_t spx_int32_t;\n   typedef u_int32_t spx_uint32_t;\n\n#elif defined(__BEOS__)\n\n   /* Be */\n#  include <inttypes.h>\n   typedef int16_t spx_int16_t;\n   typedef u_int16_t spx_uint16_t;\n   typedef int32_t spx_int32_t;\n   typedef u_int32_t spx_uint32_t;\n\n#elif defined (__EMX__)\n\n   /* OS/2 GCC */\n   typedef short spx_int16_t;\n   typedef unsigned short spx_uint16_t;\n   typedef int spx_int32_t;\n   typedef unsigned int spx_uint32_t;\n\n#elif defined (DJGPP)\n\n   /* DJGPP */\n   typedef short spx_int16_t;\n   typedef int spx_int32_t;\n   typedef unsigned int spx_uint32_t;\n\n#elif defined(R5900)\n\n   /* PS2 EE */\n   typedef int spx_int32_t;\n   typedef unsigned spx_uint32_t;\n   typedef short spx_int16_t;\n\n#elif defined(__SYMBIAN32__)\n\n   /* Symbian GCC */\n   typedef signed short spx_int16_t;\n   typedef unsigned short spx_uint16_t;\n   typedef signed int spx_int32_t;\n   typedef unsigned int spx_uint32_t;\n\n#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)\n\n   typedef short spx_int16_t;\n   typedef unsigned short spx_uint16_t;\n   typedef long spx_int32_t;\n   typedef unsigned long spx_uint32_t;\n\n#elif defined(CONFIG_TI_C6X)\n\n   typedef short spx_int16_t;\n   typedef unsigned short spx_uint16_t;\n   typedef int spx_int32_t;\n   typedef unsigned int spx_uint32_t;\n\n#else\n\n#  include <speex/speex_config_types.h>\n\n#endif\n\n#endif  /* _SPEEX_TYPES_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/_kiss_fft_guts.h",
    "content": "/*\nCopyright (c) 2003-2004, Mark Borgerding\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#define MIN(a,b) ((a)<(b) ? (a):(b))\n#define MAX(a,b) ((a)>(b) ? (a):(b))\n\n/* kiss_fft.h\n   defines kiss_fft_scalar as either short or a float type\n   and defines\n   typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */\n#include \"kiss_fft.h\"\n#include \"math_approx.h\"\n\n#define MAXFACTORS 32\n/* e.g. an fft of length 128 has 4 factors \n as far as kissfft is concerned\n 4*4*4*2\n */\n\nstruct kiss_fft_state{\n    int nfft;\n    int inverse;\n    int factors[2*MAXFACTORS];\n    kiss_fft_cpx twiddles[1];\n};\n\n/*\n  Explanation of macros dealing with complex math:\n\n   C_MUL(m,a,b)         : m = a*b\n   C_FIXDIV( c , div )  : if a fixed point impl., c /= div. noop otherwise\n   C_SUB( res, a,b)     : res = a - b\n   C_SUBFROM( res , a)  : res -= a\n   C_ADDTO( res , a)    : res += a\n * */\n#ifdef FIXED_POINT\n#include \"arch.h\"\n# define FRACBITS 15\n# define SAMPPROD spx_int32_t \n#define SAMP_MAX 32767\n\n#define SAMP_MIN -SAMP_MAX\n\n#if defined(CHECK_OVERFLOW)\n#  define CHECK_OVERFLOW_OP(a,op,b)  \\\n\tif ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \\\n\t\tfprintf(stderr,\"WARNING:overflow @ \" __FILE__ \"(%d): (%d \" #op\" %d) = %ld\\n\",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) );  }\n#endif\n\n\n#   define smul(a,b) ( (SAMPPROD)(a)*(b) )\n#   define sround( x )  (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS )\n\n#   define S_MUL(a,b) sround( smul(a,b) )\n\n#   define C_MUL(m,a,b) \\\n      do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \\\n          (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)\n\n#   define C_MUL4(m,a,b) \\\n               do{ (m).r = PSHR32( smul((a).r,(b).r) - smul((a).i,(b).i),17 ); \\\n               (m).i = PSHR32( smul((a).r,(b).i) + smul((a).i,(b).r),17 ); }while(0)\n\n#   define DIVSCALAR(x,k) \\\n\t(x) = sround( smul(  x, SAMP_MAX/k ) )\n\n#   define C_FIXDIV(c,div) \\\n\tdo {    DIVSCALAR( (c).r , div);  \\\n\t\tDIVSCALAR( (c).i  , div); }while (0)\n\n#   define C_MULBYSCALAR( c, s ) \\\n    do{ (c).r =  sround( smul( (c).r , s ) ) ;\\\n        (c).i =  sround( smul( (c).i , s ) ) ; }while(0)\n\n#else  /* not FIXED_POINT*/\n\n#   define S_MUL(a,b) ( (a)*(b) )\n#define C_MUL(m,a,b) \\\n    do{ (m).r = (a).r*(b).r - (a).i*(b).i;\\\n        (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)\n\n#define C_MUL4(m,a,b) C_MUL(m,a,b)\n\n#   define C_FIXDIV(c,div) /* NOOP */\n#   define C_MULBYSCALAR( c, s ) \\\n    do{ (c).r *= (s);\\\n        (c).i *= (s); }while(0)\n#endif\n\n#ifndef CHECK_OVERFLOW_OP\n#  define CHECK_OVERFLOW_OP(a,op,b) /* noop */\n#endif\n\n#define  C_ADD( res, a,b)\\\n    do { \\\n\t    CHECK_OVERFLOW_OP((a).r,+,(b).r)\\\n\t    CHECK_OVERFLOW_OP((a).i,+,(b).i)\\\n\t    (res).r=(a).r+(b).r;  (res).i=(a).i+(b).i; \\\n    }while(0)\n#define  C_SUB( res, a,b)\\\n    do { \\\n\t    CHECK_OVERFLOW_OP((a).r,-,(b).r)\\\n\t    CHECK_OVERFLOW_OP((a).i,-,(b).i)\\\n\t    (res).r=(a).r-(b).r;  (res).i=(a).i-(b).i; \\\n    }while(0)\n#define C_ADDTO( res , a)\\\n    do { \\\n\t    CHECK_OVERFLOW_OP((res).r,+,(a).r)\\\n\t    CHECK_OVERFLOW_OP((res).i,+,(a).i)\\\n\t    (res).r += (a).r;  (res).i += (a).i;\\\n    }while(0)\n\n#define C_SUBFROM( res , a)\\\n    do {\\\n\t    CHECK_OVERFLOW_OP((res).r,-,(a).r)\\\n\t    CHECK_OVERFLOW_OP((res).i,-,(a).i)\\\n\t    (res).r -= (a).r;  (res).i -= (a).i; \\\n    }while(0)\n\n\n#ifdef FIXED_POINT\n#  define KISS_FFT_COS(phase)  floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase))))\n#  define KISS_FFT_SIN(phase)  floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase))))\n#  define HALF_OF(x) ((x)>>1)\n#elif defined(USE_SIMD)\n#  define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )\n#  define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )\n#  define HALF_OF(x) ((x)*_mm_set1_ps(.5))\n#else\n#  define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)\n#  define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)\n#  define HALF_OF(x) ((x)*.5)\n#endif\n\n#define  kf_cexp(x,phase) \\\n\tdo{ \\\n\t\t(x)->r = KISS_FFT_COS(phase);\\\n\t\t(x)->i = KISS_FFT_SIN(phase);\\\n\t}while(0)\n#define  kf_cexp2(x,phase) \\\n               do{ \\\n               (x)->r = spx_cos_norm((phase));\\\n               (x)->i = spx_cos_norm((phase)-32768);\\\n}while(0)\n\n\n/* a debugging function */\n#define pcpx(c)\\\n    fprintf(stderr,\"%g + %gi\\n\",(double)((c)->r),(double)((c)->i) )\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/arch.h",
    "content": "/* Copyright (C) 2003 Jean-Marc Valin */\n/**\n   @file arch.h\n   @brief Various architecture definitions Speex\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef ARCH_H\n#define ARCH_H\n\n#ifndef SPEEX_VERSION\n#define SPEEX_MAJOR_VERSION 1         /**< Major Speex version. */\n#define SPEEX_MINOR_VERSION 1         /**< Minor Speex version. */\n#define SPEEX_MICRO_VERSION 15        /**< Micro Speex version. */\n#define SPEEX_EXTRA_VERSION \"\"        /**< Extra Speex version. */\n#define SPEEX_VERSION \"speex-1.2beta3\"  /**< Speex version string. */\n#endif\n\n/* A couple test to catch stupid option combinations */\n#ifdef FIXED_POINT\n\n#ifdef FLOATING_POINT\n#error You cannot compile as floating point and fixed point at the same time\n#endif\n#ifdef _USE_SSE\n#error SSE is only for floating-point\n#endif\n#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM))\n#error Make up your mind. What CPU do you have?\n#endif\n#ifdef VORBIS_PSYCHO\n#error Vorbis-psy model currently not implemented in fixed-point\n#endif\n\n#else\n\n#ifndef FLOATING_POINT\n#error You now need to define either FIXED_POINT or FLOATING_POINT\n#endif\n#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM)\n#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions?\n#endif\n#ifdef FIXED_POINT_DEBUG\n#error \"Don't you think enabling fixed-point is a good thing to do if you want to debug that?\"\n#endif\n\n\n#endif\n\n#ifndef OUTSIDE_SPEEX\n#include \"speex/speex_types.h\"\n#endif\n\n#define ABS(x) ((x) < 0 ? (-(x)) : (x))      /**< Absolute integer value. */\n#define ABS16(x) ((x) < 0 ? (-(x)) : (x))    /**< Absolute 16-bit value.  */\n#define MIN16(a,b) ((a) < (b) ? (a) : (b))   /**< Maximum 16-bit value.   */\n#define MAX16(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum 16-bit value.   */\n#define ABS32(x) ((x) < 0 ? (-(x)) : (x))    /**< Absolute 32-bit value.  */\n#define MIN32(a,b) ((a) < (b) ? (a) : (b))   /**< Maximum 32-bit value.   */\n#define MAX32(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum 32-bit value.   */\n\n#ifdef FIXED_POINT\n\ntypedef spx_int16_t spx_word16_t;\ntypedef spx_int32_t   spx_word32_t;\ntypedef spx_word32_t spx_mem_t;\ntypedef spx_word16_t spx_coef_t;\ntypedef spx_word16_t spx_lsp_t;\ntypedef spx_word32_t spx_sig_t;\n\n#define Q15ONE 32767\n\n#define LPC_SCALING  8192\n#define SIG_SCALING  16384\n#define LSP_SCALING  8192.\n#define GAMMA_SCALING 32768.\n#define GAIN_SCALING 64\n#define GAIN_SCALING_1 0.015625\n\n#define LPC_SHIFT    13\n#define LSP_SHIFT    13\n#define SIG_SHIFT    14\n#define GAIN_SHIFT   6\n\n#define VERY_SMALL 0\n#define VERY_LARGE32 ((spx_word32_t)2147483647)\n#define VERY_LARGE16 ((spx_word16_t)32767)\n#define Q15_ONE ((spx_word16_t)32767)\n\n\n#ifdef FIXED_DEBUG\n#include \"fixed_debug.h\"\n#else\n\n#include \"fixed_generic.h\"\n\n#ifdef ARM5E_ASM\n#include \"fixed_arm5e.h\"\n#elif defined (ARM4_ASM)\n#include \"fixed_arm4.h\"\n#elif defined (BFIN_ASM)\n#include \"fixed_bfin.h\"\n#endif\n\n#endif\n\n\n#else\n\ntypedef float spx_mem_t;\ntypedef float spx_coef_t;\ntypedef float spx_lsp_t;\ntypedef float spx_sig_t;\ntypedef float spx_word16_t;\ntypedef float spx_word32_t;\n\n#define Q15ONE 1.0f\n#define LPC_SCALING  1.f\n#define SIG_SCALING  1.f\n#define LSP_SCALING  1.f\n#define GAMMA_SCALING 1.f\n#define GAIN_SCALING 1.f\n#define GAIN_SCALING_1 1.f\n\n\n#define VERY_SMALL 1e-15f\n#define VERY_LARGE32 1e15f\n#define VERY_LARGE16 1e15f\n#define Q15_ONE ((spx_word16_t)1.f)\n\n#define QCONST16(x,bits) (x)\n#define QCONST32(x,bits) (x)\n\n#define NEG16(x) (-(x))\n#define NEG32(x) (-(x))\n#define EXTRACT16(x) (x)\n#define EXTEND32(x) (x)\n#define SHR16(a,shift) (a)\n#define SHL16(a,shift) (a)\n#define SHR32(a,shift) (a)\n#define SHL32(a,shift) (a)\n#define PSHR16(a,shift) (a)\n#define PSHR32(a,shift) (a)\n#define VSHR32(a,shift) (a)\n#define SATURATE16(x,a) (x)\n#define SATURATE32(x,a) (x)\n\n#define PSHR(a,shift)       (a)\n#define SHR(a,shift)       (a)\n#define SHL(a,shift)       (a)\n#define SATURATE(x,a) (x)\n\n#define ADD16(a,b) ((a)+(b))\n#define SUB16(a,b) ((a)-(b))\n#define ADD32(a,b) ((a)+(b))\n#define SUB32(a,b) ((a)-(b))\n#define MULT16_16_16(a,b)     ((a)*(b))\n#define MULT16_16(a,b)     ((spx_word32_t)(a)*(spx_word32_t)(b))\n#define MAC16_16(c,a,b)     ((c)+(spx_word32_t)(a)*(spx_word32_t)(b))\n\n#define MULT16_32_Q11(a,b)     ((a)*(b))\n#define MULT16_32_Q13(a,b)     ((a)*(b))\n#define MULT16_32_Q14(a,b)     ((a)*(b))\n#define MULT16_32_Q15(a,b)     ((a)*(b))\n#define MULT16_32_P15(a,b)     ((a)*(b))\n\n#define MAC16_32_Q11(c,a,b)     ((c)+(a)*(b))\n#define MAC16_32_Q15(c,a,b)     ((c)+(a)*(b))\n\n#define MAC16_16_Q11(c,a,b)     ((c)+(a)*(b))\n#define MAC16_16_Q13(c,a,b)     ((c)+(a)*(b))\n#define MAC16_16_P13(c,a,b)     ((c)+(a)*(b))\n#define MULT16_16_Q11_32(a,b)     ((a)*(b))\n#define MULT16_16_Q13(a,b)     ((a)*(b))\n#define MULT16_16_Q14(a,b)     ((a)*(b))\n#define MULT16_16_Q15(a,b)     ((a)*(b))\n#define MULT16_16_P15(a,b)     ((a)*(b))\n#define MULT16_16_P13(a,b)     ((a)*(b))\n#define MULT16_16_P14(a,b)     ((a)*(b))\n\n#define DIV32_16(a,b)     (((spx_word32_t)(a))/(spx_word16_t)(b))\n#define PDIV32_16(a,b)     (((spx_word32_t)(a))/(spx_word16_t)(b))\n#define DIV32(a,b)     (((spx_word32_t)(a))/(spx_word32_t)(b))\n#define PDIV32(a,b)     (((spx_word32_t)(a))/(spx_word32_t)(b))\n\n\n#endif\n\n\n#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)\n\n/* 2 on TI C5x DSP */\n#define BYTES_PER_CHAR 2 \n#define BITS_PER_CHAR 16\n#define LOG2_BITS_PER_CHAR 4\n\n#else \n\n#define BYTES_PER_CHAR 1\n#define BITS_PER_CHAR 8\n#define LOG2_BITS_PER_CHAR 3\n\n#endif\n\n\n\n#ifdef FIXED_DEBUG\nextern long long spx_mips;\n#endif\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/bits.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: speex_bits.c\n\n   Handles bit packing/unpacking\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <speex/speex_bits.h>\n#include \"arch.h\"\n#include \"os_support.h\"\n\n/* Maximum size of the bit-stream (for fixed-size allocation) */\n#ifndef MAX_CHARS_PER_FRAME\n#define MAX_CHARS_PER_FRAME (2000/BYTES_PER_CHAR)\n#endif\n\nEXPORT void speex_bits_init(SpeexBits *bits)\n{\n   bits->chars = (char*)speex_alloc(MAX_CHARS_PER_FRAME);\n   if (!bits->chars)\n      return;\n\n   bits->buf_size = MAX_CHARS_PER_FRAME;\n\n   bits->owner=1;\n\n   speex_bits_reset(bits);\n}\n\nEXPORT void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)\n{\n   bits->chars = (char*)buff;\n   bits->buf_size = buf_size;\n\n   bits->owner=0;\n\n   speex_bits_reset(bits);\n}\n\nEXPORT void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size)\n{\n   bits->chars = (char*)buff;\n   bits->buf_size = buf_size;\n\n   bits->owner=0;\n\n   bits->nbBits=buf_size<<LOG2_BITS_PER_CHAR;\n   bits->charPtr=0;\n   bits->bitPtr=0;\n   bits->overflow=0;\n   \n}\n\nEXPORT void speex_bits_destroy(SpeexBits *bits)\n{\n   if (bits->owner)\n      speex_free(bits->chars);\n   /* Will do something once the allocation is dynamic */\n}\n\nEXPORT void speex_bits_reset(SpeexBits *bits)\n{\n   /* We only need to clear the first byte now */\n   bits->chars[0]=0;\n   bits->nbBits=0;\n   bits->charPtr=0;\n   bits->bitPtr=0;\n   bits->overflow=0;\n}\n\nEXPORT void speex_bits_rewind(SpeexBits *bits)\n{\n   bits->charPtr=0;\n   bits->bitPtr=0;\n   bits->overflow=0;\n}\n\nEXPORT void speex_bits_read_from(SpeexBits *bits, char *chars, int len)\n{\n   int i;\n   int nchars = len / BYTES_PER_CHAR;\n   if (nchars > bits->buf_size)\n   {\n      speex_notify(\"Packet is larger than allocated buffer\");\n      if (bits->owner)\n      {\n         char *tmp = (char*)speex_realloc(bits->chars, nchars);\n         if (tmp)\n         {\n            bits->buf_size=nchars;\n            bits->chars=tmp;\n         } else {\n            nchars=bits->buf_size;\n            speex_warning(\"Could not resize input buffer: truncating input\");\n         }\n      } else {\n         speex_warning(\"Do not own input buffer: truncating oversize input\");\n         nchars=bits->buf_size;\n      }\n   }\n#if (BYTES_PER_CHAR==2)\n/* Swap bytes to proper endian order (could be done externally) */\n#define HTOLS(A) ((((A) >> 8)&0xff)|(((A) & 0xff)<<8))\n#else\n#define HTOLS(A) (A)\n#endif\n   for (i=0;i<nchars;i++)\n      bits->chars[i]=HTOLS(chars[i]);\n\n   bits->nbBits=nchars<<LOG2_BITS_PER_CHAR;\n   bits->charPtr=0;\n   bits->bitPtr=0;\n   bits->overflow=0;\n}\n\nstatic void speex_bits_flush(SpeexBits *bits)\n{\n   int nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);\n   if (bits->charPtr>0)\n      SPEEX_MOVE(bits->chars, &bits->chars[bits->charPtr], nchars-bits->charPtr);\n   bits->nbBits -= bits->charPtr<<LOG2_BITS_PER_CHAR;\n   bits->charPtr=0;\n}\n\nEXPORT void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes)\n{\n   int i,pos;\n   int nchars = nbytes/BYTES_PER_CHAR;\n\n   if (((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR)+nchars > bits->buf_size)\n   {\n      /* Packet is larger than allocated buffer */\n      if (bits->owner)\n      {\n         char *tmp = (char*)speex_realloc(bits->chars, (bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1);\n         if (tmp)\n         {\n            bits->buf_size=(bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1;\n            bits->chars=tmp;\n         } else {\n            nchars=bits->buf_size-(bits->nbBits>>LOG2_BITS_PER_CHAR)-1;\n            speex_warning(\"Could not resize input buffer: truncating oversize input\");\n         }\n      } else {\n         speex_warning(\"Do not own input buffer: truncating oversize input\");\n         nchars=bits->buf_size;\n      }\n   }\n\n   speex_bits_flush(bits);\n   pos=bits->nbBits>>LOG2_BITS_PER_CHAR;\n   for (i=0;i<nchars;i++)\n      bits->chars[pos+i]=HTOLS(chars[i]);\n   bits->nbBits+=nchars<<LOG2_BITS_PER_CHAR;\n}\n\nEXPORT int speex_bits_write(SpeexBits *bits, char *chars, int max_nbytes)\n{\n   int i;\n   int max_nchars = max_nbytes/BYTES_PER_CHAR;\n   int charPtr, bitPtr, nbBits;\n\n   /* Insert terminator, but save the data so we can put it back after */\n   bitPtr=bits->bitPtr;\n   charPtr=bits->charPtr;\n   nbBits=bits->nbBits;\n   speex_bits_insert_terminator(bits);\n   bits->bitPtr=bitPtr;\n   bits->charPtr=charPtr;\n   bits->nbBits=nbBits;\n\n   if (max_nchars > ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR))\n      max_nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);\n\n   for (i=0;i<max_nchars;i++)\n      chars[i]=HTOLS(bits->chars[i]);\n   return max_nchars*BYTES_PER_CHAR;\n}\n\nEXPORT int speex_bits_write_whole_bytes(SpeexBits *bits, char *chars, int max_nbytes)\n{\n   int max_nchars = max_nbytes/BYTES_PER_CHAR;\n   int i;\n   if (max_nchars > ((bits->nbBits)>>LOG2_BITS_PER_CHAR))\n      max_nchars = ((bits->nbBits)>>LOG2_BITS_PER_CHAR);\n   for (i=0;i<max_nchars;i++)\n      chars[i]=HTOLS(bits->chars[i]);\n\n   if (bits->bitPtr>0)\n      bits->chars[0]=bits->chars[max_nchars];\n   else\n      bits->chars[0]=0;\n   bits->charPtr=0;\n   bits->nbBits &= (BITS_PER_CHAR-1);\n   return max_nchars*BYTES_PER_CHAR;\n}\n\nEXPORT void speex_bits_pack(SpeexBits *bits, int data, int nbBits)\n{\n   unsigned int d=data;\n\n   if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size)\n   {\n      speex_notify(\"Buffer too small to pack bits\");\n      if (bits->owner)\n      {\n         int new_nchars = ((bits->buf_size+5)*3)>>1;\n         char *tmp = (char*)speex_realloc(bits->chars, new_nchars);\n         if (tmp)\n         {\n            bits->buf_size=new_nchars;\n            bits->chars=tmp;\n         } else {\n            speex_warning(\"Could not resize input buffer: not packing\");\n            return;\n         }\n      } else {\n         speex_warning(\"Do not own input buffer: not packing\");\n         return;\n      }\n   }\n\n   while(nbBits)\n   {\n      int bit;\n      bit = (d>>(nbBits-1))&1;\n      bits->chars[bits->charPtr] |= bit<<(BITS_PER_CHAR-1-bits->bitPtr);\n      bits->bitPtr++;\n\n      if (bits->bitPtr==BITS_PER_CHAR)\n      {\n         bits->bitPtr=0;\n         bits->charPtr++;\n         bits->chars[bits->charPtr] = 0;\n      }\n      bits->nbBits++;\n      nbBits--;\n   }\n}\n\nEXPORT int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)\n{\n   unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);\n   /* If number is negative */\n   if (d>>(nbBits-1))\n   {\n      d |= (-1)<<nbBits;\n   }\n   return d;\n}\n\nEXPORT unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)\n{\n   unsigned int d=0;\n   if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)\n      bits->overflow=1;\n   if (bits->overflow)\n      return 0;\n   while(nbBits)\n   {\n      d<<=1;\n      d |= (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;\n      bits->bitPtr++;\n      if (bits->bitPtr==BITS_PER_CHAR)\n      {\n         bits->bitPtr=0;\n         bits->charPtr++;\n      }\n      nbBits--;\n   }\n   return d;\n}\n\nEXPORT unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)\n{\n   unsigned int d=0;\n   int bitPtr, charPtr;\n   char *chars;\n\n   if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)\n     bits->overflow=1;\n   if (bits->overflow)\n      return 0;\n\n   bitPtr=bits->bitPtr;\n   charPtr=bits->charPtr;\n   chars = bits->chars;\n   while(nbBits)\n   {\n      d<<=1;\n      d |= (chars[charPtr]>>(BITS_PER_CHAR-1 - bitPtr))&1;\n      bitPtr++;\n      if (bitPtr==BITS_PER_CHAR)\n      {\n         bitPtr=0;\n         charPtr++;\n      }\n      nbBits--;\n   }\n   return d;\n}\n\nEXPORT int speex_bits_peek(SpeexBits *bits)\n{\n   if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+1>bits->nbBits)\n      bits->overflow=1;\n   if (bits->overflow)\n      return 0;\n   return (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;\n}\n\nEXPORT void speex_bits_advance(SpeexBits *bits, int n)\n{\n    if (((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+n>bits->nbBits) || bits->overflow){\n      bits->overflow=1;\n      return;\n    }\n   bits->charPtr += (bits->bitPtr+n) >> LOG2_BITS_PER_CHAR; /* divide by BITS_PER_CHAR */\n   bits->bitPtr = (bits->bitPtr+n) & (BITS_PER_CHAR-1);       /* modulo by BITS_PER_CHAR */\n}\n\nEXPORT int speex_bits_remaining(SpeexBits *bits)\n{\n   if (bits->overflow)\n      return -1;\n   else\n      return bits->nbBits-((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr);\n}\n\nEXPORT int speex_bits_nbytes(SpeexBits *bits)\n{\n   return ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);\n}\n\nEXPORT void speex_bits_insert_terminator(SpeexBits *bits)\n{\n   if (bits->bitPtr)\n      speex_bits_pack(bits, 0, 1);\n   while (bits->bitPtr)\n      speex_bits_pack(bits, 1, 1);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/buffer.c",
    "content": "/* Copyright (C) 2007 Jean-Marc Valin\n      \n   File: buffer.c\n   This is a very simple ring buffer implementation. It is not thread-safe\n   so you need to do your own locking.\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n\n#include \"os_support.h\"\n#include \"arch.h\"\n#include <speex/speex_buffer.h>\n\nstruct SpeexBuffer_ {\n   char *data;\n   int   size;\n   int   read_ptr;\n   int   write_ptr;\n   int   available;\n};\n\nEXPORT SpeexBuffer *speex_buffer_init(int size)\n{\n   SpeexBuffer *st = speex_alloc(sizeof(SpeexBuffer));\n   st->data = speex_alloc(size);\n   st->size = size;\n   st->read_ptr = 0;\n   st->write_ptr = 0;\n   st->available = 0;\n   return st;\n}\n\nEXPORT void speex_buffer_destroy(SpeexBuffer *st)\n{\n   speex_free(st->data);\n   speex_free(st);\n}\n\nEXPORT int speex_buffer_write(SpeexBuffer *st, void *_data, int len)\n{\n   int end;\n   int end1;\n   char *data = _data;\n   if (len > st->size)\n   {\n      data += len-st->size;\n      len = st->size;\n   }\n   end = st->write_ptr + len;\n   end1 = end;\n   if (end1 > st->size)\n      end1 = st->size;\n   SPEEX_COPY(st->data + st->write_ptr, data, end1 - st->write_ptr);\n   if (end > st->size)\n   {\n      end -= st->size;\n      SPEEX_COPY(st->data, data+end1 - st->write_ptr, end);\n   }\n   st->available += len;\n   if (st->available > st->size)\n   {\n      st->available = st->size;\n      st->read_ptr = st->write_ptr;\n   }\n   st->write_ptr += len;\n   if (st->write_ptr > st->size)\n      st->write_ptr -= st->size;\n   return len;\n}\n\nEXPORT int speex_buffer_writezeros(SpeexBuffer *st, int len)\n{\n   /* This is almost the same as for speex_buffer_write() but using \n   SPEEX_MEMSET() instead of SPEEX_COPY(). Update accordingly. */\n   int end;\n   int end1;\n   if (len > st->size)\n   {\n      len = st->size;\n   }\n   end = st->write_ptr + len;\n   end1 = end;\n   if (end1 > st->size)\n      end1 = st->size;\n   SPEEX_MEMSET(st->data + st->write_ptr, 0, end1 - st->write_ptr);\n   if (end > st->size)\n   {\n      end -= st->size;\n      SPEEX_MEMSET(st->data, 0, end);\n   }\n   st->available += len;\n   if (st->available > st->size)\n   {\n      st->available = st->size;\n      st->read_ptr = st->write_ptr;\n   }\n   st->write_ptr += len;\n   if (st->write_ptr > st->size)\n      st->write_ptr -= st->size;\n   return len;\n}\n\nEXPORT int speex_buffer_read(SpeexBuffer *st, void *_data, int len)\n{\n   int end, end1;\n   char *data = _data;\n   if (len > st->available)\n   {\n      SPEEX_MEMSET(data+st->available, 0, st->size-st->available);\n      len = st->available;\n   }\n   end = st->read_ptr + len;\n   end1 = end;\n   if (end1 > st->size)\n      end1 = st->size;\n   SPEEX_COPY(data, st->data + st->read_ptr, end1 - st->read_ptr);\n\n   if (end > st->size)\n   {\n      end -= st->size;\n      SPEEX_COPY(data+end1 - st->read_ptr, st->data, end);\n   }\n   st->available -= len;\n   st->read_ptr += len;\n   if (st->read_ptr > st->size)\n      st->read_ptr -= st->size;\n   return len;\n}\n\nEXPORT int speex_buffer_get_available(SpeexBuffer *st)\n{\n   return st->available;\n}\n\nEXPORT int speex_buffer_resize(SpeexBuffer *st, int len)\n{\n   int old_len = st->size;\n   if (len > old_len)\n   {\n      st->data = speex_realloc(st->data, len);\n      /* FIXME: move data/pointers properly for growing the buffer */\n   } else {\n      /* FIXME: move data/pointers properly for shrinking the buffer */\n      st->data = speex_realloc(st->data, len);\n   }\n   return len;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/cb_search.c",
    "content": "/* Copyright (C) 2002-2006 Jean-Marc Valin \n   File: cb_search.c\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"cb_search.h\"\n#include \"filters.h\"\n#include \"stack_alloc.h\"\n#include \"vq.h\"\n#include \"arch.h\"\n#include \"math_approx.h\"\n#include \"os_support.h\"\n\n#ifdef _USE_SSE\n#include \"cb_search_sse.h\"\n#elif defined(ARM4_ASM) || defined(ARM5E_ASM)\n#include \"cb_search_arm4.h\"\n#elif defined(BFIN_ASM)\n#include \"cb_search_bfin.h\"\n#endif\n\n#ifndef OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK\nstatic void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)\n{\n   int i, j, k;\n   VARDECL(spx_word16_t *shape);\n   ALLOC(shape, subvect_size, spx_word16_t);\n   for (i=0;i<shape_cb_size;i++)\n   {\n      spx_word16_t *res;\n      \n      res = resp+i*subvect_size;\n      for (k=0;k<subvect_size;k++)\n         shape[k] = (spx_word16_t)shape_cb[i*subvect_size+k];\n      E[i]=0;\n\n      /* Compute codeword response using convolution with impulse response */\n      for(j=0;j<subvect_size;j++)\n      {\n         spx_word32_t resj=0;\n         spx_word16_t res16;\n         for (k=0;k<=j;k++)\n            resj = MAC16_16(resj,shape[k],r[j-k]);\n#ifdef FIXED_POINT\n         res16 = EXTRACT16(SHR32(resj, 13));\n#else\n         res16 = 0.03125f*resj;\n#endif\n         /* Compute codeword energy */\n         E[i]=MAC16_16(E[i],res16,res16);\n         res[j] = res16;\n         /*printf (\"%d\\n\", (int)res[j]);*/\n      }\n   }\n\n}\n#endif\n\n#ifndef OVERRIDE_TARGET_UPDATE\nstatic inline void target_update(spx_word16_t *t, spx_word16_t g, spx_word16_t *r, int len)\n{\n   int n;\n   for (n=0;n<len;n++)\n      t[n] = SUB16(t[n],PSHR32(MULT16_16(g,r[n]),13));\n}\n#endif\n\n\n\nstatic void split_cb_search_shape_sign_N1(\nspx_word16_t target[],\t\t\t/* target vector */\nspx_coef_t ak[],\t\t\t/* LPCs for this subframe */\nspx_coef_t awk1[],\t\t\t/* Weighted LPCs for this subframe */\nspx_coef_t awk2[],\t\t\t/* Weighted LPCs for this subframe */\nconst void *par,                      /* Codebook/search parameters*/\nint   p,                        /* number of LPC coeffs */\nint   nsf,                      /* number of samples in subframe */\nspx_sig_t *exc,\nspx_word16_t *r,\nSpeexBits *bits,\nchar *stack,\nint   update_target\n)\n{\n   int i,j,m,q;\n   VARDECL(spx_word16_t *resp);\n#ifdef _USE_SSE\n   VARDECL(__m128 *resp2);\n   VARDECL(__m128 *E);\n#else\n   spx_word16_t *resp2;\n   VARDECL(spx_word32_t *E);\n#endif\n   VARDECL(spx_word16_t *t);\n   VARDECL(spx_sig_t *e);\n   const signed char *shape_cb;\n   int shape_cb_size, subvect_size, nb_subvect;\n   const split_cb_params *params;\n   int best_index;\n   spx_word32_t best_dist;\n   int have_sign;\n   \n   params = (const split_cb_params *) par;\n   subvect_size = params->subvect_size;\n   nb_subvect = params->nb_subvect;\n   shape_cb_size = 1<<params->shape_bits;\n   shape_cb = params->shape_cb;\n   have_sign = params->have_sign;\n   ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t);\n#ifdef _USE_SSE\n   ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128);\n   ALLOC(E, shape_cb_size>>2, __m128);\n#else\n   resp2 = resp;\n   ALLOC(E, shape_cb_size, spx_word32_t);\n#endif\n   ALLOC(t, nsf, spx_word16_t);\n   ALLOC(e, nsf, spx_sig_t);\n   \n   /* FIXME: Do we still need to copy the target? */\n   SPEEX_COPY(t, target, nsf);\n\n   compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);\n\n   for (i=0;i<nb_subvect;i++)\n   {\n      spx_word16_t *x=t+subvect_size*i;\n      /*Find new n-best based on previous n-best j*/\n      if (have_sign)\n         vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);\n      else\n         vq_nbest(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);\n      \n      speex_bits_pack(bits,best_index,params->shape_bits+have_sign);\n      \n      {\n         int rind;\n         spx_word16_t *res;\n         spx_word16_t sign=1;\n         rind = best_index;\n         if (rind>=shape_cb_size)\n         {\n            sign=-1;\n            rind-=shape_cb_size;\n         }\n         res = resp+rind*subvect_size;\n         if (sign>0)\n            for (m=0;m<subvect_size;m++)\n               t[subvect_size*i+m] = SUB16(t[subvect_size*i+m], res[m]);\n         else\n            for (m=0;m<subvect_size;m++)\n               t[subvect_size*i+m] = ADD16(t[subvect_size*i+m], res[m]);\n\n#ifdef FIXED_POINT\n         if (sign==1)\n         {\n            for (j=0;j<subvect_size;j++)\n               e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);\n         } else {\n            for (j=0;j<subvect_size;j++)\n               e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5));\n         }\n#else\n         for (j=0;j<subvect_size;j++)\n            e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];\n#endif\n      \n      }\n            \n      for (m=0;m<subvect_size;m++)\n      {\n         spx_word16_t g;\n         int rind;\n         spx_word16_t sign=1;\n         rind = best_index;\n         if (rind>=shape_cb_size)\n         {\n            sign=-1;\n            rind-=shape_cb_size;\n         }\n         \n         q=subvect_size-m;\n#ifdef FIXED_POINT\n         g=sign*shape_cb[rind*subvect_size+m];\n#else\n         g=sign*0.03125*shape_cb[rind*subvect_size+m];\n#endif\n         target_update(t+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1));\n      }\n   }\n\n   /* Update excitation */\n   /* FIXME: We could update the excitation directly above */\n   for (j=0;j<nsf;j++)\n      exc[j]=ADD32(exc[j],e[j]);\n   \n   /* Update target: only update target if necessary */\n   if (update_target)\n   {\n      VARDECL(spx_word16_t *r2);\n      ALLOC(r2, nsf, spx_word16_t);\n      for (j=0;j<nsf;j++)\n         r2[j] = EXTRACT16(PSHR32(e[j] ,6));\n      syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack);\n      for (j=0;j<nsf;j++)\n         target[j]=SUB16(target[j],PSHR16(r2[j],2));\n   }\n}\n\n\n\nvoid split_cb_search_shape_sign(\nspx_word16_t target[],\t\t\t/* target vector */\nspx_coef_t ak[],\t\t\t/* LPCs for this subframe */\nspx_coef_t awk1[],\t\t\t/* Weighted LPCs for this subframe */\nspx_coef_t awk2[],\t\t\t/* Weighted LPCs for this subframe */\nconst void *par,                      /* Codebook/search parameters*/\nint   p,                        /* number of LPC coeffs */\nint   nsf,                      /* number of samples in subframe */\nspx_sig_t *exc,\nspx_word16_t *r,\nSpeexBits *bits,\nchar *stack,\nint   complexity,\nint   update_target\n)\n{\n   int i,j,k,m,n,q;\n   VARDECL(spx_word16_t *resp);\n#ifdef _USE_SSE\n   VARDECL(__m128 *resp2);\n   VARDECL(__m128 *E);\n#else\n   spx_word16_t *resp2;\n   VARDECL(spx_word32_t *E);\n#endif\n   VARDECL(spx_word16_t *t);\n   VARDECL(spx_sig_t *e);\n   VARDECL(spx_word16_t *tmp);\n   VARDECL(spx_word32_t *ndist);\n   VARDECL(spx_word32_t *odist);\n   VARDECL(int *itmp);\n   VARDECL(spx_word16_t **ot2);\n   VARDECL(spx_word16_t **nt2);\n   spx_word16_t **ot, **nt;\n   VARDECL(int **nind);\n   VARDECL(int **oind);\n   VARDECL(int *ind);\n   const signed char *shape_cb;\n   int shape_cb_size, subvect_size, nb_subvect;\n   const split_cb_params *params;\n   int N=2;\n   VARDECL(int *best_index);\n   VARDECL(spx_word32_t *best_dist);\n   VARDECL(int *best_nind);\n   VARDECL(int *best_ntarget);\n   int have_sign;\n   N=complexity;\n   if (N>10)\n      N=10;\n   /* Complexity isn't as important for the codebooks as it is for the pitch */\n   N=(2*N)/3;\n   if (N<1)\n      N=1;\n   if (N==1)\n   {\n      split_cb_search_shape_sign_N1(target,ak,awk1,awk2,par,p,nsf,exc,r,bits,stack,update_target);\n      return;\n   }\n   ALLOC(ot2, N, spx_word16_t*);\n   ALLOC(nt2, N, spx_word16_t*);\n   ALLOC(oind, N, int*);\n   ALLOC(nind, N, int*);\n\n   params = (const split_cb_params *) par;\n   subvect_size = params->subvect_size;\n   nb_subvect = params->nb_subvect;\n   shape_cb_size = 1<<params->shape_bits;\n   shape_cb = params->shape_cb;\n   have_sign = params->have_sign;\n   ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t);\n#ifdef _USE_SSE\n   ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128);\n   ALLOC(E, shape_cb_size>>2, __m128);\n#else\n   resp2 = resp;\n   ALLOC(E, shape_cb_size, spx_word32_t);\n#endif\n   ALLOC(t, nsf, spx_word16_t);\n   ALLOC(e, nsf, spx_sig_t);\n   ALLOC(ind, nb_subvect, int);\n\n   ALLOC(tmp, 2*N*nsf, spx_word16_t);\n   for (i=0;i<N;i++)\n   {\n      ot2[i]=tmp+2*i*nsf;\n      nt2[i]=tmp+(2*i+1)*nsf;\n   }\n   ot=ot2;\n   nt=nt2;\n   ALLOC(best_index, N, int);\n   ALLOC(best_dist, N, spx_word32_t);\n   ALLOC(best_nind, N, int);\n   ALLOC(best_ntarget, N, int);\n   ALLOC(ndist, N, spx_word32_t);\n   ALLOC(odist, N, spx_word32_t);\n   \n   ALLOC(itmp, 2*N*nb_subvect, int);\n   for (i=0;i<N;i++)\n   {\n      nind[i]=itmp+2*i*nb_subvect;\n      oind[i]=itmp+(2*i+1)*nb_subvect;\n   }\n   \n   SPEEX_COPY(t, target, nsf);\n\n   for (j=0;j<N;j++)\n      SPEEX_COPY(&ot[j][0], t, nsf);\n\n   /* Pre-compute codewords response and energy */\n   compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);\n\n   for (j=0;j<N;j++)\n      odist[j]=0;\n   \n   /*For all subvectors*/\n   for (i=0;i<nb_subvect;i++)\n   {\n      /*\"erase\" nbest list*/\n      for (j=0;j<N;j++)\n         ndist[j]=VERY_LARGE32;\n      /* This is not strictly necessary, but it provides an additonal safety \n         to prevent crashes in case something goes wrong in the previous\n         steps (e.g. NaNs) */\n      for (j=0;j<N;j++)\n         best_nind[j] = best_ntarget[j] = 0;\n      /*For all n-bests of previous subvector*/\n      for (j=0;j<N;j++)\n      {\n         spx_word16_t *x=ot[j]+subvect_size*i;\n         spx_word32_t tener = 0;\n         for (m=0;m<subvect_size;m++)\n            tener = MAC16_16(tener, x[m],x[m]);\n#ifdef FIXED_POINT\n         tener = SHR32(tener,1);\n#else\n         tener *= .5;\n#endif\n         /*Find new n-best based on previous n-best j*/\n         if (have_sign)\n            vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);\n         else\n            vq_nbest(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);\n\n         /*For all new n-bests*/\n         for (k=0;k<N;k++)\n         {\n            /* Compute total distance (including previous sub-vectors */\n            spx_word32_t err = ADD32(ADD32(odist[j],best_dist[k]),tener);\n            \n            /*update n-best list*/\n            if (err<ndist[N-1])\n            {\n               for (m=0;m<N;m++)\n               {\n                  if (err < ndist[m])\n                  {\n                     for (n=N-1;n>m;n--)\n                     {\n                        ndist[n] = ndist[n-1];\n                        best_nind[n] = best_nind[n-1];\n                        best_ntarget[n] = best_ntarget[n-1];\n                     }\n                     /* n is equal to m here, so they're interchangeable */\n                     ndist[m] = err;\n                     best_nind[n] = best_index[k];\n                     best_ntarget[n] = j;\n                     break;\n                  }\n               }\n            }\n         }\n         if (i==0)\n            break;\n      }\n      for (j=0;j<N;j++)\n      {\n         /*previous target (we don't care what happened before*/\n         for (m=(i+1)*subvect_size;m<nsf;m++)\n            nt[j][m]=ot[best_ntarget[j]][m];\n         \n         /* New code: update the rest of the target only if it's worth it */\n         for (m=0;m<subvect_size;m++)\n         {\n            spx_word16_t g;\n            int rind;\n            spx_word16_t sign=1;\n            rind = best_nind[j];\n            if (rind>=shape_cb_size)\n            {\n               sign=-1;\n               rind-=shape_cb_size;\n            }\n\n            q=subvect_size-m;\n#ifdef FIXED_POINT\n            g=sign*shape_cb[rind*subvect_size+m];\n#else\n            g=sign*0.03125*shape_cb[rind*subvect_size+m];\n#endif\n            target_update(nt[j]+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1));\n         }\n\n         for (q=0;q<nb_subvect;q++)\n            nind[j][q]=oind[best_ntarget[j]][q];\n         nind[j][i]=best_nind[j];\n      }\n\n      /*update old-new data*/\n      /* just swap pointers instead of a long copy */\n      {\n         spx_word16_t **tmp2;\n         tmp2=ot;\n         ot=nt;\n         nt=tmp2;\n      }\n      for (j=0;j<N;j++)\n         for (m=0;m<nb_subvect;m++)\n            oind[j][m]=nind[j][m];\n      for (j=0;j<N;j++)\n         odist[j]=ndist[j];\n   }\n\n   /*save indices*/\n   for (i=0;i<nb_subvect;i++)\n   {\n      ind[i]=nind[0][i];\n      speex_bits_pack(bits,ind[i],params->shape_bits+have_sign);\n   }\n   \n   /* Put everything back together */\n   for (i=0;i<nb_subvect;i++)\n   {\n      int rind;\n      spx_word16_t sign=1;\n      rind = ind[i];\n      if (rind>=shape_cb_size)\n      {\n         sign=-1;\n         rind-=shape_cb_size;\n      }\n#ifdef FIXED_POINT\n      if (sign==1)\n      {\n         for (j=0;j<subvect_size;j++)\n            e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);\n      } else {\n         for (j=0;j<subvect_size;j++)\n            e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5));\n      }\n#else\n      for (j=0;j<subvect_size;j++)\n         e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];\n#endif\n   }   \n   /* Update excitation */\n   for (j=0;j<nsf;j++)\n      exc[j]=ADD32(exc[j],e[j]);\n   \n   /* Update target: only update target if necessary */\n   if (update_target)\n   {\n      VARDECL(spx_word16_t *r2);\n      ALLOC(r2, nsf, spx_word16_t);\n      for (j=0;j<nsf;j++)\n         r2[j] = EXTRACT16(PSHR32(e[j] ,6));\n      syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack);\n      for (j=0;j<nsf;j++)\n         target[j]=SUB16(target[j],PSHR16(r2[j],2));\n   }\n}\n\n\nvoid split_cb_shape_sign_unquant(\nspx_sig_t *exc,\nconst void *par,                      /* non-overlapping codebook */\nint   nsf,                      /* number of samples in subframe */\nSpeexBits *bits,\nchar *stack,\nspx_int32_t *seed\n)\n{\n   int i,j;\n   VARDECL(int *ind);\n   VARDECL(int *signs);\n   const signed char *shape_cb;\n   int shape_cb_size, subvect_size, nb_subvect;\n   const split_cb_params *params;\n   int have_sign;\n\n   params = (const split_cb_params *) par;\n   subvect_size = params->subvect_size;\n   nb_subvect = params->nb_subvect;\n   shape_cb_size = 1<<params->shape_bits;\n   shape_cb = params->shape_cb;\n   have_sign = params->have_sign;\n\n   ALLOC(ind, nb_subvect, int);\n   ALLOC(signs, nb_subvect, int);\n\n   /* Decode codewords and gains */\n   for (i=0;i<nb_subvect;i++)\n   {\n      if (have_sign)\n         signs[i] = speex_bits_unpack_unsigned(bits, 1);\n      else\n         signs[i] = 0;\n      ind[i] = speex_bits_unpack_unsigned(bits, params->shape_bits);\n   }\n   /* Compute decoded excitation */\n   for (i=0;i<nb_subvect;i++)\n   {\n      spx_word16_t s=1;\n      if (signs[i])\n         s=-1;\n#ifdef FIXED_POINT\n      if (s==1)\n      {\n         for (j=0;j<subvect_size;j++)\n            exc[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5);\n      } else {\n         for (j=0;j<subvect_size;j++)\n            exc[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5));\n      }\n#else\n      for (j=0;j<subvect_size;j++)\n         exc[subvect_size*i+j]+=s*0.03125*shape_cb[ind[i]*subvect_size+j];      \n#endif\n   }\n}\n\nvoid noise_codebook_quant(\nspx_word16_t target[],\t\t\t/* target vector */\nspx_coef_t ak[],\t\t\t/* LPCs for this subframe */\nspx_coef_t awk1[],\t\t\t/* Weighted LPCs for this subframe */\nspx_coef_t awk2[],\t\t\t/* Weighted LPCs for this subframe */\nconst void *par,                      /* Codebook/search parameters*/\nint   p,                        /* number of LPC coeffs */\nint   nsf,                      /* number of samples in subframe */\nspx_sig_t *exc,\nspx_word16_t *r,\nSpeexBits *bits,\nchar *stack,\nint   complexity,\nint   update_target\n)\n{\n   int i;\n   VARDECL(spx_word16_t *tmp);\n   ALLOC(tmp, nsf, spx_word16_t);\n   residue_percep_zero16(target, ak, awk1, awk2, tmp, nsf, p, stack);\n\n   for (i=0;i<nsf;i++)\n      exc[i]+=SHL32(EXTEND32(tmp[i]),8);\n   SPEEX_MEMSET(target, 0, nsf);\n}\n\n\nvoid noise_codebook_unquant(\nspx_sig_t *exc,\nconst void *par,                      /* non-overlapping codebook */\nint   nsf,                      /* number of samples in subframe */\nSpeexBits *bits,\nchar *stack,\nspx_int32_t *seed\n)\n{\n   int i;\n   /* FIXME: This is bad, but I don't think the function ever gets called anyway */\n   for (i=0;i<nsf;i++)\n      exc[i]=SHL32(EXTEND32(speex_rand(1, seed)),SIG_SHIFT);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/cb_search.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin & David Rowe */\n/**\n   @file cb_search.h\n   @brief Overlapped codebook search\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef CB_SEARCH_H\n#define CB_SEARCH_H\n\n#include <speex/speex_bits.h>\n#include \"arch.h\"\n\n/** Split codebook parameters. */\ntypedef struct split_cb_params {\n   int     subvect_size;\n   int     nb_subvect;\n   const signed char  *shape_cb;\n   int     shape_bits;\n   int     have_sign;\n} split_cb_params;\n\n\nvoid split_cb_search_shape_sign(\nspx_word16_t target[],             /* target vector */\nspx_coef_t ak[],                /* LPCs for this subframe */\nspx_coef_t awk1[],              /* Weighted LPCs for this subframe */\nspx_coef_t awk2[],              /* Weighted LPCs for this subframe */\nconst void *par,                /* Codebook/search parameters */\nint   p,                        /* number of LPC coeffs */\nint   nsf,                      /* number of samples in subframe */\nspx_sig_t *exc,\nspx_word16_t *r,\nSpeexBits *bits,\nchar *stack,\nint   complexity,\nint   update_target\n);\n\nvoid split_cb_shape_sign_unquant(\nspx_sig_t *exc,\nconst void *par,                /* non-overlapping codebook */\nint   nsf,                      /* number of samples in subframe */\nSpeexBits *bits,\nchar *stack,\nspx_int32_t *seed\n);\n\n\nvoid noise_codebook_quant(\nspx_word16_t target[],             /* target vector */\nspx_coef_t ak[],                /* LPCs for this subframe */\nspx_coef_t awk1[],              /* Weighted LPCs for this subframe */\nspx_coef_t awk2[],              /* Weighted LPCs for this subframe */\nconst void *par,                /* Codebook/search parameters */\nint   p,                        /* number of LPC coeffs */\nint   nsf,                      /* number of samples in subframe */\nspx_sig_t *exc,\nspx_word16_t *r,\nSpeexBits *bits,\nchar *stack,\nint   complexity,\nint   update_target\n);\n\n\nvoid noise_codebook_unquant(\nspx_sig_t *exc,\nconst void *par,                /* non-overlapping codebook */\nint   nsf,                      /* number of samples in subframe */\nSpeexBits *bits,\nchar *stack,\nspx_int32_t *seed\n);\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/cb_search_arm4.h",
    "content": "/* Copyright (C) 2004 Jean-Marc Valin */\n/**\n   @file cb_search_arm4.h\n   @brief Fixed codebook functions (ARM4 version)\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/* This optimization is temporaly disabled until it is fixed to account for the fact \n   that \"r\" is now a 16-bit array */\n#if 0\n#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK\nstatic void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)\n{\n   int i, j, k;\n  //const signed char *shape;\n   for (i=0;i<shape_cb_size;i+=4)\n   {\n\n      //shape = shape_cb;\n      E[0]=0;\n      E[1]=0;\n      E[2]=0;\n      E[3]=0;\n\n      /* Compute codeword response using convolution with impulse response */\n      for(j=0;j<subvect_size;j++)\n      {\n#if 1\n          spx_word16_t *res;\n          res = resp+j;\n          spx_word32_t resj0,resj1,resj2,resj3;\n          spx_word32_t dead1, dead2, dead3, dead4, dead5, dead6, dead7, dead8;\n          __asm__ __volatile__ (\n                \"mov %0, #0 \\n\\t\"\n                \"mov %1, #0 \\n\\t\"\n                \"mov %2, #0 \\n\\t\"\n                \"mov %3, #0 \\n\\t\"\n                \".weighted%=: \\n\\t\"\n                \"ldrsb %8, [%6] \\n\\t\"\n                \"ldr %10, [%5], #-4 \\n\\t\"\n                \"mov %9, %6 \\n\\t\"\n                \"ldrsb %11, [%9, %7]! \\n\\t\"\n                \"mla %0, %10, %8, %0 \\n\\t\"\n                \"ldrsb %8, [%9, %7]! \\n\\t\"\n                \"mla %1, %10, %11, %1 \\n\\t\"\n                \"ldrsb %11, [%9, %7]! \\n\\t\"\n                \"mla %2, %10, %8, %2 \\n\\t\"\n                \"subs %4, %4, #1 \\n\\t\"\n                \"mla %3, %10, %11, %3 \\n\\t\"\n                \"add %6, %6, #1 \\n\\t\"\n                \"bne .weighted%= \\n\\t\"\n            : \"=r\" (resj0), \"=r\" (resj1), \"=r\" (resj2), \"=r\" (resj3),\n          \"=r\" (dead1), \"=r\" (dead2), \"=r\" (dead3), \"=r\" (dead4),\n          \"=r\" (dead5), \"=r\" (dead6), \"=r\" (dead7), \"=r\" (dead8)\n            : \"4\" (j+1), \"5\" (r+j), \"6\" (shape_cb), \"7\" (subvect_size)\n            : \"cc\", \"memory\");\n#else\n          spx_word16_t *res;\n          res = resp+j;\n          spx_word32_t resj0=0;\n          spx_word32_t resj1=0;\n          spx_word32_t resj2=0;\n          spx_word32_t resj3=0;\n          for (k=0;k<=j;k++)\n          {\n             const signed char *shape=shape_cb+k;\n             resj0 = MAC16_16(resj0,*shape,r[j-k]);\n             shape += subvect_size;\n             resj1 = MAC16_16(resj1,*shape,r[j-k]);\n             shape += subvect_size;\n             resj2 = MAC16_16(resj2,*shape,r[j-k]);\n             shape += subvect_size;\n             resj3 = MAC16_16(resj3,*shape,r[j-k]);\n             shape += subvect_size;\n          }\n#endif\n\n#ifdef FIXED_POINT\n          resj0 = SHR(resj0, 11);\n          resj1 = SHR(resj1, 11);\n          resj2 = SHR(resj2, 11);\n          resj3 = SHR(resj3, 11);\n#else\n          resj0 *= 0.03125;\n          resj1 *= 0.03125;\n          resj2 *= 0.03125;\n          resj3 *= 0.03125;\n#endif\n\n          /* Compute codeword energy */\n          E[0]=ADD32(E[0],MULT16_16(resj0,resj0));\n          E[1]=ADD32(E[1],MULT16_16(resj1,resj1));\n          E[2]=ADD32(E[2],MULT16_16(resj2,resj2));\n          E[3]=ADD32(E[3],MULT16_16(resj3,resj3));\n          *res = resj0;\n          res += subvect_size;\n          *res = resj1;\n          res += subvect_size;\n          *res = resj2;\n          res += subvect_size;\n          *res = resj3;\n          res += subvect_size;\n      }\n      resp += subvect_size<<2;\n      shape_cb += subvect_size<<2;\n      E+=4;\n   }\n\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/cb_search_bfin.h",
    "content": "/* Copyright (C) 2005 Analog Devices */\n/**\n   @author Jean-Marc Valin \n   @file cb_search_bfin.h\n   @brief Fixed codebook functions (Blackfin version)\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK \nvoid compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)\n{\n   int i;\n   for (i=0;i<shape_cb_size;i++)\n   {\n      __asm__ __volatile__ (\n         \"P0 = %0;\\n\\t\"\n         \"LC0 = P0;\\n\\t\"\n         \"P1 = %1;\\n\\t\"\n         \"P2 = %2;\\n\\t\"\n         \"P3 = %3;\\n\\t\"\n         \"P0 = 1;\\n\\t\"\n         \"L0 = 0;\\n\\t\"\n         \"L1 = 0;\\n\\t\"\n         \"R2 = 0;\\n\\t\"\n         \"A1 = 0;\\n\\t\"\n         \"LOOP outter%= LC0;\\n\\t\"\n         \"LOOP_BEGIN outter%=;\\n\\t\"\n            \"A0 = 0;\\n\\t\"\n            \"P4 = P1;\\n\\t\"\n            \"I1 = P2;\\n\\t\"\n            \"R0 = B[P4++] (X) || R1.L = W[I1--];\\n\\t\"\n            \"LOOP inner%= LC1 = P0;\\n\\t\"\n            \"LOOP_BEGIN inner%=;\\n\\t\"\n               \"A0 += R0.L*R1.L (IS) || R0 = B[P4++] (X) || R1.L = W[I1--];\\n\\t\"\n            \"LOOP_END inner%=;\\n\\t\"\n            \"R0 = A0;\\n\\t\"\n            \"R0 >>>= 13;\\n\\t\"\n            \"A1 += R0.L*R0.L (IS);\\n\\t\"\n            \"W[P3++] = R0;\\n\\t\"\n            \"P0 += 1;\\n\\t\"\n            \"P2 += 2;\\n\\t\"\n         \"LOOP_END outter%=;\\n\\t\"\n         \"P4 = %4;\\n\\t\"\n         \"R1 = A1;\\n\\t\"\n         \"[P4] = R1;\\n\\t\"\n         :\n      : \"m\" (subvect_size), \"m\" (shape_cb), \"m\" (r), \"m\" (resp), \"m\" (E)\n      : \"A0\", \"P0\", \"P1\", \"P2\", \"P3\", \"P4\", \"R0\", \"R1\", \"R2\", \"I0\", \"I1\", \"L0\", \n        \"L1\", \"A0\", \"A1\", \"memory\"\n#if !(__GNUC__ == 3)\n         , \"LC0\", \"LC1\" /* gcc 3.4 doesn't know about LC registers */\n#endif\n      );\n      shape_cb += subvect_size;\n      resp += subvect_size;\n      E++;\n   }\n}\n\n#define OVERRIDE_TARGET_UPDATE\nstatic inline void target_update(spx_word16_t *t, spx_word16_t g, spx_word16_t *r, int len)\n{\n   if (!len)\n      return;\n   __asm__ __volatile__\n         (\n         \"I0 = %0;\\n\\t\"\n         \"I1 = %1;\\n\\t\"\n         \"L0 = 0;\\n\\t\"\n         \"L1 = 0;\\n\\t\"\n         \"R2 = 4096;\\n\\t\"\n         \"LOOP tupdate%= LC0 = %3;\\n\\t\"\n         \"LOOP_BEGIN tupdate%=;\\n\\t\"\n            \"R0.L = W[I0] || R1.L = W[I1++];\\n\\t\"\n            \"R1 = (A1 = R1.L*%2.L) (IS);\\n\\t\"\n            \"R1 = R1 + R2;\\n\\t\"\n            \"R1 >>>= 13;\\n\\t\"\n            \"R0.L = R0.L - R1.L;\\n\\t\"\n            \"W[I0++] = R0.L;\\n\\t\"\n         \"LOOP_END tupdate%=;\\n\\t\"\n   :\n   : \"a\" (t), \"a\" (r), \"d\" (g), \"a\" (len)\n   : \"R0\", \"R1\", \"R2\", \"A1\", \"I0\", \"I1\", \"L0\", \"L1\"\n         );\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/cb_search_sse.h",
    "content": "/* Copyright (C) 2004 Jean-Marc Valin */\n/**\n   @file cb_search_sse.h\n   @brief Fixed codebook functions (SSE version)\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#include <xmmintrin.h>\n\nstatic inline void _spx_mm_getr_ps (__m128 U, float *__Z, float *__Y, float *__X, float *__W)\n{\n  union {\n    float __a[4];\n    __m128 __v;\n  } __u;\n  \n  __u.__v = U;\n\n  *__Z = __u.__a[0];\n  *__Y = __u.__a[1];\n  *__X = __u.__a[2];\n  *__W = __u.__a[3];\n\n}\n\n#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK\nstatic void compute_weighted_codebook(const signed char *shape_cb, const spx_sig_t *_r, float *resp, __m128 *resp2, __m128 *E, int shape_cb_size, int subvect_size, char *stack)\n{\n   int i, j, k;\n   __m128 resj, EE;\n   VARDECL(__m128 *r);\n   VARDECL(__m128 *shape);\n   ALLOC(r, subvect_size, __m128);\n   ALLOC(shape, subvect_size, __m128);\n   for(j=0;j<subvect_size;j++)\n      r[j] = _mm_load_ps1(_r+j);\n   for (i=0;i<shape_cb_size;i+=4)\n   {\n      float *_res = resp+i*subvect_size;\n      const signed char *_shape = shape_cb+i*subvect_size;\n      EE = _mm_setzero_ps();\n      for(j=0;j<subvect_size;j++)\n      {\n         shape[j] = _mm_setr_ps(0.03125*_shape[j], 0.03125*_shape[subvect_size+j], 0.03125*_shape[2*subvect_size+j], 0.03125*_shape[3*subvect_size+j]);\n      }\n      for(j=0;j<subvect_size;j++)\n      {\n         resj = _mm_setzero_ps();\n         for (k=0;k<=j;k++)\n            resj = _mm_add_ps(resj, _mm_mul_ps(shape[k],r[j-k]));\n         _spx_mm_getr_ps(resj, _res+j, _res+subvect_size+j, _res+2*subvect_size+j, _res+3*subvect_size+j);\n         *resp2++ = resj;\n         EE = _mm_add_ps(EE, _mm_mul_ps(resj, resj));\n      }\n      E[i>>2] = EE;\n   }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/echo_diagnostic.m",
    "content": "% Attempts to diagnose AEC problems from recorded samples\n%\n% out = echo_diagnostic(rec_file, play_file, out_file, tail_length)\n%\n% Computes the full matrix inversion to cancel echo from the \n% recording 'rec_file' using the far end signal 'play_file' using \n% a filter length of 'tail_length'. The output is saved to 'out_file'.\nfunction out = echo_diagnostic(rec_file, play_file, out_file, tail_length)\n\nF=fopen(rec_file,'rb');\nrec=fread(F,Inf,'short');\nfclose (F);\nF=fopen(play_file,'rb');\nplay=fread(F,Inf,'short');\nfclose (F);\n\nrec = [rec; zeros(1024,1)];\nplay = [play; zeros(1024,1)];\n\nN = length(rec);\ncorr = real(ifft(fft(rec).*conj(fft(play))));\nacorr = real(ifft(fft(play).*conj(fft(play))));\n\n[a,b] = max(corr);\n\nif b > N/2\n      b = b-N;\nend\nprintf (\"Far end to near end delay is %d samples\\n\", b);\nif (b > .3*tail_length)\n      printf ('This is too much delay, try delaying the far-end signal a bit\\n');\nelse if (b < 0)\n      printf ('You have a negative delay, the echo canceller has no chance to cancel anything!\\n');\n   else\n      printf ('Delay looks OK.\\n');\n      end\n   end\nend\nN2 = round(N/2);\ncorr1 = real(ifft(fft(rec(1:N2)).*conj(fft(play(1:N2)))));\ncorr2 = real(ifft(fft(rec(N2+1:end)).*conj(fft(play(N2+1:end)))));\n\n[a,b1] = max(corr1);\nif b1 > N2/2\n      b1 = b1-N2;\nend\n[a,b2] = max(corr2);\nif b2 > N2/2\n      b2 = b2-N2;\nend\ndrift = (b1-b2)/N2;\nprintf ('Drift estimate is %f%% (%d samples)\\n', 100*drift, b1-b2);\nif abs(b1-b2) < 10\n   printf ('A drift of a few (+-10) samples is normal.\\n');\nelse\n   if abs(b1-b2) < 30\n      printf ('There may be (not sure) excessive clock drift. Is the capture and playback done on the same soundcard?\\n');\n   else\n      printf ('Your clock is drifting! No way the AEC will be able to do anything with that. Most likely, you''re doing capture and playback from two different cards.\\n');\n      end\n   end\nend\nacorr(1) = .001+1.00001*acorr(1);\nAtA = toeplitz(acorr(1:tail_length));\nbb = corr(1:tail_length);\nh = AtA\\bb;\n\nout = (rec - filter(h, 1, play));\n\nF=fopen(out_file,'w');\nfwrite(F,out,'short');\nfclose (F);\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/exc_10_16_table.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: exc_10_16_table.c\n   Codebook for excitation in narrowband CELP mode (3200 bps)\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\nconst signed char exc_10_16_table[160] = {\n22,39,14,44,11,35,-2,23,-4,6,\n46,-28,13,-27,-23,12,4,20,-5,9,\n37,-18,-23,23,0,9,-6,-20,4,-1,\n-17,-5,-4,17,0,1,9,-2,1,2,\n2,-12,8,-25,39,15,9,16,-55,-11,\n9,11,5,10,-2,-60,8,13,-6,11,\n-16,27,-47,-12,11,1,16,-7,9,-3,\n-29,9,-14,25,-19,34,36,12,40,-10,\n-3,-24,-14,-37,-21,-35,-2,-36,3,-6,\n67,28,6,-17,-3,-12,-16,-15,-17,-7,\n-59,-36,-13,1,7,1,2,10,2,11,\n13,10,8,-2,7,3,5,4,2,2,\n-3,-8,4,-5,6,7,-42,15,35,-2,\n-46,38,28,-20,-9,1,7,-3,0,-2,\n0,0,0,0,0,0,0,0,0,0,\n-15,-28,52,32,5,-5,-17,-20,-10,-1};\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/exc_10_32_table.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: exc_10_32_table.c\n   Codebook for excitation in narrowband CELP mode (4000 bps)\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\nconst signed char exc_10_32_table[320] = {\n7,17,17,27,25,22,12,4,-3,0,\n28,-36,39,-24,-15,3,-9,15,-5,10,\n31,-28,11,31,-21,9,-11,-11,-2,-7,\n-25,14,-22,31,4,-14,19,-12,14,-5,\n4,-7,4,-5,9,0,-2,42,-47,-16,\n1,8,0,9,23,-57,0,28,-11,6,\n-31,55,-45,3,-5,4,2,-2,4,-7,\n-3,6,-2,7,-3,12,5,8,54,-10,\n8,-7,-8,-24,-25,-27,-14,-5,8,5,\n44,23,5,-9,-11,-11,-13,-9,-12,-8,\n-29,-8,-22,6,-15,3,-12,-1,-5,-3,\n34,-1,29,-16,17,-4,12,2,1,4,\n-2,-4,2,-1,11,-3,-52,28,30,-9,\n-32,25,44,-20,-24,4,6,-1,0,0,\n0,0,0,0,0,0,0,0,0,0,\n-25,-10,22,29,13,-13,-22,-13,-4,0,\n-4,-16,10,15,-36,-24,28,25,-1,-3,\n66,-33,-11,-15,6,0,3,4,-2,5,\n24,-20,-47,29,19,-2,-4,-1,0,-1,\n-2,3,1,8,-11,5,5,-57,28,28,\n0,-16,4,-4,12,-6,-1,2,-20,61,\n-9,24,-22,-42,29,6,17,8,4,2,\n-65,15,8,10,5,6,5,3,2,-2,\n-3,5,-9,4,-5,23,13,23,-3,-63,\n3,-5,-4,-6,0,-3,23,-36,-46,9,\n5,5,8,4,9,-5,1,-3,10,1,\n-6,10,-11,24,-47,31,22,-12,14,-10,\n6,11,-7,-7,7,-31,51,-12,-6,7,\n6,-17,9,-11,-20,52,-19,3,-6,-6,\n-8,-5,23,-41,37,1,-21,10,-14,8,\n7,5,-15,-15,23,39,-26,-33,7,2,\n-32,-30,-21,-8,4,12,17,15,14,11};\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/exc_20_32_table.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: exc_20_32_table.c\n   Codebook for excitation in narrowband CELP mode (2000 bps)\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\nconst signed char exc_20_32_table[640] = {\n12,32,25,46,36,33,9,14,-3,6,1,-8,0,-10,-5,-7,-7,-7,-5,-5,\n31,-27,24,-32,-4,10,-11,21,-3,19,23,-9,22,24,-10,-1,-10,-13,-7,-11,\n42,-33,31,19,-8,0,-10,-16,1,-21,-17,10,-8,14,8,4,11,-2,5,-2,\n-33,11,-16,33,11,-4,9,-4,11,2,6,-5,8,-5,11,-4,-6,26,-36,-16,\n0,4,-2,-8,12,6,-1,34,-46,-22,9,9,21,9,5,-66,-5,26,2,10,\n13,2,19,9,12,-81,3,13,13,0,-14,22,-35,6,-7,-4,6,-6,10,-6,\n-31,38,-33,0,-10,-11,5,-12,12,-17,5,0,-6,13,-9,10,8,25,33,2,\n-12,8,-6,10,-2,21,7,17,43,5,11,-7,-9,-20,-36,-20,-23,-4,-4,-3,\n27,-9,-9,-49,-39,-38,-11,-9,6,5,23,25,5,3,3,4,1,2,-3,-1,\n87,39,17,-21,-9,-19,-9,-15,-13,-14,-17,-11,-10,-11,-8,-6,-1,-3,-3,-1,\n-54,-34,-27,-8,-11,-4,-5,0,0,4,8,6,9,7,9,7,6,5,5,5,\n48,10,19,-10,12,-1,9,-3,2,5,-3,2,-2,-2,0,-2,-26,6,9,-7,\n-16,-9,2,7,7,-5,-43,11,22,-11,-9,34,37,-15,-13,-6,1,-1,1,1,\n-64,56,52,-11,-27,5,4,3,1,2,1,3,-1,-4,-4,-10,-7,-4,-4,2,\n-1,-7,-7,-12,-10,-15,-9,-5,-5,-11,-16,-13,6,16,4,-13,-16,-10,-4,2,\n-47,-13,25,47,19,-14,-20,-8,-17,0,-3,-13,1,6,-17,-14,15,1,10,6,\n-24,0,-10,19,-69,-8,14,49,17,-5,33,-29,3,-4,0,2,-8,5,-6,2,\n120,-56,-12,-47,23,-9,6,-5,1,2,-5,1,-10,4,-1,-1,4,-1,0,-3,\n30,-52,-67,30,22,11,-1,-4,3,0,7,2,0,1,-10,-4,-8,-13,5,1,\n1,-1,5,13,-9,-3,-10,-62,22,48,-4,-6,2,3,5,1,1,4,1,13,\n3,-20,10,-9,13,-2,-4,9,-20,44,-1,20,-32,-67,19,0,28,11,8,2,\n-11,15,-19,-53,31,2,34,10,6,-4,-58,8,10,13,14,1,12,2,0,0,\n-128,37,-8,44,-9,26,-3,18,2,6,11,-1,9,1,5,3,0,1,1,2,\n12,3,-2,-3,7,25,9,18,-6,-37,3,-8,-16,3,-10,-7,17,-34,-44,11,\n17,-15,-3,-16,-1,-13,11,-46,-65,-2,8,13,2,4,4,5,15,5,9,6,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n-9,19,-12,12,-28,38,29,-1,12,2,5,23,-10,3,4,-15,21,-4,3,3,\n6,17,-9,-4,-8,-20,26,5,-10,6,1,-19,18,-15,-12,47,-6,-2,-7,-9,\n-1,-17,-2,-2,-14,30,-14,2,-7,-4,-1,-12,11,-25,16,-3,-12,11,-7,7,\n-17,1,19,-28,31,-7,-10,7,-10,3,12,5,-16,6,24,41,-29,-54,0,1,\n7,-1,5,-6,13,10,-4,-8,8,-9,-27,-53,-38,-1,10,19,17,16,12,12,\n0,3,-7,-4,13,12,-31,-14,6,-5,3,5,17,43,50,25,10,1,-6,-2};\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/exc_5_256_table.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: exc_5_256_table.c\n   Codebook for excitation in narrowband CELP mode (12800 bps)\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\nconst signed char exc_5_256_table[1280] = {\n-8,-37,5,-43,5,\n73,61,39,12,-3,\n-61,-32,2,42,30,\n-3,17,-27,9,34,\n20,-1,-5,2,23,\n-7,-46,26,53,-47,\n20,-2,-33,-89,-51,\n-64,27,11,15,-34,\n-5,-56,25,-9,-1,\n-29,1,40,67,-23,\n-16,16,33,19,7,\n14,85,22,-10,-10,\n-12,-7,-1,52,89,\n29,11,-20,-37,-46,\n-15,17,-24,-28,24,\n2,1,0,23,-101,\n23,14,-1,-23,-18,\n9,5,-13,38,1,\n-28,-28,4,27,51,\n-26,34,-40,35,47,\n54,38,-54,-26,-6,\n42,-25,13,-30,-36,\n18,41,-4,-33,23,\n-32,-7,-4,51,-3,\n17,-52,56,-47,36,\n-2,-21,36,10,8,\n-33,31,19,9,-5,\n-40,10,-9,-21,19,\n18,-78,-18,-5,0,\n-26,-36,-47,-51,-44,\n18,40,27,-2,29,\n49,-26,2,32,-54,\n30,-73,54,3,-5,\n36,22,53,10,-1,\n-84,-53,-29,-5,3,\n-44,53,-51,4,22,\n71,-35,-1,33,-5,\n-27,-7,36,17,-23,\n-39,16,-9,-55,-15,\n-20,39,-35,6,-39,\n-14,18,48,-64,-17,\n-15,9,39,81,37,\n-68,37,47,-21,-6,\n-104,13,6,9,-2,\n35,8,-23,18,42,\n45,21,33,-5,-49,\n9,-6,-43,-56,39,\n2,-16,-25,87,1,\n-3,-9,17,-25,-11,\n-9,-1,10,2,-14,\n-14,4,-1,-10,28,\n-23,40,-32,26,-9,\n26,4,-27,-23,3,\n42,-60,1,49,-3,\n27,10,-52,-40,-2,\n18,45,-23,17,-44,\n3,-3,17,-46,52,\n-40,-47,25,75,31,\n-49,53,30,-30,-32,\n-36,38,-6,-15,-16,\n54,-27,-48,3,38,\n-29,-32,-22,-14,-4,\n-23,-13,32,-39,9,\n8,-45,-13,34,-16,\n49,40,32,31,28,\n23,23,32,47,59,\n-68,8,62,44,25,\n-14,-24,-65,-16,36,\n67,-25,-38,-21,4,\n-33,-2,42,5,-63,\n40,11,26,-42,-23,\n-61,79,-31,23,-20,\n10,-32,53,-25,-36,\n10,-26,-5,3,0,\n-71,5,-10,-37,1,\n-24,21,-54,-17,1,\n-29,-25,-15,-27,32,\n68,45,-16,-37,-18,\n-5,1,0,-77,71,\n-6,3,-20,71,-67,\n29,-35,10,-30,19,\n4,16,17,5,0,\n-14,19,2,28,26,\n59,3,2,24,39,\n55,-50,-45,-18,-17,\n33,-35,14,-1,1,\n8,87,-35,-29,0,\n-27,13,-7,23,-13,\n37,-40,50,-35,14,\n19,-7,-14,49,54,\n-5,22,-2,-29,-8,\n-27,38,13,27,48,\n12,-41,-21,-15,28,\n7,-16,-24,-19,-20,\n11,-20,9,2,13,\n23,-20,11,27,-27,\n71,-69,8,2,-6,\n22,12,16,16,9,\n-16,-8,-17,1,25,\n1,40,-37,-33,66,\n94,53,4,-22,-25,\n-41,-42,25,35,-16,\n-15,57,31,-29,-32,\n21,16,-60,45,15,\n-1,7,57,-26,-47,\n-29,11,8,15,19,\n-105,-8,54,27,10,\n-17,6,-12,-1,-10,\n4,0,23,-10,31,\n13,11,10,12,-64,\n23,-3,-8,-19,16,\n52,24,-40,16,10,\n40,5,9,0,-13,\n-7,-21,-8,-6,-7,\n-21,59,16,-53,18,\n-60,11,-47,14,-18,\n25,-13,-24,4,-39,\n16,-28,54,26,-67,\n30,27,-20,-52,20,\n-12,55,12,18,-16,\n39,-14,-6,-26,56,\n-88,-55,12,25,26,\n-37,6,75,0,-34,\n-81,54,-30,1,-7,\n49,-23,-14,21,10,\n-62,-58,-57,-47,-34,\n15,-4,34,-78,31,\n25,-11,7,50,-10,\n42,-63,14,-36,-4,\n57,55,57,53,42,\n-42,-1,15,40,37,\n15,25,-11,6,1,\n31,-2,-6,-1,-7,\n-64,34,28,30,-1,\n3,21,0,-88,-12,\n-56,25,-28,40,8,\n-28,-14,9,12,2,\n-6,-17,22,49,-6,\n-26,14,28,-20,4,\n-12,50,35,40,13,\n-38,-58,-29,17,30,\n22,60,26,-54,-39,\n-12,58,-28,-63,10,\n-21,-8,-12,26,-62,\n6,-10,-11,-22,-6,\n-7,4,1,18,2,\n-70,11,14,4,13,\n19,-24,-34,24,67,\n17,51,-21,13,23,\n54,-30,48,1,-13,\n80,26,-16,-2,13,\n-4,6,-30,29,-24,\n73,-58,30,-27,20,\n-2,-21,41,45,30,\n-27,-3,-5,-18,-20,\n-49,-3,-35,10,42,\n-19,-67,-53,-11,9,\n13,-15,-33,-51,-30,\n15,7,25,-30,4,\n28,-22,-34,54,-29,\n39,-46,20,16,34,\n-4,47,75,1,-44,\n-55,-24,7,-1,9,\n-42,50,-8,-36,41,\n68,0,-4,-10,-23,\n-15,-50,64,36,-9,\n-27,12,25,-38,-47,\n-37,32,-49,51,-36,\n2,-4,69,-26,19,\n7,45,67,46,13,\n-63,46,15,-47,4,\n-41,13,-6,5,-21,\n37,26,-55,-7,33,\n-1,-28,10,-17,-64,\n-14,0,-36,-17,93,\n-3,-9,-66,44,-21,\n3,-12,38,-6,-13,\n-12,19,13,43,-43,\n-10,-12,6,-5,9,\n-49,32,-5,2,4,\n5,15,-16,10,-21,\n8,-62,-8,64,8,\n79,-1,-66,-49,-18,\n5,40,-5,-30,-45,\n1,-6,21,-32,93,\n-18,-30,-21,32,21,\n-18,22,8,5,-41,\n-54,80,22,-10,-7,\n-8,-23,-64,66,56,\n-14,-30,-41,-46,-14,\n-29,-37,27,-14,42,\n-2,-9,-29,34,14,\n33,-14,22,4,10,\n26,26,28,32,23,\n-72,-32,3,0,-14,\n35,-42,-78,-32,6,\n29,-18,-45,-5,7,\n-33,-45,-3,-22,-34,\n8,-8,4,-51,-25,\n-9,59,-78,21,-5,\n-25,-48,66,-15,-17,\n-24,-49,-13,25,-23,\n-64,-6,40,-24,-19,\n-11,57,-33,-8,1,\n10,-52,-54,28,39,\n49,34,-11,-61,-41,\n-43,10,15,-15,51,\n30,15,-51,32,-34,\n-2,-34,14,18,16,\n1,1,-3,-3,1,\n1,-18,6,16,48,\n12,-5,-42,7,36,\n48,7,-20,-10,7,\n12,2,54,39,-38,\n37,54,4,-11,-8,\n-46,-10,5,-10,-34,\n46,-12,29,-37,39,\n36,-11,24,56,17,\n14,20,25,0,-25,\n-28,55,-7,-5,27,\n3,9,-26,-8,6,\n-24,-10,-30,-31,-34,\n18,4,22,21,40,\n-1,-29,-37,-8,-21,\n92,-29,11,-3,11,\n73,23,22,7,4,\n-44,-9,-11,21,-13,\n11,9,-78,-1,47,\n114,-12,-37,-19,-5,\n-11,-22,19,12,-30,\n7,38,45,-21,-8,\n-9,55,-45,56,-21,\n7,17,46,-57,-87,\n-6,27,31,31,7,\n-56,-12,46,21,-5,\n-12,36,3,3,-21,\n43,19,12,-7,9,\n-14,0,-9,-33,-91,\n7,26,3,-11,64,\n83,-31,-46,25,2,\n9,5,2,2,-1,\n20,-17,10,-5,-27,\n-8,20,8,-19,16,\n-21,-13,-31,5,5,\n42,24,9,34,-20,\n28,-61,22,11,-39,\n64,-20,-1,-30,-9,\n-20,24,-25,-24,-29,\n22,-60,6,-5,41,\n-9,-87,14,34,15,\n-57,52,69,15,-3,\n-102,58,16,3,6,\n60,-75,-32,26,7,\n-57,-27,-32,-24,-21,\n-29,-16,62,-46,31,\n30,-27,-15,7,15};\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/exc_5_64_table.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: exc_5_64_table.c\n   Codebook for excitation in narrowband CELP mode (9600 bps)\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\nconst signed char exc_5_64_table[320]={\n1,5,-15,49,-66,\n-48,-4,50,-44,7,\n37,16,-18,25,-26,\n-26,-15,19,19,-27,\n-47,28,57,5,-17,\n-32,-41,68,21,-2,\n64,56,8,-16,-13,\n-26,-9,-16,11,6,\n-39,25,-19,22,-31,\n20,-45,55,-43,10,\n-16,47,-40,40,-20,\n-51,3,-17,-14,-15,\n-24,53,-20,-46,46,\n27,-68,32,3,-18,\n-5,9,-31,16,-9,\n-10,-1,-23,48,95,\n47,25,-41,-32,-3,\n15,-25,-55,36,41,\n-27,20,5,13,14,\n-22,5,2,-23,18,\n46,-15,17,-18,-34,\n-5,-8,27,-55,73,\n16,2,-1,-17,40,\n-78,33,0,2,19,\n4,53,-16,-15,-16,\n-28,-3,-13,49,8,\n-7,-29,27,-13,32,\n20,32,-61,16,14,\n41,44,40,24,20,\n7,4,48,-60,-77,\n17,-6,-48,65,-15,\n32,-30,-71,-10,-3,\n-6,10,-2,-7,-29,\n-56,67,-30,7,-5,\n86,-6,-10,0,5,\n-31,60,34,-38,-3,\n24,10,-2,30,23,\n24,-41,12,70,-43,\n15,-17,6,13,16,\n-13,8,30,-15,-8,\n5,23,-34,-98,-4,\n-13,13,-48,-31,70,\n12,31,25,24,-24,\n26,-7,33,-16,8,\n5,-11,-14,-8,-65,\n13,10,-2,-9,0,\n-3,-68,5,35,7,\n0,-31,-1,-17,-9,\n-9,16,-37,-18,-1,\n69,-48,-28,22,-21,\n-11,5,49,55,23,\n-86,-36,16,2,13,\n63,-51,30,-11,13,\n24,-18,-6,14,-19,\n1,41,9,-5,27,\n-36,-44,-34,-37,-21,\n-26,31,-39,15,43,\n5,-8,29,20,-8,\n-20,-52,-28,-1,13,\n26,-34,-10,-9,27,\n-8,8,27,-66,4,\n12,-22,49,10,-77,\n32,-18,3,-38,12,\n-3,-1,2,2,0};\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/exc_8_128_table.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: exc_8_128_table.c\n   Codebook for excitation in narrowband CELP mode (7000 bps)\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\nconst signed char exc_8_128_table[1024] = {\n-14,9,13,-32,2,-10,31,-10,\n-8,-8,6,-4,-1,10,-64,23,\n6,20,13,6,8,-22,16,34,\n7,42,-49,-28,5,26,4,-15,\n41,34,41,32,33,24,23,14,\n8,40,34,4,-24,-41,-19,-15,\n13,-13,33,-54,24,27,-44,33,\n27,-15,-15,24,-19,14,-36,14,\n-9,24,-12,-4,37,-5,16,-34,\n5,10,33,-15,-54,-16,12,25,\n12,1,2,0,3,-1,-4,-4,\n11,2,-56,54,27,-20,13,-6,\n-46,-41,-33,-11,-5,7,12,14,\n-14,-5,8,20,6,3,4,-8,\n-5,-42,11,8,-14,25,-2,2,\n13,11,-22,39,-9,9,5,-45,\n-9,7,-9,12,-7,34,-17,-102,\n7,2,-42,18,35,-9,-34,11,\n-5,-2,3,22,46,-52,-25,-9,\n-94,8,11,-5,-5,-5,4,-7,\n-35,-7,54,5,-32,3,24,-9,\n-22,8,65,37,-1,-12,-23,-6,\n-9,-28,55,-33,14,-3,2,18,\n-60,41,-17,8,-16,17,-11,0,\n-11,29,-28,37,9,-53,33,-14,\n-9,7,-25,-7,-11,26,-32,-8,\n24,-21,22,-19,19,-10,29,-14,\n0,0,0,0,0,0,0,0,\n-5,-52,10,41,6,-30,-4,16,\n32,22,-27,-22,32,-3,-28,-3,\n3,-35,6,17,23,21,8,2,\n4,-45,-17,14,23,-4,-31,-11,\n-3,14,1,19,-11,2,61,-8,\n9,-12,7,-10,12,-3,-24,99,\n-48,23,50,-37,-5,-23,0,8,\n-14,35,-64,-5,46,-25,13,-1,\n-49,-19,-15,9,34,50,25,11,\n-6,-9,-16,-20,-32,-33,-32,-27,\n10,-8,12,-15,56,-14,-32,33,\n3,-9,1,65,-9,-9,-10,-2,\n-6,-23,9,17,3,-28,13,-32,\n4,-2,-10,4,-16,76,12,-52,\n6,13,33,-6,4,-14,-9,-3,\n1,-15,-16,28,1,-15,11,16,\n9,4,-21,-37,-40,-6,22,12,\n-15,-23,-14,-17,-16,-9,-10,-9,\n13,-39,41,5,-9,16,-38,25,\n46,-47,4,49,-14,17,-2,6,\n18,5,-6,-33,-22,44,50,-2,\n1,3,-6,7,7,-3,-21,38,\n-18,34,-14,-41,60,-13,6,16,\n-24,35,19,-13,-36,24,3,-17,\n-14,-10,36,44,-44,-29,-3,3,\n-54,-8,12,55,26,4,-2,-5,\n2,-11,22,-23,2,22,1,-25,\n-39,66,-49,21,-8,-2,10,-14,\n-60,25,6,10,27,-25,16,5,\n-2,-9,26,-13,-20,58,-2,7,\n52,-9,2,5,-4,-15,23,-1,\n-38,23,8,27,-6,0,-27,-7,\n39,-10,-14,26,11,-45,-12,9,\n-5,34,4,-35,10,43,-22,-11,\n56,-7,20,1,10,1,-26,9,\n94,11,-27,-14,-13,1,-11,0,\n14,-5,-6,-10,-4,-15,-8,-41,\n21,-5,1,-28,-8,22,-9,33,\n-23,-4,-4,-12,39,4,-7,3,\n-60,80,8,-17,2,-6,12,-5,\n1,9,15,27,31,30,27,23,\n61,47,26,10,-5,-8,-12,-13,\n5,-18,25,-15,-4,-15,-11,12,\n-2,-2,-16,-2,-6,24,12,11,\n-4,9,1,-9,14,-45,57,12,\n20,-35,26,11,-64,32,-10,-10,\n42,-4,-9,-16,32,24,7,10,\n52,-11,-57,29,0,8,0,-6,\n17,-17,-56,-40,7,20,18,12,\n-6,16,5,7,-1,9,1,10,\n29,12,16,13,-2,23,7,9,\n-3,-4,-5,18,-64,13,55,-25,\n9,-9,24,14,-25,15,-11,-40,\n-30,37,1,-19,22,-5,-31,13,\n-2,0,7,-4,16,-67,12,66,\n-36,24,-8,18,-15,-23,19,0,\n-45,-7,4,3,-13,13,35,5,\n13,33,10,27,23,0,-7,-11,\n43,-74,36,-12,2,5,-8,6,\n-33,11,-16,-14,-5,-7,-3,17,\n-34,27,-16,11,-9,15,33,-31,\n8,-16,7,-6,-7,63,-55,-17,\n11,-1,20,-46,34,-30,6,9,\n19,28,-9,5,-24,-8,-23,-2,\n31,-19,-16,-5,-15,-18,0,26,\n18,37,-5,-15,-2,17,5,-27,\n21,-33,44,12,-27,-9,17,11,\n25,-21,-31,-7,13,33,-8,-25,\n-7,7,-10,4,-6,-9,48,-82,\n-23,-8,6,11,-23,3,-3,49,\n-29,25,31,4,14,16,9,-4,\n-18,10,-26,3,5,-44,-9,9,\n-47,-55,15,9,28,1,4,-3,\n46,6,-6,-38,-29,-31,-15,-6,\n3,0,14,-6,8,-54,-50,33,\n-5,1,-14,33,-48,26,-4,-5,\n-3,-5,-3,-5,-28,-22,77,55,\n-1,2,10,10,-9,-14,-66,-49,\n11,-36,-6,-20,10,-10,16,12,\n4,-1,-16,45,-44,-50,31,-2,\n25,42,23,-32,-22,0,11,20,\n-40,-35,-40,-36,-32,-26,-21,-13,\n52,-22,6,-24,-20,17,-5,-8,\n36,-25,-11,21,-26,6,34,-8,\n7,20,-3,5,-25,-8,18,-5,\n-9,-4,1,-9,20,20,39,48,\n-24,9,5,-65,22,29,4,3,\n-43,-11,32,-6,9,19,-27,-10,\n-47,-14,24,10,-7,-36,-7,-1,\n-4,-5,-5,16,53,25,-26,-29,\n-4,-12,45,-58,-34,33,-5,2,\n-1,27,-48,31,-15,22,-5,4,\n7,7,-25,-3,11,-22,16,-12,\n8,-3,7,-11,45,14,-73,-19,\n56,-46,24,-20,28,-12,-2,-1,\n-36,-3,-33,19,-6,7,2,-15,\n5,-31,-45,8,35,13,20,0,\n-9,48,-13,-43,-3,-13,2,-5,\n72,-68,-27,2,1,-2,-7,5,\n36,33,-40,-12,-4,-5,23,19};\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/fftwrap.c",
    "content": "/* Copyright (C) 2005-2006 Jean-Marc Valin \n   File: fftwrap.c\n\n   Wrapper for various FFTs \n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arch.h\"\n#include \"os_support.h\"\n\n#define MAX_FFT_SIZE 2048\n\n#ifdef FIXED_POINT\nstatic int maximize_range(spx_word16_t *in, spx_word16_t *out, spx_word16_t bound, int len)\n{\n   int i, shift;\n   spx_word16_t max_val = 0;\n   for (i=0;i<len;i++)\n   {\n      if (in[i]>max_val)\n         max_val = in[i];\n      if (-in[i]>max_val)\n         max_val = -in[i];\n   }\n   shift=0;\n   while (max_val <= (bound>>1) && max_val != 0)\n   {\n      max_val <<= 1;\n      shift++;\n   }\n   for (i=0;i<len;i++)\n   {\n      out[i] = SHL16(in[i], shift);\n   }   \n   return shift;\n}\n\nstatic void renorm_range(spx_word16_t *in, spx_word16_t *out, int shift, int len)\n{\n   int i;\n   for (i=0;i<len;i++)\n   {\n      out[i] = PSHR16(in[i], shift);\n   }\n}\n#endif\n\n#ifdef USE_SMALLFT\n\n#include \"smallft.h\"\n#include <math.h>\n\nvoid *spx_fft_init(int size)\n{\n   struct drft_lookup *table;\n   table = speex_alloc(sizeof(struct drft_lookup));\n   spx_drft_init((struct drft_lookup *)table, size);\n   return (void*)table;\n}\n\nvoid spx_fft_destroy(void *table)\n{\n   spx_drft_clear(table);\n   speex_free(table);\n}\n\nvoid spx_fft(void *table, float *in, float *out)\n{\n   if (in==out)\n   {\n      int i;\n      float scale = 1./((struct drft_lookup *)table)->n;\n      speex_warning(\"FFT should not be done in-place\");\n      for (i=0;i<((struct drft_lookup *)table)->n;i++)\n         out[i] = scale*in[i];\n   } else {\n      int i;\n      float scale = 1./((struct drft_lookup *)table)->n;\n      for (i=0;i<((struct drft_lookup *)table)->n;i++)\n         out[i] = scale*in[i];\n   }\n   spx_drft_forward((struct drft_lookup *)table, out);\n}\n\nvoid spx_ifft(void *table, float *in, float *out)\n{\n   if (in==out)\n   {\n      speex_warning(\"FFT should not be done in-place\");\n   } else {\n      int i;\n      for (i=0;i<((struct drft_lookup *)table)->n;i++)\n         out[i] = in[i];\n   }\n   spx_drft_backward((struct drft_lookup *)table, out);\n}\n\n#elif defined(USE_INTEL_MKL)\n#include <mkl.h>\n\nstruct mkl_config {\n  DFTI_DESCRIPTOR_HANDLE desc;\n  int N;\n};\n\nvoid *spx_fft_init(int size)\n{\n  struct mkl_config *table = (struct mkl_config *) speex_alloc(sizeof(struct mkl_config));\n  table->N = size;\n  DftiCreateDescriptor(&table->desc, DFTI_SINGLE, DFTI_REAL, 1, size);\n  DftiSetValue(table->desc, DFTI_PACKED_FORMAT, DFTI_PACK_FORMAT);\n  DftiSetValue(table->desc, DFTI_PLACEMENT, DFTI_NOT_INPLACE);\n  DftiSetValue(table->desc, DFTI_FORWARD_SCALE, 1.0f / size);\n  DftiCommitDescriptor(table->desc);\n  return table;\n}\n\nvoid spx_fft_destroy(void *table)\n{\n  struct mkl_config *t = (struct mkl_config *) table;\n  DftiFreeDescriptor(t->desc);\n  speex_free(table);\n}\n\nvoid spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)\n{\n  struct mkl_config *t = (struct mkl_config *) table;\n  DftiComputeForward(t->desc, in, out);\n}\n\nvoid spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)\n{\n  struct mkl_config *t = (struct mkl_config *) table;\n  DftiComputeBackward(t->desc, in, out);\n}\n\n#elif defined(USE_GPL_FFTW3)\n\n#include <fftw3.h>\n\nstruct fftw_config {\n  float *in;\n  float *out;\n  fftwf_plan fft;\n  fftwf_plan ifft;\n  int N;\n};\n\nvoid *spx_fft_init(int size)\n{\n  struct fftw_config *table = (struct fftw_config *) speex_alloc(sizeof(struct fftw_config));\n  table->in = fftwf_malloc(sizeof(float) * (size+2));\n  table->out = fftwf_malloc(sizeof(float) * (size+2));\n\n  table->fft = fftwf_plan_dft_r2c_1d(size, table->in, (fftwf_complex *) table->out, FFTW_PATIENT);\n  table->ifft = fftwf_plan_dft_c2r_1d(size, (fftwf_complex *) table->in, table->out, FFTW_PATIENT);\n\n  table->N = size;\n  return table;\n}\n\nvoid spx_fft_destroy(void *table)\n{\n  struct fftw_config *t = (struct fftw_config *) table;\n  fftwf_destroy_plan(t->fft);\n  fftwf_destroy_plan(t->ifft);\n  fftwf_free(t->in);\n  fftwf_free(t->out);\n  speex_free(table);\n}\n\n\nvoid spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)\n{\n  int i;\n  struct fftw_config *t = (struct fftw_config *) table;\n  const int N = t->N;\n  float *iptr = t->in;\n  float *optr = t->out;\n  const float m = 1.0 / N;\n  for(i=0;i<N;++i)\n    iptr[i]=in[i] * m;\n\n  fftwf_execute(t->fft);\n\n  out[0] = optr[0];\n  for(i=1;i<N;++i)\n    out[i] = optr[i+1];\n}\n\nvoid spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out) \n{\n  int i;\n  struct fftw_config *t = (struct fftw_config *) table;\n  const int N = t->N;\n  float *iptr = t->in;\n  float *optr = t->out;\n\n  iptr[0] = in[0];\n  iptr[1] = 0.0f;\n  for(i=1;i<N;++i)\n    iptr[i+1] = in[i];\n  iptr[N+1] = 0.0f;\n\n  fftwf_execute(t->ifft);\n  \n  for(i=0;i<N;++i)\n    out[i] = optr[i];\n}\n\n#elif defined(USE_KISS_FFT)\n\n#include \"kiss_fftr.h\"\n#include \"kiss_fft.h\"\n\nstruct kiss_config {\n   kiss_fftr_cfg forward;\n   kiss_fftr_cfg backward;\n   int N;\n};\n\nvoid *spx_fft_init(int size)\n{\n   struct kiss_config *table;\n   table = (struct kiss_config*)speex_alloc(sizeof(struct kiss_config));\n   table->forward = kiss_fftr_alloc(size,0,NULL,NULL);\n   table->backward = kiss_fftr_alloc(size,1,NULL,NULL);\n   table->N = size;\n   return table;\n}\n\nvoid spx_fft_destroy(void *table)\n{\n   struct kiss_config *t = (struct kiss_config *)table;\n   kiss_fftr_free(t->forward);\n   kiss_fftr_free(t->backward);\n   speex_free(table);\n}\n\n#ifdef FIXED_POINT\n\nvoid spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)\n{\n   int shift;\n   struct kiss_config *t = (struct kiss_config *)table;\n   shift = maximize_range(in, in, 32000, t->N);\n   kiss_fftr2(t->forward, in, out);\n   renorm_range(in, in, shift, t->N);\n   renorm_range(out, out, shift, t->N);\n}\n\n#else\n\nvoid spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)\n{\n   int i;\n   float scale;\n   struct kiss_config *t = (struct kiss_config *)table;\n   scale = 1./t->N;\n   kiss_fftr2(t->forward, in, out);\n   for (i=0;i<t->N;i++)\n      out[i] *= scale;\n}\n#endif\n\nvoid spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)\n{\n   struct kiss_config *t = (struct kiss_config *)table;\n   kiss_fftri2(t->backward, in, out);\n}\n\n\n#else\n\n#error No other FFT implemented\n\n#endif\n\n\n#ifdef FIXED_POINT\n/*#include \"smallft.h\"*/\n\n\nvoid spx_fft_float(void *table, float *in, float *out)\n{\n   int i;\n#ifdef USE_SMALLFT\n   int N = ((struct drft_lookup *)table)->n;\n#elif defined(USE_KISS_FFT)\n   int N = ((struct kiss_config *)table)->N;\n#else\n#endif\n#ifdef VAR_ARRAYS\n   spx_word16_t _in[N];\n   spx_word16_t _out[N];\n#else\n   spx_word16_t _in[MAX_FFT_SIZE];\n   spx_word16_t _out[MAX_FFT_SIZE];\n#endif\n   for (i=0;i<N;i++)\n      _in[i] = (int)floor(.5+in[i]);\n   spx_fft(table, _in, _out);\n   for (i=0;i<N;i++)\n      out[i] = _out[i];\n#if 0\n   if (!fixed_point)\n   {\n      float scale;\n      struct drft_lookup t;\n      spx_drft_init(&t, ((struct kiss_config *)table)->N);\n      scale = 1./((struct kiss_config *)table)->N;\n      for (i=0;i<((struct kiss_config *)table)->N;i++)\n         out[i] = scale*in[i];\n      spx_drft_forward(&t, out);\n      spx_drft_clear(&t);\n   }\n#endif\n}\n\nvoid spx_ifft_float(void *table, float *in, float *out)\n{\n   int i;\n#ifdef USE_SMALLFT\n   int N = ((struct drft_lookup *)table)->n;\n#elif defined(USE_KISS_FFT)\n   int N = ((struct kiss_config *)table)->N;\n#else\n#endif\n#ifdef VAR_ARRAYS\n   spx_word16_t _in[N];\n   spx_word16_t _out[N];\n#else\n   spx_word16_t _in[MAX_FFT_SIZE];\n   spx_word16_t _out[MAX_FFT_SIZE];\n#endif\n   for (i=0;i<N;i++)\n      _in[i] = (int)floor(.5+in[i]);\n   spx_ifft(table, _in, _out);\n   for (i=0;i<N;i++)\n      out[i] = _out[i];\n#if 0\n   if (!fixed_point)\n   {\n      int i;\n      struct drft_lookup t;\n      spx_drft_init(&t, ((struct kiss_config *)table)->N);\n      for (i=0;i<((struct kiss_config *)table)->N;i++)\n         out[i] = in[i];\n      spx_drft_backward(&t, out);\n      spx_drft_clear(&t);\n   }\n#endif\n}\n\n#else\n\nvoid spx_fft_float(void *table, float *in, float *out)\n{\n   spx_fft(table, in, out);\n}\nvoid spx_ifft_float(void *table, float *in, float *out)\n{\n   spx_ifft(table, in, out);\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/fftwrap.h",
    "content": "/* Copyright (C) 2005 Jean-Marc Valin \n   File: fftwrap.h\n\n   Wrapper for various FFTs \n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifndef FFTWRAP_H\n#define FFTWRAP_H\n\n#include \"arch.h\"\n\n/** Compute tables for an FFT */\nvoid *spx_fft_init(int size);\n\n/** Destroy tables for an FFT */\nvoid spx_fft_destroy(void *table);\n\n/** Forward (real to half-complex) transform */\nvoid spx_fft(void *table, spx_word16_t *in, spx_word16_t *out);\n\n/** Backward (half-complex to real) transform */\nvoid spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out);\n\n/** Forward (real to half-complex) transform of float data */\nvoid spx_fft_float(void *table, float *in, float *out);\n\n/** Backward (half-complex to real) transform of float data */\nvoid spx_ifft_float(void *table, float *in, float *out);\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/filterbank.c",
    "content": "/* Copyright (C) 2006 Jean-Marc Valin */\n/**\n   @file filterbank.c\n   @brief Converting between psd and filterbank\n */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"filterbank.h\"\n#include \"arch.h\"\n#include <math.h>\n#include \"math_approx.h\"\n#include \"os_support.h\"\n      \n#ifdef FIXED_POINT\n\n#define toBARK(n)   (MULT16_16(26829,spx_atan(SHR32(MULT16_16(97,n),2))) + MULT16_16(4588,spx_atan(MULT16_32_Q15(20,MULT16_16(n,n)))) + MULT16_16(3355,n))\n      \n#else\n#define toBARK(n)   (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))\n#endif\n       \n#define toMEL(n)    (2595.f*log10(1.f+(n)/700.f))\n\nFilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type)\n{\n   FilterBank *bank;\n   spx_word32_t df;\n   spx_word32_t max_mel, mel_interval;\n   int i;\n   int id1;\n   int id2;\n   df = DIV32(SHL32(sampling,15),MULT16_16(2,len));\n   max_mel = toBARK(EXTRACT16(sampling/2));\n   mel_interval = PDIV32(max_mel,banks-1);\n   \n   bank = (FilterBank*)speex_alloc(sizeof(FilterBank));\n   bank->nb_banks = banks;\n   bank->len = len;\n   bank->bank_left = (int*)speex_alloc(len*sizeof(int));\n   bank->bank_right = (int*)speex_alloc(len*sizeof(int));\n   bank->filter_left = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));\n   bank->filter_right = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));\n   /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */\n#ifndef FIXED_POINT\n   bank->scaling = (float*)speex_alloc(banks*sizeof(float));\n#endif\n   for (i=0;i<len;i++)\n   {\n      spx_word16_t curr_freq;\n      spx_word32_t mel;\n      spx_word16_t val;\n      curr_freq = EXTRACT16(MULT16_32_P15(i,df));\n      mel = toBARK(curr_freq);\n      if (mel > max_mel)\n         break;\n#ifdef FIXED_POINT\n      id1 = DIV32(mel,mel_interval);\n#else      \n      id1 = (int)(floor(mel/mel_interval));\n#endif\n      if (id1>banks-2)\n      {\n         id1 = banks-2;\n         val = Q15_ONE;\n      } else {\n         val = DIV32_16(mel - id1*mel_interval,EXTRACT16(PSHR32(mel_interval,15)));\n      }\n      id2 = id1+1;\n      bank->bank_left[i] = id1;\n      bank->filter_left[i] = SUB16(Q15_ONE,val);\n      bank->bank_right[i] = id2;\n      bank->filter_right[i] = val;\n   }\n   \n   /* Think I can safely disable normalisation for fixed-point (and probably float as well) */\n#ifndef FIXED_POINT\n   for (i=0;i<bank->nb_banks;i++)\n      bank->scaling[i] = 0;\n   for (i=0;i<bank->len;i++)\n   {\n      int id = bank->bank_left[i];\n      bank->scaling[id] += bank->filter_left[i];\n      id = bank->bank_right[i];\n      bank->scaling[id] += bank->filter_right[i];\n   }\n   for (i=0;i<bank->nb_banks;i++)\n      bank->scaling[i] = Q15_ONE/(bank->scaling[i]);\n#endif\n   return bank;\n}\n\nvoid filterbank_destroy(FilterBank *bank)\n{\n   speex_free(bank->bank_left);\n   speex_free(bank->bank_right);\n   speex_free(bank->filter_left);\n   speex_free(bank->filter_right);\n#ifndef FIXED_POINT\n   speex_free(bank->scaling);\n#endif\n   speex_free(bank);\n}\n\nvoid filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel)\n{\n   int i;\n   for (i=0;i<bank->nb_banks;i++)\n      mel[i] = 0;\n\n   for (i=0;i<bank->len;i++)\n   {\n      int id;\n      id = bank->bank_left[i];\n      mel[id] += MULT16_32_P15(bank->filter_left[i],ps[i]);\n      id = bank->bank_right[i];\n      mel[id] += MULT16_32_P15(bank->filter_right[i],ps[i]);\n   }\n   /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */\n#ifndef FIXED_POINT\n   /*for (i=0;i<bank->nb_banks;i++)\n      mel[i] = MULT16_32_P15(Q15(bank->scaling[i]),mel[i]);\n   */\n#endif\n}\n\nvoid filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *ps)\n{\n   int i;\n   for (i=0;i<bank->len;i++)\n   {\n      spx_word32_t tmp;\n      int id1, id2;\n      id1 = bank->bank_left[i];\n      id2 = bank->bank_right[i];\n      tmp = MULT16_16(mel[id1],bank->filter_left[i]);\n      tmp += MULT16_16(mel[id2],bank->filter_right[i]);\n      ps[i] = EXTRACT16(PSHR32(tmp,15));\n   }\n}\n\n\n#ifndef FIXED_POINT\nvoid filterbank_compute_bank(FilterBank *bank, float *ps, float *mel)\n{\n   int i;\n   for (i=0;i<bank->nb_banks;i++)\n      mel[i] = 0;\n\n   for (i=0;i<bank->len;i++)\n   {\n      int id = bank->bank_left[i];\n      mel[id] += bank->filter_left[i]*ps[i];\n      id = bank->bank_right[i];\n      mel[id] += bank->filter_right[i]*ps[i];\n   }\n   for (i=0;i<bank->nb_banks;i++)\n      mel[i] *= bank->scaling[i];\n}\n\nvoid filterbank_compute_psd(FilterBank *bank, float *mel, float *ps)\n{\n   int i;\n   for (i=0;i<bank->len;i++)\n   {\n      int id = bank->bank_left[i];\n      ps[i] = mel[id]*bank->filter_left[i];\n      id = bank->bank_right[i];\n      ps[i] += mel[id]*bank->filter_right[i];\n   }\n}\n\nvoid filterbank_psy_smooth(FilterBank *bank, float *ps, float *mask)\n{\n   /* Low freq slope: 14 dB/Bark*/\n   /* High freq slope: 9 dB/Bark*/\n   /* Noise vs tone: 5 dB difference */\n   /* FIXME: Temporary kludge */\n   float bark[100];\n   int i;\n   /* Assumes 1/3 Bark resolution */\n   float decay_low = 0.34145f;\n   float decay_high = 0.50119f;\n   filterbank_compute_bank(bank, ps, bark);\n   for (i=1;i<bank->nb_banks;i++)\n   {\n      /*float decay_high = 13-1.6*log10(bark[i-1]);\n      decay_high = pow(10,(-decay_high/30.f));*/\n      bark[i] = bark[i] + decay_high*bark[i-1];\n   }\n   for (i=bank->nb_banks-2;i>=0;i--)\n   {\n      bark[i] = bark[i] + decay_low*bark[i+1];\n   }\n   filterbank_compute_psd(bank, bark, mask);\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/filterbank.h",
    "content": "/* Copyright (C) 2006 Jean-Marc Valin */\n/**\n   @file filterbank.h\n   @brief Converting between psd and filterbank\n */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef FILTERBANK_H\n#define FILTERBANK_H\n\n#include \"arch.h\"\n\ntypedef struct {\n   int *bank_left;\n   int *bank_right;\n   spx_word16_t *filter_left;\n   spx_word16_t *filter_right;\n#ifndef FIXED_POINT\n   float *scaling;\n#endif\n   int nb_banks;\n   int len;\n} FilterBank;\n\n\nFilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type);\n\nvoid filterbank_destroy(FilterBank *bank);\n\nvoid filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel);\n\nvoid filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *psd);\n\n#ifndef FIXED_POINT\nvoid filterbank_compute_bank(FilterBank *bank, float *psd, float *mel);\nvoid filterbank_compute_psd(FilterBank *bank, float *mel, float *psd);\n#endif\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/filters.c",
    "content": "/* Copyright (C) 2002-2006 Jean-Marc Valin \n   File: filters.c\n   Various analysis/synthesis filters\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"filters.h\"\n#include \"stack_alloc.h\"\n#include \"arch.h\"\n#include \"math_approx.h\"\n#include \"ltp.h\"\n#include <math.h>\n\n#ifdef _USE_SSE\n#include \"filters_sse.h\"\n#elif defined (ARM4_ASM) || defined(ARM5E_ASM)\n#include \"filters_arm4.h\"\n#elif defined (BFIN_ASM)\n#include \"filters_bfin.h\"\n#endif\n\n\n\nvoid bw_lpc(spx_word16_t gamma, const spx_coef_t *lpc_in, spx_coef_t *lpc_out, int order)\n{\n   int i;\n   spx_word16_t tmp=gamma;\n   for (i=0;i<order;i++)\n   {\n      lpc_out[i] = MULT16_16_P15(tmp,lpc_in[i]);\n      tmp = MULT16_16_P15(tmp, gamma);\n   }\n}\n\nvoid sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max_val, int len)\n{\n   int i;\n   for (i=0;i<len;i++)\n   {\n      /* It's important we do the test that way so we can catch NaNs, which are neither greater nor smaller */\n      if (!(vec[i]>=min_val && vec[i] <= max_val))\n      {\n         if (vec[i] < min_val)\n            vec[i] = min_val;\n         else if (vec[i] > max_val)\n            vec[i] = max_val;\n         else /* Has to be NaN */\n            vec[i] = 0;\n      }\n   }\n}\n\nvoid highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem)\n{\n   int i;\n#ifdef FIXED_POINT\n   const spx_word16_t Pcoef[5][3] = {{16384, -31313, 14991}, {16384, -31569, 15249}, {16384, -31677, 15328}, {16384, -32313, 15947}, {16384, -22446, 6537}};\n   const spx_word16_t Zcoef[5][3] = {{15672, -31344, 15672}, {15802, -31601, 15802}, {15847, -31694, 15847}, {16162, -32322, 16162}, {14418, -28836, 14418}};\n#else\n   const spx_word16_t Pcoef[5][3] = {{1.00000f, -1.91120f, 0.91498f}, {1.00000f, -1.92683f, 0.93071f}, {1.00000f, -1.93338f, 0.93553f}, {1.00000f, -1.97226f, 0.97332f}, {1.00000f, -1.37000f, 0.39900f}};\n   const spx_word16_t Zcoef[5][3] = {{0.95654f, -1.91309f, 0.95654f}, {0.96446f, -1.92879f, 0.96446f}, {0.96723f, -1.93445f, 0.96723f}, {0.98645f, -1.97277f, 0.98645f}, {0.88000f, -1.76000f, 0.88000f}};\n#endif\n   const spx_word16_t *den, *num;\n   if (filtID>4)\n      filtID=4;\n   \n   den = Pcoef[filtID]; num = Zcoef[filtID];\n   /*return;*/\n   for (i=0;i<len;i++)\n   {\n      spx_word16_t yi;\n      spx_word32_t vout = ADD32(MULT16_16(num[0], x[i]),mem[0]);\n      yi = EXTRACT16(SATURATE(PSHR32(vout,14),32767));\n      mem[0] = ADD32(MAC16_16(mem[1], num[1],x[i]), SHL32(MULT16_32_Q15(-den[1],vout),1));\n      mem[1] = ADD32(MULT16_16(num[2],x[i]), SHL32(MULT16_32_Q15(-den[2],vout),1));\n      y[i] = yi;\n   }\n}\n\n#ifdef FIXED_POINT\n\n/* FIXME: These functions are ugly and probably introduce too much error */\nvoid signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)\n{\n   int i;\n   for (i=0;i<len;i++)\n   {\n      y[i] = SHL32(MULT16_32_Q14(EXTRACT16(SHR32(x[i],7)),scale),7);\n   }\n}\n\nvoid signal_div(const spx_word16_t *x, spx_word16_t *y, spx_word32_t scale, int len)\n{\n   int i;\n   if (scale > SHL32(EXTEND32(SIG_SCALING), 8))\n   {\n      spx_word16_t scale_1;\n      scale = PSHR32(scale, SIG_SHIFT);\n      scale_1 = EXTRACT16(PDIV32_16(SHL32(EXTEND32(SIG_SCALING),7),scale));\n      for (i=0;i<len;i++)\n      {\n         y[i] = MULT16_16_P15(scale_1, x[i]);\n      }\n   } else if (scale > SHR32(EXTEND32(SIG_SCALING), 2)) {\n      spx_word16_t scale_1;\n      scale = PSHR32(scale, SIG_SHIFT-5);\n      scale_1 = DIV32_16(SHL32(EXTEND32(SIG_SCALING),3),scale);\n      for (i=0;i<len;i++)\n      {\n         y[i] = PSHR32(MULT16_16(scale_1, SHL16(x[i],2)),8);\n      }\n   } else {\n      spx_word16_t scale_1;\n      scale = PSHR32(scale, SIG_SHIFT-7);\n      if (scale < 5)\n         scale = 5;\n      scale_1 = DIV32_16(SHL32(EXTEND32(SIG_SCALING),3),scale);\n      for (i=0;i<len;i++)\n      {\n         y[i] = PSHR32(MULT16_16(scale_1, SHL16(x[i],2)),6);\n      }\n   }\n}\n\n#else\n\nvoid signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)\n{\n   int i;\n   for (i=0;i<len;i++)\n      y[i] = scale*x[i];\n}\n\nvoid signal_div(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)\n{\n   int i;\n   float scale_1 = 1/scale;\n   for (i=0;i<len;i++)\n      y[i] = scale_1*x[i];\n}\n#endif\n\n\n\n#ifdef FIXED_POINT\n\n\n\nspx_word16_t compute_rms(const spx_sig_t *x, int len)\n{\n   int i;\n   spx_word32_t sum=0;\n   spx_sig_t max_val=1;\n   int sig_shift;\n\n   for (i=0;i<len;i++)\n   {\n      spx_sig_t tmp = x[i];\n      if (tmp<0)\n         tmp = -tmp;\n      if (tmp > max_val)\n         max_val = tmp;\n   }\n\n   sig_shift=0;\n   while (max_val>16383)\n   {\n      sig_shift++;\n      max_val >>= 1;\n   }\n\n   for (i=0;i<len;i+=4)\n   {\n      spx_word32_t sum2=0;\n      spx_word16_t tmp;\n      tmp = EXTRACT16(SHR32(x[i],sig_shift));\n      sum2 = MAC16_16(sum2,tmp,tmp);\n      tmp = EXTRACT16(SHR32(x[i+1],sig_shift));\n      sum2 = MAC16_16(sum2,tmp,tmp);\n      tmp = EXTRACT16(SHR32(x[i+2],sig_shift));\n      sum2 = MAC16_16(sum2,tmp,tmp);\n      tmp = EXTRACT16(SHR32(x[i+3],sig_shift));\n      sum2 = MAC16_16(sum2,tmp,tmp);\n      sum = ADD32(sum,SHR32(sum2,6));\n   }\n   \n   return EXTRACT16(PSHR32(SHL32(EXTEND32(spx_sqrt(DIV32(sum,len))),(sig_shift+3)),SIG_SHIFT));\n}\n\nspx_word16_t compute_rms16(const spx_word16_t *x, int len)\n{\n   int i;\n   spx_word16_t max_val=10; \n\n   for (i=0;i<len;i++)\n   {\n      spx_sig_t tmp = x[i];\n      if (tmp<0)\n         tmp = -tmp;\n      if (tmp > max_val)\n         max_val = tmp;\n   }\n   if (max_val>16383)\n   {\n      spx_word32_t sum=0;\n      for (i=0;i<len;i+=4)\n      {\n         spx_word32_t sum2=0;\n         sum2 = MAC16_16(sum2,SHR16(x[i],1),SHR16(x[i],1));\n         sum2 = MAC16_16(sum2,SHR16(x[i+1],1),SHR16(x[i+1],1));\n         sum2 = MAC16_16(sum2,SHR16(x[i+2],1),SHR16(x[i+2],1));\n         sum2 = MAC16_16(sum2,SHR16(x[i+3],1),SHR16(x[i+3],1));\n         sum = ADD32(sum,SHR32(sum2,6));\n      }\n      return SHL16(spx_sqrt(DIV32(sum,len)),4);\n   } else {\n      spx_word32_t sum=0;\n      int sig_shift=0;\n      if (max_val < 8192)\n         sig_shift=1;\n      if (max_val < 4096)\n         sig_shift=2;\n      if (max_val < 2048)\n         sig_shift=3;\n      for (i=0;i<len;i+=4)\n      {\n         spx_word32_t sum2=0;\n         sum2 = MAC16_16(sum2,SHL16(x[i],sig_shift),SHL16(x[i],sig_shift));\n         sum2 = MAC16_16(sum2,SHL16(x[i+1],sig_shift),SHL16(x[i+1],sig_shift));\n         sum2 = MAC16_16(sum2,SHL16(x[i+2],sig_shift),SHL16(x[i+2],sig_shift));\n         sum2 = MAC16_16(sum2,SHL16(x[i+3],sig_shift),SHL16(x[i+3],sig_shift));\n         sum = ADD32(sum,SHR32(sum2,6));\n      }\n      return SHL16(spx_sqrt(DIV32(sum,len)),3-sig_shift);   \n   }\n}\n\n#ifndef OVERRIDE_NORMALIZE16\nint normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len)\n{\n   int i;\n   spx_sig_t max_val=1;\n   int sig_shift;\n   \n   for (i=0;i<len;i++)\n   {\n      spx_sig_t tmp = x[i];\n      if (tmp<0)\n         tmp = NEG32(tmp);\n      if (tmp >= max_val)\n         max_val = tmp;\n   }\n\n   sig_shift=0;\n   while (max_val>max_scale)\n   {\n      sig_shift++;\n      max_val >>= 1;\n   }\n\n   for (i=0;i<len;i++)\n      y[i] = EXTRACT16(SHR32(x[i], sig_shift));\n   \n   return sig_shift;\n}\n#endif\n\n#else\n\nspx_word16_t compute_rms(const spx_sig_t *x, int len)\n{\n   int i;\n   float sum=0;\n   for (i=0;i<len;i++)\n   {\n      sum += x[i]*x[i];\n   }\n   return sqrt(.1+sum/len);\n}\nspx_word16_t compute_rms16(const spx_word16_t *x, int len)\n{\n   return compute_rms(x, len);\n}\n#endif\n\n\n\n#ifndef OVERRIDE_FILTER_MEM16\nvoid filter_mem16(const spx_word16_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)\n{\n   int i,j;\n   spx_word16_t xi,yi,nyi;\n   for (i=0;i<N;i++)\n   {\n      xi= x[i];\n      yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767));\n      nyi = NEG16(yi);\n      for (j=0;j<ord-1;j++)\n      {\n         mem[j] = MAC16_16(MAC16_16(mem[j+1], num[j],xi), den[j],nyi);\n      }\n      mem[ord-1] = ADD32(MULT16_16(num[ord-1],xi), MULT16_16(den[ord-1],nyi));\n      y[i] = yi;\n   }\n}\n#endif\n\n#ifndef OVERRIDE_IIR_MEM16\nvoid iir_mem16(const spx_word16_t *x, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)\n{\n   int i,j;\n   spx_word16_t yi,nyi;\n\n   for (i=0;i<N;i++)\n   {\n      yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767));\n      nyi = NEG16(yi);\n      for (j=0;j<ord-1;j++)\n      {\n         mem[j] = MAC16_16(mem[j+1],den[j],nyi);\n      }\n      mem[ord-1] = MULT16_16(den[ord-1],nyi);\n      y[i] = yi;\n   }\n}\n#endif\n\n#ifndef OVERRIDE_FIR_MEM16\nvoid fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)\n{\n   int i,j;\n   spx_word16_t xi,yi;\n\n   for (i=0;i<N;i++)\n   {\n      xi=x[i];\n      yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767));\n      for (j=0;j<ord-1;j++)\n      {\n         mem[j] = MAC16_16(mem[j+1], num[j],xi);\n      }\n      mem[ord-1] = MULT16_16(num[ord-1],xi);\n      y[i] = yi;\n   }\n}\n#endif\n\n\nvoid syn_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)\n{\n   int i;\n   VARDECL(spx_mem_t *mem);\n   ALLOC(mem, ord, spx_mem_t);\n   for (i=0;i<ord;i++)\n      mem[i]=0;\n   iir_mem16(xx, ak, y, N, ord, mem, stack);\n   for (i=0;i<ord;i++)\n      mem[i]=0;\n   filter_mem16(y, awk1, awk2, y, N, ord, mem, stack);\n}\nvoid residue_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)\n{\n   int i;\n   VARDECL(spx_mem_t *mem);\n   ALLOC(mem, ord, spx_mem_t);\n   for (i=0;i<ord;i++)\n      mem[i]=0;\n   filter_mem16(xx, ak, awk1, y, N, ord, mem, stack);\n   for (i=0;i<ord;i++)\n      mem[i]=0;\n   fir_mem16(y, awk2, y, N, ord, mem, stack);\n}\n\n\n#ifndef OVERRIDE_COMPUTE_IMPULSE_RESPONSE\nvoid compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)\n{\n   int i,j;\n   spx_word16_t y1, ny1i, ny2i;\n   VARDECL(spx_mem_t *mem1);\n   VARDECL(spx_mem_t *mem2);\n   ALLOC(mem1, ord, spx_mem_t);\n   ALLOC(mem2, ord, spx_mem_t);\n   \n   y[0] = LPC_SCALING;\n   for (i=0;i<ord;i++)\n      y[i+1] = awk1[i];\n   i++;\n   for (;i<N;i++)\n      y[i] = VERY_SMALL;\n   for (i=0;i<ord;i++)\n      mem1[i] = mem2[i] = 0;\n   for (i=0;i<N;i++)\n   {\n      y1 = ADD16(y[i], EXTRACT16(PSHR32(mem1[0],LPC_SHIFT)));\n      ny1i = NEG16(y1);\n      y[i] = PSHR32(ADD32(SHL32(EXTEND32(y1),LPC_SHIFT+1),mem2[0]),LPC_SHIFT);\n      ny2i = NEG16(y[i]);\n      for (j=0;j<ord-1;j++)\n      {\n         mem1[j] = MAC16_16(mem1[j+1], awk2[j],ny1i);\n         mem2[j] = MAC16_16(mem2[j+1], ak[j],ny2i);\n      }\n      mem1[ord-1] = MULT16_16(awk2[ord-1],ny1i);\n      mem2[ord-1] = MULT16_16(ak[ord-1],ny2i);\n   }\n}\n#endif\n\n/* Decomposes a signal into low-band and high-band using a QMF */\nvoid qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *y1, spx_word16_t *y2, int N, int M, spx_word16_t *mem, char *stack)\n{\n   int i,j,k,M2;\n   VARDECL(spx_word16_t *a);\n   VARDECL(spx_word16_t *x);\n   spx_word16_t *x2;\n   \n   ALLOC(a, M, spx_word16_t);\n   ALLOC(x, N+M-1, spx_word16_t);\n   x2=x+M-1;\n   M2=M>>1;\n   for (i=0;i<M;i++)\n      a[M-i-1]= aa[i];\n   for (i=0;i<M-1;i++)\n      x[i]=mem[M-i-2];\n   for (i=0;i<N;i++)\n      x[i+M-1]=SHR16(xx[i],1);\n   for (i=0;i<M-1;i++)\n      mem[i]=SHR16(xx[N-i-1],1);\n   for (i=0,k=0;i<N;i+=2,k++)\n   {\n      spx_word32_t y1k=0, y2k=0;\n      for (j=0;j<M2;j++)\n      {\n         y1k=ADD32(y1k,MULT16_16(a[j],ADD16(x[i+j],x2[i-j])));\n         y2k=SUB32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j])));\n         j++;\n         y1k=ADD32(y1k,MULT16_16(a[j],ADD16(x[i+j],x2[i-j])));\n         y2k=ADD32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j])));\n      }\n      y1[k] = EXTRACT16(SATURATE(PSHR32(y1k,15),32767));\n      y2[k] = EXTRACT16(SATURATE(PSHR32(y2k,15),32767));\n   }\n}\n\n/* Re-synthesised a signal from the QMF low-band and high-band signals */\nvoid qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word16_t *mem1, spx_word16_t *mem2, char *stack)\n   /* assumptions:\n      all odd x[i] are zero -- well, actually they are left out of the array now\n      N and M are multiples of 4 */\n{\n   int i, j;\n   int M2, N2;\n   VARDECL(spx_word16_t *xx1);\n   VARDECL(spx_word16_t *xx2);\n   \n   M2 = M>>1;\n   N2 = N>>1;\n   ALLOC(xx1, M2+N2, spx_word16_t);\n   ALLOC(xx2, M2+N2, spx_word16_t);\n\n   for (i = 0; i < N2; i++)\n      xx1[i] = x1[N2-1-i];\n   for (i = 0; i < M2; i++)\n      xx1[N2+i] = mem1[2*i+1];\n   for (i = 0; i < N2; i++)\n      xx2[i] = x2[N2-1-i];\n   for (i = 0; i < M2; i++)\n      xx2[N2+i] = mem2[2*i+1];\n\n   for (i = 0; i < N2; i += 2) {\n      spx_sig_t y0, y1, y2, y3;\n      spx_word16_t x10, x20;\n\n      y0 = y1 = y2 = y3 = 0;\n      x10 = xx1[N2-2-i];\n      x20 = xx2[N2-2-i];\n\n      for (j = 0; j < M2; j += 2) {\n         spx_word16_t x11, x21;\n         spx_word16_t a0, a1;\n\n         a0 = a[2*j];\n         a1 = a[2*j+1];\n         x11 = xx1[N2-1+j-i];\n         x21 = xx2[N2-1+j-i];\n\n#ifdef FIXED_POINT\n         /* We multiply twice by the same coef to avoid overflows */\n         y0 = MAC16_16(MAC16_16(y0, a0, x11), NEG16(a0), x21);\n         y1 = MAC16_16(MAC16_16(y1, a1, x11), a1, x21);\n         y2 = MAC16_16(MAC16_16(y2, a0, x10), NEG16(a0), x20);\n         y3 = MAC16_16(MAC16_16(y3, a1, x10), a1, x20);\n#else\n         y0 = ADD32(y0,MULT16_16(a0, x11-x21));\n         y1 = ADD32(y1,MULT16_16(a1, x11+x21));\n         y2 = ADD32(y2,MULT16_16(a0, x10-x20));\n         y3 = ADD32(y3,MULT16_16(a1, x10+x20));\n#endif\n         a0 = a[2*j+2];\n         a1 = a[2*j+3];\n         x10 = xx1[N2+j-i];\n         x20 = xx2[N2+j-i];\n\n#ifdef FIXED_POINT\n         /* We multiply twice by the same coef to avoid overflows */\n         y0 = MAC16_16(MAC16_16(y0, a0, x10), NEG16(a0), x20);\n         y1 = MAC16_16(MAC16_16(y1, a1, x10), a1, x20);\n         y2 = MAC16_16(MAC16_16(y2, a0, x11), NEG16(a0), x21);\n         y3 = MAC16_16(MAC16_16(y3, a1, x11), a1, x21);\n#else\n         y0 = ADD32(y0,MULT16_16(a0, x10-x20));\n         y1 = ADD32(y1,MULT16_16(a1, x10+x20));\n         y2 = ADD32(y2,MULT16_16(a0, x11-x21));\n         y3 = ADD32(y3,MULT16_16(a1, x11+x21));\n#endif\n      }\n#ifdef FIXED_POINT\n      y[2*i] = EXTRACT16(SATURATE32(PSHR32(y0,15),32767));\n      y[2*i+1] = EXTRACT16(SATURATE32(PSHR32(y1,15),32767));\n      y[2*i+2] = EXTRACT16(SATURATE32(PSHR32(y2,15),32767));\n      y[2*i+3] = EXTRACT16(SATURATE32(PSHR32(y3,15),32767));\n#else\n      /* Normalize up explicitly if we're in float */\n      y[2*i] = 2.f*y0;\n      y[2*i+1] = 2.f*y1;\n      y[2*i+2] = 2.f*y2;\n      y[2*i+3] = 2.f*y3;\n#endif\n   }\n\n   for (i = 0; i < M2; i++)\n      mem1[2*i+1] = xx1[i];\n   for (i = 0; i < M2; i++)\n      mem2[2*i+1] = xx2[i];\n}\n\n#ifdef FIXED_POINT\n#if 0\nconst spx_word16_t shift_filt[3][7] = {{-33,    1043,   -4551,   19959,   19959,   -4551,    1043},\n                                 {-98,    1133,   -4425,   29179,    8895,   -2328,     444},\n                                 {444,   -2328,    8895,   29179,   -4425,    1133,     -98}};\n#else\nconst spx_word16_t shift_filt[3][7] = {{-390,    1540,   -4993,   20123,   20123,   -4993,    1540},\n                                {-1064,    2817,   -6694,   31589,    6837,    -990,    -209},\n                                 {-209,    -990,    6837,   31589,   -6694,    2817,   -1064}};\n#endif\n#else\n#if 0\nconst float shift_filt[3][7] = {{-9.9369e-04, 3.1831e-02, -1.3889e-01, 6.0910e-01, 6.0910e-01, -1.3889e-01, 3.1831e-02},\n                          {-0.0029937, 0.0345613, -0.1350474, 0.8904793, 0.2714479, -0.0710304, 0.0135403},\n                          {0.0135403, -0.0710304, 0.2714479, 0.8904793, -0.1350474, 0.0345613,  -0.0029937}};\n#else\nconst float shift_filt[3][7] = {{-0.011915f, 0.046995f, -0.152373f, 0.614108f, 0.614108f, -0.152373f, 0.046995f},\n                          {-0.0324855f, 0.0859768f, -0.2042986f, 0.9640297f, 0.2086420f, -0.0302054f, -0.0063646f},\n                          {-0.0063646f, -0.0302054f, 0.2086420f, 0.9640297f, -0.2042986f, 0.0859768f, -0.0324855f}};\n#endif\n#endif\n\nint interp_pitch(\nspx_word16_t *exc,          /*decoded excitation*/\nspx_word16_t *interp,          /*decoded excitation*/\nint pitch,               /*pitch period*/\nint len\n)\n{\n   int i,j,k;\n   spx_word32_t corr[4][7];\n   spx_word32_t maxcorr;\n   int maxi, maxj;\n   for (i=0;i<7;i++)\n   {\n      corr[0][i] = inner_prod(exc, exc-pitch-3+i, len);\n   }\n   for (i=0;i<3;i++)\n   {\n      for (j=0;j<7;j++)\n      {\n         int i1, i2;\n         spx_word32_t tmp=0;\n         i1 = 3-j;\n         if (i1<0)\n            i1 = 0;\n         i2 = 10-j;\n         if (i2>7)\n            i2 = 7;\n         for (k=i1;k<i2;k++)\n            tmp += MULT16_32_Q15(shift_filt[i][k],corr[0][j+k-3]);\n         corr[i+1][j] = tmp;\n      }\n   }\n   maxi=maxj=0;\n   maxcorr = corr[0][0];\n   for (i=0;i<4;i++)\n   {\n      for (j=0;j<7;j++)\n      {\n         if (corr[i][j] > maxcorr)\n         {\n            maxcorr = corr[i][j];\n            maxi=i;\n            maxj=j;\n         }\n      }\n   }\n   for (i=0;i<len;i++)\n   {\n      spx_word32_t tmp = 0;\n      if (maxi>0)\n      {\n         for (k=0;k<7;k++)\n         {\n            tmp += MULT16_16(exc[i-(pitch-maxj+3)+k-3],shift_filt[maxi-1][k]);\n         }\n      } else {\n         tmp = SHL32(exc[i-(pitch-maxj+3)],15);\n      }\n      interp[i] = PSHR32(tmp,15);\n   }\n   return pitch-maxj+3;\n}\n\nvoid multicomb(\nspx_word16_t *exc,          /*decoded excitation*/\nspx_word16_t *new_exc,      /*enhanced excitation*/\nspx_coef_t *ak,           /*LPC filter coefs*/\nint p,               /*LPC order*/\nint nsf,             /*sub-frame size*/\nint pitch,           /*pitch period*/\nint max_pitch,\nspx_word16_t  comb_gain,    /*gain of comb filter*/\nchar *stack\n)\n{\n   int i; \n   VARDECL(spx_word16_t *iexc);\n   spx_word16_t old_ener, new_ener;\n   int corr_pitch;\n   \n   spx_word16_t iexc0_mag, iexc1_mag, exc_mag;\n   spx_word32_t corr0, corr1;\n   spx_word16_t gain0, gain1;\n   spx_word16_t pgain1, pgain2;\n   spx_word16_t c1, c2;\n   spx_word16_t g1, g2;\n   spx_word16_t ngain;\n   spx_word16_t gg1, gg2;\n#ifdef FIXED_POINT\n   int scaledown=0;\n#endif\n#if 0 /* Set to 1 to enable full pitch search */\n   int nol_pitch[6];\n   spx_word16_t nol_pitch_coef[6];\n   spx_word16_t ol_pitch_coef;\n   open_loop_nbest_pitch(exc, 20, 120, nsf, \n                         nol_pitch, nol_pitch_coef, 6, stack);\n   corr_pitch=nol_pitch[0];\n   ol_pitch_coef = nol_pitch_coef[0];\n   /*Try to remove pitch multiples*/\n   for (i=1;i<6;i++)\n   {\n#ifdef FIXED_POINT\n      if ((nol_pitch_coef[i]>MULT16_16_Q15(nol_pitch_coef[0],19661)) && \n#else\n      if ((nol_pitch_coef[i]>.6*nol_pitch_coef[0]) && \n#endif\n         (ABS(2*nol_pitch[i]-corr_pitch)<=2 || ABS(3*nol_pitch[i]-corr_pitch)<=3 || \n         ABS(4*nol_pitch[i]-corr_pitch)<=4 || ABS(5*nol_pitch[i]-corr_pitch)<=5))\n      {\n         corr_pitch = nol_pitch[i];\n      }\n   }\n#else\n   corr_pitch = pitch;\n#endif\n   \n   ALLOC(iexc, 2*nsf, spx_word16_t);\n   \n   interp_pitch(exc, iexc, corr_pitch, 80);\n   if (corr_pitch>max_pitch)\n      interp_pitch(exc, iexc+nsf, 2*corr_pitch, 80);\n   else\n      interp_pitch(exc, iexc+nsf, -corr_pitch, 80);\n\n#ifdef FIXED_POINT\n   for (i=0;i<nsf;i++)\n   {\n      if (ABS16(exc[i])>16383)\n      {\n         scaledown = 1;\n         break;\n      }\n   }\n   if (scaledown)\n   {\n      for (i=0;i<nsf;i++)\n         exc[i] = SHR16(exc[i],1);\n      for (i=0;i<2*nsf;i++)\n         iexc[i] = SHR16(iexc[i],1);\n   }\n#endif\n   /*interp_pitch(exc, iexc+2*nsf, 2*corr_pitch, 80);*/\n   \n   /*printf (\"%d %d %f\\n\", pitch, corr_pitch, max_corr*ener_1);*/\n   iexc0_mag = spx_sqrt(1000+inner_prod(iexc,iexc,nsf));\n   iexc1_mag = spx_sqrt(1000+inner_prod(iexc+nsf,iexc+nsf,nsf));\n   exc_mag = spx_sqrt(1+inner_prod(exc,exc,nsf));\n   corr0  = inner_prod(iexc,exc,nsf);\n   if (corr0<0)\n      corr0=0;\n   corr1 = inner_prod(iexc+nsf,exc,nsf);\n   if (corr1<0)\n      corr1=0;\n#ifdef FIXED_POINT\n   /* Doesn't cost much to limit the ratio and it makes the rest easier */\n   if (SHL32(EXTEND32(iexc0_mag),6) < EXTEND32(exc_mag))\n      iexc0_mag = ADD16(1,PSHR16(exc_mag,6));\n   if (SHL32(EXTEND32(iexc1_mag),6) < EXTEND32(exc_mag))\n      iexc1_mag = ADD16(1,PSHR16(exc_mag,6));\n#endif\n   if (corr0 > MULT16_16(iexc0_mag,exc_mag))\n      pgain1 = QCONST16(1., 14);\n   else\n      pgain1 = PDIV32_16(SHL32(PDIV32(corr0, exc_mag),14),iexc0_mag);\n   if (corr1 > MULT16_16(iexc1_mag,exc_mag))\n      pgain2 = QCONST16(1., 14);\n   else\n      pgain2 = PDIV32_16(SHL32(PDIV32(corr1, exc_mag),14),iexc1_mag);\n   gg1 = PDIV32_16(SHL32(EXTEND32(exc_mag),8), iexc0_mag);\n   gg2 = PDIV32_16(SHL32(EXTEND32(exc_mag),8), iexc1_mag);\n   if (comb_gain>0)\n   {\n#ifdef FIXED_POINT\n      c1 = (MULT16_16_Q15(QCONST16(.4,15),comb_gain)+QCONST16(.07,15));\n      c2 = QCONST16(.5,15)+MULT16_16_Q14(QCONST16(1.72,14),(c1-QCONST16(.07,15)));\n#else\n      c1 = .4*comb_gain+.07;\n      c2 = .5+1.72*(c1-.07);\n#endif\n   } else \n   {\n      c1=c2=0;\n   }\n#ifdef FIXED_POINT\n   g1 = 32767 - MULT16_16_Q13(MULT16_16_Q15(c2, pgain1),pgain1);\n   g2 = 32767 - MULT16_16_Q13(MULT16_16_Q15(c2, pgain2),pgain2);\n#else\n   g1 = 1-c2*pgain1*pgain1;\n   g2 = 1-c2*pgain2*pgain2;\n#endif\n   if (g1<c1)\n      g1 = c1;\n   if (g2<c1)\n      g2 = c1;\n   g1 = (spx_word16_t)PDIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g1);\n   g2 = (spx_word16_t)PDIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g2);\n   if (corr_pitch>max_pitch)\n   {\n      gain0 = MULT16_16_Q15(QCONST16(.7,15),MULT16_16_Q14(g1,gg1));\n      gain1 = MULT16_16_Q15(QCONST16(.3,15),MULT16_16_Q14(g2,gg2));\n   } else {\n      gain0 = MULT16_16_Q15(QCONST16(.6,15),MULT16_16_Q14(g1,gg1));\n      gain1 = MULT16_16_Q15(QCONST16(.6,15),MULT16_16_Q14(g2,gg2));\n   }\n   for (i=0;i<nsf;i++)\n      new_exc[i] = ADD16(exc[i], EXTRACT16(PSHR32(ADD32(MULT16_16(gain0,iexc[i]), MULT16_16(gain1,iexc[i+nsf])),8)));\n   /* FIXME: compute_rms16 is currently not quite accurate enough (but close) */\n   new_ener = compute_rms16(new_exc, nsf);\n   old_ener = compute_rms16(exc, nsf);\n   \n   if (old_ener < 1)\n      old_ener = 1;\n   if (new_ener < 1)\n      new_ener = 1;\n   if (old_ener > new_ener)\n      old_ener = new_ener;\n   ngain = PDIV32_16(SHL32(EXTEND32(old_ener),14),new_ener);\n   \n   for (i=0;i<nsf;i++)\n      new_exc[i] = MULT16_16_Q14(ngain, new_exc[i]);\n#ifdef FIXED_POINT\n   if (scaledown)\n   {\n      for (i=0;i<nsf;i++)\n         exc[i] = SHL16(exc[i],1);\n      for (i=0;i<nsf;i++)\n         new_exc[i] = SHL16(SATURATE16(new_exc[i],16383),1);\n   }\n#endif\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/filters.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin */\n/**\n   @file filters.h\n   @brief Various analysis/synthesis filters\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef FILTERS_H\n#define FILTERS_H\n\n#include \"arch.h\"\n\nspx_word16_t compute_rms(const spx_sig_t *x, int len);\nspx_word16_t compute_rms16(const spx_word16_t *x, int len);\nvoid signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len);\nvoid signal_div(const spx_word16_t *x, spx_word16_t *y, spx_word32_t scale, int len);\n\n#ifdef FIXED_POINT\n\nint normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len);\n\n#endif\n\n\n#define HIGHPASS_NARROWBAND 0\n#define HIGHPASS_WIDEBAND 2\n#define HIGHPASS_INPUT 0\n#define HIGHPASS_OUTPUT 1\n#define HIGHPASS_IRS 4\n\nvoid highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem);\n\n\nvoid qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *, spx_word16_t *y2, int N, int M, spx_word16_t *mem, char *stack);\nvoid qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word16_t *mem1, spx_word16_t *mem2, char *stack);\n\nvoid filter_mem16(const spx_word16_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack);\nvoid iir_mem16(const spx_word16_t *x, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack);\nvoid fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack);\n\n/* Apply bandwidth expansion on LPC coef */\nvoid bw_lpc(spx_word16_t , const spx_coef_t *lpc_in, spx_coef_t *lpc_out, int order);\nvoid sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max_val, int len);\n\n\nvoid syn_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);\nvoid residue_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);\n\nvoid compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);\n\nvoid multicomb(\nspx_word16_t *exc,          /*decoded excitation*/\nspx_word16_t *new_exc,      /*enhanced excitation*/\nspx_coef_t *ak,           /*LPC filter coefs*/\nint p,               /*LPC order*/\nint nsf,             /*sub-frame size*/\nint pitch,           /*pitch period*/\nint max_pitch,   /*pitch gain (3-tap)*/\nspx_word16_t  comb_gain,    /*gain of comb filter*/\nchar *stack\n);\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/filters_arm4.h",
    "content": "/* Copyright (C) 2004 Jean-Marc Valin */\n/**\n   @file filters_arm4.h\n   @brief Various analysis/synthesis filters (ARM4 version)\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#define OVERRIDE_NORMALIZE16\nint normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len)\n{\n   spx_sig_t max_val=1;\n   int sig_shift;\n   int dead1, dead2, dead3, dead4, dead5, dead6;\n\n   __asm__ __volatile__ (\n         \"\\tmov %1, #1 \\n\"\n         \"\\tmov %3, #0 \\n\"\n\n         \".normalize16loop1%=: \\n\"\n\n         \"\\tldr %4, [%0], #4 \\n\"\n         \"\\tcmps %4, %1 \\n\"\n         \"\\tmovgt %1, %4 \\n\"\n         \"\\tcmps %4, %3 \\n\"\n         \"\\tmovlt %3, %4 \\n\"\n\n         \"\\tsubs %2, %2, #1 \\n\"\n         \"\\tbne .normalize16loop1%=\\n\"\n\n         \"\\trsb %3, %3, #0 \\n\"\n         \"\\tcmp %1, %3 \\n\"\n         \"\\tmovlt %1, %3 \\n\"\n   : \"=r\" (dead1), \"=r\" (max_val), \"=r\" (dead3), \"=r\" (dead4),\n   \"=r\" (dead5), \"=r\" (dead6)\n   : \"0\" (x), \"2\" (len)\n   : \"cc\");\n\n   sig_shift=0;\n   while (max_val>max_scale)\n   {\n      sig_shift++;\n      max_val >>= 1;\n   }\n   \n   __asm__ __volatile__ (\n         \".normalize16loop%=: \\n\"\n\n         \"\\tldr %4, [%0], #4 \\n\"\n         \"\\tldr %5, [%0], #4 \\n\"\n         \"\\tmov %4, %4, asr %3 \\n\"\n         \"\\tstrh %4, [%1], #2 \\n\"\n         \"\\tldr %4, [%0], #4 \\n\"\n         \"\\tmov %5, %5, asr %3 \\n\"\n         \"\\tstrh %5, [%1], #2 \\n\"\n         \"\\tldr %5, [%0], #4 \\n\"\n         \"\\tmov %4, %4, asr %3 \\n\"\n         \"\\tstrh %4, [%1], #2 \\n\"\n         \"\\tsubs %2, %2, #1 \\n\"\n         \"\\tmov %5, %5, asr %3 \\n\"\n         \"\\tstrh %5, [%1], #2 \\n\"\n\n         \"\\tbgt .normalize16loop%=\\n\"\n   : \"=r\" (dead1), \"=r\" (dead2), \"=r\" (dead3), \"=r\" (dead4),\n   \"=r\" (dead5), \"=r\" (dead6)\n   : \"0\" (x), \"1\" (y), \"2\" (len>>2), \"3\" (sig_shift)\n   : \"cc\", \"memory\");\n   return sig_shift;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/filters_bfin.h",
    "content": "/* Copyright (C) 2005 Analog Devices */\n/**\n   @file filters_bfin.h\n   @brief Various analysis/synthesis filters (Blackfin version)\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#define OVERRIDE_NORMALIZE16\nint normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len)\n{\n   spx_sig_t max_val=1;\n   int sig_shift;\n   __asm__ \n   (\n   \"%0 = 0;\\n\\t\"\n   \"I0 = %1;\\n\\t\"\n   \"L0 = 0;\\n\\t\"\n   \"R1 = [I0++];\\n\\t\"\n   \"LOOP norm_max%= LC0 = %2;\\n\\t\"\n   \"LOOP_BEGIN norm_max%=;\\n\\t\"\n      \"R2 = ABS R1 || R1 = [I0++];\\n\\t\"\n      \"%0 = MAX(%0, R2);\\n\\t\"\n   \"LOOP_END norm_max%=;\\n\\t\"\n   : \"=&d\" (max_val)\n   : \"a\" (x), \"a\" (len)\n   : \"R1\", \"R2\"\n   );\n\n   sig_shift=0;\n   while (max_val>max_scale)\n   {\n      sig_shift++;\n      max_val >>= 1;\n   }\n\n   __asm__ __volatile__ \n   (\n   \"I0 = %0;\\n\\t\"\n   \"L0 = 0;\\n\\t\"\n   \"P1 = %1;\\n\\t\"\n   \"R0 = [I0++];\\n\\t\"\n   \"LOOP norm_shift%= LC0 = %3;\\n\\t\"\n   \"LOOP_BEGIN norm_shift%=;\\n\\t\"\n      \"R1 = ASHIFT R0 by %2.L || R0 = [I0++];\\n\\t\"\n      \"W[P1++] = R1;\\n\\t\"\n   \"LOOP_END norm_shift%=;\\n\\t\"\n   \"R1 = ASHIFT R0 by %2.L;\\n\\t\"\n   \"W[P1++] = R1;\\n\\t\"\n   : : \"a\" (x), \"a\" (y), \"d\" (-sig_shift), \"a\" (len-1)\n   : \"I0\", \"L0\", \"P1\", \"R0\", \"R1\", \"memory\"\n   );\n   return sig_shift;\n}\n\n\n\n#define OVERRIDE_FILTER_MEM16\nvoid filter_mem16(const spx_word16_t *_x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *_y, int N, int ord, spx_mem_t *mem, char *stack)\n{\n   VARDECL(spx_word32_t *xy2);\n   VARDECL(spx_word32_t *numden_a);\n   spx_word32_t *xy;\n   spx_word16_t *numden;\n   int i;\n\n   ALLOC(xy2, (N+1), spx_word32_t);\n   ALLOC(numden_a, (2*ord+2), spx_word32_t);\n   xy = xy2+1;  \n   numden = (spx_word16_t*) numden_a;\n\n   for (i=0;i<ord;i++)\n   {\n      numden[2*i] = num[i];\n      numden[2*i+1] = den[i];\n   }\n   __asm__ __volatile__\n   (\n   /* Register setup */\n   \"R0 = %5;\\n\\t\"      /*ord */\n   \n   \"P0 = %3;\\n\\t\"\n   \"I0 = P0;\\n\\t\"\n   \"B0 = P0;\\n\\t\" /* numden */\n   \"L0 = 0;\\n\\t\"\n      \n   \"P2 = %0;\\n\\t\" /* Fused xy */\n   \"I2 = P2;\\n\\t\"\n   \"L2 = 0;\\n\\t\"\n   \n   \"P4 = %6;\\n\\t\" /* mem */\n   \"P0 = %1;\\n\\t\" /* _x */\n   \"P1 = %2;\\n\\t\" /* _y */\n   \n   /* First sample */\n   \"R1 = [P4++];\\n\\t\"\n   \"R1 <<= 3;\\n\\t\" /* shift mem */\n   \"R1.L = R1 (RND);\\n\\t\"\n   \"R2 = W[P0++];\\n\\t\" /* load x[0] */\n   \"R1.L = R1.L + R2.L;\\n\\t\"\n   \"W[P1++] = R1;\\n\\t\" /* store y[0] */\n   \"R2 = PACK(R1.L, R2.L);\\n\\t\" /* pack x16 and y16 */\n   \"[P2] = R2;\\n\\t\"\n               \n   /* Samples 1 to ord-1 (using memory) */\n   \"R0 += -1;\\n\\t\"\n   \"R3 = 0;\\n\\t\"\n   \"LC0 = R0;\\n\\t\"\n   \"LOOP filter_start%= LC0;\\n\\t\"\n   \"LOOP_BEGIN filter_start%=;\\n\\t\"\n      \"R3 += 1;\\n\\t\"\n      \"LC1 = R3;\\n\\t\"\n      \n      \"R1 = [P4++];\\n\\t\"\n      \"A1 = R1;\\n\\t\"\n      \"A0 = 0;\\n\\t\"\n      \"I0 = B0;\\n\\t\"\n      \"I2 = P2;\\n\\t\"\n      \"P2 += 4;\\n\\t\"\n      \"R4 = [I0++] || R5 = [I2--];\\n\\t\"\n      \"LOOP filter_start_inner%= LC1;\\n\\t\"\n      \"LOOP_BEGIN filter_start_inner%=;\\n\\t\"\n         \"A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\\n\\t\"\n      \"LOOP_END filter_start_inner%=;\\n\\t\"\n      \"A0 += A1;\\n\\t\"\n      \"R4 = A0;\\n\\t\"\n      \"R4 <<= 3;\\n\\t\" /* shift mem */\n      \"R4.L = R4 (RND);\\n\\t\"\n      \"R2 = W[P0++];\\n\\t\" /* load x */\n      \"R4.L = R4.L + R2.L;\\n\\t\"\n      \"W[P1++] = R4;\\n\\t\" /* store y */\n      //\"R4 <<= 2;\\n\\t\"\n      //\"R2 <<= 2;\\n\\t\"\n      \"R2 = PACK(R4.L, R2.L);\\n\\t\" /* pack x16 and y16 */\n      \"[P2] = R2;\\n\\t\"\n\n   \"LOOP_END filter_start%=;\\n\\t\"\n\n   /* Samples ord to N*/   \n   \"R0 = %5;\\n\\t\"\n   \"R0 <<= 1;\\n\\t\"\n   \"I0 = B0;\\n\\t\" /* numden */\n   \"R0 <<= 1;\\n\\t\"   \n   \"L0 = R0;\\n\\t\"\n   \n   \"R0 = %5;\\n\\t\" /* org */\n   \"R2 = %4;\\n\\t\" /* N */\n   \"R2 = R2 - R0;\\n\\t\"\n   \"R4 = [I0++];\\n\\t\" /* numden */\n   \"LC0 = R2;\\n\\t\"\n   \"P3 = R0;\\n\\t\"\n   \"R0 <<= 2;\\n\\t\"\n   \"R0 += 8;\\n\\t\"\n   \"I2 = P2;\\n\\t\"\n   \"M0 = R0;\\n\\t\"\n   \"A1 = A0 = 0;\\n\\t\"\n   \"R5 = [I2--];\\n\\t\" /* load xy */\n   \"LOOP filter_mid%= LC0;\\n\\t\"\n   \"LOOP_BEGIN filter_mid%=;\\n\\t\"\n      \"LOOP filter_mid_inner%= LC1=P3;\\n\\t\"\n      \"LOOP_BEGIN filter_mid_inner%=;\\n\\t\"\n         \"A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\\n\\t\"\n      \"LOOP_END filter_mid_inner%=;\\n\\t\"\n      \"R0 = (A0 += A1) || I2 += M0;\\n\\t\"\n      \"R0 = R0 << 3 || R5 = W[P0++];\\n\\t\" /* load x */\n      \"R0.L = R0 (RND);\\n\\t\"\n      \"R0.L = R0.L + R5.L;\\n\\t\"\n      \"R5 = PACK(R0.L, R5.L) || W[P1++] = R0;\\n\\t\" /* shift y | store y */\n      \"A1 = A0 = 0 || [I2--] = R5\\n\\t\"\n      \"LOOP_END filter_mid%=;\\n\\t\"\n   \"I2 += 4;\\n\\t\"\n   \"P2 = I2;\\n\\t\"\n   /* Update memory */\n   \"P4 = %6;\\n\\t\"\n   \"R0 = %5;\\n\\t\"\n   \"LC0 = R0;\\n\\t\"\n   \"P0 = B0;\\n\\t\"\n   \"A1 = A0 = 0;\\n\\t\"\n   \"LOOP mem_update%= LC0;\\n\\t\"\n   \"LOOP_BEGIN mem_update%=;\\n\\t\"\n      \"I2 = P2;\\n\\t\"\n      \"I0 = P0;\\n\\t\"\n      \"P0 += 4;\\n\\t\"\n      \"R0 = LC0;\\n\\t\"\n      \"LC1 = R0;\\n\\t\"\n      \"R5 = [I2--] || R4 = [I0++];\\n\\t\"\n      \"LOOP mem_accum%= LC1;\\n\\t\"\n      \"LOOP_BEGIN mem_accum%=;\\n\\t\"\n         \"A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\\n\\t\"\n      \"LOOP_END mem_accum%=;\\n\\t\"\n      \"R0 = (A0 += A1);\\n\\t\"\n      \"A1 = A0 = 0 || [P4++] = R0;\\n\\t\"\n   \"LOOP_END mem_update%=;\\n\\t\"\n   \"L0 = 0;\\n\\t\"\n   : : \"m\" (xy), \"m\" (_x), \"m\" (_y), \"m\" (numden), \"m\" (N), \"m\" (ord), \"m\" (mem)\n   : \"A0\", \"A1\", \"R0\", \"R1\", \"R2\", \"R3\", \"R4\", \"R5\", \"P0\", \"P1\", \"P2\", \"P3\", \"P4\", \"B0\", \"I0\", \"I2\", \"L0\", \"L2\", \"M0\", \"memory\"\n   );\n\n}\n\n\n\n#define OVERRIDE_IIR_MEM16\nvoid iir_mem16(const spx_word16_t *_x, const spx_coef_t *den, spx_word16_t *_y, int N, int ord, spx_mem_t *mem, char *stack)\n{\n   VARDECL(spx_word16_t *y);\n   spx_word16_t *yy;\n\n   ALLOC(y, (N+2), spx_word16_t);\n   yy = y+2;\n\n   __asm__ __volatile__\n   (\n   /* Register setup */\n   \"R0 = %5;\\n\\t\"      /*ord */\n   \n   \"P1 = %3;\\n\\t\"\n   \"I1 = P1;\\n\\t\"\n   \"B1 = P1;\\n\\t\"\n   \"L1 = 0;\\n\\t\"\n   \n   \"P3 = %0;\\n\\t\"\n   \"I3 = P3;\\n\\t\"\n   \"L3 = 0;\\n\\t\"\n   \n   \"P4 = %6;\\n\\t\"\n   \"P0 = %1;\\n\\t\"\n   \"P1 = %2;\\n\\t\"\n   \n   /* First sample */\n   \"R1 = [P4++];\\n\\t\"\n   \"R1 = R1 << 3 (S);\\n\\t\"\n   \"R1.L = R1 (RND);\\n\\t\"\n   \"R2 = W[P0++];\\n\\t\"\n   \"R1 = R1 + R2;\\n\\t\"\n   \"W[P1++] = R1;\\n\\t\"\n   \"W[P3] = R1;\\n\\t\"\n\n   /* Samples 1 to ord-1 (using memory) */\n   \"R0 += -1;\\n\\t\"\n   \"R3 = 0;\\n\\t\"\n   \"LC0 = R0;\\n\\t\"\n   \"LOOP filter_start%= LC0;\\n\\t\"\n   \"LOOP_BEGIN filter_start%=;\\n\\t\"\n      \"R3 += 1;\\n\\t\"\n      \"LC1 = R3;\\n\\t\"\n      \n      \"R1 = [P4++];\\n\\t\"\n      \"A1 = R1;\\n\\t\"\n      \"I1 = B1;\\n\\t\"\n      \"I3 = P3;\\n\\t\"\n      \"P3 += 2;\\n\\t\"\n      \"LOOP filter_start_inner%= LC1;\\n\\t\"\n      \"LOOP_BEGIN filter_start_inner%=;\\n\\t\"\n         \"R4.L = W[I1++];\\n\\t\"\n         \"R5.L = W[I3--];\\n\\t\"\n         \"A1 -= R4.L*R5.L (IS);\\n\\t\"\n      \"LOOP_END filter_start_inner%=;\\n\\t\"\n   \n      \"R1 = A1;\\n\\t\"\n      \"R1 <<= 3;\\n\\t\"\n      \"R1.L = R1 (RND);\\n\\t\"\n      \"R2 = W[P0++];\\n\\t\"\n      \"R1 = R1 + R2;\\n\\t\"\n      \"W[P1++] = R1;\\n\\t\"\n      \"W[P3] = R1;\\n\\t\"\n   \"LOOP_END filter_start%=;\\n\\t\"\n\n   /* Samples ord to N*/   \n   \"R0 = %5;\\n\\t\"\n   \"R0 <<= 1;\\n\\t\"\n   \"I1 = B1;\\n\\t\"\n   \"L1 = R0;\\n\\t\"\n   \n   \"R0 = %5;\\n\\t\"\n   \"R2 = %4;\\n\\t\"\n   \"R2 = R2 - R0;\\n\\t\"\n   \"R4.L = W[I1++];\\n\\t\"\n   \"LC0 = R2;\\n\\t\"\n   \"LOOP filter_mid%= LC0;\\n\\t\"\n   \"LOOP_BEGIN filter_mid%=;\\n\\t\"\n      \"LC1 = R0;\\n\\t\"\n      \"A1 = 0;\\n\\t\"\n      \"I3 = P3;\\n\\t\"\n      \"P3 += 2;\\n\\t\"\n      \"R5.L = W[I3--];\\n\\t\"\n      \"LOOP filter_mid_inner%= LC1;\\n\\t\"\n      \"LOOP_BEGIN filter_mid_inner%=;\\n\\t\"\n         \"A1 -= R4.L*R5.L (IS) || R4.L = W[I1++] || R5.L = W[I3--];\\n\\t\"\n      \"LOOP_END filter_mid_inner%=;\\n\\t\"\n      \"R1 = A1;\\n\\t\"\n      \"R1 = R1 << 3 || R2 = W[P0++];\\n\\t\"\n      \"R1.L = R1 (RND);\\n\\t\"\n      \"R1 = R1 + R2;\\n\\t\"\n      \"W[P1++] = R1;\\n\\t\"\n      \"W[P3] = R1;\\n\\t\"\n   \"LOOP_END filter_mid%=;\\n\\t\"\n     \n   /* Update memory */\n   \"P4 = %6;\\n\\t\"\n   \"R0 = %5;\\n\\t\"\n   \"LC0 = R0;\\n\\t\"\n   \"P1 = B1;\\n\\t\"\n   \"LOOP mem_update%= LC0;\\n\\t\"\n   \"LOOP_BEGIN mem_update%=;\\n\\t\"\n      \"A0 = 0;\\n\\t\"\n      \"I3 = P3;\\n\\t\"\n      \"I1 = P1;\\n\\t\"\n      \"P1 += 2;\\n\\t\"\n      \"R0 = LC0;\\n\\t\"\n      \"LC1=R0;\\n\\t\"\n      \"R5.L = W[I3--] || R4.L = W[I1++];\\n\\t\"\n      \"LOOP mem_accum%= LC1;\\n\\t\"\n      \"LOOP_BEGIN mem_accum%=;\\n\\t\"\n         \"A0 -= R4.L*R5.L (IS) || R4.L = W[I1++] || R5.L = W[I3--];\\n\\t\"\n      \"LOOP_END mem_accum%=;\\n\\t\"\n      \"R0 = A0;\\n\\t\"\n      \"[P4++] = R0;\\n\\t\"\n   \"LOOP_END mem_update%=;\\n\\t\"\n   \"L1 = 0;\\n\\t\"\n   : : \"m\" (yy), \"m\" (_x), \"m\" (_y), \"m\" (den), \"m\" (N), \"m\" (ord), \"m\" (mem)\n   : \"A0\", \"A1\", \"R0\", \"R1\", \"R2\", \"R3\", \"R4\", \"R5\", \"P0\", \"P1\", \"P2\", \"P3\", \"P4\", \"B1\", \"I1\", \"I3\", \"L1\", \"L3\", \"memory\"\n   );\n\n}\n\n\n#define OVERRIDE_FIR_MEM16\nvoid fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)\n{\n   int i;\n   spx_coef_t den2[12];\n   spx_coef_t *den;\n   den = (spx_coef_t*)((((int)den2)+4)&0xfffffffc);\n   for (i=0;i<10;i++)\n      den[i] = 0;\n   filter_mem16(x, num, den, y, N, ord, mem, stack);\n}\n\n\n#define OVERRIDE_COMPUTE_IMPULSE_RESPONSE\nvoid compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)\n{\n   int i;\n   VARDECL(spx_word16_t *ytmp);\n   ALLOC(ytmp, N, spx_word16_t);\n   spx_word16_t *ytmp2 = ytmp;\n   y[0] = LPC_SCALING;\n   for (i=0;i<ord;i++)\n      y[i+1] = awk1[i];\n   i++;\n   for (;i<N;i++)\n      y[i] = 0;\n\n   N-=1;\n   __asm__ __volatile__\n   (\n         \"I0 = %0;\\n\\t\"\n         \"I1 = %1;\\n\\t\"\n         \"L0 = 0;\\n\\t\"\n         \"L1 = 0;\\n\\t\"\n         \"L2 = 0;\\n\\t\"\n         \"L3 = 0;\\n\\t\"\n         \"R0 = 1;\\n\\t\"\n         \"R0 <<= 13;\\n\\t\"\n         \"W[I0] = R0.L;\\n\\t\"\n         \"R0 <<= 1;\\n\\t\"\n         \"W[I1] = R0.L;\\n\\t\"\n         \"R0 = %5;\\n\\t\"\n         \"LC0 = R0;\\n\\t\"\n         \"R2 = 0;\\n\\t\"\n         \"LOOP samples%= LC0;\\n\\t\"\n         \"LOOP_BEGIN samples%=;\\n\\t\"\n            \"R2 += 1;\\n\\t\"\n            \"R2 = MIN(R2, %4);\\n\\t\"\n            \"I0 = %0;\\n\\t\"\n            \"I1 = %1;\\n\\t\"\n            \"I2 = %2;\\n\\t\"\n            \"I3 = %3;\\n\\t\"\n            \"%0 += 2;\\n\\t\"\n            \"%1 += 2;\\n\\t\"\n            \"A1 = A0 = 0;\\n\\t\"\n            \"R0.L = W[I0--] || R1.L = W[I2++];\\n\\t\"\n            \"LC1 = R2;\\n\\t\"\n            \"LOOP filter%= LC1;\\n\\t\"\n            \"LOOP_BEGIN filter%=;\\n\\t\"\n               \"A0 -= R0.L*R1.L (IS) || R0.L = W[I1--] || R1.L = W[I3++];\\n\\t\"\n               \"A1 -= R0.L*R1.L (IS) || R0.L = W[I0--] || R1.L = W[I2++];\\n\\t\"\n            \"LOOP_END filter%=;\\n\\t\"\n            \"R0 = A0, R1 = A1;\\n\\t\"\n            \"R3 = W[%1] (X);\\n\\t\"\n            \"R3 <<= 13;\\n\\t\"\n            \"R0 = R0 + R3;\\n\\t\"\n            \"R3 = R0 >>> 13;\\n\\t\"\n            \"W[%0] = R3.L;\\n\\t\"\n            \"R0 <<= 1;\\n\\t\"\n            \"R1 = R1 + R0;\\n\\t\"\n            \"R1 >>>= 13;\\n\\t\"\n            \"W[%1] = R1.L;\\n\\t\"\n         \"LOOP_END samples%=;\\n\\t\"\n   : \"=a\" (ytmp2), \"=a\" (y)\n   : \"a\" (awk2), \"a\" (ak), \"d\" (ord), \"m\" (N), \"0\" (ytmp2), \"1\" (y)\n   : \"A0\", \"A1\", \"R0\", \"R1\", \"R2\", \"R3\", \"I0\", \"I1\", \"I2\", \"I3\", \"L0\", \"L1\", \"L2\", \"L3\", \"A0\", \"A1\"\n   );\n}\n\n\n\n#if 0 /* Equivalent C function for filter_mem2 and compute_impulse_response */\n#define min(a,b) ((a)<(b) ? (a):(b))\n\nvoid compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)\n{\n   int i,j;\n   VARDECL(spx_word16_t *ytmp);\n   ALLOC(ytmp, N, spx_word16_t);\n   \n   y[0] = LPC_SCALING;\n   for (i=0;i<ord;i++)\n      y[i+1] = awk1[i];\n   i++;\n   for (;i<N;i++)\n      y[i] = 0;\n\n   for (i=0;i<N;i++)\n   {\n      spx_word32_t yi = SHL32(EXTEND32(y[i]),LPC_SHIFT);\n      spx_word32_t yi2 = 0;\n      for (j=0;j<min(i,ord);j++)\n      {\n         yi = MAC16_16(yi, awk2[j], -ytmp[i-j-1]);\n         yi2 = MAC16_16(yi2, ak[j], -y[i-j-1]);\n      }\n      ytmp[i] = EXTRACT16(SHR32(yi,LPC_SHIFT));\n      yi2 = ADD32(yi2,SHL32(yi,1));\n      y[i] = EXTRACT16(SHR32(yi2,LPC_SHIFT));\n   }\n\n}\n\n\nvoid filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *_y, int N, int ord, spx_mem_t *mem)\n{\n   int i,j;\n   spx_word16_t xi,yi,nyi;\n   spx_word16_t x[N],y[N];\n   spx_word16_t *xx, *yy;\n   xx = x;\n   yy = y;\n   for (i=0;i<N;i++)\n   {\n      x[i] = EXTRACT16(SHR32(_x[i],SIG_SHIFT));\n   }\n   \n   for (i=0;i<ord;i++)\n   {\n      spx_word32_t yi = mem[i];\n      for (j=0;j<i;j++)\n      {\n         yi = MAC16_16(yi, num[j], x[i-j-1]);\n         yi = MAC16_16(yi, den[j], -y[i-j-1]);\n      }\n      _y[i] = ADD32(_x[i],SHL32(yi,1));\n      y[i] = EXTRACT16(SHR32(_y[i],SIG_SHIFT));\n   }\n   for (i=ord;i<N;i++)\n   {\n      spx_word32_t yi = 0;\n      for (j=0;j<ord;j++)\n      {\n         yi = MAC16_16(yi, num[j], x[i-j-1]);\n         yi = MAC16_16(yi, den[j], -y[i-j-1]);\n      }\n      _y[i] = ADD32(_x[i],SHL32(yi,1));\n      y[i] = EXTRACT16(SHR32(_y[i],SIG_SHIFT));\n   }\n\n   for (i=0;i<ord;i++)\n   {\n      spx_mem_t m = 0;\n      for (j=0;j<ord-i;j++)\n      {\n         m = MAC16_16(m, x[N-1-j], num[j+i]);\n         m = MAC16_16(m, -y[N-1-j], den[j+i]);\n      }\n      mem[i] = m;\n   }\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/filters_sse.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin */\n/**\n   @file filters_sse.h\n   @brief Various analysis/synthesis filters (SSE version)\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#include <xmmintrin.h>\n\nvoid filter_mem16_10(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)\n{\n   __m128 num[3], den[3], mem[3];\n\n   int i;\n\n   /* Copy numerator, denominator and memory to aligned xmm */\n   for (i=0;i<2;i++)\n   {\n      mem[i] = _mm_loadu_ps(_mem+4*i);\n      num[i] = _mm_loadu_ps(_num+4*i);\n      den[i] = _mm_loadu_ps(_den+4*i);\n   }\n   mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0);\n   num[2] = _mm_setr_ps(_num[8], _num[9], 0, 0);\n   den[2] = _mm_setr_ps(_den[8], _den[9], 0, 0);\n   \n   for (i=0;i<N;i++)\n   {\n      __m128 xx;\n      __m128 yy;\n      /* Compute next filter result */\n      xx = _mm_load_ps1(x+i);\n      yy = _mm_add_ss(xx, mem[0]);\n      _mm_store_ss(y+i, yy);\n      yy = _mm_shuffle_ps(yy, yy, 0);\n      \n      /* Update memory */\n      mem[0] = _mm_move_ss(mem[0], mem[1]);\n      mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);\n\n      mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));\n      mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));\n\n      mem[1] = _mm_move_ss(mem[1], mem[2]);\n      mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);\n\n      mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));\n      mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));\n\n      mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd);\n\n      mem[2] = _mm_add_ps(mem[2], _mm_mul_ps(xx, num[2]));\n      mem[2] = _mm_sub_ps(mem[2], _mm_mul_ps(yy, den[2]));\n   }\n   /* Put memory back in its place */\n   _mm_storeu_ps(_mem, mem[0]);\n   _mm_storeu_ps(_mem+4, mem[1]);\n   _mm_store_ss(_mem+8, mem[2]);\n   mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55);\n   _mm_store_ss(_mem+9, mem[2]);\n}\n\nvoid filter_mem16_8(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)\n{\n   __m128 num[2], den[2], mem[2];\n\n   int i;\n\n   /* Copy numerator, denominator and memory to aligned xmm */\n   for (i=0;i<2;i++)\n   {\n      mem[i] = _mm_loadu_ps(_mem+4*i);\n      num[i] = _mm_loadu_ps(_num+4*i);\n      den[i] = _mm_loadu_ps(_den+4*i);\n   }\n   \n   for (i=0;i<N;i++)\n   {\n      __m128 xx;\n      __m128 yy;\n      /* Compute next filter result */\n      xx = _mm_load_ps1(x+i);\n      yy = _mm_add_ss(xx, mem[0]);\n      _mm_store_ss(y+i, yy);\n      yy = _mm_shuffle_ps(yy, yy, 0);\n      \n      /* Update memory */\n      mem[0] = _mm_move_ss(mem[0], mem[1]);\n      mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);\n\n      mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));\n      mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));\n\n      mem[1] = _mm_sub_ss(mem[1], mem[1]);\n      mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);\n\n      mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));\n      mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));\n   }\n   /* Put memory back in its place */\n   _mm_storeu_ps(_mem, mem[0]);\n   _mm_storeu_ps(_mem+4, mem[1]);\n}\n\n\n#define OVERRIDE_FILTER_MEM16\nvoid filter_mem16(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem, char *stack)\n{\n   if(ord==10)\n      filter_mem16_10(x, _num, _den, y, N, ord, _mem);\n   else if (ord==8)\n      filter_mem16_8(x, _num, _den, y, N, ord, _mem);\n}\n\n\n\nvoid iir_mem16_10(const float *x, const float *_den, float *y, int N, int ord, float *_mem)\n{\n   __m128 den[3], mem[3];\n\n   int i;\n\n   /* Copy numerator, denominator and memory to aligned xmm */\n   for (i=0;i<2;i++)\n   {\n      mem[i] = _mm_loadu_ps(_mem+4*i);\n      den[i] = _mm_loadu_ps(_den+4*i);\n   }\n   mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0);\n   den[2] = _mm_setr_ps(_den[8], _den[9], 0, 0);\n   \n   for (i=0;i<N;i++)\n   {\n      __m128 xx;\n      __m128 yy;\n      /* Compute next filter result */\n      xx = _mm_load_ps1(x+i);\n      yy = _mm_add_ss(xx, mem[0]);\n      _mm_store_ss(y+i, yy);\n      yy = _mm_shuffle_ps(yy, yy, 0);\n      \n      /* Update memory */\n      mem[0] = _mm_move_ss(mem[0], mem[1]);\n      mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);\n\n      mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));\n\n      mem[1] = _mm_move_ss(mem[1], mem[2]);\n      mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);\n\n      mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));\n\n      mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd);\n\n      mem[2] = _mm_sub_ps(mem[2], _mm_mul_ps(yy, den[2]));\n   }\n   /* Put memory back in its place */\n   _mm_storeu_ps(_mem, mem[0]);\n   _mm_storeu_ps(_mem+4, mem[1]);\n   _mm_store_ss(_mem+8, mem[2]);\n   mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55);\n   _mm_store_ss(_mem+9, mem[2]);\n}\n\n\nvoid iir_mem16_8(const float *x, const float *_den, float *y, int N, int ord, float *_mem)\n{\n   __m128 den[2], mem[2];\n\n   int i;\n\n   /* Copy numerator, denominator and memory to aligned xmm */\n   for (i=0;i<2;i++)\n   {\n      mem[i] = _mm_loadu_ps(_mem+4*i);\n      den[i] = _mm_loadu_ps(_den+4*i);\n   }\n   \n   for (i=0;i<N;i++)\n   {\n      __m128 xx;\n      __m128 yy;\n      /* Compute next filter result */\n      xx = _mm_load_ps1(x+i);\n      yy = _mm_add_ss(xx, mem[0]);\n      _mm_store_ss(y+i, yy);\n      yy = _mm_shuffle_ps(yy, yy, 0);\n      \n      /* Update memory */\n      mem[0] = _mm_move_ss(mem[0], mem[1]);\n      mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);\n\n      mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));\n\n      mem[1] = _mm_sub_ss(mem[1], mem[1]);\n      mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);\n\n      mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));\n   }\n   /* Put memory back in its place */\n   _mm_storeu_ps(_mem, mem[0]);\n   _mm_storeu_ps(_mem+4, mem[1]);\n}\n\n#define OVERRIDE_IIR_MEM16\nvoid iir_mem16(const float *x, const float *_den, float *y, int N, int ord, float *_mem, char *stack)\n{\n   if(ord==10)\n      iir_mem16_10(x, _den, y, N, ord, _mem);\n   else if (ord==8)\n      iir_mem16_8(x, _den, y, N, ord, _mem);\n}\n\n\nvoid fir_mem16_10(const float *x, const float *_num, float *y, int N, int ord, float *_mem)\n{\n   __m128 num[3], mem[3];\n\n   int i;\n\n   /* Copy numerator, denominator and memory to aligned xmm */\n   for (i=0;i<2;i++)\n   {\n      mem[i] = _mm_loadu_ps(_mem+4*i);\n      num[i] = _mm_loadu_ps(_num+4*i);\n   }\n   mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0);\n   num[2] = _mm_setr_ps(_num[8], _num[9], 0, 0);\n   \n   for (i=0;i<N;i++)\n   {\n      __m128 xx;\n      __m128 yy;\n      /* Compute next filter result */\n      xx = _mm_load_ps1(x+i);\n      yy = _mm_add_ss(xx, mem[0]);\n      _mm_store_ss(y+i, yy);\n      yy = _mm_shuffle_ps(yy, yy, 0);\n      \n      /* Update memory */\n      mem[0] = _mm_move_ss(mem[0], mem[1]);\n      mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);\n\n      mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));\n\n      mem[1] = _mm_move_ss(mem[1], mem[2]);\n      mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);\n\n      mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));\n\n      mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd);\n\n      mem[2] = _mm_add_ps(mem[2], _mm_mul_ps(xx, num[2]));\n   }\n   /* Put memory back in its place */\n   _mm_storeu_ps(_mem, mem[0]);\n   _mm_storeu_ps(_mem+4, mem[1]);\n   _mm_store_ss(_mem+8, mem[2]);\n   mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55);\n   _mm_store_ss(_mem+9, mem[2]);\n}\n\nvoid fir_mem16_8(const float *x, const float *_num, float *y, int N, int ord, float *_mem)\n{\n   __m128 num[2], mem[2];\n\n   int i;\n\n   /* Copy numerator, denominator and memory to aligned xmm */\n   for (i=0;i<2;i++)\n   {\n      mem[i] = _mm_loadu_ps(_mem+4*i);\n      num[i] = _mm_loadu_ps(_num+4*i);\n   }\n   \n   for (i=0;i<N;i++)\n   {\n      __m128 xx;\n      __m128 yy;\n      /* Compute next filter result */\n      xx = _mm_load_ps1(x+i);\n      yy = _mm_add_ss(xx, mem[0]);\n      _mm_store_ss(y+i, yy);\n      yy = _mm_shuffle_ps(yy, yy, 0);\n      \n      /* Update memory */\n      mem[0] = _mm_move_ss(mem[0], mem[1]);\n      mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);\n\n      mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));\n\n      mem[1] = _mm_sub_ss(mem[1], mem[1]);\n      mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);\n\n      mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));\n   }\n   /* Put memory back in its place */\n   _mm_storeu_ps(_mem, mem[0]);\n   _mm_storeu_ps(_mem+4, mem[1]);\n}\n\n#define OVERRIDE_FIR_MEM16\nvoid fir_mem16(const float *x, const float *_num, float *y, int N, int ord, float *_mem, char *stack)\n{\n   if(ord==10)\n      fir_mem16_10(x, _num, y, N, ord, _mem);\n   else if (ord==8)\n      fir_mem16_8(x, _num, y, N, ord, _mem);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/fixed_arm4.h",
    "content": "/* Copyright (C) 2004 Jean-Marc Valin */\n/**\n   @file fixed_arm4.h\n   @brief ARM4 fixed-point operations\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef FIXED_ARM4_H\n#define FIXED_ARM4_H\n\n#undef MULT16_32_Q14\nstatic inline spx_word32_t MULT16_32_Q14(spx_word16_t x, spx_word32_t y) {\n  int res;\n  int dummy;\n  asm (\n        \"smull  %0,%1,%2,%3 \\n\\t\"\n        \"mov %0, %0, lsr #14 \\n\\t\"\n        \"add %0, %0, %1, lsl #18 \\n\\t\"\n   : \"=&r\"(res), \"=&r\" (dummy)\n   : \"r\"(y),\"r\"((int)x));\n  return(res);\n}\n\n#undef MULT16_32_Q15\nstatic inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) {\n  int res;\n  int dummy;\n  asm (\n        \"smull  %0,%1,%2,%3 \\n\\t\"\n        \"mov %0, %0, lsr #15 \\n\\t\"\n        \"add %0, %0, %1, lsl #17 \\n\\t\"\n   : \"=&r\"(res), \"=&r\" (dummy)\n   : \"r\"(y),\"r\"((int)x));\n  return(res);\n}\n\n#undef DIV32_16\nstatic inline short DIV32_16(int a, int b)\n{\n   int res=0;\n   int dead1, dead2, dead3, dead4, dead5;\n   __asm__ __volatile__ (\n         \"\\teor %5, %0, %1\\n\"\n         \"\\tmovs %4, %0\\n\"\n         \"\\trsbmi %0, %0, #0 \\n\"\n         \"\\tmovs %4, %1\\n\"\n         \"\\trsbmi %1, %1, #0 \\n\"\n         \"\\tmov %4, #1\\n\"\n\n         \"\\tsubs %3, %0, %1, asl #14 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #14 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #13 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #13 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #12 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #12 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #11 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #11 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #10 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #10 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #9 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #9 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #8 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #8 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #7 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #7 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #6 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #6 \\n\"\n         \n         \"\\tsubs %3, %0, %1, asl #5 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #5 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #4 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #4 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #3 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #2 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #2 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #1 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #1 \\n\"\n\n         \"\\tsubs %3, %0, %1 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \"\\torrpl %2, %2, %4 \\n\"\n\n         \"\\tmovs %5, %5, lsr #31 \\n\"\n         \"\\trsbne %2, %2, #0 \\n\"\n   : \"=r\" (dead1), \"=r\" (dead2), \"=r\" (res),\n   \"=r\" (dead3), \"=r\" (dead4), \"=r\" (dead5)\n   : \"0\" (a), \"1\" (b), \"2\" (res)\n   : \"cc\"\n                        );\n   return res;\n}\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/fixed_arm5e.h",
    "content": "/* Copyright (C) 2003 Jean-Marc Valin */\n/**\n   @file fixed_arm5e.h\n   @brief ARM-tuned fixed-point operations\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef FIXED_ARM5E_H\n#define FIXED_ARM5E_H\n\n#undef MULT16_16\nstatic inline spx_word32_t MULT16_16(spx_word16_t x, spx_word16_t y) {\n  int res;\n  asm (\"smulbb  %0,%1,%2;\\n\"\n              : \"=&r\"(res)\n              : \"%r\"(x),\"r\"(y));\n  return(res);\n}\n\n#undef MAC16_16\nstatic inline spx_word32_t MAC16_16(spx_word32_t a, spx_word16_t x, spx_word32_t y) {\n  int res;\n  asm (\"smlabb  %0,%1,%2,%3;\\n\"\n              : \"=&r\"(res)\n               : \"%r\"(x),\"r\"(y),\"r\"(a));\n  return(res);\n}\n\n#undef MULT16_32_Q15\nstatic inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) {\n  int res;\n  asm (\"smulwb  %0,%1,%2;\\n\"\n              : \"=&r\"(res)\n               : \"%r\"(y<<1),\"r\"(x));\n  return(res);\n}\n\n#undef MAC16_32_Q15\nstatic inline spx_word32_t MAC16_32_Q15(spx_word32_t a, spx_word16_t x, spx_word32_t y) {\n  int res;\n  asm (\"smlawb  %0,%1,%2,%3;\\n\"\n              : \"=&r\"(res)\n               : \"%r\"(y<<1),\"r\"(x),\"r\"(a));\n  return(res);\n}\n\n#undef MULT16_32_Q11\nstatic inline spx_word32_t MULT16_32_Q11(spx_word16_t x, spx_word32_t y) {\n  int res;\n  asm (\"smulwb  %0,%1,%2;\\n\"\n              : \"=&r\"(res)\n               : \"%r\"(y<<5),\"r\"(x));\n  return(res);\n}\n\n#undef MAC16_32_Q11\nstatic inline spx_word32_t MAC16_32_Q11(spx_word32_t a, spx_word16_t x, spx_word32_t y) {\n  int res;\n  asm (\"smlawb  %0,%1,%2,%3;\\n\"\n              : \"=&r\"(res)\n               : \"%r\"(y<<5),\"r\"(x),\"r\"(a));\n  return(res);\n}\n\n#undef DIV32_16\nstatic inline short DIV32_16(int a, int b)\n{\n   int res=0;\n   int dead1, dead2, dead3, dead4, dead5;\n   __asm__ __volatile__ (\n         \"\\teor %5, %0, %1\\n\"\n         \"\\tmovs %4, %0\\n\"\n         \"\\trsbmi %0, %0, #0 \\n\"\n         \"\\tmovs %4, %1\\n\"\n         \"\\trsbmi %1, %1, #0 \\n\"\n         \"\\tmov %4, #1\\n\"\n\n         \"\\tsubs %3, %0, %1, asl #14 \\n\"\n         \"\\torrpl %2, %2, %4, asl #14 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #13 \\n\"\n         \"\\torrpl %2, %2, %4, asl #13 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #12 \\n\"\n         \"\\torrpl %2, %2, %4, asl #12 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #11 \\n\"\n         \"\\torrpl %2, %2, %4, asl #11 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #10 \\n\"\n         \"\\torrpl %2, %2, %4, asl #10 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #9 \\n\"\n         \"\\torrpl %2, %2, %4, asl #9 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #8 \\n\"\n         \"\\torrpl %2, %2, %4, asl #8 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #7 \\n\"\n         \"\\torrpl %2, %2, %4, asl #7 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #6 \\n\"\n         \"\\torrpl %2, %2, %4, asl #6 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #5 \\n\"\n         \"\\torrpl %2, %2, %4, asl #5 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #4 \\n\"\n         \"\\torrpl %2, %2, %4, asl #4 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #3 \\n\"\n         \"\\torrpl %2, %2, %4, asl #3 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #2 \\n\"\n         \"\\torrpl %2, %2, %4, asl #2 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1, asl #1 \\n\"\n         \"\\torrpl %2, %2, %4, asl #1 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n\n         \"\\tsubs %3, %0, %1 \\n\"\n         \"\\torrpl %2, %2, %4 \\n\"\n         \"\\tmovpl %0, %3 \\n\"\n         \n         \"\\tmovs %5, %5, lsr #31 \\n\"\n         \"\\trsbne %2, %2, #0 \\n\"\n   : \"=r\" (dead1), \"=r\" (dead2), \"=r\" (res),\n   \"=r\" (dead3), \"=r\" (dead4), \"=r\" (dead5)\n   : \"0\" (a), \"1\" (b), \"2\" (res)\n   : \"memory\", \"cc\"\n                        );\n   return res;\n}\n\n\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/fixed_bfin.h",
    "content": "/* Copyright (C) 2005 Analog Devices\n   Author: Jean-Marc Valin */\n/**\n   @file fixed_bfin.h\n   @brief Blackfin fixed-point operations\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef FIXED_BFIN_H\n#define FIXED_BFIN_H\n\n#undef PDIV32_16\nstatic inline spx_word16_t PDIV32_16(spx_word32_t a, spx_word16_t b)\n{\n   spx_word32_t res, bb;\n   bb = b;\n   a += b>>1;\n   __asm__  (\n         \"P0 = 15;\\n\\t\"\n         \"R0 = %1;\\n\\t\"\n         \"R1 = %2;\\n\\t\"\n         //\"R0 = R0 + R1;\\n\\t\"\n         \"R0 <<= 1;\\n\\t\"\n         \"DIVS (R0, R1);\\n\\t\"\n         \"LOOP divide%= LC0 = P0;\\n\\t\"\n         \"LOOP_BEGIN divide%=;\\n\\t\"\n            \"DIVQ (R0, R1);\\n\\t\"\n         \"LOOP_END divide%=;\\n\\t\"\n         \"R0 = R0.L;\\n\\t\"\n         \"%0 = R0;\\n\\t\"\n   : \"=m\" (res)\n   : \"m\" (a), \"m\" (bb)\n   : \"P0\", \"R0\", \"R1\", \"cc\");\n   return res;\n}\n\n#undef DIV32_16\nstatic inline spx_word16_t DIV32_16(spx_word32_t a, spx_word16_t b)\n{\n   spx_word32_t res, bb;\n   bb = b;\n   /* Make the roundinf consistent with the C version \n      (do we need to do that?)*/\n   if (a<0) \n      a += (b-1);\n   __asm__  (\n         \"P0 = 15;\\n\\t\"\n         \"R0 = %1;\\n\\t\"\n         \"R1 = %2;\\n\\t\"\n         \"R0 <<= 1;\\n\\t\"\n         \"DIVS (R0, R1);\\n\\t\"\n         \"LOOP divide%= LC0 = P0;\\n\\t\"\n         \"LOOP_BEGIN divide%=;\\n\\t\"\n            \"DIVQ (R0, R1);\\n\\t\"\n         \"LOOP_END divide%=;\\n\\t\"\n         \"R0 = R0.L;\\n\\t\"\n         \"%0 = R0;\\n\\t\"\n   : \"=m\" (res)\n   : \"m\" (a), \"m\" (bb)\n   : \"P0\", \"R0\", \"R1\", \"cc\");\n   return res;\n}\n\n#undef MAX16\nstatic inline spx_word16_t MAX16(spx_word16_t a, spx_word16_t b)\n{\n   spx_word32_t res;\n   __asm__  (\n         \"%1 = %1.L (X);\\n\\t\"\n         \"%2 = %2.L (X);\\n\\t\"\n         \"%0 = MAX(%1,%2);\"\n   : \"=d\" (res)\n   : \"%d\" (a), \"d\" (b)\n   );\n   return res;\n}\n\n#undef MULT16_32_Q15\nstatic inline spx_word32_t MULT16_32_Q15(spx_word16_t a, spx_word32_t b)\n{\n   spx_word32_t res;\n   __asm__\n   (\n         \"A1 = %2.L*%1.L (M);\\n\\t\"\n         \"A1 = A1 >>> 15;\\n\\t\"\n         \"%0 = (A1 += %2.L*%1.H) ;\\n\\t\"\n   : \"=&W\" (res), \"=&d\" (b)\n   : \"d\" (a), \"1\" (b)\n   : \"A1\"\n   );\n   return res;\n}\n\n#undef MAC16_32_Q15\nstatic inline spx_word32_t MAC16_32_Q15(spx_word32_t c, spx_word16_t a, spx_word32_t b)\n{\n   spx_word32_t res;\n   __asm__\n         (\n         \"A1 = %2.L*%1.L (M);\\n\\t\"\n         \"A1 = A1 >>> 15;\\n\\t\"\n         \"%0 = (A1 += %2.L*%1.H);\\n\\t\"\n         \"%0 = %0 + %4;\\n\\t\"\n   : \"=&W\" (res), \"=&d\" (b)\n   : \"d\" (a), \"1\" (b), \"d\" (c)\n   : \"A1\"\n         );\n   return res;\n}\n\n#undef MULT16_32_Q14\nstatic inline spx_word32_t MULT16_32_Q14(spx_word16_t a, spx_word32_t b)\n{\n   spx_word32_t res;\n   __asm__\n         (\n         \"%2 <<= 1;\\n\\t\"\n         \"A1 = %1.L*%2.L (M);\\n\\t\"\n         \"A1 = A1 >>> 15;\\n\\t\"\n         \"%0 = (A1 += %1.L*%2.H);\\n\\t\"\n   : \"=W\" (res), \"=d\" (a), \"=d\" (b)\n   : \"1\" (a), \"2\" (b)\n   : \"A1\"\n         );\n   return res;\n}\n\n#undef MAC16_32_Q14\nstatic inline spx_word32_t MAC16_32_Q14(spx_word32_t c, spx_word16_t a, spx_word32_t b)\n{\n   spx_word32_t res;\n   __asm__\n         (\n         \"%1 <<= 1;\\n\\t\"\n         \"A1 = %2.L*%1.L (M);\\n\\t\"\n         \"A1 = A1 >>> 15;\\n\\t\"\n         \"%0 = (A1 += %2.L*%1.H);\\n\\t\"\n         \"%0 = %0 + %4;\\n\\t\"\n   : \"=&W\" (res), \"=&d\" (b)\n   : \"d\" (a), \"1\" (b), \"d\" (c)\n   : \"A1\"\n         );\n   return res;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/fixed_debug.h",
    "content": "/* Copyright (C) 2003 Jean-Marc Valin */\n/**\n   @file fixed_debug.h\n   @brief Fixed-point operations with debugging\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef FIXED_DEBUG_H\n#define FIXED_DEBUG_H\n\n#include <stdio.h>\n\nextern long long spx_mips;\n#define MIPS_INC spx_mips++,\n\n#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))\n#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))\n\n\n#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)\n#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)\n\nstatic inline short NEG16(int x)\n{\n   int res;\n   if (!VERIFY_SHORT(x))\n   {\n      fprintf (stderr, \"NEG16: input is not short: %d\\n\", (int)x);\n   }\n   res = -x;\n   if (!VERIFY_SHORT(res))\n      fprintf (stderr, \"NEG16: output is not short: %d\\n\", (int)res);\n   spx_mips++;\n   return res;\n}\nstatic inline int NEG32(long long x)\n{\n   long long res;\n   if (!VERIFY_INT(x))\n   {\n      fprintf (stderr, \"NEG16: input is not int: %d\\n\", (int)x);\n   }\n   res = -x;\n   if (!VERIFY_INT(res))\n      fprintf (stderr, \"NEG16: output is not int: %d\\n\", (int)res);\n   spx_mips++;\n   return res;\n}\n\n#define EXTRACT16(x) _EXTRACT16(x, __FILE__, __LINE__)\nstatic inline short _EXTRACT16(int x, char *file, int line)\n{\n   int res;\n   if (!VERIFY_SHORT(x))\n   {\n      fprintf (stderr, \"EXTRACT16: input is not short: %d in %s: line %d\\n\", x, file, line);\n   }\n   res = x;\n   spx_mips++;\n   return res;\n}\n\n#define EXTEND32(x) _EXTEND32(x, __FILE__, __LINE__)\nstatic inline int _EXTEND32(int x, char *file, int line)\n{\n   int res;\n   if (!VERIFY_SHORT(x))\n   {\n      fprintf (stderr, \"EXTEND32: input is not short: %d in %s: line %d\\n\", x, file, line);\n   }\n   res = x;\n   spx_mips++;\n   return res;\n}\n\n#define SHR16(a, shift) _SHR16(a, shift, __FILE__, __LINE__)\nstatic inline short _SHR16(int a, int shift, char *file, int line) \n{\n   int res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))\n   {\n      fprintf (stderr, \"SHR16: inputs are not short: %d >> %d in %s: line %d\\n\", a, shift, file, line);\n   }\n   res = a>>shift;\n   if (!VERIFY_SHORT(res))\n      fprintf (stderr, \"SHR16: output is not short: %d in %s: line %d\\n\", res, file, line);\n   spx_mips++;\n   return res;\n}\n#define SHL16(a, shift) _SHL16(a, shift, __FILE__, __LINE__)\nstatic inline short _SHL16(int a, int shift, char *file, int line) \n{\n   int res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))\n   {\n      fprintf (stderr, \"SHL16: inputs are not short: %d %d in %s: line %d\\n\", a, shift, file, line);\n   }\n   res = a<<shift;\n   if (!VERIFY_SHORT(res))\n      fprintf (stderr, \"SHL16: output is not short: %d in %s: line %d\\n\", res, file, line);\n   spx_mips++;\n   return res;\n}\n\nstatic inline int SHR32(long long a, int shift) \n{\n   long long  res;\n   if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))\n   {\n      fprintf (stderr, \"SHR32: inputs are not int: %d %d\\n\", (int)a, shift);\n   }\n   res = a>>shift;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"SHR32: output is not int: %d\\n\", (int)res);\n   }\n   spx_mips++;\n   return res;\n}\nstatic inline int SHL32(long long a, int shift) \n{\n   long long  res;\n   if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))\n   {\n      fprintf (stderr, \"SHL32: inputs are not int: %d %d\\n\", (int)a, shift);\n   }\n   res = a<<shift;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"SHL32: output is not int: %d\\n\", (int)res);\n   }\n   spx_mips++;\n   return res;\n}\n\n#define PSHR16(a,shift) (SHR16(ADD16((a),((1<<((shift))>>1))),shift))\n#define PSHR32(a,shift) (SHR32(ADD32((a),((EXTEND32(1)<<((shift))>>1))),shift))\n#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))\n\n#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))\n#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))\n\n//#define SHR(a,shift) ((a) >> (shift))\n//#define SHL(a,shift) ((a) << (shift))\n\n#define ADD16(a, b) _ADD16(a, b, __FILE__, __LINE__)\nstatic inline short _ADD16(int a, int b, char *file, int line) \n{\n   int res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"ADD16: inputs are not short: %d %d in %s: line %d\\n\", a, b, file, line);\n   }\n   res = a+b;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"ADD16: output is not short: %d+%d=%d in %s: line %d\\n\", a,b,res, file, line);\n   }\n   spx_mips++;\n   return res;\n}\n\n#define SUB16(a, b) _SUB16(a, b, __FILE__, __LINE__)\nstatic inline short _SUB16(int a, int b, char *file, int line) \n{\n   int res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"SUB16: inputs are not short: %d %d in %s: line %d\\n\", a, b, file, line);\n   }\n   res = a-b;\n   if (!VERIFY_SHORT(res))\n      fprintf (stderr, \"SUB16: output is not short: %d in %s: line %d\\n\", res, file, line);\n   spx_mips++;\n   return res;\n}\n\n#define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__)\nstatic inline int _ADD32(long long a, long long b, char *file, int line) \n{\n   long long res;\n   if (!VERIFY_INT(a) || !VERIFY_INT(b))\n   {\n      fprintf (stderr, \"ADD32: inputs are not int: %d %d in %s: line %d\\n\", (int)a, (int)b, file, line);\n   }\n   res = a+b;\n   if (!VERIFY_INT(res))\n   {\n      fprintf (stderr, \"ADD32: output is not int: %d in %s: line %d\\n\", (int)res, file, line);\n   }\n   spx_mips++;\n   return res;\n}\n\nstatic inline int SUB32(long long a, long long b) \n{\n   long long res;\n   if (!VERIFY_INT(a) || !VERIFY_INT(b))\n   {\n      fprintf (stderr, \"SUB32: inputs are not int: %d %d\\n\", (int)a, (int)b);\n   }\n   res = a-b;\n   if (!VERIFY_INT(res))\n      fprintf (stderr, \"SUB32: output is not int: %d\\n\", (int)res);\n   spx_mips++;\n   return res;\n}\n\n#define ADD64(a,b) (MIPS_INC(a)+(b))\n\n/* result fits in 16 bits */\nstatic inline short MULT16_16_16(int a, int b) \n{\n   int res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_16: inputs are not short: %d %d\\n\", a, b);\n   }\n   res = a*b;\n   if (!VERIFY_SHORT(res))\n      fprintf (stderr, \"MULT16_16_16: output is not short: %d\\n\", res);\n   spx_mips++;\n   return res;\n}\n\n#define MULT16_16(a, b) _MULT16_16(a, b, __FILE__, __LINE__)\nstatic inline int _MULT16_16(int a, int b, char *file, int line) \n{\n   long long res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16: inputs are not short: %d %d in %s: line %d\\n\", a, b, file, line);\n   }\n   res = ((long long)a)*b;\n   if (!VERIFY_INT(res))\n      fprintf (stderr, \"MULT16_16: output is not int: %d in %s: line %d\\n\", (int)res, file, line);\n   spx_mips++;\n   return res;\n}\n\n#define MAC16_16(c,a,b)     (spx_mips--,ADD32((c),MULT16_16((a),(b))))\n#define MAC16_16_Q11(c,a,b)     (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11)))))\n#define MAC16_16_Q13(c,a,b)     (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13)))))\n#define MAC16_16_P13(c,a,b)     (EXTRACT16(ADD32((c),SHR32(ADD32(4096,MULT16_16((a),(b))),13))))\n\n\n#define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__)\nstatic inline int _MULT16_32_QX(int a, long long b, int Q, char *file, int line)\n{\n   long long res;\n   if (!VERIFY_SHORT(a) || !VERIFY_INT(b))\n   {\n      fprintf (stderr, \"MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\\n\", Q, (int)a, (int)b, file, line);\n   }\n   if (ABS32(b)>=(EXTEND32(1)<<(15+Q)))\n      fprintf (stderr, \"MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\\n\", Q, (int)a, (int)b, file, line);      \n   res = (((long long)a)*(long long)b) >> Q;\n   if (!VERIFY_INT(res))\n      fprintf (stderr, \"MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\\n\", Q, (int)a, (int)b,(int)res, file, line);\n   spx_mips+=5;\n   return res;\n}\n\nstatic inline int MULT16_32_PX(int a, long long b, int Q)\n{\n   long long res;\n   if (!VERIFY_SHORT(a) || !VERIFY_INT(b))\n   {\n      fprintf (stderr, \"MULT16_32_P%d: inputs are not short+int: %d %d\\n\", Q, (int)a, (int)b);\n   }\n   if (ABS32(b)>=(EXTEND32(1)<<(15+Q)))\n      fprintf (stderr, \"MULT16_32_Q%d: second operand too large: %d %d\\n\", Q, (int)a, (int)b);      \n   res = ((((long long)a)*(long long)b) + ((EXTEND32(1)<<Q)>>1))>> Q;\n   if (!VERIFY_INT(res))\n      fprintf (stderr, \"MULT16_32_P%d: output is not int: %d*%d=%d\\n\", Q, (int)a, (int)b,(int)res);\n   spx_mips+=5;\n   return res;\n}\n\n\n#define MULT16_32_Q11(a,b) MULT16_32_QX(a,b,11)\n#define MAC16_32_Q11(c,a,b) ADD32((c),MULT16_32_Q11((a),(b)))\n#define MULT16_32_Q12(a,b) MULT16_32_QX(a,b,12)\n#define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13)\n#define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14)\n#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)\n#define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15)\n#define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b)))\n\nstatic inline int SATURATE(int a, int b)\n{\n   if (a>b)\n      a=b;\n   if (a<-b)\n      a = -b;\n   return a;\n}\n\nstatic inline int MULT16_16_Q11_32(int a, int b) \n{\n   long long res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_Q11: inputs are not short: %d %d\\n\", a, b);\n   }\n   res = ((long long)a)*b;\n   res >>= 11;\n   if (!VERIFY_INT(res))\n      fprintf (stderr, \"MULT16_16_Q11: output is not short: %d*%d=%d\\n\", (int)a, (int)b, (int)res);\n   spx_mips+=3;\n   return res;\n}\nstatic inline short MULT16_16_Q13(int a, int b) \n{\n   long long res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_Q13: inputs are not short: %d %d\\n\", a, b);\n   }\n   res = ((long long)a)*b;\n   res >>= 13;\n   if (!VERIFY_SHORT(res))\n      fprintf (stderr, \"MULT16_16_Q13: output is not short: %d*%d=%d\\n\", a, b, (int)res);\n   spx_mips+=3;\n   return res;\n}\nstatic inline short MULT16_16_Q14(int a, int b) \n{\n   long long res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_Q14: inputs are not short: %d %d\\n\", a, b);\n   }\n   res = ((long long)a)*b;\n   res >>= 14;\n   if (!VERIFY_SHORT(res))\n      fprintf (stderr, \"MULT16_16_Q14: output is not short: %d\\n\", (int)res);\n   spx_mips+=3;\n   return res;\n}\nstatic inline short MULT16_16_Q15(int a, int b) \n{\n   long long res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_Q15: inputs are not short: %d %d\\n\", a, b);\n   }\n   res = ((long long)a)*b;\n   res >>= 15;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"MULT16_16_Q15: output is not short: %d\\n\", (int)res);\n   }\n   spx_mips+=3;\n   return res;\n}\n\nstatic inline short MULT16_16_P13(int a, int b) \n{\n   long long res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_P13: inputs are not short: %d %d\\n\", a, b);\n   }\n   res = ((long long)a)*b;\n   res += 4096;\n   if (!VERIFY_INT(res))\n      fprintf (stderr, \"MULT16_16_P13: overflow: %d*%d=%d\\n\", a, b, (int)res);\n   res >>= 13;\n   if (!VERIFY_SHORT(res))\n      fprintf (stderr, \"MULT16_16_P13: output is not short: %d*%d=%d\\n\", a, b, (int)res);\n   spx_mips+=4;\n   return res;\n}\nstatic inline short MULT16_16_P14(int a, int b) \n{\n   long long res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_P14: inputs are not short: %d %d\\n\", a, b);\n   }\n   res = ((long long)a)*b;\n   res += 8192;\n   if (!VERIFY_INT(res))\n      fprintf (stderr, \"MULT16_16_P14: overflow: %d*%d=%d\\n\", a, b, (int)res);\n   res >>= 14;\n   if (!VERIFY_SHORT(res))\n      fprintf (stderr, \"MULT16_16_P14: output is not short: %d*%d=%d\\n\", a, b, (int)res);\n   spx_mips+=4;\n   return res;\n}\nstatic inline short MULT16_16_P15(int a, int b) \n{\n   long long res;\n   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"MULT16_16_P15: inputs are not short: %d %d\\n\", a, b);\n   }\n   res = ((long long)a)*b;\n   res += 16384;\n   if (!VERIFY_INT(res))\n      fprintf (stderr, \"MULT16_16_P15: overflow: %d*%d=%d\\n\", a, b, (int)res);\n   res >>= 15;\n   if (!VERIFY_SHORT(res))\n      fprintf (stderr, \"MULT16_16_P15: output is not short: %d*%d=%d\\n\", a, b, (int)res);\n   spx_mips+=4;\n   return res;\n}\n\n#define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__)\n\nstatic inline int _DIV32_16(long long a, long long b, char *file, int line) \n{\n   long long res;\n   if (b==0)\n   {\n      fprintf(stderr, \"DIV32_16: divide by zero: %d/%d in %s: line %d\\n\", (int)a, (int)b, file, line);\n      return 0;\n   }\n   if (!VERIFY_INT(a) || !VERIFY_SHORT(b))\n   {\n      fprintf (stderr, \"DIV32_16: inputs are not int/short: %d %d in %s: line %d\\n\", (int)a, (int)b, file, line);\n   }\n   res = a/b;\n   if (!VERIFY_SHORT(res))\n   {\n      fprintf (stderr, \"DIV32_16: output is not short: %d / %d = %d in %s: line %d\\n\", (int)a,(int)b,(int)res, file, line);\n      if (res>32767)\n         res = 32767;\n      if (res<-32768)\n         res = -32768;\n   }\n   spx_mips+=20;\n   return res;\n}\n\n#define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__)\nstatic inline int _DIV32(long long a, long long b, char *file, int line) \n{\n   long long res;\n   if (b==0)\n   {\n      fprintf(stderr, \"DIV32: divide by zero: %d/%d in %s: line %d\\n\", (int)a, (int)b, file, line);\n      return 0;\n   }\n\n   if (!VERIFY_INT(a) || !VERIFY_INT(b))\n   {\n      fprintf (stderr, \"DIV32: inputs are not int/short: %d %d in %s: line %d\\n\", (int)a, (int)b, file, line);\n   }\n   res = a/b;\n   if (!VERIFY_INT(res))\n      fprintf (stderr, \"DIV32: output is not int: %d in %s: line %d\\n\", (int)res, file, line);\n   spx_mips+=36;\n   return res;\n}\n#define PDIV32(a,b) DIV32(ADD32((a),(b)>>1),b)\n#define PDIV32_16(a,b) DIV32_16(ADD32((a),(b)>>1),b)\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/fixed_generic.h",
    "content": "/* Copyright (C) 2003 Jean-Marc Valin */\n/**\n   @file fixed_generic.h\n   @brief Generic fixed-point operations\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef FIXED_GENERIC_H\n#define FIXED_GENERIC_H\n\n#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))\n#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))\n\n#define NEG16(x) (-(x))\n#define NEG32(x) (-(x))\n#define EXTRACT16(x) ((spx_word16_t)(x))\n#define EXTEND32(x) ((spx_word32_t)(x))\n#define SHR16(a,shift) ((a) >> (shift))\n#define SHL16(a,shift) ((a) << (shift))\n#define SHR32(a,shift) ((a) >> (shift))\n#define SHL32(a,shift) ((a) << (shift))\n#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift))\n#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift))\n#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))\n#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))\n#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))\n\n#define SHR(a,shift) ((a) >> (shift))\n#define SHL(a,shift) ((spx_word32_t)(a) << (shift))\n#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))\n#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))\n\n\n#define ADD16(a,b) ((spx_word16_t)((spx_word16_t)(a)+(spx_word16_t)(b)))\n#define SUB16(a,b) ((spx_word16_t)(a)-(spx_word16_t)(b))\n#define ADD32(a,b) ((spx_word32_t)(a)+(spx_word32_t)(b))\n#define SUB32(a,b) ((spx_word32_t)(a)-(spx_word32_t)(b))\n\n\n/* result fits in 16 bits */\n#define MULT16_16_16(a,b)     ((((spx_word16_t)(a))*((spx_word16_t)(b))))\n\n/* (spx_word32_t)(spx_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */\n#define MULT16_16(a,b)     (((spx_word32_t)(spx_word16_t)(a))*((spx_word32_t)(spx_word16_t)(b)))\n\n#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))\n#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))\n#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13))\n#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14))\n\n#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))\n#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)))\n\n#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15))\n#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))\n#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))\n\n\n#define MAC16_16_Q11(c,a,b)     (ADD32((c),SHR(MULT16_16((a),(b)),11)))\n#define MAC16_16_Q13(c,a,b)     (ADD32((c),SHR(MULT16_16((a),(b)),13)))\n#define MAC16_16_P13(c,a,b)     (ADD32((c),SHR(ADD32(4096,MULT16_16((a),(b))),13)))\n\n#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))\n#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))\n#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))\n#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))\n\n#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13))\n#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14))\n#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15))\n\n#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15))\n\n#define DIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a))/((spx_word16_t)(b))))\n#define PDIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word16_t)(b))))\n#define DIV32(a,b) (((spx_word32_t)(a))/((spx_word32_t)(b)))\n#define PDIV32(a,b) (((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word32_t)(b)))\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/gain_table.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: gain_table.c\n   Codebook for 3-tap pitch prediction gain (128 entries)\n  \n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.  \n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\nconst signed char gain_cdbk_nb[512] = {\n-32, -32, -32, 0,\n-28, -67, -5, 33,\n-42, -6, -32, 18,\n-57, -10, -54, 35,\n-16, 27, -41, 42,\n19, -19, -40, 36,\n-45, 24, -21, 40,\n-8, -14, -18, 28,\n1, 14, -58, 53,\n-18, -88, -39, 39,\n-38, 21, -18, 37,\n-19, 20, -43, 38,\n10, 17, -48, 54,\n-52, -58, -13, 33,\n-44, -1, -11, 32,\n-12, -11, -34, 22,\n14, 0, -46, 46,\n-37, -35, -34, 5,\n-25, 44, -30, 43,\n6, -4, -63, 49,\n-31, 43, -41, 43,\n-23, 30, -43, 41,\n-43, 26, -14, 44,\n-33, 1, -13, 27,\n-13, 18, -37, 37,\n-46, -73, -45, 34,\n-36, 24, -25, 34,\n-36, -11, -20, 19,\n-25, 12, -18, 33,\n-36, -69, -59, 34,\n-45, 6, 8, 46,\n-22, -14, -24, 18,\n-1, 13, -44, 44,\n-39, -48, -26, 15,\n-32, 31, -37, 34,\n-33, 15, -46, 31,\n-24, 30, -36, 37,\n-41, 31, -23, 41,\n-50, 22, -4, 50,\n-22, 2, -21, 28,\n-17, 30, -34, 40,\n-7, -60, -28, 29,\n-38, 42, -28, 42,\n-44, -11, 21, 43,\n-16, 8, -44, 34,\n-39, -55, -43, 21,\n-11, -35, 26, 41,\n-9, 0, -34, 29,\n-8, 121, -81, 113,\n7, -16, -22, 33,\n-37, 33, -31, 36,\n-27, -7, -36, 17,\n-34, 70, -57, 65,\n-37, -11, -48, 21,\n-40, 17, -1, 44,\n-33, 6, -6, 33,\n-9, 0, -20, 34,\n-21, 69, -33, 57,\n-29, 33, -31, 35,\n-55, 12, -1, 49,\n-33, 27, -22, 35,\n-50, -33, -47, 17,\n-50, 54, 51, 94,\n-1, -5, -44, 35,\n-4, 22, -40, 45,\n-39, -66, -25, 24,\n-33, 1, -26, 20,\n-24, -23, -25, 12,\n-11, 21, -45, 44,\n-25, -45, -19, 17,\n-43, 105, -16, 82,\n5, -21, 1, 41,\n-16, 11, -33, 30,\n-13, -99, -4, 57,\n-37, 33, -15, 44,\n-25, 37, -63, 54,\n-36, 24, -31, 31,\n-53, -56, -38, 26,\n-41, -4, 4, 37,\n-33, 13, -30, 24,\n49, 52, -94, 114,\n-5, -30, -15, 23,\n1, 38, -40, 56,\n-23, 12, -36, 29,\n-17, 40, -47, 51,\n-37, -41, -39, 11,\n-49, 34, 0, 58,\n-18, -7, -4, 34,\n-16, 17, -27, 35,\n30, 5, -62, 65,\n4, 48, -68, 76,\n-43, 11, -11, 38,\n-18, 19, -15, 41,\n-23, -62, -39, 23,\n-42, 10, -2, 41,\n-21, -13, -13, 25,\n-9, 13, -47, 42,\n-23, -62, -24, 24,\n-44, 60, -21, 58,\n-18, -3, -52, 32,\n-22, 22, -36, 34,\n-75, 57, 16, 90,\n-19, 3, 10, 45,\n-29, 23, -38, 32,\n-5, -62, -51, 38,\n-51, 40, -18, 53,\n-42, 13, -24, 32,\n-34, 14, -20, 30,\n-56, -75, -26, 37,\n-26, 32, 15, 59,\n-26, 17, -29, 29,\n-7, 28, -52, 53,\n-12, -30, 5, 30,\n-5, -48, -5, 35,\n2, 2, -43, 40,\n21, 16, 16, 75,\n-25, -45, -32, 10,\n-43, 18, -10, 42,\n9, 0, -1, 52,\n-1, 7, -30, 36,\n19, -48, -4, 48,\n-28, 25, -29, 32,\n-22, 0, -31, 22,\n-32, 17, -10, 36,\n-64, -41, -62, 36,\n-52, 15, 16, 58,\n-30, -22, -32, 6,\n-7, 9, -38, 36};\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/gain_table_lbr.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: gain_table_lbr.c\n   Codebook for 3-tap pitch prediction gain (32 entries)\n  \n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.  \n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\nconst signed char gain_cdbk_lbr[128] = {\n-32, -32, -32, 0,\n-31, -58, -16, 22,\n-41, -24, -43, 14,\n-56, -22, -55, 29,\n-13, 33, -41, 47,\n-4, -39, -9, 29,\n-41, 15, -12, 38,\n-8, -15, -12, 31,\n1, 2, -44, 40,\n-22, -66, -42, 27,\n-38, 28, -23, 38,\n-21, 14, -37, 31,\n0, 21, -50, 52,\n-53, -71, -27, 33,\n-37, -1, -19, 25,\n-19, -5, -28, 22,\n6, 65, -44, 74,\n-33, -48, -33, 9,\n-40, 57, -14, 58,\n-17, 4, -45, 32,\n-31, 38, -33, 36,\n-23, 28, -40, 39,\n-43, 29, -12, 46,\n-34, 13, -23, 28,\n-16, 15, -27, 34,\n-14, -82, -15, 43,\n-31, 25, -32, 29,\n-21, 5, -5, 38,\n-47, -63, -51, 33,\n-46, 12, 3, 47,\n-28, -17, -29, 11,\n-10, 14, -40, 38};\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/hexc_10_32_table.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: hexc_10_32_table.c\n   Codebook for high-band excitation in SB-CELP mode (4000 bps)\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\nconst signed char hexc_10_32_table[320] = {\n-3, -2, -1, 0, -4, 5, 35, -40, -9, 13, \n-44, 5, -27, -1, -7, 6, -11, 7, -8, 7, \n19, -14, 15, -4, 9, -10, 10, -8, 10, -9, \n-1, 1, 0, 0, 2, 5, -18, 22, -53, 50, \n1, -23, 50, -36, 15, 3, -13, 14, -10, 6, \n1, 5, -3, 4, -2, 5, -32, 25, 5, -2, \n-1, -4, 1, 11, -29, 26, -6, -15, 30, -18, \n0, 15, -17, 40, -41, 3, 9, -2, -2, 3, \n-3, -1, -5, 2, 21, -6, -16, -21, 23, 2, \n60, 15, 16, -16, -9, 14, 9, -1, 7, -9, \n0, 1, 1, 0, -1, -6, 17, -28, 54, -45, \n-1, 1, -1, -6, -6, 2, 11, 26, -29, -2, \n46, -21, 34, 12, -23, 32, -23, 16, -10, 3, \n66, 19, -20, 24, 7, 11, -3, 0, -3, -1, \n-50, -46, 2, -18, -3, 4, -1, -2, 3, -3, \n-19, 41, -36, 9, 11, -24, 21, -16, 9, -3, \n-25, -3, 10, 18, -9, -2, -5, -1, -5, 6, \n-4, -3, 2, -26, 21, -19, 35, -15, 7, -13, \n17, -19, 39, -43, 48, -31, 16, -9, 7, -2, \n-5, 3, -4, 9, -19, 27, -55, 63, -35, 10, \n26, -44, -2, 9, 4, 1, -6, 8, -9, 5, \n-8, -1, -3, -16, 45, -42, 5, 15, -16, 10, \n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \n-16, 24, -55, 47, -38, 27, -19, 7, -3, 1, \n16, 27, 20, -19, 18, 5, -7, 1, -5, 2, \n-6, 8, -22, 0, -3, -3, 8, -1, 7, -8, \n1, -3, 5, 0, 17, -48, 58, -52, 29, -7, \n-2, 3, -10, 6, -26, 58, -31, 1, -6, 3, \n93, -29, 39, 3, 17, 5, 6, -1, -1, -1, \n27, 13, 10, 19, -7, -34, 12, 10, -4, 9, \n-76, 9, 8, -28, -2, -11, 2, -1, 3, 1, \n-83, 38, -39, 4, -16, -6, -2, -5, 5, -2, \n};\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/hexc_table.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: hexc_table.c\n   Codebook for high-band excitation in SB-CELP mode (8000 bps with sign)\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\nconst signed char hexc_table[1024] = {\n-24, 21, -20, 5, -5, -7, 14, -10, \n2, -27, 16, -20, 0, -32, 26, 19, \n8, -11, -41, 31, 28, -27, -32, 34, \n42, 34, -17, 22, -10, 13, -29, 18, \n-12, -26, -24, 11, 22, 5, -5, -5, \n54, -68, -43, 57, -25, 24, 4, 4, \n26, -8, -12, -17, 54, 30, -45, 1, \n10, -15, 18, -41, 11, 68, -67, 37, \n-16, -24, -16, 38, -22, 6, -29, 30, \n66, -27, 5, 7, -16, 13, 2, -12, \n-7, -3, -20, 36, 4, -28, 9, 3, \n32, 48, 26, 39, 3, 0, 7, -21, \n-13, 5, -82, -7, 73, -20, 34, -9, \n-5, 1, -1, 10, -5, -10, -1, 9, \n1, -9, 10, 0, -14, 11, -1, -2, \n-1, 11, 20, 96, -81, -22, -12, -9, \n-58, 9, 24, -30, 26, -35, 27, -12, \n13, -18, 56, -59, 15, -7, 23, -15, \n-1, 6, -25, 14, -22, -20, 47, -11, \n16, 2, 38, -23, -19, -30, -9, 40, \n-11, 5, 4, -6, 8, 26, -21, -11, \n127, 4, 1, 6, -9, 2, -7, -2, \n-3, 7, -5, 10, -19, 7, -106, 91, \n-3, 9, -4, 21, -8, 26, -80, 8, \n1, -2, -10, -17, -17, -27, 32, 71, \n6, -29, 11, -23, 54, -38, 29, -22, \n39, 87, -31, -12, -20, 3, -2, -2, \n2, 20, 0, -1, -35, 27, 9, -6, \n-12, 3, -12, -6, 13, 1, 14, -22, \n-59, -15, -17, -25, 13, -7, 7, 3, \n0, 1, -7, 6, -3, 61, -37, -23, \n-23, -29, 38, -31, 27, 1, -8, 2, \n-27, 23, -26, 36, -34, 5, 24, -24, \n-6, 7, 3, -59, 78, -62, 44, -16, \n1, 6, 0, 17, 8, 45, 0, -110, \n6, 14, -2, 32, -77, -56, 62, -3, \n3, -13, 4, -16, 102, -15, -36, -1, \n9, -113, 6, 23, 0, 9, 9, 5, \n-8, -1, -14, 5, -12, 121, -53, -27, \n-8, -9, 22, -13, 3, 2, -3, 1, \n-2, -71, 95, 38, -19, 15, -16, -5, \n71, 10, 2, -32, -13, -5, 15, -1, \n-2, -14, -85, 30, 29, 6, 3, 2, \n0, 0, 0, 0, 0, 0, 0, 0, \n2, -65, -56, -9, 18, 18, 23, -14, \n-2, 0, 12, -29, 26, -12, 1, 2, \n-12, -64, 90, -6, 4, 1, 5, -5, \n-110, -3, -31, 22, -29, 9, 0, 8, \n-40, -5, 21, -5, -5, 13, 10, -18, \n40, 1, 35, -20, 30, -28, 11, -6, \n19, 7, 14, 18, -64, 9, -6, 16, \n51, 68, 8, 16, 12, -8, 0, -9, \n20, -22, 25, 7, -4, -13, 41, -35, \n93, -18, -54, 11, -1, 1, -9, 4, \n-66, 66, -31, 20, -22, 25, -23, 11, \n10, 9, 19, 15, 11, -5, -31, -10, \n-23, -28, -6, -6, -3, -4, 5, 3, \n-28, 22, -11, -42, 25, -25, -16, 41, \n34, 47, -6, 2, 42, -19, -22, 5, \n-39, 32, 6, -35, 22, 17, -30, 8, \n-26, -11, -11, 3, -12, 33, 33, -37, \n21, -1, 6, -4, 3, 0, -5, 5, \n12, -12, 57, 27, -61, -3, 20, -17, \n2, 0, 4, 0, -2, -33, -58, 81, \n-23, 39, -10, -5, 2, 6, -7, 5, \n4, -3, -2, -13, -23, -72, 107, 15, \n-5, 0, -7, -3, -6, 5, -4, 15, \n47, 12, -31, 25, -16, 8, 22, -25, \n-62, -56, -18, 14, 28, 12, 2, -11, \n74, -66, 41, -20, -7, 16, -20, 16, \n-8, 0, -16, 4, -19, 92, 12, -59, \n-14, -39, 49, -25, -16, 23, -27, 19, \n-3, -33, 19, 85, -29, 6, -7, -10, \n16, -7, -12, 1, -6, 2, 4, -2, \n64, 10, -25, 41, -2, -31, 15, 0, \n110, 50, 69, 35, 28, 19, -10, 2, \n-43, -49, -56, -15, -16, 10, 3, 12, \n-1, -8, 1, 26, -12, -1, 7, -11, \n-27, 41, 25, 1, -11, -18, 22, -7, \n-1, -47, -8, 23, -3, -17, -7, 18, \n-125, 59, -5, 3, 18, 1, 2, 3, \n27, -35, 65, -53, 50, -46, 37, -21, \n-28, 7, 14, -37, -5, -5, 12, 5, \n-8, 78, -19, 21, -6, -16, 8, -7, \n5, 2, 7, 2, 10, -6, 12, -60, \n44, 11, -36, -32, 31, 0, 2, -2, \n2, 1, -3, 7, -10, 17, -21, 10, \n6, -2, 19, -2, 59, -38, -86, 38, \n8, -41, -30, -45, -33, 7, 15, 28, \n29, -7, 24, -40, 7, 7, 5, -2, \n9, 24, -23, -18, 6, -29, 30, 2, \n28, 49, -11, -46, 10, 43, -13, -9, \n-1, -3, -7, -7, -17, -6, 97, -33, \n-21, 3, 5, 1, 12, -43, -8, 28, \n7, -43, -7, 17, -20, 19, -1, 2, \n-13, 9, 54, 34, 9, -28, -11, -9, \n-17, 110, -59, 44, -26, 0, 3, -12, \n-47, 73, -34, -43, 38, -33, 16, -5, \n-46, -4, -6, -2, -25, 19, -29, 28, \n-13, 5, 14, 27, -40, -43, 4, 32, \n-13, -2, -35, -4, 112, -42, 9, -12, \n37, -28, 17, 14, -19, 35, -39, 23, \n3, -14, -1, -57, -5, 94, -9, 3, \n-39, 5, 30, -10, -32, 42, -13, -14, \n-97, -63, 30, -9, 1, -7, 12, 5, \n20, 17, -9, -36, -30, 25, 47, -9, \n-15, 12, -22, 98, -8, -50, 15, -27, \n21, -16, -11, 2, 12, -10, 10, -3, \n33, 36, -96, 0, -17, 31, -9, 9, \n3, -20, 13, -11, 8, -4, 10, -10, \n9, 1, 112, -70, -27, 5, -21, 2, \n-57, -3, -29, 10, 19, -21, 21, -10, \n-66, -3, 91, -35, 30, -12, 0, -7, \n59, -28, 26, 2, 14, -18, 1, 1, \n11, 17, 20, -54, -59, 27, 4, 29, \n32, 5, 19, 12, -4, 1, 7, -10, \n5, -2, 10, 0, 23, -5, 28, -104, \n46, 11, 16, 3, 29, 1, -8, -14, \n1, 7, -50, 88, -62, 26, 8, -17, \n-14, 50, 0, 32, -12, -3, -27, 18, \n-8, -5, 8, 3, -20, -11, 37, -12, \n9, 33, 46, -101, -1, -4, 1, 6, \n-1, 28, -42, -15, 16, 5, -1, -2, \n-55, 85, 38, -9, -4, 11, -2, -9, \n-6, 3, -20, -10, -77, 89, 24, -3, \n-104, -57, -26, -31, -20, -6, -9, 14, \n20, -23, 46, -15, -31, 28, 1, -15, \n-2, 6, -2, 31, 45, -76, 23, -25, \n};\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/high_lsp_tables.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: high_lsp_tables.c\n   Codebooks for high-band LSPs in SB-CELP mode\n  \n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.  \n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n \nconst signed char high_lsp_cdbk[512]={\n39,12,-14,-20,-29,-61,-67,-76,\n-32,-71,-67,68,77,46,34,5,\n-13,-48,-46,-72,-81,-84,-60,-58,\n-40,-28,82,93,68,45,29,3,\n-19,-47,-28,-43,-35,-30,-8,-13,\n-39,-91,-91,-123,-96,10,10,-6,\n-18,-55,-60,-91,-56,-36,-27,-16,\n-48,-75,40,28,-10,-28,35,9,\n37,19,1,-20,-31,-41,-18,-25,\n-35,-68,-80,45,27,-1,47,13,\n0,-29,-35,-57,-50,-79,-73,-38,\n-19,5,35,14,-10,-23,16,-8,\n5,-24,-40,-62,-23,-27,-22,-16,\n-18,-46,-72,-77,43,21,33,1,\n-80,-70,-70,-64,-56,-52,-39,-33,\n-31,-38,-19,-19,-15,32,33,-2,\n7,-15,-15,-24,-23,-33,-41,-56,\n-24,-57,5,89,64,41,27,5,\n-9,-47,-60,-97,-97,-124,-20,-9,\n-44,-73,31,29,-4,64,48,7,\n-35,-57,0,-3,-26,-47,-3,-6,\n-40,-76,-79,-48,12,81,55,10,\n9,-24,-43,-73,-57,-69,16,5,\n-28,-53,18,29,20,0,-4,-11,\n6,-13,23,7,-17,-35,-37,-37,\n-30,-68,-63,6,24,-9,-14,3,\n21,-13,-27,-57,-49,-80,-24,-41,\n-5,-16,-5,1,45,25,12,-7,\n3,-15,-6,-16,-15,-8,6,-13,\n-42,-81,-80,-87,14,1,-10,-3,\n-43,-69,-46,-24,-28,-29,36,6,\n-43,-56,-12,12,54,79,43,9,\n54,22,2,8,-12,-43,-46,-52,\n-38,-69,-89,-5,75,38,33,5,\n-13,-53,-62,-87,-89,-113,-99,-55,\n-34,-37,62,55,33,16,21,-2,\n-17,-46,-29,-38,-38,-48,-39,-42,\n-36,-75,-72,-88,-48,-30,21,2,\n-15,-57,-64,-98,-84,-76,25,1,\n-46,-80,-12,18,-7,3,34,6,\n38,31,23,4,-1,20,14,-15,\n-43,-78,-91,-24,14,-3,54,16,\n0,-27,-28,-44,-56,-83,-92,-89,\n-3,34,56,41,36,22,20,-8,\n-7,-35,-42,-62,-49,3,12,-10,\n-50,-87,-96,-66,92,70,38,9,\n-70,-71,-62,-42,-39,-43,-11,-7,\n-50,-79,-58,-50,-31,32,31,-6,\n-4,-25,7,-17,-38,-70,-58,-27,\n-43,-83,-28,59,36,20,31,2,\n-27,-71,-80,-109,-98,-75,-33,-32,\n-31,-2,33,15,-6,43,33,-5,\n0,-22,-10,-27,-34,-49,-11,-20,\n-41,-91,-100,-121,-39,57,41,10,\n-19,-50,-38,-59,-60,-70,-18,-20,\n-8,-31,-8,-15,1,-14,-26,-25,\n33,21,32,17,1,-19,-19,-26,\n-58,-81,-35,-22,45,30,11,-11,\n3,-26,-48,-87,-67,-83,-58,3,\n-1,-26,-20,44,10,25,39,5,\n-9,-35,-27,-38,7,10,4,-9,\n-42,-85,-102,-127,52,44,28,10,\n-47,-61,-40,-39,-17,-1,-10,-33,\n-42,-74,-48,21,-4,70,52,10};\n\n\nconst signed char high_lsp_cdbk2[512]={\n-36,-62,6,-9,-10,-14,-56,23,\n1,-26,23,-48,-17,12,8,-7,\n23,29,-36,-28,-6,-29,-17,-5,\n40,23,10,10,-46,-13,36,6,\n4,-30,-29,62,32,-32,-1,22,\n-14,1,-4,-22,-45,2,54,4,\n-30,-57,-59,-12,27,-3,-31,8,\n-9,5,10,-14,32,66,19,9,\n2,-25,-37,23,-15,18,-38,-31,\n5,-9,-21,15,0,22,62,30,\n15,-12,-14,-46,77,21,33,3,\n34,29,-19,50,2,11,9,-38,\n-12,-37,62,1,-15,54,32,6,\n2,-24,20,35,-21,2,19,24,\n-13,55,4,9,39,-19,30,-1,\n-21,73,54,33,8,18,3,15,\n6,-19,-47,6,-3,-48,-50,1,\n26,20,8,-23,-50,65,-14,-55,\n-17,-31,-37,-28,53,-1,-17,-53,\n1,57,11,-8,-25,-30,-37,64,\n5,-52,-45,15,23,31,15,14,\n-25,24,33,-2,-44,-56,-18,6,\n-21,-43,4,-12,17,-37,20,-10,\n34,15,2,15,55,21,-11,-31,\n-6,46,25,16,-9,-25,-8,-62,\n28,17,20,-32,-29,26,30,25,\n-19,2,-16,-17,26,-51,2,50,\n42,19,-66,23,29,-2,3,19,\n-19,-37,32,15,6,30,-34,13,\n11,-5,40,31,10,-42,4,-9,\n26,-9,-70,17,-2,-23,20,-22,\n-55,51,-24,-31,22,-22,15,-13,\n3,-10,-28,-16,56,4,-63,11,\n-18,-15,-18,-38,-35,16,-7,34,\n-1,-21,-49,-47,9,-37,7,8,\n69,55,20,6,-33,-45,-10,-9,\n6,-9,12,71,15,-3,-42,-7,\n-24,32,-35,-2,-42,-17,-5,0,\n-2,-33,-54,13,-12,-34,47,23,\n19,55,7,-8,74,31,14,16,\n-23,-26,19,12,-18,-49,-28,-31,\n-20,2,-14,-20,-47,78,40,13,\n-23,-11,21,-6,18,1,47,5,\n38,35,32,46,22,8,13,16,\n-14,18,51,19,40,39,11,-26,\n-1,-17,47,2,-53,-15,31,-22,\n38,21,-15,-16,5,-33,53,15,\n-38,86,11,-3,-24,49,13,-4,\n-11,-18,28,20,-12,-27,-26,35,\n-25,-35,-3,-20,-61,30,10,-55,\n-12,-22,-52,-54,-14,19,-32,-12,\n45,15,-8,-48,-9,11,-32,8,\n-16,-34,-13,51,18,38,-2,-32,\n-17,22,-2,-18,-28,-70,59,27,\n-28,-19,-10,-20,-9,-9,-8,-21,\n21,-8,35,-2,45,-3,-9,12,\n0,30,7,-39,43,27,-38,-91,\n30,26,19,-55,-4,63,14,-17,\n13,9,13,2,7,4,6,61,\n72,-1,-17,29,-1,-22,-17,8,\n-28,-37,63,44,41,3,2,14,\n9,-6,75,-8,-7,-12,-15,-12,\n13,9,-4,30,-22,-65,15,0,\n-45,4,-4,1,5,22,11,23};\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/jitter.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: speex_jitter.h\n\n   Adaptive jitter buffer for Speex\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n/*\nTODO:\n- Add short-term estimate\n- Defensive programming\n  + warn when last returned < last desired (begative buffering)\n  + warn if update_delay not called between get() and tick() or is called twice in a row\n- Linked list structure for holding the packets instead of the current fixed-size array\n  + return memory to a pool\n  + allow pre-allocation of the pool\n  + optional max number of elements\n- Statistics\n  + drift\n  + loss\n  + late\n  + jitter\n  + buffering delay\n*/\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n\n#include \"arch.h\"\n#include <speex/speex.h>\n#include <speex/speex_bits.h>\n#include <speex/speex_jitter.h>\n#include \"os_support.h\"\n\n#ifndef NULL\n#define NULL 0\n#endif\n\n#define SPEEX_JITTER_MAX_BUFFER_SIZE 200   /**< Maximum number of packets in jitter buffer */\n\n#define TSUB(a,b) ((spx_int32_t)((a)-(b)))\n\n#define GT32(a,b) (((spx_int32_t)((a)-(b)))>0)\n#define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0)\n#define LT32(a,b) (((spx_int32_t)((a)-(b)))<0)\n#define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0)\n\n#define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step)) \n\n#define MAX_TIMINGS 40\n#define MAX_BUFFERS 3\n#define TOP_DELAY 40\n\n/** Buffer that keeps the time of arrival of the latest packets */\nstruct TimingBuffer {\n   int filled;                         /**< Number of entries occupied in \"timing\" and \"counts\"*/\n   int curr_count;                     /**< Number of packet timings we got (including those we discarded) */\n   spx_int32_t timing[MAX_TIMINGS];    /**< Sorted list of all timings (\"latest\" packets first) */\n   spx_int16_t counts[MAX_TIMINGS];    /**< Order the packets were put in (will be used for short-term estimate) */\n};\n\nstatic void tb_init(struct TimingBuffer *tb)\n{\n   tb->filled = 0;\n   tb->curr_count = 0;\n}\n\n/* Add the timing of a new packet to the TimingBuffer */\nstatic void tb_add(struct TimingBuffer *tb, spx_int16_t timing)\n{\n   int pos;\n   /* Discard packet that won't make it into the list because they're too early */\n   if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1])\n   {\n      tb->curr_count++;\n      return;\n   }\n   \n   /* Find where the timing info goes in the sorted list */\n   pos = 0;\n   /* FIXME: Do bisection instead of linear search */\n   while (pos<tb->filled && timing >= tb->timing[pos])\n   {\n      pos++;\n   }\n   \n   speex_assert(pos <= tb->filled && pos < MAX_TIMINGS);\n   \n   /* Shift everything so we can perform the insertion */\n   if (pos < tb->filled)\n   {\n      int move_size = tb->filled-pos;\n      if (tb->filled == MAX_TIMINGS)\n         move_size -= 1;\n      SPEEX_MOVE(&tb->timing[pos+1], &tb->timing[pos], move_size);\n      SPEEX_MOVE(&tb->counts[pos+1], &tb->counts[pos], move_size);\n   }\n   /* Insert */\n   tb->timing[pos] = timing;\n   tb->counts[pos] = tb->curr_count;\n   \n   tb->curr_count++;\n   if (tb->filled<MAX_TIMINGS)\n      tb->filled++;\n}\n\n\n\n/** Jitter buffer structure */\nstruct JitterBuffer_ {\n   spx_uint32_t pointer_timestamp;                             /**< Timestamp of what we will *get* next */\n   spx_uint32_t last_returned_timestamp;                       /**< Useful for getting the next packet with the same timestamp (for fragmented media) */\n   spx_uint32_t next_stop;                                     /**< Estimated time the next get() will be called */\n   \n   spx_int32_t buffered;                                       /**< Amount of data we think is still buffered by the application (timestamp units)*/\n   \n   JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE];   /**< Packets stored in the buffer */\n   spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE];         /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */\n   \n   void (*destroy) (void *);                                   /**< Callback for destroying a packet */\n\n   spx_int32_t delay_step;                                     /**< Size of the steps when adjusting buffering (timestamp units) */\n   spx_int32_t concealment_size;                               /**< Size of the packet loss concealment \"units\" */\n   int reset_state;                                            /**< True if state was just reset        */\n   int buffer_margin;                                          /**< How many frames we want to keep in the buffer (lower bound) */\n   int late_cutoff;                                            /**< How late must a packet be for it not to be considered at all */\n   int interp_requested;                                       /**< An interpolation is requested by speex_jitter_update_delay() */\n   int auto_adjust;                                            /**< Whether to automatically adjust the delay at any time */\n   \n   struct TimingBuffer _tb[MAX_BUFFERS];                       /**< Don't use those directly */\n   struct TimingBuffer *timeBuffers[MAX_BUFFERS];              /**< Storing arrival time of latest frames so we can compute some stats */\n   int window_size;                                            /**< Total window over which the late frames are counted */\n   int subwindow_size;                                         /**< Sub-window size for faster computation  */\n   int max_late_rate;                                          /**< Absolute maximum amount of late packets tolerable (in percent) */\n   int latency_tradeoff;                                       /**< Latency equivalent of losing one percent of packets */\n   int auto_tradeoff;                                          /**< Latency equivalent of losing one percent of packets (automatic default) */\n   \n   int lost_count;                                             /**< Number of consecutive lost packets  */\n};\n\n/** Based on available data, this computes the optimal delay for the jitter buffer. \n   The optimised function is in timestamp units and is:\n   cost = delay + late_factor*[number of frames that would be late if we used that delay]\n   @param tb Array of buffers\n   @param late_factor Equivalent cost of a late frame (in timestamp units) \n */\nstatic spx_int16_t compute_opt_delay(JitterBuffer *jitter)\n{\n   int i;\n   spx_int16_t opt=0;\n   spx_int32_t best_cost=0x7fffffff;\n   int late = 0;\n   int pos[MAX_BUFFERS];\n   int tot_count;\n   float late_factor;\n   int penalty_taken = 0;\n   int best = 0;\n   int worst = 0;\n   spx_int32_t deltaT;\n   struct TimingBuffer *tb;\n   \n   tb = jitter->_tb;\n   \n   /* Number of packet timings we have received (including those we didn't keep) */\n   tot_count = 0;\n   for (i=0;i<MAX_BUFFERS;i++)\n      tot_count += tb[i].curr_count;\n   if (tot_count==0)\n      return 0;\n   \n   /* Compute cost for one lost packet */\n   if (jitter->latency_tradeoff != 0)\n      late_factor = jitter->latency_tradeoff * 100.0f / tot_count;\n   else\n      late_factor = jitter->auto_tradeoff * jitter->window_size/tot_count;\n   \n   /*fprintf(stderr, \"late_factor = %f\\n\", late_factor);*/\n   for (i=0;i<MAX_BUFFERS;i++)\n      pos[i] = 0;\n   \n   /* Pick the TOP_DELAY \"latest\" packets (doesn't need to actually be late \n      for the current settings) */\n   for (i=0;i<TOP_DELAY;i++)\n   {\n      int j;\n      int next=-1;\n      int latest = 32767;\n      /* Pick latest amoung all sub-windows */\n      for (j=0;j<MAX_BUFFERS;j++)\n      {\n         if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest)\n         {\n            next = j;\n            latest = tb[j].timing[pos[j]];\n         }\n      }\n      if (next != -1)\n      {\n         spx_int32_t cost;\n         \n         if (i==0)\n            worst = latest;\n         best = latest;\n         latest = ROUND_DOWN(latest, jitter->delay_step);\n         pos[next]++;\n         \n         /* Actual cost function that tells us how bad using this delay would be */\n         cost = -latest + late_factor*late;\n         /*fprintf(stderr, \"cost %d = %d + %f * %d\\n\", cost, -latest, late_factor, late);*/\n         if (cost < best_cost)\n         {\n            best_cost = cost;\n            opt = latest;\n         }\n      } else {\n         break;\n      }\n      \n      /* For the next timing we will consider, there will be one more late packet to count */\n      late++;\n      /* Two-frame penalty if we're going to increase the amount of late frames (hysteresis) */\n      if (latest >= 0 && !penalty_taken)\n      {\n         penalty_taken = 1;\n         late+=4;\n      }\n   }\n   \n   deltaT = best-worst;\n   /* This is a default \"automatic latency tradeoff\" when none is provided */\n   jitter->auto_tradeoff = 1 + deltaT/TOP_DELAY;\n   /*fprintf(stderr, \"auto_tradeoff = %d (%d %d %d)\\n\", jitter->auto_tradeoff, best, worst, i);*/\n   \n   /* FIXME: Compute a short-term estimate too and combine with the long-term one */\n   \n   /* Prevents reducing the buffer size when we haven't really had much data */\n   if (tot_count < TOP_DELAY && opt > 0)\n      return 0;\n   return opt;\n}\n\n\n/** Initialise jitter buffer */\nEXPORT JitterBuffer *jitter_buffer_init(int step_size)\n{\n   JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer));\n   if (jitter)\n   {\n      int i;\n      spx_int32_t tmp;\n      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)\n         jitter->packets[i].data=NULL;\n      jitter->delay_step = step_size;\n      jitter->concealment_size = step_size;\n      /*FIXME: Should this be 0 or 1?*/\n      jitter->buffer_margin = 0;\n      jitter->late_cutoff = 50;\n      jitter->destroy = NULL;\n      jitter->latency_tradeoff = 0;\n      jitter->auto_adjust = 1;\n      tmp = 4;\n      jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp);\n      jitter_buffer_reset(jitter);\n   }\n   return jitter;\n}\n\n/** Reset jitter buffer */\nEXPORT void jitter_buffer_reset(JitterBuffer *jitter)\n{\n   int i;\n   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)\n   {\n      if (jitter->packets[i].data)\n      {\n         if (jitter->destroy)\n            jitter->destroy(jitter->packets[i].data);\n         else\n            speex_free(jitter->packets[i].data);\n         jitter->packets[i].data = NULL;\n      }\n   }\n   /* Timestamp is actually undefined at this point */\n   jitter->pointer_timestamp = 0;\n   jitter->next_stop = 0;\n   jitter->reset_state = 1;\n   jitter->lost_count = 0;\n   jitter->buffered = 0;\n   jitter->auto_tradeoff = 32000;\n   \n   for (i=0;i<MAX_BUFFERS;i++)\n   {\n      tb_init(&jitter->_tb[i]);\n      jitter->timeBuffers[i] = &jitter->_tb[i];\n   }\n   /*fprintf (stderr, \"reset\\n\");*/\n}\n\n/** Destroy jitter buffer */\nEXPORT void jitter_buffer_destroy(JitterBuffer *jitter)\n{\n   jitter_buffer_reset(jitter);\n   speex_free(jitter);\n}\n\n/** Take the following timing into consideration for future calculations */\nstatic void update_timings(JitterBuffer *jitter, spx_int32_t timing)\n{\n   if (timing < -32767)\n      timing = -32767;\n   if (timing > 32767)\n      timing = 32767;\n   /* If the current sub-window is full, perform a rotation and discard oldest sub-widow */\n   if (jitter->timeBuffers[0]->curr_count >= jitter->subwindow_size)\n   {\n      int i;\n      /*fprintf(stderr, \"Rotate buffer\\n\");*/\n      struct TimingBuffer *tmp = jitter->timeBuffers[MAX_BUFFERS-1];\n      for (i=MAX_BUFFERS-1;i>=1;i--)\n         jitter->timeBuffers[i] = jitter->timeBuffers[i-1];\n      jitter->timeBuffers[0] = tmp;\n      tb_init(jitter->timeBuffers[0]);\n   }\n   tb_add(jitter->timeBuffers[0], timing);\n}\n\n/** Compensate all timings when we do an adjustment of the buffering */\nstatic void shift_timings(JitterBuffer *jitter, spx_int16_t amount)\n{\n   int i, j;\n   for (i=0;i<MAX_BUFFERS;i++)\n   {\n      for (j=0;j<jitter->timeBuffers[i]->filled;j++)\n         jitter->timeBuffers[i]->timing[j] += amount;\n   }\n}\n\n\n/** Put one packet into the jitter buffer */\nEXPORT void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)\n{\n   int i,j;\n   int late;\n   /*fprintf (stderr, \"put packet %d %d\\n\", timestamp, span);*/\n   \n   /* Cleanup buffer (remove old packets that weren't played) */\n   if (!jitter->reset_state)\n   {\n      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)\n      {\n         /* Make sure we don't discard a \"just-late\" packet in case we want to play it next (if we interpolate). */\n         if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp))\n         {\n            /*fprintf (stderr, \"cleaned (not played)\\n\");*/\n            if (jitter->destroy)\n               jitter->destroy(jitter->packets[i].data);\n            else\n               speex_free(jitter->packets[i].data);\n            jitter->packets[i].data = NULL;\n         }\n      }\n   }\n   \n   /*fprintf(stderr, \"arrival: %d %d %d\\n\", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/\n   /* Check if packet is late (could still be useful though) */\n   if (!jitter->reset_state && LT32(packet->timestamp, jitter->next_stop))\n   {\n      update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin);\n      late = 1;\n   } else {\n      late = 0;\n   }\n\n   /* For some reason, the consumer has failed the last 20 fetches. Make sure this packet is\n    * used to resync. */\n   if (jitter->lost_count>20)\n   {\n      jitter_buffer_reset(jitter);\n   }\n   \n   /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */\n   if (jitter->reset_state || GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp))\n   {\n\n      /*Find an empty slot in the buffer*/\n      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)\n      {\n         if (jitter->packets[i].data==NULL)\n            break;\n      }\n      \n      /*No place left in the buffer, need to make room for it by discarding the oldest packet */\n      if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)\n      {\n         int earliest=jitter->packets[0].timestamp;\n         i=0;\n         for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)\n         {\n            if (!jitter->packets[i].data || LT32(jitter->packets[j].timestamp,earliest))\n            {\n               earliest = jitter->packets[j].timestamp;\n               i=j;\n            }\n         }\n         if (jitter->destroy)\n            jitter->destroy(jitter->packets[i].data);\n         else\n            speex_free(jitter->packets[i].data);\n         jitter->packets[i].data=NULL;\n         /*fprintf (stderr, \"Buffer is full, discarding earliest frame %d (currently at %d)\\n\", timestamp, jitter->pointer_timestamp);*/      \n      }\n   \n      /* Copy packet in buffer */\n      if (jitter->destroy)\n      {\n         jitter->packets[i].data = packet->data;\n      } else {\n         jitter->packets[i].data=(char*)speex_alloc(packet->len);\n         for (j=0;j<packet->len;j++)\n            jitter->packets[i].data[j]=packet->data[j];\n      }\n      jitter->packets[i].timestamp=packet->timestamp;\n      jitter->packets[i].span=packet->span;\n      jitter->packets[i].len=packet->len;\n      jitter->packets[i].sequence=packet->sequence;\n      jitter->packets[i].user_data=packet->user_data;\n      if (jitter->reset_state || late)\n         jitter->arrival[i] = 0;\n      else\n         jitter->arrival[i] = jitter->next_stop;\n   }\n   \n   \n}\n\n/** Get one packet from the jitter buffer */\nEXPORT int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset)\n{\n   int i;\n   unsigned int j;\n   int incomplete = 0;\n   spx_int16_t opt;\n   \n   if (start_offset != NULL)\n      *start_offset = 0;\n\n   /* Syncing on the first call */\n   if (jitter->reset_state)\n   {\n      int found = 0;\n      /* Find the oldest packet */\n      spx_uint32_t oldest=0;\n      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)\n      {\n         if (jitter->packets[i].data && (!found || LT32(jitter->packets[i].timestamp,oldest)))\n         {\n            oldest = jitter->packets[i].timestamp;\n            found = 1;\n         }\n      }\n      if (found)\n      {\n         jitter->reset_state=0;         \n         jitter->pointer_timestamp = oldest;\n         jitter->next_stop = oldest;\n      } else {\n         packet->timestamp = 0;\n         packet->span = jitter->interp_requested;\n         return JITTER_BUFFER_MISSING;\n      }\n   }\n   \n\n   jitter->last_returned_timestamp = jitter->pointer_timestamp;\n         \n   if (jitter->interp_requested != 0)\n   {\n      packet->timestamp = jitter->pointer_timestamp;\n      packet->span = jitter->interp_requested;\n      \n      /* Increment the pointer because it got decremented in the delay update */\n      jitter->pointer_timestamp += jitter->interp_requested;\n      packet->len = 0;\n      /*fprintf (stderr, \"Deferred interpolate\\n\");*/\n      \n      jitter->interp_requested = 0;\n      \n      jitter->buffered = packet->span - desired_span;\n\n      return JITTER_BUFFER_INSERTION;\n   }\n   \n   /* Searching for the packet that fits best */\n   \n   /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */\n   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)\n   {\n      if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->pointer_timestamp && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span))\n         break;\n   }\n   \n   /* If no match, try for an \"older\" packet that still spans (fully) the current chunk */\n   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)\n   {\n      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)\n      {\n         if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span))\n            break;\n      }\n   }\n   \n   /* If still no match, try for an \"older\" packet that spans part of the current chunk */\n   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)\n   {\n      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)\n      {\n         if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GT32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp))\n            break;\n      }\n   }\n   \n   /* If still no match, try for earliest packet possible */\n   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)\n   {\n      int found = 0;\n      spx_uint32_t best_time=0;\n      int best_span=0;\n      int besti=0;\n      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)\n      {\n         /* check if packet starts within current chunk */\n         if (jitter->packets[i].data && LT32(jitter->packets[i].timestamp,jitter->pointer_timestamp+desired_span) && GE32(jitter->packets[i].timestamp,jitter->pointer_timestamp))\n         {\n            if (!found || LT32(jitter->packets[i].timestamp,best_time) || (jitter->packets[i].timestamp==best_time && GT32(jitter->packets[i].span,best_span)))\n            {\n               best_time = jitter->packets[i].timestamp;\n               best_span = jitter->packets[i].span;\n               besti = i;\n               found = 1;\n            }\n         }\n      }\n      if (found)\n      {\n         i=besti;\n         incomplete = 1;\n         /*fprintf (stderr, \"incomplete: %d %d %d %d\\n\", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span);*/\n      }\n   }\n\n   /* If we find something */\n   if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)\n   {\n      spx_int32_t offset;\n      \n      /* We (obviously) haven't lost this packet */\n      jitter->lost_count = 0;\n      \n      /* In this case, 0 isn't as a valid timestamp */\n      if (jitter->arrival[i] != 0)\n      {\n         update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]) - jitter->buffer_margin);\n      }\n      \n      \n      /* Copy packet */\n      if (jitter->destroy)\n      {\n         packet->data = jitter->packets[i].data;\n         packet->len = jitter->packets[i].len;\n      } else {\n         if (jitter->packets[i].len > packet->len)\n         {\n            speex_warning_int(\"jitter_buffer_get(): packet too large to fit. Size is\", jitter->packets[i].len);\n         } else {\n            packet->len = jitter->packets[i].len;\n         }\n         for (j=0;j<packet->len;j++)\n            packet->data[j] = jitter->packets[i].data[j];\n         /* Remove packet */\n         speex_free(jitter->packets[i].data);\n      }\n      jitter->packets[i].data = NULL;\n      /* Set timestamp and span (if requested) */\n      offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp;\n      if (start_offset != NULL)\n         *start_offset = offset;\n      else if (offset != 0)\n         speex_warning_int(\"jitter_buffer_get() discarding non-zero start_offset\", offset);\n      \n      packet->timestamp = jitter->packets[i].timestamp;\n      jitter->last_returned_timestamp = packet->timestamp;\n      \n      packet->span = jitter->packets[i].span;\n      packet->sequence = jitter->packets[i].sequence;\n      packet->user_data = jitter->packets[i].user_data;\n      /* Point to the end of the current packet */\n      jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span;\n\n      jitter->buffered = packet->span - desired_span;\n      \n      if (start_offset != NULL)\n         jitter->buffered += *start_offset;\n      \n      return JITTER_BUFFER_OK;\n   }\n   \n   \n   /* If we haven't found anything worth returning */\n   \n   /*fprintf (stderr, \"not found\\n\");*/\n   jitter->lost_count++;\n   /*fprintf (stderr, \"m\");*/\n   /*fprintf (stderr, \"lost_count = %d\\n\", jitter->lost_count);*/\n   \n   opt = compute_opt_delay(jitter);\n   \n   /* Should we force an increase in the buffer or just do normal interpolation? */   \n   if (opt < 0)\n   {\n      /* Need to increase buffering */\n      \n      /* Shift histogram to compensate */\n      shift_timings(jitter, -opt);\n      \n      packet->timestamp = jitter->pointer_timestamp;\n      packet->span = -opt;\n      /* Don't move the pointer_timestamp forward */\n      packet->len = 0;\n      \n      jitter->buffered = packet->span - desired_span;\n      return JITTER_BUFFER_INSERTION;\n      /*jitter->pointer_timestamp -= jitter->delay_step;*/\n      /*fprintf (stderr, \"Forced to interpolate\\n\");*/\n   } else {\n      /* Normal packet loss */\n      packet->timestamp = jitter->pointer_timestamp;\n      \n      desired_span = ROUND_DOWN(desired_span, jitter->concealment_size);\n      packet->span = desired_span;\n      jitter->pointer_timestamp += desired_span;\n      packet->len = 0;\n      \n      jitter->buffered = packet->span - desired_span;\n      return JITTER_BUFFER_MISSING;\n      /*fprintf (stderr, \"Normal loss\\n\");*/\n   }\n\n\n}\n\nEXPORT int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet)\n{\n   int i, j;\n   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)\n   {\n      if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->last_returned_timestamp)\n         break;\n   }\n   if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)\n   {\n      /* Copy packet */\n      packet->len = jitter->packets[i].len;\n      if (jitter->destroy)\n      {\n         packet->data = jitter->packets[i].data;\n      } else {\n         for (j=0;j<packet->len;j++)\n            packet->data[j] = jitter->packets[i].data[j];\n         /* Remove packet */\n         speex_free(jitter->packets[i].data);\n      }\n      jitter->packets[i].data = NULL;\n      packet->timestamp = jitter->packets[i].timestamp;\n      packet->span = jitter->packets[i].span;\n      packet->sequence = jitter->packets[i].sequence;\n      packet->user_data = jitter->packets[i].user_data;\n      return JITTER_BUFFER_OK;\n   } else {\n      packet->data = NULL;\n      packet->len = 0;\n      packet->span = 0;\n      return JITTER_BUFFER_MISSING;\n   }\n}\n\n/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */\nstatic int _jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)\n{\n   spx_int16_t opt = compute_opt_delay(jitter);\n   /*fprintf(stderr, \"opt adjustment is %d \", opt);*/\n   \n   if (opt < 0)\n   {\n      shift_timings(jitter, -opt);\n      \n      jitter->pointer_timestamp += opt;\n      jitter->interp_requested = -opt;\n      /*fprintf (stderr, \"Decision to interpolate %d samples\\n\", -opt);*/\n   } else if (opt > 0)\n   {\n      shift_timings(jitter, -opt);\n      jitter->pointer_timestamp += opt;\n      /*fprintf (stderr, \"Decision to drop %d samples\\n\", opt);*/\n   }\n   \n   return opt;\n}\n\n/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */\nEXPORT int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)\n{\n   /* If the programmer calls jitter_buffer_update_delay() directly, \n      automatically disable auto-adjustment */\n   jitter->auto_adjust = 0;\n\n   return _jitter_buffer_update_delay(jitter, packet, start_offset);\n}\n\n/** Get pointer timestamp of jitter buffer */\nEXPORT int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter)\n{\n   return jitter->pointer_timestamp;\n}\n\nEXPORT void jitter_buffer_tick(JitterBuffer *jitter)\n{\n   /* Automatically-adjust the buffering delay if requested */\n   if (jitter->auto_adjust)\n      _jitter_buffer_update_delay(jitter, NULL, NULL);\n   \n   if (jitter->buffered >= 0)\n   {\n      jitter->next_stop = jitter->pointer_timestamp - jitter->buffered;\n   } else {\n      jitter->next_stop = jitter->pointer_timestamp;\n      speex_warning_int(\"jitter buffer sees negative buffering, your code might be broken. Value is \", jitter->buffered);\n   }\n   jitter->buffered = 0;\n}\n\nEXPORT void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem)\n{\n   /* Automatically-adjust the buffering delay if requested */\n   if (jitter->auto_adjust)\n      _jitter_buffer_update_delay(jitter, NULL, NULL);\n   \n   if (jitter->buffered < 0)\n      speex_warning_int(\"jitter buffer sees negative buffering, your code might be broken. Value is \", jitter->buffered);\n   jitter->next_stop = jitter->pointer_timestamp - rem;\n}\n\n\n/* Used like the ioctl function to control the jitter buffer parameters */\nEXPORT int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr)\n{\n   int count, i;\n   switch(request)\n   {\n      case JITTER_BUFFER_SET_MARGIN:\n         jitter->buffer_margin = *(spx_int32_t*)ptr;\n         break;\n      case JITTER_BUFFER_GET_MARGIN:\n         *(spx_int32_t*)ptr = jitter->buffer_margin;\n         break;\n      case JITTER_BUFFER_GET_AVALIABLE_COUNT:\n         count = 0;\n         for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)\n         {\n            if (jitter->packets[i].data && LE32(jitter->pointer_timestamp, jitter->packets[i].timestamp))\n            {\n               count++;\n            }\n         }\n         *(spx_int32_t*)ptr = count;\n         break;\n      case JITTER_BUFFER_SET_DESTROY_CALLBACK:\n         jitter->destroy = (void (*) (void *))ptr;\n         break;\n      case JITTER_BUFFER_GET_DESTROY_CALLBACK:\n         *(void (**) (void *))ptr = jitter->destroy;\n         break;\n      case JITTER_BUFFER_SET_DELAY_STEP:\n         jitter->delay_step = *(spx_int32_t*)ptr;\n         break;\n      case JITTER_BUFFER_GET_DELAY_STEP:\n         *(spx_int32_t*)ptr = jitter->delay_step;\n         break;\n      case JITTER_BUFFER_SET_CONCEALMENT_SIZE:\n         jitter->concealment_size = *(spx_int32_t*)ptr;\n         break;\n      case JITTER_BUFFER_GET_CONCEALMENT_SIZE:\n         *(spx_int32_t*)ptr = jitter->concealment_size;\n         break;\n      case JITTER_BUFFER_SET_MAX_LATE_RATE:\n         jitter->max_late_rate = *(spx_int32_t*)ptr;\n         jitter->window_size = 100*TOP_DELAY/jitter->max_late_rate;\n         jitter->subwindow_size = jitter->window_size/MAX_BUFFERS;\n         break;\n      case JITTER_BUFFER_GET_MAX_LATE_RATE:\n         *(spx_int32_t*)ptr = jitter->max_late_rate;\n         break;\n      case JITTER_BUFFER_SET_LATE_COST:\n         jitter->latency_tradeoff = *(spx_int32_t*)ptr;\n         break;\n      case JITTER_BUFFER_GET_LATE_COST:\n         *(spx_int32_t*)ptr = jitter->latency_tradeoff;\n         break;\n      default:\n         speex_warning_int(\"Unknown jitter_buffer_ctl request: \", request);\n         return -1;\n   }\n   return 0;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/kiss_fft.c",
    "content": "/*\nCopyright (c) 2003-2004, Mark Borgerding\nCopyright (c) 2005-2007, Jean-Marc Valin\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"_kiss_fft_guts.h\"\n#include \"arch.h\"\n#include \"os_support.h\"\n\n/* The guts header contains all the multiplication and addition macros that are defined for\n fixed or floating point complex numbers.  It also delares the kf_ internal functions.\n */\n\nstatic void kf_bfly2(\n        kiss_fft_cpx * Fout,\n        const size_t fstride,\n        const kiss_fft_cfg st,\n        int m,\n        int N,\n        int mm\n        )\n{\n    kiss_fft_cpx * Fout2;\n    kiss_fft_cpx * tw1;\n    kiss_fft_cpx t;\n    if (!st->inverse) {\n       int i,j;\n       kiss_fft_cpx * Fout_beg = Fout;\n       for (i=0;i<N;i++)\n       {\n          Fout = Fout_beg + i*mm;\n          Fout2 = Fout + m;\n          tw1 = st->twiddles;\n          for(j=0;j<m;j++)\n          {\n             /* Almost the same as the code path below, except that we divide the input by two\n              (while keeping the best accuracy possible) */\n             spx_word32_t tr, ti;\n             tr = SHR32(SUB32(MULT16_16(Fout2->r , tw1->r),MULT16_16(Fout2->i , tw1->i)), 1);\n             ti = SHR32(ADD32(MULT16_16(Fout2->i , tw1->r),MULT16_16(Fout2->r , tw1->i)), 1);\n             tw1 += fstride;\n             Fout2->r = PSHR32(SUB32(SHL32(EXTEND32(Fout->r), 14), tr), 15);\n             Fout2->i = PSHR32(SUB32(SHL32(EXTEND32(Fout->i), 14), ti), 15);\n             Fout->r = PSHR32(ADD32(SHL32(EXTEND32(Fout->r), 14), tr), 15);\n             Fout->i = PSHR32(ADD32(SHL32(EXTEND32(Fout->i), 14), ti), 15);\n             ++Fout2;\n             ++Fout;\n          }\n       }\n    } else {\n       int i,j;\n       kiss_fft_cpx * Fout_beg = Fout;\n       for (i=0;i<N;i++)\n       {\n          Fout = Fout_beg + i*mm;\n          Fout2 = Fout + m;\n          tw1 = st->twiddles;\n          for(j=0;j<m;j++)\n          {\n             C_MUL (t,  *Fout2 , *tw1);\n             tw1 += fstride;\n             C_SUB( *Fout2 ,  *Fout , t );\n             C_ADDTO( *Fout ,  t );\n             ++Fout2;\n             ++Fout;\n          }\n       }\n    }\n}\n\nstatic void kf_bfly4(\n        kiss_fft_cpx * Fout,\n        const size_t fstride,\n        const kiss_fft_cfg st,\n        int m,\n        int N,\n        int mm\n        )\n{\n    kiss_fft_cpx *tw1,*tw2,*tw3;\n    kiss_fft_cpx scratch[6];\n    const size_t m2=2*m;\n    const size_t m3=3*m;\n    int i, j;\n\n    if (st->inverse)\n    {\n       kiss_fft_cpx * Fout_beg = Fout;\n       for (i=0;i<N;i++)\n       {\n          Fout = Fout_beg + i*mm;\n          tw3 = tw2 = tw1 = st->twiddles;\n          for (j=0;j<m;j++)\n          {\n             C_MUL(scratch[0],Fout[m] , *tw1 );\n             C_MUL(scratch[1],Fout[m2] , *tw2 );\n             C_MUL(scratch[2],Fout[m3] , *tw3 );\n             \n             C_SUB( scratch[5] , *Fout, scratch[1] );\n             C_ADDTO(*Fout, scratch[1]);\n             C_ADD( scratch[3] , scratch[0] , scratch[2] );\n             C_SUB( scratch[4] , scratch[0] , scratch[2] );\n             C_SUB( Fout[m2], *Fout, scratch[3] );\n             tw1 += fstride;\n             tw2 += fstride*2;\n             tw3 += fstride*3;\n             C_ADDTO( *Fout , scratch[3] );\n             \n             Fout[m].r = scratch[5].r - scratch[4].i;\n             Fout[m].i = scratch[5].i + scratch[4].r;\n             Fout[m3].r = scratch[5].r + scratch[4].i;\n             Fout[m3].i = scratch[5].i - scratch[4].r;\n             ++Fout;\n          }\n       }\n    } else\n    {\n       kiss_fft_cpx * Fout_beg = Fout;\n       for (i=0;i<N;i++)\n       {\n          Fout = Fout_beg + i*mm;\n          tw3 = tw2 = tw1 = st->twiddles;\n          for (j=0;j<m;j++)\n          {\n             C_MUL4(scratch[0],Fout[m] , *tw1 );\n             C_MUL4(scratch[1],Fout[m2] , *tw2 );\n             C_MUL4(scratch[2],Fout[m3] , *tw3 );\n             \n             Fout->r = PSHR16(Fout->r, 2);\n             Fout->i = PSHR16(Fout->i, 2);\n             C_SUB( scratch[5] , *Fout, scratch[1] );\n             C_ADDTO(*Fout, scratch[1]);\n             C_ADD( scratch[3] , scratch[0] , scratch[2] );\n             C_SUB( scratch[4] , scratch[0] , scratch[2] );\n             Fout[m2].r = PSHR16(Fout[m2].r, 2);\n             Fout[m2].i = PSHR16(Fout[m2].i, 2);\n             C_SUB( Fout[m2], *Fout, scratch[3] );\n             tw1 += fstride;\n             tw2 += fstride*2;\n             tw3 += fstride*3;\n             C_ADDTO( *Fout , scratch[3] );\n             \n             Fout[m].r = scratch[5].r + scratch[4].i;\n             Fout[m].i = scratch[5].i - scratch[4].r;\n             Fout[m3].r = scratch[5].r - scratch[4].i;\n             Fout[m3].i = scratch[5].i + scratch[4].r;\n             ++Fout;\n          }\n       }\n    }\n}\n\nstatic void kf_bfly3(\n         kiss_fft_cpx * Fout,\n         const size_t fstride,\n         const kiss_fft_cfg st,\n         size_t m\n         )\n{\n     size_t k=m;\n     const size_t m2 = 2*m;\n     kiss_fft_cpx *tw1,*tw2;\n     kiss_fft_cpx scratch[5];\n     kiss_fft_cpx epi3;\n     epi3 = st->twiddles[fstride*m];\n\n     tw1=tw2=st->twiddles;\n\n     do{\n        if (!st->inverse) {\n         C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);\n\t}\n\n         C_MUL(scratch[1],Fout[m] , *tw1);\n         C_MUL(scratch[2],Fout[m2] , *tw2);\n\n         C_ADD(scratch[3],scratch[1],scratch[2]);\n         C_SUB(scratch[0],scratch[1],scratch[2]);\n         tw1 += fstride;\n         tw2 += fstride*2;\n\n         Fout[m].r = Fout->r - HALF_OF(scratch[3].r);\n         Fout[m].i = Fout->i - HALF_OF(scratch[3].i);\n\n         C_MULBYSCALAR( scratch[0] , epi3.i );\n\n         C_ADDTO(*Fout,scratch[3]);\n\n         Fout[m2].r = Fout[m].r + scratch[0].i;\n         Fout[m2].i = Fout[m].i - scratch[0].r;\n\n         Fout[m].r -= scratch[0].i;\n         Fout[m].i += scratch[0].r;\n\n         ++Fout;\n     }while(--k);\n}\n\nstatic void kf_bfly5(\n        kiss_fft_cpx * Fout,\n        const size_t fstride,\n        const kiss_fft_cfg st,\n        int m\n        )\n{\n    kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;\n    int u;\n    kiss_fft_cpx scratch[13];\n    kiss_fft_cpx * twiddles = st->twiddles;\n    kiss_fft_cpx *tw;\n    kiss_fft_cpx ya,yb;\n    ya = twiddles[fstride*m];\n    yb = twiddles[fstride*2*m];\n\n    Fout0=Fout;\n    Fout1=Fout0+m;\n    Fout2=Fout0+2*m;\n    Fout3=Fout0+3*m;\n    Fout4=Fout0+4*m;\n\n    tw=st->twiddles;\n    for ( u=0; u<m; ++u ) {\n        if (!st->inverse) {\n        C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);\n\t}\n        scratch[0] = *Fout0;\n\n        C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);\n        C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);\n        C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);\n        C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);\n\n        C_ADD( scratch[7],scratch[1],scratch[4]);\n        C_SUB( scratch[10],scratch[1],scratch[4]);\n        C_ADD( scratch[8],scratch[2],scratch[3]);\n        C_SUB( scratch[9],scratch[2],scratch[3]);\n\n        Fout0->r += scratch[7].r + scratch[8].r;\n        Fout0->i += scratch[7].i + scratch[8].i;\n\n        scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);\n        scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);\n\n        scratch[6].r =  S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);\n        scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);\n\n        C_SUB(*Fout1,scratch[5],scratch[6]);\n        C_ADD(*Fout4,scratch[5],scratch[6]);\n\n        scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);\n        scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);\n        scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);\n        scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);\n\n        C_ADD(*Fout2,scratch[11],scratch[12]);\n        C_SUB(*Fout3,scratch[11],scratch[12]);\n\n        ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;\n    }\n}\n\n/* perform the butterfly for one stage of a mixed radix FFT */\nstatic void kf_bfly_generic(\n        kiss_fft_cpx * Fout,\n        const size_t fstride,\n        const kiss_fft_cfg st,\n        int m,\n        int p\n        )\n{\n    int u,k,q1,q;\n    kiss_fft_cpx * twiddles = st->twiddles;\n    kiss_fft_cpx t;\n    kiss_fft_cpx scratchbuf[17];\n    int Norig = st->nfft;\n\n    /*CHECKBUF(scratchbuf,nscratchbuf,p);*/\n    if (p>17)\n       speex_fatal(\"KissFFT: max radix supported is 17\");\n    \n    for ( u=0; u<m; ++u ) {\n        k=u;\n        for ( q1=0 ; q1<p ; ++q1 ) {\n            scratchbuf[q1] = Fout[ k  ];\n        if (!st->inverse) {\n            C_FIXDIV(scratchbuf[q1],p);\n\t}\n            k += m;\n        }\n\n        k=u;\n        for ( q1=0 ; q1<p ; ++q1 ) {\n            int twidx=0;\n            Fout[ k ] = scratchbuf[0];\n            for (q=1;q<p;++q ) {\n                twidx += fstride * k;\n                if (twidx>=Norig) twidx-=Norig;\n                C_MUL(t,scratchbuf[q] , twiddles[twidx] );\n                C_ADDTO( Fout[ k ] ,t);\n            }\n            k += m;\n        }\n    }\n}\n               \nstatic\nvoid kf_shuffle(\n         kiss_fft_cpx * Fout,\n         const kiss_fft_cpx * f,\n         const size_t fstride,\n         int in_stride,\n         int * factors,\n         const kiss_fft_cfg st\n            )\n{\n   const int p=*factors++; /* the radix  */\n   const int m=*factors++; /* stage's fft length/p */\n   \n    /*printf (\"fft %d %d %d %d %d %d\\n\", p*m, m, p, s2, fstride*in_stride, N);*/\n   if (m==1)\n   {\n      int j;\n      for (j=0;j<p;j++)\n      {\n         Fout[j] = *f;\n         f += fstride*in_stride;\n      }\n   } else {\n      int j;\n      for (j=0;j<p;j++)\n      {\n         kf_shuffle( Fout , f, fstride*p, in_stride, factors,st);\n         f += fstride*in_stride;\n         Fout += m;\n      }\n   }\n}\n\nstatic\nvoid kf_work(\n        kiss_fft_cpx * Fout,\n        const kiss_fft_cpx * f,\n        const size_t fstride,\n        int in_stride,\n        int * factors,\n        const kiss_fft_cfg st,\n        int N,\n        int s2,\n        int m2\n        )\n{\n   int i;\n    kiss_fft_cpx * Fout_beg=Fout;\n    const int p=*factors++; /* the radix  */\n    const int m=*factors++; /* stage's fft length/p */\n#if 0\n    /*printf (\"fft %d %d %d %d %d %d\\n\", p*m, m, p, s2, fstride*in_stride, N);*/\n    if (m==1)\n    {\n    /*   int j;\n       for (j=0;j<p;j++)\n       {\n          Fout[j] = *f;\n          f += fstride*in_stride;\n       }*/\n    } else {\n       int j;\n       for (j=0;j<p;j++)\n       {\n          kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m);\n          f += fstride*in_stride;\n          Fout += m;\n       }\n    }\n\n    Fout=Fout_beg;\n\n    switch (p) {\n        case 2: kf_bfly2(Fout,fstride,st,m); break;\n        case 3: kf_bfly3(Fout,fstride,st,m); break; \n        case 4: kf_bfly4(Fout,fstride,st,m); break;\n        case 5: kf_bfly5(Fout,fstride,st,m); break; \n        default: kf_bfly_generic(Fout,fstride,st,m,p); break;\n    }\n#else\n    /*printf (\"fft %d %d %d %d %d %d %d\\n\", p*m, m, p, s2, fstride*in_stride, N, m2);*/\n    if (m==1) \n    {\n       /*for (i=0;i<N;i++)\n       {\n          int j;\n          Fout = Fout_beg+i*m2;\n          const kiss_fft_cpx * f2 = f+i*s2;\n          for (j=0;j<p;j++)\n          {\n             *Fout++ = *f2;\n             f2 += fstride*in_stride;\n          }\n       }*/\n    }else{\n       kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m);\n    }\n\n    \n       \n       \n       switch (p) {\n          case 2: kf_bfly2(Fout,fstride,st,m, N, m2); break;\n          case 3: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly3(Fout,fstride,st,m);} break; \n          case 4: kf_bfly4(Fout,fstride,st,m, N, m2); break;\n          case 5: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly5(Fout,fstride,st,m);} break; \n          default: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly_generic(Fout,fstride,st,m,p);} break;\n    }    \n#endif\n}\n\n/*  facbuf is populated by p1,m1,p2,m2, ...\n    where \n    p[i] * m[i] = m[i-1]\n    m0 = n                  */\nstatic \nvoid kf_factor(int n,int * facbuf)\n{\n    int p=4;\n\n    /*factor out powers of 4, powers of 2, then any remaining primes */\n    do {\n        while (n % p) {\n            switch (p) {\n                case 4: p = 2; break;\n                case 2: p = 3; break;\n                default: p += 2; break;\n            }\n            if (p>32000 || (spx_int32_t)p*(spx_int32_t)p > n)\n                p = n;          /* no more factors, skip to end */\n        }\n        n /= p;\n        *facbuf++ = p;\n        *facbuf++ = n;\n    } while (n > 1);\n}\n/*\n *\n * User-callable function to allocate all necessary storage space for the fft.\n *\n * The return value is a contiguous block of memory, allocated with malloc.  As such,\n * It can be freed with free(), rather than a kiss_fft-specific function.\n * */\nkiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )\n{\n    kiss_fft_cfg st=NULL;\n    size_t memneeded = sizeof(struct kiss_fft_state)\n        + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/\n\n    if ( lenmem==NULL ) {\n        st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );\n    }else{\n        if (mem != NULL && *lenmem >= memneeded)\n            st = (kiss_fft_cfg)mem;\n        *lenmem = memneeded;\n    }\n    if (st) {\n        int i;\n        st->nfft=nfft;\n        st->inverse = inverse_fft;\n#ifdef FIXED_POINT\n        for (i=0;i<nfft;++i) {\n            spx_word32_t phase = i;\n            if (!st->inverse)\n                phase = -phase;\n            kf_cexp2(st->twiddles+i, DIV32(SHL32(phase,17),nfft));\n        }\n#else\n        for (i=0;i<nfft;++i) {\n           const double pi=3.14159265358979323846264338327;\n           double phase = ( -2*pi /nfft ) * i;\n           if (st->inverse)\n              phase *= -1;\n           kf_cexp(st->twiddles+i, phase );\n        }\n#endif\n        kf_factor(nfft,st->factors);\n    }\n    return st;\n}\n\n\n\n    \nvoid kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride)\n{\n    if (fin == fout) \n    {\n       speex_fatal(\"In-place FFT not supported\");\n       /*CHECKBUF(tmpbuf,ntmpbuf,st->nfft);\n       kf_work(tmpbuf,fin,1,in_stride, st->factors,st);\n       SPEEX_MOVE(fout,tmpbuf,st->nfft);*/\n    } else {\n       kf_shuffle( fout, fin, 1,in_stride, st->factors,st);\n       kf_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1);\n    }\n}\n\nvoid kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)\n{\n    kiss_fft_stride(cfg,fin,fout,1);\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/kiss_fft.h",
    "content": "#ifndef KISS_FFT_H\n#define KISS_FFT_H\n\n#include <stdlib.h>\n#include <math.h>\n#include \"arch.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n ATTENTION!\n If you would like a :\n -- a utility that will handle the caching of fft objects\n -- real-only (no imaginary time component ) FFT\n -- a multi-dimensional FFT\n -- a command-line utility to perform ffts\n -- a command-line utility to perform fast-convolution filtering\n\n Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c\n  in the tools/ directory.\n*/\n\n#ifdef USE_SIMD\n# include <xmmintrin.h>\n# define kiss_fft_scalar __m128\n#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes)\n#else\t\n#define KISS_FFT_MALLOC speex_alloc\n#endif\t\n\n\n#ifdef FIXED_POINT\n#include \"arch.h\"\t\n#  define kiss_fft_scalar spx_int16_t\n#else\n# ifndef kiss_fft_scalar\n/*  default is float */\n#   define kiss_fft_scalar float\n# endif\n#endif\n\ntypedef struct {\n    kiss_fft_scalar r;\n    kiss_fft_scalar i;\n}kiss_fft_cpx;\n\ntypedef struct kiss_fft_state* kiss_fft_cfg;\n\n/* \n *  kiss_fft_alloc\n *  \n *  Initialize a FFT (or IFFT) algorithm's cfg/state buffer.\n *\n *  typical usage:      kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL);\n *\n *  The return value from fft_alloc is a cfg buffer used internally\n *  by the fft routine or NULL.\n *\n *  If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc.\n *  The returned value should be free()d when done to avoid memory leaks.\n *  \n *  The state can be placed in a user supplied buffer 'mem':\n *  If lenmem is not NULL and mem is not NULL and *lenmem is large enough,\n *      then the function places the cfg in mem and the size used in *lenmem\n *      and returns mem.\n *  \n *  If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),\n *      then the function returns NULL and places the minimum cfg \n *      buffer size in *lenmem.\n * */\n\nkiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); \n\n/*\n * kiss_fft(cfg,in_out_buf)\n *\n * Perform an FFT on a complex input buffer.\n * for a forward FFT,\n * fin should be  f[0] , f[1] , ... ,f[nfft-1]\n * fout will be   F[0] , F[1] , ... ,F[nfft-1]\n * Note that each element is complex and can be accessed like\n    f[k].r and f[k].i\n * */\nvoid kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);\n\n/*\n A more generic version of the above function. It reads its input from every Nth sample.\n * */\nvoid kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride);\n\n/* If kiss_fft_alloc allocated a buffer, it is one contiguous \n   buffer and can be simply free()d when no longer needed*/\n#define kiss_fft_free speex_free\n\n/*\n Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up \n your compiler output to call this before you exit.\n*/\nvoid kiss_fft_cleanup(void);\n\t\n\n#ifdef __cplusplus\n} \n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/kiss_fftr.c",
    "content": "/*\nCopyright (c) 2003-2004, Mark Borgerding\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"os_support.h\"\n#include \"kiss_fftr.h\"\n#include \"_kiss_fft_guts.h\"\n\nstruct kiss_fftr_state{\n    kiss_fft_cfg substate;\n    kiss_fft_cpx * tmpbuf;\n    kiss_fft_cpx * super_twiddles;\n#ifdef USE_SIMD    \n    long pad;\n#endif    \n};\n\nkiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)\n{\n    int i;\n    kiss_fftr_cfg st = NULL;\n    size_t subsize, memneeded;\n\n    if (nfft & 1) {\n        speex_warning(\"Real FFT optimization must be even.\\n\");\n        return NULL;\n    }\n    nfft >>= 1;\n\n    kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize);\n    memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 2);\n\n    if (lenmem == NULL) {\n        st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded);\n    } else {\n        if (*lenmem >= memneeded)\n            st = (kiss_fftr_cfg) mem;\n        *lenmem = memneeded;\n    }\n    if (!st)\n        return NULL;\n\n    st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */\n    st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize);\n    st->super_twiddles = st->tmpbuf + nfft;\n    kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);\n\n#ifdef FIXED_POINT\n    for (i=0;i<nfft;++i) {\n       spx_word32_t phase = i+(nfft>>1);\n       if (!inverse_fft)\n          phase = -phase;\n       kf_cexp2(st->super_twiddles+i, DIV32(SHL32(phase,16),nfft));\n    }\n#else\n    for (i=0;i<nfft;++i) {\n       const double pi=3.14159265358979323846264338327;\n       double phase = pi*(((double)i) /nfft + .5);\n       if (!inverse_fft)\n          phase = -phase;\n       kf_cexp(st->super_twiddles+i, phase );\n    }\n#endif\n    return st;\n}\n\nvoid kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata)\n{\n    /* input buffer timedata is stored row-wise */\n    int k,ncfft;\n    kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;\n\n    if ( st->substate->inverse) {\n        speex_fatal(\"kiss fft usage error: improper alloc\\n\");\n    }\n\n    ncfft = st->substate->nfft;\n\n    /*perform the parallel fft of two real signals packed in real,imag*/\n    kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );\n    /* The real part of the DC element of the frequency spectrum in st->tmpbuf\n     * contains the sum of the even-numbered elements of the input time sequence\n     * The imag part is the sum of the odd-numbered elements\n     *\n     * The sum of tdc.r and tdc.i is the sum of the input time sequence. \n     *      yielding DC of input time sequence\n     * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... \n     *      yielding Nyquist bin of input time sequence\n     */\n \n    tdc.r = st->tmpbuf[0].r;\n    tdc.i = st->tmpbuf[0].i;\n    C_FIXDIV(tdc,2);\n    CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);\n    CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);\n    freqdata[0].r = tdc.r + tdc.i;\n    freqdata[ncfft].r = tdc.r - tdc.i;\n#ifdef USE_SIMD    \n    freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0);\n#else\n    freqdata[ncfft].i = freqdata[0].i = 0;\n#endif\n\n    for ( k=1;k <= ncfft/2 ; ++k ) {\n        fpk    = st->tmpbuf[k]; \n        fpnk.r =   st->tmpbuf[ncfft-k].r;\n        fpnk.i = - st->tmpbuf[ncfft-k].i;\n        C_FIXDIV(fpk,2);\n        C_FIXDIV(fpnk,2);\n\n        C_ADD( f1k, fpk , fpnk );\n        C_SUB( f2k, fpk , fpnk );\n        C_MUL( tw , f2k , st->super_twiddles[k]);\n\n        freqdata[k].r = HALF_OF(f1k.r + tw.r);\n        freqdata[k].i = HALF_OF(f1k.i + tw.i);\n        freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r);\n        freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i);\n    }\n}\n\nvoid kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata, kiss_fft_scalar *timedata)\n{\n    /* input buffer timedata is stored row-wise */\n    int k, ncfft;\n\n    if (st->substate->inverse == 0) {\n        speex_fatal(\"kiss fft usage error: improper alloc\\n\");\n    }\n\n    ncfft = st->substate->nfft;\n\n    st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r;\n    st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r;\n    /*C_FIXDIV(st->tmpbuf[0],2);*/\n\n    for (k = 1; k <= ncfft / 2; ++k) {\n        kiss_fft_cpx fk, fnkc, fek, fok, tmp;\n        fk = freqdata[k];\n        fnkc.r = freqdata[ncfft - k].r;\n        fnkc.i = -freqdata[ncfft - k].i;\n        /*C_FIXDIV( fk , 2 );\n        C_FIXDIV( fnkc , 2 );*/\n\n        C_ADD (fek, fk, fnkc);\n        C_SUB (tmp, fk, fnkc);\n        C_MUL (fok, tmp, st->super_twiddles[k]);\n        C_ADD (st->tmpbuf[k],     fek, fok);\n        C_SUB (st->tmpbuf[ncfft - k], fek, fok);\n#ifdef USE_SIMD        \n        st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);\n#else\n        st->tmpbuf[ncfft - k].i *= -1;\n#endif\n    }\n    kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);\n}\n\nvoid kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata)\n{\n   /* input buffer timedata is stored row-wise */\n   int k,ncfft;\n   kiss_fft_cpx f2k,tdc;\n   spx_word32_t f1kr, f1ki, twr, twi;\n\n   if ( st->substate->inverse) {\n      speex_fatal(\"kiss fft usage error: improper alloc\\n\");\n   }\n\n   ncfft = st->substate->nfft;\n\n   /*perform the parallel fft of two real signals packed in real,imag*/\n   kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );\n    /* The real part of the DC element of the frequency spectrum in st->tmpbuf\n   * contains the sum of the even-numbered elements of the input time sequence\n   * The imag part is the sum of the odd-numbered elements\n   *\n   * The sum of tdc.r and tdc.i is the sum of the input time sequence. \n   *      yielding DC of input time sequence\n   * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... \n   *      yielding Nyquist bin of input time sequence\n    */\n \n   tdc.r = st->tmpbuf[0].r;\n   tdc.i = st->tmpbuf[0].i;\n   C_FIXDIV(tdc,2);\n   CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);\n   CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);\n   freqdata[0] = tdc.r + tdc.i;\n   freqdata[2*ncfft-1] = tdc.r - tdc.i;\n\n   for ( k=1;k <= ncfft/2 ; ++k )\n   {\n      /*fpk    = st->tmpbuf[k]; \n      fpnk.r =   st->tmpbuf[ncfft-k].r;\n      fpnk.i = - st->tmpbuf[ncfft-k].i;\n      C_FIXDIV(fpk,2);\n      C_FIXDIV(fpnk,2);\n\n      C_ADD( f1k, fpk , fpnk );\n      C_SUB( f2k, fpk , fpnk );\n      \n      C_MUL( tw , f2k , st->super_twiddles[k]);\n\n      freqdata[2*k-1] = HALF_OF(f1k.r + tw.r);\n      freqdata[2*k] = HALF_OF(f1k.i + tw.i);\n      freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r);\n      freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i);\n      */\n\n      /*f1k.r = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1);\n      f1k.i = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1);\n      f2k.r = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1);\n      f2k.i = SHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1);\n      \n      C_MUL( tw , f2k , st->super_twiddles[k]);\n\n      freqdata[2*k-1] = HALF_OF(f1k.r + tw.r);\n      freqdata[2*k] = HALF_OF(f1k.i + tw.i);\n      freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r);\n      freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i);\n   */\n      f2k.r = SHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1);\n      f2k.i = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1);\n      \n      f1kr = SHL32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),13);\n      f1ki = SHL32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),13);\n      \n      twr = SHR32(SUB32(MULT16_16(f2k.r,st->super_twiddles[k].r),MULT16_16(f2k.i,st->super_twiddles[k].i)), 1);\n      twi = SHR32(ADD32(MULT16_16(f2k.i,st->super_twiddles[k].r),MULT16_16(f2k.r,st->super_twiddles[k].i)), 1);\n      \n#ifdef FIXED_POINT\n      freqdata[2*k-1] = PSHR32(f1kr + twr, 15);\n      freqdata[2*k] = PSHR32(f1ki + twi, 15);\n      freqdata[2*(ncfft-k)-1] = PSHR32(f1kr - twr, 15);\n      freqdata[2*(ncfft-k)] = PSHR32(twi - f1ki, 15);\n#else\n      freqdata[2*k-1] = .5f*(f1kr + twr);\n      freqdata[2*k] = .5f*(f1ki + twi);\n      freqdata[2*(ncfft-k)-1] = .5f*(f1kr - twr);\n      freqdata[2*(ncfft-k)] = .5f*(twi - f1ki);\n      \n#endif\n   }\n}\n\nvoid kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata,kiss_fft_scalar *timedata)\n{\n   /* input buffer timedata is stored row-wise */\n   int k, ncfft;\n\n   if (st->substate->inverse == 0) {\n      speex_fatal (\"kiss fft usage error: improper alloc\\n\");\n   }\n\n   ncfft = st->substate->nfft;\n\n   st->tmpbuf[0].r = freqdata[0] + freqdata[2*ncfft-1];\n   st->tmpbuf[0].i = freqdata[0] - freqdata[2*ncfft-1];\n   /*C_FIXDIV(st->tmpbuf[0],2);*/\n\n   for (k = 1; k <= ncfft / 2; ++k) {\n      kiss_fft_cpx fk, fnkc, fek, fok, tmp;\n      fk.r = freqdata[2*k-1];\n      fk.i = freqdata[2*k];\n      fnkc.r = freqdata[2*(ncfft - k)-1];\n      fnkc.i = -freqdata[2*(ncfft - k)];\n        /*C_FIXDIV( fk , 2 );\n      C_FIXDIV( fnkc , 2 );*/\n\n      C_ADD (fek, fk, fnkc);\n      C_SUB (tmp, fk, fnkc);\n      C_MUL (fok, tmp, st->super_twiddles[k]);\n      C_ADD (st->tmpbuf[k],     fek, fok);\n      C_SUB (st->tmpbuf[ncfft - k], fek, fok);\n#ifdef USE_SIMD        \n      st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);\n#else\n      st->tmpbuf[ncfft - k].i *= -1;\n#endif\n   }\n   kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/kiss_fftr.h",
    "content": "#ifndef KISS_FTR_H\n#define KISS_FTR_H\n\n#include \"kiss_fft.h\"\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n    \n/* \n \n Real optimized version can save about 45% cpu time vs. complex fft of a real seq.\n\n \n \n */\n\ntypedef struct kiss_fftr_state *kiss_fftr_cfg;\n\n\nkiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);\n/*\n nfft must be even\n\n If you don't care to allocate space, use mem = lenmem = NULL \n*/\n\n\nvoid kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);\n/*\n input timedata has nfft scalar points\n output freqdata has nfft/2+1 complex points\n*/\n\nvoid kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata);\n\nvoid kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);\n\nvoid kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata, kiss_fft_scalar *timedata);\n\n/*\n input freqdata has  nfft/2+1 complex points\n output timedata has nfft scalar points\n*/\n\n#define kiss_fftr_free speex_free\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/lpc.c",
    "content": "/*\n  Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,\n  Technische Universitaet Berlin\n\n  Any use of this software is permitted provided that this notice is not\n  removed and that neither the authors nor the Technische Universitaet Berlin\n  are deemed to have made any representations as to the suitability of this\n  software for any purpose nor are held responsible for any defects of\n  this software.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.\n\n  As a matter of courtesy, the authors request to be informed about uses\n  this software has found, about bugs in this software, and about any\n  improvements that may be of general interest.\n\n  Berlin, 28.11.1994\n  Jutta Degener\n  Carsten Bormann\n\n\n   Code modified by Jean-Marc Valin\n\n   Speex License:\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"lpc.h\"\n\n#ifdef BFIN_ASM\n#include \"lpc_bfin.h\"\n#endif\n\n/* LPC analysis\n *\n * The next two functions calculate linear prediction coefficients\n * and/or the related reflection coefficients from the first P_MAX+1\n * values of the autocorrelation function.\n */\n\n/* Invented by N. Levinson in 1947, modified by J. Durbin in 1959.\n */\n\n/* returns minimum mean square error    */\nspx_word32_t _spx_lpc(\nspx_coef_t       *lpc, /* out: [0...p-1] LPC coefficients      */\nconst spx_word16_t *ac,  /* in:  [0...p] autocorrelation values  */\nint          p\n)\n{\n   int i, j;  \n   spx_word16_t r;\n   spx_word16_t error = ac[0];\n\n   if (ac[0] == 0)\n   {\n      for (i = 0; i < p; i++)\n         lpc[i] = 0;\n      return 0;\n   }\n\n   for (i = 0; i < p; i++) {\n\n      /* Sum up this iteration's reflection coefficient */\n      spx_word32_t rr = NEG32(SHL32(EXTEND32(ac[i + 1]),13));\n      for (j = 0; j < i; j++) \n         rr = SUB32(rr,MULT16_16(lpc[j],ac[i - j]));\n#ifdef FIXED_POINT\n      r = DIV32_16(rr+PSHR32(error,1),ADD16(error,8));\n#else\n      r = rr/(error+.003*ac[0]);\n#endif\n      /*  Update LPC coefficients and total error */\n      lpc[i] = r;\n      for (j = 0; j < i>>1; j++) \n      {\n         spx_word16_t tmp  = lpc[j];\n         lpc[j]     = MAC16_16_P13(lpc[j],r,lpc[i-1-j]);\n         lpc[i-1-j] = MAC16_16_P13(lpc[i-1-j],r,tmp);\n      }\n      if (i & 1) \n         lpc[j] = MAC16_16_P13(lpc[j],lpc[j],r);\n\n      error = SUB16(error,MULT16_16_Q13(r,MULT16_16_Q13(error,r)));\n   }\n   return error;\n}\n\n\n#ifdef FIXED_POINT\n\n/* Compute the autocorrelation\n *                      ,--,\n *              ac(i) = >  x(n) * x(n-i)  for all n\n *                      `--'\n * for lags between 0 and lag-1, and x == 0 outside 0...n-1\n */\n\n#ifndef OVERRIDE_SPEEX_AUTOCORR\nvoid _spx_autocorr(\nconst spx_word16_t *x,   /*  in: [0...n-1] samples x   */\nspx_word16_t       *ac,  /* out: [0...lag-1] ac values */\nint          lag, \nint          n\n)\n{\n   spx_word32_t d;\n   int i, j;\n   spx_word32_t ac0=1;\n   int shift, ac_shift;\n   \n   for (j=0;j<n;j++)\n      ac0 = ADD32(ac0,SHR32(MULT16_16(x[j],x[j]),8));\n   ac0 = ADD32(ac0,n);\n   shift = 8;\n   while (shift && ac0<0x40000000)\n   {\n      shift--;\n      ac0 <<= 1;\n   }\n   ac_shift = 18;\n   while (ac_shift && ac0<0x40000000)\n   {\n      ac_shift--;\n      ac0 <<= 1;\n   }\n   \n   \n   for (i=0;i<lag;i++)\n   {\n      d=0;\n      for (j=i;j<n;j++)\n      {\n         d = ADD32(d,SHR32(MULT16_16(x[j],x[j-i]), shift));\n      }\n      \n      ac[i] = SHR32(d, ac_shift);\n   }\n}\n#endif\n\n\n#else\n\n\n\n/* Compute the autocorrelation\n *                      ,--,\n *              ac(i) = >  x(n) * x(n-i)  for all n\n *                      `--'\n * for lags between 0 and lag-1, and x == 0 outside 0...n-1\n */\nvoid _spx_autocorr(\nconst spx_word16_t *x,   /*  in: [0...n-1] samples x   */\nfloat       *ac,  /* out: [0...lag-1] ac values */\nint          lag, \nint          n\n)\n{\n   float d;\n   int i;\n   while (lag--) \n   {\n      for (i = lag, d = 0; i < n; i++) \n         d += x[i] * x[i-lag];\n      ac[lag] = d;\n   }\n   ac[0] += 10;\n}\n\n#endif\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/lpc.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin */\n/**\n   @file lpc.h\n   @brief Functions for LPC (Linear Prediction Coefficients) analysis\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef LPC_H\n#define LPC_H\n\n#include \"arch.h\"\n\nvoid _spx_autocorr(\n              const spx_word16_t * x,   /*  in: [0...n-1] samples x   */\n              spx_word16_t *ac,   /* out: [0...lag-1] ac values */\n              int lag, int   n);\n\nspx_word32_t                      /* returns minimum mean square error    */\n_spx_lpc(\n    spx_coef_t       * lpc, /*      [0...p-1] LPC coefficients      */\n    const spx_word16_t * ac,  /*  in: [0...p] autocorrelation values  */\n    int p\n    );\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/lpc_bfin.h",
    "content": "/* Copyright (C) 2005 Analog Devices */\n/**\n   @file lpc_bfin.h\n   @author Jean-Marc Valin \n   @brief Functions for LPC (Linear Prediction Coefficients) analysis (Blackfin version)\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#define OVERRIDE_SPEEX_AUTOCORR\nvoid _spx_autocorr(\nconst spx_word16_t *x,   /*  in: [0...n-1] samples x   */\nspx_word16_t       *ac,  /* out: [0...lag-1] ac values */\nint          lag, \nint          n\n                  )\n{\n   spx_word32_t d;\n   const spx_word16_t *xs;\n   int i, j;\n   spx_word32_t ac0=1;\n   spx_word32_t ac32[11], *ac32top;\n   int shift, ac_shift;\n   ac32top = ac32+lag-1;\n   int lag_1, N_lag;\n   int nshift;\n   lag_1 = lag-1;\n   N_lag = n-lag_1;\n   for (j=0;j<n;j++)\n      ac0 = ADD32(ac0,SHR32(MULT16_16(x[j],x[j]),8));\n   ac0 = ADD32(ac0,n);\n   shift = 8;\n   while (shift && ac0<0x40000000)\n   {\n      shift--;\n      ac0 <<= 1;\n   }\n   ac_shift = 18;\n   while (ac_shift && ac0<0x40000000)\n   {\n      ac_shift--;\n      ac0 <<= 1;\n   }\n   \n   xs = x+lag-1;\n   nshift = -shift;\n   __asm__ __volatile__ \n   (\n         \"P2 = %0;\\n\\t\"\n         \"I0 = P2;\\n\\t\" /* x in I0 */\n         \"B0 = P2;\\n\\t\" /* x in B0 */\n         \"R0 = %3;\\n\\t\" /* len in R0 */\n         \"P3 = %3;\\n\\t\" /* len in R0 */\n         \"P4 = %4;\\n\\t\" /* nb_pitch in R0 */\n         \"R1 = R0 << 1;\\n\\t\" /* number of bytes in x */\n         \"L0 = R1;\\n\\t\"\n         \"P0 = %1;\\n\\t\"\n         \"P1 = %2;\\n\\t\"\n         \"B1 = P1;\\n\\t\"\n         \"R4 = %5;\\n\\t\"\n         \"L1 = 0;\\n\\t\" /*Disable looping on I1*/\n\n         \"r0 = [I0++];\\n\\t\"\n         \"R2 = 0;R3=0;\"\n         \"LOOP pitch%= LC0 = P4 >> 1;\\n\\t\"\n         \"LOOP_BEGIN pitch%=;\\n\\t\"\n            \"I1 = P0;\\n\\t\"\n            \"A1 = A0 = 0;\\n\\t\"\n            \"R1 = [I1++];\\n\\t\"\n            \"LOOP inner_prod%= LC1 = P3 >> 1;\\n\\t\"\n            \"LOOP_BEGIN inner_prod%=;\\n\\t\"\n               \"A1 += R0.L*R1.H, A0 += R0.L*R1.L (IS) || R1.L = W[I1++];\\n\\t\"\n               \"A1 += R0.H*R1.L, A0 += R0.H*R1.H (IS) || R1.H = W[I1++] || R0 = [I0++];\\n\\t\"\n            \"LOOP_END inner_prod%=;\\n\\t\"\n            \"A0 = ASHIFT A0 by R4.L;\\n\\t\"\n            \"A1 = ASHIFT A1 by R4.L;\\n\\t\"\n   \n            \"R2 = A0, R3 = A1;\\n\\t\"\n            \"[P1--] = R2;\\n\\t\"\n            \"[P1--] = R3;\\n\\t\"\n            \"P0 += 4;\\n\\t\"\n         \"LOOP_END pitch%=;\\n\\t\"\n   : : \"m\" (xs), \"m\" (x), \"m\" (ac32top), \"m\" (N_lag), \"m\" (lag_1), \"m\" (nshift)\n   : \"A0\", \"A1\", \"P0\", \"P1\", \"P2\", \"P3\", \"P4\", \"R0\", \"R1\", \"R2\", \"R3\", \"R4\", \"I0\", \"I1\", \"L0\", \"L1\", \"B0\", \"B1\", \"memory\"\n   );\n   d=0;\n   for (j=0;j<n;j++)\n   {\n      d = ADD32(d,SHR32(MULT16_16(x[j],x[j]), shift));\n   }\n   ac32[0] = d;\n   \n   for (i=0;i<lag;i++)\n   {\n      d=0;\n      for (j=i;j<lag_1;j++)\n      {\n         d = ADD32(d,SHR32(MULT16_16(x[j],x[j-i]), shift));\n      }\n      if (i)\n         ac32[i] += d;\n      ac[i] = SHR32(ac32[i], ac_shift);\n   }\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/lsp.c",
    "content": "/*---------------------------------------------------------------------------*\\\nOriginal copyright\n\tFILE........: lsp.c\n\tAUTHOR......: David Rowe\n\tDATE CREATED: 24/2/93\n\nHeavily modified by Jean-Marc Valin (c) 2002-2006 (fixed-point, \n                       optimizations, additional functions, ...)\n\n   This file contains functions for converting Linear Prediction\n   Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the\n   LSP coefficients are not in radians format but in the x domain of the\n   unit circle.\n\n   Speex License:\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/*---------------------------------------------------------------------------*\\\n\n  Introduction to Line Spectrum Pairs (LSPs)\n  ------------------------------------------\n\n  LSPs are used to encode the LPC filter coefficients {ak} for\n  transmission over the channel.  LSPs have several properties (like\n  less sensitivity to quantisation noise) that make them superior to\n  direct quantisation of {ak}.\n\n  A(z) is a polynomial of order lpcrdr with {ak} as the coefficients.\n\n  A(z) is transformed to P(z) and Q(z) (using a substitution and some\n  algebra), to obtain something like:\n\n    A(z) = 0.5[P(z)(z+z^-1) + Q(z)(z-z^-1)]  (1)\n\n  As you can imagine A(z) has complex zeros all over the z-plane. P(z)\n  and Q(z) have the very neat property of only having zeros _on_ the\n  unit circle.  So to find them we take a test point z=exp(jw) and\n  evaluate P (exp(jw)) and Q(exp(jw)) using a grid of points between 0\n  and pi.\n\n  The zeros (roots) of P(z) also happen to alternate, which is why we\n  swap coefficients as we find roots.  So the process of finding the\n  LSP frequencies is basically finding the roots of 5th order\n  polynomials.\n\n  The root so P(z) and Q(z) occur in symmetrical pairs at +/-w, hence\n  the name Line Spectrum Pairs (LSPs).\n\n  To convert back to ak we just evaluate (1), \"clocking\" an impulse\n  thru it lpcrdr times gives us the impulse response of A(z) which is\n  {ak}.\n\n\\*---------------------------------------------------------------------------*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <math.h>\n#include \"lsp.h\"\n#include \"stack_alloc.h\"\n#include \"math_approx.h\"\n\n#ifndef M_PI\n#define M_PI           3.14159265358979323846  /* pi */\n#endif\n\n#ifndef NULL\n#define NULL 0\n#endif\n\n#ifdef FIXED_POINT\n\n#define FREQ_SCALE 16384\n\n/*#define ANGLE2X(a) (32768*cos(((a)/8192.)))*/\n#define ANGLE2X(a) (SHL16(spx_cos(a),2))\n\n/*#define X2ANGLE(x) (acos(.00006103515625*(x))*LSP_SCALING)*/\n#define X2ANGLE(x) (spx_acos(x))\n\n#ifdef BFIN_ASM\n#include \"lsp_bfin.h\"\n#endif\n\n#else\n\n/*#define C1 0.99940307\n#define C2 -0.49558072\n#define C3 0.03679168*/\n\n#define FREQ_SCALE 1.\n#define ANGLE2X(a) (spx_cos(a))\n#define X2ANGLE(x) (acos(x))\n\n#endif\n\n\n/*---------------------------------------------------------------------------*\\\n\n   FUNCTION....: cheb_poly_eva()\n\n   AUTHOR......: David Rowe\n   DATE CREATED: 24/2/93\n\n   This function evaluates a series of Chebyshev polynomials\n\n\\*---------------------------------------------------------------------------*/\n\n#ifdef FIXED_POINT\n\n#ifndef OVERRIDE_CHEB_POLY_EVA\nstatic inline spx_word32_t cheb_poly_eva(\n  spx_word16_t *coef, /* P or Q coefs in Q13 format               */\n  spx_word16_t     x, /* cos of freq (-1.0 to 1.0) in Q14 format  */\n  int              m, /* LPC order/2                              */\n  char         *stack\n)\n{\n    int i;\n    spx_word16_t b0, b1;\n    spx_word32_t sum;\n\n    /*Prevents overflows*/\n    if (x>16383)\n       x = 16383;\n    if (x<-16383)\n       x = -16383;\n\n    /* Initialise values */\n    b1=16384;\n    b0=x;\n\n    /* Evaluate Chebyshev series formulation usin g iterative approach  */\n    sum = ADD32(EXTEND32(coef[m]), EXTEND32(MULT16_16_P14(coef[m-1],x)));\n    for(i=2;i<=m;i++)\n    {\n       spx_word16_t tmp=b0;\n       b0 = SUB16(MULT16_16_Q13(x,b0), b1);\n       b1 = tmp;\n       sum = ADD32(sum, EXTEND32(MULT16_16_P14(coef[m-i],b0)));\n    }\n    \n    return sum;\n}\n#endif\n\n#else\n\nstatic float cheb_poly_eva(spx_word32_t *coef, spx_word16_t x, int m, char *stack)\n{\n   int k;\n   float b0, b1, tmp;\n\n   /* Initial conditions */\n   b0=0; /* b_(m+1) */\n   b1=0; /* b_(m+2) */\n\n   x*=2;\n\n   /* Calculate the b_(k) */\n   for(k=m;k>0;k--)\n   {\n      tmp=b0;                           /* tmp holds the previous value of b0 */\n      b0=x*b0-b1+coef[m-k];    /* b0 holds its new value based on b0 and b1 */\n      b1=tmp;                           /* b1 holds the previous value of b0 */\n   }\n\n   return(-b1+.5*x*b0+coef[m]);\n}\n#endif\n\n/*---------------------------------------------------------------------------*\\\n\n    FUNCTION....: lpc_to_lsp()\n\n    AUTHOR......: David Rowe\n    DATE CREATED: 24/2/93\n\n    This function converts LPC coefficients to LSP\n    coefficients.\n\n\\*---------------------------------------------------------------------------*/\n\n#ifdef FIXED_POINT\n#define SIGN_CHANGE(a,b) (((a)&0x70000000)^((b)&0x70000000)||(b==0))\n#else\n#define SIGN_CHANGE(a,b) (((a)*(b))<0.0)\n#endif\n\n\nint lpc_to_lsp (spx_coef_t *a,int lpcrdr,spx_lsp_t *freq,int nb,spx_word16_t delta, char *stack)\n/*  float *a \t\t     \tlpc coefficients\t\t\t*/\n/*  int lpcrdr\t\t\torder of LPC coefficients (10) \t\t*/\n/*  float *freq \t      \tLSP frequencies in the x domain       \t*/\n/*  int nb\t\t\tnumber of sub-intervals (4) \t\t*/\n/*  float delta\t\t\tgrid spacing interval (0.02) \t\t*/\n\n\n{\n    spx_word16_t temp_xr,xl,xr,xm=0;\n    spx_word32_t psuml,psumr,psumm,temp_psumr/*,temp_qsumr*/;\n    int i,j,m,flag,k;\n    VARDECL(spx_word32_t *Q);                 \t/* ptrs for memory allocation \t\t*/\n    VARDECL(spx_word32_t *P);\n    VARDECL(spx_word16_t *Q16);         /* ptrs for memory allocation \t\t*/\n    VARDECL(spx_word16_t *P16);\n    spx_word32_t *px;                \t/* ptrs of respective P'(z) & Q'(z)\t*/\n    spx_word32_t *qx;\n    spx_word32_t *p;\n    spx_word32_t *q;\n    spx_word16_t *pt;                \t/* ptr used for cheb_poly_eval()\n\t\t\t\twhether P' or Q' \t\t\t*/\n    int roots=0;              \t/* DR 8/2/94: number of roots found \t*/\n    flag = 1;                \t/*  program is searching for a root when,\n\t\t\t\t1 else has found one \t\t\t*/\n    m = lpcrdr/2;            \t/* order of P'(z) & Q'(z) polynomials \t*/\n\n    /* Allocate memory space for polynomials */\n    ALLOC(Q, (m+1), spx_word32_t);\n    ALLOC(P, (m+1), spx_word32_t);\n\n    /* determine P'(z)'s and Q'(z)'s coefficients where\n      P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */\n\n    px = P;                      /* initialise ptrs \t\t\t*/\n    qx = Q;\n    p = px;\n    q = qx;\n\n#ifdef FIXED_POINT\n    *px++ = LPC_SCALING;\n    *qx++ = LPC_SCALING;\n    for(i=0;i<m;i++){\n       *px++ = SUB32(ADD32(EXTEND32(a[i]),EXTEND32(a[lpcrdr-i-1])), *p++);\n       *qx++ = ADD32(SUB32(EXTEND32(a[i]),EXTEND32(a[lpcrdr-i-1])), *q++);\n    }\n    px = P;\n    qx = Q;\n    for(i=0;i<m;i++)\n    {\n       /*if (fabs(*px)>=32768)\n          speex_warning_int(\"px\", *px);\n       if (fabs(*qx)>=32768)\n       speex_warning_int(\"qx\", *qx);*/\n       *px = PSHR32(*px,2);\n       *qx = PSHR32(*qx,2);\n       px++;\n       qx++;\n    }\n    /* The reason for this lies in the way cheb_poly_eva() is implemented for fixed-point */\n    P[m] = PSHR32(P[m],3);\n    Q[m] = PSHR32(Q[m],3);\n#else\n    *px++ = LPC_SCALING;\n    *qx++ = LPC_SCALING;\n    for(i=0;i<m;i++){\n       *px++ = (a[i]+a[lpcrdr-1-i]) - *p++;\n       *qx++ = (a[i]-a[lpcrdr-1-i]) + *q++;\n    }\n    px = P;\n    qx = Q;\n    for(i=0;i<m;i++){\n       *px = 2**px;\n       *qx = 2**qx;\n       px++;\n       qx++;\n    }\n#endif\n\n    px = P;             \t/* re-initialise ptrs \t\t\t*/\n    qx = Q;\n\n    /* now that we have computed P and Q convert to 16 bits to\n       speed up cheb_poly_eval */\n\n    ALLOC(P16, m+1, spx_word16_t);\n    ALLOC(Q16, m+1, spx_word16_t);\n\n    for (i=0;i<m+1;i++)\n    {\n       P16[i] = P[i];\n       Q16[i] = Q[i];\n    }\n\n    /* Search for a zero in P'(z) polynomial first and then alternate to Q'(z).\n    Keep alternating between the two polynomials as each zero is found \t*/\n\n    xr = 0;             \t/* initialise xr to zero \t\t*/\n    xl = FREQ_SCALE;               \t/* start at point xl = 1 \t\t*/\n\n    for(j=0;j<lpcrdr;j++){\n\tif(j&1)            \t/* determines whether P' or Q' is eval. */\n\t    pt = Q16;\n\telse\n\t    pt = P16;\n\n\tpsuml = cheb_poly_eva(pt,xl,m,stack);\t/* evals poly. at xl \t*/\n\tflag = 1;\n\twhile(flag && (xr >= -FREQ_SCALE)){\n           spx_word16_t dd;\n           /* Modified by JMV to provide smaller steps around x=+-1 */\n#ifdef FIXED_POINT\n           dd = MULT16_16_Q15(delta,SUB16(FREQ_SCALE, MULT16_16_Q14(MULT16_16_Q14(xl,xl),14000)));\n           if (psuml<512 && psuml>-512)\n              dd = PSHR16(dd,1);\n#else\n           dd=delta*(1-.9*xl*xl);\n           if (fabs(psuml)<.2)\n              dd *= .5;\n#endif\n           xr = SUB16(xl, dd);                        \t/* interval spacing \t*/\n\t    psumr = cheb_poly_eva(pt,xr,m,stack);/* poly(xl-delta_x) \t*/\n\t    temp_psumr = psumr;\n\t    temp_xr = xr;\n\n    /* if no sign change increment xr and re-evaluate poly(xr). Repeat til\n    sign change.\n    if a sign change has occurred the interval is bisected and then\n    checked again for a sign change which determines in which\n    interval the zero lies in.\n    If there is no sign change between poly(xm) and poly(xl) set interval\n    between xm and xr else set interval between xl and xr and repeat till\n    root is located within the specified limits \t\t\t*/\n\n\t    if(SIGN_CHANGE(psumr,psuml))\n            {\n\t\troots++;\n\n\t\tpsumm=psuml;\n\t\tfor(k=0;k<=nb;k++){\n#ifdef FIXED_POINT\n\t\t    xm = ADD16(PSHR16(xl,1),PSHR16(xr,1));        \t/* bisect the interval \t*/\n#else\n                    xm = .5*(xl+xr);        \t/* bisect the interval \t*/\n#endif\n\t\t    psumm=cheb_poly_eva(pt,xm,m,stack);\n\t\t    /*if(psumm*psuml>0.)*/\n\t\t    if(!SIGN_CHANGE(psumm,psuml))\n                    {\n\t\t\tpsuml=psumm;\n\t\t\txl=xm;\n\t\t    } else {\n\t\t\tpsumr=psumm;\n\t\t\txr=xm;\n\t\t    }\n\t\t}\n\n\t       /* once zero is found, reset initial interval to xr \t*/\n\t       freq[j] = X2ANGLE(xm);\n\t       xl = xm;\n\t       flag = 0;       \t\t/* reset flag for next search \t*/\n\t    }\n\t    else{\n\t\tpsuml=temp_psumr;\n\t\txl=temp_xr;\n\t    }\n\t}\n    }\n    return(roots);\n}\n\n/*---------------------------------------------------------------------------*\\\n\n\tFUNCTION....: lsp_to_lpc()\n\n\tAUTHOR......: David Rowe\n\tDATE CREATED: 24/2/93\n\n        Converts LSP coefficients to LPC coefficients.\n\n\\*---------------------------------------------------------------------------*/\n\n#ifdef FIXED_POINT\n\nvoid lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack)\n/*  float *freq \tarray of LSP frequencies in the x domain\t*/\n/*  float *ak \t\tarray of LPC coefficients \t\t\t*/\n/*  int lpcrdr  \torder of LPC coefficients \t\t\t*/\n{\n    int i,j;\n    spx_word32_t xout1,xout2,xin;\n    spx_word32_t mult, a;\n    VARDECL(spx_word16_t *freqn);\n    VARDECL(spx_word32_t **xp);\n    VARDECL(spx_word32_t *xpmem);\n    VARDECL(spx_word32_t **xq);\n    VARDECL(spx_word32_t *xqmem);\n    int m = lpcrdr>>1;\n\n    /* \n    \n       Reconstruct P(z) and Q(z) by cascading second order polynomials\n       in form 1 - 2cos(w)z(-1) + z(-2), where w is the LSP frequency.\n       In the time domain this is:\n\n       y(n) = x(n) - 2cos(w)x(n-1) + x(n-2)\n    \n       This is what the ALLOCS below are trying to do:\n\n         int xp[m+1][lpcrdr+1+2]; // P matrix in QIMP\n         int xq[m+1][lpcrdr+1+2]; // Q matrix in QIMP\n\n       These matrices store the output of each stage on each row.  The\n       final (m-th) row has the output of the final (m-th) cascaded\n       2nd order filter.  The first row is the impulse input to the\n       system (not written as it is known).\n\n       The version below takes advantage of the fact that a lot of the\n       outputs are zero or known, for example if we put an inpulse\n       into the first section the \"clock\" it 10 times only the first 3\n       outputs samples are non-zero (it's an FIR filter).\n    */\n\n    ALLOC(xp, (m+1), spx_word32_t*);\n    ALLOC(xpmem, (m+1)*(lpcrdr+1+2), spx_word32_t);\n\n    ALLOC(xq, (m+1), spx_word32_t*);\n    ALLOC(xqmem, (m+1)*(lpcrdr+1+2), spx_word32_t);\n    \n    for(i=0; i<=m; i++) {\n      xp[i] = xpmem + i*(lpcrdr+1+2);\n      xq[i] = xqmem + i*(lpcrdr+1+2);\n    }\n\n    /* work out 2cos terms in Q14 */\n\n    ALLOC(freqn, lpcrdr, spx_word16_t);\n    for (i=0;i<lpcrdr;i++) \n       freqn[i] = ANGLE2X(freq[i]);\n\n    #define QIMP  21   /* scaling for impulse */\n\n    xin = SHL32(EXTEND32(1), (QIMP-1)); /* 0.5 in QIMP format */\n   \n    /* first col and last non-zero values of each row are trivial */\n    \n    for(i=0;i<=m;i++) {\n     xp[i][1] = 0;\n     xp[i][2] = xin;\n     xp[i][2+2*i] = xin;\n     xq[i][1] = 0;\n     xq[i][2] = xin;\n     xq[i][2+2*i] = xin;\n    }\n\n    /* 2nd row (first output row) is trivial */\n\n    xp[1][3] = -MULT16_32_Q14(freqn[0],xp[0][2]);\n    xq[1][3] = -MULT16_32_Q14(freqn[1],xq[0][2]);\n\n    xout1 = xout2 = 0;\n\n    /* now generate remaining rows */\n\n    for(i=1;i<m;i++) {\n\n      for(j=1;j<2*(i+1)-1;j++) {\n\tmult = MULT16_32_Q14(freqn[2*i],xp[i][j+1]);\n\txp[i+1][j+2] = ADD32(SUB32(xp[i][j+2], mult), xp[i][j]);\n\tmult = MULT16_32_Q14(freqn[2*i+1],xq[i][j+1]);\n\txq[i+1][j+2] = ADD32(SUB32(xq[i][j+2], mult), xq[i][j]);\n      }\n\n      /* for last col xp[i][j+2] = xq[i][j+2] = 0 */\n\n      mult = MULT16_32_Q14(freqn[2*i],xp[i][j+1]);\n      xp[i+1][j+2] = SUB32(xp[i][j], mult);\n      mult = MULT16_32_Q14(freqn[2*i+1],xq[i][j+1]);\n      xq[i+1][j+2] = SUB32(xq[i][j], mult);\n    }\n\n    /* process last row to extra a{k} */\n\n    for(j=1;j<=lpcrdr;j++) {\n      int shift = QIMP-13;\n\n      /* final filter sections */\n      a = PSHR32(xp[m][j+2] + xout1 + xq[m][j+2] - xout2, shift); \n      xout1 = xp[m][j+2];\n      xout2 = xq[m][j+2];\n      \n      /* hard limit ak's to +/- 32767 */\n\n      if (a < -32767) a = -32767;\n      if (a > 32767) a = 32767;\n      ak[j-1] = (short)a;\n     \n    }\n\n}\n\n#else\n\nvoid lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack)\n/*  float *freq \tarray of LSP frequencies in the x domain\t*/\n/*  float *ak \t\tarray of LPC coefficients \t\t\t*/\n/*  int lpcrdr  \torder of LPC coefficients \t\t\t*/\n\n\n{\n    int i,j;\n    float xout1,xout2,xin1,xin2;\n    VARDECL(float *Wp);\n    float *pw,*n1,*n2,*n3,*n4=NULL;\n    VARDECL(float *x_freq);\n    int m = lpcrdr>>1;\n\n    ALLOC(Wp, 4*m+2, float);\n    pw = Wp;\n\n    /* initialise contents of array */\n\n    for(i=0;i<=4*m+1;i++){       \t/* set contents of buffer to 0 */\n\t*pw++ = 0.0;\n    }\n\n    /* Set pointers up */\n\n    pw = Wp;\n    xin1 = 1.0;\n    xin2 = 1.0;\n\n    ALLOC(x_freq, lpcrdr, float);\n    for (i=0;i<lpcrdr;i++)\n       x_freq[i] = ANGLE2X(freq[i]);\n\n    /* reconstruct P(z) and Q(z) by  cascading second order\n      polynomials in form 1 - 2xz(-1) +z(-2), where x is the\n      LSP coefficient */\n\n    for(j=0;j<=lpcrdr;j++){\n       int i2=0;\n\tfor(i=0;i<m;i++,i2+=2){\n\t    n1 = pw+(i*4);\n\t    n2 = n1 + 1;\n\t    n3 = n2 + 1;\n\t    n4 = n3 + 1;\n\t    xout1 = xin1 - 2.f*x_freq[i2] * *n1 + *n2;\n\t    xout2 = xin2 - 2.f*x_freq[i2+1] * *n3 + *n4;\n\t    *n2 = *n1;\n\t    *n4 = *n3;\n\t    *n1 = xin1;\n\t    *n3 = xin2;\n\t    xin1 = xout1;\n\t    xin2 = xout2;\n\t}\n\txout1 = xin1 + *(n4+1);\n\txout2 = xin2 - *(n4+2);\n\tif (j>0)\n\t   ak[j-1] = (xout1 + xout2)*0.5f;\n\t*(n4+1) = xin1;\n\t*(n4+2) = xin2;\n\n\txin1 = 0.0;\n\txin2 = 0.0;\n    }\n\n}\n#endif\n\n\n#ifdef FIXED_POINT\n\n/*Makes sure the LSPs are stable*/\nvoid lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin)\n{\n   int i;\n   spx_word16_t m = margin;\n   spx_word16_t m2 = 25736-margin;\n  \n   if (lsp[0]<m)\n      lsp[0]=m;\n   if (lsp[len-1]>m2)\n      lsp[len-1]=m2;\n   for (i=1;i<len-1;i++)\n   {\n      if (lsp[i]<lsp[i-1]+m)\n         lsp[i]=lsp[i-1]+m;\n\n      if (lsp[i]>lsp[i+1]-m)\n         lsp[i]= SHR16(lsp[i],1) + SHR16(lsp[i+1]-m,1);\n   }\n}\n\n\nvoid lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes)\n{\n   int i;\n   spx_word16_t tmp = DIV32_16(SHL32(EXTEND32(1 + subframe),14),nb_subframes);\n   spx_word16_t tmp2 = 16384-tmp;\n   for (i=0;i<len;i++)\n   {\n      interp_lsp[i] = MULT16_16_P14(tmp2,old_lsp[i]) + MULT16_16_P14(tmp,new_lsp[i]);\n   }\n}\n\n#else\n\n/*Makes sure the LSPs are stable*/\nvoid lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin)\n{\n   int i;\n   if (lsp[0]<LSP_SCALING*margin)\n      lsp[0]=LSP_SCALING*margin;\n   if (lsp[len-1]>LSP_SCALING*(M_PI-margin))\n      lsp[len-1]=LSP_SCALING*(M_PI-margin);\n   for (i=1;i<len-1;i++)\n   {\n      if (lsp[i]<lsp[i-1]+LSP_SCALING*margin)\n         lsp[i]=lsp[i-1]+LSP_SCALING*margin;\n\n      if (lsp[i]>lsp[i+1]-LSP_SCALING*margin)\n         lsp[i]= .5f* (lsp[i] + lsp[i+1]-LSP_SCALING*margin);\n   }\n}\n\n\nvoid lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes)\n{\n   int i;\n   float tmp = (1.0f + subframe)/nb_subframes;\n   for (i=0;i<len;i++)\n   {\n      interp_lsp[i] = (1-tmp)*old_lsp[i] + tmp*new_lsp[i];\n   }\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/lsp.h",
    "content": "/*---------------------------------------------------------------------------*\\\nOriginal Copyright\n\tFILE........: AK2LSPD.H\n\tTYPE........: Turbo C header file\n\tCOMPANY.....: Voicetronix\n\tAUTHOR......: James Whitehall\n\tDATE CREATED: 21/11/95\n\nModified by Jean-Marc Valin\n\n    This file contains functions for converting Linear Prediction\n    Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the\n    LSP coefficients are not in radians format but in the x domain of the\n    unit circle.\n\n\\*---------------------------------------------------------------------------*/\n/**\n   @file lsp.h\n   @brief Line Spectral Pair (LSP) functions.\n*/\n/* Speex License:\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef __AK2LSPD__\n#define __AK2LSPD__\n\n#include \"arch.h\"\n\nint lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack);\nvoid lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack);\n\n/*Added by JMV*/\nvoid lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin);\n\nvoid lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes);\n\n#endif\t/* __AK2LSPD__ */\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/lsp_bfin.h",
    "content": "/* Copyright (C) 2006 David Rowe */\n/**\n   @file lsp_bfin.h\n   @author David Rowe\n   @brief LSP routines optimised for the Blackfin\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#define OVERRIDE_CHEB_POLY_EVA\n#ifdef OVERRIDE_CHEB_POLY_EVA\nstatic inline spx_word32_t cheb_poly_eva(\n  spx_word16_t *coef, /* P or Q coefs in Q13 format               */\n  spx_word16_t     x, /* cos of freq (-1.0 to 1.0) in Q14 format  */\n  int              m, /* LPC order/2                              */\n  char         *stack\n)\n{\n    spx_word32_t sum;\n\n   __asm__ __volatile__\n     (\n      \"P0 = %2;\\n\\t\"           /* P0: coef[m], coef[m-1],..., coef[0] */\n      \"R4 = 8192;\\n\\t\"         /* R4: rounding constant               */\n      \"R2 = %1;\\n\\t\"           /* R2: x  */\n\n      \"R5 = -16383;\\n\\t\"\n      \"R2 = MAX(R2,R5);\\n\\t\"\n      \"R5 = 16383;\\n\\t\"\n      \"R2 = MIN(R2,R5);\\n\\t\"\n\n      \"R3 = W[P0--] (X);\\n\\t\"  /* R3: sum */\n      \"R5 = W[P0--] (X);\\n\\t\"\n      \"R5 = R5.L * R2.L (IS);\\n\\t\"\n      \"R5 = R5 + R4;\\n\\t\"\n      \"R5 >>>= 14;\\n\\t\"\n      \"R3 = R3 + R5;\\n\\t\" \n      \n      \"R0 = R2;\\n\\t\"           /* R0: b0 */\n      \"R1 = 16384;\\n\\t\"        /* R1: b1 */\n      \"LOOP cpe%= LC0 = %3;\\n\\t\"\n      \"LOOP_BEGIN cpe%=;\\n\\t\"\n        \"P1 = R0;\\n\\t\" \n        \"R0 = R2.L * R0.L (IS) || R5 = W[P0--] (X);\\n\\t\"\n        \"R0 >>>= 13;\\n\\t\"\n        \"R0 = R0 - R1;\\n\\t\"\n        \"R1 = P1;\\n\\t\"\n        \"R5 = R5.L * R0.L (IS);\\n\\t\"\n        \"R5 = R5 + R4;\\n\\t\"\n        \"R5 >>>= 14;\\n\\t\"\n        \"R3 = R3 + R5;\\n\\t\"\n      \"LOOP_END cpe%=;\\n\\t\"\n      \"%0 = R3;\\n\\t\"\n      : \"=&d\" (sum)\n      : \"a\" (x), \"a\" (&coef[m]), \"a\" (m-1)\n      : \"R0\", \"R1\", \"R3\", \"R2\", \"R4\", \"R5\", \"P0\", \"P1\"\n      );\n    return sum;\n}\n#endif\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/lsp_tables_nb.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: lsp_tables_nb.c\n   Codebooks for LSPs in narrowband CELP mode\n  \n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.  \n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\nconst signed char cdbk_nb[640]={\n30,19,38,34,40,32,46,43,58,43,\n5,-18,-25,-40,-33,-55,-52,20,34,28,\n-20,-63,-97,-92,61,53,47,49,53,75,\n-14,-53,-77,-79,0,-3,-5,19,22,26,\n-9,-53,-55,66,90,72,85,68,74,52,\n-4,-41,-58,-31,-18,-31,27,32,30,18,\n24,3,8,5,-12,-3,26,28,74,63,\n-2,-39,-67,-77,-106,-74,59,59,73,65,\n44,40,71,72,82,83,98,88,89,60,\n-6,-31,-47,-48,-13,-39,-9,7,2,79,\n-1,-39,-60,-17,87,81,65,50,45,19,\n-21,-67,-91,-87,-41,-50,7,18,39,74,\n10,-31,-28,39,24,13,23,5,56,45,\n29,10,-5,-13,-11,-35,-18,-8,-10,-8,\n-25,-71,-77,-21,2,16,50,63,87,87,\n5,-32,-40,-51,-68,0,12,6,54,34,\n5,-12,32,52,68,64,69,59,65,45,\n14,-16,-31,-40,-65,-67,41,49,47,37,\n-11,-52,-75,-84,-4,57,48,42,42,33,\n-11,-51,-68,-6,13,0,8,-8,26,32,\n-23,-53,0,36,56,76,97,105,111,97,\n-1,-28,-39,-40,-43,-54,-44,-40,-18,35,\n16,-20,-19,-28,-42,29,47,38,74,45,\n3,-29,-48,-62,-80,-104,-33,56,59,59,\n10,17,46,72,84,101,117,123,123,106,\n-7,-33,-49,-51,-70,-67,-27,-31,70,67,\n-16,-62,-85,-20,82,71,86,80,85,74,\n-19,-58,-75,-45,-29,-33,-18,-25,45,57,\n-12,-42,-5,12,28,36,52,64,81,82,\n13,-9,-27,-28,22,3,2,22,26,6,\n-6,-44,-51,2,15,10,48,43,49,34,\n-19,-62,-84,-89,-102,-24,8,17,61,68,\n39,24,23,19,16,-5,12,15,27,15,\n-8,-44,-49,-60,-18,-32,-28,52,54,62,\n-8,-48,-77,-70,66,101,83,63,61,37,\n-12,-50,-75,-64,33,17,13,25,15,77,\n1,-42,-29,72,64,46,49,31,61,44,\n-8,-47,-54,-46,-30,19,20,-1,-16,0,\n16,-12,-18,-9,-26,-27,-10,-22,53,45,\n-10,-47,-75,-82,-105,-109,8,25,49,77,\n50,65,114,117,124,118,115,96,90,61,\n-9,-45,-63,-60,-75,-57,8,11,20,29,\n0,-35,-49,-43,40,47,35,40,55,38,\n-24,-76,-103,-112,-27,3,23,34,52,75,\n8,-29,-43,12,63,38,35,29,24,8,\n25,11,1,-15,-18,-43,-7,37,40,21,\n-20,-56,-19,-19,-4,-2,11,29,51,63,\n-2,-44,-62,-75,-89,30,57,51,74,51,\n50,46,68,64,65,52,63,55,65,43,\n18,-9,-26,-35,-55,-69,3,6,8,17,\n-15,-61,-86,-97,1,86,93,74,78,67,\n-1,-38,-66,-48,48,39,29,25,17,-1,\n13,13,29,39,50,51,69,82,97,98,\n-2,-36,-46,-27,-16,-30,-13,-4,-7,-4,\n25,-5,-11,-6,-25,-21,33,12,31,29,\n-8,-38,-52,-63,-68,-89,-33,-1,10,74,\n-2,-15,59,91,105,105,101,87,84,62,\n-7,-33,-50,-35,-54,-47,25,17,82,81,\n-13,-56,-83,21,58,31,42,25,72,65,\n-24,-66,-91,-56,9,-2,21,10,69,75,\n2,-24,11,22,25,28,38,34,48,33,\n7,-29,-26,17,15,-1,14,0,-2,0,\n-6,-41,-67,6,-2,-9,19,2,85,74,\n-22,-67,-84,-71,-50,3,11,-9,2,62};\n\nconst signed char cdbk_nb_low1[320]={\n-34,-52,-15,45,2,\n23,21,52,24,-33,\n-9,-1,9,-44,-41,\n-13,-17,44,22,-17,\n-6,-4,-1,22,38,\n26,16,2,50,27,\n-35,-34,-9,-41,6,\n0,-16,-34,51,8,\n-14,-31,-49,15,-33,\n45,49,33,-11,-37,\n-62,-54,45,11,-5,\n-72,11,-1,-12,-11,\n24,27,-11,-43,46,\n43,33,-12,-9,-1,\n1,-4,-23,-57,-71,\n11,8,16,17,-8,\n-20,-31,-41,53,48,\n-16,3,65,-24,-8,\n-23,-32,-37,-32,-49,\n-10,-17,6,38,5,\n-9,-17,-46,8,52,\n3,6,45,40,39,\n-7,-6,-34,-74,31,\n8,1,-16,43,68,\n-11,-19,-31,4,6,\n0,-6,-17,-16,-38,\n-16,-30,2,9,-39,\n-16,-1,43,-10,48,\n3,3,-16,-31,-3,\n62,68,43,13,3,\n-10,8,20,-56,12,\n12,-2,-18,22,-15,\n-40,-36,1,7,41,\n0,1,46,-6,-62,\n-4,-12,-2,-11,-83,\n-13,-2,91,33,-10,\n0,4,-11,-16,79,\n32,37,14,9,51,\n-21,-28,-56,-34,0,\n21,9,-26,11,28,\n-42,-54,-23,-2,-15,\n31,30,8,-39,-66,\n-39,-36,31,-28,-40,\n-46,35,40,22,24,\n33,48,23,-34,14,\n40,32,17,27,-3,\n25,26,-13,-61,-17,\n11,4,31,60,-6,\n-26,-41,-64,13,16,\n-26,54,31,-11,-23,\n-9,-11,-34,-71,-21,\n-34,-35,55,50,29,\n-22,-27,-50,-38,57,\n33,42,57,48,26,\n11,0,-49,-31,26,\n-4,-14,5,78,37,\n17,0,-49,-12,-23,\n26,14,2,2,-43,\n-17,-12,10,-8,-4,\n8,18,12,-6,20,\n-12,-6,-13,-25,34,\n15,40,49,7,8,\n13,20,20,-19,-22,\n-2,-8,2,51,-51};\n\nconst signed char cdbk_nb_low2[320]={\n-6,53,-21,-24,4,\n26,17,-4,-37,25,\n17,-36,-13,31,3,\n-6,27,15,-10,31,\n28,26,-10,-10,-40,\n16,-7,15,13,41,\n-9,0,-4,50,-6,\n-7,14,38,22,0,\n-48,2,1,-13,-19,\n32,-3,-60,11,-17,\n-1,-24,-34,-1,35,\n-5,-27,28,44,13,\n25,15,42,-11,15,\n51,35,-36,20,8,\n-4,-12,-29,19,-47,\n49,-15,-4,16,-29,\n-39,14,-30,4,25,\n-9,-5,-51,-14,-3,\n-40,-32,38,5,-9,\n-8,-4,-1,-22,71,\n-3,14,26,-18,-22,\n24,-41,-25,-24,6,\n23,19,-10,39,-26,\n-27,65,45,2,-7,\n-26,-8,22,-12,16,\n15,16,-35,-5,33,\n-21,-8,0,23,33,\n34,6,21,36,6,\n-7,-22,8,-37,-14,\n31,38,11,-4,-3,\n-39,-32,-8,32,-23,\n-6,-12,16,20,-28,\n-4,23,13,-52,-1,\n22,6,-33,-40,-6,\n4,-62,13,5,-26,\n35,39,11,2,57,\n-11,9,-20,-28,-33,\n52,-5,-6,-2,22,\n-14,-16,-48,35,1,\n-58,20,13,33,-1,\n-74,56,-18,-22,-31,\n12,6,-14,4,-2,\n-9,-47,10,-3,29,\n-17,-5,61,14,47,\n-12,2,72,-39,-17,\n92,64,-53,-51,-15,\n-30,-38,-41,-29,-28,\n27,9,36,9,-35,\n-42,81,-21,20,25,\n-16,-5,-17,-35,21,\n15,-28,48,2,-2,\n9,-19,29,-40,30,\n-18,-18,18,-16,-57,\n15,-20,-12,-15,-37,\n-15,33,-39,21,-22,\n-13,35,11,13,-38,\n-63,29,23,-27,32,\n18,3,-26,42,33,\n-64,-66,-17,16,56,\n2,36,3,31,21,\n-41,-39,8,-57,14,\n37,-2,19,-36,-19,\n-23,-29,-16,1,-3,\n-8,-10,31,64,-65};\n\nconst signed char cdbk_nb_high1[320]={\n-26,-8,29,21,4,\n19,-39,33,-7,-36,\n56,54,48,40,29,\n-4,-24,-42,-66,-43,\n-60,19,-2,37,41,\n-10,-37,-60,-64,18,\n-22,77,73,40,25,\n4,19,-19,-66,-2,\n11,5,21,14,26,\n-25,-86,-4,18,1,\n26,-37,10,37,-1,\n24,-12,-59,-11,20,\n-6,34,-16,-16,42,\n19,-28,-51,53,32,\n4,10,62,21,-12,\n-34,27,4,-48,-48,\n-50,-49,31,-7,-21,\n-42,-25,-4,-43,-22,\n59,2,27,12,-9,\n-6,-16,-8,-32,-58,\n-16,-29,-5,41,23,\n-30,-33,-46,-13,-10,\n-38,52,52,1,-17,\n-9,10,26,-25,-6,\n33,-20,53,55,25,\n-32,-5,-42,23,21,\n66,5,-28,20,9,\n75,29,-7,-42,-39,\n15,3,-23,21,6,\n11,1,-29,14,63,\n10,54,26,-24,-51,\n-49,7,-23,-51,15,\n-66,1,60,25,10,\n0,-30,-4,-15,17,\n19,59,40,4,-5,\n33,6,-22,-58,-70,\n-5,23,-6,60,44,\n-29,-16,-47,-29,52,\n-19,50,28,16,35,\n31,36,0,-21,6,\n21,27,22,42,7,\n-66,-40,-8,7,19,\n46,0,-4,60,36,\n45,-7,-29,-6,-32,\n-39,2,6,-9,33,\n20,-51,-34,18,-6,\n19,6,11,5,-19,\n-29,-2,42,-11,-45,\n-21,-55,57,37,2,\n-14,-67,-16,-27,-38,\n69,48,19,2,-17,\n20,-20,-16,-34,-17,\n-25,-61,10,73,45,\n16,-40,-64,-17,-29,\n-22,56,17,-39,8,\n-11,8,-25,-18,-13,\n-19,8,54,57,36,\n-17,-26,-4,6,-21,\n40,42,-4,20,31,\n53,10,-34,-53,31,\n-17,35,0,15,-6,\n-20,-63,-73,22,25,\n29,17,8,-29,-39,\n-69,18,15,-15,-5};\n\nconst signed char cdbk_nb_high2[320]={\n11,47,16,-9,-46,\n-32,26,-64,34,-5,\n38,-7,47,20,2,\n-73,-99,-3,-45,20,\n70,-52,15,-6,-7,\n-82,31,21,47,51,\n39,-3,9,0,-41,\n-7,-15,-54,2,0,\n27,-31,9,-45,-22,\n-38,-24,-24,8,-33,\n23,5,50,-36,-17,\n-18,-51,-2,13,19,\n43,12,-15,-12,61,\n38,38,7,13,0,\n6,-1,3,62,9,\n27,22,-33,38,-35,\n-9,30,-43,-9,-32,\n-1,4,-4,1,-5,\n-11,-8,38,31,11,\n-10,-42,-21,-37,1,\n43,15,-13,-35,-19,\n-18,15,23,-26,59,\n1,-21,53,8,-41,\n-50,-14,-28,4,21,\n25,-28,-40,5,-40,\n-41,4,51,-33,-8,\n-8,1,17,-60,12,\n25,-41,17,34,43,\n19,45,7,-37,24,\n-15,56,-2,35,-10,\n48,4,-47,-2,5,\n-5,-54,5,-3,-33,\n-10,30,-2,-44,-24,\n-38,9,-9,42,4,\n6,-56,44,-16,9,\n-40,-26,18,-20,10,\n28,-41,-21,-4,13,\n-18,32,-30,-3,37,\n15,22,28,50,-40,\n3,-29,-64,7,51,\n-19,-11,17,-27,-40,\n-64,24,-12,-7,-27,\n3,37,48,-1,2,\n-9,-38,-34,46,1,\n27,-6,19,-13,26,\n10,34,20,25,40,\n50,-6,-7,30,9,\n-24,0,-23,71,-61,\n22,58,-34,-4,2,\n-49,-33,25,30,-8,\n-6,-16,77,2,38,\n-8,-35,-6,-30,56,\n78,31,33,-20,13,\n-39,20,22,4,21,\n-8,4,-6,10,-83,\n-41,9,-25,-43,15,\n-7,-12,-34,-39,-37,\n-33,19,30,16,-33,\n42,-25,25,-68,44,\n-15,-11,-4,23,50,\n14,4,-39,-43,20,\n-30,60,9,-20,7,\n16,19,-33,37,29,\n16,-35,7,38,-27};\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/ltp.c",
    "content": "/* Copyright (C) 2002-2006 Jean-Marc Valin \n   File: ltp.c\n   Long-Term Prediction functions\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <math.h>\n#include \"ltp.h\"\n#include \"stack_alloc.h\"\n#include \"filters.h\"\n#include <speex/speex_bits.h>\n#include \"math_approx.h\"\n#include \"os_support.h\"\n\n#ifndef NULL\n#define NULL 0\n#endif\n\n\n#ifdef _USE_SSE\n#include \"ltp_sse.h\"\n#elif defined (ARM4_ASM) || defined(ARM5E_ASM)\n#include \"ltp_arm4.h\"\n#elif defined (BFIN_ASM)\n#include \"ltp_bfin.h\"\n#endif\n\n#ifndef OVERRIDE_INNER_PROD\nspx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)\n{\n   spx_word32_t sum=0;\n   len >>= 2;\n   while(len--)\n   {\n      spx_word32_t part=0;\n      part = MAC16_16(part,*x++,*y++);\n      part = MAC16_16(part,*x++,*y++);\n      part = MAC16_16(part,*x++,*y++);\n      part = MAC16_16(part,*x++,*y++);\n      /* HINT: If you had a 40-bit accumulator, you could shift only at the end */\n      sum = ADD32(sum,SHR32(part,6));\n   }\n   return sum;\n}\n#endif\n\n#ifndef OVERRIDE_PITCH_XCORR\n#if 0 /* HINT: Enable this for machines with enough registers (i.e. not x86) */\nvoid pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)\n{\n   int i,j;\n   for (i=0;i<nb_pitch;i+=4)\n   {\n      /* Compute correlation*/\n      /*corr[nb_pitch-1-i]=inner_prod(x, _y+i, len);*/\n      spx_word32_t sum1=0;\n      spx_word32_t sum2=0;\n      spx_word32_t sum3=0;\n      spx_word32_t sum4=0;\n      const spx_word16_t *y = _y+i;\n      const spx_word16_t *x = _x;\n      spx_word16_t y0, y1, y2, y3;\n      /*y0=y[0];y1=y[1];y2=y[2];y3=y[3];*/\n      y0=*y++;\n      y1=*y++;\n      y2=*y++;\n      y3=*y++;\n      for (j=0;j<len;j+=4)\n      {\n         spx_word32_t part1;\n         spx_word32_t part2;\n         spx_word32_t part3;\n         spx_word32_t part4;\n         part1 = MULT16_16(*x,y0);\n         part2 = MULT16_16(*x,y1);\n         part3 = MULT16_16(*x,y2);\n         part4 = MULT16_16(*x,y3);\n         x++;\n         y0=*y++;\n         part1 = MAC16_16(part1,*x,y1);\n         part2 = MAC16_16(part2,*x,y2);\n         part3 = MAC16_16(part3,*x,y3);\n         part4 = MAC16_16(part4,*x,y0);\n         x++;\n         y1=*y++;\n         part1 = MAC16_16(part1,*x,y2);\n         part2 = MAC16_16(part2,*x,y3);\n         part3 = MAC16_16(part3,*x,y0);\n         part4 = MAC16_16(part4,*x,y1);\n         x++;\n         y2=*y++;\n         part1 = MAC16_16(part1,*x,y3);\n         part2 = MAC16_16(part2,*x,y0);\n         part3 = MAC16_16(part3,*x,y1);\n         part4 = MAC16_16(part4,*x,y2);\n         x++;\n         y3=*y++;\n         \n         sum1 = ADD32(sum1,SHR32(part1,6));\n         sum2 = ADD32(sum2,SHR32(part2,6));\n         sum3 = ADD32(sum3,SHR32(part3,6));\n         sum4 = ADD32(sum4,SHR32(part4,6));\n      }\n      corr[nb_pitch-1-i]=sum1;\n      corr[nb_pitch-2-i]=sum2;\n      corr[nb_pitch-3-i]=sum3;\n      corr[nb_pitch-4-i]=sum4;\n   }\n\n}\n#else\nvoid pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)\n{\n   int i;\n   for (i=0;i<nb_pitch;i++)\n   {\n      /* Compute correlation*/\n      corr[nb_pitch-1-i]=inner_prod(_x, _y+i, len);\n   }\n\n}\n#endif\n#endif\n\n#ifndef OVERRIDE_COMPUTE_PITCH_ERROR\nstatic inline spx_word32_t compute_pitch_error(spx_word16_t *C, spx_word16_t *g, spx_word16_t pitch_control)\n{\n   spx_word32_t sum = 0;\n   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0]));\n   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1]));\n   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2]));\n   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3]));\n   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4]));\n   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5]));\n   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6]));\n   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7]));\n   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8]));\n   return sum;\n}\n#endif\n\n#ifndef OVERRIDE_OPEN_LOOP_NBEST_PITCH\nvoid open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack)\n{\n   int i,j,k;\n   VARDECL(spx_word32_t *best_score);\n   VARDECL(spx_word32_t *best_ener);\n   spx_word32_t e0;\n   VARDECL(spx_word32_t *corr);\n#ifdef FIXED_POINT\n   /* In fixed-point, we need only one (temporary) array of 32-bit values and two (corr16, ener16) \n      arrays for (normalized) 16-bit values */\n   VARDECL(spx_word16_t *corr16);\n   VARDECL(spx_word16_t *ener16);\n   spx_word32_t *energy;\n   int cshift=0, eshift=0;\n   int scaledown = 0;\n   ALLOC(corr16, end-start+1, spx_word16_t);\n   ALLOC(ener16, end-start+1, spx_word16_t);\n   ALLOC(corr, end-start+1, spx_word32_t);\n   energy = corr;\n#else\n   /* In floating-point, we need to float arrays and no normalized copies */\n   VARDECL(spx_word32_t *energy);\n   spx_word16_t *corr16;\n   spx_word16_t *ener16;\n   ALLOC(energy, end-start+2, spx_word32_t);\n   ALLOC(corr, end-start+1, spx_word32_t);\n   corr16 = corr;\n   ener16 = energy;\n#endif\n   \n   ALLOC(best_score, N, spx_word32_t);\n   ALLOC(best_ener, N, spx_word32_t);\n   for (i=0;i<N;i++)\n   {\n        best_score[i]=-1;\n        best_ener[i]=0;\n        pitch[i]=start;\n   }\n   \n#ifdef FIXED_POINT\n   for (i=-end;i<len;i++)\n   {\n      if (ABS16(sw[i])>16383)\n      {\n         scaledown=1;\n         break;\n      }\n   }\n   /* If the weighted input is close to saturation, then we scale it down */\n   if (scaledown)\n   {\n      for (i=-end;i<len;i++)\n      {\n         sw[i]=SHR16(sw[i],1);\n      }\n   }      \n#endif\n   energy[0]=inner_prod(sw-start, sw-start, len);\n   e0=inner_prod(sw, sw, len);\n   for (i=start;i<end;i++)\n   {\n      /* Update energy for next pitch*/\n      energy[i-start+1] = SUB32(ADD32(energy[i-start],SHR32(MULT16_16(sw[-i-1],sw[-i-1]),6)), SHR32(MULT16_16(sw[-i+len-1],sw[-i+len-1]),6));\n      if (energy[i-start+1] < 0)\n         energy[i-start+1] = 0;\n   }\n   \n#ifdef FIXED_POINT\n   eshift = normalize16(energy, ener16, 32766, end-start+1);\n#endif\n   \n   /* In fixed-point, this actually overrites the energy array (aliased to corr) */\n   pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack);\n   \n#ifdef FIXED_POINT\n   /* Normalize to 180 so we can square it and it still fits in 16 bits */\n   cshift = normalize16(corr, corr16, 180, end-start+1);\n   /* If we scaled weighted input down, we need to scale it up again (OK, so we've just lost the LSB, who cares?) */\n   if (scaledown)\n   {\n      for (i=-end;i<len;i++)\n      {\n         sw[i]=SHL16(sw[i],1);\n      }\n   }      \n#endif\n\n   /* Search for the best pitch prediction gain */\n   for (i=start;i<=end;i++)\n   {\n      spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]);\n      /* Instead of dividing the tmp by the energy, we multiply on the other side */\n      if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))\n      {\n         /* We can safely put it last and then check */\n         best_score[N-1]=tmp;\n         best_ener[N-1]=ener16[i-start]+1;\n         pitch[N-1]=i;\n         /* Check if it comes in front of others */\n         for (j=0;j<N-1;j++)\n         {\n            if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))\n            {\n               for (k=N-1;k>j;k--)\n               {\n                  best_score[k]=best_score[k-1];\n                  best_ener[k]=best_ener[k-1];\n                  pitch[k]=pitch[k-1];\n               }\n               best_score[j]=tmp;\n               best_ener[j]=ener16[i-start]+1;\n               pitch[j]=i;\n               break;\n            }\n         }\n      }\n   }\n   \n   /* Compute open-loop gain if necessary */\n   if (gain)\n   {\n      for (j=0;j<N;j++)\n      {\n         spx_word16_t g;\n         i=pitch[j];\n         g = DIV32(SHL32(EXTEND32(corr16[i-start]),cshift), 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(SHL32(EXTEND32(ener16[i-start]),eshift))),6));\n         /* FIXME: g = max(g,corr/energy) */\n         if (g<0)\n            g = 0;\n         gain[j]=g;\n      }\n   }\n\n\n}\n#endif\n\n#ifndef OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ\nstatic int pitch_gain_search_3tap_vq(\n  const signed char *gain_cdbk,\n  int                gain_cdbk_size,\n  spx_word16_t      *C16,\n  spx_word16_t       max_gain\n)\n{\n  const signed char *ptr=gain_cdbk;\n  int                best_cdbk=0;\n  spx_word32_t       best_sum=-VERY_LARGE32;\n  spx_word32_t       sum=0;\n  spx_word16_t       g[3];\n  spx_word16_t       pitch_control=64;\n  spx_word16_t       gain_sum;\n  int                i;\n\n  for (i=0;i<gain_cdbk_size;i++) {\n         \n    ptr = gain_cdbk+4*i;\n    g[0]=ADD16((spx_word16_t)ptr[0],32);\n    g[1]=ADD16((spx_word16_t)ptr[1],32);\n    g[2]=ADD16((spx_word16_t)ptr[2],32);\n    gain_sum = (spx_word16_t)ptr[3];\n         \n    sum = compute_pitch_error(C16, g, pitch_control);\n         \n    if (sum>best_sum && gain_sum<=max_gain) {\n      best_sum=sum;\n      best_cdbk=i;\n    }\n  }\n\n  return best_cdbk;\n}\n#endif\n\n/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */\nstatic spx_word32_t pitch_gain_search_3tap(\nconst spx_word16_t target[],       /* Target vector */\nconst spx_coef_t ak[],          /* LPCs for this subframe */\nconst spx_coef_t awk1[],        /* Weighted LPCs #1 for this subframe */\nconst spx_coef_t awk2[],        /* Weighted LPCs #2 for this subframe */\nspx_sig_t exc[],                /* Excitation */\nconst signed char *gain_cdbk,\nint gain_cdbk_size,\nint   pitch,                    /* Pitch value */\nint   p,                        /* Number of LPC coeffs */\nint   nsf,                      /* Number of samples in subframe */\nSpeexBits *bits,\nchar *stack,\nconst spx_word16_t *exc2,\nconst spx_word16_t *r,\nspx_word16_t *new_target,\nint  *cdbk_index,\nint plc_tuning,\nspx_word32_t cumul_gain,\nint scaledown\n)\n{\n   int i,j;\n   VARDECL(spx_word16_t *tmp1);\n   VARDECL(spx_word16_t *e);\n   spx_word16_t *x[3];\n   spx_word32_t corr[3];\n   spx_word32_t A[3][3];\n   spx_word16_t gain[3];\n   spx_word32_t err;\n   spx_word16_t max_gain=128;\n   int          best_cdbk=0;\n\n   ALLOC(tmp1, 3*nsf, spx_word16_t);\n   ALLOC(e, nsf, spx_word16_t);\n\n   if (cumul_gain > 262144)\n      max_gain = 31;\n   \n   x[0]=tmp1;\n   x[1]=tmp1+nsf;\n   x[2]=tmp1+2*nsf;\n   \n   for (j=0;j<nsf;j++)\n      new_target[j] = target[j];\n\n   {\n      VARDECL(spx_mem_t *mm);\n      int pp=pitch-1;\n      ALLOC(mm, p, spx_mem_t);\n      for (j=0;j<nsf;j++)\n      {\n         if (j-pp<0)\n            e[j]=exc2[j-pp];\n         else if (j-pp-pitch<0)\n            e[j]=exc2[j-pp-pitch];\n         else\n            e[j]=0;\n      }\n#ifdef FIXED_POINT\n      /* Scale target and excitation down if needed (avoiding overflow) */\n      if (scaledown)\n      {\n         for (j=0;j<nsf;j++)\n            e[j] = SHR16(e[j],1);\n         for (j=0;j<nsf;j++)\n            new_target[j] = SHR16(new_target[j],1);\n      }\n#endif\n      for (j=0;j<p;j++)\n         mm[j] = 0;\n      iir_mem16(e, ak, e, nsf, p, mm, stack);\n      for (j=0;j<p;j++)\n         mm[j] = 0;\n      filter_mem16(e, awk1, awk2, e, nsf, p, mm, stack);\n      for (j=0;j<nsf;j++)\n         x[2][j] = e[j];\n   }\n   for (i=1;i>=0;i--)\n   {\n      spx_word16_t e0=exc2[-pitch-1+i];\n#ifdef FIXED_POINT\n      /* Scale excitation down if needed (avoiding overflow) */\n      if (scaledown)\n         e0 = SHR16(e0,1);\n#endif\n      x[i][0]=MULT16_16_Q14(r[0], e0);\n      for (j=0;j<nsf-1;j++)\n         x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0));\n   }\n\n   for (i=0;i<3;i++)\n      corr[i]=inner_prod(x[i],new_target,nsf);\n   for (i=0;i<3;i++)\n      for (j=0;j<=i;j++)\n         A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);\n\n   {\n      spx_word32_t C[9];\n#ifdef FIXED_POINT\n      spx_word16_t C16[9];\n#else\n      spx_word16_t *C16=C;\n#endif      \n      C[0]=corr[2];\n      C[1]=corr[1];\n      C[2]=corr[0];\n      C[3]=A[1][2];\n      C[4]=A[0][1];\n      C[5]=A[0][2];      \n      C[6]=A[2][2];\n      C[7]=A[1][1];\n      C[8]=A[0][0];\n      \n      /*plc_tuning *= 2;*/\n      if (plc_tuning<2)\n         plc_tuning=2;\n      if (plc_tuning>30)\n         plc_tuning=30;\n#ifdef FIXED_POINT\n      C[0] = SHL32(C[0],1);\n      C[1] = SHL32(C[1],1);\n      C[2] = SHL32(C[2],1);\n      C[3] = SHL32(C[3],1);\n      C[4] = SHL32(C[4],1);\n      C[5] = SHL32(C[5],1);\n      C[6] = MAC16_32_Q15(C[6],MULT16_16_16(plc_tuning,655),C[6]);\n      C[7] = MAC16_32_Q15(C[7],MULT16_16_16(plc_tuning,655),C[7]);\n      C[8] = MAC16_32_Q15(C[8],MULT16_16_16(plc_tuning,655),C[8]);\n      normalize16(C, C16, 32767, 9);\n#else\n      C[6]*=.5*(1+.02*plc_tuning);\n      C[7]*=.5*(1+.02*plc_tuning);\n      C[8]*=.5*(1+.02*plc_tuning);\n#endif\n\n      best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain);\n\n#ifdef FIXED_POINT\n      gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4]);\n      gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+1]);\n      gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+2]);\n      /*printf (\"%d %d %d %d\\n\",gain[0],gain[1],gain[2], best_cdbk);*/\n#else\n      gain[0] = 0.015625*gain_cdbk[best_cdbk*4]  + .5;\n      gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5;\n      gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5;\n#endif\n      *cdbk_index=best_cdbk;\n   }\n\n   SPEEX_MEMSET(exc, 0, nsf);\n   for (i=0;i<3;i++)\n   {\n      int j;\n      int tmp1, tmp3;\n      int pp=pitch+1-i;\n      tmp1=nsf;\n      if (tmp1>pp)\n         tmp1=pp;\n      for (j=0;j<tmp1;j++)\n         exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]);\n      tmp3=nsf;\n      if (tmp3>pp+pitch)\n         tmp3=pp+pitch;\n      for (j=tmp1;j<tmp3;j++)\n         exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]);\n   }\n   for (i=0;i<nsf;i++)\n   {\n      spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])),\n                            MULT16_16(gain[2],x[0][i]));\n      new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6)));\n   }\n   err = inner_prod(new_target, new_target, nsf);\n\n   return err;\n}\n\n/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */\nint pitch_search_3tap(\nspx_word16_t target[],                 /* Target vector */\nspx_word16_t *sw,\nspx_coef_t ak[],                     /* LPCs for this subframe */\nspx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */\nspx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */\nspx_sig_t exc[],                    /* Excitation */\nconst void *par,\nint   start,                    /* Smallest pitch value allowed */\nint   end,                      /* Largest pitch value allowed */\nspx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */\nint   p,                        /* Number of LPC coeffs */\nint   nsf,                      /* Number of samples in subframe */\nSpeexBits *bits,\nchar *stack,\nspx_word16_t *exc2,\nspx_word16_t *r,\nint complexity,\nint cdbk_offset,\nint plc_tuning,\nspx_word32_t *cumul_gain\n)\n{\n   int i;\n   int cdbk_index, pitch=0, best_gain_index=0;\n   VARDECL(spx_sig_t *best_exc);\n   VARDECL(spx_word16_t *new_target);\n   VARDECL(spx_word16_t *best_target);\n   int best_pitch=0;\n   spx_word32_t err, best_err=-1;\n   int N;\n   const ltp_params *params;\n   const signed char *gain_cdbk;\n   int   gain_cdbk_size;\n   int scaledown=0;\n         \n   VARDECL(int *nbest);\n   \n   params = (const ltp_params*) par;\n   gain_cdbk_size = 1<<params->gain_bits;\n   gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;\n   \n   N=complexity;\n   if (N>10)\n      N=10;\n   if (N<1)\n      N=1;\n\n   ALLOC(nbest, N, int);\n   params = (const ltp_params*) par;\n\n   if (end<start)\n   {\n      speex_bits_pack(bits, 0, params->pitch_bits);\n      speex_bits_pack(bits, 0, params->gain_bits);\n      SPEEX_MEMSET(exc, 0, nsf);\n      return start;\n   }\n   \n#ifdef FIXED_POINT\n   /* Check if we need to scale everything down in the pitch search to avoid overflows */\n   for (i=0;i<nsf;i++)\n   {\n      if (ABS16(target[i])>16383)\n      {\n         scaledown=1;\n         break;\n      }\n   }\n   for (i=-end;i<nsf;i++)\n   {\n      if (ABS16(exc2[i])>16383)\n      {\n         scaledown=1;\n         break;\n      }\n   }\n#endif\n   if (N>end-start+1)\n      N=end-start+1;\n   if (end != start)\n      open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack);\n   else\n      nbest[0] = start;\n   \n   ALLOC(best_exc, nsf, spx_sig_t);\n   ALLOC(new_target, nsf, spx_word16_t);\n   ALLOC(best_target, nsf, spx_word16_t);\n   \n   for (i=0;i<N;i++)\n   {\n      pitch=nbest[i];\n      SPEEX_MEMSET(exc, 0, nsf);\n      err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf,\n                                 bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown);\n      if (err<best_err || best_err<0)\n      {\n         SPEEX_COPY(best_exc, exc, nsf);\n         SPEEX_COPY(best_target, new_target, nsf);\n         best_err=err;\n         best_pitch=pitch;\n         best_gain_index=cdbk_index;\n      }\n   }\n   /*printf (\"pitch: %d %d\\n\", best_pitch, best_gain_index);*/\n   speex_bits_pack(bits, best_pitch-start, params->pitch_bits);\n   speex_bits_pack(bits, best_gain_index, params->gain_bits);\n#ifdef FIXED_POINT\n   *cumul_gain = MULT16_32_Q13(SHL16(params->gain_cdbk[4*best_gain_index+3],8), MAX32(1024,*cumul_gain));\n#else\n   *cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3];\n#endif\n   /*printf (\"%f\\n\", cumul_gain);*/\n   /*printf (\"encode pitch: %d %d\\n\", best_pitch, best_gain_index);*/\n   SPEEX_COPY(exc, best_exc, nsf);\n   SPEEX_COPY(target, best_target, nsf);\n#ifdef FIXED_POINT\n   /* Scale target back up if needed */\n   if (scaledown)\n   {\n      for (i=0;i<nsf;i++)\n         target[i]=SHL16(target[i],1);\n   }\n#endif\n   return pitch;\n}\n\nvoid pitch_unquant_3tap(\nspx_word16_t exc[],             /* Input excitation */\nspx_word32_t exc_out[],         /* Output excitation */\nint   start,                    /* Smallest pitch value allowed */\nint   end,                      /* Largest pitch value allowed */\nspx_word16_t pitch_coef,        /* Voicing (pitch) coefficient */\nconst void *par,\nint   nsf,                      /* Number of samples in subframe */\nint *pitch_val,\nspx_word16_t *gain_val,\nSpeexBits *bits,\nchar *stack,\nint count_lost,\nint subframe_offset,\nspx_word16_t last_pitch_gain,\nint cdbk_offset\n)\n{\n   int i;\n   int pitch;\n   int gain_index;\n   spx_word16_t gain[3];\n   const signed char *gain_cdbk;\n   int gain_cdbk_size;\n   const ltp_params *params;\n\n   params = (const ltp_params*) par;\n   gain_cdbk_size = 1<<params->gain_bits;\n   gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;\n\n   pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);\n   pitch += start;\n   gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);\n   /*printf (\"decode pitch: %d %d\\n\", pitch, gain_index);*/\n#ifdef FIXED_POINT\n   gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4]);\n   gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+1]);\n   gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+2]);\n#else\n   gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5;\n   gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5;\n   gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5;\n#endif\n\n   if (count_lost && pitch > subframe_offset)\n   {\n      spx_word16_t gain_sum;\n      if (1) {\n#ifdef FIXED_POINT\n         spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain,1);\n         if (tmp>62)\n            tmp=62;\n#else\n         spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain;\n         if (tmp>.95)\n            tmp=.95;\n#endif\n         gain_sum = gain_3tap_to_1tap(gain);\n\n         if (gain_sum > tmp)\n         {\n            spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp),14),gain_sum);\n            for (i=0;i<3;i++)\n               gain[i]=MULT16_16_Q14(fact,gain[i]);\n         }\n\n      }\n\n   }\n\n   *pitch_val = pitch;\n   gain_val[0]=gain[0];\n   gain_val[1]=gain[1];\n   gain_val[2]=gain[2];\n   gain[0] = SHL16(gain[0],7);\n   gain[1] = SHL16(gain[1],7);\n   gain[2] = SHL16(gain[2],7);\n   SPEEX_MEMSET(exc_out, 0, nsf);\n   for (i=0;i<3;i++)\n   {\n      int j;\n      int tmp1, tmp3;\n      int pp=pitch+1-i;\n      tmp1=nsf;\n      if (tmp1>pp)\n         tmp1=pp;\n      for (j=0;j<tmp1;j++)\n         exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]);\n      tmp3=nsf;\n      if (tmp3>pp+pitch)\n         tmp3=pp+pitch;\n      for (j=tmp1;j<tmp3;j++)\n         exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]);\n   }\n   /*for (i=0;i<nsf;i++)\n   exc[i]=PSHR32(exc32[i],13);*/\n}\n\n\n/** Forced pitch delay and gain */\nint forced_pitch_quant(\nspx_word16_t target[],                 /* Target vector */\nspx_word16_t *sw,\nspx_coef_t ak[],                     /* LPCs for this subframe */\nspx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */\nspx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */\nspx_sig_t exc[],                    /* Excitation */\nconst void *par,\nint   start,                    /* Smallest pitch value allowed */\nint   end,                      /* Largest pitch value allowed */\nspx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */\nint   p,                        /* Number of LPC coeffs */\nint   nsf,                      /* Number of samples in subframe */\nSpeexBits *bits,\nchar *stack,\nspx_word16_t *exc2,\nspx_word16_t *r,\nint complexity,\nint cdbk_offset,\nint plc_tuning,\nspx_word32_t *cumul_gain\n)\n{\n   int i;\n   VARDECL(spx_word16_t *res);\n   ALLOC(res, nsf, spx_word16_t);\n#ifdef FIXED_POINT\n   if (pitch_coef>63)\n      pitch_coef=63;\n#else\n   if (pitch_coef>.99)\n      pitch_coef=.99;\n#endif\n   for (i=0;i<nsf&&i<start;i++)\n   {\n      exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]);\n   }\n   for (;i<nsf;i++)\n   {\n      exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]);\n   }\n   for (i=0;i<nsf;i++)\n      res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1));\n   syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack);\n   for (i=0;i<nsf;i++)\n      target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700));\n   return start;\n}\n\n/** Unquantize forced pitch delay and gain */\nvoid forced_pitch_unquant(\nspx_word16_t exc[],             /* Input excitation */\nspx_word32_t exc_out[],         /* Output excitation */\nint   start,                    /* Smallest pitch value allowed */\nint   end,                      /* Largest pitch value allowed */\nspx_word16_t pitch_coef,        /* Voicing (pitch) coefficient */\nconst void *par,\nint   nsf,                      /* Number of samples in subframe */\nint *pitch_val,\nspx_word16_t *gain_val,\nSpeexBits *bits,\nchar *stack,\nint count_lost,\nint subframe_offset,\nspx_word16_t last_pitch_gain,\nint cdbk_offset\n)\n{\n   int i;\n#ifdef FIXED_POINT\n   if (pitch_coef>63)\n      pitch_coef=63;\n#else\n   if (pitch_coef>.99)\n      pitch_coef=.99;\n#endif\n   for (i=0;i<nsf;i++)\n   {\n      exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7));\n      exc[i] = EXTRACT16(PSHR32(exc_out[i],13));\n   }\n   *pitch_val = start;\n   gain_val[0]=gain_val[2]=0;\n   gain_val[1] = pitch_coef;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/ltp.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin */\n/**\n   @file ltp.h\n   @brief Long-Term Prediction functions\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#include <speex/speex_bits.h>\n#include \"arch.h\"\n\n/** LTP parameters. */\ntypedef struct {\n   const signed char *gain_cdbk;\n   int     gain_bits;\n   int     pitch_bits;\n} ltp_params;\n\n#ifdef FIXED_POINT\n#define gain_3tap_to_1tap(g) (ABS(g[1]) + (g[0]>0 ? g[0] : -SHR16(g[0],1)) + (g[2]>0 ? g[2] : -SHR16(g[2],1)))\n#else\n#define gain_3tap_to_1tap(g) (ABS(g[1]) + (g[0]>0 ? g[0] : -.5*g[0]) + (g[2]>0 ? g[2] : -.5*g[2]))\n#endif\n\nspx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len);\nvoid pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack);\n\nvoid open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack);\n\n\n/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */\nint pitch_search_3tap(\nspx_word16_t target[],                 /* Target vector */\nspx_word16_t *sw,\nspx_coef_t ak[],                     /* LPCs for this subframe */\nspx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */\nspx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */\nspx_sig_t exc[],                    /* Overlapping codebook */\nconst void *par,\nint   start,                    /* Smallest pitch value allowed */\nint   end,                      /* Largest pitch value allowed */\nspx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */\nint   p,                        /* Number of LPC coeffs */\nint   nsf,                      /* Number of samples in subframe */\nSpeexBits *bits,\nchar *stack,\nspx_word16_t *exc2,\nspx_word16_t *r,\nint   complexity,\nint   cdbk_offset,\nint plc_tuning,\nspx_word32_t *cumul_gain\n);\n\n/*Unquantize adaptive codebook and update pitch contribution*/\nvoid pitch_unquant_3tap(\nspx_word16_t exc[],             /* Input excitation */\nspx_word32_t exc_out[],         /* Output excitation */\nint   start,                    /* Smallest pitch value allowed */\nint   end,                      /* Largest pitch value allowed */\nspx_word16_t pitch_coef,        /* Voicing (pitch) coefficient */\nconst void *par,\nint   nsf,                      /* Number of samples in subframe */\nint *pitch_val,\nspx_word16_t *gain_val,\nSpeexBits *bits,\nchar *stack,\nint lost,\nint subframe_offset,\nspx_word16_t last_pitch_gain,\nint cdbk_offset\n);\n\n/** Forced pitch delay and gain */\nint forced_pitch_quant(\nspx_word16_t target[],                 /* Target vector */\nspx_word16_t *sw,\nspx_coef_t ak[],                     /* LPCs for this subframe */\nspx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */\nspx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */\nspx_sig_t exc[],                    /* Excitation */\nconst void *par,\nint   start,                    /* Smallest pitch value allowed */\nint   end,                      /* Largest pitch value allowed */\nspx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */\nint   p,                        /* Number of LPC coeffs */\nint   nsf,                      /* Number of samples in subframe */\nSpeexBits *bits,\nchar *stack,\nspx_word16_t *exc2,\nspx_word16_t *r,\nint complexity,\nint cdbk_offset,\nint plc_tuning,\nspx_word32_t *cumul_gain\n);\n\n/** Unquantize forced pitch delay and gain */\nvoid forced_pitch_unquant(\nspx_word16_t exc[],             /* Input excitation */\nspx_word32_t exc_out[],         /* Output excitation */\nint   start,                    /* Smallest pitch value allowed */\nint   end,                      /* Largest pitch value allowed */\nspx_word16_t pitch_coef,        /* Voicing (pitch) coefficient */\nconst void *par,\nint   nsf,                      /* Number of samples in subframe */\nint *pitch_val,\nspx_word16_t *gain_val,\nSpeexBits *bits,\nchar *stack,\nint lost,\nint subframe_offset,\nspx_word16_t last_pitch_gain,\nint cdbk_offset\n);\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/ltp_arm4.h",
    "content": "/* Copyright (C) 2004 Jean-Marc Valin */\n/**\n   @file ltp_arm4.h\n   @brief Long-Term Prediction functions (ARM4 version)\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#define OVERRIDE_INNER_PROD\nspx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)\n{\n   spx_word32_t sum1=0,sum2=0;\n   spx_word16_t *deadx, *deady;\n   int deadlen, dead1, dead2, dead3, dead4, dead5, dead6;\n   __asm__ __volatile__ (\n         \"\\tldrsh %5, [%0], #2 \\n\"\n         \"\\tldrsh %6, [%1], #2 \\n\"\n         \".inner_prod_loop%=:\\n\"\n         \"\\tsub %7, %7, %7\\n\"\n         \"\\tsub %10, %10, %10\\n\"\n\n         \"\\tldrsh %8, [%0], #2 \\n\"\n         \"\\tldrsh %9, [%1], #2 \\n\"\n         \"\\tmla %7, %5, %6, %7\\n\"\n         \"\\tldrsh %5, [%0], #2 \\n\"\n         \"\\tldrsh %6, [%1], #2 \\n\"\n         \"\\tmla %10, %8, %9, %10\\n\"\n         \"\\tldrsh %8, [%0], #2 \\n\"\n         \"\\tldrsh %9, [%1], #2 \\n\"\n         \"\\tmla %7, %5, %6, %7\\n\"\n         \"\\tldrsh %5, [%0], #2 \\n\"\n         \"\\tldrsh %6, [%1], #2 \\n\"\n         \"\\tmla %10, %8, %9, %10\\n\"\n\n         \"\\tldrsh %8, [%0], #2 \\n\"\n         \"\\tldrsh %9, [%1], #2 \\n\"\n         \"\\tmla %7, %5, %6, %7\\n\"\n         \"\\tldrsh %5, [%0], #2 \\n\"\n         \"\\tldrsh %6, [%1], #2 \\n\"\n         \"\\tmla %10, %8, %9, %10\\n\"\n         \"\\tldrsh %8, [%0], #2 \\n\"\n         \"\\tldrsh %9, [%1], #2 \\n\"\n         \"\\tmla %7, %5, %6, %7\\n\"\n         \"\\tldrsh %5, [%0], #2 \\n\"\n         \"\\tldrsh %6, [%1], #2 \\n\"\n         \"\\tmla %10, %8, %9, %10\\n\"\n\n         \"\\tsubs %4, %4, #1\\n\"\n         \"\\tadd %2, %2, %7, asr #5\\n\"\n         \"\\tadd %3, %3, %10, asr #5\\n\"\n         \"\\tbne .inner_prod_loop%=\\n\"\n   : \"=r\" (deadx), \"=r\" (deady), \"+r\" (sum1),  \"+r\" (sum2),\n     \"=r\" (deadlen), \"=r\" (dead1), \"=r\" (dead2), \"=r\" (dead3),\n     \"=r\" (dead4), \"=r\" (dead5), \"=r\" (dead6)\n   : \"0\" (x), \"1\" (y), \"4\" (len>>3)\n   : \"cc\"\n                        );\n   return (sum1+sum2)>>1;\n}\n\n#define OVERRIDE_PITCH_XCORR\nvoid pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)\n{\n   int i,j;\n   for (i=0;i<nb_pitch;i+=4)\n   {\n      /* Compute correlation*/\n      //corr[nb_pitch-1-i]=inner_prod(x, _y+i, len);\n      spx_word32_t sum1=0;\n      spx_word32_t sum2=0;\n      spx_word32_t sum3=0;\n      spx_word32_t sum4=0;\n      const spx_word16_t *y = _y+i;\n      const spx_word16_t *x = _x;\n      spx_word32_t y0, y1, y2, y3;\n      y0=*y++;\n      y1=*y++;\n      y2=*y++;\n      y3=*y++;\n      for (j=0;j<len;j+=4)\n      {\n         spx_word32_t part1, part2, part3, part4, x0;\n         spx_word32_t dead1;\n         __asm__ __volatile__ (\n#ifdef SHORTCUTS\n               \"\\tldrsh %10, [%8], #4 \\n\"\n               \"\\tmul %4, %10, %0 \\n\"\n               \"\\tldrsh %15, [%8], #4 \\n\"\n               \"\\tmul %5, %10, %1 \\n\"\n               \"\\tldrsh %0, [%9], #2 \\n\"\n               \"\\tmul %6, %10, %2 \\n\"\n               \"\\tldrsh %1, [%9], #2 \\n\"\n               \"\\tmul %7, %10, %3 \\n\"\n               \n               \n               \"\\tmla %4, %15, %2, %4 \\n\"\n               \"\\tldrsh %2, [%9], #2 \\n\"\n               \"\\tmla %5, %15, %3, %5 \\n\"\n               \"\\tldrsh %3, [%9], #2 \\n\"\n               \"\\tmla %6, %15, %0, %6 \\n\"\n               \"\\tmla %7, %15, %1, %7 \\n\"\n\n#else\n               \"\\tldrsh %10, [%8], #2 \\n\"\n               \"\\tmul %4, %10, %0 \\n\"\n               \"\\tmul %5, %10, %1 \\n\"\n               \"\\tmul %6, %10, %2 \\n\"\n               \"\\tmul %7, %10, %3 \\n\"\n\n               \"\\tldrsh %10, [%8], #2 \\n\"\n               \"\\tldrsh %0, [%9], #2 \\n\"\n               \"\\tmla %4, %10, %1, %4 \\n\"\n               \"\\tmla %5, %10, %2, %5 \\n\"\n               \"\\tmla %6, %10, %3, %6 \\n\"\n               \"\\tmla %7, %10, %0, %7 \\n\"\n\n               \"\\tldrsh %10, [%8], #2 \\n\"\n               \"\\tldrsh %1, [%9], #2 \\n\"\n               \"\\tmla %4, %10, %2, %4 \\n\"\n               \"\\tmla %5, %10, %3, %5 \\n\"\n               \"\\tmla %6, %10, %0, %6 \\n\"\n               \"\\tmla %7, %10, %1, %7 \\n\"\n\n               \"\\tldrsh %10, [%8], #2 \\n\"\n               \"\\tldrsh %2, [%9], #2 \\n\"\n               \"\\tmla %4, %10, %3, %4 \\n\"\n               \"\\tmla %5, %10, %0, %5 \\n\"\n               \"\\tmla %6, %10, %1, %6 \\n\"\n               \"\\tmla %7, %10, %2, %7 \\n\"\n\n               \"\\tldrsh %3, [%9], #2 \\n\"\n#endif\n\n               \"\\tldr %10, %11 \\n\"\n               \"\\tldr %15, %12 \\n\"\n               \"\\tadd %4, %10, %4, asr #6 \\n\"\n               \"\\tstr %4, %11 \\n\"\n               \"\\tldr %10, %13 \\n\"\n               \"\\tadd %5, %15, %5, asr #6 \\n\"\n               \"\\tstr %5, %12 \\n\"\n               \"\\tldr %15, %14 \\n\"\n               \"\\tadd %6, %10, %6, asr #6 \\n\"\n               \"\\tadd %7, %15, %7, asr #6 \\n\"\n               \"\\tstr %6, %13 \\n\"\n               \"\\tstr %7, %14 \\n\"\n\n            : \"+r\" (y0), \"+r\" (y1), \"+r\" (y2), \"+r\" (y3),\n         \"=r\" (part1),  \"=r\" (part2),  \"=r\" (part3),  \"=r\" (part4),\n              \"+r\" (x), \"+r\" (y), \"=r\" (x0), \"+m\" (sum1),\n              \"+m\" (sum2), \"+m\" (sum3), \"+m\" (sum4), \"=r\" (dead1)\n            :\n            : \"cc\", \"memory\"\n                              );\n      }\n      corr[nb_pitch-1-i]=sum1;\n      corr[nb_pitch-2-i]=sum2;\n      corr[nb_pitch-3-i]=sum3;\n      corr[nb_pitch-4-i]=sum4;\n   }\n\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/ltp_bfin.h",
    "content": "/* Copyright (C) 2005 Analog Devices */\n/**\n   @file ltp_bfin.h\n   @author Jean-Marc Valin\n   @brief Long-Term Prediction functions (Blackfin version)\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#define OVERRIDE_INNER_PROD\nspx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)\n{\n   spx_word32_t sum=0;\n   __asm__ __volatile__ (\n      \"P0 = %3;\\n\\t\"\n      \"P1 = %1;\\n\\t\"\n      \"P2 = %2;\\n\\t\"\n      \"I0 = P1;\\n\\t\"\n      \"I1 = P2;\\n\\t\"\n      \"L0 = 0;\\n\\t\"\n      \"L1 = 0;\\n\\t\"\n      \"A0 = 0;\\n\\t\"\n      \"R0.L = W[I0++] || R1.L = W[I1++];\\n\\t\"\n      \"LOOP inner%= LC0 = P0;\\n\\t\"\n      \"LOOP_BEGIN inner%=;\\n\\t\"\n         \"A0 += R0.L*R1.L (IS) || R0.L = W[I0++] || R1.L = W[I1++];\\n\\t\"\n      \"LOOP_END inner%=;\\n\\t\"\n      \"A0 += R0.L*R1.L (IS);\\n\\t\"\n      \"A0 = A0 >>> 6;\\n\\t\"\n      \"R0 = A0;\\n\\t\"\n      \"%0 = R0;\\n\\t\"\n   : \"=m\" (sum)\n   : \"m\" (x), \"m\" (y), \"d\" (len-1)\n   : \"P0\", \"P1\", \"P2\", \"R0\", \"R1\", \"A0\", \"I0\", \"I1\", \"L0\", \"L1\", \"R3\"\n   );\n   return sum;\n}\n\n#define OVERRIDE_PITCH_XCORR\nvoid pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)\n{\n   corr += nb_pitch - 1;\n   __asm__ __volatile__ (\n      \"P2 = %0;\\n\\t\"\n      \"I0 = P2;\\n\\t\" /* x in I0 */\n      \"B0 = P2;\\n\\t\" /* x in B0 */\n      \"R0 = %3;\\n\\t\" /* len in R0 */\n      \"P3 = %3;\\n\\t\"\n      \"P3 += -2;\\n\\t\" /* len in R0 */\n      \"P4 = %4;\\n\\t\" /* nb_pitch in R0 */\n      \"R1 = R0 << 1;\\n\\t\" /* number of bytes in x */\n      \"L0 = R1;\\n\\t\"\n      \"P0 = %1;\\n\\t\"\n\n      \"P1 = %2;\\n\\t\"\n      \"B1 = P1;\\n\\t\"\n      \"L1 = 0;\\n\\t\" /*Disable looping on I1*/\n\n      \"r0 = [I0++];\\n\\t\"\n      \"LOOP pitch%= LC0 = P4 >> 1;\\n\\t\"\n      \"LOOP_BEGIN pitch%=;\\n\\t\"\n         \"I1 = P0;\\n\\t\"\n         \"A1 = A0 = 0;\\n\\t\"\n         \"R1 = [I1++];\\n\\t\"\n         \"LOOP inner_prod%= LC1 = P3 >> 1;\\n\\t\"\n         \"LOOP_BEGIN inner_prod%=;\\n\\t\"\n            \"A1 += R0.L*R1.H, A0 += R0.L*R1.L (IS) || R1.L = W[I1++];\\n\\t\"\n            \"A1 += R0.H*R1.L, A0 += R0.H*R1.H (IS) || R1.H = W[I1++] || R0 = [I0++];\\n\\t\"\n         \"LOOP_END inner_prod%=;\\n\\t\"\n         \"A1 += R0.L*R1.H, A0 += R0.L*R1.L (IS) || R1.L = W[I1++];\\n\\t\"\n         \"A1 += R0.H*R1.L, A0 += R0.H*R1.H (IS) || R0 = [I0++];\\n\\t\"\n         \"A0 = A0 >>> 6;\\n\\t\"\n         \"A1 = A1 >>> 6;\\n\\t\"\n         \"R2 = A0, R3 = A1;\\n\\t\"\n         \"[P1--] = r2;\\n\\t\"\n         \"[P1--] = r3;\\n\\t\"\n         \"P0 += 4;\\n\\t\"\n      \"LOOP_END pitch%=;\\n\\t\"\n      \"L0 = 0;\\n\\t\"\n   : : \"m\" (_x), \"m\" (_y), \"m\" (corr), \"m\" (len), \"m\" (nb_pitch)\n   : \"A0\", \"A1\", \"P0\", \"P1\", \"P2\", \"P3\", \"P4\", \"R0\", \"R1\", \"R2\", \"R3\", \"I0\", \"I1\", \"L0\", \"L1\", \"B0\", \"B1\", \"memory\"\n   );\n}\n\n#define OVERRIDE_COMPUTE_PITCH_ERROR\nstatic inline spx_word32_t compute_pitch_error(spx_word16_t *C, spx_word16_t *g, spx_word16_t pitch_control)\n{\n   spx_word32_t sum;\n   __asm__ __volatile__\n         (\n         \"A0 = 0;\\n\\t\"\n         \n         \"R0 = W[%1++];\\n\\t\"\n         \"R1.L = %2.L*%5.L (IS);\\n\\t\"\n         \"A0 += R1.L*R0.L (IS) || R0 = W[%1++];\\n\\t\"\n         \n         \"R1.L = %3.L*%5.L (IS);\\n\\t\"\n         \"A0 += R1.L*R0.L (IS) || R0 = W[%1++];\\n\\t\"\n         \n         \"R1.L = %4.L*%5.L (IS);\\n\\t\"\n         \"A0 += R1.L*R0.L (IS) || R0 = W[%1++];\\n\\t\"\n         \n         \"R1.L = %2.L*%3.L (IS);\\n\\t\"\n         \"A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\\n\\t\"\n\n         \"R1.L = %4.L*%3.L (IS);\\n\\t\"\n         \"A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\\n\\t\"\n         \n         \"R1.L = %4.L*%2.L (IS);\\n\\t\"\n         \"A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\\n\\t\"\n         \n         \"R1.L = %2.L*%2.L (IS);\\n\\t\"\n         \"A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\\n\\t\"\n\n         \"R1.L = %3.L*%3.L (IS);\\n\\t\"\n         \"A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\\n\\t\"\n         \n         \"R1.L = %4.L*%4.L (IS);\\n\\t\"\n         \"A0 -= R1.L*R0.L (IS);\\n\\t\"\n         \n         \"%0 = A0;\\n\\t\"\n   : \"=&D\" (sum), \"=a\" (C)\n   : \"d\" (g[0]), \"d\" (g[1]), \"d\" (g[2]), \"d\" (pitch_control), \"1\" (C)\n   : \"R0\", \"R1\", \"R2\", \"A0\"\n         );\n   return sum;\n}\n\n#define OVERRIDE_OPEN_LOOP_NBEST_PITCH\n#ifdef OVERRIDE_OPEN_LOOP_NBEST_PITCH\nvoid open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack)\n{\n   int i,j,k;\n   VARDECL(spx_word32_t *best_score);\n   VARDECL(spx_word32_t *best_ener);\n   spx_word32_t e0;\n   VARDECL(spx_word32_t *corr);\n   VARDECL(spx_word32_t *energy);\n\n   ALLOC(best_score, N, spx_word32_t);\n   ALLOC(best_ener, N, spx_word32_t);\n   ALLOC(corr, end-start+1, spx_word32_t);\n   ALLOC(energy, end-start+2, spx_word32_t);\n\n   for (i=0;i<N;i++)\n   {\n        best_score[i]=-1;\n        best_ener[i]=0;\n        pitch[i]=start;\n   }\n\n   energy[0]=inner_prod(sw-start, sw-start, len);\n   e0=inner_prod(sw, sw, len);\n\n   /* energy update -------------------------------------*/\n\n      __asm__ __volatile__\n      (\n\"        P0 = %0;\\n\\t\"\n\"        I1 = %1;\\n\\t\"\n\"        L1 = 0;\\n\\t\"\n\"        I2 = %2;\\n\\t\"\n\"        L2 = 0;\\n\\t\"\n\"        R2 = [P0++];\\n\\t\"\n\"        R3 = 0;\\n\\t\"\n\"        LSETUP (eu1, eu2) LC1 = %3;\\n\\t\"\n\"eu1:      R1.L = W [I1--] || R0.L = W [I2--] ;\\n\\t\"\n\"          R1 = R1.L * R1.L (IS);\\n\\t\"\n\"          R0 = R0.L * R0.L (IS);\\n\\t\"\n\"          R1 >>>= 6;\\n\\t\"\n\"          R1 = R1 + R2;\\n\\t\"\n\"          R0 >>>= 6;\\n\\t\"\n\"          R1 = R1 - R0;\\n\\t\"\n\"          R2 = MAX(R1,R3);\\n\\t\"\n\"eu2:      [P0++] = R2;\\n\\t\"\n       : : \"d\" (energy), \"d\" (&sw[-start-1]), \"d\" (&sw[-start+len-1]),\n           \"a\" (end-start)  \n       : \"P0\", \"I1\", \"I2\", \"R0\", \"R1\", \"R2\", \"R3\"\n#if (__GNUC__ == 4)\n         , \"LC1\"\n#endif\n       );\n\n   pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack);\n\n   /* FIXME: Fixed-point and floating-point code should be merged */\n   {\n      VARDECL(spx_word16_t *corr16);\n      VARDECL(spx_word16_t *ener16);\n      ALLOC(corr16, end-start+1, spx_word16_t);\n      ALLOC(ener16, end-start+1, spx_word16_t);\n      /* Normalize to 180 so we can square it and it still fits in 16 bits */\n      normalize16(corr, corr16, 180, end-start+1);\n      normalize16(energy, ener16, 180, end-start+1);\n\n      if (N == 1) {\n\t/* optimised asm to handle N==1 case */\n      __asm__ __volatile__\n      (\n\"        I0 = %1;\\n\\t\"                     /* I0: corr16[]    */\n\"        L0 = 0;\\n\\t\"\n\"        I1 = %2;\\n\\t\"                     /* I1: energy      */\n\"        L1 = 0;\\n\\t\"\n\"        R2 = -1;\\n\\t\"                     /* R2: best score  */\n\"        R3 = 0;\\n\\t\"                      /* R3: best energy */\n\"        P0 = %4;\\n\\t\"                     /* P0: best pitch  */\n\"        P1 = %4;\\n\\t\"                     /* P1: counter     */\n\"        LSETUP (sl1, sl2) LC1 = %3;\\n\\t\"\n\"sl1:      R0.L = W [I0++] || R1.L = W [I1++];\\n\\t\"         \n\"          R0 = R0.L * R0.L (IS);\\n\\t\"\n\"          R1   += 1;\\n\\t\"\n\"          R4   = R0.L * R3.L;\\n\\t\"\n\"          R5   = R2.L * R1.L;\\n\\t\"\n\"          cc   = R5 < R4;\\n\\t\"\n\"          if cc R2 = R0;\\n\\t\"\n\"          if cc R3 = R1;\\n\\t\"\n\"          if cc P0 = P1;\\n\\t\"\n\"sl2:      P1 += 1;\\n\\t\"\n\"        %0 = P0;\\n\\t\"\n       : \"=&d\" (pitch[0])\n       : \"a\" (corr16), \"a\" (ener16), \"a\" (end+1-start), \"d\" (start) \n       : \"P0\", \"P1\", \"I0\", \"I1\", \"R0\", \"R1\", \"R2\", \"R3\", \"R4\", \"R5\"\n#if (__GNUC__ == 4)\n         , \"LC1\"\n#endif\n       );\n\n      }\n      else {\n\tfor (i=start;i<=end;i++)\n\t  {\n\t    spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]);\n\t    /* Instead of dividing the tmp by the energy, we multiply on the other side */\n\t    if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))\n\t      {\n\t\t/* We can safely put it last and then check */\n\t\tbest_score[N-1]=tmp;\n\t\tbest_ener[N-1]=ener16[i-start]+1;\n\t\tpitch[N-1]=i;\n\t\t/* Check if it comes in front of others */\n\t\tfor (j=0;j<N-1;j++)\n\t\t  {\n\t\t    if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))\n\t\t      {\n\t\t\tfor (k=N-1;k>j;k--)\n\t\t\t  {\n\t\t\t    best_score[k]=best_score[k-1];\n\t\t\t    best_ener[k]=best_ener[k-1];\n\t\t\t    pitch[k]=pitch[k-1];\n\t\t\t  }\n\t\t\tbest_score[j]=tmp;\n\t\t\tbest_ener[j]=ener16[i-start]+1;\n\t\t\tpitch[j]=i;\n\t\t\tbreak;\n\t\t      }\n\t\t  }\n\t      }\n\t  }\n      }\n   }\n\n   /* Compute open-loop gain */\n   if (gain)\n   {\n       for (j=0;j<N;j++)\n       {\n          spx_word16_t g;\n          i=pitch[j];\n          g = DIV32(corr[i-start], 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(energy[i-start])),6));\n          /* FIXME: g = max(g,corr/energy) */\n                   if (g<0)\n                   g = 0;\n             gain[j]=g;\n       }\n   }\n}\n#endif\n\n#define OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ\n#ifdef OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ\nstatic int pitch_gain_search_3tap_vq(\n  const signed char *gain_cdbk,\n  int                gain_cdbk_size,\n  spx_word16_t      *C16,\n  spx_word16_t       max_gain\n)\n{\n  const signed char *ptr=gain_cdbk;\n  int                best_cdbk=0;\n  spx_word32_t       best_sum=-VERY_LARGE32;\n  spx_word32_t       sum=0;\n  spx_word16_t       g[3];\n  spx_word16_t       pitch_control=64;\n  spx_word16_t       gain_sum;\n  int                i;\n\n      /* fast asm version of VQ codebook search */\n\n      __asm__ __volatile__\n      (\n\n\"        P0 = %2;\\n\\t\"                     /* P0: ptr to gain_cdbk */\n\"        L1 = 0;\\n\\t\"                      /* no circ addr for L1  */\n\"        %0 = 0;\\n\\t\"                      /* %0: best_sum         */\n\"        %1 = 0;\\n\\t\"                      /* %1: best_cbdk        */\n\"        P1 = 0;\\n\\t\"                      /* P1: loop counter     */\n\n\"        LSETUP (pgs1, pgs2) LC1 = %4;\\n\\t\"\n\"pgs1:     R2  = B [P0++] (X);\\n\\t\"        /* R2: g[0]             */\n\"          R3  = B [P0++] (X);\\n\\t\"        /* R3: g[1]             */\n\"          R4  = B [P0++] (X);\\n\\t\"        /* R4: g[2]             */\n\"          R2 += 32;\\n\\t\"\n\"          R3 += 32;\\n\\t\"\n\"          R4 += 32;\\n\\t\"\n\"          R4.H = 64;\\n\\t\"                 /* R4.H: pitch_control    */\n\n\"          R0  = B [P0++] (X);\\n\\t\"              \n\"          B0  = R0;\\n\\t\"                  /* BO: gain_sum         */\n          \n           /* compute_pitch_error() -------------------------------*/\n\n\"          I1 = %3;\\n\\t\"                   /* I1: ptr to C         */\n\"          A0 = 0;\\n\\t\"\n         \n\"          R0.L = W[I1++];\\n\\t\"\n\"          R1.L = R2.L*R4.H (IS);\\n\\t\"\n\"          A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\\n\\t\"\n         \n\"          R1.L = R3.L*R4.H (IS);\\n\\t\"\n\"          A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\\n\\t\"\n         \n\"          R1.L = R4.L*R4.H (IS);\\n\\t\"\n\"          A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\\n\\t\"\n         \n\"          R1.L = R2.L*R3.L (IS);\\n\\t\"\n\"          A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\\n\\t\"\n\n\"          R1.L = R4.L*R3.L (IS);\\n\\t\"\n\"          A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\\n\\t\"\n         \n\"          R1.L = R4.L*R2.L (IS);\\n\\t\"\n\"          A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\\n\\t\"\n         \n\"          R1.L = R2.L*R2.L (IS);\\n\\t\"\n\"          A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\\n\\t\"\n\n\"          R1.L = R3.L*R3.L (IS);\\n\\t\"\n\"          A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\\n\\t\"\n         \n\"          R1.L = R4.L*R4.L (IS);\\n\\t\"\n\"          R0 = (A0 -= R1.L*R0.L) (IS);\\n\\t\"\n\n/*\n    Re-arrange the if-then to code efficiently on the Blackfin:\n\n      if (sum>best_sum && gain_sum<=max_gain)   ------ (1)\n\n      if (sum>best_sum && !(gain_sum>max_gain)) ------ (2)\n\n      if (max_gain<=gain_sum) {                 ------ (3)\n      sum = -VERY_LARGE32;\n      }\n      if (best_sum<=sum)\n\n    The blackin cc instructions are all of the form:\n\n      cc = x < y (or cc = x <= y)\n*/\n\"          R1 = B0\\n\\t\"\n\"          R2 = %5\\n\\t\"\n\"          R3 = %6\\n\\t\"\n\"          cc = R2 <= R1;\\n\\t\" \n\"          if cc R0 = R3;\\n\\t\"\n\"          cc = %0 <= R0;\\n\\t\"\n\"          if cc %0 = R0;\\n\\t\"\n\"          if cc %1 = P1;\\n\\t\"\n\n\"pgs2:     P1 += 1;\\n\\t\"\n   \n       : \"=&d\" (best_sum), \"=&d\" (best_cdbk) \n       : \"a\" (gain_cdbk), \"a\" (C16), \"a\" (gain_cdbk_size), \"a\" (max_gain),\n         \"b\" (-VERY_LARGE32)\n       : \"R0\", \"R1\", \"R2\", \"R3\", \"R4\", \"P0\", \n         \"P1\", \"I1\", \"L1\", \"A0\", \"B0\"\n#if (__GNUC__ == 4)\n         , \"LC1\"\n#endif\n       );\n\n  return best_cdbk;\n}\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/ltp_sse.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin */\n/**\n   @file ltp_sse.h\n   @brief Long-Term Prediction functions (SSE version)\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#include <xmmintrin.h>\n\n#define OVERRIDE_INNER_PROD\nfloat inner_prod(const float *a, const float *b, int len)\n{\n   int i;\n   float ret;\n   __m128 sum = _mm_setzero_ps();\n   for (i=0;i<(len>>2);i+=2)\n   {\n      sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+0), _mm_loadu_ps(b+0)));\n      sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+4), _mm_loadu_ps(b+4)));\n      a += 8;\n      b += 8;\n   }\n   sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));\n   sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));\n   _mm_store_ss(&ret, sum);\n   return ret;\n}\n\n#define OVERRIDE_PITCH_XCORR\nvoid pitch_xcorr(const float *_x, const float *_y, float *corr, int len, int nb_pitch, char *stack)\n{\n   int i, offset;\n   VARDECL(__m128 *x);\n   VARDECL(__m128 *y);\n   int N, L;\n   N = len>>2;\n   L = nb_pitch>>2;\n   ALLOC(x, N, __m128);\n   ALLOC(y, N+L, __m128);\n   for (i=0;i<N;i++)\n      x[i] = _mm_loadu_ps(_x+(i<<2));\n   for (offset=0;offset<4;offset++)\n   {\n      for (i=0;i<N+L;i++)\n         y[i] = _mm_loadu_ps(_y+(i<<2)+offset);\n      for (i=0;i<L;i++)\n      {\n         int j;\n         __m128 sum, *xx, *yy;\n         sum = _mm_setzero_ps();\n         yy = y+i;\n         xx = x;\n         for (j=0;j<N;j+=2)\n         {\n            sum = _mm_add_ps(sum, _mm_mul_ps(xx[0], yy[0]));\n            sum = _mm_add_ps(sum, _mm_mul_ps(xx[1], yy[1]));\n            xx += 2;\n            yy += 2;\n         }\n         sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));\n         sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));\n         _mm_store_ss(corr+nb_pitch-1-(i<<2)-offset, sum);\n      }\n   }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/math_approx.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin */\n/**\n   @file math_approx.h\n   @brief Various math approximation functions for Speex\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef MATH_APPROX_H\n#define MATH_APPROX_H\n\n#include \"arch.h\"\n\n#ifndef FIXED_POINT\n\n#define spx_sqrt sqrt\n#define spx_acos acos\n#define spx_exp exp\n#define spx_cos_norm(x) (cos((.5f*M_PI)*(x)))\n#define spx_atan atan\n\n/** Generate a pseudo-random number */\nstatic inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)\n{\n   const unsigned int jflone = 0x3f800000;\n   const unsigned int jflmsk = 0x007fffff;\n   union {int i; float f;} ran;\n   *seed = 1664525 * *seed + 1013904223;\n   ran.i = jflone | (jflmsk & *seed);\n   ran.f -= 1.5;\n   return 3.4642*std*ran.f;\n}\n\n\n#endif\n\n\nstatic inline spx_int16_t spx_ilog2(spx_uint32_t x)\n{\n   int r=0;\n   if (x>=(spx_int32_t)65536)\n   {\n      x >>= 16;\n      r += 16;\n   }\n   if (x>=256)\n   {\n      x >>= 8;\n      r += 8;\n   }\n   if (x>=16)\n   {\n      x >>= 4;\n      r += 4;\n   }\n   if (x>=4)\n   {\n      x >>= 2;\n      r += 2;\n   }\n   if (x>=2)\n   {\n      r += 1;\n   }\n   return r;\n}\n\nstatic inline spx_int16_t spx_ilog4(spx_uint32_t x)\n{\n   int r=0;\n   if (x>=(spx_int32_t)65536)\n   {\n      x >>= 16;\n      r += 8;\n   }\n   if (x>=256)\n   {\n      x >>= 8;\n      r += 4;\n   }\n   if (x>=16)\n   {\n      x >>= 4;\n      r += 2;\n   }\n   if (x>=4)\n   {\n      r += 1;\n   }\n   return r;\n}\n\n#ifdef FIXED_POINT\n\n/** Generate a pseudo-random number */\nstatic inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)\n{\n   spx_word32_t res;\n   *seed = 1664525 * *seed + 1013904223;\n   res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std);\n   return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14));\n}\n\n/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */\n/*#define C0 3634\n#define C1 21173\n#define C2 -12627\n#define C3 4215*/\n\n/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */\n#define C0 3634\n#define C1 21173\n#define C2 -12627\n#define C3 4204\n\nstatic inline spx_word16_t spx_sqrt(spx_word32_t x)\n{\n   int k;\n   spx_word32_t rt;\n   k = spx_ilog4(x)-6;\n   x = VSHR32(x, (k<<1));\n   rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3)))))));\n   rt = VSHR32(rt,7-k);\n   return rt;\n}\n\n/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */\n\n\n#define A1 16469\n#define A2 2242\n#define A3 1486\n\nstatic inline spx_word16_t spx_acos(spx_word16_t x)\n{\n   int s=0;\n   spx_word16_t ret;\n   spx_word16_t sq;\n   if (x<0)\n   {\n      s=1;\n      x = NEG16(x);\n   }\n   x = SUB16(16384,x);\n   \n   x = x >> 1;\n   sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3))))));\n   ret = spx_sqrt(SHL32(EXTEND32(sq),13));\n   \n   /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/\n   if (s)\n      ret = SUB16(25736,ret);\n   return ret;\n}\n\n\n#define K1 8192\n#define K2 -4096\n#define K3 340\n#define K4 -10\n\nstatic inline spx_word16_t spx_cos(spx_word16_t x)\n{\n   spx_word16_t x2;\n\n   if (x<12868)\n   {\n      x2 = MULT16_16_P13(x,x);\n      return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));\n   } else {\n      x = SUB16(25736,x);\n      x2 = MULT16_16_P13(x,x);\n      return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));\n   }\n}\n\n#define L1 32767\n#define L2 -7651\n#define L3 8277\n#define L4 -626\n\nstatic inline spx_word16_t _spx_cos_pi_2(spx_word16_t x)\n{\n   spx_word16_t x2;\n   \n   x2 = MULT16_16_P15(x,x);\n   return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2))))))));\n}\n\nstatic inline spx_word16_t spx_cos_norm(spx_word32_t x)\n{\n   x = x&0x0001ffff;\n   if (x>SHL32(EXTEND32(1), 16))\n      x = SUB32(SHL32(EXTEND32(1), 17),x);\n   if (x&0x00007fff)\n   {\n      if (x<SHL32(EXTEND32(1), 15))\n      {\n         return _spx_cos_pi_2(EXTRACT16(x));\n      } else {\n         return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x)));\n      }\n   } else {\n      if (x&0x0000ffff)\n         return 0;\n      else if (x&0x0001ffff)\n         return -32767;\n      else\n         return 32767;\n   }\n}\n\n/*\n K0 = 1\n K1 = log(2)\n K2 = 3-4*log(2)\n K3 = 3*log(2) - 2\n*/\n#define D0 16384\n#define D1 11356\n#define D2 3726\n#define D3 1301\n/* Input in Q11 format, output in Q16 */\nstatic inline spx_word32_t spx_exp2(spx_word16_t x)\n{\n   int integer;\n   spx_word16_t frac;\n   integer = SHR16(x,11);\n   if (integer>14)\n      return 0x7fffffff;\n   else if (integer < -15)\n      return 0;\n   frac = SHL16(x-SHL16(integer,11),3);\n   frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac))))));\n   return VSHR32(EXTEND32(frac), -integer-2);\n}\n\n/* Input in Q11 format, output in Q16 */\nstatic inline spx_word32_t spx_exp(spx_word16_t x)\n{\n   if (x>21290)\n      return 0x7fffffff;\n   else if (x<-21290)\n      return 0;\n   else\n      return spx_exp2(MULT16_16_P14(23637,x));\n}\n#define M1 32767\n#define M2 -21\n#define M3 -11943\n#define M4 4936\n\nstatic inline spx_word16_t spx_atan01(spx_word16_t x)\n{\n   return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));\n}\n\n#undef M1\n#undef M2\n#undef M3\n#undef M4\n\n/* Input in Q15, output in Q14 */\nstatic inline spx_word16_t spx_atan(spx_word32_t x)\n{\n   if (x <= 32767)\n   {\n      return SHR16(spx_atan01(x),1);\n   } else {\n      int e = spx_ilog2(x);\n      if (e>=29)\n         return 25736;\n      x = DIV32_16(SHL32(EXTEND32(32767),29-e), EXTRACT16(SHR32(x, e-14)));\n      return SUB16(25736, SHR16(spx_atan01(x),1));\n   }\n}\n#else\n\n#ifndef M_PI\n#define M_PI           3.14159265358979323846  /* pi */\n#endif\n\n#define C1 0.9999932946f\n#define C2 -0.4999124376f\n#define C3 0.0414877472f\n#define C4 -0.0012712095f\n\n\n#define SPX_PI_2 1.5707963268\nstatic inline spx_word16_t spx_cos(spx_word16_t x)\n{\n   if (x<SPX_PI_2)\n   {\n      x *= x;\n      return C1 + x*(C2+x*(C3+C4*x));\n   } else {\n      x = M_PI-x;\n      x *= x;\n      return NEG16(C1 + x*(C2+x*(C3+C4*x)));\n   }\n}\n\n#endif\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/mdf.c",
    "content": "/* Copyright (C) 2003-2006 Jean-Marc Valin\n\n   File: mdf.c\n   Echo canceller based on the MDF algorithm (see below)\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/*\n   The echo canceller is based on the MDF algorithm described in:\n\n   J. S. Soo, K. K. Pang Multidelay block frequency adaptive filter, \n   IEEE Trans. Acoust. Speech Signal Process., Vol. ASSP-38, No. 2, \n   February 1990.\n   \n   We use the Alternatively Updated MDF (AUMDF) variant. Robustness to \n   double-talk is achieved using a variable learning rate as described in:\n   \n   Valin, J.-M., On Adjusting the Learning Rate in Frequency Domain Echo \n   Cancellation With Double-Talk. IEEE Transactions on Audio,\n   Speech and Language Processing, Vol. 15, No. 3, pp. 1030-1034, 2007.\n   http://people.xiph.org/~jm/papers/valin_taslp2006.pdf\n   \n   There is no explicit double-talk detection, but a continuous variation\n   in the learning rate based on residual echo, double-talk and background\n   noise.\n   \n   About the fixed-point version:\n   All the signals are represented with 16-bit words. The filter weights \n   are represented with 32-bit words, but only the top 16 bits are used\n   in most cases. The lower 16 bits are completely unreliable (due to the\n   fact that the update is done only on the top bits), but help in the\n   adaptation -- probably by removing a \"threshold effect\" due to\n   quantization (rounding going to zero) when the gradient is small.\n   \n   Another kludge that seems to work good: when performing the weight\n   update, we only move half the way toward the \"goal\" this seems to\n   reduce the effect of quantization noise in the update phase. This\n   can be seen as applying a gradient descent on a \"soft constraint\"\n   instead of having a hard constraint.\n   \n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arch.h\"\n#include \"speex/speex_echo.h\"\n#include \"fftwrap.h\"\n#include \"pseudofloat.h\"\n#include \"math_approx.h\"\n#include \"os_support.h\"\n\n#ifndef M_PI\n#define M_PI 3.14159265358979323846\n#endif\n\n#ifdef FIXED_POINT\n#define WEIGHT_SHIFT 11\n#define NORMALIZE_SCALEDOWN 5\n#define NORMALIZE_SCALEUP 3\n#else\n#define WEIGHT_SHIFT 0\n#endif\n\n/* If enabled, the AEC will use a foreground filter and a background filter to be more robust to double-talk\n   and difficult signals in general. The cost is an extra FFT and a matrix-vector multiply */\n#define TWO_PATH\n\n#ifdef FIXED_POINT\nstatic const spx_float_t MIN_LEAK = {20972, -22};\n\n/* Constants for the two-path filter */\nstatic const spx_float_t VAR1_SMOOTH = {23593, -16};\nstatic const spx_float_t VAR2_SMOOTH = {23675, -15};\nstatic const spx_float_t VAR1_UPDATE = {16384, -15};\nstatic const spx_float_t VAR2_UPDATE = {16384, -16};\nstatic const spx_float_t VAR_BACKTRACK = {16384, -12};\n#define TOP16(x) ((x)>>16)\n\n#else\n\nstatic const spx_float_t MIN_LEAK = .005f;\n\n/* Constants for the two-path filter */\nstatic const spx_float_t VAR1_SMOOTH = .36f;\nstatic const spx_float_t VAR2_SMOOTH = .7225f;\nstatic const spx_float_t VAR1_UPDATE = .5f;\nstatic const spx_float_t VAR2_UPDATE = .25f;\nstatic const spx_float_t VAR_BACKTRACK = 4.f;\n#define TOP16(x) (x)\n#endif\n\n\n#define PLAYBACK_DELAY 2\n\nvoid speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len);\n\n\n/** Speex echo cancellation state. */\nstruct SpeexEchoState_ {\n   int frame_size;           /**< Number of samples processed each time */\n   int window_size;\n   int M;\n   int cancel_count;\n   int adapted;\n   int saturated;\n   int screwed_up;\n   spx_int32_t sampling_rate;\n   spx_word16_t spec_average;\n   spx_word16_t beta0;\n   spx_word16_t beta_max;\n   spx_word32_t sum_adapt;\n   spx_word16_t leak_estimate;\n   \n   spx_word16_t *e;      /* scratch */\n   spx_word16_t *x;      /* Far-end input buffer (2N) */\n   spx_word16_t *X;      /* Far-end buffer (M+1 frames) in frequency domain */\n   spx_word16_t *input;  /* scratch */\n   spx_word16_t *y;      /* scratch */\n   spx_word16_t *last_y;\n   spx_word16_t *Y;      /* scratch */\n   spx_word16_t *E;\n   spx_word32_t *PHI;    /* scratch */\n   spx_word32_t *W;      /* (Background) filter weights */\n#ifdef TWO_PATH\n   spx_word16_t *foreground; /* Foreground filter weights */\n   spx_word32_t  Davg1;  /* 1st recursive average of the residual power difference */\n   spx_word32_t  Davg2;  /* 2nd recursive average of the residual power difference */\n   spx_float_t   Dvar1;  /* Estimated variance of 1st estimator */\n   spx_float_t   Dvar2;  /* Estimated variance of 2nd estimator */\n#endif\n   spx_word32_t *power;  /* Power of the far-end signal */\n   spx_float_t  *power_1;/* Inverse power of far-end */\n   spx_word16_t *wtmp;   /* scratch */\n#ifdef FIXED_POINT\n   spx_word16_t *wtmp2;  /* scratch */\n#endif\n   spx_word32_t *Rf;     /* scratch */\n   spx_word32_t *Yf;     /* scratch */\n   spx_word32_t *Xf;     /* scratch */\n   spx_word32_t *Eh;\n   spx_word32_t *Yh;\n   spx_float_t   Pey;\n   spx_float_t   Pyy;\n   spx_word16_t *window;\n   spx_word16_t *prop;\n   void *fft_table;\n   spx_word16_t memX, memD, memE;\n   spx_word16_t preemph;\n   spx_word16_t notch_radius;\n   spx_mem_t notch_mem[2];\n\n   /* NOTE: If you only use speex_echo_cancel() and want to save some memory, remove this */\n   spx_int16_t *play_buf;\n   int play_buf_pos;\n   int play_buf_started;\n};\n\nstatic inline void filter_dc_notch16(const spx_int16_t *in, spx_word16_t radius, spx_word16_t *out, int len, spx_mem_t *mem)\n{\n   int i;\n   spx_word16_t den2;\n#ifdef FIXED_POINT\n   den2 = MULT16_16_Q15(radius,radius) + MULT16_16_Q15(QCONST16(.7,15),MULT16_16_Q15(32767-radius,32767-radius));\n#else\n   den2 = radius*radius + .7*(1-radius)*(1-radius);\n#endif   \n   /*printf (\"%d %d %d %d %d %d\\n\", num[0], num[1], num[2], den[0], den[1], den[2]);*/\n   for (i=0;i<len;i++)\n   {\n      spx_word16_t vin = in[i];\n      spx_word32_t vout = mem[0] + SHL32(EXTEND32(vin),15);\n#ifdef FIXED_POINT\n      mem[0] = mem[1] + SHL32(SHL32(-EXTEND32(vin),15) + MULT16_32_Q15(radius,vout),1);\n#else\n      mem[0] = mem[1] + 2*(-vin + radius*vout);\n#endif\n      mem[1] = SHL32(EXTEND32(vin),15) - MULT16_32_Q15(den2,vout);\n      out[i] = SATURATE32(PSHR32(MULT16_32_Q15(radius,vout),15),32767);\n   }\n}\n\n/* This inner product is slightly different from the codec version because of fixed-point */\nstatic inline spx_word32_t mdf_inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)\n{\n   spx_word32_t sum=0;\n   len >>= 1;\n   while(len--)\n   {\n      spx_word32_t part=0;\n      part = MAC16_16(part,*x++,*y++);\n      part = MAC16_16(part,*x++,*y++);\n      /* HINT: If you had a 40-bit accumulator, you could shift only at the end */\n      sum = ADD32(sum,SHR32(part,6));\n   }\n   return sum;\n}\n\n/** Compute power spectrum of a half-complex (packed) vector */\nstatic inline void power_spectrum(const spx_word16_t *X, spx_word32_t *ps, int N)\n{\n   int i, j;\n   ps[0]=MULT16_16(X[0],X[0]);\n   for (i=1,j=1;i<N-1;i+=2,j++)\n   {\n      ps[j] =  MULT16_16(X[i],X[i]) + MULT16_16(X[i+1],X[i+1]);\n   }\n   ps[j]=MULT16_16(X[i],X[i]);\n}\n\n/** Compute cross-power spectrum of a half-complex (packed) vectors and add to acc */\n#ifdef FIXED_POINT\nstatic inline void spectral_mul_accum(const spx_word16_t *X, const spx_word32_t *Y, spx_word16_t *acc, int N, int M)\n{\n   int i,j;\n   spx_word32_t tmp1=0,tmp2=0;\n   for (j=0;j<M;j++)\n   {\n      tmp1 = MAC16_16(tmp1, X[j*N],TOP16(Y[j*N]));\n   }\n   acc[0] = PSHR32(tmp1,WEIGHT_SHIFT);\n   for (i=1;i<N-1;i+=2)\n   {\n      tmp1 = tmp2 = 0;\n      for (j=0;j<M;j++)\n      {\n         tmp1 = SUB32(MAC16_16(tmp1, X[j*N+i],TOP16(Y[j*N+i])), MULT16_16(X[j*N+i+1],TOP16(Y[j*N+i+1])));\n         tmp2 = MAC16_16(MAC16_16(tmp2, X[j*N+i+1],TOP16(Y[j*N+i])), X[j*N+i], TOP16(Y[j*N+i+1]));\n      }\n      acc[i] = PSHR32(tmp1,WEIGHT_SHIFT);\n      acc[i+1] = PSHR32(tmp2,WEIGHT_SHIFT);\n   }\n   tmp1 = tmp2 = 0;\n   for (j=0;j<M;j++)\n   {\n      tmp1 = MAC16_16(tmp1, X[(j+1)*N-1],TOP16(Y[(j+1)*N-1]));\n   }\n   acc[N-1] = PSHR32(tmp1,WEIGHT_SHIFT);\n}\nstatic inline void spectral_mul_accum16(const spx_word16_t *X, const spx_word16_t *Y, spx_word16_t *acc, int N, int M)\n{\n   int i,j;\n   spx_word32_t tmp1=0,tmp2=0;\n   for (j=0;j<M;j++)\n   {\n      tmp1 = MAC16_16(tmp1, X[j*N],Y[j*N]);\n   }\n   acc[0] = PSHR32(tmp1,WEIGHT_SHIFT);\n   for (i=1;i<N-1;i+=2)\n   {\n      tmp1 = tmp2 = 0;\n      for (j=0;j<M;j++)\n      {\n         tmp1 = SUB32(MAC16_16(tmp1, X[j*N+i],Y[j*N+i]), MULT16_16(X[j*N+i+1],Y[j*N+i+1]));\n         tmp2 = MAC16_16(MAC16_16(tmp2, X[j*N+i+1],Y[j*N+i]), X[j*N+i], Y[j*N+i+1]);\n      }\n      acc[i] = PSHR32(tmp1,WEIGHT_SHIFT);\n      acc[i+1] = PSHR32(tmp2,WEIGHT_SHIFT);\n   }\n   tmp1 = tmp2 = 0;\n   for (j=0;j<M;j++)\n   {\n      tmp1 = MAC16_16(tmp1, X[(j+1)*N-1],Y[(j+1)*N-1]);\n   }\n   acc[N-1] = PSHR32(tmp1,WEIGHT_SHIFT);\n}\n\n#else\nstatic inline void spectral_mul_accum(const spx_word16_t *X, const spx_word32_t *Y, spx_word16_t *acc, int N, int M)\n{\n   int i,j;\n   for (i=0;i<N;i++)\n      acc[i] = 0;\n   for (j=0;j<M;j++)\n   {\n      acc[0] += X[0]*Y[0];\n      for (i=1;i<N-1;i+=2)\n      {\n         acc[i] += (X[i]*Y[i] - X[i+1]*Y[i+1]);\n         acc[i+1] += (X[i+1]*Y[i] + X[i]*Y[i+1]);\n      }\n      acc[i] += X[i]*Y[i];\n      X += N;\n      Y += N;\n   }\n}\n#define spectral_mul_accum16 spectral_mul_accum\n#endif\n\n/** Compute weighted cross-power spectrum of a half-complex (packed) vector with conjugate */\nstatic inline void weighted_spectral_mul_conj(const spx_float_t *w, const spx_float_t p, const spx_word16_t *X, const spx_word16_t *Y, spx_word32_t *prod, int N)\n{\n   int i, j;\n   spx_float_t W;\n   W = FLOAT_AMULT(p, w[0]);\n   prod[0] = FLOAT_MUL32(W,MULT16_16(X[0],Y[0]));\n   for (i=1,j=1;i<N-1;i+=2,j++)\n   {\n      W = FLOAT_AMULT(p, w[j]);\n      prod[i] = FLOAT_MUL32(W,MAC16_16(MULT16_16(X[i],Y[i]), X[i+1],Y[i+1]));\n      prod[i+1] = FLOAT_MUL32(W,MAC16_16(MULT16_16(-X[i+1],Y[i]), X[i],Y[i+1]));\n   }\n   W = FLOAT_AMULT(p, w[j]);\n   prod[i] = FLOAT_MUL32(W,MULT16_16(X[i],Y[i]));\n}\n\nstatic inline void mdf_adjust_prop(const spx_word32_t *W, int N, int M, spx_word16_t *prop)\n{\n   int i, j;\n   spx_word16_t max_sum = 1;\n   spx_word32_t prop_sum = 1;\n   for (i=0;i<M;i++)\n   {\n      spx_word32_t tmp = 1;\n      for (j=0;j<N;j++)\n         tmp += MULT16_16(EXTRACT16(SHR32(W[i*N+j],18)), EXTRACT16(SHR32(W[i*N+j],18)));\n#ifdef FIXED_POINT\n      /* Just a security in case an overflow were to occur */\n      tmp = MIN32(ABS32(tmp), 536870912);\n#endif\n      prop[i] = spx_sqrt(tmp);\n      if (prop[i] > max_sum)\n         max_sum = prop[i];\n   }\n   for (i=0;i<M;i++)\n   {\n      prop[i] += MULT16_16_Q15(QCONST16(.1f,15),max_sum);\n      prop_sum += EXTEND32(prop[i]);\n   }\n   for (i=0;i<M;i++)\n   {\n      prop[i] = DIV32(MULT16_16(QCONST16(.99f,15), prop[i]),prop_sum);\n      /*printf (\"%f \", prop[i]);*/\n   }\n   /*printf (\"\\n\");*/\n}\n\n#ifdef DUMP_ECHO_CANCEL_DATA\n#include <stdio.h>\nstatic FILE *rFile=NULL, *pFile=NULL, *oFile=NULL;\n\nstatic void dump_audio(const spx_int16_t *rec, const spx_int16_t *play, const spx_int16_t *out, int len)\n{\n   if (!(rFile && pFile && oFile))\n   {\n      speex_fatal(\"Dump files not open\");\n   }\n   fwrite(rec, sizeof(spx_int16_t), len, rFile);\n   fwrite(play, sizeof(spx_int16_t), len, pFile);\n   fwrite(out, sizeof(spx_int16_t), len, oFile);\n}\n#endif\n\n/** Creates a new echo canceller state */\nSpeexEchoState *speex_echo_state_init(int frame_size, int filter_length)\n{\n   int i,N,M;\n   SpeexEchoState *st = (SpeexEchoState *)speex_alloc(sizeof(SpeexEchoState));\n\n#ifdef DUMP_ECHO_CANCEL_DATA\n   if (rFile || pFile || oFile)\n      speex_fatal(\"Opening dump files twice\");\n   rFile = fopen(\"aec_rec.sw\", \"wb\");\n   pFile = fopen(\"aec_play.sw\", \"wb\");\n   oFile = fopen(\"aec_out.sw\", \"wb\");\n#endif\n   \n   st->frame_size = frame_size;\n   st->window_size = 2*frame_size;\n   N = st->window_size;\n   M = st->M = (filter_length+st->frame_size-1)/frame_size;\n   st->cancel_count=0;\n   st->sum_adapt = 0;\n   st->saturated = 0;\n   st->screwed_up = 0;\n   /* This is the default sampling rate */\n   st->sampling_rate = 8000;\n   st->spec_average = DIV32_16(SHL32(EXTEND32(st->frame_size), 15), st->sampling_rate);\n#ifdef FIXED_POINT\n   st->beta0 = DIV32_16(SHL32(EXTEND32(st->frame_size), 16), st->sampling_rate);\n   st->beta_max = DIV32_16(SHL32(EXTEND32(st->frame_size), 14), st->sampling_rate);\n#else\n   st->beta0 = (2.0f*st->frame_size)/st->sampling_rate;\n   st->beta_max = (.5f*st->frame_size)/st->sampling_rate;\n#endif\n   st->leak_estimate = 0;\n\n   st->fft_table = spx_fft_init(N);\n   \n   st->e = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));\n   st->x = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));\n   st->input = (spx_word16_t*)speex_alloc(st->frame_size*sizeof(spx_word16_t));\n   st->y = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));\n   st->last_y = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));\n   st->Yf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t));\n   st->Rf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t));\n   st->Xf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t));\n   st->Yh = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t));\n   st->Eh = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t));\n\n   st->X = (spx_word16_t*)speex_alloc((M+1)*N*sizeof(spx_word16_t));\n   st->Y = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));\n   st->E = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));\n   st->W = (spx_word32_t*)speex_alloc(M*N*sizeof(spx_word32_t));\n#ifdef TWO_PATH\n   st->foreground = (spx_word16_t*)speex_alloc(M*N*sizeof(spx_word16_t));\n#endif\n   st->PHI = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t));\n   st->power = (spx_word32_t*)speex_alloc((frame_size+1)*sizeof(spx_word32_t));\n   st->power_1 = (spx_float_t*)speex_alloc((frame_size+1)*sizeof(spx_float_t));\n   st->window = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));\n   st->prop = (spx_word16_t*)speex_alloc(M*sizeof(spx_word16_t));\n   st->wtmp = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));\n#ifdef FIXED_POINT\n   st->wtmp2 = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));\n   for (i=0;i<N>>1;i++)\n   {\n      st->window[i] = (16383-SHL16(spx_cos(DIV32_16(MULT16_16(25736,i<<1),N)),1));\n      st->window[N-i-1] = st->window[i];\n   }\n#else\n   for (i=0;i<N;i++)\n      st->window[i] = .5-.5*cos(2*M_PI*i/N);\n#endif\n   for (i=0;i<=st->frame_size;i++)\n      st->power_1[i] = FLOAT_ONE;\n   for (i=0;i<N*M;i++)\n      st->W[i] = 0;\n   {\n      spx_word32_t sum = 0;\n      /* Ratio of ~10 between adaptation rate of first and last block */\n      spx_word16_t decay = SHR32(spx_exp(NEG16(DIV32_16(QCONST16(2.4,11),M))),1);\n      st->prop[0] = QCONST16(.7, 15);\n      sum = EXTEND32(st->prop[0]);\n      for (i=1;i<M;i++)\n      {\n         st->prop[i] = MULT16_16_Q15(st->prop[i-1], decay);\n         sum = ADD32(sum, EXTEND32(st->prop[i]));\n      }\n      for (i=M-1;i>=0;i--)\n      {\n         st->prop[i] = DIV32(MULT16_16(QCONST16(.8,15), st->prop[i]),sum);\n      }\n   }\n   \n   st->memX=st->memD=st->memE=0;\n   st->preemph = QCONST16(.9,15);\n   if (st->sampling_rate<12000)\n      st->notch_radius = QCONST16(.9, 15);\n   else if (st->sampling_rate<24000)\n      st->notch_radius = QCONST16(.982, 15);\n   else\n      st->notch_radius = QCONST16(.992, 15);\n\n   st->notch_mem[0] = st->notch_mem[1] = 0;\n   st->adapted = 0;\n   st->Pey = st->Pyy = FLOAT_ONE;\n   \n#ifdef TWO_PATH\n   st->Davg1 = st->Davg2 = 0;\n   st->Dvar1 = st->Dvar2 = FLOAT_ZERO;\n#endif\n   \n   st->play_buf = (spx_int16_t*)speex_alloc((PLAYBACK_DELAY+1)*st->frame_size*sizeof(spx_int16_t));\n   st->play_buf_pos = PLAYBACK_DELAY*st->frame_size;\n   st->play_buf_started = 0;\n   \n   return st;\n}\n\n/** Resets echo canceller state */\nvoid speex_echo_state_reset(SpeexEchoState *st)\n{\n   int i, M, N;\n   st->cancel_count=0;\n   st->screwed_up = 0;\n   N = st->window_size;\n   M = st->M;\n   for (i=0;i<N*M;i++)\n      st->W[i] = 0;\n#ifdef TWO_PATH\n   for (i=0;i<N*M;i++)\n      st->foreground[i] = 0;\n#endif\n   for (i=0;i<N*(M+1);i++)\n      st->X[i] = 0;\n   for (i=0;i<=st->frame_size;i++)\n   {\n      st->power[i] = 0;\n      st->power_1[i] = FLOAT_ONE;\n      st->Eh[i] = 0;\n      st->Yh[i] = 0;\n   }\n   for (i=0;i<st->frame_size;i++)\n   {\n      st->last_y[i] = 0;\n   }\n   for (i=0;i<N;i++)\n   {\n      st->E[i] = 0;\n      st->x[i] = 0;\n   }\n   st->notch_mem[0] = st->notch_mem[1] = 0;\n   st->memX=st->memD=st->memE=0;\n\n   st->saturated = 0;\n   st->adapted = 0;\n   st->sum_adapt = 0;\n   st->Pey = st->Pyy = FLOAT_ONE;\n#ifdef TWO_PATH\n   st->Davg1 = st->Davg2 = 0;\n   st->Dvar1 = st->Dvar2 = FLOAT_ZERO;\n#endif\n   for (i=0;i<3*st->frame_size;i++)\n      st->play_buf[i] = 0;\n   st->play_buf_pos = PLAYBACK_DELAY*st->frame_size;\n   st->play_buf_started = 0;\n\n}\n\n/** Destroys an echo canceller state */\nvoid speex_echo_state_destroy(SpeexEchoState *st)\n{\n   spx_fft_destroy(st->fft_table);\n\n   speex_free(st->e);\n   speex_free(st->x);\n   speex_free(st->input);\n   speex_free(st->y);\n   speex_free(st->last_y);\n   speex_free(st->Yf);\n   speex_free(st->Rf);\n   speex_free(st->Xf);\n   speex_free(st->Yh);\n   speex_free(st->Eh);\n\n   speex_free(st->X);\n   speex_free(st->Y);\n   speex_free(st->E);\n   speex_free(st->W);\n#ifdef TWO_PATH\n   speex_free(st->foreground);\n#endif\n   speex_free(st->PHI);\n   speex_free(st->power);\n   speex_free(st->power_1);\n   speex_free(st->window);\n   speex_free(st->prop);\n   speex_free(st->wtmp);\n#ifdef FIXED_POINT\n   speex_free(st->wtmp2);\n#endif\n   speex_free(st->play_buf);\n   speex_free(st);\n   \n#ifdef DUMP_ECHO_CANCEL_DATA\n   fclose(rFile);\n   fclose(pFile);\n   fclose(oFile);\n   rFile = pFile = oFile = NULL;\n#endif\n}\n\nvoid speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out)\n{\n   int i;\n   /*speex_warning_int(\"capture with fill level \", st->play_buf_pos/st->frame_size);*/\n   st->play_buf_started = 1;\n   if (st->play_buf_pos>=st->frame_size)\n   {\n      speex_echo_cancellation(st, rec, st->play_buf, out);\n      st->play_buf_pos -= st->frame_size;\n      for (i=0;i<st->play_buf_pos;i++)\n         st->play_buf[i] = st->play_buf[i+st->frame_size];\n   } else {\n      speex_warning(\"No playback frame available (your application is buggy and/or got xruns)\");\n      if (st->play_buf_pos!=0)\n      {\n         speex_warning(\"internal playback buffer corruption?\");\n         st->play_buf_pos = 0;\n      }\n      for (i=0;i<st->frame_size;i++)\n         out[i] = rec[i];\n   }\n}\n\nvoid speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play)\n{\n   /*speex_warning_int(\"playback with fill level \", st->play_buf_pos/st->frame_size);*/\n   if (!st->play_buf_started)\n   {\n      speex_warning(\"discarded first playback frame\");\n      return;\n   }\n   if (st->play_buf_pos<=PLAYBACK_DELAY*st->frame_size)\n   {\n      int i;\n      for (i=0;i<st->frame_size;i++)\n         st->play_buf[st->play_buf_pos+i] = play[i];\n      st->play_buf_pos += st->frame_size;\n      if (st->play_buf_pos <= (PLAYBACK_DELAY-1)*st->frame_size)\n      {\n         speex_warning(\"Auto-filling the buffer (your application is buggy and/or got xruns)\");\n         for (i=0;i<st->frame_size;i++)\n            st->play_buf[st->play_buf_pos+i] = play[i];\n         st->play_buf_pos += st->frame_size;\n      }\n   } else {\n      speex_warning(\"Had to discard a playback frame (your application is buggy and/or got xruns)\");\n   }\n}\n\n/** Performs echo cancellation on a frame (deprecated, last arg now ignored) */\nvoid speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout)\n{\n   speex_echo_cancellation(st, in, far_end, out);\n}\n\n/** Performs echo cancellation on a frame */\nvoid speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out)\n{\n   int i,j;\n   int N,M;\n   spx_word32_t Syy,See,Sxx,Sdd, Sff;\n#ifdef TWO_PATH\n   spx_word32_t Dbf;\n   int update_foreground;\n#endif\n   spx_word32_t Sey;\n   spx_word16_t ss, ss_1;\n   spx_float_t Pey = FLOAT_ONE, Pyy=FLOAT_ONE;\n   spx_float_t alpha, alpha_1;\n   spx_word16_t RER;\n   spx_word32_t tmp32;\n   \n   N = st->window_size;\n   M = st->M;\n   st->cancel_count++;\n#ifdef FIXED_POINT\n   ss=DIV32_16(11469,M);\n   ss_1 = SUB16(32767,ss);\n#else\n   ss=.35/M;\n   ss_1 = 1-ss;\n#endif\n\n   /* Apply a notch filter to make sure DC doesn't end up causing problems */\n   filter_dc_notch16(in, st->notch_radius, st->input, st->frame_size, st->notch_mem);\n   /* Copy input data to buffer and apply pre-emphasis */\n   for (i=0;i<st->frame_size;i++)\n   {\n      spx_word32_t tmp32;\n      tmp32 = SUB32(EXTEND32(far_end[i]), EXTEND32(MULT16_16_P15(st->preemph, st->memX)));\n#ifdef FIXED_POINT\n      /* If saturation occurs here, we need to freeze adaptation for M+1 frames (not just one) */\n      if (tmp32 > 32767)\n      {\n         tmp32 = 32767;\n         st->saturated = M+1;\n      }\n      if (tmp32 < -32767)\n      {\n         tmp32 = -32767;\n         st->saturated = M+1;\n      }      \n#endif\n      st->x[i+st->frame_size] = EXTRACT16(tmp32);\n      st->memX = far_end[i];\n      \n      tmp32 = SUB32(EXTEND32(st->input[i]), EXTEND32(MULT16_16_P15(st->preemph, st->memD)));\n#ifdef FIXED_POINT\n      if (tmp32 > 32767)\n      {\n         tmp32 = 32767;\n         if (st->saturated == 0)\n            st->saturated = 1;\n      }      \n      if (tmp32 < -32767)\n      {\n         tmp32 = -32767;\n         if (st->saturated == 0)\n            st->saturated = 1;\n      }\n#endif\n      st->memD = st->input[i];\n      st->input[i] = tmp32;\n   }\n\n   /* Shift memory: this could be optimized eventually*/\n   for (j=M-1;j>=0;j--)\n   {\n      for (i=0;i<N;i++)\n         st->X[(j+1)*N+i] = st->X[j*N+i];\n   }\n\n   /* Convert x (far end) to frequency domain */\n   spx_fft(st->fft_table, st->x, &st->X[0]);\n   for (i=0;i<N;i++)\n      st->last_y[i] = st->x[i];\n   Sxx = mdf_inner_prod(st->x+st->frame_size, st->x+st->frame_size, st->frame_size);\n   for (i=0;i<st->frame_size;i++)\n      st->x[i] = st->x[i+st->frame_size];\n   /* From here on, the top part of x is used as scratch space */\n   \n#ifdef TWO_PATH\n   /* Compute foreground filter */\n   spectral_mul_accum16(st->X, st->foreground, st->Y, N, M);   \n   spx_ifft(st->fft_table, st->Y, st->e);\n   for (i=0;i<st->frame_size;i++)\n      st->e[i] = SUB16(st->input[i], st->e[i+st->frame_size]);\n   Sff = mdf_inner_prod(st->e, st->e, st->frame_size);\n#endif\n   \n   /* Adjust proportional adaption rate */\n   mdf_adjust_prop (st->W, N, M, st->prop);\n   /* Compute weight gradient */\n   if (st->saturated == 0)\n   {\n      for (j=M-1;j>=0;j--)\n      {\n         weighted_spectral_mul_conj(st->power_1, FLOAT_SHL(PSEUDOFLOAT(st->prop[j]),-15), &st->X[(j+1)*N], st->E, st->PHI, N);\n         for (i=0;i<N;i++)\n            st->W[j*N+i] = ADD32(st->W[j*N+i], st->PHI[i]);\n         \n      }\n   } else {\n      st->saturated--;\n   }\n   \n   /* Update weight to prevent circular convolution (MDF / AUMDF) */\n   for (j=0;j<M;j++)\n   {\n      /* This is a variant of the Alternatively Updated MDF (AUMDF) */\n      /* Remove the \"if\" to make this an MDF filter */\n      if (j==0 || st->cancel_count%(M-1) == j-1)\n      {\n#ifdef FIXED_POINT\n         for (i=0;i<N;i++)\n            st->wtmp2[i] = EXTRACT16(PSHR32(st->W[j*N+i],NORMALIZE_SCALEDOWN+16));\n         spx_ifft(st->fft_table, st->wtmp2, st->wtmp);\n         for (i=0;i<st->frame_size;i++)\n         {\n            st->wtmp[i]=0;\n         }\n         for (i=st->frame_size;i<N;i++)\n         {\n            st->wtmp[i]=SHL16(st->wtmp[i],NORMALIZE_SCALEUP);\n         }\n         spx_fft(st->fft_table, st->wtmp, st->wtmp2);\n         /* The \"-1\" in the shift is a sort of kludge that trades less efficient update speed for decrease noise */\n         for (i=0;i<N;i++)\n            st->W[j*N+i] -= SHL32(EXTEND32(st->wtmp2[i]),16+NORMALIZE_SCALEDOWN-NORMALIZE_SCALEUP-1);\n#else\n         spx_ifft(st->fft_table, &st->W[j*N], st->wtmp);\n         for (i=st->frame_size;i<N;i++)\n         {\n            st->wtmp[i]=0;\n         }\n         spx_fft(st->fft_table, st->wtmp, &st->W[j*N]);\n#endif\n      }\n   }\n\n   /* Compute filter response Y */\n   spectral_mul_accum(st->X, st->W, st->Y, N, M);\n   spx_ifft(st->fft_table, st->Y, st->y);\n\n#ifdef TWO_PATH\n   /* Difference in response, this is used to estimate the variance of our residual power estimate */\n   for (i=0;i<st->frame_size;i++)\n      st->e[i] = SUB16(st->e[i+st->frame_size], st->y[i+st->frame_size]);\n   Dbf = 10+mdf_inner_prod(st->e, st->e, st->frame_size);\n#endif\n\n   for (i=0;i<st->frame_size;i++)\n      st->e[i] = SUB16(st->input[i], st->y[i+st->frame_size]);\n   See = mdf_inner_prod(st->e, st->e, st->frame_size);\n#ifndef TWO_PATH\n   Sff = See;\n#endif\n\n#ifdef TWO_PATH\n   /* Logic for updating the foreground filter */\n   \n   /* For two time windows, compute the mean of the energy difference, as well as the variance */\n   st->Davg1 = ADD32(MULT16_32_Q15(QCONST16(.6f,15),st->Davg1), MULT16_32_Q15(QCONST16(.4f,15),SUB32(Sff,See)));\n   st->Davg2 = ADD32(MULT16_32_Q15(QCONST16(.85f,15),st->Davg2), MULT16_32_Q15(QCONST16(.15f,15),SUB32(Sff,See)));\n   st->Dvar1 = FLOAT_ADD(FLOAT_MULT(VAR1_SMOOTH, st->Dvar1), FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.4f,15),Sff), MULT16_32_Q15(QCONST16(.4f,15),Dbf)));\n   st->Dvar2 = FLOAT_ADD(FLOAT_MULT(VAR2_SMOOTH, st->Dvar2), FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.15f,15),Sff), MULT16_32_Q15(QCONST16(.15f,15),Dbf)));\n   \n   /* Equivalent float code:\n   st->Davg1 = .6*st->Davg1 + .4*(Sff-See);\n   st->Davg2 = .85*st->Davg2 + .15*(Sff-See);\n   st->Dvar1 = .36*st->Dvar1 + .16*Sff*Dbf;\n   st->Dvar2 = .7225*st->Dvar2 + .0225*Sff*Dbf;\n   */\n   \n   update_foreground = 0;\n   /* Check if we have a statistically significant reduction in the residual echo */\n   /* Note that this is *not* Gaussian, so we need to be careful about the longer tail */\n   if (FLOAT_GT(FLOAT_MUL32U(SUB32(Sff,See),ABS32(SUB32(Sff,See))), FLOAT_MUL32U(Sff,Dbf)))\n      update_foreground = 1;\n   else if (FLOAT_GT(FLOAT_MUL32U(st->Davg1, ABS32(st->Davg1)), FLOAT_MULT(VAR1_UPDATE,(st->Dvar1))))\n      update_foreground = 1;\n   else if (FLOAT_GT(FLOAT_MUL32U(st->Davg2, ABS32(st->Davg2)), FLOAT_MULT(VAR2_UPDATE,(st->Dvar2))))\n      update_foreground = 1;\n   \n   /* Do we update? */\n   if (update_foreground)\n   {\n      st->Davg1 = st->Davg2 = 0;\n      st->Dvar1 = st->Dvar2 = FLOAT_ZERO;\n      /* Copy background filter to foreground filter */\n      for (i=0;i<N*M;i++)\n         st->foreground[i] = EXTRACT16(PSHR32(st->W[i],16));\n      /* Apply a smooth transition so as to not introduce blocking artifacts */\n      for (i=0;i<st->frame_size;i++)\n         st->e[i+st->frame_size] = MULT16_16_Q15(st->window[i+st->frame_size],st->e[i+st->frame_size]) + MULT16_16_Q15(st->window[i],st->y[i+st->frame_size]);\n   } else {\n      int reset_background=0;\n      /* Otherwise, check if the background filter is significantly worse */\n      if (FLOAT_GT(FLOAT_MUL32U(NEG32(SUB32(Sff,See)),ABS32(SUB32(Sff,See))), FLOAT_MULT(VAR_BACKTRACK,FLOAT_MUL32U(Sff,Dbf))))\n         reset_background = 1;\n      if (FLOAT_GT(FLOAT_MUL32U(NEG32(st->Davg1), ABS32(st->Davg1)), FLOAT_MULT(VAR_BACKTRACK,st->Dvar1)))\n         reset_background = 1;\n      if (FLOAT_GT(FLOAT_MUL32U(NEG32(st->Davg2), ABS32(st->Davg2)), FLOAT_MULT(VAR_BACKTRACK,st->Dvar2)))\n         reset_background = 1;\n      if (reset_background)\n      {\n         /* Copy foreground filter to background filter */\n         for (i=0;i<N*M;i++)\n            st->W[i] = SHL32(EXTEND32(st->foreground[i]),16);\n         /* We also need to copy the output so as to get correct adaptation */\n         for (i=0;i<st->frame_size;i++)\n            st->y[i+st->frame_size] = st->e[i+st->frame_size];\n         for (i=0;i<st->frame_size;i++)\n            st->e[i] = SUB16(st->input[i], st->y[i+st->frame_size]);\n         See = Sff;\n         st->Davg1 = st->Davg2 = 0;\n         st->Dvar1 = st->Dvar2 = FLOAT_ZERO;\n      }\n   }\n#endif\n\n   /* Compute error signal (for the output with de-emphasis) */ \n   for (i=0;i<st->frame_size;i++)\n   {\n      spx_word32_t tmp_out;\n#ifdef TWO_PATH\n      tmp_out = SUB32(EXTEND32(st->input[i]), EXTEND32(st->e[i+st->frame_size]));\n#else\n      tmp_out = SUB32(EXTEND32(st->input[i]), EXTEND32(st->y[i+st->frame_size]));\n#endif\n      /* Saturation */\n      if (tmp_out>32767)\n         tmp_out = 32767;\n      else if (tmp_out<-32768)\n         tmp_out = -32768;\n      tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(st->preemph, st->memE)));\n      /* This is an arbitrary test for saturation in the microphone signal */\n      if (in[i] <= -32000 || in[i] >= 32000)\n      {\n         tmp_out = 0;\n         if (st->saturated == 0)\n            st->saturated = 1;\n      }\n      out[i] = (spx_int16_t)tmp_out;\n      st->memE = tmp_out;\n   }\n   \n#ifdef DUMP_ECHO_CANCEL_DATA\n   dump_audio(in, far_end, out, st->frame_size);\n#endif\n   \n   /* Compute error signal (filter update version) */ \n   for (i=0;i<st->frame_size;i++)\n   {\n      st->e[i+st->frame_size] = st->e[i];\n      st->e[i] = 0;\n   }\n\n   /* Compute a bunch of correlations */\n   Sey = mdf_inner_prod(st->e+st->frame_size, st->y+st->frame_size, st->frame_size);\n   Syy = mdf_inner_prod(st->y+st->frame_size, st->y+st->frame_size, st->frame_size);\n   Sdd = mdf_inner_prod(st->input, st->input, st->frame_size);\n   \n   /*printf (\"%f %f %f %f\\n\", Sff, See, Syy, Sdd, st->update_cond);*/\n   \n   /* Do some sanity check */\n   if (!(Syy>=0 && Sxx>=0 && See >= 0)\n#ifndef FIXED_POINT\n       || !(Sff < N*1e9 && Syy < N*1e9 && Sxx < N*1e9)\n#endif\n      )\n   {\n      /* Things have gone really bad */\n      st->screwed_up += 50;\n      for (i=0;i<st->frame_size;i++)\n         out[i] = 0;\n   } else if (SHR32(Sff, 2) > ADD32(Sdd, SHR32(MULT16_16(N, 10000),6)))\n   {\n      /* AEC seems to add lots of echo instead of removing it, let's see if it will improve */\n      st->screwed_up++;\n   } else {\n      /* Everything's fine */\n      st->screwed_up=0;\n   }\n   if (st->screwed_up>=50)\n   {\n      speex_warning(\"The echo canceller started acting funny and got slapped (reset). It swears it will behave now.\");\n      speex_echo_state_reset(st);\n      return;\n   }\n\n   /* Add a small noise floor to make sure not to have problems when dividing */\n   See = MAX32(See, SHR32(MULT16_16(N, 100),6));\n\n   /* Convert error to frequency domain */\n   spx_fft(st->fft_table, st->e, st->E);\n   for (i=0;i<st->frame_size;i++)\n      st->y[i] = 0;\n   spx_fft(st->fft_table, st->y, st->Y);\n\n   /* Compute power spectrum of far end (X), error (E) and filter response (Y) */\n   power_spectrum(st->E, st->Rf, N);\n   power_spectrum(st->Y, st->Yf, N);\n   power_spectrum(st->X, st->Xf, N);\n   \n   /* Smooth far end energy estimate over time */\n   for (j=0;j<=st->frame_size;j++)\n      st->power[j] = MULT16_32_Q15(ss_1,st->power[j]) + 1 + MULT16_32_Q15(ss,st->Xf[j]);\n   \n   /* Enable this to compute the power based only on the tail (would need to compute more \n      efficiently to make this really useful */\n   if (0)\n   {\n      float scale2 = .5f/M;\n      for (j=0;j<=st->frame_size;j++)\n         st->power[j] = 100;\n      for (i=0;i<M;i++)\n      {\n         power_spectrum(&st->X[i*N], st->Xf, N);\n         for (j=0;j<=st->frame_size;j++)\n            st->power[j] += scale2*st->Xf[j];\n      }\n   }\n\n   /* Compute filtered spectra and (cross-)correlations */\n   for (j=st->frame_size;j>=0;j--)\n   {\n      spx_float_t Eh, Yh;\n      Eh = PSEUDOFLOAT(st->Rf[j] - st->Eh[j]);\n      Yh = PSEUDOFLOAT(st->Yf[j] - st->Yh[j]);\n      Pey = FLOAT_ADD(Pey,FLOAT_MULT(Eh,Yh));\n      Pyy = FLOAT_ADD(Pyy,FLOAT_MULT(Yh,Yh));\n#ifdef FIXED_POINT\n      st->Eh[j] = MAC16_32_Q15(MULT16_32_Q15(SUB16(32767,st->spec_average),st->Eh[j]), st->spec_average, st->Rf[j]);\n      st->Yh[j] = MAC16_32_Q15(MULT16_32_Q15(SUB16(32767,st->spec_average),st->Yh[j]), st->spec_average, st->Yf[j]);\n#else\n      st->Eh[j] = (1-st->spec_average)*st->Eh[j] + st->spec_average*st->Rf[j];\n      st->Yh[j] = (1-st->spec_average)*st->Yh[j] + st->spec_average*st->Yf[j];\n#endif\n   }\n   \n   Pyy = FLOAT_SQRT(Pyy);\n   Pey = FLOAT_DIVU(Pey,Pyy);\n\n   /* Compute correlation updatete rate */\n   tmp32 = MULT16_32_Q15(st->beta0,Syy);\n   if (tmp32 > MULT16_32_Q15(st->beta_max,See))\n      tmp32 = MULT16_32_Q15(st->beta_max,See);\n   alpha = FLOAT_DIV32(tmp32, See);\n   alpha_1 = FLOAT_SUB(FLOAT_ONE, alpha);\n   /* Update correlations (recursive average) */\n   st->Pey = FLOAT_ADD(FLOAT_MULT(alpha_1,st->Pey) , FLOAT_MULT(alpha,Pey));\n   st->Pyy = FLOAT_ADD(FLOAT_MULT(alpha_1,st->Pyy) , FLOAT_MULT(alpha,Pyy));\n   if (FLOAT_LT(st->Pyy, FLOAT_ONE))\n      st->Pyy = FLOAT_ONE;\n   /* We don't really hope to get better than 33 dB (MIN_LEAK-3dB) attenuation anyway */\n   if (FLOAT_LT(st->Pey, FLOAT_MULT(MIN_LEAK,st->Pyy)))\n      st->Pey = FLOAT_MULT(MIN_LEAK,st->Pyy);\n   if (FLOAT_GT(st->Pey, st->Pyy))\n      st->Pey = st->Pyy;\n   /* leak_estimate is the linear regression result */\n   st->leak_estimate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIVU(st->Pey, st->Pyy),14));\n   /* This looks like a stupid bug, but it's right (because we convert from Q14 to Q15) */\n   if (st->leak_estimate > 16383)\n      st->leak_estimate = 32767;\n   else\n      st->leak_estimate = SHL16(st->leak_estimate,1);\n   /*printf (\"%f\\n\", st->leak_estimate);*/\n   \n   /* Compute Residual to Error Ratio */\n#ifdef FIXED_POINT\n   tmp32 = MULT16_32_Q15(st->leak_estimate,Syy);\n   tmp32 = ADD32(SHR32(Sxx,13), ADD32(tmp32, SHL32(tmp32,1)));\n   /* Check for y in e (lower bound on RER) */\n   {\n      spx_float_t bound = PSEUDOFLOAT(Sey);\n      bound = FLOAT_DIVU(FLOAT_MULT(bound, bound), PSEUDOFLOAT(ADD32(1,Syy)));\n      if (FLOAT_GT(bound, PSEUDOFLOAT(See)))\n         tmp32 = See;\n      else if (tmp32 < FLOAT_EXTRACT32(bound))\n         tmp32 = FLOAT_EXTRACT32(bound);\n   }\n   if (tmp32 > SHR32(See,1))\n      tmp32 = SHR32(See,1);\n   RER = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32,See),15));\n#else\n   RER = (.0001*Sxx + 3.*MULT16_32_Q15(st->leak_estimate,Syy)) / See;\n   /* Check for y in e (lower bound on RER) */\n   if (RER < Sey*Sey/(1+See*Syy))\n      RER = Sey*Sey/(1+See*Syy);\n   if (RER > .5)\n      RER = .5;\n#endif\n\n   /* We consider that the filter has had minimal adaptation if the following is true*/\n   if (!st->adapted && st->sum_adapt > SHL32(EXTEND32(M),15) && MULT16_32_Q15(st->leak_estimate,Syy) > MULT16_32_Q15(QCONST16(.03f,15),Syy))\n   {\n      st->adapted = 1;\n   }\n\n   if (st->adapted)\n   {\n      /* Normal learning rate calculation once we're past the minimal adaptation phase */\n      for (i=0;i<=st->frame_size;i++)\n      {\n         spx_word32_t r, e;\n         /* Compute frequency-domain adaptation mask */\n         r = MULT16_32_Q15(st->leak_estimate,SHL32(st->Yf[i],3));\n         e = SHL32(st->Rf[i],3)+1;\n#ifdef FIXED_POINT\n         if (r>SHR32(e,1))\n            r = SHR32(e,1);\n#else\n         if (r>.5*e)\n            r = .5*e;\n#endif\n         r = MULT16_32_Q15(QCONST16(.7,15),r) + MULT16_32_Q15(QCONST16(.3,15),(spx_word32_t)(MULT16_32_Q15(RER,e)));\n         /*st->power_1[i] = adapt_rate*r/(e*(1+st->power[i]));*/\n         st->power_1[i] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r,FLOAT_MUL32U(e,st->power[i]+10)),WEIGHT_SHIFT+16);\n      }\n   } else {\n      /* Temporary adaption rate if filter is not yet adapted enough */\n      spx_word16_t adapt_rate=0;\n\n      if (Sxx > SHR32(MULT16_16(N, 1000),6)) \n      {\n         tmp32 = MULT16_32_Q15(QCONST16(.25f, 15), Sxx);\n#ifdef FIXED_POINT\n         if (tmp32 > SHR32(See,2))\n            tmp32 = SHR32(See,2);\n#else\n         if (tmp32 > .25*See)\n            tmp32 = .25*See;\n#endif\n         adapt_rate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32, See),15));\n      }\n      for (i=0;i<=st->frame_size;i++)\n         st->power_1[i] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(st->power[i],10)),WEIGHT_SHIFT+1);\n\n\n      /* How much have we adapted so far? */\n      st->sum_adapt = ADD32(st->sum_adapt,adapt_rate);\n   }\n\n   /* Save residual echo so it can be used by the nonlinear processor */\n   if (st->adapted)\n   {\n      /* If the filter is adapted, take the filtered echo */\n      for (i=0;i<st->frame_size;i++)\n         st->last_y[i] = st->last_y[st->frame_size+i];\n      for (i=0;i<st->frame_size;i++)\n         st->last_y[st->frame_size+i] = in[i]-out[i];\n   } else {\n      /* If filter isn't adapted yet, all we can do is take the far end signal directly */\n      /* moved earlier: for (i=0;i<N;i++)\n      st->last_y[i] = st->x[i];*/\n   }\n\n}\n\n/* Compute spectrum of estimated echo for use in an echo post-filter */\nvoid speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *residual_echo, int len)\n{\n   int i;\n   spx_word16_t leak2;\n   int N;\n   \n   N = st->window_size;\n\n   /* Apply hanning window (should pre-compute it)*/\n   for (i=0;i<N;i++)\n      st->y[i] = MULT16_16_Q15(st->window[i],st->last_y[i]);\n      \n   /* Compute power spectrum of the echo */\n   spx_fft(st->fft_table, st->y, st->Y);\n   power_spectrum(st->Y, residual_echo, N);\n      \n#ifdef FIXED_POINT\n   if (st->leak_estimate > 16383)\n      leak2 = 32767;\n   else\n      leak2 = SHL16(st->leak_estimate, 1);\n#else\n   if (st->leak_estimate>.5)\n      leak2 = 1;\n   else\n      leak2 = 2*st->leak_estimate;\n#endif\n   /* Estimate residual echo */\n   for (i=0;i<=st->frame_size;i++)\n      residual_echo[i] = (spx_int32_t)MULT16_32_Q15(leak2,residual_echo[i]);\n   \n}\n\nint speex_echo_ctl(SpeexEchoState *st, int request, void *ptr)\n{\n   switch(request)\n   {\n      \n      case SPEEX_ECHO_GET_FRAME_SIZE:\n         (*(int*)ptr) = st->frame_size;\n         break;\n      case SPEEX_ECHO_SET_SAMPLING_RATE:\n         st->sampling_rate = (*(int*)ptr);\n         st->spec_average = DIV32_16(SHL32(EXTEND32(st->frame_size), 15), st->sampling_rate);\n#ifdef FIXED_POINT\n         st->beta0 = DIV32_16(SHL32(EXTEND32(st->frame_size), 16), st->sampling_rate);\n         st->beta_max = DIV32_16(SHL32(EXTEND32(st->frame_size), 14), st->sampling_rate);\n#else\n         st->beta0 = (2.0f*st->frame_size)/st->sampling_rate;\n         st->beta_max = (.5f*st->frame_size)/st->sampling_rate;\n#endif\n         if (st->sampling_rate<12000)\n            st->notch_radius = QCONST16(.9, 15);\n         else if (st->sampling_rate<24000)\n            st->notch_radius = QCONST16(.982, 15);\n         else\n            st->notch_radius = QCONST16(.992, 15);\n         break;\n      case SPEEX_ECHO_GET_SAMPLING_RATE:\n         (*(int*)ptr) = st->sampling_rate;\n         break;\n      default:\n         speex_warning_int(\"Unknown speex_echo_ctl request: \", request);\n         return -1;\n   }\n   return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/misc_bfin.h",
    "content": "/* Copyright (C) 2005 Analog Devices */\n/**\n   @file misc_bfin.h\n   @author Jean-Marc Valin \n   @brief Various compatibility routines for Speex (Blackfin version)\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#define OVERRIDE_SPEEX_MOVE\nvoid *speex_move (void *dest, void *src, int n)\n{\n   __asm__ __volatile__\n         (\n         \"L0 = 0;\\n\\t\"\n         \"I0 = %0;\\n\\t\"\n         \"R0 = [I0++];\\n\\t\"\n         \"LOOP move%= LC0 = %2;\\n\\t\"\n         \"LOOP_BEGIN move%=;\\n\\t\"\n            \"[%1++] = R0 || R0 = [I0++];\\n\\t\"\n         \"LOOP_END move%=;\\n\\t\"\n         \"[%1++] = R0;\\n\\t\"\n   : \"=a\" (src), \"=a\" (dest)\n   : \"a\" ((n>>2)-1), \"0\" (src), \"1\" (dest)\n   : \"R0\", \"I0\", \"L0\", \"memory\"\n         );\n   return dest;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/modes.c",
    "content": "/* Copyright (C) 2002-2006 Jean-Marc Valin \n   File: modes.c\n\n   Describes the different modes of the codec\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"modes.h\"\n#include \"ltp.h\"\n#include \"quant_lsp.h\"\n#include \"cb_search.h\"\n#include \"sb_celp.h\"\n#include \"nb_celp.h\"\n#include \"vbr.h\"\n#include \"arch.h\"\n#include <math.h>\n\n#ifndef NULL\n#define NULL 0\n#endif\n\n\n/* Extern declarations for all codebooks we use here */\nextern const signed char gain_cdbk_nb[];\nextern const signed char gain_cdbk_lbr[];\nextern const signed char exc_5_256_table[];\nextern const signed char exc_5_64_table[];\nextern const signed char exc_8_128_table[];\nextern const signed char exc_10_32_table[];\nextern const signed char exc_10_16_table[];\nextern const signed char exc_20_32_table[];\n\n\n/* Parameters for Long-Term Prediction (LTP)*/\nstatic const ltp_params ltp_params_nb = {\n   gain_cdbk_nb,\n   7,\n   7\n};\n\n/* Parameters for Long-Term Prediction (LTP)*/\nstatic const ltp_params ltp_params_vlbr = {\n   gain_cdbk_lbr,\n   5,\n   0\n};\n\n/* Parameters for Long-Term Prediction (LTP)*/\nstatic const ltp_params ltp_params_lbr = {\n   gain_cdbk_lbr,\n   5,\n   7\n};\n\n/* Parameters for Long-Term Prediction (LTP)*/\nstatic const ltp_params ltp_params_med = {\n   gain_cdbk_lbr,\n   5,\n   7\n};\n\n/* Split-VQ innovation parameters for very low bit-rate narrowband */\nstatic const split_cb_params split_cb_nb_vlbr = {\n   10,               /*subvect_size*/\n   4,               /*nb_subvect*/\n   exc_10_16_table, /*shape_cb*/\n   4,               /*shape_bits*/\n   0,\n};\n\n/* Split-VQ innovation parameters for very low bit-rate narrowband */\nstatic const split_cb_params split_cb_nb_ulbr = {\n   20,               /*subvect_size*/\n   2,               /*nb_subvect*/\n   exc_20_32_table, /*shape_cb*/\n   5,               /*shape_bits*/\n   0,\n};\n\n/* Split-VQ innovation parameters for low bit-rate narrowband */\nstatic const split_cb_params split_cb_nb_lbr = {\n   10,              /*subvect_size*/\n   4,               /*nb_subvect*/\n   exc_10_32_table, /*shape_cb*/\n   5,               /*shape_bits*/\n   0,\n};\n\n\n/* Split-VQ innovation parameters narrowband */\nstatic const split_cb_params split_cb_nb = {\n   5,               /*subvect_size*/\n   8,               /*nb_subvect*/\n   exc_5_64_table, /*shape_cb*/\n   6,               /*shape_bits*/\n   0,\n};\n\n/* Split-VQ innovation parameters narrowband */\nstatic const split_cb_params split_cb_nb_med = {\n   8,               /*subvect_size*/\n   5,               /*nb_subvect*/\n   exc_8_128_table, /*shape_cb*/\n   7,               /*shape_bits*/\n   0,\n};\n\n/* Split-VQ innovation for low-band wideband */\nstatic const split_cb_params split_cb_sb = {\n   5,               /*subvect_size*/\n   8,              /*nb_subvect*/\n   exc_5_256_table,    /*shape_cb*/\n   8,               /*shape_bits*/\n   0,\n};\n\n\n\n/* 2150 bps \"vocoder-like\" mode for comfort noise */\nstatic const SpeexSubmode nb_submode1 = {\n   0,\n   1,\n   0,\n   0,\n   /* LSP quantization */\n   lsp_quant_lbr,\n   lsp_unquant_lbr,\n   /* No pitch quantization */\n   forced_pitch_quant,\n   forced_pitch_unquant,\n   NULL,\n   /* No innovation quantization (noise only) */\n   noise_codebook_quant,\n   noise_codebook_unquant,\n   NULL,\n   -1,\n   43\n};\n\n/* 3.95 kbps very low bit-rate mode */\nstatic const SpeexSubmode nb_submode8 = {\n   0,\n   1,\n   0,\n   0,\n   /*LSP quantization*/\n   lsp_quant_lbr,\n   lsp_unquant_lbr,\n   /*No pitch quantization*/\n   forced_pitch_quant,\n   forced_pitch_unquant,\n   NULL,\n   /*Innovation quantization*/\n   split_cb_search_shape_sign,\n   split_cb_shape_sign_unquant,\n   &split_cb_nb_ulbr,\n   QCONST16(.5,15),\n   79\n};\n\n/* 5.95 kbps very low bit-rate mode */\nstatic const SpeexSubmode nb_submode2 = {\n   0,\n   0,\n   0,\n   0,\n   /*LSP quantization*/\n   lsp_quant_lbr,\n   lsp_unquant_lbr,\n   /*No pitch quantization*/\n   pitch_search_3tap,\n   pitch_unquant_3tap,\n   &ltp_params_vlbr,\n   /*Innovation quantization*/\n   split_cb_search_shape_sign,\n   split_cb_shape_sign_unquant,\n   &split_cb_nb_vlbr,\n   QCONST16(.6,15),\n   119\n};\n\n/* 8 kbps low bit-rate mode */\nstatic const SpeexSubmode nb_submode3 = {\n   -1,\n   0,\n   1,\n   0,\n   /*LSP quantization*/\n   lsp_quant_lbr,\n   lsp_unquant_lbr,\n   /*Pitch quantization*/\n   pitch_search_3tap,\n   pitch_unquant_3tap,\n   &ltp_params_lbr,\n   /*Innovation quantization*/\n   split_cb_search_shape_sign,\n   split_cb_shape_sign_unquant,\n   &split_cb_nb_lbr,\n   QCONST16(.55,15),\n   160\n};\n\n/* 11 kbps medium bit-rate mode */\nstatic const SpeexSubmode nb_submode4 = {\n   -1,\n   0,\n   1,\n   0,\n   /*LSP quantization*/\n   lsp_quant_lbr,\n   lsp_unquant_lbr,\n   /*Pitch quantization*/\n   pitch_search_3tap,\n   pitch_unquant_3tap,\n   &ltp_params_med,\n   /*Innovation quantization*/\n   split_cb_search_shape_sign,\n   split_cb_shape_sign_unquant,\n   &split_cb_nb_med,\n   QCONST16(.45,15),\n   220\n};\n\n/* 15 kbps high bit-rate mode */\nstatic const SpeexSubmode nb_submode5 = {\n   -1,\n   0,\n   3,\n   0,\n   /*LSP quantization*/\n   lsp_quant_nb,\n   lsp_unquant_nb,\n   /*Pitch quantization*/\n   pitch_search_3tap,\n   pitch_unquant_3tap,\n   &ltp_params_nb,\n   /*Innovation quantization*/\n   split_cb_search_shape_sign,\n   split_cb_shape_sign_unquant,\n   &split_cb_nb,\n   QCONST16(.3,15),\n   300\n};\n\n/* 18.2 high bit-rate mode */\nstatic const SpeexSubmode nb_submode6 = {\n   -1,\n   0,\n   3,\n   0,\n   /*LSP quantization*/\n   lsp_quant_nb,\n   lsp_unquant_nb,\n   /*Pitch quantization*/\n   pitch_search_3tap,\n   pitch_unquant_3tap,\n   &ltp_params_nb,\n   /*Innovation quantization*/\n   split_cb_search_shape_sign,\n   split_cb_shape_sign_unquant,\n   &split_cb_sb,\n   QCONST16(.2,15),\n   364\n};\n\n/* 24.6 kbps high bit-rate mode */\nstatic const SpeexSubmode nb_submode7 = {\n   -1,\n   0,\n   3,\n   1,\n   /*LSP quantization*/\n   lsp_quant_nb,\n   lsp_unquant_nb,\n   /*Pitch quantization*/\n   pitch_search_3tap,\n   pitch_unquant_3tap,\n   &ltp_params_nb,\n   /*Innovation quantization*/\n   split_cb_search_shape_sign,\n   split_cb_shape_sign_unquant,\n   &split_cb_nb,\n   QCONST16(.1,15),\n   492\n};\n\n\n/* Default mode for narrowband */\nstatic const SpeexNBMode nb_mode = {\n   160,    /*frameSize*/\n   40,     /*subframeSize*/\n   10,     /*lpcSize*/\n   17,     /*pitchStart*/\n   144,    /*pitchEnd*/\n#ifdef FIXED_POINT\n   29491, 19661, /* gamma1, gamma2 */\n#else\n   0.9, 0.6, /* gamma1, gamma2 */\n#endif\n   QCONST16(.0002,15), /*lpc_floor*/\n   {NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, &nb_submode7,\n   &nb_submode8, NULL, NULL, NULL, NULL, NULL, NULL, NULL},\n   5,\n   {1, 8, 2, 3, 3, 4, 4, 5, 5, 6, 7}\n};\n\n\n/* Default mode for narrowband */\nEXPORT const SpeexMode speex_nb_mode = {\n   &nb_mode,\n   nb_mode_query,\n   \"narrowband\",\n   0,\n   4,\n   &nb_encoder_init,\n   &nb_encoder_destroy,\n   &nb_encode,\n   &nb_decoder_init,\n   &nb_decoder_destroy,\n   &nb_decode,\n   &nb_encoder_ctl,\n   &nb_decoder_ctl,\n};\n\n\n\nEXPORT int speex_mode_query(const SpeexMode *mode, int request, void *ptr)\n{\n   return mode->query(mode->mode, request, ptr);\n}\n\n#ifdef FIXED_DEBUG\nlong long spx_mips=0;\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/modes.h",
    "content": "/* Copyright (C) 2002-2006 Jean-Marc Valin */\n/**\n   @file modes.h\n   @brief Describes the different modes of the codec\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifndef MODES_H\n#define MODES_H\n\n#include <speex/speex.h>\n#include <speex/speex_bits.h>\n#include \"arch.h\"\n\n#define NB_SUBMODES 16\n#define NB_SUBMODE_BITS 4\n\n#define SB_SUBMODES 8\n#define SB_SUBMODE_BITS 3\n\n/* Used internally, NOT TO BE USED in applications */\n/** Used internally*/\n#define SPEEX_GET_PI_GAIN 100\n/** Used internally*/\n#define SPEEX_GET_EXC     101\n/** Used internally*/\n#define SPEEX_GET_INNOV   102\n/** Used internally*/\n#define SPEEX_GET_DTX_STATUS   103\n/** Used internally*/\n#define SPEEX_SET_INNOVATION_SAVE   104\n/** Used internally*/\n#define SPEEX_SET_WIDEBAND   105\n\n/** Used internally*/\n#define SPEEX_GET_STACK   106\n\n\n/** Quantizes LSPs */\ntypedef void (*lsp_quant_func)(spx_lsp_t *, spx_lsp_t *, int, SpeexBits *);\n\n/** Decodes quantized LSPs */\ntypedef void (*lsp_unquant_func)(spx_lsp_t *, int, SpeexBits *);\n\n\n/** Long-term predictor quantization */\ntypedef int (*ltp_quant_func)(spx_word16_t *, spx_word16_t *, spx_coef_t *, spx_coef_t *, \n                              spx_coef_t *, spx_sig_t *, const void *, int, int, spx_word16_t, \n                              int, int, SpeexBits*, char *, spx_word16_t *, spx_word16_t *, int, int, int, spx_word32_t *);\n\n/** Long-term un-quantize */\ntypedef void (*ltp_unquant_func)(spx_word16_t *, spx_word32_t *, int, int, spx_word16_t, const void *, int, int *,\n                                 spx_word16_t *, SpeexBits*, char*, int, int, spx_word16_t, int);\n\n\n/** Innovation quantization function */\ntypedef void (*innovation_quant_func)(spx_word16_t *, spx_coef_t *, spx_coef_t *, spx_coef_t *, const void *, int, int, \n                                      spx_sig_t *, spx_word16_t *, SpeexBits *, char *, int, int);\n\n/** Innovation unquantization function */\ntypedef void (*innovation_unquant_func)(spx_sig_t *, const void *, int, SpeexBits*, char *, spx_int32_t *);\n\n/** Description of a Speex sub-mode (wither narrowband or wideband */\ntypedef struct SpeexSubmode {\n   int     lbr_pitch;          /**< Set to -1 for \"normal\" modes, otherwise encode pitch using a global pitch and allowing a +- lbr_pitch variation (for low not-rates)*/\n   int     forced_pitch_gain;  /**< Use the same (forced) pitch gain for all sub-frames */\n   int     have_subframe_gain; /**< Number of bits to use as sub-frame innovation gain */\n   int     double_codebook;    /**< Apply innovation quantization twice for higher quality (and higher bit-rate)*/\n   /*LSP functions*/\n   lsp_quant_func    lsp_quant; /**< LSP quantization function */\n   lsp_unquant_func  lsp_unquant; /**< LSP unquantization function */\n\n   /*Long-term predictor functions*/\n   ltp_quant_func    ltp_quant; /**< Long-term predictor (pitch) quantizer */\n   ltp_unquant_func  ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */\n   const void       *ltp_params; /**< Pitch parameters (options) */\n\n   /*Quantization of innovation*/\n   innovation_quant_func innovation_quant; /**< Innovation quantization */\n   innovation_unquant_func innovation_unquant; /**< Innovation un-quantization */\n   const void             *innovation_params; /**< Innovation quantization parameters*/\n\n   spx_word16_t      comb_gain;  /**< Gain of enhancer comb filter */\n\n   int               bits_per_frame; /**< Number of bits per frame after encoding*/\n} SpeexSubmode;\n\n/** Struct defining the encoding/decoding mode*/\ntypedef struct SpeexNBMode {\n   int     frameSize;      /**< Size of frames used for encoding */\n   int     subframeSize;   /**< Size of sub-frames used for encoding */\n   int     lpcSize;        /**< Order of LPC filter */\n   int     pitchStart;     /**< Smallest pitch value allowed */\n   int     pitchEnd;       /**< Largest pitch value allowed */\n\n   spx_word16_t gamma1;    /**< Perceptual filter parameter #1 */\n   spx_word16_t gamma2;    /**< Perceptual filter parameter #2 */\n   spx_word16_t   lpc_floor;      /**< Noise floor for LPC analysis */\n\n   const SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */\n   int     defaultSubmode; /**< Default sub-mode to use when encoding */\n   int     quality_map[11]; /**< Mode corresponding to each quality setting */\n} SpeexNBMode;\n\n\n/** Struct defining the encoding/decoding mode for SB-CELP (wideband) */\ntypedef struct SpeexSBMode {\n   const SpeexMode *nb_mode;    /**< Embedded narrowband mode */\n   int     frameSize;     /**< Size of frames used for encoding */\n   int     subframeSize;  /**< Size of sub-frames used for encoding */\n   int     lpcSize;       /**< Order of LPC filter */\n   spx_word16_t gamma1;   /**< Perceptual filter parameter #1 */\n   spx_word16_t gamma2;   /**< Perceptual filter parameter #1 */\n   spx_word16_t   lpc_floor;     /**< Noise floor for LPC analysis */\n   spx_word16_t   folding_gain;\n\n   const SpeexSubmode *submodes[SB_SUBMODES]; /**< Sub-mode data for the mode */\n   int     defaultSubmode; /**< Default sub-mode to use when encoding */\n   int     low_quality_map[11]; /**< Mode corresponding to each quality setting */\n   int     quality_map[11]; /**< Mode corresponding to each quality setting */\n#ifndef DISABLE_VBR\n   const float (*vbr_thresh)[11];\n#endif\n   int     nb_modes;\n} SpeexSBMode;\n\nint speex_encode_native(void *state, spx_word16_t *in, SpeexBits *bits);\nint speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out);\n\nint nb_mode_query(const void *mode, int request, void *ptr);\nint wb_mode_query(const void *mode, int request, void *ptr);\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/modes_wb.c",
    "content": "/* Copyright (C) 2002-2007 Jean-Marc Valin \n   File: modes.c\n\n   Describes the wideband modes of the codec\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"modes.h\"\n#include \"ltp.h\"\n#include \"quant_lsp.h\"\n#include \"cb_search.h\"\n#include \"sb_celp.h\"\n#include \"nb_celp.h\"\n#include \"vbr.h\"\n#include \"arch.h\"\n#include <math.h>\n#include \"os_support.h\"\n\n\n#ifndef NULL\n#define NULL 0\n#endif\n\nEXPORT const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode};\n\nextern const signed char hexc_table[];\nextern const signed char hexc_10_32_table[];\n\n#ifndef DISABLE_WIDEBAND\n\n/* Split-VQ innovation for high-band wideband */\nstatic const split_cb_params split_cb_high = {\n   8,               /*subvect_size*/\n   5,               /*nb_subvect*/\n   hexc_table,       /*shape_cb*/\n   7,               /*shape_bits*/\n   1,\n};\n\n\n/* Split-VQ innovation for high-band wideband */\nstatic const split_cb_params split_cb_high_lbr = {\n   10,               /*subvect_size*/\n   4,               /*nb_subvect*/\n   hexc_10_32_table,       /*shape_cb*/\n   5,               /*shape_bits*/\n   0,\n};\n\n#endif\n\n\nstatic const SpeexSubmode wb_submode1 = {\n   0,\n   0,\n   1,\n   0,\n   /*LSP quantization*/\n   lsp_quant_high,\n   lsp_unquant_high,\n   /*Pitch quantization*/\n   NULL,\n   NULL,\n   NULL,\n   /*No innovation quantization*/\n   NULL,\n   NULL,\n   NULL,\n   -1,\n   36\n};\n\n\nstatic const SpeexSubmode wb_submode2 = {\n   0,\n   0,\n   1,\n   0,\n   /*LSP quantization*/\n   lsp_quant_high,\n   lsp_unquant_high,\n   /*Pitch quantization*/\n   NULL,\n   NULL,\n   NULL,\n   /*Innovation quantization*/\n   split_cb_search_shape_sign,\n   split_cb_shape_sign_unquant,\n#ifdef DISABLE_WIDEBAND\n   NULL,\n#else\n   &split_cb_high_lbr,\n#endif\n   -1,\n   112\n};\n\n\nstatic const SpeexSubmode wb_submode3 = {\n   0,\n   0,\n   1,\n   0,\n   /*LSP quantization*/\n   lsp_quant_high,\n   lsp_unquant_high,\n   /*Pitch quantization*/\n   NULL,\n   NULL,\n   NULL,\n   /*Innovation quantization*/\n   split_cb_search_shape_sign,\n   split_cb_shape_sign_unquant,\n#ifdef DISABLE_WIDEBAND\n   NULL,\n#else\n   &split_cb_high,\n#endif\n   -1,\n   192\n};\n\nstatic const SpeexSubmode wb_submode4 = {\n   0,\n   0,\n   1,\n   1,\n   /*LSP quantization*/\n   lsp_quant_high,\n   lsp_unquant_high,\n   /*Pitch quantization*/\n   NULL,\n   NULL,\n   NULL,\n   /*Innovation quantization*/\n   split_cb_search_shape_sign,\n   split_cb_shape_sign_unquant,\n#ifdef DISABLE_WIDEBAND\n   NULL,\n#else\n   &split_cb_high,\n#endif\n   -1,\n   352\n};\n\n\n/* Split-band wideband CELP mode*/\nstatic const SpeexSBMode sb_wb_mode = {\n   &speex_nb_mode,\n   160,    /*frameSize*/\n   40,     /*subframeSize*/\n   8,     /*lpcSize*/\n#ifdef FIXED_POINT\n   29491, 19661, /* gamma1, gamma2 */\n#else\n   0.9, 0.6, /* gamma1, gamma2 */\n#endif\n   QCONST16(.0002,15), /*lpc_floor*/\n   QCONST16(0.9f,15),\n   {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},\n   3,\n   {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7},\n   {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4},\n#ifndef DISABLE_VBR\n   vbr_hb_thresh,\n#endif\n   5\n};\n\n\nEXPORT const SpeexMode speex_wb_mode = {\n   &sb_wb_mode,\n   wb_mode_query,\n   \"wideband (sub-band CELP)\",\n   1,\n   4,\n   &sb_encoder_init,\n   &sb_encoder_destroy,\n   &sb_encode,\n   &sb_decoder_init,\n   &sb_decoder_destroy,\n   &sb_decode,\n   &sb_encoder_ctl,\n   &sb_decoder_ctl,\n};\n\n\n\n/* \"Ultra-wideband\" mode stuff */\n\n\n\n/* Split-band \"ultra-wideband\" (32 kbps) CELP mode*/\nstatic const SpeexSBMode sb_uwb_mode = {\n   &speex_wb_mode,\n   320,    /*frameSize*/\n   80,     /*subframeSize*/\n   8,     /*lpcSize*/\n#ifdef FIXED_POINT\n   29491, 19661, /* gamma1, gamma2 */\n#else\n   0.9, 0.6, /* gamma1, gamma2 */\n#endif\n   QCONST16(.0002,15), /*lpc_floor*/\n   QCONST16(0.7f,15),\n   {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL},\n   1,\n   {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},\n   {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},\n#ifndef DISABLE_VBR\n   vbr_uhb_thresh,\n#endif\n   2\n};\n\nint wb_mode_query(const void *mode, int request, void *ptr)\n{\n   const SpeexSBMode *m = (const SpeexSBMode*)mode;\n\n   switch (request)\n   {\n      case SPEEX_MODE_FRAME_SIZE:\n         *((int*)ptr)=2*m->frameSize;\n         break;\n      case SPEEX_SUBMODE_BITS_PER_FRAME:\n         if (*((int*)ptr)==0)\n            *((int*)ptr) = SB_SUBMODE_BITS+1;\n         else if (m->submodes[*((int*)ptr)]==NULL)\n            *((int*)ptr) = -1;\n         else\n            *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;\n         break;\n      default:\n         speex_warning_int(\"Unknown wb_mode_query request: \", request);\n         return -1;\n   }\n   return 0;\n}\n\n\nEXPORT const SpeexMode speex_uwb_mode = {\n   &sb_uwb_mode,\n   wb_mode_query,\n   \"ultra-wideband (sub-band CELP)\",\n   2,\n   4,\n   &sb_encoder_init,\n   &sb_encoder_destroy,\n   &sb_encode,\n   &sb_decoder_init,\n   &sb_decoder_destroy,\n   &sb_decode,\n   &sb_encoder_ctl,\n   &sb_decoder_ctl,\n};\n\n/* We have defined speex_lib_get_mode() as a macro in speex.h */\n#undef speex_lib_get_mode\n\nEXPORT const SpeexMode * speex_lib_get_mode (int mode)\n{\n   if (mode < 0 || mode >= SPEEX_NB_MODES) return NULL;\n\n   return speex_mode_list[mode];\n}\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/nb_celp.c",
    "content": "/* Copyright (C) 2002-2006 Jean-Marc Valin \n   File: nb_celp.c\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <math.h>\n#include \"nb_celp.h\"\n#include \"lpc.h\"\n#include \"lsp.h\"\n#include \"ltp.h\"\n#include \"quant_lsp.h\"\n#include \"cb_search.h\"\n#include \"filters.h\"\n#include \"stack_alloc.h\"\n#include \"vq.h\"\n#include <speex/speex_bits.h>\n#include \"vbr.h\"\n#include \"arch.h\"\n#include \"math_approx.h\"\n#include \"os_support.h\"\n#include <speex/speex_callbacks.h>\n\n#ifdef VORBIS_PSYCHO\n#include \"vorbis_psy.h\"\n#endif\n\n#ifndef M_PI\n#define M_PI           3.14159265358979323846  /* pi */\n#endif\n\n#ifndef NULL\n#define NULL 0\n#endif\n\n#define SUBMODE(x) st->submodes[st->submodeID]->x\n\n/* Default size for the encoder and decoder stack (can be changed at compile time).\n   This does not apply when using variable-size arrays or alloca. */\n#ifndef NB_ENC_STACK\n#define NB_ENC_STACK (8000*sizeof(spx_sig_t))\n#endif\n\n#ifndef NB_DEC_STACK\n#define NB_DEC_STACK (4000*sizeof(spx_sig_t))\n#endif\n\n\n#ifdef FIXED_POINT\nconst spx_word32_t ol_gain_table[32]={18900, 25150, 33468, 44536, 59265, 78865, 104946, 139653, 185838, 247297, 329081, 437913, 582736, 775454, 1031906, 1373169, 1827293, 2431601, 3235761, 4305867, 5729870, 7624808, 10146425, 13501971, 17967238, 23909222, 31816294, 42338330, 56340132, 74972501, 99766822, 132760927};\nconst spx_word16_t exc_gain_quant_scal3_bound[7]={1841, 3883, 6051, 8062, 10444, 13580, 18560};\nconst spx_word16_t exc_gain_quant_scal3[8]={1002, 2680, 5086, 7016, 9108, 11781, 15380, 21740};\nconst spx_word16_t exc_gain_quant_scal1_bound[1]={14385};\nconst spx_word16_t exc_gain_quant_scal1[2]={11546, 17224};\n\n#define LSP_MARGIN 16\n#define LSP_DELTA1 6553\n#define LSP_DELTA2 1638\n\n#else\n\nconst float exc_gain_quant_scal3_bound[7]={0.112338f, 0.236980f, 0.369316f, 0.492054f, 0.637471f, 0.828874f, 1.132784f};\nconst float exc_gain_quant_scal3[8]={0.061130f, 0.163546f, 0.310413f, 0.428220f, 0.555887f, 0.719055f, 0.938694f, 1.326874f};\nconst float exc_gain_quant_scal1_bound[1]={0.87798f};\nconst float exc_gain_quant_scal1[2]={0.70469f, 1.05127f};\n\n#define LSP_MARGIN .002f\n#define LSP_DELTA1 .2f\n#define LSP_DELTA2 .05f\n\n#endif\n\n#ifdef VORBIS_PSYCHO\n#define EXTRA_BUFFER 100\n#else\n#define EXTRA_BUFFER 0\n#endif\n\n\n#define sqr(x) ((x)*(x))\n\nextern const spx_word16_t lag_window[];\nextern const spx_word16_t lpc_window[];\n\nvoid *nb_encoder_init(const SpeexMode *m)\n{\n   EncState *st;\n   const SpeexNBMode *mode;\n   int i;\n\n   mode=(const SpeexNBMode *)m->mode;\n   st = (EncState*)speex_alloc(sizeof(EncState));\n   if (!st)\n      return NULL;\n#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)\n   st->stack = NULL;\n#else\n   st->stack = (char*)speex_alloc_scratch(NB_ENC_STACK);\n#endif\n   \n   st->mode=m;\n\n   st->frameSize = mode->frameSize;\n   st->nbSubframes=mode->frameSize/mode->subframeSize;\n   st->subframeSize=mode->subframeSize;\n   st->windowSize = st->frameSize+st->subframeSize;\n   st->lpcSize = mode->lpcSize;\n   st->gamma1=mode->gamma1;\n   st->gamma2=mode->gamma2;\n   st->min_pitch=mode->pitchStart;\n   st->max_pitch=mode->pitchEnd;\n   st->lpc_floor = mode->lpc_floor;\n  \n   st->submodes=mode->submodes;\n   st->submodeID=st->submodeSelect=mode->defaultSubmode;\n   st->bounded_pitch = 1;\n\n   st->encode_submode = 1;\n\n#ifdef VORBIS_PSYCHO\n   st->psy = vorbis_psy_init(8000, 256);\n   st->curve = (float*)speex_alloc(128*sizeof(float));\n   st->old_curve = (float*)speex_alloc(128*sizeof(float));\n   st->psy_window = (float*)speex_alloc(256*sizeof(float));\n#endif\n\n   st->cumul_gain = 1024;\n\n   /* Allocating input buffer */\n   st->winBuf = (spx_word16_t*)speex_alloc((st->windowSize-st->frameSize)*sizeof(spx_word16_t));\n   /* Allocating excitation buffer */\n   st->excBuf = (spx_word16_t*)speex_alloc((mode->frameSize+mode->pitchEnd+2)*sizeof(spx_word16_t));\n   st->exc = st->excBuf + mode->pitchEnd + 2;\n   st->swBuf = (spx_word16_t*)speex_alloc((mode->frameSize+mode->pitchEnd+2)*sizeof(spx_word16_t));\n   st->sw = st->swBuf + mode->pitchEnd + 2;\n\n   st->window= lpc_window;\n   \n   /* Create the window for autocorrelation (lag-windowing) */\n   st->lagWindow = lag_window;\n\n   st->old_lsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));\n   st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));\n   st->first = 1;\n   for (i=0;i<st->lpcSize;i++)\n      st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);\n\n   st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));\n   st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));\n   st->mem_sw_whole = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));\n   st->mem_exc = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));\n   st->mem_exc2 = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));\n\n   st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));\n   st->innov_rms_save = NULL;\n   \n   st->pitch = (int*)speex_alloc((st->nbSubframes)*sizeof(int));\n\n#ifndef DISABLE_VBR\n   st->vbr = (VBRState*)speex_alloc(sizeof(VBRState));\n   vbr_init(st->vbr);\n   st->vbr_quality = 8;\n   st->vbr_enabled = 0;\n   st->vbr_max = 0;\n   st->vad_enabled = 0;\n   st->dtx_enabled = 0;\n   st->dtx_count=0;\n   st->abr_enabled = 0;\n   st->abr_drift = 0;\n   st->abr_drift2 = 0;\n#endif /* #ifndef DISABLE_VBR */\n\n   st->plc_tuning = 2;\n   st->complexity=2;\n   st->sampling_rate=8000;\n   st->isWideband = 0;\n   st->highpass_enabled = 1;\n   \n#ifdef ENABLE_VALGRIND\n   VALGRIND_MAKE_READABLE(st, NB_ENC_STACK);\n#endif\n   return st;\n}\n\nvoid nb_encoder_destroy(void *state)\n{\n   EncState *st=(EncState *)state;\n   /* Free all allocated memory */\n#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))\n   speex_free_scratch(st->stack);\n#endif\n\n   speex_free (st->winBuf);\n   speex_free (st->excBuf);\n   speex_free (st->old_qlsp);\n   speex_free (st->swBuf);\n\n   speex_free (st->old_lsp);\n   speex_free (st->mem_sp);\n   speex_free (st->mem_sw);\n   speex_free (st->mem_sw_whole);\n   speex_free (st->mem_exc);\n   speex_free (st->mem_exc2);\n   speex_free (st->pi_gain);\n   speex_free (st->pitch);\n\n#ifndef DISABLE_VBR\n   vbr_destroy(st->vbr);\n   speex_free (st->vbr);\n#endif /* #ifndef DISABLE_VBR */\n\n#ifdef VORBIS_PSYCHO\n   vorbis_psy_destroy(st->psy);\n   speex_free (st->curve);\n   speex_free (st->old_curve);\n   speex_free (st->psy_window);\n#endif\n\n   /*Free state memory... should be last*/\n   speex_free(st);\n}\n\nint nb_encode(void *state, void *vin, SpeexBits *bits)\n{\n   EncState *st;\n   int i, sub, roots;\n   int ol_pitch;\n   spx_word16_t ol_pitch_coef;\n   spx_word32_t ol_gain;\n   VARDECL(spx_word16_t *ringing);\n   VARDECL(spx_word16_t *target);\n   VARDECL(spx_sig_t *innov);\n   VARDECL(spx_word32_t *exc32);\n   VARDECL(spx_mem_t *mem);\n   VARDECL(spx_coef_t *bw_lpc1);\n   VARDECL(spx_coef_t *bw_lpc2);\n   VARDECL(spx_coef_t *lpc);\n   VARDECL(spx_lsp_t *lsp);\n   VARDECL(spx_lsp_t *qlsp);\n   VARDECL(spx_lsp_t *interp_lsp);\n   VARDECL(spx_lsp_t *interp_qlsp);\n   VARDECL(spx_coef_t *interp_lpc);\n   VARDECL(spx_coef_t *interp_qlpc);\n   char *stack;\n   VARDECL(spx_word16_t *syn_resp);\n   VARDECL(spx_word16_t *real_exc);\n   \n   spx_word32_t ener=0;\n   spx_word16_t fine_gain;\n   spx_word16_t *in = (spx_word16_t*)vin;\n\n   st=(EncState *)state;\n   stack=st->stack;\n\n   ALLOC(lpc, st->lpcSize, spx_coef_t);\n   ALLOC(bw_lpc1, st->lpcSize, spx_coef_t);\n   ALLOC(bw_lpc2, st->lpcSize, spx_coef_t);\n   ALLOC(lsp, st->lpcSize, spx_lsp_t);\n   ALLOC(qlsp, st->lpcSize, spx_lsp_t);\n   ALLOC(interp_lsp, st->lpcSize, spx_lsp_t);\n   ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);\n   ALLOC(interp_lpc, st->lpcSize, spx_coef_t);\n   ALLOC(interp_qlpc, st->lpcSize, spx_coef_t);\n\n   /* Move signals 1 frame towards the past */\n   SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, st->max_pitch+2);\n   SPEEX_MOVE(st->swBuf, st->swBuf+st->frameSize, st->max_pitch+2);\n\n   if (st->highpass_enabled)\n      highpass(in, in, st->frameSize, (st->isWideband?HIGHPASS_WIDEBAND:HIGHPASS_NARROWBAND)|HIGHPASS_INPUT, st->mem_hp);\n   \n   {\n      VARDECL(spx_word16_t *w_sig);\n      VARDECL(spx_word16_t *autocorr);\n      ALLOC(w_sig, st->windowSize, spx_word16_t);\n      ALLOC(autocorr, st->lpcSize+1, spx_word16_t);\n      /* Window for analysis */\n      for (i=0;i<st->windowSize-st->frameSize;i++)\n         w_sig[i] = EXTRACT16(SHR32(MULT16_16(st->winBuf[i],st->window[i]),SIG_SHIFT));\n      for (;i<st->windowSize;i++)\n         w_sig[i] = EXTRACT16(SHR32(MULT16_16(in[i-st->windowSize+st->frameSize],st->window[i]),SIG_SHIFT));\n      /* Compute auto-correlation */\n      _spx_autocorr(w_sig, autocorr, st->lpcSize+1, st->windowSize);\n      autocorr[0] = ADD16(autocorr[0],MULT16_16_Q15(autocorr[0],st->lpc_floor)); /* Noise floor in auto-correlation domain */\n\n      /* Lag windowing: equivalent to filtering in the power-spectrum domain */\n      for (i=0;i<st->lpcSize+1;i++)\n         autocorr[i] = MULT16_16_Q14(autocorr[i],st->lagWindow[i]);\n\n      /* Levinson-Durbin */\n      _spx_lpc(lpc, autocorr, st->lpcSize);\n      /* LPC to LSPs (x-domain) transform */\n      roots=lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA1, stack);\n      /* Check if we found all the roots */\n      if (roots!=st->lpcSize)\n      {\n         /*If we can't find all LSP's, do some damage control and use previous filter*/\n         for (i=0;i<st->lpcSize;i++)\n         {\n            lsp[i]=st->old_lsp[i];\n         }\n      }\n   }\n\n\n\n\n   /* Whole frame analysis (open-loop estimation of pitch and excitation gain) */\n   {\n      int diff = st->windowSize-st->frameSize;\n      if (st->first)\n         for (i=0;i<st->lpcSize;i++)\n            interp_lsp[i] = lsp[i];\n      else\n         lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, st->nbSubframes, st->nbSubframes<<1);\n\n      lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN);\n\n      /* Compute interpolated LPCs (unquantized) for whole frame*/\n      lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack);\n\n\n      /*Open-loop pitch*/\n      if (!st->submodes[st->submodeID] || (st->complexity>2 && SUBMODE(have_subframe_gain)<3) || SUBMODE(forced_pitch_gain) || SUBMODE(lbr_pitch) != -1 \n#ifndef DISABLE_VBR\n           || st->vbr_enabled || st->vad_enabled\n#endif\n                  )\n      {\n         int nol_pitch[6];\n         spx_word16_t nol_pitch_coef[6];\n         \n         bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize);\n         bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);\n\n         SPEEX_COPY(st->sw, st->winBuf, diff);\n         SPEEX_COPY(st->sw+diff, in, st->frameSize-diff);\n         filter_mem16(st->sw, bw_lpc1, bw_lpc2, st->sw, st->frameSize, st->lpcSize, st->mem_sw_whole, stack);\n\n         open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize, \n                               nol_pitch, nol_pitch_coef, 6, stack);\n         ol_pitch=nol_pitch[0];\n         ol_pitch_coef = nol_pitch_coef[0];\n         /*Try to remove pitch multiples*/\n         for (i=1;i<6;i++)\n         {\n#ifdef FIXED_POINT\n            if ((nol_pitch_coef[i]>MULT16_16_Q15(nol_pitch_coef[0],27853)) && \n#else\n            if ((nol_pitch_coef[i]>.85*nol_pitch_coef[0]) && \n#endif\n                (ABS(2*nol_pitch[i]-ol_pitch)<=2 || ABS(3*nol_pitch[i]-ol_pitch)<=3 || \n                 ABS(4*nol_pitch[i]-ol_pitch)<=4 || ABS(5*nol_pitch[i]-ol_pitch)<=5))\n            {\n               /*ol_pitch_coef=nol_pitch_coef[i];*/\n               ol_pitch = nol_pitch[i];\n            }\n         }\n         /*if (ol_pitch>50)\n           ol_pitch/=2;*/\n         /*ol_pitch_coef = sqrt(ol_pitch_coef);*/\n\n      } else {\n         ol_pitch=0;\n         ol_pitch_coef=0;\n      }\n      \n      /*Compute \"real\" excitation*/\n      SPEEX_COPY(st->exc, st->winBuf, diff);\n      SPEEX_COPY(st->exc+diff, in, st->frameSize-diff);\n      fir_mem16(st->exc, interp_lpc, st->exc, st->frameSize, st->lpcSize, st->mem_exc, stack);\n\n      /* Compute open-loop excitation gain */\n      {\n         spx_word16_t g = compute_rms16(st->exc, st->frameSize);\n         if (st->submodeID!=1 && ol_pitch>0)\n            ol_gain = MULT16_16(g, MULT16_16_Q14(QCONST16(1.1,14),\n                                spx_sqrt(QCONST32(1.,28)-MULT16_32_Q15(QCONST16(.8,15),SHL32(MULT16_16(ol_pitch_coef,ol_pitch_coef),16)))));\n         else\n            ol_gain = SHL32(EXTEND32(g),SIG_SHIFT);\n      }\n   }\n\n#ifdef VORBIS_PSYCHO\n   SPEEX_MOVE(st->psy_window, st->psy_window+st->frameSize, 256-st->frameSize);\n   SPEEX_COPY(&st->psy_window[256-st->frameSize], in, st->frameSize);\n   compute_curve(st->psy, st->psy_window, st->curve);\n   /*print_vec(st->curve, 128, \"curve\");*/\n   if (st->first)\n      SPEEX_COPY(st->old_curve, st->curve, 128);\n#endif\n\n   /*VBR stuff*/\n#ifndef DISABLE_VBR\n   if (st->vbr && (st->vbr_enabled||st->vad_enabled))\n   {\n      float lsp_dist=0;\n      for (i=0;i<st->lpcSize;i++)\n         lsp_dist += (st->old_lsp[i] - lsp[i])*(st->old_lsp[i] - lsp[i]);\n      lsp_dist /= LSP_SCALING*LSP_SCALING;\n      \n      if (st->abr_enabled)\n      {\n         float qual_change=0;\n         if (st->abr_drift2 * st->abr_drift > 0)\n         {\n            /* Only adapt if long-term and short-term drift are the same sign */\n            qual_change = -.00001*st->abr_drift/(1+st->abr_count);\n            if (qual_change>.05)\n               qual_change=.05;\n            if (qual_change<-.05)\n               qual_change=-.05;\n         }\n         st->vbr_quality += qual_change;\n         if (st->vbr_quality>10)\n            st->vbr_quality=10;\n         if (st->vbr_quality<0)\n            st->vbr_quality=0;\n      }\n\n      st->relative_quality = vbr_analysis(st->vbr, in, st->frameSize, ol_pitch, GAIN_SCALING_1*ol_pitch_coef);\n      /*if (delta_qual<0)*/\n      /*  delta_qual*=.1*(3+st->vbr_quality);*/\n      if (st->vbr_enabled) \n      {\n         spx_int32_t mode;\n         int choice=0;\n         float min_diff=100;\n         mode = 8;\n         while (mode)\n         {\n            int v1;\n            float thresh;\n            v1=(int)floor(st->vbr_quality);\n            if (v1==10)\n               thresh = vbr_nb_thresh[mode][v1];\n            else\n               thresh = (st->vbr_quality-v1)*vbr_nb_thresh[mode][v1+1] + (1+v1-st->vbr_quality)*vbr_nb_thresh[mode][v1];\n            if (st->relative_quality > thresh && \n                st->relative_quality-thresh<min_diff)\n            {\n               choice = mode;\n               min_diff = st->relative_quality-thresh;\n            }\n            mode--;\n         }\n         mode=choice;\n         if (mode==0)\n         {\n            if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)\n            {\n               mode=1;\n               st->dtx_count=1;\n            } else {\n               mode=0;\n               st->dtx_count++;\n            }\n         } else {\n            st->dtx_count=0;\n         }\n\n         speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);\n         if (st->vbr_max>0)\n         {\n            spx_int32_t rate;\n            speex_encoder_ctl(state, SPEEX_GET_BITRATE, &rate);\n            if (rate > st->vbr_max)\n            {\n               rate = st->vbr_max;\n               speex_encoder_ctl(state, SPEEX_SET_BITRATE, &rate);\n            }\n         }\n         \n         if (st->abr_enabled)\n         {\n            spx_int32_t bitrate;\n            speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate);\n            st->abr_drift+=(bitrate-st->abr_enabled);\n            st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled);\n            st->abr_count += 1.0;\n         }\n\n      } else {\n         /*VAD only case*/\n         int mode;\n         if (st->relative_quality<2)\n         {\n            if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)\n            {\n               st->dtx_count=1;\n               mode=1;\n            } else {\n               mode=0;\n               st->dtx_count++;\n            }\n         } else {\n            st->dtx_count = 0;\n            mode=st->submodeSelect;\n         }\n         /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/\n         st->submodeID=mode;\n      } \n   } else {\n      st->relative_quality = -1;\n   }\n#endif /* #ifndef DISABLE_VBR */\n\n   if (st->encode_submode)\n   {\n      /* First, transmit a zero for narrowband */\n      speex_bits_pack(bits, 0, 1);\n\n      /* Transmit the sub-mode we use for this frame */\n      speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS);\n\n   }\n\n   /* If null mode (no transmission), just set a couple things to zero*/\n   if (st->submodes[st->submodeID] == NULL)\n   {\n      for (i=0;i<st->frameSize;i++)\n         st->exc[i]=st->sw[i]=VERY_SMALL;\n\n      for (i=0;i<st->lpcSize;i++)\n         st->mem_sw[i]=0;\n      st->first=1;\n      st->bounded_pitch = 1;\n\n      SPEEX_COPY(st->winBuf, in+2*st->frameSize-st->windowSize, st->windowSize-st->frameSize);\n\n      /* Clear memory (no need to really compute it) */\n      for (i=0;i<st->lpcSize;i++)\n         st->mem_sp[i] = 0;\n      return 0;\n\n   }\n\n   /* LSP Quantization */\n   if (st->first)\n   {\n      for (i=0;i<st->lpcSize;i++)\n         st->old_lsp[i] = lsp[i];\n   }\n\n\n   /*Quantize LSPs*/\n#if 1 /*0 for unquantized*/\n   SUBMODE(lsp_quant)(lsp, qlsp, st->lpcSize, bits);\n#else\n   for (i=0;i<st->lpcSize;i++)\n     qlsp[i]=lsp[i];\n#endif\n\n   /*If we use low bit-rate pitch mode, transmit open-loop pitch*/\n   if (SUBMODE(lbr_pitch)!=-1)\n   {\n      speex_bits_pack(bits, ol_pitch-st->min_pitch, 7);\n   } \n\n   if (SUBMODE(forced_pitch_gain))\n   {\n      int quant;\n      /* This just damps the pitch a bit, because it tends to be too aggressive when forced */\n      ol_pitch_coef = MULT16_16_Q15(QCONST16(.9,15), ol_pitch_coef);\n#ifdef FIXED_POINT\n      quant = PSHR16(MULT16_16_16(15, ol_pitch_coef),GAIN_SHIFT);\n#else\n      quant = (int)floor(.5+15*ol_pitch_coef*GAIN_SCALING_1);\n#endif\n      if (quant>15)\n         quant=15;\n      if (quant<0)\n         quant=0;\n      speex_bits_pack(bits, quant, 4);\n      ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT));\n   }\n   \n   \n   /*Quantize and transmit open-loop excitation gain*/\n#ifdef FIXED_POINT\n   {\n      int qe = scal_quant32(ol_gain, ol_gain_table, 32);\n      /*ol_gain = exp(qe/3.5)*SIG_SCALING;*/\n      ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]);\n      speex_bits_pack(bits, qe, 5);\n   }\n#else\n   {\n      int qe = (int)(floor(.5+3.5*log(ol_gain*1.0/SIG_SCALING)));\n      if (qe<0)\n         qe=0;\n      if (qe>31)\n         qe=31;\n      ol_gain = exp(qe/3.5)*SIG_SCALING;\n      speex_bits_pack(bits, qe, 5);\n   }\n#endif\n\n\n\n   /* Special case for first frame */\n   if (st->first)\n   {\n      for (i=0;i<st->lpcSize;i++)\n         st->old_qlsp[i] = qlsp[i];\n   }\n\n   /* Target signal */\n   ALLOC(target, st->subframeSize, spx_word16_t);\n   ALLOC(innov, st->subframeSize, spx_sig_t);\n   ALLOC(exc32, st->subframeSize, spx_word32_t);\n   ALLOC(ringing, st->subframeSize, spx_word16_t);\n   ALLOC(syn_resp, st->subframeSize, spx_word16_t);\n   ALLOC(real_exc, st->subframeSize, spx_word16_t);\n   ALLOC(mem, st->lpcSize, spx_mem_t);\n\n   /* Loop on sub-frames */\n   for (sub=0;sub<st->nbSubframes;sub++)\n   {\n      int   offset;\n      spx_word16_t *sw;\n      spx_word16_t *exc;\n      int pitch;\n      int response_bound = st->subframeSize;\n\n      /* Offset relative to start of frame */\n      offset = st->subframeSize*sub;\n      /* Excitation */\n      exc=st->exc+offset;\n      /* Weighted signal */\n      sw=st->sw+offset;\n      \n      /* LSP interpolation (quantized and unquantized) */\n      lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, sub, st->nbSubframes);\n      lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);\n\n      /* Make sure the filters are stable */\n      lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN);\n      lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);\n\n      /* Compute interpolated LPCs (quantized and unquantized) */\n      lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack);\n\n      lsp_to_lpc(interp_qlsp, interp_qlpc, st->lpcSize, stack);\n\n      /* Compute analysis filter gain at w=pi (for use in SB-CELP) */\n      {\n         spx_word32_t pi_g=LPC_SCALING;\n         for (i=0;i<st->lpcSize;i+=2)\n         {\n            /*pi_g += -st->interp_qlpc[i] +  st->interp_qlpc[i+1];*/\n            pi_g = ADD32(pi_g, SUB32(EXTEND32(interp_qlpc[i+1]),EXTEND32(interp_qlpc[i])));\n         }\n         st->pi_gain[sub] = pi_g;\n      }\n\n#ifdef VORBIS_PSYCHO\n      {\n         float curr_curve[128];\n         float fact = ((float)sub+1.0f)/st->nbSubframes;\n         for (i=0;i<128;i++)\n            curr_curve[i] = (1.0f-fact)*st->old_curve[i] + fact*st->curve[i];\n         curve_to_lpc(st->psy, curr_curve, bw_lpc1, bw_lpc2, 10);\n      }\n#else\n      /* Compute bandwidth-expanded (unquantized) LPCs for perceptual weighting */\n      bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize);\n      if (st->gamma2>=0)\n         bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);\n      else\n      {\n         for (i=0;i<st->lpcSize;i++)\n            bw_lpc2[i]=0;\n      }\n      /*print_vec(st->bw_lpc1, 10, \"bw_lpc\");*/\n#endif\n\n      /*FIXME: This will break if we change the window size */\n      speex_assert(st->windowSize-st->frameSize == st->subframeSize);\n      if (sub==0)\n      {\n         for (i=0;i<st->subframeSize;i++)\n            real_exc[i] = sw[i] = st->winBuf[i];\n      } else {\n         for (i=0;i<st->subframeSize;i++)\n            real_exc[i] = sw[i] = in[i+((sub-1)*st->subframeSize)];\n      }\n      fir_mem16(real_exc, interp_qlpc, real_exc, st->subframeSize, st->lpcSize, st->mem_exc2, stack);\n      \n      if (st->complexity==0)\n         response_bound >>= 1;\n      compute_impulse_response(interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, response_bound, st->lpcSize, stack);\n      for (i=response_bound;i<st->subframeSize;i++)\n         syn_resp[i]=VERY_SMALL;\n      \n      /* Compute zero response of A(z/g1) / ( A(z/g2) * A(z) ) */\n      for (i=0;i<st->lpcSize;i++)\n         mem[i]=SHL32(st->mem_sp[i],1);\n      for (i=0;i<st->subframeSize;i++)\n         ringing[i] = VERY_SMALL;\n#ifdef SHORTCUTS2\n      iir_mem16(ringing, interp_qlpc, ringing, response_bound, st->lpcSize, mem, stack);\n      for (i=0;i<st->lpcSize;i++)\n         mem[i]=SHL32(st->mem_sw[i],1);\n      filter_mem16(ringing, st->bw_lpc1, st->bw_lpc2, ringing, response_bound, st->lpcSize, mem, stack);\n      SPEEX_MEMSET(&ringing[response_bound], 0, st->subframeSize-response_bound);\n#else\n      iir_mem16(ringing, interp_qlpc, ringing, st->subframeSize, st->lpcSize, mem, stack);\n      for (i=0;i<st->lpcSize;i++)\n         mem[i]=SHL32(st->mem_sw[i],1);\n      filter_mem16(ringing, bw_lpc1, bw_lpc2, ringing, st->subframeSize, st->lpcSize, mem, stack);\n#endif\n      \n      /* Compute weighted signal */\n      for (i=0;i<st->lpcSize;i++)\n         mem[i]=st->mem_sw[i];\n      filter_mem16(sw, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, mem, stack);\n      \n      if (st->complexity==0)\n         for (i=0;i<st->lpcSize;i++)\n            st->mem_sw[i]=mem[i];\n      \n      /* Compute target signal (saturation prevents overflows on clipped input speech) */\n      for (i=0;i<st->subframeSize;i++)\n         target[i]=EXTRACT16(SATURATE(SUB32(sw[i],PSHR32(ringing[i],1)),32767));\n\n      /* Reset excitation */\n      SPEEX_MEMSET(exc, 0, st->subframeSize);\n\n      /* If we have a long-term predictor (otherwise, something's wrong) */\n      speex_assert (SUBMODE(ltp_quant));\n      {\n         int pit_min, pit_max;\n         /* Long-term prediction */\n         if (SUBMODE(lbr_pitch) != -1)\n         {\n            /* Low bit-rate pitch handling */\n            int margin;\n            margin = SUBMODE(lbr_pitch);\n            if (margin)\n            {\n               if (ol_pitch < st->min_pitch+margin-1)\n                  ol_pitch=st->min_pitch+margin-1;\n               if (ol_pitch > st->max_pitch-margin)\n                  ol_pitch=st->max_pitch-margin;\n               pit_min = ol_pitch-margin+1;\n               pit_max = ol_pitch+margin;\n            } else {\n               pit_min=pit_max=ol_pitch;\n            }\n         } else {\n            pit_min = st->min_pitch;\n            pit_max = st->max_pitch;\n         }\n         \n         /* Force pitch to use only the current frame if needed */\n         if (st->bounded_pitch && pit_max>offset)\n            pit_max=offset;\n\n         /* Perform pitch search */\n         pitch = SUBMODE(ltp_quant)(target, sw, interp_qlpc, bw_lpc1, bw_lpc2,\n                                    exc32, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef,\n                                    st->lpcSize, st->subframeSize, bits, stack, \n                                    exc, syn_resp, st->complexity, 0, st->plc_tuning, &st->cumul_gain);\n\n         st->pitch[sub]=pitch;\n      }\n      /* Quantization of innovation */\n      SPEEX_MEMSET(innov, 0, st->subframeSize);\n      \n      /* FIXME: Make sure this is save from overflows (so far so good) */\n      for (i=0;i<st->subframeSize;i++)\n         real_exc[i] = EXTRACT16(SUB32(EXTEND32(real_exc[i]), PSHR32(exc32[i],SIG_SHIFT-1)));\n      \n      ener = SHL32(EXTEND32(compute_rms16(real_exc, st->subframeSize)),SIG_SHIFT);\n      \n      /*FIXME: Should use DIV32_16 and make sure result fits in 16 bits */\n#ifdef FIXED_POINT\n      {\n         spx_word32_t f = PDIV32(ener,PSHR32(ol_gain,SIG_SHIFT));\n         if (f<=32767)\n            fine_gain = f;\n         else\n            fine_gain = 32767;\n      }\n#else\n      fine_gain = PDIV32_16(ener,PSHR32(ol_gain,SIG_SHIFT));\n#endif\n      /* Calculate gain correction for the sub-frame (if any) */\n      if (SUBMODE(have_subframe_gain)) \n      {\n         int qe;\n         if (SUBMODE(have_subframe_gain)==3)\n         {\n            qe = scal_quant(fine_gain, exc_gain_quant_scal3_bound, 8);\n            speex_bits_pack(bits, qe, 3);\n            ener=MULT16_32_Q14(exc_gain_quant_scal3[qe],ol_gain);\n         } else {\n            qe = scal_quant(fine_gain, exc_gain_quant_scal1_bound, 2);\n            speex_bits_pack(bits, qe, 1);\n            ener=MULT16_32_Q14(exc_gain_quant_scal1[qe],ol_gain);               \n         }\n      } else {\n         ener=ol_gain;\n      }\n      \n      /*printf (\"%f %f\\n\", ener, ol_gain);*/\n      \n      /* Normalize innovation */\n      signal_div(target, target, ener, st->subframeSize);\n      \n      /* Quantize innovation */\n      speex_assert (SUBMODE(innovation_quant));\n      {\n         /* Codebook search */\n         SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2, \n                  SUBMODE(innovation_params), st->lpcSize, st->subframeSize, \n                  innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook));\n         \n         /* De-normalize innovation and update excitation */\n         signal_mul(innov, innov, ener, st->subframeSize);\n         \n         for (i=0;i<st->subframeSize;i++)\n            exc[i] = EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767));\n\n         /* In some (rare) modes, we do a second search (more bits) to reduce noise even more */\n         if (SUBMODE(double_codebook)) {\n            char *tmp_stack=stack;\n            VARDECL(spx_sig_t *innov2);\n            ALLOC(innov2, st->subframeSize, spx_sig_t);\n            SPEEX_MEMSET(innov2, 0, st->subframeSize);\n            for (i=0;i<st->subframeSize;i++)\n               target[i]=MULT16_16_P13(QCONST16(2.2f,13), target[i]);\n            SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2, \n                                      SUBMODE(innovation_params), st->lpcSize, st->subframeSize, \n                                      innov2, syn_resp, bits, stack, st->complexity, 0);\n            signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), st->subframeSize);\n            for (i=0;i<st->subframeSize;i++)\n               innov[i] = ADD32(innov[i],innov2[i]);\n            stack = tmp_stack;\n         }\n         for (i=0;i<st->subframeSize;i++)\n            exc[i] = EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767));\n         if (st->innov_rms_save)\n         {\n            st->innov_rms_save[sub] = compute_rms(innov, st->subframeSize);\n         }\n      }\n\n      /* Final signal synthesis from excitation */\n      iir_mem16(exc, interp_qlpc, sw, st->subframeSize, st->lpcSize, st->mem_sp, stack);\n\n      /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */\n      if (st->complexity!=0)\n         filter_mem16(sw, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw, stack);\n      \n   }\n\n   /* Store the LSPs for interpolation in the next frame */\n   if (st->submodeID>=1)\n   {\n      for (i=0;i<st->lpcSize;i++)\n         st->old_lsp[i] = lsp[i];\n      for (i=0;i<st->lpcSize;i++)\n         st->old_qlsp[i] = qlsp[i];\n   }\n\n#ifdef VORBIS_PSYCHO\n   if (st->submodeID>=1)\n      SPEEX_COPY(st->old_curve, st->curve, 128);\n#endif\n\n   if (st->submodeID==1)\n   {\n#ifndef DISABLE_VBR\n      if (st->dtx_count)\n         speex_bits_pack(bits, 15, 4);\n      else\n#endif\n         speex_bits_pack(bits, 0, 4);\n   }\n\n   /* The next frame will not be the first (Duh!) */\n   st->first = 0;\n   SPEEX_COPY(st->winBuf, in+2*st->frameSize-st->windowSize, st->windowSize-st->frameSize);\n\n   if (SUBMODE(innovation_quant) == noise_codebook_quant || st->submodeID==0)\n      st->bounded_pitch = 1;\n   else\n      st->bounded_pitch = 0;\n\n   return 1;\n}\n\nvoid *nb_decoder_init(const SpeexMode *m)\n{\n   DecState *st;\n   const SpeexNBMode *mode;\n   int i;\n\n   mode=(const SpeexNBMode*)m->mode;\n   st = (DecState *)speex_alloc(sizeof(DecState));\n   if (!st)\n      return NULL;\n#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)\n   st->stack = NULL;\n#else\n   st->stack = (char*)speex_alloc_scratch(NB_DEC_STACK);\n#endif\n\n   st->mode=m;\n\n\n   st->encode_submode = 1;\n\n   st->first=1;\n   /* Codec parameters, should eventually have several \"modes\"*/\n   st->frameSize = mode->frameSize;\n   st->nbSubframes=mode->frameSize/mode->subframeSize;\n   st->subframeSize=mode->subframeSize;\n   st->lpcSize = mode->lpcSize;\n   st->min_pitch=mode->pitchStart;\n   st->max_pitch=mode->pitchEnd;\n\n   st->submodes=mode->submodes;\n   st->submodeID=mode->defaultSubmode;\n\n   st->lpc_enh_enabled=1;\n\n   st->excBuf = (spx_word16_t*)speex_alloc((st->frameSize + 2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_word16_t));\n   st->exc = st->excBuf + 2*st->max_pitch + st->subframeSize + 6;\n   SPEEX_MEMSET(st->excBuf, 0, st->frameSize + st->max_pitch);\n\n   st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t));\n   st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t));\n   st->mem_sp = (spx_mem_t*)speex_alloc(st->lpcSize*sizeof(spx_mem_t));\n   st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));\n   st->last_pitch = 40;\n   st->count_lost=0;\n   st->pitch_gain_buf[0] = st->pitch_gain_buf[1] = st->pitch_gain_buf[2] = 0;\n   st->pitch_gain_buf_idx = 0;\n   st->seed = 1000;\n   \n   st->sampling_rate=8000;\n   st->last_ol_gain = 0;\n\n   st->user_callback.func = &speex_default_user_handler;\n   st->user_callback.data = NULL;\n   for (i=0;i<16;i++)\n      st->speex_callbacks[i].func = NULL;\n\n   st->voc_m1=st->voc_m2=st->voc_mean=0;\n   st->voc_offset=0;\n   st->dtx_enabled=0;\n   st->isWideband = 0;\n   st->highpass_enabled = 1;\n\n#ifdef ENABLE_VALGRIND\n   VALGRIND_MAKE_READABLE(st, NB_DEC_STACK);\n#endif\n   return st;\n}\n\nvoid nb_decoder_destroy(void *state)\n{\n   DecState *st;\n   st=(DecState*)state;\n   \n#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))\n   speex_free_scratch(st->stack);\n#endif\n\n   speex_free (st->excBuf);\n   speex_free (st->interp_qlpc);\n   speex_free (st->old_qlsp);\n   speex_free (st->mem_sp);\n   speex_free (st->pi_gain);\n\n   speex_free(state);\n}\n\n#define median3(a, b, c)\t((a) < (b) ? ((b) < (c) ? (b) : ((a) < (c) ? (c) : (a))) : ((c) < (b) ? (b) : ((c) < (a) ? (c) : (a))))\n\n#ifdef FIXED_POINT\nconst spx_word16_t attenuation[10] = {32767, 31483, 27923, 22861, 17278, 12055, 7764, 4616, 2533, 1283};\n#else\nconst spx_word16_t attenuation[10] = {1., 0.961, 0.852, 0.698, 0.527, 0.368, 0.237, 0.141, 0.077, 0.039};\n\n#endif\n\nstatic void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack)\n{\n   int i;\n   int pitch_val;\n   spx_word16_t pitch_gain;\n   spx_word16_t fact;\n   spx_word16_t gain_med;\n   spx_word16_t innov_gain;\n   spx_word16_t noise_gain;\n   \n   if (st->count_lost<10)\n      fact = attenuation[st->count_lost];\n   else\n      fact = 0;\n\n   gain_med = median3(st->pitch_gain_buf[0], st->pitch_gain_buf[1], st->pitch_gain_buf[2]);\n   if (gain_med < st->last_pitch_gain)\n      st->last_pitch_gain = gain_med;\n   \n#ifdef FIXED_POINT\n   pitch_gain = st->last_pitch_gain;\n   if (pitch_gain>54)\n      pitch_gain = 54;\n   pitch_gain = SHL16(pitch_gain, 9);\n#else   \n   pitch_gain = GAIN_SCALING_1*st->last_pitch_gain;\n   if (pitch_gain>.85)\n      pitch_gain=.85;\n#endif\n   pitch_gain = MULT16_16_Q15(fact,pitch_gain) + VERY_SMALL;\n   /* FIXME: This was rms of innovation (not exc) */\n   innov_gain = compute_rms16(st->exc, st->frameSize);\n   noise_gain = MULT16_16_Q15(innov_gain, MULT16_16_Q15(fact, SUB16(Q15ONE,MULT16_16_Q15(pitch_gain,pitch_gain))));\n   /* Shift all buffers by one frame */\n   SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, 2*st->max_pitch + st->subframeSize + 12);\n   \n\n   pitch_val = st->last_pitch + SHR32((spx_int32_t)speex_rand(1+st->count_lost, &st->seed),SIG_SHIFT);\n   if (pitch_val > st->max_pitch)\n      pitch_val = st->max_pitch;\n   if (pitch_val < st->min_pitch)\n      pitch_val = st->min_pitch;\n   for (i=0;i<st->frameSize;i++)\n   {\n      st->exc[i]= MULT16_16_Q15(pitch_gain, (st->exc[i-pitch_val]+VERY_SMALL)) + \n            speex_rand(noise_gain, &st->seed);\n   }\n\n   bw_lpc(QCONST16(.98,15), st->interp_qlpc, st->interp_qlpc, st->lpcSize);\n   iir_mem16(&st->exc[-st->subframeSize], st->interp_qlpc, out, st->frameSize,\n             st->lpcSize, st->mem_sp, stack);\n   highpass(out, out, st->frameSize, HIGHPASS_NARROWBAND|HIGHPASS_OUTPUT, st->mem_hp);\n   \n   st->first = 0;\n   st->count_lost++;\n   st->pitch_gain_buf[st->pitch_gain_buf_idx++] = PSHR16(pitch_gain,9);\n   if (st->pitch_gain_buf_idx > 2) /* rollover */\n      st->pitch_gain_buf_idx = 0;\n}\n\n/* Just so we don't need to carry the complete wideband mode information */\nstatic const int wb_skip_table[8] = {0, 36, 112, 192, 352, 0, 0, 0};\n   \nint nb_decode(void *state, SpeexBits *bits, void *vout)\n{\n   DecState *st;\n   int i, sub;\n   int pitch;\n   spx_word16_t pitch_gain[3];\n   spx_word32_t ol_gain=0;\n   int ol_pitch=0;\n   spx_word16_t ol_pitch_coef=0;\n   int best_pitch=40;\n   spx_word16_t best_pitch_gain=0;\n   int wideband;\n   int m;\n   char *stack;\n   VARDECL(spx_sig_t *innov);\n   VARDECL(spx_word32_t *exc32);\n   VARDECL(spx_coef_t *ak);\n   VARDECL(spx_lsp_t *qlsp);\n   spx_word16_t pitch_average=0;\n   \n   spx_word16_t *out = (spx_word16_t*)vout;\n   VARDECL(spx_lsp_t *interp_qlsp);\n\n   st=(DecState*)state;\n   stack=st->stack;\n\n   /* Check if we're in DTX mode*/\n   if (!bits && st->dtx_enabled)\n   {\n      st->submodeID=0;\n   } else \n   {\n      /* If bits is NULL, consider the packet to be lost (what could we do anyway) */\n      if (!bits)\n      {\n         nb_decode_lost(st, out, stack);\n         return 0;\n      }\n\n      if (st->encode_submode)\n      {\n\n      /* Search for next narrowband block (handle requests, skip wideband blocks) */\n      do {\n         if (speex_bits_remaining(bits)<5)\n            return -1;\n         wideband = speex_bits_unpack_unsigned(bits, 1);\n         if (wideband) /* Skip wideband block (for compatibility) */\n         {\n            int submode;\n            int advance;\n            advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);\n            /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/\n            advance = wb_skip_table[submode];\n            if (advance < 0)\n            {\n               speex_notify(\"Invalid mode encountered. The stream is corrupted.\");\n               return -2;\n            } \n            advance -= (SB_SUBMODE_BITS+1);\n            speex_bits_advance(bits, advance);\n            \n            if (speex_bits_remaining(bits)<5)\n               return -1;\n            wideband = speex_bits_unpack_unsigned(bits, 1);\n            if (wideband)\n            {\n               advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);\n               /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/\n               advance = wb_skip_table[submode];\n               if (advance < 0)\n               {\n                  speex_notify(\"Invalid mode encountered. The stream is corrupted.\");\n                  return -2;\n               } \n               advance -= (SB_SUBMODE_BITS+1);\n               speex_bits_advance(bits, advance);\n               wideband = speex_bits_unpack_unsigned(bits, 1);\n               if (wideband)\n               {\n                  speex_notify(\"More than two wideband layers found. The stream is corrupted.\");\n                  return -2;\n               }\n\n            }\n         }\n         if (speex_bits_remaining(bits)<4)\n            return -1;\n         /* FIXME: Check for overflow */\n         m = speex_bits_unpack_unsigned(bits, 4);\n         if (m==15) /* We found a terminator */\n         {\n            return -1;\n         } else if (m==14) /* Speex in-band request */\n         {\n            int ret = speex_inband_handler(bits, st->speex_callbacks, state);\n            if (ret)\n               return ret;\n         } else if (m==13) /* User in-band request */\n         {\n            int ret = st->user_callback.func(bits, state, st->user_callback.data);\n            if (ret)\n               return ret;\n         } else if (m>8) /* Invalid mode */\n         {\n            speex_notify(\"Invalid mode encountered. The stream is corrupted.\");\n            return -2;\n         }\n      \n      } while (m>8);\n\n      /* Get the sub-mode that was used */\n      st->submodeID = m;\n      }\n\n   }\n\n   /* Shift all buffers by one frame */\n   SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, 2*st->max_pitch + st->subframeSize + 12);\n\n   /* If null mode (no transmission), just set a couple things to zero*/\n   if (st->submodes[st->submodeID] == NULL)\n   {\n      VARDECL(spx_coef_t *lpc);\n      ALLOC(lpc, st->lpcSize, spx_coef_t);\n      bw_lpc(QCONST16(0.93f,15), st->interp_qlpc, lpc, st->lpcSize);\n      {\n         spx_word16_t innov_gain=0;\n         /* FIXME: This was innov, not exc */\n         innov_gain = compute_rms16(st->exc, st->frameSize);\n         for (i=0;i<st->frameSize;i++)\n            st->exc[i]=speex_rand(innov_gain, &st->seed);\n      }\n\n\n      st->first=1;\n\n      /* Final signal synthesis from excitation */\n      iir_mem16(st->exc, lpc, out, st->frameSize, st->lpcSize, st->mem_sp, stack);\n\n      st->count_lost=0;\n      return 0;\n   }\n\n   ALLOC(qlsp, st->lpcSize, spx_lsp_t);\n\n   /* Unquantize LSPs */\n   SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits);\n\n   /*Damp memory if a frame was lost and the LSP changed too much*/\n   if (st->count_lost)\n   {\n      spx_word16_t fact;\n      spx_word32_t lsp_dist=0;\n      for (i=0;i<st->lpcSize;i++)\n         lsp_dist = ADD32(lsp_dist, EXTEND32(ABS(st->old_qlsp[i] - qlsp[i])));\n#ifdef FIXED_POINT\n      fact = SHR16(19661,SHR32(lsp_dist,LSP_SHIFT+2));      \n#else\n      fact = .6*exp(-.2*lsp_dist);\n#endif\n      for (i=0;i<st->lpcSize;i++)\n         st->mem_sp[i] = MULT16_32_Q15(fact,st->mem_sp[i]);\n   }\n\n\n   /* Handle first frame and lost-packet case */\n   if (st->first || st->count_lost)\n   {\n      for (i=0;i<st->lpcSize;i++)\n         st->old_qlsp[i] = qlsp[i];\n   }\n\n   /* Get open-loop pitch estimation for low bit-rate pitch coding */\n   if (SUBMODE(lbr_pitch)!=-1)\n   {\n      ol_pitch = st->min_pitch+speex_bits_unpack_unsigned(bits, 7);\n   } \n   \n   if (SUBMODE(forced_pitch_gain))\n   {\n      int quant;\n      quant = speex_bits_unpack_unsigned(bits, 4);\n      ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT));\n   }\n   \n   /* Get global excitation gain */\n   {\n      int qe;\n      qe = speex_bits_unpack_unsigned(bits, 5);\n#ifdef FIXED_POINT\n      /* FIXME: Perhaps we could slightly lower the gain here when the output is going to saturate? */\n      ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]);\n#else\n      ol_gain = SIG_SCALING*exp(qe/3.5);\n#endif\n   }\n\n   ALLOC(ak, st->lpcSize, spx_coef_t);\n   ALLOC(innov, st->subframeSize, spx_sig_t);\n   ALLOC(exc32, st->subframeSize, spx_word32_t);\n\n   if (st->submodeID==1)\n   {\n      int extra;\n      extra = speex_bits_unpack_unsigned(bits, 4);\n\n      if (extra==15)\n         st->dtx_enabled=1;\n      else\n         st->dtx_enabled=0;\n   }\n   if (st->submodeID>1)\n      st->dtx_enabled=0;\n\n   /*Loop on subframes */\n   for (sub=0;sub<st->nbSubframes;sub++)\n   {\n      int offset;\n      spx_word16_t *exc;\n      spx_word16_t *sp;\n      spx_word16_t *innov_save = NULL;\n      spx_word16_t tmp;\n\n      /* Offset relative to start of frame */\n      offset = st->subframeSize*sub;\n      /* Excitation */\n      exc=st->exc+offset;\n      /* Original signal */\n      sp=out+offset;\n      if (st->innov_save)\n         innov_save = st->innov_save+offset;\n\n\n      /* Reset excitation */\n      SPEEX_MEMSET(exc, 0, st->subframeSize);\n\n      /*Adaptive codebook contribution*/\n      speex_assert (SUBMODE(ltp_unquant));\n      {\n         int pit_min, pit_max;\n         /* Handle pitch constraints if any */\n         if (SUBMODE(lbr_pitch) != -1)\n         {\n            int margin;\n            margin = SUBMODE(lbr_pitch);\n            if (margin)\n            {\n/* GT - need optimization?\n               if (ol_pitch < st->min_pitch+margin-1)\n                  ol_pitch=st->min_pitch+margin-1;\n               if (ol_pitch > st->max_pitch-margin)\n                  ol_pitch=st->max_pitch-margin;\n               pit_min = ol_pitch-margin+1;\n               pit_max = ol_pitch+margin;\n*/\n               pit_min = ol_pitch-margin+1;\n               if (pit_min < st->min_pitch)\n\t\t  pit_min = st->min_pitch;\n               pit_max = ol_pitch+margin;\n               if (pit_max > st->max_pitch)\n\t\t  pit_max = st->max_pitch;\n            } else {\n               pit_min = pit_max = ol_pitch;\n            }\n         } else {\n            pit_min = st->min_pitch;\n            pit_max = st->max_pitch;\n         }\n\n\n\n         SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params), \n                 st->subframeSize, &pitch, &pitch_gain[0], bits, stack, \n                 st->count_lost, offset, st->last_pitch_gain, 0);\n\n         /* Ensuring that things aren't blowing up as would happen if e.g. an encoder is \n         crafting packets to make us produce NaNs and slow down the decoder (vague DoS threat).\n         We can probably be even more aggressive and limit to 15000 or so. */\n         sanitize_values32(exc32, NEG32(QCONST32(32000,SIG_SHIFT-1)), QCONST32(32000,SIG_SHIFT-1), st->subframeSize);\n         \n         tmp = gain_3tap_to_1tap(pitch_gain);\n\n         pitch_average += tmp;\n         if ((tmp>best_pitch_gain&&ABS(2*best_pitch-pitch)>=3&&ABS(3*best_pitch-pitch)>=4&&ABS(4*best_pitch-pitch)>=5) \n              || (tmp>MULT16_16_Q15(QCONST16(.6,15),best_pitch_gain)&&(ABS(best_pitch-2*pitch)<3||ABS(best_pitch-3*pitch)<4||ABS(best_pitch-4*pitch)<5)) \n              || (MULT16_16_Q15(QCONST16(.67,15),tmp)>best_pitch_gain&&(ABS(2*best_pitch-pitch)<3||ABS(3*best_pitch-pitch)<4||ABS(4*best_pitch-pitch)<5)) )\n         {\n            best_pitch = pitch;\n            if (tmp > best_pitch_gain)\n               best_pitch_gain = tmp;\n         }\n      }\n      \n      /* Unquantize the innovation */\n      {\n         int q_energy;\n         spx_word32_t ener;\n         \n         SPEEX_MEMSET(innov, 0, st->subframeSize);\n\n         /* Decode sub-frame gain correction */\n         if (SUBMODE(have_subframe_gain)==3)\n         {\n            q_energy = speex_bits_unpack_unsigned(bits, 3);\n            ener = MULT16_32_Q14(exc_gain_quant_scal3[q_energy],ol_gain);\n         } else if (SUBMODE(have_subframe_gain)==1)\n         {\n            q_energy = speex_bits_unpack_unsigned(bits, 1);\n            ener = MULT16_32_Q14(exc_gain_quant_scal1[q_energy],ol_gain);\n         } else {\n            ener = ol_gain;\n         }\n                  \n         speex_assert (SUBMODE(innovation_unquant));\n         {\n            /*Fixed codebook contribution*/\n            SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed);\n            /* De-normalize innovation and update excitation */\n\n            signal_mul(innov, innov, ener, st->subframeSize);\n\n            /* Decode second codebook (only for some modes) */\n            if (SUBMODE(double_codebook))\n            {\n               char *tmp_stack=stack;\n               VARDECL(spx_sig_t *innov2);\n               ALLOC(innov2, st->subframeSize, spx_sig_t);\n               SPEEX_MEMSET(innov2, 0, st->subframeSize);\n               SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed);\n               signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), st->subframeSize);\n               for (i=0;i<st->subframeSize;i++)\n                  innov[i] = ADD32(innov[i], innov2[i]);\n               stack = tmp_stack;\n            }\n            for (i=0;i<st->subframeSize;i++)\n               exc[i]=EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767));\n            /*print_vec(exc, 40, \"innov\");*/\n            if (innov_save)\n            {\n               for (i=0;i<st->subframeSize;i++)\n                  innov_save[i] = EXTRACT16(PSHR32(innov[i], SIG_SHIFT));\n            }\n         }\n\n         /*Vocoder mode*/\n         if (st->submodeID==1) \n         {\n            spx_word16_t g=ol_pitch_coef;\n            g=MULT16_16_P14(QCONST16(1.5f,14),(g-QCONST16(.2f,6)));\n            if (g<0)\n               g=0;\n            if (g>GAIN_SCALING)\n               g=GAIN_SCALING;\n            \n            SPEEX_MEMSET(exc, 0, st->subframeSize);\n            while (st->voc_offset<st->subframeSize)\n            {\n               /* exc[st->voc_offset]= g*sqrt(2*ol_pitch)*ol_gain;\n                  Not quite sure why we need the factor of two in the sqrt */\n               if (st->voc_offset>=0)\n                  exc[st->voc_offset]=MULT16_16(spx_sqrt(MULT16_16_16(2,ol_pitch)),EXTRACT16(PSHR32(MULT16_16(g,PSHR32(ol_gain,SIG_SHIFT)),6)));\n               st->voc_offset+=ol_pitch;\n            }\n            st->voc_offset -= st->subframeSize;\n            \n            for (i=0;i<st->subframeSize;i++)\n            {\n               spx_word16_t exci=exc[i];\n               exc[i]= ADD16(ADD16(MULT16_16_Q15(QCONST16(.7f,15),exc[i]) , MULT16_16_Q15(QCONST16(.3f,15),st->voc_m1)),\n                             SUB16(MULT16_16_Q15(Q15_ONE-MULT16_16_16(QCONST16(.85f,9),g),EXTRACT16(PSHR32(innov[i],SIG_SHIFT))),\n                                   MULT16_16_Q15(MULT16_16_16(QCONST16(.15f,9),g),EXTRACT16(PSHR32(st->voc_m2,SIG_SHIFT)))\n                                  ));\n               st->voc_m1 = exci;\n               st->voc_m2=innov[i];\n               st->voc_mean = EXTRACT16(PSHR32(ADD32(MULT16_16(QCONST16(.8f,15),st->voc_mean), MULT16_16(QCONST16(.2f,15),exc[i])), 15));\n               exc[i]-=st->voc_mean;\n            }\n         }\n\n      }\n   }\n   \n   ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);\n\n   if (st->lpc_enh_enabled && SUBMODE(comb_gain)>0 && !st->count_lost)\n   {\n      multicomb(st->exc-st->subframeSize, out, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack);\n      multicomb(st->exc+st->subframeSize, out+2*st->subframeSize, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack);\n   } else {\n      SPEEX_COPY(out, &st->exc[-st->subframeSize], st->frameSize);\n   }\n   \n   /* If the last packet was lost, re-scale the excitation to obtain the same energy as encoded in ol_gain */\n   if (st->count_lost) \n   {\n      spx_word16_t exc_ener;\n      spx_word32_t gain32;\n      spx_word16_t gain;\n      exc_ener = compute_rms16 (st->exc, st->frameSize);\n      gain32 = PDIV32(ol_gain, ADD16(exc_ener,1));\n#ifdef FIXED_POINT\n      if (gain32 > 32767)\n         gain32 = 32767;\n      gain = EXTRACT16(gain32);\n#else\n      if (gain32 > 2)\n         gain32=2;\n      gain = gain32;\n#endif\n      for (i=0;i<st->frameSize;i++)\n      {\n         st->exc[i] = MULT16_16_Q14(gain, st->exc[i]);\n         out[i]=st->exc[i-st->subframeSize];\n      }\n   }\n\n   /*Loop on subframes */\n   for (sub=0;sub<st->nbSubframes;sub++)\n   {\n      int offset;\n      spx_word16_t *sp;\n      spx_word16_t *exc;\n      /* Offset relative to start of frame */\n      offset = st->subframeSize*sub;\n      /* Original signal */\n      sp=out+offset;\n      /* Excitation */\n      exc=st->exc+offset;\n\n      /* LSP interpolation (quantized and unquantized) */\n      lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);\n\n      /* Make sure the LSP's are stable */\n      lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);\n\n      /* Compute interpolated LPCs (unquantized) */\n      lsp_to_lpc(interp_qlsp, ak, st->lpcSize, stack);\n\n      /* Compute analysis filter at w=pi */\n      {\n         spx_word32_t pi_g=LPC_SCALING;\n         for (i=0;i<st->lpcSize;i+=2)\n         {\n            /*pi_g += -st->interp_qlpc[i] +  st->interp_qlpc[i+1];*/\n            pi_g = ADD32(pi_g, SUB32(EXTEND32(ak[i+1]),EXTEND32(ak[i])));\n         }\n         st->pi_gain[sub] = pi_g;\n      }\n      \n      iir_mem16(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, \n                st->mem_sp, stack);\n      \n      for (i=0;i<st->lpcSize;i++)\n         st->interp_qlpc[i] = ak[i];\n\n   }\n\n   if (st->highpass_enabled)\n      highpass(out, out, st->frameSize, (st->isWideband?HIGHPASS_WIDEBAND:HIGHPASS_NARROWBAND)|HIGHPASS_OUTPUT, st->mem_hp);\n   /*for (i=0;i<st->frameSize;i++)\n     printf (\"%d\\n\", (int)st->frame[i]);*/\n\n   /* Tracking output level */\n   st->level = 1+PSHR32(ol_gain,SIG_SHIFT);\n   st->max_level = MAX16(MULT16_16_Q15(QCONST16(.99f,15), st->max_level), st->level);\n   st->min_level = MIN16(ADD16(1,MULT16_16_Q14(QCONST16(1.01f,14), st->min_level)), st->level);\n   if (st->max_level < st->min_level+1)\n      st->max_level = st->min_level+1;\n   /*printf (\"%f %f %f %d\\n\", og, st->min_level, st->max_level, update);*/\n   \n   /* Store the LSPs for interpolation in the next frame */\n   for (i=0;i<st->lpcSize;i++)\n      st->old_qlsp[i] = qlsp[i];\n\n   /* The next frame will not be the first (Duh!) */\n   st->first = 0;\n   st->count_lost=0;\n   st->last_pitch = best_pitch;\n#ifdef FIXED_POINT\n   st->last_pitch_gain = PSHR16(pitch_average,2);\n#else\n   st->last_pitch_gain = .25*pitch_average;   \n#endif\n   st->pitch_gain_buf[st->pitch_gain_buf_idx++] = st->last_pitch_gain;\n   if (st->pitch_gain_buf_idx > 2) /* rollover */\n      st->pitch_gain_buf_idx = 0;\n\n   st->last_ol_gain = ol_gain;\n\n   return 0;\n}\n\nint nb_encoder_ctl(void *state, int request, void *ptr)\n{\n   EncState *st;\n   st=(EncState*)state;     \n   switch(request)\n   {\n   case SPEEX_GET_FRAME_SIZE:\n      (*(spx_int32_t*)ptr) = st->frameSize;\n      break;\n   case SPEEX_SET_LOW_MODE:\n   case SPEEX_SET_MODE:\n      st->submodeSelect = st->submodeID = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_LOW_MODE:\n   case SPEEX_GET_MODE:\n      (*(spx_int32_t*)ptr) = st->submodeID;\n      break;\n#ifndef DISABLE_VBR\n      case SPEEX_SET_VBR:\n      st->vbr_enabled = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_VBR:\n      (*(spx_int32_t*)ptr) = st->vbr_enabled;\n      break;\n   case SPEEX_SET_VAD:\n      st->vad_enabled = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_VAD:\n      (*(spx_int32_t*)ptr) = st->vad_enabled;\n      break;\n   case SPEEX_SET_DTX:\n      st->dtx_enabled = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_DTX:\n      (*(spx_int32_t*)ptr) = st->dtx_enabled;\n      break;\n   case SPEEX_SET_ABR:\n      st->abr_enabled = (*(spx_int32_t*)ptr);\n      st->vbr_enabled = st->abr_enabled!=0;\n      if (st->vbr_enabled) \n      {\n         spx_int32_t i=10;\n         spx_int32_t rate, target;\n         float vbr_qual;\n         target = (*(spx_int32_t*)ptr);\n         while (i>=0)\n         {\n            speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);\n            speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);\n            if (rate <= target)\n               break;\n            i--;\n         }\n         vbr_qual=i;\n         if (vbr_qual<0)\n            vbr_qual=0;\n         speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual);\n         st->abr_count=0;\n         st->abr_drift=0;\n         st->abr_drift2=0;\n      }\n      \n      break;\n   case SPEEX_GET_ABR:\n      (*(spx_int32_t*)ptr) = st->abr_enabled;\n      break;\n#endif /* #ifndef DISABLE_VBR */\n#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API)\n   case SPEEX_SET_VBR_QUALITY:\n      st->vbr_quality = (*(float*)ptr);\n      break;\n   case SPEEX_GET_VBR_QUALITY:\n      (*(float*)ptr) = st->vbr_quality;\n      break;\n#endif /* !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */\n   case SPEEX_SET_QUALITY:\n      {\n         int quality = (*(spx_int32_t*)ptr);\n         if (quality < 0)\n            quality = 0;\n         if (quality > 10)\n            quality = 10;\n         st->submodeSelect = st->submodeID = ((const SpeexNBMode*)(st->mode->mode))->quality_map[quality];\n      }\n      break;\n   case SPEEX_SET_COMPLEXITY:\n      st->complexity = (*(spx_int32_t*)ptr);\n      if (st->complexity<0)\n         st->complexity=0;\n      break;\n   case SPEEX_GET_COMPLEXITY:\n      (*(spx_int32_t*)ptr) = st->complexity;\n      break;\n   case SPEEX_SET_BITRATE:\n      {\n         spx_int32_t i=10;\n         spx_int32_t rate, target;\n         target = (*(spx_int32_t*)ptr);\n         while (i>=0)\n         {\n            speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);\n            speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);\n            if (rate <= target)\n               break;\n            i--;\n         }\n      }\n      break;\n   case SPEEX_GET_BITRATE:\n      if (st->submodes[st->submodeID])\n         (*(spx_int32_t*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize;\n      else\n         (*(spx_int32_t*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize;\n      break;\n   case SPEEX_SET_SAMPLING_RATE:\n      st->sampling_rate = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_SAMPLING_RATE:\n      (*(spx_int32_t*)ptr)=st->sampling_rate;\n      break;\n   case SPEEX_RESET_STATE:\n      {\n         int i;\n         st->bounded_pitch = 1;\n         st->first = 1;\n         for (i=0;i<st->lpcSize;i++)\n            st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);\n         for (i=0;i<st->lpcSize;i++)\n            st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0;\n         for (i=0;i<st->frameSize+st->max_pitch+1;i++)\n            st->excBuf[i]=st->swBuf[i]=0;\n         for (i=0;i<st->windowSize-st->frameSize;i++)\n            st->winBuf[i]=0;\n      }\n      break;\n   case SPEEX_SET_SUBMODE_ENCODING:\n      st->encode_submode = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_SUBMODE_ENCODING:\n      (*(spx_int32_t*)ptr) = st->encode_submode;\n      break;\n   case SPEEX_GET_LOOKAHEAD:\n      (*(spx_int32_t*)ptr)=(st->windowSize-st->frameSize);\n      break;\n   case SPEEX_SET_PLC_TUNING:\n      st->plc_tuning = (*(spx_int32_t*)ptr);\n      if (st->plc_tuning>100)\n         st->plc_tuning=100;\n      break;\n   case SPEEX_GET_PLC_TUNING:\n      (*(spx_int32_t*)ptr)=(st->plc_tuning);\n      break;\n#ifndef DISABLE_VBR\n   case SPEEX_SET_VBR_MAX_BITRATE:\n      st->vbr_max = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_VBR_MAX_BITRATE:\n      (*(spx_int32_t*)ptr) = st->vbr_max;\n      break;\n#endif /* #ifndef DISABLE_VBR */\n   case SPEEX_SET_HIGHPASS:\n      st->highpass_enabled = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_HIGHPASS:\n      (*(spx_int32_t*)ptr) = st->highpass_enabled;\n      break;\n\n   /* This is all internal stuff past this point */\n   case SPEEX_GET_PI_GAIN:\n      {\n         int i;\n         spx_word32_t *g = (spx_word32_t*)ptr;\n         for (i=0;i<st->nbSubframes;i++)\n            g[i]=st->pi_gain[i];\n      }\n      break;\n   case SPEEX_GET_EXC:\n      {\n         int i;\n         for (i=0;i<st->nbSubframes;i++)\n            ((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize);\n      }\n      break;\n#ifndef DISABLE_VBR\n   case SPEEX_GET_RELATIVE_QUALITY:\n      (*(float*)ptr)=st->relative_quality;\n      break;\n#endif /* #ifndef DISABLE_VBR */\n   case SPEEX_SET_INNOVATION_SAVE:\n      st->innov_rms_save = (spx_word16_t*)ptr;\n      break;\n   case SPEEX_SET_WIDEBAND:\n      st->isWideband = *((spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_STACK:\n      *((char**)ptr) = st->stack;\n      break;\n   default:\n      speex_warning_int(\"Unknown nb_ctl request: \", request);\n      return -1;\n   }\n   return 0;\n}\n\nint nb_decoder_ctl(void *state, int request, void *ptr)\n{\n   DecState *st;\n   st=(DecState*)state;\n   switch(request)\n   {\n   case SPEEX_SET_LOW_MODE:\n   case SPEEX_SET_MODE:\n      st->submodeID = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_LOW_MODE:\n   case SPEEX_GET_MODE:\n      (*(spx_int32_t*)ptr) = st->submodeID;\n      break;\n   case SPEEX_SET_ENH:\n      st->lpc_enh_enabled = *((spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_ENH:\n      *((spx_int32_t*)ptr) = st->lpc_enh_enabled;\n      break;\n   case SPEEX_GET_FRAME_SIZE:\n      (*(spx_int32_t*)ptr) = st->frameSize;\n      break;\n   case SPEEX_GET_BITRATE:\n      if (st->submodes[st->submodeID])\n         (*(spx_int32_t*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize;\n      else\n         (*(spx_int32_t*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize;\n      break;\n   case SPEEX_SET_SAMPLING_RATE:\n      st->sampling_rate = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_SAMPLING_RATE:\n      (*(spx_int32_t*)ptr)=st->sampling_rate;\n      break;\n   case SPEEX_SET_HANDLER:\n      {\n         SpeexCallback *c = (SpeexCallback*)ptr;\n         st->speex_callbacks[c->callback_id].func=c->func;\n         st->speex_callbacks[c->callback_id].data=c->data;\n         st->speex_callbacks[c->callback_id].callback_id=c->callback_id;\n      }\n      break;\n   case SPEEX_SET_USER_HANDLER:\n      {\n         SpeexCallback *c = (SpeexCallback*)ptr;\n         st->user_callback.func=c->func;\n         st->user_callback.data=c->data;\n         st->user_callback.callback_id=c->callback_id;\n      }\n      break;\n   case SPEEX_RESET_STATE:\n      {\n         int i;\n         for (i=0;i<st->lpcSize;i++)\n            st->mem_sp[i]=0;\n         for (i=0;i<st->frameSize + st->max_pitch + 1;i++)\n            st->excBuf[i]=0;\n      }\n      break;\n   case SPEEX_SET_SUBMODE_ENCODING:\n      st->encode_submode = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_SUBMODE_ENCODING:\n      (*(spx_int32_t*)ptr) = st->encode_submode;\n      break;\n   case SPEEX_GET_LOOKAHEAD:\n      (*(spx_int32_t*)ptr)=st->subframeSize;\n      break;\n   case SPEEX_SET_HIGHPASS:\n      st->highpass_enabled = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_HIGHPASS:\n      (*(spx_int32_t*)ptr) = st->highpass_enabled;\n      break;\n      /* FIXME: Convert to fixed-point and re-enable even when float API is disabled */\n#ifndef DISABLE_FLOAT_API\n   case SPEEX_GET_ACTIVITY:\n   {\n      float ret;\n      ret = log(st->level/st->min_level)/log(st->max_level/st->min_level);\n      if (ret>1)\n         ret = 1;\n      /* Done in a strange way to catch NaNs as well */\n      if (!(ret > 0))\n         ret = 0;\n      /*printf (\"%f %f %f %f\\n\", st->level, st->min_level, st->max_level, ret);*/\n      (*(spx_int32_t*)ptr) = (int)(100*ret);\n   }\n   break;\n#endif\n   case SPEEX_GET_PI_GAIN:\n      {\n         int i;\n         spx_word32_t *g = (spx_word32_t*)ptr;\n         for (i=0;i<st->nbSubframes;i++)\n            g[i]=st->pi_gain[i];\n      }\n      break;\n   case SPEEX_GET_EXC:\n      {\n         int i;\n         for (i=0;i<st->nbSubframes;i++)\n            ((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize);\n      }\n      break;\n   case SPEEX_GET_DTX_STATUS:\n      *((spx_int32_t*)ptr) = st->dtx_enabled;\n      break;\n   case SPEEX_SET_INNOVATION_SAVE:\n      st->innov_save = (spx_word16_t*)ptr;\n      break;\n   case SPEEX_SET_WIDEBAND:\n      st->isWideband = *((spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_STACK:\n      *((char**)ptr) = st->stack;\n      break;\n   default:\n      speex_warning_int(\"Unknown nb_ctl request: \", request);\n      return -1;\n   }\n   return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/nb_celp.h",
    "content": "/* Copyright (C) 2002-2006 Jean-Marc Valin */\n/**\n    @file nb_celp.h\n    @brief Narrowband CELP encoder/decoder\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifndef NB_CELP_H\n#define NB_CELP_H\n\n#include \"modes.h\"\n#include <speex/speex_bits.h>\n#include <speex/speex_callbacks.h>\n#include \"vbr.h\"\n#include \"filters.h\"\n\n#ifdef VORBIS_PSYCHO\n#include \"vorbis_psy.h\"\n#endif\n\n/**Structure representing the full state of the narrowband encoder*/\ntypedef struct EncState {\n   const SpeexMode *mode;        /**< Mode corresponding to the state */\n   int    first;                 /**< Is this the first frame? */\n   int    frameSize;             /**< Size of frames */\n   int    subframeSize;          /**< Size of sub-frames */\n   int    nbSubframes;           /**< Number of sub-frames */\n   int    windowSize;            /**< Analysis (LPC) window length */\n   int    lpcSize;               /**< LPC order */\n   int    min_pitch;             /**< Minimum pitch value allowed */\n   int    max_pitch;             /**< Maximum pitch value allowed */\n\n   spx_word32_t cumul_gain;      /**< Product of previously used pitch gains (Q10) */\n   int    bounded_pitch;         /**< Next frame should not rely on previous frames for pitch */\n   int    ol_pitch;              /**< Open-loop pitch */\n   int    ol_voiced;             /**< Open-loop voiced/non-voiced decision */\n   int   *pitch;\n\n#ifdef VORBIS_PSYCHO\n   VorbisPsy *psy;\n   float *psy_window;\n   float *curve;\n   float *old_curve;\n#endif\n\n   spx_word16_t  gamma1;         /**< Perceptual filter: A(z/gamma1) */\n   spx_word16_t  gamma2;         /**< Perceptual filter: A(z/gamma2) */\n   spx_word16_t  lpc_floor;      /**< Noise floor multiplier for A[0] in LPC analysis*/\n   char  *stack;                 /**< Pseudo-stack allocation for temporary memory */\n   spx_word16_t *winBuf;         /**< Input buffer (original signal) */\n   spx_word16_t *excBuf;         /**< Excitation buffer */\n   spx_word16_t *exc;            /**< Start of excitation frame */\n   spx_word16_t *swBuf;          /**< Weighted signal buffer */\n   spx_word16_t *sw;             /**< Start of weighted signal frame */\n   const spx_word16_t *window;   /**< Temporary (Hanning) window */\n   const spx_word16_t *lagWindow;      /**< Window applied to auto-correlation */\n   spx_lsp_t *old_lsp;           /**< LSPs for previous frame */\n   spx_lsp_t *old_qlsp;          /**< Quantized LSPs for previous frame */\n   spx_mem_t *mem_sp;            /**< Filter memory for signal synthesis */\n   spx_mem_t *mem_sw;            /**< Filter memory for perceptually-weighted signal */\n   spx_mem_t *mem_sw_whole;      /**< Filter memory for perceptually-weighted signal (whole frame)*/\n   spx_mem_t *mem_exc;           /**< Filter memory for excitation (whole frame) */\n   spx_mem_t *mem_exc2;          /**< Filter memory for excitation (whole frame) */\n   spx_mem_t mem_hp[2];          /**< High-pass filter memory */\n   spx_word32_t *pi_gain;        /**< Gain of LPC filter at theta=pi (fe/2) */\n   spx_word16_t *innov_rms_save; /**< If non-NULL, innovation RMS is copied here */\n\n#ifndef DISABLE_VBR\n   VBRState *vbr;                /**< State of the VBR data */\n   float  vbr_quality;           /**< Quality setting for VBR encoding */\n   float  relative_quality;      /**< Relative quality that will be needed by VBR */\n   spx_int32_t vbr_enabled;      /**< 1 for enabling VBR, 0 otherwise */\n   spx_int32_t vbr_max;          /**< Max bit-rate allowed in VBR mode */\n   int    vad_enabled;           /**< 1 for enabling VAD, 0 otherwise */\n   int    dtx_enabled;           /**< 1 for enabling DTX, 0 otherwise */\n   int    dtx_count;             /**< Number of consecutive DTX frames */\n   spx_int32_t abr_enabled;      /**< ABR setting (in bps), 0 if off */\n   float  abr_drift;\n   float  abr_drift2;\n   float  abr_count;\n#endif /* #ifndef DISABLE_VBR */\n   \n   int    complexity;            /**< Complexity setting (0-10 from least complex to most complex) */\n   spx_int32_t sampling_rate;\n   int    plc_tuning;\n   int    encode_submode;\n   const SpeexSubmode * const *submodes; /**< Sub-mode data */\n   int    submodeID;             /**< Activated sub-mode */\n   int    submodeSelect;         /**< Mode chosen by the user (may differ from submodeID if VAD is on) */\n   int    isWideband;            /**< Is this used as part of the embedded wideband codec */\n   int    highpass_enabled;        /**< Is the input filter enabled */\n} EncState;\n\n/**Structure representing the full state of the narrowband decoder*/\ntypedef struct DecState {\n   const SpeexMode *mode;       /**< Mode corresponding to the state */\n   int    first;                /**< Is this the first frame? */\n   int    count_lost;           /**< Was the last frame lost? */\n   int    frameSize;            /**< Size of frames */\n   int    subframeSize;         /**< Size of sub-frames */\n   int    nbSubframes;          /**< Number of sub-frames */\n   int    lpcSize;              /**< LPC order */\n   int    min_pitch;            /**< Minimum pitch value allowed */\n   int    max_pitch;            /**< Maximum pitch value allowed */\n   spx_int32_t sampling_rate;\n\n   spx_word16_t  last_ol_gain;  /**< Open-loop gain for previous frame */\n\n   char  *stack;                /**< Pseudo-stack allocation for temporary memory */\n   spx_word16_t *excBuf;        /**< Excitation buffer */\n   spx_word16_t *exc;           /**< Start of excitation frame */\n   spx_lsp_t *old_qlsp;         /**< Quantized LSPs for previous frame */\n   spx_coef_t *interp_qlpc;     /**< Interpolated quantized LPCs */\n   spx_mem_t *mem_sp;           /**< Filter memory for synthesis signal */\n   spx_mem_t mem_hp[2];         /**< High-pass filter memory */\n   spx_word32_t *pi_gain;       /**< Gain of LPC filter at theta=pi (fe/2) */\n   spx_word16_t *innov_save;    /** If non-NULL, innovation is copied here */\n   \n   spx_word16_t level;\n   spx_word16_t max_level;\n   spx_word16_t min_level;\n   \n   /* This is used in packet loss concealment */\n   int    last_pitch;           /**< Pitch of last correctly decoded frame */\n   spx_word16_t  last_pitch_gain; /**< Pitch gain of last correctly decoded frame */\n   spx_word16_t  pitch_gain_buf[3]; /**< Pitch gain of last decoded frames */\n   int    pitch_gain_buf_idx;   /**< Tail of the buffer */\n   spx_int32_t seed;            /** Seed used for random number generation */\n   \n   int    encode_submode;\n   const SpeexSubmode * const *submodes; /**< Sub-mode data */\n   int    submodeID;            /**< Activated sub-mode */\n   int    lpc_enh_enabled;      /**< 1 when LPC enhancer is on, 0 otherwise */\n   SpeexCallback speex_callbacks[SPEEX_MAX_CALLBACKS];\n\n   SpeexCallback user_callback;\n\n   /*Vocoder data*/\n   spx_word16_t  voc_m1;\n   spx_word32_t  voc_m2;\n   spx_word16_t  voc_mean;\n   int    voc_offset;\n\n   int    dtx_enabled;\n   int    isWideband;            /**< Is this used as part of the embedded wideband codec */\n   int    highpass_enabled;        /**< Is the input filter enabled */\n} DecState;\n\n/** Initializes encoder state*/\nvoid *nb_encoder_init(const SpeexMode *m);\n\n/** De-allocates encoder state resources*/\nvoid nb_encoder_destroy(void *state);\n\n/** Encodes one frame*/\nint nb_encode(void *state, void *in, SpeexBits *bits);\n\n\n/** Initializes decoder state*/\nvoid *nb_decoder_init(const SpeexMode *m);\n\n/** De-allocates decoder state resources*/\nvoid nb_decoder_destroy(void *state);\n\n/** Decodes one frame*/\nint nb_decode(void *state, SpeexBits *bits, void *out);\n\n/** ioctl-like function for controlling a narrowband encoder */\nint nb_encoder_ctl(void *state, int request, void *ptr);\n\n/** ioctl-like function for controlling a narrowband decoder */\nint nb_decoder_ctl(void *state, int request, void *ptr);\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/os_support.h",
    "content": "/* Copyright (C) 2007 Jean-Marc Valin\n      \n   File: os_support.h\n   This is the (tiny) OS abstraction layer. Aside from math.h, this is the\n   only place where system headers are allowed.\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef OS_SUPPORT_H\n#define OS_SUPPORT_H\n\n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#ifdef OS_SUPPORT_CUSTOM\n#include \"os_support_custom.h\"\n#endif\n\n/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free \n    NOTE: speex_alloc needs to CLEAR THE MEMORY */\n#ifndef OVERRIDE_SPEEX_ALLOC\nstatic inline void *speex_alloc (int size)\n{\n   /* WARNING: this is not equivalent to malloc(). If you want to use malloc() \n      or your own allocator, YOU NEED TO CLEAR THE MEMORY ALLOCATED. Otherwise\n      you will experience strange bugs */\n   return calloc(size,1);\n}\n#endif\n\n/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */\n#ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH\nstatic inline void *speex_alloc_scratch (int size)\n{\n   /* Scratch space doesn't need to be cleared */\n   return calloc(size,1);\n}\n#endif\n\n/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */\n#ifndef OVERRIDE_SPEEX_REALLOC\nstatic inline void *speex_realloc (void *ptr, int size)\n{\n   return realloc(ptr, size);\n}\n#endif\n\n/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */\n#ifndef OVERRIDE_SPEEX_FREE\nstatic inline void speex_free (void *ptr)\n{\n   free(ptr);\n}\n#endif\n\n/** Same as speex_free, except that the area is only needed inside a Speex call (might cause problem with wideband though) */\n#ifndef OVERRIDE_SPEEX_FREE_SCRATCH\nstatic inline void speex_free_scratch (void *ptr)\n{\n   free(ptr);\n}\n#endif\n\n/** Copy n bytes of memory from src to dst. The 0* term provides compile-time type checking  */\n#ifndef OVERRIDE_SPEEX_COPY\n#define SPEEX_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))\n#endif\n\n/** Copy n bytes of memory from src to dst, allowing overlapping regions. The 0* term \n    provides compile-time type checking */\n#ifndef OVERRIDE_SPEEX_MOVE\n#define SPEEX_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))\n#endif\n\n/** Set n bytes of memory to value of c, starting at address s */\n#ifndef OVERRIDE_SPEEX_MEMSET\n#define SPEEX_MEMSET(dst, c, n) (memset((dst), (c), (n)*sizeof(*(dst))))\n#endif\n\n\n#ifndef OVERRIDE_SPEEX_FATAL\nstatic inline void _speex_fatal(const char *str, const char *file, int line)\n{\n   fprintf (stderr, \"Fatal (internal) error in %s, line %d: %s\\n\", file, line, str);\n   exit(1);\n}\n#endif\n\n#ifndef OVERRIDE_SPEEX_WARNING\nstatic inline void speex_warning(const char *str)\n{\n#ifndef DISABLE_WARNINGS\n   fprintf (stderr, \"warning: %s\\n\", str);\n#endif\n}\n#endif\n\n#ifndef OVERRIDE_SPEEX_WARNING_INT\nstatic inline void speex_warning_int(const char *str, int val)\n{\n#ifndef DISABLE_WARNINGS\n   fprintf (stderr, \"warning: %s %d\\n\", str, val);\n#endif\n}\n#endif\n\n#ifndef OVERRIDE_SPEEX_NOTIFY\nstatic inline void speex_notify(const char *str)\n{\n#ifndef DISABLE_NOTIFICATIONS\n   fprintf (stderr, \"notification: %s\\n\", str);\n#endif\n}\n#endif\n\n#ifndef OVERRIDE_SPEEX_PUTC\n/** Speex wrapper for putc */\nstatic inline void _speex_putc(int ch, void *file)\n{\n   FILE *f = (FILE *)file;\n   fprintf(f, \"%c\", ch);\n}\n#endif\n\n#define speex_fatal(str) _speex_fatal(str, __FILE__, __LINE__);\n#define speex_assert(cond) {if (!(cond)) {speex_fatal(\"assertion failed: \" #cond);}}\n\n#ifndef RELEASE\nstatic inline void print_vec(float *vec, int len, char *name)\n{\n   int i;\n   printf (\"%s \", name);\n   for (i=0;i<len;i++)\n      printf (\" %f\", vec[i]);\n   printf (\"\\n\");\n}\n#endif\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/preprocess.c",
    "content": "/* Copyright (C) 2003 Epic Games (written by Jean-Marc Valin)\n   Copyright (C) 2004-2006 Epic Games \n   \n   File: preprocess.c\n   Preprocessor with denoising based on the algorithm by Ephraim and Malah\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\n/*\n   Recommended papers:\n   \n   Y. Ephraim and D. Malah, \"Speech enhancement using minimum mean-square error\n   short-time spectral amplitude estimator\". IEEE Transactions on Acoustics, \n   Speech and Signal Processing, vol. ASSP-32, no. 6, pp. 1109-1121, 1984.\n   \n   Y. Ephraim and D. Malah, \"Speech enhancement using minimum mean-square error\n   log-spectral amplitude estimator\". IEEE Transactions on Acoustics, Speech and \n   Signal Processing, vol. ASSP-33, no. 2, pp. 443-445, 1985.\n   \n   I. Cohen and B. Berdugo, \"Speech enhancement for non-stationary noise environments\".\n   Signal Processing, vol. 81, no. 2, pp. 2403-2418, 2001.\n\n   Stefan Gustafsson, Rainer Martin, Peter Jax, and Peter Vary. \"A psychoacoustic \n   approach to combined acoustic echo cancellation and noise reduction\". IEEE \n   Transactions on Speech and Audio Processing, 2002.\n   \n   J.-M. Valin, J. Rouat, and F. Michaud, \"Microphone array post-filter for separation\n   of simultaneous non-stationary sources\". In Proceedings IEEE International \n   Conference on Acoustics, Speech, and Signal Processing, 2004.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <math.h>\n#include \"speex/speex_preprocess.h\"\n#include \"speex/speex_echo.h\"\n#include \"arch.h\"\n#include \"fftwrap.h\"\n#include \"filterbank.h\"\n#include \"math_approx.h\"\n#include \"os_support.h\"\n\n#ifndef M_PI\n#define M_PI 3.14159263\n#endif\n\n#define LOUDNESS_EXP 5.f\n#define AMP_SCALE .001f\n#define AMP_SCALE_1 1000.f\n      \n#define NB_BANDS 24\n\n#define SPEECH_PROB_START_DEFAULT       QCONST16(0.35f,15)\n#define SPEECH_PROB_CONTINUE_DEFAULT    QCONST16(0.20f,15)\n#define NOISE_SUPPRESS_DEFAULT       -15\n#define ECHO_SUPPRESS_DEFAULT        -40\n#define ECHO_SUPPRESS_ACTIVE_DEFAULT -15\n\n#ifndef NULL\n#define NULL 0\n#endif\n\n#define SQR(x) ((x)*(x))\n#define SQR16(x) (MULT16_16((x),(x)))\n#define SQR16_Q15(x) (MULT16_16_Q15((x),(x)))\n\n#ifdef FIXED_POINT\nstatic inline spx_word16_t DIV32_16_Q8(spx_word32_t a, spx_word32_t b)\n{\n   if (SHR32(a,7) >= b)\n   {\n      return 32767;\n   } else {\n      if (b>=QCONST32(1,23))\n      {\n         a = SHR32(a,8);\n         b = SHR32(b,8);\n      }\n      if (b>=QCONST32(1,19))\n      {\n         a = SHR32(a,4);\n         b = SHR32(b,4);\n      }\n      if (b>=QCONST32(1,15))\n      {\n         a = SHR32(a,4);\n         b = SHR32(b,4);\n      }\n      a = SHL32(a,8);\n      return PDIV32_16(a,b);\n   }\n   \n}\nstatic inline spx_word16_t DIV32_16_Q15(spx_word32_t a, spx_word32_t b)\n{\n   if (SHR32(a,15) >= b)\n   {\n      return 32767;\n   } else {\n      if (b>=QCONST32(1,23))\n      {\n         a = SHR32(a,8);\n         b = SHR32(b,8);\n      }\n      if (b>=QCONST32(1,19))\n      {\n         a = SHR32(a,4);\n         b = SHR32(b,4);\n      }\n      if (b>=QCONST32(1,15))\n      {\n         a = SHR32(a,4);\n         b = SHR32(b,4);\n      }\n      a = SHL32(a,15)-a;\n      return DIV32_16(a,b);\n   }\n}\n#define SNR_SCALING 256.f\n#define SNR_SCALING_1 0.0039062f\n#define SNR_SHIFT 8\n\n#define FRAC_SCALING 32767.f\n#define FRAC_SCALING_1 3.0518e-05\n#define FRAC_SHIFT 1\n\n#define EXPIN_SCALING 2048.f\n#define EXPIN_SCALING_1 0.00048828f\n#define EXPIN_SHIFT 11\n#define EXPOUT_SCALING_1 1.5259e-05\n\n#define NOISE_SHIFT 7\n\n#else\n\n#define DIV32_16_Q8(a,b) ((a)/(b))\n#define DIV32_16_Q15(a,b) ((a)/(b))\n#define SNR_SCALING 1.f\n#define SNR_SCALING_1 1.f\n#define SNR_SHIFT 0\n#define FRAC_SCALING 1.f\n#define FRAC_SCALING_1 1.f\n#define FRAC_SHIFT 0\n#define NOISE_SHIFT 0\n\n#define EXPIN_SCALING 1.f\n#define EXPIN_SCALING_1 1.f\n#define EXPOUT_SCALING_1 1.f\n\n#endif\n\n/** Speex pre-processor state. */\nstruct SpeexPreprocessState_ {\n   /* Basic info */\n   int    frame_size;        /**< Number of samples processed each time */\n   int    ps_size;           /**< Number of points in the power spectrum */\n   int    sampling_rate;     /**< Sampling rate of the input/output */\n   int    nbands;\n   FilterBank *bank;\n   \n   /* Parameters */\n   int    denoise_enabled;\n   int    vad_enabled;\n   int    dereverb_enabled;\n   spx_word16_t  reverb_decay;\n   spx_word16_t  reverb_level;\n   spx_word16_t speech_prob_start;\n   spx_word16_t speech_prob_continue;\n   int    noise_suppress;\n   int    echo_suppress;\n   int    echo_suppress_active;\n   SpeexEchoState *echo_state;\n   \n   spx_word16_t\tspeech_prob;  /**< Probability last frame was speech */\n\n   /* DSP-related arrays */\n   spx_word16_t *frame;      /**< Processing frame (2*ps_size) */\n   spx_word16_t *ft;         /**< Processing frame in freq domain (2*ps_size) */\n   spx_word32_t *ps;         /**< Current power spectrum */\n   spx_word16_t *gain2;      /**< Adjusted gains */\n   spx_word16_t *gain_floor; /**< Minimum gain allowed */\n   spx_word16_t *window;     /**< Analysis/Synthesis window */\n   spx_word32_t *noise;      /**< Noise estimate */\n   spx_word32_t *reverb_estimate; /**< Estimate of reverb energy */\n   spx_word32_t *old_ps;     /**< Power spectrum for last frame */\n   spx_word16_t *gain;       /**< Ephraim Malah gain */\n   spx_word16_t *prior;      /**< A-priori SNR */\n   spx_word16_t *post;       /**< A-posteriori SNR */\n\n   spx_word32_t *S;          /**< Smoothed power spectrum */\n   spx_word32_t *Smin;       /**< See Cohen paper */\n   spx_word32_t *Stmp;       /**< See Cohen paper */\n   int *update_prob;         /**< Probability of speech presence for noise update */\n\n   spx_word16_t *zeta;       /**< Smoothed a priori SNR */\n   spx_word32_t *echo_noise;\n   spx_word32_t *residual_echo;\n\n   /* Misc */\n   spx_word16_t *inbuf;      /**< Input buffer (overlapped analysis) */\n   spx_word16_t *outbuf;     /**< Output buffer (for overlap and add) */\n\n   /* AGC stuff, only for floating point for now */\n#ifndef FIXED_POINT\n   int    agc_enabled;\n   float  agc_level;\n   float  loudness_accum;\n   float *loudness_weight;   /**< Perceptual loudness curve */\n   float  loudness;          /**< Loudness estimate */\n   float  agc_gain;          /**< Current AGC gain */\n   float  max_gain;          /**< Maximum gain allowed */\n   float  max_increase_step; /**< Maximum increase in gain from one frame to another */\n   float  max_decrease_step; /**< Maximum decrease in gain from one frame to another */\n   float  prev_loudness;     /**< Loudness of previous frame */\n   float  init_max;          /**< Current gain limit during initialisation */\n#endif\n   int    nb_adapt;          /**< Number of frames used for adaptation so far */\n   int    was_speech;\n   int    min_count;         /**< Number of frames processed so far */\n   void  *fft_lookup;        /**< Lookup table for the FFT */\n#ifdef FIXED_POINT\n   int    frame_shift;\n#endif\n};\n\n\nstatic void conj_window(spx_word16_t *w, int len)\n{\n   int i;\n   for (i=0;i<len;i++)\n   {\n      spx_word16_t tmp;\n#ifdef FIXED_POINT\n      spx_word16_t x = DIV32_16(MULT16_16(32767,i),len);\n#else      \n      spx_word16_t x = DIV32_16(MULT16_16(QCONST16(4.f,13),i),len);\n#endif\n      int inv=0;\n      if (x<QCONST16(1.f,13))\n      {\n      } else if (x<QCONST16(2.f,13))\n      {\n         x=QCONST16(2.f,13)-x;\n         inv=1;\n      } else if (x<QCONST16(3.f,13))\n      {\n         x=x-QCONST16(2.f,13);\n         inv=1;\n      } else {\n         x=QCONST16(2.f,13)-x+QCONST16(2.f,13); /* 4 - x */\n      }\n      x = MULT16_16_Q14(QCONST16(1.271903f,14), x);\n      tmp = SQR16_Q15(QCONST16(.5f,15)-MULT16_16_P15(QCONST16(.5f,15),spx_cos_norm(SHL32(EXTEND32(x),2))));\n      if (inv)\n         tmp=SUB16(Q15_ONE,tmp);\n      w[i]=spx_sqrt(SHL32(EXTEND32(tmp),15));\n   }\n}\n\n      \n#ifdef FIXED_POINT\n/* This function approximates the gain function \n   y = gamma(1.25)^2 * M(-.25;1;-x) / sqrt(x)  \n   which multiplied by xi/(1+xi) is the optimal gain\n   in the loudness domain ( sqrt[amplitude] )\n   Input in Q11 format, output in Q15\n*/\nstatic inline spx_word32_t hypergeom_gain(spx_word32_t xx)\n{\n   int ind;\n   spx_word16_t frac;\n   /* Q13 table */\n   static const spx_word16_t table[21] = {\n       6730,  8357,  9868, 11267, 12563, 13770, 14898,\n      15959, 16961, 17911, 18816, 19682, 20512, 21311,\n      22082, 22827, 23549, 24250, 24931, 25594, 26241};\n      ind = SHR32(xx,10);\n      if (ind<0)\n         return Q15_ONE;\n      if (ind>19)\n         return ADD32(EXTEND32(Q15_ONE),EXTEND32(DIV32_16(QCONST32(.1296,23), SHR32(xx,EXPIN_SHIFT-SNR_SHIFT))));\n      frac = SHL32(xx-SHL32(ind,10),5);\n      return SHL32(DIV32_16(PSHR32(MULT16_16(Q15_ONE-frac,table[ind]) + MULT16_16(frac,table[ind+1]),7),(spx_sqrt(SHL32(xx,15)+6711))),7);\n}\n\nstatic inline spx_word16_t qcurve(spx_word16_t x)\n{\n   x = MAX16(x, 1);\n   return DIV32_16(SHL32(EXTEND32(32767),9),ADD16(512,MULT16_16_Q15(QCONST16(.60f,15),DIV32_16(32767,x))));\n}\n\n/* Compute the gain floor based on different floors for the background noise and residual echo */\nstatic void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len)\n{\n   int i;\n   \n   if (noise_suppress > effective_echo_suppress)\n   {\n      spx_word16_t noise_gain, gain_ratio;\n      noise_gain = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(0.11513,11),noise_suppress)),1)));\n      gain_ratio = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(.2302585f,11),effective_echo_suppress-noise_suppress)),1)));\n\n      /* gain_floor = sqrt [ (noise*noise_floor + echo*echo_floor) / (noise+echo) ] */\n      for (i=0;i<len;i++)\n         gain_floor[i] = MULT16_16_Q15(noise_gain,\n                                       spx_sqrt(SHL32(EXTEND32(DIV32_16_Q15(PSHR32(noise[i],NOISE_SHIFT) + MULT16_32_Q15(gain_ratio,echo[i]),\n                                             (1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]) )),15)));\n   } else {\n      spx_word16_t echo_gain, gain_ratio;\n      echo_gain = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(0.11513,11),effective_echo_suppress)),1)));\n      gain_ratio = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(.2302585f,11),noise_suppress-effective_echo_suppress)),1)));\n\n      /* gain_floor = sqrt [ (noise*noise_floor + echo*echo_floor) / (noise+echo) ] */\n      for (i=0;i<len;i++)\n         gain_floor[i] = MULT16_16_Q15(echo_gain,\n                                       spx_sqrt(SHL32(EXTEND32(DIV32_16_Q15(MULT16_32_Q15(gain_ratio,PSHR32(noise[i],NOISE_SHIFT)) + echo[i],\n                                             (1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]) )),15)));\n   }\n}\n\n#else\n/* This function approximates the gain function \n   y = gamma(1.25)^2 * M(-.25;1;-x) / sqrt(x)  \n   which multiplied by xi/(1+xi) is the optimal gain\n   in the loudness domain ( sqrt[amplitude] )\n*/\nstatic inline spx_word32_t hypergeom_gain(spx_word32_t xx)\n{\n   int ind;\n   float integer, frac;\n   float x;\n   static const float table[21] = {\n      0.82157f, 1.02017f, 1.20461f, 1.37534f, 1.53363f, 1.68092f, 1.81865f,\n      1.94811f, 2.07038f, 2.18638f, 2.29688f, 2.40255f, 2.50391f, 2.60144f,\n      2.69551f, 2.78647f, 2.87458f, 2.96015f, 3.04333f, 3.12431f, 3.20326f};\n      x = EXPIN_SCALING_1*xx;\n      integer = floor(2*x);\n      ind = (int)integer;\n      if (ind<0)\n         return FRAC_SCALING;\n      if (ind>19)\n         return FRAC_SCALING*(1+.1296/x);\n      frac = 2*x-integer;\n      return FRAC_SCALING*((1-frac)*table[ind] + frac*table[ind+1])/sqrt(x+.0001f);\n}\n\nstatic inline spx_word16_t qcurve(spx_word16_t x)\n{\n   return 1.f/(1.f+.15f/(SNR_SCALING_1*x));\n}\n\nstatic void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len)\n{\n   int i;\n   float echo_floor;\n   float noise_floor;\n\n   noise_floor = exp(.2302585f*noise_suppress);\n   echo_floor = exp(.2302585f*effective_echo_suppress);\n\n   /* Compute the gain floor based on different floors for the background noise and residual echo */\n   for (i=0;i<len;i++)\n      gain_floor[i] = FRAC_SCALING*sqrt(noise_floor*PSHR32(noise[i],NOISE_SHIFT) + echo_floor*echo[i])/sqrt(1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]);\n}\n\n#endif\nEXPORT SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate)\n{\n   int i;\n   int N, N3, N4, M;\n\n   SpeexPreprocessState *st = (SpeexPreprocessState *)speex_alloc(sizeof(SpeexPreprocessState));\n   st->frame_size = frame_size;\n\n   /* Round ps_size down to the nearest power of two */\n#if 0\n   i=1;\n   st->ps_size = st->frame_size;\n   while(1)\n   {\n      if (st->ps_size & ~i)\n      {\n         st->ps_size &= ~i;\n         i<<=1;\n      } else {\n         break;\n      }\n   }\n   \n   \n   if (st->ps_size < 3*st->frame_size/4)\n      st->ps_size = st->ps_size * 3 / 2;\n#else\n   st->ps_size = st->frame_size;\n#endif\n\n   N = st->ps_size;\n   N3 = 2*N - st->frame_size;\n   N4 = st->frame_size - N3;\n   \n   st->sampling_rate = sampling_rate;\n   st->denoise_enabled = 1;\n   st->vad_enabled = 0;\n   st->dereverb_enabled = 0;\n   st->reverb_decay = 0;\n   st->reverb_level = 0;\n   st->noise_suppress = NOISE_SUPPRESS_DEFAULT;\n   st->echo_suppress = ECHO_SUPPRESS_DEFAULT;\n   st->echo_suppress_active = ECHO_SUPPRESS_ACTIVE_DEFAULT;\n\n   st->speech_prob_start = SPEECH_PROB_START_DEFAULT;\n   st->speech_prob_continue = SPEECH_PROB_CONTINUE_DEFAULT;\n\n   st->echo_state = NULL;\n   \n   st->nbands = NB_BANDS;\n   M = st->nbands;\n   st->bank = filterbank_new(M, sampling_rate, N, 1);\n   \n   st->frame = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t));\n   st->window = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t));\n   st->ft = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t));\n   \n   st->ps = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t));\n   st->noise = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t));\n   st->echo_noise = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t));\n   st->residual_echo = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t));\n   st->reverb_estimate = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t));\n   st->old_ps = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t));\n   st->prior = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t));\n   st->post = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t));\n   st->gain = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t));\n   st->gain2 = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t));\n   st->gain_floor = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t));\n   st->zeta = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t));\n   \n   st->S = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t));\n   st->Smin = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t));\n   st->Stmp = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t));\n   st->update_prob = (int*)speex_alloc(N*sizeof(int));\n   \n   st->inbuf = (spx_word16_t*)speex_alloc(N3*sizeof(spx_word16_t));\n   st->outbuf = (spx_word16_t*)speex_alloc(N3*sizeof(spx_word16_t));\n\n   conj_window(st->window, 2*N3);\n   for (i=2*N3;i<2*st->ps_size;i++)\n      st->window[i]=Q15_ONE;\n   \n   if (N4>0)\n   {\n      for (i=N3-1;i>=0;i--)\n      {\n         st->window[i+N3+N4]=st->window[i+N3];\n         st->window[i+N3]=1;\n      }\n   }\n   for (i=0;i<N+M;i++)\n   {\n      st->noise[i]=QCONST32(1.f,NOISE_SHIFT);\n      st->reverb_estimate[i]=0;\n      st->old_ps[i]=1;\n      st->gain[i]=Q15_ONE;\n      st->post[i]=SHL16(1, SNR_SHIFT);\n      st->prior[i]=SHL16(1, SNR_SHIFT);\n   }\n\n   for (i=0;i<N;i++)\n      st->update_prob[i] = 1;\n   for (i=0;i<N3;i++)\n   {\n      st->inbuf[i]=0;\n      st->outbuf[i]=0;\n   }\n#ifndef FIXED_POINT\n   st->agc_enabled = 0;\n   st->agc_level = 8000;\n   st->loudness_weight = (float*)speex_alloc(N*sizeof(float));\n   for (i=0;i<N;i++)\n   {\n      float ff=((float)i)*.5*sampling_rate/((float)N);\n      /*st->loudness_weight[i] = .5f*(1.f/(1.f+ff/8000.f))+1.f*exp(-.5f*(ff-3800.f)*(ff-3800.f)/9e5f);*/\n      st->loudness_weight[i] = .35f-.35f*ff/16000.f+.73f*exp(-.5f*(ff-3800)*(ff-3800)/9e5f);\n      if (st->loudness_weight[i]<.01f)\n         st->loudness_weight[i]=.01f;\n      st->loudness_weight[i] *= st->loudness_weight[i];\n   }\n   /*st->loudness = pow(AMP_SCALE*st->agc_level,LOUDNESS_EXP);*/\n   st->loudness = 1e-15;\n   st->agc_gain = 1;\n   st->max_gain = 30;\n   st->max_increase_step = exp(0.11513f * 12.*st->frame_size / st->sampling_rate);\n   st->max_decrease_step = exp(-0.11513f * 40.*st->frame_size / st->sampling_rate);\n   st->prev_loudness = 1;\n   st->init_max = 1;\n#endif\n   st->was_speech = 0;\n\n   st->fft_lookup = spx_fft_init(2*N);\n\n   st->nb_adapt=0;\n   st->min_count=0;\n   return st;\n}\n\nEXPORT void speex_preprocess_state_destroy(SpeexPreprocessState *st)\n{\n   speex_free(st->frame);\n   speex_free(st->ft);\n   speex_free(st->ps);\n   speex_free(st->gain2);\n   speex_free(st->gain_floor);\n   speex_free(st->window);\n   speex_free(st->noise);\n   speex_free(st->reverb_estimate);\n   speex_free(st->old_ps);\n   speex_free(st->gain);\n   speex_free(st->prior);\n   speex_free(st->post);\n#ifndef FIXED_POINT\n   speex_free(st->loudness_weight);\n#endif\n   speex_free(st->echo_noise);\n   speex_free(st->residual_echo);\n\n   speex_free(st->S);\n   speex_free(st->Smin);\n   speex_free(st->Stmp);\n   speex_free(st->update_prob);\n   speex_free(st->zeta);\n\n   speex_free(st->inbuf);\n   speex_free(st->outbuf);\n\n   spx_fft_destroy(st->fft_lookup);\n   filterbank_destroy(st->bank);\n   speex_free(st);\n}\n\n/* FIXME: The AGC doesn't work yet with fixed-point*/\n#ifndef FIXED_POINT\nstatic void speex_compute_agc(SpeexPreprocessState *st, spx_word16_t Pframe, spx_word16_t *ft)\n{\n   int i;\n   int N = st->ps_size;\n   float target_gain;\n   float loudness=1.f;\n   float rate;\n   \n   for (i=2;i<N;i++)\n   {\n      loudness += 2.f*N*st->ps[i]* st->loudness_weight[i];\n   }\n   loudness=sqrt(loudness);\n      /*if (loudness < 2*pow(st->loudness, 1.0/LOUDNESS_EXP) &&\n   loudness*2 > pow(st->loudness, 1.0/LOUDNESS_EXP))*/\n   if (Pframe>.3f)\n   {\n      /*rate=2.0f*Pframe*Pframe/(1+st->nb_loudness_adapt);*/\n      rate = .03*Pframe*Pframe;\n      st->loudness = (1-rate)*st->loudness + (rate)*pow(AMP_SCALE*loudness, LOUDNESS_EXP);\n      st->loudness_accum = (1-rate)*st->loudness_accum + rate;\n      if (st->init_max < st->max_gain && st->nb_adapt > 20)\n         st->init_max *= 1.f + .1f*Pframe*Pframe;\n   }\n   /*printf (\"%f %f %f %f\\n\", Pframe, loudness, pow(st->loudness, 1.0f/LOUDNESS_EXP), st->loudness2);*/\n   \n   target_gain = AMP_SCALE*st->agc_level*pow(st->loudness/(1e-4+st->loudness_accum), -1.0f/LOUDNESS_EXP);\n\n   if ((Pframe>.5  && st->nb_adapt > 20) || target_gain < st->agc_gain)\n   {\n      if (target_gain > st->max_increase_step*st->agc_gain)\n         target_gain = st->max_increase_step*st->agc_gain;\n      if (target_gain < st->max_decrease_step*st->agc_gain && loudness < 10*st->prev_loudness)\n         target_gain = st->max_decrease_step*st->agc_gain;\n      if (target_gain > st->max_gain)\n         target_gain = st->max_gain;\n      if (target_gain > st->init_max)\n         target_gain = st->init_max;\n   \n      st->agc_gain = target_gain;\n   }\n   /*fprintf (stderr, \"%f %f %f\\n\", loudness, (float)AMP_SCALE_1*pow(st->loudness, 1.0f/LOUDNESS_EXP), st->agc_gain);*/\n      \n   for (i=0;i<2*N;i++)\n      ft[i] *= st->agc_gain;\n   st->prev_loudness = loudness;\n}\n#endif\n\nstatic void preprocess_analysis(SpeexPreprocessState *st, spx_int16_t *x)\n{\n   int i;\n   int N = st->ps_size;\n   int N3 = 2*N - st->frame_size;\n   int N4 = st->frame_size - N3;\n   spx_word32_t *ps=st->ps;\n\n   /* 'Build' input frame */\n   for (i=0;i<N3;i++)\n      st->frame[i]=st->inbuf[i];\n   for (i=0;i<st->frame_size;i++)\n      st->frame[N3+i]=x[i];\n   \n   /* Update inbuf */\n   for (i=0;i<N3;i++)\n      st->inbuf[i]=x[N4+i];\n\n   /* Windowing */\n   for (i=0;i<2*N;i++)\n      st->frame[i] = MULT16_16_Q15(st->frame[i], st->window[i]);\n\n#ifdef FIXED_POINT\n   {\n      spx_word16_t max_val=0;\n      for (i=0;i<2*N;i++)\n         max_val = MAX16(max_val, ABS16(st->frame[i]));\n      st->frame_shift = 14-spx_ilog2(EXTEND32(max_val));\n      for (i=0;i<2*N;i++)\n         st->frame[i] = SHL16(st->frame[i], st->frame_shift);\n   }\n#endif\n   \n   /* Perform FFT */\n   spx_fft(st->fft_lookup, st->frame, st->ft);\n         \n   /* Power spectrum */\n   ps[0]=MULT16_16(st->ft[0],st->ft[0]);\n   for (i=1;i<N;i++)\n      ps[i]=MULT16_16(st->ft[2*i-1],st->ft[2*i-1]) + MULT16_16(st->ft[2*i],st->ft[2*i]);\n   for (i=0;i<N;i++)\n      st->ps[i] = PSHR32(st->ps[i], 2*st->frame_shift);\n\n   filterbank_compute_bank32(st->bank, ps, ps+N);\n}\n\nstatic void update_noise_prob(SpeexPreprocessState *st)\n{\n   int i;\n   int min_range;\n   int N = st->ps_size;\n\n   for (i=1;i<N-1;i++)\n      st->S[i] =  MULT16_32_Q15(QCONST16(.8f,15),st->S[i]) + MULT16_32_Q15(QCONST16(.05f,15),st->ps[i-1]) \n                      + MULT16_32_Q15(QCONST16(.1f,15),st->ps[i]) + MULT16_32_Q15(QCONST16(.05f,15),st->ps[i+1]);\n   st->S[0] =  MULT16_32_Q15(QCONST16(.8f,15),st->S[0]) + MULT16_32_Q15(QCONST16(.2f,15),st->ps[0]);\n   st->S[N-1] =  MULT16_32_Q15(QCONST16(.8f,15),st->S[N-1]) + MULT16_32_Q15(QCONST16(.2f,15),st->ps[N-1]);\n   \n   if (st->nb_adapt==1)\n   {\n      for (i=0;i<N;i++)\n         st->Smin[i] = st->Stmp[i] = 0;\n   }\n\n   if (st->nb_adapt < 100)\n      min_range = 15;\n   else if (st->nb_adapt < 1000)\n      min_range = 50;\n   else if (st->nb_adapt < 10000)\n      min_range = 150;\n   else\n      min_range = 300;\n   if (st->min_count > min_range)\n   {\n      st->min_count = 0;\n      for (i=0;i<N;i++)\n      {\n         st->Smin[i] = MIN32(st->Stmp[i], st->S[i]);\n         st->Stmp[i] = st->S[i];\n      }\n   } else {\n      for (i=0;i<N;i++)\n      {\n         st->Smin[i] = MIN32(st->Smin[i], st->S[i]);\n         st->Stmp[i] = MIN32(st->Stmp[i], st->S[i]);      \n      }\n   }\n   for (i=0;i<N;i++)\n   {\n      if (MULT16_32_Q15(QCONST16(.4f,15),st->S[i]) > st->Smin[i])\n         st->update_prob[i] = 1;\n      else\n         st->update_prob[i] = 0;\n      /*fprintf (stderr, \"%f \", st->S[i]/st->Smin[i]);*/\n      /*fprintf (stderr, \"%f \", st->update_prob[i]);*/\n   }\n\n}\n\n#define NOISE_OVERCOMPENS 1.\n\nvoid speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len);\n\nEXPORT int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo)\n{\n   return speex_preprocess_run(st, x);\n}\n\nEXPORT int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x)\n{\n   int i;\n   int M;\n   int N = st->ps_size;\n   int N3 = 2*N - st->frame_size;\n   int N4 = st->frame_size - N3;\n   spx_word32_t *ps=st->ps;\n   spx_word32_t Zframe;\n   spx_word16_t Pframe;\n   spx_word16_t beta, beta_1;\n   spx_word16_t effective_echo_suppress;\n   \n   st->nb_adapt++;\n   if (st->nb_adapt>20000)\n      st->nb_adapt = 20000;\n   st->min_count++;\n   \n   beta = MAX16(QCONST16(.03,15),DIV32_16(Q15_ONE,st->nb_adapt));\n   beta_1 = Q15_ONE-beta;\n   M = st->nbands;\n   /* Deal with residual echo if provided */\n   if (st->echo_state)\n   {\n      speex_echo_get_residual(st->echo_state, st->residual_echo, N);\n#ifndef FIXED_POINT\n      /* If there are NaNs or ridiculous values, it'll show up in the DC and we just reset everything to zero */\n      if (!(st->residual_echo[0] >=0 && st->residual_echo[0]<N*1e9f))\n      {\n         for (i=0;i<N;i++)\n            st->residual_echo[i] = 0;\n      }\n#endif\n      for (i=0;i<N;i++)\n         st->echo_noise[i] = MAX32(MULT16_32_Q15(QCONST16(.6f,15),st->echo_noise[i]), st->residual_echo[i]);\n      filterbank_compute_bank32(st->bank, st->echo_noise, st->echo_noise+N);\n   } else {\n      for (i=0;i<N+M;i++)\n         st->echo_noise[i] = 0;\n   }\n   preprocess_analysis(st, x);\n\n   update_noise_prob(st);\n\n   /* Noise estimation always updated for the 10 first frames */\n   /*if (st->nb_adapt<10)\n   {\n      for (i=1;i<N-1;i++)\n         st->update_prob[i] = 0;\n   }\n   */\n   \n   /* Update the noise estimate for the frequencies where it can be */\n   for (i=0;i<N;i++)\n   {\n      if (!st->update_prob[i] || st->ps[i] < PSHR32(st->noise[i], NOISE_SHIFT))\n         st->noise[i] = MAX32(EXTEND32(0),MULT16_32_Q15(beta_1,st->noise[i]) + MULT16_32_Q15(beta,SHL32(st->ps[i],NOISE_SHIFT)));\n   }\n   filterbank_compute_bank32(st->bank, st->noise, st->noise+N);\n\n   /* Special case for first frame */\n   if (st->nb_adapt==1)\n      for (i=0;i<N+M;i++)\n         st->old_ps[i] = ps[i];\n\n   /* Compute a posteriori SNR */\n   for (i=0;i<N+M;i++)\n   {\n      spx_word16_t gamma;\n      \n      /* Total noise estimate including residual echo and reverberation */\n      spx_word32_t tot_noise = ADD32(ADD32(ADD32(EXTEND32(1), PSHR32(st->noise[i],NOISE_SHIFT)) , st->echo_noise[i]) , st->reverb_estimate[i]);\n      \n      /* A posteriori SNR = ps/noise - 1*/\n      st->post[i] = SUB16(DIV32_16_Q8(ps[i],tot_noise), QCONST16(1.f,SNR_SHIFT));\n      st->post[i]=MIN16(st->post[i], QCONST16(100.f,SNR_SHIFT));\n      \n      /* Computing update gamma = .1 + .9*(old/(old+noise))^2 */\n      gamma = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.89f,15),SQR16_Q15(DIV32_16_Q15(st->old_ps[i],ADD32(st->old_ps[i],tot_noise))));\n      \n      /* A priori SNR update = gamma*max(0,post) + (1-gamma)*old/noise */\n      st->prior[i] = EXTRACT16(PSHR32(ADD32(MULT16_16(gamma,MAX16(0,st->post[i])), MULT16_16(Q15_ONE-gamma,DIV32_16_Q8(st->old_ps[i],tot_noise))), 15));\n      st->prior[i]=MIN16(st->prior[i], QCONST16(100.f,SNR_SHIFT));\n   }\n\n   /*print_vec(st->post, N+M, \"\");*/\n\n   /* Recursive average of the a priori SNR. A bit smoothed for the psd components */\n   st->zeta[0] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[0]), MULT16_16(QCONST16(.3f,15),st->prior[0])),15);\n   for (i=1;i<N-1;i++)\n      st->zeta[i] = PSHR32(ADD32(ADD32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[i]), MULT16_16(QCONST16(.15f,15),st->prior[i])),\n                           MULT16_16(QCONST16(.075f,15),st->prior[i-1])), MULT16_16(QCONST16(.075f,15),st->prior[i+1])),15);\n   for (i=N-1;i<N+M;i++)\n      st->zeta[i] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[i]), MULT16_16(QCONST16(.3f,15),st->prior[i])),15);\n\n   /* Speech probability of presence for the entire frame is based on the average filterbank a priori SNR */\n   Zframe = 0;\n   for (i=N;i<N+M;i++)\n      Zframe = ADD32(Zframe, EXTEND32(st->zeta[i]));\n   Pframe = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.899f,15),qcurve(DIV32_16(Zframe,st->nbands)));\n   \n   effective_echo_suppress = EXTRACT16(PSHR32(ADD32(MULT16_16(SUB16(Q15_ONE,Pframe), st->echo_suppress), MULT16_16(Pframe, st->echo_suppress_active)),15));\n   \n   compute_gain_floor(st->noise_suppress, effective_echo_suppress, st->noise+N, st->echo_noise+N, st->gain_floor+N, M);\n         \n   /* Compute Ephraim & Malah gain speech probability of presence for each critical band (Bark scale) \n      Technically this is actually wrong because the EM gaim assumes a slightly different probability \n      distribution */\n   for (i=N;i<N+M;i++)\n   {\n      /* See EM and Cohen papers*/\n      spx_word32_t theta;\n      /* Gain from hypergeometric function */\n      spx_word32_t MM;\n      /* Weiner filter gain */\n      spx_word16_t prior_ratio;\n      /* a priority probability of speech presence based on Bark sub-band alone */\n      spx_word16_t P1;\n      /* Speech absence a priori probability (considering sub-band and frame) */\n      spx_word16_t q;\n#ifdef FIXED_POINT\n      spx_word16_t tmp;\n#endif\n      \n      prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT)));\n      theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT));\n\n      MM = hypergeom_gain(theta);\n      /* Gain with bound */\n      st->gain[i] = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM)));\n      /* Save old Bark power spectrum */\n      st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]);\n\n      P1 = QCONST16(.199f,15)+MULT16_16_Q15(QCONST16(.8f,15),qcurve (st->zeta[i]));\n      q = Q15_ONE-MULT16_16_Q15(Pframe,P1);\n#ifdef FIXED_POINT\n      theta = MIN32(theta, EXTEND32(32767));\n/*Q8*/tmp = MULT16_16_Q15((SHL32(1,SNR_SHIFT)+st->prior[i]),EXTRACT16(MIN32(Q15ONE,SHR32(spx_exp(-EXTRACT16(theta)),1))));\n      tmp = MIN16(QCONST16(3.,SNR_SHIFT), tmp); /* Prevent overflows in the next line*/\n/*Q8*/tmp = EXTRACT16(PSHR32(MULT16_16(PDIV32_16(SHL32(EXTEND32(q),8),(Q15_ONE-q)),tmp),8));\n      st->gain2[i]=DIV32_16(SHL32(EXTEND32(32767),SNR_SHIFT), ADD16(256,tmp));\n#else\n      st->gain2[i]=1/(1.f + (q/(1.f-q))*(1+st->prior[i])*exp(-theta));\n#endif\n   }\n   /* Convert the EM gains and speech prob to linear frequency */\n   filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2);\n   filterbank_compute_psd16(st->bank,st->gain+N, st->gain);\n   \n   /* Use 1 for linear gain resolution (best) or 0 for Bark gain resolution (faster) */\n   if (1)\n   {\n      filterbank_compute_psd16(st->bank,st->gain_floor+N, st->gain_floor);\n   \n      /* Compute gain according to the Ephraim-Malah algorithm -- linear frequency */\n      for (i=0;i<N;i++)\n      {\n         spx_word32_t MM;\n         spx_word32_t theta;\n         spx_word16_t prior_ratio;\n         spx_word16_t tmp;\n         spx_word16_t p;\n         spx_word16_t g;\n         \n         /* Wiener filter gain */\n         prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT)));\n         theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT));\n\n         /* Optimal estimator for loudness domain */\n         MM = hypergeom_gain(theta);\n         /* EM gain with bound */\n         g = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM)));\n         /* Interpolated speech probability of presence */\n         p = st->gain2[i];\n                  \n         /* Constrain the gain to be close to the Bark scale gain */\n         if (MULT16_16_Q15(QCONST16(.333f,15),g) > st->gain[i])\n            g = MULT16_16(3,st->gain[i]);\n         st->gain[i] = g;\n         \n         /* Save old power spectrum */\n         st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]);\n         \n         /* Apply gain floor */\n         if (st->gain[i] < st->gain_floor[i])\n            st->gain[i] = st->gain_floor[i];\n\n         /* Exponential decay model for reverberation (unused) */\n         /*st->reverb_estimate[i] = st->reverb_decay*st->reverb_estimate[i] + st->reverb_decay*st->reverb_level*st->gain[i]*st->gain[i]*st->ps[i];*/\n         \n         /* Take into account speech probability of presence (loudness domain MMSE estimator) */\n         /* gain2 = [p*sqrt(gain)+(1-p)*sqrt(gain _floor) ]^2 */\n         tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15)));\n         st->gain2[i]=SQR16_Q15(tmp);\n\n         /* Use this if you want a log-domain MMSE estimator instead */\n         /*st->gain2[i] = pow(st->gain[i], p) * pow(st->gain_floor[i],1.f-p);*/\n      }\n   } else {\n      for (i=N;i<N+M;i++)\n      {\n         spx_word16_t tmp;\n         spx_word16_t p = st->gain2[i];\n         st->gain[i] = MAX16(st->gain[i], st->gain_floor[i]);         \n         tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15)));\n         st->gain2[i]=SQR16_Q15(tmp);\n      }\n      filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2);\n   }\n   \n   /* If noise suppression is off, don't apply the gain (but then why call this in the first place!) */\n   if (!st->denoise_enabled)\n   {\n      for (i=0;i<N+M;i++)\n         st->gain2[i]=Q15_ONE;\n   }\n      \n   /* Apply computed gain */\n   for (i=1;i<N;i++)\n   {\n      st->ft[2*i-1] = MULT16_16_P15(st->gain2[i],st->ft[2*i-1]);\n      st->ft[2*i] = MULT16_16_P15(st->gain2[i],st->ft[2*i]);\n   }\n   st->ft[0] = MULT16_16_P15(st->gain2[0],st->ft[0]);\n   st->ft[2*N-1] = MULT16_16_P15(st->gain2[N-1],st->ft[2*N-1]);\n   \n   /*FIXME: This *will* not work for fixed-point */\n#ifndef FIXED_POINT\n   if (st->agc_enabled)\n      speex_compute_agc(st, Pframe, st->ft);\n#endif\n\n   /* Inverse FFT with 1/N scaling */\n   spx_ifft(st->fft_lookup, st->ft, st->frame);\n   /* Scale back to original (lower) amplitude */\n   for (i=0;i<2*N;i++)\n      st->frame[i] = PSHR16(st->frame[i], st->frame_shift);\n\n   /*FIXME: This *will* not work for fixed-point */\n#ifndef FIXED_POINT\n   if (st->agc_enabled)\n   {\n      float max_sample=0;\n      for (i=0;i<2*N;i++)\n         if (fabs(st->frame[i])>max_sample)\n            max_sample = fabs(st->frame[i]);\n      if (max_sample>28000.f)\n      {\n         float damp = 28000.f/max_sample;\n         for (i=0;i<2*N;i++)\n            st->frame[i] *= damp;\n      }\n   }\n#endif\n   \n   /* Synthesis window (for WOLA) */\n   for (i=0;i<2*N;i++)\n      st->frame[i] = MULT16_16_Q15(st->frame[i], st->window[i]);\n\n   /* Perform overlap and add */\n   for (i=0;i<N3;i++)\n      x[i] = st->outbuf[i] + st->frame[i];\n   for (i=0;i<N4;i++)\n      x[N3+i] = st->frame[N3+i];\n   \n   /* Update outbuf */\n   for (i=0;i<N3;i++)\n      st->outbuf[i] = st->frame[st->frame_size+i];\n\n   /* FIXME: This VAD is a kludge */\n   st->speech_prob = Pframe;\n   if (st->vad_enabled)\n   {\n      if (st->speech_prob > st->speech_prob_start || (st->was_speech && st->speech_prob > st->speech_prob_continue))\n      {\n         st->was_speech=1;\n         return 1;\n      } else\n      {\n         st->was_speech=0;\n         return 0;\n      }\n   } else {\n      return 1;\n   }\n}\n\nEXPORT void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x)\n{\n   int i;\n   int N = st->ps_size;\n   int N3 = 2*N - st->frame_size;\n   int M;\n   spx_word32_t *ps=st->ps;\n\n   M = st->nbands;\n   st->min_count++;\n   \n   preprocess_analysis(st, x);\n\n   update_noise_prob(st);\n   \n   for (i=1;i<N-1;i++)\n   {\n      if (!st->update_prob[i] || st->ps[i] < PSHR32(st->noise[i],NOISE_SHIFT))\n      {\n         st->noise[i] = MULT16_32_Q15(QCONST16(.95f,15),st->noise[i]) + MULT16_32_Q15(QCONST16(.05f,15),SHL32(st->ps[i],NOISE_SHIFT));\n      }\n   }\n\n   for (i=0;i<N3;i++)\n      st->outbuf[i] = MULT16_16_Q15(x[st->frame_size-N3+i],st->window[st->frame_size+i]);\n\n   /* Save old power spectrum */\n   for (i=0;i<N+M;i++)\n      st->old_ps[i] = ps[i];\n\n   for (i=0;i<N;i++)\n      st->reverb_estimate[i] = MULT16_32_Q15(st->reverb_decay, st->reverb_estimate[i]);\n}\n\n\nEXPORT int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr)\n{\n   int i;\n   SpeexPreprocessState *st;\n   st=(SpeexPreprocessState*)state;\n   switch(request)\n   {\n   case SPEEX_PREPROCESS_SET_DENOISE:\n      st->denoise_enabled = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_PREPROCESS_GET_DENOISE:\n      (*(spx_int32_t*)ptr) = st->denoise_enabled;\n      break;\n#ifndef FIXED_POINT\n   case SPEEX_PREPROCESS_SET_AGC:\n      st->agc_enabled = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_PREPROCESS_GET_AGC:\n      (*(spx_int32_t*)ptr) = st->agc_enabled;\n      break;\n#ifndef DISABLE_FLOAT_API\n   case SPEEX_PREPROCESS_SET_AGC_LEVEL:\n      st->agc_level = (*(float*)ptr);\n      if (st->agc_level<1)\n         st->agc_level=1;\n      if (st->agc_level>32768)\n         st->agc_level=32768;\n      break;\n   case SPEEX_PREPROCESS_GET_AGC_LEVEL:\n      (*(float*)ptr) = st->agc_level;\n      break;\n#endif /* #ifndef DISABLE_FLOAT_API */\n   case SPEEX_PREPROCESS_SET_AGC_INCREMENT:\n      st->max_increase_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate);\n      break;\n   case SPEEX_PREPROCESS_GET_AGC_INCREMENT:\n      (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_increase_step)*st->sampling_rate/st->frame_size);\n      break;\n   case SPEEX_PREPROCESS_SET_AGC_DECREMENT:\n      st->max_decrease_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate);\n      break;\n   case SPEEX_PREPROCESS_GET_AGC_DECREMENT:\n      (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_decrease_step)*st->sampling_rate/st->frame_size);\n      break;\n   case SPEEX_PREPROCESS_SET_AGC_MAX_GAIN:\n      st->max_gain = exp(0.11513f * (*(spx_int32_t*)ptr));\n      break;\n   case SPEEX_PREPROCESS_GET_AGC_MAX_GAIN:\n      (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_gain));\n      break;\n#endif\n   case SPEEX_PREPROCESS_SET_VAD:\n      speex_warning(\"The VAD has been replaced by a hack pending a complete rewrite\");\n      st->vad_enabled = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_PREPROCESS_GET_VAD:\n      (*(spx_int32_t*)ptr) = st->vad_enabled;\n      break;\n   \n   case SPEEX_PREPROCESS_SET_DEREVERB:\n      st->dereverb_enabled = (*(spx_int32_t*)ptr);\n      for (i=0;i<st->ps_size;i++)\n         st->reverb_estimate[i]=0;\n      break;\n   case SPEEX_PREPROCESS_GET_DEREVERB:\n      (*(spx_int32_t*)ptr) = st->dereverb_enabled;\n      break;\n\n   case SPEEX_PREPROCESS_SET_DEREVERB_LEVEL:\n      /* FIXME: Re-enable when de-reverberation is actually enabled again */\n      /*st->reverb_level = (*(float*)ptr);*/\n      break;\n   case SPEEX_PREPROCESS_GET_DEREVERB_LEVEL:\n      /* FIXME: Re-enable when de-reverberation is actually enabled again */\n      /*(*(float*)ptr) = st->reverb_level;*/\n      break;\n   \n   case SPEEX_PREPROCESS_SET_DEREVERB_DECAY:\n      /* FIXME: Re-enable when de-reverberation is actually enabled again */\n      /*st->reverb_decay = (*(float*)ptr);*/\n      break;\n   case SPEEX_PREPROCESS_GET_DEREVERB_DECAY:\n      /* FIXME: Re-enable when de-reverberation is actually enabled again */\n      /*(*(float*)ptr) = st->reverb_decay;*/\n      break;\n\n   case SPEEX_PREPROCESS_SET_PROB_START:\n      *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr));\n      st->speech_prob_start = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100);\n      break;\n   case SPEEX_PREPROCESS_GET_PROB_START:\n      (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_start, 100);\n      break;\n\n   case SPEEX_PREPROCESS_SET_PROB_CONTINUE:\n      *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr));\n      st->speech_prob_continue = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100);\n      break;\n   case SPEEX_PREPROCESS_GET_PROB_CONTINUE:\n      (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_continue, 100);\n      break;\n\n   case SPEEX_PREPROCESS_SET_NOISE_SUPPRESS:\n      st->noise_suppress = -ABS(*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_PREPROCESS_GET_NOISE_SUPPRESS:\n      (*(spx_int32_t*)ptr) = st->noise_suppress;\n      break;\n   case SPEEX_PREPROCESS_SET_ECHO_SUPPRESS:\n      st->echo_suppress = -ABS(*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_PREPROCESS_GET_ECHO_SUPPRESS:\n      (*(spx_int32_t*)ptr) = st->echo_suppress;\n      break;\n   case SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE:\n      st->echo_suppress_active = -ABS(*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE:\n      (*(spx_int32_t*)ptr) = st->echo_suppress_active;\n      break;\n   case SPEEX_PREPROCESS_SET_ECHO_STATE:\n      st->echo_state = (SpeexEchoState*)ptr;\n      break;\n   case SPEEX_PREPROCESS_GET_ECHO_STATE:\n      (*(SpeexEchoState**)ptr) = (SpeexEchoState*)st->echo_state;\n      break;\n#ifndef FIXED_POINT\n   case SPEEX_PREPROCESS_GET_AGC_LOUDNESS:\n      (*(spx_int32_t*)ptr) = pow(st->loudness, 1.0/LOUDNESS_EXP);\n      break;\n   case SPEEX_PREPROCESS_GET_AGC_GAIN:\n      (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->agc_gain));\n      break;\n#endif\n   case SPEEX_PREPROCESS_GET_PSD_SIZE:\n   case SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE:\n      (*(spx_int32_t*)ptr) = st->ps_size;\n      break;\n   case SPEEX_PREPROCESS_GET_PSD:\n      for(i=0;i<st->ps_size;i++)\n      \t((spx_int32_t *)ptr)[i] = (spx_int32_t) st->ps[i];\n      break;\n   case SPEEX_PREPROCESS_GET_NOISE_PSD:\n      for(i=0;i<st->ps_size;i++)\n      \t((spx_int32_t *)ptr)[i] = (spx_int32_t) PSHR32(st->noise[i], NOISE_SHIFT);\n      break;\n   case SPEEX_PREPROCESS_GET_PROB:\n      (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob, 100);\n      break;\n#ifndef FIXED_POINT\n   case SPEEX_PREPROCESS_SET_AGC_TARGET:\n      st->agc_level = (*(spx_int32_t*)ptr);\n      if (st->agc_level<1)\n         st->agc_level=1;\n      if (st->agc_level>32768)\n         st->agc_level=32768;\n      break;\n   case SPEEX_PREPROCESS_GET_AGC_TARGET:\n      (*(spx_int32_t*)ptr) = st->agc_level;\n      break;\n#endif\n   default:\n      speex_warning_int(\"Unknown speex_preprocess_ctl request: \", request);\n      return -1;\n   }\n   return 0;\n}\n\n#ifdef FIXED_DEBUG\nlong long spx_mips=0;\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/pseudofloat.h",
    "content": "/* Copyright (C) 2005 Jean-Marc Valin */\n/**\n   @file pseudofloat.h\n   @brief Pseudo-floating point\n * This header file provides a lightweight floating point type for\n * use on fixed-point platforms when a large dynamic range is \n * required. The new type is not compatible with the 32-bit IEEE format,\n * it is not even remotely as accurate as 32-bit floats, and is not\n * even guaranteed to produce even remotely correct results for code\n * other than Speex. It makes all kinds of shortcuts that are acceptable\n * for Speex, but may not be acceptable for your application. You're\n * quite welcome to reuse this code and improve it, but don't assume\n * it works out of the box. Most likely, it doesn't.\n */\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef PSEUDOFLOAT_H\n#define PSEUDOFLOAT_H\n\n#include \"arch.h\"\n#include \"os_support.h\"\n#include \"math_approx.h\"\n#include <math.h>\n\n#ifdef FIXED_POINT\n\ntypedef struct {\n   spx_int16_t m;\n   spx_int16_t e;\n} spx_float_t;\n\nstatic const spx_float_t FLOAT_ZERO = {0,0};\nstatic const spx_float_t FLOAT_ONE = {16384,-14};\nstatic const spx_float_t FLOAT_HALF = {16384,-15};\n\n#define MIN(a,b) ((a)<(b)?(a):(b))\nstatic inline spx_float_t PSEUDOFLOAT(spx_int32_t x)\n{\n   int e=0;\n   int sign=0;\n   if (x<0)\n   {\n      sign = 1;\n      x = -x;\n   }\n   if (x==0)\n   {\n      spx_float_t r = {0,0};\n      return r;\n   }\n   e = spx_ilog2(ABS32(x))-14;\n   x = VSHR32(x, e);\n   if (sign)\n   {\n      spx_float_t r;\n      r.m = -x;\n      r.e = e;\n      return r;\n   }\n   else      \n   {\n      spx_float_t r;\n      r.m = x;\n      r.e = e;\n      return r;\n   }\n}\n\n\nstatic inline spx_float_t FLOAT_ADD(spx_float_t a, spx_float_t b)\n{\n   spx_float_t r;\n   if (a.m==0)\n      return b;\n   else if (b.m==0)\n      return a;\n   if ((a).e > (b).e) \n   {\n      r.m = ((a).m>>1) + ((b).m>>MIN(15,(a).e-(b).e+1));\n      r.e = (a).e+1;\n   }\n   else \n   {\n      r.m = ((b).m>>1) + ((a).m>>MIN(15,(b).e-(a).e+1));\n      r.e = (b).e+1;\n   }\n   if (r.m>0)\n   {\n      if (r.m<16384)\n      {\n         r.m<<=1;\n         r.e-=1;\n      }\n   } else {\n      if (r.m>-16384)\n      {\n         r.m<<=1;\n         r.e-=1;\n      }\n   }\n   /*printf (\"%f + %f = %f\\n\", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/\n   return r;\n}\n\nstatic inline spx_float_t FLOAT_SUB(spx_float_t a, spx_float_t b)\n{\n   spx_float_t r;\n   if (a.m==0)\n      return b;\n   else if (b.m==0)\n      return a;\n   if ((a).e > (b).e)\n   {\n      r.m = ((a).m>>1) - ((b).m>>MIN(15,(a).e-(b).e+1));\n      r.e = (a).e+1;\n   }\n   else \n   {\n      r.m = ((a).m>>MIN(15,(b).e-(a).e+1)) - ((b).m>>1);\n      r.e = (b).e+1;\n   }\n   if (r.m>0)\n   {\n      if (r.m<16384)\n      {\n         r.m<<=1;\n         r.e-=1;\n      }\n   } else {\n      if (r.m>-16384)\n      {\n         r.m<<=1;\n         r.e-=1;\n      }\n   }\n   /*printf (\"%f + %f = %f\\n\", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/\n   return r;\n}\n\nstatic inline int FLOAT_LT(spx_float_t a, spx_float_t b)\n{\n   if (a.m==0)\n      return b.m>0;\n   else if (b.m==0)\n      return a.m<0;   \n   if ((a).e > (b).e)\n      return ((a).m>>1) < ((b).m>>MIN(15,(a).e-(b).e+1));\n   else \n      return ((b).m>>1) > ((a).m>>MIN(15,(b).e-(a).e+1));\n\n}\n\nstatic inline int FLOAT_GT(spx_float_t a, spx_float_t b)\n{\n   return FLOAT_LT(b,a);\n}\n\nstatic inline spx_float_t FLOAT_MULT(spx_float_t a, spx_float_t b)\n{\n   spx_float_t r;\n   r.m = (spx_int16_t)((spx_int32_t)(a).m*(b).m>>15);\n   r.e = (a).e+(b).e+15;\n   if (r.m>0)\n   {\n      if (r.m<16384)\n      {\n         r.m<<=1;\n         r.e-=1;\n      }\n   } else {\n      if (r.m>-16384)\n      {\n         r.m<<=1;\n         r.e-=1;\n      }\n   }\n   /*printf (\"%f * %f = %f\\n\", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/\n   return r;   \n}\n\nstatic inline spx_float_t FLOAT_AMULT(spx_float_t a, spx_float_t b)\n{\n   spx_float_t r;\n   r.m = (spx_int16_t)((spx_int32_t)(a).m*(b).m>>15);\n   r.e = (a).e+(b).e+15;\n   return r;   \n}\n\n\nstatic inline spx_float_t FLOAT_SHL(spx_float_t a, int b)\n{\n   spx_float_t r;\n   r.m = a.m;\n   r.e = a.e+b;\n   return r;\n}\n\nstatic inline spx_int16_t FLOAT_EXTRACT16(spx_float_t a)\n{\n   if (a.e<0)\n      return EXTRACT16((EXTEND32(a.m)+(EXTEND32(1)<<(-a.e-1)))>>-a.e);\n   else\n      return a.m<<a.e;\n}\n\nstatic inline spx_int32_t FLOAT_EXTRACT32(spx_float_t a)\n{\n   if (a.e<0)\n      return (EXTEND32(a.m)+(EXTEND32(1)<<(-a.e-1)))>>-a.e;\n   else\n      return EXTEND32(a.m)<<a.e;\n}\n\nstatic inline spx_int32_t FLOAT_MUL32(spx_float_t a, spx_word32_t b)\n{\n   return VSHR32(MULT16_32_Q15(a.m, b),-a.e-15);\n}\n\nstatic inline spx_float_t FLOAT_MUL32U(spx_word32_t a, spx_word32_t b)\n{\n   int e1, e2;\n   spx_float_t r;\n   if (a==0 || b==0)\n   {\n      return FLOAT_ZERO;\n   }\n   e1 = spx_ilog2(ABS32(a));\n   a = VSHR32(a, e1-14);\n   e2 = spx_ilog2(ABS32(b));\n   b = VSHR32(b, e2-14);\n   r.m = MULT16_16_Q15(a,b);\n   r.e = e1+e2-13;\n   return r;\n}\n\n/* Do NOT attempt to divide by a negative number */\nstatic inline spx_float_t FLOAT_DIV32_FLOAT(spx_word32_t a, spx_float_t b)\n{\n   int e=0;\n   spx_float_t r;\n   if (a==0)\n   {\n      return FLOAT_ZERO;\n   }\n   e = spx_ilog2(ABS32(a))-spx_ilog2(b.m-1)-15;\n   a = VSHR32(a, e);\n   if (ABS32(a)>=SHL32(EXTEND32(b.m-1),15))\n   {\n      a >>= 1;\n      e++;\n   }\n   r.m = DIV32_16(a,b.m);\n   r.e = e-b.e;\n   return r;\n}\n\n\n/* Do NOT attempt to divide by a negative number */\nstatic inline spx_float_t FLOAT_DIV32(spx_word32_t a, spx_word32_t b)\n{\n   int e0=0,e=0;\n   spx_float_t r;\n   if (a==0)\n   {\n      return FLOAT_ZERO;\n   }\n   if (b>32767)\n   {\n      e0 = spx_ilog2(b)-14;\n      b = VSHR32(b, e0);\n      e0 = -e0;\n   }\n   e = spx_ilog2(ABS32(a))-spx_ilog2(b-1)-15;\n   a = VSHR32(a, e);\n   if (ABS32(a)>=SHL32(EXTEND32(b-1),15))\n   {\n      a >>= 1;\n      e++;\n   }\n   e += e0;\n   r.m = DIV32_16(a,b);\n   r.e = e;\n   return r;\n}\n\n/* Do NOT attempt to divide by a negative number */\nstatic inline spx_float_t FLOAT_DIVU(spx_float_t a, spx_float_t b)\n{\n   int e=0;\n   spx_int32_t num;\n   spx_float_t r;\n   if (b.m<=0)\n   {\n      speex_warning_int(\"Attempted to divide by\", b.m);\n      return FLOAT_ONE;\n   }\n   num = a.m;\n   a.m = ABS16(a.m);\n   while (a.m >= b.m)\n   {\n      e++;\n      a.m >>= 1;\n   }\n   num = num << (15-e);\n   r.m = DIV32_16(num,b.m);\n   r.e = a.e-b.e-15+e;\n   return r;\n}\n\nstatic inline spx_float_t FLOAT_SQRT(spx_float_t a)\n{\n   spx_float_t r;\n   spx_int32_t m;\n   m = SHL32(EXTEND32(a.m), 14);\n   r.e = a.e - 14;\n   if (r.e & 1)\n   {\n      r.e -= 1;\n      m <<= 1;\n   }\n   r.e >>= 1;\n   r.m = spx_sqrt(m);\n   return r;\n}\n\n#else\n\n#define spx_float_t float\n#define FLOAT_ZERO 0.f\n#define FLOAT_ONE 1.f\n#define FLOAT_HALF 0.5f\n#define PSEUDOFLOAT(x) (x)\n#define FLOAT_MULT(a,b) ((a)*(b))\n#define FLOAT_AMULT(a,b) ((a)*(b))\n#define FLOAT_MUL32(a,b) ((a)*(b))\n#define FLOAT_DIV32(a,b) ((a)/(b))\n#define FLOAT_EXTRACT16(a) (a)\n#define FLOAT_EXTRACT32(a) (a)\n#define FLOAT_ADD(a,b) ((a)+(b))\n#define FLOAT_SUB(a,b) ((a)-(b))\n#define REALFLOAT(x) (x)\n#define FLOAT_DIV32_FLOAT(a,b) ((a)/(b))\n#define FLOAT_MUL32U(a,b) ((a)*(b))\n#define FLOAT_SHL(a,b) (a)\n#define FLOAT_LT(a,b) ((a)<(b))\n#define FLOAT_GT(a,b) ((a)>(b))\n#define FLOAT_DIVU(a,b) ((a)/(b))\n#define FLOAT_SQRT(a) (spx_sqrt(a))\n\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/quant_lsp.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: quant_lsp.c\n   LSP vector quantization\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"quant_lsp.h\"\n#include \"os_support.h\"\n#include <math.h>\n#ifndef M_PI\n#define M_PI 3.14159265358979323846\n#endif\n\n#include \"arch.h\"\n\n#ifdef BFIN_ASM\n#include \"quant_lsp_bfin.h\"\n#endif\n\n#ifdef FIXED_POINT\n\n#define LSP_LINEAR(i) (SHL16(i+1,11))\n#define LSP_LINEAR_HIGH(i) (ADD16(MULT16_16_16(i,2560),6144))\n#define LSP_DIV_256(x) (SHL16((spx_word16_t)x, 5))\n#define LSP_DIV_512(x) (SHL16((spx_word16_t)x, 4))\n#define LSP_DIV_1024(x) (SHL16((spx_word16_t)x, 3))\n#define LSP_PI 25736\n\n#else\n\n#define LSP_LINEAR(i) (.25*(i)+.25)\n#define LSP_LINEAR_HIGH(i) (.3125*(i)+.75)\n#define LSP_SCALE 256.\n#define LSP_DIV_256(x) (0.0039062*(x))\n#define LSP_DIV_512(x) (0.0019531*(x))\n#define LSP_DIV_1024(x) (0.00097656*(x))\n#define LSP_PI M_PI\n\n#endif\n\nstatic void compute_quant_weights(spx_lsp_t *qlsp, spx_word16_t *quant_weight, int order)\n{\n   int i;\n   spx_word16_t tmp1, tmp2;\n   for (i=0;i<order;i++)\n   {\n      if (i==0)\n         tmp1 = qlsp[i];\n      else\n         tmp1 = qlsp[i]-qlsp[i-1];\n      if (i==order-1)\n         tmp2 = LSP_PI-qlsp[i];\n      else\n         tmp2 = qlsp[i+1]-qlsp[i];\n      if (tmp2<tmp1)\n         tmp1 = tmp2;\n#ifdef FIXED_POINT\n      quant_weight[i] = DIV32_16(81920,ADD16(300,tmp1));\n#else\n      quant_weight[i] = 10/(.04+tmp1);\n#endif\n   }\n\n}\n\n/* Note: x is modified*/\n#ifndef OVERRIDE_LSP_QUANT\nstatic int lsp_quant(spx_word16_t *x, const signed char *cdbk, int nbVec, int nbDim)\n{\n   int i,j;\n   spx_word32_t dist;\n   spx_word16_t tmp;\n   spx_word32_t best_dist=VERY_LARGE32;\n   int best_id=0;\n   const signed char *ptr=cdbk;\n   for (i=0;i<nbVec;i++)\n   {\n      dist=0;\n      for (j=0;j<nbDim;j++)\n      {\n         tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5));\n         dist=MAC16_16(dist,tmp,tmp);\n      } \n      if (dist<best_dist)\n      {\n         best_dist=dist;\n         best_id=i;\n      }\n   }\n\n   for (j=0;j<nbDim;j++)\n      x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));\n    \n   return best_id;\n}\n#endif\n\n/* Note: x is modified*/\n#ifndef OVERRIDE_LSP_WEIGHT_QUANT\nstatic int lsp_weight_quant(spx_word16_t *x, spx_word16_t *weight, const signed char *cdbk, int nbVec, int nbDim)\n{\n   int i,j;\n   spx_word32_t dist;\n   spx_word16_t tmp;\n   spx_word32_t best_dist=VERY_LARGE32;\n   int best_id=0;\n   const signed char *ptr=cdbk;\n   for (i=0;i<nbVec;i++)\n   {\n      dist=0;\n      for (j=0;j<nbDim;j++)\n      {\n         tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5));\n         dist=MAC16_32_Q15(dist,weight[j],MULT16_16(tmp,tmp));\n      }\n      if (dist<best_dist)\n      {\n         best_dist=dist;\n         best_id=i;\n      }\n   }\n   \n   for (j=0;j<nbDim;j++)\n      x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));\n   return best_id;\n}\n#endif\n\nvoid lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)\n{\n   int i;\n   int id;\n   spx_word16_t quant_weight[10];\n   \n   for (i=0;i<order;i++)\n      qlsp[i]=lsp[i];\n\n   compute_quant_weights(qlsp, quant_weight, order);\n\n   for (i=0;i<order;i++)\n      qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i));\n\n#ifndef FIXED_POINT\n   for (i=0;i<order;i++)\n      qlsp[i] = LSP_SCALE*qlsp[i];\n#endif\n   id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);\n   speex_bits_pack(bits, id, 6);\n\n   for (i=0;i<order;i++)\n      qlsp[i]*=2;\n \n   id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);\n   speex_bits_pack(bits, id, 6);\n\n   for (i=0;i<5;i++)\n      qlsp[i]*=2;\n\n   id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low2, NB_CDBK_SIZE_LOW2, 5);\n   speex_bits_pack(bits, id, 6);\n\n   id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);\n   speex_bits_pack(bits, id, 6);\n\n   for (i=5;i<10;i++)\n      qlsp[i]*=2;\n\n   id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high2, NB_CDBK_SIZE_HIGH2, 5);\n   speex_bits_pack(bits, id, 6);\n\n#ifdef FIXED_POINT\n   for (i=0;i<order;i++)\n      qlsp[i]=PSHR16(qlsp[i],2);\n#else\n   for (i=0;i<order;i++)\n      qlsp[i]=qlsp[i] * .00097656;\n#endif\n\n   for (i=0;i<order;i++)\n      qlsp[i]=lsp[i]-qlsp[i];\n}\n\nvoid lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits)\n{\n   int i, id;\n   for (i=0;i<order;i++)\n      lsp[i]=LSP_LINEAR(i);\n\n\n   id=speex_bits_unpack_unsigned(bits, 6);\n   for (i=0;i<10;i++)\n      lsp[i] = ADD32(lsp[i], LSP_DIV_256(cdbk_nb[id*10+i]));\n\n   id=speex_bits_unpack_unsigned(bits, 6);\n   for (i=0;i<5;i++)\n      lsp[i] = ADD16(lsp[i], LSP_DIV_512(cdbk_nb_low1[id*5+i]));\n\n   id=speex_bits_unpack_unsigned(bits, 6);\n   for (i=0;i<5;i++)\n      lsp[i] = ADD32(lsp[i], LSP_DIV_1024(cdbk_nb_low2[id*5+i]));\n\n   id=speex_bits_unpack_unsigned(bits, 6);\n   for (i=0;i<5;i++)\n      lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_512(cdbk_nb_high1[id*5+i]));\n   \n   id=speex_bits_unpack_unsigned(bits, 6);\n   for (i=0;i<5;i++)\n      lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_1024(cdbk_nb_high2[id*5+i]));\n}\n\n\nvoid lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)\n{\n   int i;\n   int id;\n   spx_word16_t quant_weight[10];\n\n   for (i=0;i<order;i++)\n      qlsp[i]=lsp[i];\n\n   compute_quant_weights(qlsp, quant_weight, order);\n\n   for (i=0;i<order;i++)\n      qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i));\n#ifndef FIXED_POINT\n   for (i=0;i<order;i++)\n      qlsp[i]=qlsp[i]*LSP_SCALE;\n#endif\n   id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);\n   speex_bits_pack(bits, id, 6);\n   \n   for (i=0;i<order;i++)\n      qlsp[i]*=2;\n   \n   id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);\n   speex_bits_pack(bits, id, 6);\n\n   id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);\n   speex_bits_pack(bits, id, 6);\n\n#ifdef FIXED_POINT\n   for (i=0;i<order;i++)\n      qlsp[i] = PSHR16(qlsp[i],1);\n#else\n   for (i=0;i<order;i++)\n      qlsp[i] = qlsp[i]*0.0019531;\n#endif\n\n   for (i=0;i<order;i++)\n      qlsp[i]=lsp[i]-qlsp[i];\n}\n\nvoid lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits)\n{\n   int i, id;\n   for (i=0;i<order;i++)\n      lsp[i]=LSP_LINEAR(i);\n\n\n   id=speex_bits_unpack_unsigned(bits, 6);\n   for (i=0;i<10;i++)\n      lsp[i] += LSP_DIV_256(cdbk_nb[id*10+i]);\n\n   id=speex_bits_unpack_unsigned(bits, 6);\n   for (i=0;i<5;i++)\n      lsp[i] += LSP_DIV_512(cdbk_nb_low1[id*5+i]);\n\n   id=speex_bits_unpack_unsigned(bits, 6);\n   for (i=0;i<5;i++)\n      lsp[i+5] += LSP_DIV_512(cdbk_nb_high1[id*5+i]);\n   \n}\n\n\n#ifdef DISABLE_WIDEBAND\nvoid lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)\n{\n   speex_fatal(\"Wideband and Ultra-wideband are disabled\");\n}\nvoid lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)\n{\n   speex_fatal(\"Wideband and Ultra-wideband are disabled\");\n}\n#else\nextern const signed char high_lsp_cdbk[];\nextern const signed char high_lsp_cdbk2[];\n\n\nvoid lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)\n{\n   int i;\n   int id;\n   spx_word16_t quant_weight[10];\n\n   for (i=0;i<order;i++)\n      qlsp[i]=lsp[i];\n\n   compute_quant_weights(qlsp, quant_weight, order);\n\n   /*   quant_weight[0] = 10/(qlsp[1]-qlsp[0]);\n   quant_weight[order-1] = 10/(qlsp[order-1]-qlsp[order-2]);\n   for (i=1;i<order-1;i++)\n   {\n      tmp1 = 10/(qlsp[i]-qlsp[i-1]);\n      tmp2 = 10/(qlsp[i+1]-qlsp[i]);\n      quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;\n      }*/\n\n   for (i=0;i<order;i++)\n      qlsp[i]=SUB16(qlsp[i],LSP_LINEAR_HIGH(i));\n#ifndef FIXED_POINT\n   for (i=0;i<order;i++)\n      qlsp[i] = qlsp[i]*LSP_SCALE;\n#endif\n   id = lsp_quant(qlsp, high_lsp_cdbk, 64, order);\n   speex_bits_pack(bits, id, 6);\n\n   for (i=0;i<order;i++)\n      qlsp[i]*=2;\n\n   id = lsp_weight_quant(qlsp, quant_weight, high_lsp_cdbk2, 64, order);\n   speex_bits_pack(bits, id, 6);\n\n#ifdef FIXED_POINT\n   for (i=0;i<order;i++)\n      qlsp[i] = PSHR16(qlsp[i],1);\n#else\n   for (i=0;i<order;i++)\n      qlsp[i] = qlsp[i]*0.0019531;\n#endif\n\n   for (i=0;i<order;i++)\n      qlsp[i]=lsp[i]-qlsp[i];\n}\n\nvoid lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)\n{\n\n   int i, id;\n   for (i=0;i<order;i++)\n      lsp[i]=LSP_LINEAR_HIGH(i);\n\n\n   id=speex_bits_unpack_unsigned(bits, 6);\n   for (i=0;i<order;i++)\n      lsp[i] += LSP_DIV_256(high_lsp_cdbk[id*order+i]);\n\n\n   id=speex_bits_unpack_unsigned(bits, 6);\n   for (i=0;i<order;i++)\n      lsp[i] += LSP_DIV_512(high_lsp_cdbk2[id*order+i]);\n}\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/quant_lsp.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin */\n/**\n   @file quant_lsp.h\n   @brief LSP vector quantization\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef QUANT_LSP_H\n#define QUANT_LSP_H\n\n#include <speex/speex_bits.h>\n#include \"arch.h\"\n\n#define MAX_LSP_SIZE 20\n\n#define NB_CDBK_SIZE 64\n#define NB_CDBK_SIZE_LOW1 64\n#define NB_CDBK_SIZE_LOW2 64\n#define NB_CDBK_SIZE_HIGH1 64\n#define NB_CDBK_SIZE_HIGH2 64\n\n/*Narrowband codebooks*/\nextern const signed char cdbk_nb[];\nextern const signed char cdbk_nb_low1[];\nextern const signed char cdbk_nb_low2[];\nextern const signed char cdbk_nb_high1[];\nextern const signed char cdbk_nb_high2[];\n\n/* Quantizes narrowband LSPs with 30 bits */\nvoid lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);\n\n/* Decodes quantized narrowband LSPs */\nvoid lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits);\n\n/* Quantizes low bit-rate narrowband LSPs with 18 bits */\nvoid lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);\n\n/* Decodes quantized low bit-rate narrowband LSPs */\nvoid lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits);\n\n/* Quantizes high-band LSPs with 12 bits */\nvoid lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);\n\n/* Decodes high-band LSPs */\nvoid lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits);\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/quant_lsp_bfin.h",
    "content": "/* Copyright (C) 2006 David Rowe */\n/**\n   @file quant_lsp_bfin.h\n   @author David Rowe\n   @brief Various compatibility routines for Speex (Blackfin version)\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#define OVERRIDE_LSP_QUANT\n#ifdef OVERRIDE_LSP_QUANT\n\n/*\n  Note http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html\n  well tell you all the magic resgister constraints used below\n  for gcc in-line asm.\n*/\n\nstatic int lsp_quant(\n  spx_word16_t      *x, \n  const signed char *cdbk, \n  int                nbVec, \n  int                nbDim\n)\n{\n   int          j;\n   spx_word32_t best_dist=1<<30;\n   int          best_id=0;\n\n   __asm__ __volatile__\n     (\n\"\t%0 = 1 (X);\\n\\t\"                       /* %0: best_dist */    \n\"\t%0 <<= 30;\\n\\t\"     \n\"\t%1 = 0 (X);\\n\\t\"                       /* %1: best_i         */\n\"       P2 = %3\\n\\t\"                           /* P2: ptr to cdbk    */\n\"       R5 = 0;\\n\\t\"                           /* R5: best cb entry  */\n\n\"       R0 = %5;\\n\\t\"                          /* set up circ addr   */\n\"       R0 <<= 1;\\n\\t\"\n\"       L0 = R0;\\n\\t\"                          \n\"       I0 = %2;\\n\\t\"                          /* %2: &x[0]          */\n\"       B0 = %2;\\n\\t\"                          \n\n\"       R2.L = W [I0++];\\n\\t\"\n\"\tLSETUP (1f, 2f) LC0 = %4;\\n\\t\"\n\"1:\t  R3 = 0;\\n\\t\"                         /* R3: dist           */\n\"\t  LSETUP (3f, 4f) LC1 = %5;\\n\\t\"\n\"3:       R1 = B [P2++] (X);\\n\\t\"            \n\"\t    R1 <<= 5;\\n\\t\"\n\"\t    R0.L = R2.L - R1.L || R2.L = W [I0++];\\n\\t\"\n\"\t    R0 = R0.L*R0.L;\\n\\t\"\n\"4:\t    R3 = R3 + R0;\\n\\t\"\n\n\"\t  cc =R3<%0;\\n\\t\"\n\"\t  if cc %0=R3;\\n\\t\"\n\"\t  if cc %1=R5;\\n\\t\"\n\"2:     R5 += 1;\\n\\t\"\n\"         L0 = 0;\\n\\t\"\n   : \"=&d\" (best_dist), \"=&d\" (best_id)\n   : \"a\" (x), \"b\" (cdbk), \"a\" (nbVec), \"a\" (nbDim)\n   : \"I0\", \"P2\", \"R0\", \"R1\", \"R2\", \"R3\", \"R5\", \"L0\", \"B0\", \"A0\"\n   );\n\n   for (j=0;j<nbDim;j++) {\n      x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));\n   }\n   return best_id;\n}\n#endif\n\n#define OVERRIDE_LSP_WEIGHT_QUANT\n#ifdef OVERRIDE_LSP_WEIGHT_QUANT\n\n/*\n  Note http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html\n  well tell you all the magic resgister constraints used below\n  for gcc in-line asm.\n*/\n\nstatic int lsp_weight_quant(\n  spx_word16_t      *x, \n  spx_word16_t      *weight, \n  const signed char *cdbk, \n  int                nbVec, \n  int                nbDim\n)\n{\n   int          j;\n   spx_word32_t best_dist=1<<30;\n   int          best_id=0;\n\n   __asm__ __volatile__\n     (\n\"\t%0 = 1 (X);\\n\\t\"                       /* %0: best_dist */    \n\"\t%0 <<= 30;\\n\\t\"     \n\"\t%1 = 0 (X);\\n\\t\"                       /* %1: best_i         */\n\"       P2 = %4\\n\\t\"                           /* P2: ptr to cdbk    */\n\"       R5 = 0;\\n\\t\"                           /* R5: best cb entry  */\n\n\"       R0 = %6;\\n\\t\"                          /* set up circ addr   */\n\"       R0 <<= 1;\\n\\t\"\n\"       L0 = R0;\\n\\t\"                          \n\"       L1 = R0;\\n\\t\"\n\"       I0 = %2;\\n\\t\"                          /* %2: &x[0]          */\n\"\tI1 = %3;\\n\\t\"                          /* %3: &weight[0]     */\n\"       B0 = %2;\\n\\t\"                          \n\"\tB1 = %3;\\n\\t\"                          \n\n\"\tLSETUP (1f, 2f) LC0 = %5;\\n\\t\"\n\"1:\t  R3 = 0 (X);\\n\\t\"                     /* R3: dist           */\n\"\t  LSETUP (3f, 4f) LC1 = %6;\\n\\t\"\n\"3:\t    R0.L = W [I0++] || R2.L = W [I1++];\\n\\t\"\n\"           R1 = B [P2++] (X);\\n\\t\"            \n\"\t    R1 <<= 5;\\n\\t\"\n\"\t    R0.L = R0.L - R1.L;\\n\\t\"\n\"           R0 = R0.L*R0.L;\\n\\t\"\n\"\t    A1 = R2.L*R0.L (M,IS);\\n\\t\"\n\"\t    A1 = A1 >>> 16;\\n\\t\"\n\"\t    R1 = (A1 += R2.L*R0.H) (IS);\\n\\t\"\n\"4:\t    R3 = R3 + R1;\\n\\t\"\n\n\"\t  cc =R3<%0;\\n\\t\"\n\"\t  if cc %0=R3;\\n\\t\"\n\"\t  if cc %1=R5;\\n\\t\"\n\"2:    R5 += 1;\\n\\t\"\n\"         L0 = 0;\\n\\t\"\n\"         L1 = 0;\\n\\t\"\n   : \"=&d\" (best_dist), \"=&d\" (best_id)\n   : \"a\" (x), \"a\" (weight), \"b\" (cdbk), \"a\" (nbVec), \"a\" (nbDim)\n   : \"I0\", \"I1\", \"P2\", \"R0\", \"R1\", \"R2\", \"R3\", \"R5\", \"A1\",\n     \"L0\", \"L1\", \"B0\", \"B1\"\n   );\n\n   for (j=0;j<nbDim;j++) {\n      x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));\n   }\n   return best_id;\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/resample.c",
    "content": "/* Copyright (C) 2007-2008 Jean-Marc Valin\n   Copyright (C) 2008      Thorvald Natvig\n      \n   File: resample.c\n   Arbitrary resampling code\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/*\n   The design goals of this code are:\n      - Very fast algorithm\n      - SIMD-friendly algorithm\n      - Low memory requirement\n      - Good *perceptual* quality (and not best SNR)\n\n   Warning: This resampler is relatively new. Although I think I got rid of \n   all the major bugs and I don't expect the API to change anymore, there\n   may be something I've missed. So use with caution.\n\n   This algorithm is based on this original resampling algorithm:\n   Smith, Julius O. Digital Audio Resampling Home Page\n   Center for Computer Research in Music and Acoustics (CCRMA), \n   Stanford University, 2007.\n   Web published at http://www-ccrma.stanford.edu/~jos/resample/.\n\n   There is one main difference, though. This resampler uses cubic \n   interpolation instead of linear interpolation in the above paper. This\n   makes the table much smaller and makes it possible to compute that table\n   on a per-stream basis. In turn, being able to tweak the table for each \n   stream makes it possible to both reduce complexity on simple ratios \n   (e.g. 2/3), and get rid of the rounding operations in the inner loop. \n   The latter both reduces CPU time and makes the algorithm more SIMD-friendly.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#ifdef OUTSIDE_SPEEX\n#include <stdlib.h>\nstatic void *speex_alloc (int size) {return calloc(size,1);}\nstatic void *speex_realloc (void *ptr, int size) {return realloc(ptr, size);}\nstatic void speex_free (void *ptr) {free(ptr);}\n#include \"speex_resampler.h\"\n#include \"arch.h\"\n#else /* OUTSIDE_SPEEX */\n               \n#include \"speex/speex_resampler.h\"\n#include \"arch.h\"\n#include \"os_support.h\"\n#endif /* OUTSIDE_SPEEX */\n\n#include \"stack_alloc.h\"\n#include <math.h>\n\n#ifndef M_PI\n#define M_PI 3.14159263\n#endif\n\n#ifdef FIXED_POINT\n#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x)))  \n#else\n#define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x))))  \n#endif\n               \n#define IMAX(a,b) ((a) > (b) ? (a) : (b))\n#define IMIN(a,b) ((a) < (b) ? (a) : (b))\n\n#ifndef NULL\n#define NULL 0\n#endif\n\n#ifdef _USE_SSE\n#include \"resample_sse.h\"\n#endif\n\n/* Numer of elements to allocate on the stack */\n#ifdef VAR_ARRAYS\n#define FIXED_STACK_ALLOC 8192\n#else\n#define FIXED_STACK_ALLOC 1024\n#endif\n\ntypedef int (*resampler_basic_func)(SpeexResamplerState *, spx_uint32_t , const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *);\n\nstruct SpeexResamplerState_ {\n   spx_uint32_t in_rate;\n   spx_uint32_t out_rate;\n   spx_uint32_t num_rate;\n   spx_uint32_t den_rate;\n   \n   int    quality;\n   spx_uint32_t nb_channels;\n   spx_uint32_t filt_len;\n   spx_uint32_t mem_alloc_size;\n   spx_uint32_t buffer_size;\n   int          int_advance;\n   int          frac_advance;\n   float  cutoff;\n   spx_uint32_t oversample;\n   int          initialised;\n   int          started;\n   \n   /* These are per-channel */\n   spx_int32_t  *last_sample;\n   spx_uint32_t *samp_frac_num;\n   spx_uint32_t *magic_samples;\n   \n   spx_word16_t *mem;\n   spx_word16_t *sinc_table;\n   spx_uint32_t sinc_table_length;\n   resampler_basic_func resampler_ptr;\n         \n   int    in_stride;\n   int    out_stride;\n} ;\n\nstatic double kaiser12_table[68] = {\n   0.99859849, 1.00000000, 0.99859849, 0.99440475, 0.98745105, 0.97779076,\n   0.96549770, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014,\n   0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.72629970, 0.69451601,\n   0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014,\n   0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.34301800, 0.31506490,\n   0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546,\n   0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178,\n   0.07063950, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947,\n   0.02584161, 0.02127838, 0.01736250, 0.01402878, 0.01121463, 0.00886058,\n   0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438,\n   0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 0.0000527734,\n   0.00001000, 0.00000000};\n/*\nstatic double kaiser12_table[36] = {\n   0.99440475, 1.00000000, 0.99440475, 0.97779076, 0.95066529, 0.91384741,\n   0.86843014, 0.81573067, 0.75723148, 0.69451601, 0.62920216, 0.56287762,\n   0.49704014, 0.43304576, 0.37206735, 0.31506490, 0.26276832, 0.21567274,\n   0.17404546, 0.13794294, 0.10723616, 0.08164178, 0.06075685, 0.04409466,\n   0.03111947, 0.02127838, 0.01402878, 0.00886058, 0.00531256, 0.00298291,\n   0.00153438, 0.00069463, 0.00025272, 0.0000527734, 0.00000500, 0.00000000};\n*/\nstatic double kaiser10_table[36] = {\n   0.99537781, 1.00000000, 0.99537781, 0.98162644, 0.95908712, 0.92831446,\n   0.89005583, 0.84522401, 0.79486424, 0.74011713, 0.68217934, 0.62226347,\n   0.56155915, 0.50119680, 0.44221549, 0.38553619, 0.33194107, 0.28205962,\n   0.23636152, 0.19515633, 0.15859932, 0.12670280, 0.09935205, 0.07632451,\n   0.05731132, 0.04193980, 0.02979584, 0.02044510, 0.01345224, 0.00839739,\n   0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.00000000, 0.00000000};\n\nstatic double kaiser8_table[36] = {\n   0.99635258, 1.00000000, 0.99635258, 0.98548012, 0.96759014, 0.94302200,\n   0.91223751, 0.87580811, 0.83439927, 0.78875245, 0.73966538, 0.68797126,\n   0.63451750, 0.58014482, 0.52566725, 0.47185369, 0.41941150, 0.36897272,\n   0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758,\n   0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490,\n   0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000};\n   \nstatic double kaiser6_table[36] = {\n   0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003,\n   0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565,\n   0.71712752, 0.67172623, 0.62508937, 0.57774224, 0.53019925, 0.48295561,\n   0.43647969, 0.39120616, 0.34752997, 0.30580127, 0.26632152, 0.22934058,\n   0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.08693120, 0.06722600,\n   0.05031820, 0.03607231, 0.02432151, 0.01487334, 0.00752000, 0.00000000};\n\nstruct FuncDef {\n   double *table;\n   int oversample;\n};\n      \nstatic struct FuncDef _KAISER12 = {kaiser12_table, 64};\n#define KAISER12 (&_KAISER12)\n/*static struct FuncDef _KAISER12 = {kaiser12_table, 32};\n#define KAISER12 (&_KAISER12)*/\nstatic struct FuncDef _KAISER10 = {kaiser10_table, 32};\n#define KAISER10 (&_KAISER10)\nstatic struct FuncDef _KAISER8 = {kaiser8_table, 32};\n#define KAISER8 (&_KAISER8)\nstatic struct FuncDef _KAISER6 = {kaiser6_table, 32};\n#define KAISER6 (&_KAISER6)\n\nstruct QualityMapping {\n   int base_length;\n   int oversample;\n   float downsample_bandwidth;\n   float upsample_bandwidth;\n   struct FuncDef *window_func;\n};\n\n\n/* This table maps conversion quality to internal parameters. There are two\n   reasons that explain why the up-sampling bandwidth is larger than the \n   down-sampling bandwidth:\n   1) When up-sampling, we can assume that the spectrum is already attenuated\n      close to the Nyquist rate (from an A/D or a previous resampling filter)\n   2) Any aliasing that occurs very close to the Nyquist rate will be masked\n      by the sinusoids/noise just below the Nyquist rate (guaranteed only for\n      up-sampling).\n*/\nstatic const struct QualityMapping quality_map[11] = {\n   {  8,  4, 0.830f, 0.860f, KAISER6 }, /* Q0 */\n   { 16,  4, 0.850f, 0.880f, KAISER6 }, /* Q1 */\n   { 32,  4, 0.882f, 0.910f, KAISER6 }, /* Q2 */  /* 82.3% cutoff ( ~60 dB stop) 6  */\n   { 48,  8, 0.895f, 0.917f, KAISER8 }, /* Q3 */  /* 84.9% cutoff ( ~80 dB stop) 8  */\n   { 64,  8, 0.921f, 0.940f, KAISER8 }, /* Q4 */  /* 88.7% cutoff ( ~80 dB stop) 8  */\n   { 80, 16, 0.922f, 0.940f, KAISER10}, /* Q5 */  /* 89.1% cutoff (~100 dB stop) 10 */\n   { 96, 16, 0.940f, 0.945f, KAISER10}, /* Q6 */  /* 91.5% cutoff (~100 dB stop) 10 */\n   {128, 16, 0.950f, 0.950f, KAISER10}, /* Q7 */  /* 93.1% cutoff (~100 dB stop) 10 */\n   {160, 16, 0.960f, 0.960f, KAISER10}, /* Q8 */  /* 94.5% cutoff (~100 dB stop) 10 */\n   {192, 32, 0.968f, 0.968f, KAISER12}, /* Q9 */  /* 95.5% cutoff (~100 dB stop) 10 */\n   {256, 32, 0.975f, 0.975f, KAISER12}, /* Q10 */ /* 96.6% cutoff (~100 dB stop) 10 */\n};\n/*8,24,40,56,80,104,128,160,200,256,320*/\nstatic double compute_func(float x, struct FuncDef *func)\n{\n   float y, frac;\n   double interp[4];\n   int ind; \n   y = x*func->oversample;\n   ind = (int)floor(y);\n   frac = (y-ind);\n   /* CSE with handle the repeated powers */\n   interp[3] =  -0.1666666667*frac + 0.1666666667*(frac*frac*frac);\n   interp[2] = frac + 0.5*(frac*frac) - 0.5*(frac*frac*frac);\n   /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/\n   interp[0] = -0.3333333333*frac + 0.5*(frac*frac) - 0.1666666667*(frac*frac*frac);\n   /* Just to make sure we don't have rounding problems */\n   interp[1] = 1.f-interp[3]-interp[2]-interp[0];\n   \n   /*sum = frac*accum[1] + (1-frac)*accum[2];*/\n   return interp[0]*func->table[ind] + interp[1]*func->table[ind+1] + interp[2]*func->table[ind+2] + interp[3]*func->table[ind+3];\n}\n\n#if 0\n#include <stdio.h>\nint main(int argc, char **argv)\n{\n   int i;\n   for (i=0;i<256;i++)\n   {\n      printf (\"%f\\n\", compute_func(i/256., KAISER12));\n   }\n   return 0;\n}\n#endif\n\n#ifdef FIXED_POINT\n/* The slow way of computing a sinc for the table. Should improve that some day */\nstatic spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func)\n{\n   /*fprintf (stderr, \"%f \", x);*/\n   float xx = x * cutoff;\n   if (fabs(x)<1e-6f)\n      return WORD2INT(32768.*cutoff);\n   else if (fabs(x) > .5f*N)\n      return 0;\n   /*FIXME: Can it really be any slower than this? */\n   return WORD2INT(32768.*cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func));\n}\n#else\n/* The slow way of computing a sinc for the table. Should improve that some day */\nstatic spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func)\n{\n   /*fprintf (stderr, \"%f \", x);*/\n   float xx = x * cutoff;\n   if (fabs(x)<1e-6)\n      return cutoff;\n   else if (fabs(x) > .5*N)\n      return 0;\n   /*FIXME: Can it really be any slower than this? */\n   return cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func);\n}\n#endif\n\n#ifdef FIXED_POINT\nstatic void cubic_coef(spx_word16_t x, spx_word16_t interp[4])\n{\n   /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation\n   but I know it's MMSE-optimal on a sinc */\n   spx_word16_t x2, x3;\n   x2 = MULT16_16_P15(x, x);\n   x3 = MULT16_16_P15(x, x2);\n   interp[0] = PSHR32(MULT16_16(QCONST16(-0.16667f, 15),x) + MULT16_16(QCONST16(0.16667f, 15),x3),15);\n   interp[1] = EXTRACT16(EXTEND32(x) + SHR32(SUB32(EXTEND32(x2),EXTEND32(x3)),1));\n   interp[3] = PSHR32(MULT16_16(QCONST16(-0.33333f, 15),x) + MULT16_16(QCONST16(.5f,15),x2) - MULT16_16(QCONST16(0.16667f, 15),x3),15);\n   /* Just to make sure we don't have rounding problems */\n   interp[2] = Q15_ONE-interp[0]-interp[1]-interp[3];\n   if (interp[2]<32767)\n      interp[2]+=1;\n}\n#else\nstatic void cubic_coef(spx_word16_t frac, spx_word16_t interp[4])\n{\n   /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation\n   but I know it's MMSE-optimal on a sinc */\n   interp[0] =  -0.16667f*frac + 0.16667f*frac*frac*frac;\n   interp[1] = frac + 0.5f*frac*frac - 0.5f*frac*frac*frac;\n   /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/\n   interp[3] = -0.33333f*frac + 0.5f*frac*frac - 0.16667f*frac*frac*frac;\n   /* Just to make sure we don't have rounding problems */\n   interp[2] = 1.-interp[0]-interp[1]-interp[3];\n}\n#endif\n\nstatic int resampler_basic_direct_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)\n{\n   const int N = st->filt_len;\n   int out_sample = 0;\n   int last_sample = st->last_sample[channel_index];\n   spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];\n   const spx_word16_t *sinc_table = st->sinc_table;\n   const int out_stride = st->out_stride;\n   const int int_advance = st->int_advance;\n   const int frac_advance = st->frac_advance;\n   const spx_uint32_t den_rate = st->den_rate;\n   spx_word32_t sum;\n   int j;\n\n   while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))\n   {\n      const spx_word16_t *sinc = & sinc_table[samp_frac_num*N];\n      const spx_word16_t *iptr = & in[last_sample];\n\n#ifndef OVERRIDE_INNER_PRODUCT_SINGLE\n      float accum[4] = {0,0,0,0};\n\n      for(j=0;j<N;j+=4) {\n        accum[0] += sinc[j]*iptr[j];\n        accum[1] += sinc[j+1]*iptr[j+1];\n        accum[2] += sinc[j+2]*iptr[j+2];\n        accum[3] += sinc[j+3]*iptr[j+3];\n      }\n      sum = accum[0] + accum[1] + accum[2] + accum[3];\n#else\n      sum = inner_product_single(sinc, iptr, N);\n#endif\n\n      out[out_stride * out_sample++] = PSHR32(sum, 15);\n      last_sample += int_advance;\n      samp_frac_num += frac_advance;\n      if (samp_frac_num >= den_rate)\n      {\n         samp_frac_num -= den_rate;\n         last_sample++;\n      }\n   }\n\n   st->last_sample[channel_index] = last_sample;\n   st->samp_frac_num[channel_index] = samp_frac_num;\n   return out_sample;\n}\n\n#ifdef FIXED_POINT\n#else\n/* This is the same as the previous function, except with a double-precision accumulator */\nstatic int resampler_basic_direct_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)\n{\n   const int N = st->filt_len;\n   int out_sample = 0;\n   int last_sample = st->last_sample[channel_index];\n   spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];\n   const spx_word16_t *sinc_table = st->sinc_table;\n   const int out_stride = st->out_stride;\n   const int int_advance = st->int_advance;\n   const int frac_advance = st->frac_advance;\n   const spx_uint32_t den_rate = st->den_rate;\n   double sum;\n   int j;\n\n   while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))\n   {\n      const spx_word16_t *sinc = & sinc_table[samp_frac_num*N];\n      const spx_word16_t *iptr = & in[last_sample];\n\n#ifndef OVERRIDE_INNER_PRODUCT_DOUBLE\n      double accum[4] = {0,0,0,0};\n\n      for(j=0;j<N;j+=4) {\n        accum[0] += sinc[j]*iptr[j];\n        accum[1] += sinc[j+1]*iptr[j+1];\n        accum[2] += sinc[j+2]*iptr[j+2];\n        accum[3] += sinc[j+3]*iptr[j+3];\n      }\n      sum = accum[0] + accum[1] + accum[2] + accum[3];\n#else\n      sum = inner_product_double(sinc, iptr, N);\n#endif\n\n      out[out_stride * out_sample++] = PSHR32(sum, 15);\n      last_sample += int_advance;\n      samp_frac_num += frac_advance;\n      if (samp_frac_num >= den_rate)\n      {\n         samp_frac_num -= den_rate;\n         last_sample++;\n      }\n   }\n\n   st->last_sample[channel_index] = last_sample;\n   st->samp_frac_num[channel_index] = samp_frac_num;\n   return out_sample;\n}\n#endif\n\nstatic int resampler_basic_interpolate_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)\n{\n   const int N = st->filt_len;\n   int out_sample = 0;\n   int last_sample = st->last_sample[channel_index];\n   spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];\n   const int out_stride = st->out_stride;\n   const int int_advance = st->int_advance;\n   const int frac_advance = st->frac_advance;\n   const spx_uint32_t den_rate = st->den_rate;\n   int j;\n   spx_word32_t sum;\n\n   while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))\n   {\n      const spx_word16_t *iptr = & in[last_sample];\n\n      const int offset = samp_frac_num*st->oversample/st->den_rate;\n#ifdef FIXED_POINT\n      const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate);\n#else\n      const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate;\n#endif\n      spx_word16_t interp[4];\n\n\n#ifndef OVERRIDE_INTERPOLATE_PRODUCT_SINGLE\n      spx_word32_t accum[4] = {0,0,0,0};\n\n      for(j=0;j<N;j++) {\n        const spx_word16_t curr_in=iptr[j];\n        accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]);\n        accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]);\n        accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]);\n        accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]);\n      }\n\n      cubic_coef(frac, interp);\n      sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]);\n#else\n      cubic_coef(frac, interp);\n      sum = interpolate_product_single(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp);\n#endif\n      \n      out[out_stride * out_sample++] = PSHR32(sum,15);\n      last_sample += int_advance;\n      samp_frac_num += frac_advance;\n      if (samp_frac_num >= den_rate)\n      {\n         samp_frac_num -= den_rate;\n         last_sample++;\n      }\n   }\n\n   st->last_sample[channel_index] = last_sample;\n   st->samp_frac_num[channel_index] = samp_frac_num;\n   return out_sample;\n}\n\n#ifdef FIXED_POINT\n#else\n/* This is the same as the previous function, except with a double-precision accumulator */\nstatic int resampler_basic_interpolate_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)\n{\n   const int N = st->filt_len;\n   int out_sample = 0;\n   int last_sample = st->last_sample[channel_index];\n   spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];\n   const int out_stride = st->out_stride;\n   const int int_advance = st->int_advance;\n   const int frac_advance = st->frac_advance;\n   const spx_uint32_t den_rate = st->den_rate;\n   int j;\n   spx_word32_t sum;\n\n   while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))\n   {\n      const spx_word16_t *iptr = & in[last_sample];\n\n      const int offset = samp_frac_num*st->oversample/st->den_rate;\n#ifdef FIXED_POINT\n      const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate);\n#else\n      const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate;\n#endif\n      spx_word16_t interp[4];\n\n\n#ifndef OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE\n      double accum[4] = {0,0,0,0};\n\n      for(j=0;j<N;j++) {\n        const double curr_in=iptr[j];\n        accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]);\n        accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]);\n        accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]);\n        accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]);\n      }\n\n      cubic_coef(frac, interp);\n      sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]);\n#else\n      cubic_coef(frac, interp);\n      sum = interpolate_product_double(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp);\n#endif\n      \n      out[out_stride * out_sample++] = PSHR32(sum,15);\n      last_sample += int_advance;\n      samp_frac_num += frac_advance;\n      if (samp_frac_num >= den_rate)\n      {\n         samp_frac_num -= den_rate;\n         last_sample++;\n      }\n   }\n\n   st->last_sample[channel_index] = last_sample;\n   st->samp_frac_num[channel_index] = samp_frac_num;\n   return out_sample;\n}\n#endif\n\nstatic void update_filter(SpeexResamplerState *st)\n{\n   spx_uint32_t old_length;\n   \n   old_length = st->filt_len;\n   st->oversample = quality_map[st->quality].oversample;\n   st->filt_len = quality_map[st->quality].base_length;\n   \n   if (st->num_rate > st->den_rate)\n   {\n      /* down-sampling */\n      st->cutoff = quality_map[st->quality].downsample_bandwidth * st->den_rate / st->num_rate;\n      /* FIXME: divide the numerator and denominator by a certain amount if they're too large */\n      st->filt_len = st->filt_len*st->num_rate / st->den_rate;\n      /* Round down to make sure we have a multiple of 4 */\n      st->filt_len &= (~0x3);\n      if (2*st->den_rate < st->num_rate)\n         st->oversample >>= 1;\n      if (4*st->den_rate < st->num_rate)\n         st->oversample >>= 1;\n      if (8*st->den_rate < st->num_rate)\n         st->oversample >>= 1;\n      if (16*st->den_rate < st->num_rate)\n         st->oversample >>= 1;\n      if (st->oversample < 1)\n         st->oversample = 1;\n   } else {\n      /* up-sampling */\n      st->cutoff = quality_map[st->quality].upsample_bandwidth;\n   }\n   \n   /* Choose the resampling type that requires the least amount of memory */\n   if (st->den_rate <= st->oversample)\n   {\n      spx_uint32_t i;\n      if (!st->sinc_table)\n         st->sinc_table = (spx_word16_t *)speex_alloc(st->filt_len*st->den_rate*sizeof(spx_word16_t));\n      else if (st->sinc_table_length < st->filt_len*st->den_rate)\n      {\n         st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,st->filt_len*st->den_rate*sizeof(spx_word16_t));\n         st->sinc_table_length = st->filt_len*st->den_rate;\n      }\n      for (i=0;i<st->den_rate;i++)\n      {\n         spx_int32_t j;\n         for (j=0;j<st->filt_len;j++)\n         {\n            st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-(spx_int32_t)st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func);\n         }\n      }\n#ifdef FIXED_POINT\n      st->resampler_ptr = resampler_basic_direct_single;\n#else\n      if (st->quality>8)\n         st->resampler_ptr = resampler_basic_direct_double;\n      else\n         st->resampler_ptr = resampler_basic_direct_single;\n#endif\n      /*fprintf (stderr, \"resampler uses direct sinc table and normalised cutoff %f\\n\", cutoff);*/\n   } else {\n      spx_int32_t i;\n      if (!st->sinc_table)\n         st->sinc_table = (spx_word16_t *)speex_alloc((st->filt_len*st->oversample+8)*sizeof(spx_word16_t));\n      else if (st->sinc_table_length < st->filt_len*st->oversample+8)\n      {\n         st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,(st->filt_len*st->oversample+8)*sizeof(spx_word16_t));\n         st->sinc_table_length = st->filt_len*st->oversample+8;\n      }\n      for (i=-4;i<(spx_int32_t)(st->oversample*st->filt_len+4);i++)\n         st->sinc_table[i+4] = sinc(st->cutoff,(i/(float)st->oversample - st->filt_len/2), st->filt_len, quality_map[st->quality].window_func);\n#ifdef FIXED_POINT\n      st->resampler_ptr = resampler_basic_interpolate_single;\n#else\n      if (st->quality>8)\n         st->resampler_ptr = resampler_basic_interpolate_double;\n      else\n         st->resampler_ptr = resampler_basic_interpolate_single;\n#endif\n      /*fprintf (stderr, \"resampler uses interpolated sinc table and normalised cutoff %f\\n\", cutoff);*/\n   }\n   st->int_advance = st->num_rate/st->den_rate;\n   st->frac_advance = st->num_rate%st->den_rate;\n\n   \n   /* Here's the place where we update the filter memory to take into account\n      the change in filter length. It's probably the messiest part of the code\n      due to handling of lots of corner cases. */\n   if (!st->mem)\n   {\n      spx_uint32_t i;\n      st->mem_alloc_size = st->filt_len-1 + st->buffer_size;\n      st->mem = (spx_word16_t*)speex_alloc(st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t));\n      for (i=0;i<st->nb_channels*st->mem_alloc_size;i++)\n         st->mem[i] = 0;\n      /*speex_warning(\"init filter\");*/\n   } else if (!st->started)\n   {\n      spx_uint32_t i;\n      st->mem_alloc_size = st->filt_len-1 + st->buffer_size;\n      st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t));\n      for (i=0;i<st->nb_channels*st->mem_alloc_size;i++)\n         st->mem[i] = 0;\n      /*speex_warning(\"reinit filter\");*/\n   } else if (st->filt_len > old_length)\n   {\n      spx_int32_t i;\n      /* Increase the filter length */\n      /*speex_warning(\"increase filter size\");*/\n      int old_alloc_size = st->mem_alloc_size;\n      if ((st->filt_len-1 + st->buffer_size) > st->mem_alloc_size)\n      {\n         st->mem_alloc_size = st->filt_len-1 + st->buffer_size;\n         st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t));\n      }\n      for (i=st->nb_channels-1;i>=0;i--)\n      {\n         spx_int32_t j;\n         spx_uint32_t olen = old_length;\n         /*if (st->magic_samples[i])*/\n         {\n            /* Try and remove the magic samples as if nothing had happened */\n            \n            /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */\n            olen = old_length + 2*st->magic_samples[i];\n            for (j=old_length-2+st->magic_samples[i];j>=0;j--)\n               st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j];\n            for (j=0;j<st->magic_samples[i];j++)\n               st->mem[i*st->mem_alloc_size+j] = 0;\n            st->magic_samples[i] = 0;\n         }\n         if (st->filt_len > olen)\n         {\n            /* If the new filter length is still bigger than the \"augmented\" length */\n            /* Copy data going backward */\n            for (j=0;j<olen-1;j++)\n               st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)];\n            /* Then put zeros for lack of anything better */\n            for (;j<st->filt_len-1;j++)\n               st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0;\n            /* Adjust last_sample */\n            st->last_sample[i] += (st->filt_len - olen)/2;\n         } else {\n            /* Put back some of the magic! */\n            st->magic_samples[i] = (olen - st->filt_len)/2;\n            for (j=0;j<st->filt_len-1+st->magic_samples[i];j++)\n               st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]];\n         }\n      }\n   } else if (st->filt_len < old_length)\n   {\n      spx_uint32_t i;\n      /* Reduce filter length, this a bit tricky. We need to store some of the memory as \"magic\"\n         samples so they can be used directly as input the next time(s) */\n      for (i=0;i<st->nb_channels;i++)\n      {\n         spx_uint32_t j;\n         spx_uint32_t old_magic = st->magic_samples[i];\n         st->magic_samples[i] = (old_length - st->filt_len)/2;\n         /* We must copy some of the memory that's no longer used */\n         /* Copy data going backward */\n         for (j=0;j<st->filt_len-1+st->magic_samples[i]+old_magic;j++)\n            st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]];\n         st->magic_samples[i] += old_magic;\n      }\n   }\n\n}\n\nEXPORT SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err)\n{\n   return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err);\n}\n\nEXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err)\n{\n   spx_uint32_t i;\n   SpeexResamplerState *st;\n   if (quality > 10 || quality < 0)\n   {\n      if (err)\n         *err = RESAMPLER_ERR_INVALID_ARG;\n      return NULL;\n   }\n   st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState));\n   st->initialised = 0;\n   st->started = 0;\n   st->in_rate = 0;\n   st->out_rate = 0;\n   st->num_rate = 0;\n   st->den_rate = 0;\n   st->quality = -1;\n   st->sinc_table_length = 0;\n   st->mem_alloc_size = 0;\n   st->filt_len = 0;\n   st->mem = 0;\n   st->resampler_ptr = 0;\n         \n   st->cutoff = 1.f;\n   st->nb_channels = nb_channels;\n   st->in_stride = 1;\n   st->out_stride = 1;\n   \n#ifdef FIXED_POINT\n   st->buffer_size = 160;\n#else\n   st->buffer_size = 160;\n#endif\n   \n   /* Per channel data */\n   st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(int));\n   st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int));\n   st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int));\n   for (i=0;i<nb_channels;i++)\n   {\n      st->last_sample[i] = 0;\n      st->magic_samples[i] = 0;\n      st->samp_frac_num[i] = 0;\n   }\n\n   speex_resampler_set_quality(st, quality);\n   speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate);\n\n   \n   update_filter(st);\n   \n   st->initialised = 1;\n   if (err)\n      *err = RESAMPLER_ERR_SUCCESS;\n\n   return st;\n}\n\nEXPORT void speex_resampler_destroy(SpeexResamplerState *st)\n{\n   speex_free(st->mem);\n   speex_free(st->sinc_table);\n   speex_free(st->last_sample);\n   speex_free(st->magic_samples);\n   speex_free(st->samp_frac_num);\n   speex_free(st);\n}\n\nstatic int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t channel_index, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)\n{\n   int j=0;\n   const int N = st->filt_len;\n   int out_sample = 0;\n   spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;\n   spx_uint32_t ilen;\n   \n   st->started = 1;\n   \n   /* Call the right resampler through the function ptr */\n   out_sample = st->resampler_ptr(st, channel_index, mem, in_len, out, out_len);\n   \n   if (st->last_sample[channel_index] < (spx_int32_t)*in_len)\n      *in_len = st->last_sample[channel_index];\n   *out_len = out_sample;\n   st->last_sample[channel_index] -= *in_len;\n   \n   ilen = *in_len;\n\n   for(j=0;j<N-1;++j)\n     mem[j] = mem[j+ilen];\n\n   return RESAMPLER_ERR_SUCCESS;\n}\n\nstatic int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_index, spx_word16_t **out, spx_uint32_t out_len) {\n   spx_uint32_t tmp_in_len = st->magic_samples[channel_index];\n   spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;\n   const int N = st->filt_len;\n   \n   speex_resampler_process_native(st, channel_index, &tmp_in_len, *out, &out_len);\n\n   st->magic_samples[channel_index] -= tmp_in_len;\n   \n   /* If we couldn't process all \"magic\" input samples, save the rest for next time */\n   if (st->magic_samples[channel_index])\n   {\n      spx_uint32_t i;\n      for (i=0;i<st->magic_samples[channel_index];i++)\n         mem[N-1+i]=mem[N-1+i+tmp_in_len];\n   }\n   *out += out_len*st->out_stride;\n   return out_len;\n}\n\n#ifdef FIXED_POINT\nEXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)\n#else\nEXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)\n#endif\n{\n   int j;\n   spx_uint32_t ilen = *in_len;\n   spx_uint32_t olen = *out_len;\n   spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size;\n   const int filt_offs = st->filt_len - 1;\n   const spx_uint32_t xlen = st->mem_alloc_size - filt_offs;\n   const int istride = st->in_stride;\n\n   if (st->magic_samples[channel_index]) \n      olen -= speex_resampler_magic(st, channel_index, &out, olen);\n   if (! st->magic_samples[channel_index]) {\n      while (ilen && olen) {\n        spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;\n        spx_uint32_t ochunk = olen;\n \n        if (in) {\n           for(j=0;j<ichunk;++j)\n              x[j+filt_offs]=in[j*istride];\n        } else {\n          for(j=0;j<ichunk;++j)\n            x[j+filt_offs]=0;\n        }\n        speex_resampler_process_native(st, channel_index, &ichunk, out, &ochunk);\n        ilen -= ichunk;\n        olen -= ochunk;\n        out += ochunk * st->out_stride;\n        if (in)\n           in += ichunk * istride;\n      }\n   }\n   *in_len -= ilen;\n   *out_len -= olen;\n   return RESAMPLER_ERR_SUCCESS;\n}\n\n#ifdef FIXED_POINT\nEXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)\n#else\nEXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)\n#endif\n{\n   int j;\n   const int istride_save = st->in_stride;\n   const int ostride_save = st->out_stride;\n   spx_uint32_t ilen = *in_len;\n   spx_uint32_t olen = *out_len;\n   spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size;\n   const spx_uint32_t xlen = st->mem_alloc_size - (st->filt_len - 1);\n#ifdef VAR_ARRAYS\n   const unsigned int ylen = (olen < FIXED_STACK_ALLOC) ? olen : FIXED_STACK_ALLOC;\n   VARDECL(spx_word16_t *ystack);\n   ALLOC(ystack, ylen, spx_word16_t);\n#else\n   const unsigned int ylen = FIXED_STACK_ALLOC;\n   spx_word16_t ystack[FIXED_STACK_ALLOC];\n#endif\n\n   st->out_stride = 1;\n   \n   while (ilen && olen) {\n     spx_word16_t *y = ystack;\n     spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;\n     spx_uint32_t ochunk = (olen > ylen) ? ylen : olen;\n     spx_uint32_t omagic = 0;\n\n     if (st->magic_samples[channel_index]) {\n       omagic = speex_resampler_magic(st, channel_index, &y, ochunk);\n       ochunk -= omagic;\n       olen -= omagic;\n     }\n     if (! st->magic_samples[channel_index]) {\n       if (in) {\n         for(j=0;j<ichunk;++j)\n#ifdef FIXED_POINT\n           x[j+st->filt_len-1]=WORD2INT(in[j*istride_save]);\n#else\n           x[j+st->filt_len-1]=in[j*istride_save];\n#endif\n       } else {\n         for(j=0;j<ichunk;++j)\n           x[j+st->filt_len-1]=0;\n       }\n\n       speex_resampler_process_native(st, channel_index, &ichunk, y, &ochunk);\n     } else {\n       ichunk = 0;\n       ochunk = 0;\n     }\n\n     for (j=0;j<ochunk+omagic;++j)\n#ifdef FIXED_POINT\n        out[j*ostride_save] = ystack[j];\n#else\n        out[j*ostride_save] = WORD2INT(ystack[j]);\n#endif\n     \n     ilen -= ichunk;\n     olen -= ochunk;\n     out += (ochunk+omagic) * ostride_save;\n     if (in)\n       in += ichunk * istride_save;\n   }\n   st->out_stride = ostride_save;\n   *in_len -= ilen;\n   *out_len -= olen;\n\n   return RESAMPLER_ERR_SUCCESS;\n}\n\nEXPORT int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)\n{\n   spx_uint32_t i;\n   int istride_save, ostride_save;\n   spx_uint32_t bak_len = *out_len;\n   istride_save = st->in_stride;\n   ostride_save = st->out_stride;\n   st->in_stride = st->out_stride = st->nb_channels;\n   for (i=0;i<st->nb_channels;i++)\n   {\n      *out_len = bak_len;\n      if (in != NULL)\n         speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len);\n      else\n         speex_resampler_process_float(st, i, NULL, in_len, out+i, out_len);\n   }\n   st->in_stride = istride_save;\n   st->out_stride = ostride_save;\n   return RESAMPLER_ERR_SUCCESS;\n}\n               \nEXPORT int speex_resampler_process_interleaved_int(SpeexResamplerState *st, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)\n{\n   spx_uint32_t i;\n   int istride_save, ostride_save;\n   spx_uint32_t bak_len = *out_len;\n   istride_save = st->in_stride;\n   ostride_save = st->out_stride;\n   st->in_stride = st->out_stride = st->nb_channels;\n   for (i=0;i<st->nb_channels;i++)\n   {\n      *out_len = bak_len;\n      if (in != NULL)\n         speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len);\n      else\n         speex_resampler_process_int(st, i, NULL, in_len, out+i, out_len);\n   }\n   st->in_stride = istride_save;\n   st->out_stride = ostride_save;\n   return RESAMPLER_ERR_SUCCESS;\n}\n\nEXPORT int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate)\n{\n   return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate);\n}\n\nEXPORT void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate)\n{\n   *in_rate = st->in_rate;\n   *out_rate = st->out_rate;\n}\n\nEXPORT int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate)\n{\n   spx_uint32_t fact;\n   spx_uint32_t old_den;\n   spx_uint32_t i;\n   if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den)\n      return RESAMPLER_ERR_SUCCESS;\n   \n   old_den = st->den_rate;\n   st->in_rate = in_rate;\n   st->out_rate = out_rate;\n   st->num_rate = ratio_num;\n   st->den_rate = ratio_den;\n   /* FIXME: This is terribly inefficient, but who cares (at least for now)? */\n   for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++)\n   {\n      while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0))\n      {\n         st->num_rate /= fact;\n         st->den_rate /= fact;\n      }\n   }\n      \n   if (old_den > 0)\n   {\n      for (i=0;i<st->nb_channels;i++)\n      {\n         st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den;\n         /* Safety net */\n         if (st->samp_frac_num[i] >= st->den_rate)\n            st->samp_frac_num[i] = st->den_rate-1;\n      }\n   }\n   \n   if (st->initialised)\n      update_filter(st);\n   return RESAMPLER_ERR_SUCCESS;\n}\n\nEXPORT void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den)\n{\n   *ratio_num = st->num_rate;\n   *ratio_den = st->den_rate;\n}\n\nEXPORT int speex_resampler_set_quality(SpeexResamplerState *st, int quality)\n{\n   if (quality > 10 || quality < 0)\n      return RESAMPLER_ERR_INVALID_ARG;\n   if (st->quality == quality)\n      return RESAMPLER_ERR_SUCCESS;\n   st->quality = quality;\n   if (st->initialised)\n      update_filter(st);\n   return RESAMPLER_ERR_SUCCESS;\n}\n\nEXPORT void speex_resampler_get_quality(SpeexResamplerState *st, int *quality)\n{\n   *quality = st->quality;\n}\n\nEXPORT void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride)\n{\n   st->in_stride = stride;\n}\n\nEXPORT void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride)\n{\n   *stride = st->in_stride;\n}\n\nEXPORT void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride)\n{\n   st->out_stride = stride;\n}\n\nEXPORT void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride)\n{\n   *stride = st->out_stride;\n}\n\nEXPORT int speex_resampler_get_input_latency(SpeexResamplerState *st)\n{\n  return st->filt_len / 2;\n}\n\nEXPORT int speex_resampler_get_output_latency(SpeexResamplerState *st)\n{\n  return ((st->filt_len / 2) * st->den_rate + (st->num_rate >> 1)) / st->num_rate;\n}\n\nEXPORT int speex_resampler_skip_zeros(SpeexResamplerState *st)\n{\n   spx_uint32_t i;\n   for (i=0;i<st->nb_channels;i++)\n      st->last_sample[i] = st->filt_len/2;\n   return RESAMPLER_ERR_SUCCESS;\n}\n\nEXPORT int speex_resampler_reset_mem(SpeexResamplerState *st)\n{\n   spx_uint32_t i;\n   for (i=0;i<st->nb_channels*(st->filt_len-1);i++)\n      st->mem[i] = 0;\n   return RESAMPLER_ERR_SUCCESS;\n}\n\nEXPORT const char *speex_resampler_strerror(int err)\n{\n   switch (err)\n   {\n      case RESAMPLER_ERR_SUCCESS:\n         return \"Success.\";\n      case RESAMPLER_ERR_ALLOC_FAILED:\n         return \"Memory allocation failed.\";\n      case RESAMPLER_ERR_BAD_STATE:\n         return \"Bad resampler state.\";\n      case RESAMPLER_ERR_INVALID_ARG:\n         return \"Invalid argument.\";\n      case RESAMPLER_ERR_PTR_OVERLAP:\n         return \"Input and output buffers overlap.\";\n      default:\n         return \"Unknown error. Bad error code or strange version mismatch.\";\n   }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/resample_sse.h",
    "content": "/* Copyright (C) 2007-2008 Jean-Marc Valin\n * Copyright (C) 2008 Thorvald Natvig\n */\n/**\n   @file resample_sse.h\n   @brief Resampler functions (SSE version)\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#include <xmmintrin.h>\n\n#define OVERRIDE_INNER_PRODUCT_SINGLE\nstatic inline float inner_product_single(const float *a, const float *b, unsigned int len)\n{\n   int i;\n   float ret;\n   __m128 sum = _mm_setzero_ps();\n   for (i=0;i<len;i+=8)\n   {\n      sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i)));\n      sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4)));\n   }\n   sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));\n   sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));\n   _mm_store_ss(&ret, sum);\n   return ret;\n}\n\n#define OVERRIDE_INTERPOLATE_PRODUCT_SINGLE\nstatic inline float interpolate_product_single(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {\n  int i;\n  float ret;\n  __m128 sum = _mm_setzero_ps();\n  __m128 f = _mm_loadu_ps(frac);\n  for(i=0;i<len;i+=2)\n  {\n    sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample)));\n    sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample)));\n  }\n   sum = _mm_mul_ps(f, sum);\n   sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));\n   sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));\n   _mm_store_ss(&ret, sum);\n   return ret;\n}\n\n#ifdef _USE_SSE2\n#include <emmintrin.h>\n#define OVERRIDE_INNER_PRODUCT_DOUBLE\n\nstatic inline double inner_product_double(const float *a, const float *b, unsigned int len)\n{\n   int i;\n   double ret;\n   __m128d sum = _mm_setzero_pd();\n   __m128 t;\n   for (i=0;i<len;i+=8)\n   {\n      t = _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i));\n      sum = _mm_add_pd(sum, _mm_cvtps_pd(t));\n      sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));\n\n      t = _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4));\n      sum = _mm_add_pd(sum, _mm_cvtps_pd(t));\n      sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));\n   }\n   sum = _mm_add_sd(sum, (__m128d) _mm_movehl_ps((__m128) sum, (__m128) sum));\n   _mm_store_sd(&ret, sum);\n   return ret;\n}\n\n#define OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE\nstatic inline double interpolate_product_double(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {\n  int i;\n  double ret;\n  __m128d sum;\n  __m128d sum1 = _mm_setzero_pd();\n  __m128d sum2 = _mm_setzero_pd();\n  __m128 f = _mm_loadu_ps(frac);\n  __m128d f1 = _mm_cvtps_pd(f);\n  __m128d f2 = _mm_cvtps_pd(_mm_movehl_ps(f,f));\n  __m128 t;\n  for(i=0;i<len;i+=2)\n  {\n    t = _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample));\n    sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));\n    sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));\n\n    t = _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample));\n    sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));\n    sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));\n  }\n  sum1 = _mm_mul_pd(f1, sum1);\n  sum2 = _mm_mul_pd(f2, sum2);\n  sum = _mm_add_pd(sum1, sum2);\n  sum = _mm_add_sd(sum, (__m128d) _mm_movehl_ps((__m128) sum, (__m128) sum));\n  _mm_store_sd(&ret, sum);\n  return ret;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/sb_celp.c",
    "content": "/* Copyright (C) 2002-2006 Jean-Marc Valin \n   File: sb_celp.c\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <math.h>\n#include \"sb_celp.h\"\n#include \"filters.h\"\n#include \"lpc.h\"\n#include \"lsp.h\"\n#include \"stack_alloc.h\"\n#include \"cb_search.h\"\n#include \"quant_lsp.h\"\n#include \"vq.h\"\n#include \"ltp.h\"\n#include \"arch.h\"\n#include \"math_approx.h\"\n#include \"os_support.h\"\n\n#ifndef NULL\n#define NULL 0\n#endif\n\n/* Default size for the encoder and decoder stack (can be changed at compile time).\n   This does not apply when using variable-size arrays or alloca. */\n#ifndef SB_ENC_STACK\n#define SB_ENC_STACK (10000*sizeof(spx_sig_t))\n#endif\n\n#ifndef SB_DEC_STACK\n#define SB_DEC_STACK (6000*sizeof(spx_sig_t))\n#endif\n\n\n#ifdef DISABLE_WIDEBAND\nvoid *sb_encoder_init(const SpeexMode *m)\n{\n   speex_fatal(\"Wideband and Ultra-wideband are disabled\");\n   return NULL;\n}\nvoid sb_encoder_destroy(void *state)\n{\n   speex_fatal(\"Wideband and Ultra-wideband are disabled\");\n}\nint sb_encode(void *state, void *vin, SpeexBits *bits)\n{\n   speex_fatal(\"Wideband and Ultra-wideband are disabled\");\n   return -2;\n}\nvoid *sb_decoder_init(const SpeexMode *m)\n{\n   speex_fatal(\"Wideband and Ultra-wideband are disabled\");\n   return NULL;\n}\nvoid sb_decoder_destroy(void *state)\n{\n   speex_fatal(\"Wideband and Ultra-wideband are disabled\");\n}\nint sb_decode(void *state, SpeexBits *bits, void *vout)\n{\n   speex_fatal(\"Wideband and Ultra-wideband are disabled\");\n   return -2;\n}\nint sb_encoder_ctl(void *state, int request, void *ptr)\n{\n   speex_fatal(\"Wideband and Ultra-wideband are disabled\");\n   return -2;\n}\nint sb_decoder_ctl(void *state, int request, void *ptr)\n{\n   speex_fatal(\"Wideband and Ultra-wideband are disabled\");\n   return -2;\n}\n#else\n\n\n#ifndef M_PI\n#define M_PI           3.14159265358979323846  /* pi */\n#endif\n\n#define sqr(x) ((x)*(x))\n\n#define SUBMODE(x) st->submodes[st->submodeID]->x\n\n#ifdef FIXED_POINT\nstatic const spx_word16_t gc_quant_bound[16] = {125, 164, 215, 282, 370, 484, 635, 832, 1090, 1428, 1871, 2452, 3213, 4210, 5516, 7228};\nstatic const spx_word16_t fold_quant_bound[32] = {\n   39, 44, 50, 57, 64, 73, 83, 94,\n   106, 120, 136, 154, 175, 198, 225, 255,\n   288, 327, 370, 420, 476, 539, 611, 692,\n   784, 889, 1007, 1141, 1293, 1465, 1660, 1881};\n#define LSP_MARGIN 410\n#define LSP_DELTA1 6553\n#define LSP_DELTA2 1638\n\n#else\n\nstatic const spx_word16_t gc_quant_bound[16] = {\n      0.97979, 1.28384, 1.68223, 2.20426, 2.88829, 3.78458, 4.95900, 6.49787, \n      8.51428, 11.15642, 14.61846, 19.15484, 25.09895, 32.88761, 43.09325, 56.46588};\nstatic const spx_word16_t fold_quant_bound[32] = {\n   0.30498, 0.34559, 0.39161, 0.44375, 0.50283, 0.56979, 0.64565, 0.73162,\n   0.82903, 0.93942, 1.06450, 1.20624, 1.36685, 1.54884, 1.75506, 1.98875,\n   2.25355, 2.55360, 2.89361, 3.27889, 3.71547, 4.21018, 4.77076, 5.40598,\n   6.12577, 6.94141, 7.86565, 8.91295, 10.09969, 11.44445, 12.96826, 14.69497};\n\n#define LSP_MARGIN .05\n#define LSP_DELTA1 .2\n#define LSP_DELTA2 .05\n\n#endif\n\n#define QMF_ORDER 64\n\n#ifdef FIXED_POINT\nstatic const spx_word16_t h0[64] = {2, -7, -7, 18, 15, -39, -25, 75, 35, -130, -41, 212, 38, -327, -17, 483, -32, -689, 124, 956, -283, -1307, 543, 1780, -973, -2467, 1733, 3633, -3339, -6409, 9059, 30153, 30153, 9059, -6409, -3339, 3633, 1733, -2467, -973, 1780, 543, -1307, -283, 956, 124, -689, -32, 483, -17, -327, 38, 212, -41, -130, 35, 75, -25, -39, 15, 18, -7, -7, 2};\n\n#else\nstatic const float h0[64] = {\n   3.596189e-05f, -0.0001123515f,\n   -0.0001104587f, 0.0002790277f,\n   0.0002298438f, -0.0005953563f,\n   -0.0003823631f, 0.00113826f,\n   0.0005308539f, -0.001986177f,\n   -0.0006243724f, 0.003235877f,\n   0.0005743159f, -0.004989147f,\n   -0.0002584767f, 0.007367171f,\n   -0.0004857935f, -0.01050689f,\n   0.001894714f, 0.01459396f,\n   -0.004313674f, -0.01994365f,\n   0.00828756f, 0.02716055f,\n   -0.01485397f, -0.03764973f,\n   0.026447f, 0.05543245f,\n   -0.05095487f, -0.09779096f,\n   0.1382363f, 0.4600981f,\n   0.4600981f, 0.1382363f,\n   -0.09779096f, -0.05095487f,\n   0.05543245f, 0.026447f,\n   -0.03764973f, -0.01485397f,\n   0.02716055f, 0.00828756f,\n   -0.01994365f, -0.004313674f,\n   0.01459396f, 0.001894714f,\n   -0.01050689f, -0.0004857935f,\n   0.007367171f, -0.0002584767f,\n   -0.004989147f, 0.0005743159f,\n   0.003235877f, -0.0006243724f,\n   -0.001986177f, 0.0005308539f,\n   0.00113826f, -0.0003823631f,\n   -0.0005953563f, 0.0002298438f,\n   0.0002790277f, -0.0001104587f,\n   -0.0001123515f, 3.596189e-05f\n};\n\n#endif\n\nextern const spx_word16_t lag_window[];\nextern const spx_word16_t lpc_window[];\n\n\nvoid *sb_encoder_init(const SpeexMode *m)\n{\n   int i;\n   spx_int32_t tmp;\n   SBEncState *st;\n   const SpeexSBMode *mode;\n\n   st = (SBEncState*)speex_alloc(sizeof(SBEncState));\n   if (!st)\n      return NULL;\n   st->mode = m;\n   mode = (const SpeexSBMode*)m->mode;\n\n\n   st->st_low = speex_encoder_init(mode->nb_mode);\n#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)\n   st->stack = NULL;\n#else\n   /*st->stack = (char*)speex_alloc_scratch(SB_ENC_STACK);*/\n   speex_encoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack);\n#endif\n\n   st->full_frame_size = 2*mode->frameSize;\n   st->frame_size = mode->frameSize;\n   st->subframeSize = mode->subframeSize;\n   st->nbSubframes = mode->frameSize/mode->subframeSize;\n   st->windowSize = st->frame_size+st->subframeSize;\n   st->lpcSize=mode->lpcSize;\n\n   st->encode_submode = 1;\n   st->submodes=mode->submodes;\n   st->submodeSelect = st->submodeID=mode->defaultSubmode;\n   \n   tmp=9;\n   speex_encoder_ctl(st->st_low, SPEEX_SET_QUALITY, &tmp);\n   tmp=1;\n   speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp);\n\n   st->lpc_floor = mode->lpc_floor;\n   st->gamma1=mode->gamma1;\n   st->gamma2=mode->gamma2;\n   st->first=1;\n\n   st->high=(spx_word16_t*)speex_alloc((st->windowSize-st->frame_size)*sizeof(spx_word16_t));\n\n   st->h0_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));\n   st->h1_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));\n\n   st->window= lpc_window;\n\n   st->lagWindow = lag_window;\n\n   st->old_lsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t));\n   st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t));\n   st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t));\n   st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));\n   st->exc_rms = (spx_word16_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word16_t));\n   st->innov_rms_save = NULL;\n   \n   st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));\n   st->mem_sp2 = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));\n   st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));\n\n   for (i=0;i<st->lpcSize;i++)\n      st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);\n\n#ifndef DISABLE_VBR\n   st->vbr_quality = 8;\n   st->vbr_enabled = 0;\n   st->vbr_max = 0;\n   st->vbr_max_high = 20000;  /* We just need a big value here */\n   st->vad_enabled = 0;\n   st->abr_enabled = 0;\n   st->relative_quality=0;\n#endif /* #ifndef DISABLE_VBR */\n\n   st->complexity=2;\n   speex_encoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);\n   st->sampling_rate*=2;\n#ifdef ENABLE_VALGRIND\n   VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));\n#endif\n   return st;\n}\n\nvoid sb_encoder_destroy(void *state)\n{\n   SBEncState *st=(SBEncState*)state;\n\n   speex_encoder_destroy(st->st_low);\n#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))\n   /*speex_free_scratch(st->stack);*/\n#endif\n\n   speex_free(st->high);\n\n   speex_free(st->h0_mem);\n   speex_free(st->h1_mem);\n\n   speex_free(st->old_lsp);\n   speex_free(st->old_qlsp);\n   speex_free(st->interp_qlpc);\n   speex_free(st->pi_gain);\n   speex_free(st->exc_rms);\n\n   speex_free(st->mem_sp);\n   speex_free(st->mem_sp2);\n   speex_free(st->mem_sw);\n\n   \n   speex_free(st);\n}\n\n\nint sb_encode(void *state, void *vin, SpeexBits *bits)\n{\n   SBEncState *st;\n   int i, roots, sub;\n   char *stack;\n   VARDECL(spx_mem_t *mem);\n   VARDECL(spx_sig_t *innov);\n   VARDECL(spx_word16_t *target);\n   VARDECL(spx_word16_t *syn_resp);\n   VARDECL(spx_word32_t *low_pi_gain);\n   spx_word16_t *low;\n   spx_word16_t *high;\n   VARDECL(spx_word16_t *low_exc_rms);\n   VARDECL(spx_word16_t *low_innov_rms);\n   const SpeexSBMode *mode;\n   spx_int32_t dtx;\n   spx_word16_t *in = (spx_word16_t*)vin;\n   spx_word16_t e_low=0, e_high=0;\n   VARDECL(spx_coef_t *lpc);\n   VARDECL(spx_coef_t *interp_lpc);\n   VARDECL(spx_coef_t *bw_lpc1);\n   VARDECL(spx_coef_t *bw_lpc2);\n   VARDECL(spx_lsp_t *lsp);\n   VARDECL(spx_lsp_t *qlsp);\n   VARDECL(spx_lsp_t *interp_lsp);\n   VARDECL(spx_lsp_t *interp_qlsp);\n      \n   st = (SBEncState*)state;\n   stack=st->stack;\n   mode = (const SpeexSBMode*)(st->mode->mode);\n   low = in;\n   high = in+st->frame_size;\n   \n   /* High-band buffering / sync with low band */\n   /* Compute the two sub-bands by filtering with QMF h0*/\n   qmf_decomp(in, h0, low, high, st->full_frame_size, QMF_ORDER, st->h0_mem, stack);\n   \n#ifndef DISABLE_VBR\n   if (st->vbr_enabled || st->vad_enabled)\n   {\n      /* Need to compute things here before the signal is trashed by the encoder */\n      /*FIXME: Are the two signals (low, high) in sync? */\n      e_low = compute_rms16(low, st->frame_size);\n      e_high = compute_rms16(high, st->frame_size);\n   }\n#endif /* #ifndef DISABLE_VBR */\n\n   ALLOC(low_innov_rms, st->nbSubframes, spx_word16_t);\n   speex_encoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_rms);\n   /* Encode the narrowband part*/\n   speex_encode_native(st->st_low, low, bits);\n\n   high = high - (st->windowSize-st->frame_size);\n   SPEEX_COPY(high, st->high, st->windowSize-st->frame_size);\n   SPEEX_COPY(st->high, &high[st->frame_size], st->windowSize-st->frame_size);\n   \n\n   ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t);\n   ALLOC(low_exc_rms, st->nbSubframes, spx_word16_t);\n   speex_encoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain);\n   speex_encoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc_rms);\n   \n   speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, &dtx);\n\n   if (dtx==0)\n      dtx=1;\n   else\n      dtx=0;\n\n   ALLOC(lpc, st->lpcSize, spx_coef_t);\n   ALLOC(interp_lpc, st->lpcSize, spx_coef_t);\n   ALLOC(bw_lpc1, st->lpcSize, spx_coef_t);\n   ALLOC(bw_lpc2, st->lpcSize, spx_coef_t);\n   \n   ALLOC(lsp, st->lpcSize, spx_lsp_t);\n   ALLOC(qlsp, st->lpcSize, spx_lsp_t);\n   ALLOC(interp_lsp, st->lpcSize, spx_lsp_t);\n   ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);\n   \n   {\n      VARDECL(spx_word16_t *autocorr);\n      VARDECL(spx_word16_t *w_sig);\n      ALLOC(autocorr, st->lpcSize+1, spx_word16_t);\n      ALLOC(w_sig, st->windowSize, spx_word16_t);\n      /* Window for analysis */\n      /* FIXME: This is a kludge */\n      if (st->subframeSize==80)\n      {\n         for (i=0;i<st->windowSize;i++)\n            w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i>>1]),SIG_SHIFT));\n      } else {\n         for (i=0;i<st->windowSize;i++)\n            w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i]),SIG_SHIFT));\n      }\n      /* Compute auto-correlation */\n      _spx_autocorr(w_sig, autocorr, st->lpcSize+1, st->windowSize);\n      autocorr[0] = ADD16(autocorr[0],MULT16_16_Q15(autocorr[0],st->lpc_floor)); /* Noise floor in auto-correlation domain */\n\n      /* Lag windowing: equivalent to filtering in the power-spectrum domain */\n      for (i=0;i<st->lpcSize+1;i++)\n         autocorr[i] = MULT16_16_Q14(autocorr[i],st->lagWindow[i]);\n\n      /* Levinson-Durbin */\n      _spx_lpc(lpc, autocorr, st->lpcSize);\n   }\n\n   /* LPC to LSPs (x-domain) transform */\n   roots=lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA1, stack);\n   if (roots!=st->lpcSize)\n   {\n      roots = lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA2, stack);\n      if (roots!=st->lpcSize) {\n         /*If we can't find all LSP's, do some damage control and use a flat filter*/\n         for (i=0;i<st->lpcSize;i++)\n         {\n            lsp[i]=st->old_lsp[i];\n         }\n      }\n   }\n\n#ifndef DISABLE_VBR\n   /* VBR code */\n   if ((st->vbr_enabled || st->vad_enabled) && !dtx)\n   {\n      float ratio;\n      if (st->abr_enabled)\n      {\n         float qual_change=0;\n         if (st->abr_drift2 * st->abr_drift > 0)\n         {\n            /* Only adapt if long-term and short-term drift are the same sign */\n            qual_change = -.00001*st->abr_drift/(1+st->abr_count);\n            if (qual_change>.1)\n               qual_change=.1;\n            if (qual_change<-.1)\n               qual_change=-.1;\n         }\n         st->vbr_quality += qual_change;\n         if (st->vbr_quality>10)\n            st->vbr_quality=10;\n         if (st->vbr_quality<0)\n            st->vbr_quality=0;\n      }\n\n\n      ratio = 2*log((1.f+e_high)/(1.f+e_low));\n      \n      speex_encoder_ctl(st->st_low, SPEEX_GET_RELATIVE_QUALITY, &st->relative_quality);\n      if (ratio<-4)\n         ratio=-4;\n      if (ratio>2)\n         ratio=2;\n      /*if (ratio>-2)*/\n      if (st->vbr_enabled) \n      {\n         spx_int32_t modeid;\n         modeid = mode->nb_modes-1;\n         st->relative_quality+=1.0*(ratio+2);\n\t if (st->relative_quality<-1)\n            st->relative_quality=-1;\n         while (modeid)\n         {\n            int v1;\n            float thresh;\n            v1=(int)floor(st->vbr_quality);\n            if (v1==10)\n               thresh = mode->vbr_thresh[modeid][v1];\n            else\n               thresh = (st->vbr_quality-v1)   * mode->vbr_thresh[modeid][v1+1] + \n                        (1+v1-st->vbr_quality) * mode->vbr_thresh[modeid][v1];\n            if (st->relative_quality >= thresh && st->sampling_rate*st->submodes[modeid]->bits_per_frame/st->full_frame_size <= st->vbr_max_high)\n               break;\n            modeid--;\n         }\n         speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &modeid);\n         if (st->abr_enabled)\n         {\n            spx_int32_t bitrate;\n            speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate);\n            st->abr_drift+=(bitrate-st->abr_enabled);\n            st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled);\n            st->abr_count += 1.0;\n         }\n\n      } else {\n         /* VAD only */\n         int modeid;\n         if (st->relative_quality<2.0)\n            modeid=1;\n         else\n            modeid=st->submodeSelect;\n         /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/\n         st->submodeID=modeid;\n\n      }\n      /*fprintf (stderr, \"%f %f\\n\", ratio, low_qual);*/\n   }\n#endif /* #ifndef DISABLE_VBR */\n\n   if (st->encode_submode)\n   {\n      speex_bits_pack(bits, 1, 1);\n      if (dtx)\n         speex_bits_pack(bits, 0, SB_SUBMODE_BITS);\n      else\n         speex_bits_pack(bits, st->submodeID, SB_SUBMODE_BITS);\n   }\n\n   /* If null mode (no transmission), just set a couple things to zero*/\n   if (dtx || st->submodes[st->submodeID] == NULL)\n   {\n      for (i=0;i<st->frame_size;i++)\n         high[i]=VERY_SMALL;\n\n      for (i=0;i<st->lpcSize;i++)\n         st->mem_sw[i]=0;\n      st->first=1;\n\n      /* Final signal synthesis from excitation */\n      iir_mem16(high, st->interp_qlpc, high, st->frame_size, st->lpcSize, st->mem_sp, stack);\n\n      if (dtx)\n         return 0;\n      else\n         return 1;\n   }\n\n\n   /* LSP quantization */\n   SUBMODE(lsp_quant)(lsp, qlsp, st->lpcSize, bits);   \n\n   if (st->first)\n   {\n      for (i=0;i<st->lpcSize;i++)\n         st->old_lsp[i] = lsp[i];\n      for (i=0;i<st->lpcSize;i++)\n         st->old_qlsp[i] = qlsp[i];\n   }\n   \n   ALLOC(mem, st->lpcSize, spx_mem_t);\n   ALLOC(syn_resp, st->subframeSize, spx_word16_t);\n   ALLOC(innov, st->subframeSize, spx_sig_t);\n   ALLOC(target, st->subframeSize, spx_word16_t);\n\n   for (sub=0;sub<st->nbSubframes;sub++)\n   {\n      VARDECL(spx_word16_t *exc);\n      VARDECL(spx_word16_t *res);\n      VARDECL(spx_word16_t *sw);\n      spx_word16_t *sp;\n      spx_word16_t filter_ratio;     /*Q7*/\n      int offset;\n      spx_word32_t rl, rh;           /*Q13*/\n      spx_word16_t eh=0;\n\n      offset = st->subframeSize*sub;\n      sp=high+offset;\n      ALLOC(exc, st->subframeSize, spx_word16_t);\n      ALLOC(res, st->subframeSize, spx_word16_t);\n      ALLOC(sw, st->subframeSize, spx_word16_t);\n      \n      /* LSP interpolation (quantized and unquantized) */\n      lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, sub, st->nbSubframes);\n      lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);\n\n      lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN);\n      lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);\n\n      lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack);\n      lsp_to_lpc(interp_qlsp, st->interp_qlpc, st->lpcSize, stack);\n\n      bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize);\n      bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);\n\n      /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band\n         filters */\n      st->pi_gain[sub]=LPC_SCALING;\n      rh = LPC_SCALING;\n      for (i=0;i<st->lpcSize;i+=2)\n      {\n         rh += st->interp_qlpc[i+1] - st->interp_qlpc[i];\n         st->pi_gain[sub] += st->interp_qlpc[i] + st->interp_qlpc[i+1];\n      }\n      \n      rl = low_pi_gain[sub];\n#ifdef FIXED_POINT\n      filter_ratio=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767));\n#else\n      filter_ratio=(rl+.01)/(rh+.01);\n#endif\n      \n      /* Compute \"real excitation\" */\n      fir_mem16(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2, stack);\n      /* Compute energy of low-band and high-band excitation */\n\n      eh = compute_rms16(exc, st->subframeSize);\n\n      if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */\n         spx_word32_t g;   /*Q7*/\n         spx_word16_t el;  /*Q0*/\n         el = low_innov_rms[sub];\n\n         /* Gain to use if we want to use the low-band excitation for high-band */\n         g=PDIV32(MULT16_16(filter_ratio,eh),EXTEND32(ADD16(1,el)));\n         \n#if 0\n         {\n            char *tmp_stack=stack;\n            float *tmp_sig;\n            float g2;\n            ALLOC(tmp_sig, st->subframeSize, spx_sig_t);\n            for (i=0;i<st->lpcSize;i++)\n               mem[i]=st->mem_sp[i];\n            iir_mem2(st->low_innov+offset, st->interp_qlpc, tmp_sig, st->subframeSize, st->lpcSize, mem);\n            g2 = compute_rms(sp, st->subframeSize)/(.01+compute_rms(tmp_sig, st->subframeSize));\n            /*fprintf (stderr, \"gains: %f %f\\n\", g, g2);*/\n            g = g2;\n            stack = tmp_stack;\n         }\n#endif\n\n         /*print_vec(&g, 1, \"gain factor\");*/\n         /* Gain quantization */\n         {\n            int quant = scal_quant(g, fold_quant_bound, 32);\n            /*speex_warning_int(\"tata\", quant);*/\n            if (quant<0)\n               quant=0;\n            if (quant>31)\n               quant=31;\n            speex_bits_pack(bits, quant, 5);\n         }\n         if (st->innov_rms_save)\n         {\n            st->innov_rms_save[sub] = eh;\n         }\n         st->exc_rms[sub] = eh;\n      } else {\n         spx_word16_t gc;       /*Q7*/\n         spx_word32_t scale;    /*Q14*/\n         spx_word16_t el;       /*Q0*/\n         el = low_exc_rms[sub]; /*Q0*/\n\n         gc = PDIV32_16(MULT16_16(filter_ratio,1+eh),1+el);\n\n         /* This is a kludge that cleans up a historical bug */\n         if (st->subframeSize==80)\n            gc = MULT16_16_P15(QCONST16(0.70711f,15),gc);\n         /*printf (\"%f %f %f %f\\n\", el, eh, filter_ratio, gc);*/\n         {\n            int qgc = scal_quant(gc, gc_quant_bound, 16);\n            speex_bits_pack(bits, qgc, 4);\n            gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]);\n         }\n         if (st->subframeSize==80)\n            gc = MULT16_16_P14(QCONST16(1.4142f,14), gc);\n\n         scale = SHL32(MULT16_16(PDIV32_16(SHL32(EXTEND32(gc),SIG_SHIFT-6),filter_ratio),(1+el)),6);\n\n         compute_impulse_response(st->interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack);\n\n         \n         /* Reset excitation */\n         for (i=0;i<st->subframeSize;i++)\n            res[i]=VERY_SMALL;\n         \n         /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */\n         for (i=0;i<st->lpcSize;i++)\n            mem[i]=st->mem_sp[i];\n         iir_mem16(res, st->interp_qlpc, res, st->subframeSize, st->lpcSize, mem, stack);\n\n         for (i=0;i<st->lpcSize;i++)\n            mem[i]=st->mem_sw[i];\n         filter_mem16(res, bw_lpc1, bw_lpc2, res, st->subframeSize, st->lpcSize, mem, stack);\n\n         /* Compute weighted signal */\n         for (i=0;i<st->lpcSize;i++)\n            mem[i]=st->mem_sw[i];\n         filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, mem, stack);\n\n         /* Compute target signal */\n         for (i=0;i<st->subframeSize;i++)\n            target[i]=SUB16(sw[i],res[i]);\n\n         signal_div(target, target, scale, st->subframeSize);\n\n         /* Reset excitation */\n         SPEEX_MEMSET(innov, 0, st->subframeSize);\n\n         /*print_vec(target, st->subframeSize, \"\\ntarget\");*/\n         SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2, \n                                   SUBMODE(innovation_params), st->lpcSize, st->subframeSize, \n                                   innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook));\n         /*print_vec(target, st->subframeSize, \"after\");*/\n\n         signal_mul(innov, innov, scale, st->subframeSize);\n\n         if (SUBMODE(double_codebook)) {\n            char *tmp_stack=stack;\n            VARDECL(spx_sig_t *innov2);\n            ALLOC(innov2, st->subframeSize, spx_sig_t);\n            SPEEX_MEMSET(innov2, 0, st->subframeSize);\n            for (i=0;i<st->subframeSize;i++)\n               target[i]=MULT16_16_P13(QCONST16(2.5f,13), target[i]);\n\n            SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2, \n                                      SUBMODE(innovation_params), st->lpcSize, st->subframeSize, \n                                      innov2, syn_resp, bits, stack, st->complexity, 0);\n            signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize);\n\n            for (i=0;i<st->subframeSize;i++)\n               innov[i] = ADD32(innov[i],innov2[i]);\n            stack = tmp_stack;\n         }\n         for (i=0;i<st->subframeSize;i++)\n            exc[i] = PSHR32(innov[i],SIG_SHIFT);\n\n         if (st->innov_rms_save)\n         {\n            st->innov_rms_save[sub] = MULT16_16_Q15(QCONST16(.70711f, 15), compute_rms(innov, st->subframeSize));\n         }\n         st->exc_rms[sub] = compute_rms16(exc, st->subframeSize);\n         \n\n      }\n\n      \n      /*Keep the previous memory*/\n      for (i=0;i<st->lpcSize;i++)\n         mem[i]=st->mem_sp[i];\n      /* Final signal synthesis from excitation */\n      iir_mem16(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp, stack);\n      \n      /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */\n      filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw, stack);\n   }\n\n   for (i=0;i<st->lpcSize;i++)\n      st->old_lsp[i] = lsp[i];\n   for (i=0;i<st->lpcSize;i++)\n      st->old_qlsp[i] = qlsp[i];\n\n   st->first=0;\n\n   return 1;\n}\n\n\n\n\n\nvoid *sb_decoder_init(const SpeexMode *m)\n{\n   spx_int32_t tmp;\n   SBDecState *st;\n   const SpeexSBMode *mode;\n   st = (SBDecState*)speex_alloc(sizeof(SBDecState));\n   if (!st)\n      return NULL;\n   st->mode = m;\n   mode=(const SpeexSBMode*)m->mode;\n   st->encode_submode = 1;\n\n   st->st_low = speex_decoder_init(mode->nb_mode);\n#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)\n   st->stack = NULL;\n#else\n   /*st->stack = (char*)speex_alloc_scratch(SB_DEC_STACK);*/\n   speex_decoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack);\n#endif\n\n   st->full_frame_size = 2*mode->frameSize;\n   st->frame_size = mode->frameSize;\n   st->subframeSize = mode->subframeSize;\n   st->nbSubframes = mode->frameSize/mode->subframeSize;\n   st->lpcSize=mode->lpcSize;\n   speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);\n   st->sampling_rate*=2;\n   tmp=1;\n   speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp);\n\n   st->submodes=mode->submodes;\n   st->submodeID=mode->defaultSubmode;\n\n   st->first=1;\n\n   st->g0_mem = (spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));\n   st->g1_mem = (spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));\n\n   st->excBuf = (spx_word16_t*)speex_alloc((st->subframeSize)*sizeof(spx_word16_t));\n\n   st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));\n   st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t));\n\n   st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));\n   st->exc_rms = (spx_word16_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word16_t));\n   st->mem_sp = (spx_mem_t*)speex_alloc((2*st->lpcSize)*sizeof(spx_mem_t));\n   \n   st->innov_save = NULL;\n\n\n   st->lpc_enh_enabled=0;\n   st->seed = 1000;\n\n#ifdef ENABLE_VALGRIND\n   VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));\n#endif\n   return st;\n}\n\nvoid sb_decoder_destroy(void *state)\n{\n   SBDecState *st;\n   st = (SBDecState*)state;\n   speex_decoder_destroy(st->st_low);\n#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))\n   /*speex_free_scratch(st->stack);*/\n#endif\n\n   speex_free(st->g0_mem);\n   speex_free(st->g1_mem);\n   speex_free(st->excBuf);\n   speex_free(st->old_qlsp);\n   speex_free(st->interp_qlpc);\n   speex_free(st->pi_gain);\n   speex_free(st->exc_rms);\n   speex_free(st->mem_sp);\n\n   speex_free(state);\n}\n\nstatic void sb_decode_lost(SBDecState *st, spx_word16_t *out, int dtx, char *stack)\n{\n   int i;\n   int saved_modeid=0;\n\n   if (dtx)\n   {\n      saved_modeid=st->submodeID;\n      st->submodeID=1;\n   } else {\n      bw_lpc(QCONST16(0.99f,15), st->interp_qlpc, st->interp_qlpc, st->lpcSize);\n   }\n\n   st->first=1;\n   \n   \n   /* Final signal synthesis from excitation */\n   if (!dtx)\n   {\n      st->last_ener =  MULT16_16_Q15(QCONST16(.9f,15),st->last_ener);\n   }\n   for (i=0;i<st->frame_size;i++)\n      out[i+st->frame_size] = speex_rand(st->last_ener, &st->seed);\n\n   iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize, \n            st->mem_sp, stack);\n   \n   \n   /* Reconstruct the original */\n   qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);\n   if (dtx)\n   {\n      st->submodeID=saved_modeid;\n   }\n\n   return;\n}\n\nint sb_decode(void *state, SpeexBits *bits, void *vout)\n{\n   int i, sub;\n   SBDecState *st;\n   int wideband;\n   int ret;\n   char *stack;\n   VARDECL(spx_word32_t *low_pi_gain);\n   VARDECL(spx_word16_t *low_exc_rms);\n   VARDECL(spx_coef_t *ak);\n   VARDECL(spx_lsp_t *qlsp);\n   VARDECL(spx_lsp_t *interp_qlsp);\n   spx_int32_t dtx;\n   const SpeexSBMode *mode;\n   spx_word16_t *out = (spx_word16_t*)vout;\n   spx_word16_t *low_innov_alias;\n   spx_word32_t exc_ener_sum = 0;\n   \n   st = (SBDecState*)state;\n   stack=st->stack;\n   mode = (const SpeexSBMode*)(st->mode->mode);\n\n   low_innov_alias = out+st->frame_size;\n   speex_decoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_alias);\n   /* Decode the low-band */\n   ret = speex_decode_native(st->st_low, bits, out);\n\n   speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, &dtx);\n\n   /* If error decoding the narrowband part, propagate error */\n   if (ret!=0)\n   {\n      return ret;\n   }\n\n   if (!bits)\n   {\n      sb_decode_lost(st, out, dtx, stack);\n      return 0;\n   }\n\n   if (st->encode_submode)\n   {\n\n      /*Check \"wideband bit\"*/\n      if (speex_bits_remaining(bits)>0)\n         wideband = speex_bits_peek(bits);\n      else\n         wideband = 0;\n      if (wideband)\n      {\n         /*Regular wideband frame, read the submode*/\n         wideband = speex_bits_unpack_unsigned(bits, 1);\n         st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);\n      } else\n      {\n         /*Was a narrowband frame, set \"null submode\"*/\n         st->submodeID = 0;\n      }\n      if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL)\n      {\n         speex_notify(\"Invalid mode encountered. The stream is corrupted.\");\n         return -2;\n      }\n   }\n\n   /* If null mode (no transmission), just set a couple things to zero*/\n   if (st->submodes[st->submodeID] == NULL)\n   {\n      if (dtx)\n      {\n         sb_decode_lost(st, out, 1, stack);\n         return 0;\n      }\n\n      for (i=0;i<st->frame_size;i++)\n         out[st->frame_size+i]=VERY_SMALL;\n\n      st->first=1;\n\n      /* Final signal synthesis from excitation */\n      iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize, st->mem_sp, stack);\n\n      qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);\n\n      return 0;\n\n   }\n\n   ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t);\n   ALLOC(low_exc_rms, st->nbSubframes, spx_word16_t);\n   speex_decoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain);\n   speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc_rms);\n\n   ALLOC(qlsp, st->lpcSize, spx_lsp_t);\n   ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);\n   SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits);\n   \n   if (st->first)\n   {\n      for (i=0;i<st->lpcSize;i++)\n         st->old_qlsp[i] = qlsp[i];\n   }\n   \n   ALLOC(ak, st->lpcSize, spx_coef_t);\n\n   for (sub=0;sub<st->nbSubframes;sub++)\n   {\n      VARDECL(spx_word32_t *exc);\n      spx_word16_t *innov_save=NULL;\n      spx_word16_t *sp;\n      spx_word16_t filter_ratio;\n      spx_word16_t el=0;\n      int offset;\n      spx_word32_t rl=0,rh=0;\n      \n      offset = st->subframeSize*sub;\n      sp=out+st->frame_size+offset;\n      ALLOC(exc, st->subframeSize, spx_word32_t);\n      /* Pointer for saving innovation */\n      if (st->innov_save)\n      {\n         innov_save = st->innov_save+2*offset;\n         SPEEX_MEMSET(innov_save, 0, 2*st->subframeSize);\n      }\n      \n      /* LSP interpolation */\n      lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);\n\n      lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);\n\n      /* LSP to LPC */\n      lsp_to_lpc(interp_qlsp, ak, st->lpcSize, stack);\n\n      /* Calculate reponse ratio between the low and high filter in the middle\n         of the band (4000 Hz) */\n      \n         st->pi_gain[sub]=LPC_SCALING;\n         rh = LPC_SCALING;\n         for (i=0;i<st->lpcSize;i+=2)\n         {\n            rh += ak[i+1] - ak[i];\n            st->pi_gain[sub] += ak[i] + ak[i+1];\n         }\n\n         rl = low_pi_gain[sub];\n#ifdef FIXED_POINT\n         filter_ratio=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767));\n#else\n         filter_ratio=(rl+.01)/(rh+.01);\n#endif\n      \n      SPEEX_MEMSET(exc, 0, st->subframeSize);\n      if (!SUBMODE(innovation_unquant))\n      {\n         spx_word32_t g;\n         int quant;\n\n         quant = speex_bits_unpack_unsigned(bits, 5);\n         g= spx_exp(MULT16_16(QCONST16(.125f,11),(quant-10)));\n         \n         g = PDIV32(g, filter_ratio);\n         \n         for (i=0;i<st->subframeSize;i+=2)\n         {\n            exc[i]=SHL32(MULT16_32_P15(MULT16_16_Q15(mode->folding_gain,low_innov_alias[offset+i]),SHL32(g,6)),SIG_SHIFT);\n            exc[i+1]=NEG32(SHL32(MULT16_32_P15(MULT16_16_Q15(mode->folding_gain,low_innov_alias[offset+i+1]),SHL32(g,6)),SIG_SHIFT));\n         }\n         \n      } else {\n         spx_word16_t gc;\n         spx_word32_t scale;\n         int qgc = speex_bits_unpack_unsigned(bits, 4);\n         \n         el = low_exc_rms[sub];\n         gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]);\n\n         if (st->subframeSize==80)\n            gc = MULT16_16_P14(QCONST16(1.4142f,14),gc);\n\n         scale = SHL32(PDIV32(SHL32(MULT16_16(gc, el),3), filter_ratio),SIG_SHIFT-3);\n         SUBMODE(innovation_unquant)(exc, SUBMODE(innovation_params), st->subframeSize, \n                                     bits, stack, &st->seed);\n\n         signal_mul(exc,exc,scale,st->subframeSize);\n\n         if (SUBMODE(double_codebook)) {\n            char *tmp_stack=stack;\n            VARDECL(spx_sig_t *innov2);\n            ALLOC(innov2, st->subframeSize, spx_sig_t);\n            SPEEX_MEMSET(innov2, 0, st->subframeSize);\n            SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, \n                                        bits, stack, &st->seed);\n            signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize);\n            for (i=0;i<st->subframeSize;i++)\n               exc[i] = ADD32(exc[i],innov2[i]);\n            stack = tmp_stack;\n         }\n\n      }\n      \n      if (st->innov_save)\n      {\n         for (i=0;i<st->subframeSize;i++)\n            innov_save[2*i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT));\n      }\n      \n      iir_mem16(st->excBuf, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, \n               st->mem_sp, stack);\n      for (i=0;i<st->subframeSize;i++)\n         st->excBuf[i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT));\n      for (i=0;i<st->lpcSize;i++)\n         st->interp_qlpc[i] = ak[i];\n      st->exc_rms[sub] = compute_rms16(st->excBuf, st->subframeSize);\n      exc_ener_sum = ADD32(exc_ener_sum, DIV32(MULT16_16(st->exc_rms[sub],st->exc_rms[sub]), st->nbSubframes));\n   }\n   st->last_ener = spx_sqrt(exc_ener_sum);\n   \n   qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);\n   for (i=0;i<st->lpcSize;i++)\n      st->old_qlsp[i] = qlsp[i];\n\n   st->first=0;\n\n   return 0;\n}\n\n\nint sb_encoder_ctl(void *state, int request, void *ptr)\n{\n   SBEncState *st;\n   st=(SBEncState*)state;\n   switch(request)\n   {\n   case SPEEX_GET_FRAME_SIZE:\n      (*(spx_int32_t*)ptr) = st->full_frame_size;\n      break;\n   case SPEEX_SET_HIGH_MODE:\n      st->submodeSelect = st->submodeID = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_SET_LOW_MODE:\n      speex_encoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr);\n      break;\n   case SPEEX_SET_DTX:\n      speex_encoder_ctl(st->st_low, SPEEX_SET_DTX, ptr);\n      break;\n   case SPEEX_GET_DTX:\n      speex_encoder_ctl(st->st_low, SPEEX_GET_DTX, ptr);\n      break;\n   case SPEEX_GET_LOW_MODE:\n      speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);\n      break;\n   case SPEEX_SET_MODE:\n      speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr);\n      break;\n#ifndef DISABLE_VBR\n   case SPEEX_SET_VBR:\n      st->vbr_enabled = (*(spx_int32_t*)ptr);\n      speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr);\n      break;\n   case SPEEX_GET_VBR:\n      (*(spx_int32_t*)ptr) = st->vbr_enabled;\n      break;\n   case SPEEX_SET_VAD:\n      st->vad_enabled = (*(spx_int32_t*)ptr);\n      speex_encoder_ctl(st->st_low, SPEEX_SET_VAD, ptr);\n      break;\n   case SPEEX_GET_VAD:\n      (*(spx_int32_t*)ptr) = st->vad_enabled;\n      break;\n#endif /* #ifndef DISABLE_VBR */\n#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API)\n   case SPEEX_SET_VBR_QUALITY:\n      {\n         spx_int32_t q;\n         float qual = (*(float*)ptr)+.6;\n         st->vbr_quality = (*(float*)ptr);\n         if (qual>10)\n            qual=10;\n         q=(int)floor(.5+*(float*)ptr);\n         if (q>10)\n            q=10;\n         speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_QUALITY, &qual);\n         speex_encoder_ctl(state, SPEEX_SET_QUALITY, &q);\n         break;\n      }\n   case SPEEX_GET_VBR_QUALITY:\n      (*(float*)ptr) = st->vbr_quality;\n      break;\n#endif /* #if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */\n#ifndef DISABLE_VBR\n   case SPEEX_SET_ABR:\n      st->abr_enabled = (*(spx_int32_t*)ptr);\n      st->vbr_enabled = st->abr_enabled!=0;\n      speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, &st->vbr_enabled);\n      if (st->vbr_enabled) \n      {\n         spx_int32_t i=10, rate, target;\n         float vbr_qual;\n         target = (*(spx_int32_t*)ptr);\n         while (i>=0)\n         {\n            speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);\n            speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);\n            if (rate <= target)\n               break;\n            i--;\n         }\n         vbr_qual=i;\n         if (vbr_qual<0)\n            vbr_qual=0;\n         speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual);\n         st->abr_count=0;\n         st->abr_drift=0;\n         st->abr_drift2=0;\n      }\n      \n      break;\n   case SPEEX_GET_ABR:\n      (*(spx_int32_t*)ptr) = st->abr_enabled;\n      break;\n#endif /* #ifndef DISABLE_VBR */\n\n   case SPEEX_SET_QUALITY:\n      {\n         spx_int32_t nb_qual;\n         int quality = (*(spx_int32_t*)ptr);\n         if (quality < 0)\n            quality = 0;\n         if (quality > 10)\n            quality = 10;\n         st->submodeSelect = st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality];\n         nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality];\n         speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual);\n      }\n      break;\n   case SPEEX_SET_COMPLEXITY:\n      speex_encoder_ctl(st->st_low, SPEEX_SET_COMPLEXITY, ptr);\n      st->complexity = (*(spx_int32_t*)ptr);\n      if (st->complexity<1)\n         st->complexity=1;\n      break;\n   case SPEEX_GET_COMPLEXITY:\n      (*(spx_int32_t*)ptr) = st->complexity;\n      break;\n   case SPEEX_SET_BITRATE:\n      {\n         spx_int32_t i=10;\n         spx_int32_t rate, target;\n         target = (*(spx_int32_t*)ptr);\n         while (i>=0)\n         {\n            speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);\n            speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);\n            if (rate <= target)\n               break;\n            i--;\n         }\n      }\n      break;\n   case SPEEX_GET_BITRATE:\n      speex_encoder_ctl(st->st_low, request, ptr);\n      /*fprintf (stderr, \"before: %d\\n\", (*(int*)ptr));*/\n      if (st->submodes[st->submodeID])\n         (*(spx_int32_t*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;\n      else\n         (*(spx_int32_t*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;\n      /*fprintf (stderr, \"after: %d\\n\", (*(int*)ptr));*/\n      break;\n   case SPEEX_SET_SAMPLING_RATE:\n      {\n         spx_int32_t tmp=(*(spx_int32_t*)ptr);\n         st->sampling_rate = tmp;\n         tmp>>=1;\n         speex_encoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);\n      }\n      break;\n   case SPEEX_GET_SAMPLING_RATE:\n      (*(spx_int32_t*)ptr)=st->sampling_rate;\n      break;\n   case SPEEX_RESET_STATE:\n      {\n         int i;\n         st->first = 1;\n         for (i=0;i<st->lpcSize;i++)\n            st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);\n         for (i=0;i<st->lpcSize;i++)\n            st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0;\n         for (i=0;i<QMF_ORDER;i++)\n            st->h0_mem[i]=st->h1_mem[i]=0;\n      }\n      break;\n   case SPEEX_SET_SUBMODE_ENCODING:\n      st->encode_submode = (*(spx_int32_t*)ptr);\n      speex_encoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr);\n      break;\n   case SPEEX_GET_SUBMODE_ENCODING:\n      (*(spx_int32_t*)ptr) = st->encode_submode;\n      break;\n   case SPEEX_GET_LOOKAHEAD:\n      speex_encoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr);\n      (*(spx_int32_t*)ptr) = 2*(*(spx_int32_t*)ptr) + QMF_ORDER - 1;\n      break;\n   case SPEEX_SET_PLC_TUNING:\n      speex_encoder_ctl(st->st_low, SPEEX_SET_PLC_TUNING, ptr);\n      break;\n   case SPEEX_GET_PLC_TUNING:\n      speex_encoder_ctl(st->st_low, SPEEX_GET_PLC_TUNING, ptr);\n      break;\n#ifndef DISABLE_VBR\n   case SPEEX_SET_VBR_MAX_BITRATE:\n      {\n         st->vbr_max = (*(spx_int32_t*)ptr);\n         if (SPEEX_SET_VBR_MAX_BITRATE<1)\n         {\n            speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_MAX_BITRATE, &st->vbr_max);\n            st->vbr_max_high = 17600;\n         } else {\n            spx_int32_t low_rate;\n            if (st->vbr_max >= 42200)\n            {\n               st->vbr_max_high = 17600;\n            } else if (st->vbr_max >= 27800)\n            {\n               st->vbr_max_high = 9600;\n            } else if (st->vbr_max > 20600)\n            {\n               st->vbr_max_high = 5600;\n            } else {\n               st->vbr_max_high = 1800;\n            }\n            if (st->subframeSize==80)\n               st->vbr_max_high = 1800;\n            low_rate = st->vbr_max - st->vbr_max_high;\n            speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_MAX_BITRATE, &low_rate);\n         }\n      }\n      break;\n   case SPEEX_GET_VBR_MAX_BITRATE:\n      (*(spx_int32_t*)ptr) = st->vbr_max;\n      break;\n#endif /* #ifndef DISABLE_VBR */\n   case SPEEX_SET_HIGHPASS:\n      speex_encoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr);\n      break;\n   case SPEEX_GET_HIGHPASS:\n      speex_encoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr);\n      break;\n\n\n   /* This is all internal stuff past this point */\n   case SPEEX_GET_PI_GAIN:\n      {\n         int i;\n         spx_word32_t *g = (spx_word32_t*)ptr;\n         for (i=0;i<st->nbSubframes;i++)\n            g[i]=st->pi_gain[i];\n      }\n      break;\n   case SPEEX_GET_EXC:\n      {\n         int i;\n         for (i=0;i<st->nbSubframes;i++)\n            ((spx_word16_t*)ptr)[i] = st->exc_rms[i];\n      }\n      break;\n#ifndef DISABLE_VBR\n   case SPEEX_GET_RELATIVE_QUALITY:\n      (*(float*)ptr)=st->relative_quality;\n      break;\n#endif /* #ifndef DISABLE_VBR */\n   case SPEEX_SET_INNOVATION_SAVE:\n      st->innov_rms_save = (spx_word16_t*)ptr;\n      break;\n   case SPEEX_SET_WIDEBAND:\n      speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr);\n      break;\n   case SPEEX_GET_STACK:\n      *((char**)ptr) = st->stack;\n      break;\n   default:\n      speex_warning_int(\"Unknown nb_ctl request: \", request);\n      return -1;\n   }\n   return 0;\n}\n\nint sb_decoder_ctl(void *state, int request, void *ptr)\n{\n   SBDecState *st;\n   st=(SBDecState*)state;\n   switch(request)\n   {\n   case SPEEX_SET_HIGH_MODE:\n      st->submodeID = (*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_SET_LOW_MODE:\n      speex_decoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr);\n      break;\n   case SPEEX_GET_LOW_MODE:\n      speex_decoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);\n      break;\n   case SPEEX_GET_FRAME_SIZE:\n      (*(spx_int32_t*)ptr) = st->full_frame_size;\n      break;\n   case SPEEX_SET_ENH:\n      speex_decoder_ctl(st->st_low, request, ptr);\n      st->lpc_enh_enabled = *((spx_int32_t*)ptr);\n      break;\n   case SPEEX_GET_ENH:\n      *((spx_int32_t*)ptr) = st->lpc_enh_enabled;\n      break;\n   case SPEEX_SET_MODE:\n   case SPEEX_SET_QUALITY:\n      {\n         spx_int32_t nb_qual;\n         int quality = (*(spx_int32_t*)ptr);\n         if (quality < 0)\n            quality = 0;\n         if (quality > 10)\n            quality = 10;\n         st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality];\n         nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality];\n         speex_decoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual);\n      }\n      break;\n   case SPEEX_GET_BITRATE:\n      speex_decoder_ctl(st->st_low, request, ptr);\n      if (st->submodes[st->submodeID])\n         (*(spx_int32_t*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;\n      else\n         (*(spx_int32_t*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;\n      break;\n   case SPEEX_SET_SAMPLING_RATE:\n      {\n         spx_int32_t tmp=(*(spx_int32_t*)ptr);\n         st->sampling_rate = tmp;\n         tmp>>=1;\n         speex_decoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);\n      }\n      break;\n   case SPEEX_GET_SAMPLING_RATE:\n      (*(spx_int32_t*)ptr)=st->sampling_rate;\n      break;\n   case SPEEX_SET_HANDLER:\n      speex_decoder_ctl(st->st_low, SPEEX_SET_HANDLER, ptr);\n      break;\n   case SPEEX_SET_USER_HANDLER:\n      speex_decoder_ctl(st->st_low, SPEEX_SET_USER_HANDLER, ptr);\n      break;\n   case SPEEX_RESET_STATE:\n      {\n         int i;\n         for (i=0;i<2*st->lpcSize;i++)\n            st->mem_sp[i]=0;\n         for (i=0;i<QMF_ORDER;i++)\n            st->g0_mem[i]=st->g1_mem[i]=0;\n         st->last_ener=0;\n      }\n      break;\n   case SPEEX_SET_SUBMODE_ENCODING:\n      st->encode_submode = (*(spx_int32_t*)ptr);\n      speex_decoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr);\n      break;\n   case SPEEX_GET_SUBMODE_ENCODING:\n      (*(spx_int32_t*)ptr) = st->encode_submode;\n      break;\n   case SPEEX_GET_LOOKAHEAD:\n      speex_decoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr);\n      (*(spx_int32_t*)ptr) = 2*(*(spx_int32_t*)ptr);\n      break;\n   case SPEEX_SET_HIGHPASS:\n      speex_decoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr);\n      break;\n   case SPEEX_GET_HIGHPASS:\n      speex_decoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr);\n      break;\n   case SPEEX_GET_ACTIVITY:\n      speex_decoder_ctl(st->st_low, SPEEX_GET_ACTIVITY, ptr);\n      break;\n   case SPEEX_GET_PI_GAIN:\n      {\n         int i;\n         spx_word32_t *g = (spx_word32_t*)ptr;\n         for (i=0;i<st->nbSubframes;i++)\n            g[i]=st->pi_gain[i];\n      }\n      break;\n   case SPEEX_GET_EXC:\n      {\n         int i;\n         for (i=0;i<st->nbSubframes;i++)\n            ((spx_word16_t*)ptr)[i] = st->exc_rms[i];\n      }\n      break;\n   case SPEEX_GET_DTX_STATUS:\n      speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, ptr);\n      break;\n   case SPEEX_SET_INNOVATION_SAVE:\n      st->innov_save = (spx_word16_t*)ptr;\n      break;\n   case SPEEX_SET_WIDEBAND:\n      speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr);\n      break;\n   case SPEEX_GET_STACK:\n      *((char**)ptr) = st->stack;\n      break;\n   default:\n      speex_warning_int(\"Unknown nb_ctl request: \", request);\n      return -1;\n   }\n   return 0;\n}\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/sb_celp.h",
    "content": "/* Copyright (C) 2002-2006 Jean-Marc Valin */\n/**\n   @file sb_celp.h\n   @brief Sub-band CELP mode used for wideband encoding\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifndef SB_CELP_H\n#define SB_CELP_H\n\n#include \"modes.h\"\n#include <speex/speex_bits.h>\n#include \"nb_celp.h\"\n\n/**Structure representing the full state of the sub-band encoder*/\ntypedef struct SBEncState {\n   const SpeexMode *mode;         /**< Pointer to the mode (containing for vtable info) */\n   void *st_low;                  /**< State of the low-band (narrowband) encoder */\n   int    full_frame_size;        /**< Length of full-band frames*/\n   int    frame_size;             /**< Length of high-band frames*/\n   int    subframeSize;           /**< Length of high-band sub-frames*/\n   int    nbSubframes;            /**< Number of high-band sub-frames*/\n   int    windowSize;             /**< Length of high-band LPC window*/\n   int    lpcSize;                /**< Order of high-band LPC analysis */\n   int    first;                  /**< First frame? */\n   spx_word16_t  lpc_floor;       /**< Controls LPC analysis noise floor */\n   spx_word16_t  gamma1;          /**< Perceptual weighting coef 1 */\n   spx_word16_t  gamma2;          /**< Perceptual weighting coef 2 */\n\n   char  *stack;                  /**< Temporary allocation stack */\n   spx_word16_t *high;               /**< High-band signal (buffer) */\n   spx_word16_t *h0_mem, *h1_mem;\n\n   const spx_word16_t *window;    /**< LPC analysis window */\n   const spx_word16_t *lagWindow;       /**< Auto-correlation window */\n   spx_lsp_t *old_lsp;            /**< LSPs of previous frame */\n   spx_lsp_t *old_qlsp;           /**< Quantized LSPs of previous frame */\n   spx_coef_t *interp_qlpc;       /**< Interpolated quantized LPCs for current sub-frame */\n\n   spx_mem_t *mem_sp;             /**< Synthesis signal memory */\n   spx_mem_t *mem_sp2;\n   spx_mem_t *mem_sw;             /**< Perceptual signal memory */\n   spx_word32_t *pi_gain;\n   spx_word16_t *exc_rms;\n   spx_word16_t *innov_rms_save;         /**< If non-NULL, innovation is copied here */\n\n#ifndef DISABLE_VBR\n   float  vbr_quality;            /**< Quality setting for VBR encoding */\n   int    vbr_enabled;            /**< 1 for enabling VBR, 0 otherwise */\n   spx_int32_t vbr_max;           /**< Max bit-rate allowed in VBR mode (total) */\n   spx_int32_t vbr_max_high;      /**< Max bit-rate allowed in VBR mode for the high-band */\n   spx_int32_t abr_enabled;       /**< ABR setting (in bps), 0 if off */\n   float  abr_drift;\n   float  abr_drift2;\n   float  abr_count;\n   int    vad_enabled;            /**< 1 for enabling VAD, 0 otherwise */\n   float  relative_quality;\n#endif /* #ifndef DISABLE_VBR */\n   \n   int    encode_submode;\n   const SpeexSubmode * const *submodes;\n   int    submodeID;\n   int    submodeSelect;\n   int    complexity;\n   spx_int32_t sampling_rate;\n\n} SBEncState;\n\n\n/**Structure representing the full state of the sub-band decoder*/\ntypedef struct SBDecState {\n   const SpeexMode *mode;            /**< Pointer to the mode (containing for vtable info) */\n   void *st_low;               /**< State of the low-band (narrowband) encoder */\n   int    full_frame_size;\n   int    frame_size;\n   int    subframeSize;\n   int    nbSubframes;\n   int    lpcSize;\n   int    first;\n   spx_int32_t sampling_rate;\n   int    lpc_enh_enabled;\n\n   char  *stack;\n   spx_word16_t *g0_mem, *g1_mem;\n\n   spx_word16_t *excBuf;\n   spx_lsp_t *old_qlsp;\n   spx_coef_t *interp_qlpc;\n\n   spx_mem_t *mem_sp;\n   spx_word32_t *pi_gain;\n   spx_word16_t *exc_rms;\n   spx_word16_t *innov_save;      /** If non-NULL, innovation is copied here */\n   \n   spx_word16_t last_ener;\n   spx_int32_t seed;\n\n   int    encode_submode;\n   const SpeexSubmode * const *submodes;\n   int    submodeID;\n} SBDecState;\n\n\n/**Initializes encoder state*/\nvoid *sb_encoder_init(const SpeexMode *m);\n\n/**De-allocates encoder state resources*/\nvoid sb_encoder_destroy(void *state);\n\n/**Encodes one frame*/\nint sb_encode(void *state, void *in, SpeexBits *bits);\n\n\n/**Initializes decoder state*/\nvoid *sb_decoder_init(const SpeexMode *m);\n\n/**De-allocates decoder state resources*/\nvoid sb_decoder_destroy(void *state);\n\n/**Decodes one frame*/\nint sb_decode(void *state, SpeexBits *bits, void *out);\n\nint sb_encoder_ctl(void *state, int request, void *ptr);\n\nint sb_decoder_ctl(void *state, int request, void *ptr);\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/scal.c",
    "content": "/* Copyright (C) 2006-2008 CSIRO, Jean-Marc Valin, Xiph.Org Foundation\n\n   File: scal.c\n   Shaped comb-allpass filter for channel decorrelation\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/*\nThe algorithm implemented here is described in:\n\n* J.-M. Valin, Perceptually-Motivated Nonlinear Channel Decorrelation For \n  Stereo Acoustic Echo Cancellation, Accepted for Joint Workshop on \n  Hands­free Speech Communication and Microphone Arrays (HSCMA), 2008.\n  http://people.xiph.org/~jm/papers/valin_hscma2008.pdf\n\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"speex/speex_echo.h\"\n#include \"vorbis_psy.h\"\n#include \"arch.h\"\n#include \"os_support.h\"\n#include \"smallft.h\"\n#include <math.h>\n#include <stdlib.h>\n\n#define ALLPASS_ORDER 20\n\nstruct SpeexDecorrState_ {\n   int rate;\n   int channels;\n   int frame_size;\n#ifdef VORBIS_PSYCHO\n   VorbisPsy *psy;\n   struct drft_lookup lookup;\n   float *wola_mem;\n   float *curve;\n#endif\n   float *vorbis_win;\n   int    seed;\n   float *y;\n   \n   /* Per-channel stuff */\n   float *buff;\n   float (*ring)[ALLPASS_ORDER];\n   int *ringID;\n   int *order;\n   float *alpha;\n};\n\n\n\nEXPORT SpeexDecorrState *speex_decorrelate_new(int rate, int channels, int frame_size)\n{\n   int i, ch;\n   SpeexDecorrState *st = speex_alloc(sizeof(SpeexDecorrState));\n   st->rate = rate;\n   st->channels = channels;\n   st->frame_size = frame_size;\n#ifdef VORBIS_PSYCHO\n   st->psy = vorbis_psy_init(rate, 2*frame_size);\n   spx_drft_init(&st->lookup, 2*frame_size);\n   st->wola_mem = speex_alloc(frame_size*sizeof(float));\n   st->curve = speex_alloc(frame_size*sizeof(float));\n#endif\n   st->y = speex_alloc(frame_size*sizeof(float));\n\n   st->buff = speex_alloc(channels*2*frame_size*sizeof(float));\n   st->ringID = speex_alloc(channels*sizeof(int));\n   st->order = speex_alloc(channels*sizeof(int));\n   st->alpha = speex_alloc(channels*sizeof(float));\n   st->ring = speex_alloc(channels*ALLPASS_ORDER*sizeof(float));\n   \n   /*FIXME: The +20 is there only as a kludge for ALL_PASS_OLA*/\n   st->vorbis_win = speex_alloc((2*frame_size+20)*sizeof(float));\n   for (i=0;i<2*frame_size;i++)\n      st->vorbis_win[i] = sin(.5*M_PI* sin(M_PI*i/(2*frame_size))*sin(M_PI*i/(2*frame_size)) );\n   st->seed = rand();\n   \n   for (ch=0;ch<channels;ch++)\n   {\n      for (i=0;i<ALLPASS_ORDER;i++)\n         st->ring[ch][i] = 0;\n      st->ringID[ch] = 0;\n      st->alpha[ch] = 0;\n      st->order[ch] = 10;\n   }\n   return st;\n}\n\nstatic float uni_rand(int *seed)\n{\n   const unsigned int jflone = 0x3f800000;\n   const unsigned int jflmsk = 0x007fffff;\n   union {int i; float f;} ran;\n   *seed = 1664525 * *seed + 1013904223;\n   ran.i = jflone | (jflmsk & *seed);\n   ran.f -= 1.5;\n   return 2*ran.f;\n}\n\nstatic unsigned int irand(int *seed)\n{\n   *seed = 1664525 * *seed + 1013904223;\n   return ((unsigned int)*seed)>>16;\n}\n\n\nEXPORT void speex_decorrelate(SpeexDecorrState *st, const spx_int16_t *in, spx_int16_t *out, int strength)\n{\n   int ch;\n   float amount;\n   \n   if (strength<0)\n      strength = 0;\n   if (strength>100)\n      strength = 100;\n   \n   amount = .01*strength;\n   for (ch=0;ch<st->channels;ch++)\n   {\n      int i;\n      int N=2*st->frame_size;\n      float beta, beta2;\n      float *x;\n      float max_alpha = 0;\n      \n      float *buff;\n      float *ring;\n      int ringID;\n      int order;\n      float alpha;\n\n      buff = st->buff+ch*2*st->frame_size;\n      ring = st->ring[ch];\n      ringID = st->ringID[ch];\n      order = st->order[ch];\n      alpha = st->alpha[ch];\n      \n      for (i=0;i<st->frame_size;i++)\n         buff[i] = buff[i+st->frame_size];\n      for (i=0;i<st->frame_size;i++)\n         buff[i+st->frame_size] = in[i*st->channels+ch];\n\n      x = buff+st->frame_size;\n      beta = 1.-.3*amount*amount;\n      if (amount>1)\n         beta = 1-sqrt(.4*amount);\n      else\n         beta = 1-0.63246*amount;\n      if (beta<0)\n         beta = 0;\n   \n      beta2 = beta;\n      for (i=0;i<st->frame_size;i++)\n      {\n         st->y[i] = alpha*(x[i-ALLPASS_ORDER+order]-beta*x[i-ALLPASS_ORDER+order-1])*st->vorbis_win[st->frame_size+i+order] \n               + x[i-ALLPASS_ORDER]*st->vorbis_win[st->frame_size+i] \n               - alpha*(ring[ringID]\n               - beta*ring[ringID+1>=order?0:ringID+1]);\n         ring[ringID++]=st->y[i];\n         st->y[i] *= st->vorbis_win[st->frame_size+i];\n         if (ringID>=order)\n            ringID=0;\n      }\n      order = order+(irand(&st->seed)%3)-1;\n      if (order < 5)\n         order = 5;\n      if (order > 10)\n         order = 10;\n      /*order = 5+(irand(&st->seed)%6);*/\n      max_alpha = pow(.96+.04*(amount-1),order);\n      if (max_alpha > .98/(1.+beta2))\n         max_alpha = .98/(1.+beta2);\n   \n      alpha = alpha + .4*uni_rand(&st->seed);\n      if (alpha > max_alpha)\n         alpha = max_alpha;\n      if (alpha < -max_alpha)\n         alpha = -max_alpha;\n      for (i=0;i<ALLPASS_ORDER;i++)\n         ring[i] = 0;\n      ringID = 0;\n      for (i=0;i<st->frame_size;i++)\n      {\n         float tmp =  alpha*(x[i-ALLPASS_ORDER+order]-beta*x[i-ALLPASS_ORDER+order-1])*st->vorbis_win[i+order] \n               + x[i-ALLPASS_ORDER]*st->vorbis_win[i] \n               - alpha*(ring[ringID]\n               - beta*ring[ringID+1>=order?0:ringID+1]);\n         ring[ringID++]=tmp;\n         tmp *= st->vorbis_win[i];\n         if (ringID>=order)\n            ringID=0;\n         st->y[i] += tmp;\n      }\n   \n#ifdef VORBIS_PSYCHO\n      float frame[N];\n      float scale = 1./N;\n      for (i=0;i<2*st->frame_size;i++)\n         frame[i] = buff[i];\n   //float coef = .5*0.78130;\n      float coef = M_PI*0.075063 * 0.93763 * amount * .8 * 0.707;\n      compute_curve(st->psy, buff, st->curve);\n      for (i=1;i<st->frame_size;i++)\n      {\n         float x1,x2;\n         float gain;\n         do {\n            x1 = uni_rand(&st->seed);\n            x2 = uni_rand(&st->seed);\n         } while (x1*x1+x2*x2 > 1.);\n         gain = coef*sqrt(.1+st->curve[i]);\n         frame[2*i-1] = gain*x1;\n         frame[2*i] = gain*x2;\n      }\n      frame[0] = coef*uni_rand(&st->seed)*sqrt(.1+st->curve[0]);\n      frame[2*st->frame_size-1] = coef*uni_rand(&st->seed)*sqrt(.1+st->curve[st->frame_size-1]);\n      spx_drft_backward(&st->lookup,frame);\n      for (i=0;i<2*st->frame_size;i++)\n         frame[i] *= st->vorbis_win[i];\n#endif\n   \n      for (i=0;i<st->frame_size;i++)\n      {\n#ifdef VORBIS_PSYCHO\n         float tmp = st->y[i] + frame[i] + st->wola_mem[i];\n         st->wola_mem[i] = frame[i+st->frame_size];\n#else\n         float tmp = st->y[i];\n#endif\n         if (tmp>32767)\n            tmp = 32767;\n         if (tmp < -32767)\n            tmp = -32767;\n         out[i*st->channels+ch] = tmp;\n      }\n      \n      st->ringID[ch] = ringID;\n      st->order[ch] = order;\n      st->alpha[ch] = alpha;\n\n   }\n}\n\nEXPORT void speex_decorrelate_destroy(SpeexDecorrState *st)\n{\n#ifdef VORBIS_PSYCHO\n   vorbis_psy_destroy(st->psy);\n   speex_free(st->wola_mem);\n   speex_free(st->curve);\n#endif\n   speex_free(st->buff);\n   speex_free(st->ring);\n   speex_free(st->ringID);\n   speex_free(st->alpha);\n   speex_free(st->vorbis_win);\n   speex_free(st->order);\n   speex_free(st->y);\n   speex_free(st);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/smallft.c",
    "content": "/********************************************************************\n *                                                                  *\n * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *\n * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *\n * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *\n * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *\n *                                                                  *\n * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *\n * by the XIPHOPHORUS Company http://www.xiph.org/                  *\n *                                                                  *\n ********************************************************************\n\n function: *unnormalized* fft transform\n last mod: $Id: smallft.c 2002 2008-06-10 14:09:37Z nanang $\n\n ********************************************************************/\n\n/* FFT implementation from OggSquish, minus cosine transforms,\n * minus all but radix 2/4 case.  In Vorbis we only need this\n * cut-down version.\n *\n * To do more than just power-of-two sized vectors, see the full\n * version I wrote for NetLib.\n *\n * Note that the packing is a little strange; rather than the FFT r/i\n * packing following R_0, I_n, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1,\n * it follows R_0, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, I_n like the\n * FORTRAN version\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <math.h>\n#include \"smallft.h\"\n#include \"arch.h\"\n#include \"os_support.h\"\n\nstatic void drfti1(int n, float *wa, int *ifac){\n  static int ntryh[4] = { 4,2,3,5 };\n  static float tpi = 6.28318530717958648f;\n  float arg,argh,argld,fi;\n  int ntry=0,i,j=-1;\n  int k1, l1, l2, ib;\n  int ld, ii, ip, is, nq, nr;\n  int ido, ipm, nfm1;\n  int nl=n;\n  int nf=0;\n\n L101:\n  j++;\n  if (j < 4)\n    ntry=ntryh[j];\n  else\n    ntry+=2;\n\n L104:\n  nq=nl/ntry;\n  nr=nl-ntry*nq;\n  if (nr!=0) goto L101;\n\n  nf++;\n  ifac[nf+1]=ntry;\n  nl=nq;\n  if(ntry!=2)goto L107;\n  if(nf==1)goto L107;\n\n  for (i=1;i<nf;i++){\n    ib=nf-i+1;\n    ifac[ib+1]=ifac[ib];\n  }\n  ifac[2] = 2;\n\n L107:\n  if(nl!=1)goto L104;\n  ifac[0]=n;\n  ifac[1]=nf;\n  argh=tpi/n;\n  is=0;\n  nfm1=nf-1;\n  l1=1;\n\n  if(nfm1==0)return;\n\n  for (k1=0;k1<nfm1;k1++){\n    ip=ifac[k1+2];\n    ld=0;\n    l2=l1*ip;\n    ido=n/l2;\n    ipm=ip-1;\n\n    for (j=0;j<ipm;j++){\n      ld+=l1;\n      i=is;\n      argld=(float)ld*argh;\n      fi=0.f;\n      for (ii=2;ii<ido;ii+=2){\n\tfi+=1.f;\n\targ=fi*argld;\n\twa[i++]=cos(arg);\n\twa[i++]=sin(arg);\n      }\n      is+=ido;\n    }\n    l1=l2;\n  }\n}\n\nstatic void fdrffti(int n, float *wsave, int *ifac){\n\n  if (n == 1) return;\n  drfti1(n, wsave+n, ifac);\n}\n\nstatic void dradf2(int ido,int l1,float *cc,float *ch,float *wa1){\n  int i,k;\n  float ti2,tr2;\n  int t0,t1,t2,t3,t4,t5,t6;\n\n  t1=0;\n  t0=(t2=l1*ido);\n  t3=ido<<1;\n  for(k=0;k<l1;k++){\n    ch[t1<<1]=cc[t1]+cc[t2];\n    ch[(t1<<1)+t3-1]=cc[t1]-cc[t2];\n    t1+=ido;\n    t2+=ido;\n  }\n    \n  if(ido<2)return;\n  if(ido==2)goto L105;\n\n  t1=0;\n  t2=t0;\n  for(k=0;k<l1;k++){\n    t3=t2;\n    t4=(t1<<1)+(ido<<1);\n    t5=t1;\n    t6=t1+t1;\n    for(i=2;i<ido;i+=2){\n      t3+=2;\n      t4-=2;\n      t5+=2;\n      t6+=2;\n      tr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];\n      ti2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];\n      ch[t6]=cc[t5]+ti2;\n      ch[t4]=ti2-cc[t5];\n      ch[t6-1]=cc[t5-1]+tr2;\n      ch[t4-1]=cc[t5-1]-tr2;\n    }\n    t1+=ido;\n    t2+=ido;\n  }\n\n  if(ido%2==1)return;\n\n L105:\n  t3=(t2=(t1=ido)-1);\n  t2+=t0;\n  for(k=0;k<l1;k++){\n    ch[t1]=-cc[t2];\n    ch[t1-1]=cc[t3];\n    t1+=ido<<1;\n    t2+=ido;\n    t3+=ido;\n  }\n}\n\nstatic void dradf4(int ido,int l1,float *cc,float *ch,float *wa1,\n\t    float *wa2,float *wa3){\n  static float hsqt2 = .70710678118654752f;\n  int i,k,t0,t1,t2,t3,t4,t5,t6;\n  float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;\n  t0=l1*ido;\n  \n  t1=t0;\n  t4=t1<<1;\n  t2=t1+(t1<<1);\n  t3=0;\n\n  for(k=0;k<l1;k++){\n    tr1=cc[t1]+cc[t2];\n    tr2=cc[t3]+cc[t4];\n\n    ch[t5=t3<<2]=tr1+tr2;\n    ch[(ido<<2)+t5-1]=tr2-tr1;\n    ch[(t5+=(ido<<1))-1]=cc[t3]-cc[t4];\n    ch[t5]=cc[t2]-cc[t1];\n\n    t1+=ido;\n    t2+=ido;\n    t3+=ido;\n    t4+=ido;\n  }\n\n  if(ido<2)return;\n  if(ido==2)goto L105;\n\n\n  t1=0;\n  for(k=0;k<l1;k++){\n    t2=t1;\n    t4=t1<<2;\n    t5=(t6=ido<<1)+t4;\n    for(i=2;i<ido;i+=2){\n      t3=(t2+=2);\n      t4+=2;\n      t5-=2;\n\n      t3+=t0;\n      cr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];\n      ci2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];\n      t3+=t0;\n      cr3=wa2[i-2]*cc[t3-1]+wa2[i-1]*cc[t3];\n      ci3=wa2[i-2]*cc[t3]-wa2[i-1]*cc[t3-1];\n      t3+=t0;\n      cr4=wa3[i-2]*cc[t3-1]+wa3[i-1]*cc[t3];\n      ci4=wa3[i-2]*cc[t3]-wa3[i-1]*cc[t3-1];\n\n      tr1=cr2+cr4;\n      tr4=cr4-cr2;\n      ti1=ci2+ci4;\n      ti4=ci2-ci4;\n\n      ti2=cc[t2]+ci3;\n      ti3=cc[t2]-ci3;\n      tr2=cc[t2-1]+cr3;\n      tr3=cc[t2-1]-cr3;\n\n      ch[t4-1]=tr1+tr2;\n      ch[t4]=ti1+ti2;\n\n      ch[t5-1]=tr3-ti4;\n      ch[t5]=tr4-ti3;\n\n      ch[t4+t6-1]=ti4+tr3;\n      ch[t4+t6]=tr4+ti3;\n\n      ch[t5+t6-1]=tr2-tr1;\n      ch[t5+t6]=ti1-ti2;\n    }\n    t1+=ido;\n  }\n  if(ido&1)return;\n\n L105:\n  \n  t2=(t1=t0+ido-1)+(t0<<1);\n  t3=ido<<2;\n  t4=ido;\n  t5=ido<<1;\n  t6=ido;\n\n  for(k=0;k<l1;k++){\n    ti1=-hsqt2*(cc[t1]+cc[t2]);\n    tr1=hsqt2*(cc[t1]-cc[t2]);\n\n    ch[t4-1]=tr1+cc[t6-1];\n    ch[t4+t5-1]=cc[t6-1]-tr1;\n\n    ch[t4]=ti1-cc[t1+t0];\n    ch[t4+t5]=ti1+cc[t1+t0];\n\n    t1+=ido;\n    t2+=ido;\n    t4+=t3;\n    t6+=ido;\n  }\n}\n\nstatic void dradfg(int ido,int ip,int l1,int idl1,float *cc,float *c1,\n                          float *c2,float *ch,float *ch2,float *wa){\n\n  static float tpi=6.283185307179586f;\n  int idij,ipph,i,j,k,l,ic,ik,is;\n  int t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;\n  float dc2,ai1,ai2,ar1,ar2,ds2;\n  int nbd;\n  float dcp,arg,dsp,ar1h,ar2h;\n  int idp2,ipp2;\n  \n  arg=tpi/(float)ip;\n  dcp=cos(arg);\n  dsp=sin(arg);\n  ipph=(ip+1)>>1;\n  ipp2=ip;\n  idp2=ido;\n  nbd=(ido-1)>>1;\n  t0=l1*ido;\n  t10=ip*ido;\n\n  if(ido==1)goto L119;\n  for(ik=0;ik<idl1;ik++)ch2[ik]=c2[ik];\n\n  t1=0;\n  for(j=1;j<ip;j++){\n    t1+=t0;\n    t2=t1;\n    for(k=0;k<l1;k++){\n      ch[t2]=c1[t2];\n      t2+=ido;\n    }\n  }\n\n  is=-ido;\n  t1=0;\n  if(nbd>l1){\n    for(j=1;j<ip;j++){\n      t1+=t0;\n      is+=ido;\n      t2= -ido+t1;\n      for(k=0;k<l1;k++){\n        idij=is-1;\n        t2+=ido;\n        t3=t2;\n        for(i=2;i<ido;i+=2){\n          idij+=2;\n          t3+=2;\n          ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];\n          ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];\n        }\n      }\n    }\n  }else{\n\n    for(j=1;j<ip;j++){\n      is+=ido;\n      idij=is-1;\n      t1+=t0;\n      t2=t1;\n      for(i=2;i<ido;i+=2){\n        idij+=2;\n        t2+=2;\n        t3=t2;\n        for(k=0;k<l1;k++){\n          ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];\n          ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];\n          t3+=ido;\n        }\n      }\n    }\n  }\n\n  t1=0;\n  t2=ipp2*t0;\n  if(nbd<l1){\n    for(j=1;j<ipph;j++){\n      t1+=t0;\n      t2-=t0;\n      t3=t1;\n      t4=t2;\n      for(i=2;i<ido;i+=2){\n        t3+=2;\n        t4+=2;\n        t5=t3-ido;\n        t6=t4-ido;\n        for(k=0;k<l1;k++){\n          t5+=ido;\n          t6+=ido;\n          c1[t5-1]=ch[t5-1]+ch[t6-1];\n          c1[t6-1]=ch[t5]-ch[t6];\n          c1[t5]=ch[t5]+ch[t6];\n          c1[t6]=ch[t6-1]-ch[t5-1];\n        }\n      }\n    }\n  }else{\n    for(j=1;j<ipph;j++){\n      t1+=t0;\n      t2-=t0;\n      t3=t1;\n      t4=t2;\n      for(k=0;k<l1;k++){\n        t5=t3;\n        t6=t4;\n        for(i=2;i<ido;i+=2){\n          t5+=2;\n          t6+=2;\n          c1[t5-1]=ch[t5-1]+ch[t6-1];\n          c1[t6-1]=ch[t5]-ch[t6];\n          c1[t5]=ch[t5]+ch[t6];\n          c1[t6]=ch[t6-1]-ch[t5-1];\n        }\n        t3+=ido;\n        t4+=ido;\n      }\n    }\n  }\n\nL119:\n  for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];\n\n  t1=0;\n  t2=ipp2*idl1;\n  for(j=1;j<ipph;j++){\n    t1+=t0;\n    t2-=t0;\n    t3=t1-ido;\n    t4=t2-ido;\n    for(k=0;k<l1;k++){\n      t3+=ido;\n      t4+=ido;\n      c1[t3]=ch[t3]+ch[t4];\n      c1[t4]=ch[t4]-ch[t3];\n    }\n  }\n\n  ar1=1.f;\n  ai1=0.f;\n  t1=0;\n  t2=ipp2*idl1;\n  t3=(ip-1)*idl1;\n  for(l=1;l<ipph;l++){\n    t1+=idl1;\n    t2-=idl1;\n    ar1h=dcp*ar1-dsp*ai1;\n    ai1=dcp*ai1+dsp*ar1;\n    ar1=ar1h;\n    t4=t1;\n    t5=t2;\n    t6=t3;\n    t7=idl1;\n\n    for(ik=0;ik<idl1;ik++){\n      ch2[t4++]=c2[ik]+ar1*c2[t7++];\n      ch2[t5++]=ai1*c2[t6++];\n    }\n\n    dc2=ar1;\n    ds2=ai1;\n    ar2=ar1;\n    ai2=ai1;\n\n    t4=idl1;\n    t5=(ipp2-1)*idl1;\n    for(j=2;j<ipph;j++){\n      t4+=idl1;\n      t5-=idl1;\n\n      ar2h=dc2*ar2-ds2*ai2;\n      ai2=dc2*ai2+ds2*ar2;\n      ar2=ar2h;\n\n      t6=t1;\n      t7=t2;\n      t8=t4;\n      t9=t5;\n      for(ik=0;ik<idl1;ik++){\n        ch2[t6++]+=ar2*c2[t8++];\n        ch2[t7++]+=ai2*c2[t9++];\n      }\n    }\n  }\n\n  t1=0;\n  for(j=1;j<ipph;j++){\n    t1+=idl1;\n    t2=t1;\n    for(ik=0;ik<idl1;ik++)ch2[ik]+=c2[t2++];\n  }\n\n  if(ido<l1)goto L132;\n\n  t1=0;\n  t2=0;\n  for(k=0;k<l1;k++){\n    t3=t1;\n    t4=t2;\n    for(i=0;i<ido;i++)cc[t4++]=ch[t3++];\n    t1+=ido;\n    t2+=t10;\n  }\n\n  goto L135;\n\n L132:\n  for(i=0;i<ido;i++){\n    t1=i;\n    t2=i;\n    for(k=0;k<l1;k++){\n      cc[t2]=ch[t1];\n      t1+=ido;\n      t2+=t10;\n    }\n  }\n\n L135:\n  t1=0;\n  t2=ido<<1;\n  t3=0;\n  t4=ipp2*t0;\n  for(j=1;j<ipph;j++){\n\n    t1+=t2;\n    t3+=t0;\n    t4-=t0;\n\n    t5=t1;\n    t6=t3;\n    t7=t4;\n\n    for(k=0;k<l1;k++){\n      cc[t5-1]=ch[t6];\n      cc[t5]=ch[t7];\n      t5+=t10;\n      t6+=ido;\n      t7+=ido;\n    }\n  }\n\n  if(ido==1)return;\n  if(nbd<l1)goto L141;\n\n  t1=-ido;\n  t3=0;\n  t4=0;\n  t5=ipp2*t0;\n  for(j=1;j<ipph;j++){\n    t1+=t2;\n    t3+=t2;\n    t4+=t0;\n    t5-=t0;\n    t6=t1;\n    t7=t3;\n    t8=t4;\n    t9=t5;\n    for(k=0;k<l1;k++){\n      for(i=2;i<ido;i+=2){\n        ic=idp2-i;\n        cc[i+t7-1]=ch[i+t8-1]+ch[i+t9-1];\n        cc[ic+t6-1]=ch[i+t8-1]-ch[i+t9-1];\n        cc[i+t7]=ch[i+t8]+ch[i+t9];\n        cc[ic+t6]=ch[i+t9]-ch[i+t8];\n      }\n      t6+=t10;\n      t7+=t10;\n      t8+=ido;\n      t9+=ido;\n    }\n  }\n  return;\n\n L141:\n\n  t1=-ido;\n  t3=0;\n  t4=0;\n  t5=ipp2*t0;\n  for(j=1;j<ipph;j++){\n    t1+=t2;\n    t3+=t2;\n    t4+=t0;\n    t5-=t0;\n    for(i=2;i<ido;i+=2){\n      t6=idp2+t1-i;\n      t7=i+t3;\n      t8=i+t4;\n      t9=i+t5;\n      for(k=0;k<l1;k++){\n        cc[t7-1]=ch[t8-1]+ch[t9-1];\n        cc[t6-1]=ch[t8-1]-ch[t9-1];\n        cc[t7]=ch[t8]+ch[t9];\n        cc[t6]=ch[t9]-ch[t8];\n        t6+=t10;\n        t7+=t10;\n        t8+=ido;\n        t9+=ido;\n      }\n    }\n  }\n}\n\nstatic void drftf1(int n,float *c,float *ch,float *wa,int *ifac){\n  int i,k1,l1,l2;\n  int na,kh,nf;\n  int ip,iw,ido,idl1,ix2,ix3;\n\n  nf=ifac[1];\n  na=1;\n  l2=n;\n  iw=n;\n\n  for(k1=0;k1<nf;k1++){\n    kh=nf-k1;\n    ip=ifac[kh+1];\n    l1=l2/ip;\n    ido=n/l2;\n    idl1=ido*l1;\n    iw-=(ip-1)*ido;\n    na=1-na;\n\n    if(ip!=4)goto L102;\n\n    ix2=iw+ido;\n    ix3=ix2+ido;\n    if(na!=0)\n      dradf4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);\n    else\n      dradf4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);\n    goto L110;\n\n L102:\n    if(ip!=2)goto L104;\n    if(na!=0)goto L103;\n\n    dradf2(ido,l1,c,ch,wa+iw-1);\n    goto L110;\n\n  L103:\n    dradf2(ido,l1,ch,c,wa+iw-1);\n    goto L110;\n\n  L104:\n    if(ido==1)na=1-na;\n    if(na!=0)goto L109;\n\n    dradfg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);\n    na=1;\n    goto L110;\n\n  L109:\n    dradfg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);\n    na=0;\n\n  L110:\n    l2=l1;\n  }\n\n  if(na==1)return;\n\n  for(i=0;i<n;i++)c[i]=ch[i];\n}\n\nstatic void dradb2(int ido,int l1,float *cc,float *ch,float *wa1){\n  int i,k,t0,t1,t2,t3,t4,t5,t6;\n  float ti2,tr2;\n\n  t0=l1*ido;\n  \n  t1=0;\n  t2=0;\n  t3=(ido<<1)-1;\n  for(k=0;k<l1;k++){\n    ch[t1]=cc[t2]+cc[t3+t2];\n    ch[t1+t0]=cc[t2]-cc[t3+t2];\n    t2=(t1+=ido)<<1;\n  }\n\n  if(ido<2)return;\n  if(ido==2)goto L105;\n\n  t1=0;\n  t2=0;\n  for(k=0;k<l1;k++){\n    t3=t1;\n    t5=(t4=t2)+(ido<<1);\n    t6=t0+t1;\n    for(i=2;i<ido;i+=2){\n      t3+=2;\n      t4+=2;\n      t5-=2;\n      t6+=2;\n      ch[t3-1]=cc[t4-1]+cc[t5-1];\n      tr2=cc[t4-1]-cc[t5-1];\n      ch[t3]=cc[t4]-cc[t5];\n      ti2=cc[t4]+cc[t5];\n      ch[t6-1]=wa1[i-2]*tr2-wa1[i-1]*ti2;\n      ch[t6]=wa1[i-2]*ti2+wa1[i-1]*tr2;\n    }\n    t2=(t1+=ido)<<1;\n  }\n\n  if(ido%2==1)return;\n\nL105:\n  t1=ido-1;\n  t2=ido-1;\n  for(k=0;k<l1;k++){\n    ch[t1]=cc[t2]+cc[t2];\n    ch[t1+t0]=-(cc[t2+1]+cc[t2+1]);\n    t1+=ido;\n    t2+=ido<<1;\n  }\n}\n\nstatic void dradb3(int ido,int l1,float *cc,float *ch,float *wa1,\n                          float *wa2){\n  static float taur = -.5f;\n  static float taui = .8660254037844386f;\n  int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;\n  float ci2,ci3,di2,di3,cr2,cr3,dr2,dr3,ti2,tr2;\n  t0=l1*ido;\n\n  t1=0;\n  t2=t0<<1;\n  t3=ido<<1;\n  t4=ido+(ido<<1);\n  t5=0;\n  for(k=0;k<l1;k++){\n    tr2=cc[t3-1]+cc[t3-1];\n    cr2=cc[t5]+(taur*tr2);\n    ch[t1]=cc[t5]+tr2;\n    ci3=taui*(cc[t3]+cc[t3]);\n    ch[t1+t0]=cr2-ci3;\n    ch[t1+t2]=cr2+ci3;\n    t1+=ido;\n    t3+=t4;\n    t5+=t4;\n  }\n\n  if(ido==1)return;\n\n  t1=0;\n  t3=ido<<1;\n  for(k=0;k<l1;k++){\n    t7=t1+(t1<<1);\n    t6=(t5=t7+t3);\n    t8=t1;\n    t10=(t9=t1+t0)+t0;\n\n    for(i=2;i<ido;i+=2){\n      t5+=2;\n      t6-=2;\n      t7+=2;\n      t8+=2;\n      t9+=2;\n      t10+=2;\n      tr2=cc[t5-1]+cc[t6-1];\n      cr2=cc[t7-1]+(taur*tr2);\n      ch[t8-1]=cc[t7-1]+tr2;\n      ti2=cc[t5]-cc[t6];\n      ci2=cc[t7]+(taur*ti2);\n      ch[t8]=cc[t7]+ti2;\n      cr3=taui*(cc[t5-1]-cc[t6-1]);\n      ci3=taui*(cc[t5]+cc[t6]);\n      dr2=cr2-ci3;\n      dr3=cr2+ci3;\n      di2=ci2+cr3;\n      di3=ci2-cr3;\n      ch[t9-1]=wa1[i-2]*dr2-wa1[i-1]*di2;\n      ch[t9]=wa1[i-2]*di2+wa1[i-1]*dr2;\n      ch[t10-1]=wa2[i-2]*dr3-wa2[i-1]*di3;\n      ch[t10]=wa2[i-2]*di3+wa2[i-1]*dr3;\n    }\n    t1+=ido;\n  }\n}\n\nstatic void dradb4(int ido,int l1,float *cc,float *ch,float *wa1,\n\t\t\t  float *wa2,float *wa3){\n  static float sqrt2=1.414213562373095f;\n  int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8;\n  float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;\n  t0=l1*ido;\n  \n  t1=0;\n  t2=ido<<2;\n  t3=0;\n  t6=ido<<1;\n  for(k=0;k<l1;k++){\n    t4=t3+t6;\n    t5=t1;\n    tr3=cc[t4-1]+cc[t4-1];\n    tr4=cc[t4]+cc[t4]; \n    tr1=cc[t3]-cc[(t4+=t6)-1];\n    tr2=cc[t3]+cc[t4-1];\n    ch[t5]=tr2+tr3;\n    ch[t5+=t0]=tr1-tr4;\n    ch[t5+=t0]=tr2-tr3;\n    ch[t5+=t0]=tr1+tr4;\n    t1+=ido;\n    t3+=t2;\n  }\n\n  if(ido<2)return;\n  if(ido==2)goto L105;\n\n  t1=0;\n  for(k=0;k<l1;k++){\n    t5=(t4=(t3=(t2=t1<<2)+t6))+t6;\n    t7=t1;\n    for(i=2;i<ido;i+=2){\n      t2+=2;\n      t3+=2;\n      t4-=2;\n      t5-=2;\n      t7+=2;\n      ti1=cc[t2]+cc[t5];\n      ti2=cc[t2]-cc[t5];\n      ti3=cc[t3]-cc[t4];\n      tr4=cc[t3]+cc[t4];\n      tr1=cc[t2-1]-cc[t5-1];\n      tr2=cc[t2-1]+cc[t5-1];\n      ti4=cc[t3-1]-cc[t4-1];\n      tr3=cc[t3-1]+cc[t4-1];\n      ch[t7-1]=tr2+tr3;\n      cr3=tr2-tr3;\n      ch[t7]=ti2+ti3;\n      ci3=ti2-ti3;\n      cr2=tr1-tr4;\n      cr4=tr1+tr4;\n      ci2=ti1+ti4;\n      ci4=ti1-ti4;\n\n      ch[(t8=t7+t0)-1]=wa1[i-2]*cr2-wa1[i-1]*ci2;\n      ch[t8]=wa1[i-2]*ci2+wa1[i-1]*cr2;\n      ch[(t8+=t0)-1]=wa2[i-2]*cr3-wa2[i-1]*ci3;\n      ch[t8]=wa2[i-2]*ci3+wa2[i-1]*cr3;\n      ch[(t8+=t0)-1]=wa3[i-2]*cr4-wa3[i-1]*ci4;\n      ch[t8]=wa3[i-2]*ci4+wa3[i-1]*cr4;\n    }\n    t1+=ido;\n  }\n\n  if(ido%2 == 1)return;\n\n L105:\n\n  t1=ido;\n  t2=ido<<2;\n  t3=ido-1;\n  t4=ido+(ido<<1);\n  for(k=0;k<l1;k++){\n    t5=t3;\n    ti1=cc[t1]+cc[t4];\n    ti2=cc[t4]-cc[t1];\n    tr1=cc[t1-1]-cc[t4-1];\n    tr2=cc[t1-1]+cc[t4-1];\n    ch[t5]=tr2+tr2;\n    ch[t5+=t0]=sqrt2*(tr1-ti1);\n    ch[t5+=t0]=ti2+ti2;\n    ch[t5+=t0]=-sqrt2*(tr1+ti1);\n\n    t3+=ido;\n    t1+=t2;\n    t4+=t2;\n  }\n}\n\nstatic void dradbg(int ido,int ip,int l1,int idl1,float *cc,float *c1,\n            float *c2,float *ch,float *ch2,float *wa){\n  static float tpi=6.283185307179586f;\n  int idij,ipph,i,j,k,l,ik,is,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,\n      t11,t12;\n  float dc2,ai1,ai2,ar1,ar2,ds2;\n  int nbd;\n  float dcp,arg,dsp,ar1h,ar2h;\n  int ipp2;\n\n  t10=ip*ido;\n  t0=l1*ido;\n  arg=tpi/(float)ip;\n  dcp=cos(arg);\n  dsp=sin(arg);\n  nbd=(ido-1)>>1;\n  ipp2=ip;\n  ipph=(ip+1)>>1;\n  if(ido<l1)goto L103;\n  \n  t1=0;\n  t2=0;\n  for(k=0;k<l1;k++){\n    t3=t1;\n    t4=t2;\n    for(i=0;i<ido;i++){\n      ch[t3]=cc[t4];\n      t3++;\n      t4++;\n    }\n    t1+=ido;\n    t2+=t10;\n  }\n  goto L106;\n\n L103:\n  t1=0;\n  for(i=0;i<ido;i++){\n    t2=t1;\n    t3=t1;\n    for(k=0;k<l1;k++){\n      ch[t2]=cc[t3];\n      t2+=ido;\n      t3+=t10;\n    }\n    t1++;\n  }\n\n L106:\n  t1=0;\n  t2=ipp2*t0;\n  t7=(t5=ido<<1);\n  for(j=1;j<ipph;j++){\n    t1+=t0;\n    t2-=t0;\n    t3=t1;\n    t4=t2;\n    t6=t5;\n    for(k=0;k<l1;k++){\n      ch[t3]=cc[t6-1]+cc[t6-1];\n      ch[t4]=cc[t6]+cc[t6];\n      t3+=ido;\n      t4+=ido;\n      t6+=t10;\n    }\n    t5+=t7;\n  }\n\n  if (ido == 1)goto L116;\n  if(nbd<l1)goto L112;\n\n  t1=0;\n  t2=ipp2*t0;\n  t7=0;\n  for(j=1;j<ipph;j++){\n    t1+=t0;\n    t2-=t0;\n    t3=t1;\n    t4=t2;\n\n    t7+=(ido<<1);\n    t8=t7;\n    for(k=0;k<l1;k++){\n      t5=t3;\n      t6=t4;\n      t9=t8;\n      t11=t8;\n      for(i=2;i<ido;i+=2){\n        t5+=2;\n        t6+=2;\n        t9+=2;\n        t11-=2;\n        ch[t5-1]=cc[t9-1]+cc[t11-1];\n        ch[t6-1]=cc[t9-1]-cc[t11-1];\n        ch[t5]=cc[t9]-cc[t11];\n        ch[t6]=cc[t9]+cc[t11];\n      }\n      t3+=ido;\n      t4+=ido;\n      t8+=t10;\n    }\n  }\n  goto L116;\n\n L112:\n  t1=0;\n  t2=ipp2*t0;\n  t7=0;\n  for(j=1;j<ipph;j++){\n    t1+=t0;\n    t2-=t0;\n    t3=t1;\n    t4=t2;\n    t7+=(ido<<1);\n    t8=t7;\n    t9=t7;\n    for(i=2;i<ido;i+=2){\n      t3+=2;\n      t4+=2;\n      t8+=2;\n      t9-=2;\n      t5=t3;\n      t6=t4;\n      t11=t8;\n      t12=t9;\n      for(k=0;k<l1;k++){\n        ch[t5-1]=cc[t11-1]+cc[t12-1];\n        ch[t6-1]=cc[t11-1]-cc[t12-1];\n        ch[t5]=cc[t11]-cc[t12];\n        ch[t6]=cc[t11]+cc[t12];\n        t5+=ido;\n        t6+=ido;\n        t11+=t10;\n        t12+=t10;\n      }\n    }\n  }\n\nL116:\n  ar1=1.f;\n  ai1=0.f;\n  t1=0;\n  t9=(t2=ipp2*idl1);\n  t3=(ip-1)*idl1;\n  for(l=1;l<ipph;l++){\n    t1+=idl1;\n    t2-=idl1;\n\n    ar1h=dcp*ar1-dsp*ai1;\n    ai1=dcp*ai1+dsp*ar1;\n    ar1=ar1h;\n    t4=t1;\n    t5=t2;\n    t6=0;\n    t7=idl1;\n    t8=t3;\n    for(ik=0;ik<idl1;ik++){\n      c2[t4++]=ch2[t6++]+ar1*ch2[t7++];\n      c2[t5++]=ai1*ch2[t8++];\n    }\n    dc2=ar1;\n    ds2=ai1;\n    ar2=ar1;\n    ai2=ai1;\n\n    t6=idl1;\n    t7=t9-idl1;\n    for(j=2;j<ipph;j++){\n      t6+=idl1;\n      t7-=idl1;\n      ar2h=dc2*ar2-ds2*ai2;\n      ai2=dc2*ai2+ds2*ar2;\n      ar2=ar2h;\n      t4=t1;\n      t5=t2;\n      t11=t6;\n      t12=t7;\n      for(ik=0;ik<idl1;ik++){\n        c2[t4++]+=ar2*ch2[t11++];\n        c2[t5++]+=ai2*ch2[t12++];\n      }\n    }\n  }\n\n  t1=0;\n  for(j=1;j<ipph;j++){\n    t1+=idl1;\n    t2=t1;\n    for(ik=0;ik<idl1;ik++)ch2[ik]+=ch2[t2++];\n  }\n\n  t1=0;\n  t2=ipp2*t0;\n  for(j=1;j<ipph;j++){\n    t1+=t0;\n    t2-=t0;\n    t3=t1;\n    t4=t2;\n    for(k=0;k<l1;k++){\n      ch[t3]=c1[t3]-c1[t4];\n      ch[t4]=c1[t3]+c1[t4];\n      t3+=ido;\n      t4+=ido;\n    }\n  }\n\n  if(ido==1)goto L132;\n  if(nbd<l1)goto L128;\n\n  t1=0;\n  t2=ipp2*t0;\n  for(j=1;j<ipph;j++){\n    t1+=t0;\n    t2-=t0;\n    t3=t1;\n    t4=t2;\n    for(k=0;k<l1;k++){\n      t5=t3;\n      t6=t4;\n      for(i=2;i<ido;i+=2){\n        t5+=2;\n        t6+=2;\n        ch[t5-1]=c1[t5-1]-c1[t6];\n        ch[t6-1]=c1[t5-1]+c1[t6];\n        ch[t5]=c1[t5]+c1[t6-1];\n        ch[t6]=c1[t5]-c1[t6-1];\n      }\n      t3+=ido;\n      t4+=ido;\n    }\n  }\n  goto L132;\n\n L128:\n  t1=0;\n  t2=ipp2*t0;\n  for(j=1;j<ipph;j++){\n    t1+=t0;\n    t2-=t0;\n    t3=t1;\n    t4=t2;\n    for(i=2;i<ido;i+=2){\n      t3+=2;\n      t4+=2;\n      t5=t3;\n      t6=t4;\n      for(k=0;k<l1;k++){\n        ch[t5-1]=c1[t5-1]-c1[t6];\n        ch[t6-1]=c1[t5-1]+c1[t6];\n        ch[t5]=c1[t5]+c1[t6-1];\n        ch[t6]=c1[t5]-c1[t6-1];\n        t5+=ido;\n        t6+=ido;\n      }\n    }\n  }\n\nL132:\n  if(ido==1)return;\n\n  for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];\n\n  t1=0;\n  for(j=1;j<ip;j++){\n    t2=(t1+=t0);\n    for(k=0;k<l1;k++){\n      c1[t2]=ch[t2];\n      t2+=ido;\n    }\n  }\n\n  if(nbd>l1)goto L139;\n\n  is= -ido-1;\n  t1=0;\n  for(j=1;j<ip;j++){\n    is+=ido;\n    t1+=t0;\n    idij=is;\n    t2=t1;\n    for(i=2;i<ido;i+=2){\n      t2+=2;\n      idij+=2;\n      t3=t2;\n      for(k=0;k<l1;k++){\n        c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];\n        c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];\n        t3+=ido;\n      }\n    }\n  }\n  return;\n\n L139:\n  is= -ido-1;\n  t1=0;\n  for(j=1;j<ip;j++){\n    is+=ido;\n    t1+=t0;\n    t2=t1;\n    for(k=0;k<l1;k++){\n      idij=is;\n      t3=t2;\n      for(i=2;i<ido;i+=2){\n        idij+=2;\n        t3+=2;\n        c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];\n        c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];\n      }\n      t2+=ido;\n    }\n  }\n}\n\nstatic void drftb1(int n, float *c, float *ch, float *wa, int *ifac){\n  int i,k1,l1,l2;\n  int na;\n  int nf,ip,iw,ix2,ix3,ido,idl1;\n\n  nf=ifac[1];\n  na=0;\n  l1=1;\n  iw=1;\n\n  for(k1=0;k1<nf;k1++){\n    ip=ifac[k1 + 2];\n    l2=ip*l1;\n    ido=n/l2;\n    idl1=ido*l1;\n    if(ip!=4)goto L103;\n    ix2=iw+ido;\n    ix3=ix2+ido;\n\n    if(na!=0)\n      dradb4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);\n    else\n      dradb4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);\n    na=1-na;\n    goto L115;\n\n  L103:\n    if(ip!=2)goto L106;\n\n    if(na!=0)\n      dradb2(ido,l1,ch,c,wa+iw-1);\n    else\n      dradb2(ido,l1,c,ch,wa+iw-1);\n    na=1-na;\n    goto L115;\n\n  L106:\n    if(ip!=3)goto L109;\n\n    ix2=iw+ido;\n    if(na!=0)\n      dradb3(ido,l1,ch,c,wa+iw-1,wa+ix2-1);\n    else\n      dradb3(ido,l1,c,ch,wa+iw-1,wa+ix2-1);\n    na=1-na;\n    goto L115;\n\n  L109:\n/*    The radix five case can be translated later..... */\n/*    if(ip!=5)goto L112;\n\n    ix2=iw+ido;\n    ix3=ix2+ido;\n    ix4=ix3+ido;\n    if(na!=0)\n      dradb5(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);\n    else\n      dradb5(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);\n    na=1-na;\n    goto L115;\n\n  L112:*/\n    if(na!=0)\n      dradbg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);\n    else\n      dradbg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);\n    if(ido==1)na=1-na;\n\n  L115:\n    l1=l2;\n    iw+=(ip-1)*ido;\n  }\n\n  if(na==0)return;\n\n  for(i=0;i<n;i++)c[i]=ch[i];\n}\n\nvoid spx_drft_forward(struct drft_lookup *l,float *data){\n  if(l->n==1)return;\n  drftf1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache);\n}\n\nvoid spx_drft_backward(struct drft_lookup *l,float *data){\n  if (l->n==1)return;\n  drftb1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache);\n}\n\nvoid spx_drft_init(struct drft_lookup *l,int n)\n{\n  l->n=n;\n  l->trigcache=(float*)speex_alloc(3*n*sizeof(*l->trigcache));\n  l->splitcache=(int*)speex_alloc(32*sizeof(*l->splitcache));\n  fdrffti(n, l->trigcache, l->splitcache);\n}\n\nvoid spx_drft_clear(struct drft_lookup *l)\n{\n  if(l)\n  {\n    if(l->trigcache)\n      speex_free(l->trigcache);\n    if(l->splitcache)\n      speex_free(l->splitcache);\n  }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/smallft.h",
    "content": "/********************************************************************\n *                                                                  *\n * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *\n * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *\n * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *\n * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *\n *                                                                  *\n * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *\n * by the XIPHOPHORUS Company http://www.xiph.org/                  *\n *                                                                  *\n ********************************************************************\n\n function: fft transform\n last mod: $Id: smallft.h 2002 2008-06-10 14:09:37Z nanang $\n\n ********************************************************************/\n/**\n   @file smallft.h\n   @brief Discrete Rotational Fourier Transform (DRFT)\n*/\n\n#ifndef _V_SMFT_H_\n#define _V_SMFT_H_\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** Discrete Rotational Fourier Transform lookup */\nstruct drft_lookup{\n  int n;\n  float *trigcache;\n  int *splitcache;\n};\n\nextern void spx_drft_forward(struct drft_lookup *l,float *data);\nextern void spx_drft_backward(struct drft_lookup *l,float *data);\nextern void spx_drft_init(struct drft_lookup *l,int n);\nextern void spx_drft_clear(struct drft_lookup *l);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/speex.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: speex.c\n\n   Basic Speex functions\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"modes.h\"\n#include <math.h>\n#include \"os_support.h\"\n\n#ifndef NULL\n#define NULL 0\n#endif\n\n#define MAX_IN_SAMPLES 640\n\n\n\nEXPORT void *speex_encoder_init(const SpeexMode *mode)\n{\n   return mode->enc_init(mode);\n}\n\nEXPORT void *speex_decoder_init(const SpeexMode *mode)\n{\n   return mode->dec_init(mode);\n}\n\nEXPORT void speex_encoder_destroy(void *state)\n{\n   (*((SpeexMode**)state))->enc_destroy(state);\n}\n\nEXPORT void speex_decoder_destroy(void *state)\n{\n   (*((SpeexMode**)state))->dec_destroy(state);\n}\n\n\n\nint speex_encode_native(void *state, spx_word16_t *in, SpeexBits *bits)\n{\n   return (*((SpeexMode**)state))->enc(state, in, bits);\n}\n\nint speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out)\n{\n   return (*((SpeexMode**)state))->dec(state, bits, out);\n}\n\n\n\n#ifdef FIXED_POINT\n\n#ifndef DISABLE_FLOAT_API\nEXPORT int speex_encode(void *state, float *in, SpeexBits *bits)\n{\n   int i;\n   spx_int32_t N;\n   spx_int16_t short_in[MAX_IN_SAMPLES];\n   speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);\n   for (i=0;i<N;i++)\n   {\n      if (in[i]>32767.f)\n         short_in[i] = 32767;\n      else if (in[i]<-32768.f)\n         short_in[i] = -32768;\n      else\n         short_in[i] = (spx_int16_t)floor(.5+in[i]);\n   }\n   return (*((SpeexMode**)state))->enc(state, short_in, bits);\n}\n#endif /* #ifndef DISABLE_FLOAT_API */\n\nEXPORT int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)\n{\n   SpeexMode *mode;\n   mode = *(SpeexMode**)state;\n   return (mode)->enc(state, in, bits);\n}\n\n#ifndef DISABLE_FLOAT_API\nEXPORT int speex_decode(void *state, SpeexBits *bits, float *out)\n{\n   int i, ret;\n   spx_int32_t N;\n   spx_int16_t short_out[MAX_IN_SAMPLES];\n   speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);\n   ret = (*((SpeexMode**)state))->dec(state, bits, short_out);\n   for (i=0;i<N;i++)\n      out[i] = short_out[i];\n   return ret;\n}\n#endif /* #ifndef DISABLE_FLOAT_API */\n\nEXPORT int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)\n{\n   SpeexMode *mode = *(SpeexMode**)state;\n   return (mode)->dec(state, bits, out);\n}\n\n#else\n\nEXPORT int speex_encode(void *state, float *in, SpeexBits *bits)\n{\n   return (*((SpeexMode**)state))->enc(state, in, bits);\n}\n\nEXPORT int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)\n{\n   int i;\n   spx_int32_t N;\n   float float_in[MAX_IN_SAMPLES];\n   speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);\n   for (i=0;i<N;i++)\n      float_in[i] = in[i];\n   return (*((SpeexMode**)state))->enc(state, float_in, bits);\n}\n\nEXPORT int speex_decode(void *state, SpeexBits *bits, float *out)\n{\n   return (*((SpeexMode**)state))->dec(state, bits, out);\n}\n\nEXPORT int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)\n{\n   int i;\n   spx_int32_t N;\n   float float_out[MAX_IN_SAMPLES];\n   int ret;\n   speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);\n   ret = (*((SpeexMode**)state))->dec(state, bits, float_out);\n   for (i=0;i<N;i++)\n   {\n      if (float_out[i]>32767.f)\n         out[i] = 32767;\n      else if (float_out[i]<-32768.f)\n         out[i] = -32768;\n      else\n         out[i] = (spx_int16_t)floor(.5+float_out[i]);\n   }\n   return ret;\n}\n#endif\n\n\n\nEXPORT int speex_encoder_ctl(void *state, int request, void *ptr)\n{\n   return (*((SpeexMode**)state))->enc_ctl(state, request, ptr);\n}\n\nEXPORT int speex_decoder_ctl(void *state, int request, void *ptr)\n{\n   return (*((SpeexMode**)state))->dec_ctl(state, request, ptr);\n}\n\n\n\nint nb_mode_query(const void *mode, int request, void *ptr)\n{\n   const SpeexNBMode *m = (const SpeexNBMode*)mode;\n   \n   switch (request)\n   {\n   case SPEEX_MODE_FRAME_SIZE:\n      *((int*)ptr)=m->frameSize;\n      break;\n   case SPEEX_SUBMODE_BITS_PER_FRAME:\n      if (*((int*)ptr)==0)\n         *((int*)ptr) = NB_SUBMODE_BITS+1;\n      else if (m->submodes[*((int*)ptr)]==NULL)\n         *((int*)ptr) = -1;\n      else\n         *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;\n      break;\n   default:\n      speex_warning_int(\"Unknown nb_mode_query request: \", request);\n      return -1;\n   }\n   return 0;\n}\n\n\n\nEXPORT int speex_lib_ctl(int request, void *ptr)\n{\n   switch (request)\n   {\n      case SPEEX_LIB_GET_MAJOR_VERSION:\n         *((int*)ptr) = SPEEX_MAJOR_VERSION;\n         break;\n      case SPEEX_LIB_GET_MINOR_VERSION:\n         *((int*)ptr) = SPEEX_MINOR_VERSION;\n         break;\n      case SPEEX_LIB_GET_MICRO_VERSION:\n         *((int*)ptr) = SPEEX_MICRO_VERSION;\n         break;\n      case SPEEX_LIB_GET_EXTRA_VERSION:\n         *((const char**)ptr) = SPEEX_EXTRA_VERSION;\n         break;\n      case SPEEX_LIB_GET_VERSION_STRING:\n         *((const char**)ptr) = SPEEX_VERSION;\n         break;\n      /*case SPEEX_LIB_SET_ALLOC_FUNC:\n         break;\n      case SPEEX_LIB_GET_ALLOC_FUNC:\n         break;\n      case SPEEX_LIB_SET_FREE_FUNC:\n         break;\n      case SPEEX_LIB_GET_FREE_FUNC:\n         break;*/\n      default:\n         speex_warning_int(\"Unknown wb_mode_query request: \", request);\n         return -1;\n   }\n   return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/speex_callbacks.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin\n   File speex_callbacks.c\n   Callback handling and in-band signalling\n\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <speex/speex_callbacks.h>\n#include \"arch.h\"\n#include \"os_support.h\"\n\nEXPORT int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state)\n{\n   int id;\n   SpeexCallback *callback;\n   /*speex_bits_advance(bits, 5);*/\n   id=speex_bits_unpack_unsigned(bits, 4);\n   callback = callback_list+id;\n\n   if (callback->func)\n   {\n      return callback->func(bits, state, callback->data);\n   } else\n      /*If callback is not registered, skip the right number of bits*/\n   {\n      int adv;\n      if (id<2)\n         adv = 1;\n      else if (id<8)\n         adv = 4;\n      else if (id<10)\n         adv = 8;\n      else if (id<12)\n         adv = 16;\n      else if (id<14)\n         adv = 32;\n      else \n         adv = 64;\n      speex_bits_advance(bits, adv);\n   }\n   return 0;\n}\n\nEXPORT int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data)\n{\n   spx_int32_t m;\n   m = speex_bits_unpack_unsigned(bits, 4);\n   speex_encoder_ctl(data, SPEEX_SET_MODE, &m);\n   return 0;\n}\n\nEXPORT int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data)\n{\n   spx_int32_t m;\n   m = speex_bits_unpack_unsigned(bits, 4);\n   speex_encoder_ctl(data, SPEEX_SET_LOW_MODE, &m);\n   return 0;\n}\n\nEXPORT int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data)\n{\n   spx_int32_t m;\n   m = speex_bits_unpack_unsigned(bits, 4);\n   speex_encoder_ctl(data, SPEEX_SET_HIGH_MODE, &m);\n   return 0;\n}\n\n#ifndef DISABLE_VBR\nEXPORT int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data)\n{\n   spx_int32_t vbr;\n   vbr = speex_bits_unpack_unsigned(bits, 1);\n   speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr);\n   return 0;\n}\n#endif /* #ifndef DISABLE_VBR */\n\nEXPORT int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data)\n{\n   spx_int32_t enh;\n   enh = speex_bits_unpack_unsigned(bits, 1);\n   speex_decoder_ctl(data, SPEEX_SET_ENH, &enh);\n   return 0;\n}\n\n#ifndef DISABLE_VBR\nEXPORT int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data)\n{\n   float qual;\n   qual = speex_bits_unpack_unsigned(bits, 4);\n   speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual);\n   return 0;\n}\n#endif /* #ifndef DISABLE_VBR */\n\nEXPORT int speex_std_char_handler(SpeexBits *bits, void *state, void *data)\n{\n   unsigned char ch;\n   ch = speex_bits_unpack_unsigned(bits, 8);\n   _speex_putc(ch, data);\n   /*printf(\"speex_std_char_handler ch=%x\\n\", ch);*/\n   return 0;\n}\n\n\n\n/* Default handler for user callbacks: skip it */\nEXPORT int speex_default_user_handler(SpeexBits *bits, void *state, void *data)\n{\n   int req_size = speex_bits_unpack_unsigned(bits, 4);\n   speex_bits_advance(bits, 5+8*req_size);\n   return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/speex_header.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: speex_header.c\n   Describes the Speex header\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arch.h\"\n#include <speex/speex_header.h>\n#include <speex/speex.h>\n#include \"os_support.h\"\n\n#ifndef NULL\n#define NULL 0\n#endif\n\n/** Convert little endian */\nstatic inline spx_int32_t le_int(spx_int32_t i)\n{\n#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )\n   spx_uint32_t ui, ret;\n   ui = i;\n   ret =  ui>>24;\n   ret |= (ui>>8)&0x0000ff00;\n   ret |= (ui<<8)&0x00ff0000;\n   ret |= (ui<<24);\n   return ret;\n#else\n   return i;\n#endif\n}\n\n#define ENDIAN_SWITCH(x) {x=le_int(x);}\n\n\n/*\ntypedef struct SpeexHeader {\n   char speex_string[8];\n   char speex_version[SPEEX_HEADER_VERSION_LENGTH];\n   int speex_version_id;\n   int header_size;\n   int rate;\n   int mode;\n   int mode_bitstream_version;\n   int nb_channels;\n   int bitrate;\n   int frame_size;\n   int vbr;\n   int frames_per_packet;\n   int extra_headers;\n   int reserved1;\n   int reserved2;\n} SpeexHeader;\n*/\n\nEXPORT void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m)\n{\n   int i;\n   const char *h=\"Speex   \";\n   /*\n   strncpy(header->speex_string, \"Speex   \", 8);\n   strncpy(header->speex_version, SPEEX_VERSION, SPEEX_HEADER_VERSION_LENGTH-1);\n   header->speex_version[SPEEX_HEADER_VERSION_LENGTH-1]=0;\n   */\n   for (i=0;i<8;i++)\n      header->speex_string[i]=h[i];\n   for (i=0;i<SPEEX_HEADER_VERSION_LENGTH-1 && SPEEX_VERSION[i];i++)\n      header->speex_version[i]=SPEEX_VERSION[i];\n   for (;i<SPEEX_HEADER_VERSION_LENGTH;i++)\n      header->speex_version[i]=0;\n   \n   header->speex_version_id = 1;\n   header->header_size = sizeof(SpeexHeader);\n   \n   header->rate = rate;\n   header->mode = m->modeID;\n   header->mode_bitstream_version = m->bitstream_version;\n   if (m->modeID<0)\n      speex_warning(\"This mode is meant to be used alone\");\n   header->nb_channels = nb_channels;\n   header->bitrate = -1;\n   speex_mode_query(m, SPEEX_MODE_FRAME_SIZE, &header->frame_size);\n   header->vbr = 0;\n   \n   header->frames_per_packet = 0;\n   header->extra_headers = 0;\n   header->reserved1 = 0;\n   header->reserved2 = 0;\n}\n\nEXPORT char *speex_header_to_packet(SpeexHeader *header, int *size)\n{\n   SpeexHeader *le_header;\n   le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));\n   \n   SPEEX_COPY(le_header, header, 1);\n   \n   /*Make sure everything is now little-endian*/\n   ENDIAN_SWITCH(le_header->speex_version_id);\n   ENDIAN_SWITCH(le_header->header_size);\n   ENDIAN_SWITCH(le_header->rate);\n   ENDIAN_SWITCH(le_header->mode);\n   ENDIAN_SWITCH(le_header->mode_bitstream_version);\n   ENDIAN_SWITCH(le_header->nb_channels);\n   ENDIAN_SWITCH(le_header->bitrate);\n   ENDIAN_SWITCH(le_header->frame_size);\n   ENDIAN_SWITCH(le_header->vbr);\n   ENDIAN_SWITCH(le_header->frames_per_packet);\n   ENDIAN_SWITCH(le_header->extra_headers);\n\n   *size = sizeof(SpeexHeader);\n   return (char *)le_header;\n}\n\nEXPORT SpeexHeader *speex_packet_to_header(char *packet, int size)\n{\n   int i;\n   SpeexHeader *le_header;\n   const char *h = \"Speex   \";\n   for (i=0;i<8;i++)\n      if (packet[i]!=h[i])\n      {\n         speex_notify(\"This doesn't look like a Speex file\");\n         return NULL;\n      }\n   \n   /*FIXME: Do we allow larger headers?*/\n   if (size < (int)sizeof(SpeexHeader))\n   {\n      speex_notify(\"Speex header too small\");\n      return NULL;\n   }\n   \n   le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));\n   \n   SPEEX_COPY(le_header, (SpeexHeader*)packet, 1);\n   \n   /*Make sure everything is converted correctly from little-endian*/\n   ENDIAN_SWITCH(le_header->speex_version_id);\n   ENDIAN_SWITCH(le_header->header_size);\n   ENDIAN_SWITCH(le_header->rate);\n   ENDIAN_SWITCH(le_header->mode);\n   ENDIAN_SWITCH(le_header->mode_bitstream_version);\n   ENDIAN_SWITCH(le_header->nb_channels);\n   ENDIAN_SWITCH(le_header->bitrate);\n   ENDIAN_SWITCH(le_header->frame_size);\n   ENDIAN_SWITCH(le_header->vbr);\n   ENDIAN_SWITCH(le_header->frames_per_packet);\n   ENDIAN_SWITCH(le_header->extra_headers);\n\n   if (le_header->mode >= SPEEX_NB_MODES || le_header->mode < 0)\n   {\n      speex_notify(\"Invalid mode specified in Speex header\");\n      speex_free (le_header);\n      return NULL;\n   }\n\n   if (le_header->nb_channels>2)\n      le_header->nb_channels = 2;\n   if (le_header->nb_channels<1)\n      le_header->nb_channels = 1;\n\n   return le_header;\n\n}\n\nEXPORT void speex_header_free(void *ptr)\n{\n   speex_free(ptr);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/stack_alloc.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin */\n/**\n   @file stack_alloc.h\n   @brief Temporary memory allocation on stack\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef STACK_ALLOC_H\n#define STACK_ALLOC_H\n\n#ifdef USE_ALLOCA\n# if (defined(WIN32) || defined(WIN64))\n#  include <malloc.h>\n# else\n#  ifdef HAVE_ALLOCA_H\n#   include <alloca.h>\n#  else\n#   include <stdlib.h>\n#  endif\n# endif\n#endif\n\n/**\n * @def ALIGN(stack, size)\n *\n * Aligns the stack to a 'size' boundary\n *\n * @param stack Stack\n * @param size  New size boundary\n */\n\n/**\n * @def PUSH(stack, size, type)\n *\n * Allocates 'size' elements of type 'type' on the stack\n *\n * @param stack Stack\n * @param size  Number of elements\n * @param type  Type of element\n */\n\n/**\n * @def VARDECL(var)\n *\n * Declare variable on stack\n *\n * @param var Variable to declare\n */\n\n/**\n * @def ALLOC(var, size, type)\n *\n * Allocate 'size' elements of 'type' on stack\n *\n * @param var  Name of variable to allocate\n * @param size Number of elements\n * @param type Type of element\n */\n\n#ifdef ENABLE_VALGRIND\n\n#include <valgrind/memcheck.h>\n\n#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))\n\n#define PUSH(stack, size, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(type)),VALGRIND_MAKE_WRITABLE(stack, ((size)*sizeof(type))),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))\n\n#else\n\n#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))\n\n#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))\n\n#endif\n\n#if defined(VAR_ARRAYS)\n#define VARDECL(var) \n#define ALLOC(var, size, type) type var[size]\n#elif defined(USE_ALLOCA)\n#define VARDECL(var) var\n#define ALLOC(var, size, type) var = alloca(sizeof(type)*(size))\n#else\n#define VARDECL(var) var\n#define ALLOC(var, size, type) var = PUSH(stack, size, type)\n#endif\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/stereo.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: stereo.c\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <speex/speex_stereo.h>\n#include <speex/speex_callbacks.h>\n#include \"math_approx.h\"\n#include \"vq.h\"\n#include <math.h>\n#include \"os_support.h\"\n\ntypedef struct RealSpeexStereoState {\n   spx_word32_t balance;      /**< Left/right balance info */\n   spx_word32_t e_ratio;      /**< Ratio of energies: E(left+right)/[E(left)+E(right)]  */\n   spx_word32_t smooth_left;  /**< Smoothed left channel gain */\n   spx_word32_t smooth_right; /**< Smoothed right channel gain */\n   spx_uint32_t reserved1;     /**< Reserved for future use */\n   spx_int32_t reserved2;     /**< Reserved for future use */\n} RealSpeexStereoState;\n\n\n/*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/\n#ifndef FIXED_POINT\nstatic const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f};\nstatic const float e_ratio_quant_bounds[3] = {0.2825f, 0.356f, 0.4485f};\n#else\nstatic const spx_word16_t e_ratio_quant[4] = {8192, 10332, 13009, 16384};\nstatic const spx_word16_t e_ratio_quant_bounds[3] = {9257, 11665, 14696};\nstatic const spx_word16_t balance_bounds[31] = {18, 23, 30, 38, 49, 63,  81, 104,\n   134, 172, 221,  284, 364, 468, 600, 771,\n   990, 1271, 1632, 2096, 2691, 3455, 4436, 5696,\n   7314, 9392, 12059, 15484, 19882, 25529, 32766};\n#endif\n\n/* This is an ugly compatibility hack that properly resets the stereo state\n   In case it it compiled in fixed-point, but initialised with the deprecated\n   floating point static initialiser */\n#ifdef FIXED_POINT\n#define COMPATIBILITY_HACK(s) do {if ((s)->reserved1 != 0xdeadbeef) speex_stereo_state_reset((SpeexStereoState*)s); } while (0);\n#else\n#define COMPATIBILITY_HACK(s) \n#endif\n\nEXPORT SpeexStereoState *speex_stereo_state_init()\n{\n   SpeexStereoState *stereo = speex_alloc(sizeof(SpeexStereoState));\n   speex_stereo_state_reset(stereo);\n   return stereo;\n}\n\nEXPORT void speex_stereo_state_reset(SpeexStereoState *_stereo)\n{\n   RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;\n#ifdef FIXED_POINT\n   stereo->balance = 65536;\n   stereo->e_ratio = 16384;\n   stereo->smooth_left = 16384;\n   stereo->smooth_right = 16384;\n   stereo->reserved1 = 0xdeadbeef;\n   stereo->reserved2 = 0;\n#else\n   stereo->balance = 1.0f;\n   stereo->e_ratio = .5f;\n   stereo->smooth_left = 1.f;\n   stereo->smooth_right = 1.f;\n   stereo->reserved1 = 0;\n   stereo->reserved2 = 0;\n#endif   \n}\n\nEXPORT void speex_stereo_state_destroy(SpeexStereoState *stereo)\n{\n   speex_free(stereo);\n}\n\n#ifndef DISABLE_FLOAT_API\nEXPORT void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)\n{\n   int i, tmp;\n   float e_left=0, e_right=0, e_tot=0;\n   float balance, e_ratio;\n   for (i=0;i<frame_size;i++)\n   {\n      e_left  += ((float)data[2*i])*data[2*i];\n      e_right += ((float)data[2*i+1])*data[2*i+1];\n      data[i] =  .5*(((float)data[2*i])+data[2*i+1]);\n      e_tot   += ((float)data[i])*data[i];\n   }\n   balance=(e_left+1)/(e_right+1);\n   e_ratio = e_tot/(1+e_left+e_right);\n\n   /*Quantization*/\n   speex_bits_pack(bits, 14, 5);\n   speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);\n   \n   balance=4*log(balance);\n\n   /*Pack sign*/\n   if (balance>0)\n      speex_bits_pack(bits, 0, 1);\n   else\n      speex_bits_pack(bits, 1, 1);\n   balance=floor(.5+fabs(balance));\n   if (balance>30)\n      balance=31;\n   \n   speex_bits_pack(bits, (int)balance, 5);\n   \n   /* FIXME: this is a hack */\n   tmp=scal_quant(e_ratio*Q15_ONE, e_ratio_quant_bounds, 4);\n   speex_bits_pack(bits, tmp, 2);\n}\n#endif /* #ifndef DISABLE_FLOAT_API */\n\nEXPORT void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits)\n{\n   int i, tmp;\n   spx_word32_t e_left=0, e_right=0, e_tot=0;\n   spx_word32_t balance, e_ratio;\n   spx_word32_t largest, smallest;\n   int balance_id;\n#ifdef FIXED_POINT\n   int shift;\n#endif\n   \n   /* In band marker */\n   speex_bits_pack(bits, 14, 5);\n   /* Stereo marker */\n   speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);\n\n   for (i=0;i<frame_size;i++)\n   {\n      e_left  += SHR32(MULT16_16(data[2*i],data[2*i]),8);\n      e_right += SHR32(MULT16_16(data[2*i+1],data[2*i+1]),8);\n#ifdef FIXED_POINT\n      /* I think this is actually unbiased */\n      data[i] =  SHR16(data[2*i],1)+PSHR16(data[2*i+1],1);\n#else\n      data[i] =  .5*(((float)data[2*i])+data[2*i+1]);\n#endif\n      e_tot   += SHR32(MULT16_16(data[i],data[i]),8);\n   }\n   if (e_left > e_right)\n   {\n      speex_bits_pack(bits, 0, 1);\n      largest = e_left;\n      smallest = e_right;\n   } else {\n      speex_bits_pack(bits, 1, 1);\n      largest = e_right;\n      smallest = e_left;\n   }\n\n   /* Balance quantization */\n#ifdef FIXED_POINT\n   shift = spx_ilog2(largest)-15;\n   largest = VSHR32(largest, shift-4);\n   smallest = VSHR32(smallest, shift);\n   balance = DIV32(largest, ADD32(smallest, 1));\n   if (balance > 32767)\n      balance = 32767;\n   balance_id = scal_quant(EXTRACT16(balance), balance_bounds, 32);\n#else\n   balance=(largest+1.)/(smallest+1.);\n   balance=4*log(balance);\n   balance_id=floor(.5+fabs(balance));\n   if (balance_id>30)\n      balance_id=31;\n#endif\n   \n   speex_bits_pack(bits, balance_id, 5);\n   \n   /* \"coherence\" quantisation */\n#ifdef FIXED_POINT\n   shift = spx_ilog2(e_tot);\n   e_tot = VSHR32(e_tot, shift-25);\n   e_left = VSHR32(e_left, shift-10);\n   e_right = VSHR32(e_right, shift-10);\n   e_ratio = DIV32(e_tot, e_left+e_right+1);\n#else\n   e_ratio = e_tot/(1.+e_left+e_right);\n#endif\n   \n   tmp=scal_quant(EXTRACT16(e_ratio), e_ratio_quant_bounds, 4);\n   /*fprintf (stderr, \"%d %d %d %d\\n\", largest, smallest, balance_id, e_ratio);*/\n   speex_bits_pack(bits, tmp, 2);\n}\n\n#ifndef DISABLE_FLOAT_API\nEXPORT void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *_stereo)\n{\n   int i;\n   spx_word32_t balance;\n   spx_word16_t e_left, e_right, e_ratio;\n   RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;\n   \n   COMPATIBILITY_HACK(stereo);\n   \n   balance=stereo->balance;\n   e_ratio=stereo->e_ratio;\n   \n   /* These two are Q14, with max value just below 2. */\n   e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance))));\n   e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8);\n\n   for (i=frame_size-1;i>=0;i--)\n   {\n      spx_word16_t tmp=data[i];\n      stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15));\n      stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15));\n      data[2*i] = (float)MULT16_16_P14(stereo->smooth_left, tmp);\n      data[2*i+1] = (float)MULT16_16_P14(stereo->smooth_right, tmp);\n   }\n}\n#endif /* #ifndef DISABLE_FLOAT_API */\n\nEXPORT void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *_stereo)\n{\n   int i;\n   spx_word32_t balance;\n   spx_word16_t e_left, e_right, e_ratio;\n   RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;\n\n   COMPATIBILITY_HACK(stereo);\n   \n   balance=stereo->balance;\n   e_ratio=stereo->e_ratio;\n   \n   /* These two are Q14, with max value just below 2. */\n   e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance))));\n   e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8);\n\n   for (i=frame_size-1;i>=0;i--)\n   {\n      spx_int16_t tmp=data[i];\n      stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15));\n      stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15));\n      data[2*i] = (spx_int16_t)MULT16_16_P14(stereo->smooth_left, tmp);\n      data[2*i+1] = (spx_int16_t)MULT16_16_P14(stereo->smooth_right, tmp);\n   }\n}\n\nEXPORT int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)\n{\n   RealSpeexStereoState *stereo;\n   spx_word16_t sign=1, dexp;\n   int tmp;\n\n   stereo = (RealSpeexStereoState*)data;\n   \n   COMPATIBILITY_HACK(stereo);\n\n   if (speex_bits_unpack_unsigned(bits, 1))\n      sign=-1;\n   dexp = speex_bits_unpack_unsigned(bits, 5);\n#ifndef FIXED_POINT\n   stereo->balance = exp(sign*.25*dexp);\n#else\n   stereo->balance = spx_exp(MULT16_16(sign, SHL16(dexp, 9)));\n#endif\n   tmp = speex_bits_unpack_unsigned(bits, 2);\n   stereo->e_ratio = e_ratio_quant[tmp];\n\n   return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/testdenoise.c",
    "content": "#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <speex/speex_preprocess.h>\n#include <stdio.h>\n\n#define NN 160\n\nint main()\n{\n   short in[NN];\n   int i;\n   SpeexPreprocessState *st;\n   int count=0;\n   float f;\n\n   st = speex_preprocess_state_init(NN, 8000);\n   i=1;\n   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i);\n   i=0;\n   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i);\n   i=8000;\n   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i);\n   i=0;\n   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i);\n   f=.0;\n   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);\n   f=.0;\n   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);\n   while (1)\n   {\n      int vad;\n      fread(in, sizeof(short), NN, stdin);\n      if (feof(stdin))\n         break;\n      vad = speex_preprocess_run(st, in);\n      /*fprintf (stderr, \"%d\\n\", vad);*/\n      fwrite(in, sizeof(short), NN, stdout);\n      count++;\n   }\n   speex_preprocess_state_destroy(st);\n   return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/testecho.c",
    "content": "#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include \"speex/speex_echo.h\"\n#include \"speex/speex_preprocess.h\"\n\n\n#define NN 128\n#define TAIL 1024\n\nint main(int argc, char **argv)\n{\n   FILE *echo_fd, *ref_fd, *e_fd;\n   short echo_buf[NN], ref_buf[NN], e_buf[NN];\n   SpeexEchoState *st;\n   SpeexPreprocessState *den;\n   int sampleRate = 8000;\n\n   if (argc != 4)\n   {\n      fprintf(stderr, \"testecho mic_signal.sw speaker_signal.sw output.sw\\n\");\n      exit(1);\n   }\n   echo_fd = fopen(argv[2], \"rb\");\n   ref_fd  = fopen(argv[1],  \"rb\");\n   e_fd    = fopen(argv[3], \"wb\");\n\n   st = speex_echo_state_init(NN, TAIL);\n   den = speex_preprocess_state_init(NN, sampleRate);\n   speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);\n   speex_preprocess_ctl(den, SPEEX_PREPROCESS_SET_ECHO_STATE, st);\n\n   while (!feof(ref_fd) && !feof(echo_fd))\n   {\n      fread(ref_buf, sizeof(short), NN, ref_fd);\n      fread(echo_buf, sizeof(short), NN, echo_fd);\n      speex_echo_cancellation(st, ref_buf, echo_buf, e_buf);\n      speex_preprocess_run(den, e_buf);\n      fwrite(e_buf, sizeof(short), NN, e_fd);\n   }\n   speex_echo_state_destroy(st);\n   speex_preprocess_state_destroy(den);\n   fclose(e_fd);\n   fclose(echo_fd);\n   fclose(ref_fd);\n   return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/testenc.c",
    "content": "#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <speex/speex.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <speex/speex_callbacks.h>\n\n#ifdef FIXED_DEBUG\nextern long long spx_mips;\n#endif\n\n#define FRAME_SIZE 160\n#include <math.h>\nint main(int argc, char **argv)\n{\n   char *inFile, *outFile, *bitsFile;\n   FILE *fin, *fout, *fbits=NULL;\n   short in_short[FRAME_SIZE];\n   short out_short[FRAME_SIZE];\n   int snr_frames = 0;\n   char cbits[200];\n   int nbBits;\n   int i;\n   void *st;\n   void *dec;\n   SpeexBits bits;\n   spx_int32_t tmp;\n   int bitCount=0;\n   spx_int32_t skip_group_delay;\n   SpeexCallback callback;\n\n   st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));\n   dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));\n\n   /* BEGIN: You probably don't need the following in a real application */\n   callback.callback_id = SPEEX_INBAND_CHAR;\n   callback.func = speex_std_char_handler;\n   callback.data = stderr;\n   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);\n\n   callback.callback_id = SPEEX_INBAND_MODE_REQUEST;\n   callback.func = speex_std_mode_request_handler;\n   callback.data = st;\n   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);\n   /* END of unnecessary stuff */\n\n   tmp=1;\n   speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);\n   tmp=0;\n   speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);\n   tmp=8;\n   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);\n   tmp=1;\n   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);\n\n   /* Turn this off if you want to measure SNR (on by default) */\n   tmp=1;\n   speex_encoder_ctl(st, SPEEX_SET_HIGHPASS, &tmp);\n   speex_decoder_ctl(dec, SPEEX_SET_HIGHPASS, &tmp);\n\n   speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay);\n   speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp);\n   skip_group_delay += tmp;\n\n   if (argc != 4 && argc != 3)\n   {\n      fprintf (stderr, \"Usage: encode [in file] [out file] [bits file]\\nargc = %d\", argc);\n      exit(1);\n   }\n   inFile = argv[1];\n   fin = fopen(inFile, \"rb\");\n   outFile = argv[2];\n   fout = fopen(outFile, \"wb+\");\n   if (argc==4)\n   {\n      bitsFile = argv[3];\n      fbits = fopen(bitsFile, \"wb\");\n   }\n   speex_bits_init(&bits);\n   while (!feof(fin))\n   {\n      fread(in_short, sizeof(short), FRAME_SIZE, fin);\n      if (feof(fin))\n         break;\n      speex_bits_reset(&bits);\n\n      speex_encode_int(st, in_short, &bits);\n      nbBits = speex_bits_write(&bits, cbits, 200);\n      bitCount+=bits.nbBits;\n\n      if (argc==4)\n         fwrite(cbits, 1, nbBits, fbits);\n      speex_bits_rewind(&bits);\n\n      speex_decode_int(dec, &bits, out_short);\n      speex_bits_reset(&bits);\n\n      fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);\n      skip_group_delay = 0;\n   }\n   fprintf (stderr, \"Total encoded size: %d bits\\n\", bitCount);\n   speex_encoder_destroy(st);\n   speex_decoder_destroy(dec);\n   speex_bits_destroy(&bits);\n\n#ifndef DISABLE_FLOAT_API\n   {\n   float sigpow,errpow,snr, seg_snr=0;\n   sigpow = 0;\n   errpow = 0;\n\n   /* This code just computes SNR, so you don't need it either */\n   rewind(fin);\n   rewind(fout);\n\n   while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) \n           &&\n           FRAME_SIZE ==  fread(out_short, sizeof(short), FRAME_SIZE,fout) )\n   {\n\tfloat s=0, e=0;\n        for (i=0;i<FRAME_SIZE;++i) {\n            s += (float)in_short[i] * in_short[i];\n            e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);\n        }\n\tseg_snr += 10*log10((s+160)/(e+160));\n\tsigpow += s;\n\terrpow += e;\n\tsnr_frames++;\n   }\n   snr = 10 * log10( sigpow / errpow );\n   seg_snr /= snr_frames;\n   fprintf(stderr,\"SNR = %f\\nsegmental SNR = %f\\n\",snr, seg_snr);\n\n#ifdef FIXED_DEBUG\n   printf (\"Total: %f MIPS\\n\", (float)(1e-6*50*spx_mips/snr_frames));\n#endif\n   }\n#endif\n\n   fclose(fin);\n   fclose(fout);\n\n   return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/testenc_uwb.c",
    "content": "#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <speex/speex.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <speex/speex_callbacks.h>\n\n#ifdef FIXED_DEBUG\nextern long long spx_mips;\n#endif\n\n#define FRAME_SIZE 640\n#include <math.h>\nint main(int argc, char **argv)\n{\n   char *inFile, *outFile, *bitsFile;\n   FILE *fin, *fout, *fbits=NULL;\n   short in_short[FRAME_SIZE];\n   short out_short[FRAME_SIZE];\n   float in_float[FRAME_SIZE];\n   float sigpow,errpow,snr, seg_snr=0;\n   int snr_frames = 0;\n   char cbits[200];\n   int nbBits;\n   int i;\n   void *st;\n   void *dec;\n   SpeexBits bits;\n   spx_int32_t tmp;\n   int bitCount=0;\n   spx_int32_t skip_group_delay;\n   SpeexCallback callback;\n\n   sigpow = 0;\n   errpow = 0;\n\n   st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB));\n   dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB));\n\n   callback.callback_id = SPEEX_INBAND_CHAR;\n   callback.func = speex_std_char_handler;\n   callback.data = stderr;\n   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);\n\n   callback.callback_id = SPEEX_INBAND_MODE_REQUEST;\n   callback.func = speex_std_mode_request_handler;\n   callback.data = st;\n   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);\n\n   tmp=0;\n   speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);\n   tmp=0;\n   speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);\n   tmp=7;\n   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);\n   tmp=1;\n   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);\n\n   speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay);\n   speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp);\n   skip_group_delay += tmp;\n\n\n   if (argc != 4 && argc != 3)\n   {\n      fprintf (stderr, \"Usage: encode [in file] [out file] [bits file]\\nargc = %d\", argc);\n      exit(1);\n   }\n   inFile = argv[1];\n   fin = fopen(inFile, \"rb\");\n   outFile = argv[2];\n   fout = fopen(outFile, \"wb+\");\n   if (argc==4)\n   {\n      bitsFile = argv[3];\n      fbits = fopen(bitsFile, \"wb\");\n   }\n   speex_bits_init(&bits);\n   while (!feof(fin))\n   {\n      fread(in_short, sizeof(short), FRAME_SIZE, fin);\n      if (feof(fin))\n         break;\n      for (i=0;i<FRAME_SIZE;i++)\n         in_float[i]=in_short[i];\n      speex_bits_reset(&bits);\n\n      speex_encode_int(st, in_short, &bits);\n      nbBits = speex_bits_write(&bits, cbits, 200);\n      bitCount+=bits.nbBits;\n\n      if (argc==4)\n         fwrite(cbits, 1, nbBits, fbits);\n      speex_bits_rewind(&bits);\n\n      speex_decode_int(dec, &bits, out_short);\n      speex_bits_reset(&bits);\n\n      fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);\n      skip_group_delay = 0;\n   }\n   fprintf (stderr, \"Total encoded size: %d bits\\n\", bitCount);\n   speex_encoder_destroy(st);\n   speex_decoder_destroy(dec);\n\n   rewind(fin);\n   rewind(fout);\n\n   while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) \n           &&\n           FRAME_SIZE ==  fread(out_short, sizeof(short), FRAME_SIZE,fout) )\n   {\n\tfloat s=0, e=0;\n        for (i=0;i<FRAME_SIZE;++i) {\n            s += (float)in_short[i] * in_short[i];\n            e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);\n        }\n\tseg_snr += 10*log10((s+1)/(e+1));\n\tsigpow += s;\n\terrpow += e;\n\tsnr_frames++;\n   }\n   fclose(fin);\n   fclose(fout);\n\n   snr = 10 * log10( sigpow / errpow );\n   seg_snr /= snr_frames;\n   fprintf(stderr,\"SNR = %f\\nsegmental SNR = %f\\n\",snr, seg_snr);\n\n#ifdef FIXED_DEBUG\n   printf (\"Total: %f MIPS\\n\", (float)(1e-6*50*spx_mips/snr_frames));\n#endif\n   \n   return 1;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/testenc_wb.c",
    "content": "#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <speex/speex.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <speex/speex_callbacks.h>\n\n#ifdef FIXED_DEBUG\nextern long long spx_mips;\n#endif\n\n#define FRAME_SIZE 320\n#include <math.h>\nint main(int argc, char **argv)\n{\n   char *inFile, *outFile, *bitsFile;\n   FILE *fin, *fout, *fbits=NULL;\n   short in_short[FRAME_SIZE];\n   short out_short[FRAME_SIZE];\n   float sigpow,errpow,snr, seg_snr=0;\n   int snr_frames = 0;\n   char cbits[200];\n   int nbBits;\n   int i;\n   void *st;\n   void *dec;\n   SpeexBits bits;\n   spx_int32_t tmp;\n   int bitCount=0;\n   spx_int32_t skip_group_delay;\n   SpeexCallback callback;\n\n   sigpow = 0;\n   errpow = 0;\n\n   st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_WB));\n   dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_WB));\n\n   callback.callback_id = SPEEX_INBAND_CHAR;\n   callback.func = speex_std_char_handler;\n   callback.data = stderr;\n   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);\n\n   callback.callback_id = SPEEX_INBAND_MODE_REQUEST;\n   callback.func = speex_std_mode_request_handler;\n   callback.data = st;\n   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);\n\n   tmp=1;\n   speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);\n   tmp=0;\n   speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);\n   tmp=8;\n   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);\n   tmp=3;\n   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);\n   /*tmp=3;\n   speex_encoder_ctl(st, SPEEX_SET_HIGH_MODE, &tmp);\n   tmp=6;\n   speex_encoder_ctl(st, SPEEX_SET_LOW_MODE, &tmp);\n*/\n\n   speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay);\n   speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp);\n   skip_group_delay += tmp;\n\n\n   if (argc != 4 && argc != 3)\n   {\n      fprintf (stderr, \"Usage: encode [in file] [out file] [bits file]\\nargc = %d\", argc);\n      exit(1);\n   }\n   inFile = argv[1];\n   fin = fopen(inFile, \"rb\");\n   outFile = argv[2];\n   fout = fopen(outFile, \"wb+\");\n   if (argc==4)\n   {\n      bitsFile = argv[3];\n      fbits = fopen(bitsFile, \"wb\");\n   }\n   speex_bits_init(&bits);\n   while (!feof(fin))\n   {\n      fread(in_short, sizeof(short), FRAME_SIZE, fin);\n      if (feof(fin))\n         break;\n      speex_bits_reset(&bits);\n\n      speex_encode_int(st, in_short, &bits);\n      nbBits = speex_bits_write(&bits, cbits, 200);\n      bitCount+=bits.nbBits;\n\n      if (argc==4)\n         fwrite(cbits, 1, nbBits, fbits);\n      speex_bits_rewind(&bits);\n\n      speex_decode_int(dec, &bits, out_short);\n      speex_bits_reset(&bits);\n\n      fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);\n      skip_group_delay = 0;\n   }\n   fprintf (stderr, \"Total encoded size: %d bits\\n\", bitCount);\n   speex_encoder_destroy(st);\n   speex_decoder_destroy(dec);\n   speex_bits_destroy(&bits);\n\n   rewind(fin);\n   rewind(fout);\n\n   while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) \n           &&\n           FRAME_SIZE ==  fread(out_short, sizeof(short), FRAME_SIZE,fout) )\n   {\n\tfloat s=0, e=0;\n        for (i=0;i<FRAME_SIZE;++i) {\n            s += (float)in_short[i] * in_short[i];\n            e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);\n        }\n\tseg_snr += 10*log10((s+160)/(e+160));\n\tsigpow += s;\n\terrpow += e;\n\tsnr_frames++;\n   }\n   fclose(fin);\n   fclose(fout);\n\n   snr = 10 * log10( sigpow / errpow );\n   seg_snr /= snr_frames;\n   fprintf(stderr,\"SNR = %f\\nsegmental SNR = %f\\n\",snr, seg_snr);\n\n#ifdef FIXED_DEBUG\n   printf (\"Total: %f MIPS\\n\", (float)(1e-6*50*spx_mips/snr_frames));\n#endif\n   \n   return 1;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/testjitter.c",
    "content": "#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <speex/speex_jitter.h>\n#include <stdio.h>\n\nunion jbpdata {\n  unsigned int idx;\n  unsigned char data[4];\n};\n\nvoid synthIn(JitterBufferPacket *in, int idx, int span) {\n  union jbpdata d;\n  d.idx = idx;\n  \n  in->data = d.data;\n  in->len = sizeof(d);\n  in->timestamp = idx * 10;\n  in->span = span * 10;\n  in->sequence = idx;\n  in->user_data = 0;\n}\n\nvoid jitterFill(JitterBuffer *jb) {\n   char buffer[65536];\n   JitterBufferPacket in, out;\n   int i;\n\n   out.data = buffer;\n   \n   jitter_buffer_reset(jb);\n\n   for(i=0;i<100;++i) {\n     synthIn(&in, i, 1);\n     jitter_buffer_put(jb, &in);\n     \n     out.len = 65536;\n     if (jitter_buffer_get(jb, &out, 10, NULL) != JITTER_BUFFER_OK) {\n       printf(\"Fill test failed iteration %d\\n\", i);\n     }\n     if (out.timestamp != i * 10) {\n       printf(\"Fill test expected %d got %d\\n\", i*10, out.timestamp);\n     }\n     jitter_buffer_tick(jb);\n   }\n}\n\nint main()\n{\n   char buffer[65536];\n   JitterBufferPacket in, out;\n   int i;\n   \n   JitterBuffer *jb = jitter_buffer_init(10);\n   \n   out.data = buffer;\n   \n   /* Frozen sender case */\n   jitterFill(jb);\n   for(i=0;i<100;++i) {\n     out.len = 65536;\n     jitter_buffer_get(jb, &out, 10, NULL);\n     jitter_buffer_tick(jb);\n   }\n   synthIn(&in, 100, 1);\n   jitter_buffer_put(jb, &in);\n   out.len = 65536;\n   if (jitter_buffer_get(jb, &out, 10, NULL) != JITTER_BUFFER_OK) {\n     printf(\"Failed frozen sender resynchronize\\n\");\n   } else {\n     printf(\"Frozen sender: Jitter %d\\n\", out.timestamp - 100*10);\n   }\n   return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/testresample.c",
    "content": "/* Copyright (C) 2007 Jean-Marc Valin\n      \n   File: testresample.c\n   Testing the resampling code\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,\n   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdio.h>\n#include \"speex/speex_resampler.h\"\n#include <math.h>\n#include <stdlib.h>\n\n#define NN 256\n\nint main()\n{\n   spx_uint32_t i;\n   short *in;\n   short *out;\n   float *fin, *fout;\n   int count = 0;\n   SpeexResamplerState *st = speex_resampler_init(1, 8000, 12000, 10, NULL);\n   speex_resampler_set_rate(st, 96000, 44100);\n   speex_resampler_skip_zeros(st);\n   \n   in = malloc(NN*sizeof(short));\n   out = malloc(2*NN*sizeof(short));\n   fin = malloc(NN*sizeof(float));\n   fout = malloc(2*NN*sizeof(float));\n   while (1)\n   {\n      spx_uint32_t in_len;\n      spx_uint32_t out_len;\n      fread(in, sizeof(short), NN, stdin);\n      if (feof(stdin))\n         break;\n      for (i=0;i<NN;i++)\n         fin[i]=in[i];\n      in_len = NN;\n      out_len = 2*NN;\n      /*if (count==2)\n         speex_resampler_set_quality(st, 10);*/\n      speex_resampler_process_float(st, 0, fin, &in_len, fout, &out_len);\n      for (i=0;i<out_len;i++)\n         out[i]=floor(.5+fout[i]);\n      /*speex_warning_int(\"writing\", out_len);*/\n      fwrite(out, sizeof(short), out_len, stdout);\n      count++;\n   }\n   speex_resampler_destroy(st);\n   free(in);\n   free(out);\n   free(fin);\n   free(fout);\n   return 0;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/vbr.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin \n   File: vbr.c\n\n   VBR-related routines\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"vbr.h\"\n#include <math.h>\n\n\n#define sqr(x) ((x)*(x))\n\n#define MIN_ENERGY 6000\n#define NOISE_POW .3\n\n#ifndef DISABLE_VBR\n\nconst float vbr_nb_thresh[9][11]={\n   {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /*   CNG   */\n   { 4.0f,  2.5f,  2.0f,  1.2f,  0.5f,  0.0f, -0.5f, -0.7f, -0.8f, -0.9f, -1.0f}, /*  2 kbps */\n   {10.0f,  6.5f,  5.2f,  4.5f,  3.9f,  3.5f,  3.0f,  2.5f,  2.3f,  1.8f,  1.0f}, /*  6 kbps */\n   {11.0f,  8.8f,  7.5f,  6.5f,  5.0f,  3.9f,  3.9f,  3.9f,  3.5f,  3.0f,  1.0f}, /*  8 kbps */\n   {11.0f, 11.0f,  9.9f,  8.5f,  7.0f,  6.0f,  4.5f,  4.0f,  4.0f,  4.0f,  2.0f}, /* 11 kbps */\n   {11.0f, 11.0f, 11.0f, 11.0f,  9.5f,  8.5f,  8.0f,  7.0f,  6.0f,  5.0f,  3.0f}, /* 15 kbps */\n   {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f,  9.5f,  8.5f,  7.0f,  6.0f,  5.0f}, /* 18 kbps */\n   {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f,  9.8f,  9.5f,  7.5f}, /* 24 kbps */ \n   { 7.0f,  4.5f,  3.7f,  3.0f,  2.5f,  2.0f,  1.8f,  1.5f,  1.0f,  0.0f,  0.0f}  /*  4 kbps */\n};\n\n\nconst float vbr_hb_thresh[5][11]={\n   {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */\n   {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /*  2 kbps */\n   {11.0f, 11.0f,  9.5f,  8.5f,  7.5f,  6.0f,  5.0f,  3.9f,  3.0f,  2.0f,  1.0f}, /*  6 kbps */\n   {11.0f, 11.0f, 11.0f, 11.0f, 11.0f,  9.5f,  8.7f,  7.8f,  7.0f,  6.5f,  4.0f}, /* 10 kbps */\n   {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f,  9.8f,  7.5f,  5.5f}  /* 18 kbps */ \n};\n\nconst float vbr_uhb_thresh[2][11]={\n   {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */\n   { 3.9f,  2.5f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f, -1.0f}  /*  2 kbps */\n};\n\nvoid vbr_init(VBRState *vbr)\n{\n   int i;\n\n   vbr->average_energy=0;\n   vbr->last_energy=1;\n   vbr->accum_sum=0;\n   vbr->energy_alpha=.1;\n   vbr->soft_pitch=0;\n   vbr->last_pitch_coef=0;\n   vbr->last_quality=0;\n\n   vbr->noise_accum = .05*pow(MIN_ENERGY, NOISE_POW);\n   vbr->noise_accum_count=.05;\n   vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count;\n   vbr->consec_noise=0;\n\n\n   for (i=0;i<VBR_MEMORY_SIZE;i++)\n      vbr->last_log_energy[i] = log(MIN_ENERGY);\n}\n\n\n/*\n  This function should analyse the signal and decide how critical the\n  coding error will be perceptually. The following factors should be\n  taken into account:\n\n  -Attacks (positive energy derivative) should be coded with more bits\n\n  -Stationary voiced segments should receive more bits\n\n  -Segments with (very) low absolute energy should receive less bits (maybe\n  only shaped noise?)\n\n  -DTX for near-zero energy?\n\n  -Stationary fricative segments should have less bits\n\n  -Temporal masking: when energy slope is decreasing, decrease the bit-rate\n\n  -Decrease bit-rate for males (low pitch)?\n\n  -(wideband only) less bits in the high-band when signal is very \n  non-stationary (harder to notice high-frequency noise)???\n\n*/\n\nfloat vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float pitch_coef)\n{\n   int i;\n   float ener=0, ener1=0, ener2=0;\n   float qual=7;\n   int va;\n   float log_energy;\n   float non_st=0;\n   float voicing;\n   float pow_ener;\n\n   for (i=0;i<len>>1;i++)\n      ener1 += ((float)sig[i])*sig[i];\n\n   for (i=len>>1;i<len;i++)\n      ener2 += ((float)sig[i])*sig[i];\n   ener=ener1+ener2;\n\n   log_energy = log(ener+MIN_ENERGY);\n   for (i=0;i<VBR_MEMORY_SIZE;i++)\n      non_st += sqr(log_energy-vbr->last_log_energy[i]);\n   non_st =  non_st/(30*VBR_MEMORY_SIZE);\n   if (non_st>1)\n      non_st=1;\n\n   voicing = 3*(pitch_coef-.4)*fabs(pitch_coef-.4);\n   vbr->average_energy = (1-vbr->energy_alpha)*vbr->average_energy + vbr->energy_alpha*ener;\n   vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count;\n   pow_ener = pow(ener,NOISE_POW);\n   if (vbr->noise_accum_count<.06 && ener>MIN_ENERGY)\n      vbr->noise_accum = .05*pow_ener;\n\n   if ((voicing<.3 && non_st < .2 && pow_ener < 1.2*vbr->noise_level)\n       || (voicing<.3 && non_st < .05 && pow_ener < 1.5*vbr->noise_level)\n       || (voicing<.4 && non_st < .05 && pow_ener < 1.2*vbr->noise_level)\n       || (voicing<0 && non_st < .05))\n   {\n      float tmp;\n      va = 0;\n      vbr->consec_noise++;\n      if (pow_ener > 3*vbr->noise_level)\n         tmp = 3*vbr->noise_level;\n      else \n         tmp = pow_ener;\n      if (vbr->consec_noise>=4)\n      {\n         vbr->noise_accum = .95*vbr->noise_accum + .05*tmp;\n         vbr->noise_accum_count = .95*vbr->noise_accum_count + .05;\n      }\n   } else {\n      va = 1;\n      vbr->consec_noise=0;\n   }\n\n   if (pow_ener < vbr->noise_level && ener>MIN_ENERGY)\n   {\n      vbr->noise_accum = .95*vbr->noise_accum + .05*pow_ener;\n      vbr->noise_accum_count = .95*vbr->noise_accum_count + .05;      \n   }\n\n   /* Checking for very low absolute energy */\n   if (ener < 30000)\n   {\n      qual -= .7;\n      if (ener < 10000)\n         qual-=.7;\n      if (ener < 3000)\n         qual-=.7;\n   } else {\n      float short_diff, long_diff;\n      short_diff = log((ener+1)/(1+vbr->last_energy));\n      long_diff = log((ener+1)/(1+vbr->average_energy));\n      /*fprintf (stderr, \"%f %f\\n\", short_diff, long_diff);*/\n\n      if (long_diff<-5)\n         long_diff=-5;\n      if (long_diff>2)\n         long_diff=2;\n\n      if (long_diff>0)\n         qual += .6*long_diff;\n      if (long_diff<0)\n         qual += .5*long_diff;\n      if (short_diff>0)\n      {\n         if (short_diff>5)\n            short_diff=5;\n         qual += .5*short_diff;\n      }\n      /* Checking for energy increases */\n      if (ener2 > 1.6*ener1)\n         qual += .5;\n   }\n   vbr->last_energy = ener;\n   vbr->soft_pitch = .6*vbr->soft_pitch + .4*pitch_coef;\n   qual += 2.2*((pitch_coef-.4) + (vbr->soft_pitch-.4));\n\n   if (qual < vbr->last_quality)\n      qual = .5*qual + .5*vbr->last_quality;\n   if (qual<4)\n      qual=4;\n   if (qual>10)\n      qual=10;\n   \n   /*\n   if (vbr->consec_noise>=2)\n      qual-=1.3;\n   if (vbr->consec_noise>=5)\n      qual-=1.3;\n   if (vbr->consec_noise>=12)\n      qual-=1.3;\n   */\n   if (vbr->consec_noise>=3)\n      qual=4;\n\n   if (vbr->consec_noise)\n      qual -= 1.0 * (log(3.0 + vbr->consec_noise)-log(3));\n   if (qual<0)\n      qual=0;\n   \n   if (ener<60000)\n   {\n      if (vbr->consec_noise>2)\n         qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3));\n      if (ener<10000&&vbr->consec_noise>2)\n         qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3));\n      if (qual<0)\n         qual=0;\n      qual += .3*log(.0001+ener/60000.0);\n   }\n   if (qual<-1)\n      qual=-1;\n\n   /*printf (\"%f %f %f %f %d\\n\", qual, voicing, non_st, pow_ener/(.01+vbr->noise_level), va);*/\n\n   vbr->last_pitch_coef = pitch_coef;\n   vbr->last_quality = qual;\n\n   for (i=VBR_MEMORY_SIZE-1;i>0;i--)\n      vbr->last_log_energy[i] = vbr->last_log_energy[i-1];\n   vbr->last_log_energy[0] = log_energy;\n\n   /*printf (\"VBR: %f %f %f %d %f\\n\", (float)(log_energy-log(vbr->average_energy+MIN_ENERGY)), non_st, voicing, va, vbr->noise_level);*/\n\n   return qual;\n}\n\nvoid vbr_destroy(VBRState *vbr)\n{\n}\n\n#endif /* #ifndef DISABLE_VBR */\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/vbr.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin */\n/**\n   @file vbr.h\n   @brief Variable Bit-Rate (VBR) related routines\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n\n#ifndef VBR_H\n#define VBR_H\n\n#include \"arch.h\"\n\n#define VBR_MEMORY_SIZE 5\n\nextern const float vbr_nb_thresh[9][11];\nextern const float vbr_hb_thresh[5][11];\nextern const float vbr_uhb_thresh[2][11];\n\n/** VBR state. */\ntypedef struct VBRState {\n   float energy_alpha;\n   float average_energy;\n   float last_energy;\n   float last_log_energy[VBR_MEMORY_SIZE];\n   float accum_sum;\n   float last_pitch_coef;\n   float soft_pitch;\n   float last_quality;\n   float noise_level;\n   float noise_accum;\n   float noise_accum_count;\n   int   consec_noise;\n} VBRState;\n\nvoid vbr_init(VBRState *vbr);\n\nfloat vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float pitch_coef);\n\nvoid vbr_destroy(VBRState *vbr);\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/vorbis_psy.c",
    "content": "/* Copyright (C) 2005 Jean-Marc Valin, CSIRO, Christopher Montgomery\n   File: vorbis_psy.c\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#ifdef VORBIS_PSYCHO\n\n#include \"arch.h\"\n#include \"smallft.h\"\n#include \"lpc.h\"\n#include \"vorbis_psy.h\"\n\n#include <stdlib.h>\n#include <math.h>\n#include <string.h>\n\n/* psychoacoustic setup ********************************************/\n\nstatic VorbisPsyInfo example_tuning = {\n  \n  .5,.5,  \n  3,3,25,\n  \n  /*63     125     250     500      1k      2k      4k      8k     16k*/\n  // vorbis mode 4 style\n  //{-32,-32,-32,-32,-28,-24,-22,-20,-20, -20, -20, -8, -6, -6, -6, -6, -6},\n  { -4, -6, -6, -6, -6, -6, -6, -6, -8, -8,-10,-10, -8, -6, -4, -4, -2},\n  \n  {\n    0, 1, 2, 3, 4, 5, 5,  5,     /* 7dB */\n    6, 6, 6, 5, 4, 4, 4,  4,     /* 15dB */\n    4, 4, 5, 5, 5, 6, 6,  6,     /* 23dB */\n    7, 7, 7, 8, 8, 8, 9, 10,     /* 31dB */\n    11,12,13,14,15,16,17, 18,     /* 39dB */\n  }\n\n};\n\n\n\n/* there was no great place to put this.... */\n#include <stdio.h>\nstatic void _analysis_output(char *base,int i,float *v,int n,int bark,int dB){\n  int j;\n  FILE *of;\n  char buffer[80];\n\n  sprintf(buffer,\"%s_%d.m\",base,i);\n  of=fopen(buffer,\"w\");\n  \n  if(!of)perror(\"failed to open data dump file\");\n  \n  for(j=0;j<n;j++){\n    if(bark){\n      float b=toBARK((4000.f*j/n)+.25);\n      fprintf(of,\"%f \",b);\n    }else\n      fprintf(of,\"%f \",(double)j);\n    \n    if(dB){\n      float val;\n      if(v[j]==0.)\n\tval=-140.;\n      else\n\tval=todB(v[j]);\n      fprintf(of,\"%f\\n\",val);\n    }else{\n      fprintf(of,\"%f\\n\",v[j]);\n    }\n  }\n  fclose(of);\n}\n\nstatic void bark_noise_hybridmp(int n,const long *b,\n                                const float *f,\n                                float *noise,\n                                const float offset,\n                                const int fixed){\n  \n  float *N=alloca(n*sizeof(*N));\n  float *X=alloca(n*sizeof(*N));\n  float *XX=alloca(n*sizeof(*N));\n  float *Y=alloca(n*sizeof(*N));\n  float *XY=alloca(n*sizeof(*N));\n\n  float tN, tX, tXX, tY, tXY;\n  int i;\n\n  int lo, hi;\n  float R, A, B, D;\n  float w, x, y;\n\n  tN = tX = tXX = tY = tXY = 0.f;\n\n  y = f[0] + offset;\n  if (y < 1.f) y = 1.f;\n\n  w = y * y * .5;\n    \n  tN += w;\n  tX += w;\n  tY += w * y;\n\n  N[0] = tN;\n  X[0] = tX;\n  XX[0] = tXX;\n  Y[0] = tY;\n  XY[0] = tXY;\n\n  for (i = 1, x = 1.f; i < n; i++, x += 1.f) {\n    \n    y = f[i] + offset;\n    if (y < 1.f) y = 1.f;\n\n    w = y * y;\n    \n    tN += w;\n    tX += w * x;\n    tXX += w * x * x;\n    tY += w * y;\n    tXY += w * x * y;\n\n    N[i] = tN;\n    X[i] = tX;\n    XX[i] = tXX;\n    Y[i] = tY;\n    XY[i] = tXY;\n  }\n  \n  for (i = 0, x = 0.f;; i++, x += 1.f) {\n    \n    lo = b[i] >> 16;\n    if( lo>=0 ) break;\n    hi = b[i] & 0xffff;\n    \n    tN = N[hi] + N[-lo];\n    tX = X[hi] - X[-lo];\n    tXX = XX[hi] + XX[-lo];\n    tY = Y[hi] + Y[-lo];    \n    tXY = XY[hi] - XY[-lo];\n    \n    A = tY * tXX - tX * tXY;\n    B = tN * tXY - tX * tY;\n    D = tN * tXX - tX * tX;\n    R = (A + x * B) / D;\n    if (R < 0.f)\n      R = 0.f;\n    \n    noise[i] = R - offset;\n  }\n  \n  for ( ;; i++, x += 1.f) {\n    \n    lo = b[i] >> 16;\n    hi = b[i] & 0xffff;\n    if(hi>=n)break;\n    \n    tN = N[hi] - N[lo];\n    tX = X[hi] - X[lo];\n    tXX = XX[hi] - XX[lo];\n    tY = Y[hi] - Y[lo];\n    tXY = XY[hi] - XY[lo];\n    \n    A = tY * tXX - tX * tXY;\n    B = tN * tXY - tX * tY;\n    D = tN * tXX - tX * tX;\n    R = (A + x * B) / D;\n    if (R < 0.f) R = 0.f;\n    \n    noise[i] = R - offset;\n  }\n  for ( ; i < n; i++, x += 1.f) {\n    \n    R = (A + x * B) / D;\n    if (R < 0.f) R = 0.f;\n    \n    noise[i] = R - offset;\n  }\n  \n  if (fixed <= 0) return;\n  \n  for (i = 0, x = 0.f;; i++, x += 1.f) {\n    hi = i + fixed / 2;\n    lo = hi - fixed;\n    if(lo>=0)break;\n\n    tN = N[hi] + N[-lo];\n    tX = X[hi] - X[-lo];\n    tXX = XX[hi] + XX[-lo];\n    tY = Y[hi] + Y[-lo];\n    tXY = XY[hi] - XY[-lo];\n    \n    \n    A = tY * tXX - tX * tXY;\n    B = tN * tXY - tX * tY;\n    D = tN * tXX - tX * tX;\n    R = (A + x * B) / D;\n\n    if (R - offset < noise[i]) noise[i] = R - offset;\n  }\n  for ( ;; i++, x += 1.f) {\n    \n    hi = i + fixed / 2;\n    lo = hi - fixed;\n    if(hi>=n)break;\n    \n    tN = N[hi] - N[lo];\n    tX = X[hi] - X[lo];\n    tXX = XX[hi] - XX[lo];\n    tY = Y[hi] - Y[lo];\n    tXY = XY[hi] - XY[lo];\n    \n    A = tY * tXX - tX * tXY;\n    B = tN * tXY - tX * tY;\n    D = tN * tXX - tX * tX;\n    R = (A + x * B) / D;\n    \n    if (R - offset < noise[i]) noise[i] = R - offset;\n  }\n  for ( ; i < n; i++, x += 1.f) {\n    R = (A + x * B) / D;\n    if (R - offset < noise[i]) noise[i] = R - offset;\n  }\n}\n\nstatic void _vp_noisemask(VorbisPsy *p,\n\t\t\t  float *logfreq, \n\t\t\t  float *logmask){\n\n  int i,n=p->n/2;\n  float *work=alloca(n*sizeof(*work));\n\n  bark_noise_hybridmp(n,p->bark,logfreq,logmask,\n\t\t      140.,-1);\n\n  for(i=0;i<n;i++)work[i]=logfreq[i]-logmask[i];\n\n  bark_noise_hybridmp(n,p->bark,work,logmask,0.,\n\t\t      p->vi->noisewindowfixed);\n\n  for(i=0;i<n;i++)work[i]=logfreq[i]-work[i];\n  \n  {\n    static int seq=0;\n    \n    float work2[n];\n    for(i=0;i<n;i++){\n      work2[i]=logmask[i]+work[i];\n    }\n    \n    //_analysis_output(\"logfreq\",seq,logfreq,n,0,0);\n    //_analysis_output(\"median\",seq,work,n,0,0);\n    //_analysis_output(\"envelope\",seq,work2,n,0,0);\n    seq++;\n  }\n\n  for(i=0;i<n;i++){\n    int dB=logmask[i]+.5;\n    if(dB>=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1;\n    if(dB<0)dB=0;\n    logmask[i]= work[i]+p->vi->noisecompand[dB]+p->noiseoffset[i];\n  }\n\n}\n\nVorbisPsy *vorbis_psy_init(int rate, int n)\n{\n  long i,j,lo=-99,hi=1;\n  VorbisPsy *p = speex_alloc(sizeof(VorbisPsy));\n  memset(p,0,sizeof(*p));\n  \n  p->n = n;\n  spx_drft_init(&p->lookup, n);\n  p->bark = speex_alloc(n*sizeof(*p->bark));\n  p->rate=rate;\n  p->vi = &example_tuning;\n\n  /* BH4 window */\n  p->window = speex_alloc(sizeof(*p->window)*n);\n  float a0 = .35875f;\n  float a1 = .48829f;\n  float a2 = .14128f;\n  float a3 = .01168f;\n  for(i=0;i<n;i++)\n    p->window[i] = //a0 - a1*cos(2.*M_PI/n*(i+.5)) + a2*cos(4.*M_PI/n*(i+.5)) - a3*cos(6.*M_PI/n*(i+.5));\n      sin((i+.5)/n * M_PI)*sin((i+.5)/n * M_PI);\n  /* bark scale lookups */\n  for(i=0;i<n;i++){\n    float bark=toBARK(rate/(2*n)*i); \n    \n    for(;lo+p->vi->noisewindowlomin<i && \n\t  toBARK(rate/(2*n)*lo)<(bark-p->vi->noisewindowlo);lo++);\n    \n    for(;hi<=n && (hi<i+p->vi->noisewindowhimin ||\n\t  toBARK(rate/(2*n)*hi)<(bark+p->vi->noisewindowhi));hi++);\n    \n    p->bark[i]=((lo-1)<<16)+(hi-1);\n\n  }\n\n  /* set up rolling noise median */\n  p->noiseoffset=speex_alloc(n*sizeof(*p->noiseoffset));\n  \n  for(i=0;i<n;i++){\n    float halfoc=toOC((i+.5)*rate/(2.*n))*2.;\n    int inthalfoc;\n    float del;\n    \n    if(halfoc<0)halfoc=0;\n    if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1;\n    inthalfoc=(int)halfoc;\n    del=halfoc-inthalfoc;\n    \n    p->noiseoffset[i]=\n      p->vi->noiseoff[inthalfoc]*(1.-del) + \n      p->vi->noiseoff[inthalfoc+1]*del;\n    \n  }\n#if 0\n  _analysis_output_always(\"noiseoff0\",ls,p->noiseoffset,n,1,0,0);\n#endif\n\n   return p;\n}\n\nvoid vorbis_psy_destroy(VorbisPsy *p)\n{\n  if(p){\n    spx_drft_clear(&p->lookup);\n    if(p->bark)\n      speex_free(p->bark);\n    if(p->noiseoffset)\n      speex_free(p->noiseoffset);\n    if(p->window)\n      speex_free(p->window);\n    memset(p,0,sizeof(*p));\n    speex_free(p);\n  }\n}\n\nvoid compute_curve(VorbisPsy *psy, float *audio, float *curve)\n{\n   int i;\n   float work[psy->n];\n\n   float scale=4.f/psy->n;\n   float scale_dB;\n\n   scale_dB=todB(scale);\n  \n   /* window the PCM data; use a BH4 window, not vorbis */\n   for(i=0;i<psy->n;i++)\n     work[i]=audio[i] * psy->window[i];\n\n   {\n     static int seq=0;\n     \n     //_analysis_output(\"win\",seq,work,psy->n,0,0);\n\n     seq++;\n   }\n\n    /* FFT yields more accurate tonal estimation (not phase sensitive) */\n    spx_drft_forward(&psy->lookup,work);\n\n    /* magnitudes */\n    work[0]=scale_dB+todB(work[0]);\n    for(i=1;i<psy->n-1;i+=2){\n      float temp = work[i]*work[i] + work[i+1]*work[i+1];\n      work[(i+1)>>1] = scale_dB+.5f * todB(temp);\n    }\n\n    /* derive a noise curve */\n    _vp_noisemask(psy,work,curve);\n#define SIDEL 12\n    for (i=0;i<SIDEL;i++)\n    {\n       curve[i]=curve[SIDEL];\n    }\n#define SIDEH 12\n    for (i=0;i<SIDEH;i++)\n    {\n       curve[(psy->n>>1)-i-1]=curve[(psy->n>>1)-SIDEH];\n    }\n    for(i=0;i<((psy->n)>>1);i++)\n       curve[i] = fromdB(1.2*curve[i]+.2*i);\n       //curve[i] = fromdB(0.8*curve[i]+.35*i);\n       //curve[i] = fromdB(0.9*curve[i])*pow(1.0*i+45,1.3);\n}\n\n/* Transform a masking curve (power spectrum) into a pole-zero filter */\nvoid curve_to_lpc(VorbisPsy *psy, float *curve, float *awk1, float *awk2, int ord)\n{\n   int i;\n   float ac[psy->n];\n   float tmp;\n   int len = psy->n >> 1;\n   for (i=0;i<2*len;i++)\n      ac[i] = 0;\n   for (i=1;i<len;i++)\n      ac[2*i-1] = curve[i];\n   ac[0] = curve[0];\n   ac[2*len-1] = curve[len-1];\n   \n   spx_drft_backward(&psy->lookup, ac);\n   _spx_lpc(awk1, ac, ord);\n   tmp = 1.;\n   for (i=0;i<ord;i++)\n   {\n      tmp *= .99;\n      awk1[i] *= tmp;\n   }\n#if 0\n   for (i=0;i<ord;i++)\n      awk2[i] = 0;\n#else\n   /* Use the second (awk2) filter to correct the first one */\n   for (i=0;i<2*len;i++)\n      ac[i] = 0;   \n   for (i=0;i<ord;i++)\n      ac[i+1] = awk1[i];\n   ac[0] = 1;\n   spx_drft_forward(&psy->lookup, ac);\n   /* Compute (power) response of awk1 (all zero) */\n   ac[0] *= ac[0];\n   for (i=1;i<len;i++)\n      ac[i] = ac[2*i-1]*ac[2*i-1] + ac[2*i]*ac[2*i];\n   ac[len] = ac[2*len-1]*ac[2*len-1];\n   /* Compute correction required */\n   for (i=0;i<len;i++)\n      curve[i] = 1. / (1e-6f+curve[i]*ac[i]);\n\n   for (i=0;i<2*len;i++)\n      ac[i] = 0;\n   for (i=1;i<len;i++)\n      ac[2*i-1] = curve[i];\n   ac[0] = curve[0];\n   ac[2*len-1] = curve[len-1];\n   \n   spx_drft_backward(&psy->lookup, ac);\n   _spx_lpc(awk2, ac, ord);\n   tmp = 1;\n   for (i=0;i<ord;i++)\n   {\n      tmp *= .99;\n      awk2[i] *= tmp;\n   }\n#endif\n}\n\n#if 0\n#include <stdio.h>\n#include <math.h>\n\n#define ORDER 10\n#define CURVE_SIZE 24\n\nint main()\n{\n   int i;\n   float curve[CURVE_SIZE];\n   float awk1[ORDER], awk2[ORDER];\n   for (i=0;i<CURVE_SIZE;i++)\n      scanf(\"%f \", &curve[i]);\n   for (i=0;i<CURVE_SIZE;i++)\n      curve[i] = pow(10.f, .1*curve[i]);\n   curve_to_lpc(curve, CURVE_SIZE, awk1, awk2, ORDER);\n   for (i=0;i<ORDER;i++)\n      printf(\"%f \", awk1[i]);\n   printf (\"\\n\");\n   for (i=0;i<ORDER;i++)\n      printf(\"%f \", awk2[i]);\n   printf (\"\\n\");\n   return 0;\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/vorbis_psy.h",
    "content": "/* Copyright (C) 2005 Jean-Marc Valin, CSIRO, Christopher Montgomery\n   File: vorbis_psy.h\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef VORBIS_PSY_H\n#define VORBIS_PSY_H\n\n#ifdef VORBIS_PSYCHO\n\n#include \"smallft.h\"\n#define P_BANDS 17      /* 62Hz to 16kHz */\n#define NOISE_COMPAND_LEVELS 40\n\n\n#define todB(x)   ((x)>1e-13?log((x)*(x))*4.34294480f:-30)\n#define fromdB(x) (exp((x)*.11512925f))  \n\n/* The bark scale equations are approximations, since the original\n   table was somewhat hand rolled.  The below are chosen to have the\n   best possible fit to the rolled tables, thus their somewhat odd\n   appearance (these are more accurate and over a longer range than\n   the oft-quoted bark equations found in the texts I have).  The\n   approximations are valid from 0 - 30kHz (nyquist) or so.\n\n   all f in Hz, z in Bark */\n\n#define toBARK(n)   (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))\n#define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f)\n\n/* Frequency to octave.  We arbitrarily declare 63.5 Hz to be octave\n   0.0 */\n\n#define toOC(n)     (log(n)*1.442695f-5.965784f)\n#define fromOC(o)   (exp(((o)+5.965784f)*.693147f))\n\n\ntypedef struct {\n\n  float noisewindowlo;\n  float noisewindowhi;\n  int   noisewindowlomin;\n  int   noisewindowhimin;\n  int   noisewindowfixed;\n  float noiseoff[P_BANDS];\n  float noisecompand[NOISE_COMPAND_LEVELS];\n\n} VorbisPsyInfo;\n\n\n\ntypedef struct {\n  int n;\n  int rate;\n  struct drft_lookup lookup;\n  VorbisPsyInfo *vi;\n\n  float *window;\n  float *noiseoffset;\n  long  *bark;\n\n} VorbisPsy;\n\n\nVorbisPsy *vorbis_psy_init(int rate, int size);\nvoid vorbis_psy_destroy(VorbisPsy *psy);\nvoid compute_curve(VorbisPsy *psy, float *audio, float *curve);\nvoid curve_to_lpc(VorbisPsy *psy, float *curve, float *awk1, float *awk2, int ord);\n\n#endif\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/vq.c",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin\n   File: vq.c\n   Vector quantization\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"vq.h\"\n#include \"stack_alloc.h\"\n#include \"arch.h\"\n\n#ifdef _USE_SSE\n#include <xmmintrin.h>\n#include \"vq_sse.h\"\n#elif defined(SHORTCUTS) && (defined(ARM4_ASM) || defined(ARM5E_ASM))\n#include \"vq_arm4.h\"\n#elif defined(BFIN_ASM)\n#include \"vq_bfin.h\"\n#endif\n\n\nint scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries)\n{\n   int i=0;\n   while (i<entries-1 && in>boundary[0])\n   {\n      boundary++;\n      i++;\n   }\n   return i;\n}\n\nint scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries)\n{\n   int i=0;\n   while (i<entries-1 && in>boundary[0])\n   {\n      boundary++;\n      i++;\n   }\n   return i;\n}\n\n\n#ifndef OVERRIDE_VQ_NBEST\n/*Finds the indices of the n-best entries in a codebook*/\nvoid vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)\n{\n   int i,j,k,used;\n   used = 0;\n   for (i=0;i<entries;i++)\n   {\n      spx_word32_t dist=0;\n      for (j=0;j<len;j++)\n         dist = MAC16_16(dist,in[j],*codebook++);\n#ifdef FIXED_POINT\n      dist=SUB32(SHR32(E[i],1),dist);\n#else\n      dist=.5f*E[i]-dist;\n#endif\n      if (i<N || dist<best_dist[N-1])\n      {\n         for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--)\n         {\n            best_dist[k]=best_dist[k-1];\n            nbest[k] = nbest[k-1];\n         }\n         best_dist[k]=dist;\n         nbest[k]=i;\n         used++;\n      }\n   }\n}\n#endif\n\n\n\n\n#ifndef OVERRIDE_VQ_NBEST_SIGN\n/*Finds the indices of the n-best entries in a codebook with sign*/\nvoid vq_nbest_sign(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)\n{\n   int i,j,k, sign, used;\n   used=0;\n   for (i=0;i<entries;i++)\n   {\n      spx_word32_t dist=0;\n      for (j=0;j<len;j++)\n         dist = MAC16_16(dist,in[j],*codebook++);\n      if (dist>0)\n      {\n         sign=0;\n         dist=-dist;\n      } else\n      {\n         sign=1;\n      }\n#ifdef FIXED_POINT\n      dist = ADD32(dist,SHR32(E[i],1));\n#else\n      dist = ADD32(dist,.5f*E[i]);\n#endif\n      if (i<N || dist<best_dist[N-1])\n      {\n         for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--)\n         {\n            best_dist[k]=best_dist[k-1];\n            nbest[k] = nbest[k-1];\n         }\n         best_dist[k]=dist;\n         nbest[k]=i;\n         used++;\n         if (sign)\n            nbest[k]+=entries;\n      }\n   }\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/vq.h",
    "content": "/* Copyright (C) 2002 Jean-Marc Valin */\n/**\n   @file vq.h\n   @brief Vector quantization\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef VQ_H\n#define VQ_H\n\n#include \"arch.h\"\n\nint scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries);\nint scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries);\n\n#ifdef _USE_SSE\n#include <xmmintrin.h>\nvoid vq_nbest(spx_word16_t *in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);\n\nvoid vq_nbest_sign(spx_word16_t *in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);\n#else\nvoid vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);\n\nvoid vq_nbest_sign(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/vq_arm4.h",
    "content": "/* Copyright (C) 2004 Jean-Marc Valin */\n/**\n   @file vq_arm4.h\n   @brief ARM4-optimized vq routine\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#define OVERRIDE_VQ_NBEST\nvoid vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)\n{\n   int i,j;\n   for (i=0;i<entries;i+=4)\n   {\n#if 1\n      spx_word32_t dist1, dist2, dist3, dist4;\n      int dead1, dead2, dead3, dead4, dead5, dead6, dead7, dead8;\n      __asm__ __volatile__ (\n            \"mov %0, #0 \\n\\t\"\n            \"mov %1, #0 \\n\\t\"\n            \"mov %2, #0 \\n\\t\"\n            \"mov %3, #0 \\n\\t\"\n            \"mov %10, %4 \\n\\t\"\n            \"add %4, %4, %4\\n\\t\"\n            \".vqloop%=:\\n\\t\"\n            \"ldrsh %7, [%5], #2 \\n\\t\"\n            \"ldrsh %8, [%6] \\n\\t\"\n            \"mov %9, %6 \\n\\t\"\n            \"mla %0, %7, %8, %0 \\n\\t\"\n            \"ldrsh %8, [%9, %4]! \\n\\t\"\n            \"mla %1, %7, %8, %1 \\n\\t\"\n            \"ldrsh %8, [%9, %4]!\\n\\t\"\n            \"mla %2, %7, %8, %2 \\n\\t\"\n            \"ldrsh %8, [%9, %4]! \\n\\t\"\n            \"mla %3, %7, %8, %3 \\n\\t\"\n            \"subs %10, %10, #1 \\n\\t\"\n            \"add %6, %6, #2 \\n\\t\"\n            \"bne .vqloop%=\"\n         : \"=r\" (dist1), \"=r\" (dist2), \"=r\" (dist3), \"=r\" (dist4),\n      \"=r\" (dead1), \"=r\" (dead2), \"=r\" (codebook), \"=r\" (dead4),\n      \"=r\" (dead5), \"=r\" (dead6), \"=r\" (dead7)\n         : \"4\" (len), \"5\" (in), \"6\" (codebook)\n         : \"cc\");\n#else\ndist1=dist2=dist3=dist4=0;\n   /*   spx_word32_t dist1=0;\n      spx_word32_t dist2=0;\n      spx_word32_t dist3=0;\n      spx_word32_t dist4=0;*/\n      for (j=0;j<2;j++)\n      {\n         const spx_word16_t *code = codebook;\n         dist1 = MAC16_16(dist1,in[j],*code);\n         code += len;\n         dist2 = MAC16_16(dist2,in[j],*code);\n         code += len;\n         dist3 = MAC16_16(dist3,in[j],*code);\n         code += len;\n         dist4 = MAC16_16(dist4,in[j],*code);\n         codebook++;\n      }\n#endif\n      dist1=SUB32(SHR(*E++,1),dist1);\n      if (dist1<*best_dist || i==0)\n      {\n         *best_dist=dist1;\n         *nbest=i;\n      }\n      dist2=SUB32(SHR(*E++,1),dist2);\n      if (dist2<*best_dist)\n      {\n         *best_dist=dist2;\n         *nbest=i+1;\n      }\n      dist3=SUB32(SHR(*E++,1),dist3);\n      if (dist3<*best_dist)\n      {\n         *best_dist=dist3;\n         *nbest=i+2;\n      }\n      dist4=SUB32(SHR(*E++,1),dist4);\n      if (dist4<*best_dist)\n      {\n         *best_dist=dist4;\n         *nbest=i+3;\n      }\n      codebook += 3*len;\n   }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/vq_bfin.h",
    "content": "/* Copyright (C) 2005 Analog Devices */\n/**\n   @file vq_bfin.h\n   @author Jean-Marc Valin \n   @brief Blackfin-optimized vq routine\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#define OVERRIDE_VQ_NBEST\nvoid vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)\n{\n   if (N==1)\n   {\n      best_dist[0] = 2147483647;\n      {\n         spx_word32_t dist;\n         __asm__ __volatile__\n               (\n            \"LC0 = %8;\\n\\t\"\n            \"R2 = 0;\\n\\t\"\n            \"I0 = %6;\\n\\t\"\n            \"B0 = %6;\\n\\t\"\n            \"L0 = %9;\\n\\t\"\n            \"LOOP entries_loop%= LC0;\\n\\t\"\n            \"LOOP_BEGIN entries_loop%=;\\n\\t\"\n               \"%0 = [%4++];\\n\\t\"\n               \"%0 >>= 1;\\n\\t\"\n               \"A0 = %0;\\n\\t\"\n               \"R0.L = W[%1++%7] || R1.L = W[I0++];\\n\\t\"\n               \"LOOP vq_loop%= LC1 = %5;\\n\\t\"\n               \"LOOP_BEGIN vq_loop%=;\\n\\t\"\n                  \"%0 = (A0 -= R0.L*R1.L) (IS) || R0.L = W[%1++%7] || R1.L = W[I0++];\\n\\t\"\n               \"LOOP_END vq_loop%=;\\n\\t\"\n               \"%0 = (A0 -= R0.L*R1.L) (IS);\\n\\t\"\n               \"cc = %0 < %2;\\n\\t\"\n               \"if cc %2 = %0;\\n\\t\"\n               \"if cc %3 = R2;\\n\\t\"\n               \"R2 += 1;\\n\\t\"\n            \"LOOP_END entries_loop%=;\\n\\t\"\n            : \"=&D\" (dist), \"=&a\" (codebook), \"=&d\" (best_dist[0]), \"=&d\" (nbest[0]), \"=&a\" (E)\n            : \"a\" (len-1), \"a\" (in), \"a\" (2), \"d\" (entries), \"d\" (len<<1), \"1\" (codebook), \"4\" (E), \"2\" (best_dist[0]), \"3\" (nbest[0])\n            : \"R0\", \"R1\", \"R2\", \"I0\", \"L0\", \"B0\", \"A0\", \"cc\", \"memory\"\n               );\n      }\n   } else {\n   int i,k,used;\n   used = 0;\n   for (i=0;i<entries;i++)\n   {\n      spx_word32_t dist;\n      __asm__\n            (\n            \"%0 >>= 1;\\n\\t\"\n            \"A0 = %0;\\n\\t\"\n            \"I0 = %3;\\n\\t\"\n            \"L0 = 0;\\n\\t\"\n            \"R0.L = W[%1++%4] || R1.L = W[I0++];\\n\\t\"\n            \"LOOP vq_loop%= LC0 = %2;\\n\\t\"\n            \"LOOP_BEGIN vq_loop%=;\\n\\t\"\n               \"%0 = (A0 -= R0.L*R1.L) (IS) || R0.L = W[%1++%4] || R1.L = W[I0++];\\n\\t\"\n            \"LOOP_END vq_loop%=;\\n\\t\"\n            \"%0 = (A0 -= R0.L*R1.L) (IS);\\n\\t\"\n         : \"=D\" (dist), \"=a\" (codebook)\n         : \"a\" (len-1), \"a\" (in), \"a\" (2), \"1\" (codebook), \"0\" (E[i])\n         : \"R0\", \"R1\", \"I0\", \"L0\", \"A0\"\n            );\n      if (i<N || dist<best_dist[N-1])\n      {\n         for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--)\n         {\n            best_dist[k]=best_dist[k-1];\n            nbest[k] = nbest[k-1];\n         }\n         best_dist[k]=dist;\n         nbest[k]=i;\n         used++;\n      }\n   }\n   }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/vq_sse.h",
    "content": "/* Copyright (C) 2004 Jean-Marc Valin */\n/**\n   @file vq_sse.h\n   @brief SSE-optimized vq routine\n*/\n/*\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#define OVERRIDE_VQ_NBEST\nvoid vq_nbest(spx_word16_t *_in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)\n{\n   int i,j,k,used;\n   VARDECL(float *dist);\n   VARDECL(__m128 *in);\n   __m128 half;\n   used = 0;\n   ALLOC(dist, entries, float);\n   half = _mm_set_ps1(.5f);\n   ALLOC(in, len, __m128);\n   for (i=0;i<len;i++)\n      in[i] = _mm_set_ps1(_in[i]);\n   for (i=0;i<entries>>2;i++)\n   {\n      __m128 d = _mm_mul_ps(E[i], half);\n      for (j=0;j<len;j++)\n         d = _mm_sub_ps(d, _mm_mul_ps(in[j], *codebook++));\n      _mm_storeu_ps(dist+4*i, d);\n   }\n   for (i=0;i<entries;i++)\n   {\n      if (i<N || dist[i]<best_dist[N-1])\n      {\n         for (k=N-1; (k >= 1) && (k > used || dist[i] < best_dist[k-1]); k--)\n         {\n            best_dist[k]=best_dist[k-1];\n            nbest[k] = nbest[k-1];\n         }\n         best_dist[k]=dist[i];\n         nbest[k]=i;\n         used++;\n      }\n   }\n}\n\n\n\n\n#define OVERRIDE_VQ_NBEST_SIGN\nvoid vq_nbest_sign(spx_word16_t *_in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)\n{\n   int i,j,k,used;\n   VARDECL(float *dist);\n   VARDECL(__m128 *in);\n   __m128 half;\n   used = 0;\n   ALLOC(dist, entries, float);\n   half = _mm_set_ps1(.5f);\n   ALLOC(in, len, __m128);\n   for (i=0;i<len;i++)\n      in[i] = _mm_set_ps1(_in[i]);\n   for (i=0;i<entries>>2;i++)\n   {\n      __m128 d = _mm_setzero_ps();\n      for (j=0;j<len;j++)\n         d = _mm_add_ps(d, _mm_mul_ps(in[j], *codebook++));\n      _mm_storeu_ps(dist+4*i, d);\n   }\n   for (i=0;i<entries;i++)\n   {\n      int sign;\n      if (dist[i]>0)\n      {\n         sign=0;\n         dist[i]=-dist[i];\n      } else\n      {\n         sign=1;\n      }\n      dist[i] += .5f*((float*)E)[i];\n      if (i<N || dist[i]<best_dist[N-1])\n      {\n         for (k=N-1; (k >= 1) && (k > used || dist[i] < best_dist[k-1]); k--)\n         {\n            best_dist[k]=best_dist[k-1];\n            nbest[k] = nbest[k-1];\n         }\n         best_dist[k]=dist[i];\n         nbest[k]=i;\n         used++;\n         if (sign)\n            nbest[k]+=entries;\n      }\n   }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/libspeex/window.c",
    "content": "/* Copyright (C) 2006 Jean-Marc Valin \n   File: window.c\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n   \n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n   \n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n   \n   - Neither the name of the Xiph.org Foundation nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n   \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arch.h\"\n\n#ifdef FIXED_POINT\nconst spx_word16_t lag_window[11] = {\n   16384, 16337, 16199, 15970, 15656, 15260, 14790, 14254, 13659, 13015, 12330\n};\n\nconst spx_word16_t lpc_window[200] = {\n1310, 1313, 1321, 1333, 1352, 1375, 1403, 1436,\n1475, 1518, 1567, 1621, 1679, 1743, 1811, 1884,\n1962, 2044, 2132, 2224, 2320, 2421, 2526, 2636,\n2750, 2868, 2990, 3116, 3246, 3380, 3518, 3659,\n3804, 3952, 4104, 4259, 4417, 4578, 4742, 4909,\n5079, 5251, 5425, 5602, 5781, 5963, 6146, 6331,\n6518, 6706, 6896, 7087, 7280, 7473, 7668, 7863,\n8059, 8256, 8452, 8650, 8847, 9044, 9241, 9438,\n9635, 9831, 10026, 10220, 10414, 10606, 10797, 10987,\n11176, 11363, 11548, 11731, 11912, 12091, 12268, 12443,\n12615, 12785, 12952, 13116, 13277, 13435, 13590, 13742,\n13890, 14035, 14176, 14314, 14448, 14578, 14704, 14826,\n14944, 15058, 15168, 15273, 15374, 15470, 15562, 15649,\n15732, 15810, 15883, 15951, 16015, 16073, 16127, 16175,\n16219, 16257, 16291, 16319, 16342, 16360, 16373, 16381,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16384, 16384, 16361, 16294, 16183, 16028, 15830,\n15588, 15304, 14979, 14613, 14207, 13763, 13282, 12766,\n12215, 11631, 11016, 10373, 9702, 9007, 8289, 7551,\n6797, 6028, 5251, 4470, 3695, 2943, 2248, 1696\n};\n#else\nconst spx_word16_t lag_window[11] = {\n   1.00000, 0.99716, 0.98869, 0.97474, 0.95554, 0.93140, 0.90273, 0.86998, 0.83367, 0.79434, 0.75258\n};\n\nconst spx_word16_t lpc_window[200] = {\n   0.080000f, 0.080158f, 0.080630f, 0.081418f, 0.082520f, 0.083935f, 0.085663f, 0.087703f,\n   0.090052f, 0.092710f, 0.095674f, 0.098943f, 0.102514f, 0.106385f, 0.110553f, 0.115015f,\n   0.119769f, 0.124811f, 0.130137f, 0.135744f, 0.141628f, 0.147786f, 0.154212f, 0.160902f,\n   0.167852f, 0.175057f, 0.182513f, 0.190213f, 0.198153f, 0.206328f, 0.214731f, 0.223357f,\n   0.232200f, 0.241254f, 0.250513f, 0.259970f, 0.269619f, 0.279453f, 0.289466f, 0.299651f,\n   0.310000f, 0.320507f, 0.331164f, 0.341965f, 0.352901f, 0.363966f, 0.375151f, 0.386449f,\n   0.397852f, 0.409353f, 0.420943f, 0.432615f, 0.444361f, 0.456172f, 0.468040f, 0.479958f,\n   0.491917f, 0.503909f, 0.515925f, 0.527959f, 0.540000f, 0.552041f, 0.564075f, 0.576091f,\n   0.588083f, 0.600042f, 0.611960f, 0.623828f, 0.635639f, 0.647385f, 0.659057f, 0.670647f,\n   0.682148f, 0.693551f, 0.704849f, 0.716034f, 0.727099f, 0.738035f, 0.748836f, 0.759493f,\n   0.770000f, 0.780349f, 0.790534f, 0.800547f, 0.810381f, 0.820030f, 0.829487f, 0.838746f,\n   0.847800f, 0.856643f, 0.865269f, 0.873672f, 0.881847f, 0.889787f, 0.897487f, 0.904943f,\n   0.912148f, 0.919098f, 0.925788f, 0.932214f, 0.938372f, 0.944256f, 0.949863f, 0.955189f,\n   0.960231f, 0.964985f, 0.969447f, 0.973615f, 0.977486f, 0.981057f, 0.984326f, 0.987290f,\n   0.989948f, 0.992297f, 0.994337f, 0.996065f, 0.997480f, 0.998582f, 0.999370f, 0.999842f,\n   1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,\n   1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,\n   1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,\n   1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,\n   1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,\n   1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,\n   1.000000f, 1.000000f, 1.000000f, 0.998640f, 0.994566f, 0.987787f, 0.978324f, 0.966203f,\n   0.951458f, 0.934131f, 0.914270f, 0.891931f, 0.867179f, 0.840084f, 0.810723f, 0.779182f,\n   0.745551f, 0.709930f, 0.672424f, 0.633148f, 0.592223f, 0.549781f, 0.505964f, 0.460932f,\n   0.414863f, 0.367968f, 0.320511f, 0.272858f, 0.225569f, 0.179655f, 0.137254f, 0.103524f\n};\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/symbian/config.h",
    "content": "/*\n   Copyright (C) 2003 Commonwealth Scientific and Industrial Research\n   Organisation (CSIRO) Australia\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   - Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n   - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n   - Neither the name of CSIRO Australia nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n   PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef CONFIG_H\n#define CONFIG_H\n\n/* An inline macro is required for use of the inline keyword as not all C compilers support */\n/* inline.  It is officially C99 and C++ only */\n\n#ifdef __WINS__\n\n#define inline __inline\n\n/* Disable some pointless/stupid warnings */\n\n#pragma warning(disable: 4100) /* unreferenced formal parameter */\n#pragma warning(disable: 4127) /* conditional expression is constant */\n#pragma warning(disable: 4305) /* truncation from '...' to '...' */\n#pragma warning(disable: 4244) /* conversion from '...' to '...', possible loss of data */\n#pragma warning(disable: 4701) /* local variable may be be used without having been initialized */\n\n#endif /* ! __WINS__ */\n\n/* Use only fixed point arithmetic */\n\n#define FIXED_POINT 1\n#define USE_KISS_FFT\n#define EXPORT\n\n#endif /* ! CONFIG_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/speex/win32/config.h",
    "content": "// Microsoft version of 'inline'\n#define inline __inline\n\n// Visual Studio support alloca(), but it always align variables to 16-bit\n// boundary, while SSE need 128-bit alignment. So we disable alloca() when\n// SSE is enabled.\n#ifndef _USE_SSE\n#  define USE_ALLOCA\n#endif\n\n/* Default to floating point */\n#ifndef FIXED_POINT\n#  define USE_SMALLFT\n#else\n#  define USE_KISS_FFT\n#endif\n\n/* We don't support visibility on Win32 */\n#define EXPORT\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/CHANGES",
    "content": "Changelog\n\n1.3.20\n\n  Lots of changes.  Thanks to Jeff Chan for catching a memory leak and\n  helping track down the endian issues with the SSRCs.\n\n1.3.8\n\n  This is an interim release.  Several little-endian bugs were identified\n  and fixed; this means that we can use intel/linux for development again.\n\n  Cleaned up sha1 and hmac code significantly, got rid of some excess\n  functions and properly documented the fuctions in the .h files.\n\n  Eliminated some vestigial files.\n\n  There is a SIGBUS error in the AES encrypt function on sparc\n  (observed on both solaris and openbsd) with gcc 2.95.  Was unable to\n  find bad pointer anywhere, so I'm wondering if it isn't a compiler\n  problem (there's a known problem whose profile it fits).  It doesn't\n  appear on any other platform, even in the cipher_driver stress\n  tests.\n\n  Planned changes\n\n  Change interface to nonces (xtd_seq_num_t) so that it uses\n  network byte ordering, and is consistent with other arguments.\n\n\n1.3.6 \n\n  Changed /dev/random (in configure.in and crypto/rng/rand_source.c) to\n  /dev/urandom; the latter is non-blocking on all known platforms (which \n  corrects some programs that seem to hang) and is actually present on \n  Open BSD (unlike /dev/random, which only works in the presence of \n  hardware supported random number generation).\n\n  Added machine/types.h case in include/integers.h.\n\n1.3.5\n\n  Removing srtp_t::template and stream_clone().\n\n  Adding a new policy structure, which will reflect a complete SRTP\n  policy (including SRTCP).\n\n  This version is *incomplete* and will undergo more changes.  It is\n  provided only as a basis for discussion.\n\n1.3.4\n\n   Removed tmmh.c and tmmh.h, which implemented version one of TMMH.\n\n   Changed srtp_get_trailer_length() to act on streams rather than\n   sessions, and documented the macro SRTP_MAX_TRAILER_LEN, which should\n   usually be used rather than that function.\n\n   Removed 'salt' from cipher input. \n\n   Changed rdbx to use err.h error codes.\n\n   Changed malloc() and free() to xalloc() and xfree; these functions\n   are defined in crypto/kernel/alloc.c and declared in \n   include/alloc.h.\n\n   Added 'output' functions to cipher, in addition to 'encrypt'\n   functions.  It is no longer necessary to zeroize a buffer before\n   encrypting in order to get keystream.\n\n   Changed octet_string_hex_string() so that \"times two\" isn't needed\n   in its input.\n\n   Added crypto_kernel_init() prior to command-line parsing, so that\n   kernel can be passed command-line arguments, such as \"-d\n   debug_module\".  This was done to for the applications\n   test/srtp-driver, test/kernel-driver, and test/ust-driver.\n\n   Improved srtp_init_aes_128_prf - wrote key derivation function\n   (srtp_kdf_t).\n\n   Add the tag_len as an argument to the auth_compute() function, but\n   not the corresponding macro.  This change allows the tag length for\n   a given auth func to be set to different values at initialization\n   time.  Previously, the structure auth_t contained the\n   output_length, but that value was inaccessible from hmac_compute()\n   and other functions.\n\n   Re-named files from a-b.c to a_b.c. in order to help portability.\n\n   Re-named rijndael to aes (or aes_128 as appropriate).\n\n\n1.2.1 \n\n  Changes so that 1.2.0 compiles on cygwin-win2k.\n\n  Added better error reporting system.  If syslog is present on the\n  OS, then it is used.\n\n\n1.2.0 Many improvements and additions, and a fex fixes\n\n   Fixed endian issues in RTP header construction in the function\n   rtp_sendto() in srtp/rtp.c.\n\n   Implemented RIJNDAEL decryption operation, adding the functions\n   rijndael_decrypt() and rijndael_expand_decryption_key().  Also\n   re-named rijndael_expand_key() to rijndael_expand_encryption_key()\n   for consistency.\n\n   Implemented random number source using /dev/random, in the files\n   crypto/rng/rand_source.c and include/rand_source.h.\n\n   Added index check to SEAL cipher (only values less than 2^32 are\n   allowed)\n\n   Added test case for null_auth authentication function.\n\n   Added a timing test which tests the effect of CPU cache thrash on\n   cipher throughput.  The test is done by the function\n   cipher_test_throughput_array(); the function\n   cipher_array_alloc_init() creates an array of ciphers for use in\n   this test.  This test can be accessed by using the -a flag to\n   the application cipher-driver in the test subdirectory.\n \n   Added argument processing to ust-driver.c, and added that app to\n   the 'runtest' target in Makefile.in.\n\n   A minor auth_t API change: last argument of auth_init() eliminated.\n\n\n1.0.6 A small but important fix\n\n   Fixed srtp_init_aes_128_prf() by adding octet_string_set_to_zero()\n   after buffer allocation.\n\n   Eliminated references to no-longer-existing variables in debugging\n   code in srtp/srtp.c.  This fixes the compilation failure that\n   occured when using PRINT_DEBUG in that file.\n\n   Corrected spelling of Richard Priestley's name in credits.  Sorry\n   Richard!\n\n\n1.0.5 Many little fixes\n\n   Fixed octet_string_set_to_zero(), which was writing one\n   more zero octet than it should.  This bug caused srtp_protect()\n   and srtp_unprotect() to overwrite the byte that followed the\n   srtp packet.\n\n   Changed sizeof(uint32_t) to srtp_get_trailer_length() in\n   srtp-driver.c.  This is just defensive coding.\n\n   Added NULL check to malloc in srtp_alloc().\n\n\n1.0.4 Many minor fixes and two big ones (thanks for the bug reports!)\n\n   Removed 'ssrc' from the srtp_init_aes_128_prf() function argument\n   list.  This is so that applications which do not a priori know the\n   ssrc which they will be receiving can still use libsrtp.  Now the\n   SSRC value is gleaned from the rtp header and exored into the\n   counter mode offset in the srtp_protect() and srtp_unprotect()\n   functions, if that cipher is used.  This change cascaed through\n   many other functions, including srtp_init_from_hex(),\n   srtp_sender_init() and srtp_receiver_init() in rtp.c, and also\n   changing the CLI to test/rtpw.  In the future, another function\n   call will be added to the library that enables multiple ssrc/key\n   pairs to be installed into the same srtp session, so that libsrtp\n   works with multiple srtp senders.  For now, this functionality is\n   lacking.\n\n   Removed the GDOI interface to the rtpw demo program.  This will be\n   added again at a later date, after the SRTP and GDOI distributions\n   stabilize.  For now, I've left in the GDOI #defines and autoconf\n   definitions so that they'll be in place when needed.\n\n   Updated tmmhv2_compute() so that it didn't assume any particular\n   alginment of the output tag.\n\n   Changed bit field variables in srtp.h to unsigned char from\n   unsigned int in order to avoid a potential endianness issue.\n\n   Fixed rdbx_estimate_index() to handle all input cases.  This solves\n   the now notorious \"abaft\" bug in the rtpw demo app on linux/intel,\n   in which spurious replay protection failures happen after that word\n   is received.\n\n   Added ntohs(hdr->seq) to srtp_protect and srtp_unprotect, removed\n   from rijndael_icm_set_segment().\n\n   Added error checking and handling to srtp_sender_init() and\n   srtp_receiver_init().\n\n   Changed srtp_alloc() so that it does what you'd expect: allocate an\n   srtp_ctx_t structure.  This hides the library internals.\n\n\n1.0.1   Many minor fixes\n\n   Added cipher_driver_buffer_test(...) to test/cipher-driver.c.  This\n   function checks that the byte-buffering functions used by a cipher\n   are correct.\n\n   Fixed SunOS/Solaris build problems: added HAVE_SYS_INT_TYPES_H and\n   changed index_t to xtd_seq_num_t (see include/rdbx.h).\n\n   Fixed SEAL3.0 output byte buffering, added byte-buffering test to\n   cipher/cipher-driver.c.\n\n   Fixed roc-driver so that the non-sequential insertion test\n   automatically recovers from bad estimates.  This was required to\n   prevent spurious failures.\n\n   Made rdbx_estimate_index(...) function smarter, so that initial RTP\n   sequence numbers greater than 32,768 don't cause it to estimate the\n   rollover counter of 0xffffffff.\n\n\n1.0.0   Initial release\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/LICENSE",
    "content": "/*\n *\t\n * Copyright (c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/Makefile.in",
    "content": "# Makefile for secure rtp \n#\n# David A. McGrew\n# Cisco Systems, Inc.\n\n# targets:\n#\n# runtest       runs test applications \n# test\t\tbuilds test applications\n# libcrypt.a\tstatic library implementing crypto engine\n# libsrtp.a\tstatic library implementing srtp\n# clean\t\tremoves objects, libs, and executables\n# distribution  cleans and builds a .tgz\n# tags          builds etags file from all .c and .h files\n\n.PHONY: all test build_table_apps\n\nall: test \n\nruntest: build_table_apps test\n\t@echo \"running libsrtp test applications...\"\n\tcrypto/test/cipher_driver$(EXE) -v >/dev/null\n\tcrypto/test/kernel_driver$(EXE) -v >/dev/null\n\ttest/rdbx_driver$(EXE) -v >/dev/null\n\ttest/srtp_driver$(EXE) -v >/dev/null\n\ttest/roc_driver$(EXE) -v >/dev/null\n\ttest/replay_driver$(EXE) -v >/dev/null\n\ttest/dtls_srtp_driver$(EXE) >/dev/null\n\tcd test; ./rtpw_test.sh >/dev/null\t\n\t@echo \"libsrtp test applications passed.\"\n\t$(MAKE) -C crypto runtest\n\n# makefile variables\n\nCC\t= @CC@\nINCDIR\t= -Icrypto/include -I$(srcdir)/include -I$(srcdir)/crypto/include\nDEFS\t= @DEFS@\nCPPFLAGS= @CPPFLAGS@\nCFLAGS\t= @CFLAGS@\nLIBS\t= @LIBS@\nLDFLAGS\t= @LDFLAGS@ -L.\nCOMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS)\nSRTPLIB\t= -lsrtp\n\nRANLIB\t= @RANLIB@\nINSTALL\t= @INSTALL@\n\n# EXE defines the suffix on executables - it's .exe for Windows, and\n# null on linux, bsd, and OS X and other OSes.\nEXE\t= @EXE@\n# gdoi is the group domain of interpretation for isakmp, a group key\n# management system which can provide keys for srtp\ngdoi\t= @GDOI_OBJS@\n# Random source.\nRNG_OBJS = @RNG_OBJS@\n\nsrcdir = @srcdir@\ntop_srcdir = @top_srcdir@\ntop_builddir = @top_builddir@\nVPATH = @srcdir@\nprefix = @prefix@\nexec_prefix = @exec_prefix@\nincludedir = @includedir@\nlibdir = @libdir@\n\n\n# implicit rules for object files and test apps\n\n%.o: %.c\n\t$(COMPILE) -c $< -o $@\n\n%$(EXE): %.c\n\t$(COMPILE) $(LDFLAGS) $< -o $@ $(SRTPLIB) $(LIBS)\n\n\n# libcrypt.a (the crypto engine) \nciphers = crypto/cipher/cipher.o crypto/cipher/null_cipher.o      \\\n          crypto/cipher/aes.o crypto/cipher/aes_icm.o             \\\n          crypto/cipher/aes_cbc.o\n\nhashes  = crypto/hash/null_auth.o crypto/hash/sha1.o \\\n          crypto/hash/hmac.o crypto/hash/auth.o # crypto/hash/tmmhv2.o \n\nreplay  = crypto/replay/rdb.o crypto/replay/rdbx.o               \\\n          crypto/replay/ut_sim.o \n\nmath    = crypto/math/datatypes.o crypto/math/stat.o\n\nust     = crypto/ust/ust.o \n\nrng     = crypto/rng/$(RNG_OBJS) crypto/rng/prng.o crypto/rng/ctr_prng.o\n\nerr     = crypto/kernel/err.o\n\nkernel  = crypto/kernel/crypto_kernel.o  crypto/kernel/alloc.o   \\\n          crypto/kernel/key.o $(rng) $(err) # $(ust) \n\ncryptobj =  $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(replay)\n\n# libsrtp.a (implements srtp processing)\n\nsrtpobj = srtp/srtp.o \n\nlibsrtp.a: $(srtpobj) $(cryptobj) $(gdoi)\n\tar cr libsrtp.a $^\n\t$(RANLIB) libsrtp.a\n\n# libcryptomath.a contains general-purpose routines that are used to\n# generate tables and verify cryptoalgorithm implementations - this\n# library is not meant to be included in production code\n\ncryptomath = crypto/math/math.o crypto/math/gf2_8.o \n\nlibcryptomath.a: $(cryptomath)\n\tar cr libcryptomath.a $(cryptomath)\n\t$(RANLIB) libcryptomath.a\n\n\n# test applications \n\ncrypto_testapp = crypto/test/aes_calc$(EXE) crypto/test/cipher_driver$(EXE) \\\n\tcrypto/test/datatypes_driver$(EXE) crypto/test/kernel_driver$(EXE) \\\n\tcrypto/test/rand_gen$(EXE) crypto/test/sha1_driver$(EXE) \\\n\tcrypto/test/stat_driver$(EXE)\n\ntestapp = $(crypto_testapp) test/srtp_driver$(EXE) test/replay_driver$(EXE) \\\n\t  test/roc_driver$(EXE) test/rdbx_driver$(EXE) test/rtpw$(EXE) \\\n\t  test/dtls_srtp_driver$(EXE)\n\n$(testapp): libsrtp.a\n\ntest/rtpw$(EXE): test/rtpw.c test/rtp.c test/getopt_s.c\n\t$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)\n\ntest/srtp_driver$(EXE): test/srtp_driver.c test/getopt_s.c\n\t$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)\n\ntest/rdbx_driver$(EXE): test/rdbx_driver.c test/getopt_s.c\n\t$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)\n\ntest/dtls_srtp_driver$(EXE): test/dtls_srtp_driver.c test/getopt_s.c\n\t$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)\n\ntest: $(testapp)\n\t@echo \"Build done. Please run '$(MAKE) runtest' to run self tests.\"\n\nmemtest: test/srtp_driver\n\t@test/srtp_driver -v -d \"alloc\" > tmp\n\t@grep freed tmp | wc -l > freed\n\t@grep allocated tmp | wc -l > allocated\n\t@echo \"checking for memory leaks (only works with --enable-stdout)\"\n\tcmp -s allocated freed\n\t@echo \"passed (same number of alloc() and dealloc() calls found)\"\n\t@rm freed allocated tmp\n\n# tables_apps are used to generate the tables used in the crypto\n# implementations; these need only be generated during porting, not\n# for building libsrtp or the test applications\n\ntable_apps = tables/aes_tables \n\nbuild_table_apps: $(table_apps)\n\n# in the tables/ subdirectory, we use libcryptomath instead of libsrtp\n\ntables/%: tables/%.c libcryptomath.a \n\t$(COMPILE) $(LDFLAGS) $< -o $@ $(LIBS) libcryptomath.a\n\n# the target 'plot' runs the timing test (test/srtp_driver -t) then\n# uses gnuplot to produce plots of the results - see the script file\n# 'timing'\n\nplot:\ttest/srtp_driver\n\ttest/srtp_driver -t > timing.dat\n\n\n# bookkeeping: tags, clean, and distribution\n\ntags:\n\tetags */*.[ch] */*/*.[ch] \n\n\n# documentation - the target libsrtpdoc builds a PDF file documenting\n# libsrtp\n\nlibsrtpdoc:\n\t$(MAKE) -C doc\n\n.PHONY: clean superclean install\n\ninstall:\n\t@if [ -d $(DESTDIR)$(includedir)/srtp ]; then \\\n\t   echo \"you should run 'make uninstall' first\"; exit 1;  \\\n\tfi\n\t$(INSTALL) -d $(DESTDIR)$(includedir)/srtp\n\t$(INSTALL) -d $(DESTDIR)$(libdir)\n\tcp include/*.h $(DESTDIR)$(includedir)/srtp  \n\tcp crypto/include/*.h $(DESTDIR)$(includedir)/srtp\n\tif [ -f libsrtp.a ]; then cp libsrtp.a $(DESTDIR)$(libdir)/; fi\n\nuninstall:\n\trm -rf $(DESTDIR)$(includedir)/srtp\n\trm -rf $(DESTDIR)$(libdir)/libsrtp.a\n\nclean:\n\trm -rf $(cryptobj) $(srtpobj) $(cryptomath) TAGS \\\n        libcryptomath.a libsrtp.a core *.core test/core\n\tfor a in * */* */*/*; do\t\t\t\\\n              if [ -f \"$$a~\" ] ; then rm -f $$a~; fi;\t\\\n        done;\n\tfor a in $(testapp) $(table_apps); do rm -rf $$a$(EXE); done\n\trm -rf *.pict *.jpg *.dat \n\trm -rf freed allocated tmp\n\t$(MAKE) -C doc clean\n\t$(MAKE) -C crypto clean\n\n\nsuperclean: clean\n\trm -rf crypto/include/config.h config.log config.cache config.status \\\n               Makefile .gdb_history test/.gdb_history .DS_Store\n\trm -rf autom4te.cache\n\ndistname = srtp-$(shell cat VERSION)\n\ndistribution: runtest superclean \n\tif ! [ -f VERSION ]; then exit 1; fi\n\tif [ -f ../$(distname).tgz ]; then               \\\n           mv ../$(distname).tgz ../$(distname).tgz.bak; \\\n        fi\n\tcd ..; tar cvzf $(distname).tgz srtp\n\n# EOF\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/README",
    "content": "Secure RTP (SRTP) Reference Implementation\nDavid A. McGrew\nCisco Systems, Inc.\nmcgrew@cisco.com\n\n\nThis package provides an implementation of the Secure Real-time\nTransport Protocol (SRTP), the Universal Security Transform (UST), and\na supporting cryptographic kernel.  These mechanisms are documented in\nthe Internet Drafts in the doc/ subdirectory.  The SRTP API is\ndocumented in include/srtp.h, and the library is in libsrtp.a (after\ncompilation).  An overview and reference manual is available in\ndoc/libsrtp.pdf.  The PDF documentation is more up to date than this\nfile.\n\n\nInstallation:\n\n./configure [ options ]       # GNU autoconf script \nmake                          # or gmake if needed; use GNU make\n\nThe configure script accepts the following options:\n\n   --help              provides a usage summary\n   --disable-debug     compile without the runtime debugging system\n   --enable-syslog     use syslog for error reporting\n   --disable-stdout    use stdout for error reporting\n   --enable-console    use /dev/console for error reporting\n   --gdoi              use GDOI key management (disabled at present)\n\nBy default, debbuging is enabled and stdout is used for debugging.\nYou can use the above configure options to have the debugging output\nsent to syslog or the system console.  Alternatively, you can define\nERR_REPORTING_FILE in include/conf.h to be any other file that can be\nopened by libSRTP, and debug messages will be sent to it.  \n\nThis package has been tested on Mac OS X (powerpc-apple-darwin1.4),\nCygwin (i686-pc-cygwin), and Sparc (sparc-sun-solaris2.6).  Previous\nversions have been tested on Linux and OpenBSD on both x86 and sparc\nplatforms.\n\nA quick tour of this package:\n\nMakefile\t\ttargets: all, clean, ...\nREADME\t\t\tthis file\nCHANGES                 change log \nVERSION\t\t\tversion number of this package\nLICENSE                 legal details (it's a BSD-like license)\ncrypto/ciphers/\t\tciphers (null, aes_icm, ...)\ncrypto/math/\t\tcrypto math routines\ncrypto/hash/            crypto hashing (hmac, tmmhv2, ...)\ncrypto/replay/\t\treplay protection\ndoc/\t\t\tdocumentation: rfcs, apis, and suchlike\ninclude/\t\tinclude files for all code in distribution\nsrtp/\t\t\tsecure real-time transport protocol implementation\ntables/                 apps for generating tables (useful in porting)\ntest/\t\t\ttest drivers \n\n\nApplications\n\n  Several test drivers and a simple and portable srtp application\n  are included in the test/ subdirectory.\n\n  test driver\tfunction tested\t\n  -------------------------------------------------------------\n  kernel_driver crypto kernel (ciphers, auth funcs, rng)\n  srtp_driver\tsrtp in-memory tests (does not use the network)\n  rdbx_driver\trdbx (extended replay database)\n  roc_driver\textended sequence number functions \n  replay_driver\treplay database (n.b. not used in libsrtp)\n  cipher_driver\tciphers \n  auth_driver\thash functions \n\n  The app rtpw is a simple rtp application which reads words from\n  /usr/dict/words and then sends them out one at a time using [s]rtp.\n  Manual srtp keying uses the -k option; automated key management\n  using gdoi will be added later.\n\nusage: rtpw [-d <debug>]* [-k <key> [-a][-e]] [-s | -r] dest_ip dest_port\nor     rtpw -l\n\n  Either the -s (sender) or -r (receiver) option must be chosen.\n\n  The values dest_ip, dest_port are the ip address and udp port to\n  which the dictionary will be sent, respectively.  \n\n  options:\n\n  -s\t\t(s)rtp sender - causes app to send words\n\n  -r\t\t(s)rtp receive - causes app to receve words\n\n  -k <key>      use srtp master key <key>, where the\n\t\tkey is a hexadecimal value (without the\n                leading \"0x\")\n\n  -e            encrypt/decrypt (for data confidentiality)\n                (requires use of -k option as well)\n\n  -a            message authentication \n                (requires use of -k option as well)\n\n  -l            list debug modules\n\n  -d <debug>    turn on debugging for module <debug>\n\n\nIn order to get random 30-byte values for use as key/salt pairs , you\ncan use the following bash function to format the output of\n/dev/random (where that device is available).\n\nfunction randhex() {\n   cat /dev/random | od --read-bytes=32 --width=32 -x | awk '{ print $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 }'\n}\n\n\nAn example of an SRTP session using two rtpw programs follows:\n\nset k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451\n\n[sh1]$ test/rtpw -s -k $k -ea 0.0.0.0 9999 \nSecurity services: confidentiality message authentication\nset master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451\nsetting SSRC to 2078917053\nsending word: A\nsending word: a\nsending word: aa\nsending word: aal\n...\n\n[sh2]$ test/rtpw -r -k $k -ea 0.0.0.0 9999 \nsecurity services: confidentiality message authentication\nset master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451\n19 octets received from SSRC 2078917053 word: A\n19 octets received from SSRC 2078917053 word: a\n20 octets received from SSRC 2078917053 word: aa\n21 octets received from SSRC 2078917053 word: aal\n...\n\nImplementation Notes\n\n  * The srtp_protect() function assumes that the buffer holding the\n    rtp packet has enough storage allocated that the authentication \n    tag can be written to the end of that packet.  If this assumption\n    is not valid, memory corruption will ensue.  \n\n  * Automated tests for the crypto functions are provided through\n    the cipher_type_self_test() and auth_type_self_test() functions.\n    These functions should be used to test each port of this code \n    to a new platform.\n\n  * Replay protection is contained in the crypto engine, and\n    tests for it are provided.\n\n  * This implementation provides calls to initialize, protect, and\n    unprotect RTP packets, and makes as few as possible assumptions\n    about how these functions will be called.  For example, the\n    caller is not expected to provide packets in order (though if\n    they're called more than 65k out of sequence, synchronization\n    will be lost).\n    \n  * The sequence number in the rtp packet is used as the low 16 bits\n    of the sender's local packet index. Note that RTP will start its\n    sequence number in a random place, and the SRTP layer just jumps\n    forward to that number at its first invocation.  An earlier\n    version of this library used initial sequence numbers that are\n    less than 32,768; this trick is no longer required as the\n    rdbx_estimate_index(...) function has been made smarter.\n\n  * The replay window is 128 bits in length, and is hard-coded to this\n    value for now.  \n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/TODO",
    "content": "TODO List\n\n1.4.1\n\n  - document which fields are in NBO/HBO, and check for consistency.\n\n  - move HAVE_U_LONG_LONG inside of datatypes.c, or some other\n    separate file\n\n  - re-write configure.in to make cross-compilation easier\n\n  - eliminate GENERIC_AESICM by generalizing the code a bit\n\nOlder comments\n\n  - add tests for key_limit_t datatype \n\n  - move octet_get_weight() from datatypes.c to math.c (any other\n    funcs?)\n\nChanges and additions planned\n\n  Make cipher and auth dealloc() functions zeroize the key-storage\n  areas before calling free().\n\n  Eliminate key_len from auth_init()\n\n  Doucument internal APIs (cipher, auth, srtp_protect, ...)\n\n\nSRTP options not (yet) included in this libaray:\n\n - the aes-f8-mode cipher\n - the Master Key Index\n - re-keying using the key derivation function (only the initial\n   use of the PRF has been implemented, as it's sufficient\n   for most uses)\n\n\n(OLD) PLANNED CHANGES\n\n   strip out test/lfsr.c\n\n   Write new documentation!!!\n\n   Fix the x86 assembly code in aes.c.\n\n   Eliminate /* DAM */ - there's one in srtp.c\n\n   Change debugging so that it can print more than one line.  Or perhaps\n   just change it so that a single check of the debug-enabled flag is\n   needed.\n\n   Improve interface between cipher and rdbx - perhaps generalize rdbx\n   into 'nonce' datatype.\n\n   Make rijndael_icm accept variable sized keys.\n\n   Add rdbx functions that allow different-sized explicit sequence\n   numbers to be used.\n\n   Write uniform byte-buffering code for PRFs, preferably as macros.\n\n   Consider eliminating low-level alloc functions in favor of len()\n   functions, so that there need not be multiple allocations within a\n   particular alloc() function.\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/VERSION",
    "content": "1.4.4\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/config.h_win32vc7",
    "content": "/* Hacked config.h for Windows XP 32-bit & VC7  */\n\n/* Define if building for a CISC machine (e.g. Intel). */\n#define CPU_CISC 1\n\n/* Define if building for a RISC machine (assume slow byte access). */\n#undef CPU_RISC\n\n/* Path to random device */\n#undef DEV_URANDOM\n\n/* Define to compile in dynamic debugging system. */\n#undef ENABLE_DEBUGGING\n\n/* Report errors to this file. */\n#undef ERR_REPORTING_FILE\n\n/* Define to use logging to stdout. */\n#undef ERR_REPORTING_STDOUT\n\n/* Define this to use ISMAcryp code. */\n#undef GENERIC_AESICM\n\n/* Define to 1 if you have the <arpa/inet.h> header file. */\n#undef HAVE_ARPA_INET_H\n\n/* Define to 1 if you have the <byteswap.h> header file. */\n#undef HAVE_BYTESWAP_H\n\n/* Define to 1 if you have the `inet_aton' function. */\n#define HAVE_INET_ATON 1\n\n/* Define to 1 if the system has the type `int16_t'. */\n#undef HAVE_INT16_T\n\n/* Define to 1 if the system has the type `int32_t'. */\n#undef HAVE_INT32_T\n\n/* Define to 1 if the system has the type `int8_t'. */\n#undef HAVE_INT8_T\n\n/* Define to 1 if you have the <inttypes.h> header file. */\n#undef HAVE_INTTYPES_H\n\n/* Define to 1 if you have the `socket' library (-lsocket). */\n#undef HAVE_LIBSOCKET\n\n/* Define to 1 if you have the <machine/types.h> header file. */\n#undef HAVE_MACHINE_TYPES_H\n\n/* Define to 1 if you have the <memory.h> header file. */\n#define HAVE_MEMORY_H 1\n\n/* Define to 1 if you have the <netinet/in.h> header file. */\n#undef HAVE_NETINET_IN_H\n\n/* Define to 1 if you have the `socket' function. */\n#define HAVE_SOCKET 1\n\n/* Define to 1 if you have the <stdint.h> header file. */\n#undef HAVE_STDINT_H\n\n/* Define to 1 if you have the <stdlib.h> header file. */\n#define HAVE_STDLIB_H 1\n\n/* Define to 1 if you have the <strings.h> header file. */\n#define HAVE_STRINGS_H 1\n\n/* Define to 1 if you have the <string.h> header file. */\n#define HAVE_STRING_H 1\n\n/* Define to 1 if you have the <syslog.h> header file. */\n#undef HAVE_SYSLOG_H\n\n/* Define to 1 if you have the <sys/int_types.h> header file. */\n#undef HAVE_SYS_INT_TYPES_H\n\n/* Define to 1 if you have the <sys/socket.h> header file. */\n#undef HAVE_SYS_SOCKET_H\n\n/* Define to 1 if you have the <sys/stat.h> header file. */\n#undef HAVE_SYS_STAT_H\n\n/* Define to 1 if you have the <sys/types.h> header file. */\n#undef HAVE_SYS_TYPES_H\n\n/* Define to 1 if you have the <sys/uio.h> header file. */\n#undef HAVE_SYS_UIO_H\n\n/* Define to 1 if the system has the type `uint16_t'. */\n#undef HAVE_UINT16_T\n\n/* Define to 1 if the system has the type `uint32_t'. */\n#undef HAVE_UINT32_T \n\n/* Define to 1 if the system has the type `uint64_t'. */\n#undef HAVE_UINT64_T\n\n/* Define to 1 if the system has the type `uint8_t'. */\n#undef HAVE_UINT8_T\n\n/* Define to 1 if you have the <unistd.h> header file. */\n#define HAVE_UNISTD_H 1\n\n/* Define to 1 if you have the `usleep' function. */\n#define HAVE_USLEEP 1\n\n/* Define to 1 if you have the <windows.h> header file. */\n#define HAVE_WINDOWS_H 1\n\n/* Define to 1 if you have the <winsock2.h> header file. */\n#define HAVE_WINSOCK2_H 1\n\n/* Define to use X86 inlined assembly code */\n#undef HAVE_X86\n\n/* Define to the address where bug reports for this package should be sent. */\n#undef PACKAGE_BUGREPORT\n\n/* Define to the full name of this package. */\n#undef PACKAGE_NAME\n\n/* Define to the full name and version of this package. */\n#undef PACKAGE_STRING\n\n/* Define to the one symbol short name of this package. */\n#undef PACKAGE_TARNAME\n\n/* Define to the version of this package. */\n#undef PACKAGE_VERSION\n\n/* The size of a `unsigned long', as computed by sizeof. */\n#define SIZEOF_UNSIGNED_LONG 4\n\n/* The size of a `unsigned long long', as computed by sizeof. */\n#define SIZEOF_UNSIGNED_LONG_LONG 8\n\n/* Define to use GDOI. */\n#undef SRTP_GDOI\n\n/* Define to compile for kernel contexts. */\n#undef SRTP_KERNEL\n\n/* Define to compile for Linux kernel context. */\n#undef SRTP_KERNEL_LINUX\n\n/* Define to 1 if you have the ANSI C header files. */\n#undef STDC_HEADERS\n\n/* Write errors to this file */\n#undef USE_ERR_REPORTING_FILE\n\n/* Define to use syslog logging. */\n#undef USE_SYSLOG\n\n/* Define to 1 if your processor stores words with the most significant byte\n   first (like Motorola and SPARC, unlike Intel and VAX). */\n#undef WORDS_BIGENDIAN\n\n/* Define to empty if `const' does not conform to ANSI C. */\n//#undef const\n/* Define to `__inline__' or `__inline' if that's what the C compiler\n   calls it, or to nothing if 'inline' is not supported under any name.  */\n//#ifndef __cplusplus\n//#undef inline\n//#endif\n#define inline __inline\n\n/* Define to `unsigned' if <sys/types.h> does not define. */\n//#undef size_t\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/config.hw",
    "content": "/* crypto/include/config.h.  Generated by configure.  */\n/* config_in.h.  Generated from configure.in by autoheader.  */\n\n/* Define if building for a CISC machine (e.g. Intel). */\n#define CPU_CISC 1\n\n/* Define if building for a RISC machine (assume slow byte access). */\n/* #undef CPU_RISC */\n\n/* Path to random device */\n/* #define DEV_URANDOM \"/dev/urandom\" */\n\n/* Define to compile in dynamic debugging system. */\n#define ENABLE_DEBUGGING 1\n\n/* Report errors to this file. */\n/* #undef ERR_REPORTING_FILE */\n\n/* Define to use logging to stdout. */\n#define ERR_REPORTING_STDOUT 1\n\n/* Define this to use ISMAcryp code. */\n/* #undef GENERIC_AESICM */\n\n/* Define to 1 if you have the <arpa/inet.h> header file. */\n/* #undef HAVE_ARPA_INET_H */\n\n/* Define to 1 if you have the <byteswap.h> header file. */\n/* #undef HAVE_BYTESWAP_H */\n\n/* Define to 1 if you have the `inet_aton' function. */\n/* #undef HAVE_INET_ATON */\n\n/* Define to 1 if the system has the type `int16_t'. */\n#define HAVE_INT16_T 1\n\n/* Define to 1 if the system has the type `int32_t'. */\n#define HAVE_INT32_T 1\n\n/* Define to 1 if the system has the type `int8_t'. */\n#define HAVE_INT8_T 1\n\n/* Define to 1 if you have the <inttypes.h> header file. */\n/* #undef HAVE_INTTYPES_H */\n\n/* Define to 1 if you have the `socket' library (-lsocket). */\n/* #undef HAVE_LIBSOCKET */\n\n/* Define to 1 if you have the <machine/types.h> header file. */\n/* #undef HAVE_MACHINE_TYPES_H */\n\n/* Define to 1 if you have the <memory.h> header file. */\n#define HAVE_MEMORY_H 1\n\n/* Define to 1 if you have the <netinet/in.h> header file. */\n/* #undef HAVE_NETINET_IN_H */\n\n/* Define to 1 if you have the `socket' function. */\n/* #undef HAVE_SOCKET */\n\n/* Define to 1 if you have the <stdint.h> header file. */\n/* #undef HAVE_STDINT_H */\n\n/* Define to 1 if you have the <stdlib.h> header file. */\n#define HAVE_STDLIB_H 1\n\n/* Define to 1 if you have the <strings.h> header file. */\n#define HAVE_STRINGS_H 1\n\n/* Define to 1 if you have the <string.h> header file. */\n#define HAVE_STRING_H 1\n\n/* Define to 1 if you have the <syslog.h> header file. */\n/* #undef HAVE_SYSLOG_H */\n\n/* Define to 1 if you have the <sys/int_types.h> header file. */\n/* #undef HAVE_SYS_INT_TYPES_H */\n\n/* Define to 1 if you have the <sys/socket.h> header file. */\n/* #undef HAVE_SYS_SOCKET_H */\n\n/* Define to 1 if you have the <sys/stat.h> header file. */\n#define HAVE_SYS_STAT_H 1\n\n/* Define to 1 if you have the <sys/types.h> header file. */\n#define HAVE_SYS_TYPES_H 1\n\n/* Define to 1 if you have the <sys/uio.h> header file. */\n/* #undef HAVE_SYS_UIO_H */\n\n/* Define to 1 if the system has the type `uint16_t'. */\n#define HAVE_UINT16_T 1\n\n/* Define to 1 if the system has the type `uint32_t'. */\n#define HAVE_UINT32_T 1\n\n/* Define to 1 if the system has the type `uint64_t'. */\n#define HAVE_UINT64_T 1\n\n/* Define to 1 if the system has the type `uint8_t'. */\n#define HAVE_UINT8_T 1\n\n/* Define to 1 if you have the <unistd.h> header file. */\n/* #undef HAVE_UNISTD_H */\n\n/* Define to 1 if you have the `usleep' function. */\n/* #undef HAVE_USLEEP */\n\n/* Define to 1 if you have the <windows.h> header file. */\n#define HAVE_WINDOWS_H 1\n\n/* Define to 1 if you have the <winsock2.h> header file. */\n#define HAVE_WINSOCK2_H 1\n\n/* Define to use X86 inlined assembly code */\n/* #undef HAVE_X86 */\n\n/* Define to the address where bug reports for this package should be sent. */\n#define PACKAGE_BUGREPORT \"\"\n\n/* Define to the full name of this package. */\n#define PACKAGE_NAME \"\"\n\n/* Define to the full name and version of this package. */\n#define PACKAGE_STRING \"\"\n\n/* Define to the one symbol short name of this package. */\n#define PACKAGE_TARNAME \"\"\n\n/* Define to the version of this package. */\n#define PACKAGE_VERSION \"\"\n\n/* The size of a `unsigned long', as computed by sizeof. */\n#define SIZEOF_UNSIGNED_LONG 4\n\n/* The size of a `unsigned long long', as computed by sizeof. */\n#define SIZEOF_UNSIGNED_LONG_LONG 8\n\n/* Define to use GDOI. */\n/* #undef SRTP_GDOI */\n\n/* Define to compile for kernel contexts. */\n/* #undef SRTP_KERNEL */\n\n/* Define to compile for Linux kernel context. */\n/* #undef SRTP_KERNEL_LINUX */\n\n/* Define to 1 if you have the ANSI C header files. */\n#define STDC_HEADERS 1\n\n/* Write errors to this file */\n/* #undef USE_ERR_REPORTING_FILE */\n\n/* Define to use syslog logging. */\n/* #undef USE_SYSLOG */\n\n/* Define to 1 if your processor stores words with the most significant byte\n   first (like Motorola and SPARC, unlike Intel and VAX). */\n/* #undef WORDS_BIGENDIAN */\n\n/* Define to empty if `const' does not conform to ANSI C. */\n/* #undef const */\n\n/* Define 'inline' to nothing, since the MSVC compiler doesn't support it.  */\n#define inline \n\n/* Define to `unsigned' if <sys/types.h> does not define. */\n/* #undef size_t */\n\n#if (_MSC_VER >= 1400) // VC8+\n#ifndef _CRT_SECURE_NO_DEPRECATE\n#define _CRT_SECURE_NO_DEPRECATE\n#endif\n#ifndef _CRT_NONSTDC_NO_DEPRECATE\n#define _CRT_NONSTDC_NO_DEPRECATE\n#endif\n#endif // VC8+\n\n#ifndef uint32_t\ntypedef unsigned __int8\t\tuint8_t;\ntypedef unsigned __int16\tuint16_t;\ntypedef unsigned __int32\tuint32_t;\ntypedef unsigned __int64    uint64_t;\ntypedef __int8\t\tint8_t;\ntypedef __int16\t\tint16_t;\ntypedef __int32\t\tint32_t;\ntypedef __int64\t\tint64_t;\n#endif\n\n#ifdef _MSC_VER\n#pragma warning(disable:4311)\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/config_in.h",
    "content": "/* config_in.h.  Generated from configure.in by autoheader.  */\n\n/* Define if building for a CISC machine (e.g. Intel). */\n#undef CPU_CISC\n\n/* Define if building for a RISC machine (assume slow byte access). */\n#undef CPU_RISC\n\n/* Path to random device */\n#undef DEV_URANDOM\n\n/* Define to compile in dynamic debugging system. */\n#undef ENABLE_DEBUGGING\n\n/* Report errors to this file. */\n#undef ERR_REPORTING_FILE\n\n/* Define to use logging to stdout. */\n#undef ERR_REPORTING_STDOUT\n\n/* Define this to use ISMAcryp code. */\n#undef GENERIC_AESICM\n\n/* Define to 1 if you have the <arpa/inet.h> header file. */\n#undef HAVE_ARPA_INET_H\n\n/* Define to 1 if you have the <byteswap.h> header file. */\n#undef HAVE_BYTESWAP_H\n\n/* Define to 1 if you have the `inet_aton' function. */\n#undef HAVE_INET_ATON\n\n/* Define to 1 if the system has the type `int16_t'. */\n#undef HAVE_INT16_T\n\n/* Define to 1 if the system has the type `int32_t'. */\n#undef HAVE_INT32_T\n\n/* Define to 1 if the system has the type `int8_t'. */\n#undef HAVE_INT8_T\n\n/* Define to 1 if you have the <inttypes.h> header file. */\n#undef HAVE_INTTYPES_H\n\n/* Define to 1 if you have the `socket' library (-lsocket). */\n#undef HAVE_LIBSOCKET\n\n/* Define to 1 if you have the <machine/types.h> header file. */\n#undef HAVE_MACHINE_TYPES_H\n\n/* Define to 1 if you have the <memory.h> header file. */\n#undef HAVE_MEMORY_H\n\n/* Define to 1 if you have the <netinet/in.h> header file. */\n#undef HAVE_NETINET_IN_H\n\n/* Define to 1 if you have the `socket' function. */\n#undef HAVE_SOCKET\n\n/* Define to 1 if you have the <stdint.h> header file. */\n#undef HAVE_STDINT_H\n\n/* Define to 1 if you have the <stdlib.h> header file. */\n#undef HAVE_STDLIB_H\n\n/* Define to 1 if you have the <strings.h> header file. */\n#undef HAVE_STRINGS_H\n\n/* Define to 1 if you have the <string.h> header file. */\n#undef HAVE_STRING_H\n\n/* Define to 1 if you have the <syslog.h> header file. */\n#undef HAVE_SYSLOG_H\n\n/* Define to 1 if you have the <sys/int_types.h> header file. */\n#undef HAVE_SYS_INT_TYPES_H\n\n/* Define to 1 if you have the <sys/socket.h> header file. */\n#undef HAVE_SYS_SOCKET_H\n\n/* Define to 1 if you have the <sys/stat.h> header file. */\n#undef HAVE_SYS_STAT_H\n\n/* Define to 1 if you have the <sys/types.h> header file. */\n#undef HAVE_SYS_TYPES_H\n\n/* Define to 1 if you have the <sys/uio.h> header file. */\n#undef HAVE_SYS_UIO_H\n\n/* Define to 1 if the system has the type `uint16_t'. */\n#undef HAVE_UINT16_T\n\n/* Define to 1 if the system has the type `uint32_t'. */\n#undef HAVE_UINT32_T\n\n/* Define to 1 if the system has the type `uint64_t'. */\n#undef HAVE_UINT64_T\n\n/* Define to 1 if the system has the type `uint8_t'. */\n#undef HAVE_UINT8_T\n\n/* Define to 1 if you have the <unistd.h> header file. */\n#undef HAVE_UNISTD_H\n\n/* Define to 1 if you have the `usleep' function. */\n#undef HAVE_USLEEP\n\n/* Define to 1 if you have the <windows.h> header file. */\n#undef HAVE_WINDOWS_H\n\n/* Define to 1 if you have the <winsock2.h> header file. */\n#undef HAVE_WINSOCK2_H\n\n/* Define to use X86 inlined assembly code */\n#undef HAVE_X86\n\n/* Define to the address where bug reports for this package should be sent. */\n#undef PACKAGE_BUGREPORT\n\n/* Define to the full name of this package. */\n#undef PACKAGE_NAME\n\n/* Define to the full name and version of this package. */\n#undef PACKAGE_STRING\n\n/* Define to the one symbol short name of this package. */\n#undef PACKAGE_TARNAME\n\n/* Define to the version of this package. */\n#undef PACKAGE_VERSION\n\n/* The size of a `unsigned long', as computed by sizeof. */\n#undef SIZEOF_UNSIGNED_LONG\n\n/* The size of a `unsigned long long', as computed by sizeof. */\n#undef SIZEOF_UNSIGNED_LONG_LONG\n\n/* Define to use GDOI. */\n#undef SRTP_GDOI\n\n/* Define to compile for kernel contexts. */\n#undef SRTP_KERNEL\n\n/* Define to compile for Linux kernel context. */\n#undef SRTP_KERNEL_LINUX\n\n/* Define to 1 if you have the ANSI C header files. */\n#undef STDC_HEADERS\n\n/* Write errors to this file */\n#undef USE_ERR_REPORTING_FILE\n\n/* Define to use syslog logging. */\n#undef USE_SYSLOG\n\n/* Define to 1 if your processor stores words with the most significant byte\n   first (like Motorola and SPARC, unlike Intel and VAX). */\n#undef WORDS_BIGENDIAN\n\n/* Define to empty if `const' does not conform to ANSI C. */\n#undef const\n\n/* Define to `__inline__' or `__inline' if that's what the C compiler\n   calls it, or to nothing if 'inline' is not supported under any name.  */\n#ifndef __cplusplus\n#undef inline\n#endif\n\n/* Define to `unsigned' if <sys/types.h> does not define. */\n#undef size_t\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/configure",
    "content": "#!/bin/sh\n# Guess values for system-dependent variables and create Makefiles.\n# Generated by GNU Autoconf 2.59.\n#\n# Copyright (C) 2003 Free Software Foundation, Inc.\n# This configure script is free software; the Free Software Foundation\n# gives unlimited permission to copy, distribute and modify it.\n## --------------------- ##\n## M4sh Initialization.  ##\n## --------------------- ##\n\n# Be Bourne compatible\nif test -n \"${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then\n  emulate sh\n  NULLCMD=:\n  # Zsh 3.x and 4.x performs word splitting on ${1+\"$@\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '${1+\"$@\"}'='\"$@\"'\nelif test -n \"${BASH_VERSION+set}\" && (set -o posix) >/dev/null 2>&1; then\n  set -o posix\nfi\nDUALCASE=1; export DUALCASE # for MKS sh\n\n# Support unset when possible.\nif ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then\n  as_unset=unset\nelse\n  as_unset=false\nfi\n\n\n# Work around bugs in pre-3.0 UWIN ksh.\n$as_unset ENV MAIL MAILPATH\nPS1='$ '\nPS2='> '\nPS4='+ '\n\n# NLS nuisances.\nfor as_var in \\\n  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \\\n  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \\\n  LC_TELEPHONE LC_TIME\ndo\n  if (set +x; test -z \"`(eval $as_var=C; export $as_var) 2>&1`\"); then\n    eval $as_var=C; export $as_var\n  else\n    $as_unset $as_var\n  fi\ndone\n\n# Required to use basename.\nif expr a : '\\(a\\)' >/dev/null 2>&1; then\n  as_expr=expr\nelse\n  as_expr=false\nfi\n\nif (basename /) >/dev/null 2>&1 && test \"X`basename / 2>&1`\" = \"X/\"; then\n  as_basename=basename\nelse\n  as_basename=false\nfi\n\n\n# Name of the executable.\nas_me=`$as_basename \"$0\" ||\n$as_expr X/\"$0\" : '.*/\\([^/][^/]*\\)/*$' \\| \\\n\t X\"$0\" : 'X\\(//\\)$' \\| \\\n\t X\"$0\" : 'X\\(/\\)$' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X/\"$0\" |\n    sed '/^.*\\/\\([^/][^/]*\\)\\/*$/{ s//\\1/; q; }\n  \t  /^X\\/\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\/\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n\n\n# PATH needs CR, and LINENO needs CR and PATH.\n# Avoid depending upon Character Ranges.\nas_cr_letters='abcdefghijklmnopqrstuvwxyz'\nas_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nas_cr_Letters=$as_cr_letters$as_cr_LETTERS\nas_cr_digits='0123456789'\nas_cr_alnum=$as_cr_Letters$as_cr_digits\n\n# The user is always right.\nif test \"${PATH_SEPARATOR+set}\" != set; then\n  echo \"#! /bin/sh\" >conf$$.sh\n  echo  \"exit 0\"   >>conf$$.sh\n  chmod +x conf$$.sh\n  if (PATH=\"/nonexistent;.\"; conf$$.sh) >/dev/null 2>&1; then\n    PATH_SEPARATOR=';'\n  else\n    PATH_SEPARATOR=:\n  fi\n  rm -f conf$$.sh\nfi\n\n\n  as_lineno_1=$LINENO\n  as_lineno_2=$LINENO\n  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`\n  test \"x$as_lineno_1\" != \"x$as_lineno_2\" &&\n  test \"x$as_lineno_3\"  = \"x$as_lineno_2\"  || {\n  # Find who we are.  Look in the path if we contain no path at all\n  # relative or not.\n  case $0 in\n    *[\\\\/]* ) as_myself=$0 ;;\n    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  test -r \"$as_dir/$0\" && as_myself=$as_dir/$0 && break\ndone\n\n       ;;\n  esac\n  # We did not find ourselves, most probably we were run as `sh COMMAND'\n  # in which case we are not to be found in the path.\n  if test \"x$as_myself\" = x; then\n    as_myself=$0\n  fi\n  if test ! -f \"$as_myself\"; then\n    { echo \"$as_me: error: cannot find myself; rerun with an absolute path\" >&2\n   { (exit 1); exit 1; }; }\n  fi\n  case $CONFIG_SHELL in\n  '')\n    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  for as_base in sh bash ksh sh5; do\n\t case $as_dir in\n\t /*)\n\t   if (\"$as_dir/$as_base\" -c '\n  as_lineno_1=$LINENO\n  as_lineno_2=$LINENO\n  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`\n  test \"x$as_lineno_1\" != \"x$as_lineno_2\" &&\n  test \"x$as_lineno_3\"  = \"x$as_lineno_2\" ') 2>/dev/null; then\n\t     $as_unset BASH_ENV || test \"${BASH_ENV+set}\" != set || { BASH_ENV=; export BASH_ENV; }\n\t     $as_unset ENV || test \"${ENV+set}\" != set || { ENV=; export ENV; }\n\t     CONFIG_SHELL=$as_dir/$as_base\n\t     export CONFIG_SHELL\n\t     exec \"$CONFIG_SHELL\" \"$0\" ${1+\"$@\"}\n\t   fi;;\n\t esac\n       done\ndone\n;;\n  esac\n\n  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO\n  # uniformly replaced by the line number.  The first 'sed' inserts a\n  # line-number line before each line; the second 'sed' does the real\n  # work.  The second script uses 'N' to pair each line-number line\n  # with the numbered line, and appends trailing '-' during\n  # substitution so that $LINENO is not a special case at line end.\n  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the\n  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)\n  sed '=' <$as_myself |\n    sed '\n      N\n      s,$,-,\n      : loop\n      s,^\\(['$as_cr_digits']*\\)\\(.*\\)[$]LINENO\\([^'$as_cr_alnum'_]\\),\\1\\2\\1\\3,\n      t loop\n      s,-$,,\n      s,^['$as_cr_digits']*\\n,,\n    ' >$as_me.lineno &&\n  chmod +x $as_me.lineno ||\n    { echo \"$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell\" >&2\n   { (exit 1); exit 1; }; }\n\n  # Don't try to exec as it changes $[0], causing all sort of problems\n  # (the dirname of $[0] is not the place where we might find the\n  # original and so on.  Autoconf is especially sensible to this).\n  . ./$as_me.lineno\n  # Exit status is that of the last command.\n  exit\n}\n\n\ncase `echo \"testing\\c\"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in\n  *c*,-n*) ECHO_N= ECHO_C='\n' ECHO_T='\t' ;;\n  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;\n  *)       ECHO_N= ECHO_C='\\c' ECHO_T= ;;\nesac\n\nif expr a : '\\(a\\)' >/dev/null 2>&1; then\n  as_expr=expr\nelse\n  as_expr=false\nfi\n\nrm -f conf$$ conf$$.exe conf$$.file\necho >conf$$.file\nif ln -s conf$$.file conf$$ 2>/dev/null; then\n  # We could just check for DJGPP; but this test a) works b) is more generic\n  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).\n  if test -f conf$$.exe; then\n    # Don't use ln at all; we don't have any links\n    as_ln_s='cp -p'\n  else\n    as_ln_s='ln -s'\n  fi\nelif ln conf$$.file conf$$ 2>/dev/null; then\n  as_ln_s=ln\nelse\n  as_ln_s='cp -p'\nfi\nrm -f conf$$ conf$$.exe conf$$.file\n\nif mkdir -p . 2>/dev/null; then\n  as_mkdir_p=:\nelse\n  test -d ./-p && rmdir ./-p\n  as_mkdir_p=false\nfi\n\nas_executable_p=\"test -f\"\n\n# Sed expression to map a string onto a valid CPP name.\nas_tr_cpp=\"eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'\"\n\n# Sed expression to map a string onto a valid variable name.\nas_tr_sh=\"eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'\"\n\n\n# IFS\n# We need space, tab and new line, in precisely that order.\nas_nl='\n'\nIFS=\" \t$as_nl\"\n\n# CDPATH.\n$as_unset CDPATH\n\n\n# Name of the host.\n# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,\n# so uname gets run too.\nac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`\n\nexec 6>&1\n\n#\n# Initializations.\n#\nac_default_prefix=/usr/local\nac_config_libobj_dir=.\ncross_compiling=no\nsubdirs=\nMFLAGS=\nMAKEFLAGS=\nSHELL=${CONFIG_SHELL-/bin/sh}\n\n# Maximum number of lines to put in a shell here document.\n# This variable seems obsolete.  It should probably be removed, and\n# only ac_max_sed_lines should be used.\n: ${ac_max_here_lines=38}\n\n# Identity of this package.\nPACKAGE_NAME=\nPACKAGE_TARNAME=\nPACKAGE_VERSION=\nPACKAGE_STRING=\nPACKAGE_BUGREPORT=\n\nac_unique_file=\"srtp\"\n# Factoring default headers for most tests.\nac_includes_default=\"\\\n#include <stdio.h>\n#if HAVE_SYS_TYPES_H\n# include <sys/types.h>\n#endif\n#if HAVE_SYS_STAT_H\n# include <sys/stat.h>\n#endif\n#if STDC_HEADERS\n# include <stdlib.h>\n# include <stddef.h>\n#else\n# if HAVE_STDLIB_H\n#  include <stdlib.h>\n# endif\n#endif\n#if HAVE_STRING_H\n# if !STDC_HEADERS && HAVE_MEMORY_H\n#  include <memory.h>\n# endif\n# include <string.h>\n#endif\n#if HAVE_STRINGS_H\n# include <strings.h>\n#endif\n#if HAVE_INTTYPES_H\n# include <inttypes.h>\n#else\n# if HAVE_STDINT_H\n#  include <stdint.h>\n# endif\n#endif\n#if HAVE_UNISTD_H\n# include <unistd.h>\n#endif\"\n\nac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS RANLIB ac_ct_RANLIB CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RNG_OBJS CPP EGREP build build_cpu build_vendor build_os host host_cpu host_vendor host_os EXE GDOI_OBJS LIBOBJS LTLIBOBJS'\nac_subst_files=''\n\n# Initialize some variables set by options.\nac_init_help=\nac_init_version=false\n# The variables have the same names as the options, with\n# dashes changed to underlines.\ncache_file=/dev/null\nexec_prefix=NONE\nno_create=\nno_recursion=\nprefix=NONE\nprogram_prefix=NONE\nprogram_suffix=NONE\nprogram_transform_name=s,x,x,\nsilent=\nsite=\nsrcdir=\nverbose=\nx_includes=NONE\nx_libraries=NONE\n\n# Installation directory options.\n# These are left unexpanded so users can \"make install exec_prefix=/foo\"\n# and all the variables that are supposed to be based on exec_prefix\n# by default will actually change.\n# Use braces instead of parens because sh, perl, etc. also accept them.\nbindir='${exec_prefix}/bin'\nsbindir='${exec_prefix}/sbin'\nlibexecdir='${exec_prefix}/libexec'\ndatadir='${prefix}/share'\nsysconfdir='${prefix}/etc'\nsharedstatedir='${prefix}/com'\nlocalstatedir='${prefix}/var'\nlibdir='${exec_prefix}/lib'\nincludedir='${prefix}/include'\noldincludedir='/usr/include'\ninfodir='${prefix}/info'\nmandir='${prefix}/man'\n\nac_prev=\nfor ac_option\ndo\n  # If the previous option needs an argument, assign it.\n  if test -n \"$ac_prev\"; then\n    eval \"$ac_prev=\\$ac_option\"\n    ac_prev=\n    continue\n  fi\n\n  ac_optarg=`expr \"x$ac_option\" : 'x[^=]*=\\(.*\\)'`\n\n  # Accept the important Cygnus configure options, so we can diagnose typos.\n\n  case $ac_option in\n\n  -bindir | --bindir | --bindi | --bind | --bin | --bi)\n    ac_prev=bindir ;;\n  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)\n    bindir=$ac_optarg ;;\n\n  -build | --build | --buil | --bui | --bu)\n    ac_prev=build_alias ;;\n  -build=* | --build=* | --buil=* | --bui=* | --bu=*)\n    build_alias=$ac_optarg ;;\n\n  -cache-file | --cache-file | --cache-fil | --cache-fi \\\n  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)\n    ac_prev=cache_file ;;\n  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \\\n  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)\n    cache_file=$ac_optarg ;;\n\n  --config-cache | -C)\n    cache_file=config.cache ;;\n\n  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)\n    ac_prev=datadir ;;\n  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \\\n  | --da=*)\n    datadir=$ac_optarg ;;\n\n  -disable-* | --disable-*)\n    ac_feature=`expr \"x$ac_option\" : 'x-*disable-\\(.*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_feature\" : \".*[^-_$as_cr_alnum]\" >/dev/null &&\n      { echo \"$as_me: error: invalid feature name: $ac_feature\" >&2\n   { (exit 1); exit 1; }; }\n    ac_feature=`echo $ac_feature | sed 's/-/_/g'`\n    eval \"enable_$ac_feature=no\" ;;\n\n  -enable-* | --enable-*)\n    ac_feature=`expr \"x$ac_option\" : 'x-*enable-\\([^=]*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_feature\" : \".*[^-_$as_cr_alnum]\" >/dev/null &&\n      { echo \"$as_me: error: invalid feature name: $ac_feature\" >&2\n   { (exit 1); exit 1; }; }\n    ac_feature=`echo $ac_feature | sed 's/-/_/g'`\n    case $ac_option in\n      *=*) ac_optarg=`echo \"$ac_optarg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;;\n      *) ac_optarg=yes ;;\n    esac\n    eval \"enable_$ac_feature='$ac_optarg'\" ;;\n\n  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \\\n  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \\\n  | --exec | --exe | --ex)\n    ac_prev=exec_prefix ;;\n  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \\\n  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \\\n  | --exec=* | --exe=* | --ex=*)\n    exec_prefix=$ac_optarg ;;\n\n  -gas | --gas | --ga | --g)\n    # Obsolete; use --with-gas.\n    with_gas=yes ;;\n\n  -help | --help | --hel | --he | -h)\n    ac_init_help=long ;;\n  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)\n    ac_init_help=recursive ;;\n  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)\n    ac_init_help=short ;;\n\n  -host | --host | --hos | --ho)\n    ac_prev=host_alias ;;\n  -host=* | --host=* | --hos=* | --ho=*)\n    host_alias=$ac_optarg ;;\n\n  -includedir | --includedir | --includedi | --included | --include \\\n  | --includ | --inclu | --incl | --inc)\n    ac_prev=includedir ;;\n  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \\\n  | --includ=* | --inclu=* | --incl=* | --inc=*)\n    includedir=$ac_optarg ;;\n\n  -infodir | --infodir | --infodi | --infod | --info | --inf)\n    ac_prev=infodir ;;\n  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)\n    infodir=$ac_optarg ;;\n\n  -libdir | --libdir | --libdi | --libd)\n    ac_prev=libdir ;;\n  -libdir=* | --libdir=* | --libdi=* | --libd=*)\n    libdir=$ac_optarg ;;\n\n  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \\\n  | --libexe | --libex | --libe)\n    ac_prev=libexecdir ;;\n  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \\\n  | --libexe=* | --libex=* | --libe=*)\n    libexecdir=$ac_optarg ;;\n\n  -localstatedir | --localstatedir | --localstatedi | --localstated \\\n  | --localstate | --localstat | --localsta | --localst \\\n  | --locals | --local | --loca | --loc | --lo)\n    ac_prev=localstatedir ;;\n  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \\\n  | --localstate=* | --localstat=* | --localsta=* | --localst=* \\\n  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)\n    localstatedir=$ac_optarg ;;\n\n  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)\n    ac_prev=mandir ;;\n  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)\n    mandir=$ac_optarg ;;\n\n  -nfp | --nfp | --nf)\n    # Obsolete; use --without-fp.\n    with_fp=no ;;\n\n  -no-create | --no-create | --no-creat | --no-crea | --no-cre \\\n  | --no-cr | --no-c | -n)\n    no_create=yes ;;\n\n  -no-recursion | --no-recursion | --no-recursio | --no-recursi \\\n  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)\n    no_recursion=yes ;;\n\n  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \\\n  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \\\n  | --oldin | --oldi | --old | --ol | --o)\n    ac_prev=oldincludedir ;;\n  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \\\n  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \\\n  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)\n    oldincludedir=$ac_optarg ;;\n\n  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)\n    ac_prev=prefix ;;\n  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)\n    prefix=$ac_optarg ;;\n\n  -program-prefix | --program-prefix | --program-prefi | --program-pref \\\n  | --program-pre | --program-pr | --program-p)\n    ac_prev=program_prefix ;;\n  -program-prefix=* | --program-prefix=* | --program-prefi=* \\\n  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)\n    program_prefix=$ac_optarg ;;\n\n  -program-suffix | --program-suffix | --program-suffi | --program-suff \\\n  | --program-suf | --program-su | --program-s)\n    ac_prev=program_suffix ;;\n  -program-suffix=* | --program-suffix=* | --program-suffi=* \\\n  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)\n    program_suffix=$ac_optarg ;;\n\n  -program-transform-name | --program-transform-name \\\n  | --program-transform-nam | --program-transform-na \\\n  | --program-transform-n | --program-transform- \\\n  | --program-transform | --program-transfor \\\n  | --program-transfo | --program-transf \\\n  | --program-trans | --program-tran \\\n  | --progr-tra | --program-tr | --program-t)\n    ac_prev=program_transform_name ;;\n  -program-transform-name=* | --program-transform-name=* \\\n  | --program-transform-nam=* | --program-transform-na=* \\\n  | --program-transform-n=* | --program-transform-=* \\\n  | --program-transform=* | --program-transfor=* \\\n  | --program-transfo=* | --program-transf=* \\\n  | --program-trans=* | --program-tran=* \\\n  | --progr-tra=* | --program-tr=* | --program-t=*)\n    program_transform_name=$ac_optarg ;;\n\n  -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n  | -silent | --silent | --silen | --sile | --sil)\n    silent=yes ;;\n\n  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)\n    ac_prev=sbindir ;;\n  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \\\n  | --sbi=* | --sb=*)\n    sbindir=$ac_optarg ;;\n\n  -sharedstatedir | --sharedstatedir | --sharedstatedi \\\n  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \\\n  | --sharedst | --shareds | --shared | --share | --shar \\\n  | --sha | --sh)\n    ac_prev=sharedstatedir ;;\n  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \\\n  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \\\n  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \\\n  | --sha=* | --sh=*)\n    sharedstatedir=$ac_optarg ;;\n\n  -site | --site | --sit)\n    ac_prev=site ;;\n  -site=* | --site=* | --sit=*)\n    site=$ac_optarg ;;\n\n  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)\n    ac_prev=srcdir ;;\n  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)\n    srcdir=$ac_optarg ;;\n\n  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \\\n  | --syscon | --sysco | --sysc | --sys | --sy)\n    ac_prev=sysconfdir ;;\n  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \\\n  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)\n    sysconfdir=$ac_optarg ;;\n\n  -target | --target | --targe | --targ | --tar | --ta | --t)\n    ac_prev=target_alias ;;\n  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)\n    target_alias=$ac_optarg ;;\n\n  -v | -verbose | --verbose | --verbos | --verbo | --verb)\n    verbose=yes ;;\n\n  -version | --version | --versio | --versi | --vers | -V)\n    ac_init_version=: ;;\n\n  -with-* | --with-*)\n    ac_package=`expr \"x$ac_option\" : 'x-*with-\\([^=]*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_package\" : \".*[^-_$as_cr_alnum]\" >/dev/null &&\n      { echo \"$as_me: error: invalid package name: $ac_package\" >&2\n   { (exit 1); exit 1; }; }\n    ac_package=`echo $ac_package| sed 's/-/_/g'`\n    case $ac_option in\n      *=*) ac_optarg=`echo \"$ac_optarg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;;\n      *) ac_optarg=yes ;;\n    esac\n    eval \"with_$ac_package='$ac_optarg'\" ;;\n\n  -without-* | --without-*)\n    ac_package=`expr \"x$ac_option\" : 'x-*without-\\(.*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_package\" : \".*[^-_$as_cr_alnum]\" >/dev/null &&\n      { echo \"$as_me: error: invalid package name: $ac_package\" >&2\n   { (exit 1); exit 1; }; }\n    ac_package=`echo $ac_package | sed 's/-/_/g'`\n    eval \"with_$ac_package=no\" ;;\n\n  --x)\n    # Obsolete; use --with-x.\n    with_x=yes ;;\n\n  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \\\n  | --x-incl | --x-inc | --x-in | --x-i)\n    ac_prev=x_includes ;;\n  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \\\n  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)\n    x_includes=$ac_optarg ;;\n\n  -x-libraries | --x-libraries | --x-librarie | --x-librari \\\n  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)\n    ac_prev=x_libraries ;;\n  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \\\n  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)\n    x_libraries=$ac_optarg ;;\n\n  -*) { echo \"$as_me: error: unrecognized option: $ac_option\nTry \\`$0 --help' for more information.\" >&2\n   { (exit 1); exit 1; }; }\n    ;;\n\n  *=*)\n    ac_envvar=`expr \"x$ac_option\" : 'x\\([^=]*\\)='`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_envvar\" : \".*[^_$as_cr_alnum]\" >/dev/null &&\n      { echo \"$as_me: error: invalid variable name: $ac_envvar\" >&2\n   { (exit 1); exit 1; }; }\n    ac_optarg=`echo \"$ac_optarg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`\n    eval \"$ac_envvar='$ac_optarg'\"\n    export $ac_envvar ;;\n\n  *)\n    # FIXME: should be removed in autoconf 3.0.\n    echo \"$as_me: WARNING: you should use --build, --host, --target\" >&2\n    expr \"x$ac_option\" : \".*[^-._$as_cr_alnum]\" >/dev/null &&\n      echo \"$as_me: WARNING: invalid host type: $ac_option\" >&2\n    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}\n    ;;\n\n  esac\ndone\n\nif test -n \"$ac_prev\"; then\n  ac_option=--`echo $ac_prev | sed 's/_/-/g'`\n  { echo \"$as_me: error: missing argument to $ac_option\" >&2\n   { (exit 1); exit 1; }; }\nfi\n\n# Be sure to have absolute paths.\nfor ac_var in exec_prefix prefix\ndo\n  eval ac_val=$`echo $ac_var`\n  case $ac_val in\n    [\\\\/$]* | ?:[\\\\/]* | NONE | '' ) ;;\n    *)  { echo \"$as_me: error: expected an absolute directory name for --$ac_var: $ac_val\" >&2\n   { (exit 1); exit 1; }; };;\n  esac\ndone\n\n# Be sure to have absolute paths.\nfor ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \\\n\t      localstatedir libdir includedir oldincludedir infodir mandir\ndo\n  eval ac_val=$`echo $ac_var`\n  case $ac_val in\n    [\\\\/$]* | ?:[\\\\/]* ) ;;\n    *)  { echo \"$as_me: error: expected an absolute directory name for --$ac_var: $ac_val\" >&2\n   { (exit 1); exit 1; }; };;\n  esac\ndone\n\n# There might be people who depend on the old broken behavior: `$host'\n# used to hold the argument of --host etc.\n# FIXME: To remove some day.\nbuild=$build_alias\nhost=$host_alias\ntarget=$target_alias\n\n# FIXME: To remove some day.\nif test \"x$host_alias\" != x; then\n  if test \"x$build_alias\" = x; then\n    cross_compiling=maybe\n    echo \"$as_me: WARNING: If you wanted to set the --build type, don't use --host.\n    If a cross compiler is detected then cross compile mode will be used.\" >&2\n  elif test \"x$build_alias\" != \"x$host_alias\"; then\n    cross_compiling=yes\n  fi\nfi\n\nac_tool_prefix=\ntest -n \"$host_alias\" && ac_tool_prefix=$host_alias-\n\ntest \"$silent\" = yes && exec 6>/dev/null\n\n\n# Find the source files, if location was not specified.\nif test -z \"$srcdir\"; then\n  ac_srcdir_defaulted=yes\n  # Try the directory containing this script, then its parent.\n  ac_confdir=`(dirname \"$0\") 2>/dev/null ||\n$as_expr X\"$0\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$0\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$0\" : 'X\\(//\\)$' \\| \\\n\t X\"$0\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$0\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n  srcdir=$ac_confdir\n  if test ! -r $srcdir/$ac_unique_file; then\n    srcdir=..\n  fi\nelse\n  ac_srcdir_defaulted=no\nfi\nif test ! -r $srcdir/$ac_unique_file; then\n  if test \"$ac_srcdir_defaulted\" = yes; then\n    { echo \"$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or ..\" >&2\n   { (exit 1); exit 1; }; }\n  else\n    { echo \"$as_me: error: cannot find sources ($ac_unique_file) in $srcdir\" >&2\n   { (exit 1); exit 1; }; }\n  fi\nfi\n(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||\n  { echo \"$as_me: error: sources are in $srcdir, but \\`cd $srcdir' does not work\" >&2\n   { (exit 1); exit 1; }; }\nsrcdir=`echo \"$srcdir\" | sed 's%\\([^\\\\/]\\)[\\\\/]*$%\\1%'`\nac_env_build_alias_set=${build_alias+set}\nac_env_build_alias_value=$build_alias\nac_cv_env_build_alias_set=${build_alias+set}\nac_cv_env_build_alias_value=$build_alias\nac_env_host_alias_set=${host_alias+set}\nac_env_host_alias_value=$host_alias\nac_cv_env_host_alias_set=${host_alias+set}\nac_cv_env_host_alias_value=$host_alias\nac_env_target_alias_set=${target_alias+set}\nac_env_target_alias_value=$target_alias\nac_cv_env_target_alias_set=${target_alias+set}\nac_cv_env_target_alias_value=$target_alias\nac_env_CC_set=${CC+set}\nac_env_CC_value=$CC\nac_cv_env_CC_set=${CC+set}\nac_cv_env_CC_value=$CC\nac_env_CFLAGS_set=${CFLAGS+set}\nac_env_CFLAGS_value=$CFLAGS\nac_cv_env_CFLAGS_set=${CFLAGS+set}\nac_cv_env_CFLAGS_value=$CFLAGS\nac_env_LDFLAGS_set=${LDFLAGS+set}\nac_env_LDFLAGS_value=$LDFLAGS\nac_cv_env_LDFLAGS_set=${LDFLAGS+set}\nac_cv_env_LDFLAGS_value=$LDFLAGS\nac_env_CPPFLAGS_set=${CPPFLAGS+set}\nac_env_CPPFLAGS_value=$CPPFLAGS\nac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}\nac_cv_env_CPPFLAGS_value=$CPPFLAGS\nac_env_CPP_set=${CPP+set}\nac_env_CPP_value=$CPP\nac_cv_env_CPP_set=${CPP+set}\nac_cv_env_CPP_value=$CPP\n\n#\n# Report the --help message.\n#\nif test \"$ac_init_help\" = \"long\"; then\n  # Omit some internal or obsolete options to make the list less imposing.\n  # This message is too long to be a string in the A/UX 3.1 sh.\n  cat <<_ACEOF\n\\`configure' configures this package to adapt to many kinds of systems.\n\nUsage: $0 [OPTION]... [VAR=VALUE]...\n\nTo assign environment variables (e.g., CC, CFLAGS...), specify them as\nVAR=VALUE.  See below for descriptions of some of the useful variables.\n\nDefaults for the options are specified in brackets.\n\nConfiguration:\n  -h, --help              display this help and exit\n      --help=short        display options specific to this package\n      --help=recursive    display the short help of all the included packages\n  -V, --version           display version information and exit\n  -q, --quiet, --silent   do not print \\`checking...' messages\n      --cache-file=FILE   cache test results in FILE [disabled]\n  -C, --config-cache      alias for \\`--cache-file=config.cache'\n  -n, --no-create         do not create output files\n      --srcdir=DIR        find the sources in DIR [configure dir or \\`..']\n\n_ACEOF\n\n  cat <<_ACEOF\nInstallation directories:\n  --prefix=PREFIX         install architecture-independent files in PREFIX\n\t\t\t  [$ac_default_prefix]\n  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX\n\t\t\t  [PREFIX]\n\nBy default, \\`make install' will install all the files in\n\\`$ac_default_prefix/bin', \\`$ac_default_prefix/lib' etc.  You can specify\nan installation prefix other than \\`$ac_default_prefix' using \\`--prefix',\nfor instance \\`--prefix=\\$HOME'.\n\nFor better control, use the options below.\n\nFine tuning of the installation directories:\n  --bindir=DIR           user executables [EPREFIX/bin]\n  --sbindir=DIR          system admin executables [EPREFIX/sbin]\n  --libexecdir=DIR       program executables [EPREFIX/libexec]\n  --datadir=DIR          read-only architecture-independent data [PREFIX/share]\n  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]\n  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]\n  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]\n  --libdir=DIR           object code libraries [EPREFIX/lib]\n  --includedir=DIR       C header files [PREFIX/include]\n  --oldincludedir=DIR    C header files for non-gcc [/usr/include]\n  --infodir=DIR          info documentation [PREFIX/info]\n  --mandir=DIR           man documentation [PREFIX/man]\n_ACEOF\n\n  cat <<\\_ACEOF\n\nSystem types:\n  --build=BUILD     configure for building on BUILD [guessed]\n  --host=HOST       cross-compile to build programs to run on HOST [BUILD]\n_ACEOF\nfi\n\nif test -n \"$ac_init_help\"; then\n\n  cat <<\\_ACEOF\n\nOptional Features:\n  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)\n  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]\n  --enable-kernel-linux   build library to run in Linux kernel context\n  --disable-debug         do not compile in dynamic debugging system\n  --enable-generic-aesicm compile in changes for ISMAcryp\n  --enable-syslog         use syslog for error reporting\n  --disable-stdout        don't use stdout for error reporting\n  --enable-console        use /dev/console for error reporting\n  --enable-gdoi           enable GDOI key management\n\nSome influential environment variables:\n  CC          C compiler command\n  CFLAGS      C compiler flags\n  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a\n              nonstandard directory <lib dir>\n  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have\n              headers in a nonstandard directory <include dir>\n  CPP         C preprocessor\n\nUse these variables to override the choices made by `configure' or to help\nit to find libraries and programs with nonstandard names/locations.\n\n_ACEOF\nfi\n\nif test \"$ac_init_help\" = \"recursive\"; then\n  # If there are subdirs, report their specific --help.\n  ac_popdir=`pwd`\n  for ac_dir in : $ac_subdirs_all; do test \"x$ac_dir\" = x: && continue\n    test -d $ac_dir || continue\n    ac_builddir=.\n\nif test \"$ac_dir\" != .; then\n  ac_dir_suffix=/`echo \"$ac_dir\" | sed 's,^\\.[\\\\/],,'`\n  # A \"../\" for each directory in $ac_dir_suffix.\n  ac_top_builddir=`echo \"$ac_dir_suffix\" | sed 's,/[^\\\\/]*,../,g'`\nelse\n  ac_dir_suffix= ac_top_builddir=\nfi\n\ncase $srcdir in\n  .)  # No --srcdir option.  We are building in place.\n    ac_srcdir=.\n    if test -z \"$ac_top_builddir\"; then\n       ac_top_srcdir=.\n    else\n       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`\n    fi ;;\n  [\\\\/]* | ?:[\\\\/]* )  # Absolute path.\n    ac_srcdir=$srcdir$ac_dir_suffix;\n    ac_top_srcdir=$srcdir ;;\n  *) # Relative path.\n    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix\n    ac_top_srcdir=$ac_top_builddir$srcdir ;;\nesac\n\n# Do not use `cd foo && pwd` to compute absolute paths, because\n# the directories may not exist.\ncase `pwd` in\n.) ac_abs_builddir=\"$ac_dir\";;\n*)\n  case \"$ac_dir\" in\n  .) ac_abs_builddir=`pwd`;;\n  [\\\\/]* | ?:[\\\\/]* ) ac_abs_builddir=\"$ac_dir\";;\n  *) ac_abs_builddir=`pwd`/\"$ac_dir\";;\n  esac;;\nesac\ncase $ac_abs_builddir in\n.) ac_abs_top_builddir=${ac_top_builddir}.;;\n*)\n  case ${ac_top_builddir}. in\n  .) ac_abs_top_builddir=$ac_abs_builddir;;\n  [\\\\/]* | ?:[\\\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;\n  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;\n  esac;;\nesac\ncase $ac_abs_builddir in\n.) ac_abs_srcdir=$ac_srcdir;;\n*)\n  case $ac_srcdir in\n  .) ac_abs_srcdir=$ac_abs_builddir;;\n  [\\\\/]* | ?:[\\\\/]* ) ac_abs_srcdir=$ac_srcdir;;\n  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;\n  esac;;\nesac\ncase $ac_abs_builddir in\n.) ac_abs_top_srcdir=$ac_top_srcdir;;\n*)\n  case $ac_top_srcdir in\n  .) ac_abs_top_srcdir=$ac_abs_builddir;;\n  [\\\\/]* | ?:[\\\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;\n  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;\n  esac;;\nesac\n\n    cd $ac_dir\n    # Check for guested configure; otherwise get Cygnus style configure.\n    if test -f $ac_srcdir/configure.gnu; then\n      echo\n      $SHELL $ac_srcdir/configure.gnu  --help=recursive\n    elif test -f $ac_srcdir/configure; then\n      echo\n      $SHELL $ac_srcdir/configure  --help=recursive\n    elif test -f $ac_srcdir/configure.ac ||\n\t   test -f $ac_srcdir/configure.in; then\n      echo\n      $ac_configure --help\n    else\n      echo \"$as_me: WARNING: no configuration information is in $ac_dir\" >&2\n    fi\n    cd $ac_popdir\n  done\nfi\n\ntest -n \"$ac_init_help\" && exit 0\nif $ac_init_version; then\n  cat <<\\_ACEOF\n\nCopyright (C) 2003 Free Software Foundation, Inc.\nThis configure script is free software; the Free Software Foundation\ngives unlimited permission to copy, distribute and modify it.\n_ACEOF\n  exit 0\nfi\nexec 5>config.log\ncat >&5 <<_ACEOF\nThis file contains any messages produced by compilers while\nrunning configure, to aid debugging if configure makes a mistake.\n\nIt was created by $as_me, which was\ngenerated by GNU Autoconf 2.59.  Invocation command line was\n\n  $ $0 $@\n\n_ACEOF\n{\ncat <<_ASUNAME\n## --------- ##\n## Platform. ##\n## --------- ##\n\nhostname = `(hostname || uname -n) 2>/dev/null | sed 1q`\nuname -m = `(uname -m) 2>/dev/null || echo unknown`\nuname -r = `(uname -r) 2>/dev/null || echo unknown`\nuname -s = `(uname -s) 2>/dev/null || echo unknown`\nuname -v = `(uname -v) 2>/dev/null || echo unknown`\n\n/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`\n/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`\n\n/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`\n/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`\n/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`\nhostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`\n/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`\n/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`\n/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`\n\n_ASUNAME\n\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  echo \"PATH: $as_dir\"\ndone\n\n} >&5\n\ncat >&5 <<_ACEOF\n\n\n## ----------- ##\n## Core tests. ##\n## ----------- ##\n\n_ACEOF\n\n\n# Keep a trace of the command line.\n# Strip out --no-create and --no-recursion so they do not pile up.\n# Strip out --silent because we don't want to record it for future runs.\n# Also quote any args containing shell meta-characters.\n# Make two passes to allow for proper duplicate-argument suppression.\nac_configure_args=\nac_configure_args0=\nac_configure_args1=\nac_sep=\nac_must_keep_next=false\nfor ac_pass in 1 2\ndo\n  for ac_arg\n  do\n    case $ac_arg in\n    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;\n    -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n    | -silent | --silent | --silen | --sile | --sil)\n      continue ;;\n    *\" \"*|*\"\t\"*|*[\\[\\]\\~\\#\\$\\^\\&\\*\\(\\)\\{\\}\\\\\\|\\;\\<\\>\\?\\\"\\']*)\n      ac_arg=`echo \"$ac_arg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    esac\n    case $ac_pass in\n    1) ac_configure_args0=\"$ac_configure_args0 '$ac_arg'\" ;;\n    2)\n      ac_configure_args1=\"$ac_configure_args1 '$ac_arg'\"\n      if test $ac_must_keep_next = true; then\n\tac_must_keep_next=false # Got value, back to normal.\n      else\n\tcase $ac_arg in\n\t  *=* | --config-cache | -C | -disable-* | --disable-* \\\n\t  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \\\n\t  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \\\n\t  | -with-* | --with-* | -without-* | --without-* | --x)\n\t    case \"$ac_configure_args0 \" in\n\t      \"$ac_configure_args1\"*\" '$ac_arg' \"* ) continue ;;\n\t    esac\n\t    ;;\n\t  -* ) ac_must_keep_next=true ;;\n\tesac\n      fi\n      ac_configure_args=\"$ac_configure_args$ac_sep'$ac_arg'\"\n      # Get rid of the leading space.\n      ac_sep=\" \"\n      ;;\n    esac\n  done\ndone\n$as_unset ac_configure_args0 || test \"${ac_configure_args0+set}\" != set || { ac_configure_args0=; export ac_configure_args0; }\n$as_unset ac_configure_args1 || test \"${ac_configure_args1+set}\" != set || { ac_configure_args1=; export ac_configure_args1; }\n\n# When interrupted or exit'd, cleanup temporary files, and complete\n# config.log.  We remove comments because anyway the quotes in there\n# would cause problems or look ugly.\n# WARNING: Be sure not to use single quotes in there, as some shells,\n# such as our DU 5.0 friend, will then `close' the trap.\ntrap 'exit_status=$?\n  # Save into config.log some information that might help in debugging.\n  {\n    echo\n\n    cat <<\\_ASBOX\n## ---------------- ##\n## Cache variables. ##\n## ---------------- ##\n_ASBOX\n    echo\n    # The following way of writing the cache mishandles newlines in values,\n{\n  (set) 2>&1 |\n    case `(ac_space='\"'\"' '\"'\"'; set | grep ac_space) 2>&1` in\n    *ac_space=\\ *)\n      sed -n \\\n\t\"s/'\"'\"'/'\"'\"'\\\\\\\\'\"'\"''\"'\"'/g;\n\t  s/^\\\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\\\)=\\\\(.*\\\\)/\\\\1='\"'\"'\\\\2'\"'\"'/p\"\n      ;;\n    *)\n      sed -n \\\n\t\"s/^\\\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\\\)=\\\\(.*\\\\)/\\\\1=\\\\2/p\"\n      ;;\n    esac;\n}\n    echo\n\n    cat <<\\_ASBOX\n## ----------------- ##\n## Output variables. ##\n## ----------------- ##\n_ASBOX\n    echo\n    for ac_var in $ac_subst_vars\n    do\n      eval ac_val=$`echo $ac_var`\n      echo \"$ac_var='\"'\"'$ac_val'\"'\"'\"\n    done | sort\n    echo\n\n    if test -n \"$ac_subst_files\"; then\n      cat <<\\_ASBOX\n## ------------- ##\n## Output files. ##\n## ------------- ##\n_ASBOX\n      echo\n      for ac_var in $ac_subst_files\n      do\n\teval ac_val=$`echo $ac_var`\n\techo \"$ac_var='\"'\"'$ac_val'\"'\"'\"\n      done | sort\n      echo\n    fi\n\n    if test -s confdefs.h; then\n      cat <<\\_ASBOX\n## ----------- ##\n## confdefs.h. ##\n## ----------- ##\n_ASBOX\n      echo\n      sed \"/^$/d\" confdefs.h | sort\n      echo\n    fi\n    test \"$ac_signal\" != 0 &&\n      echo \"$as_me: caught signal $ac_signal\"\n    echo \"$as_me: exit $exit_status\"\n  } >&5\n  rm -f core *.core &&\n  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&\n    exit $exit_status\n     ' 0\nfor ac_signal in 1 2 13 15; do\n  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal\ndone\nac_signal=0\n\n# confdefs.h avoids OS command line length limits that DEFS can exceed.\nrm -rf conftest* confdefs.h\n# AIX cpp loses on an empty file, so make sure it contains at least a newline.\necho >confdefs.h\n\n# Predefined preprocessor variables.\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_NAME \"$PACKAGE_NAME\"\n_ACEOF\n\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"\n_ACEOF\n\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_VERSION \"$PACKAGE_VERSION\"\n_ACEOF\n\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_STRING \"$PACKAGE_STRING\"\n_ACEOF\n\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"\n_ACEOF\n\n\n# Let the site file select an alternate cache file if it wants to.\n# Prefer explicitly selected file to automatically selected ones.\nif test -z \"$CONFIG_SITE\"; then\n  if test \"x$prefix\" != xNONE; then\n    CONFIG_SITE=\"$prefix/share/config.site $prefix/etc/config.site\"\n  else\n    CONFIG_SITE=\"$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site\"\n  fi\nfi\nfor ac_site_file in $CONFIG_SITE; do\n  if test -r \"$ac_site_file\"; then\n    { echo \"$as_me:$LINENO: loading site script $ac_site_file\" >&5\necho \"$as_me: loading site script $ac_site_file\" >&6;}\n    sed 's/^/| /' \"$ac_site_file\" >&5\n    . \"$ac_site_file\"\n  fi\ndone\n\nif test -r \"$cache_file\"; then\n  # Some versions of bash will fail to source /dev/null (special\n  # files actually), so we avoid doing that.\n  if test -f \"$cache_file\"; then\n    { echo \"$as_me:$LINENO: loading cache $cache_file\" >&5\necho \"$as_me: loading cache $cache_file\" >&6;}\n    case $cache_file in\n      [\\\\/]* | ?:[\\\\/]* ) . $cache_file;;\n      *)                      . ./$cache_file;;\n    esac\n  fi\nelse\n  { echo \"$as_me:$LINENO: creating cache $cache_file\" >&5\necho \"$as_me: creating cache $cache_file\" >&6;}\n  >$cache_file\nfi\n\n# Check that the precious variables saved in the cache have kept the same\n# value.\nac_cache_corrupted=false\nfor ac_var in `(set) 2>&1 |\n\t       sed -n 's/^ac_env_\\([a-zA-Z_0-9]*\\)_set=.*/\\1/p'`; do\n  eval ac_old_set=\\$ac_cv_env_${ac_var}_set\n  eval ac_new_set=\\$ac_env_${ac_var}_set\n  eval ac_old_val=\"\\$ac_cv_env_${ac_var}_value\"\n  eval ac_new_val=\"\\$ac_env_${ac_var}_value\"\n  case $ac_old_set,$ac_new_set in\n    set,)\n      { echo \"$as_me:$LINENO: error: \\`$ac_var' was set to \\`$ac_old_val' in the previous run\" >&5\necho \"$as_me: error: \\`$ac_var' was set to \\`$ac_old_val' in the previous run\" >&2;}\n      ac_cache_corrupted=: ;;\n    ,set)\n      { echo \"$as_me:$LINENO: error: \\`$ac_var' was not set in the previous run\" >&5\necho \"$as_me: error: \\`$ac_var' was not set in the previous run\" >&2;}\n      ac_cache_corrupted=: ;;\n    ,);;\n    *)\n      if test \"x$ac_old_val\" != \"x$ac_new_val\"; then\n\t{ echo \"$as_me:$LINENO: error: \\`$ac_var' has changed since the previous run:\" >&5\necho \"$as_me: error: \\`$ac_var' has changed since the previous run:\" >&2;}\n\t{ echo \"$as_me:$LINENO:   former value:  $ac_old_val\" >&5\necho \"$as_me:   former value:  $ac_old_val\" >&2;}\n\t{ echo \"$as_me:$LINENO:   current value: $ac_new_val\" >&5\necho \"$as_me:   current value: $ac_new_val\" >&2;}\n\tac_cache_corrupted=:\n      fi;;\n  esac\n  # Pass precious variables to config.status.\n  if test \"$ac_new_set\" = set; then\n    case $ac_new_val in\n    *\" \"*|*\"\t\"*|*[\\[\\]\\~\\#\\$\\^\\&\\*\\(\\)\\{\\}\\\\\\|\\;\\<\\>\\?\\\"\\']*)\n      ac_arg=$ac_var=`echo \"$ac_new_val\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    *) ac_arg=$ac_var=$ac_new_val ;;\n    esac\n    case \" $ac_configure_args \" in\n      *\" '$ac_arg' \"*) ;; # Avoid dups.  Use of quotes ensures accuracy.\n      *) ac_configure_args=\"$ac_configure_args '$ac_arg'\" ;;\n    esac\n  fi\ndone\nif $ac_cache_corrupted; then\n  { echo \"$as_me:$LINENO: error: changes in the environment can compromise the build\" >&5\necho \"$as_me: error: changes in the environment can compromise the build\" >&2;}\n  { { echo \"$as_me:$LINENO: error: run \\`make distclean' and/or \\`rm $cache_file' and start over\" >&5\necho \"$as_me: error: run \\`make distclean' and/or \\`rm $cache_file' and start over\" >&2;}\n   { (exit 1); exit 1; }; }\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nif test -z \"$CFLAGS\"; then\n      CFLAGS=\"-Wall -O4 -fexpensive-optimizations -funroll-loops\"\nfi\n\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}ranlib\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}ranlib; ac_word=$2\necho \"$as_me:$LINENO: checking for $ac_word\" >&5\necho $ECHO_N \"checking for $ac_word... $ECHO_C\" >&6\nif test \"${ac_cv_prog_RANLIB+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  if test -n \"$RANLIB\"; then\n  ac_cv_prog_RANLIB=\"$RANLIB\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  for ac_exec_ext in '' $ac_executable_extensions; do\n  if $as_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_RANLIB=\"${ac_tool_prefix}ranlib\"\n    echo \"$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\ndone\n\nfi\nfi\nRANLIB=$ac_cv_prog_RANLIB\nif test -n \"$RANLIB\"; then\n  echo \"$as_me:$LINENO: result: $RANLIB\" >&5\necho \"${ECHO_T}$RANLIB\" >&6\nelse\n  echo \"$as_me:$LINENO: result: no\" >&5\necho \"${ECHO_T}no\" >&6\nfi\n\nfi\nif test -z \"$ac_cv_prog_RANLIB\"; then\n  ac_ct_RANLIB=$RANLIB\n  # Extract the first word of \"ranlib\", so it can be a program name with args.\nset dummy ranlib; ac_word=$2\necho \"$as_me:$LINENO: checking for $ac_word\" >&5\necho $ECHO_N \"checking for $ac_word... $ECHO_C\" >&6\nif test \"${ac_cv_prog_ac_ct_RANLIB+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  if test -n \"$ac_ct_RANLIB\"; then\n  ac_cv_prog_ac_ct_RANLIB=\"$ac_ct_RANLIB\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  for ac_exec_ext in '' $ac_executable_extensions; do\n  if $as_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_ac_ct_RANLIB=\"ranlib\"\n    echo \"$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\ndone\n\n  test -z \"$ac_cv_prog_ac_ct_RANLIB\" && ac_cv_prog_ac_ct_RANLIB=\":\"\nfi\nfi\nac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB\nif test -n \"$ac_ct_RANLIB\"; then\n  echo \"$as_me:$LINENO: result: $ac_ct_RANLIB\" >&5\necho \"${ECHO_T}$ac_ct_RANLIB\" >&6\nelse\n  echo \"$as_me:$LINENO: result: no\" >&5\necho \"${ECHO_T}no\" >&6\nfi\n\n  RANLIB=$ac_ct_RANLIB\nelse\n  RANLIB=\"$ac_cv_prog_RANLIB\"\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}gcc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}gcc; ac_word=$2\necho \"$as_me:$LINENO: checking for $ac_word\" >&5\necho $ECHO_N \"checking for $ac_word... $ECHO_C\" >&6\nif test \"${ac_cv_prog_CC+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  for ac_exec_ext in '' $ac_executable_extensions; do\n  if $as_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_CC=\"${ac_tool_prefix}gcc\"\n    echo \"$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\ndone\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  echo \"$as_me:$LINENO: result: $CC\" >&5\necho \"${ECHO_T}$CC\" >&6\nelse\n  echo \"$as_me:$LINENO: result: no\" >&5\necho \"${ECHO_T}no\" >&6\nfi\n\nfi\nif test -z \"$ac_cv_prog_CC\"; then\n  ac_ct_CC=$CC\n  # Extract the first word of \"gcc\", so it can be a program name with args.\nset dummy gcc; ac_word=$2\necho \"$as_me:$LINENO: checking for $ac_word\" >&5\necho $ECHO_N \"checking for $ac_word... $ECHO_C\" >&6\nif test \"${ac_cv_prog_ac_ct_CC+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  if test -n \"$ac_ct_CC\"; then\n  ac_cv_prog_ac_ct_CC=\"$ac_ct_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  for ac_exec_ext in '' $ac_executable_extensions; do\n  if $as_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_ac_ct_CC=\"gcc\"\n    echo \"$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\ndone\n\nfi\nfi\nac_ct_CC=$ac_cv_prog_ac_ct_CC\nif test -n \"$ac_ct_CC\"; then\n  echo \"$as_me:$LINENO: result: $ac_ct_CC\" >&5\necho \"${ECHO_T}$ac_ct_CC\" >&6\nelse\n  echo \"$as_me:$LINENO: result: no\" >&5\necho \"${ECHO_T}no\" >&6\nfi\n\n  CC=$ac_ct_CC\nelse\n  CC=\"$ac_cv_prog_CC\"\nfi\n\nif test -z \"$CC\"; then\n  if test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}cc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}cc; ac_word=$2\necho \"$as_me:$LINENO: checking for $ac_word\" >&5\necho $ECHO_N \"checking for $ac_word... $ECHO_C\" >&6\nif test \"${ac_cv_prog_CC+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  for ac_exec_ext in '' $ac_executable_extensions; do\n  if $as_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_CC=\"${ac_tool_prefix}cc\"\n    echo \"$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\ndone\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  echo \"$as_me:$LINENO: result: $CC\" >&5\necho \"${ECHO_T}$CC\" >&6\nelse\n  echo \"$as_me:$LINENO: result: no\" >&5\necho \"${ECHO_T}no\" >&6\nfi\n\nfi\nif test -z \"$ac_cv_prog_CC\"; then\n  ac_ct_CC=$CC\n  # Extract the first word of \"cc\", so it can be a program name with args.\nset dummy cc; ac_word=$2\necho \"$as_me:$LINENO: checking for $ac_word\" >&5\necho $ECHO_N \"checking for $ac_word... $ECHO_C\" >&6\nif test \"${ac_cv_prog_ac_ct_CC+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  if test -n \"$ac_ct_CC\"; then\n  ac_cv_prog_ac_ct_CC=\"$ac_ct_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  for ac_exec_ext in '' $ac_executable_extensions; do\n  if $as_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_ac_ct_CC=\"cc\"\n    echo \"$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\ndone\n\nfi\nfi\nac_ct_CC=$ac_cv_prog_ac_ct_CC\nif test -n \"$ac_ct_CC\"; then\n  echo \"$as_me:$LINENO: result: $ac_ct_CC\" >&5\necho \"${ECHO_T}$ac_ct_CC\" >&6\nelse\n  echo \"$as_me:$LINENO: result: no\" >&5\necho \"${ECHO_T}no\" >&6\nfi\n\n  CC=$ac_ct_CC\nelse\n  CC=\"$ac_cv_prog_CC\"\nfi\n\nfi\nif test -z \"$CC\"; then\n  # Extract the first word of \"cc\", so it can be a program name with args.\nset dummy cc; ac_word=$2\necho \"$as_me:$LINENO: checking for $ac_word\" >&5\necho $ECHO_N \"checking for $ac_word... $ECHO_C\" >&6\nif test \"${ac_cv_prog_CC+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\n  ac_prog_rejected=no\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  for ac_exec_ext in '' $ac_executable_extensions; do\n  if $as_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    if test \"$as_dir/$ac_word$ac_exec_ext\" = \"/usr/ucb/cc\"; then\n       ac_prog_rejected=yes\n       continue\n     fi\n    ac_cv_prog_CC=\"cc\"\n    echo \"$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\ndone\n\nif test $ac_prog_rejected = yes; then\n  # We found a bogon in the path, so make sure we never use it.\n  set dummy $ac_cv_prog_CC\n  shift\n  if test $# != 0; then\n    # We chose a different compiler from the bogus one.\n    # However, it has the same basename, so the bogon will be chosen\n    # first if we set CC to just the basename; use the full file name.\n    shift\n    ac_cv_prog_CC=\"$as_dir/$ac_word${1+' '}$@\"\n  fi\nfi\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  echo \"$as_me:$LINENO: result: $CC\" >&5\necho \"${ECHO_T}$CC\" >&6\nelse\n  echo \"$as_me:$LINENO: result: no\" >&5\necho \"${ECHO_T}no\" >&6\nfi\n\nfi\nif test -z \"$CC\"; then\n  if test -n \"$ac_tool_prefix\"; then\n  for ac_prog in cl\n  do\n    # Extract the first word of \"$ac_tool_prefix$ac_prog\", so it can be a program name with args.\nset dummy $ac_tool_prefix$ac_prog; ac_word=$2\necho \"$as_me:$LINENO: checking for $ac_word\" >&5\necho $ECHO_N \"checking for $ac_word... $ECHO_C\" >&6\nif test \"${ac_cv_prog_CC+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  for ac_exec_ext in '' $ac_executable_extensions; do\n  if $as_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_CC=\"$ac_tool_prefix$ac_prog\"\n    echo \"$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\ndone\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  echo \"$as_me:$LINENO: result: $CC\" >&5\necho \"${ECHO_T}$CC\" >&6\nelse\n  echo \"$as_me:$LINENO: result: no\" >&5\necho \"${ECHO_T}no\" >&6\nfi\n\n    test -n \"$CC\" && break\n  done\nfi\nif test -z \"$CC\"; then\n  ac_ct_CC=$CC\n  for ac_prog in cl\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\necho \"$as_me:$LINENO: checking for $ac_word\" >&5\necho $ECHO_N \"checking for $ac_word... $ECHO_C\" >&6\nif test \"${ac_cv_prog_ac_ct_CC+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  if test -n \"$ac_ct_CC\"; then\n  ac_cv_prog_ac_ct_CC=\"$ac_ct_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  for ac_exec_ext in '' $ac_executable_extensions; do\n  if $as_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_ac_ct_CC=\"$ac_prog\"\n    echo \"$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\ndone\n\nfi\nfi\nac_ct_CC=$ac_cv_prog_ac_ct_CC\nif test -n \"$ac_ct_CC\"; then\n  echo \"$as_me:$LINENO: result: $ac_ct_CC\" >&5\necho \"${ECHO_T}$ac_ct_CC\" >&6\nelse\n  echo \"$as_me:$LINENO: result: no\" >&5\necho \"${ECHO_T}no\" >&6\nfi\n\n  test -n \"$ac_ct_CC\" && break\ndone\n\n  CC=$ac_ct_CC\nfi\n\nfi\n\n\ntest -z \"$CC\" && { { echo \"$as_me:$LINENO: error: no acceptable C compiler found in \\$PATH\nSee \\`config.log' for more details.\" >&5\necho \"$as_me: error: no acceptable C compiler found in \\$PATH\nSee \\`config.log' for more details.\" >&2;}\n   { (exit 1); exit 1; }; }\n\n# Provide some information about the compiler.\necho \"$as_me:$LINENO:\" \\\n     \"checking for C compiler version\" >&5\nac_compiler=`set X $ac_compile; echo $2`\n{ (eval echo \"$as_me:$LINENO: \\\"$ac_compiler --version </dev/null >&5\\\"\") >&5\n  (eval $ac_compiler --version </dev/null >&5) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }\n{ (eval echo \"$as_me:$LINENO: \\\"$ac_compiler -v </dev/null >&5\\\"\") >&5\n  (eval $ac_compiler -v </dev/null >&5) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }\n{ (eval echo \"$as_me:$LINENO: \\\"$ac_compiler -V </dev/null >&5\\\"\") >&5\n  (eval $ac_compiler -V </dev/null >&5) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }\n\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nac_clean_files_save=$ac_clean_files\nac_clean_files=\"$ac_clean_files a.out a.exe b.out\"\n# Try to create an executable without -o first, disregard a.out.\n# It will help us diagnose broken compilers, and finding out an intuition\n# of exeext.\necho \"$as_me:$LINENO: checking for C compiler default output file name\" >&5\necho $ECHO_N \"checking for C compiler default output file name... $ECHO_C\" >&6\nac_link_default=`echo \"$ac_link\" | sed 's/ -o *conftest[^ ]*//'`\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_link_default\\\"\") >&5\n  (eval $ac_link_default) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; then\n  # Find the output, starting from the most likely.  This scheme is\n# not robust to junk in `.', hence go to wildcards (a.*) only as a last\n# resort.\n\n# Be careful to initialize this variable, since it used to be cached.\n# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.\nac_cv_exeext=\n# b.out is created by i960 compilers.\nfor ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out\ndo\n  test -f \"$ac_file\" || continue\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )\n\t;;\n    conftest.$ac_ext )\n\t# This is the source file.\n\t;;\n    [ab].out )\n\t# We found the default executable, but exeext='' is most\n\t# certainly right.\n\tbreak;;\n    *.* )\n\tac_cv_exeext=`expr \"$ac_file\" : '[^.]*\\(\\..*\\)'`\n\t# FIXME: I believe we export ac_cv_exeext for Libtool,\n\t# but it would be cool to find out if it's true.  Does anybody\n\t# maintain Libtool? --akim.\n\texport ac_cv_exeext\n\tbreak;;\n    * )\n\tbreak;;\n  esac\ndone\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n{ { echo \"$as_me:$LINENO: error: C compiler cannot create executables\nSee \\`config.log' for more details.\" >&5\necho \"$as_me: error: C compiler cannot create executables\nSee \\`config.log' for more details.\" >&2;}\n   { (exit 77); exit 77; }; }\nfi\n\nac_exeext=$ac_cv_exeext\necho \"$as_me:$LINENO: result: $ac_file\" >&5\necho \"${ECHO_T}$ac_file\" >&6\n\n# Check the compiler produces executables we can run.  If not, either\n# the compiler is broken, or we cross compile.\necho \"$as_me:$LINENO: checking whether the C compiler works\" >&5\necho $ECHO_N \"checking whether the C compiler works... $ECHO_C\" >&6\n# FIXME: These cross compiler hacks should be removed for Autoconf 3.0\n# If not cross compiling, check that we can run a simple program.\nif test \"$cross_compiling\" != yes; then\n  if { ac_try='./$ac_file'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n    cross_compiling=no\n  else\n    if test \"$cross_compiling\" = maybe; then\n\tcross_compiling=yes\n    else\n\t{ { echo \"$as_me:$LINENO: error: cannot run C compiled programs.\nIf you meant to cross compile, use \\`--host'.\nSee \\`config.log' for more details.\" >&5\necho \"$as_me: error: cannot run C compiled programs.\nIf you meant to cross compile, use \\`--host'.\nSee \\`config.log' for more details.\" >&2;}\n   { (exit 1); exit 1; }; }\n    fi\n  fi\nfi\necho \"$as_me:$LINENO: result: yes\" >&5\necho \"${ECHO_T}yes\" >&6\n\nrm -f a.out a.exe conftest$ac_cv_exeext b.out\nac_clean_files=$ac_clean_files_save\n# Check the compiler produces executables we can run.  If not, either\n# the compiler is broken, or we cross compile.\necho \"$as_me:$LINENO: checking whether we are cross compiling\" >&5\necho $ECHO_N \"checking whether we are cross compiling... $ECHO_C\" >&6\necho \"$as_me:$LINENO: result: $cross_compiling\" >&5\necho \"${ECHO_T}$cross_compiling\" >&6\n\necho \"$as_me:$LINENO: checking for suffix of executables\" >&5\necho $ECHO_N \"checking for suffix of executables... $ECHO_C\" >&6\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_link\\\"\") >&5\n  (eval $ac_link) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; then\n  # If both `conftest.exe' and `conftest' are `present' (well, observable)\n# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will\n# work properly (i.e., refer to `conftest.exe'), while it won't with\n# `rm'.\nfor ac_file in conftest.exe conftest conftest.*; do\n  test -f \"$ac_file\" || continue\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;\n    *.* ) ac_cv_exeext=`expr \"$ac_file\" : '[^.]*\\(\\..*\\)'`\n\t  export ac_cv_exeext\n\t  break;;\n    * ) break;;\n  esac\ndone\nelse\n  { { echo \"$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link\nSee \\`config.log' for more details.\" >&5\necho \"$as_me: error: cannot compute suffix of executables: cannot compile and link\nSee \\`config.log' for more details.\" >&2;}\n   { (exit 1); exit 1; }; }\nfi\n\nrm -f conftest$ac_cv_exeext\necho \"$as_me:$LINENO: result: $ac_cv_exeext\" >&5\necho \"${ECHO_T}$ac_cv_exeext\" >&6\n\nrm -f conftest.$ac_ext\nEXEEXT=$ac_cv_exeext\nac_exeext=$EXEEXT\necho \"$as_me:$LINENO: checking for suffix of object files\" >&5\necho $ECHO_N \"checking for suffix of object files... $ECHO_C\" >&6\nif test \"${ac_cv_objext+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.o conftest.obj\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; then\n  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;\n    *) ac_cv_objext=`expr \"$ac_file\" : '.*\\.\\(.*\\)'`\n       break;;\n  esac\ndone\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n{ { echo \"$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile\nSee \\`config.log' for more details.\" >&5\necho \"$as_me: error: cannot compute suffix of object files: cannot compile\nSee \\`config.log' for more details.\" >&2;}\n   { (exit 1); exit 1; }; }\nfi\n\nrm -f conftest.$ac_cv_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_objext\" >&5\necho \"${ECHO_T}$ac_cv_objext\" >&6\nOBJEXT=$ac_cv_objext\nac_objext=$OBJEXT\necho \"$as_me:$LINENO: checking whether we are using the GNU C compiler\" >&5\necho $ECHO_N \"checking whether we are using the GNU C compiler... $ECHO_C\" >&6\nif test \"${ac_cv_c_compiler_gnu+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n#ifndef __GNUC__\n       choke me\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_compiler_gnu=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_compiler_gnu=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nac_cv_c_compiler_gnu=$ac_compiler_gnu\n\nfi\necho \"$as_me:$LINENO: result: $ac_cv_c_compiler_gnu\" >&5\necho \"${ECHO_T}$ac_cv_c_compiler_gnu\" >&6\nGCC=`test $ac_compiler_gnu = yes && echo yes`\nac_test_CFLAGS=${CFLAGS+set}\nac_save_CFLAGS=$CFLAGS\nCFLAGS=\"-g\"\necho \"$as_me:$LINENO: checking whether $CC accepts -g\" >&5\necho $ECHO_N \"checking whether $CC accepts -g... $ECHO_C\" >&6\nif test \"${ac_cv_prog_cc_g+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_prog_cc_g=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_prog_cc_g=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_prog_cc_g\" >&5\necho \"${ECHO_T}$ac_cv_prog_cc_g\" >&6\nif test \"$ac_test_CFLAGS\" = set; then\n  CFLAGS=$ac_save_CFLAGS\nelif test $ac_cv_prog_cc_g = yes; then\n  if test \"$GCC\" = yes; then\n    CFLAGS=\"-g -O2\"\n  else\n    CFLAGS=\"-g\"\n  fi\nelse\n  if test \"$GCC\" = yes; then\n    CFLAGS=\"-O2\"\n  else\n    CFLAGS=\n  fi\nfi\necho \"$as_me:$LINENO: checking for $CC option to accept ANSI C\" >&5\necho $ECHO_N \"checking for $CC option to accept ANSI C... $ECHO_C\" >&6\nif test \"${ac_cv_prog_cc_stdc+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  ac_cv_prog_cc_stdc=no\nac_save_CC=$CC\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <stdarg.h>\n#include <stdio.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */\nstruct buf { int x; };\nFILE * (*rcsopen) (struct buf *, struct stat *, int);\nstatic char *e (p, i)\n     char **p;\n     int i;\n{\n  return p[i];\n}\nstatic char *f (char * (*g) (char **, int), char **p, ...)\n{\n  char *s;\n  va_list v;\n  va_start (v,p);\n  s = g (p, va_arg (v,int));\n  va_end (v);\n  return s;\n}\n\n/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has\n   function prototypes and stuff, but not '\\xHH' hex character constants.\n   These don't provoke an error unfortunately, instead are silently treated\n   as 'x'.  The following induces an error, until -std1 is added to get\n   proper ANSI mode.  Curiously '\\x00'!='x' always comes out true, for an\n   array size at least.  It's necessary to write '\\x00'==0 to get something\n   that's true only with -std1.  */\nint osf4_cc_array ['\\x00' == 0 ? 1 : -1];\n\nint test (int i, double x);\nstruct s1 {int (*f) (int a);};\nstruct s2 {int (*f) (double a);};\nint pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);\nint argc;\nchar **argv;\nint\nmain ()\n{\nreturn f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];\n  ;\n  return 0;\n}\n_ACEOF\n# Don't try gcc -ansi; that turns off useful extensions and\n# breaks some systems' header files.\n# AIX\t\t\t-qlanglvl=ansi\n# Ultrix and OSF/1\t-std1\n# HP-UX 10.20 and later\t-Ae\n# HP-UX older versions\t-Aa -D_HPUX_SOURCE\n# SVR4\t\t\t-Xc -D__EXTENSIONS__\nfor ac_arg in \"\" -qlanglvl=ansi -std1 -Ae \"-Aa -D_HPUX_SOURCE\" \"-Xc -D__EXTENSIONS__\"\ndo\n  CC=\"$ac_save_CC $ac_arg\"\n  rm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_prog_cc_stdc=$ac_arg\nbreak\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nfi\nrm -f conftest.err conftest.$ac_objext\ndone\nrm -f conftest.$ac_ext conftest.$ac_objext\nCC=$ac_save_CC\n\nfi\n\ncase \"x$ac_cv_prog_cc_stdc\" in\n  x|xno)\n    echo \"$as_me:$LINENO: result: none needed\" >&5\necho \"${ECHO_T}none needed\" >&6 ;;\n  *)\n    echo \"$as_me:$LINENO: result: $ac_cv_prog_cc_stdc\" >&5\necho \"${ECHO_T}$ac_cv_prog_cc_stdc\" >&6\n    CC=\"$CC $ac_cv_prog_cc_stdc\" ;;\nesac\n\n# Some people use a C++ compiler to compile C.  Since we use `exit',\n# in C++ we need to declare it.  In case someone uses the same compiler\n# for both compiling C and C++ we need to have the C++ compiler decide\n# the declaration of exit, since it's the most demanding environment.\ncat >conftest.$ac_ext <<_ACEOF\n#ifndef __cplusplus\n  choke me\n#endif\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  for ac_declaration in \\\n   '' \\\n   'extern \"C\" void std::exit (int) throw (); using std::exit;' \\\n   'extern \"C\" void std::exit (int); using std::exit;' \\\n   'extern \"C\" void exit (int) throw ();' \\\n   'extern \"C\" void exit (int);' \\\n   'void exit (int);'\ndo\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_declaration\n#include <stdlib.h>\nint\nmain ()\n{\nexit (42);\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  :\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\ncontinue\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_declaration\nint\nmain ()\n{\nexit (42);\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  break\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\ndone\nrm -f conftest*\nif test -n \"$ac_declaration\"; then\n  echo '#ifdef __cplusplus' >>confdefs.h\n  echo $ac_declaration      >>confdefs.h\n  echo '#endif'             >>confdefs.h\nfi\n\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nac_aux_dir=\nfor ac_dir in $srcdir $srcdir/.. $srcdir/../..; do\n  if test -f $ac_dir/install-sh; then\n    ac_aux_dir=$ac_dir\n    ac_install_sh=\"$ac_aux_dir/install-sh -c\"\n    break\n  elif test -f $ac_dir/install.sh; then\n    ac_aux_dir=$ac_dir\n    ac_install_sh=\"$ac_aux_dir/install.sh -c\"\n    break\n  elif test -f $ac_dir/shtool; then\n    ac_aux_dir=$ac_dir\n    ac_install_sh=\"$ac_aux_dir/shtool install -c\"\n    break\n  fi\ndone\nif test -z \"$ac_aux_dir\"; then\n  { { echo \"$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../..\" >&5\necho \"$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../..\" >&2;}\n   { (exit 1); exit 1; }; }\nfi\nac_config_guess=\"$SHELL $ac_aux_dir/config.guess\"\nac_config_sub=\"$SHELL $ac_aux_dir/config.sub\"\nac_configure=\"$SHELL $ac_aux_dir/configure\" # This should be Cygnus configure.\n\n# Find a good install program.  We prefer a C program (faster),\n# so one script is as good as another.  But avoid the broken or\n# incompatible versions:\n# SysV /etc/install, /usr/sbin/install\n# SunOS /usr/etc/install\n# IRIX /sbin/install\n# AIX /bin/install\n# AmigaOS /C/install, which installs bootblocks on floppy discs\n# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag\n# AFS /usr/afsws/bin/install, which mishandles nonexistent args\n# SVR4 /usr/ucb/install, which tries to use the nonexistent group \"staff\"\n# OS/2's system install, which has a completely different semantic\n# ./install, which can be erroneously created by make from ./install.sh.\necho \"$as_me:$LINENO: checking for a BSD-compatible install\" >&5\necho $ECHO_N \"checking for a BSD-compatible install... $ECHO_C\" >&6\nif test -z \"$INSTALL\"; then\nif test \"${ac_cv_path_install+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  # Account for people who put trailing slashes in PATH elements.\ncase $as_dir/ in\n  ./ | .// | /cC/* | \\\n  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \\\n  ?:\\\\/os2\\\\/install\\\\/* | ?:\\\\/OS2\\\\/INSTALL\\\\/* | \\\n  /usr/ucb/* ) ;;\n  *)\n    # OSF1 and SCO ODT 3.0 have their own names for install.\n    # Don't use installbsd from OSF since it installs stuff as root\n    # by default.\n    for ac_prog in ginstall scoinst install; do\n      for ac_exec_ext in '' $ac_executable_extensions; do\n\tif $as_executable_p \"$as_dir/$ac_prog$ac_exec_ext\"; then\n\t  if test $ac_prog = install &&\n\t    grep dspmsg \"$as_dir/$ac_prog$ac_exec_ext\" >/dev/null 2>&1; then\n\t    # AIX install.  It has an incompatible calling convention.\n\t    :\n\t  elif test $ac_prog = install &&\n\t    grep pwplus \"$as_dir/$ac_prog$ac_exec_ext\" >/dev/null 2>&1; then\n\t    # program-specific install script used by HP pwplus--don't use.\n\t    :\n\t  else\n\t    ac_cv_path_install=\"$as_dir/$ac_prog$ac_exec_ext -c\"\n\t    break 3\n\t  fi\n\tfi\n      done\n    done\n    ;;\nesac\ndone\n\n\nfi\n  if test \"${ac_cv_path_install+set}\" = set; then\n    INSTALL=$ac_cv_path_install\n  else\n    # As a last resort, use the slow shell script.  We don't cache a\n    # path for INSTALL within a source directory, because that will\n    # break other packages using the cache if that directory is\n    # removed, or if the path is relative.\n    INSTALL=$ac_install_sh\n  fi\nfi\necho \"$as_me:$LINENO: result: $INSTALL\" >&5\necho \"${ECHO_T}$INSTALL\" >&6\n\n# Use test -z because SunOS4 sh mishandles braces in ${var-val}.\n# It thinks the first close brace ends the variable substitution.\ntest -z \"$INSTALL_PROGRAM\" && INSTALL_PROGRAM='${INSTALL}'\n\ntest -z \"$INSTALL_SCRIPT\" && INSTALL_SCRIPT='${INSTALL}'\n\ntest -z \"$INSTALL_DATA\" && INSTALL_DATA='${INSTALL} -m 644'\n\n\n\n# Check whether --enable-kernel-linux or --disable-kernel-linux was given.\nif test \"${enable_kernel_linux+set}\" = set; then\n  enableval=\"$enable_kernel_linux\"\n\nelse\n  enable_kernel_linux=no\nfi;\necho \"$as_me:$LINENO: checking whether to build for Linux kernel context\" >&5\necho $ECHO_N \"checking whether to build for Linux kernel context... $ECHO_C\" >&6\nif test \"$enable_kernel_linux\" = \"yes\"; then\n\ncat >>confdefs.h <<\\_ACEOF\n#define SRTP_KERNEL 1\n_ACEOF\n\n\ncat >>confdefs.h <<\\_ACEOF\n#define SRTP_KERNEL_LINUX 1\n_ACEOF\n\nfi\necho \"$as_me:$LINENO: result: $enable_kernel_linux\" >&5\necho \"${ECHO_T}$enable_kernel_linux\" >&6\n\nif test \"$cross_compiling\" != yes; then\n      echo \"$as_me:$LINENO: checking for /dev/urandom\" >&5\necho $ECHO_N \"checking for /dev/urandom... $ECHO_C\" >&6\nif test \"${ac_cv_file__dev_urandom+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  test \"$cross_compiling\" = yes &&\n  { { echo \"$as_me:$LINENO: error: cannot check for file existence when cross compiling\" >&5\necho \"$as_me: error: cannot check for file existence when cross compiling\" >&2;}\n   { (exit 1); exit 1; }; }\nif test -r \"/dev/urandom\"; then\n  ac_cv_file__dev_urandom=yes\nelse\n  ac_cv_file__dev_urandom=no\nfi\nfi\necho \"$as_me:$LINENO: result: $ac_cv_file__dev_urandom\" >&5\necho \"${ECHO_T}$ac_cv_file__dev_urandom\" >&6\nif test $ac_cv_file__dev_urandom = yes; then\n  DEV_URANDOM=/dev/urandom\nelse\n  echo \"$as_me:$LINENO: checking for /dev/random\" >&5\necho $ECHO_N \"checking for /dev/random... $ECHO_C\" >&6\nif test \"${ac_cv_file__dev_random+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  test \"$cross_compiling\" = yes &&\n  { { echo \"$as_me:$LINENO: error: cannot check for file existence when cross compiling\" >&5\necho \"$as_me: error: cannot check for file existence when cross compiling\" >&2;}\n   { (exit 1); exit 1; }; }\nif test -r \"/dev/random\"; then\n  ac_cv_file__dev_random=yes\nelse\n  ac_cv_file__dev_random=no\nfi\nfi\necho \"$as_me:$LINENO: result: $ac_cv_file__dev_random\" >&5\necho \"${ECHO_T}$ac_cv_file__dev_random\" >&6\nif test $ac_cv_file__dev_random = yes; then\n  DEV_URANDOM=/dev/random\nfi\n\nfi\n\nfi\n\necho \"$as_me:$LINENO: checking which random device to use\" >&5\necho $ECHO_N \"checking which random device to use... $ECHO_C\" >&6\nif test \"$enable_kernel_linux\" = \"yes\"; then\n   RNG_OBJS=rand_linux_kernel.o\n   echo \"$as_me:$LINENO: result: Linux kernel builtin\" >&5\necho \"${ECHO_T}Linux kernel builtin\" >&6\nelse\n   RNG_OBJS=rand_source.o\n   if test -n \"$DEV_URANDOM\"; then\n\ncat >>confdefs.h <<_ACEOF\n#define DEV_URANDOM \"$DEV_URANDOM\"\n_ACEOF\n\n      echo \"$as_me:$LINENO: result: $DEV_URANDOM\" >&5\necho \"${ECHO_T}$DEV_URANDOM\" >&6\n   else\n      echo \"$as_me:$LINENO: result: standard rand() function...\" >&5\necho \"${ECHO_T}standard rand() function...\" >&6\n   fi\nfi\n\n\n\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\necho \"$as_me:$LINENO: checking how to run the C preprocessor\" >&5\necho $ECHO_N \"checking how to run the C preprocessor... $ECHO_C\" >&6\n# On Suns, sometimes $CPP names a directory.\nif test -n \"$CPP\" && test -d \"$CPP\"; then\n  CPP=\nfi\nif test -z \"$CPP\"; then\n  if test \"${ac_cv_prog_CPP+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n      # Double quotes because CPP needs to be expanded\n    for CPP in \"$CC -E\" \"$CC -E -traditional-cpp\" \"/lib/cpp\"\n    do\n      ac_preproc_ok=false\nfor ac_c_preproc_warn_flag in '' yes\ndo\n  # Use a header file that comes with gcc, so configuring glibc\n  # with a fresh cross-compiler works.\n  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n  # <limits.h> exists even on freestanding compilers.\n  # On the NeXT, cc -E runs the code through the compiler's parser,\n  # not just through cpp. \"Syntax error\" is here to catch this case.\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\t\t     Syntax error\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  :\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  # Broken: fails on valid input.\ncontinue\nfi\nrm -f conftest.err conftest.$ac_ext\n\n  # OK, works on sane cases.  Now check whether non-existent headers\n  # can be detected and how.\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <ac_nonexistent.h>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  # Broken: success on invalid input.\ncontinue\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  # Passes both tests.\nac_preproc_ok=:\nbreak\nfi\nrm -f conftest.err conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.err conftest.$ac_ext\nif $ac_preproc_ok; then\n  break\nfi\n\n    done\n    ac_cv_prog_CPP=$CPP\n\nfi\n  CPP=$ac_cv_prog_CPP\nelse\n  ac_cv_prog_CPP=$CPP\nfi\necho \"$as_me:$LINENO: result: $CPP\" >&5\necho \"${ECHO_T}$CPP\" >&6\nac_preproc_ok=false\nfor ac_c_preproc_warn_flag in '' yes\ndo\n  # Use a header file that comes with gcc, so configuring glibc\n  # with a fresh cross-compiler works.\n  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n  # <limits.h> exists even on freestanding compilers.\n  # On the NeXT, cc -E runs the code through the compiler's parser,\n  # not just through cpp. \"Syntax error\" is here to catch this case.\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\t\t     Syntax error\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  :\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  # Broken: fails on valid input.\ncontinue\nfi\nrm -f conftest.err conftest.$ac_ext\n\n  # OK, works on sane cases.  Now check whether non-existent headers\n  # can be detected and how.\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <ac_nonexistent.h>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  # Broken: success on invalid input.\ncontinue\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  # Passes both tests.\nac_preproc_ok=:\nbreak\nfi\nrm -f conftest.err conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.err conftest.$ac_ext\nif $ac_preproc_ok; then\n  :\nelse\n  { { echo \"$as_me:$LINENO: error: C preprocessor \\\"$CPP\\\" fails sanity check\nSee \\`config.log' for more details.\" >&5\necho \"$as_me: error: C preprocessor \\\"$CPP\\\" fails sanity check\nSee \\`config.log' for more details.\" >&2;}\n   { (exit 1); exit 1; }; }\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\necho \"$as_me:$LINENO: checking for egrep\" >&5\necho $ECHO_N \"checking for egrep... $ECHO_C\" >&6\nif test \"${ac_cv_prog_egrep+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  if echo a | (grep -E '(a|b)') >/dev/null 2>&1\n    then ac_cv_prog_egrep='grep -E'\n    else ac_cv_prog_egrep='egrep'\n    fi\nfi\necho \"$as_me:$LINENO: result: $ac_cv_prog_egrep\" >&5\necho \"${ECHO_T}$ac_cv_prog_egrep\" >&6\n EGREP=$ac_cv_prog_egrep\n\n\necho \"$as_me:$LINENO: checking for ANSI C header files\" >&5\necho $ECHO_N \"checking for ANSI C header files... $ECHO_C\" >&6\nif test \"${ac_cv_header_stdc+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <stdlib.h>\n#include <stdarg.h>\n#include <string.h>\n#include <float.h>\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_header_stdc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_header_stdc=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\n\nif test $ac_cv_header_stdc = yes; then\n  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <string.h>\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"memchr\" >/dev/null 2>&1; then\n  :\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f conftest*\n\nfi\n\nif test $ac_cv_header_stdc = yes; then\n  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <stdlib.h>\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"free\" >/dev/null 2>&1; then\n  :\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f conftest*\n\nfi\n\nif test $ac_cv_header_stdc = yes; then\n  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.\n  if test \"$cross_compiling\" = yes; then\n  :\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <ctype.h>\n#if ((' ' & 0x0FF) == 0x020)\n# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')\n# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))\n#else\n# define ISLOWER(c) \\\n\t\t   (('a' <= (c) && (c) <= 'i') \\\n\t\t     || ('j' <= (c) && (c) <= 'r') \\\n\t\t     || ('s' <= (c) && (c) <= 'z'))\n# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))\n#endif\n\n#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))\nint\nmain ()\n{\n  int i;\n  for (i = 0; i < 256; i++)\n    if (XOR (islower (i), ISLOWER (i))\n\t|| toupper (i) != TOUPPER (i))\n      exit(2);\n  exit (0);\n}\n_ACEOF\nrm -f conftest$ac_exeext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_link\\\"\") >&5\n  (eval $ac_link) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  :\nelse\n  echo \"$as_me: program exited with status $ac_status\" >&5\necho \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n( exit $ac_status )\nac_cv_header_stdc=no\nfi\nrm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext\nfi\nfi\nfi\necho \"$as_me:$LINENO: result: $ac_cv_header_stdc\" >&5\necho \"${ECHO_T}$ac_cv_header_stdc\" >&6\nif test $ac_cv_header_stdc = yes; then\n\ncat >>confdefs.h <<\\_ACEOF\n#define STDC_HEADERS 1\n_ACEOF\n\nfi\n\n# On IRIX 5.3, sys/types and inttypes.h are conflicting.\n\n\n\n\n\n\n\n\n\nfor ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \\\n\t\t  inttypes.h stdint.h unistd.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  eval \"$as_ac_Header=yes\"\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\neval \"$as_ac_Header=no\"\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\n\nfor ac_header in stdlib.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nelse\n  # Is the header compilable?\necho \"$as_me:$LINENO: checking $ac_header usability\" >&5\necho $ECHO_N \"checking $ac_header usability... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_header_compiler=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_header_compiler=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_compiler\" >&5\necho \"${ECHO_T}$ac_header_compiler\" >&6\n\n# Is the header present?\necho \"$as_me:$LINENO: checking $ac_header presence\" >&5\necho $ECHO_N \"checking $ac_header presence... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <$ac_header>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  ac_header_preproc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_preproc\" >&5\necho \"${ECHO_T}$ac_header_preproc\" >&6\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in\n  yes:no: )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&5\necho \"$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the compiler's result\" >&2;}\n    ac_header_preproc=yes\n    ;;\n  no:yes:* )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled\" >&5\necho \"$as_me: WARNING: $ac_header: present but cannot be compiled\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?\" >&5\necho \"$as_me: WARNING: $ac_header:     check for missing prerequisite headers?\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation\" >&5\necho \"$as_me: WARNING: $ac_header: see the Autoconf documentation\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\necho \"$as_me: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the preprocessor's result\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence\" >&5\necho \"$as_me: WARNING: $ac_header: in the future, the compiler will take precedence\" >&2;}\n    (\n      cat <<\\_ASBOX\n## ------------------------------------------ ##\n## Report this to the AC_PACKAGE_NAME lists.  ##\n## ------------------------------------------ ##\n_ASBOX\n    ) |\n      sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  eval \"$as_ac_Header=\\$ac_header_preproc\"\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\n\nfi\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\nfor ac_header in unistd.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nelse\n  # Is the header compilable?\necho \"$as_me:$LINENO: checking $ac_header usability\" >&5\necho $ECHO_N \"checking $ac_header usability... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_header_compiler=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_header_compiler=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_compiler\" >&5\necho \"${ECHO_T}$ac_header_compiler\" >&6\n\n# Is the header present?\necho \"$as_me:$LINENO: checking $ac_header presence\" >&5\necho $ECHO_N \"checking $ac_header presence... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <$ac_header>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  ac_header_preproc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_preproc\" >&5\necho \"${ECHO_T}$ac_header_preproc\" >&6\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in\n  yes:no: )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&5\necho \"$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the compiler's result\" >&2;}\n    ac_header_preproc=yes\n    ;;\n  no:yes:* )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled\" >&5\necho \"$as_me: WARNING: $ac_header: present but cannot be compiled\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?\" >&5\necho \"$as_me: WARNING: $ac_header:     check for missing prerequisite headers?\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation\" >&5\necho \"$as_me: WARNING: $ac_header: see the Autoconf documentation\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\necho \"$as_me: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the preprocessor's result\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence\" >&5\necho \"$as_me: WARNING: $ac_header: in the future, the compiler will take precedence\" >&2;}\n    (\n      cat <<\\_ASBOX\n## ------------------------------------------ ##\n## Report this to the AC_PACKAGE_NAME lists.  ##\n## ------------------------------------------ ##\n_ASBOX\n    ) |\n      sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  eval \"$as_ac_Header=\\$ac_header_preproc\"\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\n\nfi\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\nfor ac_header in byteswap.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nelse\n  # Is the header compilable?\necho \"$as_me:$LINENO: checking $ac_header usability\" >&5\necho $ECHO_N \"checking $ac_header usability... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_header_compiler=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_header_compiler=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_compiler\" >&5\necho \"${ECHO_T}$ac_header_compiler\" >&6\n\n# Is the header present?\necho \"$as_me:$LINENO: checking $ac_header presence\" >&5\necho $ECHO_N \"checking $ac_header presence... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <$ac_header>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  ac_header_preproc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_preproc\" >&5\necho \"${ECHO_T}$ac_header_preproc\" >&6\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in\n  yes:no: )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&5\necho \"$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the compiler's result\" >&2;}\n    ac_header_preproc=yes\n    ;;\n  no:yes:* )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled\" >&5\necho \"$as_me: WARNING: $ac_header: present but cannot be compiled\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?\" >&5\necho \"$as_me: WARNING: $ac_header:     check for missing prerequisite headers?\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation\" >&5\necho \"$as_me: WARNING: $ac_header: see the Autoconf documentation\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\necho \"$as_me: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the preprocessor's result\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence\" >&5\necho \"$as_me: WARNING: $ac_header: in the future, the compiler will take precedence\" >&2;}\n    (\n      cat <<\\_ASBOX\n## ------------------------------------------ ##\n## Report this to the AC_PACKAGE_NAME lists.  ##\n## ------------------------------------------ ##\n_ASBOX\n    ) |\n      sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  eval \"$as_ac_Header=\\$ac_header_preproc\"\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\n\nfi\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\nfor ac_header in stdint.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nelse\n  # Is the header compilable?\necho \"$as_me:$LINENO: checking $ac_header usability\" >&5\necho $ECHO_N \"checking $ac_header usability... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_header_compiler=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_header_compiler=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_compiler\" >&5\necho \"${ECHO_T}$ac_header_compiler\" >&6\n\n# Is the header present?\necho \"$as_me:$LINENO: checking $ac_header presence\" >&5\necho $ECHO_N \"checking $ac_header presence... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <$ac_header>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  ac_header_preproc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_preproc\" >&5\necho \"${ECHO_T}$ac_header_preproc\" >&6\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in\n  yes:no: )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&5\necho \"$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the compiler's result\" >&2;}\n    ac_header_preproc=yes\n    ;;\n  no:yes:* )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled\" >&5\necho \"$as_me: WARNING: $ac_header: present but cannot be compiled\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?\" >&5\necho \"$as_me: WARNING: $ac_header:     check for missing prerequisite headers?\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation\" >&5\necho \"$as_me: WARNING: $ac_header: see the Autoconf documentation\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\necho \"$as_me: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the preprocessor's result\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence\" >&5\necho \"$as_me: WARNING: $ac_header: in the future, the compiler will take precedence\" >&2;}\n    (\n      cat <<\\_ASBOX\n## ------------------------------------------ ##\n## Report this to the AC_PACKAGE_NAME lists.  ##\n## ------------------------------------------ ##\n_ASBOX\n    ) |\n      sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  eval \"$as_ac_Header=\\$ac_header_preproc\"\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\n\nfi\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\nfor ac_header in sys/uio.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nelse\n  # Is the header compilable?\necho \"$as_me:$LINENO: checking $ac_header usability\" >&5\necho $ECHO_N \"checking $ac_header usability... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_header_compiler=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_header_compiler=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_compiler\" >&5\necho \"${ECHO_T}$ac_header_compiler\" >&6\n\n# Is the header present?\necho \"$as_me:$LINENO: checking $ac_header presence\" >&5\necho $ECHO_N \"checking $ac_header presence... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <$ac_header>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  ac_header_preproc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_preproc\" >&5\necho \"${ECHO_T}$ac_header_preproc\" >&6\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in\n  yes:no: )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&5\necho \"$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the compiler's result\" >&2;}\n    ac_header_preproc=yes\n    ;;\n  no:yes:* )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled\" >&5\necho \"$as_me: WARNING: $ac_header: present but cannot be compiled\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?\" >&5\necho \"$as_me: WARNING: $ac_header:     check for missing prerequisite headers?\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation\" >&5\necho \"$as_me: WARNING: $ac_header: see the Autoconf documentation\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\necho \"$as_me: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the preprocessor's result\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence\" >&5\necho \"$as_me: WARNING: $ac_header: in the future, the compiler will take precedence\" >&2;}\n    (\n      cat <<\\_ASBOX\n## ------------------------------------------ ##\n## Report this to the AC_PACKAGE_NAME lists.  ##\n## ------------------------------------------ ##\n_ASBOX\n    ) |\n      sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  eval \"$as_ac_Header=\\$ac_header_preproc\"\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\n\nfi\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\nfor ac_header in inttypes.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nelse\n  # Is the header compilable?\necho \"$as_me:$LINENO: checking $ac_header usability\" >&5\necho $ECHO_N \"checking $ac_header usability... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_header_compiler=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_header_compiler=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_compiler\" >&5\necho \"${ECHO_T}$ac_header_compiler\" >&6\n\n# Is the header present?\necho \"$as_me:$LINENO: checking $ac_header presence\" >&5\necho $ECHO_N \"checking $ac_header presence... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <$ac_header>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  ac_header_preproc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_preproc\" >&5\necho \"${ECHO_T}$ac_header_preproc\" >&6\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in\n  yes:no: )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&5\necho \"$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the compiler's result\" >&2;}\n    ac_header_preproc=yes\n    ;;\n  no:yes:* )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled\" >&5\necho \"$as_me: WARNING: $ac_header: present but cannot be compiled\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?\" >&5\necho \"$as_me: WARNING: $ac_header:     check for missing prerequisite headers?\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation\" >&5\necho \"$as_me: WARNING: $ac_header: see the Autoconf documentation\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\necho \"$as_me: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the preprocessor's result\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence\" >&5\necho \"$as_me: WARNING: $ac_header: in the future, the compiler will take precedence\" >&2;}\n    (\n      cat <<\\_ASBOX\n## ------------------------------------------ ##\n## Report this to the AC_PACKAGE_NAME lists.  ##\n## ------------------------------------------ ##\n_ASBOX\n    ) |\n      sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  eval \"$as_ac_Header=\\$ac_header_preproc\"\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\n\nfi\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\nfor ac_header in sys/types.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nelse\n  # Is the header compilable?\necho \"$as_me:$LINENO: checking $ac_header usability\" >&5\necho $ECHO_N \"checking $ac_header usability... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_header_compiler=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_header_compiler=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_compiler\" >&5\necho \"${ECHO_T}$ac_header_compiler\" >&6\n\n# Is the header present?\necho \"$as_me:$LINENO: checking $ac_header presence\" >&5\necho $ECHO_N \"checking $ac_header presence... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <$ac_header>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  ac_header_preproc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_preproc\" >&5\necho \"${ECHO_T}$ac_header_preproc\" >&6\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in\n  yes:no: )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&5\necho \"$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the compiler's result\" >&2;}\n    ac_header_preproc=yes\n    ;;\n  no:yes:* )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled\" >&5\necho \"$as_me: WARNING: $ac_header: present but cannot be compiled\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?\" >&5\necho \"$as_me: WARNING: $ac_header:     check for missing prerequisite headers?\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation\" >&5\necho \"$as_me: WARNING: $ac_header: see the Autoconf documentation\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\necho \"$as_me: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the preprocessor's result\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence\" >&5\necho \"$as_me: WARNING: $ac_header: in the future, the compiler will take precedence\" >&2;}\n    (\n      cat <<\\_ASBOX\n## ------------------------------------------ ##\n## Report this to the AC_PACKAGE_NAME lists.  ##\n## ------------------------------------------ ##\n_ASBOX\n    ) |\n      sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  eval \"$as_ac_Header=\\$ac_header_preproc\"\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\n\nfi\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\nfor ac_header in machine/types.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nelse\n  # Is the header compilable?\necho \"$as_me:$LINENO: checking $ac_header usability\" >&5\necho $ECHO_N \"checking $ac_header usability... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_header_compiler=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_header_compiler=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_compiler\" >&5\necho \"${ECHO_T}$ac_header_compiler\" >&6\n\n# Is the header present?\necho \"$as_me:$LINENO: checking $ac_header presence\" >&5\necho $ECHO_N \"checking $ac_header presence... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <$ac_header>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  ac_header_preproc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_preproc\" >&5\necho \"${ECHO_T}$ac_header_preproc\" >&6\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in\n  yes:no: )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&5\necho \"$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the compiler's result\" >&2;}\n    ac_header_preproc=yes\n    ;;\n  no:yes:* )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled\" >&5\necho \"$as_me: WARNING: $ac_header: present but cannot be compiled\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?\" >&5\necho \"$as_me: WARNING: $ac_header:     check for missing prerequisite headers?\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation\" >&5\necho \"$as_me: WARNING: $ac_header: see the Autoconf documentation\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\necho \"$as_me: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the preprocessor's result\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence\" >&5\necho \"$as_me: WARNING: $ac_header: in the future, the compiler will take precedence\" >&2;}\n    (\n      cat <<\\_ASBOX\n## ------------------------------------------ ##\n## Report this to the AC_PACKAGE_NAME lists.  ##\n## ------------------------------------------ ##\n_ASBOX\n    ) |\n      sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  eval \"$as_ac_Header=\\$ac_header_preproc\"\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\n\nfi\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\nfor ac_header in sys/int_types.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nelse\n  # Is the header compilable?\necho \"$as_me:$LINENO: checking $ac_header usability\" >&5\necho $ECHO_N \"checking $ac_header usability... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_header_compiler=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_header_compiler=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_compiler\" >&5\necho \"${ECHO_T}$ac_header_compiler\" >&6\n\n# Is the header present?\necho \"$as_me:$LINENO: checking $ac_header presence\" >&5\necho $ECHO_N \"checking $ac_header presence... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <$ac_header>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  ac_header_preproc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_preproc\" >&5\necho \"${ECHO_T}$ac_header_preproc\" >&6\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in\n  yes:no: )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&5\necho \"$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the compiler's result\" >&2;}\n    ac_header_preproc=yes\n    ;;\n  no:yes:* )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled\" >&5\necho \"$as_me: WARNING: $ac_header: present but cannot be compiled\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?\" >&5\necho \"$as_me: WARNING: $ac_header:     check for missing prerequisite headers?\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation\" >&5\necho \"$as_me: WARNING: $ac_header: see the Autoconf documentation\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\necho \"$as_me: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the preprocessor's result\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence\" >&5\necho \"$as_me: WARNING: $ac_header: in the future, the compiler will take precedence\" >&2;}\n    (\n      cat <<\\_ASBOX\n## ------------------------------------------ ##\n## Report this to the AC_PACKAGE_NAME lists.  ##\n## ------------------------------------------ ##\n_ASBOX\n    ) |\n      sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  eval \"$as_ac_Header=\\$ac_header_preproc\"\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\n\nfi\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\n\n\n\nfor ac_header in sys/socket.h netinet/in.h arpa/inet.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nelse\n  # Is the header compilable?\necho \"$as_me:$LINENO: checking $ac_header usability\" >&5\necho $ECHO_N \"checking $ac_header usability... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_header_compiler=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_header_compiler=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_compiler\" >&5\necho \"${ECHO_T}$ac_header_compiler\" >&6\n\n# Is the header present?\necho \"$as_me:$LINENO: checking $ac_header presence\" >&5\necho $ECHO_N \"checking $ac_header presence... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <$ac_header>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  ac_header_preproc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_preproc\" >&5\necho \"${ECHO_T}$ac_header_preproc\" >&6\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in\n  yes:no: )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&5\necho \"$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the compiler's result\" >&2;}\n    ac_header_preproc=yes\n    ;;\n  no:yes:* )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled\" >&5\necho \"$as_me: WARNING: $ac_header: present but cannot be compiled\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?\" >&5\necho \"$as_me: WARNING: $ac_header:     check for missing prerequisite headers?\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation\" >&5\necho \"$as_me: WARNING: $ac_header: see the Autoconf documentation\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\necho \"$as_me: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the preprocessor's result\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence\" >&5\necho \"$as_me: WARNING: $ac_header: in the future, the compiler will take precedence\" >&2;}\n    (\n      cat <<\\_ASBOX\n## ------------------------------------------ ##\n## Report this to the AC_PACKAGE_NAME lists.  ##\n## ------------------------------------------ ##\n_ASBOX\n    ) |\n      sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  eval \"$as_ac_Header=\\$ac_header_preproc\"\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\n\nfi\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\nfor ac_header in windows.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nelse\n  # Is the header compilable?\necho \"$as_me:$LINENO: checking $ac_header usability\" >&5\necho $ECHO_N \"checking $ac_header usability... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_header_compiler=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_header_compiler=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_compiler\" >&5\necho \"${ECHO_T}$ac_header_compiler\" >&6\n\n# Is the header present?\necho \"$as_me:$LINENO: checking $ac_header presence\" >&5\necho $ECHO_N \"checking $ac_header presence... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <$ac_header>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  ac_header_preproc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_preproc\" >&5\necho \"${ECHO_T}$ac_header_preproc\" >&6\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in\n  yes:no: )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&5\necho \"$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the compiler's result\" >&2;}\n    ac_header_preproc=yes\n    ;;\n  no:yes:* )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled\" >&5\necho \"$as_me: WARNING: $ac_header: present but cannot be compiled\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?\" >&5\necho \"$as_me: WARNING: $ac_header:     check for missing prerequisite headers?\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation\" >&5\necho \"$as_me: WARNING: $ac_header: see the Autoconf documentation\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\necho \"$as_me: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the preprocessor's result\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence\" >&5\necho \"$as_me: WARNING: $ac_header: in the future, the compiler will take precedence\" >&2;}\n    (\n      cat <<\\_ASBOX\n## ------------------------------------------ ##\n## Report this to the AC_PACKAGE_NAME lists.  ##\n## ------------------------------------------ ##\n_ASBOX\n    ) |\n      sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  eval \"$as_ac_Header=\\$ac_header_preproc\"\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\n\nfi\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfor ac_header in winsock2.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nelse\n  # Is the header compilable?\necho \"$as_me:$LINENO: checking $ac_header usability\" >&5\necho $ECHO_N \"checking $ac_header usability... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_header_compiler=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_header_compiler=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_compiler\" >&5\necho \"${ECHO_T}$ac_header_compiler\" >&6\n\n# Is the header present?\necho \"$as_me:$LINENO: checking $ac_header presence\" >&5\necho $ECHO_N \"checking $ac_header presence... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <$ac_header>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  ac_header_preproc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_preproc\" >&5\necho \"${ECHO_T}$ac_header_preproc\" >&6\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in\n  yes:no: )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&5\necho \"$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the compiler's result\" >&2;}\n    ac_header_preproc=yes\n    ;;\n  no:yes:* )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled\" >&5\necho \"$as_me: WARNING: $ac_header: present but cannot be compiled\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?\" >&5\necho \"$as_me: WARNING: $ac_header:     check for missing prerequisite headers?\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation\" >&5\necho \"$as_me: WARNING: $ac_header: see the Autoconf documentation\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\necho \"$as_me: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the preprocessor's result\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence\" >&5\necho \"$as_me: WARNING: $ac_header: in the future, the compiler will take precedence\" >&2;}\n    (\n      cat <<\\_ASBOX\n## ------------------------------------------ ##\n## Report this to the AC_PACKAGE_NAME lists.  ##\n## ------------------------------------------ ##\n_ASBOX\n    ) |\n      sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  eval \"$as_ac_Header=\\$ac_header_preproc\"\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\n\nfi\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\nfi\n\ndone\n\n\n\nfor ac_header in syslog.h\ndo\nas_ac_Header=`echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\nelse\n  # Is the header compilable?\necho \"$as_me:$LINENO: checking $ac_header usability\" >&5\necho $ECHO_N \"checking $ac_header usability... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\n#include <$ac_header>\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_header_compiler=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_header_compiler=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_compiler\" >&5\necho \"${ECHO_T}$ac_header_compiler\" >&6\n\n# Is the header present?\necho \"$as_me:$LINENO: checking $ac_header presence\" >&5\necho $ECHO_N \"checking $ac_header presence... $ECHO_C\" >&6\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <$ac_header>\n_ACEOF\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_cpp conftest.$ac_ext\\\"\") >&5\n  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } >/dev/null; then\n  if test -s conftest.err; then\n    ac_cpp_err=$ac_c_preproc_warn_flag\n    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag\n  else\n    ac_cpp_err=\n  fi\nelse\n  ac_cpp_err=yes\nfi\nif test -z \"$ac_cpp_err\"; then\n  ac_header_preproc=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\necho \"$as_me:$LINENO: result: $ac_header_preproc\" >&5\necho \"${ECHO_T}$ac_header_preproc\" >&6\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in\n  yes:no: )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&5\necho \"$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the compiler's result\" >&2;}\n    ac_header_preproc=yes\n    ;;\n  no:yes:* )\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled\" >&5\necho \"$as_me: WARNING: $ac_header: present but cannot be compiled\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?\" >&5\necho \"$as_me: WARNING: $ac_header:     check for missing prerequisite headers?\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation\" >&5\necho \"$as_me: WARNING: $ac_header: see the Autoconf documentation\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\necho \"$as_me: WARNING: $ac_header:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result\" >&5\necho \"$as_me: WARNING: $ac_header: proceeding with the preprocessor's result\" >&2;}\n    { echo \"$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence\" >&5\necho \"$as_me: WARNING: $ac_header: in the future, the compiler will take precedence\" >&2;}\n    (\n      cat <<\\_ASBOX\n## ------------------------------------------ ##\n## Report this to the AC_PACKAGE_NAME lists.  ##\n## ------------------------------------------ ##\n_ASBOX\n    ) |\n      sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\necho \"$as_me:$LINENO: checking for $ac_header\" >&5\necho $ECHO_N \"checking for $ac_header... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_Header+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  eval \"$as_ac_Header=\\$ac_header_preproc\"\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_Header'}'`\" >&6\n\nfi\nif test `eval echo '${'$as_ac_Header'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\necho \"$as_me:$LINENO: checking for int8_t\" >&5\necho $ECHO_N \"checking for int8_t... $ECHO_C\" >&6\nif test \"${ac_cv_type_int8_t+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nif ((int8_t *) 0)\n  return 0;\nif (sizeof (int8_t))\n  return 0;\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_type_int8_t=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_type_int8_t=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_type_int8_t\" >&5\necho \"${ECHO_T}$ac_cv_type_int8_t\" >&6\nif test $ac_cv_type_int8_t = yes; then\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_INT8_T 1\n_ACEOF\n\n\nfi\necho \"$as_me:$LINENO: checking for uint8_t\" >&5\necho $ECHO_N \"checking for uint8_t... $ECHO_C\" >&6\nif test \"${ac_cv_type_uint8_t+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nif ((uint8_t *) 0)\n  return 0;\nif (sizeof (uint8_t))\n  return 0;\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_type_uint8_t=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_type_uint8_t=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_type_uint8_t\" >&5\necho \"${ECHO_T}$ac_cv_type_uint8_t\" >&6\nif test $ac_cv_type_uint8_t = yes; then\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_UINT8_T 1\n_ACEOF\n\n\nfi\necho \"$as_me:$LINENO: checking for int16_t\" >&5\necho $ECHO_N \"checking for int16_t... $ECHO_C\" >&6\nif test \"${ac_cv_type_int16_t+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nif ((int16_t *) 0)\n  return 0;\nif (sizeof (int16_t))\n  return 0;\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_type_int16_t=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_type_int16_t=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_type_int16_t\" >&5\necho \"${ECHO_T}$ac_cv_type_int16_t\" >&6\nif test $ac_cv_type_int16_t = yes; then\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_INT16_T 1\n_ACEOF\n\n\nfi\necho \"$as_me:$LINENO: checking for uint16_t\" >&5\necho $ECHO_N \"checking for uint16_t... $ECHO_C\" >&6\nif test \"${ac_cv_type_uint16_t+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nif ((uint16_t *) 0)\n  return 0;\nif (sizeof (uint16_t))\n  return 0;\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_type_uint16_t=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_type_uint16_t=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_type_uint16_t\" >&5\necho \"${ECHO_T}$ac_cv_type_uint16_t\" >&6\nif test $ac_cv_type_uint16_t = yes; then\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_UINT16_T 1\n_ACEOF\n\n\nfi\necho \"$as_me:$LINENO: checking for int32_t\" >&5\necho $ECHO_N \"checking for int32_t... $ECHO_C\" >&6\nif test \"${ac_cv_type_int32_t+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nif ((int32_t *) 0)\n  return 0;\nif (sizeof (int32_t))\n  return 0;\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_type_int32_t=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_type_int32_t=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_type_int32_t\" >&5\necho \"${ECHO_T}$ac_cv_type_int32_t\" >&6\nif test $ac_cv_type_int32_t = yes; then\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_INT32_T 1\n_ACEOF\n\n\nfi\necho \"$as_me:$LINENO: checking for uint32_t\" >&5\necho $ECHO_N \"checking for uint32_t... $ECHO_C\" >&6\nif test \"${ac_cv_type_uint32_t+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nif ((uint32_t *) 0)\n  return 0;\nif (sizeof (uint32_t))\n  return 0;\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_type_uint32_t=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_type_uint32_t=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_type_uint32_t\" >&5\necho \"${ECHO_T}$ac_cv_type_uint32_t\" >&6\nif test $ac_cv_type_uint32_t = yes; then\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_UINT32_T 1\n_ACEOF\n\n\nfi\necho \"$as_me:$LINENO: checking for uint64_t\" >&5\necho $ECHO_N \"checking for uint64_t... $ECHO_C\" >&6\nif test \"${ac_cv_type_uint64_t+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nif ((uint64_t *) 0)\n  return 0;\nif (sizeof (uint64_t))\n  return 0;\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_type_uint64_t=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_type_uint64_t=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_type_uint64_t\" >&5\necho \"${ECHO_T}$ac_cv_type_uint64_t\" >&6\nif test $ac_cv_type_uint64_t = yes; then\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_UINT64_T 1\n_ACEOF\n\n\nfi\n\necho \"$as_me:$LINENO: checking for unsigned long\" >&5\necho $ECHO_N \"checking for unsigned long... $ECHO_C\" >&6\nif test \"${ac_cv_type_unsigned_long+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nif ((unsigned long *) 0)\n  return 0;\nif (sizeof (unsigned long))\n  return 0;\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_type_unsigned_long=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_type_unsigned_long=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_type_unsigned_long\" >&5\necho \"${ECHO_T}$ac_cv_type_unsigned_long\" >&6\n\necho \"$as_me:$LINENO: checking size of unsigned long\" >&5\necho $ECHO_N \"checking size of unsigned long... $ECHO_C\" >&6\nif test \"${ac_cv_sizeof_unsigned_long+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  if test \"$ac_cv_type_unsigned_long\" = yes; then\n  # The cast to unsigned long works around a bug in the HP C Compiler\n  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects\n  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.\n  # This bug is HP SR number 8606223364.\n  if test \"$cross_compiling\" = yes; then\n  # Depending upon the size, compute the lo and hi bounds.\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nstatic int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) >= 0)];\ntest_array [0] = 0\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_lo=0 ac_mid=0\n  while :; do\n    cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nstatic int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) <= $ac_mid)];\ntest_array [0] = 0\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_hi=$ac_mid; break\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_lo=`expr $ac_mid + 1`\n\t\t    if test $ac_lo -le $ac_mid; then\n\t\t      ac_lo= ac_hi=\n\t\t      break\n\t\t    fi\n\t\t    ac_mid=`expr 2 '*' $ac_mid + 1`\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\n  done\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nstatic int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) < 0)];\ntest_array [0] = 0\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_hi=-1 ac_mid=-1\n  while :; do\n    cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nstatic int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) >= $ac_mid)];\ntest_array [0] = 0\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_lo=$ac_mid; break\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_hi=`expr '(' $ac_mid ')' - 1`\n\t\t       if test $ac_mid -le $ac_hi; then\n\t\t\t ac_lo= ac_hi=\n\t\t\t break\n\t\t       fi\n\t\t       ac_mid=`expr 2 '*' $ac_mid`\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\n  done\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_lo= ac_hi=\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\n# Binary search between lo and hi bounds.\nwhile test \"x$ac_lo\" != \"x$ac_hi\"; do\n  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nstatic int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) <= $ac_mid)];\ntest_array [0] = 0\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_hi=$ac_mid\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_lo=`expr '(' $ac_mid ')' + 1`\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\ndone\ncase $ac_lo in\n?*) ac_cv_sizeof_unsigned_long=$ac_lo;;\n'') { { echo \"$as_me:$LINENO: error: cannot compute sizeof (unsigned long), 77\nSee \\`config.log' for more details.\" >&5\necho \"$as_me: error: cannot compute sizeof (unsigned long), 77\nSee \\`config.log' for more details.\" >&2;}\n   { (exit 1); exit 1; }; } ;;\nesac\nelse\n  if test \"$cross_compiling\" = yes; then\n  { { echo \"$as_me:$LINENO: error: cannot run test program while cross compiling\nSee \\`config.log' for more details.\" >&5\necho \"$as_me: error: cannot run test program while cross compiling\nSee \\`config.log' for more details.\" >&2;}\n   { (exit 1); exit 1; }; }\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nlong longval () { return (long) (sizeof (unsigned long)); }\nunsigned long ulongval () { return (long) (sizeof (unsigned long)); }\n#include <stdio.h>\n#include <stdlib.h>\nint\nmain ()\n{\n\n  FILE *f = fopen (\"conftest.val\", \"w\");\n  if (! f)\n    exit (1);\n  if (((long) (sizeof (unsigned long))) < 0)\n    {\n      long i = longval ();\n      if (i != ((long) (sizeof (unsigned long))))\n\texit (1);\n      fprintf (f, \"%ld\\n\", i);\n    }\n  else\n    {\n      unsigned long i = ulongval ();\n      if (i != ((long) (sizeof (unsigned long))))\n\texit (1);\n      fprintf (f, \"%lu\\n\", i);\n    }\n  exit (ferror (f) || fclose (f) != 0);\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest$ac_exeext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_link\\\"\") >&5\n  (eval $ac_link) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_sizeof_unsigned_long=`cat conftest.val`\nelse\n  echo \"$as_me: program exited with status $ac_status\" >&5\necho \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n( exit $ac_status )\n{ { echo \"$as_me:$LINENO: error: cannot compute sizeof (unsigned long), 77\nSee \\`config.log' for more details.\" >&5\necho \"$as_me: error: cannot compute sizeof (unsigned long), 77\nSee \\`config.log' for more details.\" >&2;}\n   { (exit 1); exit 1; }; }\nfi\nrm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext\nfi\nfi\nrm -f conftest.val\nelse\n  ac_cv_sizeof_unsigned_long=0\nfi\nfi\necho \"$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_long\" >&5\necho \"${ECHO_T}$ac_cv_sizeof_unsigned_long\" >&6\ncat >>confdefs.h <<_ACEOF\n#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long\n_ACEOF\n\n\necho \"$as_me:$LINENO: checking for unsigned long long\" >&5\necho $ECHO_N \"checking for unsigned long long... $ECHO_C\" >&6\nif test \"${ac_cv_type_unsigned_long_long+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nif ((unsigned long long *) 0)\n  return 0;\nif (sizeof (unsigned long long))\n  return 0;\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_type_unsigned_long_long=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_type_unsigned_long_long=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_type_unsigned_long_long\" >&5\necho \"${ECHO_T}$ac_cv_type_unsigned_long_long\" >&6\n\necho \"$as_me:$LINENO: checking size of unsigned long long\" >&5\necho $ECHO_N \"checking size of unsigned long long... $ECHO_C\" >&6\nif test \"${ac_cv_sizeof_unsigned_long_long+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  if test \"$ac_cv_type_unsigned_long_long\" = yes; then\n  # The cast to unsigned long works around a bug in the HP C Compiler\n  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects\n  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.\n  # This bug is HP SR number 8606223364.\n  if test \"$cross_compiling\" = yes; then\n  # Depending upon the size, compute the lo and hi bounds.\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nstatic int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) >= 0)];\ntest_array [0] = 0\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_lo=0 ac_mid=0\n  while :; do\n    cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nstatic int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) <= $ac_mid)];\ntest_array [0] = 0\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_hi=$ac_mid; break\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_lo=`expr $ac_mid + 1`\n\t\t    if test $ac_lo -le $ac_mid; then\n\t\t      ac_lo= ac_hi=\n\t\t      break\n\t\t    fi\n\t\t    ac_mid=`expr 2 '*' $ac_mid + 1`\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\n  done\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nstatic int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) < 0)];\ntest_array [0] = 0\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_hi=-1 ac_mid=-1\n  while :; do\n    cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nstatic int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) >= $ac_mid)];\ntest_array [0] = 0\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_lo=$ac_mid; break\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_hi=`expr '(' $ac_mid ')' - 1`\n\t\t       if test $ac_mid -le $ac_hi; then\n\t\t\t ac_lo= ac_hi=\n\t\t\t break\n\t\t       fi\n\t\t       ac_mid=`expr 2 '*' $ac_mid`\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\n  done\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_lo= ac_hi=\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\n# Binary search between lo and hi bounds.\nwhile test \"x$ac_lo\" != \"x$ac_hi\"; do\n  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nstatic int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) <= $ac_mid)];\ntest_array [0] = 0\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_hi=$ac_mid\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_lo=`expr '(' $ac_mid ')' + 1`\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\ndone\ncase $ac_lo in\n?*) ac_cv_sizeof_unsigned_long_long=$ac_lo;;\n'') { { echo \"$as_me:$LINENO: error: cannot compute sizeof (unsigned long long), 77\nSee \\`config.log' for more details.\" >&5\necho \"$as_me: error: cannot compute sizeof (unsigned long long), 77\nSee \\`config.log' for more details.\" >&2;}\n   { (exit 1); exit 1; }; } ;;\nesac\nelse\n  if test \"$cross_compiling\" = yes; then\n  { { echo \"$as_me:$LINENO: error: cannot run test program while cross compiling\nSee \\`config.log' for more details.\" >&5\necho \"$as_me: error: cannot run test program while cross compiling\nSee \\`config.log' for more details.\" >&2;}\n   { (exit 1); exit 1; }; }\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nlong longval () { return (long) (sizeof (unsigned long long)); }\nunsigned long ulongval () { return (long) (sizeof (unsigned long long)); }\n#include <stdio.h>\n#include <stdlib.h>\nint\nmain ()\n{\n\n  FILE *f = fopen (\"conftest.val\", \"w\");\n  if (! f)\n    exit (1);\n  if (((long) (sizeof (unsigned long long))) < 0)\n    {\n      long i = longval ();\n      if (i != ((long) (sizeof (unsigned long long))))\n\texit (1);\n      fprintf (f, \"%ld\\n\", i);\n    }\n  else\n    {\n      unsigned long i = ulongval ();\n      if (i != ((long) (sizeof (unsigned long long))))\n\texit (1);\n      fprintf (f, \"%lu\\n\", i);\n    }\n  exit (ferror (f) || fclose (f) != 0);\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest$ac_exeext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_link\\\"\") >&5\n  (eval $ac_link) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_sizeof_unsigned_long_long=`cat conftest.val`\nelse\n  echo \"$as_me: program exited with status $ac_status\" >&5\necho \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n( exit $ac_status )\n{ { echo \"$as_me:$LINENO: error: cannot compute sizeof (unsigned long long), 77\nSee \\`config.log' for more details.\" >&5\necho \"$as_me: error: cannot compute sizeof (unsigned long long), 77\nSee \\`config.log' for more details.\" >&2;}\n   { (exit 1); exit 1; }; }\nfi\nrm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext\nfi\nfi\nrm -f conftest.val\nelse\n  ac_cv_sizeof_unsigned_long_long=0\nfi\nfi\necho \"$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_long_long\" >&5\necho \"${ECHO_T}$ac_cv_sizeof_unsigned_long_long\" >&6\ncat >>confdefs.h <<_ACEOF\n#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long\n_ACEOF\n\n\n\necho \"$as_me:$LINENO: checking for an ANSI C-conforming const\" >&5\necho $ECHO_N \"checking for an ANSI C-conforming const... $ECHO_C\" >&6\nif test \"${ac_cv_c_const+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n/* FIXME: Include the comments suggested by Paul. */\n#ifndef __cplusplus\n  /* Ultrix mips cc rejects this.  */\n  typedef int charset[2];\n  const charset x;\n  /* SunOS 4.1.1 cc rejects this.  */\n  char const *const *ccp;\n  char **p;\n  /* NEC SVR4.0.2 mips cc rejects this.  */\n  struct point {int x, y;};\n  static struct point const zero = {0,0};\n  /* AIX XL C 1.02.0.0 rejects this.\n     It does not let you subtract one const X* pointer from another in\n     an arm of an if-expression whose if-part is not a constant\n     expression */\n  const char *g = \"string\";\n  ccp = &g + (g ? g-g : 0);\n  /* HPUX 7.0 cc rejects these. */\n  ++ccp;\n  p = (char**) ccp;\n  ccp = (char const *const *) p;\n  { /* SCO 3.2v4 cc rejects this.  */\n    char *t;\n    char const *s = 0 ? (char *) 0 : (char const *) 0;\n\n    *t++ = 0;\n  }\n  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */\n    int x[] = {25, 17};\n    const int *foo = &x[0];\n    ++foo;\n  }\n  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */\n    typedef const int *iptr;\n    iptr p = 0;\n    ++p;\n  }\n  { /* AIX XL C 1.02.0.0 rejects this saying\n       \"k.c\", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */\n    struct s { int j; const int *ap[3]; };\n    struct s *b; b->j = 5;\n  }\n  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */\n    const int foo = 10;\n  }\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_c_const=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_c_const=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_c_const\" >&5\necho \"${ECHO_T}$ac_cv_c_const\" >&6\nif test $ac_cv_c_const = no; then\n\ncat >>confdefs.h <<\\_ACEOF\n#define const\n_ACEOF\n\nfi\n\necho \"$as_me:$LINENO: checking for inline\" >&5\necho $ECHO_N \"checking for inline... $ECHO_C\" >&6\nif test \"${ac_cv_c_inline+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  ac_cv_c_inline=no\nfor ac_kw in inline __inline__ __inline; do\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#ifndef __cplusplus\ntypedef int foo_t;\nstatic $ac_kw foo_t static_foo () {return 0; }\n$ac_kw foo_t foo () {return 0; }\n#endif\n\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_c_inline=$ac_kw; break\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\ndone\n\nfi\necho \"$as_me:$LINENO: result: $ac_cv_c_inline\" >&5\necho \"${ECHO_T}$ac_cv_c_inline\" >&6\n\n\ncase $ac_cv_c_inline in\n  inline | yes) ;;\n  *)\n    case $ac_cv_c_inline in\n      no) ac_val=;;\n      *) ac_val=$ac_cv_c_inline;;\n    esac\n    cat >>confdefs.h <<_ACEOF\n#ifndef __cplusplus\n#define inline $ac_val\n#endif\n_ACEOF\n    ;;\nesac\n\necho \"$as_me:$LINENO: checking for size_t\" >&5\necho $ECHO_N \"checking for size_t... $ECHO_C\" >&6\nif test \"${ac_cv_type_size_t+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\nif ((size_t *) 0)\n  return 0;\nif (sizeof (size_t))\n  return 0;\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_type_size_t=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_type_size_t=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_type_size_t\" >&5\necho \"${ECHO_T}$ac_cv_type_size_t\" >&6\nif test $ac_cv_type_size_t = yes; then\n  :\nelse\n\ncat >>confdefs.h <<_ACEOF\n#define size_t unsigned\n_ACEOF\n\nfi\n\n\n\n\n\nfor ac_func in socket inet_aton usleep\ndo\nas_ac_var=`echo \"ac_cv_func_$ac_func\" | $as_tr_sh`\necho \"$as_me:$LINENO: checking for $ac_func\" >&5\necho $ECHO_N \"checking for $ac_func... $ECHO_C\" >&6\nif eval \"test \\\"\\${$as_ac_var+set}\\\" = set\"; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.\n   For example, HP-UX 11i <limits.h> declares gettimeofday.  */\n#define $ac_func innocuous_$ac_func\n\n/* System header to define __stub macros and hopefully few prototypes,\n    which can conflict with char $ac_func (); below.\n    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n    <limits.h> exists even on freestanding compilers.  */\n\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\n#undef $ac_func\n\n/* Override any gcc2 internal prototype to avoid an error.  */\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n/* We use char because int might match the return type of a gcc2\n   builtin and then its argument prototype would still apply.  */\nchar $ac_func ();\n/* The GNU C library defines this for functions which it implements\n    to always fail with ENOSYS.  Some functions are actually named\n    something starting with __ and the normal name is an alias.  */\n#if defined (__stub_$ac_func) || defined (__stub___$ac_func)\nchoke me\n#else\nchar (*f) () = $ac_func;\n#endif\n#ifdef __cplusplus\n}\n#endif\n\nint\nmain ()\n{\nreturn f != $ac_func;\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext conftest$ac_exeext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_link\\\"\") >&5\n  (eval $ac_link) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest$ac_exeext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  eval \"$as_ac_var=yes\"\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\neval \"$as_ac_var=no\"\nfi\nrm -f conftest.err conftest.$ac_objext \\\n      conftest$ac_exeext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`\" >&5\necho \"${ECHO_T}`eval echo '${'$as_ac_var'}'`\" >&6\nif test `eval echo '${'$as_ac_var'}'` = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define `echo \"HAVE_$ac_func\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\ndone\n\n\nif test \"x$ac_cv_func_socket\" = \"xno\"; then\n\necho \"$as_me:$LINENO: checking for socket in -lsocket\" >&5\necho $ECHO_N \"checking for socket in -lsocket... $ECHO_C\" >&6\nif test \"${ac_cv_lib_socket_socket+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lsocket  $LIBS\"\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n\n/* Override any gcc2 internal prototype to avoid an error.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\n/* We use char because int might match the return type of a gcc2\n   builtin and then its argument prototype would still apply.  */\nchar socket ();\nint\nmain ()\n{\nsocket ();\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext conftest$ac_exeext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_link\\\"\") >&5\n  (eval $ac_link) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest$ac_exeext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_lib_socket_socket=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_lib_socket_socket=no\nfi\nrm -f conftest.err conftest.$ac_objext \\\n      conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\necho \"$as_me:$LINENO: result: $ac_cv_lib_socket_socket\" >&5\necho \"${ECHO_T}$ac_cv_lib_socket_socket\" >&6\nif test $ac_cv_lib_socket_socket = yes; then\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBSOCKET 1\n_ACEOF\n\n  LIBS=\"-lsocket $LIBS\"\n\nfi\n\n  echo \"$as_me:$LINENO: checking for socket in -lwsock32\" >&5\necho $ECHO_N \"checking for socket in -lwsock32... $ECHO_C\" >&6\n  SAVELIBS=\"$LIBS\"\n  LIBS=\"$LIBS -lwsock32\"\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n\n#include <winsock2.h>\n\nint\nmain ()\n{\n\nsocket(0, 0, 0);\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext conftest$ac_exeext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_link\\\"\") >&5\n  (eval $ac_link) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest$ac_exeext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_func_socket=yes\n    echo \"$as_me:$LINENO: result: yes\" >&5\necho \"${ECHO_T}yes\" >&6\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nLIBS=\"$SAVELIBS\"\n    echo \"$as_me:$LINENO: result: no\" >&5\necho \"${ECHO_T}no\" >&6\nfi\nrm -f conftest.err conftest.$ac_objext \\\n      conftest$ac_exeext conftest.$ac_ext\nfi\n\necho \"$as_me:$LINENO: checking whether byte ordering is bigendian\" >&5\necho $ECHO_N \"checking whether byte ordering is bigendian... $ECHO_C\" >&6\nif test \"${ac_cv_c_bigendian+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  # See if sys/param.h defines the BYTE_ORDER macro.\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <sys/types.h>\n#include <sys/param.h>\n\nint\nmain ()\n{\n#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN\n bogus endian macros\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  # It does; now see whether it defined to BIG_ENDIAN or not.\ncat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\n#include <sys/types.h>\n#include <sys/param.h>\n\nint\nmain ()\n{\n#if BYTE_ORDER != BIG_ENDIAN\n not big endian\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_c_bigendian=yes\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nac_cv_c_bigendian=no\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n# It does not; compile a test program.\nif test \"$cross_compiling\" = yes; then\n  # try to guess the endianness by grepping values into an object file\n  ac_cv_c_bigendian=unknown\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\nshort ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };\nshort ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };\nvoid _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }\nshort ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };\nshort ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };\nvoid _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }\nint\nmain ()\n{\n _ascii (); _ebcdic ();\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.$ac_objext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_compile\\\"\") >&5\n  (eval $ac_compile) 2>conftest.er1\n  ac_status=$?\n  grep -v '^ *+' conftest.er1 >conftest.err\n  rm -f conftest.er1\n  cat conftest.err >&5\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } &&\n\t { ac_try='test -z \"$ac_c_werror_flag\"\n\t\t\t || test ! -s conftest.err'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; } &&\n\t { ac_try='test -s conftest.$ac_objext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then\n  ac_cv_c_bigendian=yes\nfi\nif grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then\n  if test \"$ac_cv_c_bigendian\" = unknown; then\n    ac_cv_c_bigendian=no\n  else\n    # finding both strings is unlikely to happen, but who knows?\n    ac_cv_c_bigendian=unknown\n  fi\nfi\nelse\n  echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nelse\n  cat >conftest.$ac_ext <<_ACEOF\n/* confdefs.h.  */\n_ACEOF\ncat confdefs.h >>conftest.$ac_ext\ncat >>conftest.$ac_ext <<_ACEOF\n/* end confdefs.h.  */\nint\nmain ()\n{\n  /* Are we little or big endian?  From Harbison&Steele.  */\n  union\n  {\n    long l;\n    char c[sizeof (long)];\n  } u;\n  u.l = 1;\n  exit (u.c[sizeof (long) - 1] == 1);\n}\n_ACEOF\nrm -f conftest$ac_exeext\nif { (eval echo \"$as_me:$LINENO: \\\"$ac_link\\\"\") >&5\n  (eval $ac_link) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'\n  { (eval echo \"$as_me:$LINENO: \\\"$ac_try\\\"\") >&5\n  (eval $ac_try) 2>&5\n  ac_status=$?\n  echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n  (exit $ac_status); }; }; then\n  ac_cv_c_bigendian=no\nelse\n  echo \"$as_me: program exited with status $ac_status\" >&5\necho \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n( exit $ac_status )\nac_cv_c_bigendian=yes\nfi\nrm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext\nfi\nfi\nrm -f conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\necho \"$as_me:$LINENO: result: $ac_cv_c_bigendian\" >&5\necho \"${ECHO_T}$ac_cv_c_bigendian\" >&6\ncase $ac_cv_c_bigendian in\n  yes)\n\ncat >>confdefs.h <<\\_ACEOF\n#define WORDS_BIGENDIAN 1\n_ACEOF\n ;;\n  no)\n     ;;\n  *)\n    { { echo \"$as_me:$LINENO: error: unknown endianness\npresetting ac_cv_c_bigendian=no (or yes) will help\" >&5\necho \"$as_me: error: unknown endianness\npresetting ac_cv_c_bigendian=no (or yes) will help\" >&2;}\n   { (exit 1); exit 1; }; } ;;\nesac\n\n\n# Make sure we can run config.sub.\n$ac_config_sub sun4 >/dev/null 2>&1 ||\n  { { echo \"$as_me:$LINENO: error: cannot run $ac_config_sub\" >&5\necho \"$as_me: error: cannot run $ac_config_sub\" >&2;}\n   { (exit 1); exit 1; }; }\n\necho \"$as_me:$LINENO: checking build system type\" >&5\necho $ECHO_N \"checking build system type... $ECHO_C\" >&6\nif test \"${ac_cv_build+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  ac_cv_build_alias=$build_alias\ntest -z \"$ac_cv_build_alias\" &&\n  ac_cv_build_alias=`$ac_config_guess`\ntest -z \"$ac_cv_build_alias\" &&\n  { { echo \"$as_me:$LINENO: error: cannot guess build type; you must specify one\" >&5\necho \"$as_me: error: cannot guess build type; you must specify one\" >&2;}\n   { (exit 1); exit 1; }; }\nac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||\n  { { echo \"$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed\" >&5\necho \"$as_me: error: $ac_config_sub $ac_cv_build_alias failed\" >&2;}\n   { (exit 1); exit 1; }; }\n\nfi\necho \"$as_me:$LINENO: result: $ac_cv_build\" >&5\necho \"${ECHO_T}$ac_cv_build\" >&6\nbuild=$ac_cv_build\nbuild_cpu=`echo $ac_cv_build | sed 's/^\\([^-]*\\)-\\([^-]*\\)-\\(.*\\)$/\\1/'`\nbuild_vendor=`echo $ac_cv_build | sed 's/^\\([^-]*\\)-\\([^-]*\\)-\\(.*\\)$/\\2/'`\nbuild_os=`echo $ac_cv_build | sed 's/^\\([^-]*\\)-\\([^-]*\\)-\\(.*\\)$/\\3/'`\n\n\necho \"$as_me:$LINENO: checking host system type\" >&5\necho $ECHO_N \"checking host system type... $ECHO_C\" >&6\nif test \"${ac_cv_host+set}\" = set; then\n  echo $ECHO_N \"(cached) $ECHO_C\" >&6\nelse\n  ac_cv_host_alias=$host_alias\ntest -z \"$ac_cv_host_alias\" &&\n  ac_cv_host_alias=$ac_cv_build_alias\nac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||\n  { { echo \"$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed\" >&5\necho \"$as_me: error: $ac_config_sub $ac_cv_host_alias failed\" >&2;}\n   { (exit 1); exit 1; }; }\n\nfi\necho \"$as_me:$LINENO: result: $ac_cv_host\" >&5\necho \"${ECHO_T}$ac_cv_host\" >&6\nhost=$ac_cv_host\nhost_cpu=`echo $ac_cv_host | sed 's/^\\([^-]*\\)-\\([^-]*\\)-\\(.*\\)$/\\1/'`\nhost_vendor=`echo $ac_cv_host | sed 's/^\\([^-]*\\)-\\([^-]*\\)-\\(.*\\)$/\\2/'`\nhost_os=`echo $ac_cv_host | sed 's/^\\([^-]*\\)-\\([^-]*\\)-\\(.*\\)$/\\3/'`\n\n\n\ncase $host_cpu in\n     i*86 )\n\ncat >>confdefs.h <<\\_ACEOF\n#define CPU_CISC 1\n_ACEOF\n\n\ncat >>confdefs.h <<\\_ACEOF\n#define HAVE_X86 1\n_ACEOF\n;;\n\t* )\n\t# CPU_RISC is only supported for big endian machines.\n\tif test \"$ac_cv_c_bigendian\" = \"yes\"; then\n\ncat >>confdefs.h <<\\_ACEOF\n#define CPU_RISC 1\n_ACEOF\n\n\telse\n\t   cat >>confdefs.h <<\\_ACEOF\n#define CPU_CISC 1\n_ACEOF\n\n\tfi\n\t;;\nesac\n\ncase $host_os in\n  *cygwin*|*mingw* )\n\t      EXE=.exe;;\n         * )  EXE=\"\";;\nesac\n\n   # define executable suffix; this is needed for `make clean'\n\necho \"$as_me:$LINENO: checking whether to compile in debugging\" >&5\necho $ECHO_N \"checking whether to compile in debugging... $ECHO_C\" >&6\n# Check whether --enable-debug or --disable-debug was given.\nif test \"${enable_debug+set}\" = set; then\n  enableval=\"$enable_debug\"\n\nelse\n  enable_debug=yes\nfi;\nif test \"$enable_debug\" = \"yes\"; then\n\ncat >>confdefs.h <<\\_ACEOF\n#define ENABLE_DEBUGGING 1\n_ACEOF\n\nfi\necho \"$as_me:$LINENO: result: $enable_debug\" >&5\necho \"${ECHO_T}$enable_debug\" >&6\n\necho \"$as_me:$LINENO: checking whether to use ISMAcryp code\" >&5\necho $ECHO_N \"checking whether to use ISMAcryp code... $ECHO_C\" >&6\n# Check whether --enable-generic-aesicm or --disable-generic-aesicm was given.\nif test \"${enable_generic_aesicm+set}\" = set; then\n  enableval=\"$enable_generic_aesicm\"\n\nelse\n  enable_generic_aesicm=no\nfi;\nif test \"$enable_generic_aesicm\" = \"yes\"; then\n\ncat >>confdefs.h <<\\_ACEOF\n#define GENERIC_AESICM 1\n_ACEOF\n\nfi\necho \"$as_me:$LINENO: result: $enable_generic_aesicm\" >&5\necho \"${ECHO_T}$enable_generic_aesicm\" >&6\n\necho \"$as_me:$LINENO: checking whether to use syslog for error reporting\" >&5\necho $ECHO_N \"checking whether to use syslog for error reporting... $ECHO_C\" >&6\n# Check whether --enable-syslog or --disable-syslog was given.\nif test \"${enable_syslog+set}\" = set; then\n  enableval=\"$enable_syslog\"\n\nelse\n  enable_syslog=no\nfi;\nif test \"$enable_syslog\" = \"yes\"; then\n\ncat >>confdefs.h <<\\_ACEOF\n#define USE_SYSLOG 1\n_ACEOF\n\nfi\necho \"$as_me:$LINENO: result: $enable_syslog\" >&5\necho \"${ECHO_T}$enable_syslog\" >&6\n\necho \"$as_me:$LINENO: checking whether to use stdout for error reporting\" >&5\necho $ECHO_N \"checking whether to use stdout for error reporting... $ECHO_C\" >&6\n# Check whether --enable-stdout or --disable-stdout was given.\nif test \"${enable_stdout+set}\" = set; then\n  enableval=\"$enable_stdout\"\n\nelse\n  enable_stdout=yes\nfi;\nif test \"$enable_stdout\" = \"yes\"; then\n\ncat >>confdefs.h <<\\_ACEOF\n#define ERR_REPORTING_STDOUT 1\n_ACEOF\n\nfi\necho \"$as_me:$LINENO: result: $enable_stdout\" >&5\necho \"${ECHO_T}$enable_stdout\" >&6\n\necho \"$as_me:$LINENO: checking whether to use /dev/console for error reporting\" >&5\necho $ECHO_N \"checking whether to use /dev/console for error reporting... $ECHO_C\" >&6\n# Check whether --enable-console or --disable-console was given.\nif test \"${enable_console+set}\" = set; then\n  enableval=\"$enable_console\"\n\nelse\n  enable_console=no\nfi;\nif test \"$enable_console\" = \"yes\"; then\n\ncat >>confdefs.h <<\\_ACEOF\n#define USE_ERR_REPORTING_FILE 1\n_ACEOF\n\n\ncat >>confdefs.h <<\\_ACEOF\n#define ERR_REPORTING_FILE \"/dev/console\"\n_ACEOF\n\nfi\necho \"$as_me:$LINENO: result: $enable_console\" >&5\necho \"${ECHO_T}$enable_console\" >&6\n\necho \"$as_me:$LINENO: checking whether to use GDOI key management\" >&5\necho $ECHO_N \"checking whether to use GDOI key management... $ECHO_C\" >&6\n# Check whether --enable-gdoi or --disable-gdoi was given.\nif test \"${enable_gdoi+set}\" = set; then\n  enableval=\"$enable_gdoi\"\n\nelse\n  enable_gdoi=no\nfi;\nif test \"$enable_gdoi\" = \"yes\"; then\n\ncat >>confdefs.h <<\\_ACEOF\n#define SRTP_GDOI 1\n_ACEOF\n\n   GDOI_OBJS=gdoi/srtp+gdoi.o\n\nfi\necho \"$as_me:$LINENO: result: $enable_gdoi\" >&5\necho \"${ECHO_T}$enable_gdoi\" >&6\n\n          ac_config_headers=\"$ac_config_headers crypto/include/config.h:config_in.h\"\n\n\n                              ac_config_files=\"$ac_config_files Makefile crypto/Makefile doc/Makefile\"\ncat >confcache <<\\_ACEOF\n# This file is a shell script that caches the results of configure\n# tests run on this system so they can be shared between configure\n# scripts and configure runs, see configure's option --config-cache.\n# It is not useful on other systems.  If it contains results you don't\n# want to keep, you may remove or edit it.\n#\n# config.status only pays attention to the cache file if you give it\n# the --recheck option to rerun configure.\n#\n# `ac_cv_env_foo' variables (set or unset) will be overridden when\n# loading this file, other *unset* `ac_cv_foo' will be assigned the\n# following values.\n\n_ACEOF\n\n# The following way of writing the cache mishandles newlines in values,\n# but we know of no workaround that is simple, portable, and efficient.\n# So, don't put newlines in cache variables' values.\n# Ultrix sh set writes to stderr and can't be redirected directly,\n# and sets the high bit in the cache file unless we assign to the vars.\n{\n  (set) 2>&1 |\n    case `(ac_space=' '; set | grep ac_space) 2>&1` in\n    *ac_space=\\ *)\n      # `set' does not quote correctly, so add quotes (double-quote\n      # substitution turns \\\\\\\\ into \\\\, and sed turns \\\\ into \\).\n      sed -n \\\n\t\"s/'/'\\\\\\\\''/g;\n\t  s/^\\\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\\\)=\\\\(.*\\\\)/\\\\1='\\\\2'/p\"\n      ;;\n    *)\n      # `set' quotes correctly as required by POSIX, so do not add quotes.\n      sed -n \\\n\t\"s/^\\\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\\\)=\\\\(.*\\\\)/\\\\1=\\\\2/p\"\n      ;;\n    esac;\n} |\n  sed '\n     t clear\n     : clear\n     s/^\\([^=]*\\)=\\(.*[{}].*\\)$/test \"${\\1+set}\" = set || &/\n     t end\n     /^ac_cv_env/!s/^\\([^=]*\\)=\\(.*\\)$/\\1=${\\1=\\2}/\n     : end' >>confcache\nif diff $cache_file confcache >/dev/null 2>&1; then :; else\n  if test -w $cache_file; then\n    test \"x$cache_file\" != \"x/dev/null\" && echo \"updating cache $cache_file\"\n    cat confcache >$cache_file\n  else\n    echo \"not updating unwritable cache $cache_file\"\n  fi\nfi\nrm -f confcache\n\ntest \"x$prefix\" = xNONE && prefix=$ac_default_prefix\n# Let make expand exec_prefix.\ntest \"x$exec_prefix\" = xNONE && exec_prefix='${prefix}'\n\n# VPATH may cause trouble with some makes, so we remove $(srcdir),\n# ${srcdir} and @srcdir@ from VPATH if srcdir is \".\", strip leading and\n# trailing colons and then remove the whole line if VPATH becomes empty\n# (actually we leave an empty line to preserve line numbers).\nif test \"x$srcdir\" = x.; then\n  ac_vpsub='/^[\t ]*VPATH[\t ]*=/{\ns/:*\\$(srcdir):*/:/;\ns/:*\\${srcdir}:*/:/;\ns/:*@srcdir@:*/:/;\ns/^\\([^=]*=[\t ]*\\):*/\\1/;\ns/:*$//;\ns/^[^=]*=[\t ]*$//;\n}'\nfi\n\nDEFS=-DHAVE_CONFIG_H\n\nac_libobjs=\nac_ltlibobjs=\nfor ac_i in : $LIBOBJS; do test \"x$ac_i\" = x: && continue\n  # 1. Remove the extension, and $U if already installed.\n  ac_i=`echo \"$ac_i\" |\n\t sed 's/\\$U\\././;s/\\.o$//;s/\\.obj$//'`\n  # 2. Add them.\n  ac_libobjs=\"$ac_libobjs $ac_i\\$U.$ac_objext\"\n  ac_ltlibobjs=\"$ac_ltlibobjs $ac_i\"'$U.lo'\ndone\nLIBOBJS=$ac_libobjs\n\nLTLIBOBJS=$ac_ltlibobjs\n\n\n\n: ${CONFIG_STATUS=./config.status}\nac_clean_files_save=$ac_clean_files\nac_clean_files=\"$ac_clean_files $CONFIG_STATUS\"\n{ echo \"$as_me:$LINENO: creating $CONFIG_STATUS\" >&5\necho \"$as_me: creating $CONFIG_STATUS\" >&6;}\ncat >$CONFIG_STATUS <<_ACEOF\n#! $SHELL\n# Generated by $as_me.\n# Run this file to recreate the current configuration.\n# Compiler output produced by configure, useful for debugging\n# configure, is in config.log if it exists.\n\ndebug=false\nac_cs_recheck=false\nac_cs_silent=false\nSHELL=\\${CONFIG_SHELL-$SHELL}\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF\n## --------------------- ##\n## M4sh Initialization.  ##\n## --------------------- ##\n\n# Be Bourne compatible\nif test -n \"${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then\n  emulate sh\n  NULLCMD=:\n  # Zsh 3.x and 4.x performs word splitting on ${1+\"$@\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '${1+\"$@\"}'='\"$@\"'\nelif test -n \"${BASH_VERSION+set}\" && (set -o posix) >/dev/null 2>&1; then\n  set -o posix\nfi\nDUALCASE=1; export DUALCASE # for MKS sh\n\n# Support unset when possible.\nif ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then\n  as_unset=unset\nelse\n  as_unset=false\nfi\n\n\n# Work around bugs in pre-3.0 UWIN ksh.\n$as_unset ENV MAIL MAILPATH\nPS1='$ '\nPS2='> '\nPS4='+ '\n\n# NLS nuisances.\nfor as_var in \\\n  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \\\n  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \\\n  LC_TELEPHONE LC_TIME\ndo\n  if (set +x; test -z \"`(eval $as_var=C; export $as_var) 2>&1`\"); then\n    eval $as_var=C; export $as_var\n  else\n    $as_unset $as_var\n  fi\ndone\n\n# Required to use basename.\nif expr a : '\\(a\\)' >/dev/null 2>&1; then\n  as_expr=expr\nelse\n  as_expr=false\nfi\n\nif (basename /) >/dev/null 2>&1 && test \"X`basename / 2>&1`\" = \"X/\"; then\n  as_basename=basename\nelse\n  as_basename=false\nfi\n\n\n# Name of the executable.\nas_me=`$as_basename \"$0\" ||\n$as_expr X/\"$0\" : '.*/\\([^/][^/]*\\)/*$' \\| \\\n\t X\"$0\" : 'X\\(//\\)$' \\| \\\n\t X\"$0\" : 'X\\(/\\)$' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X/\"$0\" |\n    sed '/^.*\\/\\([^/][^/]*\\)\\/*$/{ s//\\1/; q; }\n  \t  /^X\\/\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\/\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n\n\n# PATH needs CR, and LINENO needs CR and PATH.\n# Avoid depending upon Character Ranges.\nas_cr_letters='abcdefghijklmnopqrstuvwxyz'\nas_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nas_cr_Letters=$as_cr_letters$as_cr_LETTERS\nas_cr_digits='0123456789'\nas_cr_alnum=$as_cr_Letters$as_cr_digits\n\n# The user is always right.\nif test \"${PATH_SEPARATOR+set}\" != set; then\n  echo \"#! /bin/sh\" >conf$$.sh\n  echo  \"exit 0\"   >>conf$$.sh\n  chmod +x conf$$.sh\n  if (PATH=\"/nonexistent;.\"; conf$$.sh) >/dev/null 2>&1; then\n    PATH_SEPARATOR=';'\n  else\n    PATH_SEPARATOR=:\n  fi\n  rm -f conf$$.sh\nfi\n\n\n  as_lineno_1=$LINENO\n  as_lineno_2=$LINENO\n  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`\n  test \"x$as_lineno_1\" != \"x$as_lineno_2\" &&\n  test \"x$as_lineno_3\"  = \"x$as_lineno_2\"  || {\n  # Find who we are.  Look in the path if we contain no path at all\n  # relative or not.\n  case $0 in\n    *[\\\\/]* ) as_myself=$0 ;;\n    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  test -r \"$as_dir/$0\" && as_myself=$as_dir/$0 && break\ndone\n\n       ;;\n  esac\n  # We did not find ourselves, most probably we were run as `sh COMMAND'\n  # in which case we are not to be found in the path.\n  if test \"x$as_myself\" = x; then\n    as_myself=$0\n  fi\n  if test ! -f \"$as_myself\"; then\n    { { echo \"$as_me:$LINENO: error: cannot find myself; rerun with an absolute path\" >&5\necho \"$as_me: error: cannot find myself; rerun with an absolute path\" >&2;}\n   { (exit 1); exit 1; }; }\n  fi\n  case $CONFIG_SHELL in\n  '')\n    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  for as_base in sh bash ksh sh5; do\n\t case $as_dir in\n\t /*)\n\t   if (\"$as_dir/$as_base\" -c '\n  as_lineno_1=$LINENO\n  as_lineno_2=$LINENO\n  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`\n  test \"x$as_lineno_1\" != \"x$as_lineno_2\" &&\n  test \"x$as_lineno_3\"  = \"x$as_lineno_2\" ') 2>/dev/null; then\n\t     $as_unset BASH_ENV || test \"${BASH_ENV+set}\" != set || { BASH_ENV=; export BASH_ENV; }\n\t     $as_unset ENV || test \"${ENV+set}\" != set || { ENV=; export ENV; }\n\t     CONFIG_SHELL=$as_dir/$as_base\n\t     export CONFIG_SHELL\n\t     exec \"$CONFIG_SHELL\" \"$0\" ${1+\"$@\"}\n\t   fi;;\n\t esac\n       done\ndone\n;;\n  esac\n\n  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO\n  # uniformly replaced by the line number.  The first 'sed' inserts a\n  # line-number line before each line; the second 'sed' does the real\n  # work.  The second script uses 'N' to pair each line-number line\n  # with the numbered line, and appends trailing '-' during\n  # substitution so that $LINENO is not a special case at line end.\n  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the\n  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)\n  sed '=' <$as_myself |\n    sed '\n      N\n      s,$,-,\n      : loop\n      s,^\\(['$as_cr_digits']*\\)\\(.*\\)[$]LINENO\\([^'$as_cr_alnum'_]\\),\\1\\2\\1\\3,\n      t loop\n      s,-$,,\n      s,^['$as_cr_digits']*\\n,,\n    ' >$as_me.lineno &&\n  chmod +x $as_me.lineno ||\n    { { echo \"$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell\" >&5\necho \"$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell\" >&2;}\n   { (exit 1); exit 1; }; }\n\n  # Don't try to exec as it changes $[0], causing all sort of problems\n  # (the dirname of $[0] is not the place where we might find the\n  # original and so on.  Autoconf is especially sensible to this).\n  . ./$as_me.lineno\n  # Exit status is that of the last command.\n  exit\n}\n\n\ncase `echo \"testing\\c\"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in\n  *c*,-n*) ECHO_N= ECHO_C='\n' ECHO_T='\t' ;;\n  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;\n  *)       ECHO_N= ECHO_C='\\c' ECHO_T= ;;\nesac\n\nif expr a : '\\(a\\)' >/dev/null 2>&1; then\n  as_expr=expr\nelse\n  as_expr=false\nfi\n\nrm -f conf$$ conf$$.exe conf$$.file\necho >conf$$.file\nif ln -s conf$$.file conf$$ 2>/dev/null; then\n  # We could just check for DJGPP; but this test a) works b) is more generic\n  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).\n  if test -f conf$$.exe; then\n    # Don't use ln at all; we don't have any links\n    as_ln_s='cp -p'\n  else\n    as_ln_s='ln -s'\n  fi\nelif ln conf$$.file conf$$ 2>/dev/null; then\n  as_ln_s=ln\nelse\n  as_ln_s='cp -p'\nfi\nrm -f conf$$ conf$$.exe conf$$.file\n\nif mkdir -p . 2>/dev/null; then\n  as_mkdir_p=:\nelse\n  test -d ./-p && rmdir ./-p\n  as_mkdir_p=false\nfi\n\nas_executable_p=\"test -f\"\n\n# Sed expression to map a string onto a valid CPP name.\nas_tr_cpp=\"eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'\"\n\n# Sed expression to map a string onto a valid variable name.\nas_tr_sh=\"eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'\"\n\n\n# IFS\n# We need space, tab and new line, in precisely that order.\nas_nl='\n'\nIFS=\" \t$as_nl\"\n\n# CDPATH.\n$as_unset CDPATH\n\nexec 6>&1\n\n# Open the log real soon, to keep \\$[0] and so on meaningful, and to\n# report actual input values of CONFIG_FILES etc. instead of their\n# values after options handling.  Logging --version etc. is OK.\nexec 5>>config.log\n{\n  echo\n  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX\n## Running $as_me. ##\n_ASBOX\n} >&5\ncat >&5 <<_CSEOF\n\nThis file was extended by $as_me, which was\ngenerated by GNU Autoconf 2.59.  Invocation command line was\n\n  CONFIG_FILES    = $CONFIG_FILES\n  CONFIG_HEADERS  = $CONFIG_HEADERS\n  CONFIG_LINKS    = $CONFIG_LINKS\n  CONFIG_COMMANDS = $CONFIG_COMMANDS\n  $ $0 $@\n\n_CSEOF\necho \"on `(hostname || uname -n) 2>/dev/null | sed 1q`\" >&5\necho >&5\n_ACEOF\n\n# Files that config.status was made for.\nif test -n \"$ac_config_files\"; then\n  echo \"config_files=\\\"$ac_config_files\\\"\" >>$CONFIG_STATUS\nfi\n\nif test -n \"$ac_config_headers\"; then\n  echo \"config_headers=\\\"$ac_config_headers\\\"\" >>$CONFIG_STATUS\nfi\n\nif test -n \"$ac_config_links\"; then\n  echo \"config_links=\\\"$ac_config_links\\\"\" >>$CONFIG_STATUS\nfi\n\nif test -n \"$ac_config_commands\"; then\n  echo \"config_commands=\\\"$ac_config_commands\\\"\" >>$CONFIG_STATUS\nfi\n\ncat >>$CONFIG_STATUS <<\\_ACEOF\n\nac_cs_usage=\"\\\n\\`$as_me' instantiates files from templates according to the\ncurrent configuration.\n\nUsage: $0 [OPTIONS] [FILE]...\n\n  -h, --help       print this help, then exit\n  -V, --version    print version number, then exit\n  -q, --quiet      do not print progress messages\n  -d, --debug      don't remove temporary files\n      --recheck    update $as_me by reconfiguring in the same conditions\n  --file=FILE[:TEMPLATE]\n\t\t   instantiate the configuration file FILE\n  --header=FILE[:TEMPLATE]\n\t\t   instantiate the configuration header FILE\n\nConfiguration files:\n$config_files\n\nConfiguration headers:\n$config_headers\n\nReport bugs to <bug-autoconf@gnu.org>.\"\n_ACEOF\n\ncat >>$CONFIG_STATUS <<_ACEOF\nac_cs_version=\"\\\\\nconfig.status\nconfigured by $0, generated by GNU Autoconf 2.59,\n  with options \\\\\"`echo \"$ac_configure_args\" | sed 's/[\\\\\"\"\\`\\$]/\\\\\\\\&/g'`\\\\\"\n\nCopyright (C) 2003 Free Software Foundation, Inc.\nThis config.status script is free software; the Free Software Foundation\ngives unlimited permission to copy, distribute and modify it.\"\nsrcdir=$srcdir\nINSTALL=\"$INSTALL\"\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF\n# If no file are specified by the user, then we need to provide default\n# value.  By we need to know if files were specified by the user.\nac_need_defaults=:\nwhile test $# != 0\ndo\n  case $1 in\n  --*=*)\n    ac_option=`expr \"x$1\" : 'x\\([^=]*\\)='`\n    ac_optarg=`expr \"x$1\" : 'x[^=]*=\\(.*\\)'`\n    ac_shift=:\n    ;;\n  -*)\n    ac_option=$1\n    ac_optarg=$2\n    ac_shift=shift\n    ;;\n  *) # This is not an option, so the user has probably given explicit\n     # arguments.\n     ac_option=$1\n     ac_need_defaults=false;;\n  esac\n\n  case $ac_option in\n  # Handling of the options.\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF\n  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)\n    ac_cs_recheck=: ;;\n  --version | --vers* | -V )\n    echo \"$ac_cs_version\"; exit 0 ;;\n  --he | --h)\n    # Conflict between --help and --header\n    { { echo \"$as_me:$LINENO: error: ambiguous option: $1\nTry \\`$0 --help' for more information.\" >&5\necho \"$as_me: error: ambiguous option: $1\nTry \\`$0 --help' for more information.\" >&2;}\n   { (exit 1); exit 1; }; };;\n  --help | --hel | -h )\n    echo \"$ac_cs_usage\"; exit 0 ;;\n  --debug | --d* | -d )\n    debug=: ;;\n  --file | --fil | --fi | --f )\n    $ac_shift\n    CONFIG_FILES=\"$CONFIG_FILES $ac_optarg\"\n    ac_need_defaults=false;;\n  --header | --heade | --head | --hea )\n    $ac_shift\n    CONFIG_HEADERS=\"$CONFIG_HEADERS $ac_optarg\"\n    ac_need_defaults=false;;\n  -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n  | -silent | --silent | --silen | --sile | --sil | --si | --s)\n    ac_cs_silent=: ;;\n\n  # This is an error.\n  -*) { { echo \"$as_me:$LINENO: error: unrecognized option: $1\nTry \\`$0 --help' for more information.\" >&5\necho \"$as_me: error: unrecognized option: $1\nTry \\`$0 --help' for more information.\" >&2;}\n   { (exit 1); exit 1; }; } ;;\n\n  *) ac_config_targets=\"$ac_config_targets $1\" ;;\n\n  esac\n  shift\ndone\n\nac_configure_extra_args=\n\nif $ac_cs_silent; then\n  exec 6>/dev/null\n  ac_configure_extra_args=\"$ac_configure_extra_args --silent\"\nfi\n\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF\nif \\$ac_cs_recheck; then\n  echo \"running $SHELL $0 \" $ac_configure_args \\$ac_configure_extra_args \" --no-create --no-recursion\" >&6\n  exec $SHELL $0 $ac_configure_args \\$ac_configure_extra_args --no-create --no-recursion\nfi\n\n_ACEOF\n\n\n\n\n\ncat >>$CONFIG_STATUS <<\\_ACEOF\nfor ac_config_target in $ac_config_targets\ndo\n  case \"$ac_config_target\" in\n  # Handling of arguments.\n  \"Makefile\" ) CONFIG_FILES=\"$CONFIG_FILES Makefile\" ;;\n  \"crypto/Makefile\" ) CONFIG_FILES=\"$CONFIG_FILES crypto/Makefile\" ;;\n  \"doc/Makefile\" ) CONFIG_FILES=\"$CONFIG_FILES doc/Makefile\" ;;\n  \"crypto/include/config.h\" ) CONFIG_HEADERS=\"$CONFIG_HEADERS crypto/include/config.h:config_in.h\" ;;\n  *) { { echo \"$as_me:$LINENO: error: invalid argument: $ac_config_target\" >&5\necho \"$as_me: error: invalid argument: $ac_config_target\" >&2;}\n   { (exit 1); exit 1; }; };;\n  esac\ndone\n\n# If the user did not use the arguments to specify the items to instantiate,\n# then the envvar interface is used.  Set only those that are not.\n# We use the long form for the default assignment because of an extremely\n# bizarre bug on SunOS 4.1.3.\nif $ac_need_defaults; then\n  test \"${CONFIG_FILES+set}\" = set || CONFIG_FILES=$config_files\n  test \"${CONFIG_HEADERS+set}\" = set || CONFIG_HEADERS=$config_headers\nfi\n\n# Have a temporary directory for convenience.  Make it in the build tree\n# simply because there is no reason to put it here, and in addition,\n# creating and moving files from /tmp can sometimes cause problems.\n# Create a temporary directory, and hook for its removal unless debugging.\n$debug ||\n{\n  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0\n  trap '{ (exit 1); exit 1; }' 1 2 13 15\n}\n\n# Create a (secure) tmp directory for tmp files.\n\n{\n  tmp=`(umask 077 && mktemp -d -q \"./confstatXXXXXX\") 2>/dev/null` &&\n  test -n \"$tmp\" && test -d \"$tmp\"\n}  ||\n{\n  tmp=./confstat$$-$RANDOM\n  (umask 077 && mkdir $tmp)\n} ||\n{\n   echo \"$me: cannot create a temporary directory in .\" >&2\n   { (exit 1); exit 1; }\n}\n\n_ACEOF\n\ncat >>$CONFIG_STATUS <<_ACEOF\n\n#\n# CONFIG_FILES section.\n#\n\n# No need to generate the scripts if there are no CONFIG_FILES.\n# This happens for instance when ./config.status config.h\nif test -n \"\\$CONFIG_FILES\"; then\n  # Protect against being on the right side of a sed subst in config.status.\n  sed 's/,@/@@/; s/@,/@@/; s/,;t t\\$/@;t t/; /@;t t\\$/s/[\\\\\\\\&,]/\\\\\\\\&/g;\n   s/@@/,@/; s/@@/@,/; s/@;t t\\$/,;t t/' >\\$tmp/subs.sed <<\\\\CEOF\ns,@SHELL@,$SHELL,;t t\ns,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t\ns,@PACKAGE_NAME@,$PACKAGE_NAME,;t t\ns,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t\ns,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t\ns,@PACKAGE_STRING@,$PACKAGE_STRING,;t t\ns,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t\ns,@exec_prefix@,$exec_prefix,;t t\ns,@prefix@,$prefix,;t t\ns,@program_transform_name@,$program_transform_name,;t t\ns,@bindir@,$bindir,;t t\ns,@sbindir@,$sbindir,;t t\ns,@libexecdir@,$libexecdir,;t t\ns,@datadir@,$datadir,;t t\ns,@sysconfdir@,$sysconfdir,;t t\ns,@sharedstatedir@,$sharedstatedir,;t t\ns,@localstatedir@,$localstatedir,;t t\ns,@libdir@,$libdir,;t t\ns,@includedir@,$includedir,;t t\ns,@oldincludedir@,$oldincludedir,;t t\ns,@infodir@,$infodir,;t t\ns,@mandir@,$mandir,;t t\ns,@build_alias@,$build_alias,;t t\ns,@host_alias@,$host_alias,;t t\ns,@target_alias@,$target_alias,;t t\ns,@DEFS@,$DEFS,;t t\ns,@ECHO_C@,$ECHO_C,;t t\ns,@ECHO_N@,$ECHO_N,;t t\ns,@ECHO_T@,$ECHO_T,;t t\ns,@LIBS@,$LIBS,;t t\ns,@RANLIB@,$RANLIB,;t t\ns,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t\ns,@CC@,$CC,;t t\ns,@CFLAGS@,$CFLAGS,;t t\ns,@LDFLAGS@,$LDFLAGS,;t t\ns,@CPPFLAGS@,$CPPFLAGS,;t t\ns,@ac_ct_CC@,$ac_ct_CC,;t t\ns,@EXEEXT@,$EXEEXT,;t t\ns,@OBJEXT@,$OBJEXT,;t t\ns,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t\ns,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t\ns,@INSTALL_DATA@,$INSTALL_DATA,;t t\ns,@RNG_OBJS@,$RNG_OBJS,;t t\ns,@CPP@,$CPP,;t t\ns,@EGREP@,$EGREP,;t t\ns,@build@,$build,;t t\ns,@build_cpu@,$build_cpu,;t t\ns,@build_vendor@,$build_vendor,;t t\ns,@build_os@,$build_os,;t t\ns,@host@,$host,;t t\ns,@host_cpu@,$host_cpu,;t t\ns,@host_vendor@,$host_vendor,;t t\ns,@host_os@,$host_os,;t t\ns,@EXE@,$EXE,;t t\ns,@GDOI_OBJS@,$GDOI_OBJS,;t t\ns,@LIBOBJS@,$LIBOBJS,;t t\ns,@LTLIBOBJS@,$LTLIBOBJS,;t t\nCEOF\n\n_ACEOF\n\n  cat >>$CONFIG_STATUS <<\\_ACEOF\n  # Split the substitutions into bite-sized pieces for seds with\n  # small command number limits, like on Digital OSF/1 and HP-UX.\n  ac_max_sed_lines=48\n  ac_sed_frag=1 # Number of current file.\n  ac_beg=1 # First line for current file.\n  ac_end=$ac_max_sed_lines # Line after last line for current file.\n  ac_more_lines=:\n  ac_sed_cmds=\n  while $ac_more_lines; do\n    if test $ac_beg -gt 1; then\n      sed \"1,${ac_beg}d; ${ac_end}q\" $tmp/subs.sed >$tmp/subs.frag\n    else\n      sed \"${ac_end}q\" $tmp/subs.sed >$tmp/subs.frag\n    fi\n    if test ! -s $tmp/subs.frag; then\n      ac_more_lines=false\n    else\n      # The purpose of the label and of the branching condition is to\n      # speed up the sed processing (if there are no `@' at all, there\n      # is no need to browse any of the substitutions).\n      # These are the two extra sed commands mentioned above.\n      (echo ':t\n  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed\n      if test -z \"$ac_sed_cmds\"; then\n\tac_sed_cmds=\"sed -f $tmp/subs-$ac_sed_frag.sed\"\n      else\n\tac_sed_cmds=\"$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed\"\n      fi\n      ac_sed_frag=`expr $ac_sed_frag + 1`\n      ac_beg=$ac_end\n      ac_end=`expr $ac_end + $ac_max_sed_lines`\n    fi\n  done\n  if test -z \"$ac_sed_cmds\"; then\n    ac_sed_cmds=cat\n  fi\nfi # test -n \"$CONFIG_FILES\"\n\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF\nfor ac_file in : $CONFIG_FILES; do test \"x$ac_file\" = x: && continue\n  # Support \"outfile[:infile[:infile...]]\", defaulting infile=\"outfile.in\".\n  case $ac_file in\n  - | *:- | *:-:* ) # input from stdin\n\tcat >$tmp/stdin\n\tac_file_in=`echo \"$ac_file\" | sed 's,[^:]*:,,'`\n\tac_file=`echo \"$ac_file\" | sed 's,:.*,,'` ;;\n  *:* ) ac_file_in=`echo \"$ac_file\" | sed 's,[^:]*:,,'`\n\tac_file=`echo \"$ac_file\" | sed 's,:.*,,'` ;;\n  * )   ac_file_in=$ac_file.in ;;\n  esac\n\n  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.\n  ac_dir=`(dirname \"$ac_file\") 2>/dev/null ||\n$as_expr X\"$ac_file\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)$' \\| \\\n\t X\"$ac_file\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$ac_file\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n  { if $as_mkdir_p; then\n    mkdir -p \"$ac_dir\"\n  else\n    as_dir=\"$ac_dir\"\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory \\\"$ac_dir\\\"\" >&5\necho \"$as_me: error: cannot create directory \\\"$ac_dir\\\"\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n  ac_builddir=.\n\nif test \"$ac_dir\" != .; then\n  ac_dir_suffix=/`echo \"$ac_dir\" | sed 's,^\\.[\\\\/],,'`\n  # A \"../\" for each directory in $ac_dir_suffix.\n  ac_top_builddir=`echo \"$ac_dir_suffix\" | sed 's,/[^\\\\/]*,../,g'`\nelse\n  ac_dir_suffix= ac_top_builddir=\nfi\n\ncase $srcdir in\n  .)  # No --srcdir option.  We are building in place.\n    ac_srcdir=.\n    if test -z \"$ac_top_builddir\"; then\n       ac_top_srcdir=.\n    else\n       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`\n    fi ;;\n  [\\\\/]* | ?:[\\\\/]* )  # Absolute path.\n    ac_srcdir=$srcdir$ac_dir_suffix;\n    ac_top_srcdir=$srcdir ;;\n  *) # Relative path.\n    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix\n    ac_top_srcdir=$ac_top_builddir$srcdir ;;\nesac\n\n# Do not use `cd foo && pwd` to compute absolute paths, because\n# the directories may not exist.\ncase `pwd` in\n.) ac_abs_builddir=\"$ac_dir\";;\n*)\n  case \"$ac_dir\" in\n  .) ac_abs_builddir=`pwd`;;\n  [\\\\/]* | ?:[\\\\/]* ) ac_abs_builddir=\"$ac_dir\";;\n  *) ac_abs_builddir=`pwd`/\"$ac_dir\";;\n  esac;;\nesac\ncase $ac_abs_builddir in\n.) ac_abs_top_builddir=${ac_top_builddir}.;;\n*)\n  case ${ac_top_builddir}. in\n  .) ac_abs_top_builddir=$ac_abs_builddir;;\n  [\\\\/]* | ?:[\\\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;\n  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;\n  esac;;\nesac\ncase $ac_abs_builddir in\n.) ac_abs_srcdir=$ac_srcdir;;\n*)\n  case $ac_srcdir in\n  .) ac_abs_srcdir=$ac_abs_builddir;;\n  [\\\\/]* | ?:[\\\\/]* ) ac_abs_srcdir=$ac_srcdir;;\n  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;\n  esac;;\nesac\ncase $ac_abs_builddir in\n.) ac_abs_top_srcdir=$ac_top_srcdir;;\n*)\n  case $ac_top_srcdir in\n  .) ac_abs_top_srcdir=$ac_abs_builddir;;\n  [\\\\/]* | ?:[\\\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;\n  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;\n  esac;;\nesac\n\n\n  case $INSTALL in\n  [\\\\/$]* | ?:[\\\\/]* ) ac_INSTALL=$INSTALL ;;\n  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;\n  esac\n\n  if test x\"$ac_file\" != x-; then\n    { echo \"$as_me:$LINENO: creating $ac_file\" >&5\necho \"$as_me: creating $ac_file\" >&6;}\n    rm -f \"$ac_file\"\n  fi\n  # Let's still pretend it is `configure' which instantiates (i.e., don't\n  # use $as_me), people would be surprised to read:\n  #    /* config.h.  Generated by config.status.  */\n  if test x\"$ac_file\" = x-; then\n    configure_input=\n  else\n    configure_input=\"$ac_file.  \"\n  fi\n  configure_input=$configure_input\"Generated from `echo $ac_file_in |\n\t\t\t\t     sed 's,.*/,,'` by configure.\"\n\n  # First look for the input files in the build tree, otherwise in the\n  # src tree.\n  ac_file_inputs=`IFS=:\n    for f in $ac_file_in; do\n      case $f in\n      -) echo $tmp/stdin ;;\n      [\\\\/$]*)\n\t # Absolute (can't be DOS-style, as IFS=:)\n\t test -f \"$f\" || { { echo \"$as_me:$LINENO: error: cannot find input file: $f\" >&5\necho \"$as_me: error: cannot find input file: $f\" >&2;}\n   { (exit 1); exit 1; }; }\n\t echo \"$f\";;\n      *) # Relative\n\t if test -f \"$f\"; then\n\t   # Build tree\n\t   echo \"$f\"\n\t elif test -f \"$srcdir/$f\"; then\n\t   # Source tree\n\t   echo \"$srcdir/$f\"\n\t else\n\t   # /dev/null tree\n\t   { { echo \"$as_me:$LINENO: error: cannot find input file: $f\" >&5\necho \"$as_me: error: cannot find input file: $f\" >&2;}\n   { (exit 1); exit 1; }; }\n\t fi;;\n      esac\n    done` || { (exit 1); exit 1; }\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF\n  sed \"$ac_vpsub\n$extrasub\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF\n:t\n/@[a-zA-Z_][a-zA-Z_0-9]*@/!b\ns,@configure_input@,$configure_input,;t t\ns,@srcdir@,$ac_srcdir,;t t\ns,@abs_srcdir@,$ac_abs_srcdir,;t t\ns,@top_srcdir@,$ac_top_srcdir,;t t\ns,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t\ns,@builddir@,$ac_builddir,;t t\ns,@abs_builddir@,$ac_abs_builddir,;t t\ns,@top_builddir@,$ac_top_builddir,;t t\ns,@abs_top_builddir@,$ac_abs_top_builddir,;t t\ns,@INSTALL@,$ac_INSTALL,;t t\n\" $ac_file_inputs | (eval \"$ac_sed_cmds\") >$tmp/out\n  rm -f $tmp/stdin\n  if test x\"$ac_file\" != x-; then\n    mv $tmp/out $ac_file\n  else\n    cat $tmp/out\n    rm -f $tmp/out\n  fi\n\ndone\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF\n\n#\n# CONFIG_HEADER section.\n#\n\n# These sed commands are passed to sed as \"A NAME B NAME C VALUE D\", where\n# NAME is the cpp macro being defined and VALUE is the value it is being given.\n#\n# ac_d sets the value in \"#define NAME VALUE\" lines.\nac_dA='s,^\\([\t ]*\\)#\\([\t ]*define[\t ][\t ]*\\)'\nac_dB='[\t ].*$,\\1#\\2'\nac_dC=' '\nac_dD=',;t'\n# ac_u turns \"#undef NAME\" without trailing blanks into \"#define NAME VALUE\".\nac_uA='s,^\\([\t ]*\\)#\\([\t ]*\\)undef\\([\t ][\t ]*\\)'\nac_uB='$,\\1#\\2define\\3'\nac_uC=' '\nac_uD=',;t'\n\nfor ac_file in : $CONFIG_HEADERS; do test \"x$ac_file\" = x: && continue\n  # Support \"outfile[:infile[:infile...]]\", defaulting infile=\"outfile.in\".\n  case $ac_file in\n  - | *:- | *:-:* ) # input from stdin\n\tcat >$tmp/stdin\n\tac_file_in=`echo \"$ac_file\" | sed 's,[^:]*:,,'`\n\tac_file=`echo \"$ac_file\" | sed 's,:.*,,'` ;;\n  *:* ) ac_file_in=`echo \"$ac_file\" | sed 's,[^:]*:,,'`\n\tac_file=`echo \"$ac_file\" | sed 's,:.*,,'` ;;\n  * )   ac_file_in=$ac_file.in ;;\n  esac\n\n  test x\"$ac_file\" != x- && { echo \"$as_me:$LINENO: creating $ac_file\" >&5\necho \"$as_me: creating $ac_file\" >&6;}\n\n  # First look for the input files in the build tree, otherwise in the\n  # src tree.\n  ac_file_inputs=`IFS=:\n    for f in $ac_file_in; do\n      case $f in\n      -) echo $tmp/stdin ;;\n      [\\\\/$]*)\n\t # Absolute (can't be DOS-style, as IFS=:)\n\t test -f \"$f\" || { { echo \"$as_me:$LINENO: error: cannot find input file: $f\" >&5\necho \"$as_me: error: cannot find input file: $f\" >&2;}\n   { (exit 1); exit 1; }; }\n\t # Do quote $f, to prevent DOS paths from being IFS'd.\n\t echo \"$f\";;\n      *) # Relative\n\t if test -f \"$f\"; then\n\t   # Build tree\n\t   echo \"$f\"\n\t elif test -f \"$srcdir/$f\"; then\n\t   # Source tree\n\t   echo \"$srcdir/$f\"\n\t else\n\t   # /dev/null tree\n\t   { { echo \"$as_me:$LINENO: error: cannot find input file: $f\" >&5\necho \"$as_me: error: cannot find input file: $f\" >&2;}\n   { (exit 1); exit 1; }; }\n\t fi;;\n      esac\n    done` || { (exit 1); exit 1; }\n  # Remove the trailing spaces.\n  sed 's/[\t ]*$//' $ac_file_inputs >$tmp/in\n\n_ACEOF\n\n# Transform confdefs.h into two sed scripts, `conftest.defines' and\n# `conftest.undefs', that substitutes the proper values into\n# config.h.in to produce config.h.  The first handles `#define'\n# templates, and the second `#undef' templates.\n# And first: Protect against being on the right side of a sed subst in\n# config.status.  Protect against being in an unquoted here document\n# in config.status.\nrm -f conftest.defines conftest.undefs\n# Using a here document instead of a string reduces the quoting nightmare.\n# Putting comments in sed scripts is not portable.\n#\n# `end' is used to avoid that the second main sed command (meant for\n# 0-ary CPP macros) applies to n-ary macro definitions.\n# See the Autoconf documentation for `clear'.\ncat >confdef2sed.sed <<\\_ACEOF\ns/[\\\\&,]/\\\\&/g\ns,[\\\\$`],\\\\&,g\nt clear\n: clear\ns,^[\t ]*#[\t ]*define[\t ][\t ]*\\([^\t (][^\t (]*\\)\\(([^)]*)\\)[\t ]*\\(.*\\)$,${ac_dA}\\1${ac_dB}\\1\\2${ac_dC}\\3${ac_dD},gp\nt end\ns,^[\t ]*#[\t ]*define[\t ][\t ]*\\([^\t ][^\t ]*\\)[\t ]*\\(.*\\)$,${ac_dA}\\1${ac_dB}\\1${ac_dC}\\2${ac_dD},gp\n: end\n_ACEOF\n# If some macros were called several times there might be several times\n# the same #defines, which is useless.  Nevertheless, we may not want to\n# sort them, since we want the *last* AC-DEFINE to be honored.\nuniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines\nsed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs\nrm -f confdef2sed.sed\n\n# This sed command replaces #undef with comments.  This is necessary, for\n# example, in the case of _POSIX_SOURCE, which is predefined and required\n# on some systems where configure will not decide to define it.\ncat >>conftest.undefs <<\\_ACEOF\ns,^[\t ]*#[\t ]*undef[\t ][\t ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,\n_ACEOF\n\n# Break up conftest.defines because some shells have a limit on the size\n# of here documents, and old seds have small limits too (100 cmds).\necho '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS\necho '  if grep \"^[\t ]*#[\t ]*define\" $tmp/in >/dev/null; then' >>$CONFIG_STATUS\necho '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS\necho '  :' >>$CONFIG_STATUS\nrm -f conftest.tail\nwhile grep . conftest.defines >/dev/null\ndo\n  # Write a limited-size here document to $tmp/defines.sed.\n  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS\n  # Speed up: don't consider the non `#define' lines.\n  echo '/^[\t ]*#[\t ]*define/!b' >>$CONFIG_STATUS\n  # Work around the forget-to-reset-the-flag bug.\n  echo 't clr' >>$CONFIG_STATUS\n  echo ': clr' >>$CONFIG_STATUS\n  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS\n  echo 'CEOF\n  sed -f $tmp/defines.sed $tmp/in >$tmp/out\n  rm -f $tmp/in\n  mv $tmp/out $tmp/in\n' >>$CONFIG_STATUS\n  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail\n  rm -f conftest.defines\n  mv conftest.tail conftest.defines\ndone\nrm -f conftest.defines\necho '  fi # grep' >>$CONFIG_STATUS\necho >>$CONFIG_STATUS\n\n# Break up conftest.undefs because some shells have a limit on the size\n# of here documents, and old seds have small limits too (100 cmds).\necho '  # Handle all the #undef templates' >>$CONFIG_STATUS\nrm -f conftest.tail\nwhile grep . conftest.undefs >/dev/null\ndo\n  # Write a limited-size here document to $tmp/undefs.sed.\n  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS\n  # Speed up: don't consider the non `#undef'\n  echo '/^[\t ]*#[\t ]*undef/!b' >>$CONFIG_STATUS\n  # Work around the forget-to-reset-the-flag bug.\n  echo 't clr' >>$CONFIG_STATUS\n  echo ': clr' >>$CONFIG_STATUS\n  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS\n  echo 'CEOF\n  sed -f $tmp/undefs.sed $tmp/in >$tmp/out\n  rm -f $tmp/in\n  mv $tmp/out $tmp/in\n' >>$CONFIG_STATUS\n  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail\n  rm -f conftest.undefs\n  mv conftest.tail conftest.undefs\ndone\nrm -f conftest.undefs\n\ncat >>$CONFIG_STATUS <<\\_ACEOF\n  # Let's still pretend it is `configure' which instantiates (i.e., don't\n  # use $as_me), people would be surprised to read:\n  #    /* config.h.  Generated by config.status.  */\n  if test x\"$ac_file\" = x-; then\n    echo \"/* Generated by configure.  */\" >$tmp/config.h\n  else\n    echo \"/* $ac_file.  Generated by configure.  */\" >$tmp/config.h\n  fi\n  cat $tmp/in >>$tmp/config.h\n  rm -f $tmp/in\n  if test x\"$ac_file\" != x-; then\n    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then\n      { echo \"$as_me:$LINENO: $ac_file is unchanged\" >&5\necho \"$as_me: $ac_file is unchanged\" >&6;}\n    else\n      ac_dir=`(dirname \"$ac_file\") 2>/dev/null ||\n$as_expr X\"$ac_file\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)$' \\| \\\n\t X\"$ac_file\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$ac_file\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n      { if $as_mkdir_p; then\n    mkdir -p \"$ac_dir\"\n  else\n    as_dir=\"$ac_dir\"\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory \\\"$ac_dir\\\"\" >&5\necho \"$as_me: error: cannot create directory \\\"$ac_dir\\\"\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n      rm -f $ac_file\n      mv $tmp/config.h $ac_file\n    fi\n  else\n    cat $tmp/config.h\n    rm -f $tmp/config.h\n  fi\ndone\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF\n\n{ (exit 0); exit 0; }\n_ACEOF\nchmod +x $CONFIG_STATUS\nac_clean_files=$ac_clean_files_save\n\n\n# configure is writing to config.log, and then calls config.status.\n# config.status does its own redirection, appending to config.log.\n# Unfortunately, on DOS this fails, as config.log is still kept open\n# by configure, so config.status won't be able to write to it; its\n# output is simply discarded.  So we exec the FD to /dev/null,\n# effectively closing config.log, so it can be properly (re)opened and\n# appended to by config.status.  When coming back to configure, we\n# need to make the FD available again.\nif test \"$no_create\" != yes; then\n  ac_cs_success=:\n  ac_config_status_args=\n  test \"$silent\" = yes &&\n    ac_config_status_args=\"$ac_config_status_args --quiet\"\n  exec 5>/dev/null\n  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false\n  exec 5>>config.log\n  # Use ||, not &&, to avoid exiting from the if with $? = 1, which\n  # would make configure fail if this is the last instruction.\n  $ac_cs_success || { (exit 1); exit 1; }\nfi\n\n\n# This is needed when building outside the source dir.\n{ if $as_mkdir_p; then\n    mkdir -p crypto/ae_xfm\n  else\n    as_dir=crypto/ae_xfm\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory crypto/ae_xfm\" >&5\necho \"$as_me: error: cannot create directory crypto/ae_xfm\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n{ if $as_mkdir_p; then\n    mkdir -p crypto/cipher\n  else\n    as_dir=crypto/cipher\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory crypto/cipher\" >&5\necho \"$as_me: error: cannot create directory crypto/cipher\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n{ if $as_mkdir_p; then\n    mkdir -p crypto/hash\n  else\n    as_dir=crypto/hash\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory crypto/hash\" >&5\necho \"$as_me: error: cannot create directory crypto/hash\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n{ if $as_mkdir_p; then\n    mkdir -p crypto/kernel\n  else\n    as_dir=crypto/kernel\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory crypto/kernel\" >&5\necho \"$as_me: error: cannot create directory crypto/kernel\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n{ if $as_mkdir_p; then\n    mkdir -p crypto/math\n  else\n    as_dir=crypto/math\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory crypto/math\" >&5\necho \"$as_me: error: cannot create directory crypto/math\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n{ if $as_mkdir_p; then\n    mkdir -p crypto/replay\n  else\n    as_dir=crypto/replay\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory crypto/replay\" >&5\necho \"$as_me: error: cannot create directory crypto/replay\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n{ if $as_mkdir_p; then\n    mkdir -p crypto/rng\n  else\n    as_dir=crypto/rng\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory crypto/rng\" >&5\necho \"$as_me: error: cannot create directory crypto/rng\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n{ if $as_mkdir_p; then\n    mkdir -p crypto/test\n  else\n    as_dir=crypto/test\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory crypto/test\" >&5\necho \"$as_me: error: cannot create directory crypto/test\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n{ if $as_mkdir_p; then\n    mkdir -p doc\n  else\n    as_dir=doc\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory doc\" >&5\necho \"$as_me: error: cannot create directory doc\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n{ if $as_mkdir_p; then\n    mkdir -p srtp\n  else\n    as_dir=srtp\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory srtp\" >&5\necho \"$as_me: error: cannot create directory srtp\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n{ if $as_mkdir_p; then\n    mkdir -p tables\n  else\n    as_dir=tables\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory tables\" >&5\necho \"$as_me: error: cannot create directory tables\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n{ if $as_mkdir_p; then\n    mkdir -p test\n  else\n    as_dir=test\n    as_dirs=\n    while test ! -d \"$as_dir\"; do\n      as_dirs=\"$as_dir $as_dirs\"\n      as_dir=`(dirname \"$as_dir\") 2>/dev/null ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| \\\n\t .     : '\\(.\\)' 2>/dev/null ||\necho X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)[^/].*/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\/\\)$/{ s//\\1/; q; }\n  \t  /^X\\(\\/\\).*/{ s//\\1/; q; }\n  \t  s/.*/./; q'`\n    done\n    test ! -n \"$as_dirs\" || mkdir $as_dirs\n  fi || { { echo \"$as_me:$LINENO: error: cannot create directory test\" >&5\necho \"$as_me: error: cannot create directory test\" >&2;}\n   { (exit 1); exit 1; }; }; }\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/configure.in",
    "content": "dnl Process this file with autoconf to produce a configure script.\nAC_INIT(srtp)\n\ndnl Must come before AC_PROG_CC\nif test -z \"$CFLAGS\"; then\n   dnl Default value for CFLAGS if not specified.\n   CFLAGS=\"-Wall -O4 -fexpensive-optimizations -funroll-loops\"\nfi\n\ndnl Checks for programs.\nAC_PROG_RANLIB\nAC_PROG_CC\nAC_PROG_INSTALL\n\n\nAC_ARG_ENABLE(kernel-linux,\n  [AS_HELP_STRING([--enable-kernel-linux],\n\t\t  [build library to run in Linux kernel context])],\n  [], enable_kernel_linux=no)\nAC_MSG_CHECKING(whether to build for Linux kernel context)\nif test \"$enable_kernel_linux\" = \"yes\"; then\n   AC_DEFINE(SRTP_KERNEL, 1,\n\t[Define to compile for kernel contexts.])\n   AC_DEFINE(SRTP_KERNEL_LINUX, 1,\n\t[Define to compile for Linux kernel context.])\nfi\nAC_MSG_RESULT($enable_kernel_linux)\n\nif test \"$cross_compiling\" != yes; then\n   dnl Check for /dev/urandom\n   AC_CHECK_FILE(/dev/urandom, DEV_URANDOM=/dev/urandom,\n      [AC_CHECK_FILE(/dev/random, DEV_URANDOM=/dev/random)])\nfi\n\nAC_MSG_CHECKING(which random device to use)\nif test \"$enable_kernel_linux\" = \"yes\"; then\n   RNG_OBJS=rand_linux_kernel.o\n   AC_MSG_RESULT([Linux kernel builtin])\nelse\n   RNG_OBJS=rand_source.o\n   if test -n \"$DEV_URANDOM\"; then\n      AC_DEFINE_UNQUOTED(DEV_URANDOM, \"$DEV_URANDOM\",[Path to random device])\n      AC_MSG_RESULT([$DEV_URANDOM])\n   else\n      AC_MSG_RESULT([standard rand() function...])\n   fi\nfi\nAC_SUBST(RNG_OBJS)\n\n\ndnl Checks for header files.\nAC_HEADER_STDC\nAC_CHECK_HEADERS(stdlib.h)\nAC_CHECK_HEADERS(unistd.h)\nAC_CHECK_HEADERS(byteswap.h)\nAC_CHECK_HEADERS(stdint.h)\nAC_CHECK_HEADERS(sys/uio.h)\nAC_CHECK_HEADERS(inttypes.h)\nAC_CHECK_HEADERS(sys/types.h)\nAC_CHECK_HEADERS(machine/types.h)\nAC_CHECK_HEADERS(sys/int_types.h)\n\ndnl socket() and friends\nAC_CHECK_HEADERS(sys/socket.h netinet/in.h arpa/inet.h)\nAC_CHECK_HEADERS(windows.h, [AC_CHECK_HEADERS(winsock2.h)])\n\nAC_CHECK_HEADERS(syslog.h)\n\nAC_CHECK_TYPES([int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,uint64_t])\nAC_CHECK_SIZEOF(unsigned long)\nAC_CHECK_SIZEOF(unsigned long long)\n\ndnl Checks for typedefs, structures, and compiler characteristics.\nAC_C_CONST\nAC_C_INLINE\nAC_TYPE_SIZE_T\n\ndnl Checks for library functions.\nAC_CHECK_FUNCS(socket inet_aton usleep)\n\ndnl Find socket function if not found yet.\nif test \"x$ac_cv_func_socket\" = \"xno\"; then\n  AC_CHECK_LIB(socket, socket)\n  AC_MSG_CHECKING([for socket in -lwsock32])\n  SAVELIBS=\"$LIBS\"\n  LIBS=\"$LIBS -lwsock32\"\n  AC_TRY_LINK([\n#include <winsock2.h>\n],[\nsocket(0, 0, 0);\n],\n    ac_cv_func_socket=yes\n    AC_MSG_RESULT(yes),\n    LIBS=\"$SAVELIBS\"\n    AC_MSG_RESULT(no))\nfi\n\ndnl Check the byte order\nAC_C_BIGENDIAN\n\nAC_CANONICAL_HOST\n\ndnl check host_cpu type, set defines appropriately\ncase $host_cpu in\n     i*86 )\n\tAC_DEFINE(CPU_CISC, 1,\n\t   [Define if building for a CISC machine (e.g. Intel).])\n        AC_DEFINE(HAVE_X86, 1,\n\t   [Define to use X86 inlined assembly code]);; \n\t* )\n\t# CPU_RISC is only supported for big endian machines.\n\tif test \"$ac_cv_c_bigendian\" = \"yes\"; then\n\t   AC_DEFINE(CPU_RISC, 1,\n\t    [Define if building for a RISC machine (assume slow byte access).])\n\telse\n\t   AC_DEFINE(CPU_CISC, 1)\n\tfi\n\t;;\nesac\t\n\ndnl Check if we're on a Windows platform.\ncase $host_os in\n  *cygwin*|*mingw* ) \n\t      EXE=.exe;;\n         * )  EXE=\"\";;\nesac\n\nAC_SUBST(EXE)   # define executable suffix; this is needed for `make clean'\n\nAC_MSG_CHECKING(whether to compile in debugging)\nAC_ARG_ENABLE(debug,\n  [AS_HELP_STRING([--disable-debug],\n\t\t  [do not compile in dynamic debugging system])],\n  [], enable_debug=yes)\nif test \"$enable_debug\" = \"yes\"; then\n   AC_DEFINE(ENABLE_DEBUGGING, 1,\n      [Define to compile in dynamic debugging system.])\nfi\nAC_MSG_RESULT($enable_debug)\n\nAC_MSG_CHECKING(whether to use ISMAcryp code)\nAC_ARG_ENABLE(generic-aesicm,\n  [AS_HELP_STRING([--enable-generic-aesicm],\n\t\t  [compile in changes for ISMAcryp])],\n  [], enable_generic_aesicm=no)\nif test \"$enable_generic_aesicm\" = \"yes\"; then\n   AC_DEFINE(GENERIC_AESICM, 1, [Define this to use ISMAcryp code.])\nfi\nAC_MSG_RESULT($enable_generic_aesicm)\n\nAC_MSG_CHECKING(whether to use syslog for error reporting)\nAC_ARG_ENABLE(syslog,\n  [AS_HELP_STRING([--enable-syslog], [use syslog for error reporting])],\n  [], enable_syslog=no)\nif test \"$enable_syslog\" = \"yes\"; then\n   AC_DEFINE(USE_SYSLOG, 1, [Define to use syslog logging.])\nfi\nAC_MSG_RESULT($enable_syslog)\n\nAC_MSG_CHECKING(whether to use stdout for error reporting)\nAC_ARG_ENABLE(stdout,\n  [AS_HELP_STRING([--disable-stdout], [don't use stdout for error reporting])],\n  [], enable_stdout=yes)\nif test \"$enable_stdout\" = \"yes\"; then\n   AC_DEFINE(ERR_REPORTING_STDOUT, 1, [Define to use logging to stdout.])\nfi\nAC_MSG_RESULT($enable_stdout)\n\nAC_MSG_CHECKING(whether to use /dev/console for error reporting)\nAC_ARG_ENABLE(console,\n  [AS_HELP_STRING([--enable-console], [use /dev/console for error reporting])],\n  [], enable_console=no)\nif test \"$enable_console\" = \"yes\"; then\n   AC_DEFINE(USE_ERR_REPORTING_FILE, 1, [Write errors to this file])\n   AC_DEFINE(ERR_REPORTING_FILE, \"/dev/console\", [Report errors to this file.])\nfi\nAC_MSG_RESULT($enable_console)\n\nAC_MSG_CHECKING(whether to use GDOI key management)\nAC_ARG_ENABLE(gdoi,\n  [AS_HELP_STRING([--enable-gdoi], [enable GDOI key management])],\n  [], enable_gdoi=no)\nif test \"$enable_gdoi\" = \"yes\"; then\n   AC_DEFINE(SRTP_GDOI, 1, [Define to use GDOI.])\n   GDOI_OBJS=gdoi/srtp+gdoi.o\n   AC_SUBST(GDOI_OBJS)                              \nfi\nAC_MSG_RESULT($enable_gdoi)\n\nAC_CONFIG_HEADER(crypto/include/config.h:config_in.h)\n\nAC_OUTPUT(Makefile crypto/Makefile doc/Makefile)\n\n# This is needed when building outside the source dir.\nAS_MKDIR_P(crypto/ae_xfm)\nAS_MKDIR_P(crypto/cipher)\nAS_MKDIR_P(crypto/hash)\nAS_MKDIR_P(crypto/kernel)\nAS_MKDIR_P(crypto/math)\nAS_MKDIR_P(crypto/replay)\nAS_MKDIR_P(crypto/rng)\nAS_MKDIR_P(crypto/test)\nAS_MKDIR_P(doc)\nAS_MKDIR_P(srtp)\nAS_MKDIR_P(tables)\nAS_MKDIR_P(test)\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/Makefile",
    "content": "# Makefile for libcryptomodule.a\n#\n# David A. McGrew\n# Cisco Systems, Inc.\n\nsrcdir = .\ntop_srcdir = ..\ntop_builddir = ../\n\n\nCC\t= gcc\nINCDIR\t= -Iinclude -I$(srcdir)/include\nDEFS\t= -DHAVE_CONFIG_H\nCPPFLAGS= \nCFLAGS\t= -Wall -O4 -fexpensive-optimizations -funroll-loops\nLIBS\t= \nLDFLAGS\t=  -L.\nCOMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS)\nCRYPTOLIB = -lcryptomodule\n\nRANLIB\t= ranlib\n\n# EXE defines the suffix on executables - it's .exe for cygwin, and\n# null on linux, bsd, and OS X and other OSes.  we define this so that\n# `make clean` will work on the cygwin platform\nEXE = \n# Random source.\nRNG_OBJS = rand_source.o\n\nifdef ARCH\n  DEFS += -D$(ARCH)=1\nendif\n\nifdef sysname\n  DEFS += -D$(sysname)=1\nendif\n\n.PHONY: dummy all runtest clean superclean\n\ndummy : all runtest \n\n# test applications \n\ntestapp = test/cipher_driver$(EXE) test/datatypes_driver$(EXE) \\\n\t  test/stat_driver$(EXE) test/sha1_driver$(EXE) \\\n\t  test/kernel_driver$(EXE) test/aes_calc$(EXE) test/rand_gen$(EXE) \\\n\t  test/env$(EXE)\n\n# data values used to test the aes_calc application\n\nk=000102030405060708090a0b0c0d0e0f\np=00112233445566778899aabbccddeeff\nc=69c4e0d86a7b0430d8cdb78070b4c55a\n\nruntest: libcryptomodule.a $(testapp)\n\ttest/env$(EXE) # print out information on the build environment\n\t@echo \"running libcryptomodule test applications...\"\n\ttest `test/aes_calc $k $p` = $c\n\ttest/cipher_driver$(EXE) -v >/dev/null\n\ttest/datatypes_driver$(EXE) -v >/dev/null\n\ttest/stat_driver$(EXE) >/dev/null\n\ttest/sha1_driver$(EXE) -v >/dev/null\n\ttest/kernel_driver$(EXE) -v >/dev/null\n\ttest/rand_gen$(EXE) -n 256 >/dev/null\n\t@echo \"libcryptomodule test applications passed.\"\n\n# libcryptomodule.a (the crypto engine) \n\nciphers = cipher/cipher.o cipher/null_cipher.o      \\\n          cipher/aes.o cipher/aes_icm.o             \\\n          cipher/aes_cbc.o\n\nhashes  = hash/null_auth.o hash/sha1.o \\\n          hash/hmac.o hash/auth.o\n\nmath    = math/datatypes.o math/stat.o\n\nrng     = rng/$(RNG_OBJS) rng/rand_source.o rng/prng.o rng/ctr_prng.o\n\nerr     = kernel/err.o\n\nkernel  = kernel/crypto_kernel.o  kernel/alloc.o   \\\n          kernel/key.o $(rng) $(err)\n\nxfm     = ae_xfm/xfm.o\n\ncryptobj =  $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(xfm)\n\n# the rule for making object files and test apps\n\n%.o: %.c\n\t$(COMPILE) -c $< -o $@\n\n%$(EXE): %.c libcryptomodule.a \n\t$(COMPILE) $(LDFLAGS) $< -o $@ $(CRYPTOLIB) $(LIBS)\n\nifndef AR\n  AR=ar\nendif\n\n# and the crypto module library itself\n\nlibcryptomodule.a: $(cryptobj) \n\t$(AR) cr libcryptomodule.a $(cryptobj) \n\t$(RANLIB) libcryptomodule.a\n\nall: libcryptomodule.a $(testapp)\n\n# housekeeping functions\n\nclean:\n\trm -f libcryptomodule.a\n\trm -f $(testapp) *.o */*.o \n\tfor a in * .* */*; do if [ -f \"$$a~\" ] ; then rm $$a~; fi; done;\n\trm -f `find . -name \"*.[ch]~*~\"`\n\trm -rf latex\n\nsuperclean: clean\n\trm -f *core TAGS ktrace.out\n\n\n# the target 'package' builds a compressed tar archive of the source code\n\ndistname = crypto-$(shell cat VERSION)\n\npackage: superclean\n\tcd ..; tar cvzf $(distname).tgz crypto/\n\n\n# EOF\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/Makefile.in",
    "content": "# Makefile for libcryptomodule.a\n#\n# David A. McGrew\n# Cisco Systems, Inc.\n\nsrcdir = @srcdir@\ntop_srcdir = @top_srcdir@\ntop_builddir = @top_builddir@\nVPATH = @srcdir@\n\nCC\t= @CC@\nINCDIR\t= -Iinclude -I$(srcdir)/include\nDEFS\t= @DEFS@\nCPPFLAGS= @CPPFLAGS@\nCFLAGS\t= @CFLAGS@\nLIBS\t= @LIBS@\nLDFLAGS\t= @LDFLAGS@ -L.\nCOMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS)\nCRYPTOLIB = -lcryptomodule\n\nRANLIB\t= @RANLIB@\n\n# EXE defines the suffix on executables - it's .exe for cygwin, and\n# null on linux, bsd, and OS X and other OSes.  we define this so that\n# `make clean` will work on the cygwin platform\nEXE = @EXE@\n# Random source.\nRNG_OBJS = @RNG_OBJS@\n\nifdef ARCH\n  DEFS += -D$(ARCH)=1\nendif\n\nifdef sysname\n  DEFS += -D$(sysname)=1\nendif\n\n.PHONY: dummy all runtest clean superclean\n\ndummy : all runtest \n\n# test applications \n\ntestapp = test/cipher_driver$(EXE) test/datatypes_driver$(EXE) \\\n\t  test/stat_driver$(EXE) test/sha1_driver$(EXE) \\\n\t  test/kernel_driver$(EXE) test/aes_calc$(EXE) test/rand_gen$(EXE) \\\n\t  test/env$(EXE)\n\n# data values used to test the aes_calc application\n\nk=000102030405060708090a0b0c0d0e0f\np=00112233445566778899aabbccddeeff\nc=69c4e0d86a7b0430d8cdb78070b4c55a\n\nruntest: libcryptomodule.a $(testapp)\n\ttest/env$(EXE) # print out information on the build environment\n\t@echo \"running libcryptomodule test applications...\"\n\ttest `test/aes_calc $k $p` = $c\n\ttest/cipher_driver$(EXE) -v >/dev/null\n\ttest/datatypes_driver$(EXE) -v >/dev/null\n\ttest/stat_driver$(EXE) >/dev/null\n\ttest/sha1_driver$(EXE) -v >/dev/null\n\ttest/kernel_driver$(EXE) -v >/dev/null\n\ttest/rand_gen$(EXE) -n 256 >/dev/null\n\t@echo \"libcryptomodule test applications passed.\"\n\n# libcryptomodule.a (the crypto engine) \n\nciphers = cipher/cipher.o cipher/null_cipher.o      \\\n          cipher/aes.o cipher/aes_icm.o             \\\n          cipher/aes_cbc.o\n\nhashes  = hash/null_auth.o hash/sha1.o \\\n          hash/hmac.o hash/auth.o\n\nmath    = math/datatypes.o math/stat.o\n\nrng     = rng/$(RNG_OBJS) rng/rand_source.o rng/prng.o rng/ctr_prng.o\n\nerr     = kernel/err.o\n\nkernel  = kernel/crypto_kernel.o  kernel/alloc.o   \\\n          kernel/key.o $(rng) $(err)\n\nxfm     = ae_xfm/xfm.o\n\ncryptobj =  $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(xfm)\n\n# the rule for making object files and test apps\n\n%.o: %.c\n\t$(COMPILE) -c $< -o $@\n\n%$(EXE): %.c libcryptomodule.a \n\t$(COMPILE) $(LDFLAGS) $< -o $@ $(CRYPTOLIB) $(LIBS)\n\nifndef AR\n  AR=ar\nendif\n\n# and the crypto module library itself\n\nlibcryptomodule.a: $(cryptobj) \n\t$(AR) cr libcryptomodule.a $(cryptobj) \n\t$(RANLIB) libcryptomodule.a\n\nall: libcryptomodule.a $(testapp)\n\n# housekeeping functions\n\nclean:\n\trm -f libcryptomodule.a\n\trm -f $(testapp) *.o */*.o \n\tfor a in * .* */*; do if [ -f \"$$a~\" ] ; then rm $$a~; fi; done;\n\trm -f `find . -name \"*.[ch]~*~\"`\n\trm -rf latex\n\nsuperclean: clean\n\trm -f *core TAGS ktrace.out\n\n\n# the target 'package' builds a compressed tar archive of the source code\n\ndistname = crypto-$(shell cat VERSION)\n\npackage: superclean\n\tcd ..; tar cvzf $(distname).tgz crypto/\n\n\n# EOF\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/VERSION",
    "content": "1.0.0\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/ae_xfm/xfm.c",
    "content": "/*\n * xfm.c\n *\n * Crypto transform implementation\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n#include \"cryptoalg.h\"\n#include \"aes_cbc.h\"\n#include \"hmac.h\"\n#include \"crypto_kernel.h\"   /* for crypto_get_random() */\n\n#define KEY_LEN     16\n#define ENC_KEY_LEN 16\n#define MAC_KEY_LEN 16\n#define IV_LEN      16\n#define TAG_LEN     12\n#define MAX_EXPAND  27\n\nerr_status_t\naes_128_cbc_hmac_sha1_96_func(void *key,            \n\t\t\t      void *clear,          \n\t\t\t      unsigned clear_len,       \n\t\t\t      void *iv,             \n\t\t\t      void *opaque,         \n\t\t\t      unsigned *opaque_len, \n\t\t\t      void *auth_tag) {\n  aes_cbc_ctx_t aes_ctx;\n  hmac_ctx_t hmac_ctx;\n  unsigned char enc_key[ENC_KEY_LEN];\n  unsigned char mac_key[MAC_KEY_LEN];\n  err_status_t status;\n\n  /* check if we're doing authentication only */\n  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {\n      \n      /* perform authentication only */\n\n  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {\n    \n    /*\n     * bad parameter - we expect either all three pointers to be NULL,\n     * or none of those pointers to be NULL \n     */\n    return err_status_fail;\n\n  } else {\n\n    /* derive encryption and authentication keys from the input key */\n    status = hmac_init(&hmac_ctx, key, KEY_LEN);\n    if (status) return status;\n    status = hmac_compute(&hmac_ctx, \"ENC\", 3, ENC_KEY_LEN, enc_key);\n    if (status) return status;\n\n    status = hmac_init(&hmac_ctx, key, KEY_LEN);\n    if (status) return status;\n    status = hmac_compute(&hmac_ctx, \"MAC\", 3, MAC_KEY_LEN, mac_key);\n    if (status) return status;\n\n\n    /* perform encryption and authentication */\n\n    /* set aes key */\n    status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt);\n    if (status) return status;\n\n    /* set iv */\n    status = crypto_get_random(iv, IV_LEN);  \n    if (status) return status; \n    status = aes_cbc_set_iv(&aes_ctx, iv);\n    \n    /* encrypt the opaque data  */\n    status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);\n    if (status) return status;\n\n    /* authenticate clear and opaque data */\n    status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);\n    if (status) return status;\n\n    status = hmac_start(&hmac_ctx);\n    if (status) return status;\n\n    status = hmac_update(&hmac_ctx, clear, clear_len);\n    if (status) return status;\n\n    status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);\n    if (status) return status;\n\n  }\n\n  return err_status_ok;\n}\n\nerr_status_t\naes_128_cbc_hmac_sha1_96_inv(void *key,            \n\t\t\t     void *clear,          \n\t\t\t     unsigned clear_len,       \n\t\t\t     void *iv,             \n\t\t\t     void *opaque,         \n\t\t\t     unsigned *opaque_len, \n\t\t\t     void *auth_tag) {\n  aes_cbc_ctx_t aes_ctx;\n  hmac_ctx_t hmac_ctx;\n  unsigned char enc_key[ENC_KEY_LEN];\n  unsigned char mac_key[MAC_KEY_LEN];\n  unsigned char tmp_tag[TAG_LEN];\n  unsigned char *tag = auth_tag;\n  err_status_t status;\n  int i;\n  \n  /* check if we're doing authentication only */\n  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {\n      \n      /* perform authentication only */\n\n  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {\n    \n    /*\n     * bad parameter - we expect either all three pointers to be NULL,\n     * or none of those pointers to be NULL \n     */\n    return err_status_fail;\n\n  } else {\n\n    /* derive encryption and authentication keys from the input key */\n    status = hmac_init(&hmac_ctx, key, KEY_LEN);\n    if (status) return status;\n    status = hmac_compute(&hmac_ctx, \"ENC\", 3, ENC_KEY_LEN, enc_key);\n    if (status) return status;\n\n    status = hmac_init(&hmac_ctx, key, KEY_LEN);\n    if (status) return status;\n    status = hmac_compute(&hmac_ctx, \"MAC\", 3, MAC_KEY_LEN, mac_key);\n    if (status) return status;\n\n    /* perform encryption and authentication */\n\n    /* set aes key */\n    status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt);\n    if (status) return status;\n\n    /* set iv */\n    status = rand_source_get_octet_string(iv, IV_LEN);  \n    if (status) return status; \n    status = aes_cbc_set_iv(&aes_ctx, iv);\n    \n    /* encrypt the opaque data  */\n    status = aes_cbc_nist_decrypt(&aes_ctx, opaque, opaque_len);\n    if (status) return status;\n\n    /* authenticate clear and opaque data */\n    status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);\n    if (status) return status;\n\n    status = hmac_start(&hmac_ctx);\n    if (status) return status;\n\n    status = hmac_update(&hmac_ctx, clear, clear_len);\n    if (status) return status;\n\n    status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, tmp_tag);\n    if (status) return status;\n\n    /* compare the computed tag with the one provided as input */\n    for (i=0; i < TAG_LEN; i++)\n      if (tmp_tag[i] != tag[i]) \n\treturn err_status_auth_fail; \n\n  }\n\n  return err_status_ok;\n}\n\n\n#define ENC 1\n\r\n// eVC4 declares DEBUG\r\n#undef DEBUG\r\n\n#define DEBUG 0\n\nerr_status_t\naes_128_cbc_hmac_sha1_96_enc(void *key,            \n\t\t\t     const void *clear,          \n\t\t\t     unsigned clear_len,       \n\t\t\t     void *iv,             \n\t\t\t     void *opaque,         \n\t\t\t     unsigned *opaque_len) {\n  aes_cbc_ctx_t aes_ctx;\n  hmac_ctx_t hmac_ctx;\n  unsigned char enc_key[ENC_KEY_LEN];\n  unsigned char mac_key[MAC_KEY_LEN];\n  unsigned char *auth_tag;\n  err_status_t status;\n\n  /* check if we're doing authentication only */\n  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {\n      \n      /* perform authentication only */\n\n  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {\n    \n    /*\n     * bad parameter - we expect either all three pointers to be NULL,\n     * or none of those pointers to be NULL \n     */\n    return err_status_fail;\n\n  } else {\n\n#if DEBUG\n    printf(\"ENC using key %s\\n\", octet_string_hex_string(key, KEY_LEN));\n#endif\n\n    /* derive encryption and authentication keys from the input key */\n    status = hmac_init(&hmac_ctx, key, KEY_LEN);\n    if (status) return status;\n    status = hmac_compute(&hmac_ctx, \"ENC\", 3, ENC_KEY_LEN, enc_key);\n    if (status) return status;\n\n    status = hmac_init(&hmac_ctx, key, KEY_LEN);\n    if (status) return status;\n    status = hmac_compute(&hmac_ctx, \"MAC\", 3, MAC_KEY_LEN, mac_key);\n    if (status) return status;\n\n\n    /* perform encryption and authentication */\n\n    /* set aes key */\n    status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt);\n    if (status) return status;\n\n    /* set iv */\n    status = rand_source_get_octet_string(iv, IV_LEN);  \n    if (status) return status; \n    status = aes_cbc_set_iv(&aes_ctx, iv);\n    if (status) return status;\n\n#if DEBUG\n    printf(\"plaintext len:  %d\\n\", *opaque_len);\n    printf(\"iv:         %s\\n\", octet_string_hex_string(iv, IV_LEN));\n    printf(\"plaintext:  %s\\n\", octet_string_hex_string(opaque, *opaque_len));\n#endif\n\n#if ENC    \n    /* encrypt the opaque data  */\n    status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);\n    if (status) return status;\n#endif\n\n#if DEBUG\n    printf(\"ciphertext len: %d\\n\", *opaque_len);\n    printf(\"ciphertext: %s\\n\", octet_string_hex_string(opaque, *opaque_len));\n#endif\n\n    /*\n     * authenticate clear and opaque data, then write the\n     * authentication tag to the location immediately following the\n     * ciphertext\n     */\n    status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);\n    if (status) return status;\n\n    status = hmac_start(&hmac_ctx);\n    if (status) return status;\n\n    status = hmac_update(&hmac_ctx, clear, clear_len);\n    if (status) return status;\n#if DEBUG\n    printf(\"hmac input: %s\\n\", \n\t   octet_string_hex_string(clear, clear_len));\n#endif\n    auth_tag = (unsigned char *)opaque;\n    auth_tag += *opaque_len;    \n    status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);\n    if (status) return status;\n#if DEBUG\n    printf(\"hmac input: %s\\n\", \n\t   octet_string_hex_string(opaque, *opaque_len));\n#endif\n    /* bump up the opaque_len to reflect the authentication tag */\n    *opaque_len += TAG_LEN;\n\n#if DEBUG\n    printf(\"prot data len:  %d\\n\", *opaque_len);\n    printf(\"prot data: %s\\n\", octet_string_hex_string(opaque, *opaque_len));\n#endif\n  }\n\n  return err_status_ok;\n}\n\nerr_status_t\naes_128_cbc_hmac_sha1_96_dec(void *key,            \n\t\t\t     const void *clear,          \n\t\t\t     unsigned clear_len,       \n\t\t\t     void *iv,             \n\t\t\t     void *opaque,         \n\t\t\t     unsigned *opaque_len) {\n  aes_cbc_ctx_t aes_ctx;\n  hmac_ctx_t hmac_ctx;\n  unsigned char enc_key[ENC_KEY_LEN];\n  unsigned char mac_key[MAC_KEY_LEN];\n  unsigned char tmp_tag[TAG_LEN];\n  unsigned char *auth_tag;\n  unsigned ciphertext_len;\n  err_status_t status;\n  int i;\n  \n  /* check if we're doing authentication only */\n  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {\n      \n      /* perform authentication only */\n\n  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {\n    \n    /*\n     * bad parameter - we expect either all three pointers to be NULL,\n     * or none of those pointers to be NULL \n     */\n    return err_status_fail;\n\n  } else {\n#if DEBUG\n    printf(\"DEC using key %s\\n\", octet_string_hex_string(key, KEY_LEN));\n#endif\n\n    /* derive encryption and authentication keys from the input key */\n    status = hmac_init(&hmac_ctx, key, KEY_LEN);\n    if (status) return status;\n    status = hmac_compute(&hmac_ctx, \"ENC\", 3, ENC_KEY_LEN, enc_key);\n    if (status) return status;\n\n    status = hmac_init(&hmac_ctx, key, KEY_LEN);\n    if (status) return status;\n    status = hmac_compute(&hmac_ctx, \"MAC\", 3, MAC_KEY_LEN, mac_key);\n    if (status) return status;\n\n#if DEBUG\n    printf(\"prot data len:  %d\\n\", *opaque_len);\n    printf(\"prot data: %s\\n\", octet_string_hex_string(opaque, *opaque_len));\n#endif\n\n    /* \n     * set the protected data length to that of the ciphertext, by\n     * subtracting out the length of the authentication tag \n     */\n    ciphertext_len = *opaque_len - TAG_LEN;\n\n#if DEBUG\n    printf(\"ciphertext len: %d\\n\", ciphertext_len);\n#endif    \n    /* verify the authentication tag */\n\n    /* \n     * compute the authentication tag for the clear and opaque data,\n     * and write it to a temporary location\n     */\n    status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);\n    if (status) return status;\n\n    status = hmac_start(&hmac_ctx);\n    if (status) return status;\n\n    status = hmac_update(&hmac_ctx, clear, clear_len);\n    if (status) return status;\n\n#if DEBUG\n    printf(\"hmac input: %s\\n\", \n\t   octet_string_hex_string(clear, clear_len));\n#endif\n\n    status = hmac_compute(&hmac_ctx, opaque, ciphertext_len, TAG_LEN, tmp_tag);\n    if (status) return status;\n\n#if DEBUG\n    printf(\"hmac input: %s\\n\", \n\t   octet_string_hex_string(opaque, ciphertext_len));\n#endif\n\n    /* \n     * compare the computed tag with the one provided as input (which\n     * immediately follows the ciphertext)\n     */\n    auth_tag = (unsigned char *)opaque;\n    auth_tag += ciphertext_len;  \n#if DEBUG\n    printf(\"auth_tag: %s\\n\", octet_string_hex_string(auth_tag, TAG_LEN));\n    printf(\"tmp_tag:  %s\\n\", octet_string_hex_string(tmp_tag, TAG_LEN));\n#endif\n    for (i=0; i < TAG_LEN; i++) {\n      if (tmp_tag[i] != auth_tag[i]) \n\treturn err_status_auth_fail; \n    }\n\n    /* bump down the opaque_len to reflect the authentication tag */\n    *opaque_len -= TAG_LEN;\n\n    /* decrypt the confidential data */\n    status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt);\n    if (status) return status;\n    status = aes_cbc_set_iv(&aes_ctx, iv);\n    if (status) return status;\n\n#if DEBUG\n    printf(\"ciphertext: %s\\n\", octet_string_hex_string(opaque, *opaque_len));\n    printf(\"iv:         %s\\n\", octet_string_hex_string(iv, IV_LEN));\n#endif\n\n#if ENC\n    status = aes_cbc_nist_decrypt(&aes_ctx, opaque, &ciphertext_len);\n    if (status) return status;\n#endif\n\n#if DEBUG\n    printf(\"plaintext len:  %d\\n\", ciphertext_len);\n    printf(\"plaintext:  %s\\n\", \n\t   octet_string_hex_string(opaque, ciphertext_len));\n#endif\n\n    /* indicate the length of the plaintext  */\n    *opaque_len = ciphertext_len;\n  }\n\n  return err_status_ok;\n}\n\ncryptoalg_ctx_t cryptoalg_ctx = {\n  aes_128_cbc_hmac_sha1_96_enc,\n  aes_128_cbc_hmac_sha1_96_dec,\n  KEY_LEN,\n  IV_LEN,\n  TAG_LEN,\n  MAX_EXPAND,\n};\n\ncryptoalg_t cryptoalg = &cryptoalg_ctx;\n\n#define NULL_TAG_LEN 12\n\nerr_status_t\nnull_enc(void *key,            \n\t const void *clear,          \n\t unsigned clear_len,       \n\t void *iv,             \n\t void *opaque,         \n\t unsigned *opaque_len) {\n  int i;\n  unsigned char *auth_tag;\n  unsigned char *init_vec = iv;\n\n  /* check if we're doing authentication only */\n  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {\n      \n      /* perform authentication only */\n\n  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {\n    \n    /*\n     * bad parameter - we expect either all three pointers to be NULL,\n     * or none of those pointers to be NULL \n     */\n    return err_status_fail;\n\n  } else {\n\n#if DEBUG\n    printf(\"NULL ENC using key %s\\n\", octet_string_hex_string(key, KEY_LEN));\n    printf(\"NULL_TAG_LEN:  %d\\n\", NULL_TAG_LEN);\n    printf(\"plaintext len:  %d\\n\", *opaque_len);\n#endif\n    for (i=0; i < IV_LEN; i++)\n      init_vec[i] = i + (i * 16);\n#if DEBUG\n    printf(\"iv:                %s\\n\", \n\t   octet_string_hex_string(iv, IV_LEN));\n    printf(\"plaintext:         %s\\n\", \n\t   octet_string_hex_string(opaque, *opaque_len));\n#endif\n    auth_tag = opaque;\n    auth_tag += *opaque_len;\n    for (i=0; i < NULL_TAG_LEN; i++)\n      auth_tag[i] = i + (i * 16);\n    *opaque_len += NULL_TAG_LEN;\n#if DEBUG\n    printf(\"protected data len: %d\\n\", *opaque_len);\n    printf(\"protected data:    %s\\n\", \n\t   octet_string_hex_string(opaque, *opaque_len));\n#endif\n\n  }\n\n  return err_status_ok;\n}\n\nerr_status_t\nnull_dec(void *key,            \n\t const void *clear,          \n\t unsigned clear_len,       \n\t void *iv,             \n\t void *opaque,         \n\t unsigned *opaque_len) {\n  unsigned char *auth_tag;\n  \n  /* check if we're doing authentication only */\n  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {\n      \n      /* perform authentication only */\n\n  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {\n    \n    /*\n     * bad parameter - we expect either all three pointers to be NULL,\n     * or none of those pointers to be NULL \n     */\n    return err_status_fail;\n\n  } else {\n\n#if DEBUG\n    printf(\"NULL DEC using key %s\\n\", octet_string_hex_string(key, KEY_LEN));\n\n    printf(\"protected data len: %d\\n\", *opaque_len);\n    printf(\"protected data:    %s\\n\", \n\t   octet_string_hex_string(opaque, *opaque_len));\n#endif\n    auth_tag = opaque;\n    auth_tag += (*opaque_len - NULL_TAG_LEN);\n#if DEBUG\n    printf(\"iv:         %s\\n\", octet_string_hex_string(iv, IV_LEN));\n#endif\n    *opaque_len -= NULL_TAG_LEN;\n#if DEBUG\n    printf(\"plaintext len:  %d\\n\", *opaque_len);\n    printf(\"plaintext:  %s\\n\", \n\t   octet_string_hex_string(opaque, *opaque_len));\n#endif\n  }\n\n  return err_status_ok;\n}\n\ncryptoalg_ctx_t null_cryptoalg_ctx = {\n  null_enc,\n  null_dec,\n  KEY_LEN,\n  IV_LEN,\n  NULL_TAG_LEN,\n  MAX_EXPAND,\n};\n\ncryptoalg_t null_cryptoalg = &null_cryptoalg_ctx;\n\nint\ncryptoalg_get_id(cryptoalg_t c) {\n  if (c == cryptoalg)\n    return 1;\n  return 0;\n}\n\ncryptoalg_t \ncryptoalg_find_by_id(int id) {\n  switch(id) {\n  case 1:\n    return cryptoalg;\n  default:\n    break;\n  }\n  return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/cipher/aes.c",
    "content": "/*\n * aes.c\n *\n * An implemnetation of the AES block cipher.\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#include \"aes.h\"\n#include \"err.h\"\n\n/* \n * we use the tables T0, T1, T2, T3, and T4 to compute AES, and \n * the tables U0, U1, U2, and U4 to compute its inverse\n *\n * different tables are used on little-endian (Intel, VMS) and\n * big-endian processors (everything else)\n *\n * these tables are computed using the program tables/aes_tables; use\n * this program to generate different tables for porting or\n * optimization on a different platform\n */\n\n#ifndef WORDS_BIGENDIAN\n\nstatic uint32_t T0[256] = {\n  0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, \n  0xdf2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, \n  0x50303060, 0x3010102, 0xa96767ce, 0x7d2b2b56, \n  0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, \n  0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, \n  0x15fafaef, 0xeb5959b2, 0xc947478e, 0xbf0f0fb, \n  0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, \n  0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, \n  0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, \n  0x5a36366c, 0x413f3f7e, 0x2f7f7f5, 0x4fcccc83, \n  0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x8f1f1f9, \n  0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, \n  0xc040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, \n  0x28181830, 0xa1969637, 0xf05050a, 0xb59a9a2f, \n  0x907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, \n  0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, \n  0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, \n  0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, \n  0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, \n  0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, \n  0xf55353a6, 0x68d1d1b9, 0x0, 0x2cededc1, \n  0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, \n  0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, \n  0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, \n  0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, \n  0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, \n  0xcf45458a, 0x10f9f9e9, 0x6020204, 0x817f7ffe, \n  0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, \n  0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, \n  0xad92923f, 0xbc9d9d21, 0x48383870, 0x4f5f5f1, \n  0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, \n  0x30101020, 0x1affffe5, 0xef3f3fd, 0x6dd2d2bf, \n  0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, \n  0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, \n  0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, \n  0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, \n  0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, \n  0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, \n  0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, \n  0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, \n  0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, \n  0xdb494992, 0xa06060c, 0x6c242448, 0xe45c5cb8, \n  0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, \n  0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, \n  0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, \n  0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, \n  0xb46c6cd8, 0xfa5656ac, 0x7f4f4f3, 0x25eaeacf, \n  0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, \n  0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, \n  0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, \n  0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, \n  0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, \n  0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, \n  0xd8484890, 0x5030306, 0x1f6f6f7, 0x120e0e1c, \n  0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, \n  0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, \n  0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, \n  0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, \n  0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, \n  0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, \n  0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, \n  0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, \n  0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, \n  0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c, \n};\n\nstatic uint32_t T1[256] = {\n  0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, \n  0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, \n  0x30306050, 0x1010203, 0x6767cea9, 0x2b2b567d, \n  0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, \n  0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, \n  0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, \n  0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, \n  0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, \n  0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, \n  0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, \n  0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, \n  0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, \n  0x404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, \n  0x18183028, 0x969637a1, 0x5050a0f, 0x9a9a2fb5, \n  0x7070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, \n  0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, \n  0x909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, \n  0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, \n  0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, \n  0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, \n  0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, \n  0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, \n  0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, \n  0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, \n  0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, \n  0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, \n  0x45458acf, 0xf9f9e910, 0x2020406, 0x7f7ffe81, \n  0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, \n  0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, \n  0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, \n  0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, \n  0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, \n  0xcdcd814c, 0xc0c1814, 0x13132635, 0xececc32f, \n  0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, \n  0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, \n  0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, \n  0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, \n  0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, \n  0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, \n  0xdedea779, 0x5e5ebce2, 0xb0b161d, 0xdbdbad76, \n  0xe0e0db3b, 0x32326456, 0x3a3a744e, 0xa0a141e, \n  0x494992db, 0x6060c0a, 0x2424486c, 0x5c5cb8e4, \n  0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, \n  0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, \n  0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, \n  0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, \n  0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, \n  0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x8081018, \n  0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, \n  0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, \n  0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, \n  0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, \n  0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, \n  0x484890d8, 0x3030605, 0xf6f6f701, 0xe0e1c12, \n  0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, \n  0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, \n  0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, \n  0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, \n  0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, \n  0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, \n  0x8c8c038f, 0xa1a159f8, 0x89890980, 0xd0d1a17, \n  0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, \n  0x414182c3, 0x999929b0, 0x2d2d5a77, 0xf0f1e11, \n  0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a, \n};\n\nstatic uint32_t T2[256] = {\n  0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, \n  0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, \n  0x30605030, 0x1020301, 0x67cea967, 0x2b567d2b, \n  0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, \n  0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, \n  0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, \n  0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, \n  0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, \n  0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, \n  0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, \n  0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, \n  0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, \n  0x4080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, \n  0x18302818, 0x9637a196, 0x50a0f05, 0x9a2fb59a, \n  0x70e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, \n  0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, \n  0x9121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, \n  0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, \n  0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, \n  0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, \n  0x53a6f553, 0xd1b968d1, 0x0, 0xedc12ced, \n  0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, \n  0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, \n  0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, \n  0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, \n  0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, \n  0x458acf45, 0xf9e910f9, 0x2040602, 0x7ffe817f, \n  0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, \n  0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, \n  0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, \n  0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, \n  0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, \n  0xcd814ccd, 0xc18140c, 0x13263513, 0xecc32fec, \n  0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, \n  0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, \n  0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, \n  0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, \n  0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, \n  0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, \n  0xdea779de, 0x5ebce25e, 0xb161d0b, 0xdbad76db, \n  0xe0db3be0, 0x32645632, 0x3a744e3a, 0xa141e0a, \n  0x4992db49, 0x60c0a06, 0x24486c24, 0x5cb8e45c, \n  0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, \n  0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, \n  0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, \n  0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, \n  0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, \n  0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x8101808, \n  0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, \n  0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, \n  0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, \n  0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, \n  0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, \n  0x4890d848, 0x3060503, 0xf6f701f6, 0xe1c120e, \n  0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, \n  0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, \n  0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, \n  0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, \n  0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, \n  0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, \n  0x8c038f8c, 0xa159f8a1, 0x89098089, 0xd1a170d, \n  0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, \n  0x4182c341, 0x9929b099, 0x2d5a772d, 0xf1e110f, \n  0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16, \n};\n\nstatic uint32_t T3[256] = {\n  0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, \n  0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, \n  0x60503030, 0x2030101, 0xcea96767, 0x567d2b2b, \n  0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, \n  0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, \n  0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, \n  0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, \n  0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, \n  0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, \n  0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, \n  0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, \n  0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, \n  0x80c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, \n  0x30281818, 0x37a19696, 0xa0f0505, 0x2fb59a9a, \n  0xe090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, \n  0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, \n  0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, \n  0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, \n  0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, \n  0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, \n  0xa6f55353, 0xb968d1d1, 0x0, 0xc12ceded, \n  0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, \n  0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, \n  0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, \n  0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, \n  0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, \n  0x8acf4545, 0xe910f9f9, 0x4060202, 0xfe817f7f, \n  0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, \n  0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x58a8f8f, \n  0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, \n  0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, \n  0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, \n  0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, \n  0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, \n  0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, \n  0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, \n  0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, \n  0x44662222, 0x547e2a2a, 0x3bab9090, 0xb838888, \n  0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, \n  0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, \n  0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, \n  0x92db4949, 0xc0a0606, 0x486c2424, 0xb8e45c5c, \n  0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, \n  0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, \n  0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, \n  0x18c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, \n  0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, \n  0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, \n  0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, \n  0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, \n  0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, \n  0x96dd4b4b, 0x61dcbdbd, 0xd868b8b, 0xf858a8a, \n  0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, \n  0x90d84848, 0x6050303, 0xf701f6f6, 0x1c120e0e, \n  0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, \n  0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, \n  0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, \n  0xd2bb6969, 0xa970d9d9, 0x7898e8e, 0x33a79494, \n  0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, \n  0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, \n  0x38f8c8c, 0x59f8a1a1, 0x9808989, 0x1a170d0d, \n  0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, \n  0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, \n  0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616, \n};\n\nstatic uint32_t U0[256] = {\n  0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, \n  0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, \n  0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, \n  0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, \n  0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, \n  0x2752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, \n  0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, \n  0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, \n  0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, \n  0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, \n  0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, \n  0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, \n  0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, \n  0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, \n  0x728ebb2, 0x3c2b52f, 0x9a7bc586, 0xa50837d3, \n  0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, \n  0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, \n  0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, \n  0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, \n  0x39ec830b, 0xaaef6040, 0x69f715e, 0x51106ebd, \n  0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, \n  0xb58d5491, 0x55dc471, 0x6fd40604, 0xff155060, \n  0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, \n  0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, \n  0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x0, \n  0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, \n  0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, \n  0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, \n  0xb1670a0c, 0xfe75793, 0xd296eeb4, 0x9e919b1b, \n  0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, \n  0xaba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, \n  0xb0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, \n  0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, \n  0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, \n  0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, \n  0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, \n  0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, \n  0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, \n  0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, \n  0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, \n  0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, \n  0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, \n  0xe49d3a2c, 0xd927850, 0x9bcc5f6a, 0x62467e54, \n  0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, \n  0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, \n  0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, \n  0x97826cd, 0xf418596e, 0x1b79aec, 0xa89a4f83, \n  0x656e95e6, 0x7ee6ffaa, 0x8cfbc21, 0xe6e815ef, \n  0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, \n  0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, \n  0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, \n  0x4a9804f1, 0xf7daec41, 0xe50cd7f, 0x2ff69117, \n  0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, \n  0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, \n  0x4ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, \n  0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, \n  0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, \n  0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, \n  0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, \n  0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, \n  0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, \n  0x72c31d16, 0xc25e2bc, 0x8b493c28, 0x41950dff, \n  0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, \n  0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0, \n};\n\nstatic uint32_t U1[256] = {\n  0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, \n  0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x3e34b93, \n  0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, \n  0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f, \n  0x5ab1de49, 0x1bba2567, 0xeea4598, 0xc0fe5de1, \n  0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, \n  0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, \n  0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44, \n  0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd, \n  0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, \n  0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, \n  0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994, \n  0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, \n  0xd373ab23, 0x24b72e2, 0x8f1fe357, 0xab55662a, \n  0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x837d3a5, \n  0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, \n  0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, \n  0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a, \n  0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, \n  0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, \n  0x8a213ef9, 0x6dd963d, 0x53eddae, 0xbde64d46, \n  0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff, \n  0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, \n  0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db, \n  0xa7ca147, 0xf427ce9, 0x1e84f8c9, 0x0, \n  0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, \n  0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627, \n  0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, \n  0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e, \n  0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, \n  0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, \n  0xd090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, \n  0x19f15785, 0x775af4c, 0xdd99eebb, 0x607fa3fd, \n  0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, \n  0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, \n  0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, \n  0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, \n  0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0, \n  0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, \n  0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, \n  0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0xbd49836, \n  0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, \n  0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, \n  0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5, \n  0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, \n  0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, \n  0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8, \n  0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6, \n  0x9be7bad9, 0x366f4ace, 0x99fead4, 0x7cb029d6, \n  0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, \n  0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, \n  0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, \n  0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x496e4df, \n  0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f, \n  0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, \n  0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, \n  0x61d79a8c, 0xca1377a, 0x14f8598e, 0x3c13eb89, \n  0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c, \n  0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, \n  0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, \n  0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, \n  0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41, \n  0x1a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490, \n  0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042, \n};\n\nstatic uint32_t U2[256] = {\n  0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, \n  0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303, \n  0x302055fa, 0x76adf66d, 0xcc889176, 0x2f5254c, \n  0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3, \n  0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, \n  0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, \n  0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, \n  0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8, \n  0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71, \n  0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, \n  0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, \n  0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x8f9942b, \n  0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, \n  0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab, \n  0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, \n  0x2830f287, 0xbf23b2a5, 0x302ba6a, 0x16ed5c82, \n  0xcf8a2b1c, 0x79a792b4, 0x7f3f0f2, 0x694ea1e2, \n  0xda65cdf4, 0x506d5be, 0x34d11f62, 0xa6c48afe, \n  0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, \n  0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, \n  0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, \n  0x5491b58d, 0xc471055d, 0x6046fd4, 0x5060ff15, \n  0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, \n  0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee, \n  0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x0, \n  0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, \n  0xefdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739, \n  0xf0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, \n  0xa0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91, \n  0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, \n  0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, \n  0x90e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, \n  0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60, \n  0x1f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, \n  0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, \n  0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, \n  0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, \n  0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3, \n  0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, \n  0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, \n  0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, \n  0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf, \n  0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, \n  0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af, \n  0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, \n  0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, \n  0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a, \n  0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8, \n  0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, \n  0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, \n  0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, \n  0x4f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, \n  0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, \n  0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51, \n  0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0xbfb2e41, \n  0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, \n  0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, \n  0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, \n  0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, \n  0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, \n  0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, \n  0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0xdff4195, \n  0xa8397101, 0xc08deb3, 0xb4d89ce4, 0x566490c1, \n  0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257, \n};\n\nstatic uint32_t U3[256] = {\n  0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, \n  0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3, \n  0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, \n  0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, \n  0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, \n  0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, \n  0x3e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, \n  0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9, \n  0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9, \n  0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, \n  0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, \n  0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, \n  0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, \n  0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55, \n  0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, \n  0x30f28728, 0x23b2a5bf, 0x2ba6a03, 0xed5c8216, \n  0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, \n  0x65cdf4da, 0x6d5be05, 0xd11f6234, 0xc48afea6, \n  0x349d532e, 0xa2a055f3, 0x532e18a, 0xa475ebf6, \n  0xb39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, \n  0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, \n  0x91b58d54, 0x71055dc4, 0x46fd406, 0x60ff1550, \n  0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, \n  0xb0bd42e8, 0x7888b89, 0xe7385b19, 0x79dbeec8, \n  0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x0, \n  0x9838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, \n  0xfdfbff0e, 0xf563885, 0x3d1ed5ae, 0x3627392d, \n  0xa64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, \n  0xcb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b, \n  0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, \n  0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, \n  0xe0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, \n  0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f, \n  0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, \n  0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, \n  0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, \n  0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, \n  0x1d4b2f9e, 0xdcf330b2, 0xdec5286, 0x77d0e3c1, \n  0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, \n  0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, \n  0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, \n  0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad, \n  0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, \n  0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3, \n  0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, \n  0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, \n  0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f, \n  0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815, \n  0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, \n  0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, \n  0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, \n  0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, \n  0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, \n  0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165, \n  0x9d04ea5e, 0x15d358c, 0xfa737487, 0xfb2e410b, \n  0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, \n  0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, \n  0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, \n  0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, \n  0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, \n  0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, \n  0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d, \n  0x397101a8, 0x8deb30c, 0xd89ce4b4, 0x6490c156, \n  0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8, \n};\n\n#else /* assume big endian */\n\nstatic uint32_t T0[256] = {\n  0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, \n  0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, \n  0x60303050, 0x2010103, 0xce6767a9, 0x562b2b7d, \n  0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, \n  0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, \n  0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, \n  0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, \n  0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, \n  0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, \n  0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, \n  0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, \n  0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, \n  0x804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, \n  0x30181828, 0x379696a1, 0xa05050f, 0x2f9a9ab5, \n  0xe070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, \n  0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, \n  0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, \n  0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, \n  0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, \n  0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, \n  0xa65353f5, 0xb9d1d168, 0x0, 0xc1eded2c, \n  0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, \n  0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, \n  0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, \n  0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, \n  0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, \n  0x8a4545cf, 0xe9f9f910, 0x4020206, 0xfe7f7f81, \n  0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, \n  0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x58f8f8a, \n  0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, \n  0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, \n  0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, \n  0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, \n  0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, \n  0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, \n  0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, \n  0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, \n  0x44222266, 0x542a2a7e, 0x3b9090ab, 0xb888883, \n  0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, \n  0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, \n  0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, \n  0x924949db, 0xc06060a, 0x4824246c, 0xb85c5ce4, \n  0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, \n  0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, \n  0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, \n  0x18d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, \n  0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, \n  0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, \n  0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, \n  0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, \n  0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, \n  0x964b4bdd, 0x61bdbddc, 0xd8b8b86, 0xf8a8a85, \n  0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, \n  0x904848d8, 0x6030305, 0xf7f6f601, 0x1c0e0e12, \n  0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, \n  0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, \n  0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, \n  0xd26969bb, 0xa9d9d970, 0x78e8e89, 0x339494a7, \n  0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, \n  0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, \n  0x38c8c8f, 0x59a1a1f8, 0x9898980, 0x1a0d0d17, \n  0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, \n  0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, \n  0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a, \n};\n\nstatic uint32_t T1[256] = {\n  0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, \n  0xdfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5, \n  0x50603030, 0x3020101, 0xa9ce6767, 0x7d562b2b, \n  0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, \n  0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, \n  0x15effafa, 0xebb25959, 0xc98e4747, 0xbfbf0f0, \n  0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, \n  0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0, \n  0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, \n  0x5a6c3636, 0x417e3f3f, 0x2f5f7f7, 0x4f83cccc, \n  0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x8f9f1f1, \n  0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515, \n  0xc080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, \n  0x28301818, 0xa1379696, 0xf0a0505, 0xb52f9a9a, \n  0x90e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, \n  0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, \n  0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, \n  0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0, \n  0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, \n  0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484, \n  0xf5a65353, 0x68b9d1d1, 0x0, 0x2cc1eded, \n  0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, \n  0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, \n  0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf, \n  0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, \n  0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585, \n  0xcf8a4545, 0x10e9f9f9, 0x6040202, 0x81fe7f7f, \n  0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, \n  0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, \n  0xad3f9292, 0xbc219d9d, 0x48703838, 0x4f1f5f5, \n  0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, \n  0x30201010, 0x1ae5ffff, 0xefdf3f3, 0x6dbfd2d2, \n  0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, \n  0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, \n  0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, \n  0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373, \n  0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, \n  0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888, \n  0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, \n  0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, \n  0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, \n  0xdb924949, 0xa0c0606, 0x6c482424, 0xe4b85c5c, \n  0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, \n  0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979, \n  0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, \n  0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, \n  0xb4d86c6c, 0xfaac5656, 0x7f3f4f4, 0x25cfeaea, \n  0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808, \n  0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, \n  0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6, \n  0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, \n  0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, \n  0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, \n  0xd8904848, 0x5060303, 0x1f7f6f6, 0x121c0e0e, \n  0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, \n  0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e, \n  0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, \n  0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, \n  0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, \n  0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf, \n  0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, \n  0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868, \n  0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, \n  0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616, \n};\n\nstatic uint32_t T2[256] = {\n  0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, \n  0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5, \n  0x30506030, 0x1030201, 0x67a9ce67, 0x2b7d562b, \n  0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, \n  0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, \n  0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0, \n  0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, \n  0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0, \n  0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, \n  0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, \n  0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, \n  0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15, \n  0x40c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, \n  0x18283018, 0x96a13796, 0x50f0a05, 0x9ab52f9a, \n  0x7090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, \n  0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, \n  0x91b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, \n  0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0, \n  0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, \n  0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384, \n  0x53f5a653, 0xd168b9d1, 0x0, 0xed2cc1ed, \n  0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, \n  0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, \n  0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf, \n  0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, \n  0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185, \n  0x45cf8a45, 0xf910e9f9, 0x2060402, 0x7f81fe7f, \n  0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, \n  0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, \n  0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5, \n  0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, \n  0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2, \n  0xcd4c81cd, 0xc14180c, 0x13352613, 0xec2fc3ec, \n  0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, \n  0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, \n  0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673, \n  0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, \n  0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88, \n  0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, \n  0xde79a7de, 0x5ee2bc5e, 0xb1d160b, 0xdb76addb, \n  0xe03bdbe0, 0x32566432, 0x3a4e743a, 0xa1e140a, \n  0x49db9249, 0x60a0c06, 0x246c4824, 0x5ce4b85c, \n  0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, \n  0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279, \n  0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, \n  0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, \n  0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, \n  0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x8181008, \n  0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, \n  0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6, \n  0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, \n  0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, \n  0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, \n  0x48d89048, 0x3050603, 0xf601f7f6, 0xe121c0e, \n  0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, \n  0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e, \n  0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, \n  0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, \n  0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, \n  0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df, \n  0x8c8f038c, 0xa1f859a1, 0x89800989, 0xd171a0d, \n  0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068, \n  0x41c38241, 0x99b02999, 0x2d775a2d, 0xf111e0f, \n  0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16, \n};\n\nstatic uint32_t T3[256] = {\n  0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, \n  0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491, \n  0x30305060, 0x1010302, 0x6767a9ce, 0x2b2b7d56, \n  0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, \n  0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, \n  0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb, \n  0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, \n  0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b, \n  0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, \n  0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, \n  0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, \n  0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a, \n  0x4040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, \n  0x18182830, 0x9696a137, 0x5050f0a, 0x9a9ab52f, \n  0x707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, \n  0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, \n  0x9091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, \n  0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b, \n  0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, \n  0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713, \n  0x5353f5a6, 0xd1d168b9, 0x0, 0xeded2cc1, \n  0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, \n  0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, \n  0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85, \n  0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, \n  0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411, \n  0x4545cf8a, 0xf9f910e9, 0x2020604, 0x7f7f81fe, \n  0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, \n  0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, \n  0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1, \n  0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, \n  0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf, \n  0xcdcd4c81, 0xc0c1418, 0x13133526, 0xecec2fc3, \n  0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, \n  0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, \n  0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6, \n  0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, \n  0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b, \n  0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, \n  0xdede79a7, 0x5e5ee2bc, 0xb0b1d16, 0xdbdb76ad, \n  0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0xa0a1e14, \n  0x4949db92, 0x6060a0c, 0x24246c48, 0x5c5ce4b8, \n  0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, \n  0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2, \n  0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, \n  0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, \n  0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, \n  0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x8081810, \n  0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, \n  0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197, \n  0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, \n  0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, \n  0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, \n  0x4848d890, 0x3030506, 0xf6f601f7, 0xe0e121c, \n  0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, \n  0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927, \n  0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, \n  0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, \n  0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, \n  0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5, \n  0x8c8c8f03, 0xa1a1f859, 0x89898009, 0xd0d171a, \n  0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0, \n  0x4141c382, 0x9999b029, 0x2d2d775a, 0xf0f111e, \n  0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c, \n};\n\nstatic uint32_t U0[256] = {\n  0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, \n  0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, \n  0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, \n  0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, \n  0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, \n  0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, \n  0x38f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, \n  0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, \n  0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, \n  0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, \n  0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, \n  0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, \n  0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, \n  0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, \n  0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, \n  0x302887f2, 0x23bfa5b2, 0x2036aba, 0xed16825c, \n  0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, \n  0x65daf4cd, 0x605bed5, 0xd134621f, 0xc4a6fe8a, \n  0x342e539d, 0xa2f355a0, 0x58ae132, 0xa4f6eb75, \n  0xb83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, \n  0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, \n  0x91548db5, 0x71c45d05, 0x406d46f, 0x605015ff, \n  0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, \n  0xb0e842bd, 0x7898b88, 0xe7195b38, 0x79c8eedb, \n  0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x0, \n  0x9808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, \n  0xfd0efffb, 0xf853856, 0x3daed51e, 0x362d3927, \n  0xa0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, \n  0xc0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, \n  0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, \n  0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, \n  0xe090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, \n  0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, \n  0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, \n  0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, \n  0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, \n  0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, \n  0x1d9e2f4b, 0xdcb230f3, 0xd8652ec, 0x77c1e3d0, \n  0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, \n  0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, \n  0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, \n  0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, \n  0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, \n  0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, \n  0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, \n  0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, \n  0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, \n  0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, \n  0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, \n  0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, \n  0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, \n  0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, \n  0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, \n  0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, \n  0x9d5eea04, 0x18c355d, 0xfa877473, 0xfb0b412e, \n  0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, \n  0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, \n  0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, \n  0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, \n  0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, \n  0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, \n  0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, \n  0x39a80171, 0x80cb3de, 0xd8b4e49c, 0x6456c190, \n  0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742\n};\n\nstatic uint32_t U1[256] = {\n  0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, \n  0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303, \n  0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, \n  0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3, \n  0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, \n  0x2c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9, \n  0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, \n  0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8, \n  0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, \n  0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a, \n  0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, \n  0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b, \n  0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, \n  0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab, \n  0x7b2eb28, 0x32fb5c2, 0x9a86c57b, 0xa5d33708, \n  0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682, \n  0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, \n  0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe, \n  0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, \n  0x390b83ec, 0xaa4060ef, 0x65e719f, 0x51bd6e10, \n  0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, \n  0xb591548d, 0x571c45d, 0x6f0406d4, 0xff605015, \n  0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, \n  0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee, \n  0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x0, \n  0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72, \n  0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, \n  0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e, \n  0xb10c0a67, 0xf9357e7, 0xd2b4ee96, 0x9e1b9b91, \n  0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a, \n  0xae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, \n  0xb0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9, \n  0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, \n  0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e, \n  0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, \n  0xcad731dc, 0x10426385, 0x40139722, 0x2084c611, \n  0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, \n  0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3, \n  0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, \n  0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390, \n  0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, \n  0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf, \n  0xe42c3a9d, 0xd507892, 0x9b6a5fcc, 0x62547e46, \n  0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af, \n  0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, \n  0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb, \n  0x9cd2678, 0xf46e5918, 0x1ec9ab7, 0xa8834f9a, \n  0x65e6956e, 0x7eaaffe6, 0x821bccf, 0xe6ef15e8, \n  0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, \n  0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266, \n  0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, \n  0x4af10498, 0xf741ecda, 0xe7fcd50, 0x2f1791f6, \n  0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, \n  0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551, \n  0x49d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, \n  0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647, \n  0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, \n  0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1, \n  0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, \n  0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db, \n  0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, \n  0x72161dc3, 0xcbce225, 0x8b283c49, 0x41ff0d95, \n  0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, \n  0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857\n};\n\nstatic uint32_t U2[256] = {\n  0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, \n  0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x3934be3, \n  0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, \n  0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562, \n  0x5a49deb1, 0x1b6725ba, 0xe9845ea, 0xc0e15dfe, \n  0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3, \n  0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, \n  0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9, \n  0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, \n  0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce, \n  0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, \n  0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908, \n  0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, \n  0xd323ab73, 0x2e2724b, 0x8f57e31f, 0xab2a6655, \n  0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x8a5d337, \n  0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16, \n  0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, \n  0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6, \n  0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, \n  0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e, \n  0x8af93e21, 0x63d96dd, 0x5aedd3e, 0xbd464de6, \n  0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050, \n  0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, \n  0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8, \n  0xa47a17c, 0xfe97c42, 0x1ec9f884, 0x0, \n  0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a, \n  0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, \n  0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436, \n  0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, \n  0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12, \n  0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, \n  0xd0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e, \n  0x198557f1, 0x74caf75, 0xddbbee99, 0x60fda37f, \n  0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb, \n  0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, \n  0xdccad731, 0x85104263, 0x22401397, 0x112084c6, \n  0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, \n  0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1, \n  0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, \n  0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233, \n  0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0xb3698d4, \n  0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad, \n  0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, \n  0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3, \n  0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, \n  0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b, \n  0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, \n  0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15, \n  0x9bd9bae7, 0x36ce4a6f, 0x9d4ea9f, 0x7cd629b0, \n  0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2, \n  0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, \n  0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791, \n  0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x4dfe496, \n  0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665, \n  0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, \n  0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6, \n  0x618c9ad7, 0xc7a37a1, 0x148e59f8, 0x3c89eb13, \n  0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47, \n  0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, \n  0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844, \n  0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, \n  0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d, \n  0x17139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, \n  0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8 \n};\n\nstatic uint32_t U3[256] = {\n  0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, \n  0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b, \n  0x30fa5520, 0x766df6ad, 0xcc769188, 0x24c25f5, \n  0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, \n  0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, \n  0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b, \n  0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, \n  0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e, \n  0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, \n  0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, \n  0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, \n  0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x82b94f9, \n  0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, \n  0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66, \n  0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, \n  0x2887f230, 0xbfa5b223, 0x36aba02, 0x16825ced, \n  0xcf1c2b8a, 0x79b492a7, 0x7f2f0f3, 0x69e2a14e, \n  0xdaf4cd65, 0x5bed506, 0x34621fd1, 0xa6fe8ac4, \n  0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, \n  0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd, \n  0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, \n  0x548db591, 0xc45d0571, 0x6d46f04, 0x5015ff60, \n  0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, \n  0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79, \n  0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x0, \n  0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c, \n  0xefffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, \n  0xfd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, \n  0xa67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, \n  0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c, \n  0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, \n  0x90d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814, \n  0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, \n  0x1269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, \n  0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, \n  0x31dccad7, 0x63851042, 0x97224013, 0xc6112084, \n  0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, \n  0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077, \n  0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, \n  0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, \n  0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, \n  0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f, \n  0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, \n  0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582, \n  0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, \n  0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, \n  0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, \n  0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef, \n  0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, \n  0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035, \n  0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, \n  0x4984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, \n  0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, \n  0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46, \n  0x5eea049d, 0x8c355d01, 0x877473fa, 0xb412efb, \n  0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d, \n  0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, \n  0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, \n  0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, \n  0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678, \n  0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, \n  0x1dc37216, 0xe2250cbc, 0x3c498b28, 0xd9541ff, \n  0xa8017139, 0xcb3de08, 0xb4e49cd8, 0x56c19064, \n  0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0 \n};\n\n#endif\n\n/* \n * the following tables (aes_sbox, aes_inv_sbox, T4, U4) are\n * endian-neutral \n */\n\nstatic uint8_t\naes_sbox[256] = {\n  0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, \n  0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, \n  0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, \n  0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, \n  0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, \n  0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, \n  0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, \n  0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, \n  0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, \n  0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, \n  0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, \n  0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, \n  0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, \n  0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, \n  0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, \n  0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, \n  0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, \n  0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, \n  0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, \n  0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, \n  0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, \n  0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, \n  0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, \n  0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, \n  0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, \n  0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, \n  0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, \n  0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, \n  0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, \n  0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, \n  0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, \n  0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 \n};\n\n#ifndef CPU_RISC\nstatic uint8_t\naes_inv_sbox[256] = {\n  0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, \n  0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,\n  0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,\n  0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,\n  0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, \n  0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,\n  0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,\n  0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,\n  0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, \n  0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,\n  0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, \n  0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,\n  0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, \n  0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,\n  0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, \n  0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,\n  0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, \n  0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,\n  0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, \n  0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,\n  0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, \n  0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,\n  0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, \n  0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,\n  0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, \n  0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,\n  0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, \n  0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,\n  0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, \n  0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,\n  0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, \n  0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d\n};\n#endif /* ! CPU_RISC */\n\n#ifdef CPU_RISC\nstatic uint32_t\nT4[256] = { \n  0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b,\n  0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5, \n  0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b, \n  0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676, \n  0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d, \n  0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0,\n  0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf,\n  0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0,\n  0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626,\n  0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc,\n  0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1,\n  0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515,\n  0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3,\n  0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a,\n  0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2,\n  0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575,\n  0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a, \n  0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0,\n  0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3,\n  0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484,\n  0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed,\n  0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b,\n  0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939,\n  0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf,\n  0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb,\n  0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585,\n  0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f,\n  0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8,\n  0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f,\n  0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5,\n  0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121,\n  0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2,\n  0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec,\n  0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717,\n  0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d,\n  0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373,\n  0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc,\n  0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888,\n  0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414, \n  0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb, \n  0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a,\n  0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c,\n  0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262, \n  0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979,\n  0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d,\n  0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9, \n  0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea,\n  0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808, \n  0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e,\n  0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6,\n  0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f,\n  0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a,\n  0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666,\n  0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e,\n  0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9,\n  0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e,\n  0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111, \n  0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494,\n  0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9,\n  0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf,\n  0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d,\n  0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868,\n  0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f,\n  0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616\n};\n\nstatic uint32_t U4[256] = {\n  0x52525252, 0x9090909, 0x6a6a6a6a, 0xd5d5d5d5, \n  0x30303030, 0x36363636, 0xa5a5a5a5, 0x38383838, \n  0xbfbfbfbf, 0x40404040, 0xa3a3a3a3, 0x9e9e9e9e, \n  0x81818181, 0xf3f3f3f3, 0xd7d7d7d7, 0xfbfbfbfb, \n  0x7c7c7c7c, 0xe3e3e3e3, 0x39393939, 0x82828282, \n  0x9b9b9b9b, 0x2f2f2f2f, 0xffffffff, 0x87878787, \n  0x34343434, 0x8e8e8e8e, 0x43434343, 0x44444444, \n  0xc4c4c4c4, 0xdededede, 0xe9e9e9e9, 0xcbcbcbcb, \n  0x54545454, 0x7b7b7b7b, 0x94949494, 0x32323232, \n  0xa6a6a6a6, 0xc2c2c2c2, 0x23232323, 0x3d3d3d3d, \n  0xeeeeeeee, 0x4c4c4c4c, 0x95959595, 0xb0b0b0b, \n  0x42424242, 0xfafafafa, 0xc3c3c3c3, 0x4e4e4e4e, \n  0x8080808, 0x2e2e2e2e, 0xa1a1a1a1, 0x66666666, \n  0x28282828, 0xd9d9d9d9, 0x24242424, 0xb2b2b2b2, \n  0x76767676, 0x5b5b5b5b, 0xa2a2a2a2, 0x49494949, \n  0x6d6d6d6d, 0x8b8b8b8b, 0xd1d1d1d1, 0x25252525, \n  0x72727272, 0xf8f8f8f8, 0xf6f6f6f6, 0x64646464, \n  0x86868686, 0x68686868, 0x98989898, 0x16161616, \n  0xd4d4d4d4, 0xa4a4a4a4, 0x5c5c5c5c, 0xcccccccc, \n  0x5d5d5d5d, 0x65656565, 0xb6b6b6b6, 0x92929292, \n  0x6c6c6c6c, 0x70707070, 0x48484848, 0x50505050, \n  0xfdfdfdfd, 0xedededed, 0xb9b9b9b9, 0xdadadada, \n  0x5e5e5e5e, 0x15151515, 0x46464646, 0x57575757, \n  0xa7a7a7a7, 0x8d8d8d8d, 0x9d9d9d9d, 0x84848484, \n  0x90909090, 0xd8d8d8d8, 0xabababab, 0x0, \n  0x8c8c8c8c, 0xbcbcbcbc, 0xd3d3d3d3, 0xa0a0a0a, \n  0xf7f7f7f7, 0xe4e4e4e4, 0x58585858, 0x5050505, \n  0xb8b8b8b8, 0xb3b3b3b3, 0x45454545, 0x6060606, \n  0xd0d0d0d0, 0x2c2c2c2c, 0x1e1e1e1e, 0x8f8f8f8f, \n  0xcacacaca, 0x3f3f3f3f, 0xf0f0f0f, 0x2020202, \n  0xc1c1c1c1, 0xafafafaf, 0xbdbdbdbd, 0x3030303, \n  0x1010101, 0x13131313, 0x8a8a8a8a, 0x6b6b6b6b, \n  0x3a3a3a3a, 0x91919191, 0x11111111, 0x41414141, \n  0x4f4f4f4f, 0x67676767, 0xdcdcdcdc, 0xeaeaeaea, \n  0x97979797, 0xf2f2f2f2, 0xcfcfcfcf, 0xcececece, \n  0xf0f0f0f0, 0xb4b4b4b4, 0xe6e6e6e6, 0x73737373, \n  0x96969696, 0xacacacac, 0x74747474, 0x22222222, \n  0xe7e7e7e7, 0xadadadad, 0x35353535, 0x85858585, \n  0xe2e2e2e2, 0xf9f9f9f9, 0x37373737, 0xe8e8e8e8, \n  0x1c1c1c1c, 0x75757575, 0xdfdfdfdf, 0x6e6e6e6e, \n  0x47474747, 0xf1f1f1f1, 0x1a1a1a1a, 0x71717171, \n  0x1d1d1d1d, 0x29292929, 0xc5c5c5c5, 0x89898989, \n  0x6f6f6f6f, 0xb7b7b7b7, 0x62626262, 0xe0e0e0e, \n  0xaaaaaaaa, 0x18181818, 0xbebebebe, 0x1b1b1b1b, \n  0xfcfcfcfc, 0x56565656, 0x3e3e3e3e, 0x4b4b4b4b, \n  0xc6c6c6c6, 0xd2d2d2d2, 0x79797979, 0x20202020, \n  0x9a9a9a9a, 0xdbdbdbdb, 0xc0c0c0c0, 0xfefefefe, \n  0x78787878, 0xcdcdcdcd, 0x5a5a5a5a, 0xf4f4f4f4, \n  0x1f1f1f1f, 0xdddddddd, 0xa8a8a8a8, 0x33333333, \n  0x88888888, 0x7070707, 0xc7c7c7c7, 0x31313131, \n  0xb1b1b1b1, 0x12121212, 0x10101010, 0x59595959, \n  0x27272727, 0x80808080, 0xecececec, 0x5f5f5f5f, \n  0x60606060, 0x51515151, 0x7f7f7f7f, 0xa9a9a9a9, \n  0x19191919, 0xb5b5b5b5, 0x4a4a4a4a, 0xd0d0d0d, \n  0x2d2d2d2d, 0xe5e5e5e5, 0x7a7a7a7a, 0x9f9f9f9f, \n  0x93939393, 0xc9c9c9c9, 0x9c9c9c9c, 0xefefefef, \n  0xa0a0a0a0, 0xe0e0e0e0, 0x3b3b3b3b, 0x4d4d4d4d, \n  0xaeaeaeae, 0x2a2a2a2a, 0xf5f5f5f5, 0xb0b0b0b0, \n  0xc8c8c8c8, 0xebebebeb, 0xbbbbbbbb, 0x3c3c3c3c, \n  0x83838383, 0x53535353, 0x99999999, 0x61616161, \n  0x17171717, 0x2b2b2b2b, 0x4040404, 0x7e7e7e7e, \n  0xbabababa, 0x77777777, 0xd6d6d6d6, 0x26262626, \n  0xe1e1e1e1, 0x69696969, 0x14141414, 0x63636363, \n  0x55555555, 0x21212121, 0xc0c0c0c, 0x7d7d7d7d\n};\n#endif /* CPU_RISC */\n\n\n/* aes internals */\n\nextern debug_module_t mod_aes_icm;\n\nvoid\naes_expand_encryption_key(const v128_t *key, \n\t\t\t  aes_expanded_key_t expanded_key) {\n  int i;\n  gf2_8 rc;\n\n  /* initialize round constant */\n  rc = 1;\n\n  expanded_key[0].v32[0] = key->v32[0];\n  expanded_key[0].v32[1] = key->v32[1];\n  expanded_key[0].v32[2] = key->v32[2];\n  expanded_key[0].v32[3] = key->v32[3];\n\n#if 0\n  debug_print(mod_aes_icm, \n\t      \"expanded key[0]:  %s\", v128_hex_string(&expanded_key[0])); \n#endif\n\n  /* loop over round keys */\n  for (i=1; i < 11; i++) {\n\n    /* munge first word of round key */\n    expanded_key[i].v8[0] = aes_sbox[expanded_key[i-1].v8[13]] ^ rc;\n    expanded_key[i].v8[1] = aes_sbox[expanded_key[i-1].v8[14]];\n    expanded_key[i].v8[2] = aes_sbox[expanded_key[i-1].v8[15]];\n    expanded_key[i].v8[3] = aes_sbox[expanded_key[i-1].v8[12]];\n\n    expanded_key[i].v32[0] ^=  expanded_key[i-1].v32[0];\n\n    /* set remaining 32 bit words to the exor of the one previous with\n     * the one four words previous */\n\n    expanded_key[i].v32[1] =\n      expanded_key[i].v32[0] ^ expanded_key[i-1].v32[1];\n\n    expanded_key[i].v32[2] =\n      expanded_key[i].v32[1] ^ expanded_key[i-1].v32[2];\n\n    expanded_key[i].v32[3] =\n      expanded_key[i].v32[2] ^ expanded_key[i-1].v32[3];\n\n#if 0\n\tdebug_print2(mod_aes_icm, \n\t\t\t\t\"expanded key[%d]:  %s\", i,v128_hex_string(&expanded_key[i])); \n#endif\n\n    /* modify round constant */\n    rc = gf2_8_shift(rc);\n\n  }\n}\n\nvoid\naes_expand_decryption_key(const v128_t *key, \n\t\t\t  aes_expanded_key_t expanded_key) {\n  int i;\n\n  aes_expand_encryption_key(key, expanded_key);\n\n  /* invert the order of the round keys */\n  for (i=0; i < 5; i++) {\n    v128_t tmp;\n    v128_copy(&tmp, &expanded_key[10-i]);\n    v128_copy(&expanded_key[10-i], &expanded_key[i]);\n    v128_copy(&expanded_key[i], &tmp);\n  }\n\n  /* \n   * apply the inverse mixColumn transform to the round keys (except\n   * for the first and the last)  \n   *\n   * mixColumn is implemented by using the tables U0, U1, U2, U3,\n   * followed by the T4 table (which cancels out the use of the sbox\n   * in the U-tables)\n   */\n  for (i=1; i < 10; i++) {\n#ifdef CPU_RISC\n    uint32_t tmp;\n\n    tmp = expanded_key[i].v32[0];\n    expanded_key[i].v32[0] = \n      U0[T4[(tmp >> 24)       ] & 0xff] ^ \n      U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ \n      U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^ \n      U3[T4[(tmp)       & 0xff] & 0xff];\n\n    tmp = expanded_key[i].v32[1];\n    expanded_key[i].v32[1] = \n      U0[T4[(tmp >> 24)       ] & 0xff] ^ \n      U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ \n      U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^ \n      U3[T4[(tmp)       & 0xff] & 0xff];\n\n    tmp = expanded_key[i].v32[2];\n    expanded_key[i].v32[2] = \n      U0[T4[(tmp >> 24)       ] & 0xff] ^ \n      U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ \n      U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^ \n      U3[T4[(tmp)       & 0xff] & 0xff];\n\n    tmp = expanded_key[i].v32[3];\n    expanded_key[i].v32[3] = \n      U0[T4[(tmp >> 24)       ] & 0xff] ^ \n      U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ \n      U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^ \n      U3[T4[(tmp)       & 0xff] & 0xff];\n#else /* assume CPU_CISC */\n\n    uint32_t c0, c1, c2, c3;\n\n    c0 = U0[aes_sbox[expanded_key[i].v8[0]]] \n       ^ U1[aes_sbox[expanded_key[i].v8[1]]] \n       ^ U2[aes_sbox[expanded_key[i].v8[2]]] \n       ^ U3[aes_sbox[expanded_key[i].v8[3]]];\n\n    c1 = U0[aes_sbox[expanded_key[i].v8[4]]] \n       ^ U1[aes_sbox[expanded_key[i].v8[5]]] \n       ^ U2[aes_sbox[expanded_key[i].v8[6]]] \n       ^ U3[aes_sbox[expanded_key[i].v8[7]]];\n\n    c2 = U0[aes_sbox[expanded_key[i].v8[8]]] \n       ^ U1[aes_sbox[expanded_key[i].v8[9]]] \n       ^ U2[aes_sbox[expanded_key[i].v8[10]]] \n       ^ U3[aes_sbox[expanded_key[i].v8[11]]];\n\n    c3 = U0[aes_sbox[expanded_key[i].v8[12]]] \n       ^ U1[aes_sbox[expanded_key[i].v8[13]]] \n       ^ U2[aes_sbox[expanded_key[i].v8[14]]] \n       ^ U3[aes_sbox[expanded_key[i].v8[15]]];\n\n    expanded_key[i].v32[0] = c0;\n    expanded_key[i].v32[1] = c1;\n    expanded_key[i].v32[2] = c2;\n    expanded_key[i].v32[3] = c3;\n\n#endif     \n  }\n}\n\n#ifdef CPU_CISC\n\n\nstatic inline void\naes_round(v128_t *state, const v128_t *round_key) {\n  uint32_t column0, column1, column2, column3;\n\n  /* compute the columns of the output square in terms of the octets\n     of state, using the tables T0, T1, T2, T3 */\n\n  column0 = T0[state->v8[0]] ^ T1[state->v8[5]]\n    ^ T2[state->v8[10]] ^ T3[state->v8[15]];\n\n  column1 = T0[state->v8[4]] ^ T1[state->v8[9]]\n    ^ T2[state->v8[14]] ^ T3[state->v8[3]];\n\n  column2 = T0[state->v8[8]] ^ T1[state->v8[13]]\n    ^ T2[state->v8[2]] ^ T3[state->v8[7]];\n\n  column3 = T0[state->v8[12]] ^ T1[state->v8[1]]\n    ^ T2[state->v8[6]] ^ T3[state->v8[11]];\n\n  state->v32[0] = column0 ^ round_key->v32[0];\n  state->v32[1] = column1 ^ round_key->v32[1];\n  state->v32[2] = column2 ^ round_key->v32[2];\n  state->v32[3] = column3 ^ round_key->v32[3];\n\n}\n\n\nstatic inline void\naes_inv_round(v128_t *state, const v128_t *round_key) {\n  uint32_t column0, column1, column2, column3;\n\n  /* compute the columns of the output square in terms of the octets\n     of state, using the tables U0, U1, U2, U3 */\n\n  column0 = U0[state->v8[0]] ^ U1[state->v8[13]]\n    ^ U2[state->v8[10]] ^ U3[state->v8[7]];\n\n  column1 = U0[state->v8[4]] ^ U1[state->v8[1]]\n    ^ U2[state->v8[14]] ^ U3[state->v8[11]];\n\n  column2 = U0[state->v8[8]] ^ U1[state->v8[5]]\n    ^ U2[state->v8[2]] ^ U3[state->v8[15]];\n\n  column3 = U0[state->v8[12]] ^ U1[state->v8[9]]\n    ^ U2[state->v8[6]] ^ U3[state->v8[3]];\n\n  state->v32[0] = column0 ^ round_key->v32[0];\n  state->v32[1] = column1 ^ round_key->v32[1];\n  state->v32[2] = column2 ^ round_key->v32[2];\n  state->v32[3] = column3 ^ round_key->v32[3];\n\n}\n\nstatic inline void\naes_final_round(v128_t *state, const v128_t *round_key) {\n  uint8_t tmp;\n\n  /* byte substitutions and row shifts */\n  /* first row - no shift */\n  state->v8[0] = aes_sbox[state->v8[0]];\n  state->v8[4] = aes_sbox[state->v8[4]];\n  state->v8[8] = aes_sbox[state->v8[8]];\n  state->v8[12] = aes_sbox[state->v8[12]];\n\n  /* second row - shift one left */\n  tmp = aes_sbox[state->v8[1]];\n  state->v8[1] = aes_sbox[state->v8[5]];\n  state->v8[5] = aes_sbox[state->v8[9]];\n  state->v8[9] = aes_sbox[state->v8[13]];\n  state->v8[13] = tmp;\n\n  /* third row - shift two left */\n  tmp = aes_sbox[state->v8[10]];\n  state->v8[10] = aes_sbox[state->v8[2]];\n  state->v8[2] = tmp;\n  tmp = aes_sbox[state->v8[14]];\n  state->v8[14] = aes_sbox[state->v8[6]];\n  state->v8[6] = tmp; \n\n  /* fourth row - shift three left */\n  tmp = aes_sbox[state->v8[15]];\n  state->v8[15] = aes_sbox[state->v8[11]];\n  state->v8[11] = aes_sbox[state->v8[7]];\n  state->v8[7] = aes_sbox[state->v8[3]];\n  state->v8[3] = tmp;\n\n  v128_xor_eq(state, round_key);\n}\n\nstatic inline void\naes_inv_final_round(v128_t *state, const v128_t *round_key) {\n  uint8_t tmp;\n\n  /* byte substitutions and row shifts */\n  /* first row - no shift */\n  state->v8[0] = aes_inv_sbox[state->v8[0]];\n  state->v8[4] = aes_inv_sbox[state->v8[4]];\n  state->v8[8] = aes_inv_sbox[state->v8[8]];\n  state->v8[12] = aes_inv_sbox[state->v8[12]];\n\n  /* second row - shift one right */\n  tmp = aes_inv_sbox[state->v8[13]];\n  state->v8[13] = aes_inv_sbox[state->v8[9]];\n  state->v8[9] = aes_inv_sbox[state->v8[5]];\n  state->v8[5] = aes_inv_sbox[state->v8[1]];\n  state->v8[1] = tmp;\n\n  /* third row - shift two right */\n  tmp = aes_inv_sbox[state->v8[2]];\n  state->v8[2] = aes_inv_sbox[state->v8[10]];\n  state->v8[10] = tmp;\n  tmp = aes_inv_sbox[state->v8[6]];\n  state->v8[6] = aes_inv_sbox[state->v8[14]];\n  state->v8[14] = tmp; \n\n  /* fourth row - shift three right */\n  tmp = aes_inv_sbox[state->v8[3]];\n  state->v8[3] = aes_inv_sbox[state->v8[7]];\n  state->v8[7] = aes_inv_sbox[state->v8[11]];\n  state->v8[11] = aes_inv_sbox[state->v8[15]];\n  state->v8[15] = tmp;\n\n  v128_xor_eq(state, round_key);\n}\n\n\n#elif CPU_RISC\n\nstatic inline void\naes_round(v128_t *state, const v128_t *round_key) {\n  uint32_t column0, column1, column2, column3;\n\n  /* compute the columns of the output square in terms of the octets\n     of state, using the tables T0, T1, T2, T3 */\n#ifdef WORDS_BIGENDIAN\n  column0 = T0[state->v32[0] >> 24] ^ T1[(state->v32[1] >> 16) & 0xff]\n    ^ T2[(state->v32[2] >> 8) & 0xff] ^ T3[state->v32[3] & 0xff];\n\n  column1 = T0[state->v32[1] >> 24] ^ T1[(state->v32[2] >> 16) & 0xff]\n    ^ T2[(state->v32[3] >> 8) & 0xff] ^ T3[state->v32[0] & 0xff];\n\n  column2 = T0[state->v32[2] >> 24] ^ T1[(state->v32[3] >> 16) & 0xff]\n    ^ T2[(state->v32[0] >> 8) & 0xff] ^ T3[state->v32[1] & 0xff];\n\n  column3 = T0[state->v32[3] >> 24] ^ T1[(state->v32[0] >> 16) & 0xff]\n    ^ T2[(state->v32[1] >> 8) & 0xff] ^ T3[state->v32[2] & 0xff];\n#else\n  column0 = T0[state->v32[0] & 0xff] ^ T1[(state->v32[1] >> 8) & 0xff]\n\t^ T2[(state->v32[2] >> 16) & 0xff] ^ T3[state->v32[3] >> 24];\n\n  column1 = T0[state->v32[1] & 0xff] ^ T1[(state->v32[2] >> 8) & 0xff]\n\t^ T2[(state->v32[3] >> 16) & 0xff] ^ T3[state->v32[0] >> 24];\n\n  column2 = T0[state->v32[2] & 0xff] ^ T1[(state->v32[3] >> 8) & 0xff]\n\t^ T2[(state->v32[0] >> 16) & 0xff] ^ T3[state->v32[1] >> 24];\n\n  column3 = T0[state->v32[3] & 0xff] ^ T1[(state->v32[0] >> 8) & 0xff]\n\t^ T2[(state->v32[1] >> 16) & 0xff] ^ T3[state->v32[2] >> 24];\n#endif /* WORDS_BIGENDIAN */\n\n  state->v32[0] = column0 ^ round_key->v32[0];\n  state->v32[1] = column1 ^ round_key->v32[1];\n  state->v32[2] = column2 ^ round_key->v32[2];\n  state->v32[3] = column3 ^ round_key->v32[3];\n\n}\n\nstatic inline void\naes_inv_round(v128_t *state, const v128_t *round_key) {\n  uint32_t column0, column1, column2, column3;\n\n  /* compute the columns of the output square in terms of the octets\n     of state, using the tables U0, U1, U2, U3 */\n\n#ifdef WORDS_BIGENDIAN\n  /* FIX!  WRong indexes */\n  column0 = U0[state->v32[0] >> 24] ^ U1[(state->v32[3] >> 16) & 0xff]\n    ^ U2[(state->v32[2] >> 8) & 0xff] ^ U3[state->v32[1] & 0xff];\n\n  column1 = U0[state->v32[1] >> 24] ^ U1[(state->v32[0] >> 16) & 0xff]\n    ^ U2[(state->v32[3] >> 8) & 0xff] ^ U3[state->v32[2] & 0xff];\n\n  column2 = U0[state->v32[2] >> 24] ^ U1[(state->v32[1] >> 16) & 0xff]\n    ^ U2[(state->v32[0] >> 8) & 0xff] ^ U3[state->v32[3] & 0xff];\n\n  column3 = U0[state->v32[3] >> 24] ^ U1[(state->v32[2] >> 16) & 0xff]\n    ^ U2[(state->v32[1] >> 8) & 0xff] ^ U3[state->v32[0] & 0xff];\n#else\n  column0 = U0[state->v32[0] & 0xff] ^ U1[(state->v32[1] >> 8) & 0xff]\n\t^ U2[(state->v32[2] >> 16) & 0xff] ^ U3[state->v32[3] >> 24];\n\n  column1 = U0[state->v32[1] & 0xff] ^ U1[(state->v32[2] >> 8) & 0xff]\n\t^ U2[(state->v32[3] >> 16) & 0xff] ^ U3[state->v32[0] >> 24];\n\n  column2 = U0[state->v32[2] & 0xff] ^ U1[(state->v32[3] >> 8) & 0xff]\n\t^ U2[(state->v32[0] >> 16) & 0xff] ^ U3[state->v32[1] >> 24];\n\n  column3 = U0[state->v32[3] & 0xff] ^ U1[(state->v32[0] >> 8) & 0xff]\n\t^ U2[(state->v32[1] >> 16) & 0xff] ^ U3[state->v32[2] >> 24];\n#endif /* WORDS_BIGENDIAN */\n\n  state->v32[0] = column0 ^ round_key->v32[0];\n  state->v32[1] = column1 ^ round_key->v32[1];\n  state->v32[2] = column2 ^ round_key->v32[2];\n  state->v32[3] = column3 ^ round_key->v32[3];\n\n}\n\nstatic inline void\naes_final_round(v128_t *state, const v128_t *round_key) {\n  uint32_t tmp0, tmp1, tmp2, tmp3;\n\n  tmp0 = (T4[(state->v32[0] >> 24)]        & 0xff000000) \n       ^ (T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) \n       ^ (T4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) \n       ^ (T4[(state->v32[3]      ) & 0xff] & 0x000000ff) \n       ^ round_key->v32[0];\n\n  tmp1 = (T4[(state->v32[1] >> 24)]        & 0xff000000)\n       ^ (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000)\n       ^ (T4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00)\n       ^ (T4[(state->v32[0]      ) & 0xff] & 0x000000ff)\n       ^ round_key->v32[1];\n\n  tmp2 = (T4[(state->v32[2] >> 24)]        & 0xff000000)\n       ^ (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000)\n       ^ (T4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00)\n       ^ (T4[(state->v32[1]      ) & 0xff] & 0x000000ff)\n       ^ round_key->v32[2];\n\n  tmp3 = (T4[(state->v32[3] >> 24)]        & 0xff000000)\n       ^ (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000)\n       ^ (T4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00)\n       ^ (T4[(state->v32[2]      ) & 0xff] & 0x000000ff)\n       ^ round_key->v32[3];\n\n  state->v32[0] = tmp0;\n  state->v32[1] = tmp1;\n  state->v32[2] = tmp2;\n  state->v32[3] = tmp3;\n\n}\n\nstatic inline void\naes_inv_final_round(v128_t *state, const v128_t *round_key) {\n  uint32_t tmp0, tmp1, tmp2, tmp3;\n\n  tmp0 = (U4[(state->v32[0] >> 24)]        & 0xff000000) \n       ^ (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) \n       ^ (U4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) \n       ^ (U4[(state->v32[1]      ) & 0xff] & 0x000000ff) \n       ^ round_key->v32[0];\n\n  tmp1 = (U4[(state->v32[1] >> 24)]        & 0xff000000)\n       ^ (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000)\n       ^ (U4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00)\n       ^ (U4[(state->v32[2]      ) & 0xff] & 0x000000ff)\n       ^ round_key->v32[1];\n\n  tmp2 = (U4[(state->v32[2] >> 24)]        & 0xff000000)\n       ^ (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000)\n       ^ (U4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00)\n       ^ (U4[(state->v32[3]      ) & 0xff] & 0x000000ff)\n       ^ round_key->v32[2];\n\n  tmp3 = (U4[(state->v32[3] >> 24)]        & 0xff000000)\n       ^ (U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000)\n       ^ (U4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00)\n       ^ (U4[(state->v32[0]      ) & 0xff] & 0x000000ff)\n       ^ round_key->v32[3];\n\n  state->v32[0] = tmp0;\n  state->v32[1] = tmp1;\n  state->v32[2] = tmp2;\n  state->v32[3] = tmp3;\n\n}\n\n#elif CPU_16  /* assume 16-bit word size on processor */\n\nstatic inline void\naes_round(v128_t *state, const v128_t *round_key) {\n  uint32_t column0, column1, column2, column3;\n  uint16_t c\n  /* compute the columns of the output square in terms of the octets\n     of state, using the tables T0, T1, T2, T3 */\n\n  column0 = T0[state->v8[0]] ^ T1[state->v8[5]]\n    ^ T2[state->v8[10]] ^ T3[state->v8[15]];\n\n  column1 = T0[state->v8[4]] ^ T1[state->v8[9]]\n    ^ T2[state->v8[14]] ^ T3[state->v8[3]];\n\n  column2 = T0[state->v8[8]] ^ T1[state->v8[13]]\n    ^ T2[state->v8[2]] ^ T3[state->v8[7]];\n\n  column3 = T0[state->v8[12]] ^ T1[state->v8[1]]\n    ^ T2[state->v8[6]] ^ T3[state->v8[11]];\n\n  state->v32[0] = column0 ^ round_key->v32[0];\n  state->v32[1] = column1 ^ round_key->v32[1];\n  state->v32[2] = column2 ^ round_key->v32[2];\n  state->v32[3] = column3 ^ round_key->v32[3];\n\n}\n\n\nstatic inline void\naes_inv_round(v128_t *state, const v128_t *round_key) {\n  uint32_t column0, column1, column2, column3;\n\n  /* compute the columns of the output square in terms of the octets\n     of state, using the tables U0, U1, U2, U3 */\n\n  column0 = U0[state->v8[0]] ^ U1[state->v8[5]]\n    ^ U2[state->v8[10]] ^ U3[state->v8[15]];\n\n  column1 = U0[state->v8[4]] ^ U1[state->v8[9]]\n    ^ U2[state->v8[14]] ^ U3[state->v8[3]];\n\n  column2 = U0[state->v8[8]] ^ U1[state->v8[13]]\n    ^ U2[state->v8[2]] ^ U3[state->v8[7]];\n\n  column3 = U0[state->v8[12]] ^ U1[state->v8[1]]\n    ^ U2[state->v8[6]] ^ U3[state->v8[11]];\n\n  state->v32[0] = column0 ^ round_key->v32[0];\n  state->v32[1] = column1 ^ round_key->v32[1];\n  state->v32[2] = column2 ^ round_key->v32[2];\n  state->v32[3] = column3 ^ round_key->v32[3];\n\n}\n\nstatic inline void\naes_final_round(v128_t *state, const v128_t *round_key) {\n  uint8_t tmp;\n\n  /* byte substitutions and row shifts */\n  /* first row - no shift */\n  state->v8[0] = aes_sbox[state->v8[0]];\n  state->v8[4] = aes_sbox[state->v8[4]];\n  state->v8[8] = aes_sbox[state->v8[8]];\n  state->v8[12] = aes_sbox[state->v8[12]];\n\n  /* second row - shift one left */\n  tmp = aes_sbox[state->v8[1]];\n  state->v8[1] = aes_sbox[state->v8[5]];\n  state->v8[5] = aes_sbox[state->v8[9]];\n  state->v8[9] = aes_sbox[state->v8[13]];\n  state->v8[13] = tmp;\n\n  /* third row - shift two left */\n  tmp = aes_sbox[state->v8[10]];\n  state->v8[10] = aes_sbox[state->v8[2]];\n  state->v8[2] = tmp;\n  tmp = aes_sbox[state->v8[14]];\n  state->v8[14] = aes_sbox[state->v8[6]];\n  state->v8[6] = tmp; \n\n  /* fourth row - shift three left */\n  tmp = aes_sbox[state->v8[15]];\n  state->v8[15] = aes_sbox[state->v8[11]];\n  state->v8[11] = aes_sbox[state->v8[7]];\n  state->v8[7] = aes_sbox[state->v8[3]];\n  state->v8[3] = tmp;\n\n  v128_xor_eq(state, round_key);\n}\n\nstatic inline void\naes_inv_final_round(v128_t *state, const v128_t *round_key) {\n  uint8_t tmp;\n\n  /* byte substitutions and row shifts */\n  /* first row - no shift */\n  state->v8[0] = aes_inv_sbox[state->v8[0]];\n  state->v8[4] = aes_inv_sbox[state->v8[4]];\n  state->v8[8] = aes_inv_sbox[state->v8[8]];\n  state->v8[12] = aes_inv_sbox[state->v8[12]];\n\n  /* second row - shift one left */\n  tmp = aes_inv_sbox[state->v8[1]];\n  state->v8[1] = aes_inv_sbox[state->v8[5]];\n  state->v8[5] = aes_inv_sbox[state->v8[9]];\n  state->v8[9] = aes_inv_sbox[state->v8[13]];\n  state->v8[13] = tmp;\n\n  /* third row - shift two left */\n  tmp = aes_inv_sbox[state->v8[10]];\n  state->v8[10] = aes_inv_sbox[state->v8[2]];\n  state->v8[2] = tmp;\n  tmp = aes_inv_sbox[state->v8[14]];\n  state->v8[14] = aes_inv_sbox[state->v8[6]];\n  state->v8[6] = tmp; \n\n  /* fourth row - shift three left */\n  tmp = aes_inv_sbox[state->v8[15]];\n  state->v8[15] = aes_inv_sbox[state->v8[11]];\n  state->v8[11] = aes_inv_sbox[state->v8[7]];\n  state->v8[7] = aes_inv_sbox[state->v8[3]];\n  state->v8[3] = tmp;\n\n  v128_xor_eq(state, round_key);\n}\n\n#endif  /* CPU type */\n\n\nvoid\naes_encrypt(v128_t *plaintext, const aes_expanded_key_t exp_key) {\n\n  /* add in the subkey */\n  v128_xor_eq(plaintext, exp_key + 0);\n\n  /* now do nine rounds */\n  aes_round(plaintext, exp_key + 1);\n  aes_round(plaintext, exp_key + 2);\n  aes_round(plaintext, exp_key + 3);\n  aes_round(plaintext, exp_key + 4);\n  aes_round(plaintext, exp_key + 5);\n  aes_round(plaintext, exp_key + 6);\n  aes_round(plaintext, exp_key + 7);\n  aes_round(plaintext, exp_key + 8);  \n  aes_round(plaintext, exp_key + 9);\n  /* the last round is different */\n\n aes_final_round(plaintext, exp_key + 10);  \n}\n\nvoid\naes_decrypt(v128_t *plaintext, const aes_expanded_key_t exp_key) {\n\n  /* add in the subkey */\n  v128_xor_eq(plaintext, exp_key + 0);\n\n  /* now do nine rounds */\n  aes_inv_round(plaintext, exp_key + 1);\n  aes_inv_round(plaintext, exp_key + 2);\n  aes_inv_round(plaintext, exp_key + 3);\n  aes_inv_round(plaintext, exp_key + 4);\n  aes_inv_round(plaintext, exp_key + 5);\n  aes_inv_round(plaintext, exp_key + 6);\n  aes_inv_round(plaintext, exp_key + 7);\n  aes_inv_round(plaintext, exp_key + 8);  \n  aes_inv_round(plaintext, exp_key + 9);\n  /* the last round is different */\n  aes_inv_final_round(plaintext, exp_key + 10);  \n}\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/cipher/aes_cbc.c",
    "content": "/*\n * aes_cbc.c\n *\n * AES Cipher Block Chaining Mode\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#include \"aes_cbc.h\"\n#include \"alloc.h\"\n\ndebug_module_t mod_aes_cbc = {\n  0,                 /* debugging is off by default */\n  \"aes cbc\"          /* printable module name       */\n};\n\n\n\nerr_status_t\naes_cbc_alloc(cipher_t **c, int key_len) {\n  extern cipher_type_t aes_cbc;\n  uint8_t *pointer;\n  int tmp;\n\n  debug_print(mod_aes_cbc, \n\t      \"allocating cipher with key length %d\", key_len);\n\n  if (key_len != 16)\n    return err_status_bad_param;\n  \n  /* allocate memory a cipher of type aes_icm */\n  tmp = (sizeof(aes_cbc_ctx_t) + sizeof(cipher_t));\n  pointer = (uint8_t*)crypto_alloc(tmp);\n  if (pointer == NULL) \n    return err_status_alloc_fail;\n\n  /* set pointers */\n  *c = (cipher_t *)pointer;\n  (*c)->type = &aes_cbc;\n  (*c)->state = pointer + sizeof(cipher_t);\n\n  /* increment ref_count */\n  aes_cbc.ref_count++;\n\n  /* set key size        */\n  (*c)->key_len = key_len;\n\n  return err_status_ok;  \n}\n\nerr_status_t\naes_cbc_dealloc(cipher_t *c) {\n  extern cipher_type_t aes_cbc;\n\n  /* zeroize entire state*/\n  octet_string_set_to_zero((uint8_t *)c, \n\t\t\t   sizeof(aes_cbc_ctx_t) + sizeof(cipher_t));\n\n  /* free memory */\n  crypto_free(c);\n\n  /* decrement ref_count */\n  aes_cbc.ref_count--;\n  \n  return err_status_ok;  \n}\n\nerr_status_t\naes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, \n\t\t     cipher_direction_t dir) {\n  v128_t tmp_key;\n\n  /* set tmp_key (for alignment) */\n  v128_copy_octet_string(&tmp_key, key);\n\n  debug_print(mod_aes_cbc, \n\t      \"key:  %s\", v128_hex_string(&tmp_key)); \n\n  /* expand key for the appropriate direction */\n  switch (dir) {\n  case (direction_encrypt):\n    aes_expand_encryption_key(&tmp_key, c->expanded_key);\n    break;\n  case (direction_decrypt):\n    aes_expand_decryption_key(&tmp_key, c->expanded_key);\n    break;\n  default:\n    return err_status_bad_param;\n  }\n\n\n  return err_status_ok;\n}\n\n\nerr_status_t\naes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv) {\n  int i;\n/*   v128_t *input = iv; */\n  uint8_t *input = (uint8_t*) iv;\n \n  /* set state and 'previous' block to iv */\n  for (i=0; i < 16; i++) \n    c->previous.v8[i] = c->state.v8[i] = input[i];\n\n  debug_print(mod_aes_cbc, \"setting iv: %s\", v128_hex_string(&c->state)); \n\n  return err_status_ok;\n}\n\nerr_status_t\naes_cbc_encrypt(aes_cbc_ctx_t *c,\n\t\tunsigned char *data, \n\t\tunsigned int *bytes_in_data) {\n  int i;\n  unsigned char *input  = data;   /* pointer to data being read    */\n  unsigned char *output = data;   /* pointer to data being written */\n  int bytes_to_encr = *bytes_in_data;\n\n  /*\n   * verify that we're 16-octet aligned\n   */\n  if (*bytes_in_data & 0xf) \n    return err_status_bad_param;\n\n  /*\n   * note that we assume that the initialization vector has already\n   * been set, e.g. by calling aes_cbc_set_iv()\n   */\n  debug_print(mod_aes_cbc, \"iv: %s\", \n\t      v128_hex_string(&c->state));\n  \n  /*\n   * loop over plaintext blocks, exoring state into plaintext then\n   * encrypting and writing to output\n   */\n  while (bytes_to_encr > 0) {\n    \n    /* exor plaintext into state */\n    for (i=0; i < 16; i++)\n      c->state.v8[i] ^= *input++;\n\n    debug_print(mod_aes_cbc, \"inblock:  %s\", \n\t      v128_hex_string(&c->state));\n\n    aes_encrypt(&c->state, c->expanded_key);\n\n    debug_print(mod_aes_cbc, \"outblock: %s\", \n\t      v128_hex_string(&c->state));\n\n    /* copy ciphertext to output */\n    for (i=0; i < 16; i++)\n      *output++ = c->state.v8[i];\n\n    bytes_to_encr -= 16;\n  }\n\n  return err_status_ok;\n}\n\nerr_status_t\naes_cbc_decrypt(aes_cbc_ctx_t *c,\n\t\tunsigned char *data, \n\t\tunsigned int *bytes_in_data) {\n  int i;\n  v128_t state, previous;\n  unsigned char *input  = data;   /* pointer to data being read    */\n  unsigned char *output = data;   /* pointer to data being written */\n  int bytes_to_encr = *bytes_in_data;\n  uint8_t tmp;\n\n  /*\n   * verify that we're 16-octet aligned\n   */\n  if (*bytes_in_data & 0x0f)\n    return err_status_bad_param;    \n\n  /* set 'previous' block to iv*/\n  for (i=0; i < 16; i++) {\n    previous.v8[i] = c->previous.v8[i];\n  }\n\n  debug_print(mod_aes_cbc, \"iv: %s\", \n\t      v128_hex_string(&previous));\n  \n  /*\n   * loop over ciphertext blocks, decrypting then exoring with state\n   * then writing plaintext to output\n   */\n  while (bytes_to_encr > 0) {\n    \n    /* set state to ciphertext input block */\n    for (i=0; i < 16; i++) {\n     state.v8[i] = *input++;\n    }\n\n    debug_print(mod_aes_cbc, \"inblock:  %s\", \n\t      v128_hex_string(&state));\n    \n    /* decrypt state */\n    aes_decrypt(&state, c->expanded_key);\n\n    debug_print(mod_aes_cbc, \"outblock: %s\", \n\t      v128_hex_string(&state));\n\n    /* \n     * exor previous ciphertext block out of plaintext, and write new\n     * plaintext block to output, while copying old ciphertext block\n     * to the 'previous' block\n     */\n    for (i=0; i < 16; i++) {\n      tmp = *output;\n      *output++ = state.v8[i] ^ previous.v8[i];\n      previous.v8[i] = tmp;\n    }\n\n    bytes_to_encr -= 16;\n  }\n\n  return err_status_ok;\n}\n\n\nerr_status_t\naes_cbc_nist_encrypt(aes_cbc_ctx_t *c,\n\t\t     unsigned char *data, \n\t\t     unsigned int *bytes_in_data) {\n  int i;\n  unsigned char *pad_start; \n  int num_pad_bytes;\n  err_status_t status;\n\n  /* \n   * determine the number of padding bytes that we need to add - \n   * this value is always between 1 and 16, inclusive.\n   */\n  num_pad_bytes = 16 - (*bytes_in_data & 0xf);\n  pad_start = data;\n  pad_start += *bytes_in_data;\n  *pad_start++ = 0xa0;\n  for (i=0; i < num_pad_bytes; i++) \n    *pad_start++ = 0x00;\n   \n  /* \n   * increment the data size \n   */\n  *bytes_in_data += num_pad_bytes;  \n\n  /*\n   * now cbc encrypt the padded data \n   */\n  status = aes_cbc_encrypt(c, data, bytes_in_data);\n  if (status) \n    return status;\n\n  return err_status_ok;\n}\n\n\nerr_status_t\naes_cbc_nist_decrypt(aes_cbc_ctx_t *c,\n\t\t     unsigned char *data, \n\t\t     unsigned int *bytes_in_data) {\n  unsigned char *pad_end;\n  int num_pad_bytes;\n  err_status_t status;\n\n  /*\n   * cbc decrypt the padded data \n   */\n  status = aes_cbc_decrypt(c, data, bytes_in_data);\n  if (status) \n    return status;\n\n  /*\n   * determine the number of padding bytes in the decrypted plaintext\n   * - this value is always between 1 and 16, inclusive.\n   */\n  num_pad_bytes = 1;\n  pad_end = data + (*bytes_in_data - 1);\n  while (*pad_end != 0xa0) {   /* note: should check padding correctness */\n    pad_end--;\n    num_pad_bytes++;\n  }\n  \n  /* decrement data size */\n  *bytes_in_data -= num_pad_bytes;  \n\n  return err_status_ok;\n}\n\n\nchar \naes_cbc_description[] = \"aes cipher block chaining (cbc) mode\";\n\n/*\n * Test case 0 is derived from FIPS 197 Appendix A; it uses an\n * all-zero IV, so that the first block encryption matches the test\n * case in that appendix.  This property provides a check of the base\n * AES encryption and decryption algorithms; if CBC fails on some\n * particular platform, then you should print out AES intermediate\n * data and compare with the detailed info provided in that appendix.\n *\n */\n\n\nuint8_t aes_cbc_test_case_0_key[16] = {\n  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \n  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f\n};\n\nuint8_t aes_cbc_test_case_0_plaintext[64] =  {\n  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,\n  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff \n};\n\nuint8_t aes_cbc_test_case_0_ciphertext[80] = {\n  0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, \n  0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a,\n  0x03, 0x35, 0xed, 0x27, 0x67, 0xf2, 0x6d, 0xf1, \n  0x64, 0x83, 0x2e, 0x23, 0x44, 0x38, 0x70, 0x8b\n\n};\n\nuint8_t aes_cbc_test_case_0_iv[16] = {\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n\n\ncipher_test_case_t aes_cbc_test_case_0 = {\n  16,                                    /* octets in key            */\n  aes_cbc_test_case_0_key,               /* key                      */\n  aes_cbc_test_case_0_iv,                /* initialization vector    */\n  16,                                    /* octets in plaintext      */\n  aes_cbc_test_case_0_plaintext,         /* plaintext                */\n  32,                                    /* octets in ciphertext     */\n  aes_cbc_test_case_0_ciphertext,        /* ciphertext               */\n  NULL                                   /* pointer to next testcase */\n};\n\n\n/*\n * this test case is taken directly from Appendix F.2 of NIST Special\n * Publication SP 800-38A\n */\n\nuint8_t aes_cbc_test_case_1_key[16] = {\n  0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,\n  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,\n};\n\nuint8_t aes_cbc_test_case_1_plaintext[64] =  {\n  0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, \n  0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,\n  0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, \n  0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,\n  0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,\n  0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,\n  0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, \n  0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10\n};\n\nuint8_t aes_cbc_test_case_1_ciphertext[80] = {\n  0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,\n  0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,\n  0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee,\n  0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,\n  0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b,\n  0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16, \n  0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, \n  0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7,\n  0x39, 0x34, 0x07, 0x03, 0x36, 0xd0, 0x77, 0x99, \n  0xe0, 0xc4, 0x2f, 0xdd, 0xa8, 0xdf, 0x4c, 0xa3\n};\n\nuint8_t aes_cbc_test_case_1_iv[16] = {\n  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \n  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f\n};\n\ncipher_test_case_t aes_cbc_test_case_1 = {\n  16,                                    /* octets in key            */\n  aes_cbc_test_case_1_key,               /* key                      */\n  aes_cbc_test_case_1_iv,                /* initialization vector    */\n  64,                                    /* octets in plaintext      */\n  aes_cbc_test_case_1_plaintext,         /* plaintext                */\n  80,                                    /* octets in ciphertext     */\n  aes_cbc_test_case_1_ciphertext,        /* ciphertext               */\n  &aes_cbc_test_case_0                    /* pointer to next testcase */\n};\n\ncipher_type_t aes_cbc = {\n  (cipher_alloc_func_t)          aes_cbc_alloc,\n  (cipher_dealloc_func_t)        aes_cbc_dealloc,  \n  (cipher_init_func_t)           aes_cbc_context_init,\n  (cipher_encrypt_func_t)        aes_cbc_nist_encrypt,\n  (cipher_decrypt_func_t)        aes_cbc_nist_decrypt,\n  (cipher_set_iv_func_t)         aes_cbc_set_iv,\n  (char *)                       aes_cbc_description,\n  (int)                          0,   /* instance count */\n  (cipher_test_case_t *)        &aes_cbc_test_case_0,\n  (debug_module_t *)            &mod_aes_cbc\n};\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/cipher/aes_icm.c",
    "content": "/*\n * aes_icm.c\n *\n * AES Integer Counter Mode\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#define ALIGN_32 0\n\n#include \"aes_icm.h\"\n#include \"alloc.h\"\n\n\ndebug_module_t mod_aes_icm = {\n  0,                 /* debugging is off by default */\n  \"aes icm\"          /* printable module name       */\n};\n\n/*\n * integer counter mode works as follows:\n *\n * 16 bits\n * <----->\n * +------+------+------+------+------+------+------+------+ \n * |           nonce           |    pakcet index    |  ctr |---+\n * +------+------+------+------+------+------+------+------+   |\n *                                                             |\n * +------+------+------+------+------+------+------+------+   v\n * |                      salt                      |000000|->(+)\n * +------+------+------+------+------+------+------+------+   |\n *                                                             |\n *                                                        +---------+\n *\t\t\t\t\t\t\t  | encrypt |\n *\t\t\t\t\t\t\t  +---------+\n *\t\t\t\t\t\t\t       | \n * +------+------+------+------+------+------+------+------+   |\n * |                    keystream block                    |<--+ \n * +------+------+------+------+------+------+------+------+   \n *\n * All fields are big-endian\n *\n * ctr is the block counter, which increments from zero for\n * each packet (16 bits wide)\n * \n * packet index is distinct for each packet (48 bits wide)\n *\n * nonce can be distinct across many uses of the same key, or\n * can be a fixed value per key, or can be per-packet randomness\n * (64 bits)\n *\n */\n\nerr_status_t\naes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) {\n  extern cipher_type_t aes_icm;\n  uint8_t *pointer;\n  int tmp;\n\n  debug_print(mod_aes_icm, \n            \"allocating cipher with key length %d\", key_len);\n\n  /*\n   * Ismacryp, for example, uses 16 byte key + 8 byte \n   * salt  so this function is called with key_len = 24.\n   * The check for key_len = 30 does not apply. Our usage\n   * of aes functions with key_len = values other than 30\n   * has not broken anything. Don't know what would be the\n   * effect of skipping this check for srtp in general.\n   */\n  if (!forIsmacryp && key_len != 30)\n    return err_status_bad_param;\n\n  /* allocate memory a cipher of type aes_icm */\n  tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t));\n  pointer = (uint8_t*)crypto_alloc(tmp);\n  if (pointer == NULL) \n    return err_status_alloc_fail;\n\n  /* set pointers */\n  *c = (cipher_t *)pointer;\n  (*c)->type = &aes_icm;\n  (*c)->state = pointer + sizeof(cipher_t);\n\n  /* increment ref_count */\n  aes_icm.ref_count++;\n\n  /* set key size        */\n  (*c)->key_len = key_len;\n\n  return err_status_ok;  \n}\n\nerr_status_t aes_icm_alloc(cipher_t **c, int key_len, int forIsmacryp) {\n  return aes_icm_alloc_ismacryp(c, key_len, 0);\n}\n\nerr_status_t\naes_icm_dealloc(cipher_t *c) {\n  extern cipher_type_t aes_icm;\n\n  /* zeroize entire state*/\n  octet_string_set_to_zero((uint8_t *)c, \n\t\t\t   sizeof(aes_icm_ctx_t) + sizeof(cipher_t));\n\n  /* free memory */\n  crypto_free(c);\n\n  /* decrement ref_count */\n  aes_icm.ref_count--;\n  \n  return err_status_ok;  \n}\n\n\n/*\n * aes_icm_context_init(...) initializes the aes_icm_context\n * using the value in key[].\n *\n * the key is the secret key \n *\n * the salt is unpredictable (but not necessarily secret) data which\n * randomizes the starting point in the keystream\n */\n\nerr_status_t\naes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key) {\n  v128_t tmp_key;\n\n  /* set counter and initial values to 'offset' value */\n  /* FIX!!! this assumes the salt is at key + 16, and thus that the */\n  /* FIX!!! cipher key length is 16!  Also note this copies past the\n            end of the 'key' array by 2 bytes! */\n  v128_copy_octet_string(&c->counter, key + 16);\n  v128_copy_octet_string(&c->offset, key + 16);\n\n  /* force last two octets of the offset to zero (for srtp compatibility) */\n  c->offset.v8[14] = c->offset.v8[15] = 0;\n  c->counter.v8[14] = c->counter.v8[15] = 0;\n  \n  /* set tmp_key (for alignment) */\n  v128_copy_octet_string(&tmp_key, key);\n\n  debug_print(mod_aes_icm, \n\t      \"key:  %s\", v128_hex_string(&tmp_key)); \n  debug_print(mod_aes_icm, \n\t      \"offset: %s\", v128_hex_string(&c->offset)); \n\n  /* expand key */\n  aes_expand_encryption_key(&tmp_key, c->expanded_key);\n\n  /* indicate that the keystream_buffer is empty */\n  c->bytes_in_buffer = 0;\n\n  return err_status_ok;\n}\n\n/*\n * aes_icm_set_octet(c, i) sets the counter of the context which it is\n * passed so that the next octet of keystream that will be generated\n * is the ith octet\n */\n\nerr_status_t\naes_icm_set_octet(aes_icm_ctx_t *c,\n\t\t  uint64_t octet_num) {\n\n#ifdef NO_64BIT_MATH\n  int tail_num       = low32(octet_num) & 0x0f;\n  /* 64-bit right-shift 4 */\n  uint64_t block_num = make64(high32(octet_num) >> 4,\n\t\t\t\t\t\t\t  ((high32(octet_num) & 0x0f)<<(32-4)) |\n\t\t\t\t\t\t\t   (low32(octet_num) >> 4));\n#else\n  int tail_num       = octet_num % 16;\n  uint64_t block_num = octet_num / 16;\n#endif\n  \n\n  /* set counter value */\n  /* FIX - There's no way this is correct */\n  c->counter.v64[0] = c->offset.v64[0];\n#ifdef NO_64BIT_MATH\n  c->counter.v64[0] = make64(high32(c->offset.v64[0]) ^ high32(block_num),\n\t\t\t\t\t\t\t low32(c->offset.v64[0])  ^ low32(block_num));\n#else\n  c->counter.v64[0] = c->offset.v64[0] ^ block_num;\n#endif\n\n  debug_print(mod_aes_icm, \n\t      \"set_octet: %s\", v128_hex_string(&c->counter)); \n\n  /* fill keystream buffer, if needed */\n  if (tail_num) {\n    v128_copy(&c->keystream_buffer, &c->counter);\n    aes_encrypt(&c->keystream_buffer, c->expanded_key);\n    c->bytes_in_buffer = sizeof(v128_t);\n\n    debug_print(mod_aes_icm, \"counter:    %s\", \n\t      v128_hex_string(&c->counter));\n    debug_print(mod_aes_icm, \"ciphertext: %s\", \n\t      v128_hex_string(&c->keystream_buffer));    \n    \n    /*  indicate number of bytes in keystream_buffer  */\n    c->bytes_in_buffer = sizeof(v128_t) - tail_num;\n  \n  } else {\n    \n    /* indicate that keystream_buffer is empty */\n    c->bytes_in_buffer = 0;\n  }\n\n  return err_status_ok;\n}\n\n/*\n * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with\n * the offset\n */\n\nerr_status_t\naes_icm_set_iv(aes_icm_ctx_t *c, void *iv) {\n  v128_t *nonce = (v128_t *) iv;\n\n  debug_print(mod_aes_icm, \n\t      \"setting iv: %s\", v128_hex_string(nonce)); \n \n  v128_xor(&c->counter, &c->offset, nonce);\n  \n  debug_print(mod_aes_icm, \n\t      \"set_counter: %s\", v128_hex_string(&c->counter)); \n\n  /* indicate that the keystream_buffer is empty */\n  c->bytes_in_buffer = 0;\n\n  return err_status_ok;\n}\n\n\n\n/*\n * aes_icm_advance(...) refills the keystream_buffer and\n * advances the block index of the sicm_context forward by one\n *\n * this is an internal, hopefully inlined function\n */\n  \nstatic inline void\naes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) {\n  /* fill buffer with new keystream */\n  v128_copy(&c->keystream_buffer, &c->counter);\n  aes_encrypt(&c->keystream_buffer, c->expanded_key);\n  c->bytes_in_buffer = sizeof(v128_t);\n\n  debug_print(mod_aes_icm, \"counter:    %s\", \n\t      v128_hex_string(&c->counter));\n  debug_print(mod_aes_icm, \"ciphertext: %s\", \n\t      v128_hex_string(&c->keystream_buffer));    \n  \n  /* clock counter forward */\n\n  if (forIsmacryp) {\n    uint32_t temp;    \n    //alex's clock counter forward\n    temp = ntohl(c->counter.v32[3]);\n    c->counter.v32[3] = htonl(++temp);\n  } else {\n    if (!++(c->counter.v8[15])) \n      ++(c->counter.v8[14]);\n  }\n}\n\ninline void aes_icm_advance(aes_icm_ctx_t *c) {\n  aes_icm_advance_ismacryp(c, 0);\n}\n\n\n/*e\n * icm_encrypt deals with the following cases:\n *\n * bytes_to_encr < bytes_in_buffer\n *  - add keystream into data\n *\n * bytes_to_encr > bytes_in_buffer\n *  - add keystream into data until keystream_buffer is depleted\n *  - loop over blocks, filling keystream_buffer and then\n *    adding keystream into data\n *  - fill buffer then add in remaining (< 16) bytes of keystream \n */\n\nerr_status_t\naes_icm_encrypt_ismacryp(aes_icm_ctx_t *c,\n              unsigned char *buf, unsigned int *enc_len, \n              int forIsmacryp) {\n  unsigned int bytes_to_encr = *enc_len;\n  unsigned int i;\n  uint32_t *b;\n\n  /* check that there's enough segment left but not for ismacryp*/\n  if (!forIsmacryp && (bytes_to_encr + htons(c->counter.v16[7])) > 0xffff)\n    return err_status_terminus;\n\n debug_print(mod_aes_icm, \"block index: %d\", \n           htons(c->counter.v16[7]));\n  if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) {\n    \n    /* deal with odd case of small bytes_to_encr */\n    for (i = (sizeof(v128_t) - c->bytes_in_buffer);\n\t\t i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++) \n\t{\n      *buf++ ^= c->keystream_buffer.v8[i];\n\t}\n\n    c->bytes_in_buffer -= bytes_to_encr;\n\n    /* return now to avoid the main loop */\n    return err_status_ok;\n\n  } else {\n    \n    /* encrypt bytes until the remaining data is 16-byte aligned */    \n    for (i=(sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++) \n      *buf++ ^= c->keystream_buffer.v8[i];\n\n    bytes_to_encr -= c->bytes_in_buffer;\n    c->bytes_in_buffer = 0;\n\n  }\n  \n  /* now loop over entire 16-byte blocks of keystream */\n  for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) {\n\n    /* fill buffer with new keystream */\n    aes_icm_advance_ismacryp(c, forIsmacryp);\n\n    /*\n     * add keystream into the data buffer (this would be a lot faster\n     * if we could assume 32-bit alignment!)\n     */\n\n#if ALIGN_32\n    b = (uint32_t *)buf;\n    *b++ ^= c->keystream_buffer.v32[0];\n    *b++ ^= c->keystream_buffer.v32[1];\n    *b++ ^= c->keystream_buffer.v32[2];\n    *b++ ^= c->keystream_buffer.v32[3];\n    buf = (uint8_t *)b;\n#else    \n    if ((((unsigned long) buf) & 0x03) != 0) {\n      *buf++ ^= c->keystream_buffer.v8[0];\n      *buf++ ^= c->keystream_buffer.v8[1];\n      *buf++ ^= c->keystream_buffer.v8[2];\n      *buf++ ^= c->keystream_buffer.v8[3];\n      *buf++ ^= c->keystream_buffer.v8[4];\n      *buf++ ^= c->keystream_buffer.v8[5];\n      *buf++ ^= c->keystream_buffer.v8[6];\n      *buf++ ^= c->keystream_buffer.v8[7];\n      *buf++ ^= c->keystream_buffer.v8[8];\n      *buf++ ^= c->keystream_buffer.v8[9];\n      *buf++ ^= c->keystream_buffer.v8[10];\n      *buf++ ^= c->keystream_buffer.v8[11];\n      *buf++ ^= c->keystream_buffer.v8[12];\n      *buf++ ^= c->keystream_buffer.v8[13];\n      *buf++ ^= c->keystream_buffer.v8[14];\n      *buf++ ^= c->keystream_buffer.v8[15];\n    } else {\n      b = (uint32_t *)buf;\n      *b++ ^= c->keystream_buffer.v32[0];\n      *b++ ^= c->keystream_buffer.v32[1];\n      *b++ ^= c->keystream_buffer.v32[2];\n      *b++ ^= c->keystream_buffer.v32[3];\n      buf = (uint8_t *)b;\n    }\n#endif /* #if ALIGN_32 */\n\n  }\n  \n  /* if there is a tail end of the data, process it */\n  if ((bytes_to_encr & 0xf) != 0) {\n    \n    /* fill buffer with new keystream */\n    aes_icm_advance_ismacryp(c, forIsmacryp);\n    \n    for (i=0; i < (bytes_to_encr & 0xf); i++)\n      *buf++ ^= c->keystream_buffer.v8[i];\n    \n    /* reset the keystream buffer size to right value */\n    c->bytes_in_buffer = sizeof(v128_t) - i;  \n  } else {\n\n    /* no tail, so just reset the keystream buffer size to zero */\n    c->bytes_in_buffer = 0;\n\n  }\n\n  return err_status_ok;\n}\n\nerr_status_t\naes_icm_encrypt(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) {\n  return aes_icm_encrypt_ismacryp(c, buf, enc_len, 0);\n}\n\nerr_status_t\naes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output) {\n  unsigned int len = num_octets_to_output;\n  \n  /* zeroize the buffer */\n  octet_string_set_to_zero(buffer, num_octets_to_output);\n  \n  /* exor keystream into buffer */\n  return aes_icm_encrypt(c, buffer, &len);\n}\n\n\nchar \naes_icm_description[] = \"aes integer counter mode\";\n\nuint8_t aes_icm_test_case_0_key[30] = {\n  0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,\n  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,\n  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,\n  0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd\n};\n\nuint8_t aes_icm_test_case_0_nonce[16] = {\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n\nuint8_t aes_icm_test_case_0_plaintext[32] =  {\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \n};\n\nuint8_t aes_icm_test_case_0_ciphertext[32] = {\n  0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,\n  0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,\n  0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,\n  0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab\n};\n\ncipher_test_case_t aes_icm_test_case_0 = {\n  30,                                    /* octets in key            */\n  aes_icm_test_case_0_key,               /* key                      */\n  aes_icm_test_case_0_nonce,             /* packet index             */\n  32,                                    /* octets in plaintext      */\n  aes_icm_test_case_0_plaintext,         /* plaintext                */\n  32,                                    /* octets in ciphertext     */\n  aes_icm_test_case_0_ciphertext,        /* ciphertext               */\n  NULL                                   /* pointer to next testcase */\n};\n\n\n/*\n * note: the encrypt function is identical to the decrypt function\n */\n\ncipher_type_t aes_icm = {\n  (cipher_alloc_func_t)          aes_icm_alloc,\n  (cipher_dealloc_func_t)        aes_icm_dealloc,  \n  (cipher_init_func_t)           aes_icm_context_init,\n  (cipher_encrypt_func_t)        aes_icm_encrypt,\n  (cipher_decrypt_func_t)        aes_icm_encrypt,\n  (cipher_set_iv_func_t)         aes_icm_set_iv,\n  (char *)                       aes_icm_description,\n  (int)                          0,   /* instance count */\n  (cipher_test_case_t *)        &aes_icm_test_case_0,\n  (debug_module_t *)            &mod_aes_icm\n};\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/cipher/cipher.c",
    "content": "/*\n * cipher.c\n *\n * cipher meta-functions\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n * \n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#include \"cipher.h\"\n#include \"rand_source.h\"        /* used in invertibiltiy tests        */\n#include \"alloc.h\"              /* for crypto_alloc(), crypto_free()  */\n\ndebug_module_t mod_cipher = {\n  0,                 /* debugging is off by default */\n  \"cipher\"           /* printable module name       */\n};\n\nerr_status_t\ncipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output) {\n  \n  /* zeroize the buffer */\n  octet_string_set_to_zero(buffer, num_octets_to_output);\n  \n  /* exor keystream into buffer */\n  return cipher_encrypt(c, buffer, (unsigned int *) &num_octets_to_output);\n}\n\n/* some bookkeeping functions */\n\nint\ncipher_get_key_length(const cipher_t *c) {\n  return c->key_len;\n}\n\n/* \n * cipher_type_self_test(ct) tests a cipher of type ct against test cases\n * provided in an array of values of key, salt, xtd_seq_num_t,\n * plaintext, and ciphertext that is known to be good\n */\n\n#define SELF_TEST_BUF_OCTETS 128\n#define NUM_RAND_TESTS       128\n#define MAX_KEY_LEN          64\n\nerr_status_t\ncipher_type_self_test(const cipher_type_t *ct) {\n  const cipher_test_case_t *test_case = ct->test_data;\n  cipher_t *c;\n  err_status_t status;\n  uint8_t buffer[SELF_TEST_BUF_OCTETS];\n  uint8_t buffer2[SELF_TEST_BUF_OCTETS];\n  unsigned int len;\n  int i, j, case_num = 0;\n\n  debug_print(mod_cipher, \"running self-test for cipher %s\", \n\t      ct->description);\n  \n  /*\n   * check to make sure that we have at least one test case, and\n   * return an error if we don't - we need to be paranoid here\n   */\n  if (test_case == NULL)\n    return err_status_cant_check;\n\n  /*\n   * loop over all test cases, perform known-answer tests of both the\n   * encryption and decryption functions\n   */  \n  while (test_case != NULL) {\n\n    /* allocate cipher */\n    status = cipher_type_alloc(ct, &c, test_case->key_length_octets);\n    if (status)\n      return status;\n    \n    /*\n     * test the encrypt function \n     */\n    debug_print(mod_cipher, \"testing encryption\", NULL);    \n    \n    /* initialize cipher */\n    status = cipher_init(c, test_case->key, direction_encrypt);\n    if (status) {\n      cipher_dealloc(c);\n      return status;\n    }\n    \n    /* copy plaintext into test buffer */\n    if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {\n      cipher_dealloc(c);    \n      return err_status_bad_param;\n    }\n    for (i=0; i < test_case->plaintext_length_octets; i++)\n      buffer[i] = test_case->plaintext[i];\n\n    debug_print(mod_cipher, \"plaintext:    %s\",\n\t     octet_string_hex_string(buffer,\n\t\t\t\t     test_case->plaintext_length_octets));\n\n    /* set the initialization vector */\n    status = cipher_set_iv(c, test_case->idx);\n    if (status) {\n      cipher_dealloc(c);\n      return status;\n    } \n    \n    /* encrypt */\n    len = test_case->plaintext_length_octets;\n    status = cipher_encrypt(c, buffer, &len);\n    if (status) {\n      cipher_dealloc(c);\n      return status;\n    }\n    \n    debug_print(mod_cipher, \"ciphertext:   %s\",\n\t     octet_string_hex_string(buffer,\n\t\t\t\t     test_case->ciphertext_length_octets));\n\n    /* compare the resulting ciphertext with that in the test case */\n    if (len != test_case->ciphertext_length_octets)\n      return err_status_algo_fail;\n    status = err_status_ok;\n    for (i=0; i < test_case->ciphertext_length_octets; i++)\n      if (buffer[i] != test_case->ciphertext[i]) {\n\tstatus = err_status_algo_fail;\n\tdebug_print(mod_cipher, \"test case %d failed\", case_num);\n\tdebug_print(mod_cipher, \"(failure at byte %d)\", i);\n\tbreak;\n      }\n    if (status) {\n\n      debug_print(mod_cipher, \"c computed: %s\",\n\t     octet_string_hex_string(buffer,\n\t\t  2*test_case->plaintext_length_octets));\n      debug_print(mod_cipher, \"c expected: %s\",\n\t\t  octet_string_hex_string(test_case->ciphertext,\n\t\t\t  2*test_case->plaintext_length_octets));\n\n      cipher_dealloc(c);\n      return err_status_algo_fail;\n    }\n\n    /*\n     * test the decrypt function\n     */\n    debug_print(mod_cipher, \"testing decryption\", NULL);    \n\n    /* re-initialize cipher for decryption */\n    status = cipher_init(c, test_case->key, direction_decrypt);\n    if (status) {\n      cipher_dealloc(c);\n      return status;\n    }\n\n    /* copy ciphertext into test buffer */\n    if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {\n      cipher_dealloc(c);    \n      return err_status_bad_param;\n    }\n    for (i=0; i < test_case->ciphertext_length_octets; i++)\n      buffer[i] = test_case->ciphertext[i];\n\n    debug_print(mod_cipher, \"ciphertext:    %s\",\n\t\toctet_string_hex_string(buffer,\n\t\t\t\t\ttest_case->plaintext_length_octets));\n\n    /* set the initialization vector */\n    status = cipher_set_iv(c, test_case->idx);\n    if (status) {\n      cipher_dealloc(c);\n      return status;\n    } \n    \n    /* decrypt */\n    len = test_case->ciphertext_length_octets;\n    status = cipher_decrypt(c, buffer, &len);\n    if (status) {\n      cipher_dealloc(c);\n      return status;\n    }\n    \n    debug_print(mod_cipher, \"plaintext:   %s\",\n\t     octet_string_hex_string(buffer,\n\t\t\t\t     test_case->plaintext_length_octets));\n\n    /* compare the resulting plaintext with that in the test case */\n    if (len != test_case->plaintext_length_octets)\n      return err_status_algo_fail;\n    status = err_status_ok;\n    for (i=0; i < test_case->plaintext_length_octets; i++)\n      if (buffer[i] != test_case->plaintext[i]) {\n\tstatus = err_status_algo_fail;\n\tdebug_print(mod_cipher, \"test case %d failed\", case_num);\n\tdebug_print(mod_cipher, \"(failure at byte %d)\", i);\n      }\n    if (status) {\n\n      debug_print(mod_cipher, \"p computed: %s\",\n\t     octet_string_hex_string(buffer,\n\t\t  2*test_case->plaintext_length_octets));\n      debug_print(mod_cipher, \"p expected: %s\",\n\t\t  octet_string_hex_string(test_case->plaintext,\n\t\t\t  2*test_case->plaintext_length_octets));\n\n      cipher_dealloc(c);\n      return err_status_algo_fail;\n    }\n\n    /* deallocate the cipher */\n    status = cipher_dealloc(c);\n    if (status)\n      return status;\n    \n    /* \n     * the cipher passed the test case, so move on to the next test\n     * case in the list; if NULL, we'l proceed to the next test\n     */   \n    test_case = test_case->next_test_case;\n    ++case_num;\n  }\n  \n  /* now run some random invertibility tests */\n\n  /* allocate cipher, using paramaters from the first test case */\n  test_case = ct->test_data;\n  status = cipher_type_alloc(ct, &c, test_case->key_length_octets);\n  if (status)\n      return status;\n  \n  rand_source_init();\n  \n  for (j=0; j < NUM_RAND_TESTS; j++) {\n    unsigned length;\n    unsigned plaintext_len;\n    uint8_t key[MAX_KEY_LEN];\n    uint8_t  iv[MAX_KEY_LEN];\n\n    /* choose a length at random (leaving room for IV and padding) */\n    length = rand() % (SELF_TEST_BUF_OCTETS - 64);\n    debug_print(mod_cipher, \"random plaintext length %d\\n\", length);\n    status = rand_source_get_octet_string(buffer, length);\n    if (status) return status;\n\n    debug_print(mod_cipher, \"plaintext:    %s\",\n\t\toctet_string_hex_string(buffer, length));\n\n    /* copy plaintext into second buffer */\n    for (i=0; (unsigned int)i < length; i++)\n      buffer2[i] = buffer[i];\n    \n    /* choose a key at random */\n    if (test_case->key_length_octets > MAX_KEY_LEN)\n      return err_status_cant_check;\n    status = rand_source_get_octet_string(key, test_case->key_length_octets);\n    if (status) return status;\n\n   /* chose a random initialization vector */\n    status = rand_source_get_octet_string(iv, MAX_KEY_LEN);\n    if (status) return status;\n        \n    /* initialize cipher */\n    status = cipher_init(c, key, direction_encrypt);\n    if (status) {\n      cipher_dealloc(c);\n      return status;\n    }\n\n    /* set initialization vector */\n    status = cipher_set_iv(c, test_case->idx);\n    if (status) {\n      cipher_dealloc(c);\n      return status;\n    } \n\n    /* encrypt buffer with cipher */\n    plaintext_len = length;\n    status = cipher_encrypt(c, buffer, &length);\n    if (status) {\n      cipher_dealloc(c);\n      return status;\n    }\n    debug_print(mod_cipher, \"ciphertext:   %s\",\n\t\toctet_string_hex_string(buffer, length));\n\n    /* \n     * re-initialize cipher for decryption, re-set the iv, then\n     * decrypt the ciphertext\n     */\n    status = cipher_init(c, key, direction_decrypt);\n    if (status) {\n      cipher_dealloc(c);\n      return status;\n    }\n    status = cipher_set_iv(c, test_case->idx);\n    if (status) {\n      cipher_dealloc(c);\n      return status;\n    } \n    status = cipher_decrypt(c, buffer, &length);\n    if (status) {\n      cipher_dealloc(c);\n      return status;\n    }    \n\n    debug_print(mod_cipher, \"plaintext[2]: %s\",\n\t\toctet_string_hex_string(buffer, length));    \n\n    /* compare the resulting plaintext with the original one */\n    if (length != plaintext_len)\n      return err_status_algo_fail;\n    status = err_status_ok;\n    for (i=0; i < plaintext_len; i++)\n      if (buffer[i] != buffer2[i]) {\n\tstatus = err_status_algo_fail;\n\tdebug_print(mod_cipher, \"random test case %d failed\", case_num);\n\tdebug_print(mod_cipher, \"(failure at byte %d)\", i);\n      }\n    if (status) {\n      cipher_dealloc(c);\n      return err_status_algo_fail;\n    }\n        \n  }\n\r\n  cipher_dealloc(c);\r\n\n  return err_status_ok;\n}\n\n\n/*\n * cipher_bits_per_second(c, l, t) computes (an estimate of) the\n * number of bits that a cipher implementation can encrypt in a second\n * \n * c is a cipher (which MUST be allocated and initialized already), l\n * is the length in octets of the test data to be encrypted, and t is\n * the number of trials\n *\n * if an error is encountered, the value 0 is returned\n */\n\nuint64_t\ncipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials) {\n  int i;\n  v128_t nonce;\n  clock_t timer;\n  unsigned char *enc_buf;\n  unsigned int len = octets_in_buffer;\n\n  enc_buf = (unsigned char*) crypto_alloc(octets_in_buffer);\n  if (enc_buf == NULL)\n    return 0;  /* indicate bad parameters by returning null */\n  \n  /* time repeated trials */\n  v128_set_to_zero(&nonce);\n  timer = clock();\n  for(i=0; i < num_trials; i++, nonce.v32[3] = i) {\n    cipher_set_iv(c, &nonce);\n    cipher_encrypt(c, enc_buf, &len);\n  }\n  timer = clock() - timer;\n\n  crypto_free(enc_buf);\n\n  if (timer == 0) {\n    /* Too fast! */\n    return 0;\n  }\n  \n  return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/cipher/null_cipher.c",
    "content": "/*\n * null_cipher.c\n *\n * A null cipher implementation.  This cipher leaves the plaintext\n * unchanged.\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#include \"datatypes.h\"\n#include \"null_cipher.h\"\n#include \"alloc.h\"\n\n/* the null_cipher uses the cipher debug module  */\n\nextern debug_module_t mod_cipher;\n\nerr_status_t\nnull_cipher_alloc(cipher_t **c, int key_len) {\n  extern cipher_type_t null_cipher;\n  uint8_t *pointer;\n  \n  debug_print(mod_cipher, \n\t      \"allocating cipher with key length %d\", key_len);\n\n  /* allocate memory a cipher of type null_cipher */\n  pointer = (uint8_t*)crypto_alloc(sizeof(null_cipher_ctx_t) + sizeof(cipher_t));\n  if (pointer == NULL)\n    return err_status_alloc_fail;\n\n  /* set pointers */\n  *c = (cipher_t *)pointer;\n  (*c)->type = &null_cipher;\n  (*c)->state = pointer + sizeof(cipher_t);\n\n  /* set key size */\n  (*c)->key_len = key_len;\n\n  /* increment ref_count */\n  null_cipher.ref_count++;\n  \n  return err_status_ok;\n  \n}\n\nerr_status_t\nnull_cipher_dealloc(cipher_t *c) {\n  extern cipher_type_t null_cipher;\n\n  /* zeroize entire state*/\n  octet_string_set_to_zero((uint8_t *)c, \n\t\t\t   sizeof(null_cipher_ctx_t) + sizeof(cipher_t));\n\n  /* free memory of type null_cipher */\n  crypto_free(c);\n\n  /* decrement reference count */\n  null_cipher.ref_count--;\n  \n  return err_status_ok;\n  \n}\n\nerr_status_t\nnull_cipher_init(null_cipher_ctx_t *ctx, const uint8_t *key) {\n\n  debug_print(mod_cipher, \"initializing null cipher\", NULL);\n\n  return err_status_ok;\n}\n\nerr_status_t\nnull_cipher_set_iv(null_cipher_ctx_t *c, void *iv) { \n  return err_status_ok;\n}\n\nerr_status_t\nnull_cipher_encrypt(null_cipher_ctx_t *c,\n\t\t    unsigned char *buf, unsigned int *bytes_to_encr) {\n  return err_status_ok;\n}\n\nchar \nnull_cipher_description[] = \"null cipher\";\n\ncipher_test_case_t  \nnull_cipher_test_0 = {\n  0,                 /* octets in key            */\n  NULL,              /* key                      */\n  0,                 /* packet index             */\n  0,                 /* octets in plaintext      */\n  NULL,              /* plaintext                */\n  0,                 /* octets in plaintext      */\n  NULL,              /* ciphertext               */\n  NULL               /* pointer to next testcase */\n};\n\n\n/*\n * note: the decrypt function is idential to the encrypt function\n */\n\ncipher_type_t null_cipher = {\n  (cipher_alloc_func_t)         null_cipher_alloc,\n  (cipher_dealloc_func_t)       null_cipher_dealloc,\n  (cipher_init_func_t)          null_cipher_init,\n  (cipher_encrypt_func_t)       null_cipher_encrypt,\n  (cipher_decrypt_func_t)       null_cipher_encrypt,\n  (cipher_set_iv_func_t)        null_cipher_set_iv,\n  (char *)                      null_cipher_description,\n  (int)                         0,\n  (cipher_test_case_t *)       &null_cipher_test_0,\n  (debug_module_t *)            NULL\n};\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/hash/auth.c",
    "content": "/*\n * auth.c\n *\n * some bookkeeping functions for authentication functions\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#include \"auth.h\"\n\n/* the debug module for authentiation */\n\ndebug_module_t mod_auth = {\n  0,                  /* debugging is off by default */\n  \"auth func\"         /* printable name for module   */\n};\n\n\nint\nauth_get_key_length(const auth_t *a) {\n  return a->key_len;\n}\n\nint\nauth_get_tag_length(const auth_t *a) {\n  return a->out_len;\n}\n\nint\nauth_get_prefix_length(const auth_t *a) {\n  return a->prefix_len;\n}\n\nint\nauth_type_get_ref_count(const auth_type_t *at) {\n  return at->ref_count;\n}\n\n/*\n * auth_type_self_test() tests an auth function of type ct against\n * test cases provided in an array of values of key, data, and tag\n * that is known to be good\n */\n\n/* should be big enough for most occasions */\n#define SELF_TEST_TAG_BUF_OCTETS 32\n\nerr_status_t\nauth_type_self_test(const auth_type_t *at) {\n  auth_test_case_t *test_case = at->test_data;\n  auth_t *a;\n  err_status_t status;\n  uint8_t tag[SELF_TEST_TAG_BUF_OCTETS];\n  int i, case_num = 0;\n\n  debug_print(mod_auth, \"running self-test for auth function %s\", \n\t      at->description);\n  \n  /*\n   * check to make sure that we have at least one test case, and\n   * return an error if we don't - we need to be paranoid here\n   */\n  if (test_case == NULL)\n    return err_status_cant_check;\n\n  /* loop over all test cases */  \n  while (test_case != NULL) {\n\n    /* check test case parameters */\n    if (test_case->tag_length_octets > SELF_TEST_TAG_BUF_OCTETS)\n      return err_status_bad_param;\n    \n    /* allocate auth */\n    status = auth_type_alloc(at, &a, test_case->key_length_octets,\n\t\t\t     test_case->tag_length_octets);\n    if (status)\n      return status;\n    \n    /* initialize auth */\n    status = auth_init(a, test_case->key);\n    if (status) {\n      auth_dealloc(a);\n      return status;\n    }\n\n    /* zeroize tag then compute */\n    octet_string_set_to_zero(tag, test_case->tag_length_octets);\n    status = auth_compute(a, test_case->data,\n\t\t\t  test_case->data_length_octets, tag);\n    if (status) {\n      auth_dealloc(a);\n      return status;\n    }\n    \n    debug_print(mod_auth, \"key: %s\",\n\t\toctet_string_hex_string(test_case->key,\n\t\t\t\t\ttest_case->key_length_octets));\n    debug_print(mod_auth, \"data: %s\",\n\t\toctet_string_hex_string(test_case->data,\n\t\t\t\t   test_case->data_length_octets));\n    debug_print(mod_auth, \"tag computed: %s\",\n\t   octet_string_hex_string(tag, test_case->tag_length_octets));\n    debug_print(mod_auth, \"tag expected: %s\",\n\t   octet_string_hex_string(test_case->tag,\n\t\t\t\t   test_case->tag_length_octets));\n\n    /* check the result */\n    status = err_status_ok;\n    for (i=0; i < test_case->tag_length_octets; i++)\n      if (tag[i] != test_case->tag[i]) {\n\tstatus = err_status_algo_fail;\n\tdebug_print(mod_auth, \"test case %d failed\", case_num);\n\tdebug_print(mod_auth, \"  (mismatch at octet %d)\", i);\n      }\n    if (status) {\n      auth_dealloc(a);\n      return err_status_algo_fail;\n    }\n    \n    /* deallocate the auth function */\n    status = auth_dealloc(a);\n    if (status)\n      return status;\n    \n    /* \n     * the auth function passed the test case, so move on to the next test\n     * case in the list; if NULL, we'll quit and return an OK\n     */   \n    test_case = test_case->next_test_case;\n    ++case_num;\n  }\n  \n  return err_status_ok;\n}\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/hash/hmac.c",
    "content": "/*\n * hmac.c\n *\n * implementation of hmac auth_type_t\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright(c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#include \"hmac.h\" \n#include \"alloc.h\"\n\n/* the debug module for authentiation */\n\ndebug_module_t mod_hmac = {\n  0,                  /* debugging is off by default */\n  \"hmac sha-1\"        /* printable name for module   */\n};\n\n\nerr_status_t\nhmac_alloc(auth_t **a, int key_len, int out_len) {\n  extern auth_type_t hmac;\n  uint8_t *pointer;\n\n  debug_print(mod_hmac, \"allocating auth func with key length %d\", key_len);\n  debug_print(mod_hmac, \"                          tag length %d\", out_len);\n\n  /*\n   * check key length - note that we don't support keys larger\n   * than 20 bytes yet\n   */\n  if (key_len > 20)\n    return err_status_bad_param;\n\n  /* check output length - should be less than 20 bytes */\n  if (out_len > 20)\n    return err_status_bad_param;\n\n  /* allocate memory for auth and hmac_ctx_t structures */\n  pointer = (uint8_t*)crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t));\n  if (pointer == NULL)\n    return err_status_alloc_fail;\n\n  /* set pointers */\n  *a = (auth_t *)pointer;\n  (*a)->type = &hmac;\n  (*a)->state = pointer + sizeof(auth_t);  \n  (*a)->out_len = out_len;\n  (*a)->key_len = key_len;\n  (*a)->prefix_len = 0;\n\n  /* increment global count of all hmac uses */\n  hmac.ref_count++;\n\n  return err_status_ok;\n}\n\nerr_status_t\nhmac_dealloc(auth_t *a) {\n  extern auth_type_t hmac;\n  \n  /* zeroize entire state*/\n  octet_string_set_to_zero((uint8_t *)a, \n\t\t\t   sizeof(hmac_ctx_t) + sizeof(auth_t));\n\n  /* free memory */\n  crypto_free(a);\n  \n  /* decrement global count of all hmac uses */\n  hmac.ref_count--;\n\n  return err_status_ok;\n}\n\nerr_status_t\nhmac_init(hmac_ctx_t *state, const uint8_t *key, int key_len) {\n  int i;\n  uint8_t ipad[64]; \n  \n    /*\n   * check key length - note that we don't support keys larger\n   * than 20 bytes yet\n   */\n  if (key_len > 20)              \n    return err_status_bad_param;\n  \n  /*\n   * set values of ipad and opad by exoring the key into the\n   * appropriate constant values\n   */\n  for (i=0; i < key_len; i++) {    \n    ipad[i] = key[i] ^ 0x36;\n    state->opad[i] = key[i] ^ 0x5c;\n  }  \n  /* set the rest of ipad, opad to constant values */\n  for (   ; i < 64; i++) {    \n    ipad[i] = 0x36;\n    ((uint8_t *)state->opad)[i] = 0x5c;\n  }  \n\n  debug_print(mod_hmac, \"ipad: %s\", octet_string_hex_string(ipad, 64));\n  \n  /* initialize sha1 context */\n  sha1_init(&state->init_ctx);\n\n  /* hash ipad ^ key */\n  sha1_update(&state->init_ctx, ipad, 64);\n  memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t)); \n\n  return err_status_ok;\n}\n\nerr_status_t\nhmac_start(hmac_ctx_t *state) {\n    \n  memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t));\n\n  return err_status_ok;\n}\n\nerr_status_t\nhmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets) {\n\n  debug_print(mod_hmac, \"input: %s\", \n\t      octet_string_hex_string(message, msg_octets));\n  \n  /* hash message into sha1 context */\n  sha1_update(&state->ctx, message, msg_octets);\n\n  return err_status_ok;\n}\n\nerr_status_t\nhmac_compute(hmac_ctx_t *state, const void *message,\n\t     int msg_octets, int tag_len, uint8_t *result) {\n  uint32_t hash_value[5];\n  uint32_t H[5];\n  int i;\n\n  /* check tag length, return error if we can't provide the value expected */\n  if (tag_len > 20)\n    return err_status_bad_param;\n  \n  /* hash message, copy output into H */\n  hmac_update(state, (const uint8_t*)message, msg_octets);\n  sha1_final(&state->ctx, H);\n\n  /*\n   * note that we don't need to debug_print() the input, since the\n   * function hmac_update() already did that for us\n   */\n  debug_print(mod_hmac, \"intermediate state: %s\", \n\t      octet_string_hex_string((uint8_t *)H, 20));\n\n  /* re-initialize hash context */\n  sha1_init(&state->ctx);\n  \n  /* hash opad ^ key  */\n  sha1_update(&state->ctx, (uint8_t *)state->opad, 64);\n\n  /* hash the result of the inner hash */\n  sha1_update(&state->ctx, (uint8_t *)H, 20);\n  \n  /* the result is returned in the array hash_value[] */\n  sha1_final(&state->ctx, hash_value);\n\n  /* copy hash_value to *result */\n  for (i=0; i < tag_len; i++)    \n    result[i] = ((uint8_t *)hash_value)[i];\n\n  debug_print(mod_hmac, \"output: %s\", \n\t      octet_string_hex_string((uint8_t *)hash_value, tag_len));\n\n  return err_status_ok;\n}\n\n\n/* begin test case 0 */\n\nuint8_t\nhmac_test_case_0_key[20] = {\n  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, \n  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, \n  0x0b, 0x0b, 0x0b, 0x0b\n};\n\nuint8_t \nhmac_test_case_0_data[8] = {\n  0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65   /* \"Hi There\" */\n};\n\nuint8_t\nhmac_test_case_0_tag[20] = {\n  0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, \n  0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, \n  0xf1, 0x46, 0xbe, 0x00\n};\n\nauth_test_case_t\nhmac_test_case_0 = {\n  20,                        /* octets in key            */\n  hmac_test_case_0_key,      /* key                      */\n  8,                         /* octets in data           */ \n  hmac_test_case_0_data,     /* data                     */\n  20,                        /* octets in tag            */\n  hmac_test_case_0_tag,      /* tag                      */\n  NULL                       /* pointer to next testcase */\n};\n\n/* end test case 0 */\n\nchar hmac_description[] = \"hmac sha-1 authentication function\";\n\n/*\n * auth_type_t hmac is the hmac metaobject\n */\n\nauth_type_t\nhmac  = {\n  (auth_alloc_func)      hmac_alloc,\n  (auth_dealloc_func)    hmac_dealloc,\n  (auth_init_func)       hmac_init,\n  (auth_compute_func)    hmac_compute,\n  (auth_update_func)     hmac_update,\n  (auth_start_func)      hmac_start,\n  (char *)               hmac_description,\n  (int)                  0,  /* instance count */\n  (auth_test_case_t *)  &hmac_test_case_0,\n  (debug_module_t *)    &mod_hmac\n};\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/hash/null_auth.c",
    "content": "/*\n * null_auth.c\n *\n * implements the do-nothing auth algorithm\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n *\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#include \"null_auth.h\" \n#include \"alloc.h\"\n\n/* null_auth uses the auth debug module */\n\nextern debug_module_t mod_auth;\n\nerr_status_t\nnull_auth_alloc(auth_t **a, int key_len, int out_len) {\n  extern auth_type_t null_auth;\n  uint8_t *pointer;\n\n  debug_print(mod_auth, \"allocating auth func with key length %d\", key_len);\n  debug_print(mod_auth, \"                          tag length %d\", out_len);\n\n  /* allocate memory for auth and null_auth_ctx_t structures */\n  pointer = (uint8_t*)crypto_alloc(sizeof(null_auth_ctx_t) + sizeof(auth_t));\n  if (pointer == NULL)\n    return err_status_alloc_fail;\n\n  /* set pointers */\n  *a = (auth_t *)pointer;\n  (*a)->type = &null_auth;\n  (*a)->state = pointer + sizeof (auth_t);  \n  (*a)->out_len = out_len;\n  (*a)->prefix_len = out_len;\n  (*a)->key_len = key_len;\n\n  /* increment global count of all null_auth uses */\n  null_auth.ref_count++;\n\n  return err_status_ok;\n}\n\nerr_status_t\nnull_auth_dealloc(auth_t *a) {\n  extern auth_type_t null_auth;\n  \n  /* zeroize entire state*/\n  octet_string_set_to_zero((uint8_t *)a, \n\t\t\t   sizeof(null_auth_ctx_t) + sizeof(auth_t));\n\n  /* free memory */\n  crypto_free(a);\n  \n  /* decrement global count of all null_auth uses */\n  null_auth.ref_count--;\n\n  return err_status_ok;\n}\n\nerr_status_t\nnull_auth_init(null_auth_ctx_t *state, const uint8_t *key, int key_len) {\n\n  /* accept any length of key, and do nothing */\n  \n  return err_status_ok;\n}\n\nerr_status_t\nnull_auth_compute(null_auth_ctx_t *state, uint8_t *message,\n\t\t   int msg_octets, int tag_len, uint8_t *result) {\n\n  return err_status_ok;\n}\n\nerr_status_t\nnull_auth_update(null_auth_ctx_t *state, uint8_t *message,\n\t\t   int msg_octets) {\n\n  return err_status_ok;\n}\n\nerr_status_t\nnull_auth_start(null_auth_ctx_t *state) {\n  return err_status_ok;\n}\n\n/*\n * auth_type_t - defines description, test case, and null_auth\n * metaobject\n */\n\n/* begin test case 0 */\n\nauth_test_case_t\nnull_auth_test_case_0 = {\n  0,                                       /* octets in key            */\n  NULL,                                    /* key                      */\n  0,                                       /* octets in data           */ \n  NULL,                                    /* data                     */\n  0,                                       /* octets in tag            */\n  NULL,                                    /* tag                      */\n  NULL                                     /* pointer to next testcase */\n};\n\n/* end test case 0 */\n\nchar null_auth_description[] = \"null authentication function\";\n\nauth_type_t\nnull_auth  = {\n  (auth_alloc_func)      null_auth_alloc,\n  (auth_dealloc_func)    null_auth_dealloc,\n  (auth_init_func)       null_auth_init,\n  (auth_compute_func)    null_auth_compute,\n  (auth_update_func)     null_auth_update,\n  (auth_start_func)      null_auth_start,\n  (char *)               null_auth_description,\n  (int)                  0,  /* instance count */\n  (auth_test_case_t *)   &null_auth_test_case_0\n};\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/hash/sha1.c",
    "content": "/*\n * sha1.c\n *\n * an implementation of the Secure Hash Algorithm v.1 (SHA-1),\n * specified in FIPS 180-1\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#include \"sha1.h\"\n\ndebug_module_t mod_sha1 = {\n  0,                 /* debugging is off by default */\n  \"sha-1\"            /* printable module name       */\n};\n\n/* SN == Rotate left N bits */\n#define S1(X)  ((X << 1)  | (X >> 31))\n#define S5(X)  ((X << 5)  | (X >> 27))\n#define S30(X) ((X << 30) | (X >> 2))\n\n#define f0(B,C,D) ((B & C) | (~B & D))              \n#define f1(B,C,D) (B ^ C ^ D)\n#define f2(B,C,D) ((B & C) | (B & D) | (C & D))\n#define f3(B,C,D) (B ^ C ^ D)\n\n/* \n * nota bene: the variable K0 appears in the curses library, so we \n * give longer names to these variables to avoid spurious warnings \n * on systems that uses curses\n */\n\nuint32_t SHA_K0 = 0x5A827999;   /* Kt for 0  <= t <= 19 */\nuint32_t SHA_K1 = 0x6ED9EBA1;   /* Kt for 20 <= t <= 39 */\nuint32_t SHA_K2 = 0x8F1BBCDC;   /* Kt for 40 <= t <= 59 */\nuint32_t SHA_K3 = 0xCA62C1D6;   /* Kt for 60 <= t <= 79 */\n\nvoid\nsha1(const uint8_t *msg,  int octets_in_msg, uint32_t hash_value[5]) {\n  sha1_ctx_t ctx;\n\n  sha1_init(&ctx);\n  sha1_update(&ctx, msg, octets_in_msg);\n  sha1_final(&ctx, hash_value);\n\n}\n\n/*\n *  sha1_core(M, H) computes the core compression function, where M is\n *  the next part of the message (in network byte order) and H is the\n *  intermediate state { H0, H1, ...} (in host byte order)\n *\n *  this function does not do any of the padding required in the\n *  complete SHA1 function\n *\n *  this function is used in the SEAL 3.0 key setup routines\n *  (crypto/cipher/seal.c)\n */\n\nvoid\nsha1_core(const uint32_t M[16], uint32_t hash_value[5]) {\n  uint32_t H0;\n  uint32_t H1;\n  uint32_t H2;\n  uint32_t H3;\n  uint32_t H4;\n  uint32_t W[80];\n  uint32_t A, B, C, D, E, TEMP;\n  int t;\n\n  /* copy hash_value into H0, H1, H2, H3, H4 */\n  H0 = hash_value[0];\n  H1 = hash_value[1];\n  H2 = hash_value[2];\n  H3 = hash_value[3];\n  H4 = hash_value[4];\n\n  /* copy/xor message into array */\n    \n  W[0]  = be32_to_cpu(M[0]);\n  W[1]  = be32_to_cpu(M[1]);\n  W[2]  = be32_to_cpu(M[2]);\n  W[3]  = be32_to_cpu(M[3]);\n  W[4]  = be32_to_cpu(M[4]);\n  W[5]  = be32_to_cpu(M[5]);\n  W[6]  = be32_to_cpu(M[6]);\n  W[7]  = be32_to_cpu(M[7]);\n  W[8]  = be32_to_cpu(M[8]);\n  W[9]  = be32_to_cpu(M[9]);\n  W[10] = be32_to_cpu(M[10]);\n  W[11] = be32_to_cpu(M[11]);\n  W[12] = be32_to_cpu(M[12]);\n  W[13] = be32_to_cpu(M[13]);\n  W[14] = be32_to_cpu(M[14]);\n  W[15] = be32_to_cpu(M[15]);\n  TEMP = W[13] ^ W[8]  ^ W[2]  ^ W[0];  W[16] = S1(TEMP);\n  TEMP = W[14] ^ W[9]  ^ W[3]  ^ W[1];  W[17] = S1(TEMP);\n  TEMP = W[15] ^ W[10] ^ W[4]  ^ W[2];  W[18] = S1(TEMP);\n  TEMP = W[16] ^ W[11] ^ W[5]  ^ W[3];  W[19] = S1(TEMP);\n  TEMP = W[17] ^ W[12] ^ W[6]  ^ W[4];  W[20] = S1(TEMP);\n  TEMP = W[18] ^ W[13] ^ W[7]  ^ W[5];  W[21] = S1(TEMP);\n  TEMP = W[19] ^ W[14] ^ W[8]  ^ W[6];  W[22] = S1(TEMP);\n  TEMP = W[20] ^ W[15] ^ W[9]  ^ W[7];  W[23] = S1(TEMP);\n  TEMP = W[21] ^ W[16] ^ W[10] ^ W[8];  W[24] = S1(TEMP);\n  TEMP = W[22] ^ W[17] ^ W[11] ^ W[9];  W[25] = S1(TEMP);\n  TEMP = W[23] ^ W[18] ^ W[12] ^ W[10]; W[26] = S1(TEMP);\n  TEMP = W[24] ^ W[19] ^ W[13] ^ W[11]; W[27] = S1(TEMP);\n  TEMP = W[25] ^ W[20] ^ W[14] ^ W[12]; W[28] = S1(TEMP);\n  TEMP = W[26] ^ W[21] ^ W[15] ^ W[13]; W[29] = S1(TEMP);\n  TEMP = W[27] ^ W[22] ^ W[16] ^ W[14]; W[30] = S1(TEMP);\n  TEMP = W[28] ^ W[23] ^ W[17] ^ W[15]; W[31] = S1(TEMP);\n\n  /* process the remainder of the array */\n  for (t=32; t < 80; t++) {\n    TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];\n    W[t] = S1(TEMP);      \n  }\n\n  A = H0; B = H1; C = H2; D = H3; E = H4;\n\n  for (t=0; t < 20; t++) {\n    TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0;\n    E = D; D = C; C = S30(B); B = A; A = TEMP;\n  }\n  for (   ; t < 40; t++) {\n    TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1;\n    E = D; D = C; C = S30(B); B = A; A = TEMP;\n  }\n  for (   ; t < 60; t++) {\n    TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2;\n    E = D; D = C; C = S30(B); B = A; A = TEMP;\n  }\n  for (   ; t < 80; t++) {\n    TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3;\n    E = D; D = C; C = S30(B); B = A; A = TEMP;\n  }\n\n  hash_value[0] = H0 + A;\n  hash_value[1] = H1 + B;\n  hash_value[2] = H2 + C;\n  hash_value[3] = H3 + D;\n  hash_value[4] = H4 + E;\n\n  return;\n}\n\nvoid\nsha1_init(sha1_ctx_t *ctx) {\n \n  /* initialize state vector */\n  ctx->H[0] = 0x67452301;\n  ctx->H[1] = 0xefcdab89;\n  ctx->H[2] = 0x98badcfe;\n  ctx->H[3] = 0x10325476;\n  ctx->H[4] = 0xc3d2e1f0;\n\n  /* indicate that message buffer is empty */\n  ctx->octets_in_buffer = 0;\n\n  /* reset message bit-count to zero */\n  ctx->num_bits_in_msg = 0;\n\n}\n\nvoid\nsha1_update(sha1_ctx_t *ctx, const uint8_t *msg, int octets_in_msg) {\n  int i;\n  uint8_t *buf = (uint8_t *)ctx->M;\n\n  /* update message bit-count */\n  ctx->num_bits_in_msg += octets_in_msg * 8;\n\n  /* loop over 16-word blocks of M */\n  while (octets_in_msg > 0) {\n    \n    if (octets_in_msg + ctx->octets_in_buffer >= 64) {\n\n      /* \n       * copy words of M into msg buffer until that buffer is full,\n       * converting them into host byte order as needed\n       */\n      octets_in_msg -= (64 - ctx->octets_in_buffer);\n      for (i=ctx->octets_in_buffer; i < 64; i++) \n\tbuf[i] = *msg++;\n      ctx->octets_in_buffer = 0;\n\n      /* process a whole block */\n\n      debug_print(mod_sha1, \"(update) running sha1_core()\", NULL);\n\n      sha1_core(ctx->M, ctx->H);\n\n    } else {\n\n      debug_print(mod_sha1, \"(update) not running sha1_core()\", NULL);\n\n      for (i=ctx->octets_in_buffer; \n\t   i < (ctx->octets_in_buffer + octets_in_msg); i++)\n\tbuf[i] = *msg++;\n      ctx->octets_in_buffer += octets_in_msg;\n      octets_in_msg = 0;\n    }\n\n  }\n\n}\n\n/*\n * sha1_final(ctx, output) computes the result for ctx and copies it\n * into the twenty octets located at *output\n */\n\nvoid\nsha1_final(sha1_ctx_t *ctx, uint32_t *output) {\n  uint32_t A, B, C, D, E, TEMP;\n  uint32_t W[80];  \n  int i, t;\n\n  /*\n   * process the remaining octets_in_buffer, padding and terminating as\n   * necessary\n   */\n  {\n    int tail = ctx->octets_in_buffer % 4;\n    \n    /* copy/xor message into array */\n    for (i=0; i < (ctx->octets_in_buffer+3)/4; i++) \n      W[i]  = be32_to_cpu(ctx->M[i]);\n\n    /* set the high bit of the octet immediately following the message */\n    switch (tail) {\n    case (3):\n      W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xffffff00) | 0x80;\n      W[i] = 0x0;\n      break;\n    case (2):      \n      W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xffff0000) | 0x8000;\n      W[i] = 0x0;\n      break;\n    case (1):\n      W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xff000000) | 0x800000;\n      W[i] = 0x0;\n      break;\n    case (0):\n      W[i] = 0x80000000;\n      break;\n    }\n    \n    /* zeroize remaining words */\n    for (i++   ; i < 15; i++)\n      W[i] = 0x0;\n\n    /* \n     * if there is room at the end of the word array, then set the\n     * last word to the bit-length of the message; otherwise, set that\n     * word to zero and then we need to do one more run of the\n     * compression algo.\n     */\n    if (ctx->octets_in_buffer < 56) \n      W[15] = ctx->num_bits_in_msg;\n    else if (ctx->octets_in_buffer < 60)\n      W[15] = 0x0;\n\n    /* process the word array */    for (t=16; t < 80; t++) {\n      TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];\n      W[t] = S1(TEMP);\n    }\n\n    A = ctx->H[0]; \n    B = ctx->H[1]; \n    C = ctx->H[2]; \n    D = ctx->H[3]; \n    E = ctx->H[4];\n\n    for (t=0; t < 20; t++) {\n      TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0;\n      E = D; D = C; C = S30(B); B = A; A = TEMP;\n    }\n    for (   ; t < 40; t++) {\n      TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1;\n      E = D; D = C; C = S30(B); B = A; A = TEMP;\n    }\n    for (   ; t < 60; t++) {\n      TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2;\n      E = D; D = C; C = S30(B); B = A; A = TEMP;\n    }\n    for (   ; t < 80; t++) {\n      TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3;\n      E = D; D = C; C = S30(B); B = A; A = TEMP;\n    }\n\n    ctx->H[0] += A;\n    ctx->H[1] += B;\n    ctx->H[2] += C;\n    ctx->H[3] += D;\n    ctx->H[4] += E;\n\n  }\n\n  debug_print(mod_sha1, \"(final) running sha1_core()\", NULL);\n\n  if (ctx->octets_in_buffer >= 56) {\n\n    debug_print(mod_sha1, \"(final) running sha1_core() again\", NULL);\n\n    /* we need to do one final run of the compression algo */\n\n    /* \n     * set initial part of word array to zeros, and set the \n     * final part to the number of bits in the message\n     */\n    for (i=0; i < 15; i++)\n      W[i] = 0x0;\n    W[15] = ctx->num_bits_in_msg;\n\n    /* process the word array */\n    for (t=16; t < 80; t++) {\n      TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];\n      W[t] = S1(TEMP);\n    }\n\n    A = ctx->H[0]; \n    B = ctx->H[1]; \n    C = ctx->H[2]; \n    D = ctx->H[3]; \n    E = ctx->H[4];\n\n    for (t=0; t < 20; t++) {\n      TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0;\n      E = D; D = C; C = S30(B); B = A; A = TEMP;\n    }\n    for (   ; t < 40; t++) {\n      TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1;\n      E = D; D = C; C = S30(B); B = A; A = TEMP;\n    }\n    for (   ; t < 60; t++) {\n      TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2;\n      E = D; D = C; C = S30(B); B = A; A = TEMP;\n    }\n    for (   ; t < 80; t++) {\n      TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3;\n      E = D; D = C; C = S30(B); B = A; A = TEMP;\n    }\n\n    ctx->H[0] += A;\n    ctx->H[1] += B;\n    ctx->H[2] += C;\n    ctx->H[3] += D;\n    ctx->H[4] += E;\n  }\n\n  /* copy result into output buffer */\n  output[0] = be32_to_cpu(ctx->H[0]);\n  output[1] = be32_to_cpu(ctx->H[1]);\n  output[2] = be32_to_cpu(ctx->H[2]);\n  output[3] = be32_to_cpu(ctx->H[3]);\n  output[4] = be32_to_cpu(ctx->H[4]);\n\n  /* indicate that message buffer in context is empty */\n  ctx->octets_in_buffer = 0;\n\n  return;\n}\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/aes.h",
    "content": "/*\n * aes.h\n *\n * header file for the AES block cipher\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#ifndef _AES_H\n#define _AES_H\n\n#include \"srtp_config.h\"\n\n#include \"datatypes.h\"\n#include \"gf2_8.h\"\n\n/* aes internals */\n\ntypedef v128_t aes_expanded_key_t[11];\n\nvoid\naes_expand_encryption_key(const v128_t *key,\n\t\t\t  aes_expanded_key_t expanded_key);\n\nvoid\naes_expand_decryption_key(const v128_t *key,\n\t\t\t  aes_expanded_key_t expanded_key);\n\nvoid\naes_encrypt(v128_t *plaintext, const aes_expanded_key_t exp_key);\n\nvoid\naes_decrypt(v128_t *plaintext, const aes_expanded_key_t exp_key);\n\n#if 0\n/*\n * internal functions \n */\n\nvoid\naes_init_sbox(void);\n\nvoid\naes_compute_tables(void);\n#endif \n\n#endif /* _AES_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/aes_cbc.h",
    "content": "/*\n * aes_cbc.h\n *\n * Header for AES Cipher Blobk Chaining Mode.\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n *\n */\n\n#ifndef AES_CBC_H\n#define AES_CBC_H\n\n#include \"aes.h\"\n#include \"cipher.h\"\n\ntypedef struct {\n  v128_t   state;                  /* cipher chaining state            */\n  v128_t   previous;               /* previous ciphertext block        */\n  aes_expanded_key_t expanded_key; /* the cipher key                   */\n} aes_cbc_ctx_t;\n\nerr_status_t\naes_cbc_set_key(aes_cbc_ctx_t *c,\n\t\tconst unsigned char *key); \n\nerr_status_t\naes_cbc_encrypt(aes_cbc_ctx_t *c, \n\t\tunsigned char *buf, \n\t\tunsigned int  *bytes_in_data);\n\nerr_status_t\naes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, \n\t\t     cipher_direction_t dir);\n\nerr_status_t\naes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv);\n\nerr_status_t\naes_cbc_nist_encrypt(aes_cbc_ctx_t *c,\n\t\t     unsigned char *data, \n\t\t     unsigned int *bytes_in_data);\n\nerr_status_t\naes_cbc_nist_decrypt(aes_cbc_ctx_t *c,\n\t\t     unsigned char *data, \n\t\t     unsigned int *bytes_in_data);\n\n#endif /* AES_CBC_H */\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/aes_icm.h",
    "content": "/*\n * aes_icm.h\n *\n * Header for AES Integer Counter Mode.\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n *\n */\n\n#ifndef AES_ICM_H\n#define AES_ICM_H\n\n#include \"aes.h\"\n#include \"cipher.h\"\n\ntypedef struct {\n  v128_t   counter;                /* holds the counter value          */\n  v128_t   offset;                 /* initial offset value             */\n  v128_t   keystream_buffer;       /* buffers bytes of keystream       */\n  aes_expanded_key_t expanded_key; /* the cipher key                   */\n  int      bytes_in_buffer;        /* number of unused bytes in buffer */\n} aes_icm_ctx_t;\n\n\nerr_status_t\naes_icm_context_init(aes_icm_ctx_t *c,\n\t\t     const unsigned char *key); \n\nerr_status_t\naes_icm_set_iv(aes_icm_ctx_t *c, void *iv);\n\nerr_status_t\naes_icm_encrypt(aes_icm_ctx_t *c,\n\t\tunsigned char *buf, unsigned int *bytes_to_encr);\n\nerr_status_t\naes_icm_output(aes_icm_ctx_t *c,\n\t       unsigned char *buf, int bytes_to_output);\n\nerr_status_t \naes_icm_dealloc(cipher_t *c);\n \nerr_status_t \naes_icm_encrypt_ismacryp(aes_icm_ctx_t *c, \n\t\t\t unsigned char *buf, \n\t\t\t unsigned int *enc_len, \n\t\t\t int forIsmacryp);\n \nerr_status_t \naes_icm_alloc_ismacryp(cipher_t **c, \n\t\t       int key_len, \n\t\t       int forIsmacryp);\n\n#endif /* AES_ICM_H */\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/alloc.h",
    "content": "/*\n * alloc.h\n *\n * interface to memory allocation and deallocation, with optional debugging \n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#ifndef CRYPTO_ALLOC_H\n#define CRYPTO_ALLOC_H\n\n#include \"datatypes.h\"\n\nvoid *\ncrypto_alloc(size_t size);\n\nvoid\ncrypto_free(void *ptr);\n\n#endif /* CRYPTO_ALLOC_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/auth.h",
    "content": "/*\n * auth.h\n *\n * common interface to authentication functions\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#ifndef AUTH_H\n#define AUTH_H\n\n#include \"datatypes.h\"          \n#include \"err.h\"                /* error codes    */\n\ntypedef struct auth_type_t *auth_type_pointer;\ntypedef struct auth_t      *auth_pointer_t;\n\ntypedef err_status_t (*auth_alloc_func)\n     (auth_pointer_t *ap, int key_len, int out_len);\n\ntypedef err_status_t (*auth_init_func)\n     (void *state, const uint8_t *key, int key_len);\n\ntypedef err_status_t (*auth_dealloc_func)(auth_pointer_t ap);\n\ntypedef err_status_t (*auth_compute_func)\n     (void *state, uint8_t *buffer, int octets_to_auth, \n      int tag_len, uint8_t *tag);\n\ntypedef err_status_t (*auth_update_func)\n     (void *state, uint8_t *buffer, int octets_to_auth);\n\ntypedef err_status_t (*auth_start_func)(void *state);\n     \n/* some syntactic sugar on these function types */\n\n#define auth_type_alloc(at, a, klen, outlen)                        \\\n                 ((at)->alloc((a), (klen), (outlen)))\n\n#define auth_init(a, key)                                           \\\n                 (((a)->type)->init((a)->state, (key), ((a)->key_len)))\n\n#define auth_compute(a, buf, len, res)                              \\\n       (((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res)))\n\n#define auth_update(a, buf, len)                                    \\\n       (((a)->type)->update((a)->state, (buf), (len)))\n\n#define auth_start(a)(((a)->type)->start((a)->state))\n\n#define auth_dealloc(c) (((c)->type)->dealloc(c))\n\n/* functions to get information about a particular auth_t */\n\nint\nauth_get_key_length(const struct auth_t *a);\n\nint\nauth_get_tag_length(const struct auth_t *a);\n\nint\nauth_get_prefix_length(const struct auth_t *a);\n\n/*\n * auth_test_case_t is a (list of) key/message/tag values that are\n * known to be correct for a particular cipher.  this data can be used\n * to test an implementation in an on-the-fly self test of the\n * correcness of the implementation.  (see the auth_type_self_test()\n * function below)\n */\n\ntypedef struct auth_test_case_t {\n  int key_length_octets;                    /* octets in key            */\n  uint8_t *key;                             /* key                      */\n  int data_length_octets;                   /* octets in data           */ \n  uint8_t *data;                            /* data                     */\n  int tag_length_octets;                    /* octets in tag            */\n  uint8_t *tag;                             /* tag                      */\n  struct auth_test_case_t *next_test_case;  /* pointer to next testcase */\n} auth_test_case_t;\n\n/* auth_type_t */\n\ntypedef struct auth_type_t {\n  auth_alloc_func      alloc;\n  auth_dealloc_func    dealloc;\n  auth_init_func       init;\n  auth_compute_func    compute;\n  auth_update_func     update;\n  auth_start_func      start;\n  char                *description;\n  int                  ref_count;\n  auth_test_case_t    *test_data;\n  debug_module_t      *debug;\n} auth_type_t;\n\ntypedef struct auth_t {\n  auth_type_t *type;\n  void        *state;                   \n  int          out_len;           /* length of output tag in octets */\n  int          key_len;           /* length of key in octets        */\n  int          prefix_len;        /* length of keystream prefix     */\n} auth_t;\n\n/* \n * auth_type_self_test() tests an auth_type against test cases\n * provided in an array of values of key/message/tag that is known to\n * be good\n */\n\nerr_status_t\nauth_type_self_test(const auth_type_t *at);\n\n/*\n * auth_type_get_ref_count(at) returns the reference count (the number\n * of instantiations) of the auth_type_t at\n */\n\nint\nauth_type_get_ref_count(const auth_type_t *at);\n\n#endif /* AUTH_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/cipher.h",
    "content": "/*\n * cipher.h\n *\n * common interface to ciphers\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#ifndef CIPHER_H\n#define CIPHER_H\n\n#include \"datatypes.h\"          \n#include \"rdbx.h\"               /* for xtd_seq_num_t */\n#include \"err.h\"                /* for error codes  */\n\n\n/**\n * @brief cipher_direction_t defines a particular cipher operation. \n *\n * A cipher_direction_t is an enum that describes a particular cipher\n * operation, i.e. encryption or decryption.  For some ciphers, this\n * distinction does not matter, but for others, it is essential.\n */\n\ntypedef enum { \n  direction_encrypt, /**< encryption (convert plaintext to ciphertext) */\n  direction_decrypt, /**< decryption (convert ciphertext to plaintext) */\n  direction_any      /**< encryption or decryption                     */\n} cipher_direction_t;\n\n/*\n * the cipher_pointer and cipher_type_pointer definitions are needed\n * as cipher_t and cipher_type_t are not yet defined\n */\n\ntypedef struct cipher_type_t *cipher_type_pointer_t;\ntypedef struct cipher_t      *cipher_pointer_t;\n\n/*\n *  a cipher_alloc_func_t allocates (but does not initialize) a cipher_t \n */\n\ntypedef err_status_t (*cipher_alloc_func_t)\n     (cipher_pointer_t *cp, int key_len);\n\n/* \n * a cipher_init_func_t [re-]initializes a cipher_t with a given key\n * and direction (i.e., encrypt or decrypt)\n */\n\ntypedef err_status_t (*cipher_init_func_t)\n  (void *state, const uint8_t *key, cipher_direction_t dir);\n\n/* a cipher_dealloc_func_t de-allocates a cipher_t */\n\ntypedef err_status_t (*cipher_dealloc_func_t)(cipher_pointer_t cp);\n\n/* a cipher_set_segment_func_t sets the segment index of a cipher_t */\n\ntypedef err_status_t (*cipher_set_segment_func_t)\n     (void *state, xtd_seq_num_t idx);\n\n/* a cipher_encrypt_func_t encrypts data in-place */\n\ntypedef err_status_t (*cipher_encrypt_func_t)\n     (void *state, uint8_t *buffer, unsigned int *octets_to_encrypt);\n\n/* a cipher_decrypt_func_t decrypts data in-place */\n\ntypedef err_status_t (*cipher_decrypt_func_t)\n     (void *state, uint8_t *buffer, unsigned int *octets_to_decrypt);\n\n/* \n * a cipher_set_nonce_seq_func_t function sets both the nonce\n * and the extended sequence number\n */\n\ntypedef err_status_t (*cipher_set_iv_func_t)\n     (cipher_pointer_t cp, void *iv);\n\n/*\n * cipher_test_case_t is a (list of) key, salt, xtd_seq_num_t,\n * plaintext, and ciphertext values that are known to be correct for a\n * particular cipher.  this data can be used to test an implementation\n * in an on-the-fly self test of the correcness of the implementation.\n * (see the cipher_type_self_test() function below)\n */\n\ntypedef struct cipher_test_case_t {\n  int key_length_octets;                      /* octets in key            */\n  uint8_t *key;                               /* key                      */\n  uint8_t *idx;                               /* packet index             */\n  unsigned int plaintext_length_octets;\t      /* octets in plaintext      */ \n  uint8_t *plaintext;                         /* plaintext                */\n  unsigned int ciphertext_length_octets;      /* octets in plaintext      */ \n  uint8_t *ciphertext;                        /* ciphertext               */\n  struct cipher_test_case_t *next_test_case;  /* pointer to next testcase */\n} cipher_test_case_t;\n\n/* cipher_type_t defines the 'metadata' for a particular cipher type */\n\ntypedef struct cipher_type_t {\n  cipher_alloc_func_t         alloc;\n  cipher_dealloc_func_t       dealloc;\n  cipher_init_func_t          init;\n  cipher_encrypt_func_t       encrypt;\n  cipher_encrypt_func_t       decrypt;\n  cipher_set_iv_func_t        set_iv;\n  char                       *description;\n  int                         ref_count;\n  cipher_test_case_t         *test_data;\n  debug_module_t             *debug;\n} cipher_type_t;\n\n/*\n * cipher_t defines an instantiation of a particular cipher, with fixed\n * key length, key and salt values\n */\n\ntypedef struct cipher_t {\n  cipher_type_t *type;\n  void          *state;\n  int            key_len;\n#ifdef FORCE_64BIT_ALIGN\n  int            pad;\n#endif\n} cipher_t;\n\n/* some syntactic sugar on these function types */\n\n#define cipher_type_alloc(ct, c, klen) ((ct)->alloc((c), (klen)))\n\n#define cipher_dealloc(c) (((c)->type)->dealloc(c))\n\n#define cipher_init(c, k, dir) (((c)->type)->init(((c)->state), (k), (dir)))\n\n#define cipher_encrypt(c, buf, len) \\\n        (((c)->type)->encrypt(((c)->state), (buf), (len)))\n\n#define cipher_decrypt(c, buf, len) \\\n        (((c)->type)->decrypt(((c)->state), (buf), (len)))\n\n#define cipher_set_iv(c, n)                           \\\n  ((c) ? (((c)->type)->set_iv(((cipher_pointer_t)(c)->state), (n))) :   \\\n                                err_status_no_such_op)  \n\nerr_status_t\ncipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output);\n\n\n/* some bookkeeping functions */\n\nint\ncipher_get_key_length(const cipher_t *c);\n\n\n/* \n * cipher_type_self_test() tests a cipher against test cases provided in \n * an array of values of key/xtd_seq_num_t/plaintext/ciphertext \n * that is known to be good\n */\n\nerr_status_t\ncipher_type_self_test(const cipher_type_t *ct);\n\n\n/*\n * cipher_bits_per_second(c, l, t) computes (and estimate of) the\n * number of bits that a cipher implementation can encrypt in a second\n * \n * c is a cipher (which MUST be allocated and initialized already), l\n * is the length in octets of the test data to be encrypted, and t is\n * the number of trials\n *\n * if an error is encountered, then the value 0 is returned\n */\n\nuint64_t\ncipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials);\n\n#endif /* CIPHER_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/crypto.h",
    "content": "/*\n * crypto.h\n *\n * API for libcrypto\n * \n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n#ifndef CRYPTO_H\n#define CRYPTO_H\n\n/** \n *  @brief A cipher_type_id_t is an identifier for a particular cipher\n *  type.\n *\n *  A cipher_type_id_t is an integer that represents a particular\n *  cipher type, e.g. the Advanced Encryption Standard (AES).  A\n *  NULL_CIPHER is avaliable; this cipher leaves the data unchanged,\n *  and can be selected to indicate that no encryption is to take\n *  place.\n * \n *  @ingroup Ciphers\n */\ntypedef uint32_t cipher_type_id_t; \n\n/**\n *  @brief An auth_type_id_t is an identifier for a particular authentication\n *   function.\n *\n *  An auth_type_id_t is an integer that represents a particular\n *  authentication function type, e.g. HMAC-SHA1.  A NULL_AUTH is\n *  avaliable; this authentication function performs no computation,\n *  and can be selected to indicate that no authentication is to take\n *  place.\n *  \n *  @ingroup Authentication\n */\ntypedef uint32_t auth_type_id_t;\n\n#endif /* CRYPTO_H */\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/crypto_kernel.h",
    "content": "/*\n * crypto_kernel.h\n *\n * header for the cryptographic kernel\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright(c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#ifndef CRYPTO_KERNEL\n#define CRYPTO_KERNEL\n\n#include \"rand_source.h\"       \n#include \"prng.h\"\n#include \"cipher.h\"    \n#include \"auth.h\"\n#include \"cryptoalg.h\"\n#include \"stat.h\"\n#include \"err.h\"\n#include \"crypto_types.h\"\n#include \"key.h\"\n#include \"crypto.h\"\n\n/*\n * crypto_kernel_state_t defines the possible states:\n *\n *    insecure - not yet initialized\n *    secure   - initialized and passed self-tests\n */\n\ntypedef enum {\n  crypto_kernel_state_insecure,\n  crypto_kernel_state_secure\n} crypto_kernel_state_t;\n\n/* \n * linked list of cipher types \n */\n\ntypedef struct kernel_cipher_type {\n  cipher_type_id_t  id;\n  cipher_type_t    *cipher_type;\n  struct kernel_cipher_type *next;\n} kernel_cipher_type_t;\n\n/* \n * linked list of auth types \n */\n\ntypedef struct kernel_auth_type {\n  auth_type_id_t  id;\n  auth_type_t    *auth_type;\n  struct kernel_auth_type *next;\n} kernel_auth_type_t;\n\n/*\n * linked list of debug modules \n */\n\ntypedef struct kernel_debug_module {\n  debug_module_t *mod;\n  struct kernel_debug_module *next;\n} kernel_debug_module_t;\n\n\n/*\n * crypto_kernel_t is the data structure for the crypto kernel\n *\n * note that there is *exactly one* instance of this data type,\n * a global variable defined in crypto_kernel.c\n */\n\ntypedef struct {\n  crypto_kernel_state_t state;              /* current state of kernel     */\n  kernel_cipher_type_t *cipher_type_list;   /* list of all cipher types    */\n  kernel_auth_type_t   *auth_type_list;     /* list of all auth func types */\n  kernel_debug_module_t *debug_module_list; /* list of all debug modules   */\n} crypto_kernel_t;\n\n\n/*\n * crypto_kernel_t external api\n */\n\n\n/*\n * The function crypto_kernel_init() initialized the crypto kernel and\n * runs the self-test operations on the random number generators and\n * crypto algorithms.  Possible return values are:\n *\n *    err_status_ok     initialization successful\n *    <other>           init failure \n *\n * If any value other than err_status_ok is returned, the\n * crypto_kernel MUST NOT be used.  \n */\n\nerr_status_t\ncrypto_kernel_init(void);\n\n\n/*\n * The function crypto_kernel_shutdown() de-initializes the\n * crypto_kernel, zeroizes keys and other cryptographic material, and\n * deallocates any dynamically allocated memory.  Possible return\n * values are:\n *\n *    err_status_ok     shutdown successful\n *    <other>           shutdown failure \n *\n */\n\nerr_status_t\ncrypto_kernel_shutdown(void);\n\n/*\n * The function crypto_kernel_stats() checks the the crypto_kernel,\n * running tests on the ciphers, auth funcs, and rng, and prints out a\n * status report.  Possible return values are:\n *\n *    err_status_ok     all tests were passed\n *    <other>           a test failed \n *\n */\n\nerr_status_t\ncrypto_kernel_status(void);\n\n\n/*\n * crypto_kernel_list_debug_modules() outputs a list of debugging modules\n *\n */\n\nerr_status_t\ncrypto_kernel_list_debug_modules(void);\n\n/*\n * crypto_kernel_load_cipher_type()\n *\n */\n\nerr_status_t\ncrypto_kernel_load_cipher_type(cipher_type_t *ct, cipher_type_id_t id);\n\nerr_status_t\ncrypto_kernel_load_auth_type(auth_type_t *ct, auth_type_id_t id);\n\nerr_status_t\ncrypto_kernel_load_debug_module(debug_module_t *new_dm);\n\n/*\n * crypto_kernel_alloc_cipher(id, cp, key_len); \n *\n * allocates a cipher of type id at location *cp, with key length\n * key_len octets.  Return values are:\n * \n *    err_status_ok           no problems\n *    err_status_alloc_fail   an allocation failure occured\n *    err_status_fail         couldn't find cipher with identifier 'id'\n */\n\nerr_status_t\ncrypto_kernel_alloc_cipher(cipher_type_id_t id, \n\t\t\t   cipher_pointer_t *cp, \n\t\t\t   int key_len);\n\n/*\n * crypto_kernel_alloc_auth(id, ap, key_len, tag_len); \n *\n * allocates an auth function of type id at location *ap, with key\n * length key_len octets and output tag length of tag_len.  Return\n * values are:\n * \n *    err_status_ok           no problems\n *    err_status_alloc_fail   an allocation failure occured\n *    err_status_fail         couldn't find auth with identifier 'id'\n */\n\nerr_status_t\ncrypto_kernel_alloc_auth(auth_type_id_t id, \n\t\t\t auth_pointer_t *ap, \n\t\t\t int key_len,\n\t\t\t int tag_len);\n\n\n/*\n * crypto_kernel_set_debug_module(mod_name, v)\n * \n * sets dynamic debugging to the value v (0 for off, 1 for on) for the\n * debug module with the name mod_name\n *\n * returns err_status_ok on success, err_status_fail otherwise\n */\n\nerr_status_t\ncrypto_kernel_set_debug_module(char *mod_name, int v);\n\n/**\n * @brief writes a random octet string.\n *\n * The function call crypto_get_random(dest, len) writes len octets of\n * random data to the location to which dest points, and returns an\n * error code.  This error code @b must be checked, and if a failure is\n * reported, the data in the buffer @b must @b not be used.\n * \n * @warning If the return code is not checked, then non-random\n *          data may be in the buffer.  This function will fail\n *          unless it is called after crypto_kernel_init().\n *\n * @return\n *     - err_status_ok    if no problems occured.\n *     - [other]          a problem occured, and no assumptions should\n *                        be made about the contents of the destination\n *                        buffer.\n *\n * @ingroup SRTP\n */\nerr_status_t\ncrypto_get_random(unsigned char *buffer, unsigned int length);\n     \n#endif /* CRYPTO_KERNEL */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/crypto_math.h",
    "content": "/*\n * math.h\n *\n * crypto math operations and data types\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#ifndef MATH_H\n#define MATH_H\n\n#include \"datatypes.h\"\n\nunsigned char\nv32_weight(v32_t a);\n\nunsigned char\nv32_distance(v32_t x, v32_t y);\n\nunsigned int\nv32_dot_product(v32_t a, v32_t b);\n\nchar *\nv16_bit_string(v16_t x);\n\nchar *\nv32_bit_string(v32_t x);\n\nchar *\nv64_bit_string(const v64_t *x);\n\nchar *\noctet_hex_string(uint8_t x);\n\nchar *\nv16_hex_string(v16_t x);\n\nchar *\nv32_hex_string(v32_t x);\n\nchar *\nv64_hex_string(const v64_t *x);\n\nint\nhex_char_to_nibble(uint8_t c);\n\nint\nis_hex_string(char *s);\n\nv16_t\nhex_string_to_v16(char *s);\n\nv32_t\nhex_string_to_v32(char *s);\n\nv64_t\nhex_string_to_v64(char *s);\n\n/* the matrix A[] is stored in column format, i.e., A[i] is\n   the ith column of the matrix */\n\nuint8_t \nA_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b);\n\nvoid\nv16_copy_octet_string(v16_t *x, const uint8_t s[2]);\n\nvoid\nv32_copy_octet_string(v32_t *x, const uint8_t s[4]);\n\nvoid\nv64_copy_octet_string(v64_t *x, const uint8_t s[8]);\n\nvoid\nv128_add(v128_t *z, v128_t *x, v128_t *y);\n\nint\noctet_string_is_eq(uint8_t *a, uint8_t *b, int len);\n\nvoid\noctet_string_set_to_zero(uint8_t *s, int len);\n\n\n\n/* \n * the matrix A[] is stored in column format, i.e., A[i] is the ith\n * column of the matrix\n*/\nuint8_t \nA_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b);\n\n\n#if 0\n#if WORDS_BIGENDIAN\n\n#define _v128_add(z, x, y) {                    \\\n  uint64_t tmp;\t\t\t\t\t\\\n    \t\t\t\t\t\t\\\n  tmp = x->v32[3] + y->v32[3];                  \\\n  z->v32[3] = (uint32_t) tmp;\t\t\t\\\n  \t\t\t\t\t\t\\\n  tmp =  x->v32[2] + y->v32[2] + (tmp >> 32);\t\\\n  z->v32[2] = (uint32_t) tmp;                   \\\n\t\t\t\t\t\t\\\n  tmp =  x->v32[1] + y->v32[1] + (tmp >> 32);\t\\\n  z->v32[1] = (uint32_t) tmp;\t\t\t\\\n                                                \\\n  tmp =  x->v32[0] + y->v32[0] + (tmp >> 32);\t\\\n  z->v32[0] = (uint32_t) tmp;\t\t\t\\\n}\n\n#else /* assume little endian architecture */\n\n#define _v128_add(z, x, y) {                    \\\n  uint64_t tmp;\t\t\t\t\t\\\n\t\t\t\t\t\t\\\n  tmp = htonl(x->v32[3]) + htonl(y->v32[3]);\t\\\n  z->v32[3] = ntohl((uint32_t) tmp);\t\t\\\n  \t\t\t\t\t\t\\\n  tmp =  htonl(x->v32[2]) + htonl(y->v32[2])\t\\\n       + htonl(tmp >> 32);\t\t\t\\\n  z->v32[2] = ntohl((uint32_t) tmp);\t\t\\\n                                                \\\n  tmp =  htonl(x->v32[1]) + htonl(y->v32[1])\t\\\n       + htonl(tmp >> 32);\t\t\t\\\n  z->v32[1] = ntohl((uint32_t) tmp);\t\t\\\n  \t\t\t\t\t\t\\\n  tmp =  htonl(x->v32[0]) + htonl(y->v32[0])\t\\\n       + htonl(tmp >> 32);\t\t\t\\\n  z->v32[0] = ntohl((uint32_t) tmp);\t\t\\\n}\n\t\t\t\t\t\t\n#endif /* WORDS_BIGENDIAN */                      \n#endif\n\n#ifdef DATATYPES_USE_MACROS  /* little functions are really macros */\n\n#define v128_set_to_zero(z)       _v128_set_to_zero(z)\n#define v128_copy(z, x)           _v128_copy(z, x)\n#define v128_xor(z, x, y)         _v128_xor(z, x, y)\n#define v128_and(z, x, y)         _v128_and(z, x, y)\n#define v128_or(z, x, y)          _v128_or(z, x, y)\n#define v128_complement(x)        _v128_complement(x) \n#define v128_is_eq(x, y)          _v128_is_eq(x, y)\n#define v128_xor_eq(x, y)         _v128_xor_eq(x, y)\n#define v128_get_bit(x, i)        _v128_get_bit(x, i)\n#define v128_set_bit(x, i)        _v128_set_bit(x, i)\n#define v128_clear_bit(x, i)      _v128_clear_bit(x, i)\n#define v128_set_bit_to(x, i, y)  _v128_set_bit_to(x, i, y)\n\n#else\n\nvoid\nv128_set_to_zero(v128_t *x);\n\nint\nv128_is_eq(const v128_t *x, const v128_t *y);\n\nvoid\nv128_copy(v128_t *x, const v128_t *y);\n\nvoid\nv128_xor(v128_t *z, v128_t *x, v128_t *y);\n\nvoid\nv128_and(v128_t *z, v128_t *x, v128_t *y);\n\nvoid\nv128_or(v128_t *z, v128_t *x, v128_t *y); \n\nvoid\nv128_complement(v128_t *x);\n\nint\nv128_get_bit(const v128_t *x, int i);\n\nvoid\nv128_set_bit(v128_t *x, int i) ;     \n\nvoid\nv128_clear_bit(v128_t *x, int i);    \n\nvoid\nv128_set_bit_to(v128_t *x, int i, int y);\n\n#endif /* DATATYPES_USE_MACROS */\n\n/*\n * octet_string_is_eq(a,b, len) returns 1 if the length len strings a\n * and b are not equal, returns 0 otherwise\n */\n\nint\noctet_string_is_eq(uint8_t *a, uint8_t *b, int len);\n\nvoid\noctet_string_set_to_zero(uint8_t *s, int len);\n\n\n/*\n * functions manipulating bit_vector_t \n *\n * A bitvector_t consists of an array of words and an integer\n * representing the number of significant bits stored in the array.\n * The bits are packed as follows: the least significant bit is that\n * of word[0], while the most significant bit is the nth most\n * significant bit of word[m], where length = bits_per_word * m + n.\n * \n */\n\n#define bits_per_word  32\n#define bytes_per_word 4\n\ntypedef struct {\n  uint32_t length;   \n  uint32_t *word;\n} bitvector_t;\n\nint\nbitvector_alloc(bitvector_t *v, unsigned long length);\n\nvoid\nbitvector_set_bit(bitvector_t *v, int bit_index);\n\nint\nbitvector_get_bit(const bitvector_t *v, int bit_index);\n\nint\nbitvector_print_hex(const bitvector_t *v, FILE *stream);\n\nint\nbitvector_set_from_hex(bitvector_t *v, char *string);\n\n#endif /* MATH_H */\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/crypto_types.h",
    "content": "/*\n * crypto_types.h\n *\n * constants for cipher types and auth func types\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright(c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#ifndef CRYPTO_TYPES_H\n#define CRYPTO_TYPES_H\n\n/**\n * @defgroup Algos Cryptographic Algorithms\n *\n *\n * This library provides several different cryptographic algorithms,\n * each of which can be selected by using the cipher_type_id_t and\n * auth_type_id_t.  These algorithms are documented below.\n *\n * Authentication functions that use the Universal Security Transform\n * (UST) must be used in conjunction with a cipher other than the null\n * cipher.  These functions require a per-message pseudorandom input\n * that is generated by the cipher.\n * \n * The identifiers STRONGHOLD_AUTH and STRONGHOLD_CIPHER identify the\n * strongest available authentication function and cipher,\n * respectively.  They are resolved at compile time to the strongest\n * available algorithm.  The stronghold algorithms can serve as did\n * the keep of a medieval fortification; they provide the strongest\n * defense (or the last refuge).\n * \n * @{\n */\n\n/**\n * @defgroup Ciphers Cipher Types\n *\n * @brief    Each cipher type is identified by an unsigned integer.  The\n *           cipher types available in this edition of libSRTP are given \n *           by the #defines below.\n *\n * A cipher_type_id_t is an identifier for a cipher_type; only values\n * given by the #defines above (or those present in the file\n * crypto_types.h) should be used.\n *\n * The identifier STRONGHOLD_CIPHER indicates the strongest available\n * cipher, allowing an application to choose the strongest available\n * algorithm without any advance knowledge about the avaliable\n * algorithms.\n *\n * @{\n */\n\n/**\n * @brief The null cipher performs no encryption.\n *\n * The NULL_CIPHER leaves its inputs unaltered, during both the \n * encryption and decryption operations.  This cipher can be chosen\n * to indicate that no encryption is to be performed.\n */\n#define NULL_CIPHER        0            \n\n/** \n * @brief AES-128 Integer Counter Mode (AES ICM)             \n *\n * AES-128 ICM is the variant of counter mode that is used by Secure RTP.  \n * This cipher uses a 16-octet key and a 30-octet offset (or salt) value.\n */\n#define AES_128_ICM        1            \n\n/**\n * @brief SEAL 3.0 \n * \n * SEAL is the Software-Optimized Encryption Algorithm of Coppersmith\n * and Rogaway.  Nota bene: this cipher is IBM proprietary.\n */\n#define SEAL               2            \n\n/** \n * @brief AES-128 Integer Counter Mode (AES ICM)             \n *\n * AES-128 ICM is the variant of counter mode that is used by Secure RTP.  \n * This cipher uses a 16-octet key and a 30-octet offset (or salt) value.\n */\n#define AES_128_CBC        3            \n\n/**\n * @brief Strongest available cipher.\n *\n * This identifier resolves to the strongest cipher type available.\n */\n#define STRONGHOLD_CIPHER  AES_128_ICM  \n\n/**\n * @}\n */\n\n\n\n/**\n * @defgroup Authentication Authentication Function Types\n * \n * @brief Each authentication function type is identified by an\n * unsigned integer.  The authentication function types available in\n * this edition of libSRTP are given by the #defines below.\n *\n * An auth_type_id_t is an identifier for an authentication function type;\n * only values given by the #defines above (or those present in the \n * file crypto_types.h) should be used.  \n *\n * The identifier STRONGHOLD_AUTH indicates the strongest available\n * authentication function, allowing an application to choose the\n * strongest available algorithm without any advance knowledge about\n * the avaliable algorithms.  The stronghold algorithms can serve as\n * did the keep of a medieval fortification; they provide the\n * strongest defense (or the last refuge).\n *\n * @{\n */\n\n/**\n * @brief The null authentication function performs no authentication.\n *\n * The NULL_AUTH function does nothing, and can be selected to indicate\n * that authentication should not be performed.\n */ \n#define NULL_AUTH          0           \n\n/**\n * @brief UST with TMMH Version 2\n *\n * UST_TMMHv2 implements the Truncated Multi-Modular Hash using\n * UST.  This function must be used in conjunction with a cipher other\n * than the null cipher.\n * with a cipher.\n */\n#define UST_TMMHv2         1           \n\n/**\n * @brief (UST) AES-128 XORMAC  \n *\n * UST_AES_128_XMAC implements AES-128 XORMAC, using UST. Nota bene:\n * the XORMAC algorithm is IBM proprietary.\n */\n#define UST_AES_128_XMAC   2           \n\n/**\n * @brief HMAC-SHA1\n *\n * HMAC_SHA1 implements the Hash-based MAC using the NIST Secure\n * Hash Algorithm version 1 (SHA1).\n */\n#define HMAC_SHA1          3          \n\n/**\n * @brief Strongest available authentication function.\n *\n * This identifier resolves to the strongest available authentication\n * function.\n */\n#define STRONGHOLD_AUTH    HMAC_SHA1   \n\n/**\n * @}\n */\n/**\n * @}\n */\n\n#endif  /* CRYPTO_TYPES_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/cryptoalg.h",
    "content": "/*\n * cryptoalg.h\n *\n * API for authenticated encryption crypto algorithms\n * \n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#ifndef CRYPTOALG_H\n#define CRYPTOALG_H\n\n#include \"err.h\"\n\n/**\n * @defgroup Crypto Cryptography\n *\n * Zed uses a simple interface to a cryptographic transform.\n *\n * @{\n */\n\n/**\n * @brief applies a crypto algorithm\n *\n * The function pointer cryptoalg_func_t points to a function that\n * implements a crypto transform, and provides a uniform API for\n * accessing crypto mechanisms.\n * \n * @param key       location of secret key                  \n *\n * @param clear     data to be authenticated but not encrypted           \n *\n * @param clear_len length of data to be authenticated but not encrypted\n *\n * @param iv        location to write the Initialization Vector (IV)\n *\n * @param protect   location of the data to be encrypted and\n * authenticated (before the function call), and the ciphertext\n * and authentication tag (after the call)\n *\n * @param protected_len location of the length of the data to be\n * encrypted and authenticated (before the function call), and the\n * length of the ciphertext (after the call)\n *\n */\n                    \ntypedef err_status_t (*cryptoalg_func_t) \n     (void *key,            \n      const void *clear,          \n      unsigned clear_len,   \n      void *iv,             \n      void *protect,         \n      unsigned *protected_len);\n\ntypedef \nerr_status_t (*cryptoalg_inv_t)\n     (void *key,            /* location of secret key                  */\n      const void *clear,     /* data to be authenticated only           */\n      unsigned clear_len,   /* length of data to be authenticated only */\n      void *iv,             /* location of iv                          */\n      void *opaque,         /* data to be decrypted and authenticated  */\n      unsigned *opaque_len  /* location of the length of data to be\n\t\t\t     * decrypted and authd (before and after) \n\t\t\t     */\n      );\n\ntypedef struct cryptoalg_ctx_t {\n  cryptoalg_func_t enc;\n  cryptoalg_inv_t  dec;\n  unsigned key_len;\n  unsigned iv_len;\n  unsigned auth_tag_len;\n  unsigned max_expansion; \n} cryptoalg_ctx_t;\n\ntypedef cryptoalg_ctx_t *cryptoalg_t;\n\n#define cryptoalg_get_key_len(cryptoalg) ((cryptoalg)->key_len)\n\n#define cryptoalg_get_iv_len(cryptoalg) ((cryptoalg)->iv_len)\n\n#define cryptoalg_get_auth_tag_len(cryptoalg) ((cryptoalg)->auth_tag_len)\n\nint\ncryptoalg_get_id(cryptoalg_t c);\n\ncryptoalg_t \ncryptoalg_find_by_id(int id);\n\n\n/**\n * @}\n */\n\n#endif /* CRYPTOALG_H */\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/datatypes.h",
    "content": "/*\n * datatypes.h\n * \n * data types for bit vectors and finite fields\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#ifndef _DATATYPES_H\n#define _DATATYPES_H\n\n#include \"integers.h\"           /* definitions of uint32_t, et cetera   */\n#include \"alloc.h\"\n\n#include <stdarg.h>\n\n#ifndef SRTP_KERNEL\n# include <stdio.h>\n# include <string.h>\n# include <time.h>\n# ifdef HAVE_NETINET_IN_H\n#  include <netinet/in.h>\n# elif defined HAVE_WINSOCK2_H\n#  include <winsock2.h>\n# endif\n#endif\n\n\n/* if DATATYPES_USE_MACROS is defined, then little functions are macros */\n#define DATATYPES_USE_MACROS  \n\ntypedef union {\n  uint8_t  v8[2];\n  uint16_t value;\n} v16_t;\n\ntypedef union {\n  uint8_t  v8[4];\n  uint16_t v16[2];\n  uint32_t value;\n} v32_t;\n\ntypedef union {\n  uint8_t  v8[8];\n  uint16_t v16[4];\n  uint32_t v32[2];\n  uint64_t value;\n} v64_t;\n\ntypedef union {\n  uint8_t  v8[16];\n  uint16_t v16[8];\n  uint32_t v32[4];\n  uint64_t v64[2];\n} v128_t;\n\n\n\n/* some useful and simple math functions */\n\n#define pow_2(X) ( (unsigned int)1 << (X) )   /* 2^X     */\n\n#define pow_minus_one(X) ( (X) ? -1 : 1 )      /* (-1)^X  */\n\n\n/*\n * octet_get_weight(x) returns the hamming weight (number of bits equal to\n * one) in the octet x\n */\n\nint\noctet_get_weight(uint8_t octet);\n\nchar *\noctet_bit_string(uint8_t x);\n\n#define MAX_PRINT_STRING_LEN 1024\n\nchar *\noctet_string_hex_string(const void *str, int length);\n\nchar *\nv128_bit_string(v128_t *x);\n\nchar *\nv128_hex_string(v128_t *x);\n\nuint8_t\nnibble_to_hex_char(uint8_t nibble);\n\nchar *\nchar_to_hex_string(char *x, int num_char);\n\nuint8_t\nhex_string_to_octet(char *s);\n\n/*\n * hex_string_to_octet_string(raw, hex, len) converts the hexadecimal\n * string at *hex (of length len octets) to the equivalent raw data\n * and writes it to *raw.\n *\n * if a character in the hex string that is not a hexadeciaml digit\n * (0123456789abcdefABCDEF) is encountered, the function stops writing\n * data to *raw\n *\n * the number of hex digits copied (which is two times the number of\n * octets in *raw) is returned\n */\n\nint\nhex_string_to_octet_string(char *raw, char *hex, int len);\n\nv128_t\nhex_string_to_v128(char *s);\n\nvoid\nv128_copy_octet_string(v128_t *x, const uint8_t s[16]);\n\nvoid\nv128_left_shift(v128_t *x, int index);\n\nvoid\nv128_right_shift(v128_t *x, int index);\n\n/*\n * the following macros define the data manipulation functions\n * \n * If DATATYPES_USE_MACROS is defined, then these macros are used\n * directly (and function call overhead is avoided).  Otherwise,\n * the macros are used through the functions defined in datatypes.c\n * (and the compiler provides better warnings).\n */\n\n#define _v128_set_to_zero(x)     \\\n(                               \\\n  (x)->v32[0] = 0,              \\\n  (x)->v32[1] = 0,              \\\n  (x)->v32[2] = 0,              \\\n  (x)->v32[3] = 0               \\\n)\n\n#define _v128_copy(x, y)          \\\n(                                \\\n  (x)->v32[0] = (y)->v32[0],     \\\n  (x)->v32[1] = (y)->v32[1],     \\\n  (x)->v32[2] = (y)->v32[2],     \\\n  (x)->v32[3] = (y)->v32[3]      \\\n)\n\n#define _v128_xor(z, x, y)                       \\\n(                                               \\\n   (z)->v32[0] = (x)->v32[0] ^ (y)->v32[0],     \\\n   (z)->v32[1] = (x)->v32[1] ^ (y)->v32[1],     \\\n   (z)->v32[2] = (x)->v32[2] ^ (y)->v32[2],     \\\n   (z)->v32[3] = (x)->v32[3] ^ (y)->v32[3]      \\\n)\n\n#define _v128_and(z, x, y)                       \\\n(                                               \\\n   (z)->v32[0] = (x)->v32[0] & (y)->v32[0],     \\\n   (z)->v32[1] = (x)->v32[1] & (y)->v32[1],     \\\n   (z)->v32[2] = (x)->v32[2] & (y)->v32[2],     \\\n   (z)->v32[3] = (x)->v32[3] & (y)->v32[3]      \\\n)\n\n#define _v128_or(z, x, y)                        \\\n(                                               \\\n   (z)->v32[0] = (x)->v32[0] | (y)->v32[0],     \\\n   (z)->v32[1] = (x)->v32[1] | (y)->v32[1],     \\\n   (z)->v32[2] = (x)->v32[2] | (y)->v32[2],     \\\n   (z)->v32[3] = (x)->v32[3] | (y)->v32[3]      \\\n)\n\n#define _v128_complement(x)        \\\n(                                  \\\n   (x)->v32[0] = ~(x)->v32[0],     \\\n   (x)->v32[1] = ~(x)->v32[1],     \\\n   (x)->v32[2] = ~(x)->v32[2],     \\\n   (x)->v32[3] = ~(x)->v32[3]      \\\n)\n\n/* ok for NO_64BIT_MATH if it can compare uint64_t's (even as structures) */\n#define _v128_is_eq(x, y)                                        \\\n  (((x)->v64[0] == (y)->v64[0]) && ((x)->v64[1] == (y)->v64[1]))\n\n\n#ifdef NO_64BIT_MATH\n#define _v128_xor_eq(z, x)         \\\n(                                  \\\n   (z)->v32[0] ^= (x)->v32[0],     \\\n   (z)->v32[1] ^= (x)->v32[1],     \\\n   (z)->v32[2] ^= (x)->v32[2],     \\\n   (z)->v32[3] ^= (x)->v32[3]      \\\n)\n#else\n#define _v128_xor_eq(z, x)         \\\n(                                  \\\n   (z)->v64[0] ^= (x)->v64[0],     \\\n   (z)->v64[1] ^= (x)->v64[1]      \\\n)\n#endif\n\n/* NOTE!  This assumes an odd ordering! */\n/* This will not be compatible directly with math on some processors */\n/* bit 0 is first 32-bit word, low order bit. in little-endian, that's\n   the first byte of the first 32-bit word.  In big-endian, that's\n   the 3rd byte of the first 32-bit word */\n/* The get/set bit code is used by the replay code ONLY, and it doesn't\n   really care which bit is which.  AES does care which bit is which, but\n   doesn't use the 128-bit get/set or 128-bit shifts  */\n\n#define _v128_get_bit(x, bit)                     \\\n(                                                 \\\n  ((((x)->v32[(bit) >> 5]) >> ((bit) & 31)) & 1)  \\\n)\n\n#define _v128_set_bit(x, bit)                                    \\\n(                                                                \\\n  (((x)->v32[(bit) >> 5]) |= ((uint32_t)1 << ((bit) & 31))) \\\n)\n\n#define _v128_clear_bit(x, bit)                                   \\\n(                                                                 \\\n  (((x)->v32[(bit) >> 5]) &= ~((uint32_t)1 << ((bit) & 31))) \\\n)\n\n#define _v128_set_bit_to(x, bit, value)   \\\n(                                         \\\n   (value) ? _v128_set_bit(x, bit) :      \\\n             _v128_clear_bit(x, bit)      \\\n)\n\n\n#if 0\n/* nothing uses this */\n#ifdef WORDS_BIGENDIAN\n\n#define _v128_add(z, x, y) {                    \\\n  uint64_t tmp;\t\t\t\t\t\\\n    \t\t\t\t\t\t\\\n  tmp = x->v32[3] + y->v32[3];                  \\\n  z->v32[3] = (uint32_t) tmp;\t\t\t\\\n  \t\t\t\t\t\t\\\n  tmp =  x->v32[2] + y->v32[2] + (tmp >> 32);\t\\\n  z->v32[2] = (uint32_t) tmp;                   \\\n\t\t\t\t\t\t\\\n  tmp =  x->v32[1] + y->v32[1] + (tmp >> 32);\t\\\n  z->v32[1] = (uint32_t) tmp;\t\t\t\\\n                                                \\\n  tmp =  x->v32[0] + y->v32[0] + (tmp >> 32);\t\\\n  z->v32[0] = (uint32_t) tmp;\t\t\t\\\n}\n\n#else /* assume little endian architecture */\n\n#define _v128_add(z, x, y) {                    \\\n  uint64_t tmp;\t\t\t\t\t\\\n\t\t\t\t\t\t\\\n  tmp = htonl(x->v32[3]) + htonl(y->v32[3]);\t\\\n  z->v32[3] = ntohl((uint32_t) tmp);\t\t\\\n  \t\t\t\t\t\t\\\n  tmp =  htonl(x->v32[2]) + htonl(y->v32[2])\t\\\n       + htonl(tmp >> 32);\t\t\t\\\n  z->v32[2] = ntohl((uint32_t) tmp);\t\t\\\n                                                \\\n  tmp =  htonl(x->v32[1]) + htonl(y->v32[1])\t\\\n       + htonl(tmp >> 32);\t\t\t\\\n  z->v32[1] = ntohl((uint32_t) tmp);\t\t\\\n  \t\t\t\t\t\t\\\n  tmp =  htonl(x->v32[0]) + htonl(y->v32[0])\t\\\n       + htonl(tmp >> 32);\t\t\t\\\n  z->v32[0] = ntohl((uint32_t) tmp);\t\t\\\n}\n#endif /* WORDS_BIGENDIAN */                      \n#endif /* 0 */\n\n\n#ifdef DATATYPES_USE_MACROS  /* little functions are really macros */\n   \n#define v128_set_to_zero(z)       _v128_set_to_zero(z)\n#define v128_copy(z, x)           _v128_copy(z, x)\n#define v128_xor(z, x, y)         _v128_xor(z, x, y)\n#define v128_and(z, x, y)         _v128_and(z, x, y)\n#define v128_or(z, x, y)          _v128_or(z, x, y)\n#define v128_complement(x)        _v128_complement(x) \n#define v128_is_eq(x, y)          _v128_is_eq(x, y)\n#define v128_xor_eq(x, y)         _v128_xor_eq(x, y)\n#define v128_get_bit(x, i)        _v128_get_bit(x, i)\n#define v128_set_bit(x, i)        _v128_set_bit(x, i)\n#define v128_clear_bit(x, i)      _v128_clear_bit(x, i)\n#define v128_set_bit_to(x, i, y)  _v128_set_bit_to(x, i, y)\n\n#else\n\nvoid\nv128_set_to_zero(v128_t *x);\n\nint\nv128_is_eq(const v128_t *x, const v128_t *y);\n\nvoid\nv128_copy(v128_t *x, const v128_t *y);\n\nvoid\nv128_xor(v128_t *z, v128_t *x, v128_t *y);\n\nvoid\nv128_and(v128_t *z, v128_t *x, v128_t *y);\n\nvoid\nv128_or(v128_t *z, v128_t *x, v128_t *y); \n\nvoid\nv128_complement(v128_t *x);\n\nint\nv128_get_bit(const v128_t *x, int i);\n\nvoid\nv128_set_bit(v128_t *x, int i) ;     \n\nvoid\nv128_clear_bit(v128_t *x, int i);    \n\nvoid\nv128_set_bit_to(v128_t *x, int i, int y);\n\n#endif /* DATATYPES_USE_MACROS */\n\n/*\n * octet_string_is_eq(a,b, len) returns 1 if the length len strings a\n * and b are not equal, returns 0 otherwise\n */\n\nint\noctet_string_is_eq(uint8_t *a, uint8_t *b, int len);\n\nvoid\noctet_string_set_to_zero(uint8_t *s, int len);\n\n\n#ifndef SRTP_KERNEL_LINUX\n\n/* \n * Convert big endian integers to CPU byte order.\n */\n#ifdef WORDS_BIGENDIAN\n/* Nothing to do. */\n# define be32_to_cpu(x)\t(x)\n# define be64_to_cpu(x)\t(x)\n#elif defined(HAVE_BYTESWAP_H)\n/* We have (hopefully) optimized versions in byteswap.h */\n# include <byteswap.h>\n# define be32_to_cpu(x)\tbswap_32((x))\n# define be64_to_cpu(x)\tbswap_64((x))\n#else\n\n#if defined(__GNUC__) && defined(HAVE_X86)\n/* Fall back. */\nstatic inline uint32_t be32_to_cpu(uint32_t v) {\n   /* optimized for x86. */\n   asm(\"bswap %0\" : \"=r\" (v) : \"0\" (v));\n   return v;\n}\n# else /* HAVE_X86 */\n#  ifdef HAVE_NETINET_IN_H\n#   include <netinet/in.h>\n#  elif defined HAVE_WINSOCK2_H\n#   include <winsock2.h>\n#  endif\n#  define be32_to_cpu(x)\tntohl((x))\n# endif /* HAVE_X86 */\n\nstatic inline uint64_t be64_to_cpu(uint64_t v) {\n# ifdef NO_64BIT_MATH\n   /* use the make64 functions to do 64-bit math */\n   v = make64(htonl(low32(v)),htonl(high32(v)));\n# else\n   /* use the native 64-bit math */\n   v= (uint64_t)((be32_to_cpu((uint32_t)(v >> 32))) | (((uint64_t)be32_to_cpu((uint32_t)v)) << 32));\n# endif\n   return v;\n}\n\n#endif /* ! SRTP_KERNEL_LINUX */\n\n#endif /* WORDS_BIGENDIAN */\n\n#endif /* _DATATYPES_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/err.h",
    "content": "/*\n * err.h\n * \n * error status codes\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#ifndef ERR_H\n#define ERR_H\n\n#include \"datatypes.h\"\n\n/**\n * @defgroup Error Error Codes\n * \n * Error status codes are represented by the enumeration err_status_t.\n * \n * @{\n */\n\n\n/*\n * @brief err_status_t defines error codes.\n *\n * The enumeration err_status_t defines error codes.  Note that the\n * value of err_status_ok is equal to zero, which can simplify error\n * checking somewhat.\n *\n */\ntypedef enum {\n  err_status_ok           = 0,  /**< nothing to report                       */\n  err_status_fail         = 1,  /**< unspecified failure                     */\n  err_status_bad_param    = 2,  /**< unsupported parameter                   */\n  err_status_alloc_fail   = 3,  /**< couldn't allocate memory                */\n  err_status_dealloc_fail = 4,  /**< couldn't deallocate properly            */\n  err_status_init_fail    = 5,  /**< couldn't initialize                     */\n  err_status_terminus     = 6,  /**< can't process as much data as requested */\n  err_status_auth_fail    = 7,  /**< authentication failure                  */\n  err_status_cipher_fail  = 8,  /**< cipher failure                          */\n  err_status_replay_fail  = 9,  /**< replay check failed (bad index)         */\n  err_status_replay_old   = 10, /**< replay check failed (index too old)     */\n  err_status_algo_fail    = 11, /**< algorithm failed test routine           */\n  err_status_no_such_op   = 12, /**< unsupported operation                   */\n  err_status_no_ctx       = 13, /**< no appropriate context found            */\n  err_status_cant_check   = 14, /**< unable to perform desired validation    */\n  err_status_key_expired  = 15, /**< can't use key any more                  */\n  err_status_socket_err   = 16, /**< error in use of socket                  */\n  err_status_signal_err   = 17, /**< error in use POSIX signals              */\n  err_status_nonce_bad    = 18, /**< nonce check failed                      */\n  err_status_read_fail    = 19, /**< couldn't read data                      */\n  err_status_write_fail   = 20, /**< couldn't write data                     */\n  err_status_parse_err    = 21, /**< error pasring data                      */\n  err_status_encode_err   = 22, /**< error encoding data                     */\n  err_status_semaphore_err = 23,/**< error while using semaphores            */\n  err_status_pfkey_err    = 24  /**< error while using pfkey                 */\n} err_status_t;\n\n/**\n * @}\n */\n\ntypedef enum {\n  err_level_emergency = 0,\n  err_level_alert,\n  err_level_critical,\n  err_level_error,\n  err_level_warning,\n  err_level_notice,\n  err_level_info,\n  err_level_debug,\n  err_level_none\n} err_reporting_level_t;\n\n/*\n * err_reporting_init prepares the error system.  If\n * ERR_REPORTING_SYSLOG is defined, it will open syslog.\n *\n * The ident argument is a string that will be prepended to\n * all syslog messages.  It is conventionally argv[0].\n */\n\nerr_status_t\nerr_reporting_init(char *ident);\n\n#ifdef SRTP_KERNEL_LINUX\nextern err_reporting_level_t err_level;\n#else\n\n/*\n * keydaemon_report_error reports a 'printf' formatted error\n * string, followed by a an arg list.  The priority argument\n * is equivalent to that defined for syslog.\n *\n * Errors will be reported to ERR_REPORTING_FILE, if defined, and to\n * syslog, if ERR_REPORTING_SYSLOG is defined.\n *\n */\n\nvoid\nerr_report(int priority, char *format, ...);\n#endif /* ! SRTP_KERNEL_LINUX */\n\n\n/*\n * debug_module_t defines a debug module\n */\n\ntypedef struct {\n  int   on;          /* 1 if debugging is on, 0 if it is off */\n  char *name;        /* printable name for debug module      */\n} debug_module_t;\n\n#ifdef ENABLE_DEBUGGING\n\n#define debug_on(mod)  (mod).on = 1\n\n#define debug_off(mod) (mod).on = 0\n\n/* use err_report() to report debug message */\n#define debug_print(mod, format, arg)                  \\\n  if (mod.on) err_report(err_level_debug, (\"%s: \" format \"\\n\"), mod.name, arg)\n#define debug_print2(mod, format, arg1,arg2)                  \\\n  if (mod.on) err_report(err_level_debug, (\"%s: \" format \"\\n\"), mod.name, arg1,arg2)\n\n#else\n\n/* define macros to do nothing */\n#define debug_print(mod, format, arg)\n\n#define debug_on(mod)\n\n#define debug_off(mod)\n\n#endif\n\n#endif /* ERR_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/gf2_8.h",
    "content": "/*\n * gf2_8.h\n *\n * GF(256) implementation\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#ifndef GF2_8_H\n#define GF2_8_H\n\n#include \"datatypes.h\"  /* for uint8_t definition */\n\ntypedef uint8_t gf2_8;\n\n#define gf2_8_field_polynomial 0x1B\n\n/*\n * gf2_8_shift(x) returns \n */\n\n/*\n * gf2_8_shift(z) returns the result of the GF(2^8) 'multiply by x' \n * operation, using the field representation from AES; that is, the \n * next gf2_8 value in the cyclic representation of that field.  The \n * value z should be an uint8_t.\n */\n\n#define gf2_8_shift(z) (((z) & 128) ? \\\n       (((z) << 1) ^ gf2_8_field_polynomial) : ((z) << 1))\n\ngf2_8\ngf2_8_compute_inverse(gf2_8 x);\n\nvoid\ntest_gf2_8(void);\n\ngf2_8\ngf2_8_multiply(gf2_8 x, gf2_8 y);\n\n#endif /* GF2_8_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/hmac.h",
    "content": "/*\n * hmac.h\n *\n * interface to hmac auth_type_t\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n *\n */\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#ifndef HMAC_H\n#define HMAC_H\n\n#include \"auth.h\"\n#include \"sha1.h\"\n\ntypedef struct {\n  uint8_t    opad[64];\n  sha1_ctx_t ctx;\n  sha1_ctx_t init_ctx;\n} hmac_ctx_t;\n\nerr_status_t\nhmac_alloc(auth_t **a, int key_len, int out_len);\n\nerr_status_t\nhmac_dealloc(auth_t *a);\n\nerr_status_t\nhmac_init(hmac_ctx_t *state, const uint8_t *key, int key_len);\n\nerr_status_t\nhmac_start(hmac_ctx_t *state);\n\nerr_status_t\nhmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets);\n\nerr_status_t\nhmac_compute(hmac_ctx_t *state, const void *message,\n\t     int msg_octets, int tag_len, uint8_t *result);\n\n\n#endif /* HMAC_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/integers.h",
    "content": "/*\n * integers.h\n *\n * defines integer types (or refers to their definitions)\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#ifndef INTEGERS_H\n#define INTEGERS_H\n\n#include \"srtp_config.h\"\t/* configuration file, using autoconf  */\n\n#ifdef SRTP_KERNEL\n\n#include \"kernel_compat.h\"\n\n#else /* SRTP_KERNEL */\n\n/* use standard integer definitions, if they're available  */\n#ifdef HAVE_STDLIB_H\n# include <stdlib.h>\n#endif\n#ifdef HAVE_STDINT_H\n# include <stdint.h>\n#endif\n#ifdef HAVE_INTTYPES_H\n# include <inttypes.h>\n#endif\n#ifdef HAVE_SYS_TYPES_H\n# include <sys/types.h>\n#endif\n#ifdef HAVE_SYS_INT_TYPES_H\n# include <sys/int_types.h>    /* this exists on Sun OS */\n#endif\n#ifdef HAVE_MACHINE_TYPES_H\n# include <machine/types.h>\n#endif\n\n/* Can we do 64 bit integers? */\n#ifndef HAVE_UINT64_T\n# if SIZEOF_UNSIGNED_LONG == 8\ntypedef unsigned long\t\tuint64_t;\n# elif SIZEOF_UNSIGNED_LONG_LONG == 8\ntypedef unsigned long long\tuint64_t;\n# else\n#  define NO_64BIT_MATH 1\n# endif\n#endif\n\n/* Reasonable defaults for 32 bit machines - you may need to\n * edit these definitions for your own machine. */\n#ifndef HAVE_UINT8_T\ntypedef unsigned char\t\tuint8_t;\n#endif\n#ifndef HAVE_UINT16_T\ntypedef unsigned short int\tuint16_t;\n#endif\n#ifndef HAVE_UINT32_T\ntypedef unsigned int\t\tuint32_t;\n#endif\n\n\n#ifdef NO_64BIT_MATH\ntypedef double uint64_t;\n/* assert that sizeof(double) == 8 */\nextern uint64_t make64(uint32_t high, uint32_t low);\nextern uint32_t high32(uint64_t value);\nextern uint32_t low32(uint64_t value);\n#endif\n\n#endif /* SRTP_KERNEL */\n\n/* These macros are to load and store 32-bit values from un-aligned\n   addresses.  This is required for processors that do not allow unaligned\n   loads. */\n#ifdef ALIGNMENT_32BIT_REQUIRED\n/* Note that if it's in a variable, you can memcpy it */\n#ifdef WORDS_BIGENDIAN\n#define PUT_32(addr,value) \\\n    { \\\n        ((unsigned char *) (addr))[0] = (value >> 24); \\\n        ((unsigned char *) (addr))[1] = (value >> 16) & 0xff; \\\n        ((unsigned char *) (addr))[2] = (value >> 8) & 0xff; \\\n        ((unsigned char *) (addr))[3] = (value)      & 0xff; \\\n    }\n#define GET_32(addr) ((((unsigned char *) (addr))[0] << 24) |  \\\n                      (((unsigned char *) (addr))[1] << 16) |  \\\n                      (((unsigned char *) (addr))[2] << 8)  |  \\\n                      (((unsigned char *) (addr))[3])) \n#else\n#define PUT_32(addr,value) \\\n    { \\\n        ((unsigned char *) (addr))[3] = (value >> 24); \\\n        ((unsigned char *) (addr))[2] = (value >> 16) & 0xff; \\\n        ((unsigned char *) (addr))[1] = (value >> 8) & 0xff; \\\n        ((unsigned char *) (addr))[0] = (value)      & 0xff; \\\n    }\n#define GET_32(addr) ((((unsigned char *) (addr))[3] << 24) |  \\\n                      (((unsigned char *) (addr))[2] << 16) |  \\\n                      (((unsigned char *) (addr))[1] << 8)  |  \\\n                      (((unsigned char *) (addr))[0])) \n#endif // WORDS_BIGENDIAN\n#else\n#define PUT_32(addr,value) *(((uint32_t *) (addr)) = (value)\n#define GET_32(addr) (*(((uint32_t *) (addr)))\n#endif\n\n#endif /* INTEGERS_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/kernel_compat.h",
    "content": "/*\n * kernel_compat.h\n * \n * Compatibility stuff for building in kernel context where standard\n * C headers and library are not available.\n *\n * Marcus Sundberg\n * Ingate Systems AB\n */\n/*\n *\t\n * Copyright(c) 2005 Ingate Systems AB\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the author(s) nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#ifndef KERNEL_COMPAT_H\n#define KERNEL_COMPAT_H\n\n#ifdef SRTP_KERNEL_LINUX\n\n#include <linux/kernel.h>\n#include <linux/slab.h>\n#include <linux/sched.h>\n#include <linux/random.h>\n#include <linux/byteorder/generic.h>\n\n\n#define err_report(priority, ...) \\\n  do {\\\n    if (priority <= err_level) {\\\n       printk(__VA_ARGS__);\\\n    }\\\n  }while(0)\n\n#define clock()\t(jiffies)\n#define time(x)\t(jiffies)\n\n/* rand() implementation. */\n#define RAND_MAX\t32767\n\nstatic inline int rand(void)\n{\n\tuint32_t temp;\n\tget_random_bytes(&temp, sizeof(temp));\n\treturn temp % (RAND_MAX+1);\n}\n\n/* stdio/stdlib implementation. */\n#define printf(...)\tprintk(__VA_ARGS__)\n#define exit(n)\tpanic(\"%s:%d: exit(%d)\\n\", __FILE__, __LINE__, (n))\n\n#endif /* SRTP_KERNEL_LINUX */\n\n#endif /* KERNEL_COMPAT_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/key.h",
    "content": "/*\n * key.h\n *\n * key usage limits enforcement\n * \n * David A. Mcgrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#ifndef KEY_H\n#define KEY_H\n\n#include \"rdbx.h\"   /* for xtd_seq_num_t */\n#include \"err.h\"\n\ntypedef struct key_limit_ctx_t *key_limit_t;\n\ntypedef enum {\n   key_event_normal,\n   key_event_soft_limit,\n   key_event_hard_limit\n} key_event_t;\n\nerr_status_t\nkey_limit_set(key_limit_t key, const xtd_seq_num_t s);\n\nerr_status_t\nkey_limit_clone(key_limit_t original, key_limit_t *new_key);\n\nerr_status_t\nkey_limit_check(const key_limit_t key);\n\nkey_event_t\nkey_limit_update(key_limit_t key);\n\ntypedef enum { \n   key_state_normal,\n   key_state_past_soft_limit,\n   key_state_expired\n} key_state_t;\n\ntypedef struct key_limit_ctx_t {\n  xtd_seq_num_t num_left;\n  key_state_t   state;\n} key_limit_ctx_t;\n\n#endif /* KEY_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/null_auth.h",
    "content": "/*\n * null-auth.h\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n *\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#ifndef NULL_AUTH_H\n#define NULL_AUTH_H\n\n#include \"auth.h\"\n\ntypedef struct {\n\tchar foo;\n} null_auth_ctx_t;\n\nerr_status_t\nnull_auth_alloc(auth_t **a, int key_len, int out_len);\n\nerr_status_t\nnull_auth_dealloc(auth_t *a);\n\nerr_status_t\nnull_auth_init(null_auth_ctx_t *state, const uint8_t *key, int key_len);\n\nerr_status_t\nnull_auth_compute (null_auth_ctx_t *state, uint8_t *message,\n\t\t   int msg_octets, int tag_len, uint8_t *result);\n\n\n#endif /* NULL_AUTH_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/null_cipher.h",
    "content": "/*\n * null-cipher.h\n *\n * header file for the null cipher\n *\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#ifndef NULL_CIPHER_H\n#define NULL_CIPHER_H\n\n#include \"datatypes.h\"\n#include \"cipher.h\"\n\ntypedef struct {\n  char foo ;/* empty, for now */\n} null_cipher_ctx_t;\n\n\n/*\n * none of these functions do anything (though future versions may keep\n * track of bytes encrypted, number of instances, and/or other info).\n */\n\nerr_status_t\nnull_cipher_init(null_cipher_ctx_t *c, const uint8_t *key);\n\nerr_status_t\nnull_cipher_set_segment(null_cipher_ctx_t *c,\n\t\t\tunsigned long index);\n\nerr_status_t\nnull_cipher_encrypt(null_cipher_ctx_t *c,\n\t\t    unsigned char *buf, unsigned int *bytes_to_encr);\n\n\nerr_status_t\nnull_cipher_encrypt_aligned(null_cipher_ctx_t *c,\n\t\t\t    unsigned char *buf, int bytes_to_encr);\n\n#endif /* NULL_CIPHER_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/prng.h",
    "content": "/*\n * prng.h\n *\n * pseudorandom source\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n#ifndef PRNG_H\n#define PRNG_H\n\n#include \"rand_source.h\"  /* for rand_source_func_t definition       */\n#include \"aes.h\"          /* for aes                                 */\n#include \"aes_icm.h\"      /* for aes ctr                             */\n\n#define MAX_PRNG_OUT_LEN 0xffffffffU\n\n/*\n * x917_prng is an ANSI X9.17-like AES-based PRNG\n */\n\ntypedef struct {\n  v128_t   state;          /* state data                              */\n  aes_expanded_key_t key;  /* secret key                              */\n  uint32_t octet_count;    /* number of octets output since last init */\n  rand_source_func_t rand; /* random source for re-initialization     */\n} x917_prng_t;\n\nerr_status_t\nx917_prng_init(rand_source_func_t random_source);\n\nerr_status_t\nx917_prng_get_octet_string(uint8_t *dest, uint32_t len);\n\n\n/*\n * ctr_prng is an AES-CTR based PRNG\n */\n\ntypedef struct {\n  uint32_t octet_count;    /* number of octets output since last init */\n  aes_icm_ctx_t   state;   /* state data                              */\n  rand_source_func_t rand; /* random source for re-initialization     */\n} ctr_prng_t;\n\nerr_status_t\nctr_prng_init(rand_source_func_t random_source);\n\nerr_status_t\nctr_prng_get_octet_string(void *dest, uint32_t len);\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/rand_source.h",
    "content": "/*\n * rand_source.h\n *\n * implements a random source based on /dev/random\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright(c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#ifndef RAND_SOURCE\n#define RAND_SOURCE\n\n#include \"err.h\"\n#include \"datatypes.h\"\n\nerr_status_t\nrand_source_init(void);\n\n/*\n * rand_source_get_octet_string() writes a random octet string.\n *\n * The function call rand_source_get_octet_string(dest, len) writes\n * len octets of random data to the location to which dest points,\n * and returns an error code.  This error code should be checked,\n * and if a failure is reported, the data in the buffer MUST NOT\n * be used.\n * \n * warning: If the return code is not checked, then non-random\n *          data may inadvertently be used.\n *\n * returns:\n *     - err_status_ok    if no problems occured.\n *     - [other]          a problem occured, and no assumptions should\n *                        be made about the contents of the destination\n *                        buffer.\n */\n\nerr_status_t\nrand_source_get_octet_string(void *dest, uint32_t length);\n\nerr_status_t\nrand_source_deinit(void);\n\n/* \n * function prototype for a random source function\n *\n * A rand_source_func_t writes num_octets at the location indicated by\n * dest and returns err_status_ok.  Any other return value indicates\n * failure.\n */\n\ntypedef err_status_t (*rand_source_func_t)\n     (void *dest, uint32_t num_octets);\n\n#endif /* RAND_SOURCE */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/rdb.h",
    "content": "/*\n * replay-database.h\n *\n * interface for a replay database for packet security\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n\n#ifndef REPLAY_DB_H\n#define REPLAY_DB_H\n\n#include \"integers.h\"         /* for uint32_t     */\n#include \"datatypes.h\"        /* for v128_t       */\n#include \"err.h\"              /* for err_status_t */\n\n/*\n * if the ith least significant bit is one, then the packet index\n * window_end-i is in the database\n */\n\ntypedef struct {\n  uint32_t window_start;   /* packet index of the first bit in bitmask */\n  v128_t bitmask;  \n} rdb_t;\n\n#define rdb_bits_in_bitmask (8*sizeof(v128_t))   \n\n/*\n * rdb init\n *\n * initalizes rdb\n *\n * returns err_status_ok on success, err_status_t_fail otherwise\n */\n\nerr_status_t\nrdb_init(rdb_t *rdb);\n\n\n/*\n * rdb_check\n *\n * checks to see if index appears in rdb\n *\n * returns err_status_fail if the index already appears in rdb,\n * returns err_status_ok otherwise\n */\n\nerr_status_t\nrdb_check(const rdb_t *rdb, uint32_t index);  \n\n/*\n * rdb_add_index\n *\n * adds index to rdb_t (and does *not* check if index appears in db)\n *\n * returns err_status_ok on success, err_status_fail otherwise\n *\n */\n\nerr_status_t\nrdb_add_index(rdb_t *rdb, uint32_t index);\n\n/*\n * the functions rdb_increment() and rdb_get_value() are for use by \n * senders, not receivers - DO NOT use these functions on the same\n * rdb_t upon which rdb_add_index is used!\n */\n\n\n/*\n * rdb_increment(db) increments the sequence number in db, if it is \n * not too high\n *\n * return values:\n * \n *    err_status_ok            no problem\n *    err_status_key_expired   sequence number too high\n *\n */\nerr_status_t\nrdb_increment(rdb_t *rdb);\n\n/*\n * rdb_get_value(db) returns the current sequence number of db\n */\n\nuint32_t\nrdb_get_value(const rdb_t *rdb);\n\n\n#endif /* REPLAY_DB_H */ \n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/rdbx.h",
    "content": "/*\n * rdbx.h\n *\n * replay database with extended packet indices, using a rollover counter\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n *\n */\n\n#ifndef RDBX_H\n#define RDBX_H\n\n#include \"datatypes.h\"\n#include \"err.h\"\n\n/* #define ROC_TEST */  \n\n#ifndef ROC_TEST\n\ntypedef uint16_t sequence_number_t;   /* 16 bit sequence number  */\ntypedef uint32_t rollover_counter_t;   /* 32 bit rollover counter */\n\n#else  /* use small seq_num and roc datatypes for testing purposes */\n\ntypedef unsigned char sequence_number_t;         /* 8 bit sequence number   */\ntypedef uint16_t rollover_counter_t;   /* 16 bit rollover counter */\n\n#endif\n\n#define seq_num_median (1 << (8*sizeof(sequence_number_t) - 1))\n#define seq_num_max    (1 << (8*sizeof(sequence_number_t)))\n\n/*\n * An xtd_seq_num_t is a 64-bit unsigned integer used as an 'extended'\n * sequence number.  \n */\n\ntypedef uint64_t xtd_seq_num_t;\n\n\n/*\n * An rdbx_t is a replay database with extended range; it uses an\n * xtd_seq_num_t and a bitmask of recently received indices.\n */\n\ntypedef struct {\n  xtd_seq_num_t index;\n  v128_t bitmask;\n} rdbx_t;\n\n\n/*\n * rdbx_init(rdbx_ptr)\n *\n * initializes the rdbx pointed to by its argument, setting the\n * rollover counter and sequence number to zero\n */\n\nerr_status_t\nrdbx_init(rdbx_t *rdbx);\n\n\n/*\n * rdbx_estimate_index(rdbx, guess, s)\n * \n * given an rdbx and a sequence number s (from a newly arrived packet),\n * sets the contents of *guess to contain the best guess of the packet\n * index to which s corresponds, and returns the difference between\n * *guess and the locally stored synch info\n */\n\nint\nrdbx_estimate_index(const rdbx_t *rdbx,\n\t\t    xtd_seq_num_t *guess,\n\t\t    sequence_number_t s);\n\n/*\n * rdbx_check(rdbx, delta);\n *\n * rdbx_check(&r, delta) checks to see if the xtd_seq_num_t\n * which is at rdbx->window_start + delta is in the rdb\n *\n */\n\nerr_status_t\nrdbx_check(const rdbx_t *rdbx, int difference);\n\n/*\n * replay_add_index(rdbx, delta)\n * \n * adds the xtd_seq_num_t at rdbx->window_start + delta to replay_db\n * (and does *not* check if that xtd_seq_num_t appears in db)\n *\n * this function should be called *only* after replay_check has\n * indicated that the index does not appear in the rdbx, and a mutex\n * should protect the rdbx between these calls if necessary.\n */\n\nerr_status_t\nrdbx_add_index(rdbx_t *rdbx, int delta);\n\n/*\n * xtd_seq_num_t functions - these are *internal* functions of rdbx, and\n * shouldn't be used to manipulate rdbx internal values.  use the rdbx\n * api instead!\n */\n\n\n/* index_init(&pi) initializes a packet index pi (sets it to zero) */\n\nvoid\nindex_init(xtd_seq_num_t *pi);\n\n/* index_advance(&pi, s) advances a xtd_seq_num_t forward by s */\n\nvoid\nindex_advance(xtd_seq_num_t *pi, sequence_number_t s);\n\n\n/*\n * index_guess(local, guess, s)\n * \n * given a xtd_seq_num_t local (which represents the highest\n * known-to-be-good index) and a sequence number s (from a newly\n * arrived packet), sets the contents of *guess to contain the best\n * guess of the packet index to which s corresponds, and returns the\n * difference between *guess and *local\n */\n\nint\nindex_guess(const xtd_seq_num_t *local,\n\t\t   xtd_seq_num_t *guess,\n\t\t   sequence_number_t s);\n\n\n#endif /* RDBX_H */\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/sha1.h",
    "content": "/*\n * sha1.h\n *\n * interface to the Secure Hash Algorithm v.1 (SHA-1), specified in\n * FIPS 180-1\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#ifndef SHA1_H\n#define SHA1_H\n\n#include \"err.h\"\n#include \"datatypes.h\"\n\ntypedef struct {\n  uint32_t H[5];             /* state vector                    */\n  uint32_t M[16];            /* message buffer                  */\n  int octets_in_buffer;      /* octets of message in buffer     */\n  uint32_t num_bits_in_msg;  /* total number of bits in message */\n} sha1_ctx_t;\n\n/*\n * sha1(&ctx, msg, len, output) hashes the len octets starting at msg\n * into the SHA1 context, then writes the result to the 20 octets at\n * output\n * \n */\n\nvoid\nsha1(const uint8_t *message,  int octets_in_msg, uint32_t output[5]);\n\n/*\n * sha1_init(&ctx) initializes the SHA1 context ctx\n * \n * sha1_update(&ctx, msg, len) hashes the len octets starting at msg\n * into the SHA1 context\n * \n * sha1_final(&ctx, output) performs the final processing of the SHA1\n * context and writes the result to the 20 octets at output\n *\n */\n\nvoid\nsha1_init(sha1_ctx_t *ctx);\n\nvoid\nsha1_update(sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg);\n\nvoid\nsha1_final(sha1_ctx_t *ctx, uint32_t output[5]);\n\n/*\n * The sha1_core function is INTERNAL to SHA-1, but it is declared\n * here because it is also used by the cipher SEAL 3.0 in its key\n * setup algorithm.  \n */\n\n/*\n *  sha1_core(M, H) computes the core sha1 compression function, where M is\n *  the next part of the message and H is the intermediate state {H0,\n *  H1, ...}\n *\n *  this function does not do any of the padding required in the\n *  complete sha1 function\n */\n\nvoid\nsha1_core(const uint32_t M[16], uint32_t hash_value[5]);\n     \n#endif /* SHA1_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/stat.h",
    "content": "/*\n * stats.h\n * \n * interface to statistical test functions\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright(c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#ifndef STAT_H\n#define STAT_H\n\n#include \"datatypes.h\"       /* for uint8_t                       */\n#include \"err.h\"             /* for err_status_t                  */\n#include \"rand_source.h\"     /* for rand_source_func_t definition */\n\nerr_status_t\nstat_test_monobit(uint8_t *data);\n\nerr_status_t\nstat_test_poker(uint8_t *data);\n\nerr_status_t\nstat_test_runs(uint8_t *data);\n\nerr_status_t\nstat_test_rand_source(rand_source_func_t rs);\n\nerr_status_t\nstat_test_rand_source_with_repetition(rand_source_func_t source, unsigned num_trials);\n\n#endif /* STAT_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/include/xfm.h",
    "content": "/*\n * xfm.h\n *\n * interface for abstract crypto transform\n * \n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n#ifndef XFM_H\n#define XFM_H\n\n#include \"crypto_kernel.h\"\n#include \"err.h\"\n\n/**\n * @defgroup Crypto Cryptography\n *\n * A simple interface to an abstract cryptographic transform that\n * provides both confidentiality and message authentication.\n *\n * @{\n */\n\n/**\n * @brief applies a crypto transform\n *\n * The function pointer xfm_func_t points to a function that\n * implements a crypto transform, and provides a uniform API for\n * accessing crypto mechanisms.\n * \n * @param key       location of secret key                  \n *\n * @param clear     data to be authenticated only           \n *\n * @param clear_len length of data to be authenticated only \n *\n * @param iv        location to write the Initialization Vector (IV)\n *\n * @param protect   location of the data to be encrypted and\n * authenticated (before the function call), and the ciphertext\n * and authentication tag (after the call)\n *\n * @param protected_len location of the length of the data to be\n * encrypted and authenticated (before the function call), and the\n * length of the ciphertext (after the call)\n *\n * @param auth_tag   location to write auth tag              \n */\n\ntypedef err_status_t (*xfm_func_t) \n     (void *key,            \n      void *clear,          \n      unsigned clear_len,   \n      void *iv,             \n      void *protect,         \n      unsigned *protected_len, \n      void *auth_tag        \n      );\n\ntypedef \nerr_status_t (*xfm_inv_t)\n     (void *key,            /* location of secret key                  */\n      void *clear,          /* data to be authenticated only           */\n      unsigned clear_len,   /* length of data to be authenticated only */\n      void *iv,             /* location of iv                          */\n      void *opaque,         /* data to be decrypted and authenticated  */\n      unsigned *opaque_len, /* location of the length of data to be\n\t\t\t     * decrypted and authd (before and after) \n\t\t\t     */\n      void *auth_tag        /* location of auth tag                    */\n      );\n\ntypedef struct xfm_ctx_t {\n  xfm_func_t func;\n  xfm_inv_t  inv;\n  unsigned key_len;\n  unsigned iv_len;\n  unsigned auth_tag_len;\n} xfm_ctx_t;\n\ntypedef xfm_ctx_t *xfm_t;\n\n#define xfm_get_key_len(xfm) ((xfm)->key_len)\n\n#define xfm_get_iv_len(xfm) ((xfm)->iv_len)\n\n#define xfm_get_auth_tag_len(xfm) ((xfm)->auth_tag_len)\n\n\n/* cryptoalgo - 5/28 */\n  \ntypedef err_status_t (*cryptoalg_func_t) \n     (void *key,            \n      void *clear,          \n      unsigned clear_len,   \n      void *iv,             \n      void *opaque,         \n      unsigned *opaque_len\n      );\n\ntypedef \nerr_status_t (*cryptoalg_inv_t)\n     (void *key,            /* location of secret key                  */\n      void *clear,          /* data to be authenticated only           */\n      unsigned clear_len,   /* length of data to be authenticated only */\n      void *iv,             /* location of iv                          */\n      void *opaque,         /* data to be decrypted and authenticated  */\n      unsigned *opaque_len  /* location of the length of data to be\n\t\t\t     * decrypted and authd (before and after) \n\t\t\t     */\n      );\n\ntypedef struct cryptoalg_ctx_t {\n  cryptoalg_func_t enc;\n  cryptoalg_inv_t  dec;\n  unsigned key_len;\n  unsigned iv_len;\n  unsigned auth_tag_len;\n  unsigned max_expansion; \n} cryptoalg_ctx_t;\n\ntypedef cryptoalg_ctx_t *cryptoalg_t;\n\n#define cryptoalg_get_key_len(cryptoalg) ((cryptoalg)->key_len)\n\n#define cryptoalg_get_iv_len(cryptoalg) ((cryptoalg)->iv_len)\n\n#define cryptoalg_get_auth_tag_len(cryptoalg) ((cryptoalg)->auth_tag_len)\n\n\n\n/**\n * @}\n */\n\n#endif /* XFM_H */\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/kernel/alloc.c",
    "content": "/*\n * alloc.c\n *\n * memory allocation and deallocation \n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#include \"alloc.h\"\n#include \"crypto_kernel.h\"\n\n/* the debug module for memory allocation */\n\ndebug_module_t mod_alloc = {\n  0,                  /* debugging is off by default */\n  \"alloc\"             /* printable name for module   */\n};\n\n/*\n * Nota bene: the debugging statements for crypto_alloc() and\n * crypto_free() have identical prefixes, which include the addresses\n * of the memory locations on which they are operating.  This fact can\n * be used to locate memory leaks, by turning on memory debugging,\n * grepping for 'alloc', then matching alloc and free calls by\n * address.\n */\n\n#ifdef SRTP_KERNEL_LINUX\n\n#include <linux/interrupt.h>\n\nvoid *\ncrypto_alloc(size_t size) {\n  void *ptr;\n\n  ptr = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);\n\n  if (ptr) {\n    debug_print(mod_alloc, \"(location: %p) allocated\", ptr);\n  } else\n    debug_print(mod_alloc, \"allocation failed (asked for %d bytes)\\n\", size);\n\n  return ptr;\n}\n\nvoid \ncrypto_free(void *ptr) {\n\n  debug_print(mod_alloc, \"(location: %p) freed\", ptr);\n\n  kfree(ptr);\n}\n\n\n#elif defined(HAVE_STDLIB_H)\n\nvoid *\ncrypto_alloc(size_t size) {\n  void *ptr;\n\n  ptr = malloc(size);\n    \n  if (ptr) {\n    debug_print(mod_alloc, \"(location: %p) allocated\", ptr);\n  } else\n    debug_print(mod_alloc, \"allocation failed (asked for %d bytes)\\n\", size);\n    \n  return ptr;\n}\n\nvoid \ncrypto_free(void *ptr) {\n\n  debug_print(mod_alloc, \"(location: %p) freed\", ptr);\n\n  free(ptr);\n}\n\n#else  /* we need to define our own memory allocation routines */\n\n#error no memory allocation defined yet \n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/kernel/crypto_kernel.c",
    "content": "/*\n * crypto_kernel.c\n *\n * header for the cryptographic kernel\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright(c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#include \"alloc.h\"\n\n#include \"crypto_kernel.h\"\n\n/* the debug module for the crypto_kernel */\n\ndebug_module_t mod_crypto_kernel = {\n  0,                  /* debugging is off by default */\n  \"crypto kernel\"     /* printable name for module   */\n};\n\n/*\n * other debug modules that can be included in the kernel\n */\n\nextern debug_module_t mod_auth;\nextern debug_module_t mod_cipher;\nextern debug_module_t mod_stat;\nextern debug_module_t mod_alloc;\n\n/* \n * cipher types that can be included in the kernel\n */ \n\nextern cipher_type_t null_cipher;\nextern cipher_type_t aes_icm;\nextern cipher_type_t aes_cbc;\n\n\n/*\n * auth func types that can be included in the kernel\n */\n\nextern auth_type_t null_auth;\nextern auth_type_t hmac;\n\n/* crypto_kernel is a global variable, the only one of its datatype */\n\ncrypto_kernel_t\ncrypto_kernel = {\n  crypto_kernel_state_insecure,    /* start off in insecure state */\n  NULL,                            /* no cipher types yet         */\n  NULL,                            /* no auth types yet           */\n  NULL                             /* no debug modules yet        */\n};\n\n#define MAX_RNG_TRIALS 25\n\nerr_status_t\ncrypto_kernel_init() {\n  err_status_t status;  \n\n  /* check the security state */\n  if (crypto_kernel.state == crypto_kernel_state_secure) {\n    \n    /*\n     * we're already in the secure state, but we've been asked to\n     * re-initialize, so we just re-run the self-tests and then return\n     */\n    return crypto_kernel_status(); \n  }\n\n  /* initialize error reporting system */\n  status = err_reporting_init(\"crypto\");\n  if (status)\n    return status;\n\n  /* load debug modules */\n  status = crypto_kernel_load_debug_module(&mod_crypto_kernel);\n  if (status)\n    return status;\n  status = crypto_kernel_load_debug_module(&mod_auth);\n  if (status)\n    return status;\n  status = crypto_kernel_load_debug_module(&mod_cipher);\n  if (status)\n    return status;\n  status = crypto_kernel_load_debug_module(&mod_stat);\n  if (status)\n    return status;\n  status = crypto_kernel_load_debug_module(&mod_alloc);\n  if (status)\n    return status;\n  \n  /* initialize random number generator */\n  status = rand_source_init();\n  if (status)\n    return status;\n\n  /* run FIPS-140 statistical tests on rand_source */  \n  status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, MAX_RNG_TRIALS);\n  if (status)\n    return status;\n\n  /* initialize pseudorandom number generator */\n  status = ctr_prng_init(rand_source_get_octet_string);\n  if (status)\n    return status;\n\n  /* run FIPS-140 statistical tests on ctr_prng */  \n  status = stat_test_rand_source_with_repetition(ctr_prng_get_octet_string, MAX_RNG_TRIALS);\n  if (status)\n    return status;\n \n  /* load cipher types */\n  status = crypto_kernel_load_cipher_type(&null_cipher, NULL_CIPHER);\n  if (status) \n    return status;\n  status = crypto_kernel_load_cipher_type(&aes_icm, AES_128_ICM);\n  if (status) \n    return status;\n  status = crypto_kernel_load_cipher_type(&aes_cbc, AES_128_CBC);\n  if (status) \n    return status;\n\n  /* load auth func types */\n  status = crypto_kernel_load_auth_type(&null_auth, NULL_AUTH);\n  if (status)\n    return status;\n  status = crypto_kernel_load_auth_type(&hmac, HMAC_SHA1);\n  if (status)\n    return status;\n\n  /* change state to secure */\n  crypto_kernel.state = crypto_kernel_state_secure;\n\n  return err_status_ok;\n}\n\nerr_status_t\ncrypto_kernel_status() {\n  err_status_t status;\n  kernel_cipher_type_t  *ctype = crypto_kernel.cipher_type_list;\n  kernel_auth_type_t    *atype = crypto_kernel.auth_type_list;\n  kernel_debug_module_t *dm    = crypto_kernel.debug_module_list;\n\n  /* run FIPS-140 statistical tests on rand_source */  \n  printf(\"testing rand_source...\");\n  status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, MAX_RNG_TRIALS);\n  if (status) {\n    printf(\"failed\\n\");\n    crypto_kernel.state = crypto_kernel_state_insecure;\n    return status;\n  }  \n  printf(\"passed\\n\");\n\n  /* for each cipher type, describe and test */\n  while(ctype != NULL) {\n    printf(\"cipher: %s\\n\", ctype->cipher_type->description);\n    printf(\"  instance count: %d\\n\", ctype->cipher_type->ref_count);\n    printf(\"  self-test: \");\n    status = cipher_type_self_test(ctype->cipher_type);\n    if (status) {\n      printf(\"failed with error code %d\\n\", status);\n      exit(status);\n    }\n    printf(\"passed\\n\");\n    ctype = ctype->next;\n  }\n  \n  /* for each auth type, describe and test */\n  while(atype != NULL) {\n    printf(\"auth func: %s\\n\", atype->auth_type->description);\n    printf(\"  instance count: %d\\n\", atype->auth_type->ref_count);\n    printf(\"  self-test: \");\n    status = auth_type_self_test(atype->auth_type);\n    if (status) {\n      printf(\"failed with error code %d\\n\", status);\n      exit(status);\n    }\n    printf(\"passed\\n\");\n    atype = atype->next;\n  }\n\n  /* describe each debug module */\n  printf(\"debug modules loaded:\\n\");\n  while (dm != NULL) {\n    printf(\"  %s \", dm->mod->name);  \n    if (dm->mod->on)\n      printf(\"(on)\\n\");\n    else\n      printf(\"(off)\\n\");\n    dm = dm->next;\n  }\n\n  return err_status_ok;\n}\n\nerr_status_t\ncrypto_kernel_list_debug_modules() {\n  kernel_debug_module_t *dm = crypto_kernel.debug_module_list;\n\n  /* describe each debug module */\n  printf(\"debug modules loaded:\\n\");\n  while (dm != NULL) {\n    printf(\"  %s \", dm->mod->name);  \n    if (dm->mod->on)\n      printf(\"(on)\\n\");\n    else\n      printf(\"(off)\\n\");\n    dm = dm->next;\n  }\n\n  return err_status_ok;\n}\n\nerr_status_t\ncrypto_kernel_shutdown() {\n  err_status_t status;\n\n  /*\n   * free dynamic memory used in crypto_kernel at present\n   */\n\n  /* walk down cipher type list, freeing memory */\n  while (crypto_kernel.cipher_type_list != NULL) {\n    kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;\n    crypto_kernel.cipher_type_list = ctype->next;\n    debug_print(mod_crypto_kernel, \n\t\t\"freeing memory for cipher %s\", \n\t\tctype->cipher_type->description);\n    crypto_free(ctype);\n  }\n\n  /* walk down authetication module list, freeing memory */\n  while (crypto_kernel.auth_type_list != NULL) {\n     kernel_auth_type_t *atype = crypto_kernel.auth_type_list;\n     crypto_kernel.auth_type_list = atype->next;\n     debug_print(mod_crypto_kernel, \n\t\t\"freeing memory for authentication %s\",\n\t\tatype->auth_type->description);\n     crypto_free(atype);\n  }\n\n  /* walk down debug module list, freeing memory */\n  while (crypto_kernel.debug_module_list != NULL) {\n    kernel_debug_module_t *kdm = crypto_kernel.debug_module_list;\n    crypto_kernel.debug_module_list = kdm->next;\n    debug_print(mod_crypto_kernel, \n\t\t\"freeing memory for debug module %s\", \n\t\tkdm->mod->name);\n    crypto_free(kdm);\n  }\n\n  /* de-initialize random number generator */  status = rand_source_deinit();\n  if (status)\n    return status;\n\n  /* return to insecure state */\n  crypto_kernel.state = crypto_kernel_state_insecure;\n  \n  return err_status_ok;\n}\n\nerr_status_t\ncrypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {\n  kernel_cipher_type_t *ctype, *new_ctype;\n  err_status_t status;\n\n  /* defensive coding */\n  if (new_ct == NULL)\n    return err_status_bad_param;\n\n  /* check cipher type by running self-test */\n  status = cipher_type_self_test(new_ct);\n  if (status) {\n    return status;\n  }\n\n  /* walk down list, checking if this type is in the list already  */\n  ctype = crypto_kernel.cipher_type_list;\n  while (ctype != NULL) {\n    if ((new_ct == ctype->cipher_type) || (id == ctype->id))\n      return err_status_bad_param;    \n    ctype = ctype->next;\n  }\n\n  /* put new_ct at the head of the list */\n  /* allocate memory */\n  new_ctype = (kernel_cipher_type_t *) crypto_alloc(sizeof(kernel_cipher_type_t));\n  if (new_ctype == NULL)\n    return err_status_alloc_fail;\n    \n  /* set fields */\n  new_ctype->cipher_type = new_ct;\n  new_ctype->id = id;\n  new_ctype->next = crypto_kernel.cipher_type_list;\n\n  /* set head of list to new cipher type */\n  crypto_kernel.cipher_type_list = new_ctype;    \n\n  /* load debug module, if there is one present */\n  if (new_ct->debug != NULL)\n    crypto_kernel_load_debug_module(new_ct->debug);\n  /* we could check for errors here */\n\n  return err_status_ok;\n}\n\nerr_status_t\ncrypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {\n  kernel_auth_type_t *atype, *new_atype;\n  err_status_t status;\n\n  /* defensive coding */\n  if (new_at == NULL)\n    return err_status_bad_param;\n\n  /* check auth type by running self-test */\n  status = auth_type_self_test(new_at);\n  if (status) {\n    return status;\n  }\n\n  /* walk down list, checking if this type is in the list already  */\n  atype = crypto_kernel.auth_type_list;\n  while (atype != NULL) {\n    if ((new_at == atype->auth_type) || (id == atype->id))\n      return err_status_bad_param;    \n    atype = atype->next;\n  }\n\n  /* put new_at at the head of the list */\n  /* allocate memory */\n  new_atype = (kernel_auth_type_t *)crypto_alloc(sizeof(kernel_auth_type_t));\n  if (new_atype == NULL)\n    return err_status_alloc_fail;\n    \n  /* set fields */\n  new_atype->auth_type = new_at;\n  new_atype->id = id;\n  new_atype->next = crypto_kernel.auth_type_list;\n\n  /* set head of list to new auth type */\n  crypto_kernel.auth_type_list = new_atype;    \n\n  /* load debug module, if there is one present */\n  if (new_at->debug != NULL)\n    crypto_kernel_load_debug_module(new_at->debug);\n  /* we could check for errors here */\n\n  return err_status_ok;\n\n}\n\n\ncipher_type_t *\ncrypto_kernel_get_cipher_type(cipher_type_id_t id) {\n  kernel_cipher_type_t *ctype;\n  \n  /* walk down list, looking for id  */\n  ctype = crypto_kernel.cipher_type_list;\n  while (ctype != NULL) {\n    if (id == ctype->id)\n      return ctype->cipher_type; \n    ctype = ctype->next;\n  } \n\n  /* haven't found the right one, indicate failure by returning NULL */\n  return NULL;\n}\n\n\nerr_status_t\ncrypto_kernel_alloc_cipher(cipher_type_id_t id, \n\t\t\t      cipher_pointer_t *cp, \n\t\t\t      int key_len) {\n  cipher_type_t *ct;\n\n  /* \n   * if the crypto_kernel is not yet initialized, we refuse to allocate\n   * any ciphers - this is a bit extra-paranoid\n   */\n  if (crypto_kernel.state != crypto_kernel_state_secure)\n    return err_status_init_fail;\n\n  ct = crypto_kernel_get_cipher_type(id);\n  if (!ct)\n    return err_status_fail;\n  \n  return ((ct)->alloc(cp, key_len));\n}\n\n\n\nauth_type_t *\ncrypto_kernel_get_auth_type(auth_type_id_t id) {\n  kernel_auth_type_t *atype;\n  \n  /* walk down list, looking for id  */\n  atype = crypto_kernel.auth_type_list;\n  while (atype != NULL) {\n    if (id == atype->id)\n      return atype->auth_type; \n    atype = atype->next;\n  } \n\n  /* haven't found the right one, indicate failure by returning NULL */\n  return NULL;\n}\n\nerr_status_t\ncrypto_kernel_alloc_auth(auth_type_id_t id, \n\t\t\t auth_pointer_t *ap, \n\t\t\t int key_len,\n\t\t\t int tag_len) {\n  auth_type_t *at;\n\n  /* \n   * if the crypto_kernel is not yet initialized, we refuse to allocate\n   * any auth functions - this is a bit extra-paranoid\n   */\n  if (crypto_kernel.state != crypto_kernel_state_secure)\n    return err_status_init_fail;\n\n  at = crypto_kernel_get_auth_type(id);\n  if (!at)\n    return err_status_fail;\n  \n  return ((at)->alloc(ap, key_len, tag_len));\n}\n\nerr_status_t\ncrypto_kernel_load_debug_module(debug_module_t *new_dm) {\n  kernel_debug_module_t *kdm, *new;\n\n  /* defensive coding */\n  if (new_dm == NULL)\n    return err_status_bad_param;\n\n  /* walk down list, checking if this type is in the list already  */\n  kdm = crypto_kernel.debug_module_list;\n  while (kdm != NULL) {\n    if (strncmp(new_dm->name, kdm->mod->name, 64) == 0)\n      return err_status_bad_param;    \n    kdm = kdm->next;\n  }\n\n  /* put new_dm at the head of the list */\n  /* allocate memory */\n  new = (kernel_debug_module_t *)crypto_alloc(sizeof(kernel_debug_module_t));\n  if (new == NULL)\n    return err_status_alloc_fail;\n    \n  /* set fields */\n  new->mod = new_dm;\n  new->next = crypto_kernel.debug_module_list;\n\n  /* set head of list to new cipher type */\n  crypto_kernel.debug_module_list = new;    \n\n  return err_status_ok;\n}\n\nerr_status_t\ncrypto_kernel_set_debug_module(char *name, int on) {\n  kernel_debug_module_t *kdm;\n  \n  /* walk down list, checking if this type is in the list already  */\n  kdm = crypto_kernel.debug_module_list;\n  while (kdm != NULL) {\n    if (strncmp(name, kdm->mod->name, 64) == 0) {\n      kdm->mod->on = on;\n      return err_status_ok;\n    }\n    kdm = kdm->next;\n  }\n\n  return err_status_fail;\n}\n\nerr_status_t\ncrypto_get_random(unsigned char *buffer, unsigned int length) {\n  if (crypto_kernel.state == crypto_kernel_state_secure)\n    return ctr_prng_get_octet_string(buffer, length);\n  else\n    return err_status_fail;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/kernel/err.c",
    "content": "/*\n * err.c\n *\n * error status reporting functions\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright(c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#include \"err.h\"\n\n#ifdef ERR_REPORTING_SYSLOG\n# ifdef HAVE_SYSLOG_H\n#  include <syslog.h>\n# endif\n#endif\n\n\n/*  err_level reflects the level of errors that are reported  */\n\nerr_reporting_level_t err_level = err_level_none;\n\n#ifdef SRTP_KERNEL_LINUX\nerr_status_t\nerr_reporting_init(char *ident) {\n\n  return err_status_ok;\n}\n\n#else /* SRTP_KERNEL_LINUX */\t\n\n/* err_file is the FILE to which errors are reported */\n\nstatic FILE *err_file = NULL;\n\nerr_status_t\nerr_reporting_init(char *ident) {\n#ifdef ERR_REPORTING_SYSLOG\n  openlog(ident, LOG_PID, LOG_AUTHPRIV);\n#endif\n  \n  /*\n   * Believe it or not, openlog doesn't return an error on failure.\n   * But then, neither does the syslog() call...\n   */\n\n#ifdef ERR_REPORTING_STDOUT\n  err_file = stdout;\n#elif defined(USE_ERR_REPORTING_FILE)\n  /* open file for error reporting */\n  err_file = fopen(ERR_REPORTING_FILE, \"w\");\n  if (err_file == NULL)\n    return err_status_init_fail;\n#endif\n\n  return err_status_ok;\n}\n\nvoid\nerr_report(int priority, char *format, ...) {\n  va_list args;\n\n  if (priority <= err_level) {\n\n    va_start(args, format);\n    if (err_file != NULL) {\n      vfprintf(err_file, format, args);\n\t  /*      fprintf(err_file, \"\\n\"); */\n    }\n#ifdef ERR_REPORTING_SYSLOG\n    if (1) { /* FIXME: Make this a runtime option. */\n      int syslogpri;\n\n      switch (priority) {\n      case err_level_emergency:\n\tsyslogpri = LOG_EMERG;\n\tbreak;\n      case err_level_alert:\n\tsyslogpri = LOG_ALERT;\n\tbreak;\n      case err_level_critical:\n\tsyslogpri = LOG_CRIT;\n\tbreak;\n      case err_level_error:\n\tsyslogpri = LOG_ERR;\n\tbreak;\n      case err_level_warning:\n\tsyslogpri = LOG_WARNING;\n\tbreak;\n      case err_level_notice:\n\tsyslogpri = LOG_NOTICE;\n\tbreak;\n      case err_level_info:\n\tsyslogpri = LOG_INFO;\n\tbreak;\n      case err_level_debug:\n      case err_level_none:\n      default:\n\tsyslogpri = LOG_DEBUG;\n\tbreak;\n      }\n\n      vsyslog(syslogpri, format, args);\n#endif\n    va_end(args);\n  }\n}\n#endif /* SRTP_KERNEL_LINUX */\t\n\nvoid\nerr_reporting_set_level(err_reporting_level_t lvl) { \n  err_level = lvl;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/kernel/key.c",
    "content": "/*\n * key.c\n *\n * key usage limits enforcement\n * \n * David A. Mcgrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#include \"key.h\"\n\n#define soft_limit 0x10000\n\nerr_status_t\nkey_limit_set(key_limit_t key, const xtd_seq_num_t s) {\n#ifdef NO_64BIT_MATH\n  if (high32(s) == 0 && low32(s) < soft_limit)\n    return err_status_bad_param;\n#else\n  if (s < soft_limit)\n    return err_status_bad_param;\n#endif\n  key->num_left = s;\n  key->state = key_state_normal;\n  return err_status_ok;\n}\n\nerr_status_t\nkey_limit_clone(key_limit_t original, key_limit_t *new_key) {\n  if (original == NULL)\n    return err_status_bad_param;\n  *new_key = original;\n  return err_status_ok;\n}\n\nerr_status_t\nkey_limit_check(const key_limit_t key) {\n  if (key->state == key_state_expired)\n    return err_status_key_expired;\n  return err_status_ok;\n}\n\nkey_event_t\nkey_limit_update(key_limit_t key) {\n#ifdef NO_64BIT_MATH\n  if (low32(key->num_left) == 0)\n  {\n\t  // carry\n\t  key->num_left = make64(high32(key->num_left)-1,low32(key->num_left) - 1);\n  }\n  else\n  {\n\t  // no carry\n\t  key->num_left = make64(high32(key->num_left),low32(key->num_left) - 1);\n  }\n  if (high32(key->num_left) != 0 || low32(key->num_left) >= soft_limit) {\n    return key_event_normal;   /* we're above the soft limit */\n  }\n#else\n  key->num_left--;\n  if (key->num_left >= soft_limit) {\n    return key_event_normal;   /* we're above the soft limit */\n  }\n#endif\n  if (key->state == key_state_normal) {\n    /* we just passed the soft limit, so change the state */\n    key->state = key_state_past_soft_limit;\n  }\n#ifdef NO_64BIT_MATH\n  if (low32(key->num_left) == 0 && high32(key->num_left == 0))\n#else\n  if (key->num_left < 1)\n#endif\n  { /* we just hit the hard limit */\n    key->state = key_state_expired;\n    return key_event_hard_limit;\n  }\n   return key_event_soft_limit;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/math/datatypes.c",
    "content": "/*\n * datatypes.c\n *\n * data types for finite fields and functions for input, output, and\n * manipulation\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#include \"datatypes.h\"\n\nint \noctet_weight[256] = {\n  0, 1, 1, 2, 1, 2, 2, 3,\n  1, 2, 2, 3, 2, 3, 3, 4,\n  1, 2, 2, 3, 2, 3, 3, 4,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  1, 2, 2, 3, 2, 3, 3, 4,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  1, 2, 2, 3, 2, 3, 3, 4,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  4, 5, 5, 6, 5, 6, 6, 7,\n  1, 2, 2, 3, 2, 3, 3, 4,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  4, 5, 5, 6, 5, 6, 6, 7,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  4, 5, 5, 6, 5, 6, 6, 7,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  4, 5, 5, 6, 5, 6, 6, 7,\n  4, 5, 5, 6, 5, 6, 6, 7,\n  5, 6, 6, 7, 6, 7, 7, 8\n};\n\nint\noctet_get_weight(uint8_t octet) {\n  extern int octet_weight[256];\n\n  return octet_weight[octet];\n}  \n\n/*\n * bit_string is a buffer that is used to hold output strings, e.g.\n * for printing.\n */\n\n/* the value MAX_PRINT_STRING_LEN is defined in datatypes.h */\n\nchar bit_string[MAX_PRINT_STRING_LEN];\n\nuint8_t\nnibble_to_hex_char(uint8_t nibble) {\n  char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7',\n\t\t  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };\n  return buf[nibble & 0xF];\n}\n\nchar *\noctet_string_hex_string(const void *s, int length) {\n  const uint8_t *str = (const uint8_t *)s;\n  int i;\n  \n  /* double length, since one octet takes two hex characters */\n  length *= 2;\n\n  /* truncate string if it would be too long */\n  if (length >= MAX_PRINT_STRING_LEN-1)\n    length = MAX_PRINT_STRING_LEN-2;\n  \n  for (i=0; i < length; i+=2) {\n    bit_string[i]   = nibble_to_hex_char(*str >> 4);\n    bit_string[i+1] = nibble_to_hex_char(*str++ & 0xF);\n  }\n  bit_string[i] = 0; /* null terminate string */\n  return bit_string;\n}\n\nstatic inline int\nhex_char_to_nibble(uint8_t c) {\n  switch(c) {\n  case ('0'): return 0x0;\n  case ('1'): return 0x1;\n  case ('2'): return 0x2;\n  case ('3'): return 0x3;\n  case ('4'): return 0x4;\n  case ('5'): return 0x5;\n  case ('6'): return 0x6;\n  case ('7'): return 0x7;\n  case ('8'): return 0x8;\n  case ('9'): return 0x9;\n  case ('a'): return 0xa;\n  case ('A'): return 0xa;\n  case ('b'): return 0xb;\n  case ('B'): return 0xb;\n  case ('c'): return 0xc;\n  case ('C'): return 0xc;\n  case ('d'): return 0xd;\n  case ('D'): return 0xd;\n  case ('e'): return 0xe;\n  case ('E'): return 0xe;\n  case ('f'): return 0xf;\n  case ('F'): return 0xf;\n  default: break;   /* this flags an error */\n  }\n  return -1;\n}\n\nint\nis_hex_string(char *s) {\n  while(*s != 0)\n    if (hex_char_to_nibble(*s++) == -1)\n      return 0;\n  return 1;\n}\n\n/*\n * hex_string_to_octet_string converts a hexadecimal string\n * of length 2 * len to a raw octet string of length len\n */\n\nint\nhex_string_to_octet_string(char *raw, char *hex, int len) {\n  uint8_t x;\n  int tmp;\n  int hex_len;\n\n  hex_len = 0;\n  while (hex_len < len) {\n    tmp = hex_char_to_nibble(hex[0]);\n    if (tmp == -1)\n      return hex_len;\n    x = (tmp << 4);\n    hex_len++;\n    tmp = hex_char_to_nibble(hex[1]);\n    if (tmp == -1)\n      return hex_len;\n    x |= (tmp & 0xff);\n    hex_len++;\n    *raw++ = x;\n    hex += 2;\n  }\n  return hex_len;\n}\n\nchar *\nv128_hex_string(v128_t *x) {\n  int i, j;\n\n  for (i=j=0; i < 16; i++) {\n    bit_string[j++]  = nibble_to_hex_char(x->v8[i] >> 4);\n    bit_string[j++]  = nibble_to_hex_char(x->v8[i] & 0xF);\n  }\n  \n  bit_string[j] = 0; /* null terminate string */\n  return bit_string;\n}\n\nchar *\nv128_bit_string(v128_t *x) {\n  int j, index;\n  uint32_t mask;\n  \n  for (j=index=0; j < 4; j++) {\n    for (mask=0x80000000; mask > 0; mask >>= 1) {\n      if (x->v32[j] & mask)\n\tbit_string[index] = '1';\n      else\n\tbit_string[index] = '0';\n      ++index;\n    }\n  }\n  bit_string[128] = 0; /* null terminate string */\n\n  return bit_string;\n}\n\nvoid\nv128_copy_octet_string(v128_t *x, const uint8_t s[16]) {\n#ifdef ALIGNMENT_32BIT_REQUIRED\n  if ((((uint32_t) &s[0]) & 0x3) != 0)\n#endif\n  {\n\t  x->v8[0]  = s[0];\n\t  x->v8[1]  = s[1];\n\t  x->v8[2]  = s[2];\n\t  x->v8[3]  = s[3];\n\t  x->v8[4]  = s[4];\n\t  x->v8[5]  = s[5];\n\t  x->v8[6]  = s[6];\n\t  x->v8[7]  = s[7];\n\t  x->v8[8]  = s[8];\n\t  x->v8[9]  = s[9];\n\t  x->v8[10] = s[10];\n\t  x->v8[11] = s[11];\n\t  x->v8[12] = s[12];\n\t  x->v8[13] = s[13];\n\t  x->v8[14] = s[14];\n\t  x->v8[15] = s[15];\n  }\n#ifdef ALIGNMENT_32BIT_REQUIRED\n  else \n  {\n\t  v128_t *v = (v128_t *) &s[0];\n\n\t  v128_copy(x,v);\n  }\n#endif\n}\n\n#ifndef DATATYPES_USE_MACROS /* little functions are not macros */\n\nvoid\nv128_set_to_zero(v128_t *x) {\n  _v128_set_to_zero(x);\n}\n\nvoid\nv128_copy(v128_t *x, const v128_t *y) {\n  _v128_copy(x, y);\n}\n\nvoid\nv128_xor(v128_t *z, v128_t *x, v128_t *y) {\n  _v128_xor(z, x, y);\n} \n\nvoid\nv128_and(v128_t *z, v128_t *x, v128_t *y) {\n  _v128_and(z, x, y);\n}\n\nvoid\nv128_or(v128_t *z, v128_t *x, v128_t *y) {\n  _v128_or(z, x, y);\n}\n\nvoid\nv128_complement(v128_t *x) {\n  _v128_complement(x);\n}\n\nint\nv128_is_eq(const v128_t *x, const v128_t *y) {\n  return _v128_is_eq(x, y);\n}\n\nint\nv128_xor_eq(v128_t *x, const v128_t *y) {\n  return _v128_xor_eq(x, y);\n}\n\nint\nv128_get_bit(const v128_t *x, int i) {\n  return _v128_get_bit(x, i);\n}\n\nvoid\nv128_set_bit(v128_t *x, int i) {\n  _v128_set_bit(x, i);\n}     \n\nvoid\nv128_clear_bit(v128_t *x, int i){\n  _v128_clear_bit(x, i);\n}    \n\nvoid\nv128_set_bit_to(v128_t *x, int i, int y){\n  _v128_set_bit_to(x, i, y);\n}\n\n\n#endif /* DATATYPES_USE_MACROS */\n\nvoid\nv128_right_shift(v128_t *x, int index) {\n  const int base_index = index >> 5;\n  const int bit_index = index & 31;\n  int i, from;\n  uint32_t b;\n    \n  if (index > 127) {\n    v128_set_to_zero(x);\n    return;\n  }\n\n  if (bit_index == 0) {\n\n    /* copy each word from left size to right side */\n    x->v32[4-1] = x->v32[4-1-base_index];\n    for (i=4-1; i > base_index; i--) \n      x->v32[i-1] = x->v32[i-1-base_index];\n\n  } else {\n    \n    /* set each word to the \"or\" of the two bit-shifted words */\n    for (i = 4; i > base_index; i--) {\n      from = i-1 - base_index;\n      b = x->v32[from] << bit_index;\n      if (from > 0)\n        b |= x->v32[from-1] >> (32-bit_index);\n      x->v32[i-1] = b;\n    }\n    \n  }\n\n  /* now wrap up the final portion */\n  for (i=0; i < base_index; i++) \n    x->v32[i] = 0;\n  \n}\n\nvoid\nv128_left_shift(v128_t *x, int index) {\n  int i;\n  const int base_index = index >> 5;\n  const int bit_index = index & 31;\n\n  if (index > 127) {\n    v128_set_to_zero(x);\n    return;\n  } \n  \n  if (bit_index == 0) {\n    for (i=0; i < 4 - base_index; i++)\n      x->v32[i] = x->v32[i+base_index];\n  } else {\n    for (i=0; i < 4 - base_index - 1; i++)\n      x->v32[i] = (x->v32[i+base_index] >> bit_index) ^\n\t(x->v32[i+base_index+1] << (32 - bit_index));\n    x->v32[4 - base_index-1] = x->v32[4-1] >> bit_index;\n  }\n\n  /* now wrap up the final portion */\n  for (i = 4 - base_index; i < 4; i++) \n    x->v32[i] = 0;\n\n}\n\n\nint\noctet_string_is_eq(uint8_t *a, uint8_t *b, int len) {\n  uint8_t *end = b + len;\n  while (b < end)\n    if (*a++ != *b++)\n      return 1;\n  return 0;\n}\n\nvoid\noctet_string_set_to_zero(uint8_t *s, int len) {\n  uint8_t *end = s + len;\n\n  do {\n    *s = 0;\n  } while (++s < end);\n  \n}\n\n\n/*\n *  From RFC 1521: The Base64 Alphabet\n *\n *   Value Encoding  Value Encoding  Value Encoding  Value Encoding\n *        0 A            17 R            34 i            51 z\n *        1 B            18 S            35 j            52 0\n *        2 C            19 T            36 k            53 1\n *        3 D            20 U            37 l            54 2\n *        4 E            21 V            38 m            55 3\n *        5 F            22 W            39 n            56 4\n *        6 G            23 X            40 o            57 5\n *        7 H            24 Y            41 p            58 6\n *        8 I            25 Z            42 q            59 7\n *        9 J            26 a            43 r            60 8\n *       10 K            27 b            44 s            61 9\n *       11 L            28 c            45 t            62 +\n *       12 M            29 d            46 u            63 /\n *       13 N            30 e            47 v\n *       14 O            31 f            48 w         (pad) =\n *       15 P            32 g            49 x\n *       16 Q            33 h            50 y\n */\n\nint\nbase64_char_to_sextet(uint8_t c) {\n  switch(c) {\n  case 'A':\n    return 0;\n  case 'B':\n    return 1;\n  case 'C':\n    return 2;\n  case 'D':\n    return 3;\n  case 'E':\n    return 4;\n  case 'F':\n    return 5;\n  case 'G':\n    return 6;\n  case 'H':\n    return 7;\n  case 'I':\n    return 8;\n  case 'J':\n    return 9;\n  case 'K':\n    return 10;\n  case 'L':\n    return 11;\n  case 'M':\n    return 12;\n  case 'N':\n    return 13;\n  case 'O':\n    return 14;\n  case 'P':\n    return 15;\n  case 'Q':\n    return 16;\n  case 'R':\n    return 17;\n  case 'S':\n    return 18;\n  case 'T':\n    return 19;\n  case 'U':\n    return 20;\n  case 'V':\n    return 21;\n  case 'W':\n    return 22;\n  case 'X':\n    return 23;\n  case 'Y':\n    return 24;\n  case 'Z':\n    return 25;\n  case 'a':\n    return 26;\n  case 'b':\n    return 27;\n  case 'c':\n    return 28;\n  case 'd':\n    return 29;\n  case 'e':\n    return 30;\n  case 'f':\n    return 31;\n  case 'g':\n    return 32;\n  case 'h':\n    return 33;\n  case 'i':\n    return 34;\n  case 'j':\n    return 35;\n  case 'k':\n    return 36;\n  case 'l':\n    return 37;\n  case 'm':\n    return 38;\n  case 'n':\n    return 39;\n  case 'o':\n    return 40;\n  case 'p':\n    return 41;\n  case 'q':\n    return 42;\n  case 'r':\n    return 43;\n  case 's':\n    return 44;\n  case 't':\n    return 45;\n  case 'u':\n    return 46;\n  case 'v':\n    return 47;\n  case 'w':\n    return 48;\n  case 'x':\n    return 49;\n  case 'y':\n    return 50;\n  case 'z':\n    return 51;\n  case '0':\n    return 52;\n  case '1':\n    return 53;\n  case '2':\n    return 54;\n  case '3':\n    return 55;\n  case '4':\n    return 56;\n  case '5':\n    return 57;\n  case '6':\n    return 58;\n  case '7':\n    return 59;\n  case '8':\n    return 60;\n  case '9':\n    return 61;\n  case '+':\n    return 62;\n  case '/':\n    return 63;\n  case '=':\n    return 64;\n  default:\n    break;\n }\n return -1;\n}\n\n/*\n * base64_string_to_octet_string converts a hexadecimal string\n * of length 2 * len to a raw octet string of length len\n */\n\nint\nbase64_string_to_octet_string(char *raw, char *base64, int len) {\n  uint8_t x;\n  int tmp;\n  int base64_len;\n\n  base64_len = 0;\n  while (base64_len < len) {\n    tmp = base64_char_to_sextet(base64[0]);\n    if (tmp == -1)\n      return base64_len;\n    x = (tmp << 6);\n    base64_len++;\n    tmp = base64_char_to_sextet(base64[1]);\n    if (tmp == -1)\n      return base64_len;\n    x |= (tmp & 0xffff);\n    base64_len++;\n    *raw++ = x;\n    base64 += 2;\n  }\n  return base64_len;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/math/gf2_8.c",
    "content": "/*\n * gf2_8.c\n *\n * GF(256) finite field implementation, with the representation used\n * in the AES cipher.\n * \n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#include \"datatypes.h\"\n#include \"gf2_8.h\"\n\n/* gf2_8_shift() moved to gf2_8.h as an inline function */\n\ninline gf2_8\ngf2_8_multiply(gf2_8 x, gf2_8 y) {\n  gf2_8 z = 0;\n\n  if (y &   1) z ^= x; x = gf2_8_shift(x);\n  if (y &   2) z ^= x; x = gf2_8_shift(x);\n  if (y &   4) z ^= x; x = gf2_8_shift(x);\n  if (y &   8) z ^= x; x = gf2_8_shift(x);\n  if (y &  16) z ^= x; x = gf2_8_shift(x);\n  if (y &  32) z ^= x; x = gf2_8_shift(x);\n  if (y &  64) z ^= x; x = gf2_8_shift(x);\n  if (y & 128) z ^= x; \n  \n  return z;\n}\n\n\n/* this should use the euclidean algorithm */\n\ngf2_8\ngf2_8_compute_inverse(gf2_8 x) {\n  unsigned int i;\n\n  if (x == 0) return 0;    /* zero is a special case */\n  for (i=0; i < 256; i++)\n    if (gf2_8_multiply((gf2_8) i, x) == 1)\n      return (gf2_8) i;\n\n    return 0;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/math/math.c",
    "content": "/*\n * math.c\n *\n * crypto math operations and data types\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#include \"crypto_math.h\"\n#include <stdlib.h>           /* malloc() used in bitvector_alloc */\n\nint \noctet_weight[256] = {\n  0, 1, 1, 2, 1, 2, 2, 3,\n  1, 2, 2, 3, 2, 3, 3, 4,\n  1, 2, 2, 3, 2, 3, 3, 4,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  1, 2, 2, 3, 2, 3, 3, 4,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  1, 2, 2, 3, 2, 3, 3, 4,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  4, 5, 5, 6, 5, 6, 6, 7,\n  1, 2, 2, 3, 2, 3, 3, 4,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  4, 5, 5, 6, 5, 6, 6, 7,\n  2, 3, 3, 4, 3, 4, 4, 5,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  4, 5, 5, 6, 5, 6, 6, 7,\n  3, 4, 4, 5, 4, 5, 5, 6,\n  4, 5, 5, 6, 5, 6, 6, 7,\n  4, 5, 5, 6, 5, 6, 6, 7,\n  5, 6, 6, 7, 6, 7, 7, 8\n};\n\nint\nlow_bit[256] = {\n  -1, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  4, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  5, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  4, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  6, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  4, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  5, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  4, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  7, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  4, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  5, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  4, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  6, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  4, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  5, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0,\n  4, 0, 1, 0, 2, 0, 1, 0,\n  3, 0, 1, 0, 2, 0, 1, 0\n};\n\n\nint\nhigh_bit[256] = {\n  -1, 0, 1, 1, 2, 2, 2, 2,\n  3, 3, 3, 3, 3, 3, 3, 3,\n  4, 4, 4, 4, 4, 4, 4, 4,\n  4, 4, 4, 4, 4, 4, 4, 4,\n  5, 5, 5, 5, 5, 5, 5, 5,\n  5, 5, 5, 5, 5, 5, 5, 5,\n  5, 5, 5, 5, 5, 5, 5, 5,\n  5, 5, 5, 5, 5, 5, 5, 5,\n  6, 6, 6, 6, 6, 6, 6, 6,\n  6, 6, 6, 6, 6, 6, 6, 6,\n  6, 6, 6, 6, 6, 6, 6, 6,\n  6, 6, 6, 6, 6, 6, 6, 6,\n  6, 6, 6, 6, 6, 6, 6, 6,\n  6, 6, 6, 6, 6, 6, 6, 6,\n  6, 6, 6, 6, 6, 6, 6, 6,\n  6, 6, 6, 6, 6, 6, 6, 6,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7,\n  7, 7, 7, 7, 7, 7, 7, 7\n};\n\nint\noctet_get_weight(uint8_t octet) {\n  extern int octet_weight[256];\n\n  return octet_weight[octet];\n}  \n\nunsigned char\nv32_weight(v32_t a) {\n  unsigned int wt = 0;\n  \n  wt += octet_weight[a.v8[0]];  /* note: endian-ness makes no difference */\n  wt += octet_weight[a.v8[1]];\n  wt += octet_weight[a.v8[2]];\n  wt += octet_weight[a.v8[3]];\n  \n  return wt;\n}\n\ninline unsigned char\nv32_distance(v32_t x, v32_t y) {\n  x.value ^= y.value;\n  return v32_weight(x);\n}\n\nunsigned int\nv32_dot_product(v32_t a, v32_t b) {\n  a.value &= b.value;\n  return v32_weight(a) & 1;\n}\n\n/*\n * _bit_string returns a NULL-terminated character string suitable for\n * printing\n */\n\n#define MAX_STRING_LENGTH 1024\n\nchar bit_string[MAX_STRING_LENGTH];\n\nchar *\noctet_bit_string(uint8_t x) {\n  int mask, index;\n\n  for (mask = 1, index = 0; mask < 256; mask <<= 1)\n    if ((x & mask) == 0)\n      bit_string[index++] = '0';\n    else\n      bit_string[index++] = '1';\n\n  bit_string[index++] = 0;  /* NULL terminate string */\n\n  return bit_string;\n}\n\nchar *\nv16_bit_string(v16_t x) {\n  int i, mask, index;\n\n  for (i = index = 0; i < 2; i++) {\n    for (mask = 1; mask < 256; mask <<= 1)\n      if ((x.v8[i] & mask) == 0)\n\tbit_string[index++] = '0';\n      else\n\tbit_string[index++] = '1';\n  }\n  bit_string[index++] = 0;  /* NULL terminate string */\n  return bit_string;\n}\n\nchar *\nv32_bit_string(v32_t x) {\n  int i, mask, index;\n\n  for (i = index = 0; i < 4; i++) {\n    for (mask = 128; mask > 0; mask >>= 1)\n      if ((x.v8[i] & mask) == 0)\n\tbit_string[index++] = '0';\n      else\n\tbit_string[index++] = '1';\n  }\n  bit_string[index++] = 0;  /* NULL terminate string */\n  return bit_string;\n}\n\nchar *\nv64_bit_string(const v64_t *x) {\n  int i, mask, index;\n\n  for (i = index = 0; i < 8; i++) {\n    for (mask = 1; mask < 256; mask <<= 1)\n      if ((x->v8[i] & mask) == 0)\n\tbit_string[index++] = '0';\n      else\n\tbit_string[index++] = '1';\n  }\n  bit_string[index++] = 0;  /* NULL terminate string */\n  return bit_string;\n}\n\nchar *\nv128_bit_string(v128_t *x) {\n  int j, index;\n  uint32_t mask;\n  \n  for (j=index=0; j < 4; j++) {\n    for (mask=0x80000000; mask > 0; mask >>= 1) {\n      if (x->v32[j] & mask)\n\tbit_string[index] = '1';\n      else\n\tbit_string[index] = '0';\n      ++index;\n    }\n  }\n  bit_string[128] = 0; /* null terminate string */\n\n  return bit_string;\n}\n\nuint8_t\nnibble_to_hex_char(uint8_t nibble) {\n  char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7',\n\t\t  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };\n  return buf[nibble & 0xF];\n}\n\nchar *\noctet_hex_string(uint8_t x) {\n\n  bit_string[0]  = nibble_to_hex_char(x >> 4);\n  bit_string[1]  = nibble_to_hex_char(x & 0xF);\n  \n  bit_string[2] = 0; /* null terminate string */\n  return bit_string;\n}\n\nchar *\noctet_string_hex_string(const void *str, int length) {\n  const uint8_t *s = str;\n  int i;\n  \n  /* double length, since one octet takes two hex characters */\n  length *= 2;\n\n  /* truncate string if it would be too long */\n  if (length > MAX_STRING_LENGTH)\n    length = MAX_STRING_LENGTH-1;\n  \n  for (i=0; i < length; i+=2) {\n    bit_string[i]   = nibble_to_hex_char(*s >> 4);\n    bit_string[i+1] = nibble_to_hex_char(*s++ & 0xF);\n  }\n  bit_string[i] = 0; /* null terminate string */\n  return bit_string;\n}\n\nchar *\nv16_hex_string(v16_t x) {\n  int i, j;\n\n  for (i=j=0; i < 2; i++) {\n    bit_string[j++]  = nibble_to_hex_char(x.v8[i] >> 4);\n    bit_string[j++]  = nibble_to_hex_char(x.v8[i] & 0xF);\n  }\n  \n  bit_string[j] = 0; /* null terminate string */\n  return bit_string;\n}\n\nchar *\nv32_hex_string(v32_t x) {\n  int i, j;\n\n  for (i=j=0; i < 4; i++) {\n    bit_string[j++]  = nibble_to_hex_char(x.v8[i] >> 4);\n    bit_string[j++]  = nibble_to_hex_char(x.v8[i] & 0xF);\n  }\n  \n  bit_string[j] = 0; /* null terminate string */\n  return bit_string;\n}\n\nchar *\nv64_hex_string(const v64_t *x) {\n  int i, j;\n\n  for (i=j=0; i < 8; i++) {\n    bit_string[j++]  = nibble_to_hex_char(x->v8[i] >> 4);\n    bit_string[j++]  = nibble_to_hex_char(x->v8[i] & 0xF);\n  }\n  \n  bit_string[j] = 0; /* null terminate string */\n  return bit_string;\n}\n\nchar *\nv128_hex_string(v128_t *x) {\n  int i, j;\n\n  for (i=j=0; i < 16; i++) {\n    bit_string[j++]  = nibble_to_hex_char(x->v8[i] >> 4);\n    bit_string[j++]  = nibble_to_hex_char(x->v8[i] & 0xF);\n  }\n  \n  bit_string[j] = 0; /* null terminate string */\n  return bit_string;\n}\n\nchar *\nchar_to_hex_string(char *x, int num_char) {\n  int i, j;\n\n  if (num_char >= 16)\n    num_char = 16;\n  for (i=j=0; i < num_char; i++) {\n    bit_string[j++]  = nibble_to_hex_char(x[i] >> 4);\n    bit_string[j++]  = nibble_to_hex_char(x[i] & 0xF);\n  }\n  \n  bit_string[j] = 0; /* null terminate string */\n  return bit_string;\n}\n\nint\nhex_char_to_nibble(uint8_t c) {\n  switch(c) {\n  case ('0'): return 0x0;\n  case ('1'): return 0x1;\n  case ('2'): return 0x2;\n  case ('3'): return 0x3;\n  case ('4'): return 0x4;\n  case ('5'): return 0x5;\n  case ('6'): return 0x6;\n  case ('7'): return 0x7;\n  case ('8'): return 0x8;\n  case ('9'): return 0x9;\n  case ('a'): return 0xa;\n  case ('A'): return 0xa;\n  case ('b'): return 0xb;\n  case ('B'): return 0xb;\n  case ('c'): return 0xc;\n  case ('C'): return 0xc;\n  case ('d'): return 0xd;\n  case ('D'): return 0xd;\n  case ('e'): return 0xe;\n  case ('E'): return 0xe;\n  case ('f'): return 0xf;\n  case ('F'): return 0xf;\n  default: return -1;   /* this flags an error */\n  }\n  /* NOTREACHED */\n  return -1;  /* this keeps compilers from complaining */\n}\n\nint\nis_hex_string(char *s) {\n  while(*s != 0)\n    if (hex_char_to_nibble(*s++) == -1)\n      return 0;\n  return 1;\n}\n\nuint8_t\nhex_string_to_octet(char *s) {\n  uint8_t x;\n\n  x = (hex_char_to_nibble(s[0]) << 4)\n    | hex_char_to_nibble(s[1] & 0xFF);\n  \n  return x;\n}\n\n/*\n * hex_string_to_octet_string converts a hexadecimal string\n * of length 2 * len to a raw octet string of length len\n */\n\nint\nhex_string_to_octet_string(char *raw, char *hex, int len) {\n  uint8_t x;\n  int tmp;\n  int hex_len;\n\n  hex_len = 0;\n  while (hex_len < len) {\n    tmp = hex_char_to_nibble(hex[0]);\n    if (tmp == -1)\n      return hex_len;\n    x = (tmp << 4);\n    hex_len++;\n    tmp = hex_char_to_nibble(hex[1]);\n    if (tmp == -1)\n      return hex_len;\n    x |= (tmp & 0xff);\n    hex_len++;\n    *raw++ = x;\n    hex += 2;\n  }\n  return hex_len;\n}\n\nv16_t\nhex_string_to_v16(char *s) {\n  v16_t x;\n  int i, j;\n\n  for (i=j=0; i < 4; i += 2, j++) {\n    x.v8[j] = (hex_char_to_nibble(s[i]) << 4)\n      | hex_char_to_nibble(s[i+1] & 0xFF);\n  }\n  return x;\n}\n\nv32_t\nhex_string_to_v32(char *s) {\n  v32_t x;\n  int i, j;\n\n  for (i=j=0; i < 8; i += 2, j++) {\n    x.v8[j] = (hex_char_to_nibble(s[i]) << 4)\n      | hex_char_to_nibble(s[i+1] & 0xFF);\n  }\n  return x;\n}\n\nv64_t\nhex_string_to_v64(char *s) {\n  v64_t x;\n  int i, j;\n\n  for (i=j=0; i < 16; i += 2, j++) {\n    x.v8[j] = (hex_char_to_nibble(s[i]) << 4)\n      | hex_char_to_nibble(s[i+1] & 0xFF);\n  }\n  return x;\n}\n\nv128_t\nhex_string_to_v128(char *s) {\n  v128_t x;\n  int i, j;\n\n  for (i=j=0; i < 32; i += 2, j++) {\n    x.v8[j] = (hex_char_to_nibble(s[i]) << 4)\n      | hex_char_to_nibble(s[i+1] & 0xFF);\n  }\n  return x;\n}\n\n\n\n/* \n * the matrix A[] is stored in column format, i.e., A[i] is the ith\n * column of the matrix \n */\n\nuint8_t \nA_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b) {\n  int index = 0;\n  unsigned mask;\n  \n  for (mask=1; mask < 256; mask *= 2) {\n    if (x & mask)\n      b^= A[index];\n    ++index;\n  }\n\n  return b;\n}\n\ninline void\nv16_copy_octet_string(v16_t *x, const uint8_t s[2]) {\n  x->v8[0]  = s[0];\n  x->v8[1]  = s[1];\n}\n\ninline void\nv32_copy_octet_string(v32_t *x, const uint8_t s[4]) {\n  x->v8[0]  = s[0];\n  x->v8[1]  = s[1];\n  x->v8[2]  = s[2];\n  x->v8[3]  = s[3];\n}\n\ninline void\nv64_copy_octet_string(v64_t *x, const uint8_t s[8]) {\n  x->v8[0]  = s[0];\n  x->v8[1]  = s[1];\n  x->v8[2]  = s[2];\n  x->v8[3]  = s[3];\n  x->v8[4]  = s[4];\n  x->v8[5]  = s[5];\n  x->v8[6]  = s[6];\n  x->v8[7]  = s[7];\n}\n\nvoid\nv128_copy_octet_string(v128_t *x, const uint8_t s[16]) {\n  x->v8[0]  = s[0];\n  x->v8[1]  = s[1];\n  x->v8[2]  = s[2];\n  x->v8[3]  = s[3];\n  x->v8[4]  = s[4];\n  x->v8[5]  = s[5];\n  x->v8[6]  = s[6];\n  x->v8[7]  = s[7];\n  x->v8[8]  = s[8];\n  x->v8[9]  = s[9];\n  x->v8[10] = s[10];\n  x->v8[11] = s[11];\n  x->v8[12] = s[12];\n  x->v8[13] = s[13];\n  x->v8[14] = s[14];\n  x->v8[15] = s[15];\n\n}\n\n#ifndef DATATYPES_USE_MACROS /* little functions are not macros */\n\nvoid\nv128_set_to_zero(v128_t *x) {\n  _v128_set_to_zero(x);\n}\n\nvoid\nv128_copy(v128_t *x, const v128_t *y) {\n  _v128_copy(x, y);\n}\n\nvoid\nv128_xor(v128_t *z, v128_t *x, v128_t *y) {\n  _v128_xor(z, x, y);\n} \n\nvoid\nv128_and(v128_t *z, v128_t *x, v128_t *y) {\n  _v128_and(z, x, y);\n}\n\nvoid\nv128_or(v128_t *z, v128_t *x, v128_t *y) {\n  _v128_or(z, x, y);\n}\n\nvoid\nv128_complement(v128_t *x) {\n  _v128_complement(x);\n}\n\nint\nv128_is_eq(const v128_t *x, const v128_t *y) {\n  return _v128_is_eq(x, y);\n}\n\nint\nv128_get_bit(const v128_t *x, int i) {\n  return _v128_get_bit(x, i);\n}\n\nvoid\nv128_set_bit(v128_t *x, int i) {\n  _v128_set_bit(x, i);\n}     \n\nvoid\nv128_clear_bit(v128_t *x, int i){\n  _v128_clear_bit(x, i);\n}    \n\nvoid\nv128_set_bit_to(v128_t *x, int i, int y){\n  _v128_set_bit_to(x, i, y);\n}\n\n\n#endif /* DATATYPES_USE_MACROS */\n\n\ninline void\nv128_left_shift2(v128_t *x, int num_bits) {\n  int i;\n  int word_shift = num_bits >> 5;\n  int bit_shift  = num_bits & 31;\n\n  for (i=0; i < (4-word_shift); i++) {\n    x->v32[i] = x->v32[i+word_shift] << bit_shift;\n  }\n  \n  for (   ; i < word_shift; i++) {\n    x->v32[i] = 0;\n  }\n  \n}\n\nvoid\nv128_right_shift(v128_t *x, int index) {\n  const int base_index = index >> 5;\n  const int bit_index = index & 31;\n  int i, from;\n  uint32_t b;\n    \n  if (index > 127) {\n    v128_set_to_zero(x);\n    return;\n  }\n\n  if (bit_index == 0) {\n\n    /* copy each word from left size to right side */\n    x->v32[4-1] = x->v32[4-1-base_index];\n    for (i=4-1; i > base_index; i--) \n      x->v32[i-1] = x->v32[i-1-base_index];\n\n  } else {\n    \n    /* set each word to the \"or\" of the two bit-shifted words */\n    for (i = 4; i > base_index; i--) {\n      from = i-1 - base_index;\n      b = x->v32[from] << bit_index;\n      if (from > 0)\n        b |= x->v32[from-1] >> (32-bit_index);\n      x->v32[i-1] = b;\n    }\n    \n  }\n\n  /* now wrap up the final portion */\n  for (i=0; i < base_index; i++) \n    x->v32[i] = 0;\n  \n}\n\nvoid\nv128_left_shift(v128_t *x, int index) {\n  int i;\n  const int base_index = index >> 5;\n  const int bit_index = index & 31;\n\n  if (index > 127) {\n    v128_set_to_zero(x);\n    return;\n  } \n  \n  if (bit_index == 0) {\n    for (i=0; i < 4 - base_index; i++)\n      x->v32[i] = x->v32[i+base_index];\n  } else {\n    for (i=0; i < 4 - base_index - 1; i++)\n      x->v32[i] = (x->v32[i+base_index] << bit_index) ^\n\t(x->v32[i+base_index+1] >> (32 - bit_index));\n    x->v32[4 - base_index-1] = x->v32[4-1] << bit_index;\n  }\n\n  /* now wrap up the final portion */\n  for (i = 4 - base_index; i < 4; i++) \n    x->v32[i] = 0;\n\n}\n\n\n#if 0\nvoid\nv128_add(v128_t *z, v128_t *x, v128_t *y) {\n  /* integer addition modulo 2^128    */\n\n#ifdef WORDS_BIGENDIAN\n  uint64_t tmp;\n    \n  tmp = x->v32[3] + y->v32[3];\n  z->v32[3] = (uint32_t) tmp;\n  \n  tmp =  x->v32[2] + y->v32[2] + (tmp >> 32);\n  z->v32[2] = (uint32_t) tmp;\n\n  tmp =  x->v32[1] + y->v32[1] + (tmp >> 32);\n  z->v32[1] = (uint32_t) tmp;\n  \n  tmp =  x->v32[0] + y->v32[0] + (tmp >> 32);\n  z->v32[0] = (uint32_t) tmp;\n\n#else /* assume little endian architecture */\n  uint64_t tmp;\n  \n  tmp = htonl(x->v32[3]) + htonl(y->v32[3]);\n  z->v32[3] = ntohl((uint32_t) tmp);\n  \n  tmp =  htonl(x->v32[2]) + htonl(y->v32[2]) + htonl(tmp >> 32);\n  z->v32[2] = ntohl((uint32_t) tmp);\n\n  tmp =  htonl(x->v32[1]) + htonl(y->v32[1]) + htonl(tmp >> 32);\n  z->v32[1] = ntohl((uint32_t) tmp);\n  \n  tmp =  htonl(x->v32[0]) + htonl(y->v32[0]) + htonl(tmp >> 32);\n  z->v32[0] = ntohl((uint32_t) tmp);\n\n#endif /* WORDS_BIGENDIAN */\n  \n}\n#endif\n\nint\noctet_string_is_eq(uint8_t *a, uint8_t *b, int len) {\n  uint8_t *end = b + len;\n  while (b < end)\n    if (*a++ != *b++)\n      return 1;\n  return 0;\n}\n\nvoid\noctet_string_set_to_zero(uint8_t *s, int len) {\n  uint8_t *end = s + len;\n\n  do {\n    *s = 0;\n  } while (++s < end);\n  \n}\n\n/* functions manipulating bit_vector_t */\n\n#define BITVECTOR_MAX_WORDS 5\n\nint\nbitvector_alloc(bitvector_t *v, unsigned long length) {\n  unsigned long l = (length + bytes_per_word - 1) / bytes_per_word;\n  int i;\n\n  /* allocate memory, then set parameters */\n  if (l > BITVECTOR_MAX_WORDS)\n    return -1;\n  else\n    l = BITVECTOR_MAX_WORDS;\n  v->word   = malloc(l);\n  if (v->word == NULL)\n    return -1;\n  v->length = length;\n\n  /* initialize bitvector to zero */\n  for (i=0; i < (length >> 5); i++) {\n    v->word = 0;\n  }\n\n  return 0;\n}\n\nvoid\nbitvector_set_bit(bitvector_t *v, int bit_index) {\n\n  v->word[(bit_index >> 5)] |= (1 << (bit_index & 31));\n  \n}\n\nint\nbitvector_get_bit(const bitvector_t *v, int bit_index) {\n\n  return ((v->word[(bit_index >> 5)]) >> (bit_index & 31)) & 1;\n  \n}\n\n#include <stdio.h>\n\nint\nbitvector_print_hex(const bitvector_t *v, FILE *stream) {\n  int i;\n  int m = v->length >> 5;\n  int n = v->length & 31;\n  char string[9];\n  uint32_t tmp;\n\n  /* if length isn't a multiple of four, we can't hex_print */\n  if (n & 3)\n    return -1;\n  \n  /* if the length is zero, do nothing */\n  if (v->length == 0)\n    return 0;\n\n  /*\n   * loop over words from most significant to least significant - \n   */\n  \n  for (i=m; i > 0; i++) {\n    char *str = string + 7;\n    tmp = v->word[i];\n    \n    /* null terminate string */\n    string[8] = 0;   \n\n    /* loop over nibbles */\n    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; \n    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; \n    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; \n    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; \n    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; \n    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; \n    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; \n    *str-- = nibble_to_hex_char(tmp & 0xf);   \n\n    /* now print stream */\n    fprintf(stream, string);\n  }\n  \n  return 0;\n\n}\n\n\nint\nhex_string_length(char *s) {\n  int count = 0;\n  \n  /* ignore leading zeros */\n  while ((*s != 0) && *s == '0')\n    s++;\n\n  /* count remaining characters */\n  while (*s != 0) {\n    if (hex_char_to_nibble(*s++) == -1)\n      return -1;\n    count++;\n  }\n\n  return count;\n}\n\nint\nbitvector_set_from_hex(bitvector_t *v, char *string) {\n  int num_hex_chars, m, n, i, j;\n  uint32_t tmp;\n  \n  num_hex_chars = hex_string_length(string);\n  if (num_hex_chars == -1)\n    return -1;\n\n  /* set length */\n  v->length = num_hex_chars * 4;\n  /* \n   * at this point, we should subtract away a bit if the high\n   * bit of the first character is zero, but we ignore that \n   * for now and assume that we're four-bit aligned - DAM\n   */\n\n  \n  m = num_hex_chars / 8;   /* number of words                */\n  n = num_hex_chars % 8;   /* number of nibbles in last word */\n\n  /* if the length is greater than the bitvector, return an error */\n  if (m > BITVECTOR_MAX_WORDS)\n    return -1;\n\n  /* \n   * loop over words from most significant - first word is a special\n   * case \n   */\n  \n  if (n) {\n    tmp = 0;\n    for (i=0; i < n; i++) {\n      tmp = hex_char_to_nibble(*string++); \n      tmp <<= 4;  \n    }\n    v->word[m] = tmp;\n  }\n\n  /* now loop over the rest of the words */\n  for (i=m-1; i >= 0; i--) {\n     tmp = 0;\n     for (j=0; j < 8; j++) {\n       tmp = hex_char_to_nibble(*string++); \n       tmp <<= 4;  \n     }\n     v->word[i] = tmp;\n  }\n\n  return 0;\n}\n\n\n/* functions below not yet tested! */\n\nint\nv32_low_bit(v32_t *w) {\n  int value;\n\n  value = low_bit[w->v8[0]];\n  if (value != -1)\n    return value;\n  value = low_bit[w->v8[1]];\n  if (value != -1)\n    return value + 8;\n  value = low_bit[w->v8[2]];\n  if (value != -1)\n    return value + 16;\n  value = low_bit[w->v8[3]];\n  if (value == -1)\n    return -1;\n  return value + 24;\n}\n\n/* high_bit not done yet */\n\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/math/stat.c",
    "content": "/*\n * stats.c\n *\n * statistical tests for randomness (FIPS 140-2, Section 4.9)\n * \n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n#include \"stat.h\"\n\ndebug_module_t mod_stat = {\n  0,                 /* debugging is off by default */\n  (char *)\"stat test\"        /* printable module name       */\n};\n\n/*\n * each test assumes that 20,000 bits (2500 octets) of data is\n * provided as input\n */\n\n#define STAT_TEST_DATA_LEN 2500\n\nerr_status_t\nstat_test_monobit(uint8_t *data) {\n  uint8_t *data_end = data + STAT_TEST_DATA_LEN;\n  uint16_t ones_count;\n\n  ones_count = 0;\n  while (data < data_end) {\n    ones_count += octet_get_weight(*data);\n    data++;\n  }\n\n  debug_print(mod_stat, \"bit count: %d\", ones_count);\n  \n  if ((ones_count < 9725) || (ones_count > 10275))\n    return err_status_algo_fail;\n\n  return err_status_ok;\n}\n\nerr_status_t\nstat_test_poker(uint8_t *data) {\n  int i;\n  uint8_t *data_end = data + STAT_TEST_DATA_LEN;\n  double poker;\n  uint16_t f[16] = {\n    0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0\n  };\n  \n  while (data < data_end) {\n    f[*data & 0x0f]++;    /* increment freq. count for low nibble  */\n    f[(*data) >> 4]++;    /* increment freq. count for high nibble */\n    data++;\n  }\n\n  poker = 0.0;\n  for (i=0; i < 16; i++) \n    poker += (double) f[i] * f[i];\n\n  poker *= (16.0 / 5000.0);\n  poker -= 5000.0;\n\n  debug_print(mod_stat, \"poker test: %f\\n\", poker);\n    \n  if ((poker < 2.16) || (poker > 46.17))\n    return err_status_algo_fail;\n  \n  return err_status_ok;\n}\n\n\n/*\n * runs[i] holds the number of runs of size (i-1)\n */\n\nerr_status_t\nstat_test_runs(uint8_t *data) {\n  uint8_t *data_end = data + STAT_TEST_DATA_LEN;\n  uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 }; \n  uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 };\n  uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 };\n  uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 };\n  int state = 0;\n  uint16_t mask;\n  int i;\n  \n  /*\n   * the state variable holds the number of bits in the\n   * current run (or gap, if negative)\n   */\n  \n  while (data < data_end) {\n\n    /* loop over the bits of this byte */\n    for (mask = 1; mask < 256; mask <<= 1) {\n      if (*data & mask) {\n\n \t/* next bit is a one  */\n\tif (state > 0) {\n\n\t  /* prefix is a run, so increment the run-count  */\n\t  state++;                          \n\n\t  /* check for long runs */ \n\t  if (state > 25) {\n\t\tdebug_print(mod_stat, \">25 runs: %d\", state);\n\t\treturn err_status_algo_fail;\n\t  }\n\n\t} else if (state < 0) {\n\n\t  /* prefix is a gap  */\n\t  if (state < -25) {\n\t\tdebug_print(mod_stat, \">25 gaps: %d\", state);\n\t    return err_status_algo_fail;    /* long-runs test failed   */\n\t  }\n\t  if (state < -6) {\n\t    state = -6;                     /* group together gaps > 5 */\n\t  }\n\t  gaps[-1-state]++;                 /* increment gap count      */\n          state = 1;                        /* set state at one set bit */\n\t} else {\n\n\t  /* state is zero; this happens only at initialization        */\n\t  state = 1;            \n\t}\n      } else {\n\n\t/* next bit is a zero  */\n\tif (state > 0) {\n\n\t  /* prefix is a run */\n\t  if (state > 25) {\n\t\tdebug_print(mod_stat, \">25 runs (2): %d\", state);\n\t    return err_status_algo_fail;    /* long-runs test failed   */\n\t  }\n\t  if (state > 6) {\n\t    state = 6;                      /* group together runs > 5 */\n\t  }\n\t  runs[state-1]++;                  /* increment run count       */\n          state = -1;                       /* set state at one zero bit */\n\t} else if (state < 0) {\n\n\t  /* prefix is a gap, so increment gap-count (decrement state) */\n\t  state--;\n\n\t  /* check for long gaps */ \n\t  if (state < -25) {\n\t\tdebug_print(mod_stat, \">25 gaps (2): %d\", state);\n\t    return err_status_algo_fail;\n\t  }\n\n\t} else {\n\n\t  /* state is zero; this happens only at initialization        */\n\t  state = -1;\n\t}\n      }\n    }\n\n    /* move along to next octet */\n    data++;\n  }\n\n  if (mod_stat.on) {\n    debug_print(mod_stat, \"runs test\", NULL);\n    for (i=0; i < 6; i++)\n      debug_print(mod_stat, \"  runs[]: %d\", runs[i]);\n    for (i=0; i < 6; i++)\n      debug_print(mod_stat, \"  gaps[]: %d\", gaps[i]);\n  }\n\n  /* check run and gap counts against the fixed limits */\n  for (i=0; i < 6; i++) \n    if (   (runs[i] < lo_value[i] ) || (runs[i] > hi_value[i])\n\t|| (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i]))\n      return err_status_algo_fail;\n\n  \n  return err_status_ok;\n}\n\n\n/*\n * the function stat_test_rand_source applys the FIPS-140-2 statistical\n * tests to the random source defined by rs\n *\n */\n\n#define RAND_SRC_BUF_OCTETS 50 /* this value MUST divide 2500! */ \n\nerr_status_t\nstat_test_rand_source(rand_source_func_t get_rand_bytes) {\n  int i;\n  double poker;\n  uint8_t *data, *data_end;\n  uint16_t f[16] = {\n    0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0\n  };\n  uint8_t buffer[RAND_SRC_BUF_OCTETS];\n  err_status_t status;\n  int ones_count = 0;\n  uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 }; \n  uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 };\n  uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 };\n  uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 };\n  int state = 0;\n  uint16_t mask;\n  \n  /* counters for monobit, poker, and runs tests are initialized above */\n\n  /* main loop: fill buffer, update counters for stat tests */\n  for (i=0; i < 2500; i+=RAND_SRC_BUF_OCTETS) {\n    \n    /* fill data buffer */\n    status = get_rand_bytes(buffer, RAND_SRC_BUF_OCTETS);\n    if (status) {\n\t  debug_print(mod_stat, \"couldn't get rand bytes: %d\",status);\n      return status;\n\t}\n\n#if 0\n    debug_print(mod_stat, \"%s\", \n\t\toctet_string_hex_string(buffer, RAND_SRC_BUF_OCTETS));\n#endif\n  \n    data = buffer;\n    data_end = data + RAND_SRC_BUF_OCTETS;\n    while (data < data_end) {\n\n      /* update monobit test counter */\n      ones_count += octet_get_weight(*data);\n\n      /* update poker test counters */\n      f[*data & 0x0f]++;    /* increment freq. count for low nibble  */\n      f[(*data) >> 4]++;    /* increment freq. count for high nibble */\n\n      /* update runs test counters */\n      /* loop over the bits of this byte */\n      for (mask = 1; mask < 256; mask <<= 1) {\n\tif (*data & mask) {\n\t  \n\t  /* next bit is a one  */\n\t  if (state > 0) {\n\t    \n\t    /* prefix is a run, so increment the run-count  */\n\t    state++;                          \n\t    \n\t    /* check for long runs */ \n\t    if (state > 25) {\n\t\t  debug_print(mod_stat, \">25 runs (3): %d\", state);\n\t      return err_status_algo_fail;\n\t\t}\n\t    \n\t  } else if (state < 0) {\n\t    \n\t    /* prefix is a gap  */\n\t    if (state < -25) {\n\t\t  debug_print(mod_stat, \">25 gaps (3): %d\", state);\n\t      return err_status_algo_fail;    /* long-runs test failed   */\n\t    }\n\t    if (state < -6) {\n\t      state = -6;                     /* group together gaps > 5 */\n\t    }\n\t    gaps[-1-state]++;                 /* increment gap count      */\n\t    state = 1;                        /* set state at one set bit */\n\t  } else {\n\t    \n\t    /* state is zero; this happens only at initialization        */\n\t    state = 1;            \n\t  }\n\t} else {\n\t  \n\t  /* next bit is a zero  */\n\t  if (state > 0) {\n\t    \n\t    /* prefix is a run */\n\t    if (state > 25) {\n\t\t  debug_print(mod_stat, \">25 runs (4): %d\", state);\n\t      return err_status_algo_fail;    /* long-runs test failed   */\n\t    }\n\t    if (state > 6) {\n\t      state = 6;                      /* group together runs > 5 */\n\t    }\n\t    runs[state-1]++;                  /* increment run count       */\n\t    state = -1;                       /* set state at one zero bit */\n\t  } else if (state < 0) {\n\t    \n\t    /* prefix is a gap, so increment gap-count (decrement state) */\n\t    state--;\n\t    \n\t    /* check for long gaps */ \n\t    if (state < -25) {\n\t\t  debug_print(mod_stat, \">25 gaps (4): %d\", state);\n\t      return err_status_algo_fail;\n\t\t}\n\t    \n\t  } else {\n\t    \n\t    /* state is zero; this happens only at initialization        */\n\t    state = -1;\n\t  }\n\t}\n      }\n      \n      /* advance data pointer */\n      data++;\n    }\n  }\n\n  /* check to see if test data is within bounds */\n\n  /* check monobit test data */\n\n  debug_print(mod_stat, \"stat: bit count: %d\", ones_count);\n  \n  if ((ones_count < 9725) || (ones_count > 10275)) {\n    debug_print(mod_stat, \"stat: failed monobit test %d\", ones_count);\n    return err_status_algo_fail;\n  }\n  \n  /* check poker test data */\n  poker = 0.0;\n  for (i=0; i < 16; i++) \n    poker += (double) f[i] * f[i];\n\n  poker *= (16.0 / 5000.0);\n  poker -= 5000.0;\n\n  debug_print(mod_stat, \"stat: poker test: %f\", poker);\n    \n  if ((poker < 2.16) || (poker > 46.17)) {\n    debug_print(mod_stat, \"stat: failed poker test\", NULL);\n    return err_status_algo_fail;\n  }\n\n  /* check run and gap counts against the fixed limits */\n  for (i=0; i < 6; i++) \n    if ((runs[i] < lo_value[i] ) || (runs[i] > hi_value[i])\n\t || (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i])) {\n      debug_print(mod_stat, \"stat: failed run/gap test\", NULL);\n      return err_status_algo_fail; \n    }\n\n  debug_print(mod_stat, \"passed random stat test\", NULL);\n  return err_status_ok;\n}\n\nerr_status_t\nstat_test_rand_source_with_repetition(rand_source_func_t source, unsigned num_trials) {\n  unsigned int i;\n  err_status_t err = err_status_algo_fail;\n\n  for (i=0; i < num_trials; i++) {\n    err = stat_test_rand_source(source);\n    if (err == err_status_ok) {\n      return err_status_ok;  \n    }\n    debug_print(mod_stat, \"failed stat test (try number %d)\\n\", i);\n  }\n  \n  return err;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/replay/rdb.c",
    "content": "/*\n * rdb.c\n *\n * Implements a replay database for packet security\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#include \"rdb.h\"\n\n\n/*\n * this implementation of a replay database works as follows:\n * \n * window_start is the index of the first packet in the window\n * bitmask      a bit-buffer, containing the most recently entered\n *              index as the leftmost bit \n *\n */\n\n/* rdb_init initalizes rdb */\n\nerr_status_t\nrdb_init(rdb_t *rdb) {\n  v128_set_to_zero(&rdb->bitmask);\n  rdb->window_start = 0;\n  return err_status_ok;\n}\n\n/*\n * rdb_check checks to see if index appears in rdb\n */\n\nerr_status_t\nrdb_check(const rdb_t *rdb, uint32_t index) {\n  \n  /* if the index appears after (or at very end of) the window, its good */\n  if (index >= rdb->window_start + rdb_bits_in_bitmask)\n    return err_status_ok;\n  \n  /* if the index appears before the window, its bad */\n  if (index < rdb->window_start)\n    return err_status_replay_old;\n\n  /* otherwise, the index appears within the window, so check the bitmask */\n  if (v128_get_bit(&rdb->bitmask, (index - rdb->window_start)) == 1)\n    return err_status_replay_fail;    \n      \n  /* otherwise, the index is okay */\n  return err_status_ok;\n}\n\n/*\n * rdb_add_index adds index to rdb_t (and does *not* check if\n * index appears in db)\n *\n * this function should be called only after rdb_check has\n * indicated that the index does not appear in the rdb, e.g., a mutex\n * should protect the rdb between these calls\n */\n\nerr_status_t\nrdb_add_index(rdb_t *rdb, uint32_t index) {\n  int delta;  \n\n  /* here we *assume* that index > rdb->window_start */\n\n  delta = (index - rdb->window_start);    \n  if (delta < rdb_bits_in_bitmask) {\n\n    /* if the index is within the window, set the appropriate bit */\n    v128_set_bit(&rdb->bitmask, delta);\n\n  } else { \n    \n    delta -= rdb_bits_in_bitmask - 1;\n\n    /* shift the window forward by delta bits*/\n    v128_left_shift(&rdb->bitmask, delta);\n    v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask-1);\n    rdb->window_start += delta;\n\n  }    \n\n  return err_status_ok;\n}\n\nerr_status_t\nrdb_increment(rdb_t *rdb) {\n\n  if (rdb->window_start++ > 0x7fffffff)\n    return err_status_key_expired;\n  return err_status_ok;\n}\n\nuint32_t\nrdb_get_value(const rdb_t *rdb) {\n  return rdb->window_start;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/replay/rdbx.c",
    "content": "/*\n * rdbx.c\n *\n * a replay database with extended range, using a rollover counter\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#include \"rdbx.h\"\n\n#define rdbx_high_bit_in_bitmask 127\n\n/*\n * from draft-ietf-avt-srtp-00.txt:\n *\n * A receiver reconstructs the index i of a packet with sequence\n *  number s using the estimate\n *\n * i = 65,536 * t + s,\n *\n * where t is chosen from the set { r-1, r, r+1 } such that i is\n * closest to the value 65,536 * r + s_l.  If the value r+1 is used,\n * then the rollover counter r in the cryptographic context is\n * incremented by one (if the packet containing s is authentic).\n */\n\n\n\n/*\n * rdbx implementation notes\n *\n * A xtd_seq_num_t is essentially a sequence number for which some of\n * the data on the wire are implicit.  It logically consists of a\n * rollover counter and a sequence number; the sequence number is the\n * explicit part, and the rollover counter is the implicit part.\n *\n * Upon receiving a sequence_number (e.g. in a newly received SRTP\n * packet), the complete xtd_seq_num_t can be estimated by using a\n * local xtd_seq_num_t as a basis.  This is done using the function\n * index_guess(&local, &guess, seq_from_packet).  This function\n * returns the difference of the guess and the local value.  The local\n * xtd_seq_num_t can be moved forward to the guess using the function\n * index_advance(&guess, delta), where delta is the difference.\n * \n *\n * A rdbx_t consists of a xtd_seq_num_t and a bitmask.  The index is highest\n * sequence number that has been received, and the bitmask indicates\n * which of the recent indicies have been received as well.  The\n * highest bit in the bitmask corresponds to the index in the bitmask.\n */\n\n\nvoid\nindex_init(xtd_seq_num_t *pi) {\n#ifdef NO_64BIT_MATH\n  *pi = make64(0,0);\n#else\n  *pi = 0;\n#endif\n}\n\nvoid\nindex_advance(xtd_seq_num_t *pi, sequence_number_t s) {\n#ifdef NO_64BIT_MATH\n  /* a > ~b means a+b will generate a carry */\n  /* s is uint16 here */\n  *pi = make64(high32(*pi) + (s > ~low32(*pi) ? 1 : 0),low32(*pi) + s);\n#else\n  *pi += s;\n#endif\n}\n\n\n/*\n * index_guess(local, guess, s)\n * \n * given a xtd_seq_num_t local (which represents the last\n * known-to-be-good received xtd_seq_num_t) and a sequence number s\n * (from a newly arrived packet), sets the contents of *guess to\n * contain the best guess of the packet index to which s corresponds,\n * and returns the difference between *guess and *local\n *\n * nota bene - the output is a signed integer, DON'T cast it to a\n * unsigned integer!  \n */\n\nint\nindex_guess(const xtd_seq_num_t *local,\n\t\t   xtd_seq_num_t *guess,\n\t\t   sequence_number_t s) {\n#ifdef NO_64BIT_MATH\n  uint32_t local_roc = ((high32(*local) << 16) |\n\t\t\t\t\t\t(low32(*local) >> 16));\n  uint16_t local_seq = (uint16_t) (low32(*local));\n#else\n  uint32_t local_roc = (uint32_t)(*local >> 16);\n  uint16_t local_seq = (uint16_t) *local;\n#endif\n#ifdef NO_64BIT_MATH\n  uint32_t guess_roc = ((high32(*guess) << 16) |\n\t\t\t\t\t\t(low32(*guess) >> 16));\n  uint16_t guess_seq = (uint16_t) (low32(*guess));\n#else\n  uint32_t guess_roc = (uint32_t)(*guess >> 16);\n  uint16_t guess_seq = (uint16_t) *guess;  \n#endif\n  int difference;\n  \n  if (local_seq < seq_num_median) {\n    if (s - local_seq > seq_num_median) {\n      guess_roc = local_roc - 1;\n      difference = seq_num_max - s + local_seq;\n    } else {\n      guess_roc = local_roc;\n      difference = s - local_seq;\n    }\n  } else {\n    if (local_seq - seq_num_median > s) {\n      guess_roc = local_roc+1;\n      difference = seq_num_max - local_seq + s;\n    } else {\n      difference = s - local_seq;\n      guess_roc = local_roc;\n    }\n  }\n  guess_seq = s;\n  \n  /* Note: guess_roc is 32 bits, so this generates a 48-bit result! */\n#ifdef NO_64BIT_MATH\n  *guess = make64(guess_roc >> 16,\n\t\t\t\t  (guess_roc << 16) | guess_seq);\n#else\n  *guess = (((uint64_t) guess_roc) << 16) | guess_seq;\n#endif\n\n  return difference;\n}\n\n/*\n * rdbx\n *\n */\n\n\n/*\n *  rdbx_init(&r) initalizes the rdbx_t pointed to by r \n */\n\nerr_status_t\nrdbx_init(rdbx_t *rdbx) {\n  v128_set_to_zero(&rdbx->bitmask);\n  index_init(&rdbx->index);\n\n  return err_status_ok;\n}\n\n\n/*\n * rdbx_check(&r, delta) checks to see if the xtd_seq_num_t\n * which is at rdbx->index + delta is in the rdb\n */\n\nerr_status_t\nrdbx_check(const rdbx_t *rdbx, int delta) {\n  \n  if (delta > 0) {       /* if delta is positive, it's good */\n    return err_status_ok;\n  } else if (rdbx_high_bit_in_bitmask + delta < 0) {   \n                         /* if delta is lower than the bitmask, it's bad */\n    return err_status_replay_old; \n  } else if (v128_get_bit(&rdbx->bitmask, \n\t\t\t  rdbx_high_bit_in_bitmask + delta) == 1) {\n                         /* delta is within the window, so check the bitmask */\n    return err_status_replay_fail;    \n  }\n /* otherwise, the index is okay */\n\n  return err_status_ok; \n}\n\n/*\n * rdbx_add_index adds the xtd_seq_num_t at rdbx->window_start + d to\n * replay_db (and does *not* check if that xtd_seq_num_t appears in db)\n *\n * this function should be called only after replay_check has\n * indicated that the index does not appear in the rdbx, e.g., a mutex\n * should protect the rdbx between these calls if need be\n */\n\nerr_status_t\nrdbx_add_index(rdbx_t *rdbx, int delta) {\n  \n  if (delta > 0) {\n    /* shift forward by delta */\n    index_advance(&rdbx->index, delta);\n    v128_left_shift(&rdbx->bitmask, delta);\n    v128_set_bit(&rdbx->bitmask, 127);\n  } else {\n    /* delta is in window, so flip bit in bitmask */\n    v128_set_bit(&rdbx->bitmask, -delta);\n  }\n\n  /* note that we need not consider the case that delta == 0 */\n  \n  return err_status_ok;\n}\n\n\n\n/*\n * rdbx_estimate_index(rdbx, guess, s)\n * \n * given an rdbx and a sequence number s (from a newly arrived packet),\n * sets the contents of *guess to contain the best guess of the packet\n * index to which s corresponds, and returns the difference between\n * *guess and the locally stored synch info\n */\n\nint\nrdbx_estimate_index(const rdbx_t *rdbx,\n\t\t    xtd_seq_num_t *guess,\n\t\t    sequence_number_t s) {\n\n  /*\n   * if the sequence number and rollover counter in the rdbx are\n   * non-zero, then use the index_guess(...) function, otherwise, just\n   * set the rollover counter to zero (since the index_guess(...)\n   * function might incorrectly guess that the rollover counter is\n   * 0xffffffff)\n   */\n\n#ifdef NO_64BIT_MATH\n  /* seq_num_median = 0x8000 */\n  if (high32(rdbx->index) > 0 ||\n\t  low32(rdbx->index) > seq_num_median)\n#else\n  if (rdbx->index > seq_num_median)\n#endif\n    return index_guess(&rdbx->index, guess, s);\n  \n#ifdef NO_64BIT_MATH\n  *guess = make64(0,(uint32_t) s);\n#else  \n  *guess = s;\n#endif\n\n#ifdef NO_64BIT_MATH\n  return s - (uint16_t) low32(rdbx->index);\n#else\n  return s - (uint16_t) rdbx->index;\n#endif\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/replay/ut_sim.c",
    "content": "/*\n * ut_sim.c\n *\n * an unreliable transport simulator\n * (for testing replay databases and suchlike)\n * \n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#include \"ut_sim.h\"\n\n\nint\nut_compar(const void *a, const void *b) {\n  return rand() > (RAND_MAX/2) ? -1 : 1;\n}\n\nvoid\nut_init(ut_connection *utc) {\n  int i;\n  utc->index = 0;\n\n  for (i=0; i < UT_BUF; i++)\n    utc->buffer[i] = i;\n  \n  qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar);\n\n  utc->index = UT_BUF - 1;\n}\n\nuint32_t\nut_next_index(ut_connection *utc) {\n  uint32_t tmp;\n\n  tmp = utc->buffer[0];\n  utc->index++;\n  utc->buffer[0] = utc->index;\n\n  qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar);\n  \n  return tmp;\n}\n\n\n\n#ifdef UT_TEST\n\n#include <stdio.h>\n\nint\nmain() {\n  uint32_t i, irecvd, idiff;\n  ut_connection utc;\n\n  ut_init(&utc);\n\n  for (i=0; i < 1000; i++) {\n    irecvd = ut_next_index(&utc);\n    idiff = i - irecvd;\n    printf(\"%lu\\t%lu\\t%d\\n\", i, irecvd, idiff);\n  }\n  \n  return 0;\n}\n\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/rng/ctr_prng.c",
    "content": "/*\n * ctr_prng.c \n *\n * counter mode based pseudorandom source\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright(c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#include \"prng.h\"\n\n/* single, global prng structure */\n\nctr_prng_t ctr_prng;\n\nerr_status_t\nctr_prng_init(rand_source_func_t random_source) {\n  uint8_t tmp_key[32];\n  err_status_t status;\n\n  /* initialize output count to zero */\n  ctr_prng.octet_count = 0;\n\n  /* set random source */\n  ctr_prng.rand = random_source;\n  \n  /* initialize secret key from random source */\n  status = random_source(tmp_key, 32);\n  if (status) \n    return status;\n\n  /* initialize aes ctr context with random key */\n  status = aes_icm_context_init(&ctr_prng.state, tmp_key);\n  if (status) \n    return status;\n\n  return err_status_ok;\n}\n\nerr_status_t\nctr_prng_get_octet_string(void *dest, uint32_t len) {\n  err_status_t status;\n\n  /* \n   * if we need to re-initialize the prng, do so now \n   *\n   * avoid 32-bit overflows by subtracting instead of adding\n   */\n  if (ctr_prng.octet_count > MAX_PRNG_OUT_LEN - len) {\n    status = ctr_prng_init(ctr_prng.rand);    \n    if (status)\n      return status;\n  }\n  ctr_prng.octet_count += len;\n\n  /*\n   * write prng output \n   */\n  status = aes_icm_output(&ctr_prng.state, (uint8_t*)dest, len);\n  if (status)\n    return status;\n  \n  return err_status_ok;\n}\n\nerr_status_t\nctr_prng_deinit(void) {\n\n  /* nothing */\n  \n  return err_status_ok;  \n}\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/rng/prng.c",
    "content": "/*\n * prng.c \n *\n * pseudorandom source\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright(c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#include \"prng.h\"\n\n/* single, global prng structure */\n\nx917_prng_t x917_prng;\n\nerr_status_t\nx917_prng_init(rand_source_func_t random_source) {\n  v128_t tmp_key;\n  err_status_t status;\n\n  /* initialize output count to zero */\n  x917_prng.octet_count = 0;\n\n  /* set random source */\n  x917_prng.rand = random_source;\n  \n  /* initialize secret key from random source */\n  status = random_source((uint8_t *)&tmp_key, 16);\n  if (status) \n    return status;\n\n  /* expand aes key */\n  aes_expand_encryption_key(&tmp_key, x917_prng.key);\n\n  /* initialize prng state from random source */\n  status = x917_prng.rand((uint8_t *)&x917_prng.state, 16);\n  if (status) \n    return status;\n\n  return err_status_ok;\n}\n\nerr_status_t\nx917_prng_get_octet_string(uint8_t *dest, uint32_t len) {\n  uint32_t t;\n  v128_t buffer;\n  uint32_t i, tail_len;\n  err_status_t status;\n\n  /* \n   * if we need to re-initialize the prng, do so now \n   *\n   * avoid overflows by subtracting instead of adding\n   */\n  if (x917_prng.octet_count > MAX_PRNG_OUT_LEN - len) {\n    status = x917_prng_init(x917_prng.rand);    \n    if (status)\n      return status;\n  }\n  x917_prng.octet_count += len;\n  \n  /* find out the time */\n  t = (uint32_t)time(NULL);\n  \n  /* loop until we have output enough data */\n  for (i=0; i < len/16; i++) {\n    \n    /* exor time into state */\n    x917_prng.state.v32[0] ^= t; \n \n    /* copy state into buffer */\n    v128_copy(&buffer, &x917_prng.state);\n\n    /* apply aes to buffer */\n    aes_encrypt(&buffer, x917_prng.key);\n    \n    /* write data to output */\n    *dest++ = buffer.v8[0];\n    *dest++ = buffer.v8[1];\n    *dest++ = buffer.v8[2];\n    *dest++ = buffer.v8[3];\n    *dest++ = buffer.v8[4];\n    *dest++ = buffer.v8[5];\n    *dest++ = buffer.v8[6];\n    *dest++ = buffer.v8[7];\n    *dest++ = buffer.v8[8];\n    *dest++ = buffer.v8[9];\n    *dest++ = buffer.v8[10];\n    *dest++ = buffer.v8[11];\n    *dest++ = buffer.v8[12];\n    *dest++ = buffer.v8[13];\n    *dest++ = buffer.v8[14];\n    *dest++ = buffer.v8[15];\n\n    /* exor time into buffer */\n    buffer.v32[0] ^= t;\n\n    /* encrypt buffer */\n    aes_encrypt(&buffer, x917_prng.key);\n\n    /* copy buffer into state */\n    v128_copy(&x917_prng.state, &buffer);\n    \n  }\n  \n  /* if we need to output any more octets, we'll do so now */\n  tail_len = len % 16;\n  if (tail_len) {\n    \n    /* exor time into state */\n    x917_prng.state.v32[0] ^= t; \n \n    /* copy value into buffer */\n    v128_copy(&buffer, &x917_prng.state);\n\n    /* apply aes to buffer */\n    aes_encrypt(&buffer, x917_prng.key);\n\n    /* write data to output */\n    for (i=0; i < tail_len; i++) {\n      *dest++ = buffer.v8[i];\n    }\n\n    /* now update the state one more time */\n\n    /* exor time into buffer */\n    buffer.v32[0] ^= t;\n\n    /* encrypt buffer */\n    aes_encrypt(&buffer, x917_prng.key);\n\n    /* copy buffer into state */\n    v128_copy(&x917_prng.state, &buffer);\n\n  }\n  \n  return err_status_ok;\n}\n\nerr_status_t\nx917_prng_deinit(void) {\n  \n  return err_status_ok;  \n}\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/rng/rand_linux_kernel.c",
    "content": "/*\n * rand_linux_kernel.c\n *\n * implements a random source using Linux kernel functions\n *\n * Marcus Sundberg\n * Ingate Systems AB\n */\n/*\n *\t\n * Copyright(c) 2005 Ingate Systems AB\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the author(s) nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#include \"config.h\"\n#include \"rand_source.h\"\n\n\nerr_status_t\nrand_source_init(void) {\n  return err_status_ok;\n}\n\nerr_status_t\nrand_source_get_octet_string(void *dest, uint32_t len) {\n\n  get_random_bytes(dest, len);\n\n  return err_status_ok;\n}\n\nerr_status_t\nrand_source_deinit(void) {\n  return err_status_ok;  \n}\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/crypto/rng/rand_source.c",
    "content": "/*\n * rand_source.c\n *\n * implements a random source based on /dev/random\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright(c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#include \"srtp_config.h\"\n\n#if defined(DEV_URANDOM) || defined(PJ_DEV_URANDOM)\n# include <fcntl.h>          /* for open()  */\n# include <unistd.h>         /* for close() */\n#elif (_MSC_VER >= 1400)\n#define _CRT_RAND_S\n# include <stdlib.h>         \n# include <stdio.h>\n#else\n# include <stdio.h>\n#endif\n\n#include \"rand_source.h\"\n\n\n/* \n * global dev_rand_fdes is file descriptor for /dev/random \n * \n * This variable is also used to indicate that the random source has\n * been initialized.  When this variable is set to the value of the\n * #define RAND_SOURCE_NOT_READY, it indicates that the random source\n * is not ready to be used.  The value of the #define\n * RAND_SOURCE_READY is for use whenever that variable is used as an\n * indicator of the state of the random source, but not as a file\n * descriptor.\n */\n\n#define RAND_SOURCE_NOT_READY (-1)\n#define RAND_SOURCE_READY     (17)\n\nstatic int dev_random_fdes = RAND_SOURCE_NOT_READY;\n\n\nerr_status_t\nrand_source_init(void) {\n  if (dev_random_fdes >= 0) {\n    /* already open */\n    return err_status_ok;\n  }\n#ifdef DEV_URANDOM\n  /* open random source for reading */\n  dev_random_fdes = open(DEV_URANDOM, O_RDONLY);\n  if (dev_random_fdes < 0)\n    return err_status_init_fail;\n#elif defined(PJ_DEV_URANDOM)\n  /* open random source for reading */\n  dev_random_fdes = open(PJ_DEV_URANDOM, O_RDONLY);\n  if (dev_random_fdes < 0) {\n    err_report(3,\"Ugh: /dev/urandom not present, using rand() instead\");\n    return err_status_ok;  /* it's ok, it'll fallback to using rand() */\n  }\n#elif (_MSC_VER >= 1400)\n  dev_random_fdes = RAND_SOURCE_READY;\n#else\n  /* no random source available; let the user know */\r\n  err_report(err_level_info, \"WARNING: no real random source present!\\n\");\n  dev_random_fdes = RAND_SOURCE_READY;\n#endif\n  return err_status_ok;\n}\n\nerr_status_t\nrand_source_get_octet_string(void *dest, uint32_t len) {\n\n  /* \n   * read len octets from /dev/random to dest, and\n   * check return value to make sure enough octets were\n   * written \n   */\n#ifdef DEV_URANDOM\n  if (read(dev_random_fdes, dest, len) != len)\n    return err_status_fail;\n#elif 0 && (_MSC_VER >= 1400) /* disabled rand_s, causing assertion 'rand_s not supported' in vs8 */\n  unsigned int *dst = dest;\n  while (len)\n  {\n      unsigned int val = 0;\n\t  errno_t err = rand_s(&val);\n      if (err != 0)\n\t      {\n              return err_status_fail;\n          }\n  \n      *dst++ = val;\n\t  len--;\n  }\n#else\n  uint8_t *dst = (uint8_t *)dest;\n\r\n#ifdef PJ_DEV_URANDOM\n  /* First try with /dev/urandom, if it's opened */\n  if (dev_random_fdes >= 0) {\n    if (read(dev_random_fdes, dest, len) == len)\n\treturn err_status_ok;\t/* success */\n  }\r\n#endif\n\n  /* Generic C-library (rand()) version */\n  /* This is a random source of last resort */\n  while (len)\n  {\n\t  int val = rand();\n\t  /* rand() returns 0-32767 (ugh) */\n\t  /* Is this a good enough way to get random bytes?\n\t     It is if it passes FIPS-140... */\n\t  *dst++ = val & 0xff;\n\t  len--;\n  }\n#endif\n  return err_status_ok;\n}\n \nerr_status_t\nrand_source_deinit(void) {\n#ifndef PJ_DEV_URANDOM\n  if (dev_random_fdes < 0)\n    return err_status_dealloc_fail;  /* well, we haven't really failed, *\n\t\t\t\t      * but there is something wrong    */\n#endif\n\r\n#if defined(DEV_URANDOM) || defined(PJ_DEV_URANDOM)\n  if (dev_random_fdes >= 0)\n    close(dev_random_fdes);  \n\n  dev_random_fdes = RAND_SOURCE_NOT_READY;\r\n#endif\n  \n  return err_status_ok;  \n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/doc/Doxyfile",
    "content": "# Doxyfile 1.3-rc3\n\n# This file describes the settings to be used by the documentation system\n# doxygen (www.doxygen.org) for a project\n#\n# All text after a hash (#) is considered a comment and will be ignored\n# The format is:\n#       TAG = value [value, ...]\n# For lists items can also be appended using:\n#       TAG += value [value, ...]\n# Values that contain spaces should be placed between quotes (\" \")\n\n#---------------------------------------------------------------------------\n# General configuration options\n#---------------------------------------------------------------------------\n\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded \n# by quotes) that should identify the project.\n\nPROJECT_NAME           = libSRTP\n\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. \n# This could be handy for archiving the generated documentation or \n# if some version control system is used.\n\nPROJECT_NUMBER         = 1.3.22\n\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) \n# base path where the generated documentation will be put. \n# If a relative path is entered, it will be relative to the location \n# where doxygen was started. If left blank the current directory will be used.\n\nOUTPUT_DIRECTORY       = \n\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all \n# documentation generated by doxygen is written. Doxygen will use this \n# information to generate all constant output in the proper language. \n# The default language is English, other supported languages are: \n# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, \n# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en \n# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, \n# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian.\n\nOUTPUT_LANGUAGE        = English\n\n# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in \n# documentation are documented, even if no documentation was available. \n# Private class members and static file members will be hidden unless \n# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES\n\nEXTRACT_ALL            = NO\n\n# If the EXTRACT_PRIVATE tag is set to YES all private members of a class \n# will be included in the documentation.\n\nEXTRACT_PRIVATE        = NO\n\n# If the EXTRACT_STATIC tag is set to YES all static members of a file \n# will be included in the documentation.\n\nEXTRACT_STATIC         = NO\n\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) \n# defined locally in source files will be included in the documentation. \n# If set to NO only classes defined in header files are included.\n\nEXTRACT_LOCAL_CLASSES  = YES\n\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all \n# undocumented members of documented classes, files or namespaces. \n# If set to NO (the default) these members will be included in the \n# various overviews, but no documentation section is generated. \n# This option has no effect if EXTRACT_ALL is enabled.\n\nHIDE_UNDOC_MEMBERS     = YES\n\n# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all \n# undocumented classes that are normally visible in the class hierarchy. \n# If set to NO (the default) these class will be included in the various \n# overviews. This option has no effect if EXTRACT_ALL is enabled.\n\nHIDE_UNDOC_CLASSES     = NO\n\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all \n# friend (class|struct|union) declarations. \n# If set to NO (the default) these declarations will be included in the \n# documentation.\n\nHIDE_FRIEND_COMPOUNDS  = NO\n\n# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any \n# documentation blocks found inside the body of a function. \n# If set to NO (the default) these blocks will be appended to the \n# function's detailed documentation block.\n\nHIDE_IN_BODY_DOCS      = NO\n\n# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will \n# include brief member descriptions after the members that are listed in \n# the file and class documentation (similar to JavaDoc). \n# Set to NO to disable this.\n\nBRIEF_MEMBER_DESC      = YES\n\n# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend \n# the brief description of a member or function before the detailed description. \n# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the \n# brief descriptions will be completely suppressed.\n\nREPEAT_BRIEF           = NO\n\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then \n# Doxygen will generate a detailed section even if there is only a brief \n# description.\n\nALWAYS_DETAILED_SEC    = NO\n\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show\n# all inherited members of a class in the documentation of that class\n# as if those members were ordinary class members. Constructors,\n# destructors and assignment operators of the base classes will not be\n# shown.\n\nINLINE_INHERITED_MEMB  = NO\n\n# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full \n# path before files name in the file list and in the header files. If set \n# to NO the shortest path that makes the file name unique will be used.\n\nFULL_PATH_NAMES        = NO\n\n# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag \n# can be used to strip a user defined part of the path. Stripping is \n# only done if one of the specified strings matches the left-hand part of \n# the path. It is allowed to use relative paths in the argument list.\n\nSTRIP_FROM_PATH        = \n\n# The INTERNAL_DOCS tag determines if documentation \n# that is typed after a \\internal command is included. If the tag is set \n# to NO (the default) then the documentation will be excluded. \n# Set it to YES to include the internal documentation.\n\nINTERNAL_DOCS          = NO\n\n# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate \n# file names in lower case letters. If set to YES upper case letters are also \n# allowed. This is useful if you have classes or files whose names only differ \n# in case and if your file system supports case sensitive file names. Windows \n# users are adviced to set this option to NO.\n\nCASE_SENSE_NAMES       = YES\n\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter \n# (but less readable) file names. This can be useful is your file systems \n# doesn't support long names like on DOS, Mac, or CD-ROM.\n\nSHORT_NAMES            = NO\n\n# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen \n# will show members with their full class and namespace scopes in the \n# documentation. If set to YES the scope will be hidden.\n\nHIDE_SCOPE_NAMES       = NO\n\n# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen \n# will generate a verbatim copy of the header file for each class for \n# which an include is specified. Set to NO to disable this.\n\nVERBATIM_HEADERS       = YES\n\n# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen \n# will put list of the files that are included by a file in the documentation \n# of that file.\n\nSHOW_INCLUDE_FILES     = NO\n\n# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen \n# will interpret the first line (until the first dot) of a JavaDoc-style \n# comment as the brief description. If set to NO, the JavaDoc \n# comments  will behave just like the Qt-style comments (thus requiring an \n# explict @brief command for a brief description.\n\nJAVADOC_AUTOBRIEF      = NO\n\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen \n# treat a multi-line C++ special comment block (i.e. a block of //! or /// \n# comments) as a brief description. This used to be the default behaviour. \n# The new default is to treat a multi-line C++ comment block as a detailed \n# description. Set this tag to YES if you prefer the old behaviour instead.\n\nMULTILINE_CPP_IS_BRIEF = NO\n\n# If the DETAILS_AT_TOP tag is set to YES then Doxygen \n# will output the detailed description near the top, like JavaDoc.\n# If set to NO, the detailed description appears after the member \n# documentation.\n\nDETAILS_AT_TOP         = NO\n\n# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented \n# member inherits the documentation from any documented member that it \n# reimplements.\n\nINHERIT_DOCS           = YES\n\n# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] \n# is inserted in the documentation for inline members.\n\nINLINE_INFO            = YES\n\n# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen \n# will sort the (detailed) documentation of file and class members \n# alphabetically by member name. If set to NO the members will appear in \n# declaration order.\n\nSORT_MEMBER_DOCS       = YES\n\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC \n# tag is set to YES, then doxygen will reuse the documentation of the first \n# member in the group (if any) for the other members of the group. By default \n# all members of a group must be documented explicitly.\n\nDISTRIBUTE_GROUP_DOC   = NO\n\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. \n# Doxygen uses this value to replace tabs by spaces in code fragments.\n\nTAB_SIZE               = 3\n\n# The GENERATE_TODOLIST tag can be used to enable (YES) or \n# disable (NO) the todo list. This list is created by putting \\todo \n# commands in the documentation.\n\nGENERATE_TODOLIST      = YES\n\n# The GENERATE_TESTLIST tag can be used to enable (YES) or \n# disable (NO) the test list. This list is created by putting \\test \n# commands in the documentation.\n\nGENERATE_TESTLIST      = YES\n\n# The GENERATE_BUGLIST tag can be used to enable (YES) or \n# disable (NO) the bug list. This list is created by putting \\bug \n# commands in the documentation.\n\nGENERATE_BUGLIST       = YES\n\n# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or \n# disable (NO) the deprecated list. This list is created by putting \n# \\deprecated commands in the documentation.\n\nGENERATE_DEPRECATEDLIST= YES\n\n# This tag can be used to specify a number of aliases that acts \n# as commands in the documentation. An alias has the form \"name=value\". \n# For example adding \"sideeffect=\\par Side Effects:\\n\" will allow you to \n# put the command \\sideeffect (or @sideeffect) in the documentation, which \n# will result in a user defined paragraph with heading \"Side Effects:\". \n# You can put \\n's in the value part of an alias to insert newlines.\n\nALIASES                = \n\n# The ENABLED_SECTIONS tag can be used to enable conditional \n# documentation sections, marked by \\if sectionname ... \\endif.\n\nENABLED_SECTIONS       = \n\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines \n# the initial value of a variable or define consist of for it to appear in \n# the documentation. If the initializer consists of more lines than specified \n# here it will be hidden. Use a value of 0 to hide initializers completely. \n# The appearance of the initializer of individual variables and defines in the \n# documentation can be controlled using \\showinitializer or \\hideinitializer \n# command in the documentation regardless of this setting.\n\nMAX_INITIALIZER_LINES  = 30\n\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources \n# only. Doxygen will then generate output that is more tailored for C. \n# For instance some of the names that are used will be different. The list \n# of all members will be omitted, etc.\n\nOPTIMIZE_OUTPUT_FOR_C  = YES\n\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources \n# only. Doxygen will then generate output that is more tailored for Java. \n# For instance namespaces will be presented as packages, qualified scopes \n# will look different, etc.\n\nOPTIMIZE_OUTPUT_JAVA   = NO\n\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated \n# at the bottom of the documentation of classes and structs. If set to YES the \n# list will mention the files that were used to generate the documentation.\n\nSHOW_USED_FILES        = YES\n\n#---------------------------------------------------------------------------\n# configuration options related to warning and progress messages\n#---------------------------------------------------------------------------\n\n# The QUIET tag can be used to turn on/off the messages that are generated \n# by doxygen. Possible values are YES and NO. If left blank NO is used.\n\nQUIET                  = NO\n\n# The WARNINGS tag can be used to turn on/off the warning messages that are \n# generated by doxygen. Possible values are YES and NO. If left blank \n# NO is used.\n\nWARNINGS               = YES\n\n# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings \n# for undocumented members. If EXTRACT_ALL is set to YES then this flag will \n# automatically be disabled.\n\nWARN_IF_UNDOCUMENTED   = YES\n\n# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for \n# potential errors in the documentation, such as not documenting some \n# parameters in a documented function, or documenting parameters that \n# don't exist or using markup commands wrongly.\n\nWARN_IF_DOC_ERROR      = YES\n\n# The WARN_FORMAT tag determines the format of the warning messages that \n# doxygen can produce. The string should contain the $file, $line, and $text \n# tags, which will be replaced by the file and line number from which the \n# warning originated and the warning text.\n\nWARN_FORMAT            = \"$file:$line: $text\"\n\n# The WARN_LOGFILE tag can be used to specify a file to which warning \n# and error messages should be written. If left blank the output is written \n# to stderr.\n\nWARN_LOGFILE           = \n\n#---------------------------------------------------------------------------\n# configuration options related to the input files\n#---------------------------------------------------------------------------\n\n# The INPUT tag can be used to specify the files and/or directories that contain \n# documented source files. You may enter file names like \"myfile.cpp\" or \n# directories like \"/usr/src/myproject\". Separate the files or directories \n# with spaces.\n\nINPUT                  = intro.txt ../include/srtp.h ../crypto/include/crypto_types.h ../crypto/include/err.h ../crypto/include/crypto.h  crypto_kernel.txt \n\n# If the value of the INPUT tag contains directories, you can use the \n# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \n# and *.h) to filter out the source-files in the directories. If left \n# blank the following patterns are tested: \n# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp \n# *.h++ *.idl *.odl\n\nFILE_PATTERNS          = \n\n# The RECURSIVE tag can be used to turn specify whether or not subdirectories \n# should be searched for input files as well. Possible values are YES and NO. \n# If left blank NO is used.\n\nRECURSIVE              = NO\n\n# The EXCLUDE tag can be used to specify files and/or directories that should \n# excluded from the INPUT source files. This way you can easily exclude a \n# subdirectory from a directory tree whose root is specified with the INPUT tag.\n\nEXCLUDE                = \n\n# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories \n# that are symbolic links (a Unix filesystem feature) are excluded from the input.\n\nEXCLUDE_SYMLINKS       = NO\n\n# If the value of the INPUT tag contains directories, you can use the \n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude \n# certain files from those directories.\n\nEXCLUDE_PATTERNS       = \n\n# The EXAMPLE_PATH tag can be used to specify one or more files or \n# directories that contain example code fragments that are included (see \n# the \\include command).\n\nEXAMPLE_PATH           = \n\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the \n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \n# and *.h) to filter out the source-files in the directories. If left \n# blank all files are included.\n\nEXAMPLE_PATTERNS       = \n\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be \n# searched for input files to be used with the \\include or \\dontinclude \n# commands irrespective of the value of the RECURSIVE tag. \n# Possible values are YES and NO. If left blank NO is used.\n\nEXAMPLE_RECURSIVE      = NO\n\n# The IMAGE_PATH tag can be used to specify one or more files or \n# directories that contain image that are included in the documentation (see \n# the \\image command).\n\nIMAGE_PATH             = \n\n# The INPUT_FILTER tag can be used to specify a program that doxygen should \n# invoke to filter for each input file. Doxygen will invoke the filter program \n# by executing (via popen()) the command <filter> <input-file>, where <filter> \n# is the value of the INPUT_FILTER tag, and <input-file> is the name of an \n# input file. Doxygen will then use the output that the filter program writes \n# to standard output.\n\nINPUT_FILTER           = \n\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using \n# INPUT_FILTER) will be used to filter the input files when producing source \n# files to browse (i.e. when SOURCE_BROWSER is set to YES).\n\nFILTER_SOURCE_FILES    = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to source browsing\n#---------------------------------------------------------------------------\n\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will \n# be generated. Documented entities will be cross-referenced with these sources.\n\nSOURCE_BROWSER         = NO\n\n# Setting the INLINE_SOURCES tag to YES will include the body \n# of functions and classes directly in the documentation.\n\nINLINE_SOURCES         = NO\n\n# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct \n# doxygen to hide any special comment blocks from generated source code \n# fragments. Normal C and C++ comments will always remain visible.\n\nSTRIP_CODE_COMMENTS    = YES\n\n# If the REFERENCED_BY_RELATION tag is set to YES (the default) \n# then for each documented function all documented \n# functions referencing it will be listed.\n\nREFERENCED_BY_RELATION = YES\n\n# If the REFERENCES_RELATION tag is set to YES (the default) \n# then for each documented function all documented entities \n# called/used by that function will be listed.\n\nREFERENCES_RELATION    = YES\n\n#---------------------------------------------------------------------------\n# configuration options related to the alphabetical class index\n#---------------------------------------------------------------------------\n\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index \n# of all compounds will be generated. Enable this if the project \n# contains a lot of classes, structs, unions or interfaces.\n\nALPHABETICAL_INDEX     = NO\n\n# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then \n# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns \n# in which this list will be split (can be a number in the range [1..20])\n\nCOLS_IN_ALPHA_INDEX    = 5\n\n# In case all classes in a project start with a common prefix, all \n# classes will be put under the same header in the alphabetical index. \n# The IGNORE_PREFIX tag can be used to specify one or more prefixes that \n# should be ignored while generating the index headers.\n\nIGNORE_PREFIX          = \n\n#---------------------------------------------------------------------------\n# configuration options related to the HTML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_HTML tag is set to YES (the default) Doxygen will \n# generate HTML output.\n\nGENERATE_HTML          = NO\n\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `html' will be used as the default path.\n\nHTML_OUTPUT            = html\n\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for \n# each generated HTML page (for example: .htm,.php,.asp). If it is left blank \n# doxygen will generate files with .html extension.\n\nHTML_FILE_EXTENSION    = .html\n\n# The HTML_HEADER tag can be used to specify a personal HTML header for \n# each generated HTML page. If it is left blank doxygen will generate a \n# standard header.\n\nHTML_HEADER            = \n\n# The HTML_FOOTER tag can be used to specify a personal HTML footer for \n# each generated HTML page. If it is left blank doxygen will generate a \n# standard footer.\n\nHTML_FOOTER            = \n\n# The HTML_STYLESHEET tag can be used to specify a user defined cascading \n# style sheet that is used by each HTML page. It can be used to \n# fine-tune the look of the HTML output. If the tag is left blank doxygen \n# will generate a default style sheet\n\nHTML_STYLESHEET        = \n\n# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, \n# files or namespaces will be aligned in HTML using tables. If set to \n# NO a bullet list will be used.\n\nHTML_ALIGN_MEMBERS     = YES\n\n# If the GENERATE_HTMLHELP tag is set to YES, additional index files \n# will be generated that can be used as input for tools like the \n# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) \n# of the generated HTML documentation.\n\nGENERATE_HTMLHELP      = NO\n\n# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can \n# be used to specify the file name of the resulting .chm file. You \n# can add a path in front of the file if the result should not be \n# written to the html output dir.\n\nCHM_FILE               = \n\n# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can \n# be used to specify the location (absolute path including file name) of \n# the HTML help compiler (hhc.exe). If non empty doxygen will try to run \n# the html help compiler on the generated index.hhp.\n\nHHC_LOCATION           = \n\n# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag \n# controls if a separate .chi index file is generated (YES) or that \n# it should be included in the master .chm file (NO).\n\nGENERATE_CHI           = NO\n\n# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag \n# controls whether a binary table of contents is generated (YES) or a \n# normal table of contents (NO) in the .chm file.\n\nBINARY_TOC             = NO\n\n# The TOC_EXPAND flag can be set to YES to add extra items for group members \n# to the contents of the Html help documentation and to the tree view.\n\nTOC_EXPAND             = NO\n\n# The DISABLE_INDEX tag can be used to turn on/off the condensed index at \n# top of each HTML page. The value NO (the default) enables the index and \n# the value YES disables it.\n\nDISABLE_INDEX          = NO\n\n# This tag can be used to set the number of enum values (range [1..20]) \n# that doxygen will group on one line in the generated HTML documentation.\n\nENUM_VALUES_PER_LINE   = 4\n\n# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be\n# generated containing a tree-like index structure (just like the one that \n# is generated for HTML Help). For this to work a browser that supports \n# JavaScript, DHTML, CSS and frames is required (for instance Mozilla, \n# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are \n# probably better off using the HTML help feature.\n\nGENERATE_TREEVIEW      = NO\n\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be \n# used to set the initial width (in pixels) of the frame in which the tree \n# is shown.\n\nTREEVIEW_WIDTH         = 250\n\n#---------------------------------------------------------------------------\n# configuration options related to the LaTeX output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will \n# generate Latex output.\n\nGENERATE_LATEX         = YES\n\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `latex' will be used as the default path.\n\nLATEX_OUTPUT           = latex\n\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be \n# invoked. If left blank `latex' will be used as the default command name.\n\nLATEX_CMD_NAME         = latex\n\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to \n# generate index for LaTeX. If left blank `makeindex' will be used as the \n# default command name.\n\nMAKEINDEX_CMD_NAME     = makeindex\n\n# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact \n# LaTeX documents. This may be useful for small projects and may help to \n# save some trees in general.\n\nCOMPACT_LATEX          = NO\n\n# The PAPER_TYPE tag can be used to set the paper type that is used \n# by the printer. Possible values are: a4, a4wide, letter, legal and \n# executive. If left blank a4wide will be used.\n\nPAPER_TYPE             = letter \n\n# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX \n# packages that should be included in the LaTeX output.\n\nEXTRA_PACKAGES         = \n\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for \n# the generated latex document. The header should contain everything until \n# the first chapter. If it is left blank doxygen will generate a \n# standard header. Notice: only use this tag if you know what you are doing!\n\nLATEX_HEADER           = header.tex\n\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated \n# is prepared for conversion to pdf (using ps2pdf). The pdf file will \n# contain links (just like the HTML output) instead of page references \n# This makes the output suitable for online browsing using a pdf viewer.\n\nPDF_HYPERLINKS         = YES\n\n# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of \n# plain latex in the generated Makefile. Set this option to YES to get a \n# higher quality PDF documentation.\n\nUSE_PDFLATEX           = YES\n\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\\\batchmode. \n# command to the generated LaTeX files. This will instruct LaTeX to keep \n# running if errors occur, instead of asking the user for help. \n# This option is also used when generating formulas in HTML.\n\nLATEX_BATCHMODE        = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to the RTF output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output \n# The RTF output is optimised for Word 97 and may not look very pretty with \n# other RTF readers or editors.\n\nGENERATE_RTF           = NO\n\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `rtf' will be used as the default path.\n\nRTF_OUTPUT             = rtf\n\n# If the COMPACT_RTF tag is set to YES Doxygen generates more compact \n# RTF documents. This may be useful for small projects and may help to \n# save some trees in general.\n\nCOMPACT_RTF            = NO\n\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated \n# will contain hyperlink fields. The RTF file will \n# contain links (just like the HTML output) instead of page references. \n# This makes the output suitable for online browsing using WORD or other \n# programs which support those fields. \n# Note: wordpad (write) and others do not support links.\n\nRTF_HYPERLINKS         = NO\n\n# Load stylesheet definitions from file. Syntax is similar to doxygen's \n# config file, i.e. a series of assigments. You only have to provide \n# replacements, missing definitions are set to their default value.\n\nRTF_STYLESHEET_FILE    = \n\n# Set optional variables used in the generation of an rtf document. \n# Syntax is similar to doxygen's config file.\n\nRTF_EXTENSIONS_FILE    = \n\n#---------------------------------------------------------------------------\n# configuration options related to the man page output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_MAN tag is set to YES (the default) Doxygen will \n# generate man pages\n\nGENERATE_MAN           = NO\n\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `man' will be used as the default path.\n\nMAN_OUTPUT             = man\n\n# The MAN_EXTENSION tag determines the extension that is added to \n# the generated man pages (default is the subroutine's section .3)\n\nMAN_EXTENSION          = .3\n\n# If the MAN_LINKS tag is set to YES and Doxygen generates man output, \n# then it will generate one additional man file for each entity \n# documented in the real man page(s). These additional files \n# only source the real man page, but without them the man command \n# would be unable to find the correct page. The default is NO.\n\nMAN_LINKS              = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to the XML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_XML tag is set to YES Doxygen will \n# generate an XML file that captures the structure of \n# the code including all documentation. Note that this \n# feature is still experimental and incomplete at the \n# moment.\n\nGENERATE_XML           = NO\n\n# The XML_SCHEMA tag can be used to specify an XML schema, \n# which can be used by a validating XML parser to check the \n# syntax of the XML files.\n\nXML_SCHEMA             = \n\n# The XML_DTD tag can be used to specify an XML DTD, \n# which can be used by a validating XML parser to check the \n# syntax of the XML files.\n\nXML_DTD                = \n\n#---------------------------------------------------------------------------\n# configuration options for the AutoGen Definitions output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will \n# generate an AutoGen Definitions (see autogen.sf.net) file \n# that captures the structure of the code including all \n# documentation. Note that this feature is still experimental \n# and incomplete at the moment.\n\nGENERATE_AUTOGEN_DEF   = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to the Perl module output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_PERLMOD tag is set to YES Doxygen will \n# generate a Perl module file that captures the structure of \n# the code including all documentation. Note that this \n# feature is still experimental and incomplete at the \n# moment.\n\nGENERATE_PERLMOD       = NO\n\n# If the PERLMOD_LATEX tag is set to YES Doxygen will generate \n# the necessary Makefile rules, Perl scripts and LaTeX code to be able \n# to generate PDF and DVI output from the Perl module output.\n\nPERLMOD_LATEX          = NO\n\n# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be \n# nicely formatted so it can be parsed by a human reader.  This is useful \n# if you want to understand what is going on.  On the other hand, if this \n# tag is set to NO the size of the Perl module output will be much smaller \n# and Perl will parse it just the same.\n\nPERLMOD_PRETTY         = YES\n\n# The names of the make variables in the generated doxyrules.make file \n# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. \n# This is useful so different doxyrules.make files included by the same \n# Makefile don't overwrite each other's variables.\n\nPERLMOD_MAKEVAR_PREFIX = \n\n#---------------------------------------------------------------------------\n# Configuration options related to the preprocessor   \n#---------------------------------------------------------------------------\n\n# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will \n# evaluate all C-preprocessor directives found in the sources and include \n# files.\n\nENABLE_PREPROCESSING   = YES\n\n# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro \n# names in the source code. If set to NO (the default) only conditional \n# compilation will be performed. Macro expansion can be done in a controlled \n# way by setting EXPAND_ONLY_PREDEF to YES.\n\nMACRO_EXPANSION        = NO\n\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES \n# then the macro expansion is limited to the macros specified with the \n# PREDEFINED and EXPAND_AS_PREDEFINED tags.\n\nEXPAND_ONLY_PREDEF     = NO\n\n# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files \n# in the INCLUDE_PATH (see below) will be search if a #include is found.\n\nSEARCH_INCLUDES        = YES\n\n# The INCLUDE_PATH tag can be used to specify one or more directories that \n# contain include files that are not input files but should be processed by \n# the preprocessor.\n\nINCLUDE_PATH           = \n\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard \n# patterns (like *.h and *.hpp) to filter out the header-files in the \n# directories. If left blank, the patterns specified with FILE_PATTERNS will \n# be used.\n\nINCLUDE_FILE_PATTERNS  = \n\n# The PREDEFINED tag can be used to specify one or more macro names that \n# are defined before the preprocessor is started (similar to the -D option of \n# gcc). The argument of the tag is a list of macros of the form: name \n# or name=definition (no spaces). If the definition and the = are \n# omitted =1 is assumed.\n\nPREDEFINED             = \n\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then \n# this tag can be used to specify a list of macro names that should be expanded. \n# The macro definition that is found in the sources will be used. \n# Use the PREDEFINED tag if you want to use a different macro definition.\n\nEXPAND_AS_DEFINED      = \n\n# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then \n# doxygen's preprocessor will remove all function-like macros that are alone \n# on a line, have an all uppercase name, and do not end with a semicolon. Such \n# function macros are typically used for boiler-plate code, and will confuse the \n# parser if not removed.\n\nSKIP_FUNCTION_MACROS   = YES\n\n#---------------------------------------------------------------------------\n# Configuration::addtions related to external references   \n#---------------------------------------------------------------------------\n\n# The TAGFILES tag can be used to specify one or more tagfiles.\n\nTAGFILES               = \n\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create \n# a tag file that is based on the input files it reads.\n\nGENERATE_TAGFILE       = \n\n# If the ALLEXTERNALS tag is set to YES all external classes will be listed \n# in the class index. If set to NO only the inherited external classes \n# will be listed.\n\nALLEXTERNALS           = NO\n\n# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed \n# in the modules index. If set to NO, only the current project's groups will \n# be listed.\n\nEXTERNAL_GROUPS        = YES\n\n# The PERL_PATH should be the absolute path and name of the perl script \n# interpreter (i.e. the result of `which perl').\n\nPERL_PATH              = /usr/bin/perl\n\n#---------------------------------------------------------------------------\n# Configuration options related to the dot tool   \n#---------------------------------------------------------------------------\n\n# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will \n# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or \n# super classes. Setting the tag to NO turns the diagrams off. Note that this \n# option is superceded by the HAVE_DOT option below. This is only a fallback. It is \n# recommended to install and use dot, since it yield more powerful graphs.\n\nCLASS_DIAGRAMS         = YES\n\n# If set to YES, the inheritance and collaboration graphs will hide \n# inheritance and usage relations if the target is undocumented \n# or is not a class.\n\nHIDE_UNDOC_RELATIONS   = YES\n\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is \n# available from the path. This tool is part of Graphviz, a graph visualization \n# toolkit from AT&T and Lucent Bell Labs. The other options in this section \n# have no effect if this option is set to NO (the default)\n\nHAVE_DOT               = NO\n\n# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen \n# will generate a graph for each documented class showing the direct and \n# indirect inheritance relations. Setting this tag to YES will force the \n# the CLASS_DIAGRAMS tag to NO.\n\nCLASS_GRAPH            = YES\n\n# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen \n# will generate a graph for each documented class showing the direct and \n# indirect implementation dependencies (inheritance, containment, and \n# class references variables) of the class with other documented classes.\n\nCOLLABORATION_GRAPH    = YES\n\n# If set to YES, the inheritance and collaboration graphs will show the \n# relations between templates and their instances.\n\nTEMPLATE_RELATIONS     = YES\n\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT \n# tags are set to YES then doxygen will generate a graph for each documented \n# file showing the direct and indirect include dependencies of the file with \n# other documented files.\n\nINCLUDE_GRAPH          = YES\n\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and \n# HAVE_DOT tags are set to YES then doxygen will generate a graph for each \n# documented header file showing the documented files that directly or \n# indirectly include this file.\n\nINCLUDED_BY_GRAPH      = YES\n\n# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen \n# will graphical hierarchy of all classes instead of a textual one.\n\nGRAPHICAL_HIERARCHY    = YES\n\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images \n# generated by dot. Possible values are png, jpg, or gif\n# If left blank png will be used.\n\nDOT_IMAGE_FORMAT       = png\n\n# The tag DOT_PATH can be used to specify the path where the dot tool can be \n# found. If left blank, it is assumed the dot tool can be found on the path.\n\nDOT_PATH               = \n\n# The DOTFILE_DIRS tag can be used to specify one or more directories that \n# contain dot files that are included in the documentation (see the \n# \\dotfile command).\n\nDOTFILE_DIRS           = \n\n# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width \n# (in pixels) of the graphs generated by dot. If a graph becomes larger than \n# this value, doxygen will try to truncate the graph, so that it fits within \n# the specified constraint. Beware that most browsers cannot cope with very \n# large images.\n\nMAX_DOT_GRAPH_WIDTH    = 1024\n\n# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height \n# (in pixels) of the graphs generated by dot. If a graph becomes larger than \n# this value, doxygen will try to truncate the graph, so that it fits within \n# the specified constraint. Beware that most browsers cannot cope with very \n# large images.\n\nMAX_DOT_GRAPH_HEIGHT   = 1024\n\n# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will \n# generate a legend page explaining the meaning of the various boxes and \n# arrows in the dot generated graphs.\n\nGENERATE_LEGEND        = YES\n\n# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will \n# remove the intermedate dot files that are used to generate \n# the various graphs.\n\nDOT_CLEANUP            = YES\n\n#---------------------------------------------------------------------------\n# Configuration::addtions related to the search engine   \n#---------------------------------------------------------------------------\n\n# The SEARCHENGINE tag specifies whether or not a search engine should be \n# used. If set to NO the values of all tags below this one will be ignored.\n\nSEARCHENGINE           = NO\n\n# The CGI_NAME tag should be the name of the CGI script that \n# starts the search engine (doxysearch) with the correct parameters. \n# A script with this name will be generated by doxygen.\n\nCGI_NAME               = search.cgi\n\n# The CGI_URL tag should be the absolute URL to the directory where the \n# cgi binaries are located. See the documentation of your http daemon for \n# details.\n\nCGI_URL                = \n\n# The DOC_URL tag should be the absolute URL to the directory where the \n# documentation is located. If left blank the absolute path to the \n# documentation, with file:// prepended to it, will be used.\n\nDOC_URL                = \n\n# The DOC_ABSPATH tag should be the absolute path to the directory where the \n# documentation is located. If left blank the directory on the local machine \n# will be used.\n\nDOC_ABSPATH            = \n\n# The BIN_ABSPATH tag must point to the directory where the doxysearch binary \n# is installed.\n\nBIN_ABSPATH            = /usr/local/bin/\n\n# The EXT_DOC_PATHS tag can be used to specify one or more paths to \n# documentation generated for other projects. This allows doxysearch to search \n# the documentation for these projects as well.\n\nEXT_DOC_PATHS          = \n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/doc/Makefile",
    "content": "# Makefile for libSRTP documentation\n#\n# David A. McGrew\n# Cisco Systems, Inc.\n#\n# This makefile does not use the autoconf system; we don't really need\n# it.  We just run doxygen then latex.  If you don't have either of\n# these, then there is no way that you can make your own\n# documentation.  Of course, you can just go online at pick up the\n# documentation from http://srtp.sourceforge.net.\n\nsrcdir = .\ntop_srcdir = ..\ntop_builddir = ../\n\n\n# Determine the version of the library\n\nversion = $(shell cat $(top_srcdir)/VERSION)\n\n\n.PHONY: libsrtpdoc cryptodoc clean\nlibsrtpdoc: \n\t@if test ! -e Doxyfile; then \\\n\t\techo \"*** Sorry, can't build doc outside source dir\"; exit 1; \\\n\tfi\n\tsed 's/LIBSRTPVERSION/$(version)/' header.template > header.tex\n\tdoxygen\n\tsed 's/\\subsection/\\section/' latex/index.tex > latex/index.tmp\n\tmv latex/index.tmp latex/index.tex\n\tcd latex; make\n\tcp latex/refman.pdf libsrtp.pdf\n\n\ncryptodoc: clean\n\tdoxygen crypto.dox\n\tcd latex; make\n\tcp latex/refman.pdf crypto.pdf\n\nclean:\n\trm -rf latex/ header.tex\n\tfor a in * ; do\t\t\t                \\\n              if [ -f \"$$a~\" ] ; then rm -f $$a~; fi;\t\\\n        done;\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/doc/Makefile.in",
    "content": "# Makefile for libSRTP documentation\n#\n# David A. McGrew\n# Cisco Systems, Inc.\n#\n# This makefile does not use the autoconf system; we don't really need\n# it.  We just run doxygen then latex.  If you don't have either of\n# these, then there is no way that you can make your own\n# documentation.  Of course, you can just go online at pick up the\n# documentation from http://srtp.sourceforge.net.\n\nsrcdir = @srcdir@\ntop_srcdir = @top_srcdir@\ntop_builddir = @top_builddir@\nVPATH = @srcdir@\n\n# Determine the version of the library\n\nversion = $(shell cat $(top_srcdir)/VERSION)\n\n\n.PHONY: libsrtpdoc cryptodoc clean\nlibsrtpdoc: \n\t@if test ! -e Doxyfile; then \\\n\t\techo \"*** Sorry, can't build doc outside source dir\"; exit 1; \\\n\tfi\n\tsed 's/LIBSRTPVERSION/$(version)/' header.template > header.tex\n\tdoxygen\n\tsed 's/\\subsection/\\section/' latex/index.tex > latex/index.tmp\n\tmv latex/index.tmp latex/index.tex\n\tcd latex; make\n\tcp latex/refman.pdf libsrtp.pdf\n\n\ncryptodoc: clean\n\tdoxygen crypto.dox\n\tcd latex; make\n\tcp latex/refman.pdf crypto.pdf\n\nclean:\n\trm -rf latex/ header.tex\n\tfor a in * ; do\t\t\t                \\\n              if [ -f \"$$a~\" ] ; then rm -f $$a~; fi;\t\\\n        done;\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/doc/crypto_kernel.txt",
    "content": "/**\n\n@defgroup CryptoKernel Cryptographic Kernel\n\nAll of the cryptographic functions are contained in a kernel.\n\n*/\n\n/**\n\n@defgroup CipherImplementations Ciphers\n@ingroup  CryptoKernel\n\n@brief A generic cipher type enables cipher agility, that is, the\nability to write code that runs with multiple cipher types.\nCiphers can be used through the crypto kernel, or can be accessed\ndirectly, if need be.\n\n@{\n\n*/\n\n/**\n * @brief Allocates a cipher of a particular type.\n * @warning May be implemented as a macro.\n */\nerr_status_t\ncipher_type_alloc(cipher_type_t *ctype, cipher_t **cipher, \n                        unsigned key_len);\n\n/**\n * @brief Initialized a cipher to use a particular key.  May\n *       be invoked more than once on the same cipher.\n * @warning May be implemented as a macro.\n */\n\nerr_status_t\ncipher_init(cipher_t *cipher, const uint8_t *key);\n\n/**\n * @brief Sets the initialization vector of a given cipher.\n * @warning May be implemented as a macro.\n */\n\nerr_status_t\ncipher_set_iv(cipher_t *cipher, void *iv);\n\n/**\n * @brief Encrypts a buffer with a given cipher.\n * @warning May be implemented as a macro.\n */                           \n\nerr_status_t\ncipher_encrypt(cipher_t *cipher, void *buf, unsigned int *len);\n\n/**\n * @brief Sets a buffer to the keystream generated by the cipher.\n * @warning May be implemented as a macro.\n */\nerr_status_t \ncipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output);\n\n/**\n * @brief Deallocates a cipher.\n * @warning May be implemented as a macro.\n */\nerr_status_t\ncipher_dealloc(cipher_t *cipher);\n\n\n\n/**\n * @} \n */\n\n */"
  },
  {
    "path": "deps/pjsip/third_party/srtp/doc/header.template",
    "content": "% header.tex\n% \n% header file for the libSRTP documentation - based on the header\n% file generated by doxygen, with the initial chapters of the \n% original libSRTP documentation tacked on\n% \n\\documentclass[letterpaper]{book}\n\\usepackage{makeidx}\n\\usepackage{fancyhdr}\n\\usepackage{graphicx}\n\\usepackage{multicol}\n\\usepackage{float}\n\\usepackage{textcomp}\n\\usepackage{alltt}\n\\usepackage{times}\n\\usepackage{graphicx}\n\\ifx\\pdfoutput\\undefined\n\\usepackage[ps2pdf,\n            pagebackref=true,\n            colorlinks=true,\n            linkcolor=blue\n           ]{hyperref}\n\\else\n\\usepackage[pdftex,\n            pagebackref=true,\n            colorlinks=true,\n            linkcolor=blue\n           ]{hyperref}\n\\fi\n\\usepackage{doxygen}\n\\makeindex\n\\setcounter{tocdepth}{1}\n\\renewcommand{\\footrulewidth}{0.4pt}\n\n% these lengths are from DAM\n\\textwidth = 6.5 in\n%\\textheight = 9 in\n\\oddsidemargin = 0.0 in\n\\evensidemargin = 0.0 in\n\\topmargin = 0.0 in\n\\headheight = 0.0 in\n%\\headsep = 0.0 in\n\\parskip = 0.2in\n\\parindent = 0.0in\n\n% these header and footer definitions from DAM\n\\lhead{libSRTP}\n\\chead{}\n\\rhead{\\rightmark}\n%\\rhead{\\slshape }\n\\lfoot{}\n\\cfoot{ \\thepage }\n\\rfoot{}\n%\\fancyhead[LE,RO]{\\rightmark }\n%\\fancyhead[LO,RE]{\\slshape }\n\n% let's use the palatino font\n\\fontfamily{ppl}\n\\selectfont\n\n\n\\begin{document}\n\\begin{titlepage}\n\\vspace*{4cm}\n%\\begin{center}\n{\\Huge \nlibSRTP LIBSRTPVERSION Overview and Reference Manual\\\\\n  \\hrulefill\n}\\\\\n\\vspace*{0cm}\n\\begin{flushright}\n{\\Large David A. McGrew \\\\ \\texttt{mcgrew@cisco.com} }\\\\\n\\vspace*{0.5cm}\n\\end{flushright}\n%\\end{center}\n\n%\\includegraphics[scale=.8]{phone}\n\n\\end{titlepage}\n\n\n\\clearemptydoublepage\n\\vspace*{3cm}\n{\\LARGE Preface}\n\\vspace{1cm}\n\nThe original implementation and documentation of libSRTP was written\nby David McGrew of Cisco Systems, Inc. in order to promote the use,\nunderstanding, and interoperability of Secure RTP.  Michael Jerris\ncontributed support for building under MSVC.  Andris Pavenis\ncontributed many important fixes.  Brian West contributed changes to\nenable dynamic linking.  Yves Shumann reported documentation bugs.\nRandell Jesup contributed a working SRTCP implementation and other\nfixes.  Alex Vanzella and Will Clark contributed changes so that the\nAES ICM implementation can be used for ISMA media encryption.  Steve\nUnderwood contributed x86\\_64 portability changes.  We also give\nthanks to Fredrik Thulin, Brian Weis, Mark Baugher, Jeff Chan, Bill\nSimon, Douglas Smith, Bill May, Richard Preistley, Joe Tardo and\nothers for contributions, comments, and corrections.\n\nThis reference material in this documenation was generated using the\n\\texttt{doxygen} utility for automatic documentation of source code.\n\n\\copyright 2001-2005 by David A. McGrew, Cisco Systems, Inc.\n\\thispagestyle{empty}\n\n\\clearemptydoublepage\n\\pagenumbering{roman}\n\\tableofcontents\n%\\clearemptydoublepage\n\n\\clearemptydoublepage\n\\pagenumbering{arabic}\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/doc/intro.txt",
    "content": "/**\n \n@mainpage Introduction to libSRTP\n \nThis document describes libSRTP, the Open Source Secure RTP library\nfrom Cisco Systems, Inc.  RTP is the Real-time Transport Protocol, an\nIETF standard for the transport of real-time data such as telephony,\naudio, and video, defined by RFC1889.  Secure RTP (SRTP) is an RTP\nprofile for providing confidentiality to RTP data and authentication\nto the RTP header and payload.  SRTP is an IETF Proposed Standard, and\nis defined in RFC 3711, and was developed in the IETF Audio/Video\nTransport (AVT) Working Group.  This library supports all of the\nmandatory features of SRTP, but not all of the optional features.  See\nthe @ref Features section for more detailed information.\n \nThis document is organized as follows.  The first chapter provides \nbackground material on SRTP and overview of libSRTP.  The following\nchapters provide a detailed reference to the libSRTP API and related\nfunctions.  The reference material is created automatically (using the\ndoxygen utility) from comments embedded in some of the C header\nfiles. The documentation is organized into modules in order to improve\nits clarity.  These modules do not directly correspond to files. An\nunderlying cryptographic kernel provides much of the basic\nfunctionality of libSRTP, but is mostly undocumented because it does\nits work behind the scenes.\n\n@section LICENSE License and Disclaimer\n\nlibSRTP is distributed under the following license, which is included\nin the source code distribution.  It is reproduced in the manual in\ncase you got the library from another source.\n\t\n@latexonly\n\\begin{quote}\nCopyright (c) 2001-2005 Cisco Systems, Inc.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\\begin{itemize}\n\\item  Redistributions of source code must retain the above copyright\n  notice, this list of conditions and the following disclaimer.\n\\item Redistributions in binary form must reproduce the above\n  copyright notice, this list of conditions and the following\n  disclaimer in the documentation and/or other materials provided\n  with the distribution.\n\\item Neither the name of the Cisco Systems, Inc. nor the names of its\n  contributors may be used to endorse or promote products derived\n  from this software without specific prior written permission.\n\\end{itemize}\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\nFOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\nINDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\nHOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\nSTRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\nOF THE POSSIBILITY OF SUCH DAMAGE.\n\\end{quote}\n@endlatexonly\n\n@section Features Supported Features\n\nThis library supports all of the mandatory-to-implement features of\nSRTP (as defined by the most recent Internet Draft).  Some of these\nfeatures can be selected (or de-selected) at run time by setting an\nappropriate policy; this is done using the structure srtp_policy_t.\nSome other behaviors of the protocol can be adapted by defining an\napproriate event handler for the exceptional events; see the @ref\nSRTPevents section.  \n\nSome options that are not included in the specification are supported.\nMost notably, the TMMH authentication function is included, though it\nwas removed from the SRTP Internet Draft during the summer of 2002.\n\n\n@latexonly\nSome options that are described in the SRTP specification are not\nsupported.  This includes \n\\begin{itemize}\n\\item the Master Key Index (MKI),\n\\item key derivation rates other than zero,\n\\item the cipher F8,\n\\item anti-replay lists with sizes other than 128,\n\\item the use of the packet index to select between master keys.\n\\end{itemize}\n@endlatexonly\n \nThe user should be aware that it is possible to misuse this libary,\nand that the result may be that the security level it provides is\ninadequate.  If you are implementing a feature using this library, you\nwill want to read the Security Considerations section of the Internet\nDraft.  In addition, it is important that you read and understand the\nterms outlined in the @ref LICENSE section.\n\n\n@section Installing Installing and Building libSRTP\n\n@latexonly\n\nTo install libSRTP, download the latest release of the distribution\nfrom \\texttt{srtp.sourceforge.net}.  The format of the names of the\ndistributions are \\texttt{srtp-A.B.C.tgz}, where \\texttt{A} is the\nversion number, \\texttt{B} is the major release number, \\texttt{C} is\nthe minor release number, and \\texttt{tgz} is the file\nextension\\footnote{The extension \\texttt{.tgz} is identical to\n\\texttt{tar.gz}, and indicates a compressed tar file.}  You probably\nwant to get the most recent release.  Unpack the distribution and\nextract the source files; the directory into which the soruce files\nwill go is named \\texttt{srtp}.\n\nlibSRTP uses the GNU \\texttt{autoconf} and \\texttt{make}\nutilities\\footnote{BSD make will not work; if both versions of make\nare on your platform, you can invoke GNU make as \\texttt{gmake}.}.  In\nthe \\texttt{srtp} directory, run the configure script and then make:\n\\begin{verbatim}\n  ./configure [ options ]       \n  make                          \n\\end{verbatim}\nThe configure script accepts the following options:\n\\begin{quote}\n\\begin{description}\n\\item[--help]              provides a usage summary.\n\\item[--disable-debug]     compiles libSRTP without the runtime \n\t\t\t   dynamic debugging system.\n\\item[--enable-generic-aesicm] compile in changes for ismacryp\n\\item[--enable-syslog]     use syslog for error reporting.\n\\item[--disable-stdout]    diables stdout for error reporting.\n\\item[--enable-console]    use \\texttt{/dev/console} for error reporting\n\\item[--gdoi]              use GDOI key management (disabled at present).\n\\end{description}\n\\end{quote}\n\nBy default, dynamic debbuging is enabled and stdout is used for\ndebugging.  You can use the configure options to have the debugging\noutput sent to syslog or the system console.  Alternatively, you can\ndefine ERR\\_REPORTING\\_FILE in \\texttt{include/conf.h} to be any other\nfile that can be opened by libSRTP, and debug messages will be sent to\nit.\n\nThis package has been tested on the following platforms: Mac OS X\n(powerpc-apple-darwin1.4), Cygwin (i686-pc-cygwin), Solaris\n(sparc-sun-solaris2.6), RedHat Linux 7.1 and 9 (i686-pc-linux), and\nOpenBSD (sparc-unknown-openbsd2.7).\n\n\n@endlatexonly\n\n@section Applications Applications\n\n@latexonly\n\nSeveral test drivers and a simple and portable srtp application are\nincluded in the \\texttt{test/} subdirectory.\n\n\\begin{center}\n\\begin{tabular}{ll}\n\\hline\nTest driver    \t& Function tested\t\\\\\n\\hline\nkernel\\_driver   & crypto kernel (ciphers, auth funcs, rng) \\\\\nsrtp\\_driver\t& srtp in-memory tests (does not use the network) \\\\\nrdbx\\_driver\t& rdbx (extended replay database) \\\\\nroc\\_driver\t& extended sequence number functions \\\\ \nreplay\\_driver\t& replay database  \\\\\ncipher\\_driver\t& ciphers  \\\\\nauth\\_driver\t& hash functions \\\\\n\\hline\n\\end{tabular}\n\\end{center}\n\nThe app rtpw is a simple rtp application which reads words from\n/usr/dict/words and then sends them out one at a time using [s]rtp.\nManual srtp keying uses the -k option; automated key management\nusing gdoi will be added later.\n\nThe usage for rtpw is\n\n\\texttt{rtpw [[-d $<$debug$>$]* [-k $<$key$>$ [-a][-e]] [-s | -r] dest\\_ip\ndest\\_port][-l]}\n\nEither the -s (sender) or -r (receiver) option must be chosen.  The\nvalues dest\\_ip, dest\\_port are the IP address and UDP port to which\nthe dictionary will be sent, respectively.  The options are:\n\\begin{center}\n\\begin{tabular}{ll}\n  -s\t\t& (S)RTP sender - causes app to send words \\\\\n  -r\t\t& (S)RTP receive - causes app to receve words \\\\\n  -k $<$key$>$      & use SRTP master key $<$key$>$, where the \n\t\tkey is a hexadecimal value (without the\n                leading \"0x\") \\\\\n  -e            & encrypt/decrypt (for data confidentiality)\n                (requires use of -k option as well)\\\\\n  -a            & message authentication \n                (requires use of -k option as well) \\\\\n  -l            & list the avaliable debug modules \\\\\n  -d $<$debug$>$    & turn on debugging for module $<$debug$>$ \\\\\n\\end{tabular}\n\\end{center}\n\nIn order to get a random 30-byte value for use as a key/salt pair, you\ncan use the \\texttt{rand\\_gen} utility in the \\texttt{test/}\nsubdirectory.\n\nAn example of an SRTP session using two rtpw programs follows:\n\n\\begin{verbatim}\n[sh1] set k=`test/rand_gen -n 30`\n[sh1] echo $k\nc1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451\n[sh1]$ test/rtpw -s -k $k -ea 0.0.0.0 9999 \nSecurity services: confidentiality message authentication\nset master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451\nsetting SSRC to 2078917053\nsending word: A\nsending word: a\nsending word: aa\nsending word: aal\nsending word: aalii\nsending word: aam\nsending word: Aani\nsending word: aardvark\n...\n\n[sh2] set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451\n[sh2]$ test/rtpw -r -k $k -ea 0.0.0.0 9999 \nsecurity services: confidentiality message authentication\nset master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451\n19 octets received from SSRC 2078917053 word: A\n19 octets received from SSRC 2078917053 word: a\n20 octets received from SSRC 2078917053 word: aa\n21 octets received from SSRC 2078917053 word: aal\n...\n\\end{verbatim}\n\n\n@endlatexonly\n\n\n@section Review Secure RTP Background\n\nIn this section we review SRTP and introduce some terms that are used\nin libSRTP.  An RTP session is defined by a pair of destination\ntransport addresses, that is, a network address plus a pair of UDP\nports for RTP and RTCP.  RTCP, the RTP control protocol, is used to\ncoordinate between the participants in an RTP session, e.g. to provide\nfeedback from receivers to senders.  An @e SRTP @e session is\nsimilarly defined; it is just an RTP session for which the SRTP\nprofile is being used.  An SRTP session consists of the traffic sent\nto the SRTP or SRTCP destination transport addresses.  Each\nparticipant in a session is identified by a synchronization source\n(SSRC) identifier.  Some participants may not send any SRTP traffic;\nthey are called receivers, even though they send out SRTCP traffic,\nsuch as receiver reports.\n\nRTP allows multiple sources to send RTP and RTCP traffic during the\nsame session.  The synchronization source identifier (SSRC) is used to\ndistinguish these sources.  In libSRTP, we call the SRTP and SRTCP\ntraffic from a particular source a @e stream.  Each stream has its own\nSSRC, sequence number, rollover counter, and other data.  A particular\nchoice of options, cryptographic mechanisms, and keys is called a @e\npolicy.  Each stream within a session can have a distinct policy\napplied to it.  A session policy is a collection of stream policies.\n\nA single policy can be used for all of the streams in a given session,\nthough the case in which a single @e key is shared across multiple\nstreams requires care.  When key sharing is used, the SSRC values that\nidentify the streams @b must be distinct.  This requirement can be\nenforced by using the convention that each SRTP and SRTCP key is used\nfor encryption by only a single sender.  In other words, the key is\nshared only across streams that originate from a particular device (of\ncourse, other SRTP participants will need to use the key for\ndecryption).  libSRTP supports this enforcement by detecting the case\nin which a key is used for both inbound and outbound data.\n\n\n@section Overview libSRTP Overview\n\nlibSRTP provides functions for protecting RTP and RTCP.  RTP packets\ncan be encrypted and authenticated (using the srtp_protect()\nfunction), turning them into SRTP packets.  Similarly, SRTP packets\ncan be decrypted and have their authentication verified (using the\nsrtp_unprotect() function), turning them into RTP packets.  Similar\nfunctions apply security to RTCP packets.\n\nThe typedef srtp_stream_t points to a structure holding all of the\nstate associated with an SRTP stream, including the keys and\nparameters for cipher and message authentication functions and the\nanti-replay data.  A particular srtp_stream_t holds the information\nneeded to protect a particular RTP and RTCP stream.  This datatype\nis intentionally opaque in order to better seperate the libSRTP\nAPI from its implementation.\n\nWithin an SRTP session, there can be multiple streams, each\noriginating from a particular sender.  Each source uses a distinct\nstream context to protect the RTP and RTCP stream that it is\noriginating.  The typedef srtp_t points to a structure holding all of\nthe state associated with an SRTP session.  There can be multiple\nstream contexts associated with a single srtp_t.  A stream context\ncannot exist indepent from an srtp_t, though of course an srtp_t can\nbe created that contains only a single stream context.  A device\nparticipating in an SRTP session must have a stream context for each\nsource in that session, so that it can process the data that it\nreceives from each sender.\n\n\nIn libSRTP, a session is created using the function srtp_create().\nThe policy to be implemented in the session is passed into this\nfunction as an srtp_policy_t structure.  A single one of these\nstructures describes the policy of a single stream.  These structures\ncan also be linked together to form an entire session policy.  A linked\nlist of srtp_policy_t structures is equivalent to a session policy.  \nIn such a policy, we refer to a single srtp_policy_t as an @e element.\n\nAn srtp_policy_t strucutre contains two crypto_policy_t structures\nthat describe the cryptograhic policies for RTP and RTCP, as well as\nthe SRTP master key and the SSRC value.  The SSRC describes what to\nprotect (e.g. which stream), and the crypto_policy_t structures\ndescribe how to protect it.  The key is contained in a policy element\nbecause it simplifies the interface to the library.  In many cases, it\nis desirable to use the same cryptographic policies across all of the\nstreams in a session, but to use a distinct key for each stream.  A\ncrypto_policy_t structure can be initialized by using either the\ncrypto_policy_set_rtp_default() or crypto_policy_set_rtcp_default()\nfunctions, which set a crypto policy structure to the default policies\nfor RTP and RTCP protection, respectively.\n\t\t\t\t   \n@section Example Example Code\n\nThis section provides a simple example of how to use libSRTP.  The\nexample code lacks error checking, but is functional.  Here we assume\nthat the value ssrc is already set to describe the SSRC of the stream\nthat we are sending, and that the functions get_rtp_packet() and\nsend_srtp_packet() are available to us.  The former puts an RTP packet\ninto the buffer and returns the number of octets written to that\nbuffer.  The latter sends the RTP packet in the buffer, given the\nlength as its second argument.\n\n@verbatim\n   srtp_t session;   \n   srtp_policy_t policy;\n   uint8_t key[30];\n\n   // initialize libSRTP \n   srtp_init();                                  \n\n   // set policy to describe a policy for an SRTP stream \n   crypto_policy_set_rtp_default(&policy.rtp);   \n   crypto_policy_set_rtcp_default(&policy.rtcp); \n   policy.ssrc = ssrc;                            \n   policy.key  = key;\n   policy.next = NULL;\n\n   // set key to random value \n   crypto_get_random(key, 30);          \n\n   // allocate and initialize the SRTP session \n   srtp_create(&session, policy);  \n   \n   // main loop: get rtp packets, send srtp packets\n   while (1) {\n      char rtp_buffer[2048];\n      unsigned len;\n\n      len = get_rtp_packet(rtp_buffer);\n      srtp_protect(session, rtp_buffer, &len);\n      send_srtp_packet(rtp_buffer, len);\n   }\n@endverbatim\n\n@section ISMAcryp ISMA Encryption Support\n\nThe Internet Streaming Media Alliance (ISMA) specifies a way \nto pre-encrypt a media file prior to streaming.  This method\nis an alternative to SRTP encryption, which is potentially\nuseful when a particular media file will be streamed\nmultiple times.  The specification is available online \nat  http://www.isma.tv/specreq.nsf/SpecRequest.\n\nlibSRTP provides the encryption and decryption functions needed for ISMAcryp\nin the library @t libaesicm.a, which is included in the default\nMakefile target.  This library is used by the MPEG4IP project; see \nhttp://mpeg4ip.sourceforge.net/.\n\nNote that ISMAcryp does not provide authentication for \nRTP nor RTCP, nor confidentiality for RTCP.  \nISMAcryp RECOMMENDS the use of SRTP message authentication for ISMAcryp\nstreams while using ISMAcryp encryption to protect the media itself.\n\n\n */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/doc/references.txt",
    "content": "SRTP and ICM References \nSeptember, 2005\n\nThis document provides references for the various cryptographic\nfunctions used in libSRTP and libaesicm.\n\nSecure RTP is defined in RFC 3711, which is included in this\ndistribution for convenience.  The counter mode definition is in\nSection 4.1.1 of the SRTP draft.\n\nSHA-1 is defined in FIPS-180-1, available online at the NIST website.\n\nHMAC is defined in RFC2104, and HMAC-SHA1 test vectors are available\nin RFC2202, which are available online at http://www.ietf.org/rfc/\n\nICM is defined by draft-irtf-cfrg-icm-00.txt, and its application in\nISMAcryp (the Internet Streaming Media Alliance 1.0 Encryption and\nAuthentication) is defined in that specification.  It is available\nfrom http://www.isma.tv/.\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/include/getopt_s.h",
    "content": "/*\n * getopt.h\n *\n * interface to a minimal implementation of the getopt() function,\n * written so that test applications that use that function can run on\n * non-POSIX platforms\n *\n */\n/*\n *\t\n * Copyright (c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#ifndef GETOPT_S_H\n#define GETOPT_S_H\n\n/* \n * getopt_s(), optarg_s, and optind_s are small, locally defined\n * versions of the POSIX standard getopt() interface.\n */\n \nint\ngetopt_s(int argc, char * const argv[], const char *optstring);\n\nextern char *optarg_s;    /* defined in getopt.c */\n\nextern int optind_s;      /* defined in getopt.c */\n\n#endif /* GETOPT_S_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/include/rtp.h",
    "content": "/*\n * rtp.h\n * \n * rtp interface for srtp reference implementation\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n *\n * data types:\n *\n * rtp_msg_t       an rtp message (the data that goes on the wire)\n * rtp_sender_t    sender side socket and rtp info\n * rtp_receiver_t  receiver side socket and rtp info\n *\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#ifndef RTP_H\n#define RTP_H\n\n#ifdef HAVE_NETINET_IN_H\n# include <netinet/in.h>\n#elif defined HAVE_WINSOCK2_H\n# include <winsock2.h>\n#endif\n\n#include \"srtp.h\"\n\ntypedef struct rtp_sender_ctx_t *rtp_sender_t;\n\ntypedef struct rtp_receiver_ctx_t *rtp_receiver_t;\n\nunsigned int\nrtp_sendto(rtp_sender_t sender, const void* msg, int len);\n\nunsigned int\nrtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len);\n\nint\nrtp_receiver_init(rtp_receiver_t rcvr, int socket, \n\t\t  struct sockaddr_in addr, unsigned int ssrc);\n\nint\nrtp_sender_init(rtp_sender_t sender, int socket, \n\t\tstruct sockaddr_in addr, unsigned int ssrc);\n\n/*\n * srtp_sender_init(...) initializes an rtp_sender_t\n */\n\nint\nsrtp_sender_init(rtp_sender_t rtp_ctx,          /* structure to be init'ed */\n\t\t struct sockaddr_in name,       /* socket name             */\n\t\t sec_serv_t security_services,  /* sec. servs. to be used  */\n\t\t unsigned char *input_key       /* master key/salt in hex  */\n\t\t );\n\nint\nsrtp_receiver_init(rtp_receiver_t rtp_ctx,       /* structure to be init'ed */\n\t\t   struct sockaddr_in name, \t /* socket name             */\n\t\t   sec_serv_t security_services, /* sec. servs. to be used  */\n\t\t   unsigned char *input_key\t /* master key/salt in hex  */\n\t\t   );\n\n\nint\nrtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy);\n\nint\nrtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy);\n\n\nrtp_sender_t \nrtp_sender_alloc();\n\nrtp_receiver_t \nrtp_receiver_alloc();\n\n\n/*\n * RTP_HEADER_LEN indicates the size of an RTP header\n */\n#define RTP_HEADER_LEN   12\n\n/* \n * RTP_MAX_BUF_LEN defines the largest RTP packet in the rtp.c implementation\n */\n#define RTP_MAX_BUF_LEN  16384\n\n\n#endif /* RTP_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/include/rtp_priv.h",
    "content": "/*\n * rtp_priv.h\n *\n * private, internal header file for RTP\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#ifndef RTP_PRIV_H\n#define RTP_PRIV_H\n\n#include \"srtp_priv.h\"\n#include \"rtp.h\"\n\ntypedef srtp_hdr_t rtp_hdr_t;\n\ntypedef struct {\n  srtp_hdr_t header;        \n  char body[RTP_MAX_BUF_LEN];  \n} rtp_msg_t;\n\ntypedef struct rtp_sender_ctx_t {\n  rtp_msg_t message;         \n  int socket;\n  srtp_ctx_t *srtp_ctx;\n  struct sockaddr_in addr;   /* reciever's address */\n} rtp_sender_ctx_t;\n\ntypedef struct rtp_receiver_ctx_t {\n  rtp_msg_t message;\n  int socket;\n  srtp_ctx_t *srtp_ctx;\n  struct sockaddr_in addr;   /* receiver's address */\n} rtp_receiver_ctx_t;\n\n\n#endif /* RTP_PRIV_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/include/srtp.h",
    "content": "/*\n * srtp.h\n *\n * interface to libsrtp\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#ifndef SRTP_H\n#define SRTP_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifdef _MSC_VER\n#   ifdef WIN64\n#\tpragma pack(8)\n#   else\n#\tpragma pack(4)\n#   endif\n#endif\n\n#include \"crypto_kernel.h\"\n\n/**\n * @defgroup SRTP Secure RTP\n *\n * @brief libSRTP provides functions for protecting RTP and RTCP.  See\n * Section @ref Overview for an introduction to the use of the library.\n *\n * @{\n */\n\n/*\n * SRTP_MASTER_KEY_LEN is the nominal master key length supported by libSRTP\n */\n\n#define SRTP_MASTER_KEY_LEN 30\n\n/*\n * SRTP_MAX_KEY_LEN is the maximum key length supported by libSRTP\n */\n#define SRTP_MAX_KEY_LEN      64\n\n/*\n * SRTP_MAX_TAG_LEN is the maximum tag length supported by libSRTP\n */\n\n#define SRTP_MAX_TAG_LEN 12 \n\n/**\n * SRTP_MAX_TRAILER_LEN is the maximum length of the SRTP trailer\n * (authentication tag and MKI) supported by libSRTP.  This value is\n * the maximum number of octets that will be added to an RTP packet by\n * srtp_protect().\n *\n * @brief the maximum number of octets added by srtp_protect().\n */\n#define SRTP_MAX_TRAILER_LEN SRTP_MAX_TAG_LEN \n\n/* \n * nota bene: since libSRTP doesn't support the use of the MKI, the\n * SRTP_MAX_TRAILER_LEN value is just the maximum tag length\n */\n\n/**\n * @brief sec_serv_t describes a set of security services. \n *\n * A sec_serv_t enumeration is used to describe the particular\n * security services that will be applied by a particular crypto\n * policy (or other mechanism).  \n */\n\ntypedef enum {\n  sec_serv_none          = 0, /**< no services                        */\n  sec_serv_conf          = 1, /**< confidentiality                    */\n  sec_serv_auth          = 2, /**< authentication                     */\n  sec_serv_conf_and_auth = 3  /**< confidentiality and authentication */\n} sec_serv_t;\n\n/** \n * @brief crypto_policy_t describes a particular crypto policy that\n * can be applied to an SRTP stream.\n *\n * A crypto_policy_t describes a particular cryptographic policy that\n * can be applied to an SRTP or SRTCP stream.  An SRTP session policy\n * consists of a list of these policies, one for each SRTP stream \n * in the session.\n */\n\ntypedef struct crypto_policy_t {\n  cipher_type_id_t cipher_type;    /**< An integer representing\n\t\t\t\t    *   the type of cipher.  */\n  int              cipher_key_len; /**< The length of the cipher key\n\t\t\t\t    *   in octets.                       */\n  auth_type_id_t   auth_type;      /**< An integer representing the\n\t\t\t\t    *   authentication function.         */\n  int              auth_key_len;   /**< The length of the authentication \n\t\t\t\t    *   function key in octets.          */\n  int              auth_tag_len;   /**< The length of the authentication \n\t\t\t\t    *   tag in octets.                   */\n  sec_serv_t       sec_serv;       /**< The flag indicating the security\n\t\t\t\t    *   services to be applied.          */\n} crypto_policy_t;\n\n\n/** \n * @brief ssrc_type_t describes the type of an SSRC.\n * \n * An ssrc_type_t enumeration is used to indicate a type of SSRC.  See\n * @ref srtp_policy_t for more informataion.\n */\n\ntypedef enum { \n  ssrc_undefined    = 0,  /**< Indicates an undefined SSRC type. */\n  ssrc_specific     = 1,  /**< Indicates a specific SSRC value   */\n  ssrc_any_inbound  = 2, /**< Indicates any inbound SSRC value \n\t\t\t    (i.e. a value that is used in the\n\t\t\t    function srtp_unprotect())              */\n  ssrc_any_outbound = 3  /**< Indicates any outbound SSRC value \n\t\t\t    (i.e. a value that is used in the \n\t\t\t    function srtp_protect())\t\t  */\n} ssrc_type_t;\n\n/**\n * @brief An ssrc_t represents a particular SSRC value, or a `wildcard' SSRC.\n * \n * An ssrc_t represents a particular SSRC value (if its type is\n * ssrc_specific), or a wildcard SSRC value that will match all\n * outbound SSRCs (if its type is ssrc_any_outbound) or all inbound\n * SSRCs (if its type is ssrc_any_inbound).  \n *\n */\n\ntypedef struct { \n  ssrc_type_t type;   /**< The type of this particular SSRC */\n  unsigned int value; /**< The value of this SSRC, if it is not a wildcard */\n} ssrc_t;\n\n\n/** \n * @brief represents the policy for an SRTP session.  \n *\n * A single srtp_policy_t struct represents the policy for a single\n * SRTP stream, and a linked list of these elements represents the\n * policy for an entire SRTP session.  Each element contains the SRTP\n * and SRTCP crypto policies for that stream, a pointer to the SRTP\n * master key for that stream, the SSRC describing that stream, or a\n * flag indicating a `wildcard' SSRC value, and a `next' field that\n * holds a pointer to the next element in the list of policy elements,\n * or NULL if it is the last element. \n *\n * The wildcard value SSRC_ANY_INBOUND matches any SSRC from an\n * inbound stream that for which there is no explicit SSRC entry in\n * another policy element.  Similarly, the value SSRC_ANY_OUTBOUND\n * will matches any SSRC from an outbound stream that does not appear\n * in another policy element.  Note that wildcard SSRCs &b cannot be\n * used to match both inbound and outbound traffic.  This restriction\n * is intentional, and it allows libSRTP to ensure that no security\n * lapses result from accidental re-use of SSRC values during key\n * sharing.\n * \n * \n * @warning The final element of the list @b must have its `next' pointer\n *          set to NULL.\n */\n\ntypedef struct srtp_policy_t {\n  ssrc_t        ssrc;        /**< The SSRC value of stream, or the \n\t\t\t      *   flags SSRC_ANY_INBOUND or \n\t\t\t      *   SSRC_ANY_OUTBOUND if key sharing\n\t\t\t      *   is used for this policy element.\n\t\t\t      */\n  crypto_policy_t rtp;         /**< SRTP crypto policy.                  */\n  crypto_policy_t rtcp;        /**< SRTCP crypto policy.                 */\n  unsigned char *key;          /**< Pointer to the SRTP master key for\n\t\t\t\t*    this stream.                        */\n  struct srtp_policy_t *next;  /**< Pointer to next stream policy.       */\n} srtp_policy_t;\n\n\n\n\n/**\n * @brief An srtp_t points to an SRTP session structure.\n *\n * The typedef srtp_t is a pointer to a structure that represents\n * an SRTP session.  This datatype is intentially opaque in \n * order to separate the interface from the implementation.\n *\n * An SRTP session consists of all of the traffic sent to the RTP and\n * RTCP destination transport addresses, using the RTP/SAVP (Secure\n * Audio/Video Profile).  A session can be viewed as a set of SRTP\n * streams, each of which originates with a different participant.\n */\n\ntypedef struct srtp_ctx_t *srtp_t;\n\n\n/**\n * @brief An srtp_stream_t points to an SRTP stream structure.\n *\n * The typedef srtp_stream_t is a pointer to a structure that\n * represents an SRTP stream.  This datatype is intentionally\n * opaque in order to separate the interface from the implementation. \n * \n * An SRTP stream consists of all of the traffic sent to an SRTP\n * session by a single participant.  A session can be viewed as\n * a set of streams.  \n *\n */\ntypedef struct srtp_stream_ctx_t *srtp_stream_t;\n\n\n\n/**\n * @brief srtp_init() initializes the srtp library.  \n *\n * @warning This function @b must be called before any other srtp\n * functions.\n */\n\nerr_status_t\nsrtp_init(void);\n\n/**\n * @brief srtp_deinit() deinitializes the srtp library.  \n *\n * @warning This function @b must be called on quitting application or\n * after srtp is no longer used.\n */\n\nerr_status_t\nsrtp_deinit(void);\n\n/**\n * @brief srtp_protect() is the Secure RTP sender-side packet processing\n * function.\n * \n * The function call srtp_protect(ctx, rtp_hdr, len_ptr) applies SRTP\n * protection to the RTP packet rtp_hdr (which has length *len_ptr) using\n * the SRTP context ctx.  If err_status_ok is returned, then rtp_hdr\n * points to the resulting SRTP packet and *len_ptr is the number of\n * octets in that packet; otherwise, no assumptions should be made\n * about the value of either data elements.\n * \n * The sequence numbers of the RTP packets presented to this function\n * need not be consecutive, but they @b must be out of order by less\n * than 2^15 = 32,768 packets.\n *\n * @warning This function assumes that it can write the authentication\n * tag into the location in memory immediately following the RTP\n * packet, and assumes that the RTP packet is aligned on a 32-bit\n * boundary.\n *\n * @param ctx is the SRTP context to use in processing the packet.\n *\n * @param rtp_hdr is a pointer to the RTP packet (before the call); after\n * the function returns, it points to the srtp packet.\n *\n * @param len_ptr is a pointer to the length in octets of the complete\n * RTP packet (header and body) before the function call, and of the\n * complete SRTP packet after the call, if err_status_ok was returned.\n * Otherwise, the value of the data to which it points is undefined.\n *\n * @return \n *    - err_status_ok            no problems\n *    - err_status_replay_fail   rtp sequence number was non-increasing\n *    - @e other                 failure in cryptographic mechanisms\n */\n\nerr_status_t\nsrtp_protect(srtp_t ctx, void *rtp_hdr, int *len_ptr);\n\t     \n/**\n * @brief srtp_unprotect() is the Secure RTP receiver-side packet\n * processing function.\n *\n * The function call srtp_unprotect(ctx, srtp_hdr, len_ptr) verifies\n * the Secure RTP protection of the SRTP packet pointed to by srtp_hdr\n * (which has length *len_ptr), using the SRTP context ctx.  If\n * err_status_ok is returned, then srtp_hdr points to the resulting\n * RTP packet and *len_ptr is the number of octets in that packet;\n * otherwise, no assumptions should be made about the value of either\n * data elements.  \n * \n * The sequence numbers of the RTP packets presented to this function\n * need not be consecutive, but they @b must be out of order by less\n * than 2^15 = 32,768 packets.\n * \n * @warning This function assumes that the SRTP packet is aligned on a\n * 32-bit boundary.\n *\n * @param ctx is a pointer to the srtp_t which applies to the\n * particular packet.\n *\n * @param srtp_hdr is a pointer to the header of the SRTP packet\n * (before the call).  after the function returns, it points to the\n * rtp packet if err_status_ok was returned; otherwise, the value of\n * the data to which it points is undefined.\n *\n * @param len_ptr is a pointer to the length in octets of the complete\n * srtp packet (header and body) before the function call, and of the\n * complete rtp packet after the call, if err_status_ok was returned.\n * Otherwise, the value of the data to which it points is undefined.\n *\n * @return \n *    - err_status_ok          if the RTP packet is valid.\n *    - err_status_auth_fail   if the SRTP packet failed the message \n *                             authentication check.\n *    - err_status_replay_fail if the SRTP packet is a replay (e.g. packet has\n *                             already been processed and accepted).\n *    - [other]  if there has been an error in the cryptographic mechanisms.\n *\n */\n\nerr_status_t\nsrtp_unprotect(srtp_t ctx, void *srtp_hdr, int *len_ptr);\n\n\n/**\n * @brief srtp_create() allocates and initializes an SRTP session.\n\n * The function call srtp_create(session, policy, key) allocates and\n * initializes an SRTP session context, applying the given policy and\n * key.\n *\n * @param session is the SRTP session to which the policy is to be added.\n * \n * @param policy is the srtp_policy_t struct that describes the policy\n * for the session.  The struct may be a single element, or it may be\n * the head of a list, in which case each element of the list is\n * processed.  It may also be NULL, in which case streams should be added\n * later using srtp_add_stream().  The final element of the list @b must\n * have its `next' field set to NULL.\n * \n * @return\n *    - err_status_ok           if creation succeded.\n *    - err_status_alloc_fail   if allocation failed.\n *    - err_status_init_fail    if initialization failed.\n */\n\nerr_status_t\nsrtp_create(srtp_t *session, const srtp_policy_t *policy);\n\n\n/**\n * @brief srtp_add_stream() allocates and initializes an SRTP stream\n * within a given SRTP session.\n * \n * The function call srtp_add_stream(session, policy) allocates and\n * initializes a new SRTP stream within a given, previously created\n * session, applying the policy given as the other argument to that\n * stream.\n *\n * @return values:\n *    - err_status_ok           if stream creation succeded.\n *    - err_status_alloc_fail   if stream allocation failed\n *    - err_status_init_fail    if stream initialization failed.\n */\n\nerr_status_t\nsrtp_add_stream(srtp_t session, \n\t\tconst srtp_policy_t *policy);\n\n\n/**\n * @brief srtp_remove_stream() deallocates an SRTP stream.\n * \n * The function call srtp_remove_stream(session, ssrc) removes\n * the SRTP stream with the SSRC value ssrc from the SRTP session\n * context given by the argument session.\n *\n * @param session is the SRTP session from which the stream\n *        will be removed.\n *\n * @param ssrc is the SSRC value of the stream to be removed.\n *\n * @warning Wildcard SSRC values cannot be removed from a\n *          session.\n * \n * @return\n *    - err_status_ok     if the stream deallocation succeded.\n *    - [other]           otherwise.\n *\n */\n\nerr_status_t\nsrtp_remove_stream(srtp_t session, unsigned int ssrc);\n\n/**\n * @brief crypto_policy_set_rtp_default() sets a crypto policy\n * structure to the SRTP default policy for RTP protection.\n *\n * @param p is a pointer to the policy structure to be set \n * \n * The function call crypto_policy_set_rtp_default(&p) sets the\n * crypto_policy_t at location p to the SRTP default policy for RTP\n * protection, as defined in the specification.  This function is a\n * convenience that helps to avoid dealing directly with the policy\n * data structure.  You are encouraged to initialize policy elements\n * with this function call.  Doing so may allow your code to be\n * forward compatible with later versions of libSRTP that include more\n * elements in the crypto_policy_t datatype.\n * \n * @return void.\n * \n */\n\nvoid\ncrypto_policy_set_rtp_default(crypto_policy_t *p);\n\n/**\n * @brief crypto_policy_set_rtcp_default() sets a crypto policy\n * structure to the SRTP default policy for RTCP protection.\n *\n * @param p is a pointer to the policy structure to be set \n * \n * The function call crypto_policy_set_rtcp_default(&p) sets the\n * crypto_policy_t at location p to the SRTP default policy for RTCP\n * protection, as defined in the specification.  This function is a\n * convenience that helps to avoid dealing directly with the policy\n * data structure.  You are encouraged to initialize policy elements\n * with this function call.  Doing so may allow your code to be\n * forward compatible with later versions of libSRTP that include more\n * elements in the crypto_policy_t datatype.\n * \n * @return void.\n * \n */\n\nvoid\ncrypto_policy_set_rtcp_default(crypto_policy_t *p);\n\n/**\n * @brief crypto_policy_set_aes_cm_128_hmac_sha1_80() sets a crypto\n * policy structure to the SRTP default policy for RTP protection.\n *\n * @param p is a pointer to the policy structure to be set \n * \n * The function crypto_policy_set_aes_cm_128_hmac_sha1_80() is a\n * synonym for crypto_policy_set_rtp_default().  It conforms to the\n * naming convention used in\n * http://www.ietf.org/internet-drafts/draft-ietf-mmusic-sdescriptions-12.txt\n * \n * @return void.\n * \n */\n\n#define crypto_policy_set_aes_cm_128_hmac_sha1_80(p) crypto_policy_set_rtp_default(p)\n\n\n/**\n * @brief crypto_policy_set_aes_cm_128_hmac_sha1_32() sets a crypto\n * policy structure to a short-authentication tag policy\n *\n * @param p is a pointer to the policy structure to be set \n * \n * The function call crypto_policy_set_aes_cm_128_hmac_sha1_32(&p)\n * sets the crypto_policy_t at location p to use policy\n * AES_CM_128_HMAC_SHA1_32 as defined in\n * draft-ietf-mmusic-sdescriptions-12.txt.  This policy uses AES-128\n * Counter Mode encryption and HMAC-SHA1 authentication, with an\n * authentication tag that is only 32 bits long.  This length is\n * considered adequate only for protecting audio and video media that\n * use a stateless playback function.  See Section 7.5 of RFC 3711\n * (http://www.ietf.org/rfc/rfc3711.txt).\n * \n * This function is a convenience that helps to avoid dealing directly\n * with the policy data structure.  You are encouraged to initialize\n * policy elements with this function call.  Doing so may allow your\n * code to be forward compatible with later versions of libSRTP that\n * include more elements in the crypto_policy_t datatype.\n *\n * @warning This crypto policy is intended for use in SRTP, but not in\n * SRTCP.  It is recommended that a policy that uses longer\n * authentication tags be used for SRTCP.  See Section 7.5 of RFC 3711\n * (http://www.ietf.org/rfc/rfc3711.txt).\n *\n * @return void.\n * \n */\n\nvoid\ncrypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p);\n\n\n\n/**\n * @brief crypto_policy_set_aes_cm_128_null_auth() sets a crypto\n * policy structure to an encryption-only policy\n *\n * @param p is a pointer to the policy structure to be set \n * \n * The function call crypto_policy_set_aes_cm_128_null_auth(&p) sets\n * the crypto_policy_t at location p to use the SRTP default cipher\n * (AES-128 Counter Mode), but to use no authentication method.  This\n * policy is NOT RECOMMENDED unless it is unavoidable; see Section 7.5\n * of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt).\n * \n * This function is a convenience that helps to avoid dealing directly\n * with the policy data structure.  You are encouraged to initialize\n * policy elements with this function call.  Doing so may allow your\n * code to be forward compatible with later versions of libSRTP that\n * include more elements in the crypto_policy_t datatype.\n *\n * @warning This policy is NOT RECOMMENDED for SRTP unless it is\n * unavoidable, and it is NOT RECOMMENDED at all for SRTCP; see\n * Section 7.5 of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt).\n *\n * @return void.\n * \n */\n\nvoid\ncrypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p);\n\n\n/**\n * @brief crypto_policy_set_null_cipher_hmac_sha1_80() sets a crypto\n * policy structure to an authentication-only policy\n *\n * @param p is a pointer to the policy structure to be set \n * \n * The function call crypto_policy_set_null_cipher_hmac_sha1_80(&p)\n * sets the crypto_policy_t at location p to use HMAC-SHA1 with an 80\n * bit authentication tag to provide message authentication, but to\n * use no encryption.  This policy is NOT RECOMMENDED for SRTP unless\n * there is a requirement to forego encryption.  \n * \n * This function is a convenience that helps to avoid dealing directly\n * with the policy data structure.  You are encouraged to initialize\n * policy elements with this function call.  Doing so may allow your\n * code to be forward compatible with later versions of libSRTP that\n * include more elements in the crypto_policy_t datatype.\n *\n * @warning This policy is NOT RECOMMENDED for SRTP unless there is a\n * requirement to forego encryption.  \n *\n * @return void.\n * \n */\n\nvoid\ncrypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p);\n\n/**\n * @brief srtp_dealloc() deallocates storage for an SRTP session\n * context.\n * \n * The function call srtp_dealloc(s) deallocates storage for the\n * SRTP session context s.  This function should be called no more\n * than one time for each of the contexts allocated by the function\n * srtp_create().\n *\n * @param s is the srtp_t for the session to be deallocated.\n *\n * @return\n *    - err_status_ok             if there no problems.\n *    - err_status_dealloc_fail   a memory deallocation failure occured.\n */\n\nerr_status_t\nsrtp_dealloc(srtp_t s);\n\n\n/*\n * @brief identifies a particular SRTP profile \n *\n * An srtp_profile_t enumeration is used to identify a particular SRTP\n * profile (that is, a set of algorithms and parameters).  These\n * profiles are defined in the DTLS-SRTP draft.\n */\n\ntypedef enum {\n  srtp_profile_reserved           = 0,\n  srtp_profile_aes128_cm_sha1_80  = 1,\n  srtp_profile_aes128_cm_sha1_32  = 2,\n  srtp_profile_aes256_cm_sha1_80  = 3,\n  srtp_profile_aes256_cm_sha1_32  = 4,\n  srtp_profile_null_sha1_80       = 5,\n  srtp_profile_null_sha1_32       = 6,\n} srtp_profile_t;\n\n\n/**\n * @brief crypto_policy_set_from_profile_for_rtp() sets a crypto policy\n * structure to the appropriate value for RTP based on an srtp_profile_t\n *\n * @param p is a pointer to the policy structure to be set \n * \n * The function call crypto_policy_set_rtp_default(&policy, profile)\n * sets the crypto_policy_t at location policy to the policy for RTP\n * protection, as defined by the srtp_profile_t profile.\n * \n * This function is a convenience that helps to avoid dealing directly\n * with the policy data structure.  You are encouraged to initialize\n * policy elements with this function call.  Doing so may allow your\n * code to be forward compatible with later versions of libSRTP that\n * include more elements in the crypto_policy_t datatype.\n * \n * @return values\n *     - err_status_ok         no problems were encountered\n *     - err_status_bad_param  the profile is not supported \n * \n */\nerr_status_t\ncrypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy, \n\t\t\t\t       srtp_profile_t profile);\n\n\n\n\n/**\n * @brief crypto_policy_set_from_profile_for_rtcp() sets a crypto policy\n * structure to the appropriate value for RTCP based on an srtp_profile_t\n *\n * @param p is a pointer to the policy structure to be set \n * \n * The function call crypto_policy_set_rtcp_default(&policy, profile)\n * sets the crypto_policy_t at location policy to the policy for RTCP\n * protection, as defined by the srtp_profile_t profile.\n * \n * This function is a convenience that helps to avoid dealing directly\n * with the policy data structure.  You are encouraged to initialize\n * policy elements with this function call.  Doing so may allow your\n * code to be forward compatible with later versions of libSRTP that\n * include more elements in the crypto_policy_t datatype.\n * \n * @return values\n *     - err_status_ok         no problems were encountered\n *     - err_status_bad_param  the profile is not supported \n * \n */\nerr_status_t\ncrypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy, \n\t\t\t\t       srtp_profile_t profile);\n\n/**\n * @brief returns the master key length for a given SRTP profile\n */\nunsigned int\nsrtp_profile_get_master_key_length(srtp_profile_t profile);\n\n\n/**\n * @brief returns the master salt length for a given SRTP profile\n */\nunsigned int\nsrtp_profile_get_master_salt_length(srtp_profile_t profile);\n\n/**\n * @brief appends the salt to the key\n *\n * The function call append_salt_to_key(k, klen, s, slen) \n * copies the string s to the location at klen bytes following\n * the location k.  \n *\n * @warning There must be at least bytes_in_salt + bytes_in_key bytes\n *          available at the location pointed to by key.\n * \n */\n\nvoid\nappend_salt_to_key(unsigned char *key, unsigned int bytes_in_key,\n\t\t   unsigned char *salt, unsigned int bytes_in_salt);\n\n\n\n/**\n * @}\n */\n\n\n\n/**\n * @defgroup SRTCP Secure RTCP\n * @ingroup  SRTP \n *\n * @brief Secure RTCP functions are used to protect RTCP traffic.\n *\n * RTCP is the control protocol for RTP.  libSRTP protects RTCP\n * traffic in much the same way as it does RTP traffic.  The function\n * srtp_protect_rtcp() applies cryptographic protections to outbound\n * RTCP packets, and srtp_unprotect_rtcp() verifies the protections on\n * inbound RTCP packets.  \n *\n * A note on the naming convention: srtp_protect_rtcp() has an srtp_t\n * as its first argument, and thus has `srtp_' as its prefix.  The\n * trailing `_rtcp' indicates the protocol on which it acts.  \n * \n * @{\n */\n\n/**\n * @brief srtp_protect_rtcp() is the Secure RTCP sender-side packet\n * processing function.\n * \n * The function call srtp_protect_rtcp(ctx, rtp_hdr, len_ptr) applies\n * SRTCP protection to the RTCP packet rtcp_hdr (which has length\n * *len_ptr) using the SRTP session context ctx.  If err_status_ok is\n * returned, then rtp_hdr points to the resulting SRTCP packet and\n * *len_ptr is the number of octets in that packet; otherwise, no\n * assumptions should be made about the value of either data elements.\n * \n * @warning This function assumes that it can write the authentication\n * tag into the location in memory immediately following the RTCP\n * packet, and assumes that the RTCP packet is aligned on a 32-bit\n * boundary.\n *\n * @param ctx is the SRTP context to use in processing the packet.\n *\n * @param rtcp_hdr is a pointer to the RTCP packet (before the call); after\n * the function returns, it points to the srtp packet.\n *\n * @param pkt_octet_len is a pointer to the length in octets of the\n * complete RTCP packet (header and body) before the function call,\n * and of the complete SRTCP packet after the call, if err_status_ok\n * was returned.  Otherwise, the value of the data to which it points\n * is undefined.\n *\n * @return \n *    - err_status_ok            if there were no problems.\n *    - [other]                  if there was a failure in \n *                               the cryptographic mechanisms.\n */\n\t     \n\nerr_status_t \nsrtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len);\n\n/**\n * @brief srtp_unprotect_rtcp() is the Secure RTCP receiver-side packet\n * processing function.\n *\n * The function call srtp_unprotect_rtcp(ctx, srtp_hdr, len_ptr)\n * verifies the Secure RTCP protection of the SRTCP packet pointed to\n * by srtcp_hdr (which has length *len_ptr), using the SRTP session\n * context ctx.  If err_status_ok is returned, then srtcp_hdr points\n * to the resulting RTCP packet and *len_ptr is the number of octets\n * in that packet; otherwise, no assumptions should be made about the\n * value of either data elements.\n * \n * @warning This function assumes that the SRTCP packet is aligned on a\n * 32-bit boundary.\n *\n * @param ctx is a pointer to the srtp_t which applies to the\n * particular packet.\n *\n * @param srtcp_hdr is a pointer to the header of the SRTCP packet\n * (before the call).  After the function returns, it points to the\n * rtp packet if err_status_ok was returned; otherwise, the value of\n * the data to which it points is undefined.\n *\n * @param pkt_octet_len is a pointer to the length in octets of the\n * complete SRTCP packet (header and body) before the function call,\n * and of the complete rtp packet after the call, if err_status_ok was\n * returned.  Otherwise, the value of the data to which it points is\n * undefined.\n *\n * @return \n *    - err_status_ok          if the RTCP packet is valid.\n *    - err_status_auth_fail   if the SRTCP packet failed the message \n *                             authentication check.\n *    - err_status_replay_fail if the SRTCP packet is a replay (e.g. has\n *                             already been processed and accepted).\n *    - [other]  if there has been an error in the cryptographic mechanisms.\n *\n */\n\nerr_status_t \nsrtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len);\n\n/**\n * @}\n */\n\n/**\n * @defgroup SRTPevents SRTP events and callbacks\n * @ingroup  SRTP\n *\n * @brief libSRTP can use a user-provided callback function to \n * handle events.\n *\n * \n * libSRTP allows a user to provide a callback function to handle\n * events that need to be dealt with outside of the data plane (see\n * the enum srtp_event_t for a description of these events).  Dealing\n * with these events is not a strict necessity; they are not\n * security-critical, but the application may suffer if they are not\n * handled.  The function srtp_set_event_handler() is used to provide\n * the callback function.\n *\n * A default event handler that merely reports on the events as they\n * happen is included.  It is also possible to set the event handler\n * function to NULL, in which case all events will just be silently\n * ignored.\n *\n * @{\n */\n\n/**\n * @brief srtp_event_t defines events that need to be handled\n *\n * The enum srtp_event_t defines events that need to be handled\n * outside the `data plane', such as SSRC collisions and \n * key expirations.  \n *\n * When a key expires or the maximum number of packets has been\n * reached, an SRTP stream will enter an `expired' state in which no\n * more packets can be protected or unprotected.  When this happens,\n * it is likely that you will want to either deallocate the stream\n * (using srtp_stream_dealloc()), and possibly allocate a new one.\n *\n * When an SRTP stream expires, the other streams in the same session\n * are unaffected, unless key sharing is used by that stream.  In the\n * latter case, all of the streams in the session will expire.\n */\n\ntypedef enum { \n  event_ssrc_collision,    /**<\n\t\t\t    * An SSRC collision occured.             \n\t\t\t    */\n  event_key_soft_limit,    /**< An SRTP stream reached the soft key\n\t\t\t    *   usage limit and will expire soon.\t   \n\t\t\t    */\n  event_key_hard_limit,    /**< An SRTP stream reached the hard \n\t\t\t    *   key usage limit and has expired.\n\t\t\t    */\n  event_packet_index_limit /**< An SRTP stream reached the hard \n\t\t\t    * packet limit (2^48 packets).             \n\t\t\t    */\n} srtp_event_t;\n\n/**\n * @brief srtp_event_data_t is the structure passed as a callback to \n * the event handler function\n *\n * The struct srtp_event_data_t holds the data passed to the event\n * handler function.  \n */\n\ntypedef struct srtp_event_data_t {\n  srtp_t        session;  /**< The session in which the event happend. */\n  srtp_stream_t stream;   /**< The stream in which the event happend.  */\n  srtp_event_t  event;    /**< An enum indicating the type of event.   */\n} srtp_event_data_t;\n\n/**\n * @brief srtp_event_handler_func_t is the function prototype for\n * the event handler.\n *\n * The typedef srtp_event_handler_func_t is the prototype for the\n * event handler function.  It has as its only argument an\n * srtp_event_data_t which describes the event that needs to be handled.\n * There can only be a single, global handler for all events in\n * libSRTP.\n */\n\ntypedef void (srtp_event_handler_func_t)(srtp_event_data_t *data);\n\n/**\n * @brief sets the event handler to the function supplied by the caller.\n * \n * The function call srtp_install_event_handler(func) sets the event\n * handler function to the value func.  The value NULL is acceptable\n * as an argument; in this case, events will be ignored rather than\n * handled.\n *\n * @param func is a pointer to a fuction that takes an srtp_event_data_t\n *             pointer as an argument and returns void.  This function\n *             will be used by libSRTP to handle events.\n */\n\nerr_status_t\nsrtp_install_event_handler(srtp_event_handler_func_t func);\n\n/**\n * @}\n */\n/* in host order, so outside the #if */\n#define SRTCP_E_BIT      0x80000000\n/* for byte-access */\n#define SRTCP_E_BYTE_BIT 0x80\n#define SRTCP_INDEX_MASK 0x7fffffff\n\n#ifdef _MSC_VER\n#pragma pack()\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* SRTP_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/include/srtp_priv.h",
    "content": "/*\n * srtp_priv.h\n *\n * private internal data structures and functions for libSRTP\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#ifndef SRTP_PRIV_H\n#define SRTP_PRIV_H\n\n#include \"srtp.h\"\n#include \"rdbx.h\"\n#include \"rdb.h\"\n#include \"integers.h\"\n\n/*\n * an srtp_hdr_t represents the srtp header\n *\n * in this implementation, an srtp_hdr_t is assumed to be 32-bit aligned\n * \n * (note that this definition follows that of RFC 1889 Appendix A, but\n * is not identical)\n */\n \n#ifdef _MSC_VER\r\n#   pragma warning(push)\r\n#   pragma warning(disable:4214) // bit field types other than int\r\n#endif\n\n#ifndef WORDS_BIGENDIAN\n\n/*\n * srtp_hdr_t represents an RTP or SRTP header.  The bit-fields in\n * this structure should be declared \"unsigned int\" instead of \n * \"unsigned char\", but doing so causes the MS compiler to not\n * fully pack the bit fields.\n */\ntypedef struct {\n  unsigned char cc:4;\t/* CSRC count             */\n  unsigned char x:1;\t/* header extension flag  */\n  unsigned char p:1;\t/* padding flag           */\n  unsigned char version:2; /* protocol version    */\n  unsigned char pt:7;\t/* payload type           */\n  unsigned char m:1;\t/* marker bit             */\n  uint16_t seq;\t\t/* sequence number        */\n  uint32_t ts;\t\t/* timestamp              */\n  uint32_t ssrc;\t/* synchronization source */\n} srtp_hdr_t;\n\n#else /*  BIG_ENDIAN */\n\ntypedef struct {\n  unsigned char version:2; /* protocol version    */\n  unsigned char p:1;\t/* padding flag           */\n  unsigned char x:1;\t/* header extension flag  */\n  unsigned char cc:4;\t/* CSRC count             */\n  unsigned char m:1;\t/* marker bit             */\n  unsigned pt:7;\t/* payload type           */\n  uint16_t seq;\t\t/* sequence number        */\n  uint32_t ts;\t\t/* timestamp              */\n  uint32_t ssrc;\t/* synchronization source */\n} srtp_hdr_t;\n\n#endif\n\r\n\ntypedef struct {\n  uint16_t profile_specific;    /* profile-specific info               */\n  uint16_t length;              /* number of 32-bit words in extension */\n} srtp_hdr_xtnd_t;\n\n\n/*\n * srtcp_hdr_t represents a secure rtcp header \n *\n * in this implementation, an srtcp header is assumed to be 32-bit\n * alinged\n */\n\n#ifndef WORDS_BIGENDIAN\n\ntypedef struct {\n  unsigned char rc:5;\t\t/* reception report count */\n  unsigned char p:1;\t\t/* padding flag           */\n  unsigned char version:2;\t/* protocol version       */\n  unsigned char pt:8;\t\t/* payload type           */\n  uint16_t len;\t\t\t/* length                 */\n  uint32_t ssrc;\t       \t/* synchronization source */\n} srtcp_hdr_t;\n\ntypedef struct {\n  unsigned int index:31;    /* srtcp packet index in network order! */\n  unsigned int e:1;         /* encrypted? 1=yes */\n  /* optional mikey/etc go here */\n  /* and then the variable-length auth tag */\n} srtcp_trailer_t;\n\n\n#else /*  BIG_ENDIAN */\n\ntypedef struct {\n  unsigned char version:2;\t/* protocol version       */\n  unsigned char p:1;\t\t/* padding flag           */\n  unsigned char rc:5;\t\t/* reception report count */\n  unsigned char pt:8;\t\t/* payload type           */\n  uint16_t len;\t\t\t/* length                 */\n  uint32_t ssrc;\t       \t/* synchronization source */\n} srtcp_hdr_t;\n\ntypedef struct {\n  unsigned int version:2;  /* protocol version                     */\n  unsigned int p:1;        /* padding flag                         */\n  unsigned int count:5;    /* varies by packet type                */\n  unsigned int pt:8;       /* payload type                         */\n  uint16_t length;         /* len of uint32s of packet less header */\n} rtcp_common_t;\n\ntypedef struct {\n  unsigned int e:1;         /* encrypted? 1=yes */\n  unsigned int index:31;    /* srtcp packet index */\n  /* optional mikey/etc go here */\n  /* and then the variable-length auth tag */\n} srtcp_trailer_t;\n\n#endif\n\n\n#ifdef _MSC_VER\r\n#   pragma warning( pop ) \n#endif\n\n\n/*\n * the following declarations are libSRTP internal functions \n */\n\n/*\n * srtp_get_stream(ssrc) returns a pointer to the stream corresponding\n * to ssrc, or NULL if no stream exists for that ssrc\n */\n\nsrtp_stream_t \nsrtp_get_stream(srtp_t srtp, uint32_t ssrc);\n\n\n/*\n * srtp_stream_init_keys(s, k) (re)initializes the srtp_stream_t s by\n * deriving all of the needed keys using the KDF and the key k.\n */\n\n\nerr_status_t\nsrtp_stream_init_keys(srtp_stream_t srtp, const void *key);\n\n/*\n * libsrtp internal datatypes \n */\n\ntypedef enum direction_t { \n  dir_unknown       = 0,\n  dir_srtp_sender   = 1, \n  dir_srtp_receiver = 2\n} direction_t;\n\n/* \n * an srtp_stream_t has its own SSRC, encryption key, authentication\n * key, sequence number, and replay database\n * \n * note that the keys might not actually be unique, in which case the\n * cipher_t and auth_t pointers will point to the same structures\n */\n\ntypedef struct srtp_stream_ctx_t {\n  uint32_t   ssrc;\n  cipher_t  *rtp_cipher;\n  auth_t    *rtp_auth;\n  rdbx_t     rtp_rdbx;\n  sec_serv_t rtp_services;\n  cipher_t  *rtcp_cipher;\n  auth_t    *rtcp_auth;\n  rdb_t      rtcp_rdb;\n  sec_serv_t rtcp_services;\n  key_limit_ctx_t *limit;\n  direction_t direction;\n  struct srtp_stream_ctx_t *next;   /* linked list of streams */\n} srtp_stream_ctx_t;\n\n\n/*\n * an srtp_ctx_t holds a stream list and a service description\n */\n\ntypedef struct srtp_ctx_t {\n  srtp_stream_ctx_t *stream_list;     /* linked list of streams            */\n  srtp_stream_ctx_t *stream_template; /* act as template for other streams */\n} srtp_ctx_t;\n\n\n\n/*\n * srtp_handle_event(srtp, srtm, evnt) calls the event handling\n * function, if there is one.\n *\n * This macro is not included in the documentation as it is \n * an internal-only function.\n */\n\n#define srtp_handle_event(srtp, strm, evnt)         \\\n   if(srtp_event_handler) {                         \\\n      srtp_event_data_t data;                       \\\n      data.session = srtp;                          \\\n      data.stream  = strm;                          \\\n      data.event   = evnt;                          \\\n      srtp_event_handler(&data);                    \\\n}   \n\n\n#endif /* SRTP_PRIV_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/include/ut_sim.h",
    "content": "/*\n * ut-sim.h\n *\n * an unreliable transport simulator\n * (for testing replay databases and suchlike)\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n\n#ifndef UT_SIM_H\n#define UT_SIM_H\n\n#include \"integers.h\"  /* for uint32_t */\n\n#define UT_BUF 160      /* maximum amount of packet reorder */\n\ntypedef struct {\n  uint32_t index;\n  uint32_t buffer[UT_BUF];\n} ut_connection;\n\n/*\n * ut_init(&u) initializes the ut_connection \n *\n * this function should always be the first one called on a new\n * ut_connection\n */\n\nvoid\nut_init(ut_connection *utc);\n\n/*\n * ut_next_index(&u) returns the next index from the simulated\n * unreliable connection\n */\n\nuint32_t\nut_next_index(ut_connection *utc);\n\n\n#endif /* UT_SIM_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/install-sh",
    "content": "#!/bin/sh\n\n# install - install a program, script, or datafile\n# This comes from X11R5 (mit/util/scripts/install.sh).\n#\n# Copyright 1991 by the Massachusetts Institute of Technology\n#\n# Permission to use, copy, modify, distribute, and sell this software and its\n# documentation for any purpose is hereby granted without fee, provided that\n# the above copyright notice appear in all copies and that both that\n# copyright notice and this permission notice appear in supporting\n# documentation, and that the name of M.I.T. not be used in advertising or\n# publicity pertaining to distribution of the software without specific,\n# written prior permission.  M.I.T. makes no representations about the\n# suitability of this software for any purpose.  It is provided \"as is\"\n# without express or implied warranty.\n#\n# Calling this script install-sh is preferred over install.sh, to prevent\n# `make' implicit rules from creating a file called install from it\n# when there is no Makefile.\n#\n# This script is compatible with the BSD install script, but was written\n# from scratch.  It can only install one file at a time, a restriction\n# shared with many OS's install programs.\n\n\n# set DOITPROG to echo to test this script\n\n# Don't use :- since 4.3BSD and earlier shells don't like it.\ndoit=\"${DOITPROG-}\"\n\n\n# put in absolute paths if you don't have them in your path; or use env. vars.\n\nmvprog=\"${MVPROG-mv}\"\ncpprog=\"${CPPROG-cp}\"\nchmodprog=\"${CHMODPROG-chmod}\"\nchownprog=\"${CHOWNPROG-chown}\"\nchgrpprog=\"${CHGRPPROG-chgrp}\"\nstripprog=\"${STRIPPROG-strip}\"\nrmprog=\"${RMPROG-rm}\"\nmkdirprog=\"${MKDIRPROG-mkdir}\"\n\ntransformbasename=\"\"\ntransform_arg=\"\"\ninstcmd=\"$mvprog\"\nchmodcmd=\"$chmodprog 0755\"\nchowncmd=\"\"\nchgrpcmd=\"\"\nstripcmd=\"\"\nrmcmd=\"$rmprog -f\"\nmvcmd=\"$mvprog\"\nsrc=\"\"\ndst=\"\"\ndir_arg=\"\"\n\nwhile [ x\"$1\" != x ]; do\n    case $1 in\n\t-c) instcmd=\"$cpprog\"\n\t    shift\n\t    continue;;\n\n\t-d) dir_arg=true\n\t    shift\n\t    continue;;\n\n\t-m) chmodcmd=\"$chmodprog $2\"\n\t    shift\n\t    shift\n\t    continue;;\n\n\t-o) chowncmd=\"$chownprog $2\"\n\t    shift\n\t    shift\n\t    continue;;\n\n\t-g) chgrpcmd=\"$chgrpprog $2\"\n\t    shift\n\t    shift\n\t    continue;;\n\n\t-s) stripcmd=\"$stripprog\"\n\t    shift\n\t    continue;;\n\n\t-t=*) transformarg=`echo $1 | sed 's/-t=//'`\n\t    shift\n\t    continue;;\n\n\t-b=*) transformbasename=`echo $1 | sed 's/-b=//'`\n\t    shift\n\t    continue;;\n\n\t*)  if [ x\"$src\" = x ]\n\t    then\n\t\tsrc=$1\n\t    else\n\t\t# this colon is to work around a 386BSD /bin/sh bug\n\t\t:\n\t\tdst=$1\n\t    fi\n\t    shift\n\t    continue;;\n    esac\ndone\n\nif [ x\"$src\" = x ]\nthen\n\techo \"install:\tno input file specified\"\n\texit 1\nelse\n\ttrue\nfi\n\nif [ x\"$dir_arg\" != x ]; then\n\tdst=$src\n\tsrc=\"\"\n\t\n\tif [ -d $dst ]; then\n\t\tinstcmd=:\n\t\tchmodcmd=\"\"\n\telse\n\t\tinstcmd=mkdir\n\tfi\nelse\n\n# Waiting for this to be detected by the \"$instcmd $src $dsttmp\" command\n# might cause directories to be created, which would be especially bad \n# if $src (and thus $dsttmp) contains '*'.\n\n\tif [ -f $src -o -d $src ]\n\tthen\n\t\ttrue\n\telse\n\t\techo \"install:  $src does not exist\"\n\t\texit 1\n\tfi\n\t\n\tif [ x\"$dst\" = x ]\n\tthen\n\t\techo \"install:\tno destination specified\"\n\t\texit 1\n\telse\n\t\ttrue\n\tfi\n\n# If destination is a directory, append the input filename; if your system\n# does not like double slashes in filenames, you may need to add some logic\n\n\tif [ -d $dst ]\n\tthen\n\t\tdst=\"$dst\"/`basename $src`\n\telse\n\t\ttrue\n\tfi\nfi\n\n## this sed command emulates the dirname command\ndstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`\n\n# Make sure that the destination directory exists.\n#  this part is taken from Noah Friedman's mkinstalldirs script\n\n# Skip lots of stat calls in the usual case.\nif [ ! -d \"$dstdir\" ]; then\ndefaultIFS='\t\n'\nIFS=\"${IFS-${defaultIFS}}\"\n\noIFS=\"${IFS}\"\n# Some sh's can't handle IFS=/ for some reason.\nIFS='%'\nset - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`\nIFS=\"${oIFS}\"\n\npathcomp=''\n\nwhile [ $# -ne 0 ] ; do\n\tpathcomp=\"${pathcomp}${1}\"\n\tshift\n\n\tif [ ! -d \"${pathcomp}\" ] ;\n        then\n\t\t$mkdirprog \"${pathcomp}\"\n\telse\n\t\ttrue\n\tfi\n\n\tpathcomp=\"${pathcomp}/\"\ndone\nfi\n\nif [ x\"$dir_arg\" != x ]\nthen\n\t$doit $instcmd $dst &&\n\n\tif [ x\"$chowncmd\" != x ]; then $doit $chowncmd $dst; else true ; fi &&\n\tif [ x\"$chgrpcmd\" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&\n\tif [ x\"$stripcmd\" != x ]; then $doit $stripcmd $dst; else true ; fi &&\n\tif [ x\"$chmodcmd\" != x ]; then $doit $chmodcmd $dst; else true ; fi\nelse\n\n# If we're going to rename the final executable, determine the name now.\n\n\tif [ x\"$transformarg\" = x ] \n\tthen\n\t\tdstfile=`basename $dst`\n\telse\n\t\tdstfile=`basename $dst $transformbasename | \n\t\t\tsed $transformarg`$transformbasename\n\tfi\n\n# don't allow the sed command to completely eliminate the filename\n\n\tif [ x\"$dstfile\" = x ] \n\tthen\n\t\tdstfile=`basename $dst`\n\telse\n\t\ttrue\n\tfi\n\n# Make a temp file name in the proper directory.\n\n\tdsttmp=$dstdir/#inst.$$#\n\n# Move or copy the file name to the temp name\n\n\t$doit $instcmd $src $dsttmp &&\n\n\ttrap \"rm -f ${dsttmp}\" 0 &&\n\n# and set any options; do chmod last to preserve setuid bits\n\n# If any of these fail, we abort the whole thing.  If we want to\n# ignore errors from any of these, just make sure not to ignore\n# errors from the above \"$doit $instcmd $src $dsttmp\" command.\n\n\tif [ x\"$chowncmd\" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&\n\tif [ x\"$chgrpcmd\" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&\n\tif [ x\"$stripcmd\" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&\n\tif [ x\"$chmodcmd\" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&\n\n# Now rename the file to the real destination.\n\n\t$doit $rmcmd -f $dstdir/$dstfile &&\n\t$doit $mvcmd $dsttmp $dstdir/$dstfile \n\nfi &&\n\n\nexit 0\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/pjlib/srtp_err.c",
    "content": "/* $Id: srtp_err.c 1907 2008-04-03 22:03:14Z bennylp $ */\n/* \n * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA \n */\n#include \"err.h\"\n#include <pj/log.h>\n\n/* Redirect libsrtp error to PJ_LOG */\n\nerr_reporting_level_t err_level = err_level_none;\n\nerr_status_t\nerr_reporting_init(char *ident) {\n    return err_status_ok;\n}\n\nvoid\nerr_report(int priority, char *format, ...) {\n  va_list args;\n\n#if PJ_LOG_MAX_LEVEL >= 1\n  if (priority <= err_level) {\n\n    va_start(args, format);\n    pj_log(\"libsrtp\", priority, format, args);\n    va_end(args);\n  }\n#endif\n}\n\nvoid\nerr_reporting_set_level(err_reporting_level_t lvl) { \n  err_level = lvl;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/srtp/srtp.c",
    "content": "/*\n * srtp.c\n *\n * the secure real-time transport protocol\n *\n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright (c) 2001-2006, Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n\n#include \"srtp_priv.h\"\n#include \"aes_icm.h\"         /* aes_icm is used in the KDF  */\n#include \"alloc.h\"           /* for crypto_alloc()          */\n\n#ifndef SRTP_KERNEL\n# include <limits.h>\n# ifdef HAVE_NETINET_IN_H\n#  include <netinet/in.h>\n# elif defined(HAVE_WINSOCK2_H)\n#  include <winsock2.h>\n# endif\n#endif /* ! SRTP_KERNEL */\n\n\nextern cipher_type_t aes_icm;\nextern auth_type_t   tmmhv2;\n\n/* the debug module for srtp */\n\ndebug_module_t mod_srtp = {\n  0,                  /* debugging is off by default */\n  \"srtp\"              /* printable name for module   */\n};\n\n#define octets_in_rtp_header   12\n#define uint32s_in_rtp_header  3\n#define octets_in_rtcp_header  8\n#define uint32s_in_rtcp_header 2\n\n\nerr_status_t\nsrtp_stream_alloc(srtp_stream_ctx_t **str_ptr,\n\t\t  const srtp_policy_t *p) {\n  srtp_stream_ctx_t *str;\n  err_status_t stat;\n\n  /*\n   * This function allocates the stream context, rtp and rtcp ciphers\n   * and auth functions, and key limit structure.  If there is a\n   * failure during allocation, we free all previously allocated\n   * memory and return a failure code.  The code could probably \n   * be improved, but it works and should be clear.\n   */\n\n  /* allocate srtp stream and set str_ptr */\n  str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t));\n  if (str == NULL)\n    return err_status_alloc_fail;\n  *str_ptr = str;  \n  \n  /* allocate cipher */\n  stat = crypto_kernel_alloc_cipher(p->rtp.cipher_type, \n\t\t\t\t    &str->rtp_cipher, \n\t\t\t\t    p->rtp.cipher_key_len); \n  if (stat) {\n    crypto_free(str);\n    return stat;\n  }\n\n  /* allocate auth function */\n  stat = crypto_kernel_alloc_auth(p->rtp.auth_type, \n\t\t\t\t  &str->rtp_auth,\n\t\t\t\t  p->rtp.auth_key_len, \n\t\t\t\t  p->rtp.auth_tag_len); \n  if (stat) {\n    cipher_dealloc(str->rtp_cipher);\n    crypto_free(str);\n    return stat;\n  }\n  \n  /* allocate key limit structure */\n  str->limit = (key_limit_ctx_t*) crypto_alloc(sizeof(key_limit_ctx_t));\n  if (str->limit == NULL) {\n    auth_dealloc(str->rtp_auth);\n    cipher_dealloc(str->rtp_cipher);\n    crypto_free(str); \n    return err_status_alloc_fail;\n  }\n\n  /*\n   * ...and now the RTCP-specific initialization - first, allocate\n   * the cipher \n   */\n  stat = crypto_kernel_alloc_cipher(p->rtcp.cipher_type, \n\t\t\t\t    &str->rtcp_cipher, \n\t\t\t\t    p->rtcp.cipher_key_len); \n  if (stat) {\n    auth_dealloc(str->rtp_auth);\n    cipher_dealloc(str->rtp_cipher);\n    crypto_free(str->limit);\n    crypto_free(str);\n    return stat;\n  }\n\n  /* allocate auth function */\n  stat = crypto_kernel_alloc_auth(p->rtcp.auth_type, \n\t\t\t\t  &str->rtcp_auth,\n\t\t\t\t  p->rtcp.auth_key_len, \n\t\t\t\t  p->rtcp.auth_tag_len); \n  if (stat) {\n    cipher_dealloc(str->rtcp_cipher);\n    auth_dealloc(str->rtp_auth);\n    cipher_dealloc(str->rtp_cipher);\n    crypto_free(str->limit);\n    crypto_free(str);\n   return stat;\n  }  \n\n  return err_status_ok;\n}\n\nerr_status_t\nsrtp_stream_dealloc(srtp_t session, srtp_stream_ctx_t *stream) { \n  err_status_t status;\n  \n  /*\n   * we use a conservative deallocation strategy - if any deallocation\n   * fails, then we report that fact without trying to deallocate\n   * anything else\n   */\n\n  /* deallocate cipher, if it is not the same as that in template */\n  if (session->stream_template\n      && stream->rtp_cipher == session->stream_template->rtp_cipher) {\n    /* do nothing */\n  } else {\n    status = cipher_dealloc(stream->rtp_cipher); \n    if (status) \n      return status;\n  }\n\n  /* deallocate auth function, if it is not the same as that in template */\n  if (session->stream_template\n      && stream->rtp_auth == session->stream_template->rtp_auth) {\n    /* do nothing */\n  } else {\n    status = auth_dealloc(stream->rtp_auth);\n    if (status)\n      return status;\n  }\n\n  /* deallocate key usage limit, if it is not the same as that in template */\n  if (session->stream_template\n      && stream->limit == session->stream_template->limit) {\n    /* do nothing */\n  } else {\n    crypto_free(stream->limit);\n  }   \n\n  /* \n   * deallocate rtcp cipher, if it is not the same as that in\n   * template \n   */\n  if (session->stream_template\n      && stream->rtcp_cipher == session->stream_template->rtcp_cipher) {\n    /* do nothing */\n  } else {\n    status = cipher_dealloc(stream->rtcp_cipher); \n    if (status) \n      return status;\n  }\n\n  /*\n   * deallocate rtcp auth function, if it is not the same as that in\n   * template \n   */\n  if (session->stream_template\n      && stream->rtcp_auth == session->stream_template->rtcp_auth) {\n    /* do nothing */\n  } else {\n    status = auth_dealloc(stream->rtcp_auth);\n    if (status)\n      return status;\n  }\n  \n  /* deallocate srtp stream context */\n  crypto_free(stream);\n\n  return err_status_ok;\n}\n\n\n/*\n * srtp_stream_clone(stream_template, new) allocates a new stream and\n * initializes it using the cipher and auth of the stream_template\n * \n * the only unique data in a cloned stream is the replay database and\n * the SSRC\n */\n\nerr_status_t\nsrtp_stream_clone(const srtp_stream_ctx_t *stream_template, \n\t\t  uint32_t ssrc, \n\t\t  srtp_stream_ctx_t **str_ptr) {\n  err_status_t status;\n  srtp_stream_ctx_t *str;\n\n  debug_print(mod_srtp, \"cloning stream (SSRC: 0x%08x)\", ssrc);\n\n  /* allocate srtp stream and set str_ptr */\n  str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t));\n  if (str == NULL)\n    return err_status_alloc_fail;\n  *str_ptr = str;  \n\n  /* set cipher and auth pointers to those of the template */\n  str->rtp_cipher  = stream_template->rtp_cipher;\n  str->rtp_auth    = stream_template->rtp_auth;\n  str->rtcp_cipher = stream_template->rtcp_cipher;\n  str->rtcp_auth   = stream_template->rtcp_auth;\n\n  /* set key limit to point to that of the template */\n  status = key_limit_clone(stream_template->limit, &str->limit);\n  if (status) \n    return status;\n\n  /* initialize replay databases */\n  rdbx_init(&str->rtp_rdbx);\n  rdb_init(&str->rtcp_rdb);\n  \n  /* set ssrc to that provided */\n  str->ssrc = ssrc;\n\n  /* set direction and security services */\n  str->direction     = stream_template->direction;\n  str->rtp_services  = stream_template->rtp_services;\n  str->rtcp_services = stream_template->rtcp_services;\n\n  /* defensive coding */\n  str->next = NULL;\n\n  return err_status_ok;\n}\n\n\n/*\n * key derivation functions, internal to libSRTP\n *\n * srtp_kdf_t is a key derivation context\n *\n * srtp_kdf_init(&kdf, k) initializes kdf with the key k\n * \n * srtp_kdf_generate(&kdf, l, kl, keylen) derives the key\n * corresponding to label l and puts it into kl; the length\n * of the key in octets is provided as keylen.  this function\n * should be called once for each subkey that is derived.\n *\n * srtp_kdf_clear(&kdf) zeroizes the kdf state\n */\n\ntypedef enum {\n  label_rtp_encryption  = 0x00,\n  label_rtp_msg_auth    = 0x01,\n  label_rtp_salt        = 0x02,\n  label_rtcp_encryption = 0x03,\n  label_rtcp_msg_auth   = 0x04,\n  label_rtcp_salt       = 0x05\n} srtp_prf_label;\n\n\n/*\n * srtp_kdf_t represents a key derivation function.  The SRTP\n * default KDF is the only one implemented at present.\n */\n\ntypedef struct { \n  aes_icm_ctx_t c;    /* cipher used for key derivation  */  \n} srtp_kdf_t;\n\nerr_status_t\nsrtp_kdf_init(srtp_kdf_t *kdf, const uint8_t key[30]) {\n\n  aes_icm_context_init(&kdf->c, key);\n\n  return err_status_ok;\n}\n\nerr_status_t\nsrtp_kdf_generate(srtp_kdf_t *kdf, srtp_prf_label label,\n\t\t  uint8_t *key, int length) {\n\n  v128_t nonce;\n  \n  /* set eigth octet of nonce to <label>, set the rest of it to zero */\n  v128_set_to_zero(&nonce);\n  nonce.v8[7] = label;\n \n  aes_icm_set_iv(&kdf->c, &nonce);  \n  \n  /* generate keystream output */\n  aes_icm_output(&kdf->c, key, length);\n\n  return err_status_ok;\n}\n\nerr_status_t\nsrtp_kdf_clear(srtp_kdf_t *kdf) {\n  \n  /* zeroize aes context */\n  octet_string_set_to_zero((uint8_t *)kdf, sizeof(srtp_kdf_t));\n\n  return err_status_ok;  \n}\n\n/*\n *  end of key derivation functions \n */\n\n#define MAX_SRTP_KEY_LEN 256\n\n\nerr_status_t\nsrtp_stream_init_keys(srtp_stream_ctx_t *srtp, const void *key) {\n  err_status_t stat;\n  srtp_kdf_t kdf;\n  uint8_t tmp_key[MAX_SRTP_KEY_LEN];\n  \n  /* initialize KDF state     */\n  srtp_kdf_init(&kdf, (const uint8_t *)key);\n  \n  /* generate encryption key  */\n  srtp_kdf_generate(&kdf, label_rtp_encryption, \n\t\t    tmp_key, cipher_get_key_length(srtp->rtp_cipher));\n  /* \n   * if the cipher in the srtp context is aes_icm, then we need\n   * to generate the salt value\n   */\n  if (srtp->rtp_cipher->type == &aes_icm) {\n    /* FIX!!! this is really the cipher key length; rest is salt */\n    int base_key_len = 16;\n    int salt_len = cipher_get_key_length(srtp->rtp_cipher) - base_key_len;\n    \n    debug_print(mod_srtp, \"found aes_icm, generating salt\", NULL);\n\n    /* generate encryption salt, put after encryption key */\n    srtp_kdf_generate(&kdf, label_rtp_salt, \n\t\t      tmp_key + base_key_len, salt_len);\n  }\n  debug_print(mod_srtp, \"cipher key: %s\", \n\t      octet_string_hex_string(tmp_key, \n\t\t      cipher_get_key_length(srtp->rtp_cipher)));  \n\n  /* initialize cipher */\n  stat = cipher_init(srtp->rtp_cipher, tmp_key, direction_any);\n  if (stat) {\n    /* zeroize temp buffer */\n    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);\n    return err_status_init_fail;\n  }\n\n  /* generate authentication key */\n  srtp_kdf_generate(&kdf, label_rtp_msg_auth,\n\t\t    tmp_key, auth_get_key_length(srtp->rtp_auth));\n  debug_print(mod_srtp, \"auth key:   %s\",\n\t      octet_string_hex_string(tmp_key, \n\t\t\t\t      auth_get_key_length(srtp->rtp_auth))); \n\n  /* initialize auth function */\n  stat = auth_init(srtp->rtp_auth, tmp_key);\n  if (stat) {\n    /* zeroize temp buffer */\n    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);\n    return err_status_init_fail;\n  }\n\n  /*\n   * ...now initialize SRTCP keys\n   */\n\n  /* generate encryption key  */\n  srtp_kdf_generate(&kdf, label_rtcp_encryption, \n\t\t    tmp_key, cipher_get_key_length(srtp->rtcp_cipher));\n  /* \n   * if the cipher in the srtp context is aes_icm, then we need\n   * to generate the salt value\n   */\n  if (srtp->rtcp_cipher->type == &aes_icm) {\n    /* FIX!!! this is really the cipher key length; rest is salt */\n    int base_key_len = 16;\n    int salt_len = cipher_get_key_length(srtp->rtcp_cipher) - base_key_len;\n\n    debug_print(mod_srtp, \"found aes_icm, generating rtcp salt\", NULL);\n\n    /* generate encryption salt, put after encryption key */\n    srtp_kdf_generate(&kdf, label_rtcp_salt, \n\t\t      tmp_key + base_key_len, salt_len);\n  }\n  debug_print(mod_srtp, \"rtcp cipher key: %s\", \n\t      octet_string_hex_string(tmp_key, \n\t\t   cipher_get_key_length(srtp->rtcp_cipher)));  \n\n  /* initialize cipher */\n  stat = cipher_init(srtp->rtcp_cipher, tmp_key, direction_any);\n  if (stat) {\n    /* zeroize temp buffer */\n    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);\n    return err_status_init_fail;\n  }\n\n  /* generate authentication key */\n  srtp_kdf_generate(&kdf, label_rtcp_msg_auth,\n\t\t    tmp_key, auth_get_key_length(srtp->rtcp_auth));\n  debug_print(mod_srtp, \"rtcp auth key:   %s\",\n\t      octet_string_hex_string(tmp_key, \n\t\t     auth_get_key_length(srtp->rtcp_auth))); \n\n  /* initialize auth function */\n  stat = auth_init(srtp->rtcp_auth, tmp_key);\n  if (stat) {\n    /* zeroize temp buffer */\n    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);\n    return err_status_init_fail;\n  }\n\n  /* clear memory then return */\n  srtp_kdf_clear(&kdf);\n  octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);  \n\n  return err_status_ok;\n}\n\nerr_status_t\nsrtp_stream_init(srtp_stream_ctx_t *srtp, \n\t\t  const srtp_policy_t *p) {\n  err_status_t err;\n\n   debug_print(mod_srtp, \"initializing stream (SSRC: 0x%08x)\", \n\t       p->ssrc.value);\n\n   /* initialize replay database */\n   rdbx_init(&srtp->rtp_rdbx);\n\n   /* initialize key limit to maximum value */\n#ifdef NO_64BIT_MATH\n{\n   uint64_t temp;\n   temp = make64(UINT_MAX,UINT_MAX);\n   key_limit_set(srtp->limit, temp);\n}\n#else\n   key_limit_set(srtp->limit, PJ_UINT64(0xffffffffffff));\n#endif\n\n   /* set the SSRC value */\n   srtp->ssrc = htonl(p->ssrc.value);\n\n   /* set the security service flags */\n   srtp->rtp_services  = p->rtp.sec_serv;\n   srtp->rtcp_services = p->rtcp.sec_serv;\n\n   /*\n    * set direction to unknown - this flag gets checked in srtp_protect(),\n    * srtp_unprotect(), srtp_protect_rtcp(), and srtp_unprotect_rtcp(), and \n    * gets set appropriately if it is set to unknown.\n    */\n   srtp->direction = dir_unknown;\n\n   /* initialize SRTCP replay database */\n   rdb_init(&srtp->rtcp_rdb);\n\n   /* DAM - no RTCP key limit at present */\n\n   /* initialize keys */\n   err = srtp_stream_init_keys(srtp, p->key);\n   if (err) return err;\n\n   return err_status_ok;  \n }\n\n\n /*\n  * srtp_event_reporter is an event handler function that merely\n  * reports the events that are reported by the callbacks\n  */\n\n void\n srtp_event_reporter(srtp_event_data_t *data) {\n\n   err_report(err_level_warning, \"srtp: in stream 0x%x: \", \n\t      data->stream->ssrc);\n\n   switch(data->event) {\n   case event_ssrc_collision:\n     err_report(err_level_warning, \"\\tSSRC collision\\n\");\n     break;\n   case event_key_soft_limit:\n     err_report(err_level_warning, \"\\tkey usage soft limit reached\\n\");\n     break;\n   case event_key_hard_limit:\n     err_report(err_level_warning, \"\\tkey usage hard limit reached\\n\");\n     break;\n   case event_packet_index_limit:\n     err_report(err_level_warning, \"\\tpacket index limit reached\\n\");\n     break;\n   default:\n     err_report(err_level_warning, \"\\tunknown event reported to handler\\n\");\n   }\n }\n\n /*\n  * srtp_event_handler is a global variable holding a pointer to the\n  * event handler function; this function is called for any unexpected\n  * event that needs to be handled out of the SRTP data path.  see\n  * srtp_event_t in srtp.h for more info\n  *\n  * it is okay to set srtp_event_handler to NULL, but we set \n  * it to the srtp_event_reporter.\n  */\n\n static srtp_event_handler_func_t *srtp_event_handler = srtp_event_reporter;\n\n err_status_t\n srtp_install_event_handler(srtp_event_handler_func_t func) {\n\n   /* \n    * note that we accept NULL arguments intentionally - calling this\n    * function with a NULL arguments removes an event handler that's\n    * been previously installed\n    */\n\n   /* set global event handling function */\n   srtp_event_handler = func;\n   return err_status_ok;\n }\n\n err_status_t\n srtp_protect(srtp_ctx_t *ctx, void *rtp_hdr, int *pkt_octet_len) {\n   srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;\n   uint32_t *enc_start;        /* pointer to start of encrypted portion  */\n   uint32_t *auth_start;       /* pointer to start of auth. portion      */\n   unsigned enc_octet_len = 0; /* number of octets in encrypted portion  */\n   xtd_seq_num_t est;          /* estimated xtd_seq_num_t of *hdr        */\n   int delta;                  /* delta of local pkt idx and that in hdr */\n   uint8_t *auth_tag = NULL;   /* location of auth_tag within packet     */\n   err_status_t status;   \n   int tag_len;\n   srtp_stream_ctx_t *stream;\n   int prefix_len;\n\n   debug_print(mod_srtp, \"function srtp_protect\", NULL);\n\n  /* we assume the hdr is 32-bit aligned to start */\n\n   /* check the packet length - it must at least contain a full header */\n   if (*pkt_octet_len < octets_in_rtp_header)\n     return err_status_bad_param;\n\n   /*\n    * look up ssrc in srtp_stream list, and process the packet with\n    * the appropriate stream.  if we haven't seen this stream before,\n    * there's a template key for this srtp_session, and the cipher\n    * supports key-sharing, then we assume that a new stream using\n    * that key has just started up\n    */\n   stream = srtp_get_stream(ctx, hdr->ssrc);\n   if (stream == NULL) {\n     if (ctx->stream_template != NULL) {\n       srtp_stream_ctx_t *new_stream;\n\n       /* allocate and initialize a new stream */\n       status = srtp_stream_clone(ctx->stream_template, \n\t\t\t\t  hdr->ssrc, &new_stream); \n       if (status)\n\t return status;\n\n       /* add new stream to the head of the stream_list */\n       new_stream->next = ctx->stream_list;\n       ctx->stream_list = new_stream;\n\n       /* set direction to outbound */\n       new_stream->direction = dir_srtp_sender;\n\n       /* set stream (the pointer used in this function) */\n       stream = new_stream;\n     } else {\n       /* no template stream, so we return an error */\n       return err_status_no_ctx;\n     } \n   }\n\n   /* \n    * verify that stream is for sending traffic - this check will\n    * detect SSRC collisions, since a stream that appears in both\n    * srtp_protect() and srtp_unprotect() will fail this test in one of\n    * those functions.\n    */\n   if (stream->direction != dir_srtp_sender) {\n     if (stream->direction == dir_unknown) {\n       stream->direction = dir_srtp_sender;\n     } else {\n       srtp_handle_event(ctx, stream, event_ssrc_collision);\n     }\n   }\n\n  /* \n   * update the key usage limit, and check it to make sure that we\n   * didn't just hit either the soft limit or the hard limit, and call\n   * the event handler if we hit either.\n   */\n  switch(key_limit_update(stream->limit)) {\n  case key_event_normal:\n    break;\n  case key_event_soft_limit: \n    srtp_handle_event(ctx, stream, event_key_soft_limit);\n    break; \n  case key_event_hard_limit:\n    srtp_handle_event(ctx, stream, event_key_hard_limit);\n\treturn err_status_key_expired;\n  default:\n    break;\n  }\n\n   /* get tag length from stream */\n   tag_len = auth_get_tag_length(stream->rtp_auth); \n\n   /*\n    * find starting point for encryption and length of data to be\n    * encrypted - the encrypted portion starts after the rtp header\n    * extension, if present; otherwise, it starts after the last csrc,\n    * if any are present\n    *\n    * if we're not providing confidentiality, set enc_start to NULL\n    */\n   if (stream->rtp_services & sec_serv_conf) {\n     enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;  \n     if (hdr->x == 1) {\n       srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;\n       enc_start += (ntohs(xtn_hdr->length) + 1);\n     }\n     enc_octet_len = (unsigned int)(*pkt_octet_len \n\t\t\t\t    - ((enc_start - (uint32_t *)hdr) << 2));\n   } else {\n     enc_start = NULL;\n   }\n\n   /* \n    * if we're providing authentication, set the auth_start and auth_tag\n    * pointers to the proper locations; otherwise, set auth_start to NULL\n    * to indicate that no authentication is needed\n    */\n   if (stream->rtp_services & sec_serv_auth) {\n     auth_start = (uint32_t *)hdr;\n     auth_tag = (uint8_t *)hdr + *pkt_octet_len;\n   } else {\n     auth_start = NULL;\n     auth_tag = NULL;\n   }\n\n   /*\n    * estimate the packet index using the start of the replay window   \n    * and the sequence number from the header\n    */\n   delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));\n   status = rdbx_check(&stream->rtp_rdbx, delta);\n   if (status)\n     return status;  /* we've been asked to reuse an index */\n   rdbx_add_index(&stream->rtp_rdbx, delta);\n\n#ifdef NO_64BIT_MATH\n   debug_print2(mod_srtp, \"estimated packet index: %08x%08x\", \n\t\thigh32(est),low32(est));\n#else\n   debug_print(mod_srtp, \"estimated packet index: %016llx\", est);\n#endif\n\n   /* \n    * if we're using rindael counter mode, set nonce and seq \n    */\n   if (stream->rtp_cipher->type == &aes_icm) {\n     v128_t iv;\n\n     iv.v32[0] = 0;\n     iv.v32[1] = hdr->ssrc;\n#ifdef NO_64BIT_MATH\n     iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),\n\t\t\t\t\t\t\t\t low32(est) << 16));\n#else\n     iv.v64[1] = be64_to_cpu(est << 16);\n#endif\n     status = cipher_set_iv(stream->rtp_cipher, &iv);\n\n   } else {  \n     v128_t iv;\n\n     /* otherwise, set the index to est */  \n#ifdef NO_64BIT_MATH\n     iv.v32[0] = 0;\n     iv.v32[1] = 0;\n#else\n     iv.v64[0] = 0;\n#endif\n     iv.v64[1] = be64_to_cpu(est);\n     status = cipher_set_iv(stream->rtp_cipher, &iv);\n   }\n   if (status)\n     return err_status_cipher_fail;\n\n   /* shift est, put into network byte order */\n#ifdef NO_64BIT_MATH\n   est = be64_to_cpu(make64((high32(est) << 16) |\n\t\t\t\t\t\t (low32(est) >> 16),\n\t\t\t\t\t\t low32(est) << 16));\n#else\n   est = be64_to_cpu(est << 16);\n#endif\n   \n   /* \n    * if we're authenticating using a universal hash, put the keystream\n    * prefix into the authentication tag\n    */\n   if (auth_start) {\n     \n    prefix_len = auth_get_prefix_length(stream->rtp_auth);    \n    if (prefix_len) {\n      status = cipher_output(stream->rtp_cipher, auth_tag, prefix_len);\n      if (status)\n\treturn err_status_cipher_fail;\n      debug_print(mod_srtp, \"keystream prefix: %s\", \n\t\t  octet_string_hex_string(auth_tag, prefix_len));\n    }\n  }\n\n  /* if we're encrypting, exor keystream into the message */\n  if (enc_start) {\n    status = cipher_encrypt(stream->rtp_cipher, \n\t\t\t    (uint8_t *)enc_start, &enc_octet_len);\n    if (status)\n      return err_status_cipher_fail;\n  }\n\n  /*\n   *  if we're authenticating, run authentication function and put result\n   *  into the auth_tag \n   */\n  if (auth_start) {        \n\n    /* initialize auth func context */\n    status = auth_start(stream->rtp_auth);\n    if (status) return status;\n\n    /* run auth func over packet */\n    status = auth_update(stream->rtp_auth, \n\t\t\t (uint8_t *)auth_start, *pkt_octet_len);\n    if (status) return status;\n    \n    /* run auth func over ROC, put result into auth_tag */\n    debug_print(mod_srtp, \"estimated packet index: %016llx\", est);\n    status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, auth_tag); \n    debug_print(mod_srtp, \"srtp auth tag:    %s\", \n\t\toctet_string_hex_string(auth_tag, tag_len));\n    if (status)\n      return err_status_auth_fail;   \n\n  }\n\n  if (auth_tag) {\n\n    /* increase the packet length by the length of the auth tag */\n    *pkt_octet_len += tag_len;\n  }\n\n  return err_status_ok;  \n}\n\n\nerr_status_t\nsrtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {\n  srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr;\n  uint32_t *enc_start;      /* pointer to start of encrypted portion  */\n  uint32_t *auth_start;     /* pointer to start of auth. portion      */\n  unsigned enc_octet_len = 0;/* number of octets in encrypted portion */\n  uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */\n  xtd_seq_num_t est;        /* estimated xtd_seq_num_t of *hdr        */\n  int delta;                /* delta of local pkt idx and that in hdr */\n  v128_t iv;\n  err_status_t status;\n  srtp_stream_ctx_t *stream;\n  uint8_t tmp_tag[SRTP_MAX_TAG_LEN];\n  int tag_len, prefix_len;\n\n  debug_print(mod_srtp, \"function srtp_unprotect\", NULL);\n\n  /* we assume the hdr is 32-bit aligned to start */\n\n  /* check the packet length - it must at least contain a full header */\n  if (*pkt_octet_len < octets_in_rtp_header)\n    return err_status_bad_param;\n\n  /*\n   * look up ssrc in srtp_stream list, and process the packet with \n   * the appropriate stream.  if we haven't seen this stream before,\n   * there's only one key for this srtp_session, and the cipher\n   * supports key-sharing, then we assume that a new stream using\n   * that key has just started up\n   */\n  stream = srtp_get_stream(ctx, hdr->ssrc);\n  if (stream == NULL) {\n    if (ctx->stream_template != NULL) {\n      stream = ctx->stream_template;\n      debug_print(mod_srtp, \"using provisional stream (SSRC: 0x%08x)\",\n\t\t  hdr->ssrc);\n      \n      /* \n       * set estimated packet index to sequence number from header,\n       * and set delta equal to the same value\n       */\n#ifdef NO_64BIT_MATH\n      est = (xtd_seq_num_t) make64(0,ntohs(hdr->seq));\n      delta = low32(est);\n#else\n      est = (xtd_seq_num_t) ntohs(hdr->seq);\n      delta = (int)est;\n#endif\n    } else {\n      \n      /*\n       * no stream corresponding to SSRC found, and we don't do\n       * key-sharing, so return an error\n       */\n      return err_status_no_ctx;\n    }\n  } else {\n  \n    /* estimate packet index from seq. num. in header */\n    delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));\n    \n    /* check replay database */\n    status = rdbx_check(&stream->rtp_rdbx, delta);\n    if (status)\n      return status;\n  }\n\n#ifdef NO_64BIT_MATH\n  debug_print2(mod_srtp, \"estimated u_packet index: %08x%08x\", high32(est),low32(est));\n#else\n  debug_print(mod_srtp, \"estimated u_packet index: %016llx\", est);\n#endif\n\n  /* get tag length from stream */\n  tag_len = auth_get_tag_length(stream->rtp_auth); \n\n  /* \n   * set the cipher's IV properly, depending on whatever cipher we\n   * happen to be using\n   */\n  if (stream->rtp_cipher->type == &aes_icm) {\n\n    /* aes counter mode */\n    iv.v32[0] = 0;\n    iv.v32[1] = hdr->ssrc;  /* still in network order */\n#ifdef NO_64BIT_MATH\n    iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),\n\t\t\t         low32(est) << 16));\n#else\n    iv.v64[1] = be64_to_cpu(est << 16);\n#endif\n    status = aes_icm_set_iv((aes_icm_ctx_t*)stream->rtp_cipher->state, &iv);\n  } else {  \n    \n    /* no particular format - set the iv to the pakcet index */  \n#ifdef NO_64BIT_MATH\n    iv.v32[0] = 0;\n    iv.v32[1] = 0;\n#else\n    iv.v64[0] = 0;\n#endif\n    iv.v64[1] = be64_to_cpu(est);\n    status = cipher_set_iv(stream->rtp_cipher, &iv);\n  }\n  if (status)\n    return err_status_cipher_fail;\n\n  /* shift est, put into network byte order */\n#ifdef NO_64BIT_MATH\n  est = be64_to_cpu(make64((high32(est) << 16) |\n\t\t\t\t\t    (low32(est) >> 16),\n\t\t\t\t\t    low32(est) << 16));\n#else\n  est = be64_to_cpu(est << 16);\n#endif\n\n  /*\n   * find starting point for decryption and length of data to be\n   * decrypted - the encrypted portion starts after the rtp header\n   * extension, if present; otherwise, it starts after the last csrc,\n   * if any are present\n   *\n   * if we're not providing confidentiality, set enc_start to NULL\n   */\n  if (stream->rtp_services & sec_serv_conf) {\n    enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;  \n    if (hdr->x == 1) {\n      srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;\n      enc_start += (ntohs(xtn_hdr->length) + 1);\n    }  \n    enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len \n\t\t\t       - ((enc_start - (uint32_t *)hdr) << 2));\n  } else {\n    enc_start = NULL;\n  }\n\n  /* \n   * if we're providing authentication, set the auth_start and auth_tag\n   * pointers to the proper locations; otherwise, set auth_start to NULL\n   * to indicate that no authentication is needed\n   */\n  if (stream->rtp_services & sec_serv_auth) {\n    auth_start = (uint32_t *)hdr;\n    auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len;\n  } else {\n    auth_start = NULL;\n    auth_tag = NULL;\n  } \n\n  /*\n   * if we expect message authentication, run the authentication\n   * function and compare the result with the value of the auth_tag\n   */\n  if (auth_start) {        \n\n    /* \n     * if we're using a universal hash, then we need to compute the\n     * keystream prefix for encrypting the universal hash output\n     *\n     * if the keystream prefix length is zero, then we know that\n     * the authenticator isn't using a universal hash function\n     */  \n    if (stream->rtp_auth->prefix_len != 0) {\n      \n      prefix_len = auth_get_prefix_length(stream->rtp_auth);    \n      status = cipher_output(stream->rtp_cipher, tmp_tag, prefix_len);\n      debug_print(mod_srtp, \"keystream prefix: %s\", \n\t\t  octet_string_hex_string(tmp_tag, prefix_len));\n      if (status)\n\treturn err_status_cipher_fail;\n    } \n\n    /* initialize auth func context */\n    status = auth_start(stream->rtp_auth);\n    if (status) return status;\n \n    /* now compute auth function over packet */\n    status = auth_update(stream->rtp_auth, (uint8_t *)auth_start,  \n\t\t\t *pkt_octet_len - tag_len);\n\n    /* run auth func over ROC, then write tmp tag */\n    status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag);  \n\n    debug_print(mod_srtp, \"computed auth tag:    %s\", \n\t\toctet_string_hex_string(tmp_tag, tag_len));\n    debug_print(mod_srtp, \"packet auth tag:      %s\", \n\t\toctet_string_hex_string(auth_tag, tag_len));\n    if (status)\n      return err_status_auth_fail;   \n\n    if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))\n      return err_status_auth_fail;\n  }\n\n  /* \n   * update the key usage limit, and check it to make sure that we\n   * didn't just hit either the soft limit or the hard limit, and call\n   * the event handler if we hit either.\n   */\n  switch(key_limit_update(stream->limit)) {\n  case key_event_normal:\n    break;\n  case key_event_soft_limit: \n    srtp_handle_event(ctx, stream, event_key_soft_limit);\n    break; \n  case key_event_hard_limit:\n    srtp_handle_event(ctx, stream, event_key_hard_limit);\n    return err_status_key_expired;\n  default:\n    break;\n  }\n\n  /* if we're encrypting, add keystream into ciphertext */\n  if (enc_start) {\n    status = cipher_encrypt(stream->rtp_cipher, \n\t\t\t    (uint8_t *)enc_start, &enc_octet_len);\n    if (status)\n      return err_status_cipher_fail;\n  }\n\n  /* \n   * verify that stream is for received traffic - this check will\n   * detect SSRC collisions, since a stream that appears in both\n   * srtp_protect() and srtp_unprotect() will fail this test in one of\n   * those functions.\n   *\n   * we do this check *after* the authentication check, so that the\n   * latter check will catch any attempts to fool us into thinking\n   * that we've got a collision\n   */\n  if (stream->direction != dir_srtp_receiver) {\n    if (stream->direction == dir_unknown) {\n      stream->direction = dir_srtp_receiver;\n    } else {\n      srtp_handle_event(ctx, stream, event_ssrc_collision);\n    }\n  }\n\n  /* \n   * if the stream is a 'provisional' one, in which the template context\n   * is used, then we need to allocate a new stream at this point, since\n   * the authentication passed\n   */\n  if (stream == ctx->stream_template) {  \n    srtp_stream_ctx_t *new_stream;\n\n    /* \n     * allocate and initialize a new stream \n     * \n     * note that we indicate failure if we can't allocate the new\n     * stream, and some implementations will want to not return\n     * failure here\n     */\n    status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); \n    if (status)\n      return status;\n    \n    /* add new stream to the head of the stream_list */\n    new_stream->next = ctx->stream_list;\n    ctx->stream_list = new_stream;\n    \n    /* set stream (the pointer used in this function) */\n    stream = new_stream;\n  }\n  \n  /* \n   * the message authentication function passed, so add the packet\n   * index into the replay database \n   */\n  rdbx_add_index(&stream->rtp_rdbx, delta);\n\n  /* decrease the packet length by the length of the auth tag */\n  *pkt_octet_len -= tag_len;\n\n  return err_status_ok;  \n}\n\nerr_status_t\nsrtp_init() {\n  err_status_t status;\n\n  /* initialize crypto kernel */\n  status = crypto_kernel_init();\n  if (status) \n    return status;\n\n  /* load srtp debug module into the kernel */\n  status = crypto_kernel_load_debug_module(&mod_srtp);\n  if (status)\n    return status;\n\n  return err_status_ok;\n}\n\nerr_status_t\nsrtp_deinit() {\n  err_status_t status;\n\n  status = crypto_kernel_shutdown();\n\n  return status;\n}\n\n/* \n * The following code is under consideration for removal.  See\n * SRTP_MAX_TRAILER_LEN \n */\n#if 0\n\n/*\n * srtp_get_trailer_length(&a) returns the number of octets that will\n * be added to an RTP packet by the SRTP processing.  This value\n * is constant for a given srtp_stream_t (i.e. between initializations).\n */\n\nint\nsrtp_get_trailer_length(const srtp_stream_t s) {\n  return auth_get_tag_length(s->rtp_auth);\n}\n\n#endif\n\n/*\n * srtp_get_stream(ssrc) returns a pointer to the stream corresponding\n * to ssrc, or NULL if no stream exists for that ssrc\n *\n * this is an internal function \n */\n\nsrtp_stream_ctx_t *\nsrtp_get_stream(srtp_t srtp, uint32_t ssrc) {\n  srtp_stream_ctx_t *stream;\n\n  /* walk down list until ssrc is found */\n  stream = srtp->stream_list;\n  while (stream != NULL) {\n    if (stream->ssrc == ssrc)\n      return stream;\n    stream = stream->next;\n  }\n  \n  /* we haven't found our ssrc, so return a null */\n  return NULL;\n}\n\nerr_status_t\nsrtp_dealloc(srtp_t session) {\n  srtp_stream_ctx_t *stream;\n  err_status_t status;\n\n  /*\n   * we take a conservative deallocation strategy - if we encounter an\n   * error deallocating a stream, then we stop trying to deallocate\n   * memory and just return an error\n   */\n\n  /* walk list of streams, deallocating as we go */\n  stream = session->stream_list;\n  while (stream != NULL) {\n    srtp_stream_t next = stream->next;\n    status = srtp_stream_dealloc(session, stream);\n    if (status)\n      return status;\n    stream = next;\n  }\n  \n  /* deallocate stream template, if there is one */\n  if (session->stream_template != NULL) {\n    status = auth_dealloc(session->stream_template->rtcp_auth); \n    if (status) \n      return status; \n    status = cipher_dealloc(session->stream_template->rtcp_cipher); \n    if (status) \n      return status; \n    crypto_free(session->stream_template->limit);\n    status = cipher_dealloc(session->stream_template->rtp_cipher); \n    if (status) \n      return status; \n    status = auth_dealloc(session->stream_template->rtp_auth);\n    if (status)\n      return status;\n    crypto_free(session->stream_template);\n  }\n\n  /* deallocate session context */\n  crypto_free(session);\n\n  return err_status_ok;\n}\n\n\nerr_status_t\nsrtp_add_stream(srtp_t session, \n\t\tconst srtp_policy_t *policy)  {\n  err_status_t status;\n  srtp_stream_t tmp;\n\n  /* sanity check arguments */\n  if ((session == NULL) || (policy == NULL) || (policy->key == NULL))\n    return err_status_bad_param;\n\n  /* allocate stream  */\n  status = srtp_stream_alloc(&tmp, policy);\n  if (status) {\n    return status;\n  }\n  \n  /* initialize stream  */\n  status = srtp_stream_init(tmp, policy);\n  if (status) {\n    crypto_free(tmp);\n    return status;\n  }\n  \n  /* \n   * set the head of the stream list or the template to point to the\n   * stream that we've just alloced and init'ed, depending on whether\n   * or not it has a wildcard SSRC value or not\n   *\n   * if the template stream has already been set, then the policy is\n   * inconsistent, so we return a bad_param error code\n   */\n  switch (policy->ssrc.type) {\n  case (ssrc_any_outbound):\n    if (session->stream_template) {\n      return err_status_bad_param;\n    }\n    session->stream_template = tmp;\n    session->stream_template->direction = dir_srtp_sender;\n    break;\n  case (ssrc_any_inbound):\n    if (session->stream_template) {\n      return err_status_bad_param;\n    }\n    session->stream_template = tmp;\n    session->stream_template->direction = dir_srtp_receiver;\n    break;\n  case (ssrc_specific):\n    tmp->next = session->stream_list;\n    session->stream_list = tmp;\n    break;\n  case (ssrc_undefined):\n  default:\n    crypto_free(tmp);\n    return err_status_bad_param;\n  }\n    \n  return err_status_ok;\n}\n\n\nerr_status_t\nsrtp_create(srtp_t *session,               /* handle for session     */ \n\t    const srtp_policy_t *policy) { /* SRTP policy (list)     */\n  err_status_t stat;\n  srtp_ctx_t *ctx;\n\n  /* sanity check arguments */\n  if (session == NULL)\n    return err_status_bad_param;\n\n  /* allocate srtp context and set ctx_ptr */\n  ctx = (srtp_ctx_t *) crypto_alloc(sizeof(srtp_ctx_t));\n  if (ctx == NULL)\n    return err_status_alloc_fail;\n  *session = ctx;\n\n  /* \n   * loop over elements in the policy list, allocating and\n   * initializing a stream for each element\n   */\n  ctx->stream_template = NULL;\n  ctx->stream_list = NULL;\n  while (policy != NULL) {    \n\n    stat = srtp_add_stream(ctx, policy);\n    if (stat) {\n      /* clean up everything */\n      srtp_dealloc(*session);\n      return stat;\n    }    \n\n    /* set policy to next item in list  */\n    policy = policy->next;\n  }\n\n  return err_status_ok;\n}\n\n\nerr_status_t\nsrtp_remove_stream(srtp_t session, uint32_t ssrc) {\n  srtp_stream_ctx_t *stream, *last_stream;\n  err_status_t status;\n\n  /* sanity check arguments */\n  if (session == NULL)\n    return err_status_bad_param;\n  \n  /* find stream in list; complain if not found */\n  last_stream = stream = session->stream_list;\n  while ((stream != NULL) && (ssrc != stream->ssrc)) {\n    last_stream = stream;\n    stream = stream->next;\n  }\n  if (stream == NULL)\n    return err_status_no_ctx;\n\n  /* remove stream from the list */\n  last_stream->next = stream->next;\n\n  /* deallocate the stream */\n  status = srtp_stream_dealloc(session, stream);\n  if (status)\n    return status;\n\n  return err_status_ok;\n}\n\n\n/*\n * the default policy - provides a convenient way for callers to use\n * the default security policy\n * \n * this policy is that defined in the current SRTP internet draft.\n *\n */\n\n/* \n * NOTE: cipher_key_len is really key len (128 bits) plus salt len\n *  (112 bits)\n */\n/* There are hard-coded 16's for base_key_len in the key generation code */\n\nvoid\ncrypto_policy_set_rtp_default(crypto_policy_t *p) {\n\n  p->cipher_type     = AES_128_ICM;           \n  p->cipher_key_len  = 30;                /* default 128 bits per RFC 3711 */\n  p->auth_type       = HMAC_SHA1;             \n  p->auth_key_len    = 20;                /* default 160 bits per RFC 3711 */\n  p->auth_tag_len    = 10;                /* default 80 bits per RFC 3711 */\n  p->sec_serv        = sec_serv_conf_and_auth;\n  \n}\n\nvoid\ncrypto_policy_set_rtcp_default(crypto_policy_t *p) {\n\n  p->cipher_type     = AES_128_ICM;           \n  p->cipher_key_len  = 30;                 /* default 128 bits per RFC 3711 */\n  p->auth_type       = HMAC_SHA1;             \n  p->auth_key_len    = 20;                 /* default 160 bits per RFC 3711 */\n  p->auth_tag_len    = 10;                 /* default 80 bits per RFC 3711 */\n  p->sec_serv        = sec_serv_conf_and_auth;\n  \n}\n\nvoid\ncrypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p) {\n\n  /*\n   * corresponds to draft-ietf-mmusic-sdescriptions-12.txt\n   *\n   * note that this crypto policy is intended for SRTP, but not SRTCP\n   */\n\n  p->cipher_type     = AES_128_ICM;           \n  p->cipher_key_len  = 30;                /* 128 bit key, 112 bit salt */\n  p->auth_type       = HMAC_SHA1;             \n  p->auth_key_len    = 20;                /* 160 bit key               */\n  p->auth_tag_len    = 4;                 /* 32 bit tag                */\n  p->sec_serv        = sec_serv_conf_and_auth;\n  \n}\n\n\nvoid\ncrypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p) {\n\n  /*\n   * corresponds to draft-ietf-mmusic-sdescriptions-12.txt\n   *\n   * note that this crypto policy is intended for SRTP, but not SRTCP\n   */\n\n  p->cipher_type     = AES_128_ICM;           \n  p->cipher_key_len  = 30;                /* 128 bit key, 112 bit salt */\n  p->auth_type       = NULL_AUTH;             \n  p->auth_key_len    = 0; \n  p->auth_tag_len    = 0; \n  p->sec_serv        = sec_serv_conf;\n  \n}\n\n\nvoid\ncrypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p) {\n\n  /*\n   * corresponds to draft-ietf-mmusic-sdescriptions-12.txt\n   */\n\n  p->cipher_type     = NULL_CIPHER;           \n  p->cipher_key_len  = 0;\n  p->auth_type       = HMAC_SHA1;             \n  p->auth_key_len    = 20; \n  p->auth_tag_len    = 10; \n  p->sec_serv        = sec_serv_auth;\n  \n}\n\n\n/* \n * secure rtcp functions\n */\n\nerr_status_t \nsrtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) {\n  srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;\n  uint32_t *enc_start;      /* pointer to start of encrypted portion  */\n  uint32_t *auth_start;     /* pointer to start of auth. portion      */\n  uint32_t *trailer;        /* pointer to start of trailer            */\n  unsigned enc_octet_len = 0;/* number of octets in encrypted portion */\n  uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */\n  err_status_t status;   \n  int tag_len;\n  srtp_stream_ctx_t *stream;\n  int prefix_len;\n  uint32_t seq_num;\n\n  /* we assume the hdr is 32-bit aligned to start */\n  /*\n   * look up ssrc in srtp_stream list, and process the packet with \n   * the appropriate stream.  if we haven't seen this stream before,\n   * there's only one key for this srtp_session, and the cipher\n   * supports key-sharing, then we assume that a new stream using\n   * that key has just started up\n   */\n  stream = srtp_get_stream(ctx, hdr->ssrc);\n  if (stream == NULL) {\n    if (ctx->stream_template != NULL) {\n      srtp_stream_ctx_t *new_stream;\n      \n      /* allocate and initialize a new stream */\n      status = srtp_stream_clone(ctx->stream_template,\n\t\t\t\t hdr->ssrc, &new_stream); \n      if (status)\n\treturn status;\n      \n      /* add new stream to the head of the stream_list */\n      new_stream->next = ctx->stream_list;\n      ctx->stream_list = new_stream;\n      \n      /* set stream (the pointer used in this function) */\n      stream = new_stream;\n    } else {\n      /* no template stream, so we return an error */\n      return err_status_no_ctx;\n    } \n  }\n  \n  /* \n   * verify that stream is for sending traffic - this check will\n   * detect SSRC collisions, since a stream that appears in both\n   * srtp_protect() and srtp_unprotect() will fail this test in one of\n   * those functions.\n   */\n  if (stream->direction != dir_srtp_sender) {\n    if (stream->direction == dir_unknown) {\n      stream->direction = dir_srtp_sender;\n    } else {\n      srtp_handle_event(ctx, stream, event_ssrc_collision);\n    }\n  }  \n\n  /* get tag length from stream context */\n  tag_len = auth_get_tag_length(stream->rtcp_auth); \n\n  /*\n   * set encryption start and encryption length - if we're not\n   * providing confidentiality, set enc_start to NULL\n   */\n  enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;  \n  enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;\n\n  /* all of the packet, except the header, gets encrypted */\n  /* NOTE: hdr->length is not usable - it refers to only the first\n\t RTCP report in the compound packet! */\n  /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always\n\t multiples of 32-bits (RFC 3550 6.1) */\n  trailer = (uint32_t *) ((char *)enc_start + enc_octet_len);\n\n  if (stream->rtcp_services & sec_serv_conf) {\n    *trailer = htonl(SRTCP_E_BIT);     /* set encrypt bit */    \n  } else {\n    enc_start = NULL;\n    enc_octet_len = 0;\n\t/* 0 is network-order independant */\n    *trailer = 0x00000000;     /* set encrypt bit */    \n  }\n\n  /* \n   * set the auth_start and auth_tag pointers to the proper locations\n   * (note that srtpc *always* provides authentication, unlike srtp)\n   */\n  /* Note: This would need to change for optional mikey data */\n  auth_start = (uint32_t *)hdr;\n  auth_tag = (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t); \n\n  /* \n   * check sequence number for overruns, and copy it into the packet\n   * if its value isn't too big\n   */\n  status = rdb_increment(&stream->rtcp_rdb);\n  if (status)\n    return status;\n  seq_num = rdb_get_value(&stream->rtcp_rdb);\n  *trailer |= htonl(seq_num);\n  debug_print(mod_srtp, \"srtcp index: %x\", seq_num);\n\n  /* \n   * if we're using rindael counter mode, set nonce and seq \n   */\n  if (stream->rtcp_cipher->type == &aes_icm) {\n    v128_t iv;\n    \n    iv.v32[0] = 0;\n    iv.v32[1] = hdr->ssrc;  /* still in network order! */\n    iv.v32[2] = htonl(seq_num >> 16);\n    iv.v32[3] = htonl(seq_num << 16);\n    status = aes_icm_set_iv((aes_icm_ctx_t*)stream->rtcp_cipher->state, &iv);\n\n  } else {  \n    v128_t iv;\n    \n    /* otherwise, just set the index to seq_num */  \n    iv.v32[0] = 0;\n    iv.v32[1] = 0;\n    iv.v32[2] = 0;\n    iv.v32[3] = htonl(seq_num);\n    status = cipher_set_iv(stream->rtcp_cipher, &iv);\n  }\n  if (status)\n    return err_status_cipher_fail;\n\n  /* \n   * if we're authenticating using a universal hash, put the keystream\n   * prefix into the authentication tag\n   */\n  \n  /* if auth_start is non-null, then put keystream into tag  */\n  if (auth_start) {\n\n    /* put keystream prefix into auth_tag */\n    prefix_len = auth_get_prefix_length(stream->rtcp_auth);    \n    status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);\n\n    debug_print(mod_srtp, \"keystream prefix: %s\", \n\t\toctet_string_hex_string(auth_tag, prefix_len));\n\n    if (status)\n      return err_status_cipher_fail;\n  }\n\n  /* if we're encrypting, exor keystream into the message */\n  if (enc_start) {\n    status = cipher_encrypt(stream->rtcp_cipher, \n\t\t\t    (uint8_t *)enc_start, &enc_octet_len);\n    if (status)\n      return err_status_cipher_fail;\n  }\n\n  /* initialize auth func context */\n  auth_start(stream->rtcp_auth);\n\n  /* \n   * run auth func over packet (including trailer), and write the\n   * result at auth_tag \n   */\n  status = auth_compute(stream->rtcp_auth, \n\t\t\t(uint8_t *)auth_start, \n\t\t\t(*pkt_octet_len) + sizeof(srtcp_trailer_t), \n\t\t\tauth_tag);\n  debug_print(mod_srtp, \"srtcp auth tag:    %s\", \n\t      octet_string_hex_string(auth_tag, tag_len));\n  if (status)\n    return err_status_auth_fail;   \n    \n  /* increase the packet length by the length of the auth tag and seq_num*/\n  *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));\n    \n  return err_status_ok;  \n}\n\n\nerr_status_t \nsrtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len) {\n  srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;\n  uint32_t *enc_start;      /* pointer to start of encrypted portion  */\n  uint32_t *auth_start;     /* pointer to start of auth. portion      */\n  uint32_t *trailer;        /* pointer to start of trailer            */\n  unsigned enc_octet_len = 0;/* number of octets in encrypted portion */\n  uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */\n  uint8_t tmp_tag[SRTP_MAX_TAG_LEN];\n  err_status_t status;   \n  int tag_len;\n  srtp_stream_ctx_t *stream;\n  int prefix_len;\n  uint32_t seq_num;\n\n  /* we assume the hdr is 32-bit aligned to start */\n  /*\n   * look up ssrc in srtp_stream list, and process the packet with \n   * the appropriate stream.  if we haven't seen this stream before,\n   * there's only one key for this srtp_session, and the cipher\n   * supports key-sharing, then we assume that a new stream using\n   * that key has just started up\n   */\n  stream = srtp_get_stream(ctx, hdr->ssrc);\n  if (stream == NULL) {\n    if (ctx->stream_template != NULL) {\n      stream = ctx->stream_template;\n      debug_print(mod_srtp, \"srtcp using provisional stream (SSRC: 0x%08x)\", \n\t\t  hdr->ssrc);\n    } else {\n      /* no template stream, so we return an error */\n      return err_status_no_ctx;\n    } \n  }\n  \n  /* get tag length from stream context */\n  tag_len = auth_get_tag_length(stream->rtcp_auth); \n\n  /*\n   * set encryption start, encryption length, and trailer\n   */\n  enc_octet_len = *pkt_octet_len - \n                  (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t));\n  /* index & E (encryption) bit follow normal data.  hdr->len\n\t is the number of words (32-bit) in the normal packet minus 1 */\n  /* This should point trailer to the word past the end of the\n\t normal data. */\n  /* This would need to be modified for optional mikey data */\n  /*\n   * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always\n   *\t multiples of 32-bits (RFC 3550 6.1)\n   */\n  trailer = (uint32_t *) ((char *) hdr +\n\t\t     *pkt_octet_len -(tag_len + sizeof(srtcp_trailer_t)));\n  if (*((unsigned char *) trailer) & SRTCP_E_BYTE_BIT) {\n    enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;  \n  } else {\n    enc_octet_len = 0;\n    enc_start = NULL; /* this indicates that there's no encryption */\n  }\n\n  /* \n   * set the auth_start and auth_tag pointers to the proper locations\n   * (note that srtcp *always* uses authentication, unlike srtp)\n   */\n  auth_start = (uint32_t *)hdr;\n  auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len;\n\n  /* \n   * check the sequence number for replays\n   */\n  /* this is easier than dealing with bitfield access */\n  seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;\n  debug_print(mod_srtp, \"srtcp index: %x\", seq_num);\n  status = rdb_check(&stream->rtcp_rdb, seq_num);\n  if (status)\n    return status;\n\n  /* \n   * if we're using aes counter mode, set nonce and seq \n   */\n  if (stream->rtcp_cipher->type == &aes_icm) {\n    v128_t iv;\n\n    iv.v32[0] = 0;\n    iv.v32[1] = hdr->ssrc; /* still in network order! */\n    iv.v32[2] = htonl(seq_num >> 16);\n    iv.v32[3] = htonl(seq_num << 16);\n    status = aes_icm_set_iv((aes_icm_ctx_t*)stream->rtcp_cipher->state, &iv);\n\n  } else {  \n    v128_t iv;\n    \n    /* otherwise, just set the index to seq_num */  \n    iv.v32[0] = 0;\n    iv.v32[1] = 0;\n    iv.v32[2] = 0;\n    iv.v32[3] = htonl(seq_num);\n    status = cipher_set_iv(stream->rtcp_cipher, &iv);\n\n  }\n  if (status)\n    return err_status_cipher_fail;\n\n  /* initialize auth func context */\n  auth_start(stream->rtcp_auth);\n\n  /* run auth func over packet, put result into tmp_tag */\n  status = auth_compute(stream->rtcp_auth, (uint8_t *)auth_start,  \n\t\t\t*pkt_octet_len - tag_len,\n\t\t\ttmp_tag);\n  debug_print(mod_srtp, \"srtcp computed tag:       %s\", \n\t      octet_string_hex_string(tmp_tag, tag_len));\n  if (status)\n    return err_status_auth_fail;   \n  \n  /* compare the tag just computed with the one in the packet */\n  debug_print(mod_srtp, \"srtcp tag from packet:    %s\", \n\t      octet_string_hex_string(auth_tag, tag_len));  \n  if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))\n    return err_status_auth_fail;\n\n  /* \n   * if we're authenticating using a universal hash, put the keystream\n   * prefix into the authentication tag\n   */\n  prefix_len = auth_get_prefix_length(stream->rtcp_auth);    \n  if (prefix_len) {\n    status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);\n    debug_print(mod_srtp, \"keystream prefix: %s\", \n\t\toctet_string_hex_string(auth_tag, prefix_len));\n    if (status)\n      return err_status_cipher_fail;\n  }\n\n  /* if we're decrypting, exor keystream into the message */\n  if (enc_start) {\n    status = cipher_encrypt(stream->rtcp_cipher, \n\t\t\t    (uint8_t *)enc_start, &enc_octet_len);\n    if (status)\n      return err_status_cipher_fail;\n  }\n\n  /* decrease the packet length by the length of the auth tag and seq_num*/\n  *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));\n\n  /* \n   * verify that stream is for received traffic - this check will\n   * detect SSRC collisions, since a stream that appears in both\n   * srtp_protect() and srtp_unprotect() will fail this test in one of\n   * those functions.\n   *\n   * we do this check *after* the authentication check, so that the\n   * latter check will catch any attempts to fool us into thinking\n   * that we've got a collision\n   */\n  if (stream->direction != dir_srtp_receiver) {\n    if (stream->direction == dir_unknown) {\n      stream->direction = dir_srtp_receiver;\n    } else {\n      srtp_handle_event(ctx, stream, event_ssrc_collision);\n    }\n  }\n\n  /* \n   * if the stream is a 'provisional' one, in which the template context\n   * is used, then we need to allocate a new stream at this point, since\n   * the authentication passed\n   */\n  if (stream == ctx->stream_template) {  \n    srtp_stream_ctx_t *new_stream;\n\n    /* \n     * allocate and initialize a new stream \n     * \n     * note that we indicate failure if we can't allocate the new\n     * stream, and some implementations will want to not return\n     * failure here\n     */\n    status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); \n    if (status)\n      return status;\n    \n    /* add new stream to the head of the stream_list */\n    new_stream->next = ctx->stream_list;\n    ctx->stream_list = new_stream;\n    \n    /* set stream (the pointer used in this function) */\n    stream = new_stream;\n  }\n\n  /* we've passed the authentication check, so add seq_num to the rdb */\n  rdb_add_index(&stream->rtcp_rdb, seq_num);\n    \n    \n  return err_status_ok;  \n}\n\n\n\n/*\n * dtls keying for srtp \n */\n\nerr_status_t\ncrypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy, \n\t\t\t\t       srtp_profile_t profile) {\n\n  /* set SRTP policy from the SRTP profile in the key set */\n  switch(profile) {\n  case srtp_profile_aes128_cm_sha1_80:\n    crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);\n    break;\n  case srtp_profile_aes128_cm_sha1_32:\n    crypto_policy_set_aes_cm_128_hmac_sha1_32(policy);\n    break;\n  case srtp_profile_null_sha1_80:\n    crypto_policy_set_null_cipher_hmac_sha1_80(policy);\n    break;\n    /* the following profiles are not (yet) supported */\n  case srtp_profile_null_sha1_32:\n  case srtp_profile_aes256_cm_sha1_80:\n  case srtp_profile_aes256_cm_sha1_32:\n  default:\n    return err_status_bad_param;\n  }\n\n  return err_status_ok;\n}\n\nerr_status_t\ncrypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy, \n\t\t\t\t\tsrtp_profile_t profile) {\n\n  /* set SRTP policy from the SRTP profile in the key set */\n  switch(profile) {\n  case srtp_profile_aes128_cm_sha1_80:\n    crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);\n    break;\n  case srtp_profile_aes128_cm_sha1_32:\n    crypto_policy_set_aes_cm_128_hmac_sha1_32(policy);\n    break;\n  case srtp_profile_null_sha1_80:\n    crypto_policy_set_null_cipher_hmac_sha1_80(policy);\n    break;\n    /* the following profiles are not (yet) supported */\n  case srtp_profile_null_sha1_32:\n  case srtp_profile_aes256_cm_sha1_80:\n  case srtp_profile_aes256_cm_sha1_32:\n  default:\n    return err_status_bad_param;\n  }\n\n  return err_status_ok;\n}\n\nvoid\nappend_salt_to_key(uint8_t *key, unsigned int bytes_in_key,\n\t\t   uint8_t *salt, unsigned int bytes_in_salt) {\n\n  memcpy(key + bytes_in_key, salt, bytes_in_salt);\n\n}\n\nunsigned int\nsrtp_profile_get_master_key_length(srtp_profile_t profile) {\n\n  switch(profile) {\n  case srtp_profile_aes128_cm_sha1_80:\n    return 16;\n    break;\n  case srtp_profile_aes128_cm_sha1_32:\n    return 16;\n    break;\n  case srtp_profile_null_sha1_80:\n    return 16;\n    break;\n    /* the following profiles are not (yet) supported */\n  case srtp_profile_null_sha1_32:\n  case srtp_profile_aes256_cm_sha1_80:\n  case srtp_profile_aes256_cm_sha1_32:\n  default:\n    return 0;  /* indicate error by returning a zero */\n  }\n}\n\nunsigned int\nsrtp_profile_get_master_salt_length(srtp_profile_t profile) {\n\n  switch(profile) {\n  case srtp_profile_aes128_cm_sha1_80:\n    return 14;\n    break;\n  case srtp_profile_aes128_cm_sha1_32:\n    return 14;\n    break;\n  case srtp_profile_null_sha1_80:\n    return 14;\n    break;\n    /* the following profiles are not (yet) supported */\n  case srtp_profile_null_sha1_32:\n  case srtp_profile_aes256_cm_sha1_80:\n  case srtp_profile_aes256_cm_sha1_32:\n  default:\n    return 0;  /* indicate error by returning a zero */\n  }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/srtp.def",
    "content": "EXPORTS\nsrtp_init\nsrtp_protect\nsrtp_unprotect\nsrtp_create\nsrtp_add_stream\nsrtp_remove_stream\ncrypto_policy_set_rtp_default\ncrypto_policy_set_rtcp_default\ncrypto_policy_set_aes_cm_128_hmac_sha1_32\ncrypto_policy_set_aes_cm_128_null_auth\ncrypto_policy_set_null_cipher_hmac_sha1_80\nsrtp_dealloc\nsrtp_get_stream\nsrtp_protect_rtcp\nsrtp_unprotect_rtcp\nsrtp_install_event_handler\ncrypto_kernel_init\ncrypto_kernel_shutdown\ncrypto_kernel_status\ncrypto_kernel_list_debug_modules\ncrypto_kernel_load_cipher_type\ncrypto_kernel_load_auth_type\ncrypto_kernel_load_debug_module\ncrypto_kernel_alloc_cipher\ncrypto_kernel_alloc_auth\ncrypto_kernel_set_debug_module\ncrypto_get_random\nrand_source_init\nrand_source_get_octet_string\nrand_source_deinit\nx917_prng_init\nx917_prng_get_octet_string\nctr_prng_init\nctr_prng_get_octet_string\ncipher_output\ncipher_get_key_length\ncipher_type_self_test\ncipher_bits_per_second\nauth_get_key_length\nauth_get_tag_length\nauth_get_prefix_length\nauth_type_self_test\nauth_type_get_ref_count\nstat_test_monobit\nstat_test_poker\nstat_test_runs\nstat_test_rand_source\nstat_test_rand_source_with_repetition\nerr_reporting_init\nerr_report\nkey_limit_set\nkey_limit_clone\nkey_limit_check\nkey_limit_update\nrdbx_init\nrdbx_estimate_index\nrdbx_check\nrdbx_add_index\nindex_init\nindex_advance\nindex_guess\noctet_get_weight\noctet_string_hex_string\nv128_bit_string\nv128_hex_string\nnibble_to_hex_char\nhex_string_to_octet_string\nv128_copy_octet_string\nv128_left_shift\nv128_right_shift\noctet_string_is_eq\noctet_string_set_to_zero\nrdb_init\nrdb_check\nrdb_add_index\nrdb_increment\nrdb_get_value\naes_expand_encryption_key\naes_expand_decryption_key\naes_encrypt\naes_decrypt\naes_icm_context_init\naes_icm_set_iv\naes_icm_encrypt\naes_icm_output\naes_icm_dealloc\naes_icm_encrypt_ismacryp\naes_icm_alloc_ismacryp\ncrypto_alloc\ncrypto_free\n\\ No newline at end of file"
  },
  {
    "path": "deps/pjsip/third_party/srtp/srtp7.sln",
    "content": "Microsoft Visual Studio Solution File, Format Version 8.00\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"libSRTP\", \"srtp7.vcproj\", \"{7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\tEndProjectSection\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfiguration) = preSolution\r\n\t\tDebug = Debug\r\n\t\tRelease = Release\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfiguration) = postSolution\r\n\t\t{7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Debug.Build.0 = Debug|Win32\r\n\t\t{7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Release.ActiveCfg = Release|Win32\r\n\t\t{7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Release.Build.0 = Release|Win32\r\n\tEndGlobalSection\r\n\tGlobalSection(ExtensibilityGlobals) = postSolution\r\n\tEndGlobalSection\r\n\tGlobalSection(ExtensibilityAddIns) = postSolution\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/tables/aes_tables.c",
    "content": "/*\n * aes_tables.c\n * \n * generate tables for the AES cipher\n * \n * David A. McGrew\n * Cisco Systems, Inc.\n */\n/*\n *\t\n * Copyright(c) 2001-2006 Cisco Systems, Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * \n *   Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * \n *   Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * \n *   Neither the name of the Cisco Systems, Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n * OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n#include <stdio.h>\n#include \"gf2_8.h\"\n#include \"crypto_math.h\"\n\n\nunsigned char aes_sbox[256];\n\nunsigned char aes_inv_sbox[256];\n\nuint32_t T0[256], T1[256], T2[256], T3[256], T4[256]; \n\n\n#define AES_INVERSE_TEST 0  /* set to 1 to test forward/backwards aes */\n\n/* functions for precomputing AES values */\n\n/*\n * A[] is the 8 x 8 binary matrix (represented as an array of columns,\n * where each column is an octet) which defines the affine\n * transformation used in the AES substitution table (Section\n * 4.2.1 of the spec).\n */\n\nuint8_t A[8] = { 31, 62, 124, 248, 241, 227, 199, 143 };\n\n/*\n * b is the 8 bit vector (represented as an octet) used in the affine\n * transform described above.\n */\n\nuint8_t b = 99;\n\n\nvoid\naes_init_sbox(void) {\n  unsigned int i;\n  uint8_t x;\n  \n  for (i=0; i < 256; i++) {\n    x = gf2_8_compute_inverse((gf2_8)i);\n    x = A_times_x_plus_b(A, x, b);\n    aes_sbox[i] = x;\n    aes_inv_sbox[x] = i;\n  }\n}\n\nvoid\naes_compute_tables(void) {\n  int i;\n  uint32_t x1, x2, x3;\n  v32_t tmp;\n\n  /* initialize substitution table */\n  aes_init_sbox();\n\n  /* combine sbox with linear operations to form 8-bit to 32-bit tables */\n  for (i=0; i < 256; i++) {\n    x1 = aes_sbox[i];\n    x2 = gf2_8_shift(x1);\n    x3 = x2 ^ x1;\n\n    tmp.v8[0] = x2;\n    tmp.v8[1] = x1;\n    tmp.v8[2] = x1;\n    tmp.v8[3] = x3;\n    T0[i] = tmp.value;\n\n    tmp.v8[0] = x3;\n    tmp.v8[1] = x2;\n    tmp.v8[2] = x1;\n    tmp.v8[3] = x1;\n    T1[i] = tmp.value;\n     \n    tmp.v8[0] = x1;\n    tmp.v8[1] = x3;\n    tmp.v8[2] = x2;\n    tmp.v8[3] = x1;\n    T2[i] = tmp.value;\n\n    tmp.v8[0] = x1;\n    tmp.v8[1] = x1;\n    tmp.v8[2] = x3;\n    tmp.v8[3] = x2;\n    T3[i] = tmp.value;\n     \n  }\n}\n\n\n/*\n * the tables U0, U1, U2, U3 implement the aes operations invSubBytes,\n * invMixColumns, and invShiftRows \n */\n\nuint32_t U0[256], U1[256], U2[256], U3[256], U4[256];\n\nextern uint8_t aes_inv_sbox[256];\n\nvoid\naes_compute_inv_tables(void) {\n  int i;\n  uint8_t x, xe, x9, xd, xb;\n  v32_t tmp;\n\n  /* combine sbox with linear operations to form 8-bit to 32-bit tables */\n  for (i=0; i < 256; i++) {\n     x = aes_inv_sbox[i];\n\n     xe = gf2_8_multiply(0x0e, x);     \n     x9 = gf2_8_multiply(0x09, x);     \n     xd = gf2_8_multiply(0x0d, x);     \n     xb = gf2_8_multiply(0x0b, x);     \n\n     tmp.v8[0] = xe;\n     tmp.v8[1] = x9;\n     tmp.v8[2] = xd;\n     tmp.v8[3] = xb;\n     U0[i] = tmp.value;\n\n     tmp.v8[0] = xb;\n     tmp.v8[1] = xe;\n     tmp.v8[2] = x9;\n     tmp.v8[3] = xd;\n     U1[i] = tmp.value;\n     \n     tmp.v8[0] = xd;\n     tmp.v8[1] = xb;\n     tmp.v8[2] = xe;\n     tmp.v8[3] = x9;\n     U2[i] = tmp.value;\n\n     tmp.v8[0] = x9;\n     tmp.v8[1] = xd;\n     tmp.v8[2] = xb;\n     tmp.v8[3] = xe;\n     U3[i] = tmp.value;\n\n     tmp.v8[0] = tmp.v8[1] = tmp.v8[2] = tmp.v8[3] = x;\n     U4[i] = tmp.value;\n   }\n}\n\n\n/*\n * aes_test_inverse() returns err_status_ok if aes\n * encryption and decryption are true inverses of each other, and\n * returns err_status_algo_fail otherwise\n */\n\n#include \"err.h\"\n\nerr_status_t\naes_test_inverse(void);\n\n#define TABLES_32BIT 1\n\nint\nmain(void) {\n  int i;\n\n  aes_init_sbox();\n  aes_compute_inv_tables();\n\n#if TABLES_32BIT\n  printf(\"uint32_t U0 = {\");\n  for (i=0; i < 256; i++) {\n    if ((i % 4) == 0)\n      printf(\"\\n\");\n    printf(\"0x%0x, \", U0[i]);\n  }\n  printf(\"\\n}\\n\");\n\n printf(\"uint32_t U1 = {\");\n  for (i=0; i < 256; i++) {\n    if ((i % 4) == 0)\n      printf(\"\\n\");\n    printf(\"0x%x, \", U1[i]);\n  }\n  printf(\"\\n}\\n\");\n\n printf(\"uint32_t U2 = {\");\n  for (i=0; i < 256; i++) {\n    if ((i % 4) == 0)\n      printf(\"\\n\");\n    printf(\"0x%x, \", U2[i]);\n  }\n  printf(\"\\n}\\n\");\n\n printf(\"uint32_t U3 = {\");\n  for (i=0; i < 256; i++) {\n    if ((i % 4) == 0)\n      printf(\"\\n\");\n    printf(\"0x%x, \", U3[i]);\n  }\n  printf(\"\\n}\\n\");\n\n printf(\"uint32_t U4 = {\");\n for (i=0; i < 256; i++) {\n    if ((i % 4) == 0)\n      printf(\"\\n\");\n    printf(\"0x%x, \", U4[i]);\n  }\n  printf(\"\\n}\\n\");\n\n#else\n\n  printf(\"uint32_t U0 = {\");\n  for (i=0; i < 256; i++) {\n    if ((i % 4) == 0)\n      printf(\"\\n\");\n    printf(\"0x%lx, \", U0[i]);\n  }\n  printf(\"\\n}\\n\");\n\n printf(\"uint32_t U1 = {\");\n  for (i=0; i < 256; i++) {\n    if ((i % 4) == 0)\n      printf(\"\\n\");\n    printf(\"0x%lx, \", U1[i]);\n  }\n  printf(\"\\n}\\n\");\n\n printf(\"uint32_t U2 = {\");\n  for (i=0; i < 256; i++) {\n    if ((i % 4) == 0)\n      printf(\"\\n\");\n    printf(\"0x%lx, \", U2[i]);\n  }\n  printf(\"\\n}\\n\");\n\n printf(\"uint32_t U3 = {\");\n  for (i=0; i < 256; i++) {\n    if ((i % 4) == 0)\n      printf(\"\\n\");\n    printf(\"0x%lx, \", U3[i]);\n  }\n  printf(\"\\n}\\n\");\n\n printf(\"uint32_t U4 = {\");\n for (i=0; i < 256; i++) {\n    if ((i % 4) == 0)\n      printf(\"\\n\");\n    printf(\"0x%lx, \", U4[i]);\n  }\n  printf(\"\\n}\\n\");\n\n\n#endif /* TABLES_32BIT */\n\n\n#if AES_INVERSE_TEST\n  /* \n   * test that aes_encrypt and aes_decrypt are actually\n   * inverses of each other \n   */\n    \n  printf(\"aes inverse test: \");\n  if (aes_test_inverse() == err_status_ok)\n    printf(\"passed\\n\");\n  else {\n    printf(\"failed\\n\");\n    exit(1);\n  }\n#endif\n  \n  return 0;\n}\n\n#if AES_INVERSE_TEST\n\nerr_status_t\naes_test_inverse(void) {\n  v128_t x, y;\n  aes_expanded_key_t expanded_key, decrypt_key;\n  uint8_t plaintext[16] = {\n    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,\n    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff \n  };\n  uint8_t key[16] = {\n    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \n    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f\n  };\n  v128_t k;\n  v128_set_to_zero(&x);\n  \n  v128_copy_octet_string(&k, key);\n  v128_copy_octet_string(&x, plaintext);\n  aes_expand_encryption_key(k, expanded_key);\n  aes_expand_decryption_key(k, decrypt_key);\n  aes_encrypt(&x, expanded_key);\n  aes_decrypt(&x, decrypt_key);\n  \n  /* compare to expected value then report */\n  v128_copy_octet_string(&y, plaintext);\n\n  if (v128_is_eq(&x, &y))\n    return err_status_ok;\n  return err_status_algo_fail;\n  \n}\n \n#endif \n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/timing",
    "content": "# timing.plt\r# \r# gnuplot script file for plotting the output generated by srtp_driver -t\r# \r# David A. McGrew\r# Cisco Systems, Inc.\r#\rset xrange [0:2500]\rset term pict \"Times-Roman\" 9\r#\r# plot authentication-only data\r#\rset title \"Authentication Only\"\rset ylabel \"Megabits per second\"\rset xlabel \"Octets in packet\"\rset yrange [0:2000]\rset output \"plot-auth.pict\"\rplot \"timing.dat\" index 0 title \"HMAC SHA1\" with lines, \"timing.dat\" index 1 title \"TMMH/AES\" with lines, \"timing.dat\" index 2 title \"TMMH/SEAL\" with lines\r#\r# plot encryption-only data\r#\rset title \"Encryption Only\"\rset ylabel \"Megabits per second\"\rset xlabel \"Octets in packet\"\rset output \"plot-enc.pict\"\rset yrange [0:1200]\rplot \"timing.dat\" index 3 title \"SEAL\" with lines, \"timing.dat\" index 4 title \"AES ICM\" with lines\r#\r# plot encryption and authentication data\r#\rset title \"Encryption and Authentication\"\rset ylabel \"Megabits per second\"\rset xlabel \"Octets in packet\"\rset yrange [0:1000]\rset output \"plot-enc-auth.pict\"\rplot \"timing.dat\" index 5 title \"TMMH/SEAL\" with lines, \"timing.dat\" index 6 title \"TMMH/AES\" with lines, \"timing.dat\" index 7 title \"HMAC/AES\" with lines"
  },
  {
    "path": "deps/pjsip/third_party/srtp/undos.sh",
    "content": "#!/bin/sh\n \n# usage: undos <file>\n# \n# strips CRs from a file - useful when moving DOS-created files\n# onto UN*X machines\n\ncat $1 | tr -d \"\\r\" > $1.tmp\nmv $1.tmp $1\n\n"
  },
  {
    "path": "deps/pjsip/third_party/srtp/update.sh",
    "content": "#!/bin/sh\n\n# update.sh\n#\n# update copyright dates in files\n\na=`find . -name \"*.[ch]\"`\nfor x in $a; do \n    sed 's/(c) 2001-2005/(c) 2001-2006/' $x > $x.tmp; \n    mv $x.tmp $x; \ndone\n\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/OWNERS",
    "content": "bjornv@webrtc.org\ntina.legrand@webrtc.org\njan.skoglund@webrtc.org\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/interface/signal_processing_library.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This header file includes all of the fix point signal processing library (SPL) function\n * descriptions and declarations.\n * For specific function calls, see bottom of file.\n */\n\n#ifndef WEBRTC_SPL_SIGNAL_PROCESSING_LIBRARY_H_\n#define WEBRTC_SPL_SIGNAL_PROCESSING_LIBRARY_H_\n\n#include <string.h>\n#include \"typedefs.h\"\n\n#ifdef ARM_WINM\n#include <Armintr.h> // intrinsic file for windows mobile\n#endif\n\n// Macros specific for the fixed point implementation\n#define WEBRTC_SPL_WORD16_MAX       32767\n#define WEBRTC_SPL_WORD16_MIN       -32768\n#define WEBRTC_SPL_WORD32_MAX       (WebRtc_Word32)0x7fffffff\n#define WEBRTC_SPL_WORD32_MIN       (WebRtc_Word32)0x80000000\n#define WEBRTC_SPL_MAX_LPC_ORDER    14\n#define WEBRTC_SPL_MAX_SEED_USED    0x80000000L\n#define WEBRTC_SPL_MIN(A, B)        (A < B ? A : B) // Get min value\n#define WEBRTC_SPL_MAX(A, B)        (A > B ? A : B) // Get max value\n#define WEBRTC_SPL_ABS_W16(a) \\\n    (((WebRtc_Word16)a >= 0) ? ((WebRtc_Word16)a) : -((WebRtc_Word16)a))\n#define WEBRTC_SPL_ABS_W32(a) \\\n    (((WebRtc_Word32)a >= 0) ? ((WebRtc_Word32)a) : -((WebRtc_Word32)a))\n\n#if (defined WEBRTC_TARGET_PC)||(defined __TARGET_XSCALE)\n#define WEBRTC_SPL_GET_BYTE(a, nr)  (((WebRtc_Word8 *)a)[nr])\n#define WEBRTC_SPL_SET_BYTE(d_ptr, val, index) \\\n    (((WebRtc_Word8 *)d_ptr)[index] = (val))\n#elif defined WEBRTC_BIG_ENDIAN\n#define WEBRTC_SPL_GET_BYTE(a, nr) \\\n    ((((WebRtc_Word16 *)a)[nr >> 1]) >> (((nr + 1) & 0x1) * 8) & 0x00ff)\n#define WEBRTC_SPL_SET_BYTE(d_ptr, val, index) \\\n    ((WebRtc_Word16 *)d_ptr)[index >> 1] = \\\n    ((((WebRtc_Word16 *)d_ptr)[index >> 1]) \\\n    & (0x00ff << (8 * ((index) & 0x1)))) | (val << (8 * ((index + 1) & 0x1)))\n#else\n#define WEBRTC_SPL_GET_BYTE(a,nr) \\\n    ((((WebRtc_Word16 *)(a))[(nr) >> 1]) >> (((nr) & 0x1) * 8) & 0x00ff)\n#define WEBRTC_SPL_SET_BYTE(d_ptr, val, index) \\\n    ((WebRtc_Word16 *)(d_ptr))[(index) >> 1] = \\\n    ((((WebRtc_Word16 *)(d_ptr))[(index) >> 1]) \\\n    & (0x00ff << (8 * (((index) + 1) & 0x1)))) | \\\n    ((val) << (8 * ((index) & 0x1)))\n#endif\n\n#define WEBRTC_SPL_MUL(a, b) \\\n    ((WebRtc_Word32) ((WebRtc_Word32)(a) * (WebRtc_Word32)(b)))\n#define WEBRTC_SPL_UMUL(a, b) \\\n    ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord32)(b)))\n#define WEBRTC_SPL_UMUL_RSFT16(a, b) \\\n    ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord32)(b)) >> 16)\n#define WEBRTC_SPL_UMUL_16_16(a, b) \\\n    ((WebRtc_UWord32) (WebRtc_UWord16)(a) * (WebRtc_UWord16)(b))\n#define WEBRTC_SPL_UMUL_16_16_RSFT16(a, b) \\\n    (((WebRtc_UWord32) (WebRtc_UWord16)(a) * (WebRtc_UWord16)(b)) >> 16)\n#define WEBRTC_SPL_UMUL_32_16(a, b) \\\n    ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord16)(b)))\n#define WEBRTC_SPL_UMUL_32_16_RSFT16(a, b) \\\n    ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord16)(b)) >> 16)\n#define WEBRTC_SPL_MUL_16_U16(a, b) \\\n    ((WebRtc_Word32)(WebRtc_Word16)(a) * (WebRtc_UWord16)(b))\n#define WEBRTC_SPL_DIV(a, b) \\\n    ((WebRtc_Word32) ((WebRtc_Word32)(a) / (WebRtc_Word32)(b)))\n#define WEBRTC_SPL_UDIV(a, b) \\\n    ((WebRtc_UWord32) ((WebRtc_UWord32)(a) / (WebRtc_UWord32)(b)))\n\n#ifndef WEBRTC_ARCH_ARM_V7A\n// For ARMv7 platforms, these are inline functions in spl_inl_armv7.h\n#define WEBRTC_SPL_MUL_16_16(a, b) \\\n    ((WebRtc_Word32) (((WebRtc_Word16)(a)) * ((WebRtc_Word16)(b))))\n#define WEBRTC_SPL_MUL_16_32_RSFT16(a, b) \\\n    (WEBRTC_SPL_MUL_16_16(a, b >> 16) \\\n     + ((WEBRTC_SPL_MUL_16_16(a, (b & 0xffff) >> 1) + 0x4000) >> 15))\n#define WEBRTC_SPL_MUL_32_32_RSFT32(a32a, a32b, b32) \\\n    ((WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT16(a32a, b32) \\\n    + (WEBRTC_SPL_MUL_16_32_RSFT16(a32b, b32) >> 16)))\n#define WEBRTC_SPL_MUL_32_32_RSFT32BI(a32, b32) \\\n    ((WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT16(( \\\n    (WebRtc_Word16)(a32 >> 16)), b32) + \\\n    (WEBRTC_SPL_MUL_16_32_RSFT16(( \\\n    (WebRtc_Word16)((a32 & 0x0000FFFF) >> 1)), b32) >> 15)))\n#endif\n\n#define WEBRTC_SPL_MUL_16_32_RSFT11(a, b) \\\n    ((WEBRTC_SPL_MUL_16_16(a, (b) >> 16) << 5) \\\n    + (((WEBRTC_SPL_MUL_16_U16(a, (WebRtc_UWord16)(b)) >> 1) + 0x0200) >> 10))\n#define WEBRTC_SPL_MUL_16_32_RSFT14(a, b) \\\n    ((WEBRTC_SPL_MUL_16_16(a, (b) >> 16) << 2) \\\n    + (((WEBRTC_SPL_MUL_16_U16(a, (WebRtc_UWord16)(b)) >> 1) + 0x1000) >> 13))\n#define WEBRTC_SPL_MUL_16_32_RSFT15(a, b) \\\n    ((WEBRTC_SPL_MUL_16_16(a, (b) >> 16) << 1) \\\n    + (((WEBRTC_SPL_MUL_16_U16(a, (WebRtc_UWord16)(b)) >> 1) + 0x2000) >> 14))\n\n#ifdef ARM_WINM\n#define WEBRTC_SPL_MUL_16_16(a, b) \\\n    _SmulLo_SW_SL((WebRtc_Word16)(a), (WebRtc_Word16)(b))\n#endif\n\n#define WEBRTC_SPL_MUL_16_16_RSFT(a, b, c) \\\n    (WEBRTC_SPL_MUL_16_16(a, b) >> (c))\n\n#define WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(a, b, c) \\\n    ((WEBRTC_SPL_MUL_16_16(a, b) + ((WebRtc_Word32) \\\n                                  (((WebRtc_Word32)1) << ((c) - 1)))) >> (c))\n#define WEBRTC_SPL_MUL_16_16_RSFT_WITH_FIXROUND(a, b) \\\n    ((WEBRTC_SPL_MUL_16_16(a, b) + ((WebRtc_Word32) (1 << 14))) >> 15)\n\n// C + the 32 most significant bits of A * B\n#define WEBRTC_SPL_SCALEDIFF32(A, B, C) \\\n    (C + (B >> 16) * A + (((WebRtc_UWord32)(0x0000FFFF & B) * A) >> 16))\n\n#define WEBRTC_SPL_ADD_SAT_W32(a, b)    WebRtcSpl_AddSatW32(a, b)\n#define WEBRTC_SPL_SAT(a, b, c)         (b > a ? a : b < c ? c : b)\n#define WEBRTC_SPL_MUL_32_16(a, b)      ((a) * (b))\n\n#define WEBRTC_SPL_SUB_SAT_W32(a, b)    WebRtcSpl_SubSatW32(a, b)\n#define WEBRTC_SPL_ADD_SAT_W16(a, b)    WebRtcSpl_AddSatW16(a, b)\n#define WEBRTC_SPL_SUB_SAT_W16(a, b)    WebRtcSpl_SubSatW16(a, b)\n\n// We cannot do casting here due to signed/unsigned problem\n#define WEBRTC_SPL_IS_NEG(a)            ((a) & 0x80000000)\n// Shifting with negative numbers allowed\n// Positive means left shift\n#define WEBRTC_SPL_SHIFT_W16(x, c) \\\n    (((c) >= 0) ? ((x) << (c)) : ((x) >> (-(c))))\n#define WEBRTC_SPL_SHIFT_W32(x, c) \\\n    (((c) >= 0) ? ((x) << (c)) : ((x) >> (-(c))))\n\n// Shifting with negative numbers not allowed\n// We cannot do casting here due to signed/unsigned problem\n#define WEBRTC_SPL_RSHIFT_W16(x, c)     ((x) >> (c))\n#define WEBRTC_SPL_LSHIFT_W16(x, c)     ((x) << (c))\n#define WEBRTC_SPL_RSHIFT_W32(x, c)     ((x) >> (c))\n#define WEBRTC_SPL_LSHIFT_W32(x, c)     ((x) << (c))\n\n#define WEBRTC_SPL_RSHIFT_U16(x, c)     ((WebRtc_UWord16)(x) >> (c))\n#define WEBRTC_SPL_LSHIFT_U16(x, c)     ((WebRtc_UWord16)(x) << (c))\n#define WEBRTC_SPL_RSHIFT_U32(x, c)     ((WebRtc_UWord32)(x) >> (c))\n#define WEBRTC_SPL_LSHIFT_U32(x, c)     ((WebRtc_UWord32)(x) << (c))\n\n#define WEBRTC_SPL_VNEW(t, n)           (t *) malloc (sizeof (t) * (n))\n#define WEBRTC_SPL_FREE                 free\n\n#define WEBRTC_SPL_RAND(a) \\\n    ((WebRtc_Word16)(WEBRTC_SPL_MUL_16_16_RSFT((a), 18816, 7) & 0x00007fff))\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n#define WEBRTC_SPL_MEMCPY_W8(v1, v2, length) \\\n   memcpy(v1, v2, (length) * sizeof(char))\n#define WEBRTC_SPL_MEMCPY_W16(v1, v2, length) \\\n   memcpy(v1, v2, (length) * sizeof(WebRtc_Word16))\n\n#define WEBRTC_SPL_MEMMOVE_W16(v1, v2, length) \\\n   memmove(v1, v2, (length) * sizeof(WebRtc_Word16))\n\n// Trigonometric tables used for quick lookup\n// default declarations\nextern WebRtc_Word16 WebRtcSpl_kCosTable[];\nextern WebRtc_Word16 WebRtcSpl_kSinTable[];\nextern WebRtc_Word16 WebRtcSpl_kSinTable1024[];\n// Hanning table\nextern WebRtc_Word16 WebRtcSpl_kHanningTable[];\n// Random table\nextern WebRtc_Word16 WebRtcSpl_kRandNTable[];\n\n// inline functions:\n#include \"spl_inl.h\"\n\n// Get SPL Version\nWebRtc_Word16 WebRtcSpl_get_version(char* version,\n                                    WebRtc_Word16 length_in_bytes);\n\nint WebRtcSpl_GetScalingSquare(WebRtc_Word16* in_vector,\n                               int in_vector_length,\n                               int times);\n\n// Copy and set operations. Implementation in copy_set_operations.c.\n// Descriptions at bottom of file.\nvoid WebRtcSpl_MemSetW16(WebRtc_Word16* vector,\n                         WebRtc_Word16 set_value,\n                         int vector_length);\nvoid WebRtcSpl_MemSetW32(WebRtc_Word32* vector,\n                         WebRtc_Word32 set_value,\n                         int vector_length);\nvoid WebRtcSpl_MemCpyReversedOrder(WebRtc_Word16* out_vector,\n                                   WebRtc_Word16* in_vector,\n                                   int vector_length);\nWebRtc_Word16 WebRtcSpl_CopyFromEndW16(G_CONST WebRtc_Word16* in_vector,\n                                       WebRtc_Word16 in_vector_length,\n                                       WebRtc_Word16 samples,\n                                       WebRtc_Word16* out_vector);\nWebRtc_Word16 WebRtcSpl_ZerosArrayW16(WebRtc_Word16* vector,\n                                      WebRtc_Word16 vector_length);\nWebRtc_Word16 WebRtcSpl_ZerosArrayW32(WebRtc_Word32* vector,\n                                      WebRtc_Word16 vector_length);\nWebRtc_Word16 WebRtcSpl_OnesArrayW16(WebRtc_Word16* vector,\n                                     WebRtc_Word16 vector_length);\nWebRtc_Word16 WebRtcSpl_OnesArrayW32(WebRtc_Word32* vector,\n                                     WebRtc_Word16 vector_length);\n// End: Copy and set operations.\n\n// Minimum and maximum operations. Implementation in min_max_operations.c.\n// Descriptions at bottom of file.\nWebRtc_Word16 WebRtcSpl_MaxAbsValueW16(const WebRtc_Word16* vector,\n                                       WebRtc_Word16 length);\nWebRtc_Word32 WebRtcSpl_MaxAbsValueW32(G_CONST WebRtc_Word32* vector,\n                                       WebRtc_Word16 length);\nWebRtc_Word16 WebRtcSpl_MinValueW16(G_CONST WebRtc_Word16* vector,\n                                    WebRtc_Word16 length);\nWebRtc_Word32 WebRtcSpl_MinValueW32(G_CONST WebRtc_Word32* vector,\n                                    WebRtc_Word16 length);\nWebRtc_Word16 WebRtcSpl_MaxValueW16(G_CONST WebRtc_Word16* vector,\n                                    WebRtc_Word16 length);\n\nWebRtc_Word16 WebRtcSpl_MaxAbsIndexW16(G_CONST WebRtc_Word16* vector,\n                                       WebRtc_Word16 length);\nWebRtc_Word32 WebRtcSpl_MaxValueW32(G_CONST WebRtc_Word32* vector,\n                                    WebRtc_Word16 length);\nWebRtc_Word16 WebRtcSpl_MinIndexW16(G_CONST WebRtc_Word16* vector,\n                                    WebRtc_Word16 length);\nWebRtc_Word16 WebRtcSpl_MinIndexW32(G_CONST WebRtc_Word32* vector,\n                                    WebRtc_Word16 length);\nWebRtc_Word16 WebRtcSpl_MaxIndexW16(G_CONST WebRtc_Word16* vector,\n                                    WebRtc_Word16 length);\nWebRtc_Word16 WebRtcSpl_MaxIndexW32(G_CONST WebRtc_Word32* vector,\n                                    WebRtc_Word16 length);\n// End: Minimum and maximum operations.\n\n// Vector scaling operations. Implementation in vector_scaling_operations.c.\n// Description at bottom of file.\nvoid WebRtcSpl_VectorBitShiftW16(WebRtc_Word16* out_vector,\n                                 WebRtc_Word16 vector_length,\n                                 G_CONST WebRtc_Word16* in_vector,\n                                 WebRtc_Word16 right_shifts);\nvoid WebRtcSpl_VectorBitShiftW32(WebRtc_Word32* out_vector,\n                                 WebRtc_Word16 vector_length,\n                                 G_CONST WebRtc_Word32* in_vector,\n                                 WebRtc_Word16 right_shifts);\nvoid WebRtcSpl_VectorBitShiftW32ToW16(WebRtc_Word16* out_vector,\n                                      WebRtc_Word16 vector_length,\n                                      G_CONST WebRtc_Word32* in_vector,\n                                      WebRtc_Word16 right_shifts);\n\nvoid WebRtcSpl_ScaleVector(G_CONST WebRtc_Word16* in_vector,\n                           WebRtc_Word16* out_vector,\n                           WebRtc_Word16 gain,\n                           WebRtc_Word16 vector_length,\n                           WebRtc_Word16 right_shifts);\nvoid WebRtcSpl_ScaleVectorWithSat(G_CONST WebRtc_Word16* in_vector,\n                                  WebRtc_Word16* out_vector,\n                                  WebRtc_Word16 gain,\n                                  WebRtc_Word16 vector_length,\n                                  WebRtc_Word16 right_shifts);\nvoid WebRtcSpl_ScaleAndAddVectors(G_CONST WebRtc_Word16* in_vector1,\n                                  WebRtc_Word16 gain1, int right_shifts1,\n                                  G_CONST WebRtc_Word16* in_vector2,\n                                  WebRtc_Word16 gain2, int right_shifts2,\n                                  WebRtc_Word16* out_vector,\n                                  int vector_length);\n// End: Vector scaling operations.\n\n// iLBC specific functions. Implementations in ilbc_specific_functions.c.\n// Description at bottom of file.\nvoid WebRtcSpl_ScaleAndAddVectorsWithRound(WebRtc_Word16* in_vector1,\n                                           WebRtc_Word16 scale1,\n                                           WebRtc_Word16* in_vector2,\n                                           WebRtc_Word16 scale2,\n                                           WebRtc_Word16 right_shifts,\n                                           WebRtc_Word16* out_vector,\n                                           WebRtc_Word16 vector_length);\nvoid WebRtcSpl_ReverseOrderMultArrayElements(WebRtc_Word16* out_vector,\n                                             G_CONST WebRtc_Word16* in_vector,\n                                             G_CONST WebRtc_Word16* window,\n                                             WebRtc_Word16 vector_length,\n                                             WebRtc_Word16 right_shifts);\nvoid WebRtcSpl_ElementwiseVectorMult(WebRtc_Word16* out_vector,\n                                     G_CONST WebRtc_Word16* in_vector,\n                                     G_CONST WebRtc_Word16* window,\n                                     WebRtc_Word16 vector_length,\n                                     WebRtc_Word16 right_shifts);\nvoid WebRtcSpl_AddVectorsAndShift(WebRtc_Word16* out_vector,\n                                  G_CONST WebRtc_Word16* in_vector1,\n                                  G_CONST WebRtc_Word16* in_vector2,\n                                  WebRtc_Word16 vector_length,\n                                  WebRtc_Word16 right_shifts);\nvoid WebRtcSpl_AddAffineVectorToVector(WebRtc_Word16* out_vector,\n                                       WebRtc_Word16* in_vector,\n                                       WebRtc_Word16 gain,\n                                       WebRtc_Word32 add_constant,\n                                       WebRtc_Word16 right_shifts,\n                                       int vector_length);\nvoid WebRtcSpl_AffineTransformVector(WebRtc_Word16* out_vector,\n                                     WebRtc_Word16* in_vector,\n                                     WebRtc_Word16 gain,\n                                     WebRtc_Word32 add_constant,\n                                     WebRtc_Word16 right_shifts,\n                                     int vector_length);\n// End: iLBC specific functions.\n\n// Signal processing operations. Descriptions at bottom of this file.\nint WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* vector,\n                              int vector_length, int order,\n                              WebRtc_Word32* result_vector,\n                              int* scale);\nWebRtc_Word16 WebRtcSpl_LevinsonDurbin(WebRtc_Word32* auto_corr,\n                                       WebRtc_Word16* lpc_coef,\n                                       WebRtc_Word16* refl_coef,\n                                       WebRtc_Word16 order);\nvoid WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16* refl_coef,\n                             int use_order,\n                             WebRtc_Word16* lpc_coef);\nvoid WebRtcSpl_LpcToReflCoef(WebRtc_Word16* lpc_coef,\n                             int use_order,\n                             WebRtc_Word16* refl_coef);\nvoid WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32* auto_corr,\n                                  int use_order,\n                                  WebRtc_Word16* refl_coef);\nvoid WebRtcSpl_CrossCorrelation(WebRtc_Word32* cross_corr,\n                                WebRtc_Word16* vector1,\n                                WebRtc_Word16* vector2,\n                                WebRtc_Word16 dim_vector,\n                                WebRtc_Word16 dim_cross_corr,\n                                WebRtc_Word16 right_shifts,\n                                WebRtc_Word16 step_vector2);\nvoid WebRtcSpl_GetHanningWindow(WebRtc_Word16* window, WebRtc_Word16 size);\nvoid WebRtcSpl_SqrtOfOneMinusXSquared(WebRtc_Word16* in_vector,\n                                      int vector_length,\n                                      WebRtc_Word16* out_vector);\n// End: Signal processing operations.\n\n// Randomization functions. Implementations collected in randomization_functions.c and\n// descriptions at bottom of this file.\nWebRtc_UWord32 WebRtcSpl_IncreaseSeed(WebRtc_UWord32* seed);\nWebRtc_Word16 WebRtcSpl_RandU(WebRtc_UWord32* seed);\nWebRtc_Word16 WebRtcSpl_RandN(WebRtc_UWord32* seed);\nWebRtc_Word16 WebRtcSpl_RandUArray(WebRtc_Word16* vector,\n                                   WebRtc_Word16 vector_length,\n                                   WebRtc_UWord32* seed);\n// End: Randomization functions.\n\n// Math functions\nWebRtc_Word32 WebRtcSpl_Sqrt(WebRtc_Word32 value);\nWebRtc_Word32 WebRtcSpl_SqrtFloor(WebRtc_Word32 value);\n\n// Divisions. Implementations collected in division_operations.c and\n// descriptions at bottom of this file.\nWebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den);\nWebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den);\nWebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den);\nWebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den);\nWebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi,\n                                    WebRtc_Word16 den_low);\n// End: Divisions.\n\nWebRtc_Word32 WebRtcSpl_Energy(WebRtc_Word16* vector,\n                               int vector_length,\n                               int* scale_factor);\n\nWebRtc_Word32 WebRtcSpl_DotProductWithScale(WebRtc_Word16* vector1,\n                                            WebRtc_Word16* vector2,\n                                            int vector_length,\n                                            int scaling);\n\n// Filter operations.\nint WebRtcSpl_FilterAR(G_CONST WebRtc_Word16* ar_coef, int ar_coef_length,\n                       G_CONST WebRtc_Word16* in_vector, int in_vector_length,\n                       WebRtc_Word16* filter_state, int filter_state_length,\n                       WebRtc_Word16* filter_state_low,\n                       int filter_state_low_length, WebRtc_Word16* out_vector,\n                       WebRtc_Word16* out_vector_low, int out_vector_low_length);\n\nvoid WebRtcSpl_FilterMAFastQ12(WebRtc_Word16* in_vector,\n                               WebRtc_Word16* out_vector,\n                               WebRtc_Word16* ma_coef,\n                               WebRtc_Word16 ma_coef_length,\n                               WebRtc_Word16 vector_length);\nvoid WebRtcSpl_FilterARFastQ12(WebRtc_Word16* in_vector,\n                               WebRtc_Word16* out_vector,\n                               WebRtc_Word16* ar_coef,\n                               WebRtc_Word16 ar_coef_length,\n                               WebRtc_Word16 vector_length);\nint WebRtcSpl_DownsampleFast(WebRtc_Word16* in_vector,\n                             WebRtc_Word16 in_vector_length,\n                             WebRtc_Word16* out_vector,\n                             WebRtc_Word16 out_vector_length,\n                             WebRtc_Word16* ma_coef,\n                             WebRtc_Word16 ma_coef_length,\n                             WebRtc_Word16 factor,\n                             WebRtc_Word16 delay);\n// End: Filter operations.\n\n// FFT operations\nint WebRtcSpl_ComplexFFT(WebRtc_Word16 vector[], int stages, int mode);\nint WebRtcSpl_ComplexIFFT(WebRtc_Word16 vector[], int stages, int mode);\nvoid WebRtcSpl_ComplexBitReverse(WebRtc_Word16 vector[], int stages);\n// End: FFT operations\n\n/************************************************************\n *\n * RESAMPLING FUNCTIONS AND THEIR STRUCTS ARE DEFINED BELOW\n *\n ************************************************************/\n\n/*******************************************************************\n * resample.c\n *\n * Includes the following resampling combinations\n * 22 kHz -> 16 kHz\n * 16 kHz -> 22 kHz\n * 22 kHz ->  8 kHz\n *  8 kHz -> 22 kHz\n *\n ******************************************************************/\n\n// state structure for 22 -> 16 resampler\ntypedef struct\n{\n    WebRtc_Word32 S_22_44[8];\n    WebRtc_Word32 S_44_32[8];\n    WebRtc_Word32 S_32_16[8];\n} WebRtcSpl_State22khzTo16khz;\n\nvoid WebRtcSpl_Resample22khzTo16khz(const WebRtc_Word16* in,\n                                    WebRtc_Word16* out,\n                                    WebRtcSpl_State22khzTo16khz* state,\n                                    WebRtc_Word32* tmpmem);\n\nvoid WebRtcSpl_ResetResample22khzTo16khz(WebRtcSpl_State22khzTo16khz* state);\n\n// state structure for 16 -> 22 resampler\ntypedef struct\n{\n    WebRtc_Word32 S_16_32[8];\n    WebRtc_Word32 S_32_22[8];\n} WebRtcSpl_State16khzTo22khz;\n\nvoid WebRtcSpl_Resample16khzTo22khz(const WebRtc_Word16* in,\n                                    WebRtc_Word16* out,\n                                    WebRtcSpl_State16khzTo22khz* state,\n                                    WebRtc_Word32* tmpmem);\n\nvoid WebRtcSpl_ResetResample16khzTo22khz(WebRtcSpl_State16khzTo22khz* state);\n\n// state structure for 22 -> 8 resampler\ntypedef struct\n{\n    WebRtc_Word32 S_22_22[16];\n    WebRtc_Word32 S_22_16[8];\n    WebRtc_Word32 S_16_8[8];\n} WebRtcSpl_State22khzTo8khz;\n\nvoid WebRtcSpl_Resample22khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                   WebRtcSpl_State22khzTo8khz* state,\n                                   WebRtc_Word32* tmpmem);\n\nvoid WebRtcSpl_ResetResample22khzTo8khz(WebRtcSpl_State22khzTo8khz* state);\n\n// state structure for 8 -> 22 resampler\ntypedef struct\n{\n    WebRtc_Word32 S_8_16[8];\n    WebRtc_Word32 S_16_11[8];\n    WebRtc_Word32 S_11_22[8];\n} WebRtcSpl_State8khzTo22khz;\n\nvoid WebRtcSpl_Resample8khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                   WebRtcSpl_State8khzTo22khz* state,\n                                   WebRtc_Word32* tmpmem);\n\nvoid WebRtcSpl_ResetResample8khzTo22khz(WebRtcSpl_State8khzTo22khz* state);\n\n/*******************************************************************\n * resample_fractional.c\n * Functions for internal use in the other resample functions\n *\n * Includes the following resampling combinations\n * 48 kHz -> 32 kHz\n * 32 kHz -> 24 kHz\n * 44 kHz -> 32 kHz\n *\n ******************************************************************/\n\nvoid WebRtcSpl_Resample48khzTo32khz(const WebRtc_Word32* In, WebRtc_Word32* Out,\n                                    const WebRtc_Word32 K);\n\nvoid WebRtcSpl_Resample32khzTo24khz(const WebRtc_Word32* In, WebRtc_Word32* Out,\n                                    const WebRtc_Word32 K);\n\nvoid WebRtcSpl_Resample44khzTo32khz(const WebRtc_Word32* In, WebRtc_Word32* Out,\n                                    const WebRtc_Word32 K);\n\n/*******************************************************************\n * resample_48khz.c\n *\n * Includes the following resampling combinations\n * 48 kHz -> 16 kHz\n * 16 kHz -> 48 kHz\n * 48 kHz ->  8 kHz\n *  8 kHz -> 48 kHz\n *\n ******************************************************************/\n\ntypedef struct\n{\n    WebRtc_Word32 S_48_48[16];\n    WebRtc_Word32 S_48_32[8];\n    WebRtc_Word32 S_32_16[8];\n} WebRtcSpl_State48khzTo16khz;\n\nvoid WebRtcSpl_Resample48khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                    WebRtcSpl_State48khzTo16khz* state,\n                                    WebRtc_Word32* tmpmem);\n\nvoid WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state);\n\ntypedef struct\n{\n    WebRtc_Word32 S_16_32[8];\n    WebRtc_Word32 S_32_24[8];\n    WebRtc_Word32 S_24_48[8];\n} WebRtcSpl_State16khzTo48khz;\n\nvoid WebRtcSpl_Resample16khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                    WebRtcSpl_State16khzTo48khz* state,\n                                    WebRtc_Word32* tmpmem);\n\nvoid WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state);\n\ntypedef struct\n{\n    WebRtc_Word32 S_48_24[8];\n    WebRtc_Word32 S_24_24[16];\n    WebRtc_Word32 S_24_16[8];\n    WebRtc_Word32 S_16_8[8];\n} WebRtcSpl_State48khzTo8khz;\n\nvoid WebRtcSpl_Resample48khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                   WebRtcSpl_State48khzTo8khz* state,\n                                   WebRtc_Word32* tmpmem);\n\nvoid WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state);\n\ntypedef struct\n{\n    WebRtc_Word32 S_8_16[8];\n    WebRtc_Word32 S_16_12[8];\n    WebRtc_Word32 S_12_24[8];\n    WebRtc_Word32 S_24_48[8];\n} WebRtcSpl_State8khzTo48khz;\n\nvoid WebRtcSpl_Resample8khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                   WebRtcSpl_State8khzTo48khz* state,\n                                   WebRtc_Word32* tmpmem);\n\nvoid WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state);\n\n/*******************************************************************\n * resample_by_2.c\n *\n * Includes down and up sampling by a factor of two.\n *\n ******************************************************************/\n\nvoid WebRtcSpl_DownsampleBy2(const WebRtc_Word16* in, const WebRtc_Word16 len,\n                             WebRtc_Word16* out, WebRtc_Word32* filtState);\n\nvoid WebRtcSpl_UpsampleBy2(const WebRtc_Word16* in, WebRtc_Word16 len, WebRtc_Word16* out,\n                           WebRtc_Word32* filtState);\n\n/************************************************************\n * END OF RESAMPLING FUNCTIONS\n ************************************************************/\nvoid WebRtcSpl_AnalysisQMF(const WebRtc_Word16* in_data,\n                           WebRtc_Word16* low_band,\n                           WebRtc_Word16* high_band,\n                           WebRtc_Word32* filter_state1,\n                           WebRtc_Word32* filter_state2);\nvoid WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band,\n                            const WebRtc_Word16* high_band,\n                            WebRtc_Word16* out_data,\n                            WebRtc_Word32* filter_state1,\n                            WebRtc_Word32* filter_state2);\n\n#ifdef __cplusplus\n}\n#endif // __cplusplus\n#endif // WEBRTC_SPL_SIGNAL_PROCESSING_LIBRARY_H_\n\n//\n// WebRtcSpl_AddSatW16(...)\n// WebRtcSpl_AddSatW32(...)\n//\n// Returns the result of a saturated 16-bit, respectively 32-bit, addition of\n// the numbers specified by the |var1| and |var2| parameters.\n//\n// Input:\n//      - var1      : Input variable 1\n//      - var2      : Input variable 2\n//\n// Return value     : Added and saturated value\n//\n\n//\n// WebRtcSpl_SubSatW16(...)\n// WebRtcSpl_SubSatW32(...)\n//\n// Returns the result of a saturated 16-bit, respectively 32-bit, subtraction\n// of the numbers specified by the |var1| and |var2| parameters.\n//\n// Input:\n//      - var1      : Input variable 1\n//      - var2      : Input variable 2\n//\n// Returned value   : Subtracted and saturated value\n//\n\n//\n// WebRtcSpl_GetSizeInBits(...)\n//\n// Returns the # of bits that are needed at the most to represent the number\n// specified by the |value| parameter.\n//\n// Input:\n//      - value     : Input value\n//\n// Return value     : Number of bits needed to represent |value|\n//\n\n//\n// WebRtcSpl_NormW32(...)\n//\n// Norm returns the # of left shifts required to 32-bit normalize the 32-bit\n// signed number specified by the |value| parameter.\n//\n// Input:\n//      - value     : Input value\n//\n// Return value     : Number of bit shifts needed to 32-bit normalize |value|\n//\n\n//\n// WebRtcSpl_NormW16(...)\n//\n// Norm returns the # of left shifts required to 16-bit normalize the 16-bit\n// signed number specified by the |value| parameter.\n//\n// Input:\n//      - value     : Input value\n//\n// Return value     : Number of bit shifts needed to 32-bit normalize |value|\n//\n\n//\n// WebRtcSpl_NormU32(...)\n//\n// Norm returns the # of left shifts required to 32-bit normalize the unsigned\n// 32-bit number specified by the |value| parameter.\n//\n// Input:\n//      - value     : Input value\n//\n// Return value     : Number of bit shifts needed to 32-bit normalize |value|\n//\n\n//\n// WebRtcSpl_GetScalingSquare(...)\n//\n// Returns the # of bits required to scale the samples specified in the\n// |in_vector| parameter so that, if the squares of the samples are added the\n// # of times specified by the |times| parameter, the 32-bit addition will not\n// overflow (result in WebRtc_Word32).\n//\n// Input:\n//      - in_vector         : Input vector to check scaling on\n//      - in_vector_length  : Samples in |in_vector|\n//      - times             : Number of additions to be performed\n//\n// Return value             : Number of right bit shifts needed to avoid\n//                            overflow in the addition calculation\n//\n\n//\n// WebRtcSpl_MemSetW16(...)\n//\n// Sets all the values in the WebRtc_Word16 vector |vector| of length\n// |vector_length| to the specified value |set_value|\n//\n// Input:\n//      - vector        : Pointer to the WebRtc_Word16 vector\n//      - set_value     : Value specified\n//      - vector_length : Length of vector\n//\n\n//\n// WebRtcSpl_MemSetW32(...)\n//\n// Sets all the values in the WebRtc_Word32 vector |vector| of length\n// |vector_length| to the specified value |set_value|\n//\n// Input:\n//      - vector        : Pointer to the WebRtc_Word16 vector\n//      - set_value     : Value specified\n//      - vector_length : Length of vector\n//\n\n//\n// WebRtcSpl_MemCpyReversedOrder(...)\n//\n// Copies all the values from the source WebRtc_Word16 vector |in_vector| to a\n// destination WebRtc_Word16 vector |out_vector|. It is done in reversed order,\n// meaning that the first sample of |in_vector| is copied to the last sample of\n// the |out_vector|. The procedure continues until the last sample of\n// |in_vector| has been copied to the first sample of |out_vector|. This\n// creates a reversed vector. Used in e.g. prediction in iLBC.\n//\n// Input:\n//      - in_vector     : Pointer to the first sample in a WebRtc_Word16 vector\n//                        of length |length|\n//      - vector_length : Number of elements to copy\n//\n// Output:\n//      - out_vector    : Pointer to the last sample in a WebRtc_Word16 vector\n//                        of length |length|\n//\n\n//\n// WebRtcSpl_CopyFromEndW16(...)\n//\n// Copies the rightmost |samples| of |in_vector| (of length |in_vector_length|)\n// to the vector |out_vector|.\n//\n// Input:\n//      - in_vector         : Input vector\n//      - in_vector_length  : Number of samples in |in_vector|\n//      - samples           : Number of samples to extract (from right side)\n//                            from |in_vector|\n//\n// Output:\n//      - out_vector        : Vector with the requested samples\n//\n// Return value             : Number of copied samples in |out_vector|\n//\n\n//\n// WebRtcSpl_ZerosArrayW16(...)\n// WebRtcSpl_ZerosArrayW32(...)\n//\n// Inserts the value \"zero\" in all positions of a w16 and a w32 vector\n// respectively.\n//\n// Input:\n//      - vector_length : Number of samples in vector\n//\n// Output:\n//      - vector        : Vector containing all zeros\n//\n// Return value         : Number of samples in vector\n//\n\n//\n// WebRtcSpl_OnesArrayW16(...)\n// WebRtcSpl_OnesArrayW32(...)\n//\n// Inserts the value \"one\" in all positions of a w16 and a w32 vector\n// respectively.\n//\n// Input:\n//      - vector_length : Number of samples in vector\n//\n// Output:\n//      - vector        : Vector containing all ones\n//\n// Return value         : Number of samples in vector\n//\n\n//\n// WebRtcSpl_MinValueW16(...)\n// WebRtcSpl_MinValueW32(...)\n//\n// Returns the minimum value of a vector\n//\n// Input:\n//      - vector        : Input vector\n//      - vector_length : Number of samples in vector\n//\n// Return value         : Minimum sample value in vector\n//\n\n//\n// WebRtcSpl_MaxValueW16(...)\n// WebRtcSpl_MaxValueW32(...)\n//\n// Returns the maximum value of a vector\n//\n// Input:\n//      - vector        : Input vector\n//      - vector_length : Number of samples in vector\n//\n// Return value         : Maximum sample value in vector\n//\n\n//\n// WebRtcSpl_MaxAbsValueW16(...)\n// WebRtcSpl_MaxAbsValueW32(...)\n//\n// Returns the largest absolute value of a vector\n//\n// Input:\n//      - vector        : Input vector\n//      - vector_length : Number of samples in vector\n//\n// Return value         : Maximum absolute value in vector\n//\n\n//\n// WebRtcSpl_MaxAbsIndexW16(...)\n//\n// Returns the vector index to the largest absolute value of a vector\n//\n// Input:\n//      - vector        : Input vector\n//      - vector_length : Number of samples in vector\n//\n// Return value         : Index to maximum absolute value in vector\n//\n\n//\n// WebRtcSpl_MinIndexW16(...)\n// WebRtcSpl_MinIndexW32(...)\n//\n// Returns the vector index to the minimum sample value of a vector\n//\n// Input:\n//      - vector        : Input vector\n//      - vector_length : Number of samples in vector\n//\n// Return value         : Index to minimum sample value in vector\n//\n\n//\n// WebRtcSpl_MaxIndexW16(...)\n// WebRtcSpl_MaxIndexW32(...)\n//\n// Returns the vector index to the maximum sample value of a vector\n//\n// Input:\n//      - vector        : Input vector\n//      - vector_length : Number of samples in vector\n//\n// Return value         : Index to maximum sample value in vector\n//\n\n//\n// WebRtcSpl_VectorBitShiftW16(...)\n// WebRtcSpl_VectorBitShiftW32(...)\n//\n// Bit shifts all the values in a vector up or downwards. Different calls for\n// WebRtc_Word16 and WebRtc_Word32 vectors respectively.\n//\n// Input:\n//      - vector_length : Length of vector\n//      - in_vector     : Pointer to the vector that should be bit shifted\n//      - right_shifts  : Number of right bit shifts (negative value gives left\n//                        shifts)\n//\n// Output:\n//      - out_vector    : Pointer to the result vector (can be the same as\n//                        |in_vector|)\n//\n\n//\n// WebRtcSpl_VectorBitShiftW32ToW16(...)\n//\n// Bit shifts all the values in a WebRtc_Word32 vector up or downwards and\n// stores the result as a WebRtc_Word16 vector\n//\n// Input:\n//      - vector_length : Length of vector\n//      - in_vector     : Pointer to the vector that should be bit shifted\n//      - right_shifts  : Number of right bit shifts (negative value gives left\n//                        shifts)\n//\n// Output:\n//      - out_vector    : Pointer to the result vector (can be the same as\n//                        |in_vector|)\n//\n\n//\n// WebRtcSpl_ScaleVector(...)\n//\n// Performs the vector operation:\n//  out_vector[k] = (gain*in_vector[k])>>right_shifts\n//\n// Input:\n//      - in_vector     : Input vector\n//      - gain          : Scaling gain\n//      - vector_length : Elements in the |in_vector|\n//      - right_shifts  : Number of right bit shifts applied\n//\n// Output:\n//      - out_vector    : Output vector (can be the same as |in_vector|)\n//\n\n//\n// WebRtcSpl_ScaleVectorWithSat(...)\n//\n// Performs the vector operation:\n//  out_vector[k] = SATURATE( (gain*in_vector[k])>>right_shifts )\n//\n// Input:\n//      - in_vector     : Input vector\n//      - gain          : Scaling gain\n//      - vector_length : Elements in the |in_vector|\n//      - right_shifts  : Number of right bit shifts applied\n//\n// Output:\n//      - out_vector    : Output vector (can be the same as |in_vector|)\n//\n\n//\n// WebRtcSpl_ScaleAndAddVectors(...)\n//\n// Performs the vector operation:\n//  out_vector[k] = (gain1*in_vector1[k])>>right_shifts1\n//                  + (gain2*in_vector2[k])>>right_shifts2\n//\n// Input:\n//      - in_vector1    : Input vector 1\n//      - gain1         : Gain to be used for vector 1\n//      - right_shifts1 : Right bit shift to be used for vector 1\n//      - in_vector2    : Input vector 2\n//      - gain2         : Gain to be used for vector 2\n//      - right_shifts2 : Right bit shift to be used for vector 2\n//      - vector_length : Elements in the input vectors\n//\n// Output:\n//      - out_vector    : Output vector\n//\n\n//\n// WebRtcSpl_ScaleAndAddVectorsWithRound(...)\n//\n// Performs the vector operation:\n//\n//  out_vector[k] = ((scale1*in_vector1[k]) + (scale2*in_vector2[k])\n//                      + round_value) >> right_shifts\n//\n//      where:\n//\n//  round_value = (1<<right_shifts)>>1\n//\n// Input:\n//      - in_vector1    : Input vector 1\n//      - scale1        : Gain to be used for vector 1\n//      - in_vector2    : Input vector 2\n//      - scale2        : Gain to be used for vector 2\n//      - right_shifts  : Number of right bit shifts to be applied\n//      - vector_length : Number of elements in the input vectors\n//\n// Output:\n//      - out_vector    : Output vector\n//\n\n//\n// WebRtcSpl_ReverseOrderMultArrayElements(...)\n//\n// Performs the vector operation:\n//  out_vector[n] = (in_vector[n]*window[-n])>>right_shifts\n//\n// Input:\n//      - in_vector     : Input vector\n//      - window        : Window vector (should be reversed). The pointer\n//                        should be set to the last value in the vector\n//      - right_shifts  : Number of right bit shift to be applied after the\n//                        multiplication\n//      - vector_length : Number of elements in |in_vector|\n//\n// Output:\n//      - out_vector    : Output vector (can be same as |in_vector|)\n//\n\n//\n// WebRtcSpl_ElementwiseVectorMult(...)\n//\n// Performs the vector operation:\n//  out_vector[n] = (in_vector[n]*window[n])>>right_shifts\n//\n// Input:\n//      - in_vector     : Input vector\n//      - window        : Window vector.\n//      - right_shifts  : Number of right bit shift to be applied after the\n//                        multiplication\n//      - vector_length : Number of elements in |in_vector|\n//\n// Output:\n//      - out_vector    : Output vector (can be same as |in_vector|)\n//\n\n//\n// WebRtcSpl_AddVectorsAndShift(...)\n//\n// Performs the vector operation:\n//  out_vector[k] = (in_vector1[k] + in_vector2[k])>>right_shifts\n//\n// Input:\n//      - in_vector1    : Input vector 1\n//      - in_vector2    : Input vector 2\n//      - right_shifts  : Number of right bit shift to be applied after the\n//                        multiplication\n//      - vector_length : Number of elements in |in_vector1| and |in_vector2|\n//\n// Output:\n//      - out_vector    : Output vector (can be same as |in_vector1|)\n//\n\n//\n// WebRtcSpl_AddAffineVectorToVector(...)\n//\n// Adds an affine transformed vector to another vector |out_vector|, i.e,\n// performs\n//  out_vector[k] += (in_vector[k]*gain+add_constant)>>right_shifts\n//\n// Input:\n//      - in_vector     : Input vector\n//      - gain          : Gain value, used to multiply the in vector with\n//      - add_constant  : Constant value to add (usually 1<<(right_shifts-1),\n//                        but others can be used as well\n//      - right_shifts  : Number of right bit shifts (0-16)\n//      - vector_length : Number of samples in |in_vector| and |out_vector|\n//\n// Output:\n//      - out_vector    : Vector with the output\n//\n\n//\n// WebRtcSpl_AffineTransformVector(...)\n//\n// Affine transforms a vector, i.e, performs\n//  out_vector[k] = (in_vector[k]*gain+add_constant)>>right_shifts\n//\n// Input:\n//      - in_vector     : Input vector\n//      - gain          : Gain value, used to multiply the in vector with\n//      - add_constant  : Constant value to add (usually 1<<(right_shifts-1),\n//                        but others can be used as well\n//      - right_shifts  : Number of right bit shifts (0-16)\n//      - vector_length : Number of samples in |in_vector| and |out_vector|\n//\n// Output:\n//      - out_vector    : Vector with the output\n//\n\n//\n// WebRtcSpl_AutoCorrelation(...)\n//\n// A 32-bit fix-point implementation of auto-correlation computation\n//\n// Input:\n//      - vector        : Vector to calculate autocorrelation upon\n//      - vector_length : Length (in samples) of |vector|\n//      - order         : The order up to which the autocorrelation should be\n//                        calculated\n//\n// Output:\n//      - result_vector : auto-correlation values (values should be seen\n//                        relative to each other since the absolute values\n//                        might have been down shifted to avoid overflow)\n//\n//      - scale         : The number of left shifts required to obtain the\n//                        auto-correlation in Q0\n//\n// Return value         : Number of samples in |result_vector|, i.e., (order+1)\n//\n\n//\n// WebRtcSpl_LevinsonDurbin(...)\n//\n// A 32-bit fix-point implementation of the Levinson-Durbin algorithm that\n// does NOT use the 64 bit class\n//\n// Input:\n//      - auto_corr : Vector with autocorrelation values of length >=\n//                    |use_order|+1\n//      - use_order : The LPC filter order (support up to order 20)\n//\n// Output:\n//      - lpc_coef  : lpc_coef[0..use_order] LPC coefficients in Q12\n//      - refl_coef : refl_coef[0...use_order-1]| Reflection coefficients in\n//                    Q15\n//\n// Return value     : 1 for stable 0 for unstable\n//\n\n//\n// WebRtcSpl_ReflCoefToLpc(...)\n//\n// Converts reflection coefficients |refl_coef| to LPC coefficients |lpc_coef|.\n// This version is a 16 bit operation.\n//\n// NOTE: The 16 bit refl_coef -> lpc_coef conversion might result in a\n// \"slightly unstable\" filter (i.e., a pole just outside the unit circle) in\n// \"rare\" cases even if the reflection coefficients are stable.\n//\n// Input:\n//      - refl_coef : Reflection coefficients in Q15 that should be converted\n//                    to LPC coefficients\n//      - use_order : Number of coefficients in |refl_coef|\n//\n// Output:\n//      - lpc_coef  : LPC coefficients in Q12\n//\n\n//\n// WebRtcSpl_LpcToReflCoef(...)\n//\n// Converts LPC coefficients |lpc_coef| to reflection coefficients |refl_coef|.\n// This version is a 16 bit operation.\n// The conversion is implemented by the step-down algorithm.\n//\n// Input:\n//      - lpc_coef  : LPC coefficients in Q12, that should be converted to\n//                    reflection coefficients\n//      - use_order : Number of coefficients in |lpc_coef|\n//\n// Output:\n//      - refl_coef : Reflection coefficients in Q15.\n//\n\n//\n// WebRtcSpl_AutoCorrToReflCoef(...)\n//\n// Calculates reflection coefficients (16 bit) from auto-correlation values\n//\n// Input:\n//      - auto_corr : Auto-correlation values\n//      - use_order : Number of coefficients wanted be calculated\n//\n// Output:\n//      - refl_coef : Reflection coefficients in Q15.\n//\n\n//\n// WebRtcSpl_CrossCorrelation(...)\n//\n// Calculates the cross-correlation between two sequences |vector1| and\n// |vector2|. |vector1| is fixed and |vector2| slides as the pointer is\n// increased with the amount |step_vector2|\n//\n// Input:\n//      - vector1           : First sequence (fixed throughout the correlation)\n//      - vector2           : Second sequence (slides |step_vector2| for each\n//                            new correlation)\n//      - dim_vector        : Number of samples to use in the cross-correlation\n//      - dim_cross_corr    : Number of cross-correlations to calculate (the\n//                            start position for |vector2| is updated for each\n//                            new one)\n//      - right_shifts      : Number of right bit shifts to use. This will\n//                            become the output Q-domain.\n//      - step_vector2      : How many (positive or negative) steps the\n//                            |vector2| pointer should be updated for each new\n//                            cross-correlation value.\n//\n// Output:\n//      - cross_corr        : The cross-correlation in Q(-right_shifts)\n//\n\n//\n// WebRtcSpl_GetHanningWindow(...)\n//\n// Creates (the first half of) a Hanning window. Size must be at least 1 and\n// at most 512.\n//\n// Input:\n//      - size      : Length of the requested Hanning window (1 to 512)\n//\n// Output:\n//      - window    : Hanning vector in Q14.\n//\n\n//\n// WebRtcSpl_SqrtOfOneMinusXSquared(...)\n//\n// Calculates y[k] = sqrt(1 - x[k]^2) for each element of the input vector\n// |in_vector|. Input and output values are in Q15.\n//\n// Inputs:\n//      - in_vector     : Values to calculate sqrt(1 - x^2) of\n//      - vector_length : Length of vector |in_vector|\n//\n// Output:\n//      - out_vector    : Output values in Q15\n//\n\n//\n// WebRtcSpl_IncreaseSeed(...)\n//\n// Increases the seed (and returns the new value)\n//\n// Input:\n//      - seed      : Seed for random calculation\n//\n// Output:\n//      - seed      : Updated seed value\n//\n// Return value     : The new seed value\n//\n\n//\n// WebRtcSpl_RandU(...)\n//\n// Produces a uniformly distributed value in the WebRtc_Word16 range\n//\n// Input:\n//      - seed      : Seed for random calculation\n//\n// Output:\n//      - seed      : Updated seed value\n//\n// Return value     : Uniformly distributed value in the range\n//                    [Word16_MIN...Word16_MAX]\n//\n\n//\n// WebRtcSpl_RandN(...)\n//\n// Produces a normal distributed value in the WebRtc_Word16 range\n//\n// Input:\n//      - seed      : Seed for random calculation\n//\n// Output:\n//      - seed      : Updated seed value\n//\n// Return value     : N(0,1) value in the Q13 domain\n//\n\n//\n// WebRtcSpl_RandUArray(...)\n//\n// Produces a uniformly distributed vector with elements in the WebRtc_Word16\n// range\n//\n// Input:\n//      - vector_length : Samples wanted in the vector\n//      - seed          : Seed for random calculation\n//\n// Output:\n//      - vector        : Vector with the uniform values\n//      - seed          : Updated seed value\n//\n// Return value         : Number of samples in vector, i.e., |vector_length|\n//\n\n//\n// WebRtcSpl_Sqrt(...)\n//\n// Returns the square root of the input value |value|. The precision of this\n// function is integer precision, i.e., sqrt(8) gives 2 as answer.\n// If |value| is a negative number then 0 is returned.\n//\n// Algorithm:\n//\n// A sixth order Taylor Series expansion is used here to compute the square\n// root of a number y^0.5 = (1+x)^0.5\n// where\n// x = y-1\n//   = 1+(x/2)-0.5*((x/2)^2+0.5*((x/2)^3-0.625*((x/2)^4+0.875*((x/2)^5)\n// 0.5 <= x < 1\n//\n// Input:\n//      - value     : Value to calculate sqrt of\n//\n// Return value     : Result of the sqrt calculation\n//\n\n//\n// WebRtcSpl_SqrtFloor(...)\n//\n// Returns the square root of the input value |value|. The precision of this\n// function is rounding down integer precision, i.e., sqrt(8) gives 2 as answer.\n// If |value| is a negative number then 0 is returned.\n//\n// Algorithm:\n//\n// An iterative 4 cylce/bit routine\n//\n// Input:\n//      - value     : Value to calculate sqrt of\n//\n// Return value     : Result of the sqrt calculation\n//\n\n//\n// WebRtcSpl_DivU32U16(...)\n//\n// Divides a WebRtc_UWord32 |num| by a WebRtc_UWord16 |den|.\n//\n// If |den|==0, (WebRtc_UWord32)0xFFFFFFFF is returned.\n//\n// Input:\n//      - num       : Numerator\n//      - den       : Denominator\n//\n// Return value     : Result of the division (as a WebRtc_UWord32), i.e., the\n//                    integer part of num/den.\n//\n\n//\n// WebRtcSpl_DivW32W16(...)\n//\n// Divides a WebRtc_Word32 |num| by a WebRtc_Word16 |den|.\n//\n// If |den|==0, (WebRtc_Word32)0x7FFFFFFF is returned.\n//\n// Input:\n//      - num       : Numerator\n//      - den       : Denominator\n//\n// Return value     : Result of the division (as a WebRtc_Word32), i.e., the\n//                    integer part of num/den.\n//\n\n//\n// WebRtcSpl_DivW32W16ResW16(...)\n//\n// Divides a WebRtc_Word32 |num| by a WebRtc_Word16 |den|, assuming that the\n// result is less than 32768, otherwise an unpredictable result will occur.\n//\n// If |den|==0, (WebRtc_Word16)0x7FFF is returned.\n//\n// Input:\n//      - num       : Numerator\n//      - den       : Denominator\n//\n// Return value     : Result of the division (as a WebRtc_Word16), i.e., the\n//                    integer part of num/den.\n//\n\n//\n// WebRtcSpl_DivResultInQ31(...)\n//\n// Divides a WebRtc_Word32 |num| by a WebRtc_Word16 |den|, assuming that the\n// absolute value of the denominator is larger than the numerator, otherwise\n// an unpredictable result will occur.\n//\n// Input:\n//      - num       : Numerator\n//      - den       : Denominator\n//\n// Return value     : Result of the division in Q31.\n//\n\n//\n// WebRtcSpl_DivW32HiLow(...)\n//\n// Divides a WebRtc_Word32 |num| by a denominator in hi, low format. The\n// absolute value of the denominator has to be larger (or equal to) the\n// numerator.\n//\n// Input:\n//      - num       : Numerator\n//      - den_hi    : High part of denominator\n//      - den_low   : Low part of denominator\n//\n// Return value     : Divided value in Q31\n//\n\n//\n// WebRtcSpl_Energy(...)\n//\n// Calculates the energy of a vector\n//\n// Input:\n//      - vector        : Vector which the energy should be calculated on\n//      - vector_length : Number of samples in vector\n//\n// Output:\n//      - scale_factor  : Number of left bit shifts needed to get the physical\n//                        energy value, i.e, to get the Q0 value\n//\n// Return value         : Energy value in Q(-|scale_factor|)\n//\n\n//\n// WebRtcSpl_FilterAR(...)\n//\n// Performs a 32-bit AR filtering on a vector in Q12\n//\n// Input:\n//  - ar_coef                   : AR-coefficient vector (values in Q12),\n//                                ar_coef[0] must be 4096.\n//  - ar_coef_length            : Number of coefficients in |ar_coef|.\n//  - in_vector                 : Vector to be filtered.\n//  - in_vector_length          : Number of samples in |in_vector|.\n//  - filter_state              : Current state (higher part) of the filter.\n//  - filter_state_length       : Length (in samples) of |filter_state|.\n//  - filter_state_low          : Current state (lower part) of the filter.\n//  - filter_state_low_length   : Length (in samples) of |filter_state_low|.\n//  - out_vector_low_length     : Maximum length (in samples) of\n//                                |out_vector_low|.\n//\n// Output:\n//  - filter_state              : Updated state (upper part) vector.\n//  - filter_state_low          : Updated state (lower part) vector.\n//  - out_vector                : Vector containing the upper part of the\n//                                filtered values.\n//  - out_vector_low            : Vector containing the lower part of the\n//                                filtered values.\n//\n// Return value                 : Number of samples in the |out_vector|.\n//\n\n//\n// WebRtcSpl_FilterMAFastQ12(...)\n//\n// Performs a MA filtering on a vector in Q12\n//\n// Input:\n//      - in_vector         : Input samples (state in positions\n//                            in_vector[-order] .. in_vector[-1])\n//      - ma_coef           : Filter coefficients (in Q12)\n//      - ma_coef_length    : Number of B coefficients (order+1)\n//      - vector_length     : Number of samples to be filtered\n//\n// Output:\n//      - out_vector        : Filtered samples\n//\n\n//\n// WebRtcSpl_FilterARFastQ12(...)\n//\n// Performs a AR filtering on a vector in Q12\n//\n// Input:\n//      - in_vector         : Input samples\n//      - out_vector        : State information in positions\n//                            out_vector[-order] .. out_vector[-1]\n//      - ar_coef           : Filter coefficients (in Q12)\n//      - ar_coef_length    : Number of B coefficients (order+1)\n//      - vector_length     : Number of samples to be filtered\n//\n// Output:\n//      - out_vector        : Filtered samples\n//\n\n//\n// WebRtcSpl_DownsampleFast(...)\n//\n// Performs a MA down sampling filter on a vector\n//\n// Input:\n//      - in_vector         : Input samples (state in positions\n//                            in_vector[-order] .. in_vector[-1])\n//      - in_vector_length  : Number of samples in |in_vector| to be filtered.\n//                            This must be at least\n//                            |delay| + |factor|*(|out_vector_length|-1) + 1)\n//      - out_vector_length : Number of down sampled samples desired\n//      - ma_coef           : Filter coefficients (in Q12)\n//      - ma_coef_length    : Number of B coefficients (order+1)\n//      - factor            : Decimation factor\n//      - delay             : Delay of filter (compensated for in out_vector)\n//\n// Output:\n//      - out_vector        : Filtered samples\n//\n// Return value             : 0 if OK, -1 if |in_vector| is too short\n//\n\n//\n// WebRtcSpl_DotProductWithScale(...)\n//\n// Calculates the dot product between two (WebRtc_Word16) vectors\n//\n// Input:\n//      - vector1       : Vector 1\n//      - vector2       : Vector 2\n//      - vector_length : Number of samples used in the dot product\n//      - scaling       : The number of right bit shifts to apply on each term\n//                        during calculation to avoid overflow, i.e., the\n//                        output will be in Q(-|scaling|)\n//\n// Return value         : The dot product in Q(-scaling)\n//\n\n//\n// WebRtcSpl_ComplexIFFT(...)\n//\n// Complex Inverse FFT\n//\n// Computes an inverse complex 2^|stages|-point FFT on the input vector, which\n// is in bit-reversed order. The original content of the vector is destroyed in\n// the process, since the input is overwritten by the output, normal-ordered,\n// FFT vector. With X as the input complex vector, y as the output complex\n// vector and with M = 2^|stages|, the following is computed:\n//\n//        M-1\n// y(k) = sum[X(i)*[cos(2*pi*i*k/M) + j*sin(2*pi*i*k/M)]]\n//        i=0\n//\n// The implementations are optimized for speed, not for code size. It uses the\n// decimation-in-time algorithm with radix-2 butterfly technique.\n//\n// Input:\n//      - vector    : In pointer to complex vector containing 2^|stages|\n//                    real elements interleaved with 2^|stages| imaginary\n//                    elements.\n//                    [ReImReImReIm....]\n//                    The elements are in Q(-scale) domain, see more on Return\n//                    Value below.\n//\n//      - stages    : Number of FFT stages. Must be at least 3 and at most 10,\n//                    since the table WebRtcSpl_kSinTable1024[] is 1024\n//                    elements long.\n//\n//      - mode      : This parameter gives the user to choose how the FFT\n//                    should work.\n//                    mode==0: Low-complexity and Low-accuracy mode\n//                    mode==1: High-complexity and High-accuracy mode\n//\n// Output:\n//      - vector    : Out pointer to the FFT vector (the same as input).\n//\n// Return Value     : The scale value that tells the number of left bit shifts\n//                    that the elements in the |vector| should be shifted with\n//                    in order to get Q0 values, i.e. the physically correct\n//                    values. The scale parameter is always 0 or positive,\n//                    except if N>1024 (|stages|>10), which returns a scale\n//                    value of -1, indicating error.\n//\n\n//\n// WebRtcSpl_ComplexFFT(...)\n//\n// Complex FFT\n//\n// Computes a complex 2^|stages|-point FFT on the input vector, which is in\n// bit-reversed order. The original content of the vector is destroyed in\n// the process, since the input is overwritten by the output, normal-ordered,\n// FFT vector. With x as the input complex vector, Y as the output complex\n// vector and with M = 2^|stages|, the following is computed:\n//\n//              M-1\n// Y(k) = 1/M * sum[x(i)*[cos(2*pi*i*k/M) + j*sin(2*pi*i*k/M)]]\n//              i=0\n//\n// The implementations are optimized for speed, not for code size. It uses the\n// decimation-in-time algorithm with radix-2 butterfly technique.\n//\n// This routine prevents overflow by scaling by 2 before each FFT stage. This is\n// a fixed scaling, for proper normalization - there will be log2(n) passes, so\n// this results in an overall factor of 1/n, distributed to maximize arithmetic\n// accuracy.\n//\n// Input:\n//      - vector    : In pointer to complex vector containing 2^|stages| real\n//                    elements interleaved with 2^|stages| imaginary elements.\n//                    [ReImReImReIm....]\n//                    The output is in the Q0 domain.\n//\n//      - stages    : Number of FFT stages. Must be at least 3 and at most 10,\n//                    since the table WebRtcSpl_kSinTable1024[] is 1024\n//                    elements long.\n//\n//      - mode      : This parameter gives the user to choose how the FFT\n//                    should work.\n//                    mode==0: Low-complexity and Low-accuracy mode\n//                    mode==1: High-complexity and High-accuracy mode\n//\n// Output:\n//      - vector    : The output FFT vector is in the Q0 domain.\n//\n// Return value     : The scale parameter is always 0, except if N>1024,\n//                    which returns a scale value of -1, indicating error.\n//\n\n//\n// WebRtcSpl_ComplexBitReverse(...)\n//\n// Complex Bit Reverse\n//\n// This function bit-reverses the position of elements in the complex input\n// vector into the output vector.\n//\n// If you bit-reverse a linear-order array, you obtain a bit-reversed order\n// array. If you bit-reverse a bit-reversed order array, you obtain a\n// linear-order array.\n//\n// Input:\n//      - vector    : In pointer to complex vector containing 2^|stages| real\n//                    elements interleaved with 2^|stages| imaginary elements.\n//                    [ReImReImReIm....]\n//      - stages    : Number of FFT stages. Must be at least 3 and at most 10,\n//                    since the table WebRtcSpl_kSinTable1024[] is 1024\n//                    elements long.\n//\n// Output:\n//      - vector    : Out pointer to complex vector in bit-reversed order.\n//                    The input vector is over written.\n//\n\n//\n// WebRtcSpl_AnalysisQMF(...)\n//\n// Splits a 0-2*F Hz signal into two sub bands: 0-F Hz and F-2*F Hz. The\n// current version has F = 8000, therefore, a super-wideband audio signal is\n// split to lower-band 0-8 kHz and upper-band 8-16 kHz.\n//\n// Input:\n//      - in_data       : Wide band speech signal, 320 samples (10 ms)\n//\n// Input & Output:\n//      - filter_state1 : Filter state for first All-pass filter\n//      - filter_state2 : Filter state for second All-pass filter\n//\n// Output:\n//      - low_band      : Lower-band signal 0-8 kHz band, 160 samples (10 ms)\n//      - high_band     : Upper-band signal 8-16 kHz band (flipped in frequency\n//                        domain), 160 samples (10 ms)\n//\n\n//\n// WebRtcSpl_SynthesisQMF(...)\n//\n// Combines the two sub bands (0-F and F-2*F Hz) into a signal of 0-2*F\n// Hz, (current version has F = 8000 Hz). So the filter combines lower-band\n// (0-8 kHz) and upper-band (8-16 kHz) channels to obtain super-wideband 0-16\n// kHz audio.\n//\n// Input:\n//      - low_band      : The signal with the 0-8 kHz band, 160 samples (10 ms)\n//      - high_band     : The signal with the 8-16 kHz band, 160 samples (10 ms)\n//\n// Input & Output:\n//      - filter_state1 : Filter state for first All-pass filter\n//      - filter_state2 : Filter state for second All-pass filter\n//\n// Output:\n//      - out_data      : Super-wideband speech signal, 0-16 kHz\n//\n\n// WebRtc_Word16 WebRtcSpl_get_version(...)\n//\n// This function gives the version string of the Signal Processing Library.\n//\n// Input:\n//      - length_in_bytes   : The size of Allocated space (in Bytes) where\n//                            the version number is written to (in string format).\n//\n// Output:\n//      - version           : Pointer to a buffer where the version number is written to.\n//\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/interface/spl_inl.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n// This header file includes the inline functions in\n// the fix point signal processing library.\n\n#ifndef WEBRTC_SPL_SPL_INL_H_\n#define WEBRTC_SPL_SPL_INL_H_\n\n#ifdef WEBRTC_ARCH_ARM_V7A\n#include \"spl_inl_armv7.h\"\n#else\n\nstatic __inline WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a,\n                                                  WebRtc_Word16 b) {\n  WebRtc_Word32 s_sum = (WebRtc_Word32) a + (WebRtc_Word32) b;\n\n  if (s_sum > WEBRTC_SPL_WORD16_MAX)\n    s_sum = WEBRTC_SPL_WORD16_MAX;\n  else if (s_sum < WEBRTC_SPL_WORD16_MIN)\n    s_sum = WEBRTC_SPL_WORD16_MIN;\n\n  return (WebRtc_Word16)s_sum;\n}\n\nstatic __inline WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1,\n                                                  WebRtc_Word32 l_var2) {\n  WebRtc_Word32 l_sum;\n\n  // perform long addition\n  l_sum = l_var1 + l_var2;\n\n  // check for under or overflow\n  if (WEBRTC_SPL_IS_NEG(l_var1)) {\n    if (WEBRTC_SPL_IS_NEG(l_var2) && !WEBRTC_SPL_IS_NEG(l_sum)) {\n        l_sum = (WebRtc_Word32)0x80000000;\n    }\n  } else {\n    if (!WEBRTC_SPL_IS_NEG(l_var2) && WEBRTC_SPL_IS_NEG(l_sum)) {\n        l_sum = (WebRtc_Word32)0x7FFFFFFF;\n    }\n  }\n\n  return l_sum;\n}\n\nstatic __inline WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1,\n                                                  WebRtc_Word16 var2) {\n  WebRtc_Word32 l_diff;\n  WebRtc_Word16 s_diff;\n\n  // perform subtraction\n  l_diff = (WebRtc_Word32)var1 - (WebRtc_Word32)var2;\n\n  // default setting\n  s_diff = (WebRtc_Word16) l_diff;\n\n  // check for overflow\n  if (l_diff > (WebRtc_Word32)32767)\n  s_diff = (WebRtc_Word16)32767;\n\n  // check for underflow\n  if (l_diff < (WebRtc_Word32)-32768)\n  s_diff = (WebRtc_Word16)-32768;\n\n  return s_diff;\n}\n\nstatic __inline WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1,\n                                                  WebRtc_Word32 l_var2) {\n  WebRtc_Word32 l_diff;\n\n  // perform subtraction\n  l_diff = l_var1 - l_var2;\n\n  // check for underflow\n  if ((l_var1 < 0) && (l_var2 > 0) && (l_diff > 0))\n    l_diff = (WebRtc_Word32)0x80000000;\n  // check for overflow\n  if ((l_var1 > 0) && (l_var2 < 0) && (l_diff < 0))\n    l_diff = (WebRtc_Word32)0x7FFFFFFF;\n\n  return l_diff;\n}\n\nstatic __inline WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n) {\n  int bits;\n\n  if (0xFFFF0000 & n) {\n    bits = 16;\n  } else {\n    bits = 0;\n  }\n  if (0x0000FF00 & (n >> bits)) bits += 8;\n  if (0x000000F0 & (n >> bits)) bits += 4;\n  if (0x0000000C & (n >> bits)) bits += 2;\n  if (0x00000002 & (n >> bits)) bits += 1;\n  if (0x00000001 & (n >> bits)) bits += 1;\n\n  return bits;\n}\n\nstatic __inline int WebRtcSpl_NormW32(WebRtc_Word32 a) {\n  int zeros;\n\n  if (a <= 0) a ^= 0xFFFFFFFF;\n\n  if (!(0xFFFF8000 & a)) {\n    zeros = 16;\n  } else {\n    zeros = 0;\n  }\n  if (!(0xFF800000 & (a << zeros))) zeros += 8;\n  if (!(0xF8000000 & (a << zeros))) zeros += 4;\n  if (!(0xE0000000 & (a << zeros))) zeros += 2;\n  if (!(0xC0000000 & (a << zeros))) zeros += 1;\n\n  return zeros;\n}\n\nstatic __inline int WebRtcSpl_NormU32(WebRtc_UWord32 a) {\n  int zeros;\n\n  if (a == 0) return 0;\n\n  if (!(0xFFFF0000 & a)) {\n    zeros = 16;\n  } else {\n    zeros = 0;\n  }\n  if (!(0xFF000000 & (a << zeros))) zeros += 8;\n  if (!(0xF0000000 & (a << zeros))) zeros += 4;\n  if (!(0xC0000000 & (a << zeros))) zeros += 2;\n  if (!(0x80000000 & (a << zeros))) zeros += 1;\n\n  return zeros;\n}\n\nstatic __inline int WebRtcSpl_NormW16(WebRtc_Word16 a) {\n  int zeros;\n\n  if (a <= 0) a ^= 0xFFFF;\n\n  if (!(0xFF80 & a)) {\n    zeros = 8;\n  } else {\n    zeros = 0;\n  }\n  if (!(0xF800 & (a << zeros))) zeros += 4;\n  if (!(0xE000 & (a << zeros))) zeros += 2;\n  if (!(0xC000 & (a << zeros))) zeros += 1;\n\n  return zeros;\n}\n\n#endif  // WEBRTC_ARCH_ARM_V7A\n\n#endif  // WEBRTC_SPL_SPL_INL_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/interface/spl_inl_armv7.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n// This header file includes the inline functions for ARM processors in\n// the fix point signal processing library.\n\n#ifndef WEBRTC_SPL_SPL_INL_ARMV7_H_\n#define WEBRTC_SPL_SPL_INL_ARMV7_H_\n\nstatic __inline WebRtc_Word32 WEBRTC_SPL_MUL_16_32_RSFT16(WebRtc_Word16 a,\n                                                          WebRtc_Word32 b) {\n  WebRtc_Word32 tmp;\n  __asm__(\"smulwb %0, %1, %2\":\"=r\"(tmp):\"r\"(b), \"r\"(a));\n  return tmp;\n}\n\nstatic __inline WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32(WebRtc_Word16 a,\n                                                          WebRtc_Word16 b,\n                                                          WebRtc_Word32 c) {\n  WebRtc_Word32 tmp;\n  __asm__(\"pkhbt %0, %1, %2, lsl #16\" : \"=r\"(tmp) : \"r\"(b), \"r\"(a));\n  __asm__(\"smmul %0, %1, %2\":\"=r\"(tmp):\"r\"(tmp), \"r\"(c));\n  return tmp;\n}\n\nstatic __inline WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32BI(WebRtc_Word32 a,\n                                                            WebRtc_Word32 b) {\n  WebRtc_Word32 tmp;\n  __asm__(\"smmul %0, %1, %2\":\"=r\"(tmp):\"r\"(a), \"r\"(b));\n  return tmp;\n}\n\nstatic __inline WebRtc_Word32 WEBRTC_SPL_MUL_16_16(WebRtc_Word16 a,\n                                                   WebRtc_Word16 b) {\n  WebRtc_Word32 tmp;\n  __asm__(\"smulbb %0, %1, %2\":\"=r\"(tmp):\"r\"(a), \"r\"(b));\n  return tmp;\n}\n\nstatic __inline WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a,\n                                                  WebRtc_Word16 b) {\n  WebRtc_Word32 s_sum;\n\n  __asm__(\"qadd16 %0, %1, %2\":\"=r\"(s_sum):\"r\"(a), \"r\"(b));\n\n  return (WebRtc_Word16) s_sum;\n}\n\nstatic __inline WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1,\n                                                  WebRtc_Word32 l_var2) {\n  WebRtc_Word32 l_sum;\n\n  __asm__(\"qadd %0, %1, %2\":\"=r\"(l_sum):\"r\"(l_var1), \"r\"(l_var2));\n\n  return l_sum;\n}\n\nstatic __inline WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1,\n                                                  WebRtc_Word16 var2) {\n  WebRtc_Word32 s_sub;\n\n  __asm__(\"qsub16 %0, %1, %2\":\"=r\"(s_sub):\"r\"(var1), \"r\"(var2));\n\n  return (WebRtc_Word16)s_sub;\n}\n\nstatic __inline WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1,\n                                                  WebRtc_Word32 l_var2) {\n  WebRtc_Word32 l_sub;\n\n  __asm__(\"qsub %0, %1, %2\":\"=r\"(l_sub):\"r\"(l_var1), \"r\"(l_var2));\n\n  return l_sub;\n}\n\nstatic __inline WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n) {\n  WebRtc_Word32 tmp;\n\n  __asm__(\"clz %0, %1\":\"=r\"(tmp):\"r\"(n));\n\n  return (WebRtc_Word16)(32 - tmp);\n}\n\nstatic __inline int WebRtcSpl_NormW32(WebRtc_Word32 a) {\n  WebRtc_Word32 tmp;\n\n  if (a <= 0) a ^= 0xFFFFFFFF;\n\n  __asm__(\"clz %0, %1\":\"=r\"(tmp):\"r\"(a));\n\n  return tmp - 1;\n}\n\nstatic __inline int WebRtcSpl_NormU32(WebRtc_UWord32 a) {\n  int tmp;\n\n  if (a == 0) return 0;\n\n  __asm__(\"clz %0, %1\":\"=r\"(tmp):\"r\"(a));\n\n  return tmp;\n}\n\nstatic __inline int WebRtcSpl_NormW16(WebRtc_Word16 a) {\n  WebRtc_Word32 tmp;\n\n  if (a <= 0) a ^= 0xFFFFFFFF;\n\n  __asm__(\"clz %0, %1\":\"=r\"(tmp):\"r\"(a));\n\n  return tmp - 17;\n}\n\n#endif  // WEBRTC_SPL_SPL_INL_ARMV7_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/auto_corr_to_refl_coef.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_AutoCorrToReflCoef().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nvoid WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 *R, int use_order, WebRtc_Word16 *K)\n{\n    int i, n;\n    WebRtc_Word16 tmp;\n    G_CONST WebRtc_Word32 *rptr;\n    WebRtc_Word32 L_num, L_den;\n    WebRtc_Word16 *acfptr, *pptr, *wptr, *p1ptr, *w1ptr, ACF[WEBRTC_SPL_MAX_LPC_ORDER],\n            P[WEBRTC_SPL_MAX_LPC_ORDER], W[WEBRTC_SPL_MAX_LPC_ORDER];\n\n    // Initialize loop and pointers.\n    acfptr = ACF;\n    rptr = R;\n    pptr = P;\n    p1ptr = &P[1];\n    w1ptr = &W[1];\n    wptr = w1ptr;\n\n    // First loop; n=0. Determine shifting.\n    tmp = WebRtcSpl_NormW32(*R);\n    *acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16);\n    *pptr++ = *acfptr++;\n\n    // Initialize ACF, P and W.\n    for (i = 1; i <= use_order; i++)\n    {\n        *acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16);\n        *wptr++ = *acfptr;\n        *pptr++ = *acfptr++;\n    }\n\n    // Compute reflection coefficients.\n    for (n = 1; n <= use_order; n++, K++)\n    {\n        tmp = WEBRTC_SPL_ABS_W16(*p1ptr);\n        if (*P < tmp)\n        {\n            for (i = n; i <= use_order; i++)\n                *K++ = 0;\n\n            return;\n        }\n\n        // Division: WebRtcSpl_div(tmp, *P)\n        *K = 0;\n        if (tmp != 0)\n        {\n            L_num = tmp;\n            L_den = *P;\n            i = 15;\n            while (i--)\n            {\n                (*K) <<= 1;\n                L_num <<= 1;\n                if (L_num >= L_den)\n                {\n                    L_num -= L_den;\n                    (*K)++;\n                }\n            }\n            if (*p1ptr > 0)\n                *K = -*K;\n        }\n\n        // Last iteration; don't do Schur recursion.\n        if (n == use_order)\n            return;\n\n        // Schur recursion.\n        pptr = P;\n        wptr = w1ptr;\n        tmp = (WebRtc_Word16)(((WebRtc_Word32)*p1ptr * (WebRtc_Word32)*K + 16384) >> 15);\n        *pptr = WEBRTC_SPL_ADD_SAT_W16( *pptr, tmp );\n        pptr++;\n        for (i = 1; i <= use_order - n; i++)\n        {\n            tmp = (WebRtc_Word16)(((WebRtc_Word32)*wptr * (WebRtc_Word32)*K + 16384) >> 15);\n            *pptr = WEBRTC_SPL_ADD_SAT_W16( *(pptr+1), tmp );\n            pptr++;\n            tmp = (WebRtc_Word16)(((WebRtc_Word32)*pptr * (WebRtc_Word32)*K + 16384) >> 15);\n            *wptr = WEBRTC_SPL_ADD_SAT_W16( *wptr, tmp );\n            wptr++;\n        }\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/auto_correlation.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_AutoCorrelation().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nint WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* in_vector,\n                              int in_vector_length,\n                              int order,\n                              WebRtc_Word32* result,\n                              int* scale)\n{\n    WebRtc_Word32 sum;\n    int i, j;\n    WebRtc_Word16 smax; // Sample max\n    G_CONST WebRtc_Word16* xptr1;\n    G_CONST WebRtc_Word16* xptr2;\n    WebRtc_Word32* resultptr;\n    int scaling = 0;\n\n#ifdef _ARM_OPT_\n#pragma message(\"NOTE: _ARM_OPT_ optimizations are used\")\n    WebRtc_Word16 loops4;\n#endif\n\n    if (order < 0)\n        order = in_vector_length;\n\n    // Find the max. sample\n    smax = WebRtcSpl_MaxAbsValueW16(in_vector, in_vector_length);\n\n    // In order to avoid overflow when computing the sum we should scale the samples so that\n    // (in_vector_length * smax * smax) will not overflow.\n\n    if (smax == 0)\n    {\n        scaling = 0;\n    } else\n    {\n        int nbits = WebRtcSpl_GetSizeInBits(in_vector_length); // # of bits in the sum loop\n        int t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); // # of bits to normalize smax\n\n        if (t > nbits)\n        {\n            scaling = 0;\n        } else\n        {\n            scaling = nbits - t;\n        }\n\n    }\n\n    resultptr = result;\n\n    // Perform the actual correlation calculation\n    for (i = 0; i < order + 1; i++)\n    {\n        int loops = (in_vector_length - i);\n        sum = 0;\n        xptr1 = in_vector;\n        xptr2 = &in_vector[i];\n#ifndef _ARM_OPT_\n        for (j = loops; j > 0; j--)\n        {\n            sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1++, *xptr2++, scaling);\n        }\n#else\n        loops4 = (loops >> 2) << 2;\n\n        if (scaling == 0)\n        {\n            for (j = 0; j < loops4; j = j + 4)\n            {\n                sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);\n                xptr1++;\n                xptr2++;\n                sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);\n                xptr1++;\n                xptr2++;\n                sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);\n                xptr1++;\n                xptr2++;\n                sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);\n                xptr1++;\n                xptr2++;\n            }\n\n            for (j = loops4; j < loops; j++)\n            {\n                sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);\n                xptr1++;\n                xptr2++;\n            }\n        }\n        else\n        {\n            for (j = 0; j < loops4; j = j + 4)\n            {\n                sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);\n                xptr1++;\n                xptr2++;\n                sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);\n                xptr1++;\n                xptr2++;\n                sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);\n                xptr1++;\n                xptr2++;\n                sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);\n                xptr1++;\n                xptr2++;\n            }\n\n            for (j = loops4; j < loops; j++)\n            {\n                sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);\n                xptr1++;\n                xptr2++;\n            }\n        }\n\n#endif\n        *resultptr++ = sum;\n    }\n\n    *scale = scaling;\n\n    return order + 1;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/complex_bit_reverse.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_ComplexBitReverse().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nvoid WebRtcSpl_ComplexBitReverse(WebRtc_Word16 frfi[], int stages)\n{\n    int mr, nn, n, l, m;\n    WebRtc_Word16 tr, ti;\n\n    n = 1 << stages;\n\n    mr = 0;\n    nn = n - 1;\n\n    // decimation in time - re-order data\n    for (m = 1; m <= nn; ++m)\n    {\n        l = n;\n        do\n        {\n            l >>= 1;\n        } while (mr + l > nn);\n        mr = (mr & (l - 1)) + l;\n\n        if (mr <= m)\n            continue;\n\n        tr = frfi[2 * m];\n        frfi[2 * m] = frfi[2 * mr];\n        frfi[2 * mr] = tr;\n\n        ti = frfi[2 * m + 1];\n        frfi[2 * m + 1] = frfi[2 * mr + 1];\n        frfi[2 * mr + 1] = ti;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/complex_fft.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_ComplexFFT().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\n#define CFFTSFT 14\n#define CFFTRND 1\n#define CFFTRND2 16384\n\nint WebRtcSpl_ComplexFFT(WebRtc_Word16 frfi[], int stages, int mode)\n{\n    int i, j, l, k, istep, n, m;\n    WebRtc_Word16 wr, wi;\n    WebRtc_Word32 tr32, ti32, qr32, qi32;\n\n    /* The 1024-value is a constant given from the size of WebRtcSpl_kSinTable1024[],\n     * and should not be changed depending on the input parameter 'stages'\n     */\n    n = 1 << stages;\n    if (n > 1024)\n        return -1;\n\n    l = 1;\n    k = 10 - 1; /* Constant for given WebRtcSpl_kSinTable1024[]. Do not change\n         depending on the input parameter 'stages' */\n\n    if (mode == 0)\n    {\n        // mode==0: Low-complexity and Low-accuracy mode\n        while (l < n)\n        {\n            istep = l << 1;\n\n            for (m = 0; m < l; ++m)\n            {\n                j = m << k;\n\n                /* The 256-value is a constant given as 1/4 of the size of\n                 * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input\n                 * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2\n                 */\n                wr = WebRtcSpl_kSinTable1024[j + 256];\n                wi = -WebRtcSpl_kSinTable1024[j];\n\n                for (i = m; i < n; i += istep)\n                {\n                    j = i + l;\n\n                    tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])\n                            - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1])), 15);\n\n                    ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])\n                            + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j])), 15);\n\n                    qr32 = (WebRtc_Word32)frfi[2 * i];\n                    qi32 = (WebRtc_Word32)frfi[2 * i + 1];\n                    frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, 1);\n                    frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, 1);\n                    frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, 1);\n                    frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, 1);\n                }\n            }\n\n            --k;\n            l = istep;\n\n        }\n\n    } else\n    {\n        // mode==1: High-complexity and High-accuracy mode\n        while (l < n)\n        {\n            istep = l << 1;\n\n            for (m = 0; m < l; ++m)\n            {\n                j = m << k;\n\n                /* The 256-value is a constant given as 1/4 of the size of\n                 * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input\n                 * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2\n                 */\n                wr = WebRtcSpl_kSinTable1024[j + 256];\n                wi = -WebRtcSpl_kSinTable1024[j];\n\n#ifdef WEBRTC_ARCH_ARM_V7A\n                WebRtc_Word32 wri;\n                WebRtc_Word32 frfi_r;\n                __asm__(\"pkhbt %0, %1, %2, lsl #16\" : \"=r\"(wri) :\n                    \"r\"((WebRtc_Word32)wr), \"r\"((WebRtc_Word32)wi));\n#endif\n\n                for (i = m; i < n; i += istep)\n                {\n                    j = i + l;\n\n#ifdef WEBRTC_ARCH_ARM_V7A\n                    __asm__(\"pkhbt %0, %1, %2, lsl #16\" : \"=r\"(frfi_r) :\n                        \"r\"((WebRtc_Word32)frfi[2*j]), \"r\"((WebRtc_Word32)frfi[2*j +1]));\n                    __asm__(\"smlsd %0, %1, %2, %3\" : \"=r\"(tr32) :\n                        \"r\"(wri), \"r\"(frfi_r), \"r\"(CFFTRND));\n                    __asm__(\"smladx %0, %1, %2, %3\" : \"=r\"(ti32) :\n                        \"r\"(wri), \"r\"(frfi_r), \"r\"(CFFTRND));\n    \n#else\n                    tr32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])\n                            - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CFFTRND;\n\n                    ti32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])\n                            + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CFFTRND;\n#endif\n\n                    tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CFFTSFT);\n                    ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CFFTSFT);\n\n                    qr32 = ((WebRtc_Word32)frfi[2 * i]) << CFFTSFT;\n                    qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CFFTSFT;\n\n                    frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(\n                            (qr32 - tr32 + CFFTRND2), 1 + CFFTSFT);\n                    frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(\n                            (qi32 - ti32 + CFFTRND2), 1 + CFFTSFT);\n                    frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(\n                            (qr32 + tr32 + CFFTRND2), 1 + CFFTSFT);\n                    frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(\n                            (qi32 + ti32 + CFFTRND2), 1 + CFFTSFT);\n                }\n            }\n\n            --k;\n            l = istep;\n        }\n    }\n    return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/complex_ifft.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_ComplexIFFT().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\n#define CIFFTSFT 14\n#define CIFFTRND 1\n\nint WebRtcSpl_ComplexIFFT(WebRtc_Word16 frfi[], int stages, int mode)\n{\n    int i, j, l, k, istep, n, m, scale, shift;\n    WebRtc_Word16 wr, wi;\n    WebRtc_Word32 tr32, ti32, qr32, qi32;\n    WebRtc_Word32 tmp32, round2;\n\n    /* The 1024-value is a constant given from the size of WebRtcSpl_kSinTable1024[],\n     * and should not be changed depending on the input parameter 'stages'\n     */\n    n = 1 << stages;\n    if (n > 1024)\n        return -1;\n\n    scale = 0;\n\n    l = 1;\n    k = 10 - 1; /* Constant for given WebRtcSpl_kSinTable1024[]. Do not change\n         depending on the input parameter 'stages' */\n\n    while (l < n)\n    {\n        // variable scaling, depending upon data\n        shift = 0;\n        round2 = 8192;\n\n        tmp32 = (WebRtc_Word32)WebRtcSpl_MaxAbsValueW16(frfi, 2 * n);\n        if (tmp32 > 13573)\n        {\n            shift++;\n            scale++;\n            round2 <<= 1;\n        }\n        if (tmp32 > 27146)\n        {\n            shift++;\n            scale++;\n            round2 <<= 1;\n        }\n\n        istep = l << 1;\n\n        if (mode == 0)\n        {\n            // mode==0: Low-complexity and Low-accuracy mode\n            for (m = 0; m < l; ++m)\n            {\n                j = m << k;\n\n                /* The 256-value is a constant given as 1/4 of the size of\n                 * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input\n                 * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2\n                 */\n                wr = WebRtcSpl_kSinTable1024[j + 256];\n                wi = WebRtcSpl_kSinTable1024[j];\n\n                for (i = m; i < n; i += istep)\n                {\n                    j = i + l;\n\n                    tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j], 0)\n                            - WEBRTC_SPL_MUL_16_16_RSFT(wi, frfi[2 * j + 1], 0)), 15);\n\n                    ti32 = WEBRTC_SPL_RSHIFT_W32(\n                            (WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j + 1], 0)\n                                    + WEBRTC_SPL_MUL_16_16_RSFT(wi,frfi[2*j],0)), 15);\n\n                    qr32 = (WebRtc_Word32)frfi[2 * i];\n                    qi32 = (WebRtc_Word32)frfi[2 * i + 1];\n                    frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, shift);\n                    frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, shift);\n                    frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, shift);\n                    frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, shift);\n                }\n            }\n        } else\n        {\n            // mode==1: High-complexity and High-accuracy mode\n\n            for (m = 0; m < l; ++m)\n            {\n                j = m << k;\n\n                /* The 256-value is a constant given as 1/4 of the size of\n                 * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input\n                 * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2\n                 */\n                wr = WebRtcSpl_kSinTable1024[j + 256];\n                wi = WebRtcSpl_kSinTable1024[j];\n\n#ifdef WEBRTC_ARCH_ARM_V7A\n                WebRtc_Word32 wri;\n                WebRtc_Word32 frfi_r;\n                __asm__(\"pkhbt %0, %1, %2, lsl #16\" : \"=r\"(wri) :\n                    \"r\"((WebRtc_Word32)wr), \"r\"((WebRtc_Word32)wi));\n#endif\n\n                for (i = m; i < n; i += istep)\n                {\n                    j = i + l;\n\n#ifdef WEBRTC_ARCH_ARM_V7A\n                    __asm__(\"pkhbt %0, %1, %2, lsl #16\" : \"=r\"(frfi_r) :\n                        \"r\"((WebRtc_Word32)frfi[2*j]), \"r\"((WebRtc_Word32)frfi[2*j +1]));\n                    __asm__(\"smlsd %0, %1, %2, %3\" : \"=r\"(tr32) :\n                        \"r\"(wri), \"r\"(frfi_r), \"r\"(CIFFTRND));\n                    __asm__(\"smladx %0, %1, %2, %3\" : \"=r\"(ti32) :\n                        \"r\"(wri), \"r\"(frfi_r), \"r\"(CIFFTRND));\n#else\n\n                    tr32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])\n                            - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CIFFTRND;\n\n                    ti32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])\n                            + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CIFFTRND;\n#endif\n                    tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CIFFTSFT);\n                    ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CIFFTSFT);\n    \n                    qr32 = ((WebRtc_Word32)frfi[2 * i]) << CIFFTSFT;\n                    qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CIFFTSFT;\n    \n                    frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 - tr32+round2),\n                                                                       shift+CIFFTSFT);\n                    frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(\n                            (qi32 - ti32 + round2), shift + CIFFTSFT);\n                    frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 + tr32 + round2),\n                                                                       shift + CIFFTSFT);\n                    frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(\n                            (qi32 + ti32 + round2), shift + CIFFTSFT);\n                }\n            }\n\n        }\n        --k;\n        l = istep;\n    }\n    return scale;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/copy_set_operations.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the implementation of functions\n * WebRtcSpl_MemSetW16()\n * WebRtcSpl_MemSetW32()\n * WebRtcSpl_MemCpyReversedOrder()\n * WebRtcSpl_CopyFromEndW16()\n * WebRtcSpl_ZerosArrayW16()\n * WebRtcSpl_ZerosArrayW32()\n * WebRtcSpl_OnesArrayW16()\n * WebRtcSpl_OnesArrayW32()\n *\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include <string.h>\n#include \"signal_processing_library.h\"\n\n\nvoid WebRtcSpl_MemSetW16(WebRtc_Word16 *ptr, WebRtc_Word16 set_value, int length)\n{\n    int j;\n    WebRtc_Word16 *arrptr = ptr;\n\n    for (j = length; j > 0; j--)\n    {\n        *arrptr++ = set_value;\n    }\n}\n\nvoid WebRtcSpl_MemSetW32(WebRtc_Word32 *ptr, WebRtc_Word32 set_value, int length)\n{\n    int j;\n    WebRtc_Word32 *arrptr = ptr;\n\n    for (j = length; j > 0; j--)\n    {\n        *arrptr++ = set_value;\n    }\n}\n\nvoid WebRtcSpl_MemCpyReversedOrder(WebRtc_Word16* dest, WebRtc_Word16* source, int length)\n{\n    int j;\n    WebRtc_Word16* destPtr = dest;\n    WebRtc_Word16* sourcePtr = source;\n\n    for (j = 0; j < length; j++)\n    {\n        *destPtr-- = *sourcePtr++;\n    }\n}\n\nWebRtc_Word16 WebRtcSpl_CopyFromEndW16(G_CONST WebRtc_Word16 *vector_in,\n                                       WebRtc_Word16 length,\n                                       WebRtc_Word16 samples,\n                                       WebRtc_Word16 *vector_out)\n{\n    // Copy the last <samples> of the input vector to vector_out\n    WEBRTC_SPL_MEMCPY_W16(vector_out, &vector_in[length - samples], samples);\n\n    return samples;\n}\n\nWebRtc_Word16 WebRtcSpl_ZerosArrayW16(WebRtc_Word16 *vector, WebRtc_Word16 length)\n{\n    WebRtcSpl_MemSetW16(vector, 0, length);\n    return length;\n}\n\nWebRtc_Word16 WebRtcSpl_ZerosArrayW32(WebRtc_Word32 *vector, WebRtc_Word16 length)\n{\n    WebRtcSpl_MemSetW32(vector, 0, length);\n    return length;\n}\n\nWebRtc_Word16 WebRtcSpl_OnesArrayW16(WebRtc_Word16 *vector, WebRtc_Word16 length)\n{\n    WebRtc_Word16 i;\n    WebRtc_Word16 *tmpvec = vector;\n    for (i = 0; i < length; i++)\n    {\n        *tmpvec++ = 1;\n    }\n    return length;\n}\n\nWebRtc_Word16 WebRtcSpl_OnesArrayW32(WebRtc_Word32 *vector, WebRtc_Word16 length)\n{\n    WebRtc_Word16 i;\n    WebRtc_Word32 *tmpvec = vector;\n    for (i = 0; i < length; i++)\n    {\n        *tmpvec++ = 1;\n    }\n    return length;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/cos_table.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the 360 degree cos table.\n *\n */\n\n#include \"signal_processing_library.h\"\n\nWebRtc_Word16 WebRtcSpl_kCosTable[] = {\n        8192,  8190,  8187,  8180,  8172,  8160,  8147,  8130,  8112,\n        8091,  8067,  8041,  8012,  7982,  7948,  7912,  7874,  7834,\n        7791,  7745,  7697,  7647,  7595,  7540,  7483,  7424,  7362,\n        7299,  7233,  7164,  7094,  7021,  6947,  6870,  6791,  6710,\n        6627,  6542,  6455,  6366,  6275,  6182,  6087,  5991,  5892,\n        5792,  5690,  5586,  5481,  5374,  5265,  5155,  5043,  4930,\n        4815,  4698,  4580,  4461,  4341,  4219,  4096,  3971,  3845,\n        3719,  3591,  3462,  3331,  3200,  3068,  2935,  2801,  2667,\n        2531,  2395,  2258,  2120,  1981,  1842,  1703,  1563,  1422,\n        1281,  1140,   998,   856,   713,   571,   428,   285,   142,\n           0,  -142,  -285,  -428,  -571,  -713,  -856,  -998, -1140,\n       -1281, -1422, -1563, -1703, -1842, -1981, -2120, -2258, -2395,\n       -2531, -2667, -2801, -2935, -3068, -3200, -3331, -3462, -3591,\n       -3719, -3845, -3971, -4095, -4219, -4341, -4461, -4580, -4698,\n       -4815, -4930, -5043, -5155, -5265, -5374, -5481, -5586, -5690,\n       -5792, -5892, -5991, -6087, -6182, -6275, -6366, -6455, -6542,\n       -6627, -6710, -6791, -6870, -6947, -7021, -7094, -7164, -7233,\n       -7299, -7362, -7424, -7483, -7540, -7595, -7647, -7697, -7745,\n       -7791, -7834, -7874, -7912, -7948, -7982, -8012, -8041, -8067,\n       -8091, -8112, -8130, -8147, -8160, -8172, -8180, -8187, -8190,\n       -8191, -8190, -8187, -8180, -8172, -8160, -8147, -8130, -8112,\n       -8091, -8067, -8041, -8012, -7982, -7948, -7912, -7874, -7834,\n       -7791, -7745, -7697, -7647, -7595, -7540, -7483, -7424, -7362,\n       -7299, -7233, -7164, -7094, -7021, -6947, -6870, -6791, -6710,\n       -6627, -6542, -6455, -6366, -6275, -6182, -6087, -5991, -5892,\n       -5792, -5690, -5586, -5481, -5374, -5265, -5155, -5043, -4930,\n       -4815, -4698, -4580, -4461, -4341, -4219, -4096, -3971, -3845,\n       -3719, -3591, -3462, -3331, -3200, -3068, -2935, -2801, -2667,\n       -2531, -2395, -2258, -2120, -1981, -1842, -1703, -1563, -1422,\n       -1281, -1140,  -998,  -856,  -713,  -571,  -428,  -285,  -142,\n           0,   142,   285,   428,   571,   713,   856,   998,  1140,\n        1281,  1422,  1563,  1703,  1842,  1981,  2120,  2258,  2395,\n        2531,  2667,  2801,  2935,  3068,  3200,  3331,  3462,  3591,\n        3719,  3845,  3971,  4095,  4219,  4341,  4461,  4580,  4698,\n        4815,  4930,  5043,  5155,  5265,  5374,  5481,  5586,  5690,\n        5792,  5892,  5991,  6087,  6182,  6275,  6366,  6455,  6542,\n        6627,  6710,  6791,  6870,  6947,  7021,  7094,  7164,  7233,\n        7299,  7362,  7424,  7483,  7540,  7595,  7647,  7697,  7745,\n        7791,  7834,  7874,  7912,  7948,  7982,  8012,  8041,  8067,\n        8091,  8112,  8130,  8147,  8160,  8172,  8180,  8187,  8190\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/cross_correlation.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_CrossCorrelation().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nvoid WebRtcSpl_CrossCorrelation(WebRtc_Word32* cross_correlation, WebRtc_Word16* seq1,\n                                WebRtc_Word16* seq2, WebRtc_Word16 dim_seq,\n                                WebRtc_Word16 dim_cross_correlation,\n                                WebRtc_Word16 right_shifts,\n                                WebRtc_Word16 step_seq2)\n{\n    int i, j;\n    WebRtc_Word16* seq1Ptr;\n    WebRtc_Word16* seq2Ptr;\n    WebRtc_Word32* CrossCorrPtr;\n\n#ifdef _XSCALE_OPT_\n\n#ifdef _WIN32\n#pragma message(\"NOTE: _XSCALE_OPT_ optimizations are used (overrides _ARM_OPT_ and requires /QRxscale compiler flag)\")\n#endif\n\n    __int64 macc40;\n\n    int iseq1[250];\n    int iseq2[250];\n    int iseq3[250];\n    int * iseq1Ptr;\n    int * iseq2Ptr;\n    int * iseq3Ptr;\n    int len, i_len;\n\n    seq1Ptr = seq1;\n    iseq1Ptr = iseq1;\n    for(i = 0; i < ((dim_seq + 1) >> 1); i++)\n    {\n        *iseq1Ptr = (unsigned short)*seq1Ptr++;\n        *iseq1Ptr++ |= (WebRtc_Word32)*seq1Ptr++ << 16;\n\n    }\n\n    if(dim_seq%2)\n    {\n        *(iseq1Ptr-1) &= 0x0000ffff;\n    }\n    *iseq1Ptr = 0;\n    iseq1Ptr++;\n    *iseq1Ptr = 0;\n    iseq1Ptr++;\n    *iseq1Ptr = 0;\n\n    if(step_seq2 < 0)\n    {\n        seq2Ptr = seq2 - dim_cross_correlation + 1;\n        CrossCorrPtr = &cross_correlation[dim_cross_correlation - 1];\n    }\n    else\n    {\n        seq2Ptr = seq2;\n        CrossCorrPtr = cross_correlation;\n    }\n\n    len = dim_seq + dim_cross_correlation - 1;\n    i_len = (len + 1) >> 1;\n    iseq2Ptr = iseq2;\n\n    iseq3Ptr = iseq3;\n    for(i = 0; i < i_len; i++)\n    {\n        *iseq2Ptr = (unsigned short)*seq2Ptr++;\n        *iseq3Ptr = (unsigned short)*seq2Ptr;\n        *iseq2Ptr++ |= (WebRtc_Word32)*seq2Ptr++ << 16;\n        *iseq3Ptr++ |= (WebRtc_Word32)*seq2Ptr << 16;\n    }\n\n    if(len % 2)\n    {\n        iseq2[i_len - 1] &= 0x0000ffff;\n        iseq3[i_len - 1] = 0;\n    }\n    else\n    iseq3[i_len - 1] &= 0x0000ffff;\n\n    iseq2[i_len] = 0;\n    iseq3[i_len] = 0;\n    iseq2[i_len + 1] = 0;\n    iseq3[i_len + 1] = 0;\n    iseq2[i_len + 2] = 0;\n    iseq3[i_len + 2] = 0;\n\n    // Set pointer to start value\n    iseq2Ptr = iseq2;\n    iseq3Ptr = iseq3;\n\n    i_len = (dim_seq + 7) >> 3;\n    for (i = 0; i < dim_cross_correlation; i++)\n    {\n\n        iseq1Ptr = iseq1;\n\n        macc40 = 0;\n\n        _WriteCoProcessor(macc40, 0);\n\n        if((i & 1))\n        {\n            iseq3Ptr = iseq3 + (i >> 1);\n            for (j = i_len; j > 0; j--)\n            {\n                _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);\n                _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);\n                _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);\n                _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);\n            }\n        }\n        else\n        {\n            iseq2Ptr = iseq2 + (i >> 1);\n            for (j = i_len; j > 0; j--)\n            {\n                _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);\n                _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);\n                _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);\n                _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);\n            }\n\n        }\n\n        macc40 = _ReadCoProcessor(0);\n        *CrossCorrPtr = (WebRtc_Word32)(macc40 >> right_shifts);\n        CrossCorrPtr += step_seq2;\n    }\n#else // #ifdef _XSCALE_OPT_\n#ifdef _ARM_OPT_\n    WebRtc_Word16 dim_seq8 = (dim_seq >> 3) << 3;\n#endif\n\n    CrossCorrPtr = cross_correlation;\n\n    for (i = 0; i < dim_cross_correlation; i++)\n    {\n        // Set the pointer to the static vector, set the pointer to the sliding vector\n        // and initialize cross_correlation\n        seq1Ptr = seq1;\n        seq2Ptr = seq2 + (step_seq2 * i);\n        (*CrossCorrPtr) = 0;\n\n#ifndef _ARM_OPT_ \n#ifdef _WIN32\n#pragma message(\"NOTE: default implementation is used\")\n#endif\n        // Perform the cross correlation\n        for (j = 0; j < dim_seq; j++)\n        {\n            (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), right_shifts);\n            seq1Ptr++;\n            seq2Ptr++;\n        }\n#else\n#ifdef _WIN32\n#pragma message(\"NOTE: _ARM_OPT_ optimizations are used\")\n#endif\n        if (right_shifts == 0)\n        {\n            // Perform the optimized cross correlation\n            for (j = 0; j < dim_seq8; j = j + 8)\n            {\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));\n                seq1Ptr++;\n                seq2Ptr++;\n            }\n\n            for (j = dim_seq8; j < dim_seq; j++)\n            {\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));\n                seq1Ptr++;\n                seq2Ptr++;\n            }\n        }\n        else // right_shifts != 0\n\n        {\n            // Perform the optimized cross correlation\n            for (j = 0; j < dim_seq8; j = j + 8)\n            {\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),\n                                                             right_shifts);\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),\n                                                             right_shifts);\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),\n                                                             right_shifts);\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),\n                                                             right_shifts);\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),\n                                                             right_shifts);\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),\n                                                             right_shifts);\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),\n                                                             right_shifts);\n                seq1Ptr++;\n                seq2Ptr++;\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),\n                                                             right_shifts);\n                seq1Ptr++;\n                seq2Ptr++;\n            }\n\n            for (j = dim_seq8; j < dim_seq; j++)\n            {\n                (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),\n                                                             right_shifts);\n                seq1Ptr++;\n                seq2Ptr++;\n            }\n        }\n#endif\n        CrossCorrPtr++;\n    }\n#endif\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/division_operations.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains implementations of the divisions\n * WebRtcSpl_DivU32U16()\n * WebRtcSpl_DivW32W16()\n * WebRtcSpl_DivW32W16ResW16()\n * WebRtcSpl_DivResultInQ31()\n * WebRtcSpl_DivW32HiLow()\n *\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nWebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den)\n{\n    // Guard against division with 0\n    if (den != 0)\n    {\n        return (WebRtc_UWord32)(num / den);\n    } else\n    {\n        return (WebRtc_UWord32)0xFFFFFFFF;\n    }\n}\n\nWebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den)\n{\n    // Guard against division with 0\n    if (den != 0)\n    {\n        return (WebRtc_Word32)(num / den);\n    } else\n    {\n        return (WebRtc_Word32)0x7FFFFFFF;\n    }\n}\n\nWebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den)\n{\n    // Guard against division with 0\n    if (den != 0)\n    {\n        return (WebRtc_Word16)(num / den);\n    } else\n    {\n        return (WebRtc_Word16)0x7FFF;\n    }\n}\n\nWebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den)\n{\n    WebRtc_Word32 L_num = num;\n    WebRtc_Word32 L_den = den;\n    WebRtc_Word32 div = 0;\n    int k = 31;\n    int change_sign = 0;\n\n    if (num == 0)\n        return 0;\n\n    if (num < 0)\n    {\n        change_sign++;\n        L_num = -num;\n    }\n    if (den < 0)\n    {\n        change_sign++;\n        L_den = -den;\n    }\n    while (k--)\n    {\n        div <<= 1;\n        L_num <<= 1;\n        if (L_num >= L_den)\n        {\n            L_num -= L_den;\n            div++;\n        }\n    }\n    if (change_sign == 1)\n    {\n        div = -div;\n    }\n    return div;\n}\n\nWebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi,\n                                    WebRtc_Word16 den_low)\n{\n    WebRtc_Word16 approx, tmp_hi, tmp_low, num_hi, num_low;\n    WebRtc_Word32 tmpW32;\n\n    approx = (WebRtc_Word16)WebRtcSpl_DivW32W16((WebRtc_Word32)0x1FFFFFFF, den_hi);\n    // result in Q14 (Note: 3FFFFFFF = 0.5 in Q30)\n\n    // tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30)\n    tmpW32 = (WEBRTC_SPL_MUL_16_16(den_hi, approx) << 1)\n            + ((WEBRTC_SPL_MUL_16_16(den_low, approx) >> 15) << 1);\n    // tmpW32 = den * approx\n\n    tmpW32 = (WebRtc_Word32)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx))\n\n    // Store tmpW32 in hi and low format\n    tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);\n    tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32\n            - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);\n\n    // tmpW32 = 1/den in Q29\n    tmpW32 = ((WEBRTC_SPL_MUL_16_16(tmp_hi, approx) + (WEBRTC_SPL_MUL_16_16(tmp_low, approx)\n            >> 15)) << 1);\n\n    // 1/den in hi and low format\n    tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);\n    tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32\n            - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);\n\n    // Store num in hi and low format\n    num_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(num, 16);\n    num_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((num\n            - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)num_hi, 16)), 1);\n\n    // num * (1/den) by 32 bit multiplication (result in Q28)\n\n    tmpW32 = (WEBRTC_SPL_MUL_16_16(num_hi, tmp_hi) + (WEBRTC_SPL_MUL_16_16(num_hi, tmp_low)\n            >> 15) + (WEBRTC_SPL_MUL_16_16(num_low, tmp_hi) >> 15));\n\n    // Put result in Q31 (convert from Q28)\n    tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);\n\n    return tmpW32;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/dot_product_with_scale.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_DotProductWithScale().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nWebRtc_Word32 WebRtcSpl_DotProductWithScale(WebRtc_Word16 *vector1, WebRtc_Word16 *vector2,\n                                            int length, int scaling)\n{\n    WebRtc_Word32 sum;\n    int i;\n#ifdef _ARM_OPT_\n#pragma message(\"NOTE: _ARM_OPT_ optimizations are used\")\n    WebRtc_Word16 len4 = (length >> 2) << 2;\n#endif\n\n    sum = 0;\n\n#ifndef _ARM_OPT_\n    for (i = 0; i < length; i++)\n    {\n        sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1++, *vector2++, scaling);\n    }\n#else\n    if (scaling == 0)\n    {\n        for (i = 0; i < len4; i = i + 4)\n        {\n            sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);\n            vector1++;\n            vector2++;\n            sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);\n            vector1++;\n            vector2++;\n            sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);\n            vector1++;\n            vector2++;\n            sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);\n            vector1++;\n            vector2++;\n        }\n\n        for (i = len4; i < length; i++)\n        {\n            sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);\n            vector1++;\n            vector2++;\n        }\n    }\n    else\n    {\n        for (i = 0; i < len4; i = i + 4)\n        {\n            sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);\n            vector1++;\n            vector2++;\n            sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);\n            vector1++;\n            vector2++;\n            sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);\n            vector1++;\n            vector2++;\n            sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);\n            vector1++;\n            vector2++;\n        }\n\n        for (i = len4; i < length; i++)\n        {\n            sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);\n            vector1++;\n            vector2++;\n        }\n    }\n#endif\n\n    return sum;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/downsample_fast.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_DownsampleFast().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nint WebRtcSpl_DownsampleFast(WebRtc_Word16 *in_ptr, WebRtc_Word16 in_length,\n                             WebRtc_Word16 *out_ptr, WebRtc_Word16 out_length,\n                             WebRtc_Word16 *B, WebRtc_Word16 B_length, WebRtc_Word16 factor,\n                             WebRtc_Word16 delay)\n{\n    WebRtc_Word32 o;\n    int i, j;\n\n    WebRtc_Word16 *downsampled_ptr = out_ptr;\n    WebRtc_Word16 *b_ptr;\n    WebRtc_Word16 *x_ptr;\n    WebRtc_Word16 endpos = delay\n            + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(factor, (out_length - 1)) + 1;\n\n    if (in_length < endpos)\n    {\n        return -1;\n    }\n\n    for (i = delay; i < endpos; i += factor)\n    {\n        b_ptr = &B[0];\n        x_ptr = &in_ptr[i];\n\n        o = (WebRtc_Word32)2048; // Round val\n\n        for (j = 0; j < B_length; j++)\n        {\n            o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);\n        }\n\n        o = WEBRTC_SPL_RSHIFT_W32(o, 12);\n\n        // If output is higher than 32768, saturate it. Same with negative side\n\n        *downsampled_ptr++ = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, o, -32768);\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/energy.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_Energy().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nWebRtc_Word32 WebRtcSpl_Energy(WebRtc_Word16* vector, int vector_length, int* scale_factor)\n{\n    WebRtc_Word32 en = 0;\n    int i;\n    int scaling = WebRtcSpl_GetScalingSquare(vector, vector_length, vector_length);\n    int looptimes = vector_length;\n    WebRtc_Word16 *vectorptr = vector;\n\n    for (i = 0; i < looptimes; i++)\n    {\n        en += WEBRTC_SPL_MUL_16_16_RSFT(*vectorptr, *vectorptr, scaling);\n        vectorptr++;\n    }\n    *scale_factor = scaling;\n\n    return en;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/filter_ar.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_FilterAR().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nint WebRtcSpl_FilterAR(G_CONST WebRtc_Word16* a,\n                       int a_length,\n                       G_CONST WebRtc_Word16* x,\n                       int x_length,\n                       WebRtc_Word16* state,\n                       int state_length,\n                       WebRtc_Word16* state_low,\n                       int state_low_length,\n                       WebRtc_Word16* filtered,\n                       WebRtc_Word16* filtered_low,\n                       int filtered_low_length)\n{\n    WebRtc_Word32 o;\n    WebRtc_Word32 oLOW;\n    int i, j, stop;\n    G_CONST WebRtc_Word16* x_ptr = &x[0];\n    WebRtc_Word16* filteredFINAL_ptr = filtered;\n    WebRtc_Word16* filteredFINAL_LOW_ptr = filtered_low;\n\n    for (i = 0; i < x_length; i++)\n    {\n        // Calculate filtered[i] and filtered_low[i]\n        G_CONST WebRtc_Word16* a_ptr = &a[1];\n        WebRtc_Word16* filtered_ptr = &filtered[i - 1];\n        WebRtc_Word16* filtered_low_ptr = &filtered_low[i - 1];\n        WebRtc_Word16* state_ptr = &state[state_length - 1];\n        WebRtc_Word16* state_low_ptr = &state_low[state_length - 1];\n\n        o = (WebRtc_Word32)(*x_ptr++) << 12;\n        oLOW = (WebRtc_Word32)0;\n\n        stop = (i < a_length) ? i + 1 : a_length;\n        for (j = 1; j < stop; j++)\n        {\n            o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *filtered_ptr--);\n            oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *filtered_low_ptr--);\n        }\n        for (j = i + 1; j < a_length; j++)\n        {\n            o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *state_ptr--);\n            oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *state_low_ptr--);\n        }\n\n        o += (oLOW >> 12);\n        *filteredFINAL_ptr = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12);\n        *filteredFINAL_LOW_ptr++ = (WebRtc_Word16)(o - ((WebRtc_Word32)(*filteredFINAL_ptr++)\n                << 12));\n    }\n\n    // Save the filter state\n    if (x_length >= state_length)\n    {\n        WebRtcSpl_CopyFromEndW16(filtered, x_length, a_length - 1, state);\n        WebRtcSpl_CopyFromEndW16(filtered_low, x_length, a_length - 1, state_low);\n    } else\n    {\n        for (i = 0; i < state_length - x_length; i++)\n        {\n            state[i] = state[i + x_length];\n            state_low[i] = state_low[i + x_length];\n        }\n        for (i = 0; i < x_length; i++)\n        {\n            state[state_length - x_length + i] = filtered[i];\n            state[state_length - x_length + i] = filtered_low[i];\n        }\n    }\n\n    return x_length;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/filter_ar_fast_q12.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_FilterARFastQ12().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nvoid WebRtcSpl_FilterARFastQ12(WebRtc_Word16 *in, WebRtc_Word16 *out, WebRtc_Word16 *A,\n                               WebRtc_Word16 A_length, WebRtc_Word16 length)\n{\n    WebRtc_Word32 o;\n    int i, j;\n\n    WebRtc_Word16 *x_ptr = &in[0];\n    WebRtc_Word16 *filtered_ptr = &out[0];\n\n    for (i = 0; i < length; i++)\n    {\n        // Calculate filtered[i]\n        G_CONST WebRtc_Word16 *a_ptr = &A[0];\n        WebRtc_Word16 *state_ptr = &out[i - 1];\n\n        o = WEBRTC_SPL_MUL_16_16(*x_ptr++, *a_ptr++);\n\n        for (j = 1; j < A_length; j++)\n        {\n            o -= WEBRTC_SPL_MUL_16_16(*a_ptr++,*state_ptr--);\n        }\n\n        // Saturate the output\n        o = WEBRTC_SPL_SAT((WebRtc_Word32)134215679, o, (WebRtc_Word32)-134217728);\n\n        *filtered_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12);\n    }\n\n    return;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/filter_ma_fast_q12.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_FilterMAFastQ12().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nvoid WebRtcSpl_FilterMAFastQ12(WebRtc_Word16* in_ptr,\n                               WebRtc_Word16* out_ptr,\n                               WebRtc_Word16* B,\n                               WebRtc_Word16 B_length,\n                               WebRtc_Word16 length)\n{\n    WebRtc_Word32 o;\n    int i, j;\n    for (i = 0; i < length; i++)\n    {\n        G_CONST WebRtc_Word16* b_ptr = &B[0];\n        G_CONST WebRtc_Word16* x_ptr = &in_ptr[i];\n\n        o = (WebRtc_Word32)0;\n\n        for (j = 0; j < B_length; j++)\n        {\n            o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);\n        }\n\n        // If output is higher than 32768, saturate it. Same with negative side\n        // 2^27 = 134217728, which corresponds to 32768 in Q12\n\n        // Saturate the output\n        o = WEBRTC_SPL_SAT((WebRtc_Word32)134215679, o, (WebRtc_Word32)-134217728);\n\n        *out_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12);\n    }\n    return;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/get_hanning_window.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_GetHanningWindow().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nvoid WebRtcSpl_GetHanningWindow(WebRtc_Word16 *v, WebRtc_Word16 size)\n{\n    int jj;\n    WebRtc_Word16 *vptr1;\n\n    WebRtc_Word32 index;\n    WebRtc_Word32 factor = ((WebRtc_Word32)0x40000000);\n\n    factor = WebRtcSpl_DivW32W16(factor, size);\n    if (size < 513)\n        index = (WebRtc_Word32)-0x200000;\n    else\n        index = (WebRtc_Word32)-0x100000;\n    vptr1 = v;\n\n    for (jj = 0; jj < size; jj++)\n    {\n        index += factor;\n        (*vptr1++) = WebRtcSpl_kHanningTable[index >> 22];\n    }\n\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/get_scaling_square.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_GetScalingSquare().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nint WebRtcSpl_GetScalingSquare(WebRtc_Word16 *in_vector, int in_vector_length, int times)\n{\n    int nbits = WebRtcSpl_GetSizeInBits(times);\n    int i;\n    WebRtc_Word16 smax = -1;\n    WebRtc_Word16 sabs;\n    WebRtc_Word16 *sptr = in_vector;\n    int t;\n    int looptimes = in_vector_length;\n\n    for (i = looptimes; i > 0; i--)\n    {\n        sabs = (*sptr > 0 ? *sptr++ : -*sptr++);\n        smax = (sabs > smax ? sabs : smax);\n    }\n    t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax));\n\n    if (smax == 0)\n    {\n        return 0; // Since norm(0) returns 0\n    } else\n    {\n        return (t > nbits) ? 0 : nbits - t;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/hanning_table.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the Hanning table with 256 entries.\n *\n */\n\n#include \"signal_processing_library.h\"\n\n// Hanning table with 256 entries\nWebRtc_Word16 WebRtcSpl_kHanningTable[] = {\n    1,      2,      6,     10,     15,     22,     30,     39,\n   50,     62,     75,     89,    104,    121,    138,    157,\n  178,    199,    222,    246,    271,    297,    324,    353,\n  383,    413,    446,    479,    513,    549,    586,    624,\n  663,    703,    744,    787,    830,    875,    920,    967,\n 1015,   1064,   1114,   1165,   1218,   1271,   1325,   1381,\n 1437,   1494,   1553,   1612,   1673,   1734,   1796,   1859,\n 1924,   1989,   2055,   2122,   2190,   2259,   2329,   2399,\n 2471,   2543,   2617,   2691,   2765,   2841,   2918,   2995,\n 3073,   3152,   3232,   3312,   3393,   3475,   3558,   3641,\n 3725,   3809,   3895,   3980,   4067,   4154,   4242,   4330,\n 4419,   4509,   4599,   4689,   4781,   4872,   4964,   5057,\n 5150,   5244,   5338,   5432,   5527,   5622,   5718,   5814,\n 5910,   6007,   6104,   6202,   6299,   6397,   6495,   6594,\n 6693,   6791,   6891,   6990,   7090,   7189,   7289,   7389,\n 7489,   7589,   7690,   7790,   7890,   7991,   8091,   8192,\n 8293,   8393,   8494,   8594,   8694,   8795,   8895,   8995,\n 9095,   9195,   9294,   9394,   9493,   9593,   9691,   9790,\n 9889,   9987,  10085,  10182,  10280,  10377,  10474,  10570,\n10666,  10762,  10857,  10952,  11046,  11140,  11234,  11327,\n11420,  11512,  11603,  11695,  11785,  11875,  11965,  12054,\n12142,  12230,  12317,  12404,  12489,  12575,  12659,  12743,\n12826,  12909,  12991,  13072,  13152,  13232,  13311,  13389,\n13466,  13543,  13619,  13693,  13767,  13841,  13913,  13985,\n14055,  14125,  14194,  14262,  14329,  14395,  14460,  14525,\n14588,  14650,  14711,  14772,  14831,  14890,  14947,  15003,\n15059,  15113,  15166,  15219,  15270,  15320,  15369,  15417,\n15464,  15509,  15554,  15597,  15640,  15681,  15721,  15760,\n15798,  15835,  15871,  15905,  15938,  15971,  16001,  16031,\n16060,  16087,  16113,  16138,  16162,  16185,  16206,  16227,\n16246,  16263,  16280,  16295,  16309,  16322,  16334,  16345,\n16354,  16362,  16369,  16374,  16378,  16382,  16383,  16384\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/ilbc_specific_functions.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains implementations of the iLBC specific functions\n * WebRtcSpl_ScaleAndAddVectorsWithRound()\n * WebRtcSpl_ReverseOrderMultArrayElements()\n * WebRtcSpl_ElementwiseVectorMult()\n * WebRtcSpl_AddVectorsAndShift()\n * WebRtcSpl_AddAffineVectorToVector()\n * WebRtcSpl_AffineTransformVector()\n *\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nvoid WebRtcSpl_ScaleAndAddVectorsWithRound(WebRtc_Word16 *vector1, WebRtc_Word16 scale1,\n                                           WebRtc_Word16 *vector2, WebRtc_Word16 scale2,\n                                           WebRtc_Word16 right_shifts, WebRtc_Word16 *out,\n                                           WebRtc_Word16 vector_length)\n{\n    int i;\n    WebRtc_Word16 roundVal;\n    roundVal = 1 << right_shifts;\n    roundVal = roundVal >> 1;\n    for (i = 0; i < vector_length; i++)\n    {\n        out[i] = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16(vector1[i], scale1)\n                + WEBRTC_SPL_MUL_16_16(vector2[i], scale2) + roundVal) >> right_shifts);\n    }\n}\n\nvoid WebRtcSpl_ReverseOrderMultArrayElements(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in,\n                                             G_CONST WebRtc_Word16 *win,\n                                             WebRtc_Word16 vector_length,\n                                             WebRtc_Word16 right_shifts)\n{\n    int i;\n    WebRtc_Word16 *outptr = out;\n    G_CONST WebRtc_Word16 *inptr = in;\n    G_CONST WebRtc_Word16 *winptr = win;\n    for (i = 0; i < vector_length; i++)\n    {\n        (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++,\n                                                               *winptr--, right_shifts);\n    }\n}\n\nvoid WebRtcSpl_ElementwiseVectorMult(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in,\n                                     G_CONST WebRtc_Word16 *win, WebRtc_Word16 vector_length,\n                                     WebRtc_Word16 right_shifts)\n{\n    int i;\n    WebRtc_Word16 *outptr = out;\n    G_CONST WebRtc_Word16 *inptr = in;\n    G_CONST WebRtc_Word16 *winptr = win;\n    for (i = 0; i < vector_length; i++)\n    {\n        (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++,\n                                                               *winptr++, right_shifts);\n    }\n}\n\nvoid WebRtcSpl_AddVectorsAndShift(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in1,\n                                  G_CONST WebRtc_Word16 *in2, WebRtc_Word16 vector_length,\n                                  WebRtc_Word16 right_shifts)\n{\n    int i;\n    WebRtc_Word16 *outptr = out;\n    G_CONST WebRtc_Word16 *in1ptr = in1;\n    G_CONST WebRtc_Word16 *in2ptr = in2;\n    for (i = vector_length; i > 0; i--)\n    {\n        (*outptr++) = (WebRtc_Word16)(((*in1ptr++) + (*in2ptr++)) >> right_shifts);\n    }\n}\n\nvoid WebRtcSpl_AddAffineVectorToVector(WebRtc_Word16 *out, WebRtc_Word16 *in,\n                                       WebRtc_Word16 gain, WebRtc_Word32 add_constant,\n                                       WebRtc_Word16 right_shifts, int vector_length)\n{\n    WebRtc_Word16 *inPtr;\n    WebRtc_Word16 *outPtr;\n    int i;\n\n    inPtr = in;\n    outPtr = out;\n    for (i = 0; i < vector_length; i++)\n    {\n        (*outPtr++) += (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain)\n                + (WebRtc_Word32)add_constant) >> right_shifts);\n    }\n}\n\nvoid WebRtcSpl_AffineTransformVector(WebRtc_Word16 *out, WebRtc_Word16 *in,\n                                     WebRtc_Word16 gain, WebRtc_Word32 add_constant,\n                                     WebRtc_Word16 right_shifts, int vector_length)\n{\n    WebRtc_Word16 *inPtr;\n    WebRtc_Word16 *outPtr;\n    int i;\n\n    inPtr = in;\n    outPtr = out;\n    for (i = 0; i < vector_length; i++)\n    {\n        (*outPtr++) = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain)\n                + (WebRtc_Word32)add_constant) >> right_shifts);\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/levinson_durbin.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_LevinsonDurbin().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\n#define SPL_LEVINSON_MAXORDER 20\n\nWebRtc_Word16 WebRtcSpl_LevinsonDurbin(WebRtc_Word32 *R, WebRtc_Word16 *A, WebRtc_Word16 *K,\n                                       WebRtc_Word16 order)\n{\n    WebRtc_Word16 i, j;\n    // Auto-correlation coefficients in high precision\n    WebRtc_Word16 R_hi[SPL_LEVINSON_MAXORDER + 1], R_low[SPL_LEVINSON_MAXORDER + 1];\n    // LPC coefficients in high precision\n    WebRtc_Word16 A_hi[SPL_LEVINSON_MAXORDER + 1], A_low[SPL_LEVINSON_MAXORDER + 1];\n    // LPC coefficients for next iteration\n    WebRtc_Word16 A_upd_hi[SPL_LEVINSON_MAXORDER + 1], A_upd_low[SPL_LEVINSON_MAXORDER + 1];\n    // Reflection coefficient in high precision\n    WebRtc_Word16 K_hi, K_low;\n    // Prediction gain Alpha in high precision and with scale factor\n    WebRtc_Word16 Alpha_hi, Alpha_low, Alpha_exp;\n    WebRtc_Word16 tmp_hi, tmp_low;\n    WebRtc_Word32 temp1W32, temp2W32, temp3W32;\n    WebRtc_Word16 norm;\n\n    // Normalize the autocorrelation R[0]...R[order+1]\n\n    norm = WebRtcSpl_NormW32(R[0]);\n\n    for (i = order; i >= 0; i--)\n    {\n        temp1W32 = WEBRTC_SPL_LSHIFT_W32(R[i], norm);\n        // Put R in hi and low format\n        R_hi[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);\n        R_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32\n                - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16)), 1);\n    }\n\n    // K = A[1] = -R[1] / R[0]\n\n    temp2W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[1],16)\n            + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[1],1); // R[1] in Q31\n    temp3W32 = WEBRTC_SPL_ABS_W32(temp2W32); // abs R[1]\n    temp1W32 = WebRtcSpl_DivW32HiLow(temp3W32, R_hi[0], R_low[0]); // abs(R[1])/R[0] in Q31\n    // Put back the sign on R[1]\n    if (temp2W32 > 0)\n    {\n        temp1W32 = -temp1W32;\n    }\n\n    // Put K in hi and low format\n    K_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);\n    K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32\n            - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1);\n\n    // Store first reflection coefficient\n    K[0] = K_hi;\n\n    temp1W32 = WEBRTC_SPL_RSHIFT_W32(temp1W32, 4); // A[1] in Q27\n\n    // Put A[1] in hi and low format\n    A_hi[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);\n    A_low[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32\n            - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[1], 16)), 1);\n\n    // Alpha = R[0] * (1-K^2)\n\n    temp1W32 = (((WEBRTC_SPL_MUL_16_16(K_hi, K_low) >> 14) + WEBRTC_SPL_MUL_16_16(K_hi, K_hi))\n            << 1); // temp1W32 = k^2 in Q31\n\n    temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0\n    temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; // temp1W32 = (1 - K[0]*K[0]) in Q31\n\n    // Store temp1W32 = 1 - K[0]*K[0] on hi and low format\n    tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);\n    tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32\n            - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);\n\n    // Calculate Alpha in Q31\n    temp1W32 = ((WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_hi)\n            + (WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_low) >> 15)\n            + (WEBRTC_SPL_MUL_16_16(R_low[0], tmp_hi) >> 15)) << 1);\n\n    // Normalize Alpha and put it in hi and low format\n\n    Alpha_exp = WebRtcSpl_NormW32(temp1W32);\n    temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp);\n    Alpha_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);\n    Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32\n            - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1);\n\n    // Perform the iterative calculations in the Levinson-Durbin algorithm\n\n    for (i = 2; i <= order; i++)\n    {\n        /*                    ----\n         temp1W32 =  R[i] + > R[j]*A[i-j]\n         /\n         ----\n         j=1..i-1\n         */\n\n        temp1W32 = 0;\n\n        for (j = 1; j < i; j++)\n        {\n            // temp1W32 is in Q31\n            temp1W32 += ((WEBRTC_SPL_MUL_16_16(R_hi[j], A_hi[i-j]) << 1)\n                    + (((WEBRTC_SPL_MUL_16_16(R_hi[j], A_low[i-j]) >> 15)\n                            + (WEBRTC_SPL_MUL_16_16(R_low[j], A_hi[i-j]) >> 15)) << 1));\n        }\n\n        temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, 4);\n        temp1W32 += (WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16)\n                + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[i], 1));\n\n        // K = -temp1W32 / Alpha\n        temp2W32 = WEBRTC_SPL_ABS_W32(temp1W32); // abs(temp1W32)\n        temp3W32 = WebRtcSpl_DivW32HiLow(temp2W32, Alpha_hi, Alpha_low); // abs(temp1W32)/Alpha\n\n        // Put the sign of temp1W32 back again\n        if (temp1W32 > 0)\n        {\n            temp3W32 = -temp3W32;\n        }\n\n        // Use the Alpha shifts from earlier to de-normalize\n        norm = WebRtcSpl_NormW32(temp3W32);\n        if ((Alpha_exp <= norm) || (temp3W32 == 0))\n        {\n            temp3W32 = WEBRTC_SPL_LSHIFT_W32(temp3W32, Alpha_exp);\n        } else\n        {\n            if (temp3W32 > 0)\n            {\n                temp3W32 = (WebRtc_Word32)0x7fffffffL;\n            } else\n            {\n                temp3W32 = (WebRtc_Word32)0x80000000L;\n            }\n        }\n\n        // Put K on hi and low format\n        K_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16);\n        K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32\n                - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1);\n\n        // Store Reflection coefficient in Q15\n        K[i - 1] = K_hi;\n\n        // Test for unstable filter.\n        // If unstable return 0 and let the user decide what to do in that case\n\n        if ((WebRtc_Word32)WEBRTC_SPL_ABS_W16(K_hi) > (WebRtc_Word32)32750)\n        {\n            return 0; // Unstable filter\n        }\n\n        /*\n         Compute updated LPC coefficient: Anew[i]\n         Anew[j]= A[j] + K*A[i-j]   for j=1..i-1\n         Anew[i]= K\n         */\n\n        for (j = 1; j < i; j++)\n        {\n            // temp1W32 = A[j] in Q27\n            temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[j],16)\n                    + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[j],1);\n\n            // temp1W32 += K*A[i-j] in Q27\n            temp1W32 += ((WEBRTC_SPL_MUL_16_16(K_hi, A_hi[i-j])\n                    + (WEBRTC_SPL_MUL_16_16(K_hi, A_low[i-j]) >> 15)\n                    + (WEBRTC_SPL_MUL_16_16(K_low, A_hi[i-j]) >> 15)) << 1);\n\n            // Put Anew in hi and low format\n            A_upd_hi[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);\n            A_upd_low[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32\n                    - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[j], 16)), 1);\n        }\n\n        // temp3W32 = K in Q27 (Convert from Q31 to Q27)\n        temp3W32 = WEBRTC_SPL_RSHIFT_W32(temp3W32, 4);\n\n        // Store Anew in hi and low format\n        A_upd_hi[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16);\n        A_upd_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32\n                - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[i], 16)), 1);\n\n        // Alpha = Alpha * (1-K^2)\n\n        temp1W32 = (((WEBRTC_SPL_MUL_16_16(K_hi, K_low) >> 14)\n                + WEBRTC_SPL_MUL_16_16(K_hi, K_hi)) << 1); // K*K in Q31\n\n        temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0\n        temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; // 1 - K*K  in Q31\n\n        // Convert 1- K^2 in hi and low format\n        tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);\n        tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32\n                - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);\n\n        // Calculate Alpha = Alpha * (1-K^2) in Q31\n        temp1W32 = ((WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_hi)\n                + (WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_low) >> 15)\n                + (WEBRTC_SPL_MUL_16_16(Alpha_low, tmp_hi) >> 15)) << 1);\n\n        // Normalize Alpha and store it on hi and low format\n\n        norm = WebRtcSpl_NormW32(temp1W32);\n        temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm);\n\n        Alpha_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);\n        Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32\n                - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1);\n\n        // Update the total normalization of Alpha\n        Alpha_exp = Alpha_exp + norm;\n\n        // Update A[]\n\n        for (j = 1; j <= i; j++)\n        {\n            A_hi[j] = A_upd_hi[j];\n            A_low[j] = A_upd_low[j];\n        }\n    }\n\n    /*\n     Set A[0] to 1.0 and store the A[i] i=1...order in Q12\n     (Convert from Q27 and use rounding)\n     */\n\n    A[0] = 4096;\n\n    for (i = 1; i <= order; i++)\n    {\n        // temp1W32 in Q27\n        temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[i], 16)\n                + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[i], 1);\n        // Round and store upper word\n        A[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32<<1)+(WebRtc_Word32)32768, 16);\n    }\n    return 1; // Stable filters\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/lpc_to_refl_coef.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_LpcToReflCoef().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\n#define SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER 50\n\nvoid WebRtcSpl_LpcToReflCoef(WebRtc_Word16* a16, int use_order, WebRtc_Word16* k16)\n{\n    int m, k;\n    WebRtc_Word32 tmp32[SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER];\n    WebRtc_Word32 tmp_inv_denom32;\n    WebRtc_Word16 tmp_inv_denom16;\n\n    k16[use_order - 1] = WEBRTC_SPL_LSHIFT_W16(a16[use_order], 3); //Q12<<3 => Q15\n    for (m = use_order - 1; m > 0; m--)\n    {\n        // (1 - k^2) in Q30\n        tmp_inv_denom32 = ((WebRtc_Word32)1073741823) - WEBRTC_SPL_MUL_16_16(k16[m], k16[m]);\n        // (1 - k^2) in Q15\n        tmp_inv_denom16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp_inv_denom32, 15);\n\n        for (k = 1; k <= m; k++)\n        {\n            // tmp[k] = (a[k] - RC[m] * a[m-k+1]) / (1.0 - RC[m]*RC[m]);\n\n            // [Q12<<16 - (Q15*Q12)<<1] = [Q28 - Q28] = Q28\n            tmp32[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)a16[k], 16)\n                    - WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(k16[m], a16[m-k+1]), 1);\n\n            tmp32[k] = WebRtcSpl_DivW32W16(tmp32[k], tmp_inv_denom16); //Q28/Q15 = Q13\n        }\n\n        for (k = 1; k < m; k++)\n        {\n            a16[k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32[k], 1); //Q13>>1 => Q12\n        }\n\n        tmp32[m] = WEBRTC_SPL_SAT(8191, tmp32[m], -8191);\n        k16[m - 1] = (WebRtc_Word16)WEBRTC_SPL_LSHIFT_W32(tmp32[m], 2); //Q13<<2 => Q15\n    }\n    return;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/min_max_operations.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/*\n * This file contains the implementation of functions\n * WebRtcSpl_MaxAbsValueW16()\n * WebRtcSpl_MaxAbsIndexW16()\n * WebRtcSpl_MaxAbsValueW32()\n * WebRtcSpl_MaxValueW16()\n * WebRtcSpl_MaxIndexW16()\n * WebRtcSpl_MaxValueW32()\n * WebRtcSpl_MaxIndexW32()\n * WebRtcSpl_MinValueW16()\n * WebRtcSpl_MinIndexW16()\n * WebRtcSpl_MinValueW32()\n * WebRtcSpl_MinIndexW32()\n *\n * The description header can be found in signal_processing_library.h.\n *\n */\n\n#include \"signal_processing_library.h\"\n\n#if !(defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM_NEON))\n\n// Maximum absolute value of word16 vector.\nWebRtc_Word16 WebRtcSpl_MaxAbsValueW16(const WebRtc_Word16 *vector, WebRtc_Word16 length)\n{\n    WebRtc_Word32 tempMax = 0;\n    WebRtc_Word32 absVal;\n    WebRtc_Word16 totMax;\n    int i;\n    G_CONST WebRtc_Word16 *tmpvector = vector;\n\n    for (i = 0; i < length; i++)\n    {\n        absVal = WEBRTC_SPL_ABS_W32((*tmpvector));\n        if (absVal > tempMax)\n        {\n            tempMax = absVal;\n        }\n        tmpvector++;\n    }\n    totMax = (WebRtc_Word16)WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD16_MAX);\n    return totMax;\n}\n\n#endif\n\n// Index of maximum absolute value in a  word16 vector.\nWebRtc_Word16 WebRtcSpl_MaxAbsIndexW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length)\n{\n    WebRtc_Word16 tempMax;\n    WebRtc_Word16 absTemp;\n    WebRtc_Word16 tempMaxIndex = 0;\n    WebRtc_Word16 i = 0;\n    G_CONST WebRtc_Word16 *tmpvector = vector;\n\n    tempMax = WEBRTC_SPL_ABS_W16(*tmpvector);\n    tmpvector++;\n    for (i = 1; i < length; i++)\n    {\n        absTemp = WEBRTC_SPL_ABS_W16(*tmpvector);\n        tmpvector++;\n        if (absTemp > tempMax)\n        {\n            tempMax = absTemp;\n            tempMaxIndex = i;\n        }\n    }\n    return tempMaxIndex;\n}\n\n// Maximum absolute value of word32 vector.\nWebRtc_Word32 WebRtcSpl_MaxAbsValueW32(G_CONST WebRtc_Word32 *vector, WebRtc_Word16 length)\n{\n    WebRtc_UWord32 tempMax = 0;\n    WebRtc_UWord32 absVal;\n    WebRtc_Word32 retval;\n    int i;\n    G_CONST WebRtc_Word32 *tmpvector = vector;\n\n    for (i = 0; i < length; i++)\n    {\n        absVal = WEBRTC_SPL_ABS_W32((*tmpvector));\n        if (absVal > tempMax)\n        {\n            tempMax = absVal;\n        }\n        tmpvector++;\n    }\n    retval = (WebRtc_Word32)(WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD32_MAX));\n    return retval;\n}\n\n// Maximum value of word16 vector.\n#ifndef XSCALE_OPT\nWebRtc_Word16 WebRtcSpl_MaxValueW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length)\n{\n    WebRtc_Word16 tempMax;\n    WebRtc_Word16 i;\n    G_CONST WebRtc_Word16 *tmpvector = vector;\n\n    tempMax = *tmpvector++;\n    for (i = 1; i < length; i++)\n    {\n        if (*tmpvector++ > tempMax)\n            tempMax = vector[i];\n    }\n    return tempMax;\n}\n#else\n#pragma message(\">> WebRtcSpl_MaxValueW16 is excluded from this build\")\n#endif\n\n// Index of maximum value in a word16 vector.\nWebRtc_Word16 WebRtcSpl_MaxIndexW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length)\n{\n    WebRtc_Word16 tempMax;\n    WebRtc_Word16 tempMaxIndex = 0;\n    WebRtc_Word16 i = 0;\n    G_CONST WebRtc_Word16 *tmpvector = vector;\n\n    tempMax = *tmpvector++;\n    for (i = 1; i < length; i++)\n    {\n        if (*tmpvector++ > tempMax)\n        {\n            tempMax = vector[i];\n            tempMaxIndex = i;\n        }\n    }\n    return tempMaxIndex;\n}\n\n// Maximum value of word32 vector.\n#ifndef XSCALE_OPT\nWebRtc_Word32 WebRtcSpl_MaxValueW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length)\n{\n    WebRtc_Word32 tempMax;\n    WebRtc_Word16 i;\n    G_CONST WebRtc_Word32 *tmpvector = vector;\n\n    tempMax = *tmpvector++;\n    for (i = 1; i < length; i++)\n    {\n        if (*tmpvector++ > tempMax)\n            tempMax = vector[i];\n    }\n    return tempMax;\n}\n#else\n#pragma message(\">> WebRtcSpl_MaxValueW32 is excluded from this build\")\n#endif\n\n// Index of maximum value in a word32 vector.\nWebRtc_Word16 WebRtcSpl_MaxIndexW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length)\n{\n    WebRtc_Word32 tempMax;\n    WebRtc_Word16 tempMaxIndex = 0;\n    WebRtc_Word16 i = 0;\n    G_CONST WebRtc_Word32 *tmpvector = vector;\n\n    tempMax = *tmpvector++;\n    for (i = 1; i < length; i++)\n    {\n        if (*tmpvector++ > tempMax)\n        {\n            tempMax = vector[i];\n            tempMaxIndex = i;\n        }\n    }\n    return tempMaxIndex;\n}\n\n// Minimum value of word16 vector.\nWebRtc_Word16 WebRtcSpl_MinValueW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length)\n{\n    WebRtc_Word16 tempMin;\n    WebRtc_Word16 i;\n    G_CONST WebRtc_Word16 *tmpvector = vector;\n\n    // Find the minimum value\n    tempMin = *tmpvector++;\n    for (i = 1; i < length; i++)\n    {\n        if (*tmpvector++ < tempMin)\n            tempMin = (vector[i]);\n    }\n    return tempMin;\n}\n\n// Index of minimum value in a word16 vector.\n#ifndef XSCALE_OPT\nWebRtc_Word16 WebRtcSpl_MinIndexW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length)\n{\n    WebRtc_Word16 tempMin;\n    WebRtc_Word16 tempMinIndex = 0;\n    WebRtc_Word16 i = 0;\n    G_CONST WebRtc_Word16* tmpvector = vector;\n\n    // Find index of smallest value\n    tempMin = *tmpvector++;\n    for (i = 1; i < length; i++)\n    {\n        if (*tmpvector++ < tempMin)\n        {\n            tempMin = vector[i];\n            tempMinIndex = i;\n        }\n    }\n    return tempMinIndex;\n}\n#else\n#pragma message(\">> WebRtcSpl_MinIndexW16 is excluded from this build\")\n#endif\n\n// Minimum value of word32 vector.\nWebRtc_Word32 WebRtcSpl_MinValueW32(G_CONST WebRtc_Word32 *vector, WebRtc_Word16 length)\n{\n    WebRtc_Word32 tempMin;\n    WebRtc_Word16 i;\n    G_CONST WebRtc_Word32 *tmpvector = vector;\n\n    // Find the minimum value\n    tempMin = *tmpvector++;\n    for (i = 1; i < length; i++)\n    {\n        if (*tmpvector++ < tempMin)\n            tempMin = (vector[i]);\n    }\n    return tempMin;\n}\n\n// Index of minimum value in a word32 vector.\n#ifndef XSCALE_OPT\nWebRtc_Word16 WebRtcSpl_MinIndexW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length)\n{\n    WebRtc_Word32 tempMin;\n    WebRtc_Word16 tempMinIndex = 0;\n    WebRtc_Word16 i = 0;\n    G_CONST WebRtc_Word32 *tmpvector = vector;\n\n    // Find index of smallest value\n    tempMin = *tmpvector++;\n    for (i = 1; i < length; i++)\n    {\n        if (*tmpvector++ < tempMin)\n        {\n            tempMin = vector[i];\n            tempMinIndex = i;\n        }\n    }\n    return tempMinIndex;\n}\n#else\n#pragma message(\">> WebRtcSpl_MinIndexW32 is excluded from this build\")\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/min_max_operations_neon.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#if (defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM_NEON))\n\n#include <arm_neon.h>\n\n#include \"signal_processing_library.h\"\n\n// Maximum absolute value of word16 vector.\nWebRtc_Word16 WebRtcSpl_MaxAbsValueW16(const WebRtc_Word16* vector,\n                                       WebRtc_Word16 length) {\n  WebRtc_Word32 temp_max = 0;\n  WebRtc_Word32 abs_val;\n  WebRtc_Word16 tot_max;\n  int i;\n\n  __asm__(\"vmov.i16 d25, #0\" : : : \"d25\");\n\n  for (i = 0; i < length - 7; i += 8) {\n    __asm__(\"vld1.16 {d26, d27}, [%0]\" : : \"r\"(&vector[i]) : \"q13\");\n    __asm__(\"vabs.s16 q13, q13\" : : : \"q13\");\n    __asm__(\"vpmax.s16 d26, d27\" : : : \"q13\");\n    __asm__(\"vpmax.s16 d25, d26\" : : : \"d25\", \"d26\");\n  }\n  __asm__(\"vpmax.s16 d25, d25\" : : : \"d25\");\n  __asm__(\"vpmax.s16 d25, d25\" : : : \"d25\");\n  __asm__(\"vmov.s16 %0, d25[0]\" : \"=r\"(temp_max): : \"d25\");\n\n  for (; i < length; i++) {\n    abs_val = WEBRTC_SPL_ABS_W32((vector[i]));\n    if (abs_val > temp_max) {\n      temp_max = abs_val;\n    }\n  }\n  tot_max = (WebRtc_Word16)WEBRTC_SPL_MIN(temp_max, WEBRTC_SPL_WORD16_MAX);\n  return tot_max;\n}\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/randn_table.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * Table with 512 samples from a normal distribution with mean 1 and std 1\n * The values are shifted up 13 steps (multiplied by 8192)\n */\n\n#include \"signal_processing_library.h\"\n\nWebRtc_Word16 WebRtcSpl_kRandNTable[] =\n{\n    9178,    -7260,       40,    10189,     4894,    -3531,   -13779,    14764,\n   -4008,    -8884,    -8990,     1008,     7368,     5184,     3251,    -5817,\n   -9786,     5963,     1770,     8066,    -7135,    10772,    -2298,     1361,\n    6484,     2241,    -8633,      792,      199,    -3344,     6553,   -10079,\n  -15040,       95,    11608,   -12469,    14161,    -4176,     2476,     6403,\n   13685,   -16005,     6646,     2239,    10916,    -3004,     -602,    -3141,\n    2142,    14144,    -5829,     5305,     8209,     4713,     2697,    -5112,\n   16092,    -1210,    -2891,    -6631,    -5360,   -11878,    -6781,    -2739,\n   -6392,      536,    10923,    10872,     5059,    -4748,    -7770,     5477,\n      38,    -1025,    -2892,     1638,     6304,    14375,   -11028,     1553,\n   -1565,    10762,     -393,     4040,     5257,    12310,     6554,    -4799,\n    4899,    -6354,     1603,    -1048,    -2220,     8247,     -186,    -8944,\n  -12004,     2332,     4801,    -4933,     6371,      131,     8614,    -5927,\n   -8287,   -22760,     4033,   -15162,     3385,     3246,     3153,    -5250,\n    3766,      784,     6494,      -62,     3531,    -1582,    15572,      662,\n   -3952,     -330,    -3196,      669,     7236,    -2678,    -6569,    23319,\n   -8645,     -741,    14830,   -15976,     4903,      315,   -11342,    10311,\n    1858,    -7777,     2145,     5436,     5677,     -113,   -10033,      826,\n   -1353,    17210,     7768,      986,    -1471,     8291,    -4982,     8207,\n  -14911,    -6255,    -2449,   -11881,    -7059,   -11703,    -4338,     8025,\n    7538,    -2823,   -12490,     9470,    -1613,    -2529,   -10092,    -7807,\n    9480,     6970,   -12844,     5123,     3532,     4816,     4803,    -8455,\n   -5045,    14032,    -4378,    -1643,     5756,   -11041,    -2732,   -16618,\n   -6430,   -18375,    -3320,     6098,     5131,    -4269,    -8840,     2482,\n   -7048,     1547,   -21890,    -6505,    -7414,     -424,   -11722,     7955,\n    1653,   -17299,     1823,      473,    -9232,     3337,     1111,      873,\n    4018,    -8982,     9889,     3531,   -11763,    -3799,     7373,    -4539,\n    3231,     7054,    -8537,     7616,     6244,    16635,      447,    -2915,\n   13967,      705,    -2669,    -1520,    -1771,   -16188,     5956,     5117,\n    6371,    -9936,    -1448,     2480,     5128,     7550,    -8130,     5236,\n    8213,    -6443,     7707,    -1950,   -13811,     7218,     7031,    -3883,\n      67,     5731,    -2874,    13480,    -3743,     9298,    -3280,     3552,\n   -4425,      -18,    -3785,    -9988,    -5357,     5477,   -11794,     2117,\n    1416,    -9935,     3376,      802,    -5079,    -8243,    12652,       66,\n    3653,    -2368,     6781,   -21895,    -7227,     2487,     7839,     -385,\n    6646,    -7016,    -4658,     5531,    -1705,      834,      129,     3694,\n   -1343,     2238,   -22640,    -6417,   -11139,    11301,    -2945,    -3494,\n   -5626,      185,    -3615,    -2041,    -7972,    -3106,      -60,   -23497,\n   -1566,    17064,     3519,     2518,      304,    -6805,   -10269,     2105,\n    1936,     -426,     -736,    -8122,    -1467,     4238,    -6939,   -13309,\n     360,     7402,    -7970,    12576,     3287,    12194,    -6289,   -16006,\n    9171,     4042,    -9193,     9123,    -2512,     6388,    -4734,    -8739,\n    1028,    -5406,    -1696,     5889,     -666,    -4736,     4971,     3565,\n    9362,    -6292,     3876,    -3652,   -19666,     7523,    -4061,      391,\n  -11773,     7502,    -3763,     4929,    -9478,    13278,     2805,     4496,\n    7814,    16419,    12455,   -14773,     2127,    -2746,     3763,     4847,\n    3698,     6978,     4751,    -6957,    -3581,      -45,     6252,     1513,\n   -4797,    -7925,    11270,    16188,    -2359,    -5269,     9376,   -10777,\n    7262,    20031,    -6515,    -2208,    -5353,     8085,    -1341,    -1303,\n    7333,     5576,     3625,     5763,    -7931,     9833,    -3371,   -10305,\n    6534,   -13539,    -9971,      997,     8464,    -4064,    -1495,     1857,\n   13624,     5458,     9490,   -11086,    -4524,    12022,     -550,     -198,\n     408,    -8455,    -7068,    10289,     9712,    -3366,     9028,    -7621,\n   -5243,     2362,     6909,     4672,    -4933,    -1799,     4709,    -4563,\n     -62,     -566,     1624,    -7010,    14730,   -17791,    -3697,    -2344,\n   -1741,     7099,    -9509,    -6855,    -1989,     3495,    -2289,     2031,\n   12784,      891,    14189,    -3963,    -5683,      421,   -12575,     1724,\n  -12682,    -5970,    -8169,     3143,    -1824,    -5488,    -5130,     8536,\n   12799,      794,     5738,     3459,   -11689,     -258,    -3738,    -3775,\n   -8742,     2333,     8312,    -9383,    10331,    13119,     8398,    10644,\n  -19433,    -6446,   -16277,   -11793,    16284,     9345,    15222,    15834,\n    2009,    -7349,      130,   -14547,      338,    -5998,     3337,    21492,\n    2406,     7703,     -951,    11196,     -564,     3406,     2217,     4806,\n    2374,    -5797,    11839,     8940,   -11874,    18213,     2855,    10492\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/randomization_functions.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains implementations of the randomization functions\n * WebRtcSpl_IncreaseSeed()\n * WebRtcSpl_RandU()\n * WebRtcSpl_RandN()\n * WebRtcSpl_RandUArray()\n *\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nWebRtc_UWord32 WebRtcSpl_IncreaseSeed(WebRtc_UWord32 *seed)\n{\n    seed[0] = (seed[0] * ((WebRtc_Word32)69069) + 1) & (WEBRTC_SPL_MAX_SEED_USED - 1);\n    return seed[0];\n}\n\nWebRtc_Word16 WebRtcSpl_RandU(WebRtc_UWord32 *seed)\n{\n    return (WebRtc_Word16)(WebRtcSpl_IncreaseSeed(seed) >> 16);\n}\n\nWebRtc_Word16 WebRtcSpl_RandN(WebRtc_UWord32 *seed)\n{\n    return WebRtcSpl_kRandNTable[WebRtcSpl_IncreaseSeed(seed) >> 23];\n}\n\n// Creates an array of uniformly distributed variables\nWebRtc_Word16 WebRtcSpl_RandUArray(WebRtc_Word16* vector,\n                                   WebRtc_Word16 vector_length,\n                                   WebRtc_UWord32* seed)\n{\n    int i;\n    for (i = 0; i < vector_length; i++)\n    {\n        vector[i] = WebRtcSpl_RandU(seed);\n    }\n    return vector_length;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/refl_coef_to_lpc.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_ReflCoefToLpc().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nvoid WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16 *k, int use_order, WebRtc_Word16 *a)\n{\n    WebRtc_Word16 any[WEBRTC_SPL_MAX_LPC_ORDER + 1];\n    WebRtc_Word16 *aptr, *aptr2, *anyptr;\n    G_CONST WebRtc_Word16 *kptr;\n    int m, i;\n\n    kptr = k;\n    *a = 4096; // i.e., (Word16_MAX >> 3)+1.\n    *any = *a;\n    a[1] = WEBRTC_SPL_RSHIFT_W16((*k), 3);\n\n    for (m = 1; m < use_order; m++)\n    {\n        kptr++;\n        aptr = a;\n        aptr++;\n        aptr2 = &a[m];\n        anyptr = any;\n        anyptr++;\n\n        any[m + 1] = WEBRTC_SPL_RSHIFT_W16((*kptr), 3);\n        for (i = 0; i < m; i++)\n        {\n            *anyptr = (*aptr)\n                    + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((*aptr2), (*kptr), 15);\n            anyptr++;\n            aptr++;\n            aptr2--;\n        }\n\n        aptr = a;\n        anyptr = any;\n        for (i = 0; i < (m + 2); i++)\n        {\n            *aptr = *anyptr;\n            aptr++;\n            anyptr++;\n        }\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/resample.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the resampling functions for 22 kHz.\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n#include \"resample_by_2_internal.h\"\n\n// Declaration of internally used functions\nstatic void WebRtcSpl_32khzTo22khzIntToShort(const WebRtc_Word32 *In, WebRtc_Word16 *Out,\n                                             const WebRtc_Word32 K);\n\nvoid WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32 *In, WebRtc_Word32 *Out,\n                                    const WebRtc_Word32 K);\n\n// interpolation coefficients\nstatic const WebRtc_Word16 kCoefficients32To22[5][9] = {\n        {127, -712,  2359, -6333, 23456, 16775, -3695,  945, -154},\n        {-39,  230,  -830,  2785, 32366, -2324,   760, -218,   38},\n        {117, -663,  2222, -6133, 26634, 13070, -3174,  831, -137},\n        {-77,  457, -1677,  5958, 31175, -4136,  1405, -408,   71},\n        { 98, -560,  1900, -5406, 29240,  9423, -2480,  663, -110}\n};\n\n//////////////////////\n// 22 kHz -> 16 kHz //\n//////////////////////\n\n// number of subblocks; options: 1, 2, 4, 5, 10\n#define SUB_BLOCKS_22_16    5\n\n// 22 -> 16 resampler\nvoid WebRtcSpl_Resample22khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                    WebRtcSpl_State22khzTo16khz* state, WebRtc_Word32* tmpmem)\n{\n    int k;\n\n    // process two blocks of 10/SUB_BLOCKS_22_16 ms (to reduce temp buffer size)\n    for (k = 0; k < SUB_BLOCKS_22_16; k++)\n    {\n        ///// 22 --> 44 /////\n        // WebRtc_Word16  in[220/SUB_BLOCKS_22_16]\n        // WebRtc_Word32 out[440/SUB_BLOCKS_22_16]\n        /////\n        WebRtcSpl_UpBy2ShortToInt(in, 220 / SUB_BLOCKS_22_16, tmpmem + 16, state->S_22_44);\n\n        ///// 44 --> 32 /////\n        // WebRtc_Word32  in[440/SUB_BLOCKS_22_16]\n        // WebRtc_Word32 out[320/SUB_BLOCKS_22_16]\n        /////\n        // copy state to and from input array\n        tmpmem[8] = state->S_44_32[0];\n        tmpmem[9] = state->S_44_32[1];\n        tmpmem[10] = state->S_44_32[2];\n        tmpmem[11] = state->S_44_32[3];\n        tmpmem[12] = state->S_44_32[4];\n        tmpmem[13] = state->S_44_32[5];\n        tmpmem[14] = state->S_44_32[6];\n        tmpmem[15] = state->S_44_32[7];\n        state->S_44_32[0] = tmpmem[440 / SUB_BLOCKS_22_16 + 8];\n        state->S_44_32[1] = tmpmem[440 / SUB_BLOCKS_22_16 + 9];\n        state->S_44_32[2] = tmpmem[440 / SUB_BLOCKS_22_16 + 10];\n        state->S_44_32[3] = tmpmem[440 / SUB_BLOCKS_22_16 + 11];\n        state->S_44_32[4] = tmpmem[440 / SUB_BLOCKS_22_16 + 12];\n        state->S_44_32[5] = tmpmem[440 / SUB_BLOCKS_22_16 + 13];\n        state->S_44_32[6] = tmpmem[440 / SUB_BLOCKS_22_16 + 14];\n        state->S_44_32[7] = tmpmem[440 / SUB_BLOCKS_22_16 + 15];\n\n        WebRtcSpl_Resample44khzTo32khz(tmpmem + 8, tmpmem, 40 / SUB_BLOCKS_22_16);\n\n        ///// 32 --> 16 /////\n        // WebRtc_Word32  in[320/SUB_BLOCKS_22_16]\n        // WebRtc_Word32 out[160/SUB_BLOCKS_22_16]\n        /////\n        WebRtcSpl_DownBy2IntToShort(tmpmem, 320 / SUB_BLOCKS_22_16, out, state->S_32_16);\n\n        // move input/output pointers 10/SUB_BLOCKS_22_16 ms seconds ahead\n        in += 220 / SUB_BLOCKS_22_16;\n        out += 160 / SUB_BLOCKS_22_16;\n    }\n}\n\n// initialize state of 22 -> 16 resampler\nvoid WebRtcSpl_ResetResample22khzTo16khz(WebRtcSpl_State22khzTo16khz* state)\n{\n    int k;\n    for (k = 0; k < 8; k++)\n    {\n        state->S_22_44[k] = 0;\n        state->S_44_32[k] = 0;\n        state->S_32_16[k] = 0;\n    }\n}\n\n//////////////////////\n// 16 kHz -> 22 kHz //\n//////////////////////\n\n// number of subblocks; options: 1, 2, 4, 5, 10\n#define SUB_BLOCKS_16_22    4\n\n// 16 -> 22 resampler\nvoid WebRtcSpl_Resample16khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                    WebRtcSpl_State16khzTo22khz* state, WebRtc_Word32* tmpmem)\n{\n    int k;\n\n    // process two blocks of 10/SUB_BLOCKS_16_22 ms (to reduce temp buffer size)\n    for (k = 0; k < SUB_BLOCKS_16_22; k++)\n    {\n        ///// 16 --> 32 /////\n        // WebRtc_Word16  in[160/SUB_BLOCKS_16_22]\n        // WebRtc_Word32 out[320/SUB_BLOCKS_16_22]\n        /////\n        WebRtcSpl_UpBy2ShortToInt(in, 160 / SUB_BLOCKS_16_22, tmpmem + 8, state->S_16_32);\n\n        ///// 32 --> 22 /////\n        // WebRtc_Word32  in[320/SUB_BLOCKS_16_22]\n        // WebRtc_Word32 out[220/SUB_BLOCKS_16_22]\n        /////\n        // copy state to and from input array\n        tmpmem[0] = state->S_32_22[0];\n        tmpmem[1] = state->S_32_22[1];\n        tmpmem[2] = state->S_32_22[2];\n        tmpmem[3] = state->S_32_22[3];\n        tmpmem[4] = state->S_32_22[4];\n        tmpmem[5] = state->S_32_22[5];\n        tmpmem[6] = state->S_32_22[6];\n        tmpmem[7] = state->S_32_22[7];\n        state->S_32_22[0] = tmpmem[320 / SUB_BLOCKS_16_22];\n        state->S_32_22[1] = tmpmem[320 / SUB_BLOCKS_16_22 + 1];\n        state->S_32_22[2] = tmpmem[320 / SUB_BLOCKS_16_22 + 2];\n        state->S_32_22[3] = tmpmem[320 / SUB_BLOCKS_16_22 + 3];\n        state->S_32_22[4] = tmpmem[320 / SUB_BLOCKS_16_22 + 4];\n        state->S_32_22[5] = tmpmem[320 / SUB_BLOCKS_16_22 + 5];\n        state->S_32_22[6] = tmpmem[320 / SUB_BLOCKS_16_22 + 6];\n        state->S_32_22[7] = tmpmem[320 / SUB_BLOCKS_16_22 + 7];\n\n        WebRtcSpl_32khzTo22khzIntToShort(tmpmem, out, 20 / SUB_BLOCKS_16_22);\n\n        // move input/output pointers 10/SUB_BLOCKS_16_22 ms seconds ahead\n        in += 160 / SUB_BLOCKS_16_22;\n        out += 220 / SUB_BLOCKS_16_22;\n    }\n}\n\n// initialize state of 16 -> 22 resampler\nvoid WebRtcSpl_ResetResample16khzTo22khz(WebRtcSpl_State16khzTo22khz* state)\n{\n    int k;\n    for (k = 0; k < 8; k++)\n    {\n        state->S_16_32[k] = 0;\n        state->S_32_22[k] = 0;\n    }\n}\n\n//////////////////////\n// 22 kHz ->  8 kHz //\n//////////////////////\n\n// number of subblocks; options: 1, 2, 5, 10\n#define SUB_BLOCKS_22_8     2\n\n// 22 -> 8 resampler\nvoid WebRtcSpl_Resample22khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                   WebRtcSpl_State22khzTo8khz* state, WebRtc_Word32* tmpmem)\n{\n    int k;\n\n    // process two blocks of 10/SUB_BLOCKS_22_8 ms (to reduce temp buffer size)\n    for (k = 0; k < SUB_BLOCKS_22_8; k++)\n    {\n        ///// 22 --> 22 lowpass /////\n        // WebRtc_Word16  in[220/SUB_BLOCKS_22_8]\n        // WebRtc_Word32 out[220/SUB_BLOCKS_22_8]\n        /////\n        WebRtcSpl_LPBy2ShortToInt(in, 220 / SUB_BLOCKS_22_8, tmpmem + 16, state->S_22_22);\n\n        ///// 22 --> 16 /////\n        // WebRtc_Word32  in[220/SUB_BLOCKS_22_8]\n        // WebRtc_Word32 out[160/SUB_BLOCKS_22_8]\n        /////\n        // copy state to and from input array\n        tmpmem[8] = state->S_22_16[0];\n        tmpmem[9] = state->S_22_16[1];\n        tmpmem[10] = state->S_22_16[2];\n        tmpmem[11] = state->S_22_16[3];\n        tmpmem[12] = state->S_22_16[4];\n        tmpmem[13] = state->S_22_16[5];\n        tmpmem[14] = state->S_22_16[6];\n        tmpmem[15] = state->S_22_16[7];\n        state->S_22_16[0] = tmpmem[220 / SUB_BLOCKS_22_8 + 8];\n        state->S_22_16[1] = tmpmem[220 / SUB_BLOCKS_22_8 + 9];\n        state->S_22_16[2] = tmpmem[220 / SUB_BLOCKS_22_8 + 10];\n        state->S_22_16[3] = tmpmem[220 / SUB_BLOCKS_22_8 + 11];\n        state->S_22_16[4] = tmpmem[220 / SUB_BLOCKS_22_8 + 12];\n        state->S_22_16[5] = tmpmem[220 / SUB_BLOCKS_22_8 + 13];\n        state->S_22_16[6] = tmpmem[220 / SUB_BLOCKS_22_8 + 14];\n        state->S_22_16[7] = tmpmem[220 / SUB_BLOCKS_22_8 + 15];\n\n        WebRtcSpl_Resample44khzTo32khz(tmpmem + 8, tmpmem, 20 / SUB_BLOCKS_22_8);\n\n        ///// 16 --> 8 /////\n        // WebRtc_Word32 in[160/SUB_BLOCKS_22_8]\n        // WebRtc_Word32 out[80/SUB_BLOCKS_22_8]\n        /////\n        WebRtcSpl_DownBy2IntToShort(tmpmem, 160 / SUB_BLOCKS_22_8, out, state->S_16_8);\n\n        // move input/output pointers 10/SUB_BLOCKS_22_8 ms seconds ahead\n        in += 220 / SUB_BLOCKS_22_8;\n        out += 80 / SUB_BLOCKS_22_8;\n    }\n}\n\n// initialize state of 22 -> 8 resampler\nvoid WebRtcSpl_ResetResample22khzTo8khz(WebRtcSpl_State22khzTo8khz* state)\n{\n    int k;\n    for (k = 0; k < 8; k++)\n    {\n        state->S_22_22[k] = 0;\n        state->S_22_22[k + 8] = 0;\n        state->S_22_16[k] = 0;\n        state->S_16_8[k] = 0;\n    }\n}\n\n//////////////////////\n//  8 kHz -> 22 kHz //\n//////////////////////\n\n// number of subblocks; options: 1, 2, 5, 10\n#define SUB_BLOCKS_8_22     2\n\n// 8 -> 22 resampler\nvoid WebRtcSpl_Resample8khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                   WebRtcSpl_State8khzTo22khz* state, WebRtc_Word32* tmpmem)\n{\n    int k;\n\n    // process two blocks of 10/SUB_BLOCKS_8_22 ms (to reduce temp buffer size)\n    for (k = 0; k < SUB_BLOCKS_8_22; k++)\n    {\n        ///// 8 --> 16 /////\n        // WebRtc_Word16  in[80/SUB_BLOCKS_8_22]\n        // WebRtc_Word32 out[160/SUB_BLOCKS_8_22]\n        /////\n        WebRtcSpl_UpBy2ShortToInt(in, 80 / SUB_BLOCKS_8_22, tmpmem + 18, state->S_8_16);\n\n        ///// 16 --> 11 /////\n        // WebRtc_Word32  in[160/SUB_BLOCKS_8_22]\n        // WebRtc_Word32 out[110/SUB_BLOCKS_8_22]\n        /////\n        // copy state to and from input array\n        tmpmem[10] = state->S_16_11[0];\n        tmpmem[11] = state->S_16_11[1];\n        tmpmem[12] = state->S_16_11[2];\n        tmpmem[13] = state->S_16_11[3];\n        tmpmem[14] = state->S_16_11[4];\n        tmpmem[15] = state->S_16_11[5];\n        tmpmem[16] = state->S_16_11[6];\n        tmpmem[17] = state->S_16_11[7];\n        state->S_16_11[0] = tmpmem[160 / SUB_BLOCKS_8_22 + 10];\n        state->S_16_11[1] = tmpmem[160 / SUB_BLOCKS_8_22 + 11];\n        state->S_16_11[2] = tmpmem[160 / SUB_BLOCKS_8_22 + 12];\n        state->S_16_11[3] = tmpmem[160 / SUB_BLOCKS_8_22 + 13];\n        state->S_16_11[4] = tmpmem[160 / SUB_BLOCKS_8_22 + 14];\n        state->S_16_11[5] = tmpmem[160 / SUB_BLOCKS_8_22 + 15];\n        state->S_16_11[6] = tmpmem[160 / SUB_BLOCKS_8_22 + 16];\n        state->S_16_11[7] = tmpmem[160 / SUB_BLOCKS_8_22 + 17];\n\n        WebRtcSpl_32khzTo22khzIntToInt(tmpmem + 10, tmpmem, 10 / SUB_BLOCKS_8_22);\n\n        ///// 11 --> 22 /////\n        // WebRtc_Word32  in[110/SUB_BLOCKS_8_22]\n        // WebRtc_Word16 out[220/SUB_BLOCKS_8_22]\n        /////\n        WebRtcSpl_UpBy2IntToShort(tmpmem, 110 / SUB_BLOCKS_8_22, out, state->S_11_22);\n\n        // move input/output pointers 10/SUB_BLOCKS_8_22 ms seconds ahead\n        in += 80 / SUB_BLOCKS_8_22;\n        out += 220 / SUB_BLOCKS_8_22;\n    }\n}\n\n// initialize state of 8 -> 22 resampler\nvoid WebRtcSpl_ResetResample8khzTo22khz(WebRtcSpl_State8khzTo22khz* state)\n{\n    int k;\n    for (k = 0; k < 8; k++)\n    {\n        state->S_8_16[k] = 0;\n        state->S_16_11[k] = 0;\n        state->S_11_22[k] = 0;\n    }\n}\n\n// compute two inner-products and store them to output array\nstatic void WebRtcSpl_DotProdIntToInt(const WebRtc_Word32* in1, const WebRtc_Word32* in2,\n                                      const WebRtc_Word16* coef_ptr, WebRtc_Word32* out1,\n                                      WebRtc_Word32* out2)\n{\n    WebRtc_Word32 tmp1 = 16384;\n    WebRtc_Word32 tmp2 = 16384;\n    WebRtc_Word16 coef;\n\n    coef = coef_ptr[0];\n    tmp1 += coef * in1[0];\n    tmp2 += coef * in2[-0];\n\n    coef = coef_ptr[1];\n    tmp1 += coef * in1[1];\n    tmp2 += coef * in2[-1];\n\n    coef = coef_ptr[2];\n    tmp1 += coef * in1[2];\n    tmp2 += coef * in2[-2];\n\n    coef = coef_ptr[3];\n    tmp1 += coef * in1[3];\n    tmp2 += coef * in2[-3];\n\n    coef = coef_ptr[4];\n    tmp1 += coef * in1[4];\n    tmp2 += coef * in2[-4];\n\n    coef = coef_ptr[5];\n    tmp1 += coef * in1[5];\n    tmp2 += coef * in2[-5];\n\n    coef = coef_ptr[6];\n    tmp1 += coef * in1[6];\n    tmp2 += coef * in2[-6];\n\n    coef = coef_ptr[7];\n    tmp1 += coef * in1[7];\n    tmp2 += coef * in2[-7];\n\n    coef = coef_ptr[8];\n    *out1 = tmp1 + coef * in1[8];\n    *out2 = tmp2 + coef * in2[-8];\n}\n\n// compute two inner-products and store them to output array\nstatic void WebRtcSpl_DotProdIntToShort(const WebRtc_Word32* in1, const WebRtc_Word32* in2,\n                                        const WebRtc_Word16* coef_ptr, WebRtc_Word16* out1,\n                                        WebRtc_Word16* out2)\n{\n    WebRtc_Word32 tmp1 = 16384;\n    WebRtc_Word32 tmp2 = 16384;\n    WebRtc_Word16 coef;\n\n    coef = coef_ptr[0];\n    tmp1 += coef * in1[0];\n    tmp2 += coef * in2[-0];\n\n    coef = coef_ptr[1];\n    tmp1 += coef * in1[1];\n    tmp2 += coef * in2[-1];\n\n    coef = coef_ptr[2];\n    tmp1 += coef * in1[2];\n    tmp2 += coef * in2[-2];\n\n    coef = coef_ptr[3];\n    tmp1 += coef * in1[3];\n    tmp2 += coef * in2[-3];\n\n    coef = coef_ptr[4];\n    tmp1 += coef * in1[4];\n    tmp2 += coef * in2[-4];\n\n    coef = coef_ptr[5];\n    tmp1 += coef * in1[5];\n    tmp2 += coef * in2[-5];\n\n    coef = coef_ptr[6];\n    tmp1 += coef * in1[6];\n    tmp2 += coef * in2[-6];\n\n    coef = coef_ptr[7];\n    tmp1 += coef * in1[7];\n    tmp2 += coef * in2[-7];\n\n    coef = coef_ptr[8];\n    tmp1 += coef * in1[8];\n    tmp2 += coef * in2[-8];\n\n    // scale down, round and saturate\n    tmp1 >>= 15;\n    if (tmp1 > (WebRtc_Word32)0x00007FFF)\n        tmp1 = 0x00007FFF;\n    if (tmp1 < (WebRtc_Word32)0xFFFF8000)\n        tmp1 = 0xFFFF8000;\n    tmp2 >>= 15;\n    if (tmp2 > (WebRtc_Word32)0x00007FFF)\n        tmp2 = 0x00007FFF;\n    if (tmp2 < (WebRtc_Word32)0xFFFF8000)\n        tmp2 = 0xFFFF8000;\n    *out1 = (WebRtc_Word16)tmp1;\n    *out2 = (WebRtc_Word16)tmp2;\n}\n\n//   Resampling ratio: 11/16\n// input:  WebRtc_Word32 (normalized, not saturated) :: size 16 * K\n// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 11 * K\n//      K: Number of blocks\n\nvoid WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32* In,\n                                    WebRtc_Word32* Out,\n                                    const WebRtc_Word32 K)\n{\n    /////////////////////////////////////////////////////////////\n    // Filter operation:\n    //\n    // Perform resampling (16 input samples -> 11 output samples);\n    // process in sub blocks of size 16 samples.\n    WebRtc_Word32 m;\n\n    for (m = 0; m < K; m++)\n    {\n        // first output sample\n        Out[0] = ((WebRtc_Word32)In[3] << 15) + (1 << 14);\n\n        // sum and accumulate filter coefficients and input samples\n        WebRtcSpl_DotProdIntToInt(&In[0], &In[22], kCoefficients32To22[0], &Out[1], &Out[10]);\n\n        // sum and accumulate filter coefficients and input samples\n        WebRtcSpl_DotProdIntToInt(&In[2], &In[20], kCoefficients32To22[1], &Out[2], &Out[9]);\n\n        // sum and accumulate filter coefficients and input samples\n        WebRtcSpl_DotProdIntToInt(&In[3], &In[19], kCoefficients32To22[2], &Out[3], &Out[8]);\n\n        // sum and accumulate filter coefficients and input samples\n        WebRtcSpl_DotProdIntToInt(&In[5], &In[17], kCoefficients32To22[3], &Out[4], &Out[7]);\n\n        // sum and accumulate filter coefficients and input samples\n        WebRtcSpl_DotProdIntToInt(&In[6], &In[16], kCoefficients32To22[4], &Out[5], &Out[6]);\n\n        // update pointers\n        In += 16;\n        Out += 11;\n    }\n}\n\n//   Resampling ratio: 11/16\n// input:  WebRtc_Word32 (normalized, not saturated) :: size 16 * K\n// output: WebRtc_Word16 (saturated) :: size 11 * K\n//      K: Number of blocks\n\nvoid WebRtcSpl_32khzTo22khzIntToShort(const WebRtc_Word32 *In,\n                                      WebRtc_Word16 *Out,\n                                      const WebRtc_Word32 K)\n{\n    /////////////////////////////////////////////////////////////\n    // Filter operation:\n    //\n    // Perform resampling (16 input samples -> 11 output samples);\n    // process in sub blocks of size 16 samples.\n    WebRtc_Word32 tmp;\n    WebRtc_Word32 m;\n\n    for (m = 0; m < K; m++)\n    {\n        // first output sample\n        tmp = In[3];\n        if (tmp > (WebRtc_Word32)0x00007FFF)\n            tmp = 0x00007FFF;\n        if (tmp < (WebRtc_Word32)0xFFFF8000)\n            tmp = 0xFFFF8000;\n        Out[0] = (WebRtc_Word16)tmp;\n\n        // sum and accumulate filter coefficients and input samples\n        WebRtcSpl_DotProdIntToShort(&In[0], &In[22], kCoefficients32To22[0], &Out[1], &Out[10]);\n\n        // sum and accumulate filter coefficients and input samples\n        WebRtcSpl_DotProdIntToShort(&In[2], &In[20], kCoefficients32To22[1], &Out[2], &Out[9]);\n\n        // sum and accumulate filter coefficients and input samples\n        WebRtcSpl_DotProdIntToShort(&In[3], &In[19], kCoefficients32To22[2], &Out[3], &Out[8]);\n\n        // sum and accumulate filter coefficients and input samples\n        WebRtcSpl_DotProdIntToShort(&In[5], &In[17], kCoefficients32To22[3], &Out[4], &Out[7]);\n\n        // sum and accumulate filter coefficients and input samples\n        WebRtcSpl_DotProdIntToShort(&In[6], &In[16], kCoefficients32To22[4], &Out[5], &Out[6]);\n\n        // update pointers\n        In += 16;\n        Out += 11;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/resample_48khz.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains resampling functions between 48 kHz and nb/wb.\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include <string.h>\n#include \"signal_processing_library.h\"\n#include \"resample_by_2_internal.h\"\n\n////////////////////////////\n///// 48 kHz -> 16 kHz /////\n////////////////////////////\n\n// 48 -> 16 resampler\nvoid WebRtcSpl_Resample48khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                    WebRtcSpl_State48khzTo16khz* state, WebRtc_Word32* tmpmem)\n{\n    ///// 48 --> 48(LP) /////\n    // WebRtc_Word16  in[480]\n    // WebRtc_Word32 out[480]\n    /////\n    WebRtcSpl_LPBy2ShortToInt(in, 480, tmpmem + 16, state->S_48_48);\n\n    ///// 48 --> 32 /////\n    // WebRtc_Word32  in[480]\n    // WebRtc_Word32 out[320]\n    /////\n    // copy state to and from input array\n    memcpy(tmpmem + 8, state->S_48_32, 8 * sizeof(WebRtc_Word32));\n    memcpy(state->S_48_32, tmpmem + 488, 8 * sizeof(WebRtc_Word32));\n    WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 160);\n\n    ///// 32 --> 16 /////\n    // WebRtc_Word32  in[320]\n    // WebRtc_Word16 out[160]\n    /////\n    WebRtcSpl_DownBy2IntToShort(tmpmem, 320, out, state->S_32_16);\n}\n\n// initialize state of 48 -> 16 resampler\nvoid WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state)\n{\n    memset(state->S_48_48, 0, 16 * sizeof(WebRtc_Word32));\n    memset(state->S_48_32, 0, 8 * sizeof(WebRtc_Word32));\n    memset(state->S_32_16, 0, 8 * sizeof(WebRtc_Word32));\n}\n\n////////////////////////////\n///// 16 kHz -> 48 kHz /////\n////////////////////////////\n\n// 16 -> 48 resampler\nvoid WebRtcSpl_Resample16khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                    WebRtcSpl_State16khzTo48khz* state, WebRtc_Word32* tmpmem)\n{\n    ///// 16 --> 32 /////\n    // WebRtc_Word16  in[160]\n    // WebRtc_Word32 out[320]\n    /////\n    WebRtcSpl_UpBy2ShortToInt(in, 160, tmpmem + 16, state->S_16_32);\n\n    ///// 32 --> 24 /////\n    // WebRtc_Word32  in[320]\n    // WebRtc_Word32 out[240]\n    // copy state to and from input array\n    /////\n    memcpy(tmpmem + 8, state->S_32_24, 8 * sizeof(WebRtc_Word32));\n    memcpy(state->S_32_24, tmpmem + 328, 8 * sizeof(WebRtc_Word32));\n    WebRtcSpl_Resample32khzTo24khz(tmpmem + 8, tmpmem, 80);\n\n    ///// 24 --> 48 /////\n    // WebRtc_Word32  in[240]\n    // WebRtc_Word16 out[480]\n    /////\n    WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48);\n}\n\n// initialize state of 16 -> 48 resampler\nvoid WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state)\n{\n    memset(state->S_16_32, 0, 8 * sizeof(WebRtc_Word32));\n    memset(state->S_32_24, 0, 8 * sizeof(WebRtc_Word32));\n    memset(state->S_24_48, 0, 8 * sizeof(WebRtc_Word32));\n}\n\n////////////////////////////\n///// 48 kHz ->  8 kHz /////\n////////////////////////////\n\n// 48 -> 8 resampler\nvoid WebRtcSpl_Resample48khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                   WebRtcSpl_State48khzTo8khz* state, WebRtc_Word32* tmpmem)\n{\n    ///// 48 --> 24 /////\n    // WebRtc_Word16  in[480]\n    // WebRtc_Word32 out[240]\n    /////\n    WebRtcSpl_DownBy2ShortToInt(in, 480, tmpmem + 256, state->S_48_24);\n\n    ///// 24 --> 24(LP) /////\n    // WebRtc_Word32  in[240]\n    // WebRtc_Word32 out[240]\n    /////\n    WebRtcSpl_LPBy2IntToInt(tmpmem + 256, 240, tmpmem + 16, state->S_24_24);\n\n    ///// 24 --> 16 /////\n    // WebRtc_Word32  in[240]\n    // WebRtc_Word32 out[160]\n    /////\n    // copy state to and from input array\n    memcpy(tmpmem + 8, state->S_24_16, 8 * sizeof(WebRtc_Word32));\n    memcpy(state->S_24_16, tmpmem + 248, 8 * sizeof(WebRtc_Word32));\n    WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 80);\n\n    ///// 16 --> 8 /////\n    // WebRtc_Word32  in[160]\n    // WebRtc_Word16 out[80]\n    /////\n    WebRtcSpl_DownBy2IntToShort(tmpmem, 160, out, state->S_16_8);\n}\n\n// initialize state of 48 -> 8 resampler\nvoid WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state)\n{\n    memset(state->S_48_24, 0, 8 * sizeof(WebRtc_Word32));\n    memset(state->S_24_24, 0, 16 * sizeof(WebRtc_Word32));\n    memset(state->S_24_16, 0, 8 * sizeof(WebRtc_Word32));\n    memset(state->S_16_8, 0, 8 * sizeof(WebRtc_Word32));\n}\n\n////////////////////////////\n/////  8 kHz -> 48 kHz /////\n////////////////////////////\n\n// 8 -> 48 resampler\nvoid WebRtcSpl_Resample8khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out,\n                                   WebRtcSpl_State8khzTo48khz* state, WebRtc_Word32* tmpmem)\n{\n    ///// 8 --> 16 /////\n    // WebRtc_Word16  in[80]\n    // WebRtc_Word32 out[160]\n    /////\n    WebRtcSpl_UpBy2ShortToInt(in, 80, tmpmem + 264, state->S_8_16);\n\n    ///// 16 --> 12 /////\n    // WebRtc_Word32  in[160]\n    // WebRtc_Word32 out[120]\n    /////\n    // copy state to and from input array\n    memcpy(tmpmem + 256, state->S_16_12, 8 * sizeof(WebRtc_Word32));\n    memcpy(state->S_16_12, tmpmem + 416, 8 * sizeof(WebRtc_Word32));\n    WebRtcSpl_Resample32khzTo24khz(tmpmem + 256, tmpmem + 240, 40);\n\n    ///// 12 --> 24 /////\n    // WebRtc_Word32  in[120]\n    // WebRtc_Word16 out[240]\n    /////\n    WebRtcSpl_UpBy2IntToInt(tmpmem + 240, 120, tmpmem, state->S_12_24);\n\n    ///// 24 --> 48 /////\n    // WebRtc_Word32  in[240]\n    // WebRtc_Word16 out[480]\n    /////\n    WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48);\n}\n\n// initialize state of 8 -> 48 resampler\nvoid WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state)\n{\n    memset(state->S_8_16, 0, 8 * sizeof(WebRtc_Word32));\n    memset(state->S_16_12, 0, 8 * sizeof(WebRtc_Word32));\n    memset(state->S_12_24, 0, 8 * sizeof(WebRtc_Word32));\n    memset(state->S_24_48, 0, 8 * sizeof(WebRtc_Word32));\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/resample_by_2.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the resampling by two functions.\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\n// allpass filter coefficients.\nstatic const WebRtc_UWord16 kResampleAllpass1[3] = {3284, 24441, 49528};\nstatic const WebRtc_UWord16 kResampleAllpass2[3] = {12199, 37471, 60255};\n\n// decimator\nvoid WebRtcSpl_DownsampleBy2(const WebRtc_Word16* in, const WebRtc_Word16 len,\n                             WebRtc_Word16* out, WebRtc_Word32* filtState)\n{\n    WebRtc_Word32 tmp1, tmp2, diff, in32, out32;\n    WebRtc_Word16 i;\n\n    register WebRtc_Word32 state0 = filtState[0];\n    register WebRtc_Word32 state1 = filtState[1];\n    register WebRtc_Word32 state2 = filtState[2];\n    register WebRtc_Word32 state3 = filtState[3];\n    register WebRtc_Word32 state4 = filtState[4];\n    register WebRtc_Word32 state5 = filtState[5];\n    register WebRtc_Word32 state6 = filtState[6];\n    register WebRtc_Word32 state7 = filtState[7];\n\n    for (i = (len >> 1); i > 0; i--)\n    {\n        // lower allpass filter\n        in32 = (WebRtc_Word32)(*in++) << 10;\n        diff = in32 - state1;\n        tmp1 = WEBRTC_SPL_SCALEDIFF32(kResampleAllpass2[0], diff, state0);\n        state0 = in32;\n        diff = tmp1 - state2;\n        tmp2 = WEBRTC_SPL_SCALEDIFF32(kResampleAllpass2[1], diff, state1);\n        state1 = tmp1;\n        diff = tmp2 - state3;\n        state3 = WEBRTC_SPL_SCALEDIFF32(kResampleAllpass2[2], diff, state2);\n        state2 = tmp2;\n\n        // upper allpass filter\n        in32 = (WebRtc_Word32)(*in++) << 10;\n        diff = in32 - state5;\n        tmp1 = WEBRTC_SPL_SCALEDIFF32(kResampleAllpass1[0], diff, state4);\n        state4 = in32;\n        diff = tmp1 - state6;\n        tmp2 = WEBRTC_SPL_SCALEDIFF32(kResampleAllpass1[1], diff, state5);\n        state5 = tmp1;\n        diff = tmp2 - state7;\n        state7 = WEBRTC_SPL_SCALEDIFF32(kResampleAllpass1[2], diff, state6);\n        state6 = tmp2;\n\n        // add two allpass outputs, divide by two and round\n        out32 = (state3 + state7 + 1024) >> 11;\n\n        // limit amplitude to prevent wrap-around, and write to output array\n#ifdef WEBRTC_ARCH_ARM_V7A\n        __asm__(\"ssat %r0, #16, %r1\" : \"=r\"(*out) : \"r\"(out32));\n        out++;\n#else\n        if (out32 > 32767)\n            *out++ = 32767;\n        else if (out32 < -32768)\n            *out++ = -32768;\n        else\n            *out++ = (WebRtc_Word16)out32;\n#endif\n    }\n\n    filtState[0] = state0;\n    filtState[1] = state1;\n    filtState[2] = state2;\n    filtState[3] = state3;\n    filtState[4] = state4;\n    filtState[5] = state5;\n    filtState[6] = state6;\n    filtState[7] = state7;\n}\n\nvoid WebRtcSpl_UpsampleBy2(const WebRtc_Word16* in, WebRtc_Word16 len, WebRtc_Word16* out,\n                           WebRtc_Word32* filtState)\n{\n    WebRtc_Word32 tmp1, tmp2, diff, in32, out32;\n    WebRtc_Word16 i;\n\n    register WebRtc_Word32 state0 = filtState[0];\n    register WebRtc_Word32 state1 = filtState[1];\n    register WebRtc_Word32 state2 = filtState[2];\n    register WebRtc_Word32 state3 = filtState[3];\n    register WebRtc_Word32 state4 = filtState[4];\n    register WebRtc_Word32 state5 = filtState[5];\n    register WebRtc_Word32 state6 = filtState[6];\n    register WebRtc_Word32 state7 = filtState[7];\n\n    for (i = len; i > 0; i--)\n    {\n        // lower allpass filter\n        in32 = (WebRtc_Word32)(*in++) << 10;\n        diff = in32 - state1;\n        tmp1 = WEBRTC_SPL_SCALEDIFF32(kResampleAllpass1[0], diff, state0);\n        state0 = in32;\n        diff = tmp1 - state2;\n        tmp2 = WEBRTC_SPL_SCALEDIFF32(kResampleAllpass1[1], diff, state1);\n        state1 = tmp1;\n        diff = tmp2 - state3;\n        state3 = WEBRTC_SPL_SCALEDIFF32(kResampleAllpass1[2], diff, state2);\n        state2 = tmp2;\n\n        // round; limit amplitude to prevent wrap-around; write to output array\n        out32 = (state3 + 512) >> 10;\n#ifdef WEBRTC_ARCH_ARM_V7A\n        __asm__(\"ssat %r0, #16, %r1\":\"=r\"(*out): \"r\"(out32));\n        out++;\n#else\n        if (out32 > 32767)\n            *out++ = 32767;\n        else if (out32 < -32768)\n            *out++ = -32768;\n        else\n            *out++ = (WebRtc_Word16)out32;\n#endif\n\n        // upper allpass filter\n        diff = in32 - state5;\n        tmp1 = WEBRTC_SPL_SCALEDIFF32(kResampleAllpass2[0], diff, state4);\n        state4 = in32;\n        diff = tmp1 - state6;\n        tmp2 = WEBRTC_SPL_SCALEDIFF32(kResampleAllpass2[1], diff, state5);\n        state5 = tmp1;\n        diff = tmp2 - state7;\n        state7 = WEBRTC_SPL_SCALEDIFF32(kResampleAllpass2[2], diff, state6);\n        state6 = tmp2;\n\n        // round; limit amplitude to prevent wrap-around; write to output array\n        out32 = (state7 + 512) >> 10;\n#ifdef WEBRTC_ARCH_ARM_V7A\n        __asm__(\"ssat %r0, #16, %r1\":\"=r\"(*out): \"r\"(out32));\n        out++;\n#else\n        if (out32 > 32767)\n            *out++ = 32767;\n        else if (out32 < -32768)\n            *out++ = -32768;\n        else\n            *out++ = (WebRtc_Word16)out32;\n#endif\n    }\n    \n    filtState[0] = state0;\n    filtState[1] = state1;\n    filtState[2] = state2;\n    filtState[3] = state3;\n    filtState[4] = state4;\n    filtState[5] = state5;\n    filtState[6] = state6;\n    filtState[7] = state7;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/resample_by_2_internal.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This header file contains some internal resampling functions.\n *\n */\n\n#include \"resample_by_2_internal.h\"\n\n// allpass filter coefficients.\nstatic const WebRtc_Word16 kResampleAllpass[2][3] = {\n        {821, 6110, 12382},\n        {3050, 9368, 15063}\n};\n\n//\n//   decimator\n// input:  WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) OVERWRITTEN!\n// output: WebRtc_Word16 (saturated) (of length len/2)\n// state:  filter state array; length = 8\n\nvoid WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out,\n                                 WebRtc_Word32 *state)\n{\n    WebRtc_Word32 tmp0, tmp1, diff;\n    WebRtc_Word32 i;\n\n    len >>= 1;\n\n    // lower allpass filter (operates on even input samples)\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = in[i << 1];\n        diff = tmp0 - state[1];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[0] + diff * kResampleAllpass[1][0];\n        state[0] = tmp0;\n        diff = tmp1 - state[2];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[1] + diff * kResampleAllpass[1][1];\n        state[1] = tmp1;\n        diff = tmp0 - state[3];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[3] = state[2] + diff * kResampleAllpass[1][2];\n        state[2] = tmp0;\n\n        // divide by two and store temporarily\n        in[i << 1] = (state[3] >> 1);\n    }\n\n    in++;\n\n    // upper allpass filter (operates on odd input samples)\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = in[i << 1];\n        diff = tmp0 - state[5];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[4] + diff * kResampleAllpass[0][0];\n        state[4] = tmp0;\n        diff = tmp1 - state[6];\n        // scale down and round\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[5] + diff * kResampleAllpass[0][1];\n        state[5] = tmp1;\n        diff = tmp0 - state[7];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[7] = state[6] + diff * kResampleAllpass[0][2];\n        state[6] = tmp0;\n\n        // divide by two and store temporarily\n        in[i << 1] = (state[7] >> 1);\n    }\n\n    in--;\n\n    // combine allpass outputs\n    for (i = 0; i < len; i += 2)\n    {\n        // divide by two, add both allpass outputs and round\n        tmp0 = (in[i << 1] + in[(i << 1) + 1]) >> 15;\n        tmp1 = (in[(i << 1) + 2] + in[(i << 1) + 3]) >> 15;\n        if (tmp0 > (WebRtc_Word32)0x00007FFF)\n            tmp0 = 0x00007FFF;\n        if (tmp0 < (WebRtc_Word32)0xFFFF8000)\n            tmp0 = 0xFFFF8000;\n        out[i] = (WebRtc_Word16)tmp0;\n        if (tmp1 > (WebRtc_Word32)0x00007FFF)\n            tmp1 = 0x00007FFF;\n        if (tmp1 < (WebRtc_Word32)0xFFFF8000)\n            tmp1 = 0xFFFF8000;\n        out[i + 1] = (WebRtc_Word16)tmp1;\n    }\n}\n\n//\n//   decimator\n// input:  WebRtc_Word16\n// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len/2)\n// state:  filter state array; length = 8\n\nvoid WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in,\n                                  WebRtc_Word32 len,\n                                  WebRtc_Word32 *out,\n                                  WebRtc_Word32 *state)\n{\n    WebRtc_Word32 tmp0, tmp1, diff;\n    WebRtc_Word32 i;\n\n    len >>= 1;\n\n    // lower allpass filter (operates on even input samples)\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);\n        diff = tmp0 - state[1];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[0] + diff * kResampleAllpass[1][0];\n        state[0] = tmp0;\n        diff = tmp1 - state[2];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[1] + diff * kResampleAllpass[1][1];\n        state[1] = tmp1;\n        diff = tmp0 - state[3];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[3] = state[2] + diff * kResampleAllpass[1][2];\n        state[2] = tmp0;\n\n        // divide by two and store temporarily\n        out[i] = (state[3] >> 1);\n    }\n\n    in++;\n\n    // upper allpass filter (operates on odd input samples)\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);\n        diff = tmp0 - state[5];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[4] + diff * kResampleAllpass[0][0];\n        state[4] = tmp0;\n        diff = tmp1 - state[6];\n        // scale down and round\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[5] + diff * kResampleAllpass[0][1];\n        state[5] = tmp1;\n        diff = tmp0 - state[7];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[7] = state[6] + diff * kResampleAllpass[0][2];\n        state[6] = tmp0;\n\n        // divide by two and store temporarily\n        out[i] += (state[7] >> 1);\n    }\n\n    in--;\n}\n\n//\n//   interpolator\n// input:  WebRtc_Word16\n// output: WebRtc_Word32 (normalized, not saturated) (of length len*2)\n// state:  filter state array; length = 8\nvoid WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, WebRtc_Word32 *out,\n                               WebRtc_Word32 *state)\n{\n    WebRtc_Word32 tmp0, tmp1, diff;\n    WebRtc_Word32 i;\n\n    // upper allpass filter (generates odd output samples)\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14);\n        diff = tmp0 - state[5];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[4] + diff * kResampleAllpass[0][0];\n        state[4] = tmp0;\n        diff = tmp1 - state[6];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[5] + diff * kResampleAllpass[0][1];\n        state[5] = tmp1;\n        diff = tmp0 - state[7];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[7] = state[6] + diff * kResampleAllpass[0][2];\n        state[6] = tmp0;\n\n        // scale down, round and store\n        out[i << 1] = state[7] >> 15;\n    }\n\n    out++;\n\n    // lower allpass filter (generates even output samples)\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14);\n        diff = tmp0 - state[1];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[0] + diff * kResampleAllpass[1][0];\n        state[0] = tmp0;\n        diff = tmp1 - state[2];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[1] + diff * kResampleAllpass[1][1];\n        state[1] = tmp1;\n        diff = tmp0 - state[3];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[3] = state[2] + diff * kResampleAllpass[1][2];\n        state[2] = tmp0;\n\n        // scale down, round and store\n        out[i << 1] = state[3] >> 15;\n    }\n}\n\n//\n//   interpolator\n// input:  WebRtc_Word32 (shifted 15 positions to the left, + offset 16384)\n// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len*2)\n// state:  filter state array; length = 8\nvoid WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word32 *out,\n                             WebRtc_Word32 *state)\n{\n    WebRtc_Word32 tmp0, tmp1, diff;\n    WebRtc_Word32 i;\n\n    // upper allpass filter (generates odd output samples)\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = in[i];\n        diff = tmp0 - state[5];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[4] + diff * kResampleAllpass[0][0];\n        state[4] = tmp0;\n        diff = tmp1 - state[6];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[5] + diff * kResampleAllpass[0][1];\n        state[5] = tmp1;\n        diff = tmp0 - state[7];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[7] = state[6] + diff * kResampleAllpass[0][2];\n        state[6] = tmp0;\n\n        // scale down, round and store\n        out[i << 1] = state[7];\n    }\n\n    out++;\n\n    // lower allpass filter (generates even output samples)\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = in[i];\n        diff = tmp0 - state[1];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[0] + diff * kResampleAllpass[1][0];\n        state[0] = tmp0;\n        diff = tmp1 - state[2];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[1] + diff * kResampleAllpass[1][1];\n        state[1] = tmp1;\n        diff = tmp0 - state[3];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[3] = state[2] + diff * kResampleAllpass[1][2];\n        state[2] = tmp0;\n\n        // scale down, round and store\n        out[i << 1] = state[3];\n    }\n}\n\n//\n//   interpolator\n// input:  WebRtc_Word32 (shifted 15 positions to the left, + offset 16384)\n// output: WebRtc_Word16 (saturated) (of length len*2)\n// state:  filter state array; length = 8\nvoid WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out,\n                               WebRtc_Word32 *state)\n{\n    WebRtc_Word32 tmp0, tmp1, diff;\n    WebRtc_Word32 i;\n\n    // upper allpass filter (generates odd output samples)\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = in[i];\n        diff = tmp0 - state[5];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[4] + diff * kResampleAllpass[0][0];\n        state[4] = tmp0;\n        diff = tmp1 - state[6];\n        // scale down and round\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[5] + diff * kResampleAllpass[0][1];\n        state[5] = tmp1;\n        diff = tmp0 - state[7];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[7] = state[6] + diff * kResampleAllpass[0][2];\n        state[6] = tmp0;\n\n        // scale down, saturate and store\n        tmp1 = state[7] >> 15;\n        if (tmp1 > (WebRtc_Word32)0x00007FFF)\n            tmp1 = 0x00007FFF;\n        if (tmp1 < (WebRtc_Word32)0xFFFF8000)\n            tmp1 = 0xFFFF8000;\n        out[i << 1] = (WebRtc_Word16)tmp1;\n    }\n\n    out++;\n\n    // lower allpass filter (generates even output samples)\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = in[i];\n        diff = tmp0 - state[1];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[0] + diff * kResampleAllpass[1][0];\n        state[0] = tmp0;\n        diff = tmp1 - state[2];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[1] + diff * kResampleAllpass[1][1];\n        state[1] = tmp1;\n        diff = tmp0 - state[3];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[3] = state[2] + diff * kResampleAllpass[1][2];\n        state[2] = tmp0;\n\n        // scale down, saturate and store\n        tmp1 = state[3] >> 15;\n        if (tmp1 > (WebRtc_Word32)0x00007FFF)\n            tmp1 = 0x00007FFF;\n        if (tmp1 < (WebRtc_Word32)0xFFFF8000)\n            tmp1 = 0xFFFF8000;\n        out[i << 1] = (WebRtc_Word16)tmp1;\n    }\n}\n\n//   lowpass filter\n// input:  WebRtc_Word16\n// output: WebRtc_Word32 (normalized, not saturated)\n// state:  filter state array; length = 8\nvoid WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, WebRtc_Word32* out,\n                               WebRtc_Word32* state)\n{\n    WebRtc_Word32 tmp0, tmp1, diff;\n    WebRtc_Word32 i;\n\n    len >>= 1;\n\n    // lower allpass filter: odd input -> even output samples\n    in++;\n    // initial state of polyphase delay element\n    tmp0 = state[12];\n    for (i = 0; i < len; i++)\n    {\n        diff = tmp0 - state[1];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[0] + diff * kResampleAllpass[1][0];\n        state[0] = tmp0;\n        diff = tmp1 - state[2];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[1] + diff * kResampleAllpass[1][1];\n        state[1] = tmp1;\n        diff = tmp0 - state[3];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[3] = state[2] + diff * kResampleAllpass[1][2];\n        state[2] = tmp0;\n\n        // scale down, round and store\n        out[i << 1] = state[3] >> 1;\n        tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);\n    }\n    in--;\n\n    // upper allpass filter: even input -> even output samples\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);\n        diff = tmp0 - state[5];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[4] + diff * kResampleAllpass[0][0];\n        state[4] = tmp0;\n        diff = tmp1 - state[6];\n        // scale down and round\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[5] + diff * kResampleAllpass[0][1];\n        state[5] = tmp1;\n        diff = tmp0 - state[7];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[7] = state[6] + diff * kResampleAllpass[0][2];\n        state[6] = tmp0;\n\n        // average the two allpass outputs, scale down and store\n        out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;\n    }\n\n    // switch to odd output samples\n    out++;\n\n    // lower allpass filter: even input -> odd output samples\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);\n        diff = tmp0 - state[9];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[8] + diff * kResampleAllpass[1][0];\n        state[8] = tmp0;\n        diff = tmp1 - state[10];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[9] + diff * kResampleAllpass[1][1];\n        state[9] = tmp1;\n        diff = tmp0 - state[11];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[11] = state[10] + diff * kResampleAllpass[1][2];\n        state[10] = tmp0;\n\n        // scale down, round and store\n        out[i << 1] = state[11] >> 1;\n    }\n\n    // upper allpass filter: odd input -> odd output samples\n    in++;\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);\n        diff = tmp0 - state[13];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[12] + diff * kResampleAllpass[0][0];\n        state[12] = tmp0;\n        diff = tmp1 - state[14];\n        // scale down and round\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[13] + diff * kResampleAllpass[0][1];\n        state[13] = tmp1;\n        diff = tmp0 - state[15];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[15] = state[14] + diff * kResampleAllpass[0][2];\n        state[14] = tmp0;\n\n        // average the two allpass outputs, scale down and store\n        out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;\n    }\n}\n\n//   lowpass filter\n// input:  WebRtc_Word32 (shifted 15 positions to the left, + offset 16384)\n// output: WebRtc_Word32 (normalized, not saturated)\n// state:  filter state array; length = 8\nvoid WebRtcSpl_LPBy2IntToInt(const WebRtc_Word32* in, WebRtc_Word32 len, WebRtc_Word32* out,\n                             WebRtc_Word32* state)\n{\n    WebRtc_Word32 tmp0, tmp1, diff;\n    WebRtc_Word32 i;\n\n    len >>= 1;\n\n    // lower allpass filter: odd input -> even output samples\n    in++;\n    // initial state of polyphase delay element\n    tmp0 = state[12];\n    for (i = 0; i < len; i++)\n    {\n        diff = tmp0 - state[1];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[0] + diff * kResampleAllpass[1][0];\n        state[0] = tmp0;\n        diff = tmp1 - state[2];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[1] + diff * kResampleAllpass[1][1];\n        state[1] = tmp1;\n        diff = tmp0 - state[3];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[3] = state[2] + diff * kResampleAllpass[1][2];\n        state[2] = tmp0;\n\n        // scale down, round and store\n        out[i << 1] = state[3] >> 1;\n        tmp0 = in[i << 1];\n    }\n    in--;\n\n    // upper allpass filter: even input -> even output samples\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = in[i << 1];\n        diff = tmp0 - state[5];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[4] + diff * kResampleAllpass[0][0];\n        state[4] = tmp0;\n        diff = tmp1 - state[6];\n        // scale down and round\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[5] + diff * kResampleAllpass[0][1];\n        state[5] = tmp1;\n        diff = tmp0 - state[7];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[7] = state[6] + diff * kResampleAllpass[0][2];\n        state[6] = tmp0;\n\n        // average the two allpass outputs, scale down and store\n        out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;\n    }\n\n    // switch to odd output samples\n    out++;\n\n    // lower allpass filter: even input -> odd output samples\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = in[i << 1];\n        diff = tmp0 - state[9];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[8] + diff * kResampleAllpass[1][0];\n        state[8] = tmp0;\n        diff = tmp1 - state[10];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[9] + diff * kResampleAllpass[1][1];\n        state[9] = tmp1;\n        diff = tmp0 - state[11];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[11] = state[10] + diff * kResampleAllpass[1][2];\n        state[10] = tmp0;\n\n        // scale down, round and store\n        out[i << 1] = state[11] >> 1;\n    }\n\n    // upper allpass filter: odd input -> odd output samples\n    in++;\n    for (i = 0; i < len; i++)\n    {\n        tmp0 = in[i << 1];\n        diff = tmp0 - state[13];\n        // scale down and round\n        diff = (diff + (1 << 13)) >> 14;\n        tmp1 = state[12] + diff * kResampleAllpass[0][0];\n        state[12] = tmp0;\n        diff = tmp1 - state[14];\n        // scale down and round\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        tmp0 = state[13] + diff * kResampleAllpass[0][1];\n        state[13] = tmp1;\n        diff = tmp0 - state[15];\n        // scale down and truncate\n        diff = diff >> 14;\n        if (diff < 0)\n            diff += 1;\n        state[15] = state[14] + diff * kResampleAllpass[0][2];\n        state[14] = tmp0;\n\n        // average the two allpass outputs, scale down and store\n        out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/resample_by_2_internal.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This header file contains some internal resampling functions.\n *\n */\n\n#ifndef WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_\n#define WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_\n\n#include \"typedefs.h\"\n\n/*******************************************************************\n * resample_by_2_fast.c\n * Functions for internal use in the other resample functions\n ******************************************************************/\nvoid WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out,\n                                 WebRtc_Word32 *state);\n\nvoid WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len,\n                                 WebRtc_Word32 *out, WebRtc_Word32 *state);\n\nvoid WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len,\n                               WebRtc_Word32 *out, WebRtc_Word32 *state);\n\nvoid WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word32 *out,\n                             WebRtc_Word32 *state);\n\nvoid WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len,\n                               WebRtc_Word16 *out, WebRtc_Word32 *state);\n\nvoid WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len,\n                               WebRtc_Word32* out, WebRtc_Word32* state);\n\nvoid WebRtcSpl_LPBy2IntToInt(const WebRtc_Word32* in, WebRtc_Word32 len, WebRtc_Word32* out,\n                             WebRtc_Word32* state);\n\n#endif // WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/resample_fractional.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the resampling functions between 48, 44, 32 and 24 kHz.\n * The description headers can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\n// interpolation coefficients\nstatic const WebRtc_Word16 kCoefficients48To32[2][8] = {\n        {778, -2050, 1087, 23285, 12903, -3783, 441, 222},\n        {222, 441, -3783, 12903, 23285, 1087, -2050, 778}\n};\n\nstatic const WebRtc_Word16 kCoefficients32To24[3][8] = {\n        {767, -2362, 2434, 24406, 10620, -3838, 721, 90},\n        {386, -381, -2646, 19062, 19062, -2646, -381, 386},\n        {90, 721, -3838, 10620, 24406, 2434, -2362, 767}\n};\n\nstatic const WebRtc_Word16 kCoefficients44To32[4][9] = {\n        {117, -669, 2245, -6183, 26267, 13529, -3245, 845, -138},\n        {-101, 612, -2283, 8532, 29790, -5138, 1789, -524, 91},\n        {50, -292, 1016, -3064, 32010, 3933, -1147, 315, -53},\n        {-156, 974, -3863, 18603, 21691, -6246, 2353, -712, 126}\n};\n\n//   Resampling ratio: 2/3\n// input:  WebRtc_Word32 (normalized, not saturated) :: size 3 * K\n// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 2 * K\n//      K: number of blocks\n\nvoid WebRtcSpl_Resample48khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out,\n                                    const WebRtc_Word32 K)\n{\n    /////////////////////////////////////////////////////////////\n    // Filter operation:\n    //\n    // Perform resampling (3 input samples -> 2 output samples);\n    // process in sub blocks of size 3 samples.\n    WebRtc_Word32 tmp;\n    WebRtc_Word32 m;\n\n    for (m = 0; m < K; m++)\n    {\n        tmp = 1 << 14;\n        tmp += kCoefficients48To32[0][0] * In[0];\n        tmp += kCoefficients48To32[0][1] * In[1];\n        tmp += kCoefficients48To32[0][2] * In[2];\n        tmp += kCoefficients48To32[0][3] * In[3];\n        tmp += kCoefficients48To32[0][4] * In[4];\n        tmp += kCoefficients48To32[0][5] * In[5];\n        tmp += kCoefficients48To32[0][6] * In[6];\n        tmp += kCoefficients48To32[0][7] * In[7];\n        Out[0] = tmp;\n\n        tmp = 1 << 14;\n        tmp += kCoefficients48To32[1][0] * In[1];\n        tmp += kCoefficients48To32[1][1] * In[2];\n        tmp += kCoefficients48To32[1][2] * In[3];\n        tmp += kCoefficients48To32[1][3] * In[4];\n        tmp += kCoefficients48To32[1][4] * In[5];\n        tmp += kCoefficients48To32[1][5] * In[6];\n        tmp += kCoefficients48To32[1][6] * In[7];\n        tmp += kCoefficients48To32[1][7] * In[8];\n        Out[1] = tmp;\n\n        // update pointers\n        In += 3;\n        Out += 2;\n    }\n}\n\n//   Resampling ratio: 3/4\n// input:  WebRtc_Word32 (normalized, not saturated) :: size 4 * K\n// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 3 * K\n//      K: number of blocks\n\nvoid WebRtcSpl_Resample32khzTo24khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out,\n                                    const WebRtc_Word32 K)\n{\n    /////////////////////////////////////////////////////////////\n    // Filter operation:\n    //\n    // Perform resampling (4 input samples -> 3 output samples);\n    // process in sub blocks of size 4 samples.\n    WebRtc_Word32 m;\n    WebRtc_Word32 tmp;\n\n    for (m = 0; m < K; m++)\n    {\n        tmp = 1 << 14;\n        tmp += kCoefficients32To24[0][0] * In[0];\n        tmp += kCoefficients32To24[0][1] * In[1];\n        tmp += kCoefficients32To24[0][2] * In[2];\n        tmp += kCoefficients32To24[0][3] * In[3];\n        tmp += kCoefficients32To24[0][4] * In[4];\n        tmp += kCoefficients32To24[0][5] * In[5];\n        tmp += kCoefficients32To24[0][6] * In[6];\n        tmp += kCoefficients32To24[0][7] * In[7];\n        Out[0] = tmp;\n\n        tmp = 1 << 14;\n        tmp += kCoefficients32To24[1][0] * In[1];\n        tmp += kCoefficients32To24[1][1] * In[2];\n        tmp += kCoefficients32To24[1][2] * In[3];\n        tmp += kCoefficients32To24[1][3] * In[4];\n        tmp += kCoefficients32To24[1][4] * In[5];\n        tmp += kCoefficients32To24[1][5] * In[6];\n        tmp += kCoefficients32To24[1][6] * In[7];\n        tmp += kCoefficients32To24[1][7] * In[8];\n        Out[1] = tmp;\n\n        tmp = 1 << 14;\n        tmp += kCoefficients32To24[2][0] * In[2];\n        tmp += kCoefficients32To24[2][1] * In[3];\n        tmp += kCoefficients32To24[2][2] * In[4];\n        tmp += kCoefficients32To24[2][3] * In[5];\n        tmp += kCoefficients32To24[2][4] * In[6];\n        tmp += kCoefficients32To24[2][5] * In[7];\n        tmp += kCoefficients32To24[2][6] * In[8];\n        tmp += kCoefficients32To24[2][7] * In[9];\n        Out[2] = tmp;\n\n        // update pointers\n        In += 4;\n        Out += 3;\n    }\n}\n\n//\n// fractional resampling filters\n//   Fout = 11/16 * Fin\n//   Fout =  8/11 * Fin\n//\n\n// compute two inner-products and store them to output array\nstatic void WebRtcSpl_ResampDotProduct(const WebRtc_Word32 *in1, const WebRtc_Word32 *in2,\n                               const WebRtc_Word16 *coef_ptr, WebRtc_Word32 *out1,\n                               WebRtc_Word32 *out2)\n{\n    WebRtc_Word32 tmp1 = 16384;\n    WebRtc_Word32 tmp2 = 16384;\n    WebRtc_Word16 coef;\n\n    coef = coef_ptr[0];\n    tmp1 += coef * in1[0];\n    tmp2 += coef * in2[-0];\n\n    coef = coef_ptr[1];\n    tmp1 += coef * in1[1];\n    tmp2 += coef * in2[-1];\n\n    coef = coef_ptr[2];\n    tmp1 += coef * in1[2];\n    tmp2 += coef * in2[-2];\n\n    coef = coef_ptr[3];\n    tmp1 += coef * in1[3];\n    tmp2 += coef * in2[-3];\n\n    coef = coef_ptr[4];\n    tmp1 += coef * in1[4];\n    tmp2 += coef * in2[-4];\n\n    coef = coef_ptr[5];\n    tmp1 += coef * in1[5];\n    tmp2 += coef * in2[-5];\n\n    coef = coef_ptr[6];\n    tmp1 += coef * in1[6];\n    tmp2 += coef * in2[-6];\n\n    coef = coef_ptr[7];\n    tmp1 += coef * in1[7];\n    tmp2 += coef * in2[-7];\n\n    coef = coef_ptr[8];\n    *out1 = tmp1 + coef * in1[8];\n    *out2 = tmp2 + coef * in2[-8];\n}\n\n//   Resampling ratio: 8/11\n// input:  WebRtc_Word32 (normalized, not saturated) :: size 11 * K\n// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size  8 * K\n//      K: number of blocks\n\nvoid WebRtcSpl_Resample44khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out,\n                                    const WebRtc_Word32 K)\n{\n    /////////////////////////////////////////////////////////////\n    // Filter operation:\n    //\n    // Perform resampling (11 input samples -> 8 output samples);\n    // process in sub blocks of size 11 samples.\n    WebRtc_Word32 tmp;\n    WebRtc_Word32 m;\n\n    for (m = 0; m < K; m++)\n    {\n        tmp = 1 << 14;\n\n        // first output sample\n        Out[0] = ((WebRtc_Word32)In[3] << 15) + tmp;\n\n        // sum and accumulate filter coefficients and input samples\n        tmp += kCoefficients44To32[3][0] * In[5];\n        tmp += kCoefficients44To32[3][1] * In[6];\n        tmp += kCoefficients44To32[3][2] * In[7];\n        tmp += kCoefficients44To32[3][3] * In[8];\n        tmp += kCoefficients44To32[3][4] * In[9];\n        tmp += kCoefficients44To32[3][5] * In[10];\n        tmp += kCoefficients44To32[3][6] * In[11];\n        tmp += kCoefficients44To32[3][7] * In[12];\n        tmp += kCoefficients44To32[3][8] * In[13];\n        Out[4] = tmp;\n\n        // sum and accumulate filter coefficients and input samples\n        WebRtcSpl_ResampDotProduct(&In[0], &In[17], kCoefficients44To32[0], &Out[1], &Out[7]);\n\n        // sum and accumulate filter coefficients and input samples\n        WebRtcSpl_ResampDotProduct(&In[2], &In[15], kCoefficients44To32[1], &Out[2], &Out[6]);\n\n        // sum and accumulate filter coefficients and input samples\n        WebRtcSpl_ResampDotProduct(&In[3], &In[14], kCoefficients44To32[2], &Out[3], &Out[5]);\n\n        // update pointers\n        In += 11;\n        Out += 8;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/sin_table.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the 360 degree sine table.\n *\n */\n\n#include \"signal_processing_library.h\"\n\nWebRtc_Word16 WebRtcSpl_kSinTable[] = {\n        0,    142,    285,    428,    571,    713,    856,    998,   1140,\n     1281,   1422,   1563,   1703,   1842,   1981,   2120,   2258,   2395,\n     2531,   2667,   2801,   2935,   3068,   3200,   3331,   3462,   3591,\n     3719,   3845,   3971,   4095,   4219,   4341,   4461,   4580,   4698,\n     4815,   4930,   5043,   5155,   5265,   5374,   5481,   5586,   5690,\n     5792,   5892,   5991,   6087,   6182,   6275,   6366,   6455,   6542,\n     6627,   6710,   6791,   6870,   6947,   7021,   7094,   7164,   7233,\n     7299,   7362,   7424,   7483,   7540,   7595,   7647,   7697,   7745,\n     7791,   7834,   7874,   7912,   7948,   7982,   8012,   8041,   8067,\n     8091,   8112,   8130,   8147,   8160,   8172,   8180,   8187,   8190,\n     8191,   8190,   8187,   8180,   8172,   8160,   8147,   8130,   8112,\n     8091,   8067,   8041,   8012,   7982,   7948,   7912,   7874,   7834,\n     7791,   7745,   7697,   7647,   7595,   7540,   7483,   7424,   7362,\n     7299,   7233,   7164,   7094,   7021,   6947,   6870,   6791,   6710,\n     6627,   6542,   6455,   6366,   6275,   6182,   6087,   5991,   5892,\n     5792,   5690,   5586,   5481,   5374,   5265,   5155,   5043,   4930,\n     4815,   4698,   4580,   4461,   4341,   4219,   4096,   3971,   3845,\n     3719,   3591,   3462,   3331,   3200,   3068,   2935,   2801,   2667,\n     2531,   2395,   2258,   2120,   1981,   1842,   1703,   1563,   1422,\n     1281,   1140,    998,    856,    713,    571,    428,    285,    142,\n        0,   -142,   -285,   -428,   -571,   -713,   -856,   -998,  -1140,\n    -1281,  -1422,  -1563,  -1703,  -1842,  -1981,  -2120,  -2258,  -2395,\n    -2531,  -2667,  -2801,  -2935,  -3068,  -3200,  -3331,  -3462,  -3591,\n    -3719,  -3845,  -3971,  -4095,  -4219,  -4341,  -4461,  -4580,  -4698,\n    -4815,  -4930,  -5043,  -5155,  -5265,  -5374,  -5481,  -5586,  -5690,\n    -5792,  -5892,  -5991,  -6087,  -6182,  -6275,  -6366,  -6455,  -6542,\n    -6627,  -6710,  -6791,  -6870,  -6947,  -7021,  -7094,  -7164,  -7233,\n    -7299,  -7362,  -7424,  -7483,  -7540,  -7595,  -7647,  -7697,  -7745,\n    -7791,  -7834,  -7874,  -7912,  -7948,  -7982,  -8012,  -8041,  -8067,\n    -8091,  -8112,  -8130,  -8147,  -8160,  -8172,  -8180,  -8187,  -8190,\n    -8191,  -8190,  -8187,  -8180,  -8172,  -8160,  -8147,  -8130,  -8112,\n    -8091,  -8067,  -8041,  -8012,  -7982,  -7948,  -7912,  -7874,  -7834,\n    -7791,  -7745,  -7697,  -7647,  -7595,  -7540,  -7483,  -7424,  -7362,\n    -7299,  -7233,  -7164,  -7094,  -7021,  -6947,  -6870,  -6791,  -6710,\n    -6627,  -6542,  -6455,  -6366,  -6275,  -6182,  -6087,  -5991,  -5892,\n    -5792,  -5690,  -5586,  -5481,  -5374,  -5265,  -5155,  -5043,  -4930,\n    -4815,  -4698,  -4580,  -4461,  -4341,  -4219,  -4096,  -3971,  -3845,\n    -3719,  -3591,  -3462,  -3331,  -3200,  -3068,  -2935,  -2801,  -2667,\n    -2531,  -2395,  -2258,  -2120,  -1981,  -1842,  -1703,  -1563,  -1422,\n    -1281,  -1140,   -998,   -856,   -713,   -571,   -428,   -285,   -142\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/sin_table_1024.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the 1024 point sine table.\n *\n */\n\n#include \"signal_processing_library.h\"\n\nWebRtc_Word16 WebRtcSpl_kSinTable1024[] =\n{\n      0,    201,    402,    603,    804,   1005,   1206,   1406,\n   1607,   1808,   2009,   2209,   2410,   2610,   2811,   3011,\n   3211,   3411,   3611,   3811,   4011,   4210,   4409,   4608,\n   4807,   5006,   5205,   5403,   5601,   5799,   5997,   6195,\n   6392,   6589,   6786,   6982,   7179,   7375,   7571,   7766,\n   7961,   8156,   8351,   8545,   8739,   8932,   9126,   9319,\n   9511,   9703,   9895,  10087,  10278,  10469,  10659,  10849,\n  11038,  11227,  11416,  11604,  11792,  11980,  12166,  12353,\n  12539,  12724,  12909,  13094,  13278,  13462,  13645,  13827,\n  14009,  14191,  14372,  14552,  14732,  14911,  15090,  15268,\n  15446,  15623,  15799,  15975,  16150,  16325,  16499,  16672,\n  16845,  17017,  17189,  17360,  17530,  17699,  17868,  18036,\n  18204,  18371,  18537,  18702,  18867,  19031,  19194,  19357,\n  19519,  19680,  19840,  20000,  20159,  20317,  20474,  20631,\n  20787,  20942,  21096,  21249,  21402,  21554,  21705,  21855,\n  22004,  22153,  22301,  22448,  22594,  22739,  22883,  23027,\n  23169,  23311,  23452,  23592,  23731,  23869,  24006,  24143,\n  24278,  24413,  24546,  24679,  24811,  24942,  25072,  25201,\n  25329,  25456,  25582,  25707,  25831,  25954,  26077,  26198,\n  26318,  26437,  26556,  26673,  26789,  26905,  27019,  27132,\n  27244,  27355,  27466,  27575,  27683,  27790,  27896,  28001,\n  28105,  28208,  28309,  28410,  28510,  28608,  28706,  28802,\n  28897,  28992,  29085,  29177,  29268,  29358,  29446,  29534,\n  29621,  29706,  29790,  29873,  29955,  30036,  30116,  30195,\n  30272,  30349,  30424,  30498,  30571,  30643,  30713,  30783,\n  30851,  30918,  30984,  31049,\n  31113,  31175,  31236,  31297,\n  31356,  31413,  31470,  31525,  31580,  31633,  31684,  31735,\n  31785,  31833,  31880,  31926,  31970,  32014,  32056,  32097,\n  32137,  32176,  32213,  32249,  32284,  32318,  32350,  32382,\n  32412,  32441,  32468,  32495,  32520,  32544,  32567,  32588,\n  32609,  32628,  32646,  32662,  32678,  32692,  32705,  32717,\n  32727,  32736,  32744,  32751,  32757,  32761,  32764,  32766,\n  32767,  32766,  32764,  32761,  32757,  32751,  32744,  32736,\n  32727,  32717,  32705,  32692,  32678,  32662,  32646,  32628,\n  32609,  32588,  32567,  32544,  32520,  32495,  32468,  32441,\n  32412,  32382,  32350,  32318,  32284,  32249,  32213,  32176,\n  32137,  32097,  32056,  32014,  31970,  31926,  31880,  31833,\n  31785,  31735,  31684,  31633,  31580,  31525,  31470,  31413,\n  31356,  31297,  31236,  31175,  31113,  31049,  30984,  30918,\n  30851,  30783,  30713,  30643,  30571,  30498,  30424,  30349,\n  30272,  30195,  30116,  30036,  29955,  29873,  29790,  29706,\n  29621,  29534,  29446,  29358,  29268,  29177,  29085,  28992,\n  28897,  28802,  28706,  28608,  28510,  28410,  28309,  28208,\n  28105,  28001,  27896,  27790,  27683,  27575,  27466,  27355,\n  27244,  27132,  27019,  26905,  26789,  26673,  26556,  26437,\n  26318,  26198,  26077,  25954,  25831,  25707,  25582,  25456,\n  25329,  25201,  25072,  24942,  24811,  24679,  24546,  24413,\n  24278,  24143,  24006,  23869,  23731,  23592,  23452,  23311,\n  23169,  23027,  22883,  22739,  22594,  22448,  22301,  22153,\n  22004,  21855,  21705,  21554,  21402,  21249,  21096,  20942,\n  20787,  20631,  20474,  20317,  20159,  20000,  19840,  19680,\n  19519,  19357,  19194,  19031,  18867,  18702,  18537,  18371,\n  18204,  18036,  17868,  17699,  17530,  17360,  17189,  17017,\n  16845,  16672,  16499,  16325,  16150,  15975,  15799,  15623,\n  15446,  15268,  15090,  14911,  14732,  14552,  14372,  14191,\n  14009,  13827,  13645,  13462,  13278,  13094,  12909,  12724,\n  12539,  12353,  12166,  11980,  11792,  11604,  11416,  11227,\n  11038,  10849,  10659,  10469,  10278,  10087,   9895,   9703,\n   9511,   9319,   9126,   8932,   8739,   8545,   8351,   8156,\n   7961,   7766,   7571,   7375,   7179,   6982,   6786,   6589,\n   6392,   6195,   5997,   5799,   5601,   5403,   5205,   5006,\n   4807,   4608,   4409,   4210,   4011,   3811,   3611,   3411,\n   3211,   3011,   2811,   2610,   2410,   2209,   2009,   1808,\n   1607,   1406,   1206,   1005,    804,    603,    402,    201,\n      0,   -201,   -402,   -603,   -804,  -1005,  -1206,  -1406,\n  -1607,  -1808,  -2009,  -2209,  -2410,  -2610,  -2811,  -3011,\n  -3211,  -3411,  -3611,  -3811,  -4011,  -4210,  -4409,  -4608,\n  -4807,  -5006,  -5205,  -5403,  -5601,  -5799,  -5997,  -6195,\n  -6392,  -6589,  -6786,  -6982,  -7179,  -7375,  -7571,  -7766,\n  -7961,  -8156,  -8351,  -8545,  -8739,  -8932,  -9126,  -9319,\n  -9511,  -9703,  -9895, -10087, -10278, -10469, -10659, -10849,\n -11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353,\n -12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827,\n -14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268,\n -15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672,\n -16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036,\n -18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357,\n -19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631,\n -20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855,\n -22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027,\n -23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143,\n -24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201,\n -25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198,\n -26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132,\n -27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001,\n -28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802,\n -28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534,\n -29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195,\n -30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783,\n -30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297,\n -31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735,\n -31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097,\n -32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382,\n -32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588,\n -32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717,\n -32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766,\n -32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736,\n -32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628,\n -32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441,\n -32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176,\n -32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833,\n -31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413,\n -31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918,\n -30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349,\n -30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706,\n -29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992,\n -28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208,\n -28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355,\n -27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437,\n -26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456,\n -25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413,\n -24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311,\n -23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153,\n -22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942,\n -20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680,\n -19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371,\n -18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017,\n -16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623,\n -15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191,\n -14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724,\n -12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227,\n -11038, -10849, -10659, -10469, -10278, -10087,  -9895,  -9703,\n  -9511,  -9319,  -9126,  -8932,  -8739,  -8545,  -8351,  -8156,\n  -7961,  -7766,  -7571,  -7375,  -7179,  -6982,  -6786,  -6589,\n  -6392,  -6195,  -5997,  -5799,  -5601,  -5403,  -5205,  -5006,\n  -4807,  -4608,  -4409,  -4210,  -4011,  -3811,  -3611,  -3411,\n  -3211,  -3011,  -2811,  -2610,  -2410,  -2209,  -2009,  -1808,\n  -1607,  -1406,  -1206,  -1005,   -804,   -603,   -402,   -201,\n};\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/spl_sqrt.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_Sqrt().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nWebRtc_Word32 WebRtcSpl_SqrtLocal(WebRtc_Word32 in);\n\nWebRtc_Word32 WebRtcSpl_SqrtLocal(WebRtc_Word32 in)\n{\n\n    WebRtc_Word16 x_half, t16;\n    WebRtc_Word32 A, B, x2;\n\n    /* The following block performs:\n     y=in/2\n     x=y-2^30\n     x_half=x/2^31\n     t = 1 + (x_half) - 0.5*((x_half)^2) + 0.5*((x_half)^3) - 0.625*((x_half)^4)\n         + 0.875*((x_half)^5)\n     */\n\n    B = in;\n\n    B = WEBRTC_SPL_RSHIFT_W32(B, 1); // B = in/2\n    B = B - ((WebRtc_Word32)0x40000000); // B = in/2 - 1/2\n    x_half = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(B, 16);// x_half = x/2 = (in-1)/2\n    B = B + ((WebRtc_Word32)0x40000000); // B = 1 + x/2\n    B = B + ((WebRtc_Word32)0x40000000); // Add 0.5 twice (since 1.0 does not exist in Q31)\n\n    x2 = ((WebRtc_Word32)x_half) * ((WebRtc_Word32)x_half) * 2; // A = (x/2)^2\n    A = -x2; // A = -(x/2)^2\n    B = B + (A >> 1); // B = 1 + x/2 - 0.5*(x/2)^2\n\n    A = WEBRTC_SPL_RSHIFT_W32(A, 16);\n    A = A * A * 2; // A = (x/2)^4\n    t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16);\n    B = B + WEBRTC_SPL_MUL_16_16(-20480, t16) * 2; // B = B - 0.625*A\n    // After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4\n\n    t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16);\n    A = WEBRTC_SPL_MUL_16_16(x_half, t16) * 2; // A = (x/2)^5\n    t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16);\n    B = B + WEBRTC_SPL_MUL_16_16(28672, t16) * 2; // B = B + 0.875*A\n    // After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4 + 0.875*(x/2)^5\n\n    t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(x2, 16);\n    A = WEBRTC_SPL_MUL_16_16(x_half, t16) * 2; // A = x/2^3\n\n    B = B + (A >> 1); // B = B + 0.5*A\n    // After this, B = 1 + x/2 - 0.5*(x/2)^2 + 0.5*(x/2)^3 - 0.625*(x/2)^4 + 0.875*(x/2)^5\n\n    B = B + ((WebRtc_Word32)32768); // Round off bit\n\n    return B;\n}\n\nWebRtc_Word32 WebRtcSpl_Sqrt(WebRtc_Word32 value)\n{\n    /*\n     Algorithm:\n\n     Six term Taylor Series is used here to compute the square root of a number\n     y^0.5 = (1+x)^0.5 where x = y-1\n     = 1+(x/2)-0.5*((x/2)^2+0.5*((x/2)^3-0.625*((x/2)^4+0.875*((x/2)^5)\n     0.5 <= x < 1\n\n     Example of how the algorithm works, with ut=sqrt(in), and\n     with in=73632 and ut=271 (even shift value case):\n\n     in=73632\n     y= in/131072\n     x=y-1\n     t = 1 + (x/2) - 0.5*((x/2)^2) + 0.5*((x/2)^3) - 0.625*((x/2)^4) + 0.875*((x/2)^5)\n     ut=t*(1/sqrt(2))*512\n\n     or:\n\n     in=73632\n     in2=73632*2^14\n     y= in2/2^31\n     x=y-1\n     t = 1 + (x/2) - 0.5*((x/2)^2) + 0.5*((x/2)^3) - 0.625*((x/2)^4) + 0.875*((x/2)^5)\n     ut=t*(1/sqrt(2))\n     ut2=ut*2^9\n\n     which gives:\n\n     in  = 73632\n     in2 = 1206386688\n     y   = 0.56176757812500\n     x   = -0.43823242187500\n     t   = 0.74973506527313\n     ut  = 0.53014274874797\n     ut2 = 2.714330873589594e+002\n\n     or:\n\n     in=73632\n     in2=73632*2^14\n     y=in2/2\n     x=y-2^30\n     x_half=x/2^31\n     t = 1 + (x_half) - 0.5*((x_half)^2) + 0.5*((x_half)^3) - 0.625*((x_half)^4)\n         + 0.875*((x_half)^5)\n     ut=t*(1/sqrt(2))\n     ut2=ut*2^9\n\n     which gives:\n\n     in  = 73632\n     in2 = 1206386688\n     y   = 603193344\n     x   = -470548480\n     x_half =  -0.21911621093750\n     t   = 0.74973506527313\n     ut  = 0.53014274874797\n     ut2 = 2.714330873589594e+002\n\n     */\n\n    WebRtc_Word16 x_norm, nshift, t16, sh;\n    WebRtc_Word32 A;\n\n    WebRtc_Word16 k_sqrt_2 = 23170; // 1/sqrt2 (==5a82)\n\n    A = value;\n\n    if (A == 0)\n        return (WebRtc_Word32)0; // sqrt(0) = 0\n\n    sh = WebRtcSpl_NormW32(A); // # shifts to normalize A\n    A = WEBRTC_SPL_LSHIFT_W32(A, sh); // Normalize A\n    if (A < (WEBRTC_SPL_WORD32_MAX - 32767))\n    {\n        A = A + ((WebRtc_Word32)32768); // Round off bit\n    } else\n    {\n        A = WEBRTC_SPL_WORD32_MAX;\n    }\n\n    x_norm = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); // x_norm = AH\n\n    nshift = WEBRTC_SPL_RSHIFT_W16(sh, 1); // nshift = sh>>1\n    nshift = -nshift; // Negate the power for later de-normalization\n\n    A = (WebRtc_Word32)WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)x_norm, 16);\n    A = WEBRTC_SPL_ABS_W32(A); // A = abs(x_norm<<16)\n    A = WebRtcSpl_SqrtLocal(A); // A = sqrt(A)\n\n    if ((-2 * nshift) == sh)\n    { // Even shift value case\n\n        t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); // t16 = AH\n\n        A = WEBRTC_SPL_MUL_16_16(k_sqrt_2, t16) * 2; // A = 1/sqrt(2)*t16\n        A = A + ((WebRtc_Word32)32768); // Round off\n        A = A & ((WebRtc_Word32)0x7fff0000); // Round off\n\n        A = WEBRTC_SPL_RSHIFT_W32(A, 15); // A = A>>16\n\n    } else\n    {\n        A = WEBRTC_SPL_RSHIFT_W32(A, 16); // A = A>>16\n    }\n\n    A = A & ((WebRtc_Word32)0x0000ffff);\n    A = (WebRtc_Word32)WEBRTC_SPL_SHIFT_W32(A, nshift); // De-normalize the result\n\n    return A;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/spl_sqrt_floor.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/*\n * This file contains the function WebRtcSpl_SqrtFloor().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\n#define WEBRTC_SPL_SQRT_ITER(N)                 \\\n  try1 = root + (1 << (N));                     \\\n  if (value >= try1 << (N))                     \\\n  {                                             \\\n    value -= try1 << (N);                       \\\n    root |= 2 << (N);                           \\\n  }\n\n// (out) Square root of input parameter\nWebRtc_Word32 WebRtcSpl_SqrtFloor(WebRtc_Word32 value)\n{\n    // new routine for performance, 4 cycles/bit in ARM\n    // output precision is 16 bits\n\n    WebRtc_Word32 root = 0, try1;\n\n    WEBRTC_SPL_SQRT_ITER (15);\n    WEBRTC_SPL_SQRT_ITER (14);\n    WEBRTC_SPL_SQRT_ITER (13);\n    WEBRTC_SPL_SQRT_ITER (12);\n    WEBRTC_SPL_SQRT_ITER (11);\n    WEBRTC_SPL_SQRT_ITER (10);\n    WEBRTC_SPL_SQRT_ITER ( 9);\n    WEBRTC_SPL_SQRT_ITER ( 8);\n    WEBRTC_SPL_SQRT_ITER ( 7);\n    WEBRTC_SPL_SQRT_ITER ( 6);\n    WEBRTC_SPL_SQRT_ITER ( 5);\n    WEBRTC_SPL_SQRT_ITER ( 4);\n    WEBRTC_SPL_SQRT_ITER ( 3);\n    WEBRTC_SPL_SQRT_ITER ( 2);\n    WEBRTC_SPL_SQRT_ITER ( 1);\n    WEBRTC_SPL_SQRT_ITER ( 0);\n\n    return root >> 1;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/spl_version.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_get_version().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include <string.h>\n#include \"signal_processing_library.h\"\n\nWebRtc_Word16 WebRtcSpl_get_version(char* version, WebRtc_Word16 length_in_bytes)\n{\n    strncpy(version, \"1.2.0\", length_in_bytes);\n    return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/splitting_filter.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/*\n * This file contains the splitting filter functions.\n *\n */\n\n#include \"signal_processing_library.h\"\n\n// Number of samples in a low/high-band frame.\nenum\n{\n    kBandFrameLength = 160\n};\n\n// QMF filter coefficients in Q16.\nstatic const WebRtc_UWord16 WebRtcSpl_kAllPassFilter1[3] = {6418, 36982, 57261};\nstatic const WebRtc_UWord16 WebRtcSpl_kAllPassFilter2[3] = {21333, 49062, 63010};\n\n///////////////////////////////////////////////////////////////////////////////////////////////\n// WebRtcSpl_AllPassQMF(...)\n//\n// Allpass filter used by the analysis and synthesis parts of the QMF filter.\n//\n// Input:\n//    - in_data             : Input data sequence (Q10)\n//    - data_length         : Length of data sequence (>2)\n//    - filter_coefficients : Filter coefficients (length 3, Q16)\n//\n// Input & Output:\n//    - filter_state        : Filter state (length 6, Q10).\n//\n// Output:\n//    - out_data            : Output data sequence (Q10), length equal to\n//                            |data_length|\n//\n\nvoid WebRtcSpl_AllPassQMF(WebRtc_Word32* in_data, const WebRtc_Word16 data_length,\n                          WebRtc_Word32* out_data, const WebRtc_UWord16* filter_coefficients,\n                          WebRtc_Word32* filter_state)\n{\n    // The procedure is to filter the input with three first order all pass filters\n    // (cascade operations).\n    //\n    //         a_3 + q^-1    a_2 + q^-1    a_1 + q^-1\n    // y[n] =  -----------   -----------   -----------   x[n]\n    //         1 + a_3q^-1   1 + a_2q^-1   1 + a_1q^-1\n    //\n    // The input vector |filter_coefficients| includes these three filter coefficients.\n    // The filter state contains the in_data state, in_data[-1], followed by\n    // the out_data state, out_data[-1]. This is repeated for each cascade.\n    // The first cascade filter will filter the |in_data| and store the output in\n    // |out_data|. The second will the take the |out_data| as input and make an\n    // intermediate storage in |in_data|, to save memory. The third, and final, cascade\n    // filter operation takes the |in_data| (which is the output from the previous cascade\n    // filter) and store the output in |out_data|.\n    // Note that the input vector values are changed during the process.\n    WebRtc_Word16 k;\n    WebRtc_Word32 diff;\n    // First all-pass cascade; filter from in_data to out_data.\n\n    // Let y_i[n] indicate the output of cascade filter i (with filter coefficient a_i) at\n    // vector position n. Then the final output will be y[n] = y_3[n]\n\n    // First loop, use the states stored in memory.\n    // \"diff\" should be safe from wrap around since max values are 2^25\n    diff = WEBRTC_SPL_SUB_SAT_W32(in_data[0], filter_state[1]); // = (x[0] - y_1[-1])\n    // y_1[0] =  x[-1] + a_1 * (x[0] - y_1[-1])\n    out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, filter_state[0]);\n\n    // For the remaining loops, use previous values.\n    for (k = 1; k < data_length; k++)\n    {\n        diff = WEBRTC_SPL_SUB_SAT_W32(in_data[k], out_data[k - 1]); // = (x[n] - y_1[n-1])\n        // y_1[n] =  x[n-1] + a_1 * (x[n] - y_1[n-1])\n        out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, in_data[k - 1]);\n    }\n\n    // Update states.\n    filter_state[0] = in_data[data_length - 1]; // x[N-1], becomes x[-1] next time\n    filter_state[1] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time\n\n    // Second all-pass cascade; filter from out_data to in_data.\n    diff = WEBRTC_SPL_SUB_SAT_W32(out_data[0], filter_state[3]); // = (y_1[0] - y_2[-1])\n    // y_2[0] =  y_1[-1] + a_2 * (y_1[0] - y_2[-1])\n    in_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, filter_state[2]);\n    for (k = 1; k < data_length; k++)\n    {\n        diff = WEBRTC_SPL_SUB_SAT_W32(out_data[k], in_data[k - 1]); // =(y_1[n] - y_2[n-1])\n        // y_2[0] =  y_1[-1] + a_2 * (y_1[0] - y_2[-1])\n        in_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, out_data[k-1]);\n    }\n\n    filter_state[2] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time\n    filter_state[3] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time\n\n    // Third all-pass cascade; filter from in_data to out_data.\n    diff = WEBRTC_SPL_SUB_SAT_W32(in_data[0], filter_state[5]); // = (y_2[0] - y[-1])\n    // y[0] =  y_2[-1] + a_3 * (y_2[0] - y[-1])\n    out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, filter_state[4]);\n    for (k = 1; k < data_length; k++)\n    {\n        diff = WEBRTC_SPL_SUB_SAT_W32(in_data[k], out_data[k - 1]); // = (y_2[n] - y[n-1])\n        // y[n] =  y_2[n-1] + a_3 * (y_2[n] - y[n-1])\n        out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, in_data[k-1]);\n    }\n    filter_state[4] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time\n    filter_state[5] = out_data[data_length - 1]; // y[N-1], becomes y[-1] next time\n}\n\nvoid WebRtcSpl_AnalysisQMF(const WebRtc_Word16* in_data, WebRtc_Word16* low_band,\n                           WebRtc_Word16* high_band, WebRtc_Word32* filter_state1,\n                           WebRtc_Word32* filter_state2)\n{\n    WebRtc_Word16 i;\n    WebRtc_Word16 k;\n    WebRtc_Word32 tmp;\n    WebRtc_Word32 half_in1[kBandFrameLength];\n    WebRtc_Word32 half_in2[kBandFrameLength];\n    WebRtc_Word32 filter1[kBandFrameLength];\n    WebRtc_Word32 filter2[kBandFrameLength];\n\n    // Split even and odd samples. Also shift them to Q10.\n    for (i = 0, k = 0; i < kBandFrameLength; i++, k += 2)\n    {\n        half_in2[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in_data[k], 10);\n        half_in1[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in_data[k + 1], 10);\n    }\n\n    // All pass filter even and odd samples, independently.\n    WebRtcSpl_AllPassQMF(half_in1, kBandFrameLength, filter1, WebRtcSpl_kAllPassFilter1,\n                         filter_state1);\n    WebRtcSpl_AllPassQMF(half_in2, kBandFrameLength, filter2, WebRtcSpl_kAllPassFilter2,\n                         filter_state2);\n\n    // Take the sum and difference of filtered version of odd and even\n    // branches to get upper & lower band.\n    for (i = 0; i < kBandFrameLength; i++)\n    {\n        tmp = filter1[i] + filter2[i] + 1024;\n        tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11);\n        low_band[i] = (WebRtc_Word16)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX,\n                tmp, WEBRTC_SPL_WORD16_MIN);\n\n        tmp = filter1[i] - filter2[i] + 1024;\n        tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11);\n        high_band[i] = (WebRtc_Word16)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX,\n                tmp, WEBRTC_SPL_WORD16_MIN);\n    }\n}\n\nvoid WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, const WebRtc_Word16* high_band,\n                            WebRtc_Word16* out_data, WebRtc_Word32* filter_state1,\n                            WebRtc_Word32* filter_state2)\n{\n    WebRtc_Word32 tmp;\n    WebRtc_Word32 half_in1[kBandFrameLength];\n    WebRtc_Word32 half_in2[kBandFrameLength];\n    WebRtc_Word32 filter1[kBandFrameLength];\n    WebRtc_Word32 filter2[kBandFrameLength];\n    WebRtc_Word16 i;\n    WebRtc_Word16 k;\n\n    // Obtain the sum and difference channels out of upper and lower-band channels.\n    // Also shift to Q10 domain.\n    for (i = 0; i < kBandFrameLength; i++)\n    {\n        tmp = (WebRtc_Word32)low_band[i] + (WebRtc_Word32)high_band[i];\n        half_in1[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10);\n        tmp = (WebRtc_Word32)low_band[i] - (WebRtc_Word32)high_band[i];\n        half_in2[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10);\n    }\n\n    // all-pass filter the sum and difference channels\n    WebRtcSpl_AllPassQMF(half_in1, kBandFrameLength, filter1, WebRtcSpl_kAllPassFilter2,\n                         filter_state1);\n    WebRtcSpl_AllPassQMF(half_in2, kBandFrameLength, filter2, WebRtcSpl_kAllPassFilter1,\n                         filter_state2);\n\n    // The filtered signals are even and odd samples of the output. Combine\n    // them. The signals are Q10 should shift them back to Q0 and take care of\n    // saturation.\n    for (i = 0, k = 0; i < kBandFrameLength; i++)\n    {\n        tmp = WEBRTC_SPL_RSHIFT_W32(filter2[i] + 512, 10);\n        out_data[k++] = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, tmp, -32768);\n\n        tmp = WEBRTC_SPL_RSHIFT_W32(filter1[i] + 512, 10);\n        out_data[k++] = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, tmp, -32768);\n    }\n\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/sqrt_of_one_minus_x_squared.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the function WebRtcSpl_SqrtOfOneMinusXSquared().\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nvoid WebRtcSpl_SqrtOfOneMinusXSquared(WebRtc_Word16 *xQ15, int vector_length,\n                                      WebRtc_Word16 *yQ15)\n{\n    WebRtc_Word32 sq;\n    int m;\n    WebRtc_Word16 tmp;\n\n    for (m = 0; m < vector_length; m++)\n    {\n        tmp = xQ15[m];\n        sq = WEBRTC_SPL_MUL_16_16(tmp, tmp); // x^2 in Q30\n        sq = 1073741823 - sq; // 1-x^2, where 1 ~= 0.99999999906 is 1073741823 in Q30\n        sq = WebRtcSpl_Sqrt(sq); // sqrt(1-x^2) in Q15\n        yQ15[m] = (WebRtc_Word16)sq;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/vector_scaling_operations.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains implementations of the functions\n * WebRtcSpl_VectorBitShiftW16()\n * WebRtcSpl_VectorBitShiftW32()\n * WebRtcSpl_VectorBitShiftW32ToW16()\n * WebRtcSpl_ScaleVector()\n * WebRtcSpl_ScaleVectorWithSat()\n * WebRtcSpl_ScaleAndAddVectors()\n *\n * The description header can be found in signal_processing_library.h\n *\n */\n\n#include \"signal_processing_library.h\"\n\nvoid WebRtcSpl_VectorBitShiftW16(WebRtc_Word16 *res,\n                             WebRtc_Word16 length,\n                             G_CONST WebRtc_Word16 *in,\n                             WebRtc_Word16 right_shifts)\n{\n    int i;\n\n    if (right_shifts > 0)\n    {\n        for (i = length; i > 0; i--)\n        {\n            (*res++) = ((*in++) >> right_shifts);\n        }\n    } else\n    {\n        for (i = length; i > 0; i--)\n        {\n            (*res++) = ((*in++) << (-right_shifts));\n        }\n    }\n}\n\nvoid WebRtcSpl_VectorBitShiftW32(WebRtc_Word32 *out_vector,\n                             WebRtc_Word16 vector_length,\n                             G_CONST WebRtc_Word32 *in_vector,\n                             WebRtc_Word16 right_shifts)\n{\n    int i;\n\n    if (right_shifts > 0)\n    {\n        for (i = vector_length; i > 0; i--)\n        {\n            (*out_vector++) = ((*in_vector++) >> right_shifts);\n        }\n    } else\n    {\n        for (i = vector_length; i > 0; i--)\n        {\n            (*out_vector++) = ((*in_vector++) << (-right_shifts));\n        }\n    }\n}\n\nvoid WebRtcSpl_VectorBitShiftW32ToW16(WebRtc_Word16 *res,\n                                  WebRtc_Word16 length,\n                                  G_CONST WebRtc_Word32 *in,\n                                  WebRtc_Word16 right_shifts)\n{\n    int i;\n\n    if (right_shifts >= 0)\n    {\n        for (i = length; i > 0; i--)\n        {\n            (*res++) = (WebRtc_Word16)((*in++) >> right_shifts);\n        }\n    } else\n    {\n        WebRtc_Word16 left_shifts = -right_shifts;\n        for (i = length; i > 0; i--)\n        {\n            (*res++) = (WebRtc_Word16)((*in++) << left_shifts);\n        }\n    }\n}\n\nvoid WebRtcSpl_ScaleVector(G_CONST WebRtc_Word16 *in_vector, WebRtc_Word16 *out_vector,\n                           WebRtc_Word16 gain, WebRtc_Word16 in_vector_length,\n                           WebRtc_Word16 right_shifts)\n{\n    // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts\n    int i;\n    G_CONST WebRtc_Word16 *inptr;\n    WebRtc_Word16 *outptr;\n\n    inptr = in_vector;\n    outptr = out_vector;\n\n    for (i = 0; i < in_vector_length; i++)\n    {\n        (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts);\n    }\n}\n\nvoid WebRtcSpl_ScaleVectorWithSat(G_CONST WebRtc_Word16 *in_vector, WebRtc_Word16 *out_vector,\n                                 WebRtc_Word16 gain, WebRtc_Word16 in_vector_length,\n                                 WebRtc_Word16 right_shifts)\n{\n    // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts\n    int i;\n    WebRtc_Word32 tmpW32;\n    G_CONST WebRtc_Word16 *inptr;\n    WebRtc_Word16 *outptr;\n\n    inptr = in_vector;\n    outptr = out_vector;\n\n    for (i = 0; i < in_vector_length; i++)\n    {\n        tmpW32 = WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts);\n        ( *outptr++) = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, tmpW32, -32768);\n    }\n}\n\nvoid WebRtcSpl_ScaleAndAddVectors(G_CONST WebRtc_Word16 *in1, WebRtc_Word16 gain1, int shift1,\n                                  G_CONST WebRtc_Word16 *in2, WebRtc_Word16 gain2, int shift2,\n                                  WebRtc_Word16 *out, int vector_length)\n{\n    // Performs vector operation: out = (gain1*in1)>>shift1 + (gain2*in2)>>shift2\n    int i;\n    G_CONST WebRtc_Word16 *in1ptr;\n    G_CONST WebRtc_Word16 *in2ptr;\n    WebRtc_Word16 *outptr;\n\n    in1ptr = in1;\n    in2ptr = in2;\n    outptr = out;\n\n    for (i = 0; i < vector_length; i++)\n    {\n        (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gain1, *in1ptr++, shift1)\n                + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gain2, *in2ptr++, shift2);\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/webrtc_fft_t_1024_8.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the Q14 radix-8 tables used in ARM9e optimizations.\n *\n */\n\nextern const int s_Q14S_8;\nconst int s_Q14S_8 = 1024;\nextern const unsigned short t_Q14S_8[2032];\nconst unsigned short t_Q14S_8[2032] = {\n  0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,\n  0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e ,\n  0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 ,\n  0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 ,\n  0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 ,\n  0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c ,\n  0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 ,\n  0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 ,\n  0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,\n  0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 ,\n  0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 ,\n  0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d ,\n  0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e ,\n  0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb ,\n  0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 ,\n  0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 ,\n  0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 ,\n  0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 ,\n  0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 ,\n  0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec ,\n  0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 ,\n  0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 ,\n  0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 ,\n  0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 ,\n  0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 ,\n  0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 ,\n  0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b ,\n  0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 ,\n  0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c ,\n  0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 ,\n  0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba ,\n  0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 ,\n  0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 ,\n  0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 ,\n  0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 ,\n  0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 ,\n  0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 ,\n  0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 ,\n  0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 ,\n  0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 ,\n  0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,\n  0x3e69,0x0192 ,0x3f36,0x00c9 ,0x3d9a,0x025b ,\n  0x3cc8,0x0324 ,0x3e69,0x0192 ,0x3b1e,0x04b5 ,\n  0x3b1e,0x04b5 ,0x3d9a,0x025b ,0x388e,0x070e ,\n  0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 ,\n  0x37af,0x07d6 ,0x3bf4,0x03ed ,0x3334,0x0bb7 ,\n  0x35eb,0x0964 ,0x3b1e,0x04b5 ,0x306c,0x0e06 ,\n  0x341e,0x0af1 ,0x3a46,0x057e ,0x2d93,0x1050 ,\n  0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 ,\n  0x306c,0x0e06 ,0x388e,0x070e ,0x27b3,0x14d2 ,\n  0x2e88,0x0f8d ,0x37af,0x07d6 ,0x24ae,0x1709 ,\n  0x2c9d,0x1112 ,0x36ce,0x089d ,0x219c,0x1937 ,\n  0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d ,\n  0x28b2,0x1413 ,0x3505,0x0a2b ,0x1b56,0x1d79 ,\n  0x26b3,0x1590 ,0x341e,0x0af1 ,0x1824,0x1f8c ,\n  0x24ae,0x1709 ,0x3334,0x0bb7 ,0x14ea,0x2193 ,\n  0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e ,\n  0x2093,0x19ef ,0x315b,0x0d41 ,0x0e61,0x257e ,\n  0x1e7e,0x1b5d ,0x306c,0x0e06 ,0x0b14,0x2760 ,\n  0x1c64,0x1cc6 ,0x2f7b,0x0eca ,0x07c4,0x2935 ,\n  0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb ,\n  0x1824,0x1f8c ,0x2d93,0x1050 ,0x011c,0x2cb2 ,\n  0x15fe,0x20e7 ,0x2c9d,0x1112 ,0xfdc7,0x2e5a ,\n  0x13d5,0x223d ,0x2ba4,0x11d3 ,0xfa73,0x2ff2 ,\n  0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 ,\n  0x0f79,0x24da ,0x29af,0x1354 ,0xf3d2,0x32ef ,\n  0x0d48,0x2620 ,0x28b2,0x1413 ,0xf087,0x3453 ,\n  0x0b14,0x2760 ,0x27b3,0x14d2 ,0xed41,0x35a5 ,\n  0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 ,\n  0x06a9,0x29ce ,0x25b1,0x164c ,0xe6cb,0x3812 ,\n  0x0471,0x2afb ,0x24ae,0x1709 ,0xe39c,0x392b ,\n  0x0239,0x2c21 ,0x23a9,0x17c4 ,0xe077,0x3a30 ,\n  0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 ,\n  0xfdc7,0x2e5a ,0x219c,0x1937 ,0xda4f,0x3bfd ,\n  0xfb8f,0x2f6c ,0x2093,0x19ef ,0xd74e,0x3cc5 ,\n  0xf957,0x3076 ,0x1f89,0x1aa7 ,0xd45c,0x3d78 ,\n  0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 ,\n  0xf4ec,0x3274 ,0x1d72,0x1c12 ,0xcea5,0x3e9d ,\n  0xf2b8,0x3368 ,0x1c64,0x1cc6 ,0xcbe2,0x3f0f ,\n  0xf087,0x3453 ,0x1b56,0x1d79 ,0xc932,0x3f6b ,\n  0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 ,\n  0xec2b,0x3612 ,0x1935,0x1edc ,0xc40c,0x3fe1 ,\n  0xea02,0x36e5 ,0x1824,0x1f8c ,0xc197,0x3ffb ,\n  0xe7dc,0x37b0 ,0x1711,0x203a ,0xbf38,0x3fff ,\n  0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec ,\n  0xe39c,0x392b ,0x14ea,0x2193 ,0xbabf,0x3fc4 ,\n  0xe182,0x39db ,0x13d5,0x223d ,0xb8a6,0x3f85 ,\n  0xdf6d,0x3a82 ,0x12bf,0x22e7 ,0xb6a5,0x3f30 ,\n  0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 ,\n  0xdb52,0x3bb6 ,0x1091,0x2435 ,0xb2f2,0x3e45 ,\n  0xd94d,0x3c42 ,0x0f79,0x24da ,0xb140,0x3daf ,\n  0xd74e,0x3cc5 ,0x0e61,0x257e ,0xafa9,0x3d03 ,\n  0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 ,\n  0xd363,0x3daf ,0x0c2e,0x26c1 ,0xacd0,0x3b6d ,\n  0xd178,0x3e15 ,0x0b14,0x2760 ,0xab8e,0x3a82 ,\n  0xcf94,0x3e72 ,0x09fa,0x27fe ,0xaa6a,0x3984 ,\n  0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 ,\n  0xcbe2,0x3f0f ,0x07c4,0x2935 ,0xa87b,0x374b ,\n  0xca15,0x3f4f ,0x06a9,0x29ce ,0xa7b1,0x3612 ,\n  0xc851,0x3f85 ,0x058d,0x2a65 ,0xa705,0x34c6 ,\n  0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 ,\n  0xc4e2,0x3fd4 ,0x0355,0x2b8f ,0xa60b,0x31f8 ,\n  0xc338,0x3fec ,0x0239,0x2c21 ,0xa5bc,0x3076 ,\n  0xc197,0x3ffb ,0x011c,0x2cb2 ,0xa58d,0x2ee4 ,\n  0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 ,\n  0xbe73,0x3ffb ,0xfee4,0x2dcf ,0xa58d,0x2b8f ,\n  0xbcf0,0x3fec ,0xfdc7,0x2e5a ,0xa5bc,0x29ce ,\n  0xbb77,0x3fd4 ,0xfcab,0x2ee4 ,0xa60b,0x27fe ,\n  0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 ,\n  0xb8a6,0x3f85 ,0xfa73,0x2ff2 ,0xa705,0x2435 ,\n  0xb74d,0x3f4f ,0xf957,0x3076 ,0xa7b1,0x223d ,\n  0xb600,0x3f0f ,0xf83c,0x30f9 ,0xa87b,0x203a ,\n  0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b ,\n  0xb388,0x3e72 ,0xf606,0x31f8 ,0xaa6a,0x1c12 ,\n  0xb25e,0x3e15 ,0xf4ec,0x3274 ,0xab8e,0x19ef ,\n  0xb140,0x3daf ,0xf3d2,0x32ef ,0xacd0,0x17c4 ,\n  0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 ,\n  0xaf28,0x3cc5 ,0xf19f,0x33df ,0xafa9,0x1354 ,\n  0xae2e,0x3c42 ,0xf087,0x3453 ,0xb140,0x1112 ,\n  0xad41,0x3bb6 ,0xef6f,0x34c6 ,0xb2f2,0x0eca ,\n  0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c ,\n  0xab8e,0x3a82 ,0xed41,0x35a5 ,0xb6a5,0x0a2b ,\n  0xaac8,0x39db ,0xec2b,0x3612 ,0xb8a6,0x07d6 ,\n  0xaa0f,0x392b ,0xeb16,0x367d ,0xbabf,0x057e ,\n  0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 ,\n  0xa8c5,0x37b0 ,0xe8ef,0x374b ,0xbf38,0x00c9 ,\n  0xa834,0x36e5 ,0xe7dc,0x37b0 ,0xc197,0xfe6e ,\n  0xa7b1,0x3612 ,0xe6cb,0x3812 ,0xc40c,0xfc13 ,\n  0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba ,\n  0xa6d3,0x3453 ,0xe4aa,0x38cf ,0xc932,0xf763 ,\n  0xa678,0x3368 ,0xe39c,0x392b ,0xcbe2,0xf50f ,\n  0xa62c,0x3274 ,0xe28e,0x3984 ,0xcea5,0xf2bf ,\n  0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 ,\n  0xa5bc,0x3076 ,0xe077,0x3a30 ,0xd45c,0xee2d ,\n  0xa599,0x2f6c ,0xdf6d,0x3a82 ,0xd74e,0xebed ,\n  0xa585,0x2e5a ,0xde64,0x3ad3 ,0xda4f,0xe9b4 ,\n  0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 ,\n  0xa585,0x2c21 ,0xdc57,0x3b6d ,0xe077,0xe559 ,\n  0xa599,0x2afb ,0xdb52,0x3bb6 ,0xe39c,0xe33a ,\n  0xa5bc,0x29ce ,0xda4f,0x3bfd ,0xe6cb,0xe124 ,\n  0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 ,\n  0xa62c,0x2760 ,0xd84d,0x3c85 ,0xed41,0xdd19 ,\n  0xa678,0x2620 ,0xd74e,0x3cc5 ,0xf087,0xdb26 ,\n  0xa6d3,0x24da ,0xd651,0x3d03 ,0xf3d2,0xd93f ,\n  0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 ,\n  0xa7b1,0x223d ,0xd45c,0x3d78 ,0xfa73,0xd59b ,\n  0xa834,0x20e7 ,0xd363,0x3daf ,0xfdc7,0xd3df ,\n  0xa8c5,0x1f8c ,0xd26d,0x3de3 ,0x011c,0xd231 ,\n  0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 ,\n  0xaa0f,0x1cc6 ,0xd085,0x3e45 ,0x07c4,0xcf07 ,\n  0xaac8,0x1b5d ,0xcf94,0x3e72 ,0x0b14,0xcd8c ,\n  0xab8e,0x19ef ,0xcea5,0x3e9d ,0x0e61,0xcc21 ,\n  0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 ,\n  0xad41,0x1709 ,0xcccc,0x3eeb ,0x14ea,0xc983 ,\n  0xae2e,0x1590 ,0xcbe2,0x3f0f ,0x1824,0xc850 ,\n  0xaf28,0x1413 ,0xcafb,0x3f30 ,0x1b56,0xc731 ,\n  0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 ,\n  0xb140,0x1112 ,0xc932,0x3f6b ,0x219c,0xc52d ,\n  0xb25e,0x0f8d ,0xc851,0x3f85 ,0x24ae,0xc44a ,\n  0xb388,0x0e06 ,0xc772,0x3f9c ,0x27b3,0xc37b ,\n  0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 ,\n  0xb600,0x0af1 ,0xc5ba,0x3fc4 ,0x2d93,0xc21d ,\n  0xb74d,0x0964 ,0xc4e2,0x3fd4 ,0x306c,0xc18e ,\n  0xb8a6,0x07d6 ,0xc40c,0x3fe1 ,0x3334,0xc115 ,\n  0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 ,\n  0xbb77,0x04b5 ,0xc266,0x3ff5 ,0x388e,0xc064 ,\n  0xbcf0,0x0324 ,0xc197,0x3ffb ,0x3b1e,0xc02c ,\n  0xbe73,0x0192 ,0xc0ca,0x3fff ,0x3d9a,0xc00b ,\n  0x4000,0x0000 ,0x3f9b,0x0065 ,0x3f36,0x00c9 ,\n  0x3ed0,0x012e ,0x3e69,0x0192 ,0x3e02,0x01f7 ,\n  0x3d9a,0x025b ,0x3d31,0x02c0 ,0x3cc8,0x0324 ,\n  0x3c5f,0x0388 ,0x3bf4,0x03ed ,0x3b8a,0x0451 ,\n  0x3b1e,0x04b5 ,0x3ab2,0x051a ,0x3a46,0x057e ,\n  0x39d9,0x05e2 ,0x396b,0x0646 ,0x38fd,0x06aa ,\n  0x388e,0x070e ,0x381f,0x0772 ,0x37af,0x07d6 ,\n  0x373f,0x0839 ,0x36ce,0x089d ,0x365d,0x0901 ,\n  0x35eb,0x0964 ,0x3578,0x09c7 ,0x3505,0x0a2b ,\n  0x3492,0x0a8e ,0x341e,0x0af1 ,0x33a9,0x0b54 ,\n  0x3334,0x0bb7 ,0x32bf,0x0c1a ,0x3249,0x0c7c ,\n  0x31d2,0x0cdf ,0x315b,0x0d41 ,0x30e4,0x0da4 ,\n  0x306c,0x0e06 ,0x2ff4,0x0e68 ,0x2f7b,0x0eca ,\n  0x2f02,0x0f2b ,0x2e88,0x0f8d ,0x2e0e,0x0fee ,\n  0x2d93,0x1050 ,0x2d18,0x10b1 ,0x2c9d,0x1112 ,\n  0x2c21,0x1173 ,0x2ba4,0x11d3 ,0x2b28,0x1234 ,\n  0x2aaa,0x1294 ,0x2a2d,0x12f4 ,0x29af,0x1354 ,\n  0x2931,0x13b4 ,0x28b2,0x1413 ,0x2833,0x1473 ,\n  0x27b3,0x14d2 ,0x2733,0x1531 ,0x26b3,0x1590 ,\n  0x2632,0x15ee ,0x25b1,0x164c ,0x252f,0x16ab ,\n  0x24ae,0x1709 ,0x242b,0x1766 ,0x23a9,0x17c4 ,\n  0x2326,0x1821 ,0x22a3,0x187e ,0x221f,0x18db ,\n  0x219c,0x1937 ,0x2117,0x1993 ,0x2093,0x19ef ,\n  0x200e,0x1a4b ,0x1f89,0x1aa7 ,0x1f04,0x1b02 ,\n  0x1e7e,0x1b5d ,0x1df8,0x1bb8 ,0x1d72,0x1c12 ,\n  0x1ceb,0x1c6c ,0x1c64,0x1cc6 ,0x1bdd,0x1d20 ,\n  0x1b56,0x1d79 ,0x1ace,0x1dd3 ,0x1a46,0x1e2b ,\n  0x19be,0x1e84 ,0x1935,0x1edc ,0x18ad,0x1f34 ,\n  0x1824,0x1f8c ,0x179b,0x1fe3 ,0x1711,0x203a ,\n  0x1688,0x2091 ,0x15fe,0x20e7 ,0x1574,0x213d ,\n  0x14ea,0x2193 ,0x145f,0x21e8 ,0x13d5,0x223d ,\n  0x134a,0x2292 ,0x12bf,0x22e7 ,0x1234,0x233b ,\n  0x11a8,0x238e ,0x111d,0x23e2 ,0x1091,0x2435 ,\n  0x1005,0x2488 ,0x0f79,0x24da ,0x0eed,0x252c ,\n  0x0e61,0x257e ,0x0dd4,0x25cf ,0x0d48,0x2620 ,\n  0x0cbb,0x2671 ,0x0c2e,0x26c1 ,0x0ba1,0x2711 ,\n  0x0b14,0x2760 ,0x0a87,0x27af ,0x09fa,0x27fe ,\n  0x096d,0x284c ,0x08df,0x289a ,0x0852,0x28e7 ,\n  0x07c4,0x2935 ,0x0736,0x2981 ,0x06a9,0x29ce ,\n  0x061b,0x2a1a ,0x058d,0x2a65 ,0x04ff,0x2ab0 ,\n  0x0471,0x2afb ,0x03e3,0x2b45 ,0x0355,0x2b8f ,\n  0x02c7,0x2bd8 ,0x0239,0x2c21 ,0x01aa,0x2c6a ,\n  0x011c,0x2cb2 ,0x008e,0x2cfa ,0x0000,0x2d41 ,\n  0xff72,0x2d88 ,0xfee4,0x2dcf ,0xfe56,0x2e15 ,\n  0xfdc7,0x2e5a ,0xfd39,0x2e9f ,0xfcab,0x2ee4 ,\n  0xfc1d,0x2f28 ,0xfb8f,0x2f6c ,0xfb01,0x2faf ,\n  0xfa73,0x2ff2 ,0xf9e5,0x3034 ,0xf957,0x3076 ,\n  0xf8ca,0x30b8 ,0xf83c,0x30f9 ,0xf7ae,0x3139 ,\n  0xf721,0x3179 ,0xf693,0x31b9 ,0xf606,0x31f8 ,\n  0xf579,0x3236 ,0xf4ec,0x3274 ,0xf45f,0x32b2 ,\n  0xf3d2,0x32ef ,0xf345,0x332c ,0xf2b8,0x3368 ,\n  0xf22c,0x33a3 ,0xf19f,0x33df ,0xf113,0x3419 ,\n  0xf087,0x3453 ,0xeffb,0x348d ,0xef6f,0x34c6 ,\n  0xeee3,0x34ff ,0xee58,0x3537 ,0xedcc,0x356e ,\n  0xed41,0x35a5 ,0xecb6,0x35dc ,0xec2b,0x3612 ,\n  0xeba1,0x3648 ,0xeb16,0x367d ,0xea8c,0x36b1 ,\n  0xea02,0x36e5 ,0xe978,0x3718 ,0xe8ef,0x374b ,\n  0xe865,0x377e ,0xe7dc,0x37b0 ,0xe753,0x37e1 ,\n  0xe6cb,0x3812 ,0xe642,0x3842 ,0xe5ba,0x3871 ,\n  0xe532,0x38a1 ,0xe4aa,0x38cf ,0xe423,0x38fd ,\n  0xe39c,0x392b ,0xe315,0x3958 ,0xe28e,0x3984 ,\n  0xe208,0x39b0 ,0xe182,0x39db ,0xe0fc,0x3a06 ,\n  0xe077,0x3a30 ,0xdff2,0x3a59 ,0xdf6d,0x3a82 ,\n  0xdee9,0x3aab ,0xde64,0x3ad3 ,0xdde1,0x3afa ,\n  0xdd5d,0x3b21 ,0xdcda,0x3b47 ,0xdc57,0x3b6d ,\n  0xdbd5,0x3b92 ,0xdb52,0x3bb6 ,0xdad1,0x3bda ,\n  0xda4f,0x3bfd ,0xd9ce,0x3c20 ,0xd94d,0x3c42 ,\n  0xd8cd,0x3c64 ,0xd84d,0x3c85 ,0xd7cd,0x3ca5 ,\n  0xd74e,0x3cc5 ,0xd6cf,0x3ce4 ,0xd651,0x3d03 ,\n  0xd5d3,0x3d21 ,0xd556,0x3d3f ,0xd4d8,0x3d5b ,\n  0xd45c,0x3d78 ,0xd3df,0x3d93 ,0xd363,0x3daf ,\n  0xd2e8,0x3dc9 ,0xd26d,0x3de3 ,0xd1f2,0x3dfc ,\n  0xd178,0x3e15 ,0xd0fe,0x3e2d ,0xd085,0x3e45 ,\n  0xd00c,0x3e5c ,0xcf94,0x3e72 ,0xcf1c,0x3e88 ,\n  0xcea5,0x3e9d ,0xce2e,0x3eb1 ,0xcdb7,0x3ec5 ,\n  0xcd41,0x3ed8 ,0xcccc,0x3eeb ,0xcc57,0x3efd ,\n  0xcbe2,0x3f0f ,0xcb6e,0x3f20 ,0xcafb,0x3f30 ,\n  0xca88,0x3f40 ,0xca15,0x3f4f ,0xc9a3,0x3f5d ,\n  0xc932,0x3f6b ,0xc8c1,0x3f78 ,0xc851,0x3f85 ,\n  0xc7e1,0x3f91 ,0xc772,0x3f9c ,0xc703,0x3fa7 ,\n  0xc695,0x3fb1 ,0xc627,0x3fbb ,0xc5ba,0x3fc4 ,\n  0xc54e,0x3fcc ,0xc4e2,0x3fd4 ,0xc476,0x3fdb ,\n  0xc40c,0x3fe1 ,0xc3a1,0x3fe7 ,0xc338,0x3fec ,\n  0xc2cf,0x3ff1 ,0xc266,0x3ff5 ,0xc1fe,0x3ff8 ,\n  0xc197,0x3ffb ,0xc130,0x3ffd ,0xc0ca,0x3fff ,\n  0xc065,0x4000 ,0xc000,0x4000 ,0xbf9c,0x4000 ,\n  0xbf38,0x3fff ,0xbed5,0x3ffd ,0xbe73,0x3ffb ,\n  0xbe11,0x3ff8 ,0xbdb0,0x3ff5 ,0xbd50,0x3ff1 ,\n  0xbcf0,0x3fec ,0xbc91,0x3fe7 ,0xbc32,0x3fe1 ,\n  0xbbd4,0x3fdb ,0xbb77,0x3fd4 ,0xbb1b,0x3fcc ,\n  0xbabf,0x3fc4 ,0xba64,0x3fbb ,0xba09,0x3fb1 ,\n  0xb9af,0x3fa7 ,0xb956,0x3f9c ,0xb8fd,0x3f91 ,\n  0xb8a6,0x3f85 ,0xb84f,0x3f78 ,0xb7f8,0x3f6b ,\n  0xb7a2,0x3f5d ,0xb74d,0x3f4f ,0xb6f9,0x3f40 ,\n  0xb6a5,0x3f30 ,0xb652,0x3f20 ,0xb600,0x3f0f ,\n  0xb5af,0x3efd ,0xb55e,0x3eeb ,0xb50e,0x3ed8 ,\n  0xb4be,0x3ec5 ,0xb470,0x3eb1 ,0xb422,0x3e9d ,\n  0xb3d5,0x3e88 ,0xb388,0x3e72 ,0xb33d,0x3e5c ,\n  0xb2f2,0x3e45 ,0xb2a7,0x3e2d ,0xb25e,0x3e15 ,\n  0xb215,0x3dfc ,0xb1cd,0x3de3 ,0xb186,0x3dc9 ,\n  0xb140,0x3daf ,0xb0fa,0x3d93 ,0xb0b5,0x3d78 ,\n  0xb071,0x3d5b ,0xb02d,0x3d3f ,0xafeb,0x3d21 ,\n  0xafa9,0x3d03 ,0xaf68,0x3ce4 ,0xaf28,0x3cc5 ,\n  0xaee8,0x3ca5 ,0xaea9,0x3c85 ,0xae6b,0x3c64 ,\n  0xae2e,0x3c42 ,0xadf2,0x3c20 ,0xadb6,0x3bfd ,\n  0xad7b,0x3bda ,0xad41,0x3bb6 ,0xad08,0x3b92 ,\n  0xacd0,0x3b6d ,0xac98,0x3b47 ,0xac61,0x3b21 ,\n  0xac2b,0x3afa ,0xabf6,0x3ad3 ,0xabc2,0x3aab ,\n  0xab8e,0x3a82 ,0xab5b,0x3a59 ,0xab29,0x3a30 ,\n  0xaaf8,0x3a06 ,0xaac8,0x39db ,0xaa98,0x39b0 ,\n  0xaa6a,0x3984 ,0xaa3c,0x3958 ,0xaa0f,0x392b ,\n  0xa9e3,0x38fd ,0xa9b7,0x38cf ,0xa98d,0x38a1 ,\n  0xa963,0x3871 ,0xa93a,0x3842 ,0xa912,0x3812 ,\n  0xa8eb,0x37e1 ,0xa8c5,0x37b0 ,0xa89f,0x377e ,\n  0xa87b,0x374b ,0xa857,0x3718 ,0xa834,0x36e5 ,\n  0xa812,0x36b1 ,0xa7f1,0x367d ,0xa7d0,0x3648 ,\n  0xa7b1,0x3612 ,0xa792,0x35dc ,0xa774,0x35a5 ,\n  0xa757,0x356e ,0xa73b,0x3537 ,0xa71f,0x34ff ,\n  0xa705,0x34c6 ,0xa6eb,0x348d ,0xa6d3,0x3453 ,\n  0xa6bb,0x3419 ,0xa6a4,0x33df ,0xa68e,0x33a3 ,\n  0xa678,0x3368 ,0xa664,0x332c ,0xa650,0x32ef ,\n  0xa63e,0x32b2 ,0xa62c,0x3274 ,0xa61b,0x3236 ,\n  0xa60b,0x31f8 ,0xa5fb,0x31b9 ,0xa5ed,0x3179 ,\n  0xa5e0,0x3139 ,0xa5d3,0x30f9 ,0xa5c7,0x30b8 ,\n  0xa5bc,0x3076 ,0xa5b2,0x3034 ,0xa5a9,0x2ff2 ,\n  0xa5a1,0x2faf ,0xa599,0x2f6c ,0xa593,0x2f28 ,\n  0xa58d,0x2ee4 ,0xa588,0x2e9f ,0xa585,0x2e5a ,\n  0xa581,0x2e15 ,0xa57f,0x2dcf ,0xa57e,0x2d88 ,\n  0xa57e,0x2d41 ,0xa57e,0x2cfa ,0xa57f,0x2cb2 ,\n  0xa581,0x2c6a ,0xa585,0x2c21 ,0xa588,0x2bd8 ,\n  0xa58d,0x2b8f ,0xa593,0x2b45 ,0xa599,0x2afb ,\n  0xa5a1,0x2ab0 ,0xa5a9,0x2a65 ,0xa5b2,0x2a1a ,\n  0xa5bc,0x29ce ,0xa5c7,0x2981 ,0xa5d3,0x2935 ,\n  0xa5e0,0x28e7 ,0xa5ed,0x289a ,0xa5fb,0x284c ,\n  0xa60b,0x27fe ,0xa61b,0x27af ,0xa62c,0x2760 ,\n  0xa63e,0x2711 ,0xa650,0x26c1 ,0xa664,0x2671 ,\n  0xa678,0x2620 ,0xa68e,0x25cf ,0xa6a4,0x257e ,\n  0xa6bb,0x252c ,0xa6d3,0x24da ,0xa6eb,0x2488 ,\n  0xa705,0x2435 ,0xa71f,0x23e2 ,0xa73b,0x238e ,\n  0xa757,0x233b ,0xa774,0x22e7 ,0xa792,0x2292 ,\n  0xa7b1,0x223d ,0xa7d0,0x21e8 ,0xa7f1,0x2193 ,\n  0xa812,0x213d ,0xa834,0x20e7 ,0xa857,0x2091 ,\n  0xa87b,0x203a ,0xa89f,0x1fe3 ,0xa8c5,0x1f8c ,\n  0xa8eb,0x1f34 ,0xa912,0x1edc ,0xa93a,0x1e84 ,\n  0xa963,0x1e2b ,0xa98d,0x1dd3 ,0xa9b7,0x1d79 ,\n  0xa9e3,0x1d20 ,0xaa0f,0x1cc6 ,0xaa3c,0x1c6c ,\n  0xaa6a,0x1c12 ,0xaa98,0x1bb8 ,0xaac8,0x1b5d ,\n  0xaaf8,0x1b02 ,0xab29,0x1aa7 ,0xab5b,0x1a4b ,\n  0xab8e,0x19ef ,0xabc2,0x1993 ,0xabf6,0x1937 ,\n  0xac2b,0x18db ,0xac61,0x187e ,0xac98,0x1821 ,\n  0xacd0,0x17c4 ,0xad08,0x1766 ,0xad41,0x1709 ,\n  0xad7b,0x16ab ,0xadb6,0x164c ,0xadf2,0x15ee ,\n  0xae2e,0x1590 ,0xae6b,0x1531 ,0xaea9,0x14d2 ,\n  0xaee8,0x1473 ,0xaf28,0x1413 ,0xaf68,0x13b4 ,\n  0xafa9,0x1354 ,0xafeb,0x12f4 ,0xb02d,0x1294 ,\n  0xb071,0x1234 ,0xb0b5,0x11d3 ,0xb0fa,0x1173 ,\n  0xb140,0x1112 ,0xb186,0x10b1 ,0xb1cd,0x1050 ,\n  0xb215,0x0fee ,0xb25e,0x0f8d ,0xb2a7,0x0f2b ,\n  0xb2f2,0x0eca ,0xb33d,0x0e68 ,0xb388,0x0e06 ,\n  0xb3d5,0x0da4 ,0xb422,0x0d41 ,0xb470,0x0cdf ,\n  0xb4be,0x0c7c ,0xb50e,0x0c1a ,0xb55e,0x0bb7 ,\n  0xb5af,0x0b54 ,0xb600,0x0af1 ,0xb652,0x0a8e ,\n  0xb6a5,0x0a2b ,0xb6f9,0x09c7 ,0xb74d,0x0964 ,\n  0xb7a2,0x0901 ,0xb7f8,0x089d ,0xb84f,0x0839 ,\n  0xb8a6,0x07d6 ,0xb8fd,0x0772 ,0xb956,0x070e ,\n  0xb9af,0x06aa ,0xba09,0x0646 ,0xba64,0x05e2 ,\n  0xbabf,0x057e ,0xbb1b,0x051a ,0xbb77,0x04b5 ,\n  0xbbd4,0x0451 ,0xbc32,0x03ed ,0xbc91,0x0388 ,\n  0xbcf0,0x0324 ,0xbd50,0x02c0 ,0xbdb0,0x025b ,\n  0xbe11,0x01f7 ,0xbe73,0x0192 ,0xbed5,0x012e ,\n  0xbf38,0x00c9 ,0xbf9c,0x0065 };\n\n\nextern const int s_Q14R_8;\nconst int s_Q14R_8 = 1024;\nextern const unsigned short t_Q14R_8[2032];\nconst unsigned short t_Q14R_8[2032] = {\n  0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,\n  0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e ,\n  0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 ,\n  0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 ,\n  0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 ,\n  0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c ,\n  0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 ,\n  0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 ,\n  0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,\n  0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 ,\n  0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 ,\n  0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d ,\n  0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e ,\n  0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb ,\n  0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 ,\n  0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 ,\n  0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 ,\n  0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 ,\n  0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 ,\n  0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec ,\n  0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 ,\n  0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 ,\n  0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 ,\n  0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 ,\n  0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 ,\n  0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 ,\n  0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b ,\n  0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 ,\n  0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c ,\n  0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 ,\n  0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba ,\n  0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 ,\n  0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 ,\n  0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 ,\n  0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 ,\n  0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 ,\n  0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 ,\n  0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 ,\n  0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 ,\n  0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 ,\n  0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,\n  0x3ffb,0x0192 ,0x3fff,0x00c9 ,0x3ff5,0x025b ,\n  0x3fec,0x0324 ,0x3ffb,0x0192 ,0x3fd4,0x04b5 ,\n  0x3fd4,0x04b5 ,0x3ff5,0x025b ,0x3f9c,0x070e ,\n  0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 ,\n  0x3f85,0x07d6 ,0x3fe1,0x03ed ,0x3eeb,0x0bb7 ,\n  0x3f4f,0x0964 ,0x3fd4,0x04b5 ,0x3e72,0x0e06 ,\n  0x3f0f,0x0af1 ,0x3fc4,0x057e ,0x3de3,0x1050 ,\n  0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 ,\n  0x3e72,0x0e06 ,0x3f9c,0x070e ,0x3c85,0x14d2 ,\n  0x3e15,0x0f8d ,0x3f85,0x07d6 ,0x3bb6,0x1709 ,\n  0x3daf,0x1112 ,0x3f6b,0x089d ,0x3ad3,0x1937 ,\n  0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d ,\n  0x3cc5,0x1413 ,0x3f30,0x0a2b ,0x38cf,0x1d79 ,\n  0x3c42,0x1590 ,0x3f0f,0x0af1 ,0x37b0,0x1f8c ,\n  0x3bb6,0x1709 ,0x3eeb,0x0bb7 ,0x367d,0x2193 ,\n  0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e ,\n  0x3a82,0x19ef ,0x3e9d,0x0d41 ,0x33df,0x257e ,\n  0x39db,0x1b5d ,0x3e72,0x0e06 ,0x3274,0x2760 ,\n  0x392b,0x1cc6 ,0x3e45,0x0eca ,0x30f9,0x2935 ,\n  0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb ,\n  0x37b0,0x1f8c ,0x3de3,0x1050 ,0x2dcf,0x2cb2 ,\n  0x36e5,0x20e7 ,0x3daf,0x1112 ,0x2c21,0x2e5a ,\n  0x3612,0x223d ,0x3d78,0x11d3 ,0x2a65,0x2ff2 ,\n  0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 ,\n  0x3453,0x24da ,0x3d03,0x1354 ,0x26c1,0x32ef ,\n  0x3368,0x2620 ,0x3cc5,0x1413 ,0x24da,0x3453 ,\n  0x3274,0x2760 ,0x3c85,0x14d2 ,0x22e7,0x35a5 ,\n  0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 ,\n  0x3076,0x29ce ,0x3bfd,0x164c ,0x1edc,0x3812 ,\n  0x2f6c,0x2afb ,0x3bb6,0x1709 ,0x1cc6,0x392b ,\n  0x2e5a,0x2c21 ,0x3b6d,0x17c4 ,0x1aa7,0x3a30 ,\n  0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 ,\n  0x2c21,0x2e5a ,0x3ad3,0x1937 ,0x164c,0x3bfd ,\n  0x2afb,0x2f6c ,0x3a82,0x19ef ,0x1413,0x3cc5 ,\n  0x29ce,0x3076 ,0x3a30,0x1aa7 ,0x11d3,0x3d78 ,\n  0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 ,\n  0x2760,0x3274 ,0x3984,0x1c12 ,0x0d41,0x3e9d ,\n  0x2620,0x3368 ,0x392b,0x1cc6 ,0x0af1,0x3f0f ,\n  0x24da,0x3453 ,0x38cf,0x1d79 ,0x089d,0x3f6b ,\n  0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 ,\n  0x223d,0x3612 ,0x3812,0x1edc ,0x03ed,0x3fe1 ,\n  0x20e7,0x36e5 ,0x37b0,0x1f8c ,0x0192,0x3ffb ,\n  0x1f8c,0x37b0 ,0x374b,0x203a ,0xff37,0x3fff ,\n  0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec ,\n  0x1cc6,0x392b ,0x367d,0x2193 ,0xfa82,0x3fc4 ,\n  0x1b5d,0x39db ,0x3612,0x223d ,0xf82a,0x3f85 ,\n  0x19ef,0x3a82 ,0x35a5,0x22e7 ,0xf5d5,0x3f30 ,\n  0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 ,\n  0x1709,0x3bb6 ,0x34c6,0x2435 ,0xf136,0x3e45 ,\n  0x1590,0x3c42 ,0x3453,0x24da ,0xeeee,0x3daf ,\n  0x1413,0x3cc5 ,0x33df,0x257e ,0xecac,0x3d03 ,\n  0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 ,\n  0x1112,0x3daf ,0x32ef,0x26c1 ,0xe83c,0x3b6d ,\n  0x0f8d,0x3e15 ,0x3274,0x2760 ,0xe611,0x3a82 ,\n  0x0e06,0x3e72 ,0x31f8,0x27fe ,0xe3ee,0x3984 ,\n  0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 ,\n  0x0af1,0x3f0f ,0x30f9,0x2935 ,0xdfc6,0x374b ,\n  0x0964,0x3f4f ,0x3076,0x29ce ,0xddc3,0x3612 ,\n  0x07d6,0x3f85 ,0x2ff2,0x2a65 ,0xdbcb,0x34c6 ,\n  0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 ,\n  0x04b5,0x3fd4 ,0x2ee4,0x2b8f ,0xd802,0x31f8 ,\n  0x0324,0x3fec ,0x2e5a,0x2c21 ,0xd632,0x3076 ,\n  0x0192,0x3ffb ,0x2dcf,0x2cb2 ,0xd471,0x2ee4 ,\n  0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 ,\n  0xfe6e,0x3ffb ,0x2cb2,0x2dcf ,0xd11c,0x2b8f ,\n  0xfcdc,0x3fec ,0x2c21,0x2e5a ,0xcf8a,0x29ce ,\n  0xfb4b,0x3fd4 ,0x2b8f,0x2ee4 ,0xce08,0x27fe ,\n  0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 ,\n  0xf82a,0x3f85 ,0x2a65,0x2ff2 ,0xcb3a,0x2435 ,\n  0xf69c,0x3f4f ,0x29ce,0x3076 ,0xc9ee,0x223d ,\n  0xf50f,0x3f0f ,0x2935,0x30f9 ,0xc8b5,0x203a ,\n  0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b ,\n  0xf1fa,0x3e72 ,0x27fe,0x31f8 ,0xc67c,0x1c12 ,\n  0xf073,0x3e15 ,0x2760,0x3274 ,0xc57e,0x19ef ,\n  0xeeee,0x3daf ,0x26c1,0x32ef ,0xc493,0x17c4 ,\n  0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 ,\n  0xebed,0x3cc5 ,0x257e,0x33df ,0xc2fd,0x1354 ,\n  0xea70,0x3c42 ,0x24da,0x3453 ,0xc251,0x1112 ,\n  0xe8f7,0x3bb6 ,0x2435,0x34c6 ,0xc1bb,0x0eca ,\n  0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c ,\n  0xe611,0x3a82 ,0x22e7,0x35a5 ,0xc0d0,0x0a2b ,\n  0xe4a3,0x39db ,0x223d,0x3612 ,0xc07b,0x07d6 ,\n  0xe33a,0x392b ,0x2193,0x367d ,0xc03c,0x057e ,\n  0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 ,\n  0xe074,0x37b0 ,0x203a,0x374b ,0xc001,0x00c9 ,\n  0xdf19,0x36e5 ,0x1f8c,0x37b0 ,0xc005,0xfe6e ,\n  0xddc3,0x3612 ,0x1edc,0x3812 ,0xc01f,0xfc13 ,\n  0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba ,\n  0xdb26,0x3453 ,0x1d79,0x38cf ,0xc095,0xf763 ,\n  0xd9e0,0x3368 ,0x1cc6,0x392b ,0xc0f1,0xf50f ,\n  0xd8a0,0x3274 ,0x1c12,0x3984 ,0xc163,0xf2bf ,\n  0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 ,\n  0xd632,0x3076 ,0x1aa7,0x3a30 ,0xc288,0xee2d ,\n  0xd505,0x2f6c ,0x19ef,0x3a82 ,0xc33b,0xebed ,\n  0xd3df,0x2e5a ,0x1937,0x3ad3 ,0xc403,0xe9b4 ,\n  0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 ,\n  0xd1a6,0x2c21 ,0x17c4,0x3b6d ,0xc5d0,0xe559 ,\n  0xd094,0x2afb ,0x1709,0x3bb6 ,0xc6d5,0xe33a ,\n  0xcf8a,0x29ce ,0x164c,0x3bfd ,0xc7ee,0xe124 ,\n  0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 ,\n  0xcd8c,0x2760 ,0x14d2,0x3c85 ,0xca5b,0xdd19 ,\n  0xcc98,0x2620 ,0x1413,0x3cc5 ,0xcbad,0xdb26 ,\n  0xcbad,0x24da ,0x1354,0x3d03 ,0xcd11,0xd93f ,\n  0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 ,\n  0xc9ee,0x223d ,0x11d3,0x3d78 ,0xd00e,0xd59b ,\n  0xc91b,0x20e7 ,0x1112,0x3daf ,0xd1a6,0xd3df ,\n  0xc850,0x1f8c ,0x1050,0x3de3 ,0xd34e,0xd231 ,\n  0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 ,\n  0xc6d5,0x1cc6 ,0x0eca,0x3e45 ,0xd6cb,0xcf07 ,\n  0xc625,0x1b5d ,0x0e06,0x3e72 ,0xd8a0,0xcd8c ,\n  0xc57e,0x19ef ,0x0d41,0x3e9d ,0xda82,0xcc21 ,\n  0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 ,\n  0xc44a,0x1709 ,0x0bb7,0x3eeb ,0xde6d,0xc983 ,\n  0xc3be,0x1590 ,0x0af1,0x3f0f ,0xe074,0xc850 ,\n  0xc33b,0x1413 ,0x0a2b,0x3f30 ,0xe287,0xc731 ,\n  0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 ,\n  0xc251,0x1112 ,0x089d,0x3f6b ,0xe6c9,0xc52d ,\n  0xc1eb,0x0f8d ,0x07d6,0x3f85 ,0xe8f7,0xc44a ,\n  0xc18e,0x0e06 ,0x070e,0x3f9c ,0xeb2e,0xc37b ,\n  0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 ,\n  0xc0f1,0x0af1 ,0x057e,0x3fc4 ,0xefb0,0xc21d ,\n  0xc0b1,0x0964 ,0x04b5,0x3fd4 ,0xf1fa,0xc18e ,\n  0xc07b,0x07d6 ,0x03ed,0x3fe1 ,0xf449,0xc115 ,\n  0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 ,\n  0xc02c,0x04b5 ,0x025b,0x3ff5 ,0xf8f2,0xc064 ,\n  0xc014,0x0324 ,0x0192,0x3ffb ,0xfb4b,0xc02c ,\n  0xc005,0x0192 ,0x00c9,0x3fff ,0xfda5,0xc00b ,\n  0x4000,0x0000 ,0x4000,0x0065 ,0x3fff,0x00c9 ,\n  0x3ffd,0x012e ,0x3ffb,0x0192 ,0x3ff8,0x01f7 ,\n  0x3ff5,0x025b ,0x3ff1,0x02c0 ,0x3fec,0x0324 ,\n  0x3fe7,0x0388 ,0x3fe1,0x03ed ,0x3fdb,0x0451 ,\n  0x3fd4,0x04b5 ,0x3fcc,0x051a ,0x3fc4,0x057e ,\n  0x3fbb,0x05e2 ,0x3fb1,0x0646 ,0x3fa7,0x06aa ,\n  0x3f9c,0x070e ,0x3f91,0x0772 ,0x3f85,0x07d6 ,\n  0x3f78,0x0839 ,0x3f6b,0x089d ,0x3f5d,0x0901 ,\n  0x3f4f,0x0964 ,0x3f40,0x09c7 ,0x3f30,0x0a2b ,\n  0x3f20,0x0a8e ,0x3f0f,0x0af1 ,0x3efd,0x0b54 ,\n  0x3eeb,0x0bb7 ,0x3ed8,0x0c1a ,0x3ec5,0x0c7c ,\n  0x3eb1,0x0cdf ,0x3e9d,0x0d41 ,0x3e88,0x0da4 ,\n  0x3e72,0x0e06 ,0x3e5c,0x0e68 ,0x3e45,0x0eca ,\n  0x3e2d,0x0f2b ,0x3e15,0x0f8d ,0x3dfc,0x0fee ,\n  0x3de3,0x1050 ,0x3dc9,0x10b1 ,0x3daf,0x1112 ,\n  0x3d93,0x1173 ,0x3d78,0x11d3 ,0x3d5b,0x1234 ,\n  0x3d3f,0x1294 ,0x3d21,0x12f4 ,0x3d03,0x1354 ,\n  0x3ce4,0x13b4 ,0x3cc5,0x1413 ,0x3ca5,0x1473 ,\n  0x3c85,0x14d2 ,0x3c64,0x1531 ,0x3c42,0x1590 ,\n  0x3c20,0x15ee ,0x3bfd,0x164c ,0x3bda,0x16ab ,\n  0x3bb6,0x1709 ,0x3b92,0x1766 ,0x3b6d,0x17c4 ,\n  0x3b47,0x1821 ,0x3b21,0x187e ,0x3afa,0x18db ,\n  0x3ad3,0x1937 ,0x3aab,0x1993 ,0x3a82,0x19ef ,\n  0x3a59,0x1a4b ,0x3a30,0x1aa7 ,0x3a06,0x1b02 ,\n  0x39db,0x1b5d ,0x39b0,0x1bb8 ,0x3984,0x1c12 ,\n  0x3958,0x1c6c ,0x392b,0x1cc6 ,0x38fd,0x1d20 ,\n  0x38cf,0x1d79 ,0x38a1,0x1dd3 ,0x3871,0x1e2b ,\n  0x3842,0x1e84 ,0x3812,0x1edc ,0x37e1,0x1f34 ,\n  0x37b0,0x1f8c ,0x377e,0x1fe3 ,0x374b,0x203a ,\n  0x3718,0x2091 ,0x36e5,0x20e7 ,0x36b1,0x213d ,\n  0x367d,0x2193 ,0x3648,0x21e8 ,0x3612,0x223d ,\n  0x35dc,0x2292 ,0x35a5,0x22e7 ,0x356e,0x233b ,\n  0x3537,0x238e ,0x34ff,0x23e2 ,0x34c6,0x2435 ,\n  0x348d,0x2488 ,0x3453,0x24da ,0x3419,0x252c ,\n  0x33df,0x257e ,0x33a3,0x25cf ,0x3368,0x2620 ,\n  0x332c,0x2671 ,0x32ef,0x26c1 ,0x32b2,0x2711 ,\n  0x3274,0x2760 ,0x3236,0x27af ,0x31f8,0x27fe ,\n  0x31b9,0x284c ,0x3179,0x289a ,0x3139,0x28e7 ,\n  0x30f9,0x2935 ,0x30b8,0x2981 ,0x3076,0x29ce ,\n  0x3034,0x2a1a ,0x2ff2,0x2a65 ,0x2faf,0x2ab0 ,\n  0x2f6c,0x2afb ,0x2f28,0x2b45 ,0x2ee4,0x2b8f ,\n  0x2e9f,0x2bd8 ,0x2e5a,0x2c21 ,0x2e15,0x2c6a ,\n  0x2dcf,0x2cb2 ,0x2d88,0x2cfa ,0x2d41,0x2d41 ,\n  0x2cfa,0x2d88 ,0x2cb2,0x2dcf ,0x2c6a,0x2e15 ,\n  0x2c21,0x2e5a ,0x2bd8,0x2e9f ,0x2b8f,0x2ee4 ,\n  0x2b45,0x2f28 ,0x2afb,0x2f6c ,0x2ab0,0x2faf ,\n  0x2a65,0x2ff2 ,0x2a1a,0x3034 ,0x29ce,0x3076 ,\n  0x2981,0x30b8 ,0x2935,0x30f9 ,0x28e7,0x3139 ,\n  0x289a,0x3179 ,0x284c,0x31b9 ,0x27fe,0x31f8 ,\n  0x27af,0x3236 ,0x2760,0x3274 ,0x2711,0x32b2 ,\n  0x26c1,0x32ef ,0x2671,0x332c ,0x2620,0x3368 ,\n  0x25cf,0x33a3 ,0x257e,0x33df ,0x252c,0x3419 ,\n  0x24da,0x3453 ,0x2488,0x348d ,0x2435,0x34c6 ,\n  0x23e2,0x34ff ,0x238e,0x3537 ,0x233b,0x356e ,\n  0x22e7,0x35a5 ,0x2292,0x35dc ,0x223d,0x3612 ,\n  0x21e8,0x3648 ,0x2193,0x367d ,0x213d,0x36b1 ,\n  0x20e7,0x36e5 ,0x2091,0x3718 ,0x203a,0x374b ,\n  0x1fe3,0x377e ,0x1f8c,0x37b0 ,0x1f34,0x37e1 ,\n  0x1edc,0x3812 ,0x1e84,0x3842 ,0x1e2b,0x3871 ,\n  0x1dd3,0x38a1 ,0x1d79,0x38cf ,0x1d20,0x38fd ,\n  0x1cc6,0x392b ,0x1c6c,0x3958 ,0x1c12,0x3984 ,\n  0x1bb8,0x39b0 ,0x1b5d,0x39db ,0x1b02,0x3a06 ,\n  0x1aa7,0x3a30 ,0x1a4b,0x3a59 ,0x19ef,0x3a82 ,\n  0x1993,0x3aab ,0x1937,0x3ad3 ,0x18db,0x3afa ,\n  0x187e,0x3b21 ,0x1821,0x3b47 ,0x17c4,0x3b6d ,\n  0x1766,0x3b92 ,0x1709,0x3bb6 ,0x16ab,0x3bda ,\n  0x164c,0x3bfd ,0x15ee,0x3c20 ,0x1590,0x3c42 ,\n  0x1531,0x3c64 ,0x14d2,0x3c85 ,0x1473,0x3ca5 ,\n  0x1413,0x3cc5 ,0x13b4,0x3ce4 ,0x1354,0x3d03 ,\n  0x12f4,0x3d21 ,0x1294,0x3d3f ,0x1234,0x3d5b ,\n  0x11d3,0x3d78 ,0x1173,0x3d93 ,0x1112,0x3daf ,\n  0x10b1,0x3dc9 ,0x1050,0x3de3 ,0x0fee,0x3dfc ,\n  0x0f8d,0x3e15 ,0x0f2b,0x3e2d ,0x0eca,0x3e45 ,\n  0x0e68,0x3e5c ,0x0e06,0x3e72 ,0x0da4,0x3e88 ,\n  0x0d41,0x3e9d ,0x0cdf,0x3eb1 ,0x0c7c,0x3ec5 ,\n  0x0c1a,0x3ed8 ,0x0bb7,0x3eeb ,0x0b54,0x3efd ,\n  0x0af1,0x3f0f ,0x0a8e,0x3f20 ,0x0a2b,0x3f30 ,\n  0x09c7,0x3f40 ,0x0964,0x3f4f ,0x0901,0x3f5d ,\n  0x089d,0x3f6b ,0x0839,0x3f78 ,0x07d6,0x3f85 ,\n  0x0772,0x3f91 ,0x070e,0x3f9c ,0x06aa,0x3fa7 ,\n  0x0646,0x3fb1 ,0x05e2,0x3fbb ,0x057e,0x3fc4 ,\n  0x051a,0x3fcc ,0x04b5,0x3fd4 ,0x0451,0x3fdb ,\n  0x03ed,0x3fe1 ,0x0388,0x3fe7 ,0x0324,0x3fec ,\n  0x02c0,0x3ff1 ,0x025b,0x3ff5 ,0x01f7,0x3ff8 ,\n  0x0192,0x3ffb ,0x012e,0x3ffd ,0x00c9,0x3fff ,\n  0x0065,0x4000 ,0x0000,0x4000 ,0xff9b,0x4000 ,\n  0xff37,0x3fff ,0xfed2,0x3ffd ,0xfe6e,0x3ffb ,\n  0xfe09,0x3ff8 ,0xfda5,0x3ff5 ,0xfd40,0x3ff1 ,\n  0xfcdc,0x3fec ,0xfc78,0x3fe7 ,0xfc13,0x3fe1 ,\n  0xfbaf,0x3fdb ,0xfb4b,0x3fd4 ,0xfae6,0x3fcc ,\n  0xfa82,0x3fc4 ,0xfa1e,0x3fbb ,0xf9ba,0x3fb1 ,\n  0xf956,0x3fa7 ,0xf8f2,0x3f9c ,0xf88e,0x3f91 ,\n  0xf82a,0x3f85 ,0xf7c7,0x3f78 ,0xf763,0x3f6b ,\n  0xf6ff,0x3f5d ,0xf69c,0x3f4f ,0xf639,0x3f40 ,\n  0xf5d5,0x3f30 ,0xf572,0x3f20 ,0xf50f,0x3f0f ,\n  0xf4ac,0x3efd ,0xf449,0x3eeb ,0xf3e6,0x3ed8 ,\n  0xf384,0x3ec5 ,0xf321,0x3eb1 ,0xf2bf,0x3e9d ,\n  0xf25c,0x3e88 ,0xf1fa,0x3e72 ,0xf198,0x3e5c ,\n  0xf136,0x3e45 ,0xf0d5,0x3e2d ,0xf073,0x3e15 ,\n  0xf012,0x3dfc ,0xefb0,0x3de3 ,0xef4f,0x3dc9 ,\n  0xeeee,0x3daf ,0xee8d,0x3d93 ,0xee2d,0x3d78 ,\n  0xedcc,0x3d5b ,0xed6c,0x3d3f ,0xed0c,0x3d21 ,\n  0xecac,0x3d03 ,0xec4c,0x3ce4 ,0xebed,0x3cc5 ,\n  0xeb8d,0x3ca5 ,0xeb2e,0x3c85 ,0xeacf,0x3c64 ,\n  0xea70,0x3c42 ,0xea12,0x3c20 ,0xe9b4,0x3bfd ,\n  0xe955,0x3bda ,0xe8f7,0x3bb6 ,0xe89a,0x3b92 ,\n  0xe83c,0x3b6d ,0xe7df,0x3b47 ,0xe782,0x3b21 ,\n  0xe725,0x3afa ,0xe6c9,0x3ad3 ,0xe66d,0x3aab ,\n  0xe611,0x3a82 ,0xe5b5,0x3a59 ,0xe559,0x3a30 ,\n  0xe4fe,0x3a06 ,0xe4a3,0x39db ,0xe448,0x39b0 ,\n  0xe3ee,0x3984 ,0xe394,0x3958 ,0xe33a,0x392b ,\n  0xe2e0,0x38fd ,0xe287,0x38cf ,0xe22d,0x38a1 ,\n  0xe1d5,0x3871 ,0xe17c,0x3842 ,0xe124,0x3812 ,\n  0xe0cc,0x37e1 ,0xe074,0x37b0 ,0xe01d,0x377e ,\n  0xdfc6,0x374b ,0xdf6f,0x3718 ,0xdf19,0x36e5 ,\n  0xdec3,0x36b1 ,0xde6d,0x367d ,0xde18,0x3648 ,\n  0xddc3,0x3612 ,0xdd6e,0x35dc ,0xdd19,0x35a5 ,\n  0xdcc5,0x356e ,0xdc72,0x3537 ,0xdc1e,0x34ff ,\n  0xdbcb,0x34c6 ,0xdb78,0x348d ,0xdb26,0x3453 ,\n  0xdad4,0x3419 ,0xda82,0x33df ,0xda31,0x33a3 ,\n  0xd9e0,0x3368 ,0xd98f,0x332c ,0xd93f,0x32ef ,\n  0xd8ef,0x32b2 ,0xd8a0,0x3274 ,0xd851,0x3236 ,\n  0xd802,0x31f8 ,0xd7b4,0x31b9 ,0xd766,0x3179 ,\n  0xd719,0x3139 ,0xd6cb,0x30f9 ,0xd67f,0x30b8 ,\n  0xd632,0x3076 ,0xd5e6,0x3034 ,0xd59b,0x2ff2 ,\n  0xd550,0x2faf ,0xd505,0x2f6c ,0xd4bb,0x2f28 ,\n  0xd471,0x2ee4 ,0xd428,0x2e9f ,0xd3df,0x2e5a ,\n  0xd396,0x2e15 ,0xd34e,0x2dcf ,0xd306,0x2d88 ,\n  0xd2bf,0x2d41 ,0xd278,0x2cfa ,0xd231,0x2cb2 ,\n  0xd1eb,0x2c6a ,0xd1a6,0x2c21 ,0xd161,0x2bd8 ,\n  0xd11c,0x2b8f ,0xd0d8,0x2b45 ,0xd094,0x2afb ,\n  0xd051,0x2ab0 ,0xd00e,0x2a65 ,0xcfcc,0x2a1a ,\n  0xcf8a,0x29ce ,0xcf48,0x2981 ,0xcf07,0x2935 ,\n  0xcec7,0x28e7 ,0xce87,0x289a ,0xce47,0x284c ,\n  0xce08,0x27fe ,0xcdca,0x27af ,0xcd8c,0x2760 ,\n  0xcd4e,0x2711 ,0xcd11,0x26c1 ,0xccd4,0x2671 ,\n  0xcc98,0x2620 ,0xcc5d,0x25cf ,0xcc21,0x257e ,\n  0xcbe7,0x252c ,0xcbad,0x24da ,0xcb73,0x2488 ,\n  0xcb3a,0x2435 ,0xcb01,0x23e2 ,0xcac9,0x238e ,\n  0xca92,0x233b ,0xca5b,0x22e7 ,0xca24,0x2292 ,\n  0xc9ee,0x223d ,0xc9b8,0x21e8 ,0xc983,0x2193 ,\n  0xc94f,0x213d ,0xc91b,0x20e7 ,0xc8e8,0x2091 ,\n  0xc8b5,0x203a ,0xc882,0x1fe3 ,0xc850,0x1f8c ,\n  0xc81f,0x1f34 ,0xc7ee,0x1edc ,0xc7be,0x1e84 ,\n  0xc78f,0x1e2b ,0xc75f,0x1dd3 ,0xc731,0x1d79 ,\n  0xc703,0x1d20 ,0xc6d5,0x1cc6 ,0xc6a8,0x1c6c ,\n  0xc67c,0x1c12 ,0xc650,0x1bb8 ,0xc625,0x1b5d ,\n  0xc5fa,0x1b02 ,0xc5d0,0x1aa7 ,0xc5a7,0x1a4b ,\n  0xc57e,0x19ef ,0xc555,0x1993 ,0xc52d,0x1937 ,\n  0xc506,0x18db ,0xc4df,0x187e ,0xc4b9,0x1821 ,\n  0xc493,0x17c4 ,0xc46e,0x1766 ,0xc44a,0x1709 ,\n  0xc426,0x16ab ,0xc403,0x164c ,0xc3e0,0x15ee ,\n  0xc3be,0x1590 ,0xc39c,0x1531 ,0xc37b,0x14d2 ,\n  0xc35b,0x1473 ,0xc33b,0x1413 ,0xc31c,0x13b4 ,\n  0xc2fd,0x1354 ,0xc2df,0x12f4 ,0xc2c1,0x1294 ,\n  0xc2a5,0x1234 ,0xc288,0x11d3 ,0xc26d,0x1173 ,\n  0xc251,0x1112 ,0xc237,0x10b1 ,0xc21d,0x1050 ,\n  0xc204,0x0fee ,0xc1eb,0x0f8d ,0xc1d3,0x0f2b ,\n  0xc1bb,0x0eca ,0xc1a4,0x0e68 ,0xc18e,0x0e06 ,\n  0xc178,0x0da4 ,0xc163,0x0d41 ,0xc14f,0x0cdf ,\n  0xc13b,0x0c7c ,0xc128,0x0c1a ,0xc115,0x0bb7 ,\n  0xc103,0x0b54 ,0xc0f1,0x0af1 ,0xc0e0,0x0a8e ,\n  0xc0d0,0x0a2b ,0xc0c0,0x09c7 ,0xc0b1,0x0964 ,\n  0xc0a3,0x0901 ,0xc095,0x089d ,0xc088,0x0839 ,\n  0xc07b,0x07d6 ,0xc06f,0x0772 ,0xc064,0x070e ,\n  0xc059,0x06aa ,0xc04f,0x0646 ,0xc045,0x05e2 ,\n  0xc03c,0x057e ,0xc034,0x051a ,0xc02c,0x04b5 ,\n  0xc025,0x0451 ,0xc01f,0x03ed ,0xc019,0x0388 ,\n  0xc014,0x0324 ,0xc00f,0x02c0 ,0xc00b,0x025b ,\n  0xc008,0x01f7 ,0xc005,0x0192 ,0xc003,0x012e ,\n  0xc001,0x00c9 ,0xc000,0x0065 };\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_audio/signal_processing_library/main/source/webrtc_fft_t_rad.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n\n/*\n * This file contains the Q14 radix-2 tables used in ARM9E optimization routines.\n *\n */\n\nextern const unsigned short t_Q14S_rad8[2];\nconst unsigned short t_Q14S_rad8[2] = {  0x0000,0x2d41 };\n\n//extern const int t_Q30S_rad8[2];\n//const int t_Q30S_rad8[2] = {  0x00000000,0x2d413ccd };\n\nextern const unsigned short t_Q14R_rad8[2];\nconst unsigned short t_Q14R_rad8[2] = {  0x2d41,0x2d41 };\n\n//extern const int t_Q30R_rad8[2];\n//const int t_Q30R_rad8[2] = {  0x2d413ccd,0x2d413ccd };\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/common_types.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_COMMON_TYPES_H\n#define WEBRTC_COMMON_TYPES_H\n\n#include \"typedefs.h\"\n\n#ifdef WEBRTC_EXPORT\n    #define WEBRTC_DLLEXPORT _declspec(dllexport)\n#elif WEBRTC_DLL\n    #define WEBRTC_DLLEXPORT _declspec(dllimport)\n#else\n    #define WEBRTC_DLLEXPORT\n#endif\n\n#ifndef NULL\n    #define NULL 0\n#endif\n\nnamespace webrtc {\n\nclass InStream\n{\npublic:\n    virtual int Read(void *buf,int len) = 0;\n    virtual int Rewind() {return -1;}\n    virtual ~InStream() {}\nprotected:\n    InStream() {}\n};\n\nclass OutStream\n{\npublic:\n    virtual bool Write(const void *buf,int len) = 0;\n    virtual int Rewind() {return -1;}\n    virtual ~OutStream() {}\nprotected:\n    OutStream() {}\n};\n\nenum TraceModule\n{\n    // not a module, triggered from the engine code\n    kTraceVoice              = 0x0001,\n    // not a module, triggered from the engine code\n    kTraceVideo              = 0x0002,\n    // not a module, triggered from the utility code\n    kTraceUtility            = 0x0003,\n    kTraceRtpRtcp            = 0x0004,\n    kTraceTransport          = 0x0005,\n    kTraceSrtp               = 0x0006,\n    kTraceAudioCoding        = 0x0007,\n    kTraceAudioMixerServer   = 0x0008,\n    kTraceAudioMixerClient   = 0x0009,\n    kTraceFile               = 0x000a,\n    kTraceAudioProcessing    = 0x000b,\n    kTraceVideoCoding        = 0x0010,\n    kTraceVideoMixer         = 0x0011,\n    kTraceAudioDevice        = 0x0012,\n    kTraceVideoRenderer      = 0x0014,\n    kTraceVideoCapture       = 0x0015,\n    kTraceVideoPreocessing   = 0x0016\n};\n\nenum TraceLevel\n{\n    kTraceNone               = 0x0000,    // no trace\n    kTraceStateInfo          = 0x0001,\n    kTraceWarning            = 0x0002,\n    kTraceError              = 0x0004,\n    kTraceCritical           = 0x0008,\n    kTraceApiCall            = 0x0010,\n    kTraceDefault            = 0x00ff,\n\n    kTraceModuleCall         = 0x0020,\n    kTraceMemory             = 0x0100,   // memory info\n    kTraceTimer              = 0x0200,   // timing info\n    kTraceStream             = 0x0400,   // \"continuous\" stream of data\n\n    // used for debug purposes\n    kTraceDebug              = 0x0800,  // debug\n    kTraceInfo               = 0x1000,  // debug info\n\n    kTraceAll                = 0xffff\n};\n\n// External Trace API\nclass TraceCallback\n{\npublic:\n    virtual void Print(const TraceLevel level,\n                       const char *traceString,\n                       const int length) = 0;\nprotected:\n    virtual ~TraceCallback() {}\n    TraceCallback() {}\n};\n\n\nenum FileFormats\n{\n    kFileFormatWavFile        = 1,\n    kFileFormatCompressedFile = 2,\n    kFileFormatAviFile        = 3,\n    kFileFormatPreencodedFile = 4,\n    kFileFormatPcm16kHzFile   = 7,\n    kFileFormatPcm8kHzFile    = 8,\n    kFileFormatPcm32kHzFile   = 9\n};\n\n\nenum ProcessingTypes\n{\n    kPlaybackPerChannel = 0,\n    kPlaybackAllChannelsMixed,\n    kRecordingPerChannel,\n    kRecordingAllChannelsMixed\n};\n\n// Encryption enums\nenum CipherTypes\n{\n    kCipherNull               = 0,\n    kCipherAes128CounterMode  = 1\n};\n\nenum AuthenticationTypes\n{\n    kAuthNull       = 0,\n    kAuthHmacSha1   = 3\n};\n\nenum SecurityLevels\n{\n    kNoProtection                    = 0,\n    kEncryption                      = 1,\n    kAuthentication                  = 2,\n    kEncryptionAndAuthentication     = 3\n};\n\nclass Encryption\n{\npublic:\n    virtual void encrypt(\n        int channel_no,\n        unsigned char* in_data,\n        unsigned char* out_data,\n        int bytes_in,\n        int* bytes_out) = 0;\n\n    virtual void decrypt(\n        int channel_no,\n        unsigned char* in_data,\n        unsigned char* out_data,\n        int bytes_in,\n        int* bytes_out) = 0;\n\n    virtual void encrypt_rtcp(\n        int channel_no,\n        unsigned char* in_data,\n        unsigned char* out_data,\n        int bytes_in,\n        int* bytes_out) = 0;\n\n    virtual void decrypt_rtcp(\n        int channel_no,\n        unsigned char* in_data,\n        unsigned char* out_data,\n        int bytes_in,\n        int* bytes_out) = 0;\n\nprotected:\n    virtual ~Encryption() {}\n    Encryption() {}\n};\n\n// External transport callback interface\nclass Transport\n{\npublic:\n    virtual int SendPacket(int channel, const void *data, int len) = 0;\n    virtual int SendRTCPPacket(int channel, const void *data, int len) = 0;\n\nprotected:\n    virtual ~Transport() {}\n    Transport() {}\n};\n\n// ==================================================================\n// Voice specific types\n// ==================================================================\n\n// Each codec supported can be described by this structure.\nstruct CodecInst\n{\n    int pltype;\n    char plname[32];\n    int plfreq;\n    int pacsize;\n    int channels;\n    int rate;\n};\n\nenum FrameType\n{\n    kFrameEmpty            = 0,\n    kAudioFrameSpeech      = 1,\n    kAudioFrameCN          = 2,\n    kVideoFrameKey         = 3,    // independent frame\n    kVideoFrameDelta       = 4,    // depends on the previus frame\n    kVideoFrameGolden      = 5,    // depends on a old known previus frame\n    kVideoFrameAltRef      = 6\n};\n\n// RTP\nenum {kRtpCsrcSize = 15}; // RFC 3550 page 13\n\nenum RTPDirections\n{\n    kRtpIncoming = 0,\n    kRtpOutgoing\n};\n\nenum PayloadFrequencies\n{\n    kFreq8000Hz = 8000,\n    kFreq16000Hz = 16000,\n    kFreq32000Hz = 32000\n};\n\nenum VadModes                 // degree of bandwidth reduction\n{\n    kVadConventional = 0,      // lowest reduction\n    kVadAggressiveLow,\n    kVadAggressiveMid,\n    kVadAggressiveHigh         // highest reduction\n};\n\nstruct NetworkStatistics           // NETEQ statistics\n{\n    // current jitter buffer size in ms\n    WebRtc_UWord16 currentBufferSize;\n    // preferred (optimal) buffer size in ms\n    WebRtc_UWord16 preferredBufferSize;\n    // loss rate (network + late) in percent (in Q14)\n    WebRtc_UWord16 currentPacketLossRate;\n    // late loss rate in percent (in Q14)\n    WebRtc_UWord16 currentDiscardRate;\n    // fraction (of original stream) of synthesized speech inserted through\n    // expansion (in Q14)\n    WebRtc_UWord16 currentExpandRate;\n    // fraction of synthesized speech inserted through pre-emptive expansion\n    // (in Q14)\n    WebRtc_UWord16 currentPreemptiveRate;\n    // fraction of data removed through acceleration (in Q14)\n    WebRtc_UWord16 currentAccelerateRate;\n};\n\nstruct JitterStatistics\n{\n    // smallest Jitter Buffer size during call in ms\n    WebRtc_UWord32 jbMinSize;\n    // largest Jitter Buffer size during call in ms\n    WebRtc_UWord32 jbMaxSize;\n    // the average JB size, measured over time - ms\n    WebRtc_UWord32 jbAvgSize;\n    // number of times the Jitter Buffer changed (using Accelerate or\n    // Pre-emptive Expand)\n    WebRtc_UWord32 jbChangeCount;\n    // amount (in ms) of audio data received late\n    WebRtc_UWord32 lateLossMs;\n    // milliseconds removed to reduce jitter buffer size\n    WebRtc_UWord32 accelerateMs;\n    // milliseconds discarded through buffer flushing\n    WebRtc_UWord32 flushedMs;\n    // milliseconds of generated silence\n    WebRtc_UWord32 generatedSilentMs;\n    // milliseconds of synthetic audio data (non-background noise)\n    WebRtc_UWord32 interpolatedVoiceMs;\n    // milliseconds of synthetic audio data (background noise level)\n    WebRtc_UWord32 interpolatedSilentMs;\n    // count of tiny expansions in output audio\n    WebRtc_UWord32 countExpandMoreThan120ms;\n    // count of small expansions in output audio\n    WebRtc_UWord32 countExpandMoreThan250ms;\n    // count of medium expansions in output audio\n    WebRtc_UWord32 countExpandMoreThan500ms;\n    // count of long expansions in output audio\n    WebRtc_UWord32 countExpandMoreThan2000ms;\n    // duration of longest audio drop-out\n    WebRtc_UWord32 longestExpandDurationMs;\n    // count of times we got small network outage (inter-arrival time in\n    // [500, 1000) ms)\n    WebRtc_UWord32 countIAT500ms;\n    // count of times we got medium network outage (inter-arrival time in\n    // [1000, 2000) ms)\n    WebRtc_UWord32 countIAT1000ms;\n    // count of times we got large network outage (inter-arrival time >=\n    // 2000 ms)\n    WebRtc_UWord32 countIAT2000ms;\n    // longest packet inter-arrival time in ms\n    WebRtc_UWord32 longestIATms;\n    // min time incoming Packet \"waited\" to be played\n    WebRtc_UWord32 minPacketDelayMs;\n    // max time incoming Packet \"waited\" to be played\n    WebRtc_UWord32 maxPacketDelayMs;\n    // avg time incoming Packet \"waited\" to be played\n    WebRtc_UWord32 avgPacketDelayMs;\n};\n\ntypedef struct\n{\n    int min;              // minumum\n    int max;              // maximum\n    int average;          // average\n} StatVal;\n\ntypedef struct           // All levels are reported in dBm0\n{\n    StatVal speech_rx;   // long-term speech levels on receiving side\n    StatVal speech_tx;   // long-term speech levels on transmitting side\n    StatVal noise_rx;    // long-term noise/silence levels on receiving side\n    StatVal noise_tx;    // long-term noise/silence levels on transmitting side\n} LevelStatistics;\n\ntypedef struct        // All levels are reported in dB\n{\n    StatVal erl;      // Echo Return Loss\n    StatVal erle;     // Echo Return Loss Enhancement\n    StatVal rerl;     // RERL = ERL + ERLE\n    // Echo suppression inside EC at the point just before its NLP\n    StatVal a_nlp;\n} EchoStatistics;\n\nenum TelephoneEventDetectionMethods\n{\n    kInBand = 0,\n    kOutOfBand = 1,\n    kInAndOutOfBand = 2\n};\n\nenum NsModes    // type of Noise Suppression\n{\n    kNsUnchanged = 0,   // previously set mode\n    kNsDefault,         // platform default\n    kNsConference,      // conferencing default\n    kNsLowSuppression,  // lowest suppression\n    kNsModerateSuppression,\n    kNsHighSuppression,\n    kNsVeryHighSuppression,     // highest suppression\n};\n\nenum AgcModes                  // type of Automatic Gain Control\n{\n    kAgcUnchanged = 0,        // previously set mode\n    kAgcDefault,              // platform default\n    // adaptive mode for use when analog volume control exists (e.g. for\n    // PC softphone)\n    kAgcAdaptiveAnalog,\n    // scaling takes place in the digital domain (e.g. for conference servers\n    // and embedded devices)\n    kAgcAdaptiveDigital,\n    // can be used on embedded devices where the the capture signal is level\n    // is predictable\n    kAgcFixedDigital\n};\n\n// EC modes\nenum EcModes                   // type of Echo Control\n{\n    kEcUnchanged = 0,          // previously set mode\n    kEcDefault,                // platform default\n    kEcConference,             // conferencing default (aggressive AEC)\n    kEcAec,                    // Acoustic Echo Cancellation\n    kEcAecm,                   // AEC mobile\n};\n\n// AECM modes\nenum AecmModes                 // mode of AECM\n{\n    kAecmQuietEarpieceOrHeadset = 0,\n                               // Quiet earpiece or headset use\n    kAecmEarpiece,             // most earpiece use\n    kAecmLoudEarpiece,         // Loud earpiece or quiet speakerphone use\n    kAecmSpeakerphone,         // most speakerphone use (default)\n    kAecmLoudSpeakerphone      // Loud speakerphone\n};\n\n// AGC configuration\ntypedef struct\n{\n    unsigned short targetLeveldBOv;\n    unsigned short digitalCompressionGaindB;\n    bool           limiterEnable;\n} AgcConfig;                  // AGC configuration parameters\n\nenum StereoChannel\n{\n    kStereoLeft = 0,\n    kStereoRight,\n    kStereoBoth\n};\n\n// Audio device layers\nenum AudioLayers\n{\n    kAudioPlatformDefault = 0,\n    kAudioWindowsWave = 1,\n    kAudioWindowsCore = 2,\n    kAudioLinuxAlsa = 3,\n    kAudioLinuxPulse = 4\n};\n\nenum NetEqModes             // NetEQ playout configurations\n{\n    // Optimized trade-off between low delay and jitter robustness for two-way\n    // communication.\n    kNetEqDefault = 0,\n    // Improved jitter robustness at the cost of increased delay. Can be\n    // used in one-way communication.\n    kNetEqStreaming = 1,\n    // Optimzed for decodability of fax signals rather than for perceived audio\n    // quality.\n    kNetEqFax = 2,\n};\n\nenum NetEqBgnModes          // NetEQ Background Noise (BGN) configurations\n{\n    // BGN is always on and will be generated when the incoming RTP stream\n    // stops (default).\n    kBgnOn = 0,\n    // The BGN is faded to zero (complete silence) after a few seconds.\n    kBgnFade = 1,\n    // BGN is not used at all. Silence is produced after speech extrapolation\n    // has faded.\n    kBgnOff = 2,\n};\n\nenum OnHoldModes            // On Hold direction\n{\n    kHoldSendAndPlay = 0,    // Put both sending and playing in on-hold state.\n    kHoldSendOnly,           // Put only sending in on-hold state.\n    kHoldPlayOnly            // Put only playing in on-hold state.\n};\n\nenum AmrMode\n{\n    kRfc3267BwEfficient = 0,\n    kRfc3267OctetAligned = 1,\n    kRfc3267FileStorage = 2,\n};\n\n// ==================================================================\n// Video specific types\n// ==================================================================\n\n// Raw video types\nenum RawVideoType\n{\n    kVideoI420     = 0,\n    kVideoYV12     = 1,\n    kVideoYUY2     = 2,\n    kVideoUYVY     = 3,\n    kVideoIYUV     = 4,\n    kVideoARGB     = 5,\n    kVideoRGB24    = 6,\n    kVideoRGB565   = 7,\n    kVideoARGB4444 = 8,\n    kVideoARGB1555 = 9,\n    kVideoMJPEG    = 10,\n    kVideoNV12     = 11,\n    kVideoNV21     = 12,\n    kVideoUnknown  = 99\n};\n\n// Video codec\nenum { kConfigParameterSize = 128};\nenum { kPayloadNameSize = 32};\n\n// H.263 specific\nstruct VideoCodecH263\n{\n    char quality;\n};\n\n// H.264 specific\nenum H264Packetization\n{\n    kH264SingleMode         = 0,\n    kH264NonInterleavedMode = 1\n};\n\nenum VideoCodecComplexity\n{\n    kComplexityNormal = 0,\n    kComplexityHigh    = 1,\n    kComplexityHigher  = 2,\n    kComplexityMax     = 3\n};\n\nenum VideoCodecProfile\n{\n    kProfileBase = 0x00,\n    kProfileMain = 0x01\n};\n\nstruct VideoCodecH264\n{\n    H264Packetization          packetization;\n    VideoCodecComplexity       complexity;\n    VideoCodecProfile          profile;\n    char                       level;\n    char                       quality;\n\n    bool                       useFMO;\n\n    unsigned char              configParameters[kConfigParameterSize];\n    unsigned char              configParametersSize;\n};\n\n// VP8 specific\nstruct VideoCodecVP8\n{\n    bool                       pictureLossIndicationOn;\n    bool                       feedbackModeOn;\n    VideoCodecComplexity       complexity;\n};\n\n// MPEG-4 specific\nstruct VideoCodecMPEG4\n{\n    unsigned char   configParameters[kConfigParameterSize];\n    unsigned char   configParametersSize;\n    char            level;\n};\n\n// Unknown specific\nstruct VideoCodecGeneric\n{\n};\n\n// Video codec types\nenum VideoCodecType\n{\n    kVideoCodecH263,\n    kVideoCodecH264,\n    kVideoCodecVP8,\n    kVideoCodecMPEG4,\n    kVideoCodecI420,\n    kVideoCodecRED,\n    kVideoCodecULPFEC,\n    kVideoCodecUnknown\n};\n\nunion VideoCodecUnion\n{\n    VideoCodecH263      H263;\n    VideoCodecH264      H264;\n    VideoCodecVP8       VP8;\n    VideoCodecMPEG4     MPEG4;\n    VideoCodecGeneric   Generic;\n};\n\n// Common video codec properties\nstruct VideoCodec\n{\n    VideoCodecType      codecType;\n    char                plName[kPayloadNameSize];\n    unsigned char       plType;\n\n    unsigned short      width;\n    unsigned short      height;\n\n    unsigned int        startBitrate;\n    unsigned int        maxBitrate;\n    unsigned int        minBitrate;\n    unsigned char       maxFramerate;\n\n    VideoCodecUnion     codecSpecific;\n\n    unsigned int        qpMax;\n};\n\n}  // namespace webrtc\n\n#endif  // WEBRTC_COMMON_TYPES_H\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/engine_configurations.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_ENGINE_CONFIGURATIONS_H_\n#define WEBRTC_ENGINE_CONFIGURATIONS_H_\n\n// ============================================================================\n//                              Voice and Video\n// ============================================================================\n\n// #define WEBRTC_EXTERNAL_TRANSPORT\n\n// ----------------------------------------------------------------------------\n//  [Voice] Codec settings\n// ----------------------------------------------------------------------------\n\n#define WEBRTC_CODEC_ILBC\n#define WEBRTC_CODEC_ISAC       // floating-point iSAC implementation (default)\n// #define WEBRTC_CODEC_ISACFX  // fix-point iSAC implementation\n#define WEBRTC_CODEC_G722\n#define WEBRTC_CODEC_PCM16\n#define WEBRTC_CODEC_RED\n#define WEBRTC_CODEC_AVT\n\n// ----------------------------------------------------------------------------\n//  [Video] Codec settings\n// ----------------------------------------------------------------------------\n\n#define VIDEOCODEC_I420\n#define VIDEOCODEC_VP8\n\n// ============================================================================\n//                                 VoiceEngine\n// ============================================================================\n\n// ----------------------------------------------------------------------------\n//  Settings for VoiceEngine\n// ----------------------------------------------------------------------------\n\n#define WEBRTC_VOICE_ENGINE_AGC                 // Near-end AGC\n#define WEBRTC_VOICE_ENGINE_ECHO                // Near-end AEC\n#define WEBRTC_VOICE_ENGINE_NR                  // Near-end NS\n#define WEBRTC_VOICE_ENGINE_TYPING_DETECTION\n#define WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT\n\n// ----------------------------------------------------------------------------\n//  VoiceEngine sub-APIs\n// ----------------------------------------------------------------------------\n\n#define WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API\n#define WEBRTC_VOICE_ENGINE_CALL_REPORT_API\n#define WEBRTC_VOICE_ENGINE_CODEC_API\n#define WEBRTC_VOICE_ENGINE_DTMF_API\n#define WEBRTC_VOICE_ENGINE_ENCRYPTION_API\n#define WEBRTC_VOICE_ENGINE_EXTERNAL_MEDIA_API\n#define WEBRTC_VOICE_ENGINE_FILE_API\n#define WEBRTC_VOICE_ENGINE_HARDWARE_API\n#define WEBRTC_VOICE_ENGINE_NETEQ_STATS_API\n#define WEBRTC_VOICE_ENGINE_NETWORK_API\n#define WEBRTC_VOICE_ENGINE_RTP_RTCP_API\n#define WEBRTC_VOICE_ENGINE_VIDEO_SYNC_API\n#define WEBRTC_VOICE_ENGINE_VOLUME_CONTROL_API\n\n// ============================================================================\n//                                 VideoEngine\n// ============================================================================\n\n// ----------------------------------------------------------------------------\n//  Settings for special VideoEngine configurations\n// ----------------------------------------------------------------------------\n// ----------------------------------------------------------------------------\n//  VideoEngine sub-API:s\n// ----------------------------------------------------------------------------\n\n#define WEBRTC_VIDEO_ENGINE_CAPTURE_API\n#define WEBRTC_VIDEO_ENGINE_CODEC_API\n#define WEBRTC_VIDEO_ENGINE_ENCRYPTION_API\n#define WEBRTC_VIDEO_ENGINE_FILE_API\n#define WEBRTC_VIDEO_ENGINE_IMAGE_PROCESS_API\n#define WEBRTC_VIDEO_ENGINE_NETWORK_API\n#define WEBRTC_VIDEO_ENGINE_RENDER_API\n#define WEBRTC_VIDEO_ENGINE_RTP_RTCP_API\n// #define WEBRTC_VIDEO_ENGINE_EXTERNAL_CODEC_API\n\n// ============================================================================\n//                       Platform specific configurations\n// ============================================================================\n\n// ----------------------------------------------------------------------------\n//  VideoEngine Windows\n// ----------------------------------------------------------------------------\n\n#if defined(_WIN32)\n\t// #define DIRECTDRAW_RENDERING\n\t#define DIRECT3D9_RENDERING  // Requires DirectX 9.\n#endif \n\n// ----------------------------------------------------------------------------\n//  VideoEngine MAC\n// ----------------------------------------------------------------------------\n\n#if defined(WEBRTC_MAC) && !defined(MAC_IPHONE)\n\t// #define CARBON_RENDERING\n\t#define COCOA_RENDERING\n#endif\n\n// ----------------------------------------------------------------------------\n//  VideoEngine Mobile iPhone\n// ----------------------------------------------------------------------------\n\n#if defined(MAC_IPHONE)\n    #define EAGL_RENDERING\n#endif\n\n// ----------------------------------------------------------------------------\n//  Deprecated\n// ----------------------------------------------------------------------------\n\n// #define WEBRTC_CODEC_G729\n// #define WEBRTC_DTMF_DETECTION\n// #define WEBRTC_SRTP\n// #define WEBRTC_SRTP_ALLOW_ROC_ITERATION\n\n#endif  // WEBRTC_ENGINE_CONFIGURATIONS_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/aec/main/interface/echo_cancellation.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_INTERFACE_ECHO_CANCELLATION_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_INTERFACE_ECHO_CANCELLATION_H_\n\n#include \"typedefs.h\"\n\n// Errors\n#define AEC_UNSPECIFIED_ERROR           12000\n#define AEC_UNSUPPORTED_FUNCTION_ERROR  12001\n#define AEC_UNINITIALIZED_ERROR         12002\n#define AEC_NULL_POINTER_ERROR          12003\n#define AEC_BAD_PARAMETER_ERROR         12004\n\n// Warnings\n#define AEC_BAD_PARAMETER_WARNING       12050\n\nenum {\n    kAecNlpConservative = 0,\n    kAecNlpModerate,\n    kAecNlpAggressive\n};\n\nenum {\n    kAecFalse = 0,\n    kAecTrue\n};\n\ntypedef struct {\n    WebRtc_Word16 nlpMode;        // default kAecNlpModerate\n    WebRtc_Word16 skewMode;       // default kAecFalse\n    WebRtc_Word16 metricsMode;    // default kAecFalse\n    //float realSkew;\n} AecConfig;\n\ntypedef struct {\n    WebRtc_Word16 instant;\n    WebRtc_Word16 average;\n    WebRtc_Word16 max;\n    WebRtc_Word16 min;\n} AecLevel;\n\ntypedef struct {\n    AecLevel rerl;\n    AecLevel erl;\n    AecLevel erle;\n    AecLevel aNlp;\n} AecMetrics;\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n * Allocates the memory needed by the AEC. The memory needs to be initialized\n * separately using the WebRtcAec_Init() function.\n *\n * Inputs                       Description\n * -------------------------------------------------------------------\n * void **aecInst               Pointer to the AEC instance to be created\n *                              and initilized\n *\n * Outputs                      Description\n * -------------------------------------------------------------------\n * WebRtc_Word32 return          0: OK\n *                              -1: error\n */\nWebRtc_Word32 WebRtcAec_Create(void **aecInst);\n\n/*\n * This function releases the memory allocated by WebRtcAec_Create().\n *\n * Inputs                       Description\n * -------------------------------------------------------------------\n * void         *aecInst        Pointer to the AEC instance\n *\n * Outputs                      Description\n * -------------------------------------------------------------------\n * WebRtc_Word32  return         0: OK\n *                              -1: error\n */\nWebRtc_Word32 WebRtcAec_Free(void *aecInst);\n\n/*\n * Initializes an AEC instance.\n *\n * Inputs                       Description\n * -------------------------------------------------------------------\n * void           *aecInst      Pointer to the AEC instance\n * WebRtc_Word32  sampFreq      Sampling frequency of data\n * WebRtc_Word32  scSampFreq    Soundcard sampling frequency\n *\n * Outputs                      Description\n * -------------------------------------------------------------------\n * WebRtc_Word32 return          0: OK\n *                              -1: error\n */\nWebRtc_Word32 WebRtcAec_Init(void *aecInst,\n                             WebRtc_Word32 sampFreq,\n                             WebRtc_Word32 scSampFreq);\n\n/*\n * Inserts an 80 or 160 sample block of data into the farend buffer.\n *\n * Inputs                       Description\n * -------------------------------------------------------------------\n * void           *aecInst      Pointer to the AEC instance\n * WebRtc_Word16  *farend       In buffer containing one frame of\n *                              farend signal for L band\n * WebRtc_Word16  nrOfSamples   Number of samples in farend buffer\n *\n * Outputs                      Description\n * -------------------------------------------------------------------\n * WebRtc_Word32  return         0: OK\n *                              -1: error\n */\nWebRtc_Word32 WebRtcAec_BufferFarend(void *aecInst,\n                                     const WebRtc_Word16 *farend,\n                                     WebRtc_Word16 nrOfSamples);\n\n/*\n * Runs the echo canceller on an 80 or 160 sample blocks of data.\n *\n * Inputs                       Description\n * -------------------------------------------------------------------\n * void          *aecInst       Pointer to the AEC instance\n * WebRtc_Word16 *nearend       In buffer containing one frame of\n *                              nearend+echo signal for L band\n * WebRtc_Word16 *nearendH      In buffer containing one frame of\n *                              nearend+echo signal for H band\n * WebRtc_Word16 nrOfSamples    Number of samples in nearend buffer\n * WebRtc_Word16 msInSndCardBuf Delay estimate for sound card and\n *                              system buffers\n * WebRtc_Word16 skew           Difference between number of samples played\n *                              and recorded at the soundcard (for clock skew\n *                              compensation)\n *\n * Outputs                      Description\n * -------------------------------------------------------------------\n * WebRtc_Word16  *out          Out buffer, one frame of processed nearend\n *                              for L band\n * WebRtc_Word16  *outH         Out buffer, one frame of processed nearend\n *                              for H band\n * WebRtc_Word32  return         0: OK\n *                              -1: error\n */\nWebRtc_Word32 WebRtcAec_Process(void *aecInst,\n                                const WebRtc_Word16 *nearend,\n                                const WebRtc_Word16 *nearendH,\n                                WebRtc_Word16 *out,\n                                WebRtc_Word16 *outH,\n                                WebRtc_Word16 nrOfSamples,\n                                WebRtc_Word16 msInSndCardBuf,\n                                WebRtc_Word32 skew);\n\n/*\n * This function enables the user to set certain parameters on-the-fly.\n *\n * Inputs                       Description\n * -------------------------------------------------------------------\n * void           *aecInst      Pointer to the AEC instance\n * AecConfig      config        Config instance that contains all\n *                              properties to be set\n *\n * Outputs                      Description\n * -------------------------------------------------------------------\n * WebRtc_Word32  return         0: OK\n *                              -1: error\n */\nWebRtc_Word32 WebRtcAec_set_config(void *aecInst, AecConfig config);\n\n/*\n * Gets the on-the-fly paramters.\n *\n * Inputs                       Description\n * -------------------------------------------------------------------\n * void           *aecInst      Pointer to the AEC instance\n *\n * Outputs                      Description\n * -------------------------------------------------------------------\n * AecConfig      *config       Pointer to the config instance that\n *                              all properties will be written to\n * WebRtc_Word32  return         0: OK\n *                              -1: error\n */\nWebRtc_Word32 WebRtcAec_get_config(void *aecInst, AecConfig *config);\n\n/*\n * Gets the current echo status of the nearend signal.\n *\n * Inputs                       Description\n * -------------------------------------------------------------------\n * void           *aecInst      Pointer to the AEC instance\n *\n * Outputs                      Description\n * -------------------------------------------------------------------\n * WebRtc_Word16  *status       0: Almost certainly nearend single-talk\n *                              1: Might not be neared single-talk\n * WebRtc_Word32  return         0: OK\n *                              -1: error\n */\nWebRtc_Word32 WebRtcAec_get_echo_status(void *aecInst, WebRtc_Word16 *status);\n\n/*\n * Gets the current echo metrics for the session.\n *\n * Inputs                       Description\n * -------------------------------------------------------------------\n * void           *aecInst      Pointer to the AEC instance\n *\n * Outputs                      Description\n * -------------------------------------------------------------------\n * AecMetrics     *metrics      Struct which will be filled out with the\n *                              current echo metrics.\n * WebRtc_Word32  return         0: OK\n *                              -1: error\n */\nWebRtc_Word32 WebRtcAec_GetMetrics(void *aecInst, AecMetrics *metrics);\n\n/*\n * Gets the last error code.\n *\n * Inputs                       Description\n * -------------------------------------------------------------------\n * void           *aecInst      Pointer to the AEC instance\n *\n * Outputs                      Description\n * -------------------------------------------------------------------\n * WebRtc_Word32  return        11000-11100: error code\n */\nWebRtc_Word32 WebRtcAec_get_error_code(void *aecInst);\n\n/*\n * Gets a version string.\n *\n * Inputs                       Description\n * -------------------------------------------------------------------\n * char           *versionStr   Pointer to a string array\n * WebRtc_Word16  len           The maximum length of the string\n *\n * Outputs                      Description\n * -------------------------------------------------------------------\n * WebRtc_Word8   *versionStr   Pointer to a string array\n * WebRtc_Word32  return         0: OK\n *                              -1: error\n */\nWebRtc_Word32 WebRtcAec_get_version(WebRtc_Word8 *versionStr, WebRtc_Word16 len);\n\n#ifdef __cplusplus\n}\n#endif\n#endif  /* WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_INTERFACE_ECHO_CANCELLATION_H_ */\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/aec/main/matlab/fullaec.m",
    "content": "% Partitioned block frequency domain adaptive filtering NLMS and \n% standard time-domain sample-based NLMS \n%fid=fopen('aecFar-samsung.pcm', 'rb'); % Load far end\nfid=fopen('aecFar.pcm', 'rb'); % Load far end\n%fid=fopen(farFile, 'rb'); % Load far end\nrrin=fread(fid,inf,'int16');\nfclose(fid); \n%rrin=loadsl('data/far_me2.pcm'); % Load far end\n%fid=fopen('aecNear-samsung.pcm', 'rb'); % Load near end\nfid=fopen('aecNear.pcm', 'rb'); % Load near end\n%fid=fopen(nearFile, 'rb'); % Load near end\nssin=fread(fid,inf,'int16');\n%ssin = [zeros(1024,1) ; ssin(1:end-1024)];\n\nfclose(fid);\nrand('state',13);\nfs=16000;\nmult=fs/8000;\n%rrin=rrin(fs*0+1:round(fs*120));\n%ssin=ssin(fs*0+1:round(fs*120));\nif fs == 8000\n\tcohRange = 2:3;\nelseif fs==16000\n\tcohRange = 2;\nend\n\n% Flags\nNLPon=1;  % NLP\nCNon=1; % Comfort noise\nPLTon=1;  % Plotting\n\nM = 16; % Number of partitions\nN = 64; % Partition length\nL = M*N; % Filter length \nif fs == 8000\n    mufb = 0.6;\nelse\n    mufb = 0.5;  \nend\n%mufb=1;  \nVADtd=48;\nalp = 0.1; % Power estimation factor alc = 0.1; % Coherence estimation factor\nbeta = 0.9; % Plotting factor \n%% Changed a little %%\nstep = 0.3;%0.1875; % Downward step size \n%%\nif fs == 8000\n    threshold=2e-6;  % DTrob threshold\nelse\n    %threshold=0.7e-6;\n    threshold=1.5e-6; end\n\nif fs == 8000\n    echoBandRange = ceil(300*2/fs*N):floor(1800*2/fs*N);\n    %echoBandRange = ceil(1500*2/fs*N):floor(2500*2/fs*N);\nelse\n    echoBandRange = ceil(300*2/fs*N):floor(1800*2/fs*N);\n    %echoBandRange = ceil(300*2/fs*N):floor(1800*2/fs*N);\nend\n%echoBandRange = ceil(1600*2/fs*N):floor(1900*2/fs*N);\n%echoBandRange = ceil(2000*2/fs*N):floor(4000*2/fs*N);\nsuppState = 1;\ntransCtr = 0;\n\nNt=1;\nvt=1;\n\nramp = 1.0003; % Upward ramp\nrampd = 0.999; % Downward ramp\ncvt = 20; % Subband VAD threshold;\nnnthres = 20; % Noise threshold \n\nshh=logspace(-1.3,-2.2,N+1)';\nsh=[shh;flipud(shh(2:end-1))]; % Suppression profile\n\nlen=length(ssin);\nw=zeros(L,1); % Sample-based TD NLMS \nWFb=zeros(N+1,M); % Block-based FD NLMS\nWFbOld=zeros(N+1,M); % Block-based FD NLMS\nYFb=zeros(N+1,M);\nerfb=zeros(len,1);\nerfb3=zeros(len,1);\n\nercn=zeros(len,1);\nzm=zeros(N,1);\nXFm=zeros(N+1,M);\nYFm=zeros(N+1,M);\npn0=10*ones(N+1,1);\npn=zeros(N+1,1);\nNN=len;\nNb=floor(NN/N)-M;\nerifb=zeros(Nb+1,1)+0.1;\nerifb3=zeros(Nb+1,1)+0.1;\nericn=zeros(Nb+1,1)+0.1;\ndri=zeros(Nb+1,1)+0.1;\nstart=1;\nxo=zeros(N,1);\ndo=xo;\neo=xo;\n\nechoBands=zeros(Nb+1,1);\ncohxdAvg=zeros(Nb+1,1);\ncohxdSlow=zeros(Nb+1,N+1);\ncohedSlow=zeros(Nb+1,N+1);\n%overdriveM=zeros(Nb+1,N+1);\ncohxdFastAvg=zeros(Nb+1,1);\ncohxdAvgBad=zeros(Nb+1,1);\ncohedAvg=zeros(Nb+1,1);\ncohedFastAvg=zeros(Nb+1,1);\nhnledAvg=zeros(Nb+1,1);\nhnlxdAvg=zeros(Nb+1,1);\novrdV=zeros(Nb+1,1);\ndIdxV=zeros(Nb+1,1);\nSLxV=zeros(Nb+1,1);\nhnlSortQV=zeros(Nb+1,1);\nhnlPrefAvgV=zeros(Nb+1,1);\nmutInfAvg=zeros(Nb+1,1);\n%overdrive=zeros(Nb+1,1);\nhnled = zeros(N+1, 1);\nweight=zeros(N+1,1);\nhnlMax = zeros(N+1, 1);\nhnl = zeros(N+1, 1);\noverdrive = ones(1, N+1);\nxfwm=zeros(N+1,M);\ndfm=zeros(N+1,M);\nWFbD=ones(N+1,1);\n\nfbSupp = 0;\nhnlLocalMin = 1;\ncohxdLocalMin = 1;\nhnlLocalMinV=zeros(Nb+1,1);\ncohxdLocalMinV=zeros(Nb+1,1);\nhnlMinV=zeros(Nb+1,1);\ndkEnV=zeros(Nb+1,1);\nekEnV=zeros(Nb+1,1);\novrd = 2;\novrdPos = floor((N+1)/4);\novrdSm = 2;\nhnlMin = 1;\nminCtr = 0;\nSeMin = 0;\nSdMin = 0;\nSeLocalAvg = 0;\nSeMinSm = 0;\ndivergeFact = 1;\ndIdx = 1;\nhnlMinCtr = 0;\nhnlNewMin = 0;\ndivergeState = 0;\n\nSy=ones(N+1,1);\nSym=1e7*ones(N+1,1);\n\nwins=[0;sqrt(hanning(2*N-1))];\nubufn=zeros(2*N,1);\nebuf=zeros(2*N,1);\nebuf2=zeros(2*N,1);\nebuf4=zeros(2*N,1);\nmbuf=zeros(2*N,1);\n\ncohedFast = zeros(N+1,1);\ncohxdFast = zeros(N+1,1);\ncohxd = zeros(N+1,1);\nSe = zeros(N+1,1);\nSd = zeros(N+1,1);\nSx = zeros(N+1,1);\nSxBad = zeros(N+1,1);\nSed = zeros(N+1,1);\nSxd = zeros(N+1,1);\nSxdBad = zeros(N+1,1);\nhnledp=[];\n\ncohxdMax = 0;\n\n%hh=waitbar(0,'Please wait...');\nprogressbar(0);\n\n%spaces = ' ';\n%spaces = repmat(spaces, 50, 1);\n%spaces = ['[' ; spaces ; ']'];\n%fprintf(1, spaces);\n%fprintf(1, '\\n');\n\nfor kk=1:Nb\n    pos = N * (kk-1) + start;\n    \n    % FD block method\n    % ----------------------   Organize data\n    xk = rrin(pos:pos+N-1);\n    dk = ssin(pos:pos+N-1);\n    \n    xx = [xo;xk];\n    xo = xk;\n    tmp = fft(xx); \n\tXX = tmp(1:N+1);\n\n\tdd = [do;dk];  % Overlap\n\tdo = dk;\n\ttmp = fft(dd); % Frequency domain \n\tDD = tmp(1:N+1);\n    \n    % ------------------------  Power estimation\n    pn0 = (1 - alp) * pn0 + alp * real(XX.* conj(XX));\n    pn = pn0;\n    %pn = (1 - alp) * pn + alp * M * pn0;\n\tif (CNon)\n\t\tYp =  real(conj(DD).*DD); % Instantaneous power      \n\t\tSy =  (1 - alp) * Sy + alp * Yp; % Averaged power    \n\t\t\n\t\tmm = min(Sy,Sym);  \n\t\tdiff = Sym - mm;\n\t\tif (kk>50)\n\t\t\tSym = (mm + step*diff) * ramp; % Estimated background noise power   \n\t\tend\n\tend\n    \n    % ----------------------   Filtering   \n    XFm(:,1) = XX;\n    for mm=0:(M-1)\n        m=mm+1;  \n        YFb(:,m) = XFm(:,m) .* WFb(:,m);\n    end\n    yfk = sum(YFb,2);\n\ttmp = [yfk ; flipud(conj(yfk(2:N)))];\n    ykt = real(ifft(tmp));\n    ykfb = ykt(end-N+1:end); \n    \n    % ----------------------   Error estimation \n    ekfb = dk - ykfb; \n    %if sum(abs(ekfb)) < sum(abs(dk))\n        %ekfb = dk - ykfb; \n    %    erfb(pos:pos+N-1) = ekfb; \n    %else\n        %ekfb = dk;\n    %    erfb(pos:pos+N-1) = dk; \n    %end\n\t%(kk-1)*(N*2)+1\n    erfb(pos:pos+N-1) = ekfb; \n    tmp = fft([zm;ekfb]);      % FD version for cancelling part (overlap-save)\n\tEk = tmp(1:N+1);\n\n    % ------------------------  Adaptation  \n\tEk2 = Ek ./(M*pn + 0.001); % Normalized error\n\t%Ek2 = Ek ./(pn + 0.001); % Normalized error\n\t%Ek2 = Ek ./(100*pn + 0.001); % Normalized error\n\t\n\tabsEf = max(abs(Ek2), threshold);\n\tabsEf = ones(N+1,1)*threshold./absEf;\n\tEk2 = Ek2.*absEf;\n\t\n\tmEk = mufb.*Ek2;\n\tPP = conj(XFm).*(ones(M,1) * mEk')'; \n\ttmp = [PP ; flipud(conj(PP(2:N,:)))];\n\tIFPP = real(ifft(tmp));\n\tPH = IFPP(1:N,:);\n\ttmp = fft([PH;zeros(N,M)]);\n\tFPH = tmp(1:N+1,:);\n\tWFb = WFb + FPH;\n\n    if mod(kk, 10*mult) == 0\n        WFbEn = sum(real(WFb.*conj(WFb)));\n        %WFbEn = sum(abs(WFb));\n        [tmp, dIdx] = max(WFbEn);\n\n        WFbD = sum(abs(WFb(:, dIdx)),2);\n        %WFbD = WFbD / (mean(WFbD) + 1e-10); \n        WFbD = min(max(WFbD, 0.5), 4);\n    end\n    dIdxV(kk) = dIdx;\n    \n\t% NLP\n\tif (NLPon)\n        \n        ee = [eo;ekfb]; \n        eo = ekfb;\n\t\twindow = wins;\n        if fs == 8000\n            %gamma = 0.88;\n            gamma = 0.9;\n        else\n\t\t    %gamma = 0.92;\n\t\t    gamma = 0.93;\n        end\n\t\t%gamma = 0.9;\n\n\t\ttmp = fft(xx.*window);\n\t\txf = tmp(1:N+1);\n\t\ttmp = fft(dd.*window);\n\t\tdf = tmp(1:N+1);\n\t\ttmp = fft(ee.*window);\n\t\tef = tmp(1:N+1);\n\n        xfwm(:,1) = xf;\n        xf = xfwm(:,dIdx);\n        %fprintf(1,'%d: %f\\n', kk, xf(4));\n        dfm(:,1) = df;\n        \n        SxOld = Sx;\n\n\t\tSe = gamma*Se + (1-gamma)*real(ef.*conj(ef));\n\t\tSd = gamma*Sd + (1-gamma)*real(df.*conj(df));\n\t\tSx = gamma*Sx + (1 - gamma)*real(xf.*conj(xf));\n\n        %xRatio = real(xfwm(:,1).*conj(xfwm(:,1))) ./ ...\n        %    (real(xfwm(:,2).*conj(xfwm(:,2))) + 1e-10);\n        %xRatio = Sx ./ (SxOld + 1e-10);\n        %SLx = log(1/(N+1)*sum(xRatio)) - 1/(N+1)*sum(log(xRatio));\n        %SLxV(kk) = SLx;\n\n        %freqSm = 0.9;\n        %Sx = filter(freqSm, [1 -(1-freqSm)], Sx);\n        %Sx(end:1) = filter(freqSm, [1 -(1-freqSm)], Sx(end:1));\n        %Se = filter(freqSm, [1 -(1-freqSm)], Se);\n        %Se(end:1) = filter(freqSm, [1 -(1-freqSm)], Se(end:1));\n        %Sd = filter(freqSm, [1 -(1-freqSm)], Sd);\n        %Sd(end:1) = filter(freqSm, [1 -(1-freqSm)], Sd(end:1));\n\n\t\t%SeFast = ef.*conj(ef);\n\t\t%SdFast = df.*conj(df);\n        %SxFast = xf.*conj(xf);\n        %cohedFast = 0.9*cohedFast + 0.1*SeFast ./ (SdFast + 1e-10);\n        %cohedFast(find(cohedFast > 1)) = 1;\n        %cohedFast(find(cohedFast > 1)) = 1 ./ cohedFast(find(cohedFast>1));\n        %cohedFastAvg(kk) = mean(cohedFast(echoBandRange));\n        %cohedFastAvg(kk) = min(cohedFast);\n\n        %cohxdFast = 0.8*cohxdFast + 0.2*log(SdFast ./ (SxFast + 1e-10));\n        %cohxdFastAvg(kk) = mean(cohxdFast(echoBandRange));\n\n\t\t% coherence\n        Sxd = gamma*Sxd + (1 - gamma)*xf.*conj(df);\n\t\tSed = gamma*Sed + (1-gamma)*ef.*conj(df);\n\n        %Sxd = filter(freqSm, [1 -(1-freqSm)], Sxd);\n        %Sxd(end:1) = filter(freqSm, [1 -(1-freqSm)], Sxd(end:1));\n        %Sed = filter(freqSm, [1 -(1-freqSm)], Sed);\n        %Sed(end:1) = filter(freqSm, [1 -(1-freqSm)], Sed(end:1));\n\n\t\tcohed = real(Sed.*conj(Sed))./(Se.*Sd + 1e-10);\n        %cohedAvg(kk) = mean(cohed(echoBandRange));\n        %cohedAvg(kk) = cohed(6);\n        %cohedAvg(kk) = min(cohed);\n\n\t\tcohxd = real(Sxd.*conj(Sxd))./(Sx.*Sd + 1e-10);\n        %freqSm = 0.5;\n        %cohxd(3:end) = filter(freqSm, [1 -(1-freqSm)], cohxd(3:end));\n        %cohxd(end:3) = filter(freqSm, [1 -(1-freqSm)], cohxd(end:3));\n        %cohxdAvg(kk) = mean(cohxd(echoBandRange));\n        %cohxdAvg(kk) = (cohxd(32));\n        %cohxdAvg(kk) = max(cohxd);\n\n        %xf = xfm(:,dIdx);\n\t\t%SxBad = gamma*SxBad + (1 - gamma)*real(xf.*conj(xf));\n        %SxdBad = gamma*SxdBad + (1 - gamma)*xf.*conj(df);\n\t\t%cohxdBad = real(SxdBad.*conj(SxdBad))./(SxBad.*Sd + 0.01);\n        %cohxdAvgBad(kk) = mean(cohxdBad);\n\n        %for j=1:N+1\n        %    mutInf(j) = 0.9*mutInf(j) + 0.1*information(abs(xfm(j,:)), abs(dfm(j,:)));\n        %end\n        %mutInfAvg(kk) = mean(mutInf);\n\n        %hnled = cohedFast;\n        %xIdx = find(cohxd > 1 - cohed);\n        %hnled(xIdx) = 1 - cohxd(xIdx);\n        %hnled = 1 - max(cohxd, 1-cohedFast);\n        hnled = min(1 - cohxd, cohed);\n        %hnled = 1 - cohxd;\n        %hnled = max(1 - (cohxd + (1-cohedFast)), 0);\n        %hnled = 1 - max(cohxd, 1-cohed);\n\n        if kk > 1\n            cohxdSlow(kk,:) = 0.99*cohxdSlow(kk-1,:) + 0.01*cohxd';\n            cohedSlow(kk,:) = 0.99*cohedSlow(kk-1,:) + 0.01*(1-cohed)';\n        end\n\n\n        if 0\n        %if kk > 50\n            %idx = find(hnled > 0.3);\n            hnlMax = hnlMax*0.9999;\n            %hnlMax(idx) = max(hnlMax(idx), hnled(idx));\n            hnlMax = max(hnlMax, hnled);\n            %overdrive(idx) = max(log(hnlMax(idx))/log(0.99), 1); \n            avgHnl = mean(hnlMax(echoBandRange));\n            if avgHnl > 0.3\n                overdrive = max(log(avgHnl)/log(0.99), 1);\n            end\n            weight(4:end) = max(hnlMax) - hnlMax(4:end);\n        end\n        \n        \n\n        %[hg, gidx] = max(hnled); \n        %fnrg = Sx(gidx) / (Sd(gidx) + 1e-10);\n        \n        %[tmp, bidx] = find((Sx / Sd + 1e-10) > fnrg);\n        %hnled(bidx) = hg;\n\n\n\t\t%cohed1 = mean(cohed(cohRange)); % range depends on bandwidth \n\t\t%cohed1 = cohed1^2;\n        %echoBands(kk) = length(find(cohed(echoBandRange) < 0.25))/length(echoBandRange);\n\n        %if (fbSupp == 0)\n        %    if (echoBands(kk) > 0.8)\n        %        fbSupp = 1;\n        %    end\n        %else\n        %    if (echoBands(kk) < 0.6)\n        %        fbSupp = 0;\n        %    end\n        %end\n        %overdrive(kk) = 7.5*echoBands(kk) + 0.5; \n        \n\t\t% Factor by which to weight other bands\n\t\t%if (cohed1 < 0.1)\n\t\t%\tw = 0.8 - cohed1*10*0.4;\n\t\t%else\n\t\t%\tw = 0.4;\n\t\t%end\n\t\t\t\n\t\t% Weight coherence subbands\n\t\t%hnled = w*cohed1 + (1 - w)*cohed;\n\t\t%hnled = (hnled).^2;\n\t\t%cohed(floor(N/2):end) = cohed(floor(N/2):end).^2;\n        %if fbSupp == 1\n        %    cohed = zeros(size(cohed));\n        %end\n        %cohed = cohed.^overdrive(kk);\n\n        %hnled = gamma*hnled + (1 - gamma)*cohed;\n\t\t% Additional hf suppression\n\t\t%hnledp = [hnledp ; mean(hnled)];\n\t\t%hnled(floor(N/2):end) = hnled(floor(N/2):end).^2;\n\t\t%ef = ef.*((weight*(min(1 - hnled)).^2 + (1 - weight).*(1 - hnled)).^2);\n\n        cohedMean = mean(cohed(echoBandRange));\n        %aggrFact = 4*(1-mean(hnled(echoBandRange))) + 1;\n        %[hnlSort, hnlSortIdx] = sort(hnled(echoBandRange));\n        [hnlSort, hnlSortIdx] = sort(1-cohxd(echoBandRange));\n        [xSort, xSortIdx] = sort(Sx);\n        %aggrFact = (1-mean(hnled(echoBandRange)));\n        %hnlSortQ = hnlSort(qIdx);\n        hnlSortQ = mean(1 - cohxd(echoBandRange));\n        %hnlSortQ = mean(1 - cohxd);\n\n        [hnlSort2, hnlSortIdx2] = sort(hnled(echoBandRange));\n        %[hnlSort2, hnlSortIdx2] = sort(hnled);\n        hnlQuant = 0.75;\n        hnlQuantLow = 0.5;\n        qIdx = floor(hnlQuant*length(hnlSort2));\n        qIdxLow = floor(hnlQuantLow*length(hnlSort2));\n        hnlPrefAvg = hnlSort2(qIdx);\n        hnlPrefAvgLow = hnlSort2(qIdxLow);\n        %hnlPrefAvgLow = mean(hnled);\n        %hnlPrefAvg = max(hnlSort2);\n        %hnlPrefAvgLow = min(hnlSort2);\n\n        %hnlPref = hnled(echoBandRange);\n        %hnlPrefAvg = mean(hnlPref(xSortIdx((0.5*length(xSortIdx)):end)));\n\n        %hnlPrefAvg = min(hnlPrefAvg, hnlSortQ);\n\n        %hnlSortQIdx = hnlSortIdx(qIdx);\n        %SeQ = Se(qIdx + echoBandRange(1) - 1); \n        %SdQ = Sd(qIdx + echoBandRange(1) - 1); \n        %SeQ = Se(qIdxLow + echoBandRange(1) - 1); \n        %SdQ = Sd(qIdxLow + echoBandRange(1) - 1); \n        %propLow = length(find(hnlSort < 0.1))/length(hnlSort);\n        %aggrFact = min((1 - hnlSortQ)/2, 0.5);\n        %aggrTerm = 1/aggrFact;\n\n        %hnlg = mean(hnled(echoBandRange));\n        %hnlg = hnlSortQ;\n        %if suppState == 0\n        %    if hnlg < 0.05\n        %        suppState = 2;\n        %        transCtr = 0;\n        %    elseif hnlg < 0.75\n        %        suppState = 1;\n        %        transCtr = 0;\n        %    end\n        %elseif suppState == 1\n        %    if hnlg > 0.8\n        %        suppState = 0;\n        %        transCtr = 0;\n        %    elseif hnlg < 0.05\n        %        suppState = 2;\n        %        transCtr = 0;\n        %    end\n        %else\n        %    if hnlg > 0.8\n        %        suppState = 0;\n        %        transCtr = 0;\n        %    elseif hnlg > 0.25\n        %        suppState = 1;\n        %        transCtr = 0;\n        %    end\n        %end\n        %if kk > 50\n\n            if cohedMean > 0.98 & hnlSortQ > 0.9\n                %if suppState == 1\n                %    hnled = 0.5*hnled + 0.5*cohed;\n                %    %hnlSortQ = 0.5*hnlSortQ + 0.5*cohedMean;\n                %    hnlPrefAvg = 0.5*hnlPrefAvg + 0.5*cohedMean;\n                %else\n                %    hnled = cohed;\n                %    %hnlSortQ = cohedMean;\n                %    hnlPrefAvg = cohedMean;\n                %end\n                suppState = 0;\n            elseif cohedMean < 0.95 | hnlSortQ < 0.8\n                %if suppState == 0\n                %    hnled = 0.5*hnled + 0.5*cohed;\n                %    %hnlSortQ = 0.5*hnlSortQ + 0.5*cohedMean;\n                %    hnlPrefAvg = 0.5*hnlPrefAvg + 0.5*cohedMean;\n                %end\n                suppState = 1;\n            end\n\n            if hnlSortQ < cohxdLocalMin & hnlSortQ < 0.75\n                cohxdLocalMin = hnlSortQ;\n            end\n\n            if cohxdLocalMin == 1\n                ovrd = 3;\n                hnled = 1-cohxd;\n                hnlPrefAvg = hnlSortQ;\n                hnlPrefAvgLow = hnlSortQ;\n            end\n\n            if suppState == 0\n                hnled = cohed;\n                hnlPrefAvg = cohedMean;\n                hnlPrefAvgLow = cohedMean;\n            end\n\n            %if hnlPrefAvg < hnlLocalMin & hnlPrefAvg < 0.6\n            if hnlPrefAvgLow < hnlLocalMin & hnlPrefAvgLow < 0.6\n                %hnlLocalMin = hnlPrefAvg;\n                %hnlMin = hnlPrefAvg;\n                hnlLocalMin = hnlPrefAvgLow;\n                hnlMin = hnlPrefAvgLow;\n                hnlNewMin = 1;\n                hnlMinCtr = 0;\n                %if hnlMinCtr == 0\n                %    hnlMinCtr = hnlMinCtr + 1;\n                %else\n                %    hnlMinCtr = 0;\n                %    hnlMin = hnlLocalMin;\n                    %SeLocalMin = SeQ;\n                    %SdLocalMin = SdQ;\n                    %SeLocalAvg = 0;\n                    %minCtr = 0;\n                %    ovrd = max(log(0.0001)/log(hnlMin), 2);\n                    %divergeFact = hnlLocalMin;\n            end\n\n            if hnlNewMin == 1\n                hnlMinCtr = hnlMinCtr + 1;\n            end\n            if hnlMinCtr == 2 \n                hnlNewMin = 0;\n                hnlMinCtr = 0;\n                %ovrd = max(log(0.0001)/log(hnlMin), 2);\n                ovrd = max(log(0.00001)/(log(hnlMin + 1e-10) + 1e-10), 3);\n                %ovrd = max(log(0.00000001)/(log(hnlMin + 1e-10) + 1e-10), 5);\n                %ovrd = max(log(0.0001)/log(hnlPrefAvg), 2);\n                %ovrd = max(log(0.001)/log(hnlMin), 2);\n            end\n            hnlLocalMin = min(hnlLocalMin + 0.0008/mult, 1);\n            cohxdLocalMin = min(cohxdLocalMin + 0.0004/mult, 1);\n            %divergeFact = hnlSortQ;\n\n\n            %if minCtr > 0 & hnlLocalMin < 1\n            %    hnlMin = hnlLocalMin;\n            %    %SeMin = 0.9*SeMin + 0.1*sqrt(SeLocalMin);\n            %    SdMin = sqrt(SdLocalMin);\n            %    %SeMin = sqrt(SeLocalMin)*hnlSortQ;\n            %    SeMin = sqrt(SeLocalMin);\n            %    %ovrd = log(100/SeMin)/log(hnlSortQ);\n            %    %ovrd = log(100/SeMin)/log(hnlSortQ);\n            %    ovrd = log(0.01)/log(hnlMin);\n            %    ovrd = max(ovrd, 2);\n            %    ovrdPos = hnlSortQIdx;\n            %    %ovrd = max(ovrd, 1);\n            %    %SeMin = sqrt(SeLocalAvg/5);\n            %    minCtr = 0;\n            %else\n            %    %SeLocalMin = 0.9*SeLocalMin +0.1*SeQ;\n            %    SeLocalAvg = SeLocalAvg + SeQ;\n            %    minCtr = minCtr + 1;\n            %end\n\n            if ovrd < ovrdSm\n                ovrdSm = 0.99*ovrdSm + 0.01*ovrd;\n            else\n                ovrdSm = 0.9*ovrdSm + 0.1*ovrd;\n            end\n        %end\n\n        %ekEn = sum(real(ekfb.^2));\n        %dkEn = sum(real(dk.^2));\n        ekEn = sum(Se);\n        dkEn = sum(Sd);\n\n        if divergeState == 0\n            if ekEn > dkEn\n                ef = df;\n                divergeState = 1;\n                %hnlPrefAvg = hnlSortQ;\n                %hnled = (1 - cohxd);\n            end\n        else\n            %if ekEn*1.1 < dkEn  \n            %if ekEn*1.26 < dkEn  \n            if ekEn*1.05 < dkEn  \n                divergeState = 0;\n            else\n                ef = df;\n            end\n        end\n\n        if ekEn > dkEn*19.95\n            WFb=zeros(N+1,M); % Block-based FD NLMS\n        end\n\n        ekEnV(kk) = ekEn;\n        dkEnV(kk) = dkEn;\n\n        hnlLocalMinV(kk) = hnlLocalMin;\n        cohxdLocalMinV(kk) = cohxdLocalMin;\n        hnlMinV(kk) = hnlMin;\n        %cohxdMaxLocal = max(cohxdSlow(kk,:));\n        %if kk > 50\n        %cohxdMaxLocal = 1-hnlSortQ;\n        %if cohxdMaxLocal > 0.5\n        %    %if cohxdMaxLocal > cohxdMax \n        %        odScale = max(log(cohxdMaxLocal)/log(0.95), 1);\n        %        %overdrive(7:end) = max(log(cohxdSlow(kk,7:end))/log(0.9), 1);\n        %        cohxdMax = cohxdMaxLocal;\n        %    end\n        %end\n        %end\n        %cohxdMax = cohxdMax*0.999;\n\n        %overdriveM(kk,:) = max(overdrive, 1);\n        %aggrFact = 0.25;\n        aggrFact = 0.3;\n        %aggrFact = 0.5*propLow;\n        %if fs == 8000\n        %    wCurve = [0 ; 0 ; aggrFact*sqrt(linspace(0,1,N-1))' + 0.1];\n        %else\n        %    wCurve = [0; 0; 0; aggrFact*sqrt(linspace(0,1,N-2))' + 0.1];\n        %end\n        wCurve = [0; aggrFact*sqrt(linspace(0,1,N))' + 0.1];\n        % For sync with C\n        %if fs == 8000\n        %    wCurve = wCurve(2:end);\n        %else\n        %    wCurve = wCurve(1:end-1);\n        %end\n        %weight = aggrFact*(sqrt(linspace(0,1,N+1)'));\n        %weight = aggrFact*wCurve;\n        weight = wCurve;\n        %weight = aggrFact*ones(N+1,1);\n        %weight = zeros(N+1,1);\n        %hnled = weight.*min(hnled) + (1 - weight).*hnled;\n        %hnled = weight.*min(mean(hnled(echoBandRange)), hnled) + (1 - weight).*hnled;\n        %hnled = weight.*min(hnlSortQ, hnled) + (1 - weight).*hnled;\n\n        %hnlSortQV(kk) = mean(hnled);\n        %hnlPrefAvgV(kk) = mean(hnled(echoBandRange));\n\n        hnled = weight.*min(hnlPrefAvg, hnled) + (1 - weight).*hnled;\n\n        %od = aggrFact*(sqrt(linspace(0,1,N+1)') + aggrTerm);\n        %od = 4*(sqrt(linspace(0,1,N+1)') + 1/4);\n\n        %ovrdFact = (ovrdSm - 1) / sqrt(ovrdPos/(N+1));\n        %ovrdFact = ovrdSm / sqrt(echoBandRange(floor(length(echoBandRange)/2))/(N+1));\n        %od = ovrdFact*sqrt(linspace(0,1,N+1))' + 1;\n        %od = ovrdSm*ones(N+1,1).*abs(WFb(:,dIdx))/(max(abs(WFb(:,dIdx)))+1e-10);\n\n        %od = ovrdSm*ones(N+1,1);\n        %od = ovrdSm*WFbD.*(sqrt(linspace(0,1,N+1))' + 1);\n\n        od = ovrdSm*(sqrt(linspace(0,1,N+1))' + 1);\n        %od = 4*(sqrt(linspace(0,1,N+1))' + 1);\n\n        %od = 2*ones(N+1,1);\n        %od = 2*ones(N+1,1);\n        %sshift = ((1-hnled)*2-1).^3+1; \n        sshift = ones(N+1,1);\n\n        hnled = hnled.^(od.*sshift);\n\n        %if hnlg > 0.75\n            %if (suppState ~= 0)\n            %    transCtr = 0;\n            %end\n        %    suppState = 0;\n        %elseif hnlg < 0.6 & hnlg > 0.2\n        %    suppState = 1;\n        %elseif hnlg < 0.1\n            %hnled = zeros(N+1, 1);\n            %if (suppState ~= 2)\n            %    transCtr = 0;\n            %end\n        %    suppState = 2;\n        %else\n        %    if (suppState ~= 2)\n        %        transCtr = 0;\n        %    end\n        %    suppState = 2;\n        %end\n        %if suppState == 0\n        %    hnled = ones(N+1, 1);\n        %elseif suppState == 2\n        %    hnled = zeros(N+1, 1);\n        %end\n        %hnled(find(hnled < 0.1)) = 0;\n        %hnled = hnled.^2;\n        %if transCtr < 5\n            %hnl = 0.75*hnl + 0.25*hnled;\n        %    transCtr = transCtr + 1;\n        %else\n            hnl = hnled;\n        %end\n        %hnled(find(hnled < 0.05)) = 0;\n        ef = ef.*(hnl);\n\n        %ef = ef.*(min(1 - cohxd, cohed).^2);\n        %ef = ef.*((1-cohxd).^2);\n        \n        ovrdV(kk) = ovrdSm;\n        %ovrdV(kk) = dIdx;\n        %ovrdV(kk) = divergeFact;\n        %hnledAvg(kk) = 1-mean(1-cohedFast(echoBandRange));\n        hnledAvg(kk) = 1-mean(1-cohed(echoBandRange));\n        hnlxdAvg(kk) = 1-mean(cohxd(echoBandRange));\n        %hnlxdAvg(kk) = cohxd(5);\n        %hnlSortQV(kk) = mean(hnled);\n        hnlSortQV(kk) = hnlPrefAvgLow;\n        hnlPrefAvgV(kk) = hnlPrefAvg;\n        %hnlAvg(kk) = propLow;\n        %ef(N/2:end) = 0;\n        %ner = (sum(Sd) ./ (sum(Se.*(hnl.^2)) + 1e-10));\n\n\t\t% Comfort noise\n\t\tif (CNon)\n\t\t\tsnn=sqrt(Sym);\n\t\t\tsnn(1)=0; % Reject LF noise\n\t\t\tUn=snn.*exp(j*2*pi.*[0;rand(N-1,1);0]);\n\n\t\t\t% Weight comfort noise by suppression\n\t\t\tUn = sqrt(1-hnled.^2).*Un;\n\t\t\tFmix = ef + Un;\n\t\telse\n\t\t\tFmix = ef;\n\t\tend\n\n\t\t% Overlap and add in time domain for smoothness \n\t\ttmp = [Fmix ; flipud(conj(Fmix(2:N)))];\n\t\tmixw = wins.*real(ifft(tmp));\n\t\tmola  = mbuf(end-N+1:end) + mixw(1:N);\n\t\tmbuf = mixw;\n\t\tercn(pos:pos+N-1) = mola; \n\tend % NLPon\n\n    % Filter update\n\t%Ek2 = Ek ./(12*pn + 0.001); % Normalized error\n    %Ek2 = Ek2 * divergeFact;\n\t%Ek2 = Ek ./(pn + 0.001); % Normalized error\n\t%Ek2 = Ek ./(100*pn + 0.001); % Normalized error\n\n    %divergeIdx = find(abs(Ek) > abs(DD));\n    %divergeIdx = find(Se > Sd);\n    %threshMod = threshold*ones(N+1,1); \n    %if length(divergeIdx) > 0\n    %if sum(abs(Ek)) > sum(abs(DD))\n        %WFb(divergeIdx,:) = WFb(divergeIdx,:) .* repmat(sqrt(Sd(divergeIdx)./(Se(divergeIdx)+1e-10))),1,M);\n        %Ek2(divergeIdx) = Ek2(divergeIdx) .* sqrt(Sd(divergeIdx)./(Se(divergeIdx)+1e-10));\n        %Ek2(divergeIdx) = Ek2(divergeIdx) .* abs(DD(divergeIdx))./(abs(Ek(divergeIdx))+1e-10);\n        %WFb(divergeIdx,:) = WFbOld(divergeIdx,:);\n        %WFb = WFbOld;\n        %threshMod(divergeIdx) = threshMod(divergeIdx) .* abs(DD(divergeIdx))./(abs(Ek(divergeIdx))+1e-10);\n    %    threshMod(divergeIdx) = threshMod(divergeIdx) .* sqrt(Sd(divergeIdx)./(Se(divergeIdx)+1e-10));\n    %end\n\t\n\t%absEf = max(abs(Ek2), threshold);\n\t%absEf = ones(N+1,1)*threshold./absEf;\n\t%absEf = max(abs(Ek2), threshMod);\n\t%absEf = threshMod./absEf;\n\t%Ek2 = Ek2.*absEf;\n\n    %if sum(Se) <= sum(Sd)\n\n    %    mEk = mufb.*Ek2;\n    %    PP = conj(XFm).*(ones(M,1) * mEk')'; \n    %    tmp = [PP ; flipud(conj(PP(2:N,:)))];\n    %    IFPP = real(ifft(tmp));\n    %    PH = IFPP(1:N,:);\n    %    tmp = fft([PH;zeros(N,M)]);\n    %    FPH = tmp(1:N+1,:);\n    %    %WFbOld = WFb;\n    %    WFb = WFb + FPH;\n\n    %else\n    %    WF = WFbOld;\n    %end\n\n\t% Shift old FFTs\n\t%for m=M:-1:2\n\t%\tXFm(:,m) = XFm(:,m-1);    \n\t%\tYFm(:,m) = YFm(:,m-1);    \n\t%end\n    XFm(:,2:end) = XFm(:,1:end-1);\n    YFm(:,2:end) = YFm(:,1:end-1);\n    xfwm(:,2:end) = xfwm(:,1:end-1);\n    dfm(:,2:end) = dfm(:,1:end-1);\n\n\t%if mod(kk, floor(Nb/50)) == 0\n    %    fprintf(1, '.');\n\t%end\n\n\tif mod(kk, floor(Nb/100)) == 0\n\t%if mod(kk, floor(Nb/500)) == 0\n        progressbar(kk/Nb); \n        %figure(5)\n        %plot(abs(WFb));\n        %legend('1','2','3','4','5','6','7','8','9','10','11','12');\n        %title(kk*N/fs);\n        %figure(6)\n        %plot(WFbD);\n        %figure(6)\n        %plot(threshMod)\n        %if length(divergeIdx) > 0\n        %    plot(abs(DD))\n        %    hold on\n        %    plot(abs(Ek), 'r')\n        %    hold off\n            %plot(min(sqrt(Sd./(Se+1e-10)),1))\n            %axis([0 N 0 1]);\n        %end\n        %figure(6)\n        %plot(cohedFast);\n        %axis([1 N+1 0 1]);\n        %plot(WFbEn);\n\n        %figure(7)\n        %plot(weight);\n        %plot([cohxd 1-cohed]);\n        %plot([cohxd 1-cohed 1-cohedFast hnled]);\n        %plot([cohxd cohxdFast/max(cohxdFast)]);\n        %legend('cohxd', '1-cohed', '1-cohedFast');\n        %axis([1 65 0 1]);\n        %pause(0.5);\n        %overdrive\n    end\nend\nprogressbar(1);\n\n%figure(2);\n%plot([feat(:,1) feat(:,2)+1 feat(:,3)+2 mfeat+3]);\n%plot([feat(:,1) mfeat+1]);\n\n%figure(3);\n%plot(10*log10([dri erifb erifb3 ericn]));\n%legend('Near-end','Error','Post NLP','Final',4);\n% Compensate for delay\n%ercn=[ercn(N+1:end);zeros(N,1)];\n%ercn_=[ercn_(N+1:end);zeros(N,1)];\n\n%figure(11);\n%plot(cohxdSlow);\n\n%figure(12);\n%surf(cohxdSlow);\n%shading interp;\n\n%figure(13);\n%plot(overdriveM);\n\n%figure(14);\n%surf(overdriveM);\n%shading interp;\n\nfigure(10);\nt = (0:Nb)*N/fs;\nrrinSubSamp = rrin(N*(1:(Nb+1)));\nplot(t, rrinSubSamp/max(abs(rrinSubSamp)),'b');\nhold on\nplot(t, hnledAvg, 'r');\nplot(t, hnlxdAvg, 'g');\nplot(t, hnlSortQV, 'y');\nplot(t, hnlLocalMinV, 'k');\nplot(t, cohxdLocalMinV, 'c');\nplot(t, hnlPrefAvgV, 'm');\n%plot(t, cohxdAvg, 'r');\n%plot(cohxdFastAvg, 'r');\n%plot(cohxdAvgBad, 'k');\n%plot(t, cohedAvg, 'k');\n%plot(t, 1-cohedFastAvg, 'k');\n%plot(ssin(N*(1:floor(length(ssin)/N)))/max(abs(ssin)));\n%plot(echoBands,'r');\n%plot(overdrive, 'g');\n%plot(erfb(N*(1:floor(length(erfb)/N)))/max(abs(erfb)));\nhold off\ntightx;\n\nfigure(11)\nplot(t, ovrdV);\ntightx;\n%plot(mfeat,'r');\n%plot(1-cohxyp_,'r');\n%plot(Hnlxydp,'y');\n%plot(hnledp,'k');\n%plot(Hnlxydp, 'c');\n%plot(ccohpd_,'k');\n%plot(supplot_, 'g');\n%plot(ones(length(mfeat),1)*rr1_, 'k');\n%plot(ones(length(mfeat),1)*rr2_, 'k');\n%plot(N*(1:length(feat)), feat);\n%plot(Sep_,'r');\n%axis([1 floor(length(erfb)/N) -1 1])\n%hold off\n%plot(10*log10([Se_, Sx_, Seu_, real(sf_.*conj(sf_))]));\n%legend('Se','Sx','Seu','S');\n%figure(5)\n%plot([ercn ercn_]);\n\nfigure(12)\nplot(t, dIdxV);\n%plot(t, SLxV);\ntightx;\n\n%figure(13)\n%plot(t, [ekEnV dkEnV]);\n%plot(t, dkEnV./(ekEnV+1e-10));\n%tightx;\n\n%close(hh);\n%spclab(fs,ssin,erfb,ercn,'outxd.pcm');\n%spclab(fs,rrin,ssin,erfb,1.78*ercn,'vqeOut-1.pcm');\n%spclab(fs,erfb,'aecOutLp.pcm');\n%spclab(fs,rrin,ssin,erfb,1.78*ercn,'aecOut25.pcm','vqeOut-1.pcm');\n%spclab(fs,rrin,ssin,erfb,ercn,'aecOut-mba.pcm');\n%spclab(fs,rrin,ssin,erfb,ercn,'aecOut.pcm');\n%spclab(fs, ssin, erfb, ercn, 'out0.pcm');\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/aec/main/source/aec_core.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/*\n * The core AEC algorithm, which is presented with time-aligned signals.\n */\n\n#include <math.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"aec_core.h\"\n#include \"aec_rdft.h\"\n#include \"ring_buffer.h\"\n#include \"system_wrappers/interface/cpu_features_wrapper.h\"\n\n// Noise suppression\nstatic const int converged = 250;\n\n// Metrics\nstatic const int subCountLen = 4;\nstatic const int countLen = 50;\n\n// Quantities to control H band scaling for SWB input\nstatic const int flagHbandCn = 1; // flag for adding comfort noise in H band\nstatic const float cnScaleHband = (float)0.4; // scale for comfort noise in H band\n// Initial bin for averaging nlp gain in low band\nstatic const int freqAvgIc = PART_LEN / 2;\n\n/* Matlab code to produce table:\nwin = sqrt(hanning(63)); win = [0 ; win(1:32)];\nfprintf(1, '\\t%.14f, %.14f, %.14f,\\n', win);\n*/\n/*\nstatic const float sqrtHanning[33] = {\n    0.00000000000000, 0.04906767432742, 0.09801714032956,\n    0.14673047445536, 0.19509032201613, 0.24298017990326,\n    0.29028467725446, 0.33688985339222, 0.38268343236509,\n    0.42755509343028, 0.47139673682600, 0.51410274419322,\n    0.55557023301960, 0.59569930449243, 0.63439328416365,\n    0.67155895484702, 0.70710678118655, 0.74095112535496,\n    0.77301045336274, 0.80320753148064, 0.83146961230255,\n    0.85772861000027, 0.88192126434835, 0.90398929312344,\n    0.92387953251129, 0.94154406518302, 0.95694033573221,\n    0.97003125319454, 0.98078528040323, 0.98917650996478,\n    0.99518472667220, 0.99879545620517, 1.00000000000000\n};\n*/\n\nstatic const float sqrtHanning[65] = {\n    0.00000000000000f, 0.02454122852291f, 0.04906767432742f,\n    0.07356456359967f, 0.09801714032956f, 0.12241067519922f,\n    0.14673047445536f, 0.17096188876030f, 0.19509032201613f,\n    0.21910124015687f, 0.24298017990326f, 0.26671275747490f,\n    0.29028467725446f, 0.31368174039889f, 0.33688985339222f,\n    0.35989503653499f, 0.38268343236509f, 0.40524131400499f,\n    0.42755509343028f, 0.44961132965461f, 0.47139673682600f,\n    0.49289819222978f, 0.51410274419322f, 0.53499761988710f,\n    0.55557023301960f, 0.57580819141785f, 0.59569930449243f,\n    0.61523159058063f, 0.63439328416365f, 0.65317284295378f,\n    0.67155895484702f, 0.68954054473707f, 0.70710678118655f,\n    0.72424708295147f, 0.74095112535496f, 0.75720884650648f,\n    0.77301045336274f, 0.78834642762661f, 0.80320753148064f,\n    0.81758481315158f, 0.83146961230255f, 0.84485356524971f,\n    0.85772861000027f, 0.87008699110871f, 0.88192126434835f,\n    0.89322430119552f, 0.90398929312344f, 0.91420975570353f,\n    0.92387953251129f, 0.93299279883474f, 0.94154406518302f,\n    0.94952818059304f, 0.95694033573221f, 0.96377606579544f,\n    0.97003125319454f, 0.97570213003853f, 0.98078528040323f,\n    0.98527764238894f, 0.98917650996478f, 0.99247953459871f,\n    0.99518472667220f, 0.99729045667869f, 0.99879545620517f,\n    0.99969881869620f, 1.00000000000000f\n};\n\n/* Matlab code to produce table:\nweightCurve = [0 ; 0.3 * sqrt(linspace(0,1,64))' + 0.1];\nfprintf(1, '\\t%.4f, %.4f, %.4f, %.4f, %.4f, %.4f,\\n', weightCurve);\n*/\nconst float WebRtcAec_weightCurve[65] = {\n    0.0000f, 0.1000f, 0.1378f, 0.1535f, 0.1655f, 0.1756f,\n    0.1845f, 0.1926f, 0.2000f, 0.2069f, 0.2134f, 0.2195f,\n    0.2254f, 0.2309f, 0.2363f, 0.2414f, 0.2464f, 0.2512f,\n    0.2558f, 0.2604f, 0.2648f, 0.2690f, 0.2732f, 0.2773f,\n    0.2813f, 0.2852f, 0.2890f, 0.2927f, 0.2964f, 0.3000f,\n    0.3035f, 0.3070f, 0.3104f, 0.3138f, 0.3171f, 0.3204f,\n    0.3236f, 0.3268f, 0.3299f, 0.3330f, 0.3360f, 0.3390f,\n    0.3420f, 0.3449f, 0.3478f, 0.3507f, 0.3535f, 0.3563f,\n    0.3591f, 0.3619f, 0.3646f, 0.3673f, 0.3699f, 0.3726f,\n    0.3752f, 0.3777f, 0.3803f, 0.3828f, 0.3854f, 0.3878f,\n    0.3903f, 0.3928f, 0.3952f, 0.3976f, 0.4000f\n};\n\n/* Matlab code to produce table:\noverDriveCurve = [sqrt(linspace(0,1,65))' + 1];\nfprintf(1, '\\t%.4f, %.4f, %.4f, %.4f, %.4f, %.4f,\\n', overDriveCurve);\n*/\nconst float WebRtcAec_overDriveCurve[65] = {\n    1.0000f, 1.1250f, 1.1768f, 1.2165f, 1.2500f, 1.2795f,\n    1.3062f, 1.3307f, 1.3536f, 1.3750f, 1.3953f, 1.4146f,\n    1.4330f, 1.4507f, 1.4677f, 1.4841f, 1.5000f, 1.5154f,\n    1.5303f, 1.5449f, 1.5590f, 1.5728f, 1.5863f, 1.5995f,\n    1.6124f, 1.6250f, 1.6374f, 1.6495f, 1.6614f, 1.6731f,\n    1.6847f, 1.6960f, 1.7071f, 1.7181f, 1.7289f, 1.7395f,\n    1.7500f, 1.7603f, 1.7706f, 1.7806f, 1.7906f, 1.8004f,\n    1.8101f, 1.8197f, 1.8292f, 1.8385f, 1.8478f, 1.8570f,\n    1.8660f, 1.8750f, 1.8839f, 1.8927f, 1.9014f, 1.9100f,\n    1.9186f, 1.9270f, 1.9354f, 1.9437f, 1.9520f, 1.9601f,\n    1.9682f, 1.9763f, 1.9843f, 1.9922f, 2.0000f\n};\n\n// \"Private\" function prototypes.\nstatic void ProcessBlock(aec_t *aec, const short *farend,\n                              const short *nearend, const short *nearendH,\n                              short *out, short *outH);\n\nstatic void BufferFar(aec_t *aec, const short *farend, int farLen);\nstatic void FetchFar(aec_t *aec, short *farend, int farLen, int knownDelay);\n\nstatic void NonLinearProcessing(aec_t *aec, short *output, short *outputH);\n\nstatic void GetHighbandGain(const float *lambda, float *nlpGainHband);\n\n// Comfort_noise also computes noise for H band returned in comfortNoiseHband\nstatic void ComfortNoise(aec_t *aec, float efw[2][PART_LEN1],\n                                  complex_t *comfortNoiseHband,\n                                  const float *noisePow, const float *lambda);\n\nstatic void WebRtcAec_InitLevel(power_level_t *level);\nstatic void WebRtcAec_InitStats(stats_t *stats);\nstatic void UpdateLevel(power_level_t *level, const short *in);\nstatic void UpdateMetrics(aec_t *aec);\n\n__inline static float MulRe(float aRe, float aIm, float bRe, float bIm)\n{\n    return aRe * bRe - aIm * bIm;\n}\n\n__inline static float MulIm(float aRe, float aIm, float bRe, float bIm)\n{\n    return aRe * bIm + aIm * bRe;\n}\n\nstatic int CmpFloat(const void *a, const void *b)\n{\n    const float *da = (const float *)a;\n    const float *db = (const float *)b;\n\n    return (*da > *db) - (*da < *db);\n}\n\nint WebRtcAec_CreateAec(aec_t **aecInst)\n{\n    aec_t *aec = malloc(sizeof(aec_t));\n    *aecInst = aec;\n    if (aec == NULL) {\n        return -1;\n    }\n\n    if (WebRtcApm_CreateBuffer(&aec->farFrBuf, FRAME_LEN + PART_LEN) == -1) {\n        WebRtcAec_FreeAec(aec);\n        aec = NULL;\n        return -1;\n    }\n\n    if (WebRtcApm_CreateBuffer(&aec->nearFrBuf, FRAME_LEN + PART_LEN) == -1) {\n        WebRtcAec_FreeAec(aec);\n        aec = NULL;\n        return -1;\n    }\n\n    if (WebRtcApm_CreateBuffer(&aec->outFrBuf, FRAME_LEN + PART_LEN) == -1) {\n        WebRtcAec_FreeAec(aec);\n        aec = NULL;\n        return -1;\n    }\n\n    if (WebRtcApm_CreateBuffer(&aec->nearFrBufH, FRAME_LEN + PART_LEN) == -1) {\n        WebRtcAec_FreeAec(aec);\n        aec = NULL;\n        return -1;\n    }\n\n    if (WebRtcApm_CreateBuffer(&aec->outFrBufH, FRAME_LEN + PART_LEN) == -1) {\n        WebRtcAec_FreeAec(aec);\n        aec = NULL;\n        return -1;\n    }\n\n    return 0;\n}\n\nint WebRtcAec_FreeAec(aec_t *aec)\n{\n    if (aec == NULL) {\n        return -1;\n    }\n\n    WebRtcApm_FreeBuffer(aec->farFrBuf);\n    WebRtcApm_FreeBuffer(aec->nearFrBuf);\n    WebRtcApm_FreeBuffer(aec->outFrBuf);\n\n    WebRtcApm_FreeBuffer(aec->nearFrBufH);\n    WebRtcApm_FreeBuffer(aec->outFrBufH);\n\n    free(aec);\n    return 0;\n}\n\nstatic void FilterFar(aec_t *aec, float yf[2][PART_LEN1])\n{\n  int i;\n  for (i = 0; i < NR_PART; i++) {\n    int j;\n    int xPos = (i + aec->xfBufBlockPos) * PART_LEN1;\n    int pos = i * PART_LEN1;\n    // Check for wrap\n    if (i + aec->xfBufBlockPos >= NR_PART) {\n      xPos -= NR_PART*(PART_LEN1);\n    }\n\n    for (j = 0; j < PART_LEN1; j++) {\n      yf[0][j] += MulRe(aec->xfBuf[0][xPos + j], aec->xfBuf[1][xPos + j],\n                        aec->wfBuf[0][ pos + j], aec->wfBuf[1][ pos + j]);\n      yf[1][j] += MulIm(aec->xfBuf[0][xPos + j], aec->xfBuf[1][xPos + j],\n                        aec->wfBuf[0][ pos + j], aec->wfBuf[1][ pos + j]);\n    }\n  }\n}\n\nstatic void ScaleErrorSignal(aec_t *aec, float ef[2][PART_LEN1])\n{\n  int i;\n  float absEf;\n  for (i = 0; i < (PART_LEN1); i++) {\n    ef[0][i] /= (aec->xPow[i] + 1e-10f);\n    ef[1][i] /= (aec->xPow[i] + 1e-10f);\n    absEf = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]);\n\n    if (absEf > aec->errThresh) {\n      absEf = aec->errThresh / (absEf + 1e-10f);\n      ef[0][i] *= absEf;\n      ef[1][i] *= absEf;\n    }\n\n    // Stepsize factor\n    ef[0][i] *= aec->mu;\n    ef[1][i] *= aec->mu;\n  }\n}\n\nstatic void FilterAdaptation(aec_t *aec, float *fft, float ef[2][PART_LEN1]) {\n  int i, j;\n  for (i = 0; i < NR_PART; i++) {\n    int xPos = (i + aec->xfBufBlockPos)*(PART_LEN1);\n    int pos;\n    // Check for wrap\n    if (i + aec->xfBufBlockPos >= NR_PART) {\n      xPos -= NR_PART * PART_LEN1;\n    }\n\n    pos = i * PART_LEN1;\n\n#ifdef UNCONSTR\n    for (j = 0; j < PART_LEN1; j++) {\n      aec->wfBuf[pos + j][0] += MulRe(aec->xfBuf[xPos + j][0],\n                                      -aec->xfBuf[xPos + j][1],\n                                      ef[j][0], ef[j][1]);\n      aec->wfBuf[pos + j][1] += MulIm(aec->xfBuf[xPos + j][0],\n                                      -aec->xfBuf[xPos + j][1],\n                                      ef[j][0], ef[j][1]);\n    }\n#else\n    for (j = 0; j < PART_LEN; j++) {\n\n      fft[2 * j] = MulRe(aec->xfBuf[0][xPos + j],\n                         -aec->xfBuf[1][xPos + j],\n                         ef[0][j], ef[1][j]);\n      fft[2 * j + 1] = MulIm(aec->xfBuf[0][xPos + j],\n                             -aec->xfBuf[1][xPos + j],\n                             ef[0][j], ef[1][j]);\n    }\n    fft[1] = MulRe(aec->xfBuf[0][xPos + PART_LEN],\n                   -aec->xfBuf[1][xPos + PART_LEN],\n                   ef[0][PART_LEN], ef[1][PART_LEN]);\n\n    aec_rdft_inverse_128(fft);\n    memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN);\n\n    // fft scaling\n    {\n      float scale = 2.0f / PART_LEN2;\n      for (j = 0; j < PART_LEN; j++) {\n        fft[j] *= scale;\n      }\n    }\n    aec_rdft_forward_128(fft);\n\n    aec->wfBuf[0][pos] += fft[0];\n    aec->wfBuf[0][pos + PART_LEN] += fft[1];\n\n    for (j = 1; j < PART_LEN; j++) {\n      aec->wfBuf[0][pos + j] += fft[2 * j];\n      aec->wfBuf[1][pos + j] += fft[2 * j + 1];\n    }\n#endif // UNCONSTR\n  }\n}\n\nstatic void OverdriveAndSuppress(aec_t *aec, float hNl[PART_LEN1],\n                                 const float hNlFb,\n                                 float efw[2][PART_LEN1]) {\n  int i;\n  for (i = 0; i < PART_LEN1; i++) {\n    // Weight subbands\n    if (hNl[i] > hNlFb) {\n      hNl[i] = WebRtcAec_weightCurve[i] * hNlFb +\n          (1 - WebRtcAec_weightCurve[i]) * hNl[i];\n    }\n    hNl[i] = powf(hNl[i], aec->overDriveSm * WebRtcAec_overDriveCurve[i]);\n\n    // Suppress error signal\n    efw[0][i] *= hNl[i];\n    efw[1][i] *= hNl[i];\n\n    // Ooura fft returns incorrect sign on imaginary component. It matters here\n    // because we are making an additive change with comfort noise.\n    efw[1][i] *= -1;\n  }\n}\n\nWebRtcAec_FilterFar_t WebRtcAec_FilterFar;\nWebRtcAec_ScaleErrorSignal_t WebRtcAec_ScaleErrorSignal;\nWebRtcAec_FilterAdaptation_t WebRtcAec_FilterAdaptation;\nWebRtcAec_OverdriveAndSuppress_t WebRtcAec_OverdriveAndSuppress;\n\nint WebRtcAec_InitAec(aec_t *aec, int sampFreq)\n{\n    int i;\n\n    aec->sampFreq = sampFreq;\n\n    if (sampFreq == 8000) {\n        aec->mu = 0.6f;\n        aec->errThresh = 2e-6f;\n    }\n    else {\n        aec->mu = 0.5f;\n        aec->errThresh = 1.5e-6f;\n    }\n\n    if (WebRtcApm_InitBuffer(aec->farFrBuf) == -1) {\n        return -1;\n    }\n\n    if (WebRtcApm_InitBuffer(aec->nearFrBuf) == -1) {\n        return -1;\n    }\n\n    if (WebRtcApm_InitBuffer(aec->outFrBuf) == -1) {\n        return -1;\n    }\n\n    if (WebRtcApm_InitBuffer(aec->nearFrBufH) == -1) {\n        return -1;\n    }\n\n    if (WebRtcApm_InitBuffer(aec->outFrBufH) == -1) {\n        return -1;\n    }\n\n    // Default target suppression level\n    aec->targetSupp = -11.5;\n    aec->minOverDrive = 2.0;\n\n    // Sampling frequency multiplier\n    // SWB is processed as 160 frame size\n    if (aec->sampFreq == 32000) {\n      aec->mult = (short)aec->sampFreq / 16000;\n    }\n    else {\n        aec->mult = (short)aec->sampFreq / 8000;\n    }\n\n    aec->farBufWritePos = 0;\n    aec->farBufReadPos = 0;\n\n    aec->inSamples = 0;\n    aec->outSamples = 0;\n    aec->knownDelay = 0;\n\n    // Initialize buffers\n    memset(aec->farBuf, 0, sizeof(aec->farBuf));\n    memset(aec->xBuf, 0, sizeof(aec->xBuf));\n    memset(aec->dBuf, 0, sizeof(aec->dBuf));\n    memset(aec->eBuf, 0, sizeof(aec->eBuf));\n    // For H band\n    memset(aec->dBufH, 0, sizeof(aec->dBufH));\n\n    memset(aec->xPow, 0, sizeof(aec->xPow));\n    memset(aec->dPow, 0, sizeof(aec->dPow));\n    memset(aec->dInitMinPow, 0, sizeof(aec->dInitMinPow));\n    aec->noisePow = aec->dInitMinPow;\n    aec->noiseEstCtr = 0;\n\n    // Initial comfort noise power\n    for (i = 0; i < PART_LEN1; i++) {\n        aec->dMinPow[i] = 1.0e6f;\n    }\n\n    // Holds the last block written to\n    aec->xfBufBlockPos = 0;\n    // TODO: Investigate need for these initializations. Deleting them doesn't\n    //       change the output at all and yields 0.4% overall speedup.\n    memset(aec->xfBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1);\n    memset(aec->wfBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1);\n    memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1);\n    memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1);\n    memset(aec->xfwBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1);\n    memset(aec->se, 0, sizeof(float) * PART_LEN1);\n\n    // To prevent numerical instability in the first block.\n    for (i = 0; i < PART_LEN1; i++) {\n        aec->sd[i] = 1;\n    }\n    for (i = 0; i < PART_LEN1; i++) {\n        aec->sx[i] = 1;\n    }\n\n    memset(aec->hNs, 0, sizeof(aec->hNs));\n    memset(aec->outBuf, 0, sizeof(float) * PART_LEN);\n\n    aec->hNlFbMin = 1;\n    aec->hNlFbLocalMin = 1;\n    aec->hNlXdAvgMin = 1;\n    aec->hNlNewMin = 0;\n    aec->hNlMinCtr = 0;\n    aec->overDrive = 2;\n    aec->overDriveSm = 2;\n    aec->delayIdx = 0;\n    aec->stNearState = 0;\n    aec->echoState = 0;\n    aec->divergeState = 0;\n\n    aec->seed = 777;\n    aec->delayEstCtr = 0;\n\n    // Metrics disabled by default\n    aec->metricsMode = 0;\n    WebRtcAec_InitMetrics(aec);\n\n    // Assembly optimization\n    WebRtcAec_FilterFar = FilterFar;\n    WebRtcAec_ScaleErrorSignal = ScaleErrorSignal;\n    WebRtcAec_FilterAdaptation = FilterAdaptation;\n    WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress;\n    if (WebRtc_GetCPUInfo(kSSE2)) {\n#if defined(WEBRTC_USE_SSE2)\n      WebRtcAec_InitAec_SSE2();\n#endif\n    }\n    aec_rdft_init();\n\n    return 0;\n}\n\nvoid WebRtcAec_InitMetrics(aec_t *aec)\n{\n    aec->stateCounter = 0;\n    WebRtcAec_InitLevel(&aec->farlevel);\n    WebRtcAec_InitLevel(&aec->nearlevel);\n    WebRtcAec_InitLevel(&aec->linoutlevel);\n    WebRtcAec_InitLevel(&aec->nlpoutlevel);\n\n    WebRtcAec_InitStats(&aec->erl);\n    WebRtcAec_InitStats(&aec->erle);\n    WebRtcAec_InitStats(&aec->aNlp);\n    WebRtcAec_InitStats(&aec->rerl);\n}\n\n\nvoid WebRtcAec_ProcessFrame(aec_t *aec, const short *farend,\n                       const short *nearend, const short *nearendH,\n                       short *out, short *outH,\n                       int knownDelay)\n{\n    short farBl[PART_LEN], nearBl[PART_LEN], outBl[PART_LEN];\n    short farFr[FRAME_LEN];\n    // For H band\n    short nearBlH[PART_LEN], outBlH[PART_LEN];\n\n    int size = 0;\n\n    // initialize: only used for SWB\n    memset(nearBlH, 0, sizeof(nearBlH));\n    memset(outBlH, 0, sizeof(outBlH));\n\n    // Buffer the current frame.\n    // Fetch an older one corresponding to the delay.\n    BufferFar(aec, farend, FRAME_LEN);\n    FetchFar(aec, farFr, FRAME_LEN, knownDelay);\n\n    // Buffer the synchronized far and near frames,\n    // to pass the smaller blocks individually.\n    WebRtcApm_WriteBuffer(aec->farFrBuf, farFr, FRAME_LEN);\n    WebRtcApm_WriteBuffer(aec->nearFrBuf, nearend, FRAME_LEN);\n    // For H band\n    if (aec->sampFreq == 32000) {\n        WebRtcApm_WriteBuffer(aec->nearFrBufH, nearendH, FRAME_LEN);\n    }\n\n    // Process as many blocks as possible.\n    while (WebRtcApm_get_buffer_size(aec->farFrBuf) >= PART_LEN) {\n\n        WebRtcApm_ReadBuffer(aec->farFrBuf, farBl, PART_LEN);\n        WebRtcApm_ReadBuffer(aec->nearFrBuf, nearBl, PART_LEN);\n\n        // For H band\n        if (aec->sampFreq == 32000) {\n            WebRtcApm_ReadBuffer(aec->nearFrBufH, nearBlH, PART_LEN);\n        }\n\n        ProcessBlock(aec, farBl, nearBl, nearBlH, outBl, outBlH);\n\n        WebRtcApm_WriteBuffer(aec->outFrBuf, outBl, PART_LEN);\n        // For H band\n        if (aec->sampFreq == 32000) {\n            WebRtcApm_WriteBuffer(aec->outFrBufH, outBlH, PART_LEN);\n        }\n    }\n\n    // Stuff the out buffer if we have less than a frame to output.\n    // This should only happen for the first frame.\n    size = WebRtcApm_get_buffer_size(aec->outFrBuf);\n    if (size < FRAME_LEN) {\n        WebRtcApm_StuffBuffer(aec->outFrBuf, FRAME_LEN - size);\n        if (aec->sampFreq == 32000) {\n            WebRtcApm_StuffBuffer(aec->outFrBufH, FRAME_LEN - size);\n        }\n    }\n\n    // Obtain an output frame.\n    WebRtcApm_ReadBuffer(aec->outFrBuf, out, FRAME_LEN);\n    // For H band\n    if (aec->sampFreq == 32000) {\n        WebRtcApm_ReadBuffer(aec->outFrBufH, outH, FRAME_LEN);\n    }\n}\n\nstatic void ProcessBlock(aec_t *aec, const short *farend,\n                         const short *nearend, const short *nearendH,\n                         short *output, short *outputH)\n{\n    int i;\n    float d[PART_LEN], y[PART_LEN], e[PART_LEN], dH[PART_LEN];\n    short eInt16[PART_LEN];\n    float scale;\n\n    float fft[PART_LEN2];\n    float xf[2][PART_LEN1], yf[2][PART_LEN1], ef[2][PART_LEN1];\n    complex_t df[PART_LEN1];\n\n    const float gPow[2] = {0.9f, 0.1f};\n\n    // Noise estimate constants.\n    const int noiseInitBlocks = 500 * aec->mult;\n    const float step = 0.1f;\n    const float ramp = 1.0002f;\n    const float gInitNoise[2] = {0.999f, 0.001f};\n\n#ifdef AEC_DEBUG\n    fwrite(farend, sizeof(short), PART_LEN, aec->farFile);\n    fwrite(nearend, sizeof(short), PART_LEN, aec->nearFile);\n#endif\n\n    memset(dH, 0, sizeof(dH));\n\n    // ---------- Ooura fft ----------\n    // Concatenate old and new farend blocks.\n    for (i = 0; i < PART_LEN; i++) {\n        aec->xBuf[i + PART_LEN] = (float)farend[i];\n        d[i] = (float)nearend[i];\n    }\n\n    if (aec->sampFreq == 32000) {\n        for (i = 0; i < PART_LEN; i++) {\n            dH[i] = (float)nearendH[i];\n        }\n    }\n\n    memcpy(fft, aec->xBuf, sizeof(float) * PART_LEN2);\n    memcpy(aec->dBuf + PART_LEN, d, sizeof(float) * PART_LEN);\n    // For H band\n    if (aec->sampFreq == 32000) {\n        memcpy(aec->dBufH + PART_LEN, dH, sizeof(float) * PART_LEN);\n    }\n\n    aec_rdft_forward_128(fft);\n\n    // Far fft\n    xf[1][0] = 0;\n    xf[1][PART_LEN] = 0;\n    xf[0][0] = fft[0];\n    xf[0][PART_LEN] = fft[1];\n\n    for (i = 1; i < PART_LEN; i++) {\n        xf[0][i] = fft[2 * i];\n        xf[1][i] = fft[2 * i + 1];\n    }\n\n    // Near fft\n    memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2);\n    aec_rdft_forward_128(fft);\n    df[0][1] = 0;\n    df[PART_LEN][1] = 0;\n    df[0][0] = fft[0];\n    df[PART_LEN][0] = fft[1];\n\n    for (i = 1; i < PART_LEN; i++) {\n        df[i][0] = fft[2 * i];\n        df[i][1] = fft[2 * i + 1];\n    }\n\n    // Power smoothing\n    for (i = 0; i < PART_LEN1; i++) {\n        aec->xPow[i] = gPow[0] * aec->xPow[i] + gPow[1] * NR_PART *\n            (xf[0][i] * xf[0][i] + xf[1][i] * xf[1][i]);\n        aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] *\n            (df[i][0] * df[i][0] + df[i][1] * df[i][1]);\n    }\n\n    // Estimate noise power. Wait until dPow is more stable.\n    if (aec->noiseEstCtr > 50) {\n        for (i = 0; i < PART_LEN1; i++) {\n            if (aec->dPow[i] < aec->dMinPow[i]) {\n                aec->dMinPow[i] = (aec->dPow[i] + step * (aec->dMinPow[i] -\n                    aec->dPow[i])) * ramp;\n            }\n            else {\n                aec->dMinPow[i] *= ramp;\n            }\n        }\n    }\n\n    // Smooth increasing noise power from zero at the start,\n    // to avoid a sudden burst of comfort noise.\n    if (aec->noiseEstCtr < noiseInitBlocks) {\n        aec->noiseEstCtr++;\n        for (i = 0; i < PART_LEN1; i++) {\n            if (aec->dMinPow[i] > aec->dInitMinPow[i]) {\n                aec->dInitMinPow[i] = gInitNoise[0] * aec->dInitMinPow[i] +\n                    gInitNoise[1] * aec->dMinPow[i];\n            }\n            else {\n                aec->dInitMinPow[i] = aec->dMinPow[i];\n            }\n        }\n        aec->noisePow = aec->dInitMinPow;\n    }\n    else {\n        aec->noisePow = aec->dMinPow;\n    }\n\n\n    // Update the xfBuf block position.\n    aec->xfBufBlockPos--;\n    if (aec->xfBufBlockPos == -1) {\n        aec->xfBufBlockPos = NR_PART - 1;\n    }\n\n    // Buffer xf\n    memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, xf[0],\n           sizeof(float) * PART_LEN1);\n    memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, xf[1],\n           sizeof(float) * PART_LEN1);\n\n    memset(yf[0], 0, sizeof(float) * (PART_LEN1 * 2));\n\n    // Filter far\n    WebRtcAec_FilterFar(aec, yf);\n\n    // Inverse fft to obtain echo estimate and error.\n    fft[0] = yf[0][0];\n    fft[1] = yf[0][PART_LEN];\n    for (i = 1; i < PART_LEN; i++) {\n        fft[2 * i] = yf[0][i];\n        fft[2 * i + 1] = yf[1][i];\n    }\n    aec_rdft_inverse_128(fft);\n\n    scale = 2.0f / PART_LEN2;\n    for (i = 0; i < PART_LEN; i++) {\n        y[i] = fft[PART_LEN + i] * scale; // fft scaling\n    }\n\n    for (i = 0; i < PART_LEN; i++) {\n        e[i] = d[i] - y[i];\n    }\n\n    // Error fft\n    memcpy(aec->eBuf + PART_LEN, e, sizeof(float) * PART_LEN);\n    memset(fft, 0, sizeof(float) * PART_LEN);\n    memcpy(fft + PART_LEN, e, sizeof(float) * PART_LEN);\n    aec_rdft_forward_128(fft);\n\n    ef[1][0] = 0;\n    ef[1][PART_LEN] = 0;\n    ef[0][0] = fft[0];\n    ef[0][PART_LEN] = fft[1];\n    for (i = 1; i < PART_LEN; i++) {\n        ef[0][i] = fft[2 * i];\n        ef[1][i] = fft[2 * i + 1];\n    }\n\n    // Scale error signal inversely with far power.\n    WebRtcAec_ScaleErrorSignal(aec, ef);\n    // Filter adaptation\n    WebRtcAec_FilterAdaptation(aec, fft, ef);\n\n    NonLinearProcessing(aec, output, outputH);\n\n#ifdef AEC_DEBUG\n    for (i = 0; i < PART_LEN; i++) {\n        eInt16[i] = (short)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, e[i],\n            WEBRTC_SPL_WORD16_MIN);\n    }\n#endif\n\n    if (aec->metricsMode == 1) {\n        for (i = 0; i < PART_LEN; i++) {\n            eInt16[i] = (short)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, e[i],\n                WEBRTC_SPL_WORD16_MIN);\n        }\n\n        // Update power levels and echo metrics\n        UpdateLevel(&aec->farlevel, farend);\n        UpdateLevel(&aec->nearlevel, nearend);\n        UpdateLevel(&aec->linoutlevel, eInt16);\n        UpdateLevel(&aec->nlpoutlevel, output);\n        UpdateMetrics(aec);\n    }\n\n#ifdef AEC_DEBUG\n    fwrite(eInt16, sizeof(short), PART_LEN, aec->outLpFile);\n    fwrite(output, sizeof(short), PART_LEN, aec->outFile);\n#endif\n}\n\nstatic void NonLinearProcessing(aec_t *aec, short *output, short *outputH)\n{\n    float efw[2][PART_LEN1], dfw[2][PART_LEN1];\n    complex_t xfw[PART_LEN1];\n    complex_t comfortNoiseHband[PART_LEN1];\n    float fft[PART_LEN2];\n    float scale, dtmp;\n    float nlpGainHband;\n    int i, j, pos;\n\n    // Coherence and non-linear filter\n    float cohde[PART_LEN1], cohxd[PART_LEN1];\n    float hNlDeAvg, hNlXdAvg;\n    float hNl[PART_LEN1];\n    float hNlPref[PREF_BAND_SIZE];\n    float hNlFb = 0, hNlFbLow = 0;\n    const float prefBandQuant = 0.75f, prefBandQuantLow = 0.5f;\n    const int prefBandSize = PREF_BAND_SIZE / aec->mult;\n    const int minPrefBand = 4 / aec->mult;\n\n    // Near and error power sums\n    float sdSum = 0, seSum = 0;\n\n    // Power estimate smoothing coefficients\n    const float gCoh[2][2] = {{0.9f, 0.1f}, {0.93f, 0.07f}};\n    const float *ptrGCoh = gCoh[aec->mult - 1];\n\n    // Filter energey\n    float wfEnMax = 0, wfEn = 0;\n    const int delayEstInterval = 10 * aec->mult;\n\n    aec->delayEstCtr++;\n    if (aec->delayEstCtr == delayEstInterval) {\n        aec->delayEstCtr = 0;\n    }\n\n    // initialize comfort noise for H band\n    memset(comfortNoiseHband, 0, sizeof(comfortNoiseHband));\n    nlpGainHband = (float)0.0;\n    dtmp = (float)0.0;\n\n    // Measure energy in each filter partition to determine delay.\n    // TODO: Spread by computing one partition per block?\n    if (aec->delayEstCtr == 0) {\n        wfEnMax = 0;\n        aec->delayIdx = 0;\n        for (i = 0; i < NR_PART; i++) {\n            pos = i * PART_LEN1;\n            wfEn = 0;\n            for (j = 0; j < PART_LEN1; j++) {\n                wfEn += aec->wfBuf[0][pos + j] * aec->wfBuf[0][pos + j] +\n                    aec->wfBuf[1][pos + j] * aec->wfBuf[1][pos + j];\n            }\n\n            if (wfEn > wfEnMax) {\n                wfEnMax = wfEn;\n                aec->delayIdx = i;\n            }\n        }\n    }\n\n    // NLP\n    // Windowed far fft\n    for (i = 0; i < PART_LEN; i++) {\n        fft[i] = aec->xBuf[i] * sqrtHanning[i];\n        fft[PART_LEN + i] = aec->xBuf[PART_LEN + i] * sqrtHanning[PART_LEN - i];\n    }\n    aec_rdft_forward_128(fft);\n\n    xfw[0][1] = 0;\n    xfw[PART_LEN][1] = 0;\n    xfw[0][0] = fft[0];\n    xfw[PART_LEN][0] = fft[1];\n    for (i = 1; i < PART_LEN; i++) {\n        xfw[i][0] = fft[2 * i];\n        xfw[i][1] = fft[2 * i + 1];\n    }\n\n    // Buffer far.\n    memcpy(aec->xfwBuf, xfw, sizeof(xfw));\n\n    // Use delayed far.\n    memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1, sizeof(xfw));\n\n    // Windowed near fft\n    for (i = 0; i < PART_LEN; i++) {\n        fft[i] = aec->dBuf[i] * sqrtHanning[i];\n        fft[PART_LEN + i] = aec->dBuf[PART_LEN + i] * sqrtHanning[PART_LEN - i];\n    }\n    aec_rdft_forward_128(fft);\n\n    dfw[1][0] = 0;\n    dfw[1][PART_LEN] = 0;\n    dfw[0][0] = fft[0];\n    dfw[0][PART_LEN] = fft[1];\n    for (i = 1; i < PART_LEN; i++) {\n        dfw[0][i] = fft[2 * i];\n        dfw[1][i] = fft[2 * i + 1];\n    }\n\n    // Windowed error fft\n    for (i = 0; i < PART_LEN; i++) {\n        fft[i] = aec->eBuf[i] * sqrtHanning[i];\n        fft[PART_LEN + i] = aec->eBuf[PART_LEN + i] * sqrtHanning[PART_LEN - i];\n    }\n    aec_rdft_forward_128(fft);\n    efw[1][0] = 0;\n    efw[1][PART_LEN] = 0;\n    efw[0][0] = fft[0];\n    efw[0][PART_LEN] = fft[1];\n    for (i = 1; i < PART_LEN; i++) {\n        efw[0][i] = fft[2 * i];\n        efw[1][i] = fft[2 * i + 1];\n    }\n\n    // Smoothed PSD\n    for (i = 0; i < PART_LEN1; i++) {\n        aec->sd[i] = ptrGCoh[0] * aec->sd[i] + ptrGCoh[1] *\n            (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]);\n        aec->se[i] = ptrGCoh[0] * aec->se[i] + ptrGCoh[1] *\n            (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]);\n        // We threshold here to protect against the ill-effects of a zero farend.\n        // The threshold is not arbitrarily chosen, but balances protection and\n        // adverse interaction with the algorithm's tuning.\n        // TODO: investigate further why this is so sensitive.\n        aec->sx[i] = ptrGCoh[0] * aec->sx[i] + ptrGCoh[1] *\n            WEBRTC_SPL_MAX(xfw[i][0] * xfw[i][0] + xfw[i][1] * xfw[i][1], 15);\n\n        aec->sde[i][0] = ptrGCoh[0] * aec->sde[i][0] + ptrGCoh[1] *\n            (dfw[0][i] * efw[0][i] + dfw[1][i] * efw[1][i]);\n        aec->sde[i][1] = ptrGCoh[0] * aec->sde[i][1] + ptrGCoh[1] *\n            (dfw[0][i] * efw[1][i] - dfw[1][i] * efw[0][i]);\n\n        aec->sxd[i][0] = ptrGCoh[0] * aec->sxd[i][0] + ptrGCoh[1] *\n            (dfw[0][i] * xfw[i][0] + dfw[1][i] * xfw[i][1]);\n        aec->sxd[i][1] = ptrGCoh[0] * aec->sxd[i][1] + ptrGCoh[1] *\n            (dfw[0][i] * xfw[i][1] - dfw[1][i] * xfw[i][0]);\n\n        sdSum += aec->sd[i];\n        seSum += aec->se[i];\n    }\n\n    // Divergent filter safeguard.\n    if (aec->divergeState == 0) {\n        if (seSum > sdSum) {\n            aec->divergeState = 1;\n        }\n    }\n    else {\n        if (seSum * 1.05f < sdSum) {\n            aec->divergeState = 0;\n        }\n    }\n\n    if (aec->divergeState == 1) {\n        memcpy(efw, dfw, sizeof(efw));\n    }\n\n    // Reset if error is significantly larger than nearend (13 dB).\n    if (seSum > (19.95f * sdSum)) {\n        memset(aec->wfBuf, 0, sizeof(aec->wfBuf));\n    }\n\n    // Subband coherence\n    for (i = 0; i < PART_LEN1; i++) {\n        cohde[i] = (aec->sde[i][0] * aec->sde[i][0] + aec->sde[i][1] * aec->sde[i][1]) /\n            (aec->sd[i] * aec->se[i] + 1e-10f);\n        cohxd[i] = (aec->sxd[i][0] * aec->sxd[i][0] + aec->sxd[i][1] * aec->sxd[i][1]) /\n            (aec->sx[i] * aec->sd[i] + 1e-10f);\n    }\n\n    hNlXdAvg = 0;\n    for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) {\n        hNlXdAvg += cohxd[i];\n    }\n    hNlXdAvg /= prefBandSize;\n    hNlXdAvg = 1 - hNlXdAvg;\n\n    hNlDeAvg = 0;\n    for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) {\n        hNlDeAvg += cohde[i];\n    }\n    hNlDeAvg /= prefBandSize;\n\n    if (hNlXdAvg < 0.75f && hNlXdAvg < aec->hNlXdAvgMin) {\n        aec->hNlXdAvgMin = hNlXdAvg;\n    }\n\n    if (hNlDeAvg > 0.98f && hNlXdAvg > 0.9f) {\n        aec->stNearState = 1;\n    }\n    else if (hNlDeAvg < 0.95f || hNlXdAvg < 0.8f) {\n        aec->stNearState = 0;\n    }\n\n    if (aec->hNlXdAvgMin == 1) {\n        aec->echoState = 0;\n        aec->overDrive = aec->minOverDrive;\n\n        if (aec->stNearState == 1) {\n            memcpy(hNl, cohde, sizeof(hNl));\n            hNlFb = hNlDeAvg;\n            hNlFbLow = hNlDeAvg;\n        }\n        else {\n            for (i = 0; i < PART_LEN1; i++) {\n                hNl[i] = 1 - cohxd[i];\n            }\n            hNlFb = hNlXdAvg;\n            hNlFbLow = hNlXdAvg;\n        }\n    }\n    else {\n\n        if (aec->stNearState == 1) {\n            aec->echoState = 0;\n            memcpy(hNl, cohde, sizeof(hNl));\n            hNlFb = hNlDeAvg;\n            hNlFbLow = hNlDeAvg;\n        }\n        else {\n            aec->echoState = 1;\n            for (i = 0; i < PART_LEN1; i++) {\n                hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]);\n            }\n\n            // Select an order statistic from the preferred bands.\n            // TODO: Using quicksort now, but a selection algorithm may be preferred.\n            memcpy(hNlPref, &hNl[minPrefBand], sizeof(float) * prefBandSize);\n            qsort(hNlPref, prefBandSize, sizeof(float), CmpFloat);\n            hNlFb = hNlPref[(int)floor(prefBandQuant * (prefBandSize - 1))];\n            hNlFbLow = hNlPref[(int)floor(prefBandQuantLow * (prefBandSize - 1))];\n        }\n    }\n\n    // Track the local filter minimum to determine suppression overdrive.\n    if (hNlFbLow < 0.6f && hNlFbLow < aec->hNlFbLocalMin) {\n        aec->hNlFbLocalMin = hNlFbLow;\n        aec->hNlFbMin = hNlFbLow;\n        aec->hNlNewMin = 1;\n        aec->hNlMinCtr = 0;\n    }\n    aec->hNlFbLocalMin = WEBRTC_SPL_MIN(aec->hNlFbLocalMin + 0.0008f / aec->mult, 1);\n    aec->hNlXdAvgMin = WEBRTC_SPL_MIN(aec->hNlXdAvgMin + 0.0006f / aec->mult, 1);\n\n    if (aec->hNlNewMin == 1) {\n        aec->hNlMinCtr++;\n    }\n    if (aec->hNlMinCtr == 2) {\n        aec->hNlNewMin = 0;\n        aec->hNlMinCtr = 0;\n        aec->overDrive = WEBRTC_SPL_MAX(aec->targetSupp /\n            ((float)log(aec->hNlFbMin + 1e-10f) + 1e-10f), aec->minOverDrive);\n    }\n\n    // Smooth the overdrive.\n    if (aec->overDrive < aec->overDriveSm) {\n      aec->overDriveSm = 0.99f * aec->overDriveSm + 0.01f * aec->overDrive;\n    }\n    else {\n      aec->overDriveSm = 0.9f * aec->overDriveSm + 0.1f * aec->overDrive;\n    }\n\n    WebRtcAec_OverdriveAndSuppress(aec, hNl, hNlFb, efw);\n\n    // Add comfort noise.\n    ComfortNoise(aec, efw, comfortNoiseHband, aec->noisePow, hNl);\n\n    // Inverse error fft.\n    fft[0] = efw[0][0];\n    fft[1] = efw[0][PART_LEN];\n    for (i = 1; i < PART_LEN; i++) {\n        fft[2*i] = efw[0][i];\n        // Sign change required by Ooura fft.\n        fft[2*i + 1] = -efw[1][i];\n    }\n    aec_rdft_inverse_128(fft);\n\n    // Overlap and add to obtain output.\n    scale = 2.0f / PART_LEN2;\n    for (i = 0; i < PART_LEN; i++) {\n        fft[i] *= scale; // fft scaling\n        fft[i] = fft[i]*sqrtHanning[i] + aec->outBuf[i];\n\n        // Saturation protection\n        output[i] = (short)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, fft[i],\n            WEBRTC_SPL_WORD16_MIN);\n\n        fft[PART_LEN + i] *= scale; // fft scaling\n        aec->outBuf[i] = fft[PART_LEN + i] * sqrtHanning[PART_LEN - i];\n    }\n\n    // For H band\n    if (aec->sampFreq == 32000) {\n\n        // H band gain\n        // average nlp over low band: average over second half of freq spectrum\n        // (4->8khz)\n        GetHighbandGain(hNl, &nlpGainHband);\n\n        // Inverse comfort_noise\n        if (flagHbandCn == 1) {\n            fft[0] = comfortNoiseHband[0][0];\n            fft[1] = comfortNoiseHband[PART_LEN][0];\n            for (i = 1; i < PART_LEN; i++) {\n                fft[2*i] = comfortNoiseHband[i][0];\n                fft[2*i + 1] = comfortNoiseHband[i][1];\n            }\n            aec_rdft_inverse_128(fft);\n            scale = 2.0f / PART_LEN2;\n        }\n\n        // compute gain factor\n        for (i = 0; i < PART_LEN; i++) {\n            dtmp = (float)aec->dBufH[i];\n            dtmp = (float)dtmp * nlpGainHband; // for variable gain\n\n            // add some comfort noise where Hband is attenuated\n            if (flagHbandCn == 1) {\n                fft[i] *= scale; // fft scaling\n                dtmp += cnScaleHband * fft[i];\n            }\n\n            // Saturation protection\n            outputH[i] = (short)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, dtmp,\n                WEBRTC_SPL_WORD16_MIN);\n         }\n    }\n\n    // Copy the current block to the old position.\n    memcpy(aec->xBuf, aec->xBuf + PART_LEN, sizeof(float) * PART_LEN);\n    memcpy(aec->dBuf, aec->dBuf + PART_LEN, sizeof(float) * PART_LEN);\n    memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN);\n\n    // Copy the current block to the old position for H band\n    if (aec->sampFreq == 32000) {\n        memcpy(aec->dBufH, aec->dBufH + PART_LEN, sizeof(float) * PART_LEN);\n    }\n\n    memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf, sizeof(aec->xfwBuf) -\n        sizeof(complex_t) * PART_LEN1);\n}\n\nstatic void GetHighbandGain(const float *lambda, float *nlpGainHband)\n{\n    int i;\n\n    nlpGainHband[0] = (float)0.0;\n    for (i = freqAvgIc; i < PART_LEN1 - 1; i++) {\n        nlpGainHband[0] += lambda[i];\n    }\n    nlpGainHband[0] /= (float)(PART_LEN1 - 1 - freqAvgIc);\n}\n\nstatic void ComfortNoise(aec_t *aec, float efw[2][PART_LEN1],\n    complex_t *comfortNoiseHband, const float *noisePow, const float *lambda)\n{\n    int i, num;\n    float rand[PART_LEN];\n    float noise, noiseAvg, tmp, tmpAvg;\n    WebRtc_Word16 randW16[PART_LEN];\n    complex_t u[PART_LEN1];\n\n    const float pi2 = 6.28318530717959f;\n\n    // Generate a uniform random array on [0 1]\n    WebRtcSpl_RandUArray(randW16, PART_LEN, &aec->seed);\n    for (i = 0; i < PART_LEN; i++) {\n        rand[i] = ((float)randW16[i]) / 32768;\n    }\n\n    // Reject LF noise\n    u[0][0] = 0;\n    u[0][1] = 0;\n    for (i = 1; i < PART_LEN1; i++) {\n        tmp = pi2 * rand[i - 1];\n\n        noise = sqrtf(noisePow[i]);\n        u[i][0] = noise * (float)cos(tmp);\n        u[i][1] = -noise * (float)sin(tmp);\n    }\n    u[PART_LEN][1] = 0;\n\n    for (i = 0; i < PART_LEN1; i++) {\n        // This is the proper weighting to match the background noise power\n        tmp = sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0));\n        //tmp = 1 - lambda[i];\n        efw[0][i] += tmp * u[i][0];\n        efw[1][i] += tmp * u[i][1];\n    }\n\n    // For H band comfort noise\n    // TODO: don't compute noise and \"tmp\" twice. Use the previous results.\n    noiseAvg = 0.0;\n    tmpAvg = 0.0;\n    num = 0;\n    if (aec->sampFreq == 32000 && flagHbandCn == 1) {\n\n        // average noise scale\n        // average over second half of freq spectrum (i.e., 4->8khz)\n        // TODO: we shouldn't need num. We know how many elements we're summing.\n        for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) {\n            num++;\n            noiseAvg += sqrtf(noisePow[i]);\n        }\n        noiseAvg /= (float)num;\n\n        // average nlp scale\n        // average over second half of freq spectrum (i.e., 4->8khz)\n        // TODO: we shouldn't need num. We know how many elements we're summing.\n        num = 0;\n        for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) {\n            num++;\n            tmpAvg += sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0));\n        }\n        tmpAvg /= (float)num;\n\n        // Use average noise for H band\n        // TODO: we should probably have a new random vector here.\n        // Reject LF noise\n        u[0][0] = 0;\n        u[0][1] = 0;\n        for (i = 1; i < PART_LEN1; i++) {\n            tmp = pi2 * rand[i - 1];\n\n            // Use average noise for H band\n            u[i][0] = noiseAvg * (float)cos(tmp);\n            u[i][1] = -noiseAvg * (float)sin(tmp);\n        }\n        u[PART_LEN][1] = 0;\n\n        for (i = 0; i < PART_LEN1; i++) {\n            // Use average NLP weight for H band\n            comfortNoiseHband[i][0] = tmpAvg * u[i][0];\n            comfortNoiseHband[i][1] = tmpAvg * u[i][1];\n        }\n    }\n}\n\n// Buffer the farend to account for knownDelay\nstatic void BufferFar(aec_t *aec, const short *farend, int farLen)\n{\n    int writeLen = farLen, writePos = 0;\n\n    // Check if the write position must be wrapped.\n    while (aec->farBufWritePos + writeLen > FAR_BUF_LEN) {\n\n        // Write to remaining buffer space before wrapping.\n        writeLen = FAR_BUF_LEN - aec->farBufWritePos;\n        memcpy(aec->farBuf + aec->farBufWritePos, farend + writePos,\n            sizeof(short) * writeLen);\n        aec->farBufWritePos = 0;\n        writePos = writeLen;\n        writeLen = farLen - writeLen;\n    }\n\n    memcpy(aec->farBuf + aec->farBufWritePos, farend + writePos,\n        sizeof(short) * writeLen);\n    aec->farBufWritePos +=  writeLen;\n}\n\nstatic void FetchFar(aec_t *aec, short *farend, int farLen, int knownDelay)\n{\n    int readLen = farLen, readPos = 0, delayChange = knownDelay - aec->knownDelay;\n\n    aec->farBufReadPos -= delayChange;\n\n    // Check if delay forces a read position wrap.\n    while(aec->farBufReadPos < 0) {\n        aec->farBufReadPos += FAR_BUF_LEN;\n    }\n    while(aec->farBufReadPos > FAR_BUF_LEN - 1) {\n        aec->farBufReadPos -= FAR_BUF_LEN;\n    }\n\n    aec->knownDelay = knownDelay;\n\n    // Check if read position must be wrapped.\n    while (aec->farBufReadPos + readLen > FAR_BUF_LEN) {\n\n        // Read from remaining buffer space before wrapping.\n        readLen = FAR_BUF_LEN - aec->farBufReadPos;\n        memcpy(farend + readPos, aec->farBuf + aec->farBufReadPos,\n            sizeof(short) * readLen);\n        aec->farBufReadPos = 0;\n        readPos = readLen;\n        readLen = farLen - readLen;\n    }\n    memcpy(farend + readPos, aec->farBuf + aec->farBufReadPos,\n        sizeof(short) * readLen);\n    aec->farBufReadPos += readLen;\n}\n\nstatic void WebRtcAec_InitLevel(power_level_t *level)\n{\n    const float bigFloat = 1E17f;\n\n    level->averagelevel = 0;\n    level->framelevel = 0;\n    level->minlevel = bigFloat;\n    level->frsum = 0;\n    level->sfrsum = 0;\n    level->frcounter = 0;\n    level->sfrcounter = 0;\n}\n\nstatic void WebRtcAec_InitStats(stats_t *stats)\n{\n    stats->instant = offsetLevel;\n    stats->average = offsetLevel;\n    stats->max = offsetLevel;\n    stats->min = offsetLevel * (-1);\n    stats->sum = 0;\n    stats->hisum = 0;\n    stats->himean = offsetLevel;\n    stats->counter = 0;\n    stats->hicounter = 0;\n}\n\nstatic void UpdateLevel(power_level_t *level, const short *in)\n{\n    int k;\n\n    for (k = 0; k < PART_LEN; k++) {\n        level->sfrsum += in[k] * in[k];\n    }\n    level->sfrcounter++;\n\n    if (level->sfrcounter > subCountLen) {\n        level->framelevel = level->sfrsum / (subCountLen * PART_LEN);\n        level->sfrsum = 0;\n        level->sfrcounter = 0;\n\n        if (level->framelevel > 0) {\n            if (level->framelevel < level->minlevel) {\n                level->minlevel = level->framelevel;     // New minimum\n            } else {\n                level->minlevel *= (1 + 0.001f);   // Small increase\n            }\n        }\n        level->frcounter++;\n        level->frsum += level->framelevel;\n\n        if (level->frcounter > countLen) {\n            level->averagelevel =  level->frsum / countLen;\n            level->frsum = 0;\n            level->frcounter = 0;\n        }\n\n    }\n}\n\nstatic void UpdateMetrics(aec_t *aec)\n{\n    float dtmp, dtmp2;\n\n    const float actThresholdNoisy = 8.0f;\n    const float actThresholdClean = 40.0f;\n    const float safety = 0.99995f;\n    const float noisyPower = 300000.0f;\n\n    float actThreshold;\n    float echo, suppressedEcho;\n\n    if (aec->echoState) {   // Check if echo is likely present\n        aec->stateCounter++;\n    }\n\n    if (aec->farlevel.frcounter == countLen) {\n\n        if (aec->farlevel.minlevel < noisyPower) {\n            actThreshold = actThresholdClean;\n        }\n        else {\n            actThreshold = actThresholdNoisy;\n        }\n\n        if ((aec->stateCounter > (0.5f * countLen * subCountLen))\n            && (aec->farlevel.sfrcounter == 0)\n\n            // Estimate in active far-end segments only\n            && (aec->farlevel.averagelevel > (actThreshold * aec->farlevel.minlevel))\n            ) {\n\n            // Subtract noise power\n            echo = aec->nearlevel.averagelevel - safety * aec->nearlevel.minlevel;\n\n            // ERL\n            dtmp = 10 * (float)log10(aec->farlevel.averagelevel /\n                aec->nearlevel.averagelevel + 1e-10f);\n            dtmp2 = 10 * (float)log10(aec->farlevel.averagelevel / echo + 1e-10f);\n\n            aec->erl.instant = dtmp;\n            if (dtmp > aec->erl.max) {\n                aec->erl.max = dtmp;\n            }\n\n            if (dtmp < aec->erl.min) {\n                aec->erl.min = dtmp;\n            }\n\n            aec->erl.counter++;\n            aec->erl.sum += dtmp;\n            aec->erl.average = aec->erl.sum / aec->erl.counter;\n\n            // Upper mean\n            if (dtmp > aec->erl.average) {\n                aec->erl.hicounter++;\n                aec->erl.hisum += dtmp;\n                aec->erl.himean = aec->erl.hisum / aec->erl.hicounter;\n            }\n\n            // A_NLP\n            dtmp = 10 * (float)log10(aec->nearlevel.averagelevel /\n                aec->linoutlevel.averagelevel + 1e-10f);\n\n            // subtract noise power\n            suppressedEcho = aec->linoutlevel.averagelevel - safety * aec->linoutlevel.minlevel;\n\n            dtmp2 = 10 * (float)log10(echo / suppressedEcho + 1e-10f);\n\n            aec->aNlp.instant = dtmp2;\n            if (dtmp > aec->aNlp.max) {\n                aec->aNlp.max = dtmp;\n            }\n\n            if (dtmp < aec->aNlp.min) {\n                aec->aNlp.min = dtmp;\n            }\n\n            aec->aNlp.counter++;\n            aec->aNlp.sum += dtmp;\n            aec->aNlp.average = aec->aNlp.sum / aec->aNlp.counter;\n\n            // Upper mean\n            if (dtmp > aec->aNlp.average) {\n                aec->aNlp.hicounter++;\n                aec->aNlp.hisum += dtmp;\n                aec->aNlp.himean = aec->aNlp.hisum / aec->aNlp.hicounter;\n            }\n\n            // ERLE\n\n            // subtract noise power\n            suppressedEcho = aec->nlpoutlevel.averagelevel - safety * aec->nlpoutlevel.minlevel;\n\n            dtmp = 10 * (float)log10(aec->nearlevel.averagelevel /\n                aec->nlpoutlevel.averagelevel + 1e-10f);\n            dtmp2 = 10 * (float)log10(echo / suppressedEcho + 1e-10f);\n\n            dtmp = dtmp2;\n            aec->erle.instant = dtmp;\n            if (dtmp > aec->erle.max) {\n                aec->erle.max = dtmp;\n            }\n\n            if (dtmp < aec->erle.min) {\n                aec->erle.min = dtmp;\n            }\n\n            aec->erle.counter++;\n            aec->erle.sum += dtmp;\n            aec->erle.average = aec->erle.sum / aec->erle.counter;\n\n            // Upper mean\n            if (dtmp > aec->erle.average) {\n                aec->erle.hicounter++;\n                aec->erle.hisum += dtmp;\n                aec->erle.himean = aec->erle.hisum / aec->erle.hicounter;\n            }\n        }\n\n        aec->stateCounter = 0;\n    }\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/aec/main/source/aec_core.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/*\n * Specifies the interface for the AEC core.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_CORE_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_CORE_H_\n\n#include <stdio.h>\n\n#include \"signal_processing_library.h\"\n#include \"typedefs.h\"\n\n//#define UNCONSTR // time-unconstrained filter\n//#define AEC_DEBUG // for recording files\n\n#define FRAME_LEN 80\n#define PART_LEN 64 // Length of partition\n#define PART_LEN1 (PART_LEN + 1) // Unique fft coefficients\n#define PART_LEN2 (PART_LEN * 2) // Length of partition * 2\n#define NR_PART 12 // Number of partitions\n#define FILT_LEN (PART_LEN * NR_PART) // Filter length\n#define FILT_LEN2 (FILT_LEN * 2) // Double filter length\n#define FAR_BUF_LEN (FILT_LEN2 * 2)\n#define PREF_BAND_SIZE 24\n\n#define BLOCKL_MAX FRAME_LEN\n\ntypedef float complex_t[2];\n// For performance reasons, some arrays of complex numbers are replaced by twice\n// as long arrays of float, all the real parts followed by all the imaginary\n// ones (complex_t[SIZE] -> float[2][SIZE]). This allows SIMD optimizations and\n// is better than two arrays (one for the real parts and one for the imaginary\n// parts) as this other way would require two pointers instead of one and cause\n// extra register spilling. This also allows the offsets to be calculated at\n// compile time.\n\n// Metrics\nenum {offsetLevel = -100};\n\ntypedef struct {\n    float sfrsum;\n    int sfrcounter;\n    float framelevel;\n    float frsum;\n    int frcounter;\n    float minlevel;\n    float averagelevel;\n} power_level_t;\n\ntypedef struct {\n    float instant;\n    float average;\n    float min;\n    float max;\n    float sum;\n    float hisum;\n    float himean;\n    int counter;\n    int hicounter;\n} stats_t;\n\ntypedef struct {\n    int farBufWritePos, farBufReadPos;\n\n    int knownDelay;\n    int inSamples, outSamples;\n    int delayEstCtr;\n\n    void *farFrBuf, *nearFrBuf, *outFrBuf;\n\n    void *nearFrBufH;\n    void *outFrBufH;\n\n    float xBuf[PART_LEN2]; // farend\n    float dBuf[PART_LEN2]; // nearend\n    float eBuf[PART_LEN2]; // error\n\n    float dBufH[PART_LEN2]; // nearend\n\n    float xPow[PART_LEN1];\n    float dPow[PART_LEN1];\n    float dMinPow[PART_LEN1];\n    float dInitMinPow[PART_LEN1];\n    float *noisePow;\n\n    float xfBuf[2][NR_PART * PART_LEN1]; // farend fft buffer\n    float wfBuf[2][NR_PART * PART_LEN1]; // filter fft\n    complex_t sde[PART_LEN1]; // cross-psd of nearend and error\n    complex_t sxd[PART_LEN1]; // cross-psd of farend and nearend\n    complex_t xfwBuf[NR_PART * PART_LEN1]; // farend windowed fft buffer\n\n    float sx[PART_LEN1], sd[PART_LEN1], se[PART_LEN1]; // far, near and error psd\n    float hNs[PART_LEN1];\n    float hNlFbMin, hNlFbLocalMin;\n    float hNlXdAvgMin;\n    int hNlNewMin, hNlMinCtr;\n    float overDrive, overDriveSm;\n    float targetSupp, minOverDrive;\n    float outBuf[PART_LEN];\n    int delayIdx;\n\n    short stNearState, echoState;\n    short divergeState;\n\n    int xfBufBlockPos;\n\n    short farBuf[FILT_LEN2 * 2];\n\n    short mult; // sampling frequency multiple\n    int sampFreq;\n    WebRtc_UWord32 seed;\n\n    float mu; // stepsize\n    float errThresh; // error threshold\n\n    int noiseEstCtr;\n\n    power_level_t farlevel;\n    power_level_t nearlevel;\n    power_level_t linoutlevel;\n    power_level_t nlpoutlevel;\n\n    int metricsMode;\n    int stateCounter;\n    stats_t erl;\n    stats_t erle;\n    stats_t aNlp;\n    stats_t rerl;\n\n    // Quantities to control H band scaling for SWB input\n    int freq_avg_ic;         //initial bin for averaging nlp gain\n    int flag_Hband_cn;      //for comfort noise\n    float cn_scale_Hband;   //scale for comfort noise in H band\n\n#ifdef AEC_DEBUG\n    FILE *farFile;\n    FILE *nearFile;\n    FILE *outFile;\n    FILE *outLpFile;\n#endif\n} aec_t;\n\ntypedef void (*WebRtcAec_FilterFar_t)(aec_t *aec, float yf[2][PART_LEN1]);\nextern WebRtcAec_FilterFar_t WebRtcAec_FilterFar;\ntypedef void (*WebRtcAec_ScaleErrorSignal_t)(aec_t *aec, float ef[2][PART_LEN1]);\nextern WebRtcAec_ScaleErrorSignal_t WebRtcAec_ScaleErrorSignal;\ntypedef void (*WebRtcAec_FilterAdaptation_t)\n  (aec_t *aec, float *fft, float ef[2][PART_LEN1]);\nextern WebRtcAec_FilterAdaptation_t WebRtcAec_FilterAdaptation;\ntypedef void (*WebRtcAec_OverdriveAndSuppress_t)\n  (aec_t *aec, float hNl[PART_LEN1], const float hNlFb, float efw[2][PART_LEN1]);\nextern WebRtcAec_OverdriveAndSuppress_t WebRtcAec_OverdriveAndSuppress;\n\nint WebRtcAec_CreateAec(aec_t **aec);\nint WebRtcAec_FreeAec(aec_t *aec);\nint WebRtcAec_InitAec(aec_t *aec, int sampFreq);\nvoid WebRtcAec_InitAec_SSE2(void);\n\nvoid WebRtcAec_InitMetrics(aec_t *aec);\nvoid WebRtcAec_ProcessFrame(aec_t *aec, const short *farend,\n                       const short *nearend, const short *nearendH,\n                       short *out, short *outH,\n                       int knownDelay);\n\n#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_CORE_H_\n\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/aec/main/source/aec_core_sse2.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/*\n * The core AEC algorithm, SSE2 version of speed-critical functions.\n */\n\n#include \"typedefs.h\"\n\n#if defined(WEBRTC_USE_SSE2)\n#include <emmintrin.h>\n#include <math.h>\n\n#include \"aec_core.h\"\n#include \"aec_rdft.h\"\n\n__inline static float MulRe(float aRe, float aIm, float bRe, float bIm)\n{\n  return aRe * bRe - aIm * bIm;\n}\n\n__inline static float MulIm(float aRe, float aIm, float bRe, float bIm)\n{\n  return aRe * bIm + aIm * bRe;\n}\n\nstatic void FilterFarSSE2(aec_t *aec, float yf[2][PART_LEN1])\n{\n  int i;\n  for (i = 0; i < NR_PART; i++) {\n    int j;\n    int xPos = (i + aec->xfBufBlockPos) * PART_LEN1;\n    int pos = i * PART_LEN1;\n    // Check for wrap\n    if (i + aec->xfBufBlockPos >= NR_PART) {\n      xPos -= NR_PART*(PART_LEN1);\n    }\n\n    // vectorized code (four at once)\n    for (j = 0; j + 3 < PART_LEN1; j += 4) {\n      const __m128 xfBuf_re = _mm_loadu_ps(&aec->xfBuf[0][xPos + j]);\n      const __m128 xfBuf_im = _mm_loadu_ps(&aec->xfBuf[1][xPos + j]);\n      const __m128 wfBuf_re = _mm_loadu_ps(&aec->wfBuf[0][pos + j]);\n      const __m128 wfBuf_im = _mm_loadu_ps(&aec->wfBuf[1][pos + j]);\n      const __m128 yf_re = _mm_loadu_ps(&yf[0][j]);\n      const __m128 yf_im = _mm_loadu_ps(&yf[1][j]);\n      const __m128 a = _mm_mul_ps(xfBuf_re, wfBuf_re);\n      const __m128 b = _mm_mul_ps(xfBuf_im, wfBuf_im);\n      const __m128 c = _mm_mul_ps(xfBuf_re, wfBuf_im);\n      const __m128 d = _mm_mul_ps(xfBuf_im, wfBuf_re);\n      const __m128 e = _mm_sub_ps(a, b);\n      const __m128 f = _mm_add_ps(c, d);\n      const __m128 g = _mm_add_ps(yf_re, e);\n      const __m128 h = _mm_add_ps(yf_im, f);\n      _mm_storeu_ps(&yf[0][j], g);\n      _mm_storeu_ps(&yf[1][j], h);\n    }\n    // scalar code for the remaining items.\n    for (; j < PART_LEN1; j++) {\n      yf[0][j] += MulRe(aec->xfBuf[0][xPos + j], aec->xfBuf[1][xPos + j],\n                        aec->wfBuf[0][ pos + j], aec->wfBuf[1][ pos + j]);\n      yf[1][j] += MulIm(aec->xfBuf[0][xPos + j], aec->xfBuf[1][xPos + j],\n                        aec->wfBuf[0][ pos + j], aec->wfBuf[1][ pos + j]);\n    }\n  }\n}\n\nstatic void ScaleErrorSignalSSE2(aec_t *aec, float ef[2][PART_LEN1])\n{\n  const __m128 k1e_10f = _mm_set1_ps(1e-10f);\n  const __m128 kThresh = _mm_set1_ps(aec->errThresh);\n  const __m128 kMu = _mm_set1_ps(aec->mu);\n\n  int i;\n  // vectorized code (four at once)\n  for (i = 0; i + 3 < PART_LEN1; i += 4) {\n    const __m128 xPow = _mm_loadu_ps(&aec->xPow[i]);\n    const __m128 ef_re_base = _mm_loadu_ps(&ef[0][i]);\n    const __m128 ef_im_base = _mm_loadu_ps(&ef[1][i]);\n\n    const __m128 xPowPlus = _mm_add_ps(xPow, k1e_10f);\n    __m128 ef_re = _mm_div_ps(ef_re_base, xPowPlus);\n    __m128 ef_im = _mm_div_ps(ef_im_base, xPowPlus);\n    const __m128 ef_re2 = _mm_mul_ps(ef_re, ef_re);\n    const __m128 ef_im2 = _mm_mul_ps(ef_im, ef_im);\n    const __m128 ef_sum2 = _mm_add_ps(ef_re2, ef_im2);\n    const __m128 absEf = _mm_sqrt_ps(ef_sum2);\n    const __m128 bigger = _mm_cmpgt_ps(absEf, kThresh);\n    __m128 absEfPlus = _mm_add_ps(absEf, k1e_10f);\n    const __m128 absEfInv = _mm_div_ps(kThresh, absEfPlus);\n    __m128 ef_re_if = _mm_mul_ps(ef_re, absEfInv);\n    __m128 ef_im_if = _mm_mul_ps(ef_im, absEfInv);\n    ef_re_if = _mm_and_ps(bigger, ef_re_if);\n    ef_im_if = _mm_and_ps(bigger, ef_im_if);\n    ef_re = _mm_andnot_ps(bigger, ef_re);\n    ef_im = _mm_andnot_ps(bigger, ef_im);\n    ef_re = _mm_or_ps(ef_re, ef_re_if);\n    ef_im = _mm_or_ps(ef_im, ef_im_if);\n    ef_re = _mm_mul_ps(ef_re, kMu);\n    ef_im = _mm_mul_ps(ef_im, kMu);\n\n    _mm_storeu_ps(&ef[0][i], ef_re);\n    _mm_storeu_ps(&ef[1][i], ef_im);\n  }\n  // scalar code for the remaining items.\n  for (; i < (PART_LEN1); i++) {\n    float absEf;\n    ef[0][i] /= (aec->xPow[i] + 1e-10f);\n    ef[1][i] /= (aec->xPow[i] + 1e-10f);\n    absEf = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]);\n\n    if (absEf > aec->errThresh) {\n      absEf = aec->errThresh / (absEf + 1e-10f);\n      ef[0][i] *= absEf;\n      ef[1][i] *= absEf;\n    }\n\n    // Stepsize factor\n    ef[0][i] *= aec->mu;\n    ef[1][i] *= aec->mu;\n  }\n}\n\nstatic void FilterAdaptationSSE2(aec_t *aec, float *fft, float ef[2][PART_LEN1]) {\n  int i, j;\n  for (i = 0; i < NR_PART; i++) {\n    int xPos = (i + aec->xfBufBlockPos)*(PART_LEN1);\n    int pos = i * PART_LEN1;\n    // Check for wrap\n    if (i + aec->xfBufBlockPos >= NR_PART) {\n      xPos -= NR_PART * PART_LEN1;\n    }\n\n#ifdef UNCONSTR\n    for (j = 0; j < PART_LEN1; j++) {\n      aec->wfBuf[pos + j][0] += MulRe(aec->xfBuf[xPos + j][0],\n                                      -aec->xfBuf[xPos + j][1],\n                                      ef[j][0], ef[j][1]);\n      aec->wfBuf[pos + j][1] += MulIm(aec->xfBuf[xPos + j][0],\n                                      -aec->xfBuf[xPos + j][1],\n                                      ef[j][0], ef[j][1]);\n    }\n#else\n    // Process the whole array...\n    for (j = 0; j < PART_LEN; j+= 4) {\n      // Load xfBuf and ef.\n      const __m128 xfBuf_re = _mm_loadu_ps(&aec->xfBuf[0][xPos + j]);\n      const __m128 xfBuf_im = _mm_loadu_ps(&aec->xfBuf[1][xPos + j]);\n      const __m128 ef_re = _mm_loadu_ps(&ef[0][j]);\n      const __m128 ef_im = _mm_loadu_ps(&ef[1][j]);\n      // Calculate the product of conjugate(xfBuf) by ef.\n      //   re(conjugate(a) * b) = aRe * bRe + aIm * bIm\n      //   im(conjugate(a) * b)=  aRe * bIm - aIm * bRe\n      const __m128 a = _mm_mul_ps(xfBuf_re, ef_re);\n      const __m128 b = _mm_mul_ps(xfBuf_im, ef_im);\n      const __m128 c = _mm_mul_ps(xfBuf_re, ef_im);\n      const __m128 d = _mm_mul_ps(xfBuf_im, ef_re);\n      const __m128 e = _mm_add_ps(a, b);\n      const __m128 f = _mm_sub_ps(c, d);\n      // Interleave real and imaginary parts.\n      const __m128 g = _mm_unpacklo_ps(e, f);\n      const __m128 h = _mm_unpackhi_ps(e, f);\n      // Store\n      _mm_storeu_ps(&fft[2*j + 0], g);\n      _mm_storeu_ps(&fft[2*j + 4], h);\n    }\n    // ... and fixup the first imaginary entry.\n    fft[1] = MulRe(aec->xfBuf[0][xPos + PART_LEN],\n                   -aec->xfBuf[1][xPos + PART_LEN],\n                   ef[0][PART_LEN], ef[1][PART_LEN]);\n\n    aec_rdft_inverse_128(fft);\n    memset(fft + PART_LEN, 0, sizeof(float)*PART_LEN);\n\n    // fft scaling\n    {\n      float scale = 2.0f / PART_LEN2;\n      const __m128 scale_ps = _mm_load_ps1(&scale);\n      for (j = 0; j < PART_LEN; j+=4) {\n        const __m128 fft_ps = _mm_loadu_ps(&fft[j]);\n        const __m128 fft_scale = _mm_mul_ps(fft_ps, scale_ps);\n        _mm_storeu_ps(&fft[j], fft_scale);\n      }\n    }\n    aec_rdft_forward_128(fft);\n\n    {\n      float wt1 = aec->wfBuf[1][pos];\n      aec->wfBuf[0][pos + PART_LEN] += fft[1];\n      for (j = 0; j < PART_LEN; j+= 4) {\n        __m128 wtBuf_re = _mm_loadu_ps(&aec->wfBuf[0][pos + j]);\n        __m128 wtBuf_im = _mm_loadu_ps(&aec->wfBuf[1][pos + j]);\n        const __m128 fft0 = _mm_loadu_ps(&fft[2 * j + 0]);\n        const __m128 fft4 = _mm_loadu_ps(&fft[2 * j + 4]);\n        const __m128 fft_re = _mm_shuffle_ps(fft0, fft4, _MM_SHUFFLE(2, 0, 2 ,0));\n        const __m128 fft_im = _mm_shuffle_ps(fft0, fft4, _MM_SHUFFLE(3, 1, 3 ,1));\n        wtBuf_re = _mm_add_ps(wtBuf_re, fft_re);\n        wtBuf_im = _mm_add_ps(wtBuf_im, fft_im);\n        _mm_storeu_ps(&aec->wfBuf[0][pos + j], wtBuf_re);\n        _mm_storeu_ps(&aec->wfBuf[1][pos + j], wtBuf_im);\n      }\n      aec->wfBuf[1][pos] = wt1;\n    }\n#endif // UNCONSTR\n  }\n}\n\nstatic __m128 mm_pow_ps(__m128 a, __m128 b)\n{\n  // a^b = exp2(b * log2(a))\n  //   exp2(x) and log2(x) are calculated using polynomial approximations.\n  __m128 log2_a, b_log2_a, a_exp_b;\n\n  // Calculate log2(x), x = a.\n  {\n    // To calculate log2(x), we decompose x like this:\n    //   x = y * 2^n\n    //     n is an integer\n    //     y is in the [1.0, 2.0) range\n    //\n    //   log2(x) = log2(y) + n\n    //     n       can be evaluated by playing with float representation.\n    //     log2(y) in a small range can be approximated, this code uses an order\n    //             five polynomial approximation. The coefficients have been\n    //             estimated with the Remez algorithm and the resulting\n    //             polynomial has a maximum relative error of 0.00086%.\n\n    // Compute n.\n    //    This is done by masking the exponent, shifting it into the top bit of\n    //    the mantissa, putting eight into the biased exponent (to shift/\n    //    compensate the fact that the exponent has been shifted in the top/\n    //    fractional part and finally getting rid of the implicit leading one\n    //    from the mantissa by substracting it out.\n    static const ALIGN16_BEG int float_exponent_mask[4] ALIGN16_END =\n        {0x7F800000, 0x7F800000, 0x7F800000, 0x7F800000};\n    static const ALIGN16_BEG int eight_biased_exponent[4] ALIGN16_END =\n        {0x43800000, 0x43800000, 0x43800000, 0x43800000};\n    static const ALIGN16_BEG int implicit_leading_one[4] ALIGN16_END =\n        {0x43BF8000, 0x43BF8000, 0x43BF8000, 0x43BF8000};\n    static const int shift_exponent_into_top_mantissa = 8;\n    const __m128 two_n = _mm_and_ps(a, *((__m128 *)float_exponent_mask));\n    const __m128 n_1 = (__m128)_mm_srli_epi32((__m128i)two_n,\n        shift_exponent_into_top_mantissa);\n    const __m128 n_0 = _mm_or_ps(\n        (__m128)n_1, *((__m128 *)eight_biased_exponent));\n    const __m128 n   = _mm_sub_ps(n_0,  *((__m128 *)implicit_leading_one));\n\n    // Compute y.\n    static const ALIGN16_BEG int mantissa_mask[4] ALIGN16_END =\n        {0x007FFFFF, 0x007FFFFF, 0x007FFFFF, 0x007FFFFF};\n    static const ALIGN16_BEG int zero_biased_exponent_is_one[4] ALIGN16_END =\n        {0x3F800000, 0x3F800000, 0x3F800000, 0x3F800000};\n    const __m128 mantissa = _mm_and_ps(a, *((__m128 *)mantissa_mask));\n    const __m128 y        = _mm_or_ps(\n        mantissa,  *((__m128 *)zero_biased_exponent_is_one));\n\n    // Approximate log2(y) ~= (y - 1) * pol5(y).\n    //    pol5(y) = C5 * y^5 + C4 * y^4 + C3 * y^3 + C2 * y^2 + C1 * y + C0\n    static const ALIGN16_BEG float ALIGN16_END C5[4] =\n        {-3.4436006e-2f, -3.4436006e-2f, -3.4436006e-2f, -3.4436006e-2f};\n    static const ALIGN16_BEG float ALIGN16_END C4[4] =\n        {3.1821337e-1f, 3.1821337e-1f, 3.1821337e-1f, 3.1821337e-1f};\n    static const ALIGN16_BEG float ALIGN16_END C3[4] =\n        {-1.2315303f, -1.2315303f, -1.2315303f, -1.2315303f};\n    static const ALIGN16_BEG float ALIGN16_END C2[4] =\n        {2.5988452f, 2.5988452f, 2.5988452f, 2.5988452f};\n    static const ALIGN16_BEG float ALIGN16_END C1[4] =\n        {-3.3241990f, -3.3241990f, -3.3241990f, -3.3241990f};\n    static const ALIGN16_BEG float ALIGN16_END C0[4] =\n        {3.1157899f, 3.1157899f, 3.1157899f, 3.1157899f};\n    const __m128 pol5_y_0 = _mm_mul_ps(y,        *((__m128 *)C5));\n    const __m128 pol5_y_1 = _mm_add_ps(pol5_y_0, *((__m128 *)C4));\n    const __m128 pol5_y_2 = _mm_mul_ps(pol5_y_1, y);\n    const __m128 pol5_y_3 = _mm_add_ps(pol5_y_2, *((__m128 *)C3));\n    const __m128 pol5_y_4 = _mm_mul_ps(pol5_y_3, y);\n    const __m128 pol5_y_5 = _mm_add_ps(pol5_y_4, *((__m128 *)C2));\n    const __m128 pol5_y_6 = _mm_mul_ps(pol5_y_5, y);\n    const __m128 pol5_y_7 = _mm_add_ps(pol5_y_6, *((__m128 *)C1));\n    const __m128 pol5_y_8 = _mm_mul_ps(pol5_y_7, y);\n    const __m128 pol5_y   = _mm_add_ps(pol5_y_8, *((__m128 *)C0));\n    const __m128 y_minus_one = _mm_sub_ps(\n        y, *((__m128 *)zero_biased_exponent_is_one));\n    const __m128 log2_y = _mm_mul_ps(y_minus_one ,  pol5_y);\n\n    // Combine parts.\n    log2_a = _mm_add_ps(n, log2_y);\n  }\n\n  // b * log2(a)\n  b_log2_a = _mm_mul_ps(b, log2_a);\n\n  // Calculate exp2(x), x = b * log2(a).\n  {\n    // To calculate 2^x, we decompose x like this:\n    //   x = n + y\n    //     n is an integer, the value of x - 0.5 rounded down, therefore\n    //     y is in the [0.5, 1.5) range\n    //\n    //   2^x = 2^n * 2^y\n    //     2^n can be evaluated by playing with float representation.\n    //     2^y in a small range can be approximated, this code uses an order two\n    //         polynomial approximation. The coefficients have been estimated\n    //         with the Remez algorithm and the resulting polynomial has a\n    //         maximum relative error of 0.17%.\n\n    // To avoid over/underflow, we reduce the range of input to ]-127, 129].\n    static const ALIGN16_BEG float max_input[4] ALIGN16_END =\n        {129.f, 129.f, 129.f, 129.f};\n    static const ALIGN16_BEG float min_input[4] ALIGN16_END =\n        {-126.99999f, -126.99999f, -126.99999f, -126.99999f};\n    const __m128 x_min = _mm_min_ps(b_log2_a, *((__m128 *)max_input));\n    const __m128 x_max = _mm_max_ps(x_min,    *((__m128 *)min_input));\n    // Compute n.\n    static const ALIGN16_BEG float half[4] ALIGN16_END =\n        {0.5f, 0.5f, 0.5f, 0.5f};\n    const __m128  x_minus_half = _mm_sub_ps(x_max, *((__m128 *)half));\n    const __m128i x_minus_half_floor = _mm_cvtps_epi32(x_minus_half);\n    // Compute 2^n.\n    static const ALIGN16_BEG int float_exponent_bias[4] ALIGN16_END =\n        {127, 127, 127, 127};\n    static const int float_exponent_shift = 23;\n    const __m128i two_n_exponent = _mm_add_epi32(\n        x_minus_half_floor, *((__m128i *)float_exponent_bias));\n    const __m128  two_n = (__m128)_mm_slli_epi32(\n        two_n_exponent, float_exponent_shift);\n    // Compute y.\n    const __m128 y = _mm_sub_ps(x_max, _mm_cvtepi32_ps(x_minus_half_floor));\n    // Approximate 2^y ~= C2 * y^2 + C1 * y + C0.\n    static const ALIGN16_BEG float C2[4] ALIGN16_END =\n        {3.3718944e-1f, 3.3718944e-1f, 3.3718944e-1f, 3.3718944e-1f};\n    static const ALIGN16_BEG float C1[4] ALIGN16_END =\n        {6.5763628e-1f, 6.5763628e-1f, 6.5763628e-1f, 6.5763628e-1f};\n    static const ALIGN16_BEG float C0[4] ALIGN16_END =\n        {1.0017247f, 1.0017247f, 1.0017247f, 1.0017247f};\n    const __m128 exp2_y_0 = _mm_mul_ps(y,        *((__m128 *)C2));\n    const __m128 exp2_y_1 = _mm_add_ps(exp2_y_0, *((__m128 *)C1));\n    const __m128 exp2_y_2 = _mm_mul_ps(exp2_y_1, y);\n    const __m128 exp2_y   = _mm_add_ps(exp2_y_2, *((__m128 *)C0));\n\n    // Combine parts.\n    a_exp_b = _mm_mul_ps(exp2_y, two_n);\n  }\n  return a_exp_b;\n}\n\nextern const float WebRtcAec_weightCurve[65];\nextern const float WebRtcAec_overDriveCurve[65];\n\nstatic void OverdriveAndSuppressSSE2(aec_t *aec, float hNl[PART_LEN1],\n                                     const float hNlFb,\n                                     float efw[2][PART_LEN1]) {\n  int i;\n  const __m128 vec_hNlFb = _mm_set1_ps(hNlFb);\n  const __m128 vec_one = _mm_set1_ps(1.0f);\n  const __m128 vec_minus_one = _mm_set1_ps(-1.0f);\n  const __m128 vec_overDriveSm = _mm_set1_ps(aec->overDriveSm);\n  // vectorized code (four at once)\n  for (i = 0; i + 3 < PART_LEN1; i+=4) {\n    // Weight subbands\n    __m128 vec_hNl = _mm_loadu_ps(&hNl[i]);\n    const __m128 vec_weightCurve = _mm_loadu_ps(&WebRtcAec_weightCurve[i]);\n    const __m128 bigger = _mm_cmpgt_ps(vec_hNl, vec_hNlFb);\n    const __m128 vec_weightCurve_hNlFb = _mm_mul_ps(\n        vec_weightCurve, vec_hNlFb);\n    const __m128 vec_one_weightCurve = _mm_sub_ps(vec_one, vec_weightCurve);\n    const __m128 vec_one_weightCurve_hNl = _mm_mul_ps(\n        vec_one_weightCurve, vec_hNl);\n    const __m128 vec_if0 = _mm_andnot_ps(bigger, vec_hNl);\n    const __m128 vec_if1 = _mm_and_ps(\n        bigger, _mm_add_ps(vec_weightCurve_hNlFb, vec_one_weightCurve_hNl));\n    vec_hNl = _mm_or_ps(vec_if0, vec_if1);\n\n    {\n      const __m128 vec_overDriveCurve = _mm_loadu_ps(\n          &WebRtcAec_overDriveCurve[i]);\n      const __m128 vec_overDriveSm_overDriveCurve = _mm_mul_ps(\n          vec_overDriveSm, vec_overDriveCurve);\n      vec_hNl = mm_pow_ps(vec_hNl, vec_overDriveSm_overDriveCurve);\n      _mm_storeu_ps(&hNl[i], vec_hNl);\n    }\n\n    // Suppress error signal\n    {\n      __m128 vec_efw_re = _mm_loadu_ps(&efw[0][i]);\n      __m128 vec_efw_im = _mm_loadu_ps(&efw[1][i]);\n      vec_efw_re = _mm_mul_ps(vec_efw_re, vec_hNl);\n      vec_efw_im = _mm_mul_ps(vec_efw_im, vec_hNl);\n\n      // Ooura fft returns incorrect sign on imaginary component. It matters\n      // here because we are making an additive change with comfort noise.\n      vec_efw_im = _mm_mul_ps(vec_efw_im, vec_minus_one);\n      _mm_storeu_ps(&efw[0][i], vec_efw_re);\n      _mm_storeu_ps(&efw[1][i], vec_efw_im);\n    }\n  }\n  // scalar code for the remaining items.\n  for (; i < PART_LEN1; i++) {\n    // Weight subbands\n    if (hNl[i] > hNlFb) {\n      hNl[i] = WebRtcAec_weightCurve[i] * hNlFb +\n          (1 - WebRtcAec_weightCurve[i]) * hNl[i];\n    }\n    hNl[i] = powf(hNl[i], aec->overDriveSm * WebRtcAec_overDriveCurve[i]);\n\n    // Suppress error signal\n    efw[0][i] *= hNl[i];\n    efw[1][i] *= hNl[i];\n\n    // Ooura fft returns incorrect sign on imaginary component. It matters\n    // here because we are making an additive change with comfort noise.\n    efw[1][i] *= -1;\n  }\n}\n\nvoid WebRtcAec_InitAec_SSE2(void) {\n  WebRtcAec_FilterFar = FilterFarSSE2;\n  WebRtcAec_ScaleErrorSignal = ScaleErrorSignalSSE2;\n  WebRtcAec_FilterAdaptation = FilterAdaptationSSE2;\n  WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppressSSE2;\n}\n\n#endif   // WEBRTC_USE_SSE2\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/aec/main/source/aec_rdft.c",
    "content": "/*\n * http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html\n * Copyright Takuya OOURA, 1996-2001\n *\n * You may use, copy, modify and distribute this code for any purpose (include\n * commercial use) and without fee. Please refer to this package when you modify\n * this code.\n *\n * Changes by the WebRTC authors:\n *    - Trivial type modifications.\n *    - Minimal code subset to do rdft of length 128.\n *    - Optimizations because of known length.\n *\n *  All changes are covered by the WebRTC license and IP grant:\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"aec_rdft.h\"\n\n#include <math.h>\n\n#include \"system_wrappers/interface/cpu_features_wrapper.h\"\n#include \"typedefs.h\"\n\n// constants shared by all paths (C, SSE2).\nfloat rdft_w[64];\n// constants used by the C path.\nfloat rdft_wk3ri_first[32];\nfloat rdft_wk3ri_second[32];\n// constants used by SSE2 but initialized in C path.\nALIGN16_BEG float ALIGN16_END rdft_wk1r[32];\nALIGN16_BEG float ALIGN16_END rdft_wk2r[32];\nALIGN16_BEG float ALIGN16_END rdft_wk3r[32];\nALIGN16_BEG float ALIGN16_END rdft_wk1i[32];\nALIGN16_BEG float ALIGN16_END rdft_wk2i[32];\nALIGN16_BEG float ALIGN16_END rdft_wk3i[32];\nALIGN16_BEG float ALIGN16_END cftmdl_wk1r[4];\n\nstatic int ip[16];\n\nstatic void bitrv2_32or128(int n, int *ip, float *a) {\n  // n is 32 or 128\n  int j, j1, k, k1, m, m2;\n  float xr, xi, yr, yi;\n\n  ip[0] = 0;\n  {\n    int l = n;\n    m = 1;\n    while ((m << 3) < l) {\n      l >>= 1;\n      for (j = 0; j < m; j++) {\n        ip[m + j] = ip[j] + l;\n      }\n      m <<= 1;\n    }\n  }\n  m2 = 2 * m;\n  for (k = 0; k < m; k++) {\n    for (j = 0; j < k; j++) {\n      j1 = 2 * j + ip[k];\n      k1 = 2 * k + ip[j];\n      xr = a[j1];\n      xi = a[j1 + 1];\n      yr = a[k1];\n      yi = a[k1 + 1];\n      a[j1] = yr;\n      a[j1 + 1] = yi;\n      a[k1] = xr;\n      a[k1 + 1] = xi;\n      j1 += m2;\n      k1 += 2 * m2;\n      xr = a[j1];\n      xi = a[j1 + 1];\n      yr = a[k1];\n      yi = a[k1 + 1];\n      a[j1] = yr;\n      a[j1 + 1] = yi;\n      a[k1] = xr;\n      a[k1 + 1] = xi;\n      j1 += m2;\n      k1 -= m2;\n      xr = a[j1];\n      xi = a[j1 + 1];\n      yr = a[k1];\n      yi = a[k1 + 1];\n      a[j1] = yr;\n      a[j1 + 1] = yi;\n      a[k1] = xr;\n      a[k1 + 1] = xi;\n      j1 += m2;\n      k1 += 2 * m2;\n      xr = a[j1];\n      xi = a[j1 + 1];\n      yr = a[k1];\n      yi = a[k1 + 1];\n      a[j1] = yr;\n      a[j1 + 1] = yi;\n      a[k1] = xr;\n      a[k1 + 1] = xi;\n    }\n    j1 = 2 * k + m2 + ip[k];\n    k1 = j1 + m2;\n    xr = a[j1];\n    xi = a[j1 + 1];\n    yr = a[k1];\n    yi = a[k1 + 1];\n    a[j1] = yr;\n    a[j1 + 1] = yi;\n    a[k1] = xr;\n    a[k1 + 1] = xi;\n  }\n}\n\nstatic void makewt_32(void) {\n  const int nw = 32;\n  int j, nwh;\n  float delta, x, y;\n\n  ip[0] = nw;\n  ip[1] = 1;\n  nwh = nw >> 1;\n  delta = atanf(1.0f) / nwh;\n  rdft_w[0] = 1;\n  rdft_w[1] = 0;\n  rdft_w[nwh] = cosf(delta * nwh);\n  rdft_w[nwh + 1] = rdft_w[nwh];\n  for (j = 2; j < nwh; j += 2) {\n    x = cosf(delta * j);\n    y = sinf(delta * j);\n    rdft_w[j] = x;\n    rdft_w[j + 1] = y;\n    rdft_w[nw - j] = y;\n    rdft_w[nw - j + 1] = x;\n  }\n  bitrv2_32or128(nw, ip + 2, rdft_w);\n\n  // pre-calculate constants used by cft1st_128 and cftmdl_128...\n  cftmdl_wk1r[0] = rdft_w[2];\n  cftmdl_wk1r[1] = rdft_w[2];\n  cftmdl_wk1r[2] = rdft_w[2];\n  cftmdl_wk1r[3] = -rdft_w[2];\n  {\n    int k1;\n\n    for (k1 = 0, j = 0; j < 128; j += 16, k1 += 2) {\n      const int k2 = 2 * k1;\n      const float wk2r = rdft_w[k1 + 0];\n      const float wk2i = rdft_w[k1 + 1];\n      float wk1r, wk1i;\n      // ... scalar version.\n      wk1r = rdft_w[k2 + 0];\n      wk1i = rdft_w[k2 + 1];\n      rdft_wk3ri_first[k1 + 0] = wk1r - 2 * wk2i * wk1i;\n      rdft_wk3ri_first[k1 + 1] = 2 * wk2i * wk1r - wk1i;\n      wk1r = rdft_w[k2 + 2];\n      wk1i = rdft_w[k2 + 3];\n      rdft_wk3ri_second[k1 + 0] = wk1r - 2 * wk2r * wk1i;\n      rdft_wk3ri_second[k1 + 1] = 2 * wk2r * wk1r - wk1i;\n      // ... vector version.\n      rdft_wk1r[k2 + 0] = rdft_w[k2 + 0];\n      rdft_wk1r[k2 + 1] = rdft_w[k2 + 0];\n      rdft_wk1r[k2 + 2] = rdft_w[k2 + 2];\n      rdft_wk1r[k2 + 3] = rdft_w[k2 + 2];\n      rdft_wk2r[k2 + 0] = rdft_w[k1 + 0];\n      rdft_wk2r[k2 + 1] = rdft_w[k1 + 0];\n      rdft_wk2r[k2 + 2] = -rdft_w[k1 + 1];\n      rdft_wk2r[k2 + 3] = -rdft_w[k1 + 1];\n      rdft_wk3r[k2 + 0] = rdft_wk3ri_first[k1 + 0];\n      rdft_wk3r[k2 + 1] = rdft_wk3ri_first[k1 + 0];\n      rdft_wk3r[k2 + 2] = rdft_wk3ri_second[k1 + 0];\n      rdft_wk3r[k2 + 3] = rdft_wk3ri_second[k1 + 0];\n      rdft_wk1i[k2 + 0] = -rdft_w[k2 + 1];\n      rdft_wk1i[k2 + 1] = rdft_w[k2 + 1];\n      rdft_wk1i[k2 + 2] = -rdft_w[k2 + 3];\n      rdft_wk1i[k2 + 3] = rdft_w[k2 + 3];\n      rdft_wk2i[k2 + 0] = -rdft_w[k1 + 1];\n      rdft_wk2i[k2 + 1] = rdft_w[k1 + 1];\n      rdft_wk2i[k2 + 2] = -rdft_w[k1 + 0];\n      rdft_wk2i[k2 + 3] = rdft_w[k1 + 0];\n      rdft_wk3i[k2 + 0] = -rdft_wk3ri_first[k1 + 1];\n      rdft_wk3i[k2 + 1] = rdft_wk3ri_first[k1 + 1];\n      rdft_wk3i[k2 + 2] = -rdft_wk3ri_second[k1 + 1];\n      rdft_wk3i[k2 + 3] = rdft_wk3ri_second[k1 + 1];\n    }\n  }\n}\n\nstatic void makect_32(void) {\n  float *c = rdft_w + 32;\n  const int nc = 32;\n  int j, nch;\n  float delta;\n\n  ip[1] = nc;\n  nch = nc >> 1;\n  delta = atanf(1.0f) / nch;\n  c[0] = cosf(delta * nch);\n  c[nch] = 0.5f * c[0];\n  for (j = 1; j < nch; j++) {\n    c[j] = 0.5f * cosf(delta * j);\n    c[nc - j] = 0.5f * sinf(delta * j);\n  }\n}\n\nstatic void cft1st_128_C(float *a) {\n  const int n = 128;\n  int j, k1, k2;\n  float wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;\n  float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\n  x0r = a[0] + a[2];\n  x0i = a[1] + a[3];\n  x1r = a[0] - a[2];\n  x1i = a[1] - a[3];\n  x2r = a[4] + a[6];\n  x2i = a[5] + a[7];\n  x3r = a[4] - a[6];\n  x3i = a[5] - a[7];\n  a[0] = x0r + x2r;\n  a[1] = x0i + x2i;\n  a[4] = x0r - x2r;\n  a[5] = x0i - x2i;\n  a[2] = x1r - x3i;\n  a[3] = x1i + x3r;\n  a[6] = x1r + x3i;\n  a[7] = x1i - x3r;\n  wk1r = rdft_w[2];\n  x0r = a[8] + a[10];\n  x0i = a[9] + a[11];\n  x1r = a[8] - a[10];\n  x1i = a[9] - a[11];\n  x2r = a[12] + a[14];\n  x2i = a[13] + a[15];\n  x3r = a[12] - a[14];\n  x3i = a[13] - a[15];\n  a[8] = x0r + x2r;\n  a[9] = x0i + x2i;\n  a[12] = x2i - x0i;\n  a[13] = x0r - x2r;\n  x0r = x1r - x3i;\n  x0i = x1i + x3r;\n  a[10] = wk1r * (x0r - x0i);\n  a[11] = wk1r * (x0r + x0i);\n  x0r = x3i + x1r;\n  x0i = x3r - x1i;\n  a[14] = wk1r * (x0i - x0r);\n  a[15] = wk1r * (x0i + x0r);\n  k1 = 0;\n  for (j = 16; j < n; j += 16) {\n    k1 += 2;\n    k2 = 2 * k1;\n    wk2r = rdft_w[k1 + 0];\n    wk2i = rdft_w[k1 + 1];\n    wk1r = rdft_w[k2 + 0];\n    wk1i = rdft_w[k2 + 1];\n    wk3r = rdft_wk3ri_first[k1 + 0];\n    wk3i = rdft_wk3ri_first[k1 + 1];\n    x0r = a[j + 0] + a[j + 2];\n    x0i = a[j + 1] + a[j + 3];\n    x1r = a[j + 0] - a[j + 2];\n    x1i = a[j + 1] - a[j + 3];\n    x2r = a[j + 4] + a[j + 6];\n    x2i = a[j + 5] + a[j + 7];\n    x3r = a[j + 4] - a[j + 6];\n    x3i = a[j + 5] - a[j + 7];\n    a[j + 0] = x0r + x2r;\n    a[j + 1] = x0i + x2i;\n    x0r -= x2r;\n    x0i -= x2i;\n    a[j + 4] = wk2r * x0r - wk2i * x0i;\n    a[j + 5] = wk2r * x0i + wk2i * x0r;\n    x0r = x1r - x3i;\n    x0i = x1i + x3r;\n    a[j + 2] = wk1r * x0r - wk1i * x0i;\n    a[j + 3] = wk1r * x0i + wk1i * x0r;\n    x0r = x1r + x3i;\n    x0i = x1i - x3r;\n    a[j + 6] = wk3r * x0r - wk3i * x0i;\n    a[j + 7] = wk3r * x0i + wk3i * x0r;\n    wk1r = rdft_w[k2 + 2];\n    wk1i = rdft_w[k2 + 3];\n    wk3r = rdft_wk3ri_second[k1 + 0];\n    wk3i = rdft_wk3ri_second[k1 + 1];\n    x0r = a[j + 8] + a[j + 10];\n    x0i = a[j + 9] + a[j + 11];\n    x1r = a[j + 8] - a[j + 10];\n    x1i = a[j + 9] - a[j + 11];\n    x2r = a[j + 12] + a[j + 14];\n    x2i = a[j + 13] + a[j + 15];\n    x3r = a[j + 12] - a[j + 14];\n    x3i = a[j + 13] - a[j + 15];\n    a[j + 8] = x0r + x2r;\n    a[j + 9] = x0i + x2i;\n    x0r -= x2r;\n    x0i -= x2i;\n    a[j + 12] = -wk2i * x0r - wk2r * x0i;\n    a[j + 13] = -wk2i * x0i + wk2r * x0r;\n    x0r = x1r - x3i;\n    x0i = x1i + x3r;\n    a[j + 10] = wk1r * x0r - wk1i * x0i;\n    a[j + 11] = wk1r * x0i + wk1i * x0r;\n    x0r = x1r + x3i;\n    x0i = x1i - x3r;\n    a[j + 14] = wk3r * x0r - wk3i * x0i;\n    a[j + 15] = wk3r * x0i + wk3i * x0r;\n  }\n}\n\nstatic void cftmdl_128_C(float *a) {\n  const int l = 8;\n  const int n = 128;\n  const int m = 32;\n  int j0, j1, j2, j3, k, k1, k2, m2;\n  float wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;\n  float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\n  for (j0 = 0; j0 < l; j0 += 2) {\n    j1 = j0 +  8;\n    j2 = j0 + 16;\n    j3 = j0 + 24;\n    x0r = a[j0 + 0] + a[j1 + 0];\n    x0i = a[j0 + 1] + a[j1 + 1];\n    x1r = a[j0 + 0] - a[j1 + 0];\n    x1i = a[j0 + 1] - a[j1 + 1];\n    x2r = a[j2 + 0] + a[j3 + 0];\n    x2i = a[j2 + 1] + a[j3 + 1];\n    x3r = a[j2 + 0] - a[j3 + 0];\n    x3i = a[j2 + 1] - a[j3 + 1];\n    a[j0 + 0] = x0r + x2r;\n    a[j0 + 1] = x0i + x2i;\n    a[j2 + 0] = x0r - x2r;\n    a[j2 + 1] = x0i - x2i;\n    a[j1 + 0] = x1r - x3i;\n    a[j1 + 1] = x1i + x3r;\n    a[j3 + 0] = x1r + x3i;\n    a[j3 + 1] = x1i - x3r;\n  }\n  wk1r = rdft_w[2];\n  for (j0 = m; j0 < l + m; j0 += 2) {\n    j1 = j0 +  8;\n    j2 = j0 + 16;\n    j3 = j0 + 24;\n    x0r = a[j0 + 0] + a[j1 + 0];\n    x0i = a[j0 + 1] + a[j1 + 1];\n    x1r = a[j0 + 0] - a[j1 + 0];\n    x1i = a[j0 + 1] - a[j1 + 1];\n    x2r = a[j2 + 0] + a[j3 + 0];\n    x2i = a[j2 + 1] + a[j3 + 1];\n    x3r = a[j2 + 0] - a[j3 + 0];\n    x3i = a[j2 + 1] - a[j3 + 1];\n    a[j0 + 0] = x0r + x2r;\n    a[j0 + 1] = x0i + x2i;\n    a[j2 + 0] = x2i - x0i;\n    a[j2 + 1] = x0r - x2r;\n    x0r = x1r - x3i;\n    x0i = x1i + x3r;\n    a[j1 + 0] = wk1r * (x0r - x0i);\n    a[j1 + 1] = wk1r * (x0r + x0i);\n    x0r = x3i + x1r;\n    x0i = x3r - x1i;\n    a[j3 + 0] = wk1r * (x0i - x0r);\n    a[j3 + 1] = wk1r * (x0i + x0r);\n  }\n  k1 = 0;\n  m2 = 2 * m;\n  for (k = m2; k < n; k += m2) {\n    k1 += 2;\n    k2 = 2 * k1;\n    wk2r = rdft_w[k1 + 0];\n    wk2i = rdft_w[k1 + 1];\n    wk1r = rdft_w[k2 + 0];\n    wk1i = rdft_w[k2 + 1];\n    wk3r = rdft_wk3ri_first[k1 + 0];\n    wk3i = rdft_wk3ri_first[k1 + 1];\n    for (j0 = k; j0 < l + k; j0 += 2) {\n      j1 = j0 +  8;\n      j2 = j0 + 16;\n      j3 = j0 + 24;\n      x0r = a[j0 + 0] + a[j1 + 0];\n      x0i = a[j0 + 1] + a[j1 + 1];\n      x1r = a[j0 + 0] - a[j1 + 0];\n      x1i = a[j0 + 1] - a[j1 + 1];\n      x2r = a[j2 + 0] + a[j3 + 0];\n      x2i = a[j2 + 1] + a[j3 + 1];\n      x3r = a[j2 + 0] - a[j3 + 0];\n      x3i = a[j2 + 1] - a[j3 + 1];\n      a[j0 + 0] = x0r + x2r;\n      a[j0 + 1] = x0i + x2i;\n      x0r -= x2r;\n      x0i -= x2i;\n      a[j2 + 0] = wk2r * x0r - wk2i * x0i;\n      a[j2 + 1] = wk2r * x0i + wk2i * x0r;\n      x0r = x1r - x3i;\n      x0i = x1i + x3r;\n      a[j1 + 0] = wk1r * x0r - wk1i * x0i;\n      a[j1 + 1] = wk1r * x0i + wk1i * x0r;\n      x0r = x1r + x3i;\n      x0i = x1i - x3r;\n      a[j3 + 0] = wk3r * x0r - wk3i * x0i;\n      a[j3 + 1] = wk3r * x0i + wk3i * x0r;\n    }\n    wk1r = rdft_w[k2 + 2];\n    wk1i = rdft_w[k2 + 3];\n    wk3r = rdft_wk3ri_second[k1 + 0];\n    wk3i = rdft_wk3ri_second[k1 + 1];\n    for (j0 = k + m; j0 < l + (k + m); j0 += 2) {\n      j1 = j0 +  8;\n      j2 = j0 + 16;\n      j3 = j0 + 24;\n      x0r = a[j0 + 0] + a[j1 + 0];\n      x0i = a[j0 + 1] + a[j1 + 1];\n      x1r = a[j0 + 0] - a[j1 + 0];\n      x1i = a[j0 + 1] - a[j1 + 1];\n      x2r = a[j2 + 0] + a[j3 + 0];\n      x2i = a[j2 + 1] + a[j3 + 1];\n      x3r = a[j2 + 0] - a[j3 + 0];\n      x3i = a[j2 + 1] - a[j3 + 1];\n      a[j0 + 0] = x0r + x2r;\n      a[j0 + 1] = x0i + x2i;\n      x0r -= x2r;\n      x0i -= x2i;\n      a[j2 + 0] = -wk2i * x0r - wk2r * x0i;\n      a[j2 + 1] = -wk2i * x0i + wk2r * x0r;\n      x0r = x1r - x3i;\n      x0i = x1i + x3r;\n      a[j1 + 0] = wk1r * x0r - wk1i * x0i;\n      a[j1 + 1] = wk1r * x0i + wk1i * x0r;\n      x0r = x1r + x3i;\n      x0i = x1i - x3r;\n      a[j3 + 0] = wk3r * x0r - wk3i * x0i;\n      a[j3 + 1] = wk3r * x0i + wk3i * x0r;\n    }\n  }\n}\n\nstatic void cftfsub_128(float *a) {\n  int j, j1, j2, j3, l;\n  float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\n  cft1st_128(a);\n  cftmdl_128(a);\n  l = 32;\n  for (j = 0; j < l; j += 2) {\n    j1 = j + l;\n    j2 = j1 + l;\n    j3 = j2 + l;\n    x0r = a[j] + a[j1];\n    x0i = a[j + 1] + a[j1 + 1];\n    x1r = a[j] - a[j1];\n    x1i = a[j + 1] - a[j1 + 1];\n    x2r = a[j2] + a[j3];\n    x2i = a[j2 + 1] + a[j3 + 1];\n    x3r = a[j2] - a[j3];\n    x3i = a[j2 + 1] - a[j3 + 1];\n    a[j] = x0r + x2r;\n    a[j + 1] = x0i + x2i;\n    a[j2] = x0r - x2r;\n    a[j2 + 1] = x0i - x2i;\n    a[j1] = x1r - x3i;\n    a[j1 + 1] = x1i + x3r;\n    a[j3] = x1r + x3i;\n    a[j3 + 1] = x1i - x3r;\n  }\n}\n\nstatic void cftbsub_128(float *a) {\n  int j, j1, j2, j3, l;\n  float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\n  cft1st_128(a);\n  cftmdl_128(a);\n  l = 32;\n\n  for (j = 0; j < l; j += 2) {\n    j1 = j + l;\n    j2 = j1 + l;\n    j3 = j2 + l;\n    x0r = a[j] + a[j1];\n    x0i = -a[j + 1] - a[j1 + 1];\n    x1r = a[j] - a[j1];\n    x1i = -a[j + 1] + a[j1 + 1];\n    x2r = a[j2] + a[j3];\n    x2i = a[j2 + 1] + a[j3 + 1];\n    x3r = a[j2] - a[j3];\n    x3i = a[j2 + 1] - a[j3 + 1];\n    a[j] = x0r + x2r;\n    a[j + 1] = x0i - x2i;\n    a[j2] = x0r - x2r;\n    a[j2 + 1] = x0i + x2i;\n    a[j1] = x1r - x3i;\n    a[j1 + 1] = x1i - x3r;\n    a[j3] = x1r + x3i;\n    a[j3 + 1] = x1i + x3r;\n  }\n}\n\nstatic void rftfsub_128_C(float *a) {\n  const float *c = rdft_w + 32;\n  int j1, j2, k1, k2;\n  float wkr, wki, xr, xi, yr, yi;\n\n  for (j1 = 1, j2 = 2; j2 < 64; j1 += 1, j2 += 2) {\n    k2 = 128 - j2;\n    k1 =  32 - j1;\n    wkr = 0.5f - c[k1];\n    wki = c[j1];\n    xr = a[j2 + 0] - a[k2 + 0];\n    xi = a[j2 + 1] + a[k2 + 1];\n    yr = wkr * xr - wki * xi;\n    yi = wkr * xi + wki * xr;\n    a[j2 + 0] -= yr;\n    a[j2 + 1] -= yi;\n    a[k2 + 0] += yr;\n    a[k2 + 1] -= yi;\n  }\n}\n\nstatic void rftbsub_128_C(float *a) {\n  const float *c = rdft_w + 32;\n  int j1, j2, k1, k2;\n  float wkr, wki, xr, xi, yr, yi;\n\n  a[1] = -a[1];\n  for (j1 = 1, j2 = 2; j2 < 64; j1 += 1, j2 += 2) {\n    k2 = 128 - j2;\n    k1 =  32 - j1;\n    wkr = 0.5f - c[k1];\n    wki = c[j1];\n    xr = a[j2 + 0] - a[k2 + 0];\n    xi = a[j2 + 1] + a[k2 + 1];\n    yr = wkr * xr + wki * xi;\n    yi = wkr * xi - wki * xr;\n    a[j2 + 0] = a[j2 + 0] - yr;\n    a[j2 + 1] = yi - a[j2 + 1];\n    a[k2 + 0] = yr + a[k2 + 0];\n    a[k2 + 1] = yi - a[k2 + 1];\n  }\n  a[65] = -a[65];\n}\n\nvoid aec_rdft_forward_128(float *a) {\n  const int n = 128;\n  float xi;\n\n  bitrv2_32or128(n, ip + 2, a);\n  cftfsub_128(a);\n  rftfsub_128(a);\n  xi = a[0] - a[1];\n  a[0] += a[1];\n  a[1] = xi;\n}\n\nvoid aec_rdft_inverse_128(float *a) {\n  const int n = 128;\n\n  a[1] = 0.5f * (a[0] - a[1]);\n  a[0] -= a[1];\n  rftbsub_128(a);\n  bitrv2_32or128(n, ip + 2, a);\n  cftbsub_128(a);\n}\n\n// code path selection\nrft_sub_128_t cft1st_128;\nrft_sub_128_t cftmdl_128;\nrft_sub_128_t rftfsub_128;\nrft_sub_128_t rftbsub_128;\n\nvoid aec_rdft_init(void) {\n  cft1st_128 = cft1st_128_C;\n  cftmdl_128 = cftmdl_128_C;\n  rftfsub_128 = rftfsub_128_C;\n  rftbsub_128 = rftbsub_128_C;\n  if (WebRtc_GetCPUInfo(kSSE2)) {\n#if defined(WEBRTC_USE_SSE2)\n    aec_rdft_init_sse2();\n#endif\n  }\n  // init library constants.\n  makewt_32();\n  makect_32();\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/aec/main/source/aec_rdft.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_RDFT_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_RDFT_H_\n\n#ifdef _MSC_VER /* visual c++ */\n# define ALIGN16_BEG __declspec(align(16))\n# define ALIGN16_END\n#else /* gcc or icc */\n# define ALIGN16_BEG\n# define ALIGN16_END __attribute__((aligned(16)))\n#endif\n\n// constants shared by all paths (C, SSE2).\nextern float rdft_w[64];\n// constants used by the C path.\nextern float rdft_wk3ri_first[32];\nextern float rdft_wk3ri_second[32];\n// constants used by SSE2 but initialized in C path.\nextern float rdft_wk1r[32];\nextern float rdft_wk2r[32];\nextern float rdft_wk3r[32];\nextern float rdft_wk1i[32];\nextern float rdft_wk2i[32];\nextern float rdft_wk3i[32];\nextern float cftmdl_wk1r[4];\n\n// code path selection function pointers\ntypedef void (*rft_sub_128_t)(float *a);\nextern rft_sub_128_t rftfsub_128;\nextern rft_sub_128_t rftbsub_128;\nextern rft_sub_128_t cft1st_128;\nextern rft_sub_128_t cftmdl_128;\n\n// entry points\nvoid aec_rdft_init(void);\nvoid aec_rdft_init_sse2(void);\nvoid aec_rdft_forward_128(float *a);\nvoid aec_rdft_inverse_128(float *a);\n\n#endif  // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_RDFT_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/aec/main/source/aec_rdft_sse2.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"typedefs.h\"\n\n#if defined(WEBRTC_USE_SSE2)\n#include <emmintrin.h>\n\n#include \"aec_rdft.h\"\n\nstatic const ALIGN16_BEG float ALIGN16_END k_swap_sign[4] =\n  {-1.f, 1.f, -1.f, 1.f};\n\nstatic void cft1st_128_SSE2(float *a) {\n  const __m128 mm_swap_sign = _mm_load_ps(k_swap_sign);\n  int j, k2;\n\n  for (k2 = 0, j = 0; j < 128; j += 16, k2 += 4) {\n          __m128 a00v   = _mm_loadu_ps(&a[j +  0]);\n          __m128 a04v   = _mm_loadu_ps(&a[j +  4]);\n          __m128 a08v   = _mm_loadu_ps(&a[j +  8]);\n          __m128 a12v   = _mm_loadu_ps(&a[j + 12]);\n          __m128 a01v   = _mm_shuffle_ps(a00v, a08v, _MM_SHUFFLE(1, 0, 1 ,0));\n          __m128 a23v   = _mm_shuffle_ps(a00v, a08v, _MM_SHUFFLE(3, 2, 3 ,2));\n          __m128 a45v   = _mm_shuffle_ps(a04v, a12v, _MM_SHUFFLE(1, 0, 1 ,0));\n          __m128 a67v   = _mm_shuffle_ps(a04v, a12v, _MM_SHUFFLE(3, 2, 3 ,2));\n\n    const __m128 wk1rv  = _mm_load_ps(&rdft_wk1r[k2]);\n    const __m128 wk1iv  = _mm_load_ps(&rdft_wk1i[k2]);\n    const __m128 wk2rv  = _mm_load_ps(&rdft_wk2r[k2]);\n    const __m128 wk2iv  = _mm_load_ps(&rdft_wk2i[k2]);\n    const __m128 wk3rv  = _mm_load_ps(&rdft_wk3r[k2]);\n    const __m128 wk3iv  = _mm_load_ps(&rdft_wk3i[k2]);\n          __m128 x0v    = _mm_add_ps(a01v, a23v);\n    const __m128 x1v    = _mm_sub_ps(a01v, a23v);\n    const __m128 x2v    = _mm_add_ps(a45v, a67v);\n    const __m128 x3v    = _mm_sub_ps(a45v, a67v);\n                 a01v   = _mm_add_ps(x0v, x2v);\n                 x0v    = _mm_sub_ps(x0v, x2v);\n          __m128 x0w    = _mm_shuffle_ps(x0v, x0v, _MM_SHUFFLE(2, 3, 0 ,1));\n\n    const __m128 a45_0v = _mm_mul_ps(wk2rv, x0v);\n    const __m128 a45_1v = _mm_mul_ps(wk2iv, x0w);\n                 a45v   = _mm_add_ps(a45_0v, a45_1v);\n\n    const __m128 x3w    = _mm_shuffle_ps(x3v, x3v, _MM_SHUFFLE(2, 3, 0 ,1));\n    const __m128 x3s    = _mm_mul_ps(mm_swap_sign, x3w);\n                 x0v    = _mm_add_ps(x1v, x3s);\n                 x0w    = _mm_shuffle_ps(x0v, x0v, _MM_SHUFFLE(2, 3, 0 ,1));\n    const __m128 a23_0v = _mm_mul_ps(wk1rv, x0v);\n    const __m128 a23_1v = _mm_mul_ps(wk1iv, x0w);\n                 a23v   = _mm_add_ps(a23_0v, a23_1v);\n\n                 x0v    = _mm_sub_ps(x1v, x3s);\n                 x0w    = _mm_shuffle_ps(x0v, x0v, _MM_SHUFFLE(2, 3, 0 ,1));\n    const __m128 a67_0v = _mm_mul_ps(wk3rv, x0v);\n    const __m128 a67_1v = _mm_mul_ps(wk3iv, x0w);\n                 a67v   = _mm_add_ps(a67_0v, a67_1v);\n\n                 a00v   = _mm_shuffle_ps(a01v, a23v, _MM_SHUFFLE(1, 0, 1 ,0));\n                 a04v   = _mm_shuffle_ps(a45v, a67v, _MM_SHUFFLE(1, 0, 1 ,0));\n                 a08v   = _mm_shuffle_ps(a01v, a23v, _MM_SHUFFLE(3, 2, 3 ,2));\n                 a12v   = _mm_shuffle_ps(a45v, a67v, _MM_SHUFFLE(3, 2, 3 ,2));\n    _mm_storeu_ps(&a[j +  0], a00v);\n    _mm_storeu_ps(&a[j +  4], a04v);\n    _mm_storeu_ps(&a[j +  8], a08v);\n    _mm_storeu_ps(&a[j + 12], a12v);\n  }\n}\n\nstatic void cftmdl_128_SSE2(float *a) {\n  const int l = 8;\n  const __m128 mm_swap_sign = _mm_load_ps(k_swap_sign);\n  int j0, k, k1, k2;\n\n  __m128 wk1rv = _mm_load_ps(cftmdl_wk1r);\n  for (j0 = 0; j0 < l; j0 += 2) {\n    const __m128i a_00 = _mm_loadl_epi64((__m128i*)&a[j0 +  0]);\n    const __m128i a_08 = _mm_loadl_epi64((__m128i*)&a[j0 +  8]);\n    const __m128i a_32 = _mm_loadl_epi64((__m128i*)&a[j0 + 32]);\n    const __m128i a_40 = _mm_loadl_epi64((__m128i*)&a[j0 + 40]);\n    const __m128  a_00_32 = _mm_shuffle_ps((__m128)a_00, (__m128)a_32,\n                                           _MM_SHUFFLE(1, 0, 1 ,0));\n    const __m128  a_08_40 = _mm_shuffle_ps((__m128)a_08, (__m128)a_40,\n                                           _MM_SHUFFLE(1, 0, 1 ,0));\n          __m128  x0r0_0i0_0r1_x0i1 = _mm_add_ps(a_00_32, a_08_40);\n    const __m128  x1r0_1i0_1r1_x1i1 = _mm_sub_ps(a_00_32, a_08_40);\n\n    const __m128i a_16 = _mm_loadl_epi64((__m128i*)&a[j0 + 16]);\n    const __m128i a_24 = _mm_loadl_epi64((__m128i*)&a[j0 + 24]);\n    const __m128i a_48 = _mm_loadl_epi64((__m128i*)&a[j0 + 48]);\n    const __m128i a_56 = _mm_loadl_epi64((__m128i*)&a[j0 + 56]);\n    const __m128  a_16_48 = _mm_shuffle_ps((__m128)a_16, (__m128)a_48,\n                                           _MM_SHUFFLE(1, 0, 1 ,0));\n    const __m128  a_24_56 = _mm_shuffle_ps((__m128)a_24, (__m128)a_56,\n                                           _MM_SHUFFLE(1, 0, 1 ,0));\n    const __m128  x2r0_2i0_2r1_x2i1 = _mm_add_ps(a_16_48, a_24_56);\n    const __m128  x3r0_3i0_3r1_x3i1 = _mm_sub_ps(a_16_48, a_24_56);\n\n    const __m128  xx0 = _mm_add_ps(x0r0_0i0_0r1_x0i1, x2r0_2i0_2r1_x2i1);\n    _mm_storel_epi64((__m128i*)&a[j0 +  0], (__m128i)xx0);\n    _mm_storel_epi64((__m128i*)&a[j0 + 32],\n                     _mm_shuffle_epi32((__m128i)xx0, _MM_SHUFFLE(3, 2, 3, 2)));\n    const __m128  xx1 = _mm_sub_ps(x0r0_0i0_0r1_x0i1, x2r0_2i0_2r1_x2i1);\n    _mm_storel_epi64((__m128i*)&a[j0 + 16], (__m128i)xx1);\n    _mm_storel_epi64((__m128i*)&a[j0 + 48],\n                     _mm_shuffle_epi32((__m128i)xx1, _MM_SHUFFLE(2, 3, 2, 3)));\n    a[j0 + 48] = -a[j0 + 48];\n\n    const __m128  x3i0_3r0_3i1_x3r1 = (__m128)\n        _mm_shuffle_epi32((__m128i)x3r0_3i0_3r1_x3i1, _MM_SHUFFLE(2, 3, 0, 1));\n    const __m128  x3_swapped = _mm_mul_ps(mm_swap_sign, x3i0_3r0_3i1_x3r1);\n    const __m128  x1_x3_add = _mm_add_ps(x1r0_1i0_1r1_x1i1, x3_swapped);\n    const __m128  x1_x3_sub = _mm_sub_ps(x1r0_1i0_1r1_x1i1, x3_swapped);\n    _mm_storel_epi64((__m128i*)&a[j0 +  8], (__m128i)x1_x3_add);\n    _mm_storel_epi64((__m128i*)&a[j0 + 24], (__m128i)x1_x3_sub);\n\n    const __m128 yy0 = _mm_shuffle_ps(x1_x3_add, x1_x3_sub,\n                                      _MM_SHUFFLE(2, 2, 2 ,2));\n    const __m128 yy1 = _mm_shuffle_ps(x1_x3_add, x1_x3_sub,\n                                      _MM_SHUFFLE(3, 3, 3 ,3));\n    const __m128 yy2 = _mm_mul_ps(mm_swap_sign, yy1);\n    const __m128 yy3 = _mm_add_ps(yy0, yy2);\n    const __m128 yy4 = _mm_mul_ps(wk1rv, yy3);\n    _mm_storel_epi64((__m128i*)&a[j0 + 40], (__m128i)yy4);\n    _mm_storel_epi64((__m128i*)&a[j0 + 56],\n                     _mm_shuffle_epi32((__m128i)yy4, _MM_SHUFFLE(2, 3, 2, 3)));\n  }\n\n  k1 = 0;\n  k = 64;\n  k1 += 2;\n  k2 = 2 * k1;\n  const __m128 wk2rv = _mm_load_ps(&rdft_wk2r[k2+0]);\n  const __m128 wk2iv = _mm_load_ps(&rdft_wk2i[k2+0]);\n               wk1rv = _mm_load_ps(&rdft_wk1r[k2+0]);\n  const __m128 wk1iv = _mm_load_ps(&rdft_wk1i[k2+0]);\n  const __m128 wk3rv = _mm_load_ps(&rdft_wk3r[k2+0]);\n  const __m128 wk3iv = _mm_load_ps(&rdft_wk3i[k2+0]);\n  for (j0 = k; j0 < l + k; j0 += 2) {\n    const __m128i a_00 = _mm_loadl_epi64((__m128i*)&a[j0 +  0]);\n    const __m128i a_08 = _mm_loadl_epi64((__m128i*)&a[j0 +  8]);\n    const __m128i a_32 = _mm_loadl_epi64((__m128i*)&a[j0 + 32]);\n    const __m128i a_40 = _mm_loadl_epi64((__m128i*)&a[j0 + 40]);\n    const __m128 a_00_32 = _mm_shuffle_ps((__m128)a_00, (__m128)a_32,\n                                          _MM_SHUFFLE(1, 0, 1 ,0));\n    const __m128 a_08_40 = _mm_shuffle_ps((__m128)a_08, (__m128)a_40,\n                                          _MM_SHUFFLE(1, 0, 1 ,0));\n          __m128 x0r0_0i0_0r1_x0i1 = _mm_add_ps(a_00_32, a_08_40);\n    const __m128 x1r0_1i0_1r1_x1i1 = _mm_sub_ps(a_00_32, a_08_40);\n\n    const __m128i a_16 = _mm_loadl_epi64((__m128i*)&a[j0 + 16]);\n    const __m128i a_24 = _mm_loadl_epi64((__m128i*)&a[j0 + 24]);\n    const __m128i a_48 = _mm_loadl_epi64((__m128i*)&a[j0 + 48]);\n    const __m128i a_56 = _mm_loadl_epi64((__m128i*)&a[j0 + 56]);\n    const __m128 a_16_48 = _mm_shuffle_ps((__m128)a_16, (__m128)a_48,\n                                          _MM_SHUFFLE(1, 0, 1 ,0));\n    const __m128 a_24_56 = _mm_shuffle_ps((__m128)a_24, (__m128)a_56,\n                                          _MM_SHUFFLE(1, 0, 1 ,0));\n    const __m128 x2r0_2i0_2r1_x2i1 = _mm_add_ps(a_16_48, a_24_56);\n    const __m128 x3r0_3i0_3r1_x3i1 = _mm_sub_ps(a_16_48, a_24_56);\n\n    const __m128 xx = _mm_add_ps(x0r0_0i0_0r1_x0i1, x2r0_2i0_2r1_x2i1);\n    _mm_storel_epi64((__m128i*)&a[j0 +  0], (__m128i)xx);\n    _mm_storel_epi64((__m128i*)&a[j0 + 32],\n                       _mm_shuffle_epi32((__m128i)xx, _MM_SHUFFLE(3, 2, 3, 2)));\n\n    const __m128 xx1 = _mm_sub_ps(x0r0_0i0_0r1_x0i1, x2r0_2i0_2r1_x2i1);\n    const __m128 xx2 = _mm_mul_ps(xx1 , wk2rv);\n    const __m128 xx3 = _mm_mul_ps(wk2iv,\n              (__m128)_mm_shuffle_epi32((__m128i)xx1, _MM_SHUFFLE(2, 3, 0, 1)));\n    const __m128 xx4 = _mm_add_ps(xx2, xx3);\n    _mm_storel_epi64((__m128i*)&a[j0 + 16], (__m128i)xx4);\n    _mm_storel_epi64((__m128i*)&a[j0 + 48],\n                      _mm_shuffle_epi32((__m128i)xx4, _MM_SHUFFLE(3, 2, 3, 2)));\n\n    const __m128  x3i0_3r0_3i1_x3r1 = (__m128)\n         _mm_shuffle_epi32((__m128i)x3r0_3i0_3r1_x3i1, _MM_SHUFFLE(2, 3, 0, 1));\n    const __m128  x3_swapped = _mm_mul_ps(mm_swap_sign, x3i0_3r0_3i1_x3r1);\n    const __m128  x1_x3_add = _mm_add_ps(x1r0_1i0_1r1_x1i1, x3_swapped);\n    const __m128  x1_x3_sub = _mm_sub_ps(x1r0_1i0_1r1_x1i1, x3_swapped);\n\n    const __m128 xx10 = _mm_mul_ps(x1_x3_add, wk1rv);\n    const __m128 xx11 = _mm_mul_ps(wk1iv,\n        (__m128)_mm_shuffle_epi32((__m128i)x1_x3_add, _MM_SHUFFLE(2, 3, 0, 1)));\n    const __m128 xx12 = _mm_add_ps(xx10, xx11);\n    _mm_storel_epi64((__m128i*)&a[j0 +  8], (__m128i)xx12);\n    _mm_storel_epi64((__m128i*)&a[j0 + 40],\n                     _mm_shuffle_epi32((__m128i)xx12, _MM_SHUFFLE(3, 2, 3, 2)));\n\n    const __m128 xx20 = _mm_mul_ps(x1_x3_sub, wk3rv);\n    const __m128 xx21 = _mm_mul_ps(wk3iv,\n        (__m128)_mm_shuffle_epi32((__m128i)x1_x3_sub, _MM_SHUFFLE(2, 3, 0, 1)));\n    const __m128 xx22 = _mm_add_ps(xx20, xx21);\n    _mm_storel_epi64((__m128i*)&a[j0 + 24], (__m128i)xx22);\n    _mm_storel_epi64((__m128i*)&a[j0 + 56],\n                     _mm_shuffle_epi32((__m128i)xx22, _MM_SHUFFLE(3, 2, 3, 2)));\n  }\n}\n\nstatic void rftfsub_128_SSE2(float *a) {\n  const float *c = rdft_w + 32;\n  int j1, j2, k1, k2;\n  float wkr, wki, xr, xi, yr, yi;\n\n  static const ALIGN16_BEG float ALIGN16_END k_half[4] =\n    {0.5f, 0.5f, 0.5f, 0.5f};\n  const __m128 mm_half = _mm_load_ps(k_half);\n\n  // Vectorized code (four at once).\n  //    Note: commented number are indexes for the first iteration of the loop.\n  for (j1 = 1, j2 = 2; j2 + 7 < 64; j1 += 4, j2 += 8) {\n    // Load 'wk'.\n    const __m128 c_j1 = _mm_loadu_ps(&c[     j1]);         //  1,  2,  3,  4,\n    const __m128 c_k1 = _mm_loadu_ps(&c[29 - j1]);         // 28, 29, 30, 31,\n    const __m128 wkrt = _mm_sub_ps(mm_half, c_k1);         // 28, 29, 30, 31,\n    const __m128 wkr_ =\n      _mm_shuffle_ps(wkrt, wkrt, _MM_SHUFFLE(0, 1, 2, 3)); // 31, 30, 29, 28,\n    const __m128 wki_ = c_j1;                              //  1,  2,  3,  4,\n    // Load and shuffle 'a'.\n    const __m128 a_j2_0 = _mm_loadu_ps(&a[0   + j2]);  //   2,   3,   4,   5,\n    const __m128 a_j2_4 = _mm_loadu_ps(&a[4   + j2]);  //   6,   7,   8,   9,\n    const __m128 a_k2_0 = _mm_loadu_ps(&a[122 - j2]);  // 120, 121, 122, 123,\n    const __m128 a_k2_4 = _mm_loadu_ps(&a[126 - j2]);  // 124, 125, 126, 127,\n    const __m128 a_j2_p0 = _mm_shuffle_ps(a_j2_0, a_j2_4,\n                            _MM_SHUFFLE(2, 0, 2 ,0));  //   2,   4,   6,   8,\n    const __m128 a_j2_p1 = _mm_shuffle_ps(a_j2_0, a_j2_4,\n                            _MM_SHUFFLE(3, 1, 3 ,1));  //   3,   5,   7,   9,\n    const __m128 a_k2_p0 = _mm_shuffle_ps(a_k2_4, a_k2_0,\n                            _MM_SHUFFLE(0, 2, 0 ,2));  // 126, 124, 122, 120,\n    const __m128 a_k2_p1 = _mm_shuffle_ps(a_k2_4, a_k2_0,\n                            _MM_SHUFFLE(1, 3, 1 ,3));  // 127, 125, 123, 121,\n    // Calculate 'x'.\n    const __m128 xr_ = _mm_sub_ps(a_j2_p0, a_k2_p0);\n                                               // 2-126, 4-124, 6-122, 8-120,\n    const __m128 xi_ = _mm_add_ps(a_j2_p1, a_k2_p1);\n                                               // 3-127, 5-125, 7-123, 9-121,\n    // Calculate product into 'y'.\n    //    yr = wkr * xr - wki * xi;\n    //    yi = wkr * xi + wki * xr;\n    const __m128 a_ = _mm_mul_ps(wkr_, xr_);\n    const __m128 b_ = _mm_mul_ps(wki_, xi_);\n    const __m128 c_ = _mm_mul_ps(wkr_, xi_);\n    const __m128 d_ = _mm_mul_ps(wki_, xr_);\n    const __m128 yr_ = _mm_sub_ps(a_, b_);     // 2-126, 4-124, 6-122, 8-120,\n    const __m128 yi_ = _mm_add_ps(c_, d_);     // 3-127, 5-125, 7-123, 9-121,\n    // Update 'a'.\n    //    a[j2 + 0] -= yr;\n    //    a[j2 + 1] -= yi;\n    //    a[k2 + 0] += yr;\n    //    a[k2 + 1] -= yi;\n    const __m128 a_j2_p0n = _mm_sub_ps(a_j2_p0, yr_);  //   2,   4,   6,   8,\n    const __m128 a_j2_p1n = _mm_sub_ps(a_j2_p1, yi_);  //   3,   5,   7,   9,\n    const __m128 a_k2_p0n = _mm_add_ps(a_k2_p0, yr_);  // 126, 124, 122, 120,\n    const __m128 a_k2_p1n = _mm_sub_ps(a_k2_p1, yi_);  // 127, 125, 123, 121,\n    // Shuffle in right order and store.\n    const __m128 a_j2_0n = _mm_unpacklo_ps(a_j2_p0n, a_j2_p1n);\n                                                       //   2,   3,   4,   5,\n    const __m128 a_j2_4n = _mm_unpackhi_ps(a_j2_p0n, a_j2_p1n);\n                                                       //   6,   7,   8,   9,\n    const __m128 a_k2_0nt = _mm_unpackhi_ps(a_k2_p0n, a_k2_p1n);\n                                                       // 122, 123, 120, 121,\n    const __m128 a_k2_4nt = _mm_unpacklo_ps(a_k2_p0n, a_k2_p1n);\n                                                       // 126, 127, 124, 125,\n    const __m128 a_k2_0n = _mm_shuffle_ps(a_k2_0nt, a_k2_0nt,\n                            _MM_SHUFFLE(1, 0, 3 ,2));  // 120, 121, 122, 123,\n    const __m128 a_k2_4n = _mm_shuffle_ps(a_k2_4nt, a_k2_4nt,\n                            _MM_SHUFFLE(1, 0, 3 ,2));  // 124, 125, 126, 127,\n    _mm_storeu_ps(&a[0   + j2], a_j2_0n);\n    _mm_storeu_ps(&a[4   + j2], a_j2_4n);\n    _mm_storeu_ps(&a[122 - j2], a_k2_0n);\n    _mm_storeu_ps(&a[126 - j2], a_k2_4n);\n  }\n  // Scalar code for the remaining items.\n  for (; j2 < 64; j1 += 1, j2 += 2) {\n    k2 = 128 - j2;\n    k1 =  32 - j1;\n    wkr = 0.5f - c[k1];\n    wki = c[j1];\n    xr = a[j2 + 0] - a[k2 + 0];\n    xi = a[j2 + 1] + a[k2 + 1];\n    yr = wkr * xr - wki * xi;\n    yi = wkr * xi + wki * xr;\n    a[j2 + 0] -= yr;\n    a[j2 + 1] -= yi;\n    a[k2 + 0] += yr;\n    a[k2 + 1] -= yi;\n  }\n}\n\nstatic void rftbsub_128_SSE2(float *a) {\n  const float *c = rdft_w + 32;\n  int j1, j2, k1, k2;\n  float wkr, wki, xr, xi, yr, yi;\n\n  static const ALIGN16_BEG float ALIGN16_END k_half[4] =\n    {0.5f, 0.5f, 0.5f, 0.5f};\n  const __m128 mm_half = _mm_load_ps(k_half);\n\n  a[1] = -a[1];\n  // Vectorized code (four at once).\n  //    Note: commented number are indexes for the first iteration of the loop.\n  for (j1 = 1, j2 = 2; j2 + 7 < 64; j1 += 4, j2 += 8) {\n    // Load 'wk'.\n    const __m128 c_j1 = _mm_loadu_ps(&c[     j1]);         //  1,  2,  3,  4,\n    const __m128 c_k1 = _mm_loadu_ps(&c[29 - j1]);         // 28, 29, 30, 31,\n    const __m128 wkrt = _mm_sub_ps(mm_half, c_k1);         // 28, 29, 30, 31,\n    const __m128 wkr_ =\n      _mm_shuffle_ps(wkrt, wkrt, _MM_SHUFFLE(0, 1, 2, 3)); // 31, 30, 29, 28,\n    const __m128 wki_ = c_j1;                              //  1,  2,  3,  4,\n    // Load and shuffle 'a'.\n    const __m128 a_j2_0 = _mm_loadu_ps(&a[0   + j2]);  //   2,   3,   4,   5,\n    const __m128 a_j2_4 = _mm_loadu_ps(&a[4   + j2]);  //   6,   7,   8,   9,\n    const __m128 a_k2_0 = _mm_loadu_ps(&a[122 - j2]);  // 120, 121, 122, 123,\n    const __m128 a_k2_4 = _mm_loadu_ps(&a[126 - j2]);  // 124, 125, 126, 127,\n    const __m128 a_j2_p0 = _mm_shuffle_ps(a_j2_0, a_j2_4,\n                            _MM_SHUFFLE(2, 0, 2 ,0));  //   2,   4,   6,   8,\n    const __m128 a_j2_p1 = _mm_shuffle_ps(a_j2_0, a_j2_4,\n                            _MM_SHUFFLE(3, 1, 3 ,1));  //   3,   5,   7,   9,\n    const __m128 a_k2_p0 = _mm_shuffle_ps(a_k2_4, a_k2_0,\n                            _MM_SHUFFLE(0, 2, 0 ,2));  // 126, 124, 122, 120,\n    const __m128 a_k2_p1 = _mm_shuffle_ps(a_k2_4, a_k2_0,\n                            _MM_SHUFFLE(1, 3, 1 ,3));  // 127, 125, 123, 121,\n    // Calculate 'x'.\n    const __m128 xr_ = _mm_sub_ps(a_j2_p0, a_k2_p0);\n                                               // 2-126, 4-124, 6-122, 8-120,\n    const __m128 xi_ = _mm_add_ps(a_j2_p1, a_k2_p1);\n                                               // 3-127, 5-125, 7-123, 9-121,\n    // Calculate product into 'y'.\n    //    yr = wkr * xr + wki * xi;\n    //    yi = wkr * xi - wki * xr;\n    const __m128 a_ = _mm_mul_ps(wkr_, xr_);\n    const __m128 b_ = _mm_mul_ps(wki_, xi_);\n    const __m128 c_ = _mm_mul_ps(wkr_, xi_);\n    const __m128 d_ = _mm_mul_ps(wki_, xr_);\n    const __m128 yr_ = _mm_add_ps(a_, b_);     // 2-126, 4-124, 6-122, 8-120,\n    const __m128 yi_ = _mm_sub_ps(c_, d_);     // 3-127, 5-125, 7-123, 9-121,\n    // Update 'a'.\n    //    a[j2 + 0] = a[j2 + 0] - yr;\n    //    a[j2 + 1] = yi - a[j2 + 1];\n    //    a[k2 + 0] = yr + a[k2 + 0];\n    //    a[k2 + 1] = yi - a[k2 + 1];\n    const __m128 a_j2_p0n = _mm_sub_ps(a_j2_p0, yr_);  //   2,   4,   6,   8,\n    const __m128 a_j2_p1n = _mm_sub_ps(yi_, a_j2_p1);  //   3,   5,   7,   9,\n    const __m128 a_k2_p0n = _mm_add_ps(a_k2_p0, yr_);  // 126, 124, 122, 120,\n    const __m128 a_k2_p1n = _mm_sub_ps(yi_, a_k2_p1);  // 127, 125, 123, 121,\n    // Shuffle in right order and store.\n    const __m128 a_j2_0n = _mm_unpacklo_ps(a_j2_p0n, a_j2_p1n);\n                                                       //   2,   3,   4,   5,\n    const __m128 a_j2_4n = _mm_unpackhi_ps(a_j2_p0n, a_j2_p1n);\n                                                       //   6,   7,   8,   9,\n    const __m128 a_k2_0nt = _mm_unpackhi_ps(a_k2_p0n, a_k2_p1n);\n                                                       // 122, 123, 120, 121,\n    const __m128 a_k2_4nt = _mm_unpacklo_ps(a_k2_p0n, a_k2_p1n);\n                                                       // 126, 127, 124, 125,\n    const __m128 a_k2_0n = _mm_shuffle_ps(a_k2_0nt, a_k2_0nt,\n                            _MM_SHUFFLE(1, 0, 3 ,2));  // 120, 121, 122, 123,\n    const __m128 a_k2_4n = _mm_shuffle_ps(a_k2_4nt, a_k2_4nt,\n                            _MM_SHUFFLE(1, 0, 3 ,2));  // 124, 125, 126, 127,\n    _mm_storeu_ps(&a[0   + j2], a_j2_0n);\n    _mm_storeu_ps(&a[4   + j2], a_j2_4n);\n    _mm_storeu_ps(&a[122 - j2], a_k2_0n);\n    _mm_storeu_ps(&a[126 - j2], a_k2_4n);\n  }\n  // Scalar code for the remaining items.\n  for (; j2 < 64; j1 += 1, j2 += 2) {\n    k2 = 128 - j2;\n    k1 =  32 - j1;\n    wkr = 0.5f - c[k1];\n    wki = c[j1];\n    xr = a[j2 + 0] - a[k2 + 0];\n    xi = a[j2 + 1] + a[k2 + 1];\n    yr = wkr * xr + wki * xi;\n    yi = wkr * xi - wki * xr;\n    a[j2 + 0] = a[j2 + 0] - yr;\n    a[j2 + 1] = yi - a[j2 + 1];\n    a[k2 + 0] = yr + a[k2 + 0];\n    a[k2 + 1] = yi - a[k2 + 1];\n  }\n  a[65] = -a[65];\n}\n\nvoid aec_rdft_init_sse2(void) {\n  cft1st_128 = cft1st_128_SSE2;\n  cftmdl_128 = cftmdl_128_SSE2;\n  rftfsub_128 = rftfsub_128_SSE2;\n  rftbsub_128 = rftbsub_128_SSE2;\n}\n\n#endif  // WEBRTC_USE_SS2\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/aec/main/source/echo_cancellation.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/*\n * Contains the API functions for the AEC.\n */\n#include <stdlib.h>\n#include <string.h>\n\n#include \"echo_cancellation.h\"\n#include \"aec_core.h\"\n#include \"ring_buffer.h\"\n#include \"resampler.h\"\n#ifdef AEC_DEBUG\n    #include <stdio.h>\n#endif\n\n#define BUF_SIZE_FRAMES 50 // buffer size (frames)\n// Maximum length of resampled signal. Must be an integer multiple of frames\n// (ceil(1/(1 + MIN_SKEW)*2) + 1)*FRAME_LEN\n// The factor of 2 handles wb, and the + 1 is as a safety margin\n#define MAX_RESAMP_LEN (5 * FRAME_LEN)\n\nstatic const int bufSizeSamp = BUF_SIZE_FRAMES * FRAME_LEN; // buffer size (samples)\nstatic const int sampMsNb = 8; // samples per ms in nb\n// Target suppression levels for nlp modes\n// log{0.001, 0.00001, 0.00000001}\nstatic const float targetSupp[3] = {-6.9f, -11.5f, -18.4f};\nstatic const float minOverDrive[3] = {1.0f, 2.0f, 5.0f};\nstatic const int initCheck = 42;\n\ntypedef struct {\n    int delayCtr;\n    int sampFreq;\n    int splitSampFreq;\n    int scSampFreq;\n    float sampFactor; // scSampRate / sampFreq\n    short nlpMode;\n    short autoOnOff;\n    short activity;\n    short skewMode;\n    short bufSizeStart;\n    //short bufResetCtr;  // counts number of noncausal frames\n    int knownDelay;\n\n    // Stores the last frame added to the farend buffer\n    short farendOld[2][FRAME_LEN];\n    short initFlag; // indicates if AEC has been initialized\n\n    // Variables used for averaging far end buffer size\n    short counter;\n    short sum;\n    short firstVal;\n    short checkBufSizeCtr;\n\n    // Variables used for delay shifts\n    short msInSndCardBuf;\n    short filtDelay;\n    int timeForDelayChange;\n    int ECstartup;\n    int checkBuffSize;\n    int delayChange;\n    short lastDelayDiff;\n\n#ifdef AEC_DEBUG\n    FILE *bufFile;\n    FILE *delayFile;\n    FILE *skewFile;\n    FILE *preCompFile;\n    FILE *postCompFile;\n#endif // AEC_DEBUG\n\n    // Structures\n    void *farendBuf;\n    void *resampler;\n\n    int skewFrCtr;\n    int resample; // if the skew is small enough we don't resample\n    int highSkewCtr;\n    float skew;\n\n    int lastError;\n\n    aec_t *aec;\n} aecpc_t;\n\n// Estimates delay to set the position of the farend buffer read pointer\n// (controlled by knownDelay)\nstatic int EstBufDelay(aecpc_t *aecInst, short msInSndCardBuf);\n\n// Stuffs the farend buffer if the estimated delay is too large\nstatic int DelayComp(aecpc_t *aecInst);\n\nWebRtc_Word32 WebRtcAec_Create(void **aecInst)\n{\n    aecpc_t *aecpc;\n    if (aecInst == NULL) {\n        return -1;\n    }\n\n    aecpc = malloc(sizeof(aecpc_t));\n    *aecInst = aecpc;\n    if (aecpc == NULL) {\n        return -1;\n    }\n\n    if (WebRtcAec_CreateAec(&aecpc->aec) == -1) {\n        WebRtcAec_Free(aecpc);\n        aecpc = NULL;\n        return -1;\n    }\n\n    if (WebRtcApm_CreateBuffer(&aecpc->farendBuf, bufSizeSamp) == -1) {\n        WebRtcAec_Free(aecpc);\n        aecpc = NULL;\n        return -1;\n    }\n\n    if (WebRtcAec_CreateResampler(&aecpc->resampler) == -1) {\n        WebRtcAec_Free(aecpc);\n        aecpc = NULL;\n        return -1;\n    }\n\n    aecpc->initFlag = 0;\n    aecpc->lastError = 0;\n\n#ifdef AEC_DEBUG\n    aecpc->aec->farFile = fopen(\"aecFar.pcm\",\"wb\");\n    aecpc->aec->nearFile = fopen(\"aecNear.pcm\",\"wb\");\n    aecpc->aec->outFile = fopen(\"aecOut.pcm\",\"wb\");\n    aecpc->aec->outLpFile = fopen(\"aecOutLp.pcm\",\"wb\");\n\n    aecpc->bufFile = fopen(\"aecBuf.dat\", \"wb\");\n    aecpc->skewFile = fopen(\"aecSkew.dat\", \"wb\");\n    aecpc->delayFile = fopen(\"aecDelay.dat\", \"wb\");\n    aecpc->preCompFile = fopen(\"preComp.pcm\", \"wb\");\n    aecpc->postCompFile = fopen(\"postComp.pcm\", \"wb\");\n#endif // AEC_DEBUG\n\n    return 0;\n}\n\nWebRtc_Word32 WebRtcAec_Free(void *aecInst)\n{\n    aecpc_t *aecpc = aecInst;\n\n    if (aecpc == NULL) {\n        return -1;\n    }\n\n#ifdef AEC_DEBUG\n    fclose(aecpc->aec->farFile);\n    fclose(aecpc->aec->nearFile);\n    fclose(aecpc->aec->outFile);\n    fclose(aecpc->aec->outLpFile);\n\n    fclose(aecpc->bufFile);\n    fclose(aecpc->skewFile);\n    fclose(aecpc->delayFile);\n    fclose(aecpc->preCompFile);\n    fclose(aecpc->postCompFile);\n#endif // AEC_DEBUG\n\n    WebRtcAec_FreeAec(aecpc->aec);\n    WebRtcApm_FreeBuffer(aecpc->farendBuf);\n    WebRtcAec_FreeResampler(aecpc->resampler);\n    free(aecpc);\n\n    return 0;\n}\n\nWebRtc_Word32 WebRtcAec_Init(void *aecInst, WebRtc_Word32 sampFreq, WebRtc_Word32 scSampFreq)\n{\n    aecpc_t *aecpc = aecInst;\n    AecConfig aecConfig;\n\n    if (aecpc == NULL) {\n        return -1;\n    }\n\n    if (sampFreq != 8000 && sampFreq != 16000  && sampFreq != 32000) {\n        aecpc->lastError = AEC_BAD_PARAMETER_ERROR;\n        return -1;\n    }\n    aecpc->sampFreq = sampFreq;\n\n    if (scSampFreq < 1 || scSampFreq > 96000) {\n        aecpc->lastError = AEC_BAD_PARAMETER_ERROR;\n        return -1;\n    }\n    aecpc->scSampFreq = scSampFreq;\n\n    // Initialize echo canceller core\n    if (WebRtcAec_InitAec(aecpc->aec, aecpc->sampFreq) == -1) {\n        aecpc->lastError = AEC_UNSPECIFIED_ERROR;\n        return -1;\n    }\n\n    // Initialize farend buffer\n    if (WebRtcApm_InitBuffer(aecpc->farendBuf) == -1) {\n        aecpc->lastError = AEC_UNSPECIFIED_ERROR;\n        return -1;\n    }\n\n    if (WebRtcAec_InitResampler(aecpc->resampler, aecpc->scSampFreq) == -1) {\n        aecpc->lastError = AEC_UNSPECIFIED_ERROR;\n        return -1;\n    }\n\n    aecpc->initFlag = initCheck;  // indicates that initilisation has been done\n\n    if (aecpc->sampFreq == 32000) {\n        aecpc->splitSampFreq = 16000;\n    }\n    else {\n        aecpc->splitSampFreq = sampFreq;\n    }\n\n    aecpc->skewFrCtr = 0;\n    aecpc->activity = 0;\n\n    aecpc->delayChange = 1;\n    aecpc->delayCtr = 0;\n\n    aecpc->sum = 0;\n    aecpc->counter = 0;\n    aecpc->checkBuffSize = 1;\n    aecpc->firstVal = 0;\n\n    aecpc->ECstartup = 1;\n    aecpc->bufSizeStart = 0;\n    aecpc->checkBufSizeCtr = 0;\n    aecpc->filtDelay = 0;\n    aecpc->timeForDelayChange =0;\n    aecpc->knownDelay = 0;\n    aecpc->lastDelayDiff = 0;\n\n    aecpc->skew = 0;\n    aecpc->resample = kAecFalse;\n    aecpc->highSkewCtr = 0;\n    aecpc->sampFactor = (aecpc->scSampFreq * 1.0f) / aecpc->splitSampFreq;\n\n    memset(&aecpc->farendOld[0][0], 0, 160);\n\n    // Default settings.\n    aecConfig.nlpMode = kAecNlpModerate;\n    aecConfig.skewMode = kAecFalse;\n    aecConfig.metricsMode = kAecFalse;\n\n    if (WebRtcAec_set_config(aecpc, aecConfig) == -1) {\n        aecpc->lastError = AEC_UNSPECIFIED_ERROR;\n        return -1;\n    }\n\n    return 0;\n}\n\n// only buffer L band for farend\nWebRtc_Word32 WebRtcAec_BufferFarend(void *aecInst, const WebRtc_Word16 *farend,\n    WebRtc_Word16 nrOfSamples)\n{\n    aecpc_t *aecpc = aecInst;\n    WebRtc_Word32 retVal = 0;\n    short newNrOfSamples;\n    short newFarend[MAX_RESAMP_LEN];\n    float skew;\n\n    if (aecpc == NULL) {\n        return -1;\n    }\n\n    if (farend == NULL) {\n        aecpc->lastError = AEC_NULL_POINTER_ERROR;\n        return -1;\n    }\n\n    if (aecpc->initFlag != initCheck) {\n        aecpc->lastError = AEC_UNINITIALIZED_ERROR;\n        return -1;\n    }\n\n    // number of samples == 160 for SWB input\n    if (nrOfSamples != 80 && nrOfSamples != 160) {\n        aecpc->lastError = AEC_BAD_PARAMETER_ERROR;\n        return -1;\n    }\n\n    skew = aecpc->skew;\n\n    // TODO: Is this really a good idea?\n    if (!aecpc->ECstartup) {\n        DelayComp(aecpc);\n    }\n\n    if (aecpc->skewMode == kAecTrue && aecpc->resample == kAecTrue) {\n        // Resample and get a new number of samples\n        newNrOfSamples = WebRtcAec_ResampleLinear(aecpc->resampler,\n                                                  farend,\n                                                  nrOfSamples,\n                                                  skew,\n                                                  newFarend);\n        WebRtcApm_WriteBuffer(aecpc->farendBuf, newFarend, newNrOfSamples);\n\n#ifdef AEC_DEBUG\n        fwrite(farend, 2, nrOfSamples, aecpc->preCompFile);\n        fwrite(newFarend, 2, newNrOfSamples, aecpc->postCompFile);\n#endif\n    }\n    else {\n        WebRtcApm_WriteBuffer(aecpc->farendBuf, farend, nrOfSamples);\n    }\n\n    return retVal;\n}\n\nWebRtc_Word32 WebRtcAec_Process(void *aecInst, const WebRtc_Word16 *nearend,\n    const WebRtc_Word16 *nearendH, WebRtc_Word16 *out, WebRtc_Word16 *outH,\n    WebRtc_Word16 nrOfSamples, WebRtc_Word16 msInSndCardBuf, WebRtc_Word32 skew)\n{\n    aecpc_t *aecpc = aecInst;\n    WebRtc_Word32 retVal = 0;\n    short i;\n    short farend[FRAME_LEN];\n    short nmbrOfFilledBuffers;\n    short nBlocks10ms;\n    short nFrames;\n#ifdef AEC_DEBUG\n    short msInAECBuf;\n#endif\n    // Limit resampling to doubling/halving of signal\n    const float minSkewEst = -0.5f;\n    const float maxSkewEst = 1.0f;\n\n    if (aecpc == NULL) {\n        return -1;\n    }\n\n    if (nearend == NULL) {\n        aecpc->lastError = AEC_NULL_POINTER_ERROR;\n        return -1;\n    }\n\n    if (out == NULL) {\n        aecpc->lastError = AEC_NULL_POINTER_ERROR;\n        return -1;\n    }\n\n    if (aecpc->initFlag != initCheck) {\n        aecpc->lastError = AEC_UNINITIALIZED_ERROR;\n        return -1;\n    }\n\n    // number of samples == 160 for SWB input\n    if (nrOfSamples != 80 && nrOfSamples != 160) {\n        aecpc->lastError = AEC_BAD_PARAMETER_ERROR;\n        return -1;\n    }\n\n    // Check for valid pointers based on sampling rate\n    if (aecpc->sampFreq == 32000 && nearendH == NULL) {\n       aecpc->lastError = AEC_NULL_POINTER_ERROR;\n       return -1;\n    }\n\n    if (msInSndCardBuf < 0) {\n        msInSndCardBuf = 0;\n        aecpc->lastError = AEC_BAD_PARAMETER_WARNING;\n        retVal = -1;\n    }\n    else if (msInSndCardBuf > 500) {\n        msInSndCardBuf = 500;\n        aecpc->lastError = AEC_BAD_PARAMETER_WARNING;\n        retVal = -1;\n    }\n    msInSndCardBuf += 10;\n    aecpc->msInSndCardBuf = msInSndCardBuf;\n\n    if (aecpc->skewMode == kAecTrue) {\n        if (aecpc->skewFrCtr < 25) {\n            aecpc->skewFrCtr++;\n        }\n        else {\n            retVal = WebRtcAec_GetSkew(aecpc->resampler, skew, &aecpc->skew);\n            if (retVal == -1) {\n                aecpc->skew = 0;\n                aecpc->lastError = AEC_BAD_PARAMETER_WARNING;\n            }\n\n            aecpc->skew /= aecpc->sampFactor*nrOfSamples;\n\n            if (aecpc->skew < 1.0e-3 && aecpc->skew > -1.0e-3) {\n                aecpc->resample = kAecFalse;\n            }\n            else {\n                aecpc->resample = kAecTrue;\n            }\n\n            if (aecpc->skew < minSkewEst) {\n                aecpc->skew = minSkewEst;\n            }\n            else if (aecpc->skew > maxSkewEst) {\n                aecpc->skew = maxSkewEst;\n            }\n\n#ifdef AEC_DEBUG\n            fwrite(&aecpc->skew, sizeof(aecpc->skew), 1, aecpc->skewFile);\n#endif\n        }\n    }\n\n    nFrames = nrOfSamples / FRAME_LEN;\n    nBlocks10ms = nFrames / aecpc->aec->mult;\n\n    if (aecpc->ECstartup) {\n        if (nearend != out) {\n            // Only needed if they don't already point to the same place.\n            memcpy(out, nearend, sizeof(short) * nrOfSamples);\n        }\n        nmbrOfFilledBuffers = WebRtcApm_get_buffer_size(aecpc->farendBuf) / FRAME_LEN;\n\n        // The AEC is in the start up mode\n        // AEC is disabled until the soundcard buffer and farend buffers are OK\n\n        // Mechanism to ensure that the soundcard buffer is reasonably stable.\n        if (aecpc->checkBuffSize) {\n\n            aecpc->checkBufSizeCtr++;\n            // Before we fill up the far end buffer we require the amount of data on the\n            // sound card to be stable (+/-8 ms) compared to the first value. This\n            // comparison is made during the following 4 consecutive frames. If it seems\n            // to be stable then we start to fill up the far end buffer.\n\n            if (aecpc->counter == 0) {\n                aecpc->firstVal = aecpc->msInSndCardBuf;\n                aecpc->sum = 0;\n            }\n\n            if (abs(aecpc->firstVal - aecpc->msInSndCardBuf) <\n                WEBRTC_SPL_MAX(0.2 * aecpc->msInSndCardBuf, sampMsNb)) {\n                aecpc->sum += aecpc->msInSndCardBuf;\n                aecpc->counter++;\n            }\n            else {\n                aecpc->counter = 0;\n            }\n\n            if (aecpc->counter*nBlocks10ms >= 6) {\n                // The farend buffer size is determined in blocks of 80 samples\n                // Use 75% of the average value of the soundcard buffer\n                aecpc->bufSizeStart = WEBRTC_SPL_MIN((int) (0.75 * (aecpc->sum *\n                    aecpc->aec->mult) / (aecpc->counter * 10)), BUF_SIZE_FRAMES);\n                // buffersize has now been determined\n                aecpc->checkBuffSize = 0;\n            }\n\n            if (aecpc->checkBufSizeCtr * nBlocks10ms > 50) {\n                // for really bad sound cards, don't disable echocanceller for more than 0.5 sec\n                aecpc->bufSizeStart = WEBRTC_SPL_MIN((int) (0.75 * (aecpc->msInSndCardBuf *\n                    aecpc->aec->mult) / 10), BUF_SIZE_FRAMES);\n                aecpc->checkBuffSize = 0;\n            }\n        }\n\n        // if checkBuffSize changed in the if-statement above\n        if (!aecpc->checkBuffSize) {\n            // soundcard buffer is now reasonably stable\n            // When the far end buffer is filled with approximately the same amount of\n            // data as the amount on the sound card we end the start up phase and start\n            // to cancel echoes.\n\n            if (nmbrOfFilledBuffers == aecpc->bufSizeStart) {\n                aecpc->ECstartup = 0;  // Enable the AEC\n            }\n            else if (nmbrOfFilledBuffers > aecpc->bufSizeStart) {\n                WebRtcApm_FlushBuffer(aecpc->farendBuf, WebRtcApm_get_buffer_size(aecpc->farendBuf) -\n                    aecpc->bufSizeStart * FRAME_LEN);\n                aecpc->ECstartup = 0;\n            }\n        }\n\n    }\n    else {\n        // AEC is enabled\n\n        // Note only 1 block supported for nb and 2 blocks for wb\n        for (i = 0; i < nFrames; i++) {\n            nmbrOfFilledBuffers = WebRtcApm_get_buffer_size(aecpc->farendBuf) / FRAME_LEN;\n\n            // Check that there is data in the far end buffer\n            if (nmbrOfFilledBuffers > 0) {\n                // Get the next 80 samples from the farend buffer\n                WebRtcApm_ReadBuffer(aecpc->farendBuf, farend, FRAME_LEN);\n\n                // Always store the last frame for use when we run out of data\n                memcpy(&(aecpc->farendOld[i][0]), farend, FRAME_LEN * sizeof(short));\n            }\n            else {\n                // We have no data so we use the last played frame\n                memcpy(farend, &(aecpc->farendOld[i][0]), FRAME_LEN * sizeof(short));\n            }\n\n            // Call buffer delay estimator when all data is extracted,\n            // i.e. i = 0 for NB and i = 1 for WB or SWB\n            if ((i == 0 && aecpc->splitSampFreq == 8000) ||\n                    (i == 1 && (aecpc->splitSampFreq == 16000))) {\n                EstBufDelay(aecpc, aecpc->msInSndCardBuf);\n            }\n\n            // Call the AEC\n           WebRtcAec_ProcessFrame(aecpc->aec, farend, &nearend[FRAME_LEN * i], &nearendH[FRAME_LEN * i],\n               &out[FRAME_LEN * i], &outH[FRAME_LEN * i], aecpc->knownDelay);\n        }\n    }\n\n#ifdef AEC_DEBUG\n    msInAECBuf = WebRtcApm_get_buffer_size(aecpc->farendBuf) / (sampMsNb*aecpc->aec->mult);\n    fwrite(&msInAECBuf, 2, 1, aecpc->bufFile);\n    fwrite(&(aecpc->knownDelay), sizeof(aecpc->knownDelay), 1, aecpc->delayFile);\n#endif\n\n    return retVal;\n}\n\nWebRtc_Word32 WebRtcAec_set_config(void *aecInst, AecConfig config)\n{\n    aecpc_t *aecpc = aecInst;\n\n    if (aecpc == NULL) {\n        return -1;\n    }\n\n    if (aecpc->initFlag != initCheck) {\n        aecpc->lastError = AEC_UNINITIALIZED_ERROR;\n        return -1;\n    }\n\n    if (config.skewMode != kAecFalse && config.skewMode != kAecTrue) {\n        aecpc->lastError = AEC_BAD_PARAMETER_ERROR;\n        return -1;\n    }\n    aecpc->skewMode = config.skewMode;\n\n    if (config.nlpMode != kAecNlpConservative && config.nlpMode !=\n            kAecNlpModerate && config.nlpMode != kAecNlpAggressive) {\n        aecpc->lastError = AEC_BAD_PARAMETER_ERROR;\n        return -1;\n    }\n    aecpc->nlpMode = config.nlpMode;\n    aecpc->aec->targetSupp = targetSupp[aecpc->nlpMode];\n    aecpc->aec->minOverDrive = minOverDrive[aecpc->nlpMode];\n\n    if (config.metricsMode != kAecFalse && config.metricsMode != kAecTrue) {\n        aecpc->lastError = AEC_BAD_PARAMETER_ERROR;\n        return -1;\n    }\n    aecpc->aec->metricsMode = config.metricsMode;\n    if (aecpc->aec->metricsMode == kAecTrue) {\n        WebRtcAec_InitMetrics(aecpc->aec);\n    }\n\n    return 0;\n}\n\nWebRtc_Word32 WebRtcAec_get_config(void *aecInst, AecConfig *config)\n{\n    aecpc_t *aecpc = aecInst;\n\n    if (aecpc == NULL) {\n        return -1;\n    }\n\n    if (config == NULL) {\n        aecpc->lastError = AEC_NULL_POINTER_ERROR;\n        return -1;\n    }\n\n    if (aecpc->initFlag != initCheck) {\n        aecpc->lastError = AEC_UNINITIALIZED_ERROR;\n        return -1;\n    }\n\n    config->nlpMode = aecpc->nlpMode;\n    config->skewMode = aecpc->skewMode;\n    config->metricsMode = aecpc->aec->metricsMode;\n\n    return 0;\n}\n\nWebRtc_Word32 WebRtcAec_get_echo_status(void *aecInst, WebRtc_Word16 *status)\n{\n    aecpc_t *aecpc = aecInst;\n\n    if (aecpc == NULL) {\n        return -1;\n    }\n\n    if (status == NULL) {\n        aecpc->lastError = AEC_NULL_POINTER_ERROR;\n        return -1;\n    }\n\n    if (aecpc->initFlag != initCheck) {\n        aecpc->lastError = AEC_UNINITIALIZED_ERROR;\n        return -1;\n    }\n\n    *status = aecpc->aec->echoState;\n\n    return 0;\n}\n\nWebRtc_Word32 WebRtcAec_GetMetrics(void *aecInst, AecMetrics *metrics)\n{\n    const float upweight = 0.7f;\n    float dtmp;\n    short stmp;\n    aecpc_t *aecpc = aecInst;\n\n    if (aecpc == NULL) {\n        return -1;\n    }\n\n    if (metrics == NULL) {\n        aecpc->lastError = AEC_NULL_POINTER_ERROR;\n        return -1;\n    }\n\n    if (aecpc->initFlag != initCheck) {\n        aecpc->lastError = AEC_UNINITIALIZED_ERROR;\n        return -1;\n    }\n\n    // ERL\n    metrics->erl.instant = (short) aecpc->aec->erl.instant;\n\n    if ((aecpc->aec->erl.himean > offsetLevel) && (aecpc->aec->erl.average > offsetLevel)) {\n    // Use a mix between regular average and upper part average\n        dtmp = upweight * aecpc->aec->erl.himean + (1 - upweight) * aecpc->aec->erl.average;\n        metrics->erl.average = (short) dtmp;\n    }\n    else {\n        metrics->erl.average = offsetLevel;\n    }\n\n    metrics->erl.max = (short) aecpc->aec->erl.max;\n\n    if (aecpc->aec->erl.min < (offsetLevel * (-1))) {\n        metrics->erl.min = (short) aecpc->aec->erl.min;\n    }\n    else {\n        metrics->erl.min = offsetLevel;\n    }\n\n    // ERLE\n    metrics->erle.instant = (short) aecpc->aec->erle.instant;\n\n    if ((aecpc->aec->erle.himean > offsetLevel) && (aecpc->aec->erle.average > offsetLevel)) {\n        // Use a mix between regular average and upper part average\n        dtmp =  upweight * aecpc->aec->erle.himean + (1 - upweight) * aecpc->aec->erle.average;\n        metrics->erle.average = (short) dtmp;\n    }\n    else {\n        metrics->erle.average = offsetLevel;\n    }\n\n    metrics->erle.max = (short) aecpc->aec->erle.max;\n\n    if (aecpc->aec->erle.min < (offsetLevel * (-1))) {\n        metrics->erle.min = (short) aecpc->aec->erle.min;\n    } else {\n        metrics->erle.min = offsetLevel;\n    }\n\n    // RERL\n    if ((metrics->erl.average > offsetLevel) && (metrics->erle.average > offsetLevel)) {\n        stmp = metrics->erl.average + metrics->erle.average;\n    }\n    else {\n        stmp = offsetLevel;\n    }\n    metrics->rerl.average = stmp;\n\n    // No other statistics needed, but returned for completeness\n    metrics->rerl.instant = stmp;\n    metrics->rerl.max = stmp;\n    metrics->rerl.min = stmp;\n\n    // A_NLP\n    metrics->aNlp.instant = (short) aecpc->aec->aNlp.instant;\n\n    if ((aecpc->aec->aNlp.himean > offsetLevel) && (aecpc->aec->aNlp.average > offsetLevel)) {\n        // Use a mix between regular average and upper part average\n        dtmp =  upweight * aecpc->aec->aNlp.himean + (1 - upweight) * aecpc->aec->aNlp.average;\n        metrics->aNlp.average = (short) dtmp;\n    }\n    else {\n        metrics->aNlp.average = offsetLevel;\n    }\n\n    metrics->aNlp.max = (short) aecpc->aec->aNlp.max;\n\n    if (aecpc->aec->aNlp.min < (offsetLevel * (-1))) {\n        metrics->aNlp.min = (short) aecpc->aec->aNlp.min;\n    }\n    else {\n        metrics->aNlp.min = offsetLevel;\n    }\n\n    return 0;\n}\n\nWebRtc_Word32 WebRtcAec_get_version(WebRtc_Word8 *versionStr, WebRtc_Word16 len)\n{\n    const char version[] = \"AEC 2.5.0\";\n    const short versionLen = (short)strlen(version) + 1; // +1 for null-termination\n\n    if (versionStr == NULL) {\n        return -1;\n    }\n\n    if (versionLen > len) {\n        return -1;\n    }\n\n    strncpy(versionStr, version, versionLen);\n    return 0;\n}\n\nWebRtc_Word32 WebRtcAec_get_error_code(void *aecInst)\n{\n    aecpc_t *aecpc = aecInst;\n\n    if (aecpc == NULL) {\n        return -1;\n    }\n\n    return aecpc->lastError;\n}\n\nstatic int EstBufDelay(aecpc_t *aecpc, short msInSndCardBuf)\n{\n    short delayNew, nSampFar, nSampSndCard;\n    short diff;\n\n    nSampFar = WebRtcApm_get_buffer_size(aecpc->farendBuf);\n    nSampSndCard = msInSndCardBuf * sampMsNb * aecpc->aec->mult;\n\n    delayNew = nSampSndCard - nSampFar;\n\n    // Account for resampling frame delay\n    if (aecpc->skewMode == kAecTrue && aecpc->resample == kAecTrue) {\n        delayNew -= kResamplingDelay;\n    }\n\n    if (delayNew < FRAME_LEN) {\n        WebRtcApm_FlushBuffer(aecpc->farendBuf, FRAME_LEN);\n        delayNew += FRAME_LEN;\n    }\n\n    aecpc->filtDelay = WEBRTC_SPL_MAX(0, (short)(0.8*aecpc->filtDelay + 0.2*delayNew));\n\n    diff = aecpc->filtDelay - aecpc->knownDelay;\n    if (diff > 224) {\n        if (aecpc->lastDelayDiff < 96) {\n            aecpc->timeForDelayChange = 0;\n        }\n        else {\n            aecpc->timeForDelayChange++;\n        }\n    }\n    else if (diff < 96 && aecpc->knownDelay > 0) {\n        if (aecpc->lastDelayDiff > 224) {\n            aecpc->timeForDelayChange = 0;\n        }\n        else {\n            aecpc->timeForDelayChange++;\n        }\n    }\n    else {\n        aecpc->timeForDelayChange = 0;\n    }\n    aecpc->lastDelayDiff = diff;\n\n    if (aecpc->timeForDelayChange > 25) {\n        aecpc->knownDelay = WEBRTC_SPL_MAX((int)aecpc->filtDelay - 160, 0);\n    }\n    return 0;\n}\n\nstatic int DelayComp(aecpc_t *aecpc)\n{\n    int nSampFar, nSampSndCard, delayNew, nSampAdd;\n    const int maxStuffSamp = 10 * FRAME_LEN;\n\n    nSampFar = WebRtcApm_get_buffer_size(aecpc->farendBuf);\n    nSampSndCard = aecpc->msInSndCardBuf * sampMsNb * aecpc->aec->mult;\n    delayNew = nSampSndCard - nSampFar;\n\n    // Account for resampling frame delay\n    if (aecpc->skewMode == kAecTrue && aecpc->resample == kAecTrue) {\n        delayNew -= kResamplingDelay;\n    }\n\n    if (delayNew > FAR_BUF_LEN - FRAME_LEN*aecpc->aec->mult) {\n        // The difference of the buffersizes is larger than the maximum\n        // allowed known delay. Compensate by stuffing the buffer.\n        nSampAdd = (int)(WEBRTC_SPL_MAX((int)(0.5 * nSampSndCard - nSampFar),\n                    FRAME_LEN));\n        nSampAdd = WEBRTC_SPL_MIN(nSampAdd, maxStuffSamp);\n\n        WebRtcApm_StuffBuffer(aecpc->farendBuf, nSampAdd);\n        aecpc->delayChange = 1; // the delay needs to be updated\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/aec/main/source/resampler.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/* Resamples a signal to an arbitrary rate. Used by the AEC to compensate for clock\n * skew by resampling the farend signal.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <string.h>\n#include <math.h>\n\n#include \"resampler.h\"\n#include \"aec_core.h\"\n\nenum { kFrameBufferSize = FRAME_LEN * 4 };\nenum { kEstimateLengthFrames = 400 };\n\ntypedef struct {\n    short buffer[kFrameBufferSize];\n    float position;\n\n    int deviceSampleRateHz;\n    int skewData[kEstimateLengthFrames];\n    int skewDataIndex;\n    float skewEstimate;\n} resampler_t;\n\nstatic int EstimateSkew(const int* rawSkew,\n                        int size,\n                        int absLimit,\n                        float *skewEst);\n\nint WebRtcAec_CreateResampler(void **resampInst)\n{\n    resampler_t *obj = malloc(sizeof(resampler_t));\n    *resampInst = obj;\n    if (obj == NULL) {\n        return -1;\n    }\n\n    return 0;\n}\n\nint WebRtcAec_InitResampler(void *resampInst, int deviceSampleRateHz)\n{\n    resampler_t *obj = (resampler_t*) resampInst;\n    memset(obj->buffer, 0, sizeof(obj->buffer));\n    obj->position = 0.0;\n\n    obj->deviceSampleRateHz = deviceSampleRateHz;\n    memset(obj->skewData, 0, sizeof(obj->skewData));\n    obj->skewDataIndex = 0;\n    obj->skewEstimate = 0.0;\n\n    return 0;\n}\n\nint WebRtcAec_FreeResampler(void *resampInst)\n{\n    resampler_t *obj = (resampler_t*) resampInst;\n    free(obj);\n\n    return 0;\n}\n\nint WebRtcAec_ResampleLinear(void *resampInst,\n                             const short *inspeech,\n                             int size,\n                             float skew,\n                             short *outspeech)\n{\n    resampler_t *obj = (resampler_t*) resampInst;\n\n    short *y;\n    float be, tnew, interp;\n    int tn, outsize, mm;\n\n    if (size < 0 || size > 2 * FRAME_LEN) {\n        return -1;\n    }\n\n    // Add new frame data in lookahead\n    memcpy(&obj->buffer[FRAME_LEN + kResamplingDelay],\n           inspeech,\n           size * sizeof(short));\n\n    // Sample rate ratio\n    be = 1 + skew;\n\n    // Loop over input frame\n    mm = 0;\n    y = &obj->buffer[FRAME_LEN]; // Point at current frame\n\n    tnew = be * mm + obj->position;\n    tn = (int) tnew;\n\n    while (tn < size) {\n\n        // Interpolation\n        interp = y[tn] + (tnew - tn) * (y[tn+1] - y[tn]);\n\n        if (interp > 32767) {\n            interp = 32767;\n        }\n        else if (interp < -32768) {\n            interp = -32768;\n        }\n\n        outspeech[mm] = (short) interp;\n        mm++;\n\n        tnew = be * mm + obj->position;\n        tn = (int) tnew;\n    }\n\n    outsize = mm;\n    obj->position += outsize * be - size;\n\n    // Shift buffer\n    memmove(obj->buffer,\n            &obj->buffer[size],\n            (kFrameBufferSize - size) * sizeof(short));\n\n    return outsize;\n}\n\nint WebRtcAec_GetSkew(void *resampInst, int rawSkew, float *skewEst)\n{\n    resampler_t *obj = (resampler_t*)resampInst;\n    int err = 0;\n\n    if (obj->skewDataIndex < kEstimateLengthFrames) {\n        obj->skewData[obj->skewDataIndex] = rawSkew;\n        obj->skewDataIndex++;\n    }\n    else if (obj->skewDataIndex == kEstimateLengthFrames) {\n        err = EstimateSkew(obj->skewData,\n                           kEstimateLengthFrames,\n                           obj->deviceSampleRateHz,\n                           skewEst);\n        obj->skewEstimate = *skewEst;\n        obj->skewDataIndex++;\n    }\n    else {\n        *skewEst = obj->skewEstimate;\n    }\n\n    return err;\n}\n\nint EstimateSkew(const int* rawSkew,\n                 int size,\n                 int deviceSampleRateHz,\n                 float *skewEst)\n{\n    const int absLimitOuter = (int)(0.04f * deviceSampleRateHz);\n    const int absLimitInner = (int)(0.0025f * deviceSampleRateHz);\n    int i = 0;\n    int n = 0;\n    float rawAvg = 0;\n    float err = 0;\n    float rawAbsDev = 0;\n    int upperLimit = 0;\n    int lowerLimit = 0;\n    float cumSum = 0;\n    float x = 0;\n    float x2 = 0;\n    float y = 0;\n    float xy = 0;\n    float xAvg = 0;\n    float denom = 0;\n    float skew = 0;\n\n    *skewEst = 0; // Set in case of error below.\n    for (i = 0; i < size; i++) {\n      if ((rawSkew[i] < absLimitOuter && rawSkew[i] > -absLimitOuter)) {\n        n++;\n        rawAvg += rawSkew[i];\n      }\n    }\n\n    if (n == 0) {\n      return -1;\n    }\n    assert(n > 0);\n    rawAvg /= n;\n\n    for (i = 0; i < size; i++) {\n      if ((rawSkew[i] < absLimitOuter && rawSkew[i] > -absLimitOuter)) {\n        err = rawSkew[i] - rawAvg;\n        rawAbsDev += err >= 0 ? err : -err;\n      }\n    }\n    assert(n > 0);\n    rawAbsDev /= n;\n    upperLimit = (int)(rawAvg + 5 * rawAbsDev + 1); // +1 for ceiling.\n    lowerLimit = (int)(rawAvg - 5 * rawAbsDev - 1); // -1 for floor.\n\n    n = 0;\n    for (i = 0; i < size; i++) {\n        if ((rawSkew[i] < absLimitInner && rawSkew[i] > -absLimitInner) ||\n            (rawSkew[i] < upperLimit && rawSkew[i] > lowerLimit)) {\n            n++;\n            cumSum += rawSkew[i];\n            x += n;\n            x2 += n*n;\n            y += cumSum;\n            xy += n * cumSum;\n        }\n    }\n\n    if (n == 0) {\n      return -1;\n    }\n    assert(n > 0);\n    xAvg = x / n;\n    denom = x2 - xAvg*x;\n\n    if (denom != 0) {\n        skew = (xy - xAvg*y) / denom;\n    }\n\n    *skewEst = skew;\n    return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/aec/main/source/resampler.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_RESAMPLER_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_RESAMPLER_H_\n\nenum { kResamplingDelay = 1 };\n\n// Unless otherwise specified, functions return 0 on success and -1 on error\nint WebRtcAec_CreateResampler(void **resampInst);\nint WebRtcAec_InitResampler(void *resampInst, int deviceSampleRateHz);\nint WebRtcAec_FreeResampler(void *resampInst);\n\n// Estimates skew from raw measurement.\nint WebRtcAec_GetSkew(void *resampInst, int rawSkew, float *skewEst);\n\n// Resamples input using linear interpolation.\n// Returns size of resampled array.\nint WebRtcAec_ResampleLinear(void *resampInst,\n                             const short *inspeech,\n                             int size,\n                             float skew,\n                             short *outspeech);\n\n#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_RESAMPLER_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/agc/main/interface/gain_control.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_INTERFACE_GAIN_CONTROL_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_INTERFACE_GAIN_CONTROL_H_\n\n#include \"typedefs.h\"\n\n// Errors\n#define AGC_UNSPECIFIED_ERROR           18000\n#define AGC_UNSUPPORTED_FUNCTION_ERROR  18001\n#define AGC_UNINITIALIZED_ERROR         18002\n#define AGC_NULL_POINTER_ERROR          18003\n#define AGC_BAD_PARAMETER_ERROR         18004\n\n// Warnings\n#define AGC_BAD_PARAMETER_WARNING       18050\n\nenum\n{\n    kAgcModeUnchanged,\n    kAgcModeAdaptiveAnalog,\n    kAgcModeAdaptiveDigital,\n    kAgcModeFixedDigital\n};\n\nenum\n{\n    kAgcFalse = 0,\n    kAgcTrue\n};\n\ntypedef struct\n{\n    WebRtc_Word16 targetLevelDbfs;   // default 3 (-3 dBOv)\n    WebRtc_Word16 compressionGaindB; // default 9 dB\n    WebRtc_UWord8 limiterEnable;     // default kAgcTrue (on)\n} WebRtcAgc_config_t;\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\n/*\n * This function processes a 10/20ms frame of far-end speech to determine\n * if there is active speech. Far-end speech length can be either 10ms or\n * 20ms. The length of the input speech vector must be given in samples\n * (80/160 when FS=8000, and 160/320 when FS=16000 or FS=32000).\n *\n * Input:\n *      - agcInst           : AGC instance.\n *      - inFar             : Far-end input speech vector (10 or 20ms)\n *      - samples           : Number of samples in input vector\n *\n * Return value:\n *                          :  0 - Normal operation.\n *                          : -1 - Error\n */\nint WebRtcAgc_AddFarend(void* agcInst,\n                        const WebRtc_Word16* inFar,\n                        WebRtc_Word16 samples);\n\n/*\n * This function processes a 10/20ms frame of microphone speech to determine\n * if there is active speech. Microphone speech length can be either 10ms or\n * 20ms. The length of the input speech vector must be given in samples\n * (80/160 when FS=8000, and 160/320 when FS=16000 or FS=32000). For very low\n * input levels, the input signal is increased in level by multiplying and\n * overwriting the samples in inMic[].\n *\n * This function should be called before any further processing of the\n * near-end microphone signal.\n *\n * Input:\n *      - agcInst           : AGC instance.\n *      - inMic             : Microphone input speech vector (10 or 20 ms) for\n *                            L band\n *      - inMic_H           : Microphone input speech vector (10 or 20 ms) for\n *                            H band\n *      - samples           : Number of samples in input vector\n *\n * Return value:\n *                          :  0 - Normal operation.\n *                          : -1 - Error\n */\nint WebRtcAgc_AddMic(void* agcInst,\n                     WebRtc_Word16* inMic,\n                     WebRtc_Word16* inMic_H,\n                     WebRtc_Word16 samples);\n\n/*\n * This function replaces the analog microphone with a virtual one.\n * It is a digital gain applied to the input signal and is used in the\n * agcAdaptiveDigital mode where no microphone level is adjustable.\n * Microphone speech length can be either 10ms or 20ms. The length of the\n * input speech vector must be given in samples (80/160 when FS=8000, and\n * 160/320 when FS=16000 or FS=32000).\n *\n * Input:\n *      - agcInst           : AGC instance.\n *      - inMic             : Microphone input speech vector for (10 or 20 ms)\n *                            L band\n *      - inMic_H           : Microphone input speech vector for (10 or 20 ms)\n *                            H band\n *      - samples           : Number of samples in input vector\n *      - micLevelIn        : Input level of microphone (static)\n *\n * Output:\n *      - inMic             : Microphone output after processing (L band)\n *      - inMic_H           : Microphone output after processing (H band)\n *      - micLevelOut       : Adjusted microphone level after processing\n *\n * Return value:\n *                          :  0 - Normal operation.\n *                          : -1 - Error\n */\nint WebRtcAgc_VirtualMic(void* agcInst,\n                         WebRtc_Word16* inMic,\n                         WebRtc_Word16* inMic_H,\n                         WebRtc_Word16 samples,\n                         WebRtc_Word32 micLevelIn,\n                         WebRtc_Word32* micLevelOut);\n\n/*\n * This function processes a 10/20ms frame and adjusts (normalizes) the gain\n * both analog and digitally. The gain adjustments are done only during\n * active periods of speech. The input speech length can be either 10ms or\n * 20ms and the output is of the same length. The length of the speech\n * vectors must be given in samples (80/160 when FS=8000, and 160/320 when\n * FS=16000 or FS=32000). The echo parameter can be used to ensure the AGC will\n * not adjust upward in the presence of echo.\n *\n * This function should be called after processing the near-end microphone\n * signal, in any case after any echo cancellation.\n *\n * Input:\n *      - agcInst           : AGC instance\n *      - inNear            : Near-end input speech vector (10 or 20 ms) for\n *                            L band\n *      - inNear_H          : Near-end input speech vector (10 or 20 ms) for\n *                            H band\n *      - samples           : Number of samples in input/output vector\n *      - inMicLevel        : Current microphone volume level\n *      - echo              : Set to 0 if the signal passed to add_mic is\n *                            almost certainly free of echo; otherwise set\n *                            to 1. If you have no information regarding echo\n *                            set to 0.\n *\n * Output:\n *      - outMicLevel       : Adjusted microphone volume level\n *      - out               : Gain-adjusted near-end speech vector (L band)\n *                          : May be the same vector as the input.\n *      - out_H             : Gain-adjusted near-end speech vector (H band)\n *      - saturationWarning : A returned value of 1 indicates a saturation event\n *                            has occurred and the volume cannot be further\n *                            reduced. Otherwise will be set to 0.\n *\n * Return value:\n *                          :  0 - Normal operation.\n *                          : -1 - Error\n */\nint WebRtcAgc_Process(void* agcInst,\n                      const WebRtc_Word16* inNear,\n                      const WebRtc_Word16* inNear_H,\n                      WebRtc_Word16 samples,\n                      WebRtc_Word16* out,\n                      WebRtc_Word16* out_H,\n                      WebRtc_Word32 inMicLevel,\n                      WebRtc_Word32* outMicLevel,\n                      WebRtc_Word16 echo,\n                      WebRtc_UWord8* saturationWarning);\n\n/*\n * This function sets the config parameters (targetLevelDbfs,\n * compressionGaindB and limiterEnable).\n *\n * Input:\n *      - agcInst           : AGC instance\n *      - config            : config struct\n *\n * Output:\n *\n * Return value:\n *                          :  0 - Normal operation.\n *                          : -1 - Error\n */\nint WebRtcAgc_set_config(void* agcInst, WebRtcAgc_config_t config);\n\n/*\n * This function returns the config parameters (targetLevelDbfs,\n * compressionGaindB and limiterEnable).\n *\n * Input:\n *      - agcInst           : AGC instance\n *\n * Output:\n *      - config            : config struct\n *\n * Return value:\n *                          :  0 - Normal operation.\n *                          : -1 - Error\n */\nint WebRtcAgc_get_config(void* agcInst, WebRtcAgc_config_t* config);\n\n/*\n * This function creates an AGC instance, which will contain the state\n * information for one (duplex) channel.\n *\n * Return value             : AGC instance if successful\n *                          : 0 (i.e., a NULL pointer) if unsuccessful\n */\nint WebRtcAgc_Create(void **agcInst);\n\n/*\n * This function frees the AGC instance created at the beginning.\n *\n * Input:\n *      - agcInst           : AGC instance.\n *\n * Return value             :  0 - Ok\n *                            -1 - Error\n */\nint WebRtcAgc_Free(void *agcInst);\n\n/*\n * This function initializes an AGC instance.\n *\n * Input:\n *      - agcInst           : AGC instance.\n *      - minLevel          : Minimum possible mic level\n *      - maxLevel          : Maximum possible mic level\n *      - agcMode           : 0 - Unchanged\n *                          : 1 - Adaptive Analog Automatic Gain Control -3dBOv\n *                          : 2 - Adaptive Digital Automatic Gain Control -3dBOv\n *                          : 3 - Fixed Digital Gain 0dB\n *      - fs                : Sampling frequency\n *\n * Return value             :  0 - Ok\n *                            -1 - Error\n */\nint WebRtcAgc_Init(void *agcInst,\n                   WebRtc_Word32 minLevel,\n                   WebRtc_Word32 maxLevel,\n                   WebRtc_Word16 agcMode,\n                   WebRtc_UWord32 fs);\n\n/*\n * This function returns a text string containing the version.\n *\n * Input:\n *      - length            : Length of the char array pointed to by version\n * Output:\n *      - version           : Pointer to a char array of to which the version\n *                          : string will be copied.\n *\n * Return value             :  0 - OK\n *                            -1 - Error\n */\nint WebRtcAgc_Version(WebRtc_Word8 *versionStr, WebRtc_Word16 length);\n\n#if defined(__cplusplus)\n}\n#endif\n\n#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_INTERFACE_GAIN_CONTROL_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/agc/main/source/analog_agc.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/* analog_agc.c\n *\n * Using a feedback system, determines an appropriate analog volume level\n * given an input signal and current volume level. Targets a conservative\n * signal level and is intended for use with a digital AGC to apply\n * additional gain.\n *\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#ifdef AGC_DEBUG //test log\n#include <stdio.h>\n#endif\n#include \"analog_agc.h\"\n\n/* The slope of in Q13*/\nstatic const WebRtc_Word16 kSlope1[8] = {21793, 12517, 7189, 4129, 2372, 1362, 472, 78};\n\n/* The offset in Q14 */\nstatic const WebRtc_Word16 kOffset1[8] = {25395, 23911, 22206, 20737, 19612, 18805, 17951,\n        17367};\n\n/* The slope of in Q13*/\nstatic const WebRtc_Word16 kSlope2[8] = {2063, 1731, 1452, 1218, 1021, 857, 597, 337};\n\n/* The offset in Q14 */\nstatic const WebRtc_Word16 kOffset2[8] = {18432, 18379, 18290, 18177, 18052, 17920, 17670,\n        17286};\n\nstatic const WebRtc_Word16 kMuteGuardTimeMs = 8000;\nstatic const WebRtc_Word16 kInitCheck = 42;\n\n/* Default settings if config is not used */\n#define AGC_DEFAULT_TARGET_LEVEL 3\n#define AGC_DEFAULT_COMP_GAIN 9\n/* This is the target level for the analog part in ENV scale. To convert to RMS scale you\n * have to add OFFSET_ENV_TO_RMS.\n */\n#define ANALOG_TARGET_LEVEL 11\n#define ANALOG_TARGET_LEVEL_2 5 // ANALOG_TARGET_LEVEL / 2\n/* Offset between RMS scale (analog part) and ENV scale (digital part). This value actually\n * varies with the FIXED_ANALOG_TARGET_LEVEL, hence we should in the future replace it with\n * a table.\n */\n#define OFFSET_ENV_TO_RMS 9\n/* The reference input level at which the digital part gives an output of targetLevelDbfs\n * (desired level) if we have no compression gain. This level should be set high enough not\n * to compress the peaks due to the dynamics.\n */\n#define DIGITAL_REF_AT_0_COMP_GAIN 4\n/* Speed of reference level decrease.\n */\n#define DIFF_REF_TO_ANALOG 5\n\n#ifdef MIC_LEVEL_FEEDBACK\n#define NUM_BLOCKS_IN_SAT_BEFORE_CHANGE_TARGET 7\n#endif\n/* Size of analog gain table */\n#define GAIN_TBL_LEN 32\n/* Matlab code:\n * fprintf(1, '\\t%i, %i, %i, %i,\\n', round(10.^(linspace(0,10,32)/20) * 2^12));\n */\n/* Q12 */\nstatic const WebRtc_UWord16 kGainTableAnalog[GAIN_TBL_LEN] = {4096, 4251, 4412, 4579, 4752,\n        4932, 5118, 5312, 5513, 5722, 5938, 6163, 6396, 6638, 6889, 7150, 7420, 7701, 7992,\n        8295, 8609, 8934, 9273, 9623, 9987, 10365, 10758, 11165, 11587, 12025, 12480, 12953};\n\n/* Gain/Suppression tables for virtual Mic (in Q10) */\nstatic const WebRtc_UWord16 kGainTableVirtualMic[128] = {1052, 1081, 1110, 1141, 1172, 1204,\n        1237, 1271, 1305, 1341, 1378, 1416, 1454, 1494, 1535, 1577, 1620, 1664, 1710, 1757,\n        1805, 1854, 1905, 1957, 2010, 2065, 2122, 2180, 2239, 2301, 2364, 2428, 2495, 2563,\n        2633, 2705, 2779, 2855, 2933, 3013, 3096, 3180, 3267, 3357, 3449, 3543, 3640, 3739,\n        3842, 3947, 4055, 4166, 4280, 4397, 4517, 4640, 4767, 4898, 5032, 5169, 5311, 5456,\n        5605, 5758, 5916, 6078, 6244, 6415, 6590, 6770, 6956, 7146, 7341, 7542, 7748, 7960,\n        8178, 8402, 8631, 8867, 9110, 9359, 9615, 9878, 10148, 10426, 10711, 11004, 11305,\n        11614, 11932, 12258, 12593, 12938, 13292, 13655, 14029, 14412, 14807, 15212, 15628,\n        16055, 16494, 16945, 17409, 17885, 18374, 18877, 19393, 19923, 20468, 21028, 21603,\n        22194, 22801, 23425, 24065, 24724, 25400, 26095, 26808, 27541, 28295, 29069, 29864,\n        30681, 31520, 32382};\nstatic const WebRtc_UWord16 kSuppressionTableVirtualMic[128] = {1024, 1006, 988, 970, 952,\n        935, 918, 902, 886, 870, 854, 839, 824, 809, 794, 780, 766, 752, 739, 726, 713, 700,\n        687, 675, 663, 651, 639, 628, 616, 605, 594, 584, 573, 563, 553, 543, 533, 524, 514,\n        505, 496, 487, 478, 470, 461, 453, 445, 437, 429, 421, 414, 406, 399, 392, 385, 378,\n        371, 364, 358, 351, 345, 339, 333, 327, 321, 315, 309, 304, 298, 293, 288, 283, 278,\n        273, 268, 263, 258, 254, 249, 244, 240, 236, 232, 227, 223, 219, 215, 211, 208, 204,\n        200, 197, 193, 190, 186, 183, 180, 176, 173, 170, 167, 164, 161, 158, 155, 153, 150,\n        147, 145, 142, 139, 137, 134, 132, 130, 127, 125, 123, 121, 118, 116, 114, 112, 110,\n        108, 106, 104, 102};\n\n/* Table for target energy levels. Values in Q(-7)\n * Matlab code\n * targetLevelTable = fprintf('%d,\\t%d,\\t%d,\\t%d,\\n', round((32767*10.^(-(0:63)'/20)).^2*16/2^7) */\n\nstatic const WebRtc_Word32 kTargetLevelTable[64] = {134209536, 106606424, 84680493, 67264106,\n        53429779, 42440782, 33711911, 26778323, 21270778, 16895980, 13420954, 10660642,\n        8468049, 6726411, 5342978, 4244078, 3371191, 2677832, 2127078, 1689598, 1342095,\n        1066064, 846805, 672641, 534298, 424408, 337119, 267783, 212708, 168960, 134210,\n        106606, 84680, 67264, 53430, 42441, 33712, 26778, 21271, 16896, 13421, 10661, 8468,\n        6726, 5343, 4244, 3371, 2678, 2127, 1690, 1342, 1066, 847, 673, 534, 424, 337, 268,\n        213, 169, 134, 107, 85, 67};\n\nint WebRtcAgc_AddMic(void *state, WebRtc_Word16 *in_mic, WebRtc_Word16 *in_mic_H,\n                     WebRtc_Word16 samples)\n{\n    WebRtc_Word32 nrg, max_nrg, sample, tmp32;\n    WebRtc_Word32 *ptr;\n    WebRtc_UWord16 targetGainIdx, gain;\n    WebRtc_Word16 i, n, L, M, subFrames, tmp16, tmp_speech[16];\n    Agc_t *stt;\n    stt = (Agc_t *)state;\n\n    //default/initial values corresponding to 10ms for wb and swb\n    M = 10;\n    L = 16;\n    subFrames = 160;\n\n    if (stt->fs == 8000)\n    {\n        if (samples == 80)\n        {\n            subFrames = 80;\n            M = 10;\n            L = 8;\n        } else if (samples == 160)\n        {\n            subFrames = 80;\n            M = 20;\n            L = 8;\n        } else\n        {\n#ifdef AGC_DEBUG //test log\n            fprintf(stt->fpt,\n                    \"AGC->add_mic, frame %d: Invalid number of samples\\n\\n\",\n                    (stt->fcount + 1));\n#endif\n            return -1;\n        }\n    } else if (stt->fs == 16000)\n    {\n        if (samples == 160)\n        {\n            subFrames = 160;\n            M = 10;\n            L = 16;\n        } else if (samples == 320)\n        {\n            subFrames = 160;\n            M = 20;\n            L = 16;\n        } else\n        {\n#ifdef AGC_DEBUG //test log\n            fprintf(stt->fpt,\n                    \"AGC->add_mic, frame %d: Invalid number of samples\\n\\n\",\n                    (stt->fcount + 1));\n#endif\n            return -1;\n        }\n    } else if (stt->fs == 32000)\n    {\n        /* SWB is processed as 160 sample for L and H bands */\n        if (samples == 160)\n        {\n            subFrames = 160;\n            M = 10;\n            L = 16;\n        } else\n        {\n#ifdef AGC_DEBUG\n            fprintf(stt->fpt,\n                    \"AGC->add_mic, frame %d: Invalid sample rate\\n\\n\",\n                    (stt->fcount + 1));\n#endif\n            return -1;\n        }\n    }\n\n    /* Check for valid pointers based on sampling rate */\n    if ((stt->fs == 32000) && (in_mic_H == NULL))\n    {\n        return -1;\n    }\n    /* Check for valid pointer for low band */\n    if (in_mic == NULL)\n    {\n        return -1;\n    }\n\n    /* apply slowly varying digital gain */\n    if (stt->micVol > stt->maxAnalog)\n    {\n        /* Q1 */\n        tmp16 = (WebRtc_Word16)(stt->micVol - stt->maxAnalog);\n        tmp32 = WEBRTC_SPL_MUL_16_16(GAIN_TBL_LEN - 1, tmp16);\n        tmp16 = (WebRtc_Word16)(stt->maxLevel - stt->maxAnalog);\n        targetGainIdx = (WebRtc_UWord16)WEBRTC_SPL_DIV(tmp32, tmp16);\n        assert(targetGainIdx < GAIN_TBL_LEN);\n\n        /* Increment through the table towards the target gain.\n         * If micVol drops below maxAnalog, we allow the gain\n         * to be dropped immediately. */\n        if (stt->gainTableIdx < targetGainIdx)\n        {\n            stt->gainTableIdx++;\n        } else if (stt->gainTableIdx > targetGainIdx)\n        {\n            stt->gainTableIdx--;\n        }\n\n        /* Q12 */\n        gain = kGainTableAnalog[stt->gainTableIdx];\n\n        for (i = 0; i < samples; i++)\n        {\n            // For lower band\n            tmp32 = WEBRTC_SPL_MUL_16_U16(in_mic[i], gain);\n            sample = WEBRTC_SPL_RSHIFT_W32(tmp32, 12);\n            if (sample > 32767)\n            {\n                in_mic[i] = 32767;\n            } else if (sample < -32768)\n            {\n                in_mic[i] = -32768;\n            } else\n            {\n                in_mic[i] = (WebRtc_Word16)sample;\n            }\n\n            // For higher band\n            if (stt->fs == 32000)\n            {\n                tmp32 = WEBRTC_SPL_MUL_16_U16(in_mic_H[i], gain);\n                sample = WEBRTC_SPL_RSHIFT_W32(tmp32, 12);\n                if (sample > 32767)\n                {\n                    in_mic_H[i] = 32767;\n                } else if (sample < -32768)\n                {\n                    in_mic_H[i] = -32768;\n                } else\n                {\n                    in_mic_H[i] = (WebRtc_Word16)sample;\n                }\n            }\n        }\n    } else\n    {\n        stt->gainTableIdx = 0;\n    }\n\n    /* compute envelope */\n    if ((M == 10) && (stt->inQueue > 0))\n    {\n        ptr = stt->env[1];\n    } else\n    {\n        ptr = stt->env[0];\n    }\n\n    for (i = 0; i < M; i++)\n    {\n        /* iterate over samples */\n        max_nrg = 0;\n        for (n = 0; n < L; n++)\n        {\n            nrg = WEBRTC_SPL_MUL_16_16(in_mic[i * L + n], in_mic[i * L + n]);\n            if (nrg > max_nrg)\n            {\n                max_nrg = nrg;\n            }\n        }\n        ptr[i] = max_nrg;\n    }\n\n    /* compute energy */\n    if ((M == 10) && (stt->inQueue > 0))\n    {\n        ptr = stt->Rxx16w32_array[1];\n    } else\n    {\n        ptr = stt->Rxx16w32_array[0];\n    }\n\n    for (i = 0; i < WEBRTC_SPL_RSHIFT_W16(M, 1); i++)\n    {\n        if (stt->fs == 16000)\n        {\n            WebRtcSpl_DownsampleBy2(&in_mic[i * 32], 32, tmp_speech, stt->filterState);\n        } else\n        {\n            memcpy(tmp_speech, &in_mic[i * 16], 16 * sizeof(short));\n        }\n        /* Compute energy in blocks of 16 samples */\n        ptr[i] = WebRtcSpl_DotProductWithScale(tmp_speech, tmp_speech, 16, 4);\n    }\n\n    /* update queue information */\n    if ((stt->inQueue == 0) && (M == 10))\n    {\n        stt->inQueue = 1;\n    } else\n    {\n        stt->inQueue = 2;\n    }\n\n    /* call VAD (use low band only) */\n    for (i = 0; i < samples; i += subFrames)\n    {\n        WebRtcAgc_ProcessVad(&stt->vadMic, &in_mic[i], subFrames);\n    }\n\n    return 0;\n}\n\nint WebRtcAgc_AddFarend(void *state, const WebRtc_Word16 *in_far, WebRtc_Word16 samples)\n{\n    WebRtc_Word32 errHandle = 0;\n    WebRtc_Word16 i, subFrames;\n    Agc_t *stt;\n    stt = (Agc_t *)state;\n\n    if (stt == NULL)\n    {\n        return -1;\n    }\n\n    if (stt->fs == 8000)\n    {\n        if ((samples != 80) && (samples != 160))\n        {\n#ifdef AGC_DEBUG //test log\n            fprintf(stt->fpt,\n                    \"AGC->add_far_end, frame %d: Invalid number of samples\\n\\n\",\n                    stt->fcount);\n#endif\n            return -1;\n        }\n        subFrames = 80;\n    } else if (stt->fs == 16000)\n    {\n        if ((samples != 160) && (samples != 320))\n        {\n#ifdef AGC_DEBUG //test log\n            fprintf(stt->fpt,\n                    \"AGC->add_far_end, frame %d: Invalid number of samples\\n\\n\",\n                    stt->fcount);\n#endif\n            return -1;\n        }\n        subFrames = 160;\n    } else if (stt->fs == 32000)\n    {\n        if ((samples != 160) && (samples != 320))\n        {\n#ifdef AGC_DEBUG //test log\n            fprintf(stt->fpt,\n                    \"AGC->add_far_end, frame %d: Invalid number of samples\\n\\n\",\n                    stt->fcount);\n#endif\n            return -1;\n        }\n        subFrames = 160;\n    } else\n    {\n#ifdef AGC_DEBUG //test log\n        fprintf(stt->fpt,\n                \"AGC->add_far_end, frame %d: Invalid sample rate\\n\\n\",\n                stt->fcount + 1);\n#endif\n        return -1;\n    }\n\n    for (i = 0; i < samples; i += subFrames)\n    {\n        errHandle += WebRtcAgc_AddFarendToDigital(&stt->digitalAgc, &in_far[i], subFrames);\n    }\n\n    return errHandle;\n}\n\nint WebRtcAgc_VirtualMic(void *agcInst, WebRtc_Word16 *in_near, WebRtc_Word16 *in_near_H,\n                         WebRtc_Word16 samples, WebRtc_Word32 micLevelIn,\n                         WebRtc_Word32 *micLevelOut)\n{\n    WebRtc_Word32 tmpFlt, micLevelTmp, gainIdx;\n    WebRtc_UWord16 gain;\n    WebRtc_Word16 ii;\n    Agc_t *stt;\n\n    WebRtc_UWord32 nrg;\n    WebRtc_Word16 sampleCntr;\n    WebRtc_UWord32 frameNrg = 0;\n    WebRtc_UWord32 frameNrgLimit = 5500;\n    WebRtc_Word16 numZeroCrossing = 0;\n    const WebRtc_Word16 kZeroCrossingLowLim = 15;\n    const WebRtc_Word16 kZeroCrossingHighLim = 20;\n\n    stt = (Agc_t *)agcInst;\n\n    /*\n     *  Before applying gain decide if this is a low-level signal.\n     *  The idea is that digital AGC will not adapt to low-level\n     *  signals.\n     */\n    if (stt->fs != 8000)\n    {\n        frameNrgLimit = frameNrgLimit << 1;\n    }\n\n    frameNrg = WEBRTC_SPL_MUL_16_16(in_near[0], in_near[0]);\n    for (sampleCntr = 1; sampleCntr < samples; sampleCntr++)\n    {\n\n        // increment frame energy if it is less than the limit\n        // the correct value of the energy is not important\n        if (frameNrg < frameNrgLimit)\n        {\n            nrg = WEBRTC_SPL_MUL_16_16(in_near[sampleCntr], in_near[sampleCntr]);\n            frameNrg += nrg;\n        }\n\n        // Count the zero crossings\n        numZeroCrossing += ((in_near[sampleCntr] ^ in_near[sampleCntr - 1]) < 0);\n    }\n\n    if ((frameNrg < 500) || (numZeroCrossing <= 5))\n    {\n        stt->lowLevelSignal = 1;\n    } else if (numZeroCrossing <= kZeroCrossingLowLim)\n    {\n        stt->lowLevelSignal = 0;\n    } else if (frameNrg <= frameNrgLimit)\n    {\n        stt->lowLevelSignal = 1;\n    } else if (numZeroCrossing >= kZeroCrossingHighLim)\n    {\n        stt->lowLevelSignal = 1;\n    } else\n    {\n        stt->lowLevelSignal = 0;\n    }\n\n    micLevelTmp = WEBRTC_SPL_LSHIFT_W32(micLevelIn, stt->scale);\n    /* Set desired level */\n    gainIdx = stt->micVol;\n    if (stt->micVol > stt->maxAnalog)\n    {\n        gainIdx = stt->maxAnalog;\n    }\n    if (micLevelTmp != stt->micRef)\n    {\n        /* Something has happened with the physical level, restart. */\n        stt->micRef = micLevelTmp;\n        stt->micVol = 127;\n        *micLevelOut = 127;\n        stt->micGainIdx = 127;\n        gainIdx = 127;\n    }\n    /* Pre-process the signal to emulate the microphone level. */\n    /* Take one step at a time in the gain table. */\n    if (gainIdx > 127)\n    {\n        gain = kGainTableVirtualMic[gainIdx - 128];\n    } else\n    {\n        gain = kSuppressionTableVirtualMic[127 - gainIdx];\n    }\n    for (ii = 0; ii < samples; ii++)\n    {\n        tmpFlt = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_U16(in_near[ii], gain), 10);\n        if (tmpFlt > 32767)\n        {\n            tmpFlt = 32767;\n            gainIdx--;\n            if (gainIdx >= 127)\n            {\n                gain = kGainTableVirtualMic[gainIdx - 127];\n            } else\n            {\n                gain = kSuppressionTableVirtualMic[127 - gainIdx];\n            }\n        }\n        if (tmpFlt < -32768)\n        {\n            tmpFlt = -32768;\n            gainIdx--;\n            if (gainIdx >= 127)\n            {\n                gain = kGainTableVirtualMic[gainIdx - 127];\n            } else\n            {\n                gain = kSuppressionTableVirtualMic[127 - gainIdx];\n            }\n        }\n        in_near[ii] = (WebRtc_Word16)tmpFlt;\n        if (stt->fs == 32000)\n        {\n            tmpFlt = WEBRTC_SPL_MUL_16_U16(in_near_H[ii], gain);\n            tmpFlt = WEBRTC_SPL_RSHIFT_W32(tmpFlt, 10);\n            if (tmpFlt > 32767)\n            {\n                tmpFlt = 32767;\n            }\n            if (tmpFlt < -32768)\n            {\n                tmpFlt = -32768;\n            }\n            in_near_H[ii] = (WebRtc_Word16)tmpFlt;\n        }\n    }\n    /* Set the level we (finally) used */\n    stt->micGainIdx = gainIdx;\n//    *micLevelOut = stt->micGainIdx;\n    *micLevelOut = WEBRTC_SPL_RSHIFT_W32(stt->micGainIdx, stt->scale);\n    /* Add to Mic as if it was the output from a true microphone */\n    if (WebRtcAgc_AddMic(agcInst, in_near, in_near_H, samples) != 0)\n    {\n        return -1;\n    }\n    return 0;\n}\n\nvoid WebRtcAgc_UpdateAgcThresholds(Agc_t *stt)\n{\n\n    WebRtc_Word16 tmp16;\n#ifdef MIC_LEVEL_FEEDBACK\n    int zeros;\n\n    if (stt->micLvlSat)\n    {\n        /* Lower the analog target level since we have reached its maximum */\n        zeros = WebRtcSpl_NormW32(stt->Rxx160_LPw32);\n        stt->targetIdxOffset = WEBRTC_SPL_RSHIFT_W16((3 * zeros) - stt->targetIdx - 2, 2);\n    }\n#endif\n\n    /* Set analog target level in envelope dBOv scale */\n    tmp16 = (DIFF_REF_TO_ANALOG * stt->compressionGaindB) + ANALOG_TARGET_LEVEL_2;\n    tmp16 = WebRtcSpl_DivW32W16ResW16((WebRtc_Word32)tmp16, ANALOG_TARGET_LEVEL);\n    stt->analogTarget = DIGITAL_REF_AT_0_COMP_GAIN + tmp16;\n    if (stt->analogTarget < DIGITAL_REF_AT_0_COMP_GAIN)\n    {\n        stt->analogTarget = DIGITAL_REF_AT_0_COMP_GAIN;\n    }\n    if (stt->agcMode == kAgcModeFixedDigital)\n    {\n        /* Adjust for different parameter interpretation in FixedDigital mode */\n        stt->analogTarget = stt->compressionGaindB;\n    }\n#ifdef MIC_LEVEL_FEEDBACK\n    stt->analogTarget += stt->targetIdxOffset;\n#endif\n    /* Since the offset between RMS and ENV is not constant, we should make this into a\n     * table, but for now, we'll stick with a constant, tuned for the chosen analog\n     * target level.\n     */\n    stt->targetIdx = ANALOG_TARGET_LEVEL + OFFSET_ENV_TO_RMS;\n#ifdef MIC_LEVEL_FEEDBACK\n    stt->targetIdx += stt->targetIdxOffset;\n#endif\n    /* Analog adaptation limits */\n    /* analogTargetLevel = round((32767*10^(-targetIdx/20))^2*16/2^7) */\n    stt->analogTargetLevel = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx]; /* ex. -20 dBov */\n    stt->startUpperLimit = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx - 1];/* -19 dBov */\n    stt->startLowerLimit = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx + 1];/* -21 dBov */\n    stt->upperPrimaryLimit = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx - 2];/* -18 dBov */\n    stt->lowerPrimaryLimit = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx + 2];/* -22 dBov */\n    stt->upperSecondaryLimit = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx - 5];/* -15 dBov */\n    stt->lowerSecondaryLimit = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx + 5];/* -25 dBov */\n    stt->upperLimit = stt->startUpperLimit;\n    stt->lowerLimit = stt->startLowerLimit;\n}\n\nvoid WebRtcAgc_SaturationCtrl(Agc_t *stt, WebRtc_UWord8 *saturated, WebRtc_Word32 *env)\n{\n    WebRtc_Word16 i, tmpW16;\n\n    /* Check if the signal is saturated */\n    for (i = 0; i < 10; i++)\n    {\n        tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(env[i], 20);\n        if (tmpW16 > 875)\n        {\n            stt->envSum += tmpW16;\n        }\n    }\n\n    if (stt->envSum > 25000)\n    {\n        *saturated = 1;\n        stt->envSum = 0;\n    }\n\n    /* stt->envSum *= 0.99; */\n    stt->envSum = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(stt->envSum,\n            (WebRtc_Word16)32440, 15);\n}\n\nvoid WebRtcAgc_ZeroCtrl(Agc_t *stt, WebRtc_Word32 *inMicLevel, WebRtc_Word32 *env)\n{\n    WebRtc_Word16 i;\n    WebRtc_Word32 tmp32 = 0;\n    WebRtc_Word32 midVal;\n\n    /* Is the input signal zero? */\n    for (i = 0; i < 10; i++)\n    {\n        tmp32 += env[i];\n    }\n\n    /* Each block is allowed to have a few non-zero\n     * samples.\n     */\n    if (tmp32 < 500)\n    {\n        stt->msZero += 10;\n    } else\n    {\n        stt->msZero = 0;\n    }\n\n    if (stt->muteGuardMs > 0)\n    {\n        stt->muteGuardMs -= 10;\n    }\n\n    if (stt->msZero > 500)\n    {\n        stt->msZero = 0;\n\n        /* Increase microphone level only if it's less than 50% */\n        midVal = WEBRTC_SPL_RSHIFT_W32(stt->maxAnalog + stt->minLevel + 1, 1);\n        if (*inMicLevel < midVal)\n        {\n            /* *inMicLevel *= 1.1; */\n            tmp32 = WEBRTC_SPL_MUL(1126, *inMicLevel);\n            *inMicLevel = WEBRTC_SPL_RSHIFT_W32(tmp32, 10);\n            /* Reduces risk of a muted mic repeatedly triggering excessive levels due\n             * to zero signal detection. */\n            *inMicLevel = WEBRTC_SPL_MIN(*inMicLevel, stt->zeroCtrlMax);\n            stt->micVol = *inMicLevel;\n        }\n\n#ifdef AGC_DEBUG //test log\n        fprintf(stt->fpt,\n                \"\\t\\tAGC->zeroCntrl, frame %d: 500 ms under threshold, micVol:\\n\",\n                stt->fcount, stt->micVol);\n#endif\n\n        stt->activeSpeech = 0;\n        stt->Rxx16_LPw32Max = 0;\n\n        /* The AGC has a tendency (due to problems with the VAD parameters), to\n         * vastly increase the volume after a muting event. This timer prevents\n         * upwards adaptation for a short period. */\n        stt->muteGuardMs = kMuteGuardTimeMs;\n    }\n}\n\nvoid WebRtcAgc_SpeakerInactiveCtrl(Agc_t *stt)\n{\n    /* Check if the near end speaker is inactive.\n     * If that is the case the VAD threshold is\n     * increased since the VAD speech model gets\n     * more sensitive to any sound after a long\n     * silence.\n     */\n\n    WebRtc_Word32 tmp32;\n    WebRtc_Word16 vadThresh;\n\n    if (stt->vadMic.stdLongTerm < 2500)\n    {\n        stt->vadThreshold = 1500;\n    } else\n    {\n        vadThresh = kNormalVadThreshold;\n        if (stt->vadMic.stdLongTerm < 4500)\n        {\n            /* Scale between min and max threshold */\n            vadThresh += WEBRTC_SPL_RSHIFT_W16(4500 - stt->vadMic.stdLongTerm, 1);\n        }\n\n        /* stt->vadThreshold = (31 * stt->vadThreshold + vadThresh) / 32; */\n        tmp32 = (WebRtc_Word32)vadThresh;\n        tmp32 += WEBRTC_SPL_MUL_16_16((WebRtc_Word16)31, stt->vadThreshold);\n        stt->vadThreshold = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 5);\n    }\n}\n\nvoid WebRtcAgc_ExpCurve(WebRtc_Word16 volume, WebRtc_Word16 *index)\n{\n    // volume in Q14\n    // index in [0-7]\n    /* 8 different curves */\n    if (volume > 5243)\n    {\n        if (volume > 7864)\n        {\n            if (volume > 12124)\n            {\n                *index = 7;\n            } else\n            {\n                *index = 6;\n            }\n        } else\n        {\n            if (volume > 6554)\n            {\n                *index = 5;\n            } else\n            {\n                *index = 4;\n            }\n        }\n    } else\n    {\n        if (volume > 2621)\n        {\n            if (volume > 3932)\n            {\n                *index = 3;\n            } else\n            {\n                *index = 2;\n            }\n        } else\n        {\n            if (volume > 1311)\n            {\n                *index = 1;\n            } else\n            {\n                *index = 0;\n            }\n        }\n    }\n}\n\nWebRtc_Word32 WebRtcAgc_ProcessAnalog(void *state, WebRtc_Word32 inMicLevel,\n                                        WebRtc_Word32 *outMicLevel,\n                                        WebRtc_Word16 vadLogRatio,\n                                        WebRtc_Word16 echo, WebRtc_UWord8 *saturationWarning)\n{\n    WebRtc_UWord32 tmpU32;\n    WebRtc_Word32 Rxx16w32, tmp32;\n    WebRtc_Word32 inMicLevelTmp, lastMicVol;\n    WebRtc_Word16 i;\n    WebRtc_UWord8 saturated = 0;\n    Agc_t *stt;\n\n    stt = (Agc_t *)state;\n    inMicLevelTmp = WEBRTC_SPL_LSHIFT_W32(inMicLevel, stt->scale);\n\n    if (inMicLevelTmp > stt->maxAnalog)\n    {\n#ifdef AGC_DEBUG //test log\n        fprintf(stt->fpt, \"\\tAGC->ProcessAnalog, frame %d: micLvl > maxAnalog\\n\", stt->fcount);\n#endif\n        return -1;\n    } else if (inMicLevelTmp < stt->minLevel)\n    {\n#ifdef AGC_DEBUG //test log\n        fprintf(stt->fpt, \"\\tAGC->ProcessAnalog, frame %d: micLvl < minLevel\\n\", stt->fcount);\n#endif\n        return -1;\n    }\n\n    if (stt->firstCall == 0)\n    {\n        WebRtc_Word32 tmpVol;\n        stt->firstCall = 1;\n        tmp32 = WEBRTC_SPL_RSHIFT_W32((stt->maxLevel - stt->minLevel) * (WebRtc_Word32)51, 9);\n        tmpVol = (stt->minLevel + tmp32);\n\n        /* If the mic level is very low at start, increase it! */\n        if ((inMicLevelTmp < tmpVol) && (stt->agcMode == kAgcModeAdaptiveAnalog))\n        {\n            inMicLevelTmp = tmpVol;\n        }\n        stt->micVol = inMicLevelTmp;\n    }\n\n    /* Set the mic level to the previous output value if there is digital input gain */\n    if ((inMicLevelTmp == stt->maxAnalog) && (stt->micVol > stt->maxAnalog))\n    {\n        inMicLevelTmp = stt->micVol;\n    }\n\n    /* If the mic level was manually changed to a very low value raise it! */\n    if ((inMicLevelTmp != stt->micVol) && (inMicLevelTmp < stt->minOutput))\n    {\n        tmp32 = WEBRTC_SPL_RSHIFT_W32((stt->maxLevel - stt->minLevel) * (WebRtc_Word32)51, 9);\n        inMicLevelTmp = (stt->minLevel + tmp32);\n        stt->micVol = inMicLevelTmp;\n#ifdef MIC_LEVEL_FEEDBACK\n        //stt->numBlocksMicLvlSat = 0;\n#endif\n#ifdef AGC_DEBUG //test log\n        fprintf(stt->fpt,\n                \"\\tAGC->ProcessAnalog, frame %d: micLvl < minLevel by manual decrease, raise vol\\n\",\n                stt->fcount);\n#endif\n    }\n\n    if (inMicLevelTmp != stt->micVol)\n    {\n        // Incoming level mismatch; update our level.\n        // This could be the case if the volume is changed manually, or if the\n        // sound device has a low volume resolution.\n        stt->micVol = inMicLevelTmp;\n    }\n\n    if (inMicLevelTmp > stt->maxLevel)\n    {\n        // Always allow the user to raise the volume above the maxLevel.\n        stt->maxLevel = inMicLevelTmp;\n    }\n\n    // Store last value here, after we've taken care of manual updates etc.\n    lastMicVol = stt->micVol;\n\n    /* Checks if the signal is saturated. Also a check if individual samples\n     * are larger than 12000 is done. If they are the counter for increasing\n     * the volume level is set to -100ms\n     */\n    WebRtcAgc_SaturationCtrl(stt, &saturated, stt->env[0]);\n\n    /* The AGC is always allowed to lower the level if the signal is saturated */\n    if (saturated == 1)\n    {\n        /* Lower the recording level\n         * Rxx160_LP is adjusted down because it is so slow it could\n         * cause the AGC to make wrong decisions. */\n        /* stt->Rxx160_LPw32 *= 0.875; */\n        stt->Rxx160_LPw32 = WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(stt->Rxx160_LPw32, 3), 7);\n\n        stt->zeroCtrlMax = stt->micVol;\n\n        /* stt->micVol *= 0.903; */\n        tmp32 = inMicLevelTmp - stt->minLevel;\n        tmpU32 = WEBRTC_SPL_UMUL(29591, (WebRtc_UWord32)(tmp32));\n        stt->micVol = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_U32(tmpU32, 15) + stt->minLevel;\n        if (stt->micVol > lastMicVol - 2)\n        {\n            stt->micVol = lastMicVol - 2;\n        }\n        inMicLevelTmp = stt->micVol;\n\n#ifdef AGC_DEBUG //test log\n        fprintf(stt->fpt,\n                \"\\tAGC->ProcessAnalog, frame %d: saturated, micVol = %d\\n\",\n                stt->fcount, stt->micVol);\n#endif\n\n        if (stt->micVol < stt->minOutput)\n        {\n            *saturationWarning = 1;\n        }\n\n        /* Reset counter for decrease of volume level to avoid\n         * decreasing too much. The saturation control can still\n         * lower the level if needed. */\n        stt->msTooHigh = -100;\n\n        /* Enable the control mechanism to ensure that our measure,\n         * Rxx160_LP, is in the correct range. This must be done since\n         * the measure is very slow. */\n        stt->activeSpeech = 0;\n        stt->Rxx16_LPw32Max = 0;\n\n        /* Reset to initial values */\n        stt->msecSpeechInnerChange = kMsecSpeechInner;\n        stt->msecSpeechOuterChange = kMsecSpeechOuter;\n        stt->changeToSlowMode = 0;\n\n        stt->muteGuardMs = 0;\n\n        stt->upperLimit = stt->startUpperLimit;\n        stt->lowerLimit = stt->startLowerLimit;\n#ifdef MIC_LEVEL_FEEDBACK\n        //stt->numBlocksMicLvlSat = 0;\n#endif\n    }\n\n    /* Check if the input speech is zero. If so the mic volume\n     * is increased. On some computers the input is zero up as high\n     * level as 17% */\n    WebRtcAgc_ZeroCtrl(stt, &inMicLevelTmp, stt->env[0]);\n\n    /* Check if the near end speaker is inactive.\n     * If that is the case the VAD threshold is\n     * increased since the VAD speech model gets\n     * more sensitive to any sound after a long\n     * silence.\n     */\n    WebRtcAgc_SpeakerInactiveCtrl(stt);\n\n    for (i = 0; i < 5; i++)\n    {\n        /* Computed on blocks of 16 samples */\n\n        Rxx16w32 = stt->Rxx16w32_array[0][i];\n\n        /* Rxx160w32 in Q(-7) */\n        tmp32 = WEBRTC_SPL_RSHIFT_W32(Rxx16w32 - stt->Rxx16_vectorw32[stt->Rxx16pos], 3);\n        stt->Rxx160w32 = stt->Rxx160w32 + tmp32;\n        stt->Rxx16_vectorw32[stt->Rxx16pos] = Rxx16w32;\n\n        /* Circular buffer */\n        stt->Rxx16pos++;\n        if (stt->Rxx16pos == RXX_BUFFER_LEN)\n        {\n            stt->Rxx16pos = 0;\n        }\n\n        /* Rxx16_LPw32 in Q(-4) */\n        tmp32 = WEBRTC_SPL_RSHIFT_W32(Rxx16w32 - stt->Rxx16_LPw32, kAlphaShortTerm);\n        stt->Rxx16_LPw32 = (stt->Rxx16_LPw32) + tmp32;\n\n        if (vadLogRatio > stt->vadThreshold)\n        {\n            /* Speech detected! */\n\n            /* Check if Rxx160_LP is in the correct range. If\n             * it is too high/low then we set it to the maximum of\n             * Rxx16_LPw32 during the first 200ms of speech.\n             */\n            if (stt->activeSpeech < 250)\n            {\n                stt->activeSpeech += 2;\n\n                if (stt->Rxx16_LPw32 > stt->Rxx16_LPw32Max)\n                {\n                    stt->Rxx16_LPw32Max = stt->Rxx16_LPw32;\n                }\n            } else if (stt->activeSpeech == 250)\n            {\n                stt->activeSpeech += 2;\n                tmp32 = WEBRTC_SPL_RSHIFT_W32(stt->Rxx16_LPw32Max, 3);\n                stt->Rxx160_LPw32 = WEBRTC_SPL_MUL(tmp32, RXX_BUFFER_LEN);\n            }\n\n            tmp32 = WEBRTC_SPL_RSHIFT_W32(stt->Rxx160w32 - stt->Rxx160_LPw32, kAlphaLongTerm);\n            stt->Rxx160_LPw32 = stt->Rxx160_LPw32 + tmp32;\n\n            if (stt->Rxx160_LPw32 > stt->upperSecondaryLimit)\n            {\n                stt->msTooHigh += 2;\n                stt->msTooLow = 0;\n                stt->changeToSlowMode = 0;\n\n                if (stt->msTooHigh > stt->msecSpeechOuterChange)\n                {\n                    stt->msTooHigh = 0;\n\n                    /* Lower the recording level */\n                    /* Multiply by 0.828125 which corresponds to decreasing ~0.8dB */\n                    tmp32 = WEBRTC_SPL_RSHIFT_W32(stt->Rxx160_LPw32, 6);\n                    stt->Rxx160_LPw32 = WEBRTC_SPL_MUL(tmp32, 53);\n\n                    /* Reduce the max gain to avoid excessive oscillation\n                     * (but never drop below the maximum analog level).\n                     * stt->maxLevel = (15 * stt->maxLevel + stt->micVol) / 16;\n                     */\n                    tmp32 = (15 * stt->maxLevel) + stt->micVol;\n                    stt->maxLevel = WEBRTC_SPL_RSHIFT_W32(tmp32, 4);\n                    stt->maxLevel = WEBRTC_SPL_MAX(stt->maxLevel, stt->maxAnalog);\n\n                    stt->zeroCtrlMax = stt->micVol;\n\n                    /* 0.95 in Q15 */\n                    tmp32 = inMicLevelTmp - stt->minLevel;\n                    tmpU32 = WEBRTC_SPL_UMUL(31130, (WebRtc_UWord32)(tmp32));\n                    stt->micVol = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_U32(tmpU32, 15) + stt->minLevel;\n                    if (stt->micVol > lastMicVol - 1)\n                    {\n                        stt->micVol = lastMicVol - 1;\n                    }\n                    inMicLevelTmp = stt->micVol;\n\n                    /* Enable the control mechanism to ensure that our measure,\n                     * Rxx160_LP, is in the correct range.\n                     */\n                    stt->activeSpeech = 0;\n                    stt->Rxx16_LPw32Max = 0;\n#ifdef MIC_LEVEL_FEEDBACK\n                    //stt->numBlocksMicLvlSat = 0;\n#endif\n#ifdef AGC_DEBUG //test log\n                    fprintf(stt->fpt,\n                            \"\\tAGC->ProcessAnalog, frame %d: measure > 2ndUpperLim, micVol = %d, maxLevel = %d\\n\",\n                            stt->fcount, stt->micVol, stt->maxLevel);\n#endif\n                }\n            } else if (stt->Rxx160_LPw32 > stt->upperLimit)\n            {\n                stt->msTooHigh += 2;\n                stt->msTooLow = 0;\n                stt->changeToSlowMode = 0;\n\n                if (stt->msTooHigh > stt->msecSpeechInnerChange)\n                {\n                    /* Lower the recording level */\n                    stt->msTooHigh = 0;\n                    /* Multiply by 0.828125 which corresponds to decreasing ~0.8dB */\n                    tmp32 = WEBRTC_SPL_RSHIFT_W32(stt->Rxx160_LPw32, 6);\n                    stt->Rxx160_LPw32 = WEBRTC_SPL_MUL(tmp32, 53);\n\n                    /* Reduce the max gain to avoid excessive oscillation\n                     * (but never drop below the maximum analog level).\n                     * stt->maxLevel = (15 * stt->maxLevel + stt->micVol) / 16;\n                     */\n                    tmp32 = (15 * stt->maxLevel) + stt->micVol;\n                    stt->maxLevel = WEBRTC_SPL_RSHIFT_W32(tmp32, 4);\n                    stt->maxLevel = WEBRTC_SPL_MAX(stt->maxLevel, stt->maxAnalog);\n\n                    stt->zeroCtrlMax = stt->micVol;\n\n                    /* 0.965 in Q15 */\n                    tmp32 = inMicLevelTmp - stt->minLevel;\n                    tmpU32 = WEBRTC_SPL_UMUL(31621, (WebRtc_UWord32)(inMicLevelTmp - stt->minLevel));\n                    stt->micVol = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_U32(tmpU32, 15) + stt->minLevel;\n                    if (stt->micVol > lastMicVol - 1)\n                    {\n                        stt->micVol = lastMicVol - 1;\n                    }\n                    inMicLevelTmp = stt->micVol;\n\n#ifdef MIC_LEVEL_FEEDBACK\n                    //stt->numBlocksMicLvlSat = 0;\n#endif\n#ifdef AGC_DEBUG //test log\n                    fprintf(stt->fpt,\n                            \"\\tAGC->ProcessAnalog, frame %d: measure > UpperLim, micVol = %d, maxLevel = %d\\n\",\n                            stt->fcount, stt->micVol, stt->maxLevel);\n#endif\n                }\n            } else if (stt->Rxx160_LPw32 < stt->lowerSecondaryLimit)\n            {\n                stt->msTooHigh = 0;\n                stt->changeToSlowMode = 0;\n                stt->msTooLow += 2;\n\n                if (stt->msTooLow > stt->msecSpeechOuterChange)\n                {\n                    /* Raise the recording level */\n                    WebRtc_Word16 index, weightFIX;\n                    WebRtc_Word16 volNormFIX = 16384; // =1 in Q14.\n\n                    stt->msTooLow = 0;\n\n                    /* Normalize the volume level */\n                    tmp32 = WEBRTC_SPL_LSHIFT_W32(inMicLevelTmp - stt->minLevel, 14);\n                    if (stt->maxInit != stt->minLevel)\n                    {\n                        volNormFIX = (WebRtc_Word16)WEBRTC_SPL_DIV(tmp32,\n                                                              (stt->maxInit - stt->minLevel));\n                    }\n\n                    /* Find correct curve */\n                    WebRtcAgc_ExpCurve(volNormFIX, &index);\n\n                    /* Compute weighting factor for the volume increase, 32^(-2*X)/2+1.05 */\n                    weightFIX = kOffset1[index]\n                              - (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(kSlope1[index],\n                                                                         volNormFIX, 13);\n\n                    /* stt->Rxx160_LPw32 *= 1.047 [~0.2 dB]; */\n                    tmp32 = WEBRTC_SPL_RSHIFT_W32(stt->Rxx160_LPw32, 6);\n                    stt->Rxx160_LPw32 = WEBRTC_SPL_MUL(tmp32, 67);\n\n                    tmp32 = inMicLevelTmp - stt->minLevel;\n                    tmpU32 = ((WebRtc_UWord32)weightFIX * (WebRtc_UWord32)(inMicLevelTmp - stt->minLevel));\n                    stt->micVol = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_U32(tmpU32, 14) + stt->minLevel;\n                    if (stt->micVol < lastMicVol + 2)\n                    {\n                        stt->micVol = lastMicVol + 2;\n                    }\n\n                    inMicLevelTmp = stt->micVol;\n\n#ifdef MIC_LEVEL_FEEDBACK\n                    /* Count ms in level saturation */\n                    //if (stt->micVol > stt->maxAnalog) {\n                    if (stt->micVol > 150)\n                    {\n                        /* mic level is saturated */\n                        stt->numBlocksMicLvlSat++;\n                        fprintf(stderr, \"Sat mic Level: %d\\n\", stt->numBlocksMicLvlSat);\n                    }\n#endif\n#ifdef AGC_DEBUG //test log\n                    fprintf(stt->fpt,\n                            \"\\tAGC->ProcessAnalog, frame %d: measure < 2ndLowerLim, micVol = %d\\n\",\n                            stt->fcount, stt->micVol);\n#endif\n                }\n            } else if (stt->Rxx160_LPw32 < stt->lowerLimit)\n            {\n                stt->msTooHigh = 0;\n                stt->changeToSlowMode = 0;\n                stt->msTooLow += 2;\n\n                if (stt->msTooLow > stt->msecSpeechInnerChange)\n                {\n                    /* Raise the recording level */\n                    WebRtc_Word16 index, weightFIX;\n                    WebRtc_Word16 volNormFIX = 16384; // =1 in Q14.\n\n                    stt->msTooLow = 0;\n\n                    /* Normalize the volume level */\n                    tmp32 = WEBRTC_SPL_LSHIFT_W32(inMicLevelTmp - stt->minLevel, 14);\n                    if (stt->maxInit != stt->minLevel)\n                    {\n                        volNormFIX = (WebRtc_Word16)WEBRTC_SPL_DIV(tmp32,\n                                                              (stt->maxInit - stt->minLevel));\n                    }\n\n                    /* Find correct curve */\n                    WebRtcAgc_ExpCurve(volNormFIX, &index);\n\n                    /* Compute weighting factor for the volume increase, (3.^(-2.*X))/8+1 */\n                    weightFIX = kOffset2[index]\n                              - (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(kSlope2[index],\n                                                                         volNormFIX, 13);\n\n                    /* stt->Rxx160_LPw32 *= 1.047 [~0.2 dB]; */\n                    tmp32 = WEBRTC_SPL_RSHIFT_W32(stt->Rxx160_LPw32, 6);\n                    stt->Rxx160_LPw32 = WEBRTC_SPL_MUL(tmp32, 67);\n\n                    tmp32 = inMicLevelTmp - stt->minLevel;\n                    tmpU32 = ((WebRtc_UWord32)weightFIX * (WebRtc_UWord32)(inMicLevelTmp - stt->minLevel));\n                    stt->micVol = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_U32(tmpU32, 14) + stt->minLevel;\n                    if (stt->micVol < lastMicVol + 1)\n                    {\n                        stt->micVol = lastMicVol + 1;\n                    }\n\n                    inMicLevelTmp = stt->micVol;\n\n#ifdef MIC_LEVEL_FEEDBACK\n                    /* Count ms in level saturation */\n                    //if (stt->micVol > stt->maxAnalog) {\n                    if (stt->micVol > 150)\n                    {\n                        /* mic level is saturated */\n                        stt->numBlocksMicLvlSat++;\n                        fprintf(stderr, \"Sat mic Level: %d\\n\", stt->numBlocksMicLvlSat);\n                    }\n#endif\n#ifdef AGC_DEBUG //test log\n                    fprintf(stt->fpt,\n                            \"\\tAGC->ProcessAnalog, frame %d: measure < LowerLim, micVol = %d\\n\",\n                            stt->fcount, stt->micVol);\n#endif\n\n                }\n            } else\n            {\n                /* The signal is inside the desired range which is:\n                 * lowerLimit < Rxx160_LP/640 < upperLimit\n                 */\n                if (stt->changeToSlowMode > 4000)\n                {\n                    stt->msecSpeechInnerChange = 1000;\n                    stt->msecSpeechOuterChange = 500;\n                    stt->upperLimit = stt->upperPrimaryLimit;\n                    stt->lowerLimit = stt->lowerPrimaryLimit;\n                } else\n                {\n                    stt->changeToSlowMode += 2; // in milliseconds\n                }\n                stt->msTooLow = 0;\n                stt->msTooHigh = 0;\n\n                stt->micVol = inMicLevelTmp;\n\n            }\n#ifdef MIC_LEVEL_FEEDBACK\n            if (stt->numBlocksMicLvlSat > NUM_BLOCKS_IN_SAT_BEFORE_CHANGE_TARGET)\n            {\n                stt->micLvlSat = 1;\n                fprintf(stderr, \"target before = %d (%d)\\n\", stt->analogTargetLevel, stt->targetIdx);\n                WebRtcAgc_UpdateAgcThresholds(stt);\n                WebRtcAgc_CalculateGainTable(&(stt->digitalAgc.gainTable[0]),\n                        stt->compressionGaindB, stt->targetLevelDbfs, stt->limiterEnable,\n                        stt->analogTarget);\n                stt->numBlocksMicLvlSat = 0;\n                stt->micLvlSat = 0;\n                fprintf(stderr, \"target offset = %d\\n\", stt->targetIdxOffset);\n                fprintf(stderr, \"target after  = %d (%d)\\n\", stt->analogTargetLevel, stt->targetIdx);\n            }\n#endif\n        }\n    }\n\n    /* Ensure gain is not increased in presence of echo or after a mute event\n     * (but allow the zeroCtrl() increase on the frame of a mute detection).\n     */\n    if (echo == 1 || (stt->muteGuardMs > 0 && stt->muteGuardMs < kMuteGuardTimeMs))\n    {\n        if (stt->micVol > lastMicVol)\n        {\n            stt->micVol = lastMicVol;\n        }\n    }\n\n    /* limit the gain */\n    if (stt->micVol > stt->maxLevel)\n    {\n        stt->micVol = stt->maxLevel;\n    } else if (stt->micVol < stt->minOutput)\n    {\n        stt->micVol = stt->minOutput;\n    }\n\n    *outMicLevel = WEBRTC_SPL_RSHIFT_W32(stt->micVol, stt->scale);\n    if (*outMicLevel > WEBRTC_SPL_RSHIFT_W32(stt->maxAnalog, stt->scale))\n    {\n        *outMicLevel = WEBRTC_SPL_RSHIFT_W32(stt->maxAnalog, stt->scale);\n    }\n\n    return 0;\n}\n\nint WebRtcAgc_Process(void *agcInst, const WebRtc_Word16 *in_near,\n                      const WebRtc_Word16 *in_near_H, WebRtc_Word16 samples,\n                      WebRtc_Word16 *out, WebRtc_Word16 *out_H, WebRtc_Word32 inMicLevel,\n                      WebRtc_Word32 *outMicLevel, WebRtc_Word16 echo,\n                      WebRtc_UWord8 *saturationWarning)\n{\n    Agc_t *stt;\n    WebRtc_Word32 inMicLevelTmp;\n    WebRtc_Word16 subFrames, i;\n    WebRtc_UWord8 satWarningTmp = 0;\n\n    stt = (Agc_t *)agcInst;\n\n    //\n    if (stt == NULL)\n    {\n        return -1;\n    }\n    //\n\n\n    if (stt->fs == 8000)\n    {\n        if ((samples != 80) && (samples != 160))\n        {\n#ifdef AGC_DEBUG //test log\n            fprintf(stt->fpt,\n                    \"AGC->Process, frame %d: Invalid number of samples\\n\\n\", stt->fcount);\n#endif\n            return -1;\n        }\n        subFrames = 80;\n    } else if (stt->fs == 16000)\n    {\n        if ((samples != 160) && (samples != 320))\n        {\n#ifdef AGC_DEBUG //test log\n            fprintf(stt->fpt,\n                    \"AGC->Process, frame %d: Invalid number of samples\\n\\n\", stt->fcount);\n#endif\n            return -1;\n        }\n        subFrames = 160;\n    } else if (stt->fs == 32000)\n    {\n        if ((samples != 160) && (samples != 320))\n        {\n#ifdef AGC_DEBUG //test log\n            fprintf(stt->fpt,\n                    \"AGC->Process, frame %d: Invalid number of samples\\n\\n\", stt->fcount);\n#endif\n            return -1;\n        }\n        subFrames = 160;\n    } else\n    {\n#ifdef AGC_DEBUG// test log\n        fprintf(stt->fpt,\n                \"AGC->Process, frame %d: Invalid sample rate\\n\\n\", stt->fcount);\n#endif\n        return -1;\n    }\n\n    /* Check for valid pointers based on sampling rate */\n    if (stt->fs == 32000 && in_near_H == NULL)\n    {\n        return -1;\n    }\n    /* Check for valid pointers for low band */\n    if (in_near == NULL)\n    {\n        return -1;\n    }\n\n    *saturationWarning = 0;\n    //TODO: PUT IN RANGE CHECKING FOR INPUT LEVELS\n    *outMicLevel = inMicLevel;\n    inMicLevelTmp = inMicLevel;\n\n    // TODO(andrew): clearly we don't need input and output pointers...\n    //   Change the interface to take a shared input/output.\n    if (in_near != out)\n    {\n        // Only needed if they don't already point to the same place.\n        memcpy(out, in_near, samples * sizeof(WebRtc_Word16));\n    }\n    if (stt->fs == 32000)\n    {\n        if (in_near_H != out_H)\n        {\n            memcpy(out_H, in_near_H, samples * sizeof(WebRtc_Word16));\n        }\n    }\n\n#ifdef AGC_DEBUG//test log\n    stt->fcount++;\n#endif\n\n    for (i = 0; i < samples; i += subFrames)\n    {\n        if (WebRtcAgc_ProcessDigital(&stt->digitalAgc, &in_near[i], &in_near_H[i], &out[i], &out_H[i],\n                           stt->fs, stt->lowLevelSignal) == -1)\n        {\n#ifdef AGC_DEBUG//test log\n            fprintf(stt->fpt, \"AGC->Process, frame %d: Error from DigAGC\\n\\n\", stt->fcount);\n#endif\n            return -1;\n        }\n        if ((stt->agcMode < kAgcModeFixedDigital) && ((stt->lowLevelSignal == 0)\n                || (stt->agcMode != kAgcModeAdaptiveDigital)))\n        {\n            if (WebRtcAgc_ProcessAnalog(agcInst, inMicLevelTmp, outMicLevel,\n                                          stt->vadMic.logRatio, echo, saturationWarning) == -1)\n            {\n                return -1;\n            }\n        }\n#ifdef AGC_DEBUG//test log\n        fprintf(stt->agcLog, \"%5d\\t%d\\t%d\\t%d\\n\", stt->fcount, inMicLevelTmp, *outMicLevel, stt->maxLevel, stt->micVol);\n#endif\n\n        /* update queue */\n        if (stt->inQueue > 1)\n        {\n            memcpy(stt->env[0], stt->env[1], 10 * sizeof(WebRtc_Word32));\n            memcpy(stt->Rxx16w32_array[0], stt->Rxx16w32_array[1], 5 * sizeof(WebRtc_Word32));\n        }\n\n        if (stt->inQueue > 0)\n        {\n            stt->inQueue--;\n        }\n\n        /* If 20ms frames are used the input mic level must be updated so that\n         * the analog AGC does not think that there has been a manual volume\n         * change. */\n        inMicLevelTmp = *outMicLevel;\n\n        /* Store a positive saturation warning. */\n        if (*saturationWarning == 1)\n        {\n            satWarningTmp = 1;\n        }\n    }\n\n    /* Trigger the saturation warning if displayed by any of the frames. */\n    *saturationWarning = satWarningTmp;\n\n    return 0;\n}\n\nint WebRtcAgc_set_config(void *agcInst, WebRtcAgc_config_t agcConfig)\n{\n    Agc_t *stt;\n    stt = (Agc_t *)agcInst;\n\n    if (stt == NULL)\n    {\n        return -1;\n    }\n\n    if (stt->initFlag != kInitCheck)\n    {\n        stt->lastError = AGC_UNINITIALIZED_ERROR;\n        return -1;\n    }\n\n    if (agcConfig.limiterEnable != kAgcFalse && agcConfig.limiterEnable != kAgcTrue)\n    {\n        stt->lastError = AGC_BAD_PARAMETER_ERROR;\n        return -1;\n    }\n    stt->limiterEnable = agcConfig.limiterEnable;\n    stt->compressionGaindB = agcConfig.compressionGaindB;\n    if ((agcConfig.targetLevelDbfs < 0) || (agcConfig.targetLevelDbfs > 31))\n    {\n        stt->lastError = AGC_BAD_PARAMETER_ERROR;\n        return -1;\n    }\n    stt->targetLevelDbfs = agcConfig.targetLevelDbfs;\n\n    if (stt->agcMode == kAgcModeFixedDigital)\n    {\n        /* Adjust for different parameter interpretation in FixedDigital mode */\n        stt->compressionGaindB += agcConfig.targetLevelDbfs;\n    }\n\n    /* Update threshold levels for analog adaptation */\n    WebRtcAgc_UpdateAgcThresholds(stt);\n\n    /* Recalculate gain table */\n    if (WebRtcAgc_CalculateGainTable(&(stt->digitalAgc.gainTable[0]), stt->compressionGaindB,\n                           stt->targetLevelDbfs, stt->limiterEnable, stt->analogTarget) == -1)\n    {\n#ifdef AGC_DEBUG//test log\n        fprintf(stt->fpt, \"AGC->set_config, frame %d: Error from calcGainTable\\n\\n\", stt->fcount);\n#endif\n        return -1;\n    }\n    /* Store the config in a WebRtcAgc_config_t */\n    stt->usedConfig.compressionGaindB = agcConfig.compressionGaindB;\n    stt->usedConfig.limiterEnable = agcConfig.limiterEnable;\n    stt->usedConfig.targetLevelDbfs = agcConfig.targetLevelDbfs;\n\n    return 0;\n}\n\nint WebRtcAgc_get_config(void *agcInst, WebRtcAgc_config_t *config)\n{\n    Agc_t *stt;\n    stt = (Agc_t *)agcInst;\n\n    if (stt == NULL)\n    {\n        return -1;\n    }\n\n    if (config == NULL)\n    {\n        stt->lastError = AGC_NULL_POINTER_ERROR;\n        return -1;\n    }\n\n    if (stt->initFlag != kInitCheck)\n    {\n        stt->lastError = AGC_UNINITIALIZED_ERROR;\n        return -1;\n    }\n\n    config->limiterEnable = stt->usedConfig.limiterEnable;\n    config->targetLevelDbfs = stt->usedConfig.targetLevelDbfs;\n    config->compressionGaindB = stt->usedConfig.compressionGaindB;\n\n    return 0;\n}\n\nint WebRtcAgc_Create(void **agcInst)\n{\n    Agc_t *stt;\n    if (agcInst == NULL)\n    {\n        return -1;\n    }\n    stt = (Agc_t *)malloc(sizeof(Agc_t));\n\n    *agcInst = stt;\n    if (stt == NULL)\n    {\n        return -1;\n    }\n\n#ifdef AGC_DEBUG\n    stt->fpt = fopen(\"./agc_test_log.txt\", \"wt\");\n    stt->agcLog = fopen(\"./agc_debug_log.txt\", \"wt\");\n    stt->digitalAgc.logFile = fopen(\"./agc_log.txt\", \"wt\");\n#endif\n\n    stt->initFlag = 0;\n    stt->lastError = 0;\n\n    return 0;\n}\n\nint WebRtcAgc_Free(void *state)\n{\n    Agc_t *stt;\n\n    stt = (Agc_t *)state;\n#ifdef AGC_DEBUG\n    fclose(stt->fpt);\n    fclose(stt->agcLog);\n    fclose(stt->digitalAgc.logFile);\n#endif\n    free(stt);\n\n    return 0;\n}\n\n/* minLevel     - Minimum volume level\n * maxLevel     - Maximum volume level\n */\nint WebRtcAgc_Init(void *agcInst, WebRtc_Word32 minLevel, WebRtc_Word32 maxLevel,\n                             WebRtc_Word16 agcMode, WebRtc_UWord32 fs)\n{\n    WebRtc_Word32 max_add, tmp32;\n    WebRtc_Word16 i;\n    int tmpNorm;\n    Agc_t *stt;\n\n    /* typecast state pointer */\n    stt = (Agc_t *)agcInst;\n\n    if (WebRtcAgc_InitDigital(&stt->digitalAgc, agcMode) != 0)\n    {\n        stt->lastError = AGC_UNINITIALIZED_ERROR;\n        return -1;\n    }\n\n    /* Analog AGC variables */\n    stt->envSum = 0;\n\n    /* mode     = 0 - Only saturation protection\n     *            1 - Analog Automatic Gain Control [-targetLevelDbfs (default -3 dBOv)]\n     *            2 - Digital Automatic Gain Control [-targetLevelDbfs (default -3 dBOv)]\n     *            3 - Fixed Digital Gain [compressionGaindB (default 8 dB)]\n     */\n#ifdef AGC_DEBUG//test log\n    stt->fcount = 0;\n    fprintf(stt->fpt, \"AGC->Init\\n\");\n#endif\n    if (agcMode < kAgcModeUnchanged || agcMode > kAgcModeFixedDigital)\n    {\n#ifdef AGC_DEBUG//test log\n        fprintf(stt->fpt, \"AGC->Init: error, incorrect mode\\n\\n\");\n#endif\n        return -1;\n    }\n    stt->agcMode = agcMode;\n    stt->fs = fs;\n\n    /* initialize input VAD */\n    WebRtcAgc_InitVad(&stt->vadMic);\n\n    /* If the volume range is smaller than 0-256 then\n     * the levels are shifted up to Q8-domain */\n    tmpNorm = WebRtcSpl_NormU32((WebRtc_UWord32)maxLevel);\n    stt->scale = tmpNorm - 23;\n    if (stt->scale < 0)\n    {\n        stt->scale = 0;\n    }\n    // TODO(bjornv): Investigate if we really need to scale up a small range now when we have\n    // a guard against zero-increments. For now, we do not support scale up (scale = 0).\n    stt->scale = 0;\n    maxLevel = WEBRTC_SPL_LSHIFT_W32(maxLevel, stt->scale);\n    minLevel = WEBRTC_SPL_LSHIFT_W32(minLevel, stt->scale);\n\n    /* Make minLevel and maxLevel static in AdaptiveDigital */\n    if (stt->agcMode == kAgcModeAdaptiveDigital)\n    {\n        minLevel = 0;\n        maxLevel = 255;\n        stt->scale = 0;\n    }\n    /* The maximum supplemental volume range is based on a vague idea\n     * of how much lower the gain will be than the real analog gain. */\n    max_add = WEBRTC_SPL_RSHIFT_W32(maxLevel - minLevel, 2);\n\n    /* Minimum/maximum volume level that can be set */\n    stt->minLevel = minLevel;\n    stt->maxAnalog = maxLevel;\n    stt->maxLevel = maxLevel + max_add;\n    stt->maxInit = stt->maxLevel;\n\n    stt->zeroCtrlMax = stt->maxAnalog;\n\n    /* Initialize micVol parameter */\n    stt->micVol = stt->maxAnalog;\n    if (stt->agcMode == kAgcModeAdaptiveDigital)\n    {\n        stt->micVol = 127; /* Mid-point of mic level */\n    }\n    stt->micRef = stt->micVol;\n    stt->micGainIdx = 127;\n#ifdef MIC_LEVEL_FEEDBACK\n    stt->numBlocksMicLvlSat = 0;\n    stt->micLvlSat = 0;\n#endif\n#ifdef AGC_DEBUG//test log\n    fprintf(stt->fpt,\n            \"AGC->Init: minLevel = %d, maxAnalog = %d, maxLevel = %d\\n\",\n            stt->minLevel, stt->maxAnalog, stt->maxLevel);\n#endif\n\n    /* Minimum output volume is 4% higher than the available lowest volume level */\n    tmp32 = WEBRTC_SPL_RSHIFT_W32((stt->maxLevel - stt->minLevel) * (WebRtc_Word32)10, 8);\n    stt->minOutput = (stt->minLevel + tmp32);\n\n    stt->msTooLow = 0;\n    stt->msTooHigh = 0;\n    stt->changeToSlowMode = 0;\n    stt->firstCall = 0;\n    stt->msZero = 0;\n    stt->muteGuardMs = 0;\n    stt->gainTableIdx = 0;\n\n    stt->msecSpeechInnerChange = kMsecSpeechInner;\n    stt->msecSpeechOuterChange = kMsecSpeechOuter;\n\n    stt->activeSpeech = 0;\n    stt->Rxx16_LPw32Max = 0;\n\n    stt->vadThreshold = kNormalVadThreshold;\n    stt->inActive = 0;\n\n    for (i = 0; i < RXX_BUFFER_LEN; i++)\n    {\n        stt->Rxx16_vectorw32[i] = (WebRtc_Word32)1000; /* -54dBm0 */\n    }\n    stt->Rxx160w32 = 125 * RXX_BUFFER_LEN; /* (stt->Rxx16_vectorw32[0]>>3) = 125 */\n\n    stt->Rxx16pos = 0;\n    stt->Rxx16_LPw32 = (WebRtc_Word32)16284; /* Q(-4) */\n\n    for (i = 0; i < 5; i++)\n    {\n        stt->Rxx16w32_array[0][i] = 0;\n    }\n    for (i = 0; i < 20; i++)\n    {\n        stt->env[0][i] = 0;\n    }\n    stt->inQueue = 0;\n\n#ifdef MIC_LEVEL_FEEDBACK\n    stt->targetIdxOffset = 0;\n#endif\n\n    WebRtcSpl_MemSetW32(stt->filterState, 0, 8);\n\n    stt->initFlag = kInitCheck;\n    // Default config settings.\n    stt->defaultConfig.limiterEnable = kAgcTrue;\n    stt->defaultConfig.targetLevelDbfs = AGC_DEFAULT_TARGET_LEVEL;\n    stt->defaultConfig.compressionGaindB = AGC_DEFAULT_COMP_GAIN;\n\n    if (WebRtcAgc_set_config(stt, stt->defaultConfig) == -1)\n    {\n        stt->lastError = AGC_UNSPECIFIED_ERROR;\n        return -1;\n    }\n    stt->Rxx160_LPw32 = stt->analogTargetLevel; // Initialize rms value\n\n    stt->lowLevelSignal = 0;\n\n    /* Only positive values are allowed that are not too large */\n    if ((minLevel >= maxLevel) || (maxLevel & 0xFC000000))\n    {\n#ifdef AGC_DEBUG//test log\n        fprintf(stt->fpt, \"minLevel, maxLevel value(s) are invalid\\n\\n\");\n#endif\n        return -1;\n    } else\n    {\n#ifdef AGC_DEBUG//test log\n        fprintf(stt->fpt, \"\\n\");\n#endif\n        return 0;\n    }\n}\n\nint WebRtcAgc_Version(WebRtc_Word8 *versionStr, WebRtc_Word16 length)\n{\n    const WebRtc_Word8 version[] = \"AGC 1.7.0\";\n    const WebRtc_Word16 versionLen = (WebRtc_Word16)strlen(version) + 1;\n\n    if (versionStr == NULL)\n    {\n        return -1;\n    }\n\n    if (versionLen > length)\n    {\n        return -1;\n    }\n\n    strncpy(versionStr, version, versionLen);\n    return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/agc/main/source/analog_agc.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_ANALOG_AGC_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_ANALOG_AGC_H_\n\n#include \"typedefs.h\"\n#include \"gain_control.h\"\n#include \"digital_agc.h\"\n\n//#define AGC_DEBUG\n//#define MIC_LEVEL_FEEDBACK\n#ifdef AGC_DEBUG\n#include <stdio.h>\n#endif\n\n/* Analog Automatic Gain Control variables:\n * Constant declarations (inner limits inside which no changes are done)\n * In the beginning the range is narrower to widen as soon as the measure\n * 'Rxx160_LP' is inside it. Currently the starting limits are -22.2+/-1dBm0\n * and the final limits -22.2+/-2.5dBm0. These levels makes the speech signal\n * go towards -25.4dBm0 (-31.4dBov). Tuned with wbfile-31.4dBov.pcm\n * The limits are created by running the AGC with a file having the desired\n * signal level and thereafter plotting Rxx160_LP in the dBm0-domain defined\n * by out=10*log10(in/260537279.7); Set the target level to the average level\n * of our measure Rxx160_LP. Remember that the levels are in blocks of 16 in\n * Q(-7). (Example matlab code: round(db2pow(-21.2)*16/2^7) )\n */\n#define RXX_BUFFER_LEN  10\n\nstatic const WebRtc_Word16 kMsecSpeechInner = 520;\nstatic const WebRtc_Word16 kMsecSpeechOuter = 340;\n\nstatic const WebRtc_Word16 kNormalVadThreshold = 400;\n\nstatic const WebRtc_Word16 kAlphaShortTerm = 6; // 1 >> 6 = 0.0156\nstatic const WebRtc_Word16 kAlphaLongTerm = 10; // 1 >> 10 = 0.000977\n\ntypedef struct\n{\n    // Configurable parameters/variables\n    WebRtc_UWord32      fs;                 // Sampling frequency\n    WebRtc_Word16       compressionGaindB;  // Fixed gain level in dB\n    WebRtc_Word16       targetLevelDbfs;    // Target level in -dBfs of envelope (default -3)\n    WebRtc_Word16       agcMode;            // Hard coded mode (adaptAna/adaptDig/fixedDig)\n    WebRtc_UWord8       limiterEnable;      // Enabling limiter (on/off (default off))\n    WebRtcAgc_config_t  defaultConfig;\n    WebRtcAgc_config_t  usedConfig;\n\n    // General variables\n    WebRtc_Word16       initFlag;\n    WebRtc_Word16       lastError;\n\n    // Target level parameters\n    // Based on the above: analogTargetLevel = round((32767*10^(-22/20))^2*16/2^7)\n    WebRtc_Word32       analogTargetLevel;  // = RXX_BUFFER_LEN * 846805;       -22 dBfs\n    WebRtc_Word32       startUpperLimit;    // = RXX_BUFFER_LEN * 1066064;      -21 dBfs\n    WebRtc_Word32       startLowerLimit;    // = RXX_BUFFER_LEN * 672641;       -23 dBfs\n    WebRtc_Word32       upperPrimaryLimit;  // = RXX_BUFFER_LEN * 1342095;      -20 dBfs\n    WebRtc_Word32       lowerPrimaryLimit;  // = RXX_BUFFER_LEN * 534298;       -24 dBfs\n    WebRtc_Word32       upperSecondaryLimit;// = RXX_BUFFER_LEN * 2677832;      -17 dBfs\n    WebRtc_Word32       lowerSecondaryLimit;// = RXX_BUFFER_LEN * 267783;       -27 dBfs\n    WebRtc_UWord16      targetIdx;          // Table index for corresponding target level\n#ifdef MIC_LEVEL_FEEDBACK\n    WebRtc_UWord16      targetIdxOffset;    // Table index offset for level compensation\n#endif\n    WebRtc_Word16       analogTarget;       // Digital reference level in ENV scale\n\n    // Analog AGC specific variables\n    WebRtc_Word32       filterState[8];     // For downsampling wb to nb\n    WebRtc_Word32       upperLimit;         // Upper limit for mic energy\n    WebRtc_Word32       lowerLimit;         // Lower limit for mic energy\n    WebRtc_Word32       Rxx160w32;          // Average energy for one frame\n    WebRtc_Word32       Rxx16_LPw32;        // Low pass filtered subframe energies\n    WebRtc_Word32       Rxx160_LPw32;       // Low pass filtered frame energies\n    WebRtc_Word32       Rxx16_LPw32Max;     // Keeps track of largest energy subframe\n    WebRtc_Word32       Rxx16_vectorw32[RXX_BUFFER_LEN];// Array with subframe energies\n    WebRtc_Word32       Rxx16w32_array[2][5];// Energy values of microphone signal\n    WebRtc_Word32       env[2][10];         // Envelope values of subframes\n\n    WebRtc_Word16       Rxx16pos;           // Current position in the Rxx16_vectorw32\n    WebRtc_Word16       envSum;             // Filtered scaled envelope in subframes\n    WebRtc_Word16       vadThreshold;       // Threshold for VAD decision\n    WebRtc_Word16       inActive;           // Inactive time in milliseconds\n    WebRtc_Word16       msTooLow;           // Milliseconds of speech at a too low level\n    WebRtc_Word16       msTooHigh;          // Milliseconds of speech at a too high level\n    WebRtc_Word16       changeToSlowMode;   // Change to slow mode after some time at target\n    WebRtc_Word16       firstCall;          // First call to the process-function\n    WebRtc_Word16       msZero;             // Milliseconds of zero input\n    WebRtc_Word16       msecSpeechOuterChange;// Min ms of speech between volume changes\n    WebRtc_Word16       msecSpeechInnerChange;// Min ms of speech between volume changes\n    WebRtc_Word16       activeSpeech;       // Milliseconds of active speech\n    WebRtc_Word16       muteGuardMs;        // Counter to prevent mute action\n    WebRtc_Word16       inQueue;            // 10 ms batch indicator\n\n    // Microphone level variables\n    WebRtc_Word32       micRef;             // Remember ref. mic level for virtual mic\n    WebRtc_UWord16      gainTableIdx;       // Current position in virtual gain table\n    WebRtc_Word32       micGainIdx;         // Gain index of mic level to increase slowly\n    WebRtc_Word32       micVol;             // Remember volume between frames\n    WebRtc_Word32       maxLevel;           // Max possible vol level, incl dig gain\n    WebRtc_Word32       maxAnalog;          // Maximum possible analog volume level\n    WebRtc_Word32       maxInit;            // Initial value of \"max\"\n    WebRtc_Word32       minLevel;           // Minimum possible volume level\n    WebRtc_Word32       minOutput;          // Minimum output volume level\n    WebRtc_Word32       zeroCtrlMax;        // Remember max gain => don't amp low input\n\n    WebRtc_Word16       scale;              // Scale factor for internal volume levels\n#ifdef MIC_LEVEL_FEEDBACK\n    WebRtc_Word16       numBlocksMicLvlSat;\n    WebRtc_UWord8 micLvlSat;\n#endif\n    // Structs for VAD and digital_agc\n    AgcVad_t            vadMic;\n    DigitalAgc_t        digitalAgc;\n\n#ifdef AGC_DEBUG\n    FILE*               fpt;\n    FILE*               agcLog;\n    WebRtc_Word32       fcount;\n#endif\n\n    WebRtc_Word16       lowLevelSignal;\n} Agc_t;\n\n#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_ANALOG_AGC_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/agc/main/source/digital_agc.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/* digital_agc.c\n *\n */\n\n#include <string.h>\n#ifdef AGC_DEBUG\n#include <stdio.h>\n#endif\n#include \"digital_agc.h\"\n#include \"gain_control.h\"\n\n// To generate the gaintable, copy&paste the following lines to a Matlab window:\n// MaxGain = 6; MinGain = 0; CompRatio = 3; Knee = 1;\n// zeros = 0:31; lvl = 2.^(1-zeros);\n// A = -10*log10(lvl) * (CompRatio - 1) / CompRatio;\n// B = MaxGain - MinGain;\n// gains = round(2^16*10.^(0.05 * (MinGain + B * ( log(exp(-Knee*A)+exp(-Knee*B)) - log(1+exp(-Knee*B)) ) / log(1/(1+exp(Knee*B))))));\n// fprintf(1, '\\t%i, %i, %i, %i,\\n', gains);\n// % Matlab code for plotting the gain and input/output level characteristic (copy/paste the following 3 lines):\n// in = 10*log10(lvl); out = 20*log10(gains/65536);\n// subplot(121); plot(in, out); axis([-30, 0, -5, 20]); grid on; xlabel('Input (dB)'); ylabel('Gain (dB)');\n// subplot(122); plot(in, in+out); axis([-30, 0, -30, 5]); grid on; xlabel('Input (dB)'); ylabel('Output (dB)');\n// zoom on;\n\n// Generator table for y=log2(1+e^x) in Q8.\nstatic const WebRtc_UWord16 kGenFuncTable[128] = {\n          256,   485,   786,  1126,  1484,  1849,  2217,  2586,\n         2955,  3324,  3693,  4063,  4432,  4801,  5171,  5540,\n         5909,  6279,  6648,  7017,  7387,  7756,  8125,  8495,\n         8864,  9233,  9603,  9972, 10341, 10711, 11080, 11449,\n        11819, 12188, 12557, 12927, 13296, 13665, 14035, 14404,\n        14773, 15143, 15512, 15881, 16251, 16620, 16989, 17359,\n        17728, 18097, 18466, 18836, 19205, 19574, 19944, 20313,\n        20682, 21052, 21421, 21790, 22160, 22529, 22898, 23268,\n        23637, 24006, 24376, 24745, 25114, 25484, 25853, 26222,\n        26592, 26961, 27330, 27700, 28069, 28438, 28808, 29177,\n        29546, 29916, 30285, 30654, 31024, 31393, 31762, 32132,\n        32501, 32870, 33240, 33609, 33978, 34348, 34717, 35086,\n        35456, 35825, 36194, 36564, 36933, 37302, 37672, 38041,\n        38410, 38780, 39149, 39518, 39888, 40257, 40626, 40996,\n        41365, 41734, 42104, 42473, 42842, 43212, 43581, 43950,\n        44320, 44689, 45058, 45428, 45797, 46166, 46536, 46905\n};\n\nstatic const WebRtc_Word16 kAvgDecayTime = 250; // frames; < 3000\n\nWebRtc_Word32 WebRtcAgc_CalculateGainTable(WebRtc_Word32 *gainTable, // Q16\n                                           WebRtc_Word16 digCompGaindB, // Q0\n                                           WebRtc_Word16 targetLevelDbfs,// Q0\n                                           WebRtc_UWord8 limiterEnable,\n                                           WebRtc_Word16 analogTarget) // Q0\n{\n    // This function generates the compressor gain table used in the fixed digital part.\n    WebRtc_UWord32 tmpU32no1, tmpU32no2, absInLevel, logApprox;\n    WebRtc_Word32 inLevel, limiterLvl;\n    WebRtc_Word32 tmp32, tmp32no1, tmp32no2, numFIX, den, y32;\n    const WebRtc_UWord16 kLog10 = 54426; // log2(10)     in Q14\n    const WebRtc_UWord16 kLog10_2 = 49321; // 10*log10(2)  in Q14\n    const WebRtc_UWord16 kLogE_1 = 23637; // log2(e)      in Q14\n    WebRtc_UWord16 constMaxGain;\n    WebRtc_UWord16 tmpU16, intPart, fracPart;\n    const WebRtc_Word16 kCompRatio = 3;\n    const WebRtc_Word16 kSoftLimiterLeft = 1;\n    WebRtc_Word16 limiterOffset = 0; // Limiter offset\n    WebRtc_Word16 limiterIdx, limiterLvlX;\n    WebRtc_Word16 constLinApprox, zeroGainLvl, maxGain, diffGain;\n    WebRtc_Word16 i, tmp16, tmp16no1;\n    int zeros, zerosScale;\n\n    // Constants\n//    kLogE_1 = 23637; // log2(e)      in Q14\n//    kLog10 = 54426; // log2(10)     in Q14\n//    kLog10_2 = 49321; // 10*log10(2)  in Q14\n\n    // Calculate maximum digital gain and zero gain level\n    tmp32no1 = WEBRTC_SPL_MUL_16_16(digCompGaindB - analogTarget, kCompRatio - 1);\n    tmp16no1 = analogTarget - targetLevelDbfs;\n    tmp16no1 += WebRtcSpl_DivW32W16ResW16(tmp32no1 + (kCompRatio >> 1), kCompRatio);\n    maxGain = WEBRTC_SPL_MAX(tmp16no1, (analogTarget - targetLevelDbfs));\n    tmp32no1 = WEBRTC_SPL_MUL_16_16(maxGain, kCompRatio);\n    zeroGainLvl = digCompGaindB;\n    zeroGainLvl -= WebRtcSpl_DivW32W16ResW16(tmp32no1 + ((kCompRatio - 1) >> 1),\n                                             kCompRatio - 1);\n    if ((digCompGaindB <= analogTarget) && (limiterEnable))\n    {\n        zeroGainLvl += (analogTarget - digCompGaindB + kSoftLimiterLeft);\n        limiterOffset = 0;\n    }\n\n    // Calculate the difference between maximum gain and gain at 0dB0v:\n    //  diffGain = maxGain + (compRatio-1)*zeroGainLvl/compRatio\n    //           = (compRatio-1)*digCompGaindB/compRatio\n    tmp32no1 = WEBRTC_SPL_MUL_16_16(digCompGaindB, kCompRatio - 1);\n    diffGain = WebRtcSpl_DivW32W16ResW16(tmp32no1 + (kCompRatio >> 1), kCompRatio);\n    if (diffGain < 0)\n    {\n        return -1;\n    }\n\n    // Calculate the limiter level and index:\n    //  limiterLvlX = analogTarget - limiterOffset\n    //  limiterLvl  = targetLevelDbfs + limiterOffset/compRatio\n    limiterLvlX = analogTarget - limiterOffset;\n    limiterIdx = 2\n            + WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)limiterLvlX, 13),\n                                        WEBRTC_SPL_RSHIFT_U16(kLog10_2, 1));\n    tmp16no1 = WebRtcSpl_DivW32W16ResW16(limiterOffset + (kCompRatio >> 1), kCompRatio);\n    limiterLvl = targetLevelDbfs + tmp16no1;\n\n    // Calculate (through table lookup):\n    //  constMaxGain = log2(1+2^(log2(e)*diffGain)); (in Q8)\n    constMaxGain = kGenFuncTable[diffGain]; // in Q8\n\n    // Calculate a parameter used to approximate the fractional part of 2^x with a\n    // piecewise linear function in Q14:\n    //  constLinApprox = round(3/2*(4*(3-2*sqrt(2))/(log(2)^2)-0.5)*2^14);\n    constLinApprox = 22817; // in Q14\n\n    // Calculate a denominator used in the exponential part to convert from dB to linear scale:\n    //  den = 20*constMaxGain (in Q8)\n    den = WEBRTC_SPL_MUL_16_U16(20, constMaxGain); // in Q8\n\n    for (i = 0; i < 32; i++)\n    {\n        // Calculate scaled input level (compressor):\n        //  inLevel = fix((-constLog10_2*(compRatio-1)*(1-i)+fix(compRatio/2))/compRatio)\n        tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(kCompRatio - 1, i - 1); // Q0\n        tmp32 = WEBRTC_SPL_MUL_16_U16(tmp16, kLog10_2) + 1; // Q14\n        inLevel = WebRtcSpl_DivW32W16(tmp32, kCompRatio); // Q14\n\n        // Calculate diffGain-inLevel, to map using the genFuncTable\n        inLevel = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)diffGain, 14) - inLevel; // Q14\n\n        // Make calculations on abs(inLevel) and compensate for the sign afterwards.\n        absInLevel = (WebRtc_UWord32)WEBRTC_SPL_ABS_W32(inLevel); // Q14\n\n        // LUT with interpolation\n        intPart = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_U32(absInLevel, 14);\n        fracPart = (WebRtc_UWord16)(absInLevel & 0x00003FFF); // extract the fractional part\n        tmpU16 = kGenFuncTable[intPart + 1] - kGenFuncTable[intPart]; // Q8\n        tmpU32no1 = WEBRTC_SPL_UMUL_16_16(tmpU16, fracPart); // Q22\n        tmpU32no1 += WEBRTC_SPL_LSHIFT_U32((WebRtc_UWord32)kGenFuncTable[intPart], 14); // Q22\n        logApprox = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, 8); // Q14\n        // Compensate for negative exponent using the relation:\n        //  log2(1 + 2^-x) = log2(1 + 2^x) - x\n        if (inLevel < 0)\n        {\n            zeros = WebRtcSpl_NormU32(absInLevel);\n            zerosScale = 0;\n            if (zeros < 15)\n            {\n                // Not enough space for multiplication\n                tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(absInLevel, 15 - zeros); // Q(zeros-1)\n                tmpU32no2 = WEBRTC_SPL_UMUL_32_16(tmpU32no2, kLogE_1); // Q(zeros+13)\n                if (zeros < 9)\n                {\n                    tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, 9 - zeros); // Q(zeros+13)\n                    zerosScale = 9 - zeros;\n                } else\n                {\n                    tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(tmpU32no2, zeros - 9); // Q22\n                }\n            } else\n            {\n                tmpU32no2 = WEBRTC_SPL_UMUL_32_16(absInLevel, kLogE_1); // Q28\n                tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(tmpU32no2, 6); // Q22\n            }\n            logApprox = 0;\n            if (tmpU32no2 < tmpU32no1)\n            {\n                logApprox = WEBRTC_SPL_RSHIFT_U32(tmpU32no1 - tmpU32no2, 8 - zerosScale); //Q14\n            }\n        }\n        numFIX = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_U16(maxGain, constMaxGain), 6); // Q14\n        numFIX -= WEBRTC_SPL_MUL_32_16((WebRtc_Word32)logApprox, diffGain); // Q14\n\n        // Calculate ratio\n        // Shift numFIX as much as possible\n        zeros = WebRtcSpl_NormW32(numFIX);\n        numFIX = WEBRTC_SPL_LSHIFT_W32(numFIX, zeros); // Q(14+zeros)\n\n        // Shift den so we end up in Qy1\n        tmp32no1 = WEBRTC_SPL_SHIFT_W32(den, zeros - 8); // Q(zeros)\n        if (numFIX < 0)\n        {\n            numFIX -= WEBRTC_SPL_RSHIFT_W32(tmp32no1, 1);\n        } else\n        {\n            numFIX += WEBRTC_SPL_RSHIFT_W32(tmp32no1, 1);\n        }\n        y32 = WEBRTC_SPL_DIV(numFIX, tmp32no1); // in Q14\n        if (limiterEnable && (i < limiterIdx))\n        {\n            tmp32 = WEBRTC_SPL_MUL_16_U16(i - 1, kLog10_2); // Q14\n            tmp32 -= WEBRTC_SPL_LSHIFT_W32(limiterLvl, 14); // Q14\n            y32 = WebRtcSpl_DivW32W16(tmp32 + 10, 20);\n        }\n        if (y32 > 39000)\n        {\n            tmp32 = WEBRTC_SPL_MUL(y32 >> 1, kLog10) + 4096; // in Q27\n            tmp32 = WEBRTC_SPL_RSHIFT_W32(tmp32, 13); // in Q14\n        } else\n        {\n            tmp32 = WEBRTC_SPL_MUL(y32, kLog10) + 8192; // in Q28\n            tmp32 = WEBRTC_SPL_RSHIFT_W32(tmp32, 14); // in Q14\n        }\n        tmp32 += WEBRTC_SPL_LSHIFT_W32(16, 14); // in Q14 (Make sure final output is in Q16)\n\n        // Calculate power\n        if (tmp32 > 0)\n        {\n            intPart = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 14);\n            fracPart = (WebRtc_UWord16)(tmp32 & 0x00003FFF); // in Q14\n            if (WEBRTC_SPL_RSHIFT_W32(fracPart, 13))\n            {\n                tmp16 = WEBRTC_SPL_LSHIFT_W16(2, 14) - constLinApprox;\n                tmp32no2 = WEBRTC_SPL_LSHIFT_W32(1, 14) - fracPart;\n                tmp32no2 = WEBRTC_SPL_MUL_32_16(tmp32no2, tmp16);\n                tmp32no2 = WEBRTC_SPL_RSHIFT_W32(tmp32no2, 13);\n                tmp32no2 = WEBRTC_SPL_LSHIFT_W32(1, 14) - tmp32no2;\n            } else\n            {\n                tmp16 = constLinApprox - WEBRTC_SPL_LSHIFT_W16(1, 14);\n                tmp32no2 = WEBRTC_SPL_MUL_32_16(fracPart, tmp16);\n                tmp32no2 = WEBRTC_SPL_RSHIFT_W32(tmp32no2, 13);\n            }\n            fracPart = (WebRtc_UWord16)tmp32no2;\n            gainTable[i] = WEBRTC_SPL_LSHIFT_W32(1, intPart)\n                    + WEBRTC_SPL_SHIFT_W32(fracPart, intPart - 14);\n        } else\n        {\n            gainTable[i] = 0;\n        }\n    }\n\n    return 0;\n}\n\nWebRtc_Word32 WebRtcAgc_InitDigital(DigitalAgc_t *stt, WebRtc_Word16 agcMode)\n{\n\n    if (agcMode == kAgcModeFixedDigital)\n    {\n        // start at minimum to find correct gain faster\n        stt->capacitorSlow = 0;\n    } else\n    {\n        // start out with 0 dB gain\n        stt->capacitorSlow = 134217728; // (WebRtc_Word32)(0.125f * 32768.0f * 32768.0f);\n    }\n    stt->capacitorFast = 0;\n    stt->gain = 65536;\n    stt->gatePrevious = 0;\n    stt->agcMode = agcMode;\n#ifdef AGC_DEBUG\n    stt->frameCounter = 0;\n#endif\n\n    // initialize VADs\n    WebRtcAgc_InitVad(&stt->vadNearend);\n    WebRtcAgc_InitVad(&stt->vadFarend);\n\n    return 0;\n}\n\nWebRtc_Word32 WebRtcAgc_AddFarendToDigital(DigitalAgc_t *stt, const WebRtc_Word16 *in_far,\n                                           WebRtc_Word16 nrSamples)\n{\n    // Check for valid pointer\n    if (&stt->vadFarend == NULL)\n    {\n        return -1;\n    }\n\n    // VAD for far end\n    WebRtcAgc_ProcessVad(&stt->vadFarend, in_far, nrSamples);\n\n    return 0;\n}\n\nWebRtc_Word32 WebRtcAgc_ProcessDigital(DigitalAgc_t *stt, const WebRtc_Word16 *in_near,\n                                       const WebRtc_Word16 *in_near_H, WebRtc_Word16 *out,\n                                       WebRtc_Word16 *out_H, WebRtc_UWord32 FS,\n                                       WebRtc_Word16 lowlevelSignal)\n{\n    // array for gains (one value per ms, incl start & end)\n    WebRtc_Word32 gains[11];\n\n    WebRtc_Word32 out_tmp, tmp32;\n    WebRtc_Word32 env[10];\n    WebRtc_Word32 nrg, max_nrg;\n    WebRtc_Word32 cur_level;\n    WebRtc_Word32 gain32, delta;\n    WebRtc_Word16 logratio;\n    WebRtc_Word16 lower_thr, upper_thr;\n    WebRtc_Word16 zeros, zeros_fast, frac;\n    WebRtc_Word16 decay;\n    WebRtc_Word16 gate, gain_adj;\n    WebRtc_Word16 k, n;\n    WebRtc_Word16 L, L2; // samples/subframe\n\n    // determine number of samples per ms\n    if (FS == 8000)\n    {\n        L = 8;\n        L2 = 3;\n    } else if (FS == 16000)\n    {\n        L = 16;\n        L2 = 4;\n    } else if (FS == 32000)\n    {\n        L = 16;\n        L2 = 4;\n    } else\n    {\n        return -1;\n    }\n\n    // TODO(andrew): again, we don't need input and output pointers...\n    if (in_near != out)\n    {\n        // Only needed if they don't already point to the same place.\n        memcpy(out, in_near, 10 * L * sizeof(WebRtc_Word16));\n    }\n    if (FS == 32000)\n    {\n        if (in_near_H != out_H)\n        {\n            memcpy(out_H, in_near_H, 10 * L * sizeof(WebRtc_Word16));\n        }\n    }\n    // VAD for near end\n    logratio = WebRtcAgc_ProcessVad(&stt->vadNearend, out, L * 10);\n\n    // Account for far end VAD\n    if (stt->vadFarend.counter > 10)\n    {\n        tmp32 = WEBRTC_SPL_MUL_16_16(3, logratio);\n        logratio = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32 - stt->vadFarend.logRatio, 2);\n    }\n\n    // Determine decay factor depending on VAD\n    //  upper_thr = 1.0f;\n    //  lower_thr = 0.25f;\n    upper_thr = 1024; // Q10\n    lower_thr = 0; // Q10\n    if (logratio > upper_thr)\n    {\n        // decay = -2^17 / DecayTime;  ->  -65\n        decay = -65;\n    } else if (logratio < lower_thr)\n    {\n        decay = 0;\n    } else\n    {\n        // decay = (WebRtc_Word16)(((lower_thr - logratio)\n        //       * (2^27/(DecayTime*(upper_thr-lower_thr)))) >> 10);\n        // SUBSTITUTED: 2^27/(DecayTime*(upper_thr-lower_thr))  ->  65\n        tmp32 = WEBRTC_SPL_MUL_16_16((lower_thr - logratio), 65);\n        decay = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 10);\n    }\n\n    // adjust decay factor for long silence (detected as low standard deviation)\n    // This is only done in the adaptive modes\n    if (stt->agcMode != kAgcModeFixedDigital)\n    {\n        if (stt->vadNearend.stdLongTerm < 4000)\n        {\n            decay = 0;\n        } else if (stt->vadNearend.stdLongTerm < 8096)\n        {\n            // decay = (WebRtc_Word16)(((stt->vadNearend.stdLongTerm - 4000) * decay) >> 12);\n            tmp32 = WEBRTC_SPL_MUL_16_16((stt->vadNearend.stdLongTerm - 4000), decay);\n            decay = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 12);\n        }\n\n        if (lowlevelSignal != 0)\n        {\n            decay = 0;\n        }\n    }\n#ifdef AGC_DEBUG\n    stt->frameCounter++;\n    fprintf(stt->logFile, \"%5.2f\\t%d\\t%d\\t%d\\t\", (float)(stt->frameCounter) / 100, logratio, decay, stt->vadNearend.stdLongTerm);\n#endif\n    // Find max amplitude per sub frame\n    // iterate over sub frames\n    for (k = 0; k < 10; k++)\n    {\n        // iterate over samples\n        max_nrg = 0;\n        for (n = 0; n < L; n++)\n        {\n            nrg = WEBRTC_SPL_MUL_16_16(out[k * L + n], out[k * L + n]);\n            if (nrg > max_nrg)\n            {\n                max_nrg = nrg;\n            }\n        }\n        env[k] = max_nrg;\n    }\n\n    // Calculate gain per sub frame\n    gains[0] = stt->gain;\n    for (k = 0; k < 10; k++)\n    {\n        // Fast envelope follower\n        //  decay time = -131000 / -1000 = 131 (ms)\n        stt->capacitorFast = AGC_SCALEDIFF32(-1000, stt->capacitorFast, stt->capacitorFast);\n        if (env[k] > stt->capacitorFast)\n        {\n            stt->capacitorFast = env[k];\n        }\n        // Slow envelope follower\n        if (env[k] > stt->capacitorSlow)\n        {\n            // increase capacitorSlow\n            stt->capacitorSlow\n                    = AGC_SCALEDIFF32(500, (env[k] - stt->capacitorSlow), stt->capacitorSlow);\n        } else\n        {\n            // decrease capacitorSlow\n            stt->capacitorSlow\n                    = AGC_SCALEDIFF32(decay, stt->capacitorSlow, stt->capacitorSlow);\n        }\n\n        // use maximum of both capacitors as current level\n        if (stt->capacitorFast > stt->capacitorSlow)\n        {\n            cur_level = stt->capacitorFast;\n        } else\n        {\n            cur_level = stt->capacitorSlow;\n        }\n        // Translate signal level into gain, using a piecewise linear approximation\n        // find number of leading zeros\n        zeros = WebRtcSpl_NormU32((WebRtc_UWord32)cur_level);\n        if (cur_level == 0)\n        {\n            zeros = 31;\n        }\n        tmp32 = (WEBRTC_SPL_LSHIFT_W32(cur_level, zeros) & 0x7FFFFFFF);\n        frac = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 19); // Q12\n        tmp32 = WEBRTC_SPL_MUL((stt->gainTable[zeros-1] - stt->gainTable[zeros]), frac);\n        gains[k + 1] = stt->gainTable[zeros] + WEBRTC_SPL_RSHIFT_W32(tmp32, 12);\n#ifdef AGC_DEBUG\n        if (k == 0)\n        {\n            fprintf(stt->logFile, \"%d\\t%d\\t%d\\t%d\\t%d\\n\", env[0], cur_level, stt->capacitorFast, stt->capacitorSlow, zeros);\n        }\n#endif\n    }\n\n    // Gate processing (lower gain during absence of speech)\n    zeros = WEBRTC_SPL_LSHIFT_W16(zeros, 9) - WEBRTC_SPL_RSHIFT_W16(frac, 3);\n    // find number of leading zeros\n    zeros_fast = WebRtcSpl_NormU32((WebRtc_UWord32)stt->capacitorFast);\n    if (stt->capacitorFast == 0)\n    {\n        zeros_fast = 31;\n    }\n    tmp32 = (WEBRTC_SPL_LSHIFT_W32(stt->capacitorFast, zeros_fast) & 0x7FFFFFFF);\n    zeros_fast = WEBRTC_SPL_LSHIFT_W16(zeros_fast, 9);\n    zeros_fast -= (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 22);\n\n    gate = 1000 + zeros_fast - zeros - stt->vadNearend.stdShortTerm;\n\n    if (gate < 0)\n    {\n        stt->gatePrevious = 0;\n    } else\n    {\n        tmp32 = WEBRTC_SPL_MUL_16_16(stt->gatePrevious, 7);\n        gate = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)gate + tmp32, 3);\n        stt->gatePrevious = gate;\n    }\n    // gate < 0     -> no gate\n    // gate > 2500  -> max gate\n    if (gate > 0)\n    {\n        if (gate < 2500)\n        {\n            gain_adj = WEBRTC_SPL_RSHIFT_W16(2500 - gate, 5);\n        } else\n        {\n            gain_adj = 0;\n        }\n        for (k = 0; k < 10; k++)\n        {\n            if ((gains[k + 1] - stt->gainTable[0]) > 8388608)\n            {\n                // To prevent wraparound\n                tmp32 = WEBRTC_SPL_RSHIFT_W32((gains[k+1] - stt->gainTable[0]), 8);\n                tmp32 = WEBRTC_SPL_MUL(tmp32, (178 + gain_adj));\n            } else\n            {\n                tmp32 = WEBRTC_SPL_MUL((gains[k+1] - stt->gainTable[0]), (178 + gain_adj));\n                tmp32 = WEBRTC_SPL_RSHIFT_W32(tmp32, 8);\n            }\n            gains[k + 1] = stt->gainTable[0] + tmp32;\n        }\n    }\n\n    // Limit gain to avoid overload distortion\n    for (k = 0; k < 10; k++)\n    {\n        // To prevent wrap around\n        zeros = 10;\n        if (gains[k + 1] > 47453132)\n        {\n            zeros = 16 - WebRtcSpl_NormW32(gains[k + 1]);\n        }\n        gain32 = WEBRTC_SPL_RSHIFT_W32(gains[k+1], zeros) + 1;\n        gain32 = WEBRTC_SPL_MUL(gain32, gain32);\n        // check for overflow\n        while (AGC_MUL32(WEBRTC_SPL_RSHIFT_W32(env[k], 12) + 1, gain32)\n                > WEBRTC_SPL_SHIFT_W32((WebRtc_Word32)32767, 2 * (1 - zeros + 10)))\n        {\n            // multiply by 253/256 ==> -0.1 dB\n            if (gains[k + 1] > 8388607)\n            {\n                // Prevent wrap around\n                gains[k + 1] = WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(gains[k+1], 8), 253);\n            } else\n            {\n                gains[k + 1] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(gains[k+1], 253), 8);\n            }\n            gain32 = WEBRTC_SPL_RSHIFT_W32(gains[k+1], zeros) + 1;\n            gain32 = WEBRTC_SPL_MUL(gain32, gain32);\n        }\n    }\n    // gain reductions should be done 1 ms earlier than gain increases\n    for (k = 1; k < 10; k++)\n    {\n        if (gains[k] > gains[k + 1])\n        {\n            gains[k] = gains[k + 1];\n        }\n    }\n    // save start gain for next frame\n    stt->gain = gains[10];\n\n    // Apply gain\n    // handle first sub frame separately\n    delta = WEBRTC_SPL_LSHIFT_W32(gains[1] - gains[0], (4 - L2));\n    gain32 = WEBRTC_SPL_LSHIFT_W32(gains[0], 4);\n    // iterate over samples\n    for (n = 0; n < L; n++)\n    {\n        // For lower band\n        tmp32 = WEBRTC_SPL_MUL((WebRtc_Word32)out[n], WEBRTC_SPL_RSHIFT_W32(gain32 + 127, 7));\n        out_tmp = WEBRTC_SPL_RSHIFT_W32(tmp32 , 16);\n        if (out_tmp > 4095)\n        {\n            out[n] = (WebRtc_Word16)32767;\n        } else if (out_tmp < -4096)\n        {\n            out[n] = (WebRtc_Word16)-32768;\n        } else\n        {\n            tmp32 = WEBRTC_SPL_MUL((WebRtc_Word32)out[n], WEBRTC_SPL_RSHIFT_W32(gain32, 4));\n            out[n] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32 , 16);\n        }\n        // For higher band\n        if (FS == 32000)\n        {\n            tmp32 = WEBRTC_SPL_MUL((WebRtc_Word32)out_H[n],\n                                   WEBRTC_SPL_RSHIFT_W32(gain32 + 127, 7));\n            out_tmp = WEBRTC_SPL_RSHIFT_W32(tmp32 , 16);\n            if (out_tmp > 4095)\n            {\n                out_H[n] = (WebRtc_Word16)32767;\n            } else if (out_tmp < -4096)\n            {\n                out_H[n] = (WebRtc_Word16)-32768;\n            } else\n            {\n                tmp32 = WEBRTC_SPL_MUL((WebRtc_Word32)out_H[n],\n                                       WEBRTC_SPL_RSHIFT_W32(gain32, 4));\n                out_H[n] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32 , 16);\n            }\n        }\n        //\n\n        gain32 += delta;\n    }\n    // iterate over subframes\n    for (k = 1; k < 10; k++)\n    {\n        delta = WEBRTC_SPL_LSHIFT_W32(gains[k+1] - gains[k], (4 - L2));\n        gain32 = WEBRTC_SPL_LSHIFT_W32(gains[k], 4);\n        // iterate over samples\n        for (n = 0; n < L; n++)\n        {\n            // For lower band\n            tmp32 = WEBRTC_SPL_MUL((WebRtc_Word32)out[k * L + n],\n                                   WEBRTC_SPL_RSHIFT_W32(gain32, 4));\n            out[k * L + n] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32 , 16);\n            // For higher band\n            if (FS == 32000)\n            {\n                tmp32 = WEBRTC_SPL_MUL((WebRtc_Word32)out_H[k * L + n],\n                                       WEBRTC_SPL_RSHIFT_W32(gain32, 4));\n                out_H[k * L + n] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32 , 16);\n            }\n            gain32 += delta;\n        }\n    }\n\n    return 0;\n}\n\nvoid WebRtcAgc_InitVad(AgcVad_t *state)\n{\n    WebRtc_Word16 k;\n\n    state->HPstate = 0; // state of high pass filter\n    state->logRatio = 0; // log( P(active) / P(inactive) )\n    // average input level (Q10)\n    state->meanLongTerm = WEBRTC_SPL_LSHIFT_W16(15, 10);\n\n    // variance of input level (Q8)\n    state->varianceLongTerm = WEBRTC_SPL_LSHIFT_W32(500, 8);\n\n    state->stdLongTerm = 0; // standard deviation of input level in dB\n    // short-term average input level (Q10)\n    state->meanShortTerm = WEBRTC_SPL_LSHIFT_W16(15, 10);\n\n    // short-term variance of input level (Q8)\n    state->varianceShortTerm = WEBRTC_SPL_LSHIFT_W32(500, 8);\n\n    state->stdShortTerm = 0; // short-term standard deviation of input level in dB\n    state->counter = 3; // counts updates\n    for (k = 0; k < 8; k++)\n    {\n        // downsampling filter\n        state->downState[k] = 0;\n    }\n}\n\nWebRtc_Word16 WebRtcAgc_ProcessVad(AgcVad_t *state, // (i) VAD state\n                                   const WebRtc_Word16 *in, // (i) Speech signal\n                                   WebRtc_Word16 nrSamples) // (i) number of samples\n{\n    WebRtc_Word32 out, nrg, tmp32, tmp32b;\n    WebRtc_UWord16 tmpU16;\n    WebRtc_Word16 k, subfr, tmp16;\n    WebRtc_Word16 buf1[8];\n    WebRtc_Word16 buf2[4];\n    WebRtc_Word16 HPstate;\n    WebRtc_Word16 zeros, dB;\n\n    // process in 10 sub frames of 1 ms (to save on memory)\n    nrg = 0;\n    HPstate = state->HPstate;\n    for (subfr = 0; subfr < 10; subfr++)\n    {\n        // downsample to 4 kHz\n        if (nrSamples == 160)\n        {\n            for (k = 0; k < 8; k++)\n            {\n                tmp32 = (WebRtc_Word32)in[2 * k] + (WebRtc_Word32)in[2 * k + 1];\n                tmp32 = WEBRTC_SPL_RSHIFT_W32(tmp32, 1);\n                buf1[k] = (WebRtc_Word16)tmp32;\n            }\n            in += 16;\n\n            WebRtcSpl_DownsampleBy2(buf1, 8, buf2, state->downState);\n        } else\n        {\n            WebRtcSpl_DownsampleBy2(in, 8, buf2, state->downState);\n            in += 8;\n        }\n\n        // high pass filter and compute energy\n        for (k = 0; k < 4; k++)\n        {\n            out = buf2[k] + HPstate;\n            tmp32 = WEBRTC_SPL_MUL(600, out);\n            HPstate = (WebRtc_Word16)(WEBRTC_SPL_RSHIFT_W32(tmp32, 10) - buf2[k]);\n            tmp32 = WEBRTC_SPL_MUL(out, out);\n            nrg += WEBRTC_SPL_RSHIFT_W32(tmp32, 6);\n        }\n    }\n    state->HPstate = HPstate;\n\n    // find number of leading zeros\n    if (!(0xFFFF0000 & nrg))\n    {\n        zeros = 16;\n    } else\n    {\n        zeros = 0;\n    }\n    if (!(0xFF000000 & (nrg << zeros)))\n    {\n        zeros += 8;\n    }\n    if (!(0xF0000000 & (nrg << zeros)))\n    {\n        zeros += 4;\n    }\n    if (!(0xC0000000 & (nrg << zeros)))\n    {\n        zeros += 2;\n    }\n    if (!(0x80000000 & (nrg << zeros)))\n    {\n        zeros += 1;\n    }\n\n    // energy level (range {-32..30}) (Q10)\n    dB = WEBRTC_SPL_LSHIFT_W16(15 - zeros, 11);\n\n    // Update statistics\n\n    if (state->counter < kAvgDecayTime)\n    {\n        // decay time = AvgDecTime * 10 ms\n        state->counter++;\n    }\n\n    // update short-term estimate of mean energy level (Q10)\n    tmp32 = (WEBRTC_SPL_MUL_16_16(state->meanShortTerm, 15) + (WebRtc_Word32)dB);\n    state->meanShortTerm = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 4);\n\n    // update short-term estimate of variance in energy level (Q8)\n    tmp32 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(dB, dB), 12);\n    tmp32 += WEBRTC_SPL_MUL(state->varianceShortTerm, 15);\n    state->varianceShortTerm = WEBRTC_SPL_RSHIFT_W32(tmp32, 4);\n\n    // update short-term estimate of standard deviation in energy level (Q10)\n    tmp32 = WEBRTC_SPL_MUL_16_16(state->meanShortTerm, state->meanShortTerm);\n    tmp32 = WEBRTC_SPL_LSHIFT_W32(state->varianceShortTerm, 12) - tmp32;\n    state->stdShortTerm = (WebRtc_Word16)WebRtcSpl_Sqrt(tmp32);\n\n    // update long-term estimate of mean energy level (Q10)\n    tmp32 = WEBRTC_SPL_MUL_16_16(state->meanLongTerm, state->counter) + (WebRtc_Word32)dB;\n    state->meanLongTerm = WebRtcSpl_DivW32W16ResW16(tmp32,\n                                                    WEBRTC_SPL_ADD_SAT_W16(state->counter, 1));\n\n    // update long-term estimate of variance in energy level (Q8)\n    tmp32 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(dB, dB), 12);\n    tmp32 += WEBRTC_SPL_MUL(state->varianceLongTerm, state->counter);\n    state->varianceLongTerm = WebRtcSpl_DivW32W16(tmp32,\n                                                  WEBRTC_SPL_ADD_SAT_W16(state->counter, 1));\n\n    // update long-term estimate of standard deviation in energy level (Q10)\n    tmp32 = WEBRTC_SPL_MUL_16_16(state->meanLongTerm, state->meanLongTerm);\n    tmp32 = WEBRTC_SPL_LSHIFT_W32(state->varianceLongTerm, 12) - tmp32;\n    state->stdLongTerm = (WebRtc_Word16)WebRtcSpl_Sqrt(tmp32);\n\n    // update voice activity measure (Q10)\n    tmp16 = WEBRTC_SPL_LSHIFT_W16(3, 12);\n    tmp32 = WEBRTC_SPL_MUL_16_16(tmp16, (dB - state->meanLongTerm));\n    tmp32 = WebRtcSpl_DivW32W16(tmp32, state->stdLongTerm);\n    tmpU16 = WEBRTC_SPL_LSHIFT_U16((WebRtc_UWord16)13, 12);\n    tmp32b = WEBRTC_SPL_MUL_16_U16(state->logRatio, tmpU16);\n    tmp32 += WEBRTC_SPL_RSHIFT_W32(tmp32b, 10);\n\n    state->logRatio = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 6);\n\n    // limit\n    if (state->logRatio > 2048)\n    {\n        state->logRatio = 2048;\n    }\n    if (state->logRatio < -2048)\n    {\n        state->logRatio = -2048;\n    }\n\n    return state->logRatio; // Q10\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/agc/main/source/digital_agc.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_DIGITAL_AGC_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_DIGITAL_AGC_H_\n\n#ifdef AGC_DEBUG\n#include <stdio.h>\n#endif\n#include \"typedefs.h\"\n#include \"signal_processing_library.h\"\n\n// the 32 most significant bits of A(19) * B(26) >> 13\n#define AGC_MUL32(A, B)             (((B)>>13)*(A) + ( ((0x00001FFF & (B))*(A)) >> 13 ))\n// C + the 32 most significant bits of A * B\n#define AGC_SCALEDIFF32(A, B, C)    ((C) + ((B)>>16)*(A) + ( ((0x0000FFFF & (B))*(A)) >> 16 ))\n\ntypedef struct\n{\n    WebRtc_Word32 downState[8];\n    WebRtc_Word16 HPstate;\n    WebRtc_Word16 counter;\n    WebRtc_Word16 logRatio; // log( P(active) / P(inactive) ) (Q10)\n    WebRtc_Word16 meanLongTerm; // Q10\n    WebRtc_Word32 varianceLongTerm; // Q8\n    WebRtc_Word16 stdLongTerm; // Q10\n    WebRtc_Word16 meanShortTerm; // Q10\n    WebRtc_Word32 varianceShortTerm; // Q8\n    WebRtc_Word16 stdShortTerm; // Q10\n} AgcVad_t; // total = 54 bytes\n\ntypedef struct\n{\n    WebRtc_Word32 capacitorSlow;\n    WebRtc_Word32 capacitorFast;\n    WebRtc_Word32 gain;\n    WebRtc_Word32 gainTable[32];\n    WebRtc_Word16 gatePrevious;\n    WebRtc_Word16 agcMode;\n    AgcVad_t      vadNearend;\n    AgcVad_t      vadFarend;\n#ifdef AGC_DEBUG\n    FILE*         logFile;\n    int           frameCounter;\n#endif\n} DigitalAgc_t;\n\nWebRtc_Word32 WebRtcAgc_InitDigital(DigitalAgc_t *digitalAgcInst, WebRtc_Word16 agcMode);\n\nWebRtc_Word32 WebRtcAgc_ProcessDigital(DigitalAgc_t *digitalAgcInst, const WebRtc_Word16 *inNear,\n                             const WebRtc_Word16 *inNear_H, WebRtc_Word16 *out,\n                             WebRtc_Word16 *out_H, WebRtc_UWord32 FS,\n                             WebRtc_Word16 lowLevelSignal);\n\nWebRtc_Word32 WebRtcAgc_AddFarendToDigital(DigitalAgc_t *digitalAgcInst, const WebRtc_Word16 *inFar,\n                                 WebRtc_Word16 nrSamples);\n\nvoid WebRtcAgc_InitVad(AgcVad_t *vadInst);\n\nWebRtc_Word16 WebRtcAgc_ProcessVad(AgcVad_t *vadInst, // (i) VAD state\n                            const WebRtc_Word16 *in, // (i) Speech signal\n                            WebRtc_Word16 nrSamples); // (i) number of samples\n\nWebRtc_Word32 WebRtcAgc_CalculateGainTable(WebRtc_Word32 *gainTable, // Q16\n                                 WebRtc_Word16 compressionGaindB, // Q0 (in dB)\n                                 WebRtc_Word16 targetLevelDbfs,// Q0 (in dB)\n                                 WebRtc_UWord8 limiterEnable, WebRtc_Word16 analogTarget);\n\n#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_ANALOG_AGC_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/ns/main/interface/noise_suppression.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_INTERFACE_NOISE_SUPPRESSION_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_INTERFACE_NOISE_SUPPRESSION_H_\n\n#include \"typedefs.h\"\n\ntypedef struct NsHandleT NsHandle;\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n * This function returns the version number of the code.\n *\n * Input:\n *      - version       : Pointer to a character array where the version\n *                        info is stored.\n *      - length        : Length of version.\n *\n * Return value         :  0 - Ok\n *                        -1 - Error (probably length is not sufficient)\n */\nint WebRtcNs_get_version(char *version, short length);\n\n\n/*\n * This function creates an instance to the noise reduction structure\n *\n * Input:\n *      - NS_inst       : Pointer to noise reduction instance that should be\n *                        created\n *\n * Output:\n *      - NS_inst       : Pointer to created noise reduction instance\n *\n * Return value         :  0 - Ok\n *                        -1 - Error\n */\nint WebRtcNs_Create(NsHandle **NS_inst);\n\n\n/*\n * This function frees the dynamic memory of a specified Noise Reduction\n * instance.\n *\n * Input:\n *      - NS_inst       : Pointer to NS instance that should be freed\n *\n * Return value         :  0 - Ok\n *                        -1 - Error\n */\nint WebRtcNs_Free(NsHandle *NS_inst);\n\n\n/*\n * This function initializes a NS instance\n *\n * Input:\n *      - NS_inst       : Instance that should be initialized\n *      - fs            : sampling frequency\n *\n * Output:\n *      - NS_inst       : Initialized instance\n *\n * Return value         :  0 - Ok\n *                        -1 - Error\n */\nint WebRtcNs_Init(NsHandle *NS_inst, WebRtc_UWord32 fs);\n\n/*\n * This changes the aggressiveness of the noise suppression method.\n *\n * Input:\n *      - NS_inst       : Instance that should be initialized\n *      - mode          : 0: Mild, 1: Medium , 2: Aggressive\n *\n * Output:\n *      - NS_inst       : Initialized instance\n *\n * Return value         :  0 - Ok\n *                        -1 - Error\n */\nint WebRtcNs_set_policy(NsHandle *NS_inst, int mode);\n\n\n/*\n * This functions does Noise Suppression for the inserted speech frame. The\n * input and output signals should always be 10ms (80 or 160 samples).\n *\n * Input\n *      - NS_inst       : NS Instance. Needs to be initiated before call.\n *      - spframe       : Pointer to speech frame buffer for L band\n *      - spframe_H     : Pointer to speech frame buffer for H band\n *      - fs            : sampling frequency\n *\n * Output:\n *      - NS_inst       : Updated NS instance\n *      - outframe      : Pointer to output frame for L band\n *      - outframe_H    : Pointer to output frame for H band\n *\n * Return value         :  0 - OK\n *                        -1 - Error\n */\nint WebRtcNs_Process(NsHandle *NS_inst,\n                     short *spframe,\n                     short *spframe_H,\n                     short *outframe,\n                     short *outframe_H);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_INTERFACE_NOISE_SUPPRESSION_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/ns/main/interface/noise_suppression_x.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_INTERFACE_NOISE_SUPPRESSION_X_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_INTERFACE_NOISE_SUPPRESSION_X_H_\n\n#include \"signal_processing_library.h\"\n\ntypedef struct NsxHandleT NsxHandle;\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n * This function returns the version number of the code.\n *\n * Input:\n *      - version       : Pointer to a character array where the version\n *                        info is stored.\n *      - length        : Length of version.\n *\n * Return value         :  0 - Ok\n *                        -1 - Error (probably length is not sufficient)\n */\nint WebRtcNsx_get_version(char *version, short length);\n\n\n/*\n * This function creates an instance to the noise reduction structure\n *\n * Input:\n *      - nsxInst       : Pointer to noise reduction instance that should be\n *                       created\n *\n * Output:\n *      - nsxInst       : Pointer to created noise reduction instance\n *\n * Return value         :  0 - Ok\n *                        -1 - Error\n */\nint WebRtcNsx_Create(NsxHandle **nsxInst);\n\n\n/*\n * This function frees the dynamic memory of a specified Noise Suppression\n * instance.\n *\n * Input:\n *      - nsxInst       : Pointer to NS instance that should be freed\n *\n * Return value         :  0 - Ok\n *                        -1 - Error\n */\nint WebRtcNsx_Free(NsxHandle *nsxInst);\n\n\n/*\n * This function initializes a NS instance\n *\n * Input:\n *      - nsxInst       : Instance that should be initialized\n *      - fs            : sampling frequency\n *\n * Output:\n *      - nsxInst       : Initialized instance\n *\n * Return value         :  0 - Ok\n *                        -1 - Error\n */\nint WebRtcNsx_Init(NsxHandle *nsxInst, WebRtc_UWord32 fs);\n\n/*\n * This changes the aggressiveness of the noise suppression method.\n *\n * Input:\n *      - nsxInst       : Instance that should be initialized\n *      - mode          : 0: Mild, 1: Medium , 2: Aggressive\n *\n * Output:\n *      - nsxInst       : Initialized instance\n *\n * Return value         :  0 - Ok\n *                        -1 - Error\n */\nint WebRtcNsx_set_policy(NsxHandle *nsxInst, int mode);\n\n/*\n * This functions does noise suppression for the inserted speech frame. The\n * input and output signals should always be 10ms (80 or 160 samples).\n *\n * Input\n *      - nsxInst       : NSx instance. Needs to be initiated before call.\n *      - speechFrame   : Pointer to speech frame buffer for L band\n *      - speechFrameHB : Pointer to speech frame buffer for H band\n *      - fs            : sampling frequency\n *\n * Output:\n *      - nsxInst       : Updated NSx instance\n *      - outFrame      : Pointer to output frame for L band\n *      - outFrameHB    : Pointer to output frame for H band\n *\n * Return value         :  0 - OK\n *                        -1 - Error\n */\nint WebRtcNsx_Process(NsxHandle *nsxInst,\n                      short *speechFrame,\n                      short *speechFrameHB,\n                      short *outFrame,\n                      short *outFrameHB);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_INTERFACE_NOISE_SUPPRESSION_X_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/ns/main/source/defines.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_\n\n//#define PROCESS_FLOW_0    // Use the traditional method.\n//#define PROCESS_FLOW_1    // Use traditional with DD estimate of prior SNR.\n#define PROCESS_FLOW_2    // Use the new method of speech/noise classification.\n\n#define BLOCKL_MAX          160 // max processing block length: 160\n#define ANAL_BLOCKL_MAX     256 // max analysis block length: 256\n#define HALF_ANAL_BLOCKL    129 // half max analysis block length + 1\n\n#define QUANTILE            (float)0.25\n\n#define SIMULT              3\n#define END_STARTUP_LONG    200\n#define END_STARTUP_SHORT   50\n#define FACTOR              (float)40.0\n#define WIDTH               (float)0.01\n\n#define SMOOTH              (float)0.75 // filter smoothing\n// Length of fft work arrays.\n#define IP_LENGTH (ANAL_BLOCKL_MAX >> 1) // must be at least ceil(2 + sqrt(ANAL_BLOCKL_MAX/2))\n#define W_LENGTH (ANAL_BLOCKL_MAX >> 1)\n\n//PARAMETERS FOR NEW METHOD\n#define DD_PR_SNR           (float)0.98 // DD update of prior SNR\n#define LRT_TAVG            (float)0.50 // tavg parameter for LRT (previously 0.90)\n#define SPECT_FL_TAVG       (float)0.30 // tavg parameter for spectral flatness measure\n#define SPECT_DIFF_TAVG     (float)0.30 // tavg parameter for spectral difference measure\n#define PRIOR_UPDATE        (float)0.10 // update parameter of prior model\n#define NOISE_UPDATE        (float)0.90 // update parameter for noise\n#define SPEECH_UPDATE       (float)0.99 // update parameter when likely speech\n#define WIDTH_PR_MAP        (float)4.0  // width parameter in sigmoid map for prior model\n#define LRT_FEATURE_THR     (float)0.5  // default threshold for LRT feature\n#define SF_FEATURE_THR      (float)0.5  // default threshold for Spectral Flatness feature\n#define SD_FEATURE_THR      (float)0.5  // default threshold for Spectral Difference feature\n#define PROB_RANGE          (float)0.20 // probability threshold for noise state in\n                                        // speech/noise likelihood\n#define HIST_PAR_EST         1000       // histogram size for estimation of parameters\n#define GAMMA_PAUSE         (float)0.05 // update for conservative noise estimate\n//\n#define B_LIM               (float)0.5  // threshold in final energy gain factor calculation\n#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/ns/main/source/noise_suppression.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include <stdlib.h>\n#include <string.h>\n\n#include \"noise_suppression.h\"\n#include \"ns_core.h\"\n#include \"defines.h\"\n\nint WebRtcNs_get_version(char *versionStr, short length)\n{\n    const char version[] = \"NS 2.2.0\";\n    const short versionLen = (short)strlen(version) + 1; // +1 for null-termination\n\n    if (versionStr == NULL) {\n        return -1;\n    }\n\n    if (versionLen > length) {\n        return -1;\n    }\n\n    strncpy(versionStr, version, versionLen);\n\n    return 0;\n}\n\nint WebRtcNs_Create(NsHandle **NS_inst)\n{\n    *NS_inst = (NsHandle*) malloc(sizeof(NSinst_t));\n    if (*NS_inst!=NULL) {\n        (*(NSinst_t**)NS_inst)->initFlag=0;\n        return 0;\n    } else {\n        return -1;\n    }\n\n}\n\nint WebRtcNs_Free(NsHandle *NS_inst)\n{\n    free(NS_inst);\n    return 0;\n}\n\n\nint WebRtcNs_Init(NsHandle *NS_inst, WebRtc_UWord32 fs)\n{\n    return WebRtcNs_InitCore((NSinst_t*) NS_inst, fs);\n}\n\nint WebRtcNs_set_policy(NsHandle *NS_inst, int mode)\n{\n    return WebRtcNs_set_policy_core((NSinst_t*) NS_inst, mode);\n}\n\n\nint WebRtcNs_Process(NsHandle *NS_inst, short *spframe, short *spframe_H, short *outframe, short *outframe_H)\n{\n    return WebRtcNs_ProcessCore((NSinst_t*) NS_inst, spframe, spframe_H, outframe, outframe_H);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/ns/main/source/noise_suppression_x.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include <stdlib.h>\n#include <string.h>\n\n#include \"noise_suppression_x.h\"\n#include \"nsx_core.h\"\n#include \"nsx_defines.h\"\n\nint WebRtcNsx_get_version(char *versionStr, short length)\n{\n    const char version[] = \"NS\\t3.1.0\";\n    const short versionLen = (short)strlen(version) + 1; // +1 for null-termination\n\n    if (versionStr == NULL)\n    {\n        return -1;\n    }\n\n    if (versionLen > length)\n    {\n        return -1;\n    }\n\n    strncpy(versionStr, version, versionLen);\n\n    return 0;\n}\n\nint WebRtcNsx_Create(NsxHandle **nsxInst)\n{\n    *nsxInst = (NsxHandle*)malloc(sizeof(NsxInst_t));\n    if (*nsxInst != NULL)\n    {\n        (*(NsxInst_t**)nsxInst)->initFlag = 0;\n        return 0;\n    } else\n    {\n        return -1;\n    }\n\n}\n\nint WebRtcNsx_Free(NsxHandle *nsxInst)\n{\n    free(nsxInst);\n    return 0;\n}\n\nint WebRtcNsx_Init(NsxHandle *nsxInst, WebRtc_UWord32 fs)\n{\n    return WebRtcNsx_InitCore((NsxInst_t*)nsxInst, fs);\n}\n\nint WebRtcNsx_set_policy(NsxHandle *nsxInst, int mode)\n{\n    return WebRtcNsx_set_policy_core((NsxInst_t*)nsxInst, mode);\n}\n\nint WebRtcNsx_Process(NsxHandle *nsxInst, short *speechFrame, short *speechFrameHB,\n                      short *outFrame, short *outFrameHB)\n{\n    return WebRtcNsx_ProcessCore((NsxInst_t*)nsxInst, speechFrame, speechFrameHB, outFrame,\n                              outFrameHB);\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/ns/main/source/ns_core.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include <string.h>\n#include <math.h>\n//#include <stdio.h>\n#include <stdlib.h>\n#include \"noise_suppression.h\"\n#include \"ns_core.h\"\n#include \"windows_private.h\"\n#include \"fft4g.h\"\n#include \"signal_processing_library.h\"\n\n// Set Feature Extraction Parameters\nvoid WebRtcNs_set_feature_extraction_parameters(NSinst_t *inst)\n{\n    //bin size of histogram\n    inst->featureExtractionParams.binSizeLrt      = (float)0.1;\n    inst->featureExtractionParams.binSizeSpecFlat = (float)0.05;\n    inst->featureExtractionParams.binSizeSpecDiff = (float)0.1;\n\n    //range of histogram over which lrt threshold is computed\n    inst->featureExtractionParams.rangeAvgHistLrt = (float)1.0;\n\n    //scale parameters: multiply dominant peaks of the histograms by scale factor to obtain\n    // thresholds for prior model\n    inst->featureExtractionParams.factor1ModelPars = (float)1.20; //for lrt and spectral diff\n    inst->featureExtractionParams.factor2ModelPars = (float)0.9;  //for spectral_flatness:\n                                                     // used when noise is flatter than speech\n\n    //peak limit for spectral flatness (varies between 0 and 1)\n    inst->featureExtractionParams.thresPosSpecFlat = (float)0.6;\n\n    //limit on spacing of two highest peaks in histogram: spacing determined by bin size\n    inst->featureExtractionParams.limitPeakSpacingSpecFlat = 2\n            * inst->featureExtractionParams.binSizeSpecFlat;\n    inst->featureExtractionParams.limitPeakSpacingSpecDiff = 2\n            * inst->featureExtractionParams.binSizeSpecDiff;\n\n    //limit on relevance of second peak:\n    inst->featureExtractionParams.limitPeakWeightsSpecFlat = (float)0.5;\n    inst->featureExtractionParams.limitPeakWeightsSpecDiff = (float)0.5;\n\n    // fluctuation limit of lrt feature\n    inst->featureExtractionParams.thresFluctLrt = (float)0.05;\n\n    //limit on the max and min values for the feature thresholds\n    inst->featureExtractionParams.maxLrt = (float)1.0;\n    inst->featureExtractionParams.minLrt = (float)0.20;\n\n    inst->featureExtractionParams.maxSpecFlat = (float)0.95;\n    inst->featureExtractionParams.minSpecFlat = (float)0.10;\n\n    inst->featureExtractionParams.maxSpecDiff = (float)1.0;\n    inst->featureExtractionParams.minSpecDiff = (float)0.16;\n\n    //criteria of weight of histogram peak  to accept/reject feature\n    inst->featureExtractionParams.thresWeightSpecFlat = (int)(0.3\n            * (inst->modelUpdatePars[1])); //for spectral flatness\n    inst->featureExtractionParams.thresWeightSpecDiff = (int)(0.3\n            * (inst->modelUpdatePars[1])); //for spectral difference\n}\n\n// Initialize state\nint WebRtcNs_InitCore(NSinst_t *inst, WebRtc_UWord32 fs)\n{\n    int i;\n    //We only support 10ms frames\n\n    //check for valid pointer\n    if (inst == NULL)\n    {\n        return -1;\n    }\n\n    // Initialization of struct\n    if (fs == 8000 || fs == 16000 || fs == 32000)\n    {\n        inst->fs = fs;\n    }\n    else\n    {\n        return -1;\n    }\n    inst->windShift = 0;\n    if (fs == 8000)\n    {\n        // We only support 10ms frames\n        inst->blockLen = 80;\n        inst->blockLen10ms = 80;\n        inst->anaLen = 128;\n        inst->window = kBlocks80w128;\n        inst->outLen = 0;\n    }\n    else if (fs == 16000)\n    {\n        // We only support 10ms frames\n        inst->blockLen = 160;\n        inst->blockLen10ms = 160;\n        inst->anaLen = 256;\n        inst->window = kBlocks160w256;\n        inst->outLen = 0;\n    }\n    else if (fs==32000)\n    {\n        // We only support 10ms frames\n        inst->blockLen = 160;\n        inst->blockLen10ms = 160;\n        inst->anaLen = 256;\n        inst->window = kBlocks160w256;\n        inst->outLen = 0;\n    }\n    inst->magnLen = inst->anaLen / 2 + 1; // Number of frequency bins\n\n    // Initialize fft work arrays.\n    inst->ip[0] = 0; // Setting this triggers initialization.\n    memset(inst->dataBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);\n    rdft(inst->anaLen, 1, inst->dataBuf, inst->ip, inst->wfft);\n\n    memset(inst->dataBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);\n    memset(inst->syntBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);\n\n    //for HB processing\n    memset(inst->dataBufHB, 0, sizeof(float) * ANAL_BLOCKL_MAX);\n\n    //for quantile noise estimation\n    memset(inst->quantile, 0, sizeof(float) * HALF_ANAL_BLOCKL);\n    for (i = 0; i < SIMULT * HALF_ANAL_BLOCKL; i++)\n    {\n        inst->lquantile[i] = (float)8.0;\n        inst->density[i] = (float)0.3;\n    }\n\n    for (i = 0; i < SIMULT; i++)\n    {\n        inst->counter[i] = (int)floor((float)(END_STARTUP_LONG * (i + 1)) / (float)SIMULT);\n    }\n\n    inst->updates = 0;\n\n    // Wiener filter initialization\n    for (i = 0; i < HALF_ANAL_BLOCKL; i++)\n    {\n        inst->smooth[i] = (float)1.0;\n    }\n\n    // Set the aggressiveness: default\n    inst->aggrMode = 0;\n\n    //initialize variables for new method\n    inst->priorSpeechProb = (float)0.5; //prior prob for speech/noise\n    for (i = 0; i < HALF_ANAL_BLOCKL; i++)\n    {\n        inst->magnPrev[i]      = (float)0.0; //previous mag spectrum\n        inst->noisePrev[i]     = (float)0.0; //previous noise-spectrum\n        inst->logLrtTimeAvg[i] = LRT_FEATURE_THR; //smooth LR ratio (same as threshold)\n        inst->magnAvgPause[i]  = (float)0.0; //conservative noise spectrum estimate\n        inst->speechProbHB[i]  = (float)0.0; //for estimation of HB in second pass\n        inst->initMagnEst[i]   = (float)0.0; //initial average mag spectrum\n    }\n\n    //feature quantities\n    inst->featureData[0] = SF_FEATURE_THR;  //spectral flatness (start on threshold)\n    inst->featureData[1] = (float)0.0;      //spectral entropy: not used in this version\n    inst->featureData[2] = (float)0.0;      //spectral variance: not used in this version\n    inst->featureData[3] = LRT_FEATURE_THR; //average lrt factor (start on threshold)\n    inst->featureData[4] = SF_FEATURE_THR;  //spectral template diff (start on threshold)\n    inst->featureData[5] = (float)0.0;      //normalization for spectral-diff\n    inst->featureData[6] = (float)0.0;      //window time-average of input magnitude spectrum\n\n    //histogram quantities: used to estimate/update thresholds for features\n    for (i = 0; i < HIST_PAR_EST; i++)\n    {\n        inst->histLrt[i] = 0;\n        inst->histSpecFlat[i] = 0;\n        inst->histSpecDiff[i] = 0;\n    }\n\n    inst->blockInd = -1; //frame counter\n    inst->priorModelPars[0] = LRT_FEATURE_THR; //default threshold for lrt feature\n    inst->priorModelPars[1] = (float)0.5;      //threshold for spectral flatness:\n                                               // determined on-line\n    inst->priorModelPars[2] = (float)1.0;      //sgn_map par for spectral measure:\n                                               // 1 for flatness measure\n    inst->priorModelPars[3] = (float)0.5;      //threshold for template-difference feature:\n                                               // determined on-line\n    inst->priorModelPars[4] = (float)1.0;      //default weighting parameter for lrt feature\n    inst->priorModelPars[5] = (float)0.0;      //default weighting parameter for\n                                               // spectral flatness feature\n    inst->priorModelPars[6] = (float)0.0;      //default weighting parameter for\n                                               // spectral difference feature\n\n    inst->modelUpdatePars[0] = 2;   //update flag for parameters:\n                                    // 0 no update, 1=update once, 2=update every window\n    inst->modelUpdatePars[1] = 500; //window for update\n    inst->modelUpdatePars[2] = 0;   //counter for update of conservative noise spectrum\n    //counter if the feature thresholds are updated during the sequence\n    inst->modelUpdatePars[3] = inst->modelUpdatePars[1];\n\n    inst->signalEnergy = 0.0;\n    inst->sumMagn = 0.0;\n    inst->whiteNoiseLevel = 0.0;\n    inst->pinkNoiseNumerator = 0.0;\n    inst->pinkNoiseExp = 0.0;\n\n    WebRtcNs_set_feature_extraction_parameters(inst); // Set feature configuration\n\n    //default mode\n    WebRtcNs_set_policy_core(inst, 0);\n\n\n    memset(inst->outBuf, 0, sizeof(float) * 3 * BLOCKL_MAX);\n\n    inst->initFlag = 1;\n    return 0;\n}\n\nint WebRtcNs_set_policy_core(NSinst_t *inst, int mode)\n{\n    // allow for modes:0,1,2,3\n    if (mode < 0 || mode > 3)\n    {\n        return (-1);\n    }\n\n    inst->aggrMode = mode;\n    if (mode == 0)\n    {\n        inst->overdrive = (float)1.0;\n        inst->denoiseBound = (float)0.5;\n        inst->gainmap = 0;\n    }\n    else if (mode == 1)\n    {\n        //inst->overdrive = (float)1.25;\n        inst->overdrive = (float)1.0;\n        inst->denoiseBound = (float)0.25;\n        inst->gainmap = 1;\n    }\n    else if (mode == 2)\n    {\n        //inst->overdrive = (float)1.25;\n        inst->overdrive = (float)1.1;\n        inst->denoiseBound = (float)0.125;\n        inst->gainmap = 1;\n    }\n    else if (mode == 3)\n    {\n        //inst->overdrive = (float)1.30;\n        inst->overdrive = (float)1.25;\n        inst->denoiseBound = (float)0.09;\n        inst->gainmap = 1;\n    }\n    return 0;\n}\n\n// Estimate noise\nvoid WebRtcNs_NoiseEstimation(NSinst_t *inst, float *magn, float *noise)\n{\n    int i, s, offset;\n    float lmagn[HALF_ANAL_BLOCKL], delta;\n\n    if (inst->updates < END_STARTUP_LONG)\n    {\n        inst->updates++;\n    }\n\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        lmagn[i] = (float)log(magn[i]);\n    }\n\n    // loop over simultaneous estimates\n    for (s = 0; s < SIMULT; s++)\n    {\n        offset = s * inst->magnLen;\n\n        // newquantest(...)\n        for (i = 0; i < inst->magnLen; i++)\n        {\n            // compute delta\n            if (inst->density[offset + i] > 1.0)\n            {\n                delta = FACTOR * (float)1.0 / inst->density[offset + i];\n            }\n            else\n            {\n                delta = FACTOR;\n            }\n\n            // update log quantile estimate\n            if (lmagn[i] > inst->lquantile[offset + i])\n            {\n                inst->lquantile[offset + i] += QUANTILE * delta\n                        / (float)(inst->counter[s] + 1);\n            }\n            else\n            {\n                inst->lquantile[offset + i] -= ((float)1.0 - QUANTILE) * delta\n                        / (float)(inst->counter[s] + 1);\n            }\n\n            // update density estimate\n            if (fabs(lmagn[i] - inst->lquantile[offset + i]) < WIDTH)\n            {\n                inst->density[offset + i] = ((float)inst->counter[s] * inst->density[offset\n                        + i] + (float)1.0 / ((float)2.0 * WIDTH)) / (float)(inst->counter[s]\n                        + 1);\n            }\n        } // end loop over magnitude spectrum\n\n        if (inst->counter[s] >= END_STARTUP_LONG)\n        {\n            inst->counter[s] = 0;\n            if (inst->updates >= END_STARTUP_LONG)\n            {\n                for (i = 0; i < inst->magnLen; i++)\n                {\n                    inst->quantile[i] = (float)exp(inst->lquantile[offset + i]);\n                }\n            }\n        }\n\n        inst->counter[s]++;\n    } // end loop over simultaneous estimates\n\n    // Sequentially update the noise during startup\n    if (inst->updates < END_STARTUP_LONG)\n    {\n        // Use the last \"s\" to get noise during startup that differ from zero.\n        for (i = 0; i < inst->magnLen; i++)\n        {\n            inst->quantile[i] = (float)exp(inst->lquantile[offset + i]);\n        }\n    }\n\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        noise[i] = inst->quantile[i];\n    }\n}\n\n// Extract thresholds for feature parameters\n// histograms are computed over some window_size (given by inst->modelUpdatePars[1])\n// thresholds and weights are extracted every window\n// flag 0 means update histogram only, flag 1 means compute the thresholds/weights\n// threshold and weights are returned in: inst->priorModelPars\nvoid WebRtcNs_FeatureParameterExtraction(NSinst_t *inst, int flag)\n{\n    int i, useFeatureSpecFlat, useFeatureSpecDiff, numHistLrt;\n    int maxPeak1, maxPeak2;\n    int weightPeak1SpecFlat, weightPeak2SpecFlat, weightPeak1SpecDiff, weightPeak2SpecDiff;\n\n    float binMid, featureSum;\n    float posPeak1SpecFlat, posPeak2SpecFlat, posPeak1SpecDiff, posPeak2SpecDiff;\n    float fluctLrt, avgHistLrt, avgSquareHistLrt, avgHistLrtCompl;\n\n    //3 features: lrt, flatness, difference\n    //lrt_feature = inst->featureData[3];\n    //flat_feature = inst->featureData[0];\n    //diff_feature = inst->featureData[4];\n\n    //update histograms\n    if (flag == 0)\n    {\n        // LRT\n        if ((inst->featureData[3] < HIST_PAR_EST * inst->featureExtractionParams.binSizeLrt)\n                && (inst->featureData[3] >= 0.0))\n        {\n            i = (int)(inst->featureData[3] / inst->featureExtractionParams.binSizeLrt);\n            inst->histLrt[i]++;\n        }\n        // Spectral flatness\n        if ((inst->featureData[0] < HIST_PAR_EST\n                    * inst->featureExtractionParams.binSizeSpecFlat)\n                && (inst->featureData[0] >= 0.0))\n        {\n            i = (int)(inst->featureData[0] / inst->featureExtractionParams.binSizeSpecFlat);\n            inst->histSpecFlat[i]++;\n        }\n        // Spectral difference\n        if ((inst->featureData[4] < HIST_PAR_EST\n                    * inst->featureExtractionParams.binSizeSpecDiff)\n                && (inst->featureData[4] >= 0.0))\n        {\n            i = (int)(inst->featureData[4] / inst->featureExtractionParams.binSizeSpecDiff);\n            inst->histSpecDiff[i]++;\n        }\n    }\n\n    // extract parameters for speech/noise probability\n    if (flag == 1)\n    {\n        //lrt feature: compute the average over inst->featureExtractionParams.rangeAvgHistLrt\n        avgHistLrt = 0.0;\n        avgHistLrtCompl = 0.0;\n        avgSquareHistLrt = 0.0;\n        numHistLrt = 0;\n        for (i = 0; i < HIST_PAR_EST; i++)\n        {\n            binMid = ((float)i + (float)0.5) * inst->featureExtractionParams.binSizeLrt;\n            if (binMid <= inst->featureExtractionParams.rangeAvgHistLrt)\n            {\n                avgHistLrt += inst->histLrt[i] * binMid;\n                numHistLrt += inst->histLrt[i];\n            }\n            avgSquareHistLrt += inst->histLrt[i] * binMid * binMid;\n            avgHistLrtCompl += inst->histLrt[i] * binMid;\n        }\n        if (numHistLrt > 0)\n        {\n            avgHistLrt = avgHistLrt / ((float)numHistLrt);\n        }\n        avgHistLrtCompl = avgHistLrtCompl / ((float)inst->modelUpdatePars[1]);\n        avgSquareHistLrt = avgSquareHistLrt / ((float)inst->modelUpdatePars[1]);\n        fluctLrt = avgSquareHistLrt - avgHistLrt * avgHistLrtCompl;\n        // get threshold for lrt feature:\n        if (fluctLrt < inst->featureExtractionParams.thresFluctLrt)\n        {\n            //very low fluct, so likely noise\n            inst->priorModelPars[0] = inst->featureExtractionParams.maxLrt;\n        }\n        else\n        {\n            inst->priorModelPars[0] = inst->featureExtractionParams.factor1ModelPars\n                    * avgHistLrt;\n            // check if value is within min/max range\n            if (inst->priorModelPars[0] < inst->featureExtractionParams.minLrt)\n            {\n                inst->priorModelPars[0] = inst->featureExtractionParams.minLrt;\n            }\n            if (inst->priorModelPars[0] > inst->featureExtractionParams.maxLrt)\n            {\n                inst->priorModelPars[0] = inst->featureExtractionParams.maxLrt;\n            }\n        }\n        // done with lrt feature\n\n        //\n        // for spectral flatness and spectral difference: compute the main peaks of histogram\n        maxPeak1 = 0;\n        maxPeak2 = 0;\n        posPeak1SpecFlat = 0.0;\n        posPeak2SpecFlat = 0.0;\n        weightPeak1SpecFlat = 0;\n        weightPeak2SpecFlat = 0;\n\n        // peaks for flatness\n        for (i = 0; i < HIST_PAR_EST; i++)\n        {\n            binMid = ((float)i + (float)0.5) * inst->featureExtractionParams.binSizeSpecFlat;\n            if (inst->histSpecFlat[i] > maxPeak1)\n            {\n                // Found new \"first\" peak\n                maxPeak2 = maxPeak1;\n                weightPeak2SpecFlat = weightPeak1SpecFlat;\n                posPeak2SpecFlat = posPeak1SpecFlat;\n\n                maxPeak1 = inst->histSpecFlat[i];\n                weightPeak1SpecFlat = inst->histSpecFlat[i];\n                posPeak1SpecFlat = binMid;\n            }\n            else if (inst->histSpecFlat[i] > maxPeak2)\n            {\n                // Found new \"second\" peak\n                maxPeak2 = inst->histSpecFlat[i];\n                weightPeak2SpecFlat = inst->histSpecFlat[i];\n                posPeak2SpecFlat = binMid;\n            }\n        }\n\n        //compute two peaks for spectral difference\n        maxPeak1 = 0;\n        maxPeak2 = 0;\n        posPeak1SpecDiff = 0.0;\n        posPeak2SpecDiff = 0.0;\n        weightPeak1SpecDiff = 0;\n        weightPeak2SpecDiff = 0;\n        // peaks for spectral difference\n        for (i = 0; i < HIST_PAR_EST; i++)\n        {\n            binMid = ((float)i + (float)0.5) * inst->featureExtractionParams.binSizeSpecDiff;\n            if (inst->histSpecDiff[i] > maxPeak1)\n            {\n                // Found new \"first\" peak\n                maxPeak2 = maxPeak1;\n                weightPeak2SpecDiff = weightPeak1SpecDiff;\n                posPeak2SpecDiff = posPeak1SpecDiff;\n\n                maxPeak1 = inst->histSpecDiff[i];\n                weightPeak1SpecDiff = inst->histSpecDiff[i];\n                posPeak1SpecDiff = binMid;\n            }\n            else if (inst->histSpecDiff[i] > maxPeak2)\n            {\n                // Found new \"second\" peak\n                maxPeak2 = inst->histSpecDiff[i];\n                weightPeak2SpecDiff = inst->histSpecDiff[i];\n                posPeak2SpecDiff = binMid;\n            }\n        }\n\n        // for spectrum flatness feature\n        useFeatureSpecFlat = 1;\n        // merge the two peaks if they are close\n        if ((fabs(posPeak2SpecFlat - posPeak1SpecFlat)\n                < inst->featureExtractionParams.limitPeakSpacingSpecFlat)\n                && (weightPeak2SpecFlat\n                        > inst->featureExtractionParams.limitPeakWeightsSpecFlat\n                                * weightPeak1SpecFlat))\n        {\n            weightPeak1SpecFlat += weightPeak2SpecFlat;\n            posPeak1SpecFlat = (float)0.5 * (posPeak1SpecFlat + posPeak2SpecFlat);\n        }\n        //reject if weight of peaks is not large enough, or peak value too small\n        if (weightPeak1SpecFlat < inst->featureExtractionParams.thresWeightSpecFlat\n                || posPeak1SpecFlat < inst->featureExtractionParams.thresPosSpecFlat)\n        {\n            useFeatureSpecFlat = 0;\n        }\n        // if selected, get the threshold\n        if (useFeatureSpecFlat == 1)\n        {\n            // compute the threshold\n            inst->priorModelPars[1] = inst->featureExtractionParams.factor2ModelPars\n                    * posPeak1SpecFlat;\n            //check if value is within min/max range\n            if (inst->priorModelPars[1] < inst->featureExtractionParams.minSpecFlat)\n            {\n                inst->priorModelPars[1] = inst->featureExtractionParams.minSpecFlat;\n            }\n            if (inst->priorModelPars[1] > inst->featureExtractionParams.maxSpecFlat)\n            {\n                inst->priorModelPars[1] = inst->featureExtractionParams.maxSpecFlat;\n            }\n        }\n        // done with flatness feature\n\n        // for template feature\n        useFeatureSpecDiff = 1;\n        // merge the two peaks if they are close\n        if ((fabs(posPeak2SpecDiff - posPeak1SpecDiff)\n                < inst->featureExtractionParams.limitPeakSpacingSpecDiff)\n                && (weightPeak2SpecDiff\n                        > inst->featureExtractionParams.limitPeakWeightsSpecDiff\n                                * weightPeak1SpecDiff))\n        {\n            weightPeak1SpecDiff += weightPeak2SpecDiff;\n            posPeak1SpecDiff = (float)0.5 * (posPeak1SpecDiff + posPeak2SpecDiff);\n        }\n        // get the threshold value\n        inst->priorModelPars[3] = inst->featureExtractionParams.factor1ModelPars\n                * posPeak1SpecDiff;\n        //reject if weight of peaks is not large enough\n        if (weightPeak1SpecDiff < inst->featureExtractionParams.thresWeightSpecDiff)\n        {\n            useFeatureSpecDiff = 0;\n        }\n        //check if value is within min/max range\n        if (inst->priorModelPars[3] < inst->featureExtractionParams.minSpecDiff)\n        {\n            inst->priorModelPars[3] = inst->featureExtractionParams.minSpecDiff;\n        }\n        if (inst->priorModelPars[3] > inst->featureExtractionParams.maxSpecDiff)\n        {\n            inst->priorModelPars[3] = inst->featureExtractionParams.maxSpecDiff;\n        }\n        // done with spectral difference feature\n\n        // don't use template feature if fluctuation of lrt feature is very low:\n        //  most likely just noise state\n        if (fluctLrt < inst->featureExtractionParams.thresFluctLrt)\n        {\n            useFeatureSpecDiff = 0;\n        }\n\n        // select the weights between the features\n        // inst->priorModelPars[4] is weight for lrt: always selected\n        // inst->priorModelPars[5] is weight for spectral flatness\n        // inst->priorModelPars[6] is weight for spectral difference\n        featureSum = (float)(1 + useFeatureSpecFlat + useFeatureSpecDiff);\n        inst->priorModelPars[4] = (float)1.0 / featureSum;\n        inst->priorModelPars[5] = ((float)useFeatureSpecFlat) / featureSum;\n        inst->priorModelPars[6] = ((float)useFeatureSpecDiff) / featureSum;\n\n        // set hists to zero for next update\n        if (inst->modelUpdatePars[0] >= 1)\n        {\n            for (i = 0; i < HIST_PAR_EST; i++)\n            {\n                inst->histLrt[i] = 0;\n                inst->histSpecFlat[i] = 0;\n                inst->histSpecDiff[i] = 0;\n            }\n        }\n    } // end of flag == 1\n}\n\n// Compute spectral flatness on input spectrum\n// magnIn is the magnitude spectrum\n// spectral flatness is returned in inst->featureData[0]\nvoid WebRtcNs_ComputeSpectralFlatness(NSinst_t *inst, float *magnIn)\n{\n    int i;\n    int shiftLP = 1; //option to remove first bin(s) from spectral measures\n    float avgSpectralFlatnessNum, avgSpectralFlatnessDen, spectralTmp;\n\n    // comute spectral measures\n    // for flatness\n    avgSpectralFlatnessNum = 0.0;\n    avgSpectralFlatnessDen = inst->sumMagn;\n    for (i = 0; i < shiftLP; i++)\n    {\n        avgSpectralFlatnessDen -= magnIn[i];\n    }\n    // compute log of ratio of the geometric to arithmetic mean: check for log(0) case\n    for (i = shiftLP; i < inst->magnLen; i++)\n    {\n        if (magnIn[i] > 0.0)\n        {\n            avgSpectralFlatnessNum += (float)log(magnIn[i]);\n        }\n        else\n        {\n            inst->featureData[0] -= SPECT_FL_TAVG * inst->featureData[0];\n            return;\n        }\n    }\n    //normalize\n    avgSpectralFlatnessDen = avgSpectralFlatnessDen / inst->magnLen;\n    avgSpectralFlatnessNum = avgSpectralFlatnessNum / inst->magnLen;\n\n    //ratio and inverse log: check for case of log(0)\n    spectralTmp = (float)exp(avgSpectralFlatnessNum) / avgSpectralFlatnessDen;\n\n    //time-avg update of spectral flatness feature\n    inst->featureData[0] += SPECT_FL_TAVG * (spectralTmp - inst->featureData[0]);\n    // done with flatness feature\n}\n\n// Compute the difference measure between input spectrum and a template/learned noise spectrum\n// magnIn is the input spectrum\n// the reference/template spectrum is inst->magnAvgPause[i]\n// returns (normalized) spectral difference in inst->featureData[4]\nvoid WebRtcNs_ComputeSpectralDifference(NSinst_t *inst, float *magnIn)\n{\n    // avgDiffNormMagn = var(magnIn) - cov(magnIn, magnAvgPause)^2 / var(magnAvgPause)\n    int i;\n    float avgPause, avgMagn, covMagnPause, varPause, varMagn, avgDiffNormMagn;\n\n    avgPause = 0.0;\n    avgMagn = inst->sumMagn;\n    // compute average quantities\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        //conservative smooth noise spectrum from pause frames\n        avgPause += inst->magnAvgPause[i];\n    }\n    avgPause = avgPause / ((float)inst->magnLen);\n    avgMagn = avgMagn / ((float)inst->magnLen);\n\n    covMagnPause = 0.0;\n    varPause = 0.0;\n    varMagn = 0.0;\n    // compute variance and covariance quantities\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        covMagnPause += (magnIn[i] - avgMagn) * (inst->magnAvgPause[i] - avgPause);\n        varPause += (inst->magnAvgPause[i] - avgPause) * (inst->magnAvgPause[i] - avgPause);\n        varMagn += (magnIn[i] - avgMagn) * (magnIn[i] - avgMagn);\n    }\n    covMagnPause = covMagnPause / ((float)inst->magnLen);\n    varPause = varPause / ((float)inst->magnLen);\n    varMagn = varMagn / ((float)inst->magnLen);\n    // update of average magnitude spectrum\n    inst->featureData[6] += inst->signalEnergy;\n\n    avgDiffNormMagn = varMagn - (covMagnPause * covMagnPause) / (varPause + (float)0.0001);\n    // normalize and compute time-avg update of difference feature\n    avgDiffNormMagn = (float)(avgDiffNormMagn / (inst->featureData[5] + (float)0.0001));\n    inst->featureData[4] += SPECT_DIFF_TAVG * (avgDiffNormMagn - inst->featureData[4]);\n}\n\n// Compute speech/noise probability\n// speech/noise probability is returned in: probSpeechFinal\n//magn is the input magnitude spectrum\n//noise is the noise spectrum\n//snrLocPrior is the prior snr for each freq.\n//snr loc_post is the post snr for each freq.\nvoid WebRtcNs_SpeechNoiseProb(NSinst_t *inst, float *probSpeechFinal, float *snrLocPrior,\n                              float *snrLocPost)\n{\n    int i, sgnMap;\n    float invLrt, gainPrior, indPrior;\n    float logLrtTimeAvgKsum, besselTmp;\n    float indicator0, indicator1, indicator2;\n    float tmpFloat1, tmpFloat2;\n    float weightIndPrior0, weightIndPrior1, weightIndPrior2;\n    float threshPrior0, threshPrior1, threshPrior2;\n    float widthPrior, widthPrior0, widthPrior1, widthPrior2;\n\n    widthPrior0 = WIDTH_PR_MAP;\n    widthPrior1 = (float)2.0 * WIDTH_PR_MAP; //width for pause region:\n                                             // lower range, so increase width in tanh map\n    widthPrior2 = (float)2.0 * WIDTH_PR_MAP; //for spectral-difference measure\n\n    //threshold parameters for features\n    threshPrior0 = inst->priorModelPars[0];\n    threshPrior1 = inst->priorModelPars[1];\n    threshPrior2 = inst->priorModelPars[3];\n\n    //sign for flatness feature\n    sgnMap = (int)(inst->priorModelPars[2]);\n\n    //weight parameters for features\n    weightIndPrior0 = inst->priorModelPars[4];\n    weightIndPrior1 = inst->priorModelPars[5];\n    weightIndPrior2 = inst->priorModelPars[6];\n\n    // compute feature based on average LR factor\n    // this is the average over all frequencies of the smooth log lrt\n    logLrtTimeAvgKsum = 0.0;\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        tmpFloat1 = (float)1.0 + (float)2.0 * snrLocPrior[i];\n        tmpFloat2 = (float)2.0 * snrLocPrior[i] / (tmpFloat1 + (float)0.0001);\n        besselTmp = (snrLocPost[i] + (float)1.0) * tmpFloat2;\n        inst->logLrtTimeAvg[i] += LRT_TAVG * (besselTmp - (float)log(tmpFloat1)\n                - inst->logLrtTimeAvg[i]);\n        logLrtTimeAvgKsum += inst->logLrtTimeAvg[i];\n    }\n    logLrtTimeAvgKsum = (float)logLrtTimeAvgKsum / (inst->magnLen);\n    inst->featureData[3] = logLrtTimeAvgKsum;\n    // done with computation of LR factor\n\n    //\n    //compute the indicator functions\n    //\n\n    // average lrt feature\n    widthPrior = widthPrior0;\n    //use larger width in tanh map for pause regions\n    if (logLrtTimeAvgKsum < threshPrior0)\n    {\n        widthPrior = widthPrior1;\n    }\n    // compute indicator function: sigmoid map\n    indicator0 = (float)0.5 * ((float)tanh(widthPrior * (logLrtTimeAvgKsum - threshPrior0))\n            + (float)1.0);\n\n    //spectral flatness feature\n    tmpFloat1 = inst->featureData[0];\n    widthPrior = widthPrior0;\n    //use larger width in tanh map for pause regions\n    if (sgnMap == 1 && (tmpFloat1 > threshPrior1))\n    {\n        widthPrior = widthPrior1;\n    }\n    if (sgnMap == -1 && (tmpFloat1 < threshPrior1))\n    {\n        widthPrior = widthPrior1;\n    }\n    // compute indicator function: sigmoid map\n    indicator1 = (float)0.5 * ((float)tanh(\n                                           (float)sgnMap * widthPrior * (threshPrior1\n                                                   - tmpFloat1)) + (float)1.0);\n\n    //for template spectrum-difference\n    tmpFloat1 = inst->featureData[4];\n    widthPrior = widthPrior0;\n    //use larger width in tanh map for pause regions\n    if (tmpFloat1 < threshPrior2)\n    {\n        widthPrior = widthPrior2;\n    }\n    // compute indicator function: sigmoid map\n    indicator2 = (float)0.5 * ((float)tanh(widthPrior * (tmpFloat1 - threshPrior2))\n            + (float)1.0);\n\n    //combine the indicator function with the feature weights\n    indPrior = weightIndPrior0 * indicator0 + weightIndPrior1 * indicator1 + weightIndPrior2\n            * indicator2;\n    // done with computing indicator function\n\n    //compute the prior probability\n    inst->priorSpeechProb += PRIOR_UPDATE * (indPrior - inst->priorSpeechProb);\n    // make sure probabilities are within range: keep floor to 0.01\n    if (inst->priorSpeechProb > 1.0)\n    {\n        inst->priorSpeechProb = (float)1.0;\n    }\n    if (inst->priorSpeechProb < 0.01)\n    {\n        inst->priorSpeechProb = (float)0.01;\n    }\n\n    //final speech probability: combine prior model with LR factor:\n    gainPrior = ((float)1.0 - inst->priorSpeechProb) / (inst->priorSpeechProb + (float)0.0001);\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        invLrt = (float)exp(-inst->logLrtTimeAvg[i]);\n        invLrt = (float)gainPrior * invLrt;\n        probSpeechFinal[i] = (float)1.0 / ((float)1.0 + invLrt);\n    }\n}\n\nint WebRtcNs_ProcessCore(NSinst_t *inst,\n                         short *speechFrame,\n                         short *speechFrameHB,\n                         short *outFrame,\n                         short *outFrameHB)\n{\n    // main routine for noise reduction\n\n    int     flagHB = 0;\n    int     i;\n    const int kStartBand = 5; // Skip first frequency bins during estimation.\n    int     updateParsFlag;\n\n    float   energy1, energy2, gain, factor, factor1, factor2;\n    float   signalEnergy, sumMagn;\n    float   snrPrior, currentEstimateStsa;\n    float   tmpFloat1, tmpFloat2, tmpFloat3, probSpeech, probNonSpeech;\n    float   gammaNoiseTmp, gammaNoiseOld;\n    float   noiseUpdateTmp, fTmp, dTmp;\n    float   fin[BLOCKL_MAX], fout[BLOCKL_MAX];\n    float   winData[ANAL_BLOCKL_MAX];\n    float   magn[HALF_ANAL_BLOCKL], noise[HALF_ANAL_BLOCKL];\n    float   theFilter[HALF_ANAL_BLOCKL], theFilterTmp[HALF_ANAL_BLOCKL];\n    float   snrLocPost[HALF_ANAL_BLOCKL], snrLocPrior[HALF_ANAL_BLOCKL];\n    float   probSpeechFinal[HALF_ANAL_BLOCKL], previousEstimateStsa[HALF_ANAL_BLOCKL];\n    float   real[ANAL_BLOCKL_MAX], imag[HALF_ANAL_BLOCKL];\n    // Variables during startup\n    float   sum_log_i = 0.0;\n    float   sum_log_i_square = 0.0;\n    float   sum_log_magn = 0.0;\n    float   sum_log_i_log_magn = 0.0;\n    float   parametric_noise = 0.0;\n    float   parametric_exp = 0.0;\n    float   parametric_num = 0.0;\n\n    // SWB variables\n    int     deltaBweHB = 1;\n    int     deltaGainHB = 1;\n    float   decayBweHB = 1.0;\n    float   gainMapParHB = 1.0;\n    float   gainTimeDomainHB = 1.0;\n    float   avgProbSpeechHB, avgProbSpeechHBTmp, avgFilterGainHB, gainModHB;\n\n    // Check that initiation has been done\n    if (inst->initFlag != 1)\n    {\n        return (-1);\n    }\n    // Check for valid pointers based on sampling rate\n    if (inst->fs == 32000)\n    {\n        if (speechFrameHB == NULL)\n        {\n            return -1;\n        }\n        flagHB = 1;\n        // range for averaging low band quantities for H band gain\n        deltaBweHB = (int)inst->magnLen / 4;\n        deltaGainHB = deltaBweHB;\n    }\n    //\n    updateParsFlag = inst->modelUpdatePars[0];\n    //\n\n    //for LB do all processing\n    // convert to float\n    for (i = 0; i < inst->blockLen10ms; i++)\n    {\n        fin[i] = (float)speechFrame[i];\n    }\n    // update analysis buffer for L band\n    memcpy(inst->dataBuf, inst->dataBuf + inst->blockLen10ms,\n           sizeof(float) * (inst->anaLen - inst->blockLen10ms));\n    memcpy(inst->dataBuf + inst->anaLen - inst->blockLen10ms, fin,\n           sizeof(float) * inst->blockLen10ms);\n\n    if (flagHB == 1)\n    {\n        // convert to float\n        for (i = 0; i < inst->blockLen10ms; i++)\n        {\n            fin[i] = (float)speechFrameHB[i];\n        }\n        // update analysis buffer for H band\n        memcpy(inst->dataBufHB, inst->dataBufHB + inst->blockLen10ms,\n               sizeof(float) * (inst->anaLen - inst->blockLen10ms));\n        memcpy(inst->dataBufHB + inst->anaLen - inst->blockLen10ms, fin,\n               sizeof(float) * inst->blockLen10ms);\n    }\n\n    // check if processing needed\n    if (inst->outLen == 0)\n    {\n        // windowing\n        energy1 = 0.0;\n        for (i = 0; i < inst->anaLen; i++)\n        {\n            winData[i] = inst->window[i] * inst->dataBuf[i];\n            energy1 += winData[i] * winData[i];\n        }\n        if (energy1 == 0.0)\n        {\n            // synthesize the special case of zero input\n            // we want to avoid updating statistics in this case:\n            // Updating feature statistics when we have zeros only will cause thresholds to\n            // move towards zero signal situations. This in turn has the effect that once the\n            // signal is \"turned on\" (non-zero values) everything will be treated as speech\n            // and there is no noise suppression effect. Depending on the duration of the\n            // inactive signal it takes a considerable amount of time for the system to learn\n            // what is noise and what is speech.\n\n            // read out fully processed segment\n            for (i = inst->windShift; i < inst->blockLen + inst->windShift; i++)\n            {\n                fout[i - inst->windShift] = inst->syntBuf[i];\n            }\n            // update synthesis buffer\n            memcpy(inst->syntBuf, inst->syntBuf + inst->blockLen,\n                   sizeof(float) * (inst->anaLen - inst->blockLen));\n            memset(inst->syntBuf + inst->anaLen - inst->blockLen, 0,\n                   sizeof(float) * inst->blockLen);\n\n            // out buffer\n            inst->outLen = inst->blockLen - inst->blockLen10ms;\n            if (inst->blockLen > inst->blockLen10ms)\n            {\n                for (i = 0; i < inst->outLen; i++)\n                {\n                    inst->outBuf[i] = fout[i + inst->blockLen10ms];\n                }\n            }\n            // convert to short\n            for (i = 0; i < inst->blockLen10ms; i++)\n            {\n                dTmp = fout[i];\n                if (dTmp < WEBRTC_SPL_WORD16_MIN)\n                {\n                    dTmp = WEBRTC_SPL_WORD16_MIN;\n                }\n                else if (dTmp > WEBRTC_SPL_WORD16_MAX)\n                {\n                    dTmp = WEBRTC_SPL_WORD16_MAX;\n                }\n                outFrame[i] = (short)dTmp;\n            }\n\n            // for time-domain gain of HB\n            if (flagHB == 1)\n            {\n                for (i = 0; i < inst->blockLen10ms; i++)\n                {\n                    dTmp = inst->dataBufHB[i];\n                    if (dTmp < WEBRTC_SPL_WORD16_MIN)\n                    {\n                        dTmp = WEBRTC_SPL_WORD16_MIN;\n                    }\n                    else if (dTmp > WEBRTC_SPL_WORD16_MAX)\n                    {\n                        dTmp = WEBRTC_SPL_WORD16_MAX;\n                    }\n                    outFrameHB[i] = (short)dTmp;\n                }\n            } // end of H band gain computation\n            //\n            return 0;\n        }\n\n        //\n        inst->blockInd++; // Update the block index only when we process a block.\n        // FFT\n        rdft(inst->anaLen, 1, winData, inst->ip, inst->wfft);\n\n        imag[0] = 0;\n        real[0] = winData[0];\n        magn[0] = (float)(fabs(real[0]) + 1.0f);\n        imag[inst->magnLen - 1] = 0;\n        real[inst->magnLen - 1] = winData[1];\n        magn[inst->magnLen - 1] = (float)(fabs(real[inst->magnLen - 1]) + 1.0f);\n        signalEnergy = (float)(real[0] * real[0]) + (float)(real[inst->magnLen - 1]\n                * real[inst->magnLen - 1]);\n        sumMagn = magn[0] + magn[inst->magnLen - 1];\n        if (inst->blockInd < END_STARTUP_SHORT)\n        {\n            inst->initMagnEst[0] += magn[0];\n            inst->initMagnEst[inst->magnLen - 1] += magn[inst->magnLen - 1];\n            tmpFloat2 = log((float)(inst->magnLen - 1));\n            sum_log_i = tmpFloat2;\n            sum_log_i_square = tmpFloat2 * tmpFloat2;\n            tmpFloat1 = log(magn[inst->magnLen - 1]);\n            sum_log_magn = tmpFloat1;\n            sum_log_i_log_magn = tmpFloat2 * tmpFloat1;\n        }\n        for (i = 1; i < inst->magnLen - 1; i++)\n        {\n            real[i] = winData[2 * i];\n            imag[i] = winData[2 * i + 1];\n            // magnitude spectrum\n            fTmp = real[i] * real[i];\n            fTmp += imag[i] * imag[i];\n            signalEnergy += fTmp;\n            magn[i] = ((float)sqrt(fTmp)) + 1.0f;\n            sumMagn += magn[i];\n            if (inst->blockInd < END_STARTUP_SHORT)\n            {\n                inst->initMagnEst[i] += magn[i];\n                if (i >= kStartBand)\n                {\n                    tmpFloat2 = log((float)i);\n                    sum_log_i += tmpFloat2;\n                    sum_log_i_square += tmpFloat2 * tmpFloat2;\n                    tmpFloat1 = log(magn[i]);\n                    sum_log_magn += tmpFloat1;\n                    sum_log_i_log_magn += tmpFloat2 * tmpFloat1;\n                }\n            }\n        }\n        signalEnergy = signalEnergy / ((float)inst->magnLen);\n        inst->signalEnergy = signalEnergy;\n        inst->sumMagn = sumMagn;\n\n        //compute spectral flatness on input spectrum\n        WebRtcNs_ComputeSpectralFlatness(inst, magn);\n        // quantile noise estimate\n        WebRtcNs_NoiseEstimation(inst, magn, noise);\n        //compute simplified noise model during startup\n        if (inst->blockInd < END_STARTUP_SHORT)\n        {\n            // Estimate White noise\n            inst->whiteNoiseLevel += sumMagn / ((float)inst->magnLen) * inst->overdrive;\n            // Estimate Pink noise parameters\n            tmpFloat1 = sum_log_i_square * ((float)(inst->magnLen - kStartBand));\n            tmpFloat1 -= (sum_log_i * sum_log_i);\n            tmpFloat2 = (sum_log_i_square * sum_log_magn - sum_log_i * sum_log_i_log_magn);\n            tmpFloat3 = tmpFloat2 / tmpFloat1;\n            // Constrain the estimated spectrum to be positive\n            if (tmpFloat3 < 0.0f)\n            {\n                tmpFloat3 = 0.0f;\n            }\n            inst->pinkNoiseNumerator += tmpFloat3;\n            tmpFloat2 = (sum_log_i * sum_log_magn);\n            tmpFloat2 -= ((float)(inst->magnLen - kStartBand)) * sum_log_i_log_magn;\n            tmpFloat3 = tmpFloat2 / tmpFloat1;\n            // Constrain the pink noise power to be in the interval [0, 1];\n            if (tmpFloat3 < 0.0f)\n            {\n                tmpFloat3 = 0.0f;\n            }\n            if (tmpFloat3 > 1.0f)\n            {\n                tmpFloat3 = 1.0f;\n            }\n            inst->pinkNoiseExp += tmpFloat3;\n\n            // Calculate frequency independent parts of parametric noise estimate.\n            if (inst->pinkNoiseExp == 0.0f)\n            {\n                // Use white noise estimate\n                parametric_noise = inst->whiteNoiseLevel;\n            }\n            else\n            {\n                // Use pink noise estimate\n                parametric_num = exp(inst->pinkNoiseNumerator / (float)(inst->blockInd + 1));\n                parametric_num *= (float)(inst->blockInd + 1);\n                parametric_exp = inst->pinkNoiseExp / (float)(inst->blockInd + 1);\n                parametric_noise = parametric_num / pow((float)kStartBand, parametric_exp);\n            }\n            for (i = 0; i < inst->magnLen; i++)\n            {\n                // Estimate the background noise using the white and pink noise parameters\n                if ((inst->pinkNoiseExp > 0.0f) && (i >= kStartBand))\n                {\n                    // Use pink noise estimate\n                    parametric_noise = parametric_num / pow((float)i, parametric_exp);\n                }\n                theFilterTmp[i] = (inst->initMagnEst[i] - inst->overdrive * parametric_noise);\n                theFilterTmp[i] /= (inst->initMagnEst[i] + (float)0.0001);\n                // Weight quantile noise with modeled noise\n                noise[i] *= (inst->blockInd);\n                tmpFloat2 = parametric_noise * (END_STARTUP_SHORT - inst->blockInd);\n                noise[i] += (tmpFloat2 / (float)(inst->blockInd + 1));\n                noise[i] /= END_STARTUP_SHORT;\n            }\n        }\n        //compute average signal during END_STARTUP_LONG time:\n        // used to normalize spectral difference measure\n        if (inst->blockInd < END_STARTUP_LONG)\n        {\n            inst->featureData[5] *= inst->blockInd;\n            inst->featureData[5] += signalEnergy;\n            inst->featureData[5] /= (inst->blockInd + 1);\n        }\n\n#ifdef PROCESS_FLOW_0\n        if (inst->blockInd > END_STARTUP_LONG)\n        {\n            //option: average the quantile noise: for check with AEC2\n            for (i = 0; i < inst->magnLen; i++)\n            {\n                noise[i] = (float)0.6 * inst->noisePrev[i] + (float)0.4 * noise[i];\n            }\n            for (i = 0; i < inst->magnLen; i++)\n            {\n                // Wiener with over sub-substraction:\n                theFilter[i] = (magn[i] - inst->overdrive * noise[i]) / (magn[i] + (float)0.0001);\n            }\n        }\n#else\n        //start processing at frames == converged+1\n            //\n        // STEP 1: compute  prior and post snr based on quantile noise est\n        //\n\n        // compute DD estimate of prior SNR: needed for new method\n        for (i = 0; i < inst->magnLen; i++)\n        {\n            // post snr\n            snrLocPost[i] = (float)0.0;\n            if (magn[i] > noise[i])\n            {\n                snrLocPost[i] = magn[i] / (noise[i] + (float)0.0001) - (float)1.0;\n            }\n            // previous post snr\n            // previous estimate: based on previous frame with gain filter\n            previousEstimateStsa[i] = inst->magnPrev[i] / (inst->noisePrev[i] + (float)0.0001)\n                    * (inst->smooth[i]);\n            // DD estimate is sum of two terms: current estimate and previous estimate\n            // directed decision update of snrPrior\n            snrLocPrior[i] = DD_PR_SNR * previousEstimateStsa[i] + ((float)1.0 - DD_PR_SNR)\n                    * snrLocPost[i];\n            // post and prior snr needed for step 2\n        } // end of loop over freqs\n#ifdef PROCESS_FLOW_1\n        for (i = 0; i < inst->magnLen; i++)\n        {\n            // gain filter\n            tmpFloat1 = inst->overdrive + snrLocPrior[i];\n            tmpFloat2 = (float)snrLocPrior[i] / tmpFloat1;\n            theFilter[i] = (float)tmpFloat2;\n        } // end of loop over freqs\n#endif\n        // done with step 1: dd computation of prior and post snr\n\n        //\n        //STEP 2: compute speech/noise likelihood\n        //\n#ifdef PROCESS_FLOW_2\n        // compute difference of input spectrum with learned/estimated noise spectrum\n        WebRtcNs_ComputeSpectralDifference(inst, magn);\n        // compute histograms for parameter decisions (thresholds and weights for features)\n        // parameters are extracted once every window time (=inst->modelUpdatePars[1])\n        if (updateParsFlag >= 1)\n        {\n            // counter update\n            inst->modelUpdatePars[3]--;\n            // update histogram\n            if (inst->modelUpdatePars[3] > 0)\n            {\n                WebRtcNs_FeatureParameterExtraction(inst, 0);\n            }\n            // compute model parameters\n            if (inst->modelUpdatePars[3] == 0)\n            {\n                WebRtcNs_FeatureParameterExtraction(inst, 1);\n                inst->modelUpdatePars[3] = inst->modelUpdatePars[1];\n                // if wish to update only once, set flag to zero\n                if (updateParsFlag == 1)\n                {\n                    inst->modelUpdatePars[0] = 0;\n                }\n                else\n                {\n                    // update every window:\n                    // get normalization for spectral difference for next window estimate\n                    inst->featureData[6] = inst->featureData[6]\n                            / ((float)inst->modelUpdatePars[1]);\n                    inst->featureData[5] = (float)0.5 * (inst->featureData[6]\n                            + inst->featureData[5]);\n                    inst->featureData[6] = (float)0.0;\n                }\n            }\n        }\n        // compute speech/noise probability\n        WebRtcNs_SpeechNoiseProb(inst, probSpeechFinal, snrLocPrior, snrLocPost);\n        // time-avg parameter for noise update\n        gammaNoiseTmp = NOISE_UPDATE;\n        for (i = 0; i < inst->magnLen; i++)\n        {\n            probSpeech = probSpeechFinal[i];\n            probNonSpeech = (float)1.0 - probSpeech;\n            // temporary noise update:\n            // use it for speech frames if update value is less than previous\n            noiseUpdateTmp = gammaNoiseTmp * inst->noisePrev[i] + ((float)1.0 - gammaNoiseTmp)\n                    * (probNonSpeech * magn[i] + probSpeech * inst->noisePrev[i]);\n            //\n            // time-constant based on speech/noise state\n            gammaNoiseOld = gammaNoiseTmp;\n            gammaNoiseTmp = NOISE_UPDATE;\n            // increase gamma (i.e., less noise update) for frame likely to be speech\n            if (probSpeech > PROB_RANGE)\n            {\n                gammaNoiseTmp = SPEECH_UPDATE;\n            }\n            // conservative noise update\n            if (probSpeech < PROB_RANGE)\n            {\n                inst->magnAvgPause[i] += GAMMA_PAUSE * (magn[i] - inst->magnAvgPause[i]);\n            }\n            // noise update\n            if (gammaNoiseTmp == gammaNoiseOld)\n            {\n                noise[i] = noiseUpdateTmp;\n            }\n            else\n            {\n                noise[i] = gammaNoiseTmp * inst->noisePrev[i] + ((float)1.0 - gammaNoiseTmp)\n                        * (probNonSpeech * magn[i] + probSpeech * inst->noisePrev[i]);\n                // allow for noise update downwards:\n                //  if noise update decreases the noise, it is safe, so allow it to happen\n                if (noiseUpdateTmp < noise[i])\n                {\n                    noise[i] = noiseUpdateTmp;\n                }\n            }\n        } // end of freq loop\n        // done with step 2: noise update\n\n        //\n        // STEP 3: compute dd update of prior snr and post snr based on new noise estimate\n        //\n        for (i = 0; i < inst->magnLen; i++)\n        {\n            // post and prior snr\n            currentEstimateStsa = (float)0.0;\n            if (magn[i] > noise[i])\n            {\n                currentEstimateStsa = magn[i] / (noise[i] + (float)0.0001) - (float)1.0;\n            }\n            // DD estimate is sume of two terms: current estimate and previous estimate\n            // directed decision update of snrPrior\n            snrPrior = DD_PR_SNR * previousEstimateStsa[i] + ((float)1.0 - DD_PR_SNR)\n                    * currentEstimateStsa;\n            // gain filter\n            tmpFloat1 = inst->overdrive + snrPrior;\n            tmpFloat2 = (float)snrPrior / tmpFloat1;\n            theFilter[i] = (float)tmpFloat2;\n        } // end of loop over freqs\n        // done with step3\n#endif\n#endif\n\n        for (i = 0; i < inst->magnLen; i++)\n        {\n            // flooring bottom\n            if (theFilter[i] < inst->denoiseBound)\n            {\n                theFilter[i] = inst->denoiseBound;\n            }\n            // flooring top\n            if (theFilter[i] > (float)1.0)\n            {\n                theFilter[i] = 1.0;\n            }\n            if (inst->blockInd < END_STARTUP_SHORT)\n            {\n                // flooring bottom\n                if (theFilterTmp[i] < inst->denoiseBound)\n                {\n                    theFilterTmp[i] = inst->denoiseBound;\n                }\n                // flooring top\n                if (theFilterTmp[i] > (float)1.0)\n                {\n                    theFilterTmp[i] = 1.0;\n                }\n                // Weight the two suppression filters\n                theFilter[i] *= (inst->blockInd);\n                theFilterTmp[i] *= (END_STARTUP_SHORT - inst->blockInd);\n                theFilter[i] += theFilterTmp[i];\n                theFilter[i] /= (END_STARTUP_SHORT);\n            }\n            // smoothing\n#ifdef PROCESS_FLOW_0\n            inst->smooth[i] *= SMOOTH; // value set to 0.7 in define.h file\n            inst->smooth[i] += ((float)1.0 - SMOOTH) * theFilter[i];\n#else\n            inst->smooth[i] = theFilter[i];\n#endif\n            real[i] *= inst->smooth[i];\n            imag[i] *= inst->smooth[i];\n        }\n        // keep track of noise and magn spectrum for next frame\n        for (i = 0; i < inst->magnLen; i++)\n        {\n            inst->noisePrev[i] = noise[i];\n            inst->magnPrev[i] = magn[i];\n        }\n        // back to time domain\n        winData[0] = real[0];\n        winData[1] = real[inst->magnLen - 1];\n        for (i = 1; i < inst->magnLen - 1; i++)\n        {\n            winData[2 * i] = real[i];\n            winData[2 * i + 1] = imag[i];\n        }\n        rdft(inst->anaLen, -1, winData, inst->ip, inst->wfft);\n\n        for (i = 0; i < inst->anaLen; i++)\n        {\n            real[i] = 2.0f * winData[i] / inst->anaLen; // fft scaling\n        }\n\n        //scale factor: only do it after END_STARTUP_LONG time\n        factor = (float)1.0;\n        if (inst->gainmap == 1 && inst->blockInd > END_STARTUP_LONG)\n        {\n            factor1 = (float)1.0;\n            factor2 = (float)1.0;\n\n            energy2 = 0.0;\n            for (i = 0; i < inst->anaLen;i++)\n            {\n                energy2 += (float)real[i] * (float)real[i];\n            }\n            gain = (float)sqrt(energy2 / (energy1 + (float)1.0));\n\n#ifdef PROCESS_FLOW_2\n            // scaling for new version\n            if (gain > B_LIM)\n            {\n                factor1 = (float)1.0 + (float)1.3 * (gain - B_LIM);\n                if (gain * factor1 > (float)1.0)\n                {\n                    factor1 = (float)1.0 / gain;\n                }\n            }\n            if (gain < B_LIM)\n            {\n                //don't reduce scale too much for pause regions:\n                // attenuation here should be controlled by flooring\n                if (gain <= inst->denoiseBound)\n                {\n                    gain = inst->denoiseBound;\n                }\n                factor2 = (float)1.0 - (float)0.3 * (B_LIM - gain);\n            }\n            //combine both scales with speech/noise prob:\n            // note prior (priorSpeechProb) is not frequency dependent\n            factor = inst->priorSpeechProb * factor1 + ((float)1.0 - inst->priorSpeechProb)\n                    * factor2;\n#else\n            if (gain > B_LIM)\n            {\n                factor = (float)1.0 + (float)1.3 * (gain - B_LIM);\n            }\n            else\n            {\n                factor = (float)1.0 + (float)2.0 * (gain - B_LIM);\n            }\n            if (gain * factor > (float)1.0)\n            {\n                factor = (float)1.0 / gain;\n            }\n#endif\n        } // out of inst->gainmap==1\n\n        // synthesis\n        for (i = 0; i < inst->anaLen; i++)\n        {\n            inst->syntBuf[i] += factor * inst->window[i] * (float)real[i];\n        }\n        // read out fully processed segment\n        for (i = inst->windShift; i < inst->blockLen + inst->windShift; i++)\n        {\n            fout[i - inst->windShift] = inst->syntBuf[i];\n        }\n        // update synthesis buffer\n        memcpy(inst->syntBuf, inst->syntBuf + inst->blockLen,\n               sizeof(float) * (inst->anaLen - inst->blockLen));\n        memset(inst->syntBuf + inst->anaLen - inst->blockLen, 0,\n               sizeof(float) * inst->blockLen);\n\n        // out buffer\n        inst->outLen = inst->blockLen - inst->blockLen10ms;\n        if (inst->blockLen > inst->blockLen10ms)\n        {\n            for (i = 0; i < inst->outLen; i++)\n            {\n                inst->outBuf[i] = fout[i + inst->blockLen10ms];\n            }\n        }\n    } // end of if out.len==0\n    else\n    {\n        for (i = 0; i < inst->blockLen10ms; i++)\n        {\n            fout[i] = inst->outBuf[i];\n        }\n        memcpy(inst->outBuf, inst->outBuf + inst->blockLen10ms,\n               sizeof(float) * (inst->outLen - inst->blockLen10ms));\n        memset(inst->outBuf + inst->outLen - inst->blockLen10ms, 0,\n               sizeof(float) * inst->blockLen10ms);\n        inst->outLen -= inst->blockLen10ms;\n    }\n\n    // convert to short\n    for (i = 0; i < inst->blockLen10ms; i++)\n    {\n        dTmp = fout[i];\n        if (dTmp < WEBRTC_SPL_WORD16_MIN)\n        {\n            dTmp = WEBRTC_SPL_WORD16_MIN;\n        }\n        else if (dTmp > WEBRTC_SPL_WORD16_MAX)\n        {\n            dTmp = WEBRTC_SPL_WORD16_MAX;\n        }\n        outFrame[i] = (short)dTmp;\n    }\n\n    // for time-domain gain of HB\n    if (flagHB == 1)\n    {\n        for (i = 0; i < inst->magnLen; i++)\n        {\n            inst->speechProbHB[i] = probSpeechFinal[i];\n        }\n        if (inst->blockInd > END_STARTUP_LONG)\n        {\n            // average speech prob from low band\n            // avg over second half (i.e., 4->8kHz) of freq. spectrum\n            avgProbSpeechHB = 0.0;\n            for (i = inst->magnLen - deltaBweHB - 1; i < inst->magnLen - 1; i++)\n            {\n                avgProbSpeechHB += inst->speechProbHB[i];\n            }\n            avgProbSpeechHB = avgProbSpeechHB / ((float)deltaBweHB);\n            // average filter gain from low band\n            // average over second half (i.e., 4->8kHz) of freq. spectrum\n            avgFilterGainHB = 0.0;\n            for (i = inst->magnLen - deltaGainHB - 1; i < inst->magnLen - 1; i++)\n            {\n                avgFilterGainHB += inst->smooth[i];\n            }\n            avgFilterGainHB = avgFilterGainHB / ((float)(deltaGainHB));\n            avgProbSpeechHBTmp = (float)2.0 * avgProbSpeechHB - (float)1.0;\n            // gain based on speech prob:\n            gainModHB = (float)0.5 * ((float)1.0 + (float)tanh(gainMapParHB * avgProbSpeechHBTmp));\n            //combine gain with low band gain\n            gainTimeDomainHB = (float)0.5 * gainModHB + (float)0.5 * avgFilterGainHB;\n            if (avgProbSpeechHB >= (float)0.5)\n            {\n                gainTimeDomainHB = (float)0.25 * gainModHB + (float)0.75 * avgFilterGainHB;\n            }\n            gainTimeDomainHB = gainTimeDomainHB * decayBweHB;\n        } // end of converged\n        //make sure gain is within flooring range\n        // flooring bottom\n        if (gainTimeDomainHB < inst->denoiseBound)\n        {\n            gainTimeDomainHB = inst->denoiseBound;\n        }\n        // flooring top\n        if (gainTimeDomainHB > (float)1.0)\n        {\n            gainTimeDomainHB = 1.0;\n        }\n        //apply gain\n        for (i = 0; i < inst->blockLen10ms; i++)\n        {\n            dTmp = gainTimeDomainHB * inst->dataBufHB[i];\n            if (dTmp < WEBRTC_SPL_WORD16_MIN)\n            {\n                dTmp = WEBRTC_SPL_WORD16_MIN;\n            }\n            else if (dTmp > WEBRTC_SPL_WORD16_MAX)\n            {\n                dTmp = WEBRTC_SPL_WORD16_MAX;\n            }\n            outFrameHB[i] = (short)dTmp;\n        }\n    } // end of H band gain computation\n    //\n\n    return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/ns/main/source/ns_core.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NS_CORE_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NS_CORE_H_\n\n#include \"defines.h\"\n\ntypedef struct NSParaExtract_t_ {\n\n    //bin size of histogram\n    float binSizeLrt;\n    float binSizeSpecFlat;\n    float binSizeSpecDiff;\n    //range of histogram over which lrt threshold is computed\n    float rangeAvgHistLrt;\n    //scale parameters: multiply dominant peaks of the histograms by scale factor to obtain\n    //thresholds for prior model\n    float factor1ModelPars; //for lrt and spectral difference\n    float factor2ModelPars; //for spectral_flatness: used when noise is flatter than speech\n    //peak limit for spectral flatness (varies between 0 and 1)\n    float thresPosSpecFlat;\n    //limit on spacing of two highest peaks in histogram: spacing determined by bin size\n    float limitPeakSpacingSpecFlat;\n    float limitPeakSpacingSpecDiff;\n    //limit on relevance of second peak:\n    float limitPeakWeightsSpecFlat;\n    float limitPeakWeightsSpecDiff;\n    //limit on fluctuation of lrt feature\n    float thresFluctLrt;\n    //limit on the max and min values for the feature thresholds\n    float maxLrt;\n    float minLrt;\n    float maxSpecFlat;\n    float minSpecFlat;\n    float maxSpecDiff;\n    float minSpecDiff;\n    //criteria of weight of histogram peak  to accept/reject feature\n    int thresWeightSpecFlat;\n    int thresWeightSpecDiff;\n\n} NSParaExtract_t;\n\ntypedef struct NSinst_t_ {\n\n    WebRtc_UWord32  fs;\n    int             blockLen;\n    int             blockLen10ms;\n    int             windShift;\n    int             outLen;\n    int             anaLen;\n    int             magnLen;\n    int             aggrMode;\n    const float*    window;\n    float           dataBuf[ANAL_BLOCKL_MAX];\n    float           syntBuf[ANAL_BLOCKL_MAX];\n    float           outBuf[3 * BLOCKL_MAX];\n\n    int             initFlag;\n    // parameters for quantile noise estimation\n    float           density[SIMULT * HALF_ANAL_BLOCKL];\n    float           lquantile[SIMULT * HALF_ANAL_BLOCKL];\n    float           quantile[HALF_ANAL_BLOCKL];\n    int             counter[SIMULT];\n    int             updates;\n    // parameters for Wiener filter\n    float           smooth[HALF_ANAL_BLOCKL];\n    float           overdrive;\n    float           denoiseBound;\n    int             gainmap;\n    // fft work arrays.\n    int             ip[IP_LENGTH];\n    float           wfft[W_LENGTH];\n\n    // parameters for new method: some not needed, will reduce/cleanup later\n    WebRtc_Word32   blockInd;                           //frame index counter\n    int             modelUpdatePars[4];                 //parameters for updating or estimating\n                                                        // thresholds/weights for prior model\n    float           priorModelPars[7];                  //parameters for prior model\n    float           noisePrev[HALF_ANAL_BLOCKL];        //noise spectrum from previous frame\n    float           magnPrev[HALF_ANAL_BLOCKL];         //magnitude spectrum of previous frame\n    float           logLrtTimeAvg[HALF_ANAL_BLOCKL];    //log lrt factor with time-smoothing\n    float           priorSpeechProb;                    //prior speech/noise probability\n    float           featureData[7];                     //data for features\n    float           magnAvgPause[HALF_ANAL_BLOCKL];     //conservative noise spectrum estimate\n    float           signalEnergy;                       //energy of magn\n    float           sumMagn;                            //sum of magn\n    float           whiteNoiseLevel;                    //initial noise estimate\n    float           initMagnEst[HALF_ANAL_BLOCKL];      //initial magnitude spectrum estimate\n    float           pinkNoiseNumerator;                 //pink noise parameter: numerator\n    float           pinkNoiseExp;                       //pink noise parameter: power of freq\n    NSParaExtract_t featureExtractionParams;            //parameters for feature extraction\n    //histograms for parameter estimation\n    int             histLrt[HIST_PAR_EST];\n    int             histSpecFlat[HIST_PAR_EST];\n    int             histSpecDiff[HIST_PAR_EST];\n    //quantities for high band estimate\n    float           speechProbHB[HALF_ANAL_BLOCKL];     //final speech/noise prob: prior + LRT\n    float           dataBufHB[ANAL_BLOCKL_MAX];         //buffering data for HB\n\n} NSinst_t;\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/****************************************************************************\n * WebRtcNs_InitCore(...)\n *\n * This function initializes a noise suppression instance\n *\n * Input:\n *      - inst          : Instance that should be initialized\n *      - fs            : Sampling frequency\n *\n * Output:\n *      - inst          : Initialized instance\n *\n * Return value         :  0 - Ok\n *                        -1 - Error\n */\nint WebRtcNs_InitCore(NSinst_t *inst, WebRtc_UWord32 fs);\n\n/****************************************************************************\n * WebRtcNs_set_policy_core(...)\n *\n * This changes the aggressiveness of the noise suppression method.\n *\n * Input:\n *      - inst          : Instance that should be initialized\n *      - mode          : 0: Mild (6 dB), 1: Medium (10 dB), 2: Aggressive (15 dB)\n *\n * Output:\n *      - NS_inst      : Initialized instance\n *\n * Return value         :  0 - Ok\n *                        -1 - Error\n */\nint WebRtcNs_set_policy_core(NSinst_t *inst, int mode);\n\n/****************************************************************************\n * WebRtcNs_ProcessCore\n *\n * Do noise suppression.\n *\n * Input:\n *      - inst          : Instance that should be initialized\n *      - inFrameLow    : Input speech frame for lower band\n *      - inFrameHigh   : Input speech frame for higher band\n *\n * Output:\n *      - inst          : Updated instance\n *      - outFrameLow   : Output speech frame for lower band\n *      - outFrameHigh  : Output speech frame for higher band\n *\n * Return value         :  0 - OK\n *                        -1 - Error\n */\n\n\nint WebRtcNs_ProcessCore(NSinst_t *inst,\n                         short *inFrameLow,\n                         short *inFrameHigh,\n                         short *outFrameLow,\n                         short *outFrameHigh);\n\n\n#ifdef __cplusplus\n}\n#endif\n#endif  // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NS_CORE_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/ns/main/source/nsx_core.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"noise_suppression_x.h\"\n\n#include <assert.h>\n#include <math.h>\n#include <string.h>\n#include <stdlib.h>\n\n#include \"nsx_core.h\"\n\n// Skip first frequency bins during estimation. (0 <= value < 64)\nstatic const int kStartBand = 5;\n\n// Rounding\nstatic const WebRtc_Word16 kRoundTable[16] = {0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024,\n        2048, 4096, 8192, 16384};\n\n// Constants to compensate for shifting signal log(2^shifts).\nconst WebRtc_Word16 WebRtcNsx_kLogTable[9] = {0, 177, 355, 532, 710, 887, 1065, 1242, 1420};\n\nconst WebRtc_Word16 WebRtcNsx_kCounterDiv[201] = {32767, 16384, 10923, 8192, 6554, 5461, 4681,\n        4096, 3641, 3277, 2979, 2731, 2521, 2341, 2185, 2048, 1928, 1820, 1725, 1638, 1560,\n        1489, 1425, 1365, 1311, 1260, 1214, 1170, 1130, 1092, 1057, 1024, 993, 964, 936, 910,\n        886, 862, 840, 819, 799, 780, 762, 745, 728, 712, 697, 683, 669, 655, 643, 630, 618,\n        607, 596, 585, 575, 565, 555, 546, 537, 529, 520, 512, 504, 496, 489, 482, 475, 468,\n        462, 455, 449, 443, 437, 431, 426, 420, 415, 410, 405, 400, 395, 390, 386, 381, 377,\n        372, 368, 364, 360, 356, 352, 349, 345, 341, 338, 334, 331, 328, 324, 321, 318, 315,\n        312, 309, 306, 303, 301, 298, 295, 293, 290, 287, 285, 282, 280, 278, 275, 273, 271,\n        269, 266, 264, 262, 260, 258, 256, 254, 252, 250, 248, 246, 245, 243, 241, 239, 237,\n        236, 234, 232, 231, 229, 228, 226, 224, 223, 221, 220, 218, 217, 216, 214, 213, 211,\n        210, 209, 207, 206, 205, 204, 202, 201, 200, 199, 197, 196, 195, 194, 193, 192, 191,\n        189, 188, 187, 186, 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, 175, 174, 173,\n        172, 172, 171, 170, 169, 168, 167, 166, 165, 165, 164, 163};\n\nconst WebRtc_Word16 WebRtcNsx_kLogTableFrac[256] = {\n      0,   1,   3,   4,   6,   7,   9,  10,  11,  13,  14,  16,  17,  18,  20,  21,\n     22,  24,  25,  26,  28,  29,  30,  32,  33,  34,  36,  37,  38,  40,  41,  42,\n     44,  45,  46,  47,  49,  50,  51,  52,  54,  55,  56,  57,  59,  60,  61,  62,\n     63,  65,  66,  67,  68,  69,  71,  72,  73,  74,  75,  77,  78,  79,  80,  81,\n     82,  84,  85,  86,  87,  88,  89,  90,  92,  93,  94,  95,  96,  97,  98,  99,\n    100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 116, 117,\n    118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,\n    134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,\n    150, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n    165, 166, 167, 168, 169, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 178,\n    179, 180, 181, 182, 183, 184, 185, 185, 186, 187, 188, 189, 190, 191, 192, 192,\n    193, 194, 195, 196, 197, 198, 198, 199, 200, 201, 202, 203, 203, 204, 205, 206,\n    207, 208, 208, 209, 210, 211, 212, 212, 213, 214, 215, 216, 216, 217, 218, 219,\n    220, 220, 221, 222, 223, 224, 224, 225, 226, 227, 228, 228, 229, 230, 231, 231,\n    232, 233, 234, 234, 235, 236, 237, 238, 238, 239, 240, 241, 241, 242, 243, 244,\n    244, 245, 246, 247, 247, 248, 249, 249, 250, 251, 252, 252, 253, 254, 255, 255\n};\n\nstatic const WebRtc_Word16 kPowTableFrac[1024] = {\n    0,    1,    1,    2,    3,    3,    4,    5,\n    6,    6,    7,    8,    8,    9,   10,   10,\n   11,   12,   13,   13,   14,   15,   15,   16,\n   17,   17,   18,   19,   20,   20,   21,   22,\n   22,   23,   24,   25,   25,   26,   27,   27,\n   28,   29,   30,   30,   31,   32,   32,   33,\n   34,   35,   35,   36,   37,   37,   38,   39,\n   40,   40,   41,   42,   42,   43,   44,   45,\n   45,   46,   47,   48,   48,   49,   50,   50,\n   51,   52,   53,   53,   54,   55,   56,   56,\n   57,   58,   58,   59,   60,   61,   61,   62,\n   63,   64,   64,   65,   66,   67,   67,   68,\n   69,   69,   70,   71,   72,   72,   73,   74,\n   75,   75,   76,   77,   78,   78,   79,   80,\n   81,   81,   82,   83,   84,   84,   85,   86,\n   87,   87,   88,   89,   90,   90,   91,   92,\n   93,   93,   94,   95,   96,   96,   97,   98,\n   99,  100,  100,  101,  102,  103,  103,  104,\n  105,  106,  106,  107,  108,  109,  109,  110,\n  111,  112,  113,  113,  114,  115,  116,  116,\n  117,  118,  119,  119,  120,  121,  122,  123,\n  123,  124,  125,  126,  126,  127,  128,  129,\n  130,  130,  131,  132,  133,  133,  134,  135,\n  136,  137,  137,  138,  139,  140,  141,  141,\n  142,  143,  144,  144,  145,  146,  147,  148,\n  148,  149,  150,  151,  152,  152,  153,  154,\n  155,  156,  156,  157,  158,  159,  160,  160,\n  161,  162,  163,  164,  164,  165,  166,  167,\n  168,  168,  169,  170,  171,  172,  173,  173,\n  174,  175,  176,  177,  177,  178,  179,  180,\n  181,  181,  182,  183,  184,  185,  186,  186,\n  187,  188,  189,  190,  190,  191,  192,  193,\n  194,  195,  195,  196,  197,  198,  199,  200,\n  200,  201,  202,  203,  204,  205,  205,  206,\n  207,  208,  209,  210,  210,  211,  212,  213,\n  214,  215,  215,  216,  217,  218,  219,  220,\n  220,  221,  222,  223,  224,  225,  225,  226,\n  227,  228,  229,  230,  231,  231,  232,  233,\n  234,  235,  236,  237,  237,  238,  239,  240,\n  241,  242,  243,  243,  244,  245,  246,  247,\n  248,  249,  249,  250,  251,  252,  253,  254,\n  255,  255,  256,  257,  258,  259,  260,  261,\n  262,  262,  263,  264,  265,  266,  267,  268,\n  268,  269,  270,  271,  272,  273,  274,  275,\n  276,  276,  277,  278,  279,  280,  281,  282,\n  283,  283,  284,  285,  286,  287,  288,  289,\n  290,  291,  291,  292,  293,  294,  295,  296,\n  297,  298,  299,  299,  300,  301,  302,  303,\n  304,  305,  306,  307,  308,  308,  309,  310,\n  311,  312,  313,  314,  315,  316,  317,  318,\n  318,  319,  320,  321,  322,  323,  324,  325,\n  326,  327,  328,  328,  329,  330,  331,  332,\n  333,  334,  335,  336,  337,  338,  339,  339,\n  340,  341,  342,  343,  344,  345,  346,  347,\n  348,  349,  350,  351,  352,  352,  353,  354,\n  355,  356,  357,  358,  359,  360,  361,  362,\n  363,  364,  365,  366,  367,  367,  368,  369,\n  370,  371,  372,  373,  374,  375,  376,  377,\n  378,  379,  380,  381,  382,  383,  384,  385,\n  385,  386,  387,  388,  389,  390,  391,  392,\n  393,  394,  395,  396,  397,  398,  399,  400,\n  401,  402,  403,  404,  405,  406,  407,  408,\n  409,  410,  410,  411,  412,  413,  414,  415,\n  416,  417,  418,  419,  420,  421,  422,  423,\n  424,  425,  426,  427,  428,  429,  430,  431,\n  432,  433,  434,  435,  436,  437,  438,  439,\n  440,  441,  442,  443,  444,  445,  446,  447,\n  448,  449,  450,  451,  452,  453,  454,  455,\n  456,  457,  458,  459,  460,  461,  462,  463,\n  464,  465,  466,  467,  468,  469,  470,  471,\n  472,  473,  474,  475,  476,  477,  478,  479,\n  480,  481,  482,  483,  484,  485,  486,  487,\n  488,  489,  490,  491,  492,  493,  494,  495,\n  496,  498,  499,  500,  501,  502,  503,  504,\n  505,  506,  507,  508,  509,  510,  511,  512,\n  513,  514,  515,  516,  517,  518,  519,  520,\n  521,  522,  523,  525,  526,  527,  528,  529,\n  530,  531,  532,  533,  534,  535,  536,  537,\n  538,  539,  540,  541,  542,  544,  545,  546,\n  547,  548,  549,  550,  551,  552,  553,  554,\n  555,  556,  557,  558,  560,  561,  562,  563,\n  564,  565,  566,  567,  568,  569,  570,  571,\n  572,  574,  575,  576,  577,  578,  579,  580,\n  581,  582,  583,  584,  585,  587,  588,  589,\n  590,  591,  592,  593,  594,  595,  596,  597,\n  599,  600,  601,  602,  603,  604,  605,  606,\n  607,  608,  610,  611,  612,  613,  614,  615,\n  616,  617,  618,  620,  621,  622,  623,  624,\n  625,  626,  627,  628,  630,  631,  632,  633,\n  634,  635,  636,  637,  639,  640,  641,  642,\n  643,  644,  645,  646,  648,  649,  650,  651,\n  652,  653,  654,  656,  657,  658,  659,  660,\n  661,  662,  664,  665,  666,  667,  668,  669,\n  670,  672,  673,  674,  675,  676,  677,  678,\n  680,  681,  682,  683,  684,  685,  687,  688,\n  689,  690,  691,  692,  693,  695,  696,  697,\n  698,  699,  700,  702,  703,  704,  705,  706,\n  708,  709,  710,  711,  712,  713,  715,  716,\n  717,  718,  719,  720,  722,  723,  724,  725,\n  726,  728,  729,  730,  731,  732,  733,  735,\n  736,  737,  738,  739,  741,  742,  743,  744,\n  745,  747,  748,  749,  750,  751,  753,  754,\n  755,  756,  757,  759,  760,  761,  762,  763,\n  765,  766,  767,  768,  770,  771,  772,  773,\n  774,  776,  777,  778,  779,  780,  782,  783,\n  784,  785,  787,  788,  789,  790,  792,  793,\n  794,  795,  796,  798,  799,  800,  801,  803,\n  804,  805,  806,  808,  809,  810,  811,  813,\n  814,  815,  816,  818,  819,  820,  821,  823,\n  824,  825,  826,  828,  829,  830,  831,  833,\n  834,  835,  836,  838,  839,  840,  841,  843,\n  844,  845,  846,  848,  849,  850,  851,  853,\n  854,  855,  857,  858,  859,  860,  862,  863,\n  864,  866,  867,  868,  869,  871,  872,  873,\n  874,  876,  877,  878,  880,  881,  882,  883,\n  885,  886,  887,  889,  890,  891,  893,  894,\n  895,  896,  898,  899,  900,  902,  903,  904,\n  906,  907,  908,  909,  911,  912,  913,  915,\n  916,  917,  919,  920,  921,  923,  924,  925,\n  927,  928,  929,  931,  932,  933,  935,  936,\n  937,  938,  940,  941,  942,  944,  945,  946,\n  948,  949,  950,  952,  953,  955,  956,  957,\n  959,  960,  961,  963,  964,  965,  967,  968,\n  969,  971,  972,  973,  975,  976,  977,  979,\n  980,  981,  983,  984,  986,  987,  988,  990,\n  991,  992,  994,  995,  996,  998,  999, 1001,\n 1002, 1003, 1005, 1006, 1007, 1009, 1010, 1012,\n 1013, 1014, 1016, 1017, 1018, 1020, 1021, 1023\n};\n\nstatic const WebRtc_Word16 kIndicatorTable[17] = {0, 2017, 3809, 5227, 6258, 6963, 7424, 7718,\n        7901, 8014, 8084, 8126, 8152, 8168, 8177, 8183, 8187};\n\n// hybrib Hanning & flat window\nstatic const WebRtc_Word16 kBlocks80w128x[128] = {\n        0,    536,   1072,   1606,   2139,   2669,   3196,   3720,   4240,   4756,   5266,\n     5771,   6270,   6762,   7246,   7723,   8192,   8652,   9102,   9543,   9974,  10394,\n    10803,  11200,  11585,  11958,  12318,  12665,  12998,  13318,  13623,  13913,  14189,\n    14449,  14694,  14924,  15137,  15334,  15515,  15679,  15826,  15956,  16069,  16165,\n    16244,  16305,  16349,  16375,  16384,  16384,  16384,  16384,  16384,  16384,  16384,\n    16384,  16384,  16384,  16384,  16384,  16384,  16384,  16384,  16384,  16384,  16384,\n    16384,  16384,  16384,  16384,  16384,  16384,  16384,  16384,  16384,  16384,  16384,\n    16384,  16384,  16384,  16384,  16375,  16349,  16305,  16244,  16165,  16069,  15956,\n    15826,  15679,  15515,  15334,  15137,  14924,  14694,  14449,  14189,  13913,  13623,\n    13318,  12998,  12665,  12318,  11958,  11585,  11200,  10803,  10394,   9974,   9543,\n     9102,   8652,   8192,   7723,   7246,   6762,   6270,   5771,   5266,   4756,   4240,\n     3720,   3196,   2669,   2139,   1606,   1072,    536\n};\n\n// hybrib Hanning & flat window\nstatic const WebRtc_Word16 kBlocks160w256x[256] = {\n    0,   268,   536,   804,  1072,  1339,  1606,  1872,\n 2139,  2404,  2669,  2933,  3196,  3459,  3720,  3981,\n 4240,  4499,  4756,  5012,  5266,  5520,  5771,  6021,\n 6270,  6517,  6762,  7005,  7246,  7486,  7723,  7959,\n 8192,  8423,  8652,  8878,  9102,  9324,  9543,  9760,\n 9974, 10185, 10394, 10600, 10803, 11003, 11200, 11394,\n11585, 11773, 11958, 12140, 12318, 12493, 12665, 12833,\n12998, 13160, 13318, 13472, 13623, 13770, 13913, 14053,\n14189, 14321, 14449, 14574, 14694, 14811, 14924, 15032,\n15137, 15237, 15334, 15426, 15515, 15599, 15679, 15754,\n15826, 15893, 15956, 16015, 16069, 16119, 16165, 16207,\n16244, 16277, 16305, 16329, 16349, 16364, 16375, 16382,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,\n16384, 16382, 16375, 16364, 16349, 16329, 16305, 16277,\n16244, 16207, 16165, 16119, 16069, 16015, 15956, 15893,\n15826, 15754, 15679, 15599, 15515, 15426, 15334, 15237,\n15137, 15032, 14924, 14811, 14694, 14574, 14449, 14321,\n14189, 14053, 13913, 13770, 13623, 13472, 13318, 13160,\n12998, 12833, 12665, 12493, 12318, 12140, 11958, 11773,\n11585, 11394, 11200, 11003, 10803, 10600, 10394, 10185,\n 9974,  9760,  9543,  9324,  9102,  8878,  8652,  8423,\n 8192,  7959,  7723,  7486,  7246,  7005,  6762,  6517,\n 6270,  6021,  5771,  5520,  5266,  5012,  4756,  4499,\n 4240,  3981,  3720,  3459,  3196,  2933,  2669,  2404,\n 2139,  1872,  1606,  1339,  1072,   804,   536,   268\n};\n\n// Gain factor table: Input value in Q8 and output value in Q13\nstatic const WebRtc_Word16 kFactor1Table[257] = {\n        8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8233, 8274, 8315, 8355, 8396, 8436, 8475, 8515, 8554, 8592, 8631, 8669,\n        8707, 8745, 8783, 8820, 8857, 8894, 8931, 8967, 9003, 9039, 9075, 9111, 9146, 9181,\n        9216, 9251, 9286, 9320, 9354, 9388, 9422, 9456, 9489, 9523, 9556, 9589, 9622, 9655,\n        9687, 9719, 9752, 9784, 9816, 9848, 9879, 9911, 9942, 9973, 10004, 10035, 10066,\n        10097, 10128, 10158, 10188, 10218, 10249, 10279, 10308, 10338, 10368, 10397, 10426,\n        10456, 10485, 10514, 10543, 10572, 10600, 10629, 10657, 10686, 10714, 10742, 10770,\n        10798, 10826, 10854, 10882, 10847, 10810, 10774, 10737, 10701, 10666, 10631, 10596,\n        10562, 10527, 10494, 10460, 10427, 10394, 10362, 10329, 10297, 10266, 10235, 10203,\n        10173, 10142, 10112, 10082, 10052, 10023, 9994, 9965, 9936, 9908, 9879, 9851, 9824,\n        9796, 9769, 9742, 9715, 9689, 9662, 9636, 9610, 9584, 9559, 9534, 9508, 9484, 9459,\n        9434, 9410, 9386, 9362, 9338, 9314, 9291, 9268, 9245, 9222, 9199, 9176, 9154, 9132,\n        9110, 9088, 9066, 9044, 9023, 9002, 8980, 8959, 8939, 8918, 8897, 8877, 8857, 8836,\n        8816, 8796, 8777, 8757, 8738, 8718, 8699, 8680, 8661, 8642, 8623, 8605, 8586, 8568,\n        8550, 8532, 8514, 8496, 8478, 8460, 8443, 8425, 8408, 8391, 8373, 8356, 8339, 8323,\n        8306, 8289, 8273, 8256, 8240, 8224, 8208, 8192\n};\n\n// Gain factor table: Input value in Q8 and output value in Q13\nstatic const WebRtc_Word16 kFactor2Aggressiveness1[257] = {\n        7577, 7577, 7577, 7577, 7577, 7577,\n        7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7596, 7614, 7632,\n        7650, 7667, 7683, 7699, 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845,\n        7858, 7871, 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016,\n        8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, 8152, 8162,\n        8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192\n};\n\n// Gain factor table: Input value in Q8 and output value in Q13\nstatic const WebRtc_Word16 kFactor2Aggressiveness2[257] = {\n        7270, 7270, 7270, 7270, 7270, 7306,\n        7339, 7369, 7397, 7424, 7448, 7472, 7495, 7517, 7537, 7558, 7577, 7596, 7614, 7632,\n        7650, 7667, 7683, 7699, 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845,\n        7858, 7871, 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016,\n        8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, 8152, 8162,\n        8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192\n};\n\n// Gain factor table: Input value in Q8 and output value in Q13\nstatic const WebRtc_Word16 kFactor2Aggressiveness3[257] = {\n        7184, 7184, 7184, 7229, 7270, 7306,\n        7339, 7369, 7397, 7424, 7448, 7472, 7495, 7517, 7537, 7558, 7577, 7596, 7614, 7632,\n        7650, 7667, 7683, 7699, 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845,\n        7858, 7871, 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016,\n        8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, 8152, 8162,\n        8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\n        8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192\n};\n\n// sum of log2(i) from table index to inst->anaLen2 in Q5\n// Note that the first table value is invalid, since log2(0) = -infinity\nstatic const WebRtc_Word16 kSumLogIndex[66] = {\n        0,  22917,  22917,  22885,  22834,  22770,  22696,  22613,\n    22524,  22428,  22326,  22220,  22109,  21994,  21876,  21754,\n    21629,  21501,  21370,  21237,  21101,  20963,  20822,  20679,\n    20535,  20388,  20239,  20089,  19937,  19783,  19628,  19470,\n    19312,  19152,  18991,  18828,  18664,  18498,  18331,  18164,\n    17994,  17824,  17653,  17480,  17306,  17132,  16956,  16779,\n    16602,  16423,  16243,  16063,  15881,  15699,  15515,  15331,\n    15146,  14960,  14774,  14586,  14398,  14209,  14019,  13829,\n    13637,  13445\n};\n\n// sum of log2(i)^2 from table index to inst->anaLen2 in Q2\n// Note that the first table value is invalid, since log2(0) = -infinity\nstatic const WebRtc_Word16 kSumSquareLogIndex[66] = {\n        0,  16959,  16959,  16955,  16945,  16929,  16908,  16881,\n    16850,  16814,  16773,  16729,  16681,  16630,  16575,  16517,\n    16456,  16392,  16325,  16256,  16184,  16109,  16032,  15952,\n    15870,  15786,  15700,  15612,  15521,  15429,  15334,  15238,\n    15140,  15040,  14938,  14834,  14729,  14622,  14514,  14404,\n    14292,  14179,  14064,  13947,  13830,  13710,  13590,  13468,\n    13344,  13220,  13094,  12966,  12837,  12707,  12576,  12444,\n    12310,  12175,  12039,  11902,  11763,  11624,  11483,  11341,\n    11198,  11054\n};\n\n// log2(table index) in Q12\n// Note that the first table value is invalid, since log2(0) = -infinity\nstatic const WebRtc_Word16 kLogIndex[129] = {\n        0,      0,   4096,   6492,   8192,   9511,  10588,  11499,\n    12288,  12984,  13607,  14170,  14684,  15157,  15595,  16003,\n    16384,  16742,  17080,  17400,  17703,  17991,  18266,  18529,\n    18780,  19021,  19253,  19476,  19691,  19898,  20099,  20292,\n    20480,  20662,  20838,  21010,  21176,  21338,  21496,  21649,\n    21799,  21945,  22087,  22226,  22362,  22495,  22625,  22752,\n    22876,  22998,  23117,  23234,  23349,  23462,  23572,  23680,\n    23787,  23892,  23994,  24095,  24195,  24292,  24388,  24483,\n    24576,  24668,  24758,  24847,  24934,  25021,  25106,  25189,\n    25272,  25354,  25434,  25513,  25592,  25669,  25745,  25820,\n    25895,  25968,  26041,  26112,  26183,  26253,  26322,  26390,\n    26458,  26525,  26591,  26656,  26721,  26784,  26848,  26910,\n    26972,  27033,  27094,  27154,  27213,  27272,  27330,  27388,\n    27445,  27502,  27558,  27613,  27668,  27722,  27776,  27830,\n    27883,  27935,  27988,  28039,  28090,  28141,  28191,  28241,\n    28291,  28340,  28388,  28437,  28484,  28532,  28579,  28626,\n    28672\n};\n\n// determinant of estimation matrix in Q0 corresponding to the log2 tables above\n// Note that the first table value is invalid, since log2(0) = -infinity\nstatic const WebRtc_Word16 kDeterminantEstMatrix[66] = {\n        0,  29814,  25574,  22640,  20351,  18469,  16873,  15491,\n    14277,  13199,  12233,  11362,  10571,   9851,   9192,   8587,\n     8030,   7515,   7038,   6596,   6186,   5804,   5448,   5115,\n     4805,   4514,   4242,   3988,   3749,   3524,   3314,   3116,\n     2930,   2755,   2590,   2435,   2289,   2152,   2022,   1900,\n     1785,   1677,   1575,   1478,   1388,   1302,   1221,   1145,\n     1073,   1005,    942,    881,    825,    771,    721,    674,\n      629,    587,    547,    510,    475,    442,    411,    382,\n      355,    330\n};\n\nvoid WebRtcNsx_UpdateNoiseEstimate(NsxInst_t *inst, int offset)\n{\n    WebRtc_Word32 tmp32no1 = 0;\n    WebRtc_Word32 tmp32no2 = 0;\n\n    WebRtc_Word16 tmp16no1 = 0;\n    WebRtc_Word16 tmp16no2 = 0;\n    WebRtc_Word16 exp2Const = 11819; // Q13\n\n    int i = 0;\n\n    tmp16no2 = WebRtcSpl_MaxValueW16(inst->noiseEstLogQuantile + offset, inst->magnLen);\n    inst->qNoise = 14\n            - (int)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(exp2Const, tmp16no2, 21);\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        // inst->quantile[i]=exp(inst->lquantile[offset+i]);\n        // in Q21\n        tmp32no2 = WEBRTC_SPL_MUL_16_16(exp2Const, inst->noiseEstLogQuantile[offset + i]);\n        tmp32no1 = (0x00200000 | (tmp32no2 & 0x001FFFFF));\n        tmp16no1 = -(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no2, 21);\n        tmp16no1 += 21;// shift 21 to get result in Q0\n        tmp16no1 -= (WebRtc_Word16)inst->qNoise; //shift to get result in Q(qNoise)\n        if (tmp16no1 > 0)\n        {\n            inst->noiseEstQuantile[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no1 +\n                                                       kRoundTable[tmp16no1], tmp16no1);\n        }\n        else\n        {\n            inst->noiseEstQuantile[i] = (WebRtc_Word16)WEBRTC_SPL_LSHIFT_W32(tmp32no1,\n                                                                             -tmp16no1);\n        }\n    }\n}\n\nvoid WebRtcNsx_CalcParametricNoiseEstimate(NsxInst_t *inst,\n                                           WebRtc_Word16 pink_noise_exp_avg,\n                                           WebRtc_Word32 pink_noise_num_avg,\n                                           int freq_index,\n                                           WebRtc_UWord32 *noise_estimate,\n                                           WebRtc_UWord32 *noise_estimate_avg)\n{\n    WebRtc_Word32 tmp32no1 = 0;\n    WebRtc_Word32 tmp32no2 = 0;\n\n    WebRtc_Word16 int_part = 0;\n    WebRtc_Word16 frac_part = 0;\n\n    // Use pink noise estimate\n    // noise_estimate = 2^(pinkNoiseNumerator + pinkNoiseExp * log2(j))\n    assert(freq_index > 0);\n    tmp32no2 = WEBRTC_SPL_MUL_16_16(pink_noise_exp_avg, kLogIndex[freq_index]); // Q26\n    tmp32no2 = WEBRTC_SPL_RSHIFT_W32(tmp32no2, 15); // Q11\n    tmp32no1 = pink_noise_num_avg - tmp32no2; // Q11\n\n    // Calculate output: 2^tmp32no1\n    // Output in Q(minNorm-stages)\n    tmp32no1 += WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)(inst->minNorm - inst->stages), 11);\n    if (tmp32no1 > 0)\n    {\n        int_part = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no1, 11);\n        frac_part = (WebRtc_Word16)(tmp32no1 & 0x000007ff); // Q11\n        // Piecewise linear approximation of 'b' in\n        // 2^(int_part+frac_part) = 2^int_part * (1 + b)\n        // 'b' is given in Q11 and below stored in frac_part.\n        if (WEBRTC_SPL_RSHIFT_W32(frac_part, 10))\n        {\n            // Upper fractional part\n            tmp32no2 = WEBRTC_SPL_MUL_32_16(2048 - frac_part, 1244); // Q21\n            tmp32no2 = 2048 - WEBRTC_SPL_RSHIFT_W32(tmp32no2, 10);\n        }\n        else\n        {\n            // Lower fractional part\n            tmp32no2 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_32_16(frac_part, 804), 10);\n        }\n        // Shift fractional part to Q(minNorm-stages)\n        tmp32no2 = WEBRTC_SPL_SHIFT_W32(tmp32no2, int_part - 11);\n        *noise_estimate_avg = WEBRTC_SPL_LSHIFT_U32(1, int_part) + (WebRtc_UWord32)tmp32no2;\n        // Scale up to initMagnEst, which is not block averaged\n        *noise_estimate = (*noise_estimate_avg) * (WebRtc_UWord32)(inst->blockIndex + 1);\n    }\n}\n\n// Initialize state\nWebRtc_Word32 WebRtcNsx_InitCore(NsxInst_t *inst, WebRtc_UWord32 fs)\n{\n    int i;\n\n    //check for valid pointer\n    if (inst == NULL)\n    {\n        return -1;\n    }\n    //\n\n    // Initialization of struct\n    if (fs == 8000 || fs == 16000 || fs == 32000)\n    {\n        inst->fs = fs;\n    } else\n    {\n        return -1;\n    }\n\n    if (fs == 8000)\n    {\n        inst->blockLen10ms = 80;\n        inst->anaLen = 128;\n        inst->stages = 7;\n        inst->window = kBlocks80w128x;\n        inst->thresholdLogLrt = 131072; //default threshold for LRT feature\n        inst->maxLrt = 0x0040000;\n        inst->minLrt = 52429;\n    } else if (fs == 16000)\n    {\n        inst->blockLen10ms = 160;\n        inst->anaLen = 256;\n        inst->stages = 8;\n        inst->window = kBlocks160w256x;\n        inst->thresholdLogLrt = 212644; //default threshold for LRT feature\n        inst->maxLrt = 0x0080000;\n        inst->minLrt = 104858;\n    } else if (fs == 32000)\n    {\n        inst->blockLen10ms = 160;\n        inst->anaLen = 256;\n        inst->stages = 8;\n        inst->window = kBlocks160w256x;\n        inst->thresholdLogLrt = 212644; //default threshold for LRT feature\n        inst->maxLrt = 0x0080000;\n        inst->minLrt = 104858;\n    }\n    inst->anaLen2 = WEBRTC_SPL_RSHIFT_W16(inst->anaLen, 1);\n    inst->magnLen = inst->anaLen2 + 1;\n\n    WebRtcSpl_ZerosArrayW16(inst->analysisBuffer, ANAL_BLOCKL_MAX);\n    WebRtcSpl_ZerosArrayW16(inst->synthesisBuffer, ANAL_BLOCKL_MAX);\n\n    // for HB processing\n    WebRtcSpl_ZerosArrayW16(inst->dataBufHBFX, ANAL_BLOCKL_MAX);\n    // for quantile noise estimation\n    WebRtcSpl_ZerosArrayW16(inst->noiseEstQuantile, HALF_ANAL_BLOCKL);\n    for (i = 0; i < SIMULT * HALF_ANAL_BLOCKL; i++)\n    {\n        inst->noiseEstLogQuantile[i] = 2048; // Q8\n        inst->noiseEstDensity[i] = 153; // Q9\n    }\n    for (i = 0; i < SIMULT; i++)\n    {\n        inst->noiseEstCounter[i] = (WebRtc_Word16)(END_STARTUP_LONG * (i + 1)) / SIMULT;\n    }\n\n    // Initialize suppression filter with ones\n    WebRtcSpl_MemSetW16((WebRtc_Word16*)inst->noiseSupFilter, 16384, HALF_ANAL_BLOCKL);\n\n    // Set the aggressiveness: default\n    inst->aggrMode = 0;\n\n    //initialize variables for new method\n    inst->priorNonSpeechProb = 8192; // Q14(0.5) prior probability for speech/noise\n    for (i = 0; i < HALF_ANAL_BLOCKL; i++)\n    {\n        inst->prevMagnU16[i] = 0;\n        inst->prevNoiseU32[i] = 0; //previous noise-spectrum\n        inst->logLrtTimeAvgW32[i] = 0; //smooth LR ratio\n        inst->avgMagnPause[i] = 0; //conservative noise spectrum estimate\n        inst->initMagnEst[i] = 0; //initial average magnitude spectrum\n    }\n\n    //feature quantities\n    inst->thresholdSpecDiff = 50; //threshold for difference feature: determined on-line\n    inst->thresholdSpecFlat = 20480; //threshold for flatness: determined on-line\n    inst->featureLogLrt = inst->thresholdLogLrt; //average LRT factor (= threshold)\n    inst->featureSpecFlat = inst->thresholdSpecFlat; //spectral flatness (= threshold)\n    inst->featureSpecDiff = inst->thresholdSpecDiff; //spectral difference (= threshold)\n    inst->weightLogLrt = 6; //default weighting par for LRT feature\n    inst->weightSpecFlat = 0; //default weighting par for spectral flatness feature\n    inst->weightSpecDiff = 0; //default weighting par for spectral difference feature\n\n    inst->curAvgMagnEnergy = 0; //window time-average of input magnitude spectrum\n    inst->timeAvgMagnEnergy = 0; //normalization for spectral difference\n    inst->timeAvgMagnEnergyTmp = 0; //normalization for spectral difference\n\n    //histogram quantities: used to estimate/update thresholds for features\n    WebRtcSpl_ZerosArrayW16(inst->histLrt, HIST_PAR_EST);\n    WebRtcSpl_ZerosArrayW16(inst->histSpecDiff, HIST_PAR_EST);\n    WebRtcSpl_ZerosArrayW16(inst->histSpecFlat, HIST_PAR_EST);\n\n    inst->blockIndex = -1; //frame counter\n\n    //inst->modelUpdate    = 500;   //window for update\n    inst->modelUpdate = (1 << STAT_UPDATES); //window for update\n    inst->cntThresUpdate = 0; //counter feature thresholds updates\n\n    inst->sumMagn = 0;\n    inst->magnEnergy = 0;\n    inst->prevQMagn = 0;\n    inst->qNoise = 0;\n    inst->prevQNoise = 0;\n\n    inst->energyIn = 0;\n    inst->scaleEnergyIn = 0;\n\n    inst->whiteNoiseLevel = 0;\n    inst->pinkNoiseNumerator = 0;\n    inst->pinkNoiseExp = 0;\n    inst->minNorm = 15; // Start with full scale\n    inst->zeroInputSignal = 0;\n\n    //default mode\n    WebRtcNsx_set_policy_core(inst, 0);\n\n#ifdef NS_FILEDEBUG\n    inst->infile=fopen(\"indebug.pcm\",\"wb\");\n    inst->outfile=fopen(\"outdebug.pcm\",\"wb\");\n    inst->file1=fopen(\"file1.pcm\",\"wb\");\n    inst->file2=fopen(\"file2.pcm\",\"wb\");\n    inst->file3=fopen(\"file3.pcm\",\"wb\");\n    inst->file4=fopen(\"file4.pcm\",\"wb\");\n    inst->file5=fopen(\"file5.pcm\",\"wb\");\n#endif\n\n    inst->initFlag = 1;\n\n    return 0;\n}\n\nint WebRtcNsx_set_policy_core(NsxInst_t *inst, int mode)\n{\n    // allow for modes:0,1,2,3\n    if (mode < 0 || mode > 3)\n    {\n        return -1;\n    }\n\n    inst->aggrMode = mode;\n    if (mode == 0)\n    {\n        inst->overdrive = 256; // Q8(1.0)\n        inst->denoiseBound = 8192; // Q14(0.5)\n        inst->gainMap = 0; // No gain compensation\n    } else if (mode == 1)\n    {\n        inst->overdrive = 256; // Q8(1.0)\n        inst->denoiseBound = 4096; // Q14(0.25)\n        inst->factor2Table = kFactor2Aggressiveness1;\n        inst->gainMap = 1;\n    } else if (mode == 2)\n    {\n        inst->overdrive = 282; // ~= Q8(1.1)\n        inst->denoiseBound = 2048; // Q14(0.125)\n        inst->factor2Table = kFactor2Aggressiveness2;\n        inst->gainMap = 1;\n    } else if (mode == 3)\n    {\n        inst->overdrive = 320; // Q8(1.25)\n        inst->denoiseBound = 1475; // ~= Q14(0.09)\n        inst->factor2Table = kFactor2Aggressiveness3;\n        inst->gainMap = 1;\n    }\n    return 0;\n}\n\n#if !(defined(WEBRTC_ARCH_ARM_NEON) && defined(WEBRTC_ANDROID))\nvoid WebRtcNsx_NoiseEstimation(NsxInst_t *inst, WebRtc_UWord16 *magn, WebRtc_UWord32 *noise,\n                               WebRtc_Word16 *qNoise)\n{\n    WebRtc_Word32 numerator;\n\n    WebRtc_Word16 lmagn[HALF_ANAL_BLOCKL], counter, countDiv, countProd, delta, zeros, frac;\n    WebRtc_Word16 log2, tabind, logval, tmp16, tmp16no1, tmp16no2;\n    WebRtc_Word16 log2Const = 22713; // Q15\n    WebRtc_Word16 widthFactor = 21845;\n\n    int i, s, offset;\n\n    numerator = FACTOR_Q16;\n\n    tabind = inst->stages - inst->normData;\n    if (tabind < 0)\n    {\n        logval = -WebRtcNsx_kLogTable[-tabind];\n    } else\n    {\n        logval = WebRtcNsx_kLogTable[tabind];\n    }\n\n    // lmagn(i)=log(magn(i))=log(2)*log2(magn(i))\n    // magn is in Q(-stages), and the real lmagn values are:\n    // real_lmagn(i)=log(magn(i)*2^stages)=log(magn(i))+log(2^stages)\n    // lmagn in Q8\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        if (magn[i])\n        {\n            zeros = WebRtcSpl_NormU32((WebRtc_UWord32)magn[i]);\n            frac = (WebRtc_Word16)((((WebRtc_UWord32)magn[i] << zeros) & 0x7FFFFFFF) >> 23);\n            // log2(magn(i))\n            log2 = (WebRtc_Word16)(((31 - zeros) << 8) + WebRtcNsx_kLogTableFrac[frac]);\n            // log2(magn(i))*log(2)\n            lmagn[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(log2, log2Const, 15);\n            // + log(2^stages)\n            lmagn[i] += logval;\n        } else\n        {\n            lmagn[i] = logval;//0;\n        }\n    }\n\n    // loop over simultaneous estimates\n    for (s = 0; s < SIMULT; s++)\n    {\n        offset = s * inst->magnLen;\n\n        // Get counter values from state\n        counter = inst->noiseEstCounter[s];\n        countDiv = WebRtcNsx_kCounterDiv[counter];\n        countProd = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(counter, countDiv);\n\n        // quant_est(...)\n        for (i = 0; i < inst->magnLen; i++)\n        {\n            // compute delta\n            if (inst->noiseEstDensity[offset + i] > 512)\n            {\n                delta = WebRtcSpl_DivW32W16ResW16(numerator,\n                                                  inst->noiseEstDensity[offset + i]);\n            } else\n            {\n                delta = FACTOR_Q7;\n            }\n\n            // update log quantile estimate\n            tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(delta, countDiv, 14);\n            if (lmagn[i] > inst->noiseEstLogQuantile[offset + i])\n            {\n                // +=QUANTILE*delta/(inst->counter[s]+1) QUANTILE=0.25, =1 in Q2\n                // CounterDiv=1/inst->counter[s] in Q15\n                tmp16 += 2;\n                tmp16no1 = WEBRTC_SPL_RSHIFT_W16(tmp16, 2);\n                inst->noiseEstLogQuantile[offset + i] += tmp16no1;\n            } else\n            {\n                tmp16 += 1;\n                tmp16no1 = WEBRTC_SPL_RSHIFT_W16(tmp16, 1);\n                // *(1-QUANTILE), in Q2 QUANTILE=0.25, 1-0.25=0.75=3 in Q2\n                tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16no1, 3, 1);\n                inst->noiseEstLogQuantile[offset + i] -= tmp16no2;\n            }\n\n            // update density estimate\n            if (WEBRTC_SPL_ABS_W16(lmagn[i] - inst->noiseEstLogQuantile[offset + i])\n                    < WIDTH_Q8)\n            {\n                tmp16no1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(\n                        inst->noiseEstDensity[offset + i], countProd, 15);\n                tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(widthFactor,\n                                                                               countDiv, 15);\n                inst->noiseEstDensity[offset + i] = tmp16no1 + tmp16no2;\n            }\n        } // end loop over magnitude spectrum\n\n        if (counter >= END_STARTUP_LONG)\n        {\n            inst->noiseEstCounter[s] = 0;\n            if (inst->blockIndex >= END_STARTUP_LONG)\n            {\n                WebRtcNsx_UpdateNoiseEstimate(inst, offset);\n            }\n        }\n        inst->noiseEstCounter[s]++;\n\n    } // end loop over simultaneous estimates\n\n    // Sequentially update the noise during startup\n    if (inst->blockIndex < END_STARTUP_LONG)\n    {\n        WebRtcNsx_UpdateNoiseEstimate(inst, offset);\n    }\n\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        noise[i] = (WebRtc_UWord32)(inst->noiseEstQuantile[i]); // Q(qNoise)\n    }\n    (*qNoise) = (WebRtc_Word16)inst->qNoise;\n}\n#endif  // !(defined(WEBRTC_ARCH_ARM_NEON) && defined(WEBRTC_ANDROID))\n\n// Extract thresholds for feature parameters\n// histograms are computed over some window_size (given by window_pars)\n// thresholds and weights are extracted every window\n// flag 0 means update histogram only, flag 1 means compute the thresholds/weights\n// threshold and weights are returned in: inst->priorModelPars\nvoid WebRtcNsx_FeatureParameterExtraction(NsxInst_t *inst, int flag)\n{\n    WebRtc_UWord32 tmpU32;\n    WebRtc_UWord32 histIndex;\n    WebRtc_UWord32 posPeak1SpecFlatFX, posPeak2SpecFlatFX;\n    WebRtc_UWord32 posPeak1SpecDiffFX, posPeak2SpecDiffFX;\n\n    WebRtc_Word32 tmp32;\n    WebRtc_Word32 fluctLrtFX, thresFluctLrtFX;\n    WebRtc_Word32 avgHistLrtFX, avgSquareHistLrtFX, avgHistLrtComplFX;\n\n    WebRtc_Word16 j;\n    WebRtc_Word16 numHistLrt;\n\n    int i;\n    int useFeatureSpecFlat, useFeatureSpecDiff, featureSum;\n    int maxPeak1, maxPeak2;\n    int weightPeak1SpecFlat, weightPeak2SpecFlat;\n    int weightPeak1SpecDiff, weightPeak2SpecDiff;\n\n    //update histograms\n    if (!flag)\n    {\n        // LRT\n        // Type casting to UWord32 is safe since negative values will not be wrapped to larger\n        // values than HIST_PAR_EST\n        histIndex = (WebRtc_UWord32)(inst->featureLogLrt);\n        if (histIndex < HIST_PAR_EST)\n        {\n            inst->histLrt[histIndex]++;\n        }\n        // Spectral flatness\n        // (inst->featureSpecFlat*20)>>10 = (inst->featureSpecFlat*5)>>8\n        histIndex = WEBRTC_SPL_RSHIFT_U32(inst->featureSpecFlat * 5, 8);\n        if (histIndex < HIST_PAR_EST)\n        {\n            inst->histSpecFlat[histIndex]++;\n        }\n        // Spectral difference\n        histIndex = HIST_PAR_EST;\n        if (inst->timeAvgMagnEnergy)\n        {\n            // Guard against division by zero\n            // If timeAvgMagnEnergy == 0 we have no normalizing statistics and therefore can't\n            // update the histogram\n            histIndex = WEBRTC_SPL_UDIV((inst->featureSpecDiff * 5) >> inst->stages,\n                                        inst->timeAvgMagnEnergy);\n        }\n        if (histIndex < HIST_PAR_EST)\n        {\n            inst->histSpecDiff[histIndex]++;\n        }\n    }\n\n    // extract parameters for speech/noise probability\n    if (flag)\n    {\n        useFeatureSpecDiff = 1;\n        //for LRT feature:\n        // compute the average over inst->featureExtractionParams.rangeAvgHistLrt\n        avgHistLrtFX = 0;\n        avgSquareHistLrtFX = 0;\n        numHistLrt = 0;\n        for (i = 0; i < BIN_SIZE_LRT; i++)\n        {\n            j = (2 * i + 1);\n            tmp32 = WEBRTC_SPL_MUL_16_16(inst->histLrt[i], j);\n            avgHistLrtFX += tmp32;\n            numHistLrt += inst->histLrt[i];\n            avgSquareHistLrtFX += WEBRTC_SPL_MUL_32_16(tmp32, j);\n        }\n        avgHistLrtComplFX = avgHistLrtFX;\n        for (; i < HIST_PAR_EST; i++)\n        {\n            j = (2 * i + 1);\n            tmp32 = WEBRTC_SPL_MUL_16_16(inst->histLrt[i], j);\n            avgHistLrtComplFX += tmp32;\n            avgSquareHistLrtFX += WEBRTC_SPL_MUL_32_16(tmp32, j);\n        }\n        fluctLrtFX = WEBRTC_SPL_MUL(avgSquareHistLrtFX, numHistLrt);\n        fluctLrtFX -= WEBRTC_SPL_MUL(avgHistLrtFX, avgHistLrtComplFX);\n        thresFluctLrtFX = THRES_FLUCT_LRT * numHistLrt;\n        // get threshold for LRT feature:\n        tmpU32 = (FACTOR_1_LRT_DIFF * (WebRtc_UWord32)avgHistLrtFX);\n        if ((fluctLrtFX < thresFluctLrtFX) || (numHistLrt == 0) || (tmpU32\n                > (WebRtc_UWord32)(100 * numHistLrt)))\n        {\n            inst->thresholdLogLrt = inst->maxLrt; //very low fluctuation, so likely noise\n        } else\n        {\n            tmp32 = (WebRtc_Word32)((tmpU32 << (9 + inst->stages)) / numHistLrt / 25);\n            // check if value is within min/max range\n            inst->thresholdLogLrt = WEBRTC_SPL_SAT(inst->maxLrt, tmp32, inst->minLrt);\n        }\n        if (fluctLrtFX < thresFluctLrtFX)\n        {\n            // Do not use difference feature if fluctuation of LRT feature is very low:\n            // most likely just noise state\n            useFeatureSpecDiff = 0;\n        }\n\n        // for spectral flatness and spectral difference: compute the main peaks of histogram\n        maxPeak1 = 0;\n        maxPeak2 = 0;\n        posPeak1SpecFlatFX = 0;\n        posPeak2SpecFlatFX = 0;\n        weightPeak1SpecFlat = 0;\n        weightPeak2SpecFlat = 0;\n\n        // peaks for flatness\n        for (i = 0; i < HIST_PAR_EST; i++)\n        {\n            if (inst->histSpecFlat[i] > maxPeak1)\n            {\n                // Found new \"first\" peak\n                maxPeak2 = maxPeak1;\n                weightPeak2SpecFlat = weightPeak1SpecFlat;\n                posPeak2SpecFlatFX = posPeak1SpecFlatFX;\n\n                maxPeak1 = inst->histSpecFlat[i];\n                weightPeak1SpecFlat = inst->histSpecFlat[i];\n                posPeak1SpecFlatFX = (WebRtc_UWord32)(2 * i + 1);\n            } else if (inst->histSpecFlat[i] > maxPeak2)\n            {\n                // Found new \"second\" peak\n                maxPeak2 = inst->histSpecFlat[i];\n                weightPeak2SpecFlat = inst->histSpecFlat[i];\n                posPeak2SpecFlatFX = (WebRtc_UWord32)(2 * i + 1);\n            }\n        }\n\n        // for spectral flatness feature\n        useFeatureSpecFlat = 1;\n        // merge the two peaks if they are close\n        if ((posPeak1SpecFlatFX - posPeak2SpecFlatFX < LIM_PEAK_SPACE_FLAT_DIFF)\n                && (weightPeak2SpecFlat * LIM_PEAK_WEIGHT_FLAT_DIFF > weightPeak1SpecFlat))\n        {\n            weightPeak1SpecFlat += weightPeak2SpecFlat;\n            posPeak1SpecFlatFX = (posPeak1SpecFlatFX + posPeak2SpecFlatFX) >> 1;\n        }\n        //reject if weight of peaks is not large enough, or peak value too small\n        if (weightPeak1SpecFlat < THRES_WEIGHT_FLAT_DIFF || posPeak1SpecFlatFX\n                < THRES_PEAK_FLAT)\n        {\n            useFeatureSpecFlat = 0;\n        } else // if selected, get the threshold\n        {\n            // compute the threshold and check if value is within min/max range\n            inst->thresholdSpecFlat = WEBRTC_SPL_SAT(MAX_FLAT_Q10, FACTOR_2_FLAT_Q10\n                                                     * posPeak1SpecFlatFX, MIN_FLAT_Q10); //Q10\n        }\n        // done with flatness feature\n\n        if (useFeatureSpecDiff)\n        {\n            //compute two peaks for spectral difference\n            maxPeak1 = 0;\n            maxPeak2 = 0;\n            posPeak1SpecDiffFX = 0;\n            posPeak2SpecDiffFX = 0;\n            weightPeak1SpecDiff = 0;\n            weightPeak2SpecDiff = 0;\n            // peaks for spectral difference\n            for (i = 0; i < HIST_PAR_EST; i++)\n            {\n                if (inst->histSpecDiff[i] > maxPeak1)\n                {\n                    // Found new \"first\" peak\n                    maxPeak2 = maxPeak1;\n                    weightPeak2SpecDiff = weightPeak1SpecDiff;\n                    posPeak2SpecDiffFX = posPeak1SpecDiffFX;\n\n                    maxPeak1 = inst->histSpecDiff[i];\n                    weightPeak1SpecDiff = inst->histSpecDiff[i];\n                    posPeak1SpecDiffFX = (WebRtc_UWord32)(2 * i + 1);\n                } else if (inst->histSpecDiff[i] > maxPeak2)\n                {\n                    // Found new \"second\" peak\n                    maxPeak2 = inst->histSpecDiff[i];\n                    weightPeak2SpecDiff = inst->histSpecDiff[i];\n                    posPeak2SpecDiffFX = (WebRtc_UWord32)(2 * i + 1);\n                }\n            }\n\n            // merge the two peaks if they are close\n            if ((posPeak1SpecDiffFX - posPeak2SpecDiffFX < LIM_PEAK_SPACE_FLAT_DIFF)\n                    && (weightPeak2SpecDiff * LIM_PEAK_WEIGHT_FLAT_DIFF > weightPeak1SpecDiff))\n            {\n                weightPeak1SpecDiff += weightPeak2SpecDiff;\n                posPeak1SpecDiffFX = (posPeak1SpecDiffFX + posPeak2SpecDiffFX) >> 1;\n            }\n            // get the threshold value and check if value is within min/max range\n            inst->thresholdSpecDiff = WEBRTC_SPL_SAT(MAX_DIFF, FACTOR_1_LRT_DIFF\n                                                     * posPeak1SpecDiffFX, MIN_DIFF); //5x bigger\n            //reject if weight of peaks is not large enough\n            if (weightPeak1SpecDiff < THRES_WEIGHT_FLAT_DIFF)\n            {\n                useFeatureSpecDiff = 0;\n            }\n            // done with spectral difference feature\n        }\n\n        // select the weights between the features\n        // inst->priorModelPars[4] is weight for LRT: always selected\n        featureSum = 6 / (1 + useFeatureSpecFlat + useFeatureSpecDiff);\n        inst->weightLogLrt = featureSum;\n        inst->weightSpecFlat = useFeatureSpecFlat * featureSum;\n        inst->weightSpecDiff = useFeatureSpecDiff * featureSum;\n\n        // set histograms to zero for next update\n        WebRtcSpl_ZerosArrayW16(inst->histLrt, HIST_PAR_EST);\n        WebRtcSpl_ZerosArrayW16(inst->histSpecDiff, HIST_PAR_EST);\n        WebRtcSpl_ZerosArrayW16(inst->histSpecFlat, HIST_PAR_EST);\n    } // end of flag == 1\n}\n\n\n// Compute spectral flatness on input spectrum\n// magn is the magnitude spectrum\n// spectral flatness is returned in inst->featureSpecFlat\nvoid WebRtcNsx_ComputeSpectralFlatness(NsxInst_t *inst, WebRtc_UWord16 *magn)\n{\n    WebRtc_UWord32 tmpU32;\n    WebRtc_UWord32 avgSpectralFlatnessNum, avgSpectralFlatnessDen;\n\n    WebRtc_Word32 tmp32;\n    WebRtc_Word32 currentSpectralFlatness, logCurSpectralFlatness;\n\n    WebRtc_Word16 zeros, frac, intPart;\n\n    int i;\n\n    // for flatness\n    avgSpectralFlatnessNum = 0;\n    avgSpectralFlatnessDen = inst->sumMagn - (WebRtc_UWord32)magn[0]; // Q(normData-stages)\n\n    // compute log of ratio of the geometric to arithmetic mean: check for log(0) case\n    // flatness = exp( sum(log(magn[i]))/N - log(sum(magn[i])/N) )\n    //          = exp( sum(log(magn[i]))/N ) * N / sum(magn[i])\n    //          = 2^( sum(log2(magn[i]))/N - (log2(sum(magn[i])) - log2(N)) ) [This is used]\n    for (i = 1; i < inst->magnLen; i++)\n    {\n        // First bin is excluded from spectrum measures. Number of bins is now a power of 2\n        if (magn[i])\n        {\n            zeros = WebRtcSpl_NormU32((WebRtc_UWord32)magn[i]);\n            frac = (WebRtc_Word16)(((WebRtc_UWord32)((WebRtc_UWord32)(magn[i]) << zeros)\n                    & 0x7FFFFFFF) >> 23);\n            // log2(magn(i))\n            tmpU32 = (WebRtc_UWord32)(((31 - zeros) << 8) \n                                      + WebRtcNsx_kLogTableFrac[frac]); // Q8\n            avgSpectralFlatnessNum += tmpU32; // Q8\n        } else\n        {\n            //if at least one frequency component is zero, treat separately\n            tmpU32 = WEBRTC_SPL_UMUL_32_16(inst->featureSpecFlat, SPECT_FLAT_TAVG_Q14); // Q24\n            inst->featureSpecFlat -= WEBRTC_SPL_RSHIFT_U32(tmpU32, 14); // Q10\n            return;\n        }\n    }\n    //ratio and inverse log: check for case of log(0)\n    zeros = WebRtcSpl_NormU32(avgSpectralFlatnessDen);\n    frac = (WebRtc_Word16)(((avgSpectralFlatnessDen << zeros) & 0x7FFFFFFF) >> 23);\n    // log2(avgSpectralFlatnessDen)\n    tmp32 = (WebRtc_Word32)(((31 - zeros) << 8) + WebRtcNsx_kLogTableFrac[frac]); // Q8\n    logCurSpectralFlatness = (WebRtc_Word32)avgSpectralFlatnessNum;\n    logCurSpectralFlatness += ((WebRtc_Word32)(inst->stages - 1) << (inst->stages + 7)); // Q(8+stages-1)\n    logCurSpectralFlatness -= (tmp32 << (inst->stages - 1));\n    logCurSpectralFlatness = WEBRTC_SPL_LSHIFT_W32(logCurSpectralFlatness, 10 - inst->stages); // Q17\n    tmp32 = (WebRtc_Word32)(0x00020000 | (WEBRTC_SPL_ABS_W32(logCurSpectralFlatness)\n            & 0x0001FFFF)); //Q17\n    intPart = -(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(logCurSpectralFlatness, 17);\n    intPart += 7; // Shift 7 to get the output in Q10 (from Q17 = -17+10)\n    if (intPart > 0)\n    {\n        currentSpectralFlatness = WEBRTC_SPL_RSHIFT_W32(tmp32, intPart);\n    } else\n    {\n        currentSpectralFlatness = WEBRTC_SPL_LSHIFT_W32(tmp32, -intPart);\n    }\n\n    //time average update of spectral flatness feature\n    tmp32 = currentSpectralFlatness - (WebRtc_Word32)inst->featureSpecFlat; // Q10\n    tmp32 = WEBRTC_SPL_MUL_32_16(SPECT_FLAT_TAVG_Q14, tmp32); // Q24\n    inst->featureSpecFlat = (WebRtc_UWord32)((WebRtc_Word32)inst->featureSpecFlat\n            + WEBRTC_SPL_RSHIFT_W32(tmp32, 14)); // Q10\n    // done with flatness feature\n}\n\n\n// Compute the difference measure between input spectrum and a template/learned noise spectrum\n// magn_tmp is the input spectrum\n// the reference/template spectrum is  inst->magn_avg_pause[i]\n// returns (normalized) spectral difference in inst->featureSpecDiff\nvoid WebRtcNsx_ComputeSpectralDifference(NsxInst_t *inst, WebRtc_UWord16 *magnIn)\n{\n    // This is to be calculated:\n    // avgDiffNormMagn = var(magnIn) - cov(magnIn, magnAvgPause)^2 / var(magnAvgPause)\n\n    WebRtc_UWord32 tmpU32no1, tmpU32no2;\n    WebRtc_UWord32 varMagnUFX, varPauseUFX, avgDiffNormMagnUFX;\n\n    WebRtc_Word32 tmp32no1, tmp32no2;\n    WebRtc_Word32 avgPauseFX, avgMagnFX, covMagnPauseFX;\n    WebRtc_Word32 maxPause, minPause;\n\n    WebRtc_Word16 tmp16no1;\n\n    int i, norm32, nShifts;\n\n    avgPauseFX = 0;\n    maxPause = 0;\n    minPause = inst->avgMagnPause[0]; // Q(prevQMagn)\n    // compute average quantities\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        // Compute mean of magn_pause\n        avgPauseFX += inst->avgMagnPause[i]; // in Q(prevQMagn)\n        maxPause = WEBRTC_SPL_MAX(maxPause, inst->avgMagnPause[i]);\n        minPause = WEBRTC_SPL_MIN(minPause, inst->avgMagnPause[i]);\n    }\n    // normalize by replacing div of \"inst->magnLen\" with \"inst->stages-1\" shifts\n    avgPauseFX = WEBRTC_SPL_RSHIFT_W32(avgPauseFX, inst->stages - 1);\n    avgMagnFX = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_U32(inst->sumMagn, inst->stages - 1);\n    // Largest possible deviation in magnPause for (co)var calculations\n    tmp32no1 = WEBRTC_SPL_MAX(maxPause - avgPauseFX, avgPauseFX - minPause);\n    // Get number of shifts to make sure we don't get wrap around in varPause\n    nShifts = WEBRTC_SPL_MAX(0, 10 + inst->stages - WebRtcSpl_NormW32(tmp32no1));\n\n    varMagnUFX = 0;\n    varPauseUFX = 0;\n    covMagnPauseFX = 0;\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        // Compute var and cov of magn and magn_pause\n        tmp16no1 = (WebRtc_Word16)((WebRtc_Word32)magnIn[i] - avgMagnFX);\n        tmp32no2 = inst->avgMagnPause[i] - avgPauseFX;\n        varMagnUFX += (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(tmp16no1, tmp16no1); // Q(2*qMagn)\n        tmp32no1 = WEBRTC_SPL_MUL_32_16(tmp32no2, tmp16no1); // Q(prevQMagn+qMagn)\n        covMagnPauseFX += tmp32no1; // Q(prevQMagn+qMagn)\n        tmp32no1 = WEBRTC_SPL_RSHIFT_W32(tmp32no2, nShifts); // Q(prevQMagn-minPause)\n        varPauseUFX += (WebRtc_UWord32)WEBRTC_SPL_MUL(tmp32no1, tmp32no1); // Q(2*(prevQMagn-minPause))\n    }\n    //update of average magnitude spectrum: Q(-2*stages) and averaging replaced by shifts\n    inst->curAvgMagnEnergy += WEBRTC_SPL_RSHIFT_U32(inst->magnEnergy, 2 * inst->normData\n                                                    + inst->stages - 1);\n\n    avgDiffNormMagnUFX = varMagnUFX; // Q(2*qMagn)\n    if ((varPauseUFX) && (covMagnPauseFX))\n    {\n        tmpU32no1 = (WebRtc_UWord32)WEBRTC_SPL_ABS_W32(covMagnPauseFX); // Q(prevQMagn+qMagn)\n        norm32 = WebRtcSpl_NormU32(tmpU32no1) - 16;\n        if (norm32 > 0)\n        {\n            tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(tmpU32no1, norm32); // Q(prevQMagn+qMagn+norm32)\n        } else\n        {\n            tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, -norm32); // Q(prevQMagn+qMagn+norm32)\n        }\n        tmpU32no2 = WEBRTC_SPL_UMUL(tmpU32no1, tmpU32no1); // Q(2*(prevQMagn+qMagn-norm32))\n\n        nShifts += norm32;\n        nShifts <<= 1;\n        if (nShifts < 0)\n        {\n            varPauseUFX >>= (-nShifts); // Q(2*(qMagn+norm32+minPause))\n            nShifts = 0;\n        }\n        tmpU32no1 = WEBRTC_SPL_UDIV(tmpU32no2, varPauseUFX); // Q(2*(qMagn+norm32-16+minPause))\n        tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, nShifts);\n\n        avgDiffNormMagnUFX -= WEBRTC_SPL_MIN(avgDiffNormMagnUFX, tmpU32no1); // Q(2*qMagn)\n    }\n    //normalize and compute time average update of difference feature\n    tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(avgDiffNormMagnUFX, 2 * inst->normData);\n    if (inst->featureSpecDiff > tmpU32no1)\n    {\n        tmpU32no2 = WEBRTC_SPL_UMUL_32_16(inst->featureSpecDiff - tmpU32no1,\n                                          SPECT_DIFF_TAVG_Q8); // Q(8-2*stages)\n        inst->featureSpecDiff -= WEBRTC_SPL_RSHIFT_U32(tmpU32no2, 8); // Q(-2*stages)\n    } else\n    {\n        tmpU32no2 = WEBRTC_SPL_UMUL_32_16(tmpU32no1 - inst->featureSpecDiff,\n                                          SPECT_DIFF_TAVG_Q8); // Q(8-2*stages)\n        inst->featureSpecDiff += WEBRTC_SPL_RSHIFT_U32(tmpU32no2, 8); // Q(-2*stages)\n    }\n}\n\n// Compute speech/noise probability\n// speech/noise probability is returned in: probSpeechFinal\n//snrLocPrior is the prior SNR for each frequency (in Q11)\n//snrLocPost is the post SNR for each frequency (in Q11)\nvoid WebRtcNsx_SpeechNoiseProb(NsxInst_t *inst, WebRtc_UWord16 *nonSpeechProbFinal,\n                               WebRtc_UWord32 *priorLocSnr, WebRtc_UWord32 *postLocSnr)\n{\n    WebRtc_UWord32 zeros, num, den, tmpU32no1, tmpU32no2, tmpU32no3;\n\n    WebRtc_Word32 invLrtFX, indPriorFX, tmp32, tmp32no1, tmp32no2, besselTmpFX32;\n    WebRtc_Word32 frac32, logTmp;\n    WebRtc_Word32 logLrtTimeAvgKsumFX;\n\n    WebRtc_Word16 indPriorFX16;\n    WebRtc_Word16 tmp16, tmp16no1, tmp16no2, tmpIndFX, tableIndex, frac, intPart;\n\n    int i, normTmp, normTmp2, nShifts;\n\n    // compute feature based on average LR factor\n    // this is the average over all frequencies of the smooth log LRT\n    logLrtTimeAvgKsumFX = 0;\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        besselTmpFX32 = (WebRtc_Word32)postLocSnr[i]; // Q11\n        normTmp = WebRtcSpl_NormU32(postLocSnr[i]);\n        num = WEBRTC_SPL_LSHIFT_U32(postLocSnr[i], normTmp); // Q(11+normTmp)\n        if (normTmp > 10)\n        {\n            den = WEBRTC_SPL_LSHIFT_U32(priorLocSnr[i], normTmp - 11); // Q(normTmp)\n        } else\n        {\n            den = WEBRTC_SPL_RSHIFT_U32(priorLocSnr[i], 11 - normTmp); // Q(normTmp)\n        }\n        besselTmpFX32 -= WEBRTC_SPL_UDIV(num, den); // Q11\n\n        // inst->logLrtTimeAvg[i] += LRT_TAVG * (besselTmp - log(snrLocPrior) - inst->logLrtTimeAvg[i]);\n        // Here, LRT_TAVG = 0.5\n        zeros = WebRtcSpl_NormU32(priorLocSnr[i]);\n        frac32 = (WebRtc_Word32)(((priorLocSnr[i] << zeros) & 0x7FFFFFFF) >> 19);\n        tmp32 = WEBRTC_SPL_MUL(frac32, frac32);\n        tmp32 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(tmp32, -43), 19);\n        tmp32 += WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16)frac32, 5412, 12);\n        frac32 = tmp32 + 37;\n        // tmp32 = log2(priorLocSnr[i])\n        tmp32 = (WebRtc_Word32)(((31 - zeros) << 12) + frac32) - (11 << 12); // Q12\n        logTmp = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_32_16(tmp32, 178), 8); // log2(priorLocSnr[i])*log(2)\n        tmp32no1 = WEBRTC_SPL_RSHIFT_W32(logTmp + inst->logLrtTimeAvgW32[i], 1); // Q12\n        inst->logLrtTimeAvgW32[i] += (besselTmpFX32 - tmp32no1); // Q12\n\n        logLrtTimeAvgKsumFX += inst->logLrtTimeAvgW32[i]; // Q12\n    }\n    inst->featureLogLrt = WEBRTC_SPL_RSHIFT_W32(logLrtTimeAvgKsumFX * 5, inst->stages + 10); // 5 = BIN_SIZE_LRT / 2\n    // done with computation of LR factor\n\n    //\n    //compute the indicator functions\n    //\n\n    // average LRT feature\n    // FLOAT code\n    // indicator0 = 0.5 * (tanh(widthPrior * (logLrtTimeAvgKsum - threshPrior0)) + 1.0);\n    tmpIndFX = 16384; // Q14(1.0)\n    tmp32no1 = logLrtTimeAvgKsumFX - inst->thresholdLogLrt; // Q12\n    nShifts = 7 - inst->stages; // WIDTH_PR_MAP_SHIFT - inst->stages + 5;\n    //use larger width in tanh map for pause regions\n    if (tmp32no1 < 0)\n    {\n        tmpIndFX = 0;\n        tmp32no1 = -tmp32no1;\n        //widthPrior = widthPrior * 2.0;\n        nShifts++;\n    }\n    tmp32no1 = WEBRTC_SPL_SHIFT_W32(tmp32no1, nShifts); // Q14\n    // compute indicator function: sigmoid map\n    tableIndex = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no1, 14);\n    if ((tableIndex < 16) && (tableIndex >= 0))\n    {\n        tmp16no2 = kIndicatorTable[tableIndex];\n        tmp16no1 = kIndicatorTable[tableIndex + 1] - kIndicatorTable[tableIndex];\n        frac = (WebRtc_Word16)(tmp32no1 & 0x00003fff); // Q14\n        tmp16no2 += (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16no1, frac, 14);\n        if (tmpIndFX == 0)\n        {\n            tmpIndFX = 8192 - tmp16no2; // Q14\n        } else\n        {\n            tmpIndFX = 8192 + tmp16no2; // Q14\n        }\n    }\n    indPriorFX = WEBRTC_SPL_MUL_16_16(inst->weightLogLrt, tmpIndFX); // 6*Q14\n\n    //spectral flatness feature\n    if (inst->weightSpecFlat)\n    {\n        tmpU32no1 = WEBRTC_SPL_UMUL(inst->featureSpecFlat, 400); // Q10\n        tmpIndFX = 16384; // Q14(1.0)\n        //use larger width in tanh map for pause regions\n        tmpU32no2 = inst->thresholdSpecFlat - tmpU32no1; //Q10\n        nShifts = 4;\n        if (inst->thresholdSpecFlat < tmpU32no1)\n        {\n            tmpIndFX = 0;\n            tmpU32no2 = tmpU32no1 - inst->thresholdSpecFlat;\n            //widthPrior = widthPrior * 2.0;\n            nShifts++;\n        }\n        tmp32no1 = (WebRtc_Word32)WebRtcSpl_DivU32U16(WEBRTC_SPL_LSHIFT_U32(tmpU32no2,\n                                                                            nShifts), 25); //Q14\n        tmpU32no1 = WebRtcSpl_DivU32U16(WEBRTC_SPL_LSHIFT_U32(tmpU32no2, nShifts), 25); //Q14\n        // compute indicator function: sigmoid map\n        // FLOAT code\n        // indicator1 = 0.5 * (tanh(sgnMap * widthPrior * (threshPrior1 - tmpFloat1)) + 1.0);\n        tableIndex = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(tmpU32no1, 14);\n        if (tableIndex < 16)\n        {\n            tmp16no2 = kIndicatorTable[tableIndex];\n            tmp16no1 = kIndicatorTable[tableIndex + 1] - kIndicatorTable[tableIndex];\n            frac = (WebRtc_Word16)(tmpU32no1 & 0x00003fff); // Q14\n            tmp16no2 += (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16no1, frac, 14);\n            if (tmpIndFX)\n            {\n                tmpIndFX = 8192 + tmp16no2; // Q14\n            } else\n            {\n                tmpIndFX = 8192 - tmp16no2; // Q14\n            }\n        }\n        indPriorFX += WEBRTC_SPL_MUL_16_16(inst->weightSpecFlat, tmpIndFX); // 6*Q14\n    }\n\n    //for template spectral-difference\n    if (inst->weightSpecDiff)\n    {\n        tmpU32no1 = 0;\n        if (inst->featureSpecDiff)\n        {\n            normTmp = WEBRTC_SPL_MIN(20 - inst->stages,\n                                     WebRtcSpl_NormU32(inst->featureSpecDiff));\n            tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(inst->featureSpecDiff, normTmp); // Q(normTmp-2*stages)\n            tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(inst->timeAvgMagnEnergy, 20 - inst->stages\n                                              - normTmp);\n            if (tmpU32no2)\n            {\n                tmpU32no1 = WEBRTC_SPL_UDIV(tmpU32no1, tmpU32no2); // Q14?? Q(20 - inst->stages)\n            } else\n            {\n                tmpU32no1 = (WebRtc_UWord32)(0x7fffffff);\n            }\n        }\n        tmpU32no3 = WEBRTC_SPL_UDIV(WEBRTC_SPL_LSHIFT_U32(inst->thresholdSpecDiff, 17), 25);\n        tmpU32no2 = tmpU32no1 - tmpU32no3;\n        nShifts = 1;\n        tmpIndFX = 16384; // Q14(1.0)\n        //use larger width in tanh map for pause regions\n        if (tmpU32no2 & 0x80000000)\n        {\n            tmpIndFX = 0;\n            tmpU32no2 = tmpU32no3 - tmpU32no1;\n            //widthPrior = widthPrior * 2.0;\n            nShifts--;\n        }\n        tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no2, nShifts);\n        // compute indicator function: sigmoid map\n        /* FLOAT code\n         indicator2 = 0.5 * (tanh(widthPrior * (tmpFloat1 - threshPrior2)) + 1.0);\n         */\n        tableIndex = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(tmpU32no1, 14);\n        if (tableIndex < 16)\n        {\n            tmp16no2 = kIndicatorTable[tableIndex];\n            tmp16no1 = kIndicatorTable[tableIndex + 1] - kIndicatorTable[tableIndex];\n            frac = (WebRtc_Word16)(tmpU32no1 & 0x00003fff); // Q14\n            tmp16no2 += (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(tmp16no1, frac,\n                                                                            14);\n            if (tmpIndFX)\n            {\n                tmpIndFX = 8192 + tmp16no2;\n            } else\n            {\n                tmpIndFX = 8192 - tmp16no2;\n            }\n        }\n        indPriorFX += WEBRTC_SPL_MUL_16_16(inst->weightSpecDiff, tmpIndFX); // 6*Q14\n    }\n\n    //combine the indicator function with the feature weights\n    // FLOAT code\n    // indPrior = 1 - (weightIndPrior0 * indicator0 + weightIndPrior1 * indicator1 + weightIndPrior2 * indicator2);\n    indPriorFX16 = WebRtcSpl_DivW32W16ResW16(98307 - indPriorFX, 6); // Q14\n    // done with computing indicator function\n\n    //compute the prior probability\n    // FLOAT code\n    // inst->priorNonSpeechProb += PRIOR_UPDATE * (indPriorNonSpeech - inst->priorNonSpeechProb);\n    tmp16 = indPriorFX16 - inst->priorNonSpeechProb; // Q14\n    inst->priorNonSpeechProb += (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(PRIOR_UPDATE_Q14,\n                                                                         tmp16, 14); // Q14\n\n    //final speech probability: combine prior model with LR factor:\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        // FLOAT code\n        // invLrt = exp(inst->logLrtTimeAvg[i]);\n        // invLrt = inst->priorSpeechProb * invLrt;\n        // nonSpeechProbFinal[i] = (1.0 - inst->priorSpeechProb) / (1.0 - inst->priorSpeechProb + invLrt);\n        // invLrt = (1.0 - inst->priorNonSpeechProb) * invLrt;\n        // nonSpeechProbFinal[i] = inst->priorNonSpeechProb / (inst->priorNonSpeechProb + invLrt);\n        nonSpeechProbFinal[i] = 0; // Q8\n        if ((inst->logLrtTimeAvgW32[i] < 65300) && (inst->priorNonSpeechProb > 0))\n        {\n            tmp32no1 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(inst->logLrtTimeAvgW32[i], 23637),\n                                             14); // Q12\n            intPart = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no1, 12);\n            if (intPart < -8)\n            {\n                intPart = -8;\n            }\n            frac = (WebRtc_Word16)(tmp32no1 & 0x00000fff); // Q12\n            // Quadratic approximation of 2^frac\n            tmp32no2 = WEBRTC_SPL_RSHIFT_W32(frac * frac * 44, 19); // Q12\n            tmp32no2 += WEBRTC_SPL_MUL_16_16_RSFT(frac, 84, 7); // Q12\n            invLrtFX = WEBRTC_SPL_LSHIFT_W32(1, 8 + intPart)\n                    + WEBRTC_SPL_SHIFT_W32(tmp32no2, intPart - 4); // Q8\n\n            normTmp = WebRtcSpl_NormW32(invLrtFX);\n            normTmp2 = WebRtcSpl_NormW16((16384 - inst->priorNonSpeechProb));\n            if (normTmp + normTmp2 < 15)\n            {\n                invLrtFX = WEBRTC_SPL_RSHIFT_W32(invLrtFX, 15 - normTmp2 - normTmp); // Q(normTmp+normTmp2-7)\n                tmp32no1 = WEBRTC_SPL_MUL_32_16(invLrtFX, (16384 - inst->priorNonSpeechProb)); // Q(normTmp+normTmp2+7)\n                invLrtFX = WEBRTC_SPL_SHIFT_W32(tmp32no1, 7 - normTmp - normTmp2); // Q14\n            } else\n            {\n                tmp32no1 = WEBRTC_SPL_MUL_32_16(invLrtFX, (16384 - inst->priorNonSpeechProb)); // Q22\n                invLrtFX = WEBRTC_SPL_RSHIFT_W32(tmp32no1, 8); // Q14\n            }\n\n            tmp32no1 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inst->priorNonSpeechProb, 8); // Q22\n            nonSpeechProbFinal[i] = (WebRtc_UWord16)WEBRTC_SPL_DIV(tmp32no1,\n                    (WebRtc_Word32)inst->priorNonSpeechProb\n                    + invLrtFX); // Q8\n            if (7 - normTmp - normTmp2 > 0)\n            {\n                nonSpeechProbFinal[i] = 0; // Q8\n            }\n        }\n    }\n}\n\n// Transform input (speechFrame) to frequency domain magnitude (magnU16)\nvoid WebRtcNsx_DataAnalysis(NsxInst_t *inst, short *speechFrame, WebRtc_UWord16 *magnU16)\n{\n\n    WebRtc_UWord32 tmpU32no1, tmpU32no2;\n\n    WebRtc_Word32   tmp_1_w32 = 0;\n    WebRtc_Word32   tmp_2_w32 = 0;\n    WebRtc_Word32   sum_log_magn = 0;\n    WebRtc_Word32   sum_log_i_log_magn = 0;\n\n    WebRtc_UWord16  sum_log_magn_u16 = 0;\n    WebRtc_UWord16  tmp_u16 = 0;\n\n    WebRtc_Word16   sum_log_i = 0;\n    WebRtc_Word16   sum_log_i_square = 0;\n    WebRtc_Word16   frac = 0;\n    WebRtc_Word16   log2 = 0;\n    WebRtc_Word16   matrix_determinant = 0;\n    WebRtc_Word16   winData[ANAL_BLOCKL_MAX], maxWinData;\n    WebRtc_Word16   realImag[ANAL_BLOCKL_MAX << 1];\n\n    int i, j;\n    int outCFFT;\n    int zeros;\n    int net_norm = 0;\n    int right_shifts_in_magnU16 = 0;\n    int right_shifts_in_initMagnEst = 0;\n\n    // For lower band do all processing\n    // update analysis buffer for L band\n    WEBRTC_SPL_MEMCPY_W16(inst->analysisBuffer, inst->analysisBuffer + inst->blockLen10ms,\n                          inst->anaLen - inst->blockLen10ms);\n    WEBRTC_SPL_MEMCPY_W16(inst->analysisBuffer + inst->anaLen - inst->blockLen10ms,\n                          speechFrame, inst->blockLen10ms);\n\n    // Window data before FFT\n    for (i = 0; i < inst->anaLen; i++)\n    {\n        winData[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(inst->window[i],\n                inst->analysisBuffer[i],\n                14); // Q0\n    }\n    // Get input energy\n    inst->energyIn = WebRtcSpl_Energy(winData, (int)inst->anaLen, &(inst->scaleEnergyIn));\n\n    // Reset zero input flag\n    inst->zeroInputSignal = 0;\n    // Acquire norm for winData\n    maxWinData = WebRtcSpl_MaxAbsValueW16(winData, inst->anaLen);\n    inst->normData = WebRtcSpl_NormW16(maxWinData);\n    if (maxWinData == 0)\n    {\n        // Treat zero input separately.\n        inst->zeroInputSignal = 1;\n        return;\n    }\n\n    // Determine the net normalization in the frequency domain\n    net_norm = inst->stages - inst->normData;\n    // Track lowest normalization factor and use it to prevent wrap around in shifting\n    right_shifts_in_magnU16 = inst->normData - inst->minNorm;\n    right_shifts_in_initMagnEst = WEBRTC_SPL_MAX(-right_shifts_in_magnU16, 0);\n    inst->minNorm -= right_shifts_in_initMagnEst;\n    right_shifts_in_magnU16 = WEBRTC_SPL_MAX(right_shifts_in_magnU16, 0);\n\n    // create realImag as winData interleaved with zeros (= imag. part), normalize it\n    for (i = 0; i < inst->anaLen; i++)\n    {\n        j = WEBRTC_SPL_LSHIFT_W16(i, 1);\n        realImag[j] = WEBRTC_SPL_LSHIFT_W16(winData[i], inst->normData); // Q(normData)\n        realImag[j + 1] = 0; // Insert zeros in imaginary part\n    }\n\n    // bit-reverse position of elements in array and FFT the array\n    WebRtcSpl_ComplexBitReverse(realImag, inst->stages); // Q(normData-stages)\n    outCFFT = WebRtcSpl_ComplexFFT(realImag, inst->stages, 1);\n\n    inst->imag[0] = 0; // Q(normData-stages)\n    inst->imag[inst->anaLen2] = 0;\n    inst->real[0] = realImag[0]; // Q(normData-stages)\n    inst->real[inst->anaLen2] = realImag[inst->anaLen];\n    // Q(2*(normData-stages))\n    inst->magnEnergy = (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(inst->real[0], inst->real[0]);\n    inst->magnEnergy += (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(inst->real[inst->anaLen2],\n                                                             inst->real[inst->anaLen2]);\n    magnU16[0] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(inst->real[0]); // Q(normData-stages)\n    magnU16[inst->anaLen2] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(inst->real[inst->anaLen2]);\n    inst->sumMagn = (WebRtc_UWord32)magnU16[0]; // Q(normData-stages)\n    inst->sumMagn += (WebRtc_UWord32)magnU16[inst->anaLen2];\n\n    // Gather information during startup for noise parameter estimation\n    if (inst->blockIndex < END_STARTUP_SHORT)\n    {\n        // Switch initMagnEst to Q(minNorm-stages)\n        inst->initMagnEst[0] = WEBRTC_SPL_RSHIFT_U32(inst->initMagnEst[0],\n                                                     right_shifts_in_initMagnEst);\n        inst->initMagnEst[inst->anaLen2] =\n                WEBRTC_SPL_RSHIFT_U32(inst->initMagnEst[inst->anaLen2],\n                                      right_shifts_in_initMagnEst); // Q(minNorm-stages)\n\n        // Shift magnU16 to same domain as initMagnEst\n        tmpU32no1 = WEBRTC_SPL_RSHIFT_W32((WebRtc_UWord32)magnU16[0],\n                                          right_shifts_in_magnU16); // Q(minNorm-stages)\n        tmpU32no2 = WEBRTC_SPL_RSHIFT_W32((WebRtc_UWord32)magnU16[inst->anaLen2],\n                                          right_shifts_in_magnU16); // Q(minNorm-stages)\n\n        // Update initMagnEst\n        inst->initMagnEst[0] += tmpU32no1; // Q(minNorm-stages)\n        inst->initMagnEst[inst->anaLen2] += tmpU32no2; // Q(minNorm-stages)\n\n        log2 = 0;\n        if (magnU16[inst->anaLen2])\n        {\n            // Calculate log2(magnU16[inst->anaLen2])\n            zeros = WebRtcSpl_NormU32((WebRtc_UWord32)magnU16[inst->anaLen2]);\n            frac = (WebRtc_Word16)((((WebRtc_UWord32)magnU16[inst->anaLen2] << zeros) &\n                    0x7FFFFFFF) >> 23); // Q8\n            // log2(magnU16(i)) in Q8\n            log2 = (WebRtc_Word16)(((31 - zeros) << 8) + WebRtcNsx_kLogTableFrac[frac]);\n        }\n\n        sum_log_magn = (WebRtc_Word32)log2; // Q8\n        // sum_log_i_log_magn in Q17\n        sum_log_i_log_magn = (WEBRTC_SPL_MUL_16_16(kLogIndex[inst->anaLen2], log2) >> 3);\n    }\n\n    for (i = 1; i < inst->anaLen2; i++)\n    {\n        j = WEBRTC_SPL_LSHIFT_W16(i, 1);\n        inst->real[i] = realImag[j];\n        inst->imag[i] = -realImag[j + 1];\n        // magnitude spectrum\n        // energy in Q(2*(normData-stages))\n        tmpU32no1 = (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(realImag[j], realImag[j]);\n        tmpU32no1 += (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(realImag[j + 1], realImag[j + 1]);\n        inst->magnEnergy += tmpU32no1; // Q(2*(normData-stages))\n\n        magnU16[i] = (WebRtc_UWord16)WebRtcSpl_Sqrt(tmpU32no1); // Q(normData-stages)\n        inst->sumMagn += (WebRtc_UWord32)magnU16[i]; // Q(normData-stages)\n        if (inst->blockIndex < END_STARTUP_SHORT)\n        {\n            // Switch initMagnEst to Q(minNorm-stages)\n            inst->initMagnEst[i] = WEBRTC_SPL_RSHIFT_U32(inst->initMagnEst[i],\n                                                         right_shifts_in_initMagnEst);\n\n            // Shift magnU16 to same domain as initMagnEst, i.e., Q(minNorm-stages)\n            tmpU32no1 = WEBRTC_SPL_RSHIFT_W32((WebRtc_UWord32)magnU16[i],\n                                              right_shifts_in_magnU16);\n            // Update initMagnEst\n            inst->initMagnEst[i] += tmpU32no1; // Q(minNorm-stages)\n\n            if (i >= kStartBand)\n            {\n                // For pink noise estimation. Collect data neglecting lower frequency band\n                log2 = 0;\n                if (magnU16[i])\n                {\n                    zeros = WebRtcSpl_NormU32((WebRtc_UWord32)magnU16[i]);\n                    frac = (WebRtc_Word16)((((WebRtc_UWord32)magnU16[i] << zeros) &\n                            0x7FFFFFFF) >> 23);\n                    // log2(magnU16(i)) in Q8\n                    log2 = (WebRtc_Word16)(((31 - zeros) << 8) \n                                           + WebRtcNsx_kLogTableFrac[frac]);\n                }\n                sum_log_magn += (WebRtc_Word32)log2; // Q8\n                // sum_log_i_log_magn in Q17\n                sum_log_i_log_magn += (WEBRTC_SPL_MUL_16_16(kLogIndex[i], log2) >> 3);\n            }\n        }\n    }\n\n    //compute simplified noise model during startup\n    if (inst->blockIndex < END_STARTUP_SHORT)\n    {\n        // Estimate White noise\n        // Switch whiteNoiseLevel to Q(minNorm-stages)\n        inst->whiteNoiseLevel = WEBRTC_SPL_RSHIFT_U32(inst->whiteNoiseLevel,\n                                                      right_shifts_in_initMagnEst);\n\n        // Update the average magnitude spectrum, used as noise estimate.\n        tmpU32no1 = WEBRTC_SPL_UMUL_32_16(inst->sumMagn, inst->overdrive);\n        tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, inst->stages + 8);\n\n        // Replacing division above with 'stages' shifts\n        // Shift to same Q-domain as whiteNoiseLevel\n        tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, right_shifts_in_magnU16);\n        // This operation is safe from wrap around as long as END_STARTUP_SHORT < 128\n        assert(END_STARTUP_SHORT < 128);\n        inst->whiteNoiseLevel += tmpU32no1; // Q(minNorm-stages)\n\n        // Estimate Pink noise parameters\n        // Denominator used in both parameter estimates.\n        // The value is only dependent on the size of the frequency band (kStartBand)\n        // and to reduce computational complexity stored in a table (kDeterminantEstMatrix[])\n        matrix_determinant = kDeterminantEstMatrix[kStartBand]; // Q0\n        sum_log_i = kSumLogIndex[kStartBand]; // Q5\n        sum_log_i_square = kSumSquareLogIndex[kStartBand]; // Q2\n        if (inst->fs == 8000)\n        {\n            // Adjust values to shorter blocks in narrow band.\n            tmp_1_w32 = (WebRtc_Word32)matrix_determinant;\n            tmp_1_w32 += WEBRTC_SPL_MUL_16_16_RSFT(kSumLogIndex[65], sum_log_i, 9);\n            tmp_1_w32 -= WEBRTC_SPL_MUL_16_16_RSFT(kSumLogIndex[65], kSumLogIndex[65], 10);\n            tmp_1_w32 -= WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)sum_log_i_square, 4);\n            tmp_1_w32 -= WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16)(inst->magnLen\n                    - kStartBand), kSumSquareLogIndex[65], 2);\n            matrix_determinant = (WebRtc_Word16)tmp_1_w32;\n            sum_log_i -= kSumLogIndex[65]; // Q5\n            sum_log_i_square -= kSumSquareLogIndex[65]; // Q2\n        }\n\n        // Necessary number of shifts to fit sum_log_magn in a word16\n        zeros = 16 - WebRtcSpl_NormW32(sum_log_magn);\n        if (zeros < 0)\n        {\n            zeros = 0;\n        }\n        tmp_1_w32 = WEBRTC_SPL_LSHIFT_W32(sum_log_magn, 1); // Q9\n        sum_log_magn_u16 = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_W32(tmp_1_w32, zeros);//Q(9-zeros)\n\n        // Calculate and update pinkNoiseNumerator. Result in Q11.\n        tmp_2_w32 = WEBRTC_SPL_MUL_16_U16(sum_log_i_square, sum_log_magn_u16); // Q(11-zeros)\n        tmpU32no1 = WEBRTC_SPL_RSHIFT_U32((WebRtc_UWord32)sum_log_i_log_magn, 12); // Q5\n\n        // Shift the largest value of sum_log_i and tmp32no3 before multiplication\n        tmp_u16 = WEBRTC_SPL_LSHIFT_U16((WebRtc_UWord16)sum_log_i, 1); // Q6\n        if ((WebRtc_UWord32)sum_log_i > tmpU32no1)\n        {\n            tmp_u16 = WEBRTC_SPL_RSHIFT_U16(tmp_u16, zeros);\n        }\n        else\n        {\n            tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, zeros);\n        }\n        tmp_2_w32 -= (WebRtc_Word32)WEBRTC_SPL_UMUL_32_16(tmpU32no1, tmp_u16); // Q(11-zeros)\n        matrix_determinant = WEBRTC_SPL_RSHIFT_W16(matrix_determinant, zeros); // Q(-zeros)\n        tmp_2_w32 = WebRtcSpl_DivW32W16(tmp_2_w32, matrix_determinant); // Q11\n        tmp_2_w32 += WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)net_norm, 11); // Q11\n        if (tmp_2_w32 < 0)\n        {\n            tmp_2_w32 = 0;\n        }\n        inst->pinkNoiseNumerator += tmp_2_w32; // Q11\n\n        // Calculate and update pinkNoiseExp. Result in Q14.\n        tmp_2_w32 = WEBRTC_SPL_MUL_16_U16(sum_log_i, sum_log_magn_u16); // Q(14-zeros)\n        tmp_1_w32 = WEBRTC_SPL_RSHIFT_W32(sum_log_i_log_magn, 3 + zeros);\n        tmp_1_w32 = WEBRTC_SPL_MUL((WebRtc_Word32)(inst->magnLen - kStartBand),\n                                   tmp_1_w32);\n        tmp_2_w32 -= tmp_1_w32; // Q(14-zeros)\n        if (tmp_2_w32 > 0)\n        {\n            // If the exponential parameter is negative force it to zero, which means a\n            // flat spectrum.\n            tmp_1_w32 = WebRtcSpl_DivW32W16(tmp_2_w32, matrix_determinant); // Q14\n            inst->pinkNoiseExp += WEBRTC_SPL_SAT(16384, tmp_1_w32, 0); // Q14\n        }\n    }\n}\n\nvoid WebRtcNsx_DataSynthesis(NsxInst_t *inst, short *outFrame)\n{\n    WebRtc_Word32 tmp32no1;\n    WebRtc_Word32 energyOut;\n\n    WebRtc_Word16 realImag[ANAL_BLOCKL_MAX << 1];\n    WebRtc_Word16 tmp16no1, tmp16no2;\n    WebRtc_Word16 energyRatio;\n    WebRtc_Word16 gainFactor, gainFactor1, gainFactor2;\n\n    int i, j;\n    int outCIFFT;\n    int scaleEnergyOut = 0;\n\n    if (inst->zeroInputSignal)\n    {\n        // synthesize the special case of zero input\n        // read out fully processed segment\n        for (i = 0; i < inst->blockLen10ms; i++)\n        {\n            outFrame[i] = inst->synthesisBuffer[i]; // Q0\n        }\n        // update synthesis buffer\n        WEBRTC_SPL_MEMCPY_W16(inst->synthesisBuffer,\n                              inst->synthesisBuffer + inst->blockLen10ms,\n                              inst->anaLen - inst->blockLen10ms);\n        WebRtcSpl_ZerosArrayW16(inst->synthesisBuffer + inst->anaLen - inst->blockLen10ms,\n                                inst->blockLen10ms);\n        return;\n    }\n    // Filter the data in the frequency domain\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        inst->real[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(inst->real[i],\n                (WebRtc_Word16)(inst->noiseSupFilter[i]), 14); // Q(normData-stages)\n        inst->imag[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(inst->imag[i],\n                (WebRtc_Word16)(inst->noiseSupFilter[i]), 14); // Q(normData-stages)\n    }\n    // back to time domain\n    // Create spectrum\n    realImag[0] = inst->real[0];\n    realImag[1] = -inst->imag[0];\n    for (i = 1; i < inst->anaLen2; i++)\n    {\n        j = WEBRTC_SPL_LSHIFT_W16(i, 1);\n        tmp16no1 = (inst->anaLen << 1) - j;\n        realImag[j] = inst->real[i];\n        realImag[j + 1] = -inst->imag[i];\n        realImag[tmp16no1] = inst->real[i];\n        realImag[tmp16no1 + 1] = inst->imag[i];\n    }\n    realImag[inst->anaLen] = inst->real[inst->anaLen2];\n    realImag[inst->anaLen + 1] = -inst->imag[inst->anaLen2];\n\n    // bit-reverse position of elements in array and IFFT it\n    WebRtcSpl_ComplexBitReverse(realImag, inst->stages);\n    outCIFFT = WebRtcSpl_ComplexIFFT(realImag, inst->stages, 1);\n\n    for (i = 0; i < inst->anaLen; i++)\n    {\n        j = WEBRTC_SPL_LSHIFT_W16(i, 1);\n        tmp32no1 = WEBRTC_SPL_SHIFT_W32((WebRtc_Word32)realImag[j], outCIFFT - inst->normData);\n        inst->real[i] = (WebRtc_Word16)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, tmp32no1,\n                                                      WEBRTC_SPL_WORD16_MIN);\n    }\n\n    //scale factor: only do it after END_STARTUP_LONG time\n    gainFactor = 8192; // 8192 = Q13(1.0)\n    if (inst->gainMap == 1 &&\n        inst->blockIndex > END_STARTUP_LONG &&\n        inst->energyIn > 0)\n    {\n        energyOut = WebRtcSpl_Energy(inst->real, (int)inst->anaLen, &scaleEnergyOut); // Q(-scaleEnergyOut)\n        if (scaleEnergyOut == 0 && !(energyOut & 0x7f800000))\n        {\n            energyOut = WEBRTC_SPL_SHIFT_W32(energyOut, 8 + scaleEnergyOut\n                                             - inst->scaleEnergyIn);\n        } else\n        {\n            inst->energyIn = WEBRTC_SPL_RSHIFT_W32(inst->energyIn, 8 + scaleEnergyOut\n                                                   - inst->scaleEnergyIn); // Q(-8-scaleEnergyOut)\n        }\n\n        assert(inst->energyIn > 0);\n        energyRatio = (WebRtc_Word16)WEBRTC_SPL_DIV(energyOut\n                + WEBRTC_SPL_RSHIFT_W32(inst->energyIn, 1), inst->energyIn); // Q8\n\n        //         // original FLOAT code\n        //         if (gain > blim) {\n        //         factor1=1.0+1.3*(gain-blim);\n        //         if (gain*factor1 > 1.0) { // FLOAT\n        //         factor1 = 1.0/gain; // FLOAT\n        //         }\n        //         }\n        //         else {\n        //         factor1=1.0; // FLOAT\n        //         }\n        //\n        //         if (gain > blim) {\n        //         factor2=1.0; //FLOAT\n        //         }\n        //         else {\n        //         //don't reduce scale too much for pause regions: attenuation here should be controlled by flooring\n        //         factor2=1.0-0.3*(blim-gain); // FLOAT\n        //         if (gain <= inst->denoiseBound) {\n        //         factor2=1.0-0.3*(blim-inst->denoiseBound); // FLOAT\n        //         }\n        //         }\n\n        // all done in lookup tables now\n        gainFactor1 = kFactor1Table[energyRatio]; // Q8\n        gainFactor2 = inst->factor2Table[energyRatio]; // Q8\n\n        //combine both scales with speech/noise prob: note prior (priorSpeechProb) is not frequency dependent\n\n        // factor = inst->priorSpeechProb*factor1 + (1.0-inst->priorSpeechProb)*factor2; // original code\n        tmp16no1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(16384 - inst->priorNonSpeechProb,\n                                                            gainFactor1, 14); // Q13 16384 = Q14(1.0)\n        tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(inst->priorNonSpeechProb,\n                                                            gainFactor2, 14); // Q13;\n        gainFactor = tmp16no1 + tmp16no2; // Q13\n    } // out of flag_gain_map==1\n\n    // synthesis\n    for (i = 0; i < inst->anaLen; i++)\n    {\n        tmp16no1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(inst->window[i],\n                                                                       inst->real[i], 14); // Q0, window in Q14\n        tmp32no1 = WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(tmp16no1, gainFactor, 13); // Q0\n        // Down shift with rounding\n        tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, tmp32no1,\n                                                 WEBRTC_SPL_WORD16_MIN); // Q0\n        inst->synthesisBuffer[i] = WEBRTC_SPL_ADD_SAT_W16(inst->synthesisBuffer[i], tmp16no2); // Q0\n    }\n\n    // read out fully processed segment\n    for (i = 0; i < inst->blockLen10ms; i++)\n    {\n        outFrame[i] = inst->synthesisBuffer[i]; // Q0\n    }\n    // update synthesis buffer\n    WEBRTC_SPL_MEMCPY_W16(inst->synthesisBuffer, inst->synthesisBuffer + inst->blockLen10ms,\n                          inst->anaLen - inst->blockLen10ms);\n    WebRtcSpl_ZerosArrayW16(inst->synthesisBuffer + inst->anaLen - inst->blockLen10ms,\n                            inst->blockLen10ms);\n}\n\nint WebRtcNsx_ProcessCore(NsxInst_t *inst, short *speechFrame, short *speechFrameHB,\n                          short *outFrame, short *outFrameHB)\n{\n    // main routine for noise suppression\n\n    WebRtc_UWord32 tmpU32no1, tmpU32no2, tmpU32no3;\n    WebRtc_UWord32 satMax, maxNoiseU32;\n    WebRtc_UWord32 tmpMagnU32, tmpNoiseU32;\n    WebRtc_UWord32 nearMagnEst;\n    WebRtc_UWord32 noiseUpdateU32;\n    WebRtc_UWord32 noiseU32[HALF_ANAL_BLOCKL];\n    WebRtc_UWord32 postLocSnr[HALF_ANAL_BLOCKL];\n    WebRtc_UWord32 priorLocSnr[HALF_ANAL_BLOCKL];\n    WebRtc_UWord32 prevNearSnr[HALF_ANAL_BLOCKL];\n    WebRtc_UWord32 curNearSnr;\n    WebRtc_UWord32 priorSnr;\n    WebRtc_UWord32 noise_estimate = 0;\n    WebRtc_UWord32 noise_estimate_avg = 0;\n    WebRtc_UWord32 numerator = 0;\n\n    WebRtc_Word32 tmp32no1, tmp32no2;\n    WebRtc_Word32 pink_noise_num_avg = 0;\n\n    WebRtc_UWord16 tmpU16no1;\n    WebRtc_UWord16 magnU16[HALF_ANAL_BLOCKL];\n    WebRtc_UWord16 prevNoiseU16[HALF_ANAL_BLOCKL];\n    WebRtc_UWord16 nonSpeechProbFinal[HALF_ANAL_BLOCKL];\n    WebRtc_UWord16 gammaNoise, prevGammaNoise;\n    WebRtc_UWord16 noiseSupFilterTmp[HALF_ANAL_BLOCKL];\n\n    WebRtc_Word16 qMagn, qNoise;\n    WebRtc_Word16 avgProbSpeechHB, gainModHB, avgFilterGainHB, gainTimeDomainHB;\n    WebRtc_Word16 pink_noise_exp_avg = 0;\n\n    int i;\n    int nShifts, postShifts;\n    int norm32no1, norm32no2;\n    int flag, sign;\n    int q_domain_to_use = 0;\n\n#ifdef NS_FILEDEBUG\n    fwrite(spframe, sizeof(short), inst->blockLen10ms, inst->infile);\n#endif\n\n    // Check that initialization has been done\n    if (inst->initFlag != 1)\n    {\n        return -1;\n    }\n    // Check for valid pointers based on sampling rate\n    if ((inst->fs == 32000) && (speechFrameHB == NULL))\n    {\n        return -1;\n    }\n\n    // Store speechFrame and transform to frequency domain\n    WebRtcNsx_DataAnalysis(inst, speechFrame, magnU16);\n\n    if (inst->zeroInputSignal)\n    {\n        WebRtcNsx_DataSynthesis(inst, outFrame);\n\n        if (inst->fs == 32000)\n        {\n            // update analysis buffer for H band\n            // append new data to buffer FX\n            WEBRTC_SPL_MEMCPY_W16(inst->dataBufHBFX, inst->dataBufHBFX + inst->blockLen10ms,\n                                  inst->anaLen - inst->blockLen10ms);\n            WEBRTC_SPL_MEMCPY_W16(inst->dataBufHBFX + inst->anaLen - inst->blockLen10ms,\n                                  speechFrameHB, inst->blockLen10ms);\n            for (i = 0; i < inst->blockLen10ms; i++)\n            {\n                outFrameHB[i] = inst->dataBufHBFX[i]; // Q0\n            }\n        } // end of H band gain computation\n        return 0;\n    }\n\n    // Update block index when we have something to process\n    inst->blockIndex++;\n    //\n\n    // Norm of magn\n    qMagn = inst->normData - inst->stages;\n\n    // Compute spectral flatness on input spectrum\n    WebRtcNsx_ComputeSpectralFlatness(inst, magnU16);\n\n    // quantile noise estimate\n    WebRtcNsx_NoiseEstimation(inst, magnU16, noiseU32, &qNoise);\n\n    //noise estimate from previous frame\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        prevNoiseU16[i] = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_U32(inst->prevNoiseU32[i], 11); // Q(prevQNoise)\n    }\n\n    if (inst->blockIndex < END_STARTUP_SHORT)\n    {\n        // Noise Q-domain to be used later; see description at end of section.\n        q_domain_to_use = WEBRTC_SPL_MIN((int)qNoise, inst->minNorm - inst->stages);\n\n        // Calculate frequency independent parts in parametric noise estimate and calculate\n        // the estimate for the lower frequency band (same values for all frequency bins)\n        if (inst->pinkNoiseExp)\n        {\n            pink_noise_exp_avg = (WebRtc_Word16)WebRtcSpl_DivW32W16(inst->pinkNoiseExp,\n                                                (WebRtc_Word16)(inst->blockIndex + 1)); // Q14\n            pink_noise_num_avg = WebRtcSpl_DivW32W16(inst->pinkNoiseNumerator,\n                                 (WebRtc_Word16)(inst->blockIndex + 1)); // Q11\n            WebRtcNsx_CalcParametricNoiseEstimate(inst,\n                                                  pink_noise_exp_avg,\n                                                  pink_noise_num_avg,\n                                                  kStartBand,\n                                                  &noise_estimate,\n                                                  &noise_estimate_avg);\n        }\n        else\n        {\n            // Use white noise estimate if we have poor pink noise parameter estimates\n            noise_estimate = inst->whiteNoiseLevel; // Q(minNorm-stages)\n            noise_estimate_avg = noise_estimate / (inst->blockIndex + 1); // Q(minNorm-stages)\n        }\n        for (i = 0; i < inst->magnLen; i++)\n        {\n            // Estimate the background noise using the pink noise parameters if permitted\n            if ((inst->pinkNoiseExp) && (i >= kStartBand))\n            {\n                // Reset noise_estimate\n                noise_estimate = 0;\n                noise_estimate_avg = 0;\n                // Calculate the parametric noise estimate for current frequency bin\n                WebRtcNsx_CalcParametricNoiseEstimate(inst,\n                                                      pink_noise_exp_avg,\n                                                      pink_noise_num_avg,\n                                                      i,\n                                                      &noise_estimate,\n                                                      &noise_estimate_avg);\n            }\n            // Calculate parametric Wiener filter\n            noiseSupFilterTmp[i] = inst->denoiseBound;\n            if (inst->initMagnEst[i])\n            {\n                // numerator = (initMagnEst - noise_estimate * overdrive)\n                // Result in Q(8+minNorm-stages)\n                tmpU32no1 = WEBRTC_SPL_UMUL_32_16(noise_estimate, inst->overdrive);\n                numerator = WEBRTC_SPL_LSHIFT_U32(inst->initMagnEst[i], 8);\n                if (numerator > tmpU32no1)\n                {\n                    // Suppression filter coefficient larger than zero, so calculate.\n                    numerator -= tmpU32no1;\n\n                    // Determine number of left shifts in numerator for best accuracy after\n                    // division\n                    nShifts = WebRtcSpl_NormU32(numerator);\n                    nShifts = WEBRTC_SPL_SAT(6, nShifts, 0);\n\n                    // Shift numerator to Q(nShifts+8+minNorm-stages)\n                    numerator = WEBRTC_SPL_LSHIFT_U32(numerator, nShifts);\n\n                    // Shift denominator to Q(nShifts-6+minNorm-stages)\n                    tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(inst->initMagnEst[i], 6 - nShifts);\n                    tmpU32no2 = WEBRTC_SPL_UDIV(numerator, tmpU32no1); // Q14\n                    noiseSupFilterTmp[i] = (WebRtc_UWord16)WEBRTC_SPL_SAT(16384, tmpU32no2,\n                                           (WebRtc_UWord32)(inst->denoiseBound)); // Q14\n                }\n            }\n            // Weight quantile noise 'noiseU32' with modeled noise 'noise_estimate_avg'\n            // 'noiseU32 is in Q(qNoise) and 'noise_estimate' in Q(minNorm-stages)\n            // To guarantee that we do not get wrap around when shifting to the same domain\n            // we use the lowest one. Furthermore, we need to save 6 bits for the weighting.\n            // 'noise_estimate_avg' can handle this operation by construction, but 'noiseU32'\n            // may not.\n\n            // Shift 'noiseU32' to 'q_domain_to_use'\n            tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(noiseU32[i], (int)qNoise - q_domain_to_use);\n            // Shift 'noise_estimate_avg' to 'q_domain_to_use'\n            tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(noise_estimate_avg, inst->minNorm - inst->stages\n                                              - q_domain_to_use);\n            // Make a simple check to see if we have enough room for weighting 'tmpU32no1'\n            // without wrap around\n            nShifts = 0;\n            if (tmpU32no1 & 0xfc000000) {\n                tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, 6);\n                tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(tmpU32no2, 6);\n                nShifts = 6;\n            }\n            // Add them together and divide by startup length\n            noiseU32[i] = WebRtcSpl_DivU32U16(tmpU32no1 + tmpU32no2, END_STARTUP_SHORT);\n            // Shift back if necessary\n            noiseU32[i] = WEBRTC_SPL_LSHIFT_U32(noiseU32[i], nShifts);\n        }\n        // Update new Q-domain for 'noiseU32'\n        qNoise = q_domain_to_use;\n    }\n    // compute average signal during END_STARTUP_LONG time:\n    // used to normalize spectral difference measure\n    if (inst->blockIndex < END_STARTUP_LONG)\n    {\n        // substituting division with shift ending up in Q(-2*stages)\n        inst->timeAvgMagnEnergyTmp\n                += WEBRTC_SPL_RSHIFT_U32(inst->magnEnergy,\n                                         2 * inst->normData + inst->stages - 1);\n        inst->timeAvgMagnEnergy = WebRtcSpl_DivU32U16(inst->timeAvgMagnEnergyTmp,\n                                                      inst->blockIndex + 1);\n    }\n\n    //start processing at frames == converged+1\n    // STEP 1: compute prior and post SNR based on quantile noise estimates\n\n    // compute direct decision (DD) estimate of prior SNR: needed for new method\n    satMax = (WebRtc_UWord32)1048575;// Largest possible value without getting overflow despite shifting 12 steps\n    postShifts = 6 + qMagn - qNoise;\n    nShifts = 5 - inst->prevQMagn + inst->prevQNoise;\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        // FLOAT:\n        // post SNR\n        // postLocSnr[i] = 0.0;\n        // if (magn[i] > noise[i])\n        // {\n        //   postLocSnr[i] = magn[i] / (noise[i] + 0.0001);\n        // }\n        // // previous post SNR\n        // // previous estimate: based on previous frame with gain filter (smooth is previous filter)\n        //\n        // prevNearSnr[i] = inst->prevMagnU16[i] / (inst->noisePrev[i] + 0.0001) * (inst->smooth[i]);\n        //\n        // // DD estimate is sum of two terms: current estimate and previous estimate\n        // // directed decision update of priorSnr (or we actually store [2*priorSnr+1])\n        //\n        // priorLocSnr[i] = DD_PR_SNR * prevNearSnr[i] + (1.0 - DD_PR_SNR) * (postLocSnr[i] - 1.0);\n\n        // calculate post SNR: output in Q11\n        postLocSnr[i] = 2048; // 1.0 in Q11\n        tmpU32no1 = WEBRTC_SPL_LSHIFT_U32((WebRtc_UWord32)magnU16[i], 6); // Q(6+qMagn)\n        if (postShifts < 0)\n        {\n            tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(noiseU32[i], -postShifts); // Q(6+qMagn)\n        } else\n        {\n            tmpU32no2 = WEBRTC_SPL_LSHIFT_U32(noiseU32[i], postShifts); // Q(6+qMagn)\n        }\n        if (tmpU32no1 > tmpU32no2)\n        {\n            // Current magnitude larger than noise\n            tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(tmpU32no1, 11); // Q(17+qMagn)\n            if (tmpU32no2)\n            {\n                tmpU32no1 = WEBRTC_SPL_UDIV(tmpU32no1, tmpU32no2); // Q11\n                postLocSnr[i] = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11\n            } else\n            {\n                postLocSnr[i] = satMax;\n            }\n        }\n\n        // calculate prevNearSnr[i] and save for later instead of recalculating it later\n        nearMagnEst = WEBRTC_SPL_UMUL_16_16(inst->prevMagnU16[i], inst->noiseSupFilter[i]); // Q(prevQMagn+14)\n        tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(nearMagnEst, 3); // Q(prevQMagn+17)\n        tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(inst->prevNoiseU32[i], nShifts); // Q(prevQMagn+6)\n\n        if (tmpU32no2)\n        {\n            tmpU32no1 = WEBRTC_SPL_DIV(tmpU32no1, tmpU32no2); // Q11\n            tmpU32no1 = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11\n        } else\n        {\n            tmpU32no1 = satMax; // Q11\n        }\n        prevNearSnr[i] = tmpU32no1; // Q11\n\n        //directed decision update of priorSnr\n        tmpU32no1 = WEBRTC_SPL_UMUL_32_16(prevNearSnr[i], DD_PR_SNR_Q11); // Q22\n        tmpU32no2 = WEBRTC_SPL_UMUL_32_16(postLocSnr[i] - 2048, ONE_MINUS_DD_PR_SNR_Q11); // Q22\n        priorSnr = tmpU32no1 + tmpU32no2 + 512; // Q22 (added 512 for rounding)\n        // priorLocSnr = 1 + 2*priorSnr\n        priorLocSnr[i] = 2048 + WEBRTC_SPL_RSHIFT_U32(priorSnr, 10); // Q11\n    } // end of loop over frequencies\n    // done with step 1: DD computation of prior and post SNR\n\n    // STEP 2: compute speech/noise likelihood\n\n    //compute difference of input spectrum with learned/estimated noise spectrum\n    WebRtcNsx_ComputeSpectralDifference(inst, magnU16);\n    //compute histograms for determination of parameters (thresholds and weights for features)\n    //parameters are extracted once every window time (=inst->modelUpdate)\n    //counter update\n    inst->cntThresUpdate++;\n    flag = (int)(inst->cntThresUpdate == inst->modelUpdate);\n    //update histogram\n    WebRtcNsx_FeatureParameterExtraction(inst, flag);\n    //compute model parameters\n    if (flag)\n    {\n        inst->cntThresUpdate = 0; // Reset counter\n        //update every window:\n        // get normalization for spectral difference for next window estimate\n\n        // Shift to Q(-2*stages)\n        inst->curAvgMagnEnergy = WEBRTC_SPL_RSHIFT_U32(inst->curAvgMagnEnergy, STAT_UPDATES);\n\n        tmpU32no1 = (inst->curAvgMagnEnergy + inst->timeAvgMagnEnergy + 1) >> 1; //Q(-2*stages)\n        // Update featureSpecDiff\n        if ((tmpU32no1 != inst->timeAvgMagnEnergy) && (inst->featureSpecDiff))\n        {\n            norm32no1 = 0;\n            tmpU32no3 = tmpU32no1;\n            while (0xFFFF0000 & tmpU32no3)\n            {\n                tmpU32no3 >>= 1;\n                norm32no1++;\n            }\n            tmpU32no2 = inst->featureSpecDiff;\n            while (0xFFFF0000 & tmpU32no2)\n            {\n                tmpU32no2 >>= 1;\n                norm32no1++;\n            }\n            tmpU32no3 = WEBRTC_SPL_UMUL(tmpU32no3, tmpU32no2);\n            tmpU32no3 = WEBRTC_SPL_UDIV(tmpU32no3, inst->timeAvgMagnEnergy);\n            if (WebRtcSpl_NormU32(tmpU32no3) < norm32no1)\n            {\n                inst->featureSpecDiff = 0x007FFFFF;\n            } else\n            {\n                inst->featureSpecDiff = WEBRTC_SPL_MIN(0x007FFFFF,\n                                        WEBRTC_SPL_LSHIFT_U32(tmpU32no3, norm32no1));\n            }\n        }\n\n        inst->timeAvgMagnEnergy = tmpU32no1; // Q(-2*stages)\n        inst->curAvgMagnEnergy = 0;\n    }\n\n    //compute speech/noise probability\n    WebRtcNsx_SpeechNoiseProb(inst, nonSpeechProbFinal, priorLocSnr, postLocSnr);\n\n    //time-avg parameter for noise update\n    gammaNoise = NOISE_UPDATE_Q8; // Q8\n\n    maxNoiseU32 = 0;\n    postShifts = inst->prevQNoise - qMagn;\n    nShifts = inst->prevQMagn - qMagn;\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        // temporary noise update: use it for speech frames if update value is less than previous\n        // the formula has been rewritten into:\n        // noiseUpdate = noisePrev[i] + (1 - gammaNoise) * nonSpeechProb * (magn[i] - noisePrev[i])\n\n        if (postShifts < 0)\n        {\n            tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(magnU16[i], -postShifts); // Q(prevQNoise)\n        } else\n        {\n            tmpU32no2 = WEBRTC_SPL_LSHIFT_U32(magnU16[i], postShifts); // Q(prevQNoise)\n        }\n        if (prevNoiseU16[i] > tmpU32no2)\n        {\n            sign = -1;\n            tmpU32no1 = prevNoiseU16[i] - tmpU32no2;\n        } else\n        {\n            sign = 1;\n            tmpU32no1 = tmpU32no2 - prevNoiseU16[i];\n        }\n        noiseUpdateU32 = inst->prevNoiseU32[i]; // Q(prevQNoise+11)\n        tmpU32no3 = 0;\n        if ((tmpU32no1) && (nonSpeechProbFinal[i]))\n        {\n            // This value will be used later, if gammaNoise changes\n            tmpU32no3 = WEBRTC_SPL_UMUL_32_16(tmpU32no1, nonSpeechProbFinal[i]); // Q(prevQNoise+8)\n            if (0x7c000000 & tmpU32no3)\n            {\n                // Shifting required before multiplication\n                tmpU32no2\n                        = WEBRTC_SPL_UMUL_32_16(WEBRTC_SPL_RSHIFT_U32(tmpU32no3, 5), gammaNoise); // Q(prevQNoise+11)\n            } else\n            {\n                // We can do shifting after multiplication\n                tmpU32no2\n                        = WEBRTC_SPL_RSHIFT_U32(WEBRTC_SPL_UMUL_32_16(tmpU32no3, gammaNoise), 5); // Q(prevQNoise+11)\n            }\n            if (sign > 0)\n            {\n                noiseUpdateU32 += tmpU32no2; // Q(prevQNoise+11)\n            } else\n            {\n                // This operation is safe. We can never get wrap around, since worst\n                // case scenario means magnU16 = 0\n                noiseUpdateU32 -= tmpU32no2; // Q(prevQNoise+11)\n            }\n        }\n\n        //increase gamma (i.e., less noise update) for frame likely to be speech\n        prevGammaNoise = gammaNoise;\n        gammaNoise = NOISE_UPDATE_Q8;\n        //time-constant based on speech/noise state\n        //increase gamma (i.e., less noise update) for frames likely to be speech\n        if (nonSpeechProbFinal[i] < ONE_MINUS_PROB_RANGE_Q8)\n        {\n            gammaNoise = GAMMA_NOISE_TRANS_AND_SPEECH_Q8;\n        }\n\n        if (prevGammaNoise != gammaNoise)\n        {\n            // new noise update\n            // this line is the same as above, only that the result is stored in a different variable and the gammaNoise\n            // has changed\n            //\n            // noiseUpdate = noisePrev[i] + (1 - gammaNoise) * nonSpeechProb * (magn[i] - noisePrev[i])\n\n            if (0x7c000000 & tmpU32no3)\n            {\n                // Shifting required before multiplication\n                tmpU32no2\n                        = WEBRTC_SPL_UMUL_32_16(WEBRTC_SPL_RSHIFT_U32(tmpU32no3, 5), gammaNoise); // Q(prevQNoise+11)\n            } else\n            {\n                // We can do shifting after multiplication\n                tmpU32no2\n                        = WEBRTC_SPL_RSHIFT_U32(WEBRTC_SPL_UMUL_32_16(tmpU32no3, gammaNoise), 5); // Q(prevQNoise+11)\n            }\n            if (sign > 0)\n            {\n                tmpU32no1 = inst->prevNoiseU32[i] + tmpU32no2; // Q(prevQNoise+11)\n            } else\n            {\n                tmpU32no1 = inst->prevNoiseU32[i] - tmpU32no2; // Q(prevQNoise+11)\n            }\n            if (noiseUpdateU32 > tmpU32no1)\n            {\n                noiseUpdateU32 = tmpU32no1; // Q(prevQNoise+11)\n            }\n        }\n        noiseU32[i] = noiseUpdateU32; // Q(prevQNoise+11)\n        if (noiseUpdateU32 > maxNoiseU32)\n        {\n            maxNoiseU32 = noiseUpdateU32;\n        }\n\n        // conservative noise update\n        // // original FLOAT code\n        // if (prob_speech < PROB_RANGE) {\n        // inst->avgMagnPause[i] = inst->avgMagnPause[i] + (1.0 - gamma_pause)*(magn[i] - inst->avgMagnPause[i]);\n        // }\n\n        tmp32no2 = WEBRTC_SPL_SHIFT_W32(inst->avgMagnPause[i], -nShifts);\n        if (nonSpeechProbFinal[i] > ONE_MINUS_PROB_RANGE_Q8)\n        {\n            if (nShifts < 0)\n            {\n                tmp32no1 = (WebRtc_Word32)magnU16[i] - tmp32no2; // Q(qMagn)\n                tmp32no1 = WEBRTC_SPL_MUL_32_16(tmp32no1, ONE_MINUS_GAMMA_PAUSE_Q8); // Q(8+prevQMagn+nShifts)\n                tmp32no1 = WEBRTC_SPL_RSHIFT_W32(tmp32no1 + 128, 8); // Q(qMagn)\n            } else\n            {\n                tmp32no1 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)magnU16[i], nShifts)\n                        - inst->avgMagnPause[i]; // Q(qMagn+nShifts)\n                tmp32no1 = WEBRTC_SPL_MUL_32_16(tmp32no1, ONE_MINUS_GAMMA_PAUSE_Q8); // Q(8+prevQMagn+nShifts)\n                tmp32no1 = WEBRTC_SPL_RSHIFT_W32(tmp32no1 + (128 << nShifts), 8 + nShifts); // Q(qMagn)\n            }\n            tmp32no2 += tmp32no1; // Q(qMagn)\n        }\n        inst->avgMagnPause[i] = tmp32no2;\n    } // end of frequency loop\n\n    norm32no1 = WebRtcSpl_NormU32(maxNoiseU32);\n    qNoise = inst->prevQNoise + norm32no1 - 5;\n    // done with step 2: noise update\n\n    // STEP 3: compute dd update of prior snr and post snr based on new noise estimate\n    nShifts = inst->prevQNoise + 11 - qMagn;\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        // FLOAT code\n        // // post and prior SNR\n        // curNearSnr = 0.0;\n        // if (magn[i] > noise[i])\n        // {\n        // curNearSnr = magn[i] / (noise[i] + 0.0001) - 1.0;\n        // }\n        // // DD estimate is sum of two terms: current estimate and previous estimate\n        // // directed decision update of snrPrior\n        // snrPrior = DD_PR_SNR * prevNearSnr[i] + (1.0 - DD_PR_SNR) * curNearSnr;\n        // // gain filter\n        // tmpFloat1 = inst->overdrive + snrPrior;\n        // tmpFloat2 = snrPrior / tmpFloat1;\n        // theFilter[i] = tmpFloat2;\n\n        // calculate curNearSnr again, this is necessary because a new noise estimate has been made since then. for the original\n        curNearSnr = 0; // Q11\n        if (nShifts < 0)\n        {\n            // This case is equivalent with magn < noise which implies curNearSnr = 0;\n            tmpMagnU32 = (WebRtc_UWord32)magnU16[i]; // Q(qMagn)\n            tmpNoiseU32 = WEBRTC_SPL_LSHIFT_U32(noiseU32[i], -nShifts); // Q(qMagn)\n        } else if (nShifts > 17)\n        {\n            tmpMagnU32 = WEBRTC_SPL_LSHIFT_U32(magnU16[i], 17); // Q(qMagn+17)\n            tmpNoiseU32 = WEBRTC_SPL_RSHIFT_U32(noiseU32[i], nShifts - 17); // Q(qMagn+17)\n        } else\n        {\n            tmpMagnU32 = WEBRTC_SPL_LSHIFT_U32((WebRtc_UWord32)magnU16[i], nShifts); // Q(qNoise_prev+11)\n            tmpNoiseU32 = noiseU32[i]; // Q(qNoise_prev+11)\n        }\n        if (tmpMagnU32 > tmpNoiseU32)\n        {\n            tmpU32no1 = tmpMagnU32 - tmpNoiseU32; // Q(qCur)\n            norm32no2 = WEBRTC_SPL_MIN(11, WebRtcSpl_NormU32(tmpU32no1));\n            tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(tmpU32no1, norm32no2); // Q(qCur+norm32no2)\n            tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(tmpNoiseU32, 11 - norm32no2); // Q(qCur+norm32no2-11)\n            if (tmpU32no2)\n            {\n                tmpU32no1 = WEBRTC_SPL_UDIV(tmpU32no1, tmpU32no2); // Q11\n            }\n            curNearSnr = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11\n        }\n\n        //directed decision update of priorSnr\n        // FLOAT\n        // priorSnr = DD_PR_SNR * prevNearSnr + (1.0-DD_PR_SNR) * curNearSnr;\n\n        tmpU32no1 = WEBRTC_SPL_UMUL_32_16(prevNearSnr[i], DD_PR_SNR_Q11); // Q22\n        tmpU32no2 = WEBRTC_SPL_UMUL_32_16(curNearSnr, ONE_MINUS_DD_PR_SNR_Q11); // Q22\n        priorSnr = tmpU32no1 + tmpU32no2; // Q22\n\n        //gain filter\n        tmpU32no1 = (WebRtc_UWord32)(inst->overdrive)\n                + WEBRTC_SPL_RSHIFT_U32(priorSnr + 8192, 14); // Q8\n        tmpU16no1 = (WebRtc_UWord16)WEBRTC_SPL_UDIV(priorSnr + (tmpU32no1 >> 1), tmpU32no1); // Q14\n        inst->noiseSupFilter[i] = WEBRTC_SPL_SAT(16384, tmpU16no1, inst->denoiseBound); // 16384 = Q14(1.0) // Q14\n\n        // Weight in the parametric Wiener filter during startup\n        if (inst->blockIndex < END_STARTUP_SHORT)\n        {\n            // Weight the two suppression filters\n            tmpU32no1 = WEBRTC_SPL_UMUL_16_16(inst->noiseSupFilter[i],\n                                              (WebRtc_UWord16)inst->blockIndex);\n            tmpU32no2 = WEBRTC_SPL_UMUL_16_16(noiseSupFilterTmp[i],\n                                              (WebRtc_UWord16)(END_STARTUP_SHORT\n                                                      - inst->blockIndex));\n            tmpU32no1 += tmpU32no2;\n            inst->noiseSupFilter[i] = (WebRtc_UWord16)WebRtcSpl_DivU32U16(tmpU32no1,\n                                                                          END_STARTUP_SHORT);\n        }\n    } // end of loop over frequencies\n    //done with step3\n\n    // save noise and magnitude spectrum for next frame\n    inst->prevQNoise = qNoise;\n    inst->prevQMagn = qMagn;\n    if (norm32no1 > 5)\n    {\n        for (i = 0; i < inst->magnLen; i++)\n        {\n            inst->prevNoiseU32[i] = WEBRTC_SPL_LSHIFT_U32(noiseU32[i], norm32no1 - 5); // Q(qNoise+11)\n            inst->prevMagnU16[i] = magnU16[i]; // Q(qMagn)\n        }\n    } else\n    {\n        for (i = 0; i < inst->magnLen; i++)\n        {\n            inst->prevNoiseU32[i] = WEBRTC_SPL_RSHIFT_U32(noiseU32[i], 5 - norm32no1); // Q(qNoise+11)\n            inst->prevMagnU16[i] = magnU16[i]; // Q(qMagn)\n        }\n    }\n\n    WebRtcNsx_DataSynthesis(inst, outFrame);\n#ifdef NS_FILEDEBUG\n    fwrite(outframe, sizeof(short), inst->blockLen10ms, inst->outfile);\n#endif\n\n    //for H band:\n    // only update data buffer, then apply time-domain gain is applied derived from L band\n    if (inst->fs == 32000)\n    {\n        // update analysis buffer for H band\n        // append new data to buffer FX\n        WEBRTC_SPL_MEMCPY_W16(inst->dataBufHBFX, inst->dataBufHBFX + inst->blockLen10ms, inst->anaLen - inst->blockLen10ms);\n        WEBRTC_SPL_MEMCPY_W16(inst->dataBufHBFX + inst->anaLen - inst->blockLen10ms, speechFrameHB, inst->blockLen10ms);\n        // range for averaging low band quantities for H band gain\n\n        gainTimeDomainHB = 16384; // 16384 = Q14(1.0)\n        //average speech prob from low band\n        //average filter gain from low band\n        //avg over second half (i.e., 4->8kHz) of freq. spectrum\n        tmpU32no1 = 0; // Q12\n        tmpU16no1 = 0; // Q8\n        for (i = inst->anaLen2 - (inst->anaLen2 >> 2); i < inst->anaLen2; i++)\n        {\n            tmpU16no1 += nonSpeechProbFinal[i]; // Q8\n            tmpU32no1 += (WebRtc_UWord32)(inst->noiseSupFilter[i]); // Q14\n        }\n        avgProbSpeechHB = (WebRtc_Word16)(4096\n                - WEBRTC_SPL_RSHIFT_U16(tmpU16no1, inst->stages - 7)); // Q12\n        avgFilterGainHB = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(tmpU32no1, inst->stages - 3); // Q14\n\n        // // original FLOAT code\n        // // gain based on speech probability:\n        // avg_prob_speech_tt=(float)2.0*avg_prob_speech-(float)1.0;\n        // gain_mod=(float)0.5*((float)1.0+(float)tanh(avg_prob_speech_tt)); // between 0 and 1\n\n        // gain based on speech probability:\n        // original expression: \"0.5 * (1 + tanh(2x-1))\"\n        // avgProbSpeechHB has been anyway saturated to a value between 0 and 1 so the other cases don't have to be dealt with\n        // avgProbSpeechHB and gainModHB are in Q12, 3607 = Q12(0.880615234375) which is a zero point of\n        // |0.5 * (1 + tanh(2x-1)) - x| - |0.5 * (1 + tanh(2x-1)) - 0.880615234375| meaning that from that point the error of approximating\n        // the expression with f(x) = x would be greater than the error of approximating the expression with f(x) = 0.880615234375\n        // error: \"|0.5 * (1 + tanh(2x-1)) - x| from x=0 to 0.880615234375\" -> http://www.wolframalpha.com/input/?i=|0.5+*+(1+%2B+tanh(2x-1))+-+x|+from+x%3D0+to+0.880615234375\n        // and:  \"|0.5 * (1 + tanh(2x-1)) - 0.880615234375| from x=0.880615234375 to 1\" -> http://www.wolframalpha.com/input/?i=+|0.5+*+(1+%2B+tanh(2x-1))+-+0.880615234375|+from+x%3D0.880615234375+to+1\n        gainModHB = WEBRTC_SPL_MIN(avgProbSpeechHB, 3607);\n\n        // // original FLOAT code\n        // //combine gain with low band gain\n        // if (avg_prob_speech < (float)0.5) {\n        // gain_time_domain_HB=(float)0.5*gain_mod+(float)0.5*avg_filter_gain;\n        // }\n        // else {\n        // gain_time_domain_HB=(float)0.25*gain_mod+(float)0.75*avg_filter_gain;\n        // }\n\n\n        //combine gain with low band gain\n        if (avgProbSpeechHB < 2048)\n        { // 2048 = Q12(0.5)\n            // the next two lines in float are  \"gain_time_domain = 0.5 * gain_mod + 0.5 * avg_filter_gain\"; Q2(0.5) = 2 equals one left shift\n            gainTimeDomainHB = (gainModHB << 1) + (avgFilterGainHB >> 1); // Q14\n        } else\n        {\n            // \"gain_time_domain = 0.25 * gain_mod + 0.75 * agv_filter_gain;\"\n            gainTimeDomainHB = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(3, avgFilterGainHB, 2); // 3 = Q2(0.75); Q14\n            gainTimeDomainHB += gainModHB; // Q14\n        }\n        //make sure gain is within flooring range\n        gainTimeDomainHB\n                = WEBRTC_SPL_SAT(16384, gainTimeDomainHB, (WebRtc_Word16)(inst->denoiseBound)); // 16384 = Q14(1.0)\n\n\n        //apply gain\n        for (i = 0; i < inst->blockLen10ms; i++)\n        {\n            outFrameHB[i]\n                    = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gainTimeDomainHB, inst->dataBufHBFX[i], 14); // Q0\n        }\n    } // end of H band gain computation\n\n    return 0;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/ns/main/source/nsx_core.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_CORE_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_CORE_H_\n\n#include \"typedefs.h\"\n#include \"signal_processing_library.h\"\n\n#include \"nsx_defines.h\"\n\n#ifdef NS_FILEDEBUG\n#include <stdio.h>\n#endif\n\ntypedef struct NsxInst_t_\n{\n    WebRtc_UWord32          fs;\n\n    const WebRtc_Word16*    window;\n    WebRtc_Word16           analysisBuffer[ANAL_BLOCKL_MAX];\n    WebRtc_Word16           synthesisBuffer[ANAL_BLOCKL_MAX];\n    WebRtc_UWord16          noiseSupFilter[HALF_ANAL_BLOCKL];\n    WebRtc_UWord16          overdrive; /* Q8 */\n    WebRtc_UWord16          denoiseBound; /* Q14 */\n    const WebRtc_Word16*    factor2Table;\n    WebRtc_Word16           noiseEstLogQuantile[SIMULT * HALF_ANAL_BLOCKL];\n    WebRtc_Word16           noiseEstDensity[SIMULT * HALF_ANAL_BLOCKL];\n    WebRtc_Word16           noiseEstCounter[SIMULT];\n    WebRtc_Word16           noiseEstQuantile[HALF_ANAL_BLOCKL];\n\n    WebRtc_Word16           anaLen;\n    int                     anaLen2;\n    int                     magnLen;\n    int                     aggrMode;\n    int                     stages;\n    int                     initFlag;\n    int                     gainMap;\n\n    WebRtc_Word32           maxLrt;\n    WebRtc_Word32           minLrt;\n    WebRtc_Word32           logLrtTimeAvgW32[HALF_ANAL_BLOCKL]; //log lrt factor with time-smoothing in Q8\n    WebRtc_Word32           featureLogLrt;\n    WebRtc_Word32           thresholdLogLrt;\n    WebRtc_Word16           weightLogLrt;\n\n    WebRtc_UWord32          featureSpecDiff;\n    WebRtc_UWord32          thresholdSpecDiff;\n    WebRtc_Word16           weightSpecDiff;\n\n    WebRtc_UWord32          featureSpecFlat;\n    WebRtc_UWord32          thresholdSpecFlat;\n    WebRtc_Word16           weightSpecFlat;\n\n    WebRtc_Word32           avgMagnPause[HALF_ANAL_BLOCKL]; //conservative estimate of noise spectrum\n    WebRtc_UWord32          magnEnergy;\n    WebRtc_UWord32          sumMagn;\n    WebRtc_UWord32          curAvgMagnEnergy;\n    WebRtc_UWord32          timeAvgMagnEnergy;\n    WebRtc_UWord32          timeAvgMagnEnergyTmp;\n\n    WebRtc_UWord32          whiteNoiseLevel;              //initial noise estimate\n    WebRtc_UWord32          initMagnEst[HALF_ANAL_BLOCKL];//initial magnitude spectrum estimate\n    WebRtc_Word32           pinkNoiseNumerator;           //pink noise parameter: numerator\n    WebRtc_Word32           pinkNoiseExp;                 //pink noise parameter: power of freq\n    int                     minNorm;                      //smallest normalization factor\n    int                     zeroInputSignal;              //zero input signal flag\n\n    WebRtc_UWord32          prevNoiseU32[HALF_ANAL_BLOCKL]; //noise spectrum from previous frame\n    WebRtc_UWord16          prevMagnU16[HALF_ANAL_BLOCKL]; //magnitude spectrum from previous frame\n    WebRtc_Word16           priorNonSpeechProb; //prior speech/noise probability // Q14\n\n    int                     blockIndex; //frame index counter\n    int                     modelUpdate; //parameter for updating or estimating thresholds/weights for prior model\n    int                     cntThresUpdate;\n\n    //histograms for parameter estimation\n    WebRtc_Word16           histLrt[HIST_PAR_EST];\n    WebRtc_Word16           histSpecFlat[HIST_PAR_EST];\n    WebRtc_Word16           histSpecDiff[HIST_PAR_EST];\n\n    //quantities for high band estimate\n    WebRtc_Word16           dataBufHBFX[ANAL_BLOCKL_MAX]; /* Q0 */\n\n    int                     qNoise;\n    int                     prevQNoise;\n    int                     prevQMagn;\n    int                     blockLen10ms;\n\n    WebRtc_Word16           real[ANAL_BLOCKL_MAX];\n    WebRtc_Word16           imag[ANAL_BLOCKL_MAX];\n    WebRtc_Word32           energyIn;\n    int                     scaleEnergyIn;\n    int                     normData;\n\n} NsxInst_t;\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/****************************************************************************\n * WebRtcNsx_InitCore(...)\n *\n * This function initializes a noise suppression instance\n *\n * Input:\n *      - inst          : Instance that should be initialized\n *      - fs            : Sampling frequency\n *\n * Output:\n *      - inst          : Initialized instance\n *\n * Return value         :  0 - Ok\n *                        -1 - Error\n */\nWebRtc_Word32 WebRtcNsx_InitCore(NsxInst_t *inst, WebRtc_UWord32 fs);\n\n/****************************************************************************\n * WebRtcNsx_set_policy_core(...)\n *\n * This changes the aggressiveness of the noise suppression method.\n *\n * Input:\n *      - inst          : Instance that should be initialized\n *      - mode          : 0: Mild (6 dB), 1: Medium (10 dB), 2: Aggressive (15 dB)\n *\n * Output:\n *      - NS_inst      : Initialized instance\n *\n * Return value         :  0 - Ok\n *                        -1 - Error\n */\nint WebRtcNsx_set_policy_core(NsxInst_t *inst, int mode);\n\n/****************************************************************************\n * WebRtcNsx_ProcessCore\n *\n * Do noise suppression.\n *\n * Input:\n *      - inst          : Instance that should be initialized\n *      - inFrameLow    : Input speech frame for lower band\n *      - inFrameHigh   : Input speech frame for higher band\n *\n * Output:\n *      - inst          : Updated instance\n *      - outFrameLow   : Output speech frame for lower band\n *      - outFrameHigh  : Output speech frame for higher band\n *\n * Return value         :  0 - OK\n *                        -1 - Error\n */\nint WebRtcNsx_ProcessCore(NsxInst_t *inst, short *inFrameLow, short *inFrameHigh,\n                          short *outFrameLow, short *outFrameHigh);\n\n/****************************************************************************\n * Internal functions and variable declarations shared with optimized code.\n */\nvoid WebRtcNsx_UpdateNoiseEstimate(NsxInst_t *inst, int offset);\n\nvoid WebRtcNsx_NoiseEstimation(NsxInst_t *inst, WebRtc_UWord16 *magn, WebRtc_UWord32 *noise,\n                               WebRtc_Word16 *qNoise);\n\nextern const WebRtc_Word16 WebRtcNsx_kLogTable[9];\nextern const WebRtc_Word16 WebRtcNsx_kLogTableFrac[256];\nextern const WebRtc_Word16 WebRtcNsx_kCounterDiv[201];\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_CORE_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/ns/main/source/nsx_core_neon.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#if defined(WEBRTC_ARCH_ARM_NEON) && defined(WEBRTC_ANDROID)\n\n#include \"nsx_core.h\"\n#include <arm_neon.h>\n\nvoid WebRtcNsx_NoiseEstimation(NsxInst_t *inst, WebRtc_UWord16 *magn, WebRtc_UWord32 *noise,\n                               WebRtc_Word16 *qNoise)\n{\n    WebRtc_Word32 numerator;\n\n    WebRtc_Word16 lmagn[HALF_ANAL_BLOCKL], counter, countDiv, countProd, delta, zeros, frac;\n    WebRtc_Word16 log2, tabind, logval, tmp16, tmp16no1, tmp16no2;\n    WebRtc_Word16 log2Const = 22713;\n    WebRtc_Word16 widthFactor = 21845;\n\n    int i, s, offset;\n\n    numerator = FACTOR_Q16;\n\n    tabind = inst->stages - inst->normData;\n    if (tabind < 0)\n    {\n        logval = -WebRtcNsx_kLogTable[-tabind];\n    } else\n    {\n        logval = WebRtcNsx_kLogTable[tabind];\n    }\n\n    // lmagn(i)=log(magn(i))=log(2)*log2(magn(i))\n    // magn is in Q(-stages), and the real lmagn values are:\n    // real_lmagn(i)=log(magn(i)*2^stages)=log(magn(i))+log(2^stages)\n    // lmagn in Q8\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        if (magn[i])\n        {\n            zeros = WebRtcSpl_NormU32((WebRtc_UWord32)magn[i]);\n            frac = (WebRtc_Word16)((((WebRtc_UWord32)magn[i] << zeros) & 0x7FFFFFFF) >> 23);\n            // log2(magn(i))\n            log2 = (WebRtc_Word16)(((31 - zeros) << 8) + WebRtcNsx_kLogTableFrac[frac]);\n            // log2(magn(i))*log(2)\n            lmagn[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(log2, log2Const, 15);\n            // + log(2^stages)\n            lmagn[i] += logval;\n        } else\n        {\n            lmagn[i] = logval;\n        }\n    }\n\n    int16x4_t Q3_16x4  = vdup_n_s16(3);\n    int16x8_t WIDTHQ8_16x8 = vdupq_n_s16(WIDTH_Q8);\n    int16x8_t WIDTHFACTOR_16x8 = vdupq_n_s16(widthFactor);\n\n    // Loop over simultaneous estimates\n    for (s = 0; s < SIMULT; s++)\n    {\n        offset = s * inst->magnLen;\n\n        // Get counter values from state\n        counter = inst->noiseEstCounter[s];\n        countDiv = WebRtcNsx_kCounterDiv[counter];\n        countProd = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(counter, countDiv);\n\n        // quant_est(...)\n        WebRtc_Word16 delta_[8];\n        int16x4_t tmp16x4_0;\n        int16x4_t tmp16x4_1;\n        int16x4_t countDiv_16x4 = vdup_n_s16(countDiv);\n        int16x8_t countProd_16x8 = vdupq_n_s16(countProd);\n        int16x8_t tmp16x8_0 = vdupq_n_s16(countDiv);\n        int16x8_t prod16x8 = vqrdmulhq_s16(WIDTHFACTOR_16x8, tmp16x8_0);\n        int16x8_t tmp16x8_1;\n        int16x8_t tmp16x8_2;\n        int16x8_t tmp16x8_3;\n        int16x8_t tmp16x8_4;\n        int16x8_t tmp16x8_5;\n        int32x4_t tmp32x4;\n\n        for (i = 0; i < inst->magnLen - 7; i += 8) {\n            // compute delta\n            tmp16x8_0 = vdupq_n_s16(FACTOR_Q7);\n            vst1q_s16(delta_, tmp16x8_0);\n            int j;\n            for (j = 0; j < 8; j++) {\n                if (inst->noiseEstDensity[offset + i + j] > 512)\n                    delta_[j] = WebRtcSpl_DivW32W16ResW16(numerator, \n                                   inst->noiseEstDensity[offset + i + j]);\n            }\n\n            // Update log quantile estimate\n\n            // tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(delta, countDiv, 14);\n            tmp32x4 = vmull_s16(vld1_s16(&delta_[0]), countDiv_16x4);\n            tmp16x4_1 = vshrn_n_s32(tmp32x4, 14);\n            tmp32x4 = vmull_s16(vld1_s16(&delta_[4]), countDiv_16x4);\n            tmp16x4_0 = vshrn_n_s32(tmp32x4, 14);\n            tmp16x8_0 = vcombine_s16(tmp16x4_1, tmp16x4_0); // Keep for several lines.\n\n            // prepare for the \"if\" branch\n            // tmp16 += 2;\n            // tmp16_1 = (Word16)(tmp16>>2);\n            tmp16x8_1 = vrshrq_n_s16(tmp16x8_0, 2);\n\n            // inst->noiseEstLogQuantile[offset+i] + tmp16_1;\n            tmp16x8_2 = vld1q_s16(&inst->noiseEstLogQuantile[offset + i]); // Keep\n            tmp16x8_1 = vaddq_s16(tmp16x8_2, tmp16x8_1); // Keep for several lines\n\n            // Prepare for the \"else\" branch\n            // tmp16 += 1;\n            // tmp16_1 = (Word16)(tmp16>>1);\n            tmp16x8_0 = vrshrq_n_s16(tmp16x8_0, 1);\n\n            // tmp16_2 = (Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16_1,3,1);\n            tmp32x4 = vmull_s16(vget_low_s16(tmp16x8_0), Q3_16x4);\n            tmp16x4_1 = vshrn_n_s32(tmp32x4, 1);\n\n            // tmp16_2 = (Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16_1,3,1);\n            tmp32x4 = vmull_s16(vget_high_s16(tmp16x8_0), Q3_16x4);\n            tmp16x4_0 = vshrn_n_s32(tmp32x4, 1);\n\n            // inst->noiseEstLogQuantile[offset + i] - tmp16_2;\n            tmp16x8_0 = vcombine_s16(tmp16x4_1, tmp16x4_0); // keep\n            tmp16x8_0 = vsubq_s16(tmp16x8_2, tmp16x8_0);\n\n            // Do the if-else branches:\n            tmp16x8_3 = vld1q_s16(&lmagn[i]); // keep for several lines\n            tmp16x8_5 = vsubq_s16(tmp16x8_3, tmp16x8_2);\n            __asm__(\"vcgt.s16 %q0, %q1, #0\"::\"w\"(tmp16x8_4), \"w\"(tmp16x8_5));\n            __asm__(\"vbit %q0, %q1, %q2\"::\"w\"(tmp16x8_2), \"w\"(tmp16x8_1), \"w\"(tmp16x8_4));\n            __asm__(\"vbif %q0, %q1, %q2\"::\"w\"(tmp16x8_2), \"w\"(tmp16x8_0), \"w\"(tmp16x8_4));\n            vst1q_s16(&inst->noiseEstLogQuantile[offset + i], tmp16x8_2);\n\n            // Update density estimate\n            // tmp16_1 + tmp16_2\n            tmp16x8_1 = vld1q_s16(&inst->noiseEstDensity[offset + i]);\n            tmp16x8_0 = vqrdmulhq_s16(tmp16x8_1, countProd_16x8);\n            tmp16x8_0 = vaddq_s16(tmp16x8_0, prod16x8);\n\n            // lmagn[i] - inst->noiseEstLogQuantile[offset + i]\n            tmp16x8_3 = vsubq_s16(tmp16x8_3, tmp16x8_2);\n            tmp16x8_3 = vabsq_s16(tmp16x8_3);\n            tmp16x8_4 = vcgtq_s16(WIDTHQ8_16x8, tmp16x8_3);\n            __asm__(\"vbit %q0, %q1, %q2\"::\"w\"(tmp16x8_1), \"w\"(tmp16x8_0), \"w\"(tmp16x8_4));\n            vst1q_s16(&inst->noiseEstDensity[offset + i], tmp16x8_1);\n        } // End loop over magnitude spectrum\n\n        for (; i < inst->magnLen; i++)\n        {\n            // compute delta\n            if (inst->noiseEstDensity[offset + i] > 512)\n            {\n                delta = WebRtcSpl_DivW32W16ResW16(numerator,\n                                                  inst->noiseEstDensity[offset + i]);\n            } else\n            {\n                delta = FACTOR_Q7;\n            }\n\n            // update log quantile estimate\n            tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(delta, countDiv, 14);\n            if (lmagn[i] > inst->noiseEstLogQuantile[offset + i])\n            {\n                // +=QUANTILE*delta/(inst->counter[s]+1) QUANTILE=0.25, =1 in Q2\n                // CounterDiv=1/inst->counter[s] in Q15\n                tmp16 += 2;\n                tmp16no1 = WEBRTC_SPL_RSHIFT_W16(tmp16, 2);\n                inst->noiseEstLogQuantile[offset + i] += tmp16no1;\n            } else\n            {\n                tmp16 += 1;\n                tmp16no1 = WEBRTC_SPL_RSHIFT_W16(tmp16, 1);\n                // *(1-QUANTILE), in Q2 QUANTILE=0.25, 1-0.25=0.75=3 in Q2\n                tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16no1, 3, 1);\n                inst->noiseEstLogQuantile[offset + i] -= tmp16no2;\n            }\n\n            // update density estimate\n            if (WEBRTC_SPL_ABS_W16(lmagn[i] - inst->noiseEstLogQuantile[offset + i])\n                    < WIDTH_Q8)\n            {\n                tmp16no1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(\n                        inst->noiseEstDensity[offset + i], countProd, 15);\n                tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(widthFactor,\n                                                                               countDiv, 15);\n                inst->noiseEstDensity[offset + i] = tmp16no1 + tmp16no2;\n            }\n        } // end loop over magnitude spectrum\n\n        if (counter >= END_STARTUP_LONG)\n        {\n            inst->noiseEstCounter[s] = 0;\n            if (inst->blockIndex >= END_STARTUP_LONG)\n            {\n                WebRtcNsx_UpdateNoiseEstimate(inst, offset);\n            }\n        }\n        inst->noiseEstCounter[s]++;\n\n    } // end loop over simultaneous estimates\n\n    // Sequentially update the noise during startup\n    if (inst->blockIndex < END_STARTUP_LONG)\n    {\n        WebRtcNsx_UpdateNoiseEstimate(inst, offset);\n    }\n\n    for (i = 0; i < inst->magnLen; i++)\n    {\n        noise[i] = (WebRtc_UWord32)(inst->noiseEstQuantile[i]); // Q(qNoise)\n    }\n    (*qNoise) = (WebRtc_Word16)inst->qNoise;\n}\n\n#endif // defined(WEBRTC_ARCH_ARM_NEON) && defined(WEBRTC_ANDROID)\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/ns/main/source/nsx_defines.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_DEFINES_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_DEFINES_H_\n\n#define ANAL_BLOCKL_MAX         256 // max analysis block length\n#define HALF_ANAL_BLOCKL        129 // half max analysis block length + 1\n#define SIMULT                  3\n#define END_STARTUP_LONG        200\n#define END_STARTUP_SHORT       50\n#define FACTOR_Q16              (WebRtc_Word32)2621440 // 40 in Q16\n#define FACTOR_Q7               (WebRtc_Word16)5120 // 40 in Q7\n#define WIDTH_Q8                3 // 0.01 in Q8 (or 25 )\n//PARAMETERS FOR NEW METHOD\n#define DD_PR_SNR_Q11           2007 // ~= Q11(0.98) DD update of prior SNR\n#define ONE_MINUS_DD_PR_SNR_Q11 41 // DD update of prior SNR\n#define SPECT_FLAT_TAVG_Q14     4915 // (0.30) tavg parameter for spectral flatness measure\n#define SPECT_DIFF_TAVG_Q8      77 // (0.30) tavg parameter for spectral flatness measure\n#define PRIOR_UPDATE_Q14        1638 // Q14(0.1) update parameter of prior model\n#define NOISE_UPDATE_Q8         26 // 26 ~= Q8(0.1) update parameter for noise\n// probability threshold for noise state in speech/noise likelihood\n#define ONE_MINUS_PROB_RANGE_Q8 205 // 205 ~= Q8(0.8)\n#define HIST_PAR_EST            1000 // histogram size for estimation of parameters\n//FEATURE EXTRACTION CONFIG\n//bin size of histogram\n#define BIN_SIZE_LRT            10\n//scale parameters: multiply dominant peaks of the histograms by scale factor to obtain\n// thresholds for prior model\n#define FACTOR_1_LRT_DIFF       6 //for LRT and spectral difference (5 times bigger)\n//for spectral_flatness: used when noise is flatter than speech (10 times bigger)\n#define FACTOR_2_FLAT_Q10       922\n//peak limit for spectral flatness (varies between 0 and 1)\n#define THRES_PEAK_FLAT         24 // * 2 * BIN_SIZE_FLAT_FX\n//limit on spacing of two highest peaks in histogram: spacing determined by bin size\n#define LIM_PEAK_SPACE_FLAT_DIFF    4 // * 2 * BIN_SIZE_DIFF_FX\n//limit on relevance of second peak:\n#define LIM_PEAK_WEIGHT_FLAT_DIFF   2\n#define THRES_FLUCT_LRT         10240 //=20 * inst->modelUpdate; fluctuation limit of LRT feat.\n//limit on the max and min values for the feature thresholds\n#define MAX_FLAT_Q10            38912 //  * 2 * BIN_SIZE_FLAT_FX\n#define MIN_FLAT_Q10            4096 //  * 2 * BIN_SIZE_FLAT_FX\n#define MAX_DIFF                100 // * 2 * BIN_SIZE_DIFF_FX\n#define MIN_DIFF                16 // * 2 * BIN_SIZE_DIFF_FX\n//criteria of weight of histogram peak  to accept/reject feature\n#define THRES_WEIGHT_FLAT_DIFF  154//(int)(0.3*(inst->modelUpdate)) for flatness and difference\n//\n#define STAT_UPDATES            9 // Update every 512 = 1 << 9 block\n#define ONE_MINUS_GAMMA_PAUSE_Q8    13 // ~= Q8(0.05) update for conservative noise estimate\n#define GAMMA_NOISE_TRANS_AND_SPEECH_Q8 3 // ~= Q8(0.01) update for transition and noise region\n#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_DEFINES_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/ns/main/source/windows_private.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_WINDOWS_PRIVATE_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_WINDOWS_PRIVATE_H_\n\n// Hanning window for 4ms 16kHz\nstatic const float kHanning64w128[128] = {\n0.00000000000000f, 0.02454122852291f, 0.04906767432742f,\n0.07356456359967f, 0.09801714032956f, 0.12241067519922f,\n0.14673047445536f, 0.17096188876030f, 0.19509032201613f,\n0.21910124015687f, 0.24298017990326f, 0.26671275747490f,\n0.29028467725446f, 0.31368174039889f, 0.33688985339222f,\n0.35989503653499f, 0.38268343236509f, 0.40524131400499f,\n0.42755509343028f, 0.44961132965461f, 0.47139673682600f,\n0.49289819222978f, 0.51410274419322f, 0.53499761988710f,\n0.55557023301960f, 0.57580819141785f, 0.59569930449243f,\n0.61523159058063f, 0.63439328416365f, 0.65317284295378f,\n0.67155895484702f, 0.68954054473707f, 0.70710678118655f,\n0.72424708295147f, 0.74095112535496f, 0.75720884650648f,\n0.77301045336274f, 0.78834642762661f, 0.80320753148064f,\n0.81758481315158f, 0.83146961230255f, 0.84485356524971f,\n0.85772861000027f, 0.87008699110871f, 0.88192126434835f,\n0.89322430119552f, 0.90398929312344f, 0.91420975570353f,\n0.92387953251129f, 0.93299279883474f, 0.94154406518302f,\n0.94952818059304f, 0.95694033573221f, 0.96377606579544f,\n0.97003125319454f, 0.97570213003853f, 0.98078528040323f,\n0.98527764238894f, 0.98917650996478f, 0.99247953459871f,\n0.99518472667220f, 0.99729045667869f, 0.99879545620517f,\n0.99969881869620f, 1.00000000000000f,\n0.99969881869620f, 0.99879545620517f, 0.99729045667869f,\n0.99518472667220f, 0.99247953459871f, 0.98917650996478f,\n0.98527764238894f, 0.98078528040323f, 0.97570213003853f,\n0.97003125319454f, 0.96377606579544f, 0.95694033573221f,\n0.94952818059304f, 0.94154406518302f, 0.93299279883474f,\n0.92387953251129f, 0.91420975570353f, 0.90398929312344f,\n0.89322430119552f, 0.88192126434835f, 0.87008699110871f,\n0.85772861000027f, 0.84485356524971f, 0.83146961230255f,\n0.81758481315158f, 0.80320753148064f, 0.78834642762661f,\n0.77301045336274f, 0.75720884650648f, 0.74095112535496f,\n0.72424708295147f, 0.70710678118655f, 0.68954054473707f,\n0.67155895484702f, 0.65317284295378f, 0.63439328416365f,\n0.61523159058063f, 0.59569930449243f, 0.57580819141785f,\n0.55557023301960f, 0.53499761988710f, 0.51410274419322f,\n0.49289819222978f, 0.47139673682600f, 0.44961132965461f,\n0.42755509343028f, 0.40524131400499f, 0.38268343236509f,\n0.35989503653499f, 0.33688985339222f, 0.31368174039889f,\n0.29028467725446f, 0.26671275747490f, 0.24298017990326f,\n0.21910124015687f, 0.19509032201613f, 0.17096188876030f,\n0.14673047445536f, 0.12241067519922f, 0.09801714032956f,\n0.07356456359967f, 0.04906767432742f, 0.02454122852291f\n};\n\n\n\n// hybrib Hanning & flat window\nstatic const float kBlocks80w128[128] = {\n(float)0.00000000, (float)0.03271908, (float)0.06540313, (float)0.09801714, (float)0.13052619,\n(float)0.16289547, (float)0.19509032, (float)0.22707626, (float)0.25881905, (float)0.29028468,\n(float)0.32143947, (float)0.35225005, (float)0.38268343, (float)0.41270703, (float)0.44228869,\n(float)0.47139674, (float)0.50000000, (float)0.52806785, (float)0.55557023, (float)0.58247770,\n(float)0.60876143, (float)0.63439328, (float)0.65934582, (float)0.68359230, (float)0.70710678,\n(float)0.72986407, (float)0.75183981, (float)0.77301045, (float)0.79335334, (float)0.81284668,\n(float)0.83146961, (float)0.84920218, (float)0.86602540, (float)0.88192126, (float)0.89687274,\n(float)0.91086382, (float)0.92387953, (float)0.93590593, (float)0.94693013, (float)0.95694034,\n(float)0.96592583, (float)0.97387698, (float)0.98078528, (float)0.98664333, (float)0.99144486,\n(float)0.99518473, (float)0.99785892, (float)0.99946459, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)0.99946459, (float)0.99785892, (float)0.99518473, (float)0.99144486,\n(float)0.98664333, (float)0.98078528, (float)0.97387698, (float)0.96592583, (float)0.95694034,\n(float)0.94693013, (float)0.93590593, (float)0.92387953, (float)0.91086382, (float)0.89687274,\n(float)0.88192126, (float)0.86602540, (float)0.84920218, (float)0.83146961, (float)0.81284668,\n(float)0.79335334, (float)0.77301045, (float)0.75183981, (float)0.72986407, (float)0.70710678,\n(float)0.68359230, (float)0.65934582, (float)0.63439328, (float)0.60876143, (float)0.58247770,\n(float)0.55557023, (float)0.52806785, (float)0.50000000, (float)0.47139674, (float)0.44228869,\n(float)0.41270703, (float)0.38268343, (float)0.35225005, (float)0.32143947, (float)0.29028468,\n(float)0.25881905, (float)0.22707626, (float)0.19509032, (float)0.16289547, (float)0.13052619,\n(float)0.09801714, (float)0.06540313, (float)0.03271908\n};\n\n// hybrib Hanning & flat window\nstatic const float kBlocks160w256[256] = {\n(float)0.00000000, (float)0.01636173, (float)0.03271908, (float)0.04906767, (float)0.06540313,\n(float)0.08172107, (float)0.09801714, (float)0.11428696, (float)0.13052619, (float)0.14673047,\n(float)0.16289547, (float)0.17901686, (float)0.19509032, (float)0.21111155, (float)0.22707626,\n(float)0.24298018, (float)0.25881905, (float)0.27458862, (float)0.29028468, (float)0.30590302,\n(float)0.32143947, (float)0.33688985, (float)0.35225005, (float)0.36751594, (float)0.38268343,\n(float)0.39774847, (float)0.41270703, (float)0.42755509, (float)0.44228869, (float)0.45690388,\n(float)0.47139674, (float)0.48576339, (float)0.50000000, (float)0.51410274, (float)0.52806785,\n(float)0.54189158, (float)0.55557023, (float)0.56910015, (float)0.58247770, (float)0.59569930,\n(float)0.60876143, (float)0.62166057, (float)0.63439328, (float)0.64695615, (float)0.65934582,\n(float)0.67155895, (float)0.68359230, (float)0.69544264, (float)0.70710678, (float)0.71858162,\n(float)0.72986407, (float)0.74095113, (float)0.75183981, (float)0.76252720, (float)0.77301045,\n(float)0.78328675, (float)0.79335334, (float)0.80320753, (float)0.81284668, (float)0.82226822,\n(float)0.83146961, (float)0.84044840, (float)0.84920218, (float)0.85772861, (float)0.86602540,\n(float)0.87409034, (float)0.88192126, (float)0.88951608, (float)0.89687274, (float)0.90398929,\n(float)0.91086382, (float)0.91749450, (float)0.92387953, (float)0.93001722, (float)0.93590593,\n(float)0.94154407, (float)0.94693013, (float)0.95206268, (float)0.95694034, (float)0.96156180,\n(float)0.96592583, (float)0.97003125, (float)0.97387698, (float)0.97746197, (float)0.98078528,\n(float)0.98384601, (float)0.98664333, (float)0.98917651, (float)0.99144486, (float)0.99344778,\n(float)0.99518473, (float)0.99665524, (float)0.99785892, (float)0.99879546, (float)0.99946459,\n(float)0.99986614, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)0.99986614, (float)0.99946459, (float)0.99879546, (float)0.99785892,\n(float)0.99665524, (float)0.99518473, (float)0.99344778, (float)0.99144486, (float)0.98917651,\n(float)0.98664333, (float)0.98384601, (float)0.98078528, (float)0.97746197, (float)0.97387698,\n(float)0.97003125, (float)0.96592583, (float)0.96156180, (float)0.95694034, (float)0.95206268,\n(float)0.94693013, (float)0.94154407, (float)0.93590593, (float)0.93001722, (float)0.92387953,\n(float)0.91749450, (float)0.91086382, (float)0.90398929, (float)0.89687274, (float)0.88951608,\n(float)0.88192126, (float)0.87409034, (float)0.86602540, (float)0.85772861, (float)0.84920218,\n(float)0.84044840, (float)0.83146961, (float)0.82226822, (float)0.81284668, (float)0.80320753,\n(float)0.79335334, (float)0.78328675, (float)0.77301045, (float)0.76252720, (float)0.75183981,\n(float)0.74095113, (float)0.72986407, (float)0.71858162, (float)0.70710678, (float)0.69544264,\n(float)0.68359230, (float)0.67155895, (float)0.65934582, (float)0.64695615, (float)0.63439328,\n(float)0.62166057, (float)0.60876143, (float)0.59569930, (float)0.58247770, (float)0.56910015,\n(float)0.55557023, (float)0.54189158, (float)0.52806785, (float)0.51410274, (float)0.50000000,\n(float)0.48576339, (float)0.47139674, (float)0.45690388, (float)0.44228869, (float)0.42755509,\n(float)0.41270703, (float)0.39774847, (float)0.38268343, (float)0.36751594, (float)0.35225005,\n(float)0.33688985, (float)0.32143947, (float)0.30590302, (float)0.29028468, (float)0.27458862,\n(float)0.25881905, (float)0.24298018, (float)0.22707626, (float)0.21111155, (float)0.19509032,\n(float)0.17901686, (float)0.16289547, (float)0.14673047, (float)0.13052619, (float)0.11428696,\n(float)0.09801714, (float)0.08172107, (float)0.06540313, (float)0.04906767, (float)0.03271908,\n(float)0.01636173\n};\n\n// hybrib Hanning & flat window: for 20ms\nstatic const float kBlocks320w512[512] = {\n(float)0.00000000, (float)0.00818114, (float)0.01636173, (float)0.02454123, (float)0.03271908,\n(float)0.04089475, (float)0.04906767, (float)0.05723732, (float)0.06540313, (float)0.07356456,\n(float)0.08172107, (float)0.08987211, (float)0.09801714, (float)0.10615561, (float)0.11428696,\n(float)0.12241068, (float)0.13052619, (float)0.13863297, (float)0.14673047, (float)0.15481816,\n(float)0.16289547, (float)0.17096189, (float)0.17901686, (float)0.18705985, (float)0.19509032,\n(float)0.20310773, (float)0.21111155, (float)0.21910124, (float)0.22707626, (float)0.23503609,\n(float)0.24298018, (float)0.25090801, (float)0.25881905, (float)0.26671276, (float)0.27458862,\n(float)0.28244610, (float)0.29028468, (float)0.29810383, (float)0.30590302, (float)0.31368174,\n(float)0.32143947, (float)0.32917568, (float)0.33688985, (float)0.34458148, (float)0.35225005,\n(float)0.35989504, (float)0.36751594, (float)0.37511224, (float)0.38268343, (float)0.39022901,\n(float)0.39774847, (float)0.40524131, (float)0.41270703, (float)0.42014512, (float)0.42755509,\n(float)0.43493645, (float)0.44228869, (float)0.44961133, (float)0.45690388, (float)0.46416584,\n(float)0.47139674, (float)0.47859608, (float)0.48576339, (float)0.49289819, (float)0.50000000,\n(float)0.50706834, (float)0.51410274, (float)0.52110274, (float)0.52806785, (float)0.53499762,\n(float)0.54189158, (float)0.54874927, (float)0.55557023, (float)0.56235401, (float)0.56910015,\n(float)0.57580819, (float)0.58247770, (float)0.58910822, (float)0.59569930, (float)0.60225052,\n(float)0.60876143, (float)0.61523159, (float)0.62166057, (float)0.62804795, (float)0.63439328,\n(float)0.64069616, (float)0.64695615, (float)0.65317284, (float)0.65934582, (float)0.66547466,\n(float)0.67155895, (float)0.67759830, (float)0.68359230, (float)0.68954054, (float)0.69544264,\n(float)0.70129818, (float)0.70710678, (float)0.71286806, (float)0.71858162, (float)0.72424708,\n(float)0.72986407, (float)0.73543221, (float)0.74095113, (float)0.74642045, (float)0.75183981,\n(float)0.75720885, (float)0.76252720, (float)0.76779452, (float)0.77301045, (float)0.77817464,\n(float)0.78328675, (float)0.78834643, (float)0.79335334, (float)0.79830715, (float)0.80320753,\n(float)0.80805415, (float)0.81284668, (float)0.81758481, (float)0.82226822, (float)0.82689659,\n(float)0.83146961, (float)0.83598698, (float)0.84044840, (float)0.84485357, (float)0.84920218,\n(float)0.85349396, (float)0.85772861, (float)0.86190585, (float)0.86602540, (float)0.87008699,\n(float)0.87409034, (float)0.87803519, (float)0.88192126, (float)0.88574831, (float)0.88951608,\n(float)0.89322430, (float)0.89687274, (float)0.90046115, (float)0.90398929, (float)0.90745693,\n(float)0.91086382, (float)0.91420976, (float)0.91749450, (float)0.92071783, (float)0.92387953,\n(float)0.92697940, (float)0.93001722, (float)0.93299280, (float)0.93590593, (float)0.93875641,\n(float)0.94154407, (float)0.94426870, (float)0.94693013, (float)0.94952818, (float)0.95206268,\n(float)0.95453345, (float)0.95694034, (float)0.95928317, (float)0.96156180, (float)0.96377607,\n(float)0.96592583, (float)0.96801094, (float)0.97003125, (float)0.97198664, (float)0.97387698,\n(float)0.97570213, (float)0.97746197, (float)0.97915640, (float)0.98078528, (float)0.98234852,\n(float)0.98384601, (float)0.98527764, (float)0.98664333, (float)0.98794298, (float)0.98917651,\n(float)0.99034383, (float)0.99144486, (float)0.99247953, (float)0.99344778, (float)0.99434953,\n(float)0.99518473, (float)0.99595331, (float)0.99665524, (float)0.99729046, (float)0.99785892,\n(float)0.99836060, (float)0.99879546, (float)0.99916346, (float)0.99946459, (float)0.99969882,\n(float)0.99986614, (float)0.99996653, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,\n(float)1.00000000, (float)0.99996653, (float)0.99986614, (float)0.99969882, (float)0.99946459,\n(float)0.99916346, (float)0.99879546, (float)0.99836060, (float)0.99785892, (float)0.99729046,\n(float)0.99665524, (float)0.99595331, (float)0.99518473, (float)0.99434953, (float)0.99344778,\n(float)0.99247953, (float)0.99144486, (float)0.99034383, (float)0.98917651, (float)0.98794298,\n(float)0.98664333, (float)0.98527764, (float)0.98384601, (float)0.98234852, (float)0.98078528,\n(float)0.97915640, (float)0.97746197, (float)0.97570213, (float)0.97387698, (float)0.97198664,\n(float)0.97003125, (float)0.96801094, (float)0.96592583, (float)0.96377607, (float)0.96156180,\n(float)0.95928317, (float)0.95694034, (float)0.95453345, (float)0.95206268, (float)0.94952818,\n(float)0.94693013, (float)0.94426870, (float)0.94154407, (float)0.93875641, (float)0.93590593,\n(float)0.93299280, (float)0.93001722, (float)0.92697940, (float)0.92387953, (float)0.92071783,\n(float)0.91749450, (float)0.91420976, (float)0.91086382, (float)0.90745693, (float)0.90398929,\n(float)0.90046115, (float)0.89687274, (float)0.89322430, (float)0.88951608, (float)0.88574831,\n(float)0.88192126, (float)0.87803519, (float)0.87409034, (float)0.87008699, (float)0.86602540,\n(float)0.86190585, (float)0.85772861, (float)0.85349396, (float)0.84920218, (float)0.84485357,\n(float)0.84044840, (float)0.83598698, (float)0.83146961, (float)0.82689659, (float)0.82226822,\n(float)0.81758481, (float)0.81284668, (float)0.80805415, (float)0.80320753, (float)0.79830715,\n(float)0.79335334, (float)0.78834643, (float)0.78328675, (float)0.77817464, (float)0.77301045,\n(float)0.76779452, (float)0.76252720, (float)0.75720885, (float)0.75183981, (float)0.74642045,\n(float)0.74095113, (float)0.73543221, (float)0.72986407, (float)0.72424708, (float)0.71858162,\n(float)0.71286806, (float)0.70710678, (float)0.70129818, (float)0.69544264, (float)0.68954054,\n(float)0.68359230, (float)0.67759830, (float)0.67155895, (float)0.66547466, (float)0.65934582,\n(float)0.65317284, (float)0.64695615, (float)0.64069616, (float)0.63439328, (float)0.62804795,\n(float)0.62166057, (float)0.61523159, (float)0.60876143, (float)0.60225052, (float)0.59569930,\n(float)0.58910822, (float)0.58247770, (float)0.57580819, (float)0.56910015, (float)0.56235401,\n(float)0.55557023, (float)0.54874927, (float)0.54189158, (float)0.53499762, (float)0.52806785,\n(float)0.52110274, (float)0.51410274, (float)0.50706834, (float)0.50000000, (float)0.49289819,\n(float)0.48576339, (float)0.47859608, (float)0.47139674, (float)0.46416584, (float)0.45690388,\n(float)0.44961133, (float)0.44228869, (float)0.43493645, (float)0.42755509, (float)0.42014512,\n(float)0.41270703, (float)0.40524131, (float)0.39774847, (float)0.39022901, (float)0.38268343,\n(float)0.37511224, (float)0.36751594, (float)0.35989504, (float)0.35225005, (float)0.34458148,\n(float)0.33688985, (float)0.32917568, (float)0.32143947, (float)0.31368174, (float)0.30590302,\n(float)0.29810383, (float)0.29028468, (float)0.28244610, (float)0.27458862, (float)0.26671276,\n(float)0.25881905, (float)0.25090801, (float)0.24298018, (float)0.23503609, (float)0.22707626,\n(float)0.21910124, (float)0.21111155, (float)0.20310773, (float)0.19509032, (float)0.18705985,\n(float)0.17901686, (float)0.17096189, (float)0.16289547, (float)0.15481816, (float)0.14673047,\n(float)0.13863297, (float)0.13052619, (float)0.12241068, (float)0.11428696, (float)0.10615561,\n(float)0.09801714, (float)0.08987211, (float)0.08172107, (float)0.07356456, (float)0.06540313,\n(float)0.05723732, (float)0.04906767, (float)0.04089475, (float)0.03271908, (float)0.02454123,\n(float)0.01636173, (float)0.00818114\n};\n\n\n// Hanning window: for 15ms at 16kHz with symmetric zeros\nstatic const float kBlocks240w512[512] = {\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00654494, (float)0.01308960, (float)0.01963369,\n(float)0.02617695, (float)0.03271908, (float)0.03925982, (float)0.04579887, (float)0.05233596,\n(float)0.05887080, (float)0.06540313, (float)0.07193266, (float)0.07845910, (float)0.08498218,\n(float)0.09150162, (float)0.09801714, (float)0.10452846, (float)0.11103531, (float)0.11753740,\n(float)0.12403446, (float)0.13052620, (float)0.13701233, (float)0.14349262, (float)0.14996676,\n(float)0.15643448, (float)0.16289547, (float)0.16934951, (float)0.17579629, (float)0.18223552,\n(float)0.18866697, (float)0.19509032, (float)0.20150533, (float)0.20791170, (float)0.21430916,\n(float)0.22069745, (float)0.22707628, (float)0.23344538, (float)0.23980446, (float)0.24615330,\n(float)0.25249159, (float)0.25881904, (float)0.26513544, (float)0.27144045, (float)0.27773386,\n(float)0.28401536, (float)0.29028466, (float)0.29654160, (float)0.30278578, (float)0.30901700,\n(float)0.31523499, (float)0.32143945, (float)0.32763019, (float)0.33380687, (float)0.33996925,\n(float)0.34611708, (float)0.35225007, (float)0.35836795, (float)0.36447051, (float)0.37055743,\n(float)0.37662852, (float)0.38268346, (float)0.38872197, (float)0.39474389, (float)0.40074885,\n(float)0.40673664, (float)0.41270703, (float)0.41865975, (float)0.42459452, (float)0.43051112,\n(float)0.43640924, (float)0.44228873, (float)0.44814920, (float)0.45399052, (float)0.45981237,\n(float)0.46561453, (float)0.47139674, (float)0.47715878, (float)0.48290035, (float)0.48862126,\n(float)0.49432120, (float)0.50000000, (float)0.50565743, (float)0.51129311, (float)0.51690692,\n(float)0.52249855, (float)0.52806789, (float)0.53361452, (float)0.53913832, (float)0.54463905,\n(float)0.55011642, (float)0.55557024, (float)0.56100029, (float)0.56640625, (float)0.57178795,\n(float)0.57714522, (float)0.58247769, (float)0.58778524, (float)0.59306765, (float)0.59832460,\n(float)0.60355598, (float)0.60876143, (float)0.61394083, (float)0.61909395, (float)0.62422055,\n(float)0.62932038, (float)0.63439333, (float)0.63943899, (float)0.64445734, (float)0.64944810,\n(float)0.65441096, (float)0.65934587, (float)0.66425246, (float)0.66913062, (float)0.67398012,\n(float)0.67880076, (float)0.68359232, (float)0.68835455, (float)0.69308740, (float)0.69779050,\n(float)0.70246369, (float)0.70710677, (float)0.71171963, (float)0.71630198, (float)0.72085363,\n(float)0.72537440, (float)0.72986406, (float)0.73432255, (float)0.73874950, (float)0.74314487,\n(float)0.74750835, (float)0.75183982, (float)0.75613910, (float)0.76040596, (float)0.76464027,\n(float)0.76884186, (float)0.77301043, (float)0.77714598, (float)0.78124821, (float)0.78531694,\n(float)0.78935206, (float)0.79335338, (float)0.79732066, (float)0.80125386, (float)0.80515265,\n(float)0.80901700, (float)0.81284672, (float)0.81664157, (float)0.82040149, (float)0.82412618,\n(float)0.82781565, (float)0.83146966, (float)0.83508795, (float)0.83867061, (float)0.84221727,\n(float)0.84572780, (float)0.84920216, (float)0.85264021, (float)0.85604161, (float)0.85940641,\n(float)0.86273444, (float)0.86602545, (float)0.86927933, (float)0.87249607, (float)0.87567532,\n(float)0.87881714, (float)0.88192129, (float)0.88498765, (float)0.88801610, (float)0.89100653,\n(float)0.89395881, (float)0.89687276, (float)0.89974827, (float)0.90258533, (float)0.90538365,\n(float)0.90814316, (float)0.91086388, (float)0.91354549, (float)0.91618794, (float)0.91879123,\n(float)0.92135513, (float)0.92387950, (float)0.92636442, (float)0.92880958, (float)0.93121493,\n(float)0.93358046, (float)0.93590593, (float)0.93819135, (float)0.94043654, (float)0.94264150,\n(float)0.94480604, (float)0.94693011, (float)0.94901365, (float)0.95105654, (float)0.95305866,\n(float)0.95501995, (float)0.95694035, (float)0.95881975, (float)0.96065807, (float)0.96245527,\n(float)0.96421117, (float)0.96592581, (float)0.96759909, (float)0.96923089, (float)0.97082120,\n(float)0.97236991, (float)0.97387701, (float)0.97534233, (float)0.97676587, (float)0.97814763,\n(float)0.97948742, (float)0.98078531, (float)0.98204112, (float)0.98325491, (float)0.98442656,\n(float)0.98555607, (float)0.98664331, (float)0.98768836, (float)0.98869103, (float)0.98965138,\n(float)0.99056935, (float)0.99144489, (float)0.99227792, (float)0.99306846, (float)0.99381649,\n(float)0.99452192, (float)0.99518472, (float)0.99580491, (float)0.99638247, (float)0.99691731,\n(float)0.99740952, (float)0.99785894, (float)0.99826562, (float)0.99862951, (float)0.99895066,\n(float)0.99922901, (float)0.99946457, (float)0.99965733, (float)0.99980724, (float)0.99991435,\n(float)0.99997860, (float)1.00000000, (float)0.99997860, (float)0.99991435, (float)0.99980724,\n(float)0.99965733, (float)0.99946457, (float)0.99922901, (float)0.99895066, (float)0.99862951,\n(float)0.99826562, (float)0.99785894, (float)0.99740946, (float)0.99691731, (float)0.99638247,\n(float)0.99580491, (float)0.99518472, (float)0.99452192, (float)0.99381644, (float)0.99306846,\n(float)0.99227792, (float)0.99144489, (float)0.99056935, (float)0.98965138, (float)0.98869103,\n(float)0.98768836, (float)0.98664331, (float)0.98555607, (float)0.98442656, (float)0.98325491,\n(float)0.98204112, (float)0.98078525, (float)0.97948742, (float)0.97814757, (float)0.97676587,\n(float)0.97534227, (float)0.97387695, (float)0.97236991, (float)0.97082120, (float)0.96923089,\n(float)0.96759909, (float)0.96592581, (float)0.96421117, (float)0.96245521, (float)0.96065807,\n(float)0.95881969, (float)0.95694029, (float)0.95501995, (float)0.95305860, (float)0.95105648,\n(float)0.94901365, (float)0.94693011, (float)0.94480604, (float)0.94264150, (float)0.94043654,\n(float)0.93819129, (float)0.93590593, (float)0.93358046, (float)0.93121493, (float)0.92880952,\n(float)0.92636436, (float)0.92387950, (float)0.92135507, (float)0.91879123, (float)0.91618794,\n(float)0.91354543, (float)0.91086382, (float)0.90814310, (float)0.90538365, (float)0.90258527,\n(float)0.89974827, (float)0.89687276, (float)0.89395875, (float)0.89100647, (float)0.88801610,\n(float)0.88498759, (float)0.88192123, (float)0.87881714, (float)0.87567532, (float)0.87249595,\n(float)0.86927933, (float)0.86602539, (float)0.86273432, (float)0.85940641, (float)0.85604161,\n(float)0.85264009, (float)0.84920216, (float)0.84572780, (float)0.84221715, (float)0.83867055,\n(float)0.83508795, (float)0.83146954, (float)0.82781565, (float)0.82412612, (float)0.82040137,\n(float)0.81664157, (float)0.81284660, (float)0.80901700, (float)0.80515265, (float)0.80125374,\n(float)0.79732066, (float)0.79335332, (float)0.78935200, (float)0.78531694, (float)0.78124815,\n(float)0.77714586, (float)0.77301049, (float)0.76884180, (float)0.76464021, (float)0.76040596,\n(float)0.75613904, (float)0.75183970, (float)0.74750835, (float)0.74314481, (float)0.73874938,\n(float)0.73432249, (float)0.72986400, (float)0.72537428, (float)0.72085363, (float)0.71630186,\n(float)0.71171951, (float)0.70710677, (float)0.70246363, (float)0.69779032, (float)0.69308734,\n(float)0.68835449, (float)0.68359220, (float)0.67880070, (float)0.67398006, (float)0.66913044,\n(float)0.66425240, (float)0.65934575, (float)0.65441096, (float)0.64944804, (float)0.64445722,\n(float)0.63943905, (float)0.63439327, (float)0.62932026, (float)0.62422055, (float)0.61909389,\n(float)0.61394072, (float)0.60876143, (float)0.60355592, (float)0.59832448, (float)0.59306765,\n(float)0.58778518, (float)0.58247757, (float)0.57714522, (float)0.57178789, (float)0.56640613,\n(float)0.56100023, (float)0.55557019, (float)0.55011630, (float)0.54463905, (float)0.53913826,\n(float)0.53361434, (float)0.52806783, (float)0.52249849, (float)0.51690674, (float)0.51129305,\n(float)0.50565726, (float)0.50000006, (float)0.49432117, (float)0.48862115, (float)0.48290038,\n(float)0.47715873, (float)0.47139663, (float)0.46561456, (float)0.45981231, (float)0.45399037,\n(float)0.44814920, (float)0.44228864, (float)0.43640912, (float)0.43051112, (float)0.42459446,\n(float)0.41865960, (float)0.41270703, (float)0.40673658, (float)0.40074870, (float)0.39474386,\n(float)0.38872188, (float)0.38268328, (float)0.37662849, (float)0.37055734, (float)0.36447033,\n(float)0.35836792, (float)0.35224995, (float)0.34611690, (float)0.33996922, (float)0.33380675,\n(float)0.32763001, (float)0.32143945, (float)0.31523487, (float)0.30901679, (float)0.30278572,\n(float)0.29654145, (float)0.29028472, (float)0.28401530, (float)0.27773371, (float)0.27144048,\n(float)0.26513538, (float)0.25881892, (float)0.25249159, (float)0.24615324, (float)0.23980433,\n(float)0.23344538, (float)0.22707619, (float)0.22069728, (float)0.21430916, (float)0.20791161,\n(float)0.20150517, (float)0.19509031, (float)0.18866688, (float)0.18223536, (float)0.17579627,\n(float)0.16934940, (float)0.16289529, (float)0.15643445, (float)0.14996666, (float)0.14349243,\n(float)0.13701232, (float)0.13052608, (float)0.12403426, (float)0.11753736, (float)0.11103519,\n(float)0.10452849, (float)0.09801710, (float)0.09150149, (float)0.08498220, (float)0.07845904,\n(float)0.07193252, (float)0.06540315, (float)0.05887074, (float)0.05233581, (float)0.04579888,\n(float)0.03925974, (float)0.03271893, (float)0.02617695, (float)0.01963361, (float)0.01308943,\n(float)0.00654493, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000\n};\n\n\n// Hanning window: for 30ms with 1024 fft with symmetric zeros at 16kHz\nstatic const float kBlocks480w1024[1024] = {\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00327249, (float)0.00654494,\n(float)0.00981732, (float)0.01308960, (float)0.01636173, (float)0.01963369, (float)0.02290544,\n(float)0.02617695, (float)0.02944817, (float)0.03271908, (float)0.03598964, (float)0.03925982,\n(float)0.04252957, (float)0.04579887, (float)0.04906768, (float)0.05233596, (float)0.05560368,\n(float)0.05887080, (float)0.06213730, (float)0.06540313, (float)0.06866825, (float)0.07193266,\n(float)0.07519628, (float)0.07845910, (float)0.08172107, (float)0.08498218, (float)0.08824237,\n(float)0.09150162, (float)0.09475989, (float)0.09801714, (float)0.10127335, (float)0.10452846,\n(float)0.10778246, (float)0.11103531, (float)0.11428697, (float)0.11753740, (float)0.12078657,\n(float)0.12403446, (float)0.12728101, (float)0.13052620, (float)0.13376999, (float)0.13701233,\n(float)0.14025325, (float)0.14349262, (float)0.14673047, (float)0.14996676, (float)0.15320145,\n(float)0.15643448, (float)0.15966582, (float)0.16289547, (float)0.16612339, (float)0.16934951,\n(float)0.17257382, (float)0.17579629, (float)0.17901687, (float)0.18223552, (float)0.18545224,\n(float)0.18866697, (float)0.19187967, (float)0.19509032, (float)0.19829889, (float)0.20150533,\n(float)0.20470962, (float)0.20791170, (float)0.21111156, (float)0.21430916, (float)0.21750447,\n(float)0.22069745, (float)0.22388805, (float)0.22707628, (float)0.23026206, (float)0.23344538,\n(float)0.23662618, (float)0.23980446, (float)0.24298020, (float)0.24615330, (float)0.24932377,\n(float)0.25249159, (float)0.25565669, (float)0.25881904, (float)0.26197866, (float)0.26513544,\n(float)0.26828939, (float)0.27144045, (float)0.27458861, (float)0.27773386, (float)0.28087610,\n(float)0.28401536, (float)0.28715158, (float)0.29028466, (float)0.29341471, (float)0.29654160,\n(float)0.29966527, (float)0.30278578, (float)0.30590302, (float)0.30901700, (float)0.31212768,\n(float)0.31523499, (float)0.31833893, (float)0.32143945, (float)0.32453656, (float)0.32763019,\n(float)0.33072028, (float)0.33380687, (float)0.33688986, (float)0.33996925, (float)0.34304500,\n(float)0.34611708, (float)0.34918544, (float)0.35225007, (float)0.35531089, (float)0.35836795,\n(float)0.36142117, (float)0.36447051, (float)0.36751595, (float)0.37055743, (float)0.37359497,\n(float)0.37662852, (float)0.37965801, (float)0.38268346, (float)0.38570479, (float)0.38872197,\n(float)0.39173502, (float)0.39474389, (float)0.39774847, (float)0.40074885, (float)0.40374491,\n(float)0.40673664, (float)0.40972406, (float)0.41270703, (float)0.41568562, (float)0.41865975,\n(float)0.42162940, (float)0.42459452, (float)0.42755508, (float)0.43051112, (float)0.43346250,\n(float)0.43640924, (float)0.43935132, (float)0.44228873, (float)0.44522133, (float)0.44814920,\n(float)0.45107228, (float)0.45399052, (float)0.45690390, (float)0.45981237, (float)0.46271592,\n(float)0.46561453, (float)0.46850815, (float)0.47139674, (float)0.47428030, (float)0.47715878,\n(float)0.48003215, (float)0.48290035, (float)0.48576337, (float)0.48862126, (float)0.49147385,\n(float)0.49432120, (float)0.49716330, (float)0.50000000, (float)0.50283140, (float)0.50565743,\n(float)0.50847799, (float)0.51129311, (float)0.51410276, (float)0.51690692, (float)0.51970553,\n(float)0.52249855, (float)0.52528602, (float)0.52806789, (float)0.53084403, (float)0.53361452,\n(float)0.53637928, (float)0.53913832, (float)0.54189163, (float)0.54463905, (float)0.54738063,\n(float)0.55011642, (float)0.55284631, (float)0.55557024, (float)0.55828828, (float)0.56100029,\n(float)0.56370628, (float)0.56640625, (float)0.56910014, (float)0.57178795, (float)0.57446963,\n(float)0.57714522, (float)0.57981455, (float)0.58247769, (float)0.58513463, (float)0.58778524,\n(float)0.59042960, (float)0.59306765, (float)0.59569931, (float)0.59832460, (float)0.60094351,\n(float)0.60355598, (float)0.60616195, (float)0.60876143, (float)0.61135441, (float)0.61394083,\n(float)0.61652070, (float)0.61909395, (float)0.62166059, (float)0.62422055, (float)0.62677383,\n(float)0.62932038, (float)0.63186020, (float)0.63439333, (float)0.63691956, (float)0.63943899,\n(float)0.64195162, (float)0.64445734, (float)0.64695615, (float)0.64944810, (float)0.65193301,\n(float)0.65441096, (float)0.65688187, (float)0.65934587, (float)0.66180271, (float)0.66425246,\n(float)0.66669512, (float)0.66913062, (float)0.67155898, (float)0.67398012, (float)0.67639405,\n(float)0.67880076, (float)0.68120021, (float)0.68359232, (float)0.68597710, (float)0.68835455,\n(float)0.69072467, (float)0.69308740, (float)0.69544262, (float)0.69779050, (float)0.70013082,\n(float)0.70246369, (float)0.70478904, (float)0.70710677, (float)0.70941699, (float)0.71171963,\n(float)0.71401459, (float)0.71630198, (float)0.71858168, (float)0.72085363, (float)0.72311789,\n(float)0.72537440, (float)0.72762316, (float)0.72986406, (float)0.73209721, (float)0.73432255,\n(float)0.73653996, (float)0.73874950, (float)0.74095118, (float)0.74314487, (float)0.74533057,\n(float)0.74750835, (float)0.74967808, (float)0.75183982, (float)0.75399351, (float)0.75613910,\n(float)0.75827658, (float)0.76040596, (float)0.76252723, (float)0.76464027, (float)0.76674515,\n(float)0.76884186, (float)0.77093029, (float)0.77301043, (float)0.77508241, (float)0.77714598,\n(float)0.77920127, (float)0.78124821, (float)0.78328675, (float)0.78531694, (float)0.78733873,\n(float)0.78935206, (float)0.79135692, (float)0.79335338, (float)0.79534125, (float)0.79732066,\n(float)0.79929149, (float)0.80125386, (float)0.80320752, (float)0.80515265, (float)0.80708915,\n(float)0.80901700, (float)0.81093621, (float)0.81284672, (float)0.81474853, (float)0.81664157,\n(float)0.81852591, (float)0.82040149, (float)0.82226825, (float)0.82412618, (float)0.82597536,\n(float)0.82781565, (float)0.82964706, (float)0.83146966, (float)0.83328325, (float)0.83508795,\n(float)0.83688378, (float)0.83867061, (float)0.84044838, (float)0.84221727, (float)0.84397703,\n(float)0.84572780, (float)0.84746957, (float)0.84920216, (float)0.85092574, (float)0.85264021,\n(float)0.85434544, (float)0.85604161, (float)0.85772866, (float)0.85940641, (float)0.86107504,\n(float)0.86273444, (float)0.86438453, (float)0.86602545, (float)0.86765707, (float)0.86927933,\n(float)0.87089235, (float)0.87249607, (float)0.87409031, (float)0.87567532, (float)0.87725097,\n(float)0.87881714, (float)0.88037390, (float)0.88192129, (float)0.88345921, (float)0.88498765,\n(float)0.88650668, (float)0.88801610, (float)0.88951612, (float)0.89100653, (float)0.89248741,\n(float)0.89395881, (float)0.89542055, (float)0.89687276, (float)0.89831537, (float)0.89974827,\n(float)0.90117162, (float)0.90258533, (float)0.90398932, (float)0.90538365, (float)0.90676826,\n(float)0.90814316, (float)0.90950841, (float)0.91086388, (float)0.91220951, (float)0.91354549,\n(float)0.91487163, (float)0.91618794, (float)0.91749454, (float)0.91879123, (float)0.92007810,\n(float)0.92135513, (float)0.92262226, (float)0.92387950, (float)0.92512691, (float)0.92636442,\n(float)0.92759192, (float)0.92880958, (float)0.93001723, (float)0.93121493, (float)0.93240267,\n(float)0.93358046, (float)0.93474817, (float)0.93590593, (float)0.93705362, (float)0.93819135,\n(float)0.93931901, (float)0.94043654, (float)0.94154406, (float)0.94264150, (float)0.94372880,\n(float)0.94480604, (float)0.94587320, (float)0.94693011, (float)0.94797695, (float)0.94901365,\n(float)0.95004016, (float)0.95105654, (float)0.95206273, (float)0.95305866, (float)0.95404440,\n(float)0.95501995, (float)0.95598525, (float)0.95694035, (float)0.95788521, (float)0.95881975,\n(float)0.95974404, (float)0.96065807, (float)0.96156180, (float)0.96245527, (float)0.96333838,\n(float)0.96421117, (float)0.96507370, (float)0.96592581, (float)0.96676767, (float)0.96759909,\n(float)0.96842021, (float)0.96923089, (float)0.97003126, (float)0.97082120, (float)0.97160077,\n(float)0.97236991, (float)0.97312868, (float)0.97387701, (float)0.97461486, (float)0.97534233,\n(float)0.97605932, (float)0.97676587, (float)0.97746199, (float)0.97814763, (float)0.97882277,\n(float)0.97948742, (float)0.98014158, (float)0.98078531, (float)0.98141843, (float)0.98204112,\n(float)0.98265332, (float)0.98325491, (float)0.98384601, (float)0.98442656, (float)0.98499662,\n(float)0.98555607, (float)0.98610497, (float)0.98664331, (float)0.98717111, (float)0.98768836,\n(float)0.98819500, (float)0.98869103, (float)0.98917651, (float)0.98965138, (float)0.99011570,\n(float)0.99056935, (float)0.99101239, (float)0.99144489, (float)0.99186671, (float)0.99227792,\n(float)0.99267852, (float)0.99306846, (float)0.99344778, (float)0.99381649, (float)0.99417448,\n(float)0.99452192, (float)0.99485862, (float)0.99518472, (float)0.99550015, (float)0.99580491,\n(float)0.99609905, (float)0.99638247, (float)0.99665523, (float)0.99691731, (float)0.99716878,\n(float)0.99740952, (float)0.99763954, (float)0.99785894, (float)0.99806762, (float)0.99826562,\n(float)0.99845290, (float)0.99862951, (float)0.99879545, (float)0.99895066, (float)0.99909520,\n(float)0.99922901, (float)0.99935216, (float)0.99946457, (float)0.99956632, (float)0.99965733,\n(float)0.99973762, (float)0.99980724, (float)0.99986613, (float)0.99991435, (float)0.99995178,\n(float)0.99997860, (float)0.99999464, (float)1.00000000, (float)0.99999464, (float)0.99997860,\n(float)0.99995178, (float)0.99991435, (float)0.99986613, (float)0.99980724, (float)0.99973762,\n(float)0.99965733, (float)0.99956632, (float)0.99946457, (float)0.99935216, (float)0.99922901,\n(float)0.99909520, (float)0.99895066, (float)0.99879545, (float)0.99862951, (float)0.99845290,\n(float)0.99826562, (float)0.99806762, (float)0.99785894, (float)0.99763954, (float)0.99740946,\n(float)0.99716872, (float)0.99691731, (float)0.99665523, (float)0.99638247, (float)0.99609905,\n(float)0.99580491, (float)0.99550015, (float)0.99518472, (float)0.99485862, (float)0.99452192,\n(float)0.99417448, (float)0.99381644, (float)0.99344778, (float)0.99306846, (float)0.99267852,\n(float)0.99227792, (float)0.99186671, (float)0.99144489, (float)0.99101239, (float)0.99056935,\n(float)0.99011564, (float)0.98965138, (float)0.98917651, (float)0.98869103, (float)0.98819494,\n(float)0.98768836, (float)0.98717111, (float)0.98664331, (float)0.98610497, (float)0.98555607,\n(float)0.98499656, (float)0.98442656, (float)0.98384601, (float)0.98325491, (float)0.98265326,\n(float)0.98204112, (float)0.98141843, (float)0.98078525, (float)0.98014158, (float)0.97948742,\n(float)0.97882277, (float)0.97814757, (float)0.97746193, (float)0.97676587, (float)0.97605932,\n(float)0.97534227, (float)0.97461486, (float)0.97387695, (float)0.97312862, (float)0.97236991,\n(float)0.97160077, (float)0.97082120, (float)0.97003126, (float)0.96923089, (float)0.96842015,\n(float)0.96759909, (float)0.96676761, (float)0.96592581, (float)0.96507365, (float)0.96421117,\n(float)0.96333838, (float)0.96245521, (float)0.96156180, (float)0.96065807, (float)0.95974404,\n(float)0.95881969, (float)0.95788515, (float)0.95694029, (float)0.95598525, (float)0.95501995,\n(float)0.95404440, (float)0.95305860, (float)0.95206267, (float)0.95105648, (float)0.95004016,\n(float)0.94901365, (float)0.94797695, (float)0.94693011, (float)0.94587314, (float)0.94480604,\n(float)0.94372880, (float)0.94264150, (float)0.94154406, (float)0.94043654, (float)0.93931895,\n(float)0.93819129, (float)0.93705362, (float)0.93590593, (float)0.93474817, (float)0.93358046,\n(float)0.93240267, (float)0.93121493, (float)0.93001723, (float)0.92880952, (float)0.92759192,\n(float)0.92636436, (float)0.92512691, (float)0.92387950, (float)0.92262226, (float)0.92135507,\n(float)0.92007804, (float)0.91879123, (float)0.91749448, (float)0.91618794, (float)0.91487157,\n(float)0.91354543, (float)0.91220951, (float)0.91086382, (float)0.90950835, (float)0.90814310,\n(float)0.90676820, (float)0.90538365, (float)0.90398932, (float)0.90258527, (float)0.90117157,\n(float)0.89974827, (float)0.89831525, (float)0.89687276, (float)0.89542055, (float)0.89395875,\n(float)0.89248741, (float)0.89100647, (float)0.88951600, (float)0.88801610, (float)0.88650662,\n(float)0.88498759, (float)0.88345915, (float)0.88192123, (float)0.88037384, (float)0.87881714,\n(float)0.87725091, (float)0.87567532, (float)0.87409031, (float)0.87249595, (float)0.87089223,\n(float)0.86927933, (float)0.86765701, (float)0.86602539, (float)0.86438447, (float)0.86273432,\n(float)0.86107504, (float)0.85940641, (float)0.85772860, (float)0.85604161, (float)0.85434544,\n(float)0.85264009, (float)0.85092574, (float)0.84920216, (float)0.84746951, (float)0.84572780,\n(float)0.84397697, (float)0.84221715, (float)0.84044844, (float)0.83867055, (float)0.83688372,\n(float)0.83508795, (float)0.83328319, (float)0.83146954, (float)0.82964706, (float)0.82781565,\n(float)0.82597530, (float)0.82412612, (float)0.82226813, (float)0.82040137, (float)0.81852591,\n(float)0.81664157, (float)0.81474847, (float)0.81284660, (float)0.81093609, (float)0.80901700,\n(float)0.80708915, (float)0.80515265, (float)0.80320752, (float)0.80125374, (float)0.79929143,\n(float)0.79732066, (float)0.79534125, (float)0.79335332, (float)0.79135686, (float)0.78935200,\n(float)0.78733861, (float)0.78531694, (float)0.78328675, (float)0.78124815, (float)0.77920121,\n(float)0.77714586, (float)0.77508223, (float)0.77301049, (float)0.77093029, (float)0.76884180,\n(float)0.76674509, (float)0.76464021, (float)0.76252711, (float)0.76040596, (float)0.75827658,\n(float)0.75613904, (float)0.75399339, (float)0.75183970, (float)0.74967796, (float)0.74750835,\n(float)0.74533057, (float)0.74314481, (float)0.74095106, (float)0.73874938, (float)0.73653996,\n(float)0.73432249, (float)0.73209721, (float)0.72986400, (float)0.72762305, (float)0.72537428,\n(float)0.72311789, (float)0.72085363, (float)0.71858162, (float)0.71630186, (float)0.71401453,\n(float)0.71171951, (float)0.70941705, (float)0.70710677, (float)0.70478898, (float)0.70246363,\n(float)0.70013070, (float)0.69779032, (float)0.69544268, (float)0.69308734, (float)0.69072461,\n(float)0.68835449, (float)0.68597704, (float)0.68359220, (float)0.68120021, (float)0.67880070,\n(float)0.67639399, (float)0.67398006, (float)0.67155886, (float)0.66913044, (float)0.66669512,\n(float)0.66425240, (float)0.66180259, (float)0.65934575, (float)0.65688181, (float)0.65441096,\n(float)0.65193301, (float)0.64944804, (float)0.64695609, (float)0.64445722, (float)0.64195150,\n(float)0.63943905, (float)0.63691956, (float)0.63439327, (float)0.63186014, (float)0.62932026,\n(float)0.62677372, (float)0.62422055, (float)0.62166059, (float)0.61909389, (float)0.61652064,\n(float)0.61394072, (float)0.61135429, (float)0.60876143, (float)0.60616189, (float)0.60355592,\n(float)0.60094339, (float)0.59832448, (float)0.59569913, (float)0.59306765, (float)0.59042960,\n(float)0.58778518, (float)0.58513451, (float)0.58247757, (float)0.57981461, (float)0.57714522,\n(float)0.57446963, (float)0.57178789, (float)0.56910002, (float)0.56640613, (float)0.56370628,\n(float)0.56100023, (float)0.55828822, (float)0.55557019, (float)0.55284619, (float)0.55011630,\n(float)0.54738069, (float)0.54463905, (float)0.54189152, (float)0.53913826, (float)0.53637916,\n(float)0.53361434, (float)0.53084403, (float)0.52806783, (float)0.52528596, (float)0.52249849,\n(float)0.51970541, (float)0.51690674, (float)0.51410276, (float)0.51129305, (float)0.50847787,\n(float)0.50565726, (float)0.50283122, (float)0.50000006, (float)0.49716327, (float)0.49432117,\n(float)0.49147379, (float)0.48862115, (float)0.48576325, (float)0.48290038, (float)0.48003212,\n(float)0.47715873, (float)0.47428021, (float)0.47139663, (float)0.46850798, (float)0.46561456,\n(float)0.46271589, (float)0.45981231, (float)0.45690379, (float)0.45399037, (float)0.45107210,\n(float)0.44814920, (float)0.44522130, (float)0.44228864, (float)0.43935123, (float)0.43640912,\n(float)0.43346232, (float)0.43051112, (float)0.42755505, (float)0.42459446, (float)0.42162928,\n(float)0.41865960, (float)0.41568545, (float)0.41270703, (float)0.40972400, (float)0.40673658,\n(float)0.40374479, (float)0.40074870, (float)0.39774850, (float)0.39474386, (float)0.39173496,\n(float)0.38872188, (float)0.38570464, (float)0.38268328, (float)0.37965804, (float)0.37662849,\n(float)0.37359491, (float)0.37055734, (float)0.36751580, (float)0.36447033, (float)0.36142117,\n(float)0.35836792, (float)0.35531086, (float)0.35224995, (float)0.34918529, (float)0.34611690,\n(float)0.34304500, (float)0.33996922, (float)0.33688980, (float)0.33380675, (float)0.33072016,\n(float)0.32763001, (float)0.32453656, (float)0.32143945, (float)0.31833887, (float)0.31523487,\n(float)0.31212750, (float)0.30901679, (float)0.30590302, (float)0.30278572, (float)0.29966521,\n(float)0.29654145, (float)0.29341453, (float)0.29028472, (float)0.28715155, (float)0.28401530,\n(float)0.28087601, (float)0.27773371, (float)0.27458847, (float)0.27144048, (float)0.26828936,\n(float)0.26513538, (float)0.26197854, (float)0.25881892, (float)0.25565651, (float)0.25249159,\n(float)0.24932374, (float)0.24615324, (float)0.24298008, (float)0.23980433, (float)0.23662600,\n(float)0.23344538, (float)0.23026201, (float)0.22707619, (float)0.22388794, (float)0.22069728,\n(float)0.21750426, (float)0.21430916, (float)0.21111152, (float)0.20791161, (float)0.20470949,\n(float)0.20150517, (float)0.19829892, (float)0.19509031, (float)0.19187963, (float)0.18866688,\n(float)0.18545210, (float)0.18223536, (float)0.17901689, (float)0.17579627, (float)0.17257376,\n(float)0.16934940, (float)0.16612324, (float)0.16289529, (float)0.15966584, (float)0.15643445,\n(float)0.15320137, (float)0.14996666, (float)0.14673033, (float)0.14349243, (float)0.14025325,\n(float)0.13701232, (float)0.13376991, (float)0.13052608, (float)0.12728085, (float)0.12403426,\n(float)0.12078657, (float)0.11753736, (float)0.11428688, (float)0.11103519, (float)0.10778230,\n(float)0.10452849, (float)0.10127334, (float)0.09801710, (float)0.09475980, (float)0.09150149,\n(float)0.08824220, (float)0.08498220, (float)0.08172106, (float)0.07845904, (float)0.07519618,\n(float)0.07193252, (float)0.06866808, (float)0.06540315, (float)0.06213728, (float)0.05887074,\n(float)0.05560357, (float)0.05233581, (float)0.04906749, (float)0.04579888, (float)0.04252954,\n(float)0.03925974, (float)0.03598953, (float)0.03271893, (float)0.02944798, (float)0.02617695,\n(float)0.02290541, (float)0.01963361, (float)0.01636161, (float)0.01308943, (float)0.00981712,\n(float)0.00654493, (float)0.00327244, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,\n(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000};\n\n#endif  // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_WINDOWS_PRIVATE_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/utility/fft4g.c",
    "content": "/*\n * http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html\n * Copyright Takuya OOURA, 1996-2001\n *\n * You may use, copy, modify and distribute this code for any purpose (include\n * commercial use) and without fee. Please refer to this package when you modify\n * this code.\n *\n * Changes:\n * Trivial type modifications by the WebRTC authors.\n */\n\n/*\nFast Fourier/Cosine/Sine Transform\n    dimension   :one\n    data length :power of 2\n    decimation  :frequency\n    radix       :4, 2\n    data        :inplace\n    table       :use\nfunctions\n    cdft: Complex Discrete Fourier Transform\n    rdft: Real Discrete Fourier Transform\n    ddct: Discrete Cosine Transform\n    ddst: Discrete Sine Transform\n    dfct: Cosine Transform of RDFT (Real Symmetric DFT)\n    dfst: Sine Transform of RDFT (Real Anti-symmetric DFT)\nfunction prototypes\n    void cdft(int, int, float *, int *, float *);\n    void rdft(int, int, float *, int *, float *);\n    void ddct(int, int, float *, int *, float *);\n    void ddst(int, int, float *, int *, float *);\n    void dfct(int, float *, float *, int *, float *);\n    void dfst(int, float *, float *, int *, float *);\n\n\n-------- Complex DFT (Discrete Fourier Transform) --------\n    [definition]\n        <case1>\n            X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k<n\n        <case2>\n            X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k<n\n        (notes: sum_j=0^n-1 is a summation from j=0 to n-1)\n    [usage]\n        <case1>\n            ip[0] = 0; // first time only\n            cdft(2*n, 1, a, ip, w);\n        <case2>\n            ip[0] = 0; // first time only\n            cdft(2*n, -1, a, ip, w);\n    [parameters]\n        2*n            :data length (int)\n                        n >= 1, n = power of 2\n        a[0...2*n-1]   :input/output data (float *)\n                        input data\n                            a[2*j] = Re(x[j]),\n                            a[2*j+1] = Im(x[j]), 0<=j<n\n                        output data\n                            a[2*k] = Re(X[k]),\n                            a[2*k+1] = Im(X[k]), 0<=k<n\n        ip[0...*]      :work area for bit reversal (int *)\n                        length of ip >= 2+sqrt(n)\n                        strictly,\n                        length of ip >=\n                            2+(1<<(int)(log(n+0.5)/log(2))/2).\n                        ip[0],ip[1] are pointers of the cos/sin table.\n        w[0...n/2-1]   :cos/sin table (float *)\n                        w[],ip[] are initialized if ip[0] == 0.\n    [remark]\n        Inverse of\n            cdft(2*n, -1, a, ip, w);\n        is\n            cdft(2*n, 1, a, ip, w);\n            for (j = 0; j <= 2 * n - 1; j++) {\n                a[j] *= 1.0 / n;\n            }\n        .\n\n\n-------- Real DFT / Inverse of Real DFT --------\n    [definition]\n        <case1> RDFT\n            R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2\n            I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2\n        <case2> IRDFT (excluding scale)\n            a[k] = (R[0] + R[n/2]*cos(pi*k))/2 +\n                   sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) +\n                   sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n\n    [usage]\n        <case1>\n            ip[0] = 0; // first time only\n            rdft(n, 1, a, ip, w);\n        <case2>\n            ip[0] = 0; // first time only\n            rdft(n, -1, a, ip, w);\n    [parameters]\n        n              :data length (int)\n                        n >= 2, n = power of 2\n        a[0...n-1]     :input/output data (float *)\n                        <case1>\n                            output data\n                                a[2*k] = R[k], 0<=k<n/2\n                                a[2*k+1] = I[k], 0<k<n/2\n                                a[1] = R[n/2]\n                        <case2>\n                            input data\n                                a[2*j] = R[j], 0<=j<n/2\n                                a[2*j+1] = I[j], 0<j<n/2\n                                a[1] = R[n/2]\n        ip[0...*]      :work area for bit reversal (int *)\n                        length of ip >= 2+sqrt(n/2)\n                        strictly,\n                        length of ip >=\n                            2+(1<<(int)(log(n/2+0.5)/log(2))/2).\n                        ip[0],ip[1] are pointers of the cos/sin table.\n        w[0...n/2-1]   :cos/sin table (float *)\n                        w[],ip[] are initialized if ip[0] == 0.\n    [remark]\n        Inverse of\n            rdft(n, 1, a, ip, w);\n        is\n            rdft(n, -1, a, ip, w);\n            for (j = 0; j <= n - 1; j++) {\n                a[j] *= 2.0 / n;\n            }\n        .\n\n\n-------- DCT (Discrete Cosine Transform) / Inverse of DCT --------\n    [definition]\n        <case1> IDCT (excluding scale)\n            C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k<n\n        <case2> DCT\n            C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k<n\n    [usage]\n        <case1>\n            ip[0] = 0; // first time only\n            ddct(n, 1, a, ip, w);\n        <case2>\n            ip[0] = 0; // first time only\n            ddct(n, -1, a, ip, w);\n    [parameters]\n        n              :data length (int)\n                        n >= 2, n = power of 2\n        a[0...n-1]     :input/output data (float *)\n                        output data\n                            a[k] = C[k], 0<=k<n\n        ip[0...*]      :work area for bit reversal (int *)\n                        length of ip >= 2+sqrt(n/2)\n                        strictly,\n                        length of ip >=\n                            2+(1<<(int)(log(n/2+0.5)/log(2))/2).\n                        ip[0],ip[1] are pointers of the cos/sin table.\n        w[0...n*5/4-1] :cos/sin table (float *)\n                        w[],ip[] are initialized if ip[0] == 0.\n    [remark]\n        Inverse of\n            ddct(n, -1, a, ip, w);\n        is\n            a[0] *= 0.5;\n            ddct(n, 1, a, ip, w);\n            for (j = 0; j <= n - 1; j++) {\n                a[j] *= 2.0 / n;\n            }\n        .\n\n\n-------- DST (Discrete Sine Transform) / Inverse of DST --------\n    [definition]\n        <case1> IDST (excluding scale)\n            S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k<n\n        <case2> DST\n            S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0<k<=n\n    [usage]\n        <case1>\n            ip[0] = 0; // first time only\n            ddst(n, 1, a, ip, w);\n        <case2>\n            ip[0] = 0; // first time only\n            ddst(n, -1, a, ip, w);\n    [parameters]\n        n              :data length (int)\n                        n >= 2, n = power of 2\n        a[0...n-1]     :input/output data (float *)\n                        <case1>\n                            input data\n                                a[j] = A[j], 0<j<n\n                                a[0] = A[n]\n                            output data\n                                a[k] = S[k], 0<=k<n\n                        <case2>\n                            output data\n                                a[k] = S[k], 0<k<n\n                                a[0] = S[n]\n        ip[0...*]      :work area for bit reversal (int *)\n                        length of ip >= 2+sqrt(n/2)\n                        strictly,\n                        length of ip >=\n                            2+(1<<(int)(log(n/2+0.5)/log(2))/2).\n                        ip[0],ip[1] are pointers of the cos/sin table.\n        w[0...n*5/4-1] :cos/sin table (float *)\n                        w[],ip[] are initialized if ip[0] == 0.\n    [remark]\n        Inverse of\n            ddst(n, -1, a, ip, w);\n        is\n            a[0] *= 0.5;\n            ddst(n, 1, a, ip, w);\n            for (j = 0; j <= n - 1; j++) {\n                a[j] *= 2.0 / n;\n            }\n        .\n\n\n-------- Cosine Transform of RDFT (Real Symmetric DFT) --------\n    [definition]\n        C[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n\n    [usage]\n        ip[0] = 0; // first time only\n        dfct(n, a, t, ip, w);\n    [parameters]\n        n              :data length - 1 (int)\n                        n >= 2, n = power of 2\n        a[0...n]       :input/output data (float *)\n                        output data\n                            a[k] = C[k], 0<=k<=n\n        t[0...n/2]     :work area (float *)\n        ip[0...*]      :work area for bit reversal (int *)\n                        length of ip >= 2+sqrt(n/4)\n                        strictly,\n                        length of ip >=\n                            2+(1<<(int)(log(n/4+0.5)/log(2))/2).\n                        ip[0],ip[1] are pointers of the cos/sin table.\n        w[0...n*5/8-1] :cos/sin table (float *)\n                        w[],ip[] are initialized if ip[0] == 0.\n    [remark]\n        Inverse of\n            a[0] *= 0.5;\n            a[n] *= 0.5;\n            dfct(n, a, t, ip, w);\n        is\n            a[0] *= 0.5;\n            a[n] *= 0.5;\n            dfct(n, a, t, ip, w);\n            for (j = 0; j <= n; j++) {\n                a[j] *= 2.0 / n;\n            }\n        .\n\n\n-------- Sine Transform of RDFT (Real Anti-symmetric DFT) --------\n    [definition]\n        S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0<k<n\n    [usage]\n        ip[0] = 0; // first time only\n        dfst(n, a, t, ip, w);\n    [parameters]\n        n              :data length + 1 (int)\n                        n >= 2, n = power of 2\n        a[0...n-1]     :input/output data (float *)\n                        output data\n                            a[k] = S[k], 0<k<n\n                        (a[0] is used for work area)\n        t[0...n/2-1]   :work area (float *)\n        ip[0...*]      :work area for bit reversal (int *)\n                        length of ip >= 2+sqrt(n/4)\n                        strictly,\n                        length of ip >=\n                            2+(1<<(int)(log(n/4+0.5)/log(2))/2).\n                        ip[0],ip[1] are pointers of the cos/sin table.\n        w[0...n*5/8-1] :cos/sin table (float *)\n                        w[],ip[] are initialized if ip[0] == 0.\n    [remark]\n        Inverse of\n            dfst(n, a, t, ip, w);\n        is\n            dfst(n, a, t, ip, w);\n            for (j = 1; j <= n - 1; j++) {\n                a[j] *= 2.0 / n;\n            }\n        .\n\n\nAppendix :\n    The cos/sin table is recalculated when the larger table required.\n    w[] and ip[] are compatible with all routines.\n*/\n\nvoid cdft(int n, int isgn, float *a, int *ip, float *w)\n{\n    void makewt(int nw, int *ip, float *w);\n    void bitrv2(int n, int *ip, float *a);\n    void bitrv2conj(int n, int *ip, float *a);\n    void cftfsub(int n, float *a, float *w);\n    void cftbsub(int n, float *a, float *w);\n\n    if (n > (ip[0] << 2)) {\n        makewt(n >> 2, ip, w);\n    }\n    if (n > 4) {\n        if (isgn >= 0) {\n            bitrv2(n, ip + 2, a);\n            cftfsub(n, a, w);\n        } else {\n            bitrv2conj(n, ip + 2, a);\n            cftbsub(n, a, w);\n        }\n    } else if (n == 4) {\n        cftfsub(n, a, w);\n    }\n}\n\n\nvoid rdft(int n, int isgn, float *a, int *ip, float *w)\n{\n    void makewt(int nw, int *ip, float *w);\n    void makect(int nc, int *ip, float *c);\n    void bitrv2(int n, int *ip, float *a);\n    void cftfsub(int n, float *a, float *w);\n    void cftbsub(int n, float *a, float *w);\n    void rftfsub(int n, float *a, int nc, float *c);\n    void rftbsub(int n, float *a, int nc, float *c);\n    int nw, nc;\n    float xi;\n\n    nw = ip[0];\n    if (n > (nw << 2)) {\n        nw = n >> 2;\n        makewt(nw, ip, w);\n    }\n    nc = ip[1];\n    if (n > (nc << 2)) {\n        nc = n >> 2;\n        makect(nc, ip, w + nw);\n    }\n    if (isgn >= 0) {\n        if (n > 4) {\n            bitrv2(n, ip + 2, a);\n            cftfsub(n, a, w);\n            rftfsub(n, a, nc, w + nw);\n        } else if (n == 4) {\n            cftfsub(n, a, w);\n        }\n        xi = a[0] - a[1];\n        a[0] += a[1];\n        a[1] = xi;\n    } else {\n        a[1] = 0.5f * (a[0] - a[1]);\n        a[0] -= a[1];\n        if (n > 4) {\n            rftbsub(n, a, nc, w + nw);\n            bitrv2(n, ip + 2, a);\n            cftbsub(n, a, w);\n        } else if (n == 4) {\n            cftfsub(n, a, w);\n        }\n    }\n}\n\n\nvoid ddct(int n, int isgn, float *a, int *ip, float *w)\n{\n    void makewt(int nw, int *ip, float *w);\n    void makect(int nc, int *ip, float *c);\n    void bitrv2(int n, int *ip, float *a);\n    void cftfsub(int n, float *a, float *w);\n    void cftbsub(int n, float *a, float *w);\n    void rftfsub(int n, float *a, int nc, float *c);\n    void rftbsub(int n, float *a, int nc, float *c);\n    void dctsub(int n, float *a, int nc, float *c);\n    int j, nw, nc;\n    float xr;\n\n    nw = ip[0];\n    if (n > (nw << 2)) {\n        nw = n >> 2;\n        makewt(nw, ip, w);\n    }\n    nc = ip[1];\n    if (n > nc) {\n        nc = n;\n        makect(nc, ip, w + nw);\n    }\n    if (isgn < 0) {\n        xr = a[n - 1];\n        for (j = n - 2; j >= 2; j -= 2) {\n            a[j + 1] = a[j] - a[j - 1];\n            a[j] += a[j - 1];\n        }\n        a[1] = a[0] - xr;\n        a[0] += xr;\n        if (n > 4) {\n            rftbsub(n, a, nc, w + nw);\n            bitrv2(n, ip + 2, a);\n            cftbsub(n, a, w);\n        } else if (n == 4) {\n            cftfsub(n, a, w);\n        }\n    }\n    dctsub(n, a, nc, w + nw);\n    if (isgn >= 0) {\n        if (n > 4) {\n            bitrv2(n, ip + 2, a);\n            cftfsub(n, a, w);\n            rftfsub(n, a, nc, w + nw);\n        } else if (n == 4) {\n            cftfsub(n, a, w);\n        }\n        xr = a[0] - a[1];\n        a[0] += a[1];\n        for (j = 2; j < n; j += 2) {\n            a[j - 1] = a[j] - a[j + 1];\n            a[j] += a[j + 1];\n        }\n        a[n - 1] = xr;\n    }\n}\n\n\nvoid ddst(int n, int isgn, float *a, int *ip, float *w)\n{\n    void makewt(int nw, int *ip, float *w);\n    void makect(int nc, int *ip, float *c);\n    void bitrv2(int n, int *ip, float *a);\n    void cftfsub(int n, float *a, float *w);\n    void cftbsub(int n, float *a, float *w);\n    void rftfsub(int n, float *a, int nc, float *c);\n    void rftbsub(int n, float *a, int nc, float *c);\n    void dstsub(int n, float *a, int nc, float *c);\n    int j, nw, nc;\n    float xr;\n\n    nw = ip[0];\n    if (n > (nw << 2)) {\n        nw = n >> 2;\n        makewt(nw, ip, w);\n    }\n    nc = ip[1];\n    if (n > nc) {\n        nc = n;\n        makect(nc, ip, w + nw);\n    }\n    if (isgn < 0) {\n        xr = a[n - 1];\n        for (j = n - 2; j >= 2; j -= 2) {\n            a[j + 1] = -a[j] - a[j - 1];\n            a[j] -= a[j - 1];\n        }\n        a[1] = a[0] + xr;\n        a[0] -= xr;\n        if (n > 4) {\n            rftbsub(n, a, nc, w + nw);\n            bitrv2(n, ip + 2, a);\n            cftbsub(n, a, w);\n        } else if (n == 4) {\n            cftfsub(n, a, w);\n        }\n    }\n    dstsub(n, a, nc, w + nw);\n    if (isgn >= 0) {\n        if (n > 4) {\n            bitrv2(n, ip + 2, a);\n            cftfsub(n, a, w);\n            rftfsub(n, a, nc, w + nw);\n        } else if (n == 4) {\n            cftfsub(n, a, w);\n        }\n        xr = a[0] - a[1];\n        a[0] += a[1];\n        for (j = 2; j < n; j += 2) {\n            a[j - 1] = -a[j] - a[j + 1];\n            a[j] -= a[j + 1];\n        }\n        a[n - 1] = -xr;\n    }\n}\n\n\nvoid dfct(int n, float *a, float *t, int *ip, float *w)\n{\n    void makewt(int nw, int *ip, float *w);\n    void makect(int nc, int *ip, float *c);\n    void bitrv2(int n, int *ip, float *a);\n    void cftfsub(int n, float *a, float *w);\n    void rftfsub(int n, float *a, int nc, float *c);\n    void dctsub(int n, float *a, int nc, float *c);\n    int j, k, l, m, mh, nw, nc;\n    float xr, xi, yr, yi;\n\n    nw = ip[0];\n    if (n > (nw << 3)) {\n        nw = n >> 3;\n        makewt(nw, ip, w);\n    }\n    nc = ip[1];\n    if (n > (nc << 1)) {\n        nc = n >> 1;\n        makect(nc, ip, w + nw);\n    }\n    m = n >> 1;\n    yi = a[m];\n    xi = a[0] + a[n];\n    a[0] -= a[n];\n    t[0] = xi - yi;\n    t[m] = xi + yi;\n    if (n > 2) {\n        mh = m >> 1;\n        for (j = 1; j < mh; j++) {\n            k = m - j;\n            xr = a[j] - a[n - j];\n            xi = a[j] + a[n - j];\n            yr = a[k] - a[n - k];\n            yi = a[k] + a[n - k];\n            a[j] = xr;\n            a[k] = yr;\n            t[j] = xi - yi;\n            t[k] = xi + yi;\n        }\n        t[mh] = a[mh] + a[n - mh];\n        a[mh] -= a[n - mh];\n        dctsub(m, a, nc, w + nw);\n        if (m > 4) {\n            bitrv2(m, ip + 2, a);\n            cftfsub(m, a, w);\n            rftfsub(m, a, nc, w + nw);\n        } else if (m == 4) {\n            cftfsub(m, a, w);\n        }\n        a[n - 1] = a[0] - a[1];\n        a[1] = a[0] + a[1];\n        for (j = m - 2; j >= 2; j -= 2) {\n            a[2 * j + 1] = a[j] + a[j + 1];\n            a[2 * j - 1] = a[j] - a[j + 1];\n        }\n        l = 2;\n        m = mh;\n        while (m >= 2) {\n            dctsub(m, t, nc, w + nw);\n            if (m > 4) {\n                bitrv2(m, ip + 2, t);\n                cftfsub(m, t, w);\n                rftfsub(m, t, nc, w + nw);\n            } else if (m == 4) {\n                cftfsub(m, t, w);\n            }\n            a[n - l] = t[0] - t[1];\n            a[l] = t[0] + t[1];\n            k = 0;\n            for (j = 2; j < m; j += 2) {\n                k += l << 2;\n                a[k - l] = t[j] - t[j + 1];\n                a[k + l] = t[j] + t[j + 1];\n            }\n            l <<= 1;\n            mh = m >> 1;\n            for (j = 0; j < mh; j++) {\n                k = m - j;\n                t[j] = t[m + k] - t[m + j];\n                t[k] = t[m + k] + t[m + j];\n            }\n            t[mh] = t[m + mh];\n            m = mh;\n        }\n        a[l] = t[0];\n        a[n] = t[2] - t[1];\n        a[0] = t[2] + t[1];\n    } else {\n        a[1] = a[0];\n        a[2] = t[0];\n        a[0] = t[1];\n    }\n}\n\n\nvoid dfst(int n, float *a, float *t, int *ip, float *w)\n{\n    void makewt(int nw, int *ip, float *w);\n    void makect(int nc, int *ip, float *c);\n    void bitrv2(int n, int *ip, float *a);\n    void cftfsub(int n, float *a, float *w);\n    void rftfsub(int n, float *a, int nc, float *c);\n    void dstsub(int n, float *a, int nc, float *c);\n    int j, k, l, m, mh, nw, nc;\n    float xr, xi, yr, yi;\n\n    nw = ip[0];\n    if (n > (nw << 3)) {\n        nw = n >> 3;\n        makewt(nw, ip, w);\n    }\n    nc = ip[1];\n    if (n > (nc << 1)) {\n        nc = n >> 1;\n        makect(nc, ip, w + nw);\n    }\n    if (n > 2) {\n        m = n >> 1;\n        mh = m >> 1;\n        for (j = 1; j < mh; j++) {\n            k = m - j;\n            xr = a[j] + a[n - j];\n            xi = a[j] - a[n - j];\n            yr = a[k] + a[n - k];\n            yi = a[k] - a[n - k];\n            a[j] = xr;\n            a[k] = yr;\n            t[j] = xi + yi;\n            t[k] = xi - yi;\n        }\n        t[0] = a[mh] - a[n - mh];\n        a[mh] += a[n - mh];\n        a[0] = a[m];\n        dstsub(m, a, nc, w + nw);\n        if (m > 4) {\n            bitrv2(m, ip + 2, a);\n            cftfsub(m, a, w);\n            rftfsub(m, a, nc, w + nw);\n        } else if (m == 4) {\n            cftfsub(m, a, w);\n        }\n        a[n - 1] = a[1] - a[0];\n        a[1] = a[0] + a[1];\n        for (j = m - 2; j >= 2; j -= 2) {\n            a[2 * j + 1] = a[j] - a[j + 1];\n            a[2 * j - 1] = -a[j] - a[j + 1];\n        }\n        l = 2;\n        m = mh;\n        while (m >= 2) {\n            dstsub(m, t, nc, w + nw);\n            if (m > 4) {\n                bitrv2(m, ip + 2, t);\n                cftfsub(m, t, w);\n                rftfsub(m, t, nc, w + nw);\n            } else if (m == 4) {\n                cftfsub(m, t, w);\n            }\n            a[n - l] = t[1] - t[0];\n            a[l] = t[0] + t[1];\n            k = 0;\n            for (j = 2; j < m; j += 2) {\n                k += l << 2;\n                a[k - l] = -t[j] - t[j + 1];\n                a[k + l] = t[j] - t[j + 1];\n            }\n            l <<= 1;\n            mh = m >> 1;\n            for (j = 1; j < mh; j++) {\n                k = m - j;\n                t[j] = t[m + k] + t[m + j];\n                t[k] = t[m + k] - t[m + j];\n            }\n            t[0] = t[m + mh];\n            m = mh;\n        }\n        a[l] = t[0];\n    }\n    a[0] = 0;\n}\n\n\n/* -------- initializing routines -------- */\n\n\n#include <math.h>\n\nvoid makewt(int nw, int *ip, float *w)\n{\n    void bitrv2(int n, int *ip, float *a);\n    int j, nwh;\n    float delta, x, y;\n\n    ip[0] = nw;\n    ip[1] = 1;\n    if (nw > 2) {\n        nwh = nw >> 1;\n        delta = (float)atan(1.0f) / nwh;\n        w[0] = 1;\n        w[1] = 0;\n        w[nwh] = (float)cos(delta * nwh);\n        w[nwh + 1] = w[nwh];\n        if (nwh > 2) {\n            for (j = 2; j < nwh; j += 2) {\n                x = (float)cos(delta * j);\n                y = (float)sin(delta * j);\n                w[j] = x;\n                w[j + 1] = y;\n                w[nw - j] = y;\n                w[nw - j + 1] = x;\n            }\n            bitrv2(nw, ip + 2, w);\n        }\n    }\n}\n\n\nvoid makect(int nc, int *ip, float *c)\n{\n    int j, nch;\n    float delta;\n\n    ip[1] = nc;\n    if (nc > 1) {\n        nch = nc >> 1;\n        delta = (float)atan(1.0f) / nch;\n        c[0] = (float)cos(delta * nch);\n        c[nch] = 0.5f * c[0];\n        for (j = 1; j < nch; j++) {\n            c[j] = 0.5f * (float)cos(delta * j);\n            c[nc - j] = 0.5f * (float)sin(delta * j);\n        }\n    }\n}\n\n\n/* -------- child routines -------- */\n\n\nvoid bitrv2(int n, int *ip, float *a)\n{\n    int j, j1, k, k1, l, m, m2;\n    float xr, xi, yr, yi;\n\n    ip[0] = 0;\n    l = n;\n    m = 1;\n    while ((m << 3) < l) {\n        l >>= 1;\n        for (j = 0; j < m; j++) {\n            ip[m + j] = ip[j] + l;\n        }\n        m <<= 1;\n    }\n    m2 = 2 * m;\n    if ((m << 3) == l) {\n        for (k = 0; k < m; k++) {\n            for (j = 0; j < k; j++) {\n                j1 = 2 * j + ip[k];\n                k1 = 2 * k + ip[j];\n                xr = a[j1];\n                xi = a[j1 + 1];\n                yr = a[k1];\n                yi = a[k1 + 1];\n                a[j1] = yr;\n                a[j1 + 1] = yi;\n                a[k1] = xr;\n                a[k1 + 1] = xi;\n                j1 += m2;\n                k1 += 2 * m2;\n                xr = a[j1];\n                xi = a[j1 + 1];\n                yr = a[k1];\n                yi = a[k1 + 1];\n                a[j1] = yr;\n                a[j1 + 1] = yi;\n                a[k1] = xr;\n                a[k1 + 1] = xi;\n                j1 += m2;\n                k1 -= m2;\n                xr = a[j1];\n                xi = a[j1 + 1];\n                yr = a[k1];\n                yi = a[k1 + 1];\n                a[j1] = yr;\n                a[j1 + 1] = yi;\n                a[k1] = xr;\n                a[k1 + 1] = xi;\n                j1 += m2;\n                k1 += 2 * m2;\n                xr = a[j1];\n                xi = a[j1 + 1];\n                yr = a[k1];\n                yi = a[k1 + 1];\n                a[j1] = yr;\n                a[j1 + 1] = yi;\n                a[k1] = xr;\n                a[k1 + 1] = xi;\n            }\n            j1 = 2 * k + m2 + ip[k];\n            k1 = j1 + m2;\n            xr = a[j1];\n            xi = a[j1 + 1];\n            yr = a[k1];\n            yi = a[k1 + 1];\n            a[j1] = yr;\n            a[j1 + 1] = yi;\n            a[k1] = xr;\n            a[k1 + 1] = xi;\n        }\n    } else {\n        for (k = 1; k < m; k++) {\n            for (j = 0; j < k; j++) {\n                j1 = 2 * j + ip[k];\n                k1 = 2 * k + ip[j];\n                xr = a[j1];\n                xi = a[j1 + 1];\n                yr = a[k1];\n                yi = a[k1 + 1];\n                a[j1] = yr;\n                a[j1 + 1] = yi;\n                a[k1] = xr;\n                a[k1 + 1] = xi;\n                j1 += m2;\n                k1 += m2;\n                xr = a[j1];\n                xi = a[j1 + 1];\n                yr = a[k1];\n                yi = a[k1 + 1];\n                a[j1] = yr;\n                a[j1 + 1] = yi;\n                a[k1] = xr;\n                a[k1 + 1] = xi;\n            }\n        }\n    }\n}\n\n\nvoid bitrv2conj(int n, int *ip, float *a)\n{\n    int j, j1, k, k1, l, m, m2;\n    float xr, xi, yr, yi;\n\n    ip[0] = 0;\n    l = n;\n    m = 1;\n    while ((m << 3) < l) {\n        l >>= 1;\n        for (j = 0; j < m; j++) {\n            ip[m + j] = ip[j] + l;\n        }\n        m <<= 1;\n    }\n    m2 = 2 * m;\n    if ((m << 3) == l) {\n        for (k = 0; k < m; k++) {\n            for (j = 0; j < k; j++) {\n                j1 = 2 * j + ip[k];\n                k1 = 2 * k + ip[j];\n                xr = a[j1];\n                xi = -a[j1 + 1];\n                yr = a[k1];\n                yi = -a[k1 + 1];\n                a[j1] = yr;\n                a[j1 + 1] = yi;\n                a[k1] = xr;\n                a[k1 + 1] = xi;\n                j1 += m2;\n                k1 += 2 * m2;\n                xr = a[j1];\n                xi = -a[j1 + 1];\n                yr = a[k1];\n                yi = -a[k1 + 1];\n                a[j1] = yr;\n                a[j1 + 1] = yi;\n                a[k1] = xr;\n                a[k1 + 1] = xi;\n                j1 += m2;\n                k1 -= m2;\n                xr = a[j1];\n                xi = -a[j1 + 1];\n                yr = a[k1];\n                yi = -a[k1 + 1];\n                a[j1] = yr;\n                a[j1 + 1] = yi;\n                a[k1] = xr;\n                a[k1 + 1] = xi;\n                j1 += m2;\n                k1 += 2 * m2;\n                xr = a[j1];\n                xi = -a[j1 + 1];\n                yr = a[k1];\n                yi = -a[k1 + 1];\n                a[j1] = yr;\n                a[j1 + 1] = yi;\n                a[k1] = xr;\n                a[k1 + 1] = xi;\n            }\n            k1 = 2 * k + ip[k];\n            a[k1 + 1] = -a[k1 + 1];\n            j1 = k1 + m2;\n            k1 = j1 + m2;\n            xr = a[j1];\n            xi = -a[j1 + 1];\n            yr = a[k1];\n            yi = -a[k1 + 1];\n            a[j1] = yr;\n            a[j1 + 1] = yi;\n            a[k1] = xr;\n            a[k1 + 1] = xi;\n            k1 += m2;\n            a[k1 + 1] = -a[k1 + 1];\n        }\n    } else {\n        a[1] = -a[1];\n        a[m2 + 1] = -a[m2 + 1];\n        for (k = 1; k < m; k++) {\n            for (j = 0; j < k; j++) {\n                j1 = 2 * j + ip[k];\n                k1 = 2 * k + ip[j];\n                xr = a[j1];\n                xi = -a[j1 + 1];\n                yr = a[k1];\n                yi = -a[k1 + 1];\n                a[j1] = yr;\n                a[j1 + 1] = yi;\n                a[k1] = xr;\n                a[k1 + 1] = xi;\n                j1 += m2;\n                k1 += m2;\n                xr = a[j1];\n                xi = -a[j1 + 1];\n                yr = a[k1];\n                yi = -a[k1 + 1];\n                a[j1] = yr;\n                a[j1 + 1] = yi;\n                a[k1] = xr;\n                a[k1 + 1] = xi;\n            }\n            k1 = 2 * k + ip[k];\n            a[k1 + 1] = -a[k1 + 1];\n            a[k1 + m2 + 1] = -a[k1 + m2 + 1];\n        }\n    }\n}\n\n\nvoid cftfsub(int n, float *a, float *w)\n{\n    void cft1st(int n, float *a, float *w);\n    void cftmdl(int n, int l, float *a, float *w);\n    int j, j1, j2, j3, l;\n    float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\n    l = 2;\n    if (n > 8) {\n        cft1st(n, a, w);\n        l = 8;\n        while ((l << 2) < n) {\n            cftmdl(n, l, a, w);\n            l <<= 2;\n        }\n    }\n    if ((l << 2) == n) {\n        for (j = 0; j < l; j += 2) {\n            j1 = j + l;\n            j2 = j1 + l;\n            j3 = j2 + l;\n            x0r = a[j] + a[j1];\n            x0i = a[j + 1] + a[j1 + 1];\n            x1r = a[j] - a[j1];\n            x1i = a[j + 1] - a[j1 + 1];\n            x2r = a[j2] + a[j3];\n            x2i = a[j2 + 1] + a[j3 + 1];\n            x3r = a[j2] - a[j3];\n            x3i = a[j2 + 1] - a[j3 + 1];\n            a[j] = x0r + x2r;\n            a[j + 1] = x0i + x2i;\n            a[j2] = x0r - x2r;\n            a[j2 + 1] = x0i - x2i;\n            a[j1] = x1r - x3i;\n            a[j1 + 1] = x1i + x3r;\n            a[j3] = x1r + x3i;\n            a[j3 + 1] = x1i - x3r;\n        }\n    } else {\n        for (j = 0; j < l; j += 2) {\n            j1 = j + l;\n            x0r = a[j] - a[j1];\n            x0i = a[j + 1] - a[j1 + 1];\n            a[j] += a[j1];\n            a[j + 1] += a[j1 + 1];\n            a[j1] = x0r;\n            a[j1 + 1] = x0i;\n        }\n    }\n}\n\n\nvoid cftbsub(int n, float *a, float *w)\n{\n    void cft1st(int n, float *a, float *w);\n    void cftmdl(int n, int l, float *a, float *w);\n    int j, j1, j2, j3, l;\n    float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\n    l = 2;\n    if (n > 8) {\n        cft1st(n, a, w);\n        l = 8;\n        while ((l << 2) < n) {\n            cftmdl(n, l, a, w);\n            l <<= 2;\n        }\n    }\n    if ((l << 2) == n) {\n        for (j = 0; j < l; j += 2) {\n            j1 = j + l;\n            j2 = j1 + l;\n            j3 = j2 + l;\n            x0r = a[j] + a[j1];\n            x0i = -a[j + 1] - a[j1 + 1];\n            x1r = a[j] - a[j1];\n            x1i = -a[j + 1] + a[j1 + 1];\n            x2r = a[j2] + a[j3];\n            x2i = a[j2 + 1] + a[j3 + 1];\n            x3r = a[j2] - a[j3];\n            x3i = a[j2 + 1] - a[j3 + 1];\n            a[j] = x0r + x2r;\n            a[j + 1] = x0i - x2i;\n            a[j2] = x0r - x2r;\n            a[j2 + 1] = x0i + x2i;\n            a[j1] = x1r - x3i;\n            a[j1 + 1] = x1i - x3r;\n            a[j3] = x1r + x3i;\n            a[j3 + 1] = x1i + x3r;\n        }\n    } else {\n        for (j = 0; j < l; j += 2) {\n            j1 = j + l;\n            x0r = a[j] - a[j1];\n            x0i = -a[j + 1] + a[j1 + 1];\n            a[j] += a[j1];\n            a[j + 1] = -a[j + 1] - a[j1 + 1];\n            a[j1] = x0r;\n            a[j1 + 1] = x0i;\n        }\n    }\n}\n\n\nvoid cft1st(int n, float *a, float *w)\n{\n    int j, k1, k2;\n    float wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;\n    float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\n    x0r = a[0] + a[2];\n    x0i = a[1] + a[3];\n    x1r = a[0] - a[2];\n    x1i = a[1] - a[3];\n    x2r = a[4] + a[6];\n    x2i = a[5] + a[7];\n    x3r = a[4] - a[6];\n    x3i = a[5] - a[7];\n    a[0] = x0r + x2r;\n    a[1] = x0i + x2i;\n    a[4] = x0r - x2r;\n    a[5] = x0i - x2i;\n    a[2] = x1r - x3i;\n    a[3] = x1i + x3r;\n    a[6] = x1r + x3i;\n    a[7] = x1i - x3r;\n    wk1r = w[2];\n    x0r = a[8] + a[10];\n    x0i = a[9] + a[11];\n    x1r = a[8] - a[10];\n    x1i = a[9] - a[11];\n    x2r = a[12] + a[14];\n    x2i = a[13] + a[15];\n    x3r = a[12] - a[14];\n    x3i = a[13] - a[15];\n    a[8] = x0r + x2r;\n    a[9] = x0i + x2i;\n    a[12] = x2i - x0i;\n    a[13] = x0r - x2r;\n    x0r = x1r - x3i;\n    x0i = x1i + x3r;\n    a[10] = wk1r * (x0r - x0i);\n    a[11] = wk1r * (x0r + x0i);\n    x0r = x3i + x1r;\n    x0i = x3r - x1i;\n    a[14] = wk1r * (x0i - x0r);\n    a[15] = wk1r * (x0i + x0r);\n    k1 = 0;\n    for (j = 16; j < n; j += 16) {\n        k1 += 2;\n        k2 = 2 * k1;\n        wk2r = w[k1];\n        wk2i = w[k1 + 1];\n        wk1r = w[k2];\n        wk1i = w[k2 + 1];\n        wk3r = wk1r - 2 * wk2i * wk1i;\n        wk3i = 2 * wk2i * wk1r - wk1i;\n        x0r = a[j] + a[j + 2];\n        x0i = a[j + 1] + a[j + 3];\n        x1r = a[j] - a[j + 2];\n        x1i = a[j + 1] - a[j + 3];\n        x2r = a[j + 4] + a[j + 6];\n        x2i = a[j + 5] + a[j + 7];\n        x3r = a[j + 4] - a[j + 6];\n        x3i = a[j + 5] - a[j + 7];\n        a[j] = x0r + x2r;\n        a[j + 1] = x0i + x2i;\n        x0r -= x2r;\n        x0i -= x2i;\n        a[j + 4] = wk2r * x0r - wk2i * x0i;\n        a[j + 5] = wk2r * x0i + wk2i * x0r;\n        x0r = x1r - x3i;\n        x0i = x1i + x3r;\n        a[j + 2] = wk1r * x0r - wk1i * x0i;\n        a[j + 3] = wk1r * x0i + wk1i * x0r;\n        x0r = x1r + x3i;\n        x0i = x1i - x3r;\n        a[j + 6] = wk3r * x0r - wk3i * x0i;\n        a[j + 7] = wk3r * x0i + wk3i * x0r;\n        wk1r = w[k2 + 2];\n        wk1i = w[k2 + 3];\n        wk3r = wk1r - 2 * wk2r * wk1i;\n        wk3i = 2 * wk2r * wk1r - wk1i;\n        x0r = a[j + 8] + a[j + 10];\n        x0i = a[j + 9] + a[j + 11];\n        x1r = a[j + 8] - a[j + 10];\n        x1i = a[j + 9] - a[j + 11];\n        x2r = a[j + 12] + a[j + 14];\n        x2i = a[j + 13] + a[j + 15];\n        x3r = a[j + 12] - a[j + 14];\n        x3i = a[j + 13] - a[j + 15];\n        a[j + 8] = x0r + x2r;\n        a[j + 9] = x0i + x2i;\n        x0r -= x2r;\n        x0i -= x2i;\n        a[j + 12] = -wk2i * x0r - wk2r * x0i;\n        a[j + 13] = -wk2i * x0i + wk2r * x0r;\n        x0r = x1r - x3i;\n        x0i = x1i + x3r;\n        a[j + 10] = wk1r * x0r - wk1i * x0i;\n        a[j + 11] = wk1r * x0i + wk1i * x0r;\n        x0r = x1r + x3i;\n        x0i = x1i - x3r;\n        a[j + 14] = wk3r * x0r - wk3i * x0i;\n        a[j + 15] = wk3r * x0i + wk3i * x0r;\n    }\n}\n\n\nvoid cftmdl(int n, int l, float *a, float *w)\n{\n    int j, j1, j2, j3, k, k1, k2, m, m2;\n    float wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;\n    float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\n    m = l << 2;\n    for (j = 0; j < l; j += 2) {\n        j1 = j + l;\n        j2 = j1 + l;\n        j3 = j2 + l;\n        x0r = a[j] + a[j1];\n        x0i = a[j + 1] + a[j1 + 1];\n        x1r = a[j] - a[j1];\n        x1i = a[j + 1] - a[j1 + 1];\n        x2r = a[j2] + a[j3];\n        x2i = a[j2 + 1] + a[j3 + 1];\n        x3r = a[j2] - a[j3];\n        x3i = a[j2 + 1] - a[j3 + 1];\n        a[j] = x0r + x2r;\n        a[j + 1] = x0i + x2i;\n        a[j2] = x0r - x2r;\n        a[j2 + 1] = x0i - x2i;\n        a[j1] = x1r - x3i;\n        a[j1 + 1] = x1i + x3r;\n        a[j3] = x1r + x3i;\n        a[j3 + 1] = x1i - x3r;\n    }\n    wk1r = w[2];\n    for (j = m; j < l + m; j += 2) {\n        j1 = j + l;\n        j2 = j1 + l;\n        j3 = j2 + l;\n        x0r = a[j] + a[j1];\n        x0i = a[j + 1] + a[j1 + 1];\n        x1r = a[j] - a[j1];\n        x1i = a[j + 1] - a[j1 + 1];\n        x2r = a[j2] + a[j3];\n        x2i = a[j2 + 1] + a[j3 + 1];\n        x3r = a[j2] - a[j3];\n        x3i = a[j2 + 1] - a[j3 + 1];\n        a[j] = x0r + x2r;\n        a[j + 1] = x0i + x2i;\n        a[j2] = x2i - x0i;\n        a[j2 + 1] = x0r - x2r;\n        x0r = x1r - x3i;\n        x0i = x1i + x3r;\n        a[j1] = wk1r * (x0r - x0i);\n        a[j1 + 1] = wk1r * (x0r + x0i);\n        x0r = x3i + x1r;\n        x0i = x3r - x1i;\n        a[j3] = wk1r * (x0i - x0r);\n        a[j3 + 1] = wk1r * (x0i + x0r);\n    }\n    k1 = 0;\n    m2 = 2 * m;\n    for (k = m2; k < n; k += m2) {\n        k1 += 2;\n        k2 = 2 * k1;\n        wk2r = w[k1];\n        wk2i = w[k1 + 1];\n        wk1r = w[k2];\n        wk1i = w[k2 + 1];\n        wk3r = wk1r - 2 * wk2i * wk1i;\n        wk3i = 2 * wk2i * wk1r - wk1i;\n        for (j = k; j < l + k; j += 2) {\n            j1 = j + l;\n            j2 = j1 + l;\n            j3 = j2 + l;\n            x0r = a[j] + a[j1];\n            x0i = a[j + 1] + a[j1 + 1];\n            x1r = a[j] - a[j1];\n            x1i = a[j + 1] - a[j1 + 1];\n            x2r = a[j2] + a[j3];\n            x2i = a[j2 + 1] + a[j3 + 1];\n            x3r = a[j2] - a[j3];\n            x3i = a[j2 + 1] - a[j3 + 1];\n            a[j] = x0r + x2r;\n            a[j + 1] = x0i + x2i;\n            x0r -= x2r;\n            x0i -= x2i;\n            a[j2] = wk2r * x0r - wk2i * x0i;\n            a[j2 + 1] = wk2r * x0i + wk2i * x0r;\n            x0r = x1r - x3i;\n            x0i = x1i + x3r;\n            a[j1] = wk1r * x0r - wk1i * x0i;\n            a[j1 + 1] = wk1r * x0i + wk1i * x0r;\n            x0r = x1r + x3i;\n            x0i = x1i - x3r;\n            a[j3] = wk3r * x0r - wk3i * x0i;\n            a[j3 + 1] = wk3r * x0i + wk3i * x0r;\n        }\n        wk1r = w[k2 + 2];\n        wk1i = w[k2 + 3];\n        wk3r = wk1r - 2 * wk2r * wk1i;\n        wk3i = 2 * wk2r * wk1r - wk1i;\n        for (j = k + m; j < l + (k + m); j += 2) {\n            j1 = j + l;\n            j2 = j1 + l;\n            j3 = j2 + l;\n            x0r = a[j] + a[j1];\n            x0i = a[j + 1] + a[j1 + 1];\n            x1r = a[j] - a[j1];\n            x1i = a[j + 1] - a[j1 + 1];\n            x2r = a[j2] + a[j3];\n            x2i = a[j2 + 1] + a[j3 + 1];\n            x3r = a[j2] - a[j3];\n            x3i = a[j2 + 1] - a[j3 + 1];\n            a[j] = x0r + x2r;\n            a[j + 1] = x0i + x2i;\n            x0r -= x2r;\n            x0i -= x2i;\n            a[j2] = -wk2i * x0r - wk2r * x0i;\n            a[j2 + 1] = -wk2i * x0i + wk2r * x0r;\n            x0r = x1r - x3i;\n            x0i = x1i + x3r;\n            a[j1] = wk1r * x0r - wk1i * x0i;\n            a[j1 + 1] = wk1r * x0i + wk1i * x0r;\n            x0r = x1r + x3i;\n            x0i = x1i - x3r;\n            a[j3] = wk3r * x0r - wk3i * x0i;\n            a[j3 + 1] = wk3r * x0i + wk3i * x0r;\n        }\n    }\n}\n\n\nvoid rftfsub(int n, float *a, int nc, float *c)\n{\n    int j, k, kk, ks, m;\n    float wkr, wki, xr, xi, yr, yi;\n\n    m = n >> 1;\n    ks = 2 * nc / m;\n    kk = 0;\n    for (j = 2; j < m; j += 2) {\n        k = n - j;\n        kk += ks;\n        wkr = 0.5f - c[nc - kk];\n        wki = c[kk];\n        xr = a[j] - a[k];\n        xi = a[j + 1] + a[k + 1];\n        yr = wkr * xr - wki * xi;\n        yi = wkr * xi + wki * xr;\n        a[j] -= yr;\n        a[j + 1] -= yi;\n        a[k] += yr;\n        a[k + 1] -= yi;\n    }\n}\n\n\nvoid rftbsub(int n, float *a, int nc, float *c)\n{\n    int j, k, kk, ks, m;\n    float wkr, wki, xr, xi, yr, yi;\n\n    a[1] = -a[1];\n    m = n >> 1;\n    ks = 2 * nc / m;\n    kk = 0;\n    for (j = 2; j < m; j += 2) {\n        k = n - j;\n        kk += ks;\n        wkr = 0.5f - c[nc - kk];\n        wki = c[kk];\n        xr = a[j] - a[k];\n        xi = a[j + 1] + a[k + 1];\n        yr = wkr * xr + wki * xi;\n        yi = wkr * xi - wki * xr;\n        a[j] -= yr;\n        a[j + 1] = yi - a[j + 1];\n        a[k] += yr;\n        a[k + 1] = yi - a[k + 1];\n    }\n    a[m + 1] = -a[m + 1];\n}\n\n\nvoid dctsub(int n, float *a, int nc, float *c)\n{\n    int j, k, kk, ks, m;\n    float wkr, wki, xr;\n\n    m = n >> 1;\n    ks = nc / n;\n    kk = 0;\n    for (j = 1; j < m; j++) {\n        k = n - j;\n        kk += ks;\n        wkr = c[kk] - c[nc - kk];\n        wki = c[kk] + c[nc - kk];\n        xr = wki * a[j] - wkr * a[k];\n        a[j] = wkr * a[j] + wki * a[k];\n        a[k] = xr;\n    }\n    a[m] *= c[0];\n}\n\n\nvoid dstsub(int n, float *a, int nc, float *c)\n{\n    int j, k, kk, ks, m;\n    float wkr, wki, xr;\n\n    m = n >> 1;\n    ks = nc / n;\n    kk = 0;\n    for (j = 1; j < m; j++) {\n        k = n - j;\n        kk += ks;\n        wkr = c[kk] - c[nc - kk];\n        wki = c[kk] + c[nc - kk];\n        xr = wki * a[k] - wkr * a[j];\n        a[k] = wkr * a[k] + wki * a[j];\n        a[j] = xr;\n    }\n    a[m] *= c[0];\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/utility/fft4g.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_FFT4G_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_FFT4G_H_\n\nvoid rdft(int, int, float *, int *, float *);\nvoid cdft(int, int, float *, int *, float *);\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/utility/ring_buffer.c",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/*\n * Provides a generic ring buffer that can be written to and read from with\n * arbitrarily sized blocks. The AEC uses this for several different tasks.\n */\n\n#include <stdlib.h>\n#include <string.h>\n#include \"ring_buffer.h\"\n\ntypedef struct {\n    int readPos;\n    int writePos;\n    int size;\n    char rwWrap;\n    bufdata_t *data;\n} buf_t;\n\nenum {SAME_WRAP, DIFF_WRAP};\n\nint WebRtcApm_CreateBuffer(void **bufInst, int size)\n{\n    buf_t *buf = NULL;\n\n    if (size < 0) {\n        return -1;\n    }\n\n    buf = malloc(sizeof(buf_t));\n    *bufInst = buf;\n    if (buf == NULL) {\n        return -1;\n    }\n\n    buf->data = malloc(size*sizeof(bufdata_t));\n    if (buf->data == NULL) {\n        free(buf);\n        buf = NULL;\n        return -1;\n    }\n\n    buf->size = size;\n    return 0;\n}\n\nint WebRtcApm_InitBuffer(void *bufInst)\n{\n    buf_t *buf = (buf_t*)bufInst;\n\n    buf->readPos = 0;\n    buf->writePos = 0;\n    buf->rwWrap = SAME_WRAP;\n\n    // Initialize buffer to zeros\n    memset(buf->data, 0, sizeof(bufdata_t)*buf->size);\n\n    return 0;\n}\n\nint WebRtcApm_FreeBuffer(void *bufInst)\n{\n    buf_t *buf = (buf_t*)bufInst;\n\n    if (buf == NULL) {\n        return -1;\n    }\n\n    free(buf->data);\n    free(buf);\n\n    return 0;\n}\n\nint WebRtcApm_ReadBuffer(void *bufInst, bufdata_t *data, int size)\n{\n    buf_t *buf = (buf_t*)bufInst;\n    int n = 0, margin = 0;\n\n    if (size <= 0 || size > buf->size) {\n        return -1;\n    }\n\n    n = size;\n    if (buf->rwWrap == DIFF_WRAP) {\n        margin = buf->size - buf->readPos;\n        if (n > margin) {\n            buf->rwWrap = SAME_WRAP;\n            memcpy(data, buf->data + buf->readPos,\n                sizeof(bufdata_t)*margin);\n            buf->readPos = 0;\n            n = size - margin;\n        }\n        else {\n            memcpy(data, buf->data + buf->readPos,\n                sizeof(bufdata_t)*n);\n            buf->readPos += n;\n            return n;\n        }\n    }\n\n    if (buf->rwWrap == SAME_WRAP) {\n        margin = buf->writePos - buf->readPos;\n        if (margin > n)\n            margin = n;\n        memcpy(data + size - n, buf->data + buf->readPos,\n            sizeof(bufdata_t)*margin);\n        buf->readPos += margin;\n        n -= margin;\n    }\n\n    return size - n;\n}\n\nint WebRtcApm_WriteBuffer(void *bufInst, const bufdata_t *data, int size)\n{\n    buf_t *buf = (buf_t*)bufInst;\n    int n = 0, margin = 0;\n\n    if (size < 0 || size > buf->size) {\n        return -1;\n    }\n\n    n = size;\n    if (buf->rwWrap == SAME_WRAP) {\n        margin = buf->size - buf->writePos;\n        if (n > margin) {\n            buf->rwWrap = DIFF_WRAP;\n            memcpy(buf->data + buf->writePos, data,\n                sizeof(bufdata_t)*margin);\n            buf->writePos = 0;\n            n = size - margin;\n        }\n        else {\n            memcpy(buf->data + buf->writePos, data,\n                sizeof(bufdata_t)*n);\n            buf->writePos += n;\n            return n;\n        }\n    }\n\n    if (buf->rwWrap == DIFF_WRAP) {\n        margin = buf->readPos - buf->writePos;\n        if (margin > n)\n            margin = n;\n        memcpy(buf->data + buf->writePos, data + size - n,\n            sizeof(bufdata_t)*margin);\n        buf->writePos += margin;\n        n -= margin;\n    }\n\n    return size - n;\n}\n\nint WebRtcApm_FlushBuffer(void *bufInst, int size)\n{\n    buf_t *buf = (buf_t*)bufInst;\n    int n = 0, margin = 0;\n\n    if (size <= 0 || size > buf->size) {\n        return -1;\n    }\n\n    n = size;\n    if (buf->rwWrap == DIFF_WRAP) {\n        margin = buf->size - buf->readPos;\n        if (n > margin) {\n            buf->rwWrap = SAME_WRAP;\n            buf->readPos = 0;\n            n = size - margin;\n        }\n        else {\n            buf->readPos += n;\n            return n;\n        }\n    }\n\n    if (buf->rwWrap == SAME_WRAP) {\n        margin = buf->writePos - buf->readPos;\n        if (margin > n)\n            margin = n;\n        buf->readPos += margin;\n        n -= margin;\n    }\n\n    return size - n;\n}\n\nint WebRtcApm_StuffBuffer(void *bufInst, int size)\n{\n    buf_t *buf = (buf_t*)bufInst;\n    int n = 0, margin = 0;\n\n    if (size <= 0 || size > buf->size) {\n        return -1;\n    }\n\n    n = size;\n    if (buf->rwWrap == SAME_WRAP) {\n        margin = buf->readPos;\n        if (n > margin) {\n            buf->rwWrap = DIFF_WRAP;\n            buf->readPos = buf->size - 1;\n            n -= margin + 1;\n        }\n        else {\n            buf->readPos -= n;\n            return n;\n        }\n    }\n\n    if (buf->rwWrap == DIFF_WRAP) {\n        margin = buf->readPos - buf->writePos;\n        if (margin > n)\n            margin = n;\n        buf->readPos -= margin;\n        n -= margin;\n    }\n\n    return size - n;\n}\n\nint WebRtcApm_get_buffer_size(const void *bufInst)\n{\n    const buf_t *buf = (buf_t*)bufInst;\n\n    if (buf->rwWrap == SAME_WRAP)\n        return buf->writePos - buf->readPos;\n    else\n        return buf->size - buf->readPos + buf->writePos;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/modules/audio_processing/utility/ring_buffer.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/*\n * Specifies the interface for the AEC generic buffer.\n */\n\n#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_RING_BUFFER_H_\n#define WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_RING_BUFFER_H_\n\n// Determines buffer datatype\ntypedef short bufdata_t;\n\n// Unless otherwise specified, functions return 0 on success and -1 on error\nint WebRtcApm_CreateBuffer(void **bufInst, int size);\nint WebRtcApm_InitBuffer(void *bufInst);\nint WebRtcApm_FreeBuffer(void *bufInst);\n\n// Returns number of samples read\nint WebRtcApm_ReadBuffer(void *bufInst, bufdata_t *data, int size);\n\n// Returns number of samples written\nint WebRtcApm_WriteBuffer(void *bufInst, const bufdata_t *data, int size);\n\n// Returns number of samples flushed\nint WebRtcApm_FlushBuffer(void *bufInst, int size);\n\n// Returns number of samples stuffed\nint WebRtcApm_StuffBuffer(void *bufInst, int size);\n\n// Returns number of samples in buffer\nint WebRtcApm_get_buffer_size(const void *bufInst);\n\n#endif // WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_RING_BUFFER_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/OWNERS",
    "content": "henrike@webrtc.org\npwestin@webrtc.org\nperkj@webrtc.org\nhenrika@webrtc.org\nhenrikg@webrtc.org\nmflodman@webrtc.org\nniklas.enbom@webrtc.org"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/aligned_malloc.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ALIGNED_MALLOC_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ALIGNED_MALLOC_H_\n\n#include <stddef.h>\n\nnamespace webrtc\n{\n    void* AlignedMalloc(\n        size_t size,\n        size_t alignment);\n    void AlignedFree(\n        void* memBlock);\n}\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ALIGNED_MALLOC_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/atomic32_wrapper.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n// Atomic system independant 32-bit integer.\n// Note: uses full memory barriers.\n// Note: assumes 32-bit (or higher) system\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_WRAPPER_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_WRAPPER_H_\n\n#include \"common_types.h\"\n\nnamespace webrtc {\nclass Atomic32Impl;\nclass Atomic32Wrapper\n{\npublic:\n    Atomic32Wrapper(WebRtc_Word32 initialValue = 0);\n    ~Atomic32Wrapper();\n\n    // Prefix operator!\n    WebRtc_Word32 operator++();\n    WebRtc_Word32 operator--();\n\n    Atomic32Wrapper& operator=(const Atomic32Wrapper& rhs);\n    Atomic32Wrapper& operator=(WebRtc_Word32 rhs);\n\n    WebRtc_Word32 operator+=(WebRtc_Word32 rhs);\n    WebRtc_Word32 operator-=(WebRtc_Word32 rhs);\n\n    // Sets the value atomically to newValue if the value equals compare value.\n    // The function returns true if the exchange happened.\n    bool CompareExchange(WebRtc_Word32 newValue, WebRtc_Word32 compareValue);\n    WebRtc_Word32 Value() const;\nprivate:\n    // Disable the + and - operator since it's unclear what these operations\n    // should do.\n    Atomic32Wrapper operator+(const Atomic32Wrapper& rhs);\n    Atomic32Wrapper operator-(const Atomic32Wrapper& rhs);\n\n    WebRtc_Word32& operator++(int);\n    WebRtc_Word32& operator--(int);\n\n    // Cheshire cat to hide the implementation (faster than\n    // using virtual functions)\n    Atomic32Impl& _impl;\n};\n} // namespace webrtc\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_WRAPPER_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/condition_variable_wrapper.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONDITION_VARIABLE_WRAPPER_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONDITION_VARIABLE_WRAPPER_H_\n\nnamespace webrtc {\nclass CriticalSectionWrapper;\n\nclass ConditionVariableWrapper\n{\npublic:\n    // Factory method, constructor disabled.\n    static ConditionVariableWrapper* CreateConditionVariable();\n\n    virtual ~ConditionVariableWrapper() {}\n\n    // Calling thread will atomically release critSect and wait until next\n    // some other thread calls Wake() or WakeAll().\n    virtual void SleepCS(CriticalSectionWrapper& critSect) = 0;\n\n    // Same as above but with a timeout.\n    virtual bool SleepCS(CriticalSectionWrapper& critSect,\n                         unsigned long maxTimeInMS) = 0;\n\n    // Wakes one thread calling SleepCS().\n    virtual void Wake() = 0;\n\n    // Wakes all threads calling SleepCS().\n    virtual void WakeAll() = 0;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONDITION_VARIABLE_WRAPPER_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/constructor_magic.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/*\n * WebRtc\n * Copy from third_party/libjingle/source/talk/base/constructormagic.h\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONSTRUCTOR_MAGIC_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONSTRUCTOR_MAGIC_H_\n\n#ifndef DISALLOW_ASSIGN\n#define DISALLOW_ASSIGN(TypeName) \\\n  void operator=(const TypeName&)\n#endif\n\n#ifndef DISALLOW_COPY_AND_ASSIGN\n// A macro to disallow the evil copy constructor and operator= functions\n// This should be used in the private: declarations for a class\n#define DISALLOW_COPY_AND_ASSIGN(TypeName)    \\\n  TypeName(const TypeName&);                    \\\n  DISALLOW_ASSIGN(TypeName)\n#endif\n\n#ifndef DISALLOW_EVIL_CONSTRUCTORS\n// Alternative, less-accurate legacy name.\n#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) \\\n  DISALLOW_COPY_AND_ASSIGN(TypeName)\n#endif\n\n#ifndef DISALLOW_IMPLICIT_CONSTRUCTORS\n// A macro to disallow all the implicit constructors, namely the\n// default constructor, copy constructor and operator= functions.\n//\n// This should be used in the private: declarations for a class\n// that wants to prevent anyone from instantiating it. This is\n// especially useful for classes containing only static methods.\n#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \\\n  TypeName();                                    \\\n  DISALLOW_EVIL_CONSTRUCTORS(TypeName)\n#endif\n\n#endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONSTRUCTOR_MAGIC_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/cpu_features_wrapper.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_FEATURES_WRAPPER_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_FEATURES_WRAPPER_H_\n\n#if defined(__cplusplus) || defined(c_plusplus)\nextern \"C\" {\n#endif\n\n// list of features.\ntypedef enum {\n  kSSE2,\n  kSSE3\n} CPUFeature;\n\ntypedef int (*WebRtc_CPUInfo)(CPUFeature feature);\n// returns true if the CPU supports the feature.\nextern WebRtc_CPUInfo WebRtc_GetCPUInfo;\n// No CPU feature is available => straight C path.\nextern WebRtc_CPUInfo WebRtc_GetCPUInfoNoASM;\n\n#if defined(__cplusplus) || defined(c_plusplus)\n}    // extern \"C\"\n#endif\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_FEATURES_WRAPPER_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/cpu_wrapper.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_WRAPPER_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_WRAPPER_H_\n\n#include \"typedefs.h\"\n\nnamespace webrtc {\nclass CpuWrapper\n{\npublic:\n    static WebRtc_UWord32 DetectNumberOfCores();\n\n    static CpuWrapper* CreateCpu();\n    virtual ~CpuWrapper() {}\n\n    // Returns the average CPU usage for all processors. The CPU usage can be\n    // between and including 0 to 100 (%)\n    virtual WebRtc_Word32 CpuUsage() = 0;\n    virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* processName,\n                                   WebRtc_UWord32 length) = 0;\n    virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32  dwProcessID) = 0;\n\n    // The CPU usage per core is returned in cpu_usage. The CPU can be between\n    // and including 0 to 100 (%)\n    // Note that the pointer passed as cpu_usage is redirected to a local member\n    // of the CPU wrapper.\n    // numCores is the number of cores in the cpu_usage array.\n    virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& numCores,\n                                            WebRtc_UWord32*& cpu_usage) = 0;\n\n    virtual void Reset() = 0;\n    virtual void Stop() = 0;\n\nprotected:\n    CpuWrapper() {}\n\nprivate:\n    static WebRtc_UWord32 _numberOfCores;\n\n};\n} // namespace webrtc\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_WRAPPER_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/critical_section_wrapper.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_\n\n// If the critical section is heavily contended it may be beneficial to use\n// read/write locks instead.\n\n#include \"common_types.h\"\n\nnamespace webrtc {\nclass CriticalSectionWrapper\n{\npublic:\n    // Factory method, constructor disabled\n    static CriticalSectionWrapper* CreateCriticalSection();\n\n    virtual ~CriticalSectionWrapper() {}\n\n    // Tries to grab lock, beginning of a critical section. Will wait for the\n    // lock to become available if the grab failed.\n    virtual void Enter() = 0;\n\n    // Returns a grabbed lock, end of critical section.\n    virtual void Leave() = 0;\n};\n\n// RAII extension of the critical section. Prevents Enter/Leave missmatches and\n// provides more compact critical section syntax.\nclass CriticalSectionScoped\n{\npublic:\n    CriticalSectionScoped(CriticalSectionWrapper& critsec)\n        :\n        _ptrCritSec(&critsec)\n    {\n        _ptrCritSec->Enter();\n    }\n\n    ~CriticalSectionScoped()\n    {\n        if (_ptrCritSec)\n        {\n            Leave();\n        }\n    }\n\nprivate:\n    void Leave()\n    {\n        _ptrCritSec->Leave();\n        _ptrCritSec = 0;\n    }\n\n    CriticalSectionWrapper* _ptrCritSec;\n};\n} // namespace webrtc\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/data_log.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/*\n * This singleton can be used for logging data for offline processing. Data\n * logged with it can conveniently be parsed and processed with e.g. Matlab.\n *\n * Following is an example of the log file format, starting with the header\n * row at line 1, and the data rows following.\n * col1,col2,col3,multi-value-col4[3],,,col5\n * 123,10.2,-243,1,2,3,100\n * 241,12.3,233,1,2,3,200\n * 13,16.4,-13,1,2,3,300\n *\n * As can be seen in the example, a multi-value-column is specified with the\n * name followed the number of elements it contains. This followed by\n * number of elements - 1 empty columns.\n *\n * Without multi-value-columns this format can be natively by Matlab. With\n * multi-value-columns a small Matlab script is needed, available at\n * trunk/tools/matlab/parseLog.m.\n *\n * Table names and column names are case sensitive.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_H_\n\n#include <string>\n\n#include \"data_log_impl.h\"\n\nnamespace webrtc {\n\nclass DataLog {\n public:\n  // Creates a log which uses a separate thread (referred to as the file\n  // writer thread) for writing log rows to file.\n  //\n  // Calls to this function after the log object has been created will only\n  // increment the reference counter.\n  static int CreateLog();\n\n  // Decrements the reference counter and deletes the log when the counter\n  // reaches 0. Should be called equal number of times as successful calls to\n  // CreateLog or memory leak will occur.\n  static void ReturnLog();\n\n  // Combines the string table_name and the integer table_id into a new string\n  // table_name + _ + table_id. The new string will be lower-case.\n  static std::string Combine(const std::string& table_name, int table_id);\n\n  // Adds a new table, with the name table_name, and creates the file, with the\n  // name table_name + \".txt\", to which the table will be written.\n  // table_name is treated in a case sensitive way.\n  static int AddTable(const std::string& table_name);\n\n  // Adds a new column to a table. The column will be a multi-value-column\n  // if multi_value_length is greater than 1.\n  // table_name and column_name are treated in a case sensitive way.\n  static int AddColumn(const std::string& table_name,\n                       const std::string& column_name,\n                       int multi_value_length);\n\n  // Inserts a single value into a table with name table_name at the column with\n  // name column_name.\n  // Note that the ValueContainer makes use of the copy constructor,\n  // operator= and operator<< of the type T, and that the template type must\n  // implement a deep copy copy constructor and operator=.\n  // Copy constructor and operator= must not be disabled for the type T.\n  // table_name and column_name are treated in a case sensitive way.\n  template<class T>\n  static int InsertCell(const std::string& table_name,\n                        const std::string& column_name,\n                        T value) {\n    DataLogImpl* data_log = DataLogImpl::StaticInstance();\n    if (data_log == NULL)\n      return -1;\n    return data_log->InsertCell(\n             table_name,\n             column_name,\n             new ValueContainer<T>(value));\n  }\n\n  // Inserts an array of values into a table with name table_name at the\n  // column specified by column_name, which must be a multi-value-column.\n  // Note that the MultiValueContainer makes use of the copy constructor,\n  // operator= and operator<< of the type T, and that the template type\n  // must implement a deep copy copy constructor and operator=.\n  // Copy constructor and operator= must not be disabled for the type T.\n  // table_name and column_name are treated in a case sensitive way.\n  template<class T>\n  static int InsertCell(const std::string& table_name,\n                        const std::string& column_name,\n                        const T* array,\n                        int length) {\n    DataLogImpl* data_log = DataLogImpl::StaticInstance();\n    if (data_log == NULL)\n      return -1;\n    return data_log->InsertCell(\n             table_name,\n             column_name,\n             new MultiValueContainer<T>(array, length));\n  }\n\n  // For the table with name table_name: Writes the current row to file.\n  // Starts a new empty row.\n  // table_name is treated in a case-sensitive way.\n  static int NextRow(const std::string& table_name);\n};\n\n}  // namespace webrtc\n\n#endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/data_log_impl.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n/*\n * This file contains the helper classes for the DataLog APIs. See data_log.h\n * for the APIs.\n *\n * These classes are helper classes used for logging data for offline\n * processing. Data logged with these classes can conveniently be parsed and\n * processed with e.g. Matlab.\n */\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_IMPL_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_IMPL_H_\n\n#include <map>\n#include <sstream>\n#include <string>\n#include <vector>\n\n#include \"scoped_ptr.h\"\n#include \"typedefs.h\"\n\nnamespace webrtc {\n\nclass CriticalSectionWrapper;\nclass EventWrapper;\nclass LogTable;\nclass RWLockWrapper;\nclass ThreadWrapper;\n\n// All container classes need to implement a ToString-function to be\n// writable to file. Enforce this via the Container interface.\nclass Container {\n public:\n  virtual ~Container() {}\n\n  virtual void ToString(std::string* container_string) const = 0;\n};\n\ntemplate<class T>\nclass ValueContainer : public Container {\n public:\n  explicit ValueContainer(T data) : data_(data) {}\n\n  virtual void ToString(std::string* container_string) const {\n    *container_string = \"\";\n    std::stringstream ss;\n    ss << data_ << \",\";\n    ss >> *container_string;\n  }\n\n private:\n  T   data_;\n};\n\ntemplate<class T>\nclass MultiValueContainer : public Container {\n public:\n  MultiValueContainer(const T* data, int length)\n    : data_(data, data + length) {\n  }\n\n  virtual void ToString(std::string* container_string) const {\n    *container_string = \"\";\n    std::stringstream ss;\n    for (size_t i = 0; i < data_.size(); ++i)\n      ss << data_[i] << \",\";\n    *container_string += ss.str();\n  }\n\n private:\n  std::vector<T>  data_;\n};\n\nclass DataLogImpl {\n public:\n  ~DataLogImpl();\n\n  // The implementation of the CreateLog() method declared in data_log.h.\n  // See data_log.h for a description.\n  static int CreateLog();\n\n  // The implementation of the StaticInstance() method declared in data_log.h.\n  // See data_log.h for a description.\n  static DataLogImpl* StaticInstance();\n\n  // The implementation of the ReturnLog() method declared in data_log.h. See\n  // data_log.h for a description.\n  static void ReturnLog();\n\n  // The implementation of the AddTable() method declared in data_log.h. See\n  // data_log.h for a description.\n  int AddTable(const std::string& table_name);\n\n  // The implementation of the AddColumn() method declared in data_log.h. See\n  // data_log.h for a description.\n  int AddColumn(const std::string& table_name,\n                const std::string& column_name,\n                int multi_value_length);\n\n  // Inserts a Container into a table with name table_name at the column\n  // with name column_name.\n  // column_name is treated in a case sensitive way.\n  int InsertCell(const std::string& table_name,\n                 const std::string& column_name,\n                 const Container* value_container);\n\n  // The implementation of the NextRow() method declared in data_log.h. See\n  // data_log.h for a description.\n  int NextRow(const std::string& table_name);\n\n private:\n  DataLogImpl();\n\n  // Initializes the DataLogImpl object, allocates and starts the\n  // thread file_writer_thread_.\n  int Init();\n\n  // Write all complete rows in every table to file.\n  // This function should only be called by the file_writer_thread_ if that\n  // thread is running to avoid race conditions.\n  void Flush();\n\n  // Run() is called by the thread file_writer_thread_.\n  static bool Run(void* obj);\n\n  // This function writes data to file. Note, it blocks if there is no data\n  // that should be written to file availble. Flush is the non-blocking\n  // version of this function.\n  void Process();\n\n  // Stops the continuous calling of Process().\n  void StopThread();\n\n  // Collection of tables indexed by the table name as std::string.\n  typedef std::map<std::string, LogTable*> TableMap;\n  typedef webrtc::scoped_ptr<CriticalSectionWrapper> CritSectScopedPtr;\n\n  static CritSectScopedPtr  crit_sect_;\n  static DataLogImpl*       instance_;\n  int                       counter_;\n  TableMap                  tables_;\n  EventWrapper*             flush_event_;\n  ThreadWrapper*            file_writer_thread_;\n  RWLockWrapper*            tables_lock_;\n};\n\n}  // namespace webrtc\n\n#endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_IMPL_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/event_wrapper.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_WRAPPER_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_WRAPPER_H_\n\nnamespace webrtc {\nenum EventTypeWrapper\n{\n    kEventSignaled = 1,\n    kEventError = 2,\n    kEventTimeout = 3\n};\n\n#define WEBRTC_EVENT_10_SEC   10000\n#define WEBRTC_EVENT_INFINITE 0xffffffff\n\nclass EventWrapper\n{\npublic:\n    // Factory method. Constructor disabled.\n    static EventWrapper* Create();\n    virtual ~EventWrapper() {}\n\n    // Releases threads who are calling Wait() and has started waiting. Please\n    // note that a thread calling Wait() will not start waiting immediately.\n    // assumptions to the contrary is a very common source of issues in\n    // multithreaded programming.\n    // Set is sticky in the sense that it will release at least one thread\n    // either immediately or some time in the future.\n    virtual bool Set() = 0;\n\n    // Prevents future Wait() calls from finishing without a new Set() call.\n    virtual bool Reset() = 0;\n\n    // Puts the calling thread into a wait state. The thread may be released\n    // by a Set() call depending on if other threads are waiting and if so on\n    // timing. The thread that was released will call Reset() before leaving\n    // preventing more threads from being released. If multiple threads\n    // are waiting for the same Set(), only one (random) thread is guaranteed to\n    // be released. It is possible that multiple (random) threads are released\n    // Depending on timing.\n    virtual EventTypeWrapper Wait(unsigned long maxTime) = 0;\n\n    // Starts a timer that will call a non-sticky version of Set() either once\n    // or periodically. If the timer is periodic it ensures that there is no\n    // drift over time relative to the system clock.\n    virtual bool StartTimer(bool periodic, unsigned long time) = 0;\n\n    virtual bool StopTimer() = 0;\n\n    // Only implemented on Windows\n    // Returns 1 if a key has been pressed since last call to this function.\n    // -1 indicates failure\n    // 0 indicates no key has been pressed since last call\n    // TODO(hellner) this function does not seem to belong here\n    static int KeyPressed();\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_WRAPPER_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/file_wrapper.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_FILE_WRAPPER_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_FILE_WRAPPER_H_\n\n#include \"common_types.h\"\n#include \"typedefs.h\"\n\n// Implementation of an InStream and OutStream that can read (exclusive) or\n// write from/to a file.\n\nnamespace webrtc {\nclass FileWrapper : public InStream, public OutStream\n{\npublic:\n    enum { kMaxFileNameSize = 1024};\n    enum { kFileMaxTextMessageSize = 1024};\n\n    // Factory method. Constructor disabled.\n    static FileWrapper* Create();\n\n    // Returns true if a file has been opened.\n    virtual bool Open() const = 0;\n\n    // Opens a file in read or write mode, decided by the readOnly parameter.\n    virtual WebRtc_Word32 OpenFile(const WebRtc_Word8* fileNameUTF8,\n                                   const bool readOnly,\n                                   const bool loop = false,\n                                   const bool text = false) = 0;\n\n    virtual WebRtc_Word32 CloseFile() = 0;\n\n    // Limits the file size.\n    virtual WebRtc_Word32 SetMaxFileSize(WebRtc_Word32 bytes)  = 0;\n\n    // Flush any pending writes.\n    virtual WebRtc_Word32 Flush() = 0;\n\n    // Returns the opened file's name in fileNameUTF8. size is the allocated\n    // size of fileNameUTF8. The name will be truncated if the size of\n    // fileNameUTF8 is to small.\n    virtual WebRtc_Word32 FileName(WebRtc_Word8* fileNameUTF8,\n                                   WebRtc_UWord32 size) const = 0;\n\n    // Write text to the opened file. The written text can contain plain text\n    // and text with type specifiers in the same way as sprintf works.\n    virtual WebRtc_Word32 WriteText(const WebRtc_Word8* text, ...) = 0;\n\n    // Reads len number of bytes from buf to file.\n    virtual int Read(void* buf, int len) = 0;\n\n    // Writes len number of bytes to buf from file. Please note that the actual\n    // writing to file may happen some time later. Call flush to force a write\n    // to take affect\n    virtual bool Write(const void *buf,int len) = 0;\n\n    // Rewinds the file to the start. Only available when OpenFile() has been\n    // called with loop argument set to true. Or readOnly argument has been set\n    // to false.\n    virtual int Rewind() = 0;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_FILE_WRAPPER_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/fix_interlocked_exchange_pointer_windows.h",
    "content": "// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file under third_party_mods/chromium directory of\n// source tree or at\n// http://src.chromium.org/viewvc/chrome/trunk/src/LICENSE\n\n// Various inline functions and macros to fix compilation of 32 bit target\n// on MSVC with /Wp64 flag enabled.\n\n// The original code can be found here:\n// http://src.chromium.org/svn/trunk/src/base/fix_wp64.h\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_FIX_INTERLOCKED_EXCHANGE_POINTER_WINDOWS_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_FIX_INTERLOCKED_EXCHANGE_POINTER_WINDOWS_H_\n\n#include <windows.h>\n\n// Platform SDK fixes when building with /Wp64 for a 32 bits target.\n#if !defined(_WIN64) && defined(_Wp64)\n\n#ifdef InterlockedExchangePointer\n#undef InterlockedExchangePointer\n// The problem is that the macro provided for InterlockedExchangePointer() is\n// doing a (LONG) C-style cast that triggers invariably the warning C4312 when\n// building on 32 bits.\ninline void* InterlockedExchangePointer(void* volatile* target, void* value) {\n  return reinterpret_cast<void*>(static_cast<LONG_PTR>(InterlockedExchange(\n      reinterpret_cast<volatile LONG*>(target),\n      static_cast<LONG>(reinterpret_cast<LONG_PTR>(value)))));\n}\n#endif  // #ifdef InterlockedExchangePointer\n\n#endif // #if !defined(_WIN64) && defined(_Wp64)\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_FIX_INTERLOCKED_EXCHANGE_POINTER_WINDOWS_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/list_wrapper.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LIST_WRAPPER_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LIST_WRAPPER_H_\n\n#include \"constructor_magic.h\"\n\nnamespace webrtc {\nclass CriticalSectionWrapper;\n\nclass ListItem\n{\nfriend class ListWrapper;\n\npublic:\n    ListItem(const void* ptr);\n    ListItem(const unsigned int item);\n    virtual ~ListItem();\n    void* GetItem() const;\n    unsigned int GetUnsignedItem() const;\n\nprotected:\n    ListItem* next_;\n    ListItem* prev_;\n\nprivate:\n    const void*         item_ptr_;\n    const unsigned int  item_;\n};\n\nclass ListWrapper\n{\npublic:\n    ListWrapper();\n    virtual ~ListWrapper();\n\n    // Returns the number of elements stored in the list.\n    unsigned int GetSize() const;\n\n    // Puts a pointer to anything last in the list.\n    int PushBack(const void* ptr);\n    // Puts a pointer to anything first in the list.\n    int PushFront(const void* ptr);\n\n    // Puts a copy of the specified integer last in the list.\n    int PushBack(const unsigned int item_id);\n    // Puts a copy of the specified integer first in the list.\n    int PushFront(const unsigned int item_id);\n\n    // Pops the first ListItem from the list\n    int PopFront();\n\n    // Pops the last ListItem from the list\n    int PopBack();\n\n    // Returns true if the list is empty\n    bool Empty() const;\n\n    // Returns a pointer to the first ListItem in the list.\n    ListItem* First() const;\n\n    // Returns a pointer to the last ListItem in the list.\n    ListItem* Last() const;\n\n    // Returns a pointer to the ListItem stored after item in the list.\n    ListItem* Next(ListItem* item) const;\n\n    // Returns a pointer to the ListItem stored before item in the list.\n    ListItem* Previous(ListItem* item) const;\n\n    // Removes item from the list.\n    int Erase(ListItem* item);\n\n    // Insert list item after existing_previous_item. Please note that new_item\n    // must be created using new ListItem(). The map will take ownership of\n    // new_item following a successfull insert. If insert fails new_item will\n    // not be released by the List\n    int Insert(ListItem* existing_previous_item,\n               ListItem* new_item);\n\n    // Insert list item before existing_next_item. Please note that new_item\n    // must be created using new ListItem(). The map will take ownership of\n    // new_item following a successfull insert. If insert fails new_item will\n    // not be released by the List\n    int InsertBefore(ListItem* existing_next_item,\n                     ListItem* new_item);\n\nprivate:\n    void PushBackImpl(ListItem* item);\n    void PushFrontImpl(ListItem* item);\n\n    CriticalSectionWrapper* critical_section_;\n    ListItem* first_;\n    ListItem* last_;\n    unsigned int size_;\n};\n} //namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LIST_WRAPPER_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/map_wrapper.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_MAP_WRAPPER_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_MAP_WRAPPER_H_\n\n#include <map>\n\n#include \"constructor_magic.h\"\n\nnamespace webrtc {\nclass MapItem\n{\nfriend class MapWrapper;\n\npublic:\n    MapItem(int id, void* ptr);\n    virtual ~MapItem();\n    void* GetItem();\n    int GetId();\n    unsigned int GetUnsignedId();\n    void SetItem(void* ptr);\n\nprivate:\n    int   item_id_;\n    void* item_pointer_;\n};\n\nclass MapWrapper\n{\npublic:\n    MapWrapper();\n    ~MapWrapper();\n\n    // Puts a pointer to anything in the map and associates it with id. Note, id\n    // needs to be unique for all items in the map.\n    int Insert(int id, void* ptr);\n\n    // Removes item from map.\n    int Erase(MapItem* item);\n\n    // Finds item with associated with id and removes it from the map.\n    int Erase(int id);\n\n    // Returns the number of elements stored in the map.\n    int Size() const;\n\n    // Returns a pointer to the first MapItem in the map.\n    MapItem* First() const;\n\n    // Returns a pointer to the last MapItem in the map.\n    MapItem* Last() const;\n\n    // Returns a pointer to the MapItem stored after item in the map.\n    MapItem* Next(MapItem* item) const;\n\n    // Returns a pointer to the MapItem stored before item in the map.\n    MapItem* Previous(MapItem* item) const;\n\n    // Returns a pointer to the MapItem associated with id from the map.\n    MapItem* Find(int id) const;\n\nprivate:\n    std::map<int, MapItem*>    map_;\n};\n} // namespace webrtc\n\n#endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_MAP_WRAPPER_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/ref_count.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef SYSTEM_WRAPPERS_INTERFACE_REF_COUNT_H_\n#define SYSTEM_WRAPPERS_INTERFACE_REF_COUNT_H_\n\n#include \"system_wrappers/interface/atomic32_wrapper.h\"\n\nnamespace webrtc {\n\n// This class can be used for instantiating\n// reference counted objects.\n// int32_t AddRef() and int32_t Release().\n// Usage:\n// RefCountImpl<T>* implementation = new RefCountImpl<T>(p);\n//\n// Example:\n// class MyInterface {\n//  public:\n//   virtual void DoSomething() = 0;\n//   virtual int32_t AddRef() = 0;\n//   virtual int32_t Release() = 0:\n//  private:\n//   virtual ~MyInterface(){};\n// }\n// class MyImplementation : public MyInterface {\n//  public:\n//   virtual DoSomething() { printf(\"hello\"); };\n// };\n// MyImplementation* CreateMyImplementation() {\n//   RefCountImpl<MyImplementation>* implementation =\n//       new RefCountImpl<MyImplementation>();\n//   return implementation;\n// }\n\ntemplate <class T>\nclass RefCountImpl : public T {\n public:\n  RefCountImpl() : ref_count_(0) {}\n\n  template<typename P>\n  explicit RefCountImpl(P p) : T(p), ref_count_(0) {}\n\n  template<typename P1, typename P2>\n  RefCountImpl(P1 p1, P2 p2) : T(p1, p2), ref_count_(0) {}\n\n  template<typename P1, typename P2, typename P3>\n  RefCountImpl(P1 p1, P2 p2, P3 p3) : T(p1, p2, p3), ref_count_(0) {}\n\n  template<typename P1, typename P2, typename P3, typename P4>\n  RefCountImpl(P1 p1, P2 p2, P3 p3, P4 p4) : T(p1, p2, p3, p4), ref_count_(0) {}\n\n  template<typename P1, typename P2, typename P3, typename P4, typename P5>\n  RefCountImpl(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)\n      : T(p1, p2, p3, p4, p5), ref_count_(0) {}\n\n  virtual int32_t AddRef() {\n    return ++ref_count_;\n  }\n\n  virtual int32_t Release() {\n    int32_t ref_count;\n    ref_count = --ref_count_;\n    if (ref_count == 0)\n      delete this;\n    return ref_count;\n  }\n\n protected:\n  Atomic32Wrapper ref_count_;\n};\n\n}  // namespace webrtc\n\n#endif  // SYSTEM_WRAPPERS_INTERFACE_REF_COUNT_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/rpcsal.h",
    "content": "#pragma once\n\n#if __GNUC__ >=3\n#pragma GCC system_header\n#endif\n\n#define RPC_range(min,max)\n\n#define __RPC__in           \n#define __RPC__in_string\n#define __RPC__in_opt_string\n#define __RPC__deref_opt_in_opt\n#define __RPC__opt_in_opt_string\n#define __RPC__in_ecount(size) \n#define __RPC__in_ecount_full(size)\n#define __RPC__in_ecount_full_string(size)\n#define __RPC__in_ecount_part(size, length)\n#define __RPC__in_ecount_full_opt(size)\n#define __RPC__in_ecount_full_opt_string(size)\n#define __RPC__inout_ecount_full_opt_string(size)\n#define __RPC__in_ecount_part_opt(size, length)\n\n#define __RPC__deref_in \n#define __RPC__deref_in_string\n#define __RPC__deref_opt_in\n#define __RPC__deref_in_opt\n#define __RPC__deref_in_ecount(size) \n#define __RPC__deref_in_ecount_part(size, length) \n#define __RPC__deref_in_ecount_full(size) \n#define __RPC__deref_in_ecount_full_opt(size)\n#define __RPC__deref_in_ecount_full_string(size)\n#define __RPC__deref_in_ecount_full_opt_string(size)\n#define __RPC__deref_in_ecount_opt(size) \n#define __RPC__deref_in_ecount_opt_string(size)\n#define __RPC__deref_in_ecount_part_opt(size, length) \n\n// [out]\n#define __RPC__out     \n#define __RPC__out_ecount(size) \n#define __RPC__out_ecount_part(size, length) \n#define __RPC__out_ecount_full(size)\n#define __RPC__out_ecount_full_string(size)\n\n// [in,out] \n#define __RPC__inout                                   \n#define __RPC__inout_string\n#define __RPC__opt_inout\n#define __RPC__inout_ecount(size)                     \n#define __RPC__inout_ecount_part(size, length)    \n#define __RPC__inout_ecount_full(size)          \n#define __RPC__inout_ecount_full_string(size)          \n\n// [in,unique] \n#define __RPC__in_opt       \n#define __RPC__in_ecount_opt(size)   \n\n\n// [in,out,unique] \n#define __RPC__inout_opt    \n#define __RPC__inout_ecount_opt(size)  \n#define __RPC__inout_ecount_part_opt(size, length) \n#define __RPC__inout_ecount_full_opt(size)     \n#define __RPC__inout_ecount_full_string(size)\n\n// [out] **\n#define __RPC__deref_out   \n#define __RPC__deref_out_string\n#define __RPC__deref_out_opt \n#define __RPC__deref_out_opt_string\n#define __RPC__deref_out_ecount(size) \n#define __RPC__deref_out_ecount_part(size, length) \n#define __RPC__deref_out_ecount_full(size)  \n#define __RPC__deref_out_ecount_full_string(size)\n\n\n// [in,out] **, second pointer decoration. \n#define __RPC__deref_inout    \n#define __RPC__deref_inout_string\n#define __RPC__deref_inout_opt \n#define __RPC__deref_inout_opt_string\n#define __RPC__deref_inout_ecount_full(size)\n#define __RPC__deref_inout_ecount_full_string(size)\n#define __RPC__deref_inout_ecount_opt(size) \n#define __RPC__deref_inout_ecount_part_opt(size, length) \n#define __RPC__deref_inout_ecount_full_opt(size) \n#define __RPC__deref_inout_ecount_full_opt_string(size) \n\n// #define __RPC_out_opt    out_opt is not allowed in rpc\n\n// [in,out,unique] \n#define __RPC__deref_opt_inout  \n#define __RPC__deref_opt_inout_string\n#define __RPC__deref_opt_inout_ecount(size)     \n#define __RPC__deref_opt_inout_ecount_part(size, length) \n#define __RPC__deref_opt_inout_ecount_full(size) \n#define __RPC__deref_opt_inout_ecount_full_string(size)\n\n#define __RPC__deref_out_ecount_opt(size) \n#define __RPC__deref_out_ecount_part_opt(size, length) \n#define __RPC__deref_out_ecount_full_opt(size) \n#define __RPC__deref_out_ecount_full_opt_string(size)\n\n#define __RPC__deref_opt_inout_opt      \n#define __RPC__deref_opt_inout_opt_string\n#define __RPC__deref_opt_inout_ecount_opt(size)   \n#define __RPC__deref_opt_inout_ecount_part_opt(size, length) \n#define __RPC__deref_opt_inout_ecount_full_opt(size) \n#define __RPC__deref_opt_inout_ecount_full_opt_string(size) \n\n#define __RPC_full_pointer  \n#define __RPC_unique_pointer\n#define __RPC_ref_pointer\n#define __RPC_string                               \n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/rw_lock_wrapper.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_RW_LOCK_WRAPPER_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_RW_LOCK_WRAPPER_H_\n\n// Note, Windows pre-Vista version of RW locks are not supported nativly. For\n// these OSs regular critical sections have been used to approximate RW lock\n// functionality and will therefore have worse performance.\n\nnamespace webrtc {\nclass RWLockWrapper\n{\npublic:\n    static RWLockWrapper* CreateRWLock();\n    virtual ~RWLockWrapper();\n\n    virtual void AcquireLockExclusive() = 0;\n    virtual void ReleaseLockExclusive() = 0;\n\n    virtual void AcquireLockShared() = 0;\n    virtual void ReleaseLockShared() = 0;\n\nprotected:\n    virtual int Init() = 0;\n};\n\n// RAII extensions of the RW lock. Prevents Acquire/Release missmatches and\n// provides more compact locking syntax.\nclass ReadLockScoped\n{\npublic:\n    ReadLockScoped(RWLockWrapper& rwLock)\n        :\n        _rwLock(rwLock)\n    {\n        _rwLock.AcquireLockShared();\n    }\n\n    ~ReadLockScoped()\n    {\n        _rwLock.ReleaseLockShared();\n    }\n\nprivate:\n    RWLockWrapper& _rwLock;\n};\n\nclass WriteLockScoped\n{\npublic:\n    WriteLockScoped(RWLockWrapper& rwLock)\n        :\n        _rwLock(rwLock)\n    {\n        _rwLock.AcquireLockExclusive();\n    }\n\n    ~WriteLockScoped()\n    {\n        _rwLock.ReleaseLockExclusive();\n    }\n\nprivate:\n    RWLockWrapper& _rwLock;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_RW_LOCK_WRAPPER_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/scoped_ptr.h",
    "content": "//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.\n//  Copyright (c) 2001, 2002 Peter Dimov\n//\n//  Permission to copy, use, modify, sell and distribute this software\n//  is granted provided this copyright notice appears in all copies.\n//  This software is provided \"as is\" without express or implied\n//  warranty, and with no claim as to its suitability for any purpose.\n//\n//  See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.\n//\n\n//  scoped_ptr mimics a built-in pointer except that it guarantees deletion\n//  of the object pointed to, either on destruction of the scoped_ptr or via\n//  an explicit reset(). scoped_ptr is a simple solution for simple needs;\n//  use shared_ptr or std::auto_ptr if your needs are more complex.\n\n//  scoped_ptr_malloc added in by Google.  When one of\n//  these goes out of scope, instead of doing a delete or delete[], it\n//  calls free().  scoped_ptr_malloc<char> is likely to see much more\n//  use than any other specializations.\n\n//  release() added in by Google. Use this to conditionally\n//  transfer ownership of a heap-allocated object to the caller, usually on\n//  method success.\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_\n\n#include <assert.h>            // for assert\n#include <stdlib.h>            // for free() decl\n\n#include <cstddef>             // for std::ptrdiff_t\n\n#ifdef _WIN32\nnamespace std { using ::ptrdiff_t; };\n#endif // _WIN32\n\nnamespace webrtc {\n\ntemplate <typename T>\nclass scoped_ptr {\n private:\n\n  T* ptr;\n\n  scoped_ptr(scoped_ptr const &);\n  scoped_ptr & operator=(scoped_ptr const &);\n\n public:\n\n  typedef T element_type;\n\n  explicit scoped_ptr(T* p = NULL): ptr(p) {}\n\n  ~scoped_ptr() {\n    typedef char type_must_be_complete[sizeof(T)];\n    delete ptr;\n  }\n\n  void reset(T* p = NULL) {\n    typedef char type_must_be_complete[sizeof(T)];\n\n    if (ptr != p) {\n      T* obj = ptr;\n      ptr = p;\n      // Delete last, in case obj destructor indirectly results in ~scoped_ptr\n      delete obj;\n    }\n  }\n\n  T& operator*() const {\n    assert(ptr != NULL);\n    return *ptr;\n  }\n\n  T* operator->() const  {\n    assert(ptr != NULL);\n    return ptr;\n  }\n\n  T* get() const  {\n    return ptr;\n  }\n\n  void swap(scoped_ptr & b) {\n    T* tmp = b.ptr;\n    b.ptr = ptr;\n    ptr = tmp;\n  }\n\n  T* release() {\n    T* tmp = ptr;\n    ptr = NULL;\n    return tmp;\n  }\n\n  T** accept() {\n    if (ptr) {\n      delete ptr;\n      ptr = NULL;\n    }\n    return &ptr;\n  }\n\n  T** use() {\n    return &ptr;\n  }\n};\n\ntemplate<typename T> inline\nvoid swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {\n  a.swap(b);\n}\n\n\n\n\n//  scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to\n//  is guaranteed, either on destruction of the scoped_array or via an explicit\n//  reset(). Use shared_array or std::vector if your needs are more complex.\n\ntemplate<typename T>\nclass scoped_array {\n private:\n\n  T* ptr;\n\n  scoped_array(scoped_array const &);\n  scoped_array & operator=(scoped_array const &);\n\n public:\n\n  typedef T element_type;\n\n  explicit scoped_array(T* p = NULL) : ptr(p) {}\n\n  ~scoped_array() {\n    typedef char type_must_be_complete[sizeof(T)];\n    delete[] ptr;\n  }\n\n  void reset(T* p = NULL) {\n    typedef char type_must_be_complete[sizeof(T)];\n\n    if (ptr != p) {\n      T* arr = ptr;\n      ptr = p;\n      // Delete last, in case arr destructor indirectly results in ~scoped_array\n      delete [] arr;\n    }\n  }\n\n  T& operator[](std::ptrdiff_t i) const {\n    assert(ptr != NULL);\n    assert(i >= 0);\n    return ptr[i];\n  }\n\n  T* get() const {\n    return ptr;\n  }\n\n  void swap(scoped_array & b) {\n    T* tmp = b.ptr;\n    b.ptr = ptr;\n    ptr = tmp;\n  }\n\n  T* release() {\n    T* tmp = ptr;\n    ptr = NULL;\n    return tmp;\n  }\n\n  T** accept() {\n    if (ptr) {\n      delete [] ptr;\n      ptr = NULL;\n    }\n    return &ptr;\n  }\n};\n\ntemplate<class T> inline\nvoid swap(scoped_array<T>& a, scoped_array<T>& b) {\n  a.swap(b);\n}\n\n// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a\n// second template argument, the function used to free the object.\n\ntemplate<typename T, void (*FF)(void*) = free> class scoped_ptr_malloc {\n private:\n\n  T* ptr;\n\n  scoped_ptr_malloc(scoped_ptr_malloc const &);\n  scoped_ptr_malloc & operator=(scoped_ptr_malloc const &);\n\n public:\n\n  typedef T element_type;\n\n  explicit scoped_ptr_malloc(T* p = 0): ptr(p) {}\n\n  ~scoped_ptr_malloc() {\n    FF(static_cast<void*>(ptr));\n  }\n\n  void reset(T* p = 0) {\n    if (ptr != p) {\n      FF(static_cast<void*>(ptr));\n      ptr = p;\n    }\n  }\n\n  T& operator*() const {\n    assert(ptr != 0);\n    return *ptr;\n  }\n\n  T* operator->() const {\n    assert(ptr != 0);\n    return ptr;\n  }\n\n  T* get() const {\n    return ptr;\n  }\n\n  void swap(scoped_ptr_malloc & b) {\n    T* tmp = b.ptr;\n    b.ptr = ptr;\n    ptr = tmp;\n  }\n\n  T* release() {\n    T* tmp = ptr;\n    ptr = 0;\n    return tmp;\n  }\n\n  T** accept() {\n    if (ptr) {\n      FF(static_cast<void*>(ptr));\n      ptr = 0;\n    }\n    return &ptr;\n  }\n};\n\ntemplate<typename T, void (*FF)(void*)> inline\nvoid swap(scoped_ptr_malloc<T,FF>& a, scoped_ptr_malloc<T,FF>& b) {\n  a.swap(b);\n}\n\n} // namespace webrtc\n\n#endif  // #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/sort.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n// Generic unstable sorting routines.\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SORT_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SORT_H_\n\n#include \"typedefs.h\"\n#include \"common_types.h\"\n\nnamespace webrtc\n{\n    enum Type\n    {\n        TYPE_Word8,\n        TYPE_UWord8,\n        TYPE_Word16,\n        TYPE_UWord16,\n        TYPE_Word32,\n        TYPE_UWord32,\n        TYPE_Word64,\n        TYPE_UWord64,\n        TYPE_Float32,\n        TYPE_Float64\n    };\n    // Sorts intrinsic data types.\n    //\n    // data          [in/out] A pointer to an array of intrinsic type.\n    //               Upon return it will be sorted in ascending order.\n    // numOfElements The number of elements in the array.\n    // dataType      Enum corresponding to the type of the array.\n    //\n    // returns 0 on success, -1 on failure.\n    WebRtc_Word32 Sort(void* data, WebRtc_UWord32 numOfElements, Type dataType);\n\n    // Sorts arbitrary data types. This requires an array of intrinsically typed\n    // key values which will be used to sort the data array. There must be a\n    // one-to-one correspondence between data elements and key elements, with\n    // corresponding elements sharing the same position in their respective\n    // arrays.\n    //\n    // data          [in/out] A pointer to an array of arbitrary type.\n    //               Upon return it will be sorted in ascending order.\n    // key           [in] A pointer to an array of keys used to sort the\n    //               data array.\n    // numOfElements The number of elements in the arrays.\n    // sizeOfElement The size, in bytes, of the data array.\n    // keyType       Enum corresponding to the type of the key array.\n    //\n    // returns 0 on success, -1 on failure.\n    //\n    WebRtc_Word32 KeySort(void* data, void* key, WebRtc_UWord32 numOfElements,\n                          WebRtc_UWord32 sizeOfElement, Type keyType);\n}\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SORT_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/thread_wrapper.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n// System independant wrapper for spawning threads\n// Note: the spawned thread will loop over the callback function until stopped.\n// Note: The callback function is expected to return every 2 seconds or more\n// often.\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_\n\nnamespace webrtc {\n// Object that will be passed by the spawned thread when it enters the callback\n// function.\n#define ThreadObj void*\n\n// Callback function that the spawned thread will enter once spawned\ntypedef  bool(*ThreadRunFunction)(ThreadObj);\n\nenum ThreadPriority\n{\n    kLowPriority = 1,\n    kNormalPriority = 2,\n    kHighPriority = 3,\n    kHighestPriority = 4,\n    kRealtimePriority = 5\n};\n\nclass ThreadWrapper\n{\npublic:\n    enum {kThreadMaxNameLength = 64};\n\n    virtual ~ThreadWrapper() {};\n\n    // Factory method. Constructor disabled.\n    //\n    // func        Pointer to a, by user, specified callback function.\n    // obj         Object associated with the thread. Passed in the callback\n    //             function.\n    // prio        Thread priority. May require root/admin rights.\n    // threadName  NULL terminated thread name, will be visable in the Windows\n    //             debugger.\n    static ThreadWrapper* CreateThread(ThreadRunFunction func = 0,\n                                    ThreadObj obj= 0,\n                                    ThreadPriority prio = kNormalPriority,\n                                    const char* threadName = 0);\n\n    // Non blocking termination of the spawned thread. Note that it is not safe\n    // to delete this class until the spawned thread has been reclaimed.\n    virtual void SetNotAlive() = 0;\n\n    // Spawns the thread. This will start the triggering of the callback\n    // function.\n    virtual bool Start(unsigned int& id) = 0;\n\n    // Sets the threads CPU affinity. CPUs are listed 0 - (number of CPUs - 1).\n    // The numbers in processorNumbers specify which CPUs are allowed to run the\n    // thread. processorNumbers should not contain any duplicates and elements\n    // should be lower than (number of CPUs - 1). amountOfProcessors should be\n    // equal to the number of processors listed in processorNumbers\n    virtual bool SetAffinity(const int* /*processorNumbers*/,\n                             const unsigned int /*amountOfProcessors*/)\n                            {return false;}\n\n    // Stops the spawned thread and waits for it to be reclaimed with a timeout\n    // of two seconds. Will return false if the thread was not reclaimed.\n    // Multiple tries to Stop are allowed (e.g. to wait longer than 2 seconds).\n    // It's ok to call Stop() even if the spawned thread has been reclaimed.\n    virtual bool Stop() = 0;\n\n    // Stops the spawned thread dead in its tracks. Will likely result in a\n    // corrupt state. There should be an extremely good reason for even looking\n    // at this function. Can cause many problems deadlock being one of them.\n    virtual bool Shutdown() {return false;}\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/tick_util.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n// System independant wrapper for polling elapsed time in ms and us.\n// The implementation works in the tick domain which can be mapped over to the\n// time domain.\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_\n\n#if _WIN32\n#include <windows.h>\n#include <mmsystem.h>\n#elif WEBRTC_LINUX\n#include <ctime>\n#else\n#include <sys/time.h>\n#include <time.h>\n#endif\n\n#include \"typedefs.h\"\n\nnamespace webrtc {\nclass TickInterval;\n\nclass TickTime\n{\npublic:\n    // Current time in the tick domain.\n    static TickTime Now();\n\n    // Now in the time domain in ms.\n    static WebRtc_Word64 MillisecondTimestamp();\n\n    // Now in the time domain in us.\n    static WebRtc_Word64 MicrosecondTimestamp();\n\n    WebRtc_Word64 Ticks() const;\n\n    static WebRtc_Word64 MillisecondsToTicks(const WebRtc_Word64 ms);\n\n    static WebRtc_Word64 TicksToMilliseconds(const WebRtc_Word64 ticks);\n\n    // Returns a TickTime that is ticks later than the passed TickTime\n    friend TickTime operator+(const TickTime lhs, const WebRtc_Word64 ticks);\n    TickTime& operator+=(const WebRtc_Word64& rhs);\n\n\n    // Returns a TickInterval that is the difference in ticks beween rhs and lhs\n    friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs);\nprivate:\n    WebRtc_Word64 _ticks;\n};\n\nclass TickInterval\n{\npublic:\n    TickInterval();\n\n    WebRtc_Word64 Milliseconds() const;\n    WebRtc_Word64 Microseconds() const;\n\n    // Returns the sum of two TickIntervals as a TickInterval\n    friend TickInterval operator+(const TickInterval& lhs,\n                                  const TickInterval& rhs);\n    TickInterval& operator-=(const TickInterval& rhs);\n\n    // Returns a TickInterval corresponding to rhs - lhs\n    friend TickInterval operator-(const TickInterval& lhs,\n                                  const TickInterval& rhs);\n    TickInterval& operator+=(const TickInterval& rhs);\n\nprivate:\n    TickInterval(WebRtc_Word64 interval);\n\n    friend class TickTime;\n    friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs);\n\nprivate:\n    WebRtc_Word64 _interval;\n};\n\ninline TickInterval operator+(const TickInterval& lhs, const TickInterval& rhs)\n{\n    return TickInterval(lhs._interval + rhs._interval);\n}\n\ninline TickInterval operator-(const TickInterval& lhs, const TickInterval& rhs)\n{\n    return TickInterval(lhs._interval - rhs._interval);\n}\n\ninline TickInterval operator-(const TickTime& lhs,const TickTime& rhs)\n{\n    return TickInterval(lhs._ticks - rhs._ticks);\n}\n\ninline TickTime operator+(const TickTime lhs, const WebRtc_Word64 ticks)\n{\n    TickTime time = lhs;\n    time._ticks += ticks;\n    return time;\n}\n\ninline TickTime TickTime::Now()\n{\n    TickTime result;\n#if _WIN32\n    #ifdef USE_QUERY_PERFORMANCE_COUNTER\n        // QueryPerformanceCounter returns the value from the TSC which is\n        // incremented at the CPU frequency. The algorithm used requires\n        // the CPU frequency to be constant. Technology like speed stepping\n        // which has variable CPU frequency will therefore yield unpredictable,\n        // incorrect time estimations.\n        LARGE_INTEGER qpcnt;\n        QueryPerformanceCounter(&qpcnt);\n        result._ticks = qpcnt.QuadPart;\n    #else\n        static volatile LONG lastTimeGetTime = 0;\n        static volatile WebRtc_Word64 numWrapTimeGetTime = 0;\n        volatile LONG* lastTimeGetTimePtr = &lastTimeGetTime;\n        DWORD now = timeGetTime();\n        // Atomically update the last gotten time\n        DWORD old = InterlockedExchange(lastTimeGetTimePtr, now);\n        if(now < old)\n        {\n            // If now is earlier than old, there may have been a race between\n            // threads.\n            // 0x0fffffff ~3.1 days, the code will not take that long to execute\n            // so it must have been a wrap around.\n            if(old > 0xf0000000 && now < 0x0fffffff) \n            {\n                numWrapTimeGetTime++;\n            }\n        }\n        result._ticks = now + (numWrapTimeGetTime<<32);\n    #endif\n#elif defined(WEBRTC_LINUX)\n    struct timespec ts;\n    #ifdef WEBRTC_CLOCK_TYPE_REALTIME\n        clock_gettime(CLOCK_REALTIME, &ts);\n    #else\n        clock_gettime(CLOCK_MONOTONIC, &ts);\n    #endif\n    result._ticks = 1000000000LL * static_cast<WebRtc_Word64>(ts.tv_sec) + static_cast<WebRtc_Word64>(ts.tv_nsec);\n#else\n    struct timeval tv;\n    gettimeofday(&tv, NULL);\n    result._ticks = 1000000LL * static_cast<WebRtc_Word64>(tv.tv_sec) + static_cast<WebRtc_Word64>(tv.tv_usec);\n#endif\n    return result;\n}\n\ninline WebRtc_Word64 TickTime::MillisecondTimestamp()\n{\n    TickTime now = TickTime::Now();\n#if _WIN32\n    #ifdef USE_QUERY_PERFORMANCE_COUNTER\n        LARGE_INTEGER qpfreq;\n        QueryPerformanceFrequency(&qpfreq);\n        return (now._ticks * 1000) / qpfreq.QuadPart;\n    #else\n        return now._ticks;\n    #endif\n#elif WEBRTC_LINUX\n    return now._ticks / 1000000LL;\n#else\n    return now._ticks / 1000LL;\n#endif\n}\n\ninline WebRtc_Word64 TickTime::MicrosecondTimestamp()\n{\n    TickTime now = TickTime::Now();\n\n#if _WIN32\n    #ifdef USE_QUERY_PERFORMANCE_COUNTER\n        LARGE_INTEGER qpfreq;\n        QueryPerformanceFrequency(&qpfreq);\n        return (now._ticks * 1000) / (qpfreq.QuadPart/1000);\n    #else\n        return now._ticks *1000LL;\n    #endif\n#elif WEBRTC_LINUX\n    return now._ticks / 1000LL;\n#else\n    return now._ticks;\n#endif\n}\n\ninline WebRtc_Word64 TickTime::Ticks() const\n{\n    return _ticks;\n}\n\ninline WebRtc_Word64 TickTime::MillisecondsToTicks(const WebRtc_Word64 ms)\n{\n#if _WIN32\n    #ifdef USE_QUERY_PERFORMANCE_COUNTER\n        LARGE_INTEGER qpfreq;\n        QueryPerformanceFrequency(&qpfreq);\n        return (qpfreq.QuadPart * ms) / 1000;\n    #else\n        return ms;\n    #endif\n#elif WEBRTC_LINUX\n    return ms * 1000000LL;\n#else\n    return ms * 1000LL;\n#endif\n}\n\ninline WebRtc_Word64 TickTime::TicksToMilliseconds(const WebRtc_Word64 ticks)\n{\n#if _WIN32\n    #ifdef USE_QUERY_PERFORMANCE_COUNTER\n        LARGE_INTEGER qpfreq;\n        QueryPerformanceFrequency(&qpfreq);\n        return (ticks * 1000) / qpfreq.QuadPart;\n    #else\n        return ticks;\n    #endif\n#elif WEBRTC_LINUX\n    return ticks / 1000000LL;\n#else\n    return ticks / 1000LL;\n#endif\n}\n\ninline TickTime& TickTime::operator+=(const WebRtc_Word64& ticks)\n{\n    _ticks += ticks;\n    return *this;\n}\n\ninline TickInterval::TickInterval() : _interval(0)\n{\n}\n\ninline TickInterval::TickInterval(const WebRtc_Word64 interval)\n    : _interval(interval)\n{\n}\n\ninline WebRtc_Word64 TickInterval::Milliseconds() const\n{\n#if _WIN32\n    #ifdef USE_QUERY_PERFORMANCE_COUNTER\n        LARGE_INTEGER qpfreq;\n        QueryPerformanceFrequency(&qpfreq);\n        return (_interval * 1000) / qpfreq.QuadPart;\n    #else\n\t// _interval is in ms\n        return _interval;\n    #endif\n#elif WEBRTC_LINUX\n    // _interval is in ns\n    return _interval / 1000000;\n#else\n    // _interval is usecs\n    return _interval / 1000;\n#endif\n}\n\ninline WebRtc_Word64 TickInterval::Microseconds() const\n{\n#if _WIN32\n    #ifdef USE_QUERY_PERFORMANCE_COUNTER\n        LARGE_INTEGER qpfreq;\n        QueryPerformanceFrequency(&qpfreq);\n        return (_interval * 1000000) / qpfreq.QuadPart;\n    #else\n\t// _interval is in ms\n        return _interval *1000LL;\n    #endif\n#elif WEBRTC_LINUX\n    // _interval is in ns\n    return _interval / 1000;\n#else\n    // _interval is usecs\n    return _interval;\n#endif\n}\n\ninline TickInterval& TickInterval::operator+=(const TickInterval& rhs)\n{\n    _interval += rhs._interval;\n    return *this;\n}\n\ninline TickInterval& TickInterval::operator-=(const TickInterval& rhs)\n{\n    _interval -= rhs._interval;\n    return *this;\n}\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/interface/trace.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n// System independant wrapper for logging runtime information to file.\n// Note: All log messages will be written to the same trace file.\n// Note: If to many messages are written to file there will be a build up of\n//       messages. Apply filtering to avoid that.\n#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_H_\n#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_H_\n\n#include \"common_types.h\"\n#include \"typedefs.h\"\n\n#ifdef WEBRTC_NO_TRACE\n    #define WEBRTC_TRACE\n#else\n    // Ideally we would use __VA_ARGS__ but it's not supported by all compilers\n    // such as VS2003 (it's supported in VS2005). TODO (hellner) why\n    // would this be better than current implementation (not convinced)?\n    #define WEBRTC_TRACE Trace::Add\n#endif\n\nnamespace webrtc {\nclass Trace\n{\npublic:\n\n    // Increments the reference count to the trace.\n    static void CreateTrace();\n    // Decrements the reference count to the trace.\n    static void ReturnTrace();\n    // Note: any instance that writes to the trace file should increment and\n    // decrement the reference count on construction and destruction\n    // respectively\n\n    // Specifies what type of messages should be written to the trace file. The\n    // filter parameter is a bitmask where each message type is enumerated by\n    // the TraceLevel enumerator. TODO (hellner) why is the\n    // TraceLevel enumerator not defined in this file?\n    static WebRtc_Word32 SetLevelFilter(const WebRtc_UWord32 filter);\n\n    // Returns what type of messages are written to the trace file.\n    static WebRtc_Word32 LevelFilter(WebRtc_UWord32& filter);\n\n    // Sets the file name. If addFileCounter is false the same file will be\n    // reused when it fills up. If it's true a new file with incremented name\n    // will be used.\n    static WebRtc_Word32 SetTraceFile(const WebRtc_Word8* fileName,\n                                      const bool addFileCounter = false);\n\n    // Returns the name of the file that the trace is currently writing to.\n    static WebRtc_Word32 TraceFile(WebRtc_Word8 fileName[1024]);\n\n    // Registers callback to receive trace messages. TODO (hellner)\n    // why not use OutStream instead? Why is TraceCallback not defined in this\n    // file\n    static WebRtc_Word32 SetTraceCallback(TraceCallback* callback);\n\n    // Adds a trace message for writing to file. The message is put in a queue\n    // for writing to file whenever possible for performance reasons. I.e. there\n    // is a crash it is possible that the last, vital logs are not logged yet.\n    // level is the the type of message to log. If that type of messages is\n    // filtered it will not be written to file. module is an identifier for what\n    // part of the code the message is comming.\n    // id is an identifier that should be unique for that set of classes that\n    // are associated (e.g. all instances owned by an engine).\n    // msg and the elipsis are the same as e.g. sprintf.\n    // TODO (hellner) Why is TraceModule not defined in this file?\n    static void Add(const TraceLevel level,\n                    const TraceModule module,\n                    const WebRtc_Word32 id,\n                    const char* msg, ...);\n\n};\n} // namespace webrtc\n#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/aligned_malloc.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"aligned_malloc.h\"\n\n#include <assert.h>\n#include <memory.h>\n\n#ifdef WEBRTC_ANDROID\n#include <stdlib.h>\n#endif\n\n#if WEBRTC_MAC\n  #include <malloc/malloc.h>\n#else\n  #include <malloc.h>\n#endif\n\n#if _WIN32\n    #include <windows.h>\n#else\n    #include <stdint.h>\n#endif\n\n#include \"typedefs.h\"\n\n// Ok reference on memory alignment:\n// http://stackoverflow.com/questions/227897/solve-the-memory-alignment-in-c-interview-question-that-stumped-me\n\nnamespace webrtc\n{\n// TODO (hellner) better to create just one memory block and\n//                           interpret the first sizeof(AlignedMemory) bytes as\n//                           an AlignedMemory struct.\nstruct AlignedMemory\n{\n  void* alignedBuffer;\n  void* memoryPointer;\n};\n\nvoid* AlignedMalloc(size_t size, size_t alignment)\n{\n    if(alignment == 0)\n    {\n        // Don't allow alignment 0 since it's undefined.\n        return NULL;\n    }\n    // Make sure that the alignment is an integer power of two or fail.\n    if(alignment & (alignment - 1))\n    {\n        return NULL;\n    }\n\n    AlignedMemory* returnValue = new AlignedMemory();\n    if(returnValue == NULL)\n    {\n        return NULL;\n    }\n\n    // The memory is aligned towards the lowest address that so only\n    // alignment - 1 bytes needs to be allocated.\n    // A pointer to AlignedMemory must be stored so that it can be retreived for\n    // deletion, ergo the sizeof(uintptr_t).\n    returnValue->memoryPointer = malloc(size + sizeof(uintptr_t) +\n                                        alignment - 1);\n    if(returnValue->memoryPointer == NULL)\n    {\n        delete returnValue;\n        return NULL;\n    }\n\n    // Alligning after the sizeof(header) bytes will leave room for the header\n    // in the same memory block.\n    uintptr_t alignStartPos = (uintptr_t)returnValue->memoryPointer;\n    alignStartPos += sizeof(uintptr_t);\n\n    // The buffer should be aligned with 'alignment' bytes. The - 1 guarantees\n    // that we align towards the lowest address.\n    uintptr_t alignedPos = (alignStartPos + alignment - 1) & ~(alignment - 1);\n\n    // alignedPos is the address sought for.\n    returnValue->alignedBuffer = (void*)alignedPos;\n\n    // Store the address to the AlignedMemory struct in the header so that a\n    // it's possible to reclaim all memory.\n    uintptr_t headerPos = alignedPos;\n    headerPos -= sizeof(uintptr_t);\n    void* headerPtr = (void*) headerPos;\n    uintptr_t headerValue = (uintptr_t)returnValue;\n    memcpy(headerPtr,&headerValue,sizeof(uintptr_t));\n\n    return returnValue->alignedBuffer;\n}\n\nvoid AlignedFree(void* memBlock)\n{\n    if(memBlock == NULL)\n    {\n        return;\n    }\n    uintptr_t alignedPos = (uintptr_t)memBlock;\n    uintptr_t headerPos = alignedPos - sizeof(uintptr_t);\n\n    // Read out the address of the AlignedMemory struct from the header.\n    uintptr_t* headerPtr = (uintptr_t*)headerPos;\n    AlignedMemory* deleteMemory = (AlignedMemory*) *headerPtr;\n\n    if(deleteMemory->memoryPointer != NULL)\n    {\n        free(deleteMemory->memoryPointer);\n    }\n    delete deleteMemory;\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/atomic32.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"atomic32_wrapper.h\"\n\n#if defined(_WIN32)\n    #include \"atomic32_windows.h\"\n#elif defined(WEBRTC_LINUX)\n    #include \"atomic32_linux.h\"\n#elif defined(WEBRTC_MAC)\n    #include \"atomic32_mac.h\"\n#else\n    #error unsupported os!\n#endif\n\nnamespace webrtc {\nAtomic32Wrapper::Atomic32Wrapper(WebRtc_Word32 initialValue)\n    : _impl(*new Atomic32Impl(initialValue))\n{\n}\n\nAtomic32Wrapper::~Atomic32Wrapper()\n{\n    delete &_impl;\n}\n\nWebRtc_Word32 Atomic32Wrapper::operator++()\n{\n    return ++_impl;\n}\n\nWebRtc_Word32 Atomic32Wrapper::operator--()\n{\n    return --_impl;\n}\n\n// Read and write to properly aligned variables are atomic operations.\n// Ex reference (for Windows): http://msdn.microsoft.com/en-us/library/ms684122(v=VS.85).aspx\n// TODO (hellner) operator= and Atomic32Wrapper::Value() can be fully\n// implemented here.\nAtomic32Wrapper& Atomic32Wrapper::operator=(const Atomic32Wrapper& rhs)\n{\n    if(this == &rhs)\n    {\n        return *this;\n    }\n    _impl = rhs._impl;\n    return *this;\n}\n\nAtomic32Wrapper& Atomic32Wrapper::operator=(WebRtc_Word32 rhs)\n{\n    _impl = rhs;\n    return *this;\n}\n\nWebRtc_Word32 Atomic32Wrapper::operator+=(WebRtc_Word32 rhs)\n{\n    return _impl += rhs;\n}\n\nWebRtc_Word32 Atomic32Wrapper::operator-=(WebRtc_Word32 rhs)\n{\n    return _impl -= rhs;\n}\n\nbool Atomic32Wrapper::CompareExchange(WebRtc_Word32 newValue,\n                                      WebRtc_Word32 compareValue)\n{\n    return _impl.CompareExchange(newValue,compareValue);\n}\n\nWebRtc_Word32 Atomic32Wrapper::Value() const\n{\n    return _impl.Value();\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/atomic32_linux.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n// Atomic system independant 32-bit signed integer.\n// Linux implementation.\n// Note: Requires gcc 4.1.2 or later.\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_LINUX_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_LINUX_H_\n\n#include <inttypes.h>\n#include <malloc.h>\n\n#include \"common_types.h\"\n\nnamespace webrtc {\nclass Atomic32Impl\n{\npublic:\n    inline Atomic32Impl(WebRtc_Word32 initialValue);\n    inline ~Atomic32Impl();\n\n    inline WebRtc_Word32 operator++();\n    inline WebRtc_Word32 operator--();\n\n    inline Atomic32Impl& operator=(const Atomic32Impl& rhs);\n    inline Atomic32Impl& operator=(WebRtc_Word32 rhs);\n    inline WebRtc_Word32 operator+=(WebRtc_Word32 rhs);\n    inline WebRtc_Word32 operator-=(WebRtc_Word32 rhs);\n\n    inline bool CompareExchange(WebRtc_Word32 newValue,\n                                WebRtc_Word32 compareValue);\n\n    inline WebRtc_Word32 Value() const;\nprivate:\n    void*        _ptrMemory;\n    // Volatile ensures full memory barriers.\n    volatile WebRtc_Word32* _value;\n};\n\n// TODO (hellner) use aligned_malloc instead of doing it manually.\ninline Atomic32Impl::Atomic32Impl(WebRtc_Word32 initialValue)\n    : _ptrMemory(NULL),\n      _value(NULL)\n{   // Align the memory associated with _value on a 32-bit boundary. This is a\n    // requirement for the used Linux APIs to be atomic.\n    // Keep _ptrMemory to be able to reclaim memory.\n    _ptrMemory = malloc(sizeof(WebRtc_Word32)*2);\n    _value = (WebRtc_Word32*) (((uintptr_t)_ptrMemory+3)&(~0x3));\n    *_value = initialValue;\n}\n\ninline Atomic32Impl::~Atomic32Impl()\n{\n    if(_ptrMemory != NULL)\n    {\n        free(_ptrMemory);\n    }\n}\n\ninline WebRtc_Word32 Atomic32Impl::operator++()\n{\n    WebRtc_Word32 returnValue = __sync_fetch_and_add(_value,1);\n    returnValue++;\n    return returnValue;\n}\n\ninline WebRtc_Word32 Atomic32Impl::operator--()\n{\n    WebRtc_Word32 returnValue = __sync_fetch_and_sub(_value,1);\n    returnValue--;\n    return returnValue;\n}\n\ninline Atomic32Impl& Atomic32Impl::operator=(const Atomic32Impl& rhs)\n{\n    *_value = *rhs._value;\n    return *this;\n}\n\ninline Atomic32Impl& Atomic32Impl::operator=(WebRtc_Word32 rhs)\n{\n    *_value = rhs;\n    return *this;\n}\n\ninline WebRtc_Word32 Atomic32Impl::operator+=(WebRtc_Word32 rhs)\n{\n    WebRtc_Word32 returnValue = __sync_fetch_and_add(_value,rhs);\n    returnValue += rhs;\n    return returnValue;\n}\n\ninline WebRtc_Word32 Atomic32Impl::operator-=(WebRtc_Word32 rhs)\n{\n    WebRtc_Word32 returnValue = __sync_fetch_and_sub(_value,rhs);\n    returnValue -= rhs;\n    return returnValue;\n}\n\ninline bool Atomic32Impl::CompareExchange(WebRtc_Word32 newValue,\n                                          WebRtc_Word32 compareValue)\n{\n    return __sync_bool_compare_and_swap(_value,compareValue,newValue);\n}\n\ninline WebRtc_Word32 Atomic32Impl::Value() const\n{\n    return *_value;\n}\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_LINUX_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/atomic32_mac.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n// Atomic system independant 32-bit signed integer.\n// Mac implementation.\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_MAC_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_MAC_H_\n\n#include <stdlib.h>\n#include <libkern/OSAtomic.h>\n\n#include \"common_types.h\"\n\nnamespace webrtc {\nclass Atomic32Impl\n{\npublic:\n    inline Atomic32Impl(WebRtc_Word32 initialValue);\n    inline ~Atomic32Impl();\n\n    inline WebRtc_Word32 operator++();\n    inline WebRtc_Word32 operator--();\n\n    inline Atomic32Impl& operator=(const Atomic32Impl& rhs);\n    inline Atomic32Impl& operator=(WebRtc_Word32 rhs);\n    inline WebRtc_Word32 operator+=(WebRtc_Word32 rhs);\n    inline WebRtc_Word32 operator-=(WebRtc_Word32 rhs);\n\n    inline bool CompareExchange(WebRtc_Word32 newValue,\n                                WebRtc_Word32 compareValue);\n\n    inline WebRtc_Word32 Value() const;\nprivate:\n    void*        _ptrMemory;\n    // Volatile ensures full memory barriers.\n    volatile WebRtc_Word32* _value;\n};\n\n// TODO (hellner) use aligned_malloc instead of doing it manually.\ninline Atomic32Impl::Atomic32Impl(WebRtc_Word32 initialValue)\n    :\n    _ptrMemory(NULL),\n    _value(NULL)\n{   // Align the memory associated with _value on a 32-bit boundary. This is a\n    // requirement for the used Mac APIs to be atomic.\n    // Keep _ptrMemory to be able to reclaim memory.\n    _ptrMemory = malloc(sizeof(WebRtc_Word32)*2);\n    _value = (WebRtc_Word32*) (((uintptr_t)_ptrMemory+3)&(~0x3));\n    *_value = initialValue;\n}\n\ninline Atomic32Impl::~Atomic32Impl()\n{\n    if(_ptrMemory != NULL)\n    {\n        free(_ptrMemory);\n    }\n}\n\ninline WebRtc_Word32 Atomic32Impl::operator++()\n{\n    return OSAtomicIncrement32Barrier(\n               reinterpret_cast<volatile int32_t*>(_value));\n}\n\ninline WebRtc_Word32 Atomic32Impl::operator--()\n{\n    return OSAtomicDecrement32Barrier(\n               reinterpret_cast<volatile int32_t*>(_value));\n}\n\ninline Atomic32Impl& Atomic32Impl::operator=(const Atomic32Impl& rhs)\n{\n    *_value = *rhs._value;\n    return *this;\n}\n\ninline Atomic32Impl& Atomic32Impl::operator=(WebRtc_Word32 rhs)\n{\n    *_value = rhs;\n    return *this;\n}\n\ninline WebRtc_Word32 Atomic32Impl::operator+=(WebRtc_Word32 rhs)\n{\n    return OSAtomicAdd32Barrier(rhs,\n                                reinterpret_cast<volatile int32_t*>(_value));\n}\n\ninline WebRtc_Word32 Atomic32Impl::operator-=(WebRtc_Word32 rhs)\n{\n    return OSAtomicAdd32Barrier(-rhs,\n                                reinterpret_cast<volatile int32_t*>(_value));\n}\n\ninline bool Atomic32Impl::CompareExchange(WebRtc_Word32 newValue,\n                                          WebRtc_Word32 compareValue)\n{\n    return OSAtomicCompareAndSwap32Barrier(\n               compareValue,\n               newValue,\n               reinterpret_cast<volatile int32_t*>(_value));\n}\n\ninline WebRtc_Word32 Atomic32Impl::Value() const\n{\n    return *_value;\n}\n} // namespace webrtc\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_MAC_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/atomic32_windows.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n// Atomic system independant 32-bit signed integer.\n// Windows implementation.\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_WINDOWS_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_WINDOWS_H_\n\n#include <malloc.h>\n#include <windows.h>\n\n#include \"common_types.h\"\n\nnamespace webrtc {\nclass Atomic32Impl\n{\npublic:\n    inline Atomic32Impl(WebRtc_Word32 initialValue);\n    inline ~Atomic32Impl();\n\n    inline WebRtc_Word32 operator++();\n    inline WebRtc_Word32 operator--();\n\n    inline Atomic32Impl& operator=(const Atomic32Impl& rhs);\n    inline Atomic32Impl& operator=(WebRtc_Word32 rhs);\n    inline WebRtc_Word32 operator+=(WebRtc_Word32 rhs);\n    inline WebRtc_Word32 operator-=(WebRtc_Word32 rhs);\n\n    inline bool CompareExchange(WebRtc_Word32 newValue,\n                                WebRtc_Word32 compareValue);\n\n    inline WebRtc_Word32 Value() const;\nprivate:\n    void* _ptrMemory;\n    // Volatile ensures full memory barriers.\n    volatile LONG* _value;\n};\n\n// TODO (hellner) use aligned_malloc instead of doing it manually.\ninline Atomic32Impl::Atomic32Impl(WebRtc_Word32 initialValue)\n    : _ptrMemory(NULL),\n      _value(NULL)\n{   // Align the memory associated with _value on a 32-bit boundary. This is a\n    // requirement for the used Windows APIs to be atomic.\n    // Keep _ptrMemory to be able to reclaim memory.\n    _ptrMemory = malloc(sizeof(WebRtc_Word32)*2);\n    _value = reinterpret_cast<LONG*> (((uintptr_t)_ptrMemory+3)&(~0x3));\n    *_value = initialValue;\n}\n\ninline Atomic32Impl::~Atomic32Impl()\n{\n    if(_ptrMemory != NULL)\n    {\n         free(_ptrMemory);\n    }\n}\n\ninline WebRtc_Word32 Atomic32Impl::operator++()\n{\n    return (WebRtc_Word32)InterlockedIncrement(_value);\n}\n\ninline WebRtc_Word32 Atomic32Impl::operator--()\n{\n    return (WebRtc_Word32)InterlockedDecrement(_value);\n}\n\ninline Atomic32Impl& Atomic32Impl::operator=(const Atomic32Impl& rhs)\n{\n    *_value = *rhs._value;\n    return *this;\n}\n\ninline Atomic32Impl& Atomic32Impl::operator=(WebRtc_Word32 rhs)\n{\n    *_value = rhs;\n    return *this;\n}\n\ninline WebRtc_Word32 Atomic32Impl::operator+=(WebRtc_Word32 rhs)\n{\n    return InterlockedExchangeAdd(_value,rhs);\n}\n\ninline WebRtc_Word32 Atomic32Impl::operator-=(WebRtc_Word32 rhs)\n{\n    return InterlockedExchangeAdd(_value,-rhs);\n}\n\ninline bool Atomic32Impl::CompareExchange(WebRtc_Word32 newValue,\n                                          WebRtc_Word32 compareValue)\n{\n    const LONG oldValue = InterlockedCompareExchange(_value,newValue,\n                                                     compareValue);\n    // If the old value and the compare value is the same an exchange happened.\n    return (oldValue == compareValue);\n}\n\ninline WebRtc_Word32 Atomic32Impl::Value() const\n{\n    return *_value;\n}\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_WINDOWS_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/condition_variable.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#if defined(_WIN32)\n   #include <windows.h>\n   #include \"condition_variable_wrapper.h\"\n   #include \"condition_variable_windows.h\"\n#elif defined(WEBRTC_LINUX)\n   #include <pthread.h>\n   #include \"condition_variable_wrapper.h\"\n   #include \"condition_variable_posix.h\"\n#elif defined(WEBRTC_MAC) || defined(WEBRTC_MAC_INTEL)\n   #include <pthread.h>\n   #include \"condition_variable_wrapper.h\"\n   #include \"condition_variable_posix.h\"\n#endif\n\nnamespace webrtc {\nConditionVariableWrapper*\nConditionVariableWrapper::CreateConditionVariable()\n{\n#if defined(_WIN32)\n    return new ConditionVariableWindows;\n#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) || defined(WEBRTC_MAC_INTEL)\n    return ConditionVariablePosix::Create();\n#else\n    return NULL;\n#endif\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/condition_variable_posix.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"condition_variable_posix.h\"\n\n#if defined(WEBRTC_LINUX)\n#include <ctime>\n#else\n#include <sys/time.h>\n#endif\n\n#include <errno.h>\n\n#include \"critical_section_posix.h\"\n\nnamespace webrtc {\nConditionVariableWrapper* ConditionVariablePosix::Create()\n{\n    ConditionVariablePosix* ptr = new ConditionVariablePosix;\n    if (!ptr)\n    {\n        return NULL;\n    }\n\n    const int error = ptr->Construct();\n    if (error)\n    {\n        delete ptr;\n        return NULL;\n    }\n\n    return ptr;\n}\n\nConditionVariablePosix::ConditionVariablePosix()\n{\n}\n\nint ConditionVariablePosix::Construct()\n{\n    int result = 0;\n#ifdef WEBRTC_CLOCK_TYPE_REALTIME\n    result = pthread_cond_init(&_cond, NULL);\n#else\n    pthread_condattr_t condAttr;\n    result = pthread_condattr_init(&condAttr);\n    if (result != 0)\n    {\n        return -1;\n    }\n    result = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC);\n    if (result != 0)\n    {\n        return -1;\n    }\n    result = pthread_cond_init(&_cond, &condAttr);\n    if (result != 0)\n    {\n        return -1;\n    }\n    result = pthread_condattr_destroy(&condAttr);\n    if (result != 0)\n    {\n        return -1;\n    }\n#endif\n    return 0;\n}\n\nConditionVariablePosix::~ConditionVariablePosix()\n{\n    pthread_cond_destroy(&_cond);\n}\n\nvoid ConditionVariablePosix::SleepCS(CriticalSectionWrapper& critSect)\n{\n    CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>(\n                                   &critSect);\n    pthread_cond_wait(&_cond, &cs->_mutex);\n}\n\n\nbool\nConditionVariablePosix::SleepCS(\n    CriticalSectionWrapper& critSect,\n    unsigned long maxTimeInMS)\n{\n    const unsigned long INFINITE =  0xFFFFFFFF;\n\n    const int MILLISECONDS_PER_SECOND      = 1000;\n#ifndef WEBRTC_LINUX\n    const int MICROSECONDS_PER_MILLISECOND = 1000;\n#endif\n    const int NANOSECONDS_PER_SECOND       = 1000000000;\n    const int NANOSECONDS_PER_MILLISECOND  = 1000000;\n\n    CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>(\n                                   &critSect);\n\n    if (maxTimeInMS != INFINITE)\n    {\n        timespec ts;\n#ifndef WEBRTC_MAC\n#ifdef WEBRTC_CLOCK_TYPE_REALTIME\n        clock_gettime(CLOCK_REALTIME, &ts);\n#else\n        clock_gettime(CLOCK_MONOTONIC, &ts);\n#endif\n#else\n        struct timeval tv;\n        gettimeofday(&tv, 0);\n        ts.tv_sec  = tv.tv_sec;\n        ts.tv_nsec = tv.tv_usec * MICROSECONDS_PER_MILLISECOND;\n#endif\n\n        ts.tv_sec += maxTimeInMS / MILLISECONDS_PER_SECOND;\n        ts.tv_nsec += (maxTimeInMS - ((maxTimeInMS / MILLISECONDS_PER_SECOND)*\n                      MILLISECONDS_PER_SECOND)) * NANOSECONDS_PER_MILLISECOND;\n\n        if (ts.tv_nsec >= NANOSECONDS_PER_SECOND)\n        {\n            ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;\n            ts.tv_nsec %= NANOSECONDS_PER_SECOND;\n        }\n        const int res = pthread_cond_timedwait(&_cond, &cs->_mutex, &ts);\n        return (res == ETIMEDOUT) ? false : true;\n    }\n    else\n    {\n        pthread_cond_wait(&_cond, &cs->_mutex);\n        return true;\n    }\n}\n\nvoid ConditionVariablePosix::Wake()\n{\n    pthread_cond_signal(&_cond);\n}\n\nvoid ConditionVariablePosix::WakeAll()\n{\n    pthread_cond_broadcast(&_cond);\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/condition_variable_posix.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_POSIX_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_POSIX_H_\n\n#include \"condition_variable_wrapper.h\"\n\n#include <pthread.h>\n\nnamespace webrtc {\nclass ConditionVariablePosix : public ConditionVariableWrapper\n{\npublic:\n    static ConditionVariableWrapper* Create();\n    ~ConditionVariablePosix();\n\n    void SleepCS(CriticalSectionWrapper& critSect);\n    bool SleepCS(CriticalSectionWrapper& critSect, unsigned long maxTimeInMS);\n    void Wake();\n    void WakeAll();\n\nprivate:\n    ConditionVariablePosix();\n    int Construct();\n\nprivate:\n    pthread_cond_t _cond;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_POSIX_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/condition_variable_windows.cc",
    "content": "/*\n *  Use of this source code is governed by the ACE copyright license which\n *  can be found in the LICENSE file in the third_party_mods/ace directory of\n *  the source tree or at http://www1.cse.wustl.edu/~schmidt/ACE-copying.html.\n */\n/*\n *  This source code contain modifications to the original source code\n *  which can be found here:\n *  http://www.cs.wustl.edu/~schmidt/win32-cv-1.html (section 3.2).\n *  Modifications:\n *  1) Dynamic detection of native support for condition variables.\n *  2) Use of WebRTC defined types and classes. Renaming of some functions.\n *  3) Introduction of a second event for wake all functionality. This prevents\n *     a thread from spinning on the same condition variable, preventing other\n *     threads from waking up.\n */\n\n// TODO (hellner): probably nicer to split up native and generic\n// implementation into two different files\n\n#include \"condition_variable_windows.h\"\n\n#include \"critical_section_windows.h\"\n#include \"trace.h\"\n\nnamespace webrtc {\nbool ConditionVariableWindows::_winSupportConditionVariablesPrimitive = false;\nstatic HMODULE library = NULL;\n\nPInitializeConditionVariable  _PInitializeConditionVariable;\nPSleepConditionVariableCS     _PSleepConditionVariableCS;\nPWakeConditionVariable        _PWakeConditionVariable;\nPWakeAllConditionVariable     _PWakeAllConditionVariable;\n\ntypedef void (WINAPI *PInitializeConditionVariable)(PCONDITION_VARIABLE);\ntypedef BOOL (WINAPI *PSleepConditionVariableCS)(PCONDITION_VARIABLE,\n                                                 PCRITICAL_SECTION, DWORD);\ntypedef void (WINAPI *PWakeConditionVariable)(PCONDITION_VARIABLE);\ntypedef void (WINAPI *PWakeAllConditionVariable)(PCONDITION_VARIABLE);\n\nConditionVariableWindows::ConditionVariableWindows()\n    : _eventID(WAKEALL_0)\n{\n    if (!library)\n    {\n        // Use native implementation if supported (i.e Vista+)\n        library = LoadLibrary(TEXT(\"Kernel32.dll\"));\n        if (library)\n        {\n            WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,\n                         \"Loaded Kernel.dll\");\n\n            _PInitializeConditionVariable =\n                (PInitializeConditionVariable) GetProcAddress(\n                    library,\n                    \"InitializeConditionVariable\");\n            _PSleepConditionVariableCS =\n                (PSleepConditionVariableCS)GetProcAddress(\n                    library,\n                    \"SleepConditionVariableCS\");\n            _PWakeConditionVariable =\n                (PWakeConditionVariable)GetProcAddress(\n                    library,\n                     \"WakeConditionVariable\");\n            _PWakeAllConditionVariable =\n                (PWakeAllConditionVariable)GetProcAddress(\n                    library,\n                    \"WakeAllConditionVariable\");\n\n            if(_PInitializeConditionVariable &&\n               _PSleepConditionVariableCS &&\n               _PWakeConditionVariable &&\n               _PWakeAllConditionVariable)\n            {\n                WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,\n                             \"Loaded native condition variables\");\n                _winSupportConditionVariablesPrimitive = true;\n            }\n        }\n    }\n\n    if (_winSupportConditionVariablesPrimitive)\n    {\n        _PInitializeConditionVariable(&_conditionVariable);\n\n        _events[WAKEALL_0] = NULL;\n        _events[WAKEALL_1] = NULL;\n        _events[WAKE] = NULL;\n\n    } else {\n        memset(&_numWaiters[0],0,sizeof(_numWaiters));\n\n        InitializeCriticalSection(&_numWaitersCritSect);\n\n        _events[WAKEALL_0] = CreateEvent(NULL,  // no security attributes\n                                         TRUE,  // manual-reset, sticky event\n                                         FALSE, // initial state non-signaled\n                                         NULL); // no name for event\n\n        _events[WAKEALL_1] = CreateEvent(NULL,  // no security attributes\n                                         TRUE,  // manual-reset, sticky event\n                                         FALSE, // initial state non-signaled\n                                         NULL); // no name for event\n\n        _events[WAKE] = CreateEvent(NULL,  // no security attributes\n                                    FALSE, // auto-reset, sticky event\n                                    FALSE, // initial state non-signaled\n                                    NULL); // no name for event\n    }\n}\n\nConditionVariableWindows::~ConditionVariableWindows()\n{\n    if(!_winSupportConditionVariablesPrimitive)\n    {\n        CloseHandle(_events[WAKE]);\n        CloseHandle(_events[WAKEALL_1]);\n        CloseHandle(_events[WAKEALL_0]);\n\n        DeleteCriticalSection(&_numWaitersCritSect);\n    }\n}\n\nvoid ConditionVariableWindows::SleepCS(CriticalSectionWrapper& critSect)\n{\n    SleepCS(critSect, INFINITE);\n}\n\nbool ConditionVariableWindows::SleepCS(CriticalSectionWrapper& critSect,\n                                       unsigned long maxTimeInMS)\n{\n    CriticalSectionWindows* cs = reinterpret_cast<CriticalSectionWindows*>(\n                                     &critSect);\n\n    if(_winSupportConditionVariablesPrimitive)\n    {\n        BOOL retVal = _PSleepConditionVariableCS(&_conditionVariable,\n                                                 &(cs->crit),maxTimeInMS);\n        return (retVal == 0) ? false : true;\n\n    }else\n    {\n        EnterCriticalSection(&_numWaitersCritSect);\n        // Get the eventID for the event that will be triggered by next\n        // WakeAll() call and start waiting for it.\n        const EventWakeUpType eventID = (WAKEALL_0 == _eventID) ?\n                                            WAKEALL_1 : WAKEALL_0;\n        ++(_numWaiters[eventID]);\n        LeaveCriticalSection(&_numWaitersCritSect);\n\n        LeaveCriticalSection(&cs->crit);\n        HANDLE events[2];\n        events[0] = _events[WAKE];\n        events[1] = _events[eventID];\n        const DWORD result = WaitForMultipleObjects(2, // Wait on 2 events.\n                                                    events,\n                                                    FALSE, // Wait for either.\n                                                    maxTimeInMS);\n\n        const bool retVal = (result != WAIT_TIMEOUT);\n\n        EnterCriticalSection(&_numWaitersCritSect);\n        --(_numWaiters[eventID]);\n        // Last waiter should only be true for WakeAll(). WakeAll() correspond\n        // to position 1 in events[] -> (result == WAIT_OBJECT_0 + 1)\n        const bool lastWaiter = (result == WAIT_OBJECT_0 + 1) &&\n                                (_numWaiters[eventID] == 0);\n        LeaveCriticalSection(&_numWaitersCritSect);\n\n        if (lastWaiter)\n        {\n            // Reset/unset the WakeAll() event since all threads have been\n            // released.\n            ResetEvent(_events[eventID]);\n        }\n\n        EnterCriticalSection(&cs->crit);\n        return retVal;\n    }\n}\n\nvoid\nConditionVariableWindows::Wake()\n{\n    if(_winSupportConditionVariablesPrimitive)\n    {\n        _PWakeConditionVariable(&_conditionVariable);\n    }else\n    {\n        EnterCriticalSection(&_numWaitersCritSect);\n        const bool haveWaiters = (_numWaiters[WAKEALL_0] > 0) ||\n                                 (_numWaiters[WAKEALL_1] > 0);\n        LeaveCriticalSection(&_numWaitersCritSect);\n\n        if (haveWaiters)\n        {\n            SetEvent(_events[WAKE]);\n        }\n    }\n}\n\nvoid\nConditionVariableWindows::WakeAll()\n{\n    if(_winSupportConditionVariablesPrimitive)\n    {\n        _PWakeAllConditionVariable(&_conditionVariable);\n    }else\n    {\n        EnterCriticalSection(&_numWaitersCritSect);\n        // Update current WakeAll() event\n        _eventID = (WAKEALL_0 == _eventID) ? WAKEALL_1 : WAKEALL_0;\n        // Trigger current event\n        const EventWakeUpType eventID = _eventID;\n        const bool haveWaiters = _numWaiters[eventID] > 0;\n        LeaveCriticalSection(&_numWaitersCritSect);\n\n        if (haveWaiters)\n        {\n            SetEvent(_events[eventID]);\n        }\n    }\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/condition_variable_windows.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WINDOWS_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WINDOWS_H_\n\n#include \"condition_variable_wrapper.h\"\n\n#include <windows.h>\n\nnamespace webrtc {\n#if !defined CONDITION_VARIABLE_INIT\n    typedef struct _RTL_CONDITION_VARIABLE\n    {\n        void* Ptr;\n    } RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE;\n\n    typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE;\n#endif\n\ntypedef void (WINAPI *PInitializeConditionVariable)(PCONDITION_VARIABLE);\ntypedef BOOL (WINAPI *PSleepConditionVariableCS)(PCONDITION_VARIABLE,\n                                                 PCRITICAL_SECTION, DWORD);\ntypedef void (WINAPI *PWakeConditionVariable)(PCONDITION_VARIABLE);\ntypedef void (WINAPI *PWakeAllConditionVariable)(PCONDITION_VARIABLE);\n\n\nclass ConditionVariableWindows : public ConditionVariableWrapper\n{\npublic:\n    ConditionVariableWindows();\n    ~ConditionVariableWindows();\n\n    void SleepCS(CriticalSectionWrapper& critSect);\n    bool SleepCS(CriticalSectionWrapper& critSect, unsigned long maxTimeInMS);\n    void Wake();\n    void WakeAll();\n\nprivate:\n    enum EventWakeUpType\n    {\n        WAKEALL_0   = 0,\n        WAKEALL_1   = 1,\n        WAKE        = 2,\n        EVENT_COUNT = 3\n    };\n\nprivate:\n    // Native support for Windows Vista+\n    static bool              _winSupportConditionVariablesPrimitive;\n    CONDITION_VARIABLE       _conditionVariable;\n\n    unsigned int     _numWaiters[2];\n    EventWakeUpType  _eventID;\n    CRITICAL_SECTION _numWaitersCritSect;\n    HANDLE           _events[EVENT_COUNT];\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WINDOWS_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/cpu.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"cpu_wrapper.h\"\n\n#if defined(_WIN32)\n    #include <Windows.h>\n    #include \"engine_configurations.h\"\n    #include \"cpu_windows.h\"\n#elif defined(WEBRTC_MAC)\n    #include <sys/types.h>\n    #include <sys/sysctl.h>\n    #include \"cpu_mac.h\"\n#elif defined(WEBRTC_MAC_INTEL)\n    #include \"cpu_mac.h\"\n#elif defined(WEBRTC_ANDROID)\n    // Not implemented yet, might be possible to use Linux implementation\n#else // defined(WEBRTC_LINUX)\n    #include <sys/sysinfo.h>\n    #include \"cpu_linux.h\"\n#endif\n\n#include \"trace.h\"\n\nnamespace webrtc {\nWebRtc_UWord32 CpuWrapper::_numberOfCores = 0;\n\nWebRtc_UWord32 CpuWrapper::DetectNumberOfCores()\n{\n    if (!_numberOfCores)\n    {\n#if defined(_WIN32)\n        SYSTEM_INFO si;\n        GetSystemInfo(&si);\n        _numberOfCores = static_cast<WebRtc_UWord32>(si.dwNumberOfProcessors);\n        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,\n                     \"Available number of cores:%d\", _numberOfCores);\n\n#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)\n        _numberOfCores = get_nprocs();\n        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,\n                     \"Available number of cores:%d\", _numberOfCores);\n\n#elif (defined(WEBRTC_MAC) || defined(WEBRTC_MAC_INTEL))\n        int name[] = {CTL_HW, HW_AVAILCPU};\n        int ncpu;\n        size_t size = sizeof(ncpu);\n        if(0 == sysctl(name, 2, &ncpu, &size, NULL, 0))\n        {\n            _numberOfCores = static_cast<WebRtc_UWord32>(ncpu);\n            WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,\n                         \"Available number of cores:%d\", _numberOfCores);\n    } else\n    {\n            WEBRTC_TRACE(kTraceError, kTraceUtility, -1,\n                         \"Failed to get number of cores\");\n            _numberOfCores = 1;\n    }\n#else\n        WEBRTC_TRACE(kTraceWarning, kTraceUtility, -1,\n                     \"No function to get number of cores\");\n        _numberOfCores = 1;\n#endif\n    }\n    return _numberOfCores;\n}\n\nCpuWrapper* CpuWrapper::CreateCpu()\n{\n#if defined(_WIN32)\n   return new CpuWindows();\n#elif (defined(WEBRTC_MAC) || defined(WEBRTC_MAC_INTEL))\n    return new CpuWrapperMac();\n#elif defined(WEBRTC_ANDROID)\n    return 0;\n#else\n    return new CpuLinux();\n#endif\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/cpu_features.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n// Parts of this file derived from Chromium's base/cpu.cc.\n\n#include \"cpu_features_wrapper.h\"\n\n#include \"typedefs.h\"\n\n#if defined(WEBRTC_ARCH_X86_FAMILY)\n#if defined(_MSC_VER)\n#include <intrin.h>\n#endif\n#endif\n\n// No CPU feature is available => straight C path.\nint GetCPUInfoNoASM(CPUFeature feature) {\n  (void)feature;\n  return 0;\n}\n\n#if defined(WEBRTC_ARCH_X86_FAMILY)\n#ifndef _MSC_VER\n// Intrinsic for \"cpuid\".\n#if defined(__pic__) && defined(__i386__)\nstatic inline void __cpuid(int cpu_info[4], int info_type) {\n  __asm__ volatile (\n    \"mov %%ebx, %%edi\\n\"\n    \"cpuid\\n\"\n    \"xchg %%edi, %%ebx\\n\"\n    : \"=a\"(cpu_info[0]), \"=D\"(cpu_info[1]), \"=c\"(cpu_info[2]), \"=d\"(cpu_info[3])\n    : \"a\"(info_type));\n}\n#else\nstatic inline void __cpuid(int cpu_info[4], int info_type) {\n  __asm__ volatile (\n    \"cpuid\\n\"\n    : \"=a\"(cpu_info[0]), \"=b\"(cpu_info[1]), \"=c\"(cpu_info[2]), \"=d\"(cpu_info[3])\n    : \"a\"(info_type));\n}\n#endif\n#endif  // _MSC_VER\n#endif  // WEBRTC_ARCH_X86_FAMILY\n\n#if defined(WEBRTC_ARCH_X86_FAMILY)\n// Actual feature detection for x86.\nstatic int GetCPUInfo(CPUFeature feature) {\n  int cpu_info[4];\n  __cpuid(cpu_info, 1);\n  if (feature == kSSE2) {\n    return 0 != (cpu_info[3] & 0x04000000);\n  }\n  if (feature == kSSE3) {\n    return 0 != (cpu_info[2] & 0x00000001);\n  }\n  return 0;\n}\n#else\n// Default to straight C for other platforms.\nstatic int GetCPUInfo(CPUFeature feature) {\n  (void)feature;\n  return 0;\n}\n#endif\n\nWebRtc_CPUInfo WebRtc_GetCPUInfo = GetCPUInfo;\nWebRtc_CPUInfo WebRtc_GetCPUInfoNoASM = GetCPUInfoNoASM;\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/cpu_linux.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"cpu_linux.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\nnamespace webrtc {\nCpuLinux::CpuLinux()\n    : m_oldBusyTime(0),\n      m_oldIdleTime(0),\n      m_oldBusyTimeMulti(NULL),\n      m_oldIdleTimeMulti(NULL),\n      m_idleArray(NULL),\n      m_busyArray(NULL),\n      m_resultArray(NULL),\n      m_numCores(0) {\n    const int result = GetNumCores();\n    if (result != -1) {\n      m_numCores = result;\n      m_oldBusyTimeMulti = new long long[m_numCores];\n      memset(m_oldBusyTimeMulti, 0, sizeof(long long) * m_numCores);\n      m_oldIdleTimeMulti = new long long[m_numCores];\n      memset(m_oldIdleTimeMulti, 0, sizeof(long long) * m_numCores);\n      m_idleArray = new long long[m_numCores];\n      memset(m_idleArray, 0, sizeof(long long) * m_numCores);\n      m_busyArray = new long long[m_numCores];\n      memset(m_busyArray, 0, sizeof(long long) * m_numCores);\n      m_resultArray = new WebRtc_UWord32[m_numCores];\n\n      GetData(m_oldBusyTime, m_oldIdleTime, m_busyArray, m_idleArray);\n    }\n}\n\nCpuLinux::~CpuLinux()\n{\n    delete [] m_oldBusyTimeMulti;\n    delete [] m_oldIdleTimeMulti;\n    delete [] m_idleArray;\n    delete [] m_busyArray;\n    delete [] m_resultArray;\n}\n\nWebRtc_Word32 CpuLinux::CpuUsage()\n{\n    WebRtc_UWord32 dummy = 0;\n    WebRtc_UWord32* dummyArray = NULL;\n    return CpuUsageMultiCore(dummy, dummyArray);\n}\n\nWebRtc_Word32 CpuLinux::CpuUsageMultiCore(WebRtc_UWord32& numCores,\n                                          WebRtc_UWord32*& coreArray)\n{\n    coreArray = m_resultArray;\n    numCores = m_numCores;\n    long long busy = 0;\n    long long idle = 0;\n    if (GetData(busy, idle, m_busyArray, m_idleArray) != 0)\n        return -1;\n\n    long long deltaBusy = busy - m_oldBusyTime;\n    long long deltaIdle = idle - m_oldIdleTime;\n    m_oldBusyTime = busy;\n    m_oldIdleTime = idle;\n\n    int retVal = -1;\n    if (deltaBusy + deltaIdle == 0)\n    {\n        retVal = 0;\n    }\n    else\n    {\n        retVal = (int)(100 * (deltaBusy) / (deltaBusy + deltaIdle));\n    }\n\n    if (coreArray == NULL)\n    {\n      return retVal;\n    }\n\n    for (WebRtc_UWord32 i = 0; i < m_numCores; i++)\n    {\n        deltaBusy = m_busyArray[i] - m_oldBusyTimeMulti[i];\n        deltaIdle = m_idleArray[i] - m_oldIdleTimeMulti[i];\n        m_oldBusyTimeMulti[i] = m_busyArray[i];\n        m_oldIdleTimeMulti[i] = m_idleArray[i];\n        if(deltaBusy + deltaIdle == 0)\n        {\n            coreArray[i] = 0;\n        }\n        else\n        {\n            coreArray[i] = (int)(100 * (deltaBusy) / (deltaBusy+deltaIdle));\n        }\n    }\n    return retVal;\n}\n\n\nint CpuLinux::GetData(long long& busy, long long& idle, long long*& busyArray,\n                      long long*& idleArray)\n{\n    FILE* fp = fopen(\"/proc/stat\", \"r\");\n    if (!fp)\n    {\n        return -1;\n    }\n\n    char line[100];\n    if (fgets(line, 100, fp) == NULL) {\n        fclose(fp);\n        return -1;\n    }\n    char firstWord[100];\n    if (sscanf(line, \"%s \", firstWord) != 1) {\n        fclose(fp);\n        return -1;\n    }\n    if (strncmp(firstWord, \"cpu\", 3) != 0) {\n        fclose(fp);\n        return -1;\n    }\n    char sUser[100];\n    char sNice[100];\n    char sSystem[100];\n    char sIdle[100];\n    if (sscanf(line, \"%s %s %s %s %s \",\n               firstWord, sUser, sNice, sSystem, sIdle) != 5) {\n        fclose(fp);\n        return -1;\n    }\n    long long luser = atoll(sUser);\n    long long lnice = atoll(sNice);\n    long long lsystem = atoll(sSystem);\n    long long lidle = atoll (sIdle);\n\n    busy = luser + lnice + lsystem;\n    idle = lidle;\n    for (WebRtc_UWord32 i = 0; i < m_numCores; i++)\n    {\n        if (fgets(line, 100, fp) == NULL) {\n            fclose(fp);\n            return -1;\n        }\n        if (sscanf(line, \"%s %s %s %s %s \", firstWord, sUser, sNice, sSystem,\n                   sIdle) != 5) {\n            fclose(fp);\n            return -1;\n        }\n        luser = atoll(sUser);\n        lnice = atoll(sNice);\n        lsystem = atoll(sSystem);\n        lidle = atoll (sIdle);\n        busyArray[i] = luser + lnice + lsystem;\n        idleArray[i] = lidle;\n    }\n    fclose(fp);\n    return 0;\n}\n\nint CpuLinux::GetNumCores()\n{\n    FILE* fp = fopen(\"/proc/stat\", \"r\");\n    if (!fp)\n    {\n        return -1;\n    }\n    // Skip first line\n    char line[100];\n    if (!fgets(line, 100, fp))\n    {\n        return -1;\n    }\n    int numCores = -1;\n    char firstWord[100];\n    do\n    {\n        numCores++;\n        if (fgets(line, 100, fp))\n        {\n            if (sscanf(line, \"%s \", firstWord) != 1) {\n                firstWord[0] = '\\0';\n            }\n        } else {\n            break;\n        }\n    } while (strncmp(firstWord, \"cpu\", 3) == 0);\n    fclose(fp);\n    return numCores;\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/cpu_linux.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_LINUX_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_LINUX_H_\n\n#include \"cpu_wrapper.h\"\n\nnamespace webrtc {\nclass CpuLinux : public CpuWrapper\n{\npublic:\n    CpuLinux();\n    virtual ~CpuLinux();\n\n    virtual WebRtc_Word32 CpuUsage();\n    virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* /*pProcessName*/,\n                                   WebRtc_UWord32 /*length*/) {return 0;}\n    virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 /*dwProcessID*/) {return 0;}\n\n    virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& numCores,\n                                            WebRtc_UWord32*& array);\n\n    virtual void Reset() {return;}\n    virtual void Stop() {return;}\nprivate:\n    int GetData(long long& busy, long long& idle, long long*& busyArray,\n                long long*& idleArray);\n    int GetNumCores();\n\n    long long m_oldBusyTime;\n    long long m_oldIdleTime;\n\n    long long* m_oldBusyTimeMulti;\n    long long* m_oldIdleTimeMulti;\n\n    long long* m_idleArray;\n    long long* m_busyArray;\n    WebRtc_UWord32* m_resultArray;\n    WebRtc_UWord32  m_numCores;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_LINUX_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/cpu_mac.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"cpu_mac.h\"\n\n#include <iostream>\n#include <mach/mach.h>\n#include <mach/mach_error.h>\n\n#include \"tick_util.h\"\n\nnamespace webrtc {\nCpuWrapperMac::CpuWrapperMac() : _cpuUsage(NULL)\n{\n    natural_t cpuCount;\n    processor_info_array_t infoArray;\n    mach_msg_type_number_t infoCount;\n\n    kern_return_t error = host_processor_info(mach_host_self(),\n                                              PROCESSOR_CPU_LOAD_INFO,\n                                              &cpuCount,\n                                              &infoArray,\n                                              &infoCount);\n    if (error)\n    {\n        return;\n    }\n\n    _cpuUsage = new WebRtc_UWord32[cpuCount];\n    _lastTickCount = new WebRtc_Word64[cpuCount];\n    _lastTime = TickTime::MillisecondTimestamp();\n\n    processor_cpu_load_info_data_t* cpuLoadInfo =\n        (processor_cpu_load_info_data_t*) infoArray;\n    for (unsigned int cpu= 0; cpu < cpuCount; cpu++)\n    {\n        WebRtc_Word64 ticks = 0;\n        for (int state = 0; state < 2; state++)\n        {\n            ticks += cpuLoadInfo[cpu].cpu_ticks[state];\n        }\n        _lastTickCount[cpu] = ticks;\n    }\n    vm_deallocate(mach_task_self(), (vm_address_t)infoArray, infoCount);\n}\n\nCpuWrapperMac::~CpuWrapperMac()\n{\n    delete _cpuUsage;\n    delete _lastTickCount;\n}\n\nWebRtc_Word32 CpuWrapperMac::CpuUsage()\n{\n    WebRtc_UWord32 numCores;\n    WebRtc_UWord32* array = NULL;\n    return CpuUsageMultiCore(numCores, array);\n}\n\nWebRtc_Word32\nCpuWrapperMac::CpuUsageMultiCore(WebRtc_UWord32& numCores,\n                                 WebRtc_UWord32*& array)\n{\n    natural_t cpuCount;\n    processor_info_array_t infoArray;\n    mach_msg_type_number_t infoCount;\n\n    // sanity check\n    if(_cpuUsage == NULL)\n    {\n        return -1;\n    }\n    WebRtc_Word64 now = TickTime::MillisecondTimestamp();\n    WebRtc_Word64 timeDiffMS = now - _lastTime;\n    // TODO(hellner) why block here? Why not just return the old\n    //                          value? Is this behavior consistent across all\n    //                          platforms?\n    // Make sure that at least 500 ms pass between calls.\n    if(timeDiffMS < 500)\n    {\n        usleep((500-timeDiffMS)*1000);\n        return CpuUsageMultiCore(numCores, array);\n    }\n    _lastTime = now;\n\n     kern_return_t error = host_processor_info(mach_host_self(),\n                                              PROCESSOR_CPU_LOAD_INFO,\n                                              &cpuCount,\n                                              &infoArray,\n                                              &infoCount);\n    if (error)\n    {\n        return -1;\n    }\n\n    processor_cpu_load_info_data_t* cpuLoadInfo =\n        (processor_cpu_load_info_data_t*) infoArray;\n\n    WebRtc_Word32 totalCpuUsage = 0;\n    for (unsigned int cpu = 0; cpu < cpuCount; cpu++)\n    {\n        WebRtc_Word64 ticks = 0;\n        for (int state = 0; state < 2; state++)\n        {\n            ticks += cpuLoadInfo[cpu].cpu_ticks[state];\n        }\n        if(timeDiffMS <= 0)\n        {\n            _cpuUsage[cpu] = 0;\n        }else {\n            _cpuUsage[cpu] = (WebRtc_UWord32)((1000 *\n                                              (ticks - _lastTickCount[cpu])) /\n                                              timeDiffMS);\n        }\n        _lastTickCount[cpu] = ticks;\n        totalCpuUsage += _cpuUsage[cpu];\n    }\n\n    vm_deallocate(mach_task_self(), (vm_address_t)infoArray, infoCount);\n\n    numCores = cpuCount;\n    array = _cpuUsage;\n    return totalCpuUsage/cpuCount;\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/cpu_mac.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_MAC_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_MAC_H_\n\n#include \"cpu_wrapper.h\"\n\nnamespace webrtc {\nclass CpuWrapperMac : public CpuWrapper\n{\npublic:\n    CpuWrapperMac();\n    virtual ~CpuWrapperMac();\n\n    virtual WebRtc_Word32 CpuUsage();\n    virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* /*pProcessName*/,\n                                   WebRtc_UWord32 /*length*/) {return -1;}\n    virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32  /*dwProcessID*/) {return -1;}\n\n    // Note: this class will block the call and sleep if called too fast\n    // This function blocks the calling thread if the thread is calling it more\n    // often than every 500 ms.\n    virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& numCores,\n                                            WebRtc_UWord32*& array);\n\n    virtual void Reset() {}\n    virtual void Stop() {}\n\nprivate:\n    WebRtc_UWord32* _cpuUsage;\n    WebRtc_Word64*  _lastTickCount;\n    WebRtc_Word64   _lastTime;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_MAC_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/cpu_windows.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"cpu_windows.h\"\n\n#define _WIN32_DCOM\n\n#include <assert.h>\n#include <iostream>\n#include <Wbemidl.h>\n\n#pragma comment(lib, \"wbemuuid.lib\")\n\n#include \"condition_variable_wrapper.h\"\n#include \"critical_section_wrapper.h\"\n#include \"event_wrapper.h\"\n#include \"thread_wrapper.h\"\n\nnamespace webrtc {\nWebRtc_Word32 CpuWindows::CpuUsage()\n{\n    if (!has_initialized_)\n    {\n        return -1;\n    }\n    // Last element is the average\n    return cpu_usage_[number_of_objects_ - 1];\n}\n\nWebRtc_Word32 CpuWindows::CpuUsageMultiCore(WebRtc_UWord32& num_cores,\n                                                  WebRtc_UWord32*& cpu_usage)\n{\n    if (!has_initialized_)\n    {\n        return -1;\n    }\n    num_cores = number_of_objects_ - 1;\n    cpu_usage = cpu_usage_;\n    return cpu_usage_[number_of_objects_-1];\n}\n\nCpuWindows::CpuWindows()\n    : cpu_polling_thread(NULL),\n      initialize_(true),\n      has_initialized_(false),\n      terminate_(false),\n      has_terminated_(false),\n      cpu_usage_(NULL),\n      wbem_enum_access_(NULL),\n      number_of_objects_(0),\n      cpu_usage_handle_(0),\n      previous_processor_timestamp_(NULL),\n      timestamp_sys_100_ns_handle_(0),\n      previous_100ns_timestamp_(NULL),\n      wbem_service_(NULL),\n      wbem_service_proxy_(NULL),\n      wbem_refresher_(NULL),\n      wbem_enum_(NULL)\n{\n    // All resources are allocated in PollingCpu().\n    if (AllocateComplexDataTypes())\n    {\n        const bool success = StartPollingCpu();\n        assert(success);\n    }\n    else\n    {\n        assert(false);\n    }\n}\n\nCpuWindows::~CpuWindows()\n{\n    // All resources are reclaimed in StopPollingCpu().\n    const bool success = StopPollingCpu();\n    assert(success);\n    DeAllocateComplexDataTypes();\n}\n\nbool CpuWindows::AllocateComplexDataTypes()\n{\n    cpu_polling_thread = ThreadWrapper::CreateThread(\n        CpuWindows::Process,\n        reinterpret_cast<void*>(this),\n        kNormalPriority,\n        \"CpuWindows\");\n    init_crit_ = CriticalSectionWrapper::CreateCriticalSection();\n    init_cond_ = ConditionVariableWrapper::CreateConditionVariable();\n    terminate_crit_ = CriticalSectionWrapper::CreateCriticalSection();\n    terminate_cond_ = ConditionVariableWrapper::CreateConditionVariable();\n    sleep_event = EventWrapper::Create();\n    return (cpu_polling_thread != NULL) && (init_crit_ != NULL) &&\n           (init_cond_ != NULL) && (terminate_crit_ != NULL) &&\n           (terminate_cond_ != NULL) && (sleep_event != NULL);\n}\n\nvoid CpuWindows::DeAllocateComplexDataTypes()\n{\n    if (sleep_event != NULL)\n    {\n        delete sleep_event;\n        sleep_event = NULL;\n    }\n    if (terminate_cond_ != NULL)\n    {\n        delete terminate_cond_;\n        terminate_cond_ = NULL;\n    }\n    if (terminate_crit_ != NULL)\n    {\n        delete terminate_crit_;\n        terminate_crit_ = NULL;\n    }\n    if (init_cond_ != NULL)\n    {\n        delete init_cond_;\n        init_cond_ = NULL;\n    }\n    if (init_crit_ != NULL)\n    {\n        delete init_crit_;\n        init_crit_ = NULL;\n    }\n    if (cpu_polling_thread != NULL)\n    {\n        delete cpu_polling_thread;\n        cpu_polling_thread = NULL;\n    }\n}\n\nbool CpuWindows::StartPollingCpu()\n{\n    unsigned int dummy_id = 0;\n    if (!cpu_polling_thread->Start(dummy_id))\n    {\n        return false;\n    }\n    {\n        CriticalSectionScoped cs(*init_crit_);\n        while(initialize_)\n        {\n            init_cond_->SleepCS(*init_crit_);\n        }\n    }\n    if (!has_initialized_)\n    {\n        cpu_polling_thread->Stop();\n        return false;\n    }\n    return has_initialized_;\n}\n\nbool CpuWindows::StopPollingCpu()\n{\n    if (!has_initialized_)\n    {\n        return false;\n    }\n    CriticalSectionScoped cs(*terminate_crit_);\n    terminate_ = true;\n    sleep_event->Set();\n    while (!has_terminated_)\n    {\n        terminate_cond_->SleepCS(*terminate_crit_);\n    }\n    cpu_polling_thread->Stop();\n    delete cpu_polling_thread;\n    cpu_polling_thread = NULL;\n    return true;\n}\n\nbool CpuWindows::Process(void* thread_object)\n{\n    return reinterpret_cast<CpuWindows*>(thread_object)->ProcessImpl();\n}\n\nbool CpuWindows::ProcessImpl()\n{\n    {\n        CriticalSectionScoped cs(*terminate_crit_);\n        if (terminate_)\n        {\n            const bool success = Terminate();\n            assert(success);\n            terminate_cond_->WakeAll();\n            return false;\n        }\n    }\n    // Initialize on first iteration\n    if (initialize_)\n    {\n        CriticalSectionScoped cs(*init_crit_);\n        initialize_ = false;\n        const bool success = Initialize();\n        init_cond_->WakeAll();\n        if (!success || !has_initialized_)\n        {\n            has_initialized_ = false;\n            terminate_ = true;\n            return false;\n        }\n    }\n    // Approximately one seconds sleep for each CPU measurement. Precision is\n    // not important. 1 second refresh rate is also used by Performance Monitor\n    // (perfmon).\n    if(kEventTimeout != sleep_event->Wait(1000))\n    {\n        // Terminating. No need to update CPU usage.\n        assert(terminate_);\n        return true;\n    }\n\n    // UpdateCpuUsage() returns false if a single (or more) CPU read(s) failed.\n    // Not a major problem if it happens but make sure it doesnt trigger in\n    // debug.\n    const bool success = UpdateCpuUsage();\n    assert(success);\n    return true;\n}\n\nbool CpuWindows::CreateWmiConnection()\n{\n    IWbemLocator* service_locator = NULL;\n    HRESULT hr = CoCreateInstance(CLSID_WbemLocator, NULL,\n                                  CLSCTX_INPROC_SERVER, IID_IWbemLocator,\n                                  reinterpret_cast<void**> (&service_locator));\n    if (FAILED(hr))\n    {\n        return false;\n    }\n    // To get the WMI service specify the WMI namespace.\n    BSTR wmi_namespace = SysAllocString(L\"\\\\\\\\.\\\\root\\\\cimv2\");\n    if (wmi_namespace == NULL)\n    {\n        // This type of failure signifies running out of memory.\n        service_locator->Release();\n        return false;\n    }\n    hr = service_locator->ConnectServer(wmi_namespace, NULL, NULL, NULL, 0L,\n                                        NULL, NULL, &wbem_service_);\n    SysFreeString(wmi_namespace);\n    service_locator->Release();\n    return !FAILED(hr);\n}\n\n// Sets up WMI refresher and enum\nbool CpuWindows::CreatePerfOsRefresher()\n{\n    // Create refresher.\n    HRESULT hr = CoCreateInstance(CLSID_WbemRefresher, NULL,\n                                  CLSCTX_INPROC_SERVER, IID_IWbemRefresher,\n                                  reinterpret_cast<void**> (&wbem_refresher_));\n    if (FAILED(hr))\n    {\n        return false;\n    }\n    // Create PerfOS_Processor enum.\n    IWbemConfigureRefresher* wbem_refresher_config = NULL;\n    hr = wbem_refresher_->QueryInterface(\n        IID_IWbemConfigureRefresher,\n        reinterpret_cast<void**> (&wbem_refresher_config));\n    if (FAILED(hr))\n    {\n        return false;\n    }\n\n    // Create a proxy to the IWbemServices so that a local authentication\n    // can be set up (this is needed to be able to successfully call \n    // IWbemConfigureRefresher::AddEnum). Setting authentication with\n    // CoInitializeSecurity is process-wide (which is too intrusive).\n    hr = CoCopyProxy(static_cast<IUnknown*> (wbem_service_),\n                     reinterpret_cast<IUnknown**> (&wbem_service_proxy_));\n    if(FAILED(hr))\n    {\n        return false;\n    }\n    // Set local authentication.\n    // RPC_C_AUTHN_WINNT means using NTLM instead of Kerberos which is default.\n    hr = CoSetProxyBlanket(static_cast<IUnknown*> (wbem_service_proxy_),\n                           RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,\n                           RPC_C_AUTHN_LEVEL_DEFAULT,\n                           RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);\n    if(FAILED(hr))\n    {\n        return false;\n    }\n\n    // Don't care about the particular id for the enum.\n    long enum_id = 0;\n    hr = wbem_refresher_config->AddEnum(wbem_service_proxy_,\n                                        L\"Win32_PerfRawData_PerfOS_Processor\",\n                                        0, NULL, &wbem_enum_, &enum_id);\n    wbem_refresher_config->Release();\n    wbem_refresher_config = NULL;\n    return !FAILED(hr);\n}\n\n// Have to pull the first round of data to be able set the handles.\nbool CpuWindows::CreatePerfOsCpuHandles()\n{\n    // Update the refresher so that there is data available in wbem_enum_.\n    wbem_refresher_->Refresh(0L);\n\n    // The number of enumerators is the number of processor + 1 (the total).\n    // This is unknown at this point.\n    DWORD number_returned = 0;\n    HRESULT hr = wbem_enum_->GetObjects(0L, number_of_objects_,\n                                        wbem_enum_access_, &number_returned);\n    // number_returned indicates the number of enumerators that are needed.\n    if (hr == WBEM_E_BUFFER_TOO_SMALL &&\n        number_returned > number_of_objects_)\n    {\n        // Allocate the number IWbemObjectAccess asked for by the\n        // GetObjects(..) function.\n        wbem_enum_access_ = new IWbemObjectAccess*[number_returned];\n        cpu_usage_ = new WebRtc_UWord32[number_returned];\n        previous_processor_timestamp_ = new unsigned __int64[number_returned];\n        previous_100ns_timestamp_ = new unsigned __int64[number_returned];\n        if ((wbem_enum_access_ == NULL) || (cpu_usage_ == NULL) ||\n            (previous_processor_timestamp_ == NULL) ||\n            (previous_100ns_timestamp_ == NULL))\n        {\n            // Out of memory.\n            return false;\n        }\n\n        SecureZeroMemory(wbem_enum_access_, number_returned *\n                         sizeof(IWbemObjectAccess*));\n        memset(cpu_usage_, 0, sizeof(int) * number_returned);\n        memset(previous_processor_timestamp_, 0, sizeof(unsigned __int64) *\n               number_returned);\n        memset(previous_100ns_timestamp_, 0, sizeof(unsigned __int64) *\n               number_returned);\n\n        number_of_objects_ = number_returned;\n        // Read should be successfull now that memory has been allocated.\n        hr = wbem_enum_->GetObjects(0L, number_of_objects_, wbem_enum_access_,\n                                    &number_returned);\n        if (FAILED(hr))\n        {\n            return false;\n        }\n    }\n    else\n    {\n        // 0 enumerators should not be enough. Something has gone wrong here.\n        return false;\n    }\n\n    // Get the enumerator handles that are needed for calculating CPU usage.\n    CIMTYPE cpu_usage_type;\n    hr = wbem_enum_access_[0]->GetPropertyHandle(L\"PercentProcessorTime\",\n                                                 &cpu_usage_type,\n                                                 &cpu_usage_handle_);\n    if (FAILED(hr))\n    {\n        return false;\n    }\n    CIMTYPE timestamp_sys_100_ns_type;\n    hr = wbem_enum_access_[0]->GetPropertyHandle(L\"TimeStamp_Sys100NS\",\n                                                 &timestamp_sys_100_ns_type,\n                                                 &timestamp_sys_100_ns_handle_);\n    return !FAILED(hr);\n}\n\nbool CpuWindows::Initialize()\n{\n    if (terminate_)\n    {\n        return false;\n    }\n    // Initialize COM library.\n    HRESULT hr = CoInitializeEx(NULL,COINIT_MULTITHREADED);\n    if (FAILED(hr))\n    {\n        return false;\n    }\n    if (FAILED(hr))\n    {\n        return false;\n    }\n\n    if (!CreateWmiConnection())\n    {\n        return false;\n    }\n    if (!CreatePerfOsRefresher())\n    {\n        return false;\n    }\n    if (!CreatePerfOsCpuHandles())\n    {\n        return false;\n    }\n    has_initialized_ = true;\n    return true;\n}\n\nbool CpuWindows::Terminate()\n{\n    if (has_terminated_)\n    {\n        return false;\n    }\n    // Reverse order of Initialize().\n    // Some compilers complain about deleting NULL though it's well defined\n    if (previous_100ns_timestamp_ != NULL)\n    {\n        delete[] previous_100ns_timestamp_;\n        previous_100ns_timestamp_ = NULL;\n    }\n    if (previous_processor_timestamp_ != NULL)\n    {\n        delete[] previous_processor_timestamp_;\n        previous_processor_timestamp_ = NULL;\n    }\n    if (cpu_usage_ != NULL)\n    {\n        delete[] cpu_usage_;\n        cpu_usage_ = NULL;\n    }\n    if (wbem_enum_access_ != NULL)\n    {\n        for (DWORD i = 0; i < number_of_objects_; i++)\n        {\n            if(wbem_enum_access_[i] != NULL)\n            {\n                wbem_enum_access_[i]->Release();\n            }\n        }\n        delete[] wbem_enum_access_;\n        wbem_enum_access_ = NULL;\n    }\n    if (wbem_enum_ != NULL)\n    {\n        wbem_enum_->Release();\n        wbem_enum_ = NULL;\n    }    \n    if (wbem_refresher_ != NULL)\n    {\n        wbem_refresher_->Release();\n        wbem_refresher_ = NULL;\n    }\n    if (wbem_service_proxy_ != NULL)\n    {\n        wbem_service_proxy_->Release();\n        wbem_service_proxy_ = NULL;\n    }\n    if (wbem_service_ != NULL)\n    {\n        wbem_service_->Release();\n        wbem_service_ = NULL;\n    }\n    // CoUninitialized should be called once for every CoInitializeEx.\n    // Regardless if it failed or not.\n    CoUninitialize();\n    has_terminated_ = true;\n    return true;\n}\n\nbool CpuWindows::UpdateCpuUsage()\n{\n    wbem_refresher_->Refresh(0L);\n    DWORD number_returned = 0;\n    HRESULT hr = wbem_enum_->GetObjects(0L, number_of_objects_,\n                                        wbem_enum_access_,&number_returned);\n    if (FAILED(hr))\n    {\n        // wbem_enum_access_ has already been allocated. Unless the number of\n        // CPUs change runtime this should not happen.\n        return false;\n    }\n    unsigned __int64 cpu_usage = 0;\n    unsigned __int64 timestamp_100ns = 0;\n    bool returnValue = true;\n    for (DWORD i = 0; i < number_returned; i++)\n    {\n        hr = wbem_enum_access_[i]->ReadQWORD(cpu_usage_handle_,&cpu_usage);\n        if (FAILED(hr))\n        {\n            returnValue = false;\n        }\n        hr = wbem_enum_access_[i]->ReadQWORD(timestamp_sys_100_ns_handle_,\n                                             &timestamp_100ns);\n        if (FAILED(hr))\n        {\n            returnValue = false;\n        }\n        wbem_enum_access_[i]->Release();\n        wbem_enum_access_[i] = NULL;\n\n        const bool wrapparound =\n            (previous_processor_timestamp_[i] > cpu_usage) ||\n            (previous_100ns_timestamp_[i] > timestamp_100ns);\n        const bool first_time = (previous_processor_timestamp_[i] == 0) ||\n                                (previous_100ns_timestamp_[i] == 0);\n        if (wrapparound || first_time)\n        {\n            previous_processor_timestamp_[i] = cpu_usage;\n            previous_100ns_timestamp_[i] = timestamp_100ns;\n            continue;\n        }\n        const unsigned __int64 processor_timestamp_delta =\n            cpu_usage - previous_processor_timestamp_[i];\n        const unsigned __int64 timestamp_100ns_delta =\n            timestamp_100ns - previous_100ns_timestamp_[i];\n\n        if (processor_timestamp_delta >= timestamp_100ns_delta)\n        {\n            cpu_usage_[i] = 0;\n        } else {\n            // Quotient must be float since the division is guaranteed to yield\n            // a value between 0 and 1 which is 0 in integer division.\n            const float delta_quotient =\n                static_cast<float>(processor_timestamp_delta) /\n                static_cast<float>(timestamp_100ns_delta);\n            cpu_usage_[i] = 100 - static_cast<WebRtc_UWord32>(delta_quotient *\n                                                              100);\n        }\n        previous_processor_timestamp_[i] = cpu_usage;\n        previous_100ns_timestamp_[i] = timestamp_100ns;\n    }\n    return returnValue;\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/cpu_windows.h",
    "content": "// This file contains a Windows implementation of CpuWrapper.\n// Note: Windows XP, Windows Server 2003 are the minimum requirements.\n//       The requirements are due to the implementation being based on\n//       WMI.\n/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_WINDOWS_NO_CPOL_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_WINDOWS_NO_CPOL_H_\n\n#include \"cpu_wrapper.h\"\n\n#include \"rpcsal.h\"\n#include <Wbemidl.h>\n\nnamespace webrtc {\nclass ConditionVariableWrapper;\nclass CriticalSectionWrapper;\nclass EventWrapper;\nclass ThreadWrapper;\n\nclass CpuWindows : public CpuWrapper\n{\npublic:\n    virtual WebRtc_Word32 CpuUsage();\n    virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* /*pProcessName*/,\n                                   WebRtc_UWord32 /*length*/) {return -1;}\n    virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32  /*dwProcessID*/) {return -1;}\n\n    virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& num_cores,\n                                            WebRtc_UWord32*& cpu_usage);\n\n    virtual void Reset() {}\n    virtual void Stop() {}\n\n    CpuWindows();\n    virtual ~CpuWindows();\nprivate:\n    bool AllocateComplexDataTypes();\n    void DeAllocateComplexDataTypes();\n\n    bool StartPollingCpu();\n    bool StopPollingCpu();\n\n    static bool Process(void* thread_object);\n    bool ProcessImpl();\n\n    bool CreateWmiConnection();\n    bool CreatePerfOsRefresher();\n    bool CreatePerfOsCpuHandles();\n    bool Initialize();\n    bool Terminate();\n\n    bool UpdateCpuUsage();\n\n    ThreadWrapper* cpu_polling_thread;\n\n    bool initialize_;\n    bool has_initialized_;\n    CriticalSectionWrapper* init_crit_;\n    ConditionVariableWrapper* init_cond_;\n\n    bool terminate_;\n    bool has_terminated_;\n    CriticalSectionWrapper* terminate_crit_;\n    ConditionVariableWrapper* terminate_cond_;\n\n    // For sleep with wake-up functionality.\n    EventWrapper* sleep_event;\n\n    // Will be an array. Just care about CPU 0 for now.\n    WebRtc_UWord32* cpu_usage_;\n\n    // One IWbemObjectAccess for each processor and one for the total.\n    // 0-n-1 is the individual processors.\n    // n is the total.\n    IWbemObjectAccess** wbem_enum_access_;\n    DWORD number_of_objects_;\n\n    // Cpu timestamp\n    long cpu_usage_handle_;\n    unsigned __int64* previous_processor_timestamp_;\n\n    // Timestamp\n    long timestamp_sys_100_ns_handle_;\n    unsigned __int64* previous_100ns_timestamp_;\n\n    IWbemServices* wbem_service_;\n    IWbemServices* wbem_service_proxy_;\n\n    IWbemRefresher* wbem_refresher_;\n\n    IWbemHiPerfEnum* wbem_enum_;\n\n};\n} // namespace webrtc\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_WINDOWS_NO_CPOL_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/critical_section.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#if defined(_WIN32)\n    #include <windows.h>\n    #include \"critical_section_windows.h\"\n#else\n    #include \"critical_section_posix.h\"\n#endif\n\nnamespace webrtc {\nCriticalSectionWrapper* CriticalSectionWrapper::CreateCriticalSection()\n{\n#ifdef _WIN32\n    return new CriticalSectionWindows();\n#else\n    return new CriticalSectionPosix();\n#endif\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/critical_section_posix.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"critical_section_posix.h\"\n\nnamespace webrtc {\nCriticalSectionPosix::CriticalSectionPosix()\n{\n    pthread_mutexattr_t attr;\n    pthread_mutexattr_init(&attr);\n    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);\n    pthread_mutex_init(&_mutex, &attr);\n}\n\nCriticalSectionPosix::~CriticalSectionPosix()\n{\n    pthread_mutex_destroy(&_mutex);\n}\n\nvoid\nCriticalSectionPosix::Enter()\n{\n    pthread_mutex_lock(&_mutex);\n}\n\nvoid\nCriticalSectionPosix::Leave()\n{\n    pthread_mutex_unlock(&_mutex);\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/critical_section_posix.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_\n\n#include \"critical_section_wrapper.h\"\n\n#include <pthread.h>\n\nnamespace webrtc {\nclass CriticalSectionPosix : public CriticalSectionWrapper\n{\npublic:\n    CriticalSectionPosix();\n\n    virtual ~CriticalSectionPosix();\n\n    virtual void Enter();\n    virtual void Leave();\n\nprivate:\n    pthread_mutex_t _mutex;\n    friend class ConditionVariablePosix;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/critical_section_windows.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"critical_section_windows.h\"\n\nnamespace webrtc {\nCriticalSectionWindows::CriticalSectionWindows()\n{\n    InitializeCriticalSection(&crit);\n}\n\nCriticalSectionWindows::~CriticalSectionWindows()\n{\n    DeleteCriticalSection(&crit);\n}\n\nvoid\nCriticalSectionWindows::Enter()\n{\n    EnterCriticalSection(&crit);\n}\n\nvoid\nCriticalSectionWindows::Leave()\n{\n    LeaveCriticalSection(&crit);\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/critical_section_windows.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_\n\n#include \"typedefs.h\"\n#include \"critical_section_wrapper.h\"\n#include <windows.h>\n\nnamespace webrtc {\nclass CriticalSectionWindows : public CriticalSectionWrapper\n{\npublic:\n    CriticalSectionWindows();\n\n    virtual ~CriticalSectionWindows();\n\n    virtual void Enter();\n    virtual void Leave();\n\nprivate:\n    CRITICAL_SECTION crit;\n\n    friend class ConditionVariableWindows;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/data_log.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"data_log.h\"\n\n#include <assert.h>\n\n#include <algorithm>\n#include <list>\n\n#include \"critical_section_wrapper.h\"\n#include \"event_wrapper.h\"\n#include \"file_wrapper.h\"\n#include \"rw_lock_wrapper.h\"\n#include \"thread_wrapper.h\"\n\nnamespace webrtc {\n\nDataLogImpl::CritSectScopedPtr DataLogImpl::crit_sect_(\n  CriticalSectionWrapper::CreateCriticalSection());\n\nDataLogImpl* DataLogImpl::instance_ = NULL;\n\n// A Row contains cells, which are indexed by the column names as std::string.\n// The string index is treated in a case sensitive way.\nclass Row {\n public:\n  Row();\n  ~Row();\n\n  // Inserts a Container into the cell of the column specified with\n  // column_name.\n  // column_name is treated in a case sensitive way.\n  int InsertCell(const std::string& column_name,\n                 const Container* value_container);\n\n  // Converts the value at the column specified by column_name to a string\n  // stored in value_string.\n  // column_name is treated in a case sensitive way.\n  void ToString(const std::string& column_name, std::string* value_string);\n\n private:\n  // Collection of containers indexed by column name as std::string\n  typedef std::map<std::string, const Container*> CellMap;\n\n  CellMap                   cells_;\n  CriticalSectionWrapper*   cells_lock_;\n};\n\n// A LogTable contains multiple rows, where only the latest row is active for\n// editing. The rows are defined by the ColumnMap, which contains the name of\n// each column and the length of the column (1 for one-value-columns and greater\n// than 1 for multi-value-columns).\nclass LogTable {\n public:\n  LogTable();\n  ~LogTable();\n\n  // Adds the column with name column_name to the table. The column will be a\n  // multi-value-column if multi_value_length is greater than 1.\n  // column_name is treated in a case sensitive way.\n  int AddColumn(const std::string& column_name, int multi_value_length);\n\n  // Buffers the current row while it is waiting to be written to file,\n  // which is done by a call to Flush(). A new row is available when the\n  // function returns\n  void NextRow();\n\n  // Inserts a Container into the cell of the column specified with\n  // column_name.\n  // column_name is treated in a case sensitive way.\n  int InsertCell(const std::string& column_name,\n                 const Container* value_container);\n\n  // Creates a log file, named as specified in the string file_name, to\n  // where the table will be written when calling Flush().\n  int CreateLogFile(const std::string& file_name);\n\n  // Write all complete rows to file.\n  // May not be called by two threads simultaneously (doing so may result in\n  // a race condition). Will be called by the file_writer_thread_ when that\n  // thread is running.\n  void Flush();\n\n private:\n  // Collection of multi_value_lengths indexed by column name as std::string\n  typedef std::map<std::string, int> ColumnMap;\n  typedef std::list<Row*> RowList;\n\n  ColumnMap               columns_;\n  RowList                 rows_[2];\n  RowList*                rows_history_;\n  RowList*                rows_flush_;\n  Row*                    current_row_;\n  FileWrapper*            file_;\n  bool                    write_header_;\n  CriticalSectionWrapper* table_lock_;\n};\n\nRow::Row()\n  : cells_(),\n    cells_lock_(CriticalSectionWrapper::CreateCriticalSection()) {\n}\n\nRow::~Row() {\n  for (CellMap::iterator it = cells_.begin(); it != cells_.end();) {\n    delete it->second;\n    // For maps all iterators (except the erased) are valid after an erase\n    cells_.erase(it++);\n  }\n  delete cells_lock_;\n}\n\nint Row::InsertCell(const std::string& column_name,\n                    const Container* value_container) {\n  CriticalSectionScoped synchronize(*cells_lock_);\n  assert(cells_.count(column_name) == 0);\n  if (cells_.count(column_name) > 0)\n    return -1;\n  cells_[column_name] = value_container;\n  return 0;\n}\n\nvoid Row::ToString(const std::string& column_name,\n                   std::string* value_string) {\n  CriticalSectionScoped synchronize(*cells_lock_);\n  const Container* container = cells_[column_name];\n  if (container == NULL) {\n    *value_string = \"NaN,\";\n    return;\n  }\n  container->ToString(value_string);\n}\n\nLogTable::LogTable()\n  : columns_(),\n    rows_(),\n    rows_history_(&rows_[0]),\n    rows_flush_(&rows_[1]),\n    current_row_(new Row),\n    file_(FileWrapper::Create()),\n    write_header_(true),\n    table_lock_(CriticalSectionWrapper::CreateCriticalSection()) {\n}\n\nLogTable::~LogTable() {\n  for (RowList::iterator row_it = rows_history_->begin();\n       row_it != rows_history_->end();) {\n    delete *row_it;\n    row_it = rows_history_->erase(row_it);\n  }\n  for (ColumnMap::iterator col_it = columns_.begin();\n       col_it != columns_.end();) {\n    // For maps all iterators (except the erased) are valid after an erase\n    columns_.erase(col_it++);\n  }\n  if (file_ != NULL) {\n    file_->Flush();\n    file_->CloseFile();\n    delete file_;\n  }\n  delete current_row_;\n  delete table_lock_;\n}\n\nint LogTable::AddColumn(const std::string& column_name,\n                        int multi_value_length) {\n  assert(multi_value_length > 0);\n  if (!write_header_) {\n    // It's not allowed to add new columns after the header\n    // has been written.\n    assert(false);\n    return -1;\n  } else {\n    CriticalSectionScoped synchronize(*table_lock_);\n    if (write_header_)\n      columns_[column_name] = multi_value_length;\n    else\n      return -1;\n  }\n  return 0;\n}\n\nvoid LogTable::NextRow() {\n  CriticalSectionScoped sync_rows(*table_lock_);\n  rows_history_->push_back(current_row_);\n  current_row_ = new Row;\n}\n\nint LogTable::InsertCell(const std::string& column_name,\n                         const Container* value_container) {\n  CriticalSectionScoped synchronize(*table_lock_);\n  assert(columns_.count(column_name) > 0);\n  if (columns_.count(column_name) == 0)\n    return -1;\n  return current_row_->InsertCell(column_name, value_container);\n}\n\nint LogTable::CreateLogFile(const std::string& file_name) {\n  if (file_name.length() == 0)\n    return -1;\n  if (file_->Open())\n    return -1;\n  file_->OpenFile(file_name.c_str(),\n                  false,  // Open with read/write permissions\n                  false,  // Don't wraparound and write at the beginning when\n                          // the file is full\n                  true);  // Open as a text file\n  if (file_ == NULL)\n    return -1;\n  return 0;\n}\n\nvoid LogTable::Flush() {\n  ColumnMap::iterator column_it;\n  bool commit_header = false;\n  if (write_header_) {\n    CriticalSectionScoped synchronize(*table_lock_);\n    if (write_header_) {\n      commit_header = true;\n      write_header_ = false;\n    }\n  }\n  if (commit_header) {\n    for (column_it = columns_.begin();\n         column_it != columns_.end(); ++column_it) {\n      if (column_it->second > 1) {\n        file_->WriteText(\"%s[%u],\", column_it->first.c_str(),\n                         column_it->second);\n        for (int i = 1; i < column_it->second; ++i)\n          file_->WriteText(\",\");\n      } else {\n        file_->WriteText(\"%s,\", column_it->first.c_str());\n      }\n    }\n    if (columns_.size() > 0)\n      file_->WriteText(\"\\n\");\n  }\n\n  // Swap the list used for flushing with the list containing the row history\n  // and clear the history. We also create a local pointer to the new\n  // list used for flushing to avoid race conditions if another thread\n  // calls this function while we are writing.\n  // We don't want to block the list while we're writing to file.\n  {\n    CriticalSectionScoped synchronize(*table_lock_);\n    RowList* tmp = rows_flush_;\n    rows_flush_ = rows_history_;\n    rows_history_ = tmp;\n    rows_history_->clear();\n  }\n\n  // Write all complete rows to file and delete them\n  for (RowList::iterator row_it = rows_flush_->begin();\n       row_it != rows_flush_->end();) {\n    for (column_it = columns_.begin();\n         column_it != columns_.end(); ++column_it) {\n      std::string row_string;\n      (*row_it)->ToString(column_it->first, &row_string);\n      file_->WriteText(\"%s\", row_string.c_str());\n    }\n    if (columns_.size() > 0)\n      file_->WriteText(\"\\n\");\n    delete *row_it;\n    row_it = rows_flush_->erase(row_it);\n  }\n}\n\nint DataLog::CreateLog() {\n  return DataLogImpl::CreateLog();\n}\n\nvoid DataLog::ReturnLog() {\n  return DataLogImpl::ReturnLog();\n}\n\nstd::string DataLog::Combine(const std::string& table_name, int table_id) {\n  std::stringstream ss;\n  std::string combined_id;\n  ss << table_name << \"_\" << table_id;\n  ss >> combined_id;\n  std::transform(combined_id.begin(), combined_id.end(), combined_id.begin(),\n                 ::tolower);\n  return combined_id;\n}\n\nint DataLog::AddTable(const std::string& table_name) {\n  DataLogImpl* data_log = DataLogImpl::StaticInstance();\n  if (data_log == NULL)\n    return -1;\n  return data_log->AddTable(table_name);\n}\n\nint DataLog::AddColumn(const std::string& table_name,\n                       const std::string& column_name,\n                       int multi_value_length) {\n  DataLogImpl* data_log = DataLogImpl::StaticInstance();\n  if (data_log == NULL)\n    return -1;\n  return data_log->DataLogImpl::StaticInstance()->AddColumn(table_name,\n                                                            column_name,\n                                                            multi_value_length);\n}\n\nint DataLog::NextRow(const std::string& table_name) {\n  DataLogImpl* data_log = DataLogImpl::StaticInstance();\n  if (data_log == NULL)\n    return -1;\n  return data_log->DataLogImpl::StaticInstance()->NextRow(table_name);\n}\n\nDataLogImpl::DataLogImpl()\n  : counter_(1),\n    tables_(),\n    flush_event_(EventWrapper::Create()),\n    file_writer_thread_(NULL),\n    tables_lock_(RWLockWrapper::CreateRWLock()) {\n}\n\nDataLogImpl::~DataLogImpl() {\n  StopThread();\n  Flush();  // Write any remaining rows\n  delete file_writer_thread_;\n  delete flush_event_;\n  for (TableMap::iterator it = tables_.begin(); it != tables_.end();) {\n    delete static_cast<LogTable*>(it->second);\n    // For maps all iterators (except the erased) are valid after an erase\n    tables_.erase(it++);\n  }\n  delete tables_lock_;\n}\n\nint DataLogImpl::CreateLog() {\n  CriticalSectionScoped synchronize(*crit_sect_);\n  if (instance_ == NULL) {\n    instance_ = new DataLogImpl();\n    return instance_->Init();\n  } else {\n    ++instance_->counter_;\n  }\n  return 0;\n}\n\nint DataLogImpl::Init() {\n  file_writer_thread_ = ThreadWrapper::CreateThread(\n                          DataLogImpl::Run,\n                          instance_,\n                          kHighestPriority,\n                          \"DataLog\");\n  if (file_writer_thread_ == NULL)\n    return -1;\n  unsigned int thread_id = 0;\n  bool success = file_writer_thread_->Start(thread_id);\n  if (!success)\n    return -1;\n  return 0;\n}\n\nDataLogImpl* DataLogImpl::StaticInstance() {\n  return instance_;\n}\n\nvoid DataLogImpl::ReturnLog() {\n  CriticalSectionScoped synchronize(*crit_sect_);\n  if (instance_ && instance_->counter_ > 1) {\n    --instance_->counter_;\n    return;\n  }\n  delete instance_;\n  instance_ = NULL;\n}\n\nint DataLogImpl::AddTable(const std::string& table_name) {\n  WriteLockScoped synchronize(*tables_lock_);\n  // Make sure we don't add a table which already exists\n  if (tables_.count(table_name) > 0)\n    return -1;\n  tables_[table_name] = new LogTable();\n  if (tables_[table_name]->CreateLogFile(table_name + \".txt\") == -1)\n    return -1;\n  return 0;\n}\n\nint DataLogImpl::AddColumn(const std::string& table_name,\n                           const std::string& column_name,\n                           int multi_value_length) {\n  ReadLockScoped synchronize(*tables_lock_);\n  if (tables_.count(table_name) == 0)\n    return -1;\n  return tables_[table_name]->AddColumn(column_name, multi_value_length);\n}\n\nint DataLogImpl::InsertCell(const std::string& table_name,\n                            const std::string& column_name,\n                            const Container* value_container) {\n  ReadLockScoped synchronize(*tables_lock_);\n  assert(tables_.count(table_name) > 0);\n  if (tables_.count(table_name) == 0)\n    return -1;\n  return tables_[table_name]->InsertCell(column_name, value_container);\n}\n\nint DataLogImpl::NextRow(const std::string& table_name) {\n  ReadLockScoped synchronize(*tables_lock_);\n  if (tables_.count(table_name) == 0)\n    return -1;\n  tables_[table_name]->NextRow();\n  if (file_writer_thread_ == NULL) {\n    // Write every row to file as they get complete.\n    tables_[table_name]->Flush();\n  } else {\n    // Signal a complete row\n    flush_event_->Set();\n  }\n  return 0;\n}\n\nvoid DataLogImpl::Flush() {\n  ReadLockScoped synchronize(*tables_lock_);\n  for (TableMap::iterator it = tables_.begin(); it != tables_.end(); ++it) {\n    it->second->Flush();\n  }\n}\n\nbool DataLogImpl::Run(void* obj) {\n  static_cast<DataLogImpl*>(obj)->Process();\n  return true;\n}\n\nvoid DataLogImpl::Process() {\n  // Wait for a row to be complete\n  flush_event_->Wait(WEBRTC_EVENT_INFINITE);\n  Flush();\n}\n\nvoid DataLogImpl::StopThread() {\n  if (file_writer_thread_ != NULL) {\n    file_writer_thread_->SetNotAlive();\n    flush_event_->Set();\n    // Call Stop() repeatedly, waiting for the Flush() call in Process() to\n    // finish.\n    while (!file_writer_thread_->Stop()) continue;\n  }\n}\n\n}  // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/data_log_dummy.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"data_log.h\"\n\nnamespace webrtc {\n\nint DataLog::CreateLog() {\n  return 0;\n}\n\nvoid DataLog::ReturnLog() {\n}\n\nint DataLog::AddTable(const std::string& /*table_name*/) {\n  return 0;\n}\n\nint DataLog::AddColumn(const std::string& /*table_name*/,\n                       const std::string& /*column_name*/,\n                       int /*multi_value_length*/) {\n  return 0;\n}\n\nint DataLog::NextRow(const std::string& /*table_name*/) {\n  return 0;\n}\n\nDataLogImpl::DataLogImpl() {\n}\n\nDataLogImpl::~DataLogImpl() {\n}\n\nDataLogImpl* DataLogImpl::StaticInstance() {\n  return NULL;\n}\n\nvoid DataLogImpl::ReturnLog() {\n}\n\nint DataLogImpl::AddTable(const std::string& /*table_name*/) {\n  return 0;\n}\n\nint DataLogImpl::AddColumn(const std::string& /*table_name*/,\n                           const std::string& /*column_name*/,\n                           int /*multi_value_length*/) {\n  return 0;\n}\n\nint DataLogImpl::InsertCell(const std::string& /*table_name*/,\n                            const std::string& /*column_name*/,\n                            const Container* /*value_container*/) {\n  return 0;\n}\n\nint DataLogImpl::NextRow(const std::string& /*table_name*/) {\n  return 0;\n}\n\nvoid DataLogImpl::Flush() {\n}\n\nbool DataLogImpl::Run(void* /*obj*/) {\n  return true;\n}\n\nvoid DataLogImpl::Process() {\n}\n\nvoid DataLogImpl::StopThread() {\n}\n\n}  // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/data_log_helpers_unittest.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include <string>\n\n#include \"data_log.h\"\n#include \"gtest/gtest.h\"\n\nusing ::webrtc::DataLog;\n\nTEST(TestDataLog, IntContainers) {\n  int c = 5;\n  webrtc::ValueContainer<int> v1(c);\n  c = 10;\n  webrtc::ValueContainer<int> v2(c);\n  std::string s1, s2;\n  v1.ToString(&s1);\n  v2.ToString(&s2);\n  ASSERT_EQ(s1, \"5,\");\n  ASSERT_EQ(s2, \"10,\");\n  v1 = v2;\n  v1.ToString(&s1);\n  ASSERT_EQ(s1, s2);\n}\n\nTEST(TestDataLog, DoubleContainers) {\n  double c = 3.5;\n  webrtc::ValueContainer<double> v1(c);\n  c = 10.3;\n  webrtc::ValueContainer<double> v2(c);\n  std::string s1, s2;\n  v1.ToString(&s1);\n  v2.ToString(&s2);\n  ASSERT_EQ(s1, \"3.5,\");\n  ASSERT_EQ(s2, \"10.3,\");\n  v1 = v2;\n  v1.ToString(&s1);\n  ASSERT_EQ(s1, s2);\n}\n\nTEST(TestDataLog, MultiValueContainers) {\n  int a[3] = {1, 2, 3};\n  int b[3] = {4, 5, 6};\n  webrtc::MultiValueContainer<int> m1(a, 3);\n  webrtc::MultiValueContainer<int> m2(b, 3);\n  webrtc::MultiValueContainer<int> m3(a, 3);\n  std::string s1, s2, s3;\n  m1.ToString(&s1);\n  m2.ToString(&s2);\n  ASSERT_EQ(s1, \"1,2,3,\");\n  ASSERT_EQ(s2, \"4,5,6,\");\n  m1 = m2;\n  m1.ToString(&s1);\n  ASSERT_EQ(s1, s2);\n  m3.ToString(&s3);\n  ASSERT_EQ(s3, \"1,2,3,\");\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/data_log_unittest.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include <map>\n#include <string>\n\n#include \"data_log.h\"\n#include \"gtest/gtest.h\"\n\nusing ::webrtc::DataLog;\n\n// A class for storing the values expected from a log table column when\n// verifying a log table file.\nstruct ExpectedValues {\n public:\n  ExpectedValues()\n    : values(NULL),\n      multi_value_length(1) {\n  }\n\n  ExpectedValues(std::vector<std::string> expected_values,\n                 int expected_multi_value_length)\n    : values(expected_values),\n      multi_value_length(expected_multi_value_length) {\n  }\n\n  std::vector<std::string> values;\n  int multi_value_length;\n};\n\ntypedef std::map<std::string, ExpectedValues> ExpectedValuesMap;\n\n// A static class used for parsing and verifying data log files.\nclass DataLogParser {\n public:\n  // Verifies that the log table stored in the file \"log_file\" corresponds to\n  // the cells and columns specified in \"columns\".\n  static int VerifyTable(FILE* log_file, const ExpectedValuesMap& columns) {\n    int row = 0;\n    char line_buffer[kMaxLineLength];\n    char* ret = fgets(line_buffer, kMaxLineLength, log_file);\n    EXPECT_FALSE(ret == NULL);\n    if (ret == NULL)\n      return -1;\n\n    std::string line(line_buffer, kMaxLineLength);\n    VerifyHeader(line, columns);\n    while (fgets(line_buffer, kMaxLineLength, log_file) != NULL) {\n      line = std::string(line_buffer, kMaxLineLength);\n      size_t line_position = 0;\n\n      for (ExpectedValuesMap::const_iterator it = columns.begin();\n           it != columns.end(); ++it) {\n        std::string str = ParseElement(line, &line_position,\n                                       it->second.multi_value_length);\n        EXPECT_EQ(str, it->second.values[row]);\n        if (str != it->second.values[row])\n          return -1;\n      }\n      ++row;\n    }\n    return 0;\n  }\n\n  // Verifies the table header stored in \"line\" to correspond with the header\n  // specified in \"columns\".\n  static int VerifyHeader(const std::string& line,\n                          const ExpectedValuesMap& columns) {\n    size_t line_position = 0;\n    for (ExpectedValuesMap::const_iterator it = columns.begin();\n         it != columns.end(); ++it) {\n      std::string str = ParseElement(line, &line_position,\n                                     it->second.multi_value_length);\n      EXPECT_EQ(str, it->first);\n      if (str != it->first)\n        return -1;\n    }\n    return 0;\n  }\n\n  // Parses out and returns one element from the string \"line\", which contains\n  // one line read from a log table file. An element can either be a column\n  // header or a cell of a row.\n  static std::string ParseElement(const std::string& line,\n                                  size_t* line_position,\n                                  int multi_value_length) {\n    std::string parsed_cell;\n    parsed_cell = \"\";\n    for (int i = 0; i < multi_value_length; ++i) {\n      size_t next_separator = line.find(',', *line_position);\n      EXPECT_NE(next_separator, std::string::npos);\n      if (next_separator == std::string::npos)\n        break;\n      parsed_cell += line.substr(*line_position,\n                                 next_separator - *line_position + 1);\n      *line_position = next_separator + 1;\n    }\n    return parsed_cell;\n  }\n\n  // This constant defines the maximum line length the DataLogParser can\n  // parse.\n  enum { kMaxLineLength = 100 };\n};\n\nTEST(TestDataLog, CreateReturnTest) {\n  for (int i = 0; i < 10; ++i)\n    ASSERT_EQ(DataLog::CreateLog(), 0);\n  ASSERT_EQ(DataLog::AddTable(DataLog::Combine(\"a proper table\", 1)), 0);\n  for (int i = 0; i < 10; ++i)\n    DataLog::ReturnLog();\n  ASSERT_LT(DataLog::AddTable(DataLog::Combine(\"table failure\", 1)), 0);\n}\n\nTEST(TestDataLog, VerifySingleTable) {\n  DataLog::CreateLog();\n  DataLog::AddTable(DataLog::Combine(\"table\", 1));\n  DataLog::AddColumn(DataLog::Combine(\"table\", 1), \"arrival\", 1);\n  DataLog::AddColumn(DataLog::Combine(\"table\", 1), \"timestamp\", 1);\n  DataLog::AddColumn(DataLog::Combine(\"table\", 1), \"size\", 5);\n  WebRtc_UWord32 sizes[5] = {1400, 1500, 1600, 1700, 1800};\n  for (int i = 0; i < 10; ++i) {\n    DataLog::InsertCell(DataLog::Combine(\"table\", 1), \"arrival\",\n                        static_cast<double>(i));\n    DataLog::InsertCell(DataLog::Combine(\"table\", 1), \"timestamp\",\n                        static_cast<WebRtc_Word64>(4354 + i));\n    DataLog::InsertCell(DataLog::Combine(\"table\", 1), \"size\", sizes, 5);\n    DataLog::NextRow(DataLog::Combine(\"table\", 1));\n  }\n  DataLog::ReturnLog();\n  // Verify file\n  FILE* table = fopen(\"table_1.txt\", \"r\");\n  ASSERT_FALSE(table == NULL);\n  // Read the column names and verify with the expected columns.\n  // Note that the columns are written to file in alphabetical order.\n  // Data expected from parsing the file\n  const int kNumberOfRows = 10;\n  std::string string_arrival[kNumberOfRows] = {\n    \"0,\", \"1,\", \"2,\", \"3,\", \"4,\",\n    \"5,\", \"6,\", \"7,\", \"8,\", \"9,\"\n  };\n  std::string string_timestamp[kNumberOfRows] = {\n    \"4354,\", \"4355,\", \"4356,\", \"4357,\",\n    \"4358,\", \"4359,\", \"4360,\", \"4361,\",\n    \"4362,\", \"4363,\"\n  };\n  std::string string_sizes = \"1400,1500,1600,1700,1800,\";\n  ExpectedValuesMap expected;\n  expected[\"arrival,\"] = ExpectedValues(\n                           std::vector<std::string>(string_arrival,\n                                                    string_arrival +\n                                                    kNumberOfRows),\n                           1);\n  expected[\"size[5],,,,,\"] = ExpectedValues(\n                               std::vector<std::string>(10, string_sizes), 5);\n  expected[\"timestamp,\"] = ExpectedValues(\n                             std::vector<std::string>(string_timestamp,\n                                                      string_timestamp +\n                                                      kNumberOfRows),\n                             1);\n  ASSERT_EQ(DataLogParser::VerifyTable(table, expected), 0);\n  fclose(table);\n}\n\nTEST(TestDataLog, VerifyMultipleTables) {\n  DataLog::CreateLog();\n  DataLog::AddTable(DataLog::Combine(\"table\", 2));\n  DataLog::AddTable(DataLog::Combine(\"table\", 3));\n  DataLog::AddColumn(DataLog::Combine(\"table\", 2), \"arrival\", 1);\n  DataLog::AddColumn(DataLog::Combine(\"table\", 2), \"timestamp\", 1);\n  DataLog::AddColumn(DataLog::Combine(\"table\", 2), \"size\", 1);\n  DataLog::AddTable(DataLog::Combine(\"table\", 4));\n  DataLog::AddColumn(DataLog::Combine(\"table\", 3), \"timestamp\", 1);\n  DataLog::AddColumn(DataLog::Combine(\"table\", 3), \"arrival\", 1);\n  DataLog::AddColumn(DataLog::Combine(\"table\", 4), \"size\", 1);\n  for (WebRtc_Word32 i = 0; i < 10; ++i) {\n    DataLog::InsertCell(DataLog::Combine(\"table\", 2), \"arrival\",\n                        static_cast<WebRtc_Word32>(i));\n    DataLog::InsertCell(DataLog::Combine(\"table\", 2), \"timestamp\",\n                        static_cast<WebRtc_Word32>(4354 + i));\n    DataLog::InsertCell(DataLog::Combine(\"table\", 2), \"size\",\n                        static_cast<WebRtc_Word32>(1200 + 10 * i));\n    DataLog::InsertCell(DataLog::Combine(\"table\", 3), \"timestamp\",\n                        static_cast<WebRtc_Word32>(4354 + i));\n    DataLog::InsertCell(DataLog::Combine(\"table\", 3), \"arrival\",\n                        static_cast<WebRtc_Word32>(i));\n    DataLog::InsertCell(DataLog::Combine(\"table\", 4), \"size\",\n                        static_cast<WebRtc_Word32>(1200 + 10 * i));\n    DataLog::NextRow(DataLog::Combine(\"table\", 4));\n    DataLog::NextRow(DataLog::Combine(\"table\", 2));\n    DataLog::NextRow(DataLog::Combine(\"table\", 3));\n  }\n  DataLog::ReturnLog();\n\n  // Data expected from parsing the file\n  const int kNumberOfRows = 10;\n  std::string string_arrival[kNumberOfRows] = {\n    \"0,\", \"1,\", \"2,\", \"3,\", \"4,\",\n    \"5,\", \"6,\", \"7,\", \"8,\", \"9,\"\n  };\n  std::string string_timestamp[kNumberOfRows] = {\n    \"4354,\", \"4355,\", \"4356,\", \"4357,\",\n    \"4358,\", \"4359,\", \"4360,\", \"4361,\",\n    \"4362,\", \"4363,\"\n  };\n  std::string string_size[kNumberOfRows] = {\n    \"1200,\", \"1210,\", \"1220,\", \"1230,\",\n    \"1240,\", \"1250,\", \"1260,\", \"1270,\",\n    \"1280,\", \"1290,\"\n  };\n\n  // Verify table 2\n  {\n    FILE* table = fopen(\"table_2.txt\", \"r\");\n    ASSERT_FALSE(table == NULL);\n    ExpectedValuesMap expected;\n    expected[\"arrival,\"] = ExpectedValues(\n                             std::vector<std::string>(string_arrival,\n                                                      string_arrival +\n                                                      kNumberOfRows),\n                             1);\n    expected[\"size,\"] = ExpectedValues(\n                          std::vector<std::string>(string_size,\n                                                   string_size + kNumberOfRows),\n                          1);\n    expected[\"timestamp,\"] = ExpectedValues(\n                               std::vector<std::string>(string_timestamp,\n                                                        string_timestamp +\n                                                        kNumberOfRows),\n                               1);\n    ASSERT_EQ(DataLogParser::VerifyTable(table, expected), 0);\n    fclose(table);\n  }\n\n  // Verify table 3\n  {\n    FILE* table = fopen(\"table_3.txt\", \"r\");\n    ASSERT_FALSE(table == NULL);\n    ExpectedValuesMap expected;\n    expected[\"arrival,\"] = ExpectedValues(\n                             std::vector<std::string>(string_arrival,\n                                                      string_arrival +\n                                                      kNumberOfRows),\n                             1);\n    expected[\"timestamp,\"] = ExpectedValues(\n                             std::vector<std::string>(string_timestamp,\n                                                      string_timestamp +\n                                                      kNumberOfRows),\n                               1);\n    ASSERT_EQ(DataLogParser::VerifyTable(table, expected), 0);\n    fclose(table);\n  }\n\n  // Verify table 4\n  {\n    FILE* table = fopen(\"table_4.txt\", \"r\");\n    ASSERT_FALSE(table == NULL);\n    ExpectedValuesMap expected;\n    expected[\"size,\"] = ExpectedValues(\n                          std::vector<std::string>(string_size,\n                                                   string_size +\n                                                   kNumberOfRows),\n                          1);\n    ASSERT_EQ(DataLogParser::VerifyTable(table, expected), 0);\n    fclose(table);\n  }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/event.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"event_wrapper.h\"\n\n#if defined(_WIN32)\n    #include <windows.h>\n    #include \"event_windows.h\"\n#elif defined(WEBRTC_MAC_INTEL)\n    #include <ApplicationServices/ApplicationServices.h>\n    #include <pthread.h>\n    #include \"event_posix.h\"\n#else\n    #include <pthread.h>\n    #include \"event_posix.h\"\n#endif\n\nnamespace webrtc {\nEventWrapper* EventWrapper::Create()\n{\n#if defined(_WIN32)\n    return new EventWindows();\n#else\n    return EventPosix::Create();\n#endif\n}\n\nint EventWrapper::KeyPressed()\n{\n#if defined(_WIN32)\n    int keyDown = 0;\n    for(int key = 0x20; key < 0x90; key++)\n    {\n        short res = GetAsyncKeyState(key);\n        keyDown |= res%2;  // Get the LSB\n    }\n    if(keyDown)\n    {\n        return 1;\n    }\n    else\n    {\n        return 0;\n    }\n#elif defined(WEBRTC_MAC_INTEL)\n    bool keyDown = false;\n    // loop through all Mac virtual key constant values\n    for(int keyIndex = 0; keyIndex <= 0x5C; keyIndex++) \n    {\n        keyDown |= CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, keyIndex);\n    }\n    if(keyDown)\n    {\n        return 1;\n    }\n    else\n    {\n        return 0;\n    } \n#else\n    return -1;\n#endif\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/event_posix.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"event_posix.h\"\n\n#include <errno.h>\n#include <pthread.h>\n#include <signal.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/time.h>\n#include <unistd.h>\n\nnamespace webrtc {\nconst long int E6 = 1000000;\nconst long int E9 = 1000 * E6;\n\nEventWrapper* EventPosix::Create()\n{\n    EventPosix* ptr = new EventPosix;\n    if (!ptr)\n    {\n        return NULL;\n    }\n\n    const int error = ptr->Construct();\n    if (error)\n    {\n        delete ptr;\n        return NULL;\n    }\n    return ptr;\n}\n\n\nEventPosix::EventPosix()\n    : _timerThread(0),\n      _timerEvent(0),\n      _periodic(false),\n      _time(0),\n      _count(0),\n      _state(kDown)\n{\n}\n\nint EventPosix::Construct()\n{\n    // Set start time to zero\n    memset(&_tCreate, 0, sizeof(_tCreate));\n\n    int result = pthread_mutex_init(&mutex, 0);\n    if (result != 0)\n    {\n        return -1;\n    }\n#ifdef WEBRTC_CLOCK_TYPE_REALTIME\n    result = pthread_cond_init(&cond, 0);\n    if (result != 0)\n    {\n        return -1;\n    }\n#else\n    pthread_condattr_t condAttr;\n    result = pthread_condattr_init(&condAttr);\n    if (result != 0)\n    {\n        return -1;\n    }\n    result = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC);\n    if (result != 0)\n    {\n        return -1;\n    }\n    result = pthread_cond_init(&cond, &condAttr);\n    if (result != 0)\n    {\n        return -1;\n    }\n    result = pthread_condattr_destroy(&condAttr);\n    if (result != 0)\n    {\n        return -1;\n    }\n#endif\n    return 0;\n}\n\nEventPosix::~EventPosix()\n{\n    StopTimer();\n    pthread_cond_destroy(&cond);\n    pthread_mutex_destroy(&mutex);\n}\n\nbool EventPosix::Reset()\n{\n    if (0 != pthread_mutex_lock(&mutex))\n    {\n        return false;\n    }\n    _state = kDown;\n    pthread_mutex_unlock(&mutex);\n    return true;\n}\n\nbool EventPosix::Set()\n{\n    if (0 != pthread_mutex_lock(&mutex))\n    {\n        return false;\n    }\n    _state = kUp;\n     // Release all waiting threads\n    pthread_cond_broadcast(&cond);\n    pthread_mutex_unlock(&mutex);\n    return true;\n}\n\nEventTypeWrapper EventPosix::Wait(unsigned long timeout)\n{\n    int retVal = 0;\n    if (0 != pthread_mutex_lock(&mutex))\n    {\n        return kEventError;\n    }\n\n    if (kDown == _state)\n    {\n        if (WEBRTC_EVENT_INFINITE != timeout)\n        {\n            timespec tEnd;\n#ifndef WEBRTC_MAC\n#ifdef WEBRTC_CLOCK_TYPE_REALTIME\n            clock_gettime(CLOCK_REALTIME, &tEnd);\n#else\n            clock_gettime(CLOCK_MONOTONIC, &tEnd);\n#endif\n#else\n            timeval tVal;\n            struct timezone tZone;\n            tZone.tz_minuteswest = 0;\n            tZone.tz_dsttime = 0;\n            gettimeofday(&tVal,&tZone);\n            TIMEVAL_TO_TIMESPEC(&tVal,&tEnd);\n#endif\n            tEnd.tv_sec  += timeout / 1000;\n            tEnd.tv_nsec += (timeout - (timeout / 1000) * 1000) * E6;\n\n            if (tEnd.tv_nsec >= E9)\n            {\n                tEnd.tv_sec++;\n                tEnd.tv_nsec -= E9;\n            }\n            retVal = pthread_cond_timedwait(&cond, &mutex, &tEnd);\n        } else {\n            retVal = pthread_cond_wait(&cond, &mutex);\n        }\n    }\n\n    _state = kDown;\n    pthread_mutex_unlock(&mutex);\n\n    switch(retVal)\n    {\n    case 0:\n        return kEventSignaled;\n    case ETIMEDOUT:\n        return kEventTimeout;\n    default:\n        return kEventError;\n    }\n}\n\nEventTypeWrapper EventPosix::Wait(timespec& tPulse)\n{\n    int retVal = 0;\n    if (0 != pthread_mutex_lock(&mutex))\n    {\n        return kEventError;\n    }\n\n    if (kUp != _state)\n    {\n        retVal = pthread_cond_timedwait(&cond, &mutex, &tPulse);\n    }\n    _state = kDown;\n\n    pthread_mutex_unlock(&mutex);\n\n    switch(retVal)\n    {\n    case 0:\n        return kEventSignaled;\n    case ETIMEDOUT:\n        return kEventTimeout;\n    default:\n        return kEventError;\n    }\n}\n\nbool EventPosix::StartTimer(bool periodic, unsigned long time)\n{\n    if (_timerThread)\n    {\n        if(_periodic)\n        {\n            // Timer already started.\n            return false;\n        } else  {\n            // New one shot timer\n            _time = time;\n            _tCreate.tv_sec = 0;\n            _timerEvent->Set();\n            return true;\n        }\n    }\n\n    // Start the timer thread\n    _timerEvent = static_cast<EventPosix*>(EventWrapper::Create());\n    const char* threadName = \"WebRtc_event_timer_thread\";\n    _timerThread = ThreadWrapper::CreateThread(Run, this, kRealtimePriority,\n                                               threadName);\n    _periodic = periodic;\n    _time = time;\n    unsigned int id = 0;\n    if (_timerThread->Start(id))\n    {\n        return true;\n    }\n    return false;\n}\n\nbool EventPosix::Run(ThreadObj obj)\n{\n    return static_cast<EventPosix*>(obj)->Process();\n}\n\nbool EventPosix::Process()\n{\n    if (_tCreate.tv_sec == 0)\n    {\n#ifndef WEBRTC_MAC\n#ifdef WEBRTC_CLOCK_TYPE_REALTIME\n        clock_gettime(CLOCK_REALTIME, &_tCreate);\n#else\n        clock_gettime(CLOCK_MONOTONIC, &_tCreate);\n#endif\n#else\n        timeval tVal;\n        struct timezone tZone;\n        tZone.tz_minuteswest = 0;\n        tZone.tz_dsttime = 0;\n        gettimeofday(&tVal,&tZone);\n        TIMEVAL_TO_TIMESPEC(&tVal,&_tCreate);\n#endif\n        _count=0;\n    }\n\n    timespec tEnd;\n    unsigned long long time = _time * ++_count;\n    tEnd.tv_sec  = _tCreate.tv_sec + time/1000;\n    tEnd.tv_nsec = _tCreate.tv_nsec + (time - (time/1000)*1000)*E6;\n\n    if ( tEnd.tv_nsec >= E9 )\n    {\n        tEnd.tv_sec++;\n        tEnd.tv_nsec -= E9;\n    }\n\n    switch(_timerEvent->Wait(tEnd))\n    {\n    case kEventSignaled:\n        return true;\n    case kEventError:\n        return false;\n    case kEventTimeout:\n        break;\n    }\n    if(_periodic || _count==1)\n    {\n        Set();\n    }\n    return true;\n}\n\nbool EventPosix::StopTimer()\n{\n    if(_timerThread)\n    {\n        _timerThread->SetNotAlive();\n    }\n    if (_timerEvent)\n    {\n        _timerEvent->Set();\n    }\n    if (_timerThread)\n    {\n        if(!_timerThread->Stop())\n        {\n            return false;\n        }\n\n        delete _timerThread;\n        _timerThread = 0;\n    }\n    if (_timerEvent)\n    {\n        delete _timerEvent;\n        _timerEvent = 0;\n    }\n\n    // Set time to zero to force new reference time for the timer.\n    memset(&_tCreate, 0, sizeof(_tCreate));\n    _count=0;\n    return true;\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/event_posix.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_POSIX_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_POSIX_H_\n\n#include \"event_wrapper.h\"\n\n#include <pthread.h>\n#include <time.h>\n\n#include \"thread_wrapper.h\"\n\nnamespace webrtc {\nenum State\n{\n    kUp = 1,\n    kDown = 2\n};\n\nclass EventPosix : public EventWrapper\n{\npublic:\n    static EventWrapper* Create();\n\n    virtual ~EventPosix();\n\n    virtual EventTypeWrapper Wait(unsigned long maxTime);\n    virtual bool Set();\n    virtual bool Reset();\n\n    virtual bool StartTimer(bool periodic, unsigned long time);\n    virtual bool StopTimer();\n\nprivate:\n    EventPosix();\n    int Construct();\n\n    static bool Run(ThreadObj obj);\n    bool Process();\n    EventTypeWrapper Wait(timespec& tPulse);\n\n\nprivate:\n    pthread_cond_t  cond;\n    pthread_mutex_t mutex;\n\n    ThreadWrapper* _timerThread;\n    EventPosix*    _timerEvent;\n    timespec       _tCreate;\n\n    bool          _periodic;\n    unsigned long _time;  // In ms\n    unsigned long _count;\n    State         _state;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_POSIX_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/event_windows.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"event_windows.h\"\n\n#include \"Mmsystem.h\"\n\nnamespace webrtc {\nEventWindows::EventWindows()\n    : _event(::CreateEvent(NULL  /* security attributes */,\n                           FALSE /* manual reset */,\n                           FALSE /* initial state */,\n                           NULL  /* name of event */)),\n      _timerID(NULL)\n{\n}\n\nEventWindows::~EventWindows()\n{\n    CloseHandle(_event);\n}\n\nbool EventWindows::Set()\n{\n    // Note: setting an event that is already set has no effect.\n    return SetEvent(_event);\n}\n\nbool EventWindows::Reset()\n{\n    return ResetEvent(_event);\n}\n\nEventTypeWrapper EventWindows::Wait(unsigned long maxTime)\n{\n    unsigned long res = WaitForSingleObject(_event, maxTime);\n    switch(res)\n    {\n    case WAIT_OBJECT_0:\n        return kEventSignaled;\n    case WAIT_TIMEOUT:\n        return kEventTimeout;\n    default:\n        return kEventError;\n    }\n}\n\nbool EventWindows::StartTimer(bool periodic, unsigned long time)\n{\n    if (_timerID != NULL)\n    {\n        timeKillEvent(_timerID);\n        _timerID=NULL;\n    }\n    if (periodic)\n    {\n        _timerID=timeSetEvent(time, 0,(LPTIMECALLBACK)HANDLE(_event),0,\n                              TIME_PERIODIC|TIME_CALLBACK_EVENT_PULSE);\n    } else {\n        _timerID=timeSetEvent(time, 0,(LPTIMECALLBACK)HANDLE(_event),0,\n                              TIME_ONESHOT|TIME_CALLBACK_EVENT_SET);\n    }\n\n    if (_timerID == NULL)\n    {\n        return false;\n    }\n    return true;\n}\n\nbool EventWindows::StopTimer()\n{\n    timeKillEvent(_timerID);\n    _timerID = NULL;\n    return true;\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/event_windows.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WINDOWS_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WINDOWS_H_\n\n#include <windows.h>\n\n#include \"event_wrapper.h\"\n\n#include \"typedefs.h\"\n\nnamespace webrtc {\nclass EventWindows : public EventWrapper\n{\npublic:\n    EventWindows();\n    virtual ~EventWindows();\n\n    virtual EventTypeWrapper Wait(unsigned long maxTime);\n    virtual bool Set();\n    virtual bool Reset();\n\n    virtual bool StartTimer(bool periodic, unsigned long time);\n    virtual bool StopTimer();\n\nprivate:\n    HANDLE  _event;\n    WebRtc_UWord32 _timerID;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WINDOWS_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/file_impl.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"file_impl.h\"\n\n#include <cassert>\n\n#ifdef _WIN32\n    #include <Windows.h>\n#else\n    #include <stdarg.h>\n    #include <string.h>\n#endif\n\nnamespace webrtc {\nFileWrapper* FileWrapper::Create()\n{\n    return new FileWrapperImpl();\n}\n\nFileWrapperImpl::FileWrapperImpl()\n    : _id(NULL),\n      _open(false),\n      _looping(false),\n      _readOnly(false),\n      _text(false),\n      _maxSizeInBytes(-1),\n      _sizeInBytes(0)\n{\n    memset(_fileNameUTF8, 0, kMaxFileNameSize);\n}\n\nFileWrapperImpl::~FileWrapperImpl()\n{\n    if (_id != NULL)\n    {\n        fclose(_id);\n    }\n}\n\nWebRtc_Word32 FileWrapperImpl::CloseFile()\n{\n    if (_id != NULL)\n    {\n        fclose(_id);\n        _id = NULL;\n    }\n    memset(_fileNameUTF8, 0, kMaxFileNameSize);\n    _open = false;\n    return 0;\n}\n\nint FileWrapperImpl::Rewind()\n{\n    if(_looping || !_readOnly)\n    {\n        if (_id != NULL)\n        {\n            _sizeInBytes = 0;\n            return fseek(_id, 0, SEEK_SET);\n        }\n    }\n    return -1;\n}\n\nWebRtc_Word32 FileWrapperImpl::SetMaxFileSize(WebRtc_Word32 bytes)\n{\n    _maxSizeInBytes = bytes;\n    return 0;\n}\n\nWebRtc_Word32 FileWrapperImpl::Flush()\n{\n    if (_id != NULL)\n    {\n        return fflush(_id);\n    }\n    return -1;\n}\n\nWebRtc_Word32 FileWrapperImpl::FileName(WebRtc_Word8* fileNameUTF8,\n                                        WebRtc_UWord32 size) const\n{\n    WebRtc_Word32 len = static_cast<WebRtc_Word32>(strlen(_fileNameUTF8));\n    if(len > kMaxFileNameSize)\n    {\n        assert(false);\n        return -1;\n    }\n    if(len < 1)\n    {\n        return -1;\n    }\n    // Make sure to NULL terminate\n    if(size < (WebRtc_UWord32)len)\n    {\n        len = size - 1;\n    }\n    memcpy(fileNameUTF8, _fileNameUTF8, len);\n    fileNameUTF8[len] = 0;\n    return 0;\n}\n\nbool\nFileWrapperImpl::Open() const\n{\n    return _open;\n}\n\nWebRtc_Word32 FileWrapperImpl::OpenFile(const WebRtc_Word8 *fileNameUTF8,\n                                        const bool readOnly, const bool loop,\n                                        const bool text)\n{\n    WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8);\n    if (length > kMaxFileNameSize)\n    {\n        return -1;\n    }\n\n    _readOnly = readOnly;\n\n    FILE *tmpId = NULL;\n#if defined _WIN32\n    wchar_t wideFileName[kMaxFileNameSize];\n    wideFileName[0] = 0;\n\n    MultiByteToWideChar(CP_UTF8,\n                        0 /*UTF8 flag*/,\n                        fileNameUTF8,\n                        -1 /*Null terminated string*/,\n                        wideFileName,\n                        kMaxFileNameSize);\n    if(text)\n    {\n        if(readOnly)\n        {\n            tmpId = _wfopen(wideFileName, L\"rt\");\n        } else {\n            tmpId = _wfopen(wideFileName, L\"wt\");\n        }\n    } else {\n        if(readOnly)\n        {\n            tmpId = _wfopen(wideFileName, L\"rb\");\n        } else {\n            tmpId = _wfopen(wideFileName, L\"wb\");\n        }\n    }\n#else\n    if(text)\n    {\n        if(readOnly)\n        {\n            tmpId = fopen(fileNameUTF8, \"rt\");\n        } else {\n            tmpId = fopen(fileNameUTF8, \"wt\");\n        }\n    } else {\n        if(readOnly)\n        {\n            tmpId = fopen(fileNameUTF8, \"rb\");\n        } else {\n            tmpId = fopen(fileNameUTF8, \"wb\");\n        }\n    }\n#endif\n\n    if (tmpId != NULL)\n    {\n        // + 1 comes fro copying the NULL termination charachter too\n        memcpy(_fileNameUTF8, fileNameUTF8, length + 1);\n        if (_id != NULL)\n        {\n            fclose(_id);\n        }\n        _id = tmpId;\n        _looping = loop;\n        _open = true;\n        return 0;\n    }\n    return -1;\n}\n\nint FileWrapperImpl::Read(void *buf, int len)\n{\n    if(len < 0)\n    {\n        return 0;\n    }\n    if (_id != NULL)\n    {\n        WebRtc_Word32 res = static_cast<WebRtc_Word32>(fread(buf, 1, len, _id));\n        if (res != len)\n        {\n            if(!_looping)\n            {\n                CloseFile();\n            }\n        }\n        return res;\n    }\n    return -1;\n}\n\nWebRtc_Word32 FileWrapperImpl::WriteText(const WebRtc_Word8* text, ...)\n{\n    assert(!_readOnly);\n    assert(!_text);\n\n    if (_id == NULL)\n    {\n        return -1;\n    }\n\n    char tempBuff[kFileMaxTextMessageSize];\n    if (text)\n    {\n        va_list args;\n        va_start(args, text);\n#ifdef _WIN32\n        _vsnprintf(tempBuff, kFileMaxTextMessageSize-1, text, args);\n#else\n        vsnprintf(tempBuff, kFileMaxTextMessageSize-1, text, args);\n#endif\n        va_end(args);\n        WebRtc_Word32 nBytes;\n        nBytes = fprintf(_id, \"%s\", tempBuff);\n        if (nBytes > 0)\n        {\n            return 0;\n        }\n        CloseFile();\n    }\n    return -1;\n}\n\nbool FileWrapperImpl::Write(const void* buf, int len)\n{\n    assert(!_readOnly);\n    if (_id != NULL)\n    {\n        // Check if it's time to stop writing.\n        if ((_maxSizeInBytes != -1) &&\n             _sizeInBytes + len > (WebRtc_UWord32)_maxSizeInBytes)\n        {\n            Flush();\n            return false;\n        }\n\n        size_t nBytes = fwrite((WebRtc_UWord8*)buf, 1, len, _id);\n        if (nBytes > 0)\n        {\n            _sizeInBytes += static_cast<WebRtc_Word32>(nBytes);\n            return true;\n        }\n        CloseFile();\n    }\n    return false;\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/file_impl.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_FILE_IMPL_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_FILE_IMPL_H_\n\n#include \"file_wrapper.h\"\n\n#include <stdio.h>\n\nnamespace webrtc {\nclass FileWrapperImpl : public FileWrapper\n{\npublic:\n    FileWrapperImpl();\n    virtual ~FileWrapperImpl();\n\n    virtual WebRtc_Word32 FileName(WebRtc_Word8* fileNameUTF8,\n                                   WebRtc_UWord32 size) const;\n\n    virtual bool Open() const;\n\n    virtual WebRtc_Word32 OpenFile(const WebRtc_Word8* fileNameUTF8,\n                                 const bool readOnly,\n                                 const bool loop = false,\n                                 const bool text = false);\n\n    virtual WebRtc_Word32 CloseFile();\n    virtual WebRtc_Word32 SetMaxFileSize(WebRtc_Word32 bytes);\n    virtual WebRtc_Word32 Flush();\n\n    virtual int Read(void* buf, int len);\n    virtual bool Write(const void *buf, int len);\n    virtual int Rewind();\n\n    virtual WebRtc_Word32 WriteText(const WebRtc_Word8* text, ...);\n\nprivate:\n    FILE*          _id;\n    bool           _open;\n    bool           _looping;\n    bool           _readOnly;\n    bool           _text;\n    WebRtc_Word32  _maxSizeInBytes; // -1 indicates file size limitation is off\n    WebRtc_UWord32 _sizeInBytes;\n    WebRtc_Word8   _fileNameUTF8[kMaxFileNameSize];\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_FILE_IMPL_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/list_no_stl.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"list_wrapper.h\"\n\n#include \"critical_section_wrapper.h\"\n#include \"trace.h\"\n\nnamespace webrtc {\nListItem::ListItem(const void* item)\n    : next_(0),\n      prev_(0),\n      item_ptr_(item),\n      item_(0)\n{\n}\n\nListItem::ListItem(const unsigned int item)\n    : next_(0),\n      prev_(0),\n      item_ptr_(0),\n      item_(item)\n{\n}\n\nListItem::~ListItem()\n{\n}\n\nvoid* ListItem::GetItem() const\n{\n    return const_cast<void*>(item_ptr_);\n}\n\nunsigned int ListItem::GetUnsignedItem() const\n{\n    return item_;\n}\n\nListWrapper::ListWrapper()\n    : critical_section_(CriticalSectionWrapper::CreateCriticalSection()),\n      first_(0),\n      last_(0),\n      size_(0)\n{\n}\n\nListWrapper::~ListWrapper()\n{\n    if (!Empty())\n    {\n        // TODO (hellner) I'm not sure this loggin is useful.\n        WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1,\n                   \"Potential memory leak in ListWrapper\");\n        // Remove all remaining list items.\n        while (Erase(First()) == 0)\n        {}\n    }\n    delete critical_section_;\n}\n\nbool ListWrapper::Empty() const\n{\n    return !first_ && !last_;\n}\n\nunsigned int ListWrapper::GetSize() const\n{\n    return size_;\n}\n\nint ListWrapper::PushBack(const void* ptr)\n{\n    ListItem* item = new ListItem(ptr);\n    CriticalSectionScoped lock(*critical_section_);\n    PushBackImpl(item);\n    return 0;\n}\n\nint ListWrapper::PushBack(const unsigned int item_id)\n{\n    ListItem* item = new ListItem(item_id);\n    CriticalSectionScoped lock(*critical_section_);\n    PushBackImpl(item);\n    return 0;\n}\n\nint ListWrapper::PushFront(const unsigned int item_id)\n{\n    ListItem* item = new ListItem(item_id);\n    CriticalSectionScoped lock(*critical_section_);\n    PushFrontImpl(item);\n    return 0;\n}\n\nint ListWrapper::PushFront(const void* ptr)\n{\n    ListItem* item = new ListItem(ptr);\n    CriticalSectionScoped lock(*critical_section_);\n    PushFrontImpl(item);\n    return 0;\n}\n\nint ListWrapper::PopFront()\n{\n    return Erase(first_);\n}\n\nint ListWrapper::PopBack()\n{\n    return Erase(last_);\n}\n\nListItem* ListWrapper::First() const\n{\n    return first_;\n}\n\nListItem* ListWrapper::Last() const\n{\n    return last_;\n}\n\nListItem* ListWrapper::Next(ListItem* item) const\n{\n    if(!item)\n    {\n        return 0;\n    }\n    return item->next_;\n}\n\nListItem* ListWrapper::Previous(ListItem* item) const\n{\n    if (!item)\n    {\n        return 0;\n    }\n    return item->prev_;\n}\n\nint ListWrapper::Insert(ListItem* existing_previous_item, ListItem* new_item)\n{\n    if (!new_item)\n    {\n        return -1;\n    }\n    // Allow existing_previous_item to be NULL if the list is empty.\n    // TODO (hellner) why allow this? Keep it as is for now to avoid\n    // breaking API contract.\n    if (!existing_previous_item && !Empty())\n    {\n        return -1;\n    }\n    CriticalSectionScoped lock(*critical_section_);\n    if (!existing_previous_item)\n    {\n        PushBackImpl(new_item);\n        return 0;\n    }\n    ListItem* next_item = existing_previous_item->next_;\n    new_item->next_ = existing_previous_item->next_;\n    new_item->prev_ = existing_previous_item;\n    existing_previous_item->next_ = new_item;\n    if (next_item)\n    {\n        next_item->prev_ = new_item;\n    }\n    else\n    {\n        last_ = new_item;\n    }\n    size_++;\n    return 0;\n}\n\nint ListWrapper::InsertBefore(ListItem* existing_next_item,\n                              ListItem* new_item)\n{\n    if (!new_item)\n    {\n        return -1;\n    }\n    // Allow existing_next_item to be NULL if the list is empty.\n    // Todo: why allow this? Keep it as is for now to avoid breaking API\n    // contract.\n    if (!existing_next_item && !Empty())\n    {\n        return -1;\n    }\n    CriticalSectionScoped lock(*critical_section_);\n    if (!existing_next_item)\n    {\n        PushBackImpl(new_item);\n        return 0;\n    }\n\n    ListItem* previous_item = existing_next_item->prev_;\n    new_item->next_ = existing_next_item;\n    new_item->prev_ = previous_item;\n    existing_next_item->prev_ = new_item;\n    if (previous_item)\n    {\n        previous_item->next_ = new_item;\n    }\n    else\n    {\n        first_ = new_item;\n    }\n    size_++;\n    return 0;\n}\n\nint ListWrapper::Erase(ListItem* item)\n{\n    if (!item)\n    {\n        return -1;\n    }\n    size_--;\n    ListItem* previous_item = item->prev_;\n    ListItem* next_item = item->next_;\n    if (!previous_item)\n    {\n        if(next_item)\n        {\n            next_item->prev_ = 0;\n        }\n        first_ = next_item;\n    }\n    else\n    {\n        previous_item->next_ = next_item;\n    }\n    if (!next_item)\n    {\n        if(previous_item)\n        {\n            previous_item->next_ = 0;\n        }\n        last_ = previous_item;\n    }\n    else\n    {\n        next_item->prev_ = previous_item;\n    }\n    delete item;\n    return 0;\n}\n\nvoid ListWrapper::PushBackImpl(ListItem* item)\n{\n    if (Empty())\n    {\n        first_ = item;\n        last_ = item;\n        size_++;\n        return;\n    }\n\n    item->prev_ = last_;\n    last_->next_ = item;\n    last_ = item;\n    size_++;\n}\n\nvoid ListWrapper::PushFrontImpl(ListItem* item)\n{\n    if (Empty())\n    {\n        first_ = item;\n        last_ = item;\n        size_++;\n        return;\n    }\n\n    item->next_ = first_;\n    first_->prev_ = item;\n    first_ = item;\n    size_++;\n}\n} //namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/list_no_stl.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_NO_STL_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_NO_STL_H_\n\n#include \"constructor_magic.h\"\n\nnamespace webrtc {\nclass CriticalSectionWrapper;\n\nclass ListNoStlItem\n{\npublic:\n    ListNoStlItem(const void* ptr);\n    ListNoStlItem(const unsigned int item);\n    virtual ~ListNoStlItem();\n    void* GetItem() const;\n    unsigned int GetUnsignedItem() const;\n\nprotected:\n    ListNoStlItem* next_;\n    ListNoStlItem* prev_;\n\nprivate:\n    friend class ListNoStl;\n\n    const void*         item_ptr_;\n    const unsigned int  item_;\n    DISALLOW_COPY_AND_ASSIGN(ListNoStlItem);\n};\n\n\nclass ListNoStl\n{\npublic:\n    ListNoStl();\n    virtual ~ListNoStl();\n\n    // ListWrapper functions\n    unsigned int GetSize() const;\n    int PushBack(const void* ptr);\n    int PushBack(const unsigned int item_id);\n    int PushFront(const void* ptr);\n    int PushFront(const unsigned int item_id);\n    int PopFront();\n    int PopBack();\n    bool Empty() const;\n    ListNoStlItem* First() const;\n    ListNoStlItem* Last() const;\n    ListNoStlItem* Next(ListNoStlItem* item) const;\n    ListNoStlItem* Previous(ListNoStlItem* item) const;\n    int Erase(ListNoStlItem* item);\n    int Insert(ListNoStlItem* existing_previous_item,\n               ListNoStlItem* new_item);\n\n    int InsertBefore(ListNoStlItem* existing_next_item,\n                     ListNoStlItem* new_item);\n\nprivate:\n    void PushBack(ListNoStlItem* item);\n    void PushFront(ListNoStlItem* item);\n\n    CriticalSectionWrapper* critical_section_;\n    ListNoStlItem* first_;\n    ListNoStlItem* last_;\n    unsigned int size_;\n    DISALLOW_COPY_AND_ASSIGN(ListNoStl);\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_NO_STL_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/list_stl.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"list_wrapper.h\"\n\n#include \"trace.h\"\n\nnamespace webrtc {\nListItem::ListItem(const void* item)\n    : this_iter_(),\n      item_ptr_(item),\n      item_(0)\n{\n}\n\nListItem::ListItem(const unsigned int item)\n    : this_iter_(),\n      item_ptr_(0),\n      item_(item)\n{\n}\n\nListItem::~ListItem()\n{\n}\n\nvoid* ListItem::GetItem() const\n{\n    return const_cast<void*>(item_ptr_);\n}\n\nunsigned int ListItem::GetUnsignedItem() const\n{\n    return item_;\n}\n\nListWrapper::ListWrapper() : list_()\n{\n}\n\nListWrapper::~ListWrapper()\n{\n    if (!Empty())\n    {\n        // TODO (hellner) I'm not sure this loggin is useful.\n        WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1,\n                   \"Potential memory leak in ListWrapper\");\n        // Remove all remaining list items.\n        while (Erase(First()) == 0)\n        {}\n    }\n}\n\nbool ListWrapper::Empty() const\n{\n    return list_.empty();\n}\n\nunsigned int ListWrapper::GetSize() const\n{\n    return list_.size();\n}\n\nint ListWrapper::PushBack(const void* ptr)\n{\n    ListItem* item = new ListItem(ptr);\n    list_.push_back(item);\n    return 0;\n}\n\nint ListWrapper::PushBack(const unsigned int item_id)\n{\n    ListItem* item = new ListItem(item_id);\n    list_.push_back(item);\n    return 0;\n}\n\nint ListWrapper::PushFront(const unsigned int item_id)\n{\n    ListItem* item = new ListItem(item_id);\n    list_.push_front(item);\n    return 0;\n}\n\nint ListWrapper::PushFront(const void* ptr)\n{\n    ListItem* item = new ListItem(ptr);\n    list_.push_front(item);\n    return 0;\n}\n\nint ListWrapper::PopFront()\n{\n    if(list_.empty())\n    {\n        return -1;\n    }\n    list_.pop_front();\n    return 0;\n}\n\nint ListWrapper::PopBack()\n{\n    if(list_.empty())\n    {\n        return -1;\n    }\n    list_.pop_back();\n    return 0;\n}\n\nListItem* ListWrapper::First() const\n{\n    if(list_.empty())\n    {\n        return NULL;\n    }\n    std::list<ListItem*>::iterator item_iter = list_.begin();\n    ListItem* return_item = (*item_iter);\n    return_item->this_iter_ = item_iter;\n    return return_item;\n}\n\nListItem* ListWrapper::Last() const\n{\n    if(list_.empty())\n    {\n        return NULL;\n    }\n    // std::list::end() addresses the last item + 1. Decrement so that the\n    // actual last is accessed.\n    std::list<ListItem*>::iterator item_iter = list_.end();\n    --item_iter;\n    ListItem* return_item = (*item_iter);\n    return_item->this_iter_ = item_iter;\n    return return_item;\n}\n\nListItem* ListWrapper::Next(ListItem* item) const\n{\n    if(item == NULL)\n    {\n        return NULL;\n    }\n    std::list<ListItem*>::iterator item_iter = item->this_iter_;\n    ++item_iter;\n    if (item_iter == list_.end())\n    {\n        return NULL;\n    }\n    ListItem* return_item = (*item_iter);\n    return_item->this_iter_ = item_iter;\n    return return_item;\n}\n\nListItem* ListWrapper::Previous(ListItem* item) const\n{\n    if(item == NULL)\n    {\n        return NULL;\n    }\n    std::list<ListItem*>::iterator item_iter = item->this_iter_;\n    if (item_iter == list_.begin())\n    {\n      return NULL;\n    }\n    --item_iter;\n    ListItem* return_item = (*item_iter);\n    return_item->this_iter_ = item_iter;\n    return return_item;\n}\n\nint ListWrapper::Insert(ListItem* existing_previous_item,\n                        ListItem* new_item)\n{\n    // Allow existingPreviousItem to be NULL if the list is empty.\n    // TODO (hellner) why allow this? Keep it as is for now to avoid\n    // breaking API contract.\n    if (!existing_previous_item && !Empty())\n    {\n        return -1;\n    }\n\n    if (!new_item)\n    {\n        return -1;\n    }\n\n    std::list<ListItem*>::iterator insert_location = list_.begin();\n    if (!Empty())\n    {\n        insert_location = existing_previous_item->this_iter_;\n        if(insert_location != list_.end())\n        {\n            ++insert_location;\n        }\n    }\n\n    list_.insert(insert_location,new_item);\n    return 0;\n}\n\nint ListWrapper::InsertBefore(ListItem* existing_next_item,\n                           ListItem* new_item)\n{\n    // Allow existing_next_item to be NULL if the list is empty.\n    // Todo: why allow this? Keep it as is for now to avoid breaking API\n    // contract.\n    if (!existing_next_item && !Empty())\n    {\n        return -1;\n    }\n    if (!new_item)\n    {\n        return -1;\n    }\n\n    std::list<ListItem*>::iterator insert_location = list_.begin();\n    if (!Empty())\n    {\n        insert_location = existing_next_item->this_iter_;\n    }\n\n    list_.insert(insert_location,new_item);\n    return 0;\n}\n\nint ListWrapper::Erase(ListItem* item)\n{\n    if(item == NULL)\n    {\n        return -1;\n    }\n    list_.erase(item->this_iter_);\n    return 0;\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/list_stl.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_STL_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_STL_H_\n\n#include <list>\n\n#include \"constructor_magic.h\"\n\nnamespace webrtc {\nclass ListItem\n{\nfriend class ListWrapper;\n\npublic:\n    ListItem(const void* ptr);\n    ListItem(const unsigned int item);\n    virtual ~ListItem();\n    void* GetItem() const;\n    unsigned int GetUnsignedItem() const;\n\nprivate:\n    mutable std::list<ListItem*>::iterator this_iter_;\n    const void*         item_ptr_;\n    const unsigned int  item_;\n    DISALLOW_COPY_AND_ASSIGN(ListItem);\n};\n\nclass ListWrapper\n{\npublic:\n    ListWrapper();\n    ~ListWrapper();\n\n    // ListWrapper functions\n    unsigned int GetSize() const;\n    int PushBack(const void* ptr);\n    int PushBack(const unsigned int item_id);\n    int PushFront(const void* ptr);\n    int PushFront(const unsigned int item_id);\n    int PopFront();\n    int PopBack();\n    bool Empty() const;\n    ListItem* First() const;\n    ListItem* Last() const;\n    ListItem* Next(ListItem* item) const;\n    ListItem* Previous(ListItem* item) const;\n    int Erase(ListItem* item);\n    int Insert(ListItem* existing_previous_item, ListItem* new_item);\n    int InsertBefore(ListItem* existing_next_item, ListItem* new_item);\n\nprivate:\n    mutable std::list<ListItem*> list_;\n    DISALLOW_COPY_AND_ASSIGN(ListWrapper);\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_STL_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/list_unittest.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"gtest/gtest.h\"\n\n#include \"list_wrapper.h\"\n\nusing ::webrtc::ListWrapper;\nusing ::webrtc::ListItem;\n\n// Note: kNumberOfElements needs to be even.\nconst unsigned int kNumberOfElements = 10;\n\n// An opaque implementation of dynamic or statically allocated unsigned ints.\n// This class makes it possible to use the exact same code for testing of both\n// the dynamic and static implementation of ListWrapper.\n// Clarification: ListWrapper has two versions of PushBack(..). It takes an\n// unsigned integer or a void pointer. The integer implementation takes care\n// of memory management. The void pointer version expect the caller to manage\n// the memory associated with the void pointer.\n// This class works like the integer version but can be implemented on top of\n// either the integer version or void pointer version of ListWrapper.\n// Note: the non-virtual fuctions behave the same for both versions.\nclass ListWrapperSimple {\npublic:\n    static ListWrapperSimple* Create(bool static_allocation);\n    virtual ~ListWrapperSimple() {}\n\n    // These three functions should be used for manipulating ListItems so that\n    // they are the type corresponding to the underlying implementation.\n    virtual unsigned int GetUnsignedItem(\n        const ListItem* item) const = 0;\n    virtual ListItem* CreateListItem(unsigned int item_id) = 0;\n    virtual bool DestroyListItem(ListItem* item) = 0;\n\n    unsigned int GetSize() const {\n        return list_.GetSize();\n    }\n    virtual int PushBack(const unsigned int item_id) = 0;\n    virtual int PushFront(const unsigned int item_id) = 0;\n    virtual int PopFront() = 0;\n    virtual int PopBack() = 0;\n    bool Empty() const {\n        return list_.Empty();\n    }\n    ListItem* First() const {\n        return list_.First();\n    }\n    ListItem* Last() const {\n        return list_.Last();\n    }\n    ListItem* Next(ListItem* item) const {\n        return list_.Next(item);\n    }\n    ListItem* Previous(ListItem* item) const {\n        return list_.Previous(item);\n    }\n    virtual int Erase(ListItem* item) = 0;\n    int Insert(ListItem* existing_previous_item,\n                       ListItem* new_item) {\n        return list_.Insert(existing_previous_item, new_item);\n    }\n\n    int InsertBefore(ListItem* existing_next_item,\n                             ListItem* new_item) {\n        return list_.InsertBefore(existing_next_item, new_item);\n    }\nprotected:\n    ListWrapperSimple() {}\n\n    ListWrapper list_;\n};\n\nclass ListWrapperStatic : public ListWrapperSimple {\npublic:\n    ListWrapperStatic() {}\n    virtual ~ListWrapperStatic() {}\n\n    virtual unsigned int GetUnsignedItem(const ListItem* item) const {\n        return item->GetUnsignedItem();\n    }\n    virtual ListItem* CreateListItem(unsigned int item_id) {\n        return new ListItem(item_id);\n    }\n    virtual bool DestroyListItem(ListItem* item) {\n        if (item == NULL) {\n            return false;\n        }\n        delete item;\n        return true;\n    }\n    virtual int PushBack(const unsigned int item_id) {\n        return list_.PushBack(item_id);\n    }\n    virtual int PushFront(const unsigned int item_id) {\n        return list_.PushFront(item_id);\n    }\n    virtual int PopFront() {\n        return list_.PopFront();\n    }\n    virtual int PopBack() {\n        return list_.PopBack();\n    }\n    virtual int Erase(ListItem* item) {\n        return list_.Erase(item);\n    }\n};\n\nclass ListWrapperDynamic : public ListWrapperSimple {\npublic:\n    ListWrapperDynamic() {}\n    virtual ~ListWrapperDynamic() {}\n\n    virtual unsigned int GetUnsignedItem(const ListItem* item) const {\n        const unsigned int* return_value_pointer =\n            reinterpret_cast<unsigned int*> (item->GetItem());\n        if (return_value_pointer == NULL) {\n            return -1;\n        }\n        return *return_value_pointer;\n    }\n    virtual ListItem* CreateListItem(unsigned int item_id) {\n        unsigned int* item_id_pointer = new unsigned int;\n        if (item_id_pointer == NULL) {\n            return NULL;\n        }\n        *item_id_pointer = item_id;\n        ListItem* return_value = new ListItem(\n            reinterpret_cast<void*>(item_id_pointer));\n        if (return_value == NULL) {\n            delete item_id_pointer;\n            return NULL;\n        }\n        return return_value;\n    }\n    virtual bool DestroyListItem(ListItem* item) {\n        if (item == NULL) {\n            return false;\n        }\n        bool return_value = false;\n        unsigned int* item_id_ptr = reinterpret_cast<unsigned int*>(\n            item->GetItem());\n        if (item_id_ptr != NULL) {\n            return_value = true;\n            delete item_id_ptr;\n        }\n        delete item;\n        return return_value;\n    }\n    virtual int PushBack(const unsigned int item_id) {\n        unsigned int* item_id_ptr = new unsigned int;\n        if (item_id_ptr == NULL) {\n            return -1;\n        }\n        *item_id_ptr = item_id;\n        const int return_value = list_.PushBack(\n            reinterpret_cast<void*>(item_id_ptr));\n        if (return_value != 0) {\n            delete item_id_ptr;\n        }\n        return return_value;\n    }\n    virtual int PushFront(const unsigned int item_id) {\n        unsigned int* item_id_ptr = new unsigned int;\n        if (item_id_ptr == NULL) {\n            return -1;\n        }\n        *item_id_ptr = item_id;\n        const int return_value = list_.PushFront(\n            reinterpret_cast<void*>(item_id_ptr));\n        if (return_value != 0) {\n            delete item_id_ptr;\n        }\n        return return_value;\n    }\n    virtual int PopFront() {\n        return Erase(list_.First());\n    }\n    virtual int PopBack() {\n        return Erase(list_.Last());\n    }\n    virtual int Erase(ListItem* item) {\n        if (item == NULL) {\n            return -1;\n        }\n        unsigned int* item_id_ptr = reinterpret_cast<unsigned int*> (\n            item->GetItem());\n        int return_value = -1;\n        if (item_id_ptr != NULL) {\n            delete item_id_ptr;\n            return_value = 0;\n        }\n        if (list_.Erase(item) != 0) {\n            return -1;\n        }\n        return return_value;\n    }\n};\n\nListWrapperSimple* ListWrapperSimple::Create(bool static_allocation) {\n    if(static_allocation)\n    {\n        return new ListWrapperStatic();\n    }\n    return new ListWrapperDynamic();\n}\n\nvoid ClearList(ListWrapperSimple* list) {\n    if (list == NULL)\n    {\n        return;\n    }\n    while (list->Erase(list->First()) == 0) {\n    }\n}\n\nListWrapperSimple* CreateAscendingList(bool static_allocation) {\n    ListWrapperSimple* return_value = ListWrapperSimple::Create(\n        static_allocation);\n    if (return_value == NULL) {\n        return NULL;\n    }\n    for (unsigned int i = 0; i < kNumberOfElements; ++i) {\n        if (return_value->PushBack(i) == -1) {\n            ClearList(return_value);\n            delete return_value;\n            return NULL;\n        }\n    }\n    return return_value;\n}\n\nListWrapperSimple* CreateDecendingList(bool static_allocation) {\n    ListWrapperSimple* return_value = ListWrapperSimple::Create(\n        static_allocation);\n    if (return_value == NULL) {\n        return NULL;\n    }\n    for (unsigned int i = 0; i < kNumberOfElements; ++i) {\n        if (return_value->PushBack(kNumberOfElements - i - 1) == -1) {\n            ClearList(return_value);\n            delete return_value;\n            return NULL;\n        }\n    }\n    return return_value;\n}\n\n// [0,kNumberOfElements - 1,1,kNumberOfElements - 2,...] (this is why\n// kNumberOfElements need to be even)\nListWrapperSimple* CreateInterleavedList(bool static_allocation) {\n    ListWrapperSimple* return_value = ListWrapperSimple::Create(\n        static_allocation);\n    if (return_value == NULL) {\n        return NULL;\n    }\n    unsigned int uneven_count = 0;\n    unsigned int even_count = 0;\n    for (unsigned int i = 0; i < kNumberOfElements; i++) {\n        unsigned int push_value = 0;\n        if ((i % 2) == 0) {\n            push_value = even_count;\n            even_count++;\n        } else {\n            push_value = kNumberOfElements - uneven_count - 1;\n            uneven_count++;\n        }\n        if (return_value->PushBack(push_value) == -1) {\n            ClearList(return_value);\n            delete return_value;\n            return NULL;\n        }\n    }\n    return return_value;\n}\n\nvoid PrintList(const ListWrapperSimple* list) {\n    ListItem* list_item = list->First();\n    printf(\"[\");\n    while (list_item != NULL)\n    {\n        printf(\"%3u\", list->GetUnsignedItem(list_item));\n        list_item = list->Next(list_item);\n    }\n    printf(\"]\\n\");\n}\n\nbool CompareLists(const ListWrapperSimple* lhs, const ListWrapperSimple* rhs) {\n    const unsigned int list_size = lhs->GetSize();\n    if (lhs->GetSize() != rhs->GetSize()) {\n        return false;\n    }\n    if (lhs->Empty()) {\n        return rhs->Empty();\n    }\n    unsigned int i = 0;\n    ListItem* lhs_item = lhs->First();\n    ListItem* rhs_item = rhs->First();\n    while (i < list_size) {\n        if (lhs_item == NULL) {\n            return false;\n        }\n        if (rhs_item == NULL) {\n            return false;\n        }\n        if (lhs->GetUnsignedItem(lhs_item) != rhs->GetUnsignedItem(rhs_item)) {\n            return false;\n        }\n        i++;\n        lhs_item = lhs->Next(lhs_item);\n        rhs_item = rhs->Next(rhs_item);\n    }\n    return true;\n}\n\nTEST(ListWrapperTest,ReverseNewIntList) {\n    // Create a new temporary list with elements reversed those of\n    // new_int_list_\n    const ListWrapperSimple* decending_list = CreateDecendingList(rand()%2);\n    ASSERT_FALSE(decending_list == NULL);\n    ASSERT_FALSE(decending_list->Empty());\n    ASSERT_EQ(kNumberOfElements,decending_list->GetSize());\n\n    const ListWrapperSimple* ascending_list = CreateAscendingList(rand()%2);\n    ASSERT_FALSE(ascending_list == NULL);\n    ASSERT_FALSE(ascending_list->Empty());\n    ASSERT_EQ(kNumberOfElements,ascending_list->GetSize());\n\n    ListWrapperSimple* list_to_reverse = ListWrapperSimple::Create(rand()%2);\n\n    // Reverse the list using PushBack and Previous.\n    for (ListItem* item = ascending_list->Last(); item != NULL;\n         item = ascending_list->Previous(item)) {\n         list_to_reverse->PushBack(ascending_list->GetUnsignedItem(item));\n    }\n\n    ASSERT_TRUE(CompareLists(decending_list,list_to_reverse));\n\n    ListWrapperSimple* list_to_un_reverse =\n        ListWrapperSimple::Create(rand()%2);\n    ASSERT_FALSE(list_to_un_reverse == NULL);\n    // Reverse the reversed list using PushFront and Next.\n    for (ListItem* item = list_to_reverse->First(); item != NULL;\n         item = list_to_reverse->Next(item)) {\n         list_to_un_reverse->PushFront(list_to_reverse->GetUnsignedItem(item));\n    }\n\n    ASSERT_TRUE(CompareLists(ascending_list,list_to_un_reverse));\n}\n\nTEST(ListWrapperTest,PopTest) {\n    ListWrapperSimple* ascending_list = CreateAscendingList(rand()%2);\n    ASSERT_FALSE(ascending_list == NULL);\n    ASSERT_FALSE(ascending_list->Empty());\n    EXPECT_EQ(0,ascending_list->PopFront());\n    EXPECT_EQ(1,ascending_list->GetUnsignedItem(ascending_list->First()));\n\n    EXPECT_EQ(0,ascending_list->PopBack());\n    EXPECT_EQ(kNumberOfElements - 2,ascending_list->GetUnsignedItem(\n              ascending_list->Last()));\n    EXPECT_EQ(kNumberOfElements - 2, ascending_list->GetSize());\n}\n\n// Use Insert to interleave two lists.\nTEST(ListWrapperTest,InterLeaveTest) {\n    ListWrapperSimple* interleave_list = CreateAscendingList(rand()%2);\n    ASSERT_FALSE(interleave_list == NULL);\n    ASSERT_FALSE(interleave_list->Empty());\n\n    ListWrapperSimple* decending_list = CreateDecendingList(rand()%2);\n    ASSERT_FALSE(decending_list == NULL);\n\n    for (int i = 0; i < kNumberOfElements/2; ++i) {\n        ASSERT_EQ(0,interleave_list->PopBack());\n        ASSERT_EQ(0,decending_list->PopBack());\n    }\n    ASSERT_EQ(kNumberOfElements/2,interleave_list->GetSize());\n    ASSERT_EQ(kNumberOfElements/2,decending_list->GetSize());\n\n    int insert_position = kNumberOfElements/2;\n    ASSERT_EQ(insert_position * 2, kNumberOfElements);\n    while (!decending_list->Empty())\n    {\n        ListItem* item = decending_list->Last();\n        ASSERT_FALSE(item == NULL);\n\n        const unsigned int item_id = decending_list->GetUnsignedItem(item);\n        ASSERT_EQ(0,decending_list->Erase(item));\n\n        ListItem* insert_item = interleave_list->CreateListItem(item_id);\n        ASSERT_FALSE(insert_item == NULL);\n        item = interleave_list->First();\n        ASSERT_FALSE(item == NULL);\n        for (int j = 0; j < insert_position - 1; ++j) {\n            item = interleave_list->Next(item);\n            ASSERT_FALSE(item == NULL);\n        }\n        if (0 != interleave_list->Insert(item,insert_item)) {\n            interleave_list->DestroyListItem(insert_item);\n            FAIL();\n        }\n        --insert_position;\n    }\n\n    ListWrapperSimple* interleaved_list = CreateInterleavedList(rand()%2);\n    ASSERT_FALSE(interleaved_list == NULL);\n    ASSERT_FALSE(interleaved_list->Empty());\n\n    ASSERT_TRUE(CompareLists(interleaved_list,interleave_list));\n}\n\n// Use InsertBefore to interleave two lists.\nTEST(ListWrapperTest,InterLeaveTestII) {\n    ListWrapperSimple* interleave_list = CreateDecendingList(rand()%2);\n    ASSERT_FALSE(interleave_list == NULL);\n    ASSERT_FALSE(interleave_list->Empty());\n\n    ListWrapperSimple* ascending_list = CreateAscendingList(rand()%2);\n    ASSERT_FALSE(ascending_list == NULL);\n\n    for (int i = 0; i < kNumberOfElements/2; ++i) {\n        ASSERT_EQ(0,interleave_list->PopBack());\n        ASSERT_EQ(0,ascending_list->PopBack());\n    }\n    ASSERT_EQ(kNumberOfElements/2,interleave_list->GetSize());\n    ASSERT_EQ(kNumberOfElements/2,ascending_list->GetSize());\n\n    int insert_position = kNumberOfElements/2;\n    ASSERT_EQ(insert_position * 2, kNumberOfElements);\n    while (!ascending_list->Empty())\n    {\n        ListItem* item = ascending_list->Last();\n        ASSERT_FALSE(item == NULL);\n\n        const unsigned int item_id = ascending_list->GetUnsignedItem(item);\n        ASSERT_EQ(0,ascending_list->Erase(item));\n\n        ListItem* insert_item = interleave_list->CreateListItem(item_id);\n        ASSERT_FALSE(insert_item == NULL);\n        item = interleave_list->First();\n        ASSERT_FALSE(item == NULL);\n        for (int j = 0; j < insert_position - 1; ++j) {\n            item = interleave_list->Next(item);\n            ASSERT_FALSE(item == NULL);\n        }\n        if (0 != interleave_list->InsertBefore(item,insert_item)) {\n            interleave_list->DestroyListItem(insert_item);\n            FAIL();\n        }\n        --insert_position;\n    }\n\n    ListWrapperSimple* interleaved_list = CreateInterleavedList(rand()%2);\n    ASSERT_FALSE(interleaved_list == NULL);\n    ASSERT_FALSE(interleaved_list->Empty());\n\n    ASSERT_TRUE(CompareLists(interleaved_list,interleave_list));\n}\n\nint main(int argc, char **argv)\n{\n    ::testing::InitGoogleTest(&argc, argv);\n    // Added return_value so that it's convenient to put a breakpoint before\n    // exiting please note that the return value from RUN_ALL_TESTS() must\n    // be returned by the main function.\n    const int return_value = RUN_ALL_TESTS();\n    return return_value;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/map.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"map_wrapper.h\"\n\n#include \"trace.h\"\n\nnamespace webrtc {\nMapItem::MapItem(int id, void* item) : item_id_(id), item_pointer_(item)\n{\n}\n\nMapItem::~MapItem()\n{\n}\n\nvoid* MapItem::GetItem()\n{\n    return item_pointer_;\n}\n\nint MapItem::GetId()\n{\n    return item_id_;\n}\n\nunsigned int MapItem::GetUnsignedId()\n{\n    return static_cast<unsigned int>(item_id_);\n}\n\nvoid MapItem::SetItem(void* ptr)\n{\n    item_pointer_ = ptr;\n}\n\nMapWrapper::MapWrapper() : map_()\n{\n}\n\nMapWrapper::~MapWrapper()\n{\n    if (!map_.empty())\n    {\n        WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1,\n                   \"Potential memory leak in MapWrapper\");\n        // Remove all map items. Please note that std::map::clear() can't be\n        // used because each item has some dynamically allocated memory\n        // associated with it (i.e. using std::map::clear would introduce a\n        // memory leak).\n        while (Erase(First()) == 0)\n        {}\n    }\n}\n\nint MapWrapper::Size() const\n{\n    return (int)map_.size();\n}\n\nint MapWrapper::Insert(int id, void* ptr)\n{\n    map_[id] = new MapItem(id,ptr);\n    return 0;\n}\n\nMapItem* MapWrapper::First() const\n{\n    std::map<int, MapItem*>::const_iterator it = map_.begin();\n    if (it != map_.end())\n    {\n        return it->second;\n    }\n    return 0;\n}\n\nMapItem* MapWrapper::Last() const\n{\n    std::map<int, MapItem*>::const_reverse_iterator it = map_.rbegin();\n    if (it != map_.rend())\n    {\n        return it->second;\n    }\n    return 0;\n}\n\nMapItem* MapWrapper::Next(MapItem* item) const\n{\n    if (item == 0)\n    {\n        return 0;\n    }\n    std::map<int, MapItem*>::const_iterator it = map_.find(item->item_id_);\n    if (it != map_.end())\n    {\n        it++;\n        if (it != map_.end())\n        {\n            return it->second;\n        }\n    }\n    return 0;\n}\n\nMapItem* MapWrapper::Previous(MapItem* item) const\n{\n    if (item == 0)\n    {\n        return 0;\n    }\n\n    std::map<int, MapItem*>::const_iterator it = map_.find(item->item_id_);\n    if ((it != map_.end()) &&\n       (it != map_.begin()))\n    {\n        --it;\n        return it->second;\n    }\n    return 0;\n}\n\nMapItem* MapWrapper::Find(int id) const\n{\n    std::map<int, MapItem*>::const_iterator it = map_.find(id);\n    if (it != map_.end())\n    {\n        return it->second;\n    }\n    return 0;\n}\n\nint MapWrapper::Erase(MapItem* item)\n{\n    if (item == 0)\n    {\n        return -1;\n    }\n    std::map<int, MapItem*>::iterator it = map_.find(item->item_id_);\n    if (it != map_.end())\n    {\n        delete it->second;\n        map_.erase(it);\n        return 0;\n    }\n    return -1;\n}\n\nint MapWrapper::Erase(const int id)\n{\n    std::map<int, MapItem*>::iterator it = map_.find(id);\n    if (it != map_.end())\n    {\n        delete it->second;\n        map_.erase(it);\n        return 0;\n    }\n    return -1;\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/map_no_stl.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"map_no_stl.h\"\n\n#include \"critical_section_wrapper.h\"\n#include \"trace.h\"\n\nnamespace webrtc {\nMapNoStlItem::MapNoStlItem(int id, void* item)\n    : next_(0),\n      prev_(0),\n      item_id_(id),\n      item_ptr_(item)\n{\n}\n\nMapNoStlItem::~MapNoStlItem()\n{\n}\n\nvoid* MapNoStlItem::GetItem()\n{\n    return item_ptr_;\n}\n\nint MapNoStlItem::GetId()\n{\n    return item_id_;\n}\n\nunsigned int MapNoStlItem::GetUnsignedId()\n{\n    return static_cast<unsigned int>(item_id_);\n}\n\nvoid MapNoStlItem::SetItem(void* ptr)\n{\n    item_ptr_ = ptr;\n}\n\nMapNoStl::MapNoStl()\n    : critical_section_(CriticalSectionWrapper::CreateCriticalSection()),\n      first_(0),\n      last_(0),\n      size_(0)\n{\n}\n\nMapNoStl::~MapNoStl()\n{\n    if (First())\n    {\n        WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1,\n                   \"Potential memory leak in MapNoStl\");\n        while (Erase(First()) == 0)\n        {}\n    }\n    delete critical_section_;\n}\n\nint MapNoStl::Size() const\n{\n    return size_;\n}\n\nint MapNoStl::Insert(int id, void* ptr)\n{\n    MapNoStlItem* new_item = new MapNoStlItem(id, ptr);\n\n    CriticalSectionScoped lock(*critical_section_);\n    MapNoStlItem* item = first_;\n    size_++;\n    if (!item)\n    {\n        first_ = new_item;\n        last_ = new_item;\n        return 0;\n    }\n    while(item->next_)\n    {\n        // Three scenarios\n        // 1. Item should be inserted first.\n        // 2. Item should be inserted between two items\n        // 3. Item should be inserted last\n        if (item->GetId() > id)\n        {\n            new_item->next_ = item;\n            item->prev_ = new_item;\n            if (item == first_)\n            {\n                first_ = new_item;\n            }\n            else\n            {\n                new_item->prev_ = item->prev_;\n                new_item->prev_->next_ = new_item;\n            }\n            return 0;\n        }\n        item = item->next_;\n    }\n    // 3\n    item->next_ = new_item;\n    new_item->prev_ = item;\n    last_ = new_item;\n    return 0;\n}\n\nMapNoStlItem* MapNoStl::First() const\n{\n    return first_;\n}\n\nMapNoStlItem* MapNoStl::Last() const\n{\n    return last_;\n}\n\nMapNoStlItem* MapNoStl::Next(MapNoStlItem* item) const\n{\n    if (!item)\n    {\n        return 0;\n    }\n    return item->next_;\n}\n\nMapNoStlItem* MapNoStl::Previous(MapNoStlItem* item) const\n{\n    if (!item)\n    {\n        return 0;\n    }\n    return item->prev_;\n}\n\nMapNoStlItem* MapNoStl::Find(int id) const\n{\n    CriticalSectionScoped lock(*critical_section_);\n    MapNoStlItem* item = Locate(id);\n    return item;\n}\n\nint MapNoStl::Erase(MapNoStlItem* item)\n{\n    if(!item)\n    {\n        return -1;\n    }\n    CriticalSectionScoped lock(*critical_section_);\n    return Remove(item);\n}\n\nint MapNoStl::Erase(const int id)\n{\n    CriticalSectionScoped lock(*critical_section_);\n    MapNoStlItem* item = Locate(id);\n    if(!item)\n    {\n        return -1;\n    }\n    return Remove(item);\n}\n\nMapNoStlItem* MapNoStl::Locate(int id) const\n{\n    MapNoStlItem* item = first_;\n    while(item)\n    {\n        if (item->GetId() == id)\n        {\n            return item;\n        }\n        item = item->next_;\n    }\n    return 0;\n}\n\nint MapNoStl::Remove(MapNoStlItem* item)\n{\n    if (!item)\n    {\n        return -1;\n    }\n    size_--;\n    MapNoStlItem* previous_item = item->prev_;\n    MapNoStlItem* next_item = item->next_;\n    if (!previous_item)\n    {\n        next_item->prev_ = 0;\n        first_ = next_item;\n    }\n    else\n    {\n        previous_item->next_ = next_item;\n    }\n    if (!next_item)\n    {\n        previous_item->next_ = 0;\n        last_ = previous_item;\n    }\n    else\n    {\n        next_item->prev_ = previous_item;\n    }\n    delete item;\n    return 0;\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/map_no_stl.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_MAP_NO_STL_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_MAP_NO_STL_H_\n\n#include \"constructor_magic.h\"\n\nnamespace webrtc {\nclass CriticalSectionWrapper;\n\nclass MapNoStlItem\n{\nfriend class Map;\n\npublic:\n    MapNoStlItem(int id, void* ptr);\n    virtual ~MapNoStlItem();\n    void* GetItem();\n    int GetId();\n    unsigned int GetUnsignedId();\n    void SetItem(void* ptr);\n\nprotected:\n    MapNoStlItem* next_;\n    MapNoStlItem* prev_;\n\nprivate:\n    int item_id_;\n    void* item_ptr_;\n    DISALLOW_COPY_AND_ASSIGN(MapNoStlItem);\n};\n\nclass MapNoStl\n{\npublic:\n    MapNoStl();\n    virtual ~MapNoStl();\n\n    // MapWrapper functions.\n    int Insert(int id, void* ptr);\n    int Erase(MapNoStlItem* item);\n    int Erase(int id);\n    int Size() const;\n    MapNoStlItem* First() const;\n    MapNoStlItem* Last() const;\n    MapNoStlItem* Next(MapNoStlItem* item) const;\n    MapNoStlItem* Previous(MapNoStlItem* item) const;\n    MapNoStlItem* Find(int id) const;\n\nprivate:\n    MapNoStlItem* Locate(int id) const;\n    int Remove(MapNoStlItem* item);\n\n    CriticalSection* critical_section_;\n    MapNoStlItem* first_;\n    MapNoStlItem* last_;\n    int size_;\n    DISALLOW_COPY_AND_ASSIGN(MapNoStl);\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_MAP_NO_STL_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/map_unittest.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"gtest/gtest.h\"\n\n#include \"map_wrapper.h\"\n\nusing ::webrtc::MapWrapper;\nusing ::webrtc::MapItem;\n\nconst unsigned int kNumberOfElements = 10;\n\nint* ItemPointer(MapItem* item) {\n    if (item == NULL) {\n        return NULL;\n    }\n    return reinterpret_cast<int*>(item->GetItem());\n}\n\nbool DeleteItemContent(MapItem* item) {\n    if(item == NULL) {\n        return false;\n    }\n    int* value_ptr = ItemPointer(item);\n    delete value_ptr;\n    return true;\n}\n\nint ItemValue(MapItem* item) {\n    if (item == NULL) {\n        return -1;\n    }\n    const int* value_ptr = ItemPointer(item);\n    if (value_ptr == 0) {\n        return -1;\n    }\n    return *value_ptr;\n}\n\nvoid PrintToConsole(const char* message, bool supress) {\n    if (supress) {\n        return;\n    }\n    printf(message);\n}\n\nbool CreateAscendingMap(MapWrapper* ascending_map) {\n    int* insert_value = NULL;\n    for (int i = 0; i < kNumberOfElements; ++i) {\n        insert_value = new int;\n        if (insert_value == NULL) {\n            return false;\n        }\n        *insert_value = i;\n        if (0 != ascending_map->Insert(\n                     i,\n                     reinterpret_cast<void*>(insert_value))) {\n            return false;\n        }\n    }\n    return true;\n}\n\nbool ClearMap(MapWrapper* clear_map) {\n    bool success = true;\n    while (clear_map->Size() != 0) {\n        MapItem* remove_item = clear_map->First();\n        if (remove_item == NULL) {\n            return false;\n        }\n        if (!DeleteItemContent(remove_item)) {\n            success = false;\n        }\n        if (clear_map->Erase(remove_item) != 0) {\n            return false;\n        }\n    }\n    return success;\n}\n\nvoid PrintMapItem(MapItem* item, bool supress) {\n    const int id = item->GetId();\n    const int value = ItemValue(item);\n    char print_buffer[16];\n    sprintf(print_buffer, \"(%3i,%3i) \", id, value);\n    PrintToConsole(print_buffer, supress);\n}\n\n// Succeeds only if all the items were printed.\nbool PrintMap(const MapWrapper& print_map, bool supress) {\n    const int elements_to_print = print_map.Size();\n    int elements_printed = 0;\n    MapItem* item = print_map.First();\n    PrintToConsole(\"[\", supress);\n    while (item != NULL) {\n        PrintMapItem(item, supress);\n        ++elements_printed;\n        item = print_map.Next(item);\n    }\n    PrintToConsole(\"]\\n\", supress);\n    return elements_printed == elements_to_print;\n}\n\n// Succeeds only if all the items were printed.\nbool ReversePrintMap(const MapWrapper& print_map, bool supress) {\n    const int elements_to_print = print_map.Size();\n    int elements_printed = 0;\n    MapItem* item = print_map.Last();\n    PrintToConsole(\"[\", supress);\n    while (item != NULL) {\n        PrintMapItem(item, supress);\n        ++elements_printed;\n        item = print_map.Previous(item);\n    }\n    PrintToConsole(\"]\\n\", supress);\n    return elements_printed == elements_to_print;\n}\n\n// Returns true if the map items contain the same item.\nbool CompareItems(MapItem* lhs_item, MapItem* rhs_item) {\n    if ((lhs_item == NULL) || (rhs_item == NULL)) {\n        return false;\n    }\n    if (lhs_item->GetId() != rhs_item->GetId()) {\n        return false;\n    }\n    return lhs_item->GetItem() == rhs_item->GetItem();\n}\n\n// Returns true if the map contains the same items.\nbool CompareMaps(const MapWrapper& lhs, const MapWrapper& rhs) {\n    const int map_size = lhs.Size();\n    if (map_size != rhs.Size()) {\n        return false;\n    }\n    int item_count = 0;\n    MapItem* lhs_item = lhs.First();\n    while (lhs_item != NULL) {\n        MapItem* rhs_item = rhs.Find(lhs_item->GetId());\n        if (rhs_item == NULL) {\n            return false;\n        }\n        if (!CompareItems(lhs_item, rhs_item)) {\n            return false;\n        }\n        ++item_count;\n        lhs_item = lhs.Next(lhs_item);\n    }\n    return item_count == map_size;\n} \n\nclass MapWrapperTest : public ::testing::Test {\nprotected:\n    virtual void SetUp() {\n        ASSERT_TRUE(CreateAscendingMap(&ascending_map_));\n    }\n\n    virtual void TearDown() {\n        EXPECT_TRUE(ClearMap(&ascending_map_));\n    }\n    MapWrapper ascending_map_;\n};\n\nTEST_F(MapWrapperTest,RemoveTest) {\n    // Erase using int id\n    { // Create local scope to avoid accidental re-use\n        MapItem* item_first = ascending_map_.First();\n        ASSERT_FALSE(item_first == NULL);\n        const int first_value_id = item_first->GetId();\n        const int first_value = ItemValue(item_first);\n        EXPECT_TRUE(first_value == 0);\n        EXPECT_EQ(first_value_id,first_value);\n        EXPECT_FALSE(NULL == ascending_map_.Find(first_value_id));\n        EXPECT_TRUE(DeleteItemContent(item_first));\n        ascending_map_.Erase(first_value_id);\n        EXPECT_TRUE(NULL == ascending_map_.Find(first_value_id));\n        EXPECT_EQ(kNumberOfElements-1,ascending_map_.Size());\n    }\n    \n    // Erase using MapItem* item\n    MapItem* item_last = ascending_map_.Last();\n    ASSERT_FALSE(item_last == NULL);\n    const int last_value_id = item_last->GetId();\n    const int last_value = ItemValue(item_last);\n    EXPECT_TRUE(last_value == kNumberOfElements - 1);    \n    EXPECT_EQ(last_value_id, last_value);\n    EXPECT_FALSE(NULL == ascending_map_.Find(last_value_id));\n    EXPECT_TRUE(DeleteItemContent(item_last));\n    ascending_map_.Erase(last_value_id);\n    EXPECT_TRUE(NULL == ascending_map_.Find(last_value_id));\n    EXPECT_EQ(kNumberOfElements-2,ascending_map_.Size());\n}\n\nTEST_F(MapWrapperTest, PrintTest) {\n    const bool supress = true; // Don't spam the console\n\n    EXPECT_TRUE(PrintMap(ascending_map_, supress));\n    EXPECT_TRUE(ReversePrintMap(ascending_map_, supress));\n}\n\nTEST_F(MapWrapperTest, CopyTest) {\n    MapWrapper compare_map;\n    ASSERT_TRUE(CreateAscendingMap(&compare_map));\n    const int map_size = compare_map.Size();\n    ASSERT_EQ(ascending_map_.Size(), map_size);\n    // CompareMaps compare the pointers not value of the pointers.\n    // (the values are the same since both are ascending maps).\n    EXPECT_FALSE(CompareMaps(compare_map,ascending_map_));\n\n    int copy_count = 0;\n    MapItem* ascend_item = ascending_map_.First();\n    while (ascend_item != NULL) {\n        MapItem* compare_item = compare_map.Find(ascend_item->GetId());\n        ASSERT_FALSE(compare_item == NULL);\n        DeleteItemContent(compare_item);\n        compare_item->SetItem(ascend_item->GetItem());\n        ascend_item = ascending_map_.Next(ascend_item);\n        ++copy_count;\n    }\n    EXPECT_TRUE(CompareMaps(compare_map,ascending_map_));\n    while (compare_map.Erase(compare_map.First()) == 0) {\n    }\n    EXPECT_EQ(map_size, copy_count);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/rw_lock.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"rw_lock_wrapper.h\"\n\n#include <assert.h>\n\n#if defined(_WIN32)\n    #include \"rw_lock_windows.h\"\n#elif defined(WEBRTC_ANDROID)\n    #include <stdlib.h>\n    #include \"rw_lock_generic.h\"\n#else\n    #include \"rw_lock_posix.h\"\n#endif\n\nnamespace webrtc {\nRWLockWrapper* RWLockWrapper::CreateRWLock()\n{\n#ifdef _WIN32\n    RWLockWrapper* lock =  new RWLockWindows();\n#elif defined(WEBRTC_ANDROID)\n    RWLockWrapper* lock =  new RWLockWrapperGeneric();\n#else\n    RWLockWrapper* lock =  new RWLockPosix();\n#endif\n    if(lock->Init() != 0)\n    {\n        delete lock;\n        assert(false);\n        return NULL;\n    }\n    return lock;\n}\n\nRWLockWrapper::~RWLockWrapper()\n{\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/rw_lock_generic.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"rw_lock_generic.h\"\n\n#include \"condition_variable_wrapper.h\"\n#include \"critical_section_wrapper.h\"\n\nnamespace webrtc {\nRWLockWrapperGeneric::RWLockWrapperGeneric()\n    : _readersActive(0),\n      _writerActive(false),\n      _readersWaiting(0),\n      _writersWaiting(0)\n{\n    _critSectPtr  = CriticalSectionWrapper::CreateCriticalSection();\n    _readCondPtr  = ConditionVariableWrapper::CreateConditionVariable();\n    _writeCondPtr = ConditionVariableWrapper::CreateConditionVariable();\n}\n\nRWLockWrapperGeneric::~RWLockWrapperGeneric()\n{\n    delete _writeCondPtr;\n    delete _readCondPtr;\n    delete _critSectPtr;\n}\n\nint RWLockWrapperGeneric::Init()\n{\n    return 0;\n}\n\nvoid RWLockWrapperGeneric::AcquireLockExclusive()\n{\n    _critSectPtr->Enter();\n\n    if (_writerActive || _readersActive > 0)\n    {\n        ++_writersWaiting;\n\n        while (_writerActive || _readersActive > 0)\n        {\n            _writeCondPtr->SleepCS(*_critSectPtr);\n        }\n\n        --_writersWaiting;\n    }\n    _writerActive = true;\n    _critSectPtr->Leave();\n}\n\nvoid RWLockWrapperGeneric::ReleaseLockExclusive()\n{\n    _critSectPtr->Enter();\n\n    _writerActive = false;\n\n    if (_writersWaiting > 0)\n    {\n        _writeCondPtr->Wake();\n\n    }else if (_readersWaiting > 0)\n    {\n        _readCondPtr->WakeAll();\n    }\n    _critSectPtr->Leave();\n}\n\nvoid RWLockWrapperGeneric::AcquireLockShared()\n{\n    _critSectPtr->Enter();\n\n    if (_writerActive || _writersWaiting > 0)\n    {\n        ++_readersWaiting;\n\n        while (_writerActive || _writersWaiting > 0)\n        {\n            _readCondPtr->SleepCS(*_critSectPtr);\n        }\n        --_readersWaiting;\n    }\n    ++_readersActive;\n    _critSectPtr->Leave();\n}\n\nvoid RWLockWrapperGeneric::ReleaseLockShared()\n{\n    _critSectPtr->Enter();\n\n    --_readersActive;\n\n    if (_readersActive == 0 && _writersWaiting > 0)\n    {\n        _writeCondPtr->Wake();\n    }\n    _critSectPtr->Leave();\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/rw_lock_generic.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_GENERIC_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_GENERIC_H_\n\n#include \"rw_lock_wrapper.h\"\n\nnamespace webrtc {\nclass CriticalSectionWrapper;\nclass ConditionVariableWrapper;\n\nclass RWLockWrapperGeneric : public RWLockWrapper\n{\npublic:\n    RWLockWrapperGeneric();\n    virtual ~RWLockWrapperGeneric();\n\n    virtual void AcquireLockExclusive();\n    virtual void ReleaseLockExclusive();\n\n    virtual void AcquireLockShared();\n    virtual void ReleaseLockShared();\n\nprotected:\n    virtual int Init();\n\nprivate:\n    CriticalSectionWrapper*   _critSectPtr;\n    ConditionVariableWrapper* _readCondPtr;\n    ConditionVariableWrapper* _writeCondPtr;\n\n    int  _readersActive;\n    bool _writerActive;\n    int  _readersWaiting;\n    int  _writersWaiting;\n};\n} // namespace webrtc\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_GENERIC_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/rw_lock_posix.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"rw_lock_posix.h\"\n\nnamespace webrtc {\nRWLockPosix::RWLockPosix() : _lock()\n{\n}\n\nRWLockPosix::~RWLockPosix()\n{\n    pthread_rwlock_destroy(&_lock);\n}\n\nint RWLockPosix::Init()\n{\n    return pthread_rwlock_init(&_lock, 0);\n}\n\nvoid RWLockPosix::AcquireLockExclusive()\n{\n    pthread_rwlock_wrlock(&_lock);\n}\n\nvoid RWLockPosix::ReleaseLockExclusive()\n{\n    pthread_rwlock_unlock(&_lock);\n}\n\nvoid RWLockPosix::AcquireLockShared()\n{\n    pthread_rwlock_rdlock(&_lock);\n}\n\nvoid RWLockPosix::ReleaseLockShared()\n{\n    pthread_rwlock_unlock(&_lock);\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/rw_lock_posix.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_POSIX_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_POSIX_H_\n\n#include \"rw_lock_wrapper.h\"\n\n#include <pthread.h>\n\nnamespace webrtc {\nclass RWLockPosix : public RWLockWrapper\n{\npublic:\n    RWLockPosix();\n    virtual ~RWLockPosix();\n\n    virtual void AcquireLockExclusive();\n    virtual void ReleaseLockExclusive();\n\n    virtual void AcquireLockShared();\n    virtual void ReleaseLockShared();\n\nprotected:\n    virtual int Init();\n\nprivate:\n    pthread_rwlock_t _lock;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_POSIX_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/rw_lock_windows.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"rw_lock_windows.h\"\n\n#include \"critical_section_wrapper.h\"\n#include \"condition_variable_wrapper.h\"\n#include \"trace.h\"\n\n// TODO (hellner) why not just use the rw_lock_generic.cc solution if\n//                           native is not supported? Unnecessary redundancy!\n\nnamespace webrtc {\nbool RWLockWindows::_winSupportRWLockPrimitive = false;\nstatic HMODULE library = NULL;\n\nPInitializeSRWLock       _PInitializeSRWLock;\nPAcquireSRWLockExclusive _PAcquireSRWLockExclusive;\nPAcquireSRWLockShared    _PAcquireSRWLockShared;\nPReleaseSRWLockShared    _PReleaseSRWLockShared;\nPReleaseSRWLockExclusive _PReleaseSRWLockExclusive;\n\nRWLockWindows::RWLockWindows()\n    : _critSectPtr(NULL),\n      _readCondPtr(NULL),\n      _writeCondPtr(NULL),\n      _readersActive(0),\n      _writerActive(false),\n      _readersWaiting(0),\n      _writersWaiting(0)\n{\n}\n\nRWLockWindows::~RWLockWindows()\n{\n    delete _writeCondPtr;\n    delete _readCondPtr;\n    delete _critSectPtr;\n}\n\nint RWLockWindows::Init()\n{\n    if(!library)\n    {\n        // Use native implementation if supported (i.e Vista+)\n        library = LoadLibrary(TEXT(\"Kernel32.dll\"));\n        if(library)\n        {\n            WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,\n                         \"Loaded Kernel.dll\");\n\n            _PInitializeSRWLock =\n                (PInitializeSRWLock)GetProcAddress(\n                    library,\n                    \"InitializeSRWLock\");\n\n            _PAcquireSRWLockExclusive =\n               (PAcquireSRWLockExclusive)GetProcAddress(\n                   library,\n                   \"AcquireSRWLockExclusive\");\n            _PReleaseSRWLockExclusive =\n                (PReleaseSRWLockExclusive)GetProcAddress(\n                    library,\n                    \"ReleaseSRWLockExclusive\");\n            _PAcquireSRWLockShared =\n                (PAcquireSRWLockShared)GetProcAddress(\n                    library,\n                    \"AcquireSRWLockShared\");\n            _PReleaseSRWLockShared =\n                (PReleaseSRWLockShared)GetProcAddress(\n                    library,\n                    \"ReleaseSRWLockShared\");\n\n            if( _PInitializeSRWLock &&\n                _PAcquireSRWLockExclusive &&\n                _PReleaseSRWLockExclusive &&\n                _PAcquireSRWLockShared &&\n                _PReleaseSRWLockShared )\n            {\n                WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,\n                            \"Loaded Simple RW Lock\");\n                _winSupportRWLockPrimitive = true;\n            }\n        }\n    }\n    if(_winSupportRWLockPrimitive)\n    {\n        _PInitializeSRWLock(&_lock);\n    } else {\n        _critSectPtr  = CriticalSectionWrapper::CreateCriticalSection();\n        _readCondPtr  = ConditionVariableWrapper::CreateConditionVariable();\n        _writeCondPtr = ConditionVariableWrapper::CreateConditionVariable();\n    }\n    return 0;\n}\n\nvoid RWLockWindows::AcquireLockExclusive()\n{\n    if (_winSupportRWLockPrimitive)\n    {\n        _PAcquireSRWLockExclusive(&_lock);\n    } else {\n        _critSectPtr->Enter();\n\n        if (_writerActive || _readersActive > 0)\n        {\n            ++_writersWaiting;\n            while (_writerActive || _readersActive > 0)\n            {\n                _writeCondPtr->SleepCS(*_critSectPtr);\n            }\n            --_writersWaiting;\n        }\n        _writerActive = true;\n        _critSectPtr->Leave();\n    }\n}\n\nvoid RWLockWindows::ReleaseLockExclusive()\n{\n    if(_winSupportRWLockPrimitive)\n    {\n        _PReleaseSRWLockExclusive(&_lock);\n    } else {\n        _critSectPtr->Enter();\n        _writerActive = false;\n        if (_writersWaiting > 0)\n        {\n            _writeCondPtr->Wake();\n\n        }else if (_readersWaiting > 0) {\n            _readCondPtr->WakeAll();\n        }\n        _critSectPtr->Leave();\n    }\n}\n\nvoid RWLockWindows::AcquireLockShared()\n{\n    if(_winSupportRWLockPrimitive)\n    {\n        _PAcquireSRWLockShared(&_lock);\n    } else\n    {\n        _critSectPtr->Enter();\n        if (_writerActive || _writersWaiting > 0)\n        {\n            ++_readersWaiting;\n\n            while (_writerActive || _writersWaiting > 0)\n            {\n                _readCondPtr->SleepCS(*_critSectPtr);\n            }\n            --_readersWaiting;\n        }\n        ++_readersActive;\n        _critSectPtr->Leave();\n    }\n}\n\nvoid RWLockWindows::ReleaseLockShared()\n{\n    if(_winSupportRWLockPrimitive)\n    {\n        _PReleaseSRWLockShared(&_lock);\n    } else\n    {\n        _critSectPtr->Enter();\n\n        --_readersActive;\n\n        if (_readersActive == 0 && _writersWaiting > 0)\n        {\n            _writeCondPtr->Wake();\n        }\n        _critSectPtr->Leave();\n    }\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/rw_lock_windows.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_WINDOWS_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_WINDOWS_H_\n\n#include \"rw_lock_wrapper.h\"\n\n#include <Windows.h>\n\n#if !defined(RTL_SRWLOCK_INIT)\n    typedef struct _RTL_SRWLOCK\n    {\n        void* Ptr;\n    } RTL_SRWLOCK, *PRTL_SRWLOCK;\n    typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;\n#endif\n\nnamespace webrtc {\nclass CriticalSectionWrapper;\nclass ConditionVariableWrapper;\n\ntypedef void (WINAPI *PInitializeSRWLock)(PSRWLOCK);\n\ntypedef void (WINAPI *PAcquireSRWLockExclusive)(PSRWLOCK);\ntypedef void (WINAPI *PReleaseSRWLockExclusive)(PSRWLOCK);\n\ntypedef void (WINAPI *PAcquireSRWLockShared)(PSRWLOCK);\ntypedef void (WINAPI *PReleaseSRWLockShared)(PSRWLOCK);\n\n\nclass RWLockWindows :public RWLockWrapper\n{\npublic:\n    RWLockWindows();\n    virtual ~RWLockWindows();\n\n    virtual void AcquireLockExclusive();\n    virtual void ReleaseLockExclusive();\n\n    virtual void AcquireLockShared();\n    virtual void ReleaseLockShared();\n\nprotected:\n    virtual int Init();\n\nprivate:\n    // For native implementation.\n    static bool _winSupportRWLockPrimitive;\n    SRWLOCK     _lock;\n\n    // Genric implementation, fallback if native is not supported.\n    CriticalSectionWrapper*   _critSectPtr;\n    ConditionVariableWrapper* _readCondPtr;\n    ConditionVariableWrapper* _writeCondPtr;\n\n    int  _readersActive;\n    bool _writerActive;\n    int  _readersWaiting;\n    int  _writersWaiting;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_WINDOWS_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/sort.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n// When the platform supports STL, the functions are implemented using a\n// templated spreadsort algorithm (http://sourceforge.net/projects/spreadsort/),\n// part of the Boost C++ library collection. Otherwise, the C standard library's\n// qsort() will be used.\n\n#include \"sort.h\"\n\n#include <cassert>\n#include <cstring>  // memcpy\n#include <new>      // nothrow new\n\n#ifdef NO_STL\n#include <cstdlib>      // qsort\n#else\n#include <algorithm>    // std::sort\n#include <vector>\n#include \"spreadsort.hpp\" // TODO (ajm) upgrade to spreadsortv2.\n#endif\n\n#ifdef NO_STL\n#define COMPARE_DEREFERENCED(XT, YT)        \\\n    do                                      \\\n    {                                       \\\n        if ((XT) > (YT))                    \\\n        {                                   \\\n            return 1;                       \\\n        }                                   \\\n        else if ((XT) < (YT))               \\\n        {                                   \\\n            return -1;                      \\\n        }                                   \\\n                                            \\\n        return 0;                           \\\n    }                                       \\\n    while(0)\n\n#define COMPARE_FOR_QSORT(X, Y, TYPE)                               \\\n    do                                                              \\\n    {                                                               \\\n        TYPE xT = static_cast<TYPE>(*static_cast<const TYPE*>(X));  \\\n        TYPE yT = static_cast<TYPE>(*static_cast<const TYPE*>(Y));  \\\n        COMPARE_DEREFERENCED(xT, yT);                               \\\n    }                                                               \\\n    while(0)\n\n#define COMPARE_KEY_FOR_QSORT(SORT_KEY_X, SORT_KEY_Y, TYPE)         \\\n    do                                                              \\\n    {                                                               \\\n        TYPE xT = static_cast<TYPE>(*static_cast<TYPE*>             \\\n            (static_cast<const SortKey*>(SORT_KEY_X)->key));        \\\n        TYPE yT = static_cast<TYPE>(*static_cast<TYPE*>             \\\n            (static_cast<const SortKey*>(SORT_KEY_Y)->key));        \\\n        COMPARE_DEREFERENCED(xT, yT);                               \\\n    }                                                               \\\n    while(0)\n\n#define KEY_QSORT(SORT_KEY, KEY, NUM_OF_ELEMENTS, KEY_TYPE, COMPARE_FUNC)     \\\n    do                                                                        \\\n    {                                                                         \\\n        KEY_TYPE* keyT = (KEY_TYPE*)(key);                                    \\\n        for (WebRtc_UWord32 i = 0; i < (NUM_OF_ELEMENTS); i++)                \\\n        {                                                                     \\\n            ptrSortKey[i].key = &keyT[i];                                     \\\n            ptrSortKey[i].index = i;                                          \\\n        }                                                                     \\\n                                                                              \\\n        qsort((SORT_KEY), (NUM_OF_ELEMENTS), sizeof(SortKey), (COMPARE_FUNC));\\\n    }                                                                         \\\n    while(0)\n#endif\n\nnamespace webrtc\n{\n#ifdef NO_STL\n    struct SortKey\n    {\n        void* key;\n        WebRtc_UWord32 index;\n    };\n#else\n    template<typename KeyType>\n    struct SortKey\n    {\n        KeyType key;\n        WebRtc_UWord32 index;\n    };\n#endif\n\n    namespace // Unnamed namespace provides internal linkage.\n    {\n#ifdef NO_STL\n        int CompareWord8(const void* x, const void* y)\n        {\n            COMPARE_FOR_QSORT(x, y, WebRtc_Word8);\n        }\n\n        int CompareUWord8(const void* x, const void* y)\n        {\n            COMPARE_FOR_QSORT(x, y, WebRtc_UWord8);\n        }\n\n        int CompareWord16(const void* x, const void* y)\n        {\n            COMPARE_FOR_QSORT(x, y, WebRtc_Word16);\n        }\n\n        int CompareUWord16(const void* x, const void* y)\n        {\n            COMPARE_FOR_QSORT(x, y, WebRtc_UWord16);\n        }\n\n        int CompareWord32(const void* x, const void* y)\n        {\n            COMPARE_FOR_QSORT(x, y, WebRtc_Word32);\n        }\n\n        int CompareUWord32(const void* x, const void* y)\n        {\n            COMPARE_FOR_QSORT(x, y, WebRtc_UWord32);\n        }\n\n        int CompareWord64(const void* x, const void* y)\n        {\n            COMPARE_FOR_QSORT(x, y, WebRtc_Word64);\n        }\n\n        int CompareUWord64(const void* x, const void* y)\n        {\n            COMPARE_FOR_QSORT(x, y, WebRtc_UWord64);\n        }\n\n        int CompareFloat32(const void* x, const void* y)\n        {\n            COMPARE_FOR_QSORT(x, y, float);\n        }\n\n        int CompareFloat64(const void* x, const void* y)\n        {\n            COMPARE_FOR_QSORT(x, y, double);\n        }\n\n        int CompareKeyWord8(const void* sortKeyX, const void* sortKeyY)\n        {\n            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_Word8);\n        }\n\n        int CompareKeyUWord8(const void* sortKeyX, const void* sortKeyY)\n        {\n            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_UWord8);\n        }\n\n        int CompareKeyWord16(const void* sortKeyX, const void* sortKeyY)\n        {\n            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_Word16);\n        }\n\n        int CompareKeyUWord16(const void* sortKeyX, const void* sortKeyY)\n        {\n            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_UWord16);\n        }\n\n        int CompareKeyWord32(const void* sortKeyX, const void* sortKeyY)\n        {\n            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_Word32);\n        }\n\n        int CompareKeyUWord32(const void* sortKeyX, const void* sortKeyY)\n        {\n            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_UWord32);\n        }\n\n        int CompareKeyWord64(const void* sortKeyX, const void* sortKeyY)\n        {\n            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_Word64);\n        }\n\n        int CompareKeyUWord64(const void* sortKeyX, const void* sortKeyY)\n        {\n            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_UWord64);\n        }\n\n        int CompareKeyFloat32(const void* sortKeyX, const void* sortKeyY)\n        {\n            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, float);\n        }\n\n        int CompareKeyFloat64(const void* sortKeyX, const void* sortKeyY)\n        {\n            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, double);\n        }\n#else\n        template <typename KeyType>\n        struct KeyLessThan\n        {\n            bool operator()(const SortKey<KeyType>& sortKeyX,\n                const SortKey<KeyType>& sortKeyY) const\n            {\n                return sortKeyX.key < sortKeyY.key;\n            }\n        };\n\n        template <typename KeyType>\n        struct KeyRightShift\n        {\n            KeyType operator()(const SortKey<KeyType>& sortKey,\n                const unsigned offset) const\n            {\n                return sortKey.key >> offset;\n            }\n        };\n\n        template <typename DataType>\n        inline void IntegerSort(void* data, WebRtc_UWord32 numOfElements)\n        {\n            DataType* dataT = static_cast<DataType*>(data);\n            boost::integer_sort(dataT, dataT + numOfElements);\n        }\n\n        template <typename DataType, typename IntegerType>\n        inline void FloatSort(void* data, WebRtc_UWord32 numOfElements)\n        {\n            DataType* dataT = static_cast<DataType*>(data);\n            IntegerType cVal = 0;\n            boost::float_sort_cast(dataT, dataT + numOfElements, cVal);\n        }\n\n        template <typename DataType>\n        inline void StdSort(void* data, WebRtc_UWord32 numOfElements)\n        {\n            DataType* dataT = static_cast<DataType*>(data);\n            std::sort(dataT, dataT + numOfElements);\n        }\n\n        template<typename KeyType>\n        inline WebRtc_Word32 SetupKeySort(void* key,\n                                          SortKey<KeyType>*& ptrSortKey,\n                                          WebRtc_UWord32 numOfElements)\n        {\n            ptrSortKey = new(std::nothrow) SortKey<KeyType>[numOfElements];\n            if (ptrSortKey == NULL)\n            {\n                return -1;\n            }\n\n            KeyType* keyT = static_cast<KeyType*>(key);\n            for (WebRtc_UWord32 i = 0; i < numOfElements; i++)\n            {\n                ptrSortKey[i].key = keyT[i];\n                ptrSortKey[i].index = i;\n            }\n\n            return 0;\n        }\n\n        template<typename KeyType>\n        inline WebRtc_Word32 TeardownKeySort(void* data,\n                                             SortKey<KeyType>* ptrSortKey,\n            WebRtc_UWord32 numOfElements, WebRtc_UWord32 sizeOfElement)\n        {\n            WebRtc_UWord8* ptrData = static_cast<WebRtc_UWord8*>(data);\n            WebRtc_UWord8* ptrDataSorted = new(std::nothrow) WebRtc_UWord8\n                [numOfElements * sizeOfElement];\n            if (ptrDataSorted == NULL)\n            {\n                return -1;\n            }\n\n            for (WebRtc_UWord32 i = 0; i < numOfElements; i++)\n            {\n                memcpy(ptrDataSorted + i * sizeOfElement, ptrData +\n                       ptrSortKey[i].index * sizeOfElement, sizeOfElement);\n            }\n            memcpy(ptrData, ptrDataSorted, numOfElements * sizeOfElement);\n            delete[] ptrSortKey;\n            delete[] ptrDataSorted;\n            return 0;\n        }\n\n        template<typename KeyType>\n        inline WebRtc_Word32 IntegerKeySort(void* data, void* key,\n                                            WebRtc_UWord32 numOfElements,\n                                            WebRtc_UWord32 sizeOfElement)\n        {\n            SortKey<KeyType>* ptrSortKey;\n            if (SetupKeySort<KeyType>(key, ptrSortKey, numOfElements) != 0)\n            {\n                return -1;\n            }\n\n            boost::integer_sort(ptrSortKey, ptrSortKey + numOfElements,\n                KeyRightShift<KeyType>(), KeyLessThan<KeyType>());\n\n            if (TeardownKeySort<KeyType>(data, ptrSortKey, numOfElements,\n                    sizeOfElement) != 0)\n            {\n                return -1;\n            }\n\n            return 0;\n        }\n\n        template<typename KeyType>\n        inline WebRtc_Word32 StdKeySort(void* data, void* key,\n                                        WebRtc_UWord32 numOfElements,\n                                        WebRtc_UWord32 sizeOfElement)\n        {\n            SortKey<KeyType>* ptrSortKey;\n            if (SetupKeySort<KeyType>(key, ptrSortKey, numOfElements) != 0)\n            {\n                return -1;\n            }\n\n            std::sort(ptrSortKey, ptrSortKey + numOfElements,\n                KeyLessThan<KeyType>());\n\n            if (TeardownKeySort<KeyType>(data, ptrSortKey, numOfElements,\n                    sizeOfElement) != 0)\n            {\n                return -1;\n            }\n\n            return 0;\n        }\n#endif\n    }\n\n    WebRtc_Word32 Sort(void* data, WebRtc_UWord32 numOfElements, Type type)\n    {\n        if (data == NULL)\n        {\n            return -1;\n        }\n\n#ifdef NO_STL\n        switch (type)\n        {\n        case TYPE_Word8:\n            qsort(data, numOfElements, sizeof(WebRtc_Word8), CompareWord8);\n            break;\n        case TYPE_UWord8:\n            qsort(data, numOfElements, sizeof(WebRtc_UWord8), CompareUWord8);\n            break;\n        case TYPE_Word16:\n            qsort(data, numOfElements, sizeof(WebRtc_Word16), CompareWord16);\n            break;\n        case TYPE_UWord16:\n            qsort(data, numOfElements, sizeof(WebRtc_UWord16), CompareUWord16);\n            break;\n        case TYPE_Word32:\n            qsort(data, numOfElements, sizeof(WebRtc_Word32), CompareWord32);\n            break;\n        case TYPE_UWord32:\n            qsort(data, numOfElements, sizeof(WebRtc_UWord32), CompareUWord32);\n            break;\n        case TYPE_Word64:\n            qsort(data, numOfElements, sizeof(WebRtc_Word64), CompareWord64);\n            break;\n        case TYPE_UWord64:\n            qsort(data, numOfElements, sizeof(WebRtc_UWord64), CompareUWord64);\n            break;\n        case TYPE_Float32:\n            qsort(data, numOfElements, sizeof(float), CompareFloat32);\n            break;\n        case TYPE_Float64:\n            qsort(data, numOfElements, sizeof(double), CompareFloat64);\n            break;\n        default:\n            return -1;\n        }\n#else\n        // Fall back to std::sort for 64-bit types and floats due to compiler\n\t// warnings and VS 2003 build crashes respectively with spreadsort.\n        switch (type)\n        {\n        case TYPE_Word8:\n            IntegerSort<WebRtc_Word8>(data, numOfElements);\n            break;\n        case TYPE_UWord8:\n            IntegerSort<WebRtc_UWord8>(data, numOfElements);\n            break;\n        case TYPE_Word16:\n            IntegerSort<WebRtc_Word16>(data, numOfElements);\n            break;\n        case TYPE_UWord16:\n            IntegerSort<WebRtc_UWord16>(data, numOfElements);\n            break;\n        case TYPE_Word32:\n            IntegerSort<WebRtc_Word32>(data, numOfElements);\n            break;\n        case TYPE_UWord32:\n            IntegerSort<WebRtc_UWord32>(data, numOfElements);\n            break;\n        case TYPE_Word64:\n            StdSort<WebRtc_Word64>(data, numOfElements);\n            break;\n        case TYPE_UWord64:\n            StdSort<WebRtc_UWord64>(data, numOfElements);\n            break;\n        case TYPE_Float32:\n            StdSort<float>(data, numOfElements);\n            break;\n        case TYPE_Float64:\n            StdSort<double>(data, numOfElements);\n            break;\n        default:\n            return -1;\n        }\n#endif\n        return 0;\n    }\n\n    WebRtc_Word32 KeySort(void* data, void* key, WebRtc_UWord32 numOfElements,\n                          WebRtc_UWord32 sizeOfElement, Type keyType)\n    {\n        if (data == NULL)\n        {\n            return -1;\n        }\n\n        if (key == NULL)\n        {\n            return -1;\n        }\n\n        if ((WebRtc_UWord64)numOfElements * sizeOfElement > 0xffffffff)\n        {\n            return -1;\n        }\n\n#ifdef NO_STL\n        SortKey* ptrSortKey = new(std::nothrow) SortKey[numOfElements];\n        if (ptrSortKey == NULL)\n        {\n            return -1;\n        }\n\n        switch (keyType)\n        {\n        case TYPE_Word8:\n            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_Word8,\n                CompareKeyWord8);\n            break;\n        case TYPE_UWord8:\n            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_UWord8,\n                CompareKeyUWord8);\n            break;\n        case TYPE_Word16:\n            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_Word16,\n                CompareKeyWord16);\n            break;\n        case TYPE_UWord16:\n            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_UWord16,\n                CompareKeyUWord16);\n            break;\n        case TYPE_Word32:\n            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_Word32,\n                CompareKeyWord32);\n            break;\n        case TYPE_UWord32:\n            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_UWord32,\n                CompareKeyUWord32);\n            break;\n        case TYPE_Word64:\n            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_Word64,\n                CompareKeyWord64);\n            break;\n        case TYPE_UWord64:\n            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_UWord64,\n                CompareKeyUWord64);\n            break;\n        case TYPE_Float32:\n            KEY_QSORT(ptrSortKey, key, numOfElements, float,\n                CompareKeyFloat32);\n            break;\n        case TYPE_Float64:\n            KEY_QSORT(ptrSortKey, key, numOfElements, double,\n                CompareKeyFloat64);\n            break;\n        default:\n            return -1;\n        }\n\n        // Shuffle into sorted position based on index map.\n        WebRtc_UWord8* ptrData = static_cast<WebRtc_UWord8*>(data);\n        WebRtc_UWord8* ptrDataSorted = new(std::nothrow) WebRtc_UWord8\n            [numOfElements * sizeOfElement];\n        if (ptrDataSorted == NULL)\n        {\n            return -1;\n        }\n\n        for (WebRtc_UWord32 i = 0; i < numOfElements; i++)\n        {\n            memcpy(ptrDataSorted + i * sizeOfElement, ptrData +\n                ptrSortKey[i].index * sizeOfElement, sizeOfElement);\n        }\n        memcpy(ptrData, ptrDataSorted, numOfElements * sizeOfElement);\n\n        delete[] ptrSortKey;\n        delete[] ptrDataSorted;\n\n        return 0;\n#else\n        // Fall back to std::sort for 64-bit types and floats due to compiler\n\t// warnings and errors respectively with spreadsort.\n        switch (keyType)\n        {\n        case TYPE_Word8:\n            return IntegerKeySort<WebRtc_Word8>(data, key, numOfElements,\n                                                sizeOfElement);\n        case TYPE_UWord8:\n            return IntegerKeySort<WebRtc_UWord8>(data, key, numOfElements,\n                                                 sizeOfElement);\n        case TYPE_Word16:\n            return IntegerKeySort<WebRtc_Word16>(data, key, numOfElements,\n                                                 sizeOfElement);\n        case TYPE_UWord16:\n            return IntegerKeySort<WebRtc_UWord16>(data, key, numOfElements,\n                                                  sizeOfElement);\n        case TYPE_Word32:\n            return IntegerKeySort<WebRtc_Word32>(data, key, numOfElements,\n                                                 sizeOfElement);\n        case TYPE_UWord32:\n            return IntegerKeySort<WebRtc_UWord32>(data, key, numOfElements,\n                                                  sizeOfElement);\n        case TYPE_Word64:\n            return StdKeySort<WebRtc_Word64>(data, key, numOfElements,\n                                             sizeOfElement);\n        case TYPE_UWord64:\n            return StdKeySort<WebRtc_UWord64>(data, key, numOfElements,\n                                              sizeOfElement);\n        case TYPE_Float32:\n            return StdKeySort<float>(data, key, numOfElements, sizeOfElement);\n        case TYPE_Float64:\n            return StdKeySort<double>(data, key, numOfElements, sizeOfElement);\n        default:\n            return -1;\n        }\n#endif\n    }\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/spreadsortlib/constants.hpp",
    "content": "/*Boost Software License - Version 1.0 - August 17th, 2003\r\n\r\nPermission is hereby granted, free of charge, to any person or organization\r\nobtaining a copy of the software and accompanying documentation covered by\r\nthis license (the \"Software\") to use, reproduce, display, distribute,\r\nexecute, and transmit the Software, and to prepare derivative works of the\r\nSoftware, and to permit third-parties to whom the Software is furnished to\r\ndo so, all subject to the following:\r\n\r\nThe copyright notices in the Software and this entire statement, including\r\nthe above license grant, this restriction and the following disclaimer,\r\nmust be included in all copies of the Software, in whole or in part, and\r\nall derivative works of the Software, unless such copies or derivative\r\nworks are solely in the form of machine-executable object code generated by\r\na source language processor.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\r\nSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\r\nFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\r\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\nDEALINGS IN THE SOFTWARE.*/\r\n#ifndef BOOST_SPREADSORT_CONSTANTS\r\n#define BOOST_SPREADSORT_CONSTANTS\r\nnamespace boost {\r\nnamespace detail {\r\n//Tuning constants\r\n//Sets the minimum number of items per bin.\r\nstatic const unsigned LOG_MEAN_BIN_SIZE = 2;\r\n//This should be tuned to your processor cache; if you go too large you get cache misses on bins\r\n//The smaller this number, the less worst-case memory usage.  If too small, too many recursions slow down spreadsort\r\nstatic const unsigned MAX_SPLITS = 10;\r\n//Used to force a comparison-based sorting for small bins, if it's faster.  Minimum value 0\r\nstatic const unsigned LOG_MIN_SPLIT_COUNT = 5;\r\n//There is a minimum size below which it is not worth using spreadsort\r\nstatic const long MIN_SORT_SIZE = 1000;\r\n//This is the constant on the log base n of m calculation; make this larger the faster std::sort is relative to spreadsort\r\nstatic const unsigned LOG_CONST = 2;\r\n}\r\n}\r\n#endif\r\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/spreadsortlib/spreadsort.hpp",
    "content": "//Templated spread_sort library\r\n\r\n//          Copyright Steven J. Ross 2001 - 2009.\r\n// Distributed under the Boost Software License, Version 1.0.\r\n//    (See accompanying file LICENSE_1_0.txt or copy at\r\n//          http://www.boost.org/LICENSE_1_0.txt)\r\n\r\n//  See http://www.boost.org/ for updates, documentation, and revision history.\r\n\t\t  \r\n/*\r\nSome improvements suggested by:\r\nPhil Endecott and Frank Gennari\r\nCygwin fix provided by:\r\nScott McMurray\r\n*/\r\n\r\n#ifndef BOOST_SPREAD_SORT_H\r\n#define BOOST_SPREAD_SORT_H\r\n#include <algorithm>\r\n#include <vector>\r\n#include \"constants.hpp\"\r\n#include <cstring>\r\n\r\nnamespace boost {\r\n  namespace detail {\r\n  \t//This only works on unsigned data types\r\n  \ttemplate <typename T>\r\n  \tinline unsigned \r\n  \trough_log_2_size(const T& input) \r\n  \t{\r\n  \t\tunsigned result = 0;\r\n  \t\t//The && is necessary on some compilers to avoid infinite loops; it doesn't significantly impair performance\r\n  \t\twhile((input >> result) && (result < (8*sizeof(T)))) ++result;\r\n  \t\treturn result;\r\n  \t}\r\n\r\n  \t//Gets the maximum size which we'll call spread_sort on to control worst-case performance\r\n  \t//Maintains both a minimum size to recurse and a check of distribution size versus count\r\n  \t//This is called for a set of bins, instead of bin-by-bin, to avoid performance overhead\r\n  \tinline size_t\r\n  \tget_max_count(unsigned log_range, size_t count)\r\n  \t{\r\n  \t\tunsigned divisor = rough_log_2_size(count);\r\n  \t\t//Making sure the divisor is positive\r\n  \t\tif(divisor > LOG_MEAN_BIN_SIZE)\r\n  \t\t\tdivisor -= LOG_MEAN_BIN_SIZE;\r\n  \t\telse\r\n  \t\t\tdivisor = 1;\r\n  \t\tunsigned relative_width = (LOG_CONST * log_range)/((divisor > MAX_SPLITS) ? MAX_SPLITS : divisor);\r\n  \t\t//Don't try to bitshift more than the size of an element\r\n  \t\tif((8*sizeof(size_t)) <= relative_width)\r\n  \t\t\trelative_width = (8*sizeof(size_t)) - 1;\r\n  \t\treturn (size_t)1 << ((relative_width < (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT)) ? \r\n  \t\t\t(LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT) :  relative_width);\r\n  \t}\r\n\r\n  \t//Find the minimum and maximum using <\r\n  \ttemplate <class RandomAccessIter>\r\n  \tinline void \r\n  \tfind_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min)\r\n  \t{\r\n  \t\tmin = max = current;\r\n  \t\t//Start from the second item, as max and min are initialized to the first\r\n  \t\twhile(++current < last) {\r\n  \t\t\tif(*max < *current)\r\n  \t\t\t\tmax = current;\r\n  \t\t\telse if(*current < *min)\r\n  \t\t\t\tmin = current;\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Uses a user-defined comparison operator to find minimum and maximum\r\n  \ttemplate <class RandomAccessIter, class compare>\r\n  \tinline void \r\n  \tfind_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min, compare comp)\r\n  \t{\r\n  \t\tmin = max = current;\r\n  \t\twhile(++current < last) {\r\n  \t\t\tif(comp(*max, *current))\r\n  \t\t\t\tmax = current;\r\n  \t\t\telse if(comp(*current, *min))\r\n  \t\t\t\tmin = current;\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Gets a non-negative right bit shift to operate as a logarithmic divisor\r\n  \tinline int\r\n  \tget_log_divisor(size_t count, unsigned log_range)\r\n  \t{\r\n  \t\tint log_divisor;\r\n  \t\t//If we can finish in one iteration without exceeding either (2 to the MAX_SPLITS) or n bins, do so\r\n  \t\tif((log_divisor = log_range - rough_log_2_size(count)) <= 0 && log_range < MAX_SPLITS)\r\n  \t\t\tlog_divisor = 0;\r\n  \t\telse {\r\n  \t\t\t//otherwise divide the data into an optimized number of pieces\r\n  \t\t\tlog_divisor += LOG_MEAN_BIN_SIZE;\r\n  \t\t\tif(log_divisor < 0)\r\n  \t\t\t\tlog_divisor = 0;\r\n  \t\t\t//Cannot exceed MAX_SPLITS or cache misses slow down bin lookups dramatically\r\n  \t\t\tif((log_range - log_divisor) > MAX_SPLITS)\r\n  \t\t\t\tlog_divisor = log_range - MAX_SPLITS;\r\n  \t\t}\r\n  \t\treturn log_divisor;\r\n  \t}\r\n\r\n  \ttemplate <class RandomAccessIter>\r\n  \tinline RandomAccessIter * \r\n  \tsize_bins(std::vector<size_t> &bin_sizes, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset, unsigned &cache_end, unsigned bin_count)\r\n  \t{\r\n  \t\t//Assure space for the size of each bin, followed by initializing sizes\r\n  \t\tif(bin_count > bin_sizes.size())\r\n  \t\t\tbin_sizes.resize(bin_count);\r\n  \t\tfor(size_t u = 0; u < bin_count; u++)\r\n  \t\t\tbin_sizes[u] = 0;\r\n  \t\t//Make sure there is space for the bins\r\n  \t\tcache_end = cache_offset + bin_count;\r\n  \t\tif(cache_end > bin_cache.size())\r\n  \t\t\tbin_cache.resize(cache_end);\r\n  \t\treturn &(bin_cache[cache_offset]);\r\n  \t}\r\n\r\n  \t//Implementation for recursive integer sorting\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type>\r\n  \tinline void \r\n  \tspread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset\r\n  \t\t\t\t  , std::vector<size_t> &bin_sizes)\r\n  \t{\r\n  \t\t//This step is roughly 10% of runtime, but it helps avoid worst-case behavior and improve behavior with real data\r\n  \t\t//If you know the maximum and minimum ahead of time, you can pass those values in and skip this step for the first iteration\r\n  \t\tRandomAccessIter max, min;\r\n  \t\tfind_extremes(first, last, max, min);\r\n  \t\t//max and min will be the same (the first item) iff all values are equivalent\r\n  \t\tif(max == min)\r\n  \t\t\treturn;\r\n  \t\tRandomAccessIter * target_bin;\r\n  \t\tunsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(*max >> 0) - (*min >> 0)));\r\n  \t\tdiv_type div_min = *min >> log_divisor;\r\n  \t\tdiv_type div_max = *max >> log_divisor;\r\n  \t\tunsigned bin_count = div_max - div_min + 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);\r\n  \t\r\n  \t\t//Calculating the size of each bin; this takes roughly 10% of runtime\r\n  \t\tfor (RandomAccessIter current = first; current != last;)\r\n  \t\t\tbin_sizes[(*(current++) >> log_divisor) - div_min]++;\r\n  \t\t//Assign the bin positions\r\n  \t\tbins[0] = first;\r\n  \t\tfor(unsigned u = 0; u < bin_count - 1; u++)\r\n  \t\t\tbins[u + 1] = bins[u] + bin_sizes[u];\r\n  \r\n  \t\t//Swap into place\r\n  \t\t//This dominates runtime, mostly in the swap and bin lookups\r\n  \t\tRandomAccessIter nextbinstart = first;\r\n  \t\tfor(unsigned u = 0; u < bin_count - 1; ++u) {\r\n  \t\t\tRandomAccessIter * local_bin = bins + u;\r\n  \t\t\tnextbinstart += bin_sizes[u];\r\n  \t\t\t//Iterating over each element in this bin\r\n  \t\t\tfor(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {\r\n  \t\t\t\t//Swapping elements in current into place until the correct element has been swapped in\r\n  \t\t\t\tfor(target_bin = (bins + ((*current >> log_divisor) - div_min));  target_bin != local_bin; \r\n  \t\t\t\t\ttarget_bin = bins + ((*current >> log_divisor) - div_min)) {\r\n  \t\t\t\t\t//3-way swap; this is about 1% faster than a 2-way swap with integers\r\n  \t\t\t\t\t//The main advantage is less copies are involved per item put in the correct place\r\n  \t\t\t\t\tdata_type tmp;\r\n  \t\t\t\t\tRandomAccessIter b = (*target_bin)++;\r\n  \t\t\t\t\tRandomAccessIter * b_bin = bins + ((*b >> log_divisor) - div_min);\r\n  \t\t\t\t\tif (b_bin != local_bin) {\r\n  \t\t\t\t\t\tRandomAccessIter c = (*b_bin)++;\r\n  \t\t\t\t\t\ttmp = *c;\r\n  \t\t\t\t\t\t*c = *b;\r\n  \t\t\t\t\t} \r\n  \t\t\t\t\telse\r\n  \t\t\t\t\t\ttmp = *b;\r\n  \t\t\t\t\t*b = *current;\r\n  \t\t\t\t\t*current = tmp;\r\n  \t\t\t\t}\r\n  \t\t\t}\r\n  \t\t\t*local_bin = nextbinstart;\r\n  \t\t}\r\n  \t\tbins[bin_count - 1] = last;\r\n  \r\n  \t\t//If we've bucketsorted, the array is sorted and we should skip recursion\r\n  \t\tif(!log_divisor)\r\n  \t\t\treturn;\r\n  \r\n  \t\t//Recursing; log_divisor is the remaining range\r\n  \t\tsize_t max_count = get_max_count(log_divisor, last - first);\r\n  \t\tRandomAccessIter lastPos = first;\r\n  \t\tfor(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {\r\n  \t\t\tsize_t count = bin_cache[u] - lastPos;\r\n  \t\t\t//don't sort unless there are at least two items to compare\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\t//using std::sort if its worst-case is better\r\n  \t\t\tif(count < max_count)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[u]);\r\n  \t\t\telse\r\n  \t\t\t\tspread_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Generic bitshift-based 3-way swapping code\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type, class right_shift>\r\n  \tinline void inner_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift\r\n  \t\t, const unsigned log_divisor, const div_type div_min) \r\n  \t{\r\n  \t\tRandomAccessIter * local_bin = bins + ii;\r\n  \t\tfor(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {\r\n  \t\t\tfor(RandomAccessIter * target_bin = (bins + (shift(*current, log_divisor) - div_min));  target_bin != local_bin; \r\n  \t\t\t\ttarget_bin = bins + (shift(*current, log_divisor) - div_min)) {\r\n  \t\t\t\tdata_type tmp;\r\n  \t\t\t\tRandomAccessIter b = (*target_bin)++;\r\n  \t\t\t\tRandomAccessIter * b_bin = bins + (shift(*b, log_divisor) - div_min);\r\n  \t\t\t\t//Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs\r\n  \t\t\t\tif (b_bin != local_bin) {\r\n  \t\t\t\t\tRandomAccessIter c = (*b_bin)++;\r\n  \t\t\t\t\ttmp = *c;\r\n  \t\t\t\t\t*c = *b;\r\n  \t\t\t\t} \r\n  \t\t\t\t//Note: we could increment current once the swap is done in this case, but that seems to impair performance\r\n  \t\t\t\telse\r\n  \t\t\t\t\ttmp = *b;\r\n  \t\t\t\t*b = *current;\r\n  \t\t\t\t*current = tmp;\r\n  \t\t\t}\r\n  \t\t}\r\n  \t\t*local_bin = nextbinstart;\r\n  \t}\r\n\r\n  \t//Standard swapping wrapper for ascending values\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type, class right_shift>\r\n  \tinline void swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift\r\n  \t\t, const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min) \r\n  \t{\r\n  \t\tnextbinstart += bin_sizes[ii];\r\n  \t\tinner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, log_divisor, div_min);\r\n  \t}\r\n\r\n  \t//Functor implementation for recursive sorting\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>\r\n  \tinline void \r\n  \tspread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset\r\n  \t\t\t\t\t, std::vector<size_t> &bin_sizes, right_shift shift, compare comp)\r\n  \t{\r\n  \t\tRandomAccessIter max, min;\r\n  \t\tfind_extremes(first, last, max, min, comp);\r\n  \t\tif(max == min)\r\n  \t\t\treturn;\r\n  \t\tunsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0))));\r\n  \t\tdiv_type div_min = shift(*min, log_divisor);\r\n  \t\tdiv_type div_max = shift(*max, log_divisor);\r\n  \t\tunsigned bin_count = div_max - div_min + 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin\r\n  \t\tfor (RandomAccessIter current = first; current != last;)\r\n  \t\t\tbin_sizes[shift(*(current++), log_divisor) - div_min]++;\r\n  \t\tbins[0] = first;\r\n  \t\tfor(unsigned u = 0; u < bin_count - 1; u++)\r\n  \t\t\tbins[u + 1] = bins[u] + bin_sizes[u];\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = first;\r\n  \t\tfor(unsigned u = 0; u < bin_count - 1; ++u)\r\n  \t\t\tswap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, bin_sizes, log_divisor, div_min);\r\n  \t\tbins[bin_count - 1] = last;\r\n  \t\t\r\n  \t\t//If we've bucketsorted, the array is sorted and we should skip recursion\r\n  \t\tif(!log_divisor)\r\n  \t\t\treturn;\r\n  \t\t\r\n  \t\t//Recursing\r\n  \t\tsize_t max_count = get_max_count(log_divisor, last - first);\r\n  \t\tRandomAccessIter lastPos = first;\r\n  \t\tfor(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {\r\n  \t\t\tsize_t count = bin_cache[u] - lastPos;\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\tif(count < max_count)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[u], comp);\r\n  \t\t\telse\r\n  \t\t\t\tspread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp);\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Functor implementation for recursive sorting with only Shift overridden\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type, class right_shift>\r\n  \tinline void \r\n  \tspread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset\r\n  \t\t\t\t\t, std::vector<size_t> &bin_sizes, right_shift shift)\r\n  \t{\r\n  \t\tRandomAccessIter max, min;\r\n  \t\tfind_extremes(first, last, max, min);\r\n  \t\tif(max == min)\r\n  \t\t\treturn;\r\n  \t\tunsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0))));\r\n  \t\tdiv_type div_min = shift(*min, log_divisor);\r\n  \t\tdiv_type div_max = shift(*max, log_divisor);\r\n  \t\tunsigned bin_count = div_max - div_min + 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin\r\n  \t\tfor (RandomAccessIter current = first; current != last;)\r\n  \t\t\tbin_sizes[shift(*(current++), log_divisor) - div_min]++;\r\n  \t\tbins[0] = first;\r\n  \t\tfor(unsigned u = 0; u < bin_count - 1; u++)\r\n  \t\t\tbins[u + 1] = bins[u] + bin_sizes[u];\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = first;\r\n  \t\tfor(unsigned ii = 0; ii < bin_count - 1; ++ii)\r\n  \t\t\tswap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);\r\n  \t\tbins[bin_count - 1] = last;\r\n  \t\t\r\n  \t\t//If we've bucketsorted, the array is sorted and we should skip recursion\r\n  \t\tif(!log_divisor)\r\n  \t\t\treturn;\r\n  \t\t\r\n  \t\t//Recursing\r\n  \t\tsize_t max_count = get_max_count(log_divisor, last - first);\r\n  \t\tRandomAccessIter lastPos = first;\r\n  \t\tfor(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {\r\n  \t\t\tsize_t count = bin_cache[u] - lastPos;\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\tif(count < max_count)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[u]);\r\n  \t\t\telse\r\n  \t\t\t\tspread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift);\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Holds the bin vector and makes the initial recursive call\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type>\r\n  \tinline void \r\n  \tspread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type)\r\n  \t{\r\n  \t\tstd::vector<size_t> bin_sizes;\r\n  \t\tstd::vector<RandomAccessIter> bin_cache;\r\n  \t\tspread_sort_rec<RandomAccessIter, div_type, data_type>(first, last, bin_cache, 0, bin_sizes);\r\n  \t}\r\n\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>\r\n  \tinline void \r\n  \tspread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp)\r\n  \t{\r\n  \t\tstd::vector<size_t> bin_sizes;\r\n  \t\tstd::vector<RandomAccessIter> bin_cache;\r\n  \t\tspread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(first, last, bin_cache, 0, bin_sizes, shift, comp);\r\n  \t}\r\n\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type, class right_shift>\r\n  \tinline void \r\n  \tspread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift)\r\n  \t{\r\n  \t\tstd::vector<size_t> bin_sizes;\r\n  \t\tstd::vector<RandomAccessIter> bin_cache;\r\n  \t\tspread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift);\r\n  \t}\r\n  }\r\n\r\n  //Top-level sorting call for integers\r\n  template <class RandomAccessIter>\r\n  inline void integer_sort(RandomAccessIter first, RandomAccessIter last) \r\n  {\r\n  \t//Don't sort if it's too small to optimize\r\n  \tif(last - first < detail::MIN_SORT_SIZE)\r\n  \t\tstd::sort(first, last);\r\n  \telse\r\n  \t\tdetail::spread_sort(first, last, *first >> 0, *first);\r\n  }\r\n\r\n  //integer_sort with functors\r\n  template <class RandomAccessIter, class right_shift, class compare>\r\n  inline void integer_sort(RandomAccessIter first, RandomAccessIter last,\r\n  \t\t\t\t\t\tright_shift shift, compare comp) {\r\n  \tif(last - first < detail::MIN_SORT_SIZE)\r\n  \t\tstd::sort(first, last, comp);\r\n  \telse\r\n  \t\tdetail::spread_sort(first, last, shift(*first, 0), *first, shift, comp);\r\n  }\r\n\r\n  //integer_sort with right_shift functor\r\n  template <class RandomAccessIter, class right_shift>\r\n  inline void integer_sort(RandomAccessIter first, RandomAccessIter last,\r\n  \t\t\t\t\t\tright_shift shift) {\r\n  \tif(last - first < detail::MIN_SORT_SIZE)\r\n  \t\tstd::sort(first, last);\r\n  \telse\r\n  \t\tdetail::spread_sort(first, last, shift(*first, 0), *first, shift);\r\n  }\r\n\r\n  //------------------------------------------------------ float_sort source --------------------------------------\r\n  //Casts a RandomAccessIter to the specified data type\r\n  template<class cast_type, class RandomAccessIter>\r\n  inline cast_type\r\n  cast_float_iter(const RandomAccessIter & floatiter)\r\n  {\r\n  \tcast_type result;\r\n  \tstd::memcpy(&result, &(*floatiter), sizeof(cast_type));\r\n  \treturn result;\r\n  }\r\n\r\n  //Casts a data element to the specified datinner_float_a type\r\n  template<class data_type, class cast_type>\r\n  inline cast_type\r\n  mem_cast(const data_type & data)\r\n  {\r\n  \tcast_type result;\r\n  \tstd::memcpy(&result, &data, sizeof(cast_type));\r\n  \treturn result;\r\n  }\r\n\r\n  namespace detail {\r\n  \ttemplate <class RandomAccessIter, class div_type, class right_shift>\r\n  \tinline void \r\n  \tfind_extremes(RandomAccessIter current, RandomAccessIter last, div_type & max, div_type & min, right_shift shift)\r\n  \t{\r\n  \t\tmin = max = shift(*current, 0);\r\n  \t\twhile(++current < last) {\r\n  \t\t\tdiv_type value = shift(*current, 0);\r\n  \t\t\tif(max < value)\r\n  \t\t\t\tmax = value;\r\n  \t\t\telse if(value < min)\r\n  \t\t\t\tmin = value;\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Specialized swap loops for floating-point casting\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type>\r\n  \tinline void inner_float_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii\r\n  \t\t, const unsigned log_divisor, const div_type div_min) \r\n  \t{\r\n  \t\tRandomAccessIter * local_bin = bins + ii;\r\n  \t\tfor(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {\r\n  \t\t\tfor(RandomAccessIter * target_bin = (bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min));  target_bin != local_bin; \r\n  \t\t\t\ttarget_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)) {\r\n  \t\t\t\tdata_type tmp;\r\n  \t\t\t\tRandomAccessIter b = (*target_bin)++;\r\n  \t\t\t\tRandomAccessIter * b_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(b) >> log_divisor) - div_min);\r\n  \t\t\t\t//Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs\r\n  \t\t\t\tif (b_bin != local_bin) {\r\n  \t\t\t\t\tRandomAccessIter c = (*b_bin)++;\r\n  \t\t\t\t\ttmp = *c;\r\n  \t\t\t\t\t*c = *b;\r\n  \t\t\t\t} \r\n  \t\t\t\telse\r\n  \t\t\t\t\ttmp = *b;\r\n  \t\t\t\t*b = *current;\r\n  \t\t\t\t*current = tmp;\r\n  \t\t\t}\r\n  \t\t}\r\n  \t\t*local_bin = nextbinstart;\r\n  \t}\r\n\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type>\r\n  \tinline void float_swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii\r\n  \t\t, const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min) \r\n  \t{\r\n  \t\tnextbinstart += bin_sizes[ii];\r\n  \t\tinner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, log_divisor, div_min);\r\n  \t}\r\n\r\n  \ttemplate <class RandomAccessIter, class cast_type>\r\n  \tinline void \r\n  \tfind_extremes(RandomAccessIter current, RandomAccessIter last, cast_type & max, cast_type & min)\r\n  \t{\r\n  \t\tmin = max = cast_float_iter<cast_type, RandomAccessIter>(current);\r\n  \t\twhile(++current < last) {\r\n  \t\t\tcast_type value = cast_float_iter<cast_type, RandomAccessIter>(current);\r\n  \t\t\tif(max < value)\r\n  \t\t\t\tmax = value;\r\n  \t\t\telse if(value < min)\r\n  \t\t\t\tmin = value;\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Special-case sorting of positive floats with casting instead of a right_shift\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type>\r\n  \tinline void \r\n  \tpositive_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset\r\n  \t\t\t\t\t, std::vector<size_t> &bin_sizes)\r\n  \t{\r\n  \t\tdiv_type max, min;\r\n  \t\tfind_extremes(first, last, max, min);\r\n  \t\tif(max == min)\r\n  \t\t\treturn;\r\n  \t\tunsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));\r\n  \t\tdiv_type div_min = min >> log_divisor;\r\n  \t\tdiv_type div_max = max >> log_divisor;\r\n  \t\tunsigned bin_count = div_max - div_min + 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin\r\n  \t\tfor (RandomAccessIter current = first; current != last;)\r\n  \t\t\tbin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;\r\n  \t\tbins[0] = first;\r\n  \t\tfor(unsigned u = 0; u < bin_count - 1; u++)\r\n  \t\t\tbins[u + 1] = bins[u] + bin_sizes[u];\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = first;\r\n  \t\tfor(unsigned u = 0; u < bin_count - 1; ++u)\r\n  \t\t\tfloat_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, bin_sizes, log_divisor, div_min);\r\n  \t\tbins[bin_count - 1] = last;\r\n  \t\t\r\n  \t\t//Return if we've completed bucketsorting\r\n  \t\tif(!log_divisor)\r\n  \t\t\treturn;\r\n  \t\t\r\n  \t\t//Recursing\r\n  \t\tsize_t max_count = get_max_count(log_divisor, last - first);\r\n  \t\tRandomAccessIter lastPos = first;\r\n  \t\tfor(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {\r\n  \t\t\tsize_t count = bin_cache[u] - lastPos;\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\tif(count < max_count)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[u]);\r\n  \t\t\telse\r\n  \t\t\t\tpositive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Sorting negative_ float_s\r\n  \t//Note that bins are iterated in reverse order because max_neg_float = min_neg_int\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type>\r\n  \tinline void \r\n  \tnegative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset\r\n  \t\t\t\t\t, std::vector<size_t> &bin_sizes)\r\n  \t{\r\n  \t\tdiv_type max, min;\r\n  \t\tfind_extremes(first, last, max, min);\r\n  \t\tif(max == min)\r\n  \t\t\treturn;\r\n  \t\tunsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));\r\n  \t\tdiv_type div_min = min >> log_divisor;\r\n  \t\tdiv_type div_max = max >> log_divisor;\r\n  \t\tunsigned bin_count = div_max - div_min + 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin\r\n  \t\tfor (RandomAccessIter current = first; current != last;)\r\n  \t\t\tbin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;\r\n  \t\tbins[bin_count - 1] = first;\r\n  \t\tfor(int ii = bin_count - 2; ii >= 0; --ii)\r\n  \t\t\tbins[ii] = bins[ii + 1] + bin_sizes[ii + 1];\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = first;\r\n  \t\t//The last bin will always have the correct elements in it\r\n  \t\tfor(int ii = bin_count - 1; ii > 0; --ii)\r\n  \t\t\tfloat_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, bin_sizes, log_divisor, div_min);\r\n  \t\t//Since we don't process the last bin, we need to update its end position\r\n  \t\tbin_cache[cache_offset] = last;\r\n  \t\t\r\n  \t\t//Return if we've completed bucketsorting\r\n  \t\tif(!log_divisor)\r\n  \t\t\treturn;\r\n  \t\t\r\n  \t\t//Recursing\r\n  \t\tsize_t max_count = get_max_count(log_divisor, last - first);\r\n  \t\tRandomAccessIter lastPos = first;\r\n  \t\tfor(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {\r\n  \t\t\tsize_t count = bin_cache[ii] - lastPos;\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\tif(count < max_count)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[ii]);\r\n  \t\t\telse\r\n  \t\t\t\tnegative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes);\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Sorting negative_ float_s\r\n  \t//Note that bins are iterated in reverse order because max_neg_float = min_neg_int\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type, class right_shift>\r\n  \tinline void \r\n  \tnegative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset\r\n  \t\t\t\t\t, std::vector<size_t> &bin_sizes, right_shift shift)\r\n  \t{\r\n  \t\tdiv_type max, min;\r\n  \t\tfind_extremes(first, last, max, min, shift);\r\n  \t\tif(max == min)\r\n  \t\t\treturn;\r\n  \t\tunsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));\r\n  \t\tdiv_type div_min = min >> log_divisor;\r\n  \t\tdiv_type div_max = max >> log_divisor;\r\n  \t\tunsigned bin_count = div_max - div_min + 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin\r\n  \t\tfor (RandomAccessIter current = first; current != last;)\r\n  \t\t\tbin_sizes[shift(*(current++), log_divisor) - div_min]++;\r\n  \t\tbins[bin_count - 1] = first;\r\n  \t\tfor(int ii = bin_count - 2; ii >= 0; --ii)\r\n  \t\t\tbins[ii] = bins[ii + 1] + bin_sizes[ii + 1];\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = first;\r\n  \t\t//The last bin will always have the correct elements in it\r\n  \t\tfor(int ii = bin_count - 1; ii > 0; --ii)\r\n  \t\t\tswap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);\r\n  \t\t//Since we don't process the last bin, we need to update its end position\r\n  \t\tbin_cache[cache_offset] = last;\r\n  \t\t\r\n  \t\t//Return if we've completed bucketsorting\r\n  \t\tif(!log_divisor)\r\n  \t\t\treturn;\r\n  \t\t\r\n  \t\t//Recursing\r\n  \t\tsize_t max_count = get_max_count(log_divisor, last - first);\r\n  \t\tRandomAccessIter lastPos = first;\r\n  \t\tfor(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {\r\n  \t\t\tsize_t count = bin_cache[ii] - lastPos;\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\tif(count < max_count)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[ii]);\r\n  \t\t\telse\r\n  \t\t\t\tnegative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift);\r\n  \t\t}\r\n  \t}\r\n\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>\r\n  \tinline void \r\n  \tnegative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset\r\n  \t\t\t\t\t, std::vector<size_t> &bin_sizes, right_shift shift, compare comp)\r\n  \t{\r\n  \t\tdiv_type max, min;\r\n  \t\tfind_extremes(first, last, max, min, shift);\r\n  \t\tif(max == min)\r\n  \t\t\treturn;\r\n  \t\tunsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));\r\n  \t\tdiv_type div_min = min >> log_divisor;\r\n  \t\tdiv_type div_max = max >> log_divisor;\r\n  \t\tunsigned bin_count = div_max - div_min + 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin\r\n  \t\tfor (RandomAccessIter current = first; current != last;)\r\n  \t\t\tbin_sizes[shift(*(current++), log_divisor) - div_min]++;\r\n  \t\tbins[bin_count - 1] = first;\r\n  \t\tfor(int ii = bin_count - 2; ii >= 0; --ii)\r\n  \t\t\tbins[ii] = bins[ii + 1] + bin_sizes[ii + 1];\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = first;\r\n  \t\t//The last bin will always have the correct elements in it\r\n  \t\tfor(int ii = bin_count - 1; ii > 0; --ii)\r\n  \t\t\tswap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);\r\n  \t\t//Since we don't process the last bin, we need to update its end position\r\n  \t\tbin_cache[cache_offset] = last;\r\n  \t\t\r\n  \t\t//Return if we've completed bucketsorting\r\n  \t\tif(!log_divisor)\r\n  \t\t\treturn;\r\n  \t\t\r\n  \t\t//Recursing\r\n  \t\tsize_t max_count = get_max_count(log_divisor, last - first);\r\n  \t\tRandomAccessIter lastPos = first;\r\n  \t\tfor(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {\r\n  \t\t\tsize_t count = bin_cache[ii] - lastPos;\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\tif(count < max_count)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[ii], comp);\r\n  \t\t\telse\r\n  \t\t\t\tnegative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp);\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Casting special-case for floating-point sorting\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type>\r\n  \tinline void \r\n  \tfloat_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset\r\n  \t\t\t\t\t, std::vector<size_t> &bin_sizes)\r\n  \t{\r\n  \t\tdiv_type max, min;\r\n  \t\tfind_extremes(first, last, max, min);\r\n  \t\tif(max == min)\r\n  \t\t\treturn;\r\n  \t\tunsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));\r\n  \t\tdiv_type div_min = min >> log_divisor;\r\n  \t\tdiv_type div_max = max >> log_divisor;\r\n  \t\tunsigned bin_count = div_max - div_min + 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin\r\n  \t\tfor (RandomAccessIter current = first; current != last;)\r\n  \t\t\tbin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;\r\n  \t\t//The index of the first positive bin\r\n  \t\tdiv_type first_positive = (div_min < 0) ? -div_min : 0;\r\n  \t\t//Resetting if all bins are negative\r\n  \t\tif(cache_offset + first_positive > cache_end)\r\n  \t\t\tfirst_positive = cache_end - cache_offset;\r\n  \t\t//Reversing the order of the negative bins\r\n  \t\t//Note that because of the negative/positive ordering direction flip\r\n  \t\t//We can not depend upon bin order and positions matching up\r\n  \t\t//so bin_sizes must be reused to contain the end of the bin\r\n  \t\tif(first_positive > 0) {\r\n  \t\t\tbins[first_positive - 1] = first;\r\n  \t\t\tfor(int ii = first_positive - 2; ii >= 0; --ii) {\r\n  \t\t\t\tbins[ii] = first + bin_sizes[ii + 1];\r\n  \t\t\t\tbin_sizes[ii] += bin_sizes[ii + 1];\r\n  \t\t\t}\r\n  \t\t\t//Handling positives following negatives\r\n  \t\t\tif((unsigned)first_positive < bin_count) {\r\n  \t\t\t\tbins[first_positive] = first + bin_sizes[0];\r\n  \t\t\t\tbin_sizes[first_positive] += bin_sizes[0];\r\n  \t\t\t}\r\n  \t\t}\r\n  \t\telse\r\n  \t\t\tbins[0] = first;\r\n  \t\tfor(unsigned u = first_positive; u < bin_count - 1; u++) {\r\n  \t\t\tbins[u + 1] = first + bin_sizes[u];\r\n  \t\t\tbin_sizes[u + 1] += bin_sizes[u];\r\n  \t\t}\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = first;\r\n  \t\tfor(unsigned u = 0; u < bin_count; ++u) {\r\n  \t\t\tnextbinstart = first + bin_sizes[u];\r\n  \t\t\tinner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, log_divisor, div_min);\r\n  \t\t}\r\n  \t\t\r\n  \t\tif(!log_divisor)\r\n  \t\t\treturn;\r\n  \t\t\r\n  \t\t//Handling negative values first\r\n  \t\tsize_t max_count = get_max_count(log_divisor, last - first);\r\n  \t\tRandomAccessIter lastPos = first;\r\n  \t\tfor(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {\r\n  \t\t\tsize_t count = bin_cache[ii] - lastPos;\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\tif(count < max_count)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[ii]);\r\n  \t\t\t//sort negative values using reversed-bin spread_sort\r\n  \t\t\telse\r\n  \t\t\t\tnegative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes);\r\n  \t\t}\r\n  \t\t\r\n  \t\tfor(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {\r\n  \t\t\tsize_t count = bin_cache[u] - lastPos;\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\tif(count < max_count)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[u]);\r\n  \t\t\t//sort positive values using normal spread_sort\r\n  \t\t\telse\r\n  \t\t\t\tpositive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Functor implementation for recursive sorting\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type, class right_shift>\r\n  \tinline void \r\n  \tfloat_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset\r\n  \t\t\t\t\t, std::vector<size_t> &bin_sizes, right_shift shift)\r\n  \t{\r\n  \t\tdiv_type max, min;\r\n  \t\tfind_extremes(first, last, max, min, shift);\r\n  \t\tif(max == min)\r\n  \t\t\treturn;\r\n  \t\tunsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));\r\n  \t\tdiv_type div_min = min >> log_divisor;\r\n  \t\tdiv_type div_max = max >> log_divisor;\r\n  \t\tunsigned bin_count = div_max - div_min + 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin\r\n  \t\tfor (RandomAccessIter current = first; current != last;)\r\n  \t\t\tbin_sizes[shift(*(current++), log_divisor) - div_min]++;\r\n  \t\t//The index of the first positive bin\r\n  \t\tdiv_type first_positive = (div_min < 0) ? -div_min : 0;\r\n  \t\t//Resetting if all bins are negative\r\n  \t\tif(cache_offset + first_positive > cache_end)\r\n  \t\t\tfirst_positive = cache_end - cache_offset;\r\n  \t\t//Reversing the order of the negative bins\r\n  \t\t//Note that because of the negative/positive ordering direction flip\r\n  \t\t//We can not depend upon bin order and positions matching up\r\n  \t\t//so bin_sizes must be reused to contain the end of the bin\r\n  \t\tif(first_positive > 0) {\r\n  \t\t\tbins[first_positive - 1] = first;\r\n  \t\t\tfor(int ii = first_positive - 2; ii >= 0; --ii) {\r\n  \t\t\t\tbins[ii] = first + bin_sizes[ii + 1];\r\n  \t\t\t\tbin_sizes[ii] += bin_sizes[ii + 1];\r\n  \t\t\t}\r\n  \t\t\t//Handling positives following negatives\r\n  \t\t\tif((unsigned)first_positive < bin_count) {\r\n  \t\t\t\tbins[first_positive] = first + bin_sizes[0];\r\n  \t\t\t\tbin_sizes[first_positive] += bin_sizes[0];\r\n  \t\t\t}\r\n  \t\t}\r\n  \t\telse\r\n  \t\t\tbins[0] = first;\r\n  \t\tfor(unsigned u = first_positive; u < bin_count - 1; u++) {\r\n  \t\t\tbins[u + 1] = first + bin_sizes[u];\r\n  \t\t\tbin_sizes[u + 1] += bin_sizes[u];\r\n  \t\t}\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = first;\r\n  \t\tfor(unsigned u = 0; u < bin_count; ++u) {\r\n  \t\t\tnextbinstart = first + bin_sizes[u];\r\n  \t\t\tinner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min);\r\n  \t\t}\r\n  \t\t\r\n  \t\t//Return if we've completed bucketsorting\r\n  \t\tif(!log_divisor)\r\n  \t\t\treturn;\r\n  \t\t\r\n  \t\t//Handling negative values first\r\n  \t\tsize_t max_count = get_max_count(log_divisor, last - first);\r\n  \t\tRandomAccessIter lastPos = first;\r\n  \t\tfor(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {\r\n  \t\t\tsize_t count = bin_cache[ii] - lastPos;\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\tif(count < max_count)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[ii]);\r\n  \t\t\t//sort negative values using reversed-bin spread_sort\r\n  \t\t\telse\r\n  \t\t\t\tnegative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift);\r\n  \t\t}\r\n  \t\t\r\n  \t\tfor(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {\r\n  \t\t\tsize_t count = bin_cache[u] - lastPos;\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\tif(count < max_count)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[u]);\r\n  \t\t\t//sort positive values using normal spread_sort\r\n  \t\t\telse\r\n  \t\t\t\tspread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift);\r\n  \t\t}\r\n  \t}\r\n\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>\r\n  \tinline void \r\n  \tfloat_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset\r\n  \t\t\t\t\t, std::vector<size_t> &bin_sizes, right_shift shift, compare comp)\r\n  \t{\r\n  \t\tdiv_type max, min;\r\n  \t\tfind_extremes(first, last, max, min, shift);\r\n  \t\tif(max == min)\r\n  \t\t\treturn;\r\n  \t\tunsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));\r\n  \t\tdiv_type div_min = min >> log_divisor;\r\n  \t\tdiv_type div_max = max >> log_divisor;\r\n  \t\tunsigned bin_count = div_max - div_min + 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin\r\n  \t\tfor (RandomAccessIter current = first; current != last;)\r\n  \t\t\tbin_sizes[shift(*(current++), log_divisor) - div_min]++;\r\n  \t\t//The index of the first positive bin\r\n  \t\tdiv_type first_positive = (div_min < 0) ? -div_min : 0;\r\n  \t\t//Resetting if all bins are negative\r\n  \t\tif(cache_offset + first_positive > cache_end)\r\n  \t\t\tfirst_positive = cache_end - cache_offset;\r\n  \t\t//Reversing the order of the negative bins\r\n  \t\t//Note that because of the negative/positive ordering direction flip\r\n  \t\t//We can not depend upon bin order and positions matching up\r\n  \t\t//so bin_sizes must be reused to contain the end of the bin\r\n  \t\tif(first_positive > 0) {\r\n  \t\t\tbins[first_positive - 1] = first;\r\n  \t\t\tfor(int ii = first_positive - 2; ii >= 0; --ii) {\r\n  \t\t\t\tbins[ii] = first + bin_sizes[ii + 1];\r\n  \t\t\t\tbin_sizes[ii] += bin_sizes[ii + 1];\r\n  \t\t\t}\r\n  \t\t\t//Handling positives following negatives\r\n  \t\t\tif((unsigned)first_positive < bin_count) {\r\n  \t\t\t\tbins[first_positive] = first + bin_sizes[0];\r\n  \t\t\t\tbin_sizes[first_positive] += bin_sizes[0];\r\n  \t\t\t}\r\n  \t\t}\r\n  \t\telse\r\n  \t\t\tbins[0] = first;\r\n  \t\tfor(unsigned u = first_positive; u < bin_count - 1; u++) {\r\n  \t\t\tbins[u + 1] = first + bin_sizes[u];\r\n  \t\t\tbin_sizes[u + 1] += bin_sizes[u];\r\n  \t\t}\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = first;\r\n  \t\tfor(unsigned u = 0; u < bin_count; ++u) {\r\n  \t\t\tnextbinstart = first + bin_sizes[u];\r\n  \t\t\tinner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min);\r\n  \t\t}\r\n  \t\t\r\n  \t\t//Return if we've completed bucketsorting\r\n  \t\tif(!log_divisor)\r\n  \t\t\treturn;\r\n  \t\t\r\n  \t\t//Handling negative values first\r\n  \t\tsize_t max_count = get_max_count(log_divisor, last - first);\r\n  \t\tRandomAccessIter lastPos = first;\r\n  \t\tfor(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {\r\n  \t\t\tsize_t count = bin_cache[ii] - lastPos;\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\tif(count < max_count)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[ii]);\r\n  \t\t\t//sort negative values using reversed-bin spread_sort\r\n  \t\t\telse\r\n  \t\t\t\tnegative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp);\r\n  \t\t}\r\n  \t\t\r\n  \t\tfor(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {\r\n  \t\t\tsize_t count = bin_cache[u] - lastPos;\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\tif(count < max_count)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[u]);\r\n  \t\t\t//sort positive values using normal spread_sort\r\n  \t\t\telse\r\n  \t\t\t\tspread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp);\r\n  \t\t}\r\n  \t}\r\n\r\n  \ttemplate <class RandomAccessIter, class cast_type, class data_type>\r\n  \tinline void \r\n  \tfloat_Sort(RandomAccessIter first, RandomAccessIter last, cast_type, data_type)\r\n  \t{\r\n  \t\tstd::vector<size_t> bin_sizes;\r\n  \t\tstd::vector<RandomAccessIter> bin_cache;\r\n  \t\tfloat_sort_rec<RandomAccessIter, cast_type, data_type>(first, last, bin_cache, 0, bin_sizes);\r\n  \t}\r\n\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type, class right_shift>\r\n  \tinline void \r\n  \tfloat_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift)\r\n  \t{\r\n  \t\tstd::vector<size_t> bin_sizes;\r\n  \t\tstd::vector<RandomAccessIter> bin_cache;\r\n  \t\tfloat_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift);\r\n  \t}\r\n\r\n  \ttemplate <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>\r\n  \tinline void \r\n  \tfloat_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp)\r\n  \t{\r\n  \t\tstd::vector<size_t> bin_sizes;\r\n  \t\tstd::vector<RandomAccessIter> bin_cache;\r\n  \t\tfloat_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift, comp);\r\n  \t}\r\n  }\r\n\r\n  //float_sort with casting\r\n  //The cast_type must be equal in size to the data type, and must be a signed integer\r\n  template <class RandomAccessIter, class cast_type>\r\n  inline void float_sort_cast(RandomAccessIter first, RandomAccessIter last, cast_type cVal) \r\n  {\r\n  \tif(last - first < detail::MIN_SORT_SIZE)\r\n  \t\tstd::sort(first, last);\r\n  \telse\r\n  \t\tdetail::float_Sort(first, last, cVal, *first);\r\n  }\r\n\r\n  //float_sort with casting to an int\r\n  //Only use this with IEEE floating-point numbers\r\n  template <class RandomAccessIter>\r\n  inline void float_sort_cast_to_int(RandomAccessIter first, RandomAccessIter last) \r\n  {\r\n  \tint cVal = 0;\r\n  \tfloat_sort_cast(first, last, cVal);\r\n  }\r\n\r\n  //float_sort with functors\r\n  template <class RandomAccessIter, class right_shift>\r\n  inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift) \r\n  {\r\n  \tif(last - first < detail::MIN_SORT_SIZE)\r\n  \t\tstd::sort(first, last);\r\n  \telse\r\n  \t\tdetail::float_Sort(first, last, shift(*first, 0), *first, shift);\r\n  }\r\n\r\n  template <class RandomAccessIter, class right_shift, class compare>\r\n  inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift, compare comp) \r\n  {\r\n  \tif(last - first < detail::MIN_SORT_SIZE)\r\n  \t\tstd::sort(first, last, comp);\r\n  \telse\r\n  \t\tdetail::float_Sort(first, last, shift(*first, 0), *first, shift, comp);\r\n  }\r\n\r\n  //------------------------------------------------- string_sort source ---------------------------------------------\r\n  namespace detail {\r\n  \t//Offsetting on identical characters.  This function works a character at a time for optimal worst-case performance.\r\n  \ttemplate<class RandomAccessIter>\r\n  \tinline void\r\n  \tupdate_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset)\r\n  \t{\r\n  \t\tunsigned nextOffset = char_offset;\r\n  \t\tbool done = false;\r\n  \t\twhile(!done) {\r\n  \t\t\tRandomAccessIter curr = first;\r\n  \t\t\tdo {\r\n  \t\t\t\t//ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character\r\n  \t\t\t\tif((*curr).size() > char_offset && ((*curr).size() <= (nextOffset + 1) || (*curr)[nextOffset] != (*first)[nextOffset])) {\r\n  \t\t\t\t\tdone = true;\r\n  \t\t\t\t\tbreak;\r\n  \t\t\t\t}\r\n  \t\t\t} while(++curr != finish);\r\n  \t\t\tif(!done)\r\n  \t\t\t\t++nextOffset;\r\n  \t\t} \r\n  \t\tchar_offset = nextOffset;\r\n  \t}\r\n\r\n  \t//Offsetting on identical characters.  This function works a character at a time for optimal worst-case performance.\r\n  \ttemplate<class RandomAccessIter, class get_char, class get_length>\r\n  \tinline void\r\n  \tupdate_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset, get_char getchar, get_length length)\r\n  \t{\r\n  \t\tunsigned nextOffset = char_offset;\r\n  \t\tbool done = false;\r\n  \t\twhile(!done) {\r\n  \t\t\tRandomAccessIter curr = first;\r\n  \t\t\tdo {\r\n  \t\t\t\t//ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character\r\n  \t\t\t\tif(length(*curr) > char_offset && (length(*curr) <= (nextOffset + 1) || getchar((*curr), nextOffset) != getchar((*first), nextOffset))) {\r\n  \t\t\t\t\tdone = true;\r\n  \t\t\t\t\tbreak;\r\n  \t\t\t\t}\r\n  \t\t\t} while(++curr != finish);\r\n  \t\t\tif(!done)\r\n  \t\t\t\t++nextOffset;\r\n  \t\t} \r\n  \t\tchar_offset = nextOffset;\r\n  \t}\r\n\r\n  \t//A comparison functor for strings that assumes they are identical up to char_offset\r\n  \ttemplate<class data_type, class unsignedchar_type>\r\n  \tstruct offset_lessthan {\r\n  \t\toffset_lessthan(unsigned char_offset) : fchar_offset(char_offset){}\r\n  \t\tinline bool operator()(const data_type &x, const data_type &y) const \r\n  \t\t{\r\n  \t\t\tunsigned minSize = std::min(x.size(), y.size());\r\n  \t\t\tfor(unsigned u = fchar_offset; u < minSize; ++u) {\r\n  \t\t\t\tif(static_cast<unsignedchar_type>(x[u]) < static_cast<unsignedchar_type>(y[u]))\r\n  \t\t\t\t\treturn true;\r\n  \t\t\t\telse if(static_cast<unsignedchar_type>(y[u]) < static_cast<unsignedchar_type>(x[u]))\r\n  \t\t\t\t\treturn false;\r\n  \t\t\t}\r\n  \t\t\treturn x.size() < y.size();\r\n  \t\t}\r\n  \t\tunsigned fchar_offset;\r\n  \t};\r\n\r\n  \t//A comparison functor for strings that assumes they are identical up to char_offset\r\n  \ttemplate<class data_type, class unsignedchar_type>\r\n  \tstruct offset_greaterthan {\r\n  \t\toffset_greaterthan(unsigned char_offset) : fchar_offset(char_offset){}\r\n  \t\tinline bool operator()(const data_type &x, const data_type &y) const \r\n  \t\t{\r\n  \t\t\tunsigned minSize = std::min(x.size(), y.size());\r\n  \t\t\tfor(unsigned u = fchar_offset; u < minSize; ++u) {\r\n  \t\t\t\tif(static_cast<unsignedchar_type>(x[u]) > static_cast<unsignedchar_type>(y[u]))\r\n  \t\t\t\t\treturn true;\r\n  \t\t\t\telse if(static_cast<unsignedchar_type>(y[u]) > static_cast<unsignedchar_type>(x[u]))\r\n  \t\t\t\t\treturn false;\r\n  \t\t\t}\r\n  \t\t\treturn x.size() > y.size();\r\n  \t\t}\r\n  \t\tunsigned fchar_offset;\r\n  \t};\r\n\r\n  \t//A comparison functor for strings that assumes they are identical up to char_offset\r\n  \ttemplate<class data_type, class get_char, class get_length>\r\n  \tstruct offset_char_lessthan {\r\n  \t\toffset_char_lessthan(unsigned char_offset) : fchar_offset(char_offset){}\r\n  \t\tinline bool operator()(const data_type &x, const data_type &y) const \r\n  \t\t{\r\n  \t\t\tunsigned minSize = std::min(length(x), length(y));\r\n  \t\t\tfor(unsigned u = fchar_offset; u < minSize; ++u) {\r\n  \t\t\t\tif(getchar(x, u) < getchar(y, u))\r\n  \t\t\t\t\treturn true;\r\n  \t\t\t\telse if(getchar(y, u) < getchar(x, u))\r\n  \t\t\t\t\treturn false;\r\n  \t\t\t}\r\n  \t\t\treturn length(x) < length(y);\r\n  \t\t}\r\n  \t\tunsigned fchar_offset;\r\n  \t\tget_char getchar;\r\n  \t\tget_length length;\r\n  \t};\r\n\r\n  \t//String sorting recursive implementation\r\n  \ttemplate <class RandomAccessIter, class data_type, class unsignedchar_type>\r\n  \tinline void \r\n  \tstring_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache\r\n  \t\t, unsigned cache_offset, std::vector<size_t> &bin_sizes)\r\n  \t{\r\n  \t\t//This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.\r\n  \t\t//Iterate to the end of the empties.  If all empty, return\r\n  \t\twhile((*first).size() <= char_offset) {\r\n  \t\t\tif(++first == last)\r\n  \t\t\t\treturn;\r\n  \t\t}\r\n  \t\tRandomAccessIter finish = last - 1;\r\n  \t\t//Getting the last non-empty\r\n  \t\tfor(;(*finish).size() <= char_offset; --finish) { }\r\n  \t\t++finish;\r\n  \t\t//Offsetting on identical characters.  This section works a character at a time for optimal worst-case performance.\r\n  \t\tupdate_offset(first, finish, char_offset);\r\n  \t\t\r\n  \t\tconst unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));\r\n  \t\t//Equal worst-case between radix and comparison-based is when bin_count = n*log(n).\r\n  \t\tconst unsigned max_size = bin_count;\r\n  \t\tconst unsigned membin_count = bin_count + 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin; this takes roughly 10% of runtime\r\n  \t\tfor (RandomAccessIter current = first; current != last; ++current) {\r\n  \t\t\tif((*current).size() <= char_offset) {\r\n  \t\t\t\tbin_sizes[0]++;\r\n  \t\t\t}\r\n  \t\t\telse\r\n  \t\t\t\tbin_sizes[static_cast<unsignedchar_type>((*current)[char_offset]) + 1]++;\r\n  \t\t}\r\n  \t\t//Assign the bin positions\r\n  \t\tbin_cache[cache_offset] = first;\r\n  \t\tfor(unsigned u = 0; u < membin_count - 1; u++)\r\n  \t\t\tbin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = first;\r\n  \t\t//handling empty bins\r\n  \t\tRandomAccessIter * local_bin = &(bin_cache[cache_offset]);\r\n  \t\tnextbinstart +=\tbin_sizes[0];\r\n  \t\tRandomAccessIter * target_bin;\r\n  \t\t//Iterating over each element in the bin of empties\r\n  \t\tfor(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {\r\n  \t\t\t//empties belong in this bin\r\n  \t\t\twhile((*current).size() > char_offset) {\r\n  \t\t\t\ttarget_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]);\r\n  \t\t\t\titer_swap(current, (*target_bin)++);\r\n  \t\t\t}\r\n  \t\t}\r\n  \t\t*local_bin = nextbinstart;\r\n  \t\t//iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops\r\n  \t\tunsigned last_bin = bin_count - 1;\r\n  \t\tfor(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }\r\n  \t\t//This dominates runtime, mostly in the swap and bin lookups\r\n  \t\tfor(unsigned u = 0; u < last_bin; ++u) {\r\n  \t\t\tlocal_bin = bins + u;\r\n  \t\t\tnextbinstart += bin_sizes[u + 1];\r\n  \t\t\t//Iterating over each element in this bin\r\n  \t\t\tfor(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {\r\n  \t\t\t\t//Swapping elements in current into place until the correct element has been swapped in\r\n  \t\t\t\tfor(target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]);  target_bin != local_bin; \r\n  \t\t\t\t\ttarget_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]))\r\n  \t\t\t\t\titer_swap(current, (*target_bin)++);\r\n  \t\t\t}\r\n  \t\t\t*local_bin = nextbinstart;\r\n  \t\t}\r\n  \t\tbins[last_bin] = last;\r\n  \t\t//Recursing\r\n  \t\tRandomAccessIter lastPos = bin_cache[cache_offset];\r\n  \t\t//Skip this loop for empties\r\n  \t\tfor(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {\r\n  \t\t\tsize_t count = bin_cache[u] - lastPos;\r\n  \t\t\t//don't sort unless there are at least two items to compare\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\t//using std::sort if its worst-case is better\r\n  \t\t\tif(count < max_size)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[u], offset_lessthan<data_type, unsignedchar_type>(char_offset + 1));\r\n  \t\t\telse\r\n  \t\t\t\tstring_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes);\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Sorts strings in reverse order, with empties at the end\r\n  \ttemplate <class RandomAccessIter, class data_type, class unsignedchar_type>\r\n  \tinline void \r\n  \treverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache\r\n  \t\t, unsigned cache_offset, std::vector<size_t> &bin_sizes)\r\n  \t{\r\n  \t\t//This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.\r\n  \t\tRandomAccessIter curr = first;\r\n  \t\t//Iterate to the end of the empties.  If all empty, return\r\n  \t\twhile((*curr).size() <= char_offset) {\r\n  \t\t\tif(++curr == last)\r\n  \t\t\t\treturn;\r\n  \t\t}\r\n  \t\t//Getting the last non-empty\r\n  \t\twhile((*(--last)).size() <= char_offset) { }\r\n  \t\t++last;\r\n  \t\t//Offsetting on identical characters.  This section works a character at a time for optimal worst-case performance.\r\n  \t\tupdate_offset(curr, last, char_offset);\r\n  \t\tRandomAccessIter * target_bin;\r\n  \t\t\r\n  \t\tconst unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));\r\n  \t\t//Equal worst-case between radix and comparison-based is when bin_count = n*log(n).\r\n  \t\tconst unsigned max_size = bin_count;\r\n  \t\tconst unsigned membin_count = bin_count + 1;\r\n  \t\tconst unsigned max_bin = bin_count - 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count);\r\n  \t\tRandomAccessIter * end_bin = &(bin_cache[cache_offset + max_bin]);\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin; this takes roughly 10% of runtime\r\n  \t\tfor (RandomAccessIter current = first; current != last; ++current) {\r\n  \t\t\tif((*current).size() <= char_offset) {\r\n  \t\t\t\tbin_sizes[bin_count]++;\r\n  \t\t\t}\r\n  \t\t\telse\r\n  \t\t\t\tbin_sizes[max_bin - static_cast<unsignedchar_type>((*current)[char_offset])]++;\r\n  \t\t}\r\n  \t\t//Assign the bin positions\r\n  \t\tbin_cache[cache_offset] = first;\r\n  \t\tfor(unsigned u = 0; u < membin_count - 1; u++)\r\n  \t\t\tbin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = last;\r\n  \t\t//handling empty bins\r\n  \t\tRandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]);\r\n  \t\tRandomAccessIter lastFull = *local_bin;\r\n  \t\t//Iterating over each element in the bin of empties\r\n  \t\tfor(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {\r\n  \t\t\t//empties belong in this bin\r\n  \t\t\twhile((*current).size() > char_offset) {\r\n  \t\t\t\ttarget_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]);\r\n  \t\t\t\titer_swap(current, (*target_bin)++);\r\n  \t\t\t}\r\n  \t\t}\r\n  \t\t*local_bin = nextbinstart;\r\n  \t\tnextbinstart = first;\r\n  \t\t//iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops\r\n  \t\tunsigned last_bin = max_bin;\r\n  \t\tfor(; last_bin && !bin_sizes[last_bin]; --last_bin) { }\r\n  \t\t//This dominates runtime, mostly in the swap and bin lookups\r\n  \t\tfor(unsigned u = 0; u < last_bin; ++u) {\r\n  \t\t\tlocal_bin = bins + u;\r\n  \t\t\tnextbinstart += bin_sizes[u];\r\n  \t\t\t//Iterating over each element in this bin\r\n  \t\t\tfor(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {\r\n  \t\t\t\t//Swapping elements in current into place until the correct element has been swapped in\r\n  \t\t\t\tfor(target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]);  target_bin != local_bin; \r\n  \t\t\t\t\ttarget_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]))\r\n  \t\t\t\t\titer_swap(current, (*target_bin)++);\r\n  \t\t\t}\r\n  \t\t\t*local_bin = nextbinstart;\r\n  \t\t}\r\n  \t\tbins[last_bin] = lastFull;\r\n  \t\t//Recursing\r\n  \t\tRandomAccessIter lastPos = first;\r\n  \t\t//Skip this loop for empties\r\n  \t\tfor(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) {\r\n  \t\t\tsize_t count = bin_cache[u] - lastPos;\r\n  \t\t\t//don't sort unless there are at least two items to compare\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\t//using std::sort if its worst-case is better\r\n  \t\t\tif(count < max_size)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[u], offset_greaterthan<data_type, unsignedchar_type>(char_offset + 1));\r\n  \t\t\telse\r\n  \t\t\t\treverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes);\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//String sorting recursive implementation\r\n  \ttemplate <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length>\r\n  \tinline void \r\n  \tstring_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache\r\n  \t\t, unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length)\r\n  \t{\r\n  \t\t//This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.\r\n  \t\t//Iterate to the end of the empties.  If all empty, return\r\n  \t\twhile(length(*first) <= char_offset) {\r\n  \t\t\tif(++first == last)\r\n  \t\t\t\treturn;\r\n  \t\t}\r\n  \t\tRandomAccessIter finish = last - 1;\r\n  \t\t//Getting the last non-empty\r\n  \t\tfor(;length(*finish) <= char_offset; --finish) { }\r\n  \t\t++finish;\r\n  \t\tupdate_offset(first, finish, char_offset, getchar, length);\r\n  \t\t\r\n  \t\tconst unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));\r\n  \t\t//Equal worst-case between radix and comparison-based is when bin_count = n*log(n).\r\n  \t\tconst unsigned max_size = bin_count;\r\n  \t\tconst unsigned membin_count = bin_count + 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin; this takes roughly 10% of runtime\r\n  \t\tfor (RandomAccessIter current = first; current != last; ++current) {\r\n  \t\t\tif(length(*current) <= char_offset) {\r\n  \t\t\t\tbin_sizes[0]++;\r\n  \t\t\t}\r\n  \t\t\telse\r\n  \t\t\t\tbin_sizes[getchar((*current), char_offset) + 1]++;\r\n  \t\t}\r\n  \t\t//Assign the bin positions\r\n  \t\tbin_cache[cache_offset] = first;\r\n  \t\tfor(unsigned u = 0; u < membin_count - 1; u++)\r\n  \t\t\tbin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = first;\r\n  \t\t//handling empty bins\r\n  \t\tRandomAccessIter * local_bin = &(bin_cache[cache_offset]);\r\n  \t\tnextbinstart +=\tbin_sizes[0];\r\n  \t\tRandomAccessIter * target_bin;\r\n  \t\t//Iterating over each element in the bin of empties\r\n  \t\tfor(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {\r\n  \t\t\t//empties belong in this bin\r\n  \t\t\twhile(length(*current) > char_offset) {\r\n  \t\t\t\ttarget_bin = bins + getchar((*current), char_offset);\r\n  \t\t\t\titer_swap(current, (*target_bin)++);\r\n  \t\t\t}\r\n  \t\t}\r\n  \t\t*local_bin = nextbinstart;\r\n  \t\t//iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops\r\n  \t\tunsigned last_bin = bin_count - 1;\r\n  \t\tfor(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }\r\n  \t\t//This dominates runtime, mostly in the swap and bin lookups\r\n  \t\tfor(unsigned ii = 0; ii < last_bin; ++ii) {\r\n  \t\t\tlocal_bin = bins + ii;\r\n  \t\t\tnextbinstart += bin_sizes[ii + 1];\r\n  \t\t\t//Iterating over each element in this bin\r\n  \t\t\tfor(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {\r\n  \t\t\t\t//Swapping elements in current into place until the correct element has been swapped in\r\n  \t\t\t\tfor(target_bin = bins + getchar((*current), char_offset);  target_bin != local_bin; \r\n  \t\t\t\t\ttarget_bin = bins + getchar((*current), char_offset))\r\n  \t\t\t\t\titer_swap(current, (*target_bin)++);\r\n  \t\t\t}\r\n  \t\t\t*local_bin = nextbinstart;\r\n  \t\t}\r\n  \t\tbins[last_bin] = last;\r\n  \t\t\r\n  \t\t//Recursing\r\n  \t\tRandomAccessIter lastPos = bin_cache[cache_offset];\r\n  \t\t//Skip this loop for empties\r\n  \t\tfor(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {\r\n  \t\t\tsize_t count = bin_cache[u] - lastPos;\r\n  \t\t\t//don't sort unless there are at least two items to compare\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\t//using std::sort if its worst-case is better\r\n  \t\t\tif(count < max_size)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[u], offset_char_lessthan<data_type, get_char, get_length>(char_offset + 1));\r\n  \t\t\telse\r\n  \t\t\t\tstring_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length);\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//String sorting recursive implementation\r\n  \ttemplate <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare>\r\n  \tinline void \r\n  \tstring_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache\r\n  \t\t, unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp)\r\n  \t{\r\n  \t\t//This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.\r\n  \t\t//Iterate to the end of the empties.  If all empty, return\r\n  \t\twhile(length(*first) <= char_offset) {\r\n  \t\t\tif(++first == last)\r\n  \t\t\t\treturn;\r\n  \t\t}\r\n  \t\tRandomAccessIter finish = last - 1;\r\n  \t\t//Getting the last non-empty\r\n  \t\tfor(;length(*finish) <= char_offset; --finish) { }\r\n  \t\t++finish;\r\n  \t\tupdate_offset(first, finish, char_offset, getchar, length);\r\n  \t\t\r\n  \t\tconst unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));\r\n  \t\t//Equal worst-case between radix and comparison-based is when bin_count = n*log(n).\r\n  \t\tconst unsigned max_size = bin_count;\r\n  \t\tconst unsigned membin_count = bin_count + 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin; this takes roughly 10% of runtime\r\n  \t\tfor (RandomAccessIter current = first; current != last; ++current) {\r\n  \t\t\tif(length(*current) <= char_offset) {\r\n  \t\t\t\tbin_sizes[0]++;\r\n  \t\t\t}\r\n  \t\t\telse\r\n  \t\t\t\tbin_sizes[getchar((*current), char_offset) + 1]++;\r\n  \t\t}\r\n  \t\t//Assign the bin positions\r\n  \t\tbin_cache[cache_offset] = first;\r\n  \t\tfor(unsigned u = 0; u < membin_count - 1; u++)\r\n  \t\t\tbin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = first;\r\n  \t\t//handling empty bins\r\n  \t\tRandomAccessIter * local_bin = &(bin_cache[cache_offset]);\r\n  \t\tnextbinstart +=\tbin_sizes[0];\r\n  \t\tRandomAccessIter * target_bin;\r\n  \t\t//Iterating over each element in the bin of empties\r\n  \t\tfor(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {\r\n  \t\t\t//empties belong in this bin\r\n  \t\t\twhile(length(*current) > char_offset) {\r\n  \t\t\t\ttarget_bin = bins + getchar((*current), char_offset);\r\n  \t\t\t\titer_swap(current, (*target_bin)++);\r\n  \t\t\t}\r\n  \t\t}\r\n  \t\t*local_bin = nextbinstart;\r\n  \t\t//iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops\r\n  \t\tunsigned last_bin = bin_count - 1;\r\n  \t\tfor(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }\r\n  \t\t//This dominates runtime, mostly in the swap and bin lookups\r\n  \t\tfor(unsigned u = 0; u < last_bin; ++u) {\r\n  \t\t\tlocal_bin = bins + u;\r\n  \t\t\tnextbinstart += bin_sizes[u + 1];\r\n  \t\t\t//Iterating over each element in this bin\r\n  \t\t\tfor(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {\r\n  \t\t\t\t//Swapping elements in current into place until the correct element has been swapped in\r\n  \t\t\t\tfor(target_bin = bins + getchar((*current), char_offset);  target_bin != local_bin; \r\n  \t\t\t\t\ttarget_bin = bins + getchar((*current), char_offset))\r\n  \t\t\t\t\titer_swap(current, (*target_bin)++);\r\n  \t\t\t}\r\n  \t\t\t*local_bin = nextbinstart;\r\n  \t\t}\r\n  \t\tbins[last_bin] = last;\r\n  \t\t\r\n  \t\t//Recursing\r\n  \t\tRandomAccessIter lastPos = bin_cache[cache_offset];\r\n  \t\t//Skip this loop for empties\r\n  \t\tfor(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {\r\n  \t\t\tsize_t count = bin_cache[u] - lastPos;\r\n  \t\t\t//don't sort unless there are at least two items to compare\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\t//using std::sort if its worst-case is better\r\n  \t\t\tif(count < max_size)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[u], comp);\r\n  \t\t\telse\r\n  \t\t\t\tstring_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos\r\n  \t\t\t\t\t, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp);\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Sorts strings in reverse order, with empties at the end\r\n  \ttemplate <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare>\r\n  \tinline void \r\n  \treverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache\r\n  \t\t, unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp)\r\n  \t{\r\n  \t\t//This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.\r\n  \t\tRandomAccessIter curr = first;\r\n  \t\t//Iterate to the end of the empties.  If all empty, return\r\n  \t\twhile(length(*curr) <= char_offset) {\r\n  \t\t\tif(++curr == last)\r\n  \t\t\t\treturn;\r\n  \t\t}\r\n  \t\t//Getting the last non-empty\r\n  \t\twhile(length(*(--last)) <= char_offset) { }\r\n  \t\t++last;\r\n  \t\t//Offsetting on identical characters.  This section works a character at a time for optimal worst-case performance.\r\n  \t\tupdate_offset(first, last, char_offset, getchar, length);\r\n  \t\t\r\n  \t\tconst unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));\r\n  \t\t//Equal worst-case between radix and comparison-based is when bin_count = n*log(n).\r\n  \t\tconst unsigned max_size = bin_count;\r\n  \t\tconst unsigned membin_count = bin_count + 1;\r\n  \t\tconst unsigned max_bin = bin_count - 1;\r\n  \t\tunsigned cache_end;\r\n  \t\tRandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count);\r\n  \t\tRandomAccessIter *end_bin = &(bin_cache[cache_offset + max_bin]);\r\n  \t\t\t\r\n  \t\t//Calculating the size of each bin; this takes roughly 10% of runtime\r\n  \t\tfor (RandomAccessIter current = first; current != last; ++current) {\r\n  \t\t\tif(length(*current) <= char_offset) {\r\n  \t\t\t\tbin_sizes[bin_count]++;\r\n  \t\t\t}\r\n  \t\t\telse\r\n  \t\t\t\tbin_sizes[max_bin - getchar((*current), char_offset)]++;\r\n  \t\t}\r\n  \t\t//Assign the bin positions\r\n  \t\tbin_cache[cache_offset] = first;\r\n  \t\tfor(unsigned u = 0; u < membin_count - 1; u++)\r\n  \t\t\tbin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];\r\n  \t\t\r\n  \t\t//Swap into place\r\n  \t\tRandomAccessIter nextbinstart = last;\r\n  \t\t//handling empty bins\r\n  \t\tRandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]);\r\n  \t\tRandomAccessIter lastFull = *local_bin;\r\n  \t\tRandomAccessIter * target_bin;\r\n  \t\t//Iterating over each element in the bin of empties\r\n  \t\tfor(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {\r\n  \t\t\t//empties belong in this bin\r\n  \t\t\twhile(length(*current) > char_offset) {\r\n  \t\t\t\ttarget_bin = end_bin - getchar((*current), char_offset);\r\n  \t\t\t\titer_swap(current, (*target_bin)++);\r\n  \t\t\t}\r\n  \t\t}\r\n  \t\t*local_bin = nextbinstart;\r\n  \t\tnextbinstart = first;\r\n  \t\t//iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops\r\n  \t\tunsigned last_bin = max_bin;\r\n  \t\tfor(; last_bin && !bin_sizes[last_bin]; --last_bin) { }\r\n  \t\t//This dominates runtime, mostly in the swap and bin lookups\r\n  \t\tfor(unsigned u = 0; u < last_bin; ++u) {\r\n  \t\t\tlocal_bin = bins + u;\r\n  \t\t\tnextbinstart += bin_sizes[u];\r\n  \t\t\t//Iterating over each element in this bin\r\n  \t\t\tfor(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {\r\n  \t\t\t\t//Swapping elements in current into place until the correct element has been swapped in\r\n  \t\t\t\tfor(target_bin = end_bin - getchar((*current), char_offset);  target_bin != local_bin; \r\n  \t\t\t\t\ttarget_bin = end_bin - getchar((*current), char_offset))\r\n  \t\t\t\t\titer_swap(current, (*target_bin)++);\r\n  \t\t\t}\r\n  \t\t\t*local_bin = nextbinstart;\r\n  \t\t}\r\n  \t\tbins[last_bin] = lastFull;\r\n  \t\t//Recursing\r\n  \t\tRandomAccessIter lastPos = first;\r\n  \t\t//Skip this loop for empties\r\n  \t\tfor(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) {\r\n  \t\t\tsize_t count = bin_cache[u] - lastPos;\r\n  \t\t\t//don't sort unless there are at least two items to compare\r\n  \t\t\tif(count < 2)\r\n  \t\t\t\tcontinue;\r\n  \t\t\t//using std::sort if its worst-case is better\r\n  \t\t\tif(count < max_size)\r\n  \t\t\t\tstd::sort(lastPos, bin_cache[u], comp);\r\n  \t\t\telse\r\n  \t\t\t\treverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos\r\n  \t\t\t\t\t, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp);\r\n  \t\t}\r\n  \t}\r\n\r\n  \t//Holds the bin vector and makes the initial recursive call\r\n  \ttemplate <class RandomAccessIter, class data_type, class unsignedchar_type>\r\n  \tinline void \r\n  \tstring_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type)\r\n  \t{\r\n  \t\tstd::vector<size_t> bin_sizes;\r\n  \t\tstd::vector<RandomAccessIter> bin_cache;\r\n  \t\tstring_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes);\r\n  \t}\r\n\r\n  \t//Holds the bin vector and makes the initial recursive call\r\n  \ttemplate <class RandomAccessIter, class data_type, class unsignedchar_type>\r\n  \tinline void \r\n  \treverse_string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type)\r\n  \t{\r\n  \t\tstd::vector<size_t> bin_sizes;\r\n  \t\tstd::vector<RandomAccessIter> bin_cache;\r\n  \t\treverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes);\r\n  \t}\r\n\r\n  \t//Holds the bin vector and makes the initial recursive call\r\n  \ttemplate <class RandomAccessIter, class get_char, class get_length, class data_type, class unsignedchar_type>\r\n  \tinline void \r\n  \tstring_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, data_type, unsignedchar_type)\r\n  \t{\r\n  \t\tstd::vector<size_t> bin_sizes;\r\n  \t\tstd::vector<RandomAccessIter> bin_cache;\r\n  \t\tstring_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length);\r\n  \t}\r\n\r\n  \t//Holds the bin vector and makes the initial recursive call\r\n  \ttemplate <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type>\r\n  \tinline void \r\n  \tstring_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type)\r\n  \t{\r\n  \t\tstd::vector<size_t> bin_sizes;\r\n  \t\tstd::vector<RandomAccessIter> bin_cache;\r\n  \t\tstring_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp);\r\n  \t}\r\n\r\n  \t//Holds the bin vector and makes the initial recursive call\r\n  \ttemplate <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type>\r\n  \tinline void \r\n  \treverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type)\r\n  \t{\r\n  \t\tstd::vector<size_t> bin_sizes;\r\n  \t\tstd::vector<RandomAccessIter> bin_cache;\r\n  \t\treverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp);\r\n  \t}\r\n  }\r\n\r\n  //Allows character-type overloads\r\n  template <class RandomAccessIter, class unsignedchar_type>\r\n  inline void string_sort(RandomAccessIter first, RandomAccessIter last, unsignedchar_type unused) \r\n  {\r\n  \t//Don't sort if it's too small to optimize\r\n  \tif(last - first < detail::MIN_SORT_SIZE)\r\n  \t\tstd::sort(first, last);\r\n  \telse\r\n  \t\tdetail::string_sort(first, last, *first, unused);\r\n  }\r\n\r\n  //Top-level sorting call; wraps using default of unsigned char\r\n  template <class RandomAccessIter>\r\n  inline void string_sort(RandomAccessIter first, RandomAccessIter last) \r\n  {\r\n  \tunsigned char unused = '\\0';\r\n  \tstring_sort(first, last, unused);\r\n  }\r\n\r\n  //Allows character-type overloads\r\n  template <class RandomAccessIter, class compare, class unsignedchar_type>\r\n  inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp, unsignedchar_type unused) \r\n  {\r\n  \t//Don't sort if it's too small to optimize\r\n  \tif(last - first < detail::MIN_SORT_SIZE)\r\n  \t\tstd::sort(first, last, comp);\r\n  \telse\r\n  \t\tdetail::reverse_string_sort(first, last, *first, unused);\r\n  }\r\n\r\n  //Top-level sorting call; wraps using default of unsigned char\r\n  template <class RandomAccessIter, class compare>\r\n  inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp) \r\n  {\r\n  \tunsigned char unused = '\\0';\r\n  \treverse_string_sort(first, last, comp, unused);\r\n  }\r\n\r\n  template <class RandomAccessIter, class get_char, class get_length>\r\n  inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length) \r\n  {\r\n  \t//Don't sort if it's too small to optimize\r\n  \tif(last - first < detail::MIN_SORT_SIZE)\r\n  \t\tstd::sort(first, last);\r\n  \telse {\r\n  \t\t//skipping past empties at the beginning, which allows us to get the character type \r\n  \t\t//.empty() is not used so as not to require a user declaration of it\r\n  \t\twhile(!length(*first)) {\r\n  \t\t\tif(++first == last)\r\n  \t\t\t\treturn;\r\n  \t\t}\r\n  \t\tdetail::string_sort(first, last, getchar, length, *first, getchar((*first), 0));\r\n  \t}\r\n  }\r\n\r\n  template <class RandomAccessIter, class get_char, class get_length, class compare>\r\n  inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp) \r\n  {\r\n  \t//Don't sort if it's too small to optimize\r\n  \tif(last - first < detail::MIN_SORT_SIZE)\r\n  \t\tstd::sort(first, last, comp);\r\n  \telse {\r\n  \t\t//skipping past empties at the beginning, which allows us to get the character type \r\n  \t\t//.empty() is not used so as not to require a user declaration of it\r\n  \t\twhile(!length(*first)) {\r\n  \t\t\tif(++first == last)\r\n  \t\t\t\treturn;\r\n  \t\t}\r\n  \t\tdetail::string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0));\r\n  \t}\r\n  }\r\n\r\n  template <class RandomAccessIter, class get_char, class get_length, class compare>\r\n  inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp) \r\n  {\r\n  \t//Don't sort if it's too small to optimize\r\n  \tif(last - first < detail::MIN_SORT_SIZE)\r\n  \t\tstd::sort(first, last, comp);\r\n  \telse {\r\n  \t\t//skipping past empties at the beginning, which allows us to get the character type \r\n  \t\t//.empty() is not used so as not to require a user declaration of it\r\n  \t\twhile(!length(*(--last))) {\r\n  \t\t\t//Note: if there is just one non-empty, and it's at the beginning, then it's already in sorted order\r\n  \t\t\tif(first == last)\r\n  \t\t\t\treturn;\r\n  \t\t}\r\n  \t\t//making last just after the end of the non-empty part of the array\r\n  \t\t++last;\r\n  \t\tdetail::reverse_string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0));\r\n  \t}\r\n  }\r\n}\r\n\r\n#endif\r\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/thread.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"thread_wrapper.h\"\n\n#if defined(_WIN32)\n    #include \"thread_windows.h\"\n#else\n    #include \"thread_posix.h\"\n#endif\n\nnamespace webrtc {\nThreadWrapper* ThreadWrapper::CreateThread(ThreadRunFunction func,\n                                           ThreadObj obj, ThreadPriority prio,\n                                           const char* threadName)\n{\n#if defined(_WIN32)\n    return new ThreadWindows(func, obj, prio, threadName);\n#else\n    return ThreadPosix::Create(func, obj, prio, threadName);\n#endif\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/thread_posix.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"thread_posix.h\"\n\n#include <errno.h>\n#include <string.h> // strncpy\n#include <time.h>   // nanosleep\n#include <unistd.h>\n#ifdef WEBRTC_LINUX\n#include <sys/types.h>\n#include <sched.h>\n#include <sys/syscall.h>\n#include <linux/unistd.h>\n#include <sys/prctl.h>\n#endif\n\n#include \"event_wrapper.h\"\n#include \"trace.h\"\n\nnamespace webrtc {\nextern \"C\"\n{\n    static void* StartThread(void* lpParameter)\n    {\n        static_cast<ThreadPosix*>(lpParameter)->Run();\n        return 0;\n    }\n}\n\n#if (defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID))\nstatic pid_t gettid()\n{\n#if defined(__NR_gettid)\n    return  syscall(__NR_gettid);\n#else\n    return -1;\n#endif\n}\n#endif\n\nThreadWrapper* ThreadPosix::Create(ThreadRunFunction func, ThreadObj obj,\n                                   ThreadPriority prio, const char* threadName)\n{\n    ThreadPosix* ptr = new ThreadPosix(func, obj, prio, threadName);\n    if (!ptr)\n    {\n        return NULL;\n    }\n    const int error = ptr->Construct();\n    if (error)\n    {\n        delete ptr;\n        return NULL;\n    }\n    return ptr;\n}\n\nThreadPosix::ThreadPosix(ThreadRunFunction func, ThreadObj obj,\n                         ThreadPriority prio, const char* threadName)\n    : _runFunction(func),\n      _obj(obj),\n      _alive(false),\n      _dead(true),\n      _prio(prio),\n      _event(EventWrapper::Create()),\n      _setThreadName(false)\n{\n#ifdef WEBRTC_LINUX\n    _linuxPid = -1;\n#endif\n    if (threadName != NULL)\n    {\n        _setThreadName = true;\n        strncpy(_name, threadName, kThreadMaxNameLength);\n    }\n}\n\nint ThreadPosix::Construct()\n{\n    int result = 0;\n#if !defined(WEBRTC_ANDROID)\n    // Enable immediate cancellation if requested, see Shutdown()\n    result = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);\n    if (result != 0)\n    {\n        return -1;\n    }\n    result = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);\n    if (result != 0)\n    {\n        return -1;\n    }\n#endif\n    result = pthread_attr_init(&_attr);\n    if (result != 0)\n    {\n        return -1;\n    }\n\n    return 0;\n}\n\nThreadPosix::~ThreadPosix()\n{\n    pthread_attr_destroy(&_attr);\n    delete _event;\n}\n\n#define HAS_THREAD_ID !defined(MAC_IPHONE) && !defined(MAC_IPHONE_SIM)  &&  \\\n                      !defined(WEBRTC_MAC) && !defined(WEBRTC_MAC_INTEL) && \\\n                      !defined(MAC_DYLIB)  && !defined(MAC_INTEL_DYLIB)\n#if HAS_THREAD_ID\nbool ThreadPosix::Start(unsigned int& threadID)\n#else\nbool ThreadPosix::Start(unsigned int& /*threadID*/)\n#endif\n{\n    if (!_runFunction)\n    {\n        return false;\n    }\n    int result = pthread_attr_setdetachstate(&_attr, PTHREAD_CREATE_DETACHED);\n    // Set the stack stack size to 1M.\n    result |= pthread_attr_setstacksize(&_attr, 1024*1024);\n#ifdef WEBRTC_THREAD_RR\n    const int policy = SCHED_RR;\n#else\n    const int policy = SCHED_FIFO;\n#endif\n    _event->Reset();\n    result |= pthread_create(&_thread, &_attr, &StartThread, this);\n    if (result != 0)\n    {\n        return false;\n    }\n\n    // Wait up to 10 seconds for the OS to call the callback function. Prevents\n    // race condition if Stop() is called too quickly after start.\n    if (kEventSignaled != _event->Wait(WEBRTC_EVENT_10_SEC))\n    {\n        // Timed out. Something went wrong.\n        _runFunction = NULL;\n        return false;\n    }\n\n#if HAS_THREAD_ID\n    threadID = static_cast<unsigned int>(_thread);\n#endif\n    sched_param param;\n\n    const int minPrio = sched_get_priority_min(policy);\n    const int maxPrio = sched_get_priority_max(policy);\n    if ((minPrio == EINVAL) || (maxPrio == EINVAL))\n    {\n        return false;\n    }\n\n    switch (_prio)\n    {\n    case kLowPriority:\n        param.sched_priority = minPrio + 1;\n        break;\n    case kNormalPriority:\n        param.sched_priority = (minPrio + maxPrio) / 2;\n        break;\n    case kHighPriority:\n        param.sched_priority = maxPrio - 3;\n        break;\n    case kHighestPriority:\n        param.sched_priority = maxPrio - 2;\n        break;\n    case kRealtimePriority:\n        param.sched_priority = maxPrio - 1;\n        break;\n    default:\n        return false;\n    }\n    result = pthread_setschedparam(_thread, policy, &param);\n    if (result == EINVAL)\n    {\n        return false;\n    }\n    return true;\n}\n\n#if (defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID))\nbool ThreadPosix::SetAffinity(const int* processorNumbers,\n                              const unsigned int amountOfProcessors)\n{\n    if (!processorNumbers || (amountOfProcessors == 0))\n    {\n        return false;\n    }\n\n    cpu_set_t mask;\n    CPU_ZERO(&mask);\n\n    for(unsigned int processor = 0;\n        processor < amountOfProcessors;\n        processor++)\n    {\n        CPU_SET(processorNumbers[processor], &mask);\n    }\n    const int result = sched_setaffinity(_linuxPid, (unsigned int)sizeof(mask),\n                                         &mask);\n    if (result != 0)\n    {\n        return false;\n\n    }\n    return true;\n}\n#else\n// NOTE: On Mac OS X, use the Thread affinity API in\n// /usr/include/mach/thread_policy.h: thread_policy_set and mach_thread_self()\n// instead of Linux gettid() syscall.\nbool ThreadPosix::SetAffinity(const int* , const unsigned int)\n{\n    return false;\n}\n#endif\n\nvoid ThreadPosix::SetNotAlive()\n{\n    _alive = false;\n}\n\nbool ThreadPosix::Shutdown()\n{\n#if !defined(WEBRTC_ANDROID)\n    if (_thread && (0 != pthread_cancel(_thread)))\n    {\n        return false;\n    }\n\n    return true;\n#else\n    return false;\n#endif\n}\n\nbool ThreadPosix::Stop()\n{\n    _alive = false;\n\n    // TODO (hellner) why not use an event here?\n    // Wait up to 10 seconds for the thread to terminate\n    for (int i = 0; i < 1000 && !_dead; i++)\n    {\n        timespec t;\n        t.tv_sec = 0;\n        t.tv_nsec = 10*1000*1000;\n        nanosleep(&t, NULL);\n    }\n    if (_dead)\n    {\n        return true;\n    }\n    else\n    {\n        return false;\n    }\n}\n\nvoid ThreadPosix::Run()\n{\n    _alive = true;\n    _dead  = false;\n#ifdef WEBRTC_LINUX\n    if(_linuxPid == -1)\n    {\n        _linuxPid = gettid();\n    }\n#endif\n    // The event the Start() is waiting for.\n    _event->Set();\n\n    if (_setThreadName)\n    {\n#ifdef WEBRTC_LINUX\n        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,-1,\n                     \"Thread with id:%d name:%s started \", _linuxPid, _name);\n        prctl(PR_SET_NAME, (unsigned long)_name, 0, 0, 0);\n#else\n        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,-1,\n                     \"Thread with name:%s started \", _name);\n#endif\n    }else\n    {\n#ifdef WEBRTC_LINUX\n        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,\n                     \"Thread with id:%d without name started\", _linuxPid);\n#else\n        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,\n                     \"Thread without name started\");\n#endif\n    }\n    do\n    {\n        if (_runFunction)\n        {\n            if (!_runFunction(_obj))\n            {\n                _alive = false;\n            }\n        }\n        else\n        {\n            _alive = false;\n        }\n    }\n    while (_alive);\n\n    if (_setThreadName)\n    {\n        // Don't set the name for the trace thread because it may cause a\n        // deadlock. TODO (hellner) there should be a better solution than\n        // coupling the thread and the trace class like this.\n        if (strcmp(_name, \"Trace\"))\n        {\n            WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,-1,\n                         \"Thread with name:%s stopped\", _name);\n        }\n    }\n    else\n    {\n        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,-1,\n                     \"Thread without name stopped\");\n    }\n    _dead = true;\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/thread_posix.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_POSIX_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_POSIX_H_\n\n#include \"thread_wrapper.h\"\n#include <pthread.h>\n\nnamespace webrtc {\nclass EventWrapper;\n\nclass ThreadPosix : public ThreadWrapper\n{\npublic:\n    static ThreadWrapper* Create(ThreadRunFunction func, ThreadObj obj,\n                                 ThreadPriority prio, const char* threadName);\n\n    ThreadPosix(ThreadRunFunction func, ThreadObj obj, ThreadPriority prio,\n                const char* threadName);\n    ~ThreadPosix();\n\n    // From ThreadWrapper\n    virtual void SetNotAlive();\n    virtual bool Start(unsigned int& id);\n    // Not implemented on Mac\n    virtual bool SetAffinity(const int* processorNumbers,\n                             unsigned int amountOfProcessors);\n    virtual bool Stop();\n    virtual bool Shutdown();\n\n    void Run();\n\nprivate:\n    int Construct();\n\nprivate:\n    // processing function\n    ThreadRunFunction   _runFunction;\n    ThreadObj           _obj;\n\n    // internal state\n    bool                    _alive;\n    bool                    _dead;\n    ThreadPriority          _prio;\n    EventWrapper*           _event;\n\n    // zero-terminated thread name string\n    char                    _name[kThreadMaxNameLength];\n    bool                    _setThreadName;\n\n    // handle to thread\n    pthread_attr_t          _attr;\n    pthread_t               _thread;\n#ifdef WEBRTC_LINUX\n    pid_t                   _linuxPid;\n#endif\n\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_POSIX_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/thread_windows.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"thread_windows.h\"\n\n#include <assert.h>\n#include <process.h>\n#include <stdio.h>\n#include <windows.h>\n\n#include \"thread_windows_set_name.h\"\n#include \"trace.h\"\n\n#if defined(_WIN32)\n// VS 2005: Disable warnings for default initialized arrays.\n#pragma warning(disable:4351)\n#endif\n\nnamespace webrtc {\nThreadWindows::ThreadWindows(ThreadRunFunction func, ThreadObj obj,\n                             ThreadPriority prio, const char* threadName)\n    : ThreadWrapper(),\n      _runFunction(func),\n      _obj(obj),\n      _alive(false),\n      _dead(true),\n      _doNotCloseHandle(false),\n      _prio(prio),\n      _event(NULL),\n      _thread(NULL),\n      _id(0),\n      _name(),\n      _setThreadName(false)\n{\n    _event = EventWrapper::Create();\n    _critsectStop = CriticalSectionWrapper::CreateCriticalSection();\n    if (threadName != NULL)\n    {\n        // Set the thread name to appear in the VS debugger.\n        _setThreadName = true;\n        strncpy(_name, threadName, kThreadMaxNameLength);\n    }\n}\n\nThreadWindows::~ThreadWindows()\n{\n#ifdef _DEBUG\n    assert(!_alive);\n#endif\n    if (_thread)\n    {\n        CloseHandle(_thread);\n    }\n    if(_event)\n    {\n        delete _event;\n    }\n    if(_critsectStop)\n    {\n        delete _critsectStop;\n    }\n}\n\nunsigned int WINAPI ThreadWindows::StartThread(LPVOID lpParameter)\n{\n    static_cast<ThreadWindows*>(lpParameter)->Run();\n    return 0;\n}\n\nbool ThreadWindows::Start(unsigned int& threadID)\n{\n    _doNotCloseHandle = false;\n\n    // Set stack size to 1M\n    _thread=(HANDLE)_beginthreadex(NULL, 1024*1024, StartThread, (void*)this, 0,\n                                   &threadID);\n    if(_thread == NULL)\n    {\n        return false;\n    }\n    _id = threadID;\n    _event->Wait(INFINITE);\n\n    switch(_prio)\n    {\n    case kLowPriority:\n        SetThreadPriority(_thread, THREAD_PRIORITY_BELOW_NORMAL);\n        break;\n    case kNormalPriority:\n        SetThreadPriority(_thread, THREAD_PRIORITY_NORMAL);\n        break;\n    case kHighPriority:\n        SetThreadPriority(_thread, THREAD_PRIORITY_ABOVE_NORMAL);\n        break;\n    case kHighestPriority:\n        SetThreadPriority(_thread, THREAD_PRIORITY_HIGHEST);\n        break;\n    case kRealtimePriority:\n        SetThreadPriority(_thread, THREAD_PRIORITY_TIME_CRITICAL);\n        break;\n    };\n    return true;\n}\n\nbool ThreadWindows::SetAffinity(const int* processorNumbers,\n                                const unsigned int amountOfProcessors)\n{\n    DWORD_PTR processorBitMask = 0;\n    for(unsigned int processorIndex = 0;\n        processorIndex < amountOfProcessors;\n        processorIndex++)\n    {\n        // Convert from an array with processor numbers to a bitmask\n        // Processor numbers start at zero.\n        // TODO (hellner): this looks like a bug. Shouldn't the '=' be a '+='?\n        // Or even better |=\n        processorBitMask = 1 << processorNumbers[processorIndex];\n    }\n    return SetThreadAffinityMask(_thread,processorBitMask) != 0;\n}\n\nvoid ThreadWindows::SetNotAlive()\n{\n    _alive = false;\n}\n\nbool ThreadWindows::Shutdown()\n{\n    DWORD exitCode = 0;\n    BOOL ret = TRUE;\n    if (_thread)\n    {\n        ret = TerminateThread(_thread, exitCode);\n        _alive = false;\n        _dead = true;\n        _thread = NULL;\n    }\n    return ret == TRUE;\n}\n\nbool ThreadWindows::Stop()\n{\n    _critsectStop->Enter();\n    // Prevents the handle from being closed in ThreadWindows::Run()\n    _doNotCloseHandle = true;\n    _alive = false;\n    bool signaled = false;\n    if (_thread && !_dead)\n    {\n        _critsectStop->Leave();\n        // Wait up to 2 seconds for the thread to complete.\n        if( WAIT_OBJECT_0 == WaitForSingleObject(_thread, 2000))\n        {\n            signaled = true;\n        }\n        _critsectStop->Enter();\n    }\n    if (_thread)\n    {\n        CloseHandle(_thread);\n        _thread = NULL;\n    }\n    _critsectStop->Leave();\n\n    if (_dead || signaled)\n    {\n        return true;\n    }\n    else\n    {\n        return false;\n    }\n}\n\nvoid ThreadWindows::Run()\n{\n    _alive = true;\n    _dead = false;\n    _event->Set();\n\n    // All tracing must be after _event->Set to avoid deadlock in Trace.\n    if (_setThreadName)\n    {\n        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, _id,\n                     \"Thread with name:%s started \", _name);\n        SetThreadName(-1, _name); // -1, set thread name for the calling thread.\n    }else\n    {\n        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, _id,\n                     \"Thread without name started\");\n    }\n\n    do\n    {\n        if (_runFunction)\n        {\n            if (!_runFunction(_obj))\n            {\n                _alive = false;\n            }\n        } else {\n            _alive = false;\n        }\n    } while(_alive);\n\n    if (_setThreadName)\n    {\n        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, _id,\n                     \"Thread with name:%s stopped\", _name);\n    } else {\n        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,_id,\n                     \"Thread without name stopped\");\n    }\n\n    _critsectStop->Enter();\n\n    if (_thread && !_doNotCloseHandle)\n    {\n        HANDLE thread = _thread;\n        _thread = NULL;\n        CloseHandle(thread);\n    }\n    _dead = true;\n\n    _critsectStop->Leave();\n};\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/thread_windows.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_H_\n\n#include \"thread_wrapper.h\"\n#include \"event_wrapper.h\"\n#include \"critical_section_wrapper.h\"\n\n#include <windows.h>\n\nnamespace webrtc {\n\nclass ThreadWindows : public ThreadWrapper\n{\npublic:\n    ThreadWindows(ThreadRunFunction func, ThreadObj obj, ThreadPriority prio,\n                  const char* threadName);\n    virtual ~ThreadWindows();\n\n    virtual bool Start(unsigned int& id);\n    bool SetAffinity(const int* processorNumbers,\n                     const unsigned int amountOfProcessors);\n    virtual bool Stop();\n    virtual void SetNotAlive();\n\n    static unsigned int WINAPI StartThread(LPVOID lpParameter);\n\n    virtual bool Shutdown();\n\nprotected:\n    virtual void Run();\n\nprivate:\n    ThreadRunFunction    _runFunction;\n    ThreadObj            _obj;\n\n    bool                    _alive;\n    bool                    _dead;\n\n    // TODO (hellner)\n    // _doNotCloseHandle member seem pretty redundant. Should be able to remove\n    // it. Basically it should be fine to reclaim the handle when calling stop\n    // and in the destructor.\n    bool                    _doNotCloseHandle;\n    ThreadPriority          _prio;\n    EventWrapper*           _event;\n    CriticalSectionWrapper* _critsectStop;\n\n    HANDLE                  _thread;\n    unsigned int            _id;\n    char                    _name[kThreadMaxNameLength];\n    bool                    _setThreadName;\n\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/thread_windows_set_name.h",
    "content": "/*\n *  Use of this source code is governed by the MICROSOFT LIMITED PUBLIC LICENSE\n *  copyright license which can be found in the LICENSE file in the\n *  third_party_mods/mslpl directory of the source tree or at\n *  http://msdn.microsoft.com/en-us/cc300389.aspx#P.\n */\n/*\n *  The original code can be found here:\n *  http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.71).aspx\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_SET_NAME_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_SET_NAME_H_\n\nnamespace webrtc {\n\nstruct THREADNAME_INFO\n{\n   DWORD dwType;     // must be 0x1000\n   LPCSTR szName;    // pointer to name (in user addr space)\n   DWORD dwThreadID; // thread ID (-1 = caller thread)\n   DWORD dwFlags;    // reserved for future use, must be zero\n};\n\nvoid SetThreadName(DWORD dwThreadID, LPCSTR szThreadName)\n{\n    THREADNAME_INFO info;\n    info.dwType = 0x1000;\n    info.szName = szThreadName;\n    info.dwThreadID = dwThreadID;\n    info.dwFlags = 0;\n\n    __try\n    {\n        RaiseException(0x406D1388, 0, sizeof(info) / sizeof(DWORD),\n                       (ULONG_PTR*)&info);\n    }\n    __except (EXCEPTION_CONTINUE_EXECUTION)\n    {\n    }\n}\n} // namespace webrtc\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_SET_NAME_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/trace_impl.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"trace_impl.h\"\n\n#include <cassert>\n#include <string.h> // memset\n\n#ifdef _WIN32\n#include \"trace_windows.h\"\n#include \"fix_interlocked_exchange_pointer_windows.h\"\n#else\n#include <stdio.h>\n#include <time.h>\n#include <stdarg.h>\n#include \"trace_posix.h\"\n#endif // _WIN32\n\n#define KEY_LEN_CHARS 31\n\n#ifdef _WIN32\n    #pragma warning(disable:4355)\n// VS 2005: Disable warnings for default initialized arrays.\n    #pragma warning(disable:4351)\n#endif // _WIN32\n\nnamespace webrtc {\nstatic WebRtc_UWord32 levelFilter = kTraceDefault;\n\n// Construct On First Use idiom. Avoids \"static initialization order fiasco\".\nTrace* TraceImpl::StaticInstance(TraceCount inc, const TraceLevel level)\n{\n    // TODO (hellner): use atomic wrapper instead.\n    static volatile long theTraceCount = 0;\n    static Trace* volatile theTrace = NULL;\n\n    TraceCreate state = WEBRTC_TRACE_EXIST;\n\n    // Sanitys to avoid taking lock unless absolutely necessary (for\n    // performance reasons). inc == WEBRTC_TRACE_INC_NO_CREATE) implies that\n    // a message will be written to file.\n    if(level != kTraceAll && inc == WEBRTC_TRACE_INC_NO_CREATE)\n    {\n        if(!(level & levelFilter))\n        {\n            return NULL;\n        }\n    }\n\n#ifndef _WIN32\n    // TODO (pwestin): crtiSect is never reclaimed. Fix memory leak.\n    static CriticalSectionWrapper* crtiSect(\n        CriticalSectionWrapper::CreateCriticalSection());\n    CriticalSectionScoped lock(*crtiSect);\n\n    if(inc == WEBRTC_TRACE_INC_NO_CREATE && theTraceCount == 0)\n    {\n        return NULL;\n    }\n\n    if(inc == WEBRTC_TRACE_INC || inc == WEBRTC_TRACE_INC_NO_CREATE)\n    {\n        theTraceCount++;\n        if(theTraceCount == 1)\n        {\n            state = WEBRTC_TRACE_CREATE;\n        }\n    } else {\n        theTraceCount--;\n        if(theTraceCount == 0)\n        {\n            state = WEBRTC_TRACE_DESTROY;\n        }\n    }\n    if(state == WEBRTC_TRACE_CREATE)\n    {\n        theTrace = TraceImpl::CreateTrace();\n\n    } else if(state == WEBRTC_TRACE_DESTROY) {\n        Trace* oldValue = theTrace;\n        theTrace = NULL;\n        // The lock is held by the scoped critical section. Release the lock\n        // temporarily so that the trace can be safely deleted. If the lock\n        // was kept during the delete, e.g. creating and destroying the trace\n        // too quickly may lead to a deadlock.\n        // This is due to the fact that starting and stopping a ThreadWrapper\n        // thread will trigger writing of trace messages.\n        // TODO (hellner): remove the tight coupling with the thread\n        //                 implementation.\n        crtiSect->Leave();\n        if(oldValue)\n        {\n            delete static_cast<TraceImpl*>(oldValue);\n        }\n        // Re-aqcuire the lock.\n        crtiSect->Enter();\n        return NULL;\n    }\n#else  // _WIN32\n    if(inc == WEBRTC_TRACE_INC_NO_CREATE && theTraceCount == 0)\n    {\n        return NULL;\n    }\n    if(inc == WEBRTC_TRACE_INC_NO_CREATE)\n    {\n        if(1 == InterlockedIncrement(&theTraceCount))\n        {\n            // The trace has been destroyed by some other thread. Rollback.\n            InterlockedDecrement(&theTraceCount);\n            assert(false);\n            return NULL;\n        }\n        // Sanity to catch corrupt state.\n        if(theTrace == NULL)\n        {\n            assert(false);\n            InterlockedDecrement(&theTraceCount);\n            return NULL;\n        }\n    } else if(inc == WEBRTC_TRACE_INC) {\n        if(theTraceCount == 0)\n        {\n            state = WEBRTC_TRACE_CREATE;\n        } else {\n            if(1 == InterlockedIncrement(&theTraceCount))\n            {\n                // InterlockedDecrement because reference count should not be\n                // updated just yet (that's done when the trace is created).\n                InterlockedDecrement(&theTraceCount);\n                state = WEBRTC_TRACE_CREATE;\n            }\n        }\n    } else {\n        int newValue = InterlockedDecrement(&theTraceCount);\n        if(newValue == 0)\n        {\n            state = WEBRTC_TRACE_DESTROY;\n        }\n    }\n\n    if(state == WEBRTC_TRACE_CREATE)\n    {\n        // Create trace and let whichever thread finishes first assign its local\n        // copy to the global instance. All other threads reclaim their local\n        // copy.\n        Trace* newTrace = TraceImpl::CreateTrace();\n        if(1 == InterlockedIncrement(&theTraceCount))\n        {\n            Trace* oldValue = (Trace*)InterlockedExchangePointer(\n                reinterpret_cast<void* volatile*>(&theTrace), newTrace);\n            assert(oldValue == NULL);\n            assert(theTrace);\n        } else {\n            InterlockedDecrement(&theTraceCount);\n            if(newTrace)\n            {\n                delete static_cast<TraceImpl*>(newTrace);\n            }\n        }\n        return NULL;\n    } else if(state == WEBRTC_TRACE_DESTROY)\n    {\n        Trace* oldValue = (Trace*)InterlockedExchangePointer(\n            reinterpret_cast<void* volatile*>(&theTrace), NULL);\n        if(oldValue)\n        {\n            delete static_cast<TraceImpl*>(oldValue);\n        }\n        return NULL;\n    }\n#endif // #ifndef _WIN32\n    return theTrace;\n}\n\nvoid Trace::CreateTrace()\n{\n    TraceImpl::StaticInstance(WEBRTC_TRACE_INC);\n}\n\nvoid Trace::ReturnTrace()\n{\n    TraceImpl::StaticInstance(WEBRTC_TRACE_DEC);\n}\n\nTraceImpl* TraceImpl::GetTrace(const TraceLevel level)\n{\n    return (TraceImpl*)StaticInstance(WEBRTC_TRACE_INC_NO_CREATE, level);\n}\n\nTrace* TraceImpl::CreateTrace()\n{\n#if defined(_WIN32)\n    return new TraceWindows();\n#else\n    return new TracePosix();\n#endif\n}\n\nTraceImpl::TraceImpl()\n    : _critsectInterface(*CriticalSectionWrapper::CreateCriticalSection()),\n      _callback(NULL),\n      _rowCountText(0),\n      _fileCountText(0),\n      _traceFile(*FileWrapper::Create()),\n      _thread(*ThreadWrapper::CreateThread(TraceImpl::Run, this,\n                                           kHighestPriority, \"Trace\")),\n      _event(*EventWrapper::Create()),\n      _critsectArray(*CriticalSectionWrapper::CreateCriticalSection()),\n      _nextFreeIdx(),\n      _level(),\n      _length(),\n      _messageQueue(),\n      _activeQueue(0)\n{\n    _nextFreeIdx[0] = 0;\n    _nextFreeIdx[1] = 0;\n\n    unsigned int tid = 0;\n    _thread.Start(tid);\n\n    for(int m = 0; m < WEBRTC_TRACE_NUM_ARRAY; m++)\n    {\n        for(int n = 0; n < WEBRTC_TRACE_MAX_QUEUE; n++)\n        {\n            _messageQueue[m][n] = new\n                WebRtc_Word8[WEBRTC_TRACE_MAX_MESSAGE_SIZE];\n        }\n    }\n}\n\nbool TraceImpl::StopThread()\n{\n    // Release the worker thread so that it can flush any lingering messages.\n    _event.Set();\n\n    // Allow 10 ms for pending messages to be flushed out.\n    // TODO (hellner): why not use condition variables to do this? Or let the\n    //                 worker thread die and let this thread flush remaining\n    //                 messages?\n#ifdef _WIN32\n    Sleep(10);\n#else\n    timespec t;\n    t.tv_sec = 0;\n    t.tv_nsec = 10*1000000;\n    nanosleep(&t,NULL);\n#endif\n\n    _thread.SetNotAlive();\n    // Make sure the thread finishes as quickly as possible (instead of having\n    // to wait for the timeout).\n    _event.Set();\n    bool stopped = _thread.Stop();\n\n    CriticalSectionScoped lock(_critsectInterface);\n    _traceFile.Flush();\n    _traceFile.CloseFile();\n    return stopped;\n}\n\nTraceImpl::~TraceImpl()\n{\n    StopThread();\n    delete &_event;\n    delete &_traceFile;\n    delete &_thread;\n    delete &_critsectInterface;\n    delete &_critsectArray;\n\n    for(int m = 0; m < WEBRTC_TRACE_NUM_ARRAY; m++)\n    {\n        for(int n = 0; n < WEBRTC_TRACE_MAX_QUEUE; n++)\n        {\n            delete [] _messageQueue[m][n];\n        }\n    }\n}\n\nWebRtc_Word32 TraceImpl::AddLevel(char* szMessage, const TraceLevel level) const\n{\n    switch (level)\n    {\n        case kTraceStateInfo:\n            sprintf (szMessage, \"STATEINFO ; \");\n            break;\n        case kTraceWarning:\n            sprintf (szMessage, \"WARNING   ; \");\n            break;\n        case kTraceError:\n            sprintf (szMessage, \"ERROR     ; \");\n            break;\n        case kTraceCritical:\n            sprintf (szMessage, \"CRITICAL  ; \");\n            break;\n        case kTraceInfo:\n            sprintf (szMessage, \"DEBUGINFO ; \");\n            break;\n        case kTraceModuleCall:\n            sprintf (szMessage, \"MODULECALL; \");\n            break;\n        case kTraceMemory:\n            sprintf (szMessage, \"MEMORY    ; \");\n            break;\n        case kTraceTimer:\n            sprintf (szMessage, \"TIMER     ; \");\n            break;\n        case kTraceStream:\n            sprintf (szMessage, \"STREAM    ; \");\n            break;\n        case kTraceApiCall:\n            sprintf (szMessage, \"APICALL   ; \");\n            break;\n        case kTraceDebug:\n            sprintf (szMessage, \"DEBUG     ; \");\n            break;\n        default:\n            assert(false);\n            return 0;\n    }\n    // All messages are 12 characters.\n    return 12;\n}\n\nWebRtc_Word32 TraceImpl::AddModuleAndId(char* traceMessage,\n                                        const TraceModule module,\n                                        const WebRtc_Word32 id) const\n{\n    // Use long int to prevent problems with different definitions of\n    // WebRtc_Word32.\n    // TODO (hellner): is this actually a problem? If so, it should be better to\n    //                 clean up WebRtc_Word32\n    const long int idl = id;\n    if(idl != -1)\n    {\n        const unsigned long int idEngine = id>>16;\n        const unsigned long int idChannel = id & 0xffff;\n\n        switch (module)\n        {\n            case kTraceVoice:\n                sprintf(traceMessage, \"       VOICE:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceVideo:\n                sprintf(traceMessage, \"       VIDEO:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceUtility:\n                sprintf(traceMessage, \"     UTILITY:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceRtpRtcp:\n                sprintf(traceMessage, \"    RTP/RTCP:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceTransport:\n                sprintf(traceMessage, \"   TRANSPORT:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceAudioCoding:\n                sprintf(traceMessage, \"AUDIO CODING:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceSrtp:\n                sprintf(traceMessage, \"        SRTP:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceAudioMixerServer:\n                sprintf(traceMessage, \" AUDIO MIX/S:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceAudioMixerClient:\n                sprintf(traceMessage, \" AUDIO MIX/C:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceVideoCoding:\n                sprintf(traceMessage, \"VIDEO CODING:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceVideoMixer:\n                // Print sleep time and API call\n                sprintf(traceMessage, \"   VIDEO MIX:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceFile:\n                sprintf(traceMessage, \"        FILE:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceAudioProcessing:\n                sprintf(traceMessage, \"  AUDIO PROC:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceAudioDevice:\n                sprintf(traceMessage, \"AUDIO DEVICE:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceVideoRenderer:\n                sprintf(traceMessage, \"VIDEO RENDER:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceVideoCapture:\n                sprintf(traceMessage, \"VIDEO CAPTUR:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            case kTraceVideoPreocessing:\n                sprintf(traceMessage, \"  VIDEO PROC:%5ld %5ld;\", idEngine,\n                        idChannel);\n                break;\n            default:\n                assert(false);\n                return 0;\n        }\n    } else {\n        switch (module)\n        {\n            case kTraceVoice:\n                sprintf (traceMessage, \"       VOICE:%11ld;\", idl);\n                break;\n            case kTraceVideo:\n                sprintf (traceMessage, \"       VIDEO:%11ld;\", idl);\n                break;\n            case kTraceUtility:\n                sprintf (traceMessage, \"     UTILITY:%11ld;\", idl);\n                break;\n            case kTraceRtpRtcp:\n                sprintf (traceMessage, \"    RTP/RTCP:%11ld;\", idl);\n                break;\n            case kTraceTransport:\n                sprintf (traceMessage, \"   TRANSPORT:%11ld;\", idl);\n                break;\n            case kTraceAudioCoding:\n                sprintf (traceMessage, \"AUDIO CODING:%11ld;\", idl);\n                break;\n            case kTraceSrtp:\n                sprintf (traceMessage, \"        SRTP:%11ld;\", idl);\n                break;\n            case kTraceAudioMixerServer:\n                sprintf (traceMessage, \" AUDIO MIX/S:%11ld;\", idl);\n                break;\n            case kTraceAudioMixerClient:\n                sprintf (traceMessage, \" AUDIO MIX/C:%11ld;\", idl);\n                break;\n            case kTraceVideoCoding:\n                sprintf (traceMessage, \"VIDEO CODING:%11ld;\", idl);\n                break;\n            case kTraceVideoMixer:\n                sprintf (traceMessage, \"   VIDEO MIX:%11ld;\", idl);\n                break;\n            case kTraceFile:\n                sprintf (traceMessage, \"        FILE:%11ld;\", idl);\n                break;\n            case kTraceAudioProcessing:\n                sprintf (traceMessage, \"  AUDIO PROC:%11ld;\", idl);\n                break;\n            case kTraceAudioDevice:\n                sprintf (traceMessage, \"AUDIO DEVICE:%11ld;\", idl);\n                break;\n            case kTraceVideoRenderer:\n                sprintf (traceMessage, \"VIDEO RENDER:%11ld;\", idl);\n                break;\n            case kTraceVideoCapture:\n                sprintf (traceMessage, \"VIDEO CAPTUR:%11ld;\", idl);\n                break;\n            case kTraceVideoPreocessing:\n                sprintf (traceMessage, \"  VIDEO PROC:%11ld;\", idl);\n                break;\n            default:\n                assert(false);\n                return 0;\n        }\n    }\n    // All messages are 25 characters.\n    return 25;\n}\n\nWebRtc_Word32 TraceImpl::SetTraceFileImpl(const WebRtc_Word8* fileNameUTF8,\n                                          const bool addFileCounter)\n{\n    CriticalSectionScoped lock(_critsectInterface);\n\n    _traceFile.Flush();\n    _traceFile.CloseFile();\n\n    if(fileNameUTF8)\n    {\n        if(addFileCounter)\n        {\n            _fileCountText = 1;\n\n            WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize];\n            CreateFileName(fileNameUTF8, fileNameWithCounterUTF8,\n                           _fileCountText);\n            if(_traceFile.OpenFile(fileNameWithCounterUTF8, false, false,\n                                   true) == -1)\n            {\n                return -1;\n            }\n        }else {\n            _fileCountText = 0;\n            if(_traceFile.OpenFile(fileNameUTF8, false, false, true) == -1)\n            {\n                return -1;\n            }\n        }\n    }\n    _rowCountText = 0;\n    return 0;\n}\n\nWebRtc_Word32 TraceImpl::TraceFileImpl(\n    WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize])\n{\n    CriticalSectionScoped lock(_critsectInterface);\n    return _traceFile.FileName(fileNameUTF8, FileWrapper::kMaxFileNameSize);\n}\n\nWebRtc_Word32 TraceImpl::SetTraceCallbackImpl(TraceCallback* callback)\n{\n    CriticalSectionScoped lock(_critsectInterface);\n    _callback = callback;\n    return 0;\n}\n\nWebRtc_Word32 TraceImpl::AddMessage(\n    char* traceMessage,\n    const char msg[WEBRTC_TRACE_MAX_MESSAGE_SIZE],\n    const WebRtc_UWord16 writtenSoFar) const\n\n{\n    int length = 0;\n    if(writtenSoFar >= WEBRTC_TRACE_MAX_MESSAGE_SIZE)\n    {\n        return -1;\n    }\n    // - 2 to leave room for newline and NULL termination\n#ifdef _WIN32\n    length = _snprintf(traceMessage,\n                       WEBRTC_TRACE_MAX_MESSAGE_SIZE - writtenSoFar - 2,\n                       \"%s\",msg);\n    if(length < 0)\n    {\n        length = WEBRTC_TRACE_MAX_MESSAGE_SIZE - writtenSoFar - 2;\n        traceMessage[length] = 0;\n    }\n#else\n    length = snprintf(traceMessage,\n                      WEBRTC_TRACE_MAX_MESSAGE_SIZE-writtenSoFar-2, \"%s\",msg);\n    if(length < 0 || length > WEBRTC_TRACE_MAX_MESSAGE_SIZE-writtenSoFar - 2)\n    {\n        length = WEBRTC_TRACE_MAX_MESSAGE_SIZE - writtenSoFar - 2;\n        traceMessage[length] = 0;\n    }\n#endif\n    // Length with NULL termination.\n    return length+1;\n}\n\nvoid TraceImpl::AddMessageToList(\n    const char traceMessage[WEBRTC_TRACE_MAX_MESSAGE_SIZE],\n    const WebRtc_UWord16 length,\n    const TraceLevel level)\n{\n    CriticalSectionScoped lock(_critsectArray);\n\n    if(_nextFreeIdx[_activeQueue] >= WEBRTC_TRACE_MAX_QUEUE)\n    {\n        if( ! _traceFile.Open() &&\n            !_callback)\n        {\n            // Keep at least the last 1/4 of old messages when not logging.\n            // TODO (hellner): isn't this redundant. The user will make it known\n            //                 when to start logging. Why keep messages before\n            //                 that?\n            for(int n = 0; n < WEBRTC_TRACE_MAX_QUEUE/4; n++)\n            {\n                const int lastQuarterOffset = (3*WEBRTC_TRACE_MAX_QUEUE/4);\n                memcpy(_messageQueue[_activeQueue][n],\n                       _messageQueue[_activeQueue][n + lastQuarterOffset],\n                       WEBRTC_TRACE_MAX_MESSAGE_SIZE);\n            }\n            _nextFreeIdx[_activeQueue] = WEBRTC_TRACE_MAX_QUEUE/4;\n        } else {\n            // More messages are being written than there is room for in the\n            // buffer. Drop any new messages.\n            // TODO (hellner): its probably better to drop old messages instead\n            //                 of new ones. One step further: if this happens\n            //                 it's due to writing faster than what can be\n            //                 processed. Maybe modify the filter at this point.\n            //                 E.g. turn of STREAM.\n            return;\n        }\n    }\n\n    WebRtc_UWord16 idx = _nextFreeIdx[_activeQueue];\n    _nextFreeIdx[_activeQueue]++;\n\n    _level[_activeQueue][idx] = level;\n    _length[_activeQueue][idx] = length;\n    memcpy(_messageQueue[_activeQueue][idx], traceMessage, length);\n\n    if(_nextFreeIdx[_activeQueue] == WEBRTC_TRACE_MAX_QUEUE-1)\n    {\n        // Loggin more messages than can be worked off. Log a warning.\n        memcpy(_messageQueue[_activeQueue][_nextFreeIdx[_activeQueue]],\n               \"WARNING MISSING TRACE MESSAGES\\n\", 32);\n        _nextFreeIdx[_activeQueue]++;\n    }\n}\n\nbool TraceImpl::Run(void* obj)\n{\n    return static_cast<TraceImpl*>(obj)->Process();\n}\n\nbool TraceImpl::Process()\n{\n    if(_event.Wait(1000) == kEventSignaled)\n    {\n        if(_traceFile.Open() || _callback)\n        {\n            // File mode (not calback mode).\n            WriteToFile();\n        }\n    } else {\n        _traceFile.Flush();\n    }\n    return true;\n}\n\nvoid TraceImpl::WriteToFile()\n{\n    WebRtc_UWord8 localQueueActive = 0;\n    WebRtc_UWord16 localNextFreeIdx = 0;\n\n    // There are two buffer. One for reading (for writing to file) and one for\n    // writing (for storing new messages). Let new messages be posted to the\n    // unused buffer so that the current buffer can be flushed safely.\n    {\n        CriticalSectionScoped lock(_critsectArray);\n        localNextFreeIdx = _nextFreeIdx[_activeQueue];\n        _nextFreeIdx[_activeQueue] = 0;\n        localQueueActive = _activeQueue;\n        if(_activeQueue == 0)\n        {\n            _activeQueue = 1;\n        } else\n        {\n            _activeQueue = 0;\n        }\n    }\n    if(localNextFreeIdx == 0)\n    {\n        return;\n    }\n\n    CriticalSectionScoped lock(_critsectInterface);\n\n    for(WebRtc_UWord16 idx = 0; idx <localNextFreeIdx; idx++)\n    {\n        TraceLevel localLevel = _level[localQueueActive][idx];\n        if(_callback)\n        {\n            _callback->Print(localLevel, _messageQueue[localQueueActive][idx],\n                             _length[localQueueActive][idx]);\n        }\n        if(_traceFile.Open())\n        {\n            if(_rowCountText > WEBRTC_TRACE_MAX_FILE_SIZE)\n            {\n                // wrap file\n                _rowCountText = 0;\n                _traceFile.Flush();\n\n                if(_fileCountText == 0)\n                {\n                    _traceFile.Rewind();\n                } else\n                {\n                    WebRtc_Word8 oldFileName[FileWrapper::kMaxFileNameSize];\n                    WebRtc_Word8 newFileName[FileWrapper::kMaxFileNameSize];\n\n                    // get current name\n                    _traceFile.FileName(oldFileName,\n                                        FileWrapper::kMaxFileNameSize);\n                    _traceFile.CloseFile();\n\n                    _fileCountText++;\n\n                    UpdateFileName(oldFileName, newFileName, _fileCountText);\n\n                    if(_traceFile.OpenFile(newFileName, false, false,\n                                           true) == -1)\n                    {\n                        return;\n                    }\n                }\n            }\n            if(_rowCountText ==  0)\n            {\n                WebRtc_Word8 message[WEBRTC_TRACE_MAX_MESSAGE_SIZE + 1];\n                WebRtc_Word32 length = AddDateTimeInfo(message);\n                if(length != -1)\n                {\n                    message[length] = 0;\n                    message[length-1] = '\\n';\n                    _traceFile.Write(message, length);\n                    _rowCountText++;\n                }\n                length = AddBuildInfo(message);\n                if(length != -1)\n                {\n                    message[length+1] = 0;\n                    message[length] = '\\n';\n                    message[length-1] = '\\n';\n                    _traceFile.Write(message, length+1);\n                    _rowCountText++;\n                    _rowCountText++;\n                }\n            }\n            WebRtc_UWord16 length = _length[localQueueActive][idx];\n            _messageQueue[localQueueActive][idx][length] = 0;\n            _messageQueue[localQueueActive][idx][length-1] = '\\n';\n            _traceFile.Write(_messageQueue[localQueueActive][idx], length);\n            _rowCountText++;\n        }\n    }\n}\n\nvoid TraceImpl::AddImpl(const TraceLevel level, const TraceModule module,\n                        const WebRtc_Word32 id,\n                        const char msg[WEBRTC_TRACE_MAX_MESSAGE_SIZE])\n{\n    if (TraceCheck(level))\n    {\n        char traceMessage[WEBRTC_TRACE_MAX_MESSAGE_SIZE];\n        char* meassagePtr = traceMessage;\n\n        WebRtc_Word32 len = 0;\n        WebRtc_Word32 ackLen = 0;\n\n        len = AddLevel(meassagePtr, level);\n        if(len == -1)\n        {\n            return;\n        }\n        meassagePtr += len;\n        ackLen += len;\n\n        len = AddTime(meassagePtr, level);\n        if(len == -1)\n        {\n            return;\n        }\n        meassagePtr += len;\n        ackLen += len;\n\n        len = AddModuleAndId(meassagePtr, module, id);\n        if(len == -1)\n        {\n            return;\n        }\n        meassagePtr += len;\n        ackLen += len;\n\n        len = AddThreadId(meassagePtr);\n        if(len == -1)\n        {\n            return;\n        }\n        meassagePtr += len;\n        ackLen += len;\n\n        len = AddMessage(meassagePtr, msg, (WebRtc_UWord16)ackLen);\n        if(len == -1)\n        {\n            return;\n        }\n        ackLen += len;\n        AddMessageToList(traceMessage,(WebRtc_UWord16)ackLen, level);\n\n        // Make sure that messages are written as soon as possible.\n        _event.Set();\n    }\n}\n\nbool TraceImpl::TraceCheck(const TraceLevel level) const\n{\n    return (level & levelFilter)? true:false;\n}\n\nbool TraceImpl::UpdateFileName(\n    const WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize],\n    WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],\n    const WebRtc_UWord32 newCount) const\n{\n    WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8);\n    if(length < 0)\n    {\n        return false;\n    }\n\n    WebRtc_Word32 lengthWithoutFileEnding = length-1;\n    while(lengthWithoutFileEnding > 0)\n    {\n        if(fileNameUTF8[lengthWithoutFileEnding] == '.')\n        {\n            break;\n        } else {\n            lengthWithoutFileEnding--;\n        }\n    }\n    if(lengthWithoutFileEnding == 0)\n    {\n        lengthWithoutFileEnding = length;\n    }\n    WebRtc_Word32 lengthTo_ = lengthWithoutFileEnding - 1;\n    while(lengthTo_ > 0)\n    {\n        if(fileNameUTF8[lengthTo_] == '_')\n        {\n            break;\n        } else {\n            lengthTo_--;\n        }\n    }\n\n    memcpy(fileNameWithCounterUTF8, fileNameUTF8, lengthTo_);\n    sprintf(fileNameWithCounterUTF8+lengthTo_, \"_%lu%s\",\n            static_cast<long unsigned int> (newCount),\n            fileNameUTF8+lengthWithoutFileEnding);\n    return true;\n}\n\nbool TraceImpl::CreateFileName(\n    const WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize],\n    WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],\n    const WebRtc_UWord32 newCount) const\n{\n    WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8);\n    if(length < 0)\n    {\n        return false;\n    }\n\n    WebRtc_Word32 lengthWithoutFileEnding = length-1;\n    while(lengthWithoutFileEnding > 0)\n    {\n        if(fileNameUTF8[lengthWithoutFileEnding] == '.')\n        {\n            break;\n        }else\n        {\n            lengthWithoutFileEnding--;\n        }\n    }\n    if(lengthWithoutFileEnding == 0)\n    {\n        lengthWithoutFileEnding = length;\n    }\n    memcpy(fileNameWithCounterUTF8, fileNameUTF8, lengthWithoutFileEnding);\n    sprintf(fileNameWithCounterUTF8+lengthWithoutFileEnding, \"_%lu%s\",\n            static_cast<long unsigned int> (newCount),\n            fileNameUTF8+lengthWithoutFileEnding);\n    return true;\n}\n\nWebRtc_Word32 Trace::SetLevelFilter(WebRtc_UWord32 filter)\n{\n    levelFilter = filter;\n    return 0;\n};\n\nWebRtc_Word32 Trace::LevelFilter(WebRtc_UWord32& filter)\n{\n    filter = levelFilter;\n    return 0;\n};\n\nWebRtc_Word32 Trace::TraceFile(WebRtc_Word8 fileName[FileWrapper::kMaxFileNameSize])\n{\n    TraceImpl* trace = TraceImpl::GetTrace();\n    if(trace)\n    {\n        int retVal = trace->TraceFileImpl(fileName);\n        ReturnTrace();\n        return retVal;\n    }\n    return -1;\n}\n\nWebRtc_Word32 Trace::SetTraceFile(const WebRtc_Word8* fileName,\n                                  const bool addFileCounter)\n{\n    TraceImpl* trace = TraceImpl::GetTrace();\n    if(trace)\n    {\n        int retVal = trace->SetTraceFileImpl(fileName, addFileCounter);\n        ReturnTrace();\n        return retVal;\n    }\n    return -1;\n}\n\nWebRtc_Word32 Trace::SetTraceCallback(TraceCallback* callback)\n{\n    TraceImpl* trace = TraceImpl::GetTrace();\n    if(trace)\n    {\n        int retVal = trace->SetTraceCallbackImpl(callback);\n        ReturnTrace();\n        return retVal;\n    }\n    return -1;\n}\n\nvoid Trace::Add(const TraceLevel level, const TraceModule module,\n                const WebRtc_Word32 id, const char* msg, ...)\n\n{\n    TraceImpl* trace = TraceImpl::GetTrace(level);\n    if(trace)\n    {\n        if(trace->TraceCheck(level))\n        {\n            char tempBuff[WEBRTC_TRACE_MAX_MESSAGE_SIZE];\n            char* buff = 0;\n            if(msg)\n            {\n                va_list args;\n                va_start(args, msg);\n#ifdef _WIN32\n                _vsnprintf(tempBuff,WEBRTC_TRACE_MAX_MESSAGE_SIZE-1,msg,args);\n#else\n                vsnprintf(tempBuff,WEBRTC_TRACE_MAX_MESSAGE_SIZE-1,msg,args);\n#endif\n                va_end(args);\n                buff = tempBuff;\n            }\n            trace->AddImpl(level, module, id, buff);\n        }\n        ReturnTrace();\n    }\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/trace_impl.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_IMPL_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_IMPL_H_\n\n#include \"system_wrappers/interface/critical_section_wrapper.h\"\n#include \"system_wrappers/interface/event_wrapper.h\"\n#include \"system_wrappers/interface/file_wrapper.h\"\n#include \"system_wrappers/interface/trace.h\"\n#include \"system_wrappers/interface/thread_wrapper.h\"\n\nnamespace webrtc {\nenum TraceCount\n{\n    WEBRTC_TRACE_DEC    = 0,\n    WEBRTC_TRACE_INC    = 1,\n    WEBRTC_TRACE_INC_NO_CREATE = 2\n};\n\nenum TraceCreate\n{\n    WEBRTC_TRACE_EXIST    = 0,\n    WEBRTC_TRACE_CREATE   = 1,\n    WEBRTC_TRACE_DESTROY  = 2\n};\n\n// TODO (pwestin) WEBRTC_TRACE_MAX_QUEUE needs to be tweaked\n// TODO (hellner) the buffer should be close to how much the system can write to\n//                file. Increasing the buffer will not solve anything. Sooner or\n//                later the buffer is going to fill up anyways.\n#if defined(MAC_IPHONE)\n    #define WEBRTC_TRACE_MAX_QUEUE  2000\n#else\n    #define WEBRTC_TRACE_MAX_QUEUE  8000\n#endif\n#define WEBRTC_TRACE_NUM_ARRAY 2\n#define WEBRTC_TRACE_MAX_MESSAGE_SIZE 256\n// Total buffer size is WEBRTC_TRACE_NUM_ARRAY (number of buffer partitions) *\n// WEBRTC_TRACE_MAX_QUEUE (number of lines per buffer partition) *\n// WEBRTC_TRACE_MAX_MESSAGE_SIZE (number of 1 byte charachters per line) =\n// 1 or 4 Mbyte\n\n#define WEBRTC_TRACE_MAX_FILE_SIZE 100*1000\n// Number of rows that may be written to file. On average 110 bytes per row (max\n// 256 bytes per row). So on average 110*100*1000 = 11 Mbyte, max 256*100*1000 =\n// 25.6 Mbyte\n\nclass TraceImpl : public Trace\n{\npublic:\n    virtual ~TraceImpl();\n\n    static Trace* CreateTrace();\n    static TraceImpl* GetTrace(const TraceLevel level = kTraceAll);\n\n    static Trace* StaticInstance(TraceCount inc,\n                                 const TraceLevel level = kTraceAll);\n\n    WebRtc_Word32 SetTraceFileImpl(const WebRtc_Word8* fileName,\n                                   const bool addFileCounter);\n    WebRtc_Word32 TraceFileImpl(\n        WebRtc_Word8 fileName[FileWrapper::kMaxFileNameSize]);\n\n    WebRtc_Word32 SetTraceCallbackImpl(TraceCallback* callback);\n\n    void AddImpl(const TraceLevel level, const TraceModule module,\n                 const WebRtc_Word32 id, const char* msg);\n\n    bool StopThread();\n\n    bool TraceCheck(const TraceLevel level) const;\n\nprotected:\n    TraceImpl();\n\n    // OS specific implementations\n    virtual WebRtc_Word32 AddThreadId(char* traceMessage) const = 0;\n    virtual WebRtc_Word32 AddTime(char* traceMessage,\n                                  const TraceLevel level) const = 0;\n\n    virtual WebRtc_Word32 AddBuildInfo(char* traceMessage) const = 0;\n    virtual WebRtc_Word32 AddDateTimeInfo(char* traceMessage) const = 0;\n\n    static bool Run(void* obj);\n    bool Process();\n\nprivate:\n    WebRtc_Word32 AddLevel(char* szMessage, const TraceLevel level) const;\n\n    WebRtc_Word32 AddModuleAndId(char* traceMessage, const TraceModule module,\n                                 const WebRtc_Word32 id) const;\n\n    WebRtc_Word32 AddMessage(char* traceMessage,\n                             const char msg[WEBRTC_TRACE_MAX_MESSAGE_SIZE],\n                             const WebRtc_UWord16 writtenSoFar) const;\n\n    void AddMessageToList(\n        const char traceMessage[WEBRTC_TRACE_MAX_MESSAGE_SIZE],\n        const WebRtc_UWord16 length,\n        const TraceLevel level);\n\n    bool UpdateFileName(\n        const WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize],\n        WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],\n        const WebRtc_UWord32 newCount) const;\n\n    bool CreateFileName(\n        const WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize],\n        WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],\n        const WebRtc_UWord32 newCount) const;\n\n    void WriteToFile();\n\n    CriticalSectionWrapper& _critsectInterface;\n    TraceCallback* _callback;\n    WebRtc_UWord32 _rowCountText;\n    WebRtc_UWord32 _fileCountText;\n\n    FileWrapper& _traceFile;\n    ThreadWrapper& _thread;\n    EventWrapper& _event;\n\n    // _critsectArray protects _activeQueue\n    CriticalSectionWrapper& _critsectArray;\n    WebRtc_UWord16 _nextFreeIdx[WEBRTC_TRACE_NUM_ARRAY];\n    TraceLevel _level[WEBRTC_TRACE_NUM_ARRAY][WEBRTC_TRACE_MAX_QUEUE];\n    WebRtc_UWord16 _length[WEBRTC_TRACE_NUM_ARRAY][WEBRTC_TRACE_MAX_QUEUE];\n    WebRtc_Word8* _messageQueue[WEBRTC_TRACE_NUM_ARRAY][WEBRTC_TRACE_MAX_QUEUE];\n    WebRtc_UWord8 _activeQueue;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_IMPL_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/trace_posix.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"trace_posix.h\"\n\n#include <cassert>\n#include <stdarg.h>\n#include <stdio.h>\n#include <string.h>\n#include <time.h>\n\n#ifdef WEBRTC_ANDROID\n    #include <pthread.h>\n#else\n    #include <iostream>\n#endif\n\n#if defined(_DEBUG)\n    #define BUILDMODE \"d\"\n#elif defined(DEBUG)\n    #define BUILDMODE \"d\"\n#elif defined(NDEBUG)\n    #define BUILDMODE \"r\"\n#else\n    #define BUILDMODE \"?\"\n#endif\n#define BUILDTIME __TIME__\n#define BUILDDATE __DATE__\n// example: \"Oct 10 2002 12:05:30 r\"\n#define BUILDINFO BUILDDATE \" \" BUILDTIME \" \" BUILDMODE\n\nnamespace webrtc {\nTracePosix::TracePosix()\n{\n    _prevAPITickCount = time(NULL);\n    _prevTickCount = _prevAPITickCount;\n}\n\nTracePosix::~TracePosix()\n{\n    StopThread();\n}\n\nWebRtc_Word32 TracePosix::AddThreadId(char* traceMessage) const\n{\n    WebRtc_UWord64 threadId = (WebRtc_UWord64)pthread_self();\n    sprintf(traceMessage, \"%10llu; \",\n            static_cast<long long unsigned int>(threadId));\n    // 12 bytes are written.\n    return 12;\n}\n\nWebRtc_Word32 TracePosix::AddTime(char* traceMessage,\n                                  const TraceLevel level) const\n{\n    time_t dwCurrentTimeInSeconds = time(NULL);\n    struct tm systemTime;\n    gmtime_r(&dwCurrentTimeInSeconds, &systemTime);\n\n    if(level == kTraceApiCall)\n    {\n        WebRtc_UWord32 dwDeltaTime = dwCurrentTimeInSeconds - _prevTickCount;\n        _prevTickCount = dwCurrentTimeInSeconds;\n\n        if(_prevTickCount == 0)\n        {\n            dwDeltaTime = 0;\n        }\n        if(dwDeltaTime > 0x0fffffff)\n        {\n            // Either wraparound or data race.\n            dwDeltaTime = 0;\n        }\n        if(dwDeltaTime > 99999)\n        {\n            dwDeltaTime = 99999;\n        }\n\n        sprintf(traceMessage, \"(%2u:%2u:%2u:%3u |%5lu) \", systemTime.tm_hour,\n                systemTime.tm_min, systemTime.tm_sec, 0,\n                static_cast<unsigned long>(dwDeltaTime));\n    } else {\n        WebRtc_UWord32 dwDeltaTime = dwCurrentTimeInSeconds - _prevAPITickCount;\n        _prevAPITickCount = dwCurrentTimeInSeconds;\n        if(_prevAPITickCount == 0)\n        {\n            dwDeltaTime = 0;\n        }\n        if(dwDeltaTime > 0x0fffffff)\n        {\n            // Either wraparound or data race.\n            dwDeltaTime = 0;\n        }\n        if(dwDeltaTime > 99999)\n        {\n            dwDeltaTime = 99999;\n        }\n        sprintf(traceMessage, \"(%2u:%2u:%2u:%3u |%5lu) \", systemTime.tm_hour,\n                systemTime.tm_min, systemTime.tm_sec, 0,\n                static_cast<unsigned long>(dwDeltaTime));\n    }\n    // Messages is 22 characters.\n    return 22;\n}\n\nWebRtc_Word32 TracePosix::AddBuildInfo(char* traceMessage) const\n{\n    sprintf(traceMessage, \"Build info: %s\", BUILDINFO);\n    // Include NULL termination (hence + 1).\n    return strlen(traceMessage) + 1;\n}\n\nWebRtc_Word32 TracePosix::AddDateTimeInfo(char* traceMessage) const\n{\n    time_t t;\n    time(&t);\n    sprintf(traceMessage, \"Local Date: %s\", ctime(&t));\n    WebRtc_Word32 len = static_cast<WebRtc_Word32>(strlen(traceMessage));\n\n    if ('\\n' == traceMessage[len - 1])\n    {\n        traceMessage[len - 1] = '\\0';\n        --len;\n    }\n\n    // Messages is 12 characters.\n    return len + 1;\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/trace_posix.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_POSIX_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_POSIX_H_\n\n#include \"critical_section_wrapper.h\"\n#include \"trace_impl.h\"\n\nnamespace webrtc {\nclass TracePosix : public TraceImpl\n{\npublic:\n    TracePosix();\n    virtual ~TracePosix();\n\n    virtual WebRtc_Word32 AddThreadId(char *traceMessage) const;\n    virtual WebRtc_Word32 AddTime(char* traceMessage,\n                                  const TraceLevel level) const;\n\n    virtual WebRtc_Word32 AddBuildInfo(char* traceMessage) const;\n    virtual WebRtc_Word32 AddDateTimeInfo(char* traceMessage) const;\n\nprivate:\n    volatile mutable WebRtc_UWord32  _prevAPITickCount;\n    volatile mutable WebRtc_UWord32  _prevTickCount;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_POSIX_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/trace_windows.cc",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#include \"trace_windows.h\"\n\n#include <cassert>\n#include <stdarg.h>\n\n#include \"Mmsystem.h\"\n\n#if defined(_DEBUG)\n    #define BUILDMODE \"d\"\n#elif defined(DEBUG)\n    #define BUILDMODE \"d\"\n#elif defined(NDEBUG)\n    #define BUILDMODE \"r\"\n#else\n    #define BUILDMODE \"?\"\n#endif\n#define BUILDTIME __TIME__\n#define BUILDDATE __DATE__\n// Example: \"Oct 10 2002 12:05:30 r\"\n#define BUILDINFO BUILDDATE \" \" BUILDTIME \" \" BUILDMODE\n\nnamespace webrtc {\nTraceWindows::TraceWindows()\n    : _prevAPITickCount(0),\n      _prevTickCount(0)\n{\n}\n\nTraceWindows::~TraceWindows()\n{\n    StopThread();\n}\n\nWebRtc_Word32 TraceWindows::AddThreadId(char* traceMessage) const\n{\n    WebRtc_UWord32 threadId= GetCurrentThreadId();\n    sprintf (traceMessage, \"%10u; \", threadId);\n    // Messages is 12 characters.\n    return 12;\n}\n\nWebRtc_Word32 TraceWindows::AddTime(char* traceMessage,\n                                    const TraceLevel level) const\n{\n    WebRtc_UWord32 dwCurrentTime = timeGetTime();\n    SYSTEMTIME systemTime;\n    GetSystemTime(&systemTime);\n\n    if(level == kTraceApiCall)\n    {\n        WebRtc_UWord32 dwDeltaTime = dwCurrentTime- _prevTickCount;\n        _prevTickCount = dwCurrentTime;\n\n        if(_prevTickCount == 0)\n        {\n            dwDeltaTime = 0;\n        }\n        if(dwDeltaTime > 0x0fffffff)\n        {\n            // Either wraparound or data race.\n            dwDeltaTime = 0;\n        }\n        if(dwDeltaTime > 99999)\n        {\n            dwDeltaTime = 99999;\n        }\n\n        sprintf (traceMessage, \"(%2u:%2u:%2u:%3u |%5lu) \", systemTime.wHour,\n                 systemTime.wMinute, systemTime.wSecond,\n                 systemTime.wMilliseconds, dwDeltaTime);\n    } else {\n        WebRtc_UWord32 dwDeltaTime = dwCurrentTime - _prevAPITickCount;\n        _prevAPITickCount = dwCurrentTime;\n\n        if(_prevAPITickCount == 0)\n        {\n            dwDeltaTime = 0;\n        }\n        if(dwDeltaTime > 0x0fffffff)\n        {\n            // Either wraparound or data race.\n            dwDeltaTime = 0;\n        }\n        if(dwDeltaTime > 99999)\n        {\n            dwDeltaTime = 99999;\n        }\n        sprintf (traceMessage, \"(%2u:%2u:%2u:%3u |%5lu) \", systemTime.wHour,\n                 systemTime.wMinute, systemTime.wSecond,\n                 systemTime.wMilliseconds, dwDeltaTime);\n    }\n    // Messages is 12 characters.\n    return 22;\n}\n\nWebRtc_Word32 TraceWindows::AddBuildInfo(char* traceMessage) const\n{\n    // write data and time to text file\n    sprintf(traceMessage, \"Build info: %s\", BUILDINFO);\n    // Include NULL termination (hence + 1).\n    return static_cast<WebRtc_Word32>(strlen(traceMessage)+1);\n}\n\nWebRtc_Word32 TraceWindows::AddDateTimeInfo(char* traceMessage) const\n{\n    _prevAPITickCount = timeGetTime();\n    _prevTickCount = _prevAPITickCount;\n\n    SYSTEMTIME sysTime;\n    GetLocalTime (&sysTime);\n\n    TCHAR szDateStr[20];\n    TCHAR szTimeStr[20];\n    TCHAR *pSzDateStr = szDateStr;\n    TCHAR *pSzTimeStr = szTimeStr;\n\n    // Create date string (e.g. Apr 04 2002)\n    GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, TEXT(\"MMM dd yyyy\"),\n                  szDateStr, 20);\n\n    // Create time string (e.g. 15:32:08)\n    GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, TEXT(\"HH':'mm':'ss\"),\n                  szTimeStr, 20);\n\n    sprintf(traceMessage, \"Local Date: %s Local Time: %s\", szDateStr,\n            szTimeStr);\n\n    // Include NULL termination (hence + 1).\n    return static_cast<WebRtc_Word32>(strlen(traceMessage)+ 1);\n}\n} // namespace webrtc\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/system_wrappers/source/trace_windows.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_WINDOWS_H_\n#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_WINDOWS_H_\n\n#include \"trace_impl.h\"\n#include <stdio.h>\n#include <windows.h>\n\nnamespace webrtc {\nclass TraceWindows : public TraceImpl\n{\npublic:\n    TraceWindows();\n      virtual ~TraceWindows();\n\n    virtual WebRtc_Word32 AddThreadId(char *traceMessage) const;\n    virtual WebRtc_Word32 AddTime(char* traceMessage,\n                                  const TraceLevel level) const;\n\n    virtual WebRtc_Word32 AddBuildInfo(char* traceMessage) const;\n    virtual WebRtc_Word32 AddDateTimeInfo(char* traceMessage) const;\nprivate:\n    volatile mutable WebRtc_UWord32    _prevAPITickCount;\n    volatile mutable WebRtc_UWord32   _prevTickCount;\n};\n} // namespace webrtc\n\n#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_WINDOWS_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/webrtc/src/typedefs.h",
    "content": "/*\n *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.\n *\n *  Use of this source code is governed by a BSD-style license\n *  that can be found in the LICENSE file in the root of the source\n *  tree. An additional intellectual property rights grant can be found\n *  in the file PATENTS.  All contributing project authors may\n *  be found in the AUTHORS file in the root of the source tree.\n */\n\n// This file contains platform-specific typedefs and defines.\n\n#ifndef WEBRTC_TYPEDEFS_H_\n#define WEBRTC_TYPEDEFS_H_\n\n// Reserved words definitions\n// TODO(andrew): Look at removing these.\n#define WEBRTC_EXTERN extern\n#define G_CONST const\n#define WEBRTC_INLINE extern __inline\n\n// Define WebRTC preprocessor identifiers based on the current build platform.\n// TODO(andrew): Clean these up. We can probably remove everything in this\n// block.\n//   - TARGET_MAC_INTEL and TARGET_MAC aren't used anywhere.\n//   - In the few places where TARGET_PC is used, it should be replaced by\n//     something more specific.\n//   - Do we really support PowerPC? Probably not. Remove WEBRTC_MAC_INTEL\n//     from build/common.gypi as well.\n#if defined(WIN32)\n    // Windows & Windows Mobile\n    #if !defined(WEBRTC_TARGET_PC)\n        #define WEBRTC_TARGET_PC\n    #endif\n#elif defined(__APPLE__)\n    // Mac OS X\n    #if defined(__LITTLE_ENDIAN__ )\n        #if !defined(WEBRTC_TARGET_MAC_INTEL)\n            #define WEBRTC_TARGET_MAC_INTEL\n        #endif\n    #else\n        #if !defined(WEBRTC_TARGET_MAC)\n            #define WEBRTC_TARGET_MAC\n        #endif\n    #endif\n#else\n    // Linux etc.\n    #if !defined(WEBRTC_TARGET_PC)\n        #define WEBRTC_TARGET_PC\n    #endif\n#endif\n\n// Derived from Chromium's build/build_config.h\n// Processor architecture detection.  For more info on what's defined, see:\n//   http://msdn.microsoft.com/en-us/library/b0084kay.aspx\n//   http://www.agner.org/optimize/calling_conventions.pdf\n//   or with gcc, run: \"echo | gcc -E -dM -\"\n// TODO(andrew): replace WEBRTC_LITTLE_ENDIAN with WEBRTC_ARCH_LITTLE_ENDIAN?\n#if defined(_M_X64) || defined(__x86_64__)\n#define WEBRTC_ARCH_X86_FAMILY\n#define WEBRTC_ARCH_X86_64\n#define WEBRTC_ARCH_64_BITS\n#define WEBRTC_ARCH_LITTLE_ENDIAN\n#elif defined(_M_IX86) || defined(__i386__)\n#define WEBRTC_ARCH_X86_FAMILY\n#define WEBRTC_ARCH_X86\n#define WEBRTC_ARCH_32_BITS\n#define WEBRTC_ARCH_LITTLE_ENDIAN\n#elif defined(__ARMEL__)\n// TODO(andrew): We'd prefer to control platform defines here, but this is\n// currently provided by the Android makefiles. Commented to avoid duplicate\n// definition warnings.\n//#define WEBRTC_ARCH_ARM\n// TODO(andrew): Chromium uses the following two defines. Should we switch?\n//#define WEBRTC_ARCH_ARM_FAMILY\n//#define WEBRTC_ARCH_ARMEL\n#define WEBRTC_ARCH_32_BITS\n#define WEBRTC_ARCH_LITTLE_ENDIAN\n#else\n#error Please add support for your architecture in typedefs.h\n#endif\n\n// TODO(andrew): SSE2 is disabled on Windows for the moment, because AEC\n// optimization is broken. Enable it as soon as AEC is fixed.\n//#if defined(__SSE2__) || defined(_MSC_VER)\n#if defined(__SSE2__)\n#define WEBRTC_USE_SSE2\n#endif\n\n#if defined(WEBRTC_TARGET_PC)\n\n#if !defined(_MSC_VER)\n  #include <stdint.h>\n#else\n    // Define C99 equivalent types.\n    // Since MSVC doesn't include these headers, we have to write our own\n    // version to provide a compatibility layer between MSVC and the WebRTC\n    // headers.\n    typedef signed char         int8_t;\n    typedef signed short        int16_t;\n    typedef signed int          int32_t;\n    typedef signed long long    int64_t;\n    typedef unsigned char       uint8_t;\n    typedef unsigned short      uint16_t;\n    typedef unsigned int        uint32_t;\n    typedef unsigned long long  uint64_t;\n#endif\n\n    typedef int64_t             WebRtc_Word64;\n    typedef uint64_t            WebRtc_UWord64;\n    typedef int32_t             WebRtc_Word32;\n    typedef uint32_t            WebRtc_UWord32;\n    typedef int16_t             WebRtc_Word16;\n    typedef uint16_t            WebRtc_UWord16;\n    typedef char                WebRtc_Word8;\n    typedef uint8_t             WebRtc_UWord8;\n\n    // Define endian for the platform\n    #define WEBRTC_LITTLE_ENDIAN\n\n#elif defined(WEBRTC_TARGET_MAC_INTEL)\n    #include <stdint.h>\n\n    typedef int64_t             WebRtc_Word64;\n    typedef uint64_t            WebRtc_UWord64;\n    typedef int32_t             WebRtc_Word32;\n    typedef uint32_t            WebRtc_UWord32;\n    typedef int16_t             WebRtc_Word16;\n    typedef char                WebRtc_Word8;\n    typedef uint16_t            WebRtc_UWord16;\n    typedef uint8_t             WebRtc_UWord8;\n\n    // Define endian for the platform\n    #define WEBRTC_LITTLE_ENDIAN\n\n#else\n    #error \"No platform defined for WebRTC type definitions (typedefs.h)\"\n#endif\n\n#endif  // WEBRTC_TYPEDEFS_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/include/ZsrtpCWrapper.h",
    "content": "/*\n    This file defines the ZRTP SRTP C-to-C++ wrapper.\n    Copyright (C) 2010  Werner Dittmann\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n*/\n\n#ifndef ZSRTPCWRAPPER_H\n#define ZSRTPCWRAPPER_H\n\n/**\n * @file ZsrtpCWrapper.h\n * @brief C-to-C++ wrapper for the C++ based SRTP and SRTCP implementation\n * @defgroup Z_SRTP SRTP/SRTCP implementation for ZRTP including C-to-C++ wrapper\n * @ingroup PJMEDIA_TRANSPORT_ZRTP\n * @{\n */\n\n#include <stdint.h>\n\n/*\n * Keep in synch with CryptoContext.h\n */\n#define SrtpAuthenticationNull      0\n#define SrtpAuthenticationSha1Hmac  1\n#define SrtpAuthenticationSkeinHmac 2\n\n\n#define SrtpEncryptionNull    0\n#define SrtpEncryptionAESCM   1\n#define SrtpEncryptionAESF8   2\n#define SrtpEncryptionTWOCM   3\n#define SrtpEncryptionTWOF8   4\n\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n#ifdef __cplusplus\n    typedef class CryptoContext CryptoContext;\n#else\n    typedef struct CryptoContext CryptoContext;\n#endif\n\n    typedef struct zsrtpContext\n    {\n        CryptoContext* srtp;\n        void* userData;\n    } ZsrtpContext;\n\n    /**\n     * Create a ZSRTP wrapper fir a SRTP cryptographic context.\n     *\n     * This constructor creates an active SRTP cryptographic context were\n     * algorithms are enabled, keys are computed and so on. This SRTP\n     * cryptographic context can protect a RTP SSRC stream.\n     *\n     * @param ssrc\n     *    The RTP SSRC that this SRTP cryptographic context protects.\n     *\n     * @param roc\n     *    The initial Roll-Over-Counter according to RFC 3711. These are the\n     *    upper 32 bit of the overall 48 bit SRTP packet index. Refer to\n     *    chapter 3.2.1 of the RFC.\n     *\n     * @param keyDerivRate\n     *    The key derivation rate defines when to recompute the SRTP session\n     *    keys. Refer to chapter 4.3.1 in the RFC.\n     *\n     * @param ealg\n     *    The encryption algorithm to use. Possible values are <code>\n     *    SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8\n     *    </code>. See chapter 4.1.1 for AESCM (Counter mode) and 4.1.2\n     *    for AES F8 mode.\n     *\n     * @param aalg\n     *    The authentication algorithm to use. Possible values are <code>\n     *    SrtpEncryptionNull, SrtpAuthenticationSha1Hmac</code>. The only\n     *    active algorithm here is SHA1 HMAC, a SHA1 based hashed message\n     *    authentication code as defined in RFC 2104.\n     *\n     * @param masterKey\n     *    Pointer to the master key for this SRTP cryptographic context.\n     *    Must point to <code>masterKeyLength</code> bytes. Refer to chapter\n     *    3.2.1 of the RFC about the role of the master key.\n     *\n     * @param masterKeyLength\n     *    The length in bytes of the master key in bytes. The length must\n     *    match the selected encryption algorithm. Because SRTP uses AES\n     *    based  encryption only, then master key length may be 16 or 32\n     *    bytes (128 or 256 bit master key)\n     *\n     * @param masterSalt\n     *    SRTP uses the master salt to computer the initialization vector\n     *    that in turn is input to compute the session key, session\n     *    authentication key and the session salt.\n     *\n     * @param masterSaltLength\n     *    The length in bytes of the master salt data in bytes. SRTP uses\n     *    AES as encryption algorithm. AES encrypts 16 byte blocks\n     *    (independent of the key length). According to RFC3711 the standard\n     *    value for the master salt length should be 112 bit (14 bytes).\n     *\n     * @param ekeyl\n     *    The length in bytes of the session encryption key that SRTP shall\n     *    compute and use. Usually the same length as for the master key\n     *    length. But you may use a different length as well. Be carefull\n     *    that the key management mechanisms supports different key lengths.\n     *\n     * @param akeyl\n     *    The length in bytes of the session authentication key. SRTP\n     *    computes this key and uses it as input to the authentication\n     *    algorithm.\n     *    The standard value is 160 bits (20 bytes).\n     *\n     * @param skeyl\n     *    The length in bytes of the session salt. SRTP computes this salt\n     *    key and uses it as input during encryption. The length usually\n     *    is the same as the master salt length.\n     *\n     * @param tagLength\n     *    The length is bytes of the authentication tag that SRTP appends\n     *    to the RTP packet. Refer to chapter 4.2. in the RFC 3711.\n     * \n     * @returns\n     *     Pointer to a new ZSRTP wrapper context.\n     */\n    ZsrtpContext* zsrtp_CreateWrapper(uint32_t ssrc, int32_t roc,\n                                      int64_t  keyDerivRate,\n                                      const  int32_t ealg,\n                                      const  int32_t aalg,\n                                      uint8_t* masterKey,\n                                      int32_t  masterKeyLength,\n                                      uint8_t* masterSalt,\n                                      int32_t  masterSaltLength,\n                                      int32_t  ekeyl,\n                                      int32_t  akeyl,\n                                      int32_t  skeyl,\n                                      int32_t  tagLength);\n\n    /**\n     * Destroy a ZSRTP wrapper Context\n     * \n     * @param ctx\n     *     A ZSRTP wrapper context.\n     */\n    void zsrtp_DestroyWrapper (ZsrtpContext* ctx);\n\n    /**\n     * Encrypt the RTP payload and compute authentication code.\n     *\n     * The method requires a ready made RTP packet in the RTP packet data\n     * buffer.\n     *\n     * The method computes an authentication code and appends this code to the\n     * buffer and computes a new length. The RTP packet buffer must be large\n     * enough to hold this authentication code.\n     *\n     * @param ctx\n     *     The ZsrtpContext\n     *\n     * @param buffer\n     *     Pointer to the data that contains the RTP packet data. SRTP appends\n     *     the authentication code to the encrypted RTP packet data.\n     *\n     * @param length\n     *     Length of the RTP data buffer.\n     *\n     * @param newLength\n     *     The new length of the RTP data buffer including authentication code\n     * \n     * @returns\n     *     0 if no active SRTP crypto context, 1 if data is encrypted.\n     */\n    int32_t zsrtp_protect(ZsrtpContext* ctx, uint8_t* buffer, int32_t length,\n                          int32_t* newLength);\n\n    /**\n     * Decrypt the RTP payload and check authentication code.\n     *\n     * The method requires a SRTP packet in the SRTP packet data\n     * buffer.\n     *\n     * SRTP checks SRTP packet replay, then it computes the authentication\n     * code and checks if the authentication code is correct. If the checks\n     * are ok then SRTP decrypts the payload data.\n     *\n     * @param ctx\n     *     The ZsrtpContext\n     *\n     * @param buffer\n     *     Pointer to the data that contains the SRTP packet data. SRTP removes\n     *     the authentication code from the decrypted RTP packet data.\n     *\n     * @param length\n     *     Length of the RTP data buffer.\n     *\n     * @param newLength\n     *     The new length of the RTP data buffer excluding authentication code\n     * \n     * @returns\n     *     0 if no active SRTP crypto context, 1 if data is decrypted,\n     *     -1 if data authentication failed, -2 if SRTP replay check failed\n     */\n    int32_t zsrtp_unprotect(ZsrtpContext* ctx, uint8_t* buffer, int32_t length,\n                            int32_t* newLength);\n\n    /**\n     * Derive a new Crypto Context for use with a new SSRC\n     *\n     * This method stores a new Crypto Context initialized with the data\n     * of this crypto context. Replacing the SSRC, Roll-over-Counter, and\n     * the key derivation rate the application cab use this Crypto Context\n     * to encrypt / decrypt a new stream (Synchronization source) inside\n     * one RTP session.\n     *\n     * Before the application can use this crypto context it must call\n     * the <code>deriveSrtpKeys</code> method.\n     *\n     * @param ctx\n     *     The ZsrtpContext\n     * @param ssrc\n     *     The SSRC for this context\n     * @param roc\n     *     The Roll-Over-Counter for this context\n     * @param keyDerivRate\n     *     The key derivation rate for this context\n     */\n    void zsrtp_newCryptoContextForSSRC(ZsrtpContext* ctx, uint32_t ssrc, \n                                      int32_t roc, int64_t keyDerivRate);\n\n    /**\n     * Perform key derivation according to SRTP specification\n     *\n     * This method computes the session key, session authentication key and the\n     * session salt key. This method must be called at least once after the\n     * SRTP Cryptograhic context was set up.\n     *\n     * @param ctx\n     *     The ZsrtpContext\n     * @param index\n     *    The 48 bit SRTP packet index. See the <code>guessIndex</code>\n     *    method.\n     */                                    \n    void zsrtp_deriveSrtpKeys(ZsrtpContext* ctx, uint64_t index);\n\n#ifdef __cplusplus\n    typedef class CryptoContextCtrl CryptoContextCtrl;\n#else\n    typedef struct CryptoContextCtrl CryptoContextCtrl;\n#endif\n\n    typedef struct zsrtcpContext\n    {\n        CryptoContextCtrl* srtcp;\n        void* userData;\n        uint32_t srtcpIndex;\n    } ZsrtpContextCtrl;\n\n    /**\n     * Constructor for an active SRTP cryptographic context.\n     *\n     * This constructor creates an active SRTP cryptographic context were\n     * algorithms are enabled, keys are computed and so on. This SRTP\n     * cryptographic context can protect a RTP SSRC stream.\n     *\n     * @param ssrc\n     *    The RTP SSRC that this SRTP cryptographic context protects.\n     *\n     * @param ealg\n     *    The encryption algorithm to use. Possible values are <code>\n     *    SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8\n     *    </code>. See chapter 4.1.1 for AESCM (Counter mode) and 4.1.2\n     *    for AES F8 mode.\n     *\n     * @param aalg\n     *    The authentication algorithm to use. Possible values are <code>\n     *    SrtpEncryptionNull, SrtpAuthenticationSha1Hmac</code>. The only\n     *    active algorithm here is SHA1 HMAC, a SHA1 based hashed message\n     *    authentication code as defined in RFC 2104.\n     *\n     * @param masterKey\n     *    Pointer to the master key for this SRTP cryptographic context.\n     *    Must point to <code>masterKeyLength</code> bytes. Refer to chapter\n     *    3.2.1 of the RFC about the role of the master key.\n     *\n     * @param masterKeyLength\n     *    The length in bytes of the master key in bytes. The length must\n     *    match the selected encryption algorithm. Because SRTP uses AES\n     *    based  encryption only, then master key length may be 16 or 32\n     *    bytes (128 or 256 bit master key)\n     *\n     * @param masterSalt\n     *    SRTP uses the master salt to computer the initialization vector\n     *    that in turn is input to compute the session key, session\n     *    authentication key and the session salt.\n     *\n     * @param masterSaltLength\n     *    The length in bytes of the master salt data in bytes. SRTP uses\n     *    AES as encryption algorithm. AES encrypts 16 byte blocks\n     *    (independent of the key length). According to RFC3711 the standard\n     *    value for the master salt length should be 112 bit (14 bytes).\n     *\n     * @param ekeyl\n     *    The length in bytes of the session encryption key that SRTP shall\n     *    compute and use. Usually the same length as for the master key\n     *    length. But you may use a different length as well. Be carefull\n     *    that the key management mechanisms supports different key lengths.\n     *\n     * @param akeyl\n     *    The length in bytes of the session authentication key. SRTP\n     *    computes this key and uses it as input to the authentication\n     *    algorithm.\n     *    The standard value is 160 bits (20 bytes).\n     *\n     * @param skeyl\n     *    The length in bytes of the session salt. SRTP computes this salt\n     *    key and uses it as input during encryption. The length usually\n     *    is the same as the master salt length.\n     *\n     * @param tagLength\n     *    The length is bytes of the authentication tag that SRTP appends\n     *    to the RTP packet. Refer to chapter 4.2. in the RFC 3711.\n     */\n    ZsrtpContextCtrl* zsrtp_CreateWrapperCtrl( uint32_t ssrc,\n               const  int32_t ealg,\n               const  int32_t aalg,\n               uint8_t* masterKey,\n               int32_t  masterKeyLength,\n               uint8_t* masterSalt,\n               int32_t  masterSaltLength,\n               int32_t  ekeyl,\n               int32_t  akeyl,\n               int32_t  skeyl,\n               int32_t  tagLength );\n\n    /**\n     * Destroy a ZSRTCP wrapper Context\n     * \n     * @param ctx\n     *     A ZSRTCP wrapper context.\n     */\n    void zsrtp_DestroyWrapperCtrl (ZsrtpContextCtrl* ctx);\n\n    /**\n     * Encrypt the RTCP payload and compute authentication code.\n     *\n     * The method requires a ready made RTCP packet in the RTCP packet data\n     * buffer.\n     *\n     * The method computes an authentication code and appends this code to the\n     * buffer and computes a new length. The RTCP packet buffer must be large\n     * enough to hold this authentication code.\n     *\n     * @param ctx\n     *     The ZsrtpContextCtrl\n     *\n     * @param buffer\n     *     Pointer to the data that contains the RTP packet data. SRTP appends\n     *     the authentication code to the encrypted RTP packet data.\n     *\n     * @param length\n     *     Length of the RTCP data buffer.\n     *\n     * @param newLength\n     *     The new length of the RTCP data buffer including authentication code\n     * \n     * @returns\n     *     0 if no active SRTCP crypto context, 1 if data is encrypted.\n     */\n    int32_t zsrtp_protectCtrl(ZsrtpContextCtrl* ctx, uint8_t* buffer, int32_t length,\n                          int32_t* newLength);\n\n    /**\n     * Decrypt the RTCP payload and check authentication code.\n     *\n     * The method requires a SRTCP packet in the SRTP packet data\n     * buffer.\n     *\n     * SRTP checks SRTP packet replay, then it computes the authentication\n     * code and checks if the authentication code is correct. If the checks\n     * are ok then SRTP decrypts the payload data.\n     *\n     * @param ctx\n     *     The ZsrtpContextCtrl\n     *\n     * @param buffer\n     *     Pointer to the data that contains the SRTCP packet data. SRTCP remove\n     *     the authentication code from the decrypted RTCP packet data.\n     *\n     * @param length\n     *     Length of the RTP data buffer.\n     *\n     * @param newLength\n     *     The new length of the RTCP data buffer excluding authentication code\n     * \n     * @returns\n     *     0 if no active SRTCP crypto context, 1 if data is decrypted,\n     *     -1 if data authentication failed, -2 if SRTCP replay check failed\n     */\n    int32_t zsrtp_unprotectCtrl(ZsrtpContextCtrl* ctx, uint8_t* buffer, int32_t length,\n                            int32_t* newLength);\n\n    /**\n     * Derive a new Crypto Context for use with a new SSRC\n     *\n     * This method stores a new Crypto Context initialized with the data\n     * of this crypto context. Replacing the SSRC, Roll-over-Counter, and\n     * the key derivation rate the application cab use this Crypto Context\n     * to encrypt / decrypt a new stream (Synchronization source) inside\n     * one RTP session.\n     *\n     * Before the application can use this crypto context it must call\n     * the <code>deriveSrtpKeys</code> method.\n     *\n     * @param ctx\n     *     The ZsrtpContextCtrl\n     * @param ssrc\n     *     The SSRC for this context\n     */\n    void zsrtp_newCryptoContextForSSRCCtrl(ZsrtpContextCtrl* ctx, uint32_t ssrc);\n\n    /**\n     * Perform key derivation according to SRTP specification\n     *\n     * This method computes the session key, session authentication key and the\n     * session salt key. This method must be called at least once after the\n     * SRTP Cryptograhic context was set up.\n     *\n     * @param ctx\n     *     The ZsrtpContextCtrl\n     */                                    \n    void zsrtp_deriveSrtpKeysCtrl(ZsrtpContextCtrl* ctx);\n    \n    \n#ifdef __cplusplus\n}\n#endif\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/include/openssl_compat.h",
    "content": "#ifndef _OPENSSL_COMPAT\n#define _OPENSSL_COMPAT\n\n#include <openssl/hmac.h>\n\n#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)\nstatic HMAC_CTX *HMAC_CTX_new(void)\n{\n    HMAC_CTX *ctx = (HMAC_CTX*)OPENSSL_malloc(sizeof(HMAC_CTX));\n    if (ctx != NULL)\n        HMAC_CTX_init(ctx);\n    return ctx;\n}\n\nstatic void HMAC_CTX_free(HMAC_CTX *ctx)\n{\n    if (ctx != NULL) {\n        HMAC_CTX_cleanup(ctx);\n        OPENSSL_free(ctx);\n    }\n}\n\nstatic int HMAC_CTX_reset(HMAC_CTX *ctx)\n{\n    HMAC_CTX_init(ctx);\n    return 1;\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/srtp/ZsrtpCWrapper.cpp",
    "content": "/*\n    This file implements the ZRTP SRTP C-to-C++ wrapper.\n    Copyright (C) 2010  Werner Dittmann\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n*/\n\n#include <CryptoContext.h>\n#include <CryptoContextCtrl.h>\n#include <ZsrtpCWrapper.h>\n#include <pjmedia/rtp.h>\n#include <pjmedia/errno.h>\n#include <pj/string.h>\n\n#if defined(_WIN32) || defined(_WIN64)\n# include <winsock2.h>\n#else\n# include <arpa/inet.h>\n#endif\n\nZsrtpContext* zsrtp_CreateWrapper(uint32_t ssrc, int32_t roc,\n                                  int64_t  keyDerivRate,\n                                  const  int32_t ealg,\n                                  const  int32_t aalg,\n                                  uint8_t* masterKey,\n                                  int32_t  masterKeyLength,\n                                  uint8_t* masterSalt,\n                                  int32_t  masterSaltLength,\n                                  int32_t  ekeyl,\n                                  int32_t  akeyl,\n                                  int32_t  skeyl,\n                                  int32_t  tagLength)\n{\n    ZsrtpContext* zc = new ZsrtpContext;\n    zc->srtp = new CryptoContext(ssrc, roc, keyDerivRate, ealg, aalg,\n                                 masterKey, masterKeyLength, masterSalt,\n                                 masterSaltLength, ekeyl, akeyl, skeyl,\n                                 tagLength);\n    return zc;\n}\n\nvoid zsrtp_DestroyWrapper (ZsrtpContext* ctx)\n{\n\n    if (ctx == NULL)\n        return;\n\n    delete ctx->srtp;\n    ctx->srtp = NULL;\n\n    delete ctx;\n}\n\n/*\n * Private RTP decoding, copied from rtp.c. Need this because of\n * different padding handling for SRTP.\n */\n#define RTP_VERSION   2\nstatic pj_status_t zsrtp_decode_rtp(uint8_t* pkt, int32_t pkt_len,\n                                   const pjmedia_rtp_hdr **hdr,\n                                   uint8_t** payload,\n                                   int32_t *payloadlen)\n{\n    int offset;\n\n\n    /* Assume RTP header at the start of packet. We'll verify this later. */\n    *hdr = (pjmedia_rtp_hdr*)pkt;\n\n    /* Check RTP header sanity. */\n    if ((*hdr)->v != RTP_VERSION) {\n        return PJMEDIA_RTP_EINVER;\n    }\n\n    /* Payload is located right after header plus CSRC */\n    offset = sizeof(pjmedia_rtp_hdr) + ((*hdr)->cc * sizeof(pj_uint32_t));\n\n    /* Adjust offset if RTP extension is used. */\n    if ((*hdr)->x) {\n        pjmedia_rtp_ext_hdr *ext = (pjmedia_rtp_ext_hdr*)\n                                   (((pj_uint8_t*)pkt) + offset);\n        offset += ((pj_ntohs(ext->length)+1) * sizeof(pj_uint32_t));\n    }\n\n    /* Check that offset is less than packet size */\n    if (offset > pkt_len)\n        return PJMEDIA_RTP_EINLEN;\n\n    /* Find and set payload. */\n    *payload = pkt + offset;\n    *payloadlen = pkt_len - offset;\n\n    return PJ_SUCCESS;\n}\n\nint32_t zsrtp_protect(ZsrtpContext* ctx, uint8_t* buffer, int32_t length,\n                      int32_t* newLength)\n{\n    CryptoContext* pcc = ctx->srtp;\n    const pjmedia_rtp_hdr *hdr;\n    uint8_t* payload;\n    int32_t payloadlen;\n    uint16_t seqnum;\n    uint32_t ssrc;\n\n\n    if (pcc == NULL) {\n        return 0;\n    }\n    zsrtp_decode_rtp(buffer, length, &hdr, &payload, &payloadlen);\n\n    seqnum = hdr->seq;\n    seqnum = ntohs(seqnum);\n\n    /* Encrypt the packet */\n    uint64_t index = ((uint64_t)pcc->getRoc() << 16) | (uint64_t)seqnum;\n\n    ssrc = hdr->ssrc;\n    ssrc = ntohl(ssrc);\n    pcc->srtpEncrypt(buffer, payload, payloadlen, index, ssrc);\n\n    // NO MKI support yet - here we assume MKI is zero. To build in MKI\n    // take MKI length into account when storing the authentication tag.\n\n    /* Compute MAC and store at end of RTP packet data */\n    pcc->srtpAuthenticate(buffer, length, pcc->getRoc(), buffer+length);\n\n    *newLength = length + pcc->getTagLength();\n    \n    /* Update the ROC if necessary */\n    if (seqnum == 0xFFFF ) {\n        pcc->setRoc(pcc->getRoc() + 1);\n    }\n    return 1;\n}\n\nint32_t zsrtp_unprotect(ZsrtpContext* ctx, uint8_t* buffer, int32_t length,\n                        int32_t* newLength)\n{\n    CryptoContext* pcc = ctx->srtp;\n    const pjmedia_rtp_hdr *hdr;\n    uint8_t* payload;\n    int32_t payloadlen;\n    uint16_t seqnum;\n    uint32_t ssrc;\n\n    if (pcc == NULL) {\n        return 0;\n    }\n\n    zsrtp_decode_rtp(buffer, length, &hdr, &payload, &payloadlen);\n\n    /*\n     * This is the setting of the packet data when we come to this\n     * point:\n     *\n     * length:      complete length of received data\n     * buffer:      points to data as received from network\n     * hdrSize:     length of header including header extension\n     * payloadlen:  length of data excluding hdrSize and padding\n     *\n     * Because this is an SRTP packet we need to adjust some values here.\n     * The SRTP MKI and authentication data is always at the end of a\n     * packet. Thus compute the position of this data.\n     */\n\n    uint32_t srtpDataIndex = length - (pcc->getTagLength() + pcc->getMkiLength());\n\n    // now adjust length because some RTP functions rely on the fact that\n    // total is the full length of data without SRTP data.\n    length -= pcc->getTagLength() + pcc->getMkiLength();\n    *newLength = length;\n    \n    // recompute payloadlen by subtracting SRTP data\n    payloadlen -= pcc->getTagLength() + pcc->getMkiLength();\n\n    // unused??\n    // const uint8* mki = getRawPacket() + srtpDataIndex;\n    uint8_t* tag = buffer + srtpDataIndex + pcc->getMkiLength();\n\n    /* Replay control */\n    seqnum = hdr->seq;\n    seqnum = ntohs(seqnum);\n    if (!pcc->checkReplay(seqnum)) {\n        return -2;\n    }\n    /* Guess the index */\n    uint64_t guessedIndex = pcc->guessIndex(seqnum);\n\n    uint32_t guessedRoc = guessedIndex >> 16;\n    uint8_t* mac = new uint8_t[pcc->getTagLength()];\n\n    pcc->srtpAuthenticate(buffer, length, guessedRoc, mac);\n    if (pj_memcmp(tag, mac, pcc->getTagLength()) != 0) {\n        delete[] mac;\n        return -1;\n    }\n    delete[] mac;\n\n    /* Decrypt the content */\n    ssrc = hdr->ssrc;\n    ssrc = ntohl(ssrc);\n    pcc->srtpEncrypt(buffer, payload, payloadlen, guessedIndex, ssrc);\n\n    /* Update the Crypto-context */\n    pcc->update(seqnum);\n\n    return 1;\n}\n\nvoid zsrtp_newCryptoContextForSSRC(ZsrtpContext* ctx, uint32_t ssrc,\n                                   int32_t roc, int64_t keyDerivRate)\n{\n    CryptoContext* newCrypto = ctx->srtp->newCryptoContextForSSRC(ssrc, 0, 0L);\n    ctx->srtp = newCrypto;\n}\n\nvoid zsrtp_deriveSrtpKeys(ZsrtpContext* ctx, uint64_t index)\n{\n    ctx->srtp->deriveSrtpKeys(index);\n}\n\n\n/*\n * Implement the wrapper for SRTCP crypto context\n */\nZsrtpContextCtrl* zsrtp_CreateWrapperCtrl( uint32_t ssrc,\n                                           const  int32_t ealg,\n                                           const  int32_t aalg,\n                                           uint8_t* masterKey,\n                                           int32_t  masterKeyLength,\n                                           uint8_t* masterSalt,\n                                           int32_t  masterSaltLength,\n                                           int32_t  ekeyl,\n                                           int32_t  akeyl,\n                                           int32_t  skeyl,\n                                           int32_t  tagLength )\n{\n    ZsrtpContextCtrl* zc = new ZsrtpContextCtrl;\n    zc->srtcp = new CryptoContextCtrl(ssrc, ealg, aalg, masterKey, masterKeyLength, masterSalt,\n                                      masterSaltLength, ekeyl, akeyl, skeyl, tagLength );\n    \n    zc->srtcpIndex = 0;\n    return zc;\n}\n\n\nvoid zsrtp_DestroyWrapperCtrl (ZsrtpContextCtrl* ctx)\n{\n    if (ctx == NULL)\n        return;\n\n    delete ctx->srtcp;\n    ctx->srtcp = NULL;\n\n    delete ctx;\n}\n\nint32_t zsrtp_protectCtrl(ZsrtpContextCtrl* ctx, uint8_t* buffer, int32_t length,\n                      int32_t* newLength)\n{\n    CryptoContextCtrl* pcc = ctx->srtcp;\n\n    if (pcc == NULL) {\n        return 0;\n    }\n    /* Encrypt the packet */\n    uint32_t ssrc = *(reinterpret_cast<uint32_t*>(buffer + 4)); // always SSRC of sender\n    ssrc = ntohl(ssrc);\n\n    pcc->srtcpEncrypt(buffer + 8, length - 8, ctx->srtcpIndex, ssrc);\n\n    uint32_t encIndex = ctx->srtcpIndex | 0x80000000;  // set the E flag\n\n    // Fill SRTCP index as last word\n    uint32_t* ip = reinterpret_cast<uint32_t*>(buffer+length);\n    *ip = htonl(encIndex);   \n\n    // NO MKI support yet - here we assume MKI is zero. To build in MKI\n    // take MKI length into account when storing the authentication tag.\n\n    // Compute MAC and store in packet after the SRTCP index field\n    pcc->srtcpAuthenticate(buffer, length, encIndex, buffer + length + sizeof(uint32_t));\n\n    ctx->srtcpIndex++;\n    ctx->srtcpIndex &= ~0x80000000;       // clear possible overflow\n    *newLength = length + pcc->getTagLength() + sizeof(uint32_t);\n    \n    return 1;\n}\n\nint32_t zsrtp_unprotectCtrl(ZsrtpContextCtrl* ctx, uint8_t* buffer, int32_t length,\n                            int32_t* newLength)\n{\n    CryptoContextCtrl* pcc = ctx->srtcp;\n\n    if (pcc == NULL) {\n        return 0;\n    }\n\n    // Compute the total length of the payload\n    int32_t payloadLen = length - (pcc->getTagLength() + pcc->getMkiLength() + 4);\n    *newLength = payloadLen;\n    \n    // point to the SRTCP index field just after the real payload\n    const uint32_t* index = reinterpret_cast<uint32_t*>(buffer + payloadLen);\n\n    uint32_t encIndex = ntohl(*index);\n    uint32_t remoteIndex = encIndex & ~0x80000000;    // index without Encryption flag\n    \n    if (!pcc->checkReplay(remoteIndex)) {\n       return -2;\n    }\n    \n    uint8_t mac[20];\n\n    // Now get a pointer to the authentication tag field\n    const uint8_t* tag = buffer + (length - pcc->getTagLength());\n    \n    // Authenticate includes the index, but not MKI and not (obviously) the tag itself\n    pcc->srtcpAuthenticate(buffer, payloadLen, encIndex, mac);\n    if (memcmp(tag, mac, pcc->getTagLength()) != 0) {\n        return -1;\n    }\n\n    uint32_t ssrc = *(reinterpret_cast<uint32_t*>(buffer + 4)); // always SSRC of sender\n    ssrc = ntohl(ssrc);\n\n    // Decrypt the content, exclude the very first SRTCP header (fixed, 8 bytes)\n    if (encIndex & 0x80000000)\n        pcc->srtcpEncrypt(buffer + 8, payloadLen - 8, remoteIndex, ssrc);\n\n    // Update the Crypto-context\n    pcc->update(remoteIndex);\n\n    return 1;\n}\n\nvoid zsrtp_newCryptoContextForSSRCCtrl(ZsrtpContextCtrl* ctx, uint32_t ssrc)\n{\n    CryptoContextCtrl* newCrypto = ctx->srtcp->newCryptoContextForSSRC(ssrc);\n    ctx->srtcp = newCrypto;\n}\n\nvoid zsrtp_deriveSrtpKeysCtrl(ZsrtpContextCtrl* ctx)\n{\n    ctx->srtcp->deriveSrtcpKeys();\n}\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/COPYING",
    "content": "                   GNU LESSER GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n\n  This version of the GNU Lesser General Public License incorporates\nthe terms and conditions of version 3 of the GNU General Public\nLicense, supplemented by the additional permissions listed below.\n\n  0. Additional Definitions.\n\n  As used herein, \"this License\" refers to version 3 of the GNU Lesser\nGeneral Public License, and the \"GNU GPL\" refers to version 3 of the GNU\nGeneral Public License.\n\n  \"The Library\" refers to a covered work governed by this License,\nother than an Application or a Combined Work as defined below.\n\n  An \"Application\" is any work that makes use of an interface provided\nby the Library, but which is not otherwise based on the Library.\nDefining a subclass of a class defined by the Library is deemed a mode\nof using an interface provided by the Library.\n\n  A \"Combined Work\" is a work produced by combining or linking an\nApplication with the Library.  The particular version of the Library\nwith which the Combined Work was made is also called the \"Linked\nVersion\".\n\n  The \"Minimal Corresponding Source\" for a Combined Work means the\nCorresponding Source for the Combined Work, excluding any source code\nfor portions of the Combined Work that, considered in isolation, are\nbased on the Application, and not on the Linked Version.\n\n  The \"Corresponding Application Code\" for a Combined Work means the\nobject code and/or source code for the Application, including any data\nand utility programs needed for reproducing the Combined Work from the\nApplication, but excluding the System Libraries of the Combined Work.\n\n  1. Exception to Section 3 of the GNU GPL.\n\n  You may convey a covered work under sections 3 and 4 of this License\nwithout being bound by section 3 of the GNU GPL.\n\n  2. Conveying Modified Versions.\n\n  If you modify a copy of the Library, and, in your modifications, a\nfacility refers to a function or data to be supplied by an Application\nthat uses the facility (other than as an argument passed when the\nfacility is invoked), then you may convey a copy of the modified\nversion:\n\n   a) under this License, provided that you make a good faith effort to\n   ensure that, in the event an Application does not supply the\n   function or data, the facility still operates, and performs\n   whatever part of its purpose remains meaningful, or\n\n   b) under the GNU GPL, with none of the additional permissions of\n   this License applicable to that copy.\n\n  3. Object Code Incorporating Material from Library Header Files.\n\n  The object code form of an Application may incorporate material from\na header file that is part of the Library.  You may convey such object\ncode under terms of your choice, provided that, if the incorporated\nmaterial is not limited to numerical parameters, data structure\nlayouts and accessors, or small macros, inline functions and templates\n(ten or fewer lines in length), you do both of the following:\n\n   a) Give prominent notice with each copy of the object code that the\n   Library is used in it and that the Library and its use are\n   covered by this License.\n\n   b) Accompany the object code with a copy of the GNU GPL and this license\n   document.\n\n  4. Combined Works.\n\n  You may convey a Combined Work under terms of your choice that,\ntaken together, effectively do not restrict modification of the\nportions of the Library contained in the Combined Work and reverse\nengineering for debugging such modifications, if you also do each of\nthe following:\n\n   a) Give prominent notice with each copy of the Combined Work that\n   the Library is used in it and that the Library and its use are\n   covered by this License.\n\n   b) Accompany the Combined Work with a copy of the GNU GPL and this license\n   document.\n\n   c) For a Combined Work that displays copyright notices during\n   execution, include the copyright notice for the Library among\n   these notices, as well as a reference directing the user to the\n   copies of the GNU GPL and this license document.\n\n   d) Do one of the following:\n\n       0) Convey the Minimal Corresponding Source under the terms of this\n       License, and the Corresponding Application Code in a form\n       suitable for, and under terms that permit, the user to\n       recombine or relink the Application with a modified version of\n       the Linked Version to produce a modified Combined Work, in the\n       manner specified by section 6 of the GNU GPL for conveying\n       Corresponding Source.\n\n       1) Use a suitable shared library mechanism for linking with the\n       Library.  A suitable mechanism is one that (a) uses at run time\n       a copy of the Library already present on the user's computer\n       system, and (b) will operate properly with a modified version\n       of the Library that is interface-compatible with the Linked\n       Version.\n\n   e) Provide Installation Information, but only if you would otherwise\n   be required to provide such information under section 6 of the\n   GNU GPL, and only to the extent that such information is\n   necessary to install and execute a modified version of the\n   Combined Work produced by recombining or relinking the\n   Application with a modified version of the Linked Version. (If\n   you use option 4d0, the Installation Information must accompany\n   the Minimal Corresponding Source and Corresponding Application\n   Code. If you use option 4d1, you must provide the Installation\n   Information in the manner specified by section 6 of the GNU GPL\n   for conveying Corresponding Source.)\n\n  5. Combined Libraries.\n\n  You may place library facilities that are a work based on the\nLibrary side by side in a single library together with other library\nfacilities that are not Applications and are not covered by this\nLicense, and convey such a combined library under terms of your\nchoice, if you do both of the following:\n\n   a) Accompany the combined library with a copy of the same work based\n   on the Library, uncombined with any other library facilities,\n   conveyed under the terms of this License.\n\n   b) Give prominent notice with the combined library that part of it\n   is a work based on the Library, and explaining where to find the\n   accompanying uncombined form of the same work.\n\n  6. Revised Versions of the GNU Lesser General Public License.\n\n  The Free Software Foundation may publish revised and/or new versions\nof the GNU Lesser General Public License from time to time. Such new\nversions will be similar in spirit to the present version, but may\ndiffer in detail to address new problems or concerns.\n\n  Each version is given a distinguishing version number. If the\nLibrary as you received it specifies that a certain numbered version\nof the GNU Lesser General Public License \"or any later version\"\napplies to it, you have the option of following the terms and\nconditions either of that published version or of any later version\npublished by the Free Software Foundation. If the Library as you\nreceived it does not specify a version number of the GNU Lesser\nGeneral Public License, you may choose any version of the GNU Lesser\nGeneral Public License ever published by the Free Software Foundation.\n\n  If the Library as you received it specifies that a proxy can decide\nwhether future versions of the GNU Lesser General Public License shall\napply, that proxy's public statement of acceptance of any version is\npermanent authorization for you to choose that version for the\nLibrary."
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/README.md",
    "content": "## GNU ZRTP C++\n\nThis package provides a library that adds ZRTP support to the GNU\nccRTP stack and serves as library for other RTP stacks (PJSIP, GStreamer).\nPhil Zimmermann developed ZRTP to allow ad-hoc, easy to\nuse key negotiation to setup Secure RTP (SRTP) sessions. GNU ZRTP works\ntogether with GNU ccRTP (1.5.0 or later) and provides a ZRTP\nimplementation that can be directly embedded into client and server\napplications.\n\nThe GNU ZRTP implementation is compliant to [RFC 6189][] and adds some more\nalgorithms. Currently GNU ZRTP C++ supports the following features:\n\n* multi-stream mode\n* Finite field Diffie-Hellman with 2048 and 3072 bit primes\n* Elliptic curve Diffie-Hellman with 256 and 384 bit curves (NIST curves)\n* Elliptic curves Curve25519 and Curve3617 (Dan Bernstein, Tanja Lange)\n* Skein Hash and MAC for ZRTP\n* AES-128 and AES-256 symmetric ciphers\n* Twofish-128 and Twofish-256 bit symmetric ciphers\n* The SRTP authentication methods HMAC-SHA1 with 32 bit and 80 bit length and\n  the Skein MAC with 32 bit and 64 bit length\n* The Short Authentication String (SAS) type with base 32 encoding (4\n  characters) and the SAS 256 type using words.\n\nSome features like preshared mode are not supported but the GNU\nZRTP C++ implementation defines the necessary external interfaces and\nfunctions for these enhanced features.\n\n**Note:** The Elliptic curves Cure25519 and Curve3617 are available only if you\nselect the crypto standalone mode during build.\n\nThe newer verisons (starting with 4.1) implement an extensible mechanisms to\ndefine algorithm selection policies that control selection of Hash, symmetric\ncipher, and the SRTP authentication. Currently two policies exist: _Standard_\nand _PreferNonNist_. The Standard policy selects algorihms based on the\npreferences (order) in the Hello packet, the PreferNonNist policy prefers \nnon-NIST algorithms, for example Skein and Twofish, if the selected public key\n(Diffie-Hellman) algorithm is also one of the non-NIST algorithms. This is \nfully backward compatible and in-line with RFC6189.\n\n### SDES support\nThis release also provides SDES support. The SDES implementation does not\nsupport all of the fancy stuff but is usable in most cases. This implementation\nhowever supports the new SDES crypto mixing to overcome some security issues\nfor SIP forking. Please look for `draft-zimmermann-mmusic-sdesc-mix-00`.\n\n### Interoperability\nDuring the development of ZRTP and its sister implementation ZRTP4J (the Java\nversion of the ZRTP) Phil Zimmermann, his developers, and I worked together to\nmake sure Phil's [Zfone][] implementation and the GNU ZRTP implementations can\nwork together.\n\n[zfone]: http://zfoneproject.com/index.html\n\n\n### Other implementations based on GNU ZRTP C++ \n\nThe ZRTP4J implementation is a copycat of the original C++ code. I used the\nsame overall class structure and copied a lot of C++ functionality to Java. Of\ncourse some Java adaptation were done, for example to overcome the problem of\nnon-existing pointers :-), thus I use some non-obvious array handling. If you\nare interessted in the Java implementation of ZRTP then you may have a look\n[here][javazrtp]. The Jitsi project uses the Java implementation. Jitsi is a\npowerfull communication client and is definitely worth a [look][jitsi].\n\nTo enable C based code to use ZRTP C++ I did a C wrapper that offers the same\nfunctionality to C based RTP implementations. The first use of the ZRTP C\nwrapper was for the [PJSIP][] library, actually the RTP part of this\nlibrary. The ZRTP handler for PJSIP is [here][pjzrtp]. This port enables PJSIP\nbased clients to use ZRTP. One of the first clients that uses this feature is\n*[CSipSimple][]*, an very good open source Android SIP client.\n\n[pjsip]: http://www.pjsip.org\n[pjzrtp]: https://github.com/wernerd/ZRTP4PJ\n[javazrtp]: https://github.com/wernerd/ZRTP4J\n[jitsi]: http://www.jitsi.org\n[csipsimple]: http://code.google.com/p/csipsimple\n\n\n### Some notes on GNU ZRTP C++ history\nThe first application that demonstrated the embedded ZRTP was Minisp (now\ndefunct). Minisip has it's own RTP stack and the very first version of this\nembedded ZRTP implementation worked together with this specific RTP stack. \n\nA few weeks later I implemented the GNU ccRTP glue code and ZRTP became part\nof the official GNU ccRTP project and was named GNU ZRTP C++. The Twinkle\nsoftphone uses GNU ccRTP and GNU ZRTP C++ since it's 0.8.2 release and Michel\nde Boer, the implementor of Twinkle, created a nice user interface. All\nfollowing versions of Twinkle include GNU ZRTP C++ as well.\n\n\n### License and further information\nI changed the license of the ZRTP core source files from GPL to LGPL. Other\nsources files may have own license. Please refer to the copyright notices of\nthe files.\n\nThus most of this library is licensed under the GNU LGPL, version 3 or later.\n\nFor further information refer to the [ZRTP FAQ][zrtpfaq] and the\n[GNU ZRTP howto][zrtphow]. Both are part of the GNU Telephony wiki and are\nlocated in its documentation category.\n\nSource code in the directory `clients/tivi` and below is not licensed under the\nGNU LGPL and is for reference and review only. Refer to the copyright statments\nof the source code in these directories, in particular the sqlite3 sources which\nhave their own license.\n\n[zrtphow]:  http://www.gnutelephony.org/index.php/GNU_ZRTP_How_To\n[zrtpfaq]:  http://www.gnutelephony.org/index.php/ZRTP_FAQ\n[rfc 6189]: http://tools.ietf.org/html/rfc6189\n\n## Building GNU ZRTP C++ \nSince version 1.6 GNU ZRTP C++ supports the *cmake* based build process\nonly. The cmake build process is simpler than the GNU automake/autoconf\nprocess. To build GNU ZRTP C++ perform the following steps after you unpacked\nthe source archive or pulled the source from [Github][]:\n\n    cd <zrtpsrc_dir>\n    mkdir build\n    cd build\n    cmake ..\n    make\n\nThe CMakeLists.txt supports several options. If you don't specify any options\nthen `cmake` generates the build that supports GNU ccRTP library and it uses\nthe standalone cryptographic modules, thus no it's not necessary to install an\ncryptographic library on the system. Optionally you may configure ZRTP to use\n_sqlite3_ instead of a simple file to store the ZRTP cache data. For example\n\n    cmake -DSQLITE=true ..\n\ncreates the build files that use _sqlite3_.\n\nPlease have a look at the `CMakeLists.txt` for other options.\n\nRunning cmake in a separate `build` directory is the preferred way. Cmake and\nthe following `make` generate all files in or below the build directory. Thus\nthe base directory and the source directories are not polluted with `*.o`,\n`*.la`, or other files that result from the build process. You may delete the\nbuild directory and create a new one to start from fresh (this is the ultimate\n`make clean` :-) ) or you may create a second directory to build with\ndifferent settings without mixing the two builds.\n\n[github]: http://github.com/wernerd/ZRTPCPP\n\n\n### Notes when building ZRTP C++ for Android\n\nThe CMake files support creation of an `Android.mk` file for the Tivi client\nand may give you an idea how to do it for other clients. The generated\n`Android.mk` generates `buildinfo_*.c` files in the root directory. You may\ndelete these files after the Android static libraries are ready.\n\nSince version 4.1.1 the example Android build files require NDK r9c.\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/base_version",
    "content": "4.4.0-dev\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/common/EventClass.cpp",
    "content": "//\n// EventClass.cpp: implementation file\n//\n// Copyright (C) Walter E. Capers.  All rights reserved\n//\n// This source is free to use as you like.  If you make\n// any changes please keep me in the loop.  Email them to\n// walt.capers@comcast.net.\n//\n// PURPOSE:\n//\n//  To implement event signals as a C++ object\n//\n// REVISIONS\n// =======================================================\n// Date: 10.25.07        \n// Name: Walter E. Capers\n// Description: File creation\n//\n// Date: 11/02/07\n// Name: Walter E. Capers\n// Description: removed unnessary code identified by On Freund from Code Project\n//\n//\n#include \"Thread.h\"\n\n#ifndef WINDOWS\n#include <sys/time.h>\n#endif\n\n#include <iostream>\nusing namespace std;\n\nCEventClass::CEventClass(void)\n:m_bCreated(TRUE)\n{\n\tmemset(&m_owner,0,sizeof(ThreadId_t));\n#ifdef WINDOWS\n\tm_event = CreateEvent(NULL,FALSE,FALSE,NULL);\n\tif( !m_event )\n\t{\n\t\tm_bCreated = FALSE;\n\t}\n#else\n\tpthread_mutexattr_t mattr;\n\t\n\tpthread_mutexattr_init(&mattr);\n\tpthread_mutex_init(&m_lock,&mattr);\n\tpthread_cond_init(&m_ready,NULL);\n\n#endif\t\n}\n\nCEventClass::~CEventClass(void)\n{\n#ifdef WINDOWS\n\tCloseHandle(m_event);\n#else\n\tpthread_cond_destroy(&m_ready);\n\tpthread_mutex_destroy(&m_lock);\n#endif\n}\n\n\n/**\n *\n * Set\n * set an event to signaled\n *\n **/\nvoid\nCEventClass::Set()\n{\n#ifdef WINDOWS\n\tSetEvent(m_event);\n#else\n\tpthread_cond_signal(&m_ready);\n#endif\n}\n\n/**\n *\n * Wait\n * wait for an event -- wait for an event object\n * to be set to signaled.  must be paired with a\n * call to reset within the same thread.\n *\n **/\nBOOL\nCEventClass::Wait(DWORD tmout)\n{\n\n\ttry\n\t{\n\t\tThreadId_t id = CThread::ThreadId();\n\t\tif( CThread::ThreadIdsEqual(&id,&m_owner) )\n\t\t{\n\t\t\tthrow \"\\n\\tinvalid Wait call, Wait can not be called more than once\"\n\t\t\t\t\"\\n\\twithout a corresponding call to Reset!\\n\";\n\t\t}\n\t\tThreadId_t zero;\n\t\tmemset(&zero,0,sizeof(ThreadId_t));\n\n\t\tif( memcmp(&zero,&m_owner,sizeof(ThreadId_t)) != 0 )\n\t\t{\n\t\t\tthrow \"\\n\\tanother thread is already waiting on this event!\\n\";\n\t\t}\n\n\t\tm_owner = CThread::ThreadId();\n#ifdef WINDOWS\n        tmout = tmout == 0 ? INFINITE : tmout;\n        DWORD rc = WaitForSingleObject(m_event, tmout);\n        e_timeout = FALSE;\n        if (rc ==  WAIT_OBJECT_0) {\n            return TRUE;\n        }\n        else if (rc == WAIT_TIMEOUT) {\n            e_timeout = TRUE;\n            return TRUE;\n        }\n        else\n            return FALSE;\n#else\n\t\tpthread_mutex_lock(&m_lock);\n        e_timeout = FALSE;\n        if (tmout == 0) {\n            pthread_cond_wait(&m_ready,&m_lock);\n            return TRUE;\n        }\n        struct timespec ts;\n        timeval tv;\n        gettimeofday(&tv, NULL);\n        ts.tv_sec = tv.tv_sec;\n        ts.tv_nsec = tv.tv_usec * 1000l;\n        ts.tv_sec += tmout / 1000;\n        ts.tv_nsec += (tmout % 1000) * 1000000l;\n        while(ts.tv_nsec > 1000000000l) {\n            ++ts.tv_sec;\n            ts.tv_nsec -= 1000000000l;\n        }\n        int rc = pthread_cond_timedwait(&m_ready, &m_lock, &ts);\n        if (rc == ETIMEDOUT)\n            e_timeout = TRUE;\n        return TRUE;\n#endif\n\t}\n\tcatch( char *psz )\n\t{\n#ifdef WINDOWS\n\t\tMessageBoxA(NULL,&psz[2],\"Fatal exception CEventClass::Wait\",MB_ICONHAND);\n\t\texit(-1);\n#else\n\t\tcerr << \"Fatal exception CEventClass::Wait: \" << psz;\n#endif\n\n\t}\n\treturn TRUE;\n}\n\n\n/**\n *\n * Reset\n * reset an event flag to unsignaled\n * wait must be paired with reset within the same thread.\n *\n **/\nvoid\nCEventClass::Reset()\n{\n\ttry \n\t{\n\t\tThreadId_t id = CThread::ThreadId();\n\t\tif( !CThread::ThreadIdsEqual(&id,&m_owner) )\n\t\t{\n\t\t\tthrow \"\\n\\tunbalanced call to Reset, Reset must be called from\\n\"\n\t\t\t\t  \"\\n\\tthe same Wait-Reset pair!\\n\";\n\t\t}\n\n\t\tmemset(&m_owner,0,sizeof(ThreadId_t));\n\n#ifndef WINDOWS\n\t\tpthread_mutex_unlock(&m_lock);\n#endif\n\t}\n\tcatch( char *psz )\n\t{\n#ifdef WINDOWS\n\t\tMessageBoxA(NULL,&psz[2],\"Fatal exception CEventClass::Reset\",MB_ICONHAND);\n\t\texit(-1);\n#else\n\t\tcerr << \"Fatal exception CEventClass::Reset: \" << psz;\n#endif\n\n\t}\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/common/EventClass.h",
    "content": "//\n// EventClass.h: header file\n//\n// Copyright (C) Walter E. Capers.  All rights reserved\n//\n// This source is free to use as you like.  If you make\n// any changes please keep me in the loop.  Email them to\n// walt.capers@comcast.net.\n//\n// PURPOSE:\n//\n//  To implement event signals as a C++ object\n//\n// REVISIONS\n// =======================================================\n// Date: 10.25.07        \n// Name: Walter E. Capers\n// Description: File creation\n//\n// Date:\n// Name:\n// Description:\n//\n//\n#ifndef EVENT_CLASS\n#define EVENT_CLASS\n\nclass CEventClass\n{\nprivate:\n\tThreadId_t m_owner;\n#ifdef WINDOWS\n\tHANDLE m_event;\n#else\n\tpthread_cond_t m_ready;\n\tpthread_mutex_t m_lock;\n#endif\npublic:\n    BOOL e_timeout;\n\tBOOL m_bCreated;\n\tvoid Set();\n\tBOOL Wait(DWORD tmout =0);\n\tvoid Reset();\n\tCEventClass(void);\n\t~CEventClass(void);\n};\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/common/MutexClass.cpp",
    "content": "//\n// MutexClass.cpp: implementation file\n//\n// Copyright (C) Walter E. Capers.  All rights reserved\n//\n// This source is free to use as you like.  If you make\n// any changes please keep me in the loop.  Email them to\n// walt.capers@comcast.net.\n//\n// PURPOSE:\n//\n//  To implement mutexes as a C++ object\n//\n// REVISIONS\n// =======================================================\n// Date: 10.25.07        \n// Name: Walter E. Capers\n// Description: File creation\n//\n// Date:\n// Name:\n// Description:\n//\n//\n#include \"Thread.h\"\n\n#include <iostream>\nusing namespace std;\n\nCMutexClass::CMutexClass(void)\n:m_bCreated(TRUE)\n{\n#ifdef WINDOWS\n   m_mutex = CreateMutex(NULL,FALSE,NULL);\n   if( !m_mutex ) m_bCreated = FALSE;\n#else\n   pthread_mutexattr_t mattr;\n\n   pthread_mutexattr_init( &mattr );\n   pthread_mutex_init(&m_mutex,&mattr);\n\n#endif\n   memset(&m_owner,0,sizeof(ThreadId_t));\n\n}\n\nCMutexClass::~CMutexClass(void)\n{\n#ifdef WINDOWS\n\tWaitForSingleObject(m_mutex,INFINITE);\n\tCloseHandle(m_mutex);\n#else\n\tpthread_mutex_lock(&m_mutex);\n\tpthread_mutex_unlock(&m_mutex); \n\tpthread_mutex_destroy(&m_mutex);\n#endif\n}\n\n/**\n *\n * Lock\n * the same thread can not lock the same mutex\n * more than once\n *\n **/\nvoid\nCMutexClass::Lock()\n{\n\tThreadId_t id = CThread::ThreadId();\n\ttry {\n\t\tif(CThread::ThreadIdsEqual(&m_owner,&id) )\n\t\t    throw \"\\n\\tthe same thread can not acquire a mutex twice!\\n\"; // the mutex is already locked by this thread\n#ifdef WINDOWS\n\t\tWaitForSingleObject(m_mutex,INFINITE);\n#else\n\t\tpthread_mutex_lock(&m_mutex);\n#endif\n\t\tm_owner = CThread::ThreadId();\n\t}\n\tcatch( char *psz )\n\t{\n#ifdef WINDOWS\n\t\tMessageBoxA(NULL,&psz[2],\"Fatal exception CMutexClass::Lock\",MB_ICONHAND);\n\t\texit(-1);\n#else\n\t\tcerr << \"Fatal exception CMutexClass::Lock : \" << psz;\n#endif\n\n\n\t}\n\n}\n\n/**\n *\n * Unlock\n * releases a mutex.  only the thread that acquires\n * the mutex can release it.\n *\n **/\nvoid \nCMutexClass::Unlock()\n{\n\tThreadId_t id = CThread::ThreadId();\n\ttry \n\t{\n\t  if( ! CThread::ThreadIdsEqual(&id,&m_owner) )\n\t\tthrow \"\\n\\tonly the thread that acquires a mutex can release it!\"; \n\n\t   memset(&m_owner,0,sizeof(ThreadId_t));\n#ifdef WINDOWS\n\t   ReleaseMutex(m_mutex);\n#else\n\t   pthread_mutex_unlock(&m_mutex);\n#endif\n\t}\n\tcatch ( char *psz)\n\t{\n#ifdef WINDOWS\n\t\tMessageBoxA(NULL,&psz[2],\"Fatal exception CMutexClass::Unlock\",MB_ICONHAND);\n\t\texit(-1);\n#else\n\t\tcerr << \"Fatal exception CMutexClass::Unlock : \" << psz;\n#endif\n\n\t}\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/common/MutexClass.h",
    "content": "//\n// MutexClass.h: header file\n//\n// Copyright (C) Walter E. Capers.  All rights reserved\n//\n// This source is free to use as you like.  If you make\n// any changes please keep me in the loop.  Email them to\n// walt.capers@comcast.net.\n//\n// PURPOSE:\n//\n//  To implement mutexes as a C++ object\n//\n// REVISIONS\n// =======================================================\n// Date: 10.25.07        \n// Name: Walter E. Capers\n// Description: File creation\n//\n// Date:\n// Name:\n// Description:\n//\n//\n\n#ifndef MUTEX_CLASS\n#define MUTEX_CLASS\n\n#ifndef WINDOWS\n#if defined(WIN32) || defined(WIN64)\n#define WINDOWS\n#endif\n#endif\n\n#ifndef WINDOWS\n#include <pthread.h>\n#endif\n#include <common/Thread.h>\n\nclass CMutexClass\n{\nprivate:\n#ifdef WINDOWS\n\tHANDLE m_mutex;\n#else\n\tpthread_mutex_t m_mutex;\n#endif\n\tThreadId_t m_owner;\npublic:\n\tBOOL m_bCreated;\n\tvoid Lock();\n\tvoid Unlock();\n\tCMutexClass(void);\n\t~CMutexClass(void);\n};\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/common/Thread.cpp",
    "content": "//\n// Thread.cpp: implementation file\n//\n// Copyright (C) Walter E. Capers.  All rights reserved\n//\n// This source is free to use as you like.  If you make\n// any changes please keep me in the loop.  Email your changes\n// to walt.capers@comcast.net.\n//\n// PURPOSE:\n//\n//  To implement threading as a C++ object\n//\n// NOTES:\n//  This object supports two types of thread models, event driven and\n//  interval driven.  Under the event driven model, a thread waits\n//  in a paused state until the member function Event is called.  When\n//  the Event function is called the thread wakes up and calls OnTask.\n//  Under the interval driven model, the thread wakes up every\n//  m_dwIdle milli-seconds and calls OnTask.\n//\n//  You can switch between the two models from within the same object.\n//\n// COMPILER NOTES:\n// On Unix you must use -lpthread a -lrt\n// On Windows you must specify threaded under C++ code generation\n//\n// REVISIONS\n// =======================================================\n// Date: 10.24.07        \n// Name: Walter E. Capers\n// Description: File creation\n//\n// Date: 10.24.07 11:49 am\n// Name: Walter E. Capers\n// Description: Added SetIdle function to allow the idle time to be altered\n//              independent of the SetThreadType member function.\n//              Added sleep interval to Stop function.\n//\n// Date: 10.25.07\n// Name: Walter E. Capers\n// Description: Added support for other non-windows platforms.\n//\n//              Added static functions: ThreadIdsEqual and ThreadId.\n//\n//              Added que for handling multiple events.\n//\n//              Created the CEventClass and CMutexClass classes to facilitate\n//              platform independence.\n//\n// Date: 10.26.07\n// Name: Walter E. Capers\n// Description: Made object production ready...\n//              Added more comments\n//\n//              Addressed various issues with threads on UNIX systems.\n//                -- there was a defect in the Sleep function\n//                -- there was a defect in the main thread function THKERNEL\n//                   , when transitioning between thread models the CEvent::Reset\n//                   function was not being called when it was necessary resulting\n//                   in a lock up.\n//              \n//\t\t\t\t Transition between thread types also failed on WINDOWS since the Event\n//               member function was being called from within SetThreadType.  This\n//               resulted in an Event usage error.  To correct the problem m_event.Set\n//               is called instead.  Also, eliminated unecessary logic.\n//\n//               Got rid of OnStart, OnStop, OnDestroy... Could not override with a derived\n//\t\t\t\t class, not sure why I will come back to in a later release.\n//\n//\t\t\t\t Changed default behavior of thread.  If OnTask is not redefined in the derived\n//               class the default version now expects a CTask object.  The Class for CTask \n//               is defined in thread.h.  A class must be derived from CTask to use it in\n//               the default version of OnTask(LPVOID).\n//\n// Date: 11.01.07\n// Name: Walter E. Capers\n// Description: I introduced more logic and ASSERTIONS to insure the integrity of CThread objects.  \n//              Both the Homogeneous and Specialized thread types can be physically set using the \n//              SetThreadType member function.  If the thread type is not set, the thread will\n//              determine its type based on calls to member functions; however, this does not\n//              apply to interval-based threads.  Interval-based threads must be implicitly\n//              identified using the SetThreadType member function.  The new integrity tests\n//              are implemented to insure usage consistency with a CThread object.   \n//\n//              New member functions AtCapacity and PercentCapacity were added to determine\n//              if a thread is truly busy.  AtCapacity will return TRUE under one of two \n//              conditions: the thread is processing an event and its stack is full, the thread\n//              is not running.  These new functions allow thread objects to be placed in arrays\n//              and tasked based on their workloads.\n//\n//              The Event member function has been modified to verify that a thread is running\n//              before posting an event.  This resolved a problem on SunOS were threads did not\n//              start right away; there was a small delay of a few milliseconds.    \n//\n//              Error flags are automatically reset when certain member functions are called this\n//              isolates error occurrences to specific call sequences.\n//\n//\n// Date: 11.01.07\n// Name: Walter E. Capers\n// Description: In THKernel, changed how events are released.  Events are now released right after\n//              They are recieved.\n\n#include \"Thread.h\"\n#ifdef USE_BEGIN_THREAD\n#include <process.h>\n#endif\n\n\n\n#ifndef WINDOWS\n\n#include <unistd.h>\n#include <pthread.h>\n\nextern \"C\"\n{\n //int\tusleep(useconds_t useconds);\n#ifdef NANO_SECOND_SLEEP\n int \tnanosleep(const struct timespec *rqtp, struct timespec *rmtp);\n#endif\n}\n\nvoid Sleep( unsigned int milli )\n{\n#ifdef NANO_SECOND_SLEEP\n\tstruct timespec interval, remainder;\n\tmilli = milli * 1000000;\n\tinterval.tv_sec= 0;\n\tinterval.tv_nsec=milli;\n\tnanosleep(&interval,&remainder);\n#else\n\tusleep(milli*1000);\n#endif\t\n}\n#endif\n\n#include <iostream>\nusing namespace std;\n\n/**\n * \n * _THKERNEL\n * thread callback function used by CreateThread\n *\n *\n **/\n#ifdef WINDOWS\n#ifdef USE_BEGIN_THREAD\nunsigned __stdcall\n#else\nDWORD WINAPI\n#endif\n#else\nLPVOID\n#endif\n_THKERNEL( LPVOID lpvData /* CThread Object */ \n\t\t  )\n{\n\tCThread *pThread = (CThread *)lpvData;\n\tThreadType_t lastType;\n\t/*\n\t *\n\t * initialization\n\t *\n\t */\n\n\n    pThread->m_mutex.Lock();\n\t\tpThread->m_state = ThreadStateWaiting;\n\t\tpThread->m_bRunning = TRUE;\n#ifndef WINDOWS\n\t\tpThread->m_dwId = CThread::ThreadId();\n#endif\n\tpThread->m_mutex.Unlock();\n\t\n\twhile( TRUE )\n\t{\n\t\tlastType = pThread->m_type;\n\n\t\tif( lastType == ThreadTypeHomogeneous ||\n\t\t\tlastType == ThreadTypeSpecialized ||\n\t\t\tlastType == ThreadTypeNotDefined )\n\t\t{\n\t\t\tif( ! pThread->m_event.Wait()  )  // wait for a message\n\t\t\t\t\tbreak;\n\t\t\tpThread->m_event.Reset(); // message recieved\n\t\t}\n\t\n\t\tif( ! pThread->KernelProcess() ) \n\t\t\t\tbreak;\n\n\n\t\t/*if( lastType == ThreadTypeHomogeneous ||\n\t\t\tlastType == ThreadTypeSpecialized ||\n\t\t\tlastType == ThreadTypeNotDefined )\n\t\t{\n\t\t\tpThread->m_event.Reset();\n\t\t} */\n\n\t\tif( pThread->m_type == ThreadTypeIntervalDriven )\n\t\t\tSleep(pThread->m_dwIdle);\n\n\t}\n\n\n\tpThread->m_mutex.Lock();\n\t\tpThread->m_state = ThreadStateDown;\n\t\tpThread->m_bRunning = FALSE;\n\tpThread->m_mutex.Unlock();\n\n\n#ifdef WINDOWS\n\treturn 0;\n#else\n\treturn (LPVOID)0;\n#endif\n}\n\n/**\n *\n * FromSameThread\n * determines if the calling thread is the same\n * as the thread assoicated with the object\n *\n **/\nBOOL\nCThread::FromSameThread()\n{\n\tThreadId_t id = ThreadId();\n\tif( ThreadIdsEqual(&id,&m_dwId) ) return TRUE;\n\treturn FALSE;\n}\n\n/**\n *\n * OnTask\n * called when a thread is tasked using the Event\n * member function\n *\n **/\nBOOL \nCThread::OnTask( LPVOID lpvData /*data passed from thread*/ \n\t\t\t\t\t   )\n{\n    ASSERT(lpvData && m_type == ThreadTypeHomogeneous);\n\n\tif( m_type != ThreadTypeHomogeneous )\n\t{\n\t\tcerr << \"Warning CThread::OnTask:\\n\\tOnTask(LPVOID) called for a non-homogeneous thread!\\n\";\n\t\treturn FALSE;\n\t}\n\n\t((CTask *)lpvData)->SetTaskStatus(TaskStatusBeingProcessed);\n\tBOOL bReturn = ((CTask *)lpvData)->Task();\n\t((CTask *)lpvData)->SetTaskStatus(TaskStatusCompleted);\n\n\treturn bReturn; \n} \n\n\n\n/**\n *\n * OnTask\n * overloaded implementation of OnTask that\n * takes no arguments\n *\n **/\nBOOL\nCThread::OnTask()\n{\n\tASSERT(m_type == ThreadTypeIntervalDriven);\n\tif( m_type != ThreadTypeIntervalDriven )\n\t{\n\t\tcerr << \"Warning CThread::OnTask:\\n\\tOnTask() called for a non-event driven thread!\\n\";\n\t\treturn FALSE;\n\t}\n\n\tprintf(\"\\nthread is alive\\n\");\n\n\treturn TRUE;\n}\n\n/**\n *\n * CEvent\n * used to place tasks on the threads event queue\n * wakes up thread.\n *\n **/\nBOOL\nCThread::Event(CTask *pvTask /* data to be processed by thread */\n\t\t\t   )\n{\n\tm_mutex.Lock();\n\n\tASSERT(m_type == ThreadTypeHomogeneous ||\n\t       m_type == ThreadTypeNotDefined );\n\n\ttry \n\t{\n\t\tif( FromSameThread() )\n\t\t{\n\t\t\tthrow \"\\n\\tit is illegal for a thread to place an event on its own event stack!\\n\";\n\t\t}\n\n\n\t\t// make sure that the thread is running \n\t\tif( !m_bRunning && m_dwObjectCondition == NO_ERRORS )\n\t\t{\n\t\t\tm_mutex.Unlock();\n\t\t\tPingThread(m_dwIdle*2); // wait two idle cycles for it to start\n\t\t\tm_mutex.Lock();\n\t\t}\n\t\tif( !m_bRunning ) // if it is not running return FALSE;\n\t\t{\n\t\t\tm_mutex.Unlock();\n\t\t\treturn FALSE;\n\t\t}\n\n\n\t\tif( m_dwObjectCondition & ILLEGAL_USE_OF_EVENT )\n\t\t\tm_dwObjectCondition = m_dwObjectCondition ^ ILLEGAL_USE_OF_EVENT;\n\t\tif( m_dwObjectCondition & EVENT_AND_TYPE_DONT_MATCH)\n\t\t\tm_dwObjectCondition = m_dwObjectCondition ^ EVENT_AND_TYPE_DONT_MATCH;\n\n\t\tif( m_type != ThreadTypeHomogeneous &&\n\t\t\tm_type != ThreadTypeNotDefined    )\n\t\t{\n\t\t\tm_mutex.Unlock();\n\t\t\tm_dwObjectCondition |= ILLEGAL_USE_OF_EVENT;\n\t\t\tm_dwObjectCondition |= EVENT_AND_TYPE_DONT_MATCH;\n\t\t\tm_state = ThreadStateFault;\n\t\t\tcerr << \"Warning: invalid call to CEvent::Event(CTask *), thread type is not specialized\\n\";\n\n\t\t\treturn FALSE;\n\t\t}\n\n\t\tm_type = ThreadTypeHomogeneous;\n\t\tm_mutex.Unlock();\n\n\t\tpvTask->SetId(&m_dwId);\n\t\tif( ! Push((LPVOID)pvTask) )\n\t\t\treturn FALSE;\n\n\t\tpvTask->SetTaskStatus(TaskStatusWaitingOnQueue);\n\t\tm_event.Set();\n\n\t}\n\tcatch (char *psz)\n\t{\n#ifdef WINDOWS\n\t\tMessageBoxA(NULL,&psz[2],\"Fatal exception CThread::CEvent\",MB_ICONHAND);\n\t\texit(-1);\n#else\n\t\tcerr << \"Fatal exception CThread::CEvent(CTask *pvTask):\" << psz;\n#endif\n\n\t}\n\treturn TRUE;\n}\n\n/**\n *\n * Event\n * used to place tasks on the threads event queue\n * wakes up thread.\n *\n **/\nBOOL\nCThread::Event(LPVOID lpvData /* data to be processed by thread */\n\t\t\t   )\n{\n\n\tm_mutex.Lock();\n\tASSERT( m_type == ThreadTypeSpecialized ||\n\t\t    m_type == ThreadTypeNotDefined );\n\ttry \n\t{\n\t\tif( FromSameThread() )\n\t\t{\n\t\t\tthrow \"\\n\\tit is illegal for a thread to place an event on its own event stack!\\n\";\n\t\t}\n\t}\n\tcatch (char *psz)\n\t{\n#ifdef WINDOWS\n\t\tMessageBoxA(NULL,&psz[2],\"Fatal exception CThread::CEvent\",MB_ICONHAND);\n\t\texit(-1);\n#else\n\t\tcerr << \"Fatal exception CThread::CEvent(LPVOID lpvData):\" << psz;\n#endif\n\n\t}\n\n\t// make sure that the thread is running \n\tif( !m_bRunning && m_dwObjectCondition == NO_ERRORS )\n\t{\n\t\tm_mutex.Unlock();\n\t\t  PingThread(m_dwIdle*2); // wait two idle cycles for it to start\n\t\tm_mutex.Lock();\n\t}\n\tif( !m_bRunning ) // if it is not running return FALSE;\n\t{\n\t\tm_mutex.Unlock();\n\t\treturn FALSE;\n\t}\n\n\tif( m_dwObjectCondition & ILLEGAL_USE_OF_EVENT )\n\t\tm_dwObjectCondition = m_dwObjectCondition ^ ILLEGAL_USE_OF_EVENT;\n\tif( m_dwObjectCondition & EVENT_AND_TYPE_DONT_MATCH)\n\t\tm_dwObjectCondition = m_dwObjectCondition ^ EVENT_AND_TYPE_DONT_MATCH;\n\n\tif( m_type != ThreadTypeSpecialized && \n\t\tm_type != ThreadTypeNotDefined )\n\t{\n\t\tm_dwObjectCondition |= ILLEGAL_USE_OF_EVENT;\n\t\tm_dwObjectCondition |= EVENT_AND_TYPE_DONT_MATCH;\n\t\tcerr << \"Warning: invalid call to CEvent::Event(LPVOID), thread type is not specialized\\n\";\n\t\tm_mutex.Unlock();\n\t\treturn FALSE;\n\t}\n\tm_type = ThreadTypeSpecialized;\n\n\tm_mutex.Unlock();\n\tif( ! Push(lpvData) )\n\t{\n\t\treturn FALSE;\n\t}\n\n\tm_event.Set();\n\n\treturn TRUE;\n}\n\n\n/**\n *\n * SetPriority\n * sets a threads run priority, see SetThreadPriority\n * Note: only works for Windows family of operating systems\n *\n *\n **/\nvoid\nCThread::SetPriority(DWORD dwPriority)\n{\n\n#ifdef WINDOWS\n\tSetThreadPriority(m_thread,dwPriority);\n#endif\n}\n\n\t  \n/**\n *\n * KernelProcess\n * routes thread activity\n *\n **/\nBOOL\nCThread::KernelProcess()\n{\n\n\tm_mutex.Lock();\n\tm_state = ThreadStateBusy;\n\tif( !m_bRunning )\n\t{\n\t\tm_state = ThreadStateShuttingDown;\n\t\tm_mutex.Unlock();\n\t\treturn FALSE;\n\t}\n\tm_mutex.Unlock();\n\n\tif( !Empty() )\n\t{\n\t\twhile( !Empty() )\n\t\t{\n\t\t\tPop();\n\t\t\tif( !OnTask(m_lpvProcessor) )\n\t\t\t{\n\t\t\t\tm_mutex.Lock();\n\t\t\t\tm_lpvProcessor = NULL;\n\t\t\t\tm_state = ThreadStateShuttingDown;\n\t\t\t\tm_mutex.Unlock();\n\t\t\t\treturn FALSE;\n\t\t\t}\n\t\t}\n\t\tm_mutex.Lock();\n\t\tm_lpvProcessor = NULL;\n\t\tm_state = ThreadStateWaiting;\n\t}\n\telse {\n\t\tif( !OnTask() )\n\t\t{\n\t\t\tm_mutex.Lock();\n\t\t\tm_state = ThreadStateShuttingDown;\n\t\t\tm_mutex.Unlock();\n\t\t\treturn FALSE;\n\t\t}\n\t\tm_mutex.Lock();\n\t\tm_state = ThreadStateWaiting;\n\t}\n\n\tm_mutex.Unlock();\n\n\treturn TRUE;\n}\n\n\n/**\n * \n * GetEventsPending\n * returns the total number of vents waiting\n * in the event que\n * \n **/\nunsigned int\nCThread::GetEventsPending()\n{\n\tunsigned int chEventsWaiting;\n\n\tm_mutex.Lock();\n\t  chEventsWaiting = m_queuePos;\n    m_mutex.Unlock();\n\n\treturn chEventsWaiting;\n}\n\n\n/**\n *\n * CThread\n * instanciates thread object and\n * starts thread.\n *\n **/\nCThread::CThread(void)\n:m_bRunning(FALSE)\n#ifdef WINDOWS\n,m_thread(NULL)\n#endif\n,m_dwId(0L)\n,m_state(ThreadStateDown)\n,m_dwIdle(100)\n,m_lppvQueue(NULL)\n,m_lpvProcessor(NULL)\n,m_chQueue(QUEUE_SIZE)\n,m_type(ThreadTypeNotDefined)\n,m_stackSize(DEFAULT_STACK_SIZE)\n,m_queuePos(0)\n,m_StopTimeout(30)\n{\n\n\tm_dwObjectCondition = NO_ERRORS;\n\n\tm_lppvQueue = new LPVOID [QUEUE_SIZE];\n\n\tif( !m_lppvQueue ) \n\t{\n\t\tm_dwObjectCondition |= MEMORY_FAULT;\n\t\tm_state = ThreadStateFault;\n\t\treturn;\n\t}\n\n\tif( !m_mutex.m_bCreated )\n\t{\n\t\tperror(\"mutex creation failed\");\n\t\tm_dwObjectCondition |= MUTEX_CREATION;\n\t\tm_state = ThreadStateFault;\n\t\treturn;\n\t}\n\n\n\tif( !m_event.m_bCreated )\n\t{\n\t\tperror(\"event creation failed\");\n\t\tm_dwObjectCondition |= EVENT_CREATION;\n\t\tm_state = ThreadStateFault;\n\t\treturn;\n\t}\n\n\n\tStart();\n\n}\n\n\n/**\n *\n * PercentCapacity\n * returns a floating point value identifying\n * the current workload of the thread\n *\n **/\nfloat\nCThread::PercentCapacity()\n{\n\tfloat fValue = 0;\n\tm_mutex.Lock();\n\t\tfValue = (float)m_queuePos/m_chQueue;\n\tm_mutex.Unlock();\n\treturn fValue;\n}\n\n/**\n *\n * SetQueueSize\n * changes the threads queue size\n *\n **/\nBOOL\nCThread::SetQueueSize( unsigned int ch )\n{\n\tLPVOID * newQueue = NULL;\n\n\tm_mutex.Lock();\n\t    ASSERT(ch > m_queuePos);\n\n\t    if( ch <= m_queuePos )\n\t\t{\n\t\t\tcerr << \"Warning CThread::SetQueueSize:\\n\\tthe new queue size is less than the number of tasks on a non-empty queue! Request ignored.\\n\";\n\t\t\tm_mutex.Unlock();\n\t\t\treturn FALSE;\n\t\t}\n\n\t\tnewQueue = new LPVOID [ch];\n\t\tif(  !newQueue )\n\t\t{\n\t\t\tcerr << \"Warning CThread::SetQueueSize:\\n\\ta low memory, could not reallocate queue!\\n\";\n\t\t\tm_mutex.Unlock();\n\t\t\treturn FALSE;\n\t\t}\n\n\t\tfor( unsigned int i=0;i<m_queuePos; i++ )\n\t\t{\n\t\t\tnewQueue[i] = m_lppvQueue[i];\n\t\t}\n\n\t\tdelete [] m_lppvQueue;\n\n\t\tm_chQueue = ch;\n\t\tm_lppvQueue = newQueue;\n\n\tm_mutex.Unlock();\n\n\treturn TRUE;\n}\n\n\n\n/**\n *\n * Empty\n * returns a value of TRUE if there are no items on the threads que\n * otherwise a value of FALSE is returned.\n *\n **/\nBOOL\nCThread::Empty()\n{\n\tm_mutex.Lock();\n\tif( m_queuePos <= 0 )\n\t{\n\t\tm_mutex.Unlock();\n\t\treturn TRUE;\n\t}\n\tm_mutex.Unlock();\n\treturn FALSE;\n}\n\n\n\n/**\n *\n * Push\n * place a data object in the threads que\n *\n **/\nBOOL\nCThread::Push( LPVOID lpv )\n{\n\tif( !lpv ) return TRUE;\n\n\tm_mutex.Lock();\n\n\tif( m_queuePos+1 >= m_chQueue ) {\n\t\tm_dwObjectCondition |= STACK_OVERFLOW;\n\t\tm_mutex.Unlock();\n\t\treturn FALSE;\n\t}\n\tif( m_dwObjectCondition & STACK_EMPTY    )\n\t\tm_dwObjectCondition = m_dwObjectCondition ^ STACK_EMPTY;\n\n\tif( m_dwObjectCondition & STACK_OVERFLOW ) \n\t\tm_dwObjectCondition = m_dwObjectCondition ^ STACK_OVERFLOW;\n\n\tm_lppvQueue[m_queuePos++] = lpv;\n\tif( m_queuePos+1 >= m_chQueue )\n\t\tm_dwObjectCondition |= STACK_FULL;\n\n\tm_mutex.Unlock();\n\treturn TRUE;\n}\n\n\n/**\n *\n * Pop\n * move an object from the input que to the processor\n *\n **/\nBOOL\nCThread::Pop()\n{\n\n\tm_mutex.Lock();\n\tif( m_queuePos-1 < 0 )\n\t{\n\t\tm_queuePos = 0;\n\t\tm_dwObjectCondition |= STACK_EMPTY;\n\t\tm_mutex.Unlock();\n\t\treturn FALSE;\n\t}\n\tif( m_dwObjectCondition & STACK_EMPTY )\n\t\tm_dwObjectCondition = m_dwObjectCondition ^ STACK_EMPTY;\n\tif( m_dwObjectCondition & STACK_OVERFLOW )\n\t\tm_dwObjectCondition = m_dwObjectCondition ^ STACK_OVERFLOW;\n\tif( m_dwObjectCondition & STACK_FULL )\n\t\tm_dwObjectCondition = m_dwObjectCondition ^ STACK_FULL;\n\n\tm_queuePos--;\n\tm_lpvProcessor = m_lppvQueue[m_queuePos];\n\tm_mutex.Unlock();\n\treturn TRUE;\n}\n\n\n/**\n *\n * SetThreadType\n * specifies the type of threading that is to be performed.\n *\n * ThreadTypeEventDriven (default): an event must be physically sent\n *\t\t\t\t\t\t\t\t\tto the thread using the Event member\n *\t\t\t\t\t\t\t\t\tfunction.\n *\n * ThreadTypeIntervalDriven       : an event occurs automatically every \n *                                  dwIdle milli seconds.\n *\n **/\nvoid\nCThread::SetThreadType(ThreadType_t typ,\n              DWORD dwIdle)\n{\n\n\ttry \n\t{\n\t\tif( FromSameThread() )\n\t\t{\n\t\t\tthrow \"\\n\\tit is illegal for a thread to change its own type!\\n\";\n\t\t}\n\n\n\t\tm_mutex.Lock();\n\t\tm_dwIdle = dwIdle;\n\n\n\t\tif( m_type == typ ) {\n\t\t\tm_mutex.Unlock();\n\t\t\treturn;\n\t\t}\n\t\tif( m_dwObjectCondition & ILLEGAL_USE_OF_EVENT )\n\t\t\tm_dwObjectCondition = m_dwObjectCondition ^ ILLEGAL_USE_OF_EVENT;\n\t\tif( m_dwObjectCondition & EVENT_AND_TYPE_DONT_MATCH )\n\t\t\tm_dwObjectCondition = m_dwObjectCondition ^ EVENT_AND_TYPE_DONT_MATCH;\n\n\t\tm_type = typ;\n\n\n\t\tm_mutex.Unlock();\n\t\tm_event.Set();\n\t}\n\tcatch (char *psz)\n\t{\n#ifdef WINDOWS\n\t\tMessageBoxA(NULL,&psz[2],\"Fatal exception CThread::SetThreadType\",MB_ICONHAND);\n\t\texit(-1);\n#else\n\t\tcerr << \"Fatal exception CThread::SetThreadType(ThreadType_t typ):\" << psz;\n#endif\n\n\t}\n}\n\n\n/**\n *\n * Stop\n * stop thread \n *\n **/\nBOOL\nCThread::Stop()\n{\n\ttry \n\t{\n\t\tif( FromSameThread() )\n\t\t{\n\t\t\tthrow \"\\n\\tit is illegal for a thread to attempt to signal itself to stop!\\n\";\n\t\t}\n\n\t\tm_mutex.Lock();\n\t\tm_bRunning = FALSE;\n\t\tm_mutex.Unlock();\n\t\tm_event.Set();\n\n\t\tint ticks = (m_StopTimeout*1000)/100;\n\n\t\tfor( int i=0; i<ticks; i++ )\n\t\t{\n\t\t\tSleep(100);\n\n\t\t\tm_mutex.Lock();\n\t\t\tif( m_state == ThreadStateDown )\n\t\t\t{\n\t\t\t\tm_mutex.Unlock();\n\t\t\t\treturn TRUE;\n\t\t\t}\n\t\t\tm_mutex.Unlock();\n\n\t\t} \n\t}\n\tcatch (char *psz)\n\t{\n#ifdef WINDOWS\n\t\tMessageBoxA(NULL,&psz[2],\"Fatal exception CThread::Stop\",MB_ICONHAND);\n\t\texit(-1);\n#else\n\t\tcerr << \"Fatal exception CThread::Stop():\" << psz;\n#endif\n\n\t}\n\treturn FALSE;\n}\n\n\n/**\n *\n * SetIdle\n * changes the threads idle interval\n *\n **/\nvoid\nCThread::SetIdle(DWORD dwIdle)\n{\n\tm_mutex.Lock();\n\t\tm_dwIdle = dwIdle;\n\tm_mutex.Unlock();\n}\n\n/**\n *\n * Start\n * start thread\n *\n **/\nBOOL\nCThread::Start()\n{\n\ttry \n\t{\n\t\tif( FromSameThread() )\n\t\t{\n\t\t\tthrow \"\\n\\tit is illegal for a thread to attempt to start itself!\\n\";\n\t\t}\n\n\n\t\tm_mutex.Lock();\n\t\tif( m_bRunning ) \n\t\t{\n\t\t\tm_mutex.Unlock();\n\t\t\treturn TRUE;\n\t\t}\n\n\t\tm_mutex.Unlock();\n\n\n\t\tif( m_dwObjectCondition & THREAD_CREATION )\n\t\t\tm_dwObjectCondition = m_dwObjectCondition ^ THREAD_CREATION;\n\n#ifdef WINDOWS\n\t\tif( m_thread ) CloseHandle(m_thread);\n#ifdef USE_BEGIN_THREAD\n\t\tm_thread = (HANDLE )_beginthreadex(NULL,(unsigned int)m_stackSize,_THKERNEL,(LPVOID)this,0,&m_dwId);\n#else\n\t\tm_thread = CreateThread(NULL,m_stackSize ,_THKERNEL,(LPVOID)this,0,&m_dwId);\n#endif\n\t\tif( !m_thread )\n\t\t{\n\t\t\tperror(\"thread creation failed\");\n\t\t\tm_dwObjectCondition |= THREAD_CREATION;\n\t\t\tm_state = ThreadStateFault;\n\t\t\treturn FALSE;\n\t\t}\n#else\n\t\tpthread_attr_t attr;\n\n\t\tpthread_attr_init(&attr);\n\n#ifdef VMS\n\t\tif( m_stackSize == 0 )\n\t\t\tpthread_attr_setstacksize(&attr,PTHREAD_STACK_MIN*10);\n#endif\n\t\tif( m_stackSize != 0 )\n\t\t\tpthread_attr_setstacksize(&attr,m_stackSize);\n\n\t\tint error = pthread_create(&m_thread,&attr,_THKERNEL,(LPVOID)this);\n\n\t\tif( error != 0 )\n\t\t{\n\t\t\tm_dwObjectCondition |= THREAD_CREATION;\n\t\t\tm_state = ThreadStateFault;\n\n#if defined(HPUX) || defined(SUNOS) || defined(LINUX)\n\t\t\tswitch(error)/* show the thread error */\n\t\t\t{\n\n\t\t\tcase EINVAL:\n\t\t\t\tcerr << \"error: attr in an invalid thread attributes object\\n\";\n\t\t\t\tbreak;\n\t\t\tcase EAGAIN:\n\t\t\t\tcerr << \"error: the necessary resources to create a thread are not\\n\";\n\t\t\t\tcerr << \"available.\\n\";\n\t\t\t\tbreak;\n\t\t\tcase EPERM:\n\t\t\t\tcerr << \"error: the caller does not have the privileges to create\\n\";\n\t\t\t\tcerr << \"the thread with the specified attr object.\\n\";\n\t\t\t\tbreak;\n#if defined(HPUX)\n\t\t\tcase ENOSYS:\n\n\t\t\t\tcerr << \"error: pthread_create not implemented!\\n\";\n\t\t\t\tif( __is_threadlib_linked()==0 )\n\t\t\t\t{\n\t\t\t\t\tcerr << \"error: threaded library not being used, improper linkage \\\"-lpthread -lc\\\"!\\n\";\n\t\t\t\t}\n\t\t\t\tbreak;\n#endif\n\t\t\tdefault:\n\t\t\t\tcerr << \"error: an unknown error was encountered attempting to create\\n\";\n\t\t\t\tcerr << \"the requested thread.\\n\";\n\t\t\t\tbreak;\n\t\t\t}\n#else\n\t\t\tcerr << \"error: could not create thread, pthread_create failed (\" << error << \")!\\n\";\n#endif\n\t\t\treturn FALSE;\t\n\t\t}\n#endif\n\t}\n\tcatch (char *psz)\n\t{\n#ifdef WINDOWS\n\t\tMessageBoxA(NULL,&psz[2],\"Fatal exception CThread::Start\",MB_ICONHAND);\n#else\n\t\tcerr << \"Fatal exception CThread::Start():\" << psz;\n#endif\n\t\texit(-1);\n\t}\n\treturn TRUE;\n}\n\n/**\n *\n * AtCapacity\n * returns TRUE if the threads queue is full, and the thread\n * is busy processing an event or the thread is not running\n *\n **/\nBOOL\nCThread::AtCapacity()\n{\n\tm_mutex.Lock();\n\t\tif( ((m_dwObjectCondition & STACK_OVERFLOW ||\n\t\t\t  m_dwObjectCondition & STACK_FULL ) &&\n\t\t\t  m_state == ThreadStateBusy) || !m_bRunning)\n\t\t{\n\t\t\tm_mutex.Unlock();\n\t\t\treturn TRUE;\n\t\t}\n\tm_mutex.Unlock();\n\treturn FALSE;\n}\n\n/**\n *\n * ThreadState\n * return the current state of the thread\n *\n **/\nThreadState_t \nCThread::ThreadState()\n{\n\tThreadState_t currentState;\n\tm_mutex.Lock();\n\t\tcurrentState = m_state;\n\tm_mutex.Unlock();\n\treturn currentState;\n}\n\n/**\n *\n * ~CThread\n * destructor.  Stop should be called prior to destruction to\n * allow for gracefull thread termination.\n *\n **/\nCThread::~CThread(void)\n{\n\tif( m_bRunning ) // gracefull termination\n\t{\n\t\ttry \n\t\t{\n\t\t\tif( !Stop() )\n\t\t\t{\n\t\t\t\tthrow \"\\n\\tthread failed to stop in a timely manner!\\n\";\n\t\t\t}\n\t\t}\n\t\tcatch(const char *psz )\n\t\t{\n#ifdef WINDOWS\n\t\t    MessageBoxA(NULL,&psz[2],\"Fatal exception CThread::Stop\",MB_ICONHAND);\n\t\t    exit(-1);\n#else\n\t\t\tcerr << \"Fatal exception CThread::Stop: \" << psz;\n#endif\n\t\t}\n\t}\n#ifdef WINDOWS\n\tCloseHandle(m_thread);\n#endif\n\n\tdelete [] m_lppvQueue;\n}\n\n\n/**\n *\n * PingThread\n * used to determine if a thread is running\n *\n **/\nBOOL\nCThread::PingThread(DWORD dwTimeout /* timeout in milli-seconds */\n\t\t\t\t )\n{\n    DWORD dwTotal = 0;\n\n\twhile(TRUE)\n\t{\n\t\tif( dwTotal > dwTimeout && dwTimeout > 0 )\n\t\t\treturn FALSE;\n\t\tm_mutex.Lock();\n\t\t\tif( m_bRunning )\n\t\t\t{\n\t\t\t\tm_mutex.Unlock();\n\t\t\t\treturn TRUE;\n\t\t\t}\n\t\tdwTotal += m_dwIdle;\n\t\tm_mutex.Unlock();\n\t\tSleep(m_dwIdle);\n\t}\n\n\treturn FALSE;\n}\n\n/**\n *\n * WaitTillExit\n * blocks caller until thread exits\n *\n **/\nvoid\nCThread::WaitTillExit()\n{\n\n\t/*\n\t *\n\t * prevent users from calling this function from within the same thread\n\t * of execution\n\t *\n\t */\n\ttry \n\t{\n\t\tif( FromSameThread() )\n\t\t\tthrow \"\\n\\tthis function can not be called from within the same thread!\\n\";\n\n\n\n\n\t\tif( !m_bRunning ) return;\n\n\n#ifdef WINDOWS\n\t\tWaitForSingleObject(m_thread,INFINITE);\n#else\n\t\tLPVOID lpv;\n\n\t\tpthread_join(m_thread,&lpv);\n#endif\n\t}\n\tcatch( char *psz )\n\t{\n#ifdef WINDOWS\n\t\tMessageBoxA(NULL,&psz[2],\"Fatal exception CThread::WaitTillExit\",MB_ICONHAND);\n\t\texit(-1);\n#else\n\t\tcerr << \"Fatal exception CThread::WaitTillExit: \" << psz;\n#endif\n\n\t}\n}\n\n\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/common/Thread.h",
    "content": "//\n// Thread.h: header file\n//\n// Copyright (C) Walter E. Capers.  All rights reserved\n//\n// This source is free to use as you like.  If you make\n// any changes please keep me in the loop.  Email them to\n// walt.capers@comcast.net.\n//\n// PURPOSE:\n//\n//  To implement Win32 threading as a C++ object\n//\n// REVISIONS\n// =======================================================\n// Date: 10.24.07        \n// Name: Walter E. Capers\n// Description: File creation\n//\n// Date: 10.24.07 11:49 am\n// Name: Walter E. Capers\n// Description: Added SetIdle function to allow the idle time to be altered\n//              independent of the SetThreadType member function.\n// Date: 10.31.07\n// Name: Walter E. Capers\n// Description: Added support for beginthreadex\n//              To use compile with -DUSE_BEGIN_THREAD\n//\n//\n\n#ifndef THREAD_CLASS\n#define THREAD_CLASS\n\n#ifndef WINDOWS\n#if defined(_WIN32) || defined(_WIN64)\n#define WINDOWS\n#endif\n#endif\n#ifdef __APPLE__\n#define VMS\n#endif\n\n#ifndef WINDOWS\n#include <stdio.h>\n#include <string.h>\n//#include <malloc.h>\n#include <memory.h>\n#include <pthread.h>\n#include <stdlib.h>\n#include <time.h>\n#include <errno.h>\ntypedef unsigned char BOOL;\n#define TRUE 1\n#define FALSE 0\ntypedef long DWORD;\ntypedef void *LPVOID;\n#else\n#include \"afx.h\"\n/* #include <windows.h> */\n#include <stdio.h>\n#endif\n\n#if defined(AS400) || defined(OS400)\ntypedef pthread_id_np_t ThreadId_t;\n#elif defined(VMS) || defined(__NetBSD__)\ntypedef pthread_t ThreadId_t;\n#else\n#ifdef USE_BEGIN_THREAD\ntypedef unsigned ThreadId_t;\n#else\ntypedef DWORD ThreadId_t;\n#endif\n#endif\n\n#include <common/MutexClass.h>\n#include <common/EventClass.h>\n\n#define QUEUE_SIZE 100\n#define DEFAULT_STACK_SIZE 0\n#ifndef WINDOWS\nvoid Sleep( unsigned int mseconds);\n#endif\n\n#ifndef ASSERT\n#if defined(DEBUG) || defined(_DEBUG)\n#define ASSERT(test) if( !(test) ) { \\\n\tfprintf(stderr,\"\\nASSERT(%s) FAILS, %s line %d\\n\",#test,__FILE__, __LINE__); exit(0);}\n#else\n#define ASSERT(test)\n#endif\n#endif\n\n\ntypedef enum {\n\tThreadStateBusy,               // thread is currently handling a task\n\tThreadStateWaiting,            // thread is waiting for something to do\n    ThreadStateDown,               // thread is not running\n    ThreadStateShuttingDown,       // thread is in the process of shutting down\n    ThreadStateFault               // an error has occured and the thread could not\n\t                               // be launched\n} ThreadState_t;\n\ntypedef enum {\n\tThreadTypeHomogeneous,\n\tThreadTypeSpecialized,\n    ThreadTypeIntervalDriven,\n    ThreadTypeNotDefined } ThreadType_t;\n\n\ntypedef enum {\n\tTaskStatusNotSubmitted,\n\tTaskStatusWaitingOnQueue,\n\tTaskStatusBeingProcessed,\n\tTaskStatusCompleted } TaskStatus_t;\n\nclass CTask\n{\nprivate:\n\tTaskStatus_t m_state;\n\tThreadId_t m_dwThread;\npublic:\n\tCMutexClass m_mutex;\n\n\tvoid SetTaskStatus(TaskStatus_t state) \n\t{\n\t\tm_mutex.Lock();\n\t\t\tm_state=state;\n\t\tm_mutex.Unlock();\n\t}\n\n\tvoid SetId(ThreadId_t *pid)\n\t{\n\t\tmemcpy(&m_dwThread,pid,sizeof(ThreadId_t));\n\t}\n\n\t/**\n\t *\n\t * Wait\n\t * waits for upto timeoutSeconds for a task\n\t * to complete\n\t *\n\t **/\n\tBOOL Wait(int timeoutSeconds)\n\t{\n        timeoutSeconds = timeoutSeconds * 1000;\n\t\tif( Status() != TaskStatusCompleted &&\n\t\t\ttimeoutSeconds > 0 )\n\t\t{\n\t\t\tSleep(100);\n\t\t\ttimeoutSeconds = timeoutSeconds - 100;\n\t\t}\n\t\tif( Status() == TaskStatusCompleted ) return TRUE;\n\t\treturn FALSE;\n\t}\n\n\t/**\n\t *\n\t * Status\n\t * returns current state of a task\n\t *\n\t **/\n\tTaskStatus_t Status()\n\t{\n\t\tTaskStatus_t state ;\n\n\t\tm_mutex.Lock();\n\t\t  state = m_state;\n\t\tm_mutex.Unlock();\n\t    return state;\n\t}\n\n\tvoid Thread(ThreadId_t *pId)\n\t{\n\t\tmemcpy(pId,&m_dwThread,sizeof(ThreadId_t));\n\t}\n\n\tCTask(){m_state=TaskStatusNotSubmitted; memset(&m_dwThread,0,sizeof(ThreadId_t)); }\n\t~CTask(){}\n\tvirtual BOOL Task()=0;\n};\n\n\nclass CThread \n#ifdef WINDOWS\n\t: public CObject // use CObject as a base class so object can be used in lists and\n\t               // object arrays\n#endif\n{\nprivate:\n\tCEventClass   m_event;         // event controller\n\tint           m_StopTimeout;   // specifies a timeout value for stop\n\t                               // if a thread fails to stop within m_StopTimeout\n\t                               // seconds an exception is thrown\n\n\tBOOL\t\t  m_bRunning;      // set to TRUE if thread is running\n#ifdef WINDOWS\n\tHANDLE\t\t  m_thread;\t\t   // thread handle\n#else\n\tpthread_t     m_thread;        // thread handle\n#endif\n\tThreadId_t\t  m_dwId;          // id of this thread\n\tLPVOID        *m_lppvQueue;    // task que\n\tunsigned int  m_chQueue;       // que depth\n\tunsigned int  m_queuePos;      // current que possition\n\tLPVOID        m_lpvProcessor;  // data which is currently being processed\n\tThreadState_t m_state;         // current state of thread see thread state data\n\t                               // structure.\n\tDWORD         m_dwIdle;        // used for Sleep periods\n\tThreadType_t  m_type;\n\tDWORD\t\t  m_stackSize;     // thread stack size\n#define NO_ERRORS\t\t\t       0\n#define MUTEX_CREATION\t\t       0x01\n#define EVENT_CREATION\t\t       0x02\n#define THREAD_CREATION\t\t       0x04\n#define UNKNOWN\t\t\t\t\t   0x08\n#define ILLEGAL_USE_OF_EVENT       0x10\n#define MEMORY_FAULT               0x20\n#define EVENT_AND_TYPE_DONT_MATCH  0x40\n#define STACK_OVERFLOW             0x80\n#define STACK_EMPTY                0x100\n#define STACK_FULL                 0x200\n\n\tDWORD         m_dwObjectCondition;\n\tBOOL\t\t  Push(LPVOID lpv);\n\tBOOL\t\t  Pop();\n\tBOOL\t\t  Empty();\npublic:\n\t/**\n\t *\n\t * user definable member functions\n\t *\n\t **/\n\tCMutexClass\t  m_mutex;         // mutex that protects threads internal data\n\n\tvirtual BOOL OnTask(LPVOID lpvData);     // called when an event occurs\n\tvirtual BOOL OnTask();                   // called when a time interval has elapsed\n\n\tCThread(void);\n\t~CThread(void);\n#ifdef WINDOWS\n#ifdef USE_BEGIN_THREAD\n\tfriend unsigned __stdcall _THKERNEL(LPVOID lpvData);\n#else\n\tfriend DWORD WINAPI _THKERNEL( LPVOID lpvData );\n#endif\n#else\n\tfriend LPVOID _THKERNEL(LPVOID lpvData);\n#endif\n\tBOOL        FromSameThread();\n\tfloat\t\tPercentCapacity();\n\tvoid        WaitTillExit();\n\tBOOL\t\tKernelProcess();\n\tBOOL\t\tEvent(LPVOID lpvData=NULL);\n\tBOOL        Event(CTask *pvTask);\n\tvoid\t\tSetOnStopTimeout(int seconds ) { m_StopTimeout = seconds; }\n    BOOL        SetQueueSize( unsigned int ch );\n\tBOOL\t\tStop();\n\tBOOL\t\tStart();\n\tvoid\t\tGetId(ThreadId_t *pId) { memcpy(pId,&m_dwId,sizeof(ThreadId_t)); }      // returns thread id\n\tThreadState_t ThreadState();\n\tBOOL\t\tPingThread(DWORD dwTimeout=0);\n\tBOOL        AtCapacity();\n#ifdef WINDOWS\n\tvoid\t\tSetPriority(DWORD dwPriority=THREAD_PRIORITY_NORMAL);\n#else\n\tvoid\t\tSetPriority(DWORD dwPriority=0);\n#endif\n\tDWORD\t\tGetErrorFlags() { return m_dwObjectCondition; } // returns state of object\n\tvoid\t\tSetThreadType(ThreadType_t typ=ThreadTypeNotDefined,DWORD dwIdle=100);\n\tvoid\t\tSetIdle(DWORD dwIdle=100);\n    unsigned int GetEventsPending();\n    static BOOL ThreadIdsEqual(ThreadId_t *p1,\n\t\t\t\t\t\t       ThreadId_t *p2)\n\t{\n#if defined(AS400)||defined(OS400)\n\t\treturn(( memcmp(p1,p2,sizeof(ThreadId_t))==0)?TRUE:FALSE);\n#elif defined(VMS) || defined(__NetBSD__)\n\t\treturn (( pthread_equal(*p1,*p2) )?TRUE:FALSE );\n#else\n\t\treturn ((*p1 == *p2)?TRUE:FALSE);\n#endif\n\n\t}\n\n\tstatic ThreadId_t ThreadId()\n\t{\n\t\tThreadId_t thisThreadsId ;\n#if defined(AS400) || defined(OS400)\n\t\tpthread_t thread;\n#endif\n\n#ifdef WINDOWS\n\t\tthisThreadsId = (ThreadId_t)GetCurrentThreadId();\n#else\n\n#if defined(AS400) || defined(OS400)\n\t\tthread = pthread_self();\n\t\tpthread_getunique_np(&thread,&thisThreadsId);\n#elif defined(ALPHA) || defined(DEC) || defined(VMS)\n#ifdef VMS\n\t\tthisThreadsId = pthread_self();\n#else\n\t\tthisThreadsId = pthread_getsequence_np(pthread_self());\n#endif\n#else\n\t\tthisThreadsId = pthread_self();\n#endif\n#endif\n\t\treturn thisThreadsId;\n\t}\n\n\n};\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/common/osSpecifics.c",
    "content": "/*\n  Copyright (C) 2012-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n\n#include <stdint.h>\n#include <common/osSpecifics.h>\n\n\n#if defined(_WIN32) || defined(_WIN64)\n\n#else\n\n#endif\n\n#if defined(_WIN32) || defined(_WIN64)\n# include <WinSock2.h>\n# include <time.h>\n\nuint64_t  zrtpGetTickCount()\n{\n   // return GetTickCount64();  //works only on 64bit OS\n   unsigned long long ret;\n   FILETIME ft;\n   GetSystemTimeAsFileTime(&ft);\n   ret = ft.dwHighDateTime;\n   ret <<= 32;\n   ret |= ft.dwLowDateTime;\n\n   return ret / 10;             //return msec\n}\n#else\n# include <netinet/in.h>\n# include <sys/time.h>\n\nuint64_t zrtpGetTickCount()\n{\n   struct timeval tv;\n   gettimeofday(&tv, 0);\n\n   return ((uint64_t)tv.tv_sec) * (uint64_t)1000 + ((uint64_t)tv.tv_usec) / (uint64_t)1000;\n}\n\n#endif\n\nuint32_t zrtpNtohl (uint32_t net)\n{\n    return ntohl(net);\n}\n\nuint16_t zrtpNtohs (uint16_t net)\n{\n    return ntohs(net);\n}\n\nuint32_t zrtpHtonl (uint32_t host)\n{\n    return htonl(host);\n}\nuint16_t zrtpHtons (uint16_t host)\n{\n    return htons(host);\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/common/osSpecifics.h",
    "content": "/*\n  Copyright (C) 2012-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _OSSPECIFICS_H_\n#define _OSSPECIFICS_H_\n\n/**\n * @file osSpecifics.h\n * @brief Some functions to adapt to OS and/or compiler specific handling\n * @defgroup GNU_ZRTP The GNU ZRTP C++ implementation\n * @{\n *\n * This modules contains some functions that are either specific for a particular\n * OS or use include files that are not common.\n *\n * This header file shall not #include system specific header files and shall also\n * not use specific #ifdef stuff. Refer to @c osSpecifics.c for the OS specific\n * #include, #ifdef and implementations.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef __EXPORT\n  #if (defined _WIN32 || defined __CYGWIN__) && defined(_WINDLL)\n    #define __EXPORT    __declspec(dllimport)\n    #define __LOCAL\n  #elif __GNUC__ >= 4\n    #define __EXPORT    __attribute__ ((visibility(\"default\")))\n    #define __LOCAL     __attribute__ ((visibility(\"hidden\")))\n  #else\n    #define __EXPORT\n    #define __LOCAL\n  #endif\n#endif\n\n#if defined(_WIN32) || defined(_WIN64)\n# define snprintf _snprintf\n#endif\n\n#ifdef __GNUC__\n#define DEPRECATED __attribute__((deprecated))\n#elif defined(_MSC_VER)\n#define DEPRECATED __declspec(deprecated)\n#else\n#pragma message(\"WARNING: You need to implement DEPRECATED for this compiler\")\n#define DEPRECATED\n#endif\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n/**\n * Get surrent system time in milli-second.\n *\n * @return current time in ms.\n */\nextern uint64_t zrtpGetTickCount();\n\n/**\n * Convert a 32bit variable from network to host order.\n *\n * Replaces the macros found in @c inet.h or @c WinSock2.h. Use this function\n * to avoid different includes freamed with @c #idef in the sources. Including\n * @c WinSock2 will increase compile time and may lead to other subtle problems\n * because @c WinSock2 also includes @c windows.h.\n *\n * @param net 32bit variable in network byte order.\n *\n * @return 32bit variable in host byte order.\n */\nextern uint32_t zrtpNtohl (uint32_t net);\n\n/**\n * Convert a 16bit variable from network to host order.\n *\n * @param net 16bit variable in network byte order.\n *\n * @return 16bit variable in host byte order.\n *\n * @sa zrtpNtohl()\n */\nextern uint16_t zrtpNtohs (uint16_t net);\n\n/**\n * Convert a 32bit variable from host to network order.\n *\n * @param host 32bit variable in host byte order.\n *\n * @return 32bit variable in network byte order.\n *\n * @sa zrtpNtohl()\n */\nextern uint32_t zrtpHtonl (uint32_t host);\n\n/**\n * Convert a 16bit variable from host to network order.\n *\n * @param host 16bit variable in host byte order.\n *\n * @return 16bit variable in network byte order.\n *\n * @sa zrtpNtohl()\n */\nextern uint16_t zrtpHtons (uint16_t host);\n\n#if defined(__cplusplus)\n}\n#endif\n\n\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/ZrtpRandom.cpp",
    "content": "/*\n *  Copyright (C) 2006-2013 Werner Dittmann\n *\n *  This program is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU Lesser General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <fcntl.h>\n\n#include <cryptcommon/ZrtpRandom.h>\n#include <cryptcommon/aescpp.h>\n#include <common/Thread.h>\n#include <zrtp/crypto/sha2.h>\n\nstatic sha512_ctx mainCtx;\n\nstatic CMutexClass lockRandom;\n\nstatic bool initialized = false;\n\n/*\n * memset_volatile is a volatile pointer to the memset function.\n * You can call (*memset_volatile)(buf, val, len) or even\n * memset_volatile(buf, val, len) just as you would call\n * memset(buf, val, len), but the use of a volatile pointer\n * guarantees that the compiler will not optimise the call away.\n */\nstatic void * (*volatile memset_volatile)(void *, int, size_t) = memset;\n\n/*\n * Random bits are produced as follows.\n * First stir new entropy into the random state (zrtp->rand_ctx).\n * Then make a copy of the random context and finalize it.\n * Use the digest to seed an AES-256 context and, if space remains, to\n * initialize a counter.\n * Then encrypt the counter with the AES-256 context, incrementing it\n * per block, until we have produced the desired quantity of data.\n */\n/*----------------------------------------------------------------------------*/\nint ZrtpRandom::getRandomData(uint8_t* buffer, uint32_t length) {\n\n    AESencrypt aesCtx;\n    sha512_ctx randCtx2;\n    uint8_t    md[SHA512_DIGEST_SIZE];\n    uint8_t    ctr[AES_BLOCK_SIZE];\n    uint8_t    rdata[AES_BLOCK_SIZE];\n    uint32_t   generated = length;\n\n    /*\n     * Add entropy from system state\n     * We will include whatever happens to be in the buffer, it can't hurt\n     */\n    ZrtpRandom::addEntropy(buffer, length);\n\n    lockRandom.Lock();\n\n    /* Copy the mainCtx and finalize it into the md buffer */\n    memcpy(&randCtx2, &mainCtx, sizeof(sha512_ctx));\n    sha512_end(md, &randCtx2);\n\n    lockRandom.Unlock();\n\n    /* Key an AES context from this buffer */\n    aesCtx.key256(md);\n\n    /* Initialize counter, using excess from md if available */\n    memset (ctr, 0, sizeof(ctr));\n    if (SHA512_DIGEST_SIZE > (256/8)) {\n        uint32_t ctrbytes = SHA512_DIGEST_SIZE - (256/8);\n        if (ctrbytes > AES_BLOCK_SIZE)\n            ctrbytes = AES_BLOCK_SIZE;\n        memcpy(ctr + sizeof(ctr) - ctrbytes, md + (256/8), ctrbytes);\n    }\n\n    /* Encrypt counter, copy to destination buffer, increment counter */\n    while (length) {\n        uint8_t *ctrptr;\n        uint32_t copied;\n        aesCtx.encrypt(ctr, rdata);\n        copied = (sizeof(rdata) < length) ? sizeof(rdata) : length;\n        memcpy (buffer, rdata, copied);\n        buffer += copied;\n        length -= copied;\n\n        /* Increment counter */\n        ctrptr = ctr + sizeof(ctr) - 1;\n        while (ctrptr >= ctr) {\n            if ((*ctrptr-- += 1) != 0) {\n                break;\n            }\n        }\n    }\n    memset_volatile(&randCtx2, 0, sizeof(randCtx2));\n    memset_volatile(md, 0, sizeof(md));\n    memset_volatile(&aesCtx, 0, sizeof(aesCtx));\n    memset_volatile(ctr, 0, sizeof(ctr));\n    memset_volatile(rdata, 0, sizeof(rdata));\n\n    return generated;\n}\n\n\nint ZrtpRandom::addEntropy(const uint8_t *buffer, uint32_t length)\n{\n\n    uint8_t newSeed[64];\n    size_t len = getSystemSeed(newSeed, sizeof(newSeed));\n\n    lockRandom.Lock();\n    initialize();\n\n    if (buffer && length) {\n        sha512_hash(buffer, length, &mainCtx);\n    }\n    if (len > 0) {\n        sha512_hash(newSeed, len, &mainCtx);\n        length += len;\n    }\n    lockRandom.Unlock();\n    return length;\n}\n\n\nvoid ZrtpRandom::initialize() {\n    if (initialized)\n        return;\n\n    sha512_begin(&mainCtx);\n    initialized = true;\n}\n\n/*\n * This works for Linux and similar systems. For other systems add\n * other functions (using #ifdef conditional compile) to get some\n * random data that we can use as seed for the internal PRNG below.\n */\n\nsize_t ZrtpRandom::getSystemSeed(uint8_t *seed, size_t length)\n{\n    size_t num = 0;\n\n#if !(defined(_WIN32) || defined(_WIN64))\n    int rnd = open(\"/dev/urandom\", O_RDONLY);\n    if (rnd >= 0) {\n        num = read(rnd, seed, length);\n        close(rnd);\n    }\n    else\n        return num;\n#endif\n    return num;\n}\n\nint zrtp_AddEntropy(const uint8_t *buffer, uint32_t length) {\n    return ZrtpRandom::addEntropy(buffer, length);\n}\n\nint zrtp_getRandomData(uint8_t *buffer, uint32_t length) {\n    return ZrtpRandom::getRandomData(buffer, length);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/ZrtpRandom.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPRANDOM_H_\n#define _ZRTPRANDOM_H_\n\n/**\n * @file ZrtpCommon.h\n * @brief ZRTP standalone random number generator\n * @defgroup GNU_ZRTP The GNU ZRTP C++ implementation\n * @{\n */\n\n#include <string.h>\n#if !(defined(_WIN32) || defined(_WIN64))\n#include <unistd.h>\n#endif\n#include <stdint.h>\n#include <sys/types.h>\n\n#ifdef __cplusplus\nclass ZrtpRandom {\npublic:\n    /**\n     * @brief This method adds entropy to the PRNG.\n     *\n     * An application may seed some entropy data to the PRNG. If the @c buffer is\n     * @c NULL or the @c length is zero then the method adds at least some system\n     * entropy.\n     *\n     * @param buffer some entropy data to add\n     *\n     * @param length length of entropy data in bytes\n     *\n     * @return on success: number of entropy bytes added, on failure: -1. Number of\n     *         bytes added may be bigger then @c length because of added system\n     *         entropy.\n     */\n    static int addEntropy(const uint8_t *buffer, uint32_t length);\n\n    /**\n     * @brief Get some random data.\n     *\n     * @param buffer that will contain the random data\n     *\n     * @param length how many bytes of random data to generate\n     *\n     * @return the number of generated random data bytes\n     */\n    static int getRandomData(uint8_t *buffer, uint32_t length);\n\nprivate:\n    static void initialize();\n    static size_t getSystemSeed(uint8_t *seed, size_t length);\n\n};\n#endif\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\nint zrtp_AddEntropy(const uint8_t *buffer, uint32_t length);\n\nint zrtp_getRandomData(uint8_t *buffer, uint32_t length);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* ZRTPRANDOM */"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/aes.h",
    "content": "/*\n---------------------------------------------------------------------------\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\n\nThe redistribution and use of this software (with or without changes)\nis allowed without the payment of fees or royalties provided that:\n\n  source code distributions include the above copyright notice, this\n  list of conditions and the following disclaimer;\n\n  binary distributions include the above copyright notice, this list\n  of conditions and the following disclaimer in their documentation.\n\nThis software is provided 'as is' with no explicit or implied warranties\nin respect of its operation, including, but not limited to, correctness\nand fitness for purpose.\n---------------------------------------------------------------------------\nIssue Date: 20/12/2007\n\n This file contains the definitions required to use AES in C. See aesopt.h\n for optimisation details.\n*/\n\n#ifndef _AES_H\n#define _AES_H\n\n#include <stdlib.h>\n\n/*  This include is used to find 8 & 32 bit unsigned integer types  */\n#include \"brg_types.h\"\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\n#define AES_128     /* if a fast 128 bit key scheduler is needed    */\n#define AES_192     /* if a fast 192 bit key scheduler is needed    */\n#define AES_256     /* if a fast 256 bit key scheduler is needed    */\n#define AES_VAR     /* if variable key size scheduler is needed     */\n#define AES_MODES   /* if support is needed for modes               */\n\n/* The following must also be set in assembler files if being used  */\n\n#define AES_ENCRYPT /* if support for encryption is needed          */\n#define AES_DECRYPT /* if support for decryption is needed          */\n#define AES_REV_DKS /* define to reverse decryption key schedule    */\n\n#define AES_BLOCK_SIZE  16  /* the AES block size in bytes          */\n#define N_COLS           4  /* the number of columns in the state   */\n\n/* The key schedule length is 11, 13 or 15 16-byte blocks for 128,  */\n/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes  */\n/* or 44, 52 or 60 32-bit words.                                    */\n\n#if defined( AES_VAR ) || defined( AES_256 )\n#define KS_LENGTH       60\n#elif defined( AES_192 )\n#define KS_LENGTH       52\n#else\n#define KS_LENGTH       44\n#endif\n\n#define AES_RETURN INT_RETURN\n\n/* the character array 'inf' in the following structures is used    */\n/* to hold AES context information. This AES code uses cx->inf.b[0] */\n/* to hold the number of rounds multiplied by 16. The other three   */\n/* elements can be used by code that implements additional modes    */\n\ntypedef union\n{   uint_32t l;\n    uint_8t b[4];\n} aes_inf;\n\ntypedef struct\n{   uint_32t ks[KS_LENGTH];\n    aes_inf inf;\n} aes_encrypt_ctx;\n\ntypedef struct\n{   uint_32t ks[KS_LENGTH];\n    aes_inf inf;\n} aes_decrypt_ctx;\n\n/* This routine must be called before first use if non-static       */\n/* tables are being used                                            */\n\nAES_RETURN aes_init_zrtp(void);\n\n/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */\n/* those in the range 128 <= key_len <= 256 are given in bits       */\n\n#if defined( AES_ENCRYPT )\n\n#if defined( AES_128 ) || defined( AES_VAR)\nAES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);\n#endif\n\n#if defined( AES_192 ) || defined( AES_VAR)\nAES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);\n#endif\n\n#if defined( AES_256 ) || defined( AES_VAR)\nAES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);\n#endif\n\n#if defined( AES_VAR )\nAES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]);\n#endif\n\nAES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]);\n\n#endif\n\n#if defined( AES_DECRYPT )\n\n#if defined( AES_128 ) || defined( AES_VAR)\nAES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);\n#endif\n\n#if defined( AES_192 ) || defined( AES_VAR)\nAES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);\n#endif\n\n#if defined( AES_256 ) || defined( AES_VAR)\nAES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);\n#endif\n\n#if defined( AES_VAR )\nAES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]);\n#endif\n\nAES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]);\n\n#endif\n\n#if defined( AES_MODES )\n\n/* Multiple calls to the following subroutines for multiple block   */\n/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */\n/* long messages incremantally provided that the context AND the iv */\n/* are preserved between all such calls.  For the ECB and CBC modes */\n/* each individual call within a series of incremental calls must   */\n/* process only full blocks (i.e. len must be a multiple of 16) but */\n/* the CFB, OFB and CTR mode calls can handle multiple incremental  */\n/* calls of any length. Each mode is reset when a new AES key is    */\n/* set but ECB and CBC operations can be reset without setting a    */\n/* new key by setting a new IV value.  To reset CFB, OFB and CTR    */\n/* without setting the key, aes_mode_reset() must be called and the */\n/* IV must be set.  NOTE: All these calls update the IV on exit so  */\n/* this has to be reset if a new operation with the same IV as the  */\n/* previous one is required (or decryption follows encryption with  */\n/* the same IV array).                                              */\n\nAES_RETURN aes_test_alignment_detection(unsigned int n);\n\nAES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, const aes_encrypt_ctx cx[1]);\n\nAES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, const aes_decrypt_ctx cx[1]);\n\nAES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, unsigned char *iv, const aes_encrypt_ctx cx[1]);\n\nAES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, unsigned char *iv, const aes_decrypt_ctx cx[1]);\n\nAES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]);\n\nAES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, unsigned char *iv, aes_encrypt_ctx cx[1]);\n\nAES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, unsigned char *iv, aes_encrypt_ctx cx[1]);\n\n#define aes_ofb_encrypt aes_ofb_crypt\n#define aes_ofb_decrypt aes_ofb_crypt\n\nAES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, unsigned char *iv, aes_encrypt_ctx cx[1]);\n\ntypedef void cbuf_inc(unsigned char *cbuf);\n\n#define aes_ctr_encrypt aes_ctr_crypt\n#define aes_ctr_decrypt aes_ctr_crypt\n\nAES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,\n            int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]);\n\n#endif\n\n#if defined(__cplusplus)\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/aes_modes.c",
    "content": "/*\n---------------------------------------------------------------------------\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\n\nThe redistribution and use of this software (with or without changes)\nis allowed without the payment of fees or royalties provided that:\n\n  source code distributions include the above copyright notice, this\n  list of conditions and the following disclaimer;\n\n  binary distributions include the above copyright notice, this list\n  of conditions and the following disclaimer in their documentation.\n\nThis software is provided 'as is' with no explicit or implied warranties\nin respect of its operation, including, but not limited to, correctness\nand fitness for purpose.\n---------------------------------------------------------------------------\nIssue Date: 20/12/2007\n\n These subroutines implement multiple block AES modes for ECB, CBC, CFB,\n OFB and CTR encryption,  The code provides support for the VIA Advanced\n Cryptography Engine (ACE).\n\n NOTE: In the following subroutines, the AES contexts (ctx) must be\n 16 byte aligned if VIA ACE is being used\n*/\n\n#include <string.h>\n#include <assert.h>\n\n#include \"aesopt.h\"\n\n#if defined( AES_MODES )\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\n#if defined( _MSC_VER ) && ( _MSC_VER > 800 )\n#pragma intrinsic(memcpy)\n#endif\n\n#define BFR_BLOCKS      8\n\n/* These values are used to detect long word alignment in order to */\n/* speed up some buffer operations. This facility may not work on  */\n/* some machines so this define can be commented out if necessary  */\n\n#define FAST_BUFFER_OPERATIONS\n\n#define lp32(x)         ((uint_32t*)(x))\n\n#if defined( USE_VIA_ACE_IF_PRESENT )\n\n#include \"aes_via_ace.h\"\n\n#pragma pack(16)\n\naligned_array(unsigned long,    enc_gen_table, 12, 16) =    NEH_ENC_GEN_DATA;\naligned_array(unsigned long,   enc_load_table, 12, 16) =   NEH_ENC_LOAD_DATA;\naligned_array(unsigned long, enc_hybrid_table, 12, 16) = NEH_ENC_HYBRID_DATA;\naligned_array(unsigned long,    dec_gen_table, 12, 16) =    NEH_DEC_GEN_DATA;\naligned_array(unsigned long,   dec_load_table, 12, 16) =   NEH_DEC_LOAD_DATA;\naligned_array(unsigned long, dec_hybrid_table, 12, 16) = NEH_DEC_HYBRID_DATA;\n\n/* NOTE: These control word macros must only be used after  */\n/* a key has been set up because they depend on key size    */\n/* See the VIA ACE documentation for key type information   */\n/* and aes_via_ace.h for non-default NEH_KEY_TYPE values    */\n\n#ifndef NEH_KEY_TYPE\n#  define NEH_KEY_TYPE NEH_HYBRID\n#endif\n\n#if NEH_KEY_TYPE == NEH_LOAD\n#define kd_adr(c)   ((uint_8t*)(c)->ks)\n#elif NEH_KEY_TYPE == NEH_GENERATE\n#define kd_adr(c)   ((uint_8t*)(c)->ks + (c)->inf.b[0])\n#elif NEH_KEY_TYPE == NEH_HYBRID\n#define kd_adr(c)   ((uint_8t*)(c)->ks + ((c)->inf.b[0] == 160 ? 160 : 0))\n#else\n#error no key type defined for VIA ACE \n#endif\n\n#else\n\n#define aligned_array(type, name, no, stride) type name[no]\n#define aligned_auto(type, name, no, stride)  type name[no]\n\n#endif\n\n#if defined( _MSC_VER ) && _MSC_VER > 1200\n\n#define via_cwd(cwd, ty, dir, len) \\\n    unsigned long* cwd = (dir##_##ty##_table + ((len - 128) >> 4))\n\n#else\n\n#define via_cwd(cwd, ty, dir, len)              \\\n    aligned_auto(unsigned long, cwd, 4, 16);    \\\n    cwd[1] = cwd[2] = cwd[3] = 0;               \\\n    cwd[0] = neh_##dir##_##ty##_key(len)\n\n#endif\n\n/* test the code for detecting and setting pointer alignment */\n\nAES_RETURN aes_test_alignment_detection(unsigned int n)\t/* 4 <= n <= 16 */\n{\tuint_8t\tp[16];\n    uint_32t i, count_eq = 0, count_neq = 0;\n\n    if(n < 4 || n > 16)\n        return EXIT_FAILURE;\n\n    for(i = 0; i < n; ++i)\n    {\n        uint_8t *qf = ALIGN_FLOOR(p + i, n),\n                *qh =  ALIGN_CEIL(p + i, n);\n        \n        if(qh == qf)\n            ++count_eq;\n        else if(qh == qf + n)\n            ++count_neq;\n        else\n            return EXIT_FAILURE;\n    }\n    return (count_eq != 1 || count_neq != n - 1 ? EXIT_FAILURE : EXIT_SUCCESS);\n}\n\nAES_RETURN aes_mode_reset(aes_encrypt_ctx ctx[1])\n{\n    ctx->inf.b[2] = 0;\n    return EXIT_SUCCESS;\n}\n\nAES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, const aes_encrypt_ctx ctx[1])\n{   int nb = len >> 4;\n\n    if(len & (AES_BLOCK_SIZE - 1))\n        return EXIT_FAILURE;\n\n#if defined( USE_VIA_ACE_IF_PRESENT )\n\n    if(ctx->inf.b[1] == 0xff)\n    {   uint_8t *ksp = (uint_8t*)(ctx->ks);\n        via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);\n\n        if(ALIGN_OFFSET( ctx, 16 ))\n            return EXIT_FAILURE;\n\n        if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))\n        {\n            via_ecb_op5(ksp, cwd, ibuf, obuf, nb);\n        }\n        else\n        {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);\n            uint_8t *ip, *op;\n\n            while(nb)\n            {\n                int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);\n\n                ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);\n                op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);\n\n                if(ip != ibuf)\n                    memcpy(buf, ibuf, m * AES_BLOCK_SIZE);\n\n                via_ecb_op5(ksp, cwd, ip, op, m);\n\n                if(op != obuf)\n                    memcpy(obuf, buf, m * AES_BLOCK_SIZE);\n\n                ibuf += m * AES_BLOCK_SIZE;\n                obuf += m * AES_BLOCK_SIZE;\n                nb -= m;\n            }\n        }\n\n        return EXIT_SUCCESS;\n    }\n\n#endif\n\n#if !defined( ASSUME_VIA_ACE_PRESENT )\n    while(nb--)\n    {\n        if(aes_encrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)\n            return EXIT_FAILURE;\n        ibuf += AES_BLOCK_SIZE;\n        obuf += AES_BLOCK_SIZE;\n    }\n#endif\n    return EXIT_SUCCESS;\n}\n\nAES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, const aes_decrypt_ctx ctx[1])\n{   int nb = len >> 4;\n\n    if(len & (AES_BLOCK_SIZE - 1))\n        return EXIT_FAILURE;\n\n#if defined( USE_VIA_ACE_IF_PRESENT )\n\n    if(ctx->inf.b[1] == 0xff)\n    {   uint_8t *ksp = kd_adr(ctx);\n        via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);\n\n        if(ALIGN_OFFSET( ctx, 16 ))\n            return EXIT_FAILURE;\n\n        if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))\n        {\n            via_ecb_op5(ksp, cwd, ibuf, obuf, nb);\n        }\n        else\n        {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);\n            uint_8t *ip, *op;\n\n            while(nb)\n            {\n                int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);\n\n                ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);\n                op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);\n\n                if(ip != ibuf)\n                    memcpy(buf, ibuf, m * AES_BLOCK_SIZE);\n\n                via_ecb_op5(ksp, cwd, ip, op, m);\n\n                if(op != obuf)\n                    memcpy(obuf, buf, m * AES_BLOCK_SIZE);\n\n                ibuf += m * AES_BLOCK_SIZE;\n                obuf += m * AES_BLOCK_SIZE;\n                nb -= m;\n            }\n        }\n\n        return EXIT_SUCCESS;\n    }\n\n#endif\n\n#if !defined( ASSUME_VIA_ACE_PRESENT )\n    while(nb--)\n    {\n        if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)\n            return EXIT_FAILURE;\n        ibuf += AES_BLOCK_SIZE;\n        obuf += AES_BLOCK_SIZE;\n    }\n#endif\n    return EXIT_SUCCESS;\n}\n\nAES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, unsigned char *iv, const aes_encrypt_ctx ctx[1])\n{   int nb = len >> 4;\n\n    if(len & (AES_BLOCK_SIZE - 1))\n        return EXIT_FAILURE;\n\n#if defined( USE_VIA_ACE_IF_PRESENT )\n\n    if(ctx->inf.b[1] == 0xff)\n    {   uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;\n        aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);\n        via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);\n\n        if(ALIGN_OFFSET( ctx, 16 ))\n            return EXIT_FAILURE;\n\n        if(ALIGN_OFFSET( iv, 16 ))   /* ensure an aligned iv */\n        {\n            ivp = liv;\n            memcpy(liv, iv, AES_BLOCK_SIZE);\n        }\n\n        if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ) && !ALIGN_OFFSET( iv, 16 ))\n        {\n            via_cbc_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp);\n        }\n        else\n        {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);\n            uint_8t *ip, *op;\n\n            while(nb)\n            {\n                int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);\n\n                ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);\n                op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);\n\n                if(ip != ibuf)\n                    memcpy(buf, ibuf, m * AES_BLOCK_SIZE);\n\n                via_cbc_op7(ksp, cwd, ip, op, m, ivp, ivp);\n\n                if(op != obuf)\n                    memcpy(obuf, buf, m * AES_BLOCK_SIZE);\n\n                ibuf += m * AES_BLOCK_SIZE;\n                obuf += m * AES_BLOCK_SIZE;\n                nb -= m;\n            }\n        }\n\n        if(iv != ivp)\n            memcpy(iv, ivp, AES_BLOCK_SIZE);\n\n        return EXIT_SUCCESS;\n    }\n\n#endif\n\n#if !defined( ASSUME_VIA_ACE_PRESENT )\n# ifdef FAST_BUFFER_OPERATIONS\n    if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))\n        while(nb--)\n        {\n            lp32(iv)[0] ^= lp32(ibuf)[0];\n            lp32(iv)[1] ^= lp32(ibuf)[1];\n            lp32(iv)[2] ^= lp32(ibuf)[2];\n            lp32(iv)[3] ^= lp32(ibuf)[3];\n            if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)\n                return EXIT_FAILURE;\n            memcpy(obuf, iv, AES_BLOCK_SIZE);\n            ibuf += AES_BLOCK_SIZE;\n            obuf += AES_BLOCK_SIZE;\n        }\n    else\n# endif\n        while(nb--)\n        {\n            iv[ 0] ^= ibuf[ 0]; iv[ 1] ^= ibuf[ 1];\n            iv[ 2] ^= ibuf[ 2]; iv[ 3] ^= ibuf[ 3];\n            iv[ 4] ^= ibuf[ 4]; iv[ 5] ^= ibuf[ 5];\n            iv[ 6] ^= ibuf[ 6]; iv[ 7] ^= ibuf[ 7];\n            iv[ 8] ^= ibuf[ 8]; iv[ 9] ^= ibuf[ 9];\n            iv[10] ^= ibuf[10]; iv[11] ^= ibuf[11];\n            iv[12] ^= ibuf[12]; iv[13] ^= ibuf[13];\n            iv[14] ^= ibuf[14]; iv[15] ^= ibuf[15];\n            if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)\n                return EXIT_FAILURE;\n            memcpy(obuf, iv, AES_BLOCK_SIZE);\n            ibuf += AES_BLOCK_SIZE;\n            obuf += AES_BLOCK_SIZE;\n        }\n#endif\n    return EXIT_SUCCESS;\n}\n\nAES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, unsigned char *iv, const aes_decrypt_ctx ctx[1])\n{   unsigned char tmp[AES_BLOCK_SIZE];\n    int nb = len >> 4;\n\n    if(len & (AES_BLOCK_SIZE - 1))\n        return EXIT_FAILURE;\n\n#if defined( USE_VIA_ACE_IF_PRESENT )\n\n    if(ctx->inf.b[1] == 0xff)\n    {   uint_8t *ksp = kd_adr(ctx), *ivp = iv;\n        aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);\n        via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);\n\n        if(ALIGN_OFFSET( ctx, 16 ))\n            return EXIT_FAILURE;\n\n        if(ALIGN_OFFSET( iv, 16 ))   /* ensure an aligned iv */\n        {\n            ivp = liv;\n            memcpy(liv, iv, AES_BLOCK_SIZE);\n        }\n\n        if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ) && !ALIGN_OFFSET( iv, 16 ))\n        {\n            via_cbc_op6(ksp, cwd, ibuf, obuf, nb, ivp);\n        }\n        else\n        {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);\n            uint_8t *ip, *op;\n\n            while(nb)\n            {\n                int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);\n\n                ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);\n                op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);\n\n                if(ip != ibuf)\n                    memcpy(buf, ibuf, m * AES_BLOCK_SIZE);\n\n                via_cbc_op6(ksp, cwd, ip, op, m, ivp);\n\n                if(op != obuf)\n                    memcpy(obuf, buf, m * AES_BLOCK_SIZE);\n\n                ibuf += m * AES_BLOCK_SIZE;\n                obuf += m * AES_BLOCK_SIZE;\n                nb -= m;\n            }\n        }\n\n        if(iv != ivp)\n            memcpy(iv, ivp, AES_BLOCK_SIZE);\n\n        return EXIT_SUCCESS;\n    }\n#endif\n\n#if !defined( ASSUME_VIA_ACE_PRESENT )\n# ifdef FAST_BUFFER_OPERATIONS\n    if(!ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))\n        while(nb--)\n        {\n            memcpy(tmp, ibuf, AES_BLOCK_SIZE);\n            if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)\n                return EXIT_FAILURE;\n            lp32(obuf)[0] ^= lp32(iv)[0];\n            lp32(obuf)[1] ^= lp32(iv)[1];\n            lp32(obuf)[2] ^= lp32(iv)[2];\n            lp32(obuf)[3] ^= lp32(iv)[3];\n            memcpy(iv, tmp, AES_BLOCK_SIZE);\n            ibuf += AES_BLOCK_SIZE;\n            obuf += AES_BLOCK_SIZE;\n        }\n    else\n# endif\n        while(nb--)\n        {\n            memcpy(tmp, ibuf, AES_BLOCK_SIZE);\n            if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)\n                return EXIT_FAILURE;\n            obuf[ 0] ^= iv[ 0]; obuf[ 1] ^= iv[ 1];\n            obuf[ 2] ^= iv[ 2]; obuf[ 3] ^= iv[ 3];\n            obuf[ 4] ^= iv[ 4]; obuf[ 5] ^= iv[ 5];\n            obuf[ 6] ^= iv[ 6]; obuf[ 7] ^= iv[ 7];\n            obuf[ 8] ^= iv[ 8]; obuf[ 9] ^= iv[ 9];\n            obuf[10] ^= iv[10]; obuf[11] ^= iv[11];\n            obuf[12] ^= iv[12]; obuf[13] ^= iv[13];\n            obuf[14] ^= iv[14]; obuf[15] ^= iv[15];\n            memcpy(iv, tmp, AES_BLOCK_SIZE);\n            ibuf += AES_BLOCK_SIZE;\n            obuf += AES_BLOCK_SIZE;\n        }\n#endif\n    return EXIT_SUCCESS;\n}\n\nAES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, unsigned char *iv, aes_encrypt_ctx ctx[1])\n{   int cnt = 0, b_pos = (int)ctx->inf.b[2], nb;\n\n    if(b_pos)           /* complete any partial block   */\n    {\n        while(b_pos < AES_BLOCK_SIZE && cnt < len)\n        {\n            *obuf++ = (iv[b_pos++] ^= *ibuf++);\n            cnt++;\n        }\n\n        b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);\n    }\n\n    if((nb = (len - cnt) >> 4) != 0)    /* process whole blocks */\n    {\n#if defined( USE_VIA_ACE_IF_PRESENT )\n\n        if(ctx->inf.b[1] == 0xff)\n        {   int m;\n            uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;\n            aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);\n            via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);\n\n            if(ALIGN_OFFSET( ctx, 16 ))\n                return EXIT_FAILURE;\n\n            if(ALIGN_OFFSET( iv, 16 ))   /* ensure an aligned iv */\n            {\n                ivp = liv;\n                memcpy(liv, iv, AES_BLOCK_SIZE);\n            }\n\n            if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))\n            {\n                via_cfb_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp);\n                ibuf += nb * AES_BLOCK_SIZE;\n                obuf += nb * AES_BLOCK_SIZE;\n                cnt  += nb * AES_BLOCK_SIZE;\n            }\n            else    /* input, output or both are unaligned  */\n            {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);\n                uint_8t *ip, *op;\n\n                while(nb)\n                {\n                    m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m;\n\n                    ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);\n                    op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);\n\n                    if(ip != ibuf)\n                        memcpy(buf, ibuf, m * AES_BLOCK_SIZE);\n\n                    via_cfb_op7(ksp, cwd, ip, op, m, ivp, ivp);\n\n                    if(op != obuf)\n                        memcpy(obuf, buf, m * AES_BLOCK_SIZE);\n\n                    ibuf += m * AES_BLOCK_SIZE;\n                    obuf += m * AES_BLOCK_SIZE;\n                    cnt  += m * AES_BLOCK_SIZE;\n                }\n            }\n\n            if(ivp != iv)\n                memcpy(iv, ivp, AES_BLOCK_SIZE);\n        }\n#else\n# ifdef FAST_BUFFER_OPERATIONS\n        if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))\n            while(cnt + AES_BLOCK_SIZE <= len)\n            {\n                assert(b_pos == 0);\n                if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)\n                    return EXIT_FAILURE;\n                lp32(obuf)[0] = lp32(iv)[0] ^= lp32(ibuf)[0];\n                lp32(obuf)[1] = lp32(iv)[1] ^= lp32(ibuf)[1];\n                lp32(obuf)[2] = lp32(iv)[2] ^= lp32(ibuf)[2];\n                lp32(obuf)[3] = lp32(iv)[3] ^= lp32(ibuf)[3];\n                ibuf += AES_BLOCK_SIZE;\n                obuf += AES_BLOCK_SIZE;\n                cnt  += AES_BLOCK_SIZE;\n            }\n        else\n# endif\n            while(cnt + AES_BLOCK_SIZE <= len)\n            {\n                assert(b_pos == 0);\n                if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)\n                    return EXIT_FAILURE;\n                obuf[ 0] = iv[ 0] ^= ibuf[ 0]; obuf[ 1] = iv[ 1] ^= ibuf[ 1];\n                obuf[ 2] = iv[ 2] ^= ibuf[ 2]; obuf[ 3] = iv[ 3] ^= ibuf[ 3];\n                obuf[ 4] = iv[ 4] ^= ibuf[ 4]; obuf[ 5] = iv[ 5] ^= ibuf[ 5];\n                obuf[ 6] = iv[ 6] ^= ibuf[ 6]; obuf[ 7] = iv[ 7] ^= ibuf[ 7];\n                obuf[ 8] = iv[ 8] ^= ibuf[ 8]; obuf[ 9] = iv[ 9] ^= ibuf[ 9];\n                obuf[10] = iv[10] ^= ibuf[10]; obuf[11] = iv[11] ^= ibuf[11];\n                obuf[12] = iv[12] ^= ibuf[12]; obuf[13] = iv[13] ^= ibuf[13];\n                obuf[14] = iv[14] ^= ibuf[14]; obuf[15] = iv[15] ^= ibuf[15];\n                ibuf += AES_BLOCK_SIZE;\n                obuf += AES_BLOCK_SIZE;\n                cnt  += AES_BLOCK_SIZE;\n            }\n#endif\n    }\n\n    while(cnt < len)\n    {\n        if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)\n            return EXIT_FAILURE;\n\n        while(cnt < len && b_pos < AES_BLOCK_SIZE)\n        {\n            *obuf++ = (iv[b_pos++] ^= *ibuf++);\n            cnt++;\n        }\n\n        b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);\n    }\n\n    ctx->inf.b[2] = (uint_8t)b_pos;\n    return EXIT_SUCCESS;\n}\n\nAES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, unsigned char *iv, aes_encrypt_ctx ctx[1])\n{   int cnt = 0, b_pos = (int)ctx->inf.b[2], nb;\n\n    if(b_pos)           /* complete any partial block   */\n    {   uint_8t t;\n\n        while(b_pos < AES_BLOCK_SIZE && cnt < len)\n        {\n            t = *ibuf++;\n            *obuf++ = t ^ iv[b_pos];\n            iv[b_pos++] = t;\n            cnt++;\n        }\n\n        b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);\n    }\n\n    if((nb = (len - cnt) >> 4) != 0)    /* process whole blocks */\n    {\n#if defined( USE_VIA_ACE_IF_PRESENT )\n\n        if(ctx->inf.b[1] == 0xff)\n        {   int m;\n            uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;\n            aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);\n            via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);\n\n            if(ALIGN_OFFSET( ctx, 16 ))\n                return EXIT_FAILURE;\n\n            if(ALIGN_OFFSET( iv, 16 ))   /* ensure an aligned iv */\n            {\n                ivp = liv;\n                memcpy(liv, iv, AES_BLOCK_SIZE);\n            }\n\n            if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))\n            {\n                via_cfb_op6(ksp, cwd, ibuf, obuf, nb, ivp);\n                ibuf += nb * AES_BLOCK_SIZE;\n                obuf += nb * AES_BLOCK_SIZE;\n                cnt  += nb * AES_BLOCK_SIZE;\n            }\n            else    /* input, output or both are unaligned  */\n            {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);\n                uint_8t *ip, *op;\n\n                while(nb)\n                {\n                    m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m;\n\n                    ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);\n                    op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);\n\n                    if(ip != ibuf)  /* input buffer is not aligned */\n                        memcpy(buf, ibuf, m * AES_BLOCK_SIZE);\n\n                    via_cfb_op6(ksp, cwd, ip, op, m, ivp);\n\n                    if(op != obuf)  /* output buffer is not aligned */\n                        memcpy(obuf, buf, m * AES_BLOCK_SIZE);\n\n                    ibuf += m * AES_BLOCK_SIZE;\n                    obuf += m * AES_BLOCK_SIZE;\n                    cnt  += m * AES_BLOCK_SIZE;\n                }\n            }\n\n            if(ivp != iv)\n                memcpy(iv, ivp, AES_BLOCK_SIZE);\n        }\n#else\n# ifdef FAST_BUFFER_OPERATIONS\n        if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) &&!ALIGN_OFFSET( iv, 4 ))\n            while(cnt + AES_BLOCK_SIZE <= len)\n            {   uint_32t t;\n\n                assert(b_pos == 0);\n                if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)\n                    return EXIT_FAILURE;\n                t = lp32(ibuf)[0], lp32(obuf)[0] = t ^ lp32(iv)[0], lp32(iv)[0] = t;\n                t = lp32(ibuf)[1], lp32(obuf)[1] = t ^ lp32(iv)[1], lp32(iv)[1] = t;\n                t = lp32(ibuf)[2], lp32(obuf)[2] = t ^ lp32(iv)[2], lp32(iv)[2] = t;\n                t = lp32(ibuf)[3], lp32(obuf)[3] = t ^ lp32(iv)[3], lp32(iv)[3] = t;\n                ibuf += AES_BLOCK_SIZE;\n                obuf += AES_BLOCK_SIZE;\n                cnt  += AES_BLOCK_SIZE;\n            }\n        else\n# endif\n            while(cnt + AES_BLOCK_SIZE <= len)\n            {   uint_8t t;\n\n                assert(b_pos == 0);\n                if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)\n                    return EXIT_FAILURE;\n                t = ibuf[ 0], obuf[ 0] = t ^ iv[ 0], iv[ 0] = t;\n                t = ibuf[ 1], obuf[ 1] = t ^ iv[ 1], iv[ 1] = t;\n                t = ibuf[ 2], obuf[ 2] = t ^ iv[ 2], iv[ 2] = t;\n                t = ibuf[ 3], obuf[ 3] = t ^ iv[ 3], iv[ 3] = t;\n                t = ibuf[ 4], obuf[ 4] = t ^ iv[ 4], iv[ 4] = t;\n                t = ibuf[ 5], obuf[ 5] = t ^ iv[ 5], iv[ 5] = t;\n                t = ibuf[ 6], obuf[ 6] = t ^ iv[ 6], iv[ 6] = t;\n                t = ibuf[ 7], obuf[ 7] = t ^ iv[ 7], iv[ 7] = t;\n                t = ibuf[ 8], obuf[ 8] = t ^ iv[ 8], iv[ 8] = t;\n                t = ibuf[ 9], obuf[ 9] = t ^ iv[ 9], iv[ 9] = t;\n                t = ibuf[10], obuf[10] = t ^ iv[10], iv[10] = t;\n                t = ibuf[11], obuf[11] = t ^ iv[11], iv[11] = t;\n                t = ibuf[12], obuf[12] = t ^ iv[12], iv[12] = t;\n                t = ibuf[13], obuf[13] = t ^ iv[13], iv[13] = t;\n                t = ibuf[14], obuf[14] = t ^ iv[14], iv[14] = t;\n                t = ibuf[15], obuf[15] = t ^ iv[15], iv[15] = t;\n                ibuf += AES_BLOCK_SIZE;\n                obuf += AES_BLOCK_SIZE;\n                cnt  += AES_BLOCK_SIZE;\n            }\n#endif\n    }\n\n    while(cnt < len)\n    {   uint_8t t;\n\n        if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)\n            return EXIT_FAILURE;\n\n        while(cnt < len && b_pos < AES_BLOCK_SIZE)\n        {\n            t = *ibuf++;\n            *obuf++ = t ^ iv[b_pos];\n            iv[b_pos++] = t;\n            cnt++;\n        }\n\n        b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);\n    }\n\n    ctx->inf.b[2] = (uint_8t)b_pos;\n    return EXIT_SUCCESS;\n}\n\nAES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,\n                    int len, unsigned char *iv, aes_encrypt_ctx ctx[1])\n{   int cnt = 0, b_pos = (int)ctx->inf.b[2], nb;\n\n    if(b_pos)           /* complete any partial block   */\n    {\n        while(b_pos < AES_BLOCK_SIZE && cnt < len)\n        {\n            *obuf++ = iv[b_pos++] ^ *ibuf++;\n            cnt++;\n        }\n\n        b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);\n    }\n\n    if((nb = (len - cnt) >> 4) != 0)   /* process whole blocks */\n    {\n#if defined( USE_VIA_ACE_IF_PRESENT )\n\n        if(ctx->inf.b[1] == 0xff)\n        {   int m;\n            uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;\n            aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);\n            via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);\n\n            if(ALIGN_OFFSET( ctx, 16 ))\n                return EXIT_FAILURE;\n\n            if(ALIGN_OFFSET( iv, 16 ))   /* ensure an aligned iv */\n            {\n                ivp = liv;\n                memcpy(liv, iv, AES_BLOCK_SIZE);\n            }\n\n            if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))\n            {\n                via_ofb_op6(ksp, cwd, ibuf, obuf, nb, ivp);\n                ibuf += nb * AES_BLOCK_SIZE;\n                obuf += nb * AES_BLOCK_SIZE;\n                cnt  += nb * AES_BLOCK_SIZE;\n            }\n            else    /* input, output or both are unaligned  */\n        {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);\n            uint_8t *ip, *op;\n\n                while(nb)\n                {\n                    m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m;\n\n                    ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);\n                    op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);\n\n                    if(ip != ibuf)\n                        memcpy(buf, ibuf, m * AES_BLOCK_SIZE);\n\n                    via_ofb_op6(ksp, cwd, ip, op, m, ivp);\n\n                    if(op != obuf)\n                        memcpy(obuf, buf, m * AES_BLOCK_SIZE);\n\n                    ibuf += m * AES_BLOCK_SIZE;\n                    obuf += m * AES_BLOCK_SIZE;\n                    cnt  += m * AES_BLOCK_SIZE;\n                }\n            }\n\n            if(ivp != iv)\n                memcpy(iv, ivp, AES_BLOCK_SIZE);\n        }\n#else\n# ifdef FAST_BUFFER_OPERATIONS\n        if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))\n            while(cnt + AES_BLOCK_SIZE <= len)\n            {\n                assert(b_pos == 0);\n                if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)\n                    return EXIT_FAILURE;\n                lp32(obuf)[0] = lp32(iv)[0] ^ lp32(ibuf)[0];\n                lp32(obuf)[1] = lp32(iv)[1] ^ lp32(ibuf)[1];\n                lp32(obuf)[2] = lp32(iv)[2] ^ lp32(ibuf)[2];\n                lp32(obuf)[3] = lp32(iv)[3] ^ lp32(ibuf)[3];\n                ibuf += AES_BLOCK_SIZE;\n                obuf += AES_BLOCK_SIZE;\n                cnt  += AES_BLOCK_SIZE;\n            }\n        else\n# endif\n            while(cnt + AES_BLOCK_SIZE <= len)\n            {\n                assert(b_pos == 0);\n                if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)\n                    return EXIT_FAILURE;\n                obuf[ 0] = iv[ 0] ^ ibuf[ 0]; obuf[ 1] = iv[ 1] ^ ibuf[ 1];\n                obuf[ 2] = iv[ 2] ^ ibuf[ 2]; obuf[ 3] = iv[ 3] ^ ibuf[ 3];\n                obuf[ 4] = iv[ 4] ^ ibuf[ 4]; obuf[ 5] = iv[ 5] ^ ibuf[ 5];\n                obuf[ 6] = iv[ 6] ^ ibuf[ 6]; obuf[ 7] = iv[ 7] ^ ibuf[ 7];\n                obuf[ 8] = iv[ 8] ^ ibuf[ 8]; obuf[ 9] = iv[ 9] ^ ibuf[ 9];\n                obuf[10] = iv[10] ^ ibuf[10]; obuf[11] = iv[11] ^ ibuf[11];\n                obuf[12] = iv[12] ^ ibuf[12]; obuf[13] = iv[13] ^ ibuf[13];\n                obuf[14] = iv[14] ^ ibuf[14]; obuf[15] = iv[15] ^ ibuf[15];\n                ibuf += AES_BLOCK_SIZE;\n                obuf += AES_BLOCK_SIZE;\n                cnt  += AES_BLOCK_SIZE;\n            }\n#endif\n    }\n\n    while(cnt < len)\n    {\n        if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)\n            return EXIT_FAILURE;\n\n        while(cnt < len && b_pos < AES_BLOCK_SIZE)\n        {\n            *obuf++ = iv[b_pos++] ^ *ibuf++;\n            cnt++;\n        }\n\n        b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);\n    }\n\n    ctx->inf.b[2] = (uint_8t)b_pos;\n    return EXIT_SUCCESS;\n}\n\n#define BFR_LENGTH  (BFR_BLOCKS * AES_BLOCK_SIZE)\n\nAES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,\n            int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx ctx[1])\n{   unsigned char   *ip;\n    int             i, blen, b_pos = (int)(ctx->inf.b[2]);\n\n#if defined( USE_VIA_ACE_IF_PRESENT )\n    aligned_auto(uint_8t, buf, BFR_LENGTH, 16);\n    if(ctx->inf.b[1] == 0xff && ALIGN_OFFSET( ctx, 16 ))\n        return EXIT_FAILURE;\n#else\n    uint_8t buf[BFR_LENGTH];\n#endif\n\n    if(b_pos)\n    {\n        memcpy(buf, cbuf, AES_BLOCK_SIZE);\n        if(aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)\n            return EXIT_FAILURE;\n\n        while(b_pos < AES_BLOCK_SIZE && len)\n        {\n            *obuf++ = *ibuf++ ^ buf[b_pos++];\n            --len;\n        }\n\n        if(len)\n            ctr_inc(cbuf), b_pos = 0;\n    }\n\n    while(len)\n    {\n        blen = (len > BFR_LENGTH ? BFR_LENGTH : len), len -= blen;\n\n        for(i = 0, ip = buf; i < (blen >> 4); ++i)\n        {\n            memcpy(ip, cbuf, AES_BLOCK_SIZE);\n            ctr_inc(cbuf);\n            ip += AES_BLOCK_SIZE;\n        }\n\n        if(blen & (AES_BLOCK_SIZE - 1))\n            memcpy(ip, cbuf, AES_BLOCK_SIZE), i++;\n\n#if defined( USE_VIA_ACE_IF_PRESENT )\n        if(ctx->inf.b[1] == 0xff)\n        {\n            via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);\n            via_ecb_op5((ctx->ks), cwd, buf, buf, i);\n        }\n        else\n#endif\n        if(aes_ecb_encrypt(buf, buf, i * AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)\n            return EXIT_FAILURE;\n\n        i = 0; ip = buf;\n# ifdef FAST_BUFFER_OPERATIONS\n        if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( ip, 4 ))\n            while(i + AES_BLOCK_SIZE <= blen)\n            {\n                lp32(obuf)[0] = lp32(ibuf)[0] ^ lp32(ip)[0];\n                lp32(obuf)[1] = lp32(ibuf)[1] ^ lp32(ip)[1];\n                lp32(obuf)[2] = lp32(ibuf)[2] ^ lp32(ip)[2];\n                lp32(obuf)[3] = lp32(ibuf)[3] ^ lp32(ip)[3];\n                i += AES_BLOCK_SIZE;\n                ip += AES_BLOCK_SIZE;\n                ibuf += AES_BLOCK_SIZE;\n                obuf += AES_BLOCK_SIZE;\n            }\n        else\n#endif\n            while(i + AES_BLOCK_SIZE <= blen)\n            {\n                obuf[ 0] = ibuf[ 0] ^ ip[ 0]; obuf[ 1] = ibuf[ 1] ^ ip[ 1];\n                obuf[ 2] = ibuf[ 2] ^ ip[ 2]; obuf[ 3] = ibuf[ 3] ^ ip[ 3];\n                obuf[ 4] = ibuf[ 4] ^ ip[ 4]; obuf[ 5] = ibuf[ 5] ^ ip[ 5];\n                obuf[ 6] = ibuf[ 6] ^ ip[ 6]; obuf[ 7] = ibuf[ 7] ^ ip[ 7];\n                obuf[ 8] = ibuf[ 8] ^ ip[ 8]; obuf[ 9] = ibuf[ 9] ^ ip[ 9];\n                obuf[10] = ibuf[10] ^ ip[10]; obuf[11] = ibuf[11] ^ ip[11];\n                obuf[12] = ibuf[12] ^ ip[12]; obuf[13] = ibuf[13] ^ ip[13];\n                obuf[14] = ibuf[14] ^ ip[14]; obuf[15] = ibuf[15] ^ ip[15];\n                i += AES_BLOCK_SIZE;\n                ip += AES_BLOCK_SIZE;\n                ibuf += AES_BLOCK_SIZE;\n                obuf += AES_BLOCK_SIZE;\n            }\n\n        while(i++ < blen)\n            *obuf++ = *ibuf++ ^ ip[b_pos++];\n    }\n\n    ctx->inf.b[2] = (uint_8t)b_pos;\n    return EXIT_SUCCESS;\n}\n\n#if defined(__cplusplus)\n}\n#endif\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/aescpp.h",
    "content": "/*\n---------------------------------------------------------------------------\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\n\nThe redistribution and use of this software (with or without changes)\nis allowed without the payment of fees or royalties provided that:\n\n  source code distributions include the above copyright notice, this\n  list of conditions and the following disclaimer;\n\n  binary distributions include the above copyright notice, this list\n  of conditions and the following disclaimer in their documentation.\n\nThis software is provided 'as is' with no explicit or implied warranties\nin respect of its operation, including, but not limited to, correctness\nand fitness for purpose.\n---------------------------------------------------------------------------\nIssue Date: 20/12/2007\n\n This file contains the definitions required to use AES (Rijndael) in C++.\n*/\n\n#ifndef _AESCPP_H\n#define _AESCPP_H\n\n#include \"aes.h\"\n\n#if defined( AES_ENCRYPT )\n\nclass AESencrypt\n{\npublic:\n    aes_encrypt_ctx cx[1];\n    AESencrypt(void) { aes_init_zrtp(); };\n#if defined(AES_128)\n    AESencrypt(const unsigned char key[])\n        {   aes_encrypt_key128(key, cx); }\n    AES_RETURN key128(const unsigned char key[])\n        {   return aes_encrypt_key128(key, cx); }\n#endif\n#if defined(AES_192)\n    AES_RETURN key192(const unsigned char key[])\n        {   return aes_encrypt_key192(key, cx); }\n#endif\n#if defined(AES_256)\n    AES_RETURN key256(const unsigned char key[])\n        {   return aes_encrypt_key256(key, cx); }\n#endif\n#if defined(AES_VAR)\n    AES_RETURN key(const unsigned char key[], int key_len)\n        {   return aes_encrypt_key(key, key_len, cx); }\n#endif\n    AES_RETURN encrypt(const unsigned char in[], unsigned char out[]) const\n        {   return aes_encrypt(in, out, cx);  }\n#ifndef AES_MODES\n    AES_RETURN ecb_encrypt(const unsigned char in[], unsigned char out[], int nb) const\n        {   while(nb--)\n            {   aes_encrypt(in, out, cx), in += AES_BLOCK_SIZE, out += AES_BLOCK_SIZE; }\n        }\n#endif\n#ifdef AES_MODES\n    AES_RETURN mode_reset(void)   { return aes_mode_reset(cx); }\n\n    AES_RETURN ecb_encrypt(const unsigned char in[], unsigned char out[], int nb) const\n        {   return aes_ecb_encrypt(in, out, nb, cx);  }\n\n    AES_RETURN cbc_encrypt(const unsigned char in[], unsigned char out[], int nb,\n                                    unsigned char iv[]) const\n        {   return aes_cbc_encrypt(in, out, nb, iv, cx);  }\n\n    AES_RETURN cfb_encrypt(const unsigned char in[], unsigned char out[], int nb,\n                                    unsigned char iv[])\n        {   return aes_cfb_encrypt(in, out, nb, iv, cx);  }\n\n    AES_RETURN cfb_decrypt(const unsigned char in[], unsigned char out[], int nb,\n                                    unsigned char iv[])\n        {   return aes_cfb_decrypt(in, out, nb, iv, cx);  }\n\n    AES_RETURN ofb_crypt(const unsigned char in[], unsigned char out[], int nb,\n                                    unsigned char iv[])\n        {   return aes_ofb_crypt(in, out, nb, iv, cx);  }\n\n    typedef void ctr_fn(unsigned char ctr[]);\n\n    AES_RETURN ctr_crypt(const unsigned char in[], unsigned char out[], int nb,\n                                    unsigned char iv[], ctr_fn cf)\n        {   return aes_ctr_crypt(in, out, nb, iv, cf, cx);  }\n\n#endif\n\n};\n\n#endif\n\n#if defined( AES_DECRYPT )\n\nclass AESdecrypt\n{\npublic:\n    aes_decrypt_ctx cx[1];\n    AESdecrypt(void) { aes_init_zrtp(); };\n#if defined(AES_128)\n    AESdecrypt(const unsigned char key[])\n            { aes_decrypt_key128(key, cx); }\n    AES_RETURN key128(const unsigned char key[])\n            { return aes_decrypt_key128(key, cx); }\n#endif\n#if defined(AES_192)\n    AES_RETURN key192(const unsigned char key[])\n            { return aes_decrypt_key192(key, cx); }\n#endif\n#if defined(AES_256)\n    AES_RETURN key256(const unsigned char key[])\n            { return aes_decrypt_key256(key, cx); }\n#endif\n#if defined(AES_VAR)\n    AES_RETURN key(const unsigned char key[], int key_len)\n            { return aes_decrypt_key(key, key_len, cx); }\n#endif\n    AES_RETURN decrypt(const unsigned char in[], unsigned char out[]) const\n        {   return aes_decrypt(in, out, cx);  }\n#ifndef AES_MODES\n    AES_RETURN ecb_decrypt(const unsigned char in[], unsigned char out[], int nb) const\n        {   while(nb--)\n            {   aes_decrypt(in, out, cx), in += AES_BLOCK_SIZE, out += AES_BLOCK_SIZE; }\n        }\n#endif\n#ifdef AES_MODES\n\n    AES_RETURN ecb_decrypt(const unsigned char in[], unsigned char out[], int nb) const\n        {   return aes_ecb_decrypt(in, out, nb, cx);  }\n\n    AES_RETURN cbc_decrypt(const unsigned char in[], unsigned char out[], int nb,\n                                    unsigned char iv[]) const\n        {   return aes_cbc_decrypt(in, out, nb, iv, cx);  }\n#endif\n};\n\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/aescrypt.c",
    "content": "/*\n---------------------------------------------------------------------------\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\n\nThe redistribution and use of this software (with or without changes)\nis allowed without the payment of fees or royalties provided that:\n\n  source code distributions include the above copyright notice, this\n  list of conditions and the following disclaimer;\n\n  binary distributions include the above copyright notice, this list\n  of conditions and the following disclaimer in their documentation.\n\nThis software is provided 'as is' with no explicit or implied warranties\nin respect of its operation, including, but not limited to, correctness\nand fitness for purpose.\n---------------------------------------------------------------------------\nIssue Date: 20/12/2007\n*/\n\n#include \"aesopt.h\"\n#include \"aestab.h\"\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\n#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])\n#define so(y,x,c)   word_out(y, c, s(x,c))\n\n#if defined(ARRAYS)\n#define locals(y,x)     x[4],y[4]\n#else\n#define locals(y,x)     x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3\n#endif\n\n#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \\\n                        s(y,2) = s(x,2); s(y,3) = s(x,3);\n#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)\n#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)\n#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)\n\n#if ( FUNCS_IN_C & ENCRYPTION_IN_C )\n\n/* Visual C++ .Net v7.1 provides the fastest encryption code when using\n   Pentium optimiation with small code but this is poor for decryption\n   so we need to control this with the following VC++ pragmas\n*/\n\n#if defined( _MSC_VER ) && !defined( _WIN64 )\n#pragma optimize( \"s\", on )\n#endif\n\n/* Given the column (c) of the output state variable, the following\n   macros give the input state variables which are needed in its\n   computation for each row (r) of the state. All the alternative\n   macros give the same end values but expand into different ways\n   of calculating these values.  In particular the complex macro\n   used for dynamically variable block sizes is designed to expand\n   to a compile time constant whenever possible but will expand to\n   conditional clauses on some branches (I am grateful to Frank\n   Yellin for this construction)\n*/\n\n#define fwd_var(x,r,c)\\\n ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\\\n : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\\\n : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\\\n :          ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))\n\n#if defined(FT4_SET)\n#undef  dec_fmvars\n#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))\n#elif defined(FT1_SET)\n#undef  dec_fmvars\n#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))\n#else\n#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))\n#endif\n\n#if defined(FL4_SET)\n#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))\n#elif defined(FL1_SET)\n#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))\n#else\n#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))\n#endif\n\nAES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])\n{   uint_32t         locals(b0, b1);\n    const uint_32t   *kp;\n#if defined( dec_fmvars )\n    dec_fmvars; /* declare variables for fwd_mcol() if needed */\n#endif\n\n    if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )\n        return EXIT_FAILURE;\n\n    kp = cx->ks;\n    state_in(b0, in, kp);\n\n#if (ENC_UNROLL == FULL)\n\n    switch(cx->inf.b[0])\n    {\n    case 14 * 16:\n        round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);\n        round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);\n        kp += 2 * N_COLS;\n    case 12 * 16:\n        round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);\n        round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);\n        kp += 2 * N_COLS;\n    case 10 * 16:\n        round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);\n        round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);\n        round(fwd_rnd,  b1, b0, kp + 3 * N_COLS);\n        round(fwd_rnd,  b0, b1, kp + 4 * N_COLS);\n        round(fwd_rnd,  b1, b0, kp + 5 * N_COLS);\n        round(fwd_rnd,  b0, b1, kp + 6 * N_COLS);\n        round(fwd_rnd,  b1, b0, kp + 7 * N_COLS);\n        round(fwd_rnd,  b0, b1, kp + 8 * N_COLS);\n        round(fwd_rnd,  b1, b0, kp + 9 * N_COLS);\n        round(fwd_lrnd, b0, b1, kp +10 * N_COLS);\n    }\n\n#else\n\n#if (ENC_UNROLL == PARTIAL)\n    {   uint_32t    rnd;\n        for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)\n        {\n            kp += N_COLS;\n            round(fwd_rnd, b1, b0, kp);\n            kp += N_COLS;\n            round(fwd_rnd, b0, b1, kp);\n        }\n        kp += N_COLS;\n        round(fwd_rnd,  b1, b0, kp);\n#else\n    {   uint_32t    rnd;\n        for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)\n        {\n            kp += N_COLS;\n            round(fwd_rnd, b1, b0, kp);\n            l_copy(b0, b1);\n        }\n#endif\n        kp += N_COLS;\n        round(fwd_lrnd, b0, b1, kp);\n    }\n#endif\n\n    state_out(out, b0);\n    return EXIT_SUCCESS;\n}\n\n#endif\n\n#if ( FUNCS_IN_C & DECRYPTION_IN_C)\n\n/* Visual C++ .Net v7.1 provides the fastest encryption code when using\n   Pentium optimiation with small code but this is poor for decryption\n   so we need to control this with the following VC++ pragmas\n*/\n\n#if defined( _MSC_VER ) && !defined( _WIN64 )\n#pragma optimize( \"t\", on )\n#endif\n\n/* Given the column (c) of the output state variable, the following\n   macros give the input state variables which are needed in its\n   computation for each row (r) of the state. All the alternative\n   macros give the same end values but expand into different ways\n   of calculating these values.  In particular the complex macro\n   used for dynamically variable block sizes is designed to expand\n   to a compile time constant whenever possible but will expand to\n   conditional clauses on some branches (I am grateful to Frank\n   Yellin for this construction)\n*/\n\n#define inv_var(x,r,c)\\\n ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\\\n : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\\\n : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\\\n :          ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))\n\n#if defined(IT4_SET)\n#undef  dec_imvars\n#define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))\n#elif defined(IT1_SET)\n#undef  dec_imvars\n#define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))\n#else\n#define inv_rnd(y,x,k,c)    (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))\n#endif\n\n#if defined(IL4_SET)\n#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))\n#elif defined(IL1_SET)\n#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))\n#else\n#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))\n#endif\n\n/* This code can work with the decryption key schedule in the   */\n/* order that is used for encrytpion (where the 1st decryption  */\n/* round key is at the high end ot the schedule) or with a key  */\n/* schedule that has been reversed to put the 1st decryption    */\n/* round key at the low end of the schedule in memory (when     */\n/* AES_REV_DKS is defined)                                      */\n\n#ifdef AES_REV_DKS\n#define key_ofs     0\n#define rnd_key(n)  (kp + n * N_COLS)\n#else\n#define key_ofs     1\n#define rnd_key(n)  (kp - n * N_COLS)\n#endif\n\nAES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])\n{   uint_32t        locals(b0, b1);\n#if defined( dec_imvars )\n    dec_imvars; /* declare variables for inv_mcol() if needed */\n#endif\n    const uint_32t *kp;\n\n    if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )\n        return EXIT_FAILURE;\n\n    kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);\n    state_in(b0, in, kp);\n\n#if (DEC_UNROLL == FULL)\n\n    kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));\n    switch(cx->inf.b[0])\n    {\n    case 14 * 16:\n        round(inv_rnd,  b1, b0, rnd_key(-13));\n        round(inv_rnd,  b0, b1, rnd_key(-12));\n    case 12 * 16:\n        round(inv_rnd,  b1, b0, rnd_key(-11));\n        round(inv_rnd,  b0, b1, rnd_key(-10));\n    case 10 * 16:\n        round(inv_rnd,  b1, b0, rnd_key(-9));\n        round(inv_rnd,  b0, b1, rnd_key(-8));\n        round(inv_rnd,  b1, b0, rnd_key(-7));\n        round(inv_rnd,  b0, b1, rnd_key(-6));\n        round(inv_rnd,  b1, b0, rnd_key(-5));\n        round(inv_rnd,  b0, b1, rnd_key(-4));\n        round(inv_rnd,  b1, b0, rnd_key(-3));\n        round(inv_rnd,  b0, b1, rnd_key(-2));\n        round(inv_rnd,  b1, b0, rnd_key(-1));\n        round(inv_lrnd, b0, b1, rnd_key( 0));\n    }\n\n#else\n\n#if (DEC_UNROLL == PARTIAL)\n    {   uint_32t    rnd;\n        for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)\n        {\n            kp = rnd_key(1);\n            round(inv_rnd, b1, b0, kp);\n            kp = rnd_key(1);\n            round(inv_rnd, b0, b1, kp);\n        }\n        kp = rnd_key(1);\n        round(inv_rnd, b1, b0, kp);\n#else\n    {   uint_32t    rnd;\n        for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)\n        {\n            kp = rnd_key(1);\n            round(inv_rnd, b1, b0, kp);\n            l_copy(b0, b1);\n        }\n#endif\n        kp = rnd_key(1);\n        round(inv_lrnd, b0, b1, kp);\n        }\n#endif\n\n    state_out(out, b0);\n    return EXIT_SUCCESS;\n}\n\n#endif\n\n#if defined(__cplusplus)\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/aeskey.c",
    "content": "/*\n---------------------------------------------------------------------------\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\n\nThe redistribution and use of this software (with or without changes)\nis allowed without the payment of fees or royalties provided that:\n\n  source code distributions include the above copyright notice, this\n  list of conditions and the following disclaimer;\n\n  binary distributions include the above copyright notice, this list\n  of conditions and the following disclaimer in their documentation.\n\nThis software is provided 'as is' with no explicit or implied warranties\nin respect of its operation, including, but not limited to, correctness\nand fitness for purpose.\n---------------------------------------------------------------------------\nIssue Date: 20/12/2007\n*/\n\n#include \"aesopt.h\"\n#include \"aestab.h\"\n\n/*\n#ifdef USE_VIA_ACE_IF_PRESENT\n#  include \"aes_via_ace.h\"\n#endif\n*/\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\n/* Initialise the key schedule from the user supplied key. The key\n   length can be specified in bytes, with legal values of 16, 24\n   and 32, or in bits, with legal values of 128, 192 and 256. These\n   values correspond with Nk values of 4, 6 and 8 respectively.\n\n   The following macros implement a single cycle in the key\n   schedule generation process. The number of cycles needed\n   for each cx->n_col and nk value is:\n\n    nk =             4  5  6  7  8\n    ------------------------------\n    cx->n_col = 4   10  9  8  7  7\n    cx->n_col = 5   14 11 10  9  9\n    cx->n_col = 6   19 15 12 11 11\n    cx->n_col = 7   21 19 16 13 14\n    cx->n_col = 8   29 23 19 17 14\n*/\n\n#if defined( REDUCE_CODE_SIZE )\n#  define ls_box ls_sub\n   uint_32t ls_sub(const uint_32t t, const uint_32t n);\n#  define inv_mcol im_sub\n   uint_32t im_sub(const uint_32t x);\n#  ifdef ENC_KS_UNROLL\n#    undef ENC_KS_UNROLL\n#  endif\n#  ifdef DEC_KS_UNROLL\n#    undef DEC_KS_UNROLL\n#  endif\n#endif\n\n#if (FUNCS_IN_C & ENC_KEYING_IN_C)\n\n#if defined(AES_128) || defined( AES_VAR )\n\n#define ke4(k,i) \\\n{   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \\\n    k[4*(i)+5] = ss[1] ^= ss[0]; \\\n    k[4*(i)+6] = ss[2] ^= ss[1]; \\\n    k[4*(i)+7] = ss[3] ^= ss[2]; \\\n}\n\nAES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])\n{   uint_32t    ss[4];\n\n    cx->ks[0] = ss[0] = word_in(key, 0);\n    cx->ks[1] = ss[1] = word_in(key, 1);\n    cx->ks[2] = ss[2] = word_in(key, 2);\n    cx->ks[3] = ss[3] = word_in(key, 3);\n\n#ifdef ENC_KS_UNROLL\n    ke4(cx->ks, 0);  ke4(cx->ks, 1);\n    ke4(cx->ks, 2);  ke4(cx->ks, 3);\n    ke4(cx->ks, 4);  ke4(cx->ks, 5);\n    ke4(cx->ks, 6);  ke4(cx->ks, 7);\n    ke4(cx->ks, 8);\n#else\n    {   uint_32t i;\n        for(i = 0; i < 9; ++i)\n            ke4(cx->ks, i);\n    }\n#endif\n    ke4(cx->ks, 9);\n    cx->inf.l = 0;\n    cx->inf.b[0] = 10 * 16;\n\n#ifdef USE_VIA_ACE_IF_PRESENT\n    if(VIA_ACE_AVAILABLE)\n        cx->inf.b[1] = 0xff;\n#endif\n    return EXIT_SUCCESS;\n}\n\n#endif\n\n#if defined(AES_192) || defined( AES_VAR )\n\n#define kef6(k,i) \\\n{   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \\\n    k[6*(i)+ 7] = ss[1] ^= ss[0]; \\\n    k[6*(i)+ 8] = ss[2] ^= ss[1]; \\\n    k[6*(i)+ 9] = ss[3] ^= ss[2]; \\\n}\n\n#define ke6(k,i) \\\n{   kef6(k,i); \\\n    k[6*(i)+10] = ss[4] ^= ss[3]; \\\n    k[6*(i)+11] = ss[5] ^= ss[4]; \\\n}\n\nAES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])\n{   uint_32t    ss[6];\n\n    cx->ks[0] = ss[0] = word_in(key, 0);\n    cx->ks[1] = ss[1] = word_in(key, 1);\n    cx->ks[2] = ss[2] = word_in(key, 2);\n    cx->ks[3] = ss[3] = word_in(key, 3);\n    cx->ks[4] = ss[4] = word_in(key, 4);\n    cx->ks[5] = ss[5] = word_in(key, 5);\n\n#ifdef ENC_KS_UNROLL\n    ke6(cx->ks, 0);  ke6(cx->ks, 1);\n    ke6(cx->ks, 2);  ke6(cx->ks, 3);\n    ke6(cx->ks, 4);  ke6(cx->ks, 5);\n    ke6(cx->ks, 6);\n#else\n    {   uint_32t i;\n        for(i = 0; i < 7; ++i)\n            ke6(cx->ks, i);\n    }\n#endif\n    kef6(cx->ks, 7);\n    cx->inf.l = 0;\n    cx->inf.b[0] = 12 * 16;\n\n#ifdef USE_VIA_ACE_IF_PRESENT\n    if(VIA_ACE_AVAILABLE)\n        cx->inf.b[1] = 0xff;\n#endif\n    return EXIT_SUCCESS;\n}\n\n#endif\n\n#if defined(AES_256) || defined( AES_VAR )\n\n#define kef8(k,i) \\\n{   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \\\n    k[8*(i)+ 9] = ss[1] ^= ss[0]; \\\n    k[8*(i)+10] = ss[2] ^= ss[1]; \\\n    k[8*(i)+11] = ss[3] ^= ss[2]; \\\n}\n\n#define ke8(k,i) \\\n{   kef8(k,i); \\\n    k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \\\n    k[8*(i)+13] = ss[5] ^= ss[4]; \\\n    k[8*(i)+14] = ss[6] ^= ss[5]; \\\n    k[8*(i)+15] = ss[7] ^= ss[6]; \\\n}\n\nAES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])\n{   uint_32t    ss[8];\n\n    cx->ks[0] = ss[0] = word_in(key, 0);\n    cx->ks[1] = ss[1] = word_in(key, 1);\n    cx->ks[2] = ss[2] = word_in(key, 2);\n    cx->ks[3] = ss[3] = word_in(key, 3);\n    cx->ks[4] = ss[4] = word_in(key, 4);\n    cx->ks[5] = ss[5] = word_in(key, 5);\n    cx->ks[6] = ss[6] = word_in(key, 6);\n    cx->ks[7] = ss[7] = word_in(key, 7);\n\n#ifdef ENC_KS_UNROLL\n    ke8(cx->ks, 0); ke8(cx->ks, 1);\n    ke8(cx->ks, 2); ke8(cx->ks, 3);\n    ke8(cx->ks, 4); ke8(cx->ks, 5);\n#else\n    {   uint_32t i;\n        for(i = 0; i < 6; ++i)\n            ke8(cx->ks,  i);\n    }\n#endif\n    kef8(cx->ks, 6);\n    cx->inf.l = 0;\n    cx->inf.b[0] = 14 * 16;\n\n#ifdef USE_VIA_ACE_IF_PRESENT\n    if(VIA_ACE_AVAILABLE)\n        cx->inf.b[1] = 0xff;\n#endif\n    return EXIT_SUCCESS;\n}\n\n#endif\n\n#if defined( AES_VAR )\n\nAES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])\n{   \n    switch(key_len)\n    {\n    case 16: case 128: return aes_encrypt_key128(key, cx);\n    case 24: case 192: return aes_encrypt_key192(key, cx);\n    case 32: case 256: return aes_encrypt_key256(key, cx);\n    default: return EXIT_FAILURE;\n    }\n}\n\n#endif\n\n#endif\n\n#if (FUNCS_IN_C & DEC_KEYING_IN_C)\n\n/* this is used to store the decryption round keys  */\n/* in forward or reverse order                      */\n\n#ifdef AES_REV_DKS\n#define v(n,i)  ((n) - (i) + 2 * ((i) & 3))\n#else\n#define v(n,i)  (i)\n#endif\n\n#if DEC_ROUND == NO_TABLES\n#define ff(x)   (x)\n#else\n#define ff(x)   inv_mcol(x)\n#if defined( dec_imvars )\n#define d_vars  dec_imvars\n#endif\n#endif\n\n#if defined(AES_128) || defined( AES_VAR )\n\n#define k4e(k,i) \\\n{   k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \\\n    k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \\\n    k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \\\n    k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \\\n}\n\n#if 1\n\n#define kdf4(k,i) \\\n{   ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \\\n    ss[1] = ss[1] ^ ss[3]; \\\n    ss[2] = ss[2] ^ ss[3]; \\\n    ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \\\n    ss[i % 4] ^= ss[4]; \\\n    ss[4] ^= k[v(40,(4*(i)))];   k[v(40,(4*(i))+4)] = ff(ss[4]); \\\n    ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \\\n    ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \\\n    ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \\\n}\n\n#define kd4(k,i) \\\n{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \\\n    ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \\\n    k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \\\n    k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \\\n    k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \\\n    k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \\\n}\n\n#define kdl4(k,i) \\\n{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \\\n    k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \\\n    k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \\\n    k[v(40,(4*(i))+6)] = ss[0]; \\\n    k[v(40,(4*(i))+7)] = ss[1]; \\\n}\n\n#else\n\n#define kdf4(k,i) \\\n{   ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \\\n    ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \\\n    ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \\\n    ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \\\n}\n\n#define kd4(k,i) \\\n{   ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \\\n    ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \\\n    ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \\\n    ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \\\n    ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \\\n}\n\n#define kdl4(k,i) \\\n{   ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \\\n    ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \\\n    ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \\\n    ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \\\n}\n\n#endif\n\nAES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])\n{   uint_32t    ss[5];\n#if defined( d_vars )\n        d_vars;\n#endif\n    cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);\n    cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);\n    cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);\n    cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);\n\n#ifdef DEC_KS_UNROLL\n     kdf4(cx->ks, 0); kd4(cx->ks, 1);\n     kd4(cx->ks, 2);  kd4(cx->ks, 3);\n     kd4(cx->ks, 4);  kd4(cx->ks, 5);\n     kd4(cx->ks, 6);  kd4(cx->ks, 7);\n     kd4(cx->ks, 8);  kdl4(cx->ks, 9);\n#else\n    {   uint_32t i;\n        for(i = 0; i < 10; ++i)\n            k4e(cx->ks, i);\n#if !(DEC_ROUND == NO_TABLES)\n        for(i = N_COLS; i < 10 * N_COLS; ++i)\n            cx->ks[i] = inv_mcol(cx->ks[i]);\n#endif\n    }\n#endif\n    cx->inf.l = 0;\n    cx->inf.b[0] = 10 * 16;\n\n#ifdef USE_VIA_ACE_IF_PRESENT\n    if(VIA_ACE_AVAILABLE)\n        cx->inf.b[1] = 0xff;\n#endif\n    return EXIT_SUCCESS;\n}\n\n#endif\n\n#if defined(AES_192) || defined( AES_VAR )\n\n#define k6ef(k,i) \\\n{   k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \\\n    k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \\\n    k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \\\n    k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \\\n}\n\n#define k6e(k,i) \\\n{   k6ef(k,i); \\\n    k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \\\n    k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \\\n}\n\n#define kdf6(k,i) \\\n{   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \\\n    ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \\\n    ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \\\n    ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \\\n    ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \\\n    ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \\\n}\n\n#define kd6(k,i) \\\n{   ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \\\n    ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \\\n    ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \\\n    ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \\\n    ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \\\n    ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \\\n    ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \\\n}\n\n#define kdl6(k,i) \\\n{   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \\\n    ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \\\n    ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \\\n    ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \\\n}\n\nAES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])\n{   uint_32t    ss[7];\n#if defined( d_vars )\n        d_vars;\n#endif\n    cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);\n    cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);\n    cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);\n    cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);\n\n#ifdef DEC_KS_UNROLL\n    cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));\n    cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));\n    kdf6(cx->ks, 0); kd6(cx->ks, 1);\n    kd6(cx->ks, 2);  kd6(cx->ks, 3);\n    kd6(cx->ks, 4);  kd6(cx->ks, 5);\n    kd6(cx->ks, 6);  kdl6(cx->ks, 7);\n#else\n    cx->ks[v(48,(4))] = ss[4] = word_in(key, 4);\n    cx->ks[v(48,(5))] = ss[5] = word_in(key, 5);\n    {   uint_32t i;\n\n        for(i = 0; i < 7; ++i)\n            k6e(cx->ks, i);\n        k6ef(cx->ks, 7);\n#if !(DEC_ROUND == NO_TABLES)\n        for(i = N_COLS; i < 12 * N_COLS; ++i)\n            cx->ks[i] = inv_mcol(cx->ks[i]);\n#endif\n    }\n#endif\n    cx->inf.l = 0;\n    cx->inf.b[0] = 12 * 16;\n\n#ifdef USE_VIA_ACE_IF_PRESENT\n    if(VIA_ACE_AVAILABLE)\n        cx->inf.b[1] = 0xff;\n#endif\n    return EXIT_SUCCESS;\n}\n\n#endif\n\n#if defined(AES_256) || defined( AES_VAR )\n\n#define k8ef(k,i) \\\n{   k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \\\n    k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \\\n    k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \\\n    k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \\\n}\n\n#define k8e(k,i) \\\n{   k8ef(k,i); \\\n    k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \\\n    k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \\\n    k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \\\n    k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \\\n}\n\n#define kdf8(k,i) \\\n{   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \\\n    ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \\\n    ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \\\n    ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \\\n    ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \\\n    ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \\\n    ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \\\n    ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \\\n}\n\n#define kd8(k,i) \\\n{   ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \\\n    ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \\\n    ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \\\n    ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \\\n    ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \\\n    ss[8] = ls_box(ss[3],0); \\\n    ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \\\n    ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \\\n    ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \\\n    ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \\\n}\n\n#define kdl8(k,i) \\\n{   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \\\n    ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \\\n    ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \\\n    ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \\\n}\n\nAES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])\n{   uint_32t    ss[9];\n#if defined( d_vars )\n        d_vars;\n#endif\n    cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);\n    cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);\n    cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);\n    cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);\n\n#ifdef DEC_KS_UNROLL\n    cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));\n    cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));\n    cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));\n    cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));\n    kdf8(cx->ks, 0); kd8(cx->ks, 1);\n    kd8(cx->ks, 2);  kd8(cx->ks, 3);\n    kd8(cx->ks, 4);  kd8(cx->ks, 5);\n    kdl8(cx->ks, 6);\n#else\n    cx->ks[v(56,(4))] = ss[4] = word_in(key, 4);\n    cx->ks[v(56,(5))] = ss[5] = word_in(key, 5);\n    cx->ks[v(56,(6))] = ss[6] = word_in(key, 6);\n    cx->ks[v(56,(7))] = ss[7] = word_in(key, 7);\n    {   uint_32t i;\n\n        for(i = 0; i < 6; ++i)\n            k8e(cx->ks,  i);\n        k8ef(cx->ks,  6);\n#if !(DEC_ROUND == NO_TABLES)\n        for(i = N_COLS; i < 14 * N_COLS; ++i)\n            cx->ks[i] = inv_mcol(cx->ks[i]);\n#endif\n    }\n#endif\n    cx->inf.l = 0;\n    cx->inf.b[0] = 14 * 16;\n\n#ifdef USE_VIA_ACE_IF_PRESENT\n    if(VIA_ACE_AVAILABLE)\n        cx->inf.b[1] = 0xff;\n#endif\n    return EXIT_SUCCESS;\n}\n\n#endif\n\n#if defined( AES_VAR )\n\nAES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])\n{\n    switch(key_len)\n    {\n    case 16: case 128: return aes_decrypt_key128(key, cx);\n    case 24: case 192: return aes_decrypt_key192(key, cx);\n    case 32: case 256: return aes_decrypt_key256(key, cx);\n    default: return EXIT_FAILURE;\n    }\n}\n\n#endif\n\n#endif\n\n#if defined(__cplusplus)\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/aesopt.h",
    "content": "/*\n---------------------------------------------------------------------------\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\n\nThe redistribution and use of this software (with or without changes)\nis allowed without the payment of fees or royalties provided that:\n\n  source code distributions include the above copyright notice, this\n  list of conditions and the following disclaimer;\n\n  binary distributions include the above copyright notice, this list\n  of conditions and the following disclaimer in their documentation.\n\nThis software is provided 'as is' with no explicit or implied warranties\nin respect of its operation, including, but not limited to, correctness\nand fitness for purpose.\n---------------------------------------------------------------------------\nIssue Date: 20/12/2007\n\n This file contains the compilation options for AES (Rijndael) and code\n that is common across encryption, key scheduling and table generation.\n\n OPERATION\n\n These source code files implement the AES algorithm Rijndael designed by\n Joan Daemen and Vincent Rijmen. This version is designed for the standard\n block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24\n and 32 bytes).\n\n This version is designed for flexibility and speed using operations on\n 32-bit words rather than operations on bytes.  It can be compiled with\n either big or little endian internal byte order but is faster when the\n native byte order for the processor is used.\n\n THE CIPHER INTERFACE\n\n The cipher interface is implemented as an array of bytes in which lower\n AES bit sequence indexes map to higher numeric significance within bytes.\n\n  uint_8t                 (an unsigned  8-bit type)\n  uint_32t                (an unsigned 32-bit type)\n  struct aes_encrypt_ctx  (structure for the cipher encryption context)\n  struct aes_decrypt_ctx  (structure for the cipher decryption context)\n  AES_RETURN                the function return type\n\n  C subroutine calls:\n\n  AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);\n  AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);\n  AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);\n  AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out,\n                                                  const aes_encrypt_ctx cx[1]);\n\n  AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);\n  AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);\n  AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);\n  AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out,\n                                                  const aes_decrypt_ctx cx[1]);\n\n IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that\n you call aes_init() before AES is used so that the tables are initialised.\n\n C++ aes class subroutines:\n\n     Class AESencrypt  for encryption\n\n      Construtors:\n          AESencrypt(void)\n          AESencrypt(const unsigned char *key) - 128 bit key\n      Members:\n          AES_RETURN key128(const unsigned char *key)\n          AES_RETURN key192(const unsigned char *key)\n          AES_RETURN key256(const unsigned char *key)\n          AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const\n\n      Class AESdecrypt  for encryption\n      Construtors:\n          AESdecrypt(void)\n          AESdecrypt(const unsigned char *key) - 128 bit key\n      Members:\n          AES_RETURN key128(const unsigned char *key)\n          AES_RETURN key192(const unsigned char *key)\n          AES_RETURN key256(const unsigned char *key)\n          AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const\n*/\n\n#if !defined( _AESOPT_H )\n#define _AESOPT_H\n\n#if defined( __cplusplus )\n#include \"aescpp.h\"\n#else\n#include \"aes.h\"\n#endif\n\n/*  PLATFORM SPECIFIC INCLUDES */\n\n#include \"brg_endian.h\"\n\n/*  CONFIGURATION - THE USE OF DEFINES\n\n    Later in this section there are a number of defines that control the\n    operation of the code.  In each section, the purpose of each define is\n    explained so that the relevant form can be included or excluded by\n    setting either 1's or 0's respectively on the branches of the related\n    #if clauses.  The following local defines should not be changed.\n*/\n\n#define ENCRYPTION_IN_C     1\n#define DECRYPTION_IN_C     2\n#define ENC_KEYING_IN_C     4\n#define DEC_KEYING_IN_C     8\n\n#define NO_TABLES           0\n#define ONE_TABLE           1\n#define FOUR_TABLES         4\n#define NONE                0\n#define PARTIAL             1\n#define FULL                2\n\n/*  --- START OF USER CONFIGURED OPTIONS --- */\n\n/*  1. BYTE ORDER WITHIN 32 BIT WORDS\n\n    The fundamental data processing units in Rijndael are 8-bit bytes. The\n    input, output and key input are all enumerated arrays of bytes in which\n    bytes are numbered starting at zero and increasing to one less than the\n    number of bytes in the array in question. This enumeration is only used\n    for naming bytes and does not imply any adjacency or order relationship\n    from one byte to another. When these inputs and outputs are considered\n    as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to\n    byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.\n    In this implementation bits are numbered from 0 to 7 starting at the\n    numerically least significant end of each byte (bit n represents 2^n).\n\n    However, Rijndael can be implemented more efficiently using 32-bit\n    words by packing bytes into words so that bytes 4*n to 4*n+3 are placed\n    into word[n]. While in principle these bytes can be assembled into words\n    in any positions, this implementation only supports the two formats in\n    which bytes in adjacent positions within words also have adjacent byte\n    numbers. This order is called big-endian if the lowest numbered bytes\n    in words have the highest numeric significance and little-endian if the\n    opposite applies.\n\n    This code can work in either order irrespective of the order used by the\n    machine on which it runs. Normally the internal byte order will be set\n    to the order of the processor on which the code is to be run but this\n    define can be used to reverse this in special situations\n\n    WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set.\n    This define will hence be redefined later (in section 4) if necessary\n*/\n\n#if 1\n#  define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER\n#elif 0\n#  define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN\n#elif 0\n#  define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN\n#else\n#  error The algorithm byte order is not defined\n#endif\n\n/*  2. VIA ACE SUPPORT */\n\n#if defined( __GNUC__ ) && defined( __i386__ ) \\\n || defined( _WIN32   ) && defined( _M_IX86  ) \\\n && !(defined( _WIN64 ) || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 ))\n#  define VIA_ACE_POSSIBLE\n#endif\n\n/*  Define this option if support for the VIA ACE is required. This uses\n    inline assembler instructions and is only implemented for the Microsoft,\n    Intel and GCC compilers.  If VIA ACE is known to be present, then defining\n    ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption\n    code.  If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if\n    it is detected (both present and enabled) but the normal AES code will\n    also be present.\n\n    When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte\n    aligned; other input/output buffers do not need to be 16 byte aligned\n    but there are very large performance gains if this can be arranged.\n    VIA ACE also requires the decryption key schedule to be in reverse\n    order (which later checks below ensure).\n*/\n\n#if 1 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT )\n#  define USE_VIA_ACE_IF_PRESENT\n#endif\n\n#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT )\n#  define ASSUME_VIA_ACE_PRESENT\n#  endif\n\n/*  3. ASSEMBLER SUPPORT\n\n    This define (which can be on the command line) enables the use of the\n    assembler code routines for encryption, decryption and key scheduling\n    as follows:\n\n    ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for\n                encryption and decryption and but with key scheduling in C\n    ASM_X86_V2  uses assembler (aes_x86_v2.asm) with compressed tables for\n                encryption, decryption and key scheduling\n    ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for\n                encryption and decryption and but with key scheduling in C\n    ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for\n                encryption and decryption and but with key scheduling in C\n\n    Change one 'if 0' below to 'if 1' to select the version or define\n    as a compilation option.\n*/\n\n#if 0 && !defined( ASM_X86_V1C )\n#  define ASM_X86_V1C\n#elif 0 && !defined( ASM_X86_V2  )\n#  define ASM_X86_V2\n#elif 0 && !defined( ASM_X86_V2C )\n#  define ASM_X86_V2C\n#elif 0 && !defined( ASM_AMD64_C )\n#  define ASM_AMD64_C\n#endif\n\n#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \\\n      && !defined( _M_IX86 ) || defined( ASM_AMD64_C ) && !defined( _M_X64 )\n#  error Assembler code is only available for x86 and AMD64 systems\n#endif\n\n/*  4. FAST INPUT/OUTPUT OPERATIONS.\n\n    On some machines it is possible to improve speed by transferring the\n    bytes in the input and output arrays to and from the internal 32-bit\n    variables by addressing these arrays as if they are arrays of 32-bit\n    words.  On some machines this will always be possible but there may\n    be a large performance penalty if the byte arrays are not aligned on\n    the normal word boundaries. On other machines this technique will\n    lead to memory access errors when such 32-bit word accesses are not\n    properly aligned. The option SAFE_IO avoids such problems but will\n    often be slower on those machines that support misaligned access\n    (especially so if care is taken to align the input  and output byte\n    arrays on 32-bit word boundaries). If SAFE_IO is not defined it is\n    assumed that access to byte arrays as if they are arrays of 32-bit\n    words will not cause problems when such accesses are misaligned.\n*/\n#if 1 && !defined( _MSC_VER )\n#  define SAFE_IO\n#endif\n\n/*  5. LOOP UNROLLING\n\n    The code for encryption and decrytpion cycles through a number of rounds\n    that can be implemented either in a loop or by expanding the code into a\n    long sequence of instructions, the latter producing a larger program but\n    one that will often be much faster. The latter is called loop unrolling.\n    There are also potential speed advantages in expanding two iterations in\n    a loop with half the number of iterations, which is called partial loop\n    unrolling.  The following options allow partial or full loop unrolling\n    to be set independently for encryption and decryption\n*/\n#if 1\n#  define ENC_UNROLL  FULL\n#elif 0\n#  define ENC_UNROLL  PARTIAL\n#else\n#  define ENC_UNROLL  NONE\n#endif\n\n#if 1\n#  define DEC_UNROLL  FULL\n#elif 0\n#  define DEC_UNROLL  PARTIAL\n#else\n#  define DEC_UNROLL  NONE\n#endif\n\n#if 1\n#  define ENC_KS_UNROLL\n#endif\n\n#if 1\n#  define DEC_KS_UNROLL\n#endif\n\n/*  6. FAST FINITE FIELD OPERATIONS\n\n    If this section is included, tables are used to provide faster finite\n    field arithmetic (this has no effect if FIXED_TABLES is defined).\n*/\n#if 1\n#  define FF_TABLES\n#endif\n\n/*  7. INTERNAL STATE VARIABLE FORMAT\n\n    The internal state of Rijndael is stored in a number of local 32-bit\n    word varaibles which can be defined either as an array or as individual\n    names variables. Include this section if you want to store these local\n    varaibles in arrays. Otherwise individual local variables will be used.\n*/\n#if 1\n#  define ARRAYS\n#endif\n\n/*  8. FIXED OR DYNAMIC TABLES\n\n    When this section is included the tables used by the code are compiled\n    statically into the binary file.  Otherwise the subroutine aes_init()\n    must be called to compute them before the code is first used.\n*/\n#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 ))\n#  define FIXED_TABLES\n#endif\n\n/*  9. MASKING OR CASTING FROM LONGER VALUES TO BYTES\n\n    In some systems it is better to mask longer values to extract bytes \n    rather than using a cast. This option allows this choice.\n*/\n#if 0\n#  define to_byte(x)  ((uint_8t)(x))\n#else\n#  define to_byte(x)  ((x) & 0xff)\n#endif\n\n/*  10. TABLE ALIGNMENT\n\n    On some sytsems speed will be improved by aligning the AES large lookup\n    tables on particular boundaries. This define should be set to a power of\n    two giving the desired alignment. It can be left undefined if alignment\n    is not needed.  This option is specific to the Microsft VC++ compiler -\n    it seems to sometimes cause trouble for the VC++ version 6 compiler.\n*/\n\n#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 )\n#  define TABLE_ALIGN 32\n#endif\n\n/*  11.  REDUCE CODE AND TABLE SIZE\n\n    This replaces some expanded macros with function calls if AES_ASM_V2 or\n    AES_ASM_V2C are defined\n*/\n\n#if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))\n#  define REDUCE_CODE_SIZE\n#endif\n\n/*  12. TABLE OPTIONS\n\n    This cipher proceeds by repeating in a number of cycles known as 'rounds'\n    which are implemented by a round function which can optionally be speeded\n    up using tables.  The basic tables are each 256 32-bit words, with either\n    one or four tables being required for each round function depending on\n    how much speed is required. The encryption and decryption round functions\n    are different and the last encryption and decrytpion round functions are\n    different again making four different round functions in all.\n\n    This means that:\n      1. Normal encryption and decryption rounds can each use either 0, 1\n         or 4 tables and table spaces of 0, 1024 or 4096 bytes each.\n      2. The last encryption and decryption rounds can also use either 0, 1\n         or 4 tables and table spaces of 0, 1024 or 4096 bytes each.\n\n    Include or exclude the appropriate definitions below to set the number\n    of tables used by this implementation.\n*/\n\n#if 1   /* set tables for the normal encryption round */\n#  define ENC_ROUND   FOUR_TABLES\n#elif 0\n#  define ENC_ROUND   ONE_TABLE\n#else\n#  define ENC_ROUND   NO_TABLES\n#endif\n\n#if 1   /* set tables for the last encryption round */\n#  define LAST_ENC_ROUND  FOUR_TABLES\n#elif 0\n#  define LAST_ENC_ROUND  ONE_TABLE\n#else\n#  define LAST_ENC_ROUND  NO_TABLES\n#endif\n\n#if 1   /* set tables for the normal decryption round */\n#  define DEC_ROUND   FOUR_TABLES\n#elif 0\n#  define DEC_ROUND   ONE_TABLE\n#else\n#  define DEC_ROUND   NO_TABLES\n#endif\n\n#if 1   /* set tables for the last decryption round */\n#  define LAST_DEC_ROUND  FOUR_TABLES\n#elif 0\n#  define LAST_DEC_ROUND  ONE_TABLE\n#else\n#  define LAST_DEC_ROUND  NO_TABLES\n#endif\n\n/*  The decryption key schedule can be speeded up with tables in the same\n    way that the round functions can.  Include or exclude the following\n    defines to set this requirement.\n*/\n#if 1\n#  define KEY_SCHED   FOUR_TABLES\n#elif 0\n#  define KEY_SCHED   ONE_TABLE\n#else\n#  define KEY_SCHED   NO_TABLES\n#endif\n\n/*  ---- END OF USER CONFIGURED OPTIONS ---- */\n\n/* VIA ACE support is only available for VC++ and GCC */\n\n#if !defined( _MSC_VER ) && !defined( __GNUC__ )\n#  if defined( ASSUME_VIA_ACE_PRESENT )\n#    undef ASSUME_VIA_ACE_PRESENT\n#  endif\n#  if defined( USE_VIA_ACE_IF_PRESENT )\n#    undef USE_VIA_ACE_IF_PRESENT\n#  endif\n#endif\n\n#if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT )\n#  define USE_VIA_ACE_IF_PRESENT\n#endif\n\n#if defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS )\n#  define AES_REV_DKS\n#endif\n\n/* ********** UNDEF - we don't use VIA stuff ****************** */\n#undef USE_VIA_ACE_IF_PRESENT\n\n/* Assembler support requires the use of platform byte order */\n\n#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \\\n    && (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER)\n#  undef  ALGORITHM_BYTE_ORDER\n#  define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER\n#endif\n\n/* In this implementation the columns of the state array are each held in\n   32-bit words. The state array can be held in various ways: in an array\n   of words, in a number of individual word variables or in a number of\n   processor registers. The following define maps a variable name x and\n   a column number c to the way the state array variable is to be held.\n   The first define below maps the state into an array x[c] whereas the\n   second form maps the state into a number of individual variables x0,\n   x1, etc.  Another form could map individual state colums to machine\n   register names.\n*/\n\n#if defined( ARRAYS )\n#  define s(x,c) x[c]\n#else\n#  define s(x,c) x##c\n#endif\n\n/*  This implementation provides subroutines for encryption, decryption\n    and for setting the three key lengths (separately) for encryption\n    and decryption. Since not all functions are needed, masks are set\n    up here to determine which will be implemented in C\n*/\n\n#if !defined( AES_ENCRYPT )\n#  define EFUNCS_IN_C   0\n#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \\\n    || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )\n#  define EFUNCS_IN_C   ENC_KEYING_IN_C\n#elif !defined( ASM_X86_V2 )\n#  define EFUNCS_IN_C   ( ENCRYPTION_IN_C | ENC_KEYING_IN_C )\n#else\n#  define EFUNCS_IN_C   0\n#endif\n\n#if !defined( AES_DECRYPT )\n#  define DFUNCS_IN_C   0\n#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \\\n    || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )\n#  define DFUNCS_IN_C   DEC_KEYING_IN_C\n#elif !defined( ASM_X86_V2 )\n#  define DFUNCS_IN_C   ( DECRYPTION_IN_C | DEC_KEYING_IN_C )\n#else\n#  define DFUNCS_IN_C   0\n#endif\n\n#define FUNCS_IN_C  ( EFUNCS_IN_C | DFUNCS_IN_C )\n\n/* END OF CONFIGURATION OPTIONS */\n\n#define RC_LENGTH   (5 * (AES_BLOCK_SIZE / 4 - 2))\n\n/* Disable or report errors on some combinations of options */\n\n#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES\n#  undef  LAST_ENC_ROUND\n#  define LAST_ENC_ROUND  NO_TABLES\n#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES\n#  undef  LAST_ENC_ROUND\n#  define LAST_ENC_ROUND  ONE_TABLE\n#endif\n\n#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE\n#  undef  ENC_UNROLL\n#  define ENC_UNROLL  NONE\n#endif\n\n#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES\n#  undef  LAST_DEC_ROUND\n#  define LAST_DEC_ROUND  NO_TABLES\n#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES\n#  undef  LAST_DEC_ROUND\n#  define LAST_DEC_ROUND  ONE_TABLE\n#endif\n\n#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE\n#  undef  DEC_UNROLL\n#  define DEC_UNROLL  NONE\n#endif\n\n#if defined( bswap32 )\n#  define aes_sw32    bswap32\n#elif defined( bswap_32 )\n#  define aes_sw32    bswap_32\n#else\n#  define brot(x,n)   (((uint_32t)(x) <<  n) | ((uint_32t)(x) >> (32 - n)))\n#  define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00))\n#endif\n\n/*  upr(x,n):  rotates bytes within words by n positions, moving bytes to\n               higher index positions with wrap around into low positions\n    ups(x,n):  moves bytes by n positions to higher index positions in\n               words but without wrap around\n    bval(x,n): extracts a byte from a word\n\n    WARNING:   The definitions given here are intended only for use with\n               unsigned variables and with shift counts that are compile\n               time constants\n*/\n\n#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN )\n#  define upr(x,n)      (((uint_32t)(x) << (8 * (n))) | ((uint_32t)(x) >> (32 - 8 * (n))))\n#  define ups(x,n)      ((uint_32t) (x) << (8 * (n)))\n#  define bval(x,n)     to_byte((x) >> (8 * (n)))\n#  define bytes2word(b0, b1, b2, b3)  \\\n        (((uint_32t)(b3) << 24) | ((uint_32t)(b2) << 16) | ((uint_32t)(b1) << 8) | (b0))\n#endif\n\n#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN )\n#  define upr(x,n)      (((uint_32t)(x) >> (8 * (n))) | ((uint_32t)(x) << (32 - 8 * (n))))\n#  define ups(x,n)      ((uint_32t) (x) >> (8 * (n)))\n#  define bval(x,n)     to_byte((x) >> (24 - 8 * (n)))\n#  define bytes2word(b0, b1, b2, b3)  \\\n        (((uint_32t)(b0) << 24) | ((uint_32t)(b1) << 16) | ((uint_32t)(b2) << 8) | (b3))\n#endif\n\n#if defined( SAFE_IO )\n#  define word_in(x,c)    bytes2word(((const uint_8t*)(x)+4*c)[0], ((const uint_8t*)(x)+4*c)[1], \\\n                                   ((const uint_8t*)(x)+4*c)[2], ((const uint_8t*)(x)+4*c)[3])\n#  define word_out(x,c,v) { ((uint_8t*)(x)+4*c)[0] = bval(v,0); ((uint_8t*)(x)+4*c)[1] = bval(v,1); \\\n                          ((uint_8t*)(x)+4*c)[2] = bval(v,2); ((uint_8t*)(x)+4*c)[3] = bval(v,3); }\n#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER )\n#  define word_in(x,c)    (*((uint_32t*)(x)+(c)))\n#  define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = (v))\n#else\n#  define word_in(x,c)    aes_sw32(*((uint_32t*)(x)+(c)))\n#  define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = aes_sw32(v))\n#endif\n\n/* the finite field modular polynomial and elements */\n\n#define WPOLY   0x011b\n#define BPOLY     0x1b\n\n/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */\n\n#define gf_c1  0x80808080\n#define gf_c2  0x7f7f7f7f\n#define gf_mulx(x)  ((((x) & gf_c2) << 1) ^ ((((x) & gf_c1) >> 7) * BPOLY))\n\n/* The following defines provide alternative definitions of gf_mulx that might\n   give improved performance if a fast 32-bit multiply is not available. Note\n   that a temporary variable u needs to be defined where gf_mulx is used.\n\n#define gf_mulx(x) (u = (x) & gf_c1, u |= (u >> 1), ((x) & gf_c2) << 1) ^ ((u >> 3) | (u >> 6))\n#define gf_c4  (0x01010101 * BPOLY)\n#define gf_mulx(x) (u = (x) & gf_c1, ((x) & gf_c2) << 1) ^ ((u - (u >> 7)) & gf_c4)\n*/\n\n/* Work out which tables are needed for the different options   */\n\n#if defined( ASM_X86_V1C )\n#  if defined( ENC_ROUND )\n#    undef  ENC_ROUND\n#  endif\n#  define ENC_ROUND   FOUR_TABLES\n#  if defined( LAST_ENC_ROUND )\n#    undef  LAST_ENC_ROUND\n#  endif\n#  define LAST_ENC_ROUND  FOUR_TABLES\n#  if defined( DEC_ROUND )\n#    undef  DEC_ROUND\n#  endif\n#  define DEC_ROUND   FOUR_TABLES\n#  if defined( LAST_DEC_ROUND )\n#    undef  LAST_DEC_ROUND\n#  endif\n#  define LAST_DEC_ROUND  FOUR_TABLES\n#  if defined( KEY_SCHED )\n#    undef  KEY_SCHED\n#    define KEY_SCHED   FOUR_TABLES\n#  endif\n#endif\n\n#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C )\n#  if ENC_ROUND == ONE_TABLE\n#    define FT1_SET\n#  elif ENC_ROUND == FOUR_TABLES\n#    define FT4_SET\n#  else\n#    define SBX_SET\n#  endif\n#  if LAST_ENC_ROUND == ONE_TABLE\n#    define FL1_SET\n#  elif LAST_ENC_ROUND == FOUR_TABLES\n#    define FL4_SET\n#  elif !defined( SBX_SET )\n#    define SBX_SET\n#  endif\n#endif\n\n#if ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C )\n#  if DEC_ROUND == ONE_TABLE\n#    define IT1_SET\n#  elif DEC_ROUND == FOUR_TABLES\n#    define IT4_SET\n#  else\n#    define ISB_SET\n#  endif\n#  if LAST_DEC_ROUND == ONE_TABLE\n#    define IL1_SET\n#  elif LAST_DEC_ROUND == FOUR_TABLES\n#    define IL4_SET\n#  elif !defined(ISB_SET)\n#    define ISB_SET\n#  endif\n#endif\n\n#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )))\n#  if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C))\n#    if KEY_SCHED == ONE_TABLE\n#      if !defined( FL1_SET )  && !defined( FL4_SET ) \n#        define LS1_SET\n#      endif\n#    elif KEY_SCHED == FOUR_TABLES\n#      if !defined( FL4_SET )\n#        define LS4_SET\n#      endif\n#    elif !defined( SBX_SET )\n#      define SBX_SET\n#    endif\n#  endif\n#  if (FUNCS_IN_C & DEC_KEYING_IN_C)\n#    if KEY_SCHED == ONE_TABLE\n#      define IM1_SET\n#    elif KEY_SCHED == FOUR_TABLES\n#      define IM4_SET\n#    elif !defined( SBX_SET )\n#      define SBX_SET\n#    endif\n#  endif\n#endif\n\n/* generic definitions of Rijndael macros that use tables    */\n\n#define no_table(x,box,vf,rf,c) bytes2word( \\\n    box[bval(vf(x,0,c),rf(0,c))], \\\n    box[bval(vf(x,1,c),rf(1,c))], \\\n    box[bval(vf(x,2,c),rf(2,c))], \\\n    box[bval(vf(x,3,c),rf(3,c))])\n\n#define one_table(x,op,tab,vf,rf,c) \\\n (     tab[bval(vf(x,0,c),rf(0,c))] \\\n  ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \\\n  ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \\\n  ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))\n\n#define four_tables(x,tab,vf,rf,c) \\\n (  tab[0][bval(vf(x,0,c),rf(0,c))] \\\n  ^ tab[1][bval(vf(x,1,c),rf(1,c))] \\\n  ^ tab[2][bval(vf(x,2,c),rf(2,c))] \\\n  ^ tab[3][bval(vf(x,3,c),rf(3,c))])\n\n#define vf1(x,r,c)  (x)\n#define rf1(r,c)    (r)\n#define rf2(r,c)    ((8+r-c)&3)\n\n/* perform forward and inverse column mix operation on four bytes in long word x in */\n/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros.  */\n\n#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) \n\n#if defined( FM4_SET )      /* not currently used */\n#  define fwd_mcol(x)       four_tables(x,t_use(f,m),vf1,rf1,0)\n#elif defined( FM1_SET )    /* not currently used */\n#  define fwd_mcol(x)       one_table(x,upr,t_use(f,m),vf1,rf1,0)\n#else\n#  define dec_fmvars        uint_32t g2\n#  define fwd_mcol(x)       (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1))\n#endif\n\n#if defined( IM4_SET )\n#  define inv_mcol(x)       four_tables(x,t_use(i,m),vf1,rf1,0)\n#elif defined( IM1_SET )\n#  define inv_mcol(x)       one_table(x,upr,t_use(i,m),vf1,rf1,0)\n#else\n#  define dec_imvars        uint_32t g2, g4, g9\n#  define inv_mcol(x)       (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \\\n                            (x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1))\n#endif\n\n#if defined( FL4_SET )\n#  define ls_box(x,c)       four_tables(x,t_use(f,l),vf1,rf2,c)\n#elif defined( LS4_SET )\n#  define ls_box(x,c)       four_tables(x,t_use(l,s),vf1,rf2,c)\n#elif defined( FL1_SET )\n#  define ls_box(x,c)       one_table(x,upr,t_use(f,l),vf1,rf2,c)\n#elif defined( LS1_SET )\n#  define ls_box(x,c)       one_table(x,upr,t_use(l,s),vf1,rf2,c)\n#else\n#  define ls_box(x,c)       no_table(x,t_use(s,box),vf1,rf2,c)\n#endif\n\n#endif\n\n#if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET )\n#  define ISB_SET\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/aestab.c",
    "content": "/*\n---------------------------------------------------------------------------\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\n\nThe redistribution and use of this software (with or without changes)\nis allowed without the payment of fees or royalties provided that:\n\n  source code distributions include the above copyright notice, this\n  list of conditions and the following disclaimer;\n\n  binary distributions include the above copyright notice, this list\n  of conditions and the following disclaimer in their documentation.\n\nThis software is provided 'as is' with no explicit or implied warranties\nin respect of its operation, including, but not limited to, correctness\nand fitness for purpose.\n---------------------------------------------------------------------------\nIssue Date: 20/12/2007\n*/\n\n#define DO_TABLES\n\n#include \"aes.h\"\n#include \"aesopt.h\"\n\n#if defined(FIXED_TABLES)\n\n#define sb_data(w) {\\\n    w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\\\n    w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\\\n    w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\\\n    w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\\\n    w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\\\n    w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\\\n    w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\\\n    w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\\\n    w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\\\n    w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\\\n    w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\\\n    w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\\\n    w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\\\n    w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\\\n    w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\\\n    w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\\\n    w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\\\n    w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\\\n    w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\\\n    w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\\\n    w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\\\n    w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\\\n    w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\\\n    w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\\\n    w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\\\n    w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\\\n    w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\\\n    w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\\\n    w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\\\n    w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\\\n    w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\\\n    w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }\n\n#define isb_data(w) {\\\n    w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\\\n    w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\\\n    w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\\\n    w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\\\n    w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\\\n    w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\\\n    w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\\\n    w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\\\n    w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\\\n    w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\\\n    w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\\\n    w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\\\n    w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\\\n    w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\\\n    w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\\\n    w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\\\n    w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\\\n    w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\\\n    w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\\\n    w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\\\n    w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\\\n    w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\\\n    w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\\\n    w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\\\n    w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\\\n    w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\\\n    w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\\\n    w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\\\n    w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\\\n    w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\\\n    w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\\\n    w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) }\n\n#define mm_data(w) {\\\n    w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\\\n    w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\\\n    w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\\\n    w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\\\n    w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\\\n    w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\\\n    w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\\\n    w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\\\n    w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\\\n    w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\\\n    w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\\\n    w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\\\n    w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\\\n    w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\\\n    w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\\\n    w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\\\n    w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\\\n    w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\\\n    w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\\\n    w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\\\n    w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\\\n    w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\\\n    w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\\\n    w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\\\n    w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\\\n    w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\\\n    w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\\\n    w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\\\n    w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\\\n    w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\\\n    w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\\\n    w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) }\n\n#define rc_data(w) {\\\n    w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\\\n    w(0x1b), w(0x36) }\n\n#define h0(x)   (x)\n\n#define w0(p)   bytes2word(p, 0, 0, 0)\n#define w1(p)   bytes2word(0, p, 0, 0)\n#define w2(p)   bytes2word(0, 0, p, 0)\n#define w3(p)   bytes2word(0, 0, 0, p)\n\n#define u0(p)   bytes2word(f2(p), p, p, f3(p))\n#define u1(p)   bytes2word(f3(p), f2(p), p, p)\n#define u2(p)   bytes2word(p, f3(p), f2(p), p)\n#define u3(p)   bytes2word(p, p, f3(p), f2(p))\n\n#define v0(p)   bytes2word(fe(p), f9(p), fd(p), fb(p))\n#define v1(p)   bytes2word(fb(p), fe(p), f9(p), fd(p))\n#define v2(p)   bytes2word(fd(p), fb(p), fe(p), f9(p))\n#define v3(p)   bytes2word(f9(p), fd(p), fb(p), fe(p))\n\n#endif\n\n#if defined(FIXED_TABLES) || !defined(FF_TABLES)\n\n#define f2(x)   ((x<<1) ^ (((x>>7) & 1) * WPOLY))\n#define f4(x)   ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))\n#define f8(x)   ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \\\n                        ^ (((x>>5) & 4) * WPOLY))\n#define f3(x)   (f2(x) ^ x)\n#define f9(x)   (f8(x) ^ x)\n#define fb(x)   (f8(x) ^ f2(x) ^ x)\n#define fd(x)   (f8(x) ^ f4(x) ^ x)\n#define fe(x)   (f8(x) ^ f4(x) ^ f2(x))\n\n#else\n\n#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)\n#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)\n#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)\n#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)\n#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)\n#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)\n\n#endif\n\n#include \"aestab.h\"\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\n#if defined(FIXED_TABLES)\n\n/* implemented in case of wrong call for fixed tables */\n\nAES_RETURN aes_init_zrtp(void)\n{\n    return EXIT_SUCCESS;\n}\n\n#else   /*  Generate the tables for the dynamic table option */\n\n#if defined(FF_TABLES)\n\n#define gf_inv(x)   ((x) ? pow[ 255 - log[x]] : 0)\n\n#else \n\n/*  It will generally be sensible to use tables to compute finite\n    field multiplies and inverses but where memory is scarse this\n    code might sometimes be better. But it only has effect during\n    initialisation so its pretty unimportant in overall terms.\n*/\n\n/*  return 2 ^ (n - 1) where n is the bit number of the highest bit\n    set in x with x in the range 1 < x < 0x00000200.   This form is\n    used so that locals within fi can be bytes rather than words\n*/\n\nstatic uint_8t hibit(const uint_32t x)\n{   uint_8t r = (uint_8t)((x >> 1) | (x >> 2));\n\n    r |= (r >> 2);\n    r |= (r >> 4);\n    return (r + 1) >> 1;\n}\n\n/* return the inverse of the finite field element x */\n\nstatic uint_8t gf_inv(const uint_8t x)\n{   uint_8t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;\n\n    if(x < 2) \n        return x;\n\n    for( ; ; )\n    {\n        if(n1)\n            while(n2 >= n1)             /* divide polynomial p2 by p1    */\n            {\n                n2 /= n1;               /* shift smaller polynomial left */ \n                p2 ^= (p1 * n2) & 0xff; /* and remove from larger one    */\n                v2 ^= v1 * n2;          /* shift accumulated value and   */ \n                n2 = hibit(p2);         /* add into result               */\n            }\n        else\n            return v1;\n\n        if(n2)                          /* repeat with values swapped    */ \n            while(n1 >= n2)\n            {\n                n1 /= n2; \n                p1 ^= p2 * n1; \n                v1 ^= v2 * n1; \n                n1 = hibit(p1);\n            }\n        else\n            return v2;\n    }\n}\n\n#endif\n\n/* The forward and inverse affine transformations used in the S-box */\nuint_8t fwd_affine(const uint_8t x)\n{   uint_32t w = x;\n    w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);\n    return 0x63 ^ ((w ^ (w >> 8)) & 0xff);\n}\n\nuint_8t inv_affine(const uint_8t x)\n{   uint_32t w = x;\n    w = (w << 1) ^ (w << 3) ^ (w << 6);\n    return 0x05 ^ ((w ^ (w >> 8)) & 0xff);\n}\n\nstatic int init = 0;\n\nAES_RETURN aes_init_zrtp(void)\n{   uint_32t  i, w;\n\n#if defined(FF_TABLES)\n\n    uint_8t  pow[512], log[256];\n\n    if(init)\n        return EXIT_SUCCESS;\n    /*  log and power tables for GF(2^8) finite field with\n        WPOLY as modular polynomial - the simplest primitive\n        root is 0x03, used here to generate the tables\n    */\n\n    i = 0; w = 1;\n    do\n    {\n        pow[i] = (uint_8t)w;\n        pow[i + 255] = (uint_8t)w;\n        log[w] = (uint_8t)i++;\n        w ^=  (w << 1) ^ (w & 0x80 ? WPOLY : 0);\n    }\n    while (w != 1);\n\n#else\n    if(init)\n        return EXIT_SUCCESS;\n#endif\n\n    for(i = 0, w = 1; i < RC_LENGTH; ++i)\n    {\n        t_set(r,c)[i] = bytes2word(w, 0, 0, 0);\n        w = f2(w);\n    }\n\n    for(i = 0; i < 256; ++i)\n    {   uint_8t    b;\n\n        b = fwd_affine(gf_inv((uint_8t)i));\n        w = bytes2word(f2(b), b, b, f3(b));\n\n#if defined( SBX_SET )\n        t_set(s,box)[i] = b;\n#endif\n\n#if defined( FT1_SET )                 /* tables for a normal encryption round */\n        t_set(f,n)[i] = w;\n#endif\n#if defined( FT4_SET )\n        t_set(f,n)[0][i] = w;\n        t_set(f,n)[1][i] = upr(w,1);\n        t_set(f,n)[2][i] = upr(w,2);\n        t_set(f,n)[3][i] = upr(w,3);\n#endif\n        w = bytes2word(b, 0, 0, 0);\n\n#if defined( FL1_SET )            /* tables for last encryption round (may also   */\n        t_set(f,l)[i] = w;        /* be used in the key schedule)                 */\n#endif\n#if defined( FL4_SET )\n        t_set(f,l)[0][i] = w;\n        t_set(f,l)[1][i] = upr(w,1);\n        t_set(f,l)[2][i] = upr(w,2);\n        t_set(f,l)[3][i] = upr(w,3);\n#endif\n\n#if defined( LS1_SET )\t\t\t/* table for key schedule if t_set(f,l) above is*/\n        t_set(l,s)[i] = w;      /* not of the required form                     */\n#endif\n#if defined( LS4_SET )\n        t_set(l,s)[0][i] = w;\n        t_set(l,s)[1][i] = upr(w,1);\n        t_set(l,s)[2][i] = upr(w,2);\n        t_set(l,s)[3][i] = upr(w,3);\n#endif\n\n        b = gf_inv(inv_affine((uint_8t)i));\n        w = bytes2word(fe(b), f9(b), fd(b), fb(b));\n\n#if defined( IM1_SET )\t\t\t/* tables for the inverse mix column operation  */\n        t_set(i,m)[b] = w;\n#endif\n#if defined( IM4_SET )\n        t_set(i,m)[0][b] = w;\n        t_set(i,m)[1][b] = upr(w,1);\n        t_set(i,m)[2][b] = upr(w,2);\n        t_set(i,m)[3][b] = upr(w,3);\n#endif\n\n#if defined( ISB_SET )\n        t_set(i,box)[i] = b;\n#endif\n#if defined( IT1_SET )\t\t\t/* tables for a normal decryption round */\n        t_set(i,n)[i] = w;\n#endif\n#if defined( IT4_SET )\n        t_set(i,n)[0][i] = w;\n        t_set(i,n)[1][i] = upr(w,1);\n        t_set(i,n)[2][i] = upr(w,2);\n        t_set(i,n)[3][i] = upr(w,3);\n#endif\n        w = bytes2word(b, 0, 0, 0);\n#if defined( IL1_SET )\t\t\t/* tables for last decryption round */\n        t_set(i,l)[i] = w;\n#endif\n#if defined( IL4_SET )\n        t_set(i,l)[0][i] = w;\n        t_set(i,l)[1][i] = upr(w,1);\n        t_set(i,l)[2][i] = upr(w,2);\n        t_set(i,l)[3][i] = upr(w,3);\n#endif\n    }\n    init = 1;\n    return EXIT_SUCCESS;\n}\n\n#endif\n\n#if defined(__cplusplus)\n}\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/aestab.h",
    "content": "/*\n---------------------------------------------------------------------------\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\n\nThe redistribution and use of this software (with or without changes)\nis allowed without the payment of fees or royalties provided that:\n\n  source code distributions include the above copyright notice, this\n  list of conditions and the following disclaimer;\n\n  binary distributions include the above copyright notice, this list\n  of conditions and the following disclaimer in their documentation.\n\nThis software is provided 'as is' with no explicit or implied warranties\nin respect of its operation, including, but not limited to, correctness\nand fitness for purpose.\n---------------------------------------------------------------------------\nIssue Date: 20/12/2007\n\n This file contains the code for declaring the tables needed to implement\n AES. The file aesopt.h is assumed to be included before this header file.\n If there are no global variables, the definitions here can be used to put\n the AES tables in a structure so that a pointer can then be added to the\n AES context to pass them to the AES routines that need them.   If this\n facility is used, the calling program has to ensure that this pointer is\n managed appropriately.  In particular, the value of the t_dec(in,it) item\n in the table structure must be set to zero in order to ensure that the\n tables are initialised. In practice the three code sequences in aeskey.c\n that control the calls to aes_init() and the aes_init() routine itself will\n have to be changed for a specific implementation. If global variables are\n available it will generally be preferable to use them with the precomputed\n FIXED_TABLES option that uses static global tables.\n\n The following defines can be used to control the way the tables\n are defined, initialised and used in embedded environments that\n require special features for these purposes\n\n    the 't_dec' construction is used to declare fixed table arrays\n    the 't_set' construction is used to set fixed table values\n    the 't_use' construction is used to access fixed table values\n\n    256 byte tables:\n\n        t_xxx(s,box)    => forward S box\n        t_xxx(i,box)    => inverse S box\n\n    256 32-bit word OR 4 x 256 32-bit word tables:\n\n        t_xxx(f,n)      => forward normal round\n        t_xxx(f,l)      => forward last round\n        t_xxx(i,n)      => inverse normal round\n        t_xxx(i,l)      => inverse last round\n        t_xxx(l,s)      => key schedule table\n        t_xxx(i,m)      => key schedule table\n\n    Other variables and tables:\n\n        t_xxx(r,c)      => the rcon table\n*/\n\n#if !defined( _AESTAB_H )\n#define _AESTAB_H\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n#define t_dec(m,n) t_##m##n\n#define t_set(m,n) t_##m##n\n#define t_use(m,n) t_##m##n\n\n#if defined(FIXED_TABLES)\n#  if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ ))\n/*   make tables far data to avoid using too much DGROUP space (PG) */\n#    define CONST const far\n#  else\n#    define CONST const\n#  endif\n#else\n#  define CONST\n#endif\n\n#if defined(DO_TABLES)\n#  define EXTERN\n#else\n#  define EXTERN extern\n#endif\n\n#if defined(_MSC_VER) && defined(TABLE_ALIGN)\n#define ALIGN __declspec(align(TABLE_ALIGN))\n#else\n#define ALIGN\n#endif\n\n#if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )\n#  define XP_DIR __cdecl\n#else\n#  define XP_DIR\n#endif\n\n#if defined(DO_TABLES) && defined(FIXED_TABLES)\n#define d_1(t,n,b,e)       EXTERN ALIGN CONST XP_DIR t n[256]    =   b(e)\n#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) }\nEXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);\n#else\n#define d_1(t,n,b,e)       EXTERN ALIGN CONST XP_DIR t n[256]\n#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256]\nEXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH];\n#endif\n\n#if defined( SBX_SET )\n    d_1(uint_8t, t_dec(s,box), sb_data, h0);\n#endif\n#if defined( ISB_SET )\n    d_1(uint_8t, t_dec(i,box), isb_data, h0);\n#endif\n\n#if defined( FT1_SET )\n    d_1(uint_32t, t_dec(f,n), sb_data, u0);\n#endif\n#if defined( FT4_SET )\n    d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);\n#endif\n\n#if defined( FL1_SET )\n    d_1(uint_32t, t_dec(f,l), sb_data, w0);\n#endif\n#if defined( FL4_SET )\n    d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);\n#endif\n\n#if defined( IT1_SET )\n    d_1(uint_32t, t_dec(i,n), isb_data, v0);\n#endif\n#if defined( IT4_SET )\n    d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);\n#endif\n\n#if defined( IL1_SET )\n    d_1(uint_32t, t_dec(i,l), isb_data, w0);\n#endif\n#if defined( IL4_SET )\n    d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);\n#endif\n\n#if defined( LS1_SET )\n#if defined( FL1_SET )\n#undef  LS1_SET\n#else\n    d_1(uint_32t, t_dec(l,s), sb_data, w0);\n#endif\n#endif\n\n#if defined( LS4_SET )\n#if defined( FL4_SET )\n#undef  LS4_SET\n#else\n    d_4(uint_32t, t_dec(l,s), sb_data, w0, w1, w2, w3);\n#endif\n#endif\n\n#if defined( IM1_SET )\n    d_1(uint_32t, t_dec(i,m), mm_data, v0);\n#endif\n#if defined( IM4_SET )\n    d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);\n#endif\n\n#if defined(__cplusplus)\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/brg_endian.h",
    "content": "/*\r\n---------------------------------------------------------------------------\r\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\r\n\r\nThe redistribution and use of this software (with or without changes)\r\nis allowed without the payment of fees or royalties provided that:\r\n\r\n  source code distributions include the above copyright notice, this\r\n  list of conditions and the following disclaimer;\r\n\r\n  binary distributions include the above copyright notice, this list\r\n  of conditions and the following disclaimer in their documentation.\r\n\r\nThis software is provided 'as is' with no explicit or implied warranties\r\nin respect of its operation, including, but not limited to, correctness\r\nand fitness for purpose.\r\n---------------------------------------------------------------------------\r\nIssue Date: 20/12/2007\r\n*/\r\n\r\n#ifndef _BRG_ENDIAN_H\r\n#define _BRG_ENDIAN_H\r\n\r\n#define IS_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */\r\n#define IS_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */\r\n\r\n/* Include files where endian defines and byteswap functions may reside */\r\n#if defined( __sun )\r\n#  include <sys/isa_defs.h>\r\n#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )\r\n#  include <sys/endian.h>\r\n#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \\\r\n      defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )\r\n#  include <machine/endian.h>\r\n#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )\r\n#  if !defined( __MINGW32__ ) && !defined( _AIX )\r\n#    include <endian.h>\r\n#    if !defined( __BEOS__ )\r\n#      include <byteswap.h>\r\n#    endif\r\n#  endif\r\n#endif\r\n\r\n/* Now attempt to set the define for platform byte order using any  */\r\n/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which  */\r\n/* seem to encompass most endian symbol definitions                 */\r\n\r\n#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )\r\n#  if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN\r\n#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#  elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN\r\n#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#  endif\r\n#elif defined( BIG_ENDIAN )\r\n#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#elif defined( LITTLE_ENDIAN )\r\n#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#endif\r\n\r\n#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )\r\n#  if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN\r\n#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#  elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN\r\n#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#  endif\r\n#elif defined( _BIG_ENDIAN )\r\n#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#elif defined( _LITTLE_ENDIAN )\r\n#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#endif\r\n\r\n#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )\r\n#  if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN\r\n#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#  elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN\r\n#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#  endif\r\n#elif defined( __BIG_ENDIAN )\r\n#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#elif defined( __LITTLE_ENDIAN )\r\n#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#endif\r\n\r\n#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )\r\n#  if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__\r\n#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#  elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__\r\n#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#  endif\r\n#elif defined( __BIG_ENDIAN__ )\r\n#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#elif defined( __LITTLE_ENDIAN__ )\r\n#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#endif\r\n\r\n/*  if the platform byte order could not be determined, then try to */\r\n/*  set this define using common machine defines                    */\r\n#if !defined(PLATFORM_BYTE_ORDER)\r\n\r\n#if   defined( __alpha__ ) || defined( __alpha ) || defined( i386 )       || \\\r\n      defined( __i386__ )  || defined( _M_I86 )  || defined( _M_IX86 )    || \\\r\n      defined( __OS2__ )   || defined( sun386 )  || defined( __TURBOC__ ) || \\\r\n      defined( vax )       || defined( vms )     || defined( VMS )        || \\\r\n      defined( __VMS )     || defined( _M_X64 )\r\n#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n\r\n#elif defined( AMIGA )   || defined( applec )    || defined( __AS400__ )  || \\\r\n      defined( _CRAY )   || defined( __hppa )    || defined( __hp9000 )   || \\\r\n      defined( ibm370 )  || defined( mc68000 )   || defined( m68k )       || \\\r\n      defined( __MRC__ ) || defined( __MVS__ )   || defined( __MWERKS__ ) || \\\r\n      defined( sparc )   || defined( __sparc)    || defined( SYMANTEC_C ) || \\\r\n      defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM )   || \\\r\n      defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )\r\n#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n\r\n#elif 0     /* **** EDIT HERE IF NECESSARY **** */\r\n#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#elif 0     /* **** EDIT HERE IF NECESSARY **** */\r\n#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#else\r\n#  error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order\r\n#endif\r\n\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/brg_types.h",
    "content": "/*\r\n---------------------------------------------------------------------------\r\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\r\n\r\nThe redistribution and use of this software (with or without changes)\r\nis allowed without the payment of fees or royalties provided that:\r\n\r\n  source code distributions include the above copyright notice, this\r\n  list of conditions and the following disclaimer;\r\n\r\n  binary distributions include the above copyright notice, this list\r\n  of conditions and the following disclaimer in their documentation.\r\n\r\nThis software is provided 'as is' with no explicit or implied warranties\r\nin respect of its operation, including, but not limited to, correctness\r\nand fitness for purpose.\r\n---------------------------------------------------------------------------\r\nIssue Date: 20/12/2007\r\n\r\n The unsigned integer types defined here are of the form uint_<nn>t where\r\n <nn> is the length of the type; for example, the unsigned 32-bit type is\r\n 'uint_32t'.  These are NOT the same as the 'C99 integer types' that are\r\n defined in the inttypes.h and stdint.h headers since attempts to use these\r\n types have shown that support for them is still highly variable.  However,\r\n since the latter are of the form uint<nn>_t, a regular expression search\r\n and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\\1_t')\r\n can be used to convert the types used here to the C99 standard types.\r\n*/\r\n\r\n#ifndef _BRG_TYPES_H\r\n#define _BRG_TYPES_H\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\" {\r\n#endif\r\n\r\n#include <limits.h>\r\n\r\n#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 )\r\n#  include <stddef.h>\r\n#  define ptrint_t intptr_t\r\n#elif defined( __ECOS__ )\r\n#  define intptr_t unsigned int\r\n#  define ptrint_t intptr_t\r\n#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 )\r\n#  include <stdint.h>\r\n#  define ptrint_t intptr_t\r\n#else\r\n#  define ptrint_t int\r\n#endif\r\n\r\n#ifndef BRG_UI8\r\n#  define BRG_UI8\r\n#  if UCHAR_MAX == 255u\r\n     typedef unsigned char uint_8t;\r\n#  else\r\n#    error Please define uint_8t as an 8-bit unsigned integer type in brg_types.h\r\n#  endif\r\n#endif\r\n\r\n#ifndef BRG_UI16\r\n#  define BRG_UI16\r\n#  if USHRT_MAX == 65535u\r\n     typedef unsigned short uint_16t;\r\n#  else\r\n#    error Please define uint_16t as a 16-bit unsigned short type in brg_types.h\r\n#  endif\r\n#endif\r\n\r\n#ifndef BRG_UI32\r\n#  define BRG_UI32\r\n#  if UINT_MAX == 4294967295u\r\n#    define li_32(h) 0x##h##u\r\n     typedef unsigned int uint_32t;\r\n#  elif ULONG_MAX == 4294967295u\r\n#    define li_32(h) 0x##h##ul\r\n     typedef unsigned long uint_32t;\r\n#  elif defined( _CRAY )\r\n#    error This code needs 32-bit data types, which Cray machines do not provide\r\n#  else\r\n#    error Please define uint_32t as a 32-bit unsigned integer type in brg_types.h\r\n#  endif\r\n#endif\r\n\r\n#ifndef BRG_UI64\r\n#  if defined( __BORLANDC__ ) && !defined( __MSDOS__ )\r\n#    define BRG_UI64\r\n#    define li_64(h) 0x##h##ui64\r\n     typedef unsigned __int64 uint_64t;\r\n#  elif defined( _MSC_VER ) && ( _MSC_VER < 1300 )    /* 1300 == VC++ 7.0 */\r\n#    define BRG_UI64\r\n#    define li_64(h) 0x##h##ui64\r\n     typedef unsigned __int64 uint_64t;\r\n#  elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful\r\n#    define BRG_UI64\r\n#    define li_64(h) 0x##h##ull\r\n     typedef unsigned long long uint_64t;\r\n#  elif defined( __MVS__ )\r\n#    define BRG_UI64\r\n#    define li_64(h) 0x##h##ull\r\n     typedef unsigned int long long uint_64t;\r\n#  elif defined( UINT_MAX ) && UINT_MAX > 4294967295u\r\n#    if UINT_MAX == 18446744073709551615u\r\n#      define BRG_UI64\r\n#      define li_64(h) 0x##h##u\r\n       typedef unsigned int uint_64t;\r\n#    endif\r\n#  elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u\r\n#    if ULONG_MAX == 18446744073709551615ul\r\n#      define BRG_UI64\r\n#      define li_64(h) 0x##h##ul\r\n       typedef unsigned long uint_64t;\r\n#    endif\r\n#  elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u\r\n#    if ULLONG_MAX == 18446744073709551615ull\r\n#      define BRG_UI64\r\n#      define li_64(h) 0x##h##ull\r\n       typedef unsigned long long uint_64t;\r\n#    endif\r\n#  elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u\r\n#    if ULONG_LONG_MAX == 18446744073709551615ull\r\n#      define BRG_UI64\r\n#      define li_64(h) 0x##h##ull\r\n       typedef unsigned long long uint_64t;\r\n#    endif\r\n#  endif\r\n#endif\r\n\r\n#if !defined( BRG_UI64 )\r\n#  if defined( NEED_UINT_64T )\r\n#    error Please define uint_64t as an unsigned 64 bit type in brg_types.h\r\n#  endif\r\n#endif\r\n\r\n#ifndef RETURN_VALUES\r\n#  define RETURN_VALUES\r\n#  if defined( DLL_EXPORT )\r\n#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )\r\n#      define VOID_RETURN    __declspec( dllexport ) void __stdcall\r\n#      define INT_RETURN     __declspec( dllexport ) int  __stdcall\r\n#    elif defined( __GNUC__ )\r\n#      define VOID_RETURN    __declspec( __dllexport__ ) void\r\n#      define INT_RETURN     __declspec( __dllexport__ ) int\r\n#    else\r\n#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers\r\n#    endif\r\n#  elif defined( DLL_IMPORT )\r\n#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )\r\n#      define VOID_RETURN    __declspec( dllimport ) void __stdcall\r\n#      define INT_RETURN     __declspec( dllimport ) int  __stdcall\r\n#    elif defined( __GNUC__ )\r\n#      define VOID_RETURN    __declspec( __dllimport__ ) void\r\n#      define INT_RETURN     __declspec( __dllimport__ ) int\r\n#    else\r\n#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers\r\n#    endif\r\n#  elif defined( __WATCOMC__ )\r\n#    define VOID_RETURN  void __cdecl\r\n#    define INT_RETURN   int  __cdecl\r\n#  else\r\n#    define VOID_RETURN  void\r\n#    define INT_RETURN   int\r\n#  endif\r\n#endif\r\n\r\n/*\tThese defines are used to detect and set the memory alignment of pointers.\r\n    Note that offsets are in bytes.\r\n\r\n    ALIGN_OFFSET(x,n)\t\t\treturn the positive or zero offset of \r\n                                the memory addressed by the pointer 'x' \r\n                                from an address that is aligned on an \r\n                                'n' byte boundary ('n' is a power of 2)\r\n\r\n    ALIGN_FLOOR(x,n)\t\t\treturn a pointer that points to memory\r\n                                that is aligned on an 'n' byte boundary \r\n                                and is not higher than the memory address\r\n                                pointed to by 'x' ('n' is a power of 2)\r\n\r\n    ALIGN_CEIL(x,n)\t\t\t\treturn a pointer that points to memory\r\n                                that is aligned on an 'n' byte boundary \r\n                                and is not lower than the memory address\r\n                                pointed to by 'x' ('n' is a power of 2)\r\n*/\r\n\r\n#define ALIGN_OFFSET(x,n)\t(((ptrint_t)(x)) & ((n) - 1))\r\n#define ALIGN_FLOOR(x,n)\t((uint_8t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1)))\r\n#define ALIGN_CEIL(x,n)\t\t((uint_8t*)(x) + (-((ptrint_t)(x)) & ((n) - 1)))\r\n\r\n/*  These defines are used to declare buffers in a way that allows\r\n    faster operations on longer variables to be used.  In all these\r\n    defines 'size' must be a power of 2 and >= 8. NOTE that the \r\n    buffer size is in bytes but the type length is in bits\r\n\r\n    UNIT_TYPEDEF(x,size)        declares a variable 'x' of length \r\n                                'size' bits\r\n\r\n    BUFR_TYPEDEF(x,size,bsize)  declares a buffer 'x' of length 'bsize' \r\n                                bytes defined as an array of variables\r\n                                each of 'size' bits (bsize must be a \r\n                                multiple of size / 8)\r\n\r\n    UNIT_CAST(x,size)           casts a variable to a type of \r\n                                length 'size' bits\r\n\r\n    UPTR_CAST(x,size)           casts a pointer to a pointer to a \r\n                                varaiable of length 'size' bits\r\n*/\r\n\r\n#define UI_TYPE(size)               uint_##size##t\r\n#define UNIT_TYPEDEF(x,size)        typedef UI_TYPE(size) x\r\n#define BUFR_TYPEDEF(x,size,bsize)  typedef UI_TYPE(size) x[bsize / (size >> 3)]\r\n#define UNIT_CAST(x,size)           ((UI_TYPE(size) )(x))  \r\n#define UPTR_CAST(x,size)           ((UI_TYPE(size)*)(x))\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/macSkein.cpp",
    "content": "/*\n  Copyright (C) 2010-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <cryptcommon/macSkein.h>\n#include <stdlib.h>\n\nvoid macSkein(uint8_t* key, int32_t key_length,\n               const uint8_t* data, uint32_t data_length,\n               uint8_t* mac, int32_t mac_length, SkeinSize_t skeinSize)\n{\n    SkeinCtx_t ctx;\n\n    skeinCtxPrepare(&ctx, skeinSize);\n\n    skeinMacInit(&ctx, key, key_length, mac_length);\n    skeinUpdate(&ctx, data, data_length);\n    skeinFinal(&ctx, mac);\n}\n\nvoid macSkein(uint8_t* key, int32_t key_length,\n               const uint8_t* data[], uint32_t data_length[],\n               uint8_t* mac, int32_t mac_length, SkeinSize_t skeinSize)\n{\n    SkeinCtx_t ctx;\n\n    skeinCtxPrepare(&ctx, skeinSize);\n\n    skeinMacInit(&ctx, key, key_length, mac_length);\n    while (*data) {\n        skeinUpdate(&ctx, *data, *data_length);\n        data++;\n        data_length ++;\n    }\n    skeinFinal(&ctx, mac);\n}\n\nvoid* createSkeinMacContext(uint8_t* key, int32_t key_length, \n                            int32_t mac_length, SkeinSize_t skeinSize)\n{\n    SkeinCtx_t* ctx = (SkeinCtx_t*)malloc(sizeof(SkeinCtx_t));\n    if (ctx == NULL)\n        return NULL;\n\n    skeinCtxPrepare(ctx, skeinSize);\n    skeinMacInit(ctx, key, key_length, mac_length);\n    return ctx;\n}\n\nvoid* initializeSkeinMacContext(void* ctx, uint8_t* key, int32_t key_length, int32_t mac_length, SkeinSize_t skeinSize)\n{\n    SkeinCtx_t* pctx = (SkeinCtx_t*)ctx;\n\n    skeinCtxPrepare(pctx, skeinSize);\n    skeinMacInit(pctx, key, key_length, mac_length);\n    return (void*)pctx;\n}\n\nvoid macSkeinCtx(void* ctx, const uint8_t* data, uint32_t data_length,\n                uint8_t* mac)\n{\n    SkeinCtx_t* pctx = (SkeinCtx_t*)ctx;\n\n    skeinUpdate(pctx, data, data_length);\n    skeinFinal(pctx, mac);\n    skeinReset(pctx);\n}\n\nvoid macSkeinCtx(void* ctx, const uint8_t* data[], uint32_t data_length[],\n                uint8_t* mac)\n{\n    SkeinCtx_t* pctx = (SkeinCtx_t*)ctx;\n\n    while (*data) {\n        skeinUpdate(pctx, *data, *data_length);\n        data++;\n        data_length++;\n    }\n    skeinFinal(pctx, mac);\n    skeinReset(pctx);\n}\n\nvoid freeSkeinMacContext(void* ctx)\n{\n    if (ctx)\n        free(ctx);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/macSkein.h",
    "content": "/*\n  Copyright (C) 2010-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n\n#ifndef MAC_SKEIN_H\n#define MAC_SKEIN_H\n\n#include <cryptcommon/skeinApi.h>\n/**\n * @file macSkein.h\n * @brief Function that provide Skein MAC support\n * \n *\n * Functions to compute Skein MAC.\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n/**\n * Compute Skein MAC.\n *\n * This functions takes one data chunk and computes its Skein MAC.\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lneght of the MAC key in bytes\n * @param data\n *    Points to the data chunk.\n * @param data_length\n *    Length of the data in bytes\n * @param mac\n *    Points to a buffer that receives the computed digest.\n * @param mac_length\n *    Integer that contains the length of the MAC in bits (not bytes).\n * @param skeinSize\n *    The Skein size to use.\n */\nvoid macSkein( uint8_t* key, int32_t key_length,\n                const uint8_t* data, uint32_t data_length,\n                uint8_t* mac, int32_t mac_length, SkeinSize_t skeinSize );\n\n/**\n * Compute Skein MAC over several data cunks.\n *\n * This functions takes several data chunk and computes the Skein MAC.\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lneght of the MAC key in bytes\n * @param data\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param data_length\n *    Points to an array of integers that hold the length of each data chunk.\n * @param mac\n *    Points to a buffer that receives the computed digest.\n * @param mac_length\n *    Integer that contains the length of the MAC in bits (not bytes).\n * @param skeinSize\n *    The Skein size to use.\n */\nvoid macSkein( uint8_t* key, int32_t key_length,\n                const uint8_t* data[], uint32_t data_length[],\n                uint8_t* mac, int32_t mac_length, SkeinSize_t skeinSize);\n\n/**\n * Create and initialize a Skein MAC context.\n *\n * An application uses this context to hash several data with on Skein MAC\n * Context with the same key, key length and mac length\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lenght of the MAC key in bytes\n * @param mac_length\n *    Integer that contains the length of the MAC in bits (not bytes).\n * @param skeinSize\n *    The Skein size to use.\n * @return Returns a pointer to the initialized context or @c NULL in case of an error.\n */\nvoid* createSkeinMacContext(uint8_t* key, int32_t key_length, int32_t mac_length, SkeinSize_t skeinSize);\n\n/**\n * Initialize a Skein MAC context.\n *\n * An application uses this context to hash several data with on Skein MAC\n * Context with the same key, key length and mac length\n *\n * @param ctx\n *     Pointer to initialized Skein MAC context\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lenght of the MAC key in bytes\n * @param mac_length\n *    Integer that contains the length of the MAC in bits (not bytes).\n * @param skeinSize\n *    The Skein size to use.\n * @return Returns a pointer to the initialized context\n */\nvoid* initializeSkeinMacContext(void* ctx, uint8_t* key, int32_t key_length, int32_t mac_length, SkeinSize_t skeinSize);\n\n/**\n * Compute Skein MAC.\n *\n * This functions takes one data chunk and computes its Skein MAC.\n *\n * @param ctx\n *     Pointer to initialized Skein MAC context\n * @param data\n *    Points to the data chunk.\n * @param data_length\n *    Length of the data in bytes\n * @param mac\n *    Points to a buffer that receives the computed digest.\n */\n\nvoid macSkeinCtx(void* ctx, const uint8_t* data, uint32_t data_length,\n                uint8_t* mac);\n\n/**\n * Compute Skein MAC over several data cunks.\n *\n * This functions takes several data chunk and computes the SHA1 HAMAC.\n *\n * @param ctx \n *     Pointer to initialized Skein MAC context\n * @param data\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param data_length\n *    Points to an array of integers that hold the length of each data chunk.\n * @param mac\n *    Points to a buffer that receives the computed digest.\n */\nvoid macSkeinCtx(void* ctx, const uint8_t* data[], uint32_t data_length[],\n                uint8_t* mac);\n\n/**\n * Free Skein MAC context.\n *\n * @param ctx a pointer to Skein MAC context\n */\nvoid freeSkeinMacContext(void* ctx);\n\n/**\n * @}\n */\n#endif"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/skein.c",
    "content": "/***********************************************************************\r\n**\r\n** Implementation of the Skein hash function.\r\n**\r\n** Source code author: Doug Whiting, 2008.\r\n**\r\n** This algorithm and source code is released to the public domain.\r\n**\r\n************************************************************************/\r\n\r\n#define  SKEIN_PORT_CODE /* instantiate any code in skein_port.h */\r\n\r\n#include <string.h>       /* get the memcpy/memset functions */\r\n#include <cryptcommon/skein.h> /* get the Skein API definitions   */\r\n#include <cryptcommon/skein_iv.h>    /* get precomputed IVs */\r\n\r\n/*****************************************************************/\r\n/* External function to process blkCnt (nonzero) full block(s) of data. */\r\nvoid    Skein_256_Process_Block(Skein_256_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd);\r\nvoid    Skein_512_Process_Block(Skein_512_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd);\r\nvoid    Skein1024_Process_Block(Skein1024_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd);\r\n\r\n/*****************************************************************/\r\n/*     256-bit Skein                                             */\r\n/*****************************************************************/\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* init the context for a straight hashing operation  */\r\nint Skein_256_Init(Skein_256_Ctxt_t *ctx, size_t hashBitLen)\r\n{\r\n    union\r\n    {\r\n        u08b_t  b[SKEIN_256_STATE_BYTES];\r\n        u64b_t  w[SKEIN_256_STATE_WORDS];\r\n    } cfg;                              /* config block */\r\n\r\n    Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\r\n    ctx->h.hashBitLen = hashBitLen;         /* output hash bit count */\r\n\r\n    switch (hashBitLen)\r\n    {             /* use pre-computed values, where available */\r\n    case  256:\r\n        memcpy(ctx->X,SKEIN_256_IV_256,sizeof(ctx->X));\r\n        break;\r\n    case  224:\r\n        memcpy(ctx->X,SKEIN_256_IV_224,sizeof(ctx->X));\r\n        break;\r\n    case  160:\r\n        memcpy(ctx->X,SKEIN_256_IV_160,sizeof(ctx->X));\r\n        break;\r\n    case  128:\r\n        memcpy(ctx->X,SKEIN_256_IV_128,sizeof(ctx->X));\r\n        break;\r\n    default:\r\n        /* here if there is no precomputed IV value available */\r\n        /* build/process the config block, type == CONFIG (could be precomputed) */\r\n        Skein_Start_New_Type(ctx,CFG_FINAL);        /* set tweaks: T0=0; T1=CFG | FINAL */\r\n\r\n        cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);  /* set the schema, version */\r\n        cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\r\n        cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);\r\n        memset(&cfg.w[3],0,sizeof(cfg) - 3*sizeof(cfg.w[0])); /* zero pad config block */\r\n\r\n        /* compute the initial chaining values from config block */\r\n        memset(ctx->X,0,sizeof(ctx->X));            /* zero the chaining variables */\r\n        Skein_256_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\r\n        break;\r\n    }\r\n    /* The chaining vars ctx->X are now initialized for the given hashBitLen. */\r\n    /* Set up to process the data message portion of the hash (default) */\r\n    Skein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type */\r\n\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* init the context for a MAC and/or tree hash operation */\r\n/* [identical to Skein_256_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */\r\nint Skein_256_InitExt(Skein_256_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)\r\n{\r\n    union\r\n    {\r\n        u08b_t  b[SKEIN_256_STATE_BYTES];\r\n        u64b_t  w[SKEIN_256_STATE_WORDS];\r\n    } cfg;                              /* config block */\r\n\r\n    Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\r\n    Skein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);\r\n\r\n    /* compute the initial chaining values ctx->X[], based on key */\r\n    if (keyBytes == 0)                          /* is there a key? */\r\n    {\r\n        memset(ctx->X,0,sizeof(ctx->X));        /* no key: use all zeroes as key for config block */\r\n    }\r\n    else                                        /* here to pre-process a key */\r\n    {\r\n        Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));\r\n        /* do a mini-Init right here */\r\n        ctx->h.hashBitLen=8*sizeof(ctx->X);     /* set output hash bit count = state size */\r\n        Skein_Start_New_Type(ctx,KEY);          /* set tweaks: T0 = 0; T1 = KEY type */\r\n        memset(ctx->X,0,sizeof(ctx->X));        /* zero the initial chaining variables */\r\n        Skein_256_Update(ctx,key,keyBytes);     /* hash the key */\r\n        Skein_256_Final_Pad(ctx,cfg.b);         /* put result into cfg.b[] */\r\n        memcpy(ctx->X,cfg.b,sizeof(cfg.b));     /* copy over into ctx->X[] */\r\n#if SKEIN_NEED_SWAP\r\n        {\r\n            uint_t i;\r\n            for (i=0;i<SKEIN_256_STATE_WORDS;i++)   /* convert key bytes to context words */\r\n                ctx->X[i] = Skein_Swap64(ctx->X[i]);\r\n        }\r\n#endif\r\n    }\r\n    /* build/process the config block, type == CONFIG (could be precomputed for each key) */\r\n    ctx->h.hashBitLen = hashBitLen;             /* output hash bit count */\r\n    Skein_Start_New_Type(ctx,CFG_FINAL);\r\n\r\n    memset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */\r\n    cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);\r\n    cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\r\n    cfg.w[2] = Skein_Swap64(treeInfo);          /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */\r\n\r\n    Skein_Show_Key(256,&ctx->h,key,keyBytes);\r\n\r\n    /* compute the initial chaining values from config block */\r\n    Skein_256_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\r\n\r\n    /* The chaining vars ctx->X are now initialized */\r\n    /* Set up to process the data message portion of the hash (default) */\r\n    Skein_Start_New_Type(ctx,MSG);\r\n\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* process the input bytes */\r\nint Skein_256_Update(Skein_256_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)\r\n{\r\n    size_t n;\r\n\r\n    Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r\n\r\n    /* process full blocks, if any */\r\n    if (msgByteCnt + ctx->h.bCnt > SKEIN_256_BLOCK_BYTES)\r\n    {\r\n        if (ctx->h.bCnt)                              /* finish up any buffered message data */\r\n        {\r\n            n = SKEIN_256_BLOCK_BYTES - ctx->h.bCnt;  /* # bytes free in buffer b[] */\r\n            if (n)\r\n            {\r\n                Skein_assert(n < msgByteCnt);         /* check on our logic here */\r\n                memcpy(&ctx->b[ctx->h.bCnt],msg,n);\r\n                msgByteCnt  -= n;\r\n                msg         += n;\r\n                ctx->h.bCnt += n;\r\n            }\r\n            Skein_assert(ctx->h.bCnt == SKEIN_256_BLOCK_BYTES);\r\n            Skein_256_Process_Block(ctx,ctx->b,1,SKEIN_256_BLOCK_BYTES);\r\n            ctx->h.bCnt = 0;\r\n        }\r\n        /* now process any remaining full blocks, directly from input message data */\r\n        if (msgByteCnt > SKEIN_256_BLOCK_BYTES)\r\n        {\r\n            n = (msgByteCnt-1) / SKEIN_256_BLOCK_BYTES;   /* number of full blocks to process */\r\n            Skein_256_Process_Block(ctx,msg,n,SKEIN_256_BLOCK_BYTES);\r\n            msgByteCnt -= n * SKEIN_256_BLOCK_BYTES;\r\n            msg        += n * SKEIN_256_BLOCK_BYTES;\r\n        }\r\n        Skein_assert(ctx->h.bCnt == 0);\r\n    }\r\n\r\n    /* copy any remaining source message data bytes into b[] */\r\n    if (msgByteCnt)\r\n    {\r\n        Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES);\r\n        memcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);\r\n        ctx->h.bCnt += msgByteCnt;\r\n    }\r\n\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* finalize the hash computation and output the result */\r\nint Skein_256_Final(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)\r\n{\r\n    size_t i,n,byteCnt;\r\n    u64b_t X[SKEIN_256_STATE_WORDS];\r\n    Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r\n\r\n    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;                 /* tag as the final block */\r\n    if (ctx->h.bCnt < SKEIN_256_BLOCK_BYTES)            /* zero pad b[] if necessary */\r\n        memset(&ctx->b[ctx->h.bCnt],0,SKEIN_256_BLOCK_BYTES - ctx->h.bCnt);\r\n\r\n    Skein_256_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);  /* process the final block */\r\n\r\n    /* now output the result */\r\n    byteCnt = (ctx->h.hashBitLen + 7) >> 3;             /* total number of output bytes */\r\n\r\n    /* run Threefish in \"counter mode\" to generate output */\r\n    memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\r\n    memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode \"key\" */\r\n    for (i=0;i*SKEIN_256_BLOCK_BYTES < byteCnt;i++)\r\n    {\r\n        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\r\n        Skein_Start_New_Type(ctx,OUT_FINAL);\r\n        Skein_256_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run \"counter mode\" */\r\n        n = byteCnt - i*SKEIN_256_BLOCK_BYTES;   /* number of output bytes left to go */\r\n        if (n >= SKEIN_256_BLOCK_BYTES)\r\n            n  = SKEIN_256_BLOCK_BYTES;\r\n        Skein_Put64_LSB_First(hashVal+i*SKEIN_256_BLOCK_BYTES,ctx->X,n);   /* \"output\" the ctr mode bytes */\r\n        Skein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN_256_BLOCK_BYTES);\r\n        memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\r\n    }\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*****************************************************************/\r\n/*     512-bit Skein                                             */\r\n/*****************************************************************/\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* init the context for a straight hashing operation  */\r\nint Skein_512_Init(Skein_512_Ctxt_t *ctx, size_t hashBitLen)\r\n{\r\n    union\r\n    {\r\n        u08b_t  b[SKEIN_512_STATE_BYTES];\r\n        u64b_t  w[SKEIN_512_STATE_WORDS];\r\n    } cfg;                              /* config block */\r\n\r\n    Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\r\n    ctx->h.hashBitLen = hashBitLen;         /* output hash bit count */\r\n\r\n    switch (hashBitLen)\r\n    {             /* use pre-computed values, where available */\r\n    case  512:\r\n        memcpy(ctx->X,SKEIN_512_IV_512,sizeof(ctx->X));\r\n        break;\r\n    case  384:\r\n        memcpy(ctx->X,SKEIN_512_IV_384,sizeof(ctx->X));\r\n        break;\r\n    case  256:\r\n        memcpy(ctx->X,SKEIN_512_IV_256,sizeof(ctx->X));\r\n        break;\r\n    case  224:\r\n        memcpy(ctx->X,SKEIN_512_IV_224,sizeof(ctx->X));\r\n        break;\r\n    default:\r\n        /* here if there is no precomputed IV value available */\r\n        /* build/process the config block, type == CONFIG (could be precomputed) */\r\n        Skein_Start_New_Type(ctx,CFG_FINAL);        /* set tweaks: T0=0; T1=CFG | FINAL */\r\n\r\n        cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);  /* set the schema, version */\r\n        cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\r\n        cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);\r\n        memset(&cfg.w[3],0,sizeof(cfg) - 3*sizeof(cfg.w[0])); /* zero pad config block */\r\n\r\n        /* compute the initial chaining values from config block */\r\n        memset(ctx->X,0,sizeof(ctx->X));            /* zero the chaining variables */\r\n        Skein_512_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\r\n        break;\r\n    }\r\n\r\n    /* The chaining vars ctx->X are now initialized for the given hashBitLen. */\r\n    /* Set up to process the data message portion of the hash (default) */\r\n    Skein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type */\r\n\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* init the context for a MAC and/or tree hash operation */\r\n/* [identical to Skein_512_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */\r\nint Skein_512_InitExt(Skein_512_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)\r\n{\r\n    union\r\n    {\r\n        u08b_t  b[SKEIN_512_STATE_BYTES];\r\n        u64b_t  w[SKEIN_512_STATE_WORDS];\r\n    } cfg;                              /* config block */\r\n\r\n    Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\r\n    Skein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);\r\n\r\n    /* compute the initial chaining values ctx->X[], based on key */\r\n    if (keyBytes == 0)                          /* is there a key? */\r\n    {\r\n        memset(ctx->X,0,sizeof(ctx->X));        /* no key: use all zeroes as key for config block */\r\n    }\r\n    else                                        /* here to pre-process a key */\r\n    {\r\n        Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));\r\n        /* do a mini-Init right here */\r\n        ctx->h.hashBitLen=8*sizeof(ctx->X);     /* set output hash bit count = state size */\r\n        Skein_Start_New_Type(ctx,KEY);          /* set tweaks: T0 = 0; T1 = KEY type */\r\n        memset(ctx->X,0,sizeof(ctx->X));        /* zero the initial chaining variables */\r\n        Skein_512_Update(ctx,key,keyBytes);     /* hash the key */\r\n        Skein_512_Final_Pad(ctx,cfg.b);         /* put result into cfg.b[] */\r\n        memcpy(ctx->X,cfg.b,sizeof(cfg.b));     /* copy over into ctx->X[] */\r\n#if SKEIN_NEED_SWAP\r\n        {\r\n            uint_t i;\r\n            for (i=0;i<SKEIN_512_STATE_WORDS;i++)   /* convert key bytes to context words */\r\n                ctx->X[i] = Skein_Swap64(ctx->X[i]);\r\n        }\r\n#endif\r\n    }\r\n    /* build/process the config block, type == CONFIG (could be precomputed for each key) */\r\n    ctx->h.hashBitLen = hashBitLen;             /* output hash bit count */\r\n    Skein_Start_New_Type(ctx,CFG_FINAL);\r\n\r\n    memset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */\r\n    cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);\r\n    cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\r\n    cfg.w[2] = Skein_Swap64(treeInfo);          /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */\r\n\r\n    Skein_Show_Key(512,&ctx->h,key,keyBytes);\r\n\r\n    /* compute the initial chaining values from config block */\r\n    Skein_512_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\r\n\r\n    /* The chaining vars ctx->X are now initialized */\r\n    /* Set up to process the data message portion of the hash (default) */\r\n    Skein_Start_New_Type(ctx,MSG);\r\n\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* process the input bytes */\r\nint Skein_512_Update(Skein_512_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)\r\n{\r\n    size_t n;\r\n\r\n    Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r\n\r\n    /* process full blocks, if any */\r\n    if (msgByteCnt + ctx->h.bCnt > SKEIN_512_BLOCK_BYTES)\r\n    {\r\n        if (ctx->h.bCnt)                              /* finish up any buffered message data */\r\n        {\r\n            n = SKEIN_512_BLOCK_BYTES - ctx->h.bCnt;  /* # bytes free in buffer b[] */\r\n            if (n)\r\n            {\r\n                Skein_assert(n < msgByteCnt);         /* check on our logic here */\r\n                memcpy(&ctx->b[ctx->h.bCnt],msg,n);\r\n                msgByteCnt  -= n;\r\n                msg         += n;\r\n                ctx->h.bCnt += n;\r\n            }\r\n            Skein_assert(ctx->h.bCnt == SKEIN_512_BLOCK_BYTES);\r\n            Skein_512_Process_Block(ctx,ctx->b,1,SKEIN_512_BLOCK_BYTES);\r\n            ctx->h.bCnt = 0;\r\n        }\r\n        /* now process any remaining full blocks, directly from input message data */\r\n        if (msgByteCnt > SKEIN_512_BLOCK_BYTES)\r\n        {\r\n            n = (msgByteCnt-1) / SKEIN_512_BLOCK_BYTES;   /* number of full blocks to process */\r\n            Skein_512_Process_Block(ctx,msg,n,SKEIN_512_BLOCK_BYTES);\r\n            msgByteCnt -= n * SKEIN_512_BLOCK_BYTES;\r\n            msg        += n * SKEIN_512_BLOCK_BYTES;\r\n        }\r\n        Skein_assert(ctx->h.bCnt == 0);\r\n    }\r\n\r\n    /* copy any remaining source message data bytes into b[] */\r\n    if (msgByteCnt)\r\n    {\r\n        Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES);\r\n        memcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);\r\n        ctx->h.bCnt += msgByteCnt;\r\n    }\r\n\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* finalize the hash computation and output the result */\r\nint Skein_512_Final(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)\r\n{\r\n    size_t i,n,byteCnt;\r\n    u64b_t X[SKEIN_512_STATE_WORDS];\r\n    Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r\n\r\n    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;                 /* tag as the final block */\r\n    if (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES)            /* zero pad b[] if necessary */\r\n        memset(&ctx->b[ctx->h.bCnt],0,SKEIN_512_BLOCK_BYTES - ctx->h.bCnt);\r\n\r\n    Skein_512_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);  /* process the final block */\r\n\r\n    /* now output the result */\r\n    byteCnt = (ctx->h.hashBitLen + 7) >> 3;             /* total number of output bytes */\r\n\r\n    /* run Threefish in \"counter mode\" to generate output */\r\n    memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\r\n    memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode \"key\" */\r\n    for (i=0;i*SKEIN_512_BLOCK_BYTES < byteCnt;i++)\r\n    {\r\n        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\r\n        Skein_Start_New_Type(ctx,OUT_FINAL);\r\n        Skein_512_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run \"counter mode\" */\r\n        n = byteCnt - i*SKEIN_512_BLOCK_BYTES;   /* number of output bytes left to go */\r\n        if (n >= SKEIN_512_BLOCK_BYTES)\r\n            n  = SKEIN_512_BLOCK_BYTES;\r\n        Skein_Put64_LSB_First(hashVal+i*SKEIN_512_BLOCK_BYTES,ctx->X,n);   /* \"output\" the ctr mode bytes */\r\n        Skein_Show_Final(512,&ctx->h,n,hashVal+i*SKEIN_512_BLOCK_BYTES);\r\n        memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\r\n    }\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*****************************************************************/\r\n/*    1024-bit Skein                                             */\r\n/*****************************************************************/\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* init the context for a straight hashing operation  */\r\nint Skein1024_Init(Skein1024_Ctxt_t *ctx, size_t hashBitLen)\r\n{\r\n    union\r\n    {\r\n        u08b_t  b[SKEIN1024_STATE_BYTES];\r\n        u64b_t  w[SKEIN1024_STATE_WORDS];\r\n    } cfg;                              /* config block */\r\n\r\n    Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\r\n    ctx->h.hashBitLen = hashBitLen;         /* output hash bit count */\r\n\r\n    switch (hashBitLen)\r\n    {              /* use pre-computed values, where available */\r\n    case  512:\r\n        memcpy(ctx->X,SKEIN1024_IV_512 ,sizeof(ctx->X));\r\n        break;\r\n    case  384:\r\n        memcpy(ctx->X,SKEIN1024_IV_384 ,sizeof(ctx->X));\r\n        break;\r\n    case 1024:\r\n        memcpy(ctx->X,SKEIN1024_IV_1024,sizeof(ctx->X));\r\n        break;\r\n    default:\r\n        /* here if there is no precomputed IV value available */\r\n        /* build/process the config block, type == CONFIG (could be precomputed) */\r\n        Skein_Start_New_Type(ctx,CFG_FINAL);        /* set tweaks: T0=0; T1=CFG | FINAL */\r\n\r\n        cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);  /* set the schema, version */\r\n        cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\r\n        cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);\r\n        memset(&cfg.w[3],0,sizeof(cfg) - 3*sizeof(cfg.w[0])); /* zero pad config block */\r\n\r\n        /* compute the initial chaining values from config block */\r\n        memset(ctx->X,0,sizeof(ctx->X));            /* zero the chaining variables */\r\n        Skein1024_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\r\n        break;\r\n    }\r\n\r\n    /* The chaining vars ctx->X are now initialized for the given hashBitLen. */\r\n    /* Set up to process the data message portion of the hash (default) */\r\n    Skein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type */\r\n\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* init the context for a MAC and/or tree hash operation */\r\n/* [identical to Skein1024_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */\r\nint Skein1024_InitExt(Skein1024_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)\r\n{\r\n    union\r\n    {\r\n        u08b_t  b[SKEIN1024_STATE_BYTES];\r\n        u64b_t  w[SKEIN1024_STATE_WORDS];\r\n    } cfg;                              /* config block */\r\n\r\n    Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\r\n    Skein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);\r\n\r\n    /* compute the initial chaining values ctx->X[], based on key */\r\n    if (keyBytes == 0)                          /* is there a key? */\r\n    {\r\n        memset(ctx->X,0,sizeof(ctx->X));        /* no key: use all zeroes as key for config block */\r\n    }\r\n    else                                        /* here to pre-process a key */\r\n    {\r\n        Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));\r\n        /* do a mini-Init right here */\r\n        ctx->h.hashBitLen=8*sizeof(ctx->X);     /* set output hash bit count = state size */\r\n        Skein_Start_New_Type(ctx,KEY);          /* set tweaks: T0 = 0; T1 = KEY type */\r\n        memset(ctx->X,0,sizeof(ctx->X));        /* zero the initial chaining variables */\r\n        Skein1024_Update(ctx,key,keyBytes);     /* hash the key */\r\n        Skein1024_Final_Pad(ctx,cfg.b);         /* put result into cfg.b[] */\r\n        memcpy(ctx->X,cfg.b,sizeof(cfg.b));     /* copy over into ctx->X[] */\r\n#if SKEIN_NEED_SWAP\r\n        {\r\n            uint_t i;\r\n            for (i=0;i<SKEIN1024_STATE_WORDS;i++)   /* convert key bytes to context words */\r\n                ctx->X[i] = Skein_Swap64(ctx->X[i]);\r\n        }\r\n#endif\r\n    }\r\n    /* build/process the config block, type == CONFIG (could be precomputed for each key) */\r\n    ctx->h.hashBitLen = hashBitLen;             /* output hash bit count */\r\n    Skein_Start_New_Type(ctx,CFG_FINAL);\r\n\r\n    memset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */\r\n    cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);\r\n    cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\r\n    cfg.w[2] = Skein_Swap64(treeInfo);          /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */\r\n\r\n    Skein_Show_Key(1024,&ctx->h,key,keyBytes);\r\n\r\n    /* compute the initial chaining values from config block */\r\n    Skein1024_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\r\n\r\n    /* The chaining vars ctx->X are now initialized */\r\n    /* Set up to process the data message portion of the hash (default) */\r\n    Skein_Start_New_Type(ctx,MSG);\r\n\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* process the input bytes */\r\nint Skein1024_Update(Skein1024_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)\r\n{\r\n    size_t n;\r\n\r\n    Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r\n\r\n    /* process full blocks, if any */\r\n    if (msgByteCnt + ctx->h.bCnt > SKEIN1024_BLOCK_BYTES)\r\n    {\r\n        if (ctx->h.bCnt)                              /* finish up any buffered message data */\r\n        {\r\n            n = SKEIN1024_BLOCK_BYTES - ctx->h.bCnt;  /* # bytes free in buffer b[] */\r\n            if (n)\r\n            {\r\n                Skein_assert(n < msgByteCnt);         /* check on our logic here */\r\n                memcpy(&ctx->b[ctx->h.bCnt],msg,n);\r\n                msgByteCnt  -= n;\r\n                msg         += n;\r\n                ctx->h.bCnt += n;\r\n            }\r\n            Skein_assert(ctx->h.bCnt == SKEIN1024_BLOCK_BYTES);\r\n            Skein1024_Process_Block(ctx,ctx->b,1,SKEIN1024_BLOCK_BYTES);\r\n            ctx->h.bCnt = 0;\r\n        }\r\n        /* now process any remaining full blocks, directly from input message data */\r\n        if (msgByteCnt > SKEIN1024_BLOCK_BYTES)\r\n        {\r\n            n = (msgByteCnt-1) / SKEIN1024_BLOCK_BYTES;   /* number of full blocks to process */\r\n            Skein1024_Process_Block(ctx,msg,n,SKEIN1024_BLOCK_BYTES);\r\n            msgByteCnt -= n * SKEIN1024_BLOCK_BYTES;\r\n            msg        += n * SKEIN1024_BLOCK_BYTES;\r\n        }\r\n        Skein_assert(ctx->h.bCnt == 0);\r\n    }\r\n\r\n    /* copy any remaining source message data bytes into b[] */\r\n    if (msgByteCnt)\r\n    {\r\n        Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES);\r\n        memcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);\r\n        ctx->h.bCnt += msgByteCnt;\r\n    }\r\n\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* finalize the hash computation and output the result */\r\nint Skein1024_Final(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)\r\n{\r\n    size_t i,n,byteCnt;\r\n    u64b_t X[SKEIN1024_STATE_WORDS];\r\n    Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r\n\r\n    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;                 /* tag as the final block */\r\n    if (ctx->h.bCnt < SKEIN1024_BLOCK_BYTES)            /* zero pad b[] if necessary */\r\n        memset(&ctx->b[ctx->h.bCnt],0,SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);\r\n\r\n    Skein1024_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);  /* process the final block */\r\n\r\n    /* now output the result */\r\n    byteCnt = (ctx->h.hashBitLen + 7) >> 3;             /* total number of output bytes */\r\n\r\n    /* run Threefish in \"counter mode\" to generate output */\r\n    memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\r\n    memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode \"key\" */\r\n    for (i=0;i*SKEIN1024_BLOCK_BYTES < byteCnt;i++)\r\n    {\r\n        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\r\n        Skein_Start_New_Type(ctx,OUT_FINAL);\r\n        Skein1024_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run \"counter mode\" */\r\n        n = byteCnt - i*SKEIN1024_BLOCK_BYTES;   /* number of output bytes left to go */\r\n        if (n >= SKEIN1024_BLOCK_BYTES)\r\n            n  = SKEIN1024_BLOCK_BYTES;\r\n        Skein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES,ctx->X,n);   /* \"output\" the ctr mode bytes */\r\n        Skein_Show_Final(1024,&ctx->h,n,hashVal+i*SKEIN1024_BLOCK_BYTES);\r\n        memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\r\n    }\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/**************** Functions to support MAC/tree hashing ***************/\r\n/*   (this code is identical for Optimized and Reference versions)    */\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* finalize the hash computation and output the block, no OUTPUT stage */\r\nint Skein_256_Final_Pad(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)\r\n{\r\n    Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r\n\r\n    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;        /* tag as the final block */\r\n    if (ctx->h.bCnt < SKEIN_256_BLOCK_BYTES)   /* zero pad b[] if necessary */\r\n        memset(&ctx->b[ctx->h.bCnt],0,SKEIN_256_BLOCK_BYTES - ctx->h.bCnt);\r\n    Skein_256_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);    /* process the final block */\r\n\r\n    Skein_Put64_LSB_First(hashVal,ctx->X,SKEIN_256_BLOCK_BYTES);   /* \"output\" the state bytes */\r\n\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* finalize the hash computation and output the block, no OUTPUT stage */\r\nint Skein_512_Final_Pad(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)\r\n{\r\n    Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r\n\r\n    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;        /* tag as the final block */\r\n    if (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES)   /* zero pad b[] if necessary */\r\n        memset(&ctx->b[ctx->h.bCnt],0,SKEIN_512_BLOCK_BYTES - ctx->h.bCnt);\r\n    Skein_512_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);    /* process the final block */\r\n\r\n    Skein_Put64_LSB_First(hashVal,ctx->X,SKEIN_512_BLOCK_BYTES);   /* \"output\" the state bytes */\r\n\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* finalize the hash computation and output the block, no OUTPUT stage */\r\nint Skein1024_Final_Pad(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)\r\n{\r\n    Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r\n\r\n    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;        /* tag as the final block */\r\n    if (ctx->h.bCnt < SKEIN1024_BLOCK_BYTES)   /* zero pad b[] if necessary */\r\n        memset(&ctx->b[ctx->h.bCnt],0,SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);\r\n    Skein1024_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);    /* process the final block */\r\n\r\n    Skein_Put64_LSB_First(hashVal,ctx->X,SKEIN1024_BLOCK_BYTES);   /* \"output\" the state bytes */\r\n\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n#if SKEIN_TREE_HASH\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* just do the OUTPUT stage                                       */\r\nint Skein_256_Output(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)\r\n{\r\n    size_t i,n,byteCnt;\r\n    u64b_t X[SKEIN_256_STATE_WORDS];\r\n    Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r\n\r\n    /* now output the result */\r\n    byteCnt = (ctx->h.hashBitLen + 7) >> 3;    /* total number of output bytes */\r\n\r\n    /* run Threefish in \"counter mode\" to generate output */\r\n    memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\r\n    memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode \"key\" */\r\n    for (i=0;i*SKEIN_256_BLOCK_BYTES < byteCnt;i++)\r\n    {\r\n        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\r\n        Skein_Start_New_Type(ctx,OUT_FINAL);\r\n        Skein_256_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run \"counter mode\" */\r\n        n = byteCnt - i*SKEIN_256_BLOCK_BYTES;   /* number of output bytes left to go */\r\n        if (n >= SKEIN_256_BLOCK_BYTES)\r\n            n  = SKEIN_256_BLOCK_BYTES;\r\n        Skein_Put64_LSB_First(hashVal+i*SKEIN_256_BLOCK_BYTES,ctx->X,n);   /* \"output\" the ctr mode bytes */\r\n        Skein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN_256_BLOCK_BYTES);\r\n        memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\r\n    }\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* just do the OUTPUT stage                                       */\r\nint Skein_512_Output(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)\r\n{\r\n    size_t i,n,byteCnt;\r\n    u64b_t X[SKEIN_512_STATE_WORDS];\r\n    Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r\n\r\n    /* now output the result */\r\n    byteCnt = (ctx->h.hashBitLen + 7) >> 3;    /* total number of output bytes */\r\n\r\n    /* run Threefish in \"counter mode\" to generate output */\r\n    memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\r\n    memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode \"key\" */\r\n    for (i=0;i*SKEIN_512_BLOCK_BYTES < byteCnt;i++)\r\n    {\r\n        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\r\n        Skein_Start_New_Type(ctx,OUT_FINAL);\r\n        Skein_512_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run \"counter mode\" */\r\n        n = byteCnt - i*SKEIN_512_BLOCK_BYTES;   /* number of output bytes left to go */\r\n        if (n >= SKEIN_512_BLOCK_BYTES)\r\n            n  = SKEIN_512_BLOCK_BYTES;\r\n        Skein_Put64_LSB_First(hashVal+i*SKEIN_512_BLOCK_BYTES,ctx->X,n);   /* \"output\" the ctr mode bytes */\r\n        Skein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN_512_BLOCK_BYTES);\r\n        memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\r\n    }\r\n    return SKEIN_SUCCESS;\r\n}\r\n\r\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r\n/* just do the OUTPUT stage                                       */\r\nint Skein1024_Output(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)\r\n{\r\n    size_t i,n,byteCnt;\r\n    u64b_t X[SKEIN1024_STATE_WORDS];\r\n    Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r\n\r\n    /* now output the result */\r\n    byteCnt = (ctx->h.hashBitLen + 7) >> 3;    /* total number of output bytes */\r\n\r\n    /* run Threefish in \"counter mode\" to generate output */\r\n    memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\r\n    memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode \"key\" */\r\n    for (i=0;i*SKEIN1024_BLOCK_BYTES < byteCnt;i++)\r\n    {\r\n        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\r\n        Skein_Start_New_Type(ctx,OUT_FINAL);\r\n        Skein1024_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run \"counter mode\" */\r\n        n = byteCnt - i*SKEIN1024_BLOCK_BYTES;   /* number of output bytes left to go */\r\n        if (n >= SKEIN1024_BLOCK_BYTES)\r\n            n  = SKEIN1024_BLOCK_BYTES;\r\n        Skein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES,ctx->X,n);   /* \"output\" the ctr mode bytes */\r\n        Skein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN1024_BLOCK_BYTES);\r\n        memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\r\n    }\r\n    return SKEIN_SUCCESS;\r\n}\r\n#endif\r\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/skein.h",
    "content": "#ifndef _SKEIN_H_\r\n#define _SKEIN_H_     1\r\n/**************************************************************************\r\n**\r\n** Interface declarations and internal definitions for Skein hashing.\r\n**\r\n** Source code author: Doug Whiting, 2008.\r\n**\r\n** This algorithm and source code is released to the public domain.\r\n**\r\n***************************************************************************\r\n** \r\n** The following compile-time switches may be defined to control some\r\n** tradeoffs between speed, code size, error checking, and security.\r\n**\r\n** The \"default\" note explains what happens when the switch is not defined.\r\n**\r\n**  SKEIN_DEBUG            -- make callouts from inside Skein code\r\n**                            to examine/display intermediate values.\r\n**                            [default: no callouts (no overhead)]\r\n**\r\n**  SKEIN_ERR_CHECK        -- how error checking is handled inside Skein\r\n**                            code. If not defined, most error checking \r\n**                            is disabled (for performance). Otherwise, \r\n**                            the switch value is interpreted as:\r\n**                                0: use assert()      to flag errors\r\n**                                1: return SKEIN_FAIL to flag errors\r\n**\r\n***************************************************************************/\r\n#ifdef __cplusplus\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\n#include <stddef.h>                          /* get size_t definition */\r\n#include <cryptcommon/skein_port.h>          /* get platform-specific definitions */\r\n\r\nenum\r\n    {\r\n    SKEIN_SUCCESS         =      0,          /* return codes from Skein calls */\r\n    SKEIN_FAIL            =      1,\r\n    SKEIN_BAD_HASHLEN     =      2\r\n    };\r\n\r\n#define  SKEIN_MODIFIER_WORDS  ( 2)          /* number of modifier (tweak) words */\r\n\r\n#define  SKEIN_256_STATE_WORDS ( 4)\r\n#define  SKEIN_512_STATE_WORDS ( 8)\r\n#define  SKEIN1024_STATE_WORDS (16)\r\n#define  SKEIN_MAX_STATE_WORDS (16)\r\n\r\n#define  SKEIN_256_STATE_BYTES ( 8*SKEIN_256_STATE_WORDS)\r\n#define  SKEIN_512_STATE_BYTES ( 8*SKEIN_512_STATE_WORDS)\r\n#define  SKEIN1024_STATE_BYTES ( 8*SKEIN1024_STATE_WORDS)\r\n\r\n#define  SKEIN_256_STATE_BITS  (64*SKEIN_256_STATE_WORDS)\r\n#define  SKEIN_512_STATE_BITS  (64*SKEIN_512_STATE_WORDS)\r\n#define  SKEIN1024_STATE_BITS  (64*SKEIN1024_STATE_WORDS)\r\n\r\n#define  SKEIN_256_BLOCK_BYTES ( 8*SKEIN_256_STATE_WORDS)\r\n#define  SKEIN_512_BLOCK_BYTES ( 8*SKEIN_512_STATE_WORDS)\r\n#define  SKEIN1024_BLOCK_BYTES ( 8*SKEIN1024_STATE_WORDS)\r\n\r\ntypedef struct\r\n    {\r\n    size_t  hashBitLen;                      /* size of hash result, in bits */\r\n    size_t  bCnt;                            /* current byte count in buffer b[] */\r\n    u64b_t  T[SKEIN_MODIFIER_WORDS];         /* tweak words: T[0]=byte cnt, T[1]=flags */\r\n    } Skein_Ctxt_Hdr_t;\r\n\r\ntypedef struct                               /*  256-bit Skein hash context structure */\r\n    {\r\n    Skein_Ctxt_Hdr_t h;                      /* common header context variables */\r\n    u64b_t  X[SKEIN_256_STATE_WORDS];        /* chaining variables */\r\n    u08b_t  b[SKEIN_256_BLOCK_BYTES];        /* partial block buffer (8-byte aligned) */\r\n    } Skein_256_Ctxt_t;\r\n\r\ntypedef struct                               /*  512-bit Skein hash context structure */\r\n    {\r\n    Skein_Ctxt_Hdr_t h;                      /* common header context variables */\r\n    u64b_t  X[SKEIN_512_STATE_WORDS];        /* chaining variables */\r\n    u08b_t  b[SKEIN_512_BLOCK_BYTES];        /* partial block buffer (8-byte aligned) */\r\n    } Skein_512_Ctxt_t;\r\n\r\ntypedef struct                               /* 1024-bit Skein hash context structure */\r\n    {\r\n    Skein_Ctxt_Hdr_t h;                      /* common header context variables */\r\n    u64b_t  X[SKEIN1024_STATE_WORDS];        /* chaining variables */\r\n    u08b_t  b[SKEIN1024_BLOCK_BYTES];        /* partial block buffer (8-byte aligned) */\r\n    } Skein1024_Ctxt_t;\r\n\r\n/*   Skein APIs for (incremental) \"straight hashing\" */\r\nint  Skein_256_Init  (Skein_256_Ctxt_t *ctx, size_t hashBitLen);\r\nint  Skein_512_Init  (Skein_512_Ctxt_t *ctx, size_t hashBitLen);\r\nint  Skein1024_Init  (Skein1024_Ctxt_t *ctx, size_t hashBitLen);\r\n\r\nint  Skein_256_Update(Skein_256_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt);\r\nint  Skein_512_Update(Skein_512_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt);\r\nint  Skein1024_Update(Skein1024_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt);\r\n\r\nint  Skein_256_Final (Skein_256_Ctxt_t *ctx, u08b_t * hashVal);\r\nint  Skein_512_Final (Skein_512_Ctxt_t *ctx, u08b_t * hashVal);\r\nint  Skein1024_Final (Skein1024_Ctxt_t *ctx, u08b_t * hashVal);\r\n\r\n/*\r\n**   Skein APIs for \"extended\" initialization: MAC keys, tree hashing.\r\n**   After an InitExt() call, just use Update/Final calls as with Init().\r\n**\r\n**   Notes: Same parameters as _Init() calls, plus treeInfo/key/keyBytes.\r\n**          When keyBytes == 0 and treeInfo == SKEIN_SEQUENTIAL, \r\n**              the results of InitExt() are identical to calling Init().\r\n**          The function Init() may be called once to \"precompute\" the IV for\r\n**              a given hashBitLen value, then by saving a copy of the context\r\n**              the IV computation may be avoided in later calls.\r\n**          Similarly, the function InitExt() may be called once per MAC key \r\n**              to precompute the MAC IV, then a copy of the context saved and\r\n**              reused for each new MAC computation.\r\n**/\r\nint  Skein_256_InitExt(Skein_256_Ctxt_t *ctx, size_t hashBitLen, u64b_t treeInfo, const u08b_t *key, size_t keyBytes);\r\nint  Skein_512_InitExt(Skein_512_Ctxt_t *ctx, size_t hashBitLen, u64b_t treeInfo, const u08b_t *key, size_t keyBytes);\r\nint  Skein1024_InitExt(Skein1024_Ctxt_t *ctx, size_t hashBitLen, u64b_t treeInfo, const u08b_t *key, size_t keyBytes);\r\n\r\n/*\r\n**   Skein APIs for MAC and tree hash:\r\n**      Final_Pad:  pad, do final block, but no OUTPUT type\r\n**      Output:     do just the output stage\r\n*/\r\nint  Skein_256_Final_Pad(Skein_256_Ctxt_t *ctx, u08b_t * hashVal);\r\nint  Skein_512_Final_Pad(Skein_512_Ctxt_t *ctx, u08b_t * hashVal);\r\nint  Skein1024_Final_Pad(Skein1024_Ctxt_t *ctx, u08b_t * hashVal);\r\n\r\n#ifndef SKEIN_TREE_HASH\r\n#define SKEIN_TREE_HASH (1)\r\n#endif\r\n#if  SKEIN_TREE_HASH\r\nint  Skein_256_Output   (Skein_256_Ctxt_t *ctx, u08b_t * hashVal);\r\nint  Skein_512_Output   (Skein_512_Ctxt_t *ctx, u08b_t * hashVal);\r\nint  Skein1024_Output   (Skein1024_Ctxt_t *ctx, u08b_t * hashVal);\r\n#endif\r\n\r\n/*****************************************************************\r\n** \"Internal\" Skein definitions\r\n**    -- not needed for sequential hashing API, but will be \r\n**           helpful for other uses of Skein (e.g., tree hash mode).\r\n**    -- included here so that they can be shared between\r\n**           reference and optimized code.\r\n******************************************************************/\r\n\r\n/* tweak word T[1]: bit field starting positions */\r\n#define SKEIN_T1_BIT(BIT)       ((BIT) - 64)            /* offset 64 because it's the second word  */\r\n                                \r\n#define SKEIN_T1_POS_TREE_LVL   SKEIN_T1_BIT(112)       /* bits 112..118: level in hash tree       */\r\n#define SKEIN_T1_POS_BIT_PAD    SKEIN_T1_BIT(119)       /* bit  119     : partial final input byte */\r\n#define SKEIN_T1_POS_BLK_TYPE   SKEIN_T1_BIT(120)       /* bits 120..125: type field               */\r\n#define SKEIN_T1_POS_FIRST      SKEIN_T1_BIT(126)       /* bits 126     : first block flag         */\r\n#define SKEIN_T1_POS_FINAL      SKEIN_T1_BIT(127)       /* bit  127     : final block flag         */\r\n                                \r\n/* tweak word T[1]: flag bit definition(s) */\r\n#define SKEIN_T1_FLAG_FIRST     (((u64b_t)  1 ) << SKEIN_T1_POS_FIRST)\r\n#define SKEIN_T1_FLAG_FINAL     (((u64b_t)  1 ) << SKEIN_T1_POS_FINAL)\r\n#define SKEIN_T1_FLAG_BIT_PAD   (((u64b_t)  1 ) << SKEIN_T1_POS_BIT_PAD)\r\n                                \r\n/* tweak word T[1]: tree level bit field mask */\r\n#define SKEIN_T1_TREE_LVL_MASK  (((u64b_t)0x7F) << SKEIN_T1_POS_TREE_LVL)\r\n#define SKEIN_T1_TREE_LEVEL(n)  (((u64b_t) (n)) << SKEIN_T1_POS_TREE_LVL)\r\n\r\n/* tweak word T[1]: block type field */\r\n#define SKEIN_BLK_TYPE_KEY      ( 0)                    /* key, for MAC and KDF */\r\n#define SKEIN_BLK_TYPE_CFG      ( 4)                    /* configuration block */\r\n#define SKEIN_BLK_TYPE_PERS     ( 8)                    /* personalization string */\r\n#define SKEIN_BLK_TYPE_PK       (12)                    /* public key (for digital signature hashing) */\r\n#define SKEIN_BLK_TYPE_KDF      (16)                    /* key identifier for KDF */\r\n#define SKEIN_BLK_TYPE_NONCE    (20)                    /* nonce for PRNG */\r\n#define SKEIN_BLK_TYPE_MSG      (48)                    /* message processing */\r\n#define SKEIN_BLK_TYPE_OUT      (63)                    /* output stage */\r\n#define SKEIN_BLK_TYPE_MASK     (63)                    /* bit field mask */\r\n\r\n#define SKEIN_T1_BLK_TYPE(T)   (((u64b_t) (SKEIN_BLK_TYPE_##T)) << SKEIN_T1_POS_BLK_TYPE)\r\n#define SKEIN_T1_BLK_TYPE_KEY   SKEIN_T1_BLK_TYPE(KEY)  /* key, for MAC and KDF */\r\n#define SKEIN_T1_BLK_TYPE_CFG   SKEIN_T1_BLK_TYPE(CFG)  /* configuration block */\r\n#define SKEIN_T1_BLK_TYPE_PERS  SKEIN_T1_BLK_TYPE(PERS) /* personalization string */\r\n#define SKEIN_T1_BLK_TYPE_PK    SKEIN_T1_BLK_TYPE(PK)   /* public key (for digital signature hashing) */\r\n#define SKEIN_T1_BLK_TYPE_KDF   SKEIN_T1_BLK_TYPE(KDF)  /* key identifier for KDF */\r\n#define SKEIN_T1_BLK_TYPE_NONCE SKEIN_T1_BLK_TYPE(NONCE)/* nonce for PRNG */\r\n#define SKEIN_T1_BLK_TYPE_MSG   SKEIN_T1_BLK_TYPE(MSG)  /* message processing */\r\n#define SKEIN_T1_BLK_TYPE_OUT   SKEIN_T1_BLK_TYPE(OUT)  /* output stage */\r\n#define SKEIN_T1_BLK_TYPE_MASK  SKEIN_T1_BLK_TYPE(MASK) /* field bit mask */\r\n\r\n#define SKEIN_T1_BLK_TYPE_CFG_FINAL       (SKEIN_T1_BLK_TYPE_CFG | SKEIN_T1_FLAG_FINAL)\r\n#define SKEIN_T1_BLK_TYPE_OUT_FINAL       (SKEIN_T1_BLK_TYPE_OUT | SKEIN_T1_FLAG_FINAL)\r\n\r\n#define SKEIN_VERSION           (1)\r\n\r\n#ifndef SKEIN_ID_STRING_LE      /* allow compile-time personalization */\r\n#define SKEIN_ID_STRING_LE      (0x33414853)            /* \"SHA3\" (little-endian)*/\r\n#endif\r\n\r\n#define SKEIN_MK_64(hi32,lo32)  ((lo32) + (((u64b_t) (hi32)) << 32))\r\n#define SKEIN_SCHEMA_VER        SKEIN_MK_64(SKEIN_VERSION,SKEIN_ID_STRING_LE)\r\n#define SKEIN_KS_PARITY         SKEIN_MK_64(0x1BD11BDA,0xA9FC1A22)\r\n\r\n#define SKEIN_CFG_STR_LEN       (4*8)\r\n\r\n/* bit field definitions in config block treeInfo word */\r\n#define SKEIN_CFG_TREE_LEAF_SIZE_POS  ( 0)\r\n#define SKEIN_CFG_TREE_NODE_SIZE_POS  ( 8)\r\n#define SKEIN_CFG_TREE_MAX_LEVEL_POS  (16)\r\n\r\n#define SKEIN_CFG_TREE_LEAF_SIZE_MSK  (((u64b_t) 0xFF) << SKEIN_CFG_TREE_LEAF_SIZE_POS)\r\n#define SKEIN_CFG_TREE_NODE_SIZE_MSK  (((u64b_t) 0xFF) << SKEIN_CFG_TREE_NODE_SIZE_POS)\r\n#define SKEIN_CFG_TREE_MAX_LEVEL_MSK  (((u64b_t) 0xFF) << SKEIN_CFG_TREE_MAX_LEVEL_POS)\r\n\r\n#define SKEIN_CFG_TREE_INFO(leaf,node,maxLvl)                   \\\r\n    ( (((u64b_t)(leaf  )) << SKEIN_CFG_TREE_LEAF_SIZE_POS) |    \\\r\n      (((u64b_t)(node  )) << SKEIN_CFG_TREE_NODE_SIZE_POS) |    \\\r\n      (((u64b_t)(maxLvl)) << SKEIN_CFG_TREE_MAX_LEVEL_POS) )\r\n\r\n#define SKEIN_CFG_TREE_INFO_SEQUENTIAL SKEIN_CFG_TREE_INFO(0,0,0) /* use as treeInfo in InitExt() call for sequential processing */\r\n\r\n/*\r\n**   Skein macros for getting/setting tweak words, etc.\r\n**   These are useful for partial input bytes, hash tree init/update, etc.\r\n**/\r\n#define Skein_Get_Tweak(ctxPtr,TWK_NUM)         ((ctxPtr)->h.T[TWK_NUM])\r\n#define Skein_Set_Tweak(ctxPtr,TWK_NUM,tVal)    {(ctxPtr)->h.T[TWK_NUM] = (tVal);}\r\n\r\n#define Skein_Get_T0(ctxPtr)    Skein_Get_Tweak(ctxPtr,0)\r\n#define Skein_Get_T1(ctxPtr)    Skein_Get_Tweak(ctxPtr,1)\r\n#define Skein_Set_T0(ctxPtr,T0) Skein_Set_Tweak(ctxPtr,0,T0)\r\n#define Skein_Set_T1(ctxPtr,T1) Skein_Set_Tweak(ctxPtr,1,T1)\r\n\r\n/* set both tweak words at once */\r\n#define Skein_Set_T0_T1(ctxPtr,T0,T1)           \\\r\n    {                                           \\\r\n    Skein_Set_T0(ctxPtr,(T0));                  \\\r\n    Skein_Set_T1(ctxPtr,(T1));                  \\\r\n    }\r\n\r\n#define Skein_Set_Type(ctxPtr,BLK_TYPE)         \\\r\n    Skein_Set_T1(ctxPtr,SKEIN_T1_BLK_TYPE_##BLK_TYPE)\r\n\r\n/* set up for starting with a new type: h.T[0]=0; h.T[1] = NEW_TYPE; h.bCnt=0; */\r\n#define Skein_Start_New_Type(ctxPtr,BLK_TYPE)   \\\r\n    { Skein_Set_T0_T1(ctxPtr,0,SKEIN_T1_FLAG_FIRST | SKEIN_T1_BLK_TYPE_##BLK_TYPE); (ctxPtr)->h.bCnt=0; }\r\n\r\n#define Skein_Clear_First_Flag(hdr)      { (hdr).T[1] &= ~SKEIN_T1_FLAG_FIRST;       }\r\n#define Skein_Set_Bit_Pad_Flag(hdr)      { (hdr).T[1] |=  SKEIN_T1_FLAG_BIT_PAD;     }\r\n\r\n#define Skein_Set_Tree_Level(hdr,height) { (hdr).T[1] |= SKEIN_T1_TREE_LEVEL(height);}\r\n\r\n/*****************************************************************\r\n** \"Internal\" Skein definitions for debugging and error checking\r\n******************************************************************/\r\n#ifdef  SKEIN_DEBUG             /* examine/display intermediate values? */\r\n#include \"skein_debug.h\"\r\n#else                           /* default is no callouts */\r\n#define Skein_Show_Block(bits,ctx,X,blkPtr,wPtr,ksEvenPtr,ksOddPtr)\r\n#define Skein_Show_Round(bits,ctx,r,X)\r\n#define Skein_Show_R_Ptr(bits,ctx,r,X_ptr)\r\n#define Skein_Show_Final(bits,ctx,cnt,outPtr)\r\n#define Skein_Show_Key(bits,ctx,key,keyBytes)\r\n#endif\r\n\r\n#ifndef SKEIN_ERR_CHECK        /* run-time checks (e.g., bad params, uninitialized context)? */\r\n#define Skein_Assert(x,retCode)/* default: ignore all Asserts, for performance */\r\n#define Skein_assert(x)\r\n#elif   defined(SKEIN_ASSERT)\r\n#include <assert.h>     \r\n#define Skein_Assert(x,retCode) assert(x) \r\n#define Skein_assert(x)         assert(x) \r\n#else\r\n#include <assert.h>     \r\n#define Skein_Assert(x,retCode) { if (!(x)) return retCode; } /*  caller  error */\r\n#define Skein_assert(x)         assert(x)                     /* internal error */\r\n#endif\r\n\r\n/*****************************************************************\r\n** Skein block function constants (shared across Ref and Opt code)\r\n******************************************************************/\r\nenum    \r\n    {   \r\n        /* Skein_256 round rotation constants */\r\n    R_256_0_0=14, R_256_0_1=16,\r\n    R_256_1_0=52, R_256_1_1=57,\r\n    R_256_2_0=23, R_256_2_1=40,\r\n    R_256_3_0= 5, R_256_3_1=37,\r\n    R_256_4_0=25, R_256_4_1=33,\r\n    R_256_5_0=46, R_256_5_1=12,\r\n    R_256_6_0=58, R_256_6_1=22,\r\n    R_256_7_0=32, R_256_7_1=32,\r\n\r\n        /* Skein_512 round rotation constants */\r\n    R_512_0_0=46, R_512_0_1=36, R_512_0_2=19, R_512_0_3=37,\r\n    R_512_1_0=33, R_512_1_1=27, R_512_1_2=14, R_512_1_3=42,\r\n    R_512_2_0=17, R_512_2_1=49, R_512_2_2=36, R_512_2_3=39,\r\n    R_512_3_0=44, R_512_3_1= 9, R_512_3_2=54, R_512_3_3=56,\r\n    R_512_4_0=39, R_512_4_1=30, R_512_4_2=34, R_512_4_3=24,\r\n    R_512_5_0=13, R_512_5_1=50, R_512_5_2=10, R_512_5_3=17,\r\n    R_512_6_0=25, R_512_6_1=29, R_512_6_2=39, R_512_6_3=43,\r\n    R_512_7_0= 8, R_512_7_1=35, R_512_7_2=56, R_512_7_3=22,\r\n\r\n        /* Skein1024 round rotation constants */\r\n    R1024_0_0=24, R1024_0_1=13, R1024_0_2= 8, R1024_0_3=47, R1024_0_4= 8, R1024_0_5=17, R1024_0_6=22, R1024_0_7=37,\r\n    R1024_1_0=38, R1024_1_1=19, R1024_1_2=10, R1024_1_3=55, R1024_1_4=49, R1024_1_5=18, R1024_1_6=23, R1024_1_7=52,\r\n    R1024_2_0=33, R1024_2_1= 4, R1024_2_2=51, R1024_2_3=13, R1024_2_4=34, R1024_2_5=41, R1024_2_6=59, R1024_2_7=17,\r\n    R1024_3_0= 5, R1024_3_1=20, R1024_3_2=48, R1024_3_3=41, R1024_3_4=47, R1024_3_5=28, R1024_3_6=16, R1024_3_7=25,\r\n    R1024_4_0=41, R1024_4_1= 9, R1024_4_2=37, R1024_4_3=31, R1024_4_4=12, R1024_4_5=47, R1024_4_6=44, R1024_4_7=30,\r\n    R1024_5_0=16, R1024_5_1=34, R1024_5_2=56, R1024_5_3=51, R1024_5_4= 4, R1024_5_5=53, R1024_5_6=42, R1024_5_7=41,\r\n    R1024_6_0=31, R1024_6_1=44, R1024_6_2=47, R1024_6_3=46, R1024_6_4=19, R1024_6_5=42, R1024_6_6=44, R1024_6_7=25,\r\n    R1024_7_0= 9, R1024_7_1=48, R1024_7_2=35, R1024_7_3=52, R1024_7_4=23, R1024_7_5=31, R1024_7_6=37, R1024_7_7=20\r\n    };\r\n\r\n#ifndef SKEIN_ROUNDS\r\n#define SKEIN_256_ROUNDS_TOTAL (72)          /* number of rounds for the different block sizes */\r\n#define SKEIN_512_ROUNDS_TOTAL (72)\r\n#define SKEIN1024_ROUNDS_TOTAL (80)\r\n#else                                        /* allow command-line define in range 8*(5..14)   */\r\n#define SKEIN_256_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/100) + 5) % 10) + 5))\r\n#define SKEIN_512_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/ 10) + 5) % 10) + 5))\r\n#define SKEIN1024_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS    ) + 5) % 10) + 5))\r\n#endif\r\n\r\n#ifdef __cplusplus\r\n}\r\n#endif\r\n\r\n#endif  /* ifndef _SKEIN_H_ */\r\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/skeinApi.c",
    "content": "/*\nCopyright (c) 2010 Werner Dittmann\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n\n*/\n\n#define SKEIN_ERR_CHECK 1\n#include <cryptcommon/skeinApi.h>\n#include <string.h>\n#include <stdio.h>\n\nint skeinCtxPrepare(SkeinCtx_t* ctx, SkeinSize_t size)\n{\n    Skein_Assert(ctx && size, SKEIN_FAIL);\n\n    memset(ctx ,0, sizeof(SkeinCtx_t));\n    ctx->skeinSize = size;\n\n    return SKEIN_SUCCESS;\n}\n\nint skeinInit(SkeinCtx_t* ctx, size_t hashBitLen)\n{\n    int ret = SKEIN_FAIL;\n    size_t Xlen = 0;\n    u64b_t*  X = NULL;\n    uint64_t treeInfo = SKEIN_CFG_TREE_INFO_SEQUENTIAL;\n\n    Skein_Assert(ctx, SKEIN_FAIL);\n    /*\n     * The following two lines rely of the fact that the real Skein contexts are\n     * a union in out context and thus have tha maximum memory available.\n     * The beauty of C :-) .\n     */\n    X = ctx->m.s256.X;\n    Xlen = (size_t)(ctx->skeinSize/8);\n    /*\n     * If size is the same and hash bit length is zero then reuse\n     * the save chaining variables.\n     */\n    switch (ctx->skeinSize) {\n    case Skein256:\n        ret = Skein_256_InitExt(&ctx->m.s256, hashBitLen,\n                                treeInfo, NULL, 0);\n        break;\n    case Skein512:\n        ret = Skein_512_InitExt(&ctx->m.s512, hashBitLen,\n                                treeInfo, NULL, 0);\n        break;\n    case Skein1024:\n        ret = Skein1024_InitExt(&ctx->m.s1024, hashBitLen,\n                                treeInfo, NULL, 0);\n        break;\n    }\n\n    if (ret == SKEIN_SUCCESS) {\n        /* Save chaining variables for this combination of size and hashBitLen */\n        memcpy(ctx->XSave, X, Xlen);\n    }\n    return ret;\n}\n\nint skeinMacInit(SkeinCtx_t* ctx, const uint8_t *key, size_t keyLen,\n                 size_t hashBitLen)\n{\n    int ret = SKEIN_FAIL;\n    u64b_t*  X = NULL;\n    size_t Xlen = 0;\n    uint64_t treeInfo = SKEIN_CFG_TREE_INFO_SEQUENTIAL;\n\n    Skein_Assert(ctx, SKEIN_FAIL);\n\n    X = ctx->m.s256.X;\n    Xlen = (size_t)(ctx->skeinSize/8);\n\n    Skein_Assert(hashBitLen, SKEIN_BAD_HASHLEN);\n\n    switch (ctx->skeinSize) {\n    case Skein256:\n        ret = Skein_256_InitExt(&ctx->m.s256, hashBitLen,\n                                treeInfo,\n                                (const u08b_t*)key, keyLen);\n\n        break;\n    case Skein512:\n        ret = Skein_512_InitExt(&ctx->m.s512, hashBitLen,\n                                treeInfo,\n                                (const u08b_t*)key, keyLen);\n        break;\n    case Skein1024:\n        ret = Skein1024_InitExt(&ctx->m.s1024, hashBitLen,\n                                treeInfo,\n                                (const u08b_t*)key, keyLen);\n\n        break;\n    }\n    if (ret == SKEIN_SUCCESS) {\n        /* Save chaining variables for this combination of key, keyLen, hashBitLen */\n        memcpy(ctx->XSave, X, Xlen);\n    }\n    return ret;\n}\n\nvoid skeinReset(SkeinCtx_t* ctx)\n{\n    size_t Xlen = 0;\n    u64b_t*  X = NULL;\n\n    /*\n     * The following two lines rely of the fact that the real Skein contexts are\n     * a union in out context and thus have tha maximum memory available.\n     * The beautiy of C :-) .\n     */\n    X = ctx->m.s256.X;\n    Xlen = (size_t)(ctx->skeinSize/8);\n    /*\n     * If size is the same and hash bit length is zero then reuse\n     * the save chaining variables.\n     */\n    /* Restore the chaing variable, reset byte counter */\n    memcpy(X, ctx->XSave, Xlen);\n\n    /* Setup context to process the message */\n    Skein_Start_New_Type(&ctx->m, MSG);\n}\n\nint skeinUpdate(SkeinCtx_t *ctx, const uint8_t *msg,\n                size_t msgByteCnt)\n{\n    int ret = SKEIN_FAIL;\n    Skein_Assert(ctx, SKEIN_FAIL);\n\n    switch (ctx->skeinSize) {\n    case Skein256:\n        ret = Skein_256_Update(&ctx->m.s256, (const u08b_t*)msg, msgByteCnt);\n        break;\n    case Skein512:\n        ret = Skein_512_Update(&ctx->m.s512, (const u08b_t*)msg, msgByteCnt);\n        break;\n    case Skein1024:\n        ret = Skein1024_Update(&ctx->m.s1024, (const u08b_t*)msg, msgByteCnt);\n        break;\n    }\n    return ret;\n\n}\n\nint skeinUpdateBits(SkeinCtx_t *ctx, const uint8_t *msg,\n                    size_t msgBitCnt)\n{\n    /*\n     * I've used the bit pad implementation from skein_test.c (see NIST CD)\n     * and modified it to use the convenience functions and added some pointer\n     * arithmetic.\n     */\n    size_t length;\n    uint8_t mask;\n    uint8_t* up;\n\n    /* only the final Update() call is allowed do partial bytes, else assert an error */\n    Skein_Assert((ctx->m.h.T[1] & SKEIN_T1_FLAG_BIT_PAD) == 0 || msgBitCnt == 0, SKEIN_FAIL);\n\n    /* if number of bits is a multiple of bytes - that's easy */\n    if ((msgBitCnt & 0x7) == 0) {\n        return skeinUpdate(ctx, msg, msgBitCnt >> 3);\n    }\n    skeinUpdate(ctx, msg, (msgBitCnt >> 3) + 1);\n\n    /*\n     * The next line rely on the fact that the real Skein contexts\n     * are a union in our context. After the addition the pointer points to\n     * Skein's real partial block buffer.\n     * If this layout ever changes we have to adapt this as well.\n     */\n    up = (uint8_t*)ctx->m.s256.X + ctx->skeinSize / 8;\n\n    Skein_Set_Bit_Pad_Flag(ctx->m.h);                       /* set tweak flag for the skeinFinal call */\n\n    /* now \"pad\" the final partial byte the way NIST likes */\n    length = ctx->m.h.bCnt;                                 /* get the bCnt value (same location for all block sizes) */\n    Skein_assert(length != 0);                              /* internal sanity check: there IS a partial byte in the buffer! */\n    mask = (uint8_t) (1u << (7 - (msgBitCnt & 7)));         /* partial byte bit mask */\n    up[length-1]  = (uint8_t)((up[length-1] & (0-mask))|mask);   /* apply bit padding on final byte (in the buffer) */\n\n    return SKEIN_SUCCESS;\n}\n\nint skeinFinal(SkeinCtx_t* ctx, uint8_t* hash)\n{\n    int ret = SKEIN_FAIL;\n    Skein_Assert(ctx, SKEIN_FAIL);\n\n    switch (ctx->skeinSize) {\n    case Skein256:\n        ret = Skein_256_Final(&ctx->m.s256, (u08b_t*)hash);\n        break;\n    case Skein512:\n        ret = Skein_512_Final(&ctx->m.s512, (u08b_t*)hash);\n        break;\n    case Skein1024:\n        ret = Skein1024_Final(&ctx->m.s1024, (u08b_t*)hash);\n        break;\n    }\n    return ret;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/skeinApi.h",
    "content": "/*\nCopyright (c) 2010 Werner Dittmann\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n\n*/\n\n#ifndef SKEINAPI_H\n#define SKEINAPI_H\n\n/**\n * @file skeinApi.h\n * @brief A Skein API and its functions.\n * @{\n *\n * This API and the functions that implement this API simplify usage\n * of Skein. The design and the way to use the functions follow the openSSL\n * design but at the same time take care of some Skein specific behaviour\n * and possibilities.\n * \n * The functions enable applications to create normal Skein hashes and\n * message authentication codes (MAC).\n * \n * Using these functions is simple and straight forward:\n * \n * @code\n * \n * #include <skeinApi.h>\n * \n * ...\n * SkeinCtx_t ctx;             // a Skein hash or MAC context\n * \n * // prepare context, here for a Skein with a state size of 512 bits.\n * skeinCtxPrepare(&ctx, Skein512);\n * \n * // Initialize the context to set the requested hash length in bits:\n * // request an output hash size of 31 bits (Skein supports variable\n * // output sizes, even very strange sizes)\n * skeinInit(&ctx, 31);\n * \n * // Now update Skein with any number of message bits. A function that\n * // takes a number of bytes is also available.\n * skeinUpdateBits(&ctx, message, msgLength);\n * \n * // Now get the result of the Skein hash. The output buffer must be\n * // large enough to hold the request number of output bits. The application\n * // may now extract the bits.\n * skeinFinal(&ctx, result);\n * ...\n * @endcode\n * \n * An application may use @c skeinReset to reset a Skein context and use\n * it for creation of another hash with the same Skein state size and output\n * bit length. In this case the API implementation restores some internal\n * state data and saves a full Skein initialization round.\n * \n * To create a MAC the application just uses @c skeinMacInit instead of \n * @c skeinInit. All other function calls remain the same.\n * \n */\n\n#include <cryptcommon/skein.h>\n\n#ifdef _MSC_VER\ntypedef signed __int8 int8_t;\ntypedef unsigned __int8 uint8_t;\ntypedef signed __int16 int16_t;\ntypedef unsigned __int16 uint16_t;\ntypedef signed __int32 int32_t;\ntypedef unsigned __int32 uint32_t;\ntypedef signed __int64 int64_t;\ntypedef unsigned __int64 uint64_t;\n#else\n#include <stdint.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    /**\n     * Which Skein size to use\n     */\n    typedef enum SkeinSize {\n        Skein256 = 256,     /*!< Skein with 256 bit state */\n        Skein512 = 512,     /*!< Skein with 512 bit state */\n        Skein1024 = 1024    /*!< Skein with 1024 bit state */\n    } SkeinSize_t;\n\n    /**\n     * Context for Skein.\n     *\n     * This structure was setup with some know-how of the internal\n     * Skein structures, in particular ordering of header and size dependent\n     * variables. If Skein implementation changes this, then adapt these\n     * structures as well.\n     */\n    typedef struct SkeinCtx {\n        u64b_t skeinSize;\n        u64b_t  XSave[SKEIN_MAX_STATE_WORDS];   /* save area for state variables */\n        union {\n            Skein_Ctxt_Hdr_t h;\n            Skein_256_Ctxt_t s256;\n            Skein_512_Ctxt_t s512;\n            Skein1024_Ctxt_t s1024;\n        } m;\n    } SkeinCtx_t;\n\n    /**\n     * Prepare a Skein context.\n     * \n     * An application must call this function before it can use the Skein\n     * context. The functions clears memory and initializes size dependent\n     * variables.\n     *\n     * @param ctx\n     *     Pointer to a Skein context.\n     * @param size\n     *     Which Skein size to use.\n     * @return\n     *     SKEIN_SUCESS of SKEIN_FAIL\n     */\n    int skeinCtxPrepare(SkeinCtx_t* ctx, SkeinSize_t size);\n\n    /**\n     * Initialize a Skein context.\n     *\n     * Initializes the context with this data and saves the resulting Skein \n     * state variables for further use.\n     *\n     * @param ctx\n     *     Pointer to a Skein context.\n     * @param hashBitLen\n     *     Number of MAC hash bits to compute or zero\n     * @return\n     *     SKEIN_SUCESS of SKEIN_FAIL\n     * @see skeinReset\n     */\n    int skeinInit(SkeinCtx_t* ctx, size_t hashBitLen);\n\n    /**\n     * Resets a Skein context for furter use.\n     * \n     * Restores the saved chaining variables to reset the Skein context. \n     * Thus applications can reuse the same setup to  process several \n     * messages. This saves a complete Skein initialization cycle.\n     * \n     * @param ctx\n     *     Pointer to a pre-initialized Skein MAC context\n     */\n    void skeinReset(SkeinCtx_t* ctx);\n    \n    /**\n     * Initializes or reuses a Skein context for MAC usage.\n     * \n     * Initializes the context with this data and saves the resulting Skein \n     * state variables for further use.\n     *\n     * Applications call the normal Skein functions to update the MAC and\n     * get the final result.\n     *\n     * @param ctx\n     *     Pointer to an empty or preinitialized Skein MAC context\n     * @param key\n     *     Pointer to key bytes or NULL\n     * @param keyLen\n     *     Length of the key in bytes or zero\n     * @param hashBitLen\n     *     Number of MAC hash bits to compute or zero\n     * @return\n     *     SKEIN_SUCESS of SKEIN_FAIL\n     */\n    int skeinMacInit(SkeinCtx_t* ctx, const uint8_t *key, size_t keyLen,\n                     size_t hashBitLen);\n\n    /**\n     * Update Skein with the next part of the message.\n     *\n     * @param ctx\n     *     Pointer to initialized Skein context\n     * @param msg\n     *     Pointer to the message.\n     * @param msgByteCnt\n     *     Length of the message in @b bytes\n     * @return\n     *     Success or error code.\n     */\n    int skeinUpdate(SkeinCtx_t *ctx, const uint8_t *msg,\n                    size_t msgByteCnt);\n\n    /**\n     * Update the hash with a message bit string.\n     *\n     * Skein can handle data not only as bytes but also as bit strings of\n     * arbitrary length (up to its maximum design size).\n     *\n     * @param ctx\n     *     Pointer to initialized Skein context\n     * @param msg\n     *     Pointer to the message.\n     * @param msgBitCnt\n     *     Length of the message in @b bits.\n     */\n    int skeinUpdateBits(SkeinCtx_t *ctx, const uint8_t *msg,\n                        size_t msgBitCnt);\n\n    /**\n     * Finalize Skein and return the hash.\n     * \n     * Before an application can reuse a Skein setup the application must\n     * reinitialize the Skein context.See the approriate initialization \n     * methods how to achieve this.\n     *\n     * @param ctx\n     *     Pointer to initialized Skein context\n     * @param hash\n     *     Pointer to buffer that receives the hash. The buffer must be large\n     *     enough to store @c hashBitLen bits.\n     * @return\n     *     Success or error code.\n     * @see skeinInit\n     * @see skeinMacInit\n     */\n    int skeinFinal(SkeinCtx_t* ctx, uint8_t* hash);\n\n#ifdef __cplusplus\n}\n#endif\n\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/skein_block.c",
    "content": "/***********************************************************************\r\n**\r\n** Implementation of the Skein block functions.\r\n**\r\n** Source code author: Doug Whiting, 2008.\r\n**\r\n** This algorithm and source code is released to the public domain.\r\n**\r\n** Compile-time switches:\r\n**\r\n**  SKEIN_USE_ASM  -- set bits (256/512/1024) to select which\r\n**                    versions use ASM code for block processing\r\n**                    [default: use C for all block sizes]\r\n**\r\n************************************************************************/\r\n\r\n#include <string.h>\r\n#include <cryptcommon/skein.h>\r\n\r\n#ifndef SKEIN_USE_ASM\r\n#define SKEIN_USE_ASM   (0)                     /* default is all C code (no ASM) */\r\n#endif\r\n\r\n#ifndef SKEIN_LOOP\r\n#define SKEIN_LOOP 001                          /* default: unroll 256 and 512, but not 1024 */\r\n#endif\r\n\r\n#define BLK_BITS        (WCNT*64)               /* some useful definitions for code here */\r\n#define KW_TWK_BASE     (0)\r\n#define KW_KEY_BASE     (3)\r\n#define ks              (kw + KW_KEY_BASE)                \r\n#define ts              (kw + KW_TWK_BASE)\r\n\r\n#ifdef SKEIN_DEBUG\r\n#define DebugSaveTweak(ctx) { ctx->h.T[0] = ts[0]; ctx->h.T[1] = ts[1]; }\r\n#else\r\n#define DebugSaveTweak(ctx)\r\n#endif\r\n\r\n/*****************************  Skein_256 ******************************/\r\n#if !(SKEIN_USE_ASM & 256)\r\nvoid Skein_256_Process_Block(Skein_256_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd)\r\n    { /* do it in C */\r\n    enum\r\n        {\r\n        WCNT = SKEIN_256_STATE_WORDS\r\n        };\r\n#undef  RCNT\r\n#define RCNT  (SKEIN_256_ROUNDS_TOTAL/8)\r\n\r\n#ifdef  SKEIN_LOOP                              /* configure how much to unroll the loop */\r\n#define SKEIN_UNROLL_256 (((SKEIN_LOOP)/100)%10)\r\n#else\r\n#define SKEIN_UNROLL_256 (0)\r\n#endif\r\n\r\n#if SKEIN_UNROLL_256\r\n#if (RCNT % SKEIN_UNROLL_256)\r\n#error \"Invalid SKEIN_UNROLL_256\"               /* sanity check on unroll count */\r\n#endif\r\n    size_t  r;\r\n    u64b_t  kw[WCNT+4+RCNT*2];                  /* key schedule words : chaining vars + tweak + \"rotation\"*/\r\n#else\r\n    u64b_t  kw[WCNT+4];                         /* key schedule words : chaining vars + tweak */\r\n#endif\r\n    u64b_t  X0,X1,X2,X3;                        /* local copy of context vars, for speed */\r\n    u64b_t  w [WCNT];                           /* local copy of input block */\r\n#ifdef SKEIN_DEBUG\r\n    const u64b_t *Xptr[4];                      /* use for debugging (help compiler put Xn in registers) */\r\n    Xptr[0] = &X0;  Xptr[1] = &X1;  Xptr[2] = &X2;  Xptr[3] = &X3;\r\n#endif\r\n    Skein_assert(blkCnt != 0);                  /* never call with blkCnt == 0! */\r\n    ts[0] = ctx->h.T[0];\r\n    ts[1] = ctx->h.T[1];\r\n    do  {\r\n        /* this implementation only supports 2**64 input bytes (no carry out here) */\r\n        ts[0] += byteCntAdd;                    /* update processed length */\r\n\r\n        /* precompute the key schedule for this block */\r\n        ks[0] = ctx->X[0];     \r\n        ks[1] = ctx->X[1];\r\n        ks[2] = ctx->X[2];\r\n        ks[3] = ctx->X[3];\r\n        ks[4] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ SKEIN_KS_PARITY;\r\n\r\n        ts[2] = ts[0] ^ ts[1];\r\n\r\n        Skein_Get64_LSB_First(w,blkPtr,WCNT);   /* get input block in little-endian format */\r\n        DebugSaveTweak(ctx);\r\n        Skein_Show_Block(BLK_BITS,&ctx->h,ctx->X,blkPtr,w,ks,ts);\r\n\r\n        X0 = w[0] + ks[0];                      /* do the first full key injection */\r\n        X1 = w[1] + ks[1] + ts[0];\r\n        X2 = w[2] + ks[2] + ts[1];\r\n        X3 = w[3] + ks[3];\r\n\r\n        Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INITIAL,Xptr);    /* show starting state values */\r\n\r\n        blkPtr += SKEIN_256_BLOCK_BYTES;\r\n\r\n        /* run the rounds */\r\n\r\n#define Round256(p0,p1,p2,p3,ROT,rNum)                              \\\r\n    X##p0 += X##p1; X##p1 = RotL_64(X##p1,ROT##_0); X##p1 ^= X##p0; \\\r\n    X##p2 += X##p3; X##p3 = RotL_64(X##p3,ROT##_1); X##p3 ^= X##p2; \\\r\n\r\n#if SKEIN_UNROLL_256 == 0                       \r\n#define R256(p0,p1,p2,p3,ROT,rNum)           /* fully unrolled */   \\\r\n    Round256(p0,p1,p2,p3,ROT,rNum)                                  \\\r\n    Skein_Show_R_Ptr(BLK_BITS,&ctx->h,rNum,Xptr);\r\n\r\n#define I256(R)                                                     \\\r\n    X0   += ks[((R)+1) % 5];    /* inject the key schedule value */ \\\r\n    X1   += ks[((R)+2) % 5] + ts[((R)+1) % 3];                      \\\r\n    X2   += ks[((R)+3) % 5] + ts[((R)+2) % 3];                      \\\r\n    X3   += ks[((R)+4) % 5] +     (R)+1;                            \\\r\n    Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);\r\n#else                                       /* looping version */\r\n#define R256(p0,p1,p2,p3,ROT,rNum)                                  \\\r\n    Round256(p0,p1,p2,p3,ROT,rNum)                                  \\\r\n    Skein_Show_R_Ptr(BLK_BITS,&ctx->h,4*(r-1)+rNum,Xptr);\r\n\r\n#define I256(R)                                                     \\\r\n    X0   += ks[r+(R)+0];        /* inject the key schedule value */ \\\r\n    X1   += ks[r+(R)+1] + ts[r+(R)+0];                              \\\r\n    X2   += ks[r+(R)+2] + ts[r+(R)+1];                              \\\r\n    X3   += ks[r+(R)+3] +    r+(R)   ;                              \\\r\n    ks[r + (R)+4    ]   = ks[r+(R)-1];     /* rotate key schedule */\\\r\n    ts[r + (R)+2    ]   = ts[r+(R)-1];                              \\\r\n    Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);\r\n\r\n    for (r=1;r < 2*RCNT;r+=2*SKEIN_UNROLL_256)  /* loop thru it */\r\n#endif  \r\n        {    \r\n#define R256_8_rounds(R)                  \\\r\n        R256(0,1,2,3,R_256_0,8*(R) + 1);  \\\r\n        R256(0,3,2,1,R_256_1,8*(R) + 2);  \\\r\n        R256(0,1,2,3,R_256_2,8*(R) + 3);  \\\r\n        R256(0,3,2,1,R_256_3,8*(R) + 4);  \\\r\n        I256(2*(R));                      \\\r\n        R256(0,1,2,3,R_256_4,8*(R) + 5);  \\\r\n        R256(0,3,2,1,R_256_5,8*(R) + 6);  \\\r\n        R256(0,1,2,3,R_256_6,8*(R) + 7);  \\\r\n        R256(0,3,2,1,R_256_7,8*(R) + 8);  \\\r\n        I256(2*(R)+1);\r\n\r\n        R256_8_rounds( 0);\r\n\r\n#define R256_Unroll_R(NN) ((SKEIN_UNROLL_256 == 0 && SKEIN_256_ROUNDS_TOTAL/8 > (NN)) || (SKEIN_UNROLL_256 > (NN)))\r\n\r\n  #if   R256_Unroll_R( 1)\r\n        R256_8_rounds( 1);\r\n  #endif\r\n  #if   R256_Unroll_R( 2)\r\n        R256_8_rounds( 2);\r\n  #endif\r\n  #if   R256_Unroll_R( 3)\r\n        R256_8_rounds( 3);\r\n  #endif\r\n  #if   R256_Unroll_R( 4)\r\n        R256_8_rounds( 4);\r\n  #endif\r\n  #if   R256_Unroll_R( 5)\r\n        R256_8_rounds( 5);\r\n  #endif\r\n  #if   R256_Unroll_R( 6)\r\n        R256_8_rounds( 6);\r\n  #endif\r\n  #if   R256_Unroll_R( 7)\r\n        R256_8_rounds( 7);\r\n  #endif\r\n  #if   R256_Unroll_R( 8)\r\n        R256_8_rounds( 8);\r\n  #endif\r\n  #if   R256_Unroll_R( 9)\r\n        R256_8_rounds( 9);\r\n  #endif\r\n  #if   R256_Unroll_R(10)\r\n        R256_8_rounds(10);\r\n  #endif\r\n  #if   R256_Unroll_R(11)\r\n        R256_8_rounds(11);\r\n  #endif\r\n  #if   R256_Unroll_R(12)\r\n        R256_8_rounds(12);\r\n  #endif\r\n  #if   R256_Unroll_R(13)\r\n        R256_8_rounds(13);\r\n  #endif\r\n  #if   R256_Unroll_R(14)\r\n        R256_8_rounds(14);\r\n  #endif\r\n  #if  (SKEIN_UNROLL_256 > 14)\r\n#error  \"need more unrolling in Skein_256_Process_Block\"\r\n  #endif\r\n        }\r\n        /* do the final \"feedforward\" xor, update context chaining vars */\r\n        ctx->X[0] = X0 ^ w[0];\r\n        ctx->X[1] = X1 ^ w[1];\r\n        ctx->X[2] = X2 ^ w[2];\r\n        ctx->X[3] = X3 ^ w[3];\r\n\r\n        Skein_Show_Round(BLK_BITS,&ctx->h,SKEIN_RND_FEED_FWD,ctx->X);\r\n\r\n        ts[1] &= ~SKEIN_T1_FLAG_FIRST;\r\n        }\r\n    while (--blkCnt);\r\n    ctx->h.T[0] = ts[0];\r\n    ctx->h.T[1] = ts[1];\r\n    }\r\n\r\n#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)\r\nsize_t Skein_256_Process_Block_CodeSize(void)\r\n    {\r\n    return ((u08b_t *) Skein_256_Process_Block_CodeSize) -\r\n           ((u08b_t *) Skein_256_Process_Block);\r\n    }\r\nuint_t Skein_256_Unroll_Cnt(void)\r\n    {\r\n    return SKEIN_UNROLL_256;\r\n    }\r\n#endif\r\n#endif\r\n\r\n/*****************************  Skein_512 ******************************/\r\n#if !(SKEIN_USE_ASM & 512)\r\nvoid Skein_512_Process_Block(Skein_512_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd)\r\n    { /* do it in C */\r\n    enum\r\n        {\r\n        WCNT = SKEIN_512_STATE_WORDS\r\n        };\r\n#undef  RCNT\r\n#define RCNT  (SKEIN_512_ROUNDS_TOTAL/8)\r\n\r\n#ifdef  SKEIN_LOOP                              /* configure how much to unroll the loop */\r\n#define SKEIN_UNROLL_512 (((SKEIN_LOOP)/10)%10)\r\n#else\r\n#define SKEIN_UNROLL_512 (0)\r\n#endif\r\n\r\n#if SKEIN_UNROLL_512\r\n#if (RCNT % SKEIN_UNROLL_512)\r\n#error \"Invalid SKEIN_UNROLL_512\"               /* sanity check on unroll count */\r\n#endif\r\n    size_t  r;\r\n    u64b_t  kw[WCNT+4+RCNT*2];                  /* key schedule words : chaining vars + tweak + \"rotation\"*/\r\n#else\r\n    u64b_t  kw[WCNT+4];                         /* key schedule words : chaining vars + tweak */\r\n#endif\r\n    u64b_t  X0,X1,X2,X3,X4,X5,X6,X7;            /* local copy of vars, for speed */\r\n    u64b_t  w [WCNT];                           /* local copy of input block */\r\n#ifdef SKEIN_DEBUG\r\n    const u64b_t *Xptr[8];                      /* use for debugging (help compiler put Xn in registers) */\r\n    Xptr[0] = &X0;  Xptr[1] = &X1;  Xptr[2] = &X2;  Xptr[3] = &X3;\r\n    Xptr[4] = &X4;  Xptr[5] = &X5;  Xptr[6] = &X6;  Xptr[7] = &X7;\r\n#endif\r\n\r\n    Skein_assert(blkCnt != 0);                  /* never call with blkCnt == 0! */\r\n    ts[0] = ctx->h.T[0];\r\n    ts[1] = ctx->h.T[1];\r\n    do  {\r\n        /* this implementation only supports 2**64 input bytes (no carry out here) */\r\n        ts[0] += byteCntAdd;                    /* update processed length */\r\n\r\n        /* precompute the key schedule for this block */\r\n        ks[0] = ctx->X[0];\r\n        ks[1] = ctx->X[1];\r\n        ks[2] = ctx->X[2];\r\n        ks[3] = ctx->X[3];\r\n        ks[4] = ctx->X[4];\r\n        ks[5] = ctx->X[5];\r\n        ks[6] = ctx->X[6];\r\n        ks[7] = ctx->X[7];\r\n        ks[8] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ \r\n                ks[4] ^ ks[5] ^ ks[6] ^ ks[7] ^ SKEIN_KS_PARITY;\r\n\r\n        ts[2] = ts[0] ^ ts[1];\r\n\r\n        Skein_Get64_LSB_First(w,blkPtr,WCNT); /* get input block in little-endian format */\r\n        DebugSaveTweak(ctx);\r\n        Skein_Show_Block(BLK_BITS,&ctx->h,ctx->X,blkPtr,w,ks,ts);\r\n\r\n        X0   = w[0] + ks[0];                    /* do the first full key injection */\r\n        X1   = w[1] + ks[1];\r\n        X2   = w[2] + ks[2];\r\n        X3   = w[3] + ks[3];\r\n        X4   = w[4] + ks[4];\r\n        X5   = w[5] + ks[5] + ts[0];\r\n        X6   = w[6] + ks[6] + ts[1];\r\n        X7   = w[7] + ks[7];\r\n\r\n        blkPtr += SKEIN_512_BLOCK_BYTES;\r\n\r\n        Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INITIAL,Xptr);\r\n        /* run the rounds */\r\n#define Round512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                  \\\r\n    X##p0 += X##p1; X##p1 = RotL_64(X##p1,ROT##_0); X##p1 ^= X##p0; \\\r\n    X##p2 += X##p3; X##p3 = RotL_64(X##p3,ROT##_1); X##p3 ^= X##p2; \\\r\n    X##p4 += X##p5; X##p5 = RotL_64(X##p5,ROT##_2); X##p5 ^= X##p4; \\\r\n    X##p6 += X##p7; X##p7 = RotL_64(X##p7,ROT##_3); X##p7 ^= X##p6; \\\r\n\r\n#if SKEIN_UNROLL_512 == 0                       \r\n#define R512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)      /* unrolled */  \\\r\n    Round512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                      \\\r\n    Skein_Show_R_Ptr(BLK_BITS,&ctx->h,rNum,Xptr);\r\n\r\n#define I512(R)                                                     \\\r\n    X0   += ks[((R)+1) % 9];   /* inject the key schedule value */  \\\r\n    X1   += ks[((R)+2) % 9];                                        \\\r\n    X2   += ks[((R)+3) % 9];                                        \\\r\n    X3   += ks[((R)+4) % 9];                                        \\\r\n    X4   += ks[((R)+5) % 9];                                        \\\r\n    X5   += ks[((R)+6) % 9] + ts[((R)+1) % 3];                      \\\r\n    X6   += ks[((R)+7) % 9] + ts[((R)+2) % 3];                      \\\r\n    X7   += ks[((R)+8) % 9] +     (R)+1;                            \\\r\n    Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);\r\n#else                                       /* looping version */\r\n#define R512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                      \\\r\n    Round512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                      \\\r\n    Skein_Show_R_Ptr(BLK_BITS,&ctx->h,4*(r-1)+rNum,Xptr);\r\n\r\n#define I512(R)                                                     \\\r\n    X0   += ks[r+(R)+0];        /* inject the key schedule value */ \\\r\n    X1   += ks[r+(R)+1];                                            \\\r\n    X2   += ks[r+(R)+2];                                            \\\r\n    X3   += ks[r+(R)+3];                                            \\\r\n    X4   += ks[r+(R)+4];                                            \\\r\n    X5   += ks[r+(R)+5] + ts[r+(R)+0];                              \\\r\n    X6   += ks[r+(R)+6] + ts[r+(R)+1];                              \\\r\n    X7   += ks[r+(R)+7] +    r+(R)   ;                              \\\r\n    ks[r +       (R)+8] = ks[r+(R)-1];  /* rotate key schedule */   \\\r\n    ts[r +       (R)+2] = ts[r+(R)-1];                              \\\r\n    Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);\r\n\r\n    for (r=1;r < 2*RCNT;r+=2*SKEIN_UNROLL_512)   /* loop thru it */\r\n#endif                         /* end of looped code definitions */\r\n        {\r\n#define R512_8_rounds(R)  /* do 8 full rounds */  \\\r\n        R512(0,1,2,3,4,5,6,7,R_512_0,8*(R)+ 1);   \\\r\n        R512(2,1,4,7,6,5,0,3,R_512_1,8*(R)+ 2);   \\\r\n        R512(4,1,6,3,0,5,2,7,R_512_2,8*(R)+ 3);   \\\r\n        R512(6,1,0,7,2,5,4,3,R_512_3,8*(R)+ 4);   \\\r\n        I512(2*(R));                              \\\r\n        R512(0,1,2,3,4,5,6,7,R_512_4,8*(R)+ 5);   \\\r\n        R512(2,1,4,7,6,5,0,3,R_512_5,8*(R)+ 6);   \\\r\n        R512(4,1,6,3,0,5,2,7,R_512_6,8*(R)+ 7);   \\\r\n        R512(6,1,0,7,2,5,4,3,R_512_7,8*(R)+ 8);   \\\r\n        I512(2*(R)+1);        /* and key injection */\r\n\r\n        R512_8_rounds( 0);\r\n\r\n#define R512_Unroll_R(NN) ((SKEIN_UNROLL_512 == 0 && SKEIN_512_ROUNDS_TOTAL/8 > (NN)) || (SKEIN_UNROLL_512 > (NN)))\r\n\r\n  #if   R512_Unroll_R( 1)\r\n        R512_8_rounds( 1);\r\n  #endif\r\n  #if   R512_Unroll_R( 2)\r\n        R512_8_rounds( 2);\r\n  #endif\r\n  #if   R512_Unroll_R( 3)\r\n        R512_8_rounds( 3);\r\n  #endif\r\n  #if   R512_Unroll_R( 4)\r\n        R512_8_rounds( 4);\r\n  #endif\r\n  #if   R512_Unroll_R( 5)\r\n        R512_8_rounds( 5);\r\n  #endif\r\n  #if   R512_Unroll_R( 6)\r\n        R512_8_rounds( 6);\r\n  #endif\r\n  #if   R512_Unroll_R( 7)\r\n        R512_8_rounds( 7);\r\n  #endif\r\n  #if   R512_Unroll_R( 8)\r\n        R512_8_rounds( 8);\r\n  #endif\r\n  #if   R512_Unroll_R( 9)\r\n        R512_8_rounds( 9);\r\n  #endif\r\n  #if   R512_Unroll_R(10)\r\n        R512_8_rounds(10);\r\n  #endif\r\n  #if   R512_Unroll_R(11)\r\n        R512_8_rounds(11);\r\n  #endif\r\n  #if   R512_Unroll_R(12)\r\n        R512_8_rounds(12);\r\n  #endif\r\n  #if   R512_Unroll_R(13)\r\n        R512_8_rounds(13);\r\n  #endif\r\n  #if   R512_Unroll_R(14)\r\n        R512_8_rounds(14);\r\n  #endif\r\n  #if  (SKEIN_UNROLL_512 > 14)\r\n#error  \"need more unrolling in Skein_512_Process_Block\"\r\n  #endif\r\n        }\r\n\r\n        /* do the final \"feedforward\" xor, update context chaining vars */\r\n        ctx->X[0] = X0 ^ w[0];\r\n        ctx->X[1] = X1 ^ w[1];\r\n        ctx->X[2] = X2 ^ w[2];\r\n        ctx->X[3] = X3 ^ w[3];\r\n        ctx->X[4] = X4 ^ w[4];\r\n        ctx->X[5] = X5 ^ w[5];\r\n        ctx->X[6] = X6 ^ w[6];\r\n        ctx->X[7] = X7 ^ w[7];\r\n        Skein_Show_Round(BLK_BITS,&ctx->h,SKEIN_RND_FEED_FWD,ctx->X);\r\n\r\n        ts[1] &= ~SKEIN_T1_FLAG_FIRST;\r\n        }\r\n    while (--blkCnt);\r\n    ctx->h.T[0] = ts[0];\r\n    ctx->h.T[1] = ts[1];\r\n    }\r\n\r\n#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)\r\nsize_t Skein_512_Process_Block_CodeSize(void)\r\n    {\r\n    return ((u08b_t *) Skein_512_Process_Block_CodeSize) -\r\n           ((u08b_t *) Skein_512_Process_Block);\r\n    }\r\nuint_t Skein_512_Unroll_Cnt(void)\r\n    {\r\n    return SKEIN_UNROLL_512;\r\n    }\r\n#endif\r\n#endif\r\n\r\n/*****************************  Skein1024 ******************************/\r\n#if !(SKEIN_USE_ASM & 1024)\r\nvoid Skein1024_Process_Block(Skein1024_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd)\r\n    { /* do it in C, always looping (unrolled is bigger AND slower!) */\r\n    enum\r\n        {\r\n        WCNT = SKEIN1024_STATE_WORDS\r\n        };\r\n#undef  RCNT\r\n#define RCNT  (SKEIN1024_ROUNDS_TOTAL/8)\r\n\r\n#ifdef  SKEIN_LOOP                              /* configure how much to unroll the loop */\r\n#define SKEIN_UNROLL_1024 ((SKEIN_LOOP)%10)\r\n#else\r\n#define SKEIN_UNROLL_1024 (0)\r\n#endif\r\n\r\n#if (SKEIN_UNROLL_1024 != 0)\r\n#if (RCNT % SKEIN_UNROLL_1024)\r\n#error \"Invalid SKEIN_UNROLL_1024\"              /* sanity check on unroll count */\r\n#endif\r\n    size_t  r;\r\n    u64b_t  kw[WCNT+4+RCNT*2];                  /* key schedule words : chaining vars + tweak + \"rotation\"*/\r\n#else\r\n    u64b_t  kw[WCNT+4];                         /* key schedule words : chaining vars + tweak */\r\n#endif\r\n\r\n    u64b_t  X00,X01,X02,X03,X04,X05,X06,X07,    /* local copy of vars, for speed */\r\n            X08,X09,X10,X11,X12,X13,X14,X15;\r\n    u64b_t  w [WCNT];                           /* local copy of input block */\r\n#ifdef SKEIN_DEBUG\r\n    const u64b_t *Xptr[16];                     /* use for debugging (help compiler put Xn in registers) */\r\n    Xptr[ 0] = &X00;  Xptr[ 1] = &X01;  Xptr[ 2] = &X02;  Xptr[ 3] = &X03;\r\n    Xptr[ 4] = &X04;  Xptr[ 5] = &X05;  Xptr[ 6] = &X06;  Xptr[ 7] = &X07;\r\n    Xptr[ 8] = &X08;  Xptr[ 9] = &X09;  Xptr[10] = &X10;  Xptr[11] = &X11;\r\n    Xptr[12] = &X12;  Xptr[13] = &X13;  Xptr[14] = &X14;  Xptr[15] = &X15;\r\n#endif\r\n\r\n    Skein_assert(blkCnt != 0);                  /* never call with blkCnt == 0! */\r\n    ts[0] = ctx->h.T[0];\r\n    ts[1] = ctx->h.T[1];\r\n    do  {\r\n        /* this implementation only supports 2**64 input bytes (no carry out here) */\r\n        ts[0] += byteCntAdd;                    /* update processed length */\r\n\r\n        /* precompute the key schedule for this block */\r\n        ks[ 0] = ctx->X[ 0];\r\n        ks[ 1] = ctx->X[ 1];\r\n        ks[ 2] = ctx->X[ 2];\r\n        ks[ 3] = ctx->X[ 3];\r\n        ks[ 4] = ctx->X[ 4];\r\n        ks[ 5] = ctx->X[ 5];\r\n        ks[ 6] = ctx->X[ 6];\r\n        ks[ 7] = ctx->X[ 7];\r\n        ks[ 8] = ctx->X[ 8];\r\n        ks[ 9] = ctx->X[ 9];\r\n        ks[10] = ctx->X[10];\r\n        ks[11] = ctx->X[11];\r\n        ks[12] = ctx->X[12];\r\n        ks[13] = ctx->X[13];\r\n        ks[14] = ctx->X[14];\r\n        ks[15] = ctx->X[15];\r\n        ks[16] = ks[ 0] ^ ks[ 1] ^ ks[ 2] ^ ks[ 3] ^\r\n                 ks[ 4] ^ ks[ 5] ^ ks[ 6] ^ ks[ 7] ^\r\n                 ks[ 8] ^ ks[ 9] ^ ks[10] ^ ks[11] ^\r\n                 ks[12] ^ ks[13] ^ ks[14] ^ ks[15] ^ SKEIN_KS_PARITY;\r\n\r\n        ts[2]  = ts[0] ^ ts[1];\r\n\r\n        Skein_Get64_LSB_First(w,blkPtr,WCNT); /* get input block in little-endian format */\r\n        DebugSaveTweak(ctx);\r\n        Skein_Show_Block(BLK_BITS,&ctx->h,ctx->X,blkPtr,w,ks,ts);\r\n\r\n        X00    = w[ 0] + ks[ 0];                 /* do the first full key injection */\r\n        X01    = w[ 1] + ks[ 1];\r\n        X02    = w[ 2] + ks[ 2];\r\n        X03    = w[ 3] + ks[ 3];\r\n        X04    = w[ 4] + ks[ 4];\r\n        X05    = w[ 5] + ks[ 5];\r\n        X06    = w[ 6] + ks[ 6];\r\n        X07    = w[ 7] + ks[ 7];\r\n        X08    = w[ 8] + ks[ 8];\r\n        X09    = w[ 9] + ks[ 9];\r\n        X10    = w[10] + ks[10];\r\n        X11    = w[11] + ks[11];\r\n        X12    = w[12] + ks[12];\r\n        X13    = w[13] + ks[13] + ts[0];\r\n        X14    = w[14] + ks[14] + ts[1];\r\n        X15    = w[15] + ks[15];\r\n\r\n        Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INITIAL,Xptr);\r\n\r\n#define Round1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rNum) \\\r\n    X##p0 += X##p1; X##p1 = RotL_64(X##p1,ROT##_0); X##p1 ^= X##p0;   \\\r\n    X##p2 += X##p3; X##p3 = RotL_64(X##p3,ROT##_1); X##p3 ^= X##p2;   \\\r\n    X##p4 += X##p5; X##p5 = RotL_64(X##p5,ROT##_2); X##p5 ^= X##p4;   \\\r\n    X##p6 += X##p7; X##p7 = RotL_64(X##p7,ROT##_3); X##p7 ^= X##p6;   \\\r\n    X##p8 += X##p9; X##p9 = RotL_64(X##p9,ROT##_4); X##p9 ^= X##p8;   \\\r\n    X##pA += X##pB; X##pB = RotL_64(X##pB,ROT##_5); X##pB ^= X##pA;   \\\r\n    X##pC += X##pD; X##pD = RotL_64(X##pD,ROT##_6); X##pD ^= X##pC;   \\\r\n    X##pE += X##pF; X##pF = RotL_64(X##pF,ROT##_7); X##pF ^= X##pE;   \\\r\n\r\n#if SKEIN_UNROLL_1024 == 0                      \r\n#define R1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \\\r\n    Round1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \\\r\n    Skein_Show_R_Ptr(BLK_BITS,&ctx->h,rn,Xptr);\r\n\r\n#define I1024(R)                                                      \\\r\n    X00   += ks[((R)+ 1) % 17]; /* inject the key schedule value */   \\\r\n    X01   += ks[((R)+ 2) % 17];                                       \\\r\n    X02   += ks[((R)+ 3) % 17];                                       \\\r\n    X03   += ks[((R)+ 4) % 17];                                       \\\r\n    X04   += ks[((R)+ 5) % 17];                                       \\\r\n    X05   += ks[((R)+ 6) % 17];                                       \\\r\n    X06   += ks[((R)+ 7) % 17];                                       \\\r\n    X07   += ks[((R)+ 8) % 17];                                       \\\r\n    X08   += ks[((R)+ 9) % 17];                                       \\\r\n    X09   += ks[((R)+10) % 17];                                       \\\r\n    X10   += ks[((R)+11) % 17];                                       \\\r\n    X11   += ks[((R)+12) % 17];                                       \\\r\n    X12   += ks[((R)+13) % 17];                                       \\\r\n    X13   += ks[((R)+14) % 17] + ts[((R)+1) % 3];                     \\\r\n    X14   += ks[((R)+15) % 17] + ts[((R)+2) % 3];                     \\\r\n    X15   += ks[((R)+16) % 17] +     (R)+1;                           \\\r\n    Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr); \r\n#else                                       /* looping version */\r\n#define R1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \\\r\n    Round1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \\\r\n    Skein_Show_R_Ptr(BLK_BITS,&ctx->h,4*(r-1)+rn,Xptr);\r\n\r\n#define I1024(R)                                                      \\\r\n    X00   += ks[r+(R)+ 0];    /* inject the key schedule value */     \\\r\n    X01   += ks[r+(R)+ 1];                                            \\\r\n    X02   += ks[r+(R)+ 2];                                            \\\r\n    X03   += ks[r+(R)+ 3];                                            \\\r\n    X04   += ks[r+(R)+ 4];                                            \\\r\n    X05   += ks[r+(R)+ 5];                                            \\\r\n    X06   += ks[r+(R)+ 6];                                            \\\r\n    X07   += ks[r+(R)+ 7];                                            \\\r\n    X08   += ks[r+(R)+ 8];                                            \\\r\n    X09   += ks[r+(R)+ 9];                                            \\\r\n    X10   += ks[r+(R)+10];                                            \\\r\n    X11   += ks[r+(R)+11];                                            \\\r\n    X12   += ks[r+(R)+12];                                            \\\r\n    X13   += ks[r+(R)+13] + ts[r+(R)+0];                              \\\r\n    X14   += ks[r+(R)+14] + ts[r+(R)+1];                              \\\r\n    X15   += ks[r+(R)+15] +    r+(R)   ;                              \\\r\n    ks[r  +       (R)+16] = ks[r+(R)-1];  /* rotate key schedule */   \\\r\n    ts[r  +       (R)+ 2] = ts[r+(R)-1];                              \\\r\n    Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);\r\n\r\n    for (r=1;r <= 2*RCNT;r+=2*SKEIN_UNROLL_1024)    /* loop thru it */\r\n#endif  \r\n        {\r\n#define R1024_8_rounds(R)    /* do 8 full rounds */                               \\\r\n        R1024(00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,R1024_0,8*(R) + 1); \\\r\n        R1024(00,09,02,13,06,11,04,15,10,07,12,03,14,05,08,01,R1024_1,8*(R) + 2); \\\r\n        R1024(00,07,02,05,04,03,06,01,12,15,14,13,08,11,10,09,R1024_2,8*(R) + 3); \\\r\n        R1024(00,15,02,11,06,13,04,09,14,01,08,05,10,03,12,07,R1024_3,8*(R) + 4); \\\r\n        I1024(2*(R));                                                             \\\r\n        R1024(00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,R1024_4,8*(R) + 5); \\\r\n        R1024(00,09,02,13,06,11,04,15,10,07,12,03,14,05,08,01,R1024_5,8*(R) + 6); \\\r\n        R1024(00,07,02,05,04,03,06,01,12,15,14,13,08,11,10,09,R1024_6,8*(R) + 7); \\\r\n        R1024(00,15,02,11,06,13,04,09,14,01,08,05,10,03,12,07,R1024_7,8*(R) + 8); \\\r\n        I1024(2*(R)+1);\r\n\r\n        R1024_8_rounds( 0);\r\n\r\n#define R1024_Unroll_R(NN) ((SKEIN_UNROLL_1024 == 0 && SKEIN1024_ROUNDS_TOTAL/8 > (NN)) || (SKEIN_UNROLL_1024 > (NN)))\r\n\r\n  #if   R1024_Unroll_R( 1)\r\n        R1024_8_rounds( 1);\r\n  #endif\r\n  #if   R1024_Unroll_R( 2)\r\n        R1024_8_rounds( 2);\r\n  #endif\r\n  #if   R1024_Unroll_R( 3)\r\n        R1024_8_rounds( 3);\r\n  #endif\r\n  #if   R1024_Unroll_R( 4)\r\n        R1024_8_rounds( 4);\r\n  #endif\r\n  #if   R1024_Unroll_R( 5)\r\n        R1024_8_rounds( 5);\r\n  #endif\r\n  #if   R1024_Unroll_R( 6)\r\n        R1024_8_rounds( 6);\r\n  #endif\r\n  #if   R1024_Unroll_R( 7)\r\n        R1024_8_rounds( 7);\r\n  #endif\r\n  #if   R1024_Unroll_R( 8)\r\n        R1024_8_rounds( 8);\r\n  #endif\r\n  #if   R1024_Unroll_R( 9)\r\n        R1024_8_rounds( 9);\r\n  #endif\r\n  #if   R1024_Unroll_R(10)\r\n        R1024_8_rounds(10);\r\n  #endif\r\n  #if   R1024_Unroll_R(11)\r\n        R1024_8_rounds(11);\r\n  #endif\r\n  #if   R1024_Unroll_R(12)\r\n        R1024_8_rounds(12);\r\n  #endif\r\n  #if   R1024_Unroll_R(13)\r\n        R1024_8_rounds(13);\r\n  #endif\r\n  #if   R1024_Unroll_R(14)\r\n        R1024_8_rounds(14);\r\n  #endif\r\n  #if  (SKEIN_UNROLL_1024 > 14)\r\n#error  \"need more unrolling in Skein_1024_Process_Block\"\r\n  #endif\r\n        }\r\n        /* do the final \"feedforward\" xor, update context chaining vars */\r\n\r\n        ctx->X[ 0] = X00 ^ w[ 0];\r\n        ctx->X[ 1] = X01 ^ w[ 1];\r\n        ctx->X[ 2] = X02 ^ w[ 2];\r\n        ctx->X[ 3] = X03 ^ w[ 3];\r\n        ctx->X[ 4] = X04 ^ w[ 4];\r\n        ctx->X[ 5] = X05 ^ w[ 5];\r\n        ctx->X[ 6] = X06 ^ w[ 6];\r\n        ctx->X[ 7] = X07 ^ w[ 7];\r\n        ctx->X[ 8] = X08 ^ w[ 8];\r\n        ctx->X[ 9] = X09 ^ w[ 9];\r\n        ctx->X[10] = X10 ^ w[10];\r\n        ctx->X[11] = X11 ^ w[11];\r\n        ctx->X[12] = X12 ^ w[12];\r\n        ctx->X[13] = X13 ^ w[13];\r\n        ctx->X[14] = X14 ^ w[14];\r\n        ctx->X[15] = X15 ^ w[15];\r\n\r\n        Skein_Show_Round(BLK_BITS,&ctx->h,SKEIN_RND_FEED_FWD,ctx->X);\r\n        \r\n        ts[1] &= ~SKEIN_T1_FLAG_FIRST;\r\n        blkPtr += SKEIN1024_BLOCK_BYTES;\r\n        }\r\n    while (--blkCnt);\r\n    ctx->h.T[0] = ts[0];\r\n    ctx->h.T[1] = ts[1];\r\n    }\r\n\r\n#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)\r\nsize_t Skein1024_Process_Block_CodeSize(void)\r\n    {\r\n    return ((u08b_t *) Skein1024_Process_Block_CodeSize) -\r\n           ((u08b_t *) Skein1024_Process_Block);\r\n    }\r\nuint_t Skein1024_Unroll_Cnt(void)\r\n    {\r\n    return SKEIN_UNROLL_1024;\r\n    }\r\n#endif\r\n#endif\r\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/skein_iv.h",
    "content": "#ifndef _SKEIN_IV_H_\r\n#define _SKEIN_IV_H_\r\n\r\n#include <cryptcommon/skein.h>    /* get Skein macros and types */\r\n\r\n/*\r\n***************** Pre-computed Skein IVs *******************\r\n**\r\n** NOTE: these values are not \"magic\" constants, but\r\n** are generated using the Threefish block function.\r\n** They are pre-computed here only for speed; i.e., to\r\n** avoid the need for a Threefish call during Init().\r\n**\r\n** The IV for any fixed hash length may be pre-computed.\r\n** Only the most common values are included here.\r\n**\r\n************************************************************\r\n**/\r\n\r\n#define MK_64 SKEIN_MK_64\r\n\r\n/* blkSize =  256 bits. hashSize =  128 bits */\r\nconst u64b_t SKEIN_256_IV_128[] =\r\n    {\r\n    MK_64(0xE1111906,0x964D7260),\r\n    MK_64(0x883DAAA7,0x7C8D811C),\r\n    MK_64(0x10080DF4,0x91960F7A),\r\n    MK_64(0xCCF7DDE5,0xB45BC1C2)\r\n    };\r\n\r\n/* blkSize =  256 bits. hashSize =  160 bits */\r\nconst u64b_t SKEIN_256_IV_160[] =\r\n    {\r\n    MK_64(0x14202314,0x72825E98),\r\n    MK_64(0x2AC4E9A2,0x5A77E590),\r\n    MK_64(0xD47A5856,0x8838D63E),\r\n    MK_64(0x2DD2E496,0x8586AB7D)\r\n    };\r\n\r\n/* blkSize =  256 bits. hashSize =  224 bits */\r\nconst u64b_t SKEIN_256_IV_224[] =\r\n    {\r\n    MK_64(0xC6098A8C,0x9AE5EA0B),\r\n    MK_64(0x876D5686,0x08C5191C),\r\n    MK_64(0x99CB88D7,0xD7F53884),\r\n    MK_64(0x384BDDB1,0xAEDDB5DE)\r\n    };\r\n\r\n/* blkSize =  256 bits. hashSize =  256 bits */\r\nconst u64b_t SKEIN_256_IV_256[] =\r\n    {\r\n    MK_64(0xFC9DA860,0xD048B449),\r\n    MK_64(0x2FCA6647,0x9FA7D833),\r\n    MK_64(0xB33BC389,0x6656840F),\r\n    MK_64(0x6A54E920,0xFDE8DA69)\r\n    };\r\n\r\n/* blkSize =  512 bits. hashSize =  128 bits */\r\nconst u64b_t SKEIN_512_IV_128[] =\r\n    {\r\n    MK_64(0xA8BC7BF3,0x6FBF9F52),\r\n    MK_64(0x1E9872CE,0xBD1AF0AA),\r\n    MK_64(0x309B1790,0xB32190D3),\r\n    MK_64(0xBCFBB854,0x3F94805C),\r\n    MK_64(0x0DA61BCD,0x6E31B11B),\r\n    MK_64(0x1A18EBEA,0xD46A32E3),\r\n    MK_64(0xA2CC5B18,0xCE84AA82),\r\n    MK_64(0x6982AB28,0x9D46982D)\r\n    };\r\n\r\n/* blkSize =  512 bits. hashSize =  160 bits */\r\nconst u64b_t SKEIN_512_IV_160[] =\r\n    {\r\n    MK_64(0x28B81A2A,0xE013BD91),\r\n    MK_64(0xC2F11668,0xB5BDF78F),\r\n    MK_64(0x1760D8F3,0xF6A56F12),\r\n    MK_64(0x4FB74758,0x8239904F),\r\n    MK_64(0x21EDE07F,0x7EAF5056),\r\n    MK_64(0xD908922E,0x63ED70B8),\r\n    MK_64(0xB8EC76FF,0xECCB52FA),\r\n    MK_64(0x01A47BB8,0xA3F27A6E)\r\n    };\r\n\r\n/* blkSize =  512 bits. hashSize =  224 bits */\r\nconst u64b_t SKEIN_512_IV_224[] =\r\n    {\r\n    MK_64(0xCCD06162,0x48677224),\r\n    MK_64(0xCBA65CF3,0xA92339EF),\r\n    MK_64(0x8CCD69D6,0x52FF4B64),\r\n    MK_64(0x398AED7B,0x3AB890B4),\r\n    MK_64(0x0F59D1B1,0x457D2BD0),\r\n    MK_64(0x6776FE65,0x75D4EB3D),\r\n    MK_64(0x99FBC70E,0x997413E9),\r\n    MK_64(0x9E2CFCCF,0xE1C41EF7)\r\n    };\r\n\r\n/* blkSize =  512 bits. hashSize =  256 bits */\r\nconst u64b_t SKEIN_512_IV_256[] =\r\n    {\r\n    MK_64(0xCCD044A1,0x2FDB3E13),\r\n    MK_64(0xE8359030,0x1A79A9EB),\r\n    MK_64(0x55AEA061,0x4F816E6F),\r\n    MK_64(0x2A2767A4,0xAE9B94DB),\r\n    MK_64(0xEC06025E,0x74DD7683),\r\n    MK_64(0xE7A436CD,0xC4746251),\r\n    MK_64(0xC36FBAF9,0x393AD185),\r\n    MK_64(0x3EEDBA18,0x33EDFC13)\r\n    };\r\n\r\n/* blkSize =  512 bits. hashSize =  384 bits */\r\nconst u64b_t SKEIN_512_IV_384[] =\r\n    {\r\n    MK_64(0xA3F6C6BF,0x3A75EF5F),\r\n    MK_64(0xB0FEF9CC,0xFD84FAA4),\r\n    MK_64(0x9D77DD66,0x3D770CFE),\r\n    MK_64(0xD798CBF3,0xB468FDDA),\r\n    MK_64(0x1BC4A666,0x8A0E4465),\r\n    MK_64(0x7ED7D434,0xE5807407),\r\n    MK_64(0x548FC1AC,0xD4EC44D6),\r\n    MK_64(0x266E1754,0x6AA18FF8)\r\n    };\r\n\r\n/* blkSize =  512 bits. hashSize =  512 bits */\r\nconst u64b_t SKEIN_512_IV_512[] =\r\n    {\r\n    MK_64(0x4903ADFF,0x749C51CE),\r\n    MK_64(0x0D95DE39,0x9746DF03),\r\n    MK_64(0x8FD19341,0x27C79BCE),\r\n    MK_64(0x9A255629,0xFF352CB1),\r\n    MK_64(0x5DB62599,0xDF6CA7B0),\r\n    MK_64(0xEABE394C,0xA9D5C3F4),\r\n    MK_64(0x991112C7,0x1A75B523),\r\n    MK_64(0xAE18A40B,0x660FCC33)\r\n    };\r\n\r\n/* blkSize = 1024 bits. hashSize =  384 bits */\r\nconst u64b_t SKEIN1024_IV_384[] =\r\n    {\r\n    MK_64(0x5102B6B8,0xC1894A35),\r\n    MK_64(0xFEEBC9E3,0xFE8AF11A),\r\n    MK_64(0x0C807F06,0xE32BED71),\r\n    MK_64(0x60C13A52,0xB41A91F6),\r\n    MK_64(0x9716D35D,0xD4917C38),\r\n    MK_64(0xE780DF12,0x6FD31D3A),\r\n    MK_64(0x797846B6,0xC898303A),\r\n    MK_64(0xB172C2A8,0xB3572A3B),\r\n    MK_64(0xC9BC8203,0xA6104A6C),\r\n    MK_64(0x65909338,0xD75624F4),\r\n    MK_64(0x94BCC568,0x4B3F81A0),\r\n    MK_64(0x3EBBF51E,0x10ECFD46),\r\n    MK_64(0x2DF50F0B,0xEEB08542),\r\n    MK_64(0x3B5A6530,0x0DBC6516),\r\n    MK_64(0x484B9CD2,0x167BBCE1),\r\n    MK_64(0x2D136947,0xD4CBAFEA)\r\n    };\r\n\r\n/* blkSize = 1024 bits. hashSize =  512 bits */\r\nconst u64b_t SKEIN1024_IV_512[] =\r\n    {\r\n    MK_64(0xCAEC0E5D,0x7C1B1B18),\r\n    MK_64(0xA01B0E04,0x5F03E802),\r\n    MK_64(0x33840451,0xED912885),\r\n    MK_64(0x374AFB04,0xEAEC2E1C),\r\n    MK_64(0xDF25A0E2,0x813581F7),\r\n    MK_64(0xE4004093,0x8B12F9D2),\r\n    MK_64(0xA662D539,0xC2ED39B6),\r\n    MK_64(0xFA8B85CF,0x45D8C75A),\r\n    MK_64(0x8316ED8E,0x29EDE796),\r\n    MK_64(0x053289C0,0x2E9F91B8),\r\n    MK_64(0xC3F8EF1D,0x6D518B73),\r\n    MK_64(0xBDCEC3C4,0xD5EF332E),\r\n    MK_64(0x549A7E52,0x22974487),\r\n    MK_64(0x67070872,0x5B749816),\r\n    MK_64(0xB9CD28FB,0xF0581BD1),\r\n    MK_64(0x0E2940B8,0x15804974)\r\n    };\r\n\r\n/* blkSize = 1024 bits. hashSize = 1024 bits */\r\nconst u64b_t SKEIN1024_IV_1024[] =\r\n    {\r\n    MK_64(0xD593DA07,0x41E72355),\r\n    MK_64(0x15B5E511,0xAC73E00C),\r\n    MK_64(0x5180E5AE,0xBAF2C4F0),\r\n    MK_64(0x03BD41D3,0xFCBCAFAF),\r\n    MK_64(0x1CAEC6FD,0x1983A898),\r\n    MK_64(0x6E510B8B,0xCDD0589F),\r\n    MK_64(0x77E2BDFD,0xC6394ADA),\r\n    MK_64(0xC11E1DB5,0x24DCB0A3),\r\n    MK_64(0xD6D14AF9,0xC6329AB5),\r\n    MK_64(0x6A9B0BFC,0x6EB67E0D),\r\n    MK_64(0x9243C60D,0xCCFF1332),\r\n    MK_64(0x1A1F1DDE,0x743F02D4),\r\n    MK_64(0x0996753C,0x10ED0BB8),\r\n    MK_64(0x6572DD22,0xF2B4969A),\r\n    MK_64(0x61FD3062,0xD00A579A),\r\n    MK_64(0x1DE0536E,0x8682E539)\r\n    };\r\n\r\n#endif /* _SKEIN_IV_H_ */\r\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/skein_port.h",
    "content": "#ifndef _SKEIN_PORT_H_\r\n#define _SKEIN_PORT_H_\r\n/*******************************************************************\r\n**\r\n** Platform-specific definitions for Skein hash function.\r\n**\r\n** Source code author: Doug Whiting, 2008.\r\n**\r\n** This algorithm and source code is released to the public domain.\r\n**\r\n** Many thanks to Brian Gladman for his portable header files.\r\n**\r\n** To port Skein to an \"unsupported\" platform, change the definitions\r\n** in this file appropriately.\r\n** \r\n********************************************************************/\r\n\r\n#include <cryptcommon/brg_types.h>                      /* get integer type definitions */\r\n\r\n/*r3gis3r : android already has that defined in types */\r\n#ifndef ANDROID\r\ntypedef unsigned int    uint_t;             /* native unsigned integer */\r\n#endif\r\ntypedef uint_8t         u08b_t;             /*  8-bit unsigned integer */\r\ntypedef uint_64t        u64b_t;             /* 64-bit unsigned integer */\r\n\r\n#ifndef RotL_64\r\n#define RotL_64(x,N)    (((x) << (N)) | ((x) >> (64-(N))))\r\n#endif\r\n\r\n/*\r\n * Skein is \"natively\" little-endian (unlike SHA-xxx), for optimal\r\n * performance on x86 CPUs.  The Skein code requires the following\r\n * definitions for dealing with endianness:\r\n *\r\n *    SKEIN_NEED_SWAP:  0 for little-endian, 1 for big-endian\r\n *    Skein_Put64_LSB_First\r\n *    Skein_Get64_LSB_First\r\n *    Skein_Swap64\r\n *\r\n * If SKEIN_NEED_SWAP is defined at compile time, it is used here\r\n * along with the portable versions of Put64/Get64/Swap64, which \r\n * are slow in general.\r\n *\r\n * Otherwise, an \"auto-detect\" of endianness is attempted below.\r\n * If the default handling doesn't work well, the user may insert\r\n * platform-specific code instead (e.g., for big-endian CPUs).\r\n *\r\n */\r\n#ifndef SKEIN_NEED_SWAP /* compile-time \"override\" for endianness? */\r\n\r\n#include <cryptcommon/brg_endian.h>              /* get endianness selection */\r\n#if   PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN\r\n    /* here for big-endian CPUs */\r\n#define SKEIN_NEED_SWAP   (1)\r\n#elif PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN\r\n    /* here for x86 and x86-64 CPUs (and other detected little-endian CPUs) */\r\n#define SKEIN_NEED_SWAP   (0)\r\n#if   PLATFORM_MUST_ALIGN == 0              /* ok to use \"fast\" versions? */\r\n#define Skein_Put64_LSB_First(dst08,src64,bCnt) memcpy(dst08,src64,bCnt)\r\n#define Skein_Get64_LSB_First(dst64,src08,wCnt) memcpy(dst64,src08,8*(wCnt))\r\n#endif\r\n#else\r\n#error \"Skein needs endianness setting!\"\r\n#endif\r\n\r\n#endif /* ifndef SKEIN_NEED_SWAP */\r\n\r\n/*\r\n ******************************************************************\r\n *      Provide any definitions still needed.\r\n ******************************************************************\r\n */\r\n#ifndef Skein_Swap64  /* swap for big-endian, nop for little-endian */\r\n#if     SKEIN_NEED_SWAP\r\n#define Skein_Swap64(w64)                       \\\r\n  ( (( ((u64b_t)(w64))       & 0xFF) << 56) |   \\\r\n    (((((u64b_t)(w64)) >> 8) & 0xFF) << 48) |   \\\r\n    (((((u64b_t)(w64)) >>16) & 0xFF) << 40) |   \\\r\n    (((((u64b_t)(w64)) >>24) & 0xFF) << 32) |   \\\r\n    (((((u64b_t)(w64)) >>32) & 0xFF) << 24) |   \\\r\n    (((((u64b_t)(w64)) >>40) & 0xFF) << 16) |   \\\r\n    (((((u64b_t)(w64)) >>48) & 0xFF) <<  8) |   \\\r\n    (((((u64b_t)(w64)) >>56) & 0xFF)      ) )\r\n#else\r\n#define Skein_Swap64(w64)  (w64)\r\n#endif\r\n#endif  /* ifndef Skein_Swap64 */\r\n\r\n\r\n#ifndef Skein_Put64_LSB_First\r\nvoid    Skein_Put64_LSB_First(u08b_t *dst,const u64b_t *src,size_t bCnt)\r\n#ifdef  SKEIN_PORT_CODE /* instantiate the function code here? */\r\n    { /* this version is fully portable (big-endian or little-endian), but slow */\r\n    size_t n;\r\n\r\n    for (n=0;n<bCnt;n++)\r\n        dst[n] = (u08b_t) (src[n>>3] >> (8*(n&7)));\r\n    }\r\n#else\r\n    ;    /* output only the function prototype */\r\n#endif\r\n#endif   /* ifndef Skein_Put64_LSB_First */\r\n\r\n\r\n#ifndef Skein_Get64_LSB_First\r\nvoid    Skein_Get64_LSB_First(u64b_t *dst,const u08b_t *src,size_t wCnt)\r\n#ifdef  SKEIN_PORT_CODE /* instantiate the function code here? */\r\n    { /* this version is fully portable (big-endian or little-endian), but slow */\r\n    size_t n;\r\n\r\n    for (n=0;n<8*wCnt;n+=8)\r\n        dst[n/8] = (((u64b_t) src[n  ])      ) +\r\n                   (((u64b_t) src[n+1]) <<  8) +\r\n                   (((u64b_t) src[n+2]) << 16) +\r\n                   (((u64b_t) src[n+3]) << 24) +\r\n                   (((u64b_t) src[n+4]) << 32) +\r\n                   (((u64b_t) src[n+5]) << 40) +\r\n                   (((u64b_t) src[n+6]) << 48) +\r\n                   (((u64b_t) src[n+7]) << 56) ;\r\n    }\r\n#else\r\n    ;    /* output only the function prototype */\r\n#endif\r\n#endif   /* ifndef Skein_Get64_LSB_First */\r\n\r\n#endif   /* ifndef _SKEIN_PORT_H_ */\r\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/twofish.c",
    "content": "/* \n * Fast, portable, and easy-to-use Twofish implementation,  \n * Version 0.3. \n * Copyright (c) 2002 by Niels Ferguson.  \n * (See further down for the almost-unrestricted licensing terms.) \n * \n * -------------------------------------------------------------------------- \n * There are two files for this implementation: \n * - twofish.h, the header file. \n * - twofish.c, the code file. \n * \n * To incorporate this code into your program you should: \n * - Check the licensing terms further down in this comment. \n * - Fix the two type definitions in twofish.h to suit your platform. \n * - Fix a few definitions in twofish.c in the section marked  \n *   PLATFORM FIXES. There is one important ones that affects  \n *   functionality, and then a few definitions that you can optimise  \n *   for efficiency but those have no effect on the functionality.  \n *   Don't change anything else. \n * - Put the code in your project and compile it. \n * \n * To use this library you should: \n * - Call Twofish_initialise() in your program before any other function in \n *   this library. \n * - Use Twofish_prepare_key(...) to convert a key to internal form. \n * - Use Twofish_encrypt(...) and Twofish_decrypt(...) to encrypt and decrypt \n *   data. \n * See the comments in the header file for details on these functions. \n * -------------------------------------------------------------------------- \n *  \n * There are many Twofish implementation available for free on the web. \n * Most of them are hard to integrate into your own program. \n * As we like people to use our cipher, I thought I would make it easier.  \n * Here is a free and easy-to-integrate Twofish implementation in C. \n * The latest version is always available from my personal home page at \n *    http://niels.ferguson.net/ \n * \n * Integrating library code into a project is difficult because the library \n * header files interfere with the project's header files and code.  \n * And of course the project's header files interfere with the library code. \n * I've tried to resolve these problems here.  \n * The header file of this implementation is very light-weight.  \n * It contains two typedefs, a structure, and a few function declarations. \n * All names it defines start with \"Twofish_\".  \n * The header file is therefore unlikely to cause problems in your project. \n * The code file of this implementation doesn't need to include the header \n * files of the project. There is thus no danger of the project interfering \n * with all the definitions and macros of the Twofish code. \n * In most situations, all you need to do is fill in a few platform-specific \n * definitions in the header file and code file,  \n * and you should be able to run the Twofish code in your project. \n * I estimate it should take you less than an hour to integrate this code \n * into your project, most of it spent reading the comments telling you what \n * to do. \n * \n * For people using C++: it is very easy to wrap this library into a \n * TwofishKey class. One of the big advantages is that you can automate the \n * wiping of the key material in the destructor. I have not provided a C++ \n * class because the interface depends too much on the abstract base class  \n * you use for block ciphers in your program, which I don't know about. \n * \n * This implementation is designed for use on PC-class machines. It uses the  \n * Twofish 'full' keying option which uses large tables. Total table size is  \n * around 5-6 kB for static tables plus 4.5 kB for each pre-processed key. \n * If you need an implementation that uses less memory, \n * take a look at Brian Gladman's code on his web site: \n *     http://fp.gladman.plus.com/cryptography_technology/aes/ \n * He has code for all AES candidates. \n * His Twofish code has lots of options trading off table size vs. speed. \n * You can also take a look at the optimised code by Doug Whiting on the \n * Twofish web site \n *      http://www.counterpane.com/twofish.html \n * which has loads of options. \n * I believe these existing implementations are harder to re-use because they \n * are not clean libraries and they impose requirements on the environment.  \n * This implementation is very careful to minimise those,  \n * and should be easier to integrate into any larger program. \n * \n * The default mode of this implementation is fully portable as it uses no \n * behaviour not defined in the C standard. (This is harder than you think.) \n * If you have any problems porting the default mode, please let me know \n * so that I can fix the problem. (But only if this code is at fault, I  \n * don't fix compilers.) \n * Most of the platform fixes are related to non-portable but faster ways  \n * of implementing certain functions. \n * \n * In general I've tried to make the code as fast as possible, at the expense \n * of memory and code size. However, C does impose limits, and this  \n * implementation will be slower than an optimised assembler implementation. \n * But beware of assembler implementations: a good Pentium implementation \n * uses completely different code than a good Pentium II implementation. \n * You basically have to re-write the assembly code for every generation of \n * processor. Unless you are severely pressed for speed, stick with C. \n * \n * The initialisation routine of this implementation contains a self-test. \n * If initialisation succeeds without calling the fatal routine, then \n * the implementation works. I don't think you can break the implementation \n * in such a way that it still passes the tests, unless you are malicious. \n * In other words: if the initialisation routine returns,  \n * you have successfully ported the implementation.  \n * (Or not implemented the fatal routine properly, but that is your problem.) \n * \n * I'm indebted to many people who helped me in one way or another to write \n * this code. During the design of Twofish and the AES process I had very  \n * extensive discussions of all implementation issues with various people. \n * Doug Whiting in particular provided a wealth of information. The Twofish  \n * team spent untold hours discussion various cipher features, and their  \n * implementation. Brian Gladman implemented all AES candidates in C,  \n * and we had some fruitful discussions on how to implement Twofish in C. \n * Jan Nieuwenhuizen tested this code on Linux using GCC. \n * \n * Now for the license: \n * The author hereby grants a perpetual license to everybody to \n * use this code for any purpose as long as the copyright message is included \n * in the source code of this or any derived work. \n *  \n * Yes, this means that you, your company, your club, and anyone else \n * can use this code anywhere you want. You can change it and distribute it \n * under the GPL, include it in your commercial product without releasing \n * the source code, put it on the web, etc.  \n * The only thing you cannot do is remove my copyright message,  \n * or distribute any source code based on this implementation that does not  \n * include my copyright message.  \n *  \n * I appreciate a mention in the documentation or credits,  \n * but I understand if that is difficult to do. \n * I also appreciate it if you tell me where and why you used my code. \n * \n * Please send any questions or comments to niels@ferguson.net \n * \n * Have Fun! \n * \n * Niels \n */ \n \n/* \n * DISCLAIMER: As I'm giving away my work for free, I'm of course not going \n * to accept any liability of any form. This code, or the Twofish cipher, \n * might very well be flawed; you have been warned. \n * This software is provided as-is, without any kind of warrenty or \n * guarantee. And that is really all you can expect when you download  \n * code for free from the Internet.  \n * \n * I think it is really sad that disclaimers like this seem to be necessary. \n * If people only had a little bit more common sense, and didn't come \n * whining like little children every time something happens.... \n */ \n  \n/* \n * Version history: \n * Version 0.0, 2002-08-30 \n *      First written. \n * Version 0.1, 2002-09-03 \n *      Added disclaimer. Improved self-tests. \n * Version 0.2, 2002-09-09 \n *      Removed last non-portabilities. Default now works completely within \n *      the C standard. UInt32 can be larger than 32 bits without problems. \n * Version 0.3, 2002-09-28 \n *      Bugfix: use  instead of  to adhere to ANSI/ISO. \n *      Rename BIG_ENDIAN macro to CPU_IS_BIG_ENDIAN. The gcc library  \n *      header  already defines BIG_ENDIAN, even though it is not  \n *      supposed to. \n */ \n \n \n/*  \n * Minimum set of include files. \n * You should not need any application-specific include files for this code.  \n * In fact, adding you own header files could break one of the many macros or \n * functions in this file. Be very careful. \n * Standard include files will probably be ok. \n */ \n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n/* #include      * for memset(), memcpy(), and memcmp() */ \n#include \"twofish.h\" \n \n \n/* \n * PLATFORM FIXES \n * ============== \n * \n * Fix the type definitions in twofish.h first! \n *  \n * The following definitions have to be fixed for each particular platform  \n * you work on. If you have a multi-platform program, you no doubt have  \n * portable definitions that you can substitute here without changing the  \n * rest of the code. \n */ \n \n \n/*  \n * Function called if something is fatally wrong with the implementation.  \n * This fatal function is called when a coding error is detected in the \n * Twofish implementation, or when somebody passes an obviously erroneous \n * parameter to this implementation. There is not much you can do when \n * the code contains bugs, so we just stop. \n *  \n * The argument is a string. Ideally the fatal function prints this string \n * as an error message. Whatever else this function does, it should never \n * return. A typical implementation would stop the program completely after \n * printing the error message. \n * \n * This default implementation is not very useful,  \n * but does not assume anything about your environment.  \n * It will at least let you know something is wrong.... \n * I didn't want to include any libraries to print and error or so, \n * as this makes the code much harder to integrate in a project. \n * \n * Note that the Twofish_fatal function may not return to the caller. \n * Unfortunately this is not something the self-test can test for, \n * so you have to make sure of this yourself. \n * \n * If you want to call an external function, be careful about including \n * your own header files here. This code uses a lot of macros, and your \n * header file could easily break it. Maybe the best solution is to use \n * a separate extern statement for your fatal function. \n */ \n/* #define Twofish_fatal(pmsgx) { fprintf(stderr, pmsgx); exit(1); } */\n#define Twofish_fatal(pmsgx, code) { return(code); } \n \n \n/* \n * The rest of the settings are not important for the functionality \n * of this Twofish implementation. That is, their default settings \n * work on all platforms. You can change them to improve the  \n * speed of the implementation on your platform. Erroneous settings \n * will result in erroneous implementations, but the self-test should \n * catch those. \n */ \n \n \n/*  \n * Macros to rotate a Twofish_UInt32 value left or right by the  \n * specified number of bits. This should be a 32-bit rotation,  \n * and not rotation of, say, 64-bit values. \n * \n * Every encryption or decryption operation uses 32 of these rotations, \n * so it is a good idea to make these macros efficient. \n * \n * This fully portable definition has one piece of tricky stuff. \n * The UInt32 might be larger than 32 bits, so we have to mask \n * any higher bits off. The simplest way to do this is to 'and' the \n * value first with 0xffffffff and then shift it right. An optimising \n * compiler that has a 32-bit type can optimise this 'and' away. \n *  \n * Unfortunately there is no portable way of writing the constant \n * 0xffffffff. You don't know which suffix to use (U, or UL?) \n * The UINT32_MASK definition uses a bit of trickery. Shift-left \n * is only defined if the shift amount is strictly less than the size \n * of the UInt32, so we can't use (1<<32). The answer it to take the value \n * 2, cast it to a UInt32, shift it left 31 positions, and subtract one. \n * Another example of how to make something very simple extremely difficult. \n * I hate C. \n *  \n * The rotation macros are straightforward. \n * They are only applied to UInt32 values, which are _unsigned_ \n * so the >> operator must do a logical shift that brings in zeroes. \n * On most platforms you will only need to optimise the ROL32 macro; the \n * ROR32 macro is not inefficient on an optimising compiler as all rotation \n * amounts in this code are known at compile time. \n * \n * On many platforms there is a faster solution. \n * For example, MS compilers have the __rotl and __rotr functions \n * that generate x86 rotation instructions. \n */ \n#define UINT32_MASK    ( (((Twofish_UInt32)2)<<31) - 1 ) \n \n#ifndef _MSC_VER \n#define ROL32(x,n) ( (x)<<(n) | ((x) & UINT32_MASK) >> (32-(n)) ) \n#define ROR32(x,n) ( (x)>>(n) | ((x) & UINT32_MASK) << (32-(n)) ) \n#else \n#define ROL32(x,n) (_lrotl((x), (n))) \n#define ROR32(x,n) (_lrotr((x), (n))) \n#endif \n \n/* \n * Select data type for q-table entries.  \n * \n * Larger entry types cost more memory (1.5 kB), and might be faster  \n * or slower depending on the CPU and compiler details. \n * \n * This choice only affects the static data size and the key setup speed. \n * Functionality, expanded key size, or encryption speed are not affected. \n * Define to 1 to get large q-table entries. \n */ \n#define LARGE_Q_TABLE   0    /* default = 0 */ \n \n \n/* \n * Method to select a single byte from a UInt32. \n * WARNING: non-portable code if set; might not work on all platforms. \n * \n * Inside the inner loop of Twofish it is necessary to access the 4  \n * individual bytes of a UInt32. This can be done using either shifts \n * and masks, or memory accesses. \n * \n * Set to 0 to use shift and mask operations for the byte selection. \n * This is more ALU intensive. It is also fully portable.  \n *  \n * Set to 1 to use memory accesses. The UInt32 is stored in memory and \n * the individual bytes are read from memory one at a time. \n * This solution is more memory-intensive, and not fully portable. \n * It might be faster on your platform, or not. If you use this option, \n * make sure you set the CPU_IS_BIG_ENDIAN flag appropriately. \n *  \n * This macro does not affect the conversion of the inputs and outputs \n * of the cipher. See the CONVERT_USING_CASTS macro for that. \n */ \n#define SELECT_BYTE_FROM_UINT32_IN_MEMORY    0    /* default = 0 */ \n \n \n/* \n * Method used to read the input and write the output. \n * WARNING: non-portable code if set; might not work on all platforms. \n * \n * Twofish operates on 32-bit words. The input to the cipher is \n * a byte array, as is the output. The portable method of doing the \n * conversion is a bunch of rotate and mask operations, but on many  \n * platforms it can be done faster using a cast. \n * This only works if your CPU allows UInt32 accesses to arbitrary Byte \n * addresses. \n *  \n * Set to 0 to use the shift and mask operations. This is fully \n * portable. . \n * \n * Set to 1 to use a cast. The Byte * is cast to a UInt32 *, and a \n * UInt32 is read. If necessary (as indicated by the CPU_IS_BIG_ENDIAN  \n * macro) the byte order in the UInt32 is swapped. The reverse is done \n * to write the output of the encryption/decryption. Make sure you set \n * the CPU_IS_BIG_ENDIAN flag appropriately. \n * This option does not work unless a UInt32 is exactly 32 bits. \n * \n * This macro only changes the reading/writing of the plaintext/ciphertext. \n * See the SELECT_BYTE_FROM_UINT32_IN_MEMORY to affect the way in which \n * a UInt32 is split into 4 bytes for the S-box selection. \n */ \n#define CONVERT_USING_CASTS    0    /* default = 0 */ \n \n \n/*  \n * Endianness switch. \n * Only relevant if SELECT_BYTE_FROM_UINT32_IN_MEMORY or \n * CONVERT_USING_CASTS is set. \n * \n * Set to 1 on a big-endian machine, and to 0 on a little-endian machine.  \n * Twofish uses the little-endian convention (least significant byte first) \n * and big-endian machines (using most significant byte first)  \n * have to do a few conversions.  \n * \n * CAUTION: This code has never been tested on a big-endian machine,  \n * because I don't have access to one. Feedback appreciated. \n */ \n#define CPU_IS_BIG_ENDIAN    0 \n \n \n/*  \n * Macro to reverse the order of the bytes in a UInt32. \n * Used to convert to little-endian on big-endian machines. \n * This macro is always tested, but only used in the encryption and \n * decryption if CONVERT_USING_CASTS, and CPU_IS_BIG_ENDIAN \n * are both set. In other words: this macro is only speed-critical if \n * both these flags have been set. \n * \n * This default definition of SWAP works, but on many platforms there is a  \n * more efficient implementation.  \n */ \n#define BSWAP(x) ((ROL32((x),8)&0x00ff00ff) | (ROR32((x),8) & 0xff00ff00)) \n \n \n/* \n * END OF PLATFORM FIXES \n * ===================== \n *  \n * You should not have to touch the rest of this file. \n */ \n \n \n/* \n * Convert the external type names to some that are easier to use inside \n * this file. I didn't want to use the names Byte and UInt32 in the \n * header file, because many programs already define them and using two \n * conventions at once can be very difficult. \n * Don't change these definitions! Change the originals  \n * in twofish.h instead.  \n */ \n/* A Byte must be an unsigned integer, 8 bits long. */ \n/* typedef Twofish_Byte    Byte; */\n/* A UInt32 must be an unsigned integer at least 32 bits long. */ \n/* typedef Twofish_UInt32  UInt32; */\n \n \n/*  \n * Define a macro ENDIAN_CONVERT. \n * \n * We define a macro ENDIAN_CONVERT that performs a BSWAP on big-endian \n * machines, and is the identity function on little-endian machines. \n * The code then uses this macro without considering the endianness. \n */ \n \n#if CPU_IS_BIG_ENDIAN \n#define ENDIAN_CONVERT(x)    BSWAP(x) \n#else \n#define ENDIAN_CONVERT(x)    (x) \n#endif \n \n \n/*  \n * Compute byte offset within a UInt32 stored in memory. \n * \n * This is only used when SELECT_BYTE_FROM_UINT32_IN_MEMORY is set. \n *  \n * The input is the byte number 0..3, 0 for least significant. \n * Note the use of sizeof() to support UInt32 types that are larger \n * than 4 bytes. \n */ \n#if CPU_IS_BIG_ENDIAN \n#define BYTE_OFFSET( n )  (sizeof(Twofish_UInt32) - 1 - (n) ) \n#else \n#define BYTE_OFFSET( n )  (n) \n#endif \n \n \n/* \n * Macro to get Byte no. b from UInt32 value X. \n * We use two different definition, depending on the settings. \n */ \n#if SELECT_BYTE_FROM_UINT32_IN_MEMORY \n    /* Pick the byte from the memory in which X is stored. */ \n#define SELECT_BYTE( X, b ) (((Twofish_Byte *)(&(X)))[BYTE_OFFSET(b)]) \n#else \n    /* Portable solution: Pick the byte directly from the X value. */ \n#define SELECT_BYTE( X, b ) (((X) >> (8*(b))) & 0xff) \n#endif \n \n \n/* Some shorthands because we use byte selection in large formulae. */ \n#define b0(X)   SELECT_BYTE((X),0) \n#define b1(X)   SELECT_BYTE((X),1) \n#define b2(X)   SELECT_BYTE((X),2) \n#define b3(X)   SELECT_BYTE((X),3) \n \n \n/* \n * We need macros to load and store UInt32 from/to byte arrays \n * using the least-significant-byte-first convention. \n * \n * GET32( p ) gets a UInt32 in lsb-first form from four bytes pointed to \n * by p. \n * PUT32( v, p ) writes the UInt32 value v at address p in lsb-first form. \n */ \n#if CONVERT_USING_CASTS \n \n    /* Get UInt32 from four bytes pointed to by p. */ \n#define GET32( p )    ENDIAN_CONVERT( *((Twofish_UInt32 *)(p)) ) \n    /* Put UInt32 into four bytes pointed to by p */ \n#define PUT32( v, p ) *((Twofish_UInt32 *)(p)) = ENDIAN_CONVERT(v) \n \n#else \n \n    /* Get UInt32 from four bytes pointed to by p. */ \n#define GET32( p ) \\\n    ( \\\n      (Twofish_UInt32)((p)[0])     \\\n    | (Twofish_UInt32)((p)[1])<< 8 \\\n    | (Twofish_UInt32)((p)[2])<<16 \\\n    | (Twofish_UInt32)((p)[3])<<24 \\\n    ) \n    /* Put UInt32 into four bytes pointed to by p */ \n#define PUT32( v, p ) \\\n    (p)[0] = (Twofish_Byte)(((v)      ) & 0xff); \\\n    (p)[1] = (Twofish_Byte)(((v) >>  8) & 0xff); \\\n    (p)[2] = (Twofish_Byte)(((v) >> 16) & 0xff); \\\n    (p)[3] = (Twofish_Byte)(((v) >> 24) & 0xff)\n \n#endif \n\n#ifdef ANDROID\n/**\n * Dummy function to disable some compiler optimizations.\n * \n * See comment in Twofish_cfb128_encrypt().\n */\nvoid Two_debugDummy(Twofish_Byte* in, Twofish_Byte* out, Twofish_Byte* ivec)\n{\n}\n#endif\n/* \n * Test the platform-specific macros. \n * This function tests the macros defined so far to make sure the  \n * definitions are appropriate for this platform. \n * If you make any mistake in the platform configuration, this should detect \n * that and inform you what went wrong. \n * Somewhere, someday, this is going to save somebody a lot of time, \n * because misbehaving macros are hard to debug. \n */ \nstatic int test_platform() \n    { \n    /* Buffer with test values. */ \n    Twofish_Byte buf[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0}; \n    Twofish_UInt32 C; \n    Twofish_UInt32 x,y; \n    int i; \n \n    /*  \n     * Some sanity checks on the types that can't be done in compile time.  \n     * A smart compiler will just optimise these tests away. \n     * The pre-processor doesn't understand different types, so we cannot \n     * do these checks in compile-time. \n     * \n     * I hate C. \n     * \n     * The first check in each case is to make sure the size is correct. \n     * The second check is to ensure that it is an unsigned type. \n     */ \n    if( ((Twofish_UInt32)((Twofish_UInt32)1 << 31) == 0) || ((Twofish_UInt32)-1 < 0 ))  \n        { \n\t  Twofish_fatal( \"Twofish code: Twofish_UInt32 type not suitable\", ERR_UINT32 ); \n        } \n    if( (sizeof( Twofish_Byte ) != 1) || (((Twofish_Byte)-1) < 0) )  \n        { \n\t  Twofish_fatal( \"Twofish code: Twofish_Byte type not suitable\", ERR_BYTE ); \n        } \n \n    /*  \n     * Sanity-check the endianness conversions.  \n     * This is just an aid to find problems. If you do the endianness \n     * conversion macros wrong you will fail the full cipher test, \n     * but that does not help you find the error. \n     * Always make it easy to find the bugs!  \n     * \n     * Detail: There is no fully portable way of writing UInt32 constants, \n     * as you don't know whether to use the U or UL suffix. Using only U you \n     * might only be allowed 16-bit constants. Using UL you might get 64-bit \n     * constants which cannot be stored in a UInt32 without warnings, and \n     * which generally behave subtly different from a true UInt32. \n     * As long as we're just comparing with the constant,  \n     * we can always use the UL suffix and at worst lose some efficiency.  \n     * I use a separate '32-bit constant' macro in most of my other code. \n     * \n     * I hate C. \n     * \n     * Start with testing GET32. We test it on all positions modulo 4  \n     * to make sure we can handly any position of inputs. (Some CPUs \n     * do not allow non-aligned accesses which we would do if you used \n     * the CONVERT_USING_CASTS option. \n     */ \n    if( (GET32( buf ) != 0x78563412UL) || (GET32(buf+1) != 0x9a785634UL)  \n        || (GET32( buf+2 ) != 0xbc9a7856UL) || (GET32(buf+3) != 0xdebc9a78UL) ) \n        { \n\t  Twofish_fatal( \"Twofish code: GET32 not implemented properly\", ERR_GET32 ); \n        } \n \n    /*  \n     * We can now use GET32 to test PUT32. \n     * We don't test the shifted versions. If GET32 can do that then \n     * so should PUT32. \n     */ \n    C = GET32( buf ); \n    PUT32( 3*C, buf ); \n    if( GET32( buf ) != 0x69029c36UL ) \n        { \n\t  Twofish_fatal( \"Twofish code: PUT32 not implemented properly\", ERR_PUT32 ); \n        } \n \n \n    /* Test ROL and ROR */ \n    for( i=1; i<32; i++ )  \n        { \n        /* Just a simple test. */ \n        x = ROR32( C, i ); \n        y = ROL32( C, i ); \n        x ^= (C>>i) ^ (C<<(32-i)); \n        /*y ^= (C<>(32-i));  */\n        y ^= (C<<i) ^ (C>>(32-i));\n        x |= y; \n        /*  \n         * Now all we check is that x is zero in the least significant \n         * 32 bits. Using the UL suffix is safe here, as it doesn't matter \n         * if we get a larger type. \n         */ \n\tif( (x & 0xffffffffUL) != 0 ) \n            { \n\t      Twofish_fatal( \"Twofish ROL or ROR not properly defined.\", ERR_ROLR ); \n            } \n        } \n \n    /* Test the BSWAP macro */ \n    if( BSWAP(C) != 0x12345678UL ) \n        { \n        /* \n         * The BSWAP macro should always work, even if you are not using it. \n         * A smart optimising compiler will just remove this entire test. \n         */ \n\t  Twofish_fatal( \"BSWAP not properly defined.\", ERR_BSWAP ); \n        } \n \n    /* And we can test the b macros which use SELECT_BYTE. */ \n    if( (b0(C)!=0x12) || (b1(C) != 0x34) || (b2(C) != 0x56) || (b3(C) != 0x78) ) \n        { \n        /* \n         * There are many reasons why this could fail. \n         * Most likely is that CPU_IS_BIG_ENDIAN has the wrong value.  \n         */ \n\t  Twofish_fatal( \"Twofish code: SELECT_BYTE not implemented properly\", ERR_SELECTB ); \n        }\n    return SUCCESS;\n    } \n \n \n/* \n * Finally, we can start on the Twofish-related code. \n * You really need the Twofish specifications to understand this code. The \n * best source is the Twofish book: \n *     \"The Twofish Encryption Algorithm\", by Bruce Schneier, John Kelsey, \n *     Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson. \n * you can also use the AES submission document of Twofish, which is  \n * available from my list of publications on my personal web site at  \n *    http://niels.ferguson.net/. \n * \n * The first thing we do is write the testing routines. This is what the  \n * implementation has to satisfy in the end. We only test the external \n * behaviour of the implementation of course. \n */ \n \n \n/* \n * Perform a single self test on a (plaintext,ciphertext,key) triple. \n * Arguments: \n *  key     array of key bytes \n *  key_len length of key in bytes \n *  p       plaintext \n *  c       ciphertext \n */ \nstatic int test_vector( Twofish_Byte key[], int key_len, Twofish_Byte p[16], Twofish_Byte c[16] ) \n    { \n    Twofish_Byte tmp[16];               /* scratch pad. */ \n    Twofish_key xkey;           /* The expanded key */ \n    int i; \n \n \n    /* Prepare the key */ \n    if ((i = Twofish_prepare_key( key, key_len, &xkey)) < 0)\n\treturn i; \n \n    /*  \n     * We run the test twice to ensure that the xkey structure \n     * is not damaged by the first encryption.  \n     * Those are hideous bugs to find if you get them in an application. \n     */ \n    for( i=0; i<2; i++ )  \n        { \n        /* Encrypt and test */ \n        Twofish_encrypt( &xkey, p, tmp ); \n        if( memcmp( c, tmp, 16 ) != 0 )  \n            { \n\t      Twofish_fatal( \"Twofish encryption failure\", ERR_TEST_ENC ); \n            } \n \n        /* Decrypt and test */ \n        Twofish_decrypt( &xkey, c, tmp ); \n        if( memcmp( p, tmp, 16 ) != 0 )  \n            { \n\t      Twofish_fatal( \"Twofish decryption failure\", ERR_TEST_DEC ); \n            } \n        } \n \n    /* The test keys are not secret, so we don't need to wipe xkey. */\n    return SUCCESS;\n    }\n \n \n/* \n * Check implementation using three (key,plaintext,ciphertext) \n * test vectors, one for each major key length. \n *  \n * This is an absolutely minimal self-test.  \n * This routine does not test odd-sized keys. \n */ \nstatic int test_vectors() \n    { \n    /* \n     * We run three tests, one for each major key length. \n     * These test vectors come from the Twofish specification. \n     * One encryption and one decryption using randomish data and key \n     * will detect almost any error, especially since we generate the \n     * tables ourselves, so we don't have the problem of a single \n     * damaged table entry in the source. \n     */ \n \n    /* 128-bit test is the I=3 case of section B.2 of the Twofish book. */ \n    static Twofish_Byte k128[] = { \n        0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,  \n        0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A, \n        }; \n    static Twofish_Byte p128[] = { \n        0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,  \n        0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 \n        }; \n    static Twofish_Byte c128[] = { \n        0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,  \n        0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 \n        }; \n \n    /* 192-bit test is the I=4 case of section B.2 of the Twofish book. */ \n    static Twofish_Byte k192[] = { \n        0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36,  \n        0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88,  \n        0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 \n        }; \n    static Twofish_Byte p192[] = { \n        0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, \n        0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 \n        }; \n    static Twofish_Byte c192[] = { \n        0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, \n        0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 \n        }; \n \n    /* 256-bit test is the I=4 case of section B.2 of the Twofish book. */ \n    static Twofish_Byte k256[] = { \n        0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,  \n        0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, \n        0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, \n        0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F \n        }; \n    static Twofish_Byte p256[] = { \n        0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, \n        0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 \n        }; \n    static Twofish_Byte c256[] = { \n        0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, \n        0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA \n        }; \n\n    int ret;\n\n    /* Run the actual tests. */ \n    if ((ret = test_vector( k128, 16, p128, c128 )) < 0)\n      return ret; \n    if ((ret = test_vector( k192, 24, p192, c192 )) < 0)\n      return ret; \n    if ((ret = test_vector( k256, 32, p256, c256 )) < 0)\n      return ret;\n    return SUCCESS;\n    }    \n \n \n/* \n * Perform extensive test for a single key size. \n *  \n * Test a single key size against the test vectors from section \n * B.2 in the Twofish book. This is a sequence of 49 encryptions \n * and decryptions. Each plaintext is equal to the ciphertext of \n * the previous encryption. The key is made up from the ciphertext \n * two and three encryptions ago. Both plaintext and key start \n * at the zero value.  \n * We should have designed a cleaner recurrence relation for \n * these tests, but it is too late for that now. At least we learned \n * how to do it better next time. \n * For details see appendix B of the book. \n * \n * Arguments: \n * key_len      Number of bytes of key \n * final_value  Final plaintext value after 49 iterations \n */ \nstatic int test_sequence( int key_len, Twofish_Byte final_value[] ) \n    { \n    Twofish_Byte buf[ (50+3)*16 ];      /* Buffer to hold our computation values. */ \n    Twofish_Byte tmp[16];               /* Temp for testing the decryption. */ \n    Twofish_key xkey;           /* The expanded key */ \n    int i, ret;\n    Twofish_Byte * p; \n \n    /* Wipe the buffer */ \n    memset( buf, 0, sizeof( buf ) ); \n \n    /* \n     * Because the recurrence relation is done in an inconvenient manner \n     * we end up looping backwards over the buffer. \n     */ \n \n    /* Pointer in buffer points to current plaintext. */ \n    p = &buf[50*16]; \n    for( i=1; i<50; i++ ) \n        { \n        /*  \n         * Prepare a key. \n         * This automatically checks that key_len is valid. \n         */ \n\t  if ((ret = Twofish_prepare_key( p+16, key_len, &xkey)) < 0)\n\t    return ret; \n \n        /* Compute the next 16 bytes in the buffer */ \n        Twofish_encrypt( &xkey, p, p-16 ); \n \n        /* Check that the decryption is correct. */ \n        Twofish_decrypt( &xkey, p-16, tmp ); \n        if( memcmp( tmp, p, 16 ) != 0 ) \n            { \n\t      Twofish_fatal( \"Twofish decryption failure in sequence\", ERR_SEQ_DEC ); \n            } \n        /* Move on to next 16 bytes in the buffer. */ \n        p -= 16; \n        } \n \n    /* And check the final value. */ \n    if( memcmp( p, final_value, 16 ) != 0 )  \n        { \n\t  Twofish_fatal( \"Twofish encryption failure in sequence\", ERR_SEQ_ENC ); \n        } \n \n    /* None of the data was secret, so there is no need to wipe anything. */\n    return SUCCESS;\n    } \n \n \n/*  \n * Run all three sequence tests from the Twofish test vectors.  \n * \n * This checks the most extensive test vectors currently available  \n * for Twofish. The data is from the Twofish book, appendix B.2. \n */ \nstatic int test_sequences() \n    { \n    static Twofish_Byte r128[] = { \n        0x5D, 0x9D, 0x4E, 0xEF, 0xFA, 0x91, 0x51, 0x57, \n        0x55, 0x24, 0xF1, 0x15, 0x81, 0x5A, 0x12, 0xE0 \n        }; \n    static Twofish_Byte r192[] = { \n        0xE7, 0x54, 0x49, 0x21, 0x2B, 0xEE, 0xF9, 0xF4, \n        0xA3, 0x90, 0xBD, 0x86, 0x0A, 0x64, 0x09, 0x41 \n        }; \n    static Twofish_Byte r256[] = { \n        0x37, 0xFE, 0x26, 0xFF, 0x1C, 0xF6, 0x61, 0x75, \n        0xF5, 0xDD, 0xF4, 0xC3, 0x3B, 0x97, 0xA2, 0x05 \n        }; \n \n    /* Run the three sequence test vectors */\n    int ret;\n    if ((ret = test_sequence( 16, r128)) < 0)\n      return ret; \n    if ((ret = test_sequence( 24, r192)) < 0)\n      return ret; \n    if ((ret = test_sequence( 32, r256)) < 0)\n      return ret;\n    return SUCCESS;\n    } \n \n \n/* \n * Test the odd-sized keys. \n * \n * Every odd-sized key is equivalent to a one of 128, 192, or 256 bits. \n * The equivalent key is found by padding at the end with zero bytes \n * until a regular key size is reached. \n * \n * We just test that the key expansion routine behaves properly. \n * If the expanded keys are identical, then the encryptions and decryptions \n * will behave the same. \n */ \nstatic int test_odd_sized_keys() \n    { \n    Twofish_Byte buf[32]; \n    Twofish_key xkey; \n    Twofish_key xkey_two; \n    int i, ret;\n \n    /*  \n     * We first create an all-zero key to use as PRNG key.  \n     * Normally we would not have to fill the buffer with zeroes, as we could \n     * just pass a zero key length to the Twofish_prepare_key function. \n     * However, this relies on using odd-sized keys, and those are just the \n     * ones we are testing here. We can't use an untested function to test  \n     * itself.  \n     */ \n    memset( buf, 0, sizeof( buf ) ); \n    if ((ret = Twofish_prepare_key( buf, 16, &xkey)) < 0)\n      return ret; \n \n    /* Fill buffer with pseudo-random data derived from two encryptions */ \n    Twofish_encrypt( &xkey, buf, buf ); \n    Twofish_encrypt( &xkey, buf, buf+16 ); \n \n    /* Create all possible shorter keys that are prefixes of the buffer. */ \n    for( i=31; i>=0; i-- ) \n        { \n        /* Set a byte to zero. This is the new padding byte */ \n        buf[i] = 0; \n \n        /* Expand the key with only i bytes of length */ \n        if ((ret = Twofish_prepare_key( buf, i, &xkey)) < 0)\n\t  return ret; \n \n        /* Expand the corresponding padded key of regular length */ \n        if ((ret = Twofish_prepare_key( buf, i<=16 ? 16 : (i<= 24 ? 24 : 32), &xkey_two )) < 0)\n\t  return ret; \n \n        /* Compare the two */ \n        if( memcmp( &xkey, &xkey_two, sizeof( xkey ) ) != 0 ) \n            { \n\t      Twofish_fatal( \"Odd sized keys do not expand properly\", ERR_ODD_KEY ); \n            } \n        } \n \n    /* None of the key values are secret, so we don't need to wipe them. */\n    return SUCCESS;\n    } \n \n \n/* \n * Test the Twofish implementation. \n * \n * This routine runs all the self tests, in order of importance. \n * It is called by the Twofish_initialise routine. \n *  \n * In almost all applications the cost of running the self tests during \n * initialisation is insignificant, especially \n * compared to the time it takes to load the application from disk.  \n * If you are very pressed for initialisation performance,  \n * you could remove some of the tests. Make sure you did run them \n * once in the software and hardware configuration you are using. \n */ \nstatic int self_test() \n    {\n      int ret;\n    /* The three test vectors form an absolute minimal test set. */ \n      if ((ret = test_vectors()) < 0)\n\treturn ret;\n \n    /*  \n     * If at all possible you should run these tests too. They take \n     * more time, but provide a more thorough coverage. \n     */ \n      if ((ret = test_sequences()) < 0)\n\treturn ret;\n \n    /* Test the odd-sized keys. */ \n      if ((ret = test_odd_sized_keys()) < 0)\n\treturn ret;\n      return SUCCESS;\n    } \n \n \n/* \n * And now, the actual Twofish implementation. \n * \n * This implementation generates all the tables during initialisation.  \n * I don't like large tables in the code, especially since they are easily  \n * damaged in the source without anyone noticing it. You need code to  \n * generate them anyway, and this way all the code is close together. \n * Generating them in the application leads to a smaller executable  \n * (the code is smaller than the tables it generates) and a  \n * larger static memory footprint. \n * \n * Twofish can be implemented in many ways. I have chosen to  \n * use large tables with a relatively long key setup time. \n * If you encrypt more than a few blocks of data it pays to pre-compute  \n * as much as possible. This implementation is relatively inefficient for  \n * applications that need to re-key every block or so. \n */ \n \n/*  \n * We start with the t-tables, directly from the Twofish definition.  \n * These are nibble-tables, but merging them and putting them two nibbles  \n * in one byte is more work than it is worth. \n */ \nstatic Twofish_Byte t_table[2][4][16] = { \n    { \n        {0x8,0x1,0x7,0xD,0x6,0xF,0x3,0x2,0x0,0xB,0x5,0x9,0xE,0xC,0xA,0x4}, \n        {0xE,0xC,0xB,0x8,0x1,0x2,0x3,0x5,0xF,0x4,0xA,0x6,0x7,0x0,0x9,0xD}, \n        {0xB,0xA,0x5,0xE,0x6,0xD,0x9,0x0,0xC,0x8,0xF,0x3,0x2,0x4,0x7,0x1}, \n        {0xD,0x7,0xF,0x4,0x1,0x2,0x6,0xE,0x9,0xB,0x3,0x0,0x8,0x5,0xC,0xA} \n    }, \n    { \n        {0x2,0x8,0xB,0xD,0xF,0x7,0x6,0xE,0x3,0x1,0x9,0x4,0x0,0xA,0xC,0x5}, \n        {0x1,0xE,0x2,0xB,0x4,0xC,0x3,0x7,0x6,0xD,0xA,0x5,0xF,0x9,0x0,0x8}, \n        {0x4,0xC,0x7,0x5,0x1,0x6,0x9,0xA,0x0,0xE,0xD,0x8,0x2,0xB,0x3,0xF}, \n        {0xB,0x9,0x5,0x1,0xC,0x3,0xD,0xE,0x6,0x4,0x7,0xF,0x2,0x0,0x8,0xA} \n    } \n}; \n \n \n/* A 1-bit rotation of 4-bit values. Input must be in range 0..15 */ \n#define ROR4BY1( x ) (((x)>>1) | (((x)<<3) & 0x8) ) \n \n/* \n * The q-boxes are only used during the key schedule computations.  \n * These are 8->8 bit lookup tables. Some CPUs prefer to have 8->32 bit  \n * lookup tables as it is faster to load a 32-bit value than to load an  \n * 8-bit value and zero the rest of the register. \n * The LARGE_Q_TABLE switch allows you to choose 32-bit entries in  \n * the q-tables. Here we just define the Qtype which is used to store  \n * the entries of the q-tables. \n */ \n#if LARGE_Q_TABLE \ntypedef Twofish_UInt32      Qtype; \n#else \ntypedef Twofish_Byte        Qtype; \n#endif \n \n/*  \n * The actual q-box tables.  \n * There are two q-boxes, each having 256 entries. \n */ \nstatic Qtype q_table[2][256]; \n \n \n/* \n * Now the function that converts a single t-table into a q-table. \n * \n * Arguments: \n * t[4][16] : four 4->4bit lookup tables that define the q-box \n * q[256]   : output parameter: the resulting q-box as a lookup table. \n */ \nstatic void make_q_table( Twofish_Byte t[4][16], Qtype q[256] ) \n    { \n    int ae,be,ao,bo;        /* Some temporaries. */ \n    int i; \n    /* Loop over all input values and compute the q-box result. */ \n    for( i=0; i<256; i++ ) { \n        /*  \n         * This is straight from the Twofish specifications.  \n         *  \n         * The ae variable is used for the a_i values from the specs \n         * with even i, and ao for the odd i's. Similarly for the b's. \n         */ \n        ae = i>>4; be = i&0xf; \n        ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8); \n        ae = t[0][ao]; be = t[1][bo]; \n        ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8); \n        ae = t[2][ao]; be = t[3][bo]; \n \n        /* Store the result in the q-box table, the cast avoids a warning. */ \n        q[i] = (Qtype) ((be<<4) | ae); \n        } \n    } \n \n \n/*  \n * Initialise both q-box tables.  \n */ \nstatic void initialise_q_boxes() { \n    /* Initialise each of the q-boxes using the t-tables */ \n    make_q_table( t_table[0], q_table[0] ); \n    make_q_table( t_table[1], q_table[1] ); \n    } \n \n \n/* \n * Next up is the MDS matrix multiplication. \n * The MDS matrix multiplication operates in the field \n * GF(2)[x]/p(x) with p(x)=x^8+x^6+x^5+x^3+1. \n * If you don't understand this, read a book on finite fields. You cannot \n * follow the finite-field computations without some background. \n *  \n * In this field, multiplication by x is easy: shift left one bit  \n * and if bit 8 is set then xor the result with 0x169.  \n * \n * The MDS coefficients use a multiplication by 1/x, \n * or rather a division by x. This is easy too: first make the \n * value 'even' (i.e. bit 0 is zero) by xorring with 0x169 if necessary,  \n * and then shift right one position.  \n * Even easier: shift right and xor with 0xb4 if the lsbit was set. \n * \n * The MDS coefficients are 1, EF, and 5B, and we use the fact that \n *   EF = 1 + 1/x + 1/x^2 \n *   5B = 1       + 1/x^2 \n * in this field. This makes multiplication by EF and 5B relatively easy. \n * \n * This property is no accident, the MDS matrix was designed to allow \n * this implementation technique to be used. \n * \n * We have four MDS tables, each mapping 8 bits to 32 bits. \n * Each table performs one column of the matrix multiplication.  \n * As the MDS is always preceded by q-boxes, each of these tables \n * also implements the q-box just previous to that column. \n */ \n \n/* The actual MDS tables. */ \nstatic Twofish_UInt32 MDS_table[4][256]; \n \n/* A small table to get easy conditional access to the 0xb4 constant. */ \nstatic Twofish_UInt32 mds_poly_divx_const[] = {0,0xb4}; \n \n/* Function to initialise the MDS tables. */ \nstatic void initialise_mds_tables() \n    { \n    int i; \n    Twofish_UInt32 q,qef,q5b;       /* Temporary variables. */ \n \n    /* Loop over all 8-bit input values */ \n    for( i=0; i<256; i++ )  \n        { \n        /*  \n         * To save some work during the key expansion we include the last \n         * of the q-box layers from the h() function in these MDS tables. \n         */ \n \n        /* We first do the inputs that are mapped through the q0 table. */ \n        q = q_table[0][i]; \n        /* \n         * Here we divide by x, note the table to get 0xb4 only if the  \n         * lsbit is set.  \n         * This sets qef = (1/x)*q in the finite field \n         */ \n        qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ]; \n        /* \n         * Divide by x again, and add q to get (1+1/x^2)*q.  \n         * Note that (1+1/x^2) =  5B in the field, and addition in the field \n         * is exclusive or on the bits. \n         */ \n        q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q; \n        /*  \n         * Add q5b to qef to set qef = (1+1/x+1/x^2)*q. \n         * Again, (1+1/x+1/x^2) = EF in the field. \n         */ \n        qef ^= q5b; \n \n        /*  \n         * Now that we have q5b = 5B * q and qef = EF * q  \n         * we can fill two of the entries in the MDS matrix table.  \n         * See the Twofish specifications for the order of the constants. \n         */ \n        MDS_table[1][i] = (q  <<24) | (q5b<<16) | (qef<<8) | qef; \n        MDS_table[3][i] = (q5b<<24) | (qef<<16) | (q  <<8) | q5b; \n \n        /* Now we do it all again for the two columns that have a q1 box. */ \n        q = q_table[1][i]; \n        qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ]; \n        q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q; \n        qef ^= q5b; \n \n        /* The other two columns use the coefficient in a different order. */ \n        MDS_table[0][i] = (qef<<24) | (qef<<16) | (q5b<<8) | q  ; \n        MDS_table[2][i] = (qef<<24) | (q  <<16) | (qef<<8) | q5b; \n        } \n    } \n \n \n/* \n * The h() function is the heart of the Twofish cipher.  \n * It is a complicated sequence of q-box lookups, key material xors,  \n * and finally the MDS matrix. \n * We use lots of macros to make this reasonably fast. \n */ \n \n/* First a shorthand for the two q-tables */ \n#define q0  q_table[0] \n#define q1  q_table[1] \n \n/* \n * Each macro computes one column of the h for either 2, 3, or 4 stages. \n * As there are 4 columns, we have 12 macros in all. \n *  \n * The key bytes are stored in the Byte array L at offset  \n * 0,1,2,3,  8,9,10,11,  [16,17,18,19,   [24,25,26,27]] as this is the \n * order we get the bytes from the user. If you look at the Twofish  \n * specs, you'll see that h() is applied to the even key words or the \n * odd key words. The bytes of the even words appear in this spacing, \n * and those of the odd key words too. \n * \n * These macros are the only place where the q-boxes and the MDS table \n * are used. \n */ \n#define H02( y, L )  MDS_table[0][q0[q0[y]^L[ 8]]^L[0]] \n#define H12( y, L )  MDS_table[1][q0[q1[y]^L[ 9]]^L[1]] \n#define H22( y, L )  MDS_table[2][q1[q0[y]^L[10]]^L[2]] \n#define H32( y, L )  MDS_table[3][q1[q1[y]^L[11]]^L[3]] \n#define H03( y, L )  H02( q1[y]^L[16], L ) \n#define H13( y, L )  H12( q1[y]^L[17], L ) \n#define H23( y, L )  H22( q0[y]^L[18], L ) \n#define H33( y, L )  H32( q0[y]^L[19], L ) \n#define H04( y, L )  H03( q1[y]^L[24], L ) \n#define H14( y, L )  H13( q0[y]^L[25], L ) \n#define H24( y, L )  H23( q0[y]^L[26], L ) \n#define H34( y, L )  H33( q1[y]^L[27], L ) \n \n/* \n * Now we can define the h() function given an array of key bytes.  \n * This function is only used in the key schedule, and not to pre-compute \n * the keyed S-boxes. \n * \n * In the key schedule, the input is always of the form k*(1+2^8+2^16+2^24) \n * so we only provide k as an argument. \n * \n * Arguments: \n * k        input to the h() function. \n * L        pointer to array of key bytes at  \n *          offsets 0,1,2,3, ... 8,9,10,11, [16,17,18,19, [24,25,26,27]] \n * kCycles  # key cycles, 2, 3, or 4. \n */ \nstatic Twofish_UInt32 h( int k, Twofish_Byte L[], int kCycles ) \n    { \n    switch( kCycles ) { \n        /* We code all 3 cases separately for speed reasons. */ \n    case 2: \n        return H02(k,L) ^ H12(k,L) ^ H22(k,L) ^ H32(k,L); \n    case 3: \n        return H03(k,L) ^ H13(k,L) ^ H23(k,L) ^ H33(k,L); \n    case 4: \n        return H04(k,L) ^ H14(k,L) ^ H24(k,L) ^ H34(k,L); \n    default:  \n        /* This is always a coding error, which is fatal. */ \n      Twofish_fatal( \"Twofish h(): Illegal argument\", ERR_ILL_ARG ); \n      return ERR_ILL_ARG;\n        } \n    } \n \n \n/* \n * Pre-compute the keyed S-boxes. \n * Fill the pre-computed S-box array in the expanded key structure. \n * Each pre-computed S-box maps 8 bits to 32 bits. \n * \n * The S argument contains half the number of bytes of the full key, but is \n * derived from the full key. (See Twofish specifications for details.) \n * S has the weird byte input order used by the Hxx macros. \n * \n * This function takes most of the time of a key expansion. \n * \n * Arguments: \n * S        pointer to array of 8*kCycles Bytes containing the S vector. \n * kCycles  number of key words, must be in the set {2,3,4} \n * xkey     pointer to Twofish_key structure that will contain the S-boxes. \n */ \nstatic int fill_keyed_sboxes( Twofish_Byte S[], int kCycles, Twofish_key * xkey ) \n    { \n    int i; \n    switch( kCycles ) { \n        /* We code all 3 cases separately for speed reasons. */ \n    case 2: \n        for( i=0; i<256; i++ ) \n            { \n            xkey->s[0][i]= H02( i, S ); \n            xkey->s[1][i]= H12( i, S ); \n            xkey->s[2][i]= H22( i, S ); \n            xkey->s[3][i]= H32( i, S ); \n            } \n        break; \n    case 3: \n        for( i=0; i<256; i++ ) \n            { \n            xkey->s[0][i]= H03( i, S ); \n            xkey->s[1][i]= H13( i, S ); \n            xkey->s[2][i]= H23( i, S ); \n            xkey->s[3][i]= H33( i, S ); \n            } \n        break; \n    case 4: \n        for( i=0; i<256; i++ ) \n            { \n            xkey->s[0][i]= H04( i, S ); \n            xkey->s[1][i]= H14( i, S ); \n            xkey->s[2][i]= H24( i, S ); \n            xkey->s[3][i]= H34( i, S ); \n            } \n        break; \n    default:  \n        /* This is always a coding error, which is fatal. */ \n      Twofish_fatal( \"Twofish fill_keyed_sboxes(): Illegal argument\", ERR_ILL_ARG ); \n        }\n    return SUCCESS;\n    }\n \n \n/* A flag to keep track of whether we have been initialised or not. */ \nstatic int Twofish_initialised = 0; \n \n/* \n * Initialise the Twofish implementation. \n * This function must be called before any other function in the \n * Twofish implementation is called. \n * This routine also does some sanity checks, to make sure that \n * all the macros behave, and it tests the whole cipher. \n */ \nint Twofish_initialise() \n    {\n      int ret;\n    /* First test the various platform-specific definitions. */ \n      if ((ret = test_platform()) < 0)\n\treturn ret;\n \n    /* We can now generate our tables, in the right order of course. */ \n    initialise_q_boxes(); \n    initialise_mds_tables(); \n \n    /* We're finished with the initialisation itself. */ \n    Twofish_initialised = 1; \n \n    /*  \n     * And run some tests on the whole cipher.  \n     * Yes, you need to do this every time you start your program.  \n     * It is called assurance; you have to be certain that your program \n     * still works properly.  \n     */ \n    return self_test(); \n    } \n \n \n/* \n * The Twofish key schedule uses an Reed-Solomon code matrix multiply. \n * Just like the MDS matrix, the RS-matrix is designed to be easy \n * to implement. Details are below in the code.  \n * \n * These constants make it easy to compute in the finite field used  \n * for the RS code. \n * \n * We use Bytes for the RS computation, but these are automatically \n * widened to unsigned integers in the expressions. Having unsigned \n * ints in these tables therefore provides the fastest access. \n */ \nstatic unsigned int rs_poly_const[] = {0, 0x14d}; \nstatic unsigned int rs_poly_div_const[] = {0, 0xa6 }; \n \n/*\n * memset_volatile is a volatile pointer to the memset function.\n * You can call (*memset_volatile)(buf, val, len) or even\n * memset_volatile(buf, val, len) just as you would call\n * memset(buf, val, len), but the use of a volatile pointer\n * guarantees that the compiler will not optimise the call away.\n */\nstatic void * (*volatile memset_volatile)(void *, int, size_t) = memset;\n\n/* \n * Prepare a key for use in encryption and decryption. \n * Like most block ciphers, Twofish allows the key schedule  \n * to be pre-computed given only the key.  \n * Twofish has a fairly 'heavy' key schedule that takes a lot of time  \n * to compute. The main work is pre-computing the S-boxes used in the  \n * encryption and decryption. We feel that this makes the cipher much  \n * harder to attack. The attacker doesn't even know what the S-boxes  \n * contain without including the entire key schedule in the analysis.  \n * \n * Unlike most Twofish implementations, this one allows any key size from \n * 0 to 32 bytes. Odd key sizes are defined for Twofish (see the  \n * specifications); the key is simply padded with zeroes to the next real  \n * key size of 16, 24, or 32 bytes. \n * Each odd-sized key is thus equivalent to a single normal-sized key. \n * \n * Arguments: \n * key      array of key bytes \n * key_len  number of bytes in the key, must be in the range 0,...,32. \n * xkey     Pointer to an Twofish_key structure that will be filled  \n *             with the internal form of the cipher key. \n */ \nint Twofish_prepare_key( Twofish_Byte key[], int key_len, Twofish_key * xkey ) \n    { \n    /* We use a single array to store all key material in,  \n     * to simplify the wiping of the key material at the end. \n     * The first 32 bytes contain the actual (padded) cipher key. \n     * The next 32 bytes contain the S-vector in its weird format, \n     * and we have 4 bytes of overrun necessary for the RS-reduction. \n     */ \n    Twofish_Byte K[32+32+4];  \n \n    int kCycles;        /* # key cycles, 2,3, or 4. */ \n \n    int i; \n    Twofish_UInt32 A, B;        /* Used to compute the round keys. */ \n \n    Twofish_Byte * kptr;        /* Three pointers for the RS computation. */ \n    Twofish_Byte * sptr; \n    Twofish_Byte * t; \n \n    Twofish_Byte b,bx,bxx;      /* Some more temporaries for the RS computation. */ \n \n    /* Check that the Twofish implementation was initialised. */ \n    if( Twofish_initialised == 0 ) \n        { \n        /*  \n         * You didn't call Twofish_initialise before calling this routine. \n         * This is a programming error, and therefore we call the fatal \n         * routine.  \n         * \n         * I could of course call the initialisation routine here, \n         * but there are a few reasons why I don't. First of all, the  \n         * self-tests have to be done at startup. It is no good to inform \n         * the user that the cipher implementation fails when he wants to \n         * write his data to disk in encrypted form. You have to warn him \n         * before he spends time typing his data. Second, the initialisation \n         * and self test are much slower than a single key expansion. \n         * Calling the initialisation here makes the performance of the \n         * cipher unpredictable. This can lead to really weird problems  \n         * if you use the cipher for a real-time task. Suddenly it fails  \n         * once in a while the first time you try to use it. Things like  \n         * that are almost impossible to debug. \n         */ \n\t  /* Twofish_fatal( \"Twofish implementation was not initialised.\", ERR_INIT ); */\n         \n        /* \n         * There is always a danger that the Twofish_fatal routine returns, \n         * in spite of the specifications that it should not.  \n         * (A good programming rule: don't trust the rest of the code.) \n         * This would be disasterous. If the q-tables and MDS-tables have \n         * not been initialised, they are probably still filled with zeroes. \n         * Suppose the MDS-tables are all zero. The key expansion would then \n         * generate all-zero round keys, and all-zero s-boxes. The danger \n         * is that nobody would notice as the encry\n         * mangles the input, and the decryption still 'decrypts' it, \n         * but now in a completely key-independent manner.  \n         * To stop such security disasters, we use blunt force. \n         * If your program hangs here: fix the fatal routine! \n         */ \n        for(;;);        /* Infinite loop, which beats being insecure. */ \n        } \n \n    /* Check for valid key length. */ \n    if( key_len < 0 || key_len > 32 ) \n        { \n        /*  \n         * This can only happen if a programmer didn't read the limitations \n         * on the key size.  \n         */ \n\t  Twofish_fatal( \"Twofish_prepare_key: illegal key length\", ERR_KEY_LEN ); \n        /*  \n         * A return statement just in case the fatal macro returns. \n         * The rest of the code assumes that key_len is in range, and would \n         * buffer-overflow if it wasn't.  \n         * \n         * Why do we still use a programming language that has problems like \n         * buffer overflows, when these problems were solved in 1960 with \n         * the development of Algol? Have we not leared anything? \n         */ \n        return ERR_KEY_LEN; \n        } \n \n    /* Pad the key with zeroes to the next suitable key length. */ \n    memcpy( K, key, key_len ); \n    memset( K+key_len, 0, sizeof(K)-key_len ); \n \n    /*  \n     * Compute kCycles: the number of key cycles used in the cipher.  \n     * 2 for 128-bit keys, 3 for 192-bit keys, and 4 for 256-bit keys. \n     */ \n    kCycles = (key_len + 7) >> 3; \n    /* Handle the special case of very short keys: minimum 2 cycles. */ \n    if( kCycles < 2 ) \n        { \n        kCycles = 2; \n        } \n \n    /*  \n     * From now on we just pretend to have 8*kCycles bytes of  \n     * key material in K. This handles all the key size cases.  \n     */ \n \n    /*  \n     * We first compute the 40 expanded key words,  \n     * formulas straight from the Twofish specifications. \n     */ \n    for( i=0; i<40; i+=2 ) \n        { \n        /*  \n         * Due to the byte spacing expected by the h() function  \n         * we can pick the bytes directly from the key K. \n         * As we use bytes, we never have the little/big endian \n         * problem. \n         * \n         * Note that we apply the rotation function only to simple \n         * variables, as the rotation macro might evaluate its argument \n         * more than once. \n         */ \n        A = h( i  , K  , kCycles ); \n        B = h( i+1, K+4, kCycles ); \n        B = ROL32( B, 8 ); \n \n        /* Compute and store the round keys. */ \n        A += B; \n        B += A; \n        xkey->K[i]   = A; \n        xkey->K[i+1] = ROL32( B, 9 ); \n        } \n \n    /* Wipe variables that contained key material. */ \n    A=B=0; \n \n    /*  \n     * And now the dreaded RS multiplication that few seem to understand. \n     * The RS matrix is not random, and is specially designed to compute the \n     * RS matrix multiplication in a simple way. \n     * \n     * We work in the field GF(2)[x]/x^8+x^6+x^3+x^2+1. Note that this is a \n     * different field than used for the MDS matrix.  \n     * (At least, it is a different representation because all GF(2^8)  \n     * representations are equivalent in some form.) \n     *  \n     * We take 8 consecutive bytes of the key and interpret them as  \n     * a polynomial k_0 + k_1 y + k_2 y^2 + ... + k_7 y^7 where  \n     * the k_i bytes are the key bytes and are elements of the finite field. \n     * We multiply this polynomial by y^4 and reduce it modulo \n     *     y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1.  \n     * using straightforward polynomial modulo reduction. \n     * The coefficients of the result are the result of the RS \n     * matrix multiplication. When we wrote the Twofish specification,  \n     * the original RS definition used the polynomials,  \n     * but that requires much more mathematical knowledge.  \n     * We were already using matrix multiplication in a finite field for  \n     * the MDS matrix, so I re-wrote the RS operation as a matrix  \n     * multiplication to reduce the difficulty of understanding it.  \n     * Some implementors have not picked up on this simpler method of \n     * computing the RS operation, even though it is mentioned in the \n     * specifications. \n     * \n     * It is possible to perform these computations faster by using 32-bit  \n     * word operations, but that is not portable and this is not a speed- \n     * critical area. \n     * \n     * We explained the 1/x computation when we did the MDS matrix.  \n     * \n     * The S vector is stored in K[32..64]. \n     * The S vector has to be reversed, so we loop cross-wise. \n     * \n     * Note the weird byte spacing of the S-vector, to match the even  \n     * or odd key words arrays. See the discussion at the Hxx macros for \n     * details. \n     */ \n    kptr = K + 8*kCycles;           /* Start at end of key */ \n    sptr = K + 32;                  /* Start at start of S */ \n \n    /* Loop over all key material */ \n    while( kptr > K )  \n        { \n        kptr -= 8; \n        /*  \n         * Initialise the polynimial in sptr[0..12] \n         * The first four coefficients are 0 as we have to multiply by y^4. \n         * The next 8 coefficients are from the key material. \n         */ \n        memset( sptr, 0, 4 ); \n        memcpy( sptr+4, kptr, 8 ); \n \n        /*  \n         * The 12 bytes starting at sptr are now the coefficients of \n         * the polynomial we need to reduce. \n         */ \n \n        /* Loop over the polynomial coefficients from high to low */ \n        t = sptr+11; \n        /* Keep looping until polynomial is degree 3; */ \n        while( t > sptr+3 ) \n            { \n            /* Pick up the highest coefficient of the poly. */ \n            b = *t; \n \n            /*  \n             * Compute x and (x+1/x) times this coefficient.  \n             * See the MDS matrix implementation for a discussion of  \n             * multiplication by x and 1/x. We just use different  \n             * constants here as we are in a  \n             * different finite field representation. \n             * \n             * These two statements set  \n             * bx = (x) * b  \n             * bxx= (x + 1/x) * b \n             */ \n            bx = (Twofish_Byte)((b<<1) ^ rs_poly_const[ b>>7 ]); \n            bxx= (Twofish_Byte)((b>>1) ^ rs_poly_div_const[ b&1 ] ^ bx); \n \n            /* \n             * Subtract suitable multiple of  \n             * y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1  \n             * from the polynomial, except that we don't bother \n             * updating t[0] as it will become zero anyway. \n             */ \n            t[-1] ^= bxx; \n            t[-2] ^= bx; \n            t[-3] ^= bxx; \n            t[-4] ^= b; \n             \n            /* Go to the next coefficient. */ \n            t--; \n            } \n \n        /* Go to next S-vector word, obeying the weird spacing rules. */ \n        sptr += 8; \n        } \n \n    /* Wipe variables that contained key material. */ \n    b = bx = bxx = 0; \n \n    /* And finally, we can compute the key-dependent S-boxes. */ \n    fill_keyed_sboxes( &K[32], kCycles, xkey ); \n \n    /* Wipe array that contained key material. */ \n    (*memset_volatile)( K, 0, sizeof( K ) );\n    return SUCCESS;\n    } \n \n \n/* \n * We can now start on the actual encryption and decryption code. \n * As these are often speed-critical we will use a lot of macros. \n */ \n \n/* \n * The g() function is the heart of the round function. \n * We have two versions of the g() function, one without an input \n * rotation and one with. \n * The pre-computed S-boxes make this pretty simple. \n */ \n#define g0(X,xkey) \\\n (xkey->s[0][b0(X)]^xkey->s[1][b1(X)]^xkey->s[2][b2(X)]^xkey->s[3][b3(X)]) \n \n#define g1(X,xkey) \\\n (xkey->s[0][b3(X)]^xkey->s[1][b0(X)]^xkey->s[2][b1(X)]^xkey->s[3][b2(X)]) \n \n/* \n * A single round of Twofish. The A,B,C,D are the four state variables, \n * T0 and T1 are temporaries, xkey is the expanded key, and r the  \n * round number. \n * \n * Note that this macro does not implement the swap at the end of the round. \n */ \n#define ENCRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \\\n    T0 = g0(A,xkey); T1 = g1(B,xkey);\\\n    C ^= T0+T1+xkey->K[8+2*(r)]; C = ROR32(C,1);\\\n    D = ROL32(D,1); D ^= T0+2*T1+xkey->K[8+2*(r)+1] \n \n/* \n * Encrypt a single cycle, consisting of two rounds. \n * This avoids the swapping of the two halves.  \n * Parameter r is now the cycle number. \n */ \n#define ENCRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \\\n    ENCRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r)   );\\\n    ENCRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r)+1 )\n \n/* Full 16-round encryption */ \n#define ENCRYPT( A,B,C,D,T0,T1,xkey ) \\\n    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 );\\\n    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\\\n    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\\\n    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\\\n    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\\\n    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\\\n    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\\\n    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 )\n \n/* \n * A single round of Twofish for decryption. It differs from \n * ENCRYTP_RND only because of the 1-bit rotations. \n */ \n#define DECRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \\\n    T0 = g0(A,xkey); T1 = g1(B,xkey);\\\n    C = ROL32(C,1); C ^= T0+T1+xkey->K[8+2*(r)];\\\n    D ^= T0+2*T1+xkey->K[8+2*(r)+1]; D = ROR32(D,1)\n \n/* \n * Decrypt a single cycle, consisting of two rounds.  \n * This avoids the swapping of the two halves.  \n * Parameter r is now the cycle number. \n */ \n#define DECRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \\\n    DECRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r)+1 );\\\n    DECRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r)   )\n \n/* Full 16-round decryption. */ \n#define DECRYPT( A,B,C,D,T0,T1, xkey ) \\\n    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 );\\\n    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\\\n    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\\\n    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\\\n    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\\\n    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\\\n    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\\\n    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 ) \n\n/* \n * A macro to read the state from the plaintext and do the initial key xors. \n * The koff argument allows us to use the same macro  \n * for the decryption which uses different key words at the start. \n */ \n#define GET_INPUT( src, A,B,C,D, xkey, koff ) \\\n    A = GET32(src   )^xkey->K[  koff]; B = GET32(src+ 4)^xkey->K[1+koff]; \\\n    C = GET32(src+ 8)^xkey->K[2+koff]; D = GET32(src+12)^xkey->K[3+koff]\n \n/* \n * Similar macro to put the ciphertext in the output buffer. \n * We xor the keys into the state variables before we use the PUT32  \n * macro as the macro might use its argument multiple times. \n */ \n#define PUT_OUTPUT( A,B,C,D, dst, xkey, koff ) \\\n    A ^= xkey->K[  koff]; B ^= xkey->K[1+koff]; \\\n    C ^= xkey->K[2+koff]; D ^= xkey->K[3+koff]; \\\n    PUT32( A, dst   ); PUT32( B, dst+ 4 ); \\\n    PUT32( C, dst+8 ); PUT32( D, dst+12 )\n \n \n/* \n * Twofish block encryption \n * \n * Arguments: \n * xkey         expanded key array \n * p            16 bytes of plaintext \n * c            16 bytes in which to store the ciphertext \n */ \nvoid Twofish_encrypt( Twofish_key * xkey, Twofish_Byte p[16], Twofish_Byte c[16]) \n    { \n    Twofish_UInt32 A,B,C,D,T0,T1;       /* Working variables */ \n \n    /* Get the four plaintext words xorred with the key */ \n    GET_INPUT( p, A,B,C,D, xkey, 0 ); \n \n    /* Do 8 cycles (= 16 rounds) */ \n    ENCRYPT( A,B,C,D,T0,T1,xkey ); \n \n    /* Store them with the final swap and the output whitening. */ \n    PUT_OUTPUT( C,D,A,B, c, xkey, 4 ); \n    } \n \n \n/* \n * Twofish block decryption. \n * \n * Arguments: \n * xkey         expanded key array \n * p            16 bytes of plaintext \n * c            16 bytes in which to store the ciphertext \n */ \nvoid Twofish_decrypt( Twofish_key * xkey, Twofish_Byte c[16], Twofish_Byte p[16]) \n    { \n    Twofish_UInt32 A,B,C,D,T0,T1;       /* Working variables */ \n \n    /* Get the four plaintext words xorred with the key */ \n    GET_INPUT( c, A,B,C,D, xkey, 4 ); \n \n    /* Do 8 cycles (= 16 rounds) */ \n    DECRYPT( A,B,C,D,T0,T1,xkey ); \n \n    /* Store them with the final swap and the output whitening. */ \n    PUT_OUTPUT( C,D,A,B, p, xkey, 0 ); \n    } \n \n/* \n * Using the macros it is easy to make special routines for \n * CBC mode, CTR mode etc. The only thing you might want to \n * add is a XOR_PUT_OUTPUT which xors the outputs into the \n * destinationa instead of overwriting the data. This requires \n * a XOR_PUT32 macro as well, but that should all be trivial. \n * \n * I thought about including routines for the separate cipher \n * modes here, but it is unclear which modes should be included, \n * and each encryption or decryption routine takes up a lot of code space. \n * Also, I don't have any test vectors for any cipher modes \n * with Twofish. \n */ \n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/twofish.h",
    "content": "/* \n * Fast, portable, and easy-to-use Twofish implementation,  \n * Version 0.3. \n * Copyright (c) 2002 by Niels Ferguson. \n * \n * See the twofish.c file for the details of the how and why of this code. \n * \n * The author hereby grants a perpetual license to everybody to \n * use this code for any purpose as long as the copyright message is included \n * in the source code of this or any derived work. \n */ \n \n \n/* \n * PLATFORM FIXES \n * ============== \n * \n * The following definitions have to be fixed for each particular platform  \n * you work on. If you have a multi-platform program, you no doubt have  \n * portable definitions that you can substitute here without changing  \n * the rest of the code. \n * \n * The defaults provided here should work on most PC compilers. \n */ \n \n#ifndef TWOFISH_H\n#define TWOFISH_H\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/**\n * @file twofish.h\n * @brief Function that provide basic Twofish crypto support\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n \n/**\n * A Twofish_Byte must be an unsigned 8-bit integer.\n *\n * It must also be the elementary data size of your C platform, \n * i.e. sizeof( Twofish_Byte ) == 1. \n */ \ntypedef unsigned char   Twofish_Byte; \n \n/**\n * A Twofish_UInt32 must be an unsigned integer of at least 32 bits.  \n *  \n * This type is used only internally in the implementation, so ideally it \n * would not appear in the header file, but it is used inside the \n * Twofish_key structure which means it has to be included here. \n */ \ntypedef unsigned int    Twofish_UInt32; \n \n \n/* \n * END OF PLATFORM FIXES \n * ===================== \n *  \n * You should not have to touch the rest of this file, but the code \n * in twofish.c has a few things you need to fix too. \n */ \n\n/**\n * Return  codes\n */\n#define SUCCESS          1\n#define ERR_UINT32      -2\n#define ERR_BYTE        -3\n#define ERR_GET32       -4\n#define ERR_PUT32       -5\n#define ERR_ROLR        -6\n#define ERR_BSWAP       -7\n#define ERR_SELECTB     -8\n#define ERR_TEST_ENC    -9\n#define ERR_TEST_DEC   -10\n#define ERR_SEQ_ENC    -11\n#define ERR_SEQ_DEC    -12\n#define ERR_ODD_KEY    -13\n#define ERR_INIT       -14\n#define ERR_KEY_LEN    -15\n#define ERR_ILL_ARG    -16\n\n\n/**\n * Structure that contains a prepared Twofish key.\n *\n * A cipher key is used in two stages. In the first stage it is converted \n * form the original form to an internal representation.  \n * This internal form is then used to encrypt and decrypt data.  \n * This structure contains the internal form. It is rather large: 4256 bytes \n * on a platform with 32-bit unsigned values. \n * \n * Treat this as an opague structure, and don't try to manipulate the \n * elements in it. I wish I could hide the inside of the structure, \n * but C doesn't allow that. \n */ \ntypedef \n    struct\n        {\n        Twofish_UInt32 s[4][256];   /* pre-computed S-boxes */ \n        Twofish_UInt32 K[40];       /* Round key words */ \n        }\n    Twofish_key; \n\n\n/**\n * Initialise and test the Twofish implementation.  \n *  \n * This function MUST be called before any other function in the  \n * Twofish implementation is called. \n * It only needs to be called once. \n *  \n * Apart from initialising the implementation it performs a self test. \n * If the Twofish_fatal function is not called, the code passed the test. \n * (See the twofish.c file for details on the Twofish_fatal function.)\n *\n * @returns a negative number if an error happend, +1 otherwise\n */ \nextern int Twofish_initialise(); \n \n \n/**\n * Convert a cipher key to the internal form used for  \n * encryption and decryption. \n *  \n * The cipher key is an array of bytes; the Twofish_Byte type is  \n * defined above to a type suitable on your platform.  \n * \n * Any key must be converted to an internal form in the Twofisk_key structure \n * before it can be used. \n * The encryption and decryption functions only work with the internal form. \n * The conversion to internal form need only be done once for each key value. \n * \n * Be sure to wipe all key storage, including the Twofish_key structure,  \n * once you are done with the key data.  \n * A simple memset( TwofishKey, 0, sizeof( TwofishKey ) ) will do just fine. \n * \n * Unlike most implementations, this one allows any key size from 0 bytes  \n * to 32 bytes. According to the Twofish specifications,  \n * irregular key sizes are handled by padding the key with zeroes at the end  \n * until the key size is 16, 24, or 32 bytes, whichever \n * comes first. Note that each key of irregular size is equivalent to exactly \n * one key of 16, 24, or 32 bytes. \n * \n * WARNING: Short keys have low entropy, and result in low security. \n * Anything less than 8 bytes is utterly insecure. For good security \n * use at least 16 bytes. I prefer to use 32-byte keys to prevent \n * any collision attacks on the key. \n * \n * The key length argument key_len must be in the proper range. \n * If key_len is not in the range 0,...,32 this routine attempts to generate  \n * a fatal error (depending on the code environment),  \n * and at best (or worst) returns without having done anything. \n * \n * @param key      Array of key bytes \n * @param key_len  Number of key bytes, must be in the range 0,1,...,32.  \n * @param xkey     Pointer to an Twofish_key structure that will be filled  \n *                 with the internal form of the cipher key.\n * @returns a negative number if an error happend, +1 otherwise\n */ \nextern int Twofish_prepare_key(\n                                Twofish_Byte key[],\n                                int key_len,\n                                Twofish_key * xkey\n                                );\n\n\n/**\n * Encrypt a single block of data. \n * \n * This function encrypts a single block of 16 bytes of data. \n * If you want to encrypt a larger or variable-length message,  \n * you will have to use a cipher mode, such as CBC or CTR.  \n * These are outside the scope of this implementation. \n * \n * The xkey structure is not modified by this routine, and can be \n * used for further encryption and decryption operations. \n * \n * @param xkey     pointer to Twofish_key, internal form of the key \n *                 produces by Twofish_prepare_key() \n * @param p        Plaintext to be encrypted \n * @param c        Place to store the ciphertext \n */ \nextern void Twofish_encrypt(\n                            Twofish_key * xkey,\n                            Twofish_Byte p[16],\n                            Twofish_Byte c[16]\n                            ); \n\n\n/**\n * Decrypt a single block of data. \n * \n * This function decrypts a single block of 16 bytes of data. \n * If you want to decrypt a larger or variable-length message,  \n * you will have to use a cipher mode, such as CBC or CTR.  \n * These are outside the scope of this implementation. \n * \n * The xkey structure is not modified by this routine, and can be \n * used for further encryption and decryption operations. \n * \n * @param xkey     pointer to Twofish_key, internal form of the key \n *                 produces by Twofish_prepare_key() \n * @param c        Ciphertext to be decrypted \n * @param p        Place to store the plaintext \n */ \nextern void Twofish_decrypt(\n                            Twofish_key * xkey,\n                            Twofish_Byte c[16],\n                            Twofish_Byte p[16]\n                            ); \n\n\n/**\n * Encrypt data in CFB mode. \n * \n * This function encrypts data in CFB mode.\n *\n * The key structure is not modified by this routine, and can be \n * used for further encryption and decryption operations. \n * \n * @param keyCtx   pointer to Twofish_key, internal form of the key \n *                 produced by Twofish_prepare_key() \n * @param in       Plaintext to be encrypted \n * @param out      Place to store the ciphertext \n * @param len      number of bytes to encrypt.\n * @param ivec     initialization vector for this CFB mode encryption.\n * @param num      pointer to integer that holds number of available crypto bytes.\n */\nvoid Twofish_cfb128_encrypt(Twofish_key* keyCtx, Twofish_Byte* in,\n                            Twofish_Byte* out, size_t len,\n                            Twofish_Byte* ivec, int *num);\n\n/**\n * Decrypt data in CFB mode. \n * \n * This function decrypts data in CFB. \n *\n * The key structure is not modified by this routine, and can be \n * used for further encryption and decryption operations. \n * \n * @param keyCtx   pointer to Twofish_key, internal form of the key \n *                 produced by Twofish_prepare_key() \n * @param in       Ciphertext to be decrypted \n * @param out      Place to store the plaintext \n * @param len      number of bytes to decrypt.\n * @param ivec     initialization vector for this CFB mode encryption.\n * @param num      pointer to integer that holds number of available crypto bytes.\n */ \nvoid Twofish_cfb128_decrypt(Twofish_key* keyCtx, Twofish_Byte* in,\n                            Twofish_Byte* out, size_t len,\n                            Twofish_Byte* ivec, int *num);\n/**\n * @}\n */\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/cryptcommon/twofish_cfb.c",
    "content": "#include <stdint.h>\n#include <stdlib.h>\n\n#include \"twofish.h\"\n\n#ifdef ANDROID\nvoid Two_debugDummy(Twofish_Byte* in, Twofish_Byte* out, Twofish_Byte* ivec);\n#endif\n\nvoid Twofish_cfb128_encrypt(Twofish_key* keyCtx, Twofish_Byte* in, \n\t\t\t    Twofish_Byte* out, size_t len,\n\t\t\t    Twofish_Byte* ivec, int32_t *num)\n{\n  uint32_t n;\n\n  n = *num;\n\n  do {\n    while (n && len) {\n      *(out++) = ivec[n] ^= *(in++);\n      --len;\n      n = (n+1) % 16;\n    }\n    while (len>=16) {\n      Twofish_encrypt(keyCtx, ivec, ivec);\n      for (n=0; n<16; n+=sizeof(size_t)) {\n\n/*\n * Some GCC version(s) of Android's NDK produce code that leads to a crash (SIGBUS). The\n * offending line if the line that produces the output by xor'ing the ivec. Somehow the\n * compiler/optimizer seems to incorrectly setup the pointers. Adding a call to an\n * external function that uses the pointer disabled or modifies this optimzing\n * behaviour. This debug functions as such does nothing, it just disables some\n * optimization. Don't use a local (static) function - the compiler sees that it does\n * nothing and optimizes again :-) .\n */\n#ifdef ANDROID\n          Two_debugDummy(in, out, ivec);\n#endif\n          *(size_t*)(out+n) = *(size_t*)(ivec+n) ^= *(size_t*)(in+n);;\n      }\n      len -= 16;\n      out += 16;\n      in  += 16;\n    }\n    n = 0;\n    if (len) {\n      Twofish_encrypt(keyCtx, ivec, ivec);\n      while (len--) {\n          out[n] = ivec[n] ^= in[n];\n          ++n;\n      }\n    }\n    *num = n;\n    return;\n  } while (0);\n}\n\n\nvoid Twofish_cfb128_decrypt(Twofish_key* keyCtx, Twofish_Byte* in, \n\t\t\t    Twofish_Byte* out, size_t len,\n\t\t\t    Twofish_Byte* ivec, int32_t *num)\n{\n  uint32_t n;\n\n  n = *num;\n\n  do {\n    while (n && len) {\n      unsigned char c;\n      *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;\n      --len;\n      n = (n+1) % 16;\n    }\n    while (len>=16) {\n      Twofish_encrypt(keyCtx, ivec, ivec);\n      for (n=0; n<16; n+=sizeof(size_t)) {\n\tsize_t t = *(size_t*)(in+n);\n\t*(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;\n\t*(size_t*)(ivec+n) = t;\n      }\n      len -= 16;\n      out += 16;\n      in  += 16;\n    }\n    n = 0;\n    if (len) {\n      Twofish_encrypt(keyCtx, ivec, ivec);\n      while (len--) {\n\tunsigned char c;\n\tout[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;\n\t++n;\n      }\n    }\n    *num = n;\n    return;\n  } while (0);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/CryptoContext.cpp",
    "content": "/*\n  Copyright (C) 2006 - 2012 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\n*/\n\n/*\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <string.h>\n#include <stdio.h>\n#include <stdint.h>\n\n#include <common/osSpecifics.h>\n\n#include <CryptoContext.h>\n#include <crypto/SrtpSymCrypto.h>\n\nCryptoContext::CryptoContext( uint32_t ssrc,\n                              int32_t roc,\n                              int64_t key_deriv_rate,\n                              const int32_t ealg,\n                              const int32_t aalg,\n                              uint8_t* master_key,\n                              int32_t master_key_length,\n                              uint8_t* master_salt,\n                              int32_t master_salt_length,\n                              int32_t ekeyl,\n                              int32_t akeyl,\n                              int32_t skeyl,\n                              int32_t tagLength):\n\n        ssrcCtx(ssrc), mkiLength(0),mki(NULL), roc(roc),guessed_roc(0),\n        s_l(0),key_deriv_rate(key_deriv_rate), labelBase(0), seqNumSet(false),\n        macCtx(NULL), cipher(NULL), f8Cipher(NULL)\n{\n    replay_window[0] = replay_window[1] = 0;\n    this->ealg = ealg;\n    this->aalg = aalg;\n    this->ekeyl = ekeyl;\n    this->akeyl = akeyl;\n    this->skeyl = skeyl;\n\n    this->master_key_length = master_key_length;\n    this->master_key = new uint8_t[master_key_length];\n    memcpy(this->master_key, master_key, master_key_length);\n\n    this->master_salt_length = master_salt_length;\n    this->master_salt = new uint8_t[master_salt_length];\n    memcpy(this->master_salt, master_salt, master_salt_length);\n\n    switch (ealg) {\n        case SrtpEncryptionNull:\n            n_e = 0;\n            k_e = NULL;\n            n_s = 0;\n            k_s = NULL;\n            break;\n\n        case SrtpEncryptionTWOF8:\n            f8Cipher = new SrtpSymCrypto(SrtpEncryptionTWOF8);\n\n        case SrtpEncryptionTWOCM:\n            n_e = ekeyl;\n            k_e = new uint8_t[n_e];\n            n_s = skeyl;\n            k_s = new uint8_t[n_s];\n            cipher = new SrtpSymCrypto(SrtpEncryptionTWOCM);\n            break;\n\n        case SrtpEncryptionAESF8:\n            f8Cipher = new SrtpSymCrypto(SrtpEncryptionAESF8);\n\n        case SrtpEncryptionAESCM:\n            n_e = ekeyl;\n            k_e = new uint8_t[n_e];\n            n_s = skeyl;\n            k_s = new uint8_t[n_s];\n            cipher = new SrtpSymCrypto(SrtpEncryptionAESCM);\n            break;\n    }\n\n    switch (aalg) {\n        case SrtpAuthenticationNull:\n            n_a = 0;\n            k_a = NULL;\n            this->tagLength = 0;\n            break;\n\n        case SrtpAuthenticationSha1Hmac:\n            n_a = akeyl;\n            k_a = new uint8_t[n_a];\n            this->tagLength = tagLength;\n            this->macCtx = createSha1HmacContext(k_a, n_a);\n            break;\n\n        case SrtpAuthenticationSkeinHmac:\n            n_a = akeyl;\n            k_a = new uint8_t[n_a];\n            this->tagLength = tagLength;\n            this->macCtx = createSkeinMacContext(k_a, n_a, tagLength*8, Skein512);  // Skein MAC uses number of bits as MAC size, not just bytes\n            break;\n    }\n}\n\n/*\n * memset_volatile is a volatile pointer to the memset function.\n * You can call (*memset_volatile)(buf, val, len) or even\n * memset_volatile(buf, val, len) just as you would call\n * memset(buf, val, len), but the use of a volatile pointer\n * guarantees that the compiler will not optimise the call away.\n */\nstatic void * (*volatile memset_volatile)(void *, int, size_t) = memset;\n\nCryptoContext::~CryptoContext()\n{\n    if (macCtx) {\n        switch (aalg) {\n            case SrtpAuthenticationSha1Hmac:\n                freeSha1HmacContext(macCtx);\n                break;\n\n            case SrtpAuthenticationSkeinHmac:\n                freeSkeinMacContext(macCtx);\n                break;\n        }\n        macCtx = NULL;\n    }\n\n    if (mki)\n        delete [] mki;\n\n    if (master_key_length > 0) {\n        memset_volatile(master_key, 0, master_key_length);\n        master_key_length = 0;\n        delete [] master_key;\n    }\n    if (master_salt_length > 0) {\n        memset_volatile(master_salt, 0, master_salt_length);\n        master_salt_length = 0;\n        delete [] master_salt;\n    }\n    if (n_e > 0) {\n        memset_volatile(k_e, 0, n_e);\n        n_e = 0;\n        delete [] k_e;\n    }\n    if (n_s > 0) {\n        memset_volatile(k_s, 0, n_s);\n        n_s = 0;\n        delete [] k_s;\n    }\n    if (n_a > 0) {\n        memset_volatile(k_a, 0, n_a);\n        n_a = 0;\n        delete [] k_a;\n    }\n    if (cipher != NULL) {\n        delete cipher;\n        cipher = NULL;\n    }\n    if (f8Cipher != NULL) {\n        delete f8Cipher;\n        f8Cipher = NULL;\n    }\n}\n\nvoid CryptoContext::srtpEncrypt(uint8_t* pkt, uint8_t* payload, uint32_t paylen, uint64_t index, uint32_t ssrc ) {\n\n    if (ealg == SrtpEncryptionNull) {\n        return;\n    }\n    if (ealg == SrtpEncryptionAESCM || ealg == SrtpEncryptionTWOCM) {\n\n        /* Compute the CM IV (refer to chapter 4.1.1 in RFC 3711):\n         *\n         * k_s   XX XX XX XX XX XX XX XX XX XX XX XX XX XX\n         * SSRC              XX XX XX XX\n         * index                         XX XX XX XX XX XX\n         * ------------------------------------------------------XOR\n         * IV    XX XX XX XX XX XX XX XX XX XX XX XX XX XX 00 00\n         */\n\n        unsigned char iv[16];\n        memcpy(iv, k_s, 4);\n\n        int i;\n        for (i = 4; i < 8; i++ ) {\n            iv[i] = (0xFF & (ssrc >> ((7-i)*8))) ^ k_s[i];\n        }\n        for (i = 8; i < 14; i++ ) {\n            iv[i] = (0xFF & (unsigned char)(index >> ((13-i)*8) ) ) ^ k_s[i];\n        }\n        iv[14] = iv[15] = 0;\n\n        cipher->ctr_encrypt(payload, paylen, iv);\n    }\n\n    if (ealg == SrtpEncryptionAESF8 || ealg == SrtpEncryptionTWOF8) {\n\n        /* Create the F8 IV (refer to chapter 4.1.2.2 in RFC 3711):\n         *\n         * IV = 0x00 || M || PT || SEQ  ||      TS    ||    SSRC   ||    ROC\n         *      8Bit  1bit  7bit  16bit       32bit        32bit        32bit\n         * ------------\\     /--------------------------------------------------\n         *       XX       XX      XX XX   XX XX XX XX   XX XX XX XX  XX XX XX XX\n         */\n\n        unsigned char iv[16];\n        uint32_t *ui32p = (uint32_t *)iv;\n\n        memcpy(iv, pkt, 12);\n        iv[0] = 0;\n\n        // set ROC in network order into IV\n        ui32p[3] = zrtpHtonl(roc);\n\n        cipher->f8_encrypt(payload, paylen, iv, f8Cipher);\n    }\n}\n\n/* Warning: tag must have been initialized */\nvoid CryptoContext::srtpAuthenticate(uint8_t* pkt, uint32_t pktlen, uint32_t roc, uint8_t* tag )\n{\n\n    if (aalg == SrtpAuthenticationNull) {\n        return;\n    }\n    int32_t macL;\n\n    unsigned char temp[20];\n    const unsigned char* chunks[3];\n    unsigned int chunkLength[3];\n    uint32_t beRoc = zrtpHtonl(roc);\n\n    chunks[0] = pkt;\n    chunkLength[0] = pktlen;\n\n    chunks[1] = (unsigned char *)&beRoc;\n    chunkLength[1] = 4;\n    chunks[2] = NULL;\n\n    switch (aalg) {\n    case SrtpAuthenticationSha1Hmac:\n        hmacSha1Ctx(macCtx,\n                    chunks,           // data chunks to hash\n                    chunkLength,      // length of the data to hash\n                    temp, &macL);\n        /* truncate the result */\n        memcpy(tag, temp, getTagLength());\n        break;\n    case SrtpAuthenticationSkeinHmac:\n        macSkeinCtx(macCtx,\n                    chunks,           // data chunks to hash\n                    chunkLength,      // length of the data to hash\n                    temp);\n        /* truncate the result */\n        memcpy(tag, temp, getTagLength());\n        break;\n    }\n}\n\n/* used by the key derivation method */\nstatic void computeIv(unsigned char* iv, uint64_t label, uint64_t index,\n                      int64_t kdv, unsigned char* master_salt)\n{\n\n    uint64_t key_id;\n\n    if (kdv == 0) {\n        key_id = label << 48;\n    }\n    else {\n        key_id = ((label << 48) | (index / kdv));\n    }\n\n    //printf( \"Key_ID: %llx\\n\", key_id );\n\n    /* compute the IV\n       key_id:                           XX XX XX XX XX XX XX\n       master_salt: XX XX XX XX XX XX XX XX XX XX XX XX XX XX\n       ------------------------------------------------------------ XOR\n       IV:          XX XX XX XX XX XX XX XX XX XX XX XX XX XX 00 00\n    */\n\n    int i;\n    for (i = 0; i < 7 ; i++ ) {\n        iv[i] = master_salt[i];\n    }\n\n    for (i = 7; i < 14 ; i++ ) {\n        iv[i] = (unsigned char)(0xFF & (key_id >> (8*(13-i)))) ^  master_salt[i];\n    }\n    iv[14] = iv[15] = 0;\n}\n\n/* Derive the srtp session keys from the master key */\nvoid CryptoContext::deriveSrtpKeys(uint64_t index)\n{\n    uint8_t iv[16];\n\n    // prepare cipher to compute derived keys.\n    cipher->setNewKey(master_key, master_key_length);\n    memset(master_key, 0, master_key_length);\n\n    // compute the session encryption key\n    uint64_t label = labelBase + 0;\n    computeIv(iv, label, index, key_deriv_rate, master_salt);\n    cipher->get_ctr_cipher_stream(k_e, n_e, iv);\n\n    // compute the session authentication key\n    label = labelBase + 0x01;\n    computeIv(iv, label, index, key_deriv_rate, master_salt);\n    cipher->get_ctr_cipher_stream(k_a, n_a, iv);\n\n    // Initialize MAC context with the derived key\n    switch (aalg) {\n    case SrtpAuthenticationSha1Hmac:\n        initializeSha1HmacContext(macCtx, k_a, n_a);\n        break;\n    case SrtpAuthenticationSkeinHmac:\n        initializeSkeinMacContext(macCtx, k_a, n_a, tagLength*8, Skein512);  // Skein MAC uses number of bits as MAC size, not just bytes\n        break;\n    }\n    memset(k_a, 0, n_a);\n\n    // compute the session salt\n    label = labelBase + 0x02;\n    computeIv(iv, label, index, key_deriv_rate, master_salt);\n    cipher->get_ctr_cipher_stream(k_s, n_s, iv);\n    memset(master_salt, 0, master_salt_length);\n\n    // as last step prepare cipher with derived key.\n    cipher->setNewKey(k_e, n_e);\n    if (f8Cipher != NULL)\n        cipher->f8_deriveForIV(f8Cipher, k_e, n_e, k_s, n_s);\n    memset(k_e, 0, n_e);\n}\n\n/* Based on the algorithm provided in Appendix A - draft-ietf-srtp-05.txt */\nuint64_t CryptoContext::guessIndex(uint16_t new_seq_nb )\n{\n    /*\n     * Initialize the sequences number on first call that uses the\n     * sequence number. Either GuessIndex() or checkReplay().\n     */\n    if (!seqNumSet) {\n        seqNumSet = true;\n        s_l = new_seq_nb;\n    }\n    if (s_l < 32768) {\n        if (new_seq_nb - s_l > 32768) {\n            guessed_roc = roc - 1;\n        }\n        else {\n            guessed_roc = roc;\n        }\n    }\n    else {\n        if (s_l - 32768 > new_seq_nb) {\n            guessed_roc = roc + 1;\n        }\n        else {\n            guessed_roc = roc;\n        }\n    }\n\n    return ((uint64_t)guessed_roc) << 16 | new_seq_nb;\n}\n\n\nbool CryptoContext::checkReplay(uint16_t newSeq)\n{\n    if ( aalg == SrtpAuthenticationNull && ealg == SrtpEncryptionNull ) {\n        /* No security policy, don't use the replay protection */\n        return true;\n    }\n\n    /*\n     * Initialize the sequences number on first call that uses the\n     * sequence number. Either guessIndex() or checkReplay().\n     */\n    if (!seqNumSet) {\n        seqNumSet = true;\n        s_l = newSeq;\n    }\n    uint64_t guessed_index = guessIndex(newSeq);\n    uint64_t local_index = (((uint64_t)roc) << 16) | s_l;\n\n    int64_t delta = guessed_index - local_index;\n    if (delta > 0) {\n        return true;           /* Packet not yet received*/\n    }\n    else {\n        if (-delta >= REPLAY_WINDOW_SIZE) {\n            return false;      /* Packet too old */\n        }\n\n        delta = -delta;\n        int idx = delta / 64;\n        uint64_t bit = 1UL << (delta % 64);\n        if ((replay_window[idx] & bit) == bit) {\n            return false;  /* Packet already received ! */\n        }\n        else {\n            return true;  /* Packet not yet received */\n        }\n    }\n}\n\n// This function assumes that it never gets a sequence number that is out of order\n// greater or equal than REPLAY_WINDOW_SIZE. Thus an application MUST perform a \n// replay check first and discard any packet which fails this check. This restriction\n// applies to older packets only, a new (not seen) packet's sequence number can jump \n// ahead by more than REPLAY_WINDOW_SIZE.\nvoid CryptoContext::update(uint16_t newSeq)\n{\n    // Get the index of the new sequence number and compute the delta to the\n    // index of the highest sequence number we received so far. If the delta \n    // is negative then we received an older packet, thus we will not\n    // update the locally stored remote sequence number (s_l) below.\n    int64_t delta = guessIndex(newSeq) - (((uint64_t)roc) << 16 | s_l );\n    int64_t rocDelta = delta;\n    uint64_t carry = 0;\n\n    // update the replay shift register\n    // The shift register array stores bits of newer packets (higher sequence numbers) at \n    // index 0 and shifts older packets (lower sequence numbers) left to index one\n    if (delta > 0) {                         // We got a new packet, no yet seen\n        if (delta >= REPLAY_WINDOW_SIZE) {\n            replay_window[0] = 1;\n            replay_window[1] = 0;\n        }\n        else {\n            if (delta < REPLAY_WINDOW_SIZE/2) {\n                carry = replay_window[0] >> ((REPLAY_WINDOW_SIZE/2) - delta);\n                replay_window[0] = (replay_window[0] << delta) | 1;\n                replay_window[1] = (replay_window[1] << delta) | carry;\n            }\n            else {\n                replay_window[1] = replay_window[0] << (delta - REPLAY_WINDOW_SIZE/2);\n                replay_window[0] = 1;\n            }\n        }\n    }\n    else {\n        delta = -delta;\n        int idx = delta / 64;\n        uint64_t bit = 1UL << (delta % 64);\n        replay_window[idx] |= bit;\n    }\n\n    // update the locally stored ROC and highest sequence number if we received a not\n    // yet received packet, i.e. the delta is > 0\n    if (rocDelta > 0 && newSeq > s_l) {\n        s_l = newSeq;\n    }\n    // Reset local stored sequence number (low 16 bits) also if ROC increases\n    // The guessed_roc is bigger than roc only if we received a not yet seen packet.\n    if (guessed_roc > roc) {\n        roc = guessed_roc;\n        s_l = newSeq;\n    }\n}\n\nCryptoContext* CryptoContext::newCryptoContextForSSRC(uint32_t ssrc, int roc, int64_t keyDerivRate)\n{\n    CryptoContext* pcc = new CryptoContext(\n        ssrc,\n        roc,                                     // Roll over Counter,\n        keyDerivRate,                            // keyderivation << 48,\n        this->ealg,                              // encryption algo\n        this->aalg,                              // authentication algo\n        this->master_key,                        // Master Key\n        this->master_key_length,                 // Master Key length\n        this->master_salt,                       // Master Salt\n        this->master_salt_length,                // Master Salt length\n        this->ekeyl,                             // encryption keyl\n        this->akeyl,                             // authentication key len\n        this->skeyl,                             // session salt len\n        this->tagLength);                        // authentication tag len\n\n    return pcc;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/CryptoContext.h",
    "content": "/*\n  Copyright (C) 2006 - 2012 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\n*/\n\n#ifndef CRYPTOCONTEXT_H\n#define CRYPTOCONTEXT_H\n\n/**\n * @file CryptoContext.h\n * @brief The C++ SRTP implementation\n * @ingroup Z_SRTP\n * @{\n */\n\n#define REPLAY_WINDOW_SIZE 128\n\nconst int SrtpAuthenticationNull      = 0;\nconst int SrtpAuthenticationSha1Hmac  = 1;\nconst int SrtpAuthenticationSkeinHmac = 2;\n\nconst int SrtpEncryptionNull  = 0;\nconst int SrtpEncryptionAESCM = 1;\nconst int SrtpEncryptionAESF8 = 2;\nconst int SrtpEncryptionTWOCM = 3;\nconst int SrtpEncryptionTWOF8 = 4;\n\n// Check if included via CryptoContextCtrl.cpp - avoid double definitions\n#ifndef CRYPTOCONTEXTCTRL_H\n\n#include <stdint.h>\n#include <crypto/hmac.h>\n#include <cryptcommon/macSkein.h>\n\nclass SrtpSymCrypto;\n\n/**\n * @brief Implementation for a SRTP cryptographic context.\n *\n * This class holds data and provides functions that implement a\n * cryptographic context for SRTP. Refer to RFC 3711, chapter 3.2 for some\n * more detailed information about the SRTP cryptographic context.\n *\n * Each SRTP cryptographic context uses a RTP source identified by\n * its SSRC. Thus you can independently protect each source inside a RTP\n * session.\n *\n * Key management mechanisms negotiate the parameters for the SRTP\n * cryptographic context, such as master key, key length, authentication\n * length and so on. The key management mechanisms are not part of\n * SRTP. Refer to MIKEY (RFC 3880) or to Phil Zimmermann's ZRTP protocol\n * (RFC6189). After key management negotiated the data the application can\n * setup the SRTP cryptographic context and enable SRTP processing.\n *\n * This SRTP context implementation supports RTP only.\n *\n * A short eample how to setup a SRTP CryptoContext:\n @verbatim\n\n // First some key and salt data - this data is just for demo purposes\n uint8 masterKey[] = {   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n                        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };\n\n uint8 masterSalt[] = {  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,\n                        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d };\n\n ...\n\n CryptoContext* cryptoCtxSend =\n     new CryptoContext(0xfeedbacc,\n     0,                           // roc,\n     0L,                          // keyderivation rate << 48,\n     SrtpEncryptionAESCM,         // encryption algo\n     SrtpAuthenticationSha1Hmac,  // authtication algo\n     masterKey,                   // Master Key data\n     128 / 8,                     // Master Key length in bytes\n     masterSalt,                  // Master Salt data\n     112 / 8,                     // Master Salt length in bytes\n     128 / 8,                     // encryption keylength in bytes\n     160 / 8,                     // authentication key length in bytes (SHA1)\n     112 / 8,                     // session salt length in bytes\n      80 / 8);                     // authentication tag length in bytes\n\n cryptoCtxSend->deriveSrtpKeys(0);\n\n ....\n\n // To protect a RTP packet\n // buffer: pointer to the RTP packet, length of the RTP data, newLength is a\n // pointer to a size_t that gets the updated length.\n bool rc = SrtpHandler::protect(cryptoCtxSend, buffer, length, newLength);\n\n // To unprotect a SRTP packet:\n // buffer: pointer to the RTP packet, length of the SRTP data, newLength is a\n // pointer to a size_t that gets the updated length.\n int32_t rc = SrtpHandler::unprotect(cryptoCtxRecv, buffer, length, newLength);\n\n @endverbatim\n *\n * @note You need two CryptoContext instances - one for the sending channel the\n * other one for the receiving channel. \n *\n * Before an appliction can use a CryptoContext it must call the key derivation\n * function deriveSrtpKeys() first. Only then this SRTP cryptographic context is ready\n * to protect or unprotect a RTP SSRC stream.\n *\n * Together with the newCryptoContextForSSRC() function an application can prepare a\n * CryptoContext and save it as template. Once it needs a new CryptoContext, say\n * for a new SSRC, it calls newCryptoContextForSSRC() on the saved context to get an\n * initialized copy and then call deriveSrtpKeys() to compute and process the keys.\n *\n * @note A saved, pre-initialized template contains the non-processed keys. Only\n * the method deriveSrtpKeys() processes the keys and cleares them. Thus don't store\n * CryptoContext templates if the application cannot protect the templates against\n * reading from other possibly rogue applications.\n *\n * @sa SrtpHandler\n * \n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\nclass CryptoContext {\npublic:\n    /**\n     * @brief Constructor for an active SRTP cryptographic context.\n     *\n     * This constructor creates an pre-initialized SRTP cryptographic context were\n     * algorithms are allocated, keys are stored and so on. An application can\n     * call newCryptoContextForSSRC() to get a full copy of this pre-initialized\n     * CryptoContext.\n     *\n     *\n     * @param ssrc\n     *    The RTP SSRC that this SRTP cryptographic context belongs to.\n     *\n     * @param roc\n     *    The initial Roll-Over-Counter according to RFC 3711. These are the\n     *    upper 32 bit of the overall 48 bit SRTP packet index. Usually set to zero.\n     *    Refer to chapter 3.2.1 of the RFC.\n     *\n     * @param keyDerivRate\n     *    The key derivation rate defines when to recompute the SRTP session\n     *    keys. Refer to chapter 4.3.1 in the RFC.\n     *\n     * @param ealg\n     *    The encryption algorithm to use. Possible values are <code>\n     *    SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8,\n     *    SrtpEncryptionTWOCM, SrtpEncryptionTWOF8</code>. See chapter 4.1.1\n     *    for AESCM (Counter mode) and 4.1.2 for AES F8 mode.\n     *\n     * @param aalg\n     *    The authentication algorithm to use. Possible values are <code>\n     *    SrtpEncryptionNull, SrtpAuthenticationSha1Hmac, SrtpAuthenticationSkeinHmac\n     *    </code>.\n     *\n     * @param masterKey\n     *    Pointer to the master key for this SRTP cryptographic context.\n     *    Must point to <code>masterKeyLength</code> bytes. Refer to chapter\n     *    3.2.1 of the RFC about the role of the master key.\n     *\n     * @param masterKeyLength\n     *    The length in bytes of the master key in bytes. The length must\n     *    match the selected encryption algorithm. Because SRTP uses AES\n     *    based  encryption only, then master key length may be 16 or 32\n     *    bytes (128 or 256 bit master key)\n     *\n     * @param masterSalt\n     *    SRTP uses the master salt to generate the initialization vector\n     *    that in turn is input to compute the session key, session\n     *    authentication key and the session salt.\n     *\n     * @param masterSaltLength\n     *    The length in bytes of the master salt data in bytes. According to\n     *    RFC3711 the standard value for the master salt length should\n     *    be 14 bytes (112 bit).\n     *\n     * @param ekeyl\n     *    The length in bytes of the session encryption key that SRTP shall\n     *    generate and use. Usually the same length as for the master key\n     *    length, however you may use a different length as well.\n     *\n     * @param akeyl\n     *    The length in bytes of the session authentication key. SRTP\n     *    computes this key and uses it as input to the authentication\n     *    algorithm.\n     *    This is usually 160 bits (20 bytes) for @c SrtpAuthenticationSha1Hmac\n     *    and 256 bits (32 bytes) for @c SrtpAuthenticationSkeinHmac.\n     *\n     * @param skeyl\n     *    The length in bytes of the session salt. SRTP computes this salt\n     *    key and uses it as input during encryption. The length usually\n     *    is the same as the master salt length.\n     *\n     * @param tagLength\n     *    The length is bytes of the authentication tag that SRTP appends\n     *    to the RTP packet. The @c CryptoContext supports @c SrtpAuthenticationSha1Hmac\n     *    with 4 and 10 byte (32 and 80 bits) and @c SrtpAuthenticationSkeinHmac\n     *    with 4 and 8 bytes (32 and 64 bits) tag length. Refer to chapter 4.2. in RFC 3711.\n     */\n    CryptoContext(uint32_t ssrc, int32_t roc,\n                   int64_t  keyDerivRate,\n                   const  int32_t ealg,\n                   const  int32_t aalg,\n                   uint8_t* masterKey,\n                   int32_t  masterKeyLength,\n                   uint8_t* masterSalt,\n                   int32_t  masterSaltLength,\n                   int32_t  ekeyl,\n                   int32_t  akeyl,\n                   int32_t  skeyl,\n                   int32_t  tagLength);\n\n    /**\n     * @brief Destructor.\n     *\n     * Cleans the SRTP cryptographic context.\n     */\n    ~CryptoContext();\n\n    /**\n     * @brief Set the Roll-Over-Counter.\n     *\n     * Ths method sets the upper 32 bit of the 48 bit SRTP packet index\n     * (the roll-over-part)\n     *\n     * @param r\n     *   The roll-over-counter\n     */\n    inline void setRoc(uint32_t r) { roc = r; }\n\n    /**\n     * @brief Get the Roll-Over-Counter.\n     *\n     * Ths method get the upper 32 bit of the 48 bit SRTP packet index\n     * (the roll-over-part)\n     *\n     * @return The roll-over-counter\n     */\n    inline uint32_t getRoc() const { return roc; }\n\n    /**\n     * @brief Perform SRTP encryption.\n     *\n     * This method encrypts <em>and</em> decrypts SRTP payload data. Plain\n     * data gets encrypted, encrypted data get decrypted.\n     *\n     * @param pkt\n     *    Pointer to RTP packet buffer, used for F8.\n     *\n     * @param payload\n     *    The data to encrypt.\n     *\n     * @param paylen\n     *    Length of payload.\n     *\n     * @param index\n     *    The 48 bit SRTP packet index. See the <code>guessIndex</code>\n     *    method.\n     *\n     * @param ssrc\n     *    The RTP SSRC data in <em>host</em> order.\n     */\n    void srtpEncrypt(uint8_t* pkt, uint8_t* payload, uint32_t paylen, uint64_t index, uint32_t ssrc);\n\n    /**\n     * @brief Compute the authentication tag.\n     *\n     * Compute the authentication tag according the the paramters in the\n     * SRTP Cryptograhic context.\n     *\n     * @param pkt\n     *    Pointer to RTP packet buffer that contains the data to authenticate.\n     *\n     * @param pktlen\n     *    Length of the RTP packet buffer\n     *\n     * @param roc\n     *    The 32 bit SRTP roll-over-counter.\n     *\n     * @param tag\n     *    Points to a buffer that hold the computed tag. This buffer must\n     *    be able to hold <code>tagLength</code> bytes.\n     */\n    void srtpAuthenticate(uint8_t* pkt, uint32_t pktlen, uint32_t roc, uint8_t* tag);\n\n    /**\n     * @brief Perform key derivation according to SRTP specification\n     *\n     * This method computes the session key, session authentication key and the\n     * session salt key. This method must be called at least once after the\n     * SRTP Cryptograhic context was set up.\n     *\n     * This method clears the key data once it was processed by the encryptions'\n     * set key functions.\n     *\n     * @param index\n     *    The 48 bit SRTP packet index. See the <code>guessIndex</code>\n     *    method. Usually 0.\n     */\n    void deriveSrtpKeys(uint64_t index);\n\n    /**\n     * @brief Compute (guess) the new SRTP index based on the sequence number of\n     * a received RTP packet.\n     *\n     * The method uses the algorithm show in RFC3711, Appendix A, to compute\n     * the new index.\n     *\n     * @param newSeqNumber\n     *    The sequence number of the received RTP packet in host order.\n     *\n     * @return The new SRTP packet index\n     */\n    uint64_t guessIndex(uint16_t newSeqNumber);\n\n    /**\n     * @brief Check for packet replay.\n     *\n     * The method check if a received packet is either to old or was already\n     * received.\n     *\n     * The method supports a 64 packet history relative the the given\n     * sequence number.\n     *\n     * @param newSeqNumber\n     *    The sequence number of the received RTP packet in host order.\n     *\n     * @return <code>true</code> if no replay, <code>false</code> if packet\n     *    is too old ar was already received.\n     */\n    bool checkReplay(uint16_t newSeqNumber);\n\n    /**\n     * @brief Update the SRTP packet index.\n     *\n     * Call this method after all checks were successful. See chapter\n     * 3.3.1 in the RFC when to update the ROC and ROC processing.\n     *\n     * @param newSeqNumber\n     *    The sequence number of the received RTP packet in host order.\n     */\n    void update(uint16_t newSeqNumber);\n\n    /**\n     * @brief Get the length of the SRTP authentication tag in bytes.\n     *\n     * @return the length of the authentication tag.\n     */\n    int32_t getTagLength() const { return tagLength; }\n\n    /**\n     * @brief Get the length of the MKI in bytes.\n     *\n     * @return the length of the MKI.\n     */\n    int32_t getMkiLength() const { return mkiLength; }\n\n    /**\n     * @brief Get the SSRC of this SRTP Cryptograhic context.\n     *\n     * @return the SSRC.\n     */\n    uint32_t getSsrc() const { return ssrcCtx; }\n\n    /**\n     * @brief Set the start (base) number to compute the PRF labels.\n     *\n     * Refer to RFC3711, chapters 4.3.1 and 4.3.2 about values for labels.\n     * CryptoContext computes the labes as follows:\n     *\n     * - labelBase + 0 -> encryption label\n     * - labelBase + 1 -> authentication label\n     * - labelBase + 2 -> salting key label\n     *\n     * The CryptoContext constructor initializes CryptoContext::labelBase\n     * with 0 to comply with RFC 3711 label values.\n     *\n     * Applications may set the #labelBase to other values to use the CryptoContext\n     * for other purposes.\n     */\n    void setLabelbase(uint8_t base) { labelBase = base; }\n\n    /**\n     * @brief Derive a new Crypto Context for use with a new SSRC\n     *\n     * This method returns a new Crypto Context initialized with the data\n     * of this crypto context. Replacing the SSRC, Roll-over-Counter, and\n     * the key derivation rate the application can use this Crypto Context\n     * to encrypt / decrypt a new stream (Synchronization source) inside\n     * one RTP session.\n     *\n     * Before the application can use this crypto context it must call deriveSrtpKeys().\n     *\n     * @param ssrc\n     *     The SSRC for this context\n     * @param roc\n     *     The Roll-Over-Counter for this context, usually 0\n     * @param keyDerivRate\n     *     The key derivation rate for this context, usally 0\n     * @return\n     *     a new CryptoContext with all relevant data set.\n     */\n    CryptoContext* newCryptoContextForSSRC(uint32_t ssrc, int roc, int64_t keyDerivRate);\n\nprivate:\n    uint32_t ssrcCtx;\n    uint32_t mkiLength;\n    uint8_t* mki;\n\n    uint32_t roc;\n    uint32_t guessed_roc;\n    uint16_t s_l;\n    int64_t  key_deriv_rate;\n\n    /* bitmask for replay check */\n    uint64_t replay_window[2];\n\n    uint8_t* master_key;\n    uint32_t master_key_length;\n    uint8_t* master_salt;\n    uint32_t master_salt_length;\n\n    /* Session Encryption, Authentication keys, Salt */\n    int32_t  n_e;\n    uint8_t* k_e;\n    int32_t  n_a;\n    uint8_t* k_a;\n    int32_t  n_s;\n    uint8_t* k_s;\n\n    int32_t ealg;\n    int32_t aalg;\n    int32_t ekeyl;\n    int32_t akeyl;\n    int32_t skeyl;\n    int32_t tagLength;\n    uint8_t labelBase;\n    bool  seqNumSet;\n\n    void* macCtx;\n\n    SrtpSymCrypto* cipher;\n    SrtpSymCrypto* f8Cipher;\n};\n\n#endif\n\n/**\n * @}\n */\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/CryptoContextCtrl.cpp",
    "content": "/*\n  Copyright (C) 2011 - 2012 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\n*/\n\n/* \n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <string.h>\n#include <stdio.h>\n#include <stdint.h>\n\n#include <common/osSpecifics.h>\n\n#include <CryptoContextCtrl.h>\n#include <CryptoContext.h>\n\n#include <crypto/SrtpSymCrypto.h>\n\n\nCryptoContextCtrl::CryptoContextCtrl(uint32_t ssrc,\n                                const int32_t ealg,\n                                const int32_t aalg,\n                                uint8_t* master_key,\n                                int32_t master_key_length,\n                                uint8_t* master_salt,\n                                int32_t master_salt_length,\n                                int32_t ekeyl,\n                                int32_t akeyl,\n                                int32_t skeyl,\n                                int32_t tagLength):\nssrcCtx(ssrc), mkiLength(0),mki(NULL), replay_window(0), srtcpIndex(0),\nlabelBase(3), macCtx(NULL), cipher(NULL), f8Cipher(NULL)        // SRTCP labels start at 3\n\n{\n    this->ealg = ealg;\n    this->aalg = aalg;\n    this->ekeyl = ekeyl;\n    this->akeyl = akeyl;\n    this->skeyl = skeyl;\n\n    this->master_key_length = master_key_length;\n    this->master_key = new uint8_t[master_key_length];\n    memcpy(this->master_key, master_key, master_key_length);\n\n    this->master_salt_length = master_salt_length;\n    this->master_salt = new uint8_t[master_salt_length];\n    memcpy(this->master_salt, master_salt, master_salt_length);\n\n    switch (ealg) {\n        case SrtpEncryptionNull:\n            n_e = 0;\n            k_e = NULL;\n            n_s = 0;\n            k_s = NULL;\n            break;\n\n        case SrtpEncryptionTWOF8:\n            f8Cipher = new SrtpSymCrypto(SrtpEncryptionTWOF8);\n\n        case SrtpEncryptionTWOCM:\n            n_e = ekeyl;\n            k_e = new uint8_t[n_e];\n            n_s = skeyl;\n            k_s = new uint8_t[n_s];\n            cipher = new SrtpSymCrypto(SrtpEncryptionTWOCM);\n            break;\n\n        case SrtpEncryptionAESF8:\n            f8Cipher = new SrtpSymCrypto(SrtpEncryptionAESF8);\n\n        case SrtpEncryptionAESCM:\n            n_e = ekeyl;\n            k_e = new uint8_t[n_e];\n            n_s = skeyl;\n            k_s = new uint8_t[n_s];\n            cipher = new SrtpSymCrypto(SrtpEncryptionAESCM);\n            break;\n    }\n\n    switch (aalg) {\n        case SrtpAuthenticationNull:\n            n_a = 0;\n            k_a = NULL;\n            this->tagLength = 0;\n            break;\n\n        case SrtpAuthenticationSha1Hmac:\n            n_a = akeyl;\n            k_a = new uint8_t[n_a];\n            this->tagLength = tagLength;\n            this->macCtx = createSha1HmacContext(k_a, n_a);\n            break;\n\n        case SrtpAuthenticationSkeinHmac:\n            n_a = akeyl;\n            k_a = new uint8_t[n_a];\n            this->tagLength = tagLength;\n            this->macCtx = createSkeinMacContext(k_a, n_a, tagLength*8, Skein512);  // Skein MAC uses number of bits as MAC size, not just bytes\n            break;\n    }\n}\n\n/*\n * memset_volatile is a volatile pointer to the memset function.\n * You can call (*memset_volatile)(buf, val, len) or even\n * memset_volatile(buf, val, len) just as you would call\n * memset(buf, val, len), but the use of a volatile pointer\n * guarantees that the compiler will not optimise the call away.\n */\nstatic void * (*volatile memset_volatile)(void *, int, size_t) = memset;\n\nCryptoContextCtrl::~CryptoContextCtrl()\n{\n    if (macCtx) {\n        switch (aalg) {\n            case SrtpAuthenticationSha1Hmac:\n                freeSha1HmacContext(macCtx);\n                break;\n\n            case SrtpAuthenticationSkeinHmac:\n                freeSkeinMacContext(macCtx);\n                break;\n        }\n        macCtx = NULL;\n    }\n\n    if (mki)\n        delete [] mki;\n\n    if (master_key_length > 0) {\n        memset_volatile(master_key, 0, master_key_length);\n        master_key_length = 0;\n        delete [] master_key;\n    }\n    if (master_salt_length > 0) {\n        memset_volatile(master_salt, 0, master_salt_length);\n        master_salt_length = 0;\n        delete [] master_salt;\n    }\n    if (n_e > 0) {\n        memset_volatile(k_e, 0, n_e);\n        n_e = 0;\n        delete [] k_e;\n    }\n    if (n_s > 0) {\n        memset_volatile(k_s, 0, n_s);\n        n_s = 0;\n        delete [] k_s;\n    }\n    if (n_a > 0) {\n        n_a = 0;\n        memset_volatile(k_a, 0, n_a);\n        delete [] k_a;\n    }\n    if (cipher != NULL) {\n        delete cipher;\n        cipher = NULL;\n    }\n    if (f8Cipher != NULL) {\n        delete f8Cipher;\n        f8Cipher = NULL;\n    }\n}\n\nvoid CryptoContextCtrl::srtcpEncrypt( uint8_t* rtp, int32_t len, uint32_t index, uint32_t ssrc )\n{\n    if (ealg == SrtpEncryptionNull) {\n        return;\n    }\n    if (ealg == SrtpEncryptionAESCM || ealg == SrtpEncryptionTWOCM) {\n\n        /* Compute the CM IV (refer to chapter 4.1.1 in RFC 3711):\n        *\n        * k_s   XX XX XX XX XX XX XX XX XX XX XX XX XX XX\n        * SSRC              XX XX XX XX\n        * index                               XX XX XX XX\n        * ------------------------------------------------------XOR\n        * IV    XX XX XX XX XX XX XX XX XX XX XX XX XX XX 00 00\n        *        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15\n        */\n        unsigned char iv[16];\n\n        iv[0] = k_s[0];\n        iv[1] = k_s[1];\n        iv[2] = k_s[2];\n        iv[3] = k_s[3];\n\n        // The shifts transform the ssrc and index into network order\n        iv[4] = ((ssrc >> 24) & 0xff) ^ k_s[4];\n        iv[5] = ((ssrc >> 16) & 0xff) ^ k_s[5];\n        iv[6] = ((ssrc >> 8) & 0xff) ^ k_s[6];\n        iv[7] = (ssrc & 0xff) ^ k_s[7];\n\n        iv[8] = k_s[8];\n        iv[9] = k_s[9];\n\n        iv[10] = ((index >> 24) & 0xff) ^ k_s[10];\n        iv[11] = ((index >> 16) & 0xff) ^ k_s[11];\n        iv[12] = ((index >> 8) & 0xff) ^ k_s[12];\n        iv[13] = (index & 0xff) ^ k_s[13];\n\n        iv[14] = iv[15] = 0;\n\n        cipher->ctr_encrypt(rtp, len, iv);\n    }\n\n    if (ealg == SrtpEncryptionAESF8 || ealg == SrtpEncryptionTWOF8) {\n\n        unsigned char iv[16];\n\n        // 4 bytes of the iv are zero\n        // the first byte of the RTP header is not used.\n        iv[0] = 0;\n        iv[1] = 0;\n        iv[2] = 0;\n        iv[3] = 0;\n\n        // Need the encryption flag\n        index = index | 0x80000000;\n\n        // set the index and the encrypt flag in network order into IV\n        iv[4] = index >> 24;\n        iv[5] = index >> 16;\n        iv[6] = index >> 8;\n        iv[7] = index;\n\n        // The fixed header follows and fills the rest of the IV\n        memcpy(iv+8, rtp, 8);\n\n        cipher->f8_encrypt(rtp, len, iv, f8Cipher);\n    }\n}\n\n/* Warning: tag must have been initialized */\nvoid CryptoContextCtrl::srtcpAuthenticate(uint8_t* rtp, int32_t len, uint32_t index, uint8_t* tag )\n{\n    if (aalg == SrtpAuthenticationNull) {\n        return;\n    }\n    int32_t macL;\n\n    unsigned char temp[20];\n    const unsigned char* chunks[3];\n    unsigned int chunkLength[3];\n    uint32_t beIndex = zrtpHtonl(index);\n\n    chunks[0] = rtp;\n    chunkLength[0] = len;\n\n    chunks[1] = (unsigned char *)&beIndex;\n    chunkLength[1] = 4;\n    chunks[2] = NULL;\n\n    switch (aalg) {\n    case SrtpAuthenticationSha1Hmac:\n        hmacSha1Ctx(macCtx,\n                    chunks,           // data chunks to hash\n                    chunkLength,      // length of the data to hash\n                    temp, &macL);\n        /* truncate the result */\n        memcpy(tag, temp, getTagLength());\n        break;\n    case SrtpAuthenticationSkeinHmac:\n        macSkeinCtx(macCtx,\n                    chunks,           // data chunks to hash\n                    chunkLength,      // length of the data to hash\n                    temp);\n        /* truncate the result */\n        memcpy(tag, temp, getTagLength());\n        break;\n    }\n}\n\n/* used by the key derivation method */\nstatic void computeIv(unsigned char* iv, uint8_t label, uint8_t* master_salt)\n{\n    //printf( \"Key_ID: %llx\\n\", key_id );\n\n    /* compute the IV\n       key_id:                           XX XX XX XX XX XX XX\n       master_salt: XX XX XX XX XX XX XX XX XX XX XX XX XX XX\n       ------------------------------------------------------------ XOR\n       IV:          XX XX XX XX XX XX XX XX XX XX XX XX XX XX 00 00\n    */\n\n    memcpy(iv, master_salt, 14);\n    iv[7] ^= label;\n\n    iv[14] = iv[15] = 0;\n}\n\n/* Derives the srtp session keys from the master key */\nvoid CryptoContextCtrl::deriveSrtcpKeys()\n{\n    uint8_t iv[16];\n\n    // prepare cipher to compute derived keys.\n    cipher->setNewKey(master_key, master_key_length);\n    memset(master_key, 0, master_key_length);\n\n    // compute the session encryption key\n    uint8_t label = labelBase;\n    computeIv(iv, label, master_salt);\n    cipher->get_ctr_cipher_stream(k_e, n_e, iv);\n\n    // compute the session authentication key\n    label = labelBase + 1;\n    computeIv(iv, label, master_salt);\n    cipher->get_ctr_cipher_stream(k_a, n_a, iv);\n\n    // Initialize MAC context with the derived key\n    switch (aalg) {\n    case SrtpAuthenticationSha1Hmac:\n        initializeSha1HmacContext(macCtx, k_a, n_a);\n        break;\n    case SrtpAuthenticationSkeinHmac:\n        initializeSkeinMacContext(macCtx, k_a, n_a, tagLength*8, Skein512);  // Skein MAC uses number of bits as MAC size, not just bytes\n        break;\n    }\n    memset(k_a, 0, n_a);\n\n    // compute the session salt\n    label = labelBase + 2;\n    computeIv(iv, label, master_salt);\n    cipher->get_ctr_cipher_stream(k_s, n_s, iv);\n    memset(master_salt, 0, master_salt_length);\n\n    // as last step prepare cipher with derived key.\n    cipher->setNewKey(k_e, n_e);\n    if (f8Cipher != NULL)\n        cipher->f8_deriveForIV(f8Cipher, k_e, n_e, k_s, n_s);\n    memset(k_e, 0, n_e);\n}\n\nbool CryptoContextCtrl::checkReplay( uint32_t index )\n{\n    if ( aalg == SrtpAuthenticationNull && ealg == SrtpEncryptionNull ) {\n        /* No security policy, don't use the replay protection */\n        return true;\n    }\n\n    int64_t delta = index - s_l;\n    if (delta > 0) {\n        /* Packet not yet received*/\n        return true;\n    }\n    else {\n        if( -delta >= REPLAY_WINDOW_SIZE ) {\n            return false;       /* Packet too old */\n        }\n        else {\n            if((replay_window >> (-delta)) & 0x1) {\n                return false;   /* Packet already received ! */\n            }\n            else {\n                return true;    /* Packet not yet received */\n            }\n        }\n    }\n}\n\nvoid CryptoContextCtrl::update(uint32_t index)\n{\n    int64_t delta = index - s_l;\n\n    /* update the replay bitmask */\n    if( delta > 0 ){\n        replay_window = replay_window << delta;\n        replay_window |= 1;\n    }\n    else {\n        replay_window |= ( 1 << -delta );\n    }\n    if (index > s_l)\n        s_l = index;\n}\n\nCryptoContextCtrl* CryptoContextCtrl::newCryptoContextForSSRC(uint32_t ssrc)\n{\n    CryptoContextCtrl* pcc = new CryptoContextCtrl(\n            ssrc,\n            this->ealg,                              // encryption algo\n            this->aalg,                              // authentication algo\n            this->master_key,                        // Master Key\n            this->master_key_length,                 // Master Key length\n            this->master_salt,                       // Master Salt\n            this->master_salt_length,                // Master Salt length\n            this->ekeyl,                             // encryption keyl\n            this->akeyl,                             // authentication key len\n            this->skeyl,                             // session salt len\n            this->tagLength);                        // authentication tag len\n\n    return pcc;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/CryptoContextCtrl.h",
    "content": "/*\n  Copyright (C) 2011 - 2012 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\n*/\n\n#ifndef CRYPTOCONTEXTCTRL_H\n#define CRYPTOCONTEXTCTRL_H\n\n/**\n * @file CryptoContextCtrl.h\n * @brief The C++ SRTCP implementation\n * @ingroup Z_SRTP\n * @{\n */\n\n#include <crypto/hmac.h>\n#include <cryptcommon/macSkein.h>\n\nclass SrtpSymCrypto;\n\n/**\n * The implementation for a SRTCP cryptographic context.\n *\n * This class holds data and provides functions that implement a\n * cryptographic context for SRTCP, Refer to RFC 3711, chapter 3.2 for some\n * more detailed information about the SRTCP cryptographic context.\n *\n * Each SRTCP cryptographic context maintains a RTCP source identified by\n * its SSRC. Thus you can independently protect each source inside a RTP\n * session.\n *\n * Key management mechanisms negotiate the parameters for the SRTCP\n * cryptographic context, such as master key, key length, authentication\n * length and so on. The key management mechanisms are not part of\n * SRTCP. Refer to MIKEY (RFC 3880) or to Phil Zimmermann's ZRTP protocol\n * (RFC6189). After key management negotiated the data the application\n * can setup the SRTCP cryptographic context and enable SRTCP processing.\n *\n * @sa CryptoContext\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\nclass CryptoContextCtrl {\n    public:\n    /**\n     * @brief Constructor for an active SRTCP cryptographic context.\n     *\n     * This constructor creates an active SRTCP cryptographic context were\n     * algorithms are enabled, keys are computed and so on. This SRTCP\n     * cryptographic context can protect a RTCP SSRC stream.\n     *\n     * See the notes in CryptoContext documentation regarding the handling\n     * of key data.\n     *\n     * @param ssrc\n     *    The RTP SSRC that this SRTCP cryptographic context protects.\n     *\n     * @param ealg\n     *    The encryption algorithm to use. Possible values are <code>\n     *    SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8,\n     *    </code>. See chapter 4.1.1 for AESCM (Counter mode) and 4.1.2\n     *    for AES F8 mode.\n     *\n     * @param aalg\n     *    The authentication algorithm to use. Possible values are <code>\n     *    SrtpEncryptionNull, SrtpAuthenticationSha1Hmac, SrtpAuthenticationSkeinHmac\n     *    </code>.\n     *\n     * @param masterKey\n     *    Pointer to the master key for this SRTCP cryptographic context.\n     *    Must point to <code>masterKeyLength</code> bytes. Refer to chapter\n     *    3.2.1 of the RFC about the role of the master key.\n     *\n     * @param masterKeyLength\n     *    The length in bytes of the master key in bytes. The length must\n     *    match the selected encryption algorithm. Because SRTCP uses AES\n     *    based  encryption only, then master key length may be 16 or 32\n     *    bytes (128 or 256 bit master key)\n     *\n     * @param masterSalt\n     *    SRTCP uses the master salt to computer the initialization vector\n     *    that in turn is input to compute the session key, session\n     *    authentication key and the session salt.\n     *\n     * @param masterSaltLength\n     *    The length in bytes of the master salt data in bytes. SRTCP uses\n     *    AES as encryption algorithm. AES encrypts 16 byte blocks\n     *    (independent of the key length). According to RFC3711 the standard\n     *    value for the master salt length should be 112 bit (14 bytes).\n     *\n     * @param ekeyl\n     *    The length in bytes of the session encryption key that SRTCP shall\n     *    compute and use. Usually the same length as for the master key\n     *    length. But you may use a different length as well. Be carefull\n     *    that the key management mechanisms supports different key lengths.\n     *\n     * @param akeyl\n     *    The length in bytes of the session authentication key. SRTCP\n     *    computes this key and uses it as input to the authentication\n     *    algorithm.\n     *    The standard value is 160 bits (20 bytes).\n     *\n     * @param skeyl\n     *    The length in bytes of the session salt. SRTCP computes this salt\n     *    key and uses it as input during encryption. The length usually\n     *    is the same as the master salt length.\n     *\n     * @param tagLength\n     *    The length is bytes of the authentication tag that SRTCP appends\n     *    to the RTP packet. Refer to chapter 4.2. in the RFC 3711.\n     */\n    CryptoContextCtrl(uint32_t ssrc,\n               const  int32_t ealg,\n               const  int32_t aalg,\n               uint8_t* masterKey,\n               int32_t  masterKeyLength,\n               uint8_t* masterSalt,\n               int32_t  masterSaltLength,\n               int32_t  ekeyl,\n               int32_t  akeyl,\n               int32_t  skeyl,\n               int32_t  tagLength);\n\n    /**\n     * @brief Destructor.\n     *\n     * Cleans the SRTCP cryptographic context.\n     */\n    ~CryptoContextCtrl();\n\n    /**\n     * @brief Perform SRTCP encryption.\n     *\n     * This method encrypts <em>and</em> decrypts SRTCP payload data. Plain\n     * data gets encrypted, encrypted data get decrypted.\n     *\n     * @param rtp\n     *    The RTP packet that contains the data to encrypt.\n     *\n     * @param len\n     *    Length of the RTCP packet\n     *\n     * @param index\n     *    The 31 bit SRTCP packet index.\n     *\n     * @param ssrc\n     *    The RTCP SSRC data in <em>host</em> order.\n     */\n    void srtcpEncrypt(uint8_t* rtp, int32_t len, uint32_t index, uint32_t ssrc);\n\n    /**\n     * @brief Compute the authentication tag.\n     *\n     * Compute the authentication tag according the the paramters in the\n     * SRTCP Cryptograhic context.\n     *\n     * @param rtp\n     *    The RTCP packet that contains the data to authenticate.\n     *\n     * @param len\n     *    Length of the RTCP packet\n     *\n     * @param index\n     *    The 31 bit SRTCP index.\n     *\n     * @param tag\n     *    Points to a buffer that hold the computed tag. This buffer must\n     *    be able to hold <code>tagLength</code> bytes.\n     */\n    void srtcpAuthenticate(uint8_t* rtp, int32_t len, uint32_t index, uint8_t* tag);\n\n    /**\n     * @brief Perform key derivation according to SRTCP specification\n     *\n     * This method computes the session key, session authentication key and the\n     * session salt key. This method must be called at least once after the\n     * SRTCP cryptograhic context was set up.\n     *\n     * This method clears the key data once it was processed by the encryptions'\n     * set key functions.\n     *\n     */\n     void deriveSrtcpKeys();\n\n    /**\n     * @brief Check for packet replay.\n     *\n     * The method check if a received packet is either to old or was already\n     * received.\n     *\n     * The method supports a 64 packet history relative the the given\n     * sequence number.\n     *\n     * @param newSeqNumber\n     *    The sequence number of the received RTCP packet in host order.\n     *\n     * @return <code>true</code> if no replay, <code>false</code> if packet\n     *    is too old ar was already received.\n     */\n     bool checkReplay(uint32_t newSeqNumber);\n\n    /**\n     * @brief Update the SRTCP packet index.\n     *\n     * Call this method after all checks were successful. See chapter\n     * 3.3.1 in the RFC when to update the ROC and ROC processing.\n     *\n     * @param newSeqNumber\n     *    The sequence number of the received RTCP packet in host order.\n     */\n    void update(uint32_t newSeqNumber);\n\n    /**\n     * @brief Get the length of the SRTCP authentication tag in bytes.\n     *\n     * @return the length of the authentication tag.\n     */\n    inline int32_t getTagLength() const { return tagLength; }\n\n    /**\n     * @brief Get the length of the MKI in bytes.\n     *\n     * @return the length of the MKI.\n     */\n    inline int32_t getMkiLength() const { return mkiLength; }\n\n    /**\n     * @brief Get the SSRC of this SRTCP Cryptograhic context.\n     *\n     * @return the SSRC.\n     */\n    inline uint32_t getSsrc() const { return ssrcCtx; }\n\n    /**\n     * @brief Get the SRTCP index field of this SRTCP Cryptograhic context.\n     *\n     * @return the SRTCP.\n     */\n    uint32_t getSrtcpIndex() const { return srtcpIndex; }\n\n    /**\n     * @brief Set the SRTCP index field of this SRTCP Cryptograhic context.\n     *\n     * @param index the new SRTCP index value.\n     *\n     */\n    void setSrtcpIndex(uint32_t index) { srtcpIndex = index; }\n\n    /**\n     * @brief Set the start (base) number to compute the PRF labels.\n     *\n     * Refer to RFC3711, chapters 4.3.1 and 4.3.2 about values for labels.\n     * CryptoContextCtrl computes the labes as follows:\n     *\n     * - labelBase + 0 -> encryption label\n     * - labelBase + 1 -> authentication label\n     * - labelBase + 2 -> salting key label\n     *\n     * The CryptoContextCtrl constructor initializes CryptoContextCtrl#labelBase\n     * with 3 to comply with RFC 3711 label values.\n     *\n     * Applications may set #labelBase to other values to use CryptoContextCtrl\n     * for other purposes.\n     */\n    void setLabelbase(uint8_t base) { labelBase = base; }\n\n    /**\n     * @brief Derive a new Crypto Context for use with a new SSRC\n     *\n     * This method returns a new CryptoContextCtrl initialized with the data\n     * of this crypto context. The application can use this CryptoContextCtrl\n     * instance to encrypt / decrypt a new stream (Synchronization source) inside\n     * one RTCP session.\n     *\n     * Before the application can use this crypto context it must call deriveSrtcpKeys().\n     *\n     * @param ssrc\n     *     The SSRC for this context\n     *\n     * @return\n     *     a new CryptoContextCtrl with all relevant data set.\n     */\n    CryptoContextCtrl* newCryptoContextForSSRC(uint32_t ssrc);\n\n    private:\n        uint32_t ssrcCtx;\n        uint32_t mkiLength;\n        uint8_t* mki;\n\n        uint32_t s_l;\n\n        /* bitmask for replay check */\n        uint64_t replay_window;\n\n        uint8_t* master_key;\n        uint32_t master_key_length;\n        uint8_t* master_salt;\n        uint32_t master_salt_length;\n\n        /* Session Encryption, Authentication keys, Salt */\n        int32_t  n_e;\n        uint8_t* k_e;\n        int32_t  n_a;\n        uint8_t* k_a;\n        int32_t  n_s;\n        uint8_t* k_s;\n\n        int32_t ealg;\n        int32_t aalg;\n        int32_t ekeyl;\n        int32_t akeyl;\n        int32_t skeyl;\n        int32_t tagLength;\n        uint32_t srtcpIndex;\n        uint8_t labelBase;\n\n        void* macCtx;\n\n        SrtpSymCrypto* cipher;\n        SrtpSymCrypto* f8Cipher;\n    };\n\n/**\n * @}\n */\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/SrtpHandler.cpp",
    "content": "/*\n  Copyright (C) 2012 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\n*/\n\n/*\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n\n#include <common/osSpecifics.h>\n\n#include <SrtpHandler.h>\n#include <CryptoContext.h>\n#include <CryptoContextCtrl.h>\n\nbool SrtpHandler::decodeRtp(uint8_t* buffer, int32_t length, uint32_t *ssrc, uint16_t *seq, uint8_t** payload, int32_t *payloadlen)\n{\n    int offset;\n    uint16_t *pus;\n    uint32_t *pui;\n\n    /* Assume RTP header at the start of buffer. */\n\n    if ((*buffer & 0xC0) != 0x80) {         // check version bits\n        return false;\n    }\n    if (length < RTP_HEADER_LENGTH)\n        return false;\n\n    /* Get some handy pointers */\n    pus = (uint16_t*)buffer;\n    pui = (uint32_t*)buffer;\n\n    uint16_t tmp16 = pus[1];                    // get seq number\n    *seq = zrtpNtohs(tmp16);                        // and return in host oder\n\n    uint32_t tmp32 = pui[2];                    // get SSRC\n    *ssrc = zrtpNtohl(tmp32);                       // and return in host order\n\n    /* Payload is located right after header plus CSRC */\n    int32_t numCC = buffer[0] & 0x0f;           // lower 4 bits in first byte is num of contrib SSRC\n    offset = RTP_HEADER_LENGTH + (numCC * sizeof(uint32_t));\n\n    // Sanity check\n    if (offset > length)\n        return false;\n\n    /* Adjust payload offset if RTP extension is used. */\n    if ((*buffer & 0x10) == 0x10) {             // packet contains RTP extension\n        pus = (uint16_t*)(buffer + offset);     // pus points to extension as 16bit pointer\n        tmp16 = pus[1];                         // the second 16 bit word is the length\n        tmp16 = zrtpNtohs(tmp16);                   // to host order\n        offset += (tmp16 + 1) * sizeof(uint32_t);\n    }\n    /* Sanity check */\n    if (offset > length)\n        return false;\n\n    /* Set payload and payload length. */\n    *payload = buffer + offset;\n    *payloadlen = length - offset;\n\n    return true;\n}\n\nstatic void fillErrorData(SrtpErrorData* data, SrtpErrorType type, uint8_t* buffer, size_t length, uint64_t guessedIndex)\n{\n    data->errorType = type;\n    memcpy((void*)data->rtpHeader, (void*)buffer, RTP_HEADER_LENGTH);\n    data->length = length;\n    data->guessedIndex = guessedIndex;\n}\n\nbool SrtpHandler::protect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength)\n{\n    uint8_t* payload = NULL;\n    int32_t payloadlen = 0;\n    uint16_t seqnum;\n    uint32_t ssrc;\n\n\n    if (pcc == NULL) {\n        return false;\n    }\n    if (!decodeRtp(buffer, length, &ssrc, &seqnum, &payload, &payloadlen))\n        return false;\n\n    /* Encrypt the packet */\n    uint64_t index = ((uint64_t)pcc->getRoc() << 16) | (uint64_t)seqnum;\n\n    pcc->srtpEncrypt(buffer, payload, payloadlen, index, ssrc);\n\n    // NO MKI support yet - here we assume MKI is zero. To build in MKI\n    // take MKI length into account when storing the authentication tag.\n\n    /* Compute MAC and store at end of RTP packet data */\n    if (pcc->getTagLength() > 0) {\n        pcc->srtpAuthenticate(buffer, length, pcc->getRoc(), buffer+length);\n    }\n    *newLength = length + pcc->getTagLength();\n\n    /* Update the ROC if necessary */\n    if (seqnum == 0xFFFF ) {\n        pcc->setRoc(pcc->getRoc() + 1);\n    }\n    return true;\n}\n\nint32_t SrtpHandler::unprotect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength, SrtpErrorData* errorData)\n{\n    uint8_t* payload = NULL;\n    int32_t payloadlen = 0;\n    uint16_t seqnum;\n    uint32_t ssrc;\n\n    if (pcc == NULL) {\n        return 0;\n    }\n\n    if (!decodeRtp(buffer, length, &ssrc, &seqnum, &payload, &payloadlen)) {\n        if (errorData != NULL)\n            fillErrorData(errorData, DecodeError, buffer, length, 0);\n        return 0;\n    }\n    /*\n     * This is the setting of the packet data when we come to this point:\n     *\n     * length:      complete length of received data\n     * buffer:      points to data as received from network\n     * payloadlen:  length of data excluding hdrSize and padding\n     *\n     * Because this is an SRTP packet we need to adjust some values here.\n     * The SRTP MKI and authentication data is always at the end of a\n     * packet. Thus compute the positions of this data.\n     */\n    uint32_t srtpDataIndex = length - (pcc->getTagLength() + pcc->getMkiLength());\n\n    // Compute new length\n    length -= pcc->getTagLength() + pcc->getMkiLength();\n    *newLength = length;\n\n    // recompute payloadlen by subtracting SRTP data\n    payloadlen -= pcc->getTagLength() + pcc->getMkiLength();\n\n    // MKI is unused, so just skip it\n    // const uint8* mki = buffer + srtpDataIndex;\n    uint8_t* tag = buffer + srtpDataIndex + pcc->getMkiLength();\n\n    /* Guess the index */\n    uint64_t guessedIndex = pcc->guessIndex(seqnum);\n\n    /* Replay control */\n    if (!pcc->checkReplay(seqnum)) {\n        if (errorData != NULL)\n            fillErrorData(errorData, ReplayError, buffer, length, guessedIndex);\n        return -2;\n    }\n\n    if (pcc->getTagLength() > 0) {\n        uint32_t guessedRoc = guessedIndex >> 16;\n        uint8_t mac[20];\n\n        pcc->srtpAuthenticate(buffer, (uint32_t)length, guessedRoc, mac);\n        if (memcmp(tag, mac, pcc->getTagLength()) != 0) {\n            if (errorData != NULL)\n                fillErrorData(errorData, AuthError, buffer, length, guessedIndex);\n            return -1;\n        }\n    }\n    /* Decrypt the content */\n    pcc->srtpEncrypt(buffer, payload, payloadlen, guessedIndex, ssrc);\n\n    /* Update the Crypto-context */\n    pcc->update(seqnum);\n\n    return 1;\n}\n\n\nbool SrtpHandler::protectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength)\n{\n\n    if (pcc == NULL) {\n        return false;\n    }\n    /* Encrypt the packet */\n    uint32_t ssrc = *(reinterpret_cast<uint32_t*>(buffer + 4)); // always SSRC of sender\n    ssrc = zrtpNtohl(ssrc);\n\n    uint32_t encIndex = pcc->getSrtcpIndex();\n    pcc->srtcpEncrypt(buffer + 8, length - 8, encIndex, ssrc);\n\n    encIndex |= 0x80000000;                                     // set the E flag\n\n    // Fill SRTCP index as last word\n    uint32_t* ip = reinterpret_cast<uint32_t*>(buffer+length);\n    *ip = zrtpHtonl(encIndex);\n\n    // NO MKI support yet - here we assume MKI is zero. To build in MKI\n    // take MKI length into account when storing the authentication tag.\n\n    // Compute MAC and store in packet after the SRTCP index field\n    pcc->srtcpAuthenticate(buffer, length, encIndex, buffer + length + sizeof(uint32_t));\n\n    encIndex++;\n    encIndex &= ~0x80000000;                                // clear the E-flag and modulo 2^31\n    pcc->setSrtcpIndex(encIndex);\n    *newLength = length + pcc->getTagLength() + sizeof(uint32_t);\n\n    return true;\n}\n\nint32_t SrtpHandler::unprotectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength)\n{\n\n    if (pcc == NULL) {\n        return 0;\n    }\n\n    // Compute the total length of the payload\n    int32_t payloadLen = length - (pcc->getTagLength() + pcc->getMkiLength() + 4);\n    *newLength = payloadLen;\n\n    // point to the SRTCP index field just after the real payload\n    const uint32_t* index = reinterpret_cast<uint32_t*>(buffer + payloadLen);\n\n    uint32_t encIndex = zrtpNtohl(*index);\n    uint32_t remoteIndex = encIndex & ~0x80000000;    // get index without Encryption flag\n\n    if (!pcc->checkReplay(remoteIndex)) {\n       return -2;\n    }\n\n    uint8_t mac[20];\n\n    // Now get a pointer to the authentication tag field\n    const uint8_t* tag = buffer + (length - pcc->getTagLength());\n\n    // Authenticate includes the index, but not MKI and not (obviously) the tag itself\n    pcc->srtcpAuthenticate(buffer, payloadLen, encIndex, mac);\n    if (memcmp(tag, mac, pcc->getTagLength()) != 0) {\n        return -1;\n    }\n\n    uint32_t ssrc = *(reinterpret_cast<uint32_t*>(buffer + 4)); // always SSRC of sender\n    ssrc = zrtpNtohl(ssrc);\n\n    // Decrypt the content, exclude the very first SRTCP header (fixed, 8 bytes)\n    if (encIndex & 0x80000000)\n        pcc->srtcpEncrypt(buffer + 8, payloadLen - 8, remoteIndex, ssrc);\n\n    // Update the Crypto-context\n    pcc->update(remoteIndex);\n\n    return 1;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/SrtpHandler.h",
    "content": "/*\n  Copyright (C) 2012 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\n*/\n\n#ifndef _SRTPHANDLER_H_\n#define _SRTPHANDLER_H_\n\n#include <stdint.h>\n#include <libzrtpcpp/ZrtpCodes.h>\n\nclass CryptoContext;\nclass CryptoContextCtrl;\n\n/**\n * @brief SRTP and SRTCP protect and unprotect functions.\n *\n * The static methods take SRTP or SRTCP crypto contexts, a pointer uint8_t buffer\n * that must contain an RTP/SRTP packet and perform the actions necessary to protect\n * the RTP/RTCP packet or to unprotect the SRTP/SRTCP packet.\n * \n * The methods assume that the buffer contains all protocol relevant fields (SSRC,\n * sequence number etc.) in network order.\n *\n * When encrypting the buffer must be big enough to store additional data, usually\n * 4 - 14 bytes, depending on how the application configured the authentication parameters.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\nclass SrtpHandler\n{\npublic:\n    /**\n     * @brief Protect an RTP packet.\n     *\n     * @param pcc the SRTP CryptoContext instance\n     *\n     * @param buffer the RTP packet to protect\n     *\n     * @param length the length of the RTP packet data in bytes\n     *\n     * @param newLength the length of the resulting SRTP packet data in bytes\n     *\n     * @return @c true if protection was successful, @c false otherwise\n     */\n    static bool protect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength);\n\n    /**\n     * @brief Unprotect a SRTP packet.\n     * \n     * If the @c errorData pointer is not @c NULL then this function fills the data structure\n     * in case of an error return. The caller may store and evaluate this data to further\n     * trace the problem.\n     *\n     * @param pcc the SRTP CryptoContext instance\n     *\n     * @param buffer the SRTP packet to unprotect\n     *\n     * @param length the length of the SRTP packet data in bytes\n     *\n     * @param newLength the length of the resulting RTP packet data in bytes\n     * \n     * @param errorData Pointer to @c errorData structure or @c NULL, default is @c NULL\n     *\n     * @return an integer value\n     *         - 1 - success\n     *         - 0 - SRTP/RTP packet decode error\n     *         - -1 - SRTP authentication failed\n     *         - -2 - SRTP replay check failed\n     */\n    static int32_t unprotect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength, SrtpErrorData* errorData=NULL);\n\n    /**\n     * @brief Protect an RTCP packet.\n     *\n     * @param pcc the SRTCP CryptoContextCtrl instance\n     *\n     * @param buffer the RTCP packet to protect\n     *\n     * @param length the length of the RTCP packet data in bytes\n     *\n     * @param newLength the length of the resulting SRTCP packet data in bytes\n     *\n     * @return @c true if protection was successful, @c false otherwise\n     */\n    static bool protectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength);\n\n    /**\n     * @brief Unprotect a SRTCP packet.\n     *\n     * @param pcc the SRTCP CryptoContextCtrl instance\n     *\n     * @param buffer the SRTCP packet to unprotect\n     *\n     * @param length the length of the SRTCP packet data in bytes\n     *\n     * @param newLength the length of the resulting RTCP packet data in bytes\n     *\n     * @return an integer value\n     *         - 0 - illegal packet (too short, not a valid RTP header byte), dismiss it\n     *         - 1 - success\n     *         - -1 - SRTCP authentication failed\n     *         - -2 - SRTCP replay check failed\n     */\n    static int32_t unprotectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength);\n\nprivate:\n    static bool decodeRtp(uint8_t* buffer, int32_t length, uint32_t *ssrc, uint16_t *seq, uint8_t** payload, int32_t *payloadlen);\n\n};\n#endif // _SRTPHANDLER_H_"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/crypto/SrtpSymCrypto.cpp",
    "content": "/*\n  Copyright (C) 2012 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  * In addition, as a special exception, the copyright holders give\n  * permission to link the code of portions of this program with the\n  * OpenSSL library under certain conditions as described in each\n  * individual source file, and distribute linked combinations\n  * including the two.\n  * You must obey the GNU General Public License in all respects\n  * for all of the code used other than OpenSSL.  If you modify\n  * file(s) with this exception, you may extend this exception to your\n  * version of the file(s), but you are not obligated to do so.  If you\n  * do not wish to do so, delete this exception statement from your\n  * version.  If you delete this exception statement from all source\n  * files in the program, then also delete it here.\n  */\n\n/**\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#define MAKE_F8_TEST\n\n#include <stdlib.h>\n#include <crypto/SrtpSymCrypto.h>\n#include <cryptcommon/twofish.h>\n#include <cryptcommon/aesopt.h>\n#include <string.h>\n#include <stdio.h>\n#include <common/osSpecifics.h>\n\nSrtpSymCrypto::SrtpSymCrypto(int algo):key(NULL), algorithm(algo) {\n}\n\nSrtpSymCrypto::SrtpSymCrypto( uint8_t* k, int32_t keyLength, int algo):\n    key(NULL), algorithm(algo) {\n\n    setNewKey(k, keyLength);\n}\n\nSrtpSymCrypto::~SrtpSymCrypto() {\n    if (key != NULL) {\n        if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {\n            AESencrypt *saAes = reinterpret_cast<AESencrypt*>(key);\n            memset(saAes->cx, 0, sizeof(aes_encrypt_ctx));\n            delete saAes;\n        }\n        else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {\n            memset(key, 0, sizeof(Twofish_key));\n            delete[] (uint8_t*)key;\n        }\n        key = NULL;\n    }\n}\n\nstatic int twoFishInit = 0;\n\nbool SrtpSymCrypto::setNewKey(const uint8_t* k, int32_t keyLength) {\n    // release an existing key before setting a new one\n    if (key != NULL) {\n        if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {\n            AESencrypt *saAes = reinterpret_cast<AESencrypt*>(key);\n            memset(saAes->cx, 0, sizeof(aes_encrypt_ctx));\n            delete saAes;\n        }\n        else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {\n            memset(key, 0, sizeof(Twofish_key));\n            delete[] (uint8_t*)key;\n        }\n        key = NULL;\n    }\n\n    if (!(keyLength == 16 || keyLength == 32)) {\n        return false;\n    }\n    if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {\n        AESencrypt *saAes = new AESencrypt();\n        if (keyLength == 16)\n            saAes->key128(k);\n        else\n            saAes->key256(k);\n        key = saAes;\n    }\n    else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {\n        if (!twoFishInit) {\n            Twofish_initialise();\n            twoFishInit = 1;\n        }\n        key = new uint8_t[sizeof(Twofish_key)];\n        memset(key, 0, sizeof(Twofish_key));\n        Twofish_prepare_key((Twofish_Byte*)k, keyLength,  (Twofish_key*)key);\n    }\n    else\n        return false;\n\n    return true;\n}\n\nvoid SrtpSymCrypto::encrypt(const uint8_t* input, uint8_t* output) {\n    if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {\n        AESencrypt *saAes = reinterpret_cast<AESencrypt*>(key);\n        saAes->encrypt(input, output);\n    }\n    else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {\n        Twofish_encrypt((Twofish_key*)key, (Twofish_Byte*)input,\n                        (Twofish_Byte*)output); \n    }\n}\n\nvoid SrtpSymCrypto::get_ctr_cipher_stream(uint8_t* output, uint32_t length, uint8_t* iv) {\n    uint16_t ctr = 0;\n    unsigned char temp[SRTP_BLOCK_SIZE];\n\n    for(ctr = 0; ctr < length/SRTP_BLOCK_SIZE; ctr++) {\n        //compute the cipher stream\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, &output[ctr*SRTP_BLOCK_SIZE]);\n    }\n    if ((length % SRTP_BLOCK_SIZE) > 0) {\n        // Treat the last bytes:\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        memcpy(&output[ctr*SRTP_BLOCK_SIZE], temp, length % SRTP_BLOCK_SIZE );\n    }\n}\n\nvoid SrtpSymCrypto::ctr_encrypt(const uint8_t* input, uint32_t input_length, uint8_t* output, uint8_t* iv) {\n\n    if (key == NULL)\n        return;\n\n    uint16_t ctr = 0;\n    unsigned char temp[SRTP_BLOCK_SIZE];\n\n    int l = input_length/SRTP_BLOCK_SIZE;\n    for (ctr = 0; ctr < l; ctr++ ) {\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        for (int i = 0; i < SRTP_BLOCK_SIZE; i++ ) {\n            *output++ = temp[i] ^ *input++;\n        }\n\n    }\n    l = input_length % SRTP_BLOCK_SIZE;\n    if (l > 0) {\n        // Treat the last bytes:\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        for (int i = 0; i < l; i++ ) {\n            *output++ = temp[i] ^ *input++;\n        }\n    }\n}\n\nvoid SrtpSymCrypto::ctr_encrypt( uint8_t* data, uint32_t data_length, uint8_t* iv ) {\n\n    if (key == NULL)\n        return;\n\n    uint16_t ctr = 0;\n    unsigned char temp[SRTP_BLOCK_SIZE];\n\n    int l = data_length/SRTP_BLOCK_SIZE;\n    for (ctr = 0; ctr < l; ctr++ ) {\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        for (int i = 0; i < SRTP_BLOCK_SIZE; i++ ) {\n            *data++ ^= temp[i];\n        }\n\n    }\n    l = data_length % SRTP_BLOCK_SIZE;\n    if (l > 0) {\n        // Treat the last bytes:\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        for (int i = 0; i < l; i++ ) {\n            *data++ ^= temp[i];\n        }\n    }\n}\n\nvoid SrtpSymCrypto::f8_encrypt(const uint8_t* data, uint32_t data_length,\n                         uint8_t* iv, SrtpSymCrypto* f8Cipher ) {\n\n    f8_encrypt(data, data_length, const_cast<uint8_t*>(data), iv, f8Cipher);\n}\n\n#define MAX_KEYLEN 32\n\nvoid SrtpSymCrypto::f8_deriveForIV(SrtpSymCrypto* f8Cipher, uint8_t* key, int32_t keyLen,\n             uint8_t* salt, int32_t saltLen) {\n\n    unsigned char *cp_in, *cp_in1, *cp_out;\n\n    unsigned char maskedKey[MAX_KEYLEN];\n    unsigned char saltMask[MAX_KEYLEN];\n\n    if (keyLen > MAX_KEYLEN)\n        return;\n\n    if (saltLen > keyLen)\n        return;\n    /*\n     * First copy the salt into the mask field, then fill with 0x55 to\n     * get a full key.\n     */\n    memcpy(saltMask, salt, saltLen);\n    memset(saltMask+saltLen, 0x55, keyLen-saltLen);\n\n    /*\n     * XOR the original key with the above created mask to\n     * get the special key.\n     */\n    cp_out = maskedKey;\n    cp_in = key;\n    cp_in1 = saltMask;\n    for (int i = 0; i < keyLen; i++) {\n        *cp_out++ = *cp_in++ ^ *cp_in1++;\n    }\n    /*\n     * Prepare the a new AES cipher with the special key to compute IV'\n     */\n    f8Cipher->setNewKey(maskedKey, keyLen);\n}\n\nvoid SrtpSymCrypto::f8_encrypt(const uint8_t* in, uint32_t in_length, uint8_t* out,\n                         uint8_t* iv, SrtpSymCrypto* f8Cipher ) {\n\n\n    int offset = 0;\n\n    unsigned char ivAccent[SRTP_BLOCK_SIZE];\n    unsigned char S[SRTP_BLOCK_SIZE];\n\n    F8_CIPHER_CTX f8ctx;\n\n    if (key == NULL)\n        return;\n    /*\n     * Get memory for the derived IV (IV')\n     */\n    f8ctx.ivAccent = ivAccent;\n    /*\n     * Use the derived IV encryption setup to encrypt the original IV to produce IV'.\n     */\n    f8Cipher->encrypt(iv, f8ctx.ivAccent);\n\n    f8ctx.J = 0;                       // initialize the counter\n    f8ctx.S = S;               // get the key stream buffer\n\n    memset(f8ctx.S, 0, SRTP_BLOCK_SIZE); // initial value for key stream\n\n    while (in_length >= SRTP_BLOCK_SIZE) {\n        processBlock(&f8ctx, in+offset, SRTP_BLOCK_SIZE, out+offset);\n        in_length -= SRTP_BLOCK_SIZE;\n        offset += SRTP_BLOCK_SIZE;\n    }\n    if (in_length > 0) {\n        processBlock(&f8ctx, in+offset, in_length, out+offset);\n    }\n}\n\nint SrtpSymCrypto::processBlock(F8_CIPHER_CTX *f8ctx, const uint8_t* in, int32_t length, uint8_t* out) {\n\n    int i;\n    const uint8_t *cp_in;\n    uint8_t* cp_in1, *cp_out;\n    uint32_t *ui32p;\n\n    /*\n     * XOR the previous key stream with IV'\n     * ( S(-1) xor IV' )\n     */\n    cp_in = f8ctx->ivAccent;\n    cp_out = f8ctx->S;\n    for (i = 0; i < SRTP_BLOCK_SIZE; i++) {\n        *cp_out++ ^= *cp_in++;\n    }\n    /*\n     * Now XOR (S(n-1) xor IV') with the current counter, then increment the counter\n     */\n    ui32p = (uint32_t *)f8ctx->S;\n    ui32p[3] ^= zrtpHtonl(f8ctx->J);\n    f8ctx->J++;\n    /*\n     * Now compute the new key stream using AES encrypt\n     */\n    encrypt(f8ctx->S, f8ctx->S);\n    /*\n     * as the last step XOR the plain text with the key stream to produce\n     * the ciphertext.\n     */\n    cp_out = out;\n    cp_in = in;\n    cp_in1 = f8ctx->S;\n    for (i = 0; i < length; i++) {\n        *cp_out++ = *cp_in++ ^ *cp_in1++;\n    }\n    return length;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/crypto/SrtpSymCrypto.h",
    "content": "/*\r\n  Copyright (C) 2008-2012 Werner Dittmann\r\n\r\n  This library is free software; you can redistribute it and/or\r\n  modify it under the terms of the GNU Lesser General Public\r\n  License as published by the Free Software Foundation; either\r\n  version 2.1 of the License, or (at your option) any later version.\r\n\r\n  This library is distributed in the hope that it will be useful,\r\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n  Lesser General Public License for more details.\r\n\r\n  You should have received a copy of the GNU Lesser General Public\r\n  License along with this library; if not, write to the Free Software\r\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r\n\r\n * In addition, as a special exception, the copyright holders give\r\n * permission to link the code of portions of this program with the\r\n * OpenSSL library under certain conditions as described in each\r\n * individual source file, and distribute linked combinations\r\n * including the two.\r\n * You must obey the GNU General Public License in all respects\r\n * for all of the code used other than OpenSSL.  If you modify\r\n * file(s) with this exception, you may extend this exception to your\r\n * version of the file(s), but you are not obligated to do so.  If you\r\n * do not wish to do so, delete this exception statement from your\r\n * version.  If you delete this exception statement from all source\r\n * files in the program, then also delete it here.\r\n*/\r\n\r\n\r\n\r\n#ifndef SRTPSYMCRYPTO_H\r\n#define SRTPSYMCRYPTO_H\r\n\r\n/**\r\n * @file SrtpSymCrypto.h\r\n * @brief Class which implements SRTP cryptographic functions\r\n * \r\n * @ingroup GNU_ZRTP\r\n * @{\r\n */\r\n\r\n#include <stdint.h>\r\n#include <CryptoContext.h>\r\n\r\n#ifndef SRTP_BLOCK_SIZE\r\n#define SRTP_BLOCK_SIZE 16\r\n#endif\r\n\r\ntypedef struct _f8_ctx {\r\n    unsigned char *S;           ///< Intermetiade buffer\r\n    unsigned char *ivAccent;    ///< second IV\r\n    uint32_t J;                 ///< Counter\r\n} F8_CIPHER_CTX;\r\n\r\n/**\r\n * @brief Implments the SRTP encryption modes as defined in RFC3711\r\n *\r\n * The SRTP specification defines two encryption modes, AES-CTR\r\n * (AES Counter mode) and AES-F8 mode. The AES-CTR is required,\r\n * AES-F8 is optional.\r\n *\r\n * Both modes are desinged to encrypt/decrypt data of arbitrary length\r\n * (with a specified upper limit, refer to RFC 3711). These modes do\r\n * <em>not</em> require that the amount of data to encrypt is a multiple\r\n * of the AES blocksize (16 bytes), no padding is necessary.\r\n *\r\n * The implementation uses the openSSL library as its cryptographic\r\n * backend.\r\n *\r\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\r\n */\r\nclass SrtpSymCrypto {\r\npublic:\r\n    /**\r\n     * @brief Constructor that does not initialize key data\r\n     *\r\n     * @param algo\r\n     *    The Encryption algorithm to use.Possible values are <code>\r\n     *    SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8\r\n     *    SrtpEncryptionTWOCM, SrtpEncryptionTWOF8</code>. See chapter 4.1.1\r\n     *    for CM (Counter mode) and 4.1.2 for F8 mode.\r\n     */\r\n    SrtpSymCrypto(int algo = SrtpEncryptionAESCM);\r\n\r\n    /**\r\n     * @brief Constructor that initializes key data\r\n     * \r\n     * @param key\r\n     *     Pointer to key bytes.\r\n     * @param key_length\r\n     *     Number of key bytes.\r\n     * @param algo\r\n     *    The Encryption algorithm to use.Possible values are <code>\r\n     *    SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8\r\n     *    SrtpEncryptionTWOCM, SrtpEncryptionTWOF8</code>. See chapter 4.1.1\r\n     *    for CM (Counter mode) and 4.1.2 for F8 mode.\r\n     */\r\n    SrtpSymCrypto(uint8_t* key, int32_t key_length, int algo = SrtpEncryptionAESCM);\r\n\r\n    ~SrtpSymCrypto();\r\n\r\n    /**\r\n     * @brief Encrypts the input to the output.\r\n     *\r\n     * Encrypts one input block to one output block. Each block\r\n     * is 16 bytes according to the encryption algorithms used.\r\n     *\r\n     * @param input\r\n     *    Pointer to input block, must be 16 bytes\r\n     *\r\n     * @param output\r\n     *    Pointer to output block, must be 16 bytes\r\n     */\r\n    void encrypt( const uint8_t* input, uint8_t* output );\r\n\r\n    /**\r\n     * @brief Set new key\r\n     *\r\n     * @param key\r\n     *   Pointer to key data, must have at least a size of keyLength \r\n     *\r\n     * @param keyLength\r\n     *   Length of the key in bytes, must be 16, 24, or 32\r\n     *\r\n     * @return\r\n     *   false if key could not set.\r\n     */\r\n    bool setNewKey(const uint8_t* key, int32_t keyLength);\r\n\r\n    /**\r\n     * @brief Computes the cipher stream for AES CM mode.\r\n     *\r\n     * @param output\r\n     *    Pointer to a buffer that receives the cipher stream. Must be\r\n     *    at least <code>length</code> bytes long.\r\n     *\r\n     * @param length\r\n     *    Number of cipher stream bytes to produce. Usually the same\r\n     *    length as the data to be encrypted.\r\n     *\r\n     * @param iv\r\n     *    The initialization vector as input to create the cipher stream.\r\n     *    Refer to chapter 4.1.1 in RFC 3711.\r\n     */\r\n    void get_ctr_cipher_stream(uint8_t* output, uint32_t length, uint8_t* iv);\r\n\r\n    /**\r\n     * @brief Counter-mode encryption.\r\n     *\r\n     * This method performs the CM encryption.\r\n     *\r\n     * @param input\r\n     *    Pointer to input buffer, must be <code>inputLen</code> bytes.\r\n     *\r\n     * @param inputLen\r\n     *    Number of bytes to process.\r\n     *\r\n     * @param output\r\n     *    Pointer to output buffer, must be <code>inputLen</code> bytes.\r\n     *\r\n     * @param iv\r\n     *    The initialization vector as input to create the cipher stream.\r\n     *    Refer to chapter 4.1.1 in RFC 3711.\r\n     */\r\n    void ctr_encrypt(const uint8_t* input, uint32_t inputLen, uint8_t* output, uint8_t* iv );\r\n\r\n    /**\r\n     * @brief Counter-mode encryption, in place.\r\n     *\r\n     * This method performs the CM encryption.\r\n     *\r\n     * @param data\r\n     *    Pointer to input and output block, must be <code>dataLen</code>\r\n     *    bytes.\r\n     *\r\n     * @param data_length\r\n     *    Number of bytes to process.\r\n     *\r\n     * @param iv\r\n     *    The initialization vector as input to create the cipher stream.\r\n     *    Refer to chapter 4.1.1 in RFC 3711.\r\n     */\r\n    void ctr_encrypt(uint8_t* data, uint32_t data_length, uint8_t* iv );\r\n\r\n    /**\r\n     * @brief Derive a cipher context to compute the IV'.\r\n     *\r\n     * See chapter 4.1.2.1 in RFC 3711.\r\n     *\r\n     * @param f8Cipher\r\n     *    Pointer to the cipher context that will be used to encrypt IV to IV'\r\n     *\r\n     * @param key\r\n     *    The master key\r\n     *\r\n     * @param keyLen\r\n     *    Length of the master key.\r\n     *\r\n     * @param salt\r\n     *   Master salt.\r\n     *\r\n     * @param saltLen\r\n     *   length of master salt.\r\n     */\r\n    void f8_deriveForIV(SrtpSymCrypto* f8Cipher, uint8_t* key, int32_t keyLen, uint8_t* salt, int32_t saltLen);\r\n\r\n    /**\r\n     * @brief F8 mode encryption, in place.\r\n     *\r\n     * This method performs the F8 encryption, see chapter 4.1.2 in RFC 3711.\r\n     *\r\n     * @param data\r\n     *    Pointer to input and output block, must be <code>dataLen</code>\r\n     *    bytes.\r\n     *\r\n     * @param dataLen\r\n     *    Number of bytes to process.\r\n     *\r\n     * @param iv\r\n     *    The initialization vector as input to create the cipher stream.\r\n     *    Refer to chapter 4.1.1 in RFC 3711.\r\n     *\r\n     * @param f8Cipher\r\n     *   An AES cipher context used to encrypt IV to IV'.\r\n     */\r\n    void f8_encrypt(const uint8_t* data, uint32_t dataLen, uint8_t* iv, SrtpSymCrypto* f8Cipher);\r\n\r\n    /**\r\n     * @brief F8 mode encryption.\r\n     *\r\n     * This method performs the F8 encryption, see chapter 4.1.2 in RFC 3711.\r\n     *\r\n     * @param data\r\n     *    Pointer to input and output block, must be <code>dataLen</code>\r\n     *    bytes.\r\n     *\r\n     * @param dataLen\r\n     *    Number of bytes to process.\r\n     *\r\n     * @param out\r\n     *    Pointer to output buffer, must be <code>dataLen</code> bytes.\r\n     *\r\n     * @param iv\r\n     *    The initialization vector as input to create the cipher stream.\r\n     *    Refer to chapter 4.1.1 in RFC 3711.\r\n     *\r\n     * @param f8Cipher\r\n     *   An AES cipher context used to encrypt IV to IV'.\r\n     */\r\n    void f8_encrypt(const uint8_t* data, uint32_t dataLen, uint8_t* out, uint8_t* iv, SrtpSymCrypto* f8Cipher);\r\n\r\nprivate:\r\n    int processBlock(F8_CIPHER_CTX* f8ctx, const uint8_t* in, int32_t length, uint8_t* out);\r\n    void* key;\r\n    int32_t algorithm;\r\n};\r\n\r\n#pragma GCC visibility push(default)\r\nint testF8();\r\n#pragma GCC visibility pop\r\n\r\n/* Only SrtpSymCrypto functions defines the MAKE_F8_TEST */\r\n#ifdef MAKE_F8_TEST\r\n\r\n#include <cstring>\r\n#include <iostream>\r\n#include <cstdio>\r\n#include <common/osSpecifics.h>\r\n\r\nusing namespace std;\r\n\r\nstatic void hexdump(const char* title, const unsigned char *s, int l)\r\n{\r\n    int n=0;\r\n\r\n    if (s == NULL) return;\r\n\r\n    fprintf(stderr, \"%s\",title);\r\n    for( ; n < l ; ++n) {\r\n        if((n%16) == 0)\r\n            fprintf(stderr, \"\\n%04x\",n);\r\n        fprintf(stderr, \" %02x\",s[n]);\r\n    }\r\n    fprintf(stderr, \"\\n\");\r\n}\r\n\r\n/*\r\n * The F8 test vectors according to RFC3711\r\n */\r\nstatic unsigned char salt[] = {0x32, 0xf2, 0x87, 0x0d};\r\n\r\nstatic unsigned char iv[] = {  0x00, 0x6e, 0x5c, 0xba, 0x50, 0x68, 0x1d, 0xe5,\r\n                        0x5c, 0x62, 0x15, 0x99, 0xd4, 0x62, 0x56, 0x4a};\r\n\r\nstatic unsigned char key[]= {  0x23, 0x48, 0x29, 0x00, 0x84, 0x67, 0xbe, 0x18,\r\n                        0x6c, 0x3d, 0xe1, 0x4a, 0xae, 0x72, 0xd6, 0x2c};\r\n\r\nstatic unsigned char payload[] = {\r\n                        0x70, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x72, 0x61,\r\n                        0x6e, 0x64, 0x6f, 0x6d, 0x6e, 0x65, 0x73, 0x73,\r\n                        0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,\r\n                        0x6e, 0x65, 0x78, 0x74, 0x20, 0x62, 0x65, 0x73,\r\n                        0x74, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67};  // 39 bytes\r\n\r\nstatic unsigned char cipherText[] = {\r\n                        0x01, 0x9c, 0xe7, 0xa2, 0x6e, 0x78, 0x54, 0x01,\r\n                        0x4a, 0x63, 0x66, 0xaa, 0x95, 0xd4, 0xee, 0xfd,\r\n                        0x1a, 0xd4, 0x17, 0x2a, 0x14, 0xf9, 0xfa, 0xf4,\r\n                        0x55, 0xb7, 0xf1, 0xd4, 0xb6, 0x2b, 0xd0, 0x8f,\r\n                        0x56, 0x2c, 0x0e, 0xef, 0x7c, 0x48, 0x02}; // 39 bytes\r\n\r\n// static unsigned char rtpPacketHeader[] = {\r\n//                         0x80, 0x6e, 0x5c, 0xba, 0x50, 0x68, 0x1d, 0xe5,\r\n//                         0x5c, 0x62, 0x15, 0x99};\r\n\r\nstatic unsigned char rtpPacket[] = {\r\n                    0x80, 0x6e, 0x5c, 0xba, 0x50, 0x68, 0x1d, 0xe5,\r\n                    0x5c, 0x62, 0x15, 0x99,                        // header\r\n                    0x70, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x72, 0x61, // payload\r\n                    0x6e, 0x64, 0x6f, 0x6d, 0x6e, 0x65, 0x73, 0x73,\r\n                    0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,\r\n                    0x6e, 0x65, 0x78, 0x74, 0x20, 0x62, 0x65, 0x73,\r\n                    0x74, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67};\r\nstatic uint32_t ROC = 0xd462564a;\r\n\r\nint testF8()\r\n{\r\n    SrtpSymCrypto* aesCipher = new SrtpSymCrypto(SrtpEncryptionAESF8);\r\n    SrtpSymCrypto* f8AesCipher = new SrtpSymCrypto(SrtpEncryptionAESF8);\r\n\r\n    aesCipher->setNewKey(key, sizeof(key));\r\n\r\n    /* Create the F8 IV (refer to chapter 4.1.2.2 in RFC 3711):\r\n     *\r\n     * IV = 0x00 || M || PT || SEQ  ||      TS    ||    SSRC   ||    ROC\r\n     *      8Bit  1bit  7bit  16bit       32bit        32bit        32bit\r\n     * ------------\\     /--------------------------------------------------\r\n     *       XX       XX      XX XX   XX XX XX XX   XX XX XX XX  XX XX XX XX\r\n     */\r\n\r\n    unsigned char derivedIv[16];\r\n    uint32_t* ui32p = (uint32_t*)derivedIv;\r\n\r\n    memcpy(derivedIv, rtpPacket, 12);\r\n    derivedIv[0] = 0;\r\n\r\n    // set ROC in network order into IV\r\n    ui32p[3] = zrtpHtonl(ROC);\r\n\r\n    int32_t pad = 0;\r\n\r\n    if (memcmp(iv, derivedIv, 16) != 0) {\r\n        cerr << \"Wrong IV constructed\" << endl;\r\n        hexdump(\"derivedIv\", derivedIv, 16);\r\n        hexdump(\"test vector Iv\", iv, 16);\r\n        return -1;\r\n    }\r\n\r\n    aesCipher->f8_deriveForIV(f8AesCipher, key, sizeof(key), salt, sizeof(salt));\r\n\r\n    // now encrypt the RTP payload data\r\n    aesCipher->f8_encrypt(rtpPacket + 12, sizeof(rtpPacket)-12+pad,\r\n        derivedIv, f8AesCipher);\r\n\r\n    // compare with test vector cipher data\r\n    if (memcmp(rtpPacket+12, cipherText, sizeof(rtpPacket)-12+pad) != 0) {\r\n        cerr << \"cipher data mismatch\" << endl;\r\n        hexdump(\"computed cipher data\", rtpPacket+12, sizeof(rtpPacket)-12+pad);\r\n        hexdump(\"Test vcetor cipher data\", cipherText, sizeof(cipherText));\r\n        return -1;\r\n    }\r\n\r\n    // Now decrypt the data to get the payload data again\r\n    aesCipher->f8_encrypt(rtpPacket+12, sizeof(rtpPacket)-12+pad, derivedIv, f8AesCipher);\r\n\r\n    // compare decrypted data with test vector payload data\r\n    if (memcmp(rtpPacket+12, payload, sizeof(rtpPacket)-12+pad) != 0) {\r\n        cerr << \"payload data mismatch\" << endl;\r\n        hexdump(\"computed payload data\", rtpPacket+12, sizeof(rtpPacket)-12+pad);\r\n        hexdump(\"Test vector payload data\", payload, sizeof(payload));\r\n        return -1;\r\n    }\r\n    return 0;\r\n}\r\n#endif\r\n\r\n/**\r\n * @}\r\n */\r\n\r\n#endif\r\n\r\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/crypto/gcrypt/InitializeGcrypt.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <stdio.h>\n\n#include <string.h>\n#include <pthread.h>\n#include <errno.h>\n#include <gcrypt.h>\n\n/*\n * The following macro was copied from gcrypt.h and modified to explicitly\n * cast the pointer types to keep the compiler happy.\n */\n#define GCRY_THREAD_OPTION_PTHREAD_CPP_IMPL                                   \\\nstatic int gcry_pthread_mutex_init (void **priv)                              \\\n{                                                                             \\\n  int err = 0;                                                                \\\n  pthread_mutex_t *lock = (pthread_mutex_t *)malloc (sizeof (pthread_mutex_t)); \\\n                                                                              \\\n  if (!lock)                                                                  \\\n    err = ENOMEM;                                                             \\\n  if (!err)                                                                   \\\n{                                                                         \\\n      err = pthread_mutex_init (lock, NULL);                                  \\\n      if (err)                                                                \\\n        free (lock);                                                          \\\n      else                                                                    \\\n        *priv = lock;                                                         \\\n}                                                                         \\\n  return err;                                                                 \\\n}                                                                             \\\nstatic int gcry_pthread_mutex_destroy (void **lock)                           \\\n{ int err = pthread_mutex_destroy ((pthread_mutex_t *)*lock);  free (*lock); return err; }     \\\nstatic int gcry_pthread_mutex_lock (void **lock)                              \\\n{ return pthread_mutex_lock ((pthread_mutex_t *)*lock); }                     \\\nstatic int gcry_pthread_mutex_unlock (void **lock)                            \\\n{ return pthread_mutex_unlock ((pthread_mutex_t *)*lock); }                   \\\n                                                                              \\\nstatic struct gcry_thread_cbs gcry_threads_pthread =                          \\\n{ GCRY_THREAD_OPTION_PTHREAD, NULL,                                           \\\n  gcry_pthread_mutex_init, gcry_pthread_mutex_destroy,                        \\\n  gcry_pthread_mutex_lock, gcry_pthread_mutex_unlock }\n\n/** Implement the locking callback functions for libgcrypt.\n *\n */\n\nstatic int initialized = 0;\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\nGCRY_THREAD_OPTION_PTHREAD_CPP_IMPL;\n#ifdef __cplusplus\n}\n#endif\n\nint initializeGcrypt ()\n{\n\n    if (initialized) {\n\treturn 1;\n    }\n    gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);\n    gcry_check_version(NULL);\n    gcry_control(GCRYCTL_DISABLE_SECMEM);\n    initialized = 1;\n    return 1;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/crypto/gcrypt/gcryptSrtpSymCrypto.cpp",
    "content": "/*\n  Copyright (C) 2005, 2004, 2012 Erik Eliasson, Johan Bilien, Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n*/\n\n/**\n * @author Erik Eliasson <eliasson@it.kth.se>\n * @author Johan Bilien <jobi@via.ecp.fr>\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nextern void initializeGcrypt();\n\n#define MAKE_F8_TEST\n\n#include <gcrypt.h>            // the include of gcrypt\n#include <stdlib.h>\n#include <crypto/SrtpSymCrypto.h>\n#include <crypto/twofish.h>\n\n#include <stdio.h>\n\nSrtpSymCrypto::SrtpSymCrypto(int algo) : key(NULL), algorithm(algo) {\n    initializeGcrypt();\n}\n\nSrtpSymCrypto::SrtpSymCrypto( uint8_t* k, int32_t keyLength, int algo) :\n    key(NULL),  algorithm(algo) {\n\n    initializeGcrypt();\n    setNewKey(k, keyLength);\n}\n\nSrtpSymCrypto::~SrtpSymCrypto() {\n    if (key) {\n        if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8)\n            gcry_cipher_close(static_cast<gcry_cipher_hd_t>(key));\n        else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {\n            memset(key, 0, sizeof(Twofish_key));\n            delete[] (uint8_t*)key;\n        }\n        key = NULL;\n    }\n}\n\nstatic int twoFishInit = 0;\n\nbool SrtpSymCrypto::setNewKey(const uint8_t* k, int32_t keyLength) {\n\n    // release an existing key before setting a new one\n    if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {\n        if (key != NULL) {\n            gcry_cipher_close(static_cast<gcry_cipher_hd_t>(key));\n            key = NULL;\n        }\n\n        int algo = 0;\n        if (keyLength == 16) {\n            algo = GCRY_CIPHER_AES;\n        }\n        else if (keyLength == 32) {\n            algo = GCRY_CIPHER_AES256;\n        }\n        else {\n            return false;\n        }\n        gcry_cipher_hd_t tmp;\n        gcry_cipher_open(&tmp, algo, GCRY_CIPHER_MODE_ECB, 0);\n        key = tmp;\n        gcry_cipher_setkey(static_cast<gcry_cipher_hd_t>(key), k, keyLength);\n    }\n    else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {\n        if (!twoFishInit) {\n            Twofish_initialise();\n            twoFishInit = 1;\n        }\n        if (key != NULL)\n            delete[] (uint8_t*)key;\n\n        key = new uint8_t[sizeof(Twofish_key)];\n        memset(key, 0, sizeof(Twofish_key));\n        Twofish_prepare_key((Twofish_Byte*)k, keyLength,  (Twofish_key*)key);\n    }\n    else\n        return false;\n\n    return true;\n}\n\n\nvoid SrtpSymCrypto::encrypt(const uint8_t* input, uint8_t* output) {\n    if (key != NULL) {\n        if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8)\n            gcry_cipher_encrypt (static_cast<gcry_cipher_hd_t>(key),\n                                 output, SRTP_BLOCK_SIZE, input, SRTP_BLOCK_SIZE);\n        else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8)\n            Twofish_encrypt((Twofish_key*)key, (Twofish_Byte*)input,\n                            (Twofish_Byte*)output);\n        }\n}\n\nvoid SrtpSymCrypto::get_ctr_cipher_stream( uint8_t* output, uint32_t length,\n                                     uint8_t* iv ) {\n    uint16_t ctr = 0;\n\n    unsigned char temp[SRTP_BLOCK_SIZE];\n\n    for(ctr = 0; ctr < length/SRTP_BLOCK_SIZE; ctr++ ){\n        //compute the cipher stream\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, &output[ctr*SRTP_BLOCK_SIZE]);\n    }\n    if ((length % SRTP_BLOCK_SIZE) > 0) {\n        // Treat the last bytes:\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        memcpy(&output[ctr*SRTP_BLOCK_SIZE], temp, length % SRTP_BLOCK_SIZE);\n    }\n}\n\nvoid SrtpSymCrypto::ctr_encrypt( const uint8_t* input, uint32_t input_length,\n\t\t\t   uint8_t* output, uint8_t* iv ) {\n\n    if (key == NULL)\n        return;\n\n    uint16_t ctr = 0;\n    unsigned char temp[SRTP_BLOCK_SIZE];\n\n    int l = input_length/SRTP_BLOCK_SIZE;\n    for ( ctr = 0; ctr < l; ctr++ ) {\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        for (int i = 0; i < SRTP_BLOCK_SIZE; i++ ) {\n            *output++ = temp[i] ^ *input++;\n        }\n\n    }\n    l = input_length % SRTP_BLOCK_SIZE;\n    if (l > 0) {\n        // Treat the last bytes:\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        for (int i = 0; i < l; i++ ) {\n            *output++ = temp[i] ^ *input++;\n        }\n    }\n}\n\nvoid SrtpSymCrypto::ctr_encrypt( uint8_t* data, uint32_t data_length, uint8_t* iv ) {\n\n    if (key == NULL)\n        return;\n    \n    uint16_t ctr = 0;\n    unsigned char temp[SRTP_BLOCK_SIZE];\n\n    int l = data_length/SRTP_BLOCK_SIZE;\n    for (ctr = 0; ctr < l; ctr++ ) {\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        for (int i = 0; i < SRTP_BLOCK_SIZE; i++ ) {\n            *data++ ^= temp[i];\n        }\n\n    }\n    l = data_length % SRTP_BLOCK_SIZE;\n    if (l > 0) {\n        // Treat the last bytes:\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        for (int i = 0; i < l; i++ ) {\n            *data++ ^= temp[i];\n        }\n    }\n\n}\n\nvoid SrtpSymCrypto::f8_encrypt(const uint8_t* data, uint32_t data_length, uint8_t* iv, SrtpSymCrypto* f8Cipher ) {\n\n    f8_encrypt(data, data_length, const_cast<uint8_t*>(data), iv, f8Cipher);\n}\n\n#define MAX_KEYLEN 32\n\nvoid SrtpSymCrypto::f8_deriveForIV(SrtpSymCrypto* f8Cipher, uint8_t* key, int32_t keyLen,\n             uint8_t* salt, int32_t saltLen) {\n\n    unsigned char *cp_in, *cp_in1, *cp_out;\n\n    unsigned char maskedKey[MAX_KEYLEN];\n    unsigned char saltMask[MAX_KEYLEN];\n\n    if (keyLen > MAX_KEYLEN)\n        return;\n\n    if (saltLen > keyLen)\n        return;\n    /*\n     * First copy the salt into the mask field, then fill with 0x55 to\n     * get a full key.\n     */\n    memcpy(saltMask, salt, saltLen);\n    memset(saltMask+saltLen, 0x55, keyLen-saltLen);\n\n    /*\n     * XOR the original key with the above created mask to\n     * get the special key.\n     */\n    cp_out = maskedKey;\n    cp_in = key;\n    cp_in1 = saltMask;\n    for (int i = 0; i < keyLen; i++) {\n        *cp_out++ = *cp_in++ ^ *cp_in1++;\n    }\n    /*\n     * Prepare the a new AES cipher with the special key to compute IV'\n     */\n    f8Cipher->setNewKey(maskedKey, keyLen);\n}\n\nvoid SrtpSymCrypto::f8_encrypt(const uint8_t* in, uint32_t in_length, uint8_t* out,\n                         uint8_t* iv, SrtpSymCrypto* f8Cipher ) {\n\n    int offset = 0;\n\n    unsigned char ivAccent[SRTP_BLOCK_SIZE];\n    unsigned char S[SRTP_BLOCK_SIZE];\n\n    F8_CIPHER_CTX f8ctx;\n\n    if (key == NULL)\n        return;\n\n    /*\n     * Get memory for the derived IV (IV')\n     */\n    f8ctx.ivAccent = ivAccent;\n    /*\n     * Use the derived IV encryption setup to encrypt the original IV to produce IV'.\n     */\n    f8Cipher->encrypt(iv, f8ctx.ivAccent);\n\n    f8ctx.J = 0;                        // initialize the counter\n    f8ctx.S = S;                        // get the key stream buffer\n\n    memset(f8ctx.S, 0, SRTP_BLOCK_SIZE); // initial value for key stream\n\n    while (in_length >= SRTP_BLOCK_SIZE) {\n        processBlock(&f8ctx, in+offset, SRTP_BLOCK_SIZE, out+offset);\n        in_length -= SRTP_BLOCK_SIZE;\n        offset += SRTP_BLOCK_SIZE;\n    }\n    if (in_length > 0) {\n        processBlock(&f8ctx, in+offset, in_length, out+offset);\n    }\n}\n\nint SrtpSymCrypto::processBlock(F8_CIPHER_CTX *f8ctx, const uint8_t* in, int32_t length, uint8_t* out) {\n\n    int i;\n    const uint8_t *cp_in;\n    uint8_t* cp_in1, *cp_out;\n    uint32_t *ui32p;\n\n    /*\n     * XOR the previous key stream with IV'\n     * ( S(-1) xor IV' )\n     */\n    cp_in = f8ctx->ivAccent;\n    cp_out = f8ctx->S;\n    for (i = 0; i < SRTP_BLOCK_SIZE; i++) {\n        *cp_out++ ^= *cp_in++;\n    }\n    /*\n     * Now XOR (S(n-1) xor IV') with the current counter, then increment the counter\n     */\n    ui32p = (uint32_t *)f8ctx->S;\n    ui32p[3] ^= htonl(f8ctx->J);\n    f8ctx->J++;\n    /*\n     * Now compute the new key stream using encrypt\n     */\n    encrypt(f8ctx->S, f8ctx->S);\n    /*\n     * as the last step XOR the plain text with the key stream to produce\n     * the ciphertext.\n     */\n    cp_out = out;\n    cp_in = in;\n    cp_in1 = f8ctx->S;\n    for (i = 0; i < length; i++) {\n        *cp_out++ = *cp_in++ ^ *cp_in1++;\n    }\n    return length;\n}\n\n/** EMACS **\n * Local variables:\n * mode: c++\n * c-default-style: ellemtel\n * c-basic-offset: 4\n * End:\n */\n\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/crypto/gcrypt/gcrypthmac.cpp",
    "content": "/*\n  Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n*/\n\n/*\n * Authors: Erik Eliasson <eliasson@it.kth.se>\n *          Johan Bilien <jobi@via.ecp.fr>\n */\n#include <gcrypt.h>\n\n#include <crypto/hmac.h>\n#include <stdio.h>\n\nvoid hmac_sha1(uint8_t* key, int32_t keyLength,\n                 const uint8_t* data, int32_t dataLength,\n                 uint8_t* mac, int32_t* macLength)\n{\n    gcry_md_hd_t hd;\n\n     gcry_md_open(&hd, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);\n    gcry_md_setkey(hd, key, keyLength);\n\n    gcry_md_write (hd, data, dataLength);\n\n    uint8_t* p = gcry_md_read (hd, GCRY_MD_SHA1);\n    memcpy(mac, p, SHA1_DIGEST_LENGTH);\n    if (macLength != NULL) {\n        *macLength = SHA1_DIGEST_LENGTH;\n    }\n    gcry_md_close (hd);\n}\n\nvoid hmac_sha1( uint8_t* key, int32_t keyLength,\n                  const uint8_t* dataChunks[],\n                  uint32_t dataChunkLength[],\n                  uint8_t* mac, int32_t* macLength )\n{\n    gcry_md_hd_t hd;\n\n    gcry_md_open(&hd, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);\n    gcry_md_setkey(hd, key, keyLength);\n\n    while (*dataChunks) {\n        gcry_md_write (hd, *dataChunks, (uint32_t)(*dataChunkLength));\n        dataChunks++;\n        dataChunkLength++;\n    }\n    uint8_t* p = gcry_md_read (hd, GCRY_MD_SHA1);\n    memcpy(mac, p, SHA1_DIGEST_LENGTH);\n    if (macLength != NULL) {\n        *macLength = SHA1_DIGEST_LENGTH;\n    }\n    gcry_md_close (hd);\n}\n\nvoid* createSha1HmacContext(uint8_t* key, int32_t key_length)\n{\n    gcry_md_hd_t ctx;\n\n    gcry_md_open(&ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);\n    gcry_md_setkey(ctx, key, key_length);\n    return ctx;\n}\n\nvoid hmacSha1Ctx(void* ctx, const uint8_t* data, uint32_t data_length,\n                uint8_t* mac, int32_t* mac_length)\n{\n    gcry_md_hd_t pctx = (gcry_md_hd_t)ctx;\n\n    gcry_md_reset(pctx);\n\n    gcry_md_write (pctx, data, data_length);\n\n    uint8_t* p = gcry_md_read (pctx, GCRY_MD_SHA1);\n    memcpy(mac, p, SHA1_DIGEST_LENGTH);\n    if (mac_length != NULL) {\n        *mac_length = SHA1_DIGEST_LENGTH;\n    }\n}\n\nvoid hmacSha1Ctx(void* ctx, const uint8_t* data[], uint32_t data_length[],\n                uint8_t* mac, int32_t* mac_length )\n{\n    gcry_md_hd_t pctx = (gcry_md_hd_t)ctx;\n\n    gcry_md_reset (pctx);\n    while (*data) {\n        gcry_md_write (pctx, *data, (uint32_t)(*data_length));\n        data++;\n        data_length++;\n    }\n    uint8_t* p = gcry_md_read (pctx, GCRY_MD_SHA1);\n    memcpy(mac, p, SHA1_DIGEST_LENGTH);\n    if (mac_length != NULL) {\n        *mac_length = SHA1_DIGEST_LENGTH;\n    }\n}\n\nvoid freeSha1HmacContext(void* ctx)\n{\n    gcry_md_hd_t pctx = (gcry_md_hd_t)ctx;\n    gcry_md_close (pctx);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/crypto/hmac.cpp",
    "content": "/*\n  Copyright (C) 2012 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/*\n * Authors: Werner Dittmann\n */\n\n#include <stdint.h>\n#include <string.h>\n#include <stdio.h>\n#include \"crypto/hmac.h\"\n\nstatic int32_t hmacSha1Init(hmacSha1Context *ctx, const uint8_t *key, uint32_t kLength)\n{\n    int32_t i;\n    uint8_t localPad[SHA1_BLOCK_SIZE] = {0};\n    uint8_t localKey[SHA1_BLOCK_SIZE] = {0};\n\n    if (key == NULL)\n        return 0;\n\n    memset(ctx, 0, sizeof(hmacSha1Context));\n\n    /* check key length and reduce it if necessary */\n    if (kLength > SHA1_BLOCK_SIZE) {\n        sha1_begin(&ctx->ctx);\n        sha1_hash(key, kLength, &ctx->ctx);\n        sha1_end(localKey, &ctx->ctx);\n    }\n    else {\n        memcpy(localKey, key, kLength);\n    }\n    /* prepare inner hash and hold the context */\n    for (i = 0; i < SHA1_BLOCK_SIZE; i++)\n        localPad[i] = localKey[i] ^ 0x36;\n\n    sha1_begin(&ctx->innerCtx);\n    sha1_hash(localPad, SHA1_BLOCK_SIZE, &ctx->innerCtx);\n\n    /* prepare outer hash and hold the context */\n    for (i = 0; i < SHA1_BLOCK_SIZE; i++)\n        localPad[i] = localKey[i] ^ 0x5c;\n\n    sha1_begin(&ctx->outerCtx);\n    sha1_hash(localPad, SHA1_BLOCK_SIZE, &ctx->outerCtx);\n\n    /* copy prepared inner hash to work hash - ready to process data */\n    memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha1_ctx));\n\n    memset(localKey, 0, sizeof(localKey));\n\n    return 1;\n}\n\nstatic void hmacSha1Reset(hmacSha1Context *ctx)\n{\n    /* copy prepared inner hash to work hash context */\n    memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha1_ctx));\n}\n\nstatic void hmacSha1Update(hmacSha1Context *ctx, const uint8_t *data, uint32_t dLength)\n{\n    /* hash new data to work hash context */\n    sha1_hash(data, dLength, &ctx->ctx);\n}\n\nstatic void hmacSha1Final(hmacSha1Context *ctx, uint8_t *mac)\n{\n    uint8_t tmpDigest[SHA1_DIGEST_SIZE];\n\n    /* finalize work hash context */\n    sha1_end(tmpDigest, &ctx->ctx);\n\n    /* copy prepared outer hash to work hash */\n    memcpy(&ctx->ctx, &ctx->outerCtx, sizeof(sha1_ctx));\n\n    /* hash inner digest to work (outer) hash context */\n    sha1_hash(tmpDigest, SHA1_DIGEST_SIZE, &ctx->ctx);\n\n    /* finalize work hash context to get the hmac*/\n    sha1_end(mac, &ctx->ctx);\n}\n\n\nvoid hmac_sha1(uint8_t *key, int32_t keyLength, const uint8_t* data, uint32_t dataLength, uint8_t* mac, int32_t* macLength)\n{\n    hmacSha1Context ctx;\n\n    hmacSha1Init(&ctx, key, keyLength);\n    hmacSha1Update(&ctx, data, dataLength);\n    hmacSha1Final(&ctx, mac);\n    *macLength = SHA1_BLOCK_SIZE;\n}\n\nvoid hmac_sha1( uint8_t* key, int32_t keyLength, const uint8_t* dataChunks[], uint32_t dataChunckLength[],\n                uint8_t* mac, int32_t* macLength )\n{\n    hmacSha1Context ctx;\n\n    hmacSha1Init(&ctx, key, keyLength);\n\n    while (*dataChunks) {\n        hmacSha1Update(&ctx, *dataChunks, *dataChunckLength);\n        dataChunks ++;\n        dataChunckLength ++;\n    }\n    hmacSha1Final(&ctx, mac);\n    *macLength = SHA1_BLOCK_SIZE;\n}\n\nvoid* createSha1HmacContext(uint8_t* key, int32_t keyLength)\n{\n    hmacSha1Context *ctx = reinterpret_cast<hmacSha1Context*>(malloc(sizeof(hmacSha1Context)));\n    if (ctx == NULL)\n        return NULL;\n\n    hmacSha1Init(ctx, key, keyLength);\n    return ctx;\n}\n\nvoid* initializeSha1HmacContext(void* ctx, uint8_t* key, int32_t keyLength)\n{\n    hmacSha1Context *pctx = (hmacSha1Context*)ctx;\n\n    hmacSha1Init(pctx, key, keyLength);\n    return pctx;\n}\n\nvoid hmacSha1Ctx(void* ctx, const uint8_t* data, uint32_t dataLength,\n                uint8_t* mac, int32_t* macLength)\n{\n    hmacSha1Context *pctx = (hmacSha1Context*)ctx;\n\n    hmacSha1Reset(pctx);\n    hmacSha1Update(pctx, data, dataLength);\n    hmacSha1Final(pctx, mac);\n    *macLength = SHA1_BLOCK_SIZE;\n}\n\nvoid hmacSha1Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[],\n                uint8_t* mac, int32_t* macLength )\n{\n    hmacSha1Context *pctx = (hmacSha1Context*)ctx;\n\n    hmacSha1Reset(pctx);\n    while (*data) {\n        hmacSha1Update(pctx, *data, *dataLength);\n        data++;\n        dataLength++;\n    }\n    hmacSha1Final(pctx, mac);\n    *macLength = SHA1_BLOCK_SIZE;\n}\n\nvoid freeSha1HmacContext(void* ctx)\n{\n    if (ctx) {\n        memset(ctx, 0, sizeof(hmacSha1Context));\n        free(ctx);\n    }\n}"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/crypto/hmac.h",
    "content": "/*\n  Copyright (C) 2010 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/**\n * Functions to compute SHA1 HAMAC.\n *\n * @author Werner Dittmann\n */\n\n#ifndef HMAC_H\n#define HMAC_H\n\n/**\n * @file hmac.h\n * @brief Functions that provide SHA1 HMAC support\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <stdint.h>\n#include \"crypto/sha1.h\"\n\n#ifndef SHA1_DIGEST_LENGTH\n#define SHA1_DIGEST_LENGTH 20\n#endif\n\ntypedef struct _hmacSha1Context {\n    sha1_ctx ctx;\n    sha1_ctx innerCtx;\n    sha1_ctx outerCtx;\n} hmacSha1Context;\n\n\n/**\n * Compute SHA1 HMAC.\n *\n * This functions takes one data chunk and computes its SHA1 HMAC.\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lneght of the MAC key in bytes\n * @param data\n *    Points to the data chunk.\n * @param data_length\n *    Length of the data in bytes\n * @param mac\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 20 bytes (SHA1_DIGEST_LENGTH).\n * @param mac_length\n *    Point to an integer that receives the length of the computed HMAC.\n */\n\nvoid hmac_sha1( uint8_t* key, int32_t key_length,\n                const uint8_t* data, uint32_t data_length,\n                uint8_t* mac, int32_t* mac_length );\n\n/**\n * Compute SHA1 HMAC over several data cunks.\n *\n * This functions takes several data chunk and computes the SHA1 HAMAC.\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lneght of the MAC key in bytes\n * @param data\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param data_length\n *    Points to an array of integers that hold the length of each data chunk.\n * @param mac\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 20 bytes (SHA1_DIGEST_LENGTH).\n * @param mac_length\n *    Point to an integer that receives the length of the computed HMAC.\n */\nvoid hmac_sha1( uint8_t* key, int32_t key_length,\n                const uint8_t* data[], uint32_t data_length[],\n                uint8_t* mac, int32_t* mac_length );\n\n/**\n * Create and initialize a SHA1 HMAC context.\n *\n * An application uses this context to create several HMAC with the same key.\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lenght of the MAC key in bytes\n * @return Returns a pointer to the initialized context or @c NULL in case of an error.\n */\nvoid* createSha1HmacContext(uint8_t* key, int32_t key_length);\n\n/**\n * Initialize a SHA1 HMAC context.\n *\n * An application uses this context to create several HMAC with the same key.\n *\n * @param ctx\n *     Pointer to initialized SHA1 HMAC context\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lenght of the MAC key in bytes\n * @return Returns a pointer to the initialized context.\n */\nvoid* initializeSha1HmacContext(void* ctx, uint8_t* key, int32_t key_length);\n\n/**\n * Compute SHA1 HMAC.\n *\n * This functions takes one data chunk and computes its SHA1 HMAC. On return\n * the SHA1 MAC context is ready to compute a HMAC for another data chunk.\n *\n * @param ctx\n *     Pointer to initialized SHA1 HMAC context\n * @param data\n *    Points to the data chunk.\n * @param data_length\n *    Length of the data in bytes\n * @param mac\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 20 bytes (SHA1_DIGEST_LENGTH).\n * @param mac_length\n *    Point to an integer that receives the length of the computed HMAC.\n */\nvoid hmacSha1Ctx(void* ctx, const uint8_t* data, uint32_t data_length,\n                uint8_t* mac, int32_t* mac_length );\n\n/**\n * Compute SHA1 HMAC over several data cunks.\n *\n * This functions takes several data chunks and computes the SHA1 HAMAC. On return\n * the SHA1 MAC context is ready to compute a HMAC for another data chunk.\n *\n * @param ctx \n *     Pointer to initialized SHA1 HMAC context\n * @param data\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param data_length\n *    Points to an array of integers that hold the length of each data chunk.\n * @param mac\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 20 bytes (SHA1_DIGEST_LENGTH).\n * @param mac_length\n *    Point to an integer that receives the length of the computed HMAC.\n */\nvoid hmacSha1Ctx(void* ctx, const uint8_t* data[], uint32_t data_length[],\n                uint8_t* mac, int32_t* mac_length );\n\n/**\n * Free SHA1 HMAC context.\n *\n * @param ctx a pointer to SHA1 HMAC context\n */\nvoid freeSha1HmacContext(void* ctx);\n\n\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/crypto/openssl/SrtpSymCrypto.cpp",
    "content": "/*\n  Copyright (C) 2012 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  * In addition, as a special exception, the copyright holders give\n  * permission to link the code of portions of this program with the\n  * OpenSSL library under certain conditions as described in each\n  * individual source file, and distribute linked combinations\n  * including the two.\n  * You must obey the GNU General Public License in all respects\n  * for all of the code used other than OpenSSL.  If you modify\n  * file(s) with this exception, you may extend this exception to your\n  * version of the file(s), but you are not obligated to do so.  If you\n  * do not wish to do so, delete this exception statement from your\n  * version.  If you delete this exception statement from all source\n  * files in the program, then also delete it here.\n  */\n\n/**\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#define MAKE_F8_TEST\n\n#include <stdlib.h>\n#include <openssl/aes.h>                // the include of openSSL\n#include <crypto/SrtpSymCrypto.h>\n#include <cryptcommon/twofish.h>\n#include <string.h>\n#include <stdio.h>\n#include <common/osSpecifics.h>\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic push\n#  pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n#endif\n\nSrtpSymCrypto::SrtpSymCrypto(int algo):key(NULL), algorithm(algo) {\n}\n\nSrtpSymCrypto::SrtpSymCrypto( uint8_t* k, int32_t keyLength, int algo ):\n    key(NULL), algorithm(algo) {\n\n    setNewKey(k, keyLength);\n}\n\nSrtpSymCrypto::~SrtpSymCrypto() {\n    if (key != NULL) {\n        if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {\n            memset(key, 0, sizeof(AES_KEY) );\n        }\n        else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {\n            memset(key, 0, sizeof(Twofish_key));\n        }\n        delete[] (uint8_t*)key;\n        key = NULL;\n    }\n}\n\nstatic int twoFishInit = 0;\n\nbool SrtpSymCrypto::setNewKey(const uint8_t* k, int32_t keyLength) {\n    // release an existing key before setting a new one\n    if (key != NULL)\n        delete[] (uint8_t*)key;\n\n    if (!(keyLength == 16 || keyLength == 32)) {\n        return false;\n    }\n    if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {\n        key = new uint8_t[sizeof(AES_KEY)];\n        memset(key, 0, sizeof(AES_KEY) );\n        AES_set_encrypt_key(k, keyLength*8, (AES_KEY *)key);\n    }\n    else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {\n        if (!twoFishInit) {\n            Twofish_initialise();\n            twoFishInit = 1;\n        }\n        key = new uint8_t[sizeof(Twofish_key)];\n        memset(key, 0, sizeof(Twofish_key));\n        Twofish_prepare_key((Twofish_Byte*)k, keyLength,  (Twofish_key*)key);\n    }\n    else\n        return false;\n\n    return true;\n}\n\n\nvoid SrtpSymCrypto::encrypt(const uint8_t* input, uint8_t* output ) {\n    if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {\n        AES_encrypt(input, output, (AES_KEY *)key);\n    }\n    else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {\n        Twofish_encrypt((Twofish_key*)key, (Twofish_Byte*)input,\n                        (Twofish_Byte*)output); \n    }\n}\n\nvoid SrtpSymCrypto::get_ctr_cipher_stream(uint8_t* output, uint32_t length,\n                                    uint8_t* iv ) {\n    uint16_t ctr = 0;\n    unsigned char temp[SRTP_BLOCK_SIZE];\n\n    for(ctr = 0; ctr < length/SRTP_BLOCK_SIZE; ctr++) {\n        //compute the cipher stream\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, &output[ctr*SRTP_BLOCK_SIZE]);\n    }\n    if ((length % SRTP_BLOCK_SIZE) > 0) {\n        // Treat the last bytes:\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        memcpy(&output[ctr*SRTP_BLOCK_SIZE], temp, length % SRTP_BLOCK_SIZE );\n    }\n}\n\nvoid SrtpSymCrypto::ctr_encrypt(const uint8_t* input, uint32_t input_length,\n                           uint8_t* output, uint8_t* iv ) {\n\n    if (key == NULL)\n        return;\n\n    uint16_t ctr = 0;\n    unsigned char temp[SRTP_BLOCK_SIZE];\n\n    int l = input_length/SRTP_BLOCK_SIZE;\n    for (ctr = 0; ctr < l; ctr++ ) {\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        for (int i = 0; i < SRTP_BLOCK_SIZE; i++ ) {\n            *output++ = temp[i] ^ *input++;\n        }\n\n    }\n    l = input_length % SRTP_BLOCK_SIZE;\n    if (l > 0) {\n        // Treat the last bytes:\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        for (int i = 0; i < l; i++ ) {\n            *output++ = temp[i] ^ *input++;\n        }\n    }\n}\n\nvoid SrtpSymCrypto::ctr_encrypt( uint8_t* data, uint32_t data_length, uint8_t* iv ) {\n\n    if (key == NULL)\n        return;\n\n    uint16_t ctr = 0;\n    unsigned char temp[SRTP_BLOCK_SIZE];\n\n    int l = data_length/SRTP_BLOCK_SIZE;\n    for (ctr = 0; ctr < l; ctr++ ) {\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        for (int i = 0; i < SRTP_BLOCK_SIZE; i++ ) {\n            *data++ ^= temp[i];\n        }\n\n    }\n    l = data_length % SRTP_BLOCK_SIZE;\n    if (l > 0) {\n        // Treat the last bytes:\n        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);\n        iv[15] = (uint8_t)((ctr & 0x00FF));\n\n        encrypt(iv, temp);\n        for (int i = 0; i < l; i++ ) {\n            *data++ ^= temp[i];\n        }\n    }\n}\n\nvoid SrtpSymCrypto::f8_encrypt(const uint8_t* data, uint32_t data_length,\n                         uint8_t* iv, SrtpSymCrypto* f8Cipher ) {\n\n    f8_encrypt(data, data_length, const_cast<uint8_t*>(data), iv, f8Cipher);\n}\n\n#define MAX_KEYLEN 32\n\nvoid SrtpSymCrypto::f8_deriveForIV(SrtpSymCrypto* f8Cipher, uint8_t* key, int32_t keyLen,\n             uint8_t* salt, int32_t saltLen) {\n\n    unsigned char *cp_in, *cp_in1, *cp_out;\n\n    unsigned char maskedKey[MAX_KEYLEN];\n    unsigned char saltMask[MAX_KEYLEN];\n\n    if (keyLen > MAX_KEYLEN)\n        return;\n\n    if (saltLen > keyLen)\n        return;\n    /*\n     * First copy the salt into the mask field, then fill with 0x55 to\n     * get a full key.\n     */\n    memcpy(saltMask, salt, saltLen);\n    memset(saltMask+saltLen, 0x55, keyLen-saltLen);\n\n    /*\n     * XOR the original key with the above created mask to\n     * get the special key.\n     */\n    cp_out = maskedKey;\n    cp_in = key;\n    cp_in1 = saltMask;\n    for (int i = 0; i < keyLen; i++) {\n        *cp_out++ = *cp_in++ ^ *cp_in1++;\n    }\n    /*\n     * Prepare the a new AES cipher with the special key to compute IV'\n     */\n    f8Cipher->setNewKey(maskedKey, keyLen);\n}\n\nvoid SrtpSymCrypto::f8_encrypt(const uint8_t* in, uint32_t in_length, uint8_t* out,\n                         uint8_t* iv, SrtpSymCrypto* f8Cipher ) {\n\n\n    int offset = 0;\n\n    unsigned char ivAccent[SRTP_BLOCK_SIZE];\n    unsigned char S[SRTP_BLOCK_SIZE];\n\n    F8_CIPHER_CTX f8ctx;\n\n    if (key == NULL)\n        return;\n    /*\n     * Get memory for the derived IV (IV')\n     */\n    f8ctx.ivAccent = ivAccent;\n    /*\n     * Use the derived IV encryption setup to encrypt the original IV to produce IV'.\n     */\n    f8Cipher->encrypt(iv, f8ctx.ivAccent);\n\n    f8ctx.J = 0;                       // initialize the counter\n    f8ctx.S = S;               // get the key stream buffer\n\n    memset(f8ctx.S, 0, SRTP_BLOCK_SIZE); // initial value for key stream\n\n    while (in_length >= SRTP_BLOCK_SIZE) {\n        processBlock(&f8ctx, in+offset, SRTP_BLOCK_SIZE, out+offset);\n        in_length -= SRTP_BLOCK_SIZE;\n        offset += SRTP_BLOCK_SIZE;\n    }\n    if (in_length > 0) {\n        processBlock(&f8ctx, in+offset, in_length, out+offset);\n    }\n}\n\nint SrtpSymCrypto::processBlock(F8_CIPHER_CTX *f8ctx, const uint8_t* in, int32_t length, uint8_t* out) {\n\n    int i;\n    const uint8_t *cp_in;\n    uint8_t* cp_in1, *cp_out;\n    uint32_t *ui32p;\n\n    /*\n     * XOR the previous key stream with IV'\n     * ( S(-1) xor IV' )\n     */\n    cp_in = f8ctx->ivAccent;\n    cp_out = f8ctx->S;\n    for (i = 0; i < SRTP_BLOCK_SIZE; i++) {\n        *cp_out++ ^= *cp_in++;\n    }\n    /*\n     * Now XOR (S(n-1) xor IV') with the current counter, then increment the counter\n     */\n    ui32p = (uint32_t *)f8ctx->S;\n    ui32p[3] ^= zrtpHtonl(f8ctx->J);\n    f8ctx->J++;\n    /*\n     * Now compute the new key stream using AES encrypt\n     */\n    encrypt(f8ctx->S, f8ctx->S);\n    /*\n     * as the last step XOR the plain text with the key stream to produce\n     * the ciphertext.\n     */\n    cp_out = out;\n    cp_in = in;\n    cp_in1 = f8ctx->S;\n    for (i = 0; i < length; i++) {\n        *cp_out++ = *cp_in++ ^ *cp_in1++;\n    }\n    return length;\n}\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic pop\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/crypto/openssl/hmac.cpp",
    "content": "/*\n  Copyright (C) 2010 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/*\n * Authors: Werner Dittmann\n */\n\n#include <stdint.h>\n#include <openssl/hmac.h>\n#include <crypto/hmac.h>\n\n#include <openssl_compat.h>\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic push\n#  pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n#endif\n\nvoid hmac_sha1(uint8_t * key, int32_t key_length,\n               const uint8_t* data, uint32_t data_length,\n               uint8_t* mac, int32_t* mac_length )\n{\n    HMAC(EVP_sha1(), key, key_length,\n         data, data_length, mac,\n         reinterpret_cast<uint32_t*>(mac_length) );\n}\n\nvoid hmac_sha1( uint8_t* key, int32_t key_length,\n                const uint8_t* data_chunks[],\n                uint32_t data_chunck_length[],\n                uint8_t* mac, int32_t* mac_length ) {\n    HMAC_CTX* ctx = HMAC_CTX_new();\n    HMAC_Init_ex(ctx, key, key_length, EVP_sha1(), NULL);\n    while (*data_chunks) {\n        HMAC_Update(ctx, *data_chunks, *data_chunck_length);\n        data_chunks ++;\n        data_chunck_length ++;\n    }\n    HMAC_Final(ctx, mac, reinterpret_cast<uint32_t*>(mac_length));\n    HMAC_CTX_free(ctx);\n}\n\nvoid* createSha1HmacContext(uint8_t* key, int32_t key_length)\n{\n    HMAC_CTX* ctx = HMAC_CTX_new();\n\n    HMAC_Init_ex(ctx, key, key_length, EVP_sha1(), NULL);\n    return ctx;\n}\n\nvoid* initializeSha1HmacContext(void* ctx, uint8_t* key, int32_t keyLength)\n{\n    HMAC_CTX *pctx = (HMAC_CTX*)ctx;\n\n    HMAC_CTX_reset(pctx);\n    HMAC_Init_ex(pctx, key, keyLength, EVP_sha1(), NULL);\n    return pctx;\n}\n\nvoid hmacSha1Ctx(void* ctx, const uint8_t* data, uint32_t data_length,\n                uint8_t* mac, int32_t* mac_length)\n{\n    HMAC_CTX* pctx = (HMAC_CTX*)ctx;\n\n    HMAC_Init_ex(pctx, NULL, 0, NULL, NULL );\n    HMAC_Update(pctx, data, data_length );\n    HMAC_Final(pctx, mac, reinterpret_cast<uint32_t*>(mac_length) );\n}\n\nvoid hmacSha1Ctx(void* ctx, const uint8_t* data[], uint32_t data_length[],\n                uint8_t* mac, int32_t* mac_length )\n{\n    HMAC_CTX* pctx = (HMAC_CTX*)ctx;\n\n    HMAC_Init_ex(pctx, NULL, 0, NULL, NULL );\n    while (*data) {\n        HMAC_Update(pctx, *data, *data_length);\n        data++;\n        data_length++;\n    }\n    HMAC_Final(pctx, mac, reinterpret_cast<uint32_t*>(mac_length) );\n}\n\nvoid freeSha1HmacContext(void* ctx)\n{\n    if (ctx) {\n        HMAC_CTX_free((HMAC_CTX*)ctx);\n    }\n}\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic pop\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/crypto/sha1.c",
    "content": "/*\n ---------------------------------------------------------------------------\n Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.\n\n LICENSE TERMS\n\n The free distribution and use of this software in both source and binary\n form is allowed (with or without changes) provided that:\n\n   1. distributions of this source code include the above copyright\n      notice, this list of conditions and the following disclaimer;\n\n   2. distributions in binary form include the above copyright\n      notice, this list of conditions and the following disclaimer\n      in the documentation and/or other associated materials;\n\n   3. the copyright holder's name is not used to endorse products\n      built using this software without specific written permission.\n\n ALTERNATIVELY, provided that this notice is retained in full, this product\n may be distributed under the terms of the GNU General Public License (GPL),\n in which case the provisions of the GPL apply INSTEAD OF those given above.\n\n DISCLAIMER\n\n This software is provided 'as is' with no explicit or implied warranties\n in respect of its properties, including, but not limited to, correctness\n and/or fitness for purpose.\n ---------------------------------------------------------------------------\n Issue Date: 01/08/2005\n\n This is a byte oriented version of SHA1 that operates on arrays of bytes\n stored in memory.\n*/\n\n#include <string.h>     /* for memcpy() etc.        */\n\n#include \"sha1.h\"\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\n#if defined( _MSC_VER ) && ( _MSC_VER > 800 )\n#pragma intrinsic(memcpy)\n#endif\n\n#if 0 && defined(_MSC_VER)\n#define rotl32  _lrotl\n#define rotr32  _lrotr\n#else\n#define rotl32(x,n)   (((x) << n) | ((x) >> (32 - n)))\n#define rotr32(x,n)   (((x) >> n) | ((x) << (32 - n)))\n#endif\n\n#if !defined(bswap_32)\n#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))\n#endif\n\n#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)\n#define SWAP_BYTES\n#else\n#undef  SWAP_BYTES\n#endif\n\n#if defined(SWAP_BYTES)\n#define bsw_32(p,n) \\\n    { int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); }\n#else\n#define bsw_32(p,n)\n#endif\n\n#define SHA1_MASK   (SHA1_BLOCK_SIZE - 1)\n\n#if 0\n\n#define ch(x,y,z)       (((x) & (y)) ^ (~(x) & (z)))\n#define parity(x,y,z)   ((x) ^ (y) ^ (z))\n#define maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))\n\n#else   /* Discovered by Rich Schroeppel and Colin Plumb   */\n\n#define ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))\n#define parity(x,y,z)   ((x) ^ (y) ^ (z))\n#define maj(x,y,z)      (((x) & (y)) | ((z) & ((x) ^ (y))))\n\n#endif\n\n/* Compile 64 bytes of hash data into SHA1 context. Note    */\n/* that this routine assumes that the byte order in the     */\n/* ctx->wbuf[] at this point is in such an order that low   */\n/* address bytes in the ORIGINAL byte stream will go in     */\n/* this buffer to the high end of 32-bit words on BOTH big  */\n/* and little endian systems                                */\n\n#ifdef ARRAY\n#define q(v,n)  v[n]\n#else\n#define q(v,n)  v##n\n#endif\n\n#define one_cycle(v,a,b,c,d,e,f,k,h)            \\\n    q(v,e) += rotr32(q(v,a),27) +               \\\n              f(q(v,b),q(v,c),q(v,d)) + k + h;  \\\n    q(v,b)  = rotr32(q(v,b), 2)\n\n#define five_cycle(v,f,k,i)                 \\\n    one_cycle(v, 0,1,2,3,4, f,k,hf(i  ));   \\\n    one_cycle(v, 4,0,1,2,3, f,k,hf(i+1));   \\\n    one_cycle(v, 3,4,0,1,2, f,k,hf(i+2));   \\\n    one_cycle(v, 2,3,4,0,1, f,k,hf(i+3));   \\\n    one_cycle(v, 1,2,3,4,0, f,k,hf(i+4))\n\nVOID_RETURN sha1_compile(sha1_ctx ctx[1])\n{   uint_32t    *w = ctx->wbuf;\n\n#ifdef ARRAY\n    uint_32t    v[5];\n    memcpy(v, ctx->hash, 5 * sizeof(uint_32t));\n#else\n    uint_32t    v0, v1, v2, v3, v4;\n    v0 = ctx->hash[0]; v1 = ctx->hash[1];\n    v2 = ctx->hash[2]; v3 = ctx->hash[3];\n    v4 = ctx->hash[4];\n#endif\n\n#define hf(i)   w[i]\n\n    five_cycle(v, ch, 0x5a827999,  0);\n    five_cycle(v, ch, 0x5a827999,  5);\n    five_cycle(v, ch, 0x5a827999, 10);\n    one_cycle(v,0,1,2,3,4, ch, 0x5a827999, hf(15)); \\\n\n#undef  hf\n#define hf(i) (w[(i) & 15] = rotl32(                    \\\n                 w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \\\n               ^ w[((i) +  2) & 15] ^ w[(i) & 15], 1))\n\n    one_cycle(v,4,0,1,2,3, ch, 0x5a827999, hf(16));\n    one_cycle(v,3,4,0,1,2, ch, 0x5a827999, hf(17));\n    one_cycle(v,2,3,4,0,1, ch, 0x5a827999, hf(18));\n    one_cycle(v,1,2,3,4,0, ch, 0x5a827999, hf(19));\n\n    five_cycle(v, parity, 0x6ed9eba1,  20);\n    five_cycle(v, parity, 0x6ed9eba1,  25);\n    five_cycle(v, parity, 0x6ed9eba1,  30);\n    five_cycle(v, parity, 0x6ed9eba1,  35);\n\n    five_cycle(v, maj, 0x8f1bbcdc,  40);\n    five_cycle(v, maj, 0x8f1bbcdc,  45);\n    five_cycle(v, maj, 0x8f1bbcdc,  50);\n    five_cycle(v, maj, 0x8f1bbcdc,  55);\n\n    five_cycle(v, parity, 0xca62c1d6,  60);\n    five_cycle(v, parity, 0xca62c1d6,  65);\n    five_cycle(v, parity, 0xca62c1d6,  70);\n    five_cycle(v, parity, 0xca62c1d6,  75);\n\n#ifdef ARRAY\n    ctx->hash[0] += v[0]; ctx->hash[1] += v[1];\n    ctx->hash[2] += v[2]; ctx->hash[3] += v[3];\n    ctx->hash[4] += v[4];\n#else\n    ctx->hash[0] += v0; ctx->hash[1] += v1;\n    ctx->hash[2] += v2; ctx->hash[3] += v3;\n    ctx->hash[4] += v4;\n#endif\n}\n\nVOID_RETURN sha1_begin(sha1_ctx ctx[1])\n{\n    ctx->count[0] = ctx->count[1] = 0;\n    ctx->hash[0] = 0x67452301;\n    ctx->hash[1] = 0xefcdab89;\n    ctx->hash[2] = 0x98badcfe;\n    ctx->hash[3] = 0x10325476;\n    ctx->hash[4] = 0xc3d2e1f0;\n}\n\n/* SHA1 hash data in an array of bytes into hash buffer and */\n/* call the hash_compile function as required.              */\n\nVOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1])\n{   \n\tuint_32t pos = (uint_32t)(ctx->count[0] & SHA1_MASK),\n            space = SHA1_BLOCK_SIZE - pos;\n    const unsigned char *sp = data;\n\n    if((ctx->count[0] += len) < len)\n        ++(ctx->count[1]);\n\n    while(len >= space)     /* tranfer whole blocks if possible  */\n    {\n        memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);\n        sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0;\n        bsw_32(ctx->wbuf, SHA1_BLOCK_SIZE >> 2);\n        sha1_compile(ctx);\n    }\n\n    memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);\n}\n\n/* SHA1 final padding and digest calculation  */\n\nVOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1])\n{   uint_32t    i = (uint_32t)(ctx->count[0] & SHA1_MASK);\n\n    /* put bytes in the buffer in an order in which references to   */\n    /* 32-bit words will put bytes with lower addresses into the    */\n    /* top of 32 bit words on BOTH big and little endian machines   */\n    bsw_32(ctx->wbuf, (i + 3) >> 2);\n\n    /* we now need to mask valid bytes and add the padding which is */\n    /* a single 1 bit and as many zero bits as necessary. Note that */\n    /* we can always add the first padding byte here because the    */\n    /* buffer always has at least one empty slot                    */\n    ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3);\n    ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3);\n\n    /* we need 9 or more empty positions, one for the padding byte  */\n    /* (above) and eight for the length count. If there is not      */\n    /* enough space, pad and empty the buffer                       */\n    if(i > SHA1_BLOCK_SIZE - 9)\n    {\n        if(i < 60) ctx->wbuf[15] = 0;\n        sha1_compile(ctx);\n        i = 0;\n    }\n    else    /* compute a word index for the empty buffer positions  */\n        i = (i >> 2) + 1;\n\n    while(i < 14) /* and zero pad all but last two positions        */\n        ctx->wbuf[i++] = 0;\n\n    /* the following 32-bit length fields are assembled in the      */\n    /* wrong byte order on little endian machines but this is       */\n    /* corrected later since they are only ever used as 32-bit      */\n    /* word values.                                                 */\n    ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);\n    ctx->wbuf[15] = ctx->count[0] << 3;\n    sha1_compile(ctx);\n\n    /* extract the hash value as bytes in case the hash buffer is   */\n    /* misaligned for 32-bit words                                  */\n    for(i = 0; i < SHA1_DIGEST_SIZE; ++i)\n        hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));\n}\n\nVOID_RETURN bg_sha1(unsigned char hval[], const unsigned char data[], unsigned long len)\n{   sha1_ctx    cx[1];\n\n    sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx);\n}\n\n#if defined(__cplusplus)\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/srtp/crypto/sha1.h",
    "content": "/*\n ---------------------------------------------------------------------------\n Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.\n\n LICENSE TERMS\n\n The free distribution and use of this software in both source and binary\n form is allowed (with or without changes) provided that:\n\n   1. distributions of this source code include the above copyright\n      notice, this list of conditions and the following disclaimer;\n\n   2. distributions in binary form include the above copyright\n      notice, this list of conditions and the following disclaimer\n      in the documentation and/or other associated materials;\n\n   3. the copyright holder's name is not used to endorse products\n      built using this software without specific written permission.\n\n ALTERNATIVELY, provided that this notice is retained in full, this product\n may be distributed under the terms of the GNU General Public License (GPL),\n in which case the provisions of the GPL apply INSTEAD OF those given above.\n\n DISCLAIMER\n\n This software is provided 'as is' with no explicit or implied warranties\n in respect of its properties, including, but not limited to, correctness\n and/or fitness for purpose.\n ---------------------------------------------------------------------------\n Issue Date: 01/08/2005\n*/\n\n#ifndef _SHA1_H\n#define _SHA1_H\n\n#include <stdlib.h>\n#include <cryptcommon/brg_types.h>\n\n#define SHA1_BLOCK_SIZE  64\n#define SHA1_DIGEST_SIZE 20\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\n/* type to hold the SHA256 context  */\n\ntypedef struct\n{   uint_32t count[2];\n    uint_32t hash[5];\n    uint_32t wbuf[16];\n} sha1_ctx;\n\n/* Note that these prototypes are the same for both bit and */\n/* byte oriented implementations. However the length fields */\n/* are in bytes or bits as appropriate for the version used */\n/* and bit sequences are input as arrays of bytes in which  */\n/* bit sequences run from the most to the least significant */\n/* end of each byte                                         */\n\nVOID_RETURN sha1_compile(sha1_ctx ctx[1]);\n\nVOID_RETURN sha1_begin(sha1_ctx ctx[1]);\nVOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]);\nVOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1]);\nVOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len);\n\n#if defined(__cplusplus)\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/Base32.cpp",
    "content": "/**\n *\n * Copyright (c) 2002 Bryce \"Zooko\" Wilcox-O'Hearn Permission is hereby\n * granted, free of charge, to any person obtaining a copy of this software to\n * deal in this software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of this software, and to permit persons to whom this software\n * is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of this software.\n *\n * THIS SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THIS SOFTWARE.\n *\n * Converted to C++ by:\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n#ifndef UNIT_TEST\n#include <libzrtpcpp/Base32.h>\n#else\n#include \"libzrtpcpp/Base32.h\"\n#endif\n\nint divceil(int a, int b) {\n    int c;\n    if (a>0) {\n\tif (b>0) c=a+b-1;\n\telse c=a;\n    } else {\n\tif (b>0) c=a;\n\telse c=a+b+1;\n    }\n    return c/b;\n}\n\n//                                         1         2         3\n//                               01234567890123456789012345678901\nstatic const char* const chars= \"ybndrfg8ejkmcpqxot1uwisza345h769\";\n\n/*\n * revchars: index into this table with the ASCII value of the char.\n * The result is the value of that quintet.\n */\nstatic const unsigned char revchars[]= {\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255,  18, 255,  25,  26,  27,  30,  29,\n      7,  31, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255,  24,   1,  12,   3,   8,   5,   6,\n    28,   21,   9,  10, 255,  11,   2,  16,\n    13,   14,   4,  22,  17,  19, 255,  20,\n    15,    0,  23, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255,\n    255, 255, 255, 255, 255, 255, 255, 255\n};\n\n\nBase32::Base32(const string encoded):\n    binaryResult(NULL), resultLength(0) {\n\n    a2b_l(encoded, encoded.size(), (encoded.size()*5/8)*8);\n}\n\nBase32::Base32(const string encoded, int noOfBits):\n    binaryResult(NULL), resultLength(0) {\n\n    a2b_l(encoded, divceil(noOfBits, 5), noOfBits);\n}\n\nBase32::Base32(const unsigned char* data, int noOfBits):\n    binaryResult(NULL), resultLength(0) {\n\n    b2a_l(data, (noOfBits+7)/8, noOfBits);\n}\n\nBase32::~Base32() {\n    if (binaryResult != NULL && binaryResult != smallBuffer) {\n\tdelete [] binaryResult;\n    }\n    binaryResult = NULL;\n}\n\nconst unsigned char* Base32::getDecoded(int &length) {\n    length = resultLength;\n    return binaryResult;\n}\n\nvoid Base32::b2a_l(const unsigned char* os, int len,\n\t\t   const size_t lengthinbits) {\n\n    /* if lengthinbits is not a multiple of 8 then this is allocating\n     * space for 0, 1, or 2 extra quintets that will be truncated at the\n     * end of this function if they are not needed\n     */\n    string result(divceil(len*8, 5), ' ');\n\n    /* index into the result buffer, initially pointing to the\n     * \"one-past-the-end\" quintet\n     */\n    int resp = result.size();\n\n    /* pointer into the os buffer, initially pointing to the\n     * \"one-past-the-end\" octet\n     */\n    const unsigned char* osp = os + len;\n\n    /* Now this is a real live Duff's device.  You gotta love it. */\n\n    unsigned long x = 0;\t// to hold up to 32 bits worth of the input\n    switch ((osp - os) % 5) {\n\n\tcase 0:\n\t    do {\n\t\tx = *--osp;\n\t\tresult[--resp] = chars[x % 32]; /* The least sig 5 bits go into the final quintet. */\n\t\tx /= 32;\t/* ... now we have 3 bits worth in x... */\n\t\tcase 4:\n\t\t    x |= ((unsigned long)(*--osp)) << 3; /* ... now we have 11 bits worth in x... */\n\t\t    result[--resp] = chars[x % 32];\n\t\t    x /= 32; /* ... now we have 6 bits worth in x... */\n\t\t    result[--resp] = chars[x % 32];\n\t\t    x /= 32; /* ... now we have 1 bits worth in x... */\n\t\tcase 3:\n\t\t    x |= ((unsigned long)(*--osp)) << 1; /* The 8 bits from the 2-indexed octet.\n\t\t\t\t\t\t\t    So now we have 9 bits worth in x... */\n\t\t    result[--resp] = chars[x % 32];\n\t\t    x /= 32; /* ... now we have 4 bits worth in x... */\n\t\tcase 2:\n\t\t    x |= ((unsigned long)(*--osp)) << 4; /* The 8 bits from the 1-indexed octet.\n\t\t\t\t\t\t\t    So now we have 12 bits worth in x... */\n\t\t    result[--resp] = chars[x%32];\n\t\t    x /= 32; /* ... now we have 7 bits worth in x... */\n\t\t    result[--resp] = chars[x%32];\n\t\t    x /= 32; /* ... now we have 2 bits worth in x... */\n\t\tcase 1:\n\t\t    x |= ((unsigned long)(*--osp)) << 2; /* The 8 bits from the 0-indexed octet.\n\t\t\t\t\t\t\t    So now we have 10 bits worth in x... */\n\t\t    result[--resp] = chars[x%32];\n\t\t    x /= 32; /* ... now we have 5 bits worth in x... */\n\t\t    result[--resp] = chars[x];\n\t    } while (osp > os);\n    } /* switch ((osp - os.buf) % 5) */\n\n    /* truncate any unused trailing zero quintets */\n    encoded = result.substr(0, divceil(lengthinbits, 5));\n    return;\n}\n\nvoid Base32::a2b_l(const string cs, size_t size, const size_t lengthinbits ) {\n    unsigned long x = 0;\t// to hold up to 32 bits worth of the input\n\n    int len = divceil(size*5, 8);\n\n    /* if lengthinbits is not a multiple of 5 then this is\n     * allocating space for 0 or 1 extra octets that will be\n     * truncated at the end of this function if they are\n     * not needed\n     */\n\n    if (len < 128) {\n        binaryResult = smallBuffer;\n    }\n    else {\n        binaryResult = new unsigned char[len];\n    }\n\n    /* pointer into the result buffer, initially pointing to\n     * the \"one-past-the-end\" octet\n     */\n    unsigned char* resp = binaryResult + len;\n\n    /* index into the input buffer, initially pointing to the\n     * \"one-past-the-end\" character\n     */\n    int csp = size;\n\n    /* Now this is a real live Duff's device.  You gotta love it. */\n    switch (csp % 8) {\n\tcase 0:\n\t    do {\n\t\tx = revchars[cs[--csp]&0xff]; /* 5 bits... */\n\t\tcase 7:\n\t\t    x |= revchars[cs[--csp]&0xff] << 5; /* 10 bits... */\n\t\t    *--resp = x % 256;\n\t\t    x /= 256; /* 2 bits... */\n\t\tcase 6:\n\t\t    x |= revchars[cs[--csp]&0xff] << 2; /* 7 bits... */\n\t\tcase 5:\n\t\t    x |= revchars[cs[--csp]&0xff] << 7; /* 12 bits... */\n\t\t    *--resp = x % 256;\n\t\t    x /= 256; /* 4 bits... */\n\t\tcase 4:\n\t\t    x |= revchars[cs[--csp]&0xff] << 4; /* 9 bits... */\n\t\t    *--resp = x % 256;\n\t\t    x /= 256; /* 1 bit... */\n\t\tcase 3:\n\t\t    x |= revchars[cs[--csp]&0xff] << 1; /* 6 bits... */\n\t\tcase 2:\n\t\t    x |= revchars[cs[--csp]&0xff] << 6; /* 11 bits... */\n\t\t    *--resp = x % 256;\n\t\t    x /= 256; /* 3 bits... */\n\t\tcase 1:\n\t\t    x |= revchars[cs[--csp]&0xff] << 3; /* 8 bits... */\n\t\t    *--resp = x % 256;\n\t    } while (csp);\n    } /* switch ((csp - cs.buf) % 8) */\n\n    /* truncate any unused trailing zero octets */\n    resultLength = divceil(lengthinbits, 8);\n    return;\n}\n\n#ifdef UNIT_TEST\n#include <math.h>\n\n\nstatic uint8_t *randz(const size_t len)\n{\n    uint8_t* result = (uint8_t*)malloc(len);\n    size_t i;\n    for (i=0; i<len; i++) {\n        result[i] = rand() % 256;\n    }\n    return result;\n}\n\nint main(int argc, char *argv[]) {\n\n    int32_t resLen;\n    string a;\n    const uint8_t* zrecovered;\n    uint8_t ones[] = {1, 1, 1, 1, 1};\n    uint8_t zrtpVec01[] = {0x00, 0x00, 0x00, 0x00};\n    uint8_t zrtpVec02[] = {0x80, 0x00, 0x00, 0x00};\n    uint8_t zrtpVec03[] = {0x40, 0x00, 0x00, 0x00};\n    uint8_t zrtpVec04[] = {0xc0, 0x00, 0x00, 0x00};\n    uint8_t zrtpVec05[] = {0x00, 0x00, 0x00, 0x00};\n    uint8_t zrtpVec06[] = {0x80, 0x80, 0x00, 0x00};\n    uint8_t zrtpVec07[] = {0x8b, 0x88, 0x80, 0x00};\n    uint8_t zrtpVec08[] = {0xf0, 0xbf, 0xc7, 0x00};\n    uint8_t zrtpVec09[] = {0xd4, 0x7a, 0x04, 0x00};\n    uint8_t zrtpVec10[] = {0xf5, 0x57, 0xbb, 0x0c};\n\n    // Encode all bits of the 5 one bytes (= 40 bits)\n    a = Base32(ones, 5*8).getEncoded();\n\n    // The string should be: \"yryonyeb\"\n    cout << \"Encoded 5 ones: '\" << a << \"', Expected: 'yryonyeb'\" << endl;\n\n    // Now decode all bits and check\n    Base32 *y = new Base32(a);\n    zrecovered = y->getDecoded(resLen);\n    if (resLen != 5 && memcmp(ones, zrecovered, 5)) {\n        printf(\"Failed basic 5 ones recovery test.\\n\");\n        return -1;\n    }\n    delete y;\n\n    a = Base32(ones, 15).getEncoded();\n    cout << \"Encoded 5 ones, 15 bits only: '\" << a << \"', Expected: 'yry'\" << endl;\n    // now decode 15 bits (out of 40 possible)\n    y = new Base32(a, 15);\n    zrecovered = y->getDecoded(resLen);\n    printf(\"Decoded 15 bits, result length: %d (should be 2)\\n\", resLen);\n    printf(\"Decoded bytes: %x %x (should be 1 0)\\n\", zrecovered[0], zrecovered[1]);\n    delete y;\n\n    // Encode 20 bits of the test vectors\n    a = Base32(zrtpVec01, 20).getEncoded();\n    cout << \"Encoded ZRTP vector 01: '\" << a << \"', Expected: 'yyyy'\" << endl;\n    a = Base32(zrtpVec02, 20).getEncoded();\n    cout << \"Encoded ZRTP vector 02: '\" << a << \"', Expected: 'oyyy'\" << endl;\n    a = Base32(zrtpVec03, 20).getEncoded();\n    cout << \"Encoded ZRTP vector 02: '\" << a << \"', Expected: 'eyyy'\" << endl;\n    a = Base32(zrtpVec04, 20).getEncoded();\n    cout << \"Encoded ZRTP vector 04: '\" << a << \"', Expected: 'ayyy'\" << endl;\n    a = Base32(zrtpVec05, 20).getEncoded();\n    cout << \"Encoded ZRTP vector 05: '\" << a << \"', Expected: 'yyyy'\" << endl;\n    a = Base32(zrtpVec06, 20).getEncoded();\n    cout << \"Encoded ZRTP vector 06: '\" << a << \"', Expected: 'onyy'\" << endl;\n    a = Base32(zrtpVec07, 20).getEncoded();\n    cout << \"Encoded ZRTP vector 07: '\" << a << \"', Expected: 'tqre'\" << endl;\n    a = Base32(zrtpVec08, 20).getEncoded();\n    cout << \"Encoded ZRTP vector 08: '\" << a << \"', Expected: '6n9h'\" << endl;\n    a = Base32(zrtpVec09, 20).getEncoded();\n    cout << \"Encoded ZRTP vector 09: '\" << a << \"', Expected: '4t7y'\" << endl;\n    a = Base32(zrtpVec10, 20).getEncoded();\n    cout << \"Encoded ZRTP vector 10: '\" << a << \"', Expected: '6im5'\" << endl;\n\n    // test the 30 bit output of same data as 20 bit\n    a = Base32(zrtpVec10, 30).getEncoded();\n    cout << \"Encoded ZRTP vector 10 (30bit): '\" << a << \"', Expected: '6im5sd'\" << endl;\n\n    for (int i = 0; i < 2; i++) {\n        uint8_t* z = randz(16);\n        a = Base32(z, 16*8).getEncoded();\n//        cout << \"Result: \" << a << endl;\n        assert (a.size() == Base32::b2alen(16*8));\n        zrecovered = Base32(a).getDecoded(resLen);\n        if (resLen != 16 && memcmp(z, zrecovered, 16)) {\n            printf(\"Failed basic recovery test.\\n\");\n            return -1;\n        }\n        free((void*)z);\n    }\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZIDCacheDb.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n// #define UNIT_TEST\n#include <sstream>\n#include <string>\n#include <time.h>\n#include <stdlib.h>\n\n#include <libzrtpcpp/ZIDCacheDb.h>\n#include <cryptcommon/aes.h>\n\n\nstatic ZIDCacheDb* instance;\n\n/**\n * A poor man's factory.\n *\n * The build process must not allow to implementation classes linked\n * into the same library.\n */\n\nZIDCache* getZidCacheInstance() {\n\n    if (instance == NULL) {\n        instance = new ZIDCacheDb();\n    }\n    return instance;\n}\n\n\nZIDCacheDb::~ZIDCacheDb() {\n    close();\n}\n\nint ZIDCacheDb::open(char* name) {\n\n    // check for an already active ZID file\n    if (zidFile != NULL) {\n        return 0;\n    }\n    if (cacheOps.openCache(name, &zidFile, errorBuffer) == 0)\n        cacheOps.readLocalZid(zidFile, associatedZid, NULL, errorBuffer);\n    else {\n        cacheOps.closeCache(zidFile);\n        zidFile = NULL;\n    }\n\n    return ((zidFile == NULL) ? -1 : 1);\n}\n\nvoid ZIDCacheDb::close() {\n\n    if (zidFile != NULL) {\n        cacheOps.closeCache(zidFile);\n        zidFile = NULL;\n    }\n}\n\nZIDRecord *ZIDCacheDb::getRecord(unsigned char *zid) {\n    ZIDRecordDb *zidRecord = new ZIDRecordDb();\n\n    cacheOps.readRemoteZidRecord(zidFile, zid, associatedZid, zidRecord->getRecordData(), errorBuffer);\n\n    zidRecord->setZid(zid);\n\n    // We need to create a new ZID record.\n    if (!zidRecord->isValid()) {\n        zidRecord->setValid();\n        zidRecord->getRecordData()->secureSince = (int64_t)time(NULL);\n        cacheOps.insertRemoteZidRecord(zidFile, zid, associatedZid, zidRecord->getRecordData(), errorBuffer);\n    }\n    return zidRecord;\n}\n\nunsigned int ZIDCacheDb::saveRecord(ZIDRecord *zidRec) {\n    ZIDRecordDb *zidRecord = reinterpret_cast<ZIDRecordDb *>(zidRec);\n\n    cacheOps.updateRemoteZidRecord(zidFile, zidRecord->getIdentifier(), associatedZid, zidRecord->getRecordData(), errorBuffer);\n    return 1;\n}\n\nint32_t ZIDCacheDb::getPeerName(const uint8_t *peerZid, std::string *name) {\n    zidNameRecord_t nameRec;\n    char buffer[201] = {'\\0'};\n\n    nameRec.name = buffer;\n    nameRec.nameLength = 200;\n    cacheOps.readZidNameRecord(zidFile, peerZid, associatedZid, NULL, &nameRec, errorBuffer);\n    if ((nameRec.flags & Valid) != Valid) {\n        return 0;\n    }\n    name->assign(buffer);\n    return name->length();\n}\n\nvoid ZIDCacheDb::putPeerName(const uint8_t *peerZid, const std::string name) {\n    zidNameRecord_t nameRec;\n    char buffer[201] = {'\\0'};\n\n    nameRec.name = buffer;\n    nameRec.nameLength = 200;\n    cacheOps.readZidNameRecord(zidFile, peerZid, associatedZid, NULL, &nameRec, errorBuffer);\n\n    nameRec.name = (char*)name.c_str();\n    nameRec.nameLength = name.length();\n    nameRec.nameLength = nameRec.nameLength > 200 ? 200 : nameRec.nameLength;\n    if ((nameRec.flags & Valid) != Valid) {\n        nameRec.flags = Valid;\n        cacheOps.insertZidNameRecord(zidFile, peerZid, associatedZid, NULL, &nameRec, errorBuffer);\n    }\n    else\n        cacheOps.updateZidNameRecord(zidFile, peerZid, associatedZid, NULL, &nameRec, errorBuffer);\n\n    return;\n}\n\nvoid ZIDCacheDb::cleanup() {\n    cacheOps.cleanCache(zidFile, errorBuffer);\n    cacheOps.readLocalZid(zidFile, associatedZid, NULL, errorBuffer);\n}\n\nvoid *ZIDCacheDb::prepareReadAll() {\n    return cacheOps.prepareReadAllZid(zidFile, errorBuffer);\n}\n\nstatic void formatHex(std::ostringstream &stm, uint8_t *hexBuffer, int32_t length) {\n    stm << std::hex;\n    for (int i = 0; i < length; i++) {\n        stm.width(2);\n        stm << static_cast<uint32_t>(*hexBuffer++);\n    }\n\n}\n\nvoid ZIDCacheDb::formatOutput(remoteZidRecord_t *remZid, const char *nameBuffer, std::string *output) {\n    std::ostringstream stm;\n\n    stm.fill('0');\n    formatHex(stm, associatedZid, IDENTIFIER_LEN); stm << '|';\n    formatHex(stm, remZid->identifier, IDENTIFIER_LEN); stm << '|';\n    uint_8t flag = remZid->flags & 0xff;\n    formatHex(stm, &flag, 1); stm << '|';\n\n    formatHex(stm, remZid->rs1, RS_LENGTH); stm << '|';\n    stm << std::dec;\n    stm << remZid->rs1LastUse; stm << '|';\n    stm << remZid->rs1Ttl; stm << '|';\n\n    formatHex(stm, remZid->rs2, RS_LENGTH); stm << '|';\n    stm << std::dec;\n    stm << remZid->rs2LastUse; stm << '|';\n    stm << remZid->rs2Ttl; stm << '|';\n\n    formatHex(stm, remZid->mitmKey, RS_LENGTH); stm << '|';\n    stm << std::dec;\n    stm << remZid->mitmLastUse; stm << '|';\n\n    stm << remZid->secureSince; stm << '|';\n    stm << nameBuffer;\n    output->assign(stm.str());\n}\n\nvoid *ZIDCacheDb::readNextRecord(void *stmt, std::string *output) {\n    void *iStmnt = stmt;\n    zidNameRecord_t nameRec;\n    ZIDRecordDb zidRec;\n    char buffer[201] = {'\\0'};\n\n    nameRec.name = buffer;\n    nameRec.nameLength = 200;\n    while ((iStmnt = cacheOps.readNextZidRecord(zidFile, stmt, zidRec.getRecordData(), errorBuffer)) != NULL) {\n        if (!zidRec.isValid())\n            continue;\n        cacheOps.readZidNameRecord(zidFile, zidRec.getIdentifier(), associatedZid, NULL, &nameRec, errorBuffer);\n        if ((nameRec.flags & Valid) != Valid)\n            formatOutput(zidRec.getRecordData(), \"\", output);\n        else\n            formatOutput(zidRec.getRecordData(), buffer, output);\n        return iStmnt;\n    }\n    return NULL;\n}\n\nvoid ZIDCacheDb::closeOpenStatment(void *stmt) {\n    cacheOps.closeStatement(stmt);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZIDCacheFile.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n// #define UNIT_TEST\n\n#include <string>\n#include <stdlib.h>\n\n#ifdef _MSC_VER\n#include <io.h>\n#else\n#include <unistd.h>\n#endif\n\n#include <crypto/zrtpDH.h>\n\n#include <libzrtpcpp/ZIDCacheFile.h>\n\n\nstatic ZIDCacheFile* instance;\nstatic int errors = 0;  // maybe we will use as member of ZIDCache later...\n\n\n/**\n * A poor man's factory.\n *\n * The build process must not allow two cache file implementation classes linked\n * into the same library.\n */\n\nZIDCache* getZidCacheInstance() {\n\n    if (instance == NULL) {\n        instance = new ZIDCacheFile();\n    }\n    return instance;\n}\n\n\nvoid ZIDCacheFile::createZIDFile(char* name) {\n    zidFile = fopen(name, \"wb+\");\n    // New file, generate an associated random ZID and save\n    // it as first record\n    if (zidFile != NULL) {\n        randomZRTP(associatedZid, IDENTIFIER_LEN);\n\n        ZIDRecordFile rec;\n        rec.setZid(associatedZid);\n        rec.setOwnZIDRecord();\n        fseek(zidFile, 0L, SEEK_SET);\n        if (fwrite(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) < 1)\n            ++errors;\n        fflush(zidFile);\n    }\n}\n\n/**\n * Migrate old ZID file format to new one.\n *\n * If ZID file is old format:\n * - close it, rename it, then re-open\n * - create ZID file for new format\n * - copy over contents and flags.\n */\nvoid ZIDCacheFile::checkDoMigration(char* name) {\n    FILE* fdOld;\n    unsigned char inb[2];\n    zidrecord1_t recOld;\n\n    fseek(zidFile, 0L, SEEK_SET);\n    if (fread(inb, 2, 1, zidFile) < 1) {\n        ++errors;\n        inb[0] = 0;\n    }\n\n    if (inb[0] > 0) {           // if it's new format just return\n        return;\n    }\n    fclose(zidFile);            // close old ZID file\n    zidFile = NULL;\n\n    // create save file name, rename and re-open\n    // if rename fails, just unlink old ZID file and create a brand new file\n    // just a little inconvenience for the user, need to verify new SAS\n    std::string fn = std::string(name) + std::string(\".save\");\n    if (rename(name, fn.c_str()) < 0) {\n        unlink(name);\n        createZIDFile(name);\n        return;\n    }\n    fdOld = fopen(fn.c_str(), \"rb\");    // reopen old format in read only mode\n\n    // Get first record from old file - is the own ZID\n    fseek(fdOld, 0L, SEEK_SET);\n    if (fread(&recOld, sizeof(zidrecord1_t), 1, fdOld) != 1) {\n        fclose(fdOld);\n        return;\n    }\n    if (recOld.ownZid != 1) {\n        fclose(fdOld);\n        return;\n    }\n    zidFile = fopen(name, \"wb+\");    // create new format file in binary r/w mode\n    if (zidFile == NULL) {\n        fclose(fdOld);\n        return;\n    }\n    // create ZIDRecord in new format, copy over own ZID and write the record\n    ZIDRecordFile rec;\n    rec.setZid(recOld.identifier);\n    rec.setOwnZIDRecord();\n    if (fwrite(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) < 1)\n        ++errors;\n\n    // now copy over all valid records from old ZID file format.\n    // Sequentially read old records, sequentially write new records\n    int numRead;\n    do {\n        numRead = fread(&recOld, sizeof(zidrecord1_t), 1, fdOld);\n        if (numRead == 0) {     // all old records processed\n            break;\n        }\n        // skip own ZID record and invalid records\n        if (recOld.ownZid == 1 || recOld.recValid == 0) {\n            continue;\n        }\n        ZIDRecordFile rec2;\n        rec2.setZid(recOld.identifier);\n        rec2.setValid();\n        if (recOld.rs1Valid & SASVerified) {\n            rec2.setSasVerified();\n        }\n        rec2.setNewRs1(recOld.rs2Data); // TODO: check squenec\n        rec2.setNewRs1(recOld.rs1Data);\n        if (fwrite(rec2.getRecordData(), rec2.getRecordLength(), 1, zidFile) < 1)\n            ++errors;\n\n    } while (numRead == 1);\n    fflush(zidFile);\n}\n\nZIDCacheFile::~ZIDCacheFile() {\n    close();\n}\n\nint ZIDCacheFile::open(char* name) {\n\n    // check for an already active ZID file\n    if (zidFile != NULL) {\n        return 0;\n    }\n    if ((zidFile = fopen(name, \"rb+\")) == NULL) {\n        createZIDFile(name);\n    } else {\n        checkDoMigration(name);\n        if (zidFile != NULL) {\n            ZIDRecordFile rec;\n            fseek(zidFile, 0L, SEEK_SET);\n            if (fread(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) != 1) {\n                fclose(zidFile);\n                zidFile = NULL;\n                return -1;\n            }\n            if (!rec.isOwnZIDRecord()) {\n                fclose(zidFile);\n                zidFile = NULL;\n                return -1;\n            }\n            memcpy(associatedZid, rec.getIdentifier(), IDENTIFIER_LEN);\n        }\n    }\n    return ((zidFile == NULL) ? -1 : 1);\n}\n\nvoid ZIDCacheFile::close() {\n\n    if (zidFile != NULL) {\n        fclose(zidFile);\n        zidFile = NULL;\n    }\n}\n\nZIDRecord *ZIDCacheFile::getRecord(unsigned char *zid) {\n    unsigned long pos;\n    int numRead;\n    //    ZIDRecordFile rec;\n    ZIDRecordFile *zidRecord = new ZIDRecordFile();\n\n    // set read pointer behind first record (\n    fseek(zidFile, zidRecord->getRecordLength(), SEEK_SET);\n\n    do {\n        pos = ftell(zidFile);\n        numRead = fread(zidRecord->getRecordData(), zidRecord->getRecordLength(), 1, zidFile);\n        if (numRead == 0) {\n            break;\n        }\n\n        // skip own ZID record and invalid records\n        if (zidRecord->isOwnZIDRecord() || !zidRecord->isValid()) {\n            continue;\n        }\n\n    } while (numRead == 1 &&\n             memcmp(zidRecord->getIdentifier(), zid, IDENTIFIER_LEN) != 0);\n\n    // If we reached end of file, then no record with the ZID\n    // found. We need to create a new ZID record.\n    if (numRead == 0) {\n        // create new record\n        //        ZIDRecordFile rec1;\n        zidRecord->setZid(zid);\n        zidRecord->setValid();\n        if (fwrite(zidRecord->getRecordData(), zidRecord->getRecordLength(), 1, zidFile) < 1)\n            ++errors;\n    }\n    //  remember position of record in file for save operation\n    zidRecord->setPosition(pos);\n    return zidRecord;\n}\n\nunsigned int ZIDCacheFile::saveRecord(ZIDRecord *zidRec) {\n    ZIDRecordFile *zidRecord = reinterpret_cast<ZIDRecordFile *>(zidRec);\n\n    fseek(zidFile, zidRecord->getPosition(), SEEK_SET);\n    if (fwrite(zidRecord->getRecordData(), zidRecord->getRecordLength(), 1, zidFile) < 1)\n        ++errors;\n    fflush(zidFile);\n    return 1;\n}\n\nint32_t ZIDCacheFile::getPeerName(const uint8_t *peerZid, std::string *name) {\n    return 0;\n}\n\nvoid ZIDCacheFile::putPeerName(const uint8_t *peerZid, const std::string name) {\n    return;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZIDRecordDb.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <time.h>\n\n#include <libzrtpcpp/ZIDRecordDb.h>\n\nvoid ZIDRecordDb::setNewRs1(const unsigned char* data, int32_t expire) {\n\n    // shift RS1 data into RS2 position\n    memcpy(record.rs2, record.rs1, RS_LENGTH);\n    record.rs2Ttl = record.rs1Ttl;\n\n    // set new RS1 data\n    memcpy(record.rs1, data, RS_LENGTH);\n\n    time_t validThru;\n    if (expire == -1) {\n        validThru = -1;\n    }\n    else if (expire <= 0) {\n        validThru = 0;\n    }\n    else {\n        validThru = time(NULL) + expire;\n    }\n    record.rs1Ttl = validThru;\n    resetRs2Valid();\n    setRs1Valid();\n}\n\n\nbool ZIDRecordDb::isRs1NotExpired() {\n    time_t current = time(NULL);\n    time_t validThru;\n\n    validThru = record.rs1Ttl;\n\n    if (validThru == -1)\n        return true;\n    if (validThru == 0)\n        return false;\n    return (current <= validThru) ? true : false;\n}\n\nbool ZIDRecordDb::isRs2NotExpired() {\n    time_t current = time(NULL);\n    time_t validThru;\n\n    validThru = record.rs2Ttl;\n\n    if (validThru == -1)\n        return true;\n    if (validThru == 0)\n        return false;\n    return (current <= validThru) ? true : false;\n}\n\nvoid ZIDRecordDb::setMiTMData(const unsigned char* data) {\n    memcpy(record.mitmKey, data, RS_LENGTH);\n    setMITMKeyAvailable();\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZIDRecordFile.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <time.h>\n\n#include <libzrtpcpp/ZIDRecordFile.h>\n\nvoid ZIDRecordFile::setNewRs1(const unsigned char* data, int32_t expire) {\n\n    // shift RS1 data into RS2 position\n    memcpy(record.rs2Data, record.rs1Data, RS_LENGTH);\n    memcpy(record.rs2Interval, record.rs1Interval, TIME_LENGTH);\n\n    // set new RS1 data\n    memcpy(record.rs1Data, data, RS_LENGTH);\n\n    time_t validThru;\n    if (expire == -1) {\n        validThru = -1;\n    }\n    else if (expire <= 0) {\n        validThru = 0;\n    }\n    else {\n        validThru = time(NULL) + expire;\n    }\n\n    if (sizeof(time_t) == 4) {\n        long long temp = validThru;\n        memcpy(record.rs1Interval, (unsigned char*)&temp, TIME_LENGTH);\n    }\n    else {\n        memcpy(record.rs1Interval, (unsigned char*)&validThru, TIME_LENGTH);\n    }\n    resetRs2Valid();\n    setRs1Valid();\n}\n\n\nbool ZIDRecordFile::isRs1NotExpired() {\n    time_t current = time(NULL);\n    time_t validThru;\n\n    if (sizeof(time_t) == 4) {\n        long long temp;\n        memcpy((unsigned char*)&temp, record.rs1Interval, TIME_LENGTH);\n        validThru = temp;\n    }\n    else {\n        memcpy((unsigned char*)&validThru, record.rs1Interval, TIME_LENGTH);\n    }\n\n    if (validThru == -1)\n        return true;\n    if (validThru == 0)\n        return false;\n    return (current <= validThru) ? true : false;\n}\n\nbool ZIDRecordFile::isRs2NotExpired() {\n    time_t current = time(NULL);\n    time_t validThru;\n\n    if (sizeof(time_t) == 4) {\n        long long temp;\n        memcpy((unsigned char*)&temp, record.rs2Interval, TIME_LENGTH);\n        validThru = temp;\n    }\n    else {\n        memcpy((unsigned char*)&validThru, record.rs2Interval, TIME_LENGTH);\n    }\n\n    if (validThru == -1)\n        return true;\n    if (validThru == 0)\n        return false;\n    return (current <= validThru) ? true : false;\n}\n\nvoid ZIDRecordFile::setMiTMData(const unsigned char* data) {\n    memcpy(record.mitmKey, data, RS_LENGTH);\n    setMITMKeyAvailable();\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZRtp.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n#include <sstream>\n\n#include <crypto/zrtpDH.h>\n#include <crypto/hmac256.h>\n#include <crypto/sha256.h>\n#include <crypto/hmac384.h>\n#include <crypto/sha384.h>\n\n#include <crypto/skeinMac256.h>\n#include <crypto/skein256.h>\n#include <crypto/skeinMac384.h>\n#include <crypto/skein384.h>\n\n#include <crypto/aesCFB.h>\n#include <crypto/twoCFB.h>\n\n#include <libzrtpcpp/ZRtp.h>\n#include <libzrtpcpp/ZrtpStateClass.h>\n#include <libzrtpcpp/ZIDCache.h>\n#include <libzrtpcpp/Base32.h>\n\nusing namespace GnuZrtpCodes;\n\n/* disabled...but used in testing and debugging, probably should have a\n   controlling #define...\n   *\nstatic void hexdump(const char* title, const unsigned char *s, int l) {\n    int n=0;\n\n    if (s == NULL) return;\n\n    fprintf(stderr, \"%s\",title);\n    for( ; n < l ; ++n)\n    {\n        if((n%16) == 0)\n            fprintf(stderr, \"\\n%04x\",n);\n        fprintf(stderr, \" %02x\",s[n]);\n    }\n    fprintf(stderr, \"\\n\");\n}\n * */\n\n/*\n * This method simplifies detection of libzrtpcpp inside Automake, configure\n * and friends\n */\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n    int ZrtpAvailable()\n    {\n        return 1;\n    }\n#ifdef __cplusplus\n}\n#endif\n\nZRtp::ZRtp(uint8_t *myZid, ZrtpCallback *cb, std::string id, ZrtpConfigure* config, bool mitmm, bool sasSignSupport):\n        callback(cb), dhContext(NULL), DHss(NULL), auxSecret(NULL), auxSecretLength(0), rs1Valid(false),\n        rs2Valid(false), msgShaContext(NULL), hash(NULL), cipher(NULL), pubKey(NULL), sasType(NULL), authLength(NULL),\n        multiStream(false), multiStreamAvailable(false), peerIsEnrolled(false), mitmSeen(false), pbxSecretTmp(NULL),\n        enrollmentMode(false), configureAlgos(*config), zidRec(NULL), saveZidRecord(true), masterStream(NULL) {\n\n#ifdef ZRTP_SAS_RELAY_SUPPORT\n    enableMitmEnrollment = config->isTrustedMitM();\n#pragma message \"ZRTP SAS relay support is enabled.\"\n#else\n    enableMitmEnrollment = false;\n#endif\n\n    signatureData = NULL;\n    paranoidMode = config->isParanoidMode();\n\n    // setup the implicit hash function pointers and length\n    hashLengthImpl = SHA256_DIGEST_LENGTH;\n    hashFunctionImpl = sha256;\n    hashListFunctionImpl = sha256;\n\n    hmacFunctionImpl = hmac_sha256;\n    hmacListFunctionImpl = hmac_sha256;\n\n    memcpy(ownZid, myZid, ZID_SIZE);        // save the ZID\n\n    /*\n     * Generate H0 as a random number (256 bits, 32 bytes) and then\n     * the hash chain, refer to chapter 9. Use the implicit hash function.\n     */\n    randomZRTP(H0, HASH_IMAGE_SIZE);\n    sha256(H0, HASH_IMAGE_SIZE, H1);        // hash H0 and generate H1\n    sha256(H1, HASH_IMAGE_SIZE, H2);        // H2\n    sha256(H2, HASH_IMAGE_SIZE, H3);        // H3\n\n    // configure all supported Hello packet versions\n    zrtpHello_11.configureHello(&configureAlgos);\n    zrtpHello_11.setH3(H3);                    // set H3 in Hello, included in helloHash\n    zrtpHello_11.setZid(ownZid);\n    zrtpHello_11.setVersion((uint8_t*)zrtpVersion_11);\n\n\n    zrtpHello_12.configureHello(&configureAlgos);\n    zrtpHello_12.setH3(H3);                 // set H3 in Hello, included in helloHash\n    zrtpHello_12.setZid(ownZid);\n    zrtpHello_12.setVersion((uint8_t*)zrtpVersion_12);\n\n    if (mitmm) {                            // this session acts for a trusted MitM (PBX)\n        zrtpHello_11.setMitmMode();\n        zrtpHello_12.setMitmMode();\n    }\n    if (sasSignSupport) {                   // the application supports SAS signing\n        zrtpHello_11.setSasSign();\n        zrtpHello_12.setSasSign();\n    }\n\n    // Keep array in ascending order (greater index -> greater version)\n    helloPackets[0].packet = &zrtpHello_11;\n    helloPackets[0].version = zrtpHello_11.getVersionInt();\n    setClientId(id, &helloPackets[0]);      // set id, compute HMAC and final helloHash\n\n    helloPackets[1].packet = &zrtpHello_12;\n    helloPackets[1].version = zrtpHello_12.getVersionInt();\n    setClientId(id, &helloPackets[1]);      // set id, compute HMAC and final helloHash\n \n    currentHelloPacket = helloPackets[SUPPORTED_ZRTP_VERSIONS-1].packet;  // start with highest supported version\n    helloPackets[SUPPORTED_ZRTP_VERSIONS].packet = NULL;\n    peerHelloVersion[0] = 0;\n\n    stateEngine = new ZrtpStateClass(this);\n}\n\nZRtp::~ZRtp() {\n    stopZrtp();\n    if (DHss != NULL) {\n        delete DHss;\n        DHss = NULL;\n    }\n    if (stateEngine != NULL) {\n        delete stateEngine;\n        stateEngine = NULL;\n    }\n    if (dhContext != NULL) {\n        delete dhContext;\n        dhContext = NULL;\n    }\n    if (msgShaContext != NULL) {\n        closeHashCtx(msgShaContext, NULL);\n        msgShaContext = NULL;\n    }\n    if (auxSecret != NULL) {\n        delete auxSecret;\n        auxSecret = NULL;\n        auxSecretLength = 0;\n    }\n    if (zidRec != NULL) {\n        delete zidRec;\n        zidRec = NULL;\n    }\n    memset(hmacKeyI, 0, MAX_DIGEST_LENGTH);\n    memset(hmacKeyR, 0, MAX_DIGEST_LENGTH);\n\n    memset(zrtpKeyI, 0, MAX_DIGEST_LENGTH);\n    memset(zrtpKeyR, 0, MAX_DIGEST_LENGTH);\n    /*\n     * Clear the Initiator's srtp key and salt\n     */\n    memset(srtpKeyI, 0, MAX_DIGEST_LENGTH);\n    memset(srtpSaltI, 0,  MAX_DIGEST_LENGTH);\n    /*\n     * Clear he Responder's srtp key and salt\n     */\n    memset(srtpKeyR, 0, MAX_DIGEST_LENGTH);\n    memset(srtpSaltR, 0, MAX_DIGEST_LENGTH);\n\n    memset(zrtpSession, 0, MAX_DIGEST_LENGTH);\n\n    peerNonces.clear();\n}\n\nvoid ZRtp::processZrtpMessage(uint8_t *message, uint32_t pSSRC, size_t length) {\n    Event_t ev;\n\n    peerSSRC = pSSRC;\n    ev.type = ZrtpPacket;\n    ev.length = length;\n    ev.packet = message;\n\n    if (stateEngine != NULL) {\n        stateEngine->processEvent(&ev);\n    }\n}\n\nvoid ZRtp::processTimeout() {\n    Event_t ev;\n\n    ev.type = Timer;\n    if (stateEngine != NULL) {\n        stateEngine->processEvent(&ev);\n    }\n}\n\n#ifdef oldgoclear\nbool ZRtp::handleGoClear(uint8_t *message)\n{\n    char *msg, first, last;\n\n    msg = (char *)message + 4;\n    first = tolower(*msg);\n    last = tolower(*(msg+6));\n\n    if (first == 'g' && last == 'r') {\n        Event_t ev;\n\n        ev.type = ZrtpGoClear;\n        ev.packet = message;\n        if (stateEngine != NULL) {\n            stateEngine->processEvent(&ev);\n        }\n        return true;\n    }\n    else {\n        return false;\n    }\n}\n#endif\n\nvoid ZRtp::startZrtpEngine() {\n    Event_t ev;\n\n    if (stateEngine != NULL && stateEngine->inState(Initial)) {\n        ev.type = ZrtpInitial;\n        stateEngine->processEvent(&ev);\n    }\n}\n\nvoid ZRtp::stopZrtp() {\n    Event_t ev;\n\n    if (stateEngine != NULL) {\n        ev.type = ZrtpClose;\n        stateEngine->processEvent(&ev);\n    }\n}\n\nbool ZRtp::inState(int32_t state)\n{\n    if (stateEngine != NULL) {\n        return stateEngine->inState(state);\n    }\n    else {\n        return false;\n    }\n}\n\nZrtpPacketHello* ZRtp::prepareHello() {\n    return currentHelloPacket;\n}\n\nZrtpPacketHelloAck* ZRtp::prepareHelloAck() {\n    return &zrtpHelloAck;\n}\n\n/*\n * At this point we will assume the role of Initiator. This role may change\n * in case we have a commit-clash. Refer to chapter 5.2 in the spec how\n * to break this tie.\n */\nZrtpPacketCommit* ZRtp::prepareCommit(ZrtpPacketHello *hello, uint32_t* errMsg) {\n\n    myRole = Initiator;\n\n    if (!hello->isLengthOk()) {\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n    // Save data before detailed checks - may aid in analysing problems\n    peerClientId.assign((char*)hello->getClientId(), ZRTP_WORD_SIZE * 4);\n    memcpy(peerHelloVersion, hello->getVersion(), ZRTP_WORD_SIZE);\n    peerHelloVersion[ZRTP_WORD_SIZE] = 0;\n\n    // Save our peer's (presumably the Responder) ZRTP id\n    memcpy(peerZid, hello->getZid(), ZID_SIZE);\n    if (memcmp(peerZid, ownZid, ZID_SIZE) == 0) {       // peers have same ZID????\n        *errMsg = EqualZIDHello;\n        return NULL;\n    }\n    memcpy(peerH3, hello->getH3(), HASH_IMAGE_SIZE);\n\n    int32_t helloLen = hello->getLength() * ZRTP_WORD_SIZE;\n\n    // calculate hash over the received Hello packet - is peer's hello hash.\n    // Use implicit hash algorithm\n    hashFunctionImpl((unsigned char*)hello->getHeaderBase(), helloLen, peerHelloHash);\n\n    sendInfo(Info, InfoHelloReceived);\n\n    /*\n     * The Following section extracts the algorithm from the peer's Hello\n     * packet. Always the preferend offered algorithms are\n     * used. If the received Hello does not contain algo specifiers\n     * or offers only unsupported optional algos then replace\n     * these with mandatory algos and put them into the Commit packet.\n     * Refer to the findBest*() functions.\n     * If this is a MultiStream ZRTP object then do not get the cipher,\n     * authentication from hello packet but use the pre-initialized values\n     * as proposed by the standard. If we switch to responder mode the\n     * commit packet may contain other algos - see function\n     * prepareConfirm2MultiStream(...).\n     */\n    sasType = findBestSASType(hello);\n\n    if (!multiStream) {\n        pubKey = findBestPubkey(hello);                 // Check for public key algorithm first, must set 'hash' as well\n        if (hash == NULL) {\n            *errMsg = UnsuppHashType;\n            return NULL;\n        }\n        if (cipher == NULL)                             // public key selection may have set the cipher already\n            cipher = findBestCipher(hello, pubKey);\n        if (authLength == NULL)                         // public key selection may have set the SRTP authLen already\n            authLength = findBestAuthLen(hello);\n        multiStreamAvailable = checkMultiStream(hello);\n    }\n    else {\n        if (checkMultiStream(hello)) {\n            return prepareCommitMultiStream(hello);\n        }\n        else {\n            // we are in multi-stream but peer does not offer multi-stream\n            // return error code to other party - unsupported PK, must be Mult\n            *errMsg = UnsuppPKExchange;\n            return NULL;\n        }\n    }\n    setNegotiatedHash(hash);\n\n    // Modify here when introducing new DH key agreement, for example\n    // elliptic curves.\n    dhContext = new ZrtpDH(pubKey->getName());\n    dhContext->generatePublicKey();\n\n    dhContext->getPubKeyBytes(pubKeyBytes);\n    sendInfo(Info, InfoCommitDHGenerated);\n\n    // Prepare IV data that we will use during confirm packet encryption.\n    randomZRTP(randomIV, sizeof(randomIV));\n\n    /*\n     * Prepare our DHPart2 packet here. Required to compute HVI. If we stay\n     * in Initiator role then we reuse this packet later in prepareDHPart2().\n     * To create this DH packet we have to compute the retained secret ids,\n     * thus get our peer's retained secret data first.\n     */\n    zidRec = getZidCacheInstance()->getRecord(peerZid);\n\n    //Compute the Initator's and Responder's retained secret ids.\n    computeSharedSecretSet(zidRec);\n\n#ifdef ZRTP_SAS_RELAY_SUPPORT\n    // Check if a PBX application set the MitM flag.\n    mitmSeen = hello->isMitmMode();\n#endif\n\n    signSasSeen = hello->isSasSign();\n    // Construct a DHPart2 message (Initiator's DH message). This packet\n    // is required to compute the HVI (Hash Value Initiator), refer to\n    // chapter 5.4.1.1.\n\n    // Fill the values in the DHPart2 packet\n    zrtpDH2.setPubKeyType(pubKey->getName());\n    zrtpDH2.setMessageType((uint8_t*)DHPart2Msg);\n    zrtpDH2.setRs1Id(rs1IDi);\n    zrtpDH2.setRs2Id(rs2IDi);\n    zrtpDH2.setAuxSecretId(auxSecretIDi);\n    zrtpDH2.setPbxSecretId(pbxSecretIDi);\n    zrtpDH2.setPv(pubKeyBytes);\n    zrtpDH2.setH1(H1);\n\n    int32_t len = zrtpDH2.getLength() * ZRTP_WORD_SIZE;\n\n    // Compute HMAC over DH2, excluding the HMAC field (HMAC_SIZE)\n    // and store in DH2. Key to HMAC is H0, use HASH_IMAGE_SIZE bytes only.\n    // Must use implicit HMAC functions.\n    uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];\n    uint32_t macLen;\n    hmacFunctionImpl(H0, HASH_IMAGE_SIZE, (uint8_t*)zrtpDH2.getHeaderBase(), len-(HMAC_SIZE), hmac, &macLen);\n    zrtpDH2.setHMAC(hmac);\n\n    // Compute the HVI, refer to chapter 5.4.1.1 of the specification\n    computeHvi(&zrtpDH2, hello);\n\n    zrtpCommit.setZid(ownZid);\n    zrtpCommit.setHashType((uint8_t*)hash->getName());\n    zrtpCommit.setCipherType((uint8_t*)cipher->getName());\n    zrtpCommit.setAuthLen((uint8_t*)authLength->getName());\n    zrtpCommit.setPubKeyType((uint8_t*)pubKey->getName());\n    zrtpCommit.setSasType((uint8_t*)sasType->getName());\n    zrtpCommit.setHvi(hvi);\n    zrtpCommit.setH2(H2);\n\n    len = zrtpCommit.getLength() * ZRTP_WORD_SIZE;\n\n    // Compute HMAC over Commit, excluding the HMAC field (HMAC_SIZE)\n    // and store in Hello. Key to HMAC is H1, use HASH_IMAGE_SIZE bytes only.\n    // Must use implicit HMAC functions.\n    hmacFunctionImpl(H1, HASH_IMAGE_SIZE, (uint8_t*)zrtpCommit.getHeaderBase(), len-(HMAC_SIZE), hmac, &macLen);\n    zrtpCommit.setHMAC(hmac);\n\n    // hash first messages to produce overall message hash\n    // First the Responder's Hello message, second the Commit (always Initator's).\n    // Must use negotiated hash.\n    msgShaContext = createHashCtx(msgShaContext);\n    hashCtxFunction(msgShaContext, (unsigned char*)hello->getHeaderBase(), helloLen);\n    hashCtxFunction(msgShaContext, (unsigned char*)zrtpCommit.getHeaderBase(), len);\n\n    // store Hello data temporarily until we can check HMAC after receiving Commit as\n    // Responder or DHPart1 as Initiator\n    storeMsgTemp(hello);\n\n    return &zrtpCommit;\n}\n\nZrtpPacketCommit* ZRtp::prepareCommitMultiStream(ZrtpPacketHello *hello) {\n\n    randomZRTP(hvi, ZRTP_WORD_SIZE*4);  // This is the Multi-Stream NONCE size\n\n    zrtpCommit.setZid(ownZid);\n    zrtpCommit.setHashType((uint8_t*)hash->getName());\n    zrtpCommit.setCipherType((uint8_t*)cipher->getName());\n    zrtpCommit.setAuthLen((uint8_t*)authLength->getName());\n    zrtpCommit.setPubKeyType((uint8_t*)mult);  // this is fixed because of Multi Stream mode\n    zrtpCommit.setSasType((uint8_t*)sasType->getName());\n    zrtpCommit.setNonce(hvi);\n    zrtpCommit.setH2(H2);\n\n    int32_t len = zrtpCommit.getLength() * ZRTP_WORD_SIZE;\n\n    // Compute HMAC over Commit, excluding the HMAC field (HMAC_SIZE)\n    // and store in Hello. Key to HMAC is H1, use HASH_IMAGE_SIZE bytes only.\n    // Must use the implicit HMAC function.\n    uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];\n    uint32_t macLen;\n    hmacFunctionImpl(H1, HASH_IMAGE_SIZE, (uint8_t*)zrtpCommit.getHeaderBase(), len-(HMAC_SIZE), hmac, &macLen);\n    zrtpCommit.setHMACMulti(hmac);\n\n\n    // hash first messages to produce overall message hash\n    // First the Responder's Hello message, second the Commit\n    // (always Initator's).\n    // Must use the negotiated hash.\n    msgShaContext = createHashCtx(msgShaContext);\n\n    int32_t helloLen = hello->getLength() * ZRTP_WORD_SIZE;\n    hashCtxFunction(msgShaContext, (unsigned char*)hello->getHeaderBase(), helloLen);\n    hashCtxFunction(msgShaContext, (unsigned char*)zrtpCommit.getHeaderBase(), len);\n\n    // store Hello data temporarily until we can check HMAC after receiving Commit as\n    // Responder or DHPart1 as Initiator\n    storeMsgTemp(hello);\n\n    return &zrtpCommit;\n}\n\n/*\n * At this point we will take the role of the Responder. We have been in\n * the role of the Initiator before and already sent a commit packet that\n * clashed with a commit packet from our peer. If our HVI was lower than our\n * peer's HVI then we switched to Responder and handle our peer's commit packet\n * here. This method takes care to delete and refresh data left over from a\n * possible Initiator preparation. This belongs to prepared DH data, message\n * hash SHA context\n */\nZrtpPacketDHPart* ZRtp::prepareDHPart1(ZrtpPacketCommit *commit, uint32_t* errMsg) {\n\n    sendInfo(Info, InfoRespCommitReceived);\n\n    if (!commit->isLengthOk(ZrtpPacketCommit::DhExchange)) {\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n\n    // Check if ZID in Commit is the same as we got in Hello\n    uint8_t tmpZid[ZID_SIZE];\n    memcpy(tmpZid, commit->getZid(), ZID_SIZE);\n    if (memcmp(peerZid, tmpZid, ZID_SIZE) != 0) {       // ZIDs do not match????\n        sendInfo(Severe, SevereProtocolError);\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n\n    // The following code checks the hash chain according chapter 10 to detect false ZRTP packets.\n    // Must use the implicit hash function.\n    uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];\n    memcpy(peerH2, commit->getH2(), HASH_IMAGE_SIZE);\n    hashFunctionImpl(peerH2, HASH_IMAGE_SIZE, tmpH3);\n\n    if (memcmp(tmpH3, peerH3, HASH_IMAGE_SIZE) != 0) {\n        *errMsg = IgnorePacket;\n        return NULL;\n    }\n\n    // Check HMAC of previous Hello packet stored in temporary buffer. The\n    // HMAC key of peer's Hello packet is peer's H2 that is contained in the\n    // Commit packet. Refer to chapter 9.1.\n    if (!checkMsgHmac(peerH2)) {\n        sendInfo(Severe, SevereHelloHMACFailed);\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n\n    // check if we support the commited Cipher type\n    AlgorithmEnum* cp = &zrtpSymCiphers.getByName((const char*)commit->getCipherType());\n    if (!cp->isValid()) { // no match - something went wrong\n        *errMsg = UnsuppCiphertype;\n        return NULL;\n    }\n    cipher = cp;\n\n    // check if we support the commited Authentication length\n    cp = &zrtpAuthLengths.getByName((const char*)commit->getAuthLen());\n    if (!cp->isValid()) { // no match - something went wrong\n        *errMsg = UnsuppSRTPAuthTag;\n        return NULL;\n    }\n    authLength = cp;\n\n    // check if we support the commited hash type\n    cp = &zrtpHashes.getByName((const char*)commit->getHashType());\n    if (!cp->isValid()) { // no match - something went wrong\n        *errMsg = UnsuppHashType;\n        return NULL;\n    }\n    // check if the peer's commited hash is the same that we used when\n    // preparing our commit packet. If not do the necessary resets and\n    // recompute some data.\n    if (*(int32_t*)(hash->getName()) != *(int32_t*)(cp->getName())) {\n        hash = cp;\n        setNegotiatedHash(hash);\n        // Compute the Initator's and Responder's retained secret ids\n        // with the committed hash.\n        computeSharedSecretSet(zidRec);\n    }\n    // check if we support the commited pub key type\n    cp = &zrtpPubKeys.getByName((const char*)commit->getPubKeysType());\n    if (!cp->isValid()) { // no match - something went wrong\n        *errMsg = UnsuppPKExchange;\n        return NULL;\n    }\n    if (*(int32_t*)(cp->getName()) == *(int32_t*)ec38 || *(int32_t*)(cp->getName()) == *(int32_t*)e414) {\n        if (!(*(int32_t*)(hash->getName()) == *(int32_t*)s384 || *(int32_t*)(hash->getName()) == *(int32_t*)skn3)) {\n            *errMsg = UnsuppHashType;\n            return NULL;\n        }\n    }\n    pubKey = cp;\n\n    // check if we support the commited SAS type\n    cp = &zrtpSasTypes.getByName((const char*)commit->getSasType());\n    if (!cp->isValid()) { // no match - something went wrong\n        *errMsg = UnsuppSASScheme;\n        return NULL;\n    }\n    sasType = cp;\n\n    // dhContext cannot be NULL - always setup during prepareCommit()\n    // check if we can use the dhContext prepared by prepareCommit(),\n    // if not delete old DH context and generate new one\n    // The algorithm names are 4 chars only, thus we can cast to int32_t\n    if (*(int32_t*)(dhContext->getDHtype()) != *(int32_t*)(pubKey->getName())) {\n        delete dhContext;\n        dhContext = new ZrtpDH(pubKey->getName());\n        dhContext->generatePublicKey();\n    }\n    sendInfo(Info, InfoDH1DHGenerated);\n\n    dhContext->getPubKeyBytes(pubKeyBytes);\n\n    // Re-compute auxSecretIDr because we changed roles *IDr with my H3, *IDi with peer's H3\n    // Setup a DHPart1 packet.\n    myRole = Responder;\n    computeAuxSecretIds();                 // recompute AUX secret ids because we are now Responder, use different H3\n\n    zrtpDH1.setPubKeyType(pubKey->getName());\n    zrtpDH1.setMessageType((uint8_t*)DHPart1Msg);\n    zrtpDH1.setRs1Id(rs1IDr);\n    zrtpDH1.setRs2Id(rs2IDr);\n    zrtpDH1.setAuxSecretId(auxSecretIDr);\n    zrtpDH1.setPbxSecretId(pbxSecretIDr);\n    zrtpDH1.setPv(pubKeyBytes);\n    zrtpDH1.setH1(H1);\n\n    int32_t len = zrtpDH1.getLength() * ZRTP_WORD_SIZE;\n\n    // Compute HMAC over DHPart1, excluding the HMAC field (HMAC_SIZE)\n    // and store in DHPart1.\n    // Use implicit Hash function\n    uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];\n    uint32_t macLen;\n    hmacFunctionImpl(H0, HASH_IMAGE_SIZE, (uint8_t*)zrtpDH1.getHeaderBase(), len-(HMAC_SIZE), hmac, &macLen);\n    zrtpDH1.setHMAC(hmac);\n\n    // We are definitly responder. Save the peer's hvi for later compare.\n    memcpy(peerHvi, commit->getHvi(), HVI_SIZE);\n\n    // We are responder. Release the pre-computed SHA context because it was prepared for Initiator.\n    // Setup and compute for Responder.\n    if (msgShaContext != NULL) {\n        closeHashCtx(msgShaContext, NULL);\n    }\n    msgShaContext = createHashCtx(msgShaContext);\n\n    // Hash messages to produce overall message hash:\n    // First the Responder's (my) Hello message, second the Commit (always Initator's), \n    // then the DH1 message (which is always a Responder's message).\n    // Must use negotiated hash.\n    hashCtxFunction(msgShaContext, (unsigned char*)currentHelloPacket->getHeaderBase(), currentHelloPacket->getLength() * ZRTP_WORD_SIZE);\n    hashCtxFunction(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);\n    hashCtxFunction(msgShaContext, (unsigned char*)zrtpDH1.getHeaderBase(), zrtpDH1.getLength() * ZRTP_WORD_SIZE);\n\n    // store Commit data temporarily until we can check HMAC after we got DHPart2\n    storeMsgTemp(commit);\n\n    return &zrtpDH1;\n}\n\n/*\n * At this point we will take the role of the Initiator.\n */\nZrtpPacketDHPart* ZRtp::prepareDHPart2(ZrtpPacketDHPart *dhPart1, uint32_t* errMsg) {\n\n    uint8_t* pvr;\n\n    sendInfo(Info, InfoInitDH1Received);\n\n    if (!dhPart1->isLengthOk()) {\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n    // Because we are initiator the protocol engine didn't receive Commit\n    // thus could not store a peer's H2. A two step SHA256 is required to\n    // re-compute H3. Then compare with peer's H3 from peer's Hello packet.\n    // Must use implicit hash function.\n    uint8_t tmpHash[IMPL_MAX_DIGEST_LENGTH];\n    hashFunctionImpl(dhPart1->getH1(), HASH_IMAGE_SIZE, tmpHash); // Compute peer's H2\n    memcpy(peerH2, tmpHash, HASH_IMAGE_SIZE);\n    hashFunctionImpl(peerH2, HASH_IMAGE_SIZE, tmpHash);          // Compute peer's H3 (tmpHash)\n\n    if (memcmp(tmpHash, peerH3, HASH_IMAGE_SIZE) != 0) {\n        *errMsg = IgnorePacket;\n        return NULL;\n    }\n\n    // Check HMAC of previous Hello packet stored in temporary buffer. The\n    // HMAC key of the Hello packet is peer's H2 that was computed above.\n    // Refer to chapter 9.1 and chapter 10.\n    if (!checkMsgHmac(peerH2)) {\n        sendInfo(Severe, SevereHelloHMACFailed);\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n\n    // get memory to store DH result TODO: make it fixed memory\n    DHss = new uint8_t[dhContext->getDhSize()];\n    if (DHss == NULL) {\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n\n    // get and check Responder's public value, see chap. 5.4.3 in the spec\n    pvr = dhPart1->getPv();\n    if (!dhContext->checkPubKey(pvr)) {\n        *errMsg = DHErrorWrongPV;\n        return NULL;\n    }\n    dhContext->computeSecretKey(pvr, DHss);\n\n    // We are Initiator: the Responder's Hello and the Initiator's (our) Commit\n    // are already hashed in the context. Now hash the Responder's DH1 and then\n    // the Initiator's (our) DH2 in that order.\n    // Use the negotiated hash function.\n    hashCtxFunction(msgShaContext, (unsigned char*)dhPart1->getHeaderBase(), dhPart1->getLength() * ZRTP_WORD_SIZE);\n    hashCtxFunction(msgShaContext, (unsigned char*)zrtpDH2.getHeaderBase(), zrtpDH2.getLength() * ZRTP_WORD_SIZE);\n\n    // Compute the message Hash\n    closeHashCtx(msgShaContext, messageHash);\n    msgShaContext = NULL;\n    // Now compute the S0, all dependend keys and the new RS1. The function\n    // also performs sign SAS callback if it's active.\n    generateKeysInitiator(dhPart1, zidRec);\n\n    delete dhContext;\n    dhContext = NULL;\n\n    // TODO: at initiator we can call signSAS at this point, don't dealy until confirm1 reveived\n    // store DHPart1 data temporarily until we can check HMAC after receiving Confirm1\n    storeMsgTemp(dhPart1);\n    return &zrtpDH2;\n}\n\n/*\n * At this point we are Responder.\n */\nZrtpPacketConfirm* ZRtp::prepareConfirm1(ZrtpPacketDHPart* dhPart2, uint32_t* errMsg) {\n\n    uint8_t* pvi;\n\n    sendInfo(Info, InfoRespDH2Received);\n\n    if (!dhPart2->isLengthOk()) {\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n    // Because we are responder we received a Commit and stored its H2.\n    // Now re-compute H2 from received H1 and compare with stored peer's H2.\n    // Use implicit hash function\n    uint8_t tmpHash[IMPL_MAX_DIGEST_LENGTH];\n    hashFunctionImpl(dhPart2->getH1(), HASH_IMAGE_SIZE, tmpHash);\n    if (memcmp(tmpHash, peerH2, HASH_IMAGE_SIZE) != 0) {\n        *errMsg = IgnorePacket;\n        return NULL;\n    }\n\n    // Check HMAC of Commit packet stored in temporary buffer. The\n    // HMAC key of the Commit packet is peer's H1 that is contained in\n    // DHPart2. Refer to chapter 9.1 and chapter 10.\n    if (!checkMsgHmac(dhPart2->getH1())) {\n        sendInfo(Severe, SevereCommitHMACFailed);\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n    // Now we have the peer's pvi. Because we are responder re-compute my hvi\n    // using my Hello packet and the Initiator's DHPart2 and compare with\n    // hvi sent in commit packet. If it doesn't macht then a MitM attack\n    // may have occured.\n    computeHvi(dhPart2, currentHelloPacket);\n    if (memcmp(hvi, peerHvi, HVI_SIZE) != 0) {\n        *errMsg = DHErrorWrongHVI;\n        return NULL;\n    }\n    DHss = new uint8_t[dhContext->getDhSize()];\n    if (DHss == NULL) {\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n    // Get and check the Initiator's public value, see chap. 5.4.2 of the spec\n    pvi = dhPart2->getPv();\n    if (!dhContext->checkPubKey(pvi)) {\n        *errMsg = DHErrorWrongPV;\n        return NULL;\n    }\n    dhContext->computeSecretKey(pvi, DHss);\n\n    // Hash the Initiator's DH2 into the message Hash (other messages already prepared, see method prepareDHPart1().\n    // Use neotiated hash function\n    hashCtxFunction(msgShaContext, (unsigned char*)dhPart2->getHeaderBase(), dhPart2->getLength() * ZRTP_WORD_SIZE);\n\n    closeHashCtx(msgShaContext, messageHash);\n    msgShaContext = NULL;\n    /*\n     * The expected shared secret Ids were already computed when we built the\n     * DHPart1 packet. Generate s0, all depended keys, and the new RS1 value\n     * for the ZID record. The functions also performs sign SAS callback if it's\n     * active. May reset the verify flag in ZID record.\n     */\n    generateKeysResponder(dhPart2, zidRec);\n\n    delete dhContext;\n    dhContext = NULL;\n\n    // Fill in Confirm1 packet.\n    zrtpConfirm1.setMessageType((uint8_t*)Confirm1Msg);\n\n    // Check if user verfied the SAS in a previous call and thus verfied\n    // the retained secret. Don't set the verified flag if paranoidMode is true.\n    if (zidRec->isSasVerified() && !paranoidMode) {\n        zrtpConfirm1.setSASFlag();\n    }\n    zrtpConfirm1.setExpTime(0xFFFFFFFF);\n    zrtpConfirm1.setIv(randomIV);\n    zrtpConfirm1.setHashH0(H0);\n\n#ifdef ZRTP_SAS_RELAY_SUPPORT\n    // if this runs at PBX user agent enrollment service then set flag in confirm\n    // packet and store the MitM key\n    if (enrollmentMode) {\n        // As clarification to RFC6189: store new PBX secret only if we don't have\n        // a matching PBX secret for the peer's ZID.\n        if (!peerIsEnrolled) {\n            computePBXSecret();\n            zidRec->setMiTMData(pbxSecretTmp);\n        }\n        // Set flag to enable user's client to ask for confirmation or re-confirmation.\n        zrtpConfirm1.setPBXEnrollment();\n    }\n#endif\n    uint8_t confMac[MAX_DIGEST_LENGTH];\n    uint32_t macLen;\n\n    // Encrypt and HMAC with Responder's key - we are Respondere here\n    int hmlen = (zrtpConfirm1.getLength() - 9) * ZRTP_WORD_SIZE;\n    cipher->getEncrypt()(zrtpKeyR, cipher->getKeylen(), randomIV, zrtpConfirm1.getHashH0(), hmlen);\n    hmacFunction(hmacKeyR, hashLength, (unsigned char*)zrtpConfirm1.getHashH0(), hmlen, confMac, &macLen);\n\n    zrtpConfirm1.setHmac(confMac);\n\n    // store DHPart2 data temporarily until we can check HMAC after receiving Confirm2\n    storeMsgTemp(dhPart2);\n    return &zrtpConfirm1;\n}\n\n/*\n * At this point we are Responder.\n */\nZrtpPacketConfirm* ZRtp::prepareConfirm1MultiStream(ZrtpPacketCommit* commit, uint32_t* errMsg) {\n\n    sendInfo(Info, InfoRespCommitReceived);\n\n    if (!commit->isLengthOk(ZrtpPacketCommit::MultiStream)) {\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n    // The following code checks the hash chain according chapter 10 to detect\n    // false ZRTP packets.\n    // Use implicit hash function\n    uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];\n    memcpy(peerH2, commit->getH2(), HASH_IMAGE_SIZE);\n    hashFunctionImpl(peerH2, HASH_IMAGE_SIZE, tmpH3);\n\n    if (memcmp(tmpH3, peerH3, HASH_IMAGE_SIZE) != 0) {\n        *errMsg = IgnorePacket;\n        return NULL;\n    }\n\n    // Check HMAC of previous Hello packet stored in temporary buffer. The\n    // HMAC key of peer's Hello packet is peer's H2 that is contained in the\n    // Commit packet. Refer to chapter 9.1.\n    if (!checkMsgHmac(peerH2)) {\n        sendInfo(Severe, SevereHelloHMACFailed);\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n\n    if (!checkAndSetNonce(commit->getNonce())) {\n        *errMsg = NonceReused;\n        return NULL;\n    }\n    // check if Commit contains \"Mult\" as pub key type\n    AlgorithmEnum* cp = &zrtpPubKeys.getByName((const char*)commit->getPubKeysType());\n    if (!cp->isValid() || *(int32_t*)(cp->getName()) != *(int32_t*)mult) {\n        *errMsg = UnsuppPKExchange;\n        return NULL;\n    }\n\n    // check if we support the commited cipher\n    cp = &zrtpSymCiphers.getByName((const char*)commit->getCipherType());\n    if (!cp->isValid()) { // no match - something went wrong\n        *errMsg = UnsuppCiphertype;\n        return NULL;\n    }\n    cipher = cp;\n\n    // check if we support the commited Authentication length\n    cp = &zrtpAuthLengths.getByName((const char*)commit->getAuthLen());\n    if (!cp->isValid()) { // no match - something went wrong\n        *errMsg = UnsuppSRTPAuthTag;\n        return NULL;\n    }\n    authLength = cp;\n\n    // check if we support the commited hash type\n    cp = &zrtpHashes.getByName((const char*)commit->getHashType());\n    if (!cp->isValid()) { // no match - something went wrong\n        *errMsg = UnsuppHashType;\n        return NULL;\n    }\n    // check if the peer's commited hash is the same that we used when\n    // preparing our commit packet. If not do the necessary resets and\n    // recompute some data.\n    if (*(int32_t*)(hash->getName()) != *(int32_t*)(cp->getName())) {\n        hash = cp;\n        setNegotiatedHash(hash);\n    }\n    myRole = Responder;\n\n    // We are responder. Release a possibly pre-computed SHA256 context\n    // because this was prepared for Initiator. Then create a new one.\n    if (msgShaContext != NULL) {\n        closeHashCtx(msgShaContext, NULL);\n    }\n    msgShaContext = createHashCtx(msgShaContext);\n\n    // Hash messages to produce overall message hash:\n    // First the Responder's (my) Hello message, second the Commit\n    // (always Initator's)\n    // use negotiated hash\n    hashCtxFunction(msgShaContext, (unsigned char*)currentHelloPacket->getHeaderBase(), currentHelloPacket->getLength() * ZRTP_WORD_SIZE);\n    hashCtxFunction(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);\n\n    closeHashCtx(msgShaContext, messageHash);\n    msgShaContext = NULL;\n\n    generateKeysMultiStream();\n\n    // Fill in Confirm1 packet.\n    zrtpConfirm1.setMessageType((uint8_t*)Confirm1Msg);\n    zrtpConfirm1.setExpTime(0xFFFFFFFF);\n    zrtpConfirm1.setIv(randomIV);\n    zrtpConfirm1.setHashH0(H0);\n\n    uint8_t confMac[MAX_DIGEST_LENGTH];\n    uint32_t macLen;\n\n    // Encrypt and HMAC with Responder's key - we are Respondere here\n    int32_t hmlen = (zrtpConfirm1.getLength() - 9) * ZRTP_WORD_SIZE;\n    cipher->getEncrypt()(zrtpKeyR, cipher->getKeylen(), randomIV, zrtpConfirm1.getHashH0(), hmlen);\n\n    // Use negotiated HMAC (hash)\n    hmacFunction(hmacKeyR, hashLength, (unsigned char*)zrtpConfirm1.getHashH0(), hmlen, confMac, &macLen);\n\n    zrtpConfirm1.setHmac(confMac);\n\n    // Store Commit data temporarily until we can check HMAC after receiving Confirm2\n    storeMsgTemp(commit);\n    return &zrtpConfirm1;\n}\n\n/*\n * At this point we are Initiator.\n */\nZrtpPacketConfirm* ZRtp::prepareConfirm2(ZrtpPacketConfirm* confirm1, uint32_t* errMsg) {\n\n    sendInfo(Info, InfoInitConf1Received);\n\n    if (!confirm1->isLengthOk()) {\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n    uint8_t confMac[MAX_DIGEST_LENGTH];\n    uint32_t macLen;\n\n    // Use the Responder's keys here because we are Initiator here and\n    // receive packets from Responder\n    int16_t hmlen = (confirm1->getLength() - 9) * ZRTP_WORD_SIZE;\n\n    // Use negotiated HMAC (hash)\n    hmacFunction(hmacKeyR, hashLength, (unsigned char*)confirm1->getHashH0(), hmlen, confMac, &macLen);\n\n    if (memcmp(confMac, confirm1->getHmac(), HMAC_SIZE) != 0) {\n        *errMsg = ConfirmHMACWrong;\n        return NULL;\n    }\n    cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), (uint8_t*)confirm1->getIv(), confirm1->getHashH0(), hmlen);\n\n    // Check HMAC of DHPart1 packet stored in temporary buffer. The\n    // HMAC key of the DHPart1 packet is peer's H0 that is contained in\n    // Confirm1. Refer to chapter 9.\n    if (!checkMsgHmac(confirm1->getHashH0())) {\n        sendInfo(Severe, SevereDH1HMACFailed);\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n    signatureLength = confirm1->getSignatureLength();\n    if (signSasSeen && signatureLength > 0 && confirm1->isSignatureLengthOk()) {\n        signatureData = confirm1->getSignatureData();\n        callback->checkSASSignature(sasHash);\n        // TODO: error handling if checkSASSignature returns false.\n    }\n    /*\n     * The Confirm1 is ok, handle the Retained secret stuff and inform\n     * GUI about state.\n     */\n    bool sasFlag = confirm1->isSASFlag();\n\n    // Our peer did not confirm the SAS in last session, thus reset\n    // our SAS flag too. Reset the flag also if paranoidMode is true.\n    if (!sasFlag || paranoidMode) {\n        zidRec->resetSasVerified();\n    }\n    // get verified flag from current RS1 before set a new RS1. This\n    // may not be set even if peer's flag is set in confirm1 message.\n    sasFlag = zidRec->isSasVerified();\n\n    // now we are ready to save the new RS1 which inherits the verified\n    // flag from old RS1\n    zidRec->setNewRs1((const uint8_t*)newRs1);\n\n    // now generate my Confirm2 message\n    zrtpConfirm2.setMessageType((uint8_t*)Confirm2Msg);\n    zrtpConfirm2.setHashH0(H0);\n\n    if (sasFlag) {\n        zrtpConfirm2.setSASFlag();\n    }\n    zrtpConfirm2.setExpTime(0xFFFFFFFF);\n    zrtpConfirm2.setIv(randomIV);\n\n#ifdef ZRTP_SAS_RELAY_SUPPORT\n    // Compute PBX secret if we are in enrollemnt mode (PBX user agent)\n    // or enrollment was enabled at normal user agent and flag in confirm packet\n    if (enrollmentMode || (enableMitmEnrollment && confirm1->isPBXEnrollment())) {\n        computePBXSecret();\n\n        // if this runs at PBX user agent enrollment service then set flag in confirm\n        // packet and store the MitM key. The PBX user agent service always stores\n        // its MitM key.\n        if (enrollmentMode) {\n            // As clarification to RFC6189: store new PBX secret only if we don't have\n            // a matching PBX secret for the peer's ZID.\n            if (!peerIsEnrolled) {\n                computePBXSecret();\n                zidRec->setMiTMData(pbxSecretTmp);\n            }\n            // Set flag to enable user's client to ask for confirmation or re-confirmation.\n            zrtpConfirm2.setPBXEnrollment();\n        }\n    }\n#endif\n    if (saveZidRecord)\n        getZidCacheInstance()->saveRecord(zidRec);\n\n    // Encrypt and HMAC with Initiator's key - we are Initiator here\n    hmlen = (zrtpConfirm2.getLength() - 9) * ZRTP_WORD_SIZE;\n    cipher->getEncrypt()(zrtpKeyI, cipher->getKeylen(), randomIV, zrtpConfirm2.getHashH0(), hmlen);\n\n    // Use negotiated HMAC (hash)\n    hmacFunction(hmacKeyI, hashLength, (unsigned char*)zrtpConfirm2.getHashH0(), hmlen, confMac, &macLen);\n\n    zrtpConfirm2.setHmac(confMac);\n\n#ifdef ZRTP_SAS_RELAY_SUPPORT\n    // Ask for enrollment only if enabled via configuration and the\n    // confirm1 packet contains the enrollment flag. The enrolling user\n    // agent stores the MitM key only if the user accepts the enrollment\n    // request.\n    if (enableMitmEnrollment && confirm1->isPBXEnrollment()) {\n        // As clarification to RFC6189: if already enrolled (having a matching PBX secret)\n        // ask for reconfirmation.\n        if (!peerIsEnrolled) {\n            callback->zrtpAskEnrollment(EnrollmentRequest);\n        }\n        else {\n            callback->zrtpAskEnrollment(EnrollmentReconfirm);\n        }\n    }\n#endif\n    return &zrtpConfirm2;\n}\n\n/*\n * At this point we are Initiator.\n */\nZrtpPacketConfirm* ZRtp::prepareConfirm2MultiStream(ZrtpPacketConfirm* confirm1, uint32_t* errMsg) {\n\n    // check Confirm1 packet using the keys\n    // prepare Confirm2 packet\n    // don't update SAS, RS\n    sendInfo(Info, InfoInitConf1Received);\n\n    if (!confirm1->isLengthOk()) {\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n    uint8_t confMac[MAX_DIGEST_LENGTH];\n    uint32_t macLen;\n\n    closeHashCtx(msgShaContext, messageHash);\n    msgShaContext = NULL;\n    myRole = Initiator;\n\n    generateKeysMultiStream();\n\n    // Use the Responder's keys here because we are Initiator here and\n    // receive packets from Responder\n    int32_t hmlen = (confirm1->getLength() - 9) * ZRTP_WORD_SIZE;\n\n    // Use negotiated HMAC (hash)\n    hmacFunction(hmacKeyR, hashLength, (unsigned char*)confirm1->getHashH0(), hmlen, confMac, &macLen);\n\n    if (memcmp(confMac, confirm1->getHmac(), HMAC_SIZE) != 0) {\n        *errMsg = ConfirmHMACWrong;\n        return NULL;\n    }\n    // Cast away the const for the IV - the standalone AES CFB modifies IV on return\n    cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), (uint8_t*)confirm1->getIv(), confirm1->getHashH0(), hmlen);\n\n    // Because we are initiator the protocol engine didn't receive Commit and\n    // because we are using multi-stream mode here we also did not receive a DHPart1 and\n    // thus could not store a responder's H2 or H1. A two step hash is required to\n    // re-compute H1, H2.\n    // USe implicit hash function.\n    uint8_t tmpHash[IMPL_MAX_DIGEST_LENGTH];\n    hashFunctionImpl(confirm1->getHashH0(), HASH_IMAGE_SIZE, tmpHash); // Compute peer's H1 in tmpHash\n    hashFunctionImpl(tmpHash, HASH_IMAGE_SIZE, tmpHash);               // Compute peer's H2 in tmpHash\n    memcpy(peerH2, tmpHash, HASH_IMAGE_SIZE);                          // copy and truncate to peerH2\n\n    // Check HMAC of previous Hello packet stored in temporary buffer. The\n    // HMAC key of the Hello packet is peer's H2 that was computed above.\n    // Refer to chapter 9.1 and chapter 10.\n    if (!checkMsgHmac(peerH2)) {\n        sendInfo(Severe, SevereHelloHMACFailed);\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n    // now generate my Confirm2 message\n    zrtpConfirm2.setMessageType((uint8_t*)Confirm2Msg);\n    zrtpConfirm2.setHashH0(H0);\n    zrtpConfirm2.setExpTime(0xFFFFFFFF);\n    zrtpConfirm2.setIv(randomIV);\n\n    // Encrypt and HMAC with Initiator's key - we are Initiator here\n    hmlen = (zrtpConfirm2.getLength() - 9) * ZRTP_WORD_SIZE;\n    cipher->getEncrypt()(zrtpKeyI, cipher->getKeylen(), randomIV, zrtpConfirm2.getHashH0(), hmlen);\n\n    // Use negotiated HMAC (hash)\n    hmacFunction(hmacKeyI, hashLength, (unsigned char*)zrtpConfirm2.getHashH0(), hmlen, confMac, &macLen);\n\n    zrtpConfirm2.setHmac(confMac);\n    return &zrtpConfirm2;\n}\n\n/*\n * At this point we are Responder.\n */\nZrtpPacketConf2Ack* ZRtp::prepareConf2Ack(ZrtpPacketConfirm *confirm2, uint32_t* errMsg) {\n\n    sendInfo(Info, InfoRespConf2Received);\n\n    if (!confirm2->isLengthOk()) {\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n    uint8_t confMac[MAX_DIGEST_LENGTH];\n    uint32_t macLen;\n\n    // Use the Initiator's keys here because we are Responder here and\n    // reveice packets from Initiator\n    int16_t hmlen = (confirm2->getLength() - 9) * ZRTP_WORD_SIZE;\n\n    // Use negotiated HMAC (hash)\n    hmacFunction(hmacKeyI, hashLength,\n                 (unsigned char*)confirm2->getHashH0(),\n                 hmlen, confMac, &macLen);\n\n    if (memcmp(confMac, confirm2->getHmac(), HMAC_SIZE) != 0) {\n        *errMsg = ConfirmHMACWrong;\n        return NULL;\n    }\n    // Cast away the const for the IV - the standalone AES CFB modifies IV on return\n    cipher->getDecrypt()(zrtpKeyI, cipher->getKeylen(), (uint8_t*)confirm2->getIv(), confirm2->getHashH0(), hmlen);\n\n    if (!multiStream) {\n        // Check HMAC of DHPart2 packet stored in temporary buffer. The\n        // HMAC key of the DHPart2 packet is peer's H0 that is contained in\n        // Confirm2. Refer to chapter 9.1 and chapter 10.\n        if (!checkMsgHmac(confirm2->getHashH0())) {\n            sendInfo(Severe, SevereDH2HMACFailed);\n            *errMsg = CriticalSWError;\n            return NULL;\n        }\n        signatureLength = confirm2->getSignatureLength();\n        if (signSasSeen && signatureLength > 0 && confirm2->isSignatureLengthOk() ) {\n            signatureData = confirm2->getSignatureData();\n            callback->checkSASSignature(sasHash);\n            // TODO: error handling if checkSASSignature returns false.\n        }\n        /*\n        * The Confirm2 is ok, handle the Retained secret stuff and inform\n        * GUI about state.\n        */\n        bool sasFlag = confirm2->isSASFlag();\n        // Our peer did not confirm the SAS in last session, thus reset\n        // our SAS flag too. Reset the flag also if paranoidMode is true.\n        if (!sasFlag || paranoidMode) {\n            zidRec->resetSasVerified();\n        }\n\n        // save new RS1, this inherits the verified flag from old RS1\n        zidRec->setNewRs1((const uint8_t*)newRs1);\n        if (saveZidRecord)\n            getZidCacheInstance()->saveRecord(zidRec);\n\n#ifdef ZRTP_SAS_RELAY_SUPPORT\n        // Ask for enrollment only if enabled via configuration and the\n        // confirm packet contains the enrollment flag. The enrolling user\n        // agent stores the MitM key only if the user accepts the enrollment\n        // request.\n        if (enableMitmEnrollment && confirm2->isPBXEnrollment()) {\n            computePBXSecret();\n            // As clarification to RFC6189: if already enrolled (having a matching PBX secret)\n            // ask for reconfirmation.\n            if (!peerIsEnrolled) {\n                callback->zrtpAskEnrollment(EnrollmentRequest);\n            }\n            else {\n                callback->zrtpAskEnrollment(EnrollmentReconfirm);\n            }\n        }\n#endif\n    }\n    else {\n        // Check HMAC of Commit packet stored in temporary buffer. The\n        // HMAC key of the Commit packet is initiator's H1\n        // use implicit hash function.\n        uint8_t tmpHash[IMPL_MAX_DIGEST_LENGTH];\n        hashFunctionImpl(confirm2->getHashH0(), HASH_IMAGE_SIZE, tmpHash); // Compute initiator's H1 in tmpHash\n\n        if (!checkMsgHmac(tmpHash)) {\n            sendInfo(Severe, SevereCommitHMACFailed);\n            *errMsg = CriticalSWError;\n            return NULL;\n        }\n    }\n    return &zrtpConf2Ack;\n}\n\nZrtpPacketErrorAck* ZRtp::prepareErrorAck(ZrtpPacketError* epkt) {\n    if (epkt->getLength() < 4)\n        sendInfo(ZrtpError, CriticalSWError * -1);\n    else\n        sendInfo(ZrtpError, epkt->getErrorCode() * -1);\n    return &zrtpErrorAck;\n}\n\nZrtpPacketError* ZRtp::prepareError(uint32_t errMsg) {\n    zrtpError.setErrorCode(errMsg);\n    return &zrtpError;\n}\n\nZrtpPacketPingAck* ZRtp::preparePingAck(ZrtpPacketPing* ppkt) {\n    if (ppkt->getLength() != 6)                    // A PING packet must have a length of 6 words\n        return NULL;\n    // Because we do not support ZRTP proxy mode use the truncated ZID.\n    // If this code shall be used in ZRTP proxy implementation the computation\n    // of the endpoint hash must be enhanced (see chaps 5.15ff and 5.16)\n    zrtpPingAck.setLocalEpHash(ownZid);\n    zrtpPingAck.setRemoteEpHash(ppkt->getEpHash());\n    zrtpPingAck.setSSRC(peerSSRC);\n    return &zrtpPingAck;\n}\n\nZrtpPacketRelayAck* ZRtp::prepareRelayAck(ZrtpPacketSASrelay* srly, uint32_t* errMsg) {\n\n#ifdef ZRTP_SAS_RELAY_SUPPORT\n    // handle and render SAS relay data only if the peer announced that it is a trusted\n    // PBX. Don't handle SAS relay in paranoidMode.\n    if (!mitmSeen || paranoidMode)\n        return &zrtpRelayAck;\n\n    if (!srly->isLengthOk()) {\n        *errMsg = CriticalSWError;\n        return NULL;\n    }\n    uint8_t* hkey, *ekey;\n    // If we are responder then the PBX used it's Initiator keys\n    if (myRole == Responder) {\n        hkey = hmacKeyI;\n        ekey = zrtpKeyI;\n    }\n    else {\n        hkey = hmacKeyR;\n        ekey = zrtpKeyR;\n    }\n\n    uint8_t confMac[MAX_DIGEST_LENGTH];\n    uint32_t macLen;\n\n    int16_t hmlen = (srly->getLength() - 9) * ZRTP_WORD_SIZE;\n\n    // Use negotiated HMAC (hash)\n    hmacFunction(hkey, hashLength, (unsigned char*)srly->getFiller(), hmlen, confMac, &macLen);\n\n    if (memcmp(confMac, srly->getHmac(), HMAC_SIZE) != 0) {\n        *errMsg = ConfirmHMACWrong;\n        return NULL;                // TODO - check error handling\n    }\n    // Cast away the const for the IV - the standalone AES CFB modifies IV on return\n    cipher->getDecrypt()(ekey, cipher->getKeylen(), (uint8_t*)srly->getIv(), (uint8_t*)srly->getFiller(), hmlen);\n\n    const uint8_t* newSasHash = srly->getTrustedSas();\n    bool sasHashNull = true;\n    for (int i = 0; i < HASH_IMAGE_SIZE; i++) {\n        if (newSasHash[i] != 0) {\n            sasHashNull = false;\n            break;\n        }\n    }\n    std::string cs(cipher->getReadable());\n    cs.append(\"/\").append(pubKey->getName());\n\n    // Check if new SAS is null or a trusted MitM relationship doesn't exist.\n    // If this is the case then don't render and don't show the new SAS - use\n    // our computed SAS hash but we may use a different SAS rendering algorithm to\n    // render the computed SAS.\n    if (sasHashNull || !peerIsEnrolled) {\n        cs.append(\"/MitM\");\n        newSasHash = sasHash;\n    }\n    else {\n        cs.append(\"/SASviaMitM\");\n    }\n    // If other SAS schemes required - check here and use others\n    const uint8_t* render = srly->getSasAlgo();\n    AlgorithmEnum* renderAlgo = &zrtpSasTypes.getByName((const char*)render);\n    uint8_t sasBytes[4];\n    if (renderAlgo->isValid()) {\n        sasBytes[0] = newSasHash[0];\n        sasBytes[1] = newSasHash[1];\n        sasBytes[2] = newSasHash[2] & 0xf0;\n        sasBytes[3] = 0;\n        if (*(int32_t*)b32 == *(int32_t*)(renderAlgo->getName())) {\n            SAS = Base32(sasBytes, 20).getEncoded();\n        }\n        else {\n            SAS.assign(sas256WordsEven[sasBytes[0]]).append(\":\").append(sas256WordsOdd[sasBytes[1]]);\n        }\n    }\n    bool verify = zidRec->isSasVerified() && srly->isSASFlag();\n    callback->srtpSecretsOn(cs, SAS, verify);\n\n#endif\n    return &zrtpRelayAck;\n}\n\n// TODO Implement GoClear handling\nZrtpPacketClearAck* ZRtp::prepareClearAck(ZrtpPacketGoClear* gpkt) {\n    sendInfo(Warning, WarningGoClearReceived);\n    return &zrtpClearAck;\n}\n\nZrtpPacketGoClear* ZRtp::prepareGoClear(uint32_t errMsg) {\n    ZrtpPacketGoClear* gclr = &zrtpGoClear;\n    gclr->clrClearHmac();\n    return gclr;\n}\n\n/*\n * The next functions look up and return a prefered algorithm. These\n * functions work as follows:\n * - If the Hello packet does not contain an algorithm (number of algorithms\n*    is zero) then return the mandatory algorithm.\n * - Build a list of algorithm names and ids from configuration data. If\n *   the configuration data does not contain a mandatory algorithm append\n *   the mandatory algorithm to the list and ids.\n * - Build a list of algorithm names from the Hello message. If\n *   the Hello message does not contain a mandatory algorithm append\n *   the mandatory algorithm to the list.\n * - Lookup a matching algorithm. The list built from Hello takes\n *   precedence in the lookup (indexed by the outermost loop).\n *\n * This guarantees that we always return a supported alogrithm respecting\n * the order of algorithms in the Hello message\n *\n * The mandatory algorithms are: (internal enums are our prefered algoritms)\n * Hash:                S256 (SHA 256)             (internal enum Sha256)\n * Symmetric Cipher:    AES1 (AES 128)             (internal enum Aes128)\n * SRTP Authentication: HS32 and HS80 (32/80 bits) (internal enum AuthLen32)\n * Key Agreement:       DH3k (3072 Diffie-Helman)  (internal enum Dh3072)\n *\n */\nAlgorithmEnum* ZRtp::findBestHash(ZrtpPacketHello *hello) {\n\n    int i;\n    int ii;\n    int numAlgosOffered;\n    AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+1];\n\n    int numAlgosConf;\n    AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];\n\n    // If Hello does not contain any hash names return Sha256, its mandatory\n    int num = hello->getNumHashes();\n    if (num == 0) {\n        return &zrtpHashes.getByName(mandatoryHash);\n    }\n    // Build list of configured hash algorithm names.\n    numAlgosConf = configureAlgos.getNumConfiguredAlgos(HashAlgorithm);\n    for (i = 0; i < numAlgosConf; i++) {\n        algosConf[i] = &configureAlgos.getAlgoAt(HashAlgorithm, i);\n    }\n\n    // Build list of offered known algos in Hello, append mandatory algos if necessary\n    for (numAlgosOffered = 0, i = 0; i < num; i++) {\n        algosOffered[numAlgosOffered] = &zrtpHashes.getByName((const char*)hello->getHashType(i));\n        if (!algosOffered[numAlgosOffered]->isValid())\n            continue;\n        numAlgosOffered++;\n    }\n\n    // Lookup offered algos in configured algos.\n    for (i = 0; i < numAlgosOffered; i++) {\n        for (ii = 0; ii < numAlgosConf; ii++) {\n            if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {\n                return algosConf[ii];\n            }\n        }\n    }\n    return &zrtpHashes.getByName(mandatoryHash);\n}\n\n\nAlgorithmEnum* ZRtp::findBestCipher(ZrtpPacketHello *hello, AlgorithmEnum* pk) {\n\n    int i;\n    int ii;\n    int numAlgosOffered;\n    AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+1];\n\n    int numAlgosConf;\n    AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];\n\n    int num = hello->getNumCiphers();\n    if (num == 0 || (*(int32_t*)(pk->getName()) == *(int32_t*)dh2k)) {\n        return &zrtpSymCiphers.getByName(aes1);\n    }\n\n    // Build list of configured cipher algorithm names.\n    numAlgosConf = configureAlgos.getNumConfiguredAlgos(CipherAlgorithm);\n    for (i = 0; i < numAlgosConf; i++) {\n        algosConf[i] = &configureAlgos.getAlgoAt(CipherAlgorithm, i);\n    }\n    // Build list of offered known algos names in Hello.\n    for (numAlgosOffered = 0, i = 0; i < num; i++) {\n        algosOffered[numAlgosOffered] = &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));\n        if (!algosOffered[numAlgosOffered]->isValid())\n            continue;\n        numAlgosOffered++;\n    }\n    // Lookup offered algos in configured algos.  Prefer algorithms that appear first in Hello packet (offered).\n    for (i = 0; i < numAlgosOffered; i++) {\n        for (ii = 0; ii < numAlgosConf; ii++) {\n            if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {\n                return algosConf[ii];\n            }\n        }\n    }\n    // If we don't have a match - use the mandatory algorithm\n    return &zrtpSymCiphers.getByName(mandatoryCipher);\n}\n\n// We can have the non-NIST in the list of orderedAlgos even if they are not available\n// in the code (refer to ZrtpConfigure.cpp). If they are not build in they cannot appear\n// in'configureAlgos' and thus not in the intersection lists. Thus a ZRTP build that\n// does not include the non-NIST curves also works without problems.\n//\nAlgorithmEnum* ZRtp::findBestPubkey(ZrtpPacketHello *hello) {\n\n    AlgorithmEnum* peerIntersect[ZrtpConfigure::maxNoOfAlgos+1];\n    AlgorithmEnum* ownIntersect[ZrtpConfigure::maxNoOfAlgos+1];\n\n    // Build list of own pubkey algorithm names, must follow the order\n    // defined in RFC 6189, chapter 4.1.2.\n    const char *orderedAlgos[] = {dh2k, e255, ec25, dh3k, e414, ec38};\n    int numOrderedAlgos = sizeof(orderedAlgos) / sizeof(const char*);\n\n    int numAlgosPeer = hello->getNumPubKeys();\n    if (numAlgosPeer == 0) {\n        hash = findBestHash(hello);                    // find a hash algorithm\n        return &zrtpPubKeys.getByName(mandatoryPubKey);\n    }\n    // Build own list of intersecting algos, keep own order or algorithms\n    // The list must include real public key algorithms only, so skip mult-stream mode, \n    // preshared and alike.\n    int numAlgosOwn = configureAlgos.getNumConfiguredAlgos(PubKeyAlgorithm);\n    int numOwnIntersect = 0;\n    for (int i = 0; i < numAlgosOwn; i++) {\n        ownIntersect[numOwnIntersect] = &configureAlgos.getAlgoAt(PubKeyAlgorithm, i);\n        if (*(int32_t*)(ownIntersect[numOwnIntersect]->getName()) == *(int32_t*)mult) {\n            continue;                               // skip multi-stream mode\n        }\n        for (int ii = 0; ii < numAlgosPeer; ii++) {\n            if (*(int32_t*)(ownIntersect[numOwnIntersect]->getName()) == *(int32_t*)(zrtpPubKeys.getByName((const char*)hello->getPubKeyType(ii)).getName())) {\n                numOwnIntersect++;\n                break;\n            }\n        }\n    }\n    // Build list of peer's intersecting algos: take own list as input and build a \n    // list of algorithms that we have in common. The order of the list is according\n    // to peer's Hello packet (peer's preferences). \n    int numPeerIntersect = 0;\n    for (int i = 0; i < numAlgosPeer; i++) {\n        peerIntersect[numPeerIntersect] = &zrtpPubKeys.getByName((const char*)hello->getPubKeyType(i));\n        for (int ii = 0; ii < numOwnIntersect; ii++) {\n            if (*(int32_t*)(ownIntersect[ii]->getName()) == *(int32_t*)(peerIntersect[numPeerIntersect]->getName())) {\n                numPeerIntersect++;\n                break;\n            }\n        }\n    }\n    if (numPeerIntersect == 0) {       // If we don't have a common algorithm - use mandatory algorithms\n        hash = findBestHash(hello);\n        return &zrtpPubKeys.getByName(mandatoryPubKey);\n    }\n\n    // If we have only one algorithm in common or if the first entry matches - take it.\n    // Otherwise determine which algorithm from the intersection lists is first in the \n    // list of ordered algorithms and select it (RFC6189, section 4.1.2).\n    AlgorithmEnum* useAlgo;\n    if (numPeerIntersect > 1 && *(int32_t*)(ownIntersect[0]->getName()) != *(int32_t*)(peerIntersect[0]->getName())) {\n        int own, peer;\n\n        const int32_t *name = (int32_t*)ownIntersect[0]->getName();\n        for (own = 0; own < numOrderedAlgos; own++) {\n            if (*name == *(int32_t*)orderedAlgos[own])\n                break;\n        }\n        name = (int32_t*)peerIntersect[0]->getName();\n        for (peer = 0; peer < numOrderedAlgos; peer++) {\n            if (*name == *(int32_t*)orderedAlgos[peer])\n                break;\n        }\n        if (own < peer) {\n            useAlgo = ownIntersect[0];\n        }\n        else {\n            useAlgo = peerIntersect[0];\n        }\n        // find fastest of conf vs intersecting\n    }\n    else {\n        useAlgo = peerIntersect[0];\n    }\n    int32_t algoName = *(int32_t*)(useAlgo->getName());\n\n    // select a corresponding strong hash if necessary.\n    if (algoName == *(int32_t*)ec38 || algoName == *(int32_t*)e414) {\n        hash = getStrongHashOffered(hello, algoName);\n        cipher = getStrongCipherOffered(hello, algoName);\n    }\n    else {\n        hash = getHashOffered(hello, algoName);;\n        cipher = getCipherOffered(hello, algoName);\n    }\n    authLength = getAuthLenOffered(hello, algoName);\n    return useAlgo;\n}\n\nAlgorithmEnum* ZRtp::findBestSASType(ZrtpPacketHello *hello) {\n\n    int  i;\n    int ii;\n    int numAlgosOffered;\n    AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+1];\n\n    int numAlgosConf;\n    AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];\n\n    int num = hello->getNumSas();\n    if (num == 0) {\n        return &zrtpSasTypes.getByName(mandatorySasType);\n    }\n    // Build list of configured SAS algorithm names\n    numAlgosConf = configureAlgos.getNumConfiguredAlgos(SasType);\n    for (i = 0; i < numAlgosConf; i++) {\n        algosConf[i] = &configureAlgos.getAlgoAt(SasType, i);\n    }\n    // Build list of offered known algos in Hello,\n    for (numAlgosOffered = 0, i = 0; i < num; i++) {\n        algosOffered[numAlgosOffered] = &zrtpSasTypes.getByName((const char*)hello->getSasType(i));\n        if (!algosOffered[numAlgosOffered]->isValid())\n            continue;\n        numAlgosOffered++;\n    }\n    // Lookup offered algos in configured algos. Prefer algorithms that appear first in Hello packet (offered).\n    for (i = 0; i < numAlgosOffered; i++) {\n        for (ii = 0; ii < numAlgosConf; ii++) {\n            if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {\n                return algosConf[ii];\n            }\n        }\n    }\n    // If we don't have a match - use the mandatory algorithm\n    return &zrtpSasTypes.getByName(mandatorySasType);\n}\n\nAlgorithmEnum* ZRtp::findBestAuthLen(ZrtpPacketHello *hello) {\n\n    int  i;\n    int ii;\n    int numAlgosOffered;\n    AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+2];\n\n    int numAlgosConf;\n    AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+2];\n\n    int num = hello->getNumAuth();\n    if (num == 0) {\n        return &zrtpAuthLengths.getByName(mandatoryAuthLen_1);\n    }\n\n    // Build list of configured Authentication tag length algorithm names.\n    numAlgosConf = configureAlgos.getNumConfiguredAlgos(AuthLength);\n    for (i = 0; i < numAlgosConf; i++) {\n        algosConf[i] = &configureAlgos.getAlgoAt(AuthLength, i);\n    }\n\n    // Build list of offered known algos in Hello.\n    for (numAlgosOffered = 0, i = 0; i < num; i++) {\n        algosOffered[numAlgosOffered] = &zrtpAuthLengths.getByName((const char*)hello->getAuthLen(i));\n        if (!algosOffered[numAlgosOffered]->isValid())\n            continue;\n        numAlgosOffered++;\n    }\n\n    // Lookup offered algos in configured algos. Prefer algorithms that appear first in Hello packet (offered).\n    for (i = 0; i < numAlgosOffered; i++) {\n        for (ii = 0; ii < numAlgosConf; ii++) {\n            if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {\n                return algosConf[ii];\n            }\n        }\n    }\n    // If we don't have a match - use the mandatory algorithm\n    return &zrtpAuthLengths.getByName(mandatoryAuthLen_1);\n}\n\n// The following set of functions implement a 'non-NIST first policy' if nonNist computes \n// to true. They prefer nonNist algorithms if these are available. Otherwise they use the NIST\n// counterpart or simply call the according findBest*(...) function.\n//\n// Only the findBestPubkey(...) function calls them after it selected the public key algorithm.\n// If the public key algorithm is non-NIST and if the policy is set to PreferNonNist then\n// nonNist becomes true.\n//\n// The functions work according to the RFC6189 spec: the initiator can select every algorithm\n// that both parties support. Thus the Initiator can even select an algorithm the wasn't offered\n// in its own Hello packet but that the Initiator found in the peer's Hello and that is available\n// for it.\n//\nAlgorithmEnum* ZRtp::getStrongHashOffered(ZrtpPacketHello *hello, int32_t algoName) {\n\n    int numHash = hello->getNumHashes();\n    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;\n\n    if (nonNist) {\n        for (int i = 0; i < numHash; i++) {\n            int32_t nm = *(int32_t*)(hello->getHashType(i));\n            if (nm == *(int32_t*)skn3) {\n                return &zrtpHashes.getByName((const char*)hello->getHashType(i));\n            }\n        }\n    }\n    for (int i = 0; i < numHash; i++) {\n        int32_t nm = *(int32_t*)(hello->getHashType(i));\n        if (nm == *(int32_t*)s384 || nm == *(int32_t*)skn3) {\n            return &zrtpHashes.getByName((const char*)hello->getHashType(i));\n        }\n    }\n    return NULL;         // returning NULL -> prepareCommit(...) terminates ZRTP, missing strong hash is an error\n}\n\nAlgorithmEnum* ZRtp::getStrongCipherOffered(ZrtpPacketHello *hello, int32_t algoName) {\n\n    int num = hello->getNumCiphers();\n    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;\n\n    if (nonNist) {\n        for (int i = 0; i < num; i++) {\n            int32_t nm = *(int32_t*)(hello->getCipherType(i));\n            if (nm == *(int32_t*)two3) {\n                return &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));\n            }\n        }\n    }\n    for (int i = 0; i < num; i++) {\n        int32_t nm = *(int32_t*)(hello->getCipherType(i));\n        if (nm == *(int32_t*)aes3 || nm == *(int32_t*)two3) {\n            return &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));\n        }\n    }\n    return NULL;       // returning NULL -> prepareCommit(...) finds the best cipher\n}\n\nAlgorithmEnum* ZRtp::getHashOffered(ZrtpPacketHello *hello, int32_t algoName) {\n\n    int num = hello->getNumHashes();\n    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;\n\n    if (nonNist) {\n        for (int i = 0; i < num; i++) {\n            int32_t nm = *(int32_t*)(hello->getHashType(i));\n            if (nm == *(int32_t*)skn2 || nm == *(int32_t*)skn3) {\n                return &zrtpHashes.getByName((const char*)hello->getHashType(i));\n            }\n        }\n    }\n    return findBestHash(hello);\n}\n\nAlgorithmEnum* ZRtp::getCipherOffered(ZrtpPacketHello *hello, int32_t algoName) {\n\n    int num = hello->getNumCiphers();\n    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;\n\n    if (nonNist) {\n        for (int i = 0; i < num; i++) {\n            int32_t nm = *(int32_t*)(hello->getCipherType(i));\n            if (nm == *(int32_t*)two2 || nm == *(int32_t*)two3) {\n                return &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));\n            }\n        }\n    }\n    return NULL;       // returning NULL -> prepareCommit(...) finds the best cipher\n}\n\nAlgorithmEnum* ZRtp::getAuthLenOffered(ZrtpPacketHello *hello, int32_t algoName) {\n\n    int num = hello->getNumAuth();\n    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;\n\n    if (nonNist) {\n        for (int i = 0; i < num; i++) {\n            int32_t nm = *(int32_t*)(hello->getAuthLen(i));\n            if (nm == *(int32_t*)sk32 || nm == *(int32_t*)sk64) {\n                return &zrtpAuthLengths.getByName((const char*)hello->getAuthLen(i));\n            }\n        }\n    }\n    return findBestAuthLen(hello);\n}\n\nbool ZRtp::checkMultiStream(ZrtpPacketHello *hello) {\n\n    int  i;\n    int num = hello->getNumPubKeys();\n\n    // Multi Stream mode is mandatory, thus if nothing is offered then it is supported :-)\n    if (num == 0) {\n        return true;\n    }\n    for (i = 0; i < num; i++) {\n        if (*(int32_t*)(hello->getPubKeyType(i)) == *(int32_t*)mult) {\n            return true;\n        }\n    }\n    return false;\n}\n\nbool ZRtp::verifyH2(ZrtpPacketCommit *commit) {\n    uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];\n\n    // packet does not have the correct size, treat H2 verfication as failed.\n    if (!commit->isLengthOk(multiStream ? ZrtpPacketCommit::MultiStream : ZrtpPacketCommit::DhExchange))\n        return false;\n\n    sha256(commit->getH2(), HASH_IMAGE_SIZE, tmpH3);\n    if (memcmp(tmpH3, peerH3, HASH_IMAGE_SIZE) != 0) {\n        return false;\n    }\n    return true;\n}\n\nvoid ZRtp::computeHvi(ZrtpPacketDHPart* dh, ZrtpPacketHello *hello) {\n\n    unsigned char* data[3];\n    unsigned int length[3];\n    /*\n     * populate the vector to compute the HVI hash according to the\n     * ZRTP specification.\n     */\n    data[0] = (uint8_t*)dh->getHeaderBase();\n    length[0] = dh->getLength() * ZRTP_WORD_SIZE;\n\n    data[1] = (uint8_t*)hello->getHeaderBase();\n    length[1] = hello->getLength() * ZRTP_WORD_SIZE;\n\n    data[2] = NULL;            // terminate data chunks\n    hashListFunction(data, length, hvi);\n    return;\n}\n\nvoid ZRtp:: computeSharedSecretSet(ZIDRecord *zidRec) {\n\n    /*\n     * Compute the Initiator's and Reponder's retained shared secret Ids.\n     * Use negotiated HMAC.\n     */\n    uint8_t randBuf[RS_LENGTH];\n    uint32_t macLen;\n\n    detailInfo.secretsCached = 0;\n    if (!zidRec->isRs1Valid()) {\n        randomZRTP(randBuf, RS_LENGTH);\n        hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs1IDi, &macLen);\n        hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), rs1IDr, &macLen);\n    }\n    else {\n        rs1Valid = true;\n        hmacFunction((unsigned char*)zidRec->getRs1(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs1IDi, &macLen);\n        hmacFunction((unsigned char*)zidRec->getRs1(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs1IDr, &macLen);\n        detailInfo.secretsCached = Rs1;\n    }\n\n    if (!zidRec->isRs2Valid()) {\n        randomZRTP(randBuf, RS_LENGTH);\n        hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs2IDi, &macLen);\n        hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), rs2IDr, &macLen);\n    }\n    else {\n        rs2Valid = true;\n        hmacFunction((unsigned char*)zidRec->getRs2(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs2IDi, &macLen);\n        hmacFunction((unsigned char*)zidRec->getRs2(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs2IDr, &macLen);\n        detailInfo.secretsCached |= Rs2;\n    }\n\n    if (!zidRec->isMITMKeyAvailable()) {\n        randomZRTP(randBuf, RS_LENGTH);\n        hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), pbxSecretIDi, &macLen);\n        hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), pbxSecretIDr, &macLen);\n\n    }\n    else {\n        hmacFunction((unsigned char*)zidRec->getMiTMData(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), pbxSecretIDi, &macLen);\n        hmacFunction((unsigned char*)zidRec->getMiTMData(), RS_LENGTH, (unsigned char*)responder, strlen(responder), pbxSecretIDr, &macLen);\n        detailInfo.secretsCached |= Pbx;\n    }\n    computeAuxSecretIds();\n}\n\nvoid ZRtp::computeAuxSecretIds() {\n    uint8_t randBuf[RS_LENGTH];\n    uint32_t macLen;\n\n    if (auxSecret == NULL) {\n        randomZRTP(randBuf, RS_LENGTH);\n        hmacFunction(randBuf, RS_LENGTH, H3, HASH_IMAGE_SIZE, auxSecretIDi, &macLen);\n        hmacFunction(randBuf, RS_LENGTH, H3, HASH_IMAGE_SIZE, auxSecretIDr, &macLen);\n    }\n    else {\n        if (myRole == Initiator) {  // I'm initiator thus use my H3 for initiator's IDi, peerH3 for respnder's IDr\n            hmacFunction(auxSecret, auxSecretLength, H3, HASH_IMAGE_SIZE, auxSecretIDi, &macLen);\n            hmacFunction(auxSecret, auxSecretLength, peerH3, HASH_IMAGE_SIZE, auxSecretIDr, &macLen);\n        }\n        else {\n            hmacFunction(auxSecret, auxSecretLength, peerH3, HASH_IMAGE_SIZE, auxSecretIDi, &macLen);\n            hmacFunction(auxSecret, auxSecretLength, H3, HASH_IMAGE_SIZE, auxSecretIDr, &macLen);\n        }\n    }\n}\n\n/*\n * memset_volatile is a volatile pointer to the memset function.\n * You can call (*memset_volatile)(buf, val, len) or even\n * memset_volatile(buf, val, len) just as you would call\n * memset(buf, val, len), but the use of a volatile pointer\n * guarantees that the compiler will not optimise the call away.\n */\nstatic void * (*volatile memset_volatile)(void *, int, size_t) = memset;\n\n/*\n * The DH packet for this function is DHPart1 and contains the Responder's\n * retained secret ids. Compare them with the expected secret ids (refer\n * to chapter 5.3 in the specification).\n * When using this method then we are in Initiator role.\n */\nvoid ZRtp::generateKeysInitiator(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec) {\n    const uint8_t* setD[3];\n    int32_t rsFound = 0;\n\n    setD[0] = setD[1] = setD[2] = NULL;\n\n    detailInfo.secretsMatchedDH = 0;\n    if (memcmp(rs1IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs1IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0)\n        detailInfo.secretsMatchedDH |= Rs1;\n    if (memcmp(rs2IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs2IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0)\n        detailInfo.secretsMatchedDH |= Rs2;\n    /*\n     * Select the real secrets into setD. The dhPart is DHpart1 message\n     * received from responder. rs1IDr and rs2IDr are the expected ids using\n     * the initator's cached retained secrets.\n     */\n    // Check which RS we shall use for first place (s1)\n    detailInfo.secretsMatched = 0;\n    if (memcmp(rs1IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0) {\n        setD[0] = zidRec->getRs1();\n        rsFound = 0x1;\n        detailInfo.secretsMatched = Rs1;\n    }\n    else if (memcmp(rs1IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0) {\n        setD[0] = zidRec->getRs1();\n        rsFound = 0x2;\n        detailInfo.secretsMatched = Rs1;\n    }\n    else if (memcmp(rs2IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0) {\n        setD[0] = zidRec->getRs2();\n        rsFound = 0x4;\n        detailInfo.secretsMatched = Rs2;\n    }\n    else if (memcmp(rs2IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0) {\n        setD[0] = zidRec->getRs2();\n        rsFound = 0x8;\n        detailInfo.secretsMatched = Rs2;\n    }\n\n    if (memcmp(auxSecretIDr, dhPart->getAuxSecretId(), 8) == 0) {\n        DEBUGOUT((fprintf(stdout, \"Initiator: Match for aux secret found\\n\")));\n        setD[1] = auxSecret;\n        detailInfo.secretsMatched |= Aux;\n        detailInfo.secretsMatchedDH |= Aux;\n    }\n    if (auxSecret != NULL && (detailInfo.secretsMatched & Aux) == 0) {\n        sendInfo(Warning, WarningNoExpectedAuxMatch);\n    }\n\n#ifdef ZRTP_SAS_RELAY_SUPPORT\n    // check if we have a matching PBX secret and place it third (s3)\n    if (memcmp(pbxSecretIDr, dhPart->getPbxSecretId(), HMAC_SIZE) == 0) {\n        DEBUGOUT((fprintf(stdout, \"%c: Match for Other_secret found\\n\", zid[0])));\n        setD[2] = zidRec->getMiTMData();\n        detailInfo.secretsMatched |= Pbx;\n        detailInfo.secretsMatchedDH |= Pbx;\n        // Flag to record that fact that we have a MitM key of the other peer.\n        peerIsEnrolled = true;\n    }\n#endif\n    // Check if some retained secrets found\n    if (rsFound == 0) {                        // no RS matches found\n        if (rs1Valid || rs2Valid) {            // but valid RS records in cache\n            sendInfo(Warning, WarningNoExpectedRSMatch);\n            zidRec->resetSasVerified();\n            saveZidRecord = false;             // Don't save RS until user verfied/confirmed SAS\n        }\n        else {                                 // No valid RS record in cache\n            sendInfo(Warning, WarningNoRSMatch);\n        }\n    }\n    else {                                     // at least one RS matches\n        sendInfo(Info, InfoRSMatchFound);\n    }\n    /*\n     * Ready to generate s0 here.\n     * The formular to compute S0 (Refer to ZRTP specification 5.4.4):\n     *\n      s0 = hash( counter | DHResult | \"ZRTP-HMAC-KDF\" | ZIDi | ZIDr | \\\n      total_hash | len(s1) | s1 | len(s2) | s2 | len(s3) | s3)\n     *\n     * Note: in this function we are Initiator, thus ZIDi is our zid\n     * (zid), ZIDr is the peer's zid (peerZid).\n     */\n\n    /*\n     * These arrays hold the pointers and lengths of the data that must be\n     * hashed to create S0.  According to the formula the max number of\n     * elements to hash is 12, add one for the terminating \"NULL\"\n     */\n    unsigned char* data[13];\n    unsigned int   length[13];\n    uint32_t pos = 0;                  // index into the array\n\n    // we need a number of length data items, so define them here\n    uint32_t counter, sLen[3];\n\n    //Very first element is a fixed counter, big endian\n    counter = 1;\n    counter = zrtpHtonl(counter);\n    data[pos] = (unsigned char*)&counter;\n    length[pos++] = sizeof(uint32_t);\n\n    // Next is the DH result itself\n    data[pos] = DHss;\n    length[pos++] = dhContext->getDhSize();\n\n    // Next the fixed string \"ZRTP-HMAC-KDF\"\n    data[pos] = (unsigned char*)KDFString;\n    length[pos++] = strlen(KDFString);\n\n    // Next is Initiator's id (ZIDi), in this case as Initiator\n    // it is zid\n    data[pos] = ownZid;\n    length[pos++] = ZID_SIZE;\n\n    // Next is Responder's id (ZIDr), in this case our peer's id\n    data[pos] = peerZid;\n    length[pos++] = ZID_SIZE;\n\n    // Next ist total hash (messageHash) itself\n    data[pos] = messageHash;\n    length[pos++] = hashLength;\n\n    /*\n     * For each matching shared secret hash the length of\n     * the shared secret as 32 bit big-endian number followd by the\n     * shared secret itself. The length of a shared seceret is\n     * currently fixed to RS_LENGTH. If a shared\n     * secret is not used _only_ its length is hased as zero\n     * length. NOTE: if implementing auxSecret and/or pbxSecret -> check\n     * this length stuff again.\n     */\n    int secretHashLen = RS_LENGTH;\n    secretHashLen = zrtpHtonl(secretHashLen);        // prepare 32 bit big-endian number\n\n    for (int32_t i = 0; i < 3; i++) {\n        if (setD[i] != NULL) {           // a matching secret, set length, then secret\n            sLen[i] = secretHashLen;\n            data[pos] = (unsigned char*)&sLen[i];\n            length[pos++] = sizeof(uint32_t);\n            data[pos] = (unsigned char*)setD[i];\n            length[pos++] = (i != 1) ? RS_LENGTH : auxSecretLength;\n        }\n        else {                           // no machting secret, set length 0, skip secret\n            sLen[i] = 0;\n            data[pos] = (unsigned char*)&sLen[i];\n            length[pos++] = sizeof(uint32_t);\n        }\n    }\n\n    data[pos] = NULL;\n    hashListFunction(data, length, s0);\n//  hexdump(\"S0 I\", s0, hashLength);\n\n    memset_volatile(DHss, 0, dhContext->getDhSize());\n    delete[] DHss;\n    DHss = NULL;\n\n    computeSRTPKeys();\n    memset(s0, 0, MAX_DIGEST_LENGTH);\n}\n/*\n * The DH packet for this function is DHPart2 and contains the Initiator's\n * retained secret ids. Compare them with the expected secret ids (refer\n * to chapter 5.3.1 in the specification).\n */\nvoid ZRtp::generateKeysResponder(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec) {\n    const uint8_t* setD[3];\n    int32_t rsFound = 0;\n\n    setD[0] = setD[1] = setD[2] = NULL;\n\n    detailInfo.secretsMatchedDH = 0;\n    if (memcmp(rs1IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs1IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0)\n        detailInfo.secretsMatchedDH |= Rs1;\n    if (memcmp(rs2IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs2IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0)\n        detailInfo.secretsMatchedDH |= Rs2;\n\n    /*\n     * Select the real secrets into setD\n     */\n    // Check which RS we shall use for first place (s1)\n    detailInfo.secretsMatched = 0;\n    if (memcmp(rs1IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0) {\n        setD[0] = zidRec->getRs1();\n        rsFound = 0x1;\n        detailInfo.secretsMatched = Rs1;\n    }\n    else if (memcmp(rs1IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0) {\n        setD[0] = zidRec->getRs1();\n        rsFound = 0x2;\n        detailInfo.secretsMatched = Rs1;\n    }\n    else if (memcmp(rs2IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0) {\n        setD[0] = zidRec->getRs2();\n        rsFound |= 0x4;\n        detailInfo.secretsMatched = Rs2;\n    }\n    else if (memcmp(rs2IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0) {\n        setD[0] = zidRec->getRs2();\n        rsFound |= 0x8;\n        detailInfo.secretsMatched = Rs2;\n    }\n\n    if (memcmp(auxSecretIDi, dhPart->getAuxSecretId(), 8) == 0) {\n        DEBUGOUT((fprintf(stdout, \"Responder: Match for aux secret found\\n\")));\n        setD[1] = auxSecret;\n        detailInfo.secretsMatched |= Aux;\n        detailInfo.secretsMatchedDH |= Aux;\n    }\n    // If we have an auxSecret but no match from peer - report this.\n    if (auxSecret != NULL && (detailInfo.secretsMatched & Aux) == 0) {\n        sendInfo(Warning, WarningNoExpectedAuxMatch);\n    }\n\n#ifdef ZRTP_SAS_RELAY_SUPPORT\n    if (memcmp(pbxSecretIDi, dhPart->getPbxSecretId(), 8) == 0) {\n        DEBUGOUT((fprintf(stdout, \"%c: Match for PBX secret found\\n\", ownZid[0])));\n        setD[2] = zidRec->getMiTMData();\n        detailInfo.secretsMatched |= Pbx;\n        detailInfo.secretsMatchedDH |= Pbx;\n        peerIsEnrolled = true;\n    }\n#endif\n    // Check if some retained secrets found\n    if (rsFound == 0) {                        // no RS matches found\n        if (rs1Valid || rs2Valid) {            // but valid RS records in cache\n            sendInfo(Warning, WarningNoExpectedRSMatch);\n            zidRec->resetSasVerified();\n            saveZidRecord = false;             // Don't save RS until user verfied/confirmed SAS\n        }\n        else {                                 // No valid RS record in cache\n            sendInfo(Warning, WarningNoRSMatch);\n        }\n    }\n    else {                                     // at least one RS matches\n        sendInfo(Info, InfoRSMatchFound);\n    }\n\n    /*\n     * ready to generate s0 here.\n     * The formular to compute S0 (Refer to ZRTP specification 5.4.4):\n     *\n      s0 = hash( counter | DHResult | \"ZRTP-HMAC-KDF\" | ZIDi | ZIDr | \\\n      total_hash | len(s1) | s1 | len(s2) | s2 | len(s3) | s3)\n     *\n     * Note: in this function we are Responder, thus ZIDi is the peer's zid\n     * (peerZid), ZIDr is our zid.\n     */\n\n    /*\n     * These arrays hold the pointers and lengths of the data that must be\n     * hashed to create S0.  According to the formula the max number of\n     * elements to hash is 12, add one for the terminating \"NULL\"\n     */\n    unsigned char* data[13];\n    unsigned int   length[13];\n    uint32_t pos = 0;                  // index into the array\n\n\n    // we need a number of length data items, so define them here\n    uint32_t counter, sLen[3];\n\n    //Very first element is a fixed counter, big endian\n    counter = 1;\n    counter = zrtpHtonl(counter);\n    data[pos] = (unsigned char*)&counter;\n    length[pos++] = sizeof(uint32_t);\n\n    // Next is the DH result itself\n    data[pos] = DHss;\n    length[pos++] = dhContext->getDhSize();\n\n    // Next the fixed string \"ZRTP-HMAC-KDF\"\n    data[pos] = (unsigned char*)KDFString;\n    length[pos++] = strlen(KDFString);\n\n    // Next is Initiator's id (ZIDi), in this case as Responder\n    // it is peerZid\n    data[pos] = peerZid;\n    length[pos++] = ZID_SIZE;\n\n    // Next is Responder's id (ZIDr), in this case our own zid\n    data[pos] = ownZid;\n    length[pos++] = ZID_SIZE;\n\n    // Next ist total hash (messageHash) itself\n    data[pos] = messageHash;\n    length[pos++] = hashLength;\n\n    /*\n     * For each matching shared secret hash the length of\n     * the shared secret as 32 bit big-endian number followd by the\n     * shared secret itself. The length of a shared seceret is\n     * currently fixed to SHA256_DIGEST_LENGTH. If a shared\n     * secret is not used _only_ its length is hased as zero\n     * length. NOTE: if implementing auxSecret and/or pbxSecret -> check\n     * this length stuff again.\n     */\n    int secretHashLen = RS_LENGTH;\n    secretHashLen = zrtpHtonl(secretHashLen);        // prepare 32 bit big-endian number\n\n    for (int32_t i = 0; i < 3; i++) {\n        if (setD[i] != NULL) {           // a matching secret, set length, then secret\n            sLen[i] = secretHashLen;\n            data[pos] = (unsigned char*)&sLen[i];\n            length[pos++] = sizeof(uint32_t);\n            data[pos] = (unsigned char*)setD[i];\n            length[pos++] = (i != 1) ? RS_LENGTH : auxSecretLength;\n        }\n        else {                           // no machting secret, set length 0, skip secret\n            sLen[i] = 0;\n            data[pos] = (unsigned char*)&sLen[i];\n            length[pos++] = sizeof(uint32_t);\n        }\n    }\n\n    data[pos] = NULL;\n    hashListFunction(data, length, s0);\n//  hexdump(\"S0 R\", s0, hashLength);\n\n    memset_volatile(DHss, 0, dhContext->getDhSize());\n    delete[] DHss;\n    DHss = NULL;\n\n    computeSRTPKeys();\n    memset(s0, 0, MAX_DIGEST_LENGTH);\n}\n\n\nvoid ZRtp::KDF(uint8_t* key, uint32_t keyLength, uint8_t* label, int32_t labelLength,\n               uint8_t* context, int32_t contextLength, int32_t L, uint8_t* output) {\n\n    unsigned char* data[6];\n    uint32_t length[6];\n    uint32_t pos = 0;                  // index into the array\n    uint32_t maclen = 0;\n\n    // Very first element is a fixed counter, big endian\n    uint32_t counter = 1;\n    counter = zrtpHtonl(counter);\n    data[pos] = (unsigned char*)&counter;\n    length[pos++] = sizeof(uint32_t);\n\n    // Next element is the label, null terminated, labelLength includes null byte.\n    data[pos] = label;\n    length[pos++] = labelLength;\n\n    // Next is the KDF context\n    data[pos] = context;\n    length[pos++] = contextLength;\n\n    // last element is HMAC length in bits, big endian\n    uint32_t len = zrtpHtonl(L);\n    data[pos] = (unsigned char*)&len;\n    length[pos++] = sizeof(uint32_t);\n\n    data[pos] = NULL;\n\n    // Use negotiated hash.\n    hmacListFunction(key, keyLength, data, length, output, &maclen);\n}\n\n// Compute the Multi Stream mode s0\nvoid ZRtp::generateKeysMultiStream() {\n\n    // allocate the maximum size, compute real size to use\n    uint8_t KDFcontext[sizeof(peerZid)+sizeof(ownZid)+sizeof(messageHash)];\n    int32_t kdfSize = sizeof(peerZid)+sizeof(ownZid)+hashLength;\n\n    if (myRole == Responder) {\n        memcpy(KDFcontext, peerZid, sizeof(peerZid));\n        memcpy(KDFcontext+sizeof(peerZid), ownZid, sizeof(ownZid));\n    }\n    else {\n        memcpy(KDFcontext, ownZid, sizeof(ownZid));\n        memcpy(KDFcontext+sizeof(ownZid), peerZid, sizeof(peerZid));\n    }\n    memcpy(KDFcontext+sizeof(ownZid)+sizeof(peerZid), messageHash, hashLength);\n\n    KDF(zrtpSession, hashLength, (unsigned char*)zrtpMsk, strlen(zrtpMsk)+1, KDFcontext, kdfSize, hashLength*8, s0);\n\n    memset(KDFcontext, 0, sizeof(KDFcontext));\n\n    computeSRTPKeys();\n}\n\nvoid ZRtp::computePBXSecret() {\n#ifdef ZRTP_SAS_RELAY_SUPPORT\n    // Construct the KDF context as per ZRTP specification chap 7.3.1:\n    // ZIDi || ZIDr\n    uint8_t KDFcontext[sizeof(peerZid)+sizeof(ownZid)];\n    int32_t kdfSize = sizeof(peerZid)+sizeof(ownZid);\n\n    if (myRole == Responder) {\n        memcpy(KDFcontext, peerZid, sizeof(peerZid));\n        memcpy(KDFcontext+sizeof(peerZid), ownZid, sizeof(ownZid));\n    }\n    else {\n        memcpy(KDFcontext, ownZid, sizeof(ownZid));\n        memcpy(KDFcontext+sizeof(ownZid), peerZid, sizeof(peerZid));\n    }\n\n    KDF(zrtpSession, hashLength, (unsigned char*)zrtpTrustedMitm, strlen(zrtpTrustedMitm)+1, KDFcontext,\n        kdfSize, SHA256_DIGEST_LENGTH * 8, pbxSecretTmpBuffer);\n\n    pbxSecretTmp = pbxSecretTmpBuffer;  // set pointer to buffer, signal PBX secret was computed\n#endif\n}\n\nvoid ZRtp::computeSRTPKeys() {\n\n    // allocate the maximum size, compute real size to use\n    uint8_t KDFcontext[sizeof(peerZid)+sizeof(ownZid)+sizeof(messageHash)];\n    int32_t kdfSize = sizeof(peerZid)+sizeof(ownZid)+hashLength;\n\n    int32_t keyLen = cipher->getKeylen() * 8;\n\n    if (myRole == Responder) {\n        memcpy(KDFcontext, peerZid, sizeof(peerZid));\n        memcpy(KDFcontext+sizeof(peerZid), ownZid, sizeof(ownZid));\n    }\n    else {\n        memcpy(KDFcontext, ownZid, sizeof(ownZid));\n        memcpy(KDFcontext+sizeof(ownZid), peerZid, sizeof(peerZid));\n    }\n    memcpy(KDFcontext+sizeof(ownZid)+sizeof(peerZid), messageHash, hashLength);\n\n    // Inititiator key and salt\n    KDF(s0, hashLength, (unsigned char*)iniMasterKey, strlen(iniMasterKey)+1, KDFcontext, kdfSize, keyLen, srtpKeyI);\n    KDF(s0, hashLength, (unsigned char*)iniMasterSalt, strlen(iniMasterSalt)+1, KDFcontext, kdfSize, 112, srtpSaltI);\n\n    // Responder key and salt\n    KDF(s0, hashLength, (unsigned char*)respMasterKey, strlen(respMasterKey)+1, KDFcontext, kdfSize, keyLen, srtpKeyR);\n    KDF(s0, hashLength, (unsigned char*)respMasterSalt, strlen(respMasterSalt)+1, KDFcontext, kdfSize, 112, srtpSaltR);\n\n    // The HMAC keys for GoClear\n    KDF(s0, hashLength, (unsigned char*)iniHmacKey, strlen(iniHmacKey)+1, KDFcontext, kdfSize, hashLength*8, hmacKeyI);\n    KDF(s0, hashLength, (unsigned char*)respHmacKey, strlen(respHmacKey)+1, KDFcontext, kdfSize, hashLength*8, hmacKeyR);\n\n    // The keys for Confirm messages\n    KDF(s0, hashLength, (unsigned char*)iniZrtpKey, strlen(iniZrtpKey)+1, KDFcontext, kdfSize, keyLen, zrtpKeyI);\n    KDF(s0, hashLength, (unsigned char*)respZrtpKey, strlen(respZrtpKey)+1, KDFcontext, kdfSize, keyLen, zrtpKeyR);\n\n    detailInfo.pubKey = detailInfo.sasType = NULL;\n    if (!multiStream) {\n        // Compute the new Retained Secret\n        KDF(s0, hashLength, (unsigned char*)retainedSec, strlen(retainedSec)+1, KDFcontext, kdfSize, SHA256_DIGEST_LENGTH*8, newRs1);\n\n        // Compute the ZRTP Session Key\n        KDF(s0, hashLength, (unsigned char*)zrtpSessionKey, strlen(zrtpSessionKey)+1, KDFcontext, kdfSize, hashLength*8, zrtpSession);\n\n        // perform  generation according to chapter 5.5 and 8.\n        // we don't need a speciai sasValue filed. sasValue are the first\n        // (leftmost) 32 bits (4 bytes) of sasHash\n        uint8_t sasBytes[4];\n        KDF(s0, hashLength, (unsigned char*)sasString, strlen(sasString)+1, KDFcontext, kdfSize, SHA256_DIGEST_LENGTH*8, sasHash);\n\n        // according to chapter 8 only the leftmost 20 bits of sasValue (aka\n        //  sasHash) are used to create the character SAS string of type SAS\n        // base 32 (5 bits per character)\n        sasBytes[0] = sasHash[0];\n        sasBytes[1] = sasHash[1];\n        sasBytes[2] = sasHash[2] & 0xf0;\n        sasBytes[3] = 0;\n        if (*(int32_t*)b32 == *(int32_t*)(sasType->getName())) {\n            SAS = Base32(sasBytes, 20).getEncoded();\n        }\n        else {\n            SAS.assign(sas256WordsEven[sasBytes[0]]).append(\":\").append(sas256WordsOdd[sasBytes[1]]);\n        }\n\n        if (signSasSeen)\n            callback->signSAS(sasHash);\n\n        detailInfo.pubKey = pubKey->getReadable();\n        detailInfo.sasType = sasType->getReadable();\n    }\n    // set algorithm names into detailInfo structure\n    detailInfo.authLength = authLength->getReadable();\n    detailInfo.cipher = cipher->getReadable();\n    detailInfo.hash = hash->getReadable();\n\n    memset(KDFcontext, 0, sizeof(KDFcontext));\n}\n\nbool ZRtp::srtpSecretsReady(EnableSecurity part) {\n\n    SrtpSecret_t sec;\n\n    sec.symEncAlgorithm = cipher->getAlgoId();\n\n    sec.keyInitiator = srtpKeyI;\n    sec.initKeyLen = cipher->getKeylen() * 8;\n    sec.saltInitiator = srtpSaltI;\n    sec.initSaltLen = 112;\n\n    sec.keyResponder = srtpKeyR;\n    sec.respKeyLen = cipher->getKeylen() * 8;\n    sec.saltResponder = srtpSaltR;\n    sec.respSaltLen = 112;\n\n    sec.authAlgorithm = authLength->getAlgoId();\n    sec.srtpAuthTagLen = authLength->getKeylen();\n\n    sec.sas = SAS;\n    sec.role = myRole;\n\n    bool rc = callback->srtpSecretsReady(&sec, part);\n\n    // The call state engine calls ForSender always after ForReceiver.\n    if (part == ForSender) {\n        std::string cs(cipher->getReadable());\n        if (!multiStream) {\n            cs.append(\"/\").append(pubKey->getName());\n            if (mitmSeen)\n                cs.append(\"/EndAtMitM\");\n            callback->srtpSecretsOn(cs, SAS, zidRec->isSasVerified());\n        }\n        else {\n            std::string cs1(\"\");\n            if (mitmSeen)\n                cs.append(\"/EndAtMitM\");\n            callback->srtpSecretsOn(cs, cs1, true);\n        }\n    }\n    return rc;\n}\n\n\nvoid ZRtp::setNegotiatedHash(AlgorithmEnum* hash) {\n    switch (zrtpHashes.getOrdinal(*hash)) {\n    case 0:\n        hashLength = SHA256_DIGEST_LENGTH;\n        hashFunction = sha256;\n        hashListFunction = sha256;\n\n        hmacFunction = hmac_sha256;\n        hmacListFunction = hmac_sha256;\n\n        createHashCtx = initializeSha256Context;\n        msgShaContext = &hashCtx.sha256Ctx;\n        closeHashCtx = finalizeSha256Context;\n        hashCtxFunction = sha256Ctx;\n        hashCtxListFunction = sha256Ctx;\n        break;\n\n    case 1:\n        hashLength = SHA384_DIGEST_LENGTH;\n        hashFunction = sha384;\n        hashListFunction = sha384;\n\n        hmacFunction = hmac_sha384;\n        hmacListFunction = hmac_sha384;\n\n        createHashCtx = initializeSha384Context;\n        msgShaContext = &hashCtx.sha384Ctx;\n        closeHashCtx = finalizeSha384Context;\n        hashCtxFunction = sha384Ctx;\n        hashCtxListFunction = sha384Ctx;\n        break;\n\n    case 2:\n        hashLength = SKEIN256_DIGEST_LENGTH;\n        hashFunction = skein256;\n        hashListFunction = skein256;\n\n        hmacFunction = macSkein256;\n        hmacListFunction = macSkein256;\n\n        createHashCtx = initializeSkein256Context;\n        msgShaContext = &hashCtx.skeinCtx;\n        closeHashCtx = finalizeSkein256Context;\n        hashCtxFunction = skein256Ctx;\n        hashCtxListFunction = skein256Ctx;\n        break;\n\n    case 3:\n        hashLength = SKEIN384_DIGEST_LENGTH;\n        hashFunction = skein384;\n        hashListFunction = skein384;\n\n        hmacFunction = macSkein384;\n        hmacListFunction = macSkein384;\n\n        createHashCtx = initializeSkein384Context;\n        msgShaContext = &hashCtx.skeinCtx;\n        closeHashCtx = finalizeSkein384Context;\n        hashCtxFunction = skein384Ctx;\n        hashCtxListFunction = skein384Ctx;\n        break;\n    }\n}\n\n\nvoid ZRtp::srtpSecretsOff(EnableSecurity part) {\n    callback->srtpSecretsOff(part);\n}\n\nvoid ZRtp::SASVerified() {\n    if (paranoidMode)\n        return;\n\n    zidRec->setSasVerified();\n    saveZidRecord = true;\n    getZidCacheInstance()->saveRecord(zidRec);\n}\n\nvoid ZRtp::resetSASVerified() {\n\n    zidRec->resetSasVerified();\n    getZidCacheInstance()->saveRecord(zidRec);\n}\n\nvoid ZRtp::setRs2Valid() {\n\n    if (zidRec != NULL) {\n        zidRec->setRs2Valid();\n        if (saveZidRecord)\n            getZidCacheInstance()->saveRecord(zidRec);\n    }\n}\n\nint64_t ZRtp::getSecureSince() {\n    if (zidRec != NULL)\n        return zidRec->getSecureSince();\n    return 0;\n}\n\n\nvoid ZRtp::sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode) {\n\n    // We've reached secure state: overwrite the SRTP master key and master salt.\n    if (severity == Info && subCode == InfoSecureStateOn) {\n        memset(srtpKeyI, 0, cipher->getKeylen());\n        memset(srtpSaltI, 0, 112/8);\n        memset(srtpKeyR, 0, cipher->getKeylen());\n        memset(srtpSaltR, 0, 112/8);\n    }\n    callback->sendInfo(severity, subCode);\n}\n\n\nvoid ZRtp::zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity, int32_t subCode) {\n    callback->zrtpNegotiationFailed(severity, subCode);\n}\n\nvoid ZRtp::zrtpNotSuppOther() {\n    callback->zrtpNotSuppOther();\n}\n\nvoid ZRtp::synchEnter() {\n    callback->synchEnter();\n}\n\nvoid ZRtp::synchLeave() {\n    callback->synchLeave();\n}\n\nint32_t ZRtp::sendPacketZRTP(ZrtpPacketBase *packet) {\n    return ((packet == NULL) ? 0 :\n            callback->sendDataZRTP(packet->getHeaderBase(), (packet->getLength() * 4) + 4));\n}\n\nint32_t ZRtp::activateTimer(int32_t tm) {\n    return (callback->activateTimer(tm));\n}\n\nint32_t ZRtp::cancelTimer() {\n    return (callback->cancelTimer());\n}\n\nvoid ZRtp::setAuxSecret(uint8_t* data, int32_t length) {\n    if (length > 0) {\n        auxSecret = new uint8_t[length];\n        auxSecretLength = length;\n        memcpy(auxSecret, data, length);\n    }\n}\n\nvoid ZRtp::setClientId(std::string id, HelloPacketVersion* hpv) {\n\n    unsigned char tmp[CLIENT_ID_SIZE +1] = {' '};\n    memcpy(tmp, id.c_str(), id.size() > CLIENT_ID_SIZE ? CLIENT_ID_SIZE : id.size());\n    tmp[CLIENT_ID_SIZE] = 0;\n\n    hpv->packet->setClientId(tmp);\n\n    int32_t len = hpv->packet->getLength() * ZRTP_WORD_SIZE;\n\n    // Hello packets are ready now, compute its HMAC\n    // (excluding the HMAC field (2*ZTP_WORD_SIZE)) and store in Hello\n    // use the implicit hash function\n    uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];\n    uint32_t macLen;\n    hmacFunctionImpl(H2, HASH_IMAGE_SIZE, (uint8_t*)hpv->packet->getHeaderBase(), len-(2*ZRTP_WORD_SIZE), hmac, &macLen);\n    hpv->packet->setHMAC(hmac);\n\n    // calculate hash over the final Hello packet, refer to chap 9.1 how to\n    // use this hash in SIP/SDP.\n    hashFunctionImpl((uint8_t*)hpv->packet->getHeaderBase(), len, hpv->helloHash);\n}\n\nvoid ZRtp::storeMsgTemp(ZrtpPacketBase* pkt) {\n    uint32_t length = pkt->getLength() * ZRTP_WORD_SIZE;\n    length = (length > sizeof(tempMsgBuffer)) ? sizeof(tempMsgBuffer) : length;\n    memset(tempMsgBuffer, 0, sizeof(tempMsgBuffer));\n    memcpy(tempMsgBuffer, (uint8_t*)pkt->getHeaderBase(), length);\n    lengthOfMsgData = length;\n}\n\nbool ZRtp::checkMsgHmac(uint8_t* key) {\n    uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];\n    uint32_t macLen;\n    int32_t len = lengthOfMsgData-(HMAC_SIZE);  // compute HMAC, but exlude the stored HMAC :-)\n\n    // Use the implicit hash function\n    hmacFunctionImpl(key, HASH_IMAGE_SIZE, tempMsgBuffer, len, hmac, &macLen);\n    return (memcmp(hmac, tempMsgBuffer+len, (HMAC_SIZE)) == 0 ? true : false);\n}\n\nstd::string ZRtp::getHelloHash(int32_t index) {\n    std::ostringstream stm;\n\n    if (index < 0 || index >= MAX_ZRTP_VERSIONS)\n        return std::string();\n\n    uint8_t* hp = helloPackets[index].helloHash;\n\n    char version[5] = {'\\0'};\n    strncpy(version, (const char*)helloPackets[index].packet->getVersion(), ZRTP_WORD_SIZE);\n\n    stm << version;\n    stm << \" \";\n    stm.fill('0');\n    stm << hex;\n    for (int i = 0; i < hashLengthImpl; i++) {\n        stm.width(2);\n        stm << static_cast<uint32_t>(*hp++);\n    }\n    return stm.str();\n}\n\nstd::string ZRtp::getPeerHelloHash() {\n    std::ostringstream stm;\n\n    if (peerHelloVersion[0] == 0)\n        return std::string();\n\n    uint8_t* hp = peerHelloHash;\n\n    stm << peerHelloVersion;\n    stm << \" \";\n    stm.fill('0');\n    stm << hex;\n    for (int i = 0; i < hashLengthImpl; i++) {\n        stm.width(2);\n        stm << static_cast<uint32_t>(*hp++);\n    }\n    return stm.str();\n}\n\nstd::string ZRtp::getMultiStrParams(ZRtp **zrtpMaster) {\n\n    // the string will hold binary data - it's opaque to the application\n    std::string str(\"\");\n    char tmp[MAX_DIGEST_LENGTH + 1 + 1 + 1]; // hash length + cipher + authLength + hash\n\n    if (inState(SecureState) && !multiStream) {\n        // construct array that holds zrtpSession, cipher type, auth-length, and hash type\n        tmp[0] = zrtpHashes.getOrdinal(*hash);\n        tmp[1] = zrtpAuthLengths.getOrdinal(*authLength);\n        tmp[2] = zrtpSymCiphers.getOrdinal(*cipher);\n        memcpy(tmp+3, zrtpSession, hashLength);\n        str.assign(tmp, hashLength + 1 + 1 + 1); // set chars (bytes) to the string\n        if (zrtpMaster != NULL)\n            *zrtpMaster = this;\n    }\n    return str;\n}\n\nvoid ZRtp::setMultiStrParams(std::string parameters, ZRtp *zrtpMaster) {\n\n    char tmp[MAX_DIGEST_LENGTH + 1 + 1 + 1]; // max. hash length + cipher + authLength + hash\n\n    // First get negotiated hash from parameters, set algorithms and length\n    int i = parameters.at(0) & 0xff;\n    hash = &zrtpHashes.getByOrdinal(i);\n    setNegotiatedHash(hash);           // sets hashlength\n\n    // use string.copy(buffer, num, start=0) to retrieve chars (bytes) from the string\n    parameters.copy(tmp, hashLength + 1 + 1 + 1, 0);\n\n    i = tmp[1] & 0xff;\n    authLength = &zrtpAuthLengths.getByOrdinal(i);\n    i = tmp[2] & 0xff;\n    cipher = &zrtpSymCiphers.getByOrdinal(i);\n    memcpy(zrtpSession, tmp+3, hashLength);\n\n    // after setting zrtpSession, cipher, and auth-length set multi-stream to true\n    multiStream = true;\n    stateEngine->setMultiStream(true);\n    if (zrtpMaster != NULL)\n        masterStream = zrtpMaster;\n}\n\nbool ZRtp::isMultiStream() {\n    return multiStream;\n}\n\nbool ZRtp::isMultiStreamAvailable() {\n    return multiStreamAvailable;\n}\n\nvoid ZRtp::acceptEnrollment(bool accepted) {\n#ifdef ZRTP_SAS_RELAY_SUPPORT\n    if (!accepted) {\n        zidRec->resetMITMKeyAvailable();\n        callback->zrtpInformEnrollment(EnrollmentCanceled);\n        getZidCacheInstance()->saveRecord(zidRec);\n        return;\n    }\n    if (pbxSecretTmp != NULL) {\n        zidRec->setMiTMData(pbxSecretTmp);\n        getZidCacheInstance()->saveRecord(zidRec);\n        callback->zrtpInformEnrollment(EnrollmentOk);\n    }\n    else {\n        callback->zrtpInformEnrollment(EnrollmentFailed);\n    }\n#endif\n}\n\nbool ZRtp::setSignatureData(uint8_t* data, int32_t length) {\n    if ((length % 4) != 0)\n        return false;\n\n    ZrtpPacketConfirm* cfrm = (myRole == Responder) ? &zrtpConfirm1 : &zrtpConfirm2;\n    cfrm->setSignatureLength(length / 4);\n    return cfrm->setSignatureData(data, length);\n}\n\nconst uint8_t* ZRtp::getSignatureData() {\n    return signatureData;\n}\n\nint32_t ZRtp::getSignatureLength() {\n    return signatureLength * ZRTP_WORD_SIZE;\n}\n\nvoid ZRtp::conf2AckSecure() {\n    Event_t ev;\n\n    ev.type = ZrtpPacket;\n    ev.packet = (uint8_t*)zrtpConf2Ack.getHeaderBase();\n    ev.length = sizeof (Conf2AckPacket_t) + 12;  // 12 is fixed ZRTP (RTP) header size\n\n    if (stateEngine != NULL) {\n        stateEngine->processEvent(&ev);\n    }\n}\n\nint32_t ZRtp::compareCommit(ZrtpPacketCommit *commit) {\n    // TODO: enhance to compare according to rules defined in chapter 4.2,\n    // but we don't support Preshared.\n    int32_t len = 0;\n    len = !multiStream ? HVI_SIZE : (4 * ZRTP_WORD_SIZE);\n    return (memcmp(hvi, commit->getHvi(), len));\n}\n\nbool ZRtp::isEnrollmentMode() {\n    return enrollmentMode;\n}\n\nvoid ZRtp::setEnrollmentMode(bool enrollmentMode) {\n#ifdef ZRTP_SAS_RELAY_SUPPORT\n    this->enrollmentMode = enrollmentMode;\n#else\n    this->enrollmentMode = false;\n#endif\n}\n\nbool ZRtp::isPeerEnrolled() {\n    return peerIsEnrolled;\n}\n\nbool ZRtp::sendSASRelayPacket(uint8_t* sh, std::string render) {\n\n    uint8_t confMac[MAX_DIGEST_LENGTH];\n    uint32_t macLen;\n    uint8_t* hkey, *ekey;\n\n    // If we are responder then the PBX used it's Initiator keys\n    if (myRole == Responder) {\n        hkey = hmacKeyR;\n        ekey = zrtpKeyR;\n        // TODO: check signature length in zrtpConfirm1 and if not zero copy Signature data\n    }\n    else {\n        hkey = hmacKeyI;\n        ekey = zrtpKeyI;\n        // TODO: check signature length in zrtpConfirm2 and if not zero copy Signature data\n    }\n    // Prepare IV data that we will use during confirm packet encryption.\n    randomZRTP(randomIV, sizeof(randomIV));\n    zrtpSasRelay.setIv(randomIV);\n    zrtpSasRelay.setTrustedSas(sh);\n    zrtpSasRelay.setSasAlgo((uint8_t*)render.c_str());\n\n    int16_t hmlen = (zrtpSasRelay.getLength() - 9) * ZRTP_WORD_SIZE;\n    cipher->getEncrypt()(ekey, cipher->getKeylen(), randomIV, (uint8_t*)zrtpSasRelay.getFiller(), hmlen);\n\n    // Use negotiated HMAC (hash)\n    hmacFunction(hkey, hashLength, (unsigned char*)zrtpSasRelay.getFiller(), hmlen, confMac, &macLen);\n\n    zrtpSasRelay.setHmac(confMac);\n\n    stateEngine->sendSASRelay(&zrtpSasRelay);\n    return true;\n}\n\nstd::string ZRtp::getSasType() {\n    std::string sasT(sasType->getName());\n    return sasT;\n}\n\nuint8_t* ZRtp::getSasHash() {\n    return sasHash;\n}\n\nint32_t ZRtp::getPeerZid(uint8_t* data) {\n    memcpy(data, peerZid, IDENTIFIER_LEN);\n    return IDENTIFIER_LEN;\n}\n\nconst ZRtp::zrtpInfo* ZRtp::getDetailInfo() {\n    return &detailInfo;\n}\n\nstd::string ZRtp::getPeerClientId() {\n    if (peerClientId.empty())\n        return std::string();\n    return peerClientId;\n}\n\nstd::string ZRtp::getPeerProtcolVersion() {\n    if (peerHelloVersion[0] == 0)\n        return std::string();\n    return std::string((char*)peerHelloVersion);\n}\n\nvoid ZRtp::setT1Resend(int32_t counter) {\n    if (counter < 0 || counter > 10)\n        stateEngine->setT1Resend(counter);\n}\n\nvoid ZRtp::setT1ResendExtend(int32_t counter) {\n    stateEngine->setT1ResendExtend(counter);\n}\n\nvoid ZRtp::setT1Capping(int32_t capping) {\n    if (capping >= 50)\n        stateEngine->setT1Capping(capping);\n}\n\nvoid ZRtp::setT2Resend(int32_t counter) {\n    if (counter < 0 || counter > 10)\n        stateEngine->setT2Resend(counter);\n}\n\nvoid ZRtp::setT2Capping(int32_t capping) {\n    if (capping >= 150)\n        stateEngine->setT2Capping(capping);\n}\n\nint ZRtp::getNumberOfCountersZrtp() {\n    // If we add some other counters add them here before returning\n    return stateEngine->getNumberOfRetryCounters();\n}\n\nint ZRtp::getCountersZrtp(int32_t* counters) {\n    return stateEngine->getRetryCounters(counters);\n}\n\nbool ZRtp::checkAndSetNonce(uint8_t* nonce) {\n    // This is for backward compatibility if an applications uses the old\n    // get- and setMultiStrParams functions\n    if (masterStream == NULL)\n        return true;\n\n    for (std::vector<std::string>::iterator it = masterStream->peerNonces.begin() ; it != masterStream->peerNonces.end(); ++it) {\n        if (memcmp((*it).data(), nonce, ZRTP_WORD_SIZE * 4) == 0) {\n            return false;\n        }\n    }\n    // the string holds the binary nonce\n    std::string str(\"\");\n    str.assign((char *)nonce, ZRTP_WORD_SIZE * 4);\n    masterStream->peerNonces.push_back(str);\n    return true;\n}\n\n/** EMACS **\n * Local variables:\n * mode: c++\n * c-default-style: ellemtel\n * c-basic-offset: 4\n * End:\n */\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpCWrapper.cpp",
    "content": "/*\n    This class maps the ZRTP C calls to ZRTP C++ methods.\n    Copyright (C) 2010-2013  Werner Dittmann\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU Lesser General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n*/\n\n#include <libzrtpcpp/ZrtpCallback.h>\n#include <libzrtpcpp/ZrtpConfigure.h>\n#include <libzrtpcpp/ZIDCache.h>\n#include <libzrtpcpp/ZRtp.h>\n#include <libzrtpcpp/ZrtpCallbackWrapper.h>\n#include <libzrtpcpp/ZrtpCWrapper.h>\n#include <libzrtpcpp/ZrtpCrc32.h>\n\nstatic int32_t zrtp_initZidFile(const char* zidFilename);\n\nZrtpContext* zrtp_CreateWrapper() \n{\n    ZrtpContext* zc = new ZrtpContext;\n    zc->configure = 0;\n    zc->zrtpEngine = 0;\n    zc->zrtpCallback = 0;\n\n    return zc;\n}\n\nvoid zrtp_initializeZrtpEngine(ZrtpContext* zrtpContext, \n                               zrtp_Callbacks *cb, const char* id,\n                               const char* zidFilename,\n                               void* userData,\n                               int32_t mitmMode)\n{\n    std::string clientIdString(id);\n\n    zrtpContext->zrtpCallback = new ZrtpCallbackWrapper(cb, zrtpContext);\n    zrtpContext->userData = userData;\n\n    if (zrtpContext->configure == 0) {\n        zrtpContext->configure = new ZrtpConfigure();\n        zrtpContext->configure->setStandardConfig();\n    }\n\n    // Initialize ZID file (cache) and get my own ZID\n    zrtp_initZidFile(zidFilename);\n    const unsigned char* myZid = getZidCacheInstance()->getZid();\n\n    zrtpContext->zrtpEngine = new ZRtp((uint8_t*)myZid, zrtpContext->zrtpCallback,\n                              clientIdString, zrtpContext->configure, mitmMode == 0 ? false : true);\n}\n\nvoid zrtp_DestroyWrapper(ZrtpContext* zrtpContext) {\n\n    if (zrtpContext == NULL)\n        return;\n\n    delete zrtpContext->zrtpEngine;\n    zrtpContext->zrtpEngine = NULL;\n\n    delete zrtpContext->zrtpCallback;\n    zrtpContext->zrtpCallback = NULL;\n\n    delete zrtpContext->configure;\n    zrtpContext->configure = NULL;\n\n    delete zrtpContext;\n}\n\nstatic int32_t zrtp_initZidFile(const char* zidFilename) {\n    ZIDCache* zf = getZidCacheInstance();\n\n    if (!zf->isOpen()) {\n        std::string fname;\n        if (zidFilename == NULL) {\n            char *home = getenv(\"HOME\");\n            std::string baseDir = (home != NULL) ? (std::string(home) + std::string(\"/.\"))\n                                  : std::string(\".\");\n            fname = baseDir + std::string(\"GNUccRTP.zid\");\n            zidFilename = fname.c_str();\n        }\n        return zf->open((char *)zidFilename);\n    }\n    return 0;\n}\n\nint32_t zrtp_CheckCksum(uint8_t* buffer, uint16_t temp, uint32_t crc) \n{\n    return zrtpCheckCksum(buffer, temp, crc);\n}\n\nuint32_t zrtp_GenerateCksum(uint8_t* buffer, uint16_t temp)\n{\n    return zrtpGenerateCksum(buffer, temp);\n}\n\nuint32_t zrtp_EndCksum(uint32_t crc)\n{\n    return zrtpEndCksum(crc);\n}\n\n/*\n * Applications use the following methods to control ZRTP, for example\n * to enable ZRTP, set flags etc.\n */\nvoid zrtp_startZrtpEngine(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        zrtpContext->zrtpEngine->startZrtpEngine();\n}\n\nvoid zrtp_stopZrtpEngine(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        zrtpContext->zrtpEngine->stopZrtp();\n}\n\nvoid zrtp_processZrtpMessage(ZrtpContext* zrtpContext, uint8_t *extHeader, uint32_t peerSSRC, size_t length) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        zrtpContext->zrtpEngine->processZrtpMessage(extHeader, peerSSRC, length);\n}\n\nvoid zrtp_processTimeout(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        zrtpContext->zrtpEngine->processTimeout();\n}\n\n//int32_t zrtp_handleGoClear(ZrtpContext* zrtpContext, uint8_t *extHeader)\n//{\n//    if (zrtpContext && zrtpContext->zrtpEngine)\n//        return zrtpContext->zrtpEngine->handleGoClear(extHeader) ? 1 : 0;\n//\n//    return 0;\n//}\n\nvoid zrtp_setAuxSecret(ZrtpContext* zrtpContext, uint8_t* data, int32_t length) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        zrtpContext->zrtpEngine->setAuxSecret(data, length);\n}\n\nint32_t zrtp_inState(ZrtpContext* zrtpContext, int32_t state) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->inState(state) ? 1 : 0;\n\n    return 0;\n}\n\nvoid zrtp_SASVerified(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        zrtpContext->zrtpEngine->SASVerified();\n}\n\nvoid zrtp_resetSASVerified(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        zrtpContext->zrtpEngine->resetSASVerified();\n}\n\nchar* zrtp_getHelloHash(ZrtpContext* zrtpContext, int32_t index) {\n    std::string ret;\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        ret = zrtpContext->zrtpEngine->getHelloHash(index);\n    else\n        return NULL;\n\n    if (ret.size() == 0)\n        return NULL;\n\n    char* retval = (char*)malloc(ret.size()+1);\n    strcpy(retval, ret.c_str());\n    return retval;\n}\n\nchar* zrtp_getPeerHelloHash(ZrtpContext* zrtpContext) {\n    std::string ret;\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        ret = zrtpContext->zrtpEngine->getPeerHelloHash();\n    else\n        return NULL;\n\n    if (ret.size() == 0)\n        return NULL;\n\n    char* retval = (char*)malloc(ret.size()+1);\n    strcpy(retval, ret.c_str());\n    return retval;\n}\n\nchar* zrtp_getPeerName(ZrtpContext* zrtpContext) {\n    uint8_t peerZid[IDENTIFIER_LEN];\n    std::string ret;\n\n    if (zrtpContext && zrtpContext->zrtpEngine) {\n        if (!zrtpContext->zrtpEngine->getPeerZid(peerZid))\n            return NULL;\n        if (!getZidCacheInstance()->getPeerName(peerZid, &ret))\n            return NULL;\n    } else {\n        return NULL;\n    }\n\n    if (ret.size() == 0)\n        return NULL;\n\n    char* retval = (char*)malloc(ret.size()+1);\n    strcpy(retval, ret.c_str());\n    return retval;\n}\n\nvoid zrtp_putPeerName(ZrtpContext* zrtpContext, const char* name) {\n    uint8_t peerZid[IDENTIFIER_LEN];\n    std::string ret;\n\n    if (!name)\n        return;\n\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        if (!zrtpContext->zrtpEngine->getPeerZid(peerZid))\n            return;\n\n        std::string str(name);\n        getZidCacheInstance()->putPeerName(peerZid, str);\n}\n\nchar* zrtp_getMultiStrParams(ZrtpContext* zrtpContext, int32_t *length) {\n    std::string ret;\n\n    *length = 0;\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        ret = zrtpContext->zrtpEngine->getMultiStrParams(&zrtpContext->zrtpMaster);\n    else\n        return NULL;\n\n    if (ret.size() == 0)\n        return NULL;\n\n    *length = ret.size();\n    char* retval = (char*) malloc(ret.size());\n    ret.copy(retval, ret.size(), 0);\n    return retval;\n}\n\nvoid zrtp_setMultiStrParams(ZrtpContext* zrtpContext, char* parameters, int32_t length, ZrtpContext* master) {\n    if (!zrtpContext || !zrtpContext->zrtpEngine)\n        return;\n\n    if (parameters == NULL)\n        return;\n\n    std::string str(\"\");\n    str.assign(parameters, length); // set chars (bytes) to the string\n\n    zrtpContext->zrtpEngine->setMultiStrParams(str, master->zrtpMaster);\n}\n\nint32_t zrtp_isMultiStream(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->isMultiStream() ? 1 : 0;\n\n    return 0;\n}\n\nint32_t zrtp_isMultiStreamAvailable(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->isMultiStreamAvailable() ? 1 : 0;\n\n    return 0;\n}\n\nvoid zrtp_acceptEnrollment(ZrtpContext* zrtpContext, int32_t accepted) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->acceptEnrollment(accepted == 0 ? false : true);\n}\n\nint32_t zrtp_isEnrollmentMode(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->isEnrollmentMode() ? 1 : 0;\n\n    return 0;\n}\n\nvoid zrtp_setEnrollmentMode(ZrtpContext* zrtpContext, int32_t enrollmentMode) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->setEnrollmentMode(enrollmentMode == 0 ? false : true);\n}\n\nint32_t isPeerEnrolled(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->isPeerEnrolled() ? 1 : 0;\n\n    return 0;\n}\n\nint32_t zrtp_sendSASRelayPacket(ZrtpContext* zrtpContext, uint8_t* sh, char* render) {\n    if (zrtpContext && zrtpContext->zrtpEngine) {\n        std::string rn(render);\n        return zrtpContext->zrtpEngine->sendSASRelayPacket(sh, rn) ? 1 : 0;\n    }\n    return 0;\n}\n\n\nconst char* zrtp_getSasType(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine) {\n        std::string rn = zrtpContext->zrtpEngine->getSasType();\n        if (rn.size() == 0)\n            return NULL;\n\n        char* retval = (char*)malloc(rn.size()+1);\n        strcpy(retval, rn.c_str());\n        return retval;\n    }\n    return NULL;\n}\n\n\nuint8_t* zrtp_getSasHash(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->getSasHash();\n\n    return NULL;\n}\n\nint32_t zrtp_setSignatureData(ZrtpContext* zrtpContext, uint8_t* data, int32_t length) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->setSignatureData(data, length) ? 1 : 0;\n\n    return 0;\n}\n\nconst uint8_t* zrtp_getSignatureData(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->getSignatureData();\n\n    return 0;\n}\n\nint32_t zrtp_getSignatureLength(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->getSignatureLength();\n\n    return 0;\n}\n\nvoid zrtp_conf2AckSecure(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        zrtpContext->zrtpEngine->conf2AckSecure();\n}\n\nint32_t zrtp_getPeerZid(ZrtpContext* zrtpContext, uint8_t* data) {\n    if (data == NULL)\n        return 0;\n\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->getPeerZid(data);\n\n    return 0;\n}\n\nint32_t zrtp_getNumberSupportedVersions(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->getNumberSupportedVersions();\n    return -1;\n}\n\nint32_t zrtp_getCurrentProtocolVersion(ZrtpContext* zrtpContext) {\n    if (zrtpContext && zrtpContext->zrtpEngine)\n        return zrtpContext->zrtpEngine->getCurrentProtocolVersion();\n    return -1;\n}\n/*\n * The following methods wrap the ZRTP Configure functions\n */\nint32_t zrtp_InitializeConfig (ZrtpContext* zrtpContext)\n{\n    zrtpContext->configure = new ZrtpConfigure();\n    return 1;\n}\n\nstatic EnumBase* getEnumBase(zrtp_AlgoTypes type)\n{\n        switch(type) {\n        case zrtp_HashAlgorithm:\n            return &zrtpHashes;\n            break;\n\n        case zrtp_CipherAlgorithm:\n            return &zrtpSymCiphers;\n            break;\n\n        case zrtp_PubKeyAlgorithm:\n            return &zrtpPubKeys;\n            break;\n\n        case zrtp_SasType:\n            return &zrtpSasTypes;\n            break;\n\n        case zrtp_AuthLength:\n            return &zrtpAuthLengths;\n            break;\n\n        default:\n            return NULL;\n    }\n}\n\nchar** zrtp_getAlgorithmNames(ZrtpContext* zrtpContext, Zrtp_AlgoTypes type) \n{\n    std::list<std::string>* names = NULL;\n    EnumBase* base = getEnumBase(type);\n\n    if (!base)\n        return NULL;\n\n    names = base->getAllNames();\n    int size = base->getSize();\n    char** cNames = new char* [size+1];\n    cNames[size] = NULL;\n\n    std::list<std::string >::iterator b = names->begin();\n    std::list<std::string >::iterator e = names->end();\n\n    for (int i = 0; b != e; b++, i++) {\n        cNames[i] = new char [(*b).size()+1];\n        strcpy(cNames[i], (*b).c_str());\n    }\n    return cNames;\n}\n\nvoid zrtp_freeAlgorithmNames(char** names)\n{\n    if (!names)\n        return;\n    \n    for (char** cp = names; *cp; cp++)\n        delete *cp;\n    \n    delete names;\n}\n\nvoid zrtp_setStandardConfig(ZrtpContext* zrtpContext)\n{\n    if (zrtpContext && zrtpContext->configure)\n        zrtpContext->configure->setStandardConfig();\n}\n\nvoid zrtp_setMandatoryOnly(ZrtpContext* zrtpContext)\n{\n    if (zrtpContext && zrtpContext->configure)\n        zrtpContext->configure->setMandatoryOnly();\n}\n\nint32_t zrtp_addAlgo(ZrtpContext* zrtpContext, zrtp_AlgoTypes algoType, const char* algo)\n{\n    EnumBase* base = getEnumBase(algoType);\n    if (base) {\n        AlgorithmEnum& a = base->getByName(algo);\n        if (zrtpContext && zrtpContext->configure)\n            return zrtpContext->configure->addAlgo((AlgoTypes)algoType, a);\n    }\n    return -1;\n}\n\nint32_t zrtp_addAlgoAt(ZrtpContext* zrtpContext, zrtp_AlgoTypes algoType, const char* algo, int32_t index)\n{\n    EnumBase* base = getEnumBase(algoType);\n    if (base) {\n        AlgorithmEnum& a = base->getByName(algo);\n        if (zrtpContext && zrtpContext->configure)\n            return zrtpContext->configure->addAlgoAt((AlgoTypes)algoType, a, index);\n    }\n    return -1;\n}\n\nint32_t zrtp_removeAlgo(ZrtpContext* zrtpContext, zrtp_AlgoTypes algoType, const char* algo)\n{\n    EnumBase* base = getEnumBase(algoType);\n    if (base) {\n        AlgorithmEnum& a = base->getByName(algo);\n        if (zrtpContext && zrtpContext->configure)\n            return zrtpContext->configure->removeAlgo((AlgoTypes)algoType, a);\n    }\n    return -1;\n}\n\nint32_t zrtp_getNumConfiguredAlgos(ZrtpContext* zrtpContext, zrtp_AlgoTypes algoType)\n{\n    if (zrtpContext && zrtpContext->configure)\n        return zrtpContext->configure->getNumConfiguredAlgos((AlgoTypes)algoType);\n    return -1;\n}\n\nconst char* zrtp_getAlgoAt(ZrtpContext* zrtpContext, Zrtp_AlgoTypes algoType, int32_t index)\n{\n    if (zrtpContext && zrtpContext->configure) {\n       AlgorithmEnum& a = zrtpContext->configure->getAlgoAt((AlgoTypes)algoType, index);\n       return a.getName();\n    }\n    return NULL;\n}\n\nint32_t zrtp_containsAlgo(ZrtpContext* zrtpContext, Zrtp_AlgoTypes algoType, const char*  algo)\n{\n    EnumBase* base = getEnumBase(algoType);\n    if (base) {\n        AlgorithmEnum& a = base->getByName(algo);\n        if (zrtpContext && zrtpContext->configure)\n            return zrtpContext->configure->containsAlgo((AlgoTypes)algoType, a) ? 1 : 0;\n    }\n    return 0;\n}\n\nvoid zrtp_setTrustedMitM(ZrtpContext* zrtpContext, int32_t yesNo)\n{\n    if (zrtpContext && zrtpContext->configure)\n        zrtpContext->configure->setTrustedMitM(yesNo ? true : false);\n}\n\nint32_t zrtp_isTrustedMitM(ZrtpContext* zrtpContext)\n{\n    if (zrtpContext && zrtpContext->configure)\n        return zrtpContext->configure->isTrustedMitM() ? 1 : 0;\n    return 0;        /* standard setting: trustedMitM is false, thus if zrtp not initialized it's always false */\n}\n\nvoid zrtp_setSasSignature(ZrtpContext* zrtpContext, int32_t yesNo)\n{\n    if (zrtpContext && zrtpContext->configure)\n        zrtpContext->configure->setSasSignature(yesNo ? true : false);\n}\n\nint32_t zrtp_isSasSignature(ZrtpContext* zrtpContext)\n{\n    if (zrtpContext && zrtpContext->configure)\n        return zrtpContext->configure->isSasSignature() ? 1 : 0;\n    return 0;       /* standard setting: sasSignature is false, thus if zrtp not initialized it's always false */\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpCallbackWrapper.cpp",
    "content": "/*\n    This class maps the ZRTP C++ callback methods to C callback methods.\n    Copyright (C) 2010-2013  Werner Dittmann\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU Lesser General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n*/\n\n#include <libzrtpcpp/ZrtpCallbackWrapper.h>\n\nZrtpCallbackWrapper::ZrtpCallbackWrapper(zrtp_Callbacks* cb, ZrtpContext* ctx) :\n        c_callbacks(cb), zrtpCtx(ctx)\n{\n    init();\n}\n\nvoid ZrtpCallbackWrapper::init()\n{\n}\n/*\n* The following methods implement the GNU ZRTP callback interface.\n* For detailed documentation refer to file ZrtpCallback.h\n*/\nint32_t ZrtpCallbackWrapper::sendDataZRTP(const unsigned char* data, int32_t length)\n{\n    return c_callbacks->zrtp_sendDataZRTP(zrtpCtx, data, length);\n}\n\nint32_t ZrtpCallbackWrapper::activateTimer (int32_t time)\n{\n    c_callbacks->zrtp_activateTimer(zrtpCtx, time);\n    return 1;\n}\n\nint32_t ZrtpCallbackWrapper::cancelTimer()\n{\n    c_callbacks->zrtp_cancelTimer(zrtpCtx);\n    return 0;\n}\n\nvoid ZrtpCallbackWrapper::sendInfo (GnuZrtpCodes::MessageSeverity severity, int32_t subCode)\n{\n    c_callbacks->zrtp_sendInfo(zrtpCtx, (int32_t)severity, subCode);\n}\n\nbool ZrtpCallbackWrapper::srtpSecretsReady(SrtpSecret_t* secrets, EnableSecurity part)\n{\n    C_SrtpSecret_t* cs = new C_SrtpSecret_t;\n    cs->symEncAlgorithm = (zrtp_SrtpAlgorithms)secrets->symEncAlgorithm;\n    cs->initKeyLen = secrets->initKeyLen;\n    cs->initSaltLen = secrets->initSaltLen;\n    cs->keyInitiator = secrets->keyInitiator;\n    cs->keyResponder = secrets->keyResponder;\n    cs->respKeyLen = secrets->respKeyLen;\n    cs->respSaltLen = secrets->respSaltLen;\n    cs->role = (int32_t)secrets->role;\n    cs->saltInitiator = secrets->saltInitiator;\n    cs->saltResponder = secrets->saltResponder;\n    cs->sas = new char [secrets->sas.size()+1];\n    strcpy(cs->sas, secrets->sas.c_str());\n    cs->authAlgorithm = (zrtp_SrtpAlgorithms)secrets->authAlgorithm;\n    cs->srtpAuthTagLen = secrets->srtpAuthTagLen;\n\n    bool retval = (c_callbacks->zrtp_srtpSecretsReady(zrtpCtx, cs, (int32_t)part) == 0) ? false : true ;\n\n    delete[] cs->sas;\n    delete cs;\n\n    return retval;\n}\n\nvoid ZrtpCallbackWrapper::srtpSecretsOff (EnableSecurity part )\n{\n    c_callbacks->zrtp_srtpSecretsOff(zrtpCtx, (int32_t)part);\n}\n\nvoid ZrtpCallbackWrapper::srtpSecretsOn ( std::string c, std::string s, bool verified )\n{\n    char* cc = new char [c.size()+1];\n    char* cs = new char [s.size()+1];\n\n    strcpy(cc, c.c_str());\n    if(!s.empty()) \n        strcpy(cs, s.c_str());\n    else\n        *cs = '\\0';\n\n    c_callbacks->zrtp_rtpSecretsOn(zrtpCtx, cc, cs, verified?1:0);\n\n    delete[] cc;\n    delete[] cs;\n}\n\nvoid ZrtpCallbackWrapper::handleGoClear()\n{\n}\n\nvoid ZrtpCallbackWrapper::zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity, int32_t subCode)\n{\n    c_callbacks->zrtp_zrtpNegotiationFailed(zrtpCtx, (int32_t)severity, subCode);\n}\n\nvoid ZrtpCallbackWrapper::zrtpNotSuppOther()\n{\n    c_callbacks->zrtp_zrtpNotSuppOther(zrtpCtx);\n}\n\nvoid ZrtpCallbackWrapper::synchEnter()\n{\n    c_callbacks->zrtp_synchEnter(zrtpCtx);\n}\n\n\nvoid ZrtpCallbackWrapper::synchLeave()\n{\n    c_callbacks->zrtp_synchLeave(zrtpCtx);\n}\n\nvoid ZrtpCallbackWrapper::zrtpAskEnrollment(GnuZrtpCodes::InfoEnrollment info)\n{\n    c_callbacks->zrtp_zrtpAskEnrollment(zrtpCtx, (zrtp_InfoEnrollment)info);\n}\n\nvoid ZrtpCallbackWrapper::zrtpInformEnrollment(GnuZrtpCodes::InfoEnrollment info)\n{\n    c_callbacks->zrtp_zrtpInformEnrollment(zrtpCtx, (zrtp_InfoEnrollment)info);\n\n}\n\nvoid ZrtpCallbackWrapper::signSAS(uint8_t* sasHash)\n{\n    c_callbacks->zrtp_signSAS(zrtpCtx, sasHash);\n}\n\nbool ZrtpCallbackWrapper::checkSASSignature(uint8_t* sasHash)\n{\n    bool retval = (c_callbacks->zrtp_checkSASSignature(zrtpCtx, sasHash) == 0) ? false : true;\n\n    return retval;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpConfigure.cpp",
    "content": "/*\r\n  Copyright (C) 2006-2013 Werner Dittmann\r\n\r\n  This program is free software: you can redistribute it and/or modify\r\n  it under the terms of the GNU Lesser General Public License as published by\r\n  the Free Software Foundation, either version 3 of the License, or\r\n  (at your option) any later version.\r\n\r\n  This program is distributed in the hope that it will be useful,\r\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n  GNU General Public License for more details.\r\n\r\n  You should have received a copy of the GNU General Public License\r\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\r\n*/\r\n\r\n/*\r\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\r\n */\r\n\r\n#include <crypto/aesCFB.h>\r\n#include <crypto/twoCFB.h>\r\n#include <libzrtpcpp/ZrtpConfigure.h>\r\n#include <libzrtpcpp/ZrtpTextData.h>\r\n\r\nAlgorithmEnum::AlgorithmEnum(const AlgoTypes type, const char* name, \r\n                             int32_t klen, const char* ra, encrypt_t en, \r\n                             decrypt_t de, SrtpAlgorithms alId):\r\n    algoType(type) , algoName(name), keyLen(klen), readable(ra), encrypt(en),\r\n    decrypt(de), algoId(alId) {\r\n}\r\n\r\nAlgorithmEnum::~AlgorithmEnum()\r\n{\r\n}\r\n\r\nconst char* AlgorithmEnum::getName() {\r\n    return algoName.c_str(); \r\n}\r\n\r\nconst char* AlgorithmEnum::getReadable() {\r\n    return readable.c_str();\r\n}\r\n    \r\nint AlgorithmEnum::getKeylen() {\r\n    return keyLen;\r\n}\r\n\r\nSrtpAlgorithms AlgorithmEnum::getAlgoId() {\r\n    return algoId;\r\n}\r\n\r\nencrypt_t AlgorithmEnum::getEncrypt() {\r\n    return encrypt;\r\n}\r\n\r\ndecrypt_t AlgorithmEnum::getDecrypt() {\r\n    return decrypt;\r\n}\r\n\r\nAlgoTypes AlgorithmEnum::getAlgoType() { \r\n    return algoType; \r\n}\r\n\r\nbool AlgorithmEnum::isValid() {\r\n    return (algoType != Invalid); \r\n}\r\n\r\nstatic AlgorithmEnum invalidAlgo(Invalid, \"\", 0, \"\", NULL, NULL, None);\r\n\r\n\r\nEnumBase::EnumBase(AlgoTypes a) : algoType(a) {\r\n}\r\n\r\n\r\nEnumBase::~EnumBase() {\r\n    std::vector<AlgorithmEnum* >::iterator b = algos.begin();\r\n    std::vector<AlgorithmEnum* >::iterator e = algos.end();\r\n\r\n    for (; b != e; b++) {\r\n        if (*b) {\r\n            delete *b;\r\n        }\r\n    }\r\n}\r\n\r\nvoid EnumBase::insert(const char* name) {\r\n    if (!name)\r\n        return;\r\n    AlgorithmEnum* e = new AlgorithmEnum(algoType, name, 0, \"\", NULL, NULL, None);\r\n    algos.push_back(e);\r\n}\r\n\r\nvoid EnumBase::insert(const char* name, int32_t klen, const char* ra,\r\n                      encrypt_t enc, decrypt_t dec, SrtpAlgorithms alId) {\r\n    if (!name)\r\n        return;\r\n    AlgorithmEnum* e = new AlgorithmEnum(algoType, name, klen, ra, enc, dec, alId);\r\n    algos.push_back(e);\r\n}\r\n\r\nint EnumBase::getSize() {\r\n    return algos.size(); \r\n}\r\n\r\nAlgoTypes EnumBase::getAlgoType() {\r\n    return algoType;\r\n}\r\n\r\nAlgorithmEnum& EnumBase::getByName(const char* name) {\r\n    std::vector<AlgorithmEnum* >::iterator b = algos.begin();\r\n    std::vector<AlgorithmEnum* >::iterator e = algos.end();\r\n\r\n    for (; b != e; b++) {\r\n        if (strncmp((*b)->getName(), name, 4) == 0) {\r\n            return *(*b);\r\n        }\r\n    }\r\n    return invalidAlgo;\r\n}\r\n\r\nAlgorithmEnum& EnumBase::getByOrdinal(int ord) {\r\n    std::vector<AlgorithmEnum* >::iterator b = algos.begin();\r\n    std::vector<AlgorithmEnum* >::iterator e = algos.end();\r\n\r\n    for (int i = 0; b != e; ++b) {\r\n        if (i == ord) {\r\n            return *(*b);\r\n        }\r\n        i++;\r\n    }\r\n    return invalidAlgo;\r\n}\r\n\r\nint EnumBase::getOrdinal(AlgorithmEnum& algo) {\r\n    std::vector<AlgorithmEnum* >::iterator b = algos.begin();\r\n    std::vector<AlgorithmEnum* >::iterator e = algos.end();\r\n\r\n    for (int i = 0; b != e; ++b) {\r\n        if (strncmp((*b)->getName(), algo.getName(), 4) == 0) {\r\n            return i;\r\n        }\r\n        i++;\r\n    }\r\n    return -1;\r\n}\r\n\r\nstd::list<std::string>* EnumBase::getAllNames() {\r\n    std::vector<AlgorithmEnum* >::iterator b = algos.begin();\r\n    std::vector<AlgorithmEnum* >::iterator e = algos.end();\r\n\r\n    std::list<std::string>* strg = new std::list<std::string>();\r\n\r\n    for (; b != e; b++) {\r\n        std::string s((*b)->getName());\r\n        strg->push_back(s);\r\n    }\r\n    return strg;\r\n}\r\n\r\n\r\n/**\r\n * Set up the enumeration list for available hash algorithms\r\n */\r\nHashEnum::HashEnum() : EnumBase(HashAlgorithm) {\r\n    insert(s256, 0, \"SHA-256\", NULL, NULL, None);\r\n    insert(s384, 0, \"SHA-384\", NULL, NULL, None);\r\n    insert(skn2, 0, \"Skein-256\", NULL, NULL, None);\r\n    insert(skn3, 0, \"Skein-384\", NULL, NULL, None);\r\n}\r\n\r\nHashEnum::~HashEnum() {}\r\n\r\n/**\r\n * Set up the enumeration list for available symmetric cipher algorithms\r\n */\r\nSymCipherEnum::SymCipherEnum() : EnumBase(CipherAlgorithm) {\r\n    insert(aes3, 32, \"AES-256\", aesCfbEncrypt, aesCfbDecrypt, Aes);\r\n    insert(aes1, 16, \"AES-128\", aesCfbEncrypt, aesCfbDecrypt, Aes);\r\n    insert(two3, 32, \"Twofish-256\", twoCfbEncrypt, twoCfbDecrypt, TwoFish);\r\n    insert(two1, 16, \"TwoFish-128\", twoCfbEncrypt, twoCfbDecrypt, TwoFish);\r\n}\r\n\r\nSymCipherEnum::~SymCipherEnum() {}\r\n\r\n/**\r\n * Set up the enumeration list for available public key algorithms\r\n */\r\nPubKeyEnum::PubKeyEnum() : EnumBase(PubKeyAlgorithm) {\r\n    insert(dh2k, 0, \"DH-2048\", NULL, NULL, None);\r\n    insert(ec25, 0, \"NIST ECDH-256\", NULL, NULL, None);\r\n    insert(dh3k, 0, \"DH-3072\", NULL, NULL, None);\r\n    insert(ec38, 0, \"NIST ECDH-384\", NULL, NULL, None);\r\n    insert(mult, 0, \"Multi-stream\",  NULL, NULL, None);\r\n#ifdef SUPPORT_NON_NIST\r\n    insert(e255, 0, \"ECDH-255\", NULL, NULL, None);\r\n    insert(e414, 0, \"ECDH-414\", NULL, NULL, None);\r\n#endif\r\n}\r\n\r\nPubKeyEnum::~PubKeyEnum() {}\r\n\r\n/**\r\n * Set up the enumeration list for available SAS algorithms\r\n */\r\nSasTypeEnum::SasTypeEnum() : EnumBase(SasType) {\r\n    insert(b32);\r\n    insert(b256);\r\n}\r\n\r\nSasTypeEnum::~SasTypeEnum() {}\r\n\r\n/**\r\n * Set up the enumeration list for available SRTP authentications\r\n */\r\nAuthLengthEnum::AuthLengthEnum() : EnumBase(AuthLength) {\r\n    insert(hs32, 32, \"HMAC-SHA1 32 bit\", NULL, NULL, Sha1);\r\n    insert(hs80, 80, \"HMAC-SHA1 80 bit\", NULL, NULL, Sha1);\r\n    insert(sk32, 32, \"Skein-MAC 32 bit\", NULL, NULL, Skein);\r\n    insert(sk64, 64, \"Skein-MAC 64 bit\", NULL, NULL, Skein);\r\n}\r\n\r\nAuthLengthEnum::~AuthLengthEnum() {}\r\n\r\n/*\r\n * Here the global accessible enumerations for all implemented algorithms.\r\n */\r\nHashEnum zrtpHashes;\r\nSymCipherEnum zrtpSymCiphers;\r\nPubKeyEnum zrtpPubKeys;\r\nSasTypeEnum zrtpSasTypes;\r\nAuthLengthEnum zrtpAuthLengths;\r\n\r\n/*\r\n * The public methods are mainly a facade to the private methods.\r\n */\r\nZrtpConfigure::ZrtpConfigure(): enableTrustedMitM(false), enableSasSignature(false), enableParanoidMode(false),\r\nselectionPolicy(Standard){}\r\n\r\nZrtpConfigure::~ZrtpConfigure() {}\r\n\r\nvoid ZrtpConfigure::setStandardConfig() {\r\n    clear();\r\n\r\n    addAlgo(HashAlgorithm, zrtpHashes.getByName(s384));\r\n    addAlgo(HashAlgorithm, zrtpHashes.getByName(s256));\r\n\r\n    addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName(aes3));\r\n    addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName(aes1));\r\n    addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName(two3));\r\n    addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName(two1));\r\n\r\n    addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(ec25));\r\n    addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(dh3k));\r\n    addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(ec38));\r\n    addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(dh2k));\r\n    addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(mult));\r\n\r\n    addAlgo(SasType, zrtpSasTypes.getByName(b32));\r\n\r\n    addAlgo(AuthLength, zrtpAuthLengths.getByName(sk32));\r\n    addAlgo(AuthLength, zrtpAuthLengths.getByName(sk64));\r\n    addAlgo(AuthLength, zrtpAuthLengths.getByName(hs32));\r\n    addAlgo(AuthLength, zrtpAuthLengths.getByName(hs80));\r\n}\r\n\r\nvoid ZrtpConfigure::setMandatoryOnly() {\r\n    clear();\r\n\r\n    addAlgo(HashAlgorithm, zrtpHashes.getByName(s256));\r\n\r\n    addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName(aes1));\r\n\r\n    addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(dh3k));\r\n    addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(mult));\r\n\r\n    addAlgo(SasType, zrtpSasTypes.getByName(b32));\r\n\r\n    addAlgo(AuthLength, zrtpAuthLengths.getByName(hs32));\r\n    addAlgo(AuthLength, zrtpAuthLengths.getByName(hs80));\r\n\r\n}\r\n\r\nvoid ZrtpConfigure::clear() {\r\n    hashes.clear();\r\n    symCiphers.clear();\r\n    publicKeyAlgos.clear();\r\n    sasTypes.clear();\r\n    authLengths.clear();\r\n}\r\n\r\nint32_t ZrtpConfigure::addAlgo(AlgoTypes algoType, AlgorithmEnum& algo) {\r\n\r\n    return addAlgo(getEnum(algoType), algo);\r\n}\r\n\r\nint32_t ZrtpConfigure::addAlgoAt(AlgoTypes algoType, AlgorithmEnum& algo, int32_t index) {\r\n\r\n    return addAlgoAt(getEnum(algoType), algo, index);\r\n}\r\n\r\nAlgorithmEnum& ZrtpConfigure::getAlgoAt(AlgoTypes algoType, int32_t index) {\r\n\r\n    return getAlgoAt(getEnum(algoType), index);\r\n}\r\n\r\nint32_t ZrtpConfigure::removeAlgo(AlgoTypes algoType, AlgorithmEnum& algo) {\r\n\r\n    return removeAlgo(getEnum(algoType), algo);\r\n}\r\n\r\nint32_t ZrtpConfigure::getNumConfiguredAlgos(AlgoTypes algoType) {\r\n\r\n    return getNumConfiguredAlgos(getEnum(algoType));\r\n}\r\n\r\nbool ZrtpConfigure::containsAlgo(AlgoTypes algoType, AlgorithmEnum& algo) {\r\n\r\n    return containsAlgo(getEnum(algoType), algo);\r\n}\r\n\r\nvoid ZrtpConfigure::printConfiguredAlgos(AlgoTypes algoType) {\r\n\r\n    printConfiguredAlgos(getEnum(algoType));\r\n}\r\n\r\n/*\r\n * The next methods are the private methods that implement the real\r\n * details.\r\n */\r\nAlgorithmEnum& ZrtpConfigure::getAlgoAt(std::vector<AlgorithmEnum* >& a, int32_t index) {\r\n\r\n    if (index >= (int)a.size())\r\n        return invalidAlgo;\r\n\r\n    std::vector<AlgorithmEnum* >::iterator b = a.begin();\r\n    std::vector<AlgorithmEnum* >::iterator e = a.end();\r\n\r\n    for (int i = 0; b != e; ++b) {\r\n        if (i == index) {\r\n            return *(*b);\r\n        }\r\n        i++;\r\n    }\r\n    return invalidAlgo;\r\n}\r\n\r\nint32_t ZrtpConfigure::addAlgo(std::vector<AlgorithmEnum* >& a, AlgorithmEnum& algo) {\r\n    int size = (int)a.size();\r\n    if (size >= maxNoOfAlgos)\r\n        return -1;\r\n\r\n    if (!algo.isValid())\r\n        return -1;\r\n\r\n    if (containsAlgo(a, algo))\r\n        return (maxNoOfAlgos - size);\r\n\r\n    a.push_back(&algo);\r\n    return (maxNoOfAlgos - (int)a.size());\r\n}\r\n\r\nint32_t ZrtpConfigure::addAlgoAt(std::vector<AlgorithmEnum* >& a, AlgorithmEnum& algo, int32_t index) {\r\n    if (index >= maxNoOfAlgos)\r\n        return -1;\r\n\r\n    int size = (int)a.size();\r\n\r\n    if (!algo.isValid())\r\n        return -1;\r\n\r\n//    a[index] = &algo;\r\n\r\n    if (index >= size) {\r\n        a.push_back(&algo);\r\n        return maxNoOfAlgos - (int)a.size();\r\n    }\r\n    std::vector<AlgorithmEnum* >::iterator b = a.begin();\r\n    std::vector<AlgorithmEnum* >::iterator e = a.end();\r\n\r\n    for (int i = 0; b != e; ++b) {\r\n        if (i == index) {\r\n            a.insert(b, &algo);\r\n            break;\r\n        }\r\n        i++;\r\n    }\r\n    return (maxNoOfAlgos - (int)a.size());\r\n}\r\n\r\nint32_t ZrtpConfigure::removeAlgo(std::vector<AlgorithmEnum* >& a, AlgorithmEnum& algo) {\r\n\r\n    if ((int)a.size() == 0 || !algo.isValid())\r\n        return maxNoOfAlgos;\r\n\r\n    std::vector<AlgorithmEnum* >::iterator b = a.begin();\r\n    std::vector<AlgorithmEnum* >::iterator e = a.end();\r\n\r\n    for (; b != e; ++b) {\r\n        if (strcmp((*b)->getName(), algo.getName()) == 0) {\r\n            a.erase(b);\r\n            break;\r\n        }\r\n    }\r\n    return (maxNoOfAlgos - (int)a.size());\r\n}\r\n\r\nint32_t ZrtpConfigure::getNumConfiguredAlgos(std::vector<AlgorithmEnum* >& a) {\r\n    return (int32_t)a.size();\r\n}\r\n\r\nbool ZrtpConfigure::containsAlgo(std::vector<AlgorithmEnum* >& a, AlgorithmEnum& algo) {\r\n\r\n    if ((int)a.size() == 0 || !algo.isValid())\r\n        return false;\r\n\r\n    std::vector<AlgorithmEnum* >::iterator b = a.begin();\r\n    std::vector<AlgorithmEnum* >::iterator e = a.end();\r\n\r\n    for (; b != e; ++b) {\r\n        if (strcmp((*b)->getName(), algo.getName()) == 0) {\r\n            return true;\r\n        }\r\n    }\r\n    return false;\r\n}\r\n\r\nvoid ZrtpConfigure::printConfiguredAlgos(std::vector<AlgorithmEnum* >& a) {\r\n\r\n    std::vector<AlgorithmEnum* >::iterator b = a.begin();\r\n    std::vector<AlgorithmEnum* >::iterator e = a.end();\r\n\r\n    for (; b != e; ++b) {\r\n        printf(\"print configured: name: %s\\n\", (*b)->getName());\r\n    }\r\n}\r\n\r\nstd::vector<AlgorithmEnum* >& ZrtpConfigure::getEnum(AlgoTypes algoType) {\r\n\r\n    switch(algoType) {\r\n        case HashAlgorithm:\r\n            return hashes;\r\n            break;\r\n\r\n        case CipherAlgorithm:\r\n            return symCiphers;\r\n            break;\r\n\r\n        case PubKeyAlgorithm:\r\n            return publicKeyAlgos;\r\n            break;\r\n\r\n        case SasType:\r\n            return sasTypes;\r\n            break;\r\n\r\n        case AuthLength:\r\n            return authLengths;\r\n            break;\r\n\r\n        default:\r\n            break;\r\n    }\r\n    return hashes;\r\n}\r\n\r\nvoid ZrtpConfigure::setTrustedMitM(bool yesNo) {\r\n    enableTrustedMitM = yesNo;\r\n}\r\n\r\nbool ZrtpConfigure::isTrustedMitM() {\r\n    return enableTrustedMitM;\r\n}\r\n\r\nvoid ZrtpConfigure::setSasSignature(bool yesNo) {\r\n    enableSasSignature = yesNo;\r\n}\r\n\r\nbool ZrtpConfigure::isSasSignature() {\r\n    return enableSasSignature;\r\n}\r\n\r\nvoid ZrtpConfigure::setParanoidMode(bool yesNo) {\r\n    enableParanoidMode = yesNo;\r\n}\r\n\r\nbool ZrtpConfigure::isParanoidMode() {\r\n    return enableParanoidMode;\r\n}\r\n\r\n#if 0\r\nZrtpConfigure config;\r\n\r\nmain() {\r\n    printf(\"Start\\n\");\r\n    printf(\"size: %d\\n\", zrtpHashes.getSize());\r\n    AlgorithmEnum e = zrtpHashes.getByName(\"S256\");\r\n    printf(\"algo name: %s\\n\", e.getName());\r\n    printf(\"algo type: %d\\n\", e.getAlgoType());\r\n\r\n    std::list<std::string>* names = zrtpHashes.getAllNames();\r\n    printf(\"size of name list: %d\\n\", names->size());\r\n    printf(\"first name: %s\\n\", names->front().c_str());\r\n    printf(\"last name: %s\\n\", names->back().c_str());\r\n\r\n    printf(\"free slots: %d (expected 6)\\n\", config.addAlgo(HashAlgorithm, e));\r\n\r\n    AlgorithmEnum e1(HashAlgorithm, \"SHA384\");\r\n    printf(\"free slots: %d (expected 5)\\n\", config.addAlgoAt(HashAlgorithm, e1, 0));\r\n    AlgorithmEnum e2 = config.getAlgoAt(HashAlgorithm, 0);\r\n    printf(\"algo name: %s (expected SHA384)\\n\", e2.getName());\r\n    printf(\"Num of configured algos: %d (expected 2)\\n\", config.getNumConfiguredAlgos(HashAlgorithm));\r\n    config.printConfiguredAlgos(HashAlgorithm);\r\n    printf(\"free slots: %d (expected 6)\\n\", config.removeAlgo(HashAlgorithm, e2));\r\n    e2 = config.getAlgoAt(HashAlgorithm, 0);\r\n    printf(\"algo name: %s (expected SHA256)\\n\", e2.getName());\r\n    \r\n    printf(\"clearing config\\n\");\r\n    config.clear();\r\n    printf(\"size: %d\\n\", zrtpHashes.getSize());\r\n    e = zrtpHashes.getByName(\"S256\");\r\n    printf(\"algo name: %s\\n\", e.getName());\r\n    printf(\"algo type: %d\\n\", e.getAlgoType());\r\n\r\n}\r\n\r\n#endif\r\n/** EMACS **\r\n * Local variables:\r\n * mode: c++\r\n * c-default-style: ellemtel\r\n * c-basic-offset: 4\r\n * End:\r\n */\r\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpCrc32.cpp",
    "content": "/* The following code has been taken directly from\n * draft-ietf-tsvwg-sctpcsum-03.txt\n *\n * The code has now been modified by Werner.Dittmann@t-online.de for use\n * inside the ZRTP implementation.\n */\n\n#include <stdio.h>\n#include <stdint.h>\n#include <libzrtpcpp/ZrtpCrc32.h>\n\n#define CRC32C_POLY 0x1EDC6F41\n#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/* Copyright 2001, D. Otis.  Use this program, code or tables    */\n/* extracted from it, as desired without restriction.            */\n/*                                                               */\n/* 32 Bit Reflected CRC table generation for SCTP.               */\n/* To accommodate serial byte data being shifted out least       */\n/* significant bit first, the table's 32 bit words are reflected */\n/* which flips both byte and bit MS and LS positions.  The CRC   */\n/* is calculated MS bits first from the perspective of the serial*/\n/* stream.  The x^32 term is implied and the x^0 term may also   */\n/* be shown as +1.  The polynomial code used is 0x1EDC6F41.      */\n/* Castagnoli93                                                  */\n/* x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+  */\n/* x^11+x^10+x^9+x^8+x^6+x^0                                     */\n/* Guy Castagnoli Stefan Braeuer and Martin Herrman              */\n/* \"Optimization of Cyclic Redundancy-Check Codes                */\n/* with 24 and 32 Parity Bits\",                                  */\n/* IEEE Transactions on Communications, Vol.41, No.6, June 1993  */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\nstatic const uint32_t crc_c[256] = {\n    0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,\n    0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,\n    0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,\n    0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,\n    0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,\n    0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,\n    0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,\n    0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,\n    0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,\n    0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,\n    0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,\n    0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,\n    0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,\n    0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,\n    0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,\n    0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,\n    0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,\n    0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,\n    0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,\n    0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,\n    0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,\n    0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,\n    0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,\n    0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,\n    0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,\n    0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,\n    0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,\n    0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,\n    0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,\n    0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,\n    0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,\n    0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,\n    0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,\n    0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,\n    0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,\n    0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,\n    0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,\n    0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,\n    0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,\n    0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,\n    0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,\n    0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,\n    0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,\n    0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,\n    0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,\n    0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,\n    0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,\n    0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,\n    0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,\n    0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,\n    0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,\n    0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,\n    0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,\n    0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,\n    0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,\n    0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,\n    0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,\n    0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,\n    0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,\n    0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,\n    0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,\n    0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,\n    0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,\n    0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351,\n};\n\n\nbool zrtpCheckCksum(uint8_t *buffer, uint16_t length, uint32_t crc32)\n{\n    uint32_t chksum = zrtpGenerateCksum(buffer, length);\n    chksum = zrtpEndCksum(chksum);\n    // fprintf(stderr, \"Received crc %x, computed crc: %x\\n\", crc32, chksum);\n    return (crc32 == chksum);\n}\n\nuint32_t zrtpGenerateCksum(uint8_t *buffer, uint16_t length)\n{\n    uint32_t crc32 = ~(uint32_t) 0;\n    uint32_t i;\n\n    // fprintf(stderr, \"Buffer %xl, length: %d\\n\", buffer, length);\n    /* Calculate the CRC. */\n    for (i = 0; i < length ; i++)\n        CRC32C(crc32, buffer[i]);\n\n    return crc32;\n}\n\nuint32_t zrtpEndCksum(uint32_t crc32)\n{\n    uint32_t result;\n    uint8_t byte0, byte1, byte2, byte3;\n\n    result = ~crc32;\n\n    /*  result  now holds the negated polynomial remainder;\n     *  since the table and algorithm is \"reflected\" [williams95].\n     *  That is,  result has the same value as if we mapped the message\n     *  to a polyomial, computed the host-bit-order polynomial\n     *  remainder, performed final negation, then did an end-for-end\n     *  bit-reversal.\n     *  Note that a 32-bit bit-reversal is identical to four inplace\n     *  8-bit reversals followed by an end-for-end byteswap.\n     *  In other words, the bytes of each bit are in the right order,\n     *  but the bytes have been byteswapped.  So we now do an explicit\n     *  byteswap.  On a little-endian machine, this byteswap and\n     *  the final ntohl cancel out and could be elided.\n     */\n    byte0 = result & 0xff;\n    byte1 = (result>>8) & 0xff;\n    byte2 = (result>>16) & 0xff;\n    byte3 = (result>>24) & 0xff;\n\n    crc32 = ((byte0 << 24) |\n    (byte1 << 16) |\n    (byte2 << 8)  |\n    byte3);\n    // fprintf(stderr, \"Computed crc32: %x\\n\", crc32);\n    return crc32;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketClearAck.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <libzrtpcpp/ZrtpPacketClearAck.h>\n\nZrtpPacketClearAck::ZrtpPacketClearAck() {\n    DEBUGOUT((fprintf(stdout, \"Creating ClearAck packet without data\\n\")));\n\n    zrtpHeader = &data.hdr;\t// the standard header\n\n    setZrtpId();\n    setLength((sizeof(ClearAckPacket_t) / ZRTP_WORD_SIZE) - 1);\n    setMessageType((uint8_t*)ClearAckMsg);\n}\n\nZrtpPacketClearAck::ZrtpPacketClearAck(uint8_t *data) {\n    DEBUGOUT((fprintf(stdout, \"Creating Conf2Ack packet from data\\n\")));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((ClearAckPacket_t*)data)->hdr;\t// the standard header\n}\n\nZrtpPacketClearAck::~ZrtpPacketClearAck() {\n    DEBUGOUT((fprintf(stdout, \"Deleting ClearAck packet: alloc: %x\\n\", allocated)));\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketCommit.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <libzrtpcpp/ZrtpPacketCommit.h>\n\nZrtpPacketCommit::ZrtpPacketCommit() {\n    DEBUGOUT((fprintf(stdout, \"Creating commit packet without data\\n\")));\n\n    zrtpHeader = &data.hdr;\t// the standard header\n    commitHeader = &data.commit;\n\n    setZrtpId();\n    setLength((sizeof (CommitPacket_t) / ZRTP_WORD_SIZE) - 1);\n    setMessageType((uint8_t*)CommitMsg);\n}\n\nvoid ZrtpPacketCommit::setNonce(uint8_t* text) {\n    memcpy(commitHeader->hvi, text, sizeof(data.commit.hvi)-4*ZRTP_WORD_SIZE);\n    uint16_t len = getLength();\n    len -= 4;\n    setLength(len);\n}\n\nZrtpPacketCommit::ZrtpPacketCommit(uint8_t *data) {\n    DEBUGOUT((fprintf(stdout, \"Creating commit packet from data\\n\")));\n    zrtpHeader = (zrtpPacketHeader_t *)&((CommitPacket_t *)data)->hdr;\t// the standard header\n    commitHeader = (Commit_t *)&((CommitPacket_t *)data)->commit;\n}\n\nZrtpPacketCommit::~ZrtpPacketCommit() {\n    DEBUGOUT((fprintf(stdout, \"Deleting commit packet: alloc: %x\\n\", allocated)));\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketConf2Ack.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <libzrtpcpp/ZrtpPacketConf2Ack.h>\n\nZrtpPacketConf2Ack::ZrtpPacketConf2Ack() {\n    DEBUGOUT((fprintf(stdout, \"Creating Conf2Ack packet without data\\n\")));\n\n    zrtpHeader = &data.hdr;\t// the standard header\n\n    setZrtpId();\n    setLength((sizeof (Conf2AckPacket_t) / ZRTP_WORD_SIZE) - 1);\n    setMessageType((uint8_t*)Conf2AckMsg);\n}\n\nZrtpPacketConf2Ack::ZrtpPacketConf2Ack(char *data) {\n    DEBUGOUT((fprintf(stdout, \"Creating Conf2Ack packet from data\\n\")));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((Conf2AckPacket_t*)data)->hdr;\t// the standard header\n}\n\nZrtpPacketConf2Ack::~ZrtpPacketConf2Ack() {\n    DEBUGOUT((fprintf(stdout, \"Deleting Conf2Ack packet: alloc: %x\\n\", allocated)));\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketConfirm.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <libzrtpcpp/ZrtpPacketConfirm.h>\n\nZrtpPacketConfirm::ZrtpPacketConfirm() {\n    DEBUGOUT((fprintf(stdout, \"Creating Confirm packet without data, no sl data\\n\")));\n    initialize();\n    setSignatureLength(0);\n}\n\nZrtpPacketConfirm::ZrtpPacketConfirm(uint32_t sl) {\n    DEBUGOUT((fprintf(stdout, \"Creating Confirm packet without data\\n\")));\n    initialize();\n    setSignatureLength(sl);\n}\n\nvoid ZrtpPacketConfirm::initialize() {\n    void* allocated = &data;\n    memset(allocated, 0, sizeof(data));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((ConfirmPacket_t *)allocated)->hdr;\t// the standard header\n    confirmHeader = (Confirm_t *)&((ConfirmPacket_t *)allocated)->confirm;\n\n    setZrtpId();\n}\n\nbool ZrtpPacketConfirm::setSignatureLength(uint32_t sl) {\n    if (sl > 512)\n        return false;\n\n    int32_t length = sizeof(ConfirmPacket_t) + (sl * ZRTP_WORD_SIZE);\n    confirmHeader->sigLength = sl;                                     // sigLength is a uint byte\n    if (sl & 0x100) {                                                  // check the 9th bit\n        confirmHeader->filler[1] = 1;                                  // and set it if necessary\n    }\n    setLength(length / 4);\n    return true;\n}\n\nbool ZrtpPacketConfirm::setSignatureData(uint8_t* data, int32_t length) {\n    int32_t l = getSignatureLength() * 4;\n    if (length > l || (length % 4) != 0)\n        return false;\n\n    uint8_t* p = ((uint8_t*)&confirmHeader->expTime) + 4;              // point to signature block\n    memcpy(p, data, length);\n    return true;\n}\n\nbool ZrtpPacketConfirm::isSignatureLengthOk() {\n    int32_t actualLen = getLength();\n    int32_t expectedLen = 19;                  // Confirm packet fixed part is 19 ZRTP words\n    int32_t sigLen = getSignatureLength();\n\n    if (sigLen > 0) {                          // We have a signature\n        expectedLen += sigLen + 1;             // +1 for the signature length field\n    }\n    return (expectedLen == actualLen);\n}\n\nint32_t ZrtpPacketConfirm::getSignatureLength() {\n    int32_t sl = confirmHeader->sigLength & 0xff;\n    if (confirmHeader->filler[1] == 1) {                              // do we have a 9th bit\n        sl |= 0x100;\n    }\n    return sl;\n}\n\nZrtpPacketConfirm::ZrtpPacketConfirm(uint8_t* data) {\n    DEBUGOUT((fprintf(stdout, \"Creating Confirm packet from data\\n\")));\n\n    allocated = NULL;\n    zrtpHeader = (zrtpPacketHeader_t *)&((ConfirmPacket_t *)data)->hdr;\t// the standard header\n    confirmHeader = (Confirm_t *)&((ConfirmPacket_t *)data)->confirm;\n}\n\nZrtpPacketConfirm::~ZrtpPacketConfirm() {\n    DEBUGOUT((fprintf(stdout, \"Deleting Confirm packet: alloc: %x\\n\", allocated)));\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketDHPart.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <libzrtpcpp/ZrtpPacketDHPart.h>\n\nZrtpPacketDHPart::ZrtpPacketDHPart() {\n    DEBUGOUT((fprintf(stdout, \"Creating DHPart packet without data and pkt type\\n\")));\n    initialize();\n}\n\nZrtpPacketDHPart::ZrtpPacketDHPart(const char* pkt) {\n    DEBUGOUT((fprintf(stdout, \"Creating DHPart packet without data\\n\")));\n    initialize();\n    setPubKeyType(pkt);\n}\n\nvoid ZrtpPacketDHPart::initialize() {\n\n    void* allocated = &data;\n    memset(allocated, 0, sizeof(data));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((DHPartPacket_t *)allocated)->hdr; // the standard header\n    DHPartHeader = (DHPart_t *)&((DHPartPacket_t *)allocated)->dhPart;\n    pv = ((uint8_t*)allocated) + sizeof(DHPartPacket_t);    // point to the public key value\n\n    setZrtpId();\n}\n\n// The fixed numbers below are taken from ZRTP specification, chap 5.1.5\nvoid ZrtpPacketDHPart::setPubKeyType(const char* pkt) {\n    // Well - the algo type is only 4 char thus cast to int32 and compare\n    if (*(int32_t*)pkt == *(int32_t*)dh2k) {\n        dhLength = 256;\n    }\n    else if (*(int32_t*)pkt == *(int32_t*)dh3k) {\n        dhLength = 384;\n    }\n    else if (*(int32_t*)pkt == *(int32_t*)ec25) {\n        dhLength = 64;\n    }\n    else if (*(int32_t*)pkt == *(int32_t*)ec38) {\n        dhLength = 96;\n    }\n    else if (*(int32_t*)pkt == *(int32_t*)e255) {\n        dhLength = 32;\n    }\n    else if (*(int32_t*)pkt == *(int32_t*)e414) {\n        dhLength = 104;\n    }\n    else\n        return;\n\n    int length = sizeof(DHPartPacket_t) + dhLength + (2 * ZRTP_WORD_SIZE); // HMAC field is 2*ZRTP_WORD_SIZE\n    setLength(length / ZRTP_WORD_SIZE);\n}\n\nZrtpPacketDHPart::ZrtpPacketDHPart(uint8_t *data) {\n    DEBUGOUT((fprintf(stdout, \"Creating DHPart packet from data\\n\")));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((DHPartPacket_t *)data)->hdr;  // the standard header\n    DHPartHeader = (DHPart_t *)&((DHPartPacket_t *)data)->dhPart;\n\n    int16_t len = getLength();\n    DEBUGOUT((fprintf(stdout, \"DHPart length: %d\\n\", len)));\n    if (len == 85) {         // Dh2k\n        dhLength = 256;\n    }\n    else if (len == 117) {   // Dh3k\n        dhLength = 384;\n    }\n    else if (len == 37) {    // EC256\n        dhLength = 64;\n    }\n    else if (len == 45) {    // EC384\n        dhLength = 96;\n    }\n    else if (len == 29) {    // E255\n        dhLength = 32;\n    }\n    else if (len == 47) {    // E414\n        dhLength = 104;\n    }\n    else {\n        pv = NULL;\n        return;\n    }\n    pv = data + sizeof(DHPartPacket_t);    // point to the public key value\n}\n\nZrtpPacketDHPart::~ZrtpPacketDHPart() {\n    DEBUGOUT((fprintf(stdout, \"Deleting DHPart packet: alloc: %x\\n\", allocated)));\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketError.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/* Copyright (C) 2006\n *\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <libzrtpcpp/ZrtpPacketError.h>\n\nZrtpPacketError::ZrtpPacketError() {\n    DEBUGOUT((fprintf(stdout, \"Creating Error packet without data\\n\")));\n\n    zrtpHeader = &data.hdr;\t// the standard header\n    errorHeader = &data.error;\n\n    setZrtpId();\n    setLength((sizeof(ErrorPacket_t) / ZRTP_WORD_SIZE) - 1);\n    setMessageType((uint8_t*)ErrorMsg);\n}\n\nZrtpPacketError::ZrtpPacketError(uint8_t *data) {\n    DEBUGOUT((fprintf(stdout, \"Creating Error packet from data\\n\")));\n\n    allocated = NULL;\n    zrtpHeader = (zrtpPacketHeader_t *)&((ErrorPacket_t *)data)->hdr;\t// the standard header\n    errorHeader = (Error_t *)&((ErrorPacket_t *)data)->error;\n}\n\nZrtpPacketError::~ZrtpPacketError() {\n    DEBUGOUT((fprintf(stdout, \"Deleting Error packet: alloc: %x\\n\", allocated)));\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketErrorAck.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <libzrtpcpp/ZrtpPacketErrorAck.h>\n\nZrtpPacketErrorAck::ZrtpPacketErrorAck() {\n    DEBUGOUT((fprintf(stdout, \"Creating ErrorAck packet without data\\n\")));\n\n    zrtpHeader = &data.hdr;\t// the standard header\n\n    setZrtpId();\n    setLength((sizeof (ErrorAckPacket_t) / ZRTP_WORD_SIZE) - 1);\n    setMessageType((uint8_t*)ErrorAckMsg);\n}\n\nZrtpPacketErrorAck::ZrtpPacketErrorAck(uint8_t *data) {\n    DEBUGOUT((fprintf(stdout, \"Creating ErrorAck packet from data\\n\")));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((ErrorAckPacket_t*)data)->hdr;\t// the standard header\n}\n\nZrtpPacketErrorAck::~ZrtpPacketErrorAck() {\n    DEBUGOUT((fprintf(stdout, \"Deleting ErrorAck packet: alloc: %x\\n\", allocated)));\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketGoClear.cpp",
    "content": "/*\n  Copyright (C) 2006-2007 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/* Copyright (C) 2006\n *\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <libzrtpcpp/ZrtpPacketGoClear.h>\n\nZrtpPacketGoClear::ZrtpPacketGoClear() {\n    DEBUGOUT((fprintf(stdout, \"Creating GoClear packet without data\\n\")));\n\n    zrtpHeader = &data.hdr;\t// the standard header\n    clearHeader = &data.goClear;\n\n    setZrtpId();\n    setLength((sizeof(GoClearPacket_t) / ZRTP_WORD_SIZE) - 1);\n    setMessageType((uint8_t*)GoClearMsg);\n}\n\nZrtpPacketGoClear::ZrtpPacketGoClear(uint8_t *data) {\n    DEBUGOUT((fprintf(stdout, \"Creating GoClear packet from data\\n\")));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((GoClearPacket_t *)data)->hdr;\t// the standard header\n    clearHeader = (GoClear_t *)&((GoClearPacket_t *)data)->goClear;\n}\n\nZrtpPacketGoClear::~ZrtpPacketGoClear() {\n    DEBUGOUT((fprintf(stdout, \"Deleting GoClear packet: alloc: %x\\n\", allocated)));\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketHello.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <ctype.h>\n#include <libzrtpcpp/ZrtpPacketHello.h>\n\n\nZrtpPacketHello::ZrtpPacketHello() {\n    DEBUGOUT((fprintf(stdout, \"Creating Hello packet without data\\n\")));\n}\n\nvoid ZrtpPacketHello::configureHello(ZrtpConfigure* config) {\n    // The NumSupported* data is in ZrtpTextData.h \n    nHash = config->getNumConfiguredAlgos(HashAlgorithm);\n    nCipher = config->getNumConfiguredAlgos(CipherAlgorithm);\n    nPubkey = config->getNumConfiguredAlgos(PubKeyAlgorithm);\n    nSas = config->getNumConfiguredAlgos(SasType);\n    nAuth = config->getNumConfiguredAlgos(AuthLength);\n\n    // length is fixed Header plus HMAC size (2*ZRTP_WORD_SIZE)\n    int32_t length = sizeof(HelloPacket_t) + (2 * ZRTP_WORD_SIZE);\n    length += nHash * ZRTP_WORD_SIZE;\n    length += nCipher * ZRTP_WORD_SIZE;\n    length += nPubkey * ZRTP_WORD_SIZE;\n    length += nSas * ZRTP_WORD_SIZE;\n    length += nAuth * ZRTP_WORD_SIZE;\n\n    // Don't change order of this sequence\n    oHash = sizeof(Hello_t);\n    oCipher = oHash + (nHash * ZRTP_WORD_SIZE);\n    oAuth = oCipher + (nCipher * ZRTP_WORD_SIZE);\n    oPubkey = oAuth + (nAuth * ZRTP_WORD_SIZE);\n    oSas = oPubkey + (nPubkey * ZRTP_WORD_SIZE);\n    oHmac = oSas + (nSas * ZRTP_WORD_SIZE);         // offset to HMAC\n\n    void* allocated = &data;\n    memset(allocated, 0, sizeof(data));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((HelloPacket_t *)allocated)->hdr;\t// the standard header\n    helloHeader = (Hello_t *)&((HelloPacket_t *)allocated)->hello;\n\n    setZrtpId();\n\n    // minus 1 for CRC size \n    setLength(length / ZRTP_WORD_SIZE);\n    setMessageType((uint8_t*)HelloMsg);\n\n    uint32_t lenField = nHash << 16;\n    for (int32_t i = 0; i < nHash; i++) {\n        AlgorithmEnum& hash = config->getAlgoAt(HashAlgorithm, i);\n        setHashType(i, (int8_t*)hash.getName());\n    }\n\n    lenField |= nCipher << 12;\n    for (int32_t i = 0; i < nCipher; i++) {\n        AlgorithmEnum& cipher = config->getAlgoAt(CipherAlgorithm, i);\n        setCipherType(i, (int8_t*)cipher.getName());\n    }\n\n    lenField |= nAuth << 8;\n    for (int32_t i = 0; i < nAuth; i++) {\n        AlgorithmEnum& length = config->getAlgoAt(AuthLength, i);\n        setAuthLen(i, (int8_t*)length.getName());\n    }\n\n    lenField |= nPubkey << 4;\n    for (int32_t i = 0; i < nPubkey; i++) {\n        AlgorithmEnum& pubKey = config->getAlgoAt(PubKeyAlgorithm, i);\n        setPubKeyType(i, (int8_t*)pubKey.getName());\n    }\n\n    lenField |= nSas;\n    for (int32_t i = 0; i < nSas; i++) {\n        AlgorithmEnum& sas = config->getAlgoAt(SasType, i);\n        setSasType(i, (int8_t*)sas.getName());\n    }\n    *((uint32_t*)&helloHeader->flags) = zrtpHtonl(lenField);\n}\n\nZrtpPacketHello::ZrtpPacketHello(uint8_t *data) {\n    DEBUGOUT((fprintf(stdout, \"Creating Hello packet from data\\n\")));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((HelloPacket_t *)data)->hdr;\t// the standard header\n    helloHeader = (Hello_t *)&((HelloPacket_t *)data)->hello;\n\n    // Force the isLengthOk() check to fail when we process the packet.\n    if (getLength() < HELLO_FIXED_PART_LEN) {\n        computedLength = 0;\n        return;\n    }\n\n    uint32_t t = *((uint32_t*)&helloHeader->flags);\n    uint32_t temp = zrtpNtohl(t);\n\n    nHash = (temp & (0xf << 16)) >> 16;\n    nHash &= 0x7;                              // restrict to max 7 algorithms\n    nCipher = (temp & (0xf << 12)) >> 12;\n    nCipher &= 0x7;\n    nAuth = (temp & (0xf << 8)) >> 8;\n    nAuth &= 0x7;\n    nPubkey = (temp & (0xf << 4)) >> 4;\n    nPubkey &= 0x7;\n    nSas = temp & 0xf;\n    nSas &= 0x7;\n\n    // +2 : the MAC at the end of the packet\n    computedLength = nHash + nCipher + nAuth + nPubkey + nSas + sizeof(HelloPacket_t)/ZRTP_WORD_SIZE + 2;\n\n    oHash = sizeof(Hello_t);\n    oCipher = oHash + (nHash * ZRTP_WORD_SIZE);\n    oAuth = oCipher + (nCipher * ZRTP_WORD_SIZE);\n    oPubkey = oAuth + (nAuth * ZRTP_WORD_SIZE);\n    oSas = oPubkey + (nPubkey * ZRTP_WORD_SIZE);\n    oHmac = oSas + (nSas * ZRTP_WORD_SIZE);         // offset to HMAC\n}\n\nZrtpPacketHello::~ZrtpPacketHello() {\n    DEBUGOUT((fprintf(stdout, \"Deleting Hello packet: alloc: %x\\n\", allocated)));\n}\n\nint32_t ZrtpPacketHello::getVersionInt() {\n    uint8_t* vp = getVersion();\n    int32_t version = 0;\n\n    if (isdigit(*vp) && isdigit(*vp+2)) {\n        version = (*vp - '0') * 10;\n        version += *(vp+2) - '0';\n    }\n    return version;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketHelloAck.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <libzrtpcpp/ZrtpPacketHelloAck.h>\n\nZrtpPacketHelloAck::ZrtpPacketHelloAck() {\n    DEBUGOUT((fprintf(stdout, \"Creating HelloAck packet without data\\n\")));\n\n    zrtpHeader = &data.hdr;\t// the standard header\n\n    setZrtpId();\n    setLength((sizeof(HelloAckPacket_t) / ZRTP_WORD_SIZE) - 1);\n    setMessageType((uint8_t*)HelloAckMsg);\n}\n\nZrtpPacketHelloAck::ZrtpPacketHelloAck(uint8_t *data) {\n    DEBUGOUT((fprintf(stdout, \"Creating HelloAck packet from data\\n\")));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((HelloAckPacket_t *)data)->hdr;\t// the standard header\n\n}\n\nZrtpPacketHelloAck::~ZrtpPacketHelloAck() {\n    DEBUGOUT((fprintf(stdout, \"Deleting HelloAck packet: alloc: %x\\n\", allocated)));\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketPing.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <libzrtpcpp/ZrtpPacketPing.h>\n\nZrtpPacketPing::ZrtpPacketPing() {\n    DEBUGOUT((fprintf(stdout, \"Creating Ping packet without data\\n\")));\n\n    zrtpHeader = &data.hdr;\t// the standard header\n    pingHeader = &data.ping;\n\n    setZrtpId();\n    setLength((sizeof(PingPacket_t) / ZRTP_WORD_SIZE) - 1);\n    setMessageType((uint8_t*)PingMsg);\n    setVersion((uint8_t*)zrtpVersion_11);  // TODO: fix version string after clarification\n}\n\nZrtpPacketPing::ZrtpPacketPing(uint8_t *data) {\n    DEBUGOUT((fprintf(stdout, \"Creating Ping packet from data\\n\")));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((PingPacket_t*)data)->hdr;\t// the standard header\n    pingHeader = (Ping_t *)&((PingPacket_t *)data)->ping;\n}\n\nZrtpPacketPing::~ZrtpPacketPing() {\n    DEBUGOUT((fprintf(stdout, \"Deleting Ping packet: alloc: %x\\n\", allocated)));\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketPingAck.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <libzrtpcpp/ZrtpPacketPingAck.h>\n\nZrtpPacketPingAck::ZrtpPacketPingAck() {\n    DEBUGOUT((fprintf(stdout, \"Creating PingAck packet without data\\n\")));\n\n    zrtpHeader = &data.hdr;\t// the standard header\n    pingAckHeader = &data.pingAck;\n\n    setZrtpId();\n    setLength((sizeof(PingAckPacket_t) / ZRTP_WORD_SIZE) - 1);\n    setMessageType((uint8_t*)PingAckMsg);\n    setVersion((uint8_t*)zrtpVersion_11);  // TODO: fix version string after clarification\n}\n\nZrtpPacketPingAck::ZrtpPacketPingAck(uint8_t *data) {\n    DEBUGOUT((fprintf(stdout, \"Creating PingAck packet from data\\n\")));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((PingAckPacket_t*)data)->hdr; // the standard header\n    pingAckHeader = (PingAck_t *)&((PingAckPacket_t *)data)->pingAck;\n}\n\nZrtpPacketPingAck::~ZrtpPacketPingAck() {\n    DEBUGOUT((fprintf(stdout, \"Deleting PingAck packet: alloc: %x\\n\", allocated)));\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketRelayAck.cpp",
    "content": "/*\n  Copyright (C) 2006-20013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <libzrtpcpp/ZrtpPacketRelayAck.h>\n\nZrtpPacketRelayAck::ZrtpPacketRelayAck() {\n    DEBUGOUT((fprintf(stdout, \"Creating RelayAck packet without data\\n\")));\n\n    zrtpHeader = &data.hdr;\t// the standard header\n\n    setZrtpId();\n    setLength((sizeof (RelayAckPacket_t) / ZRTP_WORD_SIZE) - 1);\n    setMessageType((uint8_t*)RelayAckMsg);\n}\n\nZrtpPacketRelayAck::ZrtpPacketRelayAck(uint8_t *data) {\n    DEBUGOUT((fprintf(stdout, \"Creating RelayAck packet from data\\n\")));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((RelayAckPacket_t*)data)->hdr;\t// the standard header\n}\n\nZrtpPacketRelayAck::~ZrtpPacketRelayAck() {\n    DEBUGOUT((fprintf(stdout, \"Deleting RelayAck packet: alloc: %x\\n\", allocated)));\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpPacketSASrelay.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <libzrtpcpp/ZrtpPacketSASrelay.h>\n\nZrtpPacketSASrelay::ZrtpPacketSASrelay() {\n    DEBUGOUT((fprintf(stdout, \"Creating SASrelay packet without data, no sl data\\n\")));\n    initialize();\n    setSignatureLength(0);\n}\n\nZrtpPacketSASrelay::ZrtpPacketSASrelay(uint32_t sl) {\n    DEBUGOUT((fprintf(stdout, \"Creating SASrelay packet without data\\n\")));\n    initialize();\n    setSignatureLength(sl);\n}\n\nvoid ZrtpPacketSASrelay::initialize() {\n    void* allocated = &data;\n    memset(allocated, 0, sizeof(data));\n\n    zrtpHeader = (zrtpPacketHeader_t *)&((SASrelayPacket_t *)allocated)->hdr;\t// the standard header\n    sasRelayHeader = (SASrelay_t *)&((SASrelayPacket_t *)allocated)->sasrelay;\n\n    setZrtpId();\n    setMessageType((uint8_t*)SasRelayMsg);\n}\n\nvoid ZrtpPacketSASrelay::setSignatureLength(uint32_t sl) {\n    sl &= 0x1ff;                                                       // make sure it is max 9 bits\n    int32_t length = sizeof(ConfirmPacket_t) + (sl * ZRTP_WORD_SIZE);\n    sasRelayHeader->sigLength = sl;                                     // sigLength is a uint byte\n    if (sl & 0x100) {                                                  // check the 9th bit\n        sasRelayHeader->filler[1] = 1;                                  // and set it if necessary\n    }\n    setLength(length / 4);\n}\n\nuint32_t ZrtpPacketSASrelay::getSignatureLength() {\n    uint32_t sl = sasRelayHeader->sigLength;\n    if (sasRelayHeader->filler[1] == 1) {                              // do we have a 9th bit\n        sl |= 0x100;\n    }\n    return sl;\n}\n\nZrtpPacketSASrelay::ZrtpPacketSASrelay(uint8_t* data) {\n    DEBUGOUT((fprintf(stdout, \"Creating SASrelay packet from data\\n\")));\n\n    allocated = NULL;\n    zrtpHeader = (zrtpPacketHeader_t *)&((SASrelayPacket_t *)data)->hdr;\t// the standard header\n    sasRelayHeader = (SASrelay_t *)&((SASrelayPacket_t *)data)->sasrelay;\n}\n\nZrtpPacketSASrelay::~ZrtpPacketSASrelay() {\n    DEBUGOUT((fprintf(stdout, \"Deleting SASrelay packet: alloc: %x\\n\", allocated)));\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpSdesStream.cpp",
    "content": "/*\n  Copyright (C) 2012-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <string>\n#include <sstream>\n\n#include <libzrtpcpp/ZrtpSdesStream.h>\n#include <libzrtpcpp/ZrtpTextData.h>\n#include <libzrtpcpp/ZrtpConfigure.h>\n#include <libzrtpcpp/zrtpB64Decode.h>\n#include <libzrtpcpp/zrtpB64Encode.h>\n#include <srtp/CryptoContext.h>\n#include <srtp/CryptoContextCtrl.h>\n#include <cryptcommon/ZrtpRandom.h>\n#include <crypto/hmac384.h>\n\n\n#if defined(_WIN32) || defined(_WIN64)\n# define snprintf _snprintf\n#endif\n\n// SRTP authentication tag length is 80 bits = 10 bytes\n#define ZRTP_TUNNEL_AUTH_LEN  10\n#define ZRTP_TUNNEL_LABEL     10\n/*\n * The ABNF grammar for the crypto attribute is defined below (from RFC 4568):\n *\n *  \"a=crypto:\" tag 1*WSP crypto-suite 1*WSP key-params *(1*WSP session-param)\n *\n *  tag              = 1*9DIGIT\n */\n\n/*\n * Buffer size for names and other strings inside the crypto string. The parse\n * format below restricts parsing to 99 char to provide space for the @c nul byte.\n */\n#define MAX_INNER_LEN 100\n\n/*\n * This format scans a received SDES crypto attribute string according to the\n * grammer shown above but without a \"a=crypto:\" prefix.\n *\n * The format string parses:\n * - %d - the tag as decimal value\n * - %s - the crypto suite name, limited to 99 chars (see MAX_INNER_LEN)\n * - %s - the key parameters, limited to 99 chars\n * - %n - the number of parsed characters to far. The pointer to the session\n *   parameters is: cryptoString + numParsedChars.\n */\nstatic const char parseCrypto[] = \"%d %99s %99s %n\";\n\nstatic const int64_t maxTagValue = 999999999;\n\nstatic const int minElementsCrypto = 3;\n\n/*\n * The ABNF grammar for the key-param (from RFC 4568):\n *\n *  key-param        = key-method \":\" key-info\n *\n * The SRTP specific definitions:\n *\n *  key-method          = srtp-key-method\n *  key-info            = srtp-key-info\n *\n *  srtp-key-method     = \"inline\"\n *  srtp-key-info       = key-salt [\"|\" lifetime] [\"|\" mki]\n *\n */\n\n/*\n * This format parses the key parameter string which is never longer than\n * 99 chars (see parse string above):\n * - the fixed string \"inline:\"\n * - %[A-Za-z0-9+/=] - base 64 characters of master key||master salt\n * - the fixed separator character '|'\n * - %[0-9^] - the lifetime infomration as string that contains digits and ^\n * - the fixed separator character '|'\n * - %[0-9]:%d - parses and strore MKI value and MKI length, separated by ':'\n *\n * If the key parameter string does not contain the operional fields lifetime\n * and MKI information the respective parameters are not filled.\n */\nstatic const char parseKeyParam[] = \" inline:%[A-Za-z0-9+/=]|%[0-9^]|%[0-9]:%d\";\n\nstatic const int minElementsKeyParam = 1;\n\ntypedef struct _cryptoMix {\n    const char* name;\n    int32_t hashLength;\n    ZrtpSdesStream::sdesHmacTypeMix hashType;\n} cryptoMix;\n\nstatic const size_t MIX_HMAC_STRING_MIN_LEN = sizeof(\"HMAC-SHA-384\");\n\nstatic cryptoMix knownMixAlgos[] = {\n    {\"HMAC-SHA-384\", 384, ZrtpSdesStream::MIX_HMAC_SHA},\n    {NULL, 0, ZrtpSdesStream::MIX_NONE}\n};\n\ntypedef struct _suite {\n    ZrtpSdesStream::sdesSuites suite;\n    const char *name;\n    int32_t    keyLength;             // key length in bits\n    int32_t    saltLength;            // salt lenght in bits\n    int32_t    authKeyLength;         // authentication key length in bits\n    const char *tagLength;            // tag type hs80 or hs32\n    const char *cipher;               // aes1 or aes3\n    uint32_t   b64length;             // length of b64 encoded key/saltstring\n    uint64_t   defaultSrtpLifetime;   // key lifetimes in number of packets\n    uint64_t   defaultSrtcpLifetime;\n} suiteParam;\n\n/* NOTE: the b64len of a 128 bit suite is 40, a 256bit suite uses 64 characters */\nstatic suiteParam knownSuites[] = {\n    {ZrtpSdesStream::AES_CM_128_HMAC_SHA1_32, \"AES_CM_128_HMAC_SHA1_32\", 128, 112, 160,\n     hs32, \"AES-128\", 40, (uint64_t)1<<48, (uint64_t)1<<31\n    },\n    {ZrtpSdesStream::AES_CM_128_HMAC_SHA1_80, \"AES_CM_128_HMAC_SHA1_80\", 128, 112, 160,\n     hs80, \"AES-128\", 40, (uint64_t)1<<48, (uint64_t)1<<31\n    },\n    {(ZrtpSdesStream::sdesSuites)0, NULL, 0, 0, 0, 0, 0, 0, 0, 0}\n};\n\nZrtpSdesStream::ZrtpSdesStream(const sdesSuites s) :\n    state(STREAM_INITALIZED), suite(s), recvSrtp(NULL), recvSrtcp(NULL), sendSrtp(NULL),\n    sendSrtcp(NULL), srtcpIndex(0), recvZrtpTunnel(0), sendZrtpTunnel(0), cryptoMixHashLength(0), \n    cryptoMixHashType(MIX_NONE)  {\n}\n\nZrtpSdesStream::~ZrtpSdesStream() {\n    close();\n}\n\nvoid ZrtpSdesStream::close() {\n    delete sendSrtp;\n    sendSrtp = NULL;\n\n    delete recvSrtp;\n    recvSrtp = NULL;\n\n    delete sendSrtcp;\n    sendSrtp = NULL;\n\n    delete recvSrtcp;\n    recvSrtp = NULL;\n\n    delete recvZrtpTunnel;\n    recvZrtpTunnel = NULL;\n\n    delete sendZrtpTunnel;\n    sendZrtpTunnel = NULL;\n}\n\nbool ZrtpSdesStream::createSdes(char *cryptoString, size_t *maxLen, bool sipInvite) {\n\n    if (sipInvite) {\n        if (state != STREAM_INITALIZED)\n            return false;\n        tag = 1;\n    }\n    else {\n        if (state != IN_PROFILE_READY)\n            return false;\n    }\n\n    bool s = createSdesProfile(cryptoString, maxLen);\n    if (!s)\n        return s;\n\n    if (sipInvite) {\n        state = OUT_PROFILE_READY;\n    }\n    else {\n        createSrtpContexts(sipInvite);\n        state = SDES_SRTP_ACTIVE;\n    }\n    return s;\n}\n\nbool ZrtpSdesStream::parseSdes(const char *cryptoString, size_t length, bool sipInvite) {\n\n    if (sipInvite) {\n        if (state != OUT_PROFILE_READY)\n            return false;\n    }\n    else {\n        if (state != STREAM_INITALIZED)\n            return false;\n    }\n    sdesSuites tmpSuite;\n    int32_t tmpTag;\n\n    bool s = parseCreateSdesProfile(cryptoString, length, &tmpSuite, &tmpTag);\n    if (!s)\n        return s;\n\n    if (sipInvite) {\n        // Check if answerer used same tag and suite as the offerer\n        if (tmpTag != tag || suite != tmpSuite)\n            return false;\n        createSrtpContexts(sipInvite);\n        state = SDES_SRTP_ACTIVE;\n    }\n    else {\n        // Answerer stores tag and suite and uses it in createSdesProfile\n        suite = tmpSuite;\n        tag = tmpTag;\n        state = IN_PROFILE_READY;\n    }\n    return s;\n}\n\nbool ZrtpSdesStream::outgoingRtp(uint8_t *packet, size_t length, size_t *newLength) {\n\n    if (state != SDES_SRTP_ACTIVE || sendSrtp == NULL) {\n        *newLength = length;\n        return true;\n    }\n    bool rc = SrtpHandler::protect(sendSrtp, packet, length, newLength);\n    if (rc)\n        ;//protect++;\n    return rc;\n}\n\nint ZrtpSdesStream::incomingRtp(uint8_t *packet, size_t length, size_t *newLength, SrtpErrorData* errorData) {\n    if (state != SDES_SRTP_ACTIVE || recvSrtp == NULL) {    // SRTP inactive, just return with newLength set\n        *newLength = length;\n        return 1;\n    }\n    int32_t rc = SrtpHandler::unprotect(recvSrtp, packet, length, newLength, errorData);\n    if (rc == 1) {\n//            unprotect++\n    }\n    else {\n//            unprotectFailed++;\n    }\n    return rc;\n}\n\n\nbool ZrtpSdesStream::outgoingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength) {\n\n    if (state != SDES_SRTP_ACTIVE || sendZrtpTunnel == NULL) {\n        *newLength = length;\n        return true;\n    }\n    bool rc = SrtpHandler::protect(sendZrtpTunnel, packet, length, newLength);\n    if (rc)\n        ;//protect++;\n    return rc;\n}\n\nint ZrtpSdesStream::incomingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength, SrtpErrorData* errorData) {\n    if (state != SDES_SRTP_ACTIVE || recvZrtpTunnel == NULL) {    // SRTP inactive, just return with newLength set\n        *newLength = length;\n        return 1;\n    }\n    int32_t rc = SrtpHandler::unprotect(recvZrtpTunnel, packet, length, newLength, errorData);\n    if (rc == 1) {\n//            unprotect++\n    }\n    else {\n//            unprotectFailed++;\n    }\n    return rc;\n}\n\n\n\nbool ZrtpSdesStream::outgoingRtcp(uint8_t *packet, size_t length, size_t *newLength) {\n#if 0\nSrtpHandler::protectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength, uint32_t *srtcpIndex)\n#endif\n    return false;\n}\n\nint ZrtpSdesStream::incomingSrtcp(uint8_t *packet, size_t length, size_t *newLength) {\n#if 0\nint32_t SrtpHandler::unprotectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength)\n#endif\n    return 0;\n}\n\nconst char* ZrtpSdesStream::getCipher() {\n    return knownSuites[suite].cipher;\n}\n\nconst char* ZrtpSdesStream::getAuthAlgo() {\n    if (strcmp(knownSuites[suite].tagLength, hs80) == 0)\n        return \"HMAC-SHA1 80 bit\";\n    else\n        return \"HMAC-SHA1 32 bit\";\n}\n\nint ZrtpSdesStream::getCryptoMixAttribute(char *algoNames, size_t length) {\n\n    if (length < MIX_HMAC_STRING_MIN_LEN)\n        return 0;\n\n    // In case we support more than one MIX profile select the correct one if the\n    // application called setCryptoMixAttribute(...) and we already selected the one to use.\n    if (cryptoMixHashType != MIX_NONE) {\n        for (cryptoMix* cp = knownMixAlgos; cp->name != NULL; cp++) {\n            if (cp->hashLength == cryptoMixHashLength && cp->hashType == cryptoMixHashType) {\n                strcpy(algoNames, cp->name);\n                return strlen(cp->name);\n            }\n        }\n    }\n    // TODO: enhance here to support multiple algorithms (concatenate strings into the buffer until buffer full)\n    else {\n        strcpy(algoNames, knownMixAlgos[0].name);\n        return strlen(algoNames);\n    }\n    return 0;\n}\n\nbool ZrtpSdesStream::setCryptoMixAttribute(const char *algoNames) {\n\n    int len = strlen(algoNames);\n    if (len <= 0)\n        return false;\n\n    std::string algoIn(algoNames);\n    algoIn += ' ';\n\n    // split input name string and lookup if we support one of the offered algorithms\n    // We take the first match.\n    std::string delimiters = \" \";\n    size_t current;\n    size_t next = -1;\n\n    do {\n        current = next + 1;\n        next = algoIn.find_first_of(delimiters, current);\n        if (next == std::string::npos)\n            break;\n\n        std::string tmps = algoIn.substr(current, next - current );\n        const char* nm = tmps.c_str();\n\n        for (cryptoMix* cp = knownMixAlgos; cp->name != NULL; cp++) {\n            if (strncmp(cp->name, nm, strlen(cp->name)) == 0) {\n                cryptoMixHashLength = cp->hashLength;\n                cryptoMixHashType = cp->hashType;\n                return true;\n            }\n        }\n    } while (true);\n\n    return false;\n}\n\n#ifdef WEAKRANDOM\n/*\n * A standard random number generator that uses the portable random() system function.\n *\n * This should be enhanced to use a better random generator\n */\nstatic int _random(unsigned char *output, size_t len)\n{\n    size_t i;\n\n    for(i = 0; i < len; ++i )\n        output[i] = random();\n\n    return( 0 );\n}\n#else\n#include <cryptcommon/ZrtpRandom.h>\nstatic int _random(unsigned char *output, size_t len)\n{\n    return ZrtpRandom::getRandomData(output, len);\n}\n#endif\n\nstatic int b64Encode(const uint8_t *binData, int32_t binLength, char *b64Data, int32_t b64Length)\n{\n    base64_encodestate _state;\n    int codelength;\n\n    base64_init_encodestate(&_state, 0);\n    codelength = base64_encode_block(binData, binLength, b64Data, &_state);\n    codelength += base64_encode_blockend(b64Data+codelength, &_state);\n\n    return codelength;\n}\n\nstatic int b64Decode(const char *b64Data, int32_t b64length, uint8_t *binData, int32_t binLength)\n{\n    base64_decodestate _state;\n    int codelength;\n\n    base64_init_decodestate(&_state);\n    codelength = base64_decode_block(b64Data, b64length, binData, &_state);\n    return codelength;\n}\n\nvoid* createSha384HmacContext(uint8_t* key, int32_t keyLength);\nvoid freeSha384HmacContext(void* ctx);\nvoid hmacSha384Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[], uint8_t* mac, int32_t* macLength );\n\nstatic int expand(uint8_t* prk, uint32_t prkLen, uint8_t* info, int32_t infoLen, int32_t L, uint32_t hashLen, uint8_t* outbuffer)\n{\n    int32_t n;\n    uint8_t *T;\n    void* hmacCtx;\n\n    const uint8_t* data[4];      // 3 data pointers for HMAC data plus terminating NULL\n    uint32_t dataLen[4];\n    int32_t dataIdx = 0;\n\n    uint8_t counter;\n    int32_t macLength;\n\n    if (prkLen < hashLen)\n        return -1;\n\n    n = (L + (hashLen-1)) / hashLen;\n\n    // T points to buffer that holds concatenated T(1) || T(2) || ... T(N))\n    T = reinterpret_cast<uint8_t*>(malloc(n * hashLen));\n\n    if (hashLen == 384/8)\n        hmacCtx = createSha384HmacContext(prk, prkLen);\n    else {\n        free(T);\n        return -1;\n    }\n\n    // Prepare first HMAC. T(0) has zero length, thus we ignore it in first run.\n    // After first run use its output (T(1)) as first data in next HMAC run.\n    for (int i = 1; i <= n; i++) {\n        if (infoLen > 0 && info != NULL) {\n            data[dataIdx] = info;\n            dataLen[dataIdx++] = infoLen;\n        }\n        counter = i & 0xff;\n        data[dataIdx] = &counter;\n        dataLen[dataIdx++] = 1;\n\n        data[dataIdx] = NULL;\n        dataLen[dataIdx++] = 0;\n\n        if (hashLen == 384/8)\n            hmacSha384Ctx(hmacCtx, data, dataLen, T + ((i-1) * hashLen), &macLength);\n\n        // Use output of previous hash run as first input of next hash run\n        dataIdx = 0;\n        data[dataIdx] = T + ((i-1) * hashLen);\n        dataLen[dataIdx++] = hashLen;\n    }\n    freeSha384HmacContext(hmacCtx);\n    memcpy(outbuffer, T, L);\n    free(T);\n    return 0;\n}\n\nvoid ZrtpSdesStream::computeMixedKeys(bool sipInvite) {\n    uint8_t salt[MAX_SALT_LEN*2];\n    uint8_t ikm[MAX_KEY_LEN*2];\n\n    // Concatenate the existing salt and key data. Depending on our role we have to change\n    // the order of the data.\n    if (sipInvite) {             // We are offerer, use local created data as mso and mko, so they go first\n        memcpy(salt, &localKeySalt[localKeyLenBytes], localSaltLenBytes);\n        memcpy(&salt[localSaltLenBytes], &remoteKeySalt[remoteKeyLenBytes], remoteSaltLenBytes);\n\n        memcpy(ikm, localKeySalt, localKeyLenBytes);\n        memcpy(&ikm[localKeyLenBytes], remoteKeySalt, remoteKeyLenBytes);\n    }\n    else {\n        memcpy(salt, &remoteKeySalt[remoteKeyLenBytes], remoteSaltLenBytes);\n        memcpy(&salt[remoteSaltLenBytes], &localKeySalt[localKeyLenBytes], localSaltLenBytes);\n\n        memcpy(ikm, remoteKeySalt, remoteKeyLenBytes);\n        memcpy(&ikm[remoteKeyLenBytes], localKeySalt, localKeyLenBytes);\n    }\n    uint32_t saltLen = localSaltLenBytes + remoteSaltLenBytes;\n    uint32_t keyLen = localKeyLenBytes + remoteKeyLenBytes;\n    uint32_t L = saltLen + keyLen;\n\n    uint8_t prk[MAX_DIGEST_LENGTH];\n    uint32_t prkLen;\n\n    switch(cryptoMixHashType) {\n        case MIX_HMAC_SHA:\n            if (cryptoMixHashLength == 384)\n                hmac_sha384(salt, saltLen, ikm, keyLen, prk, &prkLen);\n            else\n                return;\n            break;\n\n        case MIX_MAC_SKEIN:\n            return;\n\n        default:\n            return;\n    }\n\n    uint8_t T[(MAX_SALT_LEN + MAX_KEY_LEN)*2] = {0};\n    expand(prk, prkLen, NULL, 0, L, cryptoMixHashLength/8, T);\n\n    // We have a new set of SRTP key data now, replace the old with the new.\n    int32_t offset = 0;\n    if (sipInvite) {    // We are offerer, replace local created data with mso and mko, remote with msa, mka\n        memcpy(&localKeySalt[localKeyLenBytes], T, localSaltLenBytes);\n        offset += localSaltLenBytes;\n        memcpy(&remoteKeySalt[remoteKeyLenBytes], &T[offset], remoteSaltLenBytes);\n        offset += remoteSaltLenBytes;\n\n        memcpy(localKeySalt, &T[offset], localKeyLenBytes);\n        offset += localKeyLenBytes;\n        memcpy(remoteKeySalt, &T[offset], remoteKeyLenBytes);\n    }\n    else {            // We are answerer, replace remote data with mso and mko, local data with msa, mka\n        memcpy(&remoteKeySalt[remoteKeyLenBytes], T, remoteSaltLenBytes);\n        offset += remoteSaltLenBytes;\n        memcpy(&localKeySalt[localKeyLenBytes], &T[offset], localSaltLenBytes);\n        offset += localSaltLenBytes;\n\n        memcpy(remoteKeySalt, &T[offset], remoteKeyLenBytes);\n        offset += remoteKeyLenBytes;\n        memcpy(localKeySalt, &T[offset], localKeyLenBytes);\n    }\n}\n\nvoid ZrtpSdesStream::createSrtpContexts(bool sipInvite) {\n\n    if (cryptoMixHashType != MIX_NONE) {\n        computeMixedKeys(sipInvite);\n    }\n\n    sendSrtp = new CryptoContext(0,                     // SSRC (used for lookup)\n                                 0,                     // Roll-Over-Counter (ROC)\n                                 0L,                    // keyderivation << 48,\n                                 localCipher,                // encryption algo\n                                 localAuthn,                 // authtentication algo\n                                 localKeySalt,               // Master Key\n                                 localKeyLenBytes,           // Master Key length\n                                 &localKeySalt[localKeyLenBytes], // Master Salt\n                                 localSaltLenBytes,          // Master Salt length\n                                 localKeyLenBytes,           // encryption keylen\n                                 localAuthKeyLen,            // authentication key len (HMAC key lenght)\n                                 localSaltLenBytes,          // session salt len\n                                 localTagLength);            // authentication tag len\n    sendSrtp->deriveSrtpKeys(0L);\n\n    sendZrtpTunnel = new CryptoContext(0,                     // SSRC (used for lookup)\n                                 0,                     // Roll-Over-Counter (ROC)\n                                 0L,                    // keyderivation << 48,\n                                 localCipher,                // encryption algo\n                                 localAuthn,                 // authtentication algo\n                                 localKeySalt,               // Master Key\n                                 localKeyLenBytes,           // Master Key length\n                                 &localKeySalt[localKeyLenBytes], // Master Salt\n                                 localSaltLenBytes,          // Master Salt length\n                                 localKeyLenBytes,           // encryption keylen\n                                 localAuthKeyLen,            // authentication key len (HMAC key lenght)\n                                 localSaltLenBytes,          // session salt len\n                                 ZRTP_TUNNEL_AUTH_LEN);      // authentication tag len\n\n    sendZrtpTunnel->setLabelbase(ZRTP_TUNNEL_LABEL);\n    sendZrtpTunnel->deriveSrtpKeys(0L);\n    memset(localKeySalt, 0, sizeof(localKeySalt));\n\n    recvSrtp = new CryptoContext(0,                     // SSRC (used for lookup)\n                                 0,                     // Roll-Over-Counter (ROC)\n                                 0L,                    // keyderivation << 48,\n                                 remoteCipher,                // encryption algo\n                                 remoteAuthn,                 // authtentication algo\n                                 remoteKeySalt,               // Master Key\n                                 remoteKeyLenBytes,           // Master Key length\n                                 &remoteKeySalt[remoteKeyLenBytes], // Master Salt\n                                 remoteSaltLenBytes,          // Master Salt length\n                                 remoteKeyLenBytes,           // encryption keylen\n                                 remoteAuthKeyLen,            // authentication key len (HMAC key lenght)\n                                 remoteSaltLenBytes,          // session salt len\n                                 remoteTagLength);            // authentication tag len\n    recvSrtp->deriveSrtpKeys(0L);\n\n    recvZrtpTunnel = new CryptoContext(0,                     // SSRC (used for lookup)\n                                 0,                     // Roll-Over-Counter (ROC)\n                                 0L,                    // keyderivation << 48,\n                                 remoteCipher,                // encryption algo\n                                 remoteAuthn,                 // authtentication algo\n                                 remoteKeySalt,               // Master Key\n                                 remoteKeyLenBytes,           // Master Key length\n                                 &remoteKeySalt[remoteKeyLenBytes], // Master Salt\n                                 remoteSaltLenBytes,          // Master Salt length\n                                 remoteKeyLenBytes,           // encryption keylen\n                                 remoteAuthKeyLen,            // authentication key len (HMAC key lenght)\n                                 remoteSaltLenBytes,          // session salt len\n                                 ZRTP_TUNNEL_AUTH_LEN);       // authentication tag len\n\n    recvZrtpTunnel->setLabelbase(ZRTP_TUNNEL_LABEL);\n    recvZrtpTunnel->deriveSrtpKeys(0L);\n    memset(remoteKeySalt, 0, sizeof(remoteKeySalt));\n}\n\nbool ZrtpSdesStream::createSdesProfile(char *cryptoString, size_t *maxLen) {\n\n    char b64keySalt[(MAX_KEY_LEN + MAX_SALT_LEN) * 2] = {'\\0'};\n    uint32_t sidx;\n    int32_t b64Len;\n\n    for (sidx = 0; knownSuites[sidx].name != NULL; sidx++) {  // Lookup crypto suite parameters\n        if (knownSuites[sidx].suite == suite)\n            break;\n    }\n    if (sidx >= sizeof(knownSuites)/sizeof(struct _suite)) {\n        return false;\n    }\n    suiteParam *pSuite = &knownSuites[sidx];\n    _random(localKeySalt, sizeof(localKeySalt));\n\n    AlgorithmEnum& auth = zrtpAuthLengths.getByName(pSuite->tagLength);\n    localAuthn = SrtpAuthenticationSha1Hmac;\n    localAuthKeyLen = pSuite->authKeyLength / 8;\n    localTagLength = auth.getKeylen() / 8;\n\n    // If SDES will support other encryption algos - get it here based on\n    // the algorithm name in suite\n    localCipher = SrtpEncryptionAESCM;\n\n    localKeyLenBytes = pSuite->keyLength / 8;\n    localSaltLenBytes = pSuite->saltLength / 8;\n\n    if (tag == -1)\n        tag = 1;\n\n    // Get B64 code for master key and master salt and then construct the SDES crypto string\n    b64Len = b64Encode(localKeySalt, localKeyLenBytes + localSaltLenBytes, b64keySalt, sizeof(b64keySalt));\n    b64keySalt[b64Len] = '\\0';\n    memset(cryptoString, 0, *maxLen);\n    *maxLen = snprintf(cryptoString, *maxLen-1, \"%d %s inline:%s\", tag, pSuite->name, b64keySalt);\n\n    return true;\n}\n\nbool ZrtpSdesStream::parseCreateSdesProfile(const char *cryptoStr, size_t length, sdesSuites *parsedSuite, int32_t *outTag) {\n    int elements,  i;\n    int charsScanned;\n    int mkiLength = 0;\n    uint32_t sidx;\n\n    char cryptoString[MAX_CRYPT_STRING_LEN+1] = {'\\0'};\n\n    /* Parsed strings */\n    char suiteName[MAX_INNER_LEN]  = {'\\0'};\n    char keyParams[MAX_INNER_LEN]  = {'\\0'};\n    char keySaltB64[MAX_INNER_LEN] = {'\\0'};\n    char lifetime[MAX_INNER_LEN]   = {'\\0'};\n    char mkiVal[MAX_INNER_LEN]     = {'\\0'};\n\n    if (length == 0)\n        length = strlen(cryptoStr);\n\n    if (length > MAX_CRYPT_STRING_LEN) {\n        return false;\n    }\n    memcpy(cryptoString, cryptoStr, length);   // make own copy, null terminated\n\n    *outTag = -1;\n    elements = sscanf(cryptoString, parseCrypto, outTag, suiteName, keyParams, &charsScanned);\n\n    if (elements < minElementsCrypto) {        // Do we have enough elements in the string\n        return false;\n    }\n\n    for (sidx = 0; knownSuites[sidx].name != NULL; sidx++) {  // Lookup crypto suite\n        if (!strcmp(knownSuites[sidx].name, suiteName))\n            break;\n    }\n    if (sidx >= sizeof(knownSuites)/sizeof(struct _suite)) {\n        return false;\n    }\n    suiteParam *pSuite = &knownSuites[sidx];\n    *parsedSuite = pSuite->suite;\n\n    /* Now scan the key parameters */\n    elements = sscanf(keyParams, parseKeyParam, keySaltB64, lifetime, mkiVal, &mkiLength);\n\n    if (elements != minElementsKeyParam) {     // Currently we only accept key||salt B64 string, no other parameters \n        return false;\n    }\n\n    remoteKeyLenBytes = pSuite->keyLength / 8;\n    remoteSaltLenBytes = pSuite->saltLength / 8;\n\n    if (strlen(keySaltB64) != pSuite->b64length) {  // Check if key||salt B64 string hast the correct length\n        return false;\n    }\n    i = b64Decode(keySaltB64, pSuite->b64length, remoteKeySalt, remoteKeyLenBytes + remoteSaltLenBytes);\n\n    if (i != (remoteKeyLenBytes + remoteSaltLenBytes)) {  // Did the B64 decode delivered enough data for key||salt\n        return false;\n    }\n\n    AlgorithmEnum& auth = zrtpAuthLengths.getByName(pSuite->tagLength);\n    remoteAuthn = SrtpAuthenticationSha1Hmac;\n    remoteAuthKeyLen = pSuite->authKeyLength / 8;\n    remoteTagLength = auth.getKeylen() / 8;\n\n    // If SDES will support other encryption algos - get it here based on\n    // the algorithm name in suite\n    remoteCipher = SrtpEncryptionAESCM;\n\n    return true;\n}"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpStateClass.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/**\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <iostream>\n#include <cstdlib>\n#include <ctype.h>\n\n#include <libzrtpcpp/ZRtp.h>\n#include <libzrtpcpp/ZrtpStateClass.h>\n\nusing namespace std;\nusing namespace GnuZrtpCodes;\n\nstate_t states[numberOfStates] = {\n    {Initial,      &ZrtpStateClass::evInitial },\n    {Detect,       &ZrtpStateClass::evDetect },\n    {AckDetected,  &ZrtpStateClass::evAckDetected },\n    {AckSent,      &ZrtpStateClass::evAckSent },\n    {WaitCommit,   &ZrtpStateClass::evWaitCommit },\n    {CommitSent,   &ZrtpStateClass::evCommitSent },\n    {WaitDHPart2,  &ZrtpStateClass::evWaitDHPart2 },\n    {WaitConfirm1, &ZrtpStateClass::evWaitConfirm1 },\n    {WaitConfirm2, &ZrtpStateClass::evWaitConfirm2 },\n    {WaitConfAck,  &ZrtpStateClass::evWaitConfAck },\n    {WaitClearAck, &ZrtpStateClass::evWaitClearAck },\n    {SecureState,  &ZrtpStateClass::evSecureState },\n    {WaitErrorAck, &ZrtpStateClass::evWaitErrorAck }\n};\n\n\nZrtpStateClass::ZrtpStateClass(ZRtp *p) : parent(p), commitPkt(NULL), t1Resend(20), t1ResendExtend(60), t2Resend(10),\n                                          multiStream(false), secSubstate(Normal), sentVersion(0) {\n\n    engine = new ZrtpStates(states, numberOfStates, Initial);\n    memset(retryCounters, 0, sizeof(retryCounters));\n\n    // Set up timers according to ZRTP spec\n    T1.start = 50;\n    T1.maxResend = t1Resend;\n    T1.capping = 800;\n\n    T2.start = 150;\n    T2.maxResend = t2Resend;\n    T2.capping = 1200;\n}\n\nZrtpStateClass::~ZrtpStateClass(void) {\n\n    // If not in Initial state: close the protocol engine\n    // before destroying it. This will free pending packets\n    // if necessary.\n    if (!inState(Initial)) {\n        Event_t ev;\n\n        cancelTimer();\n        ev.type = ZrtpClose;\n        event = &ev;\n        engine->processEvent(*this);\n    }\n    delete engine;\n}\n\nvoid ZrtpStateClass::processEvent(Event_t *ev) {\n\n    char *msg, first, middle, last;\n    uint8_t *pkt;\n\n    parent->synchEnter();\n\n    event = ev;\n    if (event->type == ZrtpPacket) {\n        pkt = event->packet;\n        msg = (char *)pkt + 4;\n        first = tolower(*msg);\n        middle = tolower(*(msg+4));\n        last = tolower(*(msg+7));\n\n        // Sanity check of packet size for all states except WaitErrorAck.\n        if (!inState(WaitErrorAck)) {\n            uint16_t totalLength = *(uint16_t*)(pkt+2);\n            totalLength = zrtpNtohs(totalLength) * ZRTP_WORD_SIZE;\n            totalLength += 12 + sizeof(uint32_t);           // 12 bytes is fixed header, uint32_t is CRC\n\n            if (totalLength != ev->length) {\n                fprintf(stderr, \"Total length does not match received length: %d - %ld\\n\", totalLength, (long int)(ev->length & 0xffff));\n                sendErrorPacket(MalformedPacket);\n                parent->synchLeave();\n                return;\n            }\n        }\n\n        // Check if this is an Error packet.\n        if (first == 'e' && middle =='r' && last == ' ') {\n            /*\n             * Process a received Error packet.\n             *\n             * In any case stop timer to prevent resending packets.\n             * Use callback method to prepare and get an ErrorAck packet.\n             * Modify event type to \"ErrorPkt\" and hand it over to current\n             * state for further processing.\n             */\n            cancelTimer();\n            ZrtpPacketError epkt(pkt);\n            ZrtpPacketErrorAck* eapkt = parent->prepareErrorAck(&epkt);\n            parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(eapkt));\n            event->type = ErrorPkt;\n        }\n        else if (first == 'p' && middle == ' ' && last == ' ') {\n            ZrtpPacketPing ppkt(pkt);\n            ZrtpPacketPingAck* ppktAck = parent->preparePingAck(&ppkt);\n            if (ppktAck != NULL) {          // ACK only to valid PING packet, otherwise ignore it\n                parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(ppktAck));\n            }\n            parent->synchLeave();\n            return;\n        }\n        else if (first == 's' && last == 'y') {\n            uint32_t errorCode = 0;\n            ZrtpPacketSASrelay* srly = new ZrtpPacketSASrelay(pkt);\n            ZrtpPacketRelayAck* rapkt = parent->prepareRelayAck(srly, &errorCode);\n            parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(rapkt));\n            parent->synchLeave();\n            return;\n        }\n    }\n    /*\n     * Shut down protocol state engine: cancel outstanding timer, further\n     * processing in current state.\n     */\n    else if (event->type == ZrtpClose) {\n        cancelTimer();\n    }\n    engine->processEvent(*this);\n    parent->synchLeave();\n}\n\n\nvoid ZrtpStateClass::evInitial(void) {\n    DEBUGOUT((cout << \"Checking for match in Initial.\\n\"));\n\n    if (event->type == ZrtpInitial) {\n        ZrtpPacketHello* hello = parent->prepareHello();\n        sentVersion = hello->getVersionInt();\n\n        // remember packet for easy resend in case timer triggers\n        sentPacket = static_cast<ZrtpPacketBase *>(hello);\n\n        if (!parent->sendPacketZRTP(sentPacket)) {\n            sendFailed();                 // returns to state Initial\n            return;\n        }\n        if (startTimer(&T1) <= 0) {\n            timerFailed(SevereNoTimer);      // returns to state Initial\n            return;\n        }\n        nextState(Detect);\n    }\n}\n\n/*\n * Detect state.\n *\n * When in this state the protocol engine sent an initial Hello packet\n * to the peer.\n *\n * When entering this state transition function then:\n * - Assume Initiator mode, mode may change later on peer reaction\n * - Instance variable sentPacket contains the sent Hello packet\n * - Hello timer T1 may be active. This is the case if the other peer\n *   has prepared its RTP session and answers our Hello packets nearly \n *   immediately, i.e. before the Hello timeout counter expires. If the\n *   other peer does not send a Hello during this time the state engine\n *   reports \"other peer does not support ZRTP\" but stays\n *   in state Detect with no active timer (passiv mode). Staying in state \n *   Detect allows another peer to start its detect phase any time later.\n *\n *   This restart capability is the reason why we use \"startTimer(&T1)\" in \n *   case we received a Hello packet from another peer. This effectively \n *   restarts the Hello timeout counter.\n *\n *   In this state we also handle ZrtpInitialize event. This forces a\n *   restart of ZRTP discovery if an application calls ZrtpQueue#startZrtp\n *   again. This may happen after a previous discovery phase were not \n *   successful.\n *\n *   Usually applications use some sort of signaling protocol, for example\n *   SIP, to negotiate the RTP parameters. Thus the RTP sessions setup is\n *   fairly sychronized and thus also the ZRTP detection phase. Applications\n *   that use some other ways to setup the RTP sessions this restart capability\n *   comes in handy because no RTP setup sychronization is necessary.\n * \n * Possible events in this state are:\n * - timeout for sent Hello packet: causes a resend check and \n *   repeat sending of Hello packet\n * - received a HelloAck: stop active timer, prepare and send Hello packet,\n *   switch to state AckDeteced.\n * - received a Hello: stop active timer, send HelloAck, prepare Commit \n *   packet, switch to state AckSent.\n *\n */\nvoid ZrtpStateClass::evDetect(void) {\n\n    DEBUGOUT((cout << \"Checking for match in Detect.\\n\"));\n\n    char *msg, first, last;\n    uint8_t *pkt;\n    uint32_t errorCode = 0;\n\n    /*\n     * First check the general event type, then discrimnate\n     * the real event.\n     */\n    if (event->type == ZrtpPacket) {\n        pkt = event->packet;\n        msg = (char *)pkt + 4;\n\n        first = tolower(*msg);\n        last = tolower(*(msg+7));\n        /*\n         * HelloAck:\n         * - our peer acknowledged our Hello packet, we have not seen the peer's Hello yet\n         * - cancel timer T1 to stop resending Hello\n         * - switch to state AckDetected, wait for peer's Hello (F3)\n         * \n         * When we receive an HelloAck this also means that our partner accepted our protocol version.\n         */\n        if (first == 'h' && last =='k') {\n            cancelTimer();\n            sentPacket = NULL;\n            nextState(AckDetected);\n            return;\n        }\n        /*\n         * Hello:\n         * - send HelloAck packet to acknowledge the received Hello packet if versions match.\n         *   Otherweise negotiate ZRTP versions.\n         * - use received Hello packet to prepare own Commit packet. We need to\n         *   do it at this point because we need the hash value computed from\n         *   peer's Hello packet. Follwing states my use the prepared Commit.\n         * - switch to new state AckSent which sends own Hello packet until \n         *   peer acknowledges this\n         * - Don't clear sentPacket, points to Hello\n         */\n        if (first == 'h' && last ==' ') {\n            ZrtpPacketHello hpkt(pkt);\n\n            cancelTimer();\n\n            /*\n             * Check and negotiate the ZRTP protocol version first.\n             *\n             * This selection mechanism relies on the fact that we sent the highest supported protocol version in\n             * the initial Hello packet with as stated in RFC6189, section 4.1.1\n             */\n            int32_t recvVersion = hpkt.getVersionInt();\n            if (recvVersion > sentVersion) {   // We don't support this version, stay in state with timer active\n                if (startTimer(&T1) <= 0) {\n                    timerFailed(SevereNoTimer);      // returns to state Initial\n                }\n                return;\n            }\n\n            /*\n             * The versions don't match. Start negotiating versions. This negotiation stays in the Detect state.\n             * Only if the received version matches our own sent version we start to send a HelloAck.\n             */\n            if (recvVersion != sentVersion) {\n                ZRtp::HelloPacketVersion* hpv = parent->helloPackets;\n\n                int32_t index;\n                for (index = 0; hpv->packet && hpv->packet != parent->currentHelloPacket; hpv++, index++)   // Find current sent Hello\n                    ;\n\n                for(; index >= 0 && hpv->version > recvVersion; hpv--, index--)   // find a supported version less-equal to received version\n                    ;\n\n                if (index < 0) {\n                    sendErrorPacket(UnsuppZRTPVersion);\n                    return;\n                }\n                parent->currentHelloPacket = hpv->packet;\n                sentVersion = parent->currentHelloPacket->getVersionInt();\n\n                // remember packet for easy resend in case timer triggers\n                sentPacket = static_cast<ZrtpPacketBase *>(parent->currentHelloPacket);\n\n                if (!parent->sendPacketZRTP(sentPacket)) {\n                    sendFailed();                 // returns to state Initial\n                    return;\n                }\n                if (startTimer(&T1) <= 0) {\n                    timerFailed(SevereNoTimer);      // returns to state Initial\n                    return;\n                }\n                return;\n            }\n            ZrtpPacketHelloAck* helloAck = parent->prepareHelloAck();\n\n            if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(helloAck))) {\n                parent->zrtpNegotiationFailed(Severe, SevereCannotSend);\n                return;\n            }\n            // Use peer's Hello packet to create my commit packet, store it \n            // for possible later usage in state AckSent\n            commitPkt = parent->prepareCommit(&hpkt, &errorCode);\n\n            nextState(AckSent);\n            if (commitPkt == NULL) {\n                sendErrorPacket(errorCode);    // switches to Error state\n                return;\n            }\n            if (startTimer(&T1) <= 0) {        // restart own Hello timer/counter\n                timerFailed(SevereNoTimer);    // returns to state Initial\n            }\n            T1.maxResend = t1ResendExtend;     // more retries to extend time, see chap. 6\n        }\n        return;      // unknown packet for this state - Just ignore it\n    }\n    // Timer event triggered - this is Timer T1 to resend Hello\n    else if (event->type == Timer) {\n        if (!parent->sendPacketZRTP(sentPacket)) {\n            sendFailed();       // returns to state Initial\n            return;\n        }\n        retryCounters[HelloRetry]++;\n\n        if (nextTimer(&T1) <= 0) {\n            commitPkt = NULL;\n            parent->zrtpNotSuppOther();\n            nextState(Detect);\n        }\n    }\n    // If application calls zrtpStart() to restart discovery\n    else if (event->type == ZrtpInitial) {\n        cancelTimer();\n        if (!parent->sendPacketZRTP(sentPacket)) {\n            sendFailed();                 // returns to state Initial\n            return;\n        }\n        if (startTimer(&T1) <= 0) {\n            timerFailed(SevereNoTimer);   // returns to state Initial\n        }\n    }\n    else { // unknown Event type for this state (covers Error and ZrtpClose)\n        if (event->type != ZrtpClose) {\n            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);\n        }\n        sentPacket = NULL;\n        nextState(Initial);\n    }\n}\n\n/*\n * AckSent state.\n *\n * The protocol engine got a Hello packet from peer and answered with a\n * HelloAck response.  According to the protocol we must also send a \n * Hello after HelloAck (refer to figure 1 in ZRTP RFC 6189, message\n * HelloACK (F2) must be followed by Hello (F3)). We use the timeout in \n * this state to send the required Hello (F3).\n *\n * Our peer must acknowledge the Hello with HelloAck. In earlier versions \n * also a Commit was a valid packet thus the code covers this.\n * Figure 1 in the RFC shows the HelloAck, chapter 7 states that a Commit \n * may be send to acknowledge Hello. There is one constraint when using a Commit to\n * acknowledge Hello: refer to chapter 4.1 that requires that both parties\n * have completed the Hello/HelloAck discovery handshake. This implies that \n * only message F4 may be replaced by a Commit. This constraint guarantees\n * that both peers have seen at least one Hello.\n *\n * When entering this transition function:\n * - The instance variabe sentPacket contains own Hello packet\n * - The instance variabe commitPkt points to prepared Commit packet \n * - Timer T1 is active\n *\n * Possible events in this state are:\n * - timeout for sent Hello packet: causes a resend check and repeat sending\n *   of Hello packet\n * - HelloAck: The peer answered with HelloAck to own HelloAck/Hello. Send\n *   prepared Commit packet and try Initiator mode.\n * - Commit: The peer answered with Commit to HelloAck/Hello, thus switch to\n *   responder mode.\n * - Hello: If the protcol engine receives another Hello it repeats the \n *   HelloAck/Hello response until Timer T1 exceeds its maximum. This may \n *   happen if the other peer sends Hello only (maybe due to network problems)\n */\nvoid ZrtpStateClass::evAckSent(void) {\n\n    DEBUGOUT((cout << \"Checking for match in AckSent.\\n\"));\n\n    char *msg, first, last;\n    uint8_t *pkt;\n    uint32_t errorCode = 0;\n\n    /*\n     * First check the general event type, then discrimnate\n     * the real event.\n     */\n    if (event->type == ZrtpPacket) {\n        pkt = event->packet;\n        msg = (char *)pkt + 4;\n\n        first = tolower(*msg);\n        last = tolower(*(msg+7));\n\n        /*\n         * HelloAck:\n         * The peer answers with HelloAck to own HelloAck/Hello. Send Commit\n         * and try Initiator mode. The requirement defined in chapter 4.1 to\n         * have a complete Hello/HelloAck is fulfilled.\n         * - stop Hello timer T1\n         * - send own Commit message\n         * - switch state to CommitSent, start Commit timer, assume Initiator\n         */\n        if (first == 'h' && last =='k') {\n            cancelTimer();\n\n            // remember packet for easy resend in case timer triggers\n            // Timer trigger received in new state CommitSend\n            sentPacket = static_cast<ZrtpPacketBase *>(commitPkt);\n            commitPkt = NULL;                    // now stored in sentPacket\n            nextState(CommitSent);\n            if (!parent->sendPacketZRTP(sentPacket)) {\n                sendFailed();             // returns to state Initial\n                return;\n            }\n            if (startTimer(&T2) <= 0) {\n                timerFailed(SevereNoTimer);  // returns to state Initial\n            }\n            return;\n        }\n        /*\n         * Hello:\n         * - peer didn't receive our HelloAck\n         * - repeat HelloAck/Hello response:\n         *  -- get HelloAck packet, send it\n         *  -- The timeout trigger of T1 sends our Hello packet\n         *  -- stay in state AckSent\n         *\n         * Similar to Detect state: just acknowledge the Hello, the next\n         * timeout sends the following Hello.\n         */\n\n        if (first == 'h' && last ==' ') {\n            ZrtpPacketHelloAck* helloAck = parent->prepareHelloAck();\n\n            if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(helloAck))) {\n                nextState(Detect);\n                parent->zrtpNegotiationFailed(Severe, SevereCannotSend);\n            }\n            return;\n        }\n        /*\n         * Commit:\n         * The peer answers with Commit to HelloAck/Hello, thus switch to\n         * responder mode.\n         * - stop timer T1\n         * - prepare and send our DHPart1\n         * - switch to state WaitDHPart2 and wait for peer's DHPart2\n         * - don't start timer, we are responder\n         */\n        if (first == 'c' && last == ' ') {\n            cancelTimer();\n            ZrtpPacketCommit cpkt(pkt);\n\n            if (!multiStream) {\n                ZrtpPacketDHPart* dhPart1 = parent->prepareDHPart1(&cpkt, &errorCode);\n\n                // Something went wrong during processing of the Commit packet\n                if (dhPart1 == NULL) {\n                    if (errorCode != IgnorePacket) {\n                        sendErrorPacket(errorCode);\n                    }\n                    return;\n                }\n                commitPkt = NULL;\n                sentPacket = static_cast<ZrtpPacketBase *>(dhPart1);\n                nextState(WaitDHPart2);\n            }\n            else {\n                ZrtpPacketConfirm* confirm = parent->prepareConfirm1MultiStream(&cpkt, &errorCode);\n\n                // Something went wrong during processing of the Commit packet\n                if (confirm == NULL) {\n                    if (errorCode != IgnorePacket) {\n                        sendErrorPacket(errorCode);\n                    }\n                    return;\n                }\n                sentPacket = static_cast<ZrtpPacketBase *>(confirm);\n                nextState(WaitConfirm2);\n            }\n            if (!parent->sendPacketZRTP(sentPacket)) {\n                sendFailed();      // returns to state Initial\n            }\n        }\n    }\n    /*\n     * Timer:\n     * - resend Hello packet, stay in state, restart timer until repeat\n     *   counter triggers\n     * - if repeat counter triggers switch to state Detect, con't clear\n     *   sentPacket, Detect requires it to point to own Hello message\n     */\n    else if (event->type == Timer) {\n        if (!parent->sendPacketZRTP(sentPacket)) {\n            return sendFailed();      // returns to state Initial\n        }\n        retryCounters[HelloRetryAck]++;\n\n        if (nextTimer(&T1) <= 0) {\n            parent->zrtpNotSuppOther();\n            commitPkt = NULL;\n            // Stay in state Detect to be prepared get an hello from\n            // other peer any time later\n            nextState(Detect);\n        }\n    }\n    else {   // unknown Event type for this state (covers Error and ZrtpClose)\n        if (event->type != ZrtpClose) {\n            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);\n        }\n        commitPkt = NULL;\n        sentPacket = NULL;\n        nextState(Initial);\n    }\n}\n/*\n * AckDetected state.\n *\n * The protocol engine received a HelloAck in state Detect, thus the peer \n * acknowledged our the Hello. According to ZRT RFC 6189 our peer must send\n * its Hello until our protocol engine sees it (refer also to comment for\n * state AckSent). This protocol sequence gurantees that both peers got at\n * least one Hello. \n *\n * When entering this transition function\n * - instance variable sentPacket is NULL, Hello timer stopped\n *\n * Possible events in this state are:\n * Hello: we have to choices\n *  1) we can acknowledge the peer's Hello with a HelloAck\n *  2) we can acknowledge the peer's Hello with a Commit\n *  Both choices are implemented and may be enabled by setting a compile\n *  time #if (see code below). Currently we use choice 1) here because\n *  it's more aligned to the ZRTP specification\n */\nvoid ZrtpStateClass::evAckDetected(void) {\n\n    DEBUGOUT((cout << \"Checking for match in AckDetected.\\n\"));\n\n    char *msg, first, last;\n    uint8_t *pkt;\n    uint32_t errorCode = 0;\n\n    if (event->type == ZrtpPacket) {\n        pkt = event->packet;\n        msg = (char *)pkt + 4;\n\n        first = tolower(*msg);\n        last = tolower(*(msg+7));\n\n#if 1\n        /*\n         * Implementation for choice 1)\n         * Hello:\n         * - Acknowledge peer's Hello, sending HelloACK (F4)\n         * - switch to state WaitCommit, wait for peer's Commit\n         * - we are going to be in the Responder role\n         */\n\n        if (first == 'h' && last ==' ') {\n            // Parse Hello packet and build an own Commit packet even if the\n            // Commit is not send to the peer. We need to do this to check the\n            // Hello packet and prepare the shared secret stuff.\n            ZrtpPacketHello hpkt(pkt);\n            ZrtpPacketCommit* commit = parent->prepareCommit(&hpkt, &errorCode);\n\n            // Something went wrong during processing of the Hello packet, for\n            // example wrong version, duplicate ZID.\n            if (commit == NULL) {\n                sendErrorPacket(errorCode);\n                return;\n            }\n            ZrtpPacketHelloAck *helloAck = parent->prepareHelloAck();\n            nextState(WaitCommit);\n\n            // remember packet for easy resend\n            sentPacket = static_cast<ZrtpPacketBase *>(helloAck);\n            if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(helloAck))) {\n                sendFailed();\n            }\n        }\n#else\n        /*\n         * Implementation for choice 2)\n         * Hello:\n         * - Acknowledge peer's Hello by sending Commit (F5)\n         *   instead of HelloAck (F4)\n         * - switch to state CommitSent\n         * - Initiator role, thus start timer T2 to monitor timeout for Commit\n         */\n\n        if (first == 'h' && last == ' ') {\n            // Parse peer's packet data into a Hello packet\n            ZrtpPacketHello hpkt(pkt);\n            ZrtpPacketCommit* commit = parent->prepareCommit(&hpkt, &errorCode);\n            // Something went wrong during processing of the Hello packet  \n            if (commit == NULL) {\n                sendErrorPacket(errorCode);\n                return;\n            }\n            nextState(CommitSent);\n\n            // remember packet for easy resend in case timer triggers\n            // Timer trigger received in new state CommitSend\n            sentPacket = static_cast<ZrtpPacketBase *>(commit);\n            if (!parent->sendPacketZRTP(sentPacket)) {\n                sendFailed();\n                return;\n            }\n            if (startTimer(&T2) <= 0) {\n                timerFailed(SevereNoTimer);\n            }\n        }\n#endif\n    }\n    else {  // unknown Event type for this state (covers Error and ZrtpClose)\n        if (event->type != ZrtpClose) {\n            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);\n        }\n        nextState(Initial);\n    }\n}\n\n/*\n * WaitCommit state.\n *\n * This state is only used if we use choice 1) in AckDetected.\n *\n * When entering this transition function\n * - instance variable sentPacket contains a HelloAck packet\n * \n * Possible events in this state are:\n * - Hello: just resend our HelloAck\n * - Commit: prepare and send our DHPart1 message to start first\n *   half of DH key agreement. Switch to state WaitDHPart2, don't\n *   start any timer, we a Responder.\n */\nvoid ZrtpStateClass::evWaitCommit(void) {\n\n    DEBUGOUT((cout << \"Checking for match in WaitCommit.\\n\"));\n\n    char *msg, first, last;\n    uint8_t *pkt;\n    uint32_t errorCode = 0;\n\n    if (event->type == ZrtpPacket) {\n        pkt = event->packet;\n        msg = (char *)pkt + 4;\n\n        first = tolower(*msg);\n        last = tolower(*(msg+7));\n        /*\n         * Hello:\n         * - resend HelloAck\n         * - stay in WaitCommit\n         */\n        if (first == 'h' && last == ' ') {\n            if (!parent->sendPacketZRTP(sentPacket)) {\n                sendFailed();       // returns to state Initial\n            }\n            return;\n        }\n        /*\n         * Commit:\n         * - prepare DH1Part packet or Confirm1 if multi stream mode\n         * - send it to peer\n         * - switch state to WaitDHPart2 or WaitConfirm2 if multi stream mode\n         * - don't start timer, we are responder\n         */\n        if (first == 'c' && last == ' ') {\n            ZrtpPacketCommit cpkt(pkt);\n\n            if (!multiStream) {\n                ZrtpPacketDHPart* dhPart1 = parent->prepareDHPart1(&cpkt, &errorCode);\n\n                // Something went wrong during processing of the Commit packet\n                if (dhPart1 == NULL) {\n                    if (errorCode != IgnorePacket) {\n                        sendErrorPacket(errorCode);\n                    }\n                    return;\n                }\n                sentPacket = static_cast<ZrtpPacketBase *>(dhPart1);\n                nextState(WaitDHPart2);\n            }\n            else {\n                ZrtpPacketConfirm* confirm = parent->prepareConfirm1MultiStream(&cpkt, &errorCode);\n\n                // Something went wrong during processing of the Commit packet\n                if (confirm == NULL) {\n                    if (errorCode != IgnorePacket) {\n                        sendErrorPacket(errorCode);\n                    }\n                    return;\n                }\n                sentPacket = static_cast<ZrtpPacketBase *>(confirm);\n                nextState(WaitConfirm2);\n            }\n            if (!parent->sendPacketZRTP(sentPacket)) {\n                sendFailed();       // returns to state Initial\n            }\n        }\n    }\n    else {  // unknown Event type for this state (covers Error and ZrtpClose)\n        if (event->type != ZrtpClose) {\n            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);\n        }\n        sentPacket = NULL;\n        nextState(Initial);\n    }\n}\n\n/*\n * CommitSent state.\n *\n * This state either handles a DH1Part1 message to start the first\n * half of DH key agreement or it handles a Commit clash. If handling a\n * Commit clash it may happen that we change our role from Initiator to\n * Responder.\n *\n * When entering this transition function\n * - assume Initiator mode, may change if we reveice a Commit here\n * - sentPacket contains Commit packet\n * - Commit timer (T2) active\n *\n * Possible events in this state are:\n * - timeout for sent Commit packet: causes a resend check and repeat sending\n *   of Commit packet\n * - Commit: This is a Commit clash. Break the tie accroding to chapter 5.2\n * - DHPart1: start first half of DH key agreement. Perpare and send own DHPart2\n *   and switch to state WaitConfirm1.\n */\n\nvoid ZrtpStateClass::evCommitSent(void) {\n\n    DEBUGOUT((cout << \"Checking for match in CommitSend.\\n\"));\n\n    char *msg, first, middle, last, secondLast;\n    uint8_t *pkt;\n    uint32_t errorCode = 0;\n\n    if (event->type == ZrtpPacket) {\n        pkt = event->packet;\n        msg = (char *)pkt + 4;\n\n        first = tolower(*msg);\n        middle = tolower(*(msg+4));\n        last = tolower(*(msg+7));\n        secondLast = tolower(*(msg+6));\n\n        /*\n         * HelloAck or Hello:\n         * - delayed \"HelloAck\" or \"Hello\", maybe due to network latency, just \n         *   ignore it\n         * - no switch in state, leave timer as it is\n         */\n        if (first == 'h' && middle == 'o' && (last =='k' || last == ' ')) {\n            return;\n        }\n\n        /*\n         * Commit:\n         * We have a \"Commit\" clash. Resolve it.\n         *\n         * - switch off resending Commit\n         * - compare my hvi with peer's hvi\n         * - if my hvi is greater\n         *   - we are Initiator, stay in state, wait for peer's DHPart1 packet\n         * - else\n         *   - we are Responder, stop timer\n         *   - prepare and send DH1Packt,\n         *   - switch to state WaitDHPart2, implies Responder path\n         */\n        if (first == 'c' && last == ' ') {\n            ZrtpPacketCommit zpCo(pkt);\n\n            if (!parent->verifyH2(&zpCo)) {\n                return;\n            }\n            cancelTimer();         // this cancels the Commit timer T2\n\n            if (!zpCo.isLengthOk(multiStream ? ZrtpPacketCommit::MultiStream : ZrtpPacketCommit::DhExchange)) {\n                sendErrorPacket(CriticalSWError);\n                return;\n            }\n\n            // if our hvi is less than peer's hvi: switch to Responder mode and\n            // send DHPart1 or Confirm1 packet. Peer (as Initiator) will retrigger if\n            // necessary\n            //\n            if (parent->compareCommit(&zpCo) < 0) {\n                if (!multiStream) {\n                    ZrtpPacketDHPart* dhPart1 = parent->prepareDHPart1(&zpCo, &errorCode);\n\n                    // Something went wrong during processing of the Commit packet\n                    if (dhPart1 == NULL) {\n                        if (errorCode != IgnorePacket) {\n                            sendErrorPacket(errorCode);\n                        }\n                        return;\n                    }\n                    nextState(WaitDHPart2);\n                    sentPacket = static_cast<ZrtpPacketBase *>(dhPart1);\n                }\n                else {\n                    ZrtpPacketConfirm* confirm = parent->prepareConfirm1MultiStream(&zpCo, &errorCode);\n\n                    // Something went wrong during processing of the Commit packet\n                    if (confirm == NULL) {\n                        if (errorCode != IgnorePacket) {\n                            sendErrorPacket(errorCode);\n                        }\n                        return;\n                    }\n                    nextState(WaitConfirm2);\n                    sentPacket = static_cast<ZrtpPacketBase *>(confirm);\n                }\n                if (!parent->sendPacketZRTP(sentPacket)) {\n                    sendFailed();       // returns to state Initial\n                }\n            }\n            // Stay in state, we are Initiator, wait for DHPart1 of Confirm1 packet from peer.\n            // Resend Commit after timeout until we get a DHPart1 or Confirm1\n            else {\n                if (startTimer(&T2) <= 0) { // restart the Commit timer, gives peer more time to react\n                    timerFailed(SevereNoTimer);    // returns to state Initial\n                }\n            }\n            return;\n        }\n\n        /*\n         * DHPart1:\n         * - switch off resending Commit\n         * - Prepare and send DHPart2\n         * - switch to WaitConfirm1\n         * - start timer to resend DHPart2 if necessary, we are Initiator\n         */\n        if (first == 'd' && secondLast == '1') {\n            cancelTimer();\n            sentPacket = NULL;\n            ZrtpPacketDHPart dpkt(pkt);\n            ZrtpPacketDHPart* dhPart2 = parent->prepareDHPart2(&dpkt, &errorCode);\n\n            // Something went wrong during processing of the DHPart1 packet\n            if (dhPart2 == NULL) {\n                if (errorCode != IgnorePacket) {\n                    sendErrorPacket(errorCode);\n                }\n                else {\n                    if (startTimer(&T2) <= 0) {\n                        timerFailed(SevereNoTimer);       // switches to state Initial\n                    }\n                }\n\n                return;\n            }\n            sentPacket = static_cast<ZrtpPacketBase *>(dhPart2);\n            nextState(WaitConfirm1);\n\n            if (!parent->sendPacketZRTP(sentPacket)) {\n                sendFailed();       // returns to state Initial\n                return;\n            }\n            if (startTimer(&T2) <= 0) {\n                timerFailed(SevereNoTimer);       // switches to state Initial\n            }\n            return;\n        }\n\n        /*\n         * Confirm1 and multi-stream mode\n         * - switch off resending commit\n         * - prepare Confirm2\n         */\n        if (multiStream && (first == 'c' && last == '1')) {\n            cancelTimer();\n            ZrtpPacketConfirm cpkt(pkt);\n\n            ZrtpPacketConfirm* confirm = parent->prepareConfirm2MultiStream(&cpkt, &errorCode);\n\n            // Something went wrong during processing of the Confirm1 packet\n            if (confirm == NULL) {\n                sendErrorPacket(errorCode);\n                return;\n            }\n            nextState(WaitConfAck);\n            sentPacket = static_cast<ZrtpPacketBase *>(confirm);\n\n            if (!parent->sendPacketZRTP(sentPacket)) {\n                sendFailed();         // returns to state Initial\n                return;\n            }\n            if (startTimer(&T2) <= 0) {\n                timerFailed(SevereNoTimer);  // returns to state Initial\n                return;\n            }\n            // according to chap 5.6: after sending Confirm2 the Initiator must\n            // be ready to receive SRTP data. SRTP sender will be enabled in WaitConfAck\n            // state.\n            if (!parent->srtpSecretsReady(ForReceiver)) {\n                parent->sendInfo(Severe, CriticalSWError);\n                sendErrorPacket(CriticalSWError);\n                return;\n            }\n        }\n    }\n    // Timer event triggered, resend the Commit packet\n    else if (event->type == Timer) {\n        if (!parent->sendPacketZRTP(sentPacket)) {\n                sendFailed();       // returns to state Initial\n                return;\n        }\n        retryCounters[CommitRetry]++;\n\n        if (nextTimer(&T2) <= 0) {\n            timerFailed(SevereTooMuchRetries);       // returns to state Initial\n        }\n    }\n    else {  // unknown Event type for this state (covers Error and ZrtpClose)\n        if (event->type != ZrtpClose) {\n            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);\n        }\n        sentPacket = NULL;\n        nextState(Initial);\n    }\n}\n\n/*\n * WaitDHPart2 state.\n *\n * This state handles the second part of SH key agreement. Only the Resonder\n * can enter this state.\n *\n * When entering this transition function\n * - sentPacket contains DHPart1 packet, no timer active\n *\n * Possible events in this state are:\n * - Commit: Our peer didn't receive out DHPart1 thus the peer sends Commit again.\n *   Just repeat our DHPart1.\n * - DHPart2: start second half of DH key agreement. Perpare and send own Confirm1\n *   and switch to state WaitConfirm2.\n */\nvoid ZrtpStateClass::evWaitDHPart2(void) {\n\n    DEBUGOUT((cout << \"Checking for match in DHPart2.\\n\"));\n\n    char *msg, first, secondLast, last;\n    uint8_t *pkt;\n    uint32_t errorCode = 0;\n\n    if (event->type == ZrtpPacket) {\n        pkt = event->packet;\n        msg = (char *)pkt + 4;\n\n        first = tolower(*msg);\n        last = tolower(*(msg+7));\n        secondLast = tolower(*(msg+6));\n        /*\n         * Commit:\n         * - resend DHPart1\n         * - stay in state\n         */\n        if (first == 'c' && last == ' ') {\n            if (!parent->sendPacketZRTP(sentPacket)) {\n                return sendFailed();       // returns to state Initial\n            }\n            return;\n        }\n        /*\n         * DHPart2:\n         * - prepare Confirm1 packet\n         * - switch to WaitConfirm2\n         * - No timer, we are responder\n         */\n        if (first == 'd' && secondLast == '2') {\n            ZrtpPacketDHPart dpkt(pkt);\n            ZrtpPacketConfirm* confirm = parent->prepareConfirm1(&dpkt, &errorCode);\n\n            if (confirm == NULL) {\n                if (errorCode != IgnorePacket) {\n                    sendErrorPacket(errorCode);\n                }\n                return;\n            }\n            nextState(WaitConfirm2);\n            sentPacket = static_cast<ZrtpPacketBase *>(confirm);\n            if (!parent->sendPacketZRTP(sentPacket)) {\n                sendFailed();       // returns to state Initial\n            }\n        }\n    }\n    else {  // unknown Event type for this state (covers Error and ZrtpClose)\n        if (event->type != ZrtpClose) {\n            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);\n        }\n        sentPacket = NULL;\n        nextState(Initial);\n    }\n}\n\n/*\n * WaitConirm1 state.\n *\n * This state handles a received Confirm1 message and only the Initiator\n * can enter this state.\n *\n * When entering this transition function in DH mode:\n * - Initiator mode\n * - sentPacket contains DHPart2 packet, DHPart2 timer active\n *\n * When entering this transition function in Multi stream mode via AckSent:\n * - Initiator mode\n * - sentPacket contains my Commit packet, Commit timer active\n * \n* Possible events in this state are:\n * - timeout for sent DHPart2 packet: causes a resend check and repeat sending\n *   of DHPart2 packet.\n * - Confirm1: Check Confirm1 message. If it is ok then prepare and send own\n *   Confirm2 packet and switch to state WaitConfAck.\n */\nvoid ZrtpStateClass::evWaitConfirm1(void) {\n\n    DEBUGOUT((cout << \"Checking for match in WaitConfirm1.\\n\"));\n\n    char *msg, first, last;\n    uint8_t *pkt;\n    uint32_t errorCode = 0;\n\n    if (event->type == ZrtpPacket) {\n        pkt = event->packet;\n        msg = (char *)pkt + 4;\n\n        first = tolower(*msg);\n        last = tolower(*(msg+7));\n\n        /*\n         * Confirm1:\n         * - Switch off resending DHPart2\n         * - prepare a Confirm2 packet\n         * - switch to state WaitConfAck\n         * - set timer to monitor Confirm2 packet, we are initiator\n         */\n        if (first == 'c' && last == '1') {\n            cancelTimer();\n            ZrtpPacketConfirm cpkt(pkt);\n\n            ZrtpPacketConfirm* confirm = parent->prepareConfirm2(&cpkt, &errorCode);\n\n            // Something went wrong during processing of the Confirm1 packet\n            if (confirm == NULL) {\n                sendErrorPacket(errorCode);\n                return;\n            }\n            // according to chap 5.8: after sending Confirm2 the Initiator must\n            // be ready to receive SRTP data. SRTP sender will be enabled in WaitConfAck\n            // state.\n            if (!parent->srtpSecretsReady(ForReceiver)) {\n                parent->sendInfo(Severe, CriticalSWError);\n                sendErrorPacket(CriticalSWError);\n                return;\n            }\n            nextState(WaitConfAck);\n            sentPacket = static_cast<ZrtpPacketBase *>(confirm);\n\n            if (!parent->sendPacketZRTP(sentPacket)) {\n                sendFailed();         // returns to state Initial\n                return;\n            }\n            if (startTimer(&T2) <= 0) {\n                timerFailed(SevereNoTimer);  // returns to state Initial\n            }\n        }\n    }\n    else if (event->type == Timer) {\n        if (!parent->sendPacketZRTP(sentPacket)) {\n            sendFailed();             // returns to state Initial\n            return;\n        }\n        retryCounters[DhPart2Retry]++;\n\n        if (nextTimer(&T2) <= 0) {\n            timerFailed(SevereTooMuchRetries);     // returns to state Initial\n        }\n    }\n    else {  // unknown Event type for this state (covers Error and ZrtpClose)\n        if (event->type != ZrtpClose) {\n            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);\n        }\n        sentPacket = NULL;\n        nextState(Initial);\n    }\n}\n\n/*\n * WaitConfirm2 state.\n *\n * Handles the Confirm2 message that closes the key agreement handshake. Only\n * the Responder can enter this state. If the Confirm2 message is ok send a \n * Conf2Ack to our peer. Switch to secure mode after sending Conf2Ack, our \n * peer switches to secure mode after receiving Conf2Ack.\n *\n * TODO - revise documentation comments\n * \n * When entering this transition function\n * - Responder mode\n * - sentPacket contains Confirm1 packet, no timer active\n *\n * Possible events in this state are:\n * - DHPart2: Our peer didn't receive our Confirm1 thus sends DHPart2 again.\n *   Just repeat our Confirm1.\n * - Confirm2: close DH key agreement. Perpare and send own Conf2Ack\n *   and switch to state SecureState.\n */\nvoid ZrtpStateClass::evWaitConfirm2(void) {\n\n    DEBUGOUT((cout << \"Checking for match in WaitConfirm2.\\n\"));\n\n    char *msg, first, secondLast, last;\n    uint8_t *pkt;\n    uint32_t errorCode = 0;\n\n    if (event->type == ZrtpPacket) {\n        pkt = event->packet;\n        msg = (char *)pkt + 4;\n\n        first = tolower(*msg);\n        secondLast = tolower(*(msg+6));\n        last = tolower(*(msg+7));\n\n        /*\n         * DHPart2 or Commit in multi stream mode:\n         * - resend Confirm1 packet\n         * - stay in state\n         */\n        if ((first == 'd' && secondLast == '2') || (multiStream && (first == 'c' && last == ' '))) {\n            if (!parent->sendPacketZRTP(sentPacket)) {\n                sendFailed();             // returns to state Initial\n            }\n            return;\n        }\n        /*\n         * Confirm2:\n         * - prepare ConfAck\n         * - switch on security (SRTP)\n         * - switch to SecureState\n         */\n        if (first == 'c' && last == '2') {\n            ZrtpPacketConfirm cpkt(pkt);\n            ZrtpPacketConf2Ack* confack = parent->prepareConf2Ack(&cpkt, &errorCode);\n\n            // Something went wrong during processing of the confirm2 packet\n            if (confack == NULL) {\n                sendErrorPacket(errorCode);\n                return;\n            }\n            sentPacket = static_cast<ZrtpPacketBase *>(confack);\n\n            if (!parent->sendPacketZRTP(sentPacket)) {\n                sendFailed();             // returns to state Initial\n                return;\n            }\n            if (!parent->srtpSecretsReady(ForReceiver) || !parent->srtpSecretsReady(ForSender))  {\n                parent->sendInfo(Severe, CriticalSWError);\n                sendErrorPacket(CriticalSWError);\n                return;\n            }\n            nextState(SecureState);\n            parent->sendInfo(Info, InfoSecureStateOn);\n        }\n    }\n    else {  // unknown Event type for this state (covers Error and ZrtpClose)\n        if (event->type != ZrtpClose) {\n            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);\n        }\n        sentPacket = NULL;\n        nextState(Initial);\n    }\n}\n\n/*\n * WaitConf2Ack state.\n *\n * This state handles the Conf2Ack message that acknowledges the successfull\n * processing of Confirm2. Only the Initiator can enter this state. Switch on\n * secure mode and switch to state SecureState.\n *\n * When entering this transition function\n * - Initiator mode\n * - sentPacket contains Confirm2 packet, Confirm2 timer active\n * - receiver security switched on\n *\n * Possible events in this state are:\n * - timeout for sent Confirm2 packet: causes a resend check and repeat sending\n *   of Confirm2 packet\n * - Conf2Ack: Key agreement was successfull, switch to secure mode.\n */\nvoid ZrtpStateClass::evWaitConfAck(void) {\n\n    DEBUGOUT((cout << \"Checking for match in WaitConfAck.\\n\"));\n\n    char *msg, first, last;\n    uint8_t *pkt;\n\n    if (event->type == ZrtpPacket) {\n        pkt = event->packet;\n        msg = (char *)pkt + 4;\n\n        first = tolower(*msg);\n        last = tolower(*(msg+7));\n         /*\n         * ConfAck:\n         * - Switch off resending Confirm2\n         * - switch to SecureState\n         */\n        if (first == 'c' && last == 'k') {\n            cancelTimer();\n            sentPacket = NULL;\n            // Receiver was already enabled after sending Confirm2 packet\n            // see previous states.\n            if (!parent->srtpSecretsReady(ForSender)) {\n                parent->sendInfo(Severe, CriticalSWError);\n                sendErrorPacket(CriticalSWError);\n                return;\n            }\n            nextState(SecureState);\n            // TODO: call parent to clear signature data at initiator\n            parent->sendInfo(Info, InfoSecureStateOn);\n        }\n    }\n    else if (event->type == Timer) {\n        if (!parent->sendPacketZRTP(sentPacket)) {\n            sendFailed();             // returns to state Initial\n            parent->srtpSecretsOff(ForReceiver);\n            return;\n        }\n        retryCounters[Confirm2Retry]++;\n\n        if (nextTimer(&T2) <= 0) {\n            timerFailed(SevereTooMuchRetries); // returns to state Initial\n            parent->srtpSecretsOff(ForReceiver);\n        }\n    }\n    else {  // unknown Event type for this state (covers Error and ZrtpClose)\n        if (event->type != ZrtpClose) {\n            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);\n        }\n        sentPacket = NULL;\n        nextState(Initial);\n        parent->srtpSecretsOff(ForReceiver);\n    }\n}\n\n/*\n * When entering this transition function\n * - sentPacket contains GoClear packet, GoClear timer active\n */\n\nvoid ZrtpStateClass::evWaitClearAck(void) {\n    DEBUGOUT((cout << \"Checking for match in ClearAck.\\n\"));\n\n//     char *msg, first, last, middle;\n//     uint8_t *pkt;\n// \n//     if (event->type == ZrtpPacket) {\n// \tpkt = event->packet;\n// \tmsg = (char *)pkt + 4;\n// \n// \tfirst = tolower(*msg);\n//     middle = tolower(*(msg+4));\n// \tlast = tolower(*(msg+7));\n// \n// \t/*\n// \t * ClearAck:\n// \t * - stop resending GoClear,\n// \t * - switch to state AckDetected, wait for peer's Hello\n// \t */\n// \tif (first == 'c' && middle == 'r' && last =='k') {\n// \t    cancelTimer();\n// \t    sentPacket = NULL;\n// \t    nextState(Initial);\n// \t}\n//     }\n//     // Timer event triggered - this is Timer T2 to resend GoClear w/o HMAC\n//     else if (event->type == Timer) {\n//         if (!parent->sendPacketZRTP(sentPacket)) {\n//             sendFailed();                 // returns to state Initial\n//             return;\n//         }\n//         if (nextTimer(&T2) <= 0) {\n//             timerFailed(SevereTooMuchRetries);     // returns to state Initial\n//         }\n//     }\n//     else {  // unknown Event type for this state (covers Error and ZrtpClose)\n//         if (event->type != ZrtpClose) {\n//             parent->zrtpNegotiationFailed(Severe, SevereProtocolError);\n//         }\n// \tsentPacket = NULL;\n// \tnextState(Initial);\n//     }\n}\n\n\n/*\n * WaitErrorAck state.\n *\n * This state belongs to the \"error handling state overlay\" and handle\n * ErrorAck message. Most of the ZRTP states can send Error message for\n * example if they detect wrong packets. After sending an Error message\n * the protocol engine switches to WaitErrorAck state. Receiving an\n * ErrorAck message completes the ZRTP error handling.\n *\n * When entering this transition function\n * - sentPacket contains Error packet, Error timer active\n *\n * Possible events in this state are:\n * - timeout for sent Error packet: causes a resend check and repeat sending\n *   of Error packet\n * - ErrorAck: Stop timer and switch to state Initial.\n */\n\nvoid ZrtpStateClass::evWaitErrorAck(void) {\n    DEBUGOUT((cout << \"Checking for match in ErrorAck.\\n\"));\n\n    char *msg, first, last;\n    uint8_t *pkt;\n\n    if (event->type == ZrtpPacket) {\n        pkt = event->packet;\n        msg = (char *)pkt + 4;\n\n        first = tolower(*msg);\n        last = tolower(*(msg+7));\n\n        /*\n         * Errorck:\n         * - stop resending Error,\n         * - switch to state Initial\n         */\n        if (first == 'e' && last =='k') {\n            cancelTimer();\n            sentPacket = NULL;\n            nextState(Initial);\n        }\n    }\n    // Timer event triggered - this is Timer T2 to resend Error.\n    else if (event->type == Timer) {\n        if (!parent->sendPacketZRTP(sentPacket)) {\n            sendFailed();                 // returns to state Initial\n            return;\n        }\n        retryCounters[ErrorRetry]++;\n\n        if (nextTimer(&T2) <= 0) {\n            timerFailed(SevereTooMuchRetries);     // returns to state Initial\n        }\n    }\n    else {  // unknown Event type for this state (covers Error and ZrtpClose)\n        if (event->type != ZrtpClose) {\n            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);\n        }\n        sentPacket = NULL;\n        nextState(Initial);\n    }\n}\n\nvoid ZrtpStateClass::evSecureState(void) {\n\n    DEBUGOUT((cout << \"Checking for match in SecureState.\\n\"));\n\n    char *msg, first, last;\n    uint8_t *pkt;\n\n    /*\n     * Handle a possible substate. If substate handling was ok just return.\n     */\n    if (secSubstate == WaitSasRelayAck) {\n        if (subEvWaitRelayAck())\n            return; \n    }\n\n    if (event->type == ZrtpPacket) {\n        pkt = event->packet;\n        msg = (char *)pkt + 4;\n\n        first = tolower(*msg);\n        last = tolower(*(msg+7));\n\n        /*\n         * Confirm2:\n         * - resend Conf2Ack packet\n         * - stay in state\n         */\n        if (first == 'c' && last == '2') {\n            if (sentPacket != NULL && !parent->sendPacketZRTP(sentPacket)) {\n                sentPacket = NULL;\n                nextState(Initial);\n                parent->srtpSecretsOff(ForSender);\n                parent->srtpSecretsOff(ForReceiver);\n                parent->zrtpNegotiationFailed(Severe, SevereCannotSend);\n            }\n            return;\n        }\n        /*\n         * GoClear received, handle it. TODO fix go clear handling\n         *\n        if (first == 'g' && last == 'r') {\n            ZrtpPacketGoClear gpkt(pkt);\n            ZrtpPacketClearAck* clearAck = parent->prepareClearAck(&gpkt);\n\n            if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(clearAck))) {\n                return;\n            }\n        // TODO Timeout to resend clear ack until user user confirmation\n        }\n        */\n    }\n    else if (event->type == Timer) {\n        // Ignore stray timeout in this state\n        ;\n    }\n    // unknown Event type for this state (covers Error and ZrtpClose)\n    else  {\n        // If in secure state ingnore error events to avoid Error packet injection\n        // attack - found by Dmitry Monakhov (dmonakhov@openvz.org)\n        if (event->type == ErrorPkt)\n            return;\n        sentPacket = NULL;\n        parent->srtpSecretsOff(ForSender);\n        parent->srtpSecretsOff(ForReceiver);\n        nextState(Initial);\n        if (event->type != ZrtpClose) {\n            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);\n        }\n        parent->sendInfo(Info, InfoSecureStateOff);\n    }\n}\n\nbool ZrtpStateClass::subEvWaitRelayAck() {\n    char *msg, first, last;\n    uint8_t* pkt;\n\n    /*\n     * First check the general event type, then discrimnate the real event.\n     */\n    if  (event->type == ZrtpPacket) {\n        pkt = event->packet;\n        msg = (char *)pkt + 4;\n\n        first = tolower(*msg);\n        last = tolower(*(msg+7));\n\n        /*\n         * SAS relayAck:\n         * - stop resending SASRelay,\n         * - switch to secure substate Normal\n         */\n        if (first == 'r' && last =='k') {\n            cancelTimer();\n            secSubstate = Normal;\n            sentPacket = NULL;\n        }\n        return true;\n    }\n    // Timer event triggered - this is Timer T2 to resend Error.\n    else if (event->type == Timer) {\n        if (!parent->sendPacketZRTP(sentPacket)) {\n            sendFailed(); // returns to state Initial\n            return false;\n        }\n        if (nextTimer(&T2) <= 0) {\n            // returns to state initial\n            // timerFailed(ZrtpCodes.SevereCodes.SevereTooMuchRetries);\n            return false;\n        }\n        return true;\n    }\n    return false;\n}\n\nint32_t ZrtpStateClass::startTimer(zrtpTimer_t *t) {\n\n    t->time = t->start;\n    t->counter = 0;\n    return parent->activateTimer(t->time);\n}\n\nint32_t ZrtpStateClass::nextTimer(zrtpTimer_t *t) {\n\n    t->time += t->time;\n    t->time = (t->time > t->capping)? t->capping : t->time;\n    if (t->maxResend > 0) {\n        t->counter++;\n        if (t->counter > t->maxResend) {\n            return -1;\n        }\n    }\n    return parent->activateTimer(t->time);\n}\n\nvoid ZrtpStateClass::sendErrorPacket(uint32_t errorCode) {\n    cancelTimer();\n\n    ZrtpPacketError* err = parent->prepareError(errorCode);\n    parent->zrtpNegotiationFailed(ZrtpError, errorCode);\n\n    sentPacket =  static_cast<ZrtpPacketBase *>(err);\n    nextState(WaitErrorAck);\n    if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(err)) || (startTimer(&T2) <= 0)) {\n        sendFailed();\n    }\n}\n\nvoid ZrtpStateClass::sendSASRelay(ZrtpPacketSASrelay* relay) {\n    cancelTimer();\n    sentPacket = static_cast<ZrtpPacketBase *>(relay);\n    secSubstate = WaitSasRelayAck;\n    if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(relay)) || (startTimer(&T2) <= 0)) {\n        sendFailed();\n    }\n}\n\nvoid ZrtpStateClass::sendFailed() {\n    sentPacket = NULL;\n    nextState(Initial);\n    parent->zrtpNegotiationFailed(Severe, SevereCannotSend);\n}\n\nvoid ZrtpStateClass::timerFailed(int32_t subCode) {\n    sentPacket = NULL;\n    nextState(Initial);\n    parent->zrtpNegotiationFailed(Severe, subCode);\n}\n\nvoid ZrtpStateClass::setMultiStream(bool multi) {\n    multiStream = multi;\n}\n\nbool ZrtpStateClass::isMultiStream() {\n    return multiStream;\n}\n\n\nint ZrtpStateClass::getNumberOfRetryCounters() {\n    return sizeof(retryCounters)/sizeof(int32_t);\n}\n\nint ZrtpStateClass::getRetryCounters(int32_t* counters) {\n    memcpy(counters, retryCounters, sizeof(retryCounters));\n    return sizeof(retryCounters)/sizeof(int32_t);\n}\n\n/** EMACS **\n * Local variables:\n * mode: c++\n * c-default-style: ellemtel\n * c-basic-offset: 4\n * End:\n */\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/ZrtpTextData.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n#include <stdint.h>\n#include <libzrtpcpp/ZrtpConfigure.h>\n//                             1\n//                    1234567890123456\nchar clientId[] =    \"GNU ZRTP 4.2.2  \"; // 16 chars max.\nchar zrtpVersion_11[] = \"1.10\";          // must be 4 chars\nchar zrtpVersion_12[] = \"1.20\";          // must be 4 chars\n/**\n *\n */\nchar HelloMsg[]    = \"Hello   \";\nchar HelloAckMsg[] = \"HelloACK\";\nchar CommitMsg[]   = \"Commit  \";\nchar DHPart1Msg[]  = \"DHPart1 \";\nchar DHPart2Msg[]  = \"DHPart2 \";\nchar Confirm1Msg[] = \"Confirm1\";\nchar Confirm2Msg[] = \"Confirm2\";\nchar Conf2AckMsg[] = \"Conf2ACK\";\nchar ErrorMsg[]    = \"Error   \";\nchar ErrorAckMsg[] = \"ErrorACK\";\nchar GoClearMsg[]  = \"GoClear \";\nchar ClearAckMsg[] = \"ClearACK\";\nchar PingMsg[]     = \"Ping    \";\nchar PingAckMsg[]  = \"PingACK \";\nchar SasRelayMsg[] = \"SASrelay\";\nchar RelayAckMsg[] = \"RelayACK\";\n\nchar responder[]      = \"Responder\";\nchar initiator[]      = \"Initiator\";\nchar iniMasterKey[]   = \"Initiator SRTP master key\";\nchar iniMasterSalt[]  = \"Initiator SRTP master salt\";\nchar respMasterKey[]  = \"Responder SRTP master key\";\nchar respMasterSalt[] = \"Responder SRTP master salt\";\n\nchar iniHmacKey[]  = \"Initiator HMAC key\";\nchar respHmacKey[] = \"Responder HMAC key\";\nchar retainedSec[] = \"retained secret\";\n\nchar iniZrtpKey[]  = \"Initiator ZRTP key\";\nchar respZrtpKey[] = \"Responder ZRTP key\";\n\nchar sasString[] = \"SAS\";\n\nchar KDFString[] = \"ZRTP-HMAC-KDF\";\n\nchar zrtpSessionKey[] = \"ZRTP Session Key\";\n\nchar zrtpMsk[] = \"ZRTP MSK\";\nchar zrtpTrustedMitm[] = \"Trusted MiTM key\";\n\nchar s256[] = \"S256\";\nchar s384[] = \"S384\";\nchar skn2[] = \"SKN2\";\nchar skn3[] = \"SKN3\";\nconst char* mandatoryHash = s256;\n\nchar aes3[] = \"AES3\";\nchar aes2[] = \"AES2\";\nchar aes1[] = \"AES1\";\nchar two3[] = \"2FS3\";\nchar two2[] = \"2FS2\";\nchar two1[] = \"2FS1\";\nconst char* mandatoryCipher = aes1;\n\nchar dh2k[] = \"DH2k\";\nchar ec25[] = \"EC25\";\nchar dh3k[] = \"DH3k\";\nchar ec38[] = \"EC38\";\nchar e255[] = \"E255\";\nchar e414[] = \"E414\";\nchar mult[] = \"Mult\";\nconst char* mandatoryPubKey = dh3k;\n\nchar b32[] =  \"B32 \";\nchar b256[] = \"B256\";\nconst char* mandatorySasType = b32;\n\nchar hs32[] = \"HS32\";\nchar hs80[] = \"HS80\";\nchar sk32[] = \"SK32\";\nchar sk64[] = \"SK64\";\nconst char* mandatoryAuthLen_1 = hs32;\nconst char* mandatoryAuthLen_2 = hs80;\n\nconst char* sas256WordsOdd[] = {\n    \"adroitness\",\n    \"adviser\",\n    \"aftermath\",\n    \"aggregate\",\n    \"alkali\",\n    \"almighty\",\n    \"amulet\",\n    \"amusement\",\n    \"antenna\",\n    \"applicant\",\n    \"Apollo\",\n    \"armistice\",\n    \"article\",\n    \"asteroid\",\n    \"Atlantic\",\n    \"atmosphere\",\n    \"autopsy\",\n    \"Babylon\",\n    \"backwater\",\n    \"barbecue\",\n    \"belowground\",\n    \"bifocals\",\n    \"bodyguard\",\n    \"bookseller\",\n    \"borderline\",\n    \"bottomless\",\n    \"Bradbury\",\n    \"bravado\",\n    \"Brazilian\",\n    \"breakaway\",\n    \"Burlington\",\n    \"businessman\",\n    \"butterfat\",\n    \"Camelot\",\n    \"candidate\",\n    \"cannonball\",\n    \"Capricorn\",\n    \"caravan\",\n    \"caretaker\",\n    \"celebrate\",\n    \"cellulose\",\n    \"certify\",\n    \"chambermaid\",\n    \"Cherokee\",\n    \"Chicago\",\n    \"clergyman\",\n    \"coherence\",\n    \"combustion\",\n    \"commando\",\n    \"company\",\n    \"component\",\n    \"concurrent\",\n    \"confidence\",\n    \"conformist\",\n    \"congregate\",\n    \"consensus\",\n    \"consulting\",\n    \"corporate\",\n    \"corrosion\",\n    \"councilman\",\n    \"crossover\",\n    \"crucifix\",\n    \"cumbersome\",\n    \"customer\",\n    \"Dakota\",\n    \"decadence\",\n    \"December\",\n    \"decimal\",\n    \"designing\",\n    \"detector\",\n    \"detergent\",\n    \"determine\",\n    \"dictator\",\n    \"dinosaur\",\n    \"direction\",\n    \"disable\",\n    \"disbelief\",\n    \"disruptive\",\n    \"distortion\",\n    \"document\",\n    \"embezzle\",\n    \"enchanting\",\n    \"enrollment\",\n    \"enterprise\",\n    \"equation\",\n    \"equipment\",\n    \"escapade\",\n    \"Eskimo\",\n    \"everyday\",\n    \"examine\",\n    \"existence\",\n    \"exodus\",\n    \"fascinate\",\n    \"filament\",\n    \"finicky\",\n    \"forever\",\n    \"fortitude\",\n    \"frequency\",\n    \"gadgetry\",\n    \"Galveston\",\n    \"getaway\",\n    \"glossary\",\n    \"gossamer\",\n    \"graduate\",\n    \"gravity\",\n    \"guitarist\",\n    \"hamburger\",\n    \"Hamilton\",\n    \"handiwork\",\n    \"hazardous\",\n    \"headwaters\",\n    \"hemisphere\",\n    \"hesitate\",\n    \"hideaway\",\n    \"holiness\",\n    \"hurricane\",\n    \"hydraulic\",\n    \"impartial\",\n    \"impetus\",\n    \"inception\",\n    \"indigo\",\n    \"inertia\",\n    \"infancy\",\n    \"inferno\",\n    \"informant\",\n    \"insincere\",\n    \"insurgent\",\n    \"integrate\",\n    \"intention\",\n    \"inventive\",\n    \"Istanbul\",\n    \"Jamaica\",\n    \"Jupiter\",\n    \"leprosy\",\n    \"letterhead\",\n    \"liberty\",\n    \"maritime\",\n    \"matchmaker\",\n    \"maverick\",\n    \"Medusa\",\n    \"megaton\",\n    \"microscope\",\n    \"microwave\",\n    \"midsummer\",\n    \"millionaire\",\n    \"miracle\",\n    \"misnomer\",\n    \"molasses\",\n    \"molecule\",\n    \"Montana\",\n    \"monument\",\n    \"mosquito\",\n    \"narrative\",\n    \"nebula\",\n    \"newsletter\",\n    \"Norwegian\",\n    \"October\",\n    \"Ohio\",\n    \"onlooker\",\n    \"opulent\",\n    \"Orlando\",\n    \"outfielder\",\n    \"Pacific\",\n    \"pandemic\",\n    \"Pandora\",\n    \"paperweight\",\n    \"paragon\",\n    \"paragraph\",\n    \"paramount\",\n    \"passenger\",\n    \"pedigree\",\n    \"Pegasus\",\n    \"penetrate\",\n    \"perceptive\",\n    \"performance\",\n    \"pharmacy\",\n    \"phonetic\",\n    \"photograph\",\n    \"pioneer\",\n    \"pocketful\",\n    \"politeness\",\n    \"positive\",\n    \"potato\",\n    \"processor\",\n    \"provincial\",\n    \"proximate\",\n    \"puberty\",\n    \"publisher\",\n    \"pyramid\",\n    \"quantity\",\n    \"racketeer\",\n    \"rebellion\",\n    \"recipe\",\n    \"recover\",\n    \"repellent\",\n    \"replica\",\n    \"reproduce\",\n    \"resistor\",\n    \"responsive\",\n    \"retraction\",\n    \"retrieval\",\n    \"retrospect\",\n    \"revenue\",\n    \"revival\",\n    \"revolver\",\n    \"sandalwood\",\n    \"sardonic\",\n    \"Saturday\",\n    \"savagery\",\n    \"scavenger\",\n    \"sensation\",\n    \"sociable\",\n    \"souvenir\",\n    \"specialist\",\n    \"speculate\",\n    \"stethoscope\",\n    \"stupendous\",\n    \"supportive\",\n    \"surrender\",\n    \"suspicious\",\n    \"sympathy\",\n    \"tambourine\",\n    \"telephone\",\n    \"therapist\",\n    \"tobacco\",\n    \"tolerance\",\n    \"tomorrow\",\n    \"torpedo\",\n    \"tradition\",\n    \"travesty\",\n    \"trombonist\",\n    \"truncated\",\n    \"typewriter\",\n    \"ultimate\",\n    \"undaunted\",\n    \"underfoot\",\n    \"unicorn\",\n    \"unify\",\n    \"universe\",\n    \"unravel\",\n    \"upcoming\",\n    \"vacancy\",\n    \"vagabond\",\n    \"vertigo\",\n    \"Virginia\",\n    \"visitor\",\n    \"vocalist\",\n    \"voyager\",\n    \"warranty\",\n    \"Waterloo\",\n    \"whimsical\",\n    \"Wichita\",\n    \"Wilmington\",\n    \"Wyoming\",\n    \"yesteryear\",\n    \"Yucatan\"\n    };\n\nconst char* sas256WordsEven[] = {\n    \"aardvark\",\n    \"absurd\",\n    \"accrue\",\n    \"acme\",\n    \"adrift\",\n    \"adult\",\n    \"afflict\",\n    \"ahead\",\n    \"aimless\",\n    \"Algol\",\n    \"allow\",\n    \"alone\",\n    \"ammo\",\n    \"ancient\",\n    \"apple\",\n    \"artist\",\n    \"assume\",\n    \"Athens\",\n    \"atlas\",\n    \"Aztec\",\n    \"baboon\",\n    \"backfield\",\n    \"backward\",\n    \"banjo\",\n    \"beaming\",\n    \"bedlamp\",\n    \"beehive\",\n    \"beeswax\",\n    \"befriend\",\n    \"Belfast\",\n    \"berserk\",\n    \"billiard\",\n    \"bison\",\n    \"blackjack\",\n    \"blockade\",\n    \"blowtorch\",\n    \"bluebird\",\n    \"bombast\",\n    \"bookshelf\",\n    \"brackish\",\n    \"breadline\",\n    \"breakup\",\n    \"brickyard\",\n    \"briefcase\",\n    \"Burbank\",\n    \"button\",\n    \"buzzard\",\n    \"cement\",\n    \"chairlift\",\n    \"chatter\",\n    \"checkup\",\n    \"chisel\",\n    \"choking\",\n    \"chopper\",\n    \"Christmas\",\n    \"clamshell\",\n    \"classic\",\n    \"classroom\",\n    \"cleanup\",\n    \"clockwork\",\n    \"cobra\",\n    \"commence\",\n    \"concert\",\n    \"cowbell\",\n    \"crackdown\",\n    \"cranky\",\n    \"crowfoot\",\n    \"crucial\",\n    \"crumpled\",\n    \"crusade\",\n    \"cubic\",\n    \"dashboard\",\n    \"deadbolt\",\n    \"deckhand\",\n    \"dogsled\",\n    \"dragnet\",\n    \"drainage\",\n    \"dreadful\",\n    \"drifter\",\n    \"dropper\",\n    \"drumbeat\",\n    \"drunken\",\n    \"Dupont\",\n    \"dwelling\",\n    \"eating\",\n    \"edict\",\n    \"egghead\",\n    \"eightball\",\n    \"endorse\",\n    \"endow\",\n    \"enlist\",\n    \"erase\",\n    \"escape\",\n    \"exceed\",\n    \"eyeglass\",\n    \"eyetooth\",\n    \"facial\",\n    \"fallout\",\n    \"flagpole\",\n    \"flatfoot\",\n    \"flytrap\",\n    \"fracture\",\n    \"framework\",\n    \"freedom\",\n    \"frighten\",\n    \"gazelle\",\n    \"Geiger\",\n    \"glitter\",\n    \"glucose\",\n    \"goggles\",\n    \"goldfish\",\n    \"gremlin\",\n    \"guidance\",\n    \"hamlet\",\n    \"highchair\",\n    \"hockey\",\n    \"indoors\",\n    \"indulge\",\n    \"inverse\",\n    \"involve\",\n    \"island\",\n    \"jawbone\",\n    \"keyboard\",\n    \"kickoff\",\n    \"kiwi\",\n    \"klaxon\",\n    \"locale\",\n    \"lockup\",\n    \"merit\",\n    \"minnow\",\n    \"miser\",\n    \"Mohawk\",\n    \"mural\",\n    \"music\",\n    \"necklace\",\n    \"Neptune\",\n    \"newborn\",\n    \"nightbird\",\n    \"Oakland\",\n    \"obtuse\",\n    \"offload\",\n    \"optic\",\n    \"orca\",\n    \"payday\",\n    \"peachy\",\n    \"pheasant\",\n    \"physique\",\n    \"playhouse\",\n    \"Pluto\",\n    \"preclude\",\n    \"prefer\",\n    \"preshrunk\",\n    \"printer\",\n    \"prowler\",\n    \"pupil\",\n    \"puppy\",\n    \"python\",\n    \"quadrant\",\n    \"quiver\",\n    \"quota\",\n    \"ragtime\",\n    \"ratchet\",\n    \"rebirth\",\n    \"reform\",\n    \"regain\",\n    \"reindeer\",\n    \"rematch\",\n    \"repay\",\n    \"retouch\",\n    \"revenge\",\n    \"reward\",\n    \"rhythm\",\n    \"ribcage\",\n    \"ringbolt\",\n    \"robust\",\n    \"rocker\",\n    \"ruffled\",\n    \"sailboat\",\n    \"sawdust\",\n    \"scallion\",\n    \"scenic\",\n    \"scorecard\",\n    \"Scotland\",\n    \"seabird\",\n    \"select\",\n    \"sentence\",\n    \"shadow\",\n    \"shamrock\",\n    \"showgirl\",\n    \"skullcap\",\n    \"skydive\",\n    \"slingshot\",\n    \"slowdown\",\n    \"snapline\",\n    \"snapshot\",\n    \"snowcap\",\n    \"snowslide\",\n    \"solo\",\n    \"southward\",\n    \"soybean\",\n    \"spaniel\",\n    \"spearhead\",\n    \"spellbind\",\n    \"spheroid\",\n    \"spigot\",\n    \"spindle\",\n    \"spyglass\",\n    \"stagehand\",\n    \"stagnate\",\n    \"stairway\",\n    \"standard\",\n    \"stapler\",\n    \"steamship\",\n    \"sterling\",\n    \"stockman\",\n    \"stopwatch\",\n    \"stormy\",\n    \"sugar\",\n    \"surmount\",\n    \"suspense\",\n    \"sweatband\",\n    \"swelter\",\n    \"tactics\",\n    \"talon\",\n    \"tapeworm\",\n    \"tempest\",\n    \"tiger\",\n    \"tissue\",\n    \"tonic\",\n    \"topmost\",\n    \"tracker\",\n    \"transit\",\n    \"trauma\",\n    \"treadmill\",\n    \"Trojan\",\n    \"trouble\",\n    \"tumor\",\n    \"tunnel\",\n    \"tycoon\",\n    \"uncut\",\n    \"unearth\",\n    \"unwind\",\n    \"uproot\",\n    \"upset\",\n    \"upshot\",\n    \"vapor\",\n    \"village\",\n    \"virus\",\n    \"Vulcan\",\n    \"waffle\",\n    \"wallet\",\n    \"watchword\",\n    \"wayside\",\n    \"willow\",\n    \"woodlark\",\n    \"Zulu\"\n    };\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/aesCFB.cpp",
    "content": "/*\n  Copyright (C) 2012-2013 by Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/**\n * @author  Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <string.h>\n\n#include <zrtp/crypto/aesCFB.h>\n#include <cryptcommon/aescpp.h>\n\nvoid aesCfbEncrypt(uint8_t *key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength)\n{\n    AESencrypt *saAes = new AESencrypt();\n\n    if (keyLength == 16)\n        saAes->key128(key);\n    else if (keyLength == 32)\n        saAes->key256(key);\n    else\n        return;\n\n    // Note: maybe copy IV to an internal array if we encounter strange things.\n    // the cfb encrypt modify the IV on return. Same for output data (inplace encryption)\n    saAes->cfb_encrypt(data, data, dataLength, IV);\n    delete saAes;\n}\n\n\nvoid aesCfbDecrypt(uint8_t *key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength)\n{\n    AESencrypt *saAes = new AESencrypt();\n    if (keyLength == 16)\n        saAes->key128(key);\n    else if (keyLength == 32)\n        saAes->key256(key);\n    else\n        return;\n\n    // Note: maybe copy IV to an internal array if we encounter strange things.\n    // the cfb encrypt modify the IV on return. Same for output data (inplace encryption)\n    saAes->cfb_decrypt(data, data, dataLength, IV);\n    delete saAes;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/aesCFB.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef _AESCFB_H__\n#define _AESCFB_H__\n\n#include <stdint.h>\n\n/**\n * @file aesCFB.h\n * @brief Function that provide AES CFB mode support\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#ifndef AES_BLOCK_SIZE\n#define AES_BLOCK_SIZE 16\n#endif\n\n/**\n * Encrypt data with AES CFB mode, full block feedback size.\n *\n * This functions takes one data chunk and encrypts it with\n * AES CFB mode. The lenght of the data may be arbitrary and\n * it is not needed to be a multiple of AES blocksize.\n *\n * @param key\n *    Points to the key bytes.\n * @param keyLength\n *    Length of the key in bytes\n * @param IV\n *    The initialization vector which must be AES_BLOCKSIZE (16) bytes.\n * @param data\n *    Points to a buffer that contains and receives the computed\n *    the data (in-place encryption).\n * @param dataLength\n *    Length of the data in bytes\n */\n\nvoid aesCfbEncrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,\n                   int32_t dataLength);\n\n/**\n * Decrypt data with AES CFB mode, full block feedback size.\n *\n * This functions takes one data chunk and decrypts it with\n * AES CFB mode. The lenght of the data may be arbitrary and\n * it is not needed to be a multiple of AES blocksize.\n *\n * @param key\n *    Points to the key bytes.\n * @param keyLength\n *    Length of the key in bytes\n * @param IV\n *    The initialization vector which must be AES_BLOCKSIZE (16) bytes.\n * @param data\n *    Points to a buffer that contains and receives the computed\n *    the data (in-place decryption).\n * @param dataLength\n *    Length of the data in bytes\n */\n\nvoid aesCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,\n                   int32_t dataLength);\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/gcrypt/InitializeGcrypt.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <stdio.h>\n\n#include <string.h>\n#include <pthread.h>\n#include <errno.h>\n#include <gcrypt.h>\n\n/*\n * The following macro was copied from gcrypt.h and modified to explicitly\n * cast the pointer types to keep the compiler happy.\n */\n#define GCRY_THREAD_OPTION_PTHREAD_CPP_IMPL                                   \\\nstatic int gcry_pthread_mutex_init (void **priv)                              \\\n{                                                                             \\\n  int err = 0;                                                                \\\n  pthread_mutex_t *lock = (pthread_mutex_t *)malloc (sizeof (pthread_mutex_t)); \\\n                                                                              \\\n  if (!lock)                                                                  \\\n    err = ENOMEM;                                                             \\\n  if (!err)                                                                   \\\n{                                                                         \\\n      err = pthread_mutex_init (lock, NULL);                                  \\\n      if (err)                                                                \\\n        free (lock);                                                          \\\n      else                                                                    \\\n        *priv = lock;                                                         \\\n}                                                                         \\\n  return err;                                                                 \\\n}                                                                             \\\nstatic int gcry_pthread_mutex_destroy (void **lock)                           \\\n{ int err = pthread_mutex_destroy ((pthread_mutex_t *)*lock);  free (*lock); return err; }     \\\nstatic int gcry_pthread_mutex_lock (void **lock)                              \\\n{ return pthread_mutex_lock ((pthread_mutex_t *)*lock); }                     \\\nstatic int gcry_pthread_mutex_unlock (void **lock)                            \\\n{ return pthread_mutex_unlock ((pthread_mutex_t *)*lock); }                   \\\n                                                                              \\\nstatic struct gcry_thread_cbs gcry_threads_pthread =                          \\\n{ GCRY_THREAD_OPTION_PTHREAD, NULL,                                           \\\n  gcry_pthread_mutex_init, gcry_pthread_mutex_destroy,                        \\\n  gcry_pthread_mutex_lock, gcry_pthread_mutex_unlock }\n\n/** Implement the locking callback functions for libgcrypt.\n *\n */\n\nstatic int initialized = 0;\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\nGCRY_THREAD_OPTION_PTHREAD_CPP_IMPL;\n#ifdef __cplusplus\n}\n#endif\n\nint initializeGcrypt ()\n{\n\n    if (initialized) {\n\treturn 1;\n    }\n    gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);\n    gcry_check_version(NULL);\n    gcry_control(GCRYCTL_DISABLE_SECMEM);\n    initialized = 1;\n    return 1;\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/gcrypt/gcryptAesCFB.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/** Copyright (C) 2006, 2007\n *\n * @author  Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <gcrypt.h>\n#include <crypto/aesCFB.h>\n\n\nextern void initializeGcrypt();\n\nvoid aesCfbEncrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,\n                   int32_t dataLength);\n{\n    gcry_error_t err = 0;\n    int algo;\n\n    initializeGcrypt();\n\n    if (keyLength == 16) {\n        algo = GCRY_CIPHER_AES;\n    }\n    else if (keyLength == 32) {\n        algo = GCRY_CIPHER_AES256;\n    }\n    else {\n\treturn;\n    }\n    gcry_cipher_hd_t tmp;\n    err = gcry_cipher_open(&tmp, algo, GCRY_CIPHER_MODE_CFB, 0);\n    err = gcry_cipher_setkey(tmp, key, keyLength);\n    err = gcry_cipher_setiv (tmp, IV, AES_BLOCK_SIZE);\n    err = gcry_cipher_encrypt (tmp, data, dataLength, data, dataLength);\n    gcry_cipher_close(tmp);\n}\n\nvoid aesCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,\n                   int32_t dataLength);\n{\n    gcry_error_t err = 0;\n    int algo;\n\n    initializeGcrypt();\n\n    if (keyLength == 16) {\n        algo = GCRY_CIPHER_AES;\n    }\n    else if (keyLength == 32) {\n        algo = GCRY_CIPHER_AES256;\n    }\n    else {\n\treturn;\n    }\n    gcry_cipher_hd_t tmp;\n    err = gcry_cipher_open(&tmp, algo, GCRY_CIPHER_MODE_CFB, 0);\n    err = gcry_cipher_setkey(tmp, key, keyLength);\n    err = gcry_cipher_setiv (tmp, IV, AES_BLOCK_SIZE);\n    err = gcry_cipher_decrypt (tmp, data, dataLength, data, dataLength);\n    gcry_cipher_close(tmp);\n}"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/gcrypt/gcryptZrtpDH.cpp",
    "content": "/*\n  Copyright (C) 2006, 2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/** Copyright (C) 2006, 2009\n *\n * @author  Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <gcrypt.h>\n#include <zrtp/crypto/zrtpDH.h>\n#include <zrtp/libzrtpcpp/ZrtpTextData.h>\n#include <sstream>\n\nstruct gcryptCtx {\n    gcry_mpi_t privKey;\n    gcry_mpi_t pubKey;\n//    int32_t pLength;\n};\n\nextern void initializeGcrypt();\n\nstatic gcry_mpi_t bnP2048 = NULL;\nstatic gcry_mpi_t bnP3072 = NULL;\n// static gcry_mpi_t bnP4096 = NULL;\nstatic gcry_mpi_t two = NULL;\nstatic gcry_mpi_t bnP2048MinusOne = NULL;\nstatic gcry_mpi_t bnP3072MinusOne = NULL;\n// static gcry_mpi_t bnP4096MinusOne = NULL;\n\nstatic uint8_t dhinit = 0;\n\nvoid randomZRTP(uint8_t *buf, int32_t length) {\n    initializeGcrypt();\n    gcry_randomize(buf, length, GCRY_STRONG_RANDOM);\n}\n\nstatic const uint8_t P2048[] =\n{\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, \n    0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,\n    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, \n    0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,\n    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, \n    0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,\n    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, \n    0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,\n    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, \n    0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,\n    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, \n    0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,\n    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, \n    0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,\n    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, \n    0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,\n    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,\n    0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,\n    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,\n    0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,\n    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, \n    0xFF, 0xFF, 0xFF, 0xFF\n};\n\nstatic const uint8_t P3072[] =\n    {\n\t0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,\n\t0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,\n\t0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,\n\t0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,\n\t0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,\n\t0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,\n\t0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,\n\t0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,\n\t0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,\n\t0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,\n\t0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,\n\t0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,\n\t0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,\n\t0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,\n\t0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,\n\t0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,\n\t0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,\n\t0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,\n\t0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,\n\t0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,\n\t0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,\n\t0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,\n\t0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,\n\t0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,\n\t0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,\n\t0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,\n\t0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,\n\t0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,\n\t0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,\n\t0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,\n\t0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,\n\t0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n    };\n\n    /* *************\nstatic const uint8_t P4096[] =\n{\n\t0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,\n\t0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,\n\t0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,\n\t0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,\n\t0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,\n\t0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,\n\t0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,\n\t0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,\n\t0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,\n\t0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,\n\t0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,\n\t0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,\n\t0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,\n\t0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,\n\t0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,\n\t0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,\n\t0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,\n\t0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,\n\t0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,\n\t0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,\n\t0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,\n\t0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,\n\t0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,\n\t0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,\n\t0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,\n\t0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,\n\t0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,\n\t0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,\n\t0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,\n\t0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,\n\t0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,\n\t0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,\n\t0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,\n\t0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,\n\t0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,\n\t0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,\n\t0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,\n\t0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,\n\t0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,\n\t0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,\n\t0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,\n\t0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,\n\t0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\n    *************** */\n#define DH3K 1\n#define DH2K 0\nZrtpDH::ZrtpDH(const char* type){\n\n    // Well - the algo type is only 4 char thus cast to int32 and compare\n    if (*(int32_t*)type == *(int32_t*)dh2k) {\n        pkType = DH2K;\n    }\n    else if (*(int32_t*)type == *(int32_t*)dh3k) {\n        pkType = DH3K;\n    }\n    else {\n        fprintf(stderr, \"Unknown pubkey algo: %d\\n\", pkType);\n    }\n    ctx = static_cast<void*>(new gcryptCtx);\n    gcryptCtx* tmpCtx = static_cast<gcryptCtx*>(ctx);\n    tmpCtx->privKey = NULL;\n    tmpCtx->pubKey = NULL;\n\n    initializeGcrypt();\n\n    if (!dhinit) {\n\tgcry_mpi_scan(&bnP2048, GCRYMPI_FMT_USG, P2048, sizeof(P2048), NULL);\n        gcry_mpi_scan(&bnP3072, GCRYMPI_FMT_USG, P3072, sizeof(P3072), NULL);\n//        gcry_mpi_scan(&bnP4096, GCRYMPI_FMT_USG, P4096, sizeof(P4096), NULL);\n        two = gcry_mpi_set_ui(NULL, 2);\n\n        bnP2048MinusOne = gcry_mpi_new(sizeof(P2048)*8);\n        gcry_mpi_sub_ui(bnP2048MinusOne, bnP2048, 1);\n\n        bnP3072MinusOne = gcry_mpi_new(sizeof(P3072)*8);\n        gcry_mpi_sub_ui(bnP3072MinusOne, bnP3072, 1);\n\n//        bnP4096MinusOne = gcry_mpi_new(sizeof(P4096)*8);\n//        gcry_mpi_sub_ui(bnP4096MinusOne, bnP4096, 1);\n        dhinit = 1;\n    }\n\n    if (pkType == DH3K) {\n        tmpCtx->privKey = gcry_mpi_new(256);\n        gcry_mpi_randomize(tmpCtx->privKey, 256, GCRY_STRONG_RANDOM);\n    }\n    else if (pkType == DH2K) {\n        tmpCtx->privKey = gcry_mpi_new(512);\n        gcry_mpi_randomize(tmpCtx->privKey, 512, GCRY_STRONG_RANDOM);\n    }\n//    else {\n//        tmpCtx->privKey = gcry_mpi_new(512);\n//        gcry_mpi_randomize(tmpCtx->privKey, 512, GCRY_STRONG_RANDOM);\n//    }\n}\n\nZrtpDH::~ZrtpDH() {\n    gcryptCtx* tmpCtx = static_cast<gcryptCtx*>(ctx);\n\n    if (tmpCtx != NULL) {\n        gcry_mpi_release(tmpCtx->privKey);\n        tmpCtx->privKey = NULL;\n        gcry_mpi_release(tmpCtx->pubKey);\n        tmpCtx->pubKey = NULL;\n        delete tmpCtx;\n        ctx = NULL;\n    }\n}\n\nint32_t ZrtpDH::computeSecretKey(uint8_t *pubKeyBytes, uint8_t *secret) {\n\n    int32_t length = getDhSize();\n    gcryptCtx* tmpCtx = static_cast<gcryptCtx*>(ctx);\n\n    gcry_mpi_t pubKeyOther;\n    gcry_mpi_t sec = gcry_mpi_new(0);\n    gcry_mpi_scan(&pubKeyOther, GCRYMPI_FMT_USG, pubKeyBytes, length, NULL);\n\n    if (pkType == DH2K) {\n        gcry_mpi_powm(sec, pubKeyOther, tmpCtx->privKey, bnP2048);\n    }\n    else if (pkType == DH3K) {\n        gcry_mpi_powm(sec, pubKeyOther, tmpCtx->privKey, bnP3072);\n    }\n    else {\n//\tgcry_mpi_powm(sec, pubKeyOther, tmpCtx->privKey, bnP4096);\n        return 0;\n    }\n    gcry_mpi_release(pubKeyOther);\n\n    size_t result;\n    gcry_mpi_print(GCRYMPI_FMT_USG, secret, length, &result, sec);\n    gcry_mpi_release(sec);\n\n    return result;\n}\n\nint32_t ZrtpDH::generatePublicKey()\n{\n    gcryptCtx* tmpCtx = static_cast<gcryptCtx*>(ctx);\n\n    tmpCtx->pubKey = gcry_mpi_new(0);\n    if (pkType == DH2K) {\n        gcry_mpi_powm(tmpCtx->pubKey, two, tmpCtx->privKey, bnP2048);\n    }\n    else if (pkType == DH3K) {\n        gcry_mpi_powm(tmpCtx->pubKey, two, tmpCtx->privKey, bnP3072);\n    }\n    else {\n//\tgcry_mpi_powm(tmpCtx->pubKey, two, tmpCtx->privKey, bnP4096);\n        return 0;\n    }\n    return 1;\n}\n\nint32_t ZrtpDH::getPubKeyBytes(uint8_t *buf) const\n{\n    gcryptCtx* tmpCtx = static_cast<gcryptCtx*>(ctx);\n    int32_t len = getPubKeySize();\n\n    // get length of Dh in bytes, prepend buffer with zeros if necessary\n    int32_t prepend = getDhSize() - getPubKeySize();\n    if (prepend > 0) {\n        memset(buf, 0, prepend);\n    }\n    size_t i = 0;\n    gcry_mpi_print(GCRYMPI_FMT_USG, buf + prepend, len, &i, tmpCtx->pubKey);\n    return i;\n}\n\nint32_t ZrtpDH::getDhSize() const\n{\n    switch (pkType) {\n\tcase DH2K:\n\t    return 2048/8;\n\t    break;\n\tcase DH3K:\n\t    return 3072/8;\n\t    break;\n    }\n    return 0;\n}\n\nint32_t ZrtpDH::getPubKeySize() const\n{\n    return ((gcry_mpi_get_nbits(static_cast<gcryptCtx*>(ctx)->pubKey) + 7) / 8);\n}\n\nint32_t ZrtpDH::checkPubKey(uint8_t *pubKeyBytes) const\n{\n    gcry_mpi_t pubKeyOther = NULL;\n    gcry_mpi_scan(&pubKeyOther, GCRYMPI_FMT_USG, pubKeyBytes, getDhSize(), NULL);\n\n    if (pkType == DH2K) {\n        if (gcry_mpi_cmp(bnP2048MinusOne, pubKeyOther) == 0)\n            return 0;\n    }\n    else if (pkType == DH3K) {\n        if (gcry_mpi_cmp(bnP3072MinusOne, pubKeyOther) == 0)\n            return 0;\n    }\n    else {\n//        if (gcry_mpi_cmp(bnP4096MinusOne, pubKeyOther) == 0)\n            return 0;\n    }\n    if (gcry_mpi_cmp_ui(pubKeyOther, 1) == 0) {\n        return 0;\n    }\n\n    gcry_mpi_release(pubKeyOther);\n    return 1;\n}\n\nconst char* ZrtpDH::getDHtype()\n{\n    switch (pkType) {\n\tcase DH2K:\n\t    return dh2k;\n\t    break;\n\tcase DH3K:\n\t    return dh3k;\n\t    break;\n    }\n    return NULL;\n}\n\n/** EMACS **\n * Local variables:\n * mode: c++\n * c-default-style: ellemtel\n * c-basic-offset: 4\n * End:\n */\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/gcrypt/gcrypthmac256.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Erik Eliasson <eliasson@it.kth.se>\n *          Johan Bilien <jobi@via.ecp.fr>\n */\n\n#include <gcrypt.h>\n#include <crypto/hmac256.h>\n\nvoid hmac_sha256(uint8_t* key, uint32_t keyLength,\n\t\tuint8_t* data, int32_t dataLength,\n                uint8_t* mac, uint32_t* macLength)\n{\n    gcry_md_hd_t hd;\n    gcry_error_t err = 0;\n\n    err = gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);\n    gcry_md_setkey(hd, key, keyLength);\n\n    gcry_md_write (hd, data, dataLength);\n\n    uint8_t* p = gcry_md_read (hd, GCRY_MD_SHA256);\n    memcpy(mac, p, SHA256_DIGEST_LENGTH);\n    if (macLength != NULL) {\n        *macLength = SHA256_DIGEST_LENGTH;\n    }\n    gcry_md_close (hd);\n}\n\nvoid hmac_sha256( uint8_t* key, uint32_t keyLength,\n                  uint8_t* dataChunks[],\n                  uint32_t dataChunkLength[],\n                  uint8_t* mac, uint32_t* macLength )\n{\n    gcry_md_hd_t hd;\n    gcry_error_t err = 0;\n\n    err = gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);\n    gcry_md_setkey(hd, key, keyLength);\n\n    while (*dataChunks) {\n        gcry_md_write (hd, *dataChunks, (uint32_t)(*dataChunkLength));\n\tdataChunks++;\n\tdataChunkLength++;\n    }\n    uint8_t* p = gcry_md_read (hd, GCRY_MD_SHA256);\n    memcpy(mac, p, SHA256_DIGEST_LENGTH);\n    if (macLength != NULL) {\n        *macLength = SHA256_DIGEST_LENGTH;\n    }\n    gcry_md_close (hd);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/gcrypt/gcrypthmac384.cpp",
    "content": "/*\n  Copyright (C) 2006-2009 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Erik Eliasson <eliasson@it.kth.se>\n *          Johan Bilien <jobi@via.ecp.fr>\n */\n\n#include <gcrypt.h>\n#include <crypto/hmac384.h>\n\nvoid hmac_sha384(uint8_t* key, uint32_t keyLength,\n\t\tuint8_t* data, int32_t dataLength,\n                uint8_t* mac, uint32_t* macLength)\n{\n    gcry_md_hd_t hd;\n    gcry_error_t err = 0;\n\n    err = gcry_md_open(&hd, GCRY_MD_SHA384, GCRY_MD_FLAG_HMAC);\n    gcry_md_setkey(hd, key, keyLength);\n\n    gcry_md_write (hd, data, dataLength);\n\n    uint8_t* p = gcry_md_read (hd, GCRY_MD_SHA384);\n    memcpy(mac, p, SHA384_DIGEST_LENGTH);\n    if (macLength != NULL) {\n        *macLength = SHA384_DIGEST_LENGTH;\n    }\n    gcry_md_close (hd);\n}\n\nvoid hmac_sha384( uint8_t* key, uint32_t keyLength,\n                  uint8_t* dataChunks[],\n                  uint32_t dataChunkLength[],\n                  uint8_t* mac, uint32_t* macLength )\n{\n    gcry_md_hd_t hd;\n    gcry_error_t err = 0;\n\n    err = gcry_md_open(&hd, GCRY_MD_SHA384, GCRY_MD_FLAG_HMAC);\n    gcry_md_setkey(hd, key, keyLength);\n\n    while (*dataChunks) {\n        gcry_md_write (hd, *dataChunks, (uint32_t)(*dataChunkLength));\n\tdataChunks++;\n\tdataChunkLength++;\n    }\n    uint8_t* p = gcry_md_read (hd, GCRY_MD_SHA384);\n    memcpy(mac, p, SHA384_DIGEST_LENGTH);\n    if (macLength != NULL) {\n        *macLength = SHA384_DIGEST_LENGTH;\n    }\n    gcry_md_close (hd);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/gcrypt/gcryptsha256.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/**\n * @author Erik Eliasson <eliasson@it.kth.se>\n *          Johan Bilien <jobi@via.ecp.fr>\n *\t    Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <gcrypt.h>\n#include <crypto/sha256.h>\n\nvoid sha256(unsigned char* data, unsigned int dataLength,\n            unsigned char* mac)\n{\n    gcry_md_hash_buffer(GCRY_MD_SHA256, mac, data, dataLength);\n}\n\nvoid sha256(unsigned char* dataChunks[],\n            unsigned int dataChunkLength[],\n            unsigned char* mac)\n{\n    gcry_md_hd_t hd;\n    gcry_error_t err = 0;\n\n    err = gcry_md_open(&hd, GCRY_MD_SHA256, 0);\n    while (*dataChunks) {\n        gcry_md_write (hd, *dataChunks, (uint32_t)(*dataChunkLength));\n        dataChunks++;\n        dataChunkLength++;\n    }\n    uint8_t* p = gcry_md_read (hd, GCRY_MD_SHA256);\n    memcpy(mac, p, SHA256_DIGEST_LENGTH);\n    gcry_md_close (hd);\n}\n\nvoid* createSha256Context()\n{\n    gcry_error_t err = 0;\n    gcry_md_hd_t hd;\n\n    err = gcry_md_open(&hd, GCRY_MD_SHA256, 0);\n    return (void*)hd;\n}\n\nvoid closeSha256Context(void* ctx, unsigned char* digest)\n{\n    gcry_md_hd_t hd = (gcry_md_hd_t)ctx;\n\n    if (digest != NULL) {\n        uint8_t* p = gcry_md_read (hd, GCRY_MD_SHA256);\n        memcpy(digest, p, SHA256_DIGEST_LENGTH);\n    }\n    gcry_md_close (hd);\n}\n\nvoid sha256Ctx(void* ctx, unsigned char* data, \n               unsigned int dataLength)\n{\n    gcry_md_hd_t hd = (gcry_md_hd_t)ctx;\n\n    gcry_md_write (hd, data, dataLength);\n}\n\nvoid sha256Ctx(void* ctx, unsigned char* dataChunks[],\n               unsigned int dataChunkLength[])\n{\n    gcry_md_hd_t hd = (gcry_md_hd_t)ctx;\n\n    while (*dataChunks) {\n        gcry_md_write (hd, *dataChunks, (uint32_t)(*dataChunkLength));\n        dataChunks++;\n        dataChunkLength++;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/gcrypt/gcryptsha384.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/**\n * @author Erik Eliasson <eliasson@it.kth.se>\n *          Johan Bilien <jobi@via.ecp.fr>\n *\t    Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <gcrypt.h>\n#include <crypto/sha384.h>\n\nvoid sha384(unsigned char* data, unsigned int dataLength,\n            unsigned char* mac)\n{\n    gcry_md_hash_buffer(GCRY_MD_SHA384, mac, data, dataLength);\n}\n\nvoid sha384(unsigned char* dataChunks[],\n            unsigned int dataChunkLength[],\n            unsigned char* mac)\n{\n    gcry_md_hd_t hd;\n    gcry_error_t err = 0;\n\n    err = gcry_md_open(&hd, GCRY_MD_SHA384, 0);\n    while (*dataChunks) {\n        gcry_md_write (hd, *dataChunks, (uint32_t)(*dataChunkLength));\n        dataChunks++;\n        dataChunkLength++;\n    }\n    uint8_t* p = gcry_md_read (hd, GCRY_MD_SHA384);\n    memcpy(mac, p, SHA384_DIGEST_LENGTH);\n    gcry_md_close (hd);\n}\n\nvoid* createSha384Context()\n{\n    gcry_error_t err = 0;\n    gcry_md_hd_t hd;\n\n    err = gcry_md_open(&hd, GCRY_MD_SHA384, 0);\n    return (void*)hd;\n}\n\nvoid closeSha384Context(void* ctx, unsigned char* digest)\n{\n    gcry_md_hd_t hd = (gcry_md_hd_t)ctx;\n\n    if (digest != NULL) {\n        uint8_t* p = gcry_md_read (hd, GCRY_MD_SHA384);\n        memcpy(digest, p, SHA384_DIGEST_LENGTH);\n    }\n    gcry_md_close (hd);\n}\n\nvoid sha384Ctx(void* ctx, unsigned char* data, \n               unsigned int dataLength)\n{\n    gcry_md_hd_t hd = (gcry_md_hd_t)ctx;\n\n    gcry_md_write (hd, data, dataLength);\n}\n\nvoid sha384Ctx(void* ctx, unsigned char* dataChunks[],\n               unsigned int dataChunkLength[])\n{\n    gcry_md_hd_t hd = (gcry_md_hd_t)ctx;\n\n    while (*dataChunks) {\n        gcry_md_write (hd, *dataChunks, (uint32_t)(*dataChunkLength));\n        dataChunks++;\n        dataChunkLength++;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/hmac256.cpp",
    "content": "/*\n  Copyright (C) 2012-2013 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/*\n * Authors: Werner Dittmann\n */\n\n#include <stdint.h>\n#include <string.h>\n#include <stdio.h>\n#include \"zrtp/crypto/sha2.h\"\n#include \"zrtp/crypto/hmac256.h\"\n\ntypedef struct _hmacSha256Context {\n    sha256_ctx ctx;\n    sha256_ctx innerCtx;\n    sha256_ctx outerCtx;\n} hmacSha256Context;\n\nstatic int32_t hmacSha256Init(hmacSha256Context *ctx, const uint8_t *key, uint32_t kLength)\n{\n    int32_t i;\n    uint8_t localPad[SHA256_BLOCK_SIZE] = {0};\n    uint8_t localKey[SHA256_BLOCK_SIZE] = {0};\n\n    if (key == NULL)\n        return 0;\n\n    memset(ctx, 0, sizeof(hmacSha256Context));\n\n    /* check key length and reduce it if necessary */\n    if (kLength > SHA256_BLOCK_SIZE) {\n        sha256_begin(&ctx->ctx);\n        sha256_hash(key, kLength, &ctx->ctx);\n        sha256_end(localKey, &ctx->ctx);\n    }\n    else {\n        memcpy(localKey, key, kLength);\n    }\n    /* prepare inner hash and hold the context */\n    for (i = 0; i < SHA256_BLOCK_SIZE; i++)\n        localPad[i] = localKey[i] ^ 0x36;\n\n    sha256_begin(&ctx->innerCtx);\n    sha256_hash(localPad, SHA256_BLOCK_SIZE, &ctx->innerCtx);\n\n    /* prepare outer hash and hold the context */\n    for (i = 0; i < SHA256_BLOCK_SIZE; i++)\n        localPad[i] = localKey[i] ^ 0x5c;\n\n    sha256_begin(&ctx->outerCtx);\n    sha256_hash(localPad, SHA256_BLOCK_SIZE, &ctx->outerCtx);\n\n    /* copy prepared inner hash to work hash - ready to process data */\n    memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha256_ctx));\n\n    memset(localKey, 0, sizeof(localKey));\n\n    return 1;\n}\n\nstatic void hmacSha256Reset(hmacSha256Context *ctx)\n{\n    /* copy prepared inner hash to work hash context */\n    memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha256_ctx));\n}\n\nstatic void hmacSha256Update(hmacSha256Context *ctx, const uint8_t *data, uint32_t dLength)\n{\n    /* hash new data to work hash context */\n    sha256_hash(data, dLength, &ctx->ctx);\n}\n\nstatic void hmacSha256Final(hmacSha256Context *ctx, uint8_t *mac)\n{\n    uint8_t tmpDigest[SHA256_DIGEST_SIZE];\n\n    /* finalize work hash context */\n    sha256_end(tmpDigest, &ctx->ctx);\n\n    /* copy prepared outer hash to work hash */\n    memcpy(&ctx->ctx, &ctx->outerCtx, sizeof(sha256_ctx));\n\n    /* hash inner digest to work (outer) hash context */\n    sha256_hash(tmpDigest, SHA256_DIGEST_SIZE, &ctx->ctx);\n\n    /* finalize work hash context to get the hmac*/\n    sha256_end(mac, &ctx->ctx);\n}\n\n\nvoid hmac_sha256(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)\n{\n    hmacSha256Context ctx;\n\n    hmacSha256Init(&ctx, key, keyLength);\n    hmacSha256Update(&ctx, data, dataLength);\n    hmacSha256Final(&ctx, mac);\n    *macLength = SHA256_DIGEST_SIZE;\n}\n\nvoid hmac_sha256(uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunckLength[],\n                uint8_t* mac, uint32_t* macLength )\n{\n    hmacSha256Context ctx;\n\n    hmacSha256Init(&ctx, key, keyLength);\n\n    while (*dataChunks) {\n        hmacSha256Update(&ctx, *dataChunks, *dataChunckLength);\n        dataChunks ++;\n        dataChunckLength ++;\n    }\n    hmacSha256Final(&ctx, mac);\n    *macLength = SHA256_DIGEST_SIZE;\n}\n\nvoid* createSha256HmacContext(uint8_t* key, int32_t keyLength)\n{\n    hmacSha256Context *ctx = reinterpret_cast<hmacSha256Context*>(malloc(sizeof(hmacSha256Context)));\n\n    if (ctx != NULL) {\n        hmacSha256Init(ctx, key, keyLength);\n    }\n    return ctx;\n}\n\nvoid hmacSha256Ctx(void* ctx, const uint8_t* data, uint32_t dataLength,\n                uint8_t* mac, int32_t* macLength)\n{\n    hmacSha256Context *pctx = (hmacSha256Context*)ctx;\n\n    hmacSha256Reset(pctx);\n    hmacSha256Update(pctx, data, dataLength);\n    hmacSha256Final(pctx, mac);\n    *macLength = SHA256_DIGEST_SIZE;\n}\n\nvoid hmacSha256Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[],\n                uint8_t* mac, int32_t* macLength )\n{\n    hmacSha256Context *pctx = (hmacSha256Context*)ctx;\n\n    hmacSha256Reset(pctx);\n    while (*data) {\n        hmacSha256Update(pctx, *data, *dataLength);\n        data++;\n        dataLength++;\n    }\n    hmacSha256Final(pctx, mac);\n    *macLength = SHA256_DIGEST_SIZE;\n}\n\nvoid freeSha256HmacContext(void* ctx)\n{\n    if (ctx) {\n        memset(ctx, 0, sizeof(hmacSha256Context));\n        free(ctx);\n    }\n}"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/hmac256.h",
    "content": "/*\n  Copyright (C) 2006, 2005, 2004 Erik Eliasson, Johan Bilien, Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n*/\n\n/**\n * Methods to compute a SHA256 HMAC.\n *\n * @author Erik Eliasson <eliasson@it.kth.se>\n * @author Johan Bilien <jobi@via.ecp.fr>\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef HMAC_SHA256_H\n#define HMAC_SHA256_H\n\n/**\n * @file hmac256.h\n * @brief Function that provide SHA256 HMAC support\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <stdint.h>\n\n#ifndef SHA256_DIGEST_LENGTH\n#define SHA256_DIGEST_LENGTH 32\n#endif\n\n/**\n * Compute SHA256 HMAC.\n *\n * This functions takes one data chunk and computes its SHA256 HMAC.\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lneght of the MAC key in bytes\n * @param data\n *    Points to the data chunk.\n * @param data_length\n *    Length of the data in bytes\n * @param mac\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 32 bytes (SHA256_DIGEST_LENGTH).\n * @param mac_length\n *    Point to an integer that receives the length of the computed HMAC.\n */\nvoid hmac_sha256( uint8_t* key, uint32_t key_length,\n    uint8_t* data, int32_t data_length,\n    uint8_t* mac, uint32_t* mac_length );\n\n/**\n * Compute SHA256 HMAC over several data cunks.\n *\n * This functions takes several data chunk and computes the SHA256 HAMAC. It\n * uses the openSSL HAMAC SHA256 implementation.\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lneght of the MAC key in bytes\n * @param data\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param data_length\n *    Points to an array of integers that hold the length of each data chunk.\n * @param mac\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 32 bytes (SHA256_DIGEST_LENGTH).\n * @param mac_length\n *    Point to an integer that receives the length of the computed HMAC.\n */\n\nvoid hmac_sha256( uint8_t* key, uint32_t key_length,\n                           uint8_t* data[], uint32_t data_length[],\n                           uint8_t* mac, uint32_t* mac_length );\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/hmac384.cpp",
    "content": "/*\n  Copyright (C) 2012 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/*\n * Authors: Werner Dittmann\n */\n\n#include <stdint.h>\n#include <string.h>\n#include <stdio.h>\n#include \"zrtp/crypto/sha2.h\"\n#include \"zrtp/crypto/hmac384.h\"\n\ntypedef struct _hmacSha384Context {\n    sha384_ctx ctx;\n    sha384_ctx innerCtx;\n    sha384_ctx outerCtx;\n} hmacSha384Context;\n\nstatic int32_t hmacSha384Init(hmacSha384Context *ctx, const uint8_t *key, uint32_t kLength)\n{\n    int32_t i;\n    uint8_t localPad[SHA384_BLOCK_SIZE] = {0};\n    uint8_t localKey[SHA384_BLOCK_SIZE] = {0};\n\n    if (key == NULL)\n        return 0;\n\n    memset(ctx, 0, sizeof(hmacSha384Context));\n\n    /* check key length and reduce it if necessary */\n    if (kLength > SHA384_BLOCK_SIZE) {\n        sha384_begin(&ctx->ctx);\n        sha384_hash(key, kLength, &ctx->ctx);\n        sha384_end(localKey, &ctx->ctx);\n    }\n    else {\n        memcpy(localKey, key, kLength);\n    }\n    /* prepare inner hash and hold the context */\n    for (i = 0; i < SHA384_BLOCK_SIZE; i++)\n        localPad[i] = localKey[i] ^ 0x36;\n\n    sha384_begin(&ctx->innerCtx);\n    sha384_hash(localPad, SHA384_BLOCK_SIZE, &ctx->innerCtx);\n\n    /* prepare outer hash and hold the context */\n    for (i = 0; i < SHA384_BLOCK_SIZE; i++)\n        localPad[i] = localKey[i] ^ 0x5c;\n\n    sha384_begin(&ctx->outerCtx);\n    sha384_hash(localPad, SHA384_BLOCK_SIZE, &ctx->outerCtx);\n\n    /* copy prepared inner hash to work hash - ready to process data */\n    memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha384_ctx));\n\n    memset(localKey, 0, sizeof(localKey));\n\n    return 1;\n}\n\nstatic void hmacSha384Reset(hmacSha384Context *ctx)\n{\n    /* copy prepared inner hash to work hash context */\n    memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha384_ctx));\n}\n\nstatic void hmacSha384Update(hmacSha384Context *ctx, const uint8_t *data, uint32_t dLength)\n{\n    /* hash new data to work hash context */\n    sha384_hash(data, dLength, &ctx->ctx);\n}\n\nstatic void hmacSha384Final(hmacSha384Context *ctx, uint8_t *mac)\n{\n    uint8_t tmpDigest[SHA384_DIGEST_SIZE];\n\n    /* finalize work hash context */\n    sha384_end(tmpDigest, &ctx->ctx);\n\n    /* copy prepared outer hash to work hash */\n    memcpy(&ctx->ctx, &ctx->outerCtx, sizeof(sha384_ctx));\n\n    /* hash inner digest to work (outer) hash context */\n    sha384_hash(tmpDigest, SHA384_DIGEST_SIZE, &ctx->ctx);\n\n    /* finalize work hash context to get the hmac*/\n    sha384_end(mac, &ctx->ctx);\n}\n\n\nvoid hmac_sha384(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)\n{\n    hmacSha384Context ctx;\n\n    hmacSha384Init(&ctx, key, keyLength);\n    hmacSha384Update(&ctx, data, dataLength);\n    hmacSha384Final(&ctx, mac);\n    *macLength = SHA384_DIGEST_SIZE;\n}\n\nvoid hmac_sha384( uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunckLength[],\n                uint8_t* mac, uint32_t* macLength )\n{\n    hmacSha384Context ctx;\n\n    hmacSha384Init(&ctx, key, keyLength);\n\n    while (*dataChunks) {\n        hmacSha384Update(&ctx, *dataChunks, *dataChunckLength);\n        dataChunks ++;\n        dataChunckLength ++;\n    }\n    hmacSha384Final(&ctx, mac);\n    *macLength = SHA384_DIGEST_SIZE;\n}\n\nvoid* createSha384HmacContext(uint8_t* key, int32_t keyLength)\n{\n    hmacSha384Context *ctx = reinterpret_cast<hmacSha384Context*>(malloc(sizeof(hmacSha384Context)));\n\n    if (ctx != NULL) {\n        hmacSha384Init(ctx, key, keyLength);\n    }\n    return ctx;\n}\n\nvoid hmacSha384Ctx(void* ctx, const uint8_t* data, uint32_t dataLength,\n                uint8_t* mac, int32_t* macLength)\n{\n    hmacSha384Context *pctx = (hmacSha384Context*)ctx;\n\n    hmacSha384Reset(pctx);\n    hmacSha384Update(pctx, data, dataLength);\n    hmacSha384Final(pctx, mac);\n    *macLength = SHA384_DIGEST_SIZE;\n}\n\nvoid hmacSha384Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[],\n                uint8_t* mac, int32_t* macLength )\n{\n    hmacSha384Context *pctx = (hmacSha384Context*)ctx;\n\n    hmacSha384Reset(pctx);\n    while (*data) {\n        hmacSha384Update(pctx, *data, *dataLength);\n        data++;\n        dataLength++;\n    }\n    hmacSha384Final(pctx, mac);\n    *macLength = SHA384_DIGEST_SIZE;\n}\n\nvoid freeSha384HmacContext(void* ctx)\n{\n    if (ctx) {\n        memset(ctx, 0, sizeof(hmacSha384Context));\n        free(ctx);\n    }\n}"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/hmac384.h",
    "content": "/*\n  Copyright (C) 2009, 2006, 2005, 2004 Erik Eliasson, Johan Bilien, Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n*/\n\n/**\n * Methods to compute a SHA384 HMAC.\n *\n * @author Erik Eliasson <eliasson@it.kth.se>\n * @author Johan Bilien <jobi@via.ecp.fr>\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef HMAC_SHA384_H\n#define HMAC_SHA384_H\n\n/**\n * @file hmac384.h\n * @brief Function that provide SHA384 HMAC support\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <stdint.h>\n\n#ifndef SHA384_DIGEST_LENGTH\n#define SHA384_DIGEST_LENGTH 48\n#endif\n\n/**\n * Compute SHA384 HMAC.\n *\n * This functions takes one data chunk and computes its SHA384 HMAC.\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lneght of the MAC key in bytes\n * @param data\n *    Points to the data chunk.\n * @param data_length\n *    Length of the data in bytes\n * @param mac\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 48 bytes (SHA384_DIGEST_LENGTH).\n * @param mac_length\n *    Point to an integer that receives the length of the computed HMAC.\n */\nvoid hmac_sha384( uint8_t* key, uint32_t key_length,\n    uint8_t* data, int32_t data_length,\n    uint8_t* mac, uint32_t* mac_length );\n\n/**\n * Compute SHA384 HMAC over several data cunks.\n *\n * This functions takes several data chunk and computes the SHA384 HAMAC. It\n * uses the openSSL HAMAC SHA384 implementation.\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lneght of the MAC key in bytes\n * @param data\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param data_length\n *    Points to an array of integers that hold the length of each data chunk.\n * @param mac\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 48 bytes (SHA384_DIGEST_LENGTH).\n * @param mac_length\n *    Point to an integer that receives the length of the computed HMAC.\n */\n\nvoid hmac_sha384( uint8_t* key, uint32_t key_length,\n                           uint8_t* data[], uint32_t data_length[],\n                           uint8_t* mac, uint32_t* mac_length );\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/openssl/InitializeOpenSSL.cpp",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software; you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation; either version 2, or (at your option)\n  any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Boston, MA 02111.\n*/\n\n#include <stdio.h>\n#include <openssl/evp.h>\n#include <config.h>\n\n#ifdef _MSWINDOWS_\n#include <windows.h>\n#endif\n#if defined SOLARIS && !defined HAVE_PTHREAD_H\n#include <synch.h>\n#include <thread.h>\n#endif\n#if !defined _MSWINDOWS_ && !defined SOLARIS\n#include <pthread.h>\n#endif\n\n#ifdef  const\n#undef  const\n#endif\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic push\n#  pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n#endif\n\n\nstatic void threadLockSetup(void);\nstatic void threadLockCleanup(void);\nstatic void myLockingCallback(int, int, const char *, int);\n\n/**\n * Implement the locking callback functions for openSSL.\n *\n * Unfortunatly we can't use the Commonc++ Mutex here because the\n * Mutex may use (for some cases) the Commonc++ Thread class. OpenSSL\n * does not use this Thread class.\n */\n\nstatic int initialized = 0;\n\nint initializeOpenSSL ()\n{\n\n    if (initialized) {\n    return 1;\n    }\n    initialized = 1;\n    threadLockSetup();\n    return 1;\n}\n\nint finalizeOpenSSL ()\n{\n    if(!initialized)\n        return 1;\n\n    initialized = 0;\n    threadLockCleanup();\n    return 1;\n}\n\n#ifdef _MSWINDOWS_\n\nstatic HANDLE *lock_cs;\n\nstatic void threadLockSetup(void) {\n    int i;\n\n    lock_cs=(HANDLE*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE));\n    for (i = 0; i < CRYPTO_num_locks(); i++) {\n    lock_cs[i] = CreateMutex(NULL,FALSE,NULL);\n    }\n\n    CRYPTO_set_locking_callback((void (*)(int,int,const char *,int))myLockingCallback);\n    /* id callback defined */\n}\n\nstatic void threadLockCleanup(void) {\n    int i;\n\n    CRYPTO_set_locking_callback(NULL);\n    for (i = 0; i < CRYPTO_num_locks(); i++) {\n    CloseHandle(lock_cs[i]);\n    }\n    OPENSSL_free(lock_cs);\n}\n\nstatic void myLockingCallback(int mode, int type, const char *file, int line) {\n    if (mode & CRYPTO_LOCK) {\n    WaitForSingleObject(lock_cs[type], INFINITE);\n    }\n    else {\n    ReleaseMutex(lock_cs[type]);\n    }\n}\n\n#endif /* OPENSSL_SYS_WIN32 */\n\n\n#if defined SOLARIS && !defined HAVE_PTHREAD_H\n\nstatic mutex_t *lock_cs;\nstatic long *lock_count;\n\nstatic void threadLockSetup(void) {\n    int i;\n\n    lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t));\n    lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));\n    for (i = 0; i < CRYPTO_num_locks(); i++) {\n    lock_count[i] = 0;\n    /* rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL); */\n    mutex_init(&(lock_cs[i]), USYNC_THREAD, NULL);\n    }\n    CRYPTO_set_locking_callback((void (*)(int, int ,const char *, int))myLockingCallback);\n}\n\nstatic void threadLockCleanup(void) {\n    int i;\n\n    CRYPTO_set_locking_callback(NULL);\n\n    fprintf(stderr,\"cleanup\\n\");\n\n    for (i = 0; i < CRYPTO_num_locks(); i++) {\n    /* rwlock_destroy(&(lock_cs[i])); */\n    mutex_destroy(&(lock_cs[i]));\n    fprintf(stderr,\"%8ld:%s\\n\",lock_count[i],CRYPTO_get_lock_name(i));\n    }\n    OPENSSL_free(lock_cs);\n    OPENSSL_free(lock_count);\n}\n\nstatic void myLockingCallback(int mode, int type, const char *file, int line)\n{\n#ifdef undef\n    fprintf(stderr,\"thread=%4d mode=%s lock=%s %s:%d\\n\",\n        CRYPTO_thread_id(),\n        (mode&CRYPTO_LOCK)?\"l\":\"u\",\n        (type&CRYPTO_READ)?\"r\":\"w\",file,line);\n#endif\n\n    /*\n      if (CRYPTO_LOCK_SSL_CERT == type)\n      fprintf(stderr,\"(t,m,f,l) %ld %d %s %d\\n\",\n      CRYPTO_thread_id(),\n      mode,file,line);\n    */\n    if (mode & CRYPTO_LOCK) {\n    mutex_lock(&(lock_cs[type]));\n    lock_count[type]++;\n    }\n    else {\n    mutex_unlock(&(lock_cs[type]));\n    }\n}\n\nstatic unsigned long solaris_thread_id(void) {\n    unsigned long ret;\n\n    ret=(unsigned long)thr_self();\n    return(ret);\n}\n#endif /* SOLARIS */\n\n#if !defined _MSWINDOWS_ && !defined SOLARIS\n\nstatic pthread_mutex_t* lock_cs;\nstatic long* lock_count;\n\nstatic void threadLockSetup(void) {\n    int i;\n\n    lock_cs = (pthread_mutex_t*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));\n    lock_count = (long*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));\n    for (i = 0; i < CRYPTO_num_locks(); i++) {\n    lock_count[i] = 0;\n    pthread_mutex_init(&(lock_cs[i]),NULL);\n    }\n\n    // CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);\n    CRYPTO_set_locking_callback((void (*)(int,int,const char *, int))myLockingCallback);\n}\n\nstatic void threadLockCleanup(void)\n{\n    int i;\n\n    CRYPTO_set_locking_callback(NULL);\n    fprintf(stderr,\"cleanup\\n\");\n    for (i = 0; i < CRYPTO_num_locks(); i++) {\n    pthread_mutex_destroy(&(lock_cs[i]));\n    fprintf(stderr,\"%8ld:%s\\n\",lock_count[i],\n        CRYPTO_get_lock_name(i));\n    }\n    OPENSSL_free(lock_cs);\n    OPENSSL_free(lock_count);\n}\n\nstatic void myLockingCallback(int mode, int type, const char *file,\n                  int line) {\n#ifdef undef\n    fprintf(stderr,\"thread=%4d mode=%s lock=%s %s:%d\\n\",\n        CRYPTO_thread_id(),\n        (mode&CRYPTO_LOCK)?\"l\":\"u\",\n        (type&CRYPTO_READ)?\"r\":\"w\",file,line);\n#endif\n    if (mode & CRYPTO_LOCK) {\n    pthread_mutex_lock(&(lock_cs[type]));\n    lock_count[type]++;\n    }\n    else {\n    pthread_mutex_unlock(&(lock_cs[type]));\n    }\n}\n#endif /* !defined _MSWINDOWS_ && !defined SOLARIS */\n/*\nstatic unsigned long pthreads_thread_id(void)\n{\n    unsigned long ret;\n\n    ret = (unsigned long)pthread_self();\n    return(ret);\n}\n*/\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic pop\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/openssl/aesCFB.cpp",
    "content": "/*\n  Copyright (C) 2006, 2007 by Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/** Copyright (C) 2006, 2007\n *\n * @author  Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <openssl/crypto.h>\n#include <openssl/aes.h>\n#include <string.h>\n\n#include <zrtp/crypto/aesCFB.h>\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic push\n#  pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n#endif\n\n// extern void initializeOpenSSL();\n\nvoid aesCfbEncrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,\n                   int32_t dataLength)\n{\n    AES_KEY aesKey;\n    int usedBytes = 0;\n\n//    initializeOpenSSL();\n\n    memset(&aesKey, 0, sizeof( AES_KEY ) );\n    if (keyLength == 16) {\n        AES_set_encrypt_key(key, 128, &aesKey);\n    }\n    else if (keyLength == 32) {\n        AES_set_encrypt_key(key, 256, &aesKey);\n    }\n    else {\n        return;\n    }\n    AES_cfb128_encrypt(data, data, dataLength, &aesKey,\n                       IV, &usedBytes, AES_ENCRYPT);\n}\n\n\nvoid aesCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,\n                   int32_t dataLength)\n{\n    AES_KEY aesKey;\n    int usedBytes = 0;\n\n//    initializeOpenSSL();\n\n    memset(&aesKey, 0, sizeof( AES_KEY ) );\n    if (keyLength == 16) {\n        AES_set_encrypt_key(key, 128, &aesKey);\n    }\n    else if (keyLength == 32) {\n        AES_set_encrypt_key(key, 256, &aesKey);\n    }\n    else {\n        return;\n    }\n    AES_cfb128_encrypt(data, data, dataLength, &aesKey,\n                       IV, &usedBytes, AES_DECRYPT);\n}\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic pop\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/openssl/hmac256.cpp",
    "content": "/*\n  Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n\n*/\n\n/*\n * Authors: Erik Eliasson <eliasson@it.kth.se>\n *          Johan Bilien <jobi@via.ecp.fr>\n */\n\n#include <openssl/hmac.h>\n#include <crypto/hmac256.h>\n\n#include \"openssl_compat.h\"\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic push\n#  pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n#endif\n\nvoid hmac_sha256(uint8_t* key, uint32_t key_length,\n\t\tuint8_t* data, int32_t data_length,\n                uint8_t* mac, uint32_t* mac_length)\n{\n    unsigned int tmp;\n    HMAC( EVP_sha256(), key, key_length, data, data_length, mac, &tmp );\n    *mac_length = tmp;\n}\n\nvoid hmac_sha256(uint8_t* key, uint32_t key_length,\n                 uint8_t* data_chunks[],\n                 uint32_t data_chunck_length[],\n                 uint8_t* mac, uint32_t* mac_length )\n{\n    unsigned int tmp;\n    HMAC_CTX* ctx = HMAC_CTX_new();\n    HMAC_Init_ex( ctx, key, key_length, EVP_sha256(), NULL );\n    while( *data_chunks ){\n      HMAC_Update( ctx, *data_chunks, *data_chunck_length );\n      data_chunks ++;\n      data_chunck_length ++;\n    }\n    HMAC_Final( ctx, mac, &tmp);\n    *mac_length = tmp;\n    HMAC_CTX_free( ctx );\n}\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic pop\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/openssl/hmac384.cpp",
    "content": "/*\n  Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n\n*/\n\n/*\n * Authors: Erik Eliasson <eliasson@it.kth.se>\n *          Johan Bilien <jobi@via.ecp.fr>\n */\n\n#include <openssl/hmac.h>\n#include <zrtp/crypto/hmac256.h>\n\n#include \"openssl_compat.h\"\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic push\n#  pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n#endif\n\nvoid hmac_sha384(uint8_t* key, uint32_t key_length, uint8_t* data, int32_t data_length, uint8_t* mac, uint32_t* mac_length)\n{\n    unsigned int tmp;\n    HMAC( EVP_sha384(), key, key_length, data, data_length, mac, &tmp );\n    *mac_length = tmp;\n}\n\nvoid hmac_sha384(uint8_t* key, uint32_t key_length,\n                 uint8_t* data_chunks[],\n                 uint32_t data_chunck_length[],\n                 uint8_t* mac, uint32_t* mac_length )\n{\n    unsigned int tmp;\n    HMAC_CTX* ctx = HMAC_CTX_new();\n    HMAC_Init_ex( ctx, key, key_length, EVP_sha384(), NULL );\n    while( *data_chunks ){\n      HMAC_Update( ctx, *data_chunks, *data_chunck_length );\n      data_chunks ++;\n      data_chunck_length ++;\n    }\n    HMAC_Final( ctx, mac, &tmp);\n    *mac_length = tmp;\n    HMAC_CTX_free( ctx );\n}\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic pop\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/openssl/sha256.cpp",
    "content": "/*\n  Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/**\n * @author Erik Eliasson <eliasson@it.kth.se>\n *          Johan Bilien <jobi@via.ecp.fr>\n *\t    Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <openssl/crypto.h>\n#include <openssl/sha.h>\n\n#include <crypto/sha256.h>\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic push\n#  pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n#endif\n\nvoid sha256(unsigned char *data, unsigned int data_length,\n\t    unsigned char *digest )\n{\n\tSHA256(data, data_length, digest);\n}\n\nvoid sha256(unsigned char * data_chunks[],\n\t    unsigned int data_chunck_length[],\n\t    unsigned char *digest)\n{\n\tSHA256_CTX ctx;\n\tSHA256_Init( &ctx);\n\twhile(*data_chunks) {\n\t\tSHA256_Update(&ctx, *data_chunks, *data_chunck_length);\n\t\tdata_chunks++;\n\t\tdata_chunck_length++;\n\t}\n\tSHA256_Final(digest, &ctx);\n}\n\nvoid* createSha256Context()\n{\n    SHA256_CTX* ctx = (SHA256_CTX*)malloc(sizeof (SHA256_CTX));\n    if (ctx == NULL)\n        return NULL;\n    SHA256_Init(ctx);\n    return (void*)ctx;\n}\n\nvoid closeSha256Context(void* ctx, unsigned char* digest)\n{\n    SHA256_CTX* hd = (SHA256_CTX*)ctx;\n\n    if (digest != NULL && hd != NULL) {\n        SHA256_Final(digest, hd);\n    }\n    free(hd);\n}\n\nvoid* initializeSha256Context(void* ctx) \n{\n    SHA256_CTX* hd = (SHA256_CTX*)ctx;\n    SHA256_Init(hd);\n    return (void*)hd;\n}\n\nvoid finalizeSha256Context(void* ctx, unsigned char* digest)\n{\n    SHA256_CTX* hd = (SHA256_CTX*)ctx;\n    if (digest != NULL && hd != NULL) {\n        SHA256_Final(digest, hd);\n    }\n}\n\nvoid sha256Ctx(void* ctx, unsigned char* data, \n               unsigned int dataLength)\n{\n    SHA256_CTX* hd = (SHA256_CTX*)ctx;\n    SHA256_Update(hd, data, dataLength);\n}\n\nvoid sha256Ctx(void* ctx, unsigned char* dataChunks[],\n               unsigned int dataChunkLength[])\n{\n    SHA256_CTX* hd = (SHA256_CTX*)ctx;\n\n    while (*dataChunks) {\n        SHA256_Update (hd, *dataChunks, *dataChunkLength);\n        dataChunks++;\n        dataChunkLength++;\n    }\n}\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic pop\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/openssl/sha384.cpp",
    "content": "/*\n  Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/**\n * @author Erik Eliasson <eliasson@it.kth.se>\n *          Johan Bilien <jobi@via.ecp.fr>\n *\t    Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <openssl/crypto.h>\n#include <openssl/sha.h>\n\n#include <crypto/sha384.h>\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic push\n#  pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n#endif\n\nvoid sha384(unsigned char *data, unsigned int data_length,\n\t    unsigned char *digest )\n{\n\tSHA384(data, data_length, digest);\n}\n\nvoid sha384(unsigned char * data_chunks[],\n\t    unsigned int data_chunck_length[],\n\t    unsigned char *digest)\n{\n\tSHA512_CTX ctx;\n\tSHA384_Init( &ctx);\n\twhile(*data_chunks) {\n\t\tSHA384_Update(&ctx, *data_chunks, *data_chunck_length);\n\t\tdata_chunks++;\n\t\tdata_chunck_length++;\n\t}\n\tSHA384_Final(digest, &ctx);\n}\n\nvoid* createSha384Context()\n{\n    SHA512_CTX* ctx = (SHA512_CTX*)malloc(sizeof (SHA512_CTX));\n    if (ctx == NULL)\n        return NULL;\n    SHA384_Init(ctx);\n    return (void*)ctx;\n}\n\nvoid closeSha384Context(void* ctx, unsigned char* digest)\n{\n    SHA512_CTX* hd = (SHA512_CTX*)ctx;\n\n    if (digest != NULL) {\n        SHA384_Final(digest, hd);\n    }\n    free(hd);\n}\n\nvoid* initializeSha384Context(void* ctx)\n{\n    SHA512_CTX* hd = (SHA512_CTX*)ctx;\n    SHA384_Init(hd);\n    return (void*)hd;\n}\n\nvoid finalizeSha384Context(void* ctx, unsigned char* digest)\n{\n    SHA512_CTX* hd = (SHA512_CTX*)ctx;\n\n    if (digest != NULL) {\n        SHA384_Final(digest, hd);\n    }\n}\n\nvoid sha384Ctx(void* ctx, unsigned char* data, \n               unsigned int dataLength)\n{\n    SHA512_CTX* hd = (SHA512_CTX*)ctx;\n    SHA384_Update(hd, data, dataLength);\n}\n\nvoid sha384Ctx(void* ctx, unsigned char* dataChunks[],\n               unsigned int dataChunkLength[])\n{\n    SHA512_CTX* hd = (SHA512_CTX*)ctx;\n\n    while (*dataChunks) {\n        SHA384_Update (hd, *dataChunks, *dataChunkLength);\n        dataChunks++;\n        dataChunkLength++;\n    }\n}\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic pop\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/openssl/zrtpDH.cpp",
    "content": "/*\n  Copyright (C) 2006, 2009 by Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/** Copyright (C) 2006, 2009\n *\n * @author  Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <string.h>\n\n#include <openssl/crypto.h>\n#include <openssl/bio.h>\n#include <openssl/bn.h>\n#include <openssl/rand.h>\n#include <openssl/err.h>\n#include <openssl/dh.h>\n#include <openssl/evp.h>\n#include <openssl/ec.h>\n#include <openssl/ecdh.h>\n\n#include <zrtp/crypto/zrtpDH.h>\n#include <zrtp/libzrtpcpp/ZrtpTextData.h>\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic push\n#  pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n#endif\n\n// extern void initializeOpenSSL();\n\nstatic BIGNUM* bnP2048 = NULL;\nstatic BIGNUM* bnP3072 = NULL;\n// static BIGNUM* bnP4096 = NULL;\n\nstatic BIGNUM* bnP2048MinusOne = NULL;\nstatic BIGNUM* bnP3072MinusOne = NULL;\n// static BIGNUM* bnP4096MinusOne = NULL;\n\nstatic uint8_t dhinit = 0;\n\nvoid randomZRTP(uint8_t *buf, int32_t length)\n{\n//    initializeOpenSSL();\n    RAND_bytes(buf, length);\n}\n\nstatic const uint8_t P2048[] =\n{\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,\n    0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,\n    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,\n    0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,\n    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,\n    0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,\n    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,\n    0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,\n    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,\n    0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,\n    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,\n    0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,\n    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,\n    0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,\n    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,\n    0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,\n    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,\n    0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,\n    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,\n    0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,\n    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xFF, 0xFF, 0xFF, 0xFF\n};\n\nstatic const uint8_t P3072[] =\n{\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,\n    0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,\n    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,\n    0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,\n    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,\n    0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,\n    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,\n    0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,\n    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,\n    0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,\n    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,\n    0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,\n    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,\n    0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,\n    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,\n    0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,\n    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,\n    0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,\n    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,\n    0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,\n    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,\n    0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,\n    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,\n    0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,\n    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,\n    0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,\n    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,\n    0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,\n    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,\n    0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,\n    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,\n    0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\n\n/* **************\nstatic const uint8_t P4096[] =\n{\n0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,\n0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,\n0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,\n0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,\n0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,\n0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,\n0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,\n0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,\n0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,\n0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,\n0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,\n0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,\n0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,\n0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,\n0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,\n0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,\n0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,\n0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,\n0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,\n0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,\n0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,\n0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,\n0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,\n0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,\n0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,\n0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,\n0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,\n0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,\n0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,\n0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,\n0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,\n0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,\n0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,\n0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,\n0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,\n0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,\n0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,\n0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,\n0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,\n0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,\n0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,\n0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,\n0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\n*************** */\n\nZrtpDH::ZrtpDH(const char* type) {\n\n    uint8_t random[64];\n\n    // Well - the algo type is only 4 char thus cast to int32 and compare\n    if (*(int32_t*)type == *(int32_t*)dh2k) {\n        pkType = DH2K;\n    }\n    else if (*(int32_t*)type == *(int32_t*)dh3k) {\n        pkType = DH3K;\n    }\n    else if (*(int32_t*)type == *(int32_t*)ec25) {\n        pkType = EC25;\n    }\n    else if (*(int32_t*)type == *(int32_t*)ec38) {\n        pkType = EC38;\n    }\n    else {\n        return;\n    }\n\n//  initializeOpenSSL();\n\n    if (!dhinit) {\n        bnP2048 = BN_bin2bn(P2048,sizeof(P2048),NULL);\n        bnP3072 = BN_bin2bn(P3072,sizeof(P3072),NULL);\n//      bnP4096 = BN_bin2bn(P4096,sizeof(P4096),NULL);\n\n        bnP2048MinusOne = BN_dup(bnP2048);\n        BN_sub_word(bnP2048MinusOne, 1);\n\n        bnP3072MinusOne = BN_dup(bnP3072);\n        BN_sub_word(bnP3072MinusOne, 1);\n\n//      bnP4096MinusOne = BN_dup(bnP4096);\n//      BN_sub_word(bnP4096MinusOne, 1);\n        dhinit = 1;\n    }\n\n    DH* tmpCtx = NULL;\n    BIGNUM *p = NULL;\n    BIGNUM* priv_key = NULL;\n    BIGNUM *g = BN_new();\n    switch (pkType) {\n    case DH2K:\n    case DH3K:\n        ctx = static_cast<void*>(DH_new());\n        tmpCtx = static_cast<DH*>(ctx);\n        BN_set_word(g, DH_GENERATOR_2);\n\n        if (pkType == DH2K) {\n            p = BN_dup(bnP2048);\n            RAND_bytes(random, 32);\n            priv_key = BN_bin2bn(random, 32, NULL);\n        }\n        else if (pkType == DH3K) {\n            p = BN_dup(bnP3072);\n            RAND_bytes(random, 64);\n            priv_key = BN_bin2bn(random, 32, NULL);\n        }\n\n#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined (LIBRESSL_VERSION_NUMBER)\n        tmpCtx->g = g;\n        tmpCtx->p = p;\n        tmpCtx->priv_key = priv_key;\n#else\n        DH_set0_pqg(tmpCtx, p, NULL, g);\n        DH_set0_key(tmpCtx, NULL, priv_key);\n#endif\n        break;\n\n    case EC25:\n        ctx = static_cast<void*>(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));\n        break;\n    case EC38:\n        ctx = static_cast<void*>(EC_KEY_new_by_curve_name(NID_secp384r1));\n        break;\n    }\n}\n\nZrtpDH::~ZrtpDH() {\n    if (ctx == NULL)\n        return;\n\n    switch (pkType) {\n    case DH2K:\n    case DH3K:\n        DH_free(static_cast<DH*>(ctx));\n        break;\n\n    case EC25:\n    case EC38:\n        EC_KEY_free(static_cast<EC_KEY*>(ctx));\n        break;\n    }\n}\n\nint32_t ZrtpDH::computeSecretKey(uint8_t *pubKeyBytes, uint8_t *secret) {\n\n    if (pkType == DH2K || pkType == DH3K) {\n        DH* tmpCtx = static_cast<DH*>(ctx);\n\n        BIGNUM* pub_key = BN_bin2bn(pubKeyBytes, getDhSize(), NULL);\n#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined (LIBRESSL_VERSION_NUMBER)\n        if (tmpCtx->pub_key != NULL) {\n          BN_free(tmpCtx->pub_key);\n        }\n        tmpCtx->pub_key = pub_key;\n#else\n        DH_set0_key(tmpCtx, pub_key, NULL);\n#endif\n        return DH_compute_key(secret, pub_key, tmpCtx);\n    }\n    if (pkType == EC25 || pkType == EC38) {\n        uint8_t buffer[100];\n        int32_t ret;\n        int32_t len = getPubKeySize();\n\n        buffer[0] = POINT_CONVERSION_UNCOMPRESSED;\n        memcpy(buffer+1, pubKeyBytes, len);\n        \n        EC_POINT* point = EC_POINT_new(EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)));\n        EC_POINT_oct2point(EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)),\n                                             point, buffer, len+1, NULL);\n        ret = ECDH_compute_key(secret, getDhSize(), point, static_cast<EC_KEY*>(ctx), NULL);\n        EC_POINT_free(point);\n        return ret;\n    }\n    return -1;\n}\n\nint32_t ZrtpDH::generatePublicKey()\n{\n    if (pkType == DH2K || pkType == DH3K)\n        return DH_generate_key(static_cast<DH*>(ctx));\n\n    if (pkType == EC25 || pkType == EC38)\n        return EC_KEY_generate_key(static_cast<EC_KEY*>(ctx));\n    return 0;\n}\n\nint32_t ZrtpDH::getDhSize() const\n{\n    if (pkType == DH2K || pkType == DH3K)\n        return DH_size(static_cast<DH*>(ctx));\n\n    if (pkType == EC25)\n        return 32;\n    if (pkType == EC38)\n        return 48;\n\n    return 0;\n}\n\nint32_t ZrtpDH::getPubKeySize() const\n{\n    if (pkType == DH2K || pkType == DH3K){\n        const BIGNUM* pub_key;\n#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined (LIBRESSL_VERSION_NUMBER)\n        pub_key = static_cast<DH*>(ctx)->pub_key;\n#else\n        DH_get0_key(static_cast<DH*>(ctx), &pub_key, NULL);\n#endif\n        return BN_num_bytes(pub_key);\n    }\n\n    if (pkType == EC25 || pkType == EC38)\n        return EC_POINT_point2oct(EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)),\n                                  EC_KEY_get0_public_key(static_cast<EC_KEY*>(ctx)),\n                                  POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL) - 1;\n    return 0;\n\n}\n\nint32_t ZrtpDH::getPubKeyBytes(uint8_t *buf) const\n{\n\n    if (pkType == DH2K || pkType == DH3K) {\n        // get len of pub_key, prepend with zeros to DH size\n        int32_t prepend = getDhSize() - getPubKeySize();\n        if (prepend > 0) {\n            memset(buf, 0, prepend);\n        }\n        const BIGNUM* pub_key;\n#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined (LIBRESSL_VERSION_NUMBER)\n        pub_key = static_cast<DH*>(ctx)->pub_key;\n#else\n        DH_get0_key(static_cast<DH*>(ctx), &pub_key, NULL);\n#endif\n        return BN_bn2bin(pub_key, buf + prepend);\n    }\n    if (pkType == EC25 || pkType == EC38) {\n        uint8_t buffer[100];\n\n        int len = EC_POINT_point2oct(EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)),\n                                     EC_KEY_get0_public_key(static_cast<EC_KEY*>(ctx)),\n                                     POINT_CONVERSION_UNCOMPRESSED, buffer, 100, NULL);\n        memcpy(buf, buffer+1, len-1);\n        return len-1;\n    }\n    return 0;\n}\n\nint32_t ZrtpDH::checkPubKey(uint8_t *pubKeyBytes) const\n{\n    if (pkType == EC25 || pkType == EC38) {\n        uint8_t buffer[100];\n        int32_t ret;\n        int32_t len = getPubKeySize();\n\n        buffer[0] = POINT_CONVERSION_UNCOMPRESSED;\n        memcpy(buffer+1, pubKeyBytes, len);\n\n        EC_POINT* point = EC_POINT_new(EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)));\n        EC_POINT_oct2point(EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)),\n                                             point, buffer, len+1, NULL);\n        EC_KEY* chkKey = EC_KEY_new();\n        EC_KEY_set_group(chkKey, EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)));\n        EC_KEY_set_public_key(chkKey, point);\n        ret = EC_KEY_check_key(chkKey);\n\n        EC_POINT_free(point);\n        EC_KEY_free(chkKey);\n        \n        return ret;\n    }\n\n    BIGNUM* pubKeyOther = BN_bin2bn(pubKeyBytes, getDhSize(), NULL);\n\n    if (pkType == DH2K) {\n        if (BN_cmp(bnP2048MinusOne, pubKeyOther) == 0)\n            return 0;\n    }\n    else if (pkType == DH3K) {\n        if (BN_cmp(bnP3072MinusOne, pubKeyOther) == 0)\n            return 0;\n    }\n    else {\n//        if (BN_cmp(bnP4096MinusOne, pubKeyOther) == 0)\n        return 0;\n    }\n    int one = BN_is_one(pubKeyOther);\n    if (one == 1)\n        return 0;\n\n    BN_free(pubKeyOther);\n    return 1;\n}\n\nconst char* ZrtpDH::getDHtype()\n{\n    switch (pkType) {\n    case DH2K:\n        return dh2k;\n        break;\n    case DH3K:\n        return dh3k;\n        break;\n    case EC25:\n        return ec25;\n        break;\n    case EC38:\n        return ec38;\n        break;\n    }\n    return NULL;\n}\n\n#if defined(__APPLE__)\n#  pragma GCC diagnostic pop\n#endif\n\n/** EMACS **\n * Local variables:\n * mode: c++\n * c-default-style: ellemtel\n * c-basic-offset: 4\n * End:\n */\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/sha2.c",
    "content": "/*\n ---------------------------------------------------------------------------\n Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.\n\n LICENSE TERMS\n\n The free distribution and use of this software in both source and binary\n form is allowed (with or without changes) provided that:\n\n   1. distributions of this source code include the above copyright\n      notice, this list of conditions and the following disclaimer;\n\n   2. distributions in binary form include the above copyright\n      notice, this list of conditions and the following disclaimer\n      in the documentation and/or other associated materials;\n\n   3. the copyright holder's name is not used to endorse products\n      built using this software without specific written permission.\n\n ALTERNATIVELY, provided that this notice is retained in full, this product\n may be distributed under the terms of the GNU General Public License (GPL),\n in which case the provisions of the GPL apply INSTEAD OF those given above.\n\n DISCLAIMER\n\n This software is provided 'as is' with no explicit or implied warranties\n in respect of its properties, including, but not limited to, correctness\n and/or fitness for purpose.\n ---------------------------------------------------------------------------\n Issue Date: 01/08/2005\n\n This is a byte oriented version of SHA2 that operates on arrays of bytes\n stored in memory. This code implements sha256, sha384 and sha512 but the\n latter two functions rely on efficient 64-bit integer operations that\n may not be very efficient on 32-bit machines\n\n The sha256 functions use a type 'sha256_ctx' to hold details of the\n current hash state and uses the following three calls:\n\n       void sha256_begin(sha256_ctx ctx[1])\n       void sha256_hash(const unsigned char data[],\n                            unsigned long len, sha256_ctx ctx[1])\n       void sha_end1(unsigned char hval[], sha256_ctx ctx[1])\n\n The first subroutine initialises a hash computation by setting up the\n context in the sha256_ctx context. The second subroutine hashes 8-bit\n bytes from array data[] into the hash state withinh sha256_ctx context,\n the number of bytes to be hashed being given by the the unsigned long\n integer len.  The third subroutine completes the hash calculation and\n places the resulting digest value in the array of 8-bit bytes hval[].\n\n The sha384 and sha512 functions are similar and use the interfaces:\n\n       void sha384_begin(sha384_ctx ctx[1]);\n       void sha384_hash(const unsigned char data[],\n                            unsigned long len, sha384_ctx ctx[1]);\n       void sha384_end(unsigned char hval[], sha384_ctx ctx[1]);\n\n       void sha512_begin(sha512_ctx ctx[1]);\n       void sha512_hash(const unsigned char data[],\n                            unsigned long len, sha512_ctx ctx[1]);\n       void sha512_end(unsigned char hval[], sha512_ctx ctx[1]);\n\n In addition there is a function sha2 that can be used to call all these\n functions using a call with a hash length parameter as follows:\n\n       int sha2_begin(unsigned long len, sha2_ctx ctx[1]);\n       void sha2_hash(const unsigned char data[],\n                            unsigned long len, sha2_ctx ctx[1]);\n       void sha2_end(unsigned char hval[], sha2_ctx ctx[1]);\n\n My thanks to Erik Andersen <andersen@codepoet.org> for testing this code\n on big-endian systems and for his assistance with corrections\n*/\n\n#if 0\n#define UNROLL_SHA2     /* for SHA2 loop unroll     */\n#endif\n\n#include <string.h>     /* for memcpy() etc.        */\n\n#include \"sha2.h\"\n\n#include <cryptcommon/brg_endian.h>\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\n#if defined( _MSC_VER ) && ( _MSC_VER > 800 )\n#pragma intrinsic(memcpy)\n#endif\n\n#if 0 && defined(_MSC_VER)\n#define rotl32 _lrotl\n#define rotr32 _lrotr\n#else\n#define rotl32(x,n)   (((x) << n) | ((x) >> (32 - n)))\n#define rotr32(x,n)   (((x) >> n) | ((x) << (32 - n)))\n#endif\n\n#if !defined(bswap_32)\n#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))\n#endif\n\n#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)\n#define SWAP_BYTES\n#else\n#undef  SWAP_BYTES\n#endif\n\n#if 0\n\n#define ch(x,y,z)       (((x) & (y)) ^ (~(x) & (z)))\n#define maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))\n\n#else   /* Thanks to Rich Schroeppel and Colin Plumb for the following      */\n\n#define ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))\n#define maj(x,y,z)      (((x) & (y)) | ((z) & ((x) ^ (y))))\n\n#endif\n\n/* round transforms for SHA256 and SHA512 compression functions */\n\n#define vf(n,i) v[(n - i) & 7]\n\n#define hf(i) (p[i & 15] += \\\n    g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15]))\n\n#define v_cycle(i,j)                                \\\n    vf(7,i) += (j ? hf(i) : p[i]) + k_0[i+j]        \\\n    + s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i));   \\\n    vf(3,i) += vf(7,i);                             \\\n    vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i))\n\n#if defined(SHA_224) || defined(SHA_256)\n\n#define SHA256_MASK (SHA256_BLOCK_SIZE - 1)\n\n#if defined(SWAP_BYTES)\n#define bsw_32(p,n) \\\n    { int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); }\n#else\n#define bsw_32(p,n)\n#endif\n\n#define s_0(x)  (rotr32((x),  2) ^ rotr32((x), 13) ^ rotr32((x), 22))\n#define s_1(x)  (rotr32((x),  6) ^ rotr32((x), 11) ^ rotr32((x), 25))\n#define g_0(x)  (rotr32((x),  7) ^ rotr32((x), 18) ^ ((x) >>  3))\n#define g_1(x)  (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10))\n#define k_0     k256\n\n/* rotated SHA256 round definition. Rather than swapping variables as in    */\n/* FIPS-180, different variables are 'rotated' on each round, returning     */\n/* to their starting positions every eight rounds                           */\n\n#define q(n)  v##n\n\n#define one_cycle(a,b,c,d,e,f,g,h,k,w)  \\\n    q(h) += s_1(q(e)) + ch(q(e), q(f), q(g)) + k + w; \\\n    q(d) += q(h); q(h) += s_0(q(a)) + maj(q(a), q(b), q(c))\n\n/* SHA256 mixing data   */\n\nconst uint_32t k256[64] =\n{   0x428a2f98ul, 0x71374491ul, 0xb5c0fbcful, 0xe9b5dba5ul,\n    0x3956c25bul, 0x59f111f1ul, 0x923f82a4ul, 0xab1c5ed5ul,\n    0xd807aa98ul, 0x12835b01ul, 0x243185beul, 0x550c7dc3ul,\n    0x72be5d74ul, 0x80deb1feul, 0x9bdc06a7ul, 0xc19bf174ul,\n    0xe49b69c1ul, 0xefbe4786ul, 0x0fc19dc6ul, 0x240ca1ccul,\n    0x2de92c6ful, 0x4a7484aaul, 0x5cb0a9dcul, 0x76f988daul,\n    0x983e5152ul, 0xa831c66dul, 0xb00327c8ul, 0xbf597fc7ul,\n    0xc6e00bf3ul, 0xd5a79147ul, 0x06ca6351ul, 0x14292967ul,\n    0x27b70a85ul, 0x2e1b2138ul, 0x4d2c6dfcul, 0x53380d13ul,\n    0x650a7354ul, 0x766a0abbul, 0x81c2c92eul, 0x92722c85ul,\n    0xa2bfe8a1ul, 0xa81a664bul, 0xc24b8b70ul, 0xc76c51a3ul,\n    0xd192e819ul, 0xd6990624ul, 0xf40e3585ul, 0x106aa070ul,\n    0x19a4c116ul, 0x1e376c08ul, 0x2748774cul, 0x34b0bcb5ul,\n    0x391c0cb3ul, 0x4ed8aa4aul, 0x5b9cca4ful, 0x682e6ff3ul,\n    0x748f82eeul, 0x78a5636ful, 0x84c87814ul, 0x8cc70208ul,\n    0x90befffaul, 0xa4506cebul, 0xbef9a3f7ul, 0xc67178f2ul,\n};\n\n/* Compile 64 bytes of hash data into SHA256 digest value   */\n/* NOTE: this routine assumes that the byte order in the    */\n/* ctx->wbuf[] at this point is such that low address bytes */\n/* in the ORIGINAL byte stream will go into the high end of */\n/* words on BOTH big and little endian systems              */\n\nVOID_RETURN sha256_compile(sha256_ctx ctx[1])\n{\n#if !defined(UNROLL_SHA2)\n\n    uint_32t j, *p = ctx->wbuf, v[8];\n\n    memcpy(v, ctx->hash, 8 * sizeof(uint_32t));\n\n    for(j = 0; j < 64; j += 16)\n    {\n        v_cycle( 0, j); v_cycle( 1, j);\n        v_cycle( 2, j); v_cycle( 3, j);\n        v_cycle( 4, j); v_cycle( 5, j);\n        v_cycle( 6, j); v_cycle( 7, j);\n        v_cycle( 8, j); v_cycle( 9, j);\n        v_cycle(10, j); v_cycle(11, j);\n        v_cycle(12, j); v_cycle(13, j);\n        v_cycle(14, j); v_cycle(15, j);\n    }\n\n    ctx->hash[0] += v[0]; ctx->hash[1] += v[1];\n    ctx->hash[2] += v[2]; ctx->hash[3] += v[3];\n    ctx->hash[4] += v[4]; ctx->hash[5] += v[5];\n    ctx->hash[6] += v[6]; ctx->hash[7] += v[7];\n\n#else\n\n    uint_32t *p = ctx->wbuf,v0,v1,v2,v3,v4,v5,v6,v7;\n\n    v0 = ctx->hash[0]; v1 = ctx->hash[1];\n    v2 = ctx->hash[2]; v3 = ctx->hash[3];\n    v4 = ctx->hash[4]; v5 = ctx->hash[5];\n    v6 = ctx->hash[6]; v7 = ctx->hash[7];\n\n    one_cycle(0,1,2,3,4,5,6,7,k256[ 0],p[ 0]);\n    one_cycle(7,0,1,2,3,4,5,6,k256[ 1],p[ 1]);\n    one_cycle(6,7,0,1,2,3,4,5,k256[ 2],p[ 2]);\n    one_cycle(5,6,7,0,1,2,3,4,k256[ 3],p[ 3]);\n    one_cycle(4,5,6,7,0,1,2,3,k256[ 4],p[ 4]);\n    one_cycle(3,4,5,6,7,0,1,2,k256[ 5],p[ 5]);\n    one_cycle(2,3,4,5,6,7,0,1,k256[ 6],p[ 6]);\n    one_cycle(1,2,3,4,5,6,7,0,k256[ 7],p[ 7]);\n    one_cycle(0,1,2,3,4,5,6,7,k256[ 8],p[ 8]);\n    one_cycle(7,0,1,2,3,4,5,6,k256[ 9],p[ 9]);\n    one_cycle(6,7,0,1,2,3,4,5,k256[10],p[10]);\n    one_cycle(5,6,7,0,1,2,3,4,k256[11],p[11]);\n    one_cycle(4,5,6,7,0,1,2,3,k256[12],p[12]);\n    one_cycle(3,4,5,6,7,0,1,2,k256[13],p[13]);\n    one_cycle(2,3,4,5,6,7,0,1,k256[14],p[14]);\n    one_cycle(1,2,3,4,5,6,7,0,k256[15],p[15]);\n\n    one_cycle(0,1,2,3,4,5,6,7,k256[16],hf( 0));\n    one_cycle(7,0,1,2,3,4,5,6,k256[17],hf( 1));\n    one_cycle(6,7,0,1,2,3,4,5,k256[18],hf( 2));\n    one_cycle(5,6,7,0,1,2,3,4,k256[19],hf( 3));\n    one_cycle(4,5,6,7,0,1,2,3,k256[20],hf( 4));\n    one_cycle(3,4,5,6,7,0,1,2,k256[21],hf( 5));\n    one_cycle(2,3,4,5,6,7,0,1,k256[22],hf( 6));\n    one_cycle(1,2,3,4,5,6,7,0,k256[23],hf( 7));\n    one_cycle(0,1,2,3,4,5,6,7,k256[24],hf( 8));\n    one_cycle(7,0,1,2,3,4,5,6,k256[25],hf( 9));\n    one_cycle(6,7,0,1,2,3,4,5,k256[26],hf(10));\n    one_cycle(5,6,7,0,1,2,3,4,k256[27],hf(11));\n    one_cycle(4,5,6,7,0,1,2,3,k256[28],hf(12));\n    one_cycle(3,4,5,6,7,0,1,2,k256[29],hf(13));\n    one_cycle(2,3,4,5,6,7,0,1,k256[30],hf(14));\n    one_cycle(1,2,3,4,5,6,7,0,k256[31],hf(15));\n\n    one_cycle(0,1,2,3,4,5,6,7,k256[32],hf( 0));\n    one_cycle(7,0,1,2,3,4,5,6,k256[33],hf( 1));\n    one_cycle(6,7,0,1,2,3,4,5,k256[34],hf( 2));\n    one_cycle(5,6,7,0,1,2,3,4,k256[35],hf( 3));\n    one_cycle(4,5,6,7,0,1,2,3,k256[36],hf( 4));\n    one_cycle(3,4,5,6,7,0,1,2,k256[37],hf( 5));\n    one_cycle(2,3,4,5,6,7,0,1,k256[38],hf( 6));\n    one_cycle(1,2,3,4,5,6,7,0,k256[39],hf( 7));\n    one_cycle(0,1,2,3,4,5,6,7,k256[40],hf( 8));\n    one_cycle(7,0,1,2,3,4,5,6,k256[41],hf( 9));\n    one_cycle(6,7,0,1,2,3,4,5,k256[42],hf(10));\n    one_cycle(5,6,7,0,1,2,3,4,k256[43],hf(11));\n    one_cycle(4,5,6,7,0,1,2,3,k256[44],hf(12));\n    one_cycle(3,4,5,6,7,0,1,2,k256[45],hf(13));\n    one_cycle(2,3,4,5,6,7,0,1,k256[46],hf(14));\n    one_cycle(1,2,3,4,5,6,7,0,k256[47],hf(15));\n\n    one_cycle(0,1,2,3,4,5,6,7,k256[48],hf( 0));\n    one_cycle(7,0,1,2,3,4,5,6,k256[49],hf( 1));\n    one_cycle(6,7,0,1,2,3,4,5,k256[50],hf( 2));\n    one_cycle(5,6,7,0,1,2,3,4,k256[51],hf( 3));\n    one_cycle(4,5,6,7,0,1,2,3,k256[52],hf( 4));\n    one_cycle(3,4,5,6,7,0,1,2,k256[53],hf( 5));\n    one_cycle(2,3,4,5,6,7,0,1,k256[54],hf( 6));\n    one_cycle(1,2,3,4,5,6,7,0,k256[55],hf( 7));\n    one_cycle(0,1,2,3,4,5,6,7,k256[56],hf( 8));\n    one_cycle(7,0,1,2,3,4,5,6,k256[57],hf( 9));\n    one_cycle(6,7,0,1,2,3,4,5,k256[58],hf(10));\n    one_cycle(5,6,7,0,1,2,3,4,k256[59],hf(11));\n    one_cycle(4,5,6,7,0,1,2,3,k256[60],hf(12));\n    one_cycle(3,4,5,6,7,0,1,2,k256[61],hf(13));\n    one_cycle(2,3,4,5,6,7,0,1,k256[62],hf(14));\n    one_cycle(1,2,3,4,5,6,7,0,k256[63],hf(15));\n\n    ctx->hash[0] += v0; ctx->hash[1] += v1;\n    ctx->hash[2] += v2; ctx->hash[3] += v3;\n    ctx->hash[4] += v4; ctx->hash[5] += v5;\n    ctx->hash[6] += v6; ctx->hash[7] += v7;\n#endif\n}\n\n/* SHA256 hash data in an array of bytes into hash buffer   */\n/* and call the hash_compile function as required.          */\n\nVOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1])\n{   uint_32t pos = (uint_32t)(ctx->count[0] & SHA256_MASK),\n             space = SHA256_BLOCK_SIZE - pos;\n    const unsigned char *sp = data;\n\n    if((ctx->count[0] += len) < len)\n        ++(ctx->count[1]);\n\n    while(len >= space)     /* tranfer whole blocks while possible  */\n    {\n        memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);\n        sp += space; len -= space; space = SHA256_BLOCK_SIZE; pos = 0;\n        bsw_32(ctx->wbuf, SHA256_BLOCK_SIZE >> 2)\n        sha256_compile(ctx);\n    }\n\n    memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);\n}\n\n/* SHA256 Final padding and digest calculation  */\n\nstatic void sha_end1(unsigned char hval[], sha256_ctx ctx[1], const unsigned int hlen)\n{   uint_32t    i = (uint_32t)(ctx->count[0] & SHA256_MASK);\n\n    /* put bytes in the buffer in an order in which references to   */\n    /* 32-bit words will put bytes with lower addresses into the    */\n    /* top of 32 bit words on BOTH big and little endian machines   */\n    bsw_32(ctx->wbuf, (i + 3) >> 2)\n\n    /* we now need to mask valid bytes and add the padding which is */\n    /* a single 1 bit and as many zero bits as necessary. Note that */\n    /* we can always add the first padding byte here because the    */\n    /* buffer always has at least one empty slot                    */\n    ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3);\n    ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3);\n\n    /* we need 9 or more empty positions, one for the padding byte  */\n    /* (above) and eight for the length count.  If there is not     */\n    /* enough space pad and empty the buffer                        */\n    if(i > SHA256_BLOCK_SIZE - 9)\n    {\n        if(i < 60) ctx->wbuf[15] = 0;\n        sha256_compile(ctx);\n        i = 0;\n    }\n    else    /* compute a word index for the empty buffer positions  */\n        i = (i >> 2) + 1;\n\n    while(i < 14) /* and zero pad all but last two positions        */\n        ctx->wbuf[i++] = 0;\n\n    /* the following 32-bit length fields are assembled in the      */\n    /* wrong byte order on little endian machines but this is       */\n    /* corrected later since they are only ever used as 32-bit      */\n    /* word values.                                                 */\n    ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);\n    ctx->wbuf[15] = ctx->count[0] << 3;\n    sha256_compile(ctx);\n\n    /* extract the hash value as bytes in case the hash buffer is   */\n    /* mislaigned for 32-bit words                                  */\n    for(i = 0; i < hlen; ++i)\n        hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));\n}\n\n#endif\n\n#if defined(SHA_224)\n\nconst uint_32t i224[8] =\n{\n    0xc1059ed8ul, 0x367cd507ul, 0x3070dd17ul, 0xf70e5939ul,\n    0xffc00b31ul, 0x68581511ul, 0x64f98fa7ul, 0xbefa4fa4ul\n};\n\nVOID_RETURN sha224_begin(sha224_ctx ctx[1])\n{\n    ctx->count[0] = ctx->count[1] = 0;\n    memcpy(ctx->hash, i224, 8 * sizeof(uint_32t));\n}\n\nVOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1])\n{\n    sha_end1(hval, ctx, SHA224_DIGEST_SIZE);\n}\n\nVOID_RETURN sha224_zrtp(unsigned char hval[], const unsigned char data[], unsigned long len)\n{   sha224_ctx  cx[1];\n\n    sha224_begin(cx);\n    sha224_hash(data, len, cx);\n    sha_end1(hval, cx, SHA224_DIGEST_SIZE);\n}\n\n#endif\n\n#if defined(SHA_256)\n\nconst uint_32t i256[8] =\n{\n    0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul,\n    0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul\n};\n\nVOID_RETURN sha256_begin(sha256_ctx ctx[1])\n{\n    ctx->count[0] = ctx->count[1] = 0;\n    memcpy(ctx->hash, i256, 8 * sizeof(uint_32t));\n}\n\nVOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1])\n{\n    sha_end1(hval, ctx, SHA256_DIGEST_SIZE);\n}\n\nVOID_RETURN sha256_zrtp(unsigned char hval[], const unsigned char data[], unsigned long len)\n{   sha256_ctx  cx[1];\n\n    sha256_begin(cx);\n    sha256_hash(data, len, cx);\n    sha_end1(hval, cx, SHA256_DIGEST_SIZE);\n}\n\n#endif\n\n#if defined(SHA_384) || defined(SHA_512)\n\n#define SHA512_MASK (SHA512_BLOCK_SIZE - 1)\n\n#define rotr64(x,n)   (((x) >> n) | ((x) << (64 - n)))\n\n#if !defined(bswap_64)\n#define bswap_64(x) (((uint_64t)(bswap_32((uint_32t)(x)))) << 32 | bswap_32((uint_32t)((x) >> 32)))\n#endif\n\n#if defined(SWAP_BYTES)\n#define bsw_64(p,n) \\\n    { int _i = (n); while(_i--) ((uint_64t*)p)[_i] = bswap_64(((uint_64t*)p)[_i]); }\n#else\n#define bsw_64(p,n)\n#endif\n\n/* SHA512 mixing function definitions   */\n\n#ifdef   s_0\n# undef  s_0\n# undef  s_1\n# undef  g_0\n# undef  g_1\n# undef  k_0\n#endif\n\n#define s_0(x)  (rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39))\n#define s_1(x)  (rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41))\n#define g_0(x)  (rotr64((x),  1) ^ rotr64((x),  8) ^ ((x) >>  7))\n#define g_1(x)  (rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >>  6))\n#define k_0     k512\n\n/* SHA384/SHA512 mixing data    */\n\nconst uint_64t  k512[80] =\n{\n    li_64(428a2f98d728ae22), li_64(7137449123ef65cd),\n    li_64(b5c0fbcfec4d3b2f), li_64(e9b5dba58189dbbc),\n    li_64(3956c25bf348b538), li_64(59f111f1b605d019),\n    li_64(923f82a4af194f9b), li_64(ab1c5ed5da6d8118),\n    li_64(d807aa98a3030242), li_64(12835b0145706fbe),\n    li_64(243185be4ee4b28c), li_64(550c7dc3d5ffb4e2),\n    li_64(72be5d74f27b896f), li_64(80deb1fe3b1696b1),\n    li_64(9bdc06a725c71235), li_64(c19bf174cf692694),\n    li_64(e49b69c19ef14ad2), li_64(efbe4786384f25e3),\n    li_64(0fc19dc68b8cd5b5), li_64(240ca1cc77ac9c65),\n    li_64(2de92c6f592b0275), li_64(4a7484aa6ea6e483),\n    li_64(5cb0a9dcbd41fbd4), li_64(76f988da831153b5),\n    li_64(983e5152ee66dfab), li_64(a831c66d2db43210),\n    li_64(b00327c898fb213f), li_64(bf597fc7beef0ee4),\n    li_64(c6e00bf33da88fc2), li_64(d5a79147930aa725),\n    li_64(06ca6351e003826f), li_64(142929670a0e6e70),\n    li_64(27b70a8546d22ffc), li_64(2e1b21385c26c926),\n    li_64(4d2c6dfc5ac42aed), li_64(53380d139d95b3df),\n    li_64(650a73548baf63de), li_64(766a0abb3c77b2a8),\n    li_64(81c2c92e47edaee6), li_64(92722c851482353b),\n    li_64(a2bfe8a14cf10364), li_64(a81a664bbc423001),\n    li_64(c24b8b70d0f89791), li_64(c76c51a30654be30),\n    li_64(d192e819d6ef5218), li_64(d69906245565a910),\n    li_64(f40e35855771202a), li_64(106aa07032bbd1b8),\n    li_64(19a4c116b8d2d0c8), li_64(1e376c085141ab53),\n    li_64(2748774cdf8eeb99), li_64(34b0bcb5e19b48a8),\n    li_64(391c0cb3c5c95a63), li_64(4ed8aa4ae3418acb),\n    li_64(5b9cca4f7763e373), li_64(682e6ff3d6b2b8a3),\n    li_64(748f82ee5defb2fc), li_64(78a5636f43172f60),\n    li_64(84c87814a1f0ab72), li_64(8cc702081a6439ec),\n    li_64(90befffa23631e28), li_64(a4506cebde82bde9),\n    li_64(bef9a3f7b2c67915), li_64(c67178f2e372532b),\n    li_64(ca273eceea26619c), li_64(d186b8c721c0c207),\n    li_64(eada7dd6cde0eb1e), li_64(f57d4f7fee6ed178),\n    li_64(06f067aa72176fba), li_64(0a637dc5a2c898a6),\n    li_64(113f9804bef90dae), li_64(1b710b35131c471b),\n    li_64(28db77f523047d84), li_64(32caab7b40c72493),\n    li_64(3c9ebe0a15c9bebc), li_64(431d67c49c100d4c),\n    li_64(4cc5d4becb3e42b6), li_64(597f299cfc657e2a),\n    li_64(5fcb6fab3ad6faec), li_64(6c44198c4a475817)\n};\n\n/* Compile 128 bytes of hash data into SHA384/512 digest    */\n/* NOTE: this routine assumes that the byte order in the    */\n/* ctx->wbuf[] at this point is such that low address bytes */\n/* in the ORIGINAL byte stream will go into the high end of */\n/* words on BOTH big and little endian systems              */\n\nVOID_RETURN sha512_compile(sha512_ctx ctx[1])\n{   uint_64t    v[8], *p = ctx->wbuf;\n    uint_32t    j;\n\n    memcpy(v, ctx->hash, 8 * sizeof(uint_64t));\n\n    for(j = 0; j < 80; j += 16)\n    {\n        v_cycle( 0, j); v_cycle( 1, j);\n        v_cycle( 2, j); v_cycle( 3, j);\n        v_cycle( 4, j); v_cycle( 5, j);\n        v_cycle( 6, j); v_cycle( 7, j);\n        v_cycle( 8, j); v_cycle( 9, j);\n        v_cycle(10, j); v_cycle(11, j);\n        v_cycle(12, j); v_cycle(13, j);\n        v_cycle(14, j); v_cycle(15, j);\n    }\n\n    ctx->hash[0] += v[0]; ctx->hash[1] += v[1];\n    ctx->hash[2] += v[2]; ctx->hash[3] += v[3];\n    ctx->hash[4] += v[4]; ctx->hash[5] += v[5];\n    ctx->hash[6] += v[6]; ctx->hash[7] += v[7];\n}\n\n/* Compile 128 bytes of hash data into SHA256 digest value  */\n/* NOTE: this routine assumes that the byte order in the    */\n/* ctx->wbuf[] at this point is in such an order that low   */\n/* address bytes in the ORIGINAL byte stream placed in this */\n/* buffer will now go to the high end of words on BOTH big  */\n/* and little endian systems                                */\n\nVOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1])\n{   uint_32t pos = (uint_32t)(ctx->count[0] & SHA512_MASK),\n             space = SHA512_BLOCK_SIZE - pos;\n    const unsigned char *sp = data;\n\n    if((ctx->count[0] += len) < len)\n        ++(ctx->count[1]);\n\n    while(len >= space)     /* tranfer whole blocks while possible  */\n    {\n        memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);\n        sp += space; len -= space; space = SHA512_BLOCK_SIZE; pos = 0;\n        bsw_64(ctx->wbuf, SHA512_BLOCK_SIZE >> 3);\n        sha512_compile(ctx);\n    }\n\n    memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);\n}\n\n/* SHA384/512 Final padding and digest calculation  */\n\nstatic void sha_end2(unsigned char hval[], sha512_ctx ctx[1], const unsigned int hlen)\n{   uint_32t    i = (uint_32t)(ctx->count[0] & SHA512_MASK);\n\n    /* put bytes in the buffer in an order in which references to   */\n    /* 32-bit words will put bytes with lower addresses into the    */\n    /* top of 32 bit words on BOTH big and little endian machines   */\n    bsw_64(ctx->wbuf, (i + 7) >> 3);\n\n    /* we now need to mask valid bytes and add the padding which is */\n    /* a single 1 bit and as many zero bits as necessary. Note that */\n    /* we can always add the first padding byte here because the    */\n    /* buffer always has at least one empty slot                    */\n    ctx->wbuf[i >> 3] &= li_64(ffffffffffffff00) << 8 * (~i & 7);\n    ctx->wbuf[i >> 3] |= li_64(0000000000000080) << 8 * (~i & 7);\n\n    /* we need 17 or more empty byte positions, one for the padding */\n    /* byte (above) and sixteen for the length count.  If there is  */\n    /* not enough space pad and empty the buffer                    */\n    if(i > SHA512_BLOCK_SIZE - 17)\n    {\n        if(i < 120) ctx->wbuf[15] = 0;\n        sha512_compile(ctx);\n        i = 0;\n    }\n    else\n        i = (i >> 3) + 1;\n\n    while(i < 14)\n        ctx->wbuf[i++] = 0;\n\n    /* the following 64-bit length fields are assembled in the      */\n    /* wrong byte order on little endian machines but this is       */\n    /* corrected later since they are only ever used as 64-bit      */\n    /* word values.                                                 */\n    ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 61);\n    ctx->wbuf[15] = ctx->count[0] << 3;\n    sha512_compile(ctx);\n\n    /* extract the hash value as bytes in case the hash buffer is   */\n    /* misaligned for 32-bit words                                  */\n    for(i = 0; i < hlen; ++i)\n        hval[i] = (unsigned char)(ctx->hash[i >> 3] >> (8 * (~i & 7)));\n}\n\n#endif\n\n#if defined(SHA_384)\n\n/* SHA384 initialisation data   */\n\nconst uint_64t  i384[80] =\n{\n    li_64(cbbb9d5dc1059ed8), li_64(629a292a367cd507),\n    li_64(9159015a3070dd17), li_64(152fecd8f70e5939),\n    li_64(67332667ffc00b31), li_64(8eb44a8768581511),\n    li_64(db0c2e0d64f98fa7), li_64(47b5481dbefa4fa4)\n};\n\nVOID_RETURN sha384_begin(sha384_ctx ctx[1])\n{\n    ctx->count[0] = ctx->count[1] = 0;\n    memcpy(ctx->hash, i384, 8 * sizeof(uint_64t));\n}\n\nVOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1])\n{\n    sha_end2(hval, ctx, SHA384_DIGEST_SIZE);\n}\n\nVOID_RETURN sha384_zrtp(unsigned char hval[], const unsigned char data[], unsigned long len)\n{   sha384_ctx  cx[1];\n\n    sha384_begin(cx);\n    sha384_hash(data, len, cx);\n    sha_end2(hval, cx, SHA384_DIGEST_SIZE);\n}\n\n#endif\n\n#if defined(SHA_512)\n\n/* SHA512 initialisation data   */\n\nconst uint_64t  i512[80] =\n{\n    li_64(6a09e667f3bcc908), li_64(bb67ae8584caa73b),\n    li_64(3c6ef372fe94f82b), li_64(a54ff53a5f1d36f1),\n    li_64(510e527fade682d1), li_64(9b05688c2b3e6c1f),\n    li_64(1f83d9abfb41bd6b), li_64(5be0cd19137e2179)\n};\n\nVOID_RETURN sha512_begin(sha512_ctx ctx[1])\n{\n    ctx->count[0] = ctx->count[1] = 0;\n    memcpy(ctx->hash, i512, 8 * sizeof(uint_64t));\n}\n\nVOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1])\n{\n    sha_end2(hval, ctx, SHA512_DIGEST_SIZE);\n}\n\nVOID_RETURN sha512_zrtp(unsigned char hval[], const unsigned char data[], unsigned long len)\n{   sha512_ctx  cx[1];\n\n    sha512_begin(cx);\n    sha512_hash(data, len, cx);\n    sha_end2(hval, cx, SHA512_DIGEST_SIZE);\n}\n\n#endif\n\n#if defined(SHA_2)\n\n#define CTX_224(x)  ((x)->uu->ctx256)\n#define CTX_256(x)  ((x)->uu->ctx256)\n#define CTX_384(x)  ((x)->uu->ctx512)\n#define CTX_512(x)  ((x)->uu->ctx512)\n\n/* SHA2 initialisation */\n\nINT_RETURN sha2_begin(unsigned long len, sha2_ctx ctx[1])\n{\n    switch(len)\n    {\n#if defined(SHA_224)\n        case 224:\n        case  28:   CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;\n                    memcpy(CTX_256(ctx)->hash, i224, 32);\n                    ctx->sha2_len = 28; return EXIT_SUCCESS;\n#endif\n#if defined(SHA_256)\n        case 256:\n        case  32:   CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;\n                    memcpy(CTX_256(ctx)->hash, i256, 32);\n                    ctx->sha2_len = 32; return EXIT_SUCCESS;\n#endif\n#if defined(SHA_384)\n        case 384:\n        case  48:   CTX_384(ctx)->count[0] = CTX_384(ctx)->count[1] = 0;\n                    memcpy(CTX_384(ctx)->hash, i384, 64);\n                    ctx->sha2_len = 48; return EXIT_SUCCESS;\n#endif\n#if defined(SHA_512)\n        case 512:\n        case  64:   CTX_512(ctx)->count[0] = CTX_512(ctx)->count[1] = 0;\n                    memcpy(CTX_512(ctx)->hash, i512, 64);\n                    ctx->sha2_len = 64; return EXIT_SUCCESS;\n#endif\n        default:    return EXIT_FAILURE;\n    }\n}\n\nVOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1])\n{\n    switch(ctx->sha2_len)\n    {\n#if defined(SHA_224)\n        case 28: sha224_hash(data, len, CTX_224(ctx)); return;\n#endif\n#if defined(SHA_256)\n        case 32: sha256_hash(data, len, CTX_256(ctx)); return;\n#endif\n#if defined(SHA_384)\n        case 48: sha384_hash(data, len, CTX_384(ctx)); return;\n#endif\n#if defined(SHA_512)\n        case 64: sha512_hash(data, len, CTX_512(ctx)); return;\n#endif\n    }\n}\n\nVOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1])\n{\n    switch(ctx->sha2_len)\n    {\n#if defined(SHA_224)\n        case 28: sha_end1(hval, CTX_224(ctx), SHA224_DIGEST_SIZE); return;\n#endif\n#if defined(SHA_256)\n        case 32: sha_end1(hval, CTX_256(ctx), SHA256_DIGEST_SIZE); return;\n#endif\n#if defined(SHA_384)\n        case 48: sha_end2(hval, CTX_384(ctx), SHA384_DIGEST_SIZE); return;\n#endif\n#if defined(SHA_512)\n        case 64: sha_end2(hval, CTX_512(ctx), SHA512_DIGEST_SIZE); return;\n#endif\n    }\n}\n\nINT_RETURN sha2_all(unsigned char hval[], unsigned long size,\n                                const unsigned char data[], unsigned long len)\n{   sha2_ctx    cx[1];\n\n    if(sha2_begin(size, cx) == EXIT_SUCCESS)\n    {\n        sha2_hash(data, len, cx); sha2_end(hval, cx); return EXIT_SUCCESS;\n    }\n    else\n        return EXIT_FAILURE;\n}\n\n#endif\n\n#if defined(__cplusplus)\n}\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/sha2.h",
    "content": "/*\n ---------------------------------------------------------------------------\n Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.\n\n LICENSE TERMS\n\n The free distribution and use of this software in both source and binary\n form is allowed (with or without changes) provided that:\n\n   1. distributions of this source code include the above copyright\n      notice, this list of conditions and the following disclaimer;\n\n   2. distributions in binary form include the above copyright\n      notice, this list of conditions and the following disclaimer\n      in the documentation and/or other associated materials;\n\n   3. the copyright holder's name is not used to endorse products\n      built using this software without specific written permission.\n\n ALTERNATIVELY, provided that this notice is retained in full, this product\n may be distributed under the terms of the GNU General Public License (GPL),\n in which case the provisions of the GPL apply INSTEAD OF those given above.\n\n DISCLAIMER\n\n This software is provided 'as is' with no explicit or implied warranties\n in respect of its properties, including, but not limited to, correctness\n and/or fitness for purpose.\n ---------------------------------------------------------------------------\n Issue Date: 01/08/2005\n*/\n\n#ifndef _SHA2_H\n#define _SHA2_H\n\n#include <stdlib.h>\n\n#define SHA_64BIT\n\n/* define the hash functions that you need  */\n#define SHA_2   /* for dynamic hash length  */\n#define SHA_224\n#define SHA_256\n#ifdef SHA_64BIT\n#  define SHA_384\n#  define SHA_512\n#  define NEED_UINT_64T\n#endif\n\n#include <cryptcommon/brg_types.h>\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\n/* Note that the following function prototypes are the same */\n/* for both the bit and byte oriented implementations.  But */\n/* the length fields are in bytes or bits as is appropriate */\n/* for the version used.  Bit sequences are arrays of bytes */\n/* in which bit sequence indexes increase from the most to  */\n/* the least significant end of each byte                   */\n\n#define SHA224_DIGEST_SIZE  28\n#define SHA224_BLOCK_SIZE   64\n#define SHA256_DIGEST_SIZE  32\n#define SHA256_BLOCK_SIZE   64\n\n/* type to hold the SHA256 (and SHA224) context */\n\ntypedef struct\n{   uint_32t count[2];\n    uint_32t hash[8];\n    uint_32t wbuf[16];\n} sha256_ctx;\n\ntypedef sha256_ctx  sha224_ctx;\n\nVOID_RETURN sha256_compile(sha256_ctx ctx[1]);\n\nVOID_RETURN sha224_begin(sha224_ctx ctx[1]);\n#define sha224_hash sha256_hash\nVOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1]);\nVOID_RETURN sha224_zrtp(unsigned char hval[], const unsigned char data[], unsigned long len);\n\nVOID_RETURN sha256_begin(sha256_ctx ctx[1]);\nVOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1]);\nVOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1]);\nVOID_RETURN sha256_zrtp(unsigned char hval[], const unsigned char data[], unsigned long len);\n\n#ifndef SHA_64BIT\n\ntypedef struct\n{   union\n    { sha256_ctx  ctx256[1];\n    } uu[1];\n    uint_32t    sha2_len;\n} sha2_ctx;\n\n#define SHA2_MAX_DIGEST_SIZE    SHA256_DIGEST_SIZE\n\n#else\n\n#define SHA384_DIGEST_SIZE  48\n#define SHA384_BLOCK_SIZE  128\n#define SHA512_DIGEST_SIZE  64\n#define SHA512_BLOCK_SIZE  128\n#define SHA2_MAX_DIGEST_SIZE    SHA512_DIGEST_SIZE\n\n/* type to hold the SHA384 (and SHA512) context */\n\ntypedef struct\n{   uint_64t count[2];\n    uint_64t hash[8];\n    uint_64t wbuf[16];\n} sha512_ctx;\n\ntypedef sha512_ctx  sha384_ctx;\n\ntypedef struct\n{   union\n    { sha256_ctx  ctx256[1];\n      sha512_ctx  ctx512[1];\n    } uu[1];\n    uint_32t    sha2_len;\n} sha2_ctx;\n\nVOID_RETURN sha512_compile(sha512_ctx ctx[1]);\n\nVOID_RETURN sha384_begin(sha384_ctx ctx[1]);\n#define sha384_hash sha512_hash\nVOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1]);\nVOID_RETURN sha384_zrtp(unsigned char hval[], const unsigned char data[], unsigned long len);\n\nVOID_RETURN sha512_begin(sha512_ctx ctx[1]);\nVOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1]);\nVOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1]);\nVOID_RETURN sha512_zrtp(unsigned char hval[], const unsigned char data[], unsigned long len);\n\nINT_RETURN  sha2_begin(unsigned long size, sha2_ctx ctx[1]);\nVOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1]);\nVOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1]);\nINT_RETURN  sha2_all(unsigned char hval[], unsigned long size, const unsigned char data[], unsigned long len);\n\n#endif\n\n#if defined(__cplusplus)\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/sha256.cpp",
    "content": "/*\n  Copyright (C) 2012 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/**\n * @author: Werner Dittmann\n */\n\n#include <zrtp/crypto/sha2.h>\n#include <zrtp/crypto/sha256.h>\n\nvoid sha256(unsigned char *data, unsigned int dataLength, unsigned char *digest )\n{\n    sha256_ctx ctx;\n\n    sha256_begin(&ctx);\n    sha256_hash(data, dataLength, &ctx);\n    sha256_end(digest, &ctx);\n}\n\nvoid sha256(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)\n{\n    sha256_ctx ctx;\n\n    sha256_begin(&ctx);\n    while(*dataChunks) {\n        sha256_hash(*dataChunks, *dataChunckLength, &ctx);\n        dataChunks++;\n        dataChunckLength++;\n    }\n    sha256_end(digest, &ctx);\n}\n\nvoid* createSha256Context()\n{\n    sha256_ctx *ctx = reinterpret_cast<sha256_ctx*>(malloc(sizeof(sha256_ctx)));\n    sha256_begin(ctx);\n    return (void*)ctx;\n}\n\nvoid closeSha256Context(void* ctx, unsigned char* digest)\n{\n    sha256_ctx* hd = reinterpret_cast<sha256_ctx*>(ctx);\n\n    if (digest != NULL && hd != NULL) {\n        sha256_end(digest, hd);\n    }\n    free(hd);\n}\n\nvoid* initializeSha256Context(void* ctx)\n{\n    sha256_ctx* hd = reinterpret_cast<sha256_ctx*>(ctx);\n\n    if (hd != NULL) {\n        sha256_begin(hd);\n    }\n    return (void*)hd;\n}\n\nvoid finalizeSha256Context(void* ctx, unsigned char* digest)\n{\n    sha256_ctx* hd = reinterpret_cast<sha256_ctx*>(ctx);\n\n    if (digest != NULL && hd != NULL) {\n        sha256_end(digest, hd);\n    }\n}\n\nvoid sha256Ctx(void* ctx, unsigned char* data, unsigned int dataLength)\n{\n    sha256_ctx* hd = reinterpret_cast<sha256_ctx*>(ctx);\n\n    sha256_hash(data, dataLength, hd);\n}\n\nvoid sha256Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])\n{\n    sha256_ctx* hd = reinterpret_cast<sha256_ctx*>(ctx);\n\n    while (*dataChunks) {\n        sha256_hash(*dataChunks, *dataChunkLength, hd);\n        dataChunks++;\n        dataChunkLength++;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/sha256.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/**\n * Functions to compute SHA256 digest.\n *\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef _SHA256_H\n#define _SHA256_H\n\n/**\n * @file sha256.h\n * @brief Function that provide SHA256 support\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <stdint.h>\n\n#ifndef SHA256_DIGEST_LENGTH\n#define SHA256_DIGEST_LENGTH 32\n#endif\n\n/**\n * Compute SHA256 digest.\n *\n * This functions takes one data chunk and computes its SHA256 digest. This \n * function creates and deletes an own SHA256 context to perform the SHA256\n * operations.\n *\n * @param data\n *    Points to the data chunk.\n * @param data_length\n *    Length of the data in bytes\n * @param digest\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 32 bytes (SHA256_DIGEST_LENGTH).\n */\nvoid sha256(unsigned char *data,\n            unsigned int data_length,\n            unsigned char *digest);\n\n/**\n * Compute SHA256 digest over several data cunks.\n *\n * This functions takes several data chunks and computes the SHA256 digest.\n * This function creates and deletes an own SHA256 context to perform the\n * SHA256 operations.\n *\n * @param data\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param data_length\n *    Points to an array of integers that hold the length of each data chunk.\n * @param digest\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 32 bytes (SHA256_DIGEST_LENGTH).\n */\nvoid sha256(unsigned char *data[],\n            unsigned int data_length[],\n            unsigned char *digest);\n/**\n * Create and initialize a SHA256 context.\n *\n * An application uses this context to hash several data into one SHA256\n * digest. See also sha256Ctx(...) and closeSha256Context(...).\n *\n * @return Returns a pointer to the initialized SHA256 context or @c NULL in case of an error.\n */\nvoid* createSha256Context();\n\n/**\n * Compute a digest and close the SHA256 digest.\n *\n * An application uses this function to compute the SHA256 digest and to\n * close the SHA256 context.\n *\n * @param ctx\n *    Points to the SHA256 context.\n * @param digest\n *    If this pointer is not NULL then it must point to a byte array that\n *    is big enough to hold the SHA256 digest (256 bit = 32 Bytes). If this\n *    pointer is NULL then the functions does not compute the digest but\n *    closes the context only. The context cannot be used anymore.\n */\nvoid closeSha256Context(void* ctx, unsigned char* digest);\n\n/**\n * Initialize a SHA256 context.\n *\n * An application uses this context to hash several data into one SHA256\n * digest. See also sha256Ctx(...) and closeSha384Context(...).\n *\n * @param ctx\n *    Points to the SHA256 context.\n * @return Returns the pointer to the initialized SHA256 context\n */\nvoid* initializeSha256Context(void* ctx);\n\n/**\n * Compute a digest.\n *\n * An application uses this function to compute the SHA256 digest.\n *\n * @param ctx\n *    Points to the SHA256 context.\n * @param digest\n *    If this pointer is not NULL then it must point to a byte array that\n *    is big enough to hold the SHA256 digest (256 bit = 32 Bytes). If this\n *    pointer is NULL then the functions does not compute the digest.\n */\nvoid finalizeSha256Context(void* ctx, unsigned char* digest);\n\n/**\n * Update the SHA256 context with data.\n *\n * This functions updates the SHA256 context with some data.\n * See also CloseSha256Context(...) how to get the digest.\n *\n * @param ctx\n *    Points to the SHA256 context.\n * @param data\n *    Points to the data to update the context.\n * @param dataLength\n *    The length of the data in bytes.\n */\nvoid sha256Ctx(void* ctx, unsigned char* data, \n               unsigned int dataLength);\n\n/**\n * Update the SHA256 context with several data chunks.\n *\n * This functions updates the SHA256 context with some data.\n * See also CloseSha256Context(...) how to get the digest.\n *\n * @param ctx\n *    Points to the SHA256 context.\n * @param dataChunks\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param dataChunkLength\n *    Points to an array of integers that hold the length of each data chunk.\n *\n */\nvoid sha256Ctx(void* ctx, unsigned char* dataChunks[],\n               unsigned int dataChunkLength[]);\n\n/**\n * @}\n */\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/sha384.cpp",
    "content": "/*\n  Copyright (C) 2012 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/**\n * @author: Werner Dittmann\n */\n\n#include <zrtp/crypto/sha2.h>\n#include <zrtp/crypto/sha384.h>\n\nvoid sha384(unsigned char *data, unsigned int dataLength, unsigned char *digest )\n{\n    sha384_ctx ctx;\n\n    sha384_begin(&ctx);\n    sha384_hash(data, dataLength, &ctx);\n    sha384_end(digest, &ctx);\n}\n\nvoid sha384(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)\n{\n    sha384_ctx ctx;\n\n    sha384_begin(&ctx);\n    while(*dataChunks) {\n        sha384_hash(*dataChunks, *dataChunckLength, &ctx);\n        dataChunks++;\n        dataChunckLength++;\n    }\n    sha384_end(digest, &ctx);\n}\n\nvoid* createSha384Context()\n{\n    sha384_ctx *ctx = reinterpret_cast<sha384_ctx*>(malloc(sizeof(sha384_ctx)));\n    if (ctx != NULL) {\n        sha384_begin(ctx);\n    }\n    return (void*)ctx;\n}\n\nvoid closeSha384Context(void* ctx, unsigned char* digest)\n{\n    sha384_ctx* hd = reinterpret_cast<sha384_ctx*>(ctx);\n\n    if (digest != NULL && hd != NULL) {\n        sha384_end(digest, hd);\n    }\n    free(hd);\n}\n\nvoid* initializeSha384Context(void* ctx)\n{\n    sha384_ctx* hd = reinterpret_cast<sha384_ctx*>(ctx);\n\n    if (hd != NULL) {\n        sha384_begin(hd);\n    }\n    return (void*)hd;\n}\n\nvoid finalizeSha384Context(void* ctx, unsigned char* digest)\n{\n    sha384_ctx* hd = reinterpret_cast<sha384_ctx*>(ctx);\n\n    if (digest != NULL && hd != NULL) {\n        sha384_end(digest, hd);\n    }\n}\n\nvoid sha384Ctx(void* ctx, unsigned char* data, unsigned int dataLength)\n{\n    sha384_ctx* hd = reinterpret_cast<sha384_ctx*>(ctx);\n\n    sha384_hash(data, dataLength, hd);\n}\n\nvoid sha384Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])\n{\n    sha384_ctx* hd = reinterpret_cast<sha384_ctx*>(ctx);\n\n    while (*dataChunks) {\n        sha384_hash(*dataChunks, *dataChunkLength, hd);\n        dataChunks++;\n        dataChunkLength++;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/sha384.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/**\n * Functions to compute SHA384 digest.\n *\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef _SHA384_H\n#define _SHA384_H\n\n/**\n * @file sha384.h\n * @brief Function that provide SHA384 support\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <stdint.h>\n\n#ifndef SHA384_DIGEST_LENGTH\n#define SHA384_DIGEST_LENGTH 48\n#endif\n\n/**\n * Compute SHA384 digest.\n *\n * This functions takes one data chunk and computes its SHA384 digest. This \n * function creates and deletes an own SHA384 context to perform the SHA384\n * operations.\n *\n * @param data\n *    Points to the data chunk.\n * @param data_length\n *    Length of the data in bytes\n * @param digest\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 48 bytes (SHA384_DIGEST_LENGTH).\n */\nvoid sha384(unsigned char *data,\n            unsigned int data_length,\n            unsigned char *digest);\n\n/**\n * Compute SHA384 digest over several data cunks.\n *\n * This functions takes several data chunks and computes the SHA384 digest.\n * This function creates and deletes an own SHA384 context to perform the\n * SHA384 operations.\n *\n * @param data\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param data_length\n *    Points to an array of integers that hold the length of each data chunk.\n * @param digest\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 48 bytes (SHA384_DIGEST_LENGTH).\n */\nvoid sha384(unsigned char *data[],\n            unsigned int data_length[],\n            unsigned char *digest);\n/**\n * Create and initialize a SHA384 context.\n *\n * An application uses this context to hash several data into one SHA384\n * digest. See also sha384Ctx(...) and closeSha384Context(...).\n *\n * @return Returns a pointer to the initialized SHA384 context or @c NULL in case of an error.\n */\nvoid* createSha384Context();\n\n/**\n * Compute a digest and close the SHA384 digest.\n *\n * An application uses this function to compute the SHA384 digest and to\n * close the SHA384 context. This function calls @c free to free the context.\n *\n * @param ctx\n *    Points to the SHA384 context.\n * @param digest\n *    If this pointer is not NULL then it must point to a byte array that\n *    is big enough to hold the SHA384 digest (384 bit = 48 Bytes). If this\n *    pointer is NULL then the functions does not compute the digest but\n *    closes the context only. The context cannot be used anymore.\n */\nvoid closeSha384Context(void* ctx, unsigned char* digest);\n\n/**\n * Initialize a SHA384 context.\n *\n * An application uses this context to hash several data into one SHA384\n * digest. See also sha384Ctx(...) and closeSha384Context(...).\n *\n * @param ctx\n *    Points to the SHA384 context.\n * @return Returns the pointer to the initialized SHA384 context\n */\nvoid* initializeSha384Context(void* ctx);\n\n/**\n * Compute a digest.\n *\n * An application uses this function to compute the SHA384 digest.\n *\n * @param ctx\n *    Points to the SHA384 context.\n * @param digest\n *    If this pointer is not NULL then it must point to a byte array that\n *    is big enough to hold the SHA384 digest (384 bit = 48 Bytes). If this\n *    pointer is NULL then the functions does not compute the digest.\n */\nvoid finalizeSha384Context(void* ctx, unsigned char* digest);\n\n/**\n * Update the SHA384 context with data.\n *\n * This functions updates the SHA384 context with some data.\n * See also CloseSha384Context(...) how to get the digest.\n *\n * @param ctx\n *    Points to the SHA384 context.\n * @param data\n *    Points to the data to update the context.\n * @param dataLength\n *    The length of the data in bytes.\n */\nvoid sha384Ctx(void* ctx, unsigned char* data, \n               unsigned int dataLength);\n\n/**\n * Update the SHA384 context with several data chunks.\n *\n * This functions updates the SHA384 context with some data.\n * See also CloseSha384Context(...) how to get the digest.\n *\n * @param ctx\n *    Points to the SHA384 context.\n * @param dataChunks\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param dataChunkLength\n *    Points to an array of integers that hold the length of each data chunk.\n *\n */\nvoid sha384Ctx(void* ctx, unsigned char* dataChunks[],\n               unsigned int dataChunkLength[]);\n\n/**\n * @}\n */\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/skein256.cpp",
    "content": "/*\n  Copyright (C) 2013 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/**\n * @author: Werner Dittmann\n */\n\n#include <cryptcommon/skeinApi.h>\n#include <zrtp/crypto/skein256.h>\n\n#include <stdlib.h>\n\nvoid skein256(unsigned char *data, unsigned int dataLength, unsigned char *digest )\n{\n    SkeinCtx_t ctx;\n\n    skeinCtxPrepare(&ctx, SKEIN_SIZE);\n    skeinInit(&ctx, SKEIN256_DIGEST_LENGTH*8);\n    skeinUpdate(&ctx, data, dataLength);\n\n    skeinFinal(&ctx, digest);\n}\n\nvoid skein256(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)\n{\n    SkeinCtx_t ctx;\n\n    skeinCtxPrepare(&ctx, SKEIN_SIZE);\n    skeinInit(&ctx, SKEIN256_DIGEST_LENGTH*8);\n    while(*dataChunks) {\n        skeinUpdate(&ctx, *dataChunks, *dataChunckLength);\n        dataChunks++;\n        dataChunckLength++;\n    }\n    skeinFinal(&ctx, digest);\n}\n\nvoid* createSkein256Context()\n{\n    SkeinCtx_t *ctx = reinterpret_cast<SkeinCtx_t *>(malloc(sizeof(SkeinCtx_t )));\n    skeinCtxPrepare(ctx, SKEIN_SIZE);\n    skeinInit(ctx, SKEIN256_DIGEST_LENGTH*8);\n    return (void*)ctx;\n}\n\nvoid closeSkein256Context(void* ctx, unsigned char* digest)\n{\n    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);\n\n    if (digest != NULL) {\n        skeinFinal(hd, digest);\n    }\n    free(hd);\n}\n\nvoid* initializeSkein256Context(void* ctx)\n{\n    SkeinCtx_t *hd = reinterpret_cast<SkeinCtx_t *>(ctx);\n    if (hd != NULL) {\n        skeinCtxPrepare(hd, SKEIN_SIZE);\n        skeinInit(hd, SKEIN256_DIGEST_LENGTH*8);\n    }\n    return (void*)hd;\n}\n\nvoid finalizeSkein256Context(void* ctx, unsigned char* digest)\n{\n    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);\n\n    if (digest != NULL && hd != NULL) {\n        skeinFinal(hd, digest);\n    }\n}\n\nvoid skein256Ctx(void* ctx, unsigned char* data, unsigned int dataLength)\n{\n    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);\n\n    skeinUpdate(hd, data, dataLength);\n}\n\nvoid skein256Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])\n{\n    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);\n\n    while (*dataChunks) {\n        skeinUpdate(hd, *dataChunks, *dataChunkLength);\n        dataChunks++;\n        dataChunkLength++;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/skein256.h",
    "content": "/*\n  Copyright (C) 2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/**\n * Functions to compute Skein256 digest.\n *\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef _SKEIN256_H\n#define _SKEIN256_H\n\n/**\n * @file skein256.h\n * @brief Functions that provide Skein256 support\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <stdint.h>\n\n#ifndef SKEIN256_DIGEST_LENGTH\n#define SKEIN256_DIGEST_LENGTH  32\n#endif\n#define SKEIN_SIZE Skein512\n\n\n/**\n * Compute Skein256 digest.\n *\n * This functions takes one data chunk and computes its Skein256 digest. This \n * function creates and deletes an own Skein256 context to perform the Skein256\n * operations.\n *\n * @param data\n *    Points to the data chunk.\n * @param data_length\n *    Length of the data in bytes\n * @param digest\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 32 bytes (Skein256_DIGEST_LENGTH).\n */\nvoid skein256(unsigned char *data,\n            unsigned int data_length,\n            unsigned char *digest);\n\n/**\n * Compute Skein256 digest over several data cunks.\n *\n * This functions takes several data chunks and computes the Skein256 digest.\n * This function creates and deletes an own Skein256 context to perform the\n * Skein256 operations.\n *\n * @param data\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param data_length\n *    Points to an array of integers that hold the length of each data chunk.\n * @param digest\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 32 bytes (Skein256_DIGEST_LENGTH).\n */\nvoid skein256(unsigned char *data[],\n            unsigned int data_length[],\n            unsigned char *digest);\n/**\n * Create and initialize a Skein256 context.\n *\n * An application uses this context to hash several data into one Skein256\n * digest. See also skein256Ctx(...) and closeSha256Context(...).\n *\n * @return Returns a pointer to the initialized Skein256 context or @c NULL in case of an error.\n */\nvoid* createSkein256Context();\n\n/**\n * Compute a digest and close the SHa256 digest.\n *\n * An application uses this function to compute the Skein256 digest and to\n * close the Skein256 context.\n *\n * @param ctx\n *    Points to the Skein256 context.\n * @param digest\n *    If this pointer is not NULL then it must point to a byte array that\n *    is big enough to hold the Skein256 digest (256 bit = 32 Bytes). If this\n *    pointer is NULL then the functions does not compute the digest but\n *    closes the context only. The context cannot be used anymore.\n */\nvoid closeSkein256Context(void* ctx,\n                        unsigned char* digest);\n\n/**\n * Initialize a Skein256 context.\n *\n * An application uses this context to hash several data into one Skein256\n * digest. See also skein256Ctx(...) and finalizeSkein256Context(...).\n *\n * @param ctx\n *    Points to the Skein256 context.\n * @return Returns a pointer to the initialized Skein256 context\n */\nvoid* initializeSkein256Context(void* ctx);\n\n/**\n * Compute a digest.\n *\n * An application uses this function to compute the Skein256 digest.\n *\n * @param ctx\n *    Points to the Skein256 context.\n * @param digest\n *    If this pointer is not NULL then it must point to a byte array that\n *    is big enough to hold the Skei256 digest (256 bit = 32 Bytes). If this\n *    pointer is NULL then the functions does not compute the digest.\n */\nvoid finalizeSkein256Context(void* ctx, unsigned char* digest);\n\n/**\n * Update the Skein256 context with data.\n *\n * This functions updates the Skein256 context with some data.\n * See also CloseSha256Context(...) how to get the digest.\n *\n * @param ctx\n *    Points to the Skein256 context.\n * @param data\n *    Points to the data to update the context.\n * @param dataLength\n *    The length of the data in bytes.\n */\nvoid skein256Ctx(void* ctx, unsigned char* data, \n               unsigned int dataLength);\n\n/**\n * Update the Skein256 context with several data chunks.\n *\n * This functions updates the Skein256 context with some data.\n * See also CloseSha256Context(...) how to get the digest.\n *\n * @param ctx\n *    Points to the Skein256 context.\n * @param dataChunks\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param dataChunkLength\n *    Points to an array of integers that hold the length of each data chunk.\n *\n */\nvoid skein256Ctx(void* ctx, unsigned char* dataChunks[],\n               unsigned int dataChunkLength[]);\n\n/**\n * @}\n */\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/skein384.cpp",
    "content": "/*\n  Copyright (C) 2013 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/**\n * @author: Werner Dittmann\n */\n\n#include <cryptcommon/skeinApi.h>\n#include <zrtp/crypto/skein384.h>\n\n#include <stdlib.h>\n\n#define SKEIN_SIZE Skein512\n#define SKEIN384_DIGEST_LENGTH  48\n\nvoid skein384(unsigned char *data, unsigned int dataLength, unsigned char *digest )\n{\n    SkeinCtx_t ctx;\n\n    skeinCtxPrepare(&ctx, SKEIN_SIZE);\n    skeinInit(&ctx, SKEIN384_DIGEST_LENGTH*8);\n    skeinUpdate(&ctx, data, dataLength);\n\n    skeinFinal(&ctx, digest);\n}\n\nvoid skein384(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)\n{\n    SkeinCtx_t ctx;\n\n    skeinCtxPrepare(&ctx, SKEIN_SIZE);\n    skeinInit(&ctx, SKEIN384_DIGEST_LENGTH*8);\n    while(*dataChunks) {\n        skeinUpdate(&ctx, *dataChunks, *dataChunckLength);\n        dataChunks++;\n        dataChunckLength++;\n    }\n    skeinFinal(&ctx, digest);\n}\n\nvoid* createSkein384Context()\n{\n    SkeinCtx_t *ctx = reinterpret_cast<SkeinCtx_t *>(malloc(sizeof(SkeinCtx_t )));\n    if (ctx != NULL) {\n        skeinCtxPrepare(ctx, SKEIN_SIZE);\n        skeinInit(ctx, SKEIN384_DIGEST_LENGTH*8);\n    }\n    return (void*)ctx;\n}\n\nvoid closeSkein384Context(void* ctx, unsigned char* digest)\n{\n    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);\n\n    if (digest != NULL && hd != NULL) {\n        skeinFinal(hd, digest);\n    }\n    free(hd);\n}\n\nvoid* initializeSkein384Context(void* ctx)\n{\n    SkeinCtx_t *hd = reinterpret_cast<SkeinCtx_t *>(ctx);\n    if (hd != NULL) {\n        skeinCtxPrepare(hd, SKEIN_SIZE);\n        skeinInit(hd, SKEIN384_DIGEST_LENGTH*8);\n    }\n    return (void*)hd;\n}\n\nvoid finalizeSkein384Context(void* ctx, unsigned char* digest)\n{\n    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);\n\n    if (digest != NULL && hd != NULL) {\n        skeinFinal(hd, digest);\n    }\n}\n\nvoid skein384Ctx(void* ctx, unsigned char* data, unsigned int dataLength)\n{\n    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);\n\n    skeinUpdate(hd, data, dataLength);\n}\n\nvoid skein384Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])\n{\n    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);\n\n    while (*dataChunks) {\n        skeinUpdate(hd, *dataChunks, *dataChunkLength);\n        dataChunks++;\n        dataChunkLength++;\n    }\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/skein384.h",
    "content": "/*\n  Copyright (C) 2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/**\n * Functions to compute Skein384 digest.\n *\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef _SKEIN384_H\n#define _SKEIN384_H\n\n/**\n * @file skein384.h\n * @brief Functions that provide Skein384 support\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <stdint.h>\n\n#ifndef SKEIN384_DIGEST_LENGTH\n#define SKEIN384_DIGEST_LENGTH  48\n#endif\n#define SKEIN_SIZE Skein512\n\n\n/**\n * Compute Skein384 digest.\n *\n * This functions takes one data chunk and computes its Skein384 digest. This \n * function creates and deletes an own Skein384 context to perform the Skein384\n * operations.\n *\n * @param data\n *    Points to the data chunk.\n * @param data_length\n *    Length of the data in bytes\n * @param digest\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 48 bytes (Skein384_DIGEST_LENGTH).\n */\nvoid skein384(unsigned char *data,\n            unsigned int data_length,\n            unsigned char *digest);\n\n/**\n * Compute Skein384 digest over several data cunks.\n *\n * This functions takes several data chunks and computes the Skein384 digest.\n * This function creates and deletes an own Skein384 context to perform the\n * Skein384 operations.\n *\n * @param data\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param data_length\n *    Points to an array of integers that hold the length of each data chunk.\n * @param digest\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 48 bytes (Skein384_DIGEST_LENGTH).\n */\nvoid skein384(unsigned char *data[],\n            unsigned int data_length[],\n            unsigned char *digest);\n/**\n * Create and initialize a Skein384 context.\n *\n * An application uses this context to hash several data into one Skein384\n * digest. See also skein384Ctx(...) and closeSha384Context(...).\n *\n * @return Returns a pointer to the initialized Skein384 context or @c NULL in case of an error.\n */\nvoid* createSkein384Context();\n\n/**\n * Compute a digest and close the SHa384 digest.\n *\n * An application uses this function to compute the Skein384 digest and to\n * close the Skein384 context.\n *\n * @param ctx\n *    Points to the Skein384 context.\n * @param digest\n *    If this pointer is not NULL then it must point to a byte array that\n *    is big enough to hold the Skein384 digest (384 bit = 48 Bytes). If this\n *    pointer is NULL then the functions does not compute the digest but\n *    closes the context only. The context cannot be used anymore.\n */\nvoid closeSkein384Context(void* ctx, unsigned char* digest);\n\n/**\n * Initialize a Skein384 context.\n *\n * An application uses this context to hash several data into one Skein384\n * digest. See also skein384Ctx(...) and finalizeSkein384Context(...).\n *\n * @param ctx\n *    Points to the Skein384 context.\n * @return Returns a pointer to the initialized Skein384 context\n */\nvoid* initializeSkein384Context(void* ctx);\n\n/**\n * Compute a digest.\n *\n * An application uses this function to compute the Skein384 digest.\n *\n * @param ctx\n *    Points to the Skein384 context.\n * @param digest\n *    If this pointer is not NULL then it must point to a byte array that\n *    is big enough to hold the Skei384 digest (384 bit = 48 Bytes). If this\n *    pointer is NULL then the functions does not compute the digest.\n */\nvoid finalizeSkein384Context(void* ctx, unsigned char* digest);\n\n/**\n * Update the Skein384 context with data.\n *\n * This functions updates the Skein384 context with some data.\n * See also CloseSha384Context(...) how to get the digest.\n *\n * @param ctx\n *    Points to the Skein384 context.\n * @param data\n *    Points to the data to update the context.\n * @param dataLength\n *    The length of the data in bytes.\n */\nvoid skein384Ctx(void* ctx, unsigned char* data, unsigned int dataLength);\n\n/**\n * Update the Skein384 context with several data chunks.\n *\n * This functions updates the Skein384 context with some data.\n * See also CloseSha384Context(...) how to get the digest.\n *\n * @param ctx\n *    Points to the Skein384 context.\n * @param dataChunks\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param dataChunkLength\n *    Points to an array of integers that hold the length of each data chunk.\n *\n */\nvoid skein384Ctx(void* ctx, unsigned char* dataChunks[],\n               unsigned int dataChunkLength[]);\n\n/**\n * @}\n */\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/skeinMac256.cpp",
    "content": "/*\n  Copyright (C) 2013 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/*\n * Authors: Werner Dittmann\n */\n\n#include <cryptcommon/macSkein.h>\n#include <zrtp/crypto/skeinMac256.h>\n\nvoid macSkein256(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)\n{\n    macSkein(key, keyLength, data, dataLength, mac, SKEIN256_DIGEST_LENGTH*8, SKEIN_SIZE);\n    *macLength = SKEIN256_DIGEST_LENGTH;\n}\n\n\nvoid macSkein256( uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunkLength[], uint8_t* mac, uint32_t* macLength )\n{\n    macSkein(key, keyLength, (const uint8_t**)dataChunks, dataChunkLength, mac, SKEIN256_DIGEST_LENGTH*8, SKEIN_SIZE);\n    *macLength = SKEIN256_DIGEST_LENGTH;\n}\n\nvoid* createMacSkein256Context(uint8_t* key, int32_t keyLength)\n{\n    return createSkeinMacContext(key, keyLength, SKEIN256_DIGEST_LENGTH*8, SKEIN_SIZE);\n}\n\nvoid macSkein256Ctx(void* ctx, const uint8_t* data, uint32_t dataLength, uint8_t* mac, int32_t* macLength)\n{\n\n    macSkeinCtx(ctx, data, dataLength, mac);\n    *macLength = SKEIN256_DIGEST_LENGTH;\n}\n\nvoid macSkein256Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[], uint8_t* mac, int32_t* macLength )\n{\n    macSkeinCtx(ctx, data, dataLength, mac);\n    *macLength = SKEIN256_DIGEST_LENGTH;\n}\n\nvoid freeMacSkein256Context(void* ctx)\n{\n    freeSkeinMacContext(ctx);\n}"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/skeinMac256.h",
    "content": "/*\n  Copyright (C) 2013 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n*/\n\n/**\n * Methods to compute a Skein256 HMAC.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef HMAC_SKEIN256_H\n#define HMAC_SKEIN256_H\n\n/**\n * @file skeinMac256.h\n * @brief Function that provide Skein256 HMAC support\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <stdint.h>\n\n#ifndef SKEIN256_DIGEST_LENGTH\n#define SKEIN256_DIGEST_LENGTH 32\n#endif\n\n#define SKEIN_SIZE Skein512\n\n/**\n * Compute Skein256 HMAC.\n *\n * This functions takes one data chunk and computes its Skein256 HMAC.\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lneght of the MAC key in bytes\n * @param data\n *    Points to the data chunk.\n * @param data_length\n *    Length of the data in bytes\n * @param mac\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 32 bytes (SKEIN256_DIGEST_LENGTH).\n * @param mac_length\n *    Point to an integer that receives the length of the computed HMAC.\n */\nvoid macSkein256( uint8_t* key, uint32_t key_length, uint8_t* data, int32_t data_length, uint8_t* mac, uint32_t* mac_length );\n\n/**\n * Compute Skein256 HMAC over several data cunks.\n *\n * This functions takes several data chunk and computes the Skein256 HAMAC.\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lneght of the MAC key in bytes\n * @param data\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param data_length\n *    Points to an array of integers that hold the length of each data chunk.\n * @param mac\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 32 bytes (SKEIN256_DIGEST_LENGTH).\n * @param mac_length\n *    Point to an integer that receives the length of the computed HMAC.\n */\n\nvoid macSkein256( uint8_t* key, uint32_t key_length, uint8_t* data[], uint32_t data_length[], uint8_t* mac, uint32_t* mac_length );\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/skeinMac384.cpp",
    "content": "/*\n  Copyright (C) 2013 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/*\n * Authors: Werner Dittmann\n */\n\n#define SKEIN_SIZE Skein512\n#define SKEIN384_DIGEST_LENGTH  48\n\n#include <cryptcommon/macSkein.h>\n#include <zrtp/crypto/skeinMac384.h>\n\nvoid macSkein384(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)\n{\n    macSkein(key, keyLength, data, dataLength, mac, SKEIN384_DIGEST_LENGTH*8, SKEIN_SIZE);\n    *macLength = SKEIN384_DIGEST_LENGTH;\n}\n\n\nvoid macSkein384( uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunkLength[], uint8_t* mac, uint32_t* macLength )\n{\n    macSkein(key, keyLength, (const uint8_t**)dataChunks, dataChunkLength, mac, SKEIN384_DIGEST_LENGTH*8, SKEIN_SIZE);\n    *macLength = SKEIN384_DIGEST_LENGTH;\n}\n\nvoid* createMacSkein384Context(uint8_t* key, int32_t keyLength)\n{\n    return createSkeinMacContext(key, keyLength, SKEIN384_DIGEST_LENGTH*8, SKEIN_SIZE);\n}\n\nvoid macSkein384Ctx(void* ctx, const uint8_t* data, uint32_t dataLength, uint8_t* mac, int32_t* macLength)\n{\n\n    macSkeinCtx(ctx, data, dataLength, mac);\n    *macLength = SKEIN384_DIGEST_LENGTH;\n}\n\nvoid macSkein384Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[], uint8_t* mac, int32_t* macLength )\n{\n    macSkeinCtx(ctx, data, dataLength, mac);\n    *macLength = SKEIN384_DIGEST_LENGTH;\n}\n\nvoid freeMacSkein384Context(void* ctx)\n{\n    freeSkeinMacContext(ctx);\n}"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/skeinMac384.h",
    "content": "/*\n  Copyright (C) 2013 Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n*/\n\n/**\n * Methods to compute a Skein384 HMAC.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef HMAC_SKEIN384_H\n#define HMAC_SKEIN384_H\n\n/**\n * @file skeinMac384.h\n * @brief Function that provide Skein384 HMAC support\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <stdint.h>\n\n#ifndef SKEIN384_DIGEST_LENGTH\n#define SKEIN384_DIGEST_LENGTH 48\n#endif\n\n#define SKEIN_SIZE Skein512\n\n/**\n * Compute Skein384 HMAC.\n *\n * This functions takes one data chunk and computes its Skein384 HMAC.\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lneght of the MAC key in bytes\n * @param data\n *    Points to the data chunk.\n * @param data_length\n *    Length of the data in bytes\n * @param mac\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 48 bytes (SKEIN384_DIGEST_LENGTH).\n * @param mac_length\n *    Point to an integer that receives the length of the computed HMAC.\n */\nvoid macSkein384( uint8_t* key, uint32_t key_length, uint8_t* data, int32_t data_length, uint8_t* mac, uint32_t* mac_length );\n\n/**\n * Compute Skein384 HMAC over several data cunks.\n *\n * This functions takes several data chunk and computes the Skein384 HAMAC.\n *\n * @param key\n *    The MAC key.\n * @param key_length\n *    Lneght of the MAC key in bytes\n * @param data\n *    Points to an array of pointers that point to the data chunks. A NULL\n *    pointer in an array element terminates the data chunks.\n * @param data_length\n *    Points to an array of integers that hold the length of each data chunk.\n * @param mac\n *    Points to a buffer that receives the computed digest. This\n *    buffer must have a size of at least 48 bytes (SKEIN384_DIGEST_LENGTH).\n * @param mac_length\n *    Point to an integer that receives the length of the computed HMAC.\n */\n\nvoid macSkein384( uint8_t* key, uint32_t key_length, uint8_t* data[], uint32_t data_length[], uint8_t* mac, uint32_t* mac_length );\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/twoCFB.cpp",
    "content": "/*\n  Copyright (C) 2011 by Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/** Copyright (C) 2011\n *\n * @author  Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <string.h>\n\n#include <zrtp/crypto/twoCFB.h>\n#include <cryptcommon/twofish.h>\n\nstatic int initialized = 0;\n\nvoid twoCfbEncrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength)\n{\n    Twofish_key keyCtx;\n    int usedBytes = 0;\n\n    if (!initialized) {\n        Twofish_initialise();\n        initialized = 1;\n    }\n\n    memset(&keyCtx, 0, sizeof(Twofish_key));\n    Twofish_prepare_key(key, keyLength, &keyCtx);\n\n    Twofish_cfb128_encrypt(&keyCtx, (Twofish_Byte*)data, (Twofish_Byte*)data,\n\t\t\t   (size_t)dataLength, (Twofish_Byte*)IV, &usedBytes);\n}\n\n\nvoid twoCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength)\n{\n    Twofish_key keyCtx;\n    int usedBytes = 0;\n\n    if (!initialized) {\n        Twofish_initialise();\n        initialized = 1;\n    }\n\n    memset(&keyCtx, 0, sizeof(Twofish_key));\n    Twofish_prepare_key(key, keyLength, &keyCtx);\n\n    Twofish_cfb128_decrypt(&keyCtx, (Twofish_Byte*)data, (Twofish_Byte*)data, \n\t\t\t   (size_t)dataLength, (Twofish_Byte*)IV, &usedBytes);\n}\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/twoCFB.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef _TWOCFB_H__\n#define _TWOCFB_H__\n\n#include <stdint.h>\n\n/**\n * @file aesCFB.h\n * @brief Function that provide AES CFB mode support\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#ifndef TWO_BLOCK_SIZE\n#define TWO_BLOCK_SIZE 16\n#endif\n\n/**\n * Encrypt data with Twofish CFB mode, full block feedback size.\n *\n * This functions takes one data chunk and encrypts it with\n * Twofish CFB mode. The lenght of the data may be arbitrary and\n * it is not needed to be a multiple of Twofish blocksize.\n *\n * @param key\n *    Points to the key bytes.\n * @param keyLength\n *    Length of the key in bytes\n * @param IV\n *    The initialization vector which must be TWO_BLOCKSIZE (16) bytes.\n * @param data\n *    Points to a buffer that contains and receives the computed\n *    the data (in-place encryption).\n * @param dataLength\n *    Length of the data in bytes\n */\n\nvoid twoCfbEncrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength);\n\n/**\n * Decrypt data with Twofish CFB mode, full block feedback size.\n *\n * This functions takes one data chunk and decrypts it with\n * Twofish CFB mode. The lenght of the data may be arbitrary and\n * it is not needed to be a multiple of Twofish blocksize.\n *\n * @param key\n *    Points to the key bytes.\n * @param keyLength\n *    Length of the key in bytes\n * @param IV\n *    The initialization vector which must be TWO_BLOCKSIZE (16) bytes.\n * @param data\n *    Points to a buffer that contains and receives the computed\n *    the data (in-place decryption).\n * @param dataLength\n *    Length of the data in bytes\n */\n\nvoid twoCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength);\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/zrtpDH.cpp",
    "content": "/*\n  Copyright (C) 2006, 2009 by Werner Dittmann\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\n\n * In addition, as a special exception, the copyright holders give\n * permission to link the code of portions of this program with the\n * OpenSSL library under certain conditions as described in each\n * individual source file, and distribute linked combinations\n * including the two.\n * You must obey the GNU General Public License in all respects\n * for all of the code used other than OpenSSL.  If you modify\n * file(s) with this exception, you may extend this exception to your\n * version of the file(s), but you are not obligated to do so.  If you\n * do not wish to do so, delete this exception statement from your\n * version.  If you delete this exception statement from all source\n * files in the program, then also delete it here.\n */\n\n/** Copyright (C) 2006, 2009\n *\n * @author  Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n#include <bn.h>\n#include <bnprint.h>\n#include <ec/ec.h>\n#include <ec/ecdh.h>\n#include <zrtp/crypto/zrtpDH.h>\n#include <zrtp/libzrtpcpp/ZrtpTextData.h>\n#include <cryptcommon/aes.h>\n#include <cryptcommon/ZrtpRandom.h>\n\n\nstatic BigNum bnP2048 = {0};\nstatic BigNum bnP3072 = {0};\n\nstatic BigNum bnP2048MinusOne = {0};\nstatic BigNum bnP3072MinusOne = {0};\n\nstatic BigNum two = {0};\n\nstatic uint8_t dhinit = 0;\n\ntypedef struct _dhCtx {\n    BigNum privKey;\n    BigNum pubKey;\n    EcCurve curve;\n    EcPoint pubPoint;\n} dhCtx;\n\nvoid randomZRTP(uint8_t *buf, int32_t length)\n{\n    ZrtpRandom::getRandomData(buf, length);\n}\n\nstatic const uint8_t P2048[] =\n{\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,\n    0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,\n    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,\n    0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,\n    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,\n    0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,\n    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,\n    0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,\n    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,\n    0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,\n    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,\n    0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,\n    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,\n    0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,\n    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,\n    0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,\n    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,\n    0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,\n    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,\n    0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,\n    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xFF, 0xFF, 0xFF, 0xFF\n};\n\nstatic const uint8_t P3072[] =\n{\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,\n    0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,\n    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,\n    0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,\n    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,\n    0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,\n    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,\n    0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,\n    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,\n    0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,\n    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,\n    0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,\n    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,\n    0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,\n    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,\n    0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,\n    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,\n    0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,\n    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,\n    0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,\n    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,\n    0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,\n    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,\n    0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,\n    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,\n    0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,\n    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,\n    0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,\n    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,\n    0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,\n    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,\n    0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\n\n/* **************\nstatic const uint8_t P4096[] =\n{\n0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,\n0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,\n0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,\n0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,\n0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,\n0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,\n0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,\n0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,\n0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,\n0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,\n0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,\n0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,\n0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,\n0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,\n0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,\n0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,\n0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,\n0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,\n0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,\n0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,\n0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,\n0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,\n0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,\n0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,\n0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,\n0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,\n0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,\n0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,\n0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,\n0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,\n0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,\n0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,\n0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,\n0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,\n0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,\n0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,\n0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,\n0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,\n0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,\n0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,\n0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,\n0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,\n0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\n*************** */\n\nZrtpDH::ZrtpDH(const char* type) {\n\n    uint8_t random[64];\n\n    ctx = static_cast<void*>(new dhCtx);\n    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);\n\n    // Well - the algo type is only 4 char thus cast to int32 and compare\n    if (*(int32_t*)type == *(int32_t*)dh2k) {\n        pkType = DH2K;\n    }\n    else if (*(int32_t*)type == *(int32_t*)dh3k) {\n        pkType = DH3K;\n    }\n    else if (*(int32_t*)type == *(int32_t*)ec25) {\n        pkType = EC25;\n    }\n    else if (*(int32_t*)type == *(int32_t*)ec38) {\n        pkType = EC38;\n    }\n    else if (*(int32_t*)type == *(int32_t*)e255) {\n        pkType = E255;\n    }\n    else if (*(int32_t*)type == *(int32_t*)e414) {\n        pkType = E414;\n    }\n    else {\n        return;\n    }\n\n    randomZRTP(random, sizeof(random));\n\n    if (!dhinit) {\n        bnBegin(&two);\n        bnSetQ(&two, 2);\n\n        bnBegin(&bnP2048);\n        bnInsertBigBytes(&bnP2048, P2048, 0, sizeof(P2048));\n        bnBegin(&bnP3072);\n        bnInsertBigBytes(&bnP3072, P3072, 0, sizeof(P3072));\n\n        bnBegin(&bnP2048MinusOne);\n        bnCopy(&bnP2048MinusOne, &bnP2048);\n        bnSubQ(&bnP2048MinusOne, 1);\n\n        bnBegin(&bnP3072MinusOne);\n        bnCopy(&bnP3072MinusOne, &bnP3072);\n        bnSubQ(&bnP3072MinusOne, 1);\n\n        dhinit = 1;\n    }\n\n    bnBegin(&tmpCtx->privKey);\n    INIT_EC_POINT(&tmpCtx->pubPoint);\n\n    switch (pkType) {\n    case DH2K:\n    case DH3K:\n        bnInsertBigBytes(&tmpCtx->privKey, random, 0, 256/8);\n        break;\n\n    case EC25:\n        ecGetCurveNistECp(NIST256P, &tmpCtx->curve);\n        ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);\n        break;\n\n    case EC38:\n        ecGetCurveNistECp(NIST384P, &tmpCtx->curve);\n        ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);\n        break;\n\n    case E255:\n        ecGetCurvesCurve(Curve25519, &tmpCtx->curve);\n        ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);\n        break;\n\n    case E414:\n        ecGetCurvesCurve(Curve3617, &tmpCtx->curve);\n        ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);\n        break;\n    }\n}\n\nZrtpDH::~ZrtpDH() {\n    if (ctx == NULL)\n        return;\n\n    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);\n    FREE_EC_POINT(&tmpCtx->pubPoint);\n    bnEnd(&tmpCtx->privKey);\n\n    switch (pkType) {\n    case DH2K:\n    case DH3K:\n        bnEnd(&tmpCtx->pubKey);\n        break;\n\n    case EC25:\n    case EC38:\n        ecFreeCurveNistECp(&tmpCtx->curve);\n        break;\n\n    case E255:\n    case E414:\n        ecFreeCurvesCurve(&tmpCtx->curve);\n        break;\n    }\n}\n\nint32_t ZrtpDH::computeSecretKey(uint8_t *pubKeyBytes, uint8_t *secret) {\n\n    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);\n\n    int32_t length = getDhSize();\n\n    BigNum sec;\n    if (pkType == DH2K || pkType == DH3K) {\n        BigNum pubKeyOther;\n        bnBegin(&pubKeyOther);\n        bnBegin(&sec);\n\n        bnInsertBigBytes(&pubKeyOther, pubKeyBytes, 0, length);\n\n        if (pkType == DH2K) {\n            bnExpMod(&sec, &pubKeyOther, &tmpCtx->privKey, &bnP2048);\n        }\n        else if (pkType == DH3K) {\n            bnExpMod(&sec, &pubKeyOther, &tmpCtx->privKey, &bnP3072);\n        }\n        else {\n            return 0;\n        }\n        bnEnd(&pubKeyOther);\n        bnExtractBigBytes(&sec, secret, 0, length);\n        bnEnd(&sec);\n\n        return length;\n    }\n\n    if (pkType == EC25 || pkType == EC38 || pkType == E414) {\n        int32_t len = getPubKeySize() / 2;\n        EcPoint pub;\n\n        bnBegin(&sec);\n        INIT_EC_POINT(&pub);\n        bnSetQ(pub.z, 1);               // initialze Z to one, these are affine coords\n\n        bnInsertBigBytes(pub.x, pubKeyBytes, 0, len);\n        bnInsertBigBytes(pub.y, pubKeyBytes+len, 0, len);\n\n        /* Generate agreement for responder: sec = pub * privKey */\n        ecdhComputeAgreement(&tmpCtx->curve, &sec, &pub, &tmpCtx->privKey);\n        bnExtractBigBytes(&sec, secret, 0, length);\n        bnEnd(&sec);\n        FREE_EC_POINT(&pub);\n\n        return length;\n    }\n    if (pkType == E255) {\n        int32_t len = getPubKeySize();\n        EcPoint pub;\n\n        bnBegin(&sec);\n        INIT_EC_POINT(&pub);\n\n        bnInsertLittleBytes(pub.x, pubKeyBytes, 0, len);\n\n        /* Generate agreement for responder: sec = pub * privKey */\n        ecdhComputeAgreement(&tmpCtx->curve, &sec, &pub, &tmpCtx->privKey);\n        bnExtractLittleBytes(&sec, secret, 0, length);\n        bnEnd(&sec);\n        FREE_EC_POINT(&pub);\n\n        return length;\n    }\n    return -1;\n}\n\nint32_t ZrtpDH::generatePublicKey()\n{\n    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);\n\n    bnBegin(&tmpCtx->pubKey);\n    switch (pkType) {\n    case DH2K:\n        bnExpMod(&tmpCtx->pubKey, &two, &tmpCtx->privKey, &bnP2048);\n        break;\n\n    case DH3K:\n        bnExpMod(&tmpCtx->pubKey, &two, &tmpCtx->privKey, &bnP3072);\n        break;\n\n    case EC25:\n    case EC38:\n    case E255:\n    case E414:\n        while (!ecdhGeneratePublic(&tmpCtx->curve, &tmpCtx->pubPoint, &tmpCtx->privKey))\n            ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);\n    }\n    return 0;\n}\n\nint32_t ZrtpDH::getDhSize() const\n{\n    switch (pkType) {\n    case DH2K:\n        return 2048/8;\n        break;\n    case DH3K:\n        return 3072/8;\n        break;\n\n    case EC25:\n        return 32;\n        break;\n    case EC38:\n        return 48;\n        break;\n\n    case E255:\n        return 32;\n        break;\n    case E414:\n        return 52;\n        break;\n    }\n    return 0;\n}\n\nint32_t ZrtpDH::getPubKeySize() const\n{\n    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);\n    if (pkType == DH2K || pkType == DH3K)\n        return bnBytes(&tmpCtx->pubKey);\n\n    if (pkType == EC25 || pkType == EC38 || pkType == E414)\n        return bnBytes(tmpCtx->curve.p) * 2;   // *2 -> x and y coordinate\n\n    if (pkType == E255)\n        return bnBytes(tmpCtx->curve.p);\n    return 0;\n\n}\n\nint32_t ZrtpDH::getPubKeyBytes(uint8_t *buf) const\n{\n    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);\n\n    if (pkType == DH2K || pkType == DH3K) {\n        // get len of pub_key, prepend with zeros to DH size\n        int size = getPubKeySize();\n        int32_t prepend = getDhSize() - size;\n        if (prepend > 0) {\n            memset(buf, 0, prepend);\n        }\n        bnExtractBigBytes(&tmpCtx->pubKey, buf + prepend, 0, size);\n        return size;\n    }\n\n    if (pkType == EC25 || pkType == EC38 || pkType == E414) {\n        int32_t len = getPubKeySize() / 2;\n\n        bnExtractBigBytes(tmpCtx->pubPoint.x, buf, 0, len);\n        bnExtractBigBytes(tmpCtx->pubPoint.y, buf+len, 0, len);\n        return len * 2;\n    }\n    if (pkType == E255) {\n        int32_t len = getPubKeySize();\n        bnExtractLittleBytes(tmpCtx->pubPoint.x, buf, 0, len);\n        return len;\n    }\n    return 0;\n}\n\nint32_t ZrtpDH::checkPubKey(uint8_t *pubKeyBytes) const\n{\n\n    /* ECC validation (partial), NIST SP800-56A, section 5.6.2.6 */\n    if (pkType == EC25 || pkType == EC38 || pkType == E414) {\n\n        dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);\n        EcPoint pub;\n\n        INIT_EC_POINT(&pub);\n        int32_t len = getPubKeySize() / 2;\n\n        bnInsertBigBytes(pub.x, pubKeyBytes, 0, len);\n        bnInsertBigBytes(pub.y, pubKeyBytes+len, 0, len);\n\n        return ecCheckPubKey(&tmpCtx->curve, &pub);\n    }\n\n    if (pkType == E255) {\n        return 1;\n    }\n\n    BigNum pubKeyOther;\n    bnBegin(&pubKeyOther);\n    bnInsertBigBytes(&pubKeyOther, pubKeyBytes, 0, getDhSize());\n\n    if (pkType == DH2K) {\n        if (bnCmp(&bnP2048MinusOne, &pubKeyOther) == 0) {\n            return 0;\n        }\n    }\n    else if (pkType == DH3K) {\n        if (bnCmp(&bnP3072MinusOne, &pubKeyOther) == 0) {\n            return 0;\n\n        }\n    }\n    else {\n        return 0;\n    }\n    if (bnCmpQ(&pubKeyOther, 1) == 0) {\n        return 0;\n    }\n\n    bnEnd(&pubKeyOther);\n    return 1;\n}\n\nconst char* ZrtpDH::getDHtype()\n{\n    switch (pkType) {\n    case DH2K:\n        return dh2k;\n    case DH3K:\n        return dh3k;\n    case EC25:\n        return ec25;\n    case EC38:\n        return ec38;\n    case E255:\n        return e255;\n    case E414:\n        return e414;\n    }\n    return NULL;\n}\n\n/** EMACS **\n * Local variables:\n * mode: c++\n * c-default-style: ellemtel\n * c-basic-offset: 4\n * End:\n */\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/crypto/zrtpDH.h",
    "content": "/*\n  Copyright (C) 2006-2009 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef _ZRTPDH_H__\n#define _ZRTPDH_H__\n\n#include <stdint.h>\n\n/**\n * @file zrtpDH.h\n * @brief Class that implemets Diffie-Helman key agreement for ZRTP\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n/**\n * Generates a number of random bytes.\n *\n * @param buf\n *    Pointer to a buffer that receives the random data. Must have a size\n *    of at least <code>length</code> bytes.\n *\n * @param length\n *    Number of random bytes to produce.\n */\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\nvoid randomZRTP(uint8_t *buf, int32_t length);\n#if defined(__cplusplus)\n}\n#endif\n\n#if defined(__cplusplus)\n\n#include <libzrtpcpp/ZrtpConfigure.h>\n\nconst int32_t DH2K = 0;\nconst int32_t DH3K = 1;\nconst int32_t EC25 = 2;\nconst int32_t EC38 = 3;\nconst int32_t E255 = 4;\nconst int32_t E414 = 5;\n\n\n/**\n * Implementation of Diffie-Helman for ZRTP\n *\n * This class defines functions to generate and compute the\n * Diffie-Helman public and secret data and the shared secret. According to\n * the ZRTP specification we use the MODP groups as defined by RFC 3526 for\n * length 3072 and 4096.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass ZrtpDH {\n\nprivate:\n    void* ctx;      ///< Context the DH\n    int pkType;     ///< Which type of DH to use\n\npublic:\n    /**\n     * Create a Diffie-Helman key agreement algorithm\n     * \n     * @param type\n     *     Name of the DH algorithm to use\n     */\n    ZrtpDH(const char* type);\n    \n    ~ZrtpDH();\n\n    /**\n     * Generates a public key based on the DH parameters and a random\n     * private key.\n     *\n     * @return 1 on success, 0 on failure\n     */\n    int32_t generatePublicKey();\n\n    /**\n     * Returns the size in bytes of the DH parameter p.\n     *\n     * @return Size in bytes.\n     */\n    int32_t getDhSize() const;\n\n    /**\n     * Returns the size in bytes of computed public key.\n     *\n     * @return Size in bytes.\n     */\n    int32_t getPubKeySize() const;\n\n    /**\n     * Returns the bytes of computed secret key.\n     *\n     * Returns the bytes of the public key in network (big endian) order.#\n     *\n     * @param buf\n     *    Pointer to a buffer of at least <code>getPubKeySize()</code> bytes.\n     *\n     * @return Size in bytes.\n     */\n    int32_t getPubKeyBytes(uint8_t *buf) const;\n\n    /**\n     * Compute the secret key and returns it to caller.\n     *\n     * This method computes the secret key based on the DH parameters, the\n     * private key and the peer's public key.\n     *\n     * @param pubKeyBytes\n     *    Pointer to the peer's public key bytes. Must be in big endian order.\n     *\n     * @param secret\n     *    Pointer to a buffer that receives the secret key. This buffer must\n     *    have a length of at least <code>getSecretSize()</code> bytes.\n     *\n     * @return the size of the shared secret on success, -1 on error.\n     */\n    int32_t computeSecretKey(uint8_t *pubKeyBytes, uint8_t *secret);\n\n    /**\n     * Check and validate the public key received from peer.\n     *\n     * Check if this is a correct Diffie-Helman public key. If the public\n     * key value is either one or (P-1) then this is a wrong public key\n     * value.\n     *\n     * @param pubKeyBytes\n     *     Pointer to the peer's public key bytes. Must be in big endian order.\n     *\n     * @return 0 if check faild, 1 if public key value is ok.\n     */\n    int32_t checkPubKey(uint8_t* pubKeyBytes) const;\n\n    /**\n     * Get type of DH algorithm.\n     * \n     * @return\n     *     Pointer to DH algorithm name\n     */\n    const char* getDHtype();\n};\n#endif /*__cpluscplus */\n#endif\n\n/**\n * @}\n */\n\n/** EMACS **\n * Local variables:\n * mode: c++\n * c-default-style: ellemtel\n * c-basic-offset: 4\n * End:\n */\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/Base32.h",
    "content": "#ifndef BASE32_H\n#define BASE32_H\n\n/*\n *\n * Copyright (c) 2002 Bryce \"Zooko\" Wilcox-O'Hearn Permission is hereby\n * granted, free of charge, to any person obtaining a copy of this software to\n * deal in this software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of this software, and to permit persons to whom this software\n * is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of this software.\n *\n * THIS SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THIS SOFTWARE.\n *\n * Converted to C++ by:\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n/**\n * @file Base32.h\n * @brief C++ implmentation of the Base32 encoding and decoding\n * \n * ZRTP uses the base 32 encoding and decoding to generate the Short \n * Authentication String (SAS).\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <iostream>\n#include <cstdlib>\n\n#include <string.h>\n#include <assert.h>\n#include <stddef.h>\n\nusing namespace std;\n\nextern int divceil(int a, int b);\n\nclass Base32 {\n\n public:\n\n    /**\n     * A Constructor that decodes from base32 into binary.\n     *\n     * The constructor decodes the base32 encoded data back into binary\n     * data. Use <code>getDecoded(...)</code> to get the binary data.\n     *\n     * @param encoded\n     *     The string that contains the base32 encoded data.\n     */\n    Base32(const string encoded);\n\n    /**\n     * A Constructor that decodes from base32 into binary.\n     *\n     * This constructor decodes the base32 encoded data back into\n     * binary data. Only the specified number of bits are decoded\n     * (should be a multiple of 5).  Use\n     * <code>getDecoded(...)</code> to get the binary data.\n     *\n     * @param encoded\n     *     The string that contains the base32 encoded data.\n     * @param noOfBits\n     *     How many bits to decode into binary data.\n     */\n    Base32(const string encoded, int noOfBits);\n\n    /**\n     * A Constructor that encodes binary data.\n     *\n     * The constructor converts the first specified number of bits of\n     * the binary data into a base32 presentation. Use\n     * <code>getEncoded</code> to get the encoded data.\n     *\n     * @param data\n     *    A pointer to the first bits (byte) of binary data\n     * @param noOfBits\n     *    How many bits to use for encoding. Should be a\n     *    multiple of 5.\n     */\n    Base32(const unsigned char* data, int noOfBits);\n\n    ~Base32();\n\n    /**\n     * Get the decoded binary data and its length.\n     *\n     * The method returns the decoded binary data if the appropriate\n     * Constructor was used. Otherwise we return <code>NULL</code>\n     * pointer and length zero.\n     *\n     * <em>Note:</em> This method returns a pointer to the decoded\n     * binary data. The Base32 object manages this pointer, thus you\n     * may need to copy the data to a save place before deleting this\n     * object. If the object is deleted this pointer is no longer\n     * valid.\n     *\n     * @param length\n     *     A reference to an integer.\n     * @return\n     *     A pointer to the decoded binary data.\n     */\n    const unsigned char* getDecoded(int &length);\n\n    /**\n     * Get the encoded base32 string.\n     *\n     * The method returns a string that contains the base32 encoded\n     * data if the appropriate constructor was used. Otherwise we\n     * return an empty string.\n     *\n     * @return\n     *     The string containing the base32 encoded data.\n     */\n    const string getEncoded() { return encoded; };\n\n    /**\n     * Compute the number of base32 encoded characters given the\n     * number of bits.\n     *\n     * @param lengthInBits\n     *      The length of the data in bits\n     * @return\n     *      The length of the base-32 encoding of the data in characters\n     */\n    static size_t const b2alen(const size_t lengthInBits) {\n\treturn divceil(lengthInBits, 5); };\n\n private:\n\n    /**\n     * Decodes a string with base32 presentation into binary data.\n     *\n     * a2b_l() will return a result big enough to hold lengthinbits bits.  So\n     * for example if cs is 4 characters long (encoding at least 15 and up to\n     * 20 bits) and lengthinbits is 16, then a2b_l() will return a string of\n     * length 2 (since 2 bytes is sufficient to store 16 bits).  If cs is 4\n     * characters long and lengthinbits is 20, then a2b_l() will return a\n     * string of length 3 (since 3 bytes is sufficient to store 20 bits). Note\n     * that `b2a_l()' does not mask off unused least-significant bits, so for\n     * example if cs is 4 characters long and lengthinbits is 17, then you\n     * must ensure that all three of the unused least-significant bits of cs\n     * are zero bits or you will get the wrong result. This precondition is\n     * tested by assertions if assertions are enabled. (Generally you just\n     * require the encoder to ensure this consistency property between the\n     * least significant zero bits and value of `lengthinbits', and reject\n     * strings that have a length-in-bits which isn't a multiple of 8 and yet\n     * don't have trailing zero bits, as improperly encoded.)\n     *\n     * @param cs\n     *    The data to be decoded\n     * @param size\n     *    The length of the input data buffer. Usually divceil(length in bits, 5).\n     * @param lengthinbits\n     *    The number of bits of data in <code>cs</code> to be decoded\n     */\n    void a2b_l(const string cs, size_t size, const size_t lengthinbits);\n\n    /**\n     * Encodes binary to to base32 presentation.\n     *\n     * b2a_l() will generate a base-32 encoded string big enough to encode\n     * lengthinbits bits.  So for example if os is 2 bytes long and\n     * lengthinbits is 15, then b2a_l() will generate a 3-character- long\n     * base-32 encoded string (since 3 quintets is sufficient to encode 15\n     * bits). If os is 2 bytes long and lengthinbits is 16 (or None), then\n     * b2a_l() will generate a 4-character string.  Note that `b2a_l()' does\n     * not mask off unused least-significant bits, so for example if os is 2\n     * bytes long and lengthinbits is 15, then you must ensure that the unused\n     * least-significant bit of os is a zero bit or you will get the wrong\n     * result.  This precondition is tested by assertions if assertions are\n     * enabled.\n     *\n     * Warning: if you generate a base-32 encoded string with `b2a_l()', and\n     * then someone else tries to decode it by calling `a2b()' instead of\n     * `a2b_l()', then they will (probably) get a different string than the\n     * one you encoded!  So only use `b2a_l()' when you are sure that the\n     * encoding and decoding sides know exactly which `lengthinbits' to use.\n     * If you do not have a way for the encoder and the decoder to agree upon\n     * the lengthinbits, then it is best to use `b2a()' and `a2b()'.  The only\n     * drawback to using `b2a()' over `b2a_l()' is that when you have a number\n     * of bits to encode that is not a multiple of 8, `b2a()' can sometimes\n     * generate a base-32 encoded string that is one or two characters longer\n     * than necessary.\n     *\n     * @param cs\n     *     Pointer to binary data.\n     * @param len\n     *     Length of the binary data buffer. Usually (noOfBits+7)/8.\n     * @param noOfBits\n     *    The number of bits of data in encoded into `cs'\n     */\n    void b2a_l(const unsigned char* cs, int len, const size_t noOfBits);\n\n    /**\n     * Holds the pointer to decoded binary data\n     */\n    unsigned char *binaryResult;\n\n    /**\n     * Length of decoding result\n     */\n    int resultLength;\n\n    /**\n     * The string containing the base32 encoded data.\n     */\n    string encoded;\n\n    unsigned char smallBuffer[128];\n};\n\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZIDCache.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <string>\n\n#include \"ZIDRecord.h\"\n\n#ifndef _ZIDCACHE_H_\n#define _ZIDCACHE_H_\n\n/**\n * @file ZIDCache.h\n * @brief ZID cache management\n *\n * A ZID file stores (caches) some data that helps ZRTP to achives its\n * key continuity feature. See @c ZIDRecord for further info which data\n * the ZID file contains.\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n/**\n * Interface for classes that implements a ZID (ZRTP Identifiers) file.\n *\n * The ZID file holds information about peers.\n *\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass ZIDCache;\n\n__EXPORT ZIDCache* getZidCacheInstance();\n\n\nclass __EXPORT ZIDCache {\n\npublic:\n\n    /**\n     * @brief Destructor.\n     * Define a virtual destructor to enable cleanup in derived classes.\n     */\n    virtual ~ZIDCache() {};\n\n    /**\n     * @brief Open the named ZID file and return a ZID file class.\n     *\n     * This static function either opens an existing ZID file or\n     * creates a new ZID file with the given name. The ZIDCache is a\n     * singleton, thus only <em>one</em> ZID file can be open at one\n     * time.\n     *\n     * To open another ZID file you must close the active ZID file\n     * first.\n     *\n     * @param name\n     *    The name of the ZID file to open or create\n     * @return\n     *    1 if file could be opened/created, 0 if the ZID instance\n     *    already has an open file, -1 if open/creation of file failed.\n     */\n    virtual int open(char *name) =0;\n\n    /**\n     * @brief Check if ZIDCache has an active (open) file.\n     *\n     * @return\n     *    True if ZIDCache has an active file, false otherwise\n     */\n    virtual bool isOpen() =0;\n\n     /**\n      * @brief Close the ZID file.\n      *\n      * Closes the ZID file, and prepares to open a new ZID file.\n      */\n    virtual void close() =0;\n\n    /**\n     * @brief Get a ZID record from ZID cache or create a new record.\n     *\n     * The method tries to read a ZRTP cache record for the ZID.\n     * If no matching record exists in the cache the method creates\n     * it and fills it with default values.\n     *\n     * @param zid is the ZRTP id of the peer\n     * @return pointer to the ZID record. The call must @c delete the\n     *         record if it is not longer used.\n     */\n    virtual ZIDRecord *getRecord(unsigned char *zid) =0;\n\n    /**\n     * @brief Save a ZID record into the active ZID file.\n     *\n     * This method saves the content of a ZID record into the ZID file. Before\n     * you can save the ZID record you must have performed a getRecord()\n     * first.\n     *\n     * @param zidRecord\n     *    The ZID record to save.\n     * @return\n     *    1 on success\n     */\n    virtual unsigned int saveRecord(ZIDRecord *zidRecord) =0;\n\n    /**\n     * @brief Get the ZID associated with this ZID file.\n     *\n     * @return\n     *    Pointer to the ZID\n     */\n    virtual const unsigned char* getZid() =0;\n\n    /**\n     * @brief Get peer name from database.\n     *\n     * This is an optional function.\n     *\n     * A client may use this function to retrieve a name that was assigned\n     * to the peer's ZID.\n     *\n     * @param peerZid the peer's ZID\n     *\n     * @param name string that will get the peer's name. The returned name will\n     *             be truncated to 200 bytes\n     *\n     * @return length og the name read or 0 if no name was previously stored.\n     */\n    virtual int32_t getPeerName(const uint8_t *peerZid, std::string *name) =0;\n\n    /**\n     * @brief Write peer name to database.\n     *\n     * This is an optional function.\n     *\n     * A client may use this function to write a name in the ZRTP cache database and\n     * asign it to the peer's ZID.\n     *\n     * @param peerZid the peer's ZID\n     *\n     * @param name the name string\n     *\n     */\n    virtual void putPeerName(const uint8_t *peerZid, const std::string name) =0;\n\n    /**\n     * @brief Clean the cache - only for ZID cache with Sqlite3 backend.\n     *\n     * The function drops and re-creates all tables in the database. This removes all stored\n     * data. The application must not call this while a ZRTP call is active. Also the application\n     * <b>must</b> get the local ZID again.\n     *\n     */\n    virtual void cleanup() =0;\n\n    /**\n     * @brief Prepare a SQL cursor to read all records from the remote (peer) ZID table.\n     * \n     * The function creates a SQL cursor (prepares a statement in sqlite3 parlance) to\n     * read all records from the table that contains the remote (peers') ZID data.\n     * \n     * This functions returns a pointer to the SQL cursor or @c NULL if it fails to\n     * create a cursor.\n     * \n     * @return a void pointer to the sqlite3 statment (SQL cursor) or @c NULL\n     */\n    virtual void *prepareReadAll() =0;\n\n    /**\n     * @brief Read next ZID record from and SQL cursor.\n     * \n     * The function reads the next ZID record from a SQL cursor. If it cannot read a\n     * record or encounters an error the function closes the cursor and returns @c NULL.\n     * In this case the function must not use the SQL cursor pointer again.\n     * \n     * For the second parameter the caller @b must use a ZIDRecordDb pointer, not\n     * a ZIDRecordFile pointer.\n     * \n     * The function returns a string in its output parameter. The '|' symbol separates\n     * the different fields. Here the description of the fields:\n     * <ol>\n     * <li> The own ZID, should always be the same (in theroy we coud use different local ZIDs), hex value of random data </li>\n     * <li> the partner's (remote) ZID, hex value of random data</li>\n     * <li> the flag byte (bit field, explanation see below and in ZIDRecordDb.h:\n     * <ul>\n     *     <li>Valid            = 0x1;</li>\n     *     <li>SASVerified      = 0x2;</li>\n     *     <li>RS1Valid         = 0x4;</li>\n     *     <li>RS2Valid         = 0x8;</li>\n     *     <li> MITMKeyAvailable= 0x10;</li>\n     *     <li>inUse            = 0x20;</li>\n     * </ul>\n     * </li>\n     * <li> RS1 value, hex field, 32 binary bytes</li>\n     * <li> RS1 last used timestamp (Unix epoch), decimal, currently not used, always 0</li>\n     * <li> RS1 Time-To-Live timestamp (Unix epoch), decimal, if -1: valid for ever, otherwise the time it's not longer valid</li>\n     * <li> RS2 value, hex field, 32 binary bytes</li>\n     * <li> RS2 last used timestamp (Unix epoch), decimal, currently not used, always 0</li>\n     * <li> RS2 Time-To-Live timestamp (Unix epoch), decimal, if -1: valid for ever, otherwise the time it's not longer valid</li>\n     * <li> trusted PBX shared key value, hex field, 32 binary bytes, valid only if MITMKeyAvailable bit is set</li>\n     * <li> trusted PBX shared key last used timestamp (Unix epoch), decimal, currently not used, always 0</li>\n     * <li> Secure since timestamp (Unix epoch), decimal, shows time ZRTP created this ZID record</li>\n     * <li> Name, may be empty</li>\n     * </ol>\n     * \n     * @param stmt a void pointer to a sqlite3 statement (SQL cursor)\n     *\n     * @param output that will get the peer's name. The returned name will\n     *             be truncated to 200 bytes\n     * \n     * @return void pointer to statment if successful, this is the same pointer as\n     *         the @c stmt input parameter. The function returns @c NULL if either \n     *         no more record is available or it got another error.\n     */\n    virtual void *readNextRecord(void *stmt, std::string *output) =0;\n\n    virtual void closeOpenStatment(void *stmt) =0;\n\n};\n\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZIDCacheDb.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <stdio.h>\n\n#include <libzrtpcpp/ZIDCache.h>\n#include <libzrtpcpp/ZIDRecordDb.h>\n#include <libzrtpcpp/zrtpCacheDbBackend.h>\n\n#ifndef _ZIDCACHEDB_H_\n#define _ZIDCACHEDB_H_\n\n\n/**\n * @file ZIDCacheDb.h\n * @brief ZID cache management\n *\n * A ZID file stores (caches) some data that helps ZRTP to achives its\n * key continuity feature. See @c ZIDRecordDb for further info which data\n * the ZID file contains.\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n/**\n * This class implements a ZID (ZRTP Identifiers) file.\n *\n * The interface defintion @c ZIDCache.h contains the method documentation.\n * The ZID cache file holds information about peers.\n *\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZIDCacheDb: public ZIDCache {\n\nprivate:\n\n    void *zidFile;\n    unsigned char associatedZid[IDENTIFIER_LEN];\n\n    dbCacheOps_t cacheOps;\n\n    char errorBuffer[DB_CACHE_ERR_BUFF_SIZE];\n\n    void createZIDFile(char* name);\n    void formatOutput(remoteZidRecord_t *remZid, const char *nameBuffer, std::string *output);\n\npublic:\n\n    ZIDCacheDb(): zidFile(NULL) {\n        getDbCacheOps(&cacheOps);\n    };\n\n    ~ZIDCacheDb();\n\n    int open(char *name);\n\n    bool isOpen() { return (zidFile != NULL); };\n\n    void close();\n\n    ZIDRecord *getRecord(unsigned char *zid);\n\n    unsigned int saveRecord(ZIDRecord *zidRecord);\n\n    const unsigned char* getZid() { return associatedZid; };\n\n    int32_t getPeerName(const uint8_t *peerZid, std::string *name);\n\n    void putPeerName(const uint8_t *peerZid, const std::string name);\n\n    void cleanup();\n\n    void *prepareReadAll();\n\n    void *readNextRecord(void *stmt, std::string *name);\n\n    void closeOpenStatment(void *stmt);\n};\n\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZIDCacheFile.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <stdio.h>\n\n#include <libzrtpcpp/ZIDCache.h>\n#include <libzrtpcpp/ZIDRecordFile.h>\n\n#ifndef _ZIDCACHEFILE_H_\n#define _ZIDCACHEFILE_H_\n\n\n/**\n * @file ZIDCacheFile.h\n * @brief ZID cache management\n *\n * A ZID file stores (caches) some data that helps ZRTP to achives its\n * key continuity feature. See @c ZIDRecord for further info which data\n * the ZID file contains.\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n/**\n * This class implements a ZID (ZRTP Identifiers) file.\n *\n * The interface defintion @c ZIDCache.h contains the method documentation.\n * The ZID cache file holds information about peers.\n *\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZIDCacheFile: public ZIDCache {\n\nprivate:\n\n    FILE* zidFile;\n    unsigned char associatedZid[IDENTIFIER_LEN];\n\n    void createZIDFile(char* name);\n    void checkDoMigration(char* name);\n\npublic:\n\n    ZIDCacheFile(): zidFile(NULL) {};\n\n    ~ZIDCacheFile();\n\n    int open(char *name);\n\n    bool isOpen() { return (zidFile != NULL); };\n\n    void close();\n\n    ZIDRecord *getRecord(unsigned char *zid);\n\n    unsigned int saveRecord(ZIDRecord *zidRecord);\n\n    const unsigned char* getZid() { return associatedZid; };\n\n    int32_t getPeerName(const uint8_t *peerZid, std::string *name);\n\n    void putPeerName(const uint8_t *peerZid, const std::string name);\n\n    // Not implemented for file based cache\n    void cleanup() {};\n    void *prepareReadAll() { return NULL; };\n    void *readNextRecord(void *stmt, std::string *output) { return NULL; };\n    void closeOpenStatment(void *stmt) {}\n\n\n};\n\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZIDRecord.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZIDRECORD_H_\n#define _ZIDRECORD_H_\n\n#include <stdint.h>\n#include <common/osSpecifics.h>\n/**\n * @file ZIDRecord.h\n * @brief ZID cache record management\n *\n * A ZID record stores (caches) ZID (ZRTP ID) specific data that helps ZRTP\n * to achives its key continuity feature. Please refer to the ZRTP\n * specification to get detailed information about the ZID.\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n/**\n * These length are fixed for ZRTP. See RFC 6189.\n */\n#define IDENTIFIER_LEN  12\n#define RS_LENGTH       32\n\n#define FILE_TYPE_RECORD    1\n#define SQLITE_TYPE_RECORD  2\n\n#if defined(__cplusplus)\n/**\n * Interface for classes that implement a ZID cache record.\n *\n * The ZID cache record holds data about a peer. According to ZRTP specification\n * we use a ZID to identify a peer. ZRTP uses the RS (Retained Secret) data\n * to construct shared secrets.\n *\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\nclass __EXPORT ZIDRecord {\n\npublic:\n    /**\n     * @brief Destructor.\n     * Define a virtual destructor to enable cleanup in derived classes.\n     */\n    virtual ~ZIDRecord() {};\n\n    /**\n     * @brief Set the @c ZID in the record.\n     *\n     * Set the ZID in this record before calling read or save.\n     */\n    virtual void setZid(const unsigned char *zid) =0;\n\n    /**\n     * @brief Set @c valid flag in RS1\n     */\n    virtual void setRs1Valid() =0;\n\n    /**\n     * @brief Reset @c valid flag in RS1\n     */\n    virtual void resetRs1Valid()  =0;\n\n    /**\n     * @brief Check @c valid flag in RS1\n     */\n    virtual bool isRs1Valid() =0;\n\n    /**\n     * @brief Set @c valid flag in RS2\n     */\n    virtual void setRs2Valid() =0;\n\n    /**\n     * @brief Reset @c valid flag in RS2\n     */\n    virtual void resetRs2Valid() =0;\n\n    /**\n     * @brief Check @c valid flag in RS2\n     */\n    virtual bool isRs2Valid() =0;\n\n    /**\n     * @brief Set MITM key available\n     */\n    virtual void setMITMKeyAvailable() =0;\n\n    /**\n     * @brief Reset MITM key available\n     */\n    virtual void resetMITMKeyAvailable() =0;\n\n    /**\n     * @brief Check MITM key available is set\n     */\n    virtual bool isMITMKeyAvailable() =0;\n\n    /**\n     * @brief Mark this as own ZID record\n     */\n    virtual void setOwnZIDRecord() =0;\n\n    /**\n     * @brief Reset own ZID record marker\n     */\n    virtual void resetOwnZIDRecord() =0;\n\n    /**\n     * @brief Check own ZID record marker\n     */\n    virtual bool isOwnZIDRecord() =0;\n\n    /**\n     * @brief Set SAS for this ZID as verified\n     */\n    virtual void setSasVerified() =0;\n\n    /**\n     * @brief Reset SAS for this ZID as verified\n     */\n    virtual void resetSasVerified() =0;\n\n    /**\n     * @brief Check if SAS for this ZID was verified\n     */\n    virtual bool isSasVerified() =0;\n\n    /**\n     * @brief Return the ZID for this record\n     */\n    virtual const uint8_t* getIdentifier() =0;\n\n    /**\n     * @brief Check if RS1 is still valid\n     *\n     * Returns true if RS1 is still valid, false otherwise.\n     *\n     * @return\n     *    Returns true is RS1 is not expired (valid), false otherwise.\n     */\n    virtual bool isRs1NotExpired() =0;\n\n    /**\n     * @brief Returns pointer to RS1 data.\n     */\n    virtual const unsigned char* getRs1() =0;\n\n    /**\n     * @brief Check if RS2 is still valid\n     *\n     * Returns true if RS2 is still valid, false otherwise.\n     *\n     * @return\n     *    Returns true is RS2 is not expired (valid), false otherwise.\n     */\n    virtual bool isRs2NotExpired() =0;\n\n    /**\n     * @brief Returns pointer to RS1 data.\n     */\n    virtual const unsigned char* getRs2() =0;\n\n    /**\n     * @brief Sets new RS1 data and associated expiration value.\n     *\n     * If the expiration value is >0 or -1 the method stores the new\n     * RS1. Before it stores the new RS1 it shifts the exiting RS1\n     * into RS2 (together with its expiration time). Then it computes\n     * the expiration time of the and stores the result together with\n     * the new RS1.\n     *\n     * If the expiration value is -1 then this RS will never expire.\n     *\n     * If the expiration value is 0 then the expiration value of a\n     * stored RS1 is cleared and no new RS1 value is stored. Also RS2\n     * is left unchanged.\n     *\n     * @param data\n     *    Points to the new RS1 data.\n     * @param expire\n     *    The expiration interval in seconds. Default is -1.\n     *\n     */\n    virtual void setNewRs1(const unsigned char* data, int32_t expire =-1) =0;\n\n    /**\n     * @brief Set MiTM key data.\n     *\n     */\n    virtual void setMiTMData(const unsigned char* data) =0;\n\n    /**\n     * @brief Get MiTM key data.\n     *\n     */\n    virtual const unsigned char* getMiTMData() =0;\n\n    virtual int getRecordType() =0;\n \n    /**\n     * @brief Get the secure since field\n     * \n     * Returns the secure since field or 0 if no such field is available. Secure since\n     * uses the unixepoch.\n     */\n    virtual int64_t getSecureSince() =0;\n};\n#endif /* (__cplusplus) */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZIDRecordDb.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZIDRECORDDB_H_\n#define _ZIDRECORDDB_H_\n\n\n/**\n * @file ZIDRecordDb.h\n * @brief ZID cache record management\n *\n * A ZID record stores (caches) ZID (ZRTP ID) specific data that helps ZRTP\n * to achives its key continuity feature. Please refer to the ZRTP\n * specification to get detailed information about the ZID.\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <string.h>\n#include <stdint.h>\n#include <libzrtpcpp/ZIDRecord.h>\n\n#define TIME_LENGTH      8      // 64 bit, can hold time on 64 bit systems\n\n/**\n * Internal structure that holds the non-key data of a remote ZID record.\n *\n * The data storage backends use this structure to get or to fill in data\n * to store in or that was read from the data store.\n *\n * Some notes regarding the timestamps: the structure uses 64 bit variables to\n * store a timestamp. The relevant SQL SELECT / UPDATE / INSERT statements and\n * the relevant must take care of this.\n *\n * The methods shall use the standard C time() call to get the current time in\n * seconds since Unix epoch (see time() documentation).\n */\ntypedef struct {\n    uint8_t   identifier[IDENTIFIER_LEN]; /* < the peer's ZID or own ZID */\n    uint32_t  flags;\n    uint8_t   rs1[RS_LENGTH];\n    int64_t   rs1LastUse;\n    int64_t   rs1Ttl;\n    uint8_t   rs2[RS_LENGTH];\n    int64_t   rs2LastUse;\n    int64_t   rs2Ttl;\n    uint8_t   mitmKey[RS_LENGTH];\n    int64_t   mitmLastUse;\n    int64_t   secureSince;\n    uint32_t  preshCounter;\n} remoteZidRecord_t;\n\n/*\n * The flag field stores the following bitflags\n */\nstatic const uint32_t Valid            = 0x1;\nstatic const uint32_t SASVerified      = 0x2;\nstatic const uint32_t RS1Valid         = 0x4;\nstatic const uint32_t RS2Valid         = 0x8;\nstatic const uint32_t MITMKeyAvailable = 0x10;\nstatic const uint32_t inUse            = 0x20;\n\n/**\n * Internal structure that holds the non-key data of a ZID name record.\n *\n * The flags field currently just uses the @c Valid bit.\n *\n * See comment on @c remoteZidRecord_t above.\n */\ntypedef struct {\n    uint32_t   flags;\n    char       *name;\n    int32_t    nameLength;\n} zidNameRecord_t;\n\n#if defined(__cplusplus)\n/**\n * This class implements the ZID record.\n *\n * The ZID record holds data about a peer. According to ZRTP specification\n * we use a ZID to identify a peer. ZRTP uses the RS (Retained Secret) data\n * to construct shared secrets.\n * <p>\n * NOTE: ZIDRecordDb has ZIDCacheDb as friend. ZIDCacheDb knows about the private\n *   data of ZIDRecord - please keep both classes synchronized.\n *\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\nclass __EXPORT ZIDRecordDb: public ZIDRecord {\n    friend class ZIDCacheDb;\n\nprivate:\n    remoteZidRecord_t record;\n\n    remoteZidRecord_t* getRecordData() {return &record; }\n    int getRecordLength()              {return sizeof(remoteZidRecord_t); }\n\n    bool isValid()    { return ((record.flags & Valid) == Valid); }\n    void setValid()   { record.flags |= Valid; }\n\npublic:\n    /*\n     * @brief The default constructor,\n     */\n    ZIDRecordDb() {\n        memset(&record, 0, sizeof(remoteZidRecord_t));\n    }\n\n    /**\n     * Set the @c ZID in the record.\n     *\n     * Set the ZID in this record before calling read or save.\n     */\n    void setZid(const unsigned char *zid) {\n        memcpy(record.identifier, zid, IDENTIFIER_LEN);\n    }\n\n    /**\n     * Set @c valid flag in RS1\n     */\n    void setRs1Valid()   { record.flags |= RS1Valid; }\n\n    /**\n     * reset @c valid flag in RS1\n     */\n    void resetRs1Valid() { record.flags &= ~RS1Valid; }\n\n    /**\n     * Check @c valid flag in RS1\n     */\n    bool isRs1Valid()    { return ((record.flags & RS1Valid) == RS1Valid); }\n\n    /**\n     * Set @c valid flag in RS2\n     */\n    void setRs2Valid()   { record.flags |= RS2Valid; }\n\n    /**\n     * Reset @c valid flag in RS2\n     */\n    void resetRs2Valid() { record.flags &= ~RS2Valid; }\n\n    /**\n     * Check @c valid flag in RS2\n     */\n    bool isRs2Valid()    { return ((record.flags & RS2Valid) == RS2Valid); }\n\n    /**\n     * Set MITM key available\n     */\n    void setMITMKeyAvailable()    { record.flags |= MITMKeyAvailable; }\n\n    /**\n     * Reset MITM key available\n     */\n    void resetMITMKeyAvailable()  { record.flags &= ~MITMKeyAvailable; }\n\n    /**\n     * Check MITM key available is set\n     */\n    bool isMITMKeyAvailable()     { return ((record.flags & MITMKeyAvailable) == MITMKeyAvailable); }\n\n    /**\n     * Mark this as own ZID record - not used in this DB cache backend\n     */\n    void setOwnZIDRecord()  {}\n    /**\n     * Reset own ZID record marker\n     */\n    void resetOwnZIDRecord(){}\n\n    /**\n     * Check own ZID record marker\n     */\n    bool isOwnZIDRecord()   { return false; }  // in this DB cahe implementation a record is always 'remote'\n\n    /**\n     * Set SAS for this ZID as verified\n     */\n    void setSasVerified()   { record.flags |= SASVerified; }\n    /**\n     * Reset SAS for this ZID as verified\n     */\n    void resetSasVerified() { record.flags &= ~SASVerified; }\n\n    /**\n     * Check if SAS for this ZID was verified\n     */\n    bool isSasVerified()    { return ((record.flags & SASVerified) == SASVerified); }\n\n    /**\n     * Return the ZID for this record\n     */\n    const uint8_t* getIdentifier() {return record.identifier; }\n\n    /**\n     * Check if RS1 is still valid\n     *\n     * Returns true if RS1 is still valid, false otherwise.\n     *\n     * @return\n     *    Returns true is RS1 is not expired (valid), false otherwise.\n     */\n    bool isRs1NotExpired();\n\n    /**\n     * Returns pointer to RS1 data.\n     */\n    const unsigned char* getRs1() { return record.rs1; }\n\n    /**\n     * Check if RS2 is still valid\n     *\n     * Returns true if RS2 is still valid, false otherwise.\n     *\n     * @return\n     *    Returns true is RS2 is not expired (valid), false otherwise.\n     */\n    bool isRs2NotExpired();\n\n    /**\n     * Returns pointer to RS1 data.\n     */\n    const unsigned char* getRs2() { return record.rs2; }\n\n    /**\n     * Sets new RS1 data and associated expiration value.\n     *\n     * If the expiration value is >0 or -1 the method stores the new\n     * RS1. Before it stores the new RS1 it shifts the exiting RS1\n     * into RS2 (together with its expiration time). Then it computes\n     * the expiration time of the and stores the result together with\n     * the new RS1.\n     *\n     * If the expiration value is -1 then this RS will never expire.\n     *\n     * If the expiration value is 0 then the expiration value of a\n     * stored RS1 is cleared and no new RS1 value is stored. Also RS2\n     * is left unchanged.\n     *\n     * @param data\n     *    Points to the new RS1 data.\n     * @param expire\n     *    The expiration interval in seconds. Default is -1.\n     *\n     */\n    void setNewRs1(const unsigned char* data, int32_t expire =-1);\n\n    /**\n     * Set MiTM key data.\n     *\n     */\n    void setMiTMData(const unsigned char* data);\n\n    /**\n     * Get MiTM key data.\n     *\n     */\n    const unsigned char* getMiTMData() {return record.mitmKey; }\n\n    int getRecordType() {return SQLITE_TYPE_RECORD; }\n\n    int64_t getSecureSince() { return record.secureSince; }\n};\n#endif /* (__cplusplus) */\n\n#endif\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZIDRecordFile.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZIDRECORDFILE_H_\n#define _ZIDRECORDFILE_H_\n\n\n/**\n * @file ZIDRecordFile.h\n * @brief ZID cache record management\n *\n * A ZID record stores (caches) ZID (ZRTP ID) specific data that helps ZRTP\n * to achives its key continuity feature. Please refer to the ZRTP\n * specification to get detailed information about the ZID.\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <string.h>\n#include <stdint.h>\n#include <libzrtpcpp/ZIDRecord.h>\n\n#define TIME_LENGTH      8      // 64 bit, can hold time on 64 bit systems\n\n/**\n * This is the recod structure of version 1 ZID records.\n *\n * This is not longer in use - only during migration.\n */\ntypedef struct zidrecord1 {\n    char recValid;  //!< if 1 record is valid, if 0: invalid\n    char ownZid;    //!< if >1 record contains own ZID, usually 1st record\n    char rs1Valid;  //!< if 1 RS1 contains valid data\n    char rs2Valid;  //!< if 1 RS2 contains valid data\n    unsigned char identifier[IDENTIFIER_LEN]; ///< the peer's ZID or own ZID\n    unsigned char rs1Data[RS_LENGTH], rs2Data[RS_LENGTH]; ///< the peer's RS data\n} zidrecord1_t;\n\n/**\n * This is the recod structure of version 2 ZID records.\n */\ntypedef struct zidrecord2 {\n    char version;   ///< version number of file format, this is #2\n    char flags;     ///< bit field holding various flags, see below\n    char filler1;   ///< round up to next 32 bit\n    char filler2;   ///< round up to next 32 bit\n    unsigned char identifier[IDENTIFIER_LEN]; ///< the peer's ZID or own ZID\n    unsigned char rs1Interval[TIME_LENGTH];   ///< expiration time of RS1; -1 means indefinite\n    unsigned char rs1Data[RS_LENGTH];         ///< the peer's RS2 data\n    unsigned char rs2Interval[TIME_LENGTH];   ///< expiration time of RS2; -1 means indefinite\n    unsigned char rs2Data[RS_LENGTH];         ///< the peer's RS2 data\n    unsigned char mitmKey[RS_LENGTH];         ///< MiTM key if available\n} zidrecord2_t;\n\nstatic const int Valid            = 0x1;\nstatic const int SASVerified      = 0x2;\nstatic const int RS1Valid         = 0x4;\nstatic const int RS2Valid         = 0x8;\nstatic const int MITMKeyAvailable = 0x10;\nstatic const int OwnZIDRecord     = 0x20;\n\n/**\n * This class implements the ZID record.\n *\n * The ZID record holds data about a peer. According to ZRTP specification\n * we use a ZID to identify a peer. ZRTP uses the RS (Retained Secret) data\n * to construct shared secrets.\n * <p>\n * NOTE: ZIDRecord has ZIDFile as friend. ZIDFile knows about the private\n *   data of ZIDRecord - please keep both classes synchronized.\n *\n * @author: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\nclass __EXPORT ZIDRecordFile: public ZIDRecord {\n    friend class ZIDCacheFile;\n\nprivate:\n    zidrecord2_t record;\n    unsigned long position;\n\n    /**\n     * Functions for I/O availabe for ZID file handling\n     *\n     * These functions are private, thus only friends may use it.\n     */\n    void setPosition(long pos) {position = pos;}\n    long getPosition()         {return position; }\n\n    zidrecord2_t* getRecordData() {return &record; }\n    int getRecordLength()         {return sizeof(zidrecord2_t); }\n\n    bool isValid()    { return ((record.flags & Valid) == Valid); }\n    void setValid()   { record.flags |= Valid; }\n\npublic:\n    /*\n     * @brief The default constructor,\n     */\n    ZIDRecordFile() {\n        memset(&record, 0, sizeof(zidrecord2_t));\n        record.version = 2;\n    }\n\n    /**\n     * @brief Set the @c ZID in the record.\n     *\n     * Set the ZID in this record before calling read or save.\n     */\n    void setZid(const unsigned char *zid) {\n        memcpy(record.identifier, zid, IDENTIFIER_LEN);\n    }\n\n    /**\n     * @brief Set @c valid flag in RS1\n     */\n    void setRs1Valid()   { record.flags |= RS1Valid; }\n\n    /**\n     * @brief Reset @c valid flag in RS1\n     */\n    void resetRs1Valid() { record.flags &= ~RS1Valid; }\n\n    /**\n     * @brief Check @c valid flag in RS1\n     */\n    bool isRs1Valid()    { return ((record.flags & RS1Valid) == RS1Valid); }\n\n    /**\n     * @brief Set @c valid flag in RS2\n     */\n    void setRs2Valid()   { record.flags |= RS2Valid; }\n\n    /**\n     * @brief Reset @c valid flag in RS2\n     */\n    void resetRs2Valid() { record.flags &= ~RS2Valid; }\n\n    /**\n     * @brief Check @c valid flag in RS2\n     */\n    bool isRs2Valid()    { return ((record.flags & RS2Valid) == RS2Valid); }\n\n    /**\n     * @brief Set MITM key available\n     */\n    void setMITMKeyAvailable()    { record.flags |= MITMKeyAvailable; }\n\n    /**\n     * @brief Reset MITM key available\n     */\n    void resetMITMKeyAvailable()  { record.flags &= ~MITMKeyAvailable; }\n\n    /**\n     * @brief Check MITM key available is set\n     */\n    bool isMITMKeyAvailable()     { return ((record.flags & MITMKeyAvailable) == MITMKeyAvailable); }\n\n    /**\n     * @brief Mark this as own ZID record\n     */\n    void setOwnZIDRecord()  { record.flags = OwnZIDRecord; }\n    /**\n     * @brief Reset own ZID record marker\n     */\n    void resetOwnZIDRecord(){ record.flags = 0; }\n\n    /**\n     * @brief Check own ZID record marker\n     */\n    bool isOwnZIDRecord()   { return (record.flags == OwnZIDRecord); }  // no other flag allowed if own ZID\n\n    /**\n     * @brief Set SAS for this ZID as verified\n     */\n    void setSasVerified()   { record.flags |= SASVerified; }\n    /**\n     * @brief Reset SAS for this ZID as verified\n     */\n    void resetSasVerified() { record.flags &= ~SASVerified; }\n\n    /**\n     * @brief Check if SAS for this ZID was verified\n     */\n    bool isSasVerified()    { return ((record.flags & SASVerified) == SASVerified); }\n\n    /**\n     * @brief Return the ZID for this record\n     */\n    const uint8_t* getIdentifier() {return record.identifier; }\n\n    /**\n     * @brief Check if RS1 is still valid\n     *\n     * Returns true if RS1 is still valid, false otherwise.\n     *\n     * @return\n     *    Returns true is RS1 is not expired (valid), false otherwise.\n     */\n    bool isRs1NotExpired();\n\n    /**\n     * @brief Returns pointer to RS1 data.\n     */\n    const unsigned char* getRs1() { return record.rs1Data; }\n\n    /**\n     * @brief Check if RS2 is still valid\n     *\n     * Returns true if RS2 is still valid, false otherwise.\n     *\n     * @return\n     *    Returns true is RS2 is not expired (valid), false otherwise.\n     */\n    bool isRs2NotExpired();\n\n    /**\n     * @brief Returns pointer to RS1 data.\n     */\n    const unsigned char* getRs2() { return record.rs2Data; }\n\n    /**\n     * @brief Sets new RS1 data and associated expiration value.\n     *\n     * If the expiration value is >0 or -1 the method stores the new\n     * RS1. Before it stores the new RS1 it shifts the exiting RS1\n     * into RS2 (together with its expiration time). Then it computes\n     * the expiration time of the and stores the result together with\n     * the new RS1.\n     *\n     * If the expiration value is -1 then this RS will never expire.\n     *\n     * If the expiration value is 0 then the expiration value of a\n     * stored RS1 is cleared and no new RS1 value is stored. Also RS2\n     * is left unchanged.\n     *\n     * @param data\n     *    Points to the new RS1 data.\n     * @param expire\n     *    The expiration interval in seconds. Default is -1.\n     *\n     */\n    void setNewRs1(const unsigned char* data, int32_t expire =-1);\n\n    /**\n     * @brief Set MiTM key data.\n     *\n     */\n    void setMiTMData(const unsigned char* data);\n\n    /**\n     * @brief Get MiTM key data.\n     *\n     */\n    const unsigned char* getMiTMData() {return record.mitmKey; }\n\n    int getRecordType() {return FILE_TYPE_RECORD; }\n    \n    /**\n     * @brief Get Secure since date.\n     * \n     * The file based cache implementation does not support this datum, thus return 0\n     * \n     */\n    int64_t getSecureSince() { return 0; }\n};\n\n#endif // ZIDRECORDSMALL\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZRtp.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTP_H_\n#define _ZRTP_H_\n/**\n * @file ZRtp.h\n * @brief The ZRTP main engine\n * @defgroup GNU_ZRTP The GNU ZRTP C++ implementation\n * @{\n */\n\n#include <cstdlib>\n\n#include <libzrtpcpp/ZrtpPacketHello.h>\n#include <libzrtpcpp/ZrtpPacketHelloAck.h>\n#include <libzrtpcpp/ZrtpPacketCommit.h>\n#include <libzrtpcpp/ZrtpPacketDHPart.h>\n#include <libzrtpcpp/ZrtpPacketConfirm.h>\n#include <libzrtpcpp/ZrtpPacketConf2Ack.h>\n#include <libzrtpcpp/ZrtpPacketGoClear.h>\n#include <libzrtpcpp/ZrtpPacketClearAck.h>\n#include <libzrtpcpp/ZrtpPacketError.h>\n#include <libzrtpcpp/ZrtpPacketErrorAck.h>\n#include <libzrtpcpp/ZrtpPacketPing.h>\n#include <libzrtpcpp/ZrtpPacketPingAck.h>\n#include <libzrtpcpp/ZrtpPacketSASrelay.h>\n#include <libzrtpcpp/ZrtpPacketRelayAck.h>\n#include <libzrtpcpp/ZrtpCallback.h>\n#include <libzrtpcpp/ZIDCache.h>\n\n#include <cryptcommon/skeinApi.h>\n#ifdef ZRTP_OPENSSL\n#include <openssl/crypto.h>\n#include <openssl/sha.h>\n#else\n#include <zrtp/crypto/sha2.h>\n#endif\n\n#ifndef SHA256_DIGEST_LENGTH\n#define SHA256_DIGEST_LENGTH 32\n#endif\n\n// Prepare to support digest algorithms up to 512 bit (64 bytes)\n#define MAX_DIGEST_LENGTH       64\n#define IMPL_MAX_DIGEST_LENGTH  64\n\n// max. number of parallel supported ZRTP protocol versions.\n#define MAX_ZRTP_VERSIONS       2\n\n// currently only 1.10 supported\n#define SUPPORTED_ZRTP_VERSIONS       1\n\n// Integer representation of highest supported ZRTP protocol version\n#define HIGHEST_ZRTP_VERION    12\n\nclass __EXPORT ZrtpStateClass;\nclass ZrtpDH;\nclass ZRtp;\n\n/**\n * The main ZRTP class.\n *\n * This is the main class of the RTP/SRTP independent part of the GNU\n * ZRTP. It handles the ZRTP HMAC, DH, and other data management. The\n * user of this class needs to know only a few methods and needs to\n * provide only a few external functions to connect to a Timer\n * mechanism and to send data via RTP and SRTP. Refer to the\n * ZrtpCallback class to get detailed information regading the\n * callback methods required by GNU RTP.\n *\n * The class ZrtpQueue is the GNU ccRTP specific implementation that\n * extends standard ccRTP RTP provide ZRTP support. Refer to the\n * documentation of ZrtpQueue to get more information about the usage\n * of ZRtp and associated classes.\n *\n * The main entry into the ZRTP class is the processExtensionHeader()\n * method.\n *\n * This class does not directly handle the protocol states, timers,\n * and packet resend. The protocol state engine is responsible for\n * these actions.\n *\n * Example how to use ZRtp:\n *<pre>\n *    zrtpEngine = new ZRtp((uint8_t*)ownZid, (ZrtpCallback*)this, idString);\n *    zrtpEngine->startZrtpEngine();\n *</pre>\n * @see ZrtpCallback\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\nclass __EXPORT ZRtp {\n\n    public:\n\n    typedef enum _secrets {\n        Rs1 = 1,\n        Rs2 = 2,\n        Pbx = 4,\n        Aux = 8\n    } secrets;\n\n    typedef struct _zrtpInfo {\n        int32_t secretsCached;\n        int32_t secretsMatched;\n        int32_t secretsMatchedDH;\n        const char *hash;\n        const char *cipher;\n        const char *pubKey;\n        const char *sasType;\n        const char *authLength;\n    } zrtpInfo;\n\n    /**\n     * Faster access to Hello packets with different versions.\n     */\n    typedef struct _HelloPacketVersion {\n        int32_t version;\n        ZrtpPacketHello* packet;\n        uint8_t helloHash[IMPL_MAX_DIGEST_LENGTH];\n    } HelloPacketVersion;\n\n    /**\n     * Constructor intializes all relevant data but does not start the\n     * engine.\n     */\n    ZRtp(uint8_t* myZid, ZrtpCallback* cb, std::string id,\n         ZrtpConfigure* config, bool mitmm= false, bool sasSignSupport= false);\n\n    /**\n     * Destructor cleans up.\n     */\n    ~ZRtp();\n\n    /**\n     * Kick off the ZRTP protocol engine.\n     *\n     * This method calls the ZrtpStateClass#evInitial() state of the state\n     * engine. After this call we are able to process ZRTP packets\n     * from our peer and to process them.\n     */\n    void startZrtpEngine();\n\n    /**\n     * Stop ZRTP security.\n     *\n     */\n    void stopZrtp();\n\n    /**\n     * Process ZRTP message.\n     *\n     * The method takes the data and forwards it to the ZRTP state engine for further\n     * processing. It's the caller's duty to check the ZRTP CRC and the ZRTP magic\n     * cookie before calling this function.\n     *\n     * @param extHeader\n     *    A pointer to the first byte of the ZRTP message. Refer to RFC6189.\n     * @param peerSSRC\n     *    The peer's SSRC.\n     * @param length\n     *     of the received data packet, this includes the RTP like header\n     *     and the ZRTP CRC field - used to do santity checks.\n     *\n     * @return\n     *    Code indicating further packet handling, see description above.\n     */\n    void processZrtpMessage(uint8_t *extHeader, uint32_t peerSSRC, size_t length);\n\n    /**\n     * Process a timeout event.\n     *\n     * We got a timeout from the timeout provider. Forward it to the\n     * protocol state engine.\n     *\n     */\n    void processTimeout();\n\n    /**\n     * Check for and handle GoClear ZRTP packet header.\n     *\n     * This method checks if this is a GoClear packet. If not, just return\n     * false. Otherwise handle it according to the specification.\n     *\n     * @param extHeader\n     *    A pointer to the first byte of the extension header. Refer to\n     *    RFC3550.\n     * @return\n     *    False if not a GoClear, true otherwise.\n     */\n    bool handleGoClear(uint8_t *extHeader);\n\n    /**\n     * Set the auxilliary secret.\n     *\n     * Use this method to set the auxilliary secret data. Refer to ZRTP\n     * specification, chapter 4.3 ff\n     *\n     * @param data\n     *     Points to the secret data.\n     * @param length\n     *     Length of the auxilliary secrect in bytes\n     */\n    void setAuxSecret(uint8_t* data, int32_t length);\n\n    /**\n     * Check current state of the ZRTP state engine\n     *\n     * @param state\n     *    The state to check.\n     * @return\n     *    Returns true id ZRTP engine is in the given state, false otherwise.\n     */\n    bool inState(int32_t state);\n\n    /**\n     * Set SAS as verified.\n     *\n     * Call this method if the user confirmed (verfied) the SAS. ZRTP\n     * remembers this together with the retained secrets data.\n     */\n    void SASVerified();\n\n    /**\n     * Reset the SAS verfied flag for the current active user's retained secrets.\n     *\n     */\n    void resetSASVerified();\n\n    /**\n     * Get the ZRTP Hello Hash data.\n     *\n     * Use this method to get the ZRTP Hello hash data. The method\n     * returns the data as a string containing the ZRTP protocol version and\n     * hex-digits.\n     * \n     * The index defines which Hello packet to use. Each supported ZRTP procol version\n     * uses a different Hello packet and thus computes different hashes.\n     *\n     * Refer to ZRTP specification, chapter 8.\n     * \n     * @param index\n     *     Hello hash of the Hello packet identfied by index. Index must be 0 <= index < MAX_ZRTP_VERSIONS.\n     *\n     * @return\n     *    a std::string formatted according to RFC6189 section 8 without the leading 'a=zrtp-hash:'\n     *    SDP attribute identifier. The hello hash is available immediately after class instantiation.\n     * \n     * @see getNumberSupportedVersions()\n     */\n    std::string getHelloHash(int index);\n\n    /**\n     * Get the peer's ZRTP Hello Hash data.\n     *\n     * Use this method to get the peer's ZRTP Hello Hash data. The method\n     * returns the data as a string containing the ZRTP protocol version and\n     * hex-digits.\n     *\n     * The peer's hello hash is available only after ZRTP received a hello. If\n     * no data is available the function returns an empty string.\n     *\n     * Refer to ZRTP specification, chapter 8.\n     *\n     * @return\n     *    a std:string containing the Hello version and the hello hash as hex digits.\n     */\n    std::string getPeerHelloHash();\n\n    /**\n     * Get Multi-stream parameters.\n     *\n     * Deprecated - use  getMultiStrParams(ZRtp **zrtpMaster);\n     * \n     * Use this method to get the Multi-stream that were computed during\n     * the ZRTP handshake. An application may use these parameters to\n     * enable multi-stream processing for an associated SRTP session.\n     *\n     * Refer to chapter 4.4.2 in the ZRTP specification for further details\n     * and restriction how and when to use multi-stream mode.\n     *\n     * @return\n     *    a string that contains the multi-stream parameters. The application\n     *    must not modify the contents of this string, it is opaque data. The\n     *    application may hand over this string to a new ZrtpQueue instance\n     *    to enable multi-stream processing for this ZrtpQueue.\n     *    If ZRTP was not started or ZRTP is not yet in secure state the method\n     *    returns an empty string.\n     */\n    DEPRECATED std::string getMultiStrParams() {return getMultiStrParams(NULL); }\n\n    /**\n     * Set Multi-stream parameters.\n     *\n     * Deprecated - use setMultiStrParams(std::string parameters, ZRtp* zrtpMaster);\n     * \n     * Use this method to set the parameters required to enable Multi-stream\n     * processing of ZRTP. The multi-stream parameters must be set before the\n     * application starts the ZRTP protocol engine.\n     *\n     * Refer to chapter 4.4.2 in the ZRTP specification for further details\n     * of multi-stream mode.\n     *\n     * @param parameters\n     *     A string that contains the multi-stream parameters that this\n     *     new ZrtpQueue instanace shall use. See also\n     *     <code>getMultiStrParams()</code>\n     */\n    DEPRECATED void setMultiStrParams(std::string parameters) { setMultiStrParams(parameters, NULL);}\n\n    /**\n     * Get Multi-stream parameters.\n     *\n     * Use this method to get the Multi-stream that were computed during\n     * the ZRTP handshake. An application may use these parameters to\n     * enable multi-stream processing for an associated SRTP session.\n     *\n     * Refer to chapter 4.4.2 in the ZRTP specification for further details\n     * and restriction how and when to use multi-stream mode.\n     *\n     * @param zrtpMaster\n     *     Where the function returns the pointer of the ZRTP master stream.\n     * @return\n     *    a string that contains the multi-stream parameters. The application\n     *    must not modify the contents of this string, it is opaque data. The\n     *    application may hand over this string to a new ZrtpQueue instance\n     *    to enable multi-stream processing for this ZrtpQueue.\n     *    If ZRTP was not started or ZRTP is not yet in secure state the method\n     *    returns an empty string.\n     */\n    std::string getMultiStrParams(ZRtp **zrtpMaster);\n\n    /**\n     * Set Multi-stream parameters.\n     *\n     * Use this method to set the parameters required to enable Multi-stream\n     * processing of ZRTP. The multi-stream parameters must be set before the\n     * application starts the ZRTP protocol engine.\n     *\n     * Refer to chapter 4.4.2 in the ZRTP specification for further details\n     * of multi-stream mode.\n     *\n     * @param parameters\n     *     A string that contains the multi-stream parameters that this\n     *     new ZrtpQueue instanace shall use. See also\n     *     <code>getMultiStrParams(ZRtp **zrtpMaster)</code>\n     * @param zrtpMaster\n     *     The pointer of the ZRTP master stream.\n     */\n    void setMultiStrParams(std::string parameters, ZRtp* zrtpMaster);\n\n    /**\n     * Check if this ZRTP session is a Multi-stream session.\n     *\n     * Use this method to check if this ZRTP instance uses multi-stream.\n     * Refer to chapters 4.2 and 4.4.2 in the ZRTP.\n     *\n     * @return\n     *     True if multi-stream is used, false otherwise.\n     */\n    bool isMultiStream();\n\n    /**\n     * Check if the other ZRTP client supports Multi-stream.\n     *\n     * Use this method to check if the other ZRTP client supports\n     * Multi-stream mode.\n     *\n     * @return\n     *     True if multi-stream is available, false otherwise.\n     */\n    bool isMultiStreamAvailable();\n\n    /**\n     * Accept a PBX enrollment request.\n     *\n     * If a PBX service asks to enroll the PBX trusted MitM key and the user\n     * accepts this request, for example by pressing an OK button, the client\n     * application shall call this method and set the parameter\n     * <code>accepted</code> to true. If the user does not accept the request\n     * set the parameter to false.\n     *\n     * @param accepted\n     *     True if the enrollment request is accepted, false otherwise.\n     */\n    void acceptEnrollment(bool accepted);\n\n    /**\n     * Check the state of the enrollment mode.\n     * \n     * If true then we will set the enrollment flag (E) in the confirm\n     * packets and perform the enrollment actions. A MitM (PBX) enrollment service\n     * started this ZRTP session. Can be set to true only if mitmMode is also true.\n     * \n     * @return status of the enrollmentMode flag.\n     */\n    bool isEnrollmentMode();\n\n    /**\n     * Set the state of the enrollment mode.\n     * \n     * If true then we will set the enrollment flag (E) in the confirm\n     * packets and perform the enrollment actions. A MitM (PBX) enrollment \n     * service must sets this mode to true. \n     * \n     * Can be set to true only if mitmMode is also true. \n     * \n     * @param enrollmentMode defines the new state of the enrollmentMode flag\n     */\n    void setEnrollmentMode(bool enrollmentMode);\n\n    /**\n     * Check if a peer's cache entry has a vaild MitM key.\n     *\n     * If true then the other peer ha a valid MtiM key, i.e. the peer has performed\n     * the enrollment procedure. A PBX ZRTP Back-2-Back application can use this function\n     * to check which of the peers is enrolled.\n     *\n     * @return True if the other peer has a valid Mitm key (is enrolled).\n     */\n    bool isPeerEnrolled();\n\n    /**\n     * Send the SAS relay packet.\n     * \n     * The method creates and sends a SAS relay packet according to the ZRTP\n     * specifications. Usually only a MitM capable user agent (PBX) uses this\n     * function.\n     * \n     * @param sh the full SAS hash value, 32 bytes\n     * @param render the SAS rendering algorithm\n     */\n    bool sendSASRelayPacket(uint8_t* sh, std::string render);\n\n    /**\n     * Get the commited SAS rendering algorithm for this ZRTP session.\n     * \n     * @return the commited SAS rendering algorithm\n     */\n    std::string getSasType();\n \n    /**\n     * Get the computed SAS hash for this ZRTP session.\n     *\n     * A PBX ZRTP back-to-Back function uses this function to get the SAS\n     * hash of an enrolled client to construct the SAS relay packet for\n     * the other client.\n     *\n     * @return a pointer to the byte array that contains the full\n     *         SAS hash.\n     */\n    uint8_t* getSasHash();\n\n    /**\n     * Set signature data.\n     *\n     * This functions stores signature data and transmitts it during ZRTP\n     * processing to the other party as part of the Confirm packets. Refer to\n     * chapters 5.7 and 7.2.\n     *\n     * The signature data must be set before ZRTP the application calls\n     * <code>start()</code>.\n     *\n     * @param data\n     *    The signature data including the signature type block. The method\n     *    copies this data into the Confirm packet at signature type block.\n     * @param length\n     *    The length of the signature data in bytes. This length must be\n     *    multiple of 4.\n     * @return\n     *    True if the method stored the data, false otherwise.\n     */\n    bool setSignatureData(uint8_t* data, int32_t length);\n\n    /**\n     * Get signature data.\n     *\n     * This functions returns a pointer to the signature data that was receivied\n     * during ZRTP processing. Refer to chapters 5.7 and 7.2.\n     *\n     * The returned pointer points to volatile data that is valid only during the\n     * <code>checkSASSignature()</code> callback funtion. The application must copy\n     * the signature data if it will be used after the callback function returns.\n     *\n     * The signature data can be retrieved after ZRTP enters secure state.\n     * <code>start()</code>.\n     *\n     * @return\n     *    Pointer to signature data.\n     */\n    const uint8_t* getSignatureData();\n\n    /**\n     * Get length of signature data in number of bytes.\n     *\n     * This functions returns the length of signature data that was receivied\n     * during ZRTP processing. Refer to chapters 5.7 and 7.2.\n     *\n     * @return\n     *    Length in bytes of the received signature data. The method returns\n     *    zero if no signature data is avilable.\n     */\n    int32_t getSignatureLength();\n\n    /**\n     * Emulate a Conf2Ack packet.\n     *\n     * This method emulates a Conf2Ack packet. According to ZRTP specification\n     * the first valid SRTP packet that the Initiator receives must switch\n     * on secure mode. Refer to chapter 4 in the specificaton\n     *\n     */\n    void conf2AckSecure();\n\n     /**\n      * Get other party's ZID (ZRTP Identifier) data\n      *\n      * This functions returns the other party's ZID that was receivied\n      * during ZRTP processing.\n      *\n      * The ZID data can be retrieved after ZRTP receive the first Hello\n      * packet from the other party. The application may call this method\n      * for example during SAS processing in showSAS(...) user callback\n      * method.\n      *\n      * @param data\n      *    Pointer to a data buffer. This buffer must have a size of\n      *    at least 12 bytes (96 bit) (ZRTP Identifier, see chap. 4.9)\n      * @return\n      *    Number of bytes copied into the data buffer - must be equivalent\n      *    to 96 bit, usually 12 bytes.\n      */\n     int32_t getPeerZid(uint8_t* data);\n\n     /**\n      * Returns a pointer to the gather detailed information structure.\n      *\n      * This structure contains some detailed information about the negotiated\n      * algorithms, the chached and matched shared secrets.\n      */\n     const zrtpInfo *getDetailInfo();\n\n     /**\n      * Get peer's client id.\n      *\n      * @return the peer's client id or an empty @c string if not set.\n      */\n     std::string getPeerClientId();\n\n     /**\n      * Get peer's protocl version string.\n      *\n      * @return the peer's protocol version or an empty @c string if not set.\n      */\n     std::string getPeerProtcolVersion();\n\n     /**\n      * Get number of supported ZRTP protocol versions.\n      *\n      * @return the number of supported ZRTP protocol versions.\n      */\n     int32_t getNumberSupportedVersions() {return SUPPORTED_ZRTP_VERSIONS;}\n\n     /**\n      * Get negotiated ZRTP protocol version.\n      *\n      * @return the integer representation of the negotiated ZRTP protocol version.\n      */\n     int32_t getCurrentProtocolVersion() {return currentHelloPacket->getVersionInt();}\n\n     /**\n      * Validate the RS2 data if necessary.\n      *\n      * The cache functions stores the RS2 data but does not set its valid flag. The\n      * application may decide to set this flag.\n      */\n     void setRs2Valid();\n\n     /**\n      * Get the secure since field\n      * \n      * Returns the secure since field or 0 if no such field is available. Secure since\n      * uses the unixepoch.\n      */\n     int64_t getSecureSince();\n\n     /**\n      * Set the resend counter of timer T1 - T1 controls the Hello packets.\n      * \n      * This overwrites the standard value of 20 retries. Setting to <0 means\n      * 'indefinite', counter values less then 10 are ignored.\n      * \n      * Applications may set the resend counter based on network  or some other \n      * conditions. Applications may set this value any time and it's in effect\n      * for the current call. Setting the counter after the hello phase has no\n      * effect.\n      */\n     void setT1Resend(int32_t counter);\n\n     /**\n      * Set the extended resend counter of timer T1 - T1 controls the Hello packets.\n      *\n      * More retries to extend time, see RFC6189 chap. 6. This overwrites the standard \n      * value of 60 extended retiries.\n      * \n      * Applications may set the resend counter based on network  or some other \n      * conditions. \n      */\n     void setT1ResendExtend(int32_t counter);\n\n     /**\n      * Set the time capping of timer T1 - T1 controls the Hello packets.\n      * \n      * Values <50ms are not set.\n      */\n     void setT1Capping(int32_t capping);\n\n     /**\n      * Set the resend counter of timer T2 - T2 controls other (post-Hello) packets.\n      * \n      * This overwrites the standard value of 10 retiries. Setting to <0 means\n      * 'indefinite', counter values less then 10 are ignored.\n      * \n      * Applications may set the resend counter based on network  or some other \n      * conditions. Applications may set this value any time and it's in effect\n      * for the current call. Setting the counter after tZRTP enetered secure state\n      * has no effect.\n      */\n     void setT2Resend(int32_t counter);\n\n     /**\n      * Set the time capping of timer T2 - T2 controls other (post-Hello) packets.\n      * \n      * Values <150ms are not set.\n      */\n     void setT2Capping(int32_t capping);\n\n     /**\n      * @brief Get required buffer size to get all 32-bit statistic counters of ZRTP\n      *\n      * @param streamNm stream, if not specified the default is @c AudioStream\n      * \n      * @return number of 32 bit integer elements required or < 0 on error\n      */\n     int getNumberOfCountersZrtp();\n\n     /**\n      * @brief Read statistic counters of ZRTP\n      * \n      * @param buffer Pointer to buffer of 32-bit integers. The buffer must be able to\n      *         hold at least getNumberOfCountersZrtp() 32-bit integers\n      * @param streamNm stream, if not specified the default is @c AudioStream\n      * \n      * @return number of 32-bit counters returned in buffer or < 0 on error\n      */\n     int getCountersZrtp(int32_t* counters);\n\nprivate:\n     typedef union _hashCtx {\n         SkeinCtx_t  skeinCtx;\n#ifdef ZRTP_OPENSSL\n         SHA256_CTX  sha256Ctx;\n         SHA512_CTX  sha384Ctx;\n#else\n         sha256_ctx  sha256Ctx;\n         sha384_ctx  sha384Ctx;\n#endif\n     } HashCtx;\n\n     friend class ZrtpStateClass;\n\n    /**\n     * The state engine takes care of protocol processing.\n     */\n    ZrtpStateClass* stateEngine;\n\n    /**\n     * This is my ZID that I send to the peer.\n     */\n    uint8_t ownZid[IDENTIFIER_LEN];\n\n    /**\n     * The peer's ZID\n     */\n    uint8_t peerZid[IDENTIFIER_LEN];\n\n    /**\n     * The callback class provides me with the interface to send\n     * data and to deal with timer management of the hosting system.\n     */\n    ZrtpCallback* callback;\n\n    /**\n     * My active Diffie-Helman context\n     */\n    ZrtpDH* dhContext;\n\n    /**\n     * The computed DH shared secret\n     */\n    uint8_t* DHss;\n\n    /**\n     * My computed public key\n     */\n    uint8_t pubKeyBytes[400];\n    /**\n     * Length off public key\n     */\n//    int32_t pubKeyLen;\n    /**\n     * My Role in the game\n     */\n    Role myRole;\n\n    /**\n     * The human readable SAS value\n     */\n    std::string SAS;\n\n    /**\n     * The SAS hash for signaling and alike. Refer to chapters\n     * 4.5 and 7 how sasHash, sasValue and the SAS string are derived.\n     */\n    uint8_t sasHash[MAX_DIGEST_LENGTH];\n    /**\n     * The ids for the retained and other shared secrets\n     */\n    uint8_t rs1IDr[MAX_DIGEST_LENGTH];\n    uint8_t rs2IDr[MAX_DIGEST_LENGTH];\n    uint8_t auxSecretIDr[MAX_DIGEST_LENGTH];\n    uint8_t pbxSecretIDr[MAX_DIGEST_LENGTH];\n\n    uint8_t rs1IDi[MAX_DIGEST_LENGTH];\n    uint8_t rs2IDi[MAX_DIGEST_LENGTH];\n    uint8_t auxSecretIDi[MAX_DIGEST_LENGTH];\n    uint8_t pbxSecretIDi[MAX_DIGEST_LENGTH];\n\n    /**\n     * pointers to aux secret storage and length of aux secret\n     */\n    uint8_t* auxSecret;\n    int32_t auxSecretLength;\n\n    /**\n     * Record if valid rs1 and/or rs1 were found in the\n     * retaind secret cache.\n     */\n    bool rs1Valid;\n    bool rs2Valid;\n    /**\n     * My hvi\n     */\n    uint8_t hvi[MAX_DIGEST_LENGTH];\n\n    /**\n     * The peer's hvi\n     */\n    uint8_t peerHvi[8*ZRTP_WORD_SIZE];\n\n    /**\n     * Context to compute the SHA256 hash of selected messages.\n     * Used to compute the s0, refer to chapter 4.4.1.4\n     */\n    void* msgShaContext;\n    /**\n     * Commited Hash, Cipher, and public key algorithms\n     */\n    AlgorithmEnum* hash;\n    AlgorithmEnum* cipher;\n    AlgorithmEnum* pubKey;\n    /**\n     * The selected SAS type.\n     */\n    AlgorithmEnum* sasType;\n\n    /**\n     * The selected SAS type.\n     */\n    AlgorithmEnum* authLength;\n\n    /**\n     * The Hash images as defined in chapter 5.1.1 (H0 is a random value,\n     * not stored here). Need full SHA 256 lenght to store hash value but\n     * only the leftmost 128 bits are used in computations and comparisons.\n     */\n    uint8_t H0[IMPL_MAX_DIGEST_LENGTH];\n    uint8_t H1[IMPL_MAX_DIGEST_LENGTH];\n    uint8_t H2[IMPL_MAX_DIGEST_LENGTH];\n    uint8_t H3[IMPL_MAX_DIGEST_LENGTH];\n\n    uint8_t peerHelloHash[IMPL_MAX_DIGEST_LENGTH];\n    uint8_t peerHelloVersion[ZRTP_WORD_SIZE + 1];   // +1 for nul byte\n\n    // We get the peer's H? from the message where length is defined as 8 words\n    uint8_t peerH0[8*ZRTP_WORD_SIZE];\n    uint8_t peerH1[8*ZRTP_WORD_SIZE];\n    uint8_t peerH2[8*ZRTP_WORD_SIZE];\n    uint8_t peerH3[8*ZRTP_WORD_SIZE];\n\n    /**\n     * The SHA256 hash over selected messages\n     */\n    uint8_t messageHash[MAX_DIGEST_LENGTH];\n\n    /**\n     * The s0\n     */\n    uint8_t s0[MAX_DIGEST_LENGTH];\n\n    /**\n     * The new Retained Secret\n     */\n    uint8_t newRs1[MAX_DIGEST_LENGTH];\n\n    /**\n     * The GoClear HMAC keys and confirm HMAC key\n     */\n    uint8_t hmacKeyI[MAX_DIGEST_LENGTH];\n    uint8_t hmacKeyR[MAX_DIGEST_LENGTH];\n\n    /**\n     * The Initiator's srtp key and salt\n     */\n    uint8_t srtpKeyI[MAX_DIGEST_LENGTH];\n    uint8_t srtpSaltI[MAX_DIGEST_LENGTH];\n\n    /**\n     * The Responder's srtp key and salt\n     */\n    uint8_t srtpKeyR[MAX_DIGEST_LENGTH];\n    uint8_t srtpSaltR[MAX_DIGEST_LENGTH];\n\n    /**\n     * The keys used to encrypt/decrypt the confirm message\n     */\n    uint8_t zrtpKeyI[MAX_DIGEST_LENGTH];\n    uint8_t zrtpKeyR[MAX_DIGEST_LENGTH];\n\n    HashCtx hashCtx;\n\n    /**\n     * Pointers to negotiated hash and HMAC functions\n     */\n    void (*hashFunction)(unsigned char *data,\n            unsigned int data_length,\n            unsigned char *digest);\n\n    void (*hashListFunction)(unsigned char *data[],\n            unsigned int data_length[],\n            unsigned char *digest);\n\n    void (*hmacFunction)(uint8_t* key, uint32_t key_length,\n                uint8_t* data, int32_t data_length,\n                uint8_t* mac, uint32_t* mac_length);\n\n    void (*hmacListFunction)( uint8_t* key, uint32_t key_length,\n                           uint8_t* data[], uint32_t data_length[],\n                           uint8_t* mac, uint32_t* mac_length );\n\n    void* (*createHashCtx)(void* ctx);\n\n    void (*closeHashCtx)(void* ctx, unsigned char* digest);\n\n    void (*hashCtxFunction)(void* ctx, unsigned char* data,\n           unsigned int dataLength);\n\n    void (*hashCtxListFunction)(void* ctx, unsigned char* dataChunks[],\n           unsigned int dataChunkLength[]);\n\n    int32_t hashLength;\n\n    // Funtion pointers to implicit hash and hmac functions\n    void (*hashFunctionImpl)(unsigned char *data,\n            unsigned int data_length,\n            unsigned char *digest);\n\n    void (*hashListFunctionImpl)(unsigned char *data[],\n            unsigned int data_length[],\n            unsigned char *digest);\n\n    void (*hmacFunctionImpl)(uint8_t* key, uint32_t key_length,\n                uint8_t* data, int32_t data_length,\n                uint8_t* mac, uint32_t* mac_length);\n\n    void (*hmacListFunctionImpl)( uint8_t* key, uint32_t key_length,\n                           uint8_t* data[], uint32_t data_length[],\n                           uint8_t* mac, uint32_t* mac_length );\n\n    int32_t hashLengthImpl;\n\n    /**\n     * The ZRTP Session Key\n     * Refer to chapter 5.4.1.4\n     */\n    uint8_t zrtpSession[MAX_DIGEST_LENGTH];\n\n    /**\n     * True if this ZRTP instance uses multi-stream mode.\n     */\n    bool multiStream;\n\n        /**\n     * True if the other ZRTP client supports multi-stream mode.\n     */\n    bool multiStreamAvailable;\n\n    /**\n     * Enable MitM (PBX) enrollment\n     * \n     * If set to true then ZRTP honors the PBX enrollment flag in\n     * Commit packets and calls the appropriate user callback\n     * methods. If the parameter is set to false ZRTP ignores the PBX\n     * enrollment flags.\n     */\n    bool enableMitmEnrollment;\n\n    /**\n     * True if a valid trusted MitM key of the other peer is available, i.e. enrolled.\n     */\n    bool peerIsEnrolled;\n\n    /**\n     * Set to true if the Hello packet contained the M-flag (MitM flag).\n     * We use this later to check some stuff for SAS Relay processing\n     */\n    bool mitmSeen;\n\n    /**\n     * Temporarily store computed pbxSecret, if user accepts enrollment then\n     * it will copied to our ZID record of the PBX (MitM)  \n     */\n    uint8_t* pbxSecretTmp;\n    uint8_t  pbxSecretTmpBuffer[MAX_DIGEST_LENGTH];\n\n    /**\n     * If true then we will set the enrollment flag (E) in the confirm\n     * packets. Set to true if the PBX enrollment service started this ZRTP \n     * session. Can be set to true only if mitmMode is also true. \n     */\n    bool enrollmentMode;\n\n    /**\n     * Configuration data which algorithms to use.\n     */\n    ZrtpConfigure configureAlgos;\n    /**\n     * Pre-initialized packets.\n     */\n    ZrtpPacketHello    zrtpHello_11;\n    ZrtpPacketHello    zrtpHello_12;   // Prepare for ZRTP protocol version 1.2\n\n    ZrtpPacketHelloAck zrtpHelloAck;\n    ZrtpPacketConf2Ack zrtpConf2Ack;\n    ZrtpPacketClearAck zrtpClearAck;\n    ZrtpPacketGoClear  zrtpGoClear;\n    ZrtpPacketError    zrtpError;\n    ZrtpPacketErrorAck zrtpErrorAck;\n    ZrtpPacketDHPart   zrtpDH1;\n    ZrtpPacketDHPart   zrtpDH2;\n    ZrtpPacketCommit   zrtpCommit;\n    ZrtpPacketConfirm  zrtpConfirm1;\n    ZrtpPacketConfirm  zrtpConfirm2;\n    ZrtpPacketPingAck  zrtpPingAck;\n    ZrtpPacketSASrelay zrtpSasRelay;\n    ZrtpPacketRelayAck zrtpRelayAck;\n\n    HelloPacketVersion helloPackets[MAX_ZRTP_VERSIONS + 1];\n    int32_t highestZrtpVersion;\n\n    /// Pointer to Hello packet sent to partner, initialized in ZRtp, modified by ZrtpStateClass\n    ZrtpPacketHello* currentHelloPacket;\n\n    /**\n     * ZID cache record\n     */\n    ZIDRecord *zidRec;\n\n    /**\n     * Save record\n     * \n     * If false don't save record until user vrified and confirmed the SAS.\n     */\n    bool saveZidRecord;\n    /**\n     * Random IV data to encrypt the confirm data, 128 bit for AES\n     */\n    uint8_t randomIV[16];\n\n    uint8_t tempMsgBuffer[1024];\n    int32_t lengthOfMsgData;\n\n    /**\n     * Variables to store signature data. Includes the signature type block\n     */\n    const uint8_t* signatureData;       // will be set when needed\n    int32_t  signatureLength;     // overall length in bytes\n\n    /**\n     * Is true if the other peer signaled SAS signature support in its Hello packet.\n     */\n    bool signSasSeen;\n\n    uint32_t peerSSRC;           // peer's SSRC, required to setup PingAck packet\n\n    zrtpInfo detailInfo;         // filled with some more detailded information if application would like to know\n\n    std::string peerClientId;    // store the peer's client Id\n\n    ZRtp* masterStream;                    // This is the master stream in case this is a multi-stream\n    std::vector<std::string> peerNonces;   // Store nonces we got from our partner. Using std::string\n                                           // just simplifies memnory management, nonces are binary data, not strings :-)\n    /**\n     * Enable or disable paranoid mode.\n     *\n     * The Paranoid mode controls the behaviour and handling of the SAS verify flag. If\n     * Panaoid mode is set to flase then ZRtp applies the normal handling. If Paranoid\n     * mode is set to true then the handling is:\n     *\n     * <ul>\n     * <li> Force the SAS verify flag to be false at srtpSecretsOn() callback. This gives\n     *      the user interface (UI) the indication to handle the SAS as <b>not verified</b>.\n     *      See implementation note below.</li>\n     * <li> Don't set the SAS verify flag in the <code>Confirm</code> packets, thus the other\n     *      also must report the SAS as <b>not verified</b>.</li>\n     * <li> ignore the <code>SASVerified()</code> function, thus do not set the SAS to verified\n     *      in the ZRTP cache. </li>\n     * <li> Disable the <b>Trusted PBX MitM</b> feature. Just send the <code>SASRelay</code> packet\n     *      but do not process the relayed data. This protects the user from a malicious\n     *      \"trusted PBX\".</li>\n     * </ul>\n     * ZRtp performs alls other steps during the ZRTP negotiations as usual, in particular it\n     * computes, compares, uses, and stores the retained secrets. This avoids unnecessary warning\n     * messages. The user may enable or disable the Paranoid mode on a call-by-call basis without\n     * breaking the key continuity data.\n     *\n     * <b>Implementation note:</b></br>\n     * An application shall always display the SAS code if the SAS verify flag is <code>false</code>.\n     * The application shall also use mechanisms to remind the user to compare the SAS code, for\n     * example useing larger fonts, different colours and other display features.\n     */\n    bool paranoidMode;\n\n    /**\n     * Find the best Hash algorithm that is offered in Hello.\n     *\n     * Find the best, that is the strongest, Hash algorithm that our peer\n     * offers in its Hello packet.\n     *\n     * @param hello\n     *    The Hello packet.\n     * @return\n     *    The Enum that identifies the best offered Hash algortihm. Return\n     *    mandatory algorithm if no match was found.\n     */\n    AlgorithmEnum* findBestHash(ZrtpPacketHello *hello);\n\n    /**\n     * Find the best symmetric cipher algorithm that is offered in Hello.\n     *\n     * Find the best, that is the strongest, cipher algorithm that our peer\n     * offers in its Hello packet.\n     *\n     * @param hello\n     *    The Hello packet.\n     * @param pk\n     *    The id of the selected public key algorithm\n     * @return\n     *    The Enum that identifies the best offered Cipher algorithm. Return\n     *    mandatory algorithm if no match was found.\n     */\n    AlgorithmEnum* findBestCipher(ZrtpPacketHello *hello,  AlgorithmEnum* pk);\n\n    /**\n     * Find the best Public Key algorithm that is offered in Hello.\n     *\n     * Find the best, that is the strongest, public key algorithm that our peer\n     * offers in its Hello packet.\n     *\n     * @param hello\n     *    The Hello packet.\n     * @return\n     *    The Enum that identifies the best offered Public Key algorithm. Return\n     *    mandatory algorithm if no match was found.\n     */\n    AlgorithmEnum* findBestPubkey(ZrtpPacketHello *hello);\n\n    /**\n     * Find the best SAS algorithm that is offered in Hello.\n     *\n     * Find the best, that is the strongest, SAS algorithm that our peer\n     * offers in its Hello packet. The method works as definied in RFC 6189,\n     * chapter 4.1.2.\n     *\n     * The list of own supported public key algorithms must follow the rules\n     * defined in RFC 6189, chapter 4.1.2, thus the order in the list must go\n     * from fastest to slowest.\n     *\n     * @param hello\n     *    The Hello packet.\n     * @return\n     *    The Enum that identifies the best offered SAS algorithm. Return\n     *    mandatory algorithm if no match was found.\n     */\n    AlgorithmEnum* findBestSASType(ZrtpPacketHello* hello);\n\n    /**\n     * Find the best authentication length that is offered in Hello.\n     *\n     * Find the best, that is the strongest, authentication length that our peer\n     * offers in its Hello packet.\n     *\n     * @param hello\n     *    The Hello packet.\n     * @return\n     *    The Enum that identifies the best offered authentication length. Return\n     *    mandatory algorithm if no match was found.\n     */\n    AlgorithmEnum* findBestAuthLen(ZrtpPacketHello* hello);\n\n    /**\n     * Check if MultiStream mode is offered in Hello.\n     *\n     * Find the best, that is the strongest, authentication length that our peer\n     * offers in its Hello packet.\n     *\n     * @param hello\n     *    The Hello packet.\n     * @return\n     *    True if multi stream mode is available, false otherwise.\n     */\n    bool checkMultiStream(ZrtpPacketHello* hello);\n\n    /**\n     * Checks if Hello packet contains a strong (384bit) hash based on selection policy.\n     * \n     * The function currently implements the nonNist policy only:\n     * If the public key algorithm is a non-NIST ECC algorithm this function prefers\n     * non-NIST HASH algorithms (Skein etc).\n     * \n     * If Hello packet does not contain a strong hash then this functions returns @c NULL.\n     *\n     * @param hello The Hello packet.\n     * @param algoName name of selected PK algorithm\n     * @return @c hash algorithm if found in Hello packet, @c NULL otherwise.\n     */\n    AlgorithmEnum* getStrongHashOffered(ZrtpPacketHello *hello, int32_t algoName);\n\n    /**\n     * Checks if Hello packet offers a strong (256bit) symmetric cipher based on selection policy.\n     *\n     * The function currently implements the nonNist policy only:\n     * If the public key algorithm is a non-NIST ECC algorithm this function prefers\n     * non-NIST symmetric cipher algorithms (Twofish etc).\n     *\n     * If Hello packet does not contain a symmetric cipher then this functions returns @c NULL.\n\n     * @param hello The Hello packet.\n     * @param algoName name of selected PK algorithm\n     * @return @c hash algorithm if found in Hello packet, @c NULL otherwise.\n     *\n     * @return @c cipher algorithm if found in Hello packet, @c NULL otherwise.\n     */\n    AlgorithmEnum* getStrongCipherOffered(ZrtpPacketHello *hello, int32_t algoName);\n\n    /**\n     * Checks if Hello packet contains a hash based on selection policy.\n     *\n     * The function currently implements the nonNist policy only:\n     * If the public key algorithm is a non-NIST ECC algorithm this function prefers\n     * non-NIST HASH algorithms (Skein etc).\n     *\n     * @param hello The Hello packet.\n     * @param algoName name of selected PK algorithm\n     * @return @c hash algorithm found in Hello packet.\n     */\n    AlgorithmEnum* getHashOffered(ZrtpPacketHello *hello, int32_t algoName);\n\n    /**\n     * Checks if Hello packet offers a symmetric cipher based on selection policy.\n     *\n     * The function currently implements the nonNist policy only:\n     * If the public key algorithm is a non-NIST ECC algorithm this function prefers\n     * non-NIST symmetric cipher algorithms (Twofish etc).\n     *\n     * @param hello The Hello packet.\n     * @param algoName name of selected PK algorithm\n     * @return non-NIST @c cipher algorithm if found in Hello packet, @c NULL otherwise\n     */\n    AlgorithmEnum* getCipherOffered(ZrtpPacketHello *hello, int32_t algoName);\n\n    /**\n     * Checks if Hello packet offers a SRTP authentication length based on selection policy.\n     *\n     * The function currently implements the nonNist policy only:\n     * If the public key algorithm is a non-NIST ECC algorithm this function prefers\n     * non-NIST algorithms (Skein etc).\n     *\n     * @param hello The Hello packet.\n     * @param algoName algoName name of selected PK algorithm\n     * @return @c authLen algorithm found in Hello packet\n     */\n    AlgorithmEnum* getAuthLenOffered(ZrtpPacketHello *hello, int32_t algoName);\n\n    /**\n     * Save the computed MitM secret to the ZID record of the peer\n     */\n    void writeEnrollmentPBX();\n\n    /**\n     * Compute my hvi value according to ZRTP specification.\n     */\n    void computeHvi(ZrtpPacketDHPart* dh, ZrtpPacketHello *hello);\n\n    void computeSharedSecretSet(ZIDRecord *zidRec);\n\n    void computeAuxSecretIds();\n\n    void computeSRTPKeys();\n\n    void KDF(uint8_t* key, uint32_t keyLength, uint8_t* label, int32_t labelLength,\n               uint8_t* context, int32_t contextLength, int32_t L, uint8_t* output);\n\n    void generateKeysInitiator(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec);\n\n    void generateKeysResponder(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec);\n\n    void generateKeysMultiStream();\n\n    void computePBXSecret();\n\n    void setNegotiatedHash(AlgorithmEnum* hash);\n\n    /*\n     * The following methods are helper functions for ZrtpStateClass.\n     * ZrtpStateClass calls them to prepare packets, send data, report\n     * problems, etc.\n     */\n    /**\n     * Send a ZRTP packet.\n     *\n     * The state engines calls this method to send a packet via the RTP\n     * stack.\n     *\n     * @param packet\n     *    Points to the ZRTP packet.\n     * @return\n     *    zero if sending failed, one if packet was send\n     */\n    int32_t sendPacketZRTP(ZrtpPacketBase *packet);\n\n    /**\n     * Activate a Timer using the host callback.\n     *\n     * @param tm\n     *    The time in milliseconds.\n     * @return\n     *    zero if activation failed, one if timer was activated\n     */\n    int32_t activateTimer(int32_t tm);\n\n    /**\n     * Cancel the active Timer using the host callback.\n     *\n     * @return\n     *    zero if activation failed, one if timer was activated\n     */\n    int32_t cancelTimer();\n\n    /**\n     * Prepare a Hello packet.\n     *\n     * Just take the preinitialized Hello packet and return it. No\n     * further processing required.\n     *\n     * @return\n     *    A pointer to the initialized Hello packet.\n     */\n    ZrtpPacketHello* prepareHello();\n\n    /**\n     * Prepare a HelloAck packet.\n     *\n     * Just take the preinitialized HelloAck packet and return it. No\n     * further processing required.\n     *\n     * @return\n     *    A pointer to the initialized HelloAck packet.\n     */\n    ZrtpPacketHelloAck* prepareHelloAck();\n\n    /**\n     * Prepare a Commit packet.\n     *\n     * We have received a Hello packet from our peer. Check the offers\n     * it makes to us and select the most appropriate. Using the\n     * selected values prepare a Commit packet and return it to protocol\n     * state engine.\n     *\n     * @param hello\n     *    Points to the received Hello packet\n     * @param errMsg\n     *    Points to an integer that can hold a ZRTP error code.\n     * @return\n     *    A pointer to the prepared Commit packet\n     */\n    ZrtpPacketCommit* prepareCommit(ZrtpPacketHello *hello, uint32_t* errMsg);\n\n    /**\n     * Prepare a Commit packet for Multi Stream mode.\n     *\n     * Using the selected values prepare a Commit packet and return it to protocol\n     * state engine.\n     *\n     * @param hello\n     *    Points to the received Hello packet\n     * @return\n     *    A pointer to the prepared Commit packet for multi stream mode\n     */\n    ZrtpPacketCommit* prepareCommitMultiStream(ZrtpPacketHello *hello);\n\n    /**\n     * Prepare the DHPart1 packet.\n     *\n     * This method prepares a DHPart1 packet. The input to the method is always\n     * a Commit packet received from the peer. Also we a in the role of the\n     * Responder.\n     *\n     * When we receive a Commit packet we get the selected ciphers, hashes, etc\n     * and cross-check if this is ok. Then we need to initialize a set of DH\n     * keys according to the selected cipher. Using this data we prepare our DHPart1\n     * packet.\n     */\n    ZrtpPacketDHPart* prepareDHPart1(ZrtpPacketCommit *commit, uint32_t* errMsg);\n\n    /**\n     * Prepare the DHPart2 packet.\n     *\n     * This method prepares a DHPart2 packet. The input to the method is always\n     * a DHPart1 packet received from the peer. Our peer sends the DH1Part as\n     * response to our Commit packet. Thus we are in the role of the\n     * Initiator.\n     *\n     */\n    ZrtpPacketDHPart* prepareDHPart2(ZrtpPacketDHPart* dhPart1, uint32_t* errMsg);\n\n    /**\n     * Prepare the Confirm1 packet.\n     *\n     * This method prepare the Confirm1 packet. The input to this method is the\n     * DHPart2 packect received from our peer. The peer sends the DHPart2 packet\n     * as response of our DHPart1. Here we are in the role of the Responder\n     *\n     */\n    ZrtpPacketConfirm* prepareConfirm1(ZrtpPacketDHPart* dhPart2, uint32_t* errMsg);\n\n    /**\n     * Prepare the Confirm1 packet in multi stream mode.\n     *\n     * This method prepares the Confirm1 packet. The state engine call this method\n     * if multi stream mode is selected and a Commit packet was received. The input to\n     * this method is the Commit.\n     * Here we are in the role of the Responder\n     *\n     */\n    ZrtpPacketConfirm* prepareConfirm1MultiStream(ZrtpPacketCommit* commit, uint32_t* errMsg);\n\n    /**\n     * Prepare the Confirm2 packet.\n     *\n     * This method prepare the Confirm2 packet. The input to this method is the\n     * Confirm1 packet received from our peer. The peer sends the Confirm1 packet\n     * as response of our DHPart2. Here we are in the role of the Initiator\n     */\n    ZrtpPacketConfirm* prepareConfirm2(ZrtpPacketConfirm* confirm1, uint32_t* errMsg);\n\n    /**\n     * Prepare the Confirm2 packet in multi stream mode.\n     *\n     * This method prepares the Confirm2 packet. The state engine call this method if\n     * multi stream mode is active and in state CommitSent. The input to this method is\n     * the Confirm1 packet received from our peer. The peer sends the Confirm1 packet\n     * as response of our Commit packet in multi stream mode.\n     * Here we are in the role of the Initiator\n     */\n    ZrtpPacketConfirm* prepareConfirm2MultiStream(ZrtpPacketConfirm* confirm1, uint32_t* errMsg);\n\n    /**\n     * Prepare the Conf2Ack packet.\n     *\n     * This method prepare the Conf2Ack packet. The input to this method is the\n     * Confirm2 packet received from our peer. The peer sends the Confirm2 packet\n     * as response of our Confirm1. Here we are in the role of the Initiator\n     */\n    ZrtpPacketConf2Ack* prepareConf2Ack(ZrtpPacketConfirm* confirm2, uint32_t* errMsg);\n\n    /**\n     * Prepare the ErrorAck packet.\n     *\n     * This method prepares the ErrorAck packet. The input to this method is the\n     * Error packet received from the peer.\n     */\n    ZrtpPacketErrorAck* prepareErrorAck(ZrtpPacketError* epkt);\n\n    /**\n     * Prepare the Error packet.\n     *\n     * This method prepares the Error packet. The input to this method is the\n     * error code to be included into the message.\n     */\n    ZrtpPacketError* prepareError(uint32_t errMsg);\n\n    /**\n     * Prepare a ClearAck packet.\n     *\n     * This method checks if the GoClear message is valid. If yes then switch\n     * off SRTP processing, stop sending of RTP packets (pause transmit) and\n     * inform the user about the fact. Only if user confirms the GoClear message\n     * normal RTP processing is resumed.\n     *\n     * @return\n     *     NULL if GoClear could not be authenticated, a ClearAck packet\n     *     otherwise.\n     */\n    ZrtpPacketClearAck* prepareClearAck(ZrtpPacketGoClear* gpkt);\n\n    /**\n     * Prepare the ErrorAck packet.\n     *\n     * This method prepares the ErrorAck packet. The input to this method is the\n     * Error packet received from the peer.\n     */\n    ZrtpPacketPingAck* preparePingAck(ZrtpPacketPing* ppkt);\n\n    /**\n     * Prepare the RelayAck packet.\n     *\n     * This method prepares the RelayAck packet. The input to this method is the\n     * SASrelay packet received from the peer.\n     */\n    ZrtpPacketRelayAck* prepareRelayAck(ZrtpPacketSASrelay* srly, uint32_t* errMsg);\n    \n    /**\n     * Prepare a GoClearAck packet w/o HMAC\n     *\n     * Prepare a GoCLear packet without a HMAC but with a short error message.\n     * This type of GoClear is used if something went wrong during the ZRTP\n     * negotiation phase.\n     *\n     * @return\n     *     A goClear packet without HMAC\n     */\n    ZrtpPacketGoClear* prepareGoClear(uint32_t errMsg = 0);\n\n    /**\n     * Compare the hvi values.\n     *\n     * Compare a received Commit packet with our Commit packet and returns\n     * which Commit packt is \"more important\". See chapter 5.2 to get further\n     * information how to compare Commit packets.\n     *\n     * @param commit\n     *    Pointer to the peer's commit packet we just received.\n     * @return\n     *    <0 if our Commit packet is \"less important\"\n     *    >0 if our Commit is \"more important\"\n     *     0 shouldn't happen because we compare crypto hashes\n     */\n    int32_t compareCommit(ZrtpPacketCommit *commit);\n\n    /**\n     * Verify the H2 hash image.\n     *\n     * Verifies the H2 hash contained in a received commit message.\n     * This functions just verifies H2 but does not store it.\n     *\n     * @param commit\n     *    Pointer to the peer's commit packet we just received.\n     * @return\n     *    true if H2 is ok and verified\n     *    false if H2 could not be verified\n     */\n    bool verifyH2(ZrtpPacketCommit *commit);\n\n    /**\n     * Send information messages to the hosting environment.\n     *\n     * The ZRTP implementation uses this method to send information messages\n     * to the host. Along with the message ZRTP provides a severity indicator\n     * that defines: Info, Warning, Error, Alert. Refer to the MessageSeverity\n     * enum in the ZrtpCallback class.\n     *\n     * @param severity\n     *     This defines the message's severity\n     * @param subCode\n     *     The subcode identifying the reason.\n     * @see ZrtpCodes#MessageSeverity\n     */\n    void sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode);\n\n    /**\n     * ZRTP state engine calls this if the negotiation failed.\n     *\n     * ZRTP calls this method in case ZRTP negotiation failed. The parameters\n     * show the severity as well as some explanatory text.\n     *\n     * @param severity\n     *     This defines the message's severity\n     * @param subCode\n     *     The subcode identifying the reason.\n     * @see ZrtpCodes#MessageSeverity\n     */\n    void zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity, int32_t subCode);\n\n    /**\n     * ZRTP state engine calls this method if the other side does not support ZRTP.\n     *\n     * If the other side does not answer the ZRTP <em>Hello</em> packets then\n     * ZRTP calls this method,\n     *\n     */\n    void zrtpNotSuppOther();\n\n    /**\n     * Signal SRTP secrets are ready.\n     *\n     * This method calls a callback method to inform the host that the SRTP\n     * secrets are ready.\n     *\n     * @param part\n     *    Defines for which part (sender or receiver) to switch on security\n     * @return\n     *    Returns false if something went wrong during initialization of SRTP\n     *    context. Propagate error back to state engine.\n     */\n    bool srtpSecretsReady(EnableSecurity part);\n\n    /**\n     * Switch off SRTP secrets.\n     *\n     * This method calls a callback method to inform the host that the SRTP\n     * secrets shall be cleared.\n     *\n     * @param part\n     *    Defines for which part (sender or receiver) to clear\n     */\n    void srtpSecretsOff(EnableSecurity part);\n\n    /**\n     * ZRTP state engine calls these methods to enter or leave its\n     * synchronization mutex.\n     */\n    void synchEnter();\n\n    void synchLeave();\n\n    /**\n     * Helper function to store ZRTP message data in a temporary buffer\n     *\n     * This functions first clears the temporary buffer, then stores\n     * the packet's data to it. We use this to check the packet's HMAC\n     * after we received the HMAC key in to following packet.\n     *\n     * @param data\n     *    Pointer to the packet's ZRTP message\n    */\n     void storeMsgTemp(ZrtpPacketBase* pkt);\n\n     /**\n      * Helper function to check a ZRTP message HMAC\n      *\n      * This function gets a HMAC key and uses it to compute a HMAC\n      * with this key and the stored data of a previous received ZRTP\n      * message. It compares the computed HMAC and the HMAC stored in\n      * the received message and returns the result.\n      *\n      * @param key\n      *    Pointer to the HMAC key.\n      * @return\n      *    Returns true if the computed HMAC and the stored HMAC match,\n      *    false otherwise.\n      */\n     bool checkMsgHmac(uint8_t* key);\n\n     /**\n      * Set the client ID for ZRTP Hello message.\n      *\n      * The user of ZRTP must set its id to identify itself in the\n      * ZRTP HELLO message. The maximum length is 16 characters. Shorter\n      * id string are allowed, they will be filled with blanks. A longer id\n      * is truncated to 16 characters.\n      *\n      * The identifier is set in the Hello packet of ZRTP. Thus only after\n      * setting the identifier ZRTP can compute the HMAC and the final\n      * helloHash.\n      *\n      * @param id\n      *     The client's id\n      * @param hpv\n      *     Pointer to hello packet version structure.\n      */\n     void setClientId(std::string id, HelloPacketVersion* hpv);\n     \n     /**\n      * Check and set a nonce.\n      * \n      * The function first checks if the nonce is already in use (was seen) in this ZRTP\n      * session. Refer to 4.4.3.1.\n      * \n      * @param nonce\n      *     The nonce to check and to store if not already seen.\n      * \n      * @return\n      *     True if the the nonce was stroed, thus not yet seen.\n      */\n     bool checkAndSetNonce(uint8_t* nonce);\n};\n\n/**\n * @}\n */\n#endif // ZRTP\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpCWrapper.h",
    "content": "/*\n    This file defines the GNU ZRTP C-to-C++ wrapper.\n    Copyright (C) 2013  Werner Dittmann\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU Lesser General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n*/\n\n#ifndef ZRTPCWRAPPER_H\n#define ZRTPCWRAPPER_H\n\n/**\n *\n * @file ZrtpCWrapper.h\n * @brief The GNU ZRTP C-to-C++ wrapper.\n *\n * To avoid any include of C++ header files some structure, defines, and\n * enumerations are repeated in this file. Refer to the inline comments if\n * you modify the file.\n *\n * @ingroup GNU_ZRTP\n * @{\n *\n * @see ZRtp\n */\n\n#include <stdint.h>\n\n/**\n * Defines to specify the role a ZRTP peer has.\n *\n * According to the ZRTP specification the role determines which keys to\n * use to encrypt or decrypt SRTP data.\n *\n * <ul>\n * <li> The Initiator encrypts SRTP data using the <em>keyInitiator</em> and the\n *      <em>saltInitiator</em> data, the Responder uses these data to decrypt.\n * </li>\n * <li> The Responder encrypts SRTP data using the <em>keyResponder</em> and the\n *      <em>saltResponder</em> data, the Initiator uses these data to decrypt.\n * </li>\n * </ul>\n */\n/*\n * Keep the following defines in sync with Role enumeration in ZrtpCallback.h\n */\n#define Responder 1             /*!< This client is in ZRTP Responder mode */\n#define Initiator 2             /*!< This client is in ZRTP Initiator mode */\n\n#define CRC_SIZE  4             /*!< Size of CRC code of a ZRTP packet */\n#define ZRTP_MAGIC 0x5a525450   /*!< The magic code that identifies a ZRTP packet */\n#define MAX_ZRTP_SIZE 3072      /*!< The biggest ZRTP packet ever possible */\n\n/*\n * IMPORTANT: keep the following enums in synch with ZrtpCodes. We copy them here\n * to avoid any C++ header includes and defines. The protocol states are located\n * ZrtpStateClass.h .\n */\n/**\n * This enum defines the information message severity.\n *\n * The ZRTP implementation issues information messages to inform the user\n * about ongoing processing, unusual behavior, or alerts in case of severe\n * problems. Each main severity code a number of sub-codes exist that\n * specify the exact nature of the problem.\n *\n * An application gets message severity codes and the associated sub-codes\n * via the ZrtpUserCallback#showMessage method.\n *\n * The severity levels and their meaning are:\n *\n * <dl>\n * <dt>Info</dt> <dd>keeps the user informed about ongoing processing and\n *     security setup. The enumeration InfoCodes defines the subcodes.\n * </dd>\n * <dt>Warning</dt> <dd>is an information about some security issues, e.g. if\n *     an AES 256 encryption is request but only DH 3072 as public key scheme\n *     is supported. ZRTP will establish a secure session (SRTP). The\n *     enumeration WarningCodes defines the sub-codes.\n * </dd>\n * <dt>Severe</dt> <dd>is used if an error occured during ZRTP protocol usage.\n *     In case of <em>Severe</em> ZRTP will <b>not</b> establish a secure session.\n *     The enumeration SevereCodes defines the sub-codes.\n * </dd>\n * <dt>Zrtp</dt> <dd>shows a ZRTP security problem. Refer to the enumeration\n *     ZrtpErrorCodes for sub-codes. GNU ZRTP of course will <b>not</b>\n *     establish a secure session.\n * </dd>\n * </dl>\n *\n */\nenum zrtp_MessageSeverity {\n    zrtp_Info = 1,                      /*!< Just an info message */\n    zrtp_Warning,                       /*!< A Warning message - security can be established */\n    zrtp_Severe,                        /*!< Severe error, security will not be established */\n    zrtp_ZrtpError                      /*!< ZRTP error, security will not be established  */\n};\n\n/**\n * Sub-codes for Info\n */\nenum zrtp_InfoCodes {\n    zrtp_InfoHelloReceived = 1,          /*!< Hello received, preparing a Commit */\n    zrtp_InfoCommitDHGenerated,          /*!< Commit: Generated a public DH key */\n    zrtp_InfoRespCommitReceived,         /*!< Responder: Commit received, preparing DHPart1 */\n    zrtp_InfoDH1DHGenerated,             /*!< DH1Part: Generated a public DH key */\n    zrtp_InfoInitDH1Received,            /*!< Initiator: DHPart1 received, preparing DHPart2 */\n    zrtp_InfoRespDH2Received,            /*!< Responder: DHPart2 received, preparing Confirm1 */\n    zrtp_InfoInitConf1Received,          /*!< Initiator: Confirm1 received, preparing Confirm2 */\n    zrtp_InfoRespConf2Received,          /*!< Responder: Confirm2 received, preparing Conf2Ack */\n    zrtp_InfoRSMatchFound,               /*!< At least one retained secrets matches - security OK */\n    zrtp_InfoSecureStateOn,              /*!< Entered secure state */\n    zrtp_InfoSecureStateOff              /*!< No more security for this session */\n};\n\n/**\n * Sub-codes for Warning\n */\nenum zrtp_WarningCodes {\n    zrtp_WarningDHAESmismatch = 1,       /*!< Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096 */\n    zrtp_WarningGoClearReceived,         /*!< Received a GoClear message */\n    zrtp_WarningDHShort,                 /*!< Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096 */\n    zrtp_WarningNoRSMatch,               /*!< No retained shared secrets available - must verify SAS */\n    zrtp_WarningCRCmismatch,             /*!< Internal ZRTP packet checksum mismatch - packet dropped */\n    zrtp_WarningSRTPauthError,           /*!< Dropping packet because SRTP authentication failed! */\n    zrtp_WarningSRTPreplayError,         /*!< Dropping packet because SRTP replay check failed! */\n    zrtp_WarningNoExpectedRSMatch        /*!< Valid retained shared secrets availabe but no matches found - must verify SAS */\n};\n\n/**\n * Sub-codes for Severe\n */\nenum zrtp_SevereCodes {\n    zrtp_SevereHelloHMACFailed = 1,      /*!< Hash HMAC check of Hello failed! */\n    zrtp_SevereCommitHMACFailed,         /*!< Hash HMAC check of Commit failed! */\n    zrtp_SevereDH1HMACFailed,            /*!< Hash HMAC check of DHPart1 failed! */\n    zrtp_SevereDH2HMACFailed,            /*!< Hash HMAC check of DHPart2 failed! */\n    zrtp_SevereCannotSend,               /*!< Cannot send data - connection or peer down? */\n    zrtp_SevereProtocolError,            /*!< Internal protocol error occured! */\n    zrtp_SevereNoTimer,                  /*!< Cannot start a timer - internal resources exhausted? */\n    zrtp_SevereTooMuchRetries            /*!< Too much retries during ZRTP negotiation - connection or peer down? */\n};\n\n/**\n  * Error codes according to the ZRTP specification chapter 6.9\n  *\n  * GNU ZRTP uses these error codes in two ways: to fill the appropriate\n  * field ing the ZRTP Error packet and as sub-code in\n  * ZrtpUserCallback#showMessage(). GNU ZRTP uses thes error codes also\n  * to report received Error packts, in this case the sub-codes are their\n  * negative values.\n  *\n  * The enumeration member comments are copied from the ZRTP specification.\n  */\nenum zrtp_ZrtpErrorCodes {\n    zrtp_MalformedPacket =   0x10,    /*!< Malformed packet (CRC OK, but wrong structure) */\n    zrtp_CriticalSWError =   0x20,    /*!< Critical software error */\n    zrtp_UnsuppZRTPVersion = 0x30,    /*!< Unsupported ZRTP version */\n    zrtp_HelloCompMismatch = 0x40,    /*!< Hello components mismatch */\n    zrtp_UnsuppHashType =    0x51,    /*!< Hash type not supported */\n    zrtp_UnsuppCiphertype =  0x52,    /*!< Cipher type not supported */\n    zrtp_UnsuppPKExchange =  0x53,    /*!< Public key exchange not supported */\n    zrtp_UnsuppSRTPAuthTag = 0x54,    /*!< SRTP auth. tag not supported */\n    zrtp_UnsuppSASScheme =   0x55,    /*!< SAS scheme not supported */\n    zrtp_NoSharedSecret =    0x56,    /*!< No shared secret available, DH mode required */\n    zrtp_DHErrorWrongPV =    0x61,    /*!< DH Error: bad pvi or pvr ( == 1, 0, or p-1) */\n    zrtp_DHErrorWrongHVI =   0x62,    /*!< DH Error: hvi != hashed data */\n    zrtp_SASuntrustedMiTM =  0x63,    /*!< Received relayed SAS from untrusted MiTM */\n    zrtp_ConfirmHMACWrong =  0x70,    /*!< Auth. Error: Bad Confirm pkt HMAC */\n    zrtp_NonceReused =       0x80,    /*!< Nonce reuse */\n    zrtp_EqualZIDHello =     0x90,    /*!< Equal ZIDs in Hello */\n    zrtp_GoCleatNotAllowed = 0x100,   /*!< GoClear packet received, but not allowed */\n    zrtp_IgnorePacket =      0x7fffffff /*!< Internal state, not reported */\n};\n\n/**\n * Information codes for the Enrollment user callbacks.\n */\nenum zrtp_InfoEnrollment {\n    zrtp_EnrollmentRequest,              //!< Aks user to confirm or deny an Enrollemnt request\n    zrtp_EnrollmentCanceled,             //!< User did not confirm the PBX enrollement\n    zrtp_EnrollmentFailed,               //!< Enrollment process failed, no PBX secret available\n    zrtp_EnrollmentOk                    //!< Enrollment process for this PBX was ok\n};\n\n/* The ZRTP protocol states */\nenum zrtpStates {\n    Initial,            /*!< Initial state after starting the state engine */\n    Detect,             /*!< State sending Hello, try to detect answer message */\n    AckDetected,        /*!< HelloAck received */\n    AckSent,            /*!< HelloAck sent after Hello received */\n    WaitCommit,         /*!< Wait for a Commit message */\n    CommitSent,         /*!< Commit message sent */\n    WaitDHPart2,        /*!< Wait for a DHPart2 message */\n    WaitConfirm1,       /*!< Wait for a Confirm1 message */\n    WaitConfirm2,       /*!< Wait for a confirm2 message */\n    WaitConfAck,        /*!< Wait for Conf2Ack */\n    WaitClearAck,       /*!< Wait for clearAck - not used */\n    SecureState,        /*!< This is the secure state - SRTP active */\n    WaitErrorAck,       /*!< Wait for ErrorAck message */\n    numberOfStates      /*!< Gives total number of protocol states */\n};\n\n/*! The algorihms that we support in SRTP and that ZRTP can negotiate. */\ntypedef enum {\n    zrtp_Aes = 1,        /*!< Use AES as symmetrical cipher algorithm */\n    zrtp_TwoFish,        /*!< Use TwoFish as symmetrical cipher algorithm */\n    zrtp_Sha1,           /*!< Use Sha1 as authentication algorithm */\n    zrtp_Skein           /*!< Use Skein as authentication algorithm */\n} zrtp_SrtpAlgorithms;\n\n/**\n * This structure contains pointers to the SRTP secrets and the role info.\n *\n * About the role and what the meaning of the role is refer to the\n * of the enum Role. The pointers to the secrets are valid as long as\n * the ZRtp object is active. To use these data after the ZRtp object's\n * lifetime you may copy the data into a save place.\n */\ntypedef struct c_srtpSecrets\n{\n    zrtp_SrtpAlgorithms symEncAlgorithm;/*!< symmetrical cipher algorithm */\n    const uint8_t* keyInitiator;        /*!< Initiator's key */\n    int32_t initKeyLen;                 /*!< Initiator's key length */\n    const uint8_t* saltInitiator;       /*!< Initiator's salt */\n    int32_t initSaltLen;                /*!< Initiator's salt length */\n    const uint8_t* keyResponder;        /*!< Responder's key */\n    int32_t respKeyLen;                 /*!< Responder's key length */\n    const uint8_t* saltResponder;       /*!< Responder's salt */\n    int32_t respSaltLen;                /*!< Responder's salt length */\n    zrtp_SrtpAlgorithms authAlgorithm;  /*!< SRTP authentication algorithm */\n    int32_t srtpAuthTagLen;             /*!< SRTP authentication length */\n    char* sas;                          /*!< The SAS string */\n    int32_t  role;                      /*!< ZRTP role of this client */\n} C_SrtpSecret_t;\n\n/*\n * Keep the following defines in sync with enum EnableSecurity in ZrtpCallback.h\n */\n#define ForReceiver 1       /*!< Enable security for SRTP receiver */\n#define ForSender   2       /*!< Enable security for SRTP sender */\n\n#ifdef __cplusplus\n#ifdef __GNUC__ \n#pragma GCC visibility push(default)\n#endif\nextern \"C\"\n{\n    typedef class ZRtp ZRtp;\n    typedef class ZrtpCallbackWrapper ZrtpCallbackWrapper;\n    typedef class ZrtpConfigure ZrtpConfigure;\n#else\n    typedef struct ZRtp ZRtp;\n    typedef struct ZrtpCallbackWrapper ZrtpCallbackWrapper;\n    typedef struct ZrtpConfigure ZrtpConfigure;\n#endif\n\n    typedef struct zrtpContext\n    {\n        ZRtp* zrtpEngine;                   /*!< Holds the real ZRTP engine */\n        ZrtpCallbackWrapper* zrtpCallback;  /*!< Help class Callback wrapper */\n        ZrtpConfigure* configure;           /*!< Optional configuration data */\n        ZRtp* zrtpMaster;                   /*!< Holds the master ZRTP stream in case this is a multi-stream */\n        void* userData;                     /*!< User data, set by application */\n    } ZrtpContext;\n\n    /**\n    * This structure defines the callback functions required by GNU ZRTP.\n    *\n    * The RTP stack specific part must implement the callback methods.\n    * The generic part of GNU ZRTP uses these mehtods\n    * to communicate with the specific part, for example to send data\n    * via the RTP/SRTP stack, to set timers and cancel timer and so on.\n    *\n    * The generiy part of GNU ZRTP needs only a few callback methods to\n    * be implemented by the specific part.\n    *\n    * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n    */\n\n    /**\n     * The following methods define the GNU ZRTP callback interface.\n     * For detailed documentation refer to file ZrtpCallback.h, each C\n     * method has \"zrtp_\" prepended to the C++ name.\n     *\n     * @see ZrtpCallback\n     */\n    typedef struct zrtp_Callbacks\n    {\n        /**\n        * Send a ZRTP packet via RTP.\n        *\n        * ZRTP calls this method to send a ZRTP packet via the RTP session.\n        * The ZRTP packet will have to be created using the provided ZRTP message.\n        *\n        * @param ctx\n        *    Pointer to the opaque ZrtpContext structure.\n        * @param data\n        *    Points to ZRTP message to send.\n        * @param length\n        *    The length in bytes of the data\n        * @return\n        *    zero if sending failed, one if packet was sent\n        */\n        int32_t (*zrtp_sendDataZRTP) (ZrtpContext* ctx, const uint8_t* data, int32_t length ) ;\n\n        /**\n        * Activate timer.\n        *\n        * @param ctx\n        *    Pointer to the opaque ZrtpContext structure.\n        * @param time\n        *    The time in ms for the timer\n        * @return\n        *    zero if activation failed, one if timer was activated\n        */\n        int32_t (*zrtp_activateTimer) (ZrtpContext* ctx, int32_t time ) ;\n\n        /**\n        * Cancel the active timer.\n        *\n        * @param ctx\n        *    Pointer to the opaque ZrtpContext structure.\n        * @return\n        *    zero if cancel action failed, one if timer was canceled\n        */\n        int32_t (*zrtp_cancelTimer)(ZrtpContext* ctx) ;\n\n        /**\n        * Send information messages to the hosting environment.\n        *\n        * The ZRTP implementation uses this method to send information\n        * messages to the host. Along with the message ZRTP provides a\n        * severity indicator that defines: Info, Warning, Error,\n        * Alert. Refer to the <code>MessageSeverity</code> enum above.\n        *\n        * @param ctx\n        *    Pointer to the opaque ZrtpContext structure.\n        * @param severity\n        *     This defines the message's severity\n        * @param subCode\n        *     The subcode identifying the reason.\n        * @see ZrtpCodes#MessageSeverity\n        */\n        void (*zrtp_sendInfo) (ZrtpContext* ctx, int32_t severity, int32_t subCode ) ;\n\n        /**\n         * SRTP crypto data ready for the sender or receiver.\n         *\n         * The ZRTP implementation calls this method right after all SRTP\n         * secrets are computed and ready to be used. The parameter points\n         * to a structure that contains pointers to the SRTP secrets and a\n         * <code>enum Role</code>. The called method (the implementation\n         * of this abstract method) must either copy the pointers to the SRTP\n         * data or the SRTP data itself to a save place. The SrtpSecret_t\n         * structure is destroyed after the callback method returns to the\n         * ZRTP implementation.\n         *\n         * The SRTP data themselves are obtained in the ZRtp object and are\n         * valid as long as the ZRtp object is active. TheZRtp's\n         * destructor clears the secrets. Thus the called method needs to\n         * save the pointers only, ZRtp takes care of the data.\n         *\n         * The implementing class may enable SRTP processing in this\n         * method or delay it to srtpSecertsOn().\n         *\n         * @param ctx\n         *    Pointer to the opaque ZrtpContext structure.\n         * @param secrets A pointer to a SrtpSecret_t structure that\n         *     contains all necessary data.\n         *\n         * @param part for which part (Sender or Receiver) this data is\n         *     valid.\n         *\n         * @return Returns false if something went wrong during\n         *    initialization of SRTP context, for example memory shortage.\n         */\n        int32_t (*zrtp_srtpSecretsReady) (ZrtpContext* ctx, C_SrtpSecret_t* secrets, int32_t part ) ;\n\n        /**\n         * Switch off the security for the defined part.\n         *\n         * @param ctx\n         *    Pointer to the opaque ZrtpContext structure.\n         * @param part Defines for which part (sender or receiver) to\n         *    switch on security\n         */\n        void (*zrtp_srtpSecretsOff) (ZrtpContext* ctx, int32_t part ) ;\n\n        /**\n         * Switch on the security.\n         *\n         * ZRTP calls this method after it has computed the SAS and check\n         * if it is verified or not. In addition ZRTP provides information\n         * about the cipher algorithm and key length for the SRTP session.\n         *\n         * This method must enable SRTP processing if it was not enabled\n         * during sertSecretsReady().\n         *\n         * @param ctx\n         *    Pointer to the opaque ZrtpContext structure.\n         * @param c The name of the used cipher algorithm and mode, or\n         *    NULL\n         *\n         * @param s The SAS string\n         *\n         * @param verified if <code>verified</code> is true then SAS was\n         *    verified by both parties during a previous call.\n         */\n        void (*zrtp_rtpSecretsOn) (ZrtpContext* ctx, char* c, char* s, int32_t verified ) ;\n\n        /**\n         * This method handles GoClear requests.\n         *\n         * According to the ZRTP specification the user must be informed about\n         * a GoClear request because the ZRTP implementation switches off security\n         * if it could authenticate the GoClear packet.\n         *\n         * <b>Note:</b> GoClear is not yet implemented in GNU ZRTP.\n         *\n         * @param ctx\n         *    Pointer to the opaque ZrtpContext structure.\n         */\n        void (*zrtp_handleGoClear)(ZrtpContext* ctx) ;\n\n        /**\n         * Handle ZRTP negotiation failed.\n         *\n         * ZRTP calls this method in case ZRTP negotiation failed. The\n         * parameters show the severity as well as the reason.\n         *\n         * @param ctx\n         *    Pointer to the opaque ZrtpContext structure.\n         * @param severity\n         *     This defines the message's severity\n         * @param subCode\n         *     The subcode identifying the reason.\n         * @see ZrtpCodes#MessageSeverity\n         */\n        void (*zrtp_zrtpNegotiationFailed) (ZrtpContext* ctx, int32_t severity, int32_t subCode ) ;\n\n        /**\n         * ZRTP calls this method if the other side does not support ZRTP.\n         *\n         * @param ctx\n         *    Pointer to the opaque ZrtpContext structure.\n         * If the other side does not answer the ZRTP <em>Hello</em> packets then\n         * ZRTP calls this method,\n         *\n         */\n        void (*zrtp_zrtpNotSuppOther)(ZrtpContext* ctx) ;\n\n        /**\n         * Enter synchronization mutex.\n         *\n         * GNU ZRTP requires one mutex to synchronize its\n         * processing. Because mutex implementations depend on the\n         * underlying infrastructure, for example operating system or\n         * thread implementation, GNU ZRTP delegates mutex handling to the\n         * specific part of its implementation.\n         *\n         * @param ctx\n         *    Pointer to the opaque ZrtpContext structure.\n         */\n        void (*zrtp_synchEnter)(ZrtpContext* ctx) ;\n\n        /**\n         * Leave synchronization mutex.\n         *\n         * @param ctx\n         *    Pointer to the opaque ZrtpContext structure.\n         */\n        void (*zrtp_synchLeave)(ZrtpContext* ctx) ;\n\n        /**\n         * Inform about a PBX enrollment request.\n         *\n         * Please refer to chapter 8.3 ff to get more details about PBX\n         * enrollment and SAS relay.\n         *\n         * <b>Note:</b> PBX enrollement is not yet fully supported by GNU\n         * ZRTP.\n         *\n         * @param ctx\n         *    Pointer to the opaque ZrtpContext structure.\n         * @param info Give some information to the user about the PBX\n         *    requesting an enrollment.\n         */\n        void (*zrtp_zrtpAskEnrollment) (ZrtpContext* ctx, int32_t info) ;\n\n        /**\n         * Inform about PBX enrollment result.\n         *\n         * Informs the use about the acceptance or denial of an PBX enrollment\n         * request\n         *\n         * <b>Note:</b> PBX enrollement is not yet fully supported by GNU\n         * ZRTP.\n         *\n         * @param ctx\n         *    Pointer to the opaque ZrtpContext structure.\n         * @param info Give some information to the user about the result\n         *    of an enrollment.\n         */\n        void (*zrtp_zrtpInformEnrollment) (ZrtpContext* ctx, int32_t info ) ;\n\n        /**\n         * Request a SAS signature.\n         *\n         * After ZRTP was able to compute the Short Authentication String\n         * (SAS) it calls this method. The client may now use an\n         * approriate method to sign the SAS. The client may use\n         * ZrtpQueue#setSignatureData() to store the signature data and\n         * enable signature transmission to the other peer. Refer to\n         * chapter 8.2 of ZRTP specification.\n         *\n         * <b>Note:</b> SAS signing is not yet fully supported by GNU\n         * ZRTP.\n         *\n         * @param ctx\n         *    Pointer to the opaque ZrtpContext structure.\n         * @param sas\n         *    Pointer to the 32 byte SAS hash to sign.\n         *\n         */\n        void (*zrtp_signSAS)(ZrtpContext* ctx, uint8_t* sas) ;\n\n        /**\n         * ZRTPQueue calls this method to request a SAS signature check.\n         *\n         * After ZRTP received a SAS signature in one of the Confirm packets it\n         * call this method. The client may use <code>getSignatureLength()</code>\n         * and <code>getSignatureData()</code>of ZrtpQueue to get the signature\n         * data and perform the signature check. Refer to chapter 8.2 of ZRTP\n         * specification.\n         *\n         * If the signature check fails the client may return false to ZRTP. In\n         * this case ZRTP signals an error to the other peer and terminates\n         * the ZRTP handshake.\n         *\n         * <b>Note:</b> SAS signing is not yet fully supported by GNU\n         * ZRTP.\n         *\n         * @param ctx\n         *    Pointer to the opaque ZrtpContext structure.\n         * @param sas\n         *    Pointer to the 32 byte SAS hash that was signed by the other peer.\n         * @return\n         *    true if the signature was ok, false otherwise.\n         *\n         */\n        int32_t (*zrtp_checkSASSignature) (ZrtpContext* ctx, uint8_t* sas ) ;\n    } zrtp_Callbacks;\n\n    /**\n     * Create the GNU ZRTP C wrapper.\n     *\n     * This wrapper implements the C interface to the C++ based GNU ZRTP.\n     * @returns\n     *      Pointer to the ZrtpContext\n     */\n    ZrtpContext* zrtp_CreateWrapper(void);\n\n    /**\n     * Initialize the ZRTP protocol engine.\n     *\n     * This method initialized the GNU ZRTP protocol engine. An application\n     * calls this method to actually create the ZRTP protocol engine and\n     * initialize its configuration data. This method does not start the\n     * protocol engine.\n     *\n     * If an application requires a specific algorithm configuration then it\n     * must set the algorithm configuration data before it initializes the\n     * ZRTP protocol engine.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param cb\n     *     The callback structure that holds the addresses of the callback\n     *     methods.\n     * @param id\n     *     A C string that holds the ZRTP client id, only the first 16 chars\n     *     are used.\n     * @param zidFilename\n     *     The name of the ZID file. This file holds some parameters and\n     *     other data like additional shared secrets.\n     * @param userData\n     *     A pointer to user data. The wrapper just stores this pointer in\n     *     the ZrtpContext and the application may use it for its purposes.\n     * @param mitmMode\n     *     A trusted Mitm (PBX) must set this to true. The ZRTP engine sets\n     *     the M Flag in the Hello packet to announce a trusted MitM.\n     * @returns\n     *      Pointer to the ZrtpContext\n     *\n     * @see zrtp_InitializeConfig\n     */\n    void zrtp_initializeZrtpEngine(ZrtpContext* zrtpContext,\n                                   zrtp_Callbacks *cb,\n                                   const char* id,\n                                   const char* zidFilename,\n                                   void* userData,\n                                   int32_t mitmMode);\n\n    /**\n     * Destroy the ZRTP wrapper and its underlying objects.\n     */\n    void zrtp_DestroyWrapper (ZrtpContext* zrtpContext);\n\n    /**\n     * Computes the ZRTP checksum over a received ZRTP packet buffer and\n     * compares the result with received checksum.\n     *\n     * @param buffer\n     *    Pointer to ZRTP packet buffer\n     * @param length\n     *    Length of the packet buffer excluding received CRC data\n     * @param crc\n     *    The received CRC data.\n     * @returns\n     *    True if CRC matches, false otherwise.\n     */\n    int32_t zrtp_CheckCksum(uint8_t* buffer, uint16_t length, uint32_t crc);\n\n    /**\n     * Computes the ZRTP checksum over a newly created ZRTP packet buffer.\n     *\n     * @param buffer\n     *    Pointer to the created ZRTP packet buffer\n     * @param length\n     *    Length of the packet buffer\n     * @returns\n     *    The computed CRC.\n     */\n    uint32_t zrtp_GenerateCksum(uint8_t* buffer, uint16_t length);\n\n    /**\n     * Prepares the ZRTP checksum for appending to ZRTP packet.\n     * @param crc\n     *    The computed CRC data.\n     * @returns\n     *    Prepared CRC data in host order\n     */\n    uint32_t zrtp_EndCksum(uint32_t crc);\n\n    /**\n     * Kick off the ZRTP protocol engine.\n     *\n     * This method calls the ZrtpStateClass#evInitial() state of the state\n     * engine. After this call we are able to process ZRTP packets\n     * from our peer and to process them.\n     *\n     * <b>NOTE: application shall never call this method directly but use the\n     * appropriate method provided by the RTP implementation. </b>\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     */\n    void zrtp_startZrtpEngine(ZrtpContext* zrtpContext);\n\n    /**\n     * Stop ZRTP security.\n     *\n     * <b>NOTE: An application shall never call this method directly but use the\n     * appropriate method provided by the RTP implementation. </b>\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     */\n    void zrtp_stopZrtpEngine(ZrtpContext* zrtpContext);\n\n    /**\n     * Process RTP extension header.\n     *\n     * This method expects to get a pointer to the message part of\n     * a ZRTP packet.\n     *\n     * <b>NOTE: An application shall never call this method directly. Only\n     * the module that implements the RTP binding shall use this method</b>\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param extHeader\n     *    A pointer to the first byte of the ZRTP message part.\n     * @param peerSSRC\n     *    The peer's SSRC.\n     * @param length of the received data packet - used to do santity checks.\n     *\n     * @return\n     *    Code indicating further packet handling, see description above.\n     */\n    void zrtp_processZrtpMessage(ZrtpContext* zrtpContext, uint8_t *extHeader, uint32_t peerSSRC, size_t length);\n\n    /**\n     * Process a timeout event.\n     *\n     * We got a timeout from the timeout provider. Forward it to the\n     * protocol state engine.\n     *\n     * <b>NOTE: application shall never call this method directly. Only\n     * the module that implements the RTP binding shall use this method</b>\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     */\n    void zrtp_processTimeout(ZrtpContext* zrtpContext);\n\n    /*\n     * Check for and handle GoClear ZRTP packet header.\n     *\n     * This method checks if this is a GoClear packet. If not, just return\n     * false. Otherwise handle it according to the specification.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param extHeader\n     *    A pointer to the first byte of the extension header. Refer to\n     *    RFC3550.\n     * @return\n     *    False if not a GoClear, true otherwise.\n     *\n    int32_t zrtp_handleGoClear(ZrtpContext* zrtpContext, uint8_t *extHeader);\n    */\n    \n    /**\n     * Set the auxilliary secret.\n     *\n     * Use this method to set the auxilliary secret data. Refer to ZRTP\n     * specification, chapter 4.3 ff\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param data\n     *     Points to the secret data.\n     * @param length\n     *     Length of the auxilliary secrect in bytes\n     */\n    void zrtp_setAuxSecret(ZrtpContext* zrtpContext, uint8_t* data, int32_t length);\n\n    /**\n     * Check current state of the ZRTP state engine\n     *\n     * <b>NOTE: application usually don't call this method. Only\n     * the m-odule that implements the RTP binding shall use this method</b>\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param state\n     *    The state to check.\n     * @return\n     *    Returns true if ZRTP engine is in the given state, false otherwise.\n     */\n    int32_t zrtp_inState(ZrtpContext* zrtpContext, int32_t state);\n\n    /**\n     * Set SAS as verified.\n     *\n     * Call this method if the user confirmed (verfied) the SAS. ZRTP\n     * remembers this together with the retained secrets data.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     */\n    void zrtp_SASVerified(ZrtpContext* zrtpContext);\n\n    /**\n     * Reset the SAS verfied flag for the current active user's retained secrets.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     */\n    void zrtp_resetSASVerified(ZrtpContext* zrtpContext);\n\n    /**\n     * Get the ZRTP Hello Hash data.\n     *\n     * Use this method to get the ZRTP Hello Hash data. The method\n     * returns the data as a string containing the ZRTP protocol version and\n     * hex-digits. \n\n     * The index defines which Hello packet to use. Each supported ZRTP procol version\n     * uses a different Hello packet and thus computes different hashes.\n     *\n     * Refer to ZRTP specification, chapter 8.\n     *\n     * @param index\n     *     Hello hash of the Hello packet identfied by index. Index must be 0 <= index < zrtp_getNumberSupportedVersions().\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     *\n     * @return\n     *    a pointer to a C-string that contains the Hello hash formatted according to RFC6189 section 8 \n     *    without the leading 'a=zrtp-hash:' SDP attribute identifier. The hello hash is available \n     *    immediately after @c zrtp_CreateWrapper. The caller must @c free() if it does not use the\n     *    hello hash C-string anymore.\n     *\n     * @see zrtp_getNumberSupportedVersions()\n     */\n    char* zrtp_getHelloHash(ZrtpContext* zrtpContext, int32_t index);\n\n    /**\n     * Get the peer's ZRTP Hello Hash data.\n     *\n     * Use this method to get the peer's ZRTP Hello Hash data. The method\n     * returns the data as a string containing the ZRTP protocol version and\n     * hex-digits.\n     *\n     * The peer's hello hash is available only after ZRTP received a hello. If\n     * no data is available the function returns an empty string.\n     *\n     * Refer to ZRTP specification, chapter 8.\n     *\n     * @return\n     *    a C-string containing the Hello version and the hello hash as hex digits. The caller \n     *    must @c free() if it does not use the hello hash C-string anymore.\n     */\n    char* zrtp_getPeerHelloHash(ZrtpContext* zrtpContext);\n\n    /**\n     * Get the peer's previously associated name.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @return\n     *    a heap allocated char array that contains the name.\n     *    If ZRTP was not started or there was no name set the method\n     *    returns NULL. The user is responsible for freeing the returned\n     *    memory.\n     */\n    char* zrtp_getPeerName(ZrtpContext* zrtpContext);\n\n    /**\n     * Associate a name with the peer.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param name\n     *    Char array containing the name to be associated.\n     */\n    void zrtp_putPeerName(ZrtpContext* zrtpContext, const char* name);\n\n    /**\n     * Get Multi-stream parameters.\n     *\n     * Use this method to get the Multi-stream parameters that were computed\n     * during the ZRTP handshake. An application may use these parameters to\n     * enable multi-stream processing for an associated SRTP session.\n     *\n     * The application must not modify the contents of returned char array, it\n     * is opaque data. The application may hand over this string to a new ZRTP\n     * instance to enable multi-stream processing for this new session.\n     *\n     * Refer to chapter 4.4.2 in the ZRTP specification for further details\n     * and restriction how and when to use multi-stream mode.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param length\n     *    Pointer to an integer that receives the length of the char array\n     * @return\n     *    a char array that contains the multi-stream parameters.\n     *    If ZRTP was not started or ZRTP is not yet in secure state the method\n     *    returns NULL and a length of 0. The caller must @c free() if it does not\n     *    use the data anymore, e.g. after using it in zrtp_setMultiStrParams\n     */\n    char* zrtp_getMultiStrParams(ZrtpContext* zrtpContext, int32_t *length);\n\n    /**\n     * Set Multi-stream parameters.\n     *\n     * Use this method to set the parameters required to enable Multi-stream\n     * processing of ZRTP. The multi-stream parameters must be set before the\n     * application starts the ZRTP protocol engine.\n     *\n     * Refer to chapter 4.4.2 in the ZRTP specification for further details\n     * of multi-stream mode.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure of the multi-media (slave) ZRTP session\n     * @param length\n     *    The integer that contains the length of the char array\n     * @param parameters\n     *     A char array that contains the multi-stream parameters that this\n     *     new ZRTP instance shall use. See also\n     *     <code>getMultiStrParams()</code>\n     * @param master\n     *     Pointer to the opaque ZrtpContext structure of the master ZRTP stream.\n     */\n    void zrtp_setMultiStrParams(ZrtpContext* zrtpContext, char* parameters, int32_t length, ZrtpContext* master);\n\n    /**\n     * Check if this ZRTP session is a Multi-stream session.\n     *\n     * Use this method to check if this ZRTP instance uses multi-stream.\n     * Refer to chapters 4.2 and 4.4.2 in the ZRTP.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @return\n     *     True if multi-stream is used, false otherwise.\n     */\n    int32_t zrtp_isMultiStream(ZrtpContext* zrtpContext);\n\n    /**\n     * Check if the other ZRTP client supports Multi-stream.\n     *\n     * Use this method to check if the other ZRTP client supports\n     * Multi-stream mode.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @return\n     *     True if multi-stream is available, false otherwise.\n     */\n    int32_t zrtp_isMultiStreamAvailable(ZrtpContext* zrtpContext);\n\n    /**\n     * Accept a PBX enrollment request.\n     *\n     * If a PBX service asks to enroll the PBX trusted MitM key and the user\n     * accepts this request, for example by pressing an OK button, the client\n     * application shall call this method and set the parameter\n     * <code>accepted</code> to true. If the user does not accept the request\n     * set the parameter to false.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param accepted\n     *     True if the enrollment request is accepted, false otherwise.\n     */\n    void zrtp_acceptEnrollment(ZrtpContext* zrtpContext, int32_t accepted);\n\n    /**\n     * Check the state of the enrollment mode.\n     * \n     * If true then we will set the enrollment flag (E) in the confirm\n     * packets and performs the enrollment actions. A MitM (PBX) enrollment service \n     * started this ZRTP session. Can be set to true only if mitmMode is also true.\n     * \n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @return status of the enrollmentMode flag.\n     */\n    int32_t zrtp_isEnrollmentMode(ZrtpContext* zrtpContext);\n\n    /**\n     * Check the state of the enrollment mode.\n     * \n     * If true then we will set the enrollment flag (E) in the confirm\n     * packets and perform the enrollment actions. A MitM (PBX) enrollment \n     * service must sets this mode to true. \n     * \n     * Can be set to true only if mitmMode is also true. \n     * \n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param enrollmentMode defines the new state of the enrollmentMode flag\n     */\n    void zrtp_setEnrollmentMode(ZrtpContext* zrtpContext, int32_t enrollmentMode);\n\n    /**\n     * Check if a peer's cache entry has a vaild MitM key.\n     *\n     * If true then the other peer ha a valid MtiM key, i.e. the peer has performed\n     * the enrollment procedure. A PBX ZRTP Back-2-Back application can use this function\n     * to check which of the peers is enrolled.\n     *\n     * @return True if the other peer has a valid Mitm key (is enrolled).\n     */\n    int32_t isPeerEnrolled(ZrtpContext* zrtpContext);\n\n    /**\n     * Send the SAS relay packet.\n     * \n     * The method creates and sends a SAS relay packet according to the ZRTP\n     * specifications. Usually only a MitM capable user agent (PBX) uses this\n     * function.\n     * \n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param sh the full SAS hash value\n     * @param render the SAS rendering algorithm\n     */\n    int32_t zrtp_sendSASRelayPacket(ZrtpContext* zrtpContext, uint8_t* sh, char* render);\n\n    /**\n     * Get the commited SAS rendering algorithm for this ZRTP session.\n     * \n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @return the commited SAS rendering algorithm. The caller must @c free() the buffer\n     *    if it does not use the string anymore.\n     */\n    const char* zrtp_getSasType(ZrtpContext* zrtpContext);\n\n    /**\n     * Get the computed SAS hash for this ZRTP session.\n     * \n     * A PBX ZRTP back-to-Back function uses this function to get the SAS\n     * hash of an enrolled client to construct the SAS relay packet for\n     * the other client.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @return a pointer to the byte array that contains the full \n     *         SAS hash.\n     */\n    uint8_t* zrtp_getSasHash(ZrtpContext* zrtpContext);\n\n    /**\n     * Set signature data\n     *\n     * This functions stores signature data and transmitts it during ZRTP\n     * processing to the other party as part of the Confirm packets. Refer to\n     * chapters 5.7 and 7.2.\n     *\n     * The signature data must be set before ZRTP the application calls\n     * <code>start()</code>.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param data\n     *    The signature data including the signature type block. The method\n     *    copies this data into the Confirm packet at signature type block.\n     * @param length\n     *    The length of the signature data in bytes. This length must be\n     *    multiple of 4.\n     * @return\n     *    True if the method stored the data, false otherwise.\n     */\n    int32_t zrtp_setSignatureData(ZrtpContext* zrtpContext, uint8_t* data, int32_t length);\n\n    /**\n     * Get signature data\n     *\n     * This functions returns signature data that was receivied during ZRTP\n     * processing. Refer to chapters 5.7 and 7.2.\n     *\n     * The signature data can be retrieved after ZRTP enters secure state.\n     * <code>start()</code>.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @return\n     *    Number of bytes copied into the data buffer\n     */\n    const uint8_t* zrtp_getSignatureData(ZrtpContext* zrtpContext);\n\n    /**\n     * Get length of signature data\n     *\n     * This functions returns the length of signature data that was receivied\n     * during ZRTP processing. Refer to chapters 5.7 and 7.2.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @return\n     *    Length in bytes of the received signature data. The method returns\n     *    zero if no signature data avilable.\n     */\n    int32_t zrtp_getSignatureLength(ZrtpContext* zrtpContext);\n\n    /**\n     * Emulate a Conf2Ack packet.\n     *\n     * This method emulates a Conf2Ack packet. According to ZRTP specification\n     * the first valid SRTP packet that the Initiator receives must switch\n     * on secure mode. Refer to chapter 4 in the specificaton\n     *\n     * <b>NOTE: application shall never call this method directly. Only\n     * the module that implements the RTP binding shall use this method</b>\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     */\n    void zrtp_conf2AckSecure(ZrtpContext* zrtpContext);\n\n    /**\n     * Get other party's ZID (ZRTP Identifier) data\n     *\n     * This functions returns the other party's ZID that was receivied\n     * during ZRTP processing.\n     *\n     * The ZID data can be retrieved after ZRTP receive the first Hello\n     * packet from the other party. The application may call this method\n     * for example during SAS processing in showSAS(...) user callback\n     * method.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param data\n     *    Pointer to a data buffer. This buffer must have a size of\n     *    at least 12 bytes (96 bit) (ZRTP Identifier, see chap. 4.9)\n     * @return\n     *    Number of bytes copied into the data buffer - must be equivalent\n     *    to 12 bytes.\n     */\n    int32_t zrtp_getPeerZid(ZrtpContext* zrtpContext, uint8_t* data);\n\n\n     /**\n      * Get number of supported ZRTP protocol versions.\n      *\n      * @param zrtpContext\n      *    Pointer to the opaque ZrtpContext structure.\n      *\n      * @return the number of supported ZRTP protocol versions or -1 in case\n      *         of an error, for example non-initialized data.\n      */\n     int32_t zrtp_getNumberSupportedVersions(ZrtpContext* zrtpContext);\n\n     /**\n      * Get negotiated ZRTP protocol versions.\n      *\n      * @param zrtpContext\n      *    Pointer to the opaque ZrtpContext structure.\n      *\n      * @return the integer representation of the negotiated ZRTP protocol version\n      *         of -1 in case of an error, for example non-initialized data.\n      */\n     int32_t zrtp_getCurrentProtocolVersion(ZrtpContext* zrtpContext);\n\n     /**\n     * This enumerations list all configurable algorithm types.\n     */\n\n    /* Keep in synch with enumeration in ZrtpConfigure.h */\n\n    typedef enum zrtp_AlgoTypes {\n        zrtp_HashAlgorithm = 1, zrtp_CipherAlgorithm, zrtp_PubKeyAlgorithm, zrtp_SasType, zrtp_AuthLength\n    } Zrtp_AlgoTypes;\n\n    /**\n     * Initialize the GNU ZRTP Configure data.\n     *\n     * Initializing and setting a ZRTP configuration is optional. GNU ZRTP\n     * uses a sensible default if an application does not define its own\n     * ZRTP configuration.\n     *\n     * If an application initialize th configure data it must set the\n     * configuration data.\n     *\n     * The ZRTP specification, chapters 5.1.2 through 5.1.6 defines the\n     * algorithm names and their meaning.\n     *\n     * The current ZRTP implementation implements all mandatory algorithms\n     * plus a set of the optional algorithms. An application shall use\n     * @c zrtp_getAlgorithmNames to get the names of the available algorithms.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @returns\n     *      Pointer to the ZrtpConfCtx\n     *\n     * @see zrtp_getAlgorithmNames\n     */\n    int32_t zrtp_InitializeConfig (ZrtpContext* zrtpContext);\n\n    /**\n     * Get names of all available algorithmes of a given algorithm type.\n     *\n     * The algorithm names are as specified in the ZRTP specification, chapters\n     * 5.1.2 through 5.1.6 .\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param type\n     *    The algorithm type.\n     * @returns\n     *    A NULL terminated array of character pointers.\n     */\n    char** zrtp_getAlgorithmNames(ZrtpContext* zrtpContext, Zrtp_AlgoTypes type);\n\n    /**\n     * Free storage used to store the algorithm names.\n     *\n     * If an application does not longer require the algoritm names it should\n     * free the space.\n     *\n     * @param names\n     *    The NULL terminated array of character pointers.\n     */\n    void zrtp_freeAlgorithmNames(char** names);\n\n    /**\n    * Convenience function that sets a pre-defined standard configuration.\n    *\n    * The standard configuration consists of the following algorithms:\n    * <ul>\n    * <li> Hash: SHA256 </li>\n    * <li> Symmetric Cipher: AES 128, AES 256 </li>\n    * <li> Public Key Algorithm: DH2048, DH3027, MultiStream </li>\n    * <li> SAS type: libase 32 </li>\n    * <li> SRTP Authentication lengths: 32, 80 </li>\n    *</ul>\n    *\n    * @param zrtpContext\n    *    Pointer to the opaque ZrtpContext structure.\n    */\n    void zrtp_setStandardConfig(ZrtpContext* zrtpContext);\n\n    /**\n     * Convenience function that sets the mandatory algorithms only.\n     *\n     * Mandatory algorithms are:\n     * <ul>\n     * <li> Hash: SHA256 </li>\n     * <li> Symmetric Cipher: AES 128 </li>\n     * <li> Public Key Algorithm: DH3027, MultiStream </li>\n     * <li> SAS type: libase 32 </li>\n     * <li> SRTP Authentication lengths: 32, 80 </li>\n     *</ul>\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     */\n    void zrtp_setMandatoryOnly(ZrtpContext* zrtpContext);\n\n    /**\n     * Clear all configuration data.\n     *\n     * The functions clears all configuration data.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     */\n    void zrtp_confClear(ZrtpContext* zrtpContext);\n\n    /**\n     * Add an algorithm to configuration data.\n     *\n     * Adds the specified algorithm to the configuration data.\n     * If no free configuration data slot is available the\n     * function does not add the algorithm and returns -1. The\n     * methods appends the algorithm to the existing algorithms.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param algoType\n     *    Specifies which algorithm type to select\n     * @param algo\n     *    The name of the algorithm to add.\n     * @return\n     *    Number of free configuration data slots or -1 on error\n     */\n    int32_t zrtp_addAlgo(ZrtpContext* zrtpContext, Zrtp_AlgoTypes algoType, const char* algo);\n\n    /**\n     * Add an algorithm to configuration data at given index\n     *\n     * Adds the specified algorithm to the configuration data vector\n     * at a given index. If the index is larger than the actual size\n     * of the configuration vector the method just appends the algorithm.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param algoType\n     *    Specifies which algorithm type to select\n     * @param algo\n     *    The name of the algorithm to add.\n     * @param index\n     *    The index where to add the algorihm\n     * @return\n     *    Number of free configuration data slots or -1 on error\n     */\n    int32_t zrtp_addAlgoAt(ZrtpContext* zrtpContext, Zrtp_AlgoTypes algoType, const char* algo, int32_t index);\n\n    /**\n     * Remove a algorithm from configuration data.\n     *\n     * Removes the specified algorithm from configuration data. If\n     * the algorithm was not configured previously the function does\n     * not modify the configuration data and returns the number of\n     * free configuration data slots.\n     *\n     * If an application removes all algorithms then ZRTP does not\n     * include any algorithm into the hello message and falls back\n     * to a predefined mandatory algorithm.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param algoType\n     *    Specifies which algorithm type to select\n     * @param algo\n     *    The name of the algorithm to remove.\n     * @return\n     *    Number of free configuration slots or -1 on error\n     */\n    int32_t zrtp_removeAlgo(ZrtpContext* zrtpContext, Zrtp_AlgoTypes algoType, const char* algo);\n\n    /**\n     * Returns the number of configured algorithms.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param algoType\n     *    Specifies which algorithm type to select\n     * @return\n     *    The number of configured algorithms (used configuration\n     *    data slots) or -1 on error\n     */\n    int32_t zrtp_getNumConfiguredAlgos(ZrtpContext* zrtpContext, Zrtp_AlgoTypes algoType);\n\n    /**\n     * Returns the identifier of the algorithm at index.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param algoType\n     *    Specifies which algorithm type to select\n     * @param index\n     *    The index in the list of the algorihm type\n     * @return\n     *    A pointer to the algorithm name. If the index\n     *    does not point to a configured slot then the function\n     *    returns NULL.\n     *\n     */\n    const char* zrtp_getAlgoAt(ZrtpContext* zrtpContext, Zrtp_AlgoTypes algoType, int32_t index);\n\n    /**\n     * Checks if the configuration data of the algorihm type already contains\n     * a specific algorithms.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param algoType\n     *    Specifies which algorithm type to select\n     * @param algo\n     *    The name of the algorithm to check\n     * @return\n     *    True if the algorithm was found, false otherwise.\n     *\n     */\n    int32_t zrtp_containsAlgo(ZrtpContext* zrtpContext, Zrtp_AlgoTypes algoType, const char*  algo);\n\n    /**\n     * Enables or disables trusted MitM processing.\n     *\n     * For further details of trusted MitM processing refer to ZRTP\n     * specification, chapter 7.3\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param yesNo\n     *    If set to true then trusted MitM processing is enabled.\n     */\n    void zrtp_setTrustedMitM(ZrtpContext* zrtpContext, int32_t yesNo);\n\n    /**\n     * Check status of trusted MitM processing.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @return\n     *    Returns true if trusted MitM processing is enabled.\n     */\n    int32_t zrtp_isTrustedMitM(ZrtpContext* zrtpContext);\n\n    /**\n     * Enables or disables SAS signature processing.\n     *\n     * For further details of trusted MitM processing refer to ZRTP\n     * specification, chapter 7.2\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @param yesNo\n     *    If true then certificate processing is enabled.\n     */\n    void zrtp_setSasSignature(ZrtpContext* zrtpContext, int32_t yesNo);\n\n    /**\n     * Check status of SAS signature processing.\n     *\n     * @param zrtpContext\n     *    Pointer to the opaque ZrtpContext structure.\n     * @return\n     *    Returns true if certificate processing is enabled.\n     */\n    int32_t zrtp_isSasSignature(ZrtpContext* zrtpContext);\n\n#ifdef __cplusplus\n}\n#ifdef __GNUC__ \n#pragma GCC visibility pop\n#endif\n#endif\n\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpCallback.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPCALLBACK_H_\n#define _ZRTPCALLBACK_H_\n\n/**\n * @file ZrtpCallback.h\n * @brief Callback interface between ZRTP and the RTP stack implementation\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <string>\n#include <stdint.h>\n#include <libzrtpcpp/ZrtpCodes.h>\n#include <common/osSpecifics.h>\n\n/**\n * This enum defines which role a ZRTP peer has.\n *\n * According to the ZRTP specification the role determines which keys to\n * use to encrypt or decrypt SRTP data.\n *\n * <ul>\n * <li> The Initiator encrypts SRTP data using the <em>keyInitiator</em> and the\n *      <em>saltInitiator</em> data, the Responder uses these data to decrypt.\n * </li>\n * <li> The Responder encrypts SRTP data using the <em>keyResponder</em> and the\n *      <em>saltResponder</em> data, the Initiator uses these data to decrypt.\n * </li>\n * </ul>\n */\ntypedef enum  {\n    NoRole = 0,     ///< ZRTP role not yet set\n    Responder = 1,  ///< This client is in ZRTP Responder mode\n    Initiator       ///< This client is in ZRTP Initiator mode\n} Role;\n\n/// The algorihms that we support in SRTP and that ZRTP can negotiate.\ntypedef enum {\n    None,\n    Aes = 1,        ///< Use AES as symmetrical cipher algorithm\n    TwoFish,        ///< Use TwoFish as symmetrical cipher algorithm\n    Sha1,           ///< Use Sha1 as authentication algorithm\n    Skein           ///< Use Skein as authentication algorithm\n} SrtpAlgorithms;\n\n/**\n * This structure contains pointers to the SRTP secrets and the role info.\n *\n * About the role and what the meaning of the role is refer to the\n * of the enum Role. The pointers to the secrets are valid as long as\n * the ZRtp object is active. To use these data after the ZRtp object's\n * lifetime you may copy the data into a save place. The destructor\n * of ZRtp clears the data.\n */\ntypedef struct srtpSecrets {\n    SrtpAlgorithms symEncAlgorithm;     ///< symmetrical cipher algorithm\n    const uint8_t* keyInitiator;        ///< Initiator's key\n    int32_t initKeyLen;                 ///< Initiator's key length\n    const uint8_t* saltInitiator;       ///< Initiator's salt\n    int32_t initSaltLen;                ///< Initiator's salt length\n    const uint8_t* keyResponder;        ///< Responder's key\n    int32_t respKeyLen;                 ///< Responder's key length\n    const uint8_t* saltResponder;       ///< Responder's salt\n    int32_t respSaltLen;                ///< Responder's salt length\n    SrtpAlgorithms authAlgorithm;       ///< SRTP authentication algorithm\n    int32_t srtpAuthTagLen;             ///< SRTP authentication length\n    std::string sas;                    ///< The SAS string\n    Role  role;                         ///< ZRTP role of this client\n} SrtpSecret_t;\n\nenum EnableSecurity {\n    ForReceiver = 1,        ///< Enable security for SRTP receiver\n    ForSender   = 2         ///< Enable security for SRTP sender\n};\n\n/**\n * This abstract class defines the callback functions required by GNU ZRTP.\n *\n * This class is a pure abstract class, aka Interface in Java, that\n * defines the callback interface that the specific part of a GNU ZRTP\n * must implement. The generic part of GNU ZRTP uses these mehtods\n * to communicate with the specific part, for example to send data\n * via the RTP/SRTP stack, to set timers and cancel timer and so on.\n *\n * The generiy part of GNU ZRTP needs only a few callback methods to\n * be implemented by the specific part.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZrtpCallback {\n\npublic:\n    virtual ~ZrtpCallback() {};\n\nprotected:\n    friend class ZRtp;\n\n    /**\n     * Send a ZRTP packet via RTP.\n     *\n     * ZRTP calls this method to send a ZRTP packet via the RTP session.\n     *\n     * @param data\n     *    Points to ZRTP packet to send. The packet already contains a 4 bytes\n     *    storage at the end to store CRC.\n     * @param length\n     *    The length in bytes of the data, including the CRC storage.\n     * @return\n     *    zero if sending failed, one if packet was send\n     */\n    virtual int32_t sendDataZRTP(const uint8_t* data, int32_t length) =0;\n\n    /**\n     * Activate timer.\n     *\n     * @param time\n     *    The time in ms for the timer\n     * @return\n     *    zero if activation failed, one if timer was activated\n     */\n    virtual int32_t activateTimer(int32_t time) =0;\n\n    /**\n     * Cancel the active timer.\n     *\n     * @return\n     *    zero if cancel action failed, one if timer was canceled\n     */\n    virtual int32_t cancelTimer() =0;\n\n    /**\n     * Send information messages to the hosting environment.\n     *\n     * The ZRTP implementation uses this method to send information\n     * messages to the host. Along with the message ZRTP provides a\n     * severity indicator that defines: Info, Warning, Error,\n     * Alert. Refer to the <code>MessageSeverity</code> enum above.\n     *\n     * @param severity\n     *     This defines the message's severity\n     * @param subCode\n     *     The subcode identifying the reason.\n     * @see ZrtpCodes#MessageSeverity\n     */\n    virtual void sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode) =0;\n\n    /**\n     * SRTP crypto data ready for the sender or receiver.\n     *\n     * The ZRTP implementation calls this method right after all SRTP\n     * secrets are computed and ready to be used. The parameter points\n     * to a structure that contains pointers to the SRTP secrets and a\n     * <code>enum Role</code>. The called method (the implementation\n     * of this abstract method) must either copy the pointers to the SRTP\n     * data or the SRTP data itself to a save place. The SrtpSecret_t\n     * structure is destroyed after the callback method returns to the\n     * ZRTP implementation.\n     *\n     * The SRTP data themselfs are ontained in the ZRtp object and are\n     * valid as long as the ZRtp object is active. TheZRtp's\n     * destructor clears the secrets. Thus the called method needs to\n     * save the pointers only, ZRtp takes care of the data.\n     *\n     * The implementing class may enable SRTP processing in this\n     * method or delay it to srtpSecertsOn().\n     *\n     * @param secrets A pointer to a SrtpSecret_t structure that\n     *     contains all necessary data.\n     *\n     * @param part for which part (Sender or Receiver) this data is\n     *     valid.\n     *\n     * @return Returns false if something went wrong during\n     *    initialization of SRTP context, for example memory shortage.\n     */\n    virtual bool srtpSecretsReady(SrtpSecret_t* secrets, EnableSecurity part) =0;\n\n    /**\n     * Switch off the security for the defined part.\n     *\n     * @param part Defines for which part (sender or receiver) to\n     *    switch on security\n     */\n    virtual void srtpSecretsOff(EnableSecurity part) =0;\n\n    /**\n     * Switch on the security.\n     *\n     * ZRTP calls this method after it has computed the SAS and check\n     * if it is verified or not. In addition ZRTP provides information\n     * about the cipher algorithm and key length for the SRTP session.\n     *\n     * This method must enable SRTP processing if it was not enabled\n     * during sertSecretsReady().\n     *\n     * @param c The name of the used cipher algorithm and mode, or\n     *    NULL\n     *\n     * @param s The SAS string\n     *\n     * @param verified if <code>verified</code> is true then SAS was\n     *    verified by both parties during a previous call.\n     */\n    virtual void srtpSecretsOn(std::string c, std::string s, bool verified) =0;\n\n    /**\n     * This method handles GoClear requests.\n     *\n     * According to the ZRTP specification the user must be informed about\n     * a GoClear request because the ZRTP implementation switches off security\n     * if it could authenticate the GoClear packet.\n     *\n     * <b>Note:</b> GoClear is not yet implemented in GNU ZRTP.\n     *\n     */\n    virtual void handleGoClear() =0;\n\n    /**\n     * Handle ZRTP negotiation failed.\n     *\n     * ZRTP calls this method in case ZRTP negotiation failed. The\n     * parameters show the severity as well as the reason.\n     *\n     * @param severity\n     *     This defines the message's severity\n     * @param subCode\n     *     The subcode identifying the reason.\n     * @see ZrtpCodes#MessageSeverity\n     */\n    virtual void zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity, int32_t subCode) =0;\n\n    /**\n     * ZRTP calls this method if the other side does not support ZRTP.\n     *\n     * If the other side does not answer the ZRTP <em>Hello</em> packets then\n     * ZRTP calls this method,\n     *\n     */\n    virtual void zrtpNotSuppOther() =0;\n\n    /**\n     * Enter synchronization mutex.\n     *\n     * GNU ZRTP requires one mutes to synchronize its\n     * processing. Because mutex implementations depend on the\n     * underlying infrastructure, for example operating system or\n     * thread implementation, GNU ZRTP delegates mutex handling to the\n     * spcific part of its implementation.\n     */\n    virtual void synchEnter() =0;\n\n    /**\n     * Leave synchronization mutex.\n     */\n    virtual void synchLeave() =0;\n\n    /**\n     * Inform about a PBX enrollment request.\n     *\n     * Please refer to chapter 8.3 ff to get more details about PBX\n     * enrollment and SAS relay.\n     *\n     * <b>Note:</b> PBX enrollement is not yet fully supported by GNU\n     * ZRTP.\n     *\n     * @param info Give some information to the user about the PBX\n     *    requesting an enrollment.\n     */\n    virtual void zrtpAskEnrollment(GnuZrtpCodes::InfoEnrollment info) =0;\n\n    /**\n     * Inform about PBX enrollment result.\n     *\n     * Informs the use about the acceptance or denial of an PBX enrollment\n     * request\n     *\n     * <b>Note:</b> PBX enrollement is not yet fully supported by GNU\n     * ZRTP.\n     *\n     * @param info information to the user about the result\n     *    of an enrollment.\n     */\n    virtual void zrtpInformEnrollment(GnuZrtpCodes::InfoEnrollment info) =0;\n\n    /**\n     * Request a SAS signature.\n     *\n     * After ZRTP was able to compute the Short Authentication String\n     * (SAS) it calls this method. The client may now use an\n     * approriate method to sign the SAS. The client may use\n     * ZrtpQueue#setSignatureData() to store the signature data an\n     * enable signature transmission to the other peer. Refer to\n     * chapter 8.2 of ZRTP specification.\n     *\n     * <b>Note:</b> SAS signing is not yet fully supported by GNU\n     * ZRTP.\n     *\n     * @param sasHash\n     *    The SAS hash to sign.\n     *\n     */\n    virtual void signSAS(uint8_t* sasHash) =0;\n\n    /**\n     * ZRTPQueue calls this method to request a SAS signature check.\n     *\n     * After ZRTP received a SAS signature in one of the Confirm packets it\n     * call this method. The client may use <code>getSignatureLength()</code>\n     * and <code>getSignatureData()</code>of ZrtpQueue to get the signature\n     * data and perform the signature check. Refer to chapter 8.2 of ZRTP\n     * specification.\n     *\n     * If the signature check fails the client may return false to ZRTP. In\n     * this case ZRTP signals an error to the other peer and terminates\n     * the ZRTP handshake.\n     *\n     * <b>Note:</b> SAS signing is not yet fully supported by GNU\n     * ZRTP.\n     *\n     * @param sasHash\n     *    The SAS hash that was signed by the other peer.\n     * @return\n     *    true if the signature was ok, false otherwise.\n     *\n     */\n    virtual bool checkSASSignature(uint8_t* sasHash) =0;\n};\n\n#endif // ZRTPCALLBACK\n\n/**\n * @}\n */\n/** EMACS **\n * Local variables:\n * mode: c++\n * c-default-style: ellemtel\n * c-basic-offset: 4\n * End:\n */\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpCallbackWrapper.h",
    "content": "/*\n    This class maps the ZRTP C++ callback methods to C callback methods.\n    Copyright (C) 2010-2013 Werner Dittmann\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU Lesser General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n*/\n\n#ifndef ZRTPCALLBACKWRAPPER_H\n#define ZRTPCALLBACKWRAPPER_H\n\n#include <stdlib.h>\n\n#include <libzrtpcpp/ZrtpCallback.h>\n#include <libzrtpcpp/ZrtpConfigure.h>\n#include <libzrtpcpp/ZrtpCWrapper.h>\n\n/**\n *\n * @file ZrtpCallbackWrapper.h\n * @brief C-Wrapper helper\n *\n * This is a helper class for for the C wrapper and implements\n * the GNU ZRTP callback interface. For detailed documentation about\n * the callback method refer to file <code>ZrtpCallback</code>\n * @ingroup GNU_ZRTP\n * @{\n *\n * @see ZrtpCallback\n * @see ZrtpCWrapper\n */\nclass __EXPORT ZrtpCallbackWrapper : public ZrtpCallback\n{\npublic:\n    /**\n     * Construct a class that implements ZrtpCallback and uses a C structure\n     * to call C functions that implement the callbacks.\n     *\n     * @param cb\n     *    The C callback structure that hold the addresses of the C methods\n     *    that implement the actual callback functions.\n     * @param ctx\n     *    Pointer to the ZrtpContext\n     */\n    ZrtpCallbackWrapper(zrtp_Callbacks* cb, ZrtpContext* ctx);\n\n    int32_t sendDataZRTP ( const unsigned char* data, int32_t length );\n\n    int32_t activateTimer ( int32_t time );\n\n    int32_t cancelTimer();\n\n    void sendInfo ( GnuZrtpCodes::MessageSeverity severity, int32_t subCode );\n\n    bool srtpSecretsReady ( SrtpSecret_t* secrets, EnableSecurity part );\n\n    void srtpSecretsOff ( EnableSecurity part );\n\n    void srtpSecretsOn ( std::string c, std::string s, bool verified );\n\n    void handleGoClear();\n\n    void zrtpNegotiationFailed ( GnuZrtpCodes::MessageSeverity severity, int32_t subCode );\n\n    void zrtpNotSuppOther();\n\n    void synchEnter();\n\n    void synchLeave();\n\n    void zrtpAskEnrollment (GnuZrtpCodes::InfoEnrollment info );\n\n    void zrtpInformEnrollment (GnuZrtpCodes::InfoEnrollment info );\n\n    void signSAS (uint8_t* sasHash );\n\n    bool checkSASSignature (uint8_t* sasHash );\n\nprivate:\n    void init();\n    zrtp_Callbacks *c_callbacks;\n    ZrtpContext* zrtpCtx;\n\n};\n\n/**\n * @}\n */\n\n#endif // ZRTPCALLBACKWRAPPER_H\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpCodes.h",
    "content": "/** @file ZrtpCodes.h\n */\n/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the Lesser GNU General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPCODES_H_\n#define _ZRTPCODES_H_\n/**\n * @file ZrtpCodes.h\n * @brief The ZRTP info, warning, error codes, and other contants and enums that applications may use.\n * @ingroup GNU_ZRTP\n * @{\n */\n\nnamespace GnuZrtpCodes {\n/**\n * \\namespace GnuZrtpCodes\n * \n * This enum defines the information message severity.\n *\n * The ZRTP implementation issues information messages to inform the user\n * about ongoing processing, unusual behavior, or alerts in case of severe\n * problems. Each main severity code a number of sub-codes exist that\n * specify the exact nature of the problem. \n *\n * An application gets message severity codes and the associated sub-codes\n * via the ZrtpUserCallback#showMessage method.\n * \n * The severity levels and their meaning are:\n *\n * <dl>\n * <dt>Info</dt> <dd>keeps the user informed about ongoing processing and\n *     security setup. The enumeration InfoCodes defines the subcodes.\n * </dd>\n * <dt>Warning</dt> <dd>is an information about some security issues, e.g. if\n *     an AES 256 encryption is request but only DH 3072 as public key scheme\n *     is supported. ZRTP will establish a secure session (SRTP). The\n *     enumeration WarningCodes defines the sub-codes.\n * </dd>\n * <dt>Severe</dt> <dd>is used if an error occured during ZRTP protocol usage.\n *     In case of <em>Severe</em> ZRTP will <b>not</b> establish a secure session.\n *     The enumeration SevereCodes defines the sub-codes.\n * </dd>\n * <dt>Zrtp</dt> <dd>shows a ZRTP security problem. Refer to the enumeration\n *     ZrtpErrorCodes for sub-codes. GNU ZRTP of course will <b>not</b> \n *     establish a secure session.\n * </dd>\n * </dl>\n *\n */\nenum MessageSeverity {\n    Info = 1,\n    Warning,\n    Severe,\n    ZrtpError\n};\n\n/**\n * Sub-codes for Info\n */\nenum InfoCodes {\n    InfoHelloReceived = 1,          //!< Hello received and prepared a Commit, ready to get peer's hello hash\n    InfoCommitDHGenerated,          //!< Commit: Generated a public DH key\n    InfoRespCommitReceived,         //!< Responder: Commit received, preparing DHPart1\n    InfoDH1DHGenerated,             //!< DH1Part: Generated a public DH key\n    InfoInitDH1Received,            //!< Initiator: DHPart1 received, preparing DHPart2\n    InfoRespDH2Received,            //!< Responder: DHPart2 received, preparing Confirm1\n    InfoInitConf1Received,          //!< Initiator: Confirm1 received, preparing Confirm2\n    InfoRespConf2Received,          //!< Responder: Confirm2 received, preparing Conf2Ack\n    InfoRSMatchFound,               //!< At least one retained secrets matches - security OK\n    InfoSecureStateOn,              //!< Entered secure state\n    InfoSecureStateOff              //!< No more security for this session\n};\n\n/**\n * Sub-codes for Warning\n */\nenum WarningCodes {\n    WarningDHAESmismatch = 1,       //!< Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096 - not used DH4096 was discarded\n    WarningGoClearReceived,         //!< Received a GoClear message\n    WarningDHShort,                 //!< Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096- not used DH4096 was discarded\n    WarningNoRSMatch,               //!< No retained shared secrets available - must verify SAS\n    WarningCRCmismatch,             //!< Internal ZRTP packet checksum mismatch - packet dropped\n    WarningSRTPauthError,           //!< Dropping packet because SRTP authentication failed!\n    WarningSRTPreplayError,         //!< Dropping packet because SRTP replay check failed!\n    WarningNoExpectedRSMatch,       //!< Valid retained shared secrets availabe but no matches found - must verify SAS\n    WarningNoExpectedAuxMatch       //!< Our AUX secret was set but the other peer's AUX secret does not match ours\n};\n\n/**\n * Sub-codes for Severe\n */\nenum SevereCodes {\n    SevereHelloHMACFailed = 1,      //!< Hash HMAC check of Hello failed!\n    SevereCommitHMACFailed,         //!< Hash HMAC check of Commit failed!\n    SevereDH1HMACFailed,            //!< Hash HMAC check of DHPart1 failed!\n    SevereDH2HMACFailed,            //!< Hash HMAC check of DHPart2 failed!\n    SevereCannotSend,               //!< Cannot send data - connection or peer down?\n    SevereProtocolError,            //!< Internal protocol error occured!\n    SevereNoTimer,                  //!< Cannot start a timer - internal resources exhausted?\n    SevereTooMuchRetries            //!< Too much retries during ZRTP negotiation - connection or peer down?\n};\n\n/**\n  * Error codes according to the ZRTP specification chapter 6.9\n  *\n  * GNU ZRTP uses these error codes in two ways: to fill the appropriate\n  * field ing the ZRTP Error packet and as sub-code in \n  * ZrtpUserCallback#showMessage(). GNU ZRTP uses thes error codes also\n  * to report received Error packts, in this case the sub-codes are their\n  * negative values.\n  *\n  * The enumeration member comments are copied from the ZRTP specification.\n  */\nenum ZrtpErrorCodes {\n    MalformedPacket =   0x10,    //!< Malformed packet (CRC OK, but wrong structure)\n    CriticalSWError =   0x20,    //!< Critical software error\n    UnsuppZRTPVersion = 0x30,    //!< Unsupported ZRTP version\n    HelloCompMismatch = 0x40,    //!< Hello components mismatch\n    UnsuppHashType =    0x51,    //!< Hash type not supported\n    UnsuppCiphertype =  0x52,    //!< Cipher type not supported\n    UnsuppPKExchange =  0x53,    //!< Public key exchange not supported\n    UnsuppSRTPAuthTag = 0x54,    //!< SRTP auth. tag not supported\n    UnsuppSASScheme =   0x55,    //!< SAS scheme not supported\n    NoSharedSecret =    0x56,    //!< No shared secret available, DH mode required\n    DHErrorWrongPV =    0x61,    //!< DH Error: bad pvi or pvr ( == 1, 0, or p-1)\n    DHErrorWrongHVI =   0x62,    //!< DH Error: hvi != hashed data\n    SASuntrustedMiTM =  0x63,    //!< Received relayed SAS from untrusted MiTM\n    ConfirmHMACWrong =  0x70,    //!< Auth. Error: Bad Confirm pkt HMAC\n    NonceReused =       0x80,    //!< Nonce reuse\n    EqualZIDHello =     0x90,    //!< Equal ZIDs in Hello\n    GoCleatNotAllowed = 0x100,   //!< GoClear packet received, but not allowed\n    IgnorePacket =      0x7fffffff\n};\n\n/**\n * Information codes for the Enrollment user callbacks.\n */\nenum InfoEnrollment {\n    EnrollmentRequest = 0,          //!< Aks user to confirm or deny an Enrollemnt request\n    EnrollmentReconfirm,            //!< User already enrolled, ask re-confirmation\n    EnrollmentCanceled,             //!< User did not confirm the PBX enrollement\n    EnrollmentFailed,               //!< Enrollment process failed, no PBX secret available\n    EnrollmentOk                    //!< Enrollment process for this PBX was ok\n};\n\n/**\n * Offsets into the ZRTP counter array.\n * \n */\n//!< How many Hello packet retries in detect state\n#define HelloRetry      0\n//!< How many Hello packet retries in Ack sent state\n#define HelloRetryAck   1\n//!< How many Commit packet retries\n#define CommitRetry     2\n//!< How many DhPart2 packet retries\n#define DhPart2Retry    3\n//!< How many Confirm2 packet retries\n#define Confirm2Retry   4\n//!< How many Error packet retries\n#define ErrorRetry      5\n\n\n\n}\n\n/**\n * @brief Codes and structure for SRTP error trace data\n */\n\n#define RTP_HEADER_LENGTH 12\n\ntypedef enum {\n    DecodeError = 1,\n    ReplayError = 2,\n    AuthError   = 3\n} SrtpErrorType;\n\n/**\n * @brief Trace data of SRTP packet in case of unprotect error.\n */\ntypedef struct _SrtpErrorData {\n    SrtpErrorType errorType;\n    uint32_t rtpHeader[RTP_HEADER_LENGTH / sizeof(uint32_t)];\n    size_t length;\n    uint64_t guessedIndex;\n} SrtpErrorData;\n\n\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpConfigure.h",
    "content": "/*\n  Copyright (C) 2009 - 2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef _ZRTPCONFIGURE_H_\n#define _ZRTPCONFIGURE_H_\n\n/**\n * @file ZrtpConfigure.h\n * @brief The ZRTP configure functions\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <stdio.h>\n#include <stdint.h>\n#include <list>\n#include <string>\n#include <vector>\n#include <string.h>\n\n#include <libzrtpcpp/ZrtpCallback.h>\n\n/**\n * This enumerations list all configurable algorithm types.\n */\n\nenum AlgoTypes {\n    Invalid = 0, HashAlgorithm = 1, CipherAlgorithm, PubKeyAlgorithm, SasType, AuthLength\n};\n\ntypedef void(*encrypt_t)(uint8_t*, int32_t, uint8_t*, uint8_t*, int32_t);\ntypedef void(*decrypt_t)(uint8_t*, int32_t, uint8_t*, uint8_t*, int32_t);\n\n/**\n * The algorithm enumration class.\n *\n * This simple class is just a container of an algorithm's name and\n * its associated algorithm type. We use this class together with the\n * EnumBase class to implement a Java-like enum class functionality\n * (not fully, but OK for our use case).\n *\n * An application shall use the get / check methods to retrieve information.\n */\nclass AlgorithmEnum {\npublic:\n    /**\n     * Create an AlgorithmEnum object.\n     *\n     * @param type\n     *    Defines the algorithm type\n     * @param name\n     *    Set the names of the algorithm. The name is copied\n     *    and the call may reuse the space.\n     * @param klen\n     *    The key length for this algorihm in byte, for example 16 or 32\n     * @param ra\n     *    A human readable short string that describes the algorihm.\n     * @param en\n     *    Pointer to the encryption function of this algorithn\n     * @param de\n     *    Pointer to the decryption funtions of this algorithm.\n     * @param alId\n     *    The algorithm id used by SRTP to identify an algorithm type, for\n     *    example Skein, Sha1, Aes, ...\n     *\n     * @see AlgoTypes\n     */\n    AlgorithmEnum(const AlgoTypes type, const char* name, int32_t klen,\n                  const char* ra, encrypt_t en, decrypt_t de, SrtpAlgorithms alId);\n\n    /**\n     * AlgorithmEnum destructor\n     */\n    ~AlgorithmEnum();\n\n    /**\n     * Get the algorihm's name\n     *\n     * @returns\n     *    Algorithm's name as null terminated C-string. The\n     *    application must not free this memory.\n     */\n    const char* getName();\n\n    /**\n     * Get the algorihm's readable name\n     *\n     * @returns\n     *    Algorithm's readable name as null terminated C-string. The\n     *    application must not free this memory.\n     */\n    const char* getReadable();\n\n    /**\n     * Get the algorihm's key length.\n     *\n     * @returns\n     *    An integer definig the key length in bytes.\n     */\n    int getKeylen();\n\n    /**\n     * Get the algorihm's integer id.\n     *\n     * @returns\n     *    An integer that defines the algorithm.\n     */\n    SrtpAlgorithms getAlgoId();\n    /**\n     * Get the algorihm's key length.\n     *\n     * @returns\n     *    An integer definig the key length in bytes.\n     */\n    encrypt_t getEncrypt();\n\n    /**\n     * Get the algorihm's key length.\n     *\n     * @returns\n     *    An integer definig the key length in bytes.\n     */\n    decrypt_t getDecrypt();\n\n    /**\n     * Get the algorithm type of this AlgorithmEnum object.\n     *\n     * @returns\n     *     The algorithm type.\n     *\n     * @see AlgoTypes\n     */\n    AlgoTypes getAlgoType();\n\n    /**\n     * Check if this AlgorithmEnum object is valid\n     *\n     * @returns\n     *    @c true if the object is valid, @c false otherwise\n     */\n    bool isValid();\n\nprivate:\n    AlgoTypes algoType;\n    std::string algoName;\n    int32_t   keyLen;\n    std::string readable;\n    encrypt_t encrypt;\n    decrypt_t decrypt;\n    SrtpAlgorithms   algoId;\n};\n\n/**\n * EnumBase provides methods to store and access algorithm enumerations of\n * a specific algorithm type.\n *\n * An application shall use the get / check methods to retrieve information\n * from the preset Algorithm Enumerations.\n *\n * @see AlgoTypes\n * @see zrtpHashes\n * @see zrtpSymCiphers\n * @see zrtpPubKeys\n * @see zrtpSasTypes\n * @see zrtpAuthLengths\n */\nclass __EXPORT EnumBase {\npublic:\n    /**\n     * Get an AlgorithmEnum by its name\n     *\n     * @param name\n     *    The name of the AlgorithmEnum to search.\n     * @returns\n     *    The AlgorithmEnum if found or an invalid AlgorithmEnum if the name\n     *    was not found\n     */\n    AlgorithmEnum& getByName(const char* name);\n\n    /**\n     * Return all names of all currently stored AlgorithmEnums\n     *\n     * @return\n     *    A C++ std::list of C++ std::strings that contain the names.\n     */\n    std::list<std::string>* getAllNames();\n\n    /**\n     * Get the number of currently stored AlgorithmEnums\n     *\n     * @return\n     *    The number of currently stored AlgorithmEnums\n     */\n    int getSize();\n\n    /**\n     * Get the AlgoTypes to which this EnumBase belongs.\n     *\n     * @return\n     *     The AlgoTypes of this EnumBase.\n     * @see AlgoTypes.\n     */\n    AlgoTypes getAlgoType();\n\n    /**\n     * Return the AlgorithmEnum by its ordinal number\n     *\n     * @param ord\n     *     The ordinal number of the AlgorithmEnum.\n     * @return\n     *     The AlgorithmEnum if found, an invalid Algorithm otherwise.\n     */\n    AlgorithmEnum& getByOrdinal(int ord);\n\n    /**\n     * Get the ordinal number of an AlgorithmEnum\n     *\n     * @param algo\n     *     Return toe ordinal numer of this AlgorithmEnum.\n     *\n     * @return\n     *    Return the ordinal number of this AlgorithmEnum if found,\n     *    -1 otherwise.\n     */\n    int getOrdinal(AlgorithmEnum& algo);\n\nprotected:\n    EnumBase(AlgoTypes algo);\n    ~EnumBase();\n    void insert(const char* name);\n    void insert(const char* name, int32_t klen,\n                const char* ra, encrypt_t en, decrypt_t de, SrtpAlgorithms alId);\n\nprivate:\n    AlgoTypes algoType;\n    std::vector <AlgorithmEnum* > algos;\n};\n\n/**\n * The enumaration subclasses that contain the supported algorithm enumerations.\n */\nclass __EXPORT HashEnum : public EnumBase {\npublic:\n    HashEnum();\n    ~HashEnum();\n};\n\nclass __EXPORT SymCipherEnum : public EnumBase {\npublic:\n    SymCipherEnum();\n    ~SymCipherEnum();\n};\n\nclass __EXPORT PubKeyEnum : public EnumBase {\npublic:\n    PubKeyEnum();\n    ~PubKeyEnum();\n};\n\nclass __EXPORT SasTypeEnum : public EnumBase {\npublic:\n    SasTypeEnum();\n    ~SasTypeEnum();\n};\n\nclass __EXPORT AuthLengthEnum : public EnumBase {\npublic:\n    AuthLengthEnum();\n    ~AuthLengthEnum();\n};\n\nextern __EXPORT HashEnum zrtpHashes;\nextern __EXPORT SymCipherEnum zrtpSymCiphers;\nextern __EXPORT PubKeyEnum zrtpPubKeys;\nextern __EXPORT SasTypeEnum zrtpSasTypes;\nextern __EXPORT AuthLengthEnum zrtpAuthLengths;\n\n/**\n * ZRTP configuration data.\n *\n * This class contains data and functions to set ZRTP configuration data.\n * An application may use this class to set configuration information for\n * ZRTP. ZRTP uses this configuration information to announce various\n * algorithms via its Hello message. An application may use this class to\n * restrict or allow use of algorithms.\n *\n * The constructor does not set any algorithms, thus it is an empty\n * configuration. An application may use this empty configuration and\n * hand it over to ZRTP. In this case ZRTP does not announce any algorithms\n * in its Hello message and uses mandatory algorithms only.\n *\n * An application can configure implemented algorithms only.\n */\nclass __EXPORT ZrtpConfigure {\npublic:\n    ZrtpConfigure();         /* Creates Configuration data */\n    ~ZrtpConfigure();\n\n    /**\n     * Define the algorithm selection policies.\n     */\n    typedef enum _policies {\n        Standard = 1,\n        PreferNonNist = 2\n    } Policy;\n\n    /**\n     * Set the maximum number of algorithms per algorithm type that an application can\n     * configure.\n     */\n    static const int maxNoOfAlgos = 7;\n    /**\n     * Convenience function that sets a pre-defined standard configuration.\n     *\n     * The standard configuration consists of the following algorithms:\n     * <ul>\n     * <li> Hash: SHA256 </li>\n     * <li> Symmetric Cipher: AES 128, AES 256 </li>\n     * <li> Public Key Algorithm: DH2048, DH3027, MultiStream </li>\n     * <li> SAS type: libase 32 </li>\n     * <li> SRTP Authentication lengths: 32, 80 </li>\n     *</ul>\n     */\n    void setStandardConfig();\n\n    /**\n     * Convenience function that sets the mandatory algorithms only.\n     *\n     * Mandatory algorithms are:\n     * <ul>\n     * <li> Hash: SHA256 </li>\n     * <li> Symmetric Cipher: AES 128 </li>\n     * <li> Public Key Algorithm: DH3027, MultiStream </li>\n     * <li> SAS type: libase 32 </li>\n     * <li> SRTP Authentication lengths: 32, 80 </li>\n     *</ul>\n     */\n    void setMandatoryOnly();\n\n    /**\n     * Clear all configuration data.\n     *\n     * The functions clears all configuration data.\n     */\n    void clear();\n\n    /**\n     * Add an algorithm to configuration data.\n     *\n     * Adds the specified algorithm to the configuration data.\n     * If no free configuration data slot is available the\n     * function does not add the algorithm and returns -1. The\n     * methods appends the algorithm to the existing algorithms.\n     *\n     * @param algoType\n     *    Specifies which algorithm type to select\n     * @param algo\n     *    The enumeration of the algorithm to add.\n     * @return\n     *    Number of free configuration data slots or -1 on error\n     */\n    int32_t addAlgo(AlgoTypes algoType, AlgorithmEnum& algo);\n\n    /**\n     * Add an algorithm to configuration data at given index.\n     *\n     * Adds the specified algorithm to the configuration data vector\n     * at a given index. If the index is larger than the actual size\n     * of the configuration vector the method just appends the algorithm.\n     *\n     * @param algoType\n     *    Specifies which algorithm type to select\n     * @param algo\n     *    The enumeration of the algorithm to add.\n     * @param index\n     *    The index where to add the algorihm\n     * @return\n     *    Number of free configuration data slots or -1 on error\n     */\n    int32_t addAlgoAt(AlgoTypes algoType, AlgorithmEnum& algo, int32_t index);\n\n    /**\n     * Remove a algorithm from configuration data.\n     *\n     * Removes the specified algorithm from configuration data. If\n     * the algorithm was not configured previously the function does\n     * not modify the configuration data and returns the number of\n     * free configuration data slots.\n     *\n     * If an application removes all algorithms then ZRTP does not\n     * include any algorithm into the hello message and falls back\n     * to a predefined mandatory algorithm.\n     *\n     * @param algoType\n     *    Specifies which algorithm type to select\n     * @param algo\n     *    The enumeration of the algorithm to remove.\n     * @return\n     *    Number of free configuration slots.\n     */\n    int32_t removeAlgo(AlgoTypes algoType, AlgorithmEnum& algo);\n\n    /**\n     * Returns the number of configured algorithms.\n     *\n     * @param algoType\n     *    Specifies which algorithm type to select\n     * @return\n     *    The number of configured algorithms (used configuration\n     *    data slots)\n     */\n    int32_t getNumConfiguredAlgos(AlgoTypes algoType);\n\n    /**\n     * Returns the identifier of the algorithm at index.\n     *\n     * @param algoType\n     *    Specifies which algorithm type to select\n     * @param index\n     *    The index in the list of the algorihm type\n     * @return\n     *    A pointer the the algorithm enumeration. If the index\n     *    does not point to a configured slot then the function\n     *    returns NULL.\n     *\n     */\n    AlgorithmEnum& getAlgoAt(AlgoTypes algoType, int32_t index);\n\n    /**\n     * Checks if the configuration data of the algorihm type already contains\n     * a specific algorithms.\n     *\n     * @param algoType\n     *    Specifies which algorithm type to select\n     * @param algo\n     *    The algorithm to check\n     * @return\n     *    True if the algorithm was found, false otherwise.\n     *\n     */\n    bool containsAlgo(AlgoTypes algoType, AlgorithmEnum& algo);\n\n    /**\n     * Enables or disables trusted MitM processing.\n     *\n     * For further details of trusted MitM processing refer to ZRTP\n     * specification, chapter 7.3\n     *\n     * @param yesNo\n     *    If set to true then trusted MitM processing is enabled.\n     */\n    void setTrustedMitM(bool yesNo);\n\n    /**\n     * Check status of trusted MitM processing.\n     *\n     * @return\n     *    Returns true if trusted MitM processing is enabled.\n     */\n    bool isTrustedMitM();\n\n    /**\n     * Enables or disables SAS signature processing.\n     *\n     * For further details of trusted MitM processing refer to ZRTP\n     * specification, chapter 7.2\n     *\n     * @param yesNo\n     *    If set to true then certificate processing is enabled.\n     */\n    void setSasSignature(bool yesNo);\n\n    /**\n     * Check status of SAS signature processing.\n     *\n     * @return\n     *    Returns true if certificate processing is enabled.\n     */\n    bool isSasSignature();\n\n    /**\n     * Enables or disables paranoid mode.\n     *\n     * For further explanation of paranoid mode refer to the documentation\n     * of ZRtp class.\n     *\n     * @param yesNo\n     *    If set to true then paranoid mode is enabled.\n     */\n    void setParanoidMode(bool yesNo);\n\n    /**\n     * Check status of paranoid mode.\n     *\n     * @return\n     *    Returns true if paranoid mode is enabled.\n     */\n    bool isParanoidMode();\n\n    /// Helper function to print some internal data\n    void printConfiguredAlgos(AlgoTypes algoTyp);\n\n    Policy getSelectionPolicy()         {return selectionPolicy;}\n    void setSelectionPolicy(Policy pol) {selectionPolicy = pol;}\n\n  private:\n    std::vector<AlgorithmEnum* > hashes;\n    std::vector<AlgorithmEnum* > symCiphers;\n    std::vector<AlgorithmEnum* > publicKeyAlgos;\n    std::vector<AlgorithmEnum* > sasTypes;\n    std::vector<AlgorithmEnum* > authLengths;\n\n    bool enableTrustedMitM;\n    bool enableSasSignature;\n    bool enableParanoidMode;\n\n\n    AlgorithmEnum& getAlgoAt(std::vector<AlgorithmEnum* >& a, int32_t index);\n    int32_t addAlgo(std::vector<AlgorithmEnum* >& a, AlgorithmEnum& algo);\n    int32_t addAlgoAt(std::vector<AlgorithmEnum* >& a, AlgorithmEnum& algo, int32_t index);\n    int32_t removeAlgo(std::vector<AlgorithmEnum* >& a,  AlgorithmEnum& algo);\n    int32_t getNumConfiguredAlgos(std::vector<AlgorithmEnum* >& a);\n    bool containsAlgo(std::vector<AlgorithmEnum* >& a, AlgorithmEnum& algo);\n    std::vector<AlgorithmEnum* >& getEnum(AlgoTypes algoType);\n\n    void printConfiguredAlgos(std::vector<AlgorithmEnum* >& a);\n\n    Policy selectionPolicy;\n\n  protected:\n\n  public:\n};\n\n/**\n * @}\n */\n#endif\n\n/** EMACS **\n * Local variables:\n * mode: c++\n * c-default-style: ellemtel\n * c-basic-offset: 4\n * End:\n */\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpCrc32.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPCRC32_H_\n#define _ZRTPCRC32_H_\n\n/**\n *\n * @file ZrtpCrc32.h\n * @brief Methods to compute the CRC32 checksum for ZRTP packets\n * \n * @ingroup GNU_ZRTP\n * @{\n * \n * @see ZrtpCallback\n */\n\n/**\n * Check if a buffer matches a given CRC32 checksum.\n * \n * @param buffer\n *     Pointer to the data buffer.\n * @param length\n *     Length in bytes of the data buffer.\n * @param crc32\n *     The CRC32 checksum.\n * \n * @return\n *    @c true if the CRC32 checksum matches the computed checksum of the\n *    buffer, @c false otherwise.\n */\nbool zrtpCheckCksum(uint8_t *buffer, uint16_t length, uint32_t crc32);\n\n/**\n * Generate a CRC32 checksum of a data buffer\n * \n * @param buffer\n *    Pointer to the buffer.\n * @param length\n *     Lenght of the buffer in bytes.\n * \n * @return\n *    A preliminary CRC32 checksum\n */\nuint32_t zrtpGenerateCksum(uint8_t *buffer, uint16_t length);\n\n/**\n * Close CRC32 computation.\n * \n * @param crc32\n *    A preliminary CRC32 checksum.\n * \n * @return\n *    The ready to use CRC32 checksum in host order.\n */\nuint32_t zrtpEndCksum(uint32_t crc32);\n\n/**\n * @}\n */\n#endif\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketBase.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef _ZRTPPACKETBASE_H_\n#define _ZRTPPACKETBASE_H_\n\n/**\n * @file ZrtpPacketBase.h\n * @brief The ZRTP message header class\n *\n * This class defines the ZRTP message header and provides access and\n * check methods.\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <stdio.h>\n#include <stdint.h>\n#include <string.h>\n#include <stdlib.h>\n\n#include <common/osSpecifics.h>\n\n#include <libzrtpcpp/zrtpPacket.h>\n#include <libzrtpcpp/ZrtpTextData.h>\n#include <libzrtpcpp/ZrtpConfigure.h>\n#include <libzrtpcpp/ZrtpCrc32.h>\n\n// #define DEBUGOUT(deb)   deb\n#define DEBUGOUT(deb)\n\n/*\n * This is the unique ZRTP ID in network order (PZ)\n */\nconst uint16_t zrtpId = 0x505a;\n\n/**\n * This is the base class for all ZRTP packets\n *\n * All other ZRTP packet classes inherit from this class. It does not have\n * an implementation of its own.\n *\n * The standard constructors of the subclasses usually initialize the @c allocate\n * field with their fixed data array which is large enough to hold all message\n * data. If an implementation needs to change this to use dynamic memory\n * allocation only that line in the subclasses must be changed and the destructors\n * should take care of memory management.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZrtpPacketBase {\n\n  private:\n\n  protected:\n      void* allocated;                  ///< Pointer to ZRTP message data\n      zrtpPacketHeader_t* zrtpHeader;   ///< points to the fixed ZRTP header structure\n\n  public:\n    /**\n     * Destructor is empty\n     */\n    virtual ~ZrtpPacketBase() {};\n\n    /**\n     * Get pointer to ZRTP header\n     *\n     * @return\n     *     Pointer to ZRTP header structure.\n     */\n    const uint8_t* getHeaderBase() { return (const uint8_t*)zrtpHeader; };\n\n    /**\n     * Check is this is a ZRTP message\n     *\n     * @return\n     *     @c true if check was ok\n     */\n    bool isZrtpPacket()            { return (zrtpNtohs(zrtpHeader->zrtpId) == zrtpId); };\n\n    /**\n     * Get the length in words of the ZRTP message\n     *\n     * @return\n     *     The length in words\n     */\n    uint16_t getLength()           { return zrtpNtohs(zrtpHeader->length); };\n\n    /**\n     * Return pointer to fixed length message type ASCII data\n     *\n     * @return\n     *     Pointer to ASCII character array\n     */\n    uint8_t* getMessageType()      { return zrtpHeader->messageType; };\n\n    /**\n     * Set the lenght field in the ZRTP header\n     *\n     * @param len\n     *     The length of the ZRTP message in words, host order\n     */\n    void setLength(uint16_t len)  { zrtpHeader->length = zrtpHtons(len); };\n\n    /**\n     * Copy the message type ASCII data to ZRTP message type field\n     *\n     * @param msg\n     *     Pointer to message type ASCII character array\n     */\n    void setMessageType(uint8_t *msg)\n        { memcpy(zrtpHeader->messageType, msg, sizeof(zrtpHeader->messageType)); };\n\n    /**\n     * Initializes the ZRTP Id field\n     */\n    void setZrtpId()              { zrtpHeader->zrtpId = zrtpHtons(zrtpId); }\n};\n\n/**\n * @}\n */\n#endif // ZRTPPACKETBASE\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketClearAck.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPPACKETCLEARACK_H_\n#define _ZRTPPACKETCLEARACK_H_\n\n/**\n * @file ZrtpPacketClearAck.h\n * @brief The ZRTP ClearAck message\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n/**\n * Implement the ClearAck packet - Currently not used\n *\n * The ZRTP simple message ClearAck. The implementation sends this\n * after switching to clear mode (non-SRTP mode).\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\nclass __EXPORT ZrtpPacketClearAck : public ZrtpPacketBase {\n\n public:\n    ZrtpPacketClearAck();       /// Creates a ClearAck packet with default data\n    ZrtpPacketClearAck(uint8_t* data);  /// Creates a ClearAck packet from received data\n    virtual ~ZrtpPacketClearAck();\n\n private:\n     ClearAckPacket_t data;\n};\n\n/**\n * @}\n */\n#endif // ZRTPPACKETCLEARACK\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketCommit.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n#ifndef _ZRTPPACKETCOMMIT_H_\n#define _ZRTPPACKETCOMMIT_H_\n\n/**\n * @file ZrtpPacketCommit.h\n * @brief The ZRTP Commit message\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n// PRSH here only for completeness. We don't support PRSH in the other ZRTP parts.\n#define COMMIT_DH_EX      29\n#define COMMIT_MULTI      25\n#define COMMIT_PRSH       27\n\n/**\n * Implement the Commit packet.\n *\n * The ZRTP message Commit. The ZRTP implementation sends or receives\n * this message to commit the crypto parameters offered during a Hello\n * message.\n *\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZrtpPacketCommit : public ZrtpPacketBase {\n\n protected:\n    Commit_t* commitHeader;     ///< Points to Commit message part\n\n public:\n    typedef enum _commitType {\n        DhExchange =  1,\n        MultiStream = 2\n    } commitType;\n\n    /// Creates a Commit packet with default data\n    ZrtpPacketCommit();\n\n    /// Creates a Commit packet from received data\n    ZrtpPacketCommit(uint8_t* data);\n\n    /// Normal destructor\n    virtual ~ZrtpPacketCommit();\n\n    /// Get pointer to hash algorithm type field, a fixed length character array\n    uint8_t* getHashType()    { return commitHeader->hash; };\n\n    /// Get pointer to cipher algorithm type field, a fixed length character array\n    uint8_t* getCipherType()  { return commitHeader->cipher; };\n\n    /// Get pointer to SRTP authentication algorithm type field, a fixed length character array\n    uint8_t* getAuthLen()     { return commitHeader->authlengths; };\n\n    /// Get pointer to key agreement algorithm type field, a fixed length character array\n    uint8_t* getPubKeysType() { return commitHeader->pubkey; };\n\n    /// Get pointer to SAS algorithm type field, a fixed length character array\n    uint8_t* getSasType()     { return commitHeader->sas; };\n\n    /// Get pointer to ZID field, a fixed length byte array\n    uint8_t* getZid()         { return commitHeader->zid; };\n\n    /// Get pointer to HVI field, a fixed length byte array\n    uint8_t* getHvi()         { return commitHeader->hvi; };\n\n    /// Get pointer to NONCE field, a fixed length byte array, overlaps HVI field\n    uint8_t* getNonce()       { return commitHeader->hvi; };\n\n    /// Get pointer to hashH2 field, a fixed length byte array\n    uint8_t* getH2()          { return commitHeader->hashH2; };\n\n    /// Get pointer to MAC field, a fixed length byte array\n    uint8_t* getHMAC()        { return commitHeader->hmac; };\n\n    /// Get pointer to MAC field during multi-stream mode, a fixed length byte array\n    uint8_t* getHMACMulti()   { return commitHeader->hmac-4*ZRTP_WORD_SIZE; };\n\n    /// Check if packet length makes sense.\n    bool isLengthOk(commitType type)   {int32_t len = getLength(); \n                                        return ((type == DhExchange) ? len == COMMIT_DH_EX : len == COMMIT_MULTI);}\n\n    /// Set hash algorithm type field, fixed length character field\n    void setHashType(uint8_t* text)    { memcpy(commitHeader->hash, text, ZRTP_WORD_SIZE); };\n\n    /// Set cipher algorithm type field, fixed length character field\n    void setCipherType(uint8_t* text)  { memcpy(commitHeader->cipher, text, ZRTP_WORD_SIZE); };\n\n    /// Set SRTP authentication algorithm algorithm type field, fixed length character field\n    void setAuthLen(uint8_t* text)     { memcpy(commitHeader->authlengths, text, ZRTP_WORD_SIZE); };\n\n    /// Set key agreement algorithm type field, fixed length character field\n    void setPubKeyType(uint8_t* text)  { memcpy(commitHeader->pubkey, text, ZRTP_WORD_SIZE); };\n\n    /// Set SAS algorithm type field, fixed length character field\n    void setSasType(uint8_t* text)     { memcpy(commitHeader->sas, text, ZRTP_WORD_SIZE); };\n\n    /// Set ZID field, a fixed length byte array\n    void setZid(uint8_t* text)         { memcpy(commitHeader->zid, text, sizeof(commitHeader->zid)); };\n\n    /// Set HVI field, a fixed length byte array\n    void setHvi(uint8_t* text)         { memcpy(commitHeader->hvi, text, sizeof(commitHeader->hvi)); };\n\n    /// Set conce field, a fixed length byte array, overlapping HVI field\n    void setNonce(uint8_t* text);\n\n    /// Set hashH2 field, a fixed length byte array\n    void setH2(uint8_t* hash)          { memcpy(commitHeader->hashH2, hash, sizeof(commitHeader->hashH2)); };\n\n    /// Set MAC field, a fixed length byte array\n    void setHMAC(uint8_t* hash)        { memcpy(commitHeader->hmac, hash, sizeof(commitHeader->hmac)); };\n\n    /// Set MAC field during multi-stream mode, a fixed length byte array\n    void setHMACMulti(uint8_t* hash)   { memcpy(commitHeader->hmac-4*ZRTP_WORD_SIZE, hash, sizeof(commitHeader->hmac)); };\n\n private:\n     CommitPacket_t data;\n};\n\n/**\n * @}\n */\n#endif // ZRTPPACKETCOMMIT\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPPACKETCON2FACK_H_\n#define _ZRTPPACKETCON2FACK_H_\n\n/**\n * @file ZrtpPacketConf2Ack.h\n * @brief The ZRTP Conf2Ack message\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n/**\n * Implement the Conf2Ack packet.\n *\n * The ZRTP simple message Conf2Ack. The implementation sends this\n * after receiving and checking the Confirm2 message.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZrtpPacketConf2Ack : public ZrtpPacketBase {\n\n public:\n    /// Creates a Conf2Ack packet with default data\n    ZrtpPacketConf2Ack();\n\n    ///Creates a Conf2Ack packet from received data\n    ZrtpPacketConf2Ack(char* data);\n\n    /// Normal destructor\n    virtual ~ZrtpPacketConf2Ack();\n\n private:\n     Conf2AckPacket_t data;\n};\n\n/**\n * @}\n */\n#endif // ZRTPPACKETCONF2ACK\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketConfirm.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPPACKETCONFIRM_H_\n#define _ZRTPPACKETCONFIRM_H_\n\n/**\n * @file ZrtpPacketConfirm.h\n * @brief The ZRTP Confirm message\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n/**\n * Implement the Confirm packet.\n *\n * The ZRTP message Confirm. The implementation sends this\n * to confirm the switch to SRTP (encrypted) mode. The contents of\n * the Confirm message are encrypted, thus the implementation\n * can check if the secret keys work.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZrtpPacketConfirm : public ZrtpPacketBase {\n\n    private:\n        Confirm_t* confirmHeader;   ///< Point to the Confirm message part\n\n    public:\n        /// Creates a Confirm packet with default data\n        ZrtpPacketConfirm();\n\n        /// Creates a Confirm packet with default data and a given signature length\n        ZrtpPacketConfirm(uint32_t sl);\n\n        /// Creates a Confirm packet from received data\n        ZrtpPacketConfirm(uint8_t* d);\n\n        /// Normal destructor\n        virtual ~ZrtpPacketConfirm();\n\n        /// Check if SAS verify flag is set\n        const bool isSASFlag()            { return (confirmHeader->flags & 0x4) == 0x4 ? true : false; }\n\n        /// Check if PBXEnrollment flag is set\n        const bool isPBXEnrollment()      { return (confirmHeader->flags & 0x8) == 0x8 ? true : false; }\n\n        /// Get pointer to filler bytes (contains one bit of signature length)\n        const uint8_t* getFiller()        { return confirmHeader->filler; }\n\n        /// Get pointer to IV data, fixed byte array\n        const uint8_t* getIv()            { return confirmHeader->iv; }\n\n        /// Get pointer to MAC data, fixed byte array\n        const uint8_t* getHmac()          { return confirmHeader->hmac; }\n\n        /// Get Expiration time data\n        const uint32_t getExpTime()       { return zrtpNtohl(confirmHeader->expTime); }\n\n        /// Get pointer to initial hash chain (H0) data, fixed byte array\n        uint8_t* getHashH0()              { return confirmHeader->hashH0; }\n\n        /// Get pointer to signature data, variable length, refer to getSignatureLength()\n        const uint8_t* getSignatureData() { return ((uint8_t*)&confirmHeader->expTime) + 4; }\n\n        /// get the signature length in words\n        int32_t getSignatureLength();\n\n        /// Check if packet length makes sense. Confirm packets are 19 words at minumum\n        bool isLengthOk()             {return (getLength() >= 19); }\n\n        bool isSignatureLengthOk();\n\n        /// set SAS verified flag\n        void setSASFlag()            { confirmHeader->flags |= 0x4; }\n\n        /// set setPBXEnrollment flag\n        void setPBXEnrollment()      { confirmHeader->flags |= 0x8; }\n\n        /// Set MAC data, fixed length byte array\n        void setHmac(uint8_t* text)  { memcpy(confirmHeader->hmac, text, sizeof(confirmHeader->hmac)); }\n\n        /// Set IV data, fixed length byte array\n        void setIv(uint8_t* text)    { memcpy(confirmHeader->iv, text, sizeof(confirmHeader->iv)); }\n\n        /// Set expiration time data\n        void setExpTime(uint32_t t)  { confirmHeader->expTime = zrtpHtonl(t); }\n\n        /// Set initial hash chain (H0) data, fixed length byte array\n        void setHashH0(uint8_t* t)   { memcpy(confirmHeader->hashH0, t, sizeof(confirmHeader->hashH0)); }\n\n        /// Set signature data, length of the signature data in bytes and must be a multiple of 4.\n        bool setSignatureData(uint8_t* data, int32_t length);\n\n        /// Set signature length in words\n        bool setSignatureLength(uint32_t sl);\n\n    private:\n        void initialize();\n     // Confirm packet is of variable length. It maximum size is 524 words:\n     // - 11 words fixed size\n     // - up to 513 words variable part, depending if signature is present and its length.\n     // This leads to a maximum of 4*524=2096 bytes.\n        uint8_t data[2100];       // large enough to hold a full blown Confirm packet\n\n};\n\n/**\n * @}\n */\n#endif // ZRTPPACKETCONFIRM\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketDHPart.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPPACKETDHPART_H_\n#define _ZRTPPACKETDHPART_H_\n\n/**\n * @file ZrtpPacketDHPart.h\n * @brief The ZRTP DHPart message\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n/**\n * Implement the DHPart packet.\n *\n * The ZRTP message DHPart. The implementation sends this\n * to exchange the Diffie-Helman public keys and the shared\n * secrets between the two parties.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZrtpPacketDHPart : public ZrtpPacketBase {\n\n protected:\n    uint8_t *pv;                ///< points to public key value inside DH message\n    DHPart_t* DHPartHeader;     ///< points to DH message structure\n    int32_t dhLength;           ///< length of DH message, DH message has variable length\n\n public:\n    /// Creates a DHPart packet no data, must use setPubKeyType(...)\n    ZrtpPacketDHPart();\n\n    /// Creates a DHPart packet with default data and a give public key type\n    ZrtpPacketDHPart(const char* pkt);\n\n    /// Creates a DHPart packet from received data\n    ZrtpPacketDHPart(uint8_t* data);\n\n    /// Standard destructor\n    virtual ~ZrtpPacketDHPart();\n\n    /// Get pointer to public key value, variable length byte array\n    uint8_t* getPv()             { return pv; }\n\n    /// Get pointer to first retained secretd id, fixed length byte array\n    uint8_t* getRs1Id()          { return DHPartHeader->rs1Id; };\n\n    /// Get pointer to second retained secretd id, fixed length byte array\n    uint8_t* getRs2Id()          { return DHPartHeader->rs2Id; };\n\n    /// Get pointer to additional retained secretd id, fixed length byte array\n    uint8_t* getAuxSecretId()    { return DHPartHeader->auxSecretId; };\n\n    /// Get pointer to PBX retained secretd id, fixed length byte array\n    uint8_t* getPbxSecretId()    { return DHPartHeader->pbxSecretId; };\n\n    /// Get pointer to first hash (H1) for hash chain, fixed length byte array\n    uint8_t* getH1()             { return DHPartHeader->hashH1; };\n\n    /// Get pointer to HMAC, fixed length byte array\n    uint8_t* getHMAC()           { return pv+dhLength; };\n\n    /// Check if packet length makes sense. DHPart packets are 29 words at minumum, using E255\n    bool isLengthOk()            {return (getLength() >= 29);}\n\n    /// Setpublic key value, variable length byte array\n    void setPv(uint8_t* text)         { memcpy(pv, text, dhLength); };\n\n    /// Set first retained secretd id, fixed length byte array\n    void setRs1Id(uint8_t* text)      { memcpy(DHPartHeader->rs1Id, text, sizeof(DHPartHeader->rs1Id)); };\n\n    /// Set second retained secretd id, fixed length byte array\n    void setRs2Id(uint8_t* text)      { memcpy(DHPartHeader->rs2Id, text, sizeof(DHPartHeader->rs2Id)); };\n\n    /// Set additional retained secretd id, fixed length byte array\n    void setAuxSecretId(uint8_t* t)   { memcpy(DHPartHeader->auxSecretId, t, sizeof(DHPartHeader->auxSecretId)); };\n\n    /// Set PBX retained secretd id, fixed length byte array\n    void setPbxSecretId(uint8_t* t)   { memcpy(DHPartHeader->pbxSecretId,t, sizeof(DHPartHeader->pbxSecretId)); };\n\n    /// Set first hash (H1) of hash chain, fixed length byte array\n    void setH1(uint8_t* t)            { memcpy(DHPartHeader->hashH1, t, sizeof(DHPartHeader->hashH1)); };\n\n    /// Set key agreement type, fixed size character array\n    void setPubKeyType(const char* pkt);\n\n    /// Set first MAC, fixed length byte array\n    void setHMAC(uint8_t* t)          { memcpy(pv+dhLength, t, 2*ZRTP_WORD_SIZE); };\n\n private:\n    void initialize();\n    // SupportedPubKeys pktype;\n     // DHPart packet is of variable length. It maximum size is 141 words:\n     // - 13 words fixed sizze\n     // - up to 128 words variable part, depending on DH algorithm\n     //   leads to a maximum of 4*141=564 bytes.\n     uint8_t data[768];       // large enough to hold a full blown DHPart packet\n};\n\n/**\n * @}\n */\n#endif // ZRTPPACKETDHPART\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketError.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPPACKETERROR_H_\n#define _ZRTPPACKETERROR_H_\n\n/**\n * @file ZrtpPacketError.h\n * @brief The ZRTP Error message\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n/**\n * Implement the Error packet.\n *\n * The ZRTP simple message Error. The implementation sends this\n * after detecting an error.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZrtpPacketError : public ZrtpPacketBase {\n\n protected:\n    Error_t* errorHeader;   ///< Points to Error message\n\n public:\n    /// Creates a Error packet with default data\n    ZrtpPacketError();\n\n    /// Creates a Error packet from received data\n    ZrtpPacketError(uint8_t* data);\n\n    virtual ~ZrtpPacketError();\n\n    /// Get the error code from Error message\n    uint32_t getErrorCode() { return zrtpNtohl(errorHeader->errorCode); };\n\n    /// Set error code in Error message\n    void setErrorCode(uint32_t code) {errorHeader->errorCode = zrtpHtonl(code); };\n\n private:\n     ErrorPacket_t data;\n};\n\n/**\n * @}\n */\n#endif // ZRTPPACKETERROR\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h",
    "content": "/*\n  Copyright (C) 2007-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPPACKETERRORACK_H_\n#define _ZRTPPACKETERRORACK_H_\n\n/**\n * @file ZrtpPacketErrorAck.h\n * @brief The ZRTP ErrorAck message\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n/**\n * Implement the ErrorAck packet.\n *\n * The ZRTP simple message ErrorAck. The implementation sends this\n * after receiving and checking the Error message.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\nclass __EXPORT ZrtpPacketErrorAck : public ZrtpPacketBase {\n\n public:\n    /// Creates a ErrorAck packet with default data\n    ZrtpPacketErrorAck();\n\n    /// Creates a ErrorAck packet from received data\n    ZrtpPacketErrorAck(uint8_t* data);\n    virtual ~ZrtpPacketErrorAck();\n\n private:\n     ErrorAckPacket_t data;\n};\n\n/**\n * @}\n */\n#endif  // _ZRTPPACKETERRORACK_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketGoClear.h",
    "content": "/*\n  Copyright (C) 2006-2007 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPPACKETGOCLEAR_H_\n#define _ZRTPPACKETGOCLEAR_H_\n\n/**\n * @file ZrtpPacketGoClear.h\n * @brief The ZRTP GoClear message\n *\n * GNU ZRTP does not implement GoClear feature\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n/**\n * Implement the GoClear packet.\n *\n * The ZRTP message GoClear. The implementation sends this\n * to order the peer to switch to clear mode (non-SRTP mode).\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZrtpPacketGoClear : public ZrtpPacketBase {\n\n protected:\n    GoClear_t* clearHeader;\n\n public:\n    /// Creates a GoCLear packet with default data\n    ZrtpPacketGoClear();\n\n    /// Creates a GoClear packet from received data\n    ZrtpPacketGoClear(uint8_t* data);\n\n    virtual ~ZrtpPacketGoClear();\n\n    /// Not used\n    const uint8_t* getClearHmac() { return clearHeader->clearHmac; };\n\n    /// Not used\n    void setClearHmac(uint8_t *text) { memcpy(clearHeader->clearHmac, text, 32); };\n\n    /// Not used\n    void clrClearHmac()              { memset(clearHeader->clearHmac, 0, 32); };\n\n private:\n     GoClearPacket_t data;\n};\n\n/**\n * @}\n */\n#endif // ZRTPPACKETGOCLEAR\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketHello.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPPACKETHELLO_H_\n#define _ZRTPPACKETHELLO_H_\n\n/**\n * @file ZrtpPacketHello.h\n * @brief The ZRTP Hello message\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n#define HELLO_FIXED_PART_LEN  22\n\n/**\n * Implement the Hello packet.\n *\n * The ZRTP Hello message. The implementation sends this\n * to start the ZRTP negotiation sequence. The Hello message\n * offers crypto methods and parameters to the other party. The\n * other party selects methods and parameters it can support\n * and uses the Commit message to commit these.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZrtpPacketHello : public ZrtpPacketBase {\n\n protected:\n    Hello_t* helloHeader;   ///< Point to the Hello message part\n\n    int32_t nHash,          ///< number of hash algorithms offered\n    nCipher,                ///< number of cipher algorithms offered\n    nPubkey,                ///< number of key agreement algorithms offered\n    nSas,                   ///< number of SAS algorithms offered\n    nAuth;                  ///< number of SRTP authentication algorithms offered\n\n    int32_t oHash,          ///< offsets in bytes to hash algorithm names\n    oCipher,                ///< offsets in bytes to cipher algorithm names\n    oPubkey,                ///< offsets in bytes to key agreement algorithm names\n    oSas,                   ///< offsets in bytes to SAS algorithm names\n    oAuth,                  ///< offsets in bytes to SRTP authentication algorithm names\n    oHmac;                  ///< offsets in bytes to MAC of Hello message\n\n public:\n    /// Creates a Hello packet with default data\n    ZrtpPacketHello();\n\n    /// Creates a Hello packet from received data\n    ZrtpPacketHello(uint8_t *data);\n\n    virtual ~ZrtpPacketHello();\n\n    /**\n     * Set configure data and populate Hello message data.\n     *\n     * Fill in the offered Algorithm names and compute all offset to\n     * names and MAC. An application must call this method on Hello message\n     * objects created with the standard constructor (with default data)\n     * before the application can use most of the getter and setter methods.\n     *\n     * @param config\n     *    Pointer to ZrtpConfigure data.\n     */\n    void configureHello(ZrtpConfigure* config);\n\n    /// Get version number from Hello message, fixed ASCII character array\n    uint8_t* getVersion()  { return helloHeader->version; };\n\n     /// Get version number from Hello message as integer, only relvant digits converted\n    int32_t getVersionInt();\n\n    /// Get client id from Hello message, fixed ASCII character array\n    uint8_t* getClientId() { return helloHeader->clientId; };\n\n    /// Get H3 hash from Hello message, fixed byte array\n    uint8_t* getH3()       { return helloHeader->hashH3; };\n\n    /// Get client ZID from Hello message, fixed bytes array\n    uint8_t* getZid()      { return helloHeader->zid; };\n\n    /// Set version sting in Hello message, fixed ASCII character array\n    void setVersion(const uint8_t *text)     { memcpy(helloHeader->version, text,ZRTP_WORD_SIZE ); }\n\n    /// Set client id in Hello message, fixed ASCII character array\n    void setClientId(const uint8_t *t) { memcpy(helloHeader->clientId, t, sizeof(helloHeader->clientId)); }\n\n    /// Set H3 hash in Hello message, fixed byte array\n    void setH3(uint8_t *hash)          { memcpy(helloHeader->hashH3, hash, sizeof(helloHeader->hashH3)); }\n\n    /// Set client ZID in Hello message, fixed bytes array\n    void setZid(uint8_t *text)         { memcpy(helloHeader->zid, text, sizeof(helloHeader->zid)); }\n\n    /// Check passive mode (mode not implemented)\n    bool isPassive()       { return (helloHeader->flags & 0x10) == 0x10 ? true : false; };\n\n    /// Check if MitM flag is set\n    bool isMitmMode()       { return (helloHeader->flags & 0x20) == 0x20 ? true : false; };\n\n    /// Check if SAS sign flag is set\n    bool isSasSign()       { return (helloHeader->flags & 0x40) == 0x40 ? true : false; };\n\n    /// Get hash algorithm name at position n, fixed ASCII character array\n    uint8_t* getHashType(int32_t n)   { return ((uint8_t*)helloHeader)+oHash+(n*ZRTP_WORD_SIZE); }\n\n    /// Get ciper algorithm name at position n, fixed ASCII character array\n    uint8_t* getCipherType(int32_t n) { return ((uint8_t*)helloHeader)+oCipher+(n*ZRTP_WORD_SIZE); }\n\n    /// Get SRTP authentication algorithm name at position n, fixed ASCII character array\n    uint8_t* getAuthLen(int32_t n)    { return ((uint8_t*)helloHeader)+oAuth+(n*ZRTP_WORD_SIZE); }\n\n    /// Get key agreement algorithm name at position n, fixed ASCII character array\n    uint8_t* getPubKeyType(int32_t n) { return ((uint8_t*)helloHeader)+oPubkey+(n*ZRTP_WORD_SIZE); }\n\n    /// Get SAS algorithm name at position n, fixed ASCII character array\n    uint8_t* getSasType(int32_t n)    { return ((uint8_t*)helloHeader)+oSas+(n*ZRTP_WORD_SIZE); }\n\n    /// Get Hello MAC, fixed byte array\n    uint8_t* getHMAC()                { return ((uint8_t*)helloHeader)+oHmac; }\n\n    /// Set hash algorithm name at position n, fixed ASCII character array\n    void setHashType(int32_t n, int8_t* t)\n        { memcpy(((uint8_t*)helloHeader)+oHash+(n*ZRTP_WORD_SIZE), t, ZRTP_WORD_SIZE); }\n\n    /// Set ciper algorithm name at position n, fixed ASCII character array\n    void setCipherType(int32_t n, int8_t* t)\n        { memcpy(((uint8_t*)helloHeader)+oCipher+(n*ZRTP_WORD_SIZE), t, ZRTP_WORD_SIZE); }\n\n    /// Set SRTP authentication algorithm name at position n, fixed ASCII character array\n    void setAuthLen(int32_t n, int8_t* t)\n        { memcpy(((uint8_t*)helloHeader)+oAuth+(n*ZRTP_WORD_SIZE), t, ZRTP_WORD_SIZE); }\n\n    /// Set key agreement algorithm name at position n, fixed ASCII character array\n    void setPubKeyType(int32_t n, int8_t* t)\n        { memcpy(((uint8_t*)helloHeader)+oPubkey+(n*ZRTP_WORD_SIZE), t, ZRTP_WORD_SIZE); }\n\n    /// Set SAS algorithm name at position n, fixed ASCII character array\n    void setSasType(int32_t n, int8_t* t)\n        { memcpy(((uint8_t*)helloHeader)+oSas+(n*ZRTP_WORD_SIZE), t, ZRTP_WORD_SIZE); }\n\n    /// Set Hello MAC, fixed byte array\n    void setHMAC(uint8_t* t)\n        { memcpy(((uint8_t*)helloHeader)+oHmac, t, 2*ZRTP_WORD_SIZE); }\n\n    /// Get number of offered hash algorithms\n    int32_t getNumHashes()   {return nHash; }\n\n    /// Get number of offered cipher algorithms\n    int32_t getNumCiphers()  {return nCipher; }\n\n    /// Get number of offered key agreement algorithms\n    int32_t getNumPubKeys()  {return nPubkey; }\n\n    /// Get number of offered SAS algorithms\n    int32_t getNumSas()      {return nSas; }\n\n    /// Get number of offered SRTP authentication algorithms\n    int32_t getNumAuth()     {return nAuth; }\n\n    /// set MitM flag\n    void setMitmMode()       {helloHeader->flags |= 0x20; }\n\n    /// set SAS sign flag\n    void setSasSign()        {helloHeader->flags |= 0x40; }\n\n    /// Check if packet length matches\n    bool isLengthOk()        {return (computedLength == getLength());}\n\n private:\n     uint32_t computedLength;\n     // Hello packet is of variable length. It maximum size is 46 words:\n     // - 20 words fixed sizze\n     // - up to 35 words variable part, depending on number of algorithms\n     // leads to a maximum of 4*55=220 bytes.\n     uint8_t data[256];       // large enough to hold a full blown Hello packet\n};\n\n/**\n * @}\n */\n#endif // ZRTPPACKETHELLO\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPPACKETHELLOACK_H_\n#define _ZRTPPACKETHELLOACK_H_\n\n/**\n * @file ZrtpPacketHelloAck.h\n * @brief The ZRTP HelloAck message\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n/**\n * Implement the HelloAck packet.\n *\n * The ZRTP simple message HelloAck. The implementation sends this\n * after receiving a Hello packet.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZrtpPacketHelloAck : public ZrtpPacketBase {\n\n public:\n    /// Creates a HelloAck packet with default data\n    ZrtpPacketHelloAck();\n\n    /// Creates a HelloAck packet from received data\n    ZrtpPacketHelloAck(uint8_t* data);\n\n    virtual ~ZrtpPacketHelloAck();\n\n private:\n     HelloAckPacket_t data;\n};\n\n/**\n * @}\n */\n#endif // ZRTPPACKETHELLOACK\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketPing.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPPACKETPING_H_\n#define _ZRTPPACKETPING_H_\n\n/**\n * @file ZrtpPacketPing.h\n * @brief The ZRTP Ping message\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n/**\n * Implement the PingAck packet.\n *\n * The ZRTP simple message PingAck.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\nclass __EXPORT ZrtpPacketPing : public ZrtpPacketBase {\n\n protected:\n    Ping_t* pingHeader;     ///< Point the the Ping message\n\n public:\n    /// Creates a Ping message with default data\n    ZrtpPacketPing();\n\n    /// Creates a Ping message from received data\n    ZrtpPacketPing(uint8_t* data);\n\n    virtual ~ZrtpPacketPing();\n\n    /// Set ZRTP protocol version field, fixed ASCII character array\n    void setVersion(uint8_t *text)     { memcpy(pingHeader->version, text,ZRTP_WORD_SIZE ); }\n\n    /// Get the endpoit hash, fixed byte array\n    uint8_t* getEpHash()               { return pingHeader->epHash; }\n\n private:\n     PingPacket_t data;\n};\n\n/**\n * @}\n */\n\n#endif // ZRTPPACKETCLEARACK\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketPingAck.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPPACKETPINGACK_H_\n#define _ZRTPPACKETPINGACK_H_\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n/**\n * @file ZrtpPacketPingAck.h\n * @brief The ZRTP PingAck message\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n/**\n * Implement the PingAck packet.\n *\n * The ZRTP simple message PingAck.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\nclass __EXPORT ZrtpPacketPingAck : public ZrtpPacketBase {\n\n protected:\n    PingAck_t* pingAckHeader;   ///< Points to PingAck message\n\n public:\n    /// Creates a PingAck message with default data\n    ZrtpPacketPingAck();\n\n    /// Creates a PingAck message from received data\n    ZrtpPacketPingAck(uint8_t* data);\n\n    virtual ~ZrtpPacketPingAck();\n\n    /// Get SSRC from PingAck message\n    uint32_t getSSRC() { return zrtpNtohl(pingAckHeader->ssrc); };\n\n    /// Set ZRTP protocol version field, fixed ASCII character array\n    void setVersion(uint8_t *text)      { memcpy(pingAckHeader->version, text, ZRTP_WORD_SIZE ); }\n\n    /// Set SSRC in PingAck message\n    void setSSRC(uint32_t data)         {pingAckHeader->ssrc = zrtpHtonl(data); };\n\n    /// Set remote endpoint hash, fixed byte array\n    void setRemoteEpHash(uint8_t *hash) { memcpy(pingAckHeader->remoteEpHash, hash, sizeof(pingAckHeader->remoteEpHash)); }\n\n    /// Set local endpoint hash, fixed byte array\n    void setLocalEpHash(uint8_t *hash)  { memcpy(pingAckHeader->localEpHash, hash, sizeof(pingAckHeader->localEpHash)); }\n\n private:\n     PingAckPacket_t data;\n};\n\n/**\n * @}\n */\n#endif // ZRTPPACKETCLEARACK\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h",
    "content": "/*\n  Copyright (C) 2007-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPPACKETRELAYACK_H_\n#define _ZRTPPACKETRELAYACK_H_\n\n/**\n * @file ZrtpPacketRelayAck.h\n * @brief The ZRTP RelayAck message\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n/**\n * Implement the RelayAck packet.\n *\n * The ZRTP simple message RelayAck. The implementation sends this\n * after receiving and checking the SASrelay message.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\nclass __EXPORT ZrtpPacketRelayAck : public ZrtpPacketBase {\n\n public:\n    /// Creates a RelayAck packet with default data\n    ZrtpPacketRelayAck();\n\n    /// Creates a RelayAck packet from received data\n    ZrtpPacketRelayAck(uint8_t* data);\n    virtual ~ZrtpPacketRelayAck();\n\n private:\n     RelayAckPacket_t data;\n};\n\n/**\n * @}\n */\n#endif  // _ZRTPPACKETRELAYACK_H_\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPPACKETSASRELAY_H_\n#define _ZRTPPACKETSASRELAY_H_\n\n/**\n * @file ZrtpPacketSASrelay.h\n * @brief The ZRTP SAS Relay message\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n/**\n * Implement the Confirm packet.\n *\n * The ZRTP message Confirm. The implementation sends this\n * to confirm the switch to SRTP (encrypted) mode. The contents of\n * the Confirm message are encrypted, thus the implementation\n * can check if the secret keys work.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZrtpPacketSASrelay : public ZrtpPacketBase {\n\n    private:\n        SASrelay_t* sasRelayHeader;   ///< Point to the Confirm message part\n\n    public:\n        /// Creates a Confirm packet with default data\n        ZrtpPacketSASrelay();\n\n        /// Creates a Confirm packet with default data and a given signature length\n        ZrtpPacketSASrelay(uint32_t sl);\n\n        /// Creates a Confirm packet from received data\n        ZrtpPacketSASrelay(uint8_t* d);\n\n        /// Normal destructor\n        virtual ~ZrtpPacketSASrelay();\n\n        /// Check is SAS verify flag is set\n        const bool isSASFlag()            { return (sasRelayHeader->flags & 0x4) == 0x4 ? true : false; }\n\n        /// Get pointer to filler bytes (contains one bit of signature length)\n        const uint8_t* getFiller()        { return sasRelayHeader->filler; }\n\n        /// Get pointer to IV data, fixed byte array\n        const uint8_t* getIv()            { return sasRelayHeader->iv; }\n\n        /// Get pointer to MAC data, fixed byte array\n        const uint8_t* getHmac()          { return sasRelayHeader->hmac; }\n\n        /// Get pointer to new SAS rendering algorithm, fixed byte array\n        const uint8_t* getSasAlgo() {return sasRelayHeader->sas; }\n\n        /// Get pointer to new SAS hash data, fixed byte array\n        const uint8_t* getTrustedSas()    { return sasRelayHeader->trustedSasHash; }\n\n        /// get the signature length in words\n        uint32_t getSignatureLength();\n\n        /// Check if packet length makes sense. SAS rely packets are 19 words at minumum, they are similar to Confirm\n        bool isLengthOk()                 {return (getLength() >= 19);}\n\n        /// set SAS verified flag\n        void setSASFlag()            { sasRelayHeader->flags |= 0x4; }\n\n        /// Set MAC data, fixed length byte array\n        void setHmac(uint8_t* text)  { memcpy(sasRelayHeader->hmac, text, sizeof(sasRelayHeader->hmac)); }\n\n        /// Set IV data, fixed length byte array\n        void setIv(uint8_t* text)    { memcpy(sasRelayHeader->iv, text, sizeof(sasRelayHeader->iv)); }\n\n        /// Set SAS rendering algorithm, fixed length byte array\n        void setSasAlgo(uint8_t* text) { memcpy(sasRelayHeader->sas, text, sizeof(sasRelayHeader->sas)); }\n\n        /// Set SAS hash data, fixed length byte array\n        void setTrustedSas(uint8_t* text)    { memcpy(sasRelayHeader->trustedSasHash, text, sizeof(sasRelayHeader->trustedSasHash)); }\n\n        /// Set signature length in words\n        void setSignatureLength(uint32_t sl);\n\n    private:\n        void initialize();\n     // Confirm packet is of variable length. It maximum size is 524 words:\n     // - 11 words fixed size\n     // - up to 513 words variable part, depending if signature is present and its length.\n     // This leads to a maximum of 4*524=2096 bytes.\n        uint8_t data[2100];       // large enough to hold a full blown Confirm packet\n\n};\n\n/**\n * @}\n */\n#endif // ZRTPPACKETSASRELAY\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpSdesStream.h",
    "content": "/*\n  Copyright (C) 2012-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPSDESSTREAM_H_\n#define _ZRTPSDESSTREAM_H_\n/**\n * @file ZrtpSdesStream.h\n * @brief The ZRTP main engine\n * @defgroup GNU_ZRTP The GNU ZRTP C++ implementation\n * @{\n *\n * This class implements SDES and provides a simple to use API for applications.\n *\n * This SDES implementation currently supports only two SDES algorithms and it does\n * not support optional parameters such as lifetime or MKI parameters. Also session\n * parameters are not supported. Most applications that use SDES don't use these\n * optional parameters.\n *\n * It is not necessary to explicitly start the SDES stream. The class initiates\n * the SRTP after it created and parsed all necessary SDES crypto strings.\n *\n * Because SDES works together with the signaling protocol, for example SIP, it is\n * important to adhere to a defined flow. The following pseudo code snippet depicts\n * such a flow. Applications shall follow this flow.\n *\n *<pre>\n *\n *     Inviter                           Answerer\n *    (Offerer)\n *\n * ZrtpSdesStream inv;                 ZrtpSdesStream answ;\n *\n * // create/get own SDES data\n * inv.createSdes(...);\n * inv.getCryptoMixAttribute(...)\n *\n * // prepare SIP/SDP offer, send\n * // it to answerer\n *                                    // receive SIP/SDP, get\n *                                    // SDES data, parse/set it\n *                                    answ.setCryptoMixAttribute(...)\n *                                    answ.parseSdes(...)\n *\n *                                    // create/get own SDES data\n *                                    answ.getCryptoMixAttribute(...)\n *                                    answ.createSdes(...)\n *\n *                                    // prepare SIP/SDP answer,\n *                                    // send to offerer\n * // receive SIP/SDP answer, get\n * // SDES data, parse, set mix algo\n * // if availabe\n * inv.setCryptoMixAttribute(...)\n * inv.parseSdes(...)\n *\n * ...                                ...\n *\n * inv.outgoingRtp(...)\n *                                    answ.incomingRtp(...)\n *\n *                                    answ.outgoingRtp(...)\n * inv.incomingRtp(...)\n *</pre>\n *\n * To use SDES without the new crypto mix feature just do not use the crypto mix functions.\n * An application may always send crypto mix attributes. If the answerer does not support this\n * feature it does not send back a selected algorithm and the offerer cannot set an algorithm.\n * Thus the crypto mix feature is not used.\n * \n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <common/osSpecifics.h>\n#include <srtp/SrtpHandler.h>\n\nclass CryptoContext;\nclass CryptoContextCtrl;\n\n/*\n * These functions support 256 bit encryption algorithms.\n */\n#define MAX_KEY_LEN           32\n#define MAX_SALT_LEN          14\n#define MAX_DIGEST_LENGTH     64\n\n/**\n * Maximum length of a raw crypto string.\n */\n#define MAX_CRYPT_STRING_LEN 200\n\nclass __EXPORT ZrtpSdesStream {\n\npublic:\n\n    /**\n     * Supported SDES crypto suites.\n     */\n    typedef enum {\n        AES_CM_128_HMAC_SHA1_32 = 0,\n        AES_CM_128_HMAC_SHA1_80\n    } sdesSuites;\n\n    /**\n     * SDES stream state\n     */\n    typedef enum {\n        STREAM_INITALIZED = 1,\n        OUT_PROFILE_READY,\n        IN_PROFILE_READY,\n        SDES_SRTP_ACTIVE\n    } sdesZrtpStates;\n\n    typedef enum {\n        MIX_NONE = 0,\n        MIX_HMAC_SHA,\n        MIX_MAC_SKEIN\n    } sdesHmacTypeMix;\n\n    /**\n     * @brief Create and SDES/ZRTP stream.\n     *\n     * This method creates an SDES stream with capabilities to handle RTP,\n     * RTCP, SRTP, and SRTCP packets.\n     *\n     * @param suite defines which crypto suite to use for this stream. The values are\n     *              @c AES_CM_128_HMAC_SHA1_80 or @c AES_CM_128_HMAC_SHA1_32.\n     */\n    ZrtpSdesStream(const sdesSuites suite =AES_CM_128_HMAC_SHA1_32);\n\n    ~ZrtpSdesStream();\n\n    /**\n     * @brief Close an SDES/ZRTP stream.\n     *\n     * Close the stream and return allocated memory to the pool.\n     */\n    void close();\n\n    /**\n     * @brief Creates an SDES crypto string for the SDES/ZRTP stream.\n     *\n     * Creates the crypto string that the application can use in the SDP fields of\n     * SIP INVITE or SIP 200 OK.\n     *\n     * An INVITE-ing application shall call this function at the same point when\n     * it calls the functions to get the @c zrtp-hash string and shall insert the\n     * created crypto string into the SDP.\n     *\n     * An answering application shall call this function directly @b after it called\n     * @c sdesZrtpStreamParseSdes. This usually at the same point when it gets the\n     * @c zrtp-hash from the SDP parameters and forwards it to @c libzrtp. The\n     * answering application's SRTP environment is now ready.\n     *\n     * @param cryptoString output buffer that receives the crypto  string in raw\n     *                     format, without the any signaling prefix, for example\n     *                     @c a=crypto:. The function terminates the crypto string\n     *                     with a @c nul byte\n     *\n     * @param maxLen length of the crypto string buffer. On return it contains the\n     *               actual length of the crypto string.\n     *\n     * @param sipInvite the inviter (offerer) must set this to @c true, the answerer must\n     *                  set it to @c false.\n     *\n     * @return @c true if data could be created, @c false otherwise.\n     */\n    bool createSdes(char *cryptoString, size_t *maxLen, bool sipInvite);\n\n    /**\n     * @brief Parses an SDES crypto string for the SDES/ZRTP stream.\n     *\n     * Parses a SDES crypto string that the application received in a SIP INVITE\n     * or SIP 200 OK.\n     *\n     * An INVITE-ing (offerer) application shall call this function right after it received\n     * the 200 OK from the answering application and must call this function with the\n     * @c sipInvite parameter set to @c true. The offerer's SRTP is now ready for use.\n     *\n     * The answering application calls this function after it received the INVITE and\n     * extracted the crypto string from the SDP and must call this function with the\n     * @c sipInvite parameter set to @c false.\n     *\n     * @param cryptoString the received crypto sting in raw format,\n     *                     without any signaling prefix, for example @c a=crypto:\n     *\n     * @param length length of the crypto string to parse. If the length is\n     *               @c zero then the function uses @c strlen to compute\n     *               the length.\n     *\n     * @param sipInvite the inviter (offerer) must set this to @c true, the answerer must\n     *                  set it to @c false.\n     *\n     * @return @c true if data could be created, @c false otherwise.\n     */\n    bool parseSdes(const char *cryptoString, size_t length, bool sipInvite);\n\n    /**\n     * @brief Get Crypto Mix attribute string\n     *\n     * The offerer calls this method to get a string of @b all supported crypto mix algorithms\n     * and shall send this list to the answerer.\n     *\n     * The answerer calls this function only @b after it received the crypto mix string and @b after\n     * calling @c setCryptoMixAttribute(...). The method returns only one (the selected)\n     * crypto mix algorithm and the answerer must send this to the offerer, for example in 200 OK.\n     *\n     * @param algoNames buffer to store the nul terminated crypto mix algorithm names.\n     *                  The buffer must be long enough to hold at least the name of the mandatory\n     *                  algorithm HMAC-SHA-384.\n     *\n     * @param length length of buffer\n     *\n     * @return Length of algorithm names (excluding nul byte) or zero if crypto mix not supported or\n     *         enabled.\n     */\n    int getCryptoMixAttribute(char *algoNames, size_t length);\n\n    /**\n     * @brief Set Crypto Mix attribute string\n     *\n     * The method checks if it the string contains an supported algorithm and selects one algorithm.\n     *\n     * The offerer calls this method @b after it received the selected algorithm in the answer.\n     *\n     * The answerer must call this method @b before it calls the @c getCryptoMixAttribute() method.\n     *\n     * @param algoNames buffer that contains the received crypto mix algorithm names.\n     *                  The buffer must be nul terminated.\n     *\n     * @return @c false if none of the offered algorithms is supported.\n     */\n    bool setCryptoMixAttribute(const char *algoNames);\n\n    /*\n     * ******** Outgoing RTP/RTCP packet handling\n     */\n    /**\n     * @brief Process an outgoing RTP packet\n     *\n     * This function processes an outgoing RTP packet. Depending on the state\n     * the packet is either:\n     *  - not encrypted if neither SDES nor ZRTP are active or supported by the\n     *    other client. This is the standard case if the stream was just initialized.\n     *  - encrypted with SDES provided key data. This is the case if the application\n     *    called both @c sdesZrtpStreamCreateSdes and @c sdesZrtpStreamParseSdes\n     *    functions to properly setup the SDES key data.\n     *\n     * @param packet the buffer that contains the RTP packet. After processing, the\n     *               encrypted packet is stored in the same buffer. The buffer must\n     *               big enough to hold the additional SRTP data, depending on the\n     *               SRTP profile these are usually 4 - 20 bytes.\n     *\n     * @param length length of the RTP packet\n     *\n     * @param newLength to an integer that get the new length of the packet including SRTP data.\n     *\n     * @return\n     *  - @c true if encryption is successful, app shall send packet to the recipient.\n     *  - @c false if there was an error during encryption, don't send the packet.\n     */\n    bool outgoingRtp(uint8_t *packet, size_t length, size_t *newLength);\n\n    /**\n     * @brief Process an outgoing RTCP packet\n     *\n     * This function works in the same way as @c outgoingRtp.\n     *\n     * @param packet the buffer that contains the RTCP packet. After processing, the\n     *               encrypted packet is stored in the same buffer. The buffer must\n     *               big enough to hold the additional SRTP data, depending on the\n     *               SRTP profile these are usually 8 - 20 bytes.\n     *\n     * @param length length of the RTP packet\n     *\n     * @param newLength to an integer that get the new length of the packet including SRTP data.\n     *\n     * @return\n     *  - @c true if encryption is successful, app shall send packet to the recipient.\n     *  - @c false if there was an error during encryption, don't send the packet.\n     */\n    bool outgoingRtcp(uint8_t *packet, size_t length, size_t *newLength);\n\n    /*\n     * ******** Incoming SRTP/SRTCP packet handling\n     */\n    /**\n     * @brief Process an incoming RTP or SRTP packet\n     *\n     * This function processes an incoming RTP/SRTP packet. Depending on the state\n     * the packet is either:\n     *  - not decrypted if SDES is not active or supported by the\n     *    other client. This is the standard case if the stream was just initialized.\n     *  - decrypted with SDES provided key data. This is the case if the application\n     *    called both @c sdesZrtpStreamCreateSdes and @c sdesZrtpStreamParseSdes\n     *    functions to properly setup the SDES key data.\n     *\n     * If the @c errorData pointer is not @c NULL then this function fills the data structure\n     * in case of an error return. The caller may store and evaluate this data to further\n     * trace the problem.\n     *\n     * @param packet the buffer that contains the RTP/SRTP packet. After processing,\n     *               the decrypted packet is stored in the same buffer.\n     *\n     * @param length length of the RTP packet\n     *\n     * @param newLength to an integer that get the new length of the packet excluding SRTCP data.\n     *\n     * @param errorData Pointer to @c errorData structure or @c NULL, default is @c NULL\n     *\n     * @return\n     *       - 1: success,\n     *       -  0: SRTP/RTP packet decode error\n     *       - -1: SRTP authentication failed,\n     *       - -2: SRTP replay check failed\n     */\n    int incomingRtp(uint8_t *packet, size_t length, size_t *newLength, SrtpErrorData* errorData=NULL);\n\n    /**\n     * @brief Process an incoming RTCP or SRTCP packet\n     *\n     * This function works in the same way as @c incomingRtp.\n     *\n     * @param packet the buffer that contains the RTCP/SRTCP packet. After processing,\n     *               the decrypted packet is stored in the same buffer.\n     *\n     * @param length length of the RTCP packet\n     *\n     * @param newLength to an integer that get the new length of the packet excluding SRTCP data.\n     *\n     * @return\n     *       - 1: success,\n     *       - -1: SRTCP authentication failed,\n     *       - -2: SRTCP replay check failed\n     */\n    int incomingSrtcp(uint8_t *packet, size_t length, size_t *newLength);\n\n    /**\n     * @brief Process an outgoing ZRTP packet.\n     * \n     * Works like @c outgoingRtp, refer to that documentation.\n     * \n     * @param packet the buffer that contains the ZRTP packet.\n     *\n     * @param length length of the ZRTP packet\n     *\n     * @param newLength to an integer that get the new length of the packet including SRTP data.\n     *\n     * @return\n     *  - @c true if encryption is successful, app shall send packet to the recipient.\n     *  - @c false if there was an error during encryption, don't send the packet.\n     */\n    bool outgoingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength);\n\n    /**\n     * @brief Process an incoming ZRTP packet\n     *\n     * Works like @c incomingRtp, refer to that documentation.\n     *\n     * @param packet the buffer that contains the ZRTP/SRTP packet. After processing,\n     *               the decrypted packet is stored in the same buffer.\n     *\n     * @param length length of the RTP packet\n     *\n     * @param newLength to an integer that get the new length of the packet excluding SRTCP data.\n     *\n     * @param errorData Pointer to @c errorData structure or @c NULL, default is @c NULL\n     * \n     * @return\n     *       - 1: success,\n     *       -  0: SRTP/RTP packet decode error\n     *       - -1: SRTP authentication failed,\n     *       - -2: SRTP replay check failed\n     */\n    int incomingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength, SrtpErrorData* errorData=NULL);\n\n        /**\n     * @brief Return state of SDES stream.\n     *\n     * @return state of stream.\n     */\n    sdesZrtpStates getState() {return state;}\n\n    /**\n     * @brief Return SDES crypto mixer HMAC type.\n     *\n     * @return HMAC type\n     */\n    sdesHmacTypeMix getHmacTypeMix() {return cryptoMixHashType;}\n\n    /**\n     * @brief Return name of active cipher algorithm.\n     *\n     * @return point to name of cipher algorithm.\n     */\n    const char* getCipher();\n\n    /**\n     * @brief Return name of active SRTP authentication algorithm.\n     *\n     * @return point to name of authentication algorithm.\n     */\n    const char* getAuthAlgo();\n\n\n    /*\n     * ******** Lower layer functions\n     */\nprivate:\n    /**\n     * @brief Create an SRTP crypto context and the according SDES crypto string.\n     *\n     * This lower layer method creates an SDES crypto string. It selects a valid\n     * crypto suite, generates the key and salt data, converts these into base 64\n     * and returns the crypto string in raw format without any signaling prefixes.\n     *\n     * The output string has the following format:\n     * @verbatim\n     * 1 AES_CM_128_HMAC_SHA1_32 inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj\n     * @endverbatim\n     *\n     * Applications usually don't use this method directly. Applications shall\n     * use the SDES stream functions.\n     *\n     * Depending on the crypto suite the overall length of the crypto string\n     * is variable. For a normal AES_128_CM suite the minumum lenth is 73\n     * characters, a AES_256_CM suite results in 97 characters (not counting\n     * any signaling prefixes).\n     *\n     * @param cryptoString points to a char output buffer that receives the\n     *                     crypto  string in the raw format, without the any\n     *                     signaling prefix, for example @c a=crypto: in case\n     *                     of SDP signaling. The function terminates the\n     *                     crypto string with a @c nul byte\n     *\n     * @param maxLen points to an integer. On input this integer specifies the\n     *               length of the output buffer. If @c maxLen is smaller than\n     *               the resulting crypto string the function returns an error\n     *               conde. On return the functions sets @c maxLen to the\n     *               actual length of the resultig crypto string.\n     *\n     * @param tag the value of the @c tag field in the crypto string. The\n     *            answerer must use this input to make sure that the tag value\n     *            in the answer matches the value in the offer. See RFC 4568,\n     *            section 5.1.2.\n     *            If the tag value is @c -1 the function sets the tag to @c 1.\n     *\n     * @return @c true if data could be created, @c false\n     *          otherwise.\n     */\n    bool createSdesProfile(char *cryptoString, size_t *maxLen);\n\n    /**\n     * @brief Parse and check an offered SDES crypto string and create SRTP crypto context.\n     *\n     * The method parses an offered SDES crypto string and checks if it is\n     * valid. Next it checks if the string contains a supported crypto suite\n     * and if the key and salt lengths match the selected crypto suite.\n     *\n     * Applications usually don't use this method directly. Applications shall\n     * use the SDES stream functions.\n     *\n     * @b NOTE: This function does not support the optional parameters lifetime,\n     * MKI, and session parameters. While it can parse liftime and MKI theiy are\n     * not evaluated and used. If these parameters are used in the input crypto\n     * string the function return @c false.\n     *\n     * @param cryptoString points to the crypto sting in raw format,\n     *        without any signaling prefix, for example @c a=crypto: in case of\n     *        SDP signaling.\n     *\n     * @param length length of the crypto string to parse. If the length is\n     *        @c zero then the function uses @c strlen to compute the length.\n     *\n     * @param parsedSuite the function sets this to the @c sdesSuites enumerator of\n     *        the parsed crypto suite. The answerer shall use this as input to\n     *        @c createSdesProfile to make sure that it creates the same crypto suite.\n     *        See RFC 4568, section 5.1.2\n     *\n     * @param tag the function sets this to the @c tag value of the parsed crypto\n     *        string. The answerer must use this as input to @c createSdesProfile\n     *        to make sure that it creates the correct tag in the crypto string.\n     *        See RFC 4568, section 5.1.2\n     *\n     * @return @c true if checks were ok, @c false\n     *          otherwise.\n     */\n    bool parseCreateSdesProfile(const char *cryptoString, size_t length, sdesSuites *parsedSuite, int32_t *tag);\n\n    /**\n     * @brief Create the SRTP contexts after all SDES creation and parsing is done.\n     * \n     * @param sipInvite if this is set to @c true (not zero) then the method\n     *                  computes the key data for the inviting SIP application (offerer) and\n     *                  for the answerer otherwise.\n     */\n    void createSrtpContexts(bool sipInvite);\n\n    /**\n     * @brief Compute the mixed keys if SDES mixing attribute is set.\n     *\n     * The method takes the parsed or created SDES key material and computes the mixed keys and salt.\n     * It replaces the existing key material with the new data.\n     *\n     * @param sipInvite if this is set to @c true (not zero) then the method\n     *                  computes the key data for the inviting SIP application (offerer) and\n     *                  for the answerer otherwise.\n     */\n    void computeMixedKeys(bool sipInvite);\n\n\n    sdesZrtpStates state;\n    sdesSuites     suite;\n    int32_t        tag;\n    CryptoContext     *recvSrtp;           //!< The SRTP context for this stream\n    CryptoContextCtrl *recvSrtcp;          //!< The SRTCP context for this stream\n    CryptoContext     *sendSrtp;           //!< The SRTP context for this stream\n    CryptoContextCtrl *sendSrtcp;          //!< The SRTCP context for this stream\n    uint32_t srtcpIndex;                   //!< the local SRTCP index\n\n    CryptoContext     *recvZrtpTunnel;     //!< The SRTP context for sender ZRTP tunnel\n    CryptoContext     *sendZrtpTunnel;     //!< The SRTP context for receiver ZRTP tunnel\n\n    int32_t cryptoMixHashLength;\n    sdesHmacTypeMix cryptoMixHashType;\n\n    // Variables for crypto that this client creates and sends to the other client, filled during SDES create\n    uint8_t localKeySalt[((MAX_KEY_LEN + MAX_SALT_LEN + 3)/4)*4];  //!< Some buffer for key and salt, multiple of 4\n    int localKeyLenBytes;\n    int localSaltLenBytes;\n    int localCipher;\n    int localAuthn;\n    int localAuthKeyLen;\n    int localTagLength;\n\n    // Variables for crypto that this client receives from the other client, filled during SDES parse\n    uint8_t remoteKeySalt[((MAX_KEY_LEN + MAX_SALT_LEN + 3)/4)*4];  //!< Some buffer for key and salt, multiple of 4\n    int remoteKeyLenBytes;\n    int remoteSaltLenBytes;\n    int remoteCipher;\n    int remoteAuthn;\n    int remoteAuthKeyLen;\n    int remoteTagLength;\n};\n#endif"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpStateClass.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTPSTATECLASS_H_\n#define _ZRTPSTATECLASS_H_\n\n/**\n * @file ZrtpStateClass.h\n * @brief The ZRTP state handling class\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZRtp.h>\n#include <libzrtpcpp/ZrtpStates.h>\n#include <libzrtpcpp/ZrtpPacketBase.h>\n\n/**\n * The ZRTP states\n *\n * Depending on the role of this state engine and the actual protocl flow\n * not all states are processed during a ZRTP handshake.\n */\nenum zrtpStates {\n    Initial,            ///< Initial state after starting the state engine\n    Detect,             ///< State sending Hello, try to detect answer message\n    AckDetected,        ///< HelloAck received\n    AckSent,            ///< HelloAck sent after Hello received\n    WaitCommit,         ///< Wait for a Commit message\n    CommitSent,         ///< Commit message sent\n    WaitDHPart2,        ///< Wait for a DHPart2 message\n    WaitConfirm1,       ///< Wait for a Confirm1 message\n    WaitConfirm2,       ///< Wait for a confirm2 message\n    WaitConfAck,        ///< Wait for Conf2Ack\n    WaitClearAck,       ///< Wait for clearAck - not used\n    SecureState,        ///< This is the secure state - SRTP active\n    WaitErrorAck,       ///< Wait for ErrorAck message\n    numberOfStates      ///< Gives total number of protocol states\n};\n\nenum EventReturnCodes {\n    Fail = 0,           ///< ZRTP event processing failed.\n    Done = 1            ///< Event processing ok.\n};\n\nenum EventDataType {\n    ZrtpInitial = 1,    ///< Initial event, enter Initial state\n    ZrtpClose,          ///< Close event, shut down state engine\n    ZrtpPacket,         ///< Normal ZRTP message event, process according to state\n    Timer,              ///< Timer event\n    ErrorPkt            ///< Error packet event\n};\n\nenum SecureSubStates {\n    Normal,\n    WaitSasRelayAck,\n    numberofSecureSubStates\n};\n\n/// A ZRTP state event\ntypedef struct Event {\n    EventDataType type; ///< Type of event\n    size_t   length;    ///< length of the message data\n    uint8_t* packet;    ///< Event data if availabe, usually a ZRTP message\n} Event_t;\n\n\n/**\n * The ZRTP timer structure.\n *\n * This structure holds all necessary data to compute the timer for\n * the protocol timers. The state engine allocate one structure for\n * each timer. ZRTP uses two timers, T1 and T2, to monitor protocol\n * timeouts. As a slight misuse but to make overall handling a bit\n * simpler this structure also contains the resend counter. This is\n * possible in ZRTP because it uses a simple timeout strategy.\n */\ntypedef struct zrtpTimer {\n    int32_t time,       ///< Current timeout value\n    start,              ///< Start value for timeout\n    increment,          ///< increment timeout after each timeout event (not used anymore)\n    capping,            ///< Maximum timeout value\n    counter,            ///< Current number of timeouts\n    maxResend;          ///< Maximum number of timeout resends\n} zrtpTimer_t;\n\n\nclass ZRtp;\n\n/**\n * This class is the ZRTP protocol state engine.\n *\n * This class is responsible to handle the ZRTP protocol. It does not\n * handle the ZRTP HMAC, DH, and other data management. This is done in\n * class ZRtp, which is the parent of this class.\n *\n * The methods of this class implement the ZRTP state actions.\n *\n */\n\n\nclass __EXPORT ZrtpStateClass {\n\nprivate:\n    ZRtp* parent;           ///< The ZRTP implmentation\n    ZrtpStates* engine;     ///< The state switching engine\n    Event_t* event;         ///< Current event to process\n\n    /**\n     * The last packet that was sent.\n     *\n     * If we are <code>Initiator</code> then resend this packet in case of\n     * timeout.\n     */\n    ZrtpPacketBase* sentPacket;\n\n    /**\n     * Points to prepared Commit packet after receiving a Hello packet\n     */\n    ZrtpPacketCommit* commitPkt;\n\n    zrtpTimer_t T1;         ///< The Hello message timeout timer\n    zrtpTimer_t T2;         ///< Timeout timer for other messages\n\n    int32_t t1Resend;       ///< configurable resend counter for T1 (Hello packets)\n    int32_t t1ResendExtend; ///< configurable extended resend counter for T1 (Hello packets)\n    int32_t t2Resend;       ///< configurable resend counter for T2 (other packets)\n\n    /*\n     * If this is set to true the protocol engine handle the multi-stream\n     * variant of ZRTP. Refer to chapter 5.4.2 in the ZRTP specification.\n     */\n    bool multiStream;\n\n    // Secure substate to handle SAS relay packets\n    SecureSubStates secSubstate;\n\n    /**\n     * Secure Sub state WaitSasRelayAck.\n     *\n     * This state belongs to the secure substates and handles\n     * SAS Relay Ack. \n     *\n     * When entering this transition function\n     * - sentPacket contains Error packet, Error timer active\n     *\n     * Possible events in this state are:\n     * - timeout for sent SAS Relay packet: causes a resend check and repeat sending\n     *   of packet\n     * - SASRelayAck: Stop timer and switch to secure substate Normal.\n     */\n    bool subEvWaitRelayAck();\n\n    /**\n     * Hello packet version sent to other partner\n     */\n    int32_t sentVersion;\n    \n    int32_t retryCounters[ErrorRetry+1];  // TODO adjust\n\npublic:\n    /// Create a ZrtpStateClass\n    ZrtpStateClass(ZRtp *p);\n    ~ZrtpStateClass();\n\n    /// Check if in a specified state\n    bool inState(const int32_t state) { return engine->inState(state); };\n\n    /// Switch to the specified state\n    void nextState(int32_t state)        { engine->nextState(state); };\n\n    /// Process an event, the main entry point into the state engine\n    void processEvent(Event_t *ev);\n\n    /**\n     * The state event handling methods.\n     *\n     * Refer to the protocol state diagram for further documentation.\n     */\n    /// Initial event state\n    void evInitial();\n\n    /// Detect state\n    void evDetect();\n\n    /// HelloAck detected state\n    void evAckDetected();\n\n    /// HelloAck sent state\n    void evAckSent();\n\n    /// Wait for Commit message\n    void evWaitCommit();\n\n    /// Commit sent state\n    void evCommitSent();\n\n    /// Wait for DHPart2 message\n    void evWaitDHPart2();\n\n    /// Wait for Confirm2 message\n    void evWaitConfirm1();\n\n    /// Wait for Confirm2 message\n    void evWaitConfirm2();\n\n    /// Wait for ConfAck message\n    void evWaitConfAck();\n\n    /// Wait for ClearAck message (not used)\n    void evWaitClearAck();\n\n    /// Secure reached state\n    void evSecureState();\n\n    /// Wait for ErrorAck message\n    void evWaitErrorAck();\n\n    /**\n     * Initialize and activate a timer.\n     *\n     * @param t\n     *    The ZRTP timer structure to use for the timer.\n     * @return\n     *    1 timer was activated\n     *    0 activation failed\n     */\n    int32_t startTimer(zrtpTimer_t *t);\n\n    /**\n     * Compute and set the next timeout value.\n     *\n     * @param t\n     *    The ZRTP timer structure to use for the timer.\n     * @return\n     *    1 timer was activated\n     *    0 activation failed\n     *   -1 resend counter exceeded\n     */\n    int32_t nextTimer(zrtpTimer_t *t);\n\n    /**\n     * Cancel the active timer.\n     *\n     * @return\n     *    1 timer was canceled\n     *    0 cancelation failed\n     */\n    int32_t cancelTimer() {return parent->cancelTimer(); };\n\n    /**\n     * Prepare and send an Error packet.\n     *\n     * Preparse an Error packet and sends it. It stores the Error\n     * packet in the sentPacket variable to enable resending. The\n     * method switches to protocol state Initial.\n     */\n    void sendErrorPacket(uint32_t errorCode);\n\n    /**\n     * Set status if an error occured while sending a ZRTP packet.\n     *\n     * This functions clears data and set the state to Initial after the engine\n     * detected a problem while sending a ZRTP packet.\n     *\n     * @return\n     *    Fail code\n     */\n    void sendFailed();\n\n    /**\n     * Set status if a timer problems occure.\n     *\n     * This functions clears data and set state to Initial after a timer\n     * error occured. Either no timer available or resend counter exceedeed.\n     *\n     * @return\n     *    Fail code\n     */\n    void timerFailed(int32_t subCode);\n\n    /**\n     * Set multi-stream mode flag.\n     *\n     * This functions set the multi-stream mode. The protocol\n     * engine will run the multi-stream mode variant of the ZRTP\n     * protocol if this flag is set to true.\n     *\n     * @param multi\n     *    Set the multi-stream mode flag to true or false.\n     */\n    void setMultiStream(bool multi);\n\n    /**\n     * Status of multi-stream mode flag.\n     *\n     * This functions returns the value of the multi-stream mode flag.\n     *\n     * @return\n     *    Value of the multi-stream mode flag.\n     */\n    bool isMultiStream();\n\n    /**\n     * Send a SAS relay packet.\n     *\n     * the functions stores sends the SAS relay packet and stores the pointer in\n     * the sentPacket variable to enable resending.\n     *\n     * The method switches to secure substate WaitSasRelayAck.\n     * \n     * @param relay\n     *    Pointer to the SAS relay packet.\n     */\n    void sendSASRelay(ZrtpPacketSASrelay* relay);\n\n    /**\n     * Set the resend counter of timer T1 - T1 controls the Hello packets.\n     */\n    void setT1Resend(int32_t counter) {T1.maxResend = counter;}\n\n    /**\n     * Set the time capping of timer T1 - T1 controls the Hello packets.\n     */\n    void setT1Capping(int32_t capping) {T1.capping = capping;}\n\n    /**\n     * Set the extended resend counter of timer T1 - T1 controls the Hello packets.\n     *\n     * More retries to extend time, see chap. 6\n     */\n    void setT1ResendExtend(int32_t counter) {t1ResendExtend = counter;}\n\n    /**\n     * Set the resend counter of timer T2 - T2 controls other (post-Hello) packets.\n     */\n    void setT2Resend(int32_t counter) {T2.maxResend = counter;}\n\n    /**\n     * Set the time capping of timer T2 - T2 controls other (post-Hello) packets.\n     */\n    void setT2Capping(int32_t capping) {T2.capping = capping;}\n\n    /**\n     * @brief Get required buffer size to get all 32-bit retry counters\n     *\n     * @param streamNm stream, if not specified the default is @c AudioStream\n     * \n     * @return number of 32 bit integer elements required or < 0 on error\n     */\n    int getNumberOfRetryCounters();\n\n    /**\n     * @brief Read retry counters\n     * \n     * @param buffer Pointer to buffer of 32-bit integers. The buffer must be able to\n     *         hold at least getNumberOfRetryCounters() 32-bit integers\n     * @param streamNm stream, if not specified the default is @c AudioStream\n     * \n     * @return number of 32-bit counters returned in buffer or < 0 on error\n     */\n    int getRetryCounters(int32_t* counters);\n\n};\n\n/**\n * @}\n */\n#endif // _ZRTPSTATECLASS_H_\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpStates.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef _ZRTPSTATES_H_\n#define _ZRTPSTATES_H_\n\n/**\n * @file ZrtpStates.h\n * @brief The ZRTP state switching class\n *\n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include <stdint.h>\n\nclass __EXPORT ZrtpStateClass;\n/**\n * This structure hold the state name as enum (int) number and the pointer to\n * the functions that handles the various triggers that can occur in a state.\n */\ntypedef struct  {\n    int32_t stateName;                      ///< The state number\n    void (ZrtpStateClass::* handler)(void); ///< The state handler\n} state_t;\n\n/**\n * Implement a simple state switching.\n *\n * This class provides functions that manage the states and the event handler\n * functions. Its a very simple implementation.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nclass __EXPORT ZrtpStates {\n public:\n\n    /// Create an initialize state switching\n    ZrtpStates(state_t* const zstates,\n           const int32_t numStates,\n           const int32_t initialState):\n    numStates(numStates), states(zstates), state(initialState) {}\n\n    /// Call a state handler\n    int32_t processEvent(ZrtpStateClass& zsc) {\n        (zsc.*states[state].handler)();\n        return 0;\n    }\n\n    /// Check if in specified state\n    bool inState(const int32_t s) { return ((s == state)); }\n\n    /// Set the next state\n    void nextState(int32_t s)        { state = s; }\n\n private:\n    const int32_t numStates;\n    const state_t* states;\n    int32_t  state;\n\n    ZrtpStates();\n};\n\n/**\n * @}\n */\n#endif  //ZRTPSTATES\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpTextData.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef _ZRTPTEXTDATA_H_\n#define _ZRTPTEXTDATA_H_\n\n/**\n * @file ZrtpTextData.h\n * @brief The ZRTP ASCII texts - extern references\n *  \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <libzrtpcpp/ZrtpConfigure.h>\n\n/**\n * The extern references to the global data.\n *\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\nextern char zrtpBuildInfo[];\n\nextern char clientId[];\nextern char zrtpVersion_11[];\nextern char zrtpVersion_12[];\n\n/**\n *\n */\nextern char HelloMsg[];\nextern char HelloAckMsg[];\nextern char CommitMsg[];\nextern char DHPart1Msg[];\nextern char DHPart2Msg[];\nextern char Confirm1Msg[];\nextern char Confirm2Msg[];\nextern char Conf2AckMsg[];\nextern char ErrorMsg[];\nextern char ErrorAckMsg[];\nextern char GoClearMsg[];\nextern char ClearAckMsg[];\nextern char PingMsg[];\nextern char PingAckMsg[];\nextern char SasRelayMsg[];\nextern char RelayAckMsg[];\n\n/**\n *\n */\nextern char responder[];\nextern char initiator[];\nextern char iniMasterKey[];\nextern char iniMasterSalt[];\nextern char respMasterKey[];\nextern char respMasterSalt[];\n\nextern char iniHmacKey[];\nextern char respHmacKey[];\nextern char retainedSec[];\n\nextern char iniZrtpKey[];\nextern char respZrtpKey[];\n\nextern char sasString[];\n\nextern char KDFString[];\nextern char zrtpSessionKey[];\nextern char zrtpMsk[];\nextern char zrtpTrustedMitm[];\n\n\nextern char s256[];\nextern char s384[];\nextern char skn2[];\nextern char skn3[];\nextern const char* mandatoryHash;\n\nextern char aes3[];\nextern char aes2[];\nextern char aes1[];\nextern char two3[];\nextern char two2[];\nextern char two1[];\n\nextern const char* mandatoryCipher;\n\nextern char dh2k[];\nextern char dh3k[];\nextern char ec25[];\nextern char ec38[];\nextern char e255[];\nextern char e414[];\n\nextern char mult[];\n\nextern const char* mandatoryPubKey;\n\nextern char b32[];\nextern char b256[];\nextern const char* mandatorySasType;\n\nextern char hs32[];\nextern char hs80[];\nextern char sk32[];\nextern char sk64[];\nextern const char* mandatoryAuthLen_1;\nextern const char* mandatoryAuthLen_2;\n\nextern const char* sas256WordsOdd[];\nextern const char* sas256WordsEven[];\n\n/**\n * @}\n */\n#endif     // _ZRTPTEXTDATA_H_\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/ZrtpUserCallback.h",
    "content": "/*\r\n  Copyright (C) 2006-2013 Werner Dittmann\r\n\r\n  This program is free software: you can redistribute it and/or modify\r\n  it under the terms of the GNU Lesser General Public License as published by\r\n  the Free Software Foundation, either version 3 of the License, or\r\n  (at your option) any later version.\r\n\r\n  This program is distributed in the hope that it will be useful,\r\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n  GNU General Public License for more details.\r\n\r\n  You should have received a copy of the GNU General Public License\r\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\r\n*/\r\n\r\n#ifndef _ZRTPUSERCALLBACK_H_\r\n#define _ZRTPUSERCALLBACK_H_\r\n\r\n/**\r\n * @file ZrtpUserCallback.h\r\n * @brief The ZRTP UserCallback class\r\n *\r\n * @ingroup GNU_ZRTP\r\n * @{\r\n */\r\n\r\n#include <stdint.h>\r\n#include <string>\r\n\r\n#include <libzrtpcpp/ZrtpCodes.h>\r\n\r\n/**\r\n * Application callback methods.\r\n *\r\n * The ccRTP specific part of GNU ZRTP uses these callback methods\r\n * to report ZRTP events to the application. This class implements a\r\n * default behaviour for each callback method, usually just a return.\r\n *\r\n * An application may extend this class and overload methods\r\n * to implement its own behaviour. The application must register its\r\n * callback class using ZrtpQueue#setUserCallback().\r\n *\r\n * <b>CAVEAT</b><br/>\r\n * All methods of the user callback class and classes that\r\n * extend this class run in the context of the RTP thread. Thus it is\r\n * of paramount importance to keep the execution time of the methods\r\n * as short as possible.\r\n *\r\n * @author Werner Dittmann <Werner.Dittmann@t-online.de>\r\n */\r\n\r\nclass __EXPORT ZrtpUserCallback {\r\n\r\n    public:\r\n\r\n        /// Create the stadard user callback class.\r\n        ZrtpUserCallback() {}\r\n\r\n        virtual ~ZrtpUserCallback() {};\r\n\r\n        /**\r\n         * Inform user interface that security is active now.\r\n         *\r\n         * ZRTP calls this method if the sender and the receiver are\r\n         * in secure mode now.\r\n         *\r\n         * @param cipher\r\n         *    Name and mode of cipher used to encrypt the SRTP stream\r\n         */\r\n        virtual void secureOn(std::string cipher) {\r\n            return;\r\n        }\r\n        /**\r\n         * Inform user interface that security is not active any more.\r\n         *\r\n         * ZRTP calls this method if either the sender or the receiver\r\n         * left secure mode.\r\n         *\r\n         */\r\n        virtual void secureOff() {\r\n            return;\r\n        }\r\n\r\n        /**\r\n         * Show the Short Authentication String (SAS) on user interface.\r\n         *\r\n         * ZRTP calls this method to display the SAS and inform about the SAS\r\n         * verification status. The user interface shall enable a SAS verfication\r\n         * button (or similar UI element). The user shall click on this UI\r\n         * element after he/she confirmed the SAS code with the partner.\r\n         *\r\n         * @param sas\r\n         *     The string containing the SAS.\r\n         * @param verified\r\n         *    If <code>verified</code> is true then SAS was verified by both\r\n         *    parties during a previous call, otherwise it is set to false.\r\n         */\r\n        virtual void showSAS(std::string sas, bool verified) {\r\n            return;\r\n        }\r\n\r\n        /**\r\n         * Inform the user that ZRTP received \"go clear\" message from its peer.\r\n         *\r\n         * On receipt of a go clear message the user is requested to confirm\r\n         * a switch to unsecure (clear) modus. Until the user confirms ZRTP\r\n         * (and the underlying RTP) does not send any data.\r\n         */\r\n        virtual void confirmGoClear() {\r\n            return;\r\n        }\r\n\r\n        /**\r\n         * Show some information to user.\r\n         *\r\n         * ZRTP calls this method to display some information to the user.\r\n         * Along with the message ZRTP provides a severity indicator that\r\n         * defines: Info, Warning, Error, and Alert. Refer to the <code>\r\n         * MessageSeverity</code> enum in <code>ZrtpCodes.h</code>. The\r\n         * UI may use this indicator to highlight messages or alike.\r\n         *\r\n         * @param sev\r\n         *     Severity of the message.\r\n         * @param subCode\r\n         *     The subcode identifying the reason.\r\n         */\r\n        virtual void showMessage(GnuZrtpCodes::MessageSeverity sev, int32_t subCode) {\r\n            return;\r\n        }\r\n\r\n        /**\r\n         * ZRTPQueue calls this if the negotiation failed.\r\n         *\r\n         * ZRTPQueue calls this method in case ZRTP negotiation failed. The\r\n         * parameters show the severity as well as some explanatory text.\r\n         * Refer to the <code>MessageSeverity</code> enum above.\r\n         *\r\n         * @param severity\r\n         *     This defines the message's severity\r\n         * @param subCode\r\n         *     The subcode identifying the reason.\r\n         */\r\n        virtual void zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity,\r\n                                           int32_t subCode) {\r\n            return;\r\n        }\r\n\r\n        /**\r\n         * ZRTPQueue calls this method if the other side does not support ZRTP.\r\n         *\r\n         * If the other side does not answer the ZRTP <em>Hello</em> packets then\r\n         * ZRTP calls this method.\r\n         *\r\n         */\r\n        virtual void zrtpNotSuppOther() {\r\n            return;\r\n        }\r\n\r\n        /**\r\n         * ZRTPQueue calls this method to inform about a PBX enrollment request.\r\n         *\r\n         * Please refer to chapter 8.3 ff to get more details about PBX enrollment\r\n         * and SAS relay.\r\n         *\r\n         * @param info\r\n         *    Give some information to the user about the PBX requesting an\r\n         *    enrollment.\r\n         *\r\n         */\r\n        virtual void zrtpAskEnrollment(GnuZrtpCodes::InfoEnrollment info) {\r\n            return;\r\n        }\r\n\r\n        /**\r\n         * ZRTPQueue calls this method to inform about PBX enrollment result.\r\n         *\r\n         * Informs the use about the acceptance or denial of an PBX enrollment\r\n         * request\r\n         *\r\n         * @param info\r\n         *    Give some information to the user about the result of an\r\n         *    enrollment.\r\n         *\r\n         */\r\n        virtual void zrtpInformEnrollment(GnuZrtpCodes::InfoEnrollment info) {\r\n            return;\r\n        }\r\n\r\n        /**\r\n         * ZRTPQueue calls this method to request a SAS signature.\r\n         *\r\n         * After ZRTP core was able to compute the Short Authentication String\r\n         * (SAS) it calls this method. The client may now use an approriate\r\n         * method to sign the SAS. The client may use\r\n         * setSignatureData() of ZrtpQueue to store the signature\r\n         * data an enable signature transmission to the other peer. Refer\r\n         * to chapter 8.2 of ZRTP specification.\r\n         *\r\n         * @param sasHash\r\n         *    Pointer to the 32 byte SAS hash to be signed.\r\n         * @see ZrtpQueue#setSignatureData\r\n         *\r\n         */\r\n        virtual void signSAS(uint8_t* sasHash) {\r\n            return;\r\n        }\r\n\r\n        /**\r\n         * ZRTPQueue calls this method to request a SAS signature check.\r\n         *\r\n         * After ZRTP received a SAS signature in one of the Confirm packets it\r\n         * call this method. The client may use <code>getSignatureLength()</code>\r\n         * and <code>getSignatureData()</code>of ZrtpQueue to get the signature\r\n         * data and perform the signature check. Refer to chapter 8.2 of ZRTP\r\n         * specification.\r\n         *\r\n         * If the signature check fails the client may return false to ZRTP. In\r\n         * this case ZRTP signals an error to the other peer and terminates\r\n         * the ZRTP handshake.\r\n         *\r\n         * @param sasHash\r\n         *    Pointer to the 32 byte SAS hash that was signed by the other peer.\r\n         * @return\r\n         *    true if the signature was ok, false otherwise.\r\n         *\r\n         */\r\n        virtual bool checkSASSignature(uint8_t* sasHash) {\r\n            return true;\r\n        }\r\n};\r\n\r\n#endif\r\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/zrtpB64Decode.h",
    "content": "/*\ncdecode.h - c header for a base64 decoding algorithm\n\nThis is part of the libb64 project, and has been placed in the public domain.\nFor details, see http://sourceforge.net/projects/libb64\n*/\n\n#ifndef BASE64_CDECODE_H\n#define BASE64_CDECODE_H\n\n#include <stdint.h>\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\ntypedef enum\n{\n\tstep_a, step_b, step_c, step_d\n} base64_decodestep;\n\ntypedef struct\n{\n\tbase64_decodestep step;\n\tchar plainchar;\n} base64_decodestate;\n\nvoid base64_init_decodestate(base64_decodestate* state_in);\n\nint base64_decode_value(char value_in);\n\nint base64_decode_block(const char* code_in, const int length_in, uint8_t *plaintext_out, base64_decodestate* state_in);\n\n#if defined(__cplusplus)\n}\n#endif\n\n#endif /* BASE64_CDECODE_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/zrtpB64Encode.h",
    "content": "/*\ncencode.h - c header for a base64 encoding algorithm\n\nThis is part of the libb64 project, and has been placed in the public domain.\nFor details, see http://sourceforge.net/projects/libb64\n*/\n\n#ifndef BASE64_CENCODE_H\n#define BASE64_CENCODE_H\n\n#include <stdint.h>\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\ntypedef enum\n{\n\tstep_A, step_B, step_C\n} base64_encodestep;\n\ntypedef struct\n{\n\tbase64_encodestep step;\n\tchar result;\n\tint stepcount;\n    int lineLength;\n} base64_encodestate;\n\nvoid base64_init_encodestate(base64_encodestate* state_in, int lineLength);\n\nchar base64_encode_value(const int8_t value_in);\n\nint base64_encode_block(const uint8_t *plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);\n\nint base64_encode_blockend(char *code_out, base64_encodestate* state_in);\n#if defined(__cplusplus)\n}\n#endif\n\n#endif /* BASE64_CENCODE_H */\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/zrtpCacheDbBackend.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _ZRTP_CACHE_DB_BACKEND_H_\n#define _ZRTP_CACHE_DB_BACKEND_H_\n\n#include <libzrtpcpp/ZIDRecordDb.h>\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\n#define DB_CACHE_ERR_BUFF_SIZE  1000\n\n/**\n * Set of accessible operations of database ZRTP cache implementaion.\n *\n * The only public method of the database ZRTP implementation is\n * getDbCacheOps(...)  that fills in this call structure. This mechanism\n * decouples the database implementations from libzrtp and possible other\n * clients.\n *\n * Some implementation notes:\n * <ul>\n * <li> All data storage methods return 0 (zero) if the call was successful.\n * </li>\n\n * <li> The @c errString parameter points to a buffer of at least @c\n *      DB_CACHE_ERR_BUFF_SIZE character. In case of an error methods shall\n *      store detailed, human readable information in this buffer. Use @c\n *      snprintf or similar functions to format the data.  If this parameter\n *      is @c NULL then methods must not return an error string.\n *</li>\n * <li> The methods cast the @c void to the type they need. Be aware that the\n *      open functions requires a pointer to a pointer.\n * </li>\n * </ul>\n *\n *\n * \n */\ntypedef struct {\n    /**\n     * @brief Open the cache.\n     *\n     * @param name String that identifies the database or data storage.\n     *\n     * @param pdb Pointer to an internal structure that the database\n     *            implementation requires.\n     *\n     * @param errString Pointer to a character buffer, see implementation\n     *                  notes above.\n     */\n    int (*openCache)(const char* name, void **pdb, char *errString);\n\n    /**\n     * Close the cache.\n     *\n     * @param db Pointer to an internal structure that the database\n     *           implementation requires.\n     */\n    int (*closeCache)(void *db);\n\n    /**\n     * @brief Read a local ZID from the database.\n     *\n     * The cache database may implement methods to generate and store local\n     * ZRTP identifiers (ZID) and optionally link them with account\n     * information. The account information data is the key to the request\n     * local ZID. If the application does not provide account information data\n     * the method implmentation shall use a standard predfined string that\n     * does not collide with usual account information.\n     *\n     * The SQLite backend uses the string @c \"_STANDARD_\" in this case and\n     * sets a specific type field.\n     * \n     * The first call to this method with a specific account information\n     * generates a ZID, stores it in the database usind the account\n     * information as key, and returns the ZID to the application. Any\n     * subsequent call with the same account information return the same local\n     * ZID.\n     *\n     * @param db Pointer to an internal structure that the database\n     *           implementation requires.\n     *\n     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c\n     *                 uint8_t bytes. The method stores the local ZID in this\n     *                 buffer.\n     *\n     * @param accountInfo Pointer to an account information string or @c NULL\n     *                    if explicit account information is not required.\n     *\n     * @param errString Pointer to a character buffer, see implementation\n     *                  notes above.\n     */\n    int (*readLocalZid)(void *db, uint8_t *localZid, const char *accountInfo, char *errString);\n\n    /**\n     * @brief Read a remote ZID data structure.\n     *\n     * The method uses @c remoteZid and @c localZid as keys to read the remote\n     * ZID record.  If a record does not exist in the database the method\n     * clears the @c flags field in the @c remoteZidRecord_t structure and\n     * returns without error. The application must check the flags if the\n     * method found a valid record.\n     *\n     * @param db Pointer to an internal structure that the database\n     *           implementation requires.\n     *\n     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c\n     *                 uint8_t bytes. The buffer must contain the local ZID.\n     *\n     * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c\n     *                  uint8_t bytes. The buffer must contain the remote ZID.\n     *\n     * @param remZid Pointer to the @c remoteZidRecord_t structure. The method\n     *               fills this structure with data it read from the database.\n     *\n     * @param errString Pointer to a character buffer, see implementation\n     *                  notes above.\n     */\n    int (*readRemoteZidRecord)(void *db, const uint8_t *remoteZid, const uint8_t *localZid, \n                               remoteZidRecord_t *remZid, char* errString);\n    /**\n     * @brief Update an existing remote ZID data structure.\n     *\n     * The method uses @c remoteZid and @c localZid as keys to update an\n     * existing remote ZID record.\n     *\n     * @b NOTE: application must use this methods only if\n     *          @c readRemoteZidRecord (see above) returned a @b valid record. If\n     *          @c readRemoteZidRecord returned an invalid record then no such\n     *          record exists in the database and the application must use the\n     *          @c insertRemoteZidRecord (see below).\n     *\n     * @param db Pointer to an internal structure that the database\n     *           implementation requires.\n     *\n     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c\n     *                 uint8_t bytes. The buffer must contain the local ZID.\n     *\n     * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c\n     *                  uint8_t bytes. The buffer must contain the remote ZID.\n     *\n     * @param remZid Pointer to the @c remoteZidRecord_t structure. The method\n     *               gets data from this structure and stores it in the\n     *               database.\n     *\n     * @param errString Pointer to a character buffer, see implementation\n     *                  notes above.\n     */\n    int (*updateRemoteZidRecord)(void *db, const uint8_t *remoteZid, const uint8_t *localZid, \n                                 const remoteZidRecord_t *remZid, char* errString);\n    /**\n     * @brief Insert a new remote ZID data structure.\n     *\n     * The method uses @c remoteZid and @c localZid as keys to insert a new\n     * remote ZID record.\n     *\n     * @b NOTE: application must use this methods only if @c\n     *          readRemoteZidRecord (see above) returned an @b invalid\n     *          record. Refer to note.\n     *\n     * @param db Pointer to an internal structure that the database\n     *           implementation requires.\n     *\n     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c\n     *                 uint8_t bytes. The buffer must contain the local ZID.\n     *\n     * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c\n     *                  uint8_t bytes. The buffer must contain the remote ZID.\n     *\n     * @param remZid Pointer to the @c remoteZidRecord_t structure. The method\n     *               gets data from this structure and stores it in the\n     *               database.\n     *\n     * @param errString Pointer to a character buffer, see implementation\n     *                  notes above.\n     */\n    int (*insertRemoteZidRecord)(void *db, const uint8_t *remoteZid, const uint8_t *localZid, \n                                 const remoteZidRecord_t *remZid, char* errString);\n\n    /**\n     * @brief Read a remote ZID name.\n     *\n     * The method uses @c remoteZid, @c localZid, and @c accountInfo as keys\n     * to read the remote ZID name.  If a record does not exist in the database\n     * the method clears the @c flags field in the @c zidNameRecord_t structure and\n     * returns without error. The application must check the flags if the\n     * method found a valid record.\n     * \n     * @param vdb Pointer to an internal structure that the database\n     *           implementation requires.\n     *\n     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c\n     *                 uint8_t bytes. The buffer must contain the local ZID.\n     *\n     * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c\n     *                  uint8_t bytes. The buffer must contain the remote ZID.\n     *\n     * @param accountInfo Pointer to an account information string or @c NULL\n     *                    if explicit account information is not required.\n     *\n     * @param zidName Pointer to the @c zidNameRecord_t structure. The method\n     *                returns the data in this structure.\n     *\n     * @param errString Pointer to a character buffer, see implementation\n     *                  notes above.\n     */\n    int (*readZidNameRecord)(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,\n                             const char *accountInfo, zidNameRecord_t *zidName, char* errString);\n\n    /**\n     * @brief Update an existing remote ZID data structure.\n     *\n     * The method uses @c remoteZid and @c localZid as keys to update an\n     * existing remote ZID record.\n     *\n     * @b NOTE: application must use this methods only if\n     *          @c readZidName (see above) returned a @b valid record. If\n     *          @c readZidName returned an invalid record then no such\n     *          record exists in the database and the application must use the\n     *          @c insertZidNameRecord (see below).\n     *\n     * @param vdb Pointer to an internal structure that the database\n     *           implementation requires.\n     *\n     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c\n     *                 uint8_t bytes. The buffer must contain the local ZID.\n     *\n     * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c\n     *                  uint8_t bytes. The buffer must contain the remote ZID.\n     *\n     * @param accountInfo Pointer to an account information string or @c NULL\n     *                    if explicit account information is not required.\n     *\n     * @param zidName Pointer to the @c zidNameRecord_t structure. The method\n     *               gets data from this structure and stores it in the\n     *               database.\n     *\n     * @param errString Pointer to a character buffer, see implementation\n     *                  notes above.\n     */\n    int (*updateZidNameRecord)(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,\n                               const char *accountInfo, zidNameRecord_t *zidName, char* errString);\n\n    /**\n     * @brief Insert a new ZID name record.\n     *\n     * The method uses @c remoteZid, @c localZid, and @c accountInfo as keys to\n     * insert a new ZID name record.\n     *\n     * @b NOTE: application must use this methods only if @c readZidName\n     *         (see above) returned an @b invalid record.\n     *\n     * @param db Pointer to an internal structure that the database\n     *           implementation requires.\n     *\n     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c\n     *                 uint8_t bytes. The buffer must contain the local ZID.\n     *\n     * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c\n     *                  uint8_t bytes. The buffer must contain the remote ZID.\n     *\n     * @param accountInfo Pointer to an account information string or @c NULL\n     *                    if explicit account information is not required.\n     *\n     * @param zidName Pointer to the @c zidNameRecord_t structure. The method\n     *               gets data from this structure and stores it in the\n     *               database.\n     *\n     * @param errString Pointer to a character buffer, see implementation\n     *                  notes above.\n     */\n    int (*insertZidNameRecord)(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,\n                               const char *accountInfo, zidNameRecord_t *zidName, char* errString);\n\n\n    /**\n     * @brief Clean the cache.\n     * \n     * The function drops and re-creates all tables in the database. This removes all stored\n     * data. The application must not call this while a ZRTP call is active. Also the application\n     * <b>must</b> get the local ZID again.\n     *\n     * @param db Pointer to an internal structure that the database\n     *           implementation requires.\n     *\n     * @param errString Pointer to a character buffer, see implementation\n     *                  notes above.\n     */\n    int (*cleanCache)(void *db, char* errString);\n\n    /**\n     * @brief Prepare a SQL cursor to read all records from the remote (peer) ZID table.\n     * \n     * The function creates a SQL cursor (prepares a statement in sqlite3 parlance) to\n     * read all records from the table that contains the remote (peers') ZID data.\n     * \n     * This functions returns a pointer to the SQL cursor or @c NULL if it fails to\n     * create a cursor.\n     * \n     * @param db Pointer to an internal structure that the database\n     *           implementation requires.\n     * \n     * @param errString Pointer to a character buffer, see implementation\n     *                  notes above.\n     * \n     * @return a void pointer to the sqlite3 statment (SQL cursor) or @c NULL\n     */\n    void *(*prepareReadAllZid)(void *db, char *errString);\n\n    /**\n     * @brief Read next ZID record from and SQL cursor.\n     * \n     * The function reads the next ZID record from a SQL cursor. If it cannot read a\n     * record or encounters an error the function closes the cursor and returns @c NULL.\n     * In this case the function must not use the SQL cursor pointer again.\n     * \n     * @param db Pointer to an internal structure that the database\n     *           implementation requires.\n     * \n     * @param stmt a void pointer to a sqlite3 statement (SQL cursor)\n     *\n     * @param remZid Pointer to the @c remoteZidRecord_t structure. The method\n     *               fills this structure with data it read from the database.\n     * \n     * @param errString Pointer to a character buffer, see implementation\n     *                  notes above.\n     * \n     * @return void pointer to statment if successful, this is the same pointer as\n     *         the @c stmt input parameter. The function returns @c NULL if either \n     *         no more record is available or it got another error.\n     */\n    void *(*readNextZidRecord)(void *db, void *stmt, remoteZidRecord_t *remZid, char* errString);\n\n    /**\n     * @brief Close sqlite3 statment (SQL cursor)\n     * \n     * This functions closes (finalizes) an open sqlite3 statment. Usually the \n     * @c readNextZidRecord closes the statment if no more record is available. However, an\n     * application may decide not to read every record. In this case it @b must close the\n     * sqlite3 statment\n     * \n     * @param stmt a void pointer to a sqlite3 statement (SQL cursor)\n     */\n    void (*closeStatement)(void *vstmt);\n} dbCacheOps_t;\n\nvoid getDbCacheOps(dbCacheOps_t *ops);\n\n\n#if defined(__cplusplus)\n}\n#endif\n\n#endif /* _ZRTP_CACHE_DB_BACKEND_H_*/\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/libzrtpcpp/zrtpPacket.h",
    "content": "/*\n  Copyright (C) 2006-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#ifndef ZRTPPACKET_H\n#define ZRTPPACKET_H\n\n/**\n *\n * @file zrtpPacket.h\n * @brief The data structures and definitions for ZRTP messages\n * \n * This include file defines the ZRTP message structures. Refer to\n * chapter 5 of the ZRTP specification which defines the ZRTP messages and\n * the transport format.\n * \n * @ingroup GNU_ZRTP\n * @{\n */\n\n#include <stdio.h>\n\n/**\n * The following defines match the ZRTP specification, chapter 5\n */\n#define ZRTP_MAGIC       0x5a525450\n\n#define ZRTP_WORD_SIZE   4\n#define CRC_SIZE         4\n\n#define TYPE_SIZE        (2*ZRTP_WORD_SIZE)\n#define CLIENT_ID_SIZE   (4*ZRTP_WORD_SIZE)\n#define HASH_IMAGE_SIZE  (8*ZRTP_WORD_SIZE)\n#define ZID_SIZE         (3*ZRTP_WORD_SIZE)\n#define HVI_SIZE         (8*ZRTP_WORD_SIZE)\n#define HMAC_SIZE        (2*ZRTP_WORD_SIZE)\n#define ID_SIZE          (2*ZRTP_WORD_SIZE)\n#define IV_SIZE          (4*ZRTP_WORD_SIZE)\n#define PING_HASH_SIZE   (2*ZRTP_WORD_SIZE)\n\n\n/**\n * The ZRTP message header\n * \n * A complete ZRTP message always consists of the ZRTP header\n * and a message specific part. This specific part may have a variable\n * length. The length field includes the header.\n */\ntypedef struct zrtpPacketHeader {\n    uint16_t    zrtpId;         ///< Id to identify the message, always 0x505a\n    uint16_t    length;         ///< Length of the ZRTP message in words\n    uint8_t     messageType[TYPE_SIZE]; ///< 2 word (8 octest) message type in ASCII\n} zrtpPacketHeader_t;\n\n/**\n * Hello message, fixed part.\n * \n * The complete Hello message consists of ZRTP message header, Hello fixed \n * part and a variable part. The Hello class initializes the variable part.\n */\ntypedef struct Hello {\n    uint8_t  version[ZRTP_WORD_SIZE];   ///< Announces the ZRTP protocol version \n    uint8_t  clientId[CLIENT_ID_SIZE];  ///< A 4 word ASCII identifier of the ZRTP client\n    uint8_t  hashH3[HASH_IMAGE_SIZE];   ///< The last hash of the hash chain (chap. 9)\n    uint8_t  zid[ZID_SIZE];             ///< ZID - 3 word identifier for the ZRTP endpoint\n    uint8_t  flags;                     ///< flag bits (chap 7.2)\n    uint8_t  lengths[3];                ///< number of algorithms present\n} Hello_t;\n\n/**\n * The complete ZRTP Hello message.\n */\ntypedef struct HelloPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    Hello_t hello;                  ///< Fixed part of Hello message\n} HelloPacket_t;\n\n/**\n * HelloAck message.\n * \n * The complete HelloAck message consists of ZRTP message header and\n * the CRC which is the only HelloAck specific data.\n */\ntypedef struct HelloAckPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    uint8_t crc[ZRTP_WORD_SIZE];    ///< CRC of ZRTP message\n} HelloAckPacket_t;\n\n/**\n * Commit message\n * \n * There are three subtypes of Commit messages, each of which\n * has a fixed size. The data structure defines the maximum\n * Commit message. During the ZRTP protocol the implementation\n * uses fileds according to the use case (DH handshake,\n * Multi-stream handshake) and adjusts the length.\n */\ntypedef struct Commit {\n    uint8_t hashH2[HASH_IMAGE_SIZE];        ///< The second hash of the hash chain (chap. 9)\n    uint8_t\tzid[ZID_SIZE];                  ///< ZID - 3 word identifier for the ZRTP endpoint\n    uint8_t hash[ZRTP_WORD_SIZE];           ///< Commited hash algorithm\n    uint8_t cipher[ZRTP_WORD_SIZE];         ///< Commited symmetrical cipher algorithm\n    uint8_t authlengths[ZRTP_WORD_SIZE];    ///< Commited SRTP authentication algorithm\n    uint8_t\tpubkey[ZRTP_WORD_SIZE];         ///< Commited key agreement algorithm\n    uint8_t\tsas[ZRTP_WORD_SIZE];            ///< Commited SAS algorithm\n    uint8_t\thvi[HVI_SIZE];                  ///< Hash value Initiator - chap 4.4.1.1\n    uint8_t\thmac[HMAC_SIZE];                ///< MAC of the Commit message\n} Commit_t;\n\n/**\n * The complete ZRTP Commit message.\n */\ntypedef struct CommitPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    Commit_t commit;                ///< Commit message\n    uint8_t crc[ZRTP_WORD_SIZE];    ///< CRC of ZRTP message\n} CommitPacket_t;\n\n/**\n * DHPart1 and DHPart2 messages\n * \n * The DHPart messages have a variable length. The following struct\n * defines the fixed part only. The DHPart class initializes the\n * variable part.\n */\ntypedef struct DHPart {\n    uint8_t hashH1[HASH_IMAGE_SIZE];        ///< The first hash of the hash chain (chap. 9)\n    uint8_t rs1Id[ID_SIZE];                 ///< Id of first retained secret\n    uint8_t rs2Id[ID_SIZE];                 ///< Id of second retained secret\n    uint8_t auxSecretId[ID_SIZE];           ///< Id of additional (auxilliary) secret\n    uint8_t pbxSecretId[ID_SIZE];           ///< Id of PBX secret (chap 7.3.1)\n}  DHPart_t;\n\n/**\n * The complete ZRTP DHPart message.\n */\ntypedef struct DHPartPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    DHPart_t dhPart;                ///< DHPart message fixed part\n} DHPartPacket_t;\n\n/**\n * Confirm1 and Confirm2 messages\n * \n * The Confirm message have a variable length. The following struct\n * defines the fixed part only. The Confirm class initializes the\n * variable part.\n * \n * ZRTP encrypts a part of the Confirm messages, starting at @c hashH0 \n * and includes the variable part.\n */\ntypedef struct Confirm {\n    uint8_t\t hmac[HMAC_SIZE];           ///< MAC over the encrypted part of Commit message \n    uint8_t  iv[IV_SIZE];               ///< IV for CFB mode to encrypt part of Commit\n    uint8_t  hashH0[HASH_IMAGE_SIZE];   ///< starting hash of hash chain (chap. 9)\n    uint8_t  filler[2];                 ///< Filler bytes\n    uint8_t  sigLength;                 ///< Length of an optional signature length (chap 7.2)\n    uint8_t  flags;                     ///< various flags to control behaviour\n    uint32_t expTime;                   ///< Expiration time of retained secrets (chap 4.9)\n} Confirm_t;\n\n/**\n * The complete ZRTP Confirm message.\n */\ntypedef struct ConfirmPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    Confirm_t confirm;              ///< Confirm message fixed part\n} ConfirmPacket_t;\n\n/**\n * Conf2Ack message.\n * \n * The complete Conf2Ack message consists of ZRTP message header and\n * the CRC which is the only Conf2Ack specific data.\n */\ntypedef struct Conf2AckPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    uint8_t crc[ZRTP_WORD_SIZE];    ///< CRC of ZRTP message\n} Conf2AckPacket_t;\n\n/**\n * The GoClear message is currently not used in\n * GNU ZRTP C++ - not support for GoClear.\n */\ntypedef struct GoClear {\n    uint8_t clearHmac[HMAC_SIZE];   ///< no used\n} GoClear_t;\n\n/**\n * The complete ZRTP GoClear message - no used.\n */\ntypedef struct GoClearPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    GoClear_t goClear;              ///< not used\n    uint8_t crc[ZRTP_WORD_SIZE];    ///< CRC of ZRTP message\n} GoClearPacket_t;\n\n/**\n * The ClearAck message is currently not used in\n * GNU ZRTP C++ - not support for GoClear.\n */\ntypedef struct ClearAckPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    uint8_t crc[ZRTP_WORD_SIZE];    ///< CRC of ZRTP message\n} ClearAckPacket_t;\n\n/**\n * The Error message\n */\ntypedef struct Error {\n    uint32_t errorCode;             ///< Error code, see chap 5.9\n} Error_t;\n\n/**\n * The complete ZRTP Error message.\n */\ntypedef struct ErrorPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    Error_t error;                  ///< Error message part\n    uint8_t crc[ZRTP_WORD_SIZE];    ///< CRC of ZRTP message\n} ErrorPacket_t;\n\n/**\n * ErrorAck message.\n * \n * The complete ErrorAck message consists of ZRTP message header and\n * the CRC which is the only ErrorAck specific data.\n */\ntypedef struct ErrorAckPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    uint8_t crc[ZRTP_WORD_SIZE];    ///< CRC of ZRTP message\n} ErrorAckPacket_t;\n\n/**\n * Ping message.\n * \n * The Ping message has a fixed size.\n */\ntypedef struct Ping {\n    uint8_t version[ZRTP_WORD_SIZE];    ///< The ZRTP protocol version\n    uint8_t epHash[PING_HASH_SIZE];     ///< End point hash, see chap 5.16\n} Ping_t;\n\n/**\n * The complete ZRTP Ping message.\n */\ntypedef struct PingPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    Ping_t ping;                    ///< Ping message part\n    uint8_t crc[ZRTP_WORD_SIZE];    ///< CRC of ZRTP message\n} PingPacket_t;\n\n/**\n * PingAck message.\n * \n * The PingAck message has a fixed size.\n */\ntypedef struct PingAck {\n    uint8_t version[ZRTP_WORD_SIZE];        ///< The ZRTP protocol version\n    uint8_t localEpHash[PING_HASH_SIZE];    ///< Local end point hash, see chap 5.16\n    uint8_t remoteEpHash[PING_HASH_SIZE];   ///< Remote end point hash, see chap 5.16\n    uint32_t ssrc;                          ///< SSRC copied from the Ping message (RTP packet part)\n} PingAck_t;\n\n/**\n * The complete ZRTP PingAck message.\n */\ntypedef struct PingAckPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    PingAck_t pingAck;              ///< PingAck message part\n    uint8_t crc[ZRTP_WORD_SIZE];    ///< CRC of ZRTP message\n} PingAckPacket_t;\n\n/**\n * SASrelay message\n * \n * The SASrelay message has a variable length. The following struct\n * defines the fixed part only. The SASrelay class initializes the\n * variable part.\n * \n * ZRTP encrypts a part of the SASrelay message, starting at @c hashH0 \n * and includes the variable part.\n */\ntypedef struct SASrelay {\n    uint8_t  hmac[HMAC_SIZE];           ///< MAC over the encrypted part of Commit message \n    uint8_t  iv[IV_SIZE];               ///< IV for CFB mode to encrypt part of Commit\n    uint8_t  filler[2];                 ///< Filler bytes\n    uint8_t  sigLength;                 ///< Length of an optional signature length (chap 7.2)\n    uint8_t  flags;                     ///< various flags to control behaviour\n    uint8_t  sas[ZRTP_WORD_SIZE];       ///< SAS algorithm to use\n    uint8_t  trustedSasHash[HASH_IMAGE_SIZE];  ///< New trusted SAS hash for enrolled client\n} SASrelay_t;\n\n/**\n * The complete ZRTP SASrelay message.\n */\ntypedef struct SASrelayPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    SASrelay_t sasrelay;            ///< SASrelay message fixed part\n} SASrelayPacket_t;\n\n/**\n * RelayAck message.\n * \n * The complete RelayAck message consists of ZRTP message header and\n * the CRC which is the only RelayAck specific data.\n */\ntypedef struct RelayAckPacket {\n    zrtpPacketHeader_t hdr;         ///< ZRTP Header\n    uint8_t crc[ZRTP_WORD_SIZE];    ///< CRC of ZRTP message\n} RelayAckPacket_t;\n\n#endif // ZRTPPACKET_H\n\n/**\n * @}\n */\n\n/** EMACS **\n * Local variables:\n * mode: c++\n * c-default-style: ellemtel\n * c-basic-offset: 4\n * End:\n */\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/zrtpB64Decode.c",
    "content": "/*\n * cdecoder.c - c source to a base64 decoding algorithm implementation\n *\n * This is part of the libb64 project, and has been placed in the public domain.\n * For details, see http://sourceforge.net/projects/libb64\n */\n\n#include <libzrtpcpp/zrtpB64Decode.h>\n\nint base64_decode_value(char value_in)\n{\n    static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};\n    static const char decoding_size = sizeof(decoding);\n    value_in -= 43;\n    if (value_in < 0 || value_in > decoding_size) return -1;\n    return decoding[(int)value_in];\n}\n\nvoid base64_init_decodestate(base64_decodestate* state_in)\n{\n    state_in->step = step_a;\n    state_in->plainchar = 0;\n}\n\nint base64_decode_block(const char* code_in, const int length_in, uint8_t *plaintext_out, base64_decodestate* state_in)\n{\n    const char* codechar = code_in;\n    uint8_t *plainchar = plaintext_out;\n    char fragment;\n\n    *plainchar = state_in->plainchar;\n\n    switch (state_in->step)\n    {\n        while (1)\n        {\n        case step_a:\n            do {\n                if (codechar == code_in+length_in)\n                {\n                    state_in->step = step_a;\n                    state_in->plainchar = *plainchar;\n                    return plainchar - plaintext_out;\n                }\n                fragment = (char)base64_decode_value(*codechar++);\n            } while (fragment < 0);\n            *plainchar    = (fragment & 0x03f) << 2;\n        case step_b:\n            do {\n                if (codechar == code_in+length_in)\n                {\n                    state_in->step = step_b;\n                    state_in->plainchar = *plainchar;\n                    return plainchar - plaintext_out;\n                }\n                fragment = (char)base64_decode_value(*codechar++);\n            } while (fragment < 0);\n            *plainchar++ |= (fragment & 0x030) >> 4;\n            *plainchar    = (fragment & 0x00f) << 4;\n        case step_c:\n            do {\n                if (codechar == code_in+length_in)\n                {\n                    state_in->step = step_c;\n                    state_in->plainchar = *plainchar;\n                    return plainchar - plaintext_out;\n                }\n                fragment = (char)base64_decode_value(*codechar++);\n            } while (fragment < 0);\n            *plainchar++ |= (fragment & 0x03c) >> 2;\n            *plainchar    = (fragment & 0x003) << 6;\n        case step_d:\n            do {\n                if (codechar == code_in+length_in)\n                {\n                    state_in->step = step_d;\n                    state_in->plainchar = *plainchar;\n                    return plainchar - plaintext_out;\n                }\n                fragment = (char)base64_decode_value(*codechar++);\n            } while (fragment < 0);\n            *plainchar++   |= (fragment & 0x03f);\n        }\n    }\n    /* control should not reach here */\n    return plainchar - plaintext_out;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/zrtpB64Encode.c",
    "content": "/*\ncencoder.c - c source to a base64 encoding algorithm implementation\n\nThis is part of the libb64 project, and has been placed in the public domain.\nFor details, see http://sourceforge.net/projects/libb64\n*/\n\n#include <libzrtpcpp/zrtpB64Encode.h>\n\nconst int CHARS_PER_LINE = 72;\n\nvoid base64_init_encodestate(base64_encodestate* state_in, int lineLength)\n{\n    state_in->step = step_A;\n    state_in->result = 0;\n    state_in->stepcount = 0;\n    if (lineLength < 0)\n        state_in->lineLength = CHARS_PER_LINE / 4;\n    else\n        state_in->lineLength = (lineLength+3) / 4;\n}\n\nchar base64_encode_value(const int8_t value_in)\n{\n    static const char* encoding = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n    if (value_in > 63) return '=';\n    return encoding[(int)value_in];\n}\n\nint base64_encode_block(const uint8_t *plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)\n{\n    const uint8_t *plainchar = plaintext_in;\n    const uint8_t *const plaintextend = plaintext_in + length_in;\n    char* codechar = code_out;\n    char result;\n    char fragment;\n\n    result = state_in->result;\n\n    switch (state_in->step)\n    {\n        while (1)\n        {\n        case step_A:\n            if (plainchar == plaintextend)\n            {\n                state_in->result = result;\n                state_in->step = step_A;\n                return codechar - code_out;\n            }\n            fragment = *plainchar++;\n            result = (fragment & 0x0fc) >> 2;\n            *codechar++ = base64_encode_value(result);\n            result = (fragment & 0x003) << 4;\n        case step_B:\n            if (plainchar == plaintextend)\n            {\n                state_in->result = result;\n                state_in->step = step_B;\n                return codechar - code_out;\n            }\n            fragment = *plainchar++;\n            result |= (fragment & 0x0f0) >> 4;\n            *codechar++ = base64_encode_value(result);\n            result = (fragment & 0x00f) << 2;\n        case step_C:\n            if (plainchar == plaintextend)\n            {\n                state_in->result = result;\n                state_in->step = step_C;\n                return codechar - code_out;\n            }\n            fragment = *plainchar++;\n            result |= (fragment & 0x0c0) >> 6;\n            *codechar++ = base64_encode_value(result);\n            result  = (fragment & 0x03f) >> 0;\n            *codechar++ = base64_encode_value(result);\n\n            if (state_in->lineLength > 0) {\n                state_in->stepcount++;\n                if (state_in->stepcount == state_in->lineLength)\n                {\n                    *codechar++ = '\\n';\n                    state_in->stepcount = 0;\n                }\n            }\n        }\n    }\n    /* control should not reach here */\n    return codechar - code_out;\n}\n\nint base64_encode_blockend(char* code_out, base64_encodestate* state_in)\n{\n    char* codechar = code_out;\n\n    switch (state_in->step)\n    {\n        case step_B:\n            *codechar++ = base64_encode_value(state_in->result);\n            *codechar++ = '=';\n            *codechar++ = '=';\n            break;\n        case step_C:\n            *codechar++ = base64_encode_value(state_in->result);\n            *codechar++ = '=';\n            break;\n        case step_A:\n            break;\n    }\n    if (state_in->lineLength > 0)\n        *codechar++ = '\\n';\n\n    return codechar - code_out;\n}\n\n"
  },
  {
    "path": "deps/pjsip/third_party/zsrtp/zrtp/zrtp/zrtpCacheSqliteBackend.c",
    "content": "/*\n  Copyright (C) 2012-2013 Werner Dittmann\n\n  This program is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation, either version 3 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n/*\n * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n#include <time.h>\n#include <sqlite3.h>\n\n#include <crypto/zrtpDH.h>\n\n#include <libzrtpcpp/zrtpB64Encode.h>\n#include <libzrtpcpp/zrtpB64Decode.h>\n\n#include <libzrtpcpp/zrtpCacheDbBackend.h>\n\n/* Some ported SQLite3 libs do not support the _v2 variants */\n#define SQLITE_USE_V2\n\n#ifdef SQLITE_USE_V2\n#define SQLITE_PREPARE sqlite3_prepare_v2\n#else\n#define SQLITE_PREPARE sqlite3_prepare\n#endif\n\n#if defined(_WIN32) || defined(_WIN64)\n# define snprintf _snprintf\n#else\n# include <sys/types.h>\n# include <fcntl.h>\n# include <unistd.h>\n#endif\n\n#ifdef TRANSACTIONS\nstatic const char *beginTransactionSql  = \"BEGIN TRANSACTION;\";\nstatic const char *commitTransactionSql = \"COMMIT;\";\n#endif\n\n/*\n * The database backend uses the following definitions if it implements the localZid storage.\n */\n\n/* The type field in zrtpIdOwn stores the following values */\nstatic const int32_t localZidStandard         = 1; /* this local ZID is not tied to a specific account */\nstatic const int32_t localZidWithAccount      = 2;\n\n/* Default data for account info if none specified */\nstatic const char *defaultAccountString = \"_STANDARD_\";\n\n\n/* *****************************************************************************\n * The SQLite master table.\n *\n * Used to check if we have valid ZRTP cache tables.\n */\nstatic char *lookupTables = \"SELECT name FROM sqlite_master WHERE type='table' AND name='zrtpIdOwn';\";\n\n\n/* *****************************************************************************\n * SQL statements to process the zrtpIdOwn table.\n */\nstatic const char *dropZrtpIdOwn =      \"DROP TABLE zrtpIdOwn;\";\n\n/* SQLite doesn't care about the VARCHAR length. */\nstatic char *createZrtpIdOwn = \"CREATE TABLE zrtpIdOwn(localZid CHAR(18), type INTEGER, accountInfo VARCHAR(1000));\";\n\nstatic char *selectZrtpIdOwn = \"SELECT localZid FROM zrtpIdOwn WHERE type = ?1 AND accountInfo = ?2;\";\nstatic char *insertZrtpIdOwn = \"INSERT INTO zrtpIdOwn (localZid, type, accountInfo) VALUES (?1, ?2, ?3);\";\n\n\n/* *****************************************************************************\n * SQL statements to process the remoteId table.\n */\nstatic const char *dropZrtpIdRemote =      \"DROP TABLE zrtpIdRemote;\";\n\nstatic const char *createZrtpIdRemote = \n    \"CREATE TABLE zrtpIdRemote \"\n    \"(remoteZid CHAR(16),  localZid CHAR(16), flags INTEGER,\"\n    \"rs1 BLOB(32), rs1LastUsed TIMESTAMP, rs1TimeToLive TIMESTAMP,\" \n    \"rs2 BLOB(32), rs2LastUsed TIMESTAMP, rs2TimeToLive TIMESTAMP,\"\n    \"mitmKey BLOB(32), mitmLastUsed TIMESTAMP, secureSince TIMESTAMP, preshCounter INTEGER);\";\n\nstatic const char *selectZrtpIdRemoteAll = \n    \"SELECT flags,\"\n    \"rs1, strftime('%s', rs1LastUsed, 'unixepoch'), strftime('%s', rs1TimeToLive, 'unixepoch'),\"\n    \"rs2, strftime('%s', rs2LastUsed, 'unixepoch'), strftime('%s', rs2TimeToLive, 'unixepoch'),\"\n    \"mitmKey, strftime('%s', mitmLastUsed, 'unixepoch'), strftime('%s', secureSince, 'unixepoch'),\"\n    \"preshCounter \"\n    \"FROM zrtpIdRemote WHERE remoteZid=?1 AND localZid=?2;\";\n\nstatic const char *insertZrtpIdRemote =\n    \"INSERT INTO zrtpIdRemote \"\n        \"(remoteZid, localZid, flags,\"\n        \"rs1, rs1LastUsed, rs1TimeToLive,\"\n        \"rs2, rs2LastUsed, rs2TimeToLive,\"\n        \"mitmKey, mitmLastUsed, secureSince, preshCounter)\"\n      \"VALUES\"\n        \"(?1, ?12, ?2,\"\n        \"?3, strftime('%s', ?4, 'unixepoch'), strftime('%s', ?5, 'unixepoch'),\"\n        \"?6, strftime('%s', ?7, 'unixepoch'), strftime('%s', ?8, 'unixepoch'),\"\n        \"?9, strftime('%s', ?10, 'unixepoch'), strftime('%s', ?11, 'unixepoch'), ?13);\";\n\nstatic const char *updateZrtpIdRemote = \n    \"UPDATE zrtpIdRemote SET \"\n    \"flags=?2,\"\n    \"rs1=?3, rs1LastUsed=strftime('%s', ?4, 'unixepoch'), rs1TimeToLive=strftime('%s', ?5, 'unixepoch'),\"\n    \"rs2=?6, rs2LastUsed=strftime('%s', ?7, 'unixepoch'), rs2TimeToLive=strftime('%s', ?8, 'unixepoch'),\"\n    \"mitmKey=?9, mitmLastUsed=strftime('%s', ?10, 'unixepoch'),\"\n    \"secureSince=strftime('%s', ?11, 'unixepoch'), preshCounter=?13 \"\n    \"WHERE remoteZid=?1 AND localZid=?12;\";\n\nstatic const char *selectZrtpIdRemoteAllNoCondition = \n    \"SELECT flags,\"\n    \"rs1, strftime('%s', rs1LastUsed, 'unixepoch'), strftime('%s', rs1TimeToLive, 'unixepoch'),\"\n    \"rs2, strftime('%s', rs2LastUsed, 'unixepoch'), strftime('%s', rs2TimeToLive, 'unixepoch'),\"\n    \"mitmKey, strftime('%s', mitmLastUsed, 'unixepoch'), strftime('%s', secureSince, 'unixepoch'),\"\n    \"preshCounter, remoteZid \"\n    \"FROM zrtpIdRemote ORDER BY secureSince DESC;\";\n\n\n/* *****************************************************************************\n * SQL statements to process the name table.\n *\n * The name tables holds free format information and binds it to the combination\n * of local, remote ZIDs and an optional account information.\n */\nstatic const char *dropZrtpNames = \"DROP TABLE zrtpNames;\";\n\nstatic const char *createZrtpNames =\n    \"CREATE TABLE zrtpNames \"\n    \"(remoteZid CHAR(16), localZid CHAR(16), flags INTEGER, \"\n    \"lastUpdate TIMESTAMP, accountInfo VARCHAR(1000), name VARCHAR(1000));\";\n\nstatic const char *selectZrtpNames =\n    \"SELECT flags, strftime('%s', lastUpdate, 'unixepoch'), name \"\n    \"FROM zrtpNames \"\n    \"WHERE remoteZid=?1 AND localZid=?2 AND accountInfo=?3;\";\n\nstatic const char *insertZrtpNames =\n    \"INSERT INTO zrtpNames \"\n        \"(remoteZid, localZid, flags, lastUpdate, accountInfo, name)\"\n      \"VALUES\"\n        \"(?1, ?2, ?4, strftime('%s', ?5, 'unixepoch'), ?3, ?6);\";\n\nstatic const char *updateZrtpNames =\n    \"UPDATE zrtpNames SET \"\n    \"flags=?4,\"\n    \"lastUpdate=strftime('%s', ?5, 'unixepoch'), name=?6 \"\n    \"WHERE remoteZid=?1 AND localZid=?2 AND accountInfo=?3;\";\n\n\n/* *****************************************************************************\n * A few helping macros. \n * These macros require some names/patterns in the methods that use these \n * macros:\n * \n * ERRMSG requires:\n * - a variable with name \"db\" is the pointer to sqlite3\n * - a char* with name \"errString\" points to a buffer of at least SQL_CACHE_ERR_BUFF_SIZE chars\n *\n * SQLITE_CHK requires:\n * - a cleanup label, the macro goes to that label in case of error\n * - an integer (int) variable with name \"rc\" that stores return codes from sqlite\n * - ERRMSG\n */\n#define ERRMSG  {if (errString) snprintf(errString, (size_t)DB_CACHE_ERR_BUFF_SIZE, \\\n                                         \"SQLite3 error: %s, line: %d, error message: %s\\n\", __FILE__, __LINE__, sqlite3_errmsg(db));}\n#define SQLITE_CHK(func) {                                              \\\n        rc = (func);                                                    \\\n        if(rc != SQLITE_OK) {                                           \\\n            ERRMSG;                                                     \\\n            goto cleanup;                                               \\\n        }                                                               \\\n    }\n\nstatic int b64Encode(const uint8_t *binData, int32_t binLength, char *b64Data, int32_t b64Length)\n{\n    base64_encodestate _state;\n    int codelength;\n\n    base64_init_encodestate(&_state, 0);\n    codelength = base64_encode_block(binData, binLength, b64Data, &_state);\n    codelength += base64_encode_blockend(b64Data+codelength, &_state);\n\n    return codelength;\n}\n\nstatic int b64Decode(const char *b64Data, int32_t b64length, uint8_t *binData, int32_t binLength)\n{\n    base64_decodestate _state;\n    int codelength;\n\n    base64_init_decodestate(&_state);\n    codelength = base64_decode_block(b64Data, b64length, binData, &_state);\n    return codelength;\n}\n\n#ifdef TRANSACTIONS\nstatic int beginTransaction(sqlite3 *db, char* errString)\n{\n    sqlite3_stmt *stmt;\n    int rc;\n\n    SQLITE_CHK(SQLITE_PREPARE(db, beginTransactionSql, strlen(beginTransactionSql)+1, &stmt, NULL));\n\n    rc = sqlite3_step(stmt);\n    sqlite3_finalize(stmt);\n    if (rc != SQLITE_DONE) {\n        ERRMSG;\n        return rc;\n    }\n    return SQLITE_OK;\n\n cleanup:\n    sqlite3_finalize(stmt);\n    return rc;\n}\n\nstatic int commitTransaction(sqlite3 *db, char* errString)\n{\n    sqlite3_stmt *stmt;\n    int rc;\n\n    SQLITE_CHK(SQLITE_PREPARE(db, commitTransactionSql, strlen(commitTransactionSql)+1, &stmt, NULL));\n\n    rc = sqlite3_step(stmt);\n    sqlite3_finalize(stmt);\n    if (rc != SQLITE_DONE) {\n        ERRMSG;\n        return rc;\n    }\n    return SQLITE_OK;\n\n cleanup:\n    sqlite3_finalize(stmt);\n    return rc;\n}\n#endif\n\n/**\n * Initialize remote ZID and remote name tables.\n *\n * First drop the remote ZID and remote name tables and create them again.\n * All information regarding remote peers is lost.\n */\nstatic int initializeRemoteTables(sqlite3 *db, char* errString)\n{\n    sqlite3_stmt * stmt;\n    int rc;\n\n    /* First drop them, just to be on the save side\n     * Ignore errors, there is nothing to drop on empty DB. If ZrtpIdOwn was\n     * deleted using DB admin command then we need to drop the remote id table\n     * and names also to have a clean state.\n     */\n    rc = SQLITE_PREPARE(db, dropZrtpIdRemote, strlen(dropZrtpIdRemote)+1, &stmt, NULL);\n    rc = sqlite3_step(stmt);\n    sqlite3_finalize(stmt);\n\n    rc = SQLITE_PREPARE(db, dropZrtpNames, strlen(dropZrtpNames)+1, &stmt, NULL);\n    rc = sqlite3_step(stmt);\n    sqlite3_finalize(stmt);\n\n    SQLITE_CHK(SQLITE_PREPARE(db, createZrtpIdRemote, strlen(createZrtpIdRemote)+1, &stmt, NULL));\n    rc = sqlite3_step(stmt);\n    sqlite3_finalize(stmt);\n    if (rc != SQLITE_DONE) {\n        ERRMSG;\n        return rc;\n    }\n    SQLITE_CHK(SQLITE_PREPARE(db, createZrtpNames, strlen(createZrtpNames)+1, &stmt, NULL));\n    rc = sqlite3_step(stmt);\n    sqlite3_finalize(stmt);\n    if (rc != SQLITE_DONE) {\n        ERRMSG;\n        return rc;\n    }\n    return 0;\n\n cleanup:\n    sqlite3_finalize(stmt);\n    return rc;\n\n}\n/**\n * Create ZRTP cache tables in database.\n *\n * openCache calls this function if it cannot find the table zrtpId_own. This indicates\n * that no ZRTP cache tables are available in the database.\n */\nstatic int createTables(sqlite3 *db, char* errString)\n{\n    sqlite3_stmt * stmt;\n    int rc;\n\n    /* no ZRTP cache tables were found - create them, first the OwnId table */\n    SQLITE_CHK(SQLITE_PREPARE(db, createZrtpIdOwn, strlen(createZrtpIdOwn)+1, &stmt, NULL));\n\n    rc = sqlite3_step(stmt);\n    sqlite3_finalize(stmt);\n    if (rc != SQLITE_DONE) {\n        ERRMSG;\n        return rc;\n    }\n    return initializeRemoteTables(db, errString);\n\n cleanup:\n    sqlite3_finalize(stmt);\n    return rc;\n}\n\nstatic int insertRemoteZidRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid, \n                                 const remoteZidRecord_t *remZid, char* errString)\n{\n    sqlite3 *db = (sqlite3*)vdb;\n    sqlite3_stmt *stmt;\n    int rc = 0;\n\n    char b64RemoteZid[IDENTIFIER_LEN*2] = {0};\n    char b64LocalZid[IDENTIFIER_LEN*2] = {0};\n\n    /* Get B64 code for remoteZid first */\n    b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);\n\n    /* Get B64 code for localZid now */\n    b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);\n\n    SQLITE_CHK(SQLITE_PREPARE(db, insertZrtpIdRemote, strlen(insertZrtpIdRemote)+1, &stmt, NULL));\n\n    /* For *_bind_* methods: column index starts with 1 (one), not zero */\n    SQLITE_CHK(sqlite3_bind_text(stmt,   1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_text(stmt,  12, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_int(stmt,    2, remZid->flags));\n    SQLITE_CHK(sqlite3_bind_blob(stmt,   3, remZid->rs1, RS_LENGTH, SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_int64(stmt,  4, remZid->rs1LastUse));\n    SQLITE_CHK(sqlite3_bind_int64(stmt,  5, remZid->rs1Ttl));\n    SQLITE_CHK(sqlite3_bind_blob(stmt,   6, remZid->rs2, RS_LENGTH, SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_int64(stmt,  7, remZid->rs2LastUse));\n    SQLITE_CHK(sqlite3_bind_int64(stmt,  8, remZid->rs2Ttl));\n    SQLITE_CHK(sqlite3_bind_blob(stmt,   9, remZid->mitmKey, RS_LENGTH, SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_int64(stmt, 10, remZid->mitmLastUse));\n    SQLITE_CHK(sqlite3_bind_int64(stmt, 11, remZid->secureSince));\n    SQLITE_CHK(sqlite3_bind_int(stmt,   13, remZid->preshCounter));\n\n    rc = sqlite3_step(stmt);\n    sqlite3_finalize(stmt);\n    if (rc != SQLITE_DONE) {\n        ERRMSG;\n        return rc;\n    }\n    return SQLITE_OK;\n\n cleanup:\n    sqlite3_finalize(stmt);\n    return rc;\n\n}\n\nstatic int updateRemoteZidRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid, \n                                 const remoteZidRecord_t *remZid, char* errString)\n{\n    sqlite3 *db = (sqlite3*)vdb;\n    sqlite3_stmt *stmt;\n    int rc;\n\n    char b64RemoteZid[IDENTIFIER_LEN*2] = {0};\n    char b64LocalZid[IDENTIFIER_LEN*2] = {0};\n\n    /* Get B64 code for remoteZid first */\n    b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);\n\n    /* Get B64 code for localZid now */\n    b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);\n\n    SQLITE_CHK(SQLITE_PREPARE(db, updateZrtpIdRemote, strlen(updateZrtpIdRemote)+1, &stmt, NULL));\n\n    /* For *_bind_* methods: column index starts with 1 (one), not zero */\n    /* Select for update with the following keys */\n    SQLITE_CHK(sqlite3_bind_text(stmt,   1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_text(stmt,  12, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));\n\n    /* Update the following values */\n    SQLITE_CHK(sqlite3_bind_int(stmt,    2, remZid->flags));\n    SQLITE_CHK(sqlite3_bind_blob(stmt,   3, remZid->rs1, RS_LENGTH, SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_int64(stmt,  4, remZid->rs1LastUse));\n    SQLITE_CHK(sqlite3_bind_int64(stmt,  5, remZid->rs1Ttl));\n    SQLITE_CHK(sqlite3_bind_blob(stmt,   6, remZid->rs2, RS_LENGTH, SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_int64(stmt,  7, remZid->rs2LastUse));\n    SQLITE_CHK(sqlite3_bind_int64(stmt,  8, remZid->rs2Ttl));\n    SQLITE_CHK(sqlite3_bind_blob(stmt,   9, remZid->mitmKey, RS_LENGTH, SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_int64(stmt, 10, remZid->mitmLastUse));\n    SQLITE_CHK(sqlite3_bind_int64(stmt, 11, remZid->secureSince));\n    SQLITE_CHK(sqlite3_bind_int(stmt,   13, remZid->preshCounter));\n\n    rc = sqlite3_step(stmt);\n    sqlite3_finalize(stmt);\n    if (rc != SQLITE_DONE) {\n        ERRMSG;\n        return rc;\n    }\n    return SQLITE_OK;\n\n cleanup:\n    sqlite3_finalize(stmt);\n    return rc;\n}\n\nstatic int readRemoteZidRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid, \n                               remoteZidRecord_t *remZid, char* errString)\n{\n    sqlite3 *db = (sqlite3*)vdb;\n    sqlite3_stmt *stmt;\n    int rc;\n    int found = 0;\n\n    char b64RemoteZid[IDENTIFIER_LEN*2] = {0};\n    char b64LocalZid[IDENTIFIER_LEN*2] = {0};\n\n    /* Get B64 code for remoteZid */\n    b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);\n\n    /* Get B64 code for localZid */\n    b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);\n\n    SQLITE_CHK(SQLITE_PREPARE(db, selectZrtpIdRemoteAll, strlen(selectZrtpIdRemoteAll)+1, &stmt, NULL));\n    SQLITE_CHK(sqlite3_bind_text(stmt, 1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_text(stmt, 2, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));\n\n    /* Getting data from result set: column index starts with 0 (zero), not one */\n    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {\n        remZid->flags =         sqlite3_column_int(stmt,    0);\n        memcpy(remZid->rs1,     sqlite3_column_blob(stmt,   1), RS_LENGTH);\n        remZid->rs1LastUse =    sqlite3_column_int64(stmt,  2);\n        remZid->rs1Ttl =        sqlite3_column_int64(stmt,  3);\n        memcpy(remZid->rs2,     sqlite3_column_blob(stmt,   4), RS_LENGTH);\n        remZid->rs2LastUse =    sqlite3_column_int64(stmt,  5);\n        remZid->rs2Ttl =        sqlite3_column_int64(stmt,  6);\n        memcpy(remZid->mitmKey, sqlite3_column_blob(stmt,   7), RS_LENGTH);\n        remZid->mitmLastUse =   sqlite3_column_int64(stmt,  8);\n        remZid->secureSince =   sqlite3_column_int64(stmt,  9);\n        remZid->preshCounter =  sqlite3_column_int(stmt,   10);\n        found++;\n    }\n    sqlite3_finalize(stmt);\n\n    if (rc != SQLITE_DONE) {\n        ERRMSG;\n        return rc;\n    }\n    if (found == 0) {\n        remZid->flags = 0;\n    }\n    else if (found > 1) {\n        if (errString) \n            snprintf(errString, DB_CACHE_ERR_BUFF_SIZE, \"ZRTP cache inconsistent. More than one remote ZID found: %d\\n\", found);\n        return 1;\n    }\n    return SQLITE_OK;\n\n cleanup:\n    sqlite3_finalize(stmt);\n    return rc;\n}\n\n\nstatic int readLocalZid(void *vdb, uint8_t *localZid, const char *accountInfo, char *errString)\n{\n    sqlite3 *db = (sqlite3*)vdb;\n    sqlite3_stmt *stmt;\n    char *zidBase64Text;\n    int rc = 0;\n    int found = 0;\n    int type = localZidWithAccount;\n\n    if (accountInfo == NULL || !strcmp(accountInfo, defaultAccountString)) {\n        accountInfo = defaultAccountString;\n        type = localZidStandard;\n    }\n\n    /* Find a localZid record for this combination */\n    SQLITE_CHK(SQLITE_PREPARE(db, selectZrtpIdOwn, strlen(selectZrtpIdOwn)+1, &stmt, NULL));\n\n    SQLITE_CHK(sqlite3_bind_int(stmt,  1, type));\n    SQLITE_CHK(sqlite3_bind_text(stmt, 2, accountInfo, strlen(accountInfo), SQLITE_STATIC));\n\n    /* Loop over result set and count it. However, use only the localZid of first row */\n    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {\n        if (found == 0) {\n            zidBase64Text = (char *)sqlite3_column_text(stmt, 0);\n            b64Decode(zidBase64Text, strlen(zidBase64Text), localZid, IDENTIFIER_LEN);\n        }\n        found++;\n    }\n    sqlite3_finalize(stmt);\n\n    if (rc != SQLITE_DONE) {\n        ERRMSG;\n        return rc;\n    }\n    /* No matching record found, create new local ZID for this combination and store in DB */\n    if (found == 0) {\n        char b64zid[IDENTIFIER_LEN+IDENTIFIER_LEN] = {0};\n        int b64len = 0;\n\n        /* create a 12 byte random value, convert to base 64, insert in zrtpIdOwn table */\n        randomZRTP(localZid, IDENTIFIER_LEN);\n        b64len = b64Encode(localZid, IDENTIFIER_LEN, b64zid, IDENTIFIER_LEN+IDENTIFIER_LEN);\n\n        SQLITE_CHK(SQLITE_PREPARE(db, insertZrtpIdOwn, strlen(insertZrtpIdOwn)+1, &stmt, NULL));\n\n        SQLITE_CHK(sqlite3_bind_text(stmt, 1, b64zid, b64len, SQLITE_STATIC));\n        SQLITE_CHK(sqlite3_bind_int(stmt,  2, type));\n        SQLITE_CHK(sqlite3_bind_text(stmt, 3, accountInfo, strlen(accountInfo), SQLITE_STATIC));\n\n        rc = sqlite3_step(stmt);\n        sqlite3_finalize(stmt);\n        if (rc != SQLITE_DONE) {\n            ERRMSG;\n            return rc;\n        }\n    }\n    else if (found > 1) {\n        if (errString) \n            snprintf(errString, DB_CACHE_ERR_BUFF_SIZE,\n                     \"ZRTP cache inconsistent. Found %d matching local ZID for account: %s\\n\", found, accountInfo);\n        return 1;\n    }\n    return SQLITE_OK;\n\n cleanup:\n    sqlite3_finalize(stmt);\n    return rc;\n}\n\n/*\n * SQLite use the following table structure to manage some internal data\n *\n * CREATE TABLE sqlite_master (\n *   type TEXT,\n *   name TEXT,\n *   tbl_name TEXT,\n *   rootpage INTEGER,\n *   sql TEXT\n * );\n */\n\nstatic int openCache(const char* name, void **vpdb, char *errString)\n{\n    sqlite3_stmt *stmt;\n    int found = 0;\n    sqlite3 **pdb = (sqlite3**)vpdb;\n    sqlite3 *db;\n\n#if !defined(_WIN32) && !defined(_WIN64)\n    /* try to create the file with 0600 permissions */\n    int fd = open(name, O_CREAT | O_RDWR, 0600);\n    if (fd != -1) {\n        close(fd);\n    }\n#endif\n\n#ifdef SQLITE_USE_V2\n    int rc = sqlite3_open_v2(name, pdb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL);\n#else\n    int rc = sqlite3_open(name, pdb);\n#endif\n    db = *pdb;\n    if (rc) {\n        ERRMSG;\n        return(rc);\n    }\n\n    /* check if ZRTP cache tables are already available, look if zrtpIdOwn is available */\n    SQLITE_CHK(SQLITE_PREPARE(db, lookupTables, strlen(lookupTables)+1, &stmt, NULL));\n    rc = sqlite3_step(stmt);\n    sqlite3_finalize(stmt);\n\n    if (rc == SQLITE_ROW) {\n        found++;\n    }\n    else if (rc != SQLITE_DONE) {\n        ERRMSG;\n        return rc;\n    }\n    /* If table zrtpOwnId not found then we have an empty cache DB */\n    if (found == 0) {\n        rc = createTables(db, errString);\n        if (rc)\n            return rc;\n    }\n    return SQLITE_OK;\n\n cleanup:\n    sqlite3_finalize(stmt);\n    return rc;\n}\n\nstatic int closeCache(void *vdb)\n{\n\n    sqlite3 *db = (sqlite3*)vdb;\n    sqlite3_close(db);\n    return SQLITE_OK;\n}\n\nstatic int clearCache(void *vdb, char *errString)\n{\n\n    sqlite3 *db = (sqlite3*)vdb;\n    sqlite3_stmt * stmt;\n    int rc;\n\n    rc = SQLITE_PREPARE(db, dropZrtpIdOwn, strlen(dropZrtpIdOwn)+1, &stmt, NULL);\n    rc = sqlite3_step(stmt);\n    sqlite3_finalize(stmt);\n\n    rc = createTables(db, errString);\n    if (rc)\n        return rc;\n    return SQLITE_OK;\n}\n\nstatic int insertZidNameRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,\n                               const char *accountInfo, zidNameRecord_t *zidName, char* errString)\n{\n    sqlite3 *db = (sqlite3*)vdb;\n    sqlite3_stmt *stmt;\n    int rc = 0;\n    char b64RemoteZid[IDENTIFIER_LEN*2] = {0};\n    char b64LocalZid[IDENTIFIER_LEN*2] = {0};\n\n    if (accountInfo == NULL) {\n        accountInfo = defaultAccountString;\n    }\n\n    /* Get B64 code for remoteZid */\n    b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);\n\n    /* Get B64 code for localZid */\n    b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);\n\n    SQLITE_CHK(SQLITE_PREPARE(db, insertZrtpNames, strlen(insertZrtpNames)+1, &stmt, NULL));\n\n    /* For *_bind_* methods: column index starts with 1 (one), not zero */\n    SQLITE_CHK(sqlite3_bind_text(stmt,  1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_text(stmt,  2, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_text(stmt,  3, accountInfo, strlen(accountInfo), SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_int(stmt,   4, zidName->flags));\n    SQLITE_CHK(sqlite3_bind_int64(stmt, 5, (int64_t)time(NULL)));\n    if (zidName->name != NULL) {\n        SQLITE_CHK(sqlite3_bind_text(stmt,   6, zidName->name, strlen(zidName->name), SQLITE_STATIC));\n    }\n    else {\n        SQLITE_CHK(sqlite3_bind_text(stmt,   6, \"_NO_NAME_\", 9, SQLITE_STATIC));\n    }\n    rc = sqlite3_step(stmt);\n    sqlite3_finalize(stmt);\n    if (rc != SQLITE_DONE) {\n        ERRMSG;\n        return rc;\n    }\n    return SQLITE_OK;\n\n cleanup:\n    sqlite3_finalize(stmt);\n    return rc;\n\n}\n\n\nstatic int updateZidNameRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,\n                               const char *accountInfo, zidNameRecord_t *zidName, char* errString)\n{\n    sqlite3 *db = (sqlite3*)vdb;\n    sqlite3_stmt *stmt;\n    int rc = 0;\n    char b64RemoteZid[IDENTIFIER_LEN*2] = {0};\n    char b64LocalZid[IDENTIFIER_LEN*2] = {0};\n\n    if (accountInfo == NULL) {\n        accountInfo = defaultAccountString;\n    }\n\n    /* Get B64 code for remoteZid */\n    b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);\n\n    /* Get B64 code for localZid */\n    b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);\n\n    SQLITE_CHK(SQLITE_PREPARE(db, updateZrtpNames, strlen(updateZrtpNames)+1, &stmt, NULL));\n\n    /* For *_bind_* methods: column index starts with 1 (one), not zero */\n    /* Select for update with the following values */\n    SQLITE_CHK(sqlite3_bind_text(stmt,   1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_text(stmt,   2, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_text(stmt,   3, accountInfo, strlen(accountInfo), SQLITE_STATIC));\n\n    /* Update the following vaulues */\n    SQLITE_CHK(sqlite3_bind_int(stmt,    4, zidName->flags));\n    SQLITE_CHK(sqlite3_bind_int64(stmt,  5, (int64_t)time(NULL)));\n    if (zidName->name != NULL) {\n        SQLITE_CHK(sqlite3_bind_text(stmt,   6, zidName->name, strlen(zidName->name), SQLITE_STATIC));\n    }\n    else {\n        SQLITE_CHK(sqlite3_bind_text(stmt,   6, \"_NO_NAME_\", 9, SQLITE_STATIC));\n    }\n    rc = sqlite3_step(stmt);\n    sqlite3_finalize(stmt);\n    if (rc != SQLITE_DONE) {\n        ERRMSG;\n        return rc;\n    }\n    return SQLITE_OK;\n\n cleanup:\n    sqlite3_finalize(stmt);\n    return rc;\n\n}\n\nstatic int readZidNameRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,\n                             const char *accountInfo, zidNameRecord_t *zidName, char* errString)\n{\n    sqlite3 *db = (sqlite3*)vdb;\n    sqlite3_stmt *stmt;\n    int rc;\n    int found = 0;\n\n    char b64RemoteZid[IDENTIFIER_LEN*2] = {0};\n    char b64LocalZid[IDENTIFIER_LEN*2] = {0};\n\n    if (accountInfo == NULL) {\n        accountInfo = defaultAccountString;\n    }\n    /* Get B64 code for remoteZid */\n    b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);\n\n    /* Get B64 code for localZid */\n    b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);\n\n    SQLITE_CHK(SQLITE_PREPARE(db, selectZrtpNames, strlen(selectZrtpNames)+1, &stmt, NULL));\n\n    SQLITE_CHK(sqlite3_bind_text(stmt, 1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_text(stmt, 2, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));\n    SQLITE_CHK(sqlite3_bind_text(stmt, 3, accountInfo, strlen(accountInfo), SQLITE_STATIC));\n\n    /* Getting data from result set: column index starts with 0 (zero), not one */\n    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {\n        zidName->flags = sqlite3_column_int(stmt,        0);\n        strncpy(zidName->name, (const char*)sqlite3_column_text(stmt, 2), zidName->nameLength);\n        zidName->nameLength = sqlite3_column_bytes(stmt, 2);    /* Return number of bytes in string */\n        found++;\n    }\n    sqlite3_finalize(stmt);\n\n    if (rc != SQLITE_DONE) {\n        ERRMSG;\n        return rc;\n    }\n    if (found == 0)\n        zidName->flags = 0;\n    else if (found > 1) {\n        if (errString)\n            snprintf(errString, DB_CACHE_ERR_BUFF_SIZE, \"ZRTP name cache inconsistent. More than one ZID name found: %d\\n\", found);\n        return 1;\n    }\n    return SQLITE_OK;\n\n cleanup:\n    sqlite3_finalize(stmt);\n    return rc;\n}\n\nstatic void *prepareReadAllZid(void *vdb, char *errString)\n{\n    sqlite3 *db = (sqlite3*)vdb;\n    sqlite3_stmt *stmt;\n    int rc;\n\n    SQLITE_CHK(SQLITE_PREPARE(db, selectZrtpIdRemoteAllNoCondition, strlen(selectZrtpIdRemoteAllNoCondition)+1, &stmt, NULL));\n    return stmt;\n\n  cleanup:\n    sqlite3_finalize(stmt);\n    return NULL;\n}\n\nstatic void *readNextZidRecord(void *vdb, void *vstmt, remoteZidRecord_t *remZid, char* errString)\n{\n    sqlite3 *db = (sqlite3*)vdb;\n    sqlite3_stmt *stmt;\n    char *zidBase64Text;\n    int rc;\n\n    if (vstmt == NULL)\n        return NULL;\n    stmt = (sqlite3_stmt*)vstmt;\n\n    /* Getting data from result set: column index starts with 0 (zero), not one */\n    if ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {\n        remZid->flags =         sqlite3_column_int(stmt,    0);\n        memcpy(remZid->rs1,     sqlite3_column_blob(stmt,   1), RS_LENGTH);\n        remZid->rs1LastUse =    sqlite3_column_int64(stmt,  2);\n        remZid->rs1Ttl =        sqlite3_column_int64(stmt,  3);\n        memcpy(remZid->rs2,     sqlite3_column_blob(stmt,   4), RS_LENGTH);\n        remZid->rs2LastUse =    sqlite3_column_int64(stmt,  5);\n        remZid->rs2Ttl =        sqlite3_column_int64(stmt,  6);\n        memcpy(remZid->mitmKey, sqlite3_column_blob(stmt,   7), RS_LENGTH);\n        remZid->mitmLastUse =   sqlite3_column_int64(stmt,  8);\n        remZid->secureSince =   sqlite3_column_int64(stmt,  9);\n        remZid->preshCounter =  sqlite3_column_int(stmt,   10);\n        zidBase64Text = (char *)sqlite3_column_text(stmt,  11);\n        b64Decode(zidBase64Text, strlen(zidBase64Text), remZid->identifier, IDENTIFIER_LEN);\n        return stmt;\n    }\n    sqlite3_finalize(stmt);\n\n    if (rc != SQLITE_DONE)\n        ERRMSG;\n    return NULL;\n}\n\nstatic void closeStatement(void *vstmt)\n{\n    sqlite3_stmt *stmt;\n\n    if (vstmt == NULL)\n        return;\n    stmt = (sqlite3_stmt*)vstmt;\n    sqlite3_finalize(stmt);\n}\n\nvoid getDbCacheOps(dbCacheOps_t *ops)\n{\n    ops->openCache = openCache;\n    ops->closeCache = closeCache;\n    ops->cleanCache = clearCache;\n\n    ops->readLocalZid = readLocalZid;\n\n    ops->readRemoteZidRecord =   readRemoteZidRecord;\n    ops->updateRemoteZidRecord = updateRemoteZidRecord;\n    ops->insertRemoteZidRecord = insertRemoteZidRecord;\n\n    ops->readZidNameRecord =   readZidNameRecord;\n    ops->updateZidNameRecord = updateZidNameRecord;\n    ops->insertZidNameRecord = insertZidNameRecord;\n\n    ops->prepareReadAllZid = prepareReadAllZid;\n    ops->readNextZidRecord = readNextZidRecord;\n    ops->closeStatement = closeStatement;\n}\n\n"
  },
  {
    "path": "deps/pjsip/version.mak",
    "content": "# Don't change the \"export PJ_VERSION_xxx\" style, they are parsed by setup.py\nexport PJ_VERSION_MAJOR  := 2\nexport PJ_VERSION_MINOR  := 4\nexport PJ_VERSION_REV    := 5\nexport PJ_VERSION_SUFFIX := -svn\n\nexport PJ_VERSION := $(PJ_VERSION_MAJOR).$(PJ_VERSION_MINOR)\n\nifneq ($(PJ_VERSION_REV),)\nexport PJ_VERSION := $(PJ_VERSION).$(PJ_VERSION_REV)\nendif\n\nifneq ($(PJ_VERSION_SUFFIX),)\nexport PJ_VERSION := $(PJ_VERSION)$(PJ_VERSION_SUFFIX)\nendif\n\n"
  },
  {
    "path": "docs/Dependencies.txt",
    "content": "\nDependencies for SIP SIMPLE client SDK\n--------------------------------------\n\nHome page: http://sipsimpleclient.org\n\n * python                   http://python.org                                     2.7\n * python-application       http://pypi.python.org/simple/python-application  >=2.8.0\n * python-cjson             http://pypi.python.org/pypi/python-cjson/         >=1.0.5\n * python-dateutil          http://niemeyer.net/python-dateutil                 >=1.4\n * python-eventlib          http://download.ag-projects.com/SipClient         >=0.1.0\n * python-greenlet          http://pypi.python.org/pypi/greenlet              >=0.3.2\n * python-gnutls            http://pypi.python.org/simple/python-gnutls       >=1.1.9\n * python-lxml              http://codespeak.net/lxml                         >=2.1.2\n * python-otr               http://pypi.python.org/pypi/python-otr/           >=1.2.0\n * python-msrplib           http://download.ag-projects.com/MSRP             >=0.20.0\n * python-xcaplib           http://download.ag-projects.com/XCAP             >=1.0.17\n * cython                   http://www.cython.org                            >=0.19.0\n * dnspython                http://www.dnspython.org                          >=1.9.0\n * twisted                  http://twistedmatrix.com/trac                     >=8.1.0\n * zope-interface           http://www.zope.org                               >=3.3.1\n\nOther libraries:\n\n * ffmpeg (libavformat, libswscale, libavcodec, libavutil) (>= 2.7)\n * libx264 (recent snapshot)\n * libvpx (>= 1.3.0)\n * libasund2\n * libuuid\n * libsqlite3\n * pkg-config\n * openssl\n\nTo compile the video dependencies (ffmpeg / libx264 / libvpx):\n\nexport SIPSIMPLE_FFMPEG_PATH=$HOME/work/ag-projects/video/local\n\nNOTE: yasm is required in order to enable asm optimizations. It does not\ncome preinstalled on OSX, so it has to be manually installed. (brew install\nyasm will do)\n\nNOTE: libx264 and libvpx can be installed also using Homebrew on OSX.\n\n\nFor ffmpeg:\n\n./configure --enable-shared --disable-static --enable-memalign-hack --enable-gpl --enable-libx264 --disable-avdevice --disable-swresample --disable-postproc --prefix=$SIPSIMPLE_FFMPEG_PATH\nmake\nmake install\n\n"
  },
  {
    "path": "docs/DeveloperGuide.txt",
    "content": "\nDeveloper guide\n---------------\n\nThe software allows you to create elegant real-time communications\napplications without having to read the +1200 RFC documents behind it. As a\nlibrary with a high-level API, the toolkit can be used to add voice, IM and\nPresence functionality to any network devices as long as Python/C\nenvironment is supported by such platform.\n\nThe developer guide is available at:\n\nhttp://sipsimpleclient.org/projects/sipsimpleclient/wiki/SipMiddlewareApi\n\n"
  },
  {
    "path": "docs/Install.debian",
    "content": "\nSIP SIMPLE client SDK installation on Debian\n--------------------------------------------\n\nHome page: http://sipsimpleclient.org\n\nThis document describes the installation procedure on Debian operating\nsystems from the official public repository maintained by AG Projects.\n\n\nConfigure Repository\n--------------------\n\nInstall the AG Projects debian software signing key: \n\nwget http://download.ag-projects.com/agp-debian-gpg.key\nsudo apt-key add agp-debian-gpg.key\n\nAdd these lines to /etc/apt/sources.list:\n\n\nDebian Unstable (Sid)\n---------------------\n\ndeb\thttp://ag-projects.com/debian unstable main\ndeb-src http://ag-projects.com/debian unstable main\n\n\nDebian Stable (Wheezy)\n-----------------------\n\ndeb\thttp://ag-projects.com/debian stable main\ndeb-src http://ag-projects.com/debian stable main\n\n\nUpdate the list of available packages:\n\nsudo apt-get update\n\n\nInstall SIP SIMPLE client SDK:\n\nsudo apt-get install python-sipsimple\n\n\nInstall the Command Line Clients:\n\nsudo apt-get install sipclients \n\n\nCreating Debian Packages\n------------------------\n\nInstall the building dependencies:\n\nsudo apt-get install cython cython-dbg python-setuptools devscripts \\\ndebhelper python-all-dev python-all-dbg libasound2-dev libssl-dev libsqlite3-dev\n\nFor adding Video support:\n\nsudo apt-get install libv4l-dev libavcodec-dev libavformat-dev libavutil-dev \\\nlibswscale-dev libswresample-dev libx264-dev libvpx-dev libavcodec-extra\n\nNote: do NOT use the Debian-Multimedia repositories.\n\nFor Ubuntu variants:\n\nsudo apt-get install libv4l-dev libavcodec-dev libavformat-dev libavutil-dev \\\nlibswscale-dev libswresample-dev libx264-dev libvpx-dev libavcodec-extra53\n\nObtain the source code using darcs as described in Install.linux document.\n\nCreate under each repository a clean distribution file:\n\npython setup.py sdist\n\nGo to the ./dist directory and untar the file created at the step above.\n\nGo to the newly created directory and type:\n\ndebuild -us -uc\n\nThe .deb and related files are built in the upper directory.\n\n"
  },
  {
    "path": "docs/Install.linux",
    "content": "\nSIP SIMPLE client SDK installation on Linux\n-------------------------------------------\n\nHome page: http://sipsimpleclient.org\n\nThis document described the installation procedure on Linux operating\nsystems.\n\n\nStep 1. Prerequisites\n---------------------\n\nBoth i386 or amd64 architectures are supported. Install the C compiling\nenvironment, Python 2.7 and the development version for the following\npackages:\n\n * openssl\n * ffmpeg\n\n\nStep 2. Install dependencies\n----------------------------\n\nSee Dependencies.txt for detailed description of the required libraries and\ntheir minimum version number.\n\nUse the appropriate package manager for your Linux distribution to install\nthe following packages, notice the minimum version numbers.\n\nYou can use the easy_install script provided by the python-setuptools\npackage to install the packages:\n\nsudo pip install -U cython dnspython lxml python-gnutls python-otr \\\npython-application twisted python-dateutil greenlet\n\n\nStep 3. Install SIP SIMPLE client SDK\n-------------------------------------\n\nThe SDK consists of four parts:\n\n 1. python-eventlib\n 2. XCAP library\n 3. MSRP library\n 4. SIP SIMPLE library\n\n# Eventlib\nif [ -d python-eventlib ]; then\n        cd python-eventlib\n        darcs pull -a\n        sudo python setup.py install\nelse\n        darcs get http://devel.ag-projects.com/repositories/python-eventlib\n        cd python-eventlib\n        sudo python setup.py install\nfi\ncd ..\n\n# XCAP library\nif [ -d python-xcaplib ]; then\n        cd python-xcaplib\n        darcs pull -a\n        sudo python setup.py install\nelse\n        darcs get http://devel.ag-projects.com/repositories/python-xcaplib\n        cd python-xcaplib\n        sudo python setup.py install\nfi\ncd ..\n\n# MSRP library\nif [ -d python-msrplib ]; then\n        cd python-msrplib\n        darcs pull -a\n        sudo python setup.py install\nelse\n        darcs get http://devel.ag-projects.com/repositories/python-msrplib\n        cd python-msrplib\n        sudo python setup.py install\nfi\ncd ..\n\n# SIP SIMPLE\nif [ -d python-sipsimple ]; then\n\tcd python-sipsimple\n\tdarcs pull -a\nelse\n\tdarcs get --set-scripts-executable http://devel.ag-projects.com/repositories/python-sipsimple\nfi\ncd..\n\ncd python-sipsimple\npython setup.py build_ext --pjsip-clean-compile\nsudo python setup.py install\n\nAdditional, you can install the command line interface scripts that can be\nused to test the SDK.\n\nif [ -d sipclients ]; then\n\tcd sipclients\n\tdarcs pull -a\nelse\n\tdarcs get --set-scripts-executable http://devel.ag-projects.com/repositories/sipclients\nfi\ncd..\n\nsudo python setup.py install\n\n"
  },
  {
    "path": "docs/Install.osx",
    "content": "\nInstallation procedure for SIP SIMPLE client SDK on MacOSX >= 10.11\n-------------------------------------------------------------------\n\nHome page: http://sipsimpleclient.org\n\nThis document describes the installation procedure on MacOSX >= 10.11\n\nThe installation procedure consists of the steps described below:\n\nStep 1. Prerequisites\nStep 2. Install Dependencies\nStep 3. Install SIP SIMPLE client SDK\n\n\nStep 1. Prerequisites\n---------------------\n\n * MacOSX >= 10.12\n * Apple Developer tools (XCode 9)\n * Homebrew from http://brew.sh\n * darcs version control tool\n * Python pip installer\n * Python virtualenv and virtualenvwrapper modules\n\n\n\nStep 2. Install Dependencies\n----------------------------\n\nSee Dependencies.txt for detailed description of the required libraries and\ntheir minimum version number.\n\nA. Install the C dependencies, the software will be installed\nunder /usr/local folder by default with Homebrew:\n\nbrew install darcs gnutls yasm pkg-config x264 libvpx mpfr libmpc\n\nNOTE: Install ffmpeg without SecureTransport support (or you app will be rejected\n      from the Mac App Store:\n\nbrew install -s ffmpeg --without-securetransport\n\nB.  Build and install the Python dependencies\n\nThe procedure below relies on the standard Python interpreter 2.7 that comes\nwith MacOSX and Xcode version 9.  A 64bit build will be produced.\n\nThis guide assumes all software is being installed in a virtualenv (except for\nthe packages installed with Homebrew, of course). \n\nInstall pip:\n\nsudo easy_install pip\n\nInstall virtualenv and virtualenvwrapper:\n\nsudo -H pip install virtualenv --upgrade --ignore-installed six\nsudo -H pip install virtualenvwrapper --upgrade --ignore-installed six\n\nThe above are installed in /Library/Python/2.7/site-packages\n\nAdd to ~/.bashrc:\n\nexport WORKON_HOME=$HOME/.virtualenvs\nexport PIP_VIRTUALENV_BASE=$WORKON_HOME\nexport PIP_RESPECT_VIRTUALENV=true\n[[ -f /usr/share/virtualenvwrapper/virtualenvwrapper_lazy.sh ]] && source /usr/share/virtualenvwrapper/virtualenvwrapper_lazy.sh\n[[ -f /usr/local/bin/virtualenvwrapper_lazy.sh ]] && source /usr/local/bin/virtualenvwrapper_lazy.sh\n\nCreating a virtual environment for python-simple\n\nmkvirtualenv -p $(which python2.7) sipsimple\n\nYou'll be dropped right into it. If you want to exit it:\n\ndeactivate\n\nAnd to activate the virtualenv again:\n\nworkon sipsimple\n\nInstall python dependencies:\n\npip install -U python-gnutls python-otr dnspython twisted \\\npython-application cython python-dateutil greenlet lxml\n\nAll packages are installed in:\n\n~/.virtualenvs/sipsimple/lib/python2.7/site-packages/\n\n\nStep 3. Build and install SIP SIMPLE client SDK\n-----------------------------------------------\n\nEnter virtual environment:\n\nworkon sipsimple\n\nThe SDK consists of four parts:\n\n 1. python-eventlib\n 2. XCAP library\n 3. MSRP library\n 4. SIP SIMPLE library\n\n# Eventlet\nif [ -d python-eventlib ]; then\n        cd python-eventlib\n        darcs pull -a\nelse\n        darcs get http://devel.ag-projects.com/repositories/python-eventlib\n        cd python-eventlib\nfi\npip install .\ncd ..\n\n# XCAP library\nif [ -d python-xcaplib ]; then\n        cd python-xcaplib\n        darcs pull -a\nelse\n        darcs get http://devel.ag-projects.com/repositories/python-xcaplib\n        cd python-xcaplib\nfi\npip install .\ncd ..\n\n# MSRP library\nif [ -d python-msrplib ]; then\n        cd python-msrplib\n        darcs pull -a\nelse\n        darcs get http://devel.ag-projects.com/repositories/python-msrplib\n        cd python-msrplib\nfi\npip install .\ncd ..\n\n# SIP SIMPLE library\nif [ -d python-sipsimple ]; then\n    cd python-sipsimple\n    darcs pull -a\nelse\n    darcs get --set-scripts-executable http://devel.ag-projects.com/repositories/python-sipsimple\n    cd python-sipsimple\nfi\n\nBuild and install SIP SIMPLE library:\n\npython setup.py build_ext --pjsip-clean-compile\npython setup.py install\n\nAdditional, you can install the command line interface scripts that can be\nused to test the SDK capabilities.\n\nif [ -d sipclients ]; then\n    cd sipclients\n    darcs pull -a\nelse\n    darcs get --set-scripts-executable http://devel.ag-projects.com/repositories/sipclients\n    cd sipclients\nfi\npython setup.py install\ncd ..\n\n"
  },
  {
    "path": "docs/Install.rasbian",
    "content": "\nSIP SIMPLE client SDK installation on Rasbian\n---------------------------------------------\n\nHome page: http://sipsimpleclient.org\n\nThis document described the installation procedure on Rasbian Linux\noperating system on a Rasberry Pi (armhf architecture).\n\nNote. Acoustic Echo Cancellation is not available on arm architecture\n\n\nInstall building dependencies \n-----------------------------\n\nsudo apt-get install darcs devscripts libgmp3-dev cython python-lxml python-dnspython \\\npython-twisted python-dateutil python-greenlet libv4l-dev libavcodec-dev pkg-config \\\nlibavformat-dev libavutil-dev libswscale-dev libx264-dev libvpx-dev python-all-dev \\\nlibsqlite3-dev uuid-dev python-all-dbg cython-dbg libasound2-dev libssl-dev \\\nlibmpfr-dev libmpfr-doc libmpc-dev libffi-dev dh-python python-enum34 \\\npython-cryptography python-gnutls python-gnutls python-gmpy2 -y\n\n\nBuild the debian packages\n-------------------------\n\nObtain the source code from AG Projects using darcs command:\n\ndarcs get --set-scripts-executable http://devel.ag-projects.com/repositories/project\n\nFor each of the projects listed bellow:\n\n * python-application\n * python-otr\n * python-eventlib\n * python-xcap\n * python-msrp\n * python-sipsimple\n * sipclients\n\nEnter the directory where each project has been downloaded and prepare the\nbuild directory:\n\npython setup.py sdist\n\nGo to the ./dist directory and untar the file created at the step above.\n\nGo to the newly created directory and type:\n\ndebuild -us -uc --no-sign\n\nThe .deb and related files are built in one of the upper directories.\n\nThe end result looks like the following:\n\n * python-application_2.8.0_all.deb\n * python-eventlib_0.2.5_all.deb\n * python-msrplib_0.20.0_all.deb\n * python-otr_1.2.2_all.deb\n * python-sipsimple_3.5.0_armhf.deb\n * python-xcaplib_1.2.2_all.deb\n * sipclients_3.5.3_all.deb\n\nUse dpkg -i package_name.deb command to install the software.\n\n\nPrebuild binary packages\n------------------------\n\nYou can download and install prebuild binary packages from:\n\nhttp://download.ag-projects.com/SipClient/Raspberry/\n\n"
  },
  {
    "path": "docs/Install.ubuntu",
    "content": "\nSIP SIMPLE client SDK installation on Ubuntu\n--------------------------------------------\n\nHome page: http://sipsimpleclient.org\n\nThis document describes the installation procedure on Ubuntu operating\nsystems from the official public repository maintained by AG Projects.\n\n\nConfigure Repository\n--------------------\n\nInstall the AG Projects debian software signing key: \n\nwget http://download.ag-projects.com/agp-debian-gpg.key\nsudo apt-key add agp-debian-gpg.key\n\nAdd the repository to /etc/apt/sources.list (run commands as root):\n\necho \"deb       http://ag-projects.com/ubuntu `lsb_release -c -s` main\" >> /etc/apt/sources.list\necho \"deb-src   http://ag-projects.com/ubuntu `lsb_release -c -s` main\" >> /etc/apt/sources.list\n\n\nUpdate the list of available packages:\n\nsudo apt-get update\n\n\nInstall SIP SIMPLE client SDK:\n\nsudo apt-get install python-sipsimple\n\n\nInstall the Command Line Clients:\n\nsudo apt-get install sipclients\n\n"
  },
  {
    "path": "docs/Install.windows",
    "content": "\nSIP SIMPLE client SDK installation on Microsoft Windows\n-------------------------------------------------------\n\nHome page: http://sipsimpleclient.org\n\nThis document describes the installation procedure on Microsoft Windows\noperating systems. Supported versions are Windows XP or higher.\n\n\nStep 1. Prerequisites\n---------------------\n\nFirst download and install darcs version control utility from darcs.net:\n\nhttp://darcs.net/binaries/windows/darcs-2.8.1-win1.msi\n\nThe building process is designed to work with the MSYS2 environment and the\nMinGW-w64 compiler toolchain. Other approaches might work but they are not\ntested nor supported.\n\nMSYS2: MSYS2 is a minimal Unix-like environment for Windows. It includes a port\nof the 'pacman' package manager (ported from Arch Linux) and a pretty extensive\ncollection of packages which can be easily installed. It contains packages for the\nMinGW-w64 toolchain, for 32 and 64 bit architectures.\n\nMinGW-w64: MinGW is a minimal compilation toolchain for Windows. It contains GCC and\nallows for compilation of native applications for Windows. The original MinGW project\n(available at http://mingw.org, henceforth referred to as 'MinGW32') didn't support\n64 bit Windows so the MinGW-w64 project was created. It contains support for both 32\nand 64 bit architectures and generally it's better maintained than MinGW32.\n\n\nStep 1.1. Installing MSYS2 and MinGW-w64\n----------------------------------------\n\nThe following instructions will guide you through the installation of a MSYS2 and MinGW-w64\ninstallation for a 32 bit Windows system. A 64 bit build is definitely possible but\nhasn't been tested.\n\n* Go to http://msys2.github.io and download the 32 bit (i686) MSYS2 installer\n* Run it and install it on C:\\msys2 (or any other path, but note it has to be\n  ASCII only and with no spaces! The no spaces restriction also applies to the\n  paths of the packages that will be built during the installation)\n* Once the process is finished, check the box to \"Run MSYS2 32bit now\", a new\n  terminal window will appear\n* Upgrade the system packages by following the instructions from:\n  http://msys2.github.io\n* Install the compiler toolchain and assorted tools:\n  pacman -S mingw-w64-i686-toolchain make mingw-w64-i686-libtool autoconf automake-wrapper\n\nAfter MSYS2 was installed a new menu group was created on the Window start menu: \"MSYS2 32bit\",\nwhich contains 3 links: MinGW-w64 Win32 Shell, MinGW-w64 Win64 Shell and MSYS2 Shell. We'll\nuse \"MinGW-w64 Win32 Shell\" from now on, since it will contain the 32 bit MinGW-w64 toolchain\nin the path.\n\n\nStep 1.2. Installing Python 2.7\n-------------------------------\n\nIn order to avoid problems derived from using multiple C runtimes, we are going to\ninstall Python 2.7 using pacman. The Python binaries that are available for download\non Python's official website are compiled with Visual Studio, and if we use MinGW\nto compile libraries which are then used by Python modules we are at risk because\nthe resulting application would load 2 different C runtimes.\n\n* Install Python 2.7 by running: pacman -S mingw-w64-i686-python2\n* Install pip/setuptools: pacman -S mingw-w64-i686-python2-pip\n\nNOTE: At the time of this writing the Python REPL needs to be started with \"python -i\" due to\na problem with the ncurses libraries.\n\n\nStep 2. Install dependencies\n----------------------------\n\nSee Dependencies.txt for detailed description of the required libraries and\ntheir minimum version number.\n\n* Install required dependencies with pacman:\n  pacman -S mingw-w64-i686-gnutls mingw-w64-i686-python2-lxml mingw-w64-i686-ffmpeg mingw-w64-i686-sqlite3 msys2-w32api-headers mingw-w64-i686-gmp mingw-w64-i686-mpc mingw-w64-i686-mpfr\n* Install the Python package dependencies:\n  pip install cython dnspython twisted python-dateutil greenlet python-application python-cjson python-gnutls python-otr\n\n\nStep 2.1. Install python-otr dependencies (if installation fails)\n-----------------------------------------------------------------\n\nAt the time of this writing installing python-otr straight from PyPI is not\npossible due to some of its dependencies having problems in the MinGW\ntoolchain.\n\nInstalling these from source works though, so let's do that.\n\n* Install Mercurial and Git:\n  pacman -S mercurial git\n\n* Install cffi:\n  hg clone https://bitbucket.org/cffi/cffi\n  cd cffi\n  pip install .\n\n* Install cryptography:\n  git clone https://github.com/pyca/cryptography.git\n  cd cryptography\n  pip install .\n\n  Note: if pip install fails, with:\n\n    distutils.errors.DistutilsPlatformError: VC 6.0 is not supported by this module\n\n  check: https://github.com/pypa/setuptools/issues/1118 (PeterMosmans' answer)\n\n* Install gmpy2:\n  git clone https://github.com/aleaxit/gmpy.git\n  cd gmpy\n  pip install .\n\n* Install python-otr:\n  pip install python-otr\n\n\nStep 2.2. Build and install some extra packages\n-----------------------------------------------\n\nmingw-w64-intsafe-headers\n\n* Get the package code: darcs get http://devel.ag-projects.com/repositories/windows/mingw-w64-intsafe-headers\n* Enter the directory and build+install the package: cd mingw-w64-intsafe-headers && makepkg-mingw -cfiL --nocheck --nosign\n\nmingw-w64-dshow-baseclasses\n\n* Get the package code: darcs get http://devel.ag-projects.com/repositories/windows/mingw-w64-dshow-baseclasses\n* Enter the directory and build+install the package: cd mingw-w64-dshow-baseclasses && makepkg-mingw -cfiL --nocheck --nosign\n\n\nStep 3. Install SIP SIMPLE client SDK\n-------------------------------------\n\nThe SDK consists of four parts:\n\n 1. python-eventlib\n 2. XCAP library\n 3. MSRP library\n 4. SIP SIMPLE library itself\n\nMake sure that the path where you download the software below does not\ncontain any space in its name.\n\n# Eventlib\nif [ -d python-eventlib ]; then\n        cd python-eventlib\n        darcs pull -a\nelse\n        darcs get http://devel.ag-projects.com/repositories/python-eventlib\n        cd python-eventlib\nfi\npip install .\ncd ..\n\n# XCAP library\nif [ -d python-xcaplib ]; then\n        cd python-xcaplib\n        darcs pull -a\nelse\n        darcs get http://devel.ag-projects.com/repositories/python-xcaplib\n        cd python-xcaplib\nfi\npip install .\ncd ..\n\n# MSRP library\nif [ -d python-msrplib ]; then\n        cd python-msrplib\n        darcs pull -a\nelse\n        darcs get http://devel.ag-projects.com/repositories/python-msrplib\n        cd python-msrplib\nfi\npip install .\ncd ..\n\n# SIP SIMPLE\nif [ -d python-sipsimple ]; then\n        cd python-sipsimple\n        darcs pull -a\nelse\n        darcs get --set-scripts-executable http://devel.ag-projects.com/repositories/python-sipsimple\n        cd python-sipsimple\nfi\n./build_inplace --pjsip-clean-compile\npip install .\ncd ..\n\n\nThe software has been installed in C:\\msys2\\mingw32\\lib\\python2.7\\site-packages\n\n"
  },
  {
    "path": "docs/Licenses.txt",
    "content": "\nThis document describes the licenses for the SIP SIMPLE client SDK and its\ndependencies.\n\n\nSIP SIMPLE Client SDK\n---------------------\n\nSIP SIMPLE Client SDK is licensed under GPLv3.\n\n\nLibxml2 \n-------\n\nLibxml2 is the XML C parser and toolkit developed for the Gnome project (but\nusable outside of the Gnome platform), it is available under the MIT\nLicense.\n\n\nLibxslt\n-------\n\nLibxslt is a language for transforming XML documents into other XML\ndocuments. It is available under the MIT License.\n\n\nGnuTLS\n------\n\nGnuTLS is a project that aims to develop a library which provides a secure\nlayer, over a reliable transport layer. Currently the GnuTLS library\nimplements the proposed standards by the IETF's TLS working group. The\nlibrary is licensed under the GNU Lesser General Public License version 2.1.\n\n\nSetuptools\n----------\n\nDownload, build, install, upgrade, and uninstall Python packages. It is\navailable under the Python Software Foundation License.\n\n\nCython \n------\n\nA language that makes writing C extensions for the Python language as easy\nas Python itself. Cython is available under the open source Apache License.\n\n\nPython-application \n------------------\n\nA collection of modules that are useful when building python applications.\nTheir purpose is to eliminate the need to divert resources into implementing\nthe small tasks that every application needs to do in order to run\nsuccessfully and focus instead on the application logic itself. Is available\nunder GNU Library or Lesser General Public License (LGPL).\n\n\nDnspython\n---------\n\nA DNS toolkit for Python. It supports almost all record types. It can be\nused for queries, zone transfers, and dynamic updates. Dnspython originated\nat Nominum where it was developed to facilitate the testing of DNS software.\nNominum has generously allowed it to be open sourced under a BSD-style\nlicense.\n\n\nLxml\n----\n\nLxml is the most feature-rich and easy-to-use library for working with XML\nand HTML in the Python language. A Pythonic binding for the libxml2 and\nlibxslt libraries. It is unique in that it combines the speed and feature\ncompleteness of these libraries with the simplicity of a native Python API,\nmostly compatible but superior to the well-known ElementTree API. The lxml\nlibrary is shipped under a BSD license.\n\n\nTwisted\n-------\n\nA networking engine written in Python, supporting numerous protocols. It\ncontains a web server, numerous chat clients, chat servers, mail servers,\nand more. The source code is available under a proprietary license (non GPL).\n\n\nPylib\n-----\n\nThe pylib is a development support library featuring py.test, ad-hoc\ndistributed execution, micro-threads (greenlets) and uniform local path and\nsvn abstractions. Is provided under MIT License.\n\n\nPython-gnutls\n-------------\n\nPython wrapper for gnutls available under either GPL or Lesser General\nPublic License (LGPL).\n\n\nEventlet_twisted\n----------------\n\nEventlet makes asynchronous programming look like synchronous, thus\nachieving higher signal-to-noise ratio than traditional twisted programs\nhave. It is available under the MIT License.\n\n\nPython-xcaplib\n--------------\n\nXCAP protocol, defined in RFC 4825, allows a client to read, write, and\nmodify application configuration data stored in XML format on a server. XCAP\nmaps XML document sub-trees and element attributes to HTTP URIs, so that\nthese components can be directly accessed by HTTP. An XCAP server used by\nXCAP clients to store data like presence policy in combination with a SIP\nPresence server that supports PUBLISH/SUBSCRIBE/NOTIFY SIP methods can\nprovide a complete SIP SIMPLE solution. The XCAP client example script\nprovided by this package can be used to manage documents on an XCAP server.\nThe software is available under either GPL or Lesser General Public License\n(LGPL).\n\n\nPjlib\n-----\n\nA small footprint, high performance, ultra portable abstraction library and\nframework, used by PJSIP and PJMEDIA. PJLIB is about the only library that\nPJLIB-UTIL, PJMEDIA, and PJSIP should depend, as it provides complete\nabstraction not only to Operating System dependent features, but it is also\ndesigned to abstract LIBC and provides some useful data structures too. A\ncross-platforms portability and framework library. Available under GPL or an\nalternative non-GPL license.\n\n\nPjlib-util\n----------\n\nPJLIB-UTIL is an auxiliary library providing supports for PJMEDIA and PJSIP.\nSome of the functions/components in this library: small footprint XML\nparsing, STUN client library, asynchronous/caching DNS resolver,\nhashing/encryption functions, etc. Available under GPL or an alternative\nnon-GPL license.\n\n\nPjnat\n-----\n\nPJNATH is a new library, available in the SVN trunk, for helping the\napplications with NAT traversal. It implements the latest specification of\nSession Traversal Utilities for NAT (STUN), Obtaining Relay Addresses from\nSTUN (TURN), and Interactive Connectivity Establishment (ICE). Available\nunder GPL or alternative non-GPL license.\n\n\nPjmedia\t\n-------\n\nPJMEDIA is a complementary library for PJSIP to build a complete,\nfull-featured SIP user agent applications such as softphones/hardphones,\ngateways, or B2BUA. Available under GPL or an alternative non-GPL license.\n\n\nPjmedia-codec\n-------------\n\nA placeholder library to support various multimedia codecs. Available under\nGPL or an alternative non-GPL license.\n\n\nPjsip\n-----\n\nA SIP protocol stack, the main bulding block for this project. Available\nunder GPL or an alternative non-GPL license. The non-GPL license is\navailable from its licensor for a one time fee.\n\n\nEventlet\n--------\n\nEventlet is a networking library written in Python. It achieves high\nscalability by using non-blocking io while at the same time retaining high\nprogrammer usability by using coroutines to make the non-blocking io\noperations appear blocking at the source code level. It is available under\nMIT license.\n\n\nGreenlet\n--------\n\nLightweight in-process concurrent programming. The \"greenlet\" package is a\nspin-off of Stackless, a version of CPython that supports micro-threads\ncalled \"tasklets\". Tasklets run pseudo-concurrently (typically in a single\nor a few OS-level threads) and are synchronized with data exchanges on\n\"channels\". It is provided under MIT license.\n\n"
  },
  {
    "path": "docs/Uninstall.txt",
    "content": "\nhttp://sipsimpleclient.org/projects/sipsimpleclient/wiki/SipInstallation\n\n"
  },
  {
    "path": "setup.py",
    "content": "#!/usr/bin/python2\n\nimport glob\nimport os\n\nfrom distutils.core import setup\nfrom distutils.extension import Extension\nfrom setup_pjsip import PJSIP_build_ext\n\n\ndef find_packages(root):\n    return [directory.replace(os.path.sep, '.') for directory, sub_dirs, files in os.walk(root) if '__init__.py' in files]\n\n\nclass PackageInfo(object):\n    def __init__(self, info_file):\n        with open(info_file) as f:\n            exec(f.read(), self.__dict__)\n        self.__dict__.pop('__builtins__', None)\n\n    def __getattribute__(self, name):  # this is here to silence the IDE about missing attributes\n        return super(PackageInfo, self).__getattribute__(name)\n\n\npackage_info = PackageInfo(os.path.join('sipsimple', '__info__.py'))\n\n\nsetup(\n    name=package_info.__project__,\n    version=package_info.__version__,\n\n    description=package_info.__summary__,\n    license=package_info.__license__,\n    url=package_info.__webpage__,\n\n    author=package_info.__author__,\n    author_email=package_info.__email__,\n\n    platforms=[\"Platform Independent\"],\n    classifiers=[\n        \"Development Status :: 5 - Production/Stable\",\n        \"Intended Audience :: Developers\",\n        \"Intended Audience :: Telecommunications Industry\",\n        \"License :: OSI Approved :: GNU General Public License (GPL)\",\n        \"Operating System :: OS Independent\",\n        \"Programming Language :: C\",\n        \"Programming Language :: Cython\",\n        \"Programming Language :: Python\"\n    ],\n\n    packages=find_packages('sipsimple'),\n    package_data={\n        'sipsimple.payloads': ['xml-schemas/*']\n    },\n\n    ext_modules=[\n        Extension(name=\"sipsimple.core._core\", sources=[\"sipsimple/core/_core.pyx\", \"sipsimple/core/_core.pxd\"] + glob.glob(os.path.join(\"sipsimple\", \"core\", \"_core.*.pxi\"))),\n        Extension(name=\"sipsimple.util._sha1\", sources=[\"sipsimple/util/_sha1.pyx\"], depends=[\"sipsimple/util/_sha1.h\"])\n    ],\n\n    cmdclass={\n        'build_ext': PJSIP_build_ext\n    },\n\n    provides=['sipsimple']\n)\n"
  },
  {
    "path": "setup_pjsip.py",
    "content": "\nimport errno\nimport itertools\nimport os\nimport platform\nimport re\nimport shutil\nimport subprocess\nimport sys\n\nif sys.platform.startswith('linux'):\n    sys_platform = 'linux'\nelif sys.platform.startswith('freebsd'):\n    sys_platform = 'freebsd'\nelse:\n    sys_platform = sys.platform\n\n\n# Hack to set environment variables before importing distutils\n# modules that will fetch them and set the compiler and linker\n# to be used. -Saul\n\nif sys_platform == \"darwin\":\n    min_osx_version = \"10.13\"\n    try:\n        osx_sdk_path = subprocess.check_output([\"xcodebuild\", \"-version\", \"-sdk\", \"macosx\", \"Path\"]).strip()\n    except subprocess.CalledProcessError as e:\n        raise RuntimeError(\"Could not locate SDK path: %s\" % str(e))\n    # OpenSSL (must be installed with Homebrew)\n    ossl_cflags = \"-I/usr/local/opt/openssl/include\"\n    ossl_ldflags = \"-L/usr/local/opt/openssl/lib\"\n    # SQLite (must be installed with Homebrew)\n    sqlite_cflags = \"-I/usr/local/opt/sqlite/include\"\n    sqlite_ldflags = \"-L/usr/local/opt/sqlite/lib\"\n    # Prepare final flags\n    arch_flags =  \"-arch x86_64\"\n    local_cflags = \" %s %s %s -mmacosx-version-min=%s -isysroot %s\" % (arch_flags, ossl_cflags, sqlite_cflags, min_osx_version, osx_sdk_path)\n    local_ldflags = \" %s %s %s -isysroot %s\" % (arch_flags, ossl_ldflags, sqlite_ldflags, osx_sdk_path)\n    os.environ['CFLAGS'] = os.environ.get('CFLAGS', '') + local_cflags\n    os.environ['LDFLAGS'] = os.environ.get('LDFLAGS', '') + local_ldflags\n    os.environ['ARCHFLAGS'] = arch_flags\n    os.environ['MACOSX_DEPLOYMENT_TARGET'] = min_osx_version\n\nfrom distutils import log\nfrom distutils.dir_util import copy_tree\nfrom distutils.errors import DistutilsError\nfrom Cython.Distutils import build_ext\n\n\nclass PJSIP_build_ext(build_ext):\n    config_site = [\"#define PJ_SCANNER_USE_BITWISE 0\",\n                   \"#define PJSIP_SAFE_MODULE 0\",\n                   \"#define PJSIP_MAX_PKT_LEN 262144\",\n                   \"#define PJSIP_UNESCAPE_IN_PLACE 1\",\n                   \"#define PJMEDIA_AUDIO_DEV_HAS_COREAUDIO %d\" % (1 if sys_platform==\"darwin\" else 0),\n                   \"#define PJMEDIA_AUDIO_DEV_HAS_ALSA %d\" % (1 if sys_platform==\"linux\" else 0),\n                   \"#define PJMEDIA_AUDIO_DEV_HAS_WMME %d\" % (1 if sys_platform==\"win32\" else 0),\n                   \"#define PJMEDIA_HAS_SPEEX_AEC 0\",\n                   \"#define PJMEDIA_HAS_WEBRTC_AEC %d\" % (1 if re.match('i\\d86|x86|x86_64', platform.machine()) else 0),\n                   \"#define PJMEDIA_RTP_PT_TELEPHONE_EVENTS 101\",\n                   \"#define PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR \\\"101\\\"\",\n                   \"#define PJMEDIA_STREAM_ENABLE_KA PJMEDIA_STREAM_KA_EMPTY_RTP\",\n                   \"#define PJMEDIA_STREAM_VAD_SUSPEND_MSEC 0\",\n                   \"#define PJMEDIA_CODEC_MAX_SILENCE_PERIOD -1\",\n                   \"#define PJ_ICE_MAX_CHECKS 256\",\n                   \"#define PJ_LOG_MAX_LEVEL 6\",\n                   \"#define PJ_IOQUEUE_MAX_HANDLES 1024\",\n                   \"#define PJ_DNS_RESOLVER_MAX_TTL 0\",\n                   \"#define PJ_DNS_RESOLVER_INVALID_TTL 0\",\n                   \"#define PJSIP_TRANSPORT_IDLE_TIME 7200\",\n                   \"#define PJ_ENABLE_EXTRA_CHECK 1\",\n                   \"#define PJSIP_DONT_SWITCH_TO_TCP 1\",\n                   \"#define PJMEDIA_VIDEO_DEV_HAS_SDL 0\",\n                   \"#define PJMEDIA_VIDEO_DEV_HAS_AVI 0\",\n                   \"#define PJMEDIA_VIDEO_DEV_HAS_FB 1\",\n                   \"#define PJMEDIA_VIDEO_DEV_HAS_V4L2 %d\" % (1 if sys_platform==\"linux\" else 0),\n                   \"#define PJMEDIA_VIDEO_DEV_HAS_AVF %d\" % (1 if sys_platform==\"darwin\" else 0),\n                   \"#define PJMEDIA_VIDEO_DEV_HAS_DSHOW %d\" % (1 if sys_platform==\"win32\" else 0),\n                   \"#define PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC 1\",\n                   \"#define PJMEDIA_VIDEO_DEV_HAS_NULL 1\"]\n\n    user_options = build_ext.user_options\n    user_options.extend([\n        (\"pjsip-clean-compile\", None, \"Clean PJSIP tree before compilation\"),\n        (\"pjsip-disable-assertions\", None, \"Disable assertion checks within PJSIP\"),\n        (\"pjsip-verbose-build\", None, \"Print output of PJSIP compilation process\")\n        ])\n    boolean_options = build_ext.boolean_options\n    boolean_options.extend([\"pjsip-clean-compile\", \"pjsip-disable-assertions\", \"pjsip-verbose-build\"])\n\n    @staticmethod\n    def distutils_exec_process(cmdline, silent=True, input=None, **kwargs):\n        \"\"\"Execute a subprocess and returns the returncode, stdout buffer and stderr buffer.\n        Optionally prints stdout and stderr while running.\"\"\"\n        try:\n            sub = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)\n            stdout, stderr = sub.communicate(input=input)\n            returncode = sub.returncode\n            if not silent:\n                sys.stdout.write(stdout)\n                sys.stderr.write(stderr)\n        except OSError, e:\n            if e.errno == errno.ENOENT:\n                raise RuntimeError('\"%s\" is not present on this system' % cmdline[0])\n            else:\n                raise\n        if returncode != 0:\n            raise RuntimeError('Got return value %d while executing \"%s\", stderr output was:\\n%s' % (returncode, \" \".join(cmdline), stderr.rstrip(\"\\n\")))\n        return stdout\n\n    @staticmethod\n    def get_make_cmd():\n        if sys_platform == \"freebsd\":\n            return \"gmake\"\n        else:\n            return \"make\"\n\n    @staticmethod\n    def get_opts_from_string(line, prefix):\n        \"\"\"Returns all options that have a particular prefix on a commandline\"\"\"\n        chunks = [chunk.strip() for chunk in line.split()]\n        return [chunk[len(prefix):] for chunk in chunks if chunk.startswith(prefix)]\n\n    @classmethod\n    def get_makefile_variables(cls, makefile):\n        \"\"\"Returns all variables in a makefile as a dict\"\"\"\n        stdout = cls.distutils_exec_process([cls.get_make_cmd(), \"-f\", makefile, \"-pR\", makefile], silent=True)\n        return dict(tup for tup in re.findall(\"(^[a-zA-Z]\\w+)\\s*:?=\\s*(.*)$\", stdout, re.MULTILINE))\n\n    @classmethod\n    def makedirs(cls, path):\n        try:\n            os.makedirs(path)\n        except OSError, e:\n            if e.errno==errno.EEXIST and os.path.isdir(path) and os.access(path, os.R_OK | os.W_OK | os.X_OK):\n                return\n            raise\n\n    def initialize_options(self):\n        build_ext.initialize_options(self)\n        self.pjsip_clean_compile = 0\n        self.pjsip_verbose_build = 0\n        self.pjsip_dir = os.path.join(os.path.dirname(__file__), \"deps\", \"pjsip\")\n\n    def configure_pjsip(self):\n        log.info(\"Configuring PJSIP\")\n        with open(os.path.join(self.build_dir, \"pjlib\", \"include\", \"pj\", \"config_site.h\"), \"wb\") as f:\n            f.write(\"\\n\".join(self.config_site+[\"\"]))\n        cflags = \"-DNDEBUG -g -fPIC -fno-omit-frame-pointer -fno-strict-aliasing -Wno-unused-label\"\n        if self.debug or hasattr(sys, 'gettotalrefcount'):\n            log.info(\"PJSIP will be built without optimizations\")\n            cflags += \" -O0\"\n        else:\n            cflags += \" -O2\"\n        env = os.environ.copy()\n        env['CFLAGS'] = ' '.join(x for x in (cflags, env.get('CFLAGS', None)) if x)\n        if sys_platform == \"win32\":\n            cmd = [\"bash\", \"configure\"]\n        else:\n            cmd = [\"./configure\"]\n        cmd.extend([\"--disable-g7221-codec\"])\n        ffmpeg_path = env.get(\"SIPSIMPLE_FFMPEG_PATH\", None)\n        if ffmpeg_path is not None:\n            cmd.append(\"--with-ffmpeg=%s\" % os.path.abspath(os.path.expanduser(ffmpeg_path)))\n        libvpx_path = env.get(\"SIPSIMPLE_LIBVPX_PATH\", None)\n        if libvpx_path is not None:\n            cmd.append(\"--with-vpx=%s\" % os.path.abspath(os.path.expanduser(libvpx_path)))\n        self.distutils_exec_process(cmd, silent=not self.pjsip_verbose_build, cwd=self.build_dir, env=env)\n        if \"#define PJ_HAS_SSL_SOCK 1\\n\" not in open(os.path.join(self.build_dir, \"pjlib\", \"include\", \"pj\", \"compat\", \"os_auto.h\")).readlines():\n            os.remove(os.path.join(self.build_dir, \"build.mak\"))\n            raise DistutilsError(\"PJSIP TLS support was disabled, OpenSSL development files probably not present on this system\")\n\n    def compile_pjsip(self):\n        log.info(\"Compiling PJSIP\")\n        self.distutils_exec_process([self.get_make_cmd()], silent=not self.pjsip_verbose_build, cwd=self.build_dir)\n\n    def clean_pjsip(self):\n        log.info(\"Cleaning PJSIP\")\n        try:\n            shutil.rmtree(self.build_dir)\n        except OSError, e:\n            if e.errno == errno.ENOENT:\n                return\n            raise\n\n    def update_extension(self, extension):\n        build_mak_vars = self.get_makefile_variables(os.path.join(self.build_dir, \"build.mak\"))\n        extension.include_dirs = self.get_opts_from_string(build_mak_vars[\"PJ_CFLAGS\"], \"-I\")\n        extension.library_dirs = self.get_opts_from_string(build_mak_vars[\"PJ_LDFLAGS\"], \"-L\")\n        extension.libraries = self.get_opts_from_string(build_mak_vars[\"PJ_LDLIBS\"], \"-l\")\n        extension.define_macros = [tuple(define.split(\"=\", 1)) for define in self.get_opts_from_string(build_mak_vars[\"PJ_CFLAGS\"], \"-D\")]\n        extension.define_macros.append((\"PJ_SVN_REVISION\", open(os.path.join(self.build_dir, \"base_rev\"), \"r\").read().strip()))\n        extension.define_macros.append((\"__PYX_FORCE_INIT_THREADS\", 1))\n        extension.extra_compile_args.append(\"-Wno-unused-function\")    # silence warning\n\n        if sys_platform == \"darwin\":\n            extension.define_macros.append((\"MACOSX_DEPLOYMENT_TARGET\", min_osx_version))\n            frameworks = re.findall(\"-framework (\\S+)(?:\\s|$)\", build_mak_vars[\"PJ_LDLIBS\"])\n            extension.extra_link_args = list(itertools.chain(*((\"-framework\", val) for val in frameworks)))\n            extension.extra_link_args.append(\"-mmacosx-version-min=%s\" % min_osx_version)\n            extension.extra_compile_args.append(\"-mmacosx-version-min=%s\" % min_osx_version)\n            extension.library_dirs.append(\"%s/usr/lib\" % osx_sdk_path)\n            extension.include_dirs.append(\"%s/usr/include\" % osx_sdk_path)\n\n        extension.depends = build_mak_vars[\"PJ_LIB_FILES\"].split()\n        self.libraries = extension.depends[:]\n\n    def cython_sources(self, sources, extension):\n        log.info(\"Compiling Cython extension %s\" % extension.name)\n        if extension.name == \"sipsimple.core._core\":\n            self.build_dir = os.path.join(self.build_temp, \"pjsip\")\n            if self.pjsip_clean_compile:\n                self.clean_pjsip()\n            copy_tree(self.pjsip_dir, self.build_dir, verbose=0)\n            if not os.path.exists(os.path.join(self.build_dir, \"build.mak\")):\n                self.configure_pjsip()\n            self.update_extension(extension)\n            self.compile_pjsip()\n        return build_ext.cython_sources(self, sources, extension)\n\n"
  },
  {
    "path": "sipsimple/__info__.py",
    "content": "\n\"\"\"Package information\"\"\"\n\n__project__ = \"python-sipsimple\"\n__summary__ = \"SIP SIMPLE implementation for Python\"\n__webpage__ = \"https://sipsimpleclient.org\"\n\n__version__ = \"3.6.0\"\n\n__author__ = \"AG Projects\"\n__email__ = \"support@ag-projects.com\"\n\n__license__ = \"GPL\"\n__copyright__ = \"Copyright 2008-2021 {}\".format(__author__)\n"
  },
  {
    "path": "sipsimple/__init__.py",
    "content": "\nfrom sipsimple.__info__ import __project__, __summary__, __webpage__, __version__, __author__, __email__, __license__, __copyright__\nfrom sipsimple.logging import log  # This will initialize and make our logger available early, before anything else is loaded\n"
  },
  {
    "path": "sipsimple/account/__init__.py",
    "content": "\n\"\"\"\nImplements a SIP Account management system that allows the definition of\nmultiple SIP accounts and their properties.\n\"\"\"\n\n__all__ = ['Account', 'BonjourAccount', 'AccountManager']\n\nfrom itertools import chain\nfrom threading import Lock\n\nfrom application.notification import IObserver, NotificationCenter, NotificationData\nfrom application.python import Null\nfrom application.python.decorator import execute_once\nfrom application.python.descriptor import classproperty\nfrom application.python.types import Singleton\nfrom application.system import host as Host\nfrom eventlib import coros, proc\nfrom gnutls.crypto import X509Certificate, X509PrivateKey\nfrom gnutls.interfaces.twisted import X509Credentials\nfrom zope.interface import implements\n\nfrom sipsimple.account.bonjour import BonjourServices, _bonjour\nfrom sipsimple.account.publication import PresencePublisher, DialogPublisher\nfrom sipsimple.account.registration import Registrar\nfrom sipsimple.account.subscription import MWISubscriber, PresenceWinfoSubscriber, DialogWinfoSubscriber, PresenceSubscriber, SelfPresenceSubscriber, DialogSubscriber\nfrom sipsimple.account.xcap import XCAPManager\nfrom sipsimple.core import Credentials, SIPURI, ContactURIFactory\nfrom sipsimple.configuration import ConfigurationManager, Setting, SettingsGroup, SettingsObject, SettingsObjectID\nfrom sipsimple.configuration.datatypes import AudioCodecList, MSRPConnectionModel, MSRPRelayAddress, MSRPTransport, NonNegativeInteger, Path, SIPAddress, SIPProxyAddress, SRTPKeyNegotiation, STUNServerAddressList, VideoCodecList, XCAPRoot\nfrom sipsimple.configuration.settings import SIPSimpleSettings\nfrom sipsimple.payloads import ParserError\nfrom sipsimple.payloads.messagesummary import MessageSummary\nfrom sipsimple.payloads.pidf import PIDFDocument\nfrom sipsimple.payloads.rlsnotify import RLSNotify\nfrom sipsimple.payloads.watcherinfo import WatcherInfoDocument\nfrom sipsimple.threading import call_in_thread\nfrom sipsimple.threading.green import call_in_green_thread, run_in_green_thread\nfrom sipsimple.util import user_info\n\n\n\nclass AuthSettings(SettingsGroup):\n    username = Setting(type=str, default=None, nillable=True)\n    password = Setting(type=str, default='')\n\n\nclass SIPSettings(SettingsGroup):\n    always_use_my_proxy = Setting(type=bool, default=False)\n    outbound_proxy = Setting(type=SIPProxyAddress, default=None, nillable=True)\n    register = Setting(type=bool, default=True)\n    register_interval = Setting(type=NonNegativeInteger, default=3600)\n    subscribe_interval = Setting(type=NonNegativeInteger, default=3600)\n    publish_interval = Setting(type=NonNegativeInteger, default=3600)\n\n\nclass SRTPEncryptionSettings(SettingsGroup):\n    enabled = Setting(type=bool, default=True)\n    key_negotiation = Setting(type=SRTPKeyNegotiation, default='opportunistic')\n\n\nclass RTPSettings(SettingsGroup):\n    audio_codec_list = Setting(type=AudioCodecList, default=None, nillable=True)\n    video_codec_list = Setting(type=VideoCodecList, default=None, nillable=True)\n    encryption = SRTPEncryptionSettings\n\n\nclass NATTraversalSettings(SettingsGroup):\n    use_ice = Setting(type=bool, default=False)\n    stun_server_list = Setting(type=STUNServerAddressList, default=None, nillable=True)\n    msrp_relay = Setting(type=MSRPRelayAddress, default=None, nillable=True)\n    use_msrp_relay_for_outbound = Setting(type=bool, default=False)\n\n\nclass MessageSummarySettings(SettingsGroup):\n    enabled = Setting(type=bool, default=False)\n    voicemail_uri = Setting(type=SIPAddress, default=None, nillable=True)\n\n\nclass XCAPSettings(SettingsGroup):\n    enabled = Setting(type=bool, default=False)\n    discovered = Setting(type=bool, default=False)\n    xcap_root = Setting(type=XCAPRoot, default=None, nillable=True)\n\n\nclass PresenceSettings(SettingsGroup):\n    enabled = Setting(type=bool, default=False)\n\n\nclass TLSSettings(SettingsGroup):\n    certificate = Setting(type=Path, default=None, nillable=True)\n    verify_server = Setting(type=bool, default=False)\n\n\nclass MSRPSettings(SettingsGroup):\n    transport = Setting(type=MSRPTransport, default='tls')\n    connection_model = Setting(type=MSRPConnectionModel, default='relay')\n\n\nclass Account(SettingsObject):\n    \"\"\"\n    Object representing a SIP account. Contains configuration settings and\n    attributes for accessing SIP related objects.\n\n    When the account is active, it will register, publish its presence and\n    subscribe to watcher-info events depending on its settings.\n\n    If the object is un-pickled and its enabled flag was set, it will\n    automatically activate.\n\n    When the save method is called, depending on the value of the enabled flag,\n    the account will activate/deactivate.\n\n    Notifications sent by instances of Account:\n     * CFGSettingsObjectWasCreated\n     * CFGSettingsObjectWasActivated\n     * CFGSettingsObjectWasDeleted\n     * CFGSettingsObjectDidChange\n     * SIPAccountWillActivate\n     * SIPAccountDidActivate\n     * SIPAccountWillDeactivate\n     * SIPAccountDidDeactivate\n    \"\"\"\n\n    implements(IObserver)\n\n    __group__ = 'Accounts'\n    __id__ = SettingsObjectID(type=SIPAddress)\n\n    id = __id__\n    enabled = Setting(type=bool, default=False)\n    display_name = Setting(type=unicode, default=None, nillable=True)\n\n    auth = AuthSettings\n    sip = SIPSettings\n    rtp = RTPSettings\n    nat_traversal = NATTraversalSettings\n    message_summary = MessageSummarySettings\n    msrp = MSRPSettings\n    presence = PresenceSettings\n    xcap = XCAPSettings\n    tls = TLSSettings\n\n    def __new__(cls, id):\n        with AccountManager.load.lock:\n            if not AccountManager.load.called:\n                raise RuntimeError(\"cannot instantiate %s before calling AccountManager.load\" % cls.__name__)\n        return SettingsObject.__new__(cls, id)\n\n    def __init__(self, id):\n        self.contact = ContactURIFactory()\n        self.xcap_manager = XCAPManager(self)\n        self._started = False\n        self._deleted = False\n        self._active = False\n        self._activation_lock = coros.Semaphore(1)\n        self._registrar = Registrar(self)\n        self._mwi_subscriber = MWISubscriber(self)\n        self._pwi_subscriber = PresenceWinfoSubscriber(self)\n        self._dwi_subscriber = DialogWinfoSubscriber(self)\n        self._presence_subscriber = PresenceSubscriber(self)\n        self._self_presence_subscriber = SelfPresenceSubscriber(self)\n        self._dialog_subscriber = DialogSubscriber(self)\n        self._presence_publisher = PresencePublisher(self)\n        self._dialog_publisher = DialogPublisher(self)\n        self._mwi_voicemail_uri = None\n        self._pwi_version = None\n        self._dwi_version = None\n        self._presence_version = None\n        self._dialog_version = None\n\n    def start(self):\n        if self._started or self._deleted:\n            return\n        self._started = True\n\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, name='CFGSettingsObjectDidChange', sender=self)\n        notification_center.add_observer(self, name='CFGSettingsObjectDidChange', sender=SIPSimpleSettings())\n        notification_center.add_observer(self, name='XCAPManagerDidDiscoverServerCapabilities', sender=self.xcap_manager)\n        notification_center.add_observer(self, sender=self._mwi_subscriber)\n        notification_center.add_observer(self, sender=self._pwi_subscriber)\n        notification_center.add_observer(self, sender=self._dwi_subscriber)\n        notification_center.add_observer(self, sender=self._presence_subscriber)\n        notification_center.add_observer(self, sender=self._self_presence_subscriber)\n        notification_center.add_observer(self, sender=self._dialog_subscriber)\n\n        self.xcap_manager.init()\n        if self.enabled:\n            self._activate()\n\n    def stop(self):\n        if not self._started:\n            return\n        self._started = False\n\n        self._deactivate()\n\n        notification_center = NotificationCenter()\n        notification_center.remove_observer(self, name='CFGSettingsObjectDidChange', sender=self)\n        notification_center.remove_observer(self, name='CFGSettingsObjectDidChange', sender=SIPSimpleSettings())\n        notification_center.remove_observer(self, name='XCAPManagerDidDiscoverServerCapabilities', sender=self.xcap_manager)\n        notification_center.remove_observer(self, sender=self._mwi_subscriber)\n        notification_center.remove_observer(self, sender=self._pwi_subscriber)\n        notification_center.remove_observer(self, sender=self._dwi_subscriber)\n        notification_center.remove_observer(self, sender=self._presence_subscriber)\n        notification_center.remove_observer(self, sender=self._self_presence_subscriber)\n        notification_center.remove_observer(self, sender=self._dialog_subscriber)\n\n    def delete(self):\n        if self._deleted:\n            return\n        self._deleted = True\n        self.stop()\n        self._registrar = None\n        self._mwi_subscriber = None\n        self._pwi_subscriber = None\n        self._dwi_subscriber = None\n        self._presence_subscriber = None\n        self._self_presence_subscriber = None\n        self._dialog_subscriber = None\n        self._presence_publisher = None\n        self._dialog_publisher = None\n        self.xcap_manager = None\n        SettingsObject.delete(self)\n\n    @run_in_green_thread\n    def reregister(self):\n        if self._started:\n            self._registrar.reregister()\n\n    @run_in_green_thread\n    def resubscribe(self):\n        if self._started:\n            self._mwi_subscriber.resubscribe()\n            self._pwi_subscriber.resubscribe()\n            self._dwi_subscriber.resubscribe()\n            self._presence_subscriber.resubscribe()\n            self._self_presence_subscriber.resubscribe()\n            self._dialog_subscriber.resubscribe()\n\n    @property\n    def credentials(self):\n        return Credentials(self.auth.username or self.id.username, self.auth.password)\n\n    @property\n    def registered(self):\n        try:\n            return self._registrar.registered\n        except AttributeError:\n            return False\n\n    @property\n    def mwi_active(self):\n        try:\n            return self._mwi_subscriber.subscribed\n        except AttributeError:\n            return False\n\n    @property\n    def tls_credentials(self):\n        # This property can be optimized to cache the credentials it loads from disk,\n        # however this is not a time consuming operation (~ 3000 req/sec). -Luci\n        settings = SIPSimpleSettings()\n        if self.tls.certificate is not None:\n            certificate_data = open(self.tls.certificate.normalized).read()\n            certificate = X509Certificate(certificate_data)\n            private_key = X509PrivateKey(certificate_data)\n        else:\n            certificate = None\n            private_key = None\n        if settings.tls.ca_list is not None:\n            # we should read all certificates in the file, rather than just the first -Luci\n            trusted = [X509Certificate(open(settings.tls.ca_list.normalized).read())]\n        else:\n            trusted = []\n        credentials = X509Credentials(certificate, private_key, trusted)\n        credentials.verify_peer = self.tls.verify_server\n        return credentials\n\n    @property\n    def uri(self):\n        return SIPURI(user=self.id.username, host=self.id.domain)\n\n    @property\n    def voicemail_uri(self):\n        return self._mwi_voicemail_uri or self.message_summary.voicemail_uri\n\n    @property\n    def presence_state(self):\n        try:\n            return self._presence_publisher.state\n        except AttributeError:\n            return None\n\n    @presence_state.setter\n    def presence_state(self, state):\n        try:\n            self._presence_publisher.state = state\n        except AttributeError:\n            pass\n\n    @property\n    def dialog_state(self):\n        try:\n            return self._dialog_publisher.state\n        except AttributeError:\n            return None\n\n    @dialog_state.setter\n    def dialog_state(self, state):\n        try:\n            self._dialog_publisher.state = state\n        except AttributeError:\n            pass\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    @run_in_green_thread\n    def _NH_CFGSettingsObjectDidChange(self, notification):\n        if self._started and 'enabled' in notification.data.modified:\n            if self.enabled:\n                self._activate()\n            else:\n                self._deactivate()\n\n    def _NH_XCAPManagerDidDiscoverServerCapabilities(self, notification):\n        if self._started and self.xcap.discovered is False:\n            self.xcap.discovered = True\n            self.save()\n            notification.center.post_notification('SIPAccountDidDiscoverXCAPSupport', sender=self)\n\n    def _NH_MWISubscriberDidDeactivate(self, notification):\n        self._mwi_voicemail_uri = None\n\n    def _NH_MWISubscriptionGotNotify(self, notification):\n        if notification.data.body and notification.data.content_type == MessageSummary.content_type:\n            try:\n                message_summary = MessageSummary.parse(notification.data.body)\n            except ParserError:\n                pass\n            else:\n                self._mwi_voicemail_uri = message_summary.message_account and SIPAddress(message_summary.message_account.replace('sip:', '', 1)) or None\n                notification.center.post_notification('SIPAccountGotMessageSummary', sender=self, data=NotificationData(message_summary=message_summary))\n\n    def _NH_PresenceWinfoSubscriptionGotNotify(self, notification):\n        if notification.data.body and notification.data.content_type == WatcherInfoDocument.content_type:\n            try:\n                watcher_info = WatcherInfoDocument.parse(notification.data.body)\n                watcher_list = watcher_info['sip:' + self.id]\n            except (ParserError, KeyError):\n                pass\n            else:\n                if watcher_list.package != 'presence':\n                    return\n                if self._pwi_version is None:\n                    if watcher_info.state == 'partial':\n                        self._pwi_subscriber.resubscribe()\n                elif watcher_info.version <= self._pwi_version:\n                    return\n                elif watcher_info.state == 'partial' and watcher_info.version > self._pwi_version + 1:\n                    self._pwi_subscriber.resubscribe()\n                self._pwi_version = watcher_info.version\n                data = NotificationData(version=watcher_info.version, state=watcher_info.state, watcher_list=watcher_list)\n                notification.center.post_notification('SIPAccountGotPresenceWinfo', sender=self, data=data)\n\n    def _NH_PresenceWinfoSubscriptionDidEnd(self, notification):\n        self._pwi_version = None\n\n    def _NH_PresenceWinfoSubscriptionDidFail(self, notification):\n        self._pwi_version = None\n\n    def _NH_DialogWinfoSubscriptionGotNotify(self, notification):\n        if notification.data.body and notification.data.content_type == WatcherInfoDocument.content_type:\n            try:\n                watcher_info = WatcherInfoDocument.parse(notification.data.body)\n                watcher_list = watcher_info['sip:' + self.id]\n            except (ParserError, KeyError):\n                pass\n            else:\n                if watcher_list.package != 'dialog':\n                    return\n                if self._dwi_version is None:\n                    if watcher_info.state == 'partial':\n                        self._dwi_subscriber.resubscribe()\n                elif watcher_info.version <= self._dwi_version:\n                    return\n                elif watcher_info.state == 'partial' and watcher_info.version > self._dwi_version + 1:\n                    self._dwi_subscriber.resubscribe()\n                self._dwi_version = watcher_info.version\n                data = NotificationData(version=watcher_info.version, state=watcher_info.state, watcher_list=watcher_list)\n                notification.center.post_notification('SIPAccountGotDialogWinfo', sender=self, data=data)\n\n    def _NH_DialogWinfoSubscriptionDidEnd(self, notification):\n        self._dwi_version = None\n\n    def _NH_DialogWinfoSubscriptionDidFail(self, notification):\n        self._dwi_version = None\n\n    def _NH_PresenceSubscriptionGotNotify(self, notification):\n        if notification.data.body and notification.data.content_type == RLSNotify.content_type:\n            try:\n                rls_notify = RLSNotify.parse('{content_type}\\r\\n\\r\\n{body}'.format(content_type=notification.data.headers['Content-Type'], body=notification.data.body))\n            except ParserError:\n                pass\n            else:\n                if rls_notify.uri != self.xcap_manager.rls_presence_uri:\n                    return\n                if self._presence_version is None:\n                    if not rls_notify.full_state:\n                        self._presence_subscriber.resubscribe()\n                elif rls_notify.version <= self._presence_version:\n                    return\n                elif not rls_notify.full_state and rls_notify.version > self._presence_version + 1:\n                    self._presence_subscriber.resubscribe()\n                self._presence_version = rls_notify.version\n                data = NotificationData(version=rls_notify.version, full_state=rls_notify.full_state, resource_map=dict((resource.uri, resource) for resource in rls_notify))\n                notification.center.post_notification('SIPAccountGotPresenceState', sender=self, data=data)\n\n    def _NH_PresenceSubscriptionDidEnd(self, notification):\n        self._presence_version = None\n\n    def _NH_PresenceSubscriptionDidFail(self, notification):\n        self._presence_version = None\n\n    def _NH_SelfPresenceSubscriptionGotNotify(self, notification):\n        if notification.data.body and notification.data.content_type == PIDFDocument.content_type:\n            try:\n                pidf_doc = PIDFDocument.parse(notification.data.body)\n            except ParserError:\n                pass\n            else:\n                if pidf_doc.entity.partition('sip:')[2] != self.id:\n                    return\n                notification.center.post_notification('SIPAccountGotSelfPresenceState', sender=self, data=NotificationData(pidf=pidf_doc))\n\n    def _NH_DialogSubscriptionGotNotify(self, notification):\n        if notification.data.body and notification.data.content_type == RLSNotify.content_type:\n            try:\n                rls_notify = RLSNotify.parse('{content_type}\\r\\n\\r\\n{body}'.format(content_type=notification.data.headers['Content-Type'], body=notification.data.body))\n            except ParserError:\n                pass\n            else:\n                if rls_notify.uri != self.xcap_manager.rls_dialog_uri:\n                    return\n                if self._dialog_version is None:\n                    if not rls_notify.full_state:\n                        self._dialog_subscriber.resubscribe()\n                elif rls_notify.version <= self._dialog_version:\n                    return\n                elif not rls_notify.full_state and rls_notify.version > self._dialog_version + 1:\n                    self._dialog_subscriber.resubscribe()\n                self._dialog_version = rls_notify.version\n                data = NotificationData(version=rls_notify.version, full_state=rls_notify.full_state, resource_map=dict((resource.uri, resource) for resource in rls_notify))\n                notification.center.post_notification('SIPAccountGotDialogState', sender=self, data=data)\n\n    def _NH_DialogSubscriptionDidEnd(self, notification):\n        self._dialog_version = None\n\n    def _NH_DialogSubscriptionDidFail(self, notification):\n        self._dialog_version = None\n\n    def _activate(self):\n        with self._activation_lock:\n            if self._active:\n                return\n            notification_center = NotificationCenter()\n            notification_center.post_notification('SIPAccountWillActivate', sender=self)\n            self._active = True\n            self._registrar.start()\n            self._mwi_subscriber.start()\n            self._pwi_subscriber.start()\n            self._dwi_subscriber.start()\n            self._presence_subscriber.start()\n            self._self_presence_subscriber.start()\n            self._dialog_subscriber.start()\n            self._presence_publisher.start()\n            self._dialog_publisher.start()\n            if self.xcap.enabled:\n                self.xcap_manager.start()\n            notification_center.post_notification('SIPAccountDidActivate', sender=self)\n\n    def _deactivate(self):\n        with self._activation_lock:\n            if not self._active:\n                return\n            notification_center = NotificationCenter()\n            notification_center.post_notification('SIPAccountWillDeactivate', sender=self)\n            self._active = False\n            handlers = [self._registrar, self._mwi_subscriber, self._pwi_subscriber, self._dwi_subscriber,\n                        self._presence_subscriber, self._self_presence_subscriber, self._dialog_subscriber,\n                        self._presence_publisher, self._dialog_publisher, self.xcap_manager]\n            proc.waitall([proc.spawn(handler.stop) for handler in handlers])\n            notification_center.post_notification('SIPAccountDidDeactivate', sender=self)\n\n    def __repr__(self):\n        return '%s(%r)' % (self.__class__.__name__, self.id)\n\n    def __setstate__(self, data):\n        # This restores the password from its previous location as a top level setting\n        # after it was moved under the auth group.\n        SettingsObject.__setstate__(self, data)\n        if not data.get('auth', {}).get('password') and data.get('password'):\n            self.auth.password = data.pop('password')\n            self.save()\n\n\nclass BonjourMSRPSettings(SettingsGroup):\n    transport = Setting(type=MSRPTransport, default='tcp')\n\n\nclass BonjourAccountEnabledSetting(Setting):\n    def __get__(self, obj, objtype):\n        if obj is None:\n            return self\n        return _bonjour.available and self.values.get(obj, self.default)\n\n    def __set__(self, obj, value):\n        if not _bonjour.available:\n            raise RuntimeError('mdns support is not available')\n        Setting.__set__(self, obj, value)\n\n\nclass BonjourAccount(SettingsObject):\n    \"\"\"\n    Object representing a bonjour account. Contains configuration settings and\n    attributes for accessing bonjour related options.\n\n    When the account is active, it will send broadcast its contact address on\n    the LAN.\n\n    If the object is un-pickled and its enabled flag was set, it will\n    automatically activate.\n\n    When the save method is called, depending on the value of the enabled flag,\n    the account will activate/deactivate.\n\n    Notifications sent by instances of Account:\n     * CFGSettingsObjectWasCreated\n     * CFGSettingsObjectWasActivated\n     * CFGSettingsObjectWasDeleted\n     * CFGSettingsObjectDidChange\n     * SIPAccountWillActivate\n     * SIPAccountDidActivate\n     * SIPAccountWillDeactivate\n     * SIPAccountDidDeactivate\n    \"\"\"\n\n    implements(IObserver)\n\n    __group__ = 'Accounts'\n    __id__ = SIPAddress('bonjour@local')\n\n    id = property(lambda self: self.__id__)\n    enabled = BonjourAccountEnabledSetting(type=bool, default=True)\n    display_name = Setting(type=unicode, default=user_info.fullname, nillable=False)\n\n    msrp = BonjourMSRPSettings\n    presence = PresenceSettings\n    rtp = RTPSettings\n    tls = TLSSettings\n\n    def __new__(cls):\n        with AccountManager.load.lock:\n            if not AccountManager.load.called:\n                raise RuntimeError(\"cannot instantiate %s before calling AccountManager.load\" % cls.__name__)\n        return SettingsObject.__new__(cls)\n\n    def __init__(self):\n        self.contact = ContactURIFactory()\n        self.credentials = None\n        self._started = False\n        self._active = False\n        self._activation_lock = coros.Semaphore(1)\n        self._bonjour_services = BonjourServices(self)\n\n        # initialize fake settings (these are here to make the bonjour account quack like a duck)\n\n        self.nat_traversal = NATTraversalSettings()\n        self.nat_traversal.use_ice = False\n        self.nat_traversal.msrp_relay = None\n        self.nat_traversal.use_msrp_relay_for_outbound = False\n\n        self.xcap = XCAPSettings()\n        self.xcap.enabled = False\n        self.xcap.discovered = False\n        self.xcap.xcap_root = None\n\n    def __repr__(self):\n        return '%s()' % self.__class__.__name__\n\n    def start(self):\n        if self._started:\n            return\n        self._started = True\n\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, name='CFGSettingsObjectDidChange', sender=self)\n        notification_center.add_observer(self, name='CFGSettingsObjectDidChange', sender=SIPSimpleSettings())\n\n        self._bonjour_services.start()\n        if self.enabled:\n            self._activate()\n\n    def stop(self):\n        if not self._started:\n            return\n        self._started = False\n\n        self._deactivate()\n        self._bonjour_services.stop()\n\n        notification_center = NotificationCenter()\n        notification_center.remove_observer(self, name='CFGSettingsObjectDidChange', sender=self)\n        notification_center.remove_observer(self, name='CFGSettingsObjectDidChange', sender=SIPSimpleSettings())\n\n    @classproperty\n    def mdns_available(cls):\n        return _bonjour.available\n\n    @property\n    def registered(self):\n        return False\n\n    @property\n    def tls_credentials(self):\n        # This property can be optimized to cache the credentials it loads from disk,\n        # however this is not a time consuming operation (~ 3000 req/sec). -Luci\n        settings = SIPSimpleSettings()\n        if self.tls.certificate is not None:\n            certificate_data = open(self.tls.certificate.normalized).read()\n            certificate = X509Certificate(certificate_data)\n            private_key = X509PrivateKey(certificate_data)\n        else:\n            certificate = None\n            private_key = None\n        if settings.tls.ca_list is not None:\n            # we should read all certificates in the file, rather than just the first -Luci\n            trusted = [X509Certificate(open(settings.tls.ca_list.normalized).read())]\n        else:\n            trusted = []\n        credentials = X509Credentials(certificate, private_key, trusted)\n        credentials.verify_peer = self.tls.verify_server\n        return credentials\n\n    @property\n    def uri(self):\n        return SIPURI(user=self.contact.username, host=Host.default_ip or '127.0.0.1')\n\n    @property\n    def presence_state(self):\n        return self._bonjour_services.presence_state\n\n    @presence_state.setter\n    def presence_state(self, state):\n        self._bonjour_services.presence_state = state\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    @run_in_green_thread\n    def _NH_CFGSettingsObjectDidChange(self, notification):\n        if self._started:\n            if 'enabled' in notification.data.modified:\n                if self.enabled:\n                    self._activate()\n                else:\n                    self._deactivate()\n            elif self.enabled:\n                if 'display_name' in notification.data.modified:\n                    self._bonjour_services.update_registrations()\n                if {'sip.transport_list', 'tls.certificate'}.intersection(notification.data.modified):\n                    self._bonjour_services.update_registrations()\n                    self._bonjour_services.restart_discovery()\n\n    def _activate(self):\n        with self._activation_lock:\n            if self._active:\n                return\n            notification_center = NotificationCenter()\n            notification_center.post_notification('SIPAccountWillActivate', sender=self)\n            self._active = True\n            self._bonjour_services.activate()\n            notification_center.post_notification('SIPAccountDidActivate', sender=self)\n\n    def _deactivate(self):\n        with self._activation_lock:\n            if not self._active:\n                return\n            notification_center = NotificationCenter()\n            notification_center.post_notification('SIPAccountWillDeactivate', sender=self)\n            self._active = False\n            self._bonjour_services.deactivate()\n            notification_center.post_notification('SIPAccountDidDeactivate', sender=self)\n\n\nclass AccountManager(object):\n    \"\"\"\n    This is a singleton object which manages all the SIP accounts. It is\n    also used to manage the default account (the one used for outbound\n    sessions) using the default_account attribute:\n\n    manager = AccountManager()\n    manager.default_account = manager.get_account('alice@example.net')\n\n    The following notifications are sent:\n     * SIPAccountManagerDidRemoveAccount\n     * SIPAccountManagerDidAddAccount\n     * SIPAccountManagerDidChangeDefaultAccount\n    \"\"\"\n\n    __metaclass__ = Singleton\n\n    implements(IObserver)\n\n    def __init__(self):\n        self._lock = Lock()\n        self.accounts = {}\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, name='CFGSettingsObjectWasActivated')\n        notification_center.add_observer(self, name='CFGSettingsObjectWasCreated')\n\n    @execute_once\n    def load(self):\n        \"\"\"\n        Load all accounts from the configuration. The accounts will not be\n        started until the start method is called.\n        \"\"\"\n        configuration = ConfigurationManager()\n        bonjour_account = BonjourAccount()\n        names = configuration.get_names([Account.__group__])\n        [Account(id) for id in names if id != bonjour_account.id]\n        default_account = self.default_account\n        if default_account is None or not default_account.enabled:\n            try:\n                self.default_account = (account for account in self.accounts.itervalues() if account.enabled).next()\n            except StopIteration:\n                self.default_account = None\n\n    def start(self):\n        \"\"\"\n        Start the accounts, which will determine the ones with the enabled flag\n        set to activate.\n        \"\"\"\n        notification_center = NotificationCenter()\n        notification_center.post_notification('SIPAccountManagerWillStart', sender=self)\n        proc.waitall([proc.spawn(account.start) for account in self.accounts.itervalues()])\n        notification_center.post_notification('SIPAccountManagerDidStart', sender=self)\n\n    def stop(self):\n        \"\"\"\n        Stop the accounts, which will determine the ones that were enabled to\n        deactivate. This method returns only once the accounts were stopped\n        successfully or they timed out trying.\n        \"\"\"\n        notification_center = NotificationCenter()\n        notification_center.post_notification('SIPAccountManagerWillEnd', sender=self)\n        proc.waitall([proc.spawn(account.stop) for account in self.accounts.itervalues()])\n        notification_center.post_notification('SIPAccountManagerDidEnd', sender=self)\n\n    def has_account(self, id):\n        return id in self.accounts\n\n    def get_account(self, id):\n        return self.accounts[id]\n\n    def get_accounts(self):\n        return self.accounts.values()\n\n    def iter_accounts(self):\n        return self.accounts.itervalues()\n\n    def find_account(self, contact_uri):\n        # compare contact_address with account contact\n        exact_matches = (account for account in self.accounts.itervalues() if account.enabled and account.contact.username==contact_uri.user)\n        # compare username in contact URI with account username\n        loose_matches = (account for account in self.accounts.itervalues() if account.enabled and account.id.username==contact_uri.user)\n        return chain(exact_matches, loose_matches, [None]).next()\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_CFGSettingsObjectWasActivated(self, notification):\n        if isinstance(notification.sender, Account) or (isinstance(notification.sender, BonjourAccount) and _bonjour.available):\n            account = notification.sender\n            self.accounts[account.id] = account\n            notification.center.add_observer(self, sender=account, name='CFGSettingsObjectDidChange')\n            notification.center.add_observer(self, sender=account, name='CFGSettingsObjectWasDeleted')\n            notification.center.post_notification('SIPAccountManagerDidAddAccount', sender=self, data=NotificationData(account=account))\n            from sipsimple.application import SIPApplication\n            if SIPApplication.running:\n                call_in_green_thread(account.start)\n\n    def _NH_CFGSettingsObjectWasCreated(self, notification):\n        if isinstance(notification.sender, Account):\n            account = notification.sender\n            if account.enabled and self.default_account is None:\n                self.default_account = account\n\n    def _NH_CFGSettingsObjectWasDeleted(self, notification):\n        account = notification.sender\n        del self.accounts[account.id]\n        notification.center.remove_observer(self, sender=account, name='CFGSettingsObjectDidChange')\n        notification.center.remove_observer(self, sender=account, name='CFGSettingsObjectWasDeleted')\n        notification.center.post_notification('SIPAccountManagerDidRemoveAccount', sender=self, data=NotificationData(account=account))\n\n    def _NH_CFGSettingsObjectDidChange(self, notification):\n        account = notification.sender\n        if '__id__' in notification.data.modified:\n            modified_id = notification.data.modified['__id__']\n            self.accounts[modified_id.new] = self.accounts.pop(modified_id.old)\n        if 'enabled' in notification.data.modified:\n            if account.enabled and self.default_account is None:\n                self.default_account = account\n            elif not account.enabled and self.default_account is account:\n                try:\n                    self.default_account = (account for account in self.accounts.itervalues() if account.enabled).next()\n                except StopIteration:\n                    self.default_account = None\n\n    @property\n    def default_account(self):\n        settings = SIPSimpleSettings()\n        return self.accounts.get(settings.default_account, None)\n\n    @default_account.setter\n    def default_account(self, account):\n        if account is not None and not account.enabled:\n            raise ValueError(\"account %s is not enabled\" % account.id)\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n        with self._lock:\n            old_account = self.accounts.get(settings.default_account, None)\n            if account is old_account:\n                return\n            if account is None:\n                settings.default_account = None\n            else:\n                settings.default_account = account.id\n            settings.save()\n            # we need to post the notification in the file-io thread in order to have it serialized after the\n            # SIPAccountManagerDidAddAccount notification that is triggered when the account is saved the first\n            # time, because save is executed in the file-io thread while this runs in the current thread. -Dan\n            call_in_thread('file-io', notification_center.post_notification, 'SIPAccountManagerDidChangeDefaultAccount', sender=self, data=NotificationData(old_account=old_account, account=account))\n"
  },
  {
    "path": "sipsimple/account/bonjour/__init__.py",
    "content": "\n\"\"\"Implements Bonjour service handlers\"\"\"\n\n__all__ = ['BonjourServices']\n\nimport re\nimport uuid\n\nfrom threading import Lock\nfrom weakref import WeakKeyDictionary\n\nfrom application.notification import IObserver, NotificationCenter, NotificationData\nfrom application.python import Null\nfrom eventlib import api, coros, proc\nfrom eventlib.green import select\nfrom twisted.internet import reactor\nfrom zope.interface import implements\n\nfrom sipsimple import log\nfrom sipsimple.account.bonjour import _bonjour\nfrom sipsimple.core import FrozenSIPURI, SIPCoreError, NoGRUU\nfrom sipsimple.configuration.settings import SIPSimpleSettings\nfrom sipsimple.threading import call_in_twisted_thread, run_in_twisted_thread\nfrom sipsimple.threading.green import Command\n\n\nclass RestartSelect(Exception): pass\n\n\nclass BonjourFile(object):\n    __instances__ = WeakKeyDictionary()\n\n    def __new__(cls, file):\n        if cls is BonjourFile:\n            raise TypeError(\"BonjourFile cannot be instantiated directly\")\n        instance = cls.__instances__.get(file)\n        if instance is None:\n            instance = object.__new__(cls)\n            instance.file = file\n            instance.active = False\n            cls.__instances__[file] = instance\n        return instance\n\n    def fileno(self):\n        return self.file.fileno() if not self.closed else -1\n\n    def close(self):\n        self.file.close()\n        self.file = None\n\n    @property\n    def closed(self):\n        return self.file is None\n\n    @classmethod\n    def find_by_file(cls, file):\n        \"\"\"Return the instance matching the given DNSServiceRef file\"\"\"\n        try:\n            return cls.__instances__[file]\n        except KeyError:\n            raise KeyError(\"cannot find a %s matching the given DNSServiceRef file\" % cls.__name__)\n\n\nclass BonjourDiscoveryFile(BonjourFile):\n    def __new__(cls, file, transport):\n        instance = BonjourFile.__new__(cls, file)\n        instance.transport = transport\n        return instance\n\n\nclass BonjourRegistrationFile(BonjourFile):\n    def __new__(cls, file, transport):\n        instance = BonjourFile.__new__(cls, file)\n        instance.transport = transport\n        return instance\n\n\nclass BonjourResolutionFile(BonjourFile):\n    def __new__(cls, file, discovery_file, service_description):\n        instance = BonjourFile.__new__(cls, file)\n        instance.discovery_file = discovery_file\n        instance.service_description = service_description\n        return instance\n\n    @property\n    def transport(self):\n        return self.discovery_file.transport\n\n\nclass BonjourServiceDescription(object):\n    def __init__(self, name, type, domain):\n        self.name = name\n        self.type = type\n        self.domain = domain\n\n    def __repr__(self):\n        return \"%s(%r, %r, %r)\" % (self.__class__.__name__, self.name, self.type, self.domain)\n\n    def __hash__(self):\n        return hash(self.name)\n\n    def __eq__(self, other):\n        if isinstance(other, BonjourServiceDescription):\n            return self.name==other.name and self.type==other.type and self.domain==other.domain\n        return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n\nclass BonjourNeighbourPresence(object):\n    def __init__(self, state, note):\n        self.state = state\n        self.note = note\n\n\nclass BonjourNeighbourRecord(object):\n    def __init__(self, service_description, host, txtrecord):\n        self.id = txtrecord.get('instance_id', None)\n        self.name = txtrecord.get('name', '').decode('utf-8') or None\n        self.host = re.match(r'^(?P<host>.*?)(\\.local)?\\.?$', host).group('host')\n        self.uri = FrozenSIPURI.parse(txtrecord.get('contact', service_description.name))\n        self.presence = BonjourNeighbourPresence(txtrecord.get('state', txtrecord.get('status', None)), txtrecord.get('note', '').decode('utf-8') or None) # status is read for legacy (remove later) -Dan\n\n\nclass BonjourServices(object):\n    implements(IObserver)\n\n    def __init__(self, account):\n        self.account = account\n        self._started = False\n        self._files = []\n        self._neighbours = {}\n        self._command_channel = coros.queue()\n        self._select_proc = None\n        self._discover_timer = None\n        self._register_timer = None\n        self._update_timer = None\n        self._lock = Lock()\n        self.__dict__['presence_state'] = None\n\n    def start(self):\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, name='NetworkConditionsDidChange')\n        self._select_proc = proc.spawn(self._process_files)\n        proc.spawn(self._handle_commands)\n\n    def stop(self):\n        notification_center = NotificationCenter()\n        notification_center.remove_observer(self, name='NetworkConditionsDidChange')\n        self._select_proc.kill()\n        self._command_channel.send_exception(api.GreenletExit)\n\n    def activate(self):\n        self._started = True\n        self._command_channel.send(Command('register'))\n        self._command_channel.send(Command('discover'))\n\n    def deactivate(self):\n        command = Command('stop')\n        self._command_channel.send(command)\n        command.wait()\n        self._started = False\n\n    def restart_discovery(self):\n        self._command_channel.send(Command('discover'))\n\n    def restart_registration(self):\n        self._command_channel.send(Command('unregister'))\n        self._command_channel.send(Command('register'))\n\n    def update_registrations(self):\n        self._command_channel.send(Command('update_registrations'))\n\n    @property\n    def presence_state(self):\n        return self.__dict__['presence_state']\n\n    @presence_state.setter\n    def presence_state(self, state):\n        if state is not None and not isinstance(state, BonjourPresenceState):\n            raise ValueError(\"state must be a BonjourPresenceState instance or None\")\n        with self._lock:\n            old_state = self.__dict__['presence_state']\n            self.__dict__['presence_state'] = state\n            if state != old_state:\n                call_in_twisted_thread(self.update_registrations)\n\n    def _register_cb(self, file, flags, error_code, name, regtype, domain):\n        notification_center = NotificationCenter()\n        file = BonjourRegistrationFile.find_by_file(file)\n        if error_code == _bonjour.kDNSServiceErr_NoError:\n            notification_center.post_notification('BonjourAccountRegistrationDidSucceed', sender=self.account, data=NotificationData(name=name, transport=file.transport))\n        else:\n            error = _bonjour.BonjourError(error_code)\n            notification_center.post_notification('BonjourAccountRegistrationDidFail', sender=self.account, data=NotificationData(reason=str(error), transport=file.transport))\n            self._files.remove(file)\n            self._select_proc.kill(RestartSelect)\n            file.close()\n            if self._register_timer is None:\n                self._register_timer = reactor.callLater(1, self._command_channel.send, Command('register'))\n\n    def _browse_cb(self, file, flags, interface_index, error_code, service_name, regtype, reply_domain):\n        notification_center = NotificationCenter()\n        file = BonjourDiscoveryFile.find_by_file(file)\n        service_description = BonjourServiceDescription(service_name, regtype, reply_domain)\n        if error_code != _bonjour.kDNSServiceErr_NoError:\n            error = _bonjour.BonjourError(error_code)\n            notification_center.post_notification('BonjourAccountDiscoveryDidFail', sender=self.account, data=NotificationData(reason=str(error), transport=file.transport))\n            removed_files = [file] + [f for f in self._files if isinstance(f, BonjourResolutionFile) and f.discovery_file==file]\n            for f in removed_files:\n                self._files.remove(f)\n            self._select_proc.kill(RestartSelect)\n            for f in removed_files:\n                f.close()\n            if self._discover_timer is None:\n                self._discover_timer = reactor.callLater(1, self._command_channel.send, Command('discover'))\n            return\n        if reply_domain != 'local.':\n            return\n        if flags & _bonjour.kDNSServiceFlagsAdd:\n            try:\n                resolution_file = (f for f in self._files if isinstance(f, BonjourResolutionFile) and f.discovery_file==file and f.service_description==service_description).next()\n            except StopIteration:\n                try:\n                    resolution_file = _bonjour.DNSServiceResolve(0, interface_index, service_name, regtype, reply_domain, self._resolve_cb)\n                except _bonjour.BonjourError, e:\n                    notification_center.post_notification('BonjourAccountDiscoveryFailure', sender=self.account, data=NotificationData(error=str(e), transport=file.transport))\n                else:\n                    resolution_file = BonjourResolutionFile(resolution_file, discovery_file=file, service_description=service_description)\n                    self._files.append(resolution_file)\n                    self._select_proc.kill(RestartSelect)\n        else:\n            try:\n                resolution_file = (f for f in self._files if isinstance(f, BonjourResolutionFile) and f.discovery_file==file and f.service_description==service_description).next()\n            except StopIteration:\n                pass\n            else:\n                self._files.remove(resolution_file)\n                self._select_proc.kill(RestartSelect)\n                resolution_file.close()\n                service_description = resolution_file.service_description\n                if service_description in self._neighbours:\n                    record = self._neighbours.pop(service_description)\n                    notification_center.post_notification('BonjourAccountDidRemoveNeighbour', sender=self.account, data=NotificationData(neighbour=service_description, record=record))\n\n    def _resolve_cb(self, file, flags, interface_index, error_code, fullname, host_target, port, txtrecord):\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n        file = BonjourResolutionFile.find_by_file(file)\n        if error_code == _bonjour.kDNSServiceErr_NoError:\n            service_description = file.service_description\n            try:\n                record = BonjourNeighbourRecord(service_description, host_target, _bonjour.TXTRecord.parse(txtrecord))\n            except SIPCoreError:\n                pass\n            else:\n                transport = record.uri.transport\n                supported_transport = transport in settings.sip.transport_list and (transport!='tls' or self.account.tls.certificate is not None)\n                if not supported_transport and service_description in self._neighbours:\n                    record = self._neighbours.pop(service_description)\n                    notification_center.post_notification('BonjourAccountDidRemoveNeighbour', sender=self.account, data=NotificationData(neighbour=service_description, record=record))\n                elif supported_transport:\n                    try:\n                        our_contact_uri = self.account.contact[NoGRUU, transport]\n                    except KeyError:\n                        return\n                    if record.uri != our_contact_uri:\n                        had_neighbour = service_description in self._neighbours\n                        self._neighbours[service_description] = record\n                        notification_name = 'BonjourAccountDidUpdateNeighbour' if had_neighbour else 'BonjourAccountDidAddNeighbour'\n                        notification_data = NotificationData(neighbour=service_description, record=record)\n                        notification_center.post_notification(notification_name, sender=self.account, data=notification_data)\n        else:\n            self._files.remove(file)\n            self._select_proc.kill(RestartSelect)\n            file.close()\n            error = _bonjour.BonjourError(error_code)\n            notification_center.post_notification('BonjourAccountDiscoveryFailure', sender=self.account, data=NotificationData(error=str(error), transport=file.transport))\n            # start a new resolve process here? -Dan\n\n    def _process_files(self):\n        while True:\n            try:\n                ready = select.select([f for f in self._files if not f.active and not f.closed], [], [])[0]\n            except RestartSelect:\n                continue\n            else:\n                for file in ready:\n                    file.active = True\n                self._command_channel.send(Command('process_results', files=[f for f in ready if not f.closed]))\n\n    def _handle_commands(self):\n        while True:\n            command = self._command_channel.wait()\n            if self._started:\n                handler = getattr(self, '_CH_%s' % command.name)\n                handler(command)\n\n    def _CH_unregister(self, command):\n        if self._register_timer is not None and self._register_timer.active():\n            self._register_timer.cancel()\n        self._register_timer = None\n        if self._update_timer is not None and self._update_timer.active():\n            self._update_timer.cancel()\n        self._update_timer = None\n        old_files = []\n        for file in (f for f in self._files[:] if isinstance(f, BonjourRegistrationFile)):\n            old_files.append(file)\n            self._files.remove(file)\n        self._select_proc.kill(RestartSelect)\n        for file in old_files:\n            file.close()\n        notification_center = NotificationCenter()\n        for transport in set(file.transport for file in self._files):\n            notification_center.post_notification('BonjourAccountRegistrationDidEnd', sender=self.account, data=NotificationData(transport=transport))\n        command.signal()\n\n    def _CH_register(self, command):\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n        if self._register_timer is not None and self._register_timer.active():\n            self._register_timer.cancel()\n        self._register_timer = None\n        supported_transports = set(transport for transport in settings.sip.transport_list if transport!='tls' or self.account.tls.certificate is not None)\n        registered_transports = set(file.transport for file in self._files if isinstance(file, BonjourRegistrationFile))\n        missing_transports = supported_transports - registered_transports\n        added_transports = set()\n        for transport in missing_transports:\n            notification_center.post_notification('BonjourAccountWillRegister', sender=self.account, data=NotificationData(transport=transport))\n            try:\n                contact = self.account.contact[NoGRUU, transport]\n                instance_id = str(uuid.UUID(settings.instance_id))\n                txtdata = dict(txtvers=1, name=self.account.display_name.encode('utf-8'), contact=\"<%s>\" % str(contact), instance_id=instance_id)\n                state = self.account.presence_state\n                if self.account.presence.enabled and state is not None:\n                    txtdata['state'] = state.state\n                    txtdata['note'] = state.note.encode('utf-8')\n                file = _bonjour.DNSServiceRegister(name=str(contact),\n                                                   regtype=\"_sipuri._%s\" % (transport if transport == 'udp' else 'tcp'),\n                                                   port=contact.port,\n                                                   callBack=self._register_cb,\n                                                   txtRecord=_bonjour.TXTRecord(items=txtdata))\n            except (_bonjour.BonjourError, KeyError), e:\n                notification_center.post_notification('BonjourAccountRegistrationDidFail', sender=self.account, data=NotificationData(reason=str(e), transport=transport))\n            else:\n                self._files.append(BonjourRegistrationFile(file, transport))\n                added_transports.add(transport)\n        if added_transports:\n            self._select_proc.kill(RestartSelect)\n        if added_transports != missing_transports:\n            self._register_timer = reactor.callLater(1, self._command_channel.send, Command('register', command.event))\n        else:\n            command.signal()\n\n    def _CH_update_registrations(self, command):\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n        if self._update_timer is not None and self._update_timer.active():\n            self._update_timer.cancel()\n        self._update_timer = None\n        available_transports = settings.sip.transport_list\n        old_files = []\n        for file in (f for f in self._files[:] if isinstance(f, BonjourRegistrationFile) and f.transport not in available_transports):\n            old_files.append(file)\n            self._files.remove(file)\n        self._select_proc.kill(RestartSelect)\n        for file in old_files:\n            file.close()\n        update_failure = False\n        for file in (f for f in self._files if isinstance(f, BonjourRegistrationFile)):\n            try:\n                contact = self.account.contact[NoGRUU, file.transport]\n                instance_id = str(uuid.UUID(settings.instance_id))\n                txtdata = dict(txtvers=1, name=self.account.display_name.encode('utf-8'), contact=\"<%s>\" % str(contact), instance_id=instance_id)\n                state = self.account.presence_state\n                if self.account.presence.enabled and state is not None:\n                    txtdata['state'] = state.state\n                    txtdata['note'] = state.note.encode('utf-8')\n                _bonjour.DNSServiceUpdateRecord(file.file, None, flags=0, rdata=_bonjour.TXTRecord(items=txtdata), ttl=0)\n            except (_bonjour.BonjourError, KeyError), e:\n                notification_center.post_notification('BonjourAccountRegistrationUpdateDidFail', sender=self.account, data=NotificationData(reason=str(e), transport=file.transport))\n                update_failure = True\n        self._command_channel.send(Command('register'))\n        if update_failure:\n            self._update_timer = reactor.callLater(1, self._command_channel.send, Command('update_registrations', command.event))\n        else:\n            command.signal()\n\n    def _CH_discover(self, command):\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n        if self._discover_timer is not None and self._discover_timer.active():\n            self._discover_timer.cancel()\n        self._discover_timer = None\n        supported_transports = set(transport for transport in settings.sip.transport_list if transport!='tls' or self.account.tls.certificate is not None)\n        discoverable_transports = set('tcp' if transport=='tls' else transport for transport in supported_transports)\n        old_files = []\n        for file in (f for f in self._files[:] if isinstance(f, (BonjourDiscoveryFile, BonjourResolutionFile)) and f.transport not in discoverable_transports):\n            old_files.append(file)\n            self._files.remove(file)\n        self._select_proc.kill(RestartSelect)\n        for file in old_files:\n            file.close()\n        for service_description in [service for service, record in self._neighbours.iteritems() if record.uri.transport not in supported_transports]:\n            record = self._neighbours.pop(service_description)\n            notification_center.post_notification('BonjourAccountDidRemoveNeighbour', sender=self.account, data=NotificationData(neighbour=service_description, record=record))\n        discovered_transports = set(file.transport for file in self._files if isinstance(file, BonjourDiscoveryFile))\n        missing_transports = discoverable_transports - discovered_transports\n        added_transports = set()\n        for transport in missing_transports:\n            notification_center.post_notification('BonjourAccountWillInitiateDiscovery', sender=self.account, data=NotificationData(transport=transport))\n            try:\n                file = _bonjour.DNSServiceBrowse(regtype=\"_sipuri._%s\" % transport, callBack=self._browse_cb)\n            except _bonjour.BonjourError, e:\n                notification_center.post_notification('BonjourAccountDiscoveryDidFail', sender=self.account, data=NotificationData(reason=str(e), transport=transport))\n            else:\n                self._files.append(BonjourDiscoveryFile(file, transport))\n                added_transports.add(transport)\n        if added_transports:\n            self._select_proc.kill(RestartSelect)\n        if added_transports != missing_transports:\n            self._discover_timer = reactor.callLater(1, self._command_channel.send, Command('discover', command.event))\n        else:\n            command.signal()\n\n    def _CH_process_results(self, command):\n        for file in (f for f in command.files if not f.closed):\n            try:\n                _bonjour.DNSServiceProcessResult(file.file)\n            except:\n                # Should we close the file? The documentation doesn't say anything about this. -Luci\n                log.exception()\n        for file in command.files:\n            file.active = False\n        self._files = [f for f in self._files if not f.closed]\n        self._select_proc.kill(RestartSelect)\n\n    def _CH_stop(self, command):\n        if self._discover_timer is not None and self._discover_timer.active():\n            self._discover_timer.cancel()\n        self._discover_timer = None\n        if self._register_timer is not None and self._register_timer.active():\n            self._register_timer.cancel()\n        self._register_timer = None\n        if self._update_timer is not None and self._update_timer.active():\n            self._update_timer.cancel()\n        self._update_timer = None\n        files = self._files\n        neighbours = self._neighbours\n        self._files = []\n        self._select_proc.kill(RestartSelect)\n        self._neighbours = {}\n        for file in files:\n            file.close()\n        notification_center = NotificationCenter()\n        for neighbour, record in neighbours.iteritems():\n            notification_center.post_notification('BonjourAccountDidRemoveNeighbour', sender=self.account, data=NotificationData(neighbour=neighbour, record=record))\n        for transport in set(file.transport for file in files):\n            notification_center.post_notification('BonjourAccountRegistrationDidEnd', sender=self.account, data=NotificationData(transport=transport))\n        command.signal()\n\n    @run_in_twisted_thread\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_NetworkConditionsDidChange(self, notification):\n        if self._files:\n            self.restart_discovery()\n            self.restart_registration()\n\n\nclass BonjourPresenceState(object):\n    def __init__(self, state, note=None):\n        self.state = state\n        self.note = note or u''\n\n    def __eq__(self, other):\n        if isinstance(other, BonjourPresenceState):\n            return self.state == other.state and self.note == other.note\n        return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n"
  },
  {
    "path": "sipsimple/account/bonjour/_bonjour.py",
    "content": "################################################################################\n#\n# Copyright (c) 2007-2008 Christopher J. Stawarz\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation files\n# (the \"Software\"), to deal in the Software without restriction,\n# including without limitation the rights to use, copy, modify, merge,\n# publish, distribute, sublicense, and/or sell copies of the Software,\n# and to permit persons to whom the Software is furnished to do so,\n# subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\n# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\n# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n#\n################################################################################\n\n\n\n\"\"\"\n\nPure-Python interface to Apple Bonjour and compatible DNS-SD libraries\n\npybonjour provides a pure-Python interface (via ctypes) to Apple\nBonjour and compatible DNS-SD libraries (such as Avahi).  It allows\nPython scripts to take advantage of Zero Configuration Networking\n(Zeroconf) to register, discover, and resolve services on both local\nand wide-area networks.  Since pybonjour is implemented in pure\nPython, scripts that use it can easily be ported to Mac OS X, Windows,\nLinux, and other systems that run Bonjour.\n\nNote on strings: Internally, all strings used in DNS-SD are UTF-8\nstrings.  String arguments passed to the DNS-SD functions provided by\npybonjour must be either unicode instances or str instances that can\nbe converted to unicode using the default encoding.  (Passing a\nnon-convertible str will result in an exception.)  Strings returned\nfrom pybonjour (either directly from API functions or passed to\napplication callbacks) are always unicode instances.\n\n\"\"\"\n\n__author__   = 'Christopher Stawarz <cstawarz@csail.mit.edu>'\n__version__  = '1.1.1'\n__revision__ = int('$Revision: 6125 $'.split()[1])\n\n\nimport ctypes\nimport os\nimport re\nimport socket\nimport sys\n\nfrom application.python import Null\n\n\n################################################################################\n#\n# Global setup\n#\n################################################################################\n\n\n\nclass _DummyLock(object):\n\n    @staticmethod\n    def acquire():\n        pass\n\n    @staticmethod\n    def release():\n        pass\n\n_global_lock = _DummyLock()\n\n\nif sys.platform == 'win32':\n    # Need to use the stdcall variants\n    try:\n        _libdnssd = ctypes.windll.dnssd\n    except:\n        _libdnssd = _CFunc = Null\n        available = False\n    else:\n        _CFunc = ctypes.WINFUNCTYPE\n        available = True\nelse:\n    if sys.platform == 'darwin':\n        _libdnssd = 'libSystem.B.dylib'\n    else:\n        _libdnssd = 'libdns_sd.so.1'\n\n        # If libdns_sd is actually Avahi's Bonjour compatibility\n        # layer, silence its annoying warning messages, and use a real\n        # RLock as the global lock, since the compatibility layer\n        # isn't thread safe.\n        try:\n            ctypes.cdll.LoadLibrary('libavahi-client.so.3')\n        except OSError:\n            pass\n        else:\n            os.environ['AVAHI_COMPAT_NOWARN'] = '1'\n            from eventlib.green.threading import RLock\n            _global_lock = RLock()\n\n    try:\n        _libdnssd = ctypes.cdll.LoadLibrary(_libdnssd)\n    except:\n        _libdnssd = _CFunc = Null\n        available = False\n    else:\n        _CFunc = ctypes.CFUNCTYPE\n        available = True\n\n\n\n################################################################################\n#\n# Constants\n#\n################################################################################\n\n\n\n#\n# General flags\n#\n\nkDNSServiceFlagsMoreComing          = 0x1\nkDNSServiceFlagsAdd                 = 0x2\nkDNSServiceFlagsDefault             = 0x4\nkDNSServiceFlagsNoAutoRename        = 0x8\nkDNSServiceFlagsShared              = 0x10\nkDNSServiceFlagsUnique              = 0x20\nkDNSServiceFlagsBrowseDomains       = 0x40\nkDNSServiceFlagsRegistrationDomains = 0x80\nkDNSServiceFlagsLongLivedQuery      = 0x100\nkDNSServiceFlagsAllowRemoteQuery    = 0x200\nkDNSServiceFlagsForceMulticast      = 0x400\nkDNSServiceFlagsReturnCNAME         = 0x800\n\n\n#\n# Service classes\n#\n\nkDNSServiceClass_IN                 = 1\n\n\n#\n# Service types\n#\n\nkDNSServiceType_A                   = 1\nkDNSServiceType_NS                  = 2\nkDNSServiceType_MD                  = 3\nkDNSServiceType_MF                  = 4\nkDNSServiceType_CNAME               = 5\nkDNSServiceType_SOA                 = 6\nkDNSServiceType_MB                  = 7\nkDNSServiceType_MG                  = 8\nkDNSServiceType_MR                  = 9\nkDNSServiceType_NULL                = 10\nkDNSServiceType_WKS                 = 11\nkDNSServiceType_PTR                 = 12\nkDNSServiceType_HINFO               = 13\nkDNSServiceType_MINFO               = 14\nkDNSServiceType_MX                  = 15\nkDNSServiceType_TXT                 = 16\nkDNSServiceType_RP                  = 17\nkDNSServiceType_AFSDB               = 18\nkDNSServiceType_X25                 = 19\nkDNSServiceType_ISDN                = 20\nkDNSServiceType_RT                  = 21\nkDNSServiceType_NSAP                = 22\nkDNSServiceType_NSAP_PTR            = 23\nkDNSServiceType_SIG                 = 24\nkDNSServiceType_KEY                 = 25\nkDNSServiceType_PX                  = 26\nkDNSServiceType_GPOS                = 27\nkDNSServiceType_AAAA                = 28\nkDNSServiceType_LOC                 = 29\nkDNSServiceType_NXT                 = 30\nkDNSServiceType_EID                 = 31\nkDNSServiceType_NIMLOC              = 32\nkDNSServiceType_SRV                 = 33\nkDNSServiceType_ATMA                = 34\nkDNSServiceType_NAPTR               = 35\nkDNSServiceType_KX                  = 36\nkDNSServiceType_CERT                = 37\nkDNSServiceType_A6                  = 38\nkDNSServiceType_DNAME               = 39\nkDNSServiceType_SINK                = 40\nkDNSServiceType_OPT                 = 41\nkDNSServiceType_TKEY                = 249\nkDNSServiceType_TSIG                = 250\nkDNSServiceType_IXFR                = 251\nkDNSServiceType_AXFR                = 252\nkDNSServiceType_MAILB               = 253\nkDNSServiceType_MAILA               = 254\nkDNSServiceType_ANY                 = 255\n\n\n#\n# Error codes\n#\n\nkDNSServiceErr_NoError              = 0\nkDNSServiceErr_Unknown              = -65537\nkDNSServiceErr_NoSuchName           = -65538\nkDNSServiceErr_NoMemory             = -65539\nkDNSServiceErr_BadParam             = -65540\nkDNSServiceErr_BadReference         = -65541\nkDNSServiceErr_BadState             = -65542\nkDNSServiceErr_BadFlags             = -65543\nkDNSServiceErr_Unsupported          = -65544\nkDNSServiceErr_NotInitialized       = -65545\nkDNSServiceErr_AlreadyRegistered    = -65547\nkDNSServiceErr_NameConflict         = -65548\nkDNSServiceErr_Invalid              = -65549\nkDNSServiceErr_Firewall             = -65550\nkDNSServiceErr_Incompatible         = -65551\nkDNSServiceErr_BadInterfaceIndex    = -65552\nkDNSServiceErr_Refused              = -65553\nkDNSServiceErr_NoSuchRecord         = -65554\nkDNSServiceErr_NoAuth               = -65555\nkDNSServiceErr_NoSuchKey            = -65556\nkDNSServiceErr_NATTraversal         = -65557\nkDNSServiceErr_DoubleNAT            = -65558\nkDNSServiceErr_BadTime              = -65559\n\n\n#\n# Other constants\n#\n\nkDNSServiceMaxServiceName           = 64\nkDNSServiceMaxDomainName            = 1005\nkDNSServiceInterfaceIndexAny        = 0\nkDNSServiceInterfaceIndexLocalOnly  = -1\n\n\n\n################################################################################\n#\n# Error handling\n#\n################################################################################\n\n\n\nclass BonjourError(Exception):\n\n    \"\"\"\n\n    Exception representing an error returned by the DNS-SD library.\n    The errorCode attribute contains the actual integer error code\n    returned.\n\n    \"\"\"\n\n    _errmsg = {\n        kDNSServiceErr_NoSuchName:\t\t'no such name',\n        kDNSServiceErr_NoMemory:\t\t'no memory',\n        kDNSServiceErr_BadParam:\t\t'bad param',\n        kDNSServiceErr_BadReference:\t\t'bad reference',\n        kDNSServiceErr_BadState:\t\t'bad state',\n        kDNSServiceErr_BadFlags:\t\t'bad flags',\n        kDNSServiceErr_Unsupported:\t\t'unsupported',\n        kDNSServiceErr_NotInitialized:\t\t'not initialized',\n        kDNSServiceErr_AlreadyRegistered:\t'already registered',\n        kDNSServiceErr_NameConflict:\t\t'name conflict',\n        kDNSServiceErr_Invalid:\t\t\t'invalid',\n        kDNSServiceErr_Firewall:\t\t'firewall',\n        kDNSServiceErr_Incompatible:\t\t'incompatible',\n        kDNSServiceErr_BadInterfaceIndex:\t'bad interface index',\n        kDNSServiceErr_Refused:\t\t\t'refused',\n        kDNSServiceErr_NoSuchRecord:\t\t'no such record',\n        kDNSServiceErr_NoAuth:\t\t\t'no auth',\n        kDNSServiceErr_NoSuchKey:\t\t'no such key',\n        kDNSServiceErr_NATTraversal:\t\t'NAT traversal',\n        kDNSServiceErr_DoubleNAT:\t\t'double NAT',\n        kDNSServiceErr_BadTime:\t\t\t'bad time',\n        }\n\n    @classmethod\n    def _errcheck(cls, result, func, args):\n        if result != kDNSServiceErr_NoError:\n            raise cls(result)\n        return args\n\n    def __init__(self, errorCode):\n        self.errorCode = errorCode\n        Exception.__init__(self,\n                           (errorCode, self._errmsg.get(errorCode, 'unknown')))\n\n\n\n################################################################################\n#\n# Data types\n#\n################################################################################\n\n\n\nclass _utf8_char_p(ctypes.c_char_p):\n\n    @classmethod\n    def from_param(cls, obj):\n        if (obj is not None) and (not isinstance(obj, cls)):\n            if not isinstance(obj, basestring):\n                raise TypeError('parameter must be a string type instance')\n            if not isinstance(obj, unicode):\n                obj = unicode(obj)\n            obj = obj.encode('utf-8')\n        return ctypes.c_char_p.from_param(obj)\n\n    def decode(self):\n        if self.value is None:\n            return None\n        return self.value.decode('utf-8')\n\n\nclass _utf8_char_p_non_null(_utf8_char_p):\n\n    @classmethod\n    def from_param(cls, obj):\n        if obj is None:\n            raise ValueError('parameter cannot be None')\n        return _utf8_char_p.from_param(obj)\n\n\n_DNSServiceFlags     = ctypes.c_uint32\n_DNSServiceErrorType = ctypes.c_int32\n\n\nclass DNSRecordRef(ctypes.c_void_p):\n\n    \"\"\"\n\n    A DNSRecordRef pointer.  DO NOT CREATE INSTANCES OF THIS CLASS!\n    Only instances returned by the DNS-SD library are valid.  Using\n    others will likely cause the Python interpreter to crash.\n\n    Application code should not use any of the methods of this class.\n    The only valid use of a DNSRecordRef instance is as an argument to\n    a DNS-SD function.\n\n    To compare two DNSRecordRef instances for equality, use '=='\n    rather than 'is'.\n\n    \"\"\"\n\n    @classmethod\n    def from_param(cls, obj):\n        if type(obj) is not cls:\n            raise TypeError(\"expected '%s', got '%s'\" %\n                            (cls.__name__, type(obj).__name__))\n        if obj.value is None:\n            raise ValueError('invalid %s instance' % cls.__name__)\n        return obj\n\n    def __eq__(self, other):\n        return ((type(other) is type(self)) and\t(other.value == self.value))\n\n    def __ne__(self, other):\n        return not (other == self)\n    \n    def __hash__(self):\n        return hash(self.value)\n\n    def _invalidate(self):\n        self.value = None\n\n    def _valid(self):\n        return (self.value is not None)\n\n\nclass _DNSRecordRef_or_null(DNSRecordRef):\n\n    @classmethod\n    def from_param(cls, obj):\n        if obj is None:\n            return obj\n        return DNSRecordRef.from_param(obj)\n\n\nclass DNSServiceRef(DNSRecordRef):\n\n    \"\"\"\n\n    A DNSServiceRef pointer.  DO NOT CREATE INSTANCES OF THIS CLASS!\n    Only instances returned by the DNS-SD library are valid.  Using\n    others will likely cause the Python interpreter to crash.\n\n    An instance of this class represents an active connection to the\n    mDNS daemon.  The connection remains open until the close() method\n    is called (which also terminates the associated browse, resolve,\n    etc.).  Note that this method is *not* called automatically when\n    the instance is deallocated; therefore, application code must be\n    certain to call close() when the connection is no longer needed.\n\n    The primary use of a DNSServiceRef instance is in conjunction with\n    select() or poll() to determine when a response from the daemon is\n    available.  When the file descriptor returned by fileno() is ready\n    for reading, a reply from the daemon is available and should be\n    processed by passing the DNSServiceRef instance to\n    DNSServiceProcessResult(), which will invoke the appropriate\n    application callback function.  (Note that the file descriptor\n    should never be read from or written to directly.)\n\n    The DNSServiceRef class supports the context management protocol\n    introduced in Python 2.5, meaning applications can use the 'with'\n    statement to ensure that DNSServiceRef instances are closed\n    regardless of whether an exception occurs, e.g.\n\n      sdRef = DNSServiceBrowse(...)\n      with sdRef:\n          # sdRef will be closed regardless of how this block is\n          # exited\n          ...\n\n    To compare two DNSServiceRef instances for equality, use '=='\n    rather than 'is'.\n\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        DNSRecordRef.__init__(self, *args, **kwargs)\n\n        # Since callback functions are called asynchronously, we need\n        # to hold onto references to them for as long as they're in\n        # use.  Otherwise, Python could deallocate them before we call\n        # DNSServiceProcessResult(), meaning the Bonjour library would\n        # dereference freed memory when it tried to invoke the\n        # callback.\n        self._callbacks = []\n\n        # A DNSRecordRef is invalidated if DNSServiceRefDeallocate()\n        # is called on the corresponding DNSServiceRef, so we need to\n        # keep track of all our record refs and invalidate them when\n        # we're closed.\n        self._record_refs = []\n\n    def __enter__(self):\n        return self\n\n    def __exit__(self, type, value, traceback):\n        self.close()\n\n    def _add_callback(self, cb):\n        self._callbacks.append(cb)\n\n    def _add_record_ref(self, ref):\n        self._record_refs.append(ref)\n\n    def close(self):\n        \"\"\"\n\n        Close the connection to the mDNS daemon and terminate any\n        associated browse, resolve, etc. operations.\n\n        \"\"\"\n\n        if self._valid():\n            for ref in self._record_refs:\n                ref._invalidate()\n            del self._record_refs\n\n            _global_lock.acquire()\n            try:\n                _DNSServiceRefDeallocate(self)\n            finally:\n                _global_lock.release()\n\n            self._invalidate()\n            del self._callbacks\n\n    def fileno(self):\n        \"\"\"\n\n        Return the file descriptor associated with this connection.\n        This descriptor should never be read from or written to\n        directly.  It should only be passed to select() or poll() to\n        determine when a response from the mDNS daemon is available.\n\n        \"\"\"\n\n        _global_lock.acquire()\n        try:\n            fd = _DNSServiceRefSockFD(self)\n        finally:\n            _global_lock.release()\n\n        return fd\n\n\n_DNSServiceDomainEnumReply = _CFunc(\n    None,\n    DNSServiceRef,\t\t# sdRef\n    _DNSServiceFlags,\t\t# flags\n    ctypes.c_uint32,\t\t# interfaceIndex\n    _DNSServiceErrorType,\t# errorCode\n    _utf8_char_p,\t\t# replyDomain\n    ctypes.c_void_p,\t\t# context\n    )\n\n\n_DNSServiceRegisterReply = _CFunc(\n    None,\n    DNSServiceRef,\t\t# sdRef\n    _DNSServiceFlags,\t\t# flags\n    _DNSServiceErrorType,\t# errorCode\n    _utf8_char_p,\t\t# name\n    _utf8_char_p,\t\t# regtype\n    _utf8_char_p,\t\t# domain\n    ctypes.c_void_p,\t\t# context\n    )\n\n\n_DNSServiceBrowseReply = _CFunc(\n    None,\n    DNSServiceRef,\t\t# sdRef\n    _DNSServiceFlags,\t\t# flags\n    ctypes.c_uint32,\t\t# interfaceIndex\n    _DNSServiceErrorType,\t# errorCode\n    _utf8_char_p,\t\t# serviceName\n    _utf8_char_p,\t\t# regtype\n    _utf8_char_p,\t\t# replyDomain\n    ctypes.c_void_p,\t\t# context\n    )\n\n\n_DNSServiceResolveReply = _CFunc(\n    None,\n    DNSServiceRef,\t\t# sdRef\n    _DNSServiceFlags,\t\t# flags\n    ctypes.c_uint32,\t\t# interfaceIndex\n    _DNSServiceErrorType,\t# errorCode\n    _utf8_char_p,\t\t# fullname\n    _utf8_char_p,\t\t# hosttarget\n    ctypes.c_uint16,\t\t# port\n    ctypes.c_uint16,\t\t# txtLen\n    ctypes.c_void_p,\t\t# txtRecord (not null-terminated, so c_void_p)\n    ctypes.c_void_p,\t\t# context\n    )\n\n\n_DNSServiceRegisterRecordReply = _CFunc(\n    None,\n    DNSServiceRef,\t\t# sdRef\n    DNSRecordRef,\t\t# RecordRef\n    _DNSServiceFlags,\t\t# flags\n    _DNSServiceErrorType,\t# errorCode\n    ctypes.c_void_p,\t\t# context\n    )\n\n\n_DNSServiceQueryRecordReply = _CFunc(\n    None,\n    DNSServiceRef,\t\t# sdRef\n    _DNSServiceFlags,\t\t# flags\n    ctypes.c_uint32,\t\t# interfaceIndex\n    _DNSServiceErrorType,\t# errorCode\n    _utf8_char_p,\t\t# fullname\n    ctypes.c_uint16,\t\t# rrtype\n    ctypes.c_uint16,\t\t# rrclass\n    ctypes.c_uint16,\t\t# rdlen\n    ctypes.c_void_p,\t\t# rdata\n    ctypes.c_uint32,\t\t# ttl\n    ctypes.c_void_p,\t\t# context\n    )\n\n\n\n################################################################################\n#\n# Low-level function bindings\n#\n################################################################################\n\n\n\ndef _create_function_bindings():\n\n    ERRCHECK    = True\n    NO_ERRCHECK = False\n\n    OUTPARAM    = (lambda index: index)\n    NO_OUTPARAM = None\n\n    specs = {\n\n        #'funcname':\n        #(\n        #    return_type,\n        #    errcheck,\n        #    outparam,\n        #    (\n        #\tparam_1_type,\n        #\tparam_2_type,\n        #\t...\n        #\tparam_n_type,\n        #\t)),\n\n        'DNSServiceRefSockFD':\n        (\n            ctypes.c_int,\n            NO_ERRCHECK,\n            NO_OUTPARAM,\n            (\n                DNSServiceRef,\t\t\t# sdRef\n                )),\n\n        'DNSServiceProcessResult':\n        (\n            _DNSServiceErrorType,\n            ERRCHECK,\n            NO_OUTPARAM,\n            (\n                DNSServiceRef,\t\t\t# sdRef\n                )),\n\n        'DNSServiceRefDeallocate':\n        (\n            None,\n            NO_ERRCHECK,\n            NO_OUTPARAM,\n            (\n                DNSServiceRef,\t\t\t# sdRef\n                )),\n\n        'DNSServiceEnumerateDomains':\n        (\n            _DNSServiceErrorType,\n            ERRCHECK,\n            OUTPARAM(0),\n            (\n                ctypes.POINTER(DNSServiceRef),\t# sdRef\n                _DNSServiceFlags,\t\t# flags\n                ctypes.c_uint32,\t\t# interfaceIndex\n                _DNSServiceDomainEnumReply,\t# callBack\n                ctypes.c_void_p,\t\t# context\n                )),\n\n        'DNSServiceRegister':\n        (\n            _DNSServiceErrorType,\n            ERRCHECK,\n            OUTPARAM(0),\n            (\n                ctypes.POINTER(DNSServiceRef),\t# sdRef\n                _DNSServiceFlags,\t\t# flags\n                ctypes.c_uint32,\t\t# interfaceIndex\n                _utf8_char_p,\t\t\t# name\n                _utf8_char_p_non_null,\t\t# regtype\n                _utf8_char_p,\t\t\t# domain\n                _utf8_char_p,\t\t\t# host\n                ctypes.c_uint16,\t\t# port\n                ctypes.c_uint16,\t\t# txtLen\n                ctypes.c_void_p,\t\t# txtRecord\n                _DNSServiceRegisterReply,\t# callBack\n                ctypes.c_void_p,\t\t# context\n                )),\n\n        'DNSServiceAddRecord':\n        (\n            _DNSServiceErrorType,\n            ERRCHECK,\n            OUTPARAM(1),\n            (\n                DNSServiceRef,\t\t\t# sdRef\n                ctypes.POINTER(DNSRecordRef),\t# RecordRef\n                _DNSServiceFlags,\t\t# flags\n                ctypes.c_uint16,\t\t# rrtype\n                ctypes.c_uint16,\t\t# rdlen\n                ctypes.c_void_p,\t\t# rdata\n                ctypes.c_uint32,\t\t# ttl\n                )),\n\n        'DNSServiceUpdateRecord':\n        (\n            _DNSServiceErrorType,\n            ERRCHECK,\n            NO_OUTPARAM,\n            (\n                DNSServiceRef,\t\t\t# sdRef\n                _DNSRecordRef_or_null,\t\t# RecordRef\n                _DNSServiceFlags,\t\t# flags\n                ctypes.c_uint16,\t\t# rdlen\n                ctypes.c_void_p,\t\t# rdata\n                ctypes.c_uint32,\t\t# ttl\n                )),\n\n        'DNSServiceRemoveRecord':\n        (\n            _DNSServiceErrorType,\n            ERRCHECK,\n            NO_OUTPARAM,\n            (\n                DNSServiceRef,\t\t\t# sdRef\n                DNSRecordRef,\t\t\t# RecordRef\n                _DNSServiceFlags,\t\t# flags\n                )),\n\n        'DNSServiceBrowse':\n        (\n            _DNSServiceErrorType,\n            ERRCHECK,\n            OUTPARAM(0),\n            (\n                ctypes.POINTER(DNSServiceRef),\t# sdRef\n                _DNSServiceFlags,\t\t# flags\n                ctypes.c_uint32,\t\t# interfaceIndex\n                _utf8_char_p_non_null,\t\t# regtype\n                _utf8_char_p,\t\t\t# domain\n                _DNSServiceBrowseReply,\t\t# callBack\n                ctypes.c_void_p,\t\t# context\n                )),\n\n        'DNSServiceResolve':\n        (\n            _DNSServiceErrorType,\n            ERRCHECK,\n            OUTPARAM(0),\n            (\n                ctypes.POINTER(DNSServiceRef),\t# sdRef\n                _DNSServiceFlags,\t\t# flags\n                ctypes.c_uint32,\t\t# interfaceIndex\n                _utf8_char_p_non_null,\t\t# name\n                _utf8_char_p_non_null,\t\t# regtype\n                _utf8_char_p_non_null,\t\t# domain\n                _DNSServiceResolveReply,\t# callBack\n                ctypes.c_void_p,\t\t# context\n                )),\n\n        'DNSServiceCreateConnection':\n        (\n            _DNSServiceErrorType,\n            ERRCHECK,\n            OUTPARAM(0),\n            (\n                ctypes.POINTER(DNSServiceRef),\t# sdRef\n                )),\n\n        'DNSServiceRegisterRecord':\n        (\n            _DNSServiceErrorType,\n            ERRCHECK,\n            OUTPARAM(1),\n            (\n                DNSServiceRef,\t\t\t# sdRef\n                ctypes.POINTER(DNSRecordRef),\t# RecordRef\n                _DNSServiceFlags,\t\t# flags\n                ctypes.c_uint32,\t\t# interfaceIndex\n                _utf8_char_p_non_null,\t\t# fullname\n                ctypes.c_uint16,\t\t# rrtype\n                ctypes.c_uint16,\t\t# rrclass\n                ctypes.c_uint16,\t\t# rdlen\n                ctypes.c_void_p,\t\t# rdata\n                ctypes.c_uint32,\t\t# ttl\n                _DNSServiceRegisterRecordReply,\t# callBack\n                ctypes.c_void_p,\t\t# context\n                )),\n\n        'DNSServiceQueryRecord':\n        (\n            _DNSServiceErrorType,\n            ERRCHECK,\n            OUTPARAM(0),\n            (\n                ctypes.POINTER(DNSServiceRef),\t# sdRef\n                _DNSServiceFlags,\t\t# flags\n                ctypes.c_uint32,\t\t# interfaceIndex\n                _utf8_char_p_non_null,\t\t# fullname\n                ctypes.c_uint16,\t\t# rrtype\n                ctypes.c_uint16,\t\t# rrclass\n                _DNSServiceQueryRecordReply,\t# callBack\n                ctypes.c_void_p,\t\t# context\n                )),\n\n        'DNSServiceReconfirmRecord':\n        (\n            None,\t\t# _DNSServiceErrorType in more recent versions\n            NO_ERRCHECK,\n            NO_OUTPARAM,\n            (\n                _DNSServiceFlags,\t\t# flags\n                ctypes.c_uint32,\t\t# interfaceIndex\n                _utf8_char_p_non_null,\t\t# fullname\n                ctypes.c_uint16,\t\t# rrtype\n                ctypes.c_uint16,\t\t# rrclass\n                ctypes.c_uint16,\t\t# rdlen\n                ctypes.c_void_p,\t\t# rdata\n                )),\n\n        'DNSServiceConstructFullName':\n        (\n            ctypes.c_int,\n            ERRCHECK,\n            OUTPARAM(0),\n            (\n                ctypes.c_char * kDNSServiceMaxDomainName,\t# fullName\n                _utf8_char_p,\t\t\t\t\t# service\n                _utf8_char_p_non_null,\t\t\t\t# regtype\n                _utf8_char_p_non_null,\t\t\t\t# domain\n                )),\n\n        }\n\n\n    for name, (restype, errcheck, outparam, argtypes) in specs.iteritems():\n        prototype = _CFunc(restype, *argtypes)\n\n        paramflags = [1] * len(argtypes)\n        if outparam is not None:\n            paramflags[outparam] = 2\n        paramflags = tuple((val,) for val in paramflags)\n\n        func = prototype((name, _libdnssd), paramflags)\n\n        if errcheck:\n            func.errcheck = BonjourError._errcheck\n\n        globals()['_' + name] = func\n\n\n# preset these so that pyflakes doesn't complain\n_DNSServiceRefDeallocate = None\n_DNSServiceRefSockFD = None\n_DNSServiceProcessResult = None\n_DNSServiceEnumerateDomains = None\n_DNSServiceRegister = None\n_DNSServiceAddRecord = None\n_DNSServiceUpdateRecord = None\n_DNSServiceRemoveRecord = None\n_DNSServiceBrowse = None\n_DNSServiceResolve = None\n_DNSServiceCreateConnection = None\n_DNSServiceRegisterRecord = None\n_DNSServiceQueryRecord = None\n_DNSServiceReconfirmRecord = None\n_DNSServiceConstructFullName = None\n\n# Only need to do this once\n_create_function_bindings()\ndel _create_function_bindings\n\n\n\n################################################################################\n#\n# Internal utility types and functions\n#\n################################################################################\n\n\n\nclass _NoDefault(object):\n\n    def __repr__(self):\n        return '<NO DEFAULT>'\n\n    def check(self, obj):\n        if obj is self:\n            raise ValueError('required parameter value missing')\n\n_NO_DEFAULT = _NoDefault()\n\n\ndef _string_to_length_and_void_p(string):\n    if isinstance(string, TXTRecord):\n        string = str(string)\n    void_p = ctypes.cast(ctypes.c_char_p(string), ctypes.c_void_p)\n    return len(string), void_p\n\n\ndef _length_and_void_p_to_string(length, void_p):\n    char_p = ctypes.cast(void_p, ctypes.POINTER(ctypes.c_char))\n    return ''.join(char_p[i] for i in xrange(length))\n\n\n\n################################################################################\n#\n# High-level functions\n#\n################################################################################\n\n\n\ndef DNSServiceProcessResult(\n    sdRef,\n    ):\n\n    \"\"\"\n\n    Read a reply from the daemon, calling the appropriate application\n    callback.  This call will block until the daemon's response is\n    received.  Use sdRef in conjunction with select() or poll() to\n    determine the presence of a response from the server before\n    calling this function to process the reply without blocking.  Call\n    this function at any point if it is acceptable to block until the\n    daemon's response arrives.  Note that the client is responsible\n    for ensuring that DNSServiceProcessResult() is called whenever\n    there is a reply from the daemon; the daemon may terminate its\n    connection with a client that does not process the daemon's\n    responses.\n\n      sdRef:\n        A DNSServiceRef returned by any of the DNSService calls that\n        take a callback parameter.\n\n    \"\"\"\n\n    _global_lock.acquire()\n    try:\n        _DNSServiceProcessResult(sdRef)\n    finally:\n        _global_lock.release()\n\n\ndef DNSServiceEnumerateDomains(\n    flags,\n    interfaceIndex = kDNSServiceInterfaceIndexAny,\n    callBack = None,\n    ):\n\n    \"\"\"\n\n    Asynchronously enumerate domains available for browsing and\n    registration.\n\n    The enumeration MUST be cancelled by closing the returned\n    DNSServiceRef when no more domains are to be found.\n\n      flags:\n        Possible values are:\n          kDNSServiceFlagsBrowseDomains to enumerate domains\n          recommended for browsing.\n          kDNSServiceFlagsRegistrationDomains to enumerate domains\n          recommended for registration.\n\n      interfaceIndex:\n        If non-zero, specifies the interface on which to look for\n        domains.  Most applications will pass\n        kDNSServiceInterfaceIndexAny (0) to enumerate domains on all\n        interfaces.\n\n      callBack:\n        The function to be called when a domain is found or the call\n        asynchronously fails.  Its signature should be\n        callBack(sdRef,\tflags, interfaceIndex, errorCode, replyDomain).\n\n      return value:\n        A DNSServiceRef instance.\n\n    Callback Parameters:\n\n      sdRef:\n        The DNSServiceRef returned by DNSServiceEnumerateDomains().\n\n      flags:\n        Possible values are:\n          kDNSServiceFlagsMoreComing\n          kDNSServiceFlagsAdd\n          kDNSServiceFlagsDefault\n\n      interfaceIndex:\n        Specifies the interface on which the domain exists.\n\n      errorCode:\n        Will be kDNSServiceErr_NoError (0) on success, otherwise\n        indicates the failure that occurred (in which case other\n        parameters are undefined).\n\n      replyDomain:\n        The name of the domain.\n\n    \"\"\"\n\n    @_DNSServiceDomainEnumReply\n    def _callback(sdRef, flags, interfaceIndex, errorCode, replyDomain,\n                  context):\n        if callBack is not None:\n            callBack(sdRef, flags, interfaceIndex, errorCode,\n                     replyDomain.decode())\n\n    _global_lock.acquire()\n    try:\n        sdRef = _DNSServiceEnumerateDomains(flags,\n                                            interfaceIndex,\n                                            _callback,\n                                            None)\n    finally:\n        _global_lock.release()\n\n    sdRef._add_callback(_callback)\n\n    return sdRef\n\n\ndef DNSServiceRegister(\n    flags = 0,\n    interfaceIndex = kDNSServiceInterfaceIndexAny,\n    name = None,\n    regtype = _NO_DEFAULT,\n    domain = None,\n    host = None,\n    port = _NO_DEFAULT,\n    txtRecord = '',\n    callBack = None,\n    ):\n\n    \"\"\"\n\n    Register a service that is discovered via DNSServiceBrowse() and\n    DNSServiceResolve() calls.\n\n      flags:\n        Indicates the renaming behavior on name conflict.  Most\n        applications will pass 0.\n\n      interfaceIndex:\n        If non-zero, specifies the interface on which to register the\n        service.  Most applications will pass\n        kDNSServiceInterfaceIndexAny (0) to register on all available\n        interfaces.\n\n      name:\n        If not None, specifies the service name to be registered.\n        Most applications will not specify a name, in which case the\n        computer name is used.  (This name is communicated to the\n        client via the callback.)  If a name is specified, it must be\n        1-63 bytes of UTF-8 text.  If the name is longer than 63\n        bytes, it will be automatically truncated to a legal length,\n        unless the flag kDNSServiceFlagsNoAutoRename is set, in which\n        case a BonjourError exception will be thrown.\n\n      regtype:\n        The service type followed by the protocol, separated by a dot\n        (e.g. \"_ftp._tcp\"). The service type must be an underscore,\n        followed by 1-14 characters, which may be letters, digits, or\n        hyphens.  The transport protocol must be \"_tcp\" or \"_udp\". New\n        service types should be registered at\n        <http://www.dns-sd.org/ServiceTypes.html>.\n\n      domain:\n        If not None, specifies the domain on which to advertise the\n        service.  Most applications will not specify a domain, instead\n        automatically registering in the default domain(s).\n\n      host:\n        If not None, specifies the SRV target host name.  Most\n        applications will not specify a host, instead automatically\n        using the machine's default host name(s).  Note that\n        specifying a host name does NOT create an address record for\n        that host; the application is responsible for ensuring that\n        the appropriate address record exists, or creating it via\n        DNSServiceRegisterRecord().\n\n      port:\n        The port, in host (not network) byte order, on which the\n        service accepts connections.  Pass 0 for a \"placeholder\"\n        service (i.e. a service that will not be discovered by\n        browsing, but will cause a name conflict if another client\n        tries to register that same name).  Most clients will not use\n        placeholder services.\n\n      txtRecord:\n        The TXT record rdata.  If not None, txtRecord must be either a\n        TXTRecord instance or a string containing a properly formatted\n        DNS TXT record, i.e.\n        <length byte> <data> <length byte> <data> ...\n\n      callBack:\n        The function to be called when the registration completes or\n        asynchronously fails.  Its signature should be\n        callBack(sdRef, flags, errorCode, name, regtype, domain).\n        The client MAY pass None for the callback, in which case the\n        client will NOT be notified of the default values picked on\n        its behalf, and the client will NOT be notified of any\n        asynchronous errors (e.g. out of memory errors, etc.) that may\n        prevent the registration of the service.  The client may NOT\n        pass the flag kDNSServiceFlagsNoAutoRename if the callback is\n        None.  The client may still deregister the service at any time\n        by closing the returned DNSServiceRef.\n\n      return value:\n        A DNSServiceRef instance.  The registration will remain active\n        indefinitely until the client terminates it by closing the\n        DNSServiceRef.\n\n    Callback Parameters:\n\n      sdRef:\n        The DNSServiceRef returned by DNSServiceRegister().\n\n      flags:\n        Currently unused, reserved for future use.\n\n      errorCode:\n        Will be kDNSServiceErr_NoError on success, otherwise will\n        indicate the failure that occurred (including name conflicts,\n        if the kDNSServiceFlagsNoAutoRename flag was used when\n        registering).  Other parameters are undefined if an error\n        occurred.\n\n      name:\n        The service name registered.  (If the application did not\n        specify a name in DNSServiceRegister(), this indicates what\n        name was automatically chosen.)\n\n      regtype:\n        The type of service registered, as it was passed to the\n        callout.\n\n      domain:\n        The domain on which the service was registered.  (If the\n        application did not specify a domain in DNSServiceRegister(),\n        this indicates the default domain on which the service was\n        registered.)\n\n    \"\"\"\n\n    _NO_DEFAULT.check(regtype)\n    _NO_DEFAULT.check(port)\n\n    port = socket.htons(port)\n\n    if not txtRecord:\n        txtLen, txtRecord = 1, '\\0'\n    else:\n        txtLen, txtRecord = _string_to_length_and_void_p(txtRecord)\n\n    @_DNSServiceRegisterReply\n    def _callback(sdRef, flags, errorCode, name, regtype, domain, context):\n        if callBack is not None:\n            callBack(sdRef, flags, errorCode, name.decode(), regtype.decode(),\n                     domain.decode())\n\n    _global_lock.acquire()\n    try:\n        sdRef = _DNSServiceRegister(flags,\n                                    interfaceIndex,\n                                    name,\n                                    regtype,\n                                    domain,\n                                    host,\n                                    port,\n                                    txtLen,\n                                    txtRecord,\n                                    _callback,\n                                    None)\n    finally:\n        _global_lock.release()\n\n    sdRef._add_callback(_callback)\n\n    return sdRef\n\n\ndef DNSServiceAddRecord(\n    sdRef,\n    flags = 0,\n    rrtype = _NO_DEFAULT,\n    rdata = _NO_DEFAULT,\n    ttl = 0,\n    ):\n\n    \"\"\"\n\n    Add a record to a registered service.  The name of the record will\n    be the same as the registered service's name.  The record can\n    later be updated or deregistered by passing the DNSRecordRef\n    returned by this function to DNSServiceUpdateRecord() or\n    DNSServiceRemoveRecord().\n\n    Note that DNSServiceAddRecord/UpdateRecord/RemoveRecord are NOT\n    thread-safe with respect to a single DNSServiceRef.  If you plan\n    to have multiple threads in your program simultaneously add,\n    update, or remove records from the same DNSServiceRef, then it's\n    the caller's responsibility to use a lock or take similar\n    appropriate precautions to serialize those calls.\n\n      sdRef:\n        A DNSServiceRef returned by DNSServiceRegister().\n\n      flags:\n        Currently ignored, reserved for future use.\n\n      rrtype:\n        The type of the record (e.g. kDNSServiceType_TXT,\n        kDNSServiceType_SRV, etc.).\n\n      rdata:\n        A string containing the raw rdata to be contained in the added\n        resource record.\n\n      ttl:\n        The time to live of the resource record, in seconds.  Pass 0\n        to use a default value.\n\n      return value:\n        A DNSRecordRef instance, which may be passed to\n        DNSServiceUpdateRecord() or DNSServiceRemoveRecord().  If\n        sdRef is closed, the DNSRecordRef is also invalidated and may\n        not be used further.\n\n    \"\"\"\n\n    _NO_DEFAULT.check(rrtype)\n    _NO_DEFAULT.check(rdata)\n\n    rdlen, rdata = _string_to_length_and_void_p(rdata)\n\n    _global_lock.acquire()\n    try:\n        RecordRef = _DNSServiceAddRecord(sdRef,\n                                         flags,\n                                         rrtype,\n                                         rdlen,\n                                         rdata,\n                                         ttl)\n    finally:\n        _global_lock.release()\n\n    sdRef._add_record_ref(RecordRef)\n\n    return RecordRef\n\n\ndef DNSServiceUpdateRecord(\n    sdRef,\n    RecordRef = None,\n    flags = 0,\n    rdata = _NO_DEFAULT,\n    ttl = 0,\n    ):\n\n    \"\"\"\n\n    Update a registered resource record.  The record must either be:\n      - The primary txt record of a service registered via\n        DNSServiceRegister(), or\n      - A record added to a registered service via\n        DNSServiceAddRecord(), or\n      - An individual record registered by DNSServiceRegisterRecord()\n\n      sdRef:\n        A DNSServiceRef returned by DNSServiceRegister() or\n        DNSServiceCreateConnection().\n\n      RecordRef:\n        A DNSRecordRef returned by DNSServiceAddRecord(), or None to\n        update the service's primary txt record.\n\n      flags:\n        Currently ignored, reserved for future use.\n\n      rdata:\n        A string containing the new rdata to be contained in the\n        updated resource record.\n\n      ttl:\n        The time to live of the updated resource record, in seconds.\n\n    \"\"\"\n\n    _NO_DEFAULT.check(rdata)\n\n    rdlen, rdata = _string_to_length_and_void_p(rdata)\n\n    _global_lock.acquire()\n    try:\n        _DNSServiceUpdateRecord(sdRef,\n                                RecordRef,\n                                flags,\n                                rdlen,\n                                rdata,\n                                ttl)\n    finally:\n        _global_lock.release()\n\n\ndef DNSServiceRemoveRecord(\n    sdRef,\n    RecordRef,\n    flags = 0,\n    ):\n\n    \"\"\"\n\n    Remove a record previously added to a service record set via\n    DNSServiceAddRecord(), or deregister a record registered\n    individually via DNSServiceRegisterRecord().\n\n      sdRef:\n        A DNSServiceRef returned by DNSServiceRegister() (if the\n        record being removed was registered via DNSServiceAddRecord())\n        or by DNSServiceCreateConnection() (if the record being\n        removed was registered via DNSServiceRegisterRecord()).\n\n      recordRef:\n        A DNSRecordRef returned by DNSServiceAddRecord() or\n        DNSServiceRegisterRecord().\n\n      flags:\n        Currently ignored, reserved for future use.\n\n    \"\"\"\n\n    _global_lock.acquire()\n    try:\n        _DNSServiceRemoveRecord(sdRef,\n                                RecordRef,\n                                flags)\n    finally:\n        _global_lock.release()\n\n    RecordRef._invalidate()\n\n\ndef DNSServiceBrowse(\n    flags = 0,\n    interfaceIndex = kDNSServiceInterfaceIndexAny,\n    regtype = _NO_DEFAULT,\n    domain = None,\n    callBack = None,\n    ):\n\n    \"\"\"\n\n    Browse for instances of a service.\n\n      flags:\n        Currently ignored, reserved for future use.\n\n      interfaceIndex:\n        If non-zero, specifies the interface on which to browse for\n        services.  Most applications will pass\n        kDNSServiceInterfaceIndexAny (0) to browse on all available\n        interfaces.\n\n      regtype:\n        The service type being browsed for followed by the protocol,\n        separated by a dot (e.g. \"_ftp._tcp\").  The transport protocol\n        must be \"_tcp\" or \"_udp\".\n\n      domain:\n        If not None, specifies the domain on which to browse for\n        services.  Most applications will not specify a domain,\n        instead browsing on the default domain(s).\n\n      callBack:\n        The function to be called when an instance of the service\n        being browsed for is found, or if the call asynchronously\n        fails.  Its signature should be\n        callBack(sdRef, flags, interfaceIndex, errorCode,\n                 serviceName, regtype, replyDomain).\n\n      return value:\n        A DNSServiceRef instance.  The browse operation will run\n        indefinitely until the client terminates it by closing the\n        DNSServiceRef.\n\n    Callback Parameters:\n\n      sdRef:\n        The DNSServiceRef returned by DNSServiceBrowse().\n\n      flags:\n        Possible values are kDNSServiceFlagsMoreComing and\n        kDNSServiceFlagsAdd.\n\n      interfaceIndex:\n        The interface on which the service is advertised.  This index\n        should be passed to DNSServiceResolve() when resolving the\n        service.\n\n      errorCode:\n        Will be kDNSServiceErr_NoError (0) on success, otherwise will\n        indicate the failure that occurred.  Other parameters are\n        undefined if an error occurred.\n\n      serviceName:\n        The discovered service name.  This name should be displayed to\n        the user and stored for subsequent use in the\n        DNSServiceResolve() call.\n\n      regtype:\n        The service type, which is usually (but not always) the same\n        as was passed to DNSServiceBrowse().  One case where the\n        discovered service type may not be the same as the requested\n        service type is when using subtypes: The client may want to\n        browse for only those ftp servers that allow anonymous\n        connections.  The client will pass the string\n        \"_ftp._tcp,_anon\" to DNSServiceBrowse(), but the type of the\n        service that's discovered is simply \"_ftp._tcp\".  The regtype\n        for each discovered service instance should be stored along\n        with the name, so that it can be passed to DNSServiceResolve()\n        when the service is later resolved.\n\n      replyDomain:\n        The domain of the discovered service instance.  This may or\n        may not be the same as the domain that was passed to\n        DNSServiceBrowse().  The domain for each discovered service\n        instance should be stored along with the name, so that it can\n        be passed to DNSServiceResolve() when the service is later\n        resolved.\n\n    \"\"\"\n\n    _NO_DEFAULT.check(regtype)\n\n    @_DNSServiceBrowseReply\n    def _callback(sdRef, flags, interfaceIndex, errorCode, serviceName, regtype,\n                  replyDomain, context):\n        if callBack is not None:\n            callBack(sdRef, flags, interfaceIndex, errorCode,\n                     serviceName.decode(), regtype.decode(),\n                     replyDomain.decode())\n\n    _global_lock.acquire()\n    try:\n        sdRef = _DNSServiceBrowse(flags,\n                                  interfaceIndex,\n                                  regtype,\n                                  domain,\n                                  _callback,\n                                  None)\n    finally:\n        _global_lock.release()\n\n    sdRef._add_callback(_callback)\n\n    return sdRef\n\n\ndef DNSServiceResolve(\n    flags = 0,\n    interfaceIndex = _NO_DEFAULT,\n    name = _NO_DEFAULT,\n    regtype = _NO_DEFAULT,\n    domain = _NO_DEFAULT,\n    callBack = None,\n    ):\n\n    \"\"\"\n\n    Resolve a service name discovered via DNSServiceBrowse() to a\n    target host name, port number, and txt record.\n\n    Note: Applications should NOT use DNSServiceResolve() solely for\n    txt record monitoring; use DNSServiceQueryRecord() instead, as it\n    is more efficient for this task.\n\n    Note: When the desired results have been returned, the client MUST\n    terminate the resolve by closing the returned DNSServiceRef.\n\n    Note: DNSServiceResolve() behaves correctly for typical services\n    that have a single SRV record and a single TXT record.  To resolve\n    non-standard services with multiple SRV or TXT records,\n    DNSServiceQueryRecord() should be used.\n\n      flags:\n        Currently ignored, reserved for future use.\n\n      interfaceIndex:\n        The interface on which to resolve the service.  If this\n        resolve call is as a result of a currently active\n        DNSServiceBrowse() operation, then the interfaceIndex should\n        be the index reported in the browse callback.  If this resolve\n        call is using information previously saved (e.g. in a\n        preference file) for later use, then use\n        kDNSServiceInterfaceIndexAny (0), because the desired service\n        may now be reachable via a different physical interface.\n\n      name:\n        The name of the service instance to be resolved, as reported\n        to the DNSServiceBrowse() callback.\n\n      regtype:\n        The type of the service instance to be resolved, as reported\n        to the DNSServiceBrowse() callback.\n\n      domain:\n        The domain of the service instance to be resolved, as reported\n        to the DNSServiceBrowse() callback.\n\n      callBack:\n        The function to be called when a result is found, or if the\n        call asynchronously fails.  Its signature should be\n        callBack(sdRef, flags, interfaceIndex, errorCode, fullname,\n                 hosttarget, port, txtRecord).\n\n      return value:\n        A DNSServiceRef instance.  The resolve operation will run\n        indefinitely until the client terminates it by closing the\n        DNSServiceRef.\n\n    Callback Parameters:\n\n      sdRef:\n        The DNSServiceRef returned by DNSServiceResolve().\n\n      flags:\n        Currently unused, reserved for future use.\n\n      interfaceIndex:\n        The interface on which the service was resolved.\n\n      errorCode:\n        Will be kDNSServiceErr_NoError (0) on success, otherwise will\n        indicate the failure that occurred.  Other parameters are\n        undefined if an error occurred.\n\n      fullname:\n        The full service domain name, in the form\n        <servicename>.<protocol>.<domain>.\n\n      hosttarget:\n        The target hostname of the machine providing the service.\n\n      port:\n        The port, in host (not network) byte order, on which\n        connections are accepted for this service.\n\n      txtRecord:\n        A string containing the service's primary txt record, in\n        standard txt record format.\n\n    \"\"\"\n\n    _NO_DEFAULT.check(interfaceIndex)\n    _NO_DEFAULT.check(name)\n    _NO_DEFAULT.check(regtype)\n    _NO_DEFAULT.check(domain)\n\n    @_DNSServiceResolveReply\n    def _callback(sdRef, flags, interfaceIndex, errorCode, fullname, hosttarget,\n                  port, txtLen, txtRecord, context):\n        if callBack is not None:\n            port = socket.ntohs(port)\n            txtRecord = _length_and_void_p_to_string(txtLen, txtRecord)\n            callBack(sdRef, flags, interfaceIndex, errorCode, fullname.decode(),\n                     hosttarget.decode(), port, txtRecord)\n\n    _global_lock.acquire()\n    try:\n        sdRef = _DNSServiceResolve(flags,\n                                   interfaceIndex,\n                                   name,\n                                   regtype,\n                                   domain,\n                                   _callback,\n                                   None)\n    finally:\n        _global_lock.release()\n\n    sdRef._add_callback(_callback)\n\n    return sdRef\n\n\ndef DNSServiceCreateConnection():\n\n    \"\"\"\n\n    Create a connection to the daemon allowing efficient registration\n    of multiple individual records.\n\n      return value:\n        A DNSServiceRef instance.  Closing it severs the connection\n        and deregisters all records registered on this connection.\n\n    \"\"\"\n\n    _global_lock.acquire()\n    try:\n        sdRef = _DNSServiceCreateConnection()\n    finally:\n        _global_lock.release()\n\n    return sdRef\n\n\ndef DNSServiceRegisterRecord(\n    sdRef,\n    flags,\n    interfaceIndex = kDNSServiceInterfaceIndexAny,\n    fullname = _NO_DEFAULT,\n    rrtype = _NO_DEFAULT,\n    rrclass = kDNSServiceClass_IN,\n    rdata = _NO_DEFAULT,\n    ttl = 0,\n    callBack = None,\n    ):\n\n    \"\"\"\n\n    Register an individual resource record on a connected\n    DNSServiceRef.\n\n    Note that name conflicts occurring for records registered via this\n    call must be handled by the client in the callback.\n\n      sdRef:\n        A DNSServiceRef returned by DNSServiceCreateConnection().\n\n      flags:\n        Possible values are kDNSServiceFlagsShared or\n        kDNSServiceFlagsUnique.\n\n      interfaceIndex:\n        If non-zero, specifies the interface on which to register the\n        record.  Passing kDNSServiceInterfaceIndexAny (0) causes the\n        record to be registered on all interfaces.\n\n      fullname:\n        The full domain name of the resource record.\n\n      rrtype:\n        The numerical type of the resource record\n        (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc.).\n\n      rrclass:\n        The class of the resource record (usually\n        kDNSServiceClass_IN).\n\n      rdata:\n        A string containing the raw rdata, as it is to appear in the\n        DNS record.\n\n      ttl:\n        The time to live of the resource record, in seconds.  Pass 0\n        to use a default value.\n\n      callBack:\n        The function to be called when a result is found, or if the\n        call asynchronously fails (e.g. because of a name conflict).\n        Its signature should be\n        callBack(sdRef, RecordRef, flags, errorCode).\n\n      return value:\n        A DNSRecordRef instance, which may be passed to\n        DNSServiceUpdateRecord() or DNSServiceRemoveRecord().  (To\n        deregister ALL records registered on a single connected\n        DNSServiceRef and deallocate each of their corresponding\n        DNSRecordRefs, close the DNSServiceRef.)\n\n    Callback Parameters:\n\n      sdRef:\n        The connected DNSServiceRef returned by\n        DNSServiceCreateConnection().\n\n      RecordRef:\n        The DNSRecordRef returned by DNSServiceRegisterRecord().\n\n      flags:\n        Currently unused, reserved for future use.\n\n      errorCode:\n        Will be kDNSServiceErr_NoError on success, otherwise will\n        indicate the failure that occurred (including name conflicts).\n        Other parameters are undefined if an error occurred.\n\n    \"\"\"\n\n    _NO_DEFAULT.check(fullname)\n    _NO_DEFAULT.check(rrtype)\n    _NO_DEFAULT.check(rdata)\n\n    rdlen, rdata = _string_to_length_and_void_p(rdata)\n\n    @_DNSServiceRegisterRecordReply\n    def _callback(sdRef, RecordRef, flags, errorCode, context):\n        if callBack is not None:\n            callBack(sdRef, RecordRef, flags, errorCode)\n\n    _global_lock.acquire()\n    try:\n        RecordRef = _DNSServiceRegisterRecord(sdRef,\n                                              flags,\n                                              interfaceIndex,\n                                              fullname,\n                                              rrtype,\n                                              rrclass,\n                                              rdlen,\n                                              rdata,\n                                              ttl,\n                                              _callback,\n                                              None)\n    finally:\n        _global_lock.release()\n\n    sdRef._add_callback(_callback)\n    sdRef._add_record_ref(RecordRef)\n\n    return RecordRef\n\n\ndef DNSServiceQueryRecord(\n    flags = 0,\n    interfaceIndex = kDNSServiceInterfaceIndexAny,\n    fullname = _NO_DEFAULT,\n    rrtype = _NO_DEFAULT,\n    rrclass = kDNSServiceClass_IN,\n    callBack = None,\n    ):\n\n    \"\"\"\n\n    Query for an arbitrary DNS record.\n\n      flags:\n        Pass kDNSServiceFlagsLongLivedQuery to create a \"long-lived\"\n        unicast query in a non-local domain.  Without setting this\n        flag, unicast queries will be one-shot; that is, only answers\n        available at the time of the call will be returned.  By\n        setting this flag, answers (including Add and Remove events)\n        that become available after the initial call is made will\n        generate callbacks.  This flag has no effect on link-local\n        multicast queries.\n\n      interfaceIndex:\n        If non-zero, specifies the interface on which to issue the\n        query.  Passing kDNSServiceInterfaceIndexAny (0) causes the\n        name to be queried for on all interfaces.\n\n      fullname:\n        The full domain name of the resource record to be queried for.\n\n      rrtype:\n        The numerical type of the resource record to be queried for\n        (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc.).\n\n      rrclass:\n        The class of the resource record (usually\n        kDNSServiceClass_IN).\n\n      callBack:\n        The function to be called when a result is found, or if the\n        call asynchronously fails.  Its signature should be\n        callBack(sdRef, flags, interfaceIndex, errorCode, fullname,\n                 rrtype, rrclass, rdata, ttl).\n\n      return value:\n        A DNSServiceRef instance.  The query operation will run\n        indefinitely until the client terminates it by closing the\n        DNSServiceRef.\n\n    Callback Parameters:\n\n      sdRef:\n        The DNSServiceRef returned by DNSServiceQueryRecord().\n\n      flags:\n        Possible values are kDNSServiceFlagsMoreComing and\n        kDNSServiceFlagsAdd.  The Add flag is NOT set for PTR records\n        with a ttl of 0, i.e. \"Remove\" events.\n\n      interfaceIndex:\n        The interface on which the query was resolved.\n\n      errorCode:\n        Will be kDNSServiceErr_NoError on success, otherwise will\n        indicate the failure that occurred.  Other parameters are\n        undefined if an error occurred.\n\n      fullname:\n        The resource record's full domain name.\n\n      rrtype:\n        The resource record's type (e.g. kDNSServiceType_PTR,\n        kDNSServiceType_SRV, etc.).\n\n      rrclass:\n        The class of the resource record (usually\n        kDNSServiceClass_IN).\n\n      rdata:\n        A string containing the raw rdata of the resource record.\n\n      ttl:\n        The resource record's time to live, in seconds.\n\n    \"\"\"\n\n    _NO_DEFAULT.check(fullname)\n    _NO_DEFAULT.check(rrtype)\n\n    @_DNSServiceQueryRecordReply\n    def _callback(sdRef, flags, interfaceIndex, errorCode, fullname, rrtype,\n                  rrclass, rdlen, rdata, ttl, context):\n        if callBack is not None:\n            rdata = _length_and_void_p_to_string(rdlen, rdata)\n            callBack(sdRef, flags, interfaceIndex, errorCode, fullname.decode(),\n                     rrtype, rrclass, rdata, ttl)\n\n    _global_lock.acquire()\n    try:\n        sdRef = _DNSServiceQueryRecord(flags,\n                                       interfaceIndex,\n                                       fullname,\n                                       rrtype,\n                                       rrclass,\n                                       _callback,\n                                       None)\n    finally:\n        _global_lock.release()\n\n    sdRef._add_callback(_callback)\n\n    return sdRef\n\n\ndef DNSServiceReconfirmRecord(\n    flags = 0,\n    interfaceIndex = kDNSServiceInterfaceIndexAny,\n    fullname = _NO_DEFAULT,\n    rrtype = _NO_DEFAULT,\n    rrclass = kDNSServiceClass_IN,\n    rdata = _NO_DEFAULT,\n    ):\n\n    \"\"\"\n\n    Instruct the daemon to verify the validity of a resource record\n    that appears to be out of date (e.g. because tcp connection to a\n    service's target failed).  Causes the record to be flushed from\n    the daemon's cache (as well as all other daemons' caches on the\n    network) if the record is determined to be invalid.\n\n      flags:\n        Currently unused, reserved for future use.\n\n      interfaceIndex: \n        If non-zero, specifies the interface of the record in\n        question.  Passing kDNSServiceInterfaceIndexAny (0) causes all\n        instances of this record to be reconfirmed.\n\n      fullname:\n        The resource record's full domain name.\n\n      rrtype:\n        The resource record's type (e.g. kDNSServiceType_PTR,\n        kDNSServiceType_SRV, etc.).\n\n      rrclass:\n        The class of the resource record (usually\n        kDNSServiceClass_IN).\n\n      rdata:\n        A string containing the raw rdata of the resource record.\n\n    \"\"\"\n\n    _NO_DEFAULT.check(fullname)\n    _NO_DEFAULT.check(rrtype)\n    _NO_DEFAULT.check(rdata)\n\n    rdlen, rdata = _string_to_length_and_void_p(rdata)\n\n    _global_lock.acquire()\n    try:\n        _DNSServiceReconfirmRecord(flags,\n                                   interfaceIndex,\n                                   fullname,\n                                   rrtype,\n                                   rrclass,\n                                   rdlen,\n                                   rdata)\n    finally:\n        _global_lock.release()\n\n\ndef DNSServiceConstructFullName(\n    service = None,\n    regtype = _NO_DEFAULT, \n    domain = _NO_DEFAULT,\n    ):\n\n    \"\"\"\n\n    Concatenate a three-part domain name (as returned by a callback\n    function) into a properly-escaped full domain name.  Note that\n    callback functions already escape strings where necessary.\n\n      service:\n        The service name; any dots or backslashes must NOT be escaped.\n        May be None (to construct a PTR record name, e.g.\n        \"_ftp._tcp.apple.com.\").\n\n      regtype:\n        The service type followed by the protocol, separated by a dot\n        (e.g. \"_ftp._tcp\").\n\n      domain:\n        The domain name, e.g. \"apple.com.\".  Literal dots or\n        backslashes, if any, must be escaped,\n        e.g. \"1st\\. Floor.apple.com.\"\n\n      return value:\n        The resulting full domain name.\n\n    \"\"\"\n\n    _NO_DEFAULT.check(regtype)\n    _NO_DEFAULT.check(domain)\n\n    _global_lock.acquire()\n    try:\n        fullName = _DNSServiceConstructFullName(service, regtype, domain)\n    finally:\n        _global_lock.release()\n\n    return fullName.value.decode('utf-8')\n\n\n\n################################################################################\n#\n# TXTRecord class\n#\n################################################################################\n\n\n\nclass TXTRecord(object):\n\n    \"\"\"\n\n    A mapping representing a DNS TXT record.  The TXT record's\n    name=value entries are stored as key/value pairs in the mapping.\n    Although keys can be accessed in a case-insensitive fashion\n    (meaning txt['foo'] and txt['FoO'] refer to the same value), key\n    case is preserved in the wire representation of the record (so\n    txt['FoO'] = 'bar' will generate a FoO=bar entry in the TXT\n    record).  Key order is also preserved, so keys appear in the wire\n    format in the order in which they were created.\n\n    Note that in addition to being valid as a txtRecord parameter to\n    DNSServiceRegister(), a TXTRecord instance can be used in place of\n    a resource record data string (i.e. rdata parameter) with any\n    function that accepts one.\n\n    \"\"\"\n\n    def __init__(self, items={}, strict=True):\n        \"\"\"\n\n        Create a new TXTRecord instance, initializing it with the\n        contents of items.  If strict is true, then strict conformance\n        to the DNS TXT record format will be enforced, and attempts to\n        add a name containing invalid characters or a name/value pair\n        whose wire representation is longer than 255 bytes will raise\n        a ValueError exception.\n\n        \"\"\"\n\n        self.strict = strict\n        self._names = []\n        self._items = {}\n\n        for name, value in items.iteritems():\n            self[name] = value\n\n    def __contains__(self, name):\n        'Return True if name is a key in the record, False otherwise'\n        return (name.lower() in self._items)\n\n    def __iter__(self):\n        'Return an iterator over name/value pairs'\n        for name in self._names:\n            yield self._items[name]\n\n    def __len__(self):\n        'Return the number of name/value pairs'\n        return len(self._names)\n\n    def __nonzero__(self):\n        'Return False if the record is empty, True otherwise'\n        return bool(self._items)\n\n    def __str__(self):\n        \"\"\"\n\n        Return the wire representation of the TXT record as a string.\n        If self.strict is false, any name/value pair whose wire length\n        if greater than 255 bytes will be truncated to 255 bytes.  If\n        the record is empty, '\\\\0' is returned.\n\n        \"\"\"\n\n        if not self:\n            return '\\0'\n\n        parts = []\n        for name, value in self:\n            if value is None:\n                item = name\n            else:\n                item = '%s=%s' % (name, value)\n            if (not self.strict) and (len(item) > 255):\n                item = item[:255]\n            parts.append(chr(len(item)))\n            parts.append(item)\n\n        return ''.join(parts)\n\n    def __getitem__(self, name):\n        \"\"\"\n\n        Return the value associated with name.  The value is either\n        None (meaning name has no associated value) or an str instance\n        (which may be of length 0).  Raises KeyError if name is not a\n        key.\n\n        \"\"\"\n        return self._items[name.lower()][1]\n\n    # Require one or more printable ASCII characters (0x20-0x7E),\n    # excluding '=' (0x3D)\n    _valid_name_re = re.compile(r'^[ -<>-~]+$')\n\n    def __setitem__(self, name, value):\n        \"\"\"\n\n        Add a name/value pair to the record.  If value is None, then\n        name will have no associated value.  If value is a unicode\n        instance, it will be encoded as a UTF-8 string.  Otherwise,\n        value will be converted to an str instance.\n\n        \"\"\"\n\n        stored_name = name\n        name = name.lower()\n        length = len(name)\n\n        if value is not None:\n            if isinstance(value, unicode):\n                value = value.encode('utf-8')\n            else:\n                value = str(value)\n            length += 1 + len(value)\n\n        if self.strict and (length > 255):\n            raise ValueError('name=value string must be 255 bytes or less')\n\n        if name not in self._items:\n            if self.strict and (self._valid_name_re.match(stored_name) is None):\n                raise ValueError(\"invalid name: '%s'\" % stored_name)\n            self._names.append(name)\n\n        self._items[name] = (stored_name, value)\n\n    def __delitem__(self, name):\n        \"\"\"\n\n        Remove name and its corresponding value from the record.\n        Raises KeyError if name is not a key.\n\n        \"\"\"\n        name = name.lower()\n        del self._items[name]\n        self._names.remove(name)\n\n    def get(self, name, default=None):\n        return self._items.get(name.lower(), (name, default))[1]\n\n    @classmethod\n    def parse(cls, data, strict=False):\n        \"\"\"\n\n        Given a string data containing the wire representation of a\n        DNS TXT record, parse it and return a TXTRecord instance.  The\n        strict parameter is passed to the TXTRecord constructor.\n\n        \"\"\"\n\n        txt = cls(strict=strict)\n\n        while data:\n            length = ord(data[0])\n            item = data[1:length+1].split('=', 1)\n\n            # Add the item only if the name is non-empty and there are\n            # no existing items with the same name\n            if item[0] and (item[0] not in txt):\n                if len(item) == 1:\n                    txt[item[0]] = None\n                else:\n                    txt[item[0]] = item[1]\n\n            data = data[length+1:]\n\n        return txt\n"
  },
  {
    "path": "sipsimple/account/publication.py",
    "content": "\n\"\"\"Implements the publisher handlers\"\"\"\n\n__all__ = ['Publisher', 'PresencePublisher', 'DialogPublisher']\n\nimport random\n\nfrom abc import ABCMeta, abstractproperty\nfrom threading import Lock\nfrom time import time\n\nfrom application.notification import IObserver, NotificationCenter, NotificationData\nfrom application.python import Null, limit\nfrom application.python.types import MarkerType\nfrom eventlib import coros, proc\nfrom twisted.internet import reactor\nfrom zope.interface import implements\n\nfrom sipsimple.core import FromHeader, Publication, PublicationETagError, RouteHeader, SIPURI, SIPCoreError\nfrom sipsimple.configuration.settings import SIPSimpleSettings\nfrom sipsimple.lookup import DNSLookup, DNSLookupError\nfrom sipsimple.payloads.dialoginfo import DialogInfoDocument\nfrom sipsimple.payloads.pidf import PIDFDocument\nfrom sipsimple.threading import run_in_twisted_thread\nfrom sipsimple.threading.green import Command, run_in_green_thread\n\n\n\nCommand.register_defaults('publish', refresh_interval=None)\n\n\nclass SameState: __metaclass__ = MarkerType\n\n\nclass SIPPublicationDidFail(Exception):\n    def __init__(self, data):\n        self.data = data\n\n\nclass SIPPublicationDidNotEnd(Exception):\n    def __init__(self, data):\n        self.data = data\n\n\nclass PublicationError(Exception):\n    def __init__(self, error, retry_after, refresh_interval=None):\n        self.error = error\n        self.retry_after = retry_after\n        self.refresh_interval = refresh_interval\n\n\nclass PublisherNickname(dict):\n    def __missing__(self, name):\n        return self.setdefault(name, name[:-9] if name.endswith('Publisher') else name)\n    def __get__(self, obj, objtype):\n        return self[objtype.__name__]\n    def __set__(self, obj, value):\n        raise AttributeError('cannot set attribute')\n    def __delete__(self, obj):\n        raise AttributeError('cannot delete attribute')\n\n\nclass Publisher(object):\n    __metaclass__ = ABCMeta\n    __nickname__  = PublisherNickname()\n    __transports__ = frozenset(['tls', 'tcp', 'udp'])\n\n    implements(IObserver)\n\n    def __init__(self, account):\n        self.account = account\n        self.started = False\n        self.active = False\n        self.publishing = False\n        self._lock = Lock()\n        self._command_proc = None\n        self._command_channel = coros.queue()\n        self._data_channel = coros.queue()\n        self._publication = None\n        self._dns_wait = 1\n        self._publish_wait = 1\n        self._publication_timer = None\n        self.__dict__['state'] = None\n\n    @abstractproperty\n    def event(self):\n        return None\n\n    @abstractproperty\n    def payload_type(self):\n        return None\n\n    @property\n    def extra_headers(self):\n        return []\n\n    @property\n    def state(self):\n        return self.__dict__['state']\n\n    @state.setter\n    def state(self, state):\n        if state is not None and not isinstance(state, self.payload_type.root_element):\n            raise ValueError(\"state must be a %s document or None\" % self.payload_type.root_element.__name__)\n        with self._lock:\n            old_state = self.__dict__['state']\n            self.__dict__['state'] = state\n            if state == old_state:\n                return\n            self._publish(state)\n\n    def start(self):\n        if self.started:\n            return\n        self.started = True\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, sender=self)\n        notification_center.post_notification(self.__class__.__name__ + 'WillStart', sender=self)\n        notification_center.add_observer(self, name='CFGSettingsObjectDidChange', sender=self.account)\n        notification_center.add_observer(self, name='CFGSettingsObjectDidChange', sender=SIPSimpleSettings())\n        notification_center.add_observer(self, name='NetworkConditionsDidChange')\n        self._command_proc = proc.spawn(self._run)\n        notification_center.post_notification(self.__class__.__name__ + 'DidStart', sender=self)\n        notification_center.remove_observer(self, sender=self)\n\n    def stop(self):\n        if not self.started:\n            return\n        self.started = False\n        self.active = False\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, sender=self)\n        notification_center.post_notification(self.__class__.__name__ + 'WillEnd', sender=self)\n        notification_center.remove_observer(self, name='CFGSettingsObjectDidChange', sender=self.account)\n        notification_center.remove_observer(self, name='CFGSettingsObjectDidChange', sender=SIPSimpleSettings())\n        notification_center.remove_observer(self, name='NetworkConditionsDidChange')\n        command = Command('terminate')\n        self._command_channel.send(command)\n        command.wait()\n        self._command_proc = None\n        notification_center.post_notification(self.__class__.__name__ + 'DidDeactivate', sender=self)\n        notification_center.post_notification(self.__class__.__name__ + 'DidEnd', sender=self)\n        notification_center.remove_observer(self, sender=self)\n\n    def activate(self):\n        if not self.started:\n            raise RuntimeError(\"not started\")\n        self.active = True\n        self._command_channel.send(Command('publish', state=self.state))\n        notification_center = NotificationCenter()\n        notification_center.post_notification(self.__class__.__name__ + 'DidActivate', sender=self)\n\n    def deactivate(self):\n        if not self.started:\n            raise RuntimeError(\"not started\")\n        self.active = False\n        self._command_channel.send(Command('unpublish'))\n        notification_center = NotificationCenter()\n        notification_center.post_notification(self.__class__.__name__ + 'DidDeactivate', sender=self)\n\n    @run_in_twisted_thread\n    def _publish(self, state):\n        if not self.active:\n            return\n        if state is None:\n            self._command_channel.send(Command('unpublish'))\n        else:\n            self._command_channel.send(Command('publish', state=state))\n\n    def _run(self):\n        while True:\n            command = self._command_channel.wait()\n            handler = getattr(self, '_CH_%s' % command.name)\n            handler(command)\n\n    def _CH_publish(self, command):\n        if command.state is None or self._publication is None and command.state is SameState:\n            command.signal()\n            return\n\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n\n        if self._publication_timer is not None and self._publication_timer.active():\n            self._publication_timer.cancel()\n        self._publication_timer = None\n\n        if self._publication is None:\n            duration = command.refresh_interval or self.account.sip.publish_interval\n            from_header = FromHeader(self.account.uri, self.account.display_name)\n            self._publication = Publication(from_header, self.event, self.payload_type.content_type, credentials=self.account.credentials, duration=duration, extra_headers=self.extra_headers)\n            notification_center.add_observer(self, sender=self._publication)\n            notification_center.post_notification(self.__class__.__name__ + 'WillPublish', sender=self, data=NotificationData(state=command.state, duration=duration))\n        else:\n            notification_center.post_notification(self.__class__.__name__ + 'WillRefresh', sender=self, data=NotificationData(state=command.state))\n\n        try:\n            # Lookup routes\n            valid_transports = self.__transports__.intersection(settings.sip.transport_list)\n            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in valid_transports:\n                uri = SIPURI(host=self.account.sip.outbound_proxy.host, port=self.account.sip.outbound_proxy.port, parameters={'transport': self.account.sip.outbound_proxy.transport})\n            else:\n                uri = SIPURI(host=self.account.id.domain)\n            lookup = DNSLookup()\n            try:\n                routes = lookup.lookup_sip_proxy(uri, valid_transports).wait()\n            except DNSLookupError, e:\n                retry_after = random.uniform(self._dns_wait, 2*self._dns_wait)\n                self._dns_wait = limit(2*self._dns_wait, max=30)\n                raise PublicationError('DNS lookup failed: %s' % e, retry_after=retry_after)\n            else:\n                self._dns_wait = 1\n\n            body = None if command.state is SameState else command.state.toxml()\n\n            # Publish by trying each route in turn\n            publish_timeout = time() + 30\n            for route in routes:\n                remaining_time = publish_timeout-time()\n                if remaining_time > 0:\n                    try:\n                        try:\n                            self._publication.publish(body, RouteHeader(route.uri), timeout=limit(remaining_time, min=1, max=10))\n                        except ValueError as e:  # this happens for an initial PUBLISH with body=None\n                            raise PublicationError(str(e), retry_after=0)\n                        except PublicationETagError:\n                            state = self.state # access self.state only once to avoid race conditions\n                            if state is not None:\n                                self._publication.publish(state.toxml(), RouteHeader(route.uri), timeout=limit(remaining_time, min=1, max=10))\n                            else:\n                                command.signal()\n                                return\n                    except SIPCoreError:\n                        raise PublicationError('Internal error', retry_after=5)\n\n                    try:\n                        while True:\n                            notification = self._data_channel.wait()\n                            if notification.name == 'SIPPublicationDidSucceed':\n                                break\n                            if notification.name == 'SIPPublicationDidEnd':\n                                raise PublicationError('Publication expired', retry_after=0)  # publication expired while we were trying to re-publish\n                    except SIPPublicationDidFail, e:\n                        if e.data.code == 407:\n                            # Authentication failed, so retry the publication in some time\n                            raise PublicationError('Authentication failed', retry_after=random.uniform(60, 120))\n                        elif e.data.code == 412:\n                            raise PublicationError('Conditional request failed', retry_after=0)\n                        elif e.data.code == 423:\n                            # Get the value of the Min-Expires header\n                            if e.data.min_expires is not None and e.data.min_expires > self.account.sip.publish_interval:\n                                refresh_interval = e.data.min_expires\n                            else:\n                                refresh_interval = None\n                            raise PublicationError('Interval too short', retry_after=random.uniform(60, 120), refresh_interval=refresh_interval)\n                        elif e.data.code in (405, 406, 489):\n                            raise PublicationError('Method or event not supported', retry_after=3600)\n                        else:\n                            # Otherwise just try the next route\n                            continue\n                    else:\n                        self.publishing = True\n                        self._publish_wait = 1\n                        command.signal()\n                        break\n            else:\n                # There are no more routes to try, reschedule the publication\n                retry_after = random.uniform(self._publish_wait, 2*self._publish_wait)\n                self._publish_wait = limit(self._publish_wait*2, max=30)\n                raise PublicationError('No more routes to try', retry_after=retry_after)\n        except PublicationError, e:\n            self.publishing = False\n            notification_center.remove_observer(self, sender=self._publication)\n            def publish():\n                if self.active:\n                    self._command_channel.send(Command('publish', event=command.event, state=self.state, refresh_interval=e.refresh_interval))\n                else:\n                    command.signal()\n                self._publication_timer = None\n            self._publication_timer = reactor.callLater(e.retry_after, publish)\n            self._publication = None\n            notification_center.post_notification(self.__nickname__ + 'PublicationDidFail', sender=self, data=NotificationData(reason=e.error))\n        else:\n            notification_center.post_notification(self.__nickname__ + 'PublicationDidSucceed', sender=self)\n\n    def _CH_unpublish(self, command):\n        # Cancel any timer which would restart the publication process\n        if self._publication_timer is not None and self._publication_timer.active():\n            self._publication_timer.cancel()\n        self._publication_timer = None\n        publishing = self.publishing\n        self.publishing = False\n        if self._publication is not None:\n            notification_center = NotificationCenter()\n            if publishing:\n                self._publication.end(timeout=2)\n                try:\n                    while True:\n                        notification = self._data_channel.wait()\n                        if notification.name == 'SIPPublicationDidEnd':\n                            break\n                except (SIPPublicationDidFail, SIPPublicationDidNotEnd):\n                    notification_center.post_notification(self.__nickname__ + 'PublicationDidNotEnd', sender=self)\n                else:\n                    notification_center.post_notification(self.__nickname__ + 'PublicationDidEnd', sender=self)\n            notification_center.remove_observer(self, sender=self._publication)\n            self._publication = None\n        command.signal()\n\n    def _CH_terminate(self, command):\n        self._CH_unpublish(command)\n        raise proc.ProcExit\n\n    @run_in_twisted_thread\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_SIPPublicationDidSucceed(self, notification):\n        if notification.sender is self._publication:\n            self._data_channel.send(notification)\n\n    def _NH_SIPPublicationDidFail(self, notification):\n        if notification.sender is self._publication:\n            self._data_channel.send_exception(SIPPublicationDidFail(notification.data))\n\n    def _NH_SIPPublicationDidEnd(self, notification):\n        if notification.sender is self._publication:\n            self._data_channel.send(notification)\n\n    def _NH_SIPPublicationDidNotEnd(self, notification):\n        if notification.sender is self._publication:\n            self._data_channel.send_exception(SIPPublicationDidNotEnd(notification.data))\n\n    def _NH_SIPPublicationWillExpire(self, notification):\n        if notification.sender is self._publication:\n            self._publish(SameState)\n\n    @run_in_green_thread\n    def _NH_CFGSettingsObjectDidChange(self, notification):\n        if not self.started:\n            return\n        if 'enabled' in notification.data.modified:\n            return # global account activation is handled separately by the account itself\n        elif 'presence.enabled' in notification.data.modified:\n            if self.account.presence.enabled:\n                self.activate()\n            else:\n                self.deactivate()\n        elif self.active and {'__id__', 'auth.password', 'auth.username', 'sip.outbound_proxy', 'sip.transport_list', 'sip.publish_interval'}.intersection(notification.data.modified):\n            self._command_channel.send(Command('unpublish'))\n            self._command_channel.send(Command('publish', state=self.state))\n\n    def _NH_NetworkConditionsDidChange(self, notification):\n        if self.active:\n            self._command_channel.send(Command('unpublish'))\n            self._command_channel.send(Command('publish', state=self.state))\n\n\nclass PresencePublisher(Publisher):\n    \"\"\"A publisher for presence state\"\"\"\n\n    @property\n    def event(self):\n        return 'presence'\n\n    @property\n    def payload_type(self):\n        return PIDFDocument\n\n    def _NH_PresencePublisherDidStart(self, notification):\n        if self.account.presence.enabled:\n            self.activate()\n\n\nclass DialogPublisher(Publisher):\n    \"\"\"A publisher for dialog info state\"\"\"\n\n    @property\n    def event(self):\n        return 'dialog'\n\n    @property\n    def payload_type(self):\n        return DialogInfoDocument\n\n    def _NH_DialogPublisherDidStart(self, notification):\n        if self.account.presence.enabled:\n            self.activate()\n\n\n"
  },
  {
    "path": "sipsimple/account/registration.py",
    "content": "\n\"\"\"Implements the registration handler\"\"\"\n\n__all__ = ['Registrar']\n\nimport random\n\nfrom time import time\n\nfrom application.notification import IObserver, NotificationCenter, NotificationData\nfrom application.python import Null, limit\nfrom eventlib import coros, proc\nfrom twisted.internet import reactor\nfrom zope.interface import implements\n\nfrom sipsimple.core import ContactHeader, FromHeader, Header, Registration, RouteHeader, SIPURI, SIPCoreError, NoGRUU\nfrom sipsimple.configuration.settings import SIPSimpleSettings\nfrom sipsimple.lookup import DNSLookup, DNSLookupError\nfrom sipsimple.threading import run_in_twisted_thread\nfrom sipsimple.threading.green import Command, run_in_green_thread\n\n\n\nCommand.register_defaults('register', refresh_interval=None)\n\n\nclass SIPRegistrationDidFail(Exception):\n    def __init__(self, data):\n        self.data = data\n\nclass SIPRegistrationDidNotEnd(Exception):\n    def __init__(self, data):\n        self.data = data\n\nclass RegistrationError(Exception):\n    def __init__(self, error, retry_after, refresh_interval=None):\n        self.error = error\n        self.retry_after = retry_after\n        self.refresh_interval = refresh_interval\n\n\nclass Registrar(object):\n    implements(IObserver)\n\n    def __init__(self, account):\n        self.account = account\n        self.started = False\n        self.active = False\n        self.registered = False\n        self._command_proc = None\n        self._command_channel = coros.queue()\n        self._data_channel = coros.queue()\n        self._registration = None\n        self._dns_wait = 1\n        self._register_wait = 1\n        self._registration_timer = None\n\n    def start(self):\n        if self.started:\n            return\n        self.started = True\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, name='CFGSettingsObjectDidChange', sender=self.account)\n        notification_center.add_observer(self, name='CFGSettingsObjectDidChange', sender=SIPSimpleSettings())\n        notification_center.add_observer(self, name='NetworkConditionsDidChange')\n        self._command_proc = proc.spawn(self._run)\n        if self.account.sip.register:\n            self.activate()\n\n    def stop(self):\n        if not self.started:\n            return\n        self.started = False\n        self.active = False\n        notification_center = NotificationCenter()\n        notification_center.remove_observer(self, name='CFGSettingsObjectDidChange', sender=self.account)\n        notification_center.remove_observer(self, name='CFGSettingsObjectDidChange', sender=SIPSimpleSettings())\n        notification_center.remove_observer(self, name='NetworkConditionsDidChange')\n        command = Command('terminate')\n        self._command_channel.send(command)\n        command.wait()\n        self._command_proc = None\n\n    def activate(self):\n        if not self.started:\n            raise RuntimeError(\"not started\")\n        self.active = True\n        self._command_channel.send(Command('register'))\n\n    def deactivate(self):\n        if not self.started:\n            raise RuntimeError(\"not started\")\n        self.active = False\n        self._command_channel.send(Command('unregister'))\n\n    def reregister(self):\n        if self.active:\n            self._command_channel.send(Command('unregister'))\n            self._command_channel.send(Command('register'))\n\n    def _run(self):\n        while True:\n            command = self._command_channel.wait()\n            handler = getattr(self, '_CH_%s' % command.name)\n            handler(command)\n\n    def _CH_register(self, command):\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n\n        if self._registration_timer is not None and self._registration_timer.active():\n            self._registration_timer.cancel()\n        self._registration_timer = None\n\n        # Initialize the registration\n        if self._registration is None:\n            duration = command.refresh_interval or self.account.sip.register_interval\n            self._registration = Registration(FromHeader(self.account.uri, self.account.display_name), credentials=self.account.credentials, duration=duration, extra_headers=[Header('Supported', 'gruu')])\n            notification_center.add_observer(self, sender=self._registration)\n            notification_center.post_notification('SIPAccountWillRegister', sender=self.account)\n        else:\n            notification_center.post_notification('SIPAccountRegistrationWillRefresh', sender=self.account)\n\n        try:\n            # Lookup routes\n            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in settings.sip.transport_list:\n                uri = SIPURI(host=self.account.sip.outbound_proxy.host, port=self.account.sip.outbound_proxy.port, parameters={'transport': self.account.sip.outbound_proxy.transport})\n            else:\n                uri = SIPURI(host=self.account.id.domain)\n            lookup = DNSLookup()\n            try:\n                routes = lookup.lookup_sip_proxy(uri, settings.sip.transport_list).wait()\n            except DNSLookupError, e:\n                retry_after = random.uniform(self._dns_wait, 2*self._dns_wait)\n                self._dns_wait = limit(2*self._dns_wait, max=30)\n                raise RegistrationError('DNS lookup failed: %s' % e, retry_after=retry_after)\n            else:\n                self._dns_wait = 1\n\n            # Register by trying each route in turn\n            register_timeout = time() + 30\n            for route in routes:\n                remaining_time = register_timeout-time()\n                if remaining_time > 0:\n                    try:\n                        contact_uri = self.account.contact[NoGRUU, route]\n                    except KeyError:\n                        continue\n                    contact_header = ContactHeader(contact_uri)\n                    contact_header.parameters['+sip.instance'] = '\"<%s>\"' % settings.instance_id\n                    if self.account.nat_traversal.use_ice:\n                        contact_header.parameters['+sip.ice'] = None\n                    route_header = RouteHeader(route.uri)\n                    try:\n                        self._registration.register(contact_header, route_header, timeout=limit(remaining_time, min=1, max=10))\n                    except SIPCoreError:\n                        raise RegistrationError('Internal error', retry_after=5)\n                    try:\n                        while True:\n                            notification = self._data_channel.wait()\n                            if notification.name == 'SIPRegistrationDidSucceed':\n                                break\n                            if notification.name == 'SIPRegistrationDidEnd':\n                                raise RegistrationError('Registration expired', retry_after=0)  # registration expired while we were trying to re-register\n                    except SIPRegistrationDidFail, e:\n                        notification_data = NotificationData(code=e.data.code, reason=e.data.reason, registration=self._registration, registrar=route)\n                        notification_center.post_notification('SIPAccountRegistrationGotAnswer', sender=self.account, data=notification_data)\n                        if e.data.code == 401:\n                            # Authentication failed, so retry the registration in some time\n                            raise RegistrationError('Authentication failed', retry_after=random.uniform(60, 120))\n                        elif e.data.code == 423:\n                            # Get the value of the Min-Expires header\n                            if e.data.min_expires is not None and e.data.min_expires > self.account.sip.register_interval:\n                                refresh_interval = e.data.min_expires\n                            else:\n                                refresh_interval = None\n                            raise RegistrationError('Interval too short', retry_after=random.uniform(60, 120), refresh_interval=refresh_interval)\n                        else:\n                            # Otherwise just try the next route\n                            continue\n                    else:\n                        notification_data = NotificationData(code=notification.data.code, reason=notification.data.reason, registration=self._registration, registrar=route)\n                        notification_center.post_notification('SIPAccountRegistrationGotAnswer', sender=self.account, data=notification_data)\n                        self.registered = True\n                        # Save GRUU\n                        try:\n                            header = next(header for header in notification.data.contact_header_list if header.parameters.get('+sip.instance', '').strip('\"<>') == settings.instance_id)\n                        except StopIteration:\n                            self.account.contact.public_gruu = None\n                            self.account.contact.temporary_gruu = None\n                        else:\n                            public_gruu = header.parameters.get('pub-gruu', None)\n                            temporary_gruu = header.parameters.get('temp-gruu', None)\n                            try:\n                                self.account.contact.public_gruu = SIPURI.parse(public_gruu.strip('\"'))\n                            except (AttributeError, SIPCoreError):\n                                self.account.contact.public_gruu = None\n                            try:\n                                self.account.contact.temporary_gruu = SIPURI.parse(temporary_gruu.strip('\"'))\n                            except (AttributeError, SIPCoreError):\n                                self.account.contact.temporary_gruu = None\n                        notification_data = NotificationData(contact_header=notification.data.contact_header,\n                                                             contact_header_list=notification.data.contact_header_list,\n                                                             expires=notification.data.expires_in, registrar=route)\n                        notification_center.post_notification('SIPAccountRegistrationDidSucceed', sender=self.account, data=notification_data)\n                        self._register_wait = 1\n                        command.signal()\n                        break\n            else:\n                # There are no more routes to try, reschedule the registration\n                retry_after = random.uniform(self._register_wait, 2*self._register_wait)\n                self._register_wait = limit(self._register_wait*2, max=30)\n                raise RegistrationError('No more routes to try', retry_after=retry_after)\n        except RegistrationError, e:\n            self.registered = False\n            notification_center.remove_observer(self, sender=self._registration)\n            notification_center.post_notification('SIPAccountRegistrationDidFail', sender=self.account, data=NotificationData(error=e.error, retry_after=e.retry_after))\n            def register():\n                if self.active:\n                    self._command_channel.send(Command('register', command.event, refresh_interval=e.refresh_interval))\n                self._registration_timer = None\n            self._registration_timer = reactor.callLater(e.retry_after, register)\n            self._registration = None\n            self.account.contact.public_gruu = None\n            self.account.contact.temporary_gruu = None\n\n    def _CH_unregister(self, command):\n        # Cancel any timer which would restart the registration process\n        if self._registration_timer is not None and self._registration_timer.active():\n            self._registration_timer.cancel()\n        self._registration_timer = None\n        registered = self.registered\n        self.registered = False\n        if self._registration is not None:\n            notification_center = NotificationCenter()\n            if registered:\n                self._registration.end(timeout=2)\n                try:\n                    while True:\n                        notification = self._data_channel.wait()\n                        if notification.name == 'SIPRegistrationDidEnd':\n                            break\n                except (SIPRegistrationDidFail, SIPRegistrationDidNotEnd), e:\n                    notification_center.post_notification('SIPAccountRegistrationDidNotEnd', sender=self.account, data=NotificationData(code=e.data.code, reason=e.data.reason,\n                                                                                                                                        registration=self._registration))\n                else:\n                    notification_center.post_notification('SIPAccountRegistrationDidEnd', sender=self.account, data=NotificationData(registration=self._registration))\n            notification_center.remove_observer(self, sender=self._registration)\n            self._registration = None\n            self.account.contact.public_gruu = None\n            self.account.contact.temporary_gruu = None\n        command.signal()\n\n    def _CH_terminate(self, command):\n        self._CH_unregister(command)\n        raise proc.ProcExit\n\n    @run_in_twisted_thread\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_SIPRegistrationDidSucceed(self, notification):\n        if notification.sender is self._registration:\n            self._data_channel.send(notification)\n\n    def _NH_SIPRegistrationDidFail(self, notification):\n        if notification.sender is self._registration:\n            self._data_channel.send_exception(SIPRegistrationDidFail(notification.data))\n\n    def _NH_SIPRegistrationDidEnd(self, notification):\n        if notification.sender is self._registration:\n            self._data_channel.send(notification)\n\n    def _NH_SIPRegistrationDidNotEnd(self, notification):\n        if notification.sender is self._registration:\n            self._data_channel.send_exception(SIPRegistrationDidNotEnd(notification.data))\n\n    def _NH_SIPRegistrationWillExpire(self, notification):\n        if self.active:\n            self._command_channel.send(Command('register'))\n\n    @run_in_green_thread\n    def _NH_CFGSettingsObjectDidChange(self, notification):\n        if not self.started:\n            return\n        if 'enabled' in notification.data.modified:\n            return # global account activation is handled separately by the account itself\n        elif 'sip.register' in notification.data.modified:\n            if self.account.sip.register:\n                self.activate()\n            else:\n                self.deactivate()\n        elif self.active and {'__id__', 'auth.password', 'auth.username', 'nat_traversal.use_ice', 'sip.outbound_proxy', 'sip.transport_list', 'sip.register_interval'}.intersection(notification.data.modified):\n            self._command_channel.send(Command('unregister'))\n            self._command_channel.send(Command('register'))\n\n    def _NH_NetworkConditionsDidChange(self, notification):\n        if self.active:\n            self._command_channel.send(Command('unregister'))\n            self._command_channel.send(Command('register'))\n\n"
  },
  {
    "path": "sipsimple/account/subscription.py",
    "content": "\n\"\"\"Implements the subscription handlers\"\"\"\n\n__all__ = ['Subscriber', 'MWISubscriber', 'PresenceWinfoSubscriber', 'DialogWinfoSubscriber', 'PresenceSubscriber', 'SelfPresenceSubscriber', 'DialogSubscriber']\n\nimport random\n\nfrom abc import ABCMeta, abstractproperty\nfrom time import time\n\nfrom application.notification import IObserver, NotificationCenter, NotificationData\nfrom application.python import Null, limit\nfrom eventlib import coros, proc\nfrom twisted.internet import reactor\nfrom zope.interface import implements\n\nfrom sipsimple.core import ContactHeader, FromHeader, Header, RouteHeader, SIPURI, Subscription, ToHeader, SIPCoreError, NoGRUU\nfrom sipsimple.configuration.settings import SIPSimpleSettings\nfrom sipsimple.lookup import DNSLookup, DNSLookupError\nfrom sipsimple.threading import run_in_twisted_thread\nfrom sipsimple.threading.green import Command, run_in_green_thread\n\n\n\nCommand.register_defaults('subscribe', refresh_interval=None)\n\n\nclass SIPSubscriptionDidFail(Exception):\n    def __init__(self, data):\n        self.data = data\n\nclass SubscriptionError(Exception):\n    def __init__(self, error, retry_after, refresh_interval=None):\n        self.error = error\n        self.retry_after = retry_after\n        self.refresh_interval = refresh_interval\n\nclass InterruptSubscription(Exception): pass\nclass TerminateSubscription(Exception): pass\n\n\nclass Content(object):\n    def __init__(self, body, type):\n        self.body = body\n        self.type = type\n\n\nclass SubscriberNickname(dict):\n    def __missing__(self, name):\n        return self.setdefault(name, name[:-10] if name.endswith('Subscriber') else name)\n    def __get__(self, obj, objtype):\n        return self[objtype.__name__]\n    def __set__(self, obj, value):\n        raise AttributeError('cannot set attribute')\n    def __delete__(self, obj):\n        raise AttributeError('cannot delete attribute')\n\n\nclass Subscriber(object):\n    __metaclass__  = ABCMeta\n    __nickname__   = SubscriberNickname()\n    __transports__ = frozenset(['tls', 'tcp', 'udp'])\n\n    implements(IObserver)\n\n    def __init__(self, account):\n        self.account = account\n        self.started = False\n        self.active = False\n        self.subscribed = False\n        self._command_proc = None\n        self._command_channel = coros.queue()\n        self._data_channel = coros.queue()\n        self._subscription = None\n        self._subscription_proc = None\n        self._subscription_timer = None\n\n    @abstractproperty\n    def event(self):\n        return None\n\n    @property\n    def subscription_uri(self):\n        return self.account.id\n\n    @property\n    def content(self):\n        return Content(None, None)\n\n    @property\n    def extra_headers(self):\n        return []\n\n    def start(self):\n        if self.started:\n            return\n        self.started = True\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, sender=self)\n        notification_center.post_notification(self.__class__.__name__ + 'WillStart', sender=self)\n        notification_center.add_observer(self, name='NetworkConditionsDidChange')\n        self._command_proc = proc.spawn(self._run)\n        notification_center.post_notification(self.__class__.__name__ + 'DidStart', sender=self)\n        notification_center.remove_observer(self, sender=self)\n\n    def stop(self):\n        if not self.started:\n            return\n        self.started = False\n        self.active = False\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, sender=self)\n        notification_center.post_notification(self.__class__.__name__ + 'WillEnd', sender=self)\n        notification_center.remove_observer(self, name='NetworkConditionsDidChange')\n        command = Command('terminate')\n        self._command_channel.send(command)\n        command.wait()\n        self._command_proc = None\n        notification_center.post_notification(self.__class__.__name__ + 'DidDeactivate', sender=self)\n        notification_center.post_notification(self.__class__.__name__ + 'DidEnd', sender=self)\n        notification_center.remove_observer(self, sender=self)\n\n    def activate(self):\n        if not self.started:\n            raise RuntimeError(\"not started\")\n        self.active = True\n        self._command_channel.send(Command('subscribe'))\n        notification_center = NotificationCenter()\n        notification_center.post_notification(self.__class__.__name__ + 'DidActivate', sender=self)\n\n    def deactivate(self):\n        if not self.started:\n            raise RuntimeError(\"not started\")\n        self.active = False\n        self._command_channel.send(Command('unsubscribe'))\n        notification_center = NotificationCenter()\n        notification_center.post_notification(self.__class__.__name__ + 'DidDeactivate', sender=self)\n\n    def resubscribe(self):\n        if self.active:\n            self._command_channel.send(Command('subscribe'))\n\n    def _run(self):\n        while True:\n            command = self._command_channel.wait()\n            handler = getattr(self, '_CH_%s' % command.name)\n            handler(command)\n\n    def _CH_subscribe(self, command):\n        if self._subscription_timer is not None and self._subscription_timer.active():\n            self._subscription_timer.cancel()\n        self._subscription_timer = None\n        if self._subscription_proc is not None:\n            subscription_proc = self._subscription_proc\n            subscription_proc.kill(InterruptSubscription)\n            subscription_proc.wait()\n        self._subscription_proc = proc.spawn(self._subscription_handler, command)\n\n    def _CH_unsubscribe(self, command):\n        # Cancel any timer which would restart the subscription process\n        if self._subscription_timer is not None and self._subscription_timer.active():\n            self._subscription_timer.cancel()\n        self._subscription_timer = None\n        if self._subscription_proc is not None:\n            subscription_proc = self._subscription_proc\n            subscription_proc.kill(TerminateSubscription)\n            subscription_proc.wait()\n            self._subscription_proc = None\n        command.signal()\n\n    def _CH_terminate(self, command):\n        self._CH_unsubscribe(command)\n        raise proc.ProcExit\n\n    def _subscription_handler(self, command):\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n\n        subscription_uri = self.subscription_uri\n        refresh_interval = command.refresh_interval or self.account.sip.subscribe_interval\n        valid_transports = self.__transports__.intersection(settings.sip.transport_list)\n\n        try:\n            # Lookup routes\n            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in valid_transports:\n                uri = SIPURI(host=self.account.sip.outbound_proxy.host, port=self.account.sip.outbound_proxy.port, parameters={'transport': self.account.sip.outbound_proxy.transport})\n            elif self.account.sip.always_use_my_proxy:\n                uri = SIPURI(host=self.account.id.domain)\n            else:\n                uri = SIPURI(host=subscription_uri.domain)\n            lookup = DNSLookup()\n            try:\n                routes = lookup.lookup_sip_proxy(uri, valid_transports).wait()\n            except DNSLookupError, e:\n                raise SubscriptionError('DNS lookup failed: %s' % e, retry_after=random.uniform(15, 30))\n\n            subscription_uri = SIPURI(user=subscription_uri.username, host=subscription_uri.domain)\n            content = self.content\n\n            timeout = time() + 30\n            for route in routes:\n                remaining_time = timeout - time()\n                if remaining_time > 0:\n                    try:\n                        contact_uri = self.account.contact[NoGRUU, route]\n                    except KeyError:\n                        continue\n                    subscription = Subscription(subscription_uri, FromHeader(self.account.uri, self.account.display_name),\n                                                ToHeader(subscription_uri),\n                                                ContactHeader(contact_uri),\n                                                self.event,\n                                                RouteHeader(route.uri),\n                                                credentials=self.account.credentials,\n                                                refresh=refresh_interval)\n                    notification_center.add_observer(self, sender=subscription)\n                    try:\n                        subscription.subscribe(body=content.body, content_type=content.type, extra_headers=self.extra_headers, timeout=limit(remaining_time, min=1, max=5))\n                    except SIPCoreError:\n                        notification_center.remove_observer(self, sender=subscription)\n                        raise SubscriptionError('Internal error', retry_after=5)\n                    self._subscription = subscription\n                    try:\n                        while True:\n                            notification = self._data_channel.wait()\n                            if notification.name == 'SIPSubscriptionDidStart':\n                                break\n                    except SIPSubscriptionDidFail, e:\n                        notification_center.remove_observer(self, sender=subscription)\n                        self._subscription = None\n                        if e.data.code == 407:\n                            # Authentication failed, so retry the subscription in some time\n                            raise SubscriptionError('Authentication failed', retry_after=random.uniform(60, 120))\n                        elif e.data.code == 423:\n                            # Get the value of the Min-Expires header\n                            if e.data.min_expires is not None and e.data.min_expires > self.account.sip.subscribe_interval:\n                                refresh_interval = e.data.min_expires\n                            else:\n                                refresh_interval = None\n                            raise SubscriptionError('Interval too short', retry_after=random.uniform(60, 120), refresh_interval=refresh_interval)\n                        elif e.data.code in (405, 406, 489):\n                            raise SubscriptionError('Method or event not supported', retry_after=3600)\n                        elif e.data.code == 1400:\n                            raise SubscriptionError(e.data.reason, retry_after=3600)\n                        else:\n                            # Otherwise just try the next route\n                            continue\n                    else:\n                        self.subscribed = True\n                        command.signal()\n                        break\n            else:\n                # There are no more routes to try, reschedule the subscription\n                raise SubscriptionError('No more routes to try', retry_after=random.uniform(60, 180))\n            # At this point it is subscribed. Handle notifications and ending/failures.\n            notification_center.post_notification(self.__nickname__ + 'SubscriptionDidStart', sender=self)\n            try:\n                while True:\n                    notification = self._data_channel.wait()\n                    if notification.name == 'SIPSubscriptionGotNotify':\n                        notification_center.post_notification(self.__nickname__ + 'SubscriptionGotNotify', sender=self, data=notification.data)\n                    elif notification.name == 'SIPSubscriptionDidEnd':\n                        notification_center.post_notification(self.__nickname__ + 'SubscriptionDidEnd', sender=self, data=NotificationData(originator='remote'))\n                        if self.active:\n                            self._command_channel.send(Command('subscribe'))\n                        break\n            except SIPSubscriptionDidFail:\n                notification_center.post_notification(self.__nickname__ + 'SubscriptionDidFail', sender=self)\n                if self.active:\n                    self._command_channel.send(Command('subscribe'))\n            notification_center.remove_observer(self, sender=self._subscription)\n        except InterruptSubscription, e:\n            if not self.subscribed:\n                command.signal(e)\n            if self._subscription is not None:\n                notification_center.remove_observer(self, sender=self._subscription)\n                try:\n                    self._subscription.end(timeout=2)\n                except SIPCoreError:\n                    pass\n                finally:\n                    notification_center.post_notification(self.__nickname__ + 'SubscriptionDidEnd', sender=self, data=NotificationData(originator='local'))\n        except TerminateSubscription, e:\n            if not self.subscribed:\n                command.signal(e)\n            if self._subscription is not None:\n                try:\n                    self._subscription.end(timeout=2)\n                except SIPCoreError:\n                    pass\n                else:\n                    try:\n                        while True:\n                            notification = self._data_channel.wait()\n                            if notification.name == 'SIPSubscriptionDidEnd':\n                                break\n                    except SIPSubscriptionDidFail:\n                        pass\n                finally:\n                    notification_center.remove_observer(self, sender=self._subscription)\n                    notification_center.post_notification(self.__nickname__ + 'SubscriptionDidEnd', sender=self, data=NotificationData(originator='local'))\n        except SubscriptionError, e:\n            def subscribe():\n                if self.active:\n                    self._command_channel.send(Command('subscribe', command.event, refresh_interval=e.refresh_interval))\n                self._subscription_timer = None\n            self._subscription_timer = reactor.callLater(e.retry_after, subscribe)\n            notification_center.post_notification(self.__nickname__ + 'SubscriptionDidFail', sender=self)\n        finally:\n            self.subscribed = False\n            self._subscription = None\n            self._subscription_proc = None\n\n    @run_in_twisted_thread\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_SIPSubscriptionDidStart(self, notification):\n        if notification.sender is self._subscription:\n            self._data_channel.send(notification)\n\n    def _NH_SIPSubscriptionDidEnd(self, notification):\n        if notification.sender is self._subscription:\n            self._data_channel.send(notification)\n\n    def _NH_SIPSubscriptionDidFail(self, notification):\n        if notification.sender is self._subscription:\n            self._data_channel.send_exception(SIPSubscriptionDidFail(notification.data))\n\n    def _NH_SIPSubscriptionGotNotify(self, notification):\n        if notification.sender is self._subscription:\n            self._data_channel.send(notification)\n\n    def _NH_NetworkConditionsDidChange(self, notification):\n        if self.active:\n            self._command_channel.send(Command('subscribe'))\n\n\nclass MWISubscriber(Subscriber):\n    \"\"\"Message Waiting Indicator subscriber\"\"\"\n\n    @property\n    def event(self):\n        return 'message-summary'\n\n    @property\n    def subscription_uri(self):\n        return self.account.message_summary.voicemail_uri or self.account.id\n\n    def _NH_MWISubscriberWillStart(self, notification):\n        notification.center.add_observer(self, name='CFGSettingsObjectDidChange', sender=self.account)\n        notification.center.add_observer(self, name='CFGSettingsObjectDidChange', sender=SIPSimpleSettings())\n\n    def _NH_MWISubscriberWillEnd(self, notification):\n        notification.center.remove_observer(self, name='CFGSettingsObjectDidChange', sender=self.account)\n        notification.center.remove_observer(self, name='CFGSettingsObjectDidChange', sender=SIPSimpleSettings())\n\n    def _NH_MWISubscriberDidStart(self, notification):\n        if self.account.message_summary.enabled:\n            self.activate()\n\n    @run_in_green_thread\n    def _NH_CFGSettingsObjectDidChange(self, notification):\n        if not self.started:\n            return\n        if 'enabled' in notification.data.modified:\n            return # global account activation is handled separately by the account itself\n        elif 'message_summary.enabled' in notification.data.modified:\n            if self.account.message_summary.enabled:\n                self.activate()\n            else:\n                self.deactivate()\n        elif self.active and {'__id__', 'auth.password', 'auth.username', 'message_summary.voicemail_uri', 'sip.always_use_my_proxy', 'sip.outbound_proxy',\n                              'sip.subscribe_interval', 'sip.transport_list'}.intersection(notification.data.modified):\n            self._command_channel.send(Command('subscribe'))\n\n\nclass AbstractPresenceSubscriber(Subscriber):\n    \"\"\"Abstract class defining behavior for all presence subscribers\"\"\"\n\n    __transports__ = frozenset(['tls', 'tcp'])\n\n    def _NH_AbstractPresenceSubscriberWillStart(self, notification):\n        notification.center.add_observer(self, name='SIPAccountDidDiscoverXCAPSupport', sender=self.account)\n        notification.center.add_observer(self, name='CFGSettingsObjectDidChange', sender=self.account)\n        notification.center.add_observer(self, name='CFGSettingsObjectDidChange', sender=SIPSimpleSettings())\n\n    def _NH_AbstractPresenceSubscriberWillEnd(self, notification):\n        notification.center.remove_observer(self, name='SIPAccountDidDiscoverXCAPSupport', sender=self.account)\n        notification.center.remove_observer(self, name='CFGSettingsObjectDidChange', sender=self.account)\n        notification.center.remove_observer(self, name='CFGSettingsObjectDidChange', sender=SIPSimpleSettings())\n\n    def _NH_AbstractPresenceSubscriberDidStart(self, notification):\n        if self.account.presence.enabled and self.account.xcap.discovered:\n            self.activate()\n\n    def _NH_SIPAccountDidDiscoverXCAPSupport(self, notification):\n        if self.account.presence.enabled and not self.active:\n            self.activate()\n\n    @run_in_green_thread\n    def _NH_CFGSettingsObjectDidChange(self, notification):\n        if not self.started or not self.account.xcap.discovered:\n            return\n        if 'enabled' in notification.data.modified:\n            return # global account activation is handled separately by the account itself\n        elif 'presence.enabled' in notification.data.modified:\n            if self.account.presence.enabled:\n                self.activate()\n            else:\n                self.deactivate()\n        elif self.active and {'__id__', 'auth.password', 'auth.username', 'sip.always_use_my_proxy', 'sip.outbound_proxy', 'sip.subscribe_interval', 'sip.transport_list'}.intersection(notification.data.modified):\n            self._command_channel.send(Command('subscribe'))\n\n\nclass PresenceWinfoSubscriber(AbstractPresenceSubscriber):\n    \"\"\"Presence Watcher Info subscriber\"\"\"\n\n    _NH_PresenceWinfoSubscriberWillStart = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberWillStart\n    _NH_PresenceWinfoSubscriberWillEnd   = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberWillEnd\n    _NH_PresenceWinfoSubscriberDidStart  = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberDidStart\n\n    @property\n    def event(self):\n        return 'presence.winfo'\n\n\nclass DialogWinfoSubscriber(AbstractPresenceSubscriber):\n    \"\"\"Dialog Watcher Info subscriber\"\"\"\n\n    _NH_DialogWinfoSubscriberWillStart = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberWillStart\n    _NH_DialogWinfoSubscriberWillEnd   = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberWillEnd\n    _NH_DialogWinfoSubscriberDidStart  = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberDidStart\n\n    @property\n    def event(self):\n        return 'dialog.winfo'\n\n\nclass PresenceSubscriber(AbstractPresenceSubscriber):\n    \"\"\"Presence subscriber\"\"\"\n\n    _NH_PresenceSubscriberWillStart = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberWillStart\n    _NH_PresenceSubscriberWillEnd   = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberWillEnd\n    _NH_PresenceSubscriberDidStart  = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberDidStart\n\n    @property\n    def event(self):\n        return 'presence'\n\n    @property\n    def subscription_uri(self):\n        return self.account.xcap_manager.rls_presence_uri\n\n    @property\n    def extra_headers(self):\n        return [Header('Supported', 'eventlist')]\n\n\nclass SelfPresenceSubscriber(AbstractPresenceSubscriber):\n    \"\"\"Self presence subscriber\"\"\"\n\n    _NH_SelfPresenceSubscriberWillStart = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberWillStart\n    _NH_SelfPresenceSubscriberWillEnd   = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberWillEnd\n    _NH_SelfPresenceSubscriberDidStart  = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberDidStart\n\n    @property\n    def event(self):\n        return 'presence'\n\n    @property\n    def subscription_uri(self):\n        return self.account.id\n\n\nclass DialogSubscriber(AbstractPresenceSubscriber):\n    \"\"\"Dialog subscriber\"\"\"\n\n    _NH_DialogSubscriberWillStart = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberWillStart\n    _NH_DialogSubscriberWillEnd   = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberWillEnd\n    _NH_DialogSubscriberDidStart  = AbstractPresenceSubscriber._NH_AbstractPresenceSubscriberDidStart\n\n    @property\n    def event(self):\n        return 'dialog'\n\n    @property\n    def subscription_uri(self):\n        return self.account.xcap_manager.rls_dialog_uri\n\n    @property\n    def extra_headers(self):\n        return [Header('Supported', 'eventlist')]\n\n\n"
  },
  {
    "path": "sipsimple/account/xcap/__init__.py",
    "content": "\n\"\"\"High-level management of XCAP documents based on OMA specifications\"\"\"\n\n__all__ = ['Group', 'Contact', 'ContactURI', 'EventHandling', 'Policy', 'Icon', 'OfflineStatus', 'XCAPManager', 'XCAPTransaction']\n\n\nimport base64\nimport cPickle\nimport os\nimport random\nimport socket\nimport weakref\n\nfrom cStringIO import StringIO\nfrom collections import OrderedDict\nfrom datetime import datetime\nfrom itertools import chain\nfrom operator import attrgetter\nfrom urllib2 import URLError\n\nfrom application.notification import IObserver, NotificationCenter, NotificationData\nfrom application.python import Null\nfrom application.python.decorator import execute_once\nfrom eventlib import api, coros, proc\nfrom eventlib.green.httplib import BadStatusLine\nfrom twisted.internet.error import ConnectionLost\nfrom xcaplib.green import XCAPClient\nfrom xcaplib.error import HTTPError\nfrom zope.interface import implements\n\nfrom sipsimple import log\nfrom sipsimple.account.subscription import Subscriber, Content\nfrom sipsimple.account.xcap.storage import IXCAPStorage, XCAPStorageError\nfrom sipsimple.configuration.datatypes import SIPAddress\nfrom sipsimple.configuration.settings import SIPSimpleSettings\nfrom sipsimple.lookup import DNSLookup, DNSLookupError\nfrom sipsimple.payloads import ParserError, IterateTypes, IterateIDs, IterateItems, All\nfrom sipsimple.payloads import addressbook, commonpolicy, dialogrules, omapolicy, pidf, prescontent, presrules, resourcelists, rlsservices, xcapcaps, xcapdiff\nfrom sipsimple.payloads import rpid; del rpid  # needs to be imported to register its namespace\nfrom sipsimple.threading import run_in_twisted_thread\nfrom sipsimple.threading.green import Command, Worker, run_in_green_thread\n\n\n\nclass XCAPError(Exception): pass\nclass FetchRequiredError(XCAPError): pass\n\n\nclass Document(object):\n    name               = None\n    application        = None\n    payload_type       = None\n    default_namespace  = None\n    global_tree        = None\n    filename           = None\n    cached             = True\n\n    def __init__(self, manager):\n        self.manager = weakref.proxy(manager)\n        self.content = None\n        self.etag = None\n        self.fetch_time = datetime.fromtimestamp(0)\n        self.update_time = datetime.fromtimestamp(0)\n        self.dirty = False\n        self.supported = False\n\n    def __nonzero__(self):\n        return self.content is not None\n\n    @property\n    def dirty(self):\n        return self.__dict__['dirty'] or (self.content is not None and self.content.__dirty__)\n\n    @dirty.setter\n    def dirty(self, dirty):\n        if self.content is not None and not dirty:\n            self.content.__dirty__ = dirty\n        self.__dict__['dirty'] = dirty\n\n    @property\n    def relative_url(self):\n        return self.url[len(self.manager.xcap_root):].lstrip('/')\n\n    @property\n    def url(self):\n        return self.manager.client.get_url(self.application, None, globaltree=self.global_tree, filename=self.filename)\n\n    def load_from_cache(self):\n        if not self.cached:\n            return\n        try:\n            document = StringIO(self.manager.storage.load(self.name))\n            self.etag = document.readline().strip() or None\n            self.content = self.payload_type.parse(document)\n            self.__dict__['dirty'] = False\n        except (XCAPStorageError, ParserError):\n            self.etag = None\n            self.content = None\n            self.dirty = False\n        self.fetch_time = datetime.utcnow()\n\n    def initialize(self, server_caps):\n        self.supported = self.application in server_caps.auids\n        if not self.supported:\n            self.reset()\n\n    def reset(self):\n        if self.cached and self.content is not None:\n            try:\n                self.manager.storage.delete(self.name)\n            except XCAPStorageError:\n                pass\n        self.content = None\n        self.etag = None\n        self.dirty = False\n\n    def fetch(self):\n        try:\n            document = self.manager.client.get(self.application, etagnot=self.etag, globaltree=self.global_tree, headers={'Accept': self.payload_type.content_type}, filename=self.filename)\n            self.content = self.payload_type.parse(document)\n            self.etag = document.etag\n            self.__dict__['dirty'] = False\n        except (BadStatusLine, ConnectionLost, URLError, socket.error), e:\n            raise XCAPError(\"failed to fetch %s document: %s\" % (self.name, e))\n        except HTTPError, e:\n            if e.status == 404: # Not Found\n                if self.content is not None:\n                    self.reset()\n                    self.fetch_time = datetime.utcnow()\n            elif e.status != 304: # Other than Not Modified:\n                raise XCAPError(\"failed to fetch %s document: %s\" % (self.name, e))\n        except ParserError, e:\n            raise XCAPError(\"failed to parse %s document: %s\" % (self.name, e))\n        else:\n            self.fetch_time = datetime.utcnow()\n            if self.cached:\n                try:\n                    self.manager.storage.save(self.name, self.etag + os.linesep + document)\n                except XCAPStorageError:\n                    pass\n\n    def update(self):\n        if not self.dirty:\n            return\n        data = self.content.toxml() if self.content is not None else None\n        try:\n            kw = dict(etag=self.etag) if self.etag is not None else dict(etagnot='*')\n            if data is not None:\n                response = self.manager.client.put(self.application, data, globaltree=self.global_tree, filename=self.filename, headers={'Content-Type': self.payload_type.content_type}, **kw)\n            else:\n                response = self.manager.client.delete(self.application, data, globaltree=self.global_tree, filename=self.filename, **kw)\n        except (BadStatusLine, ConnectionLost, URLError), e:\n            raise XCAPError(\"failed to update %s document: %s\" % (self.name, e))\n        except HTTPError, e:\n            if e.status == 412: # Precondition Failed\n                raise FetchRequiredError(\"document %s was modified externally\" % self.name)\n            elif e.status == 404 and data is None: # attempted to delete a document that did't exist in the first place\n                pass\n            else:\n                raise XCAPError(\"failed to update %s document: %s\" % (self.name, e))\n        self.etag = response.etag if data is not None else None\n        self.dirty = False\n        self.update_time = datetime.utcnow()\n        if self.cached:\n            try:\n                if data is not None:\n                    self.manager.storage.save(self.name, self.etag + os.linesep + data)\n                else:\n                    self.manager.storage.delete(self.name)\n            except XCAPStorageError:\n                pass\n\n\nclass DialogRulesDocument(Document):\n    name               = 'dialog-rules'\n    application        = 'org.openxcap.dialog-rules'\n    payload_type       = dialogrules.DialogRulesDocument\n    default_namespace  = dialogrules.namespace\n    global_tree        = False\n    filename           = 'index'\n\n\nclass PresRulesDocument(Document):\n    name               = 'pres-rules'\n    application        = 'org.openmobilealliance.pres-rules'\n    payload_type       = presrules.PresRulesDocument\n    default_namespace  = presrules.namespace\n    global_tree        = False\n    filename           = 'index'\n\n\nclass ResourceListsDocument(Document):\n    name               = 'resource-lists'\n    application        = 'resource-lists'\n    payload_type       = resourcelists.ResourceListsDocument\n    default_namespace  = resourcelists.namespace\n    global_tree        = False\n    filename           = 'index'\n\n    def update(self):\n        if self.content is not None:\n            sipsimple_addressbook = self.content['sipsimple_addressbook']\n\n            groups = ItemCollection(sipsimple_addressbook[addressbook.Group, IterateItems])\n            contacts = ItemCollection(sipsimple_addressbook[addressbook.Contact, IterateItems])\n            policies = ItemCollection(sipsimple_addressbook[addressbook.Policy, IterateItems])\n\n            for group, missing_id in ((group, missing_id) for group in groups for missing_id in [id for id in group.contacts if id not in contacts]):\n                group.contacts.remove(missing_id)\n\n            if any(item.__dirty__ for item in chain(contacts, policies)):\n                oma_grantedcontacts = self.content['oma_grantedcontacts']\n                oma_blockedcontacts = self.content['oma_blockedcontacts']\n                dialog_grantedcontacts = self.content['dialog_grantedcontacts']\n                dialog_blockedcontacts = self.content['dialog_blockedcontacts']\n                sipsimple_presence_rls = self.content['sipsimple_presence_rls']\n                sipsimple_dialog_rls = self.content['sipsimple_dialog_rls']\n\n                all_contact_uris = set(uri.uri for contact in contacts for uri in contact.uris)\n\n                contact_allow_presence_uris = set(uri.uri for contact in contacts for uri in contact.uris if contact.presence.policy=='allow')\n                contact_block_presence_uris = set(uri.uri for contact in contacts for uri in contact.uris if contact.presence.policy=='block')\n                contact_allow_dialog_uris = set(uri.uri for contact in contacts for uri in contact.uris if contact.dialog.policy=='allow')\n                contact_block_dialog_uris = set(uri.uri for contact in contacts for uri in contact.uris if contact.dialog.policy=='block')\n                contact_subscribe_presence_uris = set(uri.uri for contact in contacts for uri in contact.uris if contact.presence.subscribe==True)\n                contact_subscribe_dialog_uris = set(uri.uri for contact in contacts for uri in contact.uris if contact.dialog.subscribe==True)\n\n                policy_allow_presence_uris = set(policy.uri for policy in policies if policy.presence.policy=='allow')\n                policy_block_presence_uris = set(policy.uri for policy in policies if policy.presence.policy=='block')\n                policy_allow_dialog_uris = set(policy.uri for policy in policies if policy.dialog.policy=='allow')\n                policy_block_dialog_uris = set(policy.uri for policy in policies if policy.dialog.policy=='block')\n                policy_subscribe_presence_uris = set(policy.uri for policy in policies if policy.presence.subscribe==True)\n                policy_subscribe_dialog_uris = set(policy.uri for policy in policies if policy.dialog.subscribe==True)\n\n                allowed_presence_uris = contact_allow_presence_uris - contact_block_presence_uris | policy_allow_presence_uris - policy_block_presence_uris - all_contact_uris\n                blocked_presence_uris = contact_block_presence_uris | policy_block_presence_uris - all_contact_uris\n                allowed_dialog_uris = contact_allow_dialog_uris - contact_block_dialog_uris | policy_allow_dialog_uris - policy_block_dialog_uris - all_contact_uris\n                blocked_dialog_uris = contact_block_dialog_uris | policy_block_dialog_uris - all_contact_uris\n                subscribe_presence_uris = contact_subscribe_presence_uris | policy_subscribe_presence_uris - all_contact_uris\n                subscribe_dialog_uris = contact_subscribe_dialog_uris | policy_subscribe_dialog_uris - all_contact_uris\n\n                if allowed_presence_uris != set(entry.uri for entry in oma_grantedcontacts):\n                    oma_grantedcontacts.clear()\n                    oma_grantedcontacts.update(resourcelists.Entry(uri) for uri in allowed_presence_uris)\n                if blocked_presence_uris != set(entry.uri for entry in oma_blockedcontacts):\n                    oma_blockedcontacts.clear()\n                    oma_blockedcontacts.update(resourcelists.Entry(uri) for uri in blocked_presence_uris)\n                if allowed_dialog_uris != set(entry.uri for entry in dialog_grantedcontacts):\n                    dialog_grantedcontacts.clear()\n                    dialog_grantedcontacts.update(resourcelists.Entry(uri) for uri in allowed_dialog_uris)\n                if blocked_dialog_uris != set(entry.uri for entry in dialog_blockedcontacts):\n                    dialog_blockedcontacts.clear()\n                    dialog_blockedcontacts.update(resourcelists.Entry(uri) for uri in blocked_dialog_uris)\n                if subscribe_presence_uris != set(entry.uri for entry in sipsimple_presence_rls):\n                    sipsimple_presence_rls.clear()\n                    sipsimple_presence_rls.update(resourcelists.Entry(uri) for uri in subscribe_presence_uris)\n                if subscribe_dialog_uris != set(entry.uri for entry in sipsimple_dialog_rls):\n                    sipsimple_dialog_rls.clear()\n                    sipsimple_dialog_rls.update(resourcelists.Entry(uri) for uri in subscribe_dialog_uris)\n        super(ResourceListsDocument, self).update()\n\n\nclass RLSServicesDocument(Document):\n    name               = 'rls-services'\n    application        = 'rls-services'\n    payload_type       = rlsservices.RLSServicesDocument\n    default_namespace  = rlsservices.namespace\n    global_tree        = False\n    filename           = 'index'\n\n\nclass XCAPCapsDocument(Document):\n    name               = 'xcap-caps'\n    application        = 'xcap-caps'\n    payload_type       = xcapcaps.XCAPCapabilitiesDocument\n    default_namespace  = xcapcaps.namespace\n    global_tree        = True\n    filename           = 'index'\n    cached             = False\n\n    def initialize(self):\n        self.supported = True\n\n\nclass StatusIconDocument(Document):\n    name               = 'status-icon'\n    application        = 'org.openmobilealliance.pres-content'\n    payload_type       = prescontent.PresenceContentDocument\n    default_namespace  = prescontent.namespace\n    global_tree        = False\n    filename           = 'oma_status-icon/index'\n\n\nclass PIDFManipulationDocument(Document):\n    name               = 'pidf-manipulation'\n    application        = 'pidf-manipulation'\n    payload_type       = pidf.PIDFDocument\n    default_namespace  = pidf.pidf_namespace\n    global_tree        = False\n    filename           = 'index'\n\n\nclass ItemCollection(object):\n    def __init__(self, items):\n        self.items = OrderedDict((item.id, item) for item in items)\n    def __getitem__(self, key):\n        return self.items[key]\n    def __contains__(self, key):\n        return key in self.items\n    def __iter__(self):\n        return self.items.itervalues()\n    def __reversed__(self):\n        return (self[id] for id in reversed(self.items))\n    def __len__(self):\n        return len(self.items)\n    def __eq__(self, other):\n        if isinstance(other, ItemCollection):\n            return self.items == other.items\n        return NotImplemented\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n    def __repr__(self):\n        return \"%s(%r)\" % (self.__class__.__name__, self.items.values())\n    def ids(self):\n        return self.items.keys()\n    def iterids(self):\n        return self.items.iterkeys()\n    def get(self, key, default=None):\n        return self.items.get(key, default)\n    def add(self, item):\n        self.items[item.id] = item\n    def remove(self, item):\n        del self.items[item.id]\n\n\nclass ContactList(ItemCollection):\n    pass\n\n\nclass ContactURIList(ItemCollection):\n    def __init__(self, items, default=None):\n        super(ContactURIList, self).__init__(items)\n        self.default = default\n\n    def __eq__(self, other):\n        if isinstance(other, ContactURIList):\n            return self.items == other.items and self.default == other.default\n        return NotImplemented\n\n    def __repr__(self):\n        return \"%s(%r, default=%r)\" % (self.__class__.__name__, self.items.values(), self.default)\n\n\nclass Group(object):\n    def __init__(self, id, name, contacts, **attributes):\n        self.id = id\n        self.name = name\n        self.contacts = contacts\n        self.attributes = attributes\n\n    def __eq__(self, other):\n        if isinstance(other, Group):\n            return self is other or (self.id == other.id and self.name == other.name and self.contacts.ids() == other.contacts.ids() and self.attributes == other.attributes)\n        return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    def __setattr__(self, name, value):\n        if name == 'contacts' and not isinstance(value, ContactList):\n            value = ContactList(value)\n        object.__setattr__(self, name, value)\n\n\nclass ContactURI(object):\n    def __init__(self, id, uri, type, **attributes):\n        self.id = id\n        self.uri = uri\n        self.type = type\n        self.attributes = attributes\n\n    def __eq__(self, other):\n        if isinstance(other, ContactURI):\n            return self is other or (self.id == other.id and self.uri == other.uri and self.type == other.type and self.attributes == other.attributes)\n        return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n\nclass EventHandling(object):\n    def __init__(self, policy, subscribe):\n        self.policy = policy\n        self.subscribe = subscribe\n\n    def __eq__(self, other):\n        if isinstance(other, EventHandling):\n            return self is other or (self.policy == other.policy and self.subscribe == other.subscribe)\n        return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.policy, self.subscribe)\n\n\nclass Contact(object):\n    def __init__(self, id, name, uris, presence_handling=None, dialog_handling=None, **attributes):\n        self.id = id\n        self.name = name\n        self.uris = uris\n        self.dialog = dialog_handling or EventHandling(policy='default', subscribe=False)\n        self.presence = presence_handling or EventHandling(policy='default', subscribe=False)\n        self.attributes = attributes\n\n    def __eq__(self, other):\n        if isinstance(other, Contact):\n            return self is other or (self.id == other.id and self.name == other.name and self.uris == other.uris and self.dialog == other.dialog and self.presence == other.presence and\n                                     self.attributes == other.attributes)\n        return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    def __setattr__(self, name, value):\n        if name == 'uris' and not isinstance(value, ContactURIList):\n            value = ContactURIList(value)\n        object.__setattr__(self, name, value)\n\n\nclass Policy(object):\n    def __init__(self, id, uri, name, presence_handling=None, dialog_handling=None, **attributes):\n        self.id = id\n        self.uri = uri\n        self.name = name\n        self.dialog = dialog_handling or EventHandling(policy='default', subscribe=False)\n        self.presence = presence_handling or EventHandling(policy='default', subscribe=False)\n        self.attributes = attributes\n\n    def __eq__(self, other):\n        if isinstance(other, Policy):\n            return self is other or (self.id == other.id and self.uri == other.uri and self.name == other.name and self.dialog == other.dialog and self.presence == other.presence and\n                                     self.attributes == other.attributes)\n        return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n\nclass Addressbook(object):\n    def __init__(self, contacts, groups, policies):\n        self.contacts = contacts\n        self.groups = groups\n        self.policies = policies\n\n    def __eq__(self, other):\n        if isinstance(other, Addressbook):\n            return self is other or (self.contacts == other.contacts and self.groups == other.groups and self.policies == other.policies)\n        return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    @classmethod\n    def from_payload(cls, payload):\n        def payload_to_contact(payload):\n            uris = ContactURIList((ContactURI(uri.id, uri.uri, uri.type, **(uri.attributes or {})) for uri in payload.uris), default=payload.uris.default)\n            presence_handling = EventHandling(payload.presence.policy.value, payload.presence.subscribe.value)\n            dialog_handling = EventHandling(payload.dialog.policy.value, payload.dialog.subscribe.value)\n            return Contact(payload.id, payload.name.value, uris, presence_handling, dialog_handling, **(payload.attributes or {}))\n        def payload_to_group(payload):\n            return Group(payload.id, payload.name.value, [contacts[contact_id] for contact_id in payload.contacts], **(payload.attributes or {}))\n        def payload_to_policy(payload):\n            presence_handling = EventHandling(payload.presence.policy.value, payload.presence.subscribe.value)\n            dialog_handling = EventHandling(payload.dialog.policy.value, payload.dialog.subscribe.value)\n            return Policy(payload.id, payload.uri, payload.name.value, presence_handling, dialog_handling, **(payload.attributes or {}))\n        contacts = ItemCollection(payload_to_contact(item) for item in payload[addressbook.Contact, IterateItems])\n        groups = ItemCollection(payload_to_group(item) for item in payload[addressbook.Group, IterateItems])\n        policies = ItemCollection(payload_to_policy(item) for item in payload[addressbook.Policy, IterateItems])\n        return cls(contacts, groups, policies)\n\n\nclass PresenceRules(object):\n    def __init__(self, default_policy):\n        self.default_policy = default_policy\n\n    def __eq__(self, other):\n        if isinstance(other, PresenceRules):\n            return self is other or (self.default_policy == other.default_policy)\n        return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    @classmethod\n    def from_payload(cls, default_rule):\n        default_policy = next(item for item in default_rule.actions if isinstance(item, presrules.SubHandling)).value\n        return cls(default_policy)\n\n\nclass DialogRules(object):\n    def __init__(self, default_policy):\n        self.default_policy = default_policy\n\n    def __eq__(self, other):\n        if isinstance(other, DialogRules):\n            return self is other or (self.default_policy == other.default_policy)\n        return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    @classmethod\n    def from_payload(cls, default_rule):\n        if default_rule is not None:\n            default_policy = next(item for item in default_rule.actions if isinstance(item, dialogrules.SubHandling)).value\n        else:\n            default_policy = None\n        return cls(default_policy)\n\n\nclass Icon(object):\n    __mimetypes__ = ('image/jpeg', 'image/png', 'image/gif')\n\n    def __init__(self, data, mime_type, description=None):\n        self.data = data\n        self.mime_type = mime_type\n        self.description = description\n        self.url = None\n        self.etag = None\n\n    def __eq__(self, other):\n        if isinstance(other, Icon):\n            return self is other or (self.data == other.data and self.mime_type == other.mime_type and self.description == other.description)\n        return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    def __setattr__(self, name, value):\n        if name == 'mime_type' and value not in self.__mimetypes__:\n            raise ValueError(\"invalid mime type: '%s'. Should be one of: %s\" % (value, ', '.join(self.__mimetypes__)))\n        object.__setattr__(self, name, value)\n\n    @classmethod\n    def from_payload(cls, payload):\n        try:\n            data = base64.decodestring(payload.data.value)\n        except Exception:\n            return None\n        else:\n            description = payload.description.value if payload.description else None\n            return cls(data, payload.mime_type.value, description)\n\n\nclass OfflineStatus(object):\n    __slots__ = ('pidf',)\n\n    def __init__(self, pidf):\n        self.pidf = pidf\n\n    def __setattr__(self, name, value):\n        if name == 'pidf' and not isinstance(value, pidf.PIDF):\n            raise ValueError(\"pidf must be a PIDF payload\")\n        object.__setattr__(self, name, value)\n\n    def __eq__(self, other):\n        if isinstance(other, OfflineStatus):\n            return self is other or (self.pidf == other.pidf)\n        return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    def __getstate__(self):\n        return {'pidf': self.pidf.toxml()}\n\n    def __setstate__(self, state):\n        self.pidf = pidf.PIDFDocument.parse(state['pidf'])\n\n\nclass Operation(object):\n    __params__ = ()\n    def __init__(self, **params):\n        for name, value in params.iteritems():\n            setattr(self, name, value)\n        for param in set(self.__params__).difference(params):\n            raise ValueError(\"missing operation parameter: '%s'\" % param)\n        self.applied = False\n        self.timestamp = datetime.utcnow()\n\n\nclass NormalizeOperation(Operation):\n    __params__ = ()\n\nclass AddContactOperation(Operation):\n    __params__ = ('contact',)\n\nclass UpdateContactOperation(Operation):\n    __params__ = ('contact', 'attributes')\n\nclass RemoveContactOperation(Operation):\n    __params__ = ('contact',)\n\nclass AddContactURIOperation(Operation):\n    __params__ = ('contact', 'uri')\n\nclass UpdateContactURIOperation(Operation):\n    __params__ = ('contact', 'uri', 'attributes')\n\nclass RemoveContactURIOperation(Operation):\n    __params__ = ('contact', 'uri')\n\nclass AddGroupOperation(Operation):\n    __params__ = ('group',)\n\nclass UpdateGroupOperation(Operation):\n    __params__ = ('group', 'attributes')\n\nclass RemoveGroupOperation(Operation):\n    __params__ = ('group',)\n\nclass AddGroupMemberOperation(Operation):\n    __params__ = ('group', 'contact')\n\nclass RemoveGroupMemberOperation(Operation):\n    __params__ = ('group', 'contact')\n\nclass AddPolicyOperation(Operation):\n    __params__ = ('policy',)\n\nclass UpdatePolicyOperation(Operation):\n    __params__ = ('policy', 'attributes')\n\nclass RemovePolicyOperation(Operation):\n    __params__ = ('policy',)\n\nclass SetDefaultPresencePolicyOperation(Operation):\n    __params__ = ('policy',)\n\nclass SetDefaultDialogPolicyOperation(Operation):\n    __params__ = ('policy',)\n\nclass SetStatusIconOperation(Operation):\n    __params__ = ('icon',)\n\nclass SetOfflineStatusOperation(Operation):\n    __params__ = ('status',)\n\n\nclass XCAPSubscriber(Subscriber):\n    __transports__ = frozenset(['tls', 'tcp'])\n\n    @property\n    def event(self):\n        return 'xcap-diff'\n\n    @property\n    def content(self):\n        rlist = resourcelists.List()\n        for document in (doc for doc in self.account.xcap_manager.documents if doc.supported):\n            rlist.add(resourcelists.Entry(document.relative_url))\n        return Content(resourcelists.ResourceLists([rlist]).toxml(), resourcelists.ResourceListsDocument.content_type)\n\n\nclass XCAPManager(object):\n    implements(IObserver)\n\n    def __init__(self, account):\n        from sipsimple.application import SIPApplication\n        if SIPApplication.storage is None:\n            raise RuntimeError(\"SIPApplication.storage must be defined before instantiating XCAPManager\")\n        storage = SIPApplication.storage.xcap_storage_factory(account.id)\n        if not IXCAPStorage.providedBy(storage):\n            raise TypeError(\"storage must implement the IXCAPStorage interface\")\n        self.account = account\n        self.storage = storage\n        self.storage_factory = SIPApplication.storage.xcap_storage_factory\n        self.client = None\n        self.command_proc = None\n        self.command_channel = coros.queue()\n        self.last_fetch_time = datetime.fromtimestamp(0)\n        self.last_update_time = datetime.fromtimestamp(0)\n        self.not_executed_fetch = None\n        self.state = 'stopped'\n        self.timer = None\n        self.transaction_level = 0\n        self.xcap_subscriber = None\n\n        self.server_caps = XCAPCapsDocument(self)\n        self.dialog_rules = DialogRulesDocument(self)\n        self.pidf_manipulation = PIDFManipulationDocument(self)\n        self.pres_rules = PresRulesDocument(self)\n        self.resource_lists = ResourceListsDocument(self)\n        self.rls_services = RLSServicesDocument(self)\n        self.status_icon = StatusIconDocument(self)\n\n        for document in self.documents:\n            document.load_from_cache()\n\n        try:\n            journal = self.storage.load('journal')\n        except XCAPStorageError:\n            self.journal = []\n        else:\n            try:\n                self.journal = cPickle.loads(journal)\n            except Exception:\n                self.journal = []\n\n        for operation in self.journal:\n            operation.applied = False\n\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, sender=account, name='CFGSettingsObjectDidChange')\n        notification_center.add_observer(self, sender=account, name='CFGSettingsObjectWasDeleted')\n\n    @property\n    def state(self):\n        return self.__dict__['state']\n\n    @state.setter\n    def state(self, value):\n        old_value = self.__dict__.get('state', Null)\n        self.__dict__['state'] = value\n        if old_value != value and old_value is not Null:\n            notification_center = NotificationCenter()\n            notification_center.post_notification('XCAPManagerDidChangeState', sender=self, data=NotificationData(prev_state=old_value, state=value))\n\n    @property\n    def documents(self):\n        return [self.resource_lists, self.rls_services, self.pres_rules, self.dialog_rules, self.pidf_manipulation, self.status_icon]\n\n    @property\n    def document_names(self):\n        return [document.name for document in self.documents]\n\n    @property\n    def xcap_root(self):\n        return getattr(self.client, 'root', None)\n\n    @property\n    def rls_presence_uri(self):\n        return SIPAddress('%s+presence@%s' % (self.account.id.username, self.account.id.domain))\n\n    @property\n    def rls_dialog_uri(self):\n        return SIPAddress('%s+dialog@%s' % (self.account.id.username, self.account.id.domain))\n\n    @execute_once\n    def init(self):\n        \"\"\"\n        Initializes the XCAP manager before it can be started. Needs to be\n        called before any other method and in a green thread.\n        \"\"\"\n        self.command_proc = proc.spawn(self._run)\n\n    def start(self):\n        \"\"\"\n        Starts the XCAP manager. This method needs to be called in a green\n        thread.\n        \"\"\"\n        command = Command('start')\n        self.command_channel.send(command)\n        command.wait()\n\n    def stop(self):\n        \"\"\"\n        Stops the XCAP manager. This method blocks until all the operations are\n        stopped and needs to be called in a green thread.\n        \"\"\"\n        command = Command('stop')\n        self.command_channel.send(command)\n        command.wait()\n\n    def transaction(self):\n        return XCAPTransaction(self)\n\n    @run_in_twisted_thread\n    def start_transaction(self):\n        self.transaction_level += 1\n\n    @run_in_twisted_thread\n    def commit_transaction(self):\n        if self.transaction_level == 0:\n            return\n        self.transaction_level -= 1\n        if self.transaction_level == 0 and self.journal:\n            self._save_journal()\n            self.command_channel.send(Command('update'))\n\n    def add_contact(self, contact):\n        self._schedule_operation(AddContactOperation(contact=contact))\n\n    def update_contact(self, contact, attributes):\n        self._schedule_operation(UpdateContactOperation(contact=contact, attributes=attributes))\n\n    def remove_contact(self, contact):\n        self._schedule_operation(RemoveContactOperation(contact=contact))\n\n    def add_contact_uri(self, contact, uri):\n        self._schedule_operation(AddContactURIOperation(contact=contact, uri=uri))\n\n    def update_contact_uri(self, contact, uri, attributes):\n        self._schedule_operation(UpdateContactURIOperation(contact=contact, uri=uri, attributes=attributes))\n\n    def remove_contact_uri(self, contact, uri):\n        self._schedule_operation(RemoveContactURIOperation(contact=contact, uri=uri))\n\n    def add_group(self, group):\n        self._schedule_operation(AddGroupOperation(group=group))\n\n    def update_group(self, group, attributes):\n        self._schedule_operation(UpdateGroupOperation(group=group, attributes=attributes))\n\n    def remove_group(self, group):\n        self._schedule_operation(RemoveGroupOperation(group=group))\n\n    def add_group_member(self, group, contact):\n        self._schedule_operation(AddGroupMemberOperation(group=group, contact=contact))\n\n    def remove_group_member(self, group, contact):\n        self._schedule_operation(RemoveGroupMemberOperation(group=group, contact=contact))\n\n    def add_policy(self, policy):\n        self._schedule_operation(AddPolicyOperation(policy=policy))\n\n    def update_policy(self, policy, attributes):\n        self._schedule_operation(UpdatePolicyOperation(policy=policy, attributes=attributes))\n\n    def remove_policy(self, policy):\n        self._schedule_operation(RemovePolicyOperation(policy=policy))\n\n    def set_default_presence_policy(self, policy):\n        self._schedule_operation(SetDefaultPresencePolicyOperation(policy=presrules.SubHandlingValue(policy)))\n\n    def set_default_dialog_policy(self, policy):\n        self._schedule_operation(SetDefaultDialogPolicyOperation(policy=dialogrules.SubHandlingValue(policy)))\n\n    def set_status_icon(self, icon):\n        self._schedule_operation(SetStatusIconOperation(icon=icon))\n\n    def set_offline_status(self, status):\n        self._schedule_operation(SetOfflineStatusOperation(status=status))\n\n    @run_in_twisted_thread\n    def _schedule_operation(self, operation):\n        self.journal.append(operation)\n        if self.transaction_level == 0:\n            self._save_journal()\n            self.command_channel.send(Command('update'))\n\n    def _run(self):\n        while True:\n            command = self.command_channel.wait()\n            try:\n                handler = getattr(self, '_CH_%s' % command.name)\n                handler(command)\n            except:\n                self.command_proc = None\n                raise\n\n    # Command handlers\n    #\n\n    def _CH_start(self, command):\n        if self.state != 'stopped':\n            command.signal()\n            return\n        self.state = 'initializing'\n        self.xcap_subscriber = XCAPSubscriber(self.account)\n        notification_center = NotificationCenter()\n        notification_center.post_notification('XCAPManagerWillStart', sender=self)\n        notification_center.add_observer(self, sender=self.xcap_subscriber)\n        notification_center.add_observer(self, sender=SIPSimpleSettings(), name='CFGSettingsObjectDidChange')\n        self.xcap_subscriber.start()\n        self.command_channel.send(Command('initialize'))\n        notification_center.post_notification('XCAPManagerDidStart', sender=self)\n        command.signal()\n\n    def _CH_stop(self, command):\n        if self.state in ('stopped', 'terminated'):\n            command.signal()\n            return\n        notification_center = NotificationCenter()\n        notification_center.post_notification('XCAPManagerWillEnd', sender=self)\n        notification_center.remove_observer(self, sender=self.xcap_subscriber)\n        notification_center.remove_observer(self, sender=SIPSimpleSettings(), name='CFGSettingsObjectDidChange')\n        if self.timer is not None and self.timer.active():\n            self.timer.cancel()\n        self.timer = None\n        self.xcap_subscriber.stop()\n        self.xcap_subscriber = None\n        self.client = None\n        self.state = 'stopped'\n        self._save_journal()\n        notification_center.post_notification('XCAPManagerDidEnd', sender=self)\n        command.signal()\n\n    def _CH_cleanup(self, command):\n        if self.state != 'stopped':\n            command.signal()\n            return\n        try:\n            self.storage.purge()\n        except XCAPStorageError:\n            pass\n        self.journal = []\n        self.state = 'terminated'\n        command.signal()\n        raise proc.ProcExit\n\n    def _CH_initialize(self, command):\n        self.state = 'initializing'\n        if self.timer is not None and self.timer.active():\n            self.timer.cancel()\n        self.timer = None\n        if self.account.xcap.xcap_root:\n            self.client = XCAPClient(self.account.xcap.xcap_root, self.account.id, password=self.account.auth.password)\n        else:\n            try:\n                lookup = DNSLookup()\n                xcap_root = random.choice(lookup.lookup_xcap_server(self.account.uri).wait())\n            except DNSLookupError:\n                self.timer = self._schedule_command(60,  Command('initialize', command.event))\n                return\n            else:\n                self.client = XCAPClient(xcap_root, self.account.id, password=self.account.auth.password)\n\n        try:\n            self.server_caps.fetch()\n        except XCAPError:\n            self.timer = self._schedule_command(60,  Command('initialize', command.event))\n            return\n        else:\n            if self.server_caps.content is None:\n                # XCAP server must always return some content for xcap-caps\n                self.timer = self._schedule_command(60,  Command('initialize', command.event))\n                return\n            if not set(self.server_caps.content.auids).issuperset(('resource-lists', 'rls-services', 'org.openmobilealliance.pres-rules')):\n                # Server must support at least resource-lists, rls-services and org.openmobilealliance.pres-rules\n                self.timer = self._schedule_command(3600,  Command('initialize', command.event))\n                return\n        self.server_caps.initialize()\n        for document in self.documents:\n            document.initialize(self.server_caps.content)\n\n        notification_center = NotificationCenter()\n        notification_center.post_notification('XCAPManagerDidDiscoverServerCapabilities', sender=self, data=NotificationData(auids=self.server_caps.content.auids))\n\n        self.state = 'fetching'\n        self.command_channel.send(Command('fetch', documents=set(self.document_names)))\n        self.xcap_subscriber.activate()\n\n    def _CH_reload(self, command):\n        if self.state == 'terminated':\n            command.signal()\n            return\n        if '__id__' in command.modified:\n            try:\n                self.storage.purge()\n            except XCAPStorageError:\n                pass\n            self.storage = self.storage_factory(self.account.id)\n            self.journal = []\n            self._save_journal()\n        if {'__id__', 'xcap.xcap_root'}.intersection(command.modified):\n            for document in self.documents:\n                document.reset()\n        if self.state == 'stopped':\n            command.signal()\n            return\n        if {'__id__', 'auth.username', 'auth.password', 'xcap.xcap_root'}.intersection(command.modified):\n            self.state = 'initializing'\n            self.command_channel.send(Command('initialize'))\n        else:\n            self.xcap_subscriber.resubscribe()\n        command.signal()\n\n    def _CH_fetch(self, command):\n        if self.state not in ('insync', 'fetching'):\n            if self.not_executed_fetch is not None:\n                command.documents.update(self.not_executed_fetch.documents)\n            self.not_executed_fetch = command\n            return\n        if self.not_executed_fetch is not None:\n            command.documents.update(self.not_executed_fetch.documents)\n            self.not_executed_fetch = None\n        self.state = 'fetching'\n        if self.timer is not None and self.timer.active():\n            command.documents.update(self.timer.command.documents)\n            self.timer.cancel()\n        self.timer = None\n\n        try:\n            self._fetch_documents(command.documents)\n        except XCAPError:\n            self.timer = self._schedule_command(60, Command('fetch', command.event, documents=command.documents))\n            return\n\n        if not self.journal and self.last_fetch_time > datetime.fromtimestamp(0) and all(doc.fetch_time < command.timestamp for doc in self.documents):\n            self.last_fetch_time = datetime.utcnow()\n            self.state = 'insync'\n            return\n        else:\n            self.last_fetch_time = datetime.utcnow()\n\n        self.state = 'updating'\n        if not self.journal or type(self.journal[0]) is not NormalizeOperation:\n            self.journal.insert(0, NormalizeOperation())\n        self.command_channel.send(Command('update', command.event))\n\n    def _CH_update(self, command):\n        if self.state not in ('insync', 'updating'):\n            return\n        if self.transaction_level != 0:\n            return\n        self.state = 'updating'\n        if self.timer is not None and self.timer.active():\n            self.timer.cancel()\n        self.timer = None\n        journal = self.journal[:]\n        for operation in (operation for operation in journal if not operation.applied):\n            handler = getattr(self, '_OH_%s' % operation.__class__.__name__)\n            try:\n                handler(operation)\n            except Exception:\n                # Error while applying operation, needs to be logged -Luci\n                log.exception()\n            operation.applied = True\n            api.sleep(0) # Operations are quite CPU intensive\n        try:\n            for document in (doc for doc in self.documents if doc.dirty and doc.supported):\n                document.update()\n        except FetchRequiredError:\n            for document in (doc for doc in self.documents if doc.dirty and doc.supported):\n                document.reset()\n            for operation in journal:\n                operation.applied = False\n            self.state = 'fetching'\n            self.command_channel.send(Command('fetch', documents=set(self.document_names))) # Try to fetch them all just in case\n        except XCAPError:\n            self.timer = self._schedule_command(60, Command('update'))\n        else:\n            del self.journal[:len(journal)]\n            if not self.journal:\n                self.state = 'insync'\n                if any(max(doc.update_time, doc.fetch_time) > self.last_update_time for doc in self.documents):\n                    self._load_data()\n                self.last_update_time = datetime.utcnow()\n            command.signal()\n            if self.not_executed_fetch is not None:\n                self.command_channel.send(self.not_executed_fetch)\n                self.not_executed_fetch = None\n            self._save_journal()\n\n    # Operation handlers\n    #\n\n    def _OH_NormalizeOperation(self, operation):\n        # Normalize resource-lists\n        #\n        if self.resource_lists.content is None:\n            self.resource_lists.content = resourcelists.ResourceLists()\n\n        resource_lists = self.resource_lists.content\n\n        try:\n            oma_buddylist = resource_lists['oma_buddylist']\n        except KeyError:\n            oma_buddylist = resourcelists.List(name='oma_buddylist')\n            resource_lists.add(oma_buddylist)\n        try:\n            oma_grantedcontacts = resource_lists['oma_grantedcontacts']\n        except KeyError:\n            oma_grantedcontacts = resourcelists.List(name='oma_grantedcontacts')\n            resource_lists.add(oma_grantedcontacts)\n        try:\n            oma_blockedcontacts = resource_lists['oma_blockedcontacts']\n        except KeyError:\n            oma_blockedcontacts = resourcelists.List(name='oma_blockedcontacts')\n            resource_lists.add(oma_blockedcontacts)\n        try:\n            oma_allcontacts = resource_lists['oma_allcontacts']\n        except KeyError:\n            oma_allcontacts = resourcelists.List(name='oma_allcontacts')\n            oma_allcontacts.add(resourcelists.External(self.resource_lists.url + '/~~' + resource_lists.get_xpath(oma_buddylist)))\n            oma_allcontacts.add(resourcelists.External(self.resource_lists.url + '/~~' + resource_lists.get_xpath(oma_grantedcontacts)))\n            oma_allcontacts.add(resourcelists.External(self.resource_lists.url + '/~~' + resource_lists.get_xpath(oma_blockedcontacts)))\n            resource_lists.add(oma_allcontacts)\n\n        try:\n            dialog_grantedcontacts = resource_lists['dialog_grantedcontacts']\n        except KeyError:\n            dialog_grantedcontacts = resourcelists.List(name='dialog_grantedcontacts')\n            resource_lists.add(dialog_grantedcontacts)\n        try:\n            dialog_blockedcontacts = resource_lists['dialog_blockedcontacts']\n        except KeyError:\n            dialog_blockedcontacts = resourcelists.List(name='dialog_blockedcontacts')\n            resource_lists.add(dialog_blockedcontacts)\n\n        try:\n            sipsimple_presence_rls = resource_lists['sipsimple_presence_rls']\n        except KeyError:\n            sipsimple_presence_rls = resourcelists.List(name='sipsimple_presence_rls')\n            resource_lists.add(sipsimple_presence_rls)\n        try:\n            sipsimple_dialog_rls = resource_lists['sipsimple_dialog_rls']\n        except KeyError:\n            sipsimple_dialog_rls = resourcelists.List(name='sipsimple_dialog_rls')\n            resource_lists.add(sipsimple_dialog_rls)\n\n        try:\n            sipsimple_addressbook = resource_lists['sipsimple_addressbook']\n        except KeyError:\n            sipsimple_addressbook = resourcelists.List(name='sipsimple_addressbook')\n            resource_lists.add(sipsimple_addressbook)\n\n        for cls in (cls for cls in sipsimple_addressbook[IterateTypes] if cls not in (addressbook.Contact, addressbook.Group, addressbook.Policy)):\n            del sipsimple_addressbook[cls, All]\n        for cls in (cls for cls in oma_grantedcontacts[IterateTypes] if cls is not resourcelists.Entry):\n            del oma_grantedcontacts[cls, All]\n        for cls in (cls for cls in oma_blockedcontacts[IterateTypes] if cls is not resourcelists.Entry):\n            del oma_blockedcontacts[cls, All]\n        for cls in (cls for cls in dialog_grantedcontacts[IterateTypes] if cls is not resourcelists.Entry):\n            del dialog_grantedcontacts[cls, All]\n        for cls in (cls for cls in dialog_blockedcontacts[IterateTypes] if cls is not resourcelists.Entry):\n            del dialog_blockedcontacts[cls, All]\n        for cls in (cls for cls in sipsimple_presence_rls[IterateTypes] if cls is not resourcelists.Entry):\n            del sipsimple_presence_rls[cls, All]\n        for cls in (cls for cls in sipsimple_dialog_rls[IterateTypes] if cls is not resourcelists.Entry):\n            del sipsimple_dialog_rls[cls, All]\n\n        groups = ItemCollection(sipsimple_addressbook[addressbook.Group, IterateItems])\n        contacts = ItemCollection(sipsimple_addressbook[addressbook.Contact, IterateItems])\n        policies = ItemCollection(sipsimple_addressbook[addressbook.Policy, IterateItems])\n\n        for group, missing_id in [(group, missing_id) for group in groups for missing_id in (id for id in group.contacts if id not in contacts)]:\n            group.contacts.remove(missing_id)\n\n        all_contact_uris = set(uri.uri for contact in contacts for uri in contact.uris)\n\n        contact_allow_presence_uris = set(uri.uri for contact in contacts for uri in contact.uris if contact.presence.policy=='allow')\n        contact_block_presence_uris = set(uri.uri for contact in contacts for uri in contact.uris if contact.presence.policy=='block')\n        contact_allow_dialog_uris = set(uri.uri for contact in contacts for uri in contact.uris if contact.dialog.policy=='allow')\n        contact_block_dialog_uris = set(uri.uri for contact in contacts for uri in contact.uris if contact.dialog.policy=='block')\n        contact_subscribe_presence_uris = set(uri.uri for contact in contacts for uri in contact.uris if contact.presence.subscribe==True)\n        contact_subscribe_dialog_uris = set(uri.uri for contact in contacts for uri in contact.uris if contact.dialog.subscribe==True)\n\n        policy_allow_presence_uris = set(policy.uri for policy in policies if policy.presence.policy=='allow')\n        policy_block_presence_uris = set(policy.uri for policy in policies if policy.presence.policy=='block')\n        policy_allow_dialog_uris = set(policy.uri for policy in policies if policy.dialog.policy=='allow')\n        policy_block_dialog_uris = set(policy.uri for policy in policies if policy.dialog.policy=='block')\n        policy_subscribe_presence_uris = set(policy.uri for policy in policies if policy.presence.subscribe==True)\n        policy_subscribe_dialog_uris = set(policy.uri for policy in policies if policy.dialog.subscribe==True)\n\n        allowed_presence_uris = contact_allow_presence_uris - contact_block_presence_uris | policy_allow_presence_uris - policy_block_presence_uris - all_contact_uris\n        blocked_presence_uris = contact_block_presence_uris | policy_block_presence_uris - all_contact_uris\n        allowed_dialog_uris = contact_allow_dialog_uris - contact_block_dialog_uris | policy_allow_dialog_uris - policy_block_dialog_uris - all_contact_uris\n        blocked_dialog_uris = contact_block_dialog_uris | policy_block_dialog_uris - all_contact_uris\n        subscribe_presence_uris = contact_subscribe_presence_uris | policy_subscribe_presence_uris - all_contact_uris\n        subscribe_dialog_uris = contact_subscribe_dialog_uris | policy_subscribe_dialog_uris - all_contact_uris\n\n        if allowed_presence_uris != set(entry.uri for entry in oma_grantedcontacts):\n            oma_grantedcontacts.clear()\n            oma_grantedcontacts.update(resourcelists.Entry(uri) for uri in allowed_presence_uris)\n        if blocked_presence_uris != set(entry.uri for entry in oma_blockedcontacts):\n            oma_blockedcontacts.clear()\n            oma_blockedcontacts.update(resourcelists.Entry(uri) for uri in blocked_presence_uris)\n        if allowed_dialog_uris != set(entry.uri for entry in dialog_grantedcontacts):\n            dialog_grantedcontacts.clear()\n            dialog_grantedcontacts.update(resourcelists.Entry(uri) for uri in allowed_dialog_uris)\n        if blocked_dialog_uris != set(entry.uri for entry in dialog_blockedcontacts):\n            dialog_blockedcontacts.clear()\n            dialog_blockedcontacts.update(resourcelists.Entry(uri) for uri in blocked_dialog_uris)\n        if subscribe_presence_uris != set(entry.uri for entry in sipsimple_presence_rls):\n            sipsimple_presence_rls.clear()\n            sipsimple_presence_rls.update(resourcelists.Entry(uri) for uri in subscribe_presence_uris)\n        if subscribe_dialog_uris != set(entry.uri for entry in sipsimple_dialog_rls):\n            sipsimple_dialog_rls.clear()\n            sipsimple_dialog_rls.update(resourcelists.Entry(uri) for uri in subscribe_dialog_uris)\n\n        # Normalize rls-services\n        #\n        if self.rls_services.content is None:\n            self.rls_services.content = rlsservices.RLSServices()\n\n        rls_services = self.rls_services.content\n\n        rls_presence_uri = 'sip:' + self.rls_presence_uri\n        rls_dialog_uri   = 'sip:' + self.rls_dialog_uri\n        rls_presence_list = rlsservices.ResourceList(self.resource_lists.url + '/~~' + resource_lists.get_xpath(sipsimple_presence_rls))\n        rls_dialog_list = rlsservices.ResourceList(self.resource_lists.url + '/~~' + resource_lists.get_xpath(sipsimple_dialog_rls))\n\n        try:\n            rls_presence_service = rls_services[rls_presence_uri]\n        except KeyError:\n            rls_presence_service = rlsservices.Service(rls_presence_uri, list=rls_presence_list, packages=['presence'])\n            rls_services.add(rls_presence_service)\n        else:\n            if rls_presence_service.list != rls_presence_list:\n                rls_presence_service.list = rls_presence_list\n            if list(rls_presence_service.packages) != ['presence']:\n                rls_presence_service.packages = ['presence']\n        try:\n            rls_dialog_service = rls_services[rls_dialog_uri]\n        except KeyError:\n            rls_dialog_service = rlsservices.Service(rls_dialog_uri, list=rls_dialog_list, packages=['dialog'])\n            rls_services.add(rls_dialog_service)\n        else:\n            if rls_dialog_service.list != rls_dialog_list:\n                rls_dialog_service.list = rls_dialog_list\n            if list(rls_dialog_service.packages) != ['dialog']:\n                rls_dialog_service.packages = ['dialog']\n\n        # Normalize pres-rules\n        #\n        if self.pres_rules.content is None:\n            self.pres_rules.content = presrules.PresRules()\n\n        def fix_subhandling(rule, valid_values=[]):\n            subhandling_elements = sorted((item for item in rule.actions if isinstance(item, presrules.SubHandling)), key=attrgetter('value.priority'))\n            if not subhandling_elements:\n                subhandling_elements = [presrules.SubHandling('block')] # spec specifies that missing SubHandling means block\n                rule.actions.update(subhandling_elements)\n            subhandling = subhandling_elements.pop()\n            for item in subhandling_elements: # remove any extraneous SubHandling elements\n                rule.actions.remove(item)\n            if subhandling.value not in valid_values:\n                subhandling.value = valid_values[0]\n\n        pres_rules = self.pres_rules.content\n\n        oma_grantedcontacts_ref = omapolicy.ExternalList([self.resource_lists.url + '/~~' + resource_lists.get_xpath(oma_grantedcontacts)])\n        oma_blockedcontacts_ref = omapolicy.ExternalList([self.resource_lists.url + '/~~' + resource_lists.get_xpath(oma_blockedcontacts)])\n\n        try:\n            wp_prs_grantedcontacts = pres_rules['wp_prs_grantedcontacts']\n        except KeyError:\n            wp_prs_grantedcontacts = commonpolicy.Rule('wp_prs_grantedcontacts', conditions=[oma_grantedcontacts_ref], actions=[presrules.SubHandling('allow')])\n            pres_rules.add(wp_prs_grantedcontacts)\n        else:\n            fix_subhandling(wp_prs_grantedcontacts, valid_values=['allow'])\n            if list(wp_prs_grantedcontacts.conditions) != [oma_grantedcontacts_ref]:\n                wp_prs_grantedcontacts.conditions = [oma_grantedcontacts_ref]\n            if wp_prs_grantedcontacts.transformations:\n                wp_prs_grantedcontacts.transformations = None\n        try:\n            wp_prs_blockedcontacts = pres_rules['wp_prs_blockedcontacts']\n        except KeyError:\n            wp_prs_blockedcontacts = commonpolicy.Rule('wp_prs_blockedcontacts', conditions=[oma_blockedcontacts_ref], actions=[presrules.SubHandling('polite-block')])\n            pres_rules.add(wp_prs_blockedcontacts)\n        else:\n            fix_subhandling(wp_prs_blockedcontacts, valid_values=['polite-block'])\n            if list(wp_prs_blockedcontacts.conditions) != [oma_blockedcontacts_ref]:\n                wp_prs_blockedcontacts.conditions = [oma_blockedcontacts_ref]\n            if wp_prs_blockedcontacts.transformations:\n                wp_prs_blockedcontacts.transformations = None\n\n        wp_prs_unlisted = pres_rules.get('wp_prs_unlisted', None)\n        wp_prs_allow_unlisted = pres_rules.get('wp_prs_allow_unlisted', None)\n\n        if wp_prs_unlisted is not None and wp_prs_allow_unlisted is not None:\n            pres_rules.remove(wp_prs_allow_unlisted)\n            wp_prs_allow_unlisted = None\n\n        wp_prs_unlisted_rule = wp_prs_unlisted or wp_prs_allow_unlisted\n\n        if wp_prs_unlisted_rule is None:\n            wp_prs_unlisted = commonpolicy.Rule('wp_prs_unlisted', conditions=[omapolicy.OtherIdentity()], actions=[presrules.SubHandling('confirm')])\n            pres_rules.add(wp_prs_unlisted)\n            wp_prs_unlisted_rule = wp_prs_unlisted\n        else:\n            if wp_prs_unlisted_rule is wp_prs_unlisted:\n                fix_subhandling(wp_prs_unlisted_rule, valid_values=['confirm', 'block', 'polite-block'])\n            else:\n                fix_subhandling(wp_prs_unlisted_rule, valid_values=['allow'])\n            if list(wp_prs_unlisted_rule.conditions) != [omapolicy.OtherIdentity()]:\n                wp_prs_unlisted_rule.conditions = [omapolicy.OtherIdentity()]\n            if wp_prs_unlisted_rule.transformations:\n                wp_prs_unlisted_rule.transformations = None\n\n        match_anonymous = omapolicy.AnonymousRequest()\n        try:\n            wp_prs_block_anonymous = pres_rules['wp_prs_block_anonymous']\n        except KeyError:\n            wp_prs_block_anonymous = commonpolicy.Rule('wp_prs_block_anonymous', conditions=[match_anonymous], actions=[presrules.SubHandling('block')])\n            pres_rules.add(wp_prs_block_anonymous)\n        else:\n            fix_subhandling(wp_prs_block_anonymous, valid_values=['block', 'polite-block'])\n            if list(wp_prs_block_anonymous.conditions) != [match_anonymous]:\n                wp_prs_block_anonymous.conditions = [match_anonymous]\n            if wp_prs_block_anonymous.transformations:\n                wp_prs_block_anonymous.transformations = None\n\n        match_self = commonpolicy.Identity([commonpolicy.IdentityOne('sip:' + self.account.id)])\n        try:\n            wp_prs_allow_own = pres_rules['wp_prs_allow_own']\n        except KeyError:\n            wp_prs_allow_own = commonpolicy.Rule('wp_prs_allow_own', conditions=[match_self], actions=[presrules.SubHandling('allow')])\n            pres_rules.add(wp_prs_allow_own)\n        else:\n            fix_subhandling(wp_prs_allow_own, valid_values=['allow'])\n            if list(wp_prs_allow_own.conditions) != [match_self]:\n                wp_prs_allow_own.conditions = [match_self]\n            if wp_prs_allow_own.transformations:\n                wp_prs_allow_own.transformations = None\n\n        # Remove any other rules\n        all_rule_names = set(pres_rules[IterateIDs])\n        known_rule_names = {'wp_prs_grantedcontacts', 'wp_prs_blockedcontacts', 'wp_prs_unlisted', 'wp_prs_allow_unlisted', 'wp_prs_block_anonymous', 'wp_prs_allow_own'}\n        for name in all_rule_names - known_rule_names:\n            del pres_rules[name]\n\n        del fix_subhandling\n\n        # Normalize dialog-rules\n        #\n        if self.dialog_rules.supported:\n            if self.dialog_rules.content is None:\n                self.dialog_rules.content = dialogrules.DialogRules()\n            elif self.dialog_rules.content.element.nsmap.get('dr') != dialogrules.namespace:  # TODO: this elif branch should be removed in a later version as it is\n                self.dialog_rules.content = dialogrules.DialogRules()                         # only used to discard documents created with the old namespace. -Dan\n\n            def fix_subhandling(rule, valid_values=()):\n                subhandling_elements = sorted((item for item in rule.actions if isinstance(item, dialogrules.SubHandling)), key=attrgetter('value.priority'))\n                if not subhandling_elements:\n                    subhandling_elements = [dialogrules.SubHandling('block')] # spec specifies that missing SubHandling means block\n                    rule.actions.update(subhandling_elements)\n                subhandling = subhandling_elements.pop()\n                for item in subhandling_elements: # remove any extraneous SubHandling elements\n                    rule.actions.remove(item)\n                if subhandling.value not in valid_values:\n                    subhandling.value = valid_values[0]\n\n            dialog_rules = self.dialog_rules.content\n\n            dialog_grantedcontacts_ref = omapolicy.ExternalList([self.resource_lists.url + '/~~' + resource_lists.get_xpath(dialog_grantedcontacts)])\n            dialog_blockedcontacts_ref = omapolicy.ExternalList([self.resource_lists.url + '/~~' + resource_lists.get_xpath(dialog_blockedcontacts)])\n\n            try:\n                wp_dlg_grantedcontacts = dialog_rules['wp_dlg_grantedcontacts']\n            except KeyError:\n                wp_dlg_grantedcontacts = commonpolicy.Rule('wp_dlg_grantedcontacts', conditions=[dialog_grantedcontacts_ref], actions=[dialogrules.SubHandling('allow')])\n                dialog_rules.add(wp_dlg_grantedcontacts)\n            else:\n                fix_subhandling(wp_dlg_grantedcontacts, valid_values=['allow'])\n                if list(wp_dlg_grantedcontacts.conditions) != [dialog_grantedcontacts_ref]:\n                    wp_dlg_grantedcontacts.conditions = [dialog_grantedcontacts_ref]\n                if wp_dlg_grantedcontacts.transformations:\n                    wp_dlg_grantedcontacts.transformations = None\n            try:\n                wp_dlg_blockedcontacts = dialog_rules['wp_dlg_blockedcontacts']\n            except KeyError:\n                wp_dlg_blockedcontacts = commonpolicy.Rule('wp_dlg_blockedcontacts', conditions=[dialog_blockedcontacts_ref], actions=[dialogrules.SubHandling('polite-block')])\n                dialog_rules.add(wp_dlg_blockedcontacts)\n            else:\n                fix_subhandling(wp_dlg_blockedcontacts, valid_values=['polite-block'])\n                if list(wp_dlg_blockedcontacts.conditions) != [dialog_blockedcontacts_ref]:\n                    wp_dlg_blockedcontacts.conditions = [dialog_blockedcontacts_ref]\n                if wp_dlg_blockedcontacts.transformations:\n                    wp_dlg_blockedcontacts.transformations = None\n\n            wp_dlg_unlisted = dialog_rules.get('wp_dlg_unlisted', None)\n            wp_dlg_allow_unlisted = dialog_rules.get('wp_dlg_allow_unlisted', None)\n\n            if wp_dlg_unlisted is not None and wp_dlg_allow_unlisted is not None:\n                dialog_rules.remove(wp_dlg_allow_unlisted)\n                wp_dlg_allow_unlisted = None\n\n            wp_dlg_unlisted_rule = wp_dlg_unlisted or wp_dlg_allow_unlisted\n\n            if wp_dlg_unlisted_rule is None:\n                wp_dlg_unlisted = commonpolicy.Rule('wp_dlg_unlisted', conditions=[omapolicy.OtherIdentity()], actions=[dialogrules.SubHandling('confirm')])\n                dialog_rules.add(wp_dlg_unlisted)\n                wp_dlg_unlisted_rule = wp_dlg_unlisted\n            else:\n                if wp_dlg_unlisted_rule is wp_dlg_unlisted:\n                    fix_subhandling(wp_dlg_unlisted_rule, valid_values=['confirm', 'block', 'polite-block'])\n                else:\n                    fix_subhandling(wp_dlg_unlisted_rule, valid_values=['allow'])\n                if list(wp_dlg_unlisted_rule.conditions) != [omapolicy.OtherIdentity()]:\n                    wp_dlg_unlisted_rule.conditions = [omapolicy.OtherIdentity()]\n                if wp_dlg_unlisted_rule.transformations:\n                    wp_dlg_unlisted_rule.transformations = None\n\n            match_anonymous = omapolicy.AnonymousRequest()\n            try:\n                wp_dlg_block_anonymous = dialog_rules['wp_dlg_block_anonymous']\n            except KeyError:\n                wp_dlg_block_anonymous = commonpolicy.Rule('wp_dlg_block_anonymous', conditions=[match_anonymous], actions=[dialogrules.SubHandling('block')])\n                dialog_rules.add(wp_dlg_block_anonymous)\n            else:\n                fix_subhandling(wp_dlg_block_anonymous, valid_values=['block', 'polite-block'])\n                if list(wp_dlg_block_anonymous.conditions) != [match_anonymous]:\n                    wp_dlg_block_anonymous.conditions = [match_anonymous]\n                if wp_dlg_block_anonymous.transformations:\n                    wp_dlg_block_anonymous.transformations = None\n\n            match_self = commonpolicy.Identity([commonpolicy.IdentityOne('sip:' + self.account.id)])\n            try:\n                wp_dlg_allow_own = dialog_rules['wp_dlg_allow_own']\n            except KeyError:\n                wp_dlg_allow_own = commonpolicy.Rule('wp_dlg_allow_own', conditions=[match_self], actions=[dialogrules.SubHandling('allow')])\n                dialog_rules.add(wp_dlg_allow_own)\n            else:\n                fix_subhandling(wp_dlg_allow_own, valid_values=['allow'])\n                if list(wp_dlg_allow_own.conditions) != [match_self]:\n                    wp_dlg_allow_own.conditions = [match_self]\n                if wp_dlg_allow_own.transformations:\n                    wp_dlg_allow_own.transformations = None\n\n            # Remove any other rules\n            all_rule_names = set(dialog_rules[IterateIDs])\n            known_rule_names = {'wp_dlg_grantedcontacts', 'wp_dlg_blockedcontacts', 'wp_dlg_unlisted', 'wp_dlg_allow_unlisted', 'wp_dlg_block_anonymous', 'wp_dlg_allow_own'}\n            for name in all_rule_names - known_rule_names:\n                del dialog_rules[name]\n\n        # Normalize status icon\n        #\n        if self.status_icon.supported and self.status_icon.content is not None:\n            content = self.status_icon.content\n            if None in (content.encoding, content.mime_type) or content.encoding.value.lower() != 'base64' or content.mime_type.value.lower() not in Icon.__mimetypes__:\n                self.status_icon.content = None\n                self.status_icon.dirty = True\n\n    def _OH_AddContactOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        contact = operation.contact\n        presence_handling = addressbook.PresenceHandling(contact.presence.policy, contact.presence.subscribe)\n        dialog_handling = addressbook.DialogHandling(contact.dialog.policy, contact.dialog.subscribe)\n        xml_contact = addressbook.Contact(contact.id, contact.name, presence_handling=presence_handling, dialog_handling=dialog_handling)\n        for uri in contact.uris:\n            contact_uri = addressbook.ContactURI(uri.id, uri.uri, uri.type)\n            contact_uri.attributes = addressbook.ContactURI.attributes.type(uri.attributes)\n            xml_contact.uris.add(contact_uri)\n        xml_contact.uris.default = contact.uris.default\n        xml_contact.attributes = addressbook.Contact.attributes.type(contact.attributes)\n        sipsimple_addressbook.add(xml_contact)\n\n    def _OH_UpdateContactOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        try:\n            contact = sipsimple_addressbook[addressbook.Contact, operation.contact.id]\n        except KeyError:\n            return\n        attributes = dict(operation.attributes)\n        attributes.pop('id', None) # id is never modified\n        attributes.pop('uris', None) # uris are modified using dedicated methods\n        if 'name' in attributes:\n            contact.name = attributes.pop('name')\n        if 'uris.default' in attributes:\n            contact.uris.default = attributes.pop('uris.default')\n        if 'presence.policy' in attributes:\n            contact.presence.policy = attributes.pop('presence.policy')\n        if 'presence.subscribe' in attributes:\n            contact.presence.subscribe = attributes.pop('presence.subscribe')\n        if 'dialog.policy' in attributes:\n            contact.dialog.policy = attributes.pop('dialog.policy')\n        if 'dialog.subscribe' in attributes:\n            contact.dialog.subscribe = attributes.pop('dialog.subscribe')\n        if contact.attributes is None:\n            contact.attributes = addressbook.Contact.attributes.type()\n        contact.attributes.update(attributes)\n\n    def _OH_RemoveContactOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        for group in (group for group in sipsimple_addressbook[addressbook.Group, IterateItems] if operation.contact.id in group.contacts):\n            group.contacts.remove(operation.contact.id)\n        try:\n            del sipsimple_addressbook[addressbook.Contact, operation.contact.id]\n        except KeyError:\n            pass\n\n    def _OH_AddContactURIOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        try:\n            contact = sipsimple_addressbook[addressbook.Contact, operation.contact.id]\n        except KeyError:\n            return\n        uri = addressbook.ContactURI(operation.uri.id, operation.uri.uri, operation.uri.type)\n        uri.attributes = addressbook.ContactURI.attributes.type(operation.uri.attributes)\n        contact.uris.add(uri)\n\n    def _OH_UpdateContactURIOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        try:\n            contact = sipsimple_addressbook[addressbook.Contact, operation.contact.id]\n            uri = contact.uris[operation.uri.id]\n        except KeyError:\n            return\n        attributes = dict(operation.attributes)\n        attributes.pop('id', None) # id is never modified\n        if 'uri' in attributes:\n            uri.uri = attributes.pop('uri')\n        if 'type' in attributes:\n            uri.type = attributes.pop('type')\n        if uri.attributes is None:\n            uri.attributes = addressbook.ContactURI.attributes.type()\n        uri.attributes.update(attributes)\n\n    def _OH_RemoveContactURIOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        try:\n            contact = sipsimple_addressbook[addressbook.Contact, operation.contact.id]\n            del contact.uris[operation.uri.id]\n        except KeyError:\n            pass\n\n    def _OH_AddGroupOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        group = addressbook.Group(operation.group.id, operation.group.name, [contact.id for contact in operation.group.contacts])\n        group.attributes = addressbook.Group.attributes.type(operation.group.attributes)\n        sipsimple_addressbook.add(group)\n\n    def _OH_UpdateGroupOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        try:\n            group = sipsimple_addressbook[addressbook.Group, operation.group.id]\n        except KeyError:\n            return\n        attributes = dict(operation.attributes)\n        attributes.pop('id', None) # id is never modified\n        attributes.pop('contacts', None) # contacts are added/removed using dedicated methods\n        if 'name' in attributes:\n            group.name = attributes.pop('name')\n        if group.attributes is None:\n            group.attributes = addressbook.Group.attributes.type()\n        group.attributes.update(attributes)\n\n    def _OH_RemoveGroupOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        try:\n            del sipsimple_addressbook[addressbook.Group, operation.group.id]\n        except KeyError:\n            pass\n\n    def _OH_AddGroupMemberOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        try:\n            group = sipsimple_addressbook[addressbook.Group, operation.group.id]\n        except KeyError:\n            return\n        if operation.contact.id in group.contacts:\n            return\n        group.contacts.add(operation.contact.id)\n\n    def _OH_RemoveGroupMemberOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        try:\n            group = sipsimple_addressbook[addressbook.Group, operation.group.id]\n            group.contacts.remove(operation.contact.id)\n        except KeyError:\n            return\n\n    def _OH_AddPolicyOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        presence_handling = addressbook.PresenceHandling(operation.policy.presence.policy, operation.policy.presence.subscribe)\n        dialog_handling = addressbook.DialogHandling(operation.policy.dialog.policy, operation.policy.dialog.subscribe)\n        policy = addressbook.Policy(operation.policy.id, operation.policy.uri, operation.policy.name, presence_handling=presence_handling, dialog_handling=dialog_handling)\n        policy.attributes = addressbook.Policy.attributes.type(operation.policy.attributes)\n        sipsimple_addressbook.add(policy)\n\n    def _OH_UpdatePolicyOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        try:\n            policy = sipsimple_addressbook[addressbook.Policy, operation.policy.id]\n        except KeyError:\n            return\n        attributes = dict(operation.attributes)\n        attributes.pop('id', None) # id is never modified\n        if 'uri' in attributes:\n            policy.uri = attributes.pop('uri')\n        if 'name' in attributes:\n            policy.name = attributes.pop('name')\n        if 'presence.policy' in attributes:\n            policy.presence.policy = attributes.pop('presence.policy')\n        if 'presence.subscribe' in attributes:\n            policy.presence.subscribe = attributes.pop('presence.subscribe')\n        if 'dialog.policy' in attributes:\n            policy.dialog.policy = attributes.pop('dialog.policy')\n        if 'dialog.subscribe' in attributes:\n            policy.dialog.subscribe = attributes.pop('dialog.subscribe')\n        if policy.attributes is None:\n            policy.attributes = addressbook.Policy.attributes.type()\n        policy.attributes.update(attributes)\n\n    def _OH_RemovePolicyOperation(self, operation):\n        sipsimple_addressbook = self.resource_lists.content['sipsimple_addressbook']\n        try:\n            del sipsimple_addressbook[addressbook.Policy, operation.policy.id]\n        except KeyError:\n            pass\n\n    def _OH_SetStatusIconOperation(self, operation):\n        if not self.status_icon.supported:\n            return\n        icon = operation.icon\n        if icon is None or not icon.data:\n            self.status_icon.dirty = self.status_icon.content is not None\n            self.status_icon.content = None\n        else:\n            content = prescontent.PresenceContent(data=base64.encodestring(icon.data), mime_type=icon.mime_type, encoding='base64', description=icon.description)\n            if self.status_icon.content == content:\n                return\n            self.status_icon.content = content\n\n    def _OH_SetOfflineStatusOperation(self, operation):\n        pidf = operation.status.pidf if operation.status is not None else None\n        if not self.pidf_manipulation.supported or pidf == self.pidf_manipulation.content:\n            return\n        self.pidf_manipulation.content = pidf\n        self.pidf_manipulation.dirty = True\n\n    def _OH_SetDefaultPresencePolicyOperation(self, operation):\n        pres_rules = self.pres_rules.content\n        if operation.policy == 'allow':\n            rule_id, other_rule_id = 'wp_prs_allow_unlisted', 'wp_prs_unlisted'\n        else:\n            rule_id, other_rule_id = 'wp_prs_unlisted', 'wp_prs_allow_unlisted'\n        try:\n            del pres_rules[other_rule_id]\n        except KeyError:\n            rule = pres_rules[rule_id]\n            subhandling = next(item for item in rule.actions if isinstance(item, presrules.SubHandling))\n            subhandling.value = operation.policy\n        else:\n            rule = commonpolicy.Rule(rule_id, conditions=[omapolicy.OtherIdentity()], actions=[presrules.SubHandling(operation.policy)])\n            pres_rules.add(rule)\n\n    def _OH_SetDefaultDialogPolicyOperation(self, operation):\n        if not self.dialog_rules.supported:\n            return\n        dialog_rules = self.dialog_rules.content\n        if operation.policy == 'allow':\n            rule_id, other_rule_id = 'wp_dlg_allow_unlisted', 'wp_dlg_unlisted'\n        else:\n            rule_id, other_rule_id = 'wp_dlg_unlisted', 'wp_dlg_allow_unlisted'\n        try:\n            del dialog_rules[other_rule_id]\n        except KeyError:\n            rule = dialog_rules[rule_id]\n            subhandling = next(item for item in rule.actions if isinstance(item, dialogrules.SubHandling))\n            subhandling.value = operation.policy\n        else:\n            rule = commonpolicy.Rule(rule_id, conditions=[omapolicy.OtherIdentity()], actions=[dialogrules.SubHandling(operation.policy)])\n            dialog_rules.add(rule)\n\n    # Notification handlers\n    #\n\n    @run_in_twisted_thread\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    @run_in_green_thread\n    def _NH_CFGSettingsObjectDidChange(self, notification):\n        if {'__id__', 'xcap.xcap_root', 'auth.username', 'auth.password', 'sip.subscribe_interval', 'sip.transport_list'}.intersection(notification.data.modified):\n            self.command_channel.send(Command('reload', modified=notification.data.modified))\n        if 'enabled' in notification.data.modified:\n            return  # global account activation is handled separately by the account itself\n        if self.account.enabled and 'xcap.enabled' in notification.data.modified:\n            if self.account.xcap.enabled:\n                self.start()\n            else:\n                self.stop()\n\n    def _NH_CFGSettingsObjectWasDeleted(self, notification):\n        notification.center.remove_observer(self, sender=self.account, name='CFGSettingsObjectDidChange')\n        notification.center.remove_observer(self, sender=self.account, name='CFGSettingsObjectWasDeleted')\n        self.command_channel.send(Command('stop'))\n        self.command_channel.send(Command('cleanup'))\n\n    def _NH_XCAPSubscriptionDidStart(self, notification):\n        self.command_channel.send(Command('fetch', documents=set(self.document_names)))\n\n    def _NH_XCAPSubscriptionDidFail(self, notification):\n        self.command_channel.send(Command('fetch', documents=set(self.document_names)))\n\n    def _NH_XCAPSubscriptionGotNotify(self, notification):\n        if notification.data.content_type == xcapdiff.XCAPDiffDocument.content_type:\n            try:\n                xcap_diff = xcapdiff.XCAPDiffDocument.parse(notification.data.body)\n            except ParserError:\n                self.command_channel.send(Command('fetch', documents=set(self.document_names)))\n            else:\n                applications = set(child.selector.auid for child in xcap_diff if isinstance(child, xcapdiff.Document))\n                documents = set(document.name for document in self.documents if document.application in applications)\n                self.command_channel.send(Command('fetch', documents=documents))\n\n    def _load_data(self):\n        addressbook = Addressbook.from_payload(self.resource_lists.content['sipsimple_addressbook'])\n\n        default_presence_rule = self.pres_rules.content.get('wp_prs_unlisted', None) or self.pres_rules.content.get('wp_prs_allow_unlisted', None)\n        if self.dialog_rules.supported:\n            default_dialog_rule = self.dialog_rules.content.get('wp_dlg_unlisted', None) or self.dialog_rules.content.get('wp_dlg_allow_unlisted', None)\n        else:\n            default_dialog_rule = None\n        presence_rules = PresenceRules.from_payload(default_presence_rule)\n        dialog_rules = DialogRules.from_payload(default_dialog_rule)\n\n        if self.status_icon.supported and self.status_icon.content:\n            status_icon = Icon.from_payload(self.status_icon.content)\n            status_icon.url = self.status_icon.url\n            status_icon.etag = self.status_icon.etag\n        else:\n            status_icon = None\n\n        if self.pidf_manipulation.supported and self.pidf_manipulation.content:\n            offline_status = OfflineStatus(self.pidf_manipulation.content)\n        else:\n            offline_status = None\n\n        data=NotificationData(addressbook=addressbook, presence_rules=presence_rules, dialog_rules=dialog_rules, status_icon=status_icon, offline_status=offline_status)\n        NotificationCenter().post_notification('XCAPManagerDidReloadData', sender=self, data=data)\n\n    def _fetch_documents(self, documents):\n        workers = [Worker.spawn(document.fetch) for document in (doc for doc in self.documents if doc.name in documents and doc.supported)]\n        try:\n            while workers:\n                worker = workers.pop()\n                worker.wait()\n        finally:\n            for worker in workers:\n                worker.wait_ex()\n\n    def _save_journal(self):\n        try:\n            self.storage.save('journal', cPickle.dumps(self.journal))\n        except XCAPStorageError:\n            pass\n\n    def _schedule_command(self, timeout, command):\n        from twisted.internet import reactor\n        timer = reactor.callLater(timeout, self.command_channel.send, command)\n        timer.command = command\n        return timer\n\n\nclass XCAPTransaction(object):\n    def __init__(self, xcap_manager):\n        self.xcap_manager = xcap_manager\n\n    def __enter__(self):\n        self.xcap_manager.start_transaction()\n        return self\n\n    def __exit__(self, type, value, traceback):\n        self.xcap_manager.commit_transaction()\n\n\n"
  },
  {
    "path": "sipsimple/account/xcap/storage/__init__.py",
    "content": "\n\"\"\"Base definitions for concrete implementations of XCAP storage backends\"\"\"\n\n__all__ = ['IXCAPStorage', 'XCAPStorageError']\n\n\nfrom zope.interface import Interface\n\n\nclass XCAPStorageError(Exception):\n    \"\"\"Base error to be used by backends implementing IXCAPStorage.\"\"\"\n\n\nclass IXCAPStorage(Interface):\n    \"\"\"Interface describing a storage backend for XCAP data.\"\"\"\n\n    def load(name):\n        \"\"\"\n        Load and return the data corresponding to the given name by\n        using whatever means employed by the backend implementation.\n        \"\"\"\n\n    def save(name, data):\n        \"\"\"\n        Store the data associated with name by using whatever means\n        employed by the backend implementation.\n        \"\"\"\n\n    def delete(name):\n        \"\"\"Delete the data associated with name.\"\"\"\n\n    def purge():\n        \"\"\"Delete all the data stored by the backend.\"\"\"\n\n\n"
  },
  {
    "path": "sipsimple/account/xcap/storage/file.py",
    "content": "\n\"\"\"XCAP backend for storing data in files\"\"\"\n\n__all__ = [\"FileStorage\"]\n\nimport errno\nimport os\nimport platform\nimport random\n\nfrom application.system import makedirs, openfile, unlink\nfrom zope.interface import implements\n\nfrom sipsimple.account.xcap.storage import IXCAPStorage, XCAPStorageError\n\n\nclass FileStorage(object):\n    \"\"\"Implementation of an XCAP backend that stores data in files.\"\"\"\n\n    implements(IXCAPStorage)\n\n    def __init__(self, directory, account_id):\n        \"\"\"Initialize the storage for the specified directory and account ID\"\"\"\n        self.directory = directory\n        self.account_id = account_id\n        self.names = set()\n\n    def load(self, name):\n        \"\"\"Read the file given by name and return its content.\"\"\"\n        try:\n            document = open(os.path.join(self.directory, self.account_id, name)).read()\n        except (IOError, OSError), e:\n            raise XCAPStorageError(\"failed to load XCAP data for %s/%s: %s\" % (self.account_id, name, str(e)))\n        else:\n            self.names.add(name)\n            return document\n\n    def save(self, name, data):\n        \"\"\"Write the data in a file identified by name.\"\"\"\n        filename = os.path.join(self.directory, self.account_id, name)\n        tmp_filename = '%s.%d.%08X' % (filename, os.getpid(), random.getrandbits(32))\n        try:\n            makedirs(os.path.join(self.directory, self.account_id))\n            file = openfile(tmp_filename, 'wb', permissions=0600)\n            file.write(data)\n            file.close()\n            if platform.system() == 'Windows':\n                # os.rename does not work on Windows if the destination file already exists.\n                # It seems there is no atomic way to do this on Windows.\n                unlink(filename)\n            os.rename(tmp_filename, filename)\n        except (IOError, OSError), e:\n            raise XCAPStorageError(\"failed to save XCAP data for %s/%s: %s\" % (self.account_id, name, str(e)))\n        else:\n            self.names.add(name)\n\n    def delete(self, name):\n        \"\"\"Delete the data stored in the file identified by name\"\"\"\n        try:\n            os.unlink(os.path.join(self.directory, self.account_id, name))\n        except OSError, e:\n            if e.errno == errno.ENOENT:\n                self.names.discard(name)\n                return\n            raise XCAPStorageError(\"failed to delete XCAP data for %s/%s: %s\" % (self.account_id, name, str(e)))\n        else:\n            self.names.remove(name)\n\n    def purge(self):\n        \"\"\"Delete all the files stored by the backend\"\"\"\n        failed = []\n        for name in self.names:\n            try:\n                os.unlink(os.path.join(self.directory, self.account_id, name))\n            except OSError, e:\n                if e.errno == errno.ENOENT:\n                    continue\n                failed.append(name)\n        self.names.clear()\n        try:\n            os.rmdir(os.path.join(self.directory, self.account_id))\n        except OSError:\n            pass\n        if failed:\n            raise XCAPStorageError(\"the following files could not be deleted for %s: %s\" % (self.account_id, ', '.join(failed)))\n\n\n"
  },
  {
    "path": "sipsimple/account/xcap/storage/memory.py",
    "content": "\n\"\"\"XCAP backend for storing data in memory\"\"\"\n\n__all__ = [\"MemoryStorage\"]\n\nfrom zope.interface import implements\nfrom sipsimple.account.xcap.storage import IXCAPStorage, XCAPStorageError\n\n\nclass MemoryStorage(object):\n    \"\"\"Implementation of an XCAP backend that stores data in memory\"\"\"\n\n    implements(IXCAPStorage)\n\n    def __init__(self, account_id):\n        \"\"\"Initialize the backend for the specified account ID\"\"\"\n        self.account_id = account_id\n        self.data = {}\n\n    def load(self, name):\n        \"\"\"Return the data given by name\"\"\"\n        try:\n            return self.data[name]\n        except KeyError:\n            raise XCAPStorageError(\"missing entry: %s/%s\" % (self.account_id, name))\n\n    def save(self, name, data):\n        \"\"\"Store the data under a key given by name\"\"\"\n        self.data[name] = data\n\n    def delete(self, name):\n        \"\"\"Delete the data identified by name\"\"\"\n        self.data.pop(name, None)\n\n    def purge(self):\n        \"\"\"Delete all the data that is stored in the backend\"\"\"\n        self.data.clear()\n\n\n"
  },
  {
    "path": "sipsimple/addressbook.py",
    "content": "\n\"\"\"Implementation of an addressbook management system\"\"\"\n\nfrom __future__ import absolute_import\n\n__all__ = ['AddressbookManager', 'Contact', 'ContactURI', 'Group', 'Policy', 'SharedSetting', 'ContactExtension', 'ContactURIExtension', 'GroupExtension', 'PolicyExtension']\n\nfrom functools import reduce\nfrom operator import attrgetter\nfrom random import randint\nfrom threading import Lock\nfrom time import time\nfrom zope.interface import implements\n\nfrom application.notification import IObserver, NotificationCenter, NotificationData\nfrom application.python import Null\nfrom application.python.decorator import execute_once\nfrom application.python.types import Singleton, MarkerType\nfrom application.python.weakref import defaultweakobjectmap\n\nfrom sipsimple import log\nfrom sipsimple.account import xcap, AccountManager\nfrom sipsimple.configuration import ConfigurationManager, ObjectNotFoundError, DuplicateIDError, PersistentKey, ModifiedValue, ModifiedList\nfrom sipsimple.configuration import AbstractSetting, RuntimeSetting, SettingsObjectImmutableID, SettingsGroup, SettingsGroupMeta, SettingsState, ItemCollection, ItemManagement\nfrom sipsimple.payloads.addressbook import PolicyValue, ElementAttributes\nfrom sipsimple.payloads.datatypes import ID\nfrom sipsimple.payloads.resourcelists import ResourceListsDocument\nfrom sipsimple.threading import run_in_thread\n\n\ndef unique_id(prefix='id'):\n    return \"%s%d%06d\" % (prefix, time()*1e6, randint(0, 999999))\n\n\ndef recursive_getattr(obj, name):\n    return reduce(getattr, name.split('.'), obj)\n\n\nclass Local(object):\n    __metaclass__ = MarkerType\n\n\nclass Remote(object):\n    def __init__(self, account, xcap_object):\n        self.account = account\n        self.xcap_object = xcap_object\n    def __repr__(self):\n        return \"%s(%r, %r)\" % (self.__class__.__name__, self.account, self.xcap_object)\n\n\nclass Setting(AbstractSetting):\n    \"\"\"\n    Descriptor representing a setting in an addressbook object.\n\n    Unlike a standard Setting, this one will only use the default value as a\n    template to fill in a missing value and explicitly set it when saving if\n    it was not specified explicitly prior to that.\n    \"\"\"\n\n    def __init__(self, type, default=None, nillable=False):\n        if default is None and not nillable:\n            raise TypeError(\"default must be specified if object is not nillable\")\n        self.type = type\n        self.default = default\n        self.nillable = nillable\n        self.values = defaultweakobjectmap(lambda: default)\n        self.oldvalues = defaultweakobjectmap(lambda: default)\n        self.dirty = defaultweakobjectmap(bool)\n        self.lock = Lock()\n\n    def __get__(self, obj, objtype):\n        if obj is None:\n            return self\n        with self.lock:\n            return self.values[obj]\n\n    def __set__(self, obj, value):\n        if value is None and not self.nillable:\n            raise ValueError(\"setting attribute is not nillable\")\n        if value is not None and not isinstance(value, self.type):\n            value = self.type(value)\n        with self.lock:\n            self.values[obj] = value\n            self.dirty[obj] = value != self.oldvalues[obj]\n\n    def __getstate__(self, obj):\n        with self.lock:\n            value = self.values[obj]\n        if value is None:\n            pass\n        elif issubclass(self.type, bool):\n            value = u'true' if value else u'false'\n        elif issubclass(self.type, (int, long, basestring)):\n            value = unicode(value)\n        elif hasattr(value, '__getstate__'):\n            value = value.__getstate__()\n        else:\n            value = unicode(value)\n        return value\n\n    def __setstate__(self, obj, value):\n        if value is None and not self.nillable:\n            raise ValueError(\"setting attribute is not nillable\")\n        if value is None:\n            pass\n        elif issubclass(self.type, bool):\n            if value.lower() in ('true', 'yes', 'on', '1'):\n                value = True\n            elif value.lower() in ('false', 'no', 'off', '0'):\n                value = False\n            else:\n                raise ValueError(\"invalid boolean value: %s\" % (value,))\n        elif issubclass(self.type, (int, long, basestring)):\n            value = self.type(value)\n        elif hasattr(self.type, '__setstate__'):\n            object = self.type.__new__(self.type)\n            object.__setstate__(value)\n            value = object\n        else:\n            value = self.type(value)\n        with self.lock:\n            self.oldvalues[obj] = self.values[obj] = value\n            self.dirty[obj] = False\n\n    def get_modified(self, obj):\n        with self.lock:\n            try:\n                if self.dirty[obj]:\n                    return ModifiedValue(old=self.oldvalues[obj], new=self.values[obj])\n                else:\n                    return None\n            finally:\n                self.oldvalues[obj] = self.values[obj]\n                self.dirty[obj] = False\n\n    def get_old(self, obj):\n        with self.lock:\n            return self.oldvalues[obj]\n\n    def undo(self, obj):\n        with self.lock:\n            self.values[obj] = self.oldvalues[obj]\n            self.dirty[obj] = False\n\n\nclass SharedSetting(Setting):\n    \"\"\"A setting that is shared by being also stored remotely in XCAP\"\"\"\n\n    __namespace__ = None\n\n    @classmethod\n    def set_namespace(cls, namespace):\n        \"\"\"\n        Set the XML namespace to be used for the extra shared attributes of\n        a contact, when storing it in XCAP\n        \"\"\"\n        if cls.__namespace__ is not None:\n            raise RuntimeError(\"namespace already set to %s\" % cls.__namespace__)\n        cls.__namespace__ = namespace\n        class ApplicationElementAttributes(ElementAttributes):\n            _xml_namespace = 'urn:%s:xml:ns:addressbook' % namespace\n        ResourceListsDocument.unregister_namespace(ElementAttributes._xml_namespace)\n        ResourceListsDocument.register_namespace(ApplicationElementAttributes._xml_namespace, prefix=namespace.rpartition(':')[2])\n        for cls, attribute_name in ((cls, name) for cls in ResourceListsDocument.element_map.values() for name, elem in cls._xml_element_children.items() if elem.type is ElementAttributes):\n            cls.unregister_extension(attribute_name)\n            cls.register_extension(attribute_name, ApplicationElementAttributes)\n\n\nclass AddressbookKey(object):\n    def __init__(self, section):\n        self.group = 'Addressbook'\n        self.section = section\n    def __get__(self, obj, objtype):\n        if obj is None:\n            return [self.group, self.section]\n        else:\n            return [self.group, self.section, PersistentKey(obj.__id__)]\n    def __set__(self, obj, value):\n        raise AttributeError('cannot set attribute')\n    def __delete__(self, obj):\n        raise AttributeError('cannot delete attribute')\n\n\nclass MultiAccountTransaction(object):\n    def __init__(self, accounts):\n        self.accounts = accounts\n\n    def __enter__(self):\n        for account in self.accounts:\n            account.xcap_manager.start_transaction()\n        return self\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        for account in self.accounts:\n            account.xcap_manager.commit_transaction()\n\n    def __iter__(self):\n        return iter(self.accounts)\n\n\nclass XCAPGroup(xcap.Group):\n    \"\"\"An XCAP Group with attributes normalized to unicode\"\"\"\n\n    __attributes__ = set()\n\n    def __init__(self, id, name, contacts, **attributes):\n        normalized_attributes = dict((name, unicode(value) if value is not None else None) for name, value in attributes.iteritems() if name in self.__attributes__)\n        contacts = [XCAPContact.normalize(contact) for contact in contacts]\n        super(XCAPGroup, self).__init__(id, name, contacts, **normalized_attributes)\n\n    @classmethod\n    def normalize(cls, group):\n        return cls(group.id, group.name, group.contacts, **group.attributes)\n\n    def get_modified(self, modified_keys):\n        names = {'name'}\n        attributes = dict((name, getattr(self, name)) for name in names.intersection(modified_keys))\n        attributes.update((name, self.attributes[name]) for name in self.__attributes__.intersection(modified_keys))\n        return attributes\n\n\nclass XCAPContactURI(xcap.ContactURI):\n    \"\"\"An XCAP ContactURI with attributes normalized to unicode\"\"\"\n\n    __attributes__ = set()\n\n    def __init__(self, id, uri, type, **attributes):\n        normalized_attributes = dict((name, unicode(value) if value is not None else None) for name, value in attributes.iteritems() if name in self.__attributes__)\n        super(XCAPContactURI, self).__init__(id, uri, type, **normalized_attributes)\n\n    @classmethod\n    def normalize(cls, uri):\n        return cls(uri.id, uri.uri, uri.type, **uri.attributes)\n\n    def get_modified(self, modified_keys):\n        names = {'uri', 'type'}\n        attributes = dict((name, getattr(self, name)) for name in names.intersection(modified_keys))\n        attributes.update((name, self.attributes[name]) for name in self.__attributes__.intersection(modified_keys))\n        return attributes\n\n\nclass XCAPContact(xcap.Contact):\n    \"\"\"An XCAP Contact with attributes normalized to unicode\"\"\"\n\n    __attributes__ = set()\n\n    def __init__(self, id, name, uris, presence_handling=None, dialog_handling=None, **attributes):\n        normalized_attributes = dict((name, unicode(value) if value is not None else None) for name, value in attributes.iteritems() if name in self.__attributes__)\n        uris = xcap.ContactURIList((XCAPContactURI.normalize(uri) for uri in uris), default=getattr(uris, 'default', None))\n        super(XCAPContact, self).__init__(id, name, uris, presence_handling, dialog_handling, **normalized_attributes)\n\n    @classmethod\n    def normalize(cls, contact):\n        return cls(contact.id, contact.name, contact.uris, contact.presence, contact.dialog, **contact.attributes)\n\n    def get_modified(self, modified_keys):\n        names = {'name', 'uris.default', 'presence.policy', 'presence.subscribe', 'dialog.policy', 'dialog.subscribe'}\n        attributes = dict((name, recursive_getattr(self, name)) for name in names.intersection(modified_keys))\n        attributes.update((name, self.attributes[name]) for name in self.__attributes__.intersection(modified_keys))\n        return attributes\n\n\nclass XCAPPolicy(xcap.Policy):\n    \"\"\"An XCAP Policy with attributes normalized to unicode\"\"\"\n\n    __attributes__ = set()\n\n    def __init__(self, id, uri, name, presence_handling=None, dialog_handling=None, **attributes):\n        normalized_attributes = dict((name, unicode(value) if value is not None else None) for name, value in attributes.iteritems() if name in self.__attributes__)\n        super(XCAPPolicy, self).__init__(id, uri, name, presence_handling, dialog_handling, **normalized_attributes)\n\n    @classmethod\n    def normalize(cls, policy):\n        return cls(policy.id, policy.uri, policy.name, policy.presence, policy.dialog, **policy.attributes)\n\n    def get_modified(self, modified_keys):\n        names = {'uri', 'name', 'presence.policy', 'presence.subscribe', 'dialog.policy', 'dialog.subscribe'}\n        attributes = dict((name, recursive_getattr(self, name)) for name in names.intersection(modified_keys))\n        attributes.update((name, self.attributes[name]) for name in self.__attributes__.intersection(modified_keys))\n        return attributes\n\n\nclass ContactListDescriptor(AbstractSetting):\n    def __init__(self):\n        self.values = defaultweakobjectmap(ContactList)\n        self.oldvalues = defaultweakobjectmap(ContactList)\n        self.lock = Lock()\n\n    def __get__(self, obj, objtype):\n        if obj is None:\n            return self\n        with self.lock:\n            return self.values[obj]\n\n    def __set__(self, obj, value):\n        if value is None:\n            raise ValueError(\"setting attribute is not nillable\")\n        elif not isinstance(value, ContactList):\n            value = ContactList(value)\n        with self.lock:\n            self.values[obj] = value\n\n    def __getstate__(self, obj):\n        with self.lock:\n            return self.values[obj].__getstate__()\n\n    def __setstate__(self, obj, value):\n        if value is None:\n            raise ValueError(\"setting attribute is not nillable\")\n        object = ContactList.__new__(ContactList)\n        object.__setstate__(value)\n        with self.lock:\n            self.values[obj] = object\n            self.oldvalues[obj] = ContactList(object)\n\n    def get_modified(self, obj):\n        with self.lock:\n            old = self.oldvalues[obj]\n            new = self.values[obj]\n            with new.lock:\n                old_ids = set(old.ids())\n                new_ids = set(new.ids())\n                added_contacts = [new[id] for id in new_ids - old_ids]\n                removed_contacts = [old[id] for id in old_ids - new_ids]\n                try:\n                    if added_contacts or removed_contacts:\n                        return ModifiedList(added=added_contacts, removed=removed_contacts, modified=None)\n                    else:\n                        return None\n                finally:\n                    self.oldvalues[obj] = ContactList(new)\n\n    def get_old(self, obj):\n        with self.lock:\n            return self.oldvalues[obj]\n\n    def undo(self, obj):\n        with self.lock:\n            self.values[obj] = ContactList(self.oldvalues[obj])\n\n\nclass ContactList(object):\n    def __new__(cls, contacts=None):\n        instance = object.__new__(cls)\n        instance.lock = Lock()\n        return instance\n\n    def __init__(self, contacts=None):\n        self.contacts = dict((contact.id, contact) for contact in contacts or [] if contact.__state__ != 'deleted')\n\n    def __getitem__(self, key):\n        return self.contacts[key]\n\n    def __contains__(self, key):\n        return key in self.contacts\n\n    def __iter__(self):\n        return iter(sorted(self.contacts.values(), key=attrgetter('id')))\n\n    def __reversed__(self):\n        return iter(sorted(self.contacts.values(), key=attrgetter('id'), reverse=True))\n\n    __hash__ = None\n\n    def __len__(self):\n        return len(self.contacts)\n\n    def __eq__(self, other):\n        if isinstance(other, ContactList):\n            return self.contacts == other.contacts\n        return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    def __repr__(self):\n        return \"%s(%r)\" % (self.__class__.__name__, sorted(self.contacts.values(), key=attrgetter('id')))\n\n    def __getstate__(self):\n        return self.contacts.keys()\n\n    def __setstate__(self, value):\n        addressbook_manager = AddressbookManager()\n        for id in [id for id in value if not addressbook_manager.has_contact(id)]:\n            value.remove(id)\n        with self.lock:\n            self.contacts = dict((id, addressbook_manager.get_contact(id)) for id in value)\n\n    def ids(self):\n        return sorted(self.contacts.keys())\n\n    def add(self, contact):\n        if contact.__state__ == 'deleted':\n            return\n        with self.lock:\n            self.contacts[contact.id] = contact\n\n    def remove(self, contact):\n        with self.lock:\n            self.contacts.pop(contact.id, None)\n\n\nclass Group(SettingsState):\n    __key__ = AddressbookKey('Groups')\n    __id__  = SettingsObjectImmutableID(type=ID)\n\n    id = __id__\n    name = Setting(type=unicode, default='')\n    contacts = ContactListDescriptor()\n\n    def __new__(cls, id=None):\n        with AddressbookManager.load.lock:\n            if not AddressbookManager.load.called:\n                raise RuntimeError(\"cannot instantiate %s before calling AddressbookManager.load\" % cls.__name__)\n        if id is None:\n            id = unique_id()\n        elif not isinstance(id, basestring):\n            raise TypeError(\"id needs to be a string or unicode object\")\n        instance = SettingsState.__new__(cls)\n        instance.__id__ = id\n        instance.__state__ = 'new'\n        instance.__xcapgroup__ = None\n        configuration = ConfigurationManager()\n        try:\n            data = configuration.get(instance.__key__)\n        except ObjectNotFoundError:\n            pass\n        else:\n            instance.__setstate__(data)\n            instance.__state__ = 'loaded'\n            instance.__xcapgroup__ = instance.__toxcap__()\n        return instance\n\n    def __establish__(self):\n        if self.__state__ == 'loaded':\n            self.__state__ = 'active'\n            notification_center = NotificationCenter()\n            notification_center.post_notification('AddressbookGroupWasActivated', sender=self)\n\n    def __repr__(self):\n        return \"%s(id=%r)\" % (self.__class__.__name__, self.id)\n\n    def __toxcap__(self):\n        xcap_contacts = [contact.__xcapcontact__ for contact in self.contacts]\n        attributes = dict((name, getattr(self, name)) for name, attr in vars(self.__class__).iteritems() if isinstance(attr, SharedSetting))\n        return XCAPGroup(self.id, self.name, xcap_contacts, **attributes)\n\n    @run_in_thread('file-io')\n    def _internal_save(self, originator):\n        if self.__state__ == 'deleted':\n            return\n\n        for contact in [contact for contact in self.contacts if contact.__state__ == 'deleted']:\n            self.contacts.remove(contact)\n\n        modified_settings = self.get_modified()\n\n        if not modified_settings and self.__state__ != 'new':\n            return\n\n        account_manager = AccountManager()\n        configuration = ConfigurationManager()\n        notification_center = NotificationCenter()\n\n        if originator is Local:\n            originator_account = None\n            previous_xcapgroup = self.__xcapgroup__\n        else:\n            originator_account = originator.account\n            previous_xcapgroup = originator.xcap_object\n\n        xcap_accounts = [account for account in account_manager.get_accounts() if account.xcap.discovered]\n\n        self.__xcapgroup__ = self.__toxcap__()\n\n        if self.__state__ == 'new':\n            configuration.update(self.__key__, self.__getstate__())\n            self.__state__ = 'active'\n            for account in (account for account in xcap_accounts if account is not originator_account):\n                account.xcap_manager.add_group(self.__xcapgroup__)\n            modified_data = None\n            notification_center.post_notification('AddressbookGroupWasActivated', sender=self)\n            notification_center.post_notification('AddressbookGroupWasCreated', sender=self)\n        elif all(isinstance(self.__settings__[key], RuntimeSetting) for key in modified_settings):\n            notification_center.post_notification('AddressbookGroupDidChange', sender=self, data=NotificationData(modified=modified_settings))\n            return\n        else:\n            configuration.update(self.__key__, self.__getstate__())\n\n            attributes = self.__xcapgroup__.get_modified(modified_settings)\n\n            if 'contacts' in modified_settings:\n                added_contacts = [contact.__xcapcontact__ for contact in modified_settings['contacts'].added]\n                removed_contacts = [contact.__xcapcontact__ for contact in modified_settings['contacts'].removed]\n            else:\n                added_contacts = []\n                removed_contacts = []\n\n            if self.__xcapgroup__ != previous_xcapgroup:\n                outofsync_accounts = xcap_accounts\n            elif originator is Local:\n                outofsync_accounts = []\n            else:\n                outofsync_accounts = list(account for account in xcap_accounts if account is not originator_account)\n\n            with MultiAccountTransaction(outofsync_accounts):\n                for account in outofsync_accounts:\n                    xcap_manager = account.xcap_manager\n                    for xcapcontact in added_contacts:\n                        xcap_manager.add_group_member(self.__xcapgroup__, xcapcontact)\n                    for xcapcontact in removed_contacts:\n                        xcap_manager.remove_group_member(self.__xcapgroup__, xcapcontact)\n                    if attributes:\n                        xcap_manager.update_group(self.__xcapgroup__, attributes)\n\n            notification_center.post_notification('AddressbookGroupDidChange', sender=self, data=NotificationData(modified=modified_settings))\n            modified_data = modified_settings\n\n        try:\n            configuration.save()\n        except Exception, e:\n            log.exception()\n            notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData(object=self, operation='save', modified=modified_data, exception=e))\n\n    @run_in_thread('file-io')\n    def _internal_delete(self, originator):\n        if self.__state__ == 'deleted':\n            return\n        self.__state__ = 'deleted'\n\n        configuration = ConfigurationManager()\n        account_manager = AccountManager()\n        notification_center = NotificationCenter()\n\n        if originator is Local:\n            originator_account = None\n        else:\n            originator_account = originator.account\n\n        configuration.delete(self.__key__)\n\n        for account in (account for account in account_manager.iter_accounts() if account.xcap.discovered and account is not originator_account):\n            account.xcap_manager.remove_group(self.__xcapgroup__)\n\n        notification_center.post_notification('AddressbookGroupWasDeleted', sender=self)\n\n        try:\n            configuration.save()\n        except Exception, e:\n            log.exception()\n            notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData(object=self, operation='delete', exception=e))\n\n    def save(self):\n        \"\"\"\n        Store the group into persistent storage (local and xcap).\n\n        This method will post the AddressbookGroupWasCreated and\n        AddressbookGroupWasActivated notifications on the first save or a\n        AddressbookGroupDidChange notification on subsequent saves, regardless\n        of whether the contact has been saved to persistent storage or not.\n        A CFGManagerSaveFailed notification is posted if saving to the\n        persistent configuration storage fails.\n        \"\"\"\n        self._internal_save(originator=Local)\n\n    def delete(self):\n        \"\"\"Remove the group from the persistent storage.\"\"\"\n        self._internal_delete(originator=Local)\n\n    def clone(self, new_id=None):\n        \"\"\"Create a copy of this group and all its sub-settings.\"\"\"\n        raise NotImplementedError\n\n    @classmethod\n    def register_extension(cls, extension):\n        \"\"\"\n        Register an extension for this class. All Settings and SettingsGroups\n        defined in the extension will be added to this class, overwriting any\n        attributes with the same name. Other attributes in the extension are\n        ignored.\n        \"\"\"\n        if not issubclass(extension, GroupExtension):\n            raise TypeError(\"expected subclass of GroupExtension, got %r\" % (extension,))\n        for name in dir(extension):\n            attribute = getattr(extension, name, None)\n            if isinstance(attribute, SharedSetting):\n                if SharedSetting.__namespace__ is None:\n                    raise RuntimeError(\"cannot use SharedSetting attributes without first calling SharedSetting.set_namespace\")\n                XCAPGroup.__attributes__.add(name)\n            if isinstance(attribute, (AbstractSetting, SettingsGroupMeta)):\n                setattr(cls, name, attribute)\n\n\nclass GroupExtension(object):\n    \"\"\"Base class for extensions of Groups\"\"\"\n    def __new__(cls, *args, **kw):\n        raise TypeError(\"GroupExtension subclasses cannot be instantiated\")\n\n\nclass ContactURI(SettingsState):\n    __id__ = SettingsObjectImmutableID(type=ID)\n\n    id = __id__\n    uri = Setting(type=unicode, default='')\n    type = Setting(type=unicode, default=None, nillable=True)\n\n    def __new__(cls, id=None, **state):\n        if id is None:\n            id = unique_id()\n        elif not isinstance(id, basestring):\n            raise TypeError(\"id needs to be a string or unicode object\")\n        instance = SettingsState.__new__(cls)\n        instance.__id__ = id\n        instance.__setstate__(state)\n        return instance\n\n    def __repr__(self):\n        return \"%s(id=%r)\" % (self.__class__.__name__, self.id)\n\n    def __toxcap__(self):\n        attributes = dict((name, getattr(self, name)) for name, attr in vars(self.__class__).iteritems() if isinstance(attr, SharedSetting))\n        return XCAPContactURI(self.id, self.uri, self.type, **attributes)\n\n    @classmethod\n    def register_extension(cls, extension):\n        \"\"\"\n        Register an extension for this class. All Settings and SettingsGroups\n        defined in the extension will be added to this class, overwriting any\n        attributes with the same name. Other attributes in the extension are\n        ignored.\n        \"\"\"\n        if not issubclass(extension, ContactURIExtension):\n            raise TypeError(\"expected subclass of ContactURIExtension, got %r\" % (extension,))\n        for name in dir(extension):\n            attribute = getattr(extension, name, None)\n            if isinstance(attribute, SharedSetting):\n                if SharedSetting.__namespace__ is None:\n                    raise RuntimeError(\"cannot use SharedSetting attributes without first calling SharedSetting.set_namespace\")\n                XCAPContactURI.__attributes__.add(name)\n            if isinstance(attribute, (AbstractSetting, SettingsGroupMeta)):\n                setattr(cls, name, attribute)\n\n\nclass ContactURIExtension(object):\n    \"\"\"Base class for extensions of ContactURIs\"\"\"\n    def __new__(cls, *args, **kw):\n        raise TypeError(\"ContactURIExtension subclasses cannot be instantiated\")\n\n\nclass DefaultContactURI(Setting):\n    def __init__(self):\n        super(DefaultContactURI, self).__init__(type=str, default=None, nillable=True)\n\n    def __get__(self, obj, objtype):\n        value = super(DefaultContactURI, self).__get__(obj, objtype)\n        return value if value in (self, None) else obj._item_map.get(value)\n\n    def __set__(self, obj, value):\n        if value is not None:\n            if not isinstance(value, ContactURI):\n                raise TypeError(\"the default URI must be a ContactURI instance or None\")\n            with obj._lock:\n                if value.id not in obj._item_map:\n                    raise ValueError(\"the default URI can only be set to one of the URIs of the contact\")\n                super(DefaultContactURI, self).__set__(obj, value.id)\n        else:\n            super(DefaultContactURI, self).__set__(obj, None)\n\n    def get_modified(self, obj):\n        modified_value = super(DefaultContactURI, self).get_modified(obj)\n        if modified_value is not None:\n            old_uri = obj._item_map.old.get(modified_value.old) if modified_value.old is not None else None\n            new_uri = obj._item_map.get(modified_value.new) if modified_value.new is not None else None\n            modified_value = ModifiedValue(old=old_uri, new=new_uri)\n        return modified_value\n\n    def get_old(self, obj):\n        value = super(DefaultContactURI, self).get_old(obj)\n        return value if value is None else obj._item_map.old.get(value)\n\n\nclass ContactURIManagement(ItemManagement):\n    def remove_item(self, item, collection):\n        if collection.default is item:\n            collection.default = None\n\n    def set_items(self, items, collection):\n        if collection.default is not None and collection.default not in items:\n            collection.default = None\n\n\nclass ContactURIList(ItemCollection):\n    _item_type = ContactURI\n    _item_management = ContactURIManagement()\n\n    default = DefaultContactURI()\n\n\nclass DialogSettings(SettingsGroup):\n    policy = Setting(type=PolicyValue, default='default')\n    subscribe = Setting(type=bool, default=False)\n\n\nclass PresenceSettings(SettingsGroup):\n    policy = Setting(type=PolicyValue, default='default')\n    subscribe = Setting(type=bool, default=False)\n\n\nclass Contact(SettingsState):\n    __key__ = AddressbookKey('Contacts')\n    __id__  = SettingsObjectImmutableID(type=ID)\n\n    id = __id__\n    name = Setting(type=unicode, default='')\n    uris = ContactURIList\n    dialog = DialogSettings\n    presence = PresenceSettings\n\n    def __new__(cls, id=None):\n        with AddressbookManager.load.lock:\n            if not AddressbookManager.load.called:\n                raise RuntimeError(\"cannot instantiate %s before calling AddressbookManager.load\" % cls.__name__)\n        if id is None:\n            id = unique_id()\n        elif not isinstance(id, basestring):\n            raise TypeError(\"id needs to be a string or unicode object\")\n        instance = SettingsState.__new__(cls)\n        instance.__id__ = id\n        instance.__state__ = 'new'\n        instance.__xcapcontact__ = None\n        configuration = ConfigurationManager()\n        try:\n            data = configuration.get(instance.__key__)\n        except ObjectNotFoundError:\n            pass\n        else:\n            instance.__setstate__(data)\n            instance.__state__ = 'loaded'\n            instance.__xcapcontact__ = instance.__toxcap__()\n        return instance\n\n    def __establish__(self):\n        if self.__state__ == 'loaded':\n            self.__state__ = 'active'\n            notification_center = NotificationCenter()\n            notification_center.post_notification('AddressbookContactWasActivated', sender=self)\n\n    def __repr__(self):\n        return \"%s(id=%r)\" % (self.__class__.__name__, self.id)\n\n    def __toxcap__(self):\n        contact_uris = xcap.ContactURIList((uri.__toxcap__() for uri in self.uris), default=self.uris.default.id if self.uris.default is not None else None)\n        dialog_handling = xcap.EventHandling(self.dialog.policy, self.dialog.subscribe)\n        presence_handling = xcap.EventHandling(self.presence.policy, self.presence.subscribe)\n        attributes = dict((name, getattr(self, name)) for name, attr in vars(self.__class__).iteritems() if isinstance(attr, SharedSetting))\n        return XCAPContact(self.id, self.name, contact_uris, presence_handling, dialog_handling, **attributes)\n\n    @run_in_thread('file-io')\n    def _internal_save(self, originator):\n        if self.__state__ == 'deleted':\n            return\n\n        modified_settings = self.get_modified()\n\n        if not modified_settings and self.__state__ != 'new':\n            return\n\n        account_manager = AccountManager()\n        configuration = ConfigurationManager()\n        notification_center = NotificationCenter()\n\n        if originator is Local:\n            originator_account = None\n            previous_xcapcontact = self.__xcapcontact__\n        else:\n            originator_account = originator.account\n            previous_xcapcontact = originator.xcap_object\n\n        xcap_accounts = [account for account in account_manager.get_accounts() if account.xcap.discovered]\n\n        self.__xcapcontact__ = self.__toxcap__()\n\n        if self.__state__ == 'new':\n            configuration.update(self.__key__, self.__getstate__())\n            self.__state__ = 'active'\n            for account in (account for account in xcap_accounts if account is not originator_account):\n                account.xcap_manager.add_contact(self.__xcapcontact__)\n            modified_data = None\n            notification_center.post_notification('AddressbookContactWasActivated', sender=self)\n            notification_center.post_notification('AddressbookContactWasCreated', sender=self)\n        elif all(isinstance(self.__settings__[key], RuntimeSetting) for key in modified_settings):\n            notification_center.post_notification('AddressbookContactDidChange', sender=self, data=NotificationData(modified=modified_settings))\n            return\n        else:\n            configuration.update(self.__key__, self.__getstate__())\n\n            contact_attributes = self.__xcapcontact__.get_modified(modified_settings)\n\n            if 'uris' in modified_settings:\n                xcap_uris = self.__xcapcontact__.uris\n                added_uris = [xcap_uris[uri.id] for uri in modified_settings['uris'].added]\n                removed_uris = [uri.__toxcap__() for uri in modified_settings['uris'].removed]\n                modified_uris = dict((xcap_uris[id], xcap_uris[id].get_modified(changemap)) for id, changemap in modified_settings['uris'].modified.iteritems())\n            else:\n                added_uris = []\n                removed_uris = []\n                modified_uris = {}\n\n            if self.__xcapcontact__ != previous_xcapcontact:\n                outofsync_accounts = xcap_accounts\n            elif originator is Local:\n                outofsync_accounts = []\n            else:\n                outofsync_accounts = list(account for account in xcap_accounts if account is not originator_account)\n\n            with MultiAccountTransaction(outofsync_accounts):\n                for account in outofsync_accounts:\n                    xcap_manager = account.xcap_manager\n                    for xcapuri in added_uris:\n                        xcap_manager.add_contact_uri(self.__xcapcontact__, xcapuri)\n                    for xcapuri in removed_uris:\n                        xcap_manager.remove_contact_uri(self.__xcapcontact__, xcapuri)\n                    for xcapuri, uri_attributes in modified_uris.iteritems():\n                        xcap_manager.update_contact_uri(self.__xcapcontact__, xcapuri, uri_attributes)\n                    if contact_attributes:\n                        xcap_manager.update_contact(self.__xcapcontact__, contact_attributes)\n\n            notification_center.post_notification('AddressbookContactDidChange', sender=self, data=NotificationData(modified=modified_settings))\n            modified_data = modified_settings\n\n        try:\n            configuration.save()\n        except Exception, e:\n            log.exception()\n            notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData(object=self, operation='save', modified=modified_data, exception=e))\n\n    @run_in_thread('file-io')\n    def _internal_delete(self, originator):\n        if self.__state__ == 'deleted':\n            return\n        self.__state__ = 'deleted'\n\n        configuration = ConfigurationManager()\n        account_manager = AccountManager()\n        addressbook_manager = AddressbookManager()\n        notification_center = NotificationCenter()\n\n        if originator is Local:\n            originator_account = None\n        else:\n            originator_account = originator.account\n\n        configuration.delete(self.__key__)\n\n        xcap_accounts = [account for account in account_manager.get_accounts() if account.xcap.discovered]\n        with MultiAccountTransaction(xcap_accounts):\n            for group in (group for group in addressbook_manager.get_groups() if self.id in group.contacts):\n                group.contacts.remove(self)\n                group.save()\n            for account in (account for account in xcap_accounts if account is not originator_account):\n                account.xcap_manager.remove_contact(self.__xcapcontact__)\n\n        notification_center.post_notification('AddressbookContactWasDeleted', sender=self)\n\n        try:\n            configuration.save()\n        except Exception, e:\n            log.exception()\n            notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData(object=self, operation='delete', exception=e))\n\n    def save(self):\n        \"\"\"\n        Store the contact into persistent storage (local and xcap).\n\n        This method will post the AddressbookContactWasCreated and\n        AddressbookContactWasActivated notifications on the first save or\n        a AddressbookContactDidChange notification on subsequent saves,\n        regardless of whether the contact has been saved to persistent\n        storage or not. A CFGManagerSaveFailed notification is posted\n        if saving to the persistent configuration storage fails.\n        \"\"\"\n        self._internal_save(originator=Local)\n\n    def delete(self):\n        \"\"\"Remove the contact from the persistent storage.\"\"\"\n        self._internal_delete(originator=Local)\n\n    def clone(self, new_id=None):\n        \"\"\"Create a copy of this contact and all its sub-settings.\"\"\"\n        raise NotImplementedError\n\n    @classmethod\n    def register_extension(cls, extension):\n        \"\"\"\n        Register an extension for this class. All Settings and SettingsGroups\n        defined in the extension will be added to this class, overwriting any\n        attributes with the same name. Other attributes in the extension are\n        ignored.\n        \"\"\"\n        if not issubclass(extension, ContactExtension):\n            raise TypeError(\"expected subclass of ContactExtension, got %r\" % (extension,))\n        for name in dir(extension):\n            attribute = getattr(extension, name, None)\n            if isinstance(attribute, SharedSetting):\n                if SharedSetting.__namespace__ is None:\n                    raise RuntimeError(\"cannot use SharedSetting attributes without first calling SharedSetting.set_namespace\")\n                XCAPContact.__attributes__.add(name)\n            if isinstance(attribute, (AbstractSetting, SettingsGroupMeta)):\n                setattr(cls, name, attribute)\n\n\nclass ContactExtension(object):\n    \"\"\"Base class for extensions of Contacts\"\"\"\n    def __new__(cls, *args, **kw):\n        raise TypeError(\"ContactExtension subclasses cannot be instantiated\")\n\n\nclass Policy(SettingsState):\n    __key__ = AddressbookKey('Policies')\n    __id__  = SettingsObjectImmutableID(type=ID)\n\n    id = __id__\n    uri  = Setting(type=unicode, default='')\n    name = Setting(type=unicode, default='')\n    dialog = DialogSettings\n    presence = PresenceSettings\n\n    def __new__(cls, id=None):\n        with AddressbookManager.load.lock:\n            if not AddressbookManager.load.called:\n                raise RuntimeError(\"cannot instantiate %s before calling AddressbookManager.load\" % cls.__name__)\n        if id is None:\n            id = unique_id()\n        elif not isinstance(id, basestring):\n            raise TypeError(\"id needs to be a string or unicode object\")\n        instance = SettingsState.__new__(cls)\n        instance.__id__ = id\n        instance.__state__ = 'new'\n        instance.__xcappolicy__ = None\n        configuration = ConfigurationManager()\n        try:\n            data = configuration.get(instance.__key__)\n        except ObjectNotFoundError:\n            pass\n        else:\n            instance.__setstate__(data)\n            instance.__state__ = 'loaded'\n            instance.__xcappolicy__ = instance.__toxcap__()\n        return instance\n\n    def __establish__(self):\n        if self.__state__ == 'loaded':\n            self.__state__ = 'active'\n            notification_center = NotificationCenter()\n            notification_center.post_notification('AddressbookPolicyWasActivated', sender=self)\n\n    def __repr__(self):\n        return \"%s(id=%r)\" % (self.__class__.__name__, self.id)\n\n    def __toxcap__(self):\n        dialog_handling = xcap.EventHandling(self.dialog.policy, self.dialog.subscribe)\n        presence_handling = xcap.EventHandling(self.presence.policy, self.presence.subscribe)\n        attributes = dict((name, getattr(self, name)) for name, attr in vars(self.__class__).iteritems() if isinstance(attr, SharedSetting))\n        return XCAPPolicy(self.id, self.uri, self.name, presence_handling, dialog_handling, **attributes)\n\n    @run_in_thread('file-io')\n    def _internal_save(self, originator):\n        if self.__state__ == 'deleted':\n            return\n\n        modified_settings = self.get_modified()\n\n        if not modified_settings and self.__state__ != 'new':\n            return\n\n        account_manager = AccountManager()\n        configuration = ConfigurationManager()\n        notification_center = NotificationCenter()\n\n        if originator is Local:\n            originator_account = None\n            previous_xcappolicy = self.__xcappolicy__\n        else:\n            originator_account = originator.account\n            previous_xcappolicy = originator.xcap_object\n\n        xcap_accounts = [account for account in account_manager.get_accounts() if account.xcap.discovered]\n\n        self.__xcappolicy__ = self.__toxcap__()\n\n        if self.__state__ == 'new':\n            configuration.update(self.__key__, self.__getstate__())\n            self.__state__ = 'active'\n            for account in (account for account in xcap_accounts if account is not originator_account):\n                account.xcap_manager.add_policy(self.__xcappolicy__)\n            modified_data = None\n            notification_center.post_notification('AddressbookPolicyWasActivated', sender=self)\n            notification_center.post_notification('AddressbookPolicyWasCreated', sender=self)\n        elif all(isinstance(self.__settings__[key], RuntimeSetting) for key in modified_settings):\n            notification_center.post_notification('AddressbookPolicyDidChange', sender=self, data=NotificationData(modified=modified_settings))\n            return\n        else:\n            configuration.update(self.__key__, self.__getstate__())\n\n            attributes = self.__xcappolicy__.get_modified(modified_settings)\n\n            if self.__xcappolicy__ != previous_xcappolicy:\n                outofsync_accounts = xcap_accounts\n            elif originator is Local:\n                outofsync_accounts = []\n            else:\n                outofsync_accounts = list(account for account in xcap_accounts if account is not originator_account)\n\n            for account in outofsync_accounts:\n                account.xcap_manager.update_policy(self.__xcappolicy__, attributes)\n\n            notification_center.post_notification('AddressbookPolicyDidChange', sender=self, data=NotificationData(modified=modified_settings))\n            modified_data = modified_settings\n\n        try:\n            configuration.save()\n        except Exception, e:\n            log.exception()\n            notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData(object=self, operation='save', modified=modified_data, exception=e))\n\n    @run_in_thread('file-io')\n    def _internal_delete(self, originator):\n        if self.__state__ == 'deleted':\n            return\n        self.__state__ = 'deleted'\n\n        configuration = ConfigurationManager()\n        account_manager = AccountManager()\n        notification_center = NotificationCenter()\n\n        if originator is Local:\n            originator_account = None\n        else:\n            originator_account = originator.account\n\n        configuration.delete(self.__key__)\n\n        for account in (account for account in account_manager.iter_accounts() if account.xcap.discovered and account is not originator_account):\n            account.xcap_manager.remove_policy(self.__xcappolicy__)\n\n        notification_center.post_notification('AddressbookPolicyWasDeleted', sender=self)\n\n        try:\n            configuration.save()\n        except Exception, e:\n            log.exception()\n            notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData(object=self, operation='delete', exception=e))\n\n    def save(self):\n        \"\"\"\n        Store the policy into persistent storage (local and xcap).\n\n        It will post the AddressbookPolicyWasCreated and\n        AddressbookPolicyWasActivated notifications on the first save or\n        a AddressbookPolicyDidChange notification on subsequent saves,\n        regardless of whether the policy has been saved to persistent\n        storage or not. A CFGManagerSaveFailed notification is posted\n        if saving to the persistent configuration storage fails.\n        \"\"\"\n        self._internal_save(originator=Local)\n\n    def delete(self):\n        \"\"\"Remove the policy from the persistent storage.\"\"\"\n        self._internal_delete(originator=Local)\n\n    def clone(self, new_id=None):\n        \"\"\"Create a copy of this policy and all its sub-settings.\"\"\"\n        raise NotImplementedError\n\n    @classmethod\n    def register_extension(cls, extension):\n        \"\"\"\n        Register an extension for this class. All Settings and SettingsGroups\n        defined in the extension will be added to this class, overwriting any\n        attributes with the same name. Other attributes in the extension are\n        ignored.\n        \"\"\"\n        if not issubclass(extension, PolicyExtension):\n            raise TypeError(\"expected subclass of PolicyExtension, got %r\" % (extension,))\n        for name in dir(extension):\n            attribute = getattr(extension, name, None)\n            if isinstance(attribute, SharedSetting):\n                if SharedSetting.__namespace__ is None:\n                    raise RuntimeError(\"cannot use SharedSetting attributes without first calling SharedSetting.set_namespace\")\n                XCAPPolicy.__attributes__.add(name)\n            if isinstance(attribute, (AbstractSetting, SettingsGroupMeta)):\n                setattr(cls, name, attribute)\n\n\nclass PolicyExtension(object):\n    \"\"\"Base class for extensions of Policies\"\"\"\n    def __new__(cls, *args, **kw):\n        raise TypeError(\"PolicyExtension subclasses cannot be instantiated\")\n\n\nclass AddressbookManager(object):\n    __metaclass__ = Singleton\n\n    implements(IObserver)\n\n    def __init__(self):\n        self.contacts = {}\n        self.groups = {}\n        self.policies = {}\n        self.__xcapaddressbook__ = None\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, name='AddressbookContactWasActivated')\n        notification_center.add_observer(self, name='AddressbookContactWasDeleted')\n        notification_center.add_observer(self, name='AddressbookGroupWasActivated')\n        notification_center.add_observer(self, name='AddressbookGroupWasDeleted')\n        notification_center.add_observer(self, name='AddressbookPolicyWasActivated')\n        notification_center.add_observer(self, name='AddressbookPolicyWasDeleted')\n        notification_center.add_observer(self, name='SIPAccountDidDiscoverXCAPSupport')\n        notification_center.add_observer(self, name='XCAPManagerDidReloadData')\n\n    @execute_once\n    def load(self):\n        configuration = ConfigurationManager()\n\n        # temporary workaround to migrate contacts to the new format. to be removed later. -Dan\n        if 'Contacts' in configuration.data or 'ContactGroups' in configuration.data:\n            account_manager = AccountManager()\n            old_data = dict(contacts=configuration.data.pop('Contacts', {}), groups=configuration.data.pop('ContactGroups', {}))\n            if any(account.enabled and account.xcap.enabled and account.xcap.discovered for account in account_manager.get_accounts()):\n                self.__old_data = old_data\n            else:\n                self.__migrate_contacts(old_data)\n            return\n\n        [Contact(id=id) for id in configuration.get_names(Contact.__key__)]\n        [Group(id=id) for id in configuration.get_names(Group.__key__)]\n        [Policy(id=id) for id in configuration.get_names(Policy.__key__)]\n\n    def start(self):\n        pass\n\n    def stop(self):\n        pass\n\n    def has_contact(self, id):\n        return id in self.contacts\n\n    def get_contact(self, id):\n        return self.contacts[id]\n\n    def get_contacts(self):\n        return self.contacts.values()\n\n    def has_group(self, id):\n        return id in self.groups\n\n    def get_group(self, id):\n        return self.groups[id]\n\n    def get_groups(self):\n        return self.groups.values()\n\n    def has_policy(self, id):\n        return id in self.policies\n\n    def get_policy(self, id):\n        return self.policies[id]\n\n    def get_policies(self):\n        return self.policies.values()\n\n    @classmethod\n    def transaction(cls):\n        account_manager = AccountManager()\n        xcap_accounts = [account for account in account_manager.get_accounts() if account.xcap.discovered]\n        return MultiAccountTransaction(xcap_accounts)\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_AddressbookContactWasActivated(self, notification):\n        contact = notification.sender\n        self.contacts[contact.id] = contact\n        notification.center.post_notification('AddressbookManagerDidAddContact', sender=self, data=NotificationData(contact=contact))\n\n    def _NH_AddressbookContactWasDeleted(self, notification):\n        contact = notification.sender\n        del self.contacts[contact.id]\n        notification.center.post_notification('AddressbookManagerDidRemoveContact', sender=self, data=NotificationData(contact=contact))\n\n    def _NH_AddressbookGroupWasActivated(self, notification):\n        group = notification.sender\n        self.groups[group.id] = group\n        notification.center.post_notification('AddressbookManagerDidAddGroup', sender=self, data=NotificationData(group=group))\n\n    def _NH_AddressbookGroupWasDeleted(self, notification):\n        group = notification.sender\n        del self.groups[group.id]\n        notification.center.post_notification('AddressbookManagerDidRemoveGroup', sender=self, data=NotificationData(group=group))\n\n    def _NH_AddressbookPolicyWasActivated(self, notification):\n        policy = notification.sender\n        self.policies[policy.id] = policy\n        notification.center.post_notification('AddressbookManagerDidAddPolicy', sender=self, data=NotificationData(policy=policy))\n\n    def _NH_AddressbookPolicyWasDeleted(self, notification):\n        policy = notification.sender\n        del self.policies[policy.id]\n        notification.center.post_notification('AddressbookManagerDidRemovePolicy', sender=self, data=NotificationData(policy=policy))\n\n    @run_in_thread('file-io')\n    def _NH_SIPAccountDidDiscoverXCAPSupport(self, notification):\n        xcap_manager = notification.sender.xcap_manager\n        with xcap_manager.transaction():\n            for contact in self.contacts.values():\n                xcap_manager.add_contact(contact.__xcapcontact__)\n            for group in self.groups.values():\n                xcap_manager.add_group(group.__xcapgroup__)\n            for policy in self.policies.values():\n                xcap_manager.add_policy(policy.__xcappolicy__)\n\n    @run_in_thread('file-io')\n    def _NH_XCAPManagerDidReloadData(self, notification):\n        if notification.data.addressbook == self.__xcapaddressbook__:\n            return\n\n        self.__xcapaddressbook__ = notification.data.addressbook\n\n        xcap_manager = notification.sender\n        xcap_contacts = notification.data.addressbook.contacts\n        xcap_groups = notification.data.addressbook.groups\n        xcap_policies = notification.data.addressbook.policies\n\n        account_manager = AccountManager()\n        xcap_accounts = [account for account in account_manager.get_accounts() if account.xcap.discovered]\n\n        # temporary workaround to migrate contacts to the new format. to be removed later. -Dan\n        if hasattr(self, '_AddressbookManager__old_data'):\n            old_data = self.__old_data\n            del self.__old_data\n            if not xcap_contacts and not xcap_groups:\n                self.__migrate_contacts(old_data)\n                return\n\n        with MultiAccountTransaction(xcap_accounts):\n            # because groups depend on contacts, operation order is add/update contacts, add/update/remove groups & policies, remove contacts -Dan\n\n            for xcap_contact in xcap_contacts:\n                xcap_contact = XCAPContact.normalize(xcap_contact)\n                try:\n                    contact = self.contacts[xcap_contact.id]\n                except KeyError:\n                    try:\n                        contact = Contact(xcap_contact.id)\n                    except DuplicateIDError:\n                        log.exception()\n                        continue\n                contact.name = xcap_contact.name\n                contact.presence.policy = xcap_contact.presence.policy\n                contact.presence.subscribe = xcap_contact.presence.subscribe\n                contact.dialog.policy = xcap_contact.dialog.policy\n                contact.dialog.subscribe = xcap_contact.dialog.subscribe\n                for name, value in xcap_contact.attributes.iteritems():\n                    setattr(contact, name, value)\n                for xcap_uri in xcap_contact.uris:\n                    xcap_uri = XCAPContactURI.normalize(xcap_uri)\n                    try:\n                        uri = contact.uris[xcap_uri.id]\n                    except KeyError:\n                        try:\n                            uri = ContactURI(xcap_uri.id)\n                        except DuplicateIDError:\n                            log.exception()\n                            continue\n                        contact.uris.add(uri)\n                    uri.uri = xcap_uri.uri\n                    uri.type = xcap_uri.type\n                    for name, value in xcap_uri.attributes.iteritems():\n                        setattr(uri, name, value)\n                for uri in (uri for uri in list(contact.uris) if uri.id not in xcap_contact.uris):\n                    contact.uris.remove(uri)\n                contact.uris.default = contact.uris.get(xcap_contact.uris.default, None)\n                contact._internal_save(originator=Remote(xcap_manager.account, xcap_contact))\n\n            for xcap_group in xcap_groups:\n                xcap_group = XCAPGroup.normalize(xcap_group)\n                try:\n                    group = self.groups[xcap_group.id]\n                except KeyError:\n                    try:\n                        group = Group(xcap_group.id)\n                    except DuplicateIDError:\n                        log.exception()\n                        continue\n                group.name = xcap_group.name\n                for name, value in xcap_group.attributes.iteritems():\n                    setattr(group, name, value)\n                old_contact_ids = set(group.contacts.ids())\n                new_contact_ids = set(xcap_group.contacts.ids())\n                for contact in (self.contacts[id] for id in new_contact_ids - old_contact_ids):\n                    group.contacts.add(contact)\n                for contact in (group.contacts[id] for id in old_contact_ids - new_contact_ids):\n                    group.contacts.remove(contact)\n                group._internal_save(originator=Remote(xcap_manager.account, xcap_group))\n\n            for xcap_policy in xcap_policies:\n                xcap_policy = XCAPPolicy.normalize(xcap_policy)\n                try:\n                    policy = self.policies[xcap_policy.id]\n                except KeyError:\n                    try:\n                        policy = Policy(xcap_policy.id)\n                    except DuplicateIDError:\n                        log.exception()\n                        continue\n                policy.uri = xcap_policy.uri\n                policy.name = xcap_policy.name\n                policy.presence.policy = xcap_policy.presence.policy\n                policy.presence.subscribe = xcap_policy.presence.subscribe\n                policy.dialog.policy = xcap_policy.dialog.policy\n                policy.dialog.subscribe = xcap_policy.dialog.subscribe\n                for name, value in xcap_policy.attributes.iteritems():\n                    setattr(policy, name, value)\n                policy._internal_save(originator=Remote(xcap_manager.account, xcap_policy))\n\n            originator = Remote(xcap_manager.account, None)\n            for policy in (policy for policy in self.policies.values() if policy.id not in xcap_policies):\n                policy._internal_delete(originator=originator)\n            for group in (group for group in self.groups.values() if group.id not in xcap_groups):\n                group._internal_delete(originator=originator)\n            for contact in (contact for contact in self.contacts.values() if contact.id not in xcap_contacts):\n                contact._internal_delete(originator=originator)\n\n    def __migrate_contacts(self, old_data):\n        account_manager = AccountManager()\n        xcap_accounts = [account for account in account_manager.get_accounts() if account.xcap.discovered]\n        with MultiAccountTransaction(xcap_accounts):\n            # restore the old contacts and groups\n            old_groups = old_data['groups']\n            old_contacts = old_data['contacts']\n            group_idmap = {}\n            for group_id, group_state in old_groups.iteritems():\n                group_idmap[group_id] = group = Group()\n                for name, value in group_state.iteritems():\n                    try:\n                        setattr(group, name, value)\n                    except (ValueError, TypeError):\n                        pass\n            for account_id, account_contacts in old_contacts.iteritems():\n                for group_id, contact_map in account_contacts.iteritems():\n                    for uri, contact_data in contact_map.iteritems():\n                        contact = Contact()\n                        for name, value in contact_data.iteritems():\n                            try:\n                                setattr(contact, name, value)\n                            except (ValueError, TypeError):\n                                pass\n                        contact.uris.add(ContactURI(uri=uri))\n                        contact.save()\n                        group = group_idmap.get(group_id, Null)\n                        group.contacts.add(contact)\n            for group in group_idmap.itervalues():\n                group.save()\n\n\n"
  },
  {
    "path": "sipsimple/application.py",
    "content": "\n\"\"\"\nImplements a high-level application responsible for starting and stopping\nvarious sub-systems required to implement a fully featured SIP User Agent\napplication.\n\"\"\"\n\nfrom __future__ import absolute_import\n\n__all__ = [\"SIPApplication\"]\n\nimport os\n\nfrom application.notification import IObserver, NotificationCenter, NotificationData\nfrom application.python import Null\nfrom application.python.descriptor import classproperty\nfrom application.python.types import Singleton\nfrom eventlib import proc\nfrom operator import attrgetter\nfrom threading import RLock, Thread\nfrom twisted.internet import reactor\nfrom uuid import uuid4\nfrom xcaplib import client as xcap_client\nfrom zope.interface import implements\n\nfrom sipsimple.account import AccountManager\nfrom sipsimple.addressbook import AddressbookManager\nfrom sipsimple.audio import AudioDevice, RootAudioBridge\nfrom sipsimple.configuration import ConfigurationManager\nfrom sipsimple.configuration.settings import SIPSimpleSettings\nfrom sipsimple.core import AudioMixer, Engine\nfrom sipsimple.lookup import DNSManager\nfrom sipsimple.session import SessionManager\nfrom sipsimple.storage import ISIPSimpleStorage, ISIPSimpleApplicationDataStorage\nfrom sipsimple.threading import ThreadManager, run_in_thread, run_in_twisted_thread\nfrom sipsimple.threading.green import run_in_green_thread\nfrom sipsimple.video import VideoDevice\n\n\nclass ApplicationAttribute(object):\n    def __init__(self, value):\n        self.value = value\n\n    def __get__(self, obj, objtype):\n        return self.value\n\n    def __set__(self, obj, value):\n        self.value = value\n\n    def __delete__(self, obj):\n        raise AttributeError('cannot delete attribute')\n\n\nclass SIPApplication(object):\n    __metaclass__ = Singleton\n\n    implements(IObserver)\n\n    storage = ApplicationAttribute(value=None)\n    engine = ApplicationAttribute(value=None)\n    thread = ApplicationAttribute(value=None)\n\n    state = ApplicationAttribute(value=None)\n\n    alert_audio_device = ApplicationAttribute(value=None)\n    alert_audio_bridge = ApplicationAttribute(value=None)\n    voice_audio_device = ApplicationAttribute(value=None)\n    voice_audio_bridge = ApplicationAttribute(value=None)\n\n    video_device = ApplicationAttribute(value=None)\n\n    _lock = ApplicationAttribute(value=RLock())\n    _timer = ApplicationAttribute(value=None)\n    _stop_pending = ApplicationAttribute(value=False)\n\n    running           = classproperty(lambda cls: cls.state == 'started')\n    alert_audio_mixer = classproperty(lambda cls: cls.alert_audio_bridge.mixer if cls.alert_audio_bridge else None)\n    voice_audio_mixer = classproperty(lambda cls: cls.voice_audio_bridge.mixer if cls.voice_audio_bridge else None)\n\n    def start(self, storage):\n        if not ISIPSimpleStorage.providedBy(storage):\n            raise TypeError(\"storage must implement the ISIPSimpleStorage interface\")\n\n        with self._lock:\n            if self.state is not None:\n                raise RuntimeError(\"SIPApplication cannot be started from '%s' state\" % self.state)\n            self.state = 'starting'\n\n        self.engine = Engine()\n        self.storage = storage\n\n        thread_manager = ThreadManager()\n        thread_manager.start()\n\n        configuration_manager = ConfigurationManager()\n        addressbook_manager = AddressbookManager()\n        account_manager = AccountManager()\n\n        # load configuration and initialize core\n        try:\n            configuration_manager.start()\n            SIPSimpleSettings()\n            account_manager.load()\n            addressbook_manager.load()\n        except:\n            self.engine = None\n            self.state = None\n            self.storage = None\n            raise\n\n        # run the reactor thread\n        self.thread = Thread(name='Reactor Thread', target=self._run_reactor)\n        self.thread.start()\n\n    def stop(self):\n        with self._lock:\n            if self.state in (None, 'stopping', 'stopped'):\n                return\n            elif self.state == 'starting':\n                self._stop_pending = True\n                return\n            self.state = 'stopping'\n        notification_center = NotificationCenter()\n        notification_center.post_notification('SIPApplicationWillEnd', sender=self)\n        self._shutdown_subsystems()\n\n    def _run_reactor(self):\n        from eventlib.twistedutil import join_reactor; del join_reactor  # imported for the side effect of making the twisted reactor green\n\n        notification_center = NotificationCenter()\n\n        notification_center.post_notification('SIPApplicationWillStart', sender=self)\n        with self._lock:\n            stop_pending = self._stop_pending\n            if stop_pending:\n                self.state = 'stopping'\n        if stop_pending:\n            notification_center.post_notification('SIPApplicationWillEnd', sender=self)\n        else:\n            self._initialize_core()\n            reactor.run(installSignalHandlers=False)\n        with self._lock:\n            self.state = 'stopped'\n        notification_center.post_notification('SIPApplicationDidEnd', sender=self)\n\n    def _initialize_core(self):\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n\n        # initialize core\n        options = dict(# general\n                       user_agent=settings.user_agent,\n                       # SIP\n                       detect_sip_loops=True,\n                       udp_port=settings.sip.udp_port if 'udp' in settings.sip.transport_list else None,\n                       tcp_port=settings.sip.tcp_port if 'tcp' in settings.sip.transport_list else None,\n                       tls_port=None,\n                       # TLS\n                       tls_verify_server=False,\n                       tls_ca_file=None,\n                       tls_cert_file=None,\n                       tls_privkey_file=None,\n                       # rtp\n                       rtp_port_range=(settings.rtp.port_range.start, settings.rtp.port_range.end),\n                       # audio\n                       codecs=list(settings.rtp.audio_codec_list),\n                       # video\n                       video_codecs=list(settings.rtp.video_codec_list),\n                       # logging\n                       log_level=settings.logs.pjsip_level if settings.logs.trace_pjsip else 0,\n                       trace_sip=settings.logs.trace_sip)\n        notification_center.add_observer(self, sender=self.engine)\n        self.engine.start(**options)\n\n    def _initialize_tls(self):\n        settings = SIPSimpleSettings()\n        account_manager = AccountManager()\n        account = account_manager.default_account\n        if account is not None:\n            try:\n                self.engine.set_tls_options(port=settings.sip.tls_port,\n                                            verify_server=account.tls.verify_server,\n                                            ca_file=settings.tls.ca_list.normalized if settings.tls.ca_list else None,\n                                            cert_file=account.tls.certificate.normalized if account.tls.certificate else None,\n                                            privkey_file=account.tls.certificate.normalized if account.tls.certificate else None)\n            except Exception, e:\n                notification_center = NotificationCenter()\n                notification_center.post_notification('SIPApplicationFailedToStartTLS', sender=self, data=NotificationData(error=e))\n\n    @run_in_green_thread\n    def _initialize_subsystems(self):\n        notification_center = NotificationCenter()\n\n        with self._lock:\n            stop_pending = self._stop_pending\n            if stop_pending:\n                self.state = 'stopping'\n        if stop_pending:\n            notification_center.post_notification('SIPApplicationWillEnd', sender=self)\n            # stop the subsystems we already started: threads, engine and reactor\n            self.engine.stop()\n            self.engine.join(timeout=5)\n            thread_manager = ThreadManager()\n            thread_manager.stop()\n            reactor.stop()\n            return\n\n        account_manager = AccountManager()\n        addressbook_manager = AddressbookManager()\n        dns_manager = DNSManager()\n        session_manager = SessionManager()\n        settings = SIPSimpleSettings()\n\n        xcap_client.DEFAULT_HEADERS = {'User-Agent': settings.user_agent}\n\n        # initialize TLS\n        self._initialize_tls()\n\n        # initialize PJSIP internal resolver\n        self.engine.set_nameservers(dns_manager.nameservers)\n\n        # initialize audio objects\n        alert_device = settings.audio.alert_device\n        if alert_device not in (None, u'system_default') and alert_device not in self.engine.output_devices:\n            alert_device = u'system_default'\n        input_device = settings.audio.input_device\n        if input_device not in (None, u'system_default') and input_device not in self.engine.input_devices:\n            input_device = u'system_default'\n        output_device = settings.audio.output_device\n        if output_device not in (None, u'system_default') and output_device not in self.engine.output_devices:\n            output_device = u'system_default'\n        tail_length = settings.audio.echo_canceller.tail_length if settings.audio.echo_canceller.enabled else 0\n        voice_mixer = AudioMixer(input_device, output_device, settings.audio.sample_rate, tail_length)\n        voice_mixer.muted = settings.audio.muted\n        self.voice_audio_device = AudioDevice(voice_mixer)\n        self.voice_audio_bridge = RootAudioBridge(voice_mixer)\n        self.voice_audio_bridge.add(self.voice_audio_device)\n        alert_mixer = AudioMixer(None, alert_device, settings.audio.sample_rate, 0)\n        if settings.audio.silent:\n            alert_mixer.output_volume = 0\n        self.alert_audio_device = AudioDevice(alert_mixer)\n        self.alert_audio_bridge = RootAudioBridge(alert_mixer)\n        self.alert_audio_bridge.add(self.alert_audio_device)\n\n        settings.audio.input_device = voice_mixer.input_device\n        settings.audio.output_device = voice_mixer.output_device\n        settings.audio.alert_device = alert_mixer.output_device\n\n        # initialize video\n        self.video_device = VideoDevice(settings.video.device, settings.video.resolution, settings.video.framerate)\n        self.video_device.muted = settings.video.muted\n        settings.video.device = self.video_device.name\n        self.engine.set_video_options(settings.video.resolution,\n                                      settings.video.framerate,\n                                      settings.video.max_bitrate)\n        self.engine.set_h264_options(settings.video.h264.profile, settings.video.h264.level)\n\n        # initialize instance id\n        if not settings.instance_id:\n            settings.instance_id = uuid4().urn\n\n        # initialize path for ZRTP cache file\n        if ISIPSimpleApplicationDataStorage.providedBy(self.storage):\n            self.engine.zrtp_cache = os.path.join(self.storage.directory, 'zrtp.db')\n\n        # save settings in case something was modified during startup\n        settings.save()\n\n        # initialize middleware components\n        dns_manager.start()\n        account_manager.start()\n        addressbook_manager.start()\n        session_manager.start()\n\n        notification_center.add_observer(self, name='CFGSettingsObjectDidChange')\n        notification_center.add_observer(self, name='DNSNameserversDidChange')\n        notification_center.add_observer(self, name='SystemIPAddressDidChange')\n        notification_center.add_observer(self, name='SystemDidWakeUpFromSleep')\n\n        with self._lock:\n            self.state = 'started'\n            stop_pending = self._stop_pending\n\n        notification_center.post_notification('SIPApplicationDidStart', sender=self)\n\n        if stop_pending:\n            self.stop()\n\n    @run_in_green_thread\n    def _shutdown_subsystems(self):\n        # cleanup internals\n        if self._timer is not None and self._timer.active():\n            self._timer.cancel()\n        self._timer = None\n\n        # shutdown middleware components\n        dns_manager = DNSManager()\n        account_manager = AccountManager()\n        addressbook_manager = AddressbookManager()\n        session_manager = SessionManager()\n        procs = [proc.spawn(dns_manager.stop), proc.spawn(account_manager.stop), proc.spawn(addressbook_manager.stop), proc.spawn(session_manager.stop)]\n        proc.waitall(procs)\n\n        # stop video device\n        self.video_device.producer.close()\n\n        # shutdown engine\n        self.engine.stop()\n        self.engine.join(timeout=5)\n\n        # stop threads\n        thread_manager = ThreadManager()\n        thread_manager.stop()\n\n        # stop the reactor\n        reactor.stop()\n\n    def _network_conditions_changed(self):\n        if self.running and self._timer is None:\n            def notify():\n                if self.running:\n                    settings = SIPSimpleSettings()\n                    if 'tcp' in settings.sip.transport_list:\n                        self.engine.set_tcp_port(None)\n                        self.engine.set_tcp_port(settings.sip.tcp_port)\n                    if 'tls' in settings.sip.transport_list:\n                        self._initialize_tls()\n                    notification_center = NotificationCenter()\n                    notification_center.post_notification('NetworkConditionsDidChange', sender=self)\n                self._timer = None\n            self._timer = reactor.callLater(5, notify)\n\n    @run_in_twisted_thread\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_SIPEngineDidStart(self, notification):\n        self._initialize_subsystems()\n\n    def _NH_SIPEngineDidFail(self, notification):\n        with self._lock:\n            if self.state == 'stopping':\n                return\n            self.state = 'stopping'\n        notification.center.post_notification('SIPApplicationWillEnd', sender=self)\n        #\n        # In theory we need to stop the subsystems here, based on what subsystems are already running according to our state,\n        # but in practice the majority of those subsystems need the engine even to stop and the engine has failed.\n        #\n        # Even the ThreadManager might have threads that try to execute operations on the engine, which could block indefinitely\n        # waiting for an answer that will no longer arrive, thus blocking the ThreadManager stop operation.\n        #\n        # As a result the safest thing to do is to just stop the engine thread and the reactor, which means in this case we\n        # will not cleanup properly (the engine thread should already have ended as a result of the failure, so stopping it\n        # is technically a no-op).\n        #\n        self.engine.stop()\n        self.engine.join(timeout=5)\n        reactor.stop()\n\n    def _NH_SIPEngineGotException(self, notification):\n        notification.center.post_notification('SIPApplicationGotFatalError', sender=self, data=notification.data)\n\n    @run_in_thread('device-io')\n    def _NH_CFGSettingsObjectDidChange(self, notification):\n        settings = SIPSimpleSettings()\n        account_manager = AccountManager()\n\n        if notification.sender is settings:\n            if 'audio.sample_rate' in notification.data.modified:\n                alert_device = settings.audio.alert_device\n                if alert_device not in (None, u'system_default') and alert_device not in self.engine.output_devices:\n                    alert_device = u'system_default'\n                input_device = settings.audio.input_device\n                if input_device not in (None, u'system_default') and input_device not in self.engine.input_devices:\n                    input_device = u'system_default'\n                output_device = settings.audio.output_device\n                if output_device not in (None, u'system_default') and output_device not in self.engine.output_devices:\n                    output_device = u'system_default'\n                tail_length = settings.audio.echo_canceller.tail_length if settings.audio.echo_canceller.enabled else 0\n                voice_mixer = AudioMixer(input_device, output_device, settings.audio.sample_rate, tail_length)\n                voice_mixer.muted = settings.audio.muted\n                self.voice_audio_device = AudioDevice(voice_mixer)\n                self.voice_audio_bridge = RootAudioBridge(voice_mixer)\n                self.voice_audio_bridge.add(self.voice_audio_device)\n                alert_mixer = AudioMixer(None, alert_device, settings.audio.sample_rate, 0)\n                self.alert_audio_device = AudioDevice(alert_mixer)\n                self.alert_audio_bridge = RootAudioBridge(alert_mixer)\n                self.alert_audio_bridge.add(self.alert_audio_device)\n                if settings.audio.silent:\n                    alert_mixer.output_volume = 0\n                settings.audio.input_device = voice_mixer.input_device\n                settings.audio.output_device = voice_mixer.output_device\n                settings.audio.alert_device = alert_mixer.output_device\n                settings.save()\n            else:\n                if {'audio.input_device', 'audio.output_device', 'audio.alert_device', 'audio.echo_canceller.enabled', 'audio.echo_canceller.tail_length'}.intersection(notification.data.modified):\n                    input_device = settings.audio.input_device\n                    if input_device not in (None, u'system_default') and input_device not in self.engine.input_devices:\n                        input_device = u'system_default'\n                    output_device = settings.audio.output_device\n                    if output_device not in (None, u'system_default') and output_device not in self.engine.output_devices:\n                        output_device = u'system_default'\n                    tail_length = settings.audio.echo_canceller.tail_length if settings.audio.echo_canceller.enabled else 0\n                    if (input_device, output_device, tail_length) != attrgetter('input_device', 'output_device', 'ec_tail_length')(self.voice_audio_bridge.mixer):\n                        self.voice_audio_bridge.mixer.set_sound_devices(input_device, output_device, tail_length)\n                        settings.audio.input_device = self.voice_audio_bridge.mixer.input_device\n                        settings.audio.output_device = self.voice_audio_bridge.mixer.output_device\n                        settings.save()\n                    alert_device = settings.audio.alert_device\n                    if alert_device not in (None, u'system_default') and alert_device not in self.engine.output_devices:\n                        alert_device = u'system_default'\n                    if alert_device != self.alert_audio_bridge.mixer.output_device:\n                        self.alert_audio_bridge.mixer.set_sound_devices(None, alert_device, 0)\n                        settings.audio.alert_device = self.alert_audio_bridge.mixer.output_device\n                        settings.save()\n                if 'audio.muted' in notification.data.modified:\n                    self.voice_audio_bridge.mixer.muted = settings.audio.muted\n                if 'audio.silent' in notification.data.modified:\n                    if settings.audio.silent:\n                        self.alert_audio_bridge.mixer.output_volume = 0\n                    else:\n                        self.alert_audio_bridge.mixer.output_volume = 100\n            if 'video.muted' in notification.data.modified:\n                self.video_device.muted = settings.video.muted\n            if {'video.h264.profile', 'video.h264.level'}.intersection(notification.data.modified):\n                self.engine.set_h264_options(settings.video.h264.profile, settings.video.h264.level)\n            if {'video.device', 'video.resolution', 'video.framerate', 'video.max_bitrate'}.intersection(notification.data.modified):\n                if {'video.device', 'video.resolution', 'video.framerate'}.intersection(notification.data.modified) or settings.video.device != self.video_device.name:\n                    self.video_device.set_camera(settings.video.device, settings.video.resolution, settings.video.framerate)\n                    settings.video.device = self.video_device.name\n                    settings.save()\n                self.engine.set_video_options(settings.video.resolution,\n                                              settings.video.framerate,\n                                              settings.video.max_bitrate)\n            if 'user_agent' in notification.data.modified:\n                self.engine.user_agent = settings.user_agent\n            if 'sip.udp_port' in notification.data.modified:\n                self.engine.set_udp_port(settings.sip.udp_port)\n            if 'sip.tcp_port' in notification.data.modified:\n                self.engine.set_tcp_port(settings.sip.tcp_port)\n            if {'sip.tls_port', 'tls.ca_list', 'default_account'}.intersection(notification.data.modified):\n                self._initialize_tls()\n            if 'rtp.port_range' in notification.data.modified:\n                self.engine.rtp_port_range = (settings.rtp.port_range.start, settings.rtp.port_range.end)\n            if 'rtp.audio_codec_list' in notification.data.modified:\n                self.engine.codecs = list(settings.rtp.audio_codec_list)\n            if 'logs.trace_sip' in notification.data.modified:\n                self.engine.trace_sip = settings.logs.trace_sip\n            if {'logs.trace_pjsip', 'logs.pjsip_level'}.intersection(notification.data.modified):\n                self.engine.log_level = settings.logs.pjsip_level if settings.logs.trace_pjsip else 0\n        elif notification.sender is account_manager.default_account:\n            if {'tls.verify_server', 'tls.certificate'}.intersection(notification.data.modified):\n                self._initialize_tls()\n\n    @run_in_thread('device-io')\n    def _NH_DefaultAudioDeviceDidChange(self, notification):\n        if None in (self.voice_audio_bridge, self.alert_audio_bridge):\n            return\n        settings = SIPSimpleSettings()\n        current_input_device = self.voice_audio_bridge.mixer.input_device\n        current_output_device = self.voice_audio_bridge.mixer.output_device\n        current_alert_device = self.alert_audio_bridge.mixer.output_device\n        ec_tail_length = self.voice_audio_bridge.mixer.ec_tail_length\n        if notification.data.changed_input and u'system_default' in (current_input_device, settings.audio.input_device):\n            self.voice_audio_bridge.mixer.set_sound_devices(u'system_default', current_output_device, ec_tail_length)\n        if notification.data.changed_output and u'system_default' in (current_output_device, settings.audio.output_device):\n            self.voice_audio_bridge.mixer.set_sound_devices(current_input_device, u'system_default', ec_tail_length)\n        if notification.data.changed_output and u'system_default' in (current_alert_device, settings.audio.alert_device):\n            self.alert_audio_bridge.mixer.set_sound_devices(None, u'system_default', 0)\n\n    @run_in_thread('device-io')\n    def _NH_AudioDevicesDidChange(self, notification):\n        old_devices = set(notification.data.old_devices)\n        new_devices = set(notification.data.new_devices)\n        removed_devices = old_devices - new_devices\n\n        if not removed_devices:\n            return\n\n        input_device = self.voice_audio_bridge.mixer.input_device\n        output_device = self.voice_audio_bridge.mixer.output_device\n        alert_device = self.alert_audio_bridge.mixer.output_device\n        if self.voice_audio_bridge.mixer.real_input_device in removed_devices:\n            input_device = u'system_default' if new_devices else None\n        if self.voice_audio_bridge.mixer.real_output_device in removed_devices:\n            output_device = u'system_default' if new_devices else None\n        if self.alert_audio_bridge.mixer.real_output_device in removed_devices:\n            alert_device = u'system_default' if new_devices else None\n\n        self.voice_audio_bridge.mixer.set_sound_devices(input_device, output_device, self.voice_audio_bridge.mixer.ec_tail_length)\n        self.alert_audio_bridge.mixer.set_sound_devices(None, alert_device, 0)\n\n        settings = SIPSimpleSettings()\n        settings.audio.input_device = self.voice_audio_bridge.mixer.input_device\n        settings.audio.output_device = self.voice_audio_bridge.mixer.output_device\n        settings.audio.alert_device = self.alert_audio_bridge.mixer.output_device\n        settings.save()\n\n    @run_in_thread('device-io')\n    def _NH_VideoDevicesDidChange(self, notification):\n        old_devices = set(notification.data.old_devices)\n        new_devices = set(notification.data.new_devices)\n        removed_devices = old_devices - new_devices\n\n        if not removed_devices:\n            return\n\n        device = self.video_device.name\n        if self.video_device.real_name in removed_devices:\n            device = u'system_default' if new_devices else None\n\n        settings = SIPSimpleSettings()\n        self.video_device.set_camera(device, settings.video.resolution, settings.video.framerate)\n        settings.video.device = self.video_device.name\n        settings.save()\n\n    def _NH_DNSNameserversDidChange(self, notification):\n        if self.running:\n            self.engine.set_nameservers(notification.data.nameservers)\n            notification.center.post_notification('NetworkConditionsDidChange', sender=self)\n\n    def _NH_SystemIPAddressDidChange(self, notification):\n        self._network_conditions_changed()\n\n    def _NH_SystemDidWakeUpFromSleep(self, notification):\n        self._network_conditions_changed()\n\n"
  },
  {
    "path": "sipsimple/audio.py",
    "content": "\n\"\"\"Audio support\"\"\"\n\nfrom __future__ import absolute_import\n\n__all__ = ['IAudioPort', 'AudioDevice', 'AudioBridge', 'RootAudioBridge', 'AudioConference', 'WavePlayer', 'WavePlayerError', 'WaveRecorder']\n\nimport os\nimport weakref\nfrom functools import partial\nfrom itertools import combinations\nfrom threading import RLock\n\nfrom application.notification import IObserver, NotificationCenter, NotificationData, ObserverWeakrefProxy\nfrom application.system import makedirs\nfrom eventlib import coros\nfrom twisted.internet import reactor\nfrom zope.interface import Attribute, Interface, implements\n\nfrom sipsimple.core import MixerPort, RecordingWaveFile, SIPCoreError, WaveFile\nfrom sipsimple.threading import run_in_twisted_thread\nfrom sipsimple.threading.green import Command, run_in_green_thread, run_in_waitable_green_thread\n\n\nclass WavePlayerError(Exception):\n    pass\n\n\nclass IAudioPort(Interface):\n    \"\"\"\n    Interface describing an object which can produce and/or consume audio data.\n\n    If an object cannot produce audio data, its producer_slot attribute must be\n    None; similarly, if an object cannot consume audio data, its consumer_slot\n    attribute must be None.\n\n    As part of the interface, whenever an IAudioPort implementation changes its\n    slot attributes, it must send a AudioPortDidChangeSlots notification with\n    the following attributes in the notification data:\n     * consumer_slot_changed\n     * producer_slot_changed\n     * old_consumer_slot (only required if consumer_slot_changed is True)\n     * new_consumer_slot (only required if consumer_slot_changed is True)\n     * old_producer_slot (only required if producer_slot_changed is True)\n     * new_producer_slot (only required if producer_slot_changed is True)\n\n    All attributes of this interface are read-only.\n    \"\"\"\n\n    mixer         = Attribute(\"The mixer that is responsible for mixing the audio data to/from this audio port\")\n    consumer_slot = Attribute(\"The slot to which audio data can be written\")\n    producer_slot = Attribute(\"The slot from which audio data can be read\")\n\n\nclass AudioDevice(object):\n    \"\"\"\n    Objects of this class represent an audio device which can be used in an\n    AudioBridge as they implement the IAudioPort interface. Since a mixer is\n    connected to an audio device which provides the mixer's clock, an\n    AudioDevice constructed for a specific mixer represents the device that\n    mixer is using.\n    \"\"\"\n\n    implements(IAudioPort)\n\n    def __init__(self, mixer, input_muted=False, output_muted=False):\n        self.mixer = mixer\n        self.__dict__['input_muted'] = input_muted\n        self.__dict__['output_muted'] = output_muted\n\n    @property\n    def consumer_slot(self):\n        return 0 if not self.output_muted else None\n\n    @property\n    def producer_slot(self):\n        return 0 if not self.input_muted else None\n\n    @property\n    def input_muted(self):\n        return self.__dict__['input_muted']\n\n    @input_muted.setter\n    def input_muted(self, value):\n        if not isinstance(value, bool):\n            raise ValueError('illegal value for input_muted property: %r' % (value,))\n        if value == self.input_muted:\n            return\n        old_producer_slot = self.producer_slot\n        self.__dict__['input_muted'] = value\n        notification_center = NotificationCenter()\n        notification_center.post_notification('AudioPortDidChangeSlots', sender=self, data=NotificationData(consumer_slot_changed=False, producer_slot_changed=True,\n                                                                                                            old_producer_slot=old_producer_slot, new_producer_slot=self.producer_slot))\n\n    @property\n    def output_muted(self):\n        return self.__dict__['output_muted']\n\n    @output_muted.setter\n    def output_muted(self, value):\n        if not isinstance(value, bool):\n            raise ValueError('illegal value for output_muted property: %r' % (value,))\n        if value == self.output_muted:\n            return\n        old_consumer_slot = self.consumer_slot\n        self.__dict__['output_muted'] = value\n        notification_center = NotificationCenter()\n        notification_center.post_notification('AudioPortDidChangeSlots', sender=self, data=NotificationData(consumer_slot_changed=True, producer_slot_changed=False,\n                                                                                                            old_consumer_slot=old_consumer_slot, new_consumer_slot=self.consumer_slot))\n\n\nclass AudioBridge(object):\n    \"\"\"\n    An AudioBridge is a container for objects providing the IAudioPort interface.\n    It connects all such objects in a full-mesh such that all audio producers\n    are connected to all consumers.\n\n    AudioBridge implements the IAudioPort interface which means a bridge can\n    contain another bridge. This must be done such that the resulting structure\n    is a tree (i.e. no loops are allowed). All leafs of the tree will be\n    connected as if they were the children of a single bridge.\n    \"\"\"\n\n    implements(IAudioPort, IObserver)\n\n    def __init__(self, mixer):\n        self._lock = RLock()\n        self.ports = set()\n        self.mixer = mixer\n        self.multiplexer = MixerPort(mixer)\n        self.demultiplexer = MixerPort(mixer)\n        self.multiplexer.start()\n        self.demultiplexer.start()\n        notification_center = NotificationCenter()\n        notification_center.add_observer(ObserverWeakrefProxy(self), name='AudioPortDidChangeSlots')\n\n    def __del__(self):\n        self.multiplexer.stop()\n        self.demultiplexer.stop()\n        if len(self.ports) >= 2:\n            for port1, port2 in ((wr1(), wr2()) for wr1, wr2 in combinations(self.ports, 2)):\n                if port1 is None or port2 is None:\n                    continue\n                if port1.producer_slot is not None and port2.consumer_slot is not None:\n                    self.mixer.disconnect_slots(port1.producer_slot, port2.consumer_slot)\n                if port2.producer_slot is not None and port1.consumer_slot is not None:\n                    self.mixer.disconnect_slots(port2.producer_slot, port1.consumer_slot)\n        self.ports.clear()\n\n    def __contains__(self, port):\n        return weakref.ref(port) in self.ports\n\n    @property\n    def consumer_slot(self):\n        return self.demultiplexer.slot if self.demultiplexer.is_active else None\n\n    @property\n    def producer_slot(self):\n        return self.multiplexer.slot if self.multiplexer.is_active else None\n\n    def add(self, port):\n        with self._lock:\n            if not IAudioPort.providedBy(port):\n                raise TypeError(\"expected object implementing IAudioPort, got %s\" % port.__class__.__name__)\n            if port.mixer is not self.mixer:\n                raise ValueError(\"expected port with Mixer %r, got %r\" % (self.mixer, port.mixer))\n            if weakref.ref(port) in self.ports:\n                return\n            if port.consumer_slot is not None and self.demultiplexer.slot is not None:\n                self.mixer.connect_slots(self.demultiplexer.slot, port.consumer_slot)\n            if port.producer_slot is not None and self.multiplexer.slot is not None:\n                self.mixer.connect_slots(port.producer_slot, self.multiplexer.slot)\n            for other in (wr() for wr in self.ports):\n                if other is None:\n                    continue\n                if other.producer_slot is not None and port.consumer_slot is not None:\n                    self.mixer.connect_slots(other.producer_slot, port.consumer_slot)\n                if port.producer_slot is not None and other.consumer_slot is not None:\n                    self.mixer.connect_slots(port.producer_slot, other.consumer_slot)\n            # This hack is required because a weakly referenced object keeps a\n            # strong reference to weak references of itself and thus to any\n            # callbacks registered in those weak references. To be more\n            # precise, we don't want the port to have a strong reference to\n            # ourselves. -Luci\n            self.ports.add(weakref.ref(port, partial(self._remove_port, weakref.ref(self))))\n\n    def remove(self, port):\n        with self._lock:\n            if weakref.ref(port) not in self.ports:\n                raise ValueError(\"port %r is not part of this bridge\" % port)\n            if port.consumer_slot is not None and self.demultiplexer.slot is not None:\n                self.mixer.disconnect_slots(self.demultiplexer.slot, port.consumer_slot)\n            if port.producer_slot is not None and self.multiplexer.slot is not None:\n                self.mixer.disconnect_slots(port.producer_slot, self.multiplexer.slot)\n            for other in (wr() for wr in self.ports):\n                if other is None:\n                    continue\n                if other.producer_slot is not None and port.consumer_slot is not None:\n                    self.mixer.disconnect_slots(other.producer_slot, port.consumer_slot)\n                if port.producer_slot is not None and other.consumer_slot is not None:\n                    self.mixer.disconnect_slots(port.producer_slot, other.consumer_slot)\n            self.ports.remove(weakref.ref(port))\n\n    def stop(self):\n        with self._lock:\n            for port1 in (wr() for wr in self.ports):\n                if port1 is None:\n                    continue\n                for port2 in (wr() for wr in self.ports):\n                    if port2 is None or port2 is port1:\n                        continue\n                    if port1.producer_slot is not None and port2.consumer_slot is not None:\n                        self.mixer.disconnect_slots(port1.producer_slot, port2.consumer_slot)\n                    if port2.producer_slot is not None and port1.consumer_slot is not None:\n                        self.mixer.disconnect_slots(port2.producer_slot, port1.consumer_slot)\n            self.ports.clear()\n            self.multiplexer.stop()\n            self.demultiplexer.stop()\n\n    def handle_notification(self, notification):\n        with self._lock:\n            if weakref.ref(notification.sender) not in self.ports:\n                return\n            if notification.data.consumer_slot_changed:\n                if notification.data.old_consumer_slot is not None and self.demultiplexer.slot is not None:\n                    self.mixer.disconnect_slots(self.demultiplexer.slot, notification.data.old_consumer_slot)\n                if notification.data.new_consumer_slot is not None and self.demultiplexer.slot is not None:\n                    self.mixer.connect_slots(self.demultiplexer.slot, notification.data.new_consumer_slot)\n                for other in (wr() for wr in self.ports):\n                    if other is None or other is notification.sender or other.producer_slot is None:\n                        continue\n                    if notification.data.old_consumer_slot is not None:\n                        self.mixer.disconnect_slots(other.producer_slot, notification.data.old_consumer_slot)\n                    if notification.data.new_consumer_slot is not None:\n                        self.mixer.connect_slots(other.producer_slot, notification.data.new_consumer_slot)\n            if notification.data.producer_slot_changed:\n                if notification.data.old_producer_slot is not None and self.multiplexer.slot is not None:\n                    self.mixer.disconnect_slots(notification.data.old_producer_slot, self.multiplexer.slot)\n                if notification.data.new_producer_slot is not None and self.multiplexer.slot is not None:\n                    self.mixer.connect_slots(notification.data.new_producer_slot, self.multiplexer.slot)\n                for other in (wr() for wr in self.ports):\n                    if other is None or other is notification.sender or other.consumer_slot is None:\n                        continue\n                    if notification.data.old_producer_slot is not None:\n                        self.mixer.disconnect_slots(notification.data.old_producer_slot, other.consumer_slot)\n                    if notification.data.new_producer_slot is not None:\n                        self.mixer.connect_slots(notification.data.new_producer_slot, other.consumer_slot)\n\n    @staticmethod\n    def _remove_port(selfwr, portwr):\n        self = selfwr()\n        if self is not None:\n            with self._lock:\n                self.ports.discard(portwr)\n\n\nclass RootAudioBridge(object):\n    \"\"\"\n    A RootAudioBridge is a container for objects providing the IAudioPort\n    interface. It connects all such objects in a full-mesh such that all audio\n    producers are connected to all consumers.\n\n    The difference between a RootAudioBridge and an AudioBridge is that the\n    RootAudioBridge does not implement the IAudioPort interface. This makes it\n    more efficient.\n    \"\"\"\n\n    implements(IObserver)\n\n    def __init__(self, mixer):\n        self.mixer = mixer\n        self.ports = set()\n        self._lock = RLock()\n        notification_center = NotificationCenter()\n        notification_center.add_observer(ObserverWeakrefProxy(self), name='AudioPortDidChangeSlots')\n\n    def __del__(self):\n        if len(self.ports) >= 2:\n            for port1, port2 in ((wr1(), wr2()) for wr1, wr2 in combinations(self.ports, 2)):\n                if port1 is None or port2 is None:\n                    continue\n                if port1.producer_slot is not None and port2.consumer_slot is not None:\n                    self.mixer.disconnect_slots(port1.producer_slot, port2.consumer_slot)\n                if port2.producer_slot is not None and port1.consumer_slot is not None:\n                    self.mixer.disconnect_slots(port2.producer_slot, port1.consumer_slot)\n        self.ports.clear()\n\n    def __contains__(self, port):\n        return weakref.ref(port) in self.ports\n\n    def add(self, port):\n        with self._lock:\n            if not IAudioPort.providedBy(port):\n                raise TypeError(\"expected object implementing IAudioPort, got %s\" % port.__class__.__name__)\n            if port.mixer is not self.mixer:\n                raise ValueError(\"expected port with Mixer %r, got %r\" % (self.mixer, port.mixer))\n            if weakref.ref(port) in self.ports:\n                return\n            for other in (wr() for wr in self.ports):\n                if other is None:\n                    continue\n                if other.producer_slot is not None and port.consumer_slot is not None:\n                    self.mixer.connect_slots(other.producer_slot, port.consumer_slot)\n                if port.producer_slot is not None and other.consumer_slot is not None:\n                    self.mixer.connect_slots(port.producer_slot, other.consumer_slot)\n            # This hack is required because a weakly referenced object keeps a\n            # strong reference to weak references of itself and thus to any\n            # callbacks registered in those weak references. To be more\n            # precise, we don't want the port to have a strong reference to\n            # ourselves. -Luci\n            self.ports.add(weakref.ref(port, partial(self._remove_port, weakref.ref(self))))\n\n    def remove(self, port):\n        with self._lock:\n            if weakref.ref(port) not in self.ports:\n                raise ValueError(\"port %r is not part of this bridge\" % port)\n            for other in (wr() for wr in self.ports):\n                if other is None:\n                    continue\n                if other.producer_slot is not None and port.consumer_slot is not None:\n                    self.mixer.disconnect_slots(other.producer_slot, port.consumer_slot)\n                if port.producer_slot is not None and other.consumer_slot is not None:\n                    self.mixer.disconnect_slots(port.producer_slot, other.consumer_slot)\n            self.ports.remove(weakref.ref(port))\n\n    def handle_notification(self, notification):\n        with self._lock:\n            if weakref.ref(notification.sender) not in self.ports:\n                return\n            if notification.data.consumer_slot_changed:\n                for other in (wr() for wr in self.ports):\n                    if other is None or other is notification.sender or other.producer_slot is None:\n                        continue\n                    if notification.data.old_consumer_slot is not None:\n                        self.mixer.disconnect_slots(other.producer_slot, notification.data.old_consumer_slot)\n                    if notification.data.new_consumer_slot is not None:\n                        self.mixer.connect_slots(other.producer_slot, notification.data.new_consumer_slot)\n            if notification.data.producer_slot_changed:\n                for other in (wr() for wr in self.ports):\n                    if other is None or other is notification.sender or other.consumer_slot is None:\n                        continue\n                    if notification.data.old_producer_slot is not None:\n                        self.mixer.disconnect_slots(notification.data.old_producer_slot, other.consumer_slot)\n                    if notification.data.new_producer_slot is not None:\n                        self.mixer.connect_slots(notification.data.new_producer_slot, other.consumer_slot)\n\n    @staticmethod\n    def _remove_port(selfwr, portwr):\n        self = selfwr()\n        if self is not None:\n            with self._lock:\n                self.ports.discard(portwr)\n\n\nclass AudioConference(object):\n    def __init__(self):\n        from sipsimple.application import SIPApplication\n        mixer = SIPApplication.voice_audio_mixer\n        self.bridge = RootAudioBridge(mixer)\n        self.device = AudioDevice(mixer)\n        self.on_hold = False\n        self.streams = []\n        self._lock = RLock()\n        self.bridge.add(self.device)\n\n    def add(self, stream):\n        with self._lock:\n            if stream in self.streams:\n                return\n            stream.bridge.remove(stream.device)\n            self.bridge.add(stream.bridge)\n            self.streams.append(stream)\n\n    def remove(self, stream):\n        with self._lock:\n            self.streams.remove(stream)\n            self.bridge.remove(stream.bridge)\n            stream.bridge.add(stream.device)\n\n    def hold(self):\n        with self._lock:\n            if self.on_hold:\n                return\n            self.bridge.remove(self.device)\n            self.on_hold = True\n\n    def unhold(self):\n        with self._lock:\n            if not self.on_hold:\n                return\n            self.bridge.add(self.device)\n            self.on_hold = False\n\n\nclass WavePlayer(object):\n    \"\"\"\n    An object capable of playing a WAV file. It can be used as part of an\n    AudioBridge as it implements the IAudioPort interface.\n    \"\"\"\n\n    implements(IAudioPort, IObserver)\n\n    def __init__(self, mixer, filename, volume=100, loop_count=1, pause_time=0, initial_delay=0):\n        self.mixer = mixer\n        self.filename = filename\n        self.initial_delay = initial_delay\n        self.loop_count = loop_count\n        self.pause_time = pause_time\n        self.volume = volume\n        self._channel = None\n        self._current_loop = 0\n        self._state = 'stopped'\n        self._wave_file = None\n\n    @property\n    def is_active(self):\n        return self._state == \"started\"\n\n    @property\n    def consumer_slot(self):\n        return None\n\n    @property\n    def producer_slot(self):\n        return self._wave_file.slot if self._wave_file else None\n\n    def start(self):\n        self.play()\n\n    @run_in_green_thread  # run stop in a green thread in order to be similar with start/play. this avoids start/stop running out of order.\n    def stop(self):\n        if self._state != 'started':\n            return\n        self._channel.send(Command('stop'))\n\n    @run_in_waitable_green_thread\n    def play(self):\n        if self._state != 'stopped':\n            raise WavePlayerError('already playing')\n        self._state = 'started'\n        self._channel = coros.queue()\n        self._current_loop = 0\n        if self.initial_delay:\n            reactor.callLater(self.initial_delay, self._channel.send, Command('play'))\n        else:\n            self._channel.send(Command('play'))\n        self._run().wait()\n\n    @run_in_waitable_green_thread\n    def _run(self):\n        notification_center = NotificationCenter()\n        try:\n            while True:\n                command = self._channel.wait()\n                if command.name == 'play':\n                    self._wave_file = WaveFile(self.mixer, self.filename)\n                    notification_center.add_observer(self, sender=self._wave_file, name='WaveFileDidFinishPlaying')\n                    self._wave_file.volume = self.volume\n                    try:\n                        self._wave_file.start()\n                    except SIPCoreError, e:\n                        notification_center.post_notification('WavePlayerDidFail', sender=self, data=NotificationData(error=e))\n                        raise WavePlayerError(e)\n                    else:\n                        if self._current_loop == 0:\n                            notification_center.post_notification('WavePlayerDidStart', sender=self)\n                        notification_center.post_notification('AudioPortDidChangeSlots', sender=self, data=NotificationData(consumer_slot_changed=False, producer_slot_changed=True,\n                                                                                                                            old_producer_slot=None, new_producer_slot=self._wave_file.slot))\n                elif command.name == 'reschedule':\n                    self._current_loop += 1\n                    notification_center.remove_observer(self, sender=self._wave_file, name='WaveFileDidFinishPlaying')\n                    self._wave_file = None\n                    notification_center.post_notification('AudioPortDidChangeSlots', sender=self, data=NotificationData(consumer_slot_changed=False, producer_slot_changed=True,\n                                                                                                                        old_producer_slot=None, new_producer_slot=None))\n                    if self.loop_count == 0 or self._current_loop < self.loop_count:\n                        reactor.callLater(self.pause_time, self._channel.send, Command('play'))\n                    else:\n                        notification_center.post_notification('WavePlayerDidEnd', sender=self)\n                        break\n                elif command.name == 'stop':\n                    if self._wave_file is not None:\n                        notification_center.remove_observer(self, sender=self._wave_file, name='WaveFileDidFinishPlaying')\n                        self._wave_file.stop()\n                        self._wave_file = None\n                        notification_center.post_notification('AudioPortDidChangeSlots', sender=self, data=NotificationData(consumer_slot_changed=False, producer_slot_changed=True,\n                                                                                                                            old_producer_slot=None, new_producer_slot=None))\n                        notification_center.post_notification('WavePlayerDidEnd', sender=self)\n                    break\n        finally:\n            self._channel = None\n            self._state = 'stopped'\n\n    @run_in_twisted_thread\n    def handle_notification(self, notification):\n        if self._channel is not None:\n            self._channel.send(Command('reschedule'))\n\n\nclass WaveRecorder(object):\n    \"\"\"\n    An object capable of recording to a WAV file. It can be used as part of an\n    AudioBridge as it implements the IAudioPort interface.\n    \"\"\"\n\n    implements(IAudioPort)\n\n    def __init__(self, mixer, filename):\n        self.mixer = mixer\n        self.filename = filename\n        self._recording_wave_file = None\n\n    @property\n    def is_active(self):\n        return bool(self._recording_wave_file and self._recording_wave_file.is_active)\n\n    @property\n    def consumer_slot(self):\n        return self._recording_wave_file.slot if self._recording_wave_file else None\n\n    @property\n    def producer_slot(self):\n        return None\n\n    def start(self):\n        # There is still a race condition here in that the directory can be removed\n        # before the PJSIP opens the file. There's nothing that can be done about\n        # it as long as PJSIP doesn't accept an already open file descriptor. -Luci\n        makedirs(os.path.dirname(self.filename))\n        self._recording_wave_file = RecordingWaveFile(self.mixer, self.filename)\n        self._recording_wave_file.start()\n        notification_center = NotificationCenter()\n        notification_center.post_notification('AudioPortDidChangeSlots', sender=self, data=NotificationData(consumer_slot_changed=True, producer_slot_changed=False,\n                                                                                                            old_consumer_slot=None, new_consumer_slot=self._recording_wave_file.slot))\n\n    def stop(self):\n        old_slot = self.consumer_slot\n        self._recording_wave_file.stop()\n        self._recording_wave_file = None\n        notification_center = NotificationCenter()\n        notification_center.post_notification('AudioPortDidChangeSlots', sender=self, data=NotificationData(consumer_slot_changed=True, producer_slot_changed=False,\n                                                                                                            old_consumer_slot=old_slot, new_consumer_slot=None))\n"
  },
  {
    "path": "sipsimple/configuration/__init__.py",
    "content": "\n\"\"\"Generic configuration management\"\"\"\n\n__all__ = ['ConfigurationManager', 'ConfigurationError', 'ObjectNotFoundError', 'DuplicateIDError',\n           'SettingsObjectID', 'SettingsObjectImmutableID', 'AbstractSetting', 'Setting', 'CorrelatedSetting', 'RuntimeSetting',\n           'SettingsStateMeta', 'SettingsState', 'SettingsGroup', 'ItemCollection', 'SettingsObject', 'SettingsObjectExtension',\n           'DefaultValue', 'ModifiedValue', 'ModifiedList', 'PersistentKey', 'ItemContainer', 'ItemManagement']\n\nfrom abc import ABCMeta, abstractmethod\nfrom itertools import chain\nfrom operator import attrgetter\nfrom threading import Lock\nfrom weakref import WeakSet\n\nfrom application.notification import NotificationCenter, NotificationData\nfrom application.python.descriptor import isdescriptor\nfrom application.python.types import Singleton\nfrom application.python.weakref import weakobjectmap\n\nfrom sipsimple import log\nfrom sipsimple.threading import run_in_thread\n\n\n## Exceptions\n\nclass ConfigurationError(Exception): pass\nclass ObjectNotFoundError(ConfigurationError): pass\n\nclass DuplicateIDError(ValueError): pass\n\n\n## Structure markers\n\nclass PersistentKey(unicode):\n    def __repr__(self):\n        return \"%s(%s)\" % (self.__class__.__name__, unicode.__repr__(self))\n\n\nclass ItemContainer(dict):\n    def __repr__(self):\n        return \"%s(%s)\" % (self.__class__.__name__, dict.__repr__(self))\n\n\n## ConfigurationManager\n\nclass ConfigurationManager(object):\n    \"\"\"\n    Singleton class used for storing and retrieving options, organized in\n    sections. A section contains a list of objects, each with an assigned name\n    which allows access to the object.\n    \"\"\"\n    __metaclass__ = Singleton\n\n    def __init__(self):\n        self.backend = None\n        self.data = None\n\n    def start(self):\n        \"\"\"\n        Initialize the ConfigurationManager to use the specified backend. This\n        method can only be called once, with an object which provides IBackend.\n        The other methods of the object cannot be used unless this method was\n        called.\n        \"\"\"\n        from sipsimple.application import SIPApplication\n        from sipsimple.configuration.backend import IConfigurationBackend\n        if self.backend is not None:\n            raise RuntimeError(\"ConfigurationManager already started\")\n        if SIPApplication.storage is None:\n            raise RuntimeError(\"SIPApplication.storage must be defined before starting the ConfigurationManager\")\n        backend = SIPApplication.storage.configuration_backend\n        if not IConfigurationBackend.providedBy(backend):\n            raise TypeError(\"SIPApplication.storage.configuration_backend must implement the IConfigurationBackend interface\")\n        self.data = backend.load()\n        self.backend = backend\n\n    def update(self, key, data):\n        \"\"\"\n        Save the object's data under the tree path specified by key (a list\n        of strings). Cannot be called before start().\n        \"\"\"\n        if self.backend is None:\n            raise RuntimeError(\"ConfigurationManager cannot be used unless started\")\n        if not key:\n            raise KeyError(\"key cannot be empty\")\n        self._update(self.data, list(key), data)\n\n    def rename(self, old_key, new_key):\n        \"\"\"\n        Rename the object identified by old_key to new_key (list of strings).\n        Cannot be called before start().\n        \"\"\"\n        if self.backend is None:\n            raise RuntimeError(\"ConfigurationManager cannot be used unless started\")\n        if not old_key or not new_key:\n            raise KeyError(\"old_key and/or new_key cannot be empty\")\n        try:\n            data = self._pop(self.data, list(old_key))\n        except KeyError:\n            raise ObjectNotFoundError(\"object %s does not exist\" % '/'.join(old_key))\n        self._insert(self.data, list(new_key), data)\n\n    def delete(self, key):\n        \"\"\"\n        Delete the object in the tree path specified by key (list of strings).\n        Cannot be called before start().\n        \"\"\"\n        if self.backend is None:\n            raise RuntimeError(\"ConfigurationManager cannot be used unless started\")\n        if not key:\n            raise KeyError(\"key cannot be empty\")\n        try:\n            self._pop(self.data, list(key))\n        except KeyError:\n            pass\n\n    def get(self, key):\n        \"\"\"\n        Get the object in the tree path specified by key (list of strings).\n        Raises ObjectNotFoundError if the object does not exist. Cannot be\n        called before start().\n        \"\"\"\n        if self.backend is None:\n            raise RuntimeError(\"ConfigurationManager cannot be used unless started\")\n        if not key:\n            raise KeyError(\"key cannot be empty\")\n        try:\n            return self._get(self.data, list(key))\n        except KeyError:\n            raise ObjectNotFoundError(\"object %s does not exist\" % '/'.join(key))\n\n    def get_names(self, key):\n        \"\"\"\n        Get all the names under the specified key (a list of strings).\n        Returns a list containing the names. Cannot be called before start().\n        \"\"\"\n        if self.backend is None:\n            raise RuntimeError(\"ConfigurationManager cannot be used unless started\")\n        if not key:\n            raise KeyError(\"key cannot be empty\")\n        try:\n            data = self._get(self.data, list(key))\n            return data.keys()\n        except KeyError:\n            return []\n\n    def save(self):\n        \"\"\"\n        Flush the modified objects. Cannot be called before start().\n        \"\"\"\n        if self.backend is None:\n            raise RuntimeError(\"ConfigurationManager cannot be used unless started\")\n        self.backend.save(self.data)\n\n    def _get(self, data_tree, key):\n        subtree_key = key.pop(0)\n        data_subtree = data_tree[subtree_key]\n        if key:\n            return self._get(data_subtree, key)\n        else:\n            return data_subtree\n\n    def _insert(self, data_tree, key, data):\n        subtree_key = key.pop(0)\n        data_subtree = data_tree.setdefault(subtree_key, {})\n        if key:\n            self._insert(data_subtree, key, data)\n        else:\n            data_subtree.update(data)\n\n    def _pop(self, data_tree, key):\n        subtree_key = key.pop(0)\n        data_subtree = data_tree[subtree_key]\n        if key:\n            data = self._pop(data_subtree, key)\n            if not isinstance(subtree_key, PersistentKey) and not data_subtree:\n                del data_tree[subtree_key]\n            return data\n        else:\n            return data_tree.pop(subtree_key)\n\n    def _update(self, data_tree, key, data):\n        subtree_key = key.pop(0)\n        data_subtree = data_tree.setdefault(subtree_key, {})\n        if key:\n            self._update(data_subtree, key, data)\n        else:\n            self._update_dict(data_subtree, data)\n        if not isinstance(subtree_key, PersistentKey) and not data_subtree:\n            del data_tree[subtree_key]\n\n    def _update_dict(self, old_data, new_data):\n        for key, value in new_data.iteritems():\n            if value is DefaultValue:\n                old_data.pop(key, None)\n            elif isinstance(value, ItemContainer):\n                if key not in old_data or type(old_data[key]) is not dict:\n                    old_data[key] = {}\n                key_subtree = old_data[key]\n                for removed_key in set(key_subtree) - set(value):\n                    del key_subtree[removed_key]\n                self._update_dict(key_subtree, value)\n                if not key_subtree:\n                    del old_data[key]\n            elif type(value) is dict:\n                if key in old_data and type(old_data[key]) is not dict:\n                    del old_data[key]\n                self._update_dict(old_data.setdefault(key, {}), value)\n                if not old_data[key]:\n                    del old_data[key]\n            else:\n                old_data[key] = value\n\n\n# Descriptors and base classes used for representing configuration settings\n\nclass DefaultValue(object):\n    \"\"\"\n    This object can be set as the value for a setting and it will reset the\n    setting to the default value.\n    \"\"\"\n\n\nclass ModifiedValue(object):\n    \"\"\"\n    Instances of this class represent the state (the old and new values) of\n    settings.\n    \"\"\"\n\n    __slots__ = ('old', 'new')\n\n    def __init__(self, old, new):\n        self.old = old\n        self.new = new\n\n    def __repr__(self):\n        return '%s(old=%r, new=%r)' % (self.__class__.__name__, self.old, self.new)\n\n\nclass ModifiedList(object):\n    \"\"\"\n    Represents the modified state (added, removed, modified) of list like\n    settings.\n    \"\"\"\n\n    __slots__ = ('added', 'removed', 'modified')\n\n    def __init__(self, added, removed, modified):\n        self.added = added\n        self.removed = removed\n        self.modified = modified\n\n    def __repr__(self):\n        return '%s(added=%r, removed=%r, modified=%r)' % (self.__class__.__name__, self.added, self.removed, self.modified)\n\n\nclass SettingsObjectID(object):\n    \"\"\"\n    Descriptor for dynamic configuration object IDs.\n    \"\"\"\n\n    def __init__(self, type):\n        self.type = type\n        self.values = weakobjectmap()\n        self.oldvalues = weakobjectmap()\n        self.dirty = weakobjectmap()\n        self.lock = Lock()\n\n    def __get__(self, obj, objtype):\n        return self if obj is None else self.values[obj]\n\n    def __set__(self, obj, value):\n        with self.lock:\n            if not isinstance(value, self.type):\n                value = self.type(value)\n            if obj in self.values and self.values[obj] == value:\n                return\n            if obj in self.oldvalues and self.oldvalues[obj] == value:\n                self.values[obj] = self.oldvalues[obj]\n                self.dirty[obj] = False\n                return\n            try:\n                other_obj = (key for key, val in chain(self.values.iteritems(), self.oldvalues.iteritems()) if val==value).next()\n            except StopIteration:\n                pass\n            else:\n                raise DuplicateIDError('SettingsObject ID already used by another %s' % other_obj.__class__.__name__)\n            if obj in self.values:\n                self.values[obj] = value\n                self.dirty[obj] = True\n            else:\n                self.values[obj] = self.oldvalues[obj] = value\n                self.dirty[obj] = False\n\n    def __delete__(self, obj):\n        raise AttributeError('cannot delete attribute')\n\n    def get_modified(self, obj):\n        \"\"\"\n        Returns a ModifiedValue instance with references to the old and new\n        values or None if not modified.\n        \"\"\"\n        with self.lock:\n            try:\n                if self.dirty.get(obj, False):\n                    return ModifiedValue(old=self.oldvalues[obj], new=self.values[obj])\n                else:\n                    return None\n            finally:\n                self.oldvalues[obj] = self.values[obj]\n                self.dirty[obj] = False\n\n    def get_old(self, obj):\n        return self.oldvalues[obj]\n\n    def undo(self, obj):\n        with self.lock:\n            self.values[obj] = self.oldvalues[obj]\n            self.dirty[obj] = False\n\n\nclass SettingsObjectImmutableID(object):\n    \"\"\"\n    Descriptor for immutable runtime allocated configuration object IDs.\n    \"\"\"\n\n    def __init__(self, type):\n        self.type = type\n        self.values = weakobjectmap()\n        self.lock = Lock()\n\n    def __get__(self, obj, objtype):\n        return self if obj is None else self.values[obj]\n\n    def __set__(self, obj, value):\n        with self.lock:\n            if obj in self.values:\n                raise AttributeError('attribute is read-only')\n            if not isinstance(value, self.type):\n                value = self.type(value)\n            try:\n                other_obj = (key for key, val in self.values.iteritems() if val==value).next()\n            except StopIteration:\n                pass\n            else:\n                raise DuplicateIDError('SettingsObject ID already used by another %s' % other_obj.__class__.__name__)\n            self.values[obj] = value\n\n    def __delete__(self, obj):\n        raise AttributeError('cannot delete attribute')\n\n\nclass AbstractSetting(object):\n    \"\"\"Abstract base class for setting type descriptors\"\"\"\n\n    __metaclass__ = ABCMeta\n\n    @abstractmethod\n    def __get__(self, obj, objtype):\n        raise NotImplementedError\n\n    @abstractmethod\n    def __set__(self, obj, value):\n        raise NotImplementedError\n\n    def __delete__(self, obj):\n        raise AttributeError('cannot delete attribute')\n\n    @abstractmethod\n    def __getstate__(self, obj):\n        raise NotImplementedError\n\n    @abstractmethod\n    def __setstate__(self, obj, value):\n        raise NotImplementedError\n\n    @abstractmethod\n    def get_modified(self, obj):\n        raise NotImplementedError\n\n    @abstractmethod\n    def get_old(self, obj):\n        raise NotImplementedError\n\n    @abstractmethod\n    def undo(self, obj):\n        raise NotImplementedError\n\n\nclass Setting(AbstractSetting):\n    \"\"\"\n    Descriptor representing a setting in a configuration object.\n\n    If a setting is set to the object DefaultValue, it will be reset to the\n    default. Also, only Setting attributes with nillable=True can be assigned\n    the value None. All other values are passed to the type specified.\n    \"\"\"\n\n    def __init__(self, type, default=None, nillable=False):\n        if default is None and not nillable:\n            raise TypeError(\"default must be specified if object is not nillable\")\n        self.type = type\n        self.default = default\n        self.nillable = nillable\n        self.values = weakobjectmap()\n        self.oldvalues = weakobjectmap()\n        self.dirty = weakobjectmap()\n        self.lock = Lock()\n\n    def __get__(self, obj, objtype):\n        if obj is None:\n            return self\n        return self.values.get(obj, self.default)\n\n    def __set__(self, obj, value):\n        with self.lock:\n            if value is None and not self.nillable:\n                raise ValueError(\"setting attribute is not nillable\")\n            if value is DefaultValue:\n                if obj in self.values:\n                    self.values.pop(obj)\n                    self.dirty[obj] = obj in self.oldvalues\n                return\n\n            if value is not None and not isinstance(value, self.type):\n                value = self.type(value)\n            if obj in self.values and self.values[obj] == value:\n                return\n            self.values[obj] = value\n            self.dirty[obj] = value != self.oldvalues.get(obj, DefaultValue)  # if value changes from implicit default (DefaultValue) to explicit default (self.default) we mark it as dirty\n\n    def __getstate__(self, obj):\n        value = self.values.get(obj, DefaultValue)\n        if value in (None, DefaultValue):\n            pass\n        elif issubclass(self.type, bool):\n            value = u'true' if value else u'false'\n        elif issubclass(self.type, (int, long, basestring)):\n            value = unicode(value)\n        elif hasattr(value, '__getstate__'):\n            value = value.__getstate__()\n        else:\n            value = unicode(value)\n        return value\n\n    def __setstate__(self, obj, value):\n        with self.lock:\n            if value is None and not self.nillable:\n                raise ValueError(\"setting attribute is not nillable\")\n            if value is None:\n                pass\n            elif issubclass(self.type, bool):\n                if value.lower() in ('true', 'yes', 'on', '1'):\n                    value = True\n                elif value.lower() in ('false', 'no', 'off', '0'):\n                    value = False\n                else:\n                    raise ValueError(\"invalid boolean value: %s\" % (value,))\n            elif issubclass(self.type, (int, long, basestring)):\n                value = self.type(value)\n            elif hasattr(self.type, '__setstate__'):\n                object = self.type.__new__(self.type)\n                object.__setstate__(value)\n                value = object\n            else:\n                value = self.type(value)\n            self.oldvalues[obj] = self.values[obj] = value\n            self.dirty[obj] = False\n\n    def get_modified(self, obj):\n        \"\"\"\n        Returns a ModifiedValue instance with references to the old and new\n        values or None if not modified.\n        \"\"\"\n        with self.lock:\n            try:\n                if self.dirty.get(obj, False):  # if the object is dirty because it switched from implicit default to explicit default, ModifiedValue will have old==new==self.default (see __set__)\n                    return ModifiedValue(old=self.oldvalues.get(obj, self.default), new=self.values.get(obj, self.default))\n                else:\n                    return None\n            finally:\n                try:\n                    self.oldvalues[obj] = self.values[obj]\n                except KeyError:\n                    self.oldvalues.pop(obj, None)\n                self.dirty[obj] = False\n\n    def get_old(self, obj):\n        return self.oldvalues.get(obj, self.default)\n\n    def undo(self, obj):\n        with self.lock:\n            if obj in self.oldvalues:\n                self.values[obj] = self.oldvalues[obj]\n            else:\n                self.values.pop(obj, None)\n            self.dirty[obj] = False\n\n\nclass CorrelatedSetting(Setting):\n    \"\"\"\n    Descriptor representing a setting in a configuration object that is\n    correlated with another setting on the same configuration object.\n\n    Sibling is the name of the sibling setting and validator is a callable\n    that will receive the setting value and the sibling setting value and\n    should raise an exception if the setting value is not acceptable relative\n    to the sibling setting value.\n\n    If a setting is set to the object DefaultValue, it will be reset to the\n    default. Also, only Setting attributes with nillable=True can be assigned\n    the value None. All other values are passed to the type specified.\n    \"\"\"\n\n    correlation_lock = Lock()\n\n    def __init__(self, type, sibling, validator, default=None, nillable=False):\n        Setting.__init__(self, type, default, nillable)\n        self.sibling = sibling\n        self.validator = validator\n\n    def __set__(self, obj, value):\n        with self.correlation_lock:\n            sibling_value = getattr(obj, self.sibling)\n            self.validator(value, sibling_value)\n            Setting.__set__(self, obj, value)\n\n\nclass RuntimeSetting(Setting):\n    \"\"\"\n    Descriptor representing a runtime setting in a configuration object.\n\n    Unlike the standard setting, the runtime setting is never written to\n    nor read from the configuration file. It resides in memory only and\n    its lifetime ends when the application exits.\n    \"\"\"\n\n    def __getstate__(self, obj):\n        return DefaultValue\n\n    def __setstate__(self, obj, value):\n        pass\n\n\nclass SettingsIndexer(object):\n    __slots__ = ('__object__',)\n\n    def __init__(self, object):\n        self.__object__ = object\n\n    def __getitem__(self, key):\n        return reduce(getattr, key.split('.'), self.__object__.__class__)\n\n\nclass SettingsStateMeta(type):\n    __established__ = WeakSet()\n\n    def __call__(cls, *args, **kw):\n        instance = super(SettingsStateMeta, cls).__call__(*args, **kw)\n        if hasattr(instance, '__establish__') and instance not in cls.__established__:\n            cls.__established__.add(instance)\n            instance.__establish__()\n        return instance\n\n\nclass SettingsState(object):\n    \"\"\"\n    This class represents configuration objects which can be saved and restored.\n    \"\"\"\n\n    __metaclass__ = SettingsStateMeta\n\n    @property\n    def __settings__(self):\n        return SettingsIndexer(self)\n\n    def get_modified(self):\n        \"\"\"\n        Returns a dictionary containing the settings which have been changed.\n        The keys are the full paths to the attributes (from this object), which\n        are mapped to a ModifiedValue instance with references to the old and\n        new values.\n        \"\"\"\n        modified = {}\n        for name in dir(self.__class__):\n            attribute = getattr(self.__class__, name, None)\n            if isinstance(attribute, SettingsGroupMeta):\n                modified_settings = getattr(self, name).get_modified()\n                modified.update(dict((name+'.'+k if k else name, v) for k,v in modified_settings.iteritems()))\n            elif isinstance(attribute, AbstractSetting):\n                modified_value = attribute.get_modified(self)\n                if modified_value is not None:\n                    modified[name] = modified_value\n        return modified\n\n    def clone(self):\n        \"\"\"\n        Create a copy of this object and all its sub settings.\n        \"\"\"\n        raise NotImplementedError\n\n    def update(self, object):\n        \"\"\"\n        Update the settings and sub-settings of this settings object using the\n        ones in the specified object.\n        \"\"\"\n        raise NotImplementedError\n\n    def __getstate__(self):\n        state = {}\n        for name in dir(self.__class__):\n            attribute = getattr(self.__class__, name, None)\n            if isinstance(attribute, SettingsGroupMeta):\n                state[name] = getattr(self, name).__getstate__()\n            elif isinstance(attribute, AbstractSetting):\n                state[name] = attribute.__getstate__(self)\n        return state\n\n    def __setstate__(self, state):\n        configuration_manager = ConfigurationManager()\n        notification_center = NotificationCenter()\n        for name, value in state.iteritems():\n            attribute = getattr(self.__class__, name, None)\n            if isinstance(attribute, SettingsGroupMeta):\n                group = getattr(self, name)\n                try:\n                    group.__setstate__(value)\n                except ValueError, e:\n                    notification_center.post_notification('CFGManagerLoadFailed', sender=configuration_manager, data=NotificationData(attribute=name, container=self, error=e))\n            elif isinstance(attribute, AbstractSetting):\n                try:\n                    attribute.__setstate__(self, value)\n                except ValueError, e:\n                    notification_center.post_notification('CFGManagerLoadFailed', sender=configuration_manager, data=NotificationData(attribute=name, container=self, error=e))\n\n\nclass SettingsGroupMeta(SettingsStateMeta):\n    \"\"\"\n    Metaclass for SettingsGroup and its subclasses which allows them to be used\n    as descriptor instances.\n    \"\"\"\n    def __init__(cls, name, bases, dct):\n        super(SettingsGroupMeta, cls).__init__(name, bases, dct)\n        cls.values = weakobjectmap()\n\n    def __get__(cls, obj, objtype):\n        if obj is None:\n            return cls\n        try:\n            return cls.values[obj]\n        except KeyError:\n            return cls.values.setdefault(obj, cls())\n\n    def __set__(cls, obj, value):\n        raise AttributeError(\"cannot overwrite group of settings\")\n\n    def __delete__(self, obj):\n        raise AttributeError('cannot delete group of settings')\n\n\nclass SettingsGroup(SettingsState):\n    \"\"\"\n    Base class for settings groups, i.e. non-leaf and non-root nodes in the\n    configuration tree. All SettingsGroup subclasses are descriptor instances\n    which return an instance of the subclass type when accessed. All\n    SettingsGroup instances are created without passing any arguments to the\n    constructor.\n\n    class ContainedGroup(SettingsGroup):\n        pass\n    class ContainingGroup(SettingsGroup):\n        subgroup = ContainedGroup\n    \"\"\"\n\n    __metaclass__ = SettingsGroupMeta\n\n\nclass ItemMap(dict):\n    def __init__(self, *args, **kw):\n        super(ItemMap, self).__init__(*args, **kw)\n        self.old = dict(self)\n\n    def get_modified(self):\n        new_ids = set(self)\n        old_ids = set(self.old)\n        added_items = [self[id] for id in new_ids - old_ids]\n        removed_items = [self.old[id] for id in old_ids - new_ids]\n        modified_items = dict((id, modified) for id, modified in ((id, self[id].get_modified()) for id in new_ids & old_ids) if modified)\n        for item in added_items:\n            item.get_modified() # reset the dirty flag of the added items and sync their old and new values\n        if added_items or removed_items or modified_items:\n            self.old = dict(self)\n            return ModifiedList(added=added_items, removed=removed_items, modified=modified_items)\n        else:\n            return None\n\n\nclass ItemManagement(object):\n    def add_item(self, item, collection):\n        pass\n\n    def remove_item(self, item, collection):\n        pass\n\n    def set_items(self, items, collection):\n        pass\n\n\nclass ItemCollectionMeta(SettingsGroupMeta):\n    def __init__(cls, name, bases, dct):\n        if cls._item_type is not None and not issubclass(cls._item_type, SettingsState):\n            raise TypeError('_item_type must be a subclass of SettingsState')\n        if cls._item_type is not None and not isinstance(getattr(cls._item_type, 'id', None), (SettingsObjectID, SettingsObjectImmutableID)):\n            raise ValueError('the type in _item_type must have an id attribute of type SettingsObjectID or SettingsObjectImmutableID')\n        if not isinstance(cls._item_management, ItemManagement):\n            raise TypeError('_item_management must be an instance of a subclass of ItemManagement')\n        super(ItemCollectionMeta, cls).__init__(name, bases, dct)\n\n    def __set__(cls, obj, items):\n        if not all(isinstance(item, cls._item_type) for item in items):\n            raise TypeError(\"items must be instances of %s\" % cls._item_type.__name__)\n        if set(item.id for item in items).intersection(name for name in dir(cls) if isinstance(getattr(cls, name, None), (SettingsGroupMeta, AbstractSetting))):\n            raise ValueError(\"item IDs cannot overlap with static setting names\")\n        collection = cls.__get__(obj, obj.__class__)\n        with collection._lock:\n            collection._item_management.set_items(items, collection)\n            collection._item_map.clear()\n            collection._item_map.update((item.id, item) for item in items)\n\n    def __delete__(self, obj):\n        raise AttributeError('cannot delete item collection')\n\n\nclass ItemCollection(SettingsGroup):\n    \"\"\"A SettingsGroup that also contains a dynamic collection of sub-setting\"\"\"\n\n    __metaclass__ = ItemCollectionMeta\n\n    _item_type = None\n    _item_management = ItemManagement()\n\n    def __init__(self):\n        self._item_map = ItemMap()\n        self._lock = Lock()\n\n    def __getitem__(self, key):\n        return self._item_map[key]\n\n    def __contains__(self, key):\n        return key in self._item_map\n\n    def __iter__(self):\n        return iter(sorted(self._item_map.values(), key=attrgetter('id')))\n\n    def __reversed__(self):\n        return iter(sorted(self._item_map.values(), key=attrgetter('id'), reverse=True))\n\n    __hash__ = None\n\n    def __len__(self):\n        return len(self._item_map)\n\n    def __getstate__(self):\n        with self._lock:\n            state = ItemContainer((id, item.__getstate__()) for id, item in self._item_map.iteritems())\n            state.update(super(ItemCollection, self).__getstate__())\n            return state\n\n    def __setstate__(self, state):\n        with self._lock:\n            super(ItemCollection, self).__setstate__(state)\n            setting_names = set(name for name in dir(self.__class__) if isinstance(getattr(self.__class__, name, None), (SettingsGroupMeta, AbstractSetting)))\n            self._item_map = ItemMap((id, self._item_type(id, **item_state)) for id, item_state in state.iteritems() if id not in setting_names)\n\n    def get_modified(self):\n        with self._lock:\n            modified_settings = super(ItemCollection, self).get_modified()\n            modified_items = self._item_map.get_modified()\n            if modified_items is not None:\n                modified_settings[None] = modified_items\n            return modified_settings\n\n    def ids(self):\n        return sorted(self._item_map.keys())\n\n    def get(self, key, default=None):\n        return self._item_map.get(key, default)\n\n    def add(self, item):\n        if not isinstance(item, self._item_type):\n            raise TypeError(\"item must be an instances of %s\" % self._item_type.__name__)\n        if item.id in set(name for name in dir(self.__class__) if isinstance(getattr(self.__class__, name, None), (SettingsGroupMeta, AbstractSetting))):\n            raise ValueError(\"item IDs cannot overlap with static setting names\")\n        with self._lock:\n            self._item_management.add_item(item, self)\n            self._item_map[item.id] = item\n\n    def remove(self, item):\n        with self._lock:\n            self._item_management.remove_item(item, self)\n            self._item_map.pop(item.id, None)\n\n\nclass ConditionalSingleton(type):\n    \"\"\"A conditional singleton based on cls.__id__ being static or not\"\"\"\n\n    def __init__(cls, name, bases, dic):\n        super(ConditionalSingleton, cls).__init__(name, bases, dic)\n        cls.__instlock__ = Lock()\n        cls.__instance__ = None\n\n    def __call__(cls, *args, **kw):\n        if isinstance(cls.__id__, basestring):\n            if args or kw:\n                raise TypeError(\"cannot have arguments for %s because it is a singleton\" % cls.__name__)\n            with cls.__instlock__:\n                if cls.__instance__ is None:\n                    cls.__instance__ = super(ConditionalSingleton, cls).__call__(*args, **kw)\n            return cls.__instance__\n        else:\n            return super(ConditionalSingleton, cls).__call__(*args, **kw)\n\n\nclass SettingsObjectMeta(SettingsStateMeta, ConditionalSingleton):\n    \"\"\"Metaclass to singleton-ize SettingsObject subclasses with static ids\"\"\"\n\n    def __init__(cls, name, bases, dic):\n        if not (cls.__id__ is None or isinstance(cls.__id__, basestring) or isdescriptor(cls.__id__)):\n            raise TypeError(\"%s.__id__ must be None, a string instance or a descriptor\" % name)\n        super(SettingsObjectMeta, cls).__init__(name, bases, dic)\n\n\nclass SettingsObject(SettingsState):\n    \"\"\"\n    Subclass for top-level configuration objects. These objects are identifiable\n    by either a global id (set in the __id__ attribute of the class) or a local\n    id passed as the sole argument when instantiating SettingsObjects.\n\n    For SettingsObject subclasses which are meant to be used exclusively with a\n    local id, the class attribute __id__ should be left to the value None; if\n    __init__ is defined, it would have to accept exactly one argument: id.\n\n    The local id takes precedence over the one specified as a class attribute.\n\n    Note: __init__ and __new__ will be called not only when a new object is\n    created (i.e. there weren't any settings saved in the configuration), but\n    also when the object is retrieved from the configuration.\n    \"\"\"\n\n    __metaclass__ = SettingsObjectMeta\n\n    __group__ = None\n    __id__ = None\n\n    def __new__(cls, id=None):\n        id = id or cls.__id__\n        if id is None:\n            raise ValueError(\"id is required for instantiating %s\" % cls.__name__)\n        if not isinstance(id, basestring):\n            raise TypeError(\"id needs to be a string instance\")\n        configuration = ConfigurationManager()\n        instance = SettingsState.__new__(cls)\n        instance.__id__ = id\n        instance.__state__ = 'new'\n        try:\n            data = configuration.get(instance.__key__)\n        except ObjectNotFoundError:\n            pass\n        else:\n            instance.__setstate__(data)\n            instance.__state__ = 'loaded'\n        return instance\n\n    def __establish__(self):\n        if self.__state__ == 'loaded' or self.__instance__ is not None:\n            self.__state__ = 'active'\n            notification_center = NotificationCenter()\n            notification_center.post_notification('CFGSettingsObjectWasActivated', sender=self)\n\n    @property\n    def __key__(self):\n        if isinstance(self.__class__.__id__, (SettingsObjectID, SettingsObjectImmutableID)):\n            id_key = PersistentKey(self.__id__)\n        else:\n            id_key = unicode(self.__id__)\n        if self.__group__ is not None:\n            return [self.__group__, id_key]\n        else:\n            return [id_key]\n\n    @property\n    def __oldkey__(self):\n        if isinstance(self.__class__.__id__, SettingsObjectID):\n            id_key = PersistentKey(self.__class__.__id__.get_old(self))\n        elif isinstance(self.__class__.__id__, SettingsObjectImmutableID):\n            id_key = PersistentKey(self.__id__)\n        else:\n            id_key = unicode(self.__id__)\n        if self.__group__ is not None:\n            return [self.__group__, id_key]\n        else:\n            return [id_key]\n\n    @run_in_thread('file-io')\n    def save(self):\n        \"\"\"\n        Use the ConfigurationManager to store the object under its id in the\n        specified group or top-level otherwise, depending on whether group is\n        None.\n\n        This method will also post a CFGSettingsObjectDidChange notification,\n        regardless of whether the settings have been saved to persistent storage\n        or not. If the save does fail, a CFGManagerSaveFailed notification is\n        posted as well.\n        \"\"\"\n\n        if self.__state__ == 'deleted':\n            return\n\n        configuration = ConfigurationManager()\n        notification_center = NotificationCenter()\n\n        oldkey = self.__oldkey__ # save this here as get_modified will reset it\n\n        modified_id = self.__class__.__id__.get_modified(self) if isinstance(self.__class__.__id__, SettingsObjectID) else None\n        modified_settings = self.get_modified()\n\n        if not modified_id and not modified_settings and self.__state__ != 'new':\n            return\n\n        if self.__state__ == 'new':\n            configuration.update(self.__key__, self.__getstate__())\n            self.__state__ = 'active'\n            notification_center.post_notification('CFGSettingsObjectWasActivated', sender=self)\n            notification_center.post_notification('CFGSettingsObjectWasCreated', sender=self)\n            modified_data = None\n        elif not modified_id and all(isinstance(self.__settings__[key], RuntimeSetting) for key in modified_settings):\n            notification_center.post_notification('CFGSettingsObjectDidChange', sender=self, data=NotificationData(modified=modified_settings))\n            return\n        else:\n            if modified_id:\n                configuration.rename(oldkey, self.__key__)\n            if modified_settings:\n                configuration.update(self.__key__, self.__getstate__())\n            modified_data = modified_settings or {}\n            if modified_id:\n                modified_data['__id__'] = modified_id\n            notification_center.post_notification('CFGSettingsObjectDidChange', sender=self, data=NotificationData(modified=modified_data))\n\n        try:\n            configuration.save()\n        except Exception, e:\n            log.exception()\n            notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData(object=self, operation='save', modified=modified_data, exception=e))\n\n    @run_in_thread('file-io')\n    def delete(self):\n        \"\"\"\n        Remove this object from the persistent configuration.\n        \"\"\"\n        if self.__id__ is self.__class__.__id__:\n            raise TypeError(\"cannot delete %s instance with default id\" % self.__class__.__name__)\n        if self.__state__ == 'deleted':\n            return\n        self.__state__ = 'deleted'\n\n        configuration = ConfigurationManager()\n        notification_center = NotificationCenter()\n        configuration.delete(self.__oldkey__) # we need the key that wasn't yet saved\n        notification_center.post_notification('CFGSettingsObjectWasDeleted', sender=self)\n        try:\n            configuration.save()\n        except Exception, e:\n            log.exception()\n            notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData(object=self, operation='delete', exception=e))\n\n    def clone(self, new_id):\n        \"\"\"\n        Create a copy of this object and all its sub settings.\n        \"\"\"\n        raise NotImplementedError\n\n    @classmethod\n    def register_extension(cls, extension):\n        \"\"\"\n        Register an extension of this SettingsObject. All Settings and\n        SettingsGroups defined in the extension will be added to this\n        SettingsObject, overwriting any attributes with the same name.\n        Other attributes in the extension are ignored.\n        \"\"\"\n        if not issubclass(extension, SettingsObjectExtension):\n            raise TypeError(\"expected subclass of SettingsObjectExtension, got %r\" % (extension,))\n        for name in dir(extension):\n            attribute = getattr(extension, name, None)\n            if isinstance(attribute, (AbstractSetting, SettingsGroupMeta)):\n                setattr(cls, name, attribute)\n\n\nclass SettingsObjectExtension(object):\n    \"\"\"\n    Base class for extensions of SettingsObjects.\n    \"\"\"\n    def __new__(self, *args, **kwargs):\n        raise TypeError(\"SettingsObjectExtension subclasses cannot be instantiated\")\n\n\n"
  },
  {
    "path": "sipsimple/configuration/backend/__init__.py",
    "content": "\n\"\"\"Base definitions for concrete implementations of configuration backends\"\"\"\n\n__all__ = ['ConfigurationBackendError', 'IConfigurationBackend']\n\n\nfrom zope.interface import Interface\n\n\nclass ConfigurationBackendError(Exception):\n    \"\"\"Base error for use by backends implementing IConfigurationBackend.\"\"\"\n\n\nclass IConfigurationBackend(Interface):\n    \"\"\"\n    Interface describing a backend used for storing and retrieving configuration\n    data.\n\n    The data kept by the backend is a dictionary whose keys are unicode strings\n    and values are one of four types: (a) a dictionary conforming to this\n    definition; (b) a unicode string; (c) a list of unicode strings; (d) the\n    value None.\n    \"\"\"\n    def load():\n        \"\"\"\n        Load the configuration data using whatever means employed by the backend\n        implementation and return a dictionary conforming to the definition in\n        this interface.\n        \"\"\"\n\n    def save(data):\n        \"\"\"\n        Given a dictionary conforming to the definition in this interface, save\n        the data using whatever means employed by the backend implementation.\n        \"\"\"\n\n\n"
  },
  {
    "path": "sipsimple/configuration/backend/file.py",
    "content": "\n\"\"\"Configuration backend for storing settings in a simple plain text format\"\"\"\n\n__all__ = [\"FileParserError\", \"FileBuilderError\", \"FileBackend\"]\n\nimport errno\nimport os\nimport re\nimport platform\nimport random\nfrom collections import deque\n\nfrom application.system import makedirs, openfile, unlink\nfrom zope.interface import implements\n\nfrom sipsimple.configuration.backend import IConfigurationBackend, ConfigurationBackendError\n\n\nclass FileParserError(ConfigurationBackendError):\n    \"\"\"Error raised when the configuration file cannot be parsed.\"\"\"\n\nclass FileBuilderError(ConfigurationBackendError):\n    \"\"\"Error raised when the configuration data cannot be saved.\"\"\"\n\n\nclass GroupState(object):\n    \"\"\"\n    Internal class used for keeping track of the containing groups while\n    parsing.\n    \"\"\"\n    def __init__(self, indentation):\n        self.indentation = indentation\n        self.data = {}\n\n\nclass Line(object):\n    \"\"\"Internal representation of lines in a configuration file\"\"\"\n    def __init__(self, indentation, name, separator, value):\n        self.indentation = indentation\n        self.name = name\n        self.separator = separator\n        self.value = value\n\n    def __repr__(self):\n        return \"%s(%r, %r, %r, %r)\" % (self.__class__.__name__, self.indentation, self.name, self.separator, self.value)\n\n\nclass FileBackend(object):\n    \"\"\"\n    Implementation of a configuration backend that stores data in a simple\n    plain text format.\n    \"\"\"\n\n    implements(IConfigurationBackend)\n\n    escape_characters_re = re.compile(ur\"\"\"[,\"'=: #\\\\\\t\\x0b\\x0c\\n\\r]\"\"\")\n\n    def __init__(self, filename, encoding='utf-8'):\n        \"\"\"\n        Initialize the configuration backend with the specified file.\n\n        The file is not read at this time, but rather each time the load method\n        is called.\n        \"\"\"\n        self.filename = filename\n        self.encoding = encoding\n\n    def load(self):\n        \"\"\"\n        Read the file configured with this backend and parse it, returning a\n        dictionary conforming to the IConfigurationBackend specification.\n        \"\"\"\n\n        try:\n            file = open(self.filename)\n        except IOError, e:\n            if e.errno == errno.ENOENT:\n                return {}\n            else:\n                raise ConfigurationBackendError(\"failed to read configuration file: %s\" % str(e))\n\n        state_stack = deque()\n        state_stack.appendleft(GroupState(-1))\n        for lineno, line in enumerate(file, 1):\n            line = self._parse_line(line, lineno)\n            if not line.name:\n                continue\n            # find the container for this declaration\n            while state_stack[0].indentation >= line.indentation:\n                state_stack.popleft()\n            if line.separator == u':':\n                new_group_state = GroupState(line.indentation)\n                state_stack[0].data[line.name] = new_group_state.data\n                state_stack.appendleft(new_group_state)\n            elif line.separator == u'=':\n                state_stack[0].data[line.name] = line.value\n\n        return state_stack[-1].data\n\n    def save(self, data):\n        \"\"\"\n        Given a dictionary conforming to the IConfigurationBackend\n        specification, write the data to the file configured with this backend\n        in a format suitable to be read back using load().\n        \"\"\"\n        lines = self._build_group(data, 0)\n        config_directory = os.path.dirname(self.filename)\n        tmp_filename = '%s.%d.%08X' % (self.filename, os.getpid(), random.getrandbits(32))\n        try:\n            if config_directory:\n                makedirs(config_directory)\n            file = openfile(tmp_filename, 'wb', permissions=0600)\n            file.write((os.linesep.join(lines)+os.linesep).encode(self.encoding))\n            file.close()\n            if platform.system() == 'Windows':\n                # os.rename does not work on Windows if the destination file already exists.\n                # It seems there is no atomic way to do this on Windows.\n                unlink(self.filename)\n            os.rename(tmp_filename, self.filename)\n        except (IOError, OSError), e:\n            raise ConfigurationBackendError(\"failed to write configuration file: %s\" % str(e))\n\n    def _parse_line(self, line, lineno):\n        def advance_to_next_token(line):\n            counter = 0\n            while line and line[0].isspace():\n                line.popleft()\n                counter += 1\n            if line and line[0] == u'#':\n                line.clear()\n            return counter\n        def token_iterator(line, delimiter=''):\n            quote_char = None\n            while line:\n                if quote_char is None and line[0] in delimiter:\n                    break\n                char = line.popleft()\n                if char in u\"'\\\"\":\n                    if quote_char is None:\n                        quote_char = char\n                        continue\n                    elif quote_char == char:\n                        quote_char = None\n                        continue\n                    else:\n                        yield char\n                elif char == u'\\\\':\n                    if not line:\n                        raise FileParserError(\"unexpected `\\\\' at end of line %d\" % lineno)\n                    char = line.popleft()\n                    if char == 'n':\n                        yield u'\\n'\n                    elif char == 'r':\n                        yield u'\\r'\n                    else:\n                        yield char\n                elif quote_char is None and char == u'#':\n                    line.clear()\n                    break\n                elif quote_char is None and char.isspace():\n                    break\n                else:\n                    yield char\n            if quote_char is not None:\n                raise FileParserError(\"missing ending quote at line %d\" % lineno)\n\n        line = deque(line.rstrip().decode(self.encoding))\n        indentation = advance_to_next_token(line)\n        if not line:\n            return Line(indentation, None, None, None)\n        name = u''.join(token_iterator(line, delimiter=u':='))\n        advance_to_next_token(line)\n        if not line or line[0] not in u':=':\n            raise FileParserError(\"expected one of `:' or `=' at line %d\" % lineno)\n        if not name:\n            raise FileParserError(\"missing setting/section name at line %d\" % lineno)\n        separator = line.popleft()\n        advance_to_next_token(line)\n        if not line:\n            return Line(indentation, name, separator, None)\n        elif separator == u':':\n            raise FileParserError(\"unexpected characters after `:' at line %d\" % lineno)\n        value = None\n        value_list = None\n        while line:\n            value = u''.join(token_iterator(line, delimiter=u','))\n            advance_to_next_token(line)\n            if line:\n                if line[0] == u',':\n                    line.popleft()\n                    advance_to_next_token(line)\n                    if value_list is None:\n                        value_list = []\n                else:\n                    raise FileParserError(\"unexpected characters after value at line %d\" % lineno)\n            if value_list is not None:\n                value_list.append(value)\n        value = value_list if value_list is not None else value\n        return Line(indentation, name, separator, value)\n\n    def _build_group(self, group, indentation):\n        setting_lines = []\n        group_lines = []\n        indent_spaces = u' '*4*indentation\n        for name, data in sorted(group.iteritems()):\n            if data is None:\n                setting_lines.append(u'%s%s =' % (indent_spaces, self._escape(name)))\n            elif type(data) is dict:\n                group_lines.append(u'%s%s:' % (indent_spaces, self._escape(name)))\n                group_lines.extend(self._build_group(data, indentation+1))\n                group_lines.append(u'')\n            elif type(data) is list:\n                list_value = u', '.join(self._escape(item) for item in data)\n                if len(data) == 1:\n                    list_value += u','\n                setting_lines.append(u'%s%s = %s' % (indent_spaces, self._escape(name), list_value))\n            elif type(data) is unicode:\n                setting_lines.append(u'%s%s = %s' % (indent_spaces, self._escape(name), self._escape(data)))\n            else:\n                raise FileBuilderError(\"expected unicode, dict or list object, got %s\" % type(data).__name__)\n        return setting_lines + group_lines\n\n    def _escape(self, value):\n        if value == u'':\n            return u'\"\"'\n        elif self.escape_characters_re.search(value):\n            return u'\"%s\"' % value.replace(u'\\\\', u'\\\\\\\\').replace(u'\"', u'\\\\\"').replace(u'\\n', u'\\\\n').replace(u'\\r', u'\\\\r')\n        else:\n            return value\n\n\n"
  },
  {
    "path": "sipsimple/configuration/backend/memory.py",
    "content": "\n\"\"\"Configuration backend for storing settings in memory\"\"\"\n\n__all__ = [\"MemoryBackend\"]\n\nfrom zope.interface import implements\nfrom sipsimple.configuration.backend import IConfigurationBackend\n\n\nclass MemoryBackend(object):\n    \"\"\"Implementation of a configuration backend that stores data in memory.\"\"\"\n\n    implements(IConfigurationBackend)\n\n    def __init__(self):\n        self.data = {}\n\n    def load(self):\n        return self.data\n\n    def save(self, data):\n        self.data = data\n\n\n"
  },
  {
    "path": "sipsimple/configuration/datatypes.py",
    "content": "\n\"\"\"Definitions of datatypes for use in configuration settings\"\"\"\n\n__all__ = [\n           # Base datatypes\n           'List',\n           # Generic datatypes\n           'ContentType', 'ContentTypeList', 'CountryCode', 'NonNegativeInteger', 'PositiveInteger', 'SIPAddress',\n           # Custom datatypes\n           'PJSIPLogLevel',\n           # Audio datatypes\n           'AudioCodecList', 'SampleRate',\n           # Video datatypes\n           'H264Profile', 'VideoResolution', 'VideoCodecList',\n           # Address and transport datatypes\n           'Port', 'PortRange', 'Hostname', 'DomainList', 'EndpointAddress', 'EndpointIPAddress', 'MSRPRelayAddress',\n           'SIPProxyAddress', 'STUNServerAddress', 'STUNServerAddressList', 'XCAPRoot',\n           'MSRPConnectionModel', 'MSRPTransport', 'SIPTransport', 'SIPTransportList',\n           # SRTP encryption\n           'SRTPKeyNegotiation',\n           # Path datatypes\n           'Path']\n\nimport locale\nimport os\nimport re\nimport urlparse\n\nfrom operator import itemgetter\n\n\n# Base datatypes\n\nclass List(object):\n    type = unicode\n\n    def __init__(self, values=()):\n        self.values = [item if isinstance(item, self.type) else self.type(item) for item in values]\n\n    def __getstate__(self):\n        state = []\n        for item in self:\n            if item is None:\n                pass\n            elif issubclass(self.type, bool):\n                item = u'true' if item else u'false'\n            elif issubclass(self.type, (int, long, basestring)):\n                item = unicode(item)\n            elif hasattr(item, '__getstate__'):\n                item = item.__getstate__()\n                if type(item) is not unicode:\n                    raise TypeError(\"Expected unicode type for list member, got %s\" % item.__class__.__name__)\n            else:\n                item = unicode(item)\n            state.append(item)\n        return state\n\n    def __setstate__(self, state):\n        if not isinstance(state, list):\n            state = [state]\n        values = []\n        for item in state:\n            if item is None:\n                pass\n            elif issubclass(self.type, bool):\n                if item.lower() in ('true', 'yes', 'on', '1'):\n                    item = True\n                elif item.lower() in ('false', 'no', 'off', '0'):\n                    item = False\n                else:\n                    raise ValueError(\"invalid boolean value: %s\" % (item,))\n            elif issubclass(self.type, (int, long, basestring)):\n                item = self.type(item)\n            elif hasattr(self.type, '__setstate__'):\n                object = self.type.__new__(self.type)\n                object.__setstate__(item)\n                item = object\n            else:\n                item = self.type(item)\n            values.append(item)\n        self.values = values\n\n    def __add__(self, other):\n        if isinstance(other, List):\n            return self.__class__(self.values + other.values)\n        else:\n            return self.__class__(self.values + other)\n\n    def __radd__(self, other):\n        if isinstance(other, List):\n            return self.__class__(other.values + self.values)\n        else:\n            return self.__class__(other + self.values)\n\n    def __mul__(self, other):\n        return self.__class__(self.values * other)\n\n    def __rmul__(self, other):\n        return self.__class__(other * self.values)\n\n    def __eq__(self, other):\n        if isinstance(other, List):\n            return self.values == other.values\n        else:\n            return self.values == other\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n    __hash__ = None\n\n    def __iter__(self):\n        return iter(self.values)\n\n    def __contains__(self, value):\n        return value in self.values\n\n    def __getitem__(self, key):\n        return self.values[key]\n\n    def __len__(self):\n        return len(self.values)\n\n    def __repr__(self):\n        return '%s(%r)' % (self.__class__.__name__, self.values)\n\n    def __str__(self):\n        return ', '.join(str(item) for item in self)\n\n    def __unicode__(self):\n        return u', '.join(unicode(item) for item in self)\n\n\n# Generic datatypes\n\nclass ContentType(str):\n    def __new__(cls, value):\n        value = str(value)\n        if value == '*':\n            return value\n        try:\n            type, subtype = value.split('/')\n        except ValueError:\n            raise ValueError(\"illegal content-type: %s\" % value)\n        else:\n            if type == '*':\n                raise ValueError(\"illegal content-type: %s\" % value)\n        return value\n\n\nclass ContentTypeList(List):\n    type = ContentType\n\n\nclass CountryCode(str):\n    code_pattern = re.compile(r'[1-9][0-9]*')\n\n    def __new__(cls, value):\n        value = str(value)\n        if cls.code_pattern.match(value) is None:\n            raise ValueError(\"illegal country code: %s\" % value)\n        return value\n\n\nclass NonNegativeInteger(int):\n    def __new__(cls, value):\n        value = int(value)\n        if value < 0:\n            raise ValueError(\"non-negative int expected, found %d\" % value)\n        return value\n\n\nclass PositiveInteger(int):\n    def __new__(cls, value):\n        value = int(value)\n        if value <= 0:\n            raise ValueError(\"positive int expected, found %d\" % value)\n        return value\n\n\nclass SIPAddress(str):\n    def __new__(cls, address):\n        address = str(address)\n        address = address.replace('@', '%40', address.count('@')-1)\n        try:\n            username, domain = address.split('@')\n            Hostname(domain)\n        except ValueError:\n            raise ValueError(\"illegal SIP address: %s, must be in user@domain format\" % address)\n        return super(SIPAddress, cls).__new__(cls, address)\n\n    username = property(lambda self: self.split('@')[0])\n    domain = property(lambda self: self.split('@')[1])\n\n\n# Custom datatypes\n\nclass PJSIPLogLevel(int):\n    def __new__(cls, value):\n        value = int(value)\n        if not (0 <= value <= 5):\n            raise ValueError(\"expected an integer number between 0 and 5, found %d\" % value)\n        return value\n\n\nclass CodecList(List):\n    type = str\n    available_values = None    # to be defined in a subclass\n\n    @property\n    def values(self):\n        return self.__dict__['values']\n\n    @values.setter\n    def values(self, values):\n        if not set(values).issubset(self.available_values):\n            raise ValueError(\"illegal codec values: %s\" % ', '.join(values))\n        self.__dict__['values'] = values\n\n\n# Audio datatypes\n\nclass AudioCodecList(CodecList):\n    available_values = {'opus', 'speex', 'G722', 'GSM', 'iLBC', 'PCMU', 'PCMA'}\n\n\nclass SampleRate(int):\n    valid_values = (16000, 32000, 44100, 48000)\n\n    def __new__(cls, value):\n        value = int(value)\n        if value not in cls.valid_values:\n            raise ValueError(\"illegal sample rate: %d\" % value)\n        return value\n\n\n# Video datatypes\n\nclass H264Profile(str):\n    valid_values = ('baseline', 'main', 'high')\n\n    def __new__(cls, value):\n        if value.lower() not in cls.valid_values:\n            raise ValueError('invalid value, must be one of: {}'.format(', '.join(cls.valid_values)))\n        return super(H264Profile, cls).__new__(cls, value.lower())\n\n\nclass VideoResolution(tuple):\n    width = property(itemgetter(0))\n    height = property(itemgetter(1))\n\n    def __new__(cls, value):\n        if isinstance(value, tuple):\n            width, height = value\n        elif isinstance(value, basestring):\n            width, height = value.split('x')\n        else:\n            raise ValueError('invalid value: %r' % value)\n        return super(VideoResolution, cls).__new__(cls, (int(width), int(height)))\n\n    def __repr__(self):\n        return '%s(%d, %d)' % (self.__class__.__name__, self.width, self.height)\n\n    def __str__(self):\n        return '%dx%d' % (self.width, self.height)\n\n    def __unicode__(self):\n        return u'%dx%d' % (self.width, self.height)\n\n\nclass VideoCodecList(CodecList):\n    available_values = {'H264', 'VP8'}\n\n\n# Address and transport datatypes\n\nclass Port(int):\n    def __new__(cls, value):\n        value = int(value)\n        if not (0 <= value <= 65535):\n            raise ValueError(\"illegal port value: %s\" % value)\n        return value\n\n\nclass PortRange(object):\n    def __init__(self, start, end):\n        self.start = Port(start)\n        self.end = Port(end)\n        if self.start == 0:\n            raise ValueError(\"illegal port value: 0\")\n        if self.end == 0:\n            raise ValueError(\"illegal port value: 0\")\n        if self.start > self.end:\n            raise ValueError(\"illegal port range: start port (%d) cannot be larger than end port (%d)\" % (self.start, self.end))\n\n    def __getstate__(self):\n        return unicode(self)\n\n    def __setstate__(self, state):\n        self.__init__(*state.split('-'))\n\n    def __eq__(self, other):\n        if isinstance(other, PortRange):\n            return self.start == other.start and self.end == other.end\n        else:\n            return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    __hash__ = None\n\n    def __repr__(self):\n        return '%s(start=%r, end=%r)' % (self.__class__.__name__, self.start, self.end)\n\n    def __str__(self):\n        return '%d-%d' % (self.start, self.end)\n\n    def __unicode__(self):\n        return u'%d-%d' % (self.start, self.end)\n\n\nclass Hostname(str):\n    _host_re = re.compile(r\"^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})|([a-zA-Z0-9\\-_]+(\\.[a-zA-Z0-9\\-_]+)*)$\")\n\n    def __new__(cls, value):\n        value = str(value)\n        if not cls._host_re.match(value):\n            raise ValueError(\"illegal hostname or ip address: %s\" % value)\n        return value\n\n\nclass IPAddress(str):\n    _ip_re = re.compile(r\"^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$\")\n\n    def __new__(cls, value):\n        value = str(value)\n        if not cls._ip_re.match(value):\n            raise ValueError(\"illegal IP address: %s\" % value)\n        return value\n\n\nclass DomainList(List):\n    type = str\n    _domain_re = re.compile(r\"^[a-zA-Z0-9\\-_]+(\\.[a-zA-Z0-9\\-_]+)*$\")\n\n    @property\n    def values(self):\n        return self.__dict__['values']\n\n    @values.setter\n    def values(self, values):\n        for value in values:\n            if self._domain_re.match(value) is None:\n                raise ValueError(\"illegal domain: %s\" % value)\n        self.__dict__['values'] = values\n\n\nclass EndpointAddress(object):\n    _description_re = re.compile(r\"^(?P<host>(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})|([a-zA-Z0-9\\-_]+(\\.[a-zA-Z0-9\\-_]+)*))(:(?P<port>\\d+))?$\")\n\n    default_port = 0\n\n    def __init__(self, host, port=None):\n        self.host = Hostname(host)\n        self.port = Port(port if port is not None else self.default_port)\n        if self.port == 0:\n            raise ValueError(\"illegal port value: 0\")\n\n    def __getstate__(self):\n        return unicode(self)\n\n    def __setstate__(self, state):\n        match = self._description_re.match(state)\n        if match is None:\n            raise ValueError(\"illegal endpoint address: %s\" % state)\n        self.__init__(**match.groupdict())\n\n    def __eq__(self, other):\n        if isinstance(other, EndpointAddress):\n            return self.host == other.host and self.port == other.port\n        else:\n            return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    __hash__ = None\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.host, self.port)\n\n    def __str__(self):\n        return '%s:%d' % (self.host, self.port)\n\n    def __unicode__(self):\n        return u'%s:%d' % (self.host, self.port)\n\n    @classmethod\n    def from_description(cls, description):\n        if not description:\n            return None\n        match = cls._description_re.match(description)\n        if match is None:\n            raise ValueError(\"illegal endpoint address: %s\" % description)\n        return cls(**match.groupdict())\n\n\nclass EndpointIPAddress(EndpointAddress):\n    _description_re = re.compile(r\"^(?P<host>\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})(:(?P<port>\\d+))?$\")\n\n    def __init__(self, host, port=None):\n        self.host = IPAddress(host)\n        self.port = Port(port if port is not None else self.default_port)\n        if self.port == 0:\n            raise ValueError(\"illegal port value: 0\")\n\n    def __setstate__(self, state):\n        match = self._description_re.match(state)\n        if match is None:\n            raise ValueError(\"illegal value: %s, must be an IP address\" % state)\n        self.__init__(**match.groupdict())\n\n    @classmethod\n    def from_description(cls, description):\n        if not description:\n            return None\n        match = cls._description_re.match(description)\n        if match is None:\n            raise ValueError(\"illegal value: %s, must be an IP address\" % description)\n        return cls(**match.groupdict())\n\n\nclass MSRPRelayAddress(object):\n    _description_re = re.compile(r\"^(?P<host>(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})|([a-zA-Z0-9\\-_]+(\\.[a-zA-Z0-9\\-_]+)*))(:(?P<port>\\d+))?(;transport=(?P<transport>.+))?$\")\n\n    def __init__(self, host, port=2855, transport='tls'):\n        self.host = Hostname(host)\n        self.port = Port(port)\n        self.transport = MSRPTransport(transport)\n\n    def __getstate__(self):\n        return unicode(self)\n\n    def __setstate__(self, state):\n        match = self._description_re.match(state)\n        if match is None:\n            raise ValueError(\"illegal MSRP relay address: %s\" % state)\n        self.__init__(**dict((k, v) for k, v in match.groupdict().iteritems() if v is not None))\n\n    def __eq__(self, other):\n        if isinstance(other, MSRPRelayAddress):\n            return self.host == other.host and self.port == other.port and self.transport == other.transport\n        else:\n            return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    __hash__ = None\n\n    def __repr__(self):\n        return '%s(%r, port=%r, transport=%r)' % (self.__class__.__name__, self.host, self.port, self.transport)\n\n    def __str__(self):\n        return '%s:%d;transport=%s' % (self.host, self.port, self.transport)\n\n    def __unicode__(self):\n        return u'%s:%d;transport=%s' % (self.host, self.port, self.transport)\n\n    @classmethod\n    def from_description(cls, description):\n        if not description:\n            return None\n        match = cls._description_re.match(description)\n        if match is None:\n            raise ValueError(\"illegal MSRP relay address: %s\" % description)\n        return cls(**dict((k, v) for k, v in match.groupdict().iteritems() if v is not None))\n\n\nclass SIPProxyAddress(object):\n    _description_re = re.compile(r\"^(?P<host>(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})|([a-zA-Z0-9\\-_]+(\\.[a-zA-Z0-9\\-_]+)*))(:(?P<port>\\d+))?(;transport=(?P<transport>.+))?$\")\n\n    def __init__(self, host, port=5060, transport='udp'):\n        self.host = Hostname(host)\n        self.port = Port(port)\n        if self.port == 0:\n            raise ValueError(\"illegal port value: 0\")\n        self.transport = SIPTransport(transport)\n\n    def __getstate__(self):\n        return unicode(self)\n\n    def __setstate__(self, state):\n        match = self._description_re.match(state)\n        if match is None:\n            raise ValueError(\"illegal SIP proxy address: %s\" % state)\n        self.__init__(**dict((k, v) for k, v in match.groupdict().iteritems() if v is not None))\n\n    def __eq__(self, other):\n        if isinstance(other, SIPProxyAddress):\n            return self.host == other.host and self.port == other.port and self.transport == other.transport\n        else:\n            return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    __hash__ = None\n\n    def __repr__(self):\n        return '%s(%r, port=%r, transport=%r)' % (self.__class__.__name__, self.host, self.port, self.transport)\n\n    def __str__(self):\n        return '%s:%d;transport=%s' % (self.host, self.port, self.transport)\n\n    def __unicode__(self):\n        return u'%s:%d;transport=%s' % (self.host, self.port, self.transport)\n\n    @classmethod\n    def from_description(cls, description):\n        if not description:\n            return None\n        match = cls._description_re.match(description)\n        if match is None:\n            raise ValueError(\"illegal SIP proxy address: %s\" % description)\n        return cls(**dict((k, v) for k, v in match.groupdict().iteritems() if v is not None))\n\n\nclass STUNServerAddress(object):\n    _description_re = re.compile(r\"^(?P<host>(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})|([a-zA-Z0-9\\-_]+(\\.[a-zA-Z0-9\\-_]+)*))(:(?P<port>\\d+))?$\")\n\n    default_port = 3478\n\n    def __init__(self, host, port=default_port):\n        self.host = Hostname(host)\n        self.port = Port(port)\n\n    def __getstate__(self):\n        return unicode(self)\n\n    def __setstate__(self, state):\n        match = self._description_re.match(state)\n        if match is None:\n            raise ValueError(\"illegal STUN server address: %s\" % state)\n        self.__init__(**dict((k, v) for k, v in match.groupdict().iteritems() if v is not None))\n\n    def __eq__(self, other):\n        if isinstance(other, STUNServerAddress):\n            return self.host == other.host and self.port == other.port\n        else:\n            return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    __hash__ = None\n\n    def __repr__(self):\n        return '%s(%r, port=%r)' % (self.__class__.__name__, self.host, self.port)\n\n    def __str__(self):\n        return '%s:%d' % (self.host, self.port)\n\n    def __unicode__(self):\n        return u'%s:%d' % (self.host, self.port)\n\n    @classmethod\n    def from_description(cls, description):\n        if not description:\n            return None\n        match = cls._description_re.match(description)\n        if match is None:\n            raise ValueError(\"illegal STUN server address: %s\" % description)\n        return cls(**dict((k, v) for k, v in match.groupdict().iteritems() if v is not None))\n\n\nclass STUNServerAddressList(List):\n    type = STUNServerAddress\n\n\nclass XCAPRoot(str):\n    def __new__(cls, value):\n        value = str(value)\n        uri = urlparse.urlparse(value)\n        if uri.scheme not in (u'http', u'https'):\n            raise ValueError(\"illegal XCAP root scheme (http and https only): %s\" % uri.scheme)\n        if uri.params:\n            raise ValueError(\"XCAP root must not contain parameters: %s\" % (uri.params,))\n        if uri.query:\n            raise ValueError(\"XCAP root must not contain query component: %s\" % (uri.query,))\n        if uri.fragment:\n            raise ValueError(\"XCAP root must not contain fragment component: %s\" % (uri.fragment,))\n        # check port and hostname\n        Hostname(uri.hostname)\n        if uri.port is not None:\n            port = Port(uri.port)\n            if port == 0:\n                raise ValueError(\"illegal port value: 0\")\n        return value\n\n\nclass MSRPConnectionModel(str):\n    available_values = ('relay', 'acm')\n\n    def __new__(cls, value):\n        value = str(value)\n        if value not in cls.available_values:\n            raise ValueError(\"illegal value for MSRP NAT model: %s\" % value)\n        return value\n\n\nclass MSRPTransport(str):\n    available_values = ('tls', 'tcp')\n\n    def __new__(cls, value):\n        value = str(value)\n        if value not in cls.available_values:\n            raise ValueError(\"illegal value for MSRP transport: %s\" % value)\n        return value\n\n\nclass SIPTransport(str):\n    available_values = ('udp', 'tcp', 'tls')\n\n    def __new__(cls, value):\n        value = str(value)\n        if value not in cls.available_values:\n            raise ValueError(\"illegal value for SIP transport: %s\" % value)\n        return value\n\n\nclass SIPTransportList(List):\n    type = SIPTransport\n    available_values = SIPTransport.available_values\n\n\nclass SRTPKeyNegotiation(str):\n    available_values = ('opportunistic', 'sdes_optional', 'sdes_mandatory', 'zrtp')\n\n    def __new__(cls, value):\n        value = str(value)\n        if value not in cls.available_values:\n            raise ValueError(\"illegal value for SRTP key negotiation: %s\" % value)\n        return value\n\n\n# Path datatypes\n\nclass Path(unicode):\n    def __new__(cls, path):\n        return super(Path, cls).__new__(cls, os.path.normpath(path))\n\n    @property\n    def normalized(self):\n        if not self.startswith('~'):\n            return self\n        encoding = locale.getpreferredencoding() or 'ascii'\n        return os.path.expanduser(self.encode(encoding)).decode(encoding)\n"
  },
  {
    "path": "sipsimple/configuration/settings.py",
    "content": "\n\"\"\"\nSIP SIMPLE settings.\n\nDefinition of general (non-account related) settings.\n\"\"\"\n\nfrom sipsimple import __version__\nfrom sipsimple.configuration import CorrelatedSetting, RuntimeSetting, Setting, SettingsGroup, SettingsObject\nfrom sipsimple.configuration.datatypes import NonNegativeInteger, PJSIPLogLevel\nfrom sipsimple.configuration.datatypes import AudioCodecList, SampleRate, VideoCodecList\nfrom sipsimple.configuration.datatypes import Port, PortRange, SIPTransportList\nfrom sipsimple.configuration.datatypes import Path\nfrom sipsimple.configuration.datatypes import H264Profile, VideoResolution\n\n\n__all__ = ['SIPSimpleSettings']\n\n\nclass EchoCancellerSettings(SettingsGroup):\n    enabled = Setting(type=bool, default=True)\n    tail_length = Setting(type=NonNegativeInteger, default=2)\n\n\nclass AudioSettings(SettingsGroup):\n    alert_device = Setting(type=unicode, default=u'system_default', nillable=True)\n    input_device = Setting(type=unicode, default=u'system_default', nillable=True)\n    output_device = Setting(type=unicode, default=u'system_default', nillable=True)\n    sample_rate = Setting(type=SampleRate, default=44100)\n    muted = RuntimeSetting(type=bool, default=False)\n    silent = Setting(type=bool, default=False)\n    echo_canceller = EchoCancellerSettings\n\n\nclass H264Settings(SettingsGroup):\n    profile = Setting(type=H264Profile, default='baseline')\n    level = Setting(type=str, default='3.1')\n\n\nclass VideoSettings(SettingsGroup):\n    device = Setting(type=unicode, default=u'system_default', nillable=True)\n    resolution = Setting(type=VideoResolution, default=VideoResolution('1280x720'))\n    framerate = Setting(type=int, default=25)\n    max_bitrate = Setting(type=float, default=None, nillable=True)\n    muted = RuntimeSetting(type=bool, default=False)\n    h264 = H264Settings\n\n\nclass ChatSettings(SettingsGroup):\n    pass\n\n\nclass ScreenSharingSettings(SettingsGroup):\n    pass\n\n\nclass FileTransferSettings(SettingsGroup):\n    directory = Setting(type=Path, default=Path('~/Downloads'))\n\n\nclass LogsSettings(SettingsGroup):\n    trace_msrp = Setting(type=bool, default=False)\n    trace_sip = Setting(type=bool, default=False)\n    trace_pjsip = Setting(type=bool, default=False)\n    pjsip_level = Setting(type=PJSIPLogLevel, default=5)\n\n\nclass RTPSettings(SettingsGroup):\n    port_range = Setting(type=PortRange, default=PortRange(50000, 50500))\n    timeout = Setting(type=NonNegativeInteger, default=30)\n    audio_codec_list = Setting(type=AudioCodecList, default=AudioCodecList(('opus', 'G722', 'PCMU', 'PCMA')))\n    video_codec_list = Setting(type=VideoCodecList, default=VideoCodecList(('H264', 'VP8')))\n\n\ndef sip_port_validator(port, sibling_port):\n    if port == sibling_port != 0:\n        raise ValueError(\"the TCP and TLS ports must be different\")\n\nclass SIPSettings(SettingsGroup):\n    invite_timeout = Setting(type=NonNegativeInteger, default=90, nillable=True)\n    udp_port = Setting(type=Port, default=0)\n    tcp_port = CorrelatedSetting(type=Port, sibling='tls_port', validator=sip_port_validator, default=0)\n    tls_port = CorrelatedSetting(type=Port, sibling='tcp_port', validator=sip_port_validator, default=0)\n    transport_list = Setting(type=SIPTransportList, default=SIPTransportList(('tls', 'tcp', 'udp')))\n\n\nclass TLSSettings(SettingsGroup):\n    ca_list = Setting(type=Path, default=None, nillable=True)\n\n\nclass SIPSimpleSettings(SettingsObject):\n    __id__ = 'SIPSimpleSettings'\n\n    default_account = Setting(type=str, default='bonjour@local', nillable=True)\n    user_agent = Setting(type=str, default='sipsimple %s' % __version__)\n    instance_id = Setting(type=str, default='')\n\n    audio = AudioSettings\n    video = VideoSettings\n    chat = ChatSettings\n    screen_sharing = ScreenSharingSettings\n    file_transfer = FileTransferSettings\n    logs = LogsSettings\n    rtp = RTPSettings\n    sip = SIPSettings\n    tls = TLSSettings\n\n\n"
  },
  {
    "path": "sipsimple/core/__init__.py",
    "content": "\nfrom sipsimple.core._core import *\nfrom sipsimple.core._engine import *\nfrom sipsimple.core._helpers import *\nfrom sipsimple.core._primitives import *\n\nrequired_revision = 181\nif CORE_REVISION != required_revision:\n    raise ImportError(\"Wrong SIP core revision %d (expected %d)\" % (CORE_REVISION, required_revision))\ndel required_revision\n\n\n"
  },
  {
    "path": "sipsimple/core/_core.error.pxi",
    "content": "\n\nclass SIPCoreError(Exception):\n    pass\n\n\nclass PJSIPError(SIPCoreError):\n\n    def __init__(self, message, status):\n        self.status = status\n        SIPCoreError.__init__(self, \"%s: %s\" % (message, _pj_status_to_str(status)))\n\n    @property\n    def errno(self):\n        # PJ_STATUS - PJ_ERRNO_START + PJ_ERRNO_SPACE_SIZE*2\n        return 0 if self.status == 0 else self.status - 120000\n\n\nclass PJSIPTLSError(PJSIPError):\n    pass\n\n\nclass SIPCoreInvalidStateError(SIPCoreError):\n    pass\n\n"
  },
  {
    "path": "sipsimple/core/_core.event.pxi",
    "content": "\n# C types\n\ncdef struct _core_event:\n    _core_event *prev\n    _core_event *next\n    int is_log\n    int level\n    void *data\n    int len\n\ncdef struct _handler:\n    _handler *next\n    _handler *prev\n    int func(object obj) except -1\n    void *obj\n\ncdef struct _handler_queue:\n    _handler *head\n    _handler *tail\n\n# callback functions\n\ncdef void _cb_log(int level, char_ptr_const data, int len):\n    cdef _core_event *event\n    event = <_core_event *> malloc(sizeof(_core_event))\n    if event != NULL:\n        event.data = malloc(len)\n        if event.data == NULL:\n            free(event)\n            return\n        event.is_log = 1\n        event.level = level\n        memcpy(event.data, data, len)\n        event.len = len\n        if _event_queue_append(event) != 0:\n            free(event.data)\n            free(event)\n\n# functions\n\ncdef int _add_event(object event_name, dict params) except -1:\n    cdef tuple data\n    cdef _core_event *event\n    cdef int status\n    event = <_core_event *> malloc(sizeof(_core_event))\n    if event == NULL:\n        raise MemoryError()\n    data = (event_name, params)\n    event.is_log = 0\n    event.data = <void *> data\n    status = _event_queue_append(event)\n    if status != 0:\n        raise PJSIPError(\"Could not obtain lock\", status)\n    Py_INCREF(data)\n    return 0\n\ncdef int _event_queue_append(_core_event *event):\n    global _event_queue_head, _event_queue_tail, _event_queue_lock\n    cdef int locked = 0, status\n    event.next = NULL\n    if _event_queue_lock != NULL:\n        status = pj_mutex_lock(_event_queue_lock)\n        if status != 0:\n            return status\n        locked = 1\n    if _event_queue_head == NULL:\n        event.prev = NULL\n        _event_queue_head = event\n        _event_queue_tail = event\n    else:\n        _event_queue_tail.next = event\n        event.prev = _event_queue_tail\n        _event_queue_tail = event\n    if locked:\n        pj_mutex_unlock(_event_queue_lock)\n    return 0\n\ncdef list _get_clear_event_queue():\n    global _re_log, _event_queue_head, _event_queue_tail, _event_queue_lock\n    cdef object events = []\n    cdef _core_event *event\n    cdef _core_event *event_free\n    cdef object event_tup\n    cdef object event_params, log_msg, log_match\n    cdef int locked = 0\n    if _event_queue_lock != NULL:\n        status = pj_mutex_lock(_event_queue_lock)\n        if status != 0:\n            return status\n        locked = 1\n    event = _event_queue_head\n    _event_queue_head = _event_queue_tail = NULL\n    if locked:\n        pj_mutex_unlock(_event_queue_lock)\n    while event != NULL:\n        if event.is_log:\n            log_msg = PyString_FromStringAndSize(<char *> event.data, event.len)\n            event_params = dict(level=event.level, message=log_msg)\n            events.append((\"SIPEngineLog\", event_params))\n        else:\n            event_tup = <object> event.data\n            Py_DECREF(event_tup)\n            events.append(event_tup)\n        event_free = event\n        event = event.next\n        free(event_free)\n    return events\n\ncdef int _add_handler(int func(object obj) except -1, object obj, _handler_queue *queue) except -1:\n    cdef _handler *handler\n    handler = <_handler *> malloc(sizeof(_handler))\n    if handler == NULL:\n        raise MemoryError()\n    handler.func = func\n    handler.obj = <void *> obj\n    handler.next = NULL\n    if queue.head == NULL:\n        handler.prev = NULL\n        queue.head = handler\n        queue.tail = handler\n    else:\n        queue.tail.next = handler\n        handler.prev = queue.tail\n        queue.tail = handler\n    return 0\n\ncdef int _remove_handler(object obj, _handler_queue *queue) except -1:\n    cdef _handler *handler\n    cdef _handler *handler_free\n    handler = queue.head\n    while handler != NULL:\n        if handler.obj == <void *> obj:\n            if handler.prev != NULL:\n                handler.prev.next = handler.next\n            if handler.next != NULL:\n                handler.next.prev = handler.prev\n            if queue.head == handler:\n                queue.head = handler.next\n            if queue.tail == handler:\n                queue.tail = handler.prev\n            handler_free = handler\n            handler = handler.next\n            free(handler_free)\n        else:\n            handler = handler.next\n    return 0\n\ncdef int _process_handler_queue(PJSIPUA ua, _handler_queue *queue) except -1:\n    cdef _handler *handler\n    cdef _handler *handler_free\n    handler = queue.head\n    queue.head = queue.tail = NULL\n    while handler != NULL:\n        try:\n            handler.func(<object> handler.obj)\n        except:\n            ua._handle_exception(1)\n        handler_free = handler\n        handler = handler.next\n        free(handler_free)\n    return 0\n\n# globals\n\ncdef pj_mutex_t *_event_queue_lock = NULL\ncdef _core_event *_event_queue_head = NULL\ncdef _core_event *_event_queue_tail = NULL\ncdef _handler_queue _post_poll_handler_queue\n_post_poll_handler_queue.head = NULL\n_post_poll_handler_queue.tail = NULL\ncdef _handler_queue _dealloc_handler_queue\n_dealloc_handler_queue.head = NULL\n_dealloc_handler_queue.tail = NULL\n"
  },
  {
    "path": "sipsimple/core/_core.headers.pxi",
    "content": "\n# Classes\n#\n\ncdef object BaseHeader_richcmp(object self, object other, int op) with gil:\n    if op not in (2, 3):\n        return NotImplemented\n    if not isinstance(other, BaseHeader):\n        return NotImplemented\n    if op == 2:\n        return self.name == other.name and self.body == other.body\n    else:\n        return self.name != other.name or self.body != other.body\n\ncdef class BaseHeader:\n    normal_type = Header\n    frozen_type = FrozenHeader\n\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"BaseHeader cannot be instantiated directly\")\n\n    def __repr__(self):\n        return \"%s(%r, %r)\" % (self.__class__.__name__, self.name, self.body)\n\n    def __str__(self):\n        return \"%s: %s\" % (self.name, self.body)\n\n    def __richcmp__(self, other, op):\n        return BaseHeader_richcmp(self, other, op)\n\ndef Header_new(cls, BaseHeader header):\n    return cls(header.name, header.body)\n\ncdef class Header(BaseHeader):\n    def __init__(self, str name not None, str body not None):\n        self.name = name\n        self.body = body\n\n    property name:\n\n        def __get__(self):\n            return self._name\n\n        def __set__(self, str name not None):\n            self._name = name\n\n    property body:\n\n        def __get__(self):\n            return self._body\n\n        def __set__(self, str body not None):\n            self._body = body\n\n    new = classmethod(Header_new)\n\ndel Header_new\n\ndef FrozenHeader_new(cls, BaseHeader header):\n    if isinstance(header, cls):\n        return header\n    return cls(header.name, header.body)\n\ncdef class FrozenHeader(BaseHeader):\n    def __init__(self, str name not None, str body not None):\n        self.name = name\n        self.body = body\n\n    def __hash__(self):\n        return hash((self.name, self.body))\n\n    def __richcmp__(self, other, op):\n        return BaseHeader_richcmp(self, other, op)\n\n    new = classmethod(FrozenHeader_new)\n\ndel FrozenHeader_new\n\n\nclass ContentType(str):\n    def __init__(self, value):\n        if '' in value.partition('/'):\n            raise ValueError('invalid content type')\n\n    @property\n    def type(self):\n        return self.partition('/')[0]\n\n    @property\n    def subtype(self):\n        return self.partition('/')[2]\n\n\ncdef object BaseContentTypeHeader_richcmp(object self, object other, object op) with gil:\n    if op not in (2, 3):\n        return NotImplemented\n    if not isinstance(other, BaseContentTypeHeader):\n        return NotImplemented\n    if op == 2:\n        return self.content_type == other.content_type and self.parameters == other.parameters\n    else:\n        return self.content_type != other.content_type and self.parameters != other.parameters\n\ncdef class BaseContentTypeHeader:\n    normal_type = ContentTypeHeader\n    frozen_type = FrozenContentTypeHeader\n\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"%s cannot be instantiated directly\" % self.__class__.__name__)\n\n    def __repr__(self):\n        return \"%s(%r, %r)\" % (self.__class__.__name__, self.content_type, self.parameters)\n\n    def __str__(self):\n        return \"%s: %s\" % (self.name, self.body)\n\n    def __unicode__(self):\n        return unicode(self.__str__(), encoding='utf-8')\n\n    def __richcmp__(self, other, op):\n        return BaseContentTypeHeader_richcmp(self, other, op)\n\n    property name:\n\n        def __get__(self):\n            return \"Content-Type\"\n\n    property body:\n\n        def __get__(self):\n            if self.parameters:\n                parameters = \";\" + \";\".join([\"%s%s\" % (name, \"\" if value is None else \"=%s\" % value)\n                                             for name, value in self.parameters.iteritems()])\n            else:\n                parameters = \"\"\n            return self.content_type + parameters\n\ndef ContentTypeHeader_new(cls, BaseContentTypeHeader header):\n    return cls(header.content_type, dict(header.parameters))\n\ncdef class ContentTypeHeader(BaseContentTypeHeader):\n    def __init__(self, str content_type, dict parameters=None):\n        self.content_type = content_type\n        self.parameters = parameters if parameters is not None else {}\n\n    property content_type:\n\n        def __get__(self):\n            try:\n                return ContentType(self._content_type)\n            except ValueError:\n                return None\n\n        def __set__(self, str content_type):\n            self._content_type = content_type\n\n    property parameters:\n\n        def __get__(self):\n            return self._parameters\n\n        def __set__(self, dict parameters not None):\n            self._parameters = parameters\n\n    new = classmethod(ContentTypeHeader_new)\n\ndel ContentTypeHeader_new\n\ndef FrozenContentTypeHeader_new(cls, BaseContentTypeHeader header):\n    if isinstance(header, cls):\n        return header\n    return cls(header.content_type, frozendict(header.parameters))\n\ncdef class FrozenContentTypeHeader(BaseContentTypeHeader):\n    def __init__(self, str content_type, frozendict parameters not None=frozendict()):\n        if not self.initialized:\n            self._content_type = content_type\n            self.parameters = parameters\n            self.initialized = 1\n\n    property content_type:\n\n        def __get__(self):\n            try:\n                return ContentType(self._content_type)\n            except ValueError:\n                return None\n\n    def __hash__(self):\n        return hash((self.content_type, self.parameters))\n\n    def __richcmp__(self, other, op):\n        return BaseContentTypeHeader_richcmp(self, other, op)\n\n    new = classmethod(FrozenContentTypeHeader_new)\n\ndel FrozenContentTypeHeader_new\n\n\ncdef object BaseContactHeader_richcmp(object self, object other, object op) with gil:\n    if op not in (2, 3):\n        return NotImplemented\n    if not isinstance(other, BaseContactHeader):\n        return NotImplemented\n    if op == 2:\n        return self.name == other.name and self.uri == other.uri and self.display_name == other.display_name and self.parameters == other.parameters\n    else:\n        return self.name != other.name or self.uri != other.uri or self.display_name != other.display_name or self.parameters != other.parameters\n\ncdef class BaseContactHeader:\n    normal_type = ContactHeader\n    frozen_type = FrozenContactHeader\n\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"%s cannot be instantiated directly\" % self.__class__.__name__)\n\n    def __repr__(self):\n        return \"%s(%r, %r, %r)\" % (self.__class__.__name__, self.uri, self.display_name, self.parameters)\n\n    def __str__(self):\n        return \"%s: %s\" % (self.name, self.body)\n\n    def __unicode__(self):\n        return unicode(self.__str__(), encoding='utf-8')\n\n    def __richcmp__(self, other, op):\n        return BaseContactHeader_richcmp(self, other, op)\n\n    property name:\n\n        def __get__(self):\n            return \"Contact\"\n\n    property body:\n\n        def __get__(self):\n            if self.uri is None:\n                return \"*\"\n            if self.parameters:\n                parameters = \";\" + \";\".join([\"%s%s\" % (name, \"\" if value is None else \"=%s\" % value)\n                                             for name, value in self.parameters.iteritems()])\n            else:\n                parameters = \"\"\n            if self.display_name:\n                return '\"%s\" <%s>%s' % (self.display_name.encode('utf-8'), self.uri, parameters)\n            else:\n                return '<%s>%s' % (self.uri, parameters)\n\ndef ContactHeader_new(cls, BaseContactHeader header):\n    return cls(SIPURI.new(header.uri), header.display_name, dict(header.parameters))\n\ncdef class ContactHeader(BaseContactHeader):\n    def __init__(self, SIPURI uri, unicode display_name=None, dict parameters=None):\n        if uri is None and (display_name is not None or parameters not in (None, {})):\n            raise ValueError(\"uri cannot be None if display_name or parameters are specified\")\n        self.uri = uri\n        self.display_name = display_name\n        self.parameters = parameters if parameters is not None else {}\n\n    property uri:\n\n        def __get__(self):\n            return self._uri\n\n        def __set__(self, SIPURI uri):\n            if uri is None and (self.display_name is not None or self.parameters != {}):\n                raise ValueError(\"uri cannot be None if display_name or parameters are specified\")\n            self._uri = uri\n\n    property display_name:\n\n        def __get__(self):\n            return self._display_name\n\n        def __set__(self, unicode display_name):\n            if self.uri is None and display_name is not None:\n                raise ValueError(\"display_name cannot be specified if uri is None\")\n            self._display_name = display_name\n\n    property parameters:\n\n        def __get__(self):\n            return self._parameters\n\n        def __set__(self, dict parameters not None):\n            if self.uri is None and parameters != {}:\n                raise ValueError(\"parameters cannot be specified if uri is None\")\n            self._parameters = parameters\n\n    property q:\n\n        def __get__(self):\n            value = self.parameters.get(\"q\", None)\n            if value is not None:\n                value = float(value)\n            return value\n\n        def __set__(self, object value):\n            if value is None:\n                self.parameters.pop(\"q\", None)\n            else:\n                if self.uri is None:\n                    raise ValueError(\"parameters cannot be specified if uri is None\")\n                self.parameters[\"q\"] = str(float(value))\n\n    property expires:\n\n        def __get__(self):\n            value = self.parameters.get(\"expires\", None)\n            if value is not None:\n                value = int(value)\n            return value\n\n        def __set__(self, object value):\n            if value is None:\n                self.parameters.pop(\"expires\", None)\n            else:\n                if self.uri is None:\n                    raise ValueError(\"parameters cannot be specified if uri is None\")\n                self.parameters[\"expires\"] = str(int(value))\n\n    new = classmethod(ContactHeader_new)\n\ndel ContactHeader_new\n\ndef FrozenContactHeader_new(cls, BaseContactHeader header):\n    if isinstance(header, cls):\n        return header\n    return cls(FrozenSIPURI.new(header.uri), header.display_name, frozendict(header.parameters))\n\ncdef class FrozenContactHeader(BaseContactHeader):\n    def __init__(self, FrozenSIPURI uri, unicode display_name=None, frozendict parameters not None=frozendict()):\n        if not self.initialized:\n            if uri is None and (display_name is not None or parameters not in (None, {})):\n                raise ValueError(\"uri cannot be None if display_name or parameters are specified\")\n            self.uri = uri\n            self.display_name = display_name\n            self.parameters = parameters\n            self.initialized = 1\n\n    def __hash__(self):\n        return hash((self.uri, self.display_name, self.parameters))\n\n    def __richcmp__(self, other, op):\n        return BaseContactHeader_richcmp(self, other, op)\n\n    property q:\n\n        def __get__(self):\n            value = self.parameters.get(\"q\", None)\n            if value is not None:\n                value = float(value)\n            return value\n\n    property expires:\n\n        def __get__(self):\n            value = self.parameters.get(\"expires\", None)\n            if value is not None:\n                value = int(value)\n            return value\n\n    new = classmethod(FrozenContactHeader_new)\n\ndel FrozenContactHeader_new\n\n\ncdef object BaseIdentityHeader_richcmp(object self, object other, int op) with gil:\n    if op not in (2, 3):\n        return NotImplemented\n    if not isinstance(other, BaseIdentityHeader):\n        return NotImplemented\n    if op == 2:\n        return self.name == other.name and self.uri == other.uri and self.display_name == other.display_name and self.parameters == other.parameters\n    else:\n        return self.name != other.name or self.uri != other.uri or self.display_name != other.display_name or self.parameters != other.parameters\n\ncdef class BaseIdentityHeader:\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"%s cannot be instantiated directly\" % self.__class__.__name__)\n\n    def __repr__(self):\n        return \"%s(%r, %r, %r)\" % (self.__class__.__name__, self.uri, self.display_name, self.parameters)\n\n    def __str__(self):\n        return \"%s: %s\" % (self.name, self.body)\n\n    def __unicode__(self):\n        return unicode(self.__str__(), encoding='utf-8')\n\n    def __richcmp__(self, other, op):\n        return BaseIdentityHeader_richcmp(self, other, op)\n\n    property body:\n\n        def __get__(self):\n            if self.parameters:\n                parameters = \";\" + \";\".join([\"%s%s\" % (name, \"\" if value is None else \"=%s\" % value)\n                                             for name, value in self.parameters.iteritems()])\n            else:\n                parameters = \"\"\n            if self.display_name:\n                return '\"%s\" <%s>%s' % (self.display_name.encode('utf-8'), self.uri, parameters)\n            else:\n                return '<%s>%s' % (self.uri, parameters)\n\ndef IdentityHeader_new(cls, BaseIdentityHeader contact_header):\n    return cls(SIPURI.new(contact_header.uri), contact_header.display_name, dict(contact_header.parameters))\n\ncdef class IdentityHeader(BaseIdentityHeader):\n    property uri:\n\n        def __get__(self):\n            return self._uri\n\n        def __set__(self, SIPURI uri not None):\n            self._uri = uri\n\n    property parameters:\n\n        def __get__(self):\n            return self._parameters\n\n        def __set__(self, dict parameters not None):\n            self._parameters = parameters\n\n    new = classmethod(IdentityHeader_new)\n\ndel IdentityHeader_new\n\ndef FrozenIdentityHeader_new(cls, BaseIdentityHeader contact_header):\n    if isinstance(contact_header, cls):\n        return contact_header\n    return cls(FrozenSIPURI.new(contact_header.uri), contact_header.display_name, frozendict(contact_header.parameters))\n\ncdef class FrozenIdentityHeader(BaseIdentityHeader):\n    def __hash__(self):\n        return hash((self.uri, self.display_name, self.parameters))\n\n    def __richcmp__(self, other, op):\n        return BaseIdentityHeader_richcmp(self, other, op)\n\n    new = classmethod(FrozenIdentityHeader_new)\n\ndel FrozenIdentityHeader_new\n\n\ncdef class FromHeader(IdentityHeader):\n    normal_type = FromHeader\n    frozen_type = FrozenFromHeader\n\n    def __init__(self, SIPURI uri not None, unicode display_name=None, dict parameters=None):\n        self.uri = uri\n        self.display_name = display_name\n        self.parameters = parameters if parameters is not None else {}\n\n    property tag:\n\n        def __get__(self):\n            return self.parameters.get(\"tag\", None)\n\n        def __set__(self, str value):\n            if value is None:\n                self.parameters.pop(\"tag\", None)\n            else:\n                self.parameters[\"tag\"] = value\n\n    property name:\n\n        def __get__(self):\n            return \"From\"\n\ncdef class FrozenFromHeader(FrozenIdentityHeader):\n    normal_type = FromHeader\n    frozen_type = FrozenFromHeader\n\n    def __init__(self, FrozenSIPURI uri not None, unicode display_name=None, frozendict parameters not None=frozendict()):\n        if not self.initialized:\n            self.uri = uri\n            self.display_name = display_name\n            self.parameters = parameters\n            self.initialized = 1\n\n    property tag:\n\n        def __get__(self):\n            return self.parameters.get(\"tag\", None)\n\n    property name:\n\n        def __get__(self):\n            return \"From\"\n\n\ncdef class ToHeader(IdentityHeader):\n    normal_type = ToHeader\n    frozen_type = FrozenToHeader\n\n    def __init__(self, SIPURI uri not None, unicode display_name=None, dict parameters=None):\n        self.uri = uri\n        self.display_name = display_name\n        self.parameters = parameters if parameters is not None else {}\n\n    property tag:\n\n        def __get__(self):\n            return self.parameters.get(\"tag\", None)\n\n        def __set__(self, str value):\n            if value is None:\n                self.parameters.pop(\"tag\", None)\n            else:\n                self.parameters[\"tag\"] = value\n\n    property name:\n\n        def __get__(self):\n            return \"To\"\n\ncdef class FrozenToHeader(FrozenIdentityHeader):\n    normal_type = ToHeader\n    frozen_type = FrozenToHeader\n\n    def __init__(self, FrozenSIPURI uri not None, unicode display_name=None, frozendict parameters not None=frozendict()):\n        if not self.initialized:\n            self.uri = uri\n            self.display_name = display_name\n            self.parameters = parameters\n            self.initialized = 1\n\n    property tag:\n\n        def __get__(self):\n            return self.parameters.get(\"tag\", None)\n\n    property name:\n\n        def __get__(self):\n            return \"To\"\n\n\ncdef class RouteHeader(IdentityHeader):\n    normal_type = RouteHeader\n    frozen_type = FrozenRouteHeader\n\n    def __init__(self, SIPURI uri not None, unicode display_name=None, dict parameters=None):\n        self.uri = uri\n        self.display_name = display_name\n        self.parameters = parameters if parameters is not None else {}\n\n    property name:\n\n        def __get__(self):\n            return \"Route\"\n\ncdef class FrozenRouteHeader(FrozenIdentityHeader):\n    normal_type = RouteHeader\n    frozen_type = FrozenRouteHeader\n\n    def __init__(self, FrozenSIPURI uri not None, unicode display_name=None, frozendict parameters not None=frozendict()):\n        if not self.initialized:\n            self.uri = uri\n            self.display_name = display_name\n            self.parameters = parameters\n            self.initialized = 1\n\n    property name:\n\n        def __get__(self):\n            return \"Route\"\n\n\ncdef class RecordRouteHeader(IdentityHeader):\n    normal_type = RecordRouteHeader\n    frozen_type = FrozenRecordRouteHeader\n\n    def __init__(self, SIPURI uri not None, unicode display_name=None, dict parameters=None):\n        self.uri = uri\n        self.display_name = display_name\n        self.parameters = parameters if parameters is not None else {}\n\n    property name:\n\n        def __get__(self):\n            return \"Record-Route\"\n\ncdef class FrozenRecordRouteHeader(FrozenIdentityHeader):\n    normal_type = RecordRouteHeader\n    frozen_type = FrozenRecordRouteHeader\n\n    def __init__(self, FrozenSIPURI uri not None, unicode display_name=None, frozendict parameters not None=frozendict()):\n        if not self.initialized:\n            self.uri = uri\n            self.display_name = display_name\n            self.parameters = parameters\n            self.initialized = 1\n\n    property name:\n\n        def __get__(self):\n            return \"Record-Route\"\n\n\ncdef object BaseRetryAfterHeader_richcmp(object self, object other, int op) with gil:\n    if op not in (2, 3):\n        return NotImplemented\n    if not isinstance(other, BaseRetryAfterHeader):\n        return NotImplemented\n    if op == 2:\n        return self.seconds == other.seconds and self.comment == other.comment and self.parameters == other.parameters\n    else:\n        return self.seconds != other.seconds or self.comment != other.comment or self.parameters != other.parameters\n\ncdef class BaseRetryAfterHeader:\n    normal_type = RetryAfterHeader\n    frozen_type = FrozenRetryAfterHeader\n\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"BaseRetryAfterHeader cannot be instantiated directly\")\n\n    def __repr__(self):\n        return \"%s(%r, %r, %r)\" % (self.__class__.__name__, self.seconds, self.comment, self.parameters)\n\n    def __str__(self):\n        return \"%s: %s\" % (self.name, self.body)\n\n    def __richcmp__(self, other, op):\n        return BaseRetryAfterHeader_richcmp(self, other, op)\n\n    property name:\n\n        def __get__(self):\n            return \"Retry-After\"\n\n    property body:\n\n        def __get__(self):\n            string = str(self.seconds)\n            if self.comment is not None:\n                string += \" (%s)\" % self.comment\n            if self.parameters:\n                string += \";\" + \";\".join([\"%s%s\" % (name, \"\" if value is None else \"=%s\" % value)\n                                          for name, value in self.parameters.iteritems()])\n            return string\n\ndef RetryAfterHeader_new(cls, BaseRetryAfterHeader header):\n    return cls(header.seconds, header.comment, dict(header.parameters))\n\ncdef class RetryAfterHeader(BaseRetryAfterHeader):\n    def __init__(self, int seconds, str comment=None, dict parameters=None):\n        self.seconds = seconds\n        self.comment = comment\n        self.parameters = parameters if parameters is not None else {}\n\n    property parameters:\n\n        def __get__(self):\n            return self._parameters\n\n        def __set__(self, dict parameters not None):\n            self._parameters = parameters\n\n    property duration:\n\n        def __get__(self):\n            value = self.parameters.get(\"duration\", None)\n            if value is not None:\n                value = int(value)\n            return value\n\n        def __set__(self, object value):\n            if value is None:\n                self.parameters.pop(\"duration\", None)\n            else:\n                self.parameters[\"duration\"] = str(int(value))\n\n    new = classmethod(RetryAfterHeader_new)\n\ndel RetryAfterHeader_new\n\ndef FrozenRetryAfterHeader_new(cls, BaseRetryAfterHeader header):\n    if isinstance(header, cls):\n        return header\n    return cls(header.seconds, header.comment, frozendict(header.parameters))\n\ncdef class FrozenRetryAfterHeader(BaseRetryAfterHeader):\n    def __init__(self, int seconds, str comment=None, frozendict parameters not None=frozendict()):\n        if not self.initialized:\n            self.seconds = seconds\n            self.comment = comment\n            self.parameters = parameters\n            self.initialized = 1\n\n    def __hash__(self):\n        return hash((self.seconds, self.comment, self.parameters))\n\n    def __richcmp__(self, other, op):\n        return BaseRetryAfterHeader_richcmp(self, other, op)\n\n    property duration:\n\n        def __get__(self):\n            value = self.parameters.get(\"duration\", None)\n            if value is not None:\n                value = int(value)\n            return value\n\n    new = classmethod(FrozenRetryAfterHeader_new)\n\ndel FrozenRetryAfterHeader_new\n\n\ncdef object BaseViaHeader_richcmp(object self, object other, int op) with gil:\n    if op not in (2, 3):\n        return NotImplemented\n    if not isinstance(other, BaseViaHeader):\n        return NotImplemented\n    if op == 2:\n        return self.transport == other.transport and self.host == other.host and self.port == other.port and self.parameters == other.parameters\n    else:\n        return self.transport != other.transport or self.host != other.host or self.port != other.port or self.parameters != other.parameters\n\ncdef class BaseViaHeader:\n    normal_type = ViaHeader\n    frozen_type = FrozenViaHeader\n\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"BaseViaHeader cannot be instantiated directly\")\n\n    def __repr__(self):\n        return \"%s(%r, %r, %r, %r)\" % (self.__class__.__name__, self.transport, self.host, self.port, self.parameters)\n\n    def __str__(self):\n        return \"%s: %s\" % (self.name, self.body)\n\n    def __richcmp__(self, other, op):\n        return BaseViaHeader_richcmp(self, other, op)\n\n    property name:\n\n        def __get__(self):\n            return \"Via\"\n\n    property body:\n\n        def __get__(self):\n            string = \"SIP/2.0/%s %s:%d\" % (self.transport, self.host, self.port)\n            if self.parameters:\n                string += \";\" + \";\".join([\"%s%s\" % (name, \"\" if value is None else \"=%s\" % value)\n                                          for name, value in self.parameters.iteritems()])\n            return string\n\ndef ViaHeader_new(cls, BaseViaHeader header):\n    return cls(header.transport, header.host, header.port, dict(header.parameters))\n\ncdef class ViaHeader(BaseViaHeader):\n    def __init__(self, str transport not None, str host not None, int port=5060, dict parameters=None):\n        self.transport = transport\n        self.host = host\n        self.port = port\n        self.parameters = parameters if parameters is not None else {}\n\n    property transport:\n\n        def __get__(self):\n            return self._transport\n\n        def __set__(self, str transport not None):\n            self._transport = transport\n\n    property host:\n\n        def __get__(self):\n            return self._host\n\n        def __set__(self, str host not None):\n            self._host = host\n\n    property port:\n\n        def __get__(self):\n            return self._port\n\n        def __set__(self, int port):\n            if not (0 < port <= 65535):\n                raise ValueError(\"Invalid port: %d\" % port)\n            self._port = port\n\n    property parameters:\n\n        def __get__(self):\n            return self._parameters\n\n        def __set__(self, dict parameters not None):\n            self._parameters = parameters\n\n    property ttl:\n\n        def __get__(self):\n            value = self.parameters.get(\"ttl\", None)\n            if value is not None:\n                value = int(value)\n            return value\n\n        def __set__(self, object value):\n            if value is None:\n                self.parameters.pop(\"ttl\", None)\n            else:\n                self.parameters[\"ttl\"] = str(int(value))\n\n    property maddr:\n\n        def __get__(self):\n            return self.parameters.get(\"maddr\", None)\n\n        def __set__(self, str value):\n            if value is None:\n                self.parameters.pop(\"maddr\", None)\n            else:\n                self.parameters[\"maddr\"] = value\n\n    property received:\n\n        def __get__(self):\n            return self.parameters.get(\"received\", None)\n\n        def __set__(self, str value):\n            if value is None:\n                self.parameters.pop(\"received\", None)\n            else:\n                self.parameters[\"received\"] = value\n\n    property branch:\n\n        def __get__(self):\n            return self.parameters.get(\"branch\", None)\n\n        def __set__(self, str value):\n            if value is None:\n                self.parameters.pop(\"branch\", None)\n            else:\n                self.parameters[\"branch\"] = value\n\n    property compression:\n\n        def __get__(self):\n            return self.parameters.get(\"compression\", None)\n\n        def __set__(self, str value):\n            if value is None:\n                self.parameters.pop(\"compression\", None)\n            else:\n                self.parameters[\"compression\"] = value\n\n    property rport:\n\n        def __get__(self):\n            value = self.parameters.get(\"rport\", None)\n            if value is not None:\n                value = int(value)\n            return value\n\n        def __set__(self, object value):\n            if value is None:\n                self.parameters.pop(\"rport\", None)\n            else:\n                self.parameters[\"rport\"] = str(int(value))\n\n    new = classmethod(ViaHeader_new)\n\ndel ViaHeader_new\n\ndef FrozenViaHeader_new(cls, BaseViaHeader header):\n    if isinstance(header, cls):\n        return header\n    return cls(header.transport, header.host, header.port, frozendict(header.parameters))\n\ncdef class FrozenViaHeader(BaseViaHeader):\n    def __init__(self, str transport not None, str host not None, int port=5060, frozendict parameters not None=frozendict()):\n        if not self.initialized:\n            if not (0 < port <= 65535):\n                raise ValueError(\"Invalid port: %d\" % port)\n            self.transport = transport\n            self.host = host\n            self.port = port\n            self.parameters = parameters\n            self.initialized = 1\n\n    def __hash__(self):\n        return hash((self.transport, self.host, self.port, self.parameters))\n\n    def __richcmp__(self, other, op):\n        return BaseViaHeader_richcmp(self, other, op)\n\n    property ttl:\n\n        def __get__(self):\n            value = self.parameters.get(\"ttl\", None)\n            if value is not None:\n                value = int(value)\n            return value\n\n    property maddr:\n\n        def __get__(self):\n            return self.parameters.get(\"maddr\", None)\n\n    property received:\n\n        def __get__(self):\n            return self.parameters.get(\"received\", None)\n\n    property branch:\n\n        def __get__(self):\n            return self.parameters.get(\"branch\", None)\n\n    property compression:\n\n        def __get__(self):\n            return self.parameters.get(\"compression\", None)\n\n    property rport:\n\n        def __get__(self):\n            value = self.parameters.get(\"rport\", None)\n            if value is not None:\n                value = int(value)\n            return value\n\n    new = classmethod(FrozenViaHeader_new)\n\ndel FrozenViaHeader_new\n\n\ncdef object BaseWarningHeader_richcmp(object self, object other, int op) with gil:\n    if op not in (2, 3):\n        return NotImplemented\n    if not isinstance(other, BaseWarningHeader):\n        return NotImplemented\n    if op == 2:\n        return self.code == other.code and self.agent == other.agent and self.text == other.text\n    else:\n        return self.code != other.code or self.agent != other.agent or self.text != other.text\n\ncdef class BaseWarningHeader:\n    normal_type = WarningHeader\n    frozen_type = FrozenWarningHeader\n\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"BaseWarningHeader cannot be instantiated directly\")\n\n    def __repr__(self):\n        return \"%s(%r, %r, %r)\" % (self.__class__.__name__, self.code, self.agent, self.text)\n\n    def __str__(self):\n        return \"%s: %s\" % (self.name, self.body)\n\n    def __richcmp__(self, other, op):\n        return BaseWarningHeader_richcmp(self, other, op)\n\n    property name:\n\n        def __get__(self):\n            return \"Warning\"\n\n    property body:\n\n        def __get__(self):\n            return '%d %s \"%s\"' % (self.code, self.agent, self.text)\n\ndef WarningHeader_new(cls, BaseWarningHeader header):\n    return cls(header.code, header.agent, header.text)\n\ncdef class WarningHeader(BaseWarningHeader):\n    def __init__(self, int code, str agent not None, str text not None):\n        self.code = code\n        self.agent = agent\n        self.text = text\n\n    property code:\n\n        def __get__(self):\n            return self._code\n\n        def __set__(self, int code):\n            if code < 100 or code > 999:\n                raise ValueError(\"code needs to be a 3 digit number\")\n            self._code = code\n\n    property agent:\n\n        def __get__(self):\n            return self._agent\n\n        def __set__(self, str agent not None):\n            self._agent = agent\n\n    property text:\n\n        def __get__(self):\n            return self._text\n\n        def __set__(self, str text not None):\n            self._text = text\n\n    new = classmethod(WarningHeader_new)\n\ndel WarningHeader_new\n\ndef FrozenWarningHeader_new(cls, BaseWarningHeader header):\n    if isinstance(header, cls):\n        return header\n    return cls(header.code, header.agent, header.text)\n\ncdef class FrozenWarningHeader(BaseWarningHeader):\n    def __init__(self, int code, str agent not None, str text not None):\n        if not self.initialized:\n            if code < 100 or code > 999:\n                raise ValueError(\"code needs to be a 3 digit number\")\n            self.code = code\n            self.agent = agent\n            self.text = text\n            self.initialized = 1\n\n    def __hash__(self):\n        return hash((self.code, self.agent, self.text))\n\n    def __richcmp__(self, other, op):\n        return BaseWarningHeader_richcmp(self, other, op)\n\n    new = classmethod(FrozenWarningHeader_new)\n\ndel FrozenWarningHeader_new\n\n\ncdef object BaseEventHeader_richcmp(object self, object other, object op) with gil:\n    if op not in (2, 3):\n        return NotImplemented\n    if not isinstance(other, BaseEventHeader):\n        return NotImplemented\n    if op == 2:\n        return self.event == other.event and self.parameters == other.parameters\n    else:\n        return self.event != other.event or self.parameters != other.parameters\n\ncdef class BaseEventHeader:\n    normal_type = EventHeader\n    frozen_type = FrozenEventHeader\n\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"%s cannot be instantiated directly\" % self.__class__.__name__)\n\n    def __repr__(self):\n        return \"%s(%r, %r)\" % (self.__class__.__name__, self.event, self.parameters)\n\n    def __str__(self):\n        return \"%s: %s\" % (self.name, self.body)\n\n    def __richcmp__(self, other, op):\n        return BaseEventHeader_richcmp(self, other, op)\n\n    property name:\n\n        def __get__(self):\n            return \"Event\"\n\n    property body:\n\n        def __get__(self):\n            if self.parameters:\n                parameters = \";\" + \";\".join([\"%s%s\" % (name, \"\" if value is None else \"=%s\" % value)\n                                             for name, value in self.parameters.iteritems()])\n            else:\n                parameters = \"\"\n            return self.event + parameters\n\ndef EventHeader_new(cls, BaseEventHeader header):\n    return cls(header.event, dict(header.parameters))\n\ncdef class EventHeader(BaseEventHeader):\n    def __init__(self, str event not None, dict parameters=None):\n        self.event = event\n        self.parameters = parameters if parameters is not None else {}\n\n    property id:\n\n        def __get__(self):\n            return self._parameters.get(\"id\", None)\n\n        def __set__(self, str id):\n            if id is None:\n                self._parameters.pop(\"id\", None)\n            else:\n                self._parameters[\"id\"] = id\n\n    property parameters:\n\n        def __get__(self):\n            return self._parameters.copy()\n\n        def __set__(self, dict parameters not None):\n            self._parameters = parameters\n\n    new = classmethod(EventHeader_new)\n\ndel EventHeader_new\n\ndef FrozenEventHeader_new(cls, BaseEventHeader header):\n    if isinstance(header, cls):\n        return header\n    return cls(header.event, frozendict(header.parameters))\n\ncdef class FrozenEventHeader(BaseEventHeader):\n    def __init__(self, str event not None, frozendict parameters not None=frozendict()):\n        if not self.initialized:\n            self.event = event\n            self.parameters = parameters\n            self.initialized = 1\n\n    def __hash__(self):\n        return hash((self.event, self.parameters))\n\n    def __richcmp__(self, other, op):\n        return BaseEventHeader_richcmp(self, other, op)\n\n    property id:\n\n        def __get__(self):\n            return self.parameters.get(\"id\", None)\n\n    new = classmethod(FrozenEventHeader_new)\n\ndel FrozenEventHeader_new\n\n\ncdef object BaseSubscriptionStateHeader_richcmp(object self, object other, object op) with gil:\n    if op not in (2, 3):\n        return NotImplemented\n    if not isinstance(other, BaseSubscriptionStateHeader):\n        return NotImplemented\n    if op == 2:\n        return self.state == other.state and self.parameters == other.parameters\n    else:\n        return self.state != other.state or self.parameters != other.parameters\n\ncdef class BaseSubscriptionStateHeader:\n    normal_type = SubscriptionStateHeader\n    frozen_type = FrozenSubscriptionStateHeader\n\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"%s cannot be instantiated directly\" % self.__class__.__name__)\n\n    def __repr__(self):\n        return \"%s(%r, %r)\" % (self.__class__.__name__, self.state, self.parameters)\n\n    def __str__(self):\n        return \"%s: %s\" % (self.name, self.body)\n\n    def __richcmp__(self, other, op):\n        return BaseSubscriptionStateHeader_richcmp(self, other, op)\n\n    property name:\n\n        def __get__(self):\n            return \"SubscriptionState\"\n\n    property body:\n\n        def __get__(self):\n            if self.parameters:\n                parameters = \";\" + \";\".join([\"%s%s\" % (name, \"\" if value is None else \"=%s\" % value)\n                                             for name, value in self.parameters.iteritems()])\n            else:\n                parameters = \"\"\n            return self.state + parameters\n\ndef SubscriptionStateHeader_new(cls, BaseSubscriptionStateHeader header):\n    return cls(header.state, dict(header.parameters))\n\ncdef class SubscriptionStateHeader(BaseSubscriptionStateHeader):\n    def __init__(self, str state not None, dict parameters=None):\n        self.state = state\n        self.parameters = parameters if parameters is not None else {}\n\n    property reason:\n\n        def __get__(self):\n            return self._parameters.get(\"reason\", None)\n\n        def __set__(self, str reason):\n            if reason is None:\n                self._parameters.pop(\"reason\", None)\n            else:\n                self._parameters[\"reason\"] = reason\n\n    property expires:\n\n        def __get__(self):\n            return int(self._parameters.get(\"expires\", None))\n\n        def __set__(self, object expires):\n            cdef int expires_i\n            if expires is None:\n                self._parameters.pop(\"expires\", None)\n            else:\n                expires_i = expires\n                self._parameters[\"expires\"] = str(expires_i)\n\n    property retry_after:\n\n        def __get__(self):\n            return int(self._parameters.get(\"retry-after\", None))\n\n        def __set__(self, object retry_after):\n            cdef int retry_after_i\n            if retry_after is None:\n                self._parameters.pop(\"retry-after\", None)\n            else:\n                retry_after_i = retry_after\n                self._parameters[\"retry-after\"] = str(retry_after_i)\n\n    property parameters:\n\n        def __get__(self):\n            return self._parameters.copy()\n\n        def __set__(self, dict parameters not None):\n            self._parameters = parameters\n\n    new = classmethod(SubscriptionStateHeader_new)\n\ndel SubscriptionStateHeader_new\n\ndef FrozenSubscriptionStateHeader_new(cls, BaseSubscriptionStateHeader header):\n    if isinstance(header, cls):\n        return header\n    return cls(header.state, frozendict(header.parameters))\n\ncdef class FrozenSubscriptionStateHeader(BaseSubscriptionStateHeader):\n    def __init__(self, str state not None, frozendict parameters not None=frozendict()):\n        if not self.initialized:\n            self.state = state\n            self.parameters = parameters\n            self.initialized = 1\n\n    def __hash__(self):\n        return hash((self.state, self.parameters))\n\n    def __richcmp__(self, other, op):\n        return BaseSubscriptionStateHeader_richcmp(self, other, op)\n\n    property reason:\n\n        def __get__(self):\n            return self.parameters.get(\"reason\", None)\n\n    property expires:\n\n        def __get__(self):\n            expires = self.parameters.get(\"expires\", None)\n            if expires is not None:\n                expires = int(expires)\n            return expires\n\n    property retry_after:\n\n        def __get__(self):\n            retry_after = self.parameters.get(\"retry-after\", None)\n            if retry_after is not None:\n                retry_after = int(retry_after)\n            return retry_after\n\n    new = classmethod(FrozenSubscriptionStateHeader_new)\n\ndel FrozenSubscriptionStateHeader_new\n\n\ncdef object BaseReasonHeader_richcmp(object self, object other, object op) with gil:\n    if op not in (2, 3):\n        return NotImplemented\n    if not isinstance(other, BaseSubscriptionStateHeader):\n        return NotImplemented\n    if op == 2:\n        return self.protocol == other.protocol and self.parameters == other.parameters\n    else:\n        return self.protocol != other.protocol or self.parameters != other.parameters\n\ncdef class BaseReasonHeader:\n    normal_type = ReasonHeader\n    frozen_type = FrozenReasonHeader\n\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"%s cannot be instantiated directly\" % self.__class__.__name__)\n\n    def __repr__(self):\n        return \"%s(%r, %r)\" % (self.__class__.__name__, self.protocol, self.parameters)\n\n    def __str__(self):\n        return \"%s: %s\" % (self.name, self.body)\n\n    def __richcmp__(self, other, op):\n        return BaseReasonHeader_richcmp(self, other, op)\n\n    property name:\n\n        def __get__(self):\n            return \"Reason\"\n\n    property body:\n\n        def __get__(self):\n            if self.parameters:\n                parameters = \" ;\" + \" ;\".join([\"%s%s\" % (name, \"\" if value is None else \"=%s\" % value)\n                                             for name, value in self.parameters.iteritems()])\n            else:\n                parameters = \"\"\n            return self.protocol + parameters\n\ndef ReasonHeader_new(cls, BaseReasonHeader header):\n    return cls(header.state, dict(header.parameters))\n\ncdef class ReasonHeader(BaseReasonHeader):\n    def __init__(self, str protocol not None, dict parameters=None):\n        self.protocol = protocol\n        self.parameters = parameters if parameters is not None else {}\n\n    property cause:\n\n        def __get__(self):\n            cause = self.parameters.get(\"cause\", None)\n            if cause is not None:\n                cause = int(cause)\n            return cause\n\n        def __set__(self, object cause):\n            cdef int cause_i\n            if cause is None:\n                self.parameters.pop(\"cause\", None)\n            else:\n                cause_i = int(cause)\n                self.parameters[\"cause\"] = str(cause_i)\n\n    property text:\n\n        def __get__(self):\n            text = self.parameters.get(\"text\", None)\n            if text is not None:\n                text = text.strip().strip('\"')\n            return text\n\n        def __set__(self, str text):\n            if text is None:\n                self.parameters.pop(\"text\", None)\n            else:\n                if not text.startswith('\"'):\n                    text = '\"'+text\n                if not text[1:].endswith('\"'):\n                    text = text+'\"'\n                self.parameters[\"text\"] = text\n\n    new = classmethod(ReasonHeader_new)\n\ndel ReasonHeader_new\n\ndef FrozenReasonHeader_new(cls, BaseReasonHeader header):\n    if isinstance(header, cls):\n        return header\n    return cls(header.protocol, frozendict(header.parameters))\n\ncdef class FrozenReasonHeader(BaseReasonHeader):\n    def __init__(self, str protocol not None, frozendict parameters not None=frozendict()):\n        if not self.initialized:\n            self.protocol = protocol\n            self.parameters = parameters\n            self.initialized = 1\n\n    def __hash__(self):\n        return hash((self.protocol, self.parameters))\n\n    def __richcmp__(self, other, op):\n        return BaseReasonHeader_richcmp(self, other, op)\n\n    property cause:\n\n        def __get__(self):\n            cause = self.parameters.get(\"cause\", None)\n            if cause is not None:\n                cause = int(cause)\n            return cause\n\n    property text:\n\n        def __get__(self):\n            text = self.parameters.get(\"text\", None)\n            if text is not None:\n                text = text.strip().strip('\"')\n            return text\n\n    new = classmethod(FrozenReasonHeader_new)\n\ndel FrozenReasonHeader_new\n\n\ncdef object BaseReferToHeader_richcmp(object self, object other, object op) with gil:\n    if op not in (2, 3):\n        return NotImplemented\n    if not isinstance(other, BaseReferToHeader):\n        return NotImplemented\n    if op == 2:\n        return self.uri == other.uri and self.parameters == other.parameters\n    else:\n        return self.uri != other.uri or self.parameters != other.parameters\n\ncdef class BaseReferToHeader:\n    normal_type = ReferToHeader\n    frozen_type = FrozenReferToHeader\n\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"%s cannot be instantiated directly\" % self.__class__.__name__)\n\n    def __repr__(self):\n        return \"%s(%r, %r)\" % (self.__class__.__name__, self.uri, self.parameters)\n\n    def __str__(self):\n        return \"%s: %s\" % (self.name, self.body)\n\n    def __richcmp__(self, other, op):\n        return BaseReferToHeader_richcmp(self, other, op)\n\n    property name:\n\n        def __get__(self):\n            return \"Refer-To\"\n\n    property body:\n\n        def __get__(self):\n            if self.parameters:\n                parameters = \";\" + \";\".join([\"%s%s\" % (name, \"\" if value is None else \"=%s\" % value)\n                                             for name, value in self.parameters.iteritems()])\n            else:\n                parameters = \"\"\n            return \"<%s>%s\" % (self.uri, parameters)\n\ndef ReferToHeader_new(cls, BaseReferToHeader header):\n    return cls(header.uri, dict(header.parameters))\n\ncdef class ReferToHeader(BaseReferToHeader):\n    def __init__(self, str uri not None, dict parameters=None):\n        self.uri = uri\n        self.parameters = parameters if parameters is not None else {}\n\n    property parameters:\n\n        def __get__(self):\n            return self._parameters\n\n        def __set__(self, dict parameters not None):\n            self._parameters = parameters\n\n    new = classmethod(ReferToHeader_new)\n\ndel ReferToHeader_new\n\ndef FrozenReferToHeader_new(cls, BaseReferToHeader header):\n    if isinstance(header, cls):\n        return header\n    return cls(header.uri, frozendict(header.parameters))\n\ncdef class FrozenReferToHeader(BaseReferToHeader):\n    def __init__(self, str uri not None, frozendict parameters not None=frozendict()):\n        if not self.initialized:\n            self.uri = uri\n            self.parameters = parameters\n            self.initialized = 1\n\n    def __hash__(self):\n        return hash((self.uri, self.parameters))\n\n    def __richcmp__(self, other, op):\n        return BaseReferToHeader_richcmp(self, other, op)\n\n    new = classmethod(FrozenReferToHeader_new)\n\ndel FrozenReferToHeader_new\n\n\ncdef object BaseSubjectHeader_richcmp(object self, object other, int op) with gil:\n    if op not in (2, 3):\n        return NotImplemented\n    if not isinstance(other, BaseSubjectHeader):\n        return NotImplemented\n    if op == 2:\n        return self.subject == other.subject\n    else:\n        return self.subject != other.subject\n\ncdef class BaseSubjectHeader:\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"%s cannot be instantiated directly\" % self.__class__.__name__)\n\n    def __repr__(self):\n        return \"%s(%r)\" % (self.__class__.__name__, self.subject)\n\n    def __str__(self):\n        return \"%s: %s\" % (self.name, self.body)\n\n    def __unicode__(self):\n        return unicode(self.__str__(), encoding='utf-8')\n\n    def __richcmp__(self, other, op):\n        return BaseSubjectHeader_richcmp(self, other, op)\n\n    property name:\n\n        def __get__(self):\n            return \"Subject\"\n\n    property body:\n\n        def __get__(self):\n            return self.subject.encode('utf-8')\n\ndef SubjectHeader_new(cls, BaseSubjectHeader subject_header):\n    if isinstance(subject_header, cls):\n        return subject_header\n    return cls(subject_header.subject)\n\ncdef class SubjectHeader(BaseSubjectHeader):\n    def __init__(self, unicode subject=None):\n        if subject is None:\n            raise ValueError('subject must be specified')\n        self.subject = subject\n\n    new = classmethod(SubjectHeader_new)\n\ndel SubjectHeader_new\n\ndef FrozenSubjectHeader_new(cls, BaseSubjectHeader subject_header):\n    if isinstance(subject_header, cls):\n        return subject_header\n    return cls(subject_header.subject)\n\ncdef class FrozenSubjectHeader(BaseSubjectHeader):\n    def __init__(self, unicode subject=None):\n        if not self.initialized:\n            if subject is None:\n                raise ValueError('subject must be specified')\n            self.subject = subject\n            self.initialized = 1\n\n    def __hash__(self):\n        return hash((self.subject))\n\n    def __richcmp__(self, other, op):\n        return BaseSubjectHeader_richcmp(self, other, op)\n\n    new = classmethod(FrozenSubjectHeader_new)\n\ndel FrozenSubjectHeader_new\n\n\ncdef object BaseReplacesHeader_richcmp(object self, object other, int op) with gil:\n    if op not in (2, 3):\n        return NotImplemented\n    if not isinstance(other, BaseReplacesHeader):\n        return NotImplemented\n    if op == 2:\n        return self.call_id == other.call_id and self.from_tag == other.from_tag and self.to_tag == other.to_tag and self.early_only == other.early_only and self.parameters == other.parameters\n    else:\n        return self.call_id != other.call_id or self.from_tag != other.from_tag or self.to_tag != other.to_tag or self.early_only != other.early_only or self.parameters != other.parameters\n\ncdef class BaseReplacesHeader:\n    normal_type = ReplacesHeader\n    frozen_type = FrozenReplacesHeader\n\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"BaseReplacesHeader cannot be instantiated directly\")\n\n    def __repr__(self):\n        return \"%s(%r, %r, %r, %r, %r)\" % (self.__class__.__name__, self.call_id, self.from_tag, self.to_tag, self.early_only, self.parameters)\n\n    def __str__(self):\n        return \"%s: %s\" % (self.name, self.body)\n\n    def __richcmp__(self, other, op):\n        return BaseReplacesHeader_richcmp(self, other, op)\n\n    property name:\n\n        def __get__(self):\n            return \"Replaces\"\n\n    property body:\n\n        def __get__(self):\n            string = \"%s;from-tag=%s;to-tag=%s\" % (self.call_id, self.from_tag, self.to_tag)\n            if self.early_only:\n                string += \";early-only\"\n            if self.parameters:\n                string += \";\" + \";\".join([\"%s%s\" % (name, \"\" if value is None else \"=%s\" % value)\n                                          for name, value in self.parameters.iteritems()])\n            return string\n\ndef ReplacesHeader_new(cls, BaseReplacesHeader header):\n    return cls(header.call_id, header.from_tag, header.to_tag, header.early_only, dict(header.parameters))\n\ncdef class ReplacesHeader(BaseReplacesHeader):\n    def __init__(self, str call_id not None, str from_tag not None, str to_tag not None, int early_only=0, dict parameters=None):\n        self.call_id = call_id\n        self.from_tag = from_tag\n        self.to_tag = to_tag\n        self.early_only = early_only\n        self.parameters = parameters if parameters is not None else {}\n\n    property parameters:\n\n        def __get__(self):\n            return self._parameters\n\n        def __set__(self, dict parameters not None):\n            self._parameters = parameters\n\n    new = classmethod(ReplacesHeader_new)\n\ndel ReplacesHeader_new\n\ndef FrozenReplacesHeader_new(cls, BaseReplacesHeader header):\n    if isinstance(header, cls):\n        return header\n    return cls(header.call_id, header.header.from_tag, header.to_tag, header.early_only, frozendict(header.parameters))\n\ncdef class FrozenReplacesHeader(BaseReplacesHeader):\n    def __init__(self, str call_id not None, str from_tag not None, str to_tag not None, int early_only=0, frozendict parameters not None=frozendict()):\n        if not self.initialized:\n            self.call_id = call_id\n            self.from_tag = from_tag\n            self.to_tag = to_tag\n            self.early_only = early_only\n            self.parameters = parameters\n            self.initialized = 1\n\n    def __hash__(self):\n        return hash((self.call_id, self.from_tag, self.to_tag, self.early_only, self.parameters))\n\n    def __richcmp__(self, other, op):\n        return BaseReplacesHeader_richcmp(self, other, op)\n\n    new = classmethod(FrozenReplacesHeader_new)\n\ndel FrozenReplacesHeader_new\n\n\n# Factory functions\n#\n\ncdef Header Header_create(pjsip_generic_string_hdr *header):\n    return Header(_pj_str_to_str(header.name), _pj_str_to_str(header.hvalue))\n\ncdef FrozenHeader FrozenHeader_create(pjsip_generic_string_hdr *header):\n    return FrozenHeader(_pj_str_to_str(header.name), _pj_str_to_str(header.hvalue))\n\ncdef ContactHeader ContactHeader_create(pjsip_contact_hdr *header):\n    cdef pjsip_name_addr* name_addr\n    if header.star:\n        return ContactHeader(None)\n    else:\n        uri = SIPURI_create(<pjsip_sip_uri*>pjsip_uri_get_uri(header.uri))\n        name_addr = <pjsip_name_addr*> header.uri\n        if name_addr.display.slen > 0:\n            display_name = unicode(_pj_str_to_str(name_addr.display), encoding='utf-8')\n        else:\n            display_name = None\n        parameters = _pjsip_param_to_dict(&header.other_param)\n        if header.q1000 != -1:\n            parameters[\"q\"] = str(float(header.q1000)/1000)\n        if header.expires != -1:\n            parameters[\"expires\"] = str(header.expires)\n        return ContactHeader(uri, display_name, parameters)\n\ncdef FrozenContactHeader FrozenContactHeader_create(pjsip_contact_hdr *header):\n    cdef pjsip_name_addr* name_addr\n    if header.star:\n        return FrozenContactHeader(None)\n    else:\n        uri = FrozenSIPURI_create(<pjsip_sip_uri*>pjsip_uri_get_uri(header.uri))\n        name_addr = <pjsip_name_addr*> header.uri\n        if name_addr.display.slen > 0:\n            display_name = unicode(_pj_str_to_str(name_addr.display), encoding='utf-8')\n        else:\n            display_name = None\n        parameters = _pjsip_param_to_dict(&header.other_param)\n        if header.q1000 != -1:\n            parameters[\"q\"] = str(float(header.q1000)/1000)\n        if header.expires != -1:\n            parameters[\"expires\"] = str(header.expires)\n        return FrozenContactHeader(uri, display_name, frozendict(parameters))\n\ncdef ContentTypeHeader ContentTypeHeader_create(pjsip_ctype_hdr *header):\n    type_str = _pj_str_to_str(header.media.type)\n    subtype_str = _pj_str_to_str(header.media.subtype)\n    parameters = _pjsip_param_to_dict(&header.media.param)\n    if subtype_str:\n        content_type = \"%s/%s\" % (type_str, subtype_str)\n    else:\n        content_type = type_str\n    return ContentTypeHeader(content_type, parameters)\n\ncdef FrozenContentTypeHeader FrozenContentTypeHeader_create(pjsip_ctype_hdr *header):\n    type_str = _pj_str_to_str(header.media.type)\n    subtype_str = _pj_str_to_str(header.media.subtype)\n    parameters = _pjsip_param_to_dict(&header.media.param)\n    if subtype_str:\n        content_type = \"%s/%s\" % (type_str, subtype_str)\n    else:\n        content_type = type_str\n    return FrozenContentTypeHeader(content_type, frozendict(parameters))\n\ncdef FromHeader FromHeader_create(pjsip_fromto_hdr *header):\n    cdef pjsip_name_addr* name_addr\n    uri = SIPURI_create(<pjsip_sip_uri*>pjsip_uri_get_uri(header.uri))\n    name_addr = <pjsip_name_addr*> header.uri\n    if name_addr.display.slen > 0:\n        display_name = unicode(_pj_str_to_str(name_addr.display), encoding='utf-8')\n    else:\n        display_name = None\n    parameters = _pjsip_param_to_dict(&header.other_param)\n    if header.tag.slen > 0:\n        parameters[\"tag\"] = _pj_str_to_str(header.tag)\n    return FromHeader(uri, display_name, parameters)\n\ncdef FrozenFromHeader FrozenFromHeader_create(pjsip_fromto_hdr *header):\n    cdef pjsip_name_addr* name_addr\n    uri = FrozenSIPURI_create(<pjsip_sip_uri*>pjsip_uri_get_uri(header.uri))\n    name_addr = <pjsip_name_addr*> header.uri\n    if name_addr.display.slen > 0:\n        display_name = unicode(_pj_str_to_str(name_addr.display), encoding='utf-8')\n    else:\n        display_name = None\n    parameters = _pjsip_param_to_dict(&header.other_param)\n    if header.tag.slen > 0:\n        parameters[\"tag\"] = _pj_str_to_str(header.tag)\n    return FrozenFromHeader(uri, display_name, frozendict(parameters))\n\ncdef ToHeader ToHeader_create(pjsip_fromto_hdr *header):\n    cdef pjsip_name_addr* name_addr\n    uri = SIPURI_create(<pjsip_sip_uri*>pjsip_uri_get_uri(header.uri))\n    name_addr = <pjsip_name_addr*> header.uri\n    if name_addr.display.slen > 0:\n        display_name = unicode(_pj_str_to_str(name_addr.display), encoding='utf-8')\n    else:\n        display_name = None\n    parameters = _pjsip_param_to_dict(&header.other_param)\n    if header.tag.slen > 0:\n        parameters[\"tag\"] = _pj_str_to_str(header.tag)\n    return ToHeader(uri, display_name, parameters)\n\ncdef FrozenToHeader FrozenToHeader_create(pjsip_fromto_hdr *header):\n    cdef pjsip_name_addr* name_addr\n    uri = FrozenSIPURI_create(<pjsip_sip_uri*>pjsip_uri_get_uri(header.uri))\n    name_addr = <pjsip_name_addr*> header.uri\n    if name_addr.display.slen > 0:\n        display_name = unicode(_pj_str_to_str(name_addr.display), encoding='utf-8')\n    else:\n        display_name = None\n    parameters = _pjsip_param_to_dict(&header.other_param)\n    if header.tag.slen > 0:\n        parameters[\"tag\"] = _pj_str_to_str(header.tag)\n    return FrozenToHeader(uri, display_name, frozendict(parameters))\n\ncdef RouteHeader RouteHeader_create(pjsip_routing_hdr *header):\n    uri = SIPURI_create(<pjsip_sip_uri*>pjsip_uri_get_uri(<pjsip_uri *>&header.name_addr))\n    if header.name_addr.display.slen > 0:\n        display_name = unicode(_pj_str_to_str(header.name_addr.display), encoding='utf-8')\n    else:\n        display_name = None\n    parameters = _pjsip_param_to_dict(&header.other_param)\n    return RouteHeader(uri, display_name, parameters)\n\ncdef FrozenRouteHeader FrozenRouteHeader_create(pjsip_routing_hdr *header):\n    uri = FrozenSIPURI_create(<pjsip_sip_uri*>pjsip_uri_get_uri(<pjsip_uri *>&header.name_addr))\n    if header.name_addr.display.slen > 0:\n        display_name = unicode(_pj_str_to_str(header.name_addr.display), encoding='utf-8')\n    else:\n        display_name = None\n    parameters = frozendict(_pjsip_param_to_dict(&header.other_param))\n    return FrozenRouteHeader(uri, display_name, parameters)\n\ncdef RecordRouteHeader RecordRouteHeader_create(pjsip_routing_hdr *header):\n    uri = SIPURI_create(<pjsip_sip_uri*>pjsip_uri_get_uri(<pjsip_uri *>&header.name_addr))\n    if header.name_addr.display.slen > 0:\n        display_name = unicode(_pj_str_to_str(header.name_addr.display), encoding='utf-8')\n    else:\n        display_name = None\n    parameters = _pjsip_param_to_dict(&header.other_param)\n    return RecordRouteHeader(uri, display_name, parameters)\n\ncdef FrozenRecordRouteHeader FrozenRecordRouteHeader_create(pjsip_routing_hdr *header):\n    uri = FrozenSIPURI_create(<pjsip_sip_uri*>pjsip_uri_get_uri(<pjsip_uri *>&header.name_addr))\n    if header.name_addr.display.slen > 0:\n        display_name = unicode(_pj_str_to_str(header.name_addr.display), encoding='utf-8')\n    else:\n        display_name = None\n    parameters = frozendict(_pjsip_param_to_dict(&header.other_param))\n    return FrozenRecordRouteHeader(uri, display_name, parameters)\n\ncdef RetryAfterHeader RetryAfterHeader_create(pjsip_retry_after_hdr *header):\n    seconds = header.ivalue\n    if header.comment.slen > 0:\n        comment = _pj_str_to_str(header.comment)\n    else:\n        comment = None\n    parameters = _pjsip_param_to_dict(&header.param)\n    return RetryAfterHeader(seconds, comment, parameters)\n\ncdef FrozenRetryAfterHeader FrozenRetryAfterHeader_create(pjsip_retry_after_hdr *header):\n    seconds = header.ivalue\n    if header.comment.slen > 0:\n        comment = _pj_str_to_str(header.comment)\n    else:\n        comment = None\n    parameters = frozendict(_pjsip_param_to_dict(&header.param))\n    return FrozenRetryAfterHeader(seconds, comment, parameters)\n\ncdef ViaHeader ViaHeader_create(pjsip_via_hdr *header):\n    transport = _pj_str_to_str(header.transport)\n    host = _pj_str_to_str(header.sent_by.host)\n    port = header.sent_by.port or 5060\n    parameters = _pjsip_param_to_dict(&header.other_param)\n    if header.ttl_param != -1:\n        parameters[\"ttl\"] = header.ttl_param\n    if header.rport_param != -1:\n        parameters[\"rport\"] = header.rport_param\n    if header.maddr_param.slen > 0:\n        parameters[\"maddr\"] = _pj_str_to_str(header.maddr_param)\n    if header.recvd_param.slen > 0:\n        parameters[\"received\"] = _pj_str_to_str(header.recvd_param)\n    if header.branch_param.slen > 0:\n        parameters[\"branch\"] = _pj_str_to_str(header.branch_param)\n    return ViaHeader(transport, host, port, parameters)\n\ncdef FrozenViaHeader FrozenViaHeader_create(pjsip_via_hdr *header):\n    transport = _pj_str_to_str(header.transport)\n    host = _pj_str_to_str(header.sent_by.host)\n    port = header.sent_by.port or 5060\n    parameters = _pjsip_param_to_dict(&header.other_param)\n    if header.ttl_param != -1:\n        parameters[\"ttl\"] = header.ttl_param\n    if header.rport_param != -1:\n        parameters[\"rport\"] = header.rport_param\n    if header.maddr_param.slen > 0:\n        parameters[\"maddr\"] = _pj_str_to_str(header.maddr_param)\n    if header.recvd_param.slen > 0:\n        parameters[\"received\"] = _pj_str_to_str(header.recvd_param)\n    if header.branch_param.slen > 0:\n        parameters[\"branch\"] = _pj_str_to_str(header.branch_param)\n    return FrozenViaHeader(transport, host, port, frozendict(parameters))\n\ncdef EventHeader EventHeader_create(pjsip_event_hdr *header):\n    cdef dict parameters\n    parameters = _pjsip_param_to_dict(&header.other_param)\n    if header.id_param.slen != 0:\n        parameters[\"id\"] = _pj_str_to_str(header.id_param)\n    return EventHeader(_pj_str_to_str(header.event_type), parameters)\n\ncdef FrozenEventHeader FrozenEventHeader_create(pjsip_event_hdr *header):\n    cdef dict parameters\n    parameters = _pjsip_param_to_dict(&header.other_param)\n    if header.id_param.slen != 0:\n        parameters[\"id\"] = _pj_str_to_str(header.id_param)\n    return FrozenEventHeader(_pj_str_to_str(header.event_type), frozendict(parameters))\n\ncdef SubscriptionStateHeader SubscriptionStateHeader_create(pjsip_sub_state_hdr *header):\n    cdef dict parameters\n    parameters = _pjsip_param_to_dict(&header.other_param)\n    if header.reason_param.slen != 0:\n        parameters[\"reason\"] = _pj_str_to_str(header.reason_param)\n    if header.expires_param != -1:\n        parameters[\"expires\"] = str(header.expires_param)\n    if header.retry_after != -1:\n        parameters[\"retry-after\"] = str(header.retry_after)\n    return SubscriptionStateHeader(_pj_str_to_str(header.sub_state), parameters)\n\ncdef FrozenSubscriptionStateHeader FrozenSubscriptionStateHeader_create(pjsip_sub_state_hdr *header):\n    cdef dict parameters\n    parameters = _pjsip_param_to_dict(&header.other_param)\n    if header.reason_param.slen != 0:\n        parameters[\"reason\"] = _pj_str_to_str(header.reason_param)\n    if header.expires_param != -1:\n        parameters[\"expires\"] = str(header.expires_param)\n    if header.retry_after != -1:\n        parameters[\"retry-after\"] = str(header.retry_after)\n    return FrozenSubscriptionStateHeader(_pj_str_to_str(header.sub_state), frozendict(parameters))\n\ncdef ReferToHeader ReferToHeader_create(pjsip_generic_string_hdr *header):\n    cdef dict parameters\n    cdef str value\n    value = _pj_str_to_str((<pjsip_generic_string_hdr *>header).hvalue)\n    uri, sep, params_str = value.partition('>')\n    if sep:\n        uri += '>'\n    parameters = dict([(name, value or None) for name, sep, value in [param.partition('=') for param in params_str.split(';') if param]])\n    return ReferToHeader(uri, parameters)\n\ncdef FrozenReferToHeader FrozenReferToHeader_create(pjsip_generic_string_hdr *header):\n    cdef dict parameters\n    cdef str value\n    value = _pj_str_to_str((<pjsip_generic_string_hdr *>header).hvalue)\n    uri, sep, params_str = value.partition('>')\n    if sep:\n        uri += '>'\n    parameters = dict([(name, value or None) for name, sep, value in [param.partition('=') for param in params_str.split(';') if param]])\n    return FrozenReferToHeader(uri, frozendict(parameters))\n\ncdef SubjectHeader SubjectHeader_create(pjsip_generic_string_hdr *header):\n    subject = unicode(_pj_str_to_str((<pjsip_generic_string_hdr *>header).hvalue), encoding='utf-8')\n    return SubjectHeader(subject)\n\ncdef FrozenSubjectHeader FrozenSubjectHeader_create(pjsip_generic_string_hdr *header):\n    subject = unicode(_pj_str_to_str((<pjsip_generic_string_hdr *>header).hvalue), encoding='utf-8')\n    return FrozenSubjectHeader(subject)\n\ncdef ReplacesHeader ReplacesHeader_create(pjsip_replaces_hdr *header):\n    cdef dict parameters = _pjsip_param_to_dict(&header.other_param)\n    call_id = _pj_str_to_str(header.call_id)\n    from_tag = _pj_str_to_str(header.from_tag)\n    to_tag = _pj_str_to_str(header.to_tag)\n    early_only = int(header.early_only)\n    return ReplacesHeader(call_id, from_tag, to_tag, early_only, parameters)\n\ncdef FrozenReplacesHeader FrozenReplacesHeader_create(pjsip_replaces_hdr *header):\n    cdef dict parameters = _pjsip_param_to_dict(&header.other_param)\n    call_id = _pj_str_to_str(header.call_id)\n    from_tag = _pj_str_to_str(header.from_tag)\n    to_tag = _pj_str_to_str(header.to_tag)\n    early_only = int(header.early_only)\n    return FrozenReplacesHeader(call_id, from_tag, to_tag, early_only, frozendict(parameters))\n\n"
  },
  {
    "path": "sipsimple/core/_core.helper.pxi",
    "content": "\nimport re\nimport urllib\n\n\n# Classes\n#\n\ncdef class BaseCredentials:\n    def __cinit__(self, *args, **kwargs):\n        global _Credentials_scheme_digest, _Credentials_realm_wildcard\n        self._credentials.scheme = _Credentials_scheme_digest.pj_str\n\n    def __init__(self, str username not None, str password not None, str realm='*', bint digest=False):\n        if self.__class__ is BaseCredentials:\n            raise TypeError(\"BaseCredentials cannot be instantiated directly\")\n        self.username = username\n        self.realm = realm\n        self.password = password\n        self.digest = digest\n\n    def __repr__(self):\n        return \"%s(username=%r, password=%r, realm=%r, digest=%r)\" % (self.__class__.__name__, self.username, self.password, self.realm, self.digest)\n\n    def __str__(self):\n        return '<%s for \"%s@%s\">' % (self.__class__.__name__, self.username, self.realm)\n\n    cdef pjsip_cred_info* get_cred_info(self):\n        return &self._credentials\n\n\ncdef class Credentials(BaseCredentials):\n    property username:\n        def __get__(self):\n            return self._username\n\n        def __set__(self, str username not None):\n            _str_to_pj_str(username, &self._credentials.username)\n            self._username = username\n\n    property realm:\n        def __get__(self):\n            return self._realm\n\n        def __set__(self, str realm not None):\n            _str_to_pj_str(realm, &self._credentials.realm)\n            self._realm = realm\n\n    property password:\n        def __get__(self):\n            return self._password\n\n        def __set__(self, str password not None):\n            _str_to_pj_str(password, &self._credentials.data)\n            self._password = password\n\n    property digest:\n        def __get__(self):\n            return self._digest\n\n        def __set__(self, bint digest):\n            self._credentials.data_type = PJSIP_CRED_DATA_DIGEST if digest else PJSIP_CRED_DATA_PLAIN_PASSWD\n            self._digest = digest\n\n    @classmethod\n    def new(cls, BaseCredentials credentials):\n        return cls(credentials.username, credentials.password, credentials.realm, credentials.digest)\n\n\ncdef class FrozenCredentials(BaseCredentials):\n    def __init__(self, str username not None, str password not None, str realm='*', bint digest=False):\n        if not self.initialized:\n            self.username = username\n            self.realm = realm\n            self.password = password\n            self.digest = digest\n            _str_to_pj_str(self.username, &self._credentials.username)\n            _str_to_pj_str(self.realm, &self._credentials.realm)\n            _str_to_pj_str(self.password, &self._credentials.data)\n            self._credentials.data_type = PJSIP_CRED_DATA_DIGEST if digest else PJSIP_CRED_DATA_PLAIN_PASSWD\n            self.initialized = 1\n        else:\n            raise TypeError(\"{0.__class__.__name__} is read-only\".format(self))\n\n    def __hash__(self):\n        return hash((self.username, self.realm, self.password, self.digest))\n\n    @classmethod\n    def new(cls, BaseCredentials credentials):\n        if isinstance(credentials, FrozenCredentials):\n            return credentials\n        return cls(credentials.username, credentials.password, credentials.realm, credentials.digest)\n\n\ncdef class BaseSIPURI:\n    def __init__(self, object host not None, object user=None, object password=None, object port=None, bint secure=False, dict parameters=None, dict headers=None):\n        if self.__class__ is BaseSIPURI:\n            raise TypeError(\"BaseSIPURI cannot be instantiated directly\")\n        self.host = host\n        self.user = user\n        self.password = password\n        self.port = port\n        self.secure = secure\n        self.parameters = parameters if parameters is not None else {}\n        self.headers = headers if headers is not None else {}\n\n    property transport:\n        def __get__(self):\n            return self.parameters.get('transport', 'udp')\n\n        def __set__(self, str transport not None):\n            if transport.lower() == 'udp':\n                self.parameters.pop('transport', None)\n            else:\n                self.parameters['transport'] = transport\n\n    def __reduce__(self):\n        return self.__class__, (self.host, self.user, self.password, self.port, self.secure, self.parameters, self.headers), None\n\n    def __repr__(self):\n        return \"%s(%r, %r, %r, %r, %r, %r, %r)\" % (self.__class__.__name__, self.host, self.user, self.password, self.port, self.secure, self.parameters, self.headers)\n\n    def __str__(self):\n        cdef object string = self.host\n        if self.port:\n            string = \"%s:%d\" % (string, self.port)\n        if self.user is not None:\n            if self.password is not None:\n                string = \"%s:%s@%s\" % (self.user, self.password, string)\n            else:\n                string = \"%s@%s\" % (self.user, string)\n        if self.parameters:\n            string += \";\" + \";\".join([\"%s%s\" % (name, (\"\" if val is None else \"=\"+urllib.quote(val, safe=\"()[]-_.!~*'/:&+$\")))\n                                      for name, val in self.parameters.iteritems()])\n        if self.headers:\n            string += \"?\" + \"&\".join([\"%s%s\" % (name, (\"\" if val is None else \"=\"+urllib.quote(val, safe=\"()[]-_.!~*'/:?+$\")))\n                                      for name, val in self.headers.iteritems()])\n        if self.secure:\n            string = \"sips:\" + string\n        else:\n            string = \"sip:\" + string\n        return string\n\n    def __richcmp__(self, other, op):\n        if not isinstance(other, BaseSIPURI):\n            return NotImplemented\n        if op == 2:    # 2 is ==\n            return all(getattr(self, name) == getattr(other, name) for name in (\"user\", \"password\", \"host\", \"port\", \"secure\", \"parameters\", \"headers\"))\n        elif op == 3:  # 3 is !=\n            return any(getattr(self, name) != getattr(other, name) for name in (\"user\", \"password\", \"host\", \"port\", \"secure\", \"parameters\", \"headers\"))\n        else:\n            operator_map = {0: '<', 1: '<=', 2: '==', 3: '!=', 4: '>', 5: '>='}\n            raise TypeError(\"unorderable types: {0.__class__.__name__}() {2} {1.__class__.__name__}()\".format(self, other, operator_map[op]))\n\n    def matches(self, address):\n        match = re.match(r'^((?P<scheme>sip|sips):)?(?P<username>.+?)(@(?P<domain>.+?)(:(?P<port>\\d+?))?)?(;(?P<parameters>.+?))?(\\?(?P<headers>.+?))?$', address)\n        if match is None:\n            return False\n        components = match.groupdict()\n        if components['scheme'] is not None:\n            expected_scheme = 'sips' if self.secure else 'sip'\n            if components['scheme'] != expected_scheme:\n                return False\n        if components['username'] != self.user:\n            return False\n        if components['domain'] is not None and components['domain'] != self.host:\n            return False\n        if components['port'] is not None and int(components['port']) != self.port:\n            return False\n        if components['parameters']:\n            parameters = dict([(name, value) for name, sep, value in [param.partition('=') for param in components['parameters'].split(';')]])\n            expected_parameters = dict([(name, str(value) if value is not None else None) for name, value in self.parameters.iteritems() if name in parameters])\n            if parameters != expected_parameters:\n                return False\n        if components['headers']:\n            headers = dict([(name, value) for name, sep, value in [header.partition('=') for header in components['headers'].split('&')]])\n            expected_headers = dict([(name, str(value) if value is not None else None) for name, value in self.headers.iteritems() if name in headers])\n            if headers != expected_headers:\n                return False\n        return True\n\n\ncdef class SIPURI(BaseSIPURI):\n    property port:\n        def __get__(self):\n            return self._port\n\n        def __set__(self, object port):\n            if port is not None:\n                port = int(port)\n                if not (0 < port <= 65535):\n                    raise ValueError(\"Invalid port: %d\" % port)\n            self._port = port\n\n    @classmethod\n    def new(cls, BaseSIPURI sipuri):\n        return cls(user=sipuri.user, password=sipuri.password, host=sipuri.host, port=sipuri.port, secure=sipuri.secure, parameters=dict(sipuri.parameters), headers=dict(sipuri.headers))\n\n    @classmethod\n    def parse(cls, object uri_str):\n        if not isinstance(uri_str, basestring):\n            raise TypeError('a string or unicode is required')\n        cdef bytes uri_bytes = str(uri_str)\n        cdef pjsip_uri *uri = NULL\n        cdef pj_pool_t *pool = NULL\n        cdef pj_str_t tmp\n        cdef char buffer[4096]\n        pool = pj_pool_create_on_buf(\"SIPURI_parse\", buffer, sizeof(buffer))\n        if pool == NULL:\n            raise SIPCoreError(\"Could not allocate memory pool\")\n        pj_strdup2_with_null(pool, &tmp, uri_bytes)\n        uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)\n        if uri == NULL:\n            raise SIPCoreError(\"Not a valid SIP URI: %s\" % uri_str)\n        return SIPURI_create(<pjsip_sip_uri *>pjsip_uri_get_uri(uri))\n\n\ncdef class FrozenSIPURI(BaseSIPURI):\n    def __init__(self, object host not None, object user=None, object password=None, object port=None, bint secure=False, frozendict parameters not None=frozendict(), frozendict headers not None=frozendict()):\n        if not self.initialized:\n            if port is not None:\n                port = int(port)\n                if not (0 < port <= 65535):\n                    raise ValueError(\"Invalid port: %d\" % port)\n            self.host = host\n            self.user = user\n            self.password = password\n            self.port = port\n            self.secure = secure\n            self.parameters = parameters\n            self.headers = headers\n            self.initialized = 1\n        else:\n            raise TypeError(\"{0.__class__.__name__} is read-only\".format(self))\n\n    property transport:\n        def __get__(self):\n            return self.parameters.get('transport', 'udp')\n\n    def __hash__(self):\n        return hash((self.user, self.password, self.host, self.port, self.secure, self.parameters, self.headers))\n\n    def __richcmp__(self, other, op):  # since we define __hash__, __richcmp__ is not inherited (see https://docs.python.org/2/c-api/typeobj.html#c.PyTypeObject.tp_richcompare)\n        if not isinstance(other, BaseSIPURI):\n            return NotImplemented\n        if op == 2:    # 2 is ==\n            return all(getattr(self, name) == getattr(other, name) for name in (\"user\", \"password\", \"host\", \"port\", \"secure\", \"parameters\", \"headers\"))\n        elif op == 3:  # 3 is !=\n            return any(getattr(self, name) != getattr(other, name) for name in (\"user\", \"password\", \"host\", \"port\", \"secure\", \"parameters\", \"headers\"))\n        else:\n            operator_map = {0: '<', 1: '<=', 2: '==', 3: '!=', 4: '>', 5: '>='}\n            raise TypeError(\"unorderable types: {0.__class__.__name__}() {2} {1.__class__.__name__}()\".format(self, other, operator_map[op]))\n\n    @classmethod\n    def new(cls, BaseSIPURI sipuri):\n        if isinstance(sipuri, FrozenSIPURI):\n            return sipuri\n        return cls(user=sipuri.user, password=sipuri.password, host=sipuri.host, port=sipuri.port, secure=sipuri.secure, parameters=frozendict(sipuri.parameters), headers=frozendict(sipuri.headers))\n\n    @classmethod\n    def parse(cls, object uri_str):\n        if not isinstance(uri_str, basestring):\n            raise TypeError('a string or unicode is required')\n        cdef bytes uri_bytes = str(uri_str)\n        cdef pjsip_uri *uri = NULL\n        cdef pj_pool_t *pool = NULL\n        cdef pj_str_t tmp\n        cdef char buffer[4096]\n        pool = pj_pool_create_on_buf(\"FrozenSIPURI_parse\", buffer, sizeof(buffer))\n        if pool == NULL:\n            raise SIPCoreError(\"Could not allocate memory pool\")\n        pj_strdup2_with_null(pool, &tmp, uri_bytes)\n        uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)\n        if uri == NULL:\n            raise SIPCoreError(\"Not a valid SIP URI: %s\" % uri_str)\n        return FrozenSIPURI_create(<pjsip_sip_uri *>pjsip_uri_get_uri(uri))\n\n\n# Factory functions\n#\n\ncdef dict _pj_sipuri_to_dict(pjsip_sip_uri *uri):\n    cdef object scheme\n    cdef pj_str_t *scheme_str\n    cdef pjsip_param *param\n    cdef object parameters = {}\n    cdef object headers = {}\n    cdef object kwargs = dict(parameters=parameters, headers=headers)\n    kwargs[\"host\"] = _pj_str_to_str(uri.host)\n    scheme = _pj_str_to_str(pjsip_uri_get_scheme(<pjsip_uri *>uri)[0])\n    if scheme == \"sip\":\n        kwargs[\"secure\"] = False\n    elif scheme == \"sips\":\n        kwargs[\"secure\"] = True\n    else:\n        raise SIPCoreError(\"Not a sip(s) URI\")\n    if uri.user.slen > 0:\n        kwargs[\"user\"] = _pj_str_to_str(uri.user)\n    if uri.passwd.slen > 0:\n        kwargs[\"password\"] = _pj_str_to_str(uri.passwd)\n    if uri.port > 0:\n        kwargs[\"port\"] = uri.port\n    if uri.user_param.slen > 0:\n        parameters[\"user\"] = _pj_str_to_str(uri.user_param)\n    if uri.method_param.slen > 0:\n        parameters[\"method\"] = _pj_str_to_str(uri.method_param)\n    if uri.transport_param.slen > 0:\n        parameters[\"transport\"] = _pj_str_to_str(uri.transport_param)\n    if uri.ttl_param != -1:\n        parameters[\"ttl\"] = uri.ttl_param\n    if uri.lr_param != 0:\n        parameters[\"lr\"] = None\n    if uri.maddr_param.slen > 0:\n        parameters[\"maddr\"] = _pj_str_to_str(uri.maddr_param)\n    param = <pjsip_param *> (<pj_list *> &uri.other_param).next\n    while param != &uri.other_param:\n        if param.value.slen == 0:\n            parameters[_pj_str_to_str(param.name)] = None\n        else:\n            parameters[_pj_str_to_str(param.name)] = _pj_str_to_str(param.value)\n        param = <pjsip_param *> (<pj_list *> param).next\n    param = <pjsip_param *> (<pj_list *> &uri.header_param).next\n    while param != &uri.header_param:\n        if param.value.slen == 0:\n            headers[_pj_str_to_str(param.name)] = None\n        else:\n            headers[_pj_str_to_str(param.name)] = _pj_str_to_str(param.value)\n        param = <pjsip_param *> (<pj_list *> param).next\n    return kwargs\n\ncdef SIPURI SIPURI_create(pjsip_sip_uri *uri):\n    cdef dict kwargs = _pj_sipuri_to_dict(uri)\n    return SIPURI(**kwargs)\n\ncdef FrozenSIPURI FrozenSIPURI_create(pjsip_sip_uri *uri):\n    cdef dict kwargs = _pj_sipuri_to_dict(uri)\n    kwargs[\"parameters\"] = frozendict(kwargs[\"parameters\"])\n    kwargs[\"headers\"] = frozendict(kwargs[\"headers\"])\n    return FrozenSIPURI(**kwargs)\n\n\n# Globals\n#\n\ncdef PJSTR _Credentials_scheme_digest = PJSTR(\"digest\")\n\n\n"
  },
  {
    "path": "sipsimple/core/_core.invitation.pxi",
    "content": "\nimport weakref\n\nfrom errno import EADDRNOTAVAIL, ENETUNREACH\nfrom operator import itemgetter\n\n\n# classes\n\ncdef class SDPPayloads:\n    def __init__(self):\n        self.proposed_local = None\n        self.proposed_remote = None\n        self.active_local = None\n        self.active_remote = None\n\n\ncdef class StateCallbackTimer(Timer):\n    def __init__(self, state, sub_state, rdata, tdata, originator):\n        self.state = state\n        self.sub_state = sub_state\n        self.rdata = rdata\n        self.tdata = tdata\n        self.originator = originator\n\n\ncdef class SDPCallbackTimer(Timer):\n    def __init__(self, int status, active_local, active_remote):\n        self.status = status\n        self.active_local = active_local\n        self.active_remote = active_remote\n\n\ncdef class TransferStateCallbackTimer(Timer):\n    def __init__(self, state, code, reason):\n        self.state = state\n        self.code = code\n        self.reason = reason\n\n\ncdef class TransferResponseCallbackTimer(Timer):\n    def __init__(self, method, rdata):\n        self.method = method\n        self.rdata = rdata\n\n\ncdef class TransferRequestCallbackTimer(Timer):\n    def __init__(self, rdata):\n        self.rdata = rdata\n\n\nclass DialogID(tuple):\n    call_id = property(itemgetter(0))\n    local_tag = property(itemgetter(1))\n    remote_tag = property(itemgetter(2))\n\n    def __new__(cls, call_id, local_tag, remote_tag):\n        return tuple.__new__(cls, (call_id, local_tag, remote_tag))\n\n    def __repr__(self):\n        return 'DialogID(call_id=%r, local_tag=%r, remote_tag=%r)' % self\n\n\ncdef class Invitation:\n    expire_warning_time = 30\n\n    def __cinit__(self, *args, **kwargs):\n        cdef int status\n\n        self.weakref = weakref.ref(self)\n        Py_INCREF(self.weakref)\n\n        status = pj_mutex_create_recursive(_get_ua()._pjsip_endpoint._pool, \"invitation_lock\", &self._lock)\n        if status != 0:\n            raise PJSIPError(\"failed to create lock\", status)\n\n        pj_list_init(<pj_list *> &self._route_set)\n        self._invite_session = NULL\n        self._dialog = NULL\n        self._reinvite_transaction = NULL\n        self._transfer_usage = NULL\n        self._sdp_neg_status = -1\n        self._failed_response = 0\n        self._timer = None\n        self._transfer_timeout_timer = None\n        self._transfer_refresh_timer = None\n        self.from_header = None\n        self.to_header = None\n        self.request_uri = None\n        self.route_header = None\n        self.local_contact_header = None\n        self.remote_contact_header = None\n        self.credentials = None\n        self.sdp = SDPPayloads()\n        self.remote_user_agent = None\n        self.state = None\n        self.sub_state = None\n        self.transport = None\n        self.transfer_state = None\n        self.direction = None\n        self.call_id = None\n        self.peer_address = None\n\n    cdef int init_incoming(self, PJSIPUA ua, pjsip_rx_data *rdata, unsigned int inv_options) except -1:\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_sdp_session_ptr_const sdp\n        cdef pjsip_dialog *replaced_dialog = NULL\n        cdef pjsip_tpselector tp_sel\n        cdef pjsip_tx_data *tdata = NULL\n        cdef PJSTR contact_str\n        cdef char *error_message\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            # Validate replaces header\n            with nogil:\n                status = pjsip_replaces_verify_request(rdata, &replaced_dialog, 0, &tdata)\n                if status != 0:\n                    if tdata != NULL:\n                        pjsip_endpt_send_response2(ua._pjsip_endpoint._obj, rdata, tdata, NULL, NULL)\n                    else:\n                        pjsip_endpt_respond_stateless(ua._pjsip_endpoint._obj, rdata, 500, NULL, NULL, NULL)\n            if status != 0:\n                return 0\n\n            self.direction = \"incoming\"\n            self.transport = rdata.tp_info.transport.type_name.lower()\n            self.request_uri = FrozenSIPURI_create(<pjsip_sip_uri *> pjsip_uri_get_uri(rdata.msg_info.msg.line.req.uri))\n            if _is_valid_ip(pj_AF_INET(), self.request_uri.host):\n                self.local_contact_header = FrozenContactHeader(self.request_uri)\n            else:\n                self.local_contact_header = FrozenContactHeader(FrozenSIPURI(host=_pj_str_to_str(rdata.tp_info.transport.local_name.host),\n                                                                             user=self.request_uri.user, port=rdata.tp_info.transport.local_name.port,\n                                                                             parameters=(frozendict(transport=self.transport) if self.transport != \"udp\" else frozendict())))\n            contact_str = PJSTR(str(self.local_contact_header.body))\n            tp_sel.type = PJSIP_TPSELECTOR_TRANSPORT\n            tp_sel.u.transport = rdata.tp_info.transport\n\n            with nogil:\n                status = pjsip_dlg_create_uas_and_inc_lock(pjsip_ua_instance(), rdata, &contact_str.pj_str, &self._dialog)\n                if status != 0:\n                    error_message = \"Could not create dialog for new INVITE session\"\n                else:\n                    pjsip_dlg_set_transport(self._dialog, &tp_sel)\n                    status = pjsip_inv_create_uas(self._dialog, rdata, NULL, inv_options, &self._invite_session)\n                    pjsip_dlg_dec_lock(self._dialog)\n                    if status != 0:\n                        error_message = \"Could not create new INVITE session\"\n                    else:\n                        status = pjsip_inv_initial_answer(self._invite_session, rdata, 100, NULL, NULL, &tdata)\n                        if status != 0:\n                            error_message = \"Could not create initial (unused) response to INVITE\"\n                        else:\n                            pjsip_tx_data_dec_ref(tdata)\n\n            if status != 0:\n                raise PJSIPError(error_message, status)\n\n            if self._invite_session.neg != NULL:\n                if pjmedia_sdp_neg_get_state(self._invite_session.neg) == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER:\n                    pjmedia_sdp_neg_get_neg_remote(self._invite_session.neg, &sdp)\n                    self.sdp.proposed_remote = FrozenSDPSession_create(sdp)\n            self._invite_session.sdp_neg_flags = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE\n            self._invite_session.mod_data[ua._module.id] = <void *> self.weakref\n            self.call_id = _pj_str_to_str(self._dialog.call_id.id)\n            self.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n            event_dict = dict(obj=self, prev_state=self.state, state=\"incoming\", originator=\"remote\")\n            _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n            self.state = \"incoming\"\n            self.remote_user_agent = event_dict['headers']['User-Agent'].body if 'User-Agent' in event_dict['headers'] else None\n            try:\n                self.remote_contact_header = event_dict['headers']['Contact'][0]\n            except LookupError:\n                pass\n            _add_event(\"SIPInvitationChangedState\", event_dict)\n\n            self.from_header = FrozenFromHeader_create(rdata.msg_info.from_hdr)\n            self.to_header = FrozenToHeader_create(rdata.msg_info.to_hdr)\n        except:\n            if self._invite_session != NULL:\n                with nogil:\n                    pjsip_inv_terminate(self._invite_session, 500, 0)\n                self._invite_session = NULL\n            elif self._dialog != NULL:\n                with nogil:\n                    pjsip_dlg_terminate(self._dialog)\n                self._dialog = NULL\n            else:\n                with nogil:\n                    status = pjsip_endpt_create_response(ua._pjsip_endpoint._obj, rdata, 500, NULL, &tdata)\n                    if status != 0:\n                        error_message = \"Could not create response\"\n                    else:\n                        status = pjsip_endpt_send_response2(ua._pjsip_endpoint._obj, rdata, tdata, NULL, NULL)\n                        if status != 0:\n                            pjsip_tx_data_dec_ref(tdata)\n                            error_message = \"Could not send response\"\n                if status != 0:\n                    raise PJSIPError(error_message, status)\n            raise\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n        return 0\n\n    cdef int process_incoming_transfer(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1:\n        global _incoming_transfer_cb\n        global _event_hdr_name\n        cdef int status, status2\n        cdef dict rdata_dict = dict(obj=self)\n        cdef pjsip_tx_data *tdata\n        cdef pjsip_transaction *initial_tsx\n        cdef Timer timer\n        cdef char *error_message\n\n        if self._transfer_usage != NULL:\n            with nogil:\n                status = pjsip_endpt_create_response(ua._pjsip_endpoint._obj, rdata, 480, NULL, &tdata)\n                if status != 0:\n                    error_message = \"Could not create response\"\n                else:\n                    status = pjsip_endpt_send_response2(ua._pjsip_endpoint._obj, rdata, tdata, NULL, NULL)\n                    if status != 0:\n                        pjsip_tx_data_dec_ref(tdata)\n                        error_message = \"Could not send response\"\n            if status != 0:\n                raise PJSIPError(error_message, status)\n            return 0\n        _pjsip_msg_to_dict(rdata.msg_info.msg, rdata_dict)\n        try:\n            refer_to_hdr = rdata_dict[\"headers\"][\"Refer-To\"]\n            SIPURI.parse(refer_to_hdr.uri)\n        except (KeyError, SIPCoreError):\n            with nogil:\n                status = pjsip_endpt_create_response(ua._pjsip_endpoint._obj, rdata, 400, NULL, &tdata)\n                if status != 0:\n                    error_message = \"Could not create response\"\n                else:\n                    status = pjsip_endpt_send_response2(ua._pjsip_endpoint._obj, rdata, tdata, NULL, NULL)\n                    if status != 0:\n                        pjsip_tx_data_dec_ref(tdata)\n                        error_message = \"Could not send response\"\n            if status != 0:\n                raise PJSIPError(error_message, status)\n            return 0\n        try:\n            self._set_transfer_state(\"INCOMING\")\n            _add_event(\"SIPInvitationTransferNewIncoming\", rdata_dict)\n            # PJSIP event framework needs an Event header, even if it's not needed for REFER, so we insert a fake one\n            event_header = <pjsip_event_hdr *> pjsip_msg_find_hdr_by_name(rdata.msg_info.msg, &_event_hdr_name.pj_str, NULL)\n            if event_header == NULL:\n                event_header = pjsip_event_hdr_create(rdata.tp_info.pool)\n                event_header.event_type = _refer_event.pj_str\n                pjsip_msg_add_hdr(rdata.msg_info.msg, <pjsip_hdr *> event_header)\n            initial_tsx = pjsip_rdata_get_tsx(rdata)\n            with nogil:\n                status = pjsip_evsub_create_uas(self._dialog, &_incoming_transfer_cb, rdata, 0, &self._transfer_usage)\n                if status != 0:\n                    pjsip_tsx_terminate(initial_tsx, 500)\n                    error_message = \"Could not create incoming REFER session\"\n                else:\n                    self._transfer_usage_role = PJSIP_ROLE_UAS\n                    pjsip_evsub_set_mod_data(self._transfer_usage, ua._event_module.id, <void *> self.weakref)\n                    status = pjsip_dlg_create_response(self._dialog, rdata, 202, NULL, &tdata)\n                    if status != 0:\n                        pjsip_tsx_terminate(initial_tsx, 500)\n                        error_message = \"Could not create response for incoming REFER\"\n                    else:\n                        pjsip_evsub_update_expires(self._transfer_usage, 90)\n                        status = pjsip_dlg_send_response(self._dialog, initial_tsx, tdata)\n                        if status != 0:\n                            status2 = pjsip_dlg_modify_response(self._dialog, tdata, 500, NULL)\n                            if status2 != 0:\n                                error_message = \"Could not modify response\"\n                                status = status2\n                            else:\n                                pjsip_tx_data_dec_ref(tdata)  # pjsip_dlg_modify_response() increases ref count unnecessarily\n                                error_message = \"Could not send response\"\n            if status != 0:\n                raise PJSIPError(error_message, status)\n        except PJSIPError, e:\n            code = 0\n            reason = e.args[0]\n            if self._transfer_usage != NULL:\n                with nogil:\n                    pjsip_evsub_terminate(self._transfer_usage, 0)\n            # Manually trigger the state callback since we handle the timeout ourselves\n            state_timer = TransferStateCallbackTimer(\"TERMINATED\", code, reason)\n            state_timer.schedule(0, <timer_callback>self._transfer_cb_state, self)\n            raise\n        else:\n            self._set_transfer_state(\"ACTIVE\")\n            _add_event(\"SIPInvitationTransferDidStart\", dict(obj=self))\n            timer = Timer()\n            timer.schedule(0, <timer_callback>self._start_incoming_transfer, self)\n        return 0\n\n    cdef int process_incoming_options(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1:\n        cdef pjsip_tx_data *tdata\n        cdef pjsip_transaction *initial_tsx\n        cdef int status\n        cdef char *error_message\n\n        initial_tsx = pjsip_rdata_get_tsx(rdata)\n        with nogil:\n            status = pjsip_dlg_create_response(self._dialog, rdata, 200, NULL, &tdata)\n            if status != 0:\n                pjsip_tsx_terminate(initial_tsx, 500)\n                error_message = \"Could not create response for incoming OPTIONS\"\n            else:\n                status = pjsip_dlg_send_response(self._dialog, initial_tsx, tdata)\n                if status != 0:\n                    error_message = \"Could not send response\"\n        if status != 0:\n            raise PJSIPError(error_message, status)\n\n    def send_invite(self, SIPURI request_uri not None, FromHeader from_header not None, ToHeader to_header not None, RouteHeader route_header not None, ContactHeader contact_header not None,\n                    SDPSession sdp not None, Credentials credentials=None, list extra_headers not None=list(), timeout=None):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_sdp_session *local_sdp\n        cdef pjsip_cred_info *cred_info\n        cdef pjsip_replaces_hdr *pj_replaces_hdr\n        cdef pjsip_route_hdr *route_set\n        cdef pjsip_tx_data *tdata\n        cdef PJSIPUA ua\n        cdef PJSTR contact_str\n        cdef PJSTR from_header_str\n        cdef PJSTR to_header_str\n        cdef PJSTR request_uri_str\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            route_set = <pjsip_route_hdr *> &self._route_set\n\n            if self.state is not None:\n                raise SIPCoreInvalidStateError('Can only transition to the \"outgoing\" state from the \"None\" state, currently in the \"%s\" state' % self.state)\n            if timeout is not None and timeout <= 0:\n                raise ValueError(\"Timeout value must be positive\")\n\n            self.transport = route_header.uri.transport\n            self.direction = \"outgoing\"\n            self.credentials = FrozenCredentials.new(credentials) if credentials is not None else None\n            self.request_uri = FrozenSIPURI.new(request_uri)\n            self.route_header = FrozenRouteHeader.new(route_header)\n            self.route_header.uri.parameters.dict[\"lr\"] = None # always send lr parameter in Route header\n            self.route_header.uri.parameters.dict[\"hide\"] = None # always hide Route header\n            self.local_contact_header = FrozenContactHeader.new(contact_header)\n            self.sdp.proposed_local = FrozenSDPSession.new(sdp) if sdp is not None else None\n\n            from_header_parameters = from_header.parameters.copy()\n            from_header_parameters.pop(\"tag\", None)\n            from_header.parameters = {}\n            from_header_str = PJSTR(from_header.body)\n            to_header_parameters = to_header.parameters.copy()\n            to_header_parameters.pop(\"tag\", None)\n            to_header.parameters = {}\n            to_header_str = PJSTR(to_header.body)\n            contact_str = PJSTR(str(self.local_contact_header.body))\n            request_uri_str = PJSTR(str(request_uri))\n\n            with nogil:\n                status = pjsip_dlg_create_uac(pjsip_ua_instance(), &from_header_str.pj_str, &contact_str.pj_str,\n                                              &to_header_str.pj_str, &request_uri_str.pj_str, &self._dialog)\n            if status != 0:\n                raise PJSIPError(\"Could not create dialog for outgoing INVITE session\", status)\n\n            with nogil:\n                pjsip_dlg_inc_lock(self._dialog)\n\n            if contact_header.expires is not None:\n                self._dialog.local.contact.expires = contact_header.expires\n            if contact_header.q is not None:\n                self._dialog.local.contact.q1000 = int(contact_header.q*1000)\n            contact_parameters = contact_header.parameters.copy()\n            contact_parameters.pop(\"q\", None)\n            contact_parameters.pop(\"expires\", None)\n            _dict_to_pjsip_param(contact_parameters, &self._dialog.local.contact.other_param, self._dialog.pool)\n            _dict_to_pjsip_param(from_header_parameters, &self._dialog.local.info.other_param, self._dialog.pool)\n            _dict_to_pjsip_param(to_header_parameters, &self._dialog.remote.info.other_param, self._dialog.pool)\n            self.from_header = FrozenFromHeader_create(self._dialog.local.info)\n            self.to_header = FrozenToHeader.new(to_header)\n            self.call_id = _pj_str_to_str(self._dialog.call_id.id)\n            local_sdp = self.sdp.proposed_local.get_sdp_session() if sdp is not None else NULL\n            with nogil:\n                status = pjsip_inv_create_uac(self._dialog, local_sdp, 0, &self._invite_session)\n            if status != 0:\n                raise PJSIPError(\"Could not create outgoing INVITE session\", status)\n            self._invite_session.sdp_neg_flags = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE\n            self._invite_session.mod_data[ua._module.id] = <void *> self.weakref\n            if self.credentials is not None:\n                cred_info = self.credentials.get_cred_info()\n                with nogil:\n                    status = pjsip_auth_clt_set_credentials(&self._dialog.auth_sess, 1, cred_info)\n                if status != 0:\n                    raise PJSIPError(\"Could not set credentials for INVITE session\", status)\n            _BaseRouteHeader_to_pjsip_route_hdr(self.route_header, &self._route_header, self._dialog.pool)\n            pj_list_insert_after(<pj_list *> &self._route_set, <pj_list *> &self._route_header)\n            with nogil:\n                 status = pjsip_dlg_set_route_set(self._dialog, route_set)\n            if status != 0:\n                raise PJSIPError(\"Could not set route for INVITE session\", status)\n            with nogil:\n                status = pjsip_inv_invite(self._invite_session, &tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not create INVITE message\", status)\n            replaces_headers = [header for header in extra_headers if isinstance(header, BaseReplacesHeader)]\n            if len(replaces_headers) > 1:\n                raise SIPCoreError(\"Only one Replaces header is allowed\")\n            try:\n                replaces_header = replaces_headers[0]\n            except IndexError:\n                pass\n            else:\n                extra_headers.remove(replaces_header)\n                pj_replaces_hdr = pjsip_replaces_hdr_create(self._dialog.pool)\n                _str_to_pj_str(replaces_header.call_id, &pj_replaces_hdr.call_id)\n                _str_to_pj_str(replaces_header.to_tag, &pj_replaces_hdr.to_tag)\n                _str_to_pj_str(replaces_header.from_tag, &pj_replaces_hdr.from_tag)\n                _dict_to_pjsip_param(replaces_header.parameters, &pj_replaces_hdr.other_param, self._dialog.pool)\n                pjsip_msg_add_hdr(tdata.msg, <pjsip_hdr *>pj_replaces_hdr)\n            _add_headers_to_tdata(tdata, extra_headers)\n            with nogil:\n                status = pjsip_inv_send_msg(self._invite_session, tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not send initial INVITE\", status)\n            if timeout is not None:\n                self._timer = Timer()\n                self._timer.schedule(timeout, <timer_callback>self._cb_timer_disconnect, self)\n            with nogil:\n                pjsip_dlg_dec_lock(self._dialog)\n        except Exception, e:\n            if isinstance(e, PJSIPError) and e.errno == EADDRNOTAVAIL:\n                self._invite_session = NULL\n                pjsip_dlg_dec_lock(self._dialog)\n                self._dialog = NULL\n                raise\n\n            if self._invite_session != NULL:\n                pjsip_inv_terminate(self._invite_session, 500, 0)\n                self._invite_session = NULL\n            elif self._dialog != NULL:\n                pjsip_dlg_dec_lock(self._dialog)\n                self._dialog = NULL\n            raise\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def send_response(self, int code, str reason=None, BaseContactHeader contact_header=None, BaseSDPSession sdp=None, list extra_headers not None=list()):\n        cdef int status\n        cdef int clean_tdata = 0\n        cdef pj_mutex_t *lock = self._lock\n        cdef pj_str_t reason_str\n        cdef pjmedia_sdp_session_ptr_const lsdp = NULL\n        cdef pjmedia_sdp_session *local_sdp\n        cdef pjsip_inv_session *invite_session\n        cdef pjsip_msg_body *body\n        cdef pjsip_tx_data *tdata\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            invite_session = self._invite_session\n\n            if reason is not None:\n                _str_to_pj_str(reason, &reason_str)\n\n            if self.state not in (\"incoming\", \"early\", \"connected\"):\n                raise SIPCoreInvalidStateError('Can only send response from the \"incoming\", \"early\" and \"connected\" states current in the \"%s\" state.' % self.state)\n            if self.state == \"early\" and self.direction != \"incoming\":\n                raise SIPCoreInvalidStateError('Cannot send response in the \"early\" state for an outgoing INVITE')\n            if self.state == \"connected\" and self.sub_state not in (\"received_proposal\", \"received_proposal_request\"):\n                raise SIPCoreInvalidStateError('Cannot send response in the \"connected\" state if a proposal has not been received')\n\n            if contact_header is not None:\n                self._update_contact_header(contact_header)\n\n            if 200 <= code < 300 and sdp is None:\n                raise SIPCoreError(\"Local SDP needs to be set for a positive response\")\n            if code >= 300 and sdp is not None:\n                raise SIPCoreError(\"Local SDP cannot be specified for a negative response\")\n            self.sdp.proposed_local = FrozenSDPSession.new(sdp) if sdp is not None else None\n            local_sdp = self.sdp.proposed_local.get_sdp_session() if sdp is not None else NULL\n            if sdp is not None and self.sdp.proposed_remote is None:\n                # There was no remote proposal, this is a reply with an offer\n                with nogil:\n                    status = pjmedia_sdp_neg_modify_local_offer(self._dialog.pool, invite_session.neg, <pjmedia_sdp_session_ptr_const>local_sdp)\n                if status != 0:\n                    raise PJSIPError(\"Could not modify local SDP offer\", status)\n                # Retrieve the \"fixed\" offer from negotiator\n                pjmedia_sdp_neg_get_neg_local(invite_session.neg, &lsdp)\n                local_sdp = <pjmedia_sdp_session *>lsdp\n            with nogil:\n                status = pjsip_inv_answer(invite_session, code, &reason_str if reason is not None else NULL, local_sdp, &tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not create %d reply to INVITE\" % code, status)\n            _add_headers_to_tdata(tdata, extra_headers)\n            with nogil:\n                status = pjsip_inv_send_msg(invite_session, tdata)\n            if status != 0:\n                exc = PJSIPError(\"Could not send %d response\" % code, status)\n                if sdp is not None and self.sdp.proposed_remote is not None and exc.errno in (EADDRNOTAVAIL, ENETUNREACH):\n                    self._failed_response = 1\n                raise exc\n            self._failed_response = 0\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def send_reinvite(self, BaseContactHeader contact_header=None, BaseSDPSession sdp=None, list extra_headers not None=list()):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_sdp_session *local_sdp\n        cdef pjsip_inv_session *invite_session\n        cdef pjsip_tx_data *tdata\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            invite_session = self._invite_session\n\n            if self.state != \"connected\":\n                raise SIPCoreError('Can only send re-INVITE in \"connected\" state, not \"%s\" state' % self.state)\n            if self.sub_state != \"normal\":\n                raise SIPCoreError('Can only send re-INVITE if no another re-INVITE transaction is active')\n\n            if contact_header is not None:\n                self._update_contact_header(contact_header)\n\n            self.sdp.proposed_local = FrozenSDPSession.new(sdp) if sdp is not None else self.sdp.active_local\n            local_sdp = self.sdp.proposed_local.get_sdp_session()\n            with nogil:\n                status = pjsip_inv_reinvite(invite_session, NULL, local_sdp, &tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not create re-INVITE message\", status)\n            _add_headers_to_tdata(tdata, extra_headers)\n            with nogil:\n                status = pjsip_inv_send_msg(invite_session, tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not send re-INVITE\", status)\n            self._failed_response = 0\n            # TODO: use a callback tiner here instead?\n            self._reinvite_transaction = self._invite_session.invite_tsx\n            self.sub_state = \"sent_proposal\"\n            event_dict = dict(obj=self, prev_state=\"connected\", state=\"connected\", prev_sub_state=\"normal\", sub_state=\"sent_proposal\", originator=\"local\")\n            _pjsip_msg_to_dict(tdata.msg, event_dict)\n            _add_event(\"SIPInvitationChangedState\", event_dict)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def cancel_reinvite(self):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjsip_inv_session *invite_session\n        cdef pjsip_tx_data *tdata\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            invite_session = self._invite_session\n\n            if not self.sub_state == \"sent_proposal\":\n                raise SIPCoreError(\"re-INVITE can only be cancelled if INVITE session is in 'sent_proposal' sub state\")\n            if self._invite_session == NULL:\n                raise SIPCoreError(\"INVITE session is not active\")\n            if self._reinvite_transaction == NULL:\n                raise SIPCoreError(\"there is no active re-INVITE transaction\")\n\n            with nogil:\n                status = pjsip_inv_cancel_reinvite(invite_session, &tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not create message to CANCEL re-INVITE transaction\", status)\n            if tdata != NULL:\n                with nogil:\n                    status = pjsip_inv_send_msg(invite_session, tdata)\n                if status != 0:\n                    raise PJSIPError(\"Could not send %s\" % _pj_str_to_str(tdata.msg.line.req.method.name), status)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def transfer(self, SIPURI target_uri, object replaced_dialog_id=None, list extra_headers not None=list()):\n        global _refer_event\n        global _refer_method\n        cdef int status\n        cdef PJSIPUA ua\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjsip_method refer_method\n        cdef pjsip_tx_data *tdata\n        cdef dict tdata_dict = dict(obj=self)\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self.state != \"connected\":\n                raise SIPCoreError('Can only start transfer in \"connected\" state, not \"%s\" state' % self.state)\n            if self._transfer_usage != NULL:\n                raise SIPCoreError('Another transfer is in progress')\n            with nogil:\n                status = pjsip_evsub_create_uac(self._dialog, &_transfer_cb, &_refer_event.pj_str, PJSIP_EVSUB_NO_EVENT_ID, &self._transfer_usage)\n            if status != 0:\n                raise PJSIPError(\"Could not create REFER\", status)\n            self._transfer_usage_role = PJSIP_ROLE_UAC\n            pjsip_evsub_set_mod_data(self._transfer_usage, ua._event_module.id, <void *> self.weakref)\n            pjsip_method_init_np(&refer_method, &_refer_method.pj_str)\n            with nogil:\n                status = pjsip_evsub_initiate(self._transfer_usage, &refer_method, -1, &tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not create REFER message\", status)\n            if replaced_dialog_id is not None and None not in replaced_dialog_id:\n                target_uri.headers[\"Replaces\"] = \"%s;from-tag=%s;to-tag=%s\" % replaced_dialog_id\n            refer_to_header = ReferToHeader(str(target_uri))\n            _add_headers_to_tdata(tdata, [refer_to_header, Header('Referred-By', str(self.local_identity.uri))])\n            _add_headers_to_tdata(tdata, extra_headers)\n            # We can't remove the Event header or PJSIP will fail to match responses to this request\n            _remove_headers_from_tdata(tdata, [\"Expires\"])\n            with nogil:\n                status = pjsip_evsub_send_request(self._transfer_usage, tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not send REFER message\", status)\n            _pjsip_msg_to_dict(tdata.msg, tdata_dict)\n            _add_event(\"SIPInvitationTransferNewOutgoing\", tdata_dict)\n            self._transfer_timeout_timer = Timer()\n            self._transfer_timeout_timer.schedule(90, <timer_callback>self._transfer_cb_timeout_timer, self)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def notify_transfer_progress(self, int code, str reason=None):\n        cdef int status\n        cdef PJSIPUA ua\n        cdef pj_mutex_t *lock = self._lock\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._transfer_usage == NULL:\n                raise SIPCoreError(\"No transfer is in progress\")\n            if self._transfer_usage_role != PJSIP_ROLE_UAS:\n                raise SIPCoreError(\"Transfer progress can only be notified by the transfer UAS\")\n            self._set_sipfrag_payload(code, reason)\n            if 200 <= code < 700:\n                self._terminate_transfer_uas()\n            else:\n                self._send_notify()\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def end(self, list extra_headers not None=list(), timeout=None):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjsip_inv_session *invite_session\n        cdef pjsip_tx_data *tdata\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            invite_session = self._invite_session\n\n            if self.state == \"disconnected\":\n                return\n            if self.state == \"disconnecting\":\n                raise SIPCoreError('INVITE session is already in the \"disconnecting\" state')\n            if self._invite_session == NULL:\n                raise SIPCoreError(\"INVITE session is not active\")\n            if self.state not in (\"outgoing\", \"early\", \"connecting\", \"connected\"):\n                raise SIPCoreError('Can only end the INVITE dialog from the \"outgoing\", \"early\", \"connecting\" and \"connected\" states' +\n                                   'current in the \"%s\" state.' % self.state)\n            if self.state == \"early\" and self.direction != \"outgoing\":\n                raise SIPCoreError('Cannot end incoming INVITE dialog while in the \"early\" state')\n            if timeout is not None and timeout <= 0:\n                raise ValueError(\"Timeout value cannot be negative\")\n\n            # End ongoing transfer\n            self._terminate_transfer()\n\n            with nogil:\n                status = pjsip_inv_end_session(invite_session, 0, NULL, &tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not create message to end INVITE session\", status)\n            if tdata != NULL:\n                _add_headers_to_tdata(tdata, extra_headers)\n                with nogil:\n                    status = pjsip_inv_send_msg(invite_session, tdata)\n                if status != 0:\n                    raise PJSIPError(\"Could not send %s\" % _pj_str_to_str(tdata.msg.line.req.method.name), status)\n\n            if self._timer is not None:\n                self._timer.cancel()\n                self._timer = None\n            if timeout is not None and timeout > 0:\n                self._timer = Timer()\n                self._timer.schedule(timeout, <timer_callback>self._cb_timer_disconnect, self)\n\n            event_dict = dict(obj=self, prev_state=self.state, state=\"disconnecting\", originator=\"local\")\n            if self.state == \"connected\":\n                event_dict[\"prev_sub_state\"] = self.sub_state\n            self.state = \"disconnecting\"\n            self.sub_state = None\n            if tdata != NULL:\n                _pjsip_msg_to_dict(tdata.msg, event_dict)\n            _add_event(\"SIPInvitationChangedState\", event_dict)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    property local_identity:\n\n        def __get__(self):\n            if self.direction == 'outgoing':\n                return self.from_header\n            elif self.direction == 'incoming':\n                return self.to_header\n            else:\n                return None\n\n    property remote_identity:\n\n        def __get__(self):\n            if self.direction == 'incoming':\n                return self.from_header\n            elif self.direction == 'outgoing':\n                return self.to_header\n            else:\n                return None\n\n    property dialog_id:\n\n        def __get__(self):\n            local_tag = remote_tag = None\n            if self.local_identity is not None:\n                local_tag = self.local_identity.tag\n            if self.remote_identity is not None:\n                remote_tag = self.remote_identity.tag\n            return DialogID(self.call_id, local_tag, remote_tag)\n\n    cdef PJSIPUA _check_ua(self):\n        try:\n            return _get_ua()\n        except:\n            self.state = \"disconnected\"\n            self.sub_state = None\n            self._dialog = NULL\n            self._invite_session = NULL\n            self._reinvite_transaction = NULL\n\n    cdef int _do_dealloc(self) except -1:\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjsip_inv_session *invite_session\n        cdef PJSIPUA ua\n\n        try:\n            ua = _get_ua()\n        except SIPCoreError:\n            return 0\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            invite_session = self._invite_session\n\n            if self._invite_session != NULL:\n                self._invite_session.mod_data[ua._module.id] = NULL\n                if self.state != \"disconnecting\":\n                    with nogil:\n                        pjsip_inv_terminate(invite_session, 481, 0)\n                self._dialog = NULL\n                self._invite_session = NULL\n                self._reinvite_transaction = NULL\n            if self._timer is not None:\n                self._timer.cancel()\n                self._timer = None\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n        return 0\n\n    def __dealloc__(self):\n        cdef Timer timer\n\n        self._do_dealloc()\n        if self._lock != NULL:\n            pj_mutex_destroy(self._lock)\n\n        timer = Timer()\n        try:\n            timer.schedule(60, deallocate_weakref, self.weakref)\n        except SIPCoreError:\n            pass\n\n    cdef int _update_contact_header(self, BaseContactHeader contact_header) except -1:\n        # The PJSIP functions called here don't do much, so there is no need to call them\n        # without the gil.\n        cdef pj_str_t contact_str_pj\n        cdef pjsip_uri *contact\n\n        contact_str = str(contact_header.uri)\n        if contact_header.display_name:\n            contact_str = \"%s <%s>\" % (contact_header.display_name.encode('utf-8'), contact_str)\n        pj_strdup2_with_null(self._dialog.pool, &contact_str_pj, contact_str)\n        contact = pjsip_parse_uri(self._dialog.pool, contact_str_pj.ptr, contact_str_pj.slen, PJSIP_PARSE_URI_AS_NAMEADDR)\n        if contact == NULL:\n            raise SIPCoreError(\"Not a valid Contact header: %s\" % contact_str)\n        self._dialog.local.contact = pjsip_contact_hdr_create(self._dialog.pool)\n        self._dialog.local.contact.uri = contact\n        if contact_header.expires is not None:\n            self._dialog.local.contact.expires = contact_header.expires\n        if contact_header.q is not None:\n            self._dialog.local.contact.q1000 = int(contact_header.q*1000)\n        parameters = contact_header.parameters.copy()\n        parameters.pop(\"q\", None)\n        parameters.pop(\"expires\", None)\n        _dict_to_pjsip_param(parameters, &self._dialog.local.contact.other_param, self._dialog.pool)\n        self.local_contact_header = FrozenContactHeader.new(contact_header)\n        return 0\n\n    cdef int _fail(self, PJSIPUA ua) except -1:\n        cdef Timer timer\n        ua._handle_exception(0)\n        if self._transfer_usage != NULL:\n            with nogil:\n                pjsip_evsub_terminate(self._transfer_usage, 0)\n            pjsip_evsub_set_mod_data(self._transfer_usage, ua._event_module.id, NULL)\n            if self._transfer_timeout_timer is not None:\n                self._transfer_timeout_timer.cancel()\n                self._transfer_timeout_timer = None\n            if self._transfer_refresh_timer is not None:\n                self._transfer_refresh_timer.cancel()\n                self._transfer_refresh_timer = None\n            self._transfer_usage = NULL\n            _add_event(\"SIPInvitationTransferDidFail\", dict(obj=self, code=0, reason=\"internal error\"))\n        self._invite_session.mod_data[ua._module.id] = NULL\n        if self.state != \"disconnected\":\n            event_dict = dict(obj=self, prev_state=self.state, state=\"disconnected\", originator=\"local\", code=0, reason=\"internal error\", disconnect_reason=\"internal error\")\n            if self.state == \"connected\":\n                event_dict[\"prev_sub_state\"] = self.sub_state\n            self.state = \"disconnected\"\n            self.sub_state = None\n            _add_event(\"SIPInvitationChangedState\", event_dict)\n        # calling do_dealloc from within a callback makes PJSIP crash\n        # the handler will be executed after pjsip_endpt_handle_events returns\n        timer = Timer()\n        timer.schedule(0, <timer_callback>self._cb_postpoll_fail, self)\n        return 0\n\n    cdef int _cb_state(self, StateCallbackTimer timer) except -1:\n        cdef int status\n        cdef bint pjsip_error = False\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_sdp_session_ptr_const sdp\n        cdef pjsip_inv_session *invite_session\n        cdef object state\n        cdef object sub_state\n        cdef object rdata\n        cdef object tdata\n        cdef object originator\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n        if ua is None:\n            return 0\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            invite_session = self._invite_session\n            state = timer.state\n            sub_state = timer.sub_state\n            rdata = timer.rdata\n            tdata = timer.tdata\n            originator = timer.originator\n\n            if state != \"early\" and state == self.state and sub_state == self.sub_state:\n                return 0\n\n            if state == \"connected\":\n                if self.state == \"connecting\" and self._sdp_neg_status != 0:\n                    self.end()\n                    return 0\n\n            if state == \"disconnected\" and self.state != \"disconnecting\":\n                # the invite session may have been destroyed if it failed\n                if not self._invite_session:\n                    return 0\n                # we either sent a cancel or a negative reply to an incoming INVITE\n                if self._invite_session.cancelling or (self.state in (\"incoming\", \"early\") and self.direction == \"incoming\" and rdata is None):\n                    # we caused the disconnect so send the transition to the disconnecting state\n                    pjsip_error = True\n                    event_dict = dict(obj=self, prev_state=self.state, state=\"disconnecting\", originator=\"local\")\n                    self.state = \"disconnecting\"\n                    _add_event(\"SIPInvitationChangedState\", event_dict)\n\n            if self.direction == \"outgoing\" and state in ('connecting', 'connected') and self.state in ('outgoing', 'early') and rdata is not None:\n                self.to_header = rdata['headers']['To']\n\n            if self.direction == \"incoming\" and state in ('connecting', 'connected') and self.state in ('incoming', 'early') and tdata is not None:\n                self.to_header = tdata['headers']['To']\n\n            event_dict = dict(obj=self, prev_state=self.state, state=state)\n            if self.state == \"connected\":\n                event_dict[\"prev_sub_state\"] = self.sub_state\n            if state == \"connected\":\n                event_dict[\"sub_state\"] = sub_state\n            event_dict[\"originator\"] = originator\n            if rdata is not None:\n                event_dict.update(rdata)\n            if tdata is not None:\n                event_dict.update(tdata)\n            if rdata is None and tdata is None:\n                event_dict['headers'] = dict()\n                event_dict['body'] = None\n\n            if self.remote_user_agent is None and state in ('connecting', 'connected') and rdata is not None:\n                if 'User-Agent' in event_dict['headers']:\n                    self.remote_user_agent = event_dict['headers']['User-Agent'].body\n                elif 'Server' in event_dict['headers']:\n                    self.remote_user_agent = event_dict['headers']['Server'].body\n\n            if state not in ('disconnecting', 'disconnected') and rdata is not None:\n                try:\n                    self.remote_contact_header = event_dict['headers']['Contact'][0]\n                except LookupError:\n                    pass\n\n            if state == \"connected\":\n                if sub_state == \"received_proposal\":\n                    self._reinvite_transaction = self._invite_session.invite_tsx\n                    if pjmedia_sdp_neg_get_state(self._invite_session.neg) == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER:\n                        pjmedia_sdp_neg_get_neg_remote(self._invite_session.neg, &sdp)\n                        self.sdp.proposed_remote = FrozenSDPSession_create(sdp)\n                elif sub_state == \"sent_proposal\":\n                    if pjmedia_sdp_neg_get_state(self._invite_session.neg) == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER:\n                        pjmedia_sdp_neg_get_neg_local(self._invite_session.neg, &sdp)\n                        self.sdp.proposed_local = FrozenSDPSession_create(sdp)\n                elif sub_state == \"received_proposal_request\":\n                    self._reinvite_transaction = self._invite_session.invite_tsx\n                    if pjmedia_sdp_neg_get_state(self._invite_session.neg) == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER:\n                        pjmedia_sdp_neg_get_neg_local(self._invite_session.neg, &sdp)\n                        self.sdp.proposed_local = FrozenSDPSession_create(sdp)\n                elif self.sub_state in (\"received_proposal\", \"sent_proposal\", \"received_proposal_request\"):\n                    if (rdata, tdata) == (None, None):\n                        event_dict['code'] = 408\n                        event_dict['reason'] = 'Request Timeout'\n                    if pjmedia_sdp_neg_get_state(self._invite_session.neg) in (PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER):\n                        pjmedia_sdp_neg_cancel_offer(self._invite_session.neg)\n                    self._reinvite_transaction = NULL\n            if state == \"disconnected\":\n                event_dict[\"disconnect_reason\"] = \"user request\" if not pjsip_error else \"internal error\"\n                event_dict[\"code\"] = self._invite_session.cause\n                if self._invite_session.cause > 0:\n                    event_dict[\"reason\"] = _pj_str_to_str(self._invite_session.cause_text)\n                else:\n                    event_dict[\"reason\"] = \"\"\n                if not self._invite_session.cancelling and rdata is None and self._invite_session.cause > 0:\n                    # pjsip internally generates 408 and 503\n                    if self._invite_session.cause == 408:\n                        if self.direction == \"incoming\" and self.state == \"connecting\":\n                            event_dict[\"disconnect_reason\"] = \"missing ACK\"\n                        else:\n                            event_dict[\"disconnect_reason\"] = \"timeout\"\n                    else:\n                        event_dict[\"disconnect_reason\"] = _pj_str_to_str(self._invite_session.cause_text)\n                elif self._invite_session.cancelling and rdata is None and self._invite_session.cause == 408 and self.state == \"disconnecting\":\n                    # silly pjsip sets cancelling field when we call pjsip_inv_end_session in end even if we send a BYE\n                    event_dict[\"disconnect_reason\"] = \"timeout\"\n                elif rdata is not None and 'Reason' in event_dict['headers']:\n                    try:\n                        reason = event_dict['headers']['Reason'].text\n                        if reason:\n                            event_dict[\"disconnect_reason\"] = reason\n                    except (ValueError, IndexError):\n                        pass\n                if self._transfer_usage != NULL:\n                    with nogil:\n                        pjsip_evsub_terminate(self._transfer_usage, 0)\n                    pjsip_evsub_set_mod_data(self._transfer_usage, ua._event_module.id, NULL)\n                    if self._transfer_timeout_timer is not None:\n                        self._transfer_timeout_timer.cancel()\n                        self._transfer_timeout_timer = None\n                    if self._transfer_refresh_timer is not None:\n                        self._transfer_refresh_timer.cancel()\n                        self._transfer_refresh_timer = None\n                    self._transfer_usage = NULL\n                    _add_event(\"SIPInvitationTransferDidFail\", dict(obj=self, code=0, reason=\"invite dialog ended\"))\n                self._invite_session.mod_data[ua._module.id] = NULL\n                self._invite_session = NULL\n                self._dialog = NULL\n                if self._timer is not None:\n                    self._timer.cancel()\n                    self._timer = None\n            elif state in (\"early\", \"connecting\") and self._timer is not None:\n                self._timer.cancel()\n                self._timer = None\n            self.state = state\n            self.sub_state = sub_state\n            _add_event(\"SIPInvitationChangedState\", event_dict)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n        return 0\n\n    cdef int _cb_sdp_done(self, SDPCallbackTimer timer) except -1:\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._failed_response == 1:\n                return 0\n            self._sdp_neg_status = timer.status\n            self.sdp.proposed_local = None\n            self.sdp.proposed_remote = None\n            if timer.status == 0:\n                self.sdp.active_local = timer.active_local\n                self.sdp.active_remote = timer.active_remote\n            if self.state in [\"disconnecting\", \"disconnected\"]:\n                return 0\n            event_dict = dict(obj=self, succeeded=timer.status == 0)\n            if timer.status == 0:\n                event_dict[\"local_sdp\"] = self.sdp.active_local\n                event_dict[\"remote_sdp\"] = self.sdp.active_remote\n            else:\n                event_dict[\"error\"] = _pj_status_to_str(timer.status)\n            _add_event(\"SIPInvitationGotSDPUpdate\", event_dict)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n        return 0\n\n    cdef int _cb_timer_disconnect(self, timer) except -1:\n        cdef pjsip_inv_session *invite_session = self._invite_session\n        with nogil:\n            pjsip_inv_terminate(invite_session, 408, 1)\n\n    cdef int _cb_postpoll_fail(self, timer) except -1:\n        self._do_dealloc()\n\n    cdef int _start_incoming_transfer(self, timer) except -1:\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n        if ua is None:\n            return 0\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            self._set_sipfrag_payload(100, \"Trying\")\n            self._send_notify()\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n        return 0\n\n    cdef int _terminate_transfer(self) except -1:\n        if self._transfer_usage == NULL:\n            return 0\n        if self._transfer_usage_role == PJSIP_ROLE_UAC:\n            self._terminate_transfer_uac()\n        else:\n            self._terminate_transfer_uas()\n\n    cdef int _terminate_transfer_uac(self) except -1:\n        cdef pjsip_tx_data *tdata\n        cdef int status\n        cdef TransferStateCallbackTimer state_timer\n        try:\n            with nogil:\n                status = pjsip_evsub_initiate(self._transfer_usage, NULL, 0, &tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not create SUBSCRIBE message\", status)\n            with nogil:\n                status = pjsip_evsub_send_request(self._transfer_usage, tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not send SUBSCRIBE message\", status)\n            if self._transfer_timeout_timer is not None:\n                self._transfer_timeout_timer.cancel()\n                self._transfer_timeout_timer = None\n            if self._transfer_refresh_timer is not None:\n                self._transfer_refresh_timer.cancel()\n                self._transfer_refresh_timer = None\n            self._transfer_timeout_timer = Timer()\n            self._transfer_timeout_timer.schedule(1, <timer_callback>self._transfer_cb_timeout_timer, self)\n        except PJSIPError, e:\n            if self._transfer_usage != NULL:\n                code = 0\n                reason = e.args[0]\n                with nogil:\n                    pjsip_evsub_terminate(self._transfer_usage, 0)\n                # Manually trigger the state callback since we handle the timeout ourselves\n                state_timer = TransferStateCallbackTimer(\"TERMINATED\", code, reason)\n                state_timer.schedule(0, <timer_callback>self._transfer_cb_state, self)\n\n    cdef int _terminate_transfer_uas(self) except -1:\n        global sipfrag_re\n        cdef int code\n        cdef TransferStateCallbackTimer state_timer\n        if self.transfer_state == \"TERMINATED\":\n            return 0\n        self._set_transfer_state(\"TERMINATED\")\n        self._send_notify()\n        with nogil:\n            pjsip_evsub_terminate(self._transfer_usage, 0)\n        match = sipfrag_re.match(self._sipfrag_payload.str)\n        code = int(match.group('code'))\n        reason = match.group('reason')\n        state_timer = TransferStateCallbackTimer(\"TERMINATED\", code, reason)\n        state_timer.schedule(0, <timer_callback>self._transfer_cb_state, self)\n\n    cdef int _set_transfer_state(self, str state) except -1:\n        cdef str prev_state\n        prev_state = self.transfer_state\n        self.transfer_state = state\n        if prev_state != state:\n            _add_event(\"SIPInvitationTransferChangedState\", dict(obj=self, prev_state=prev_state, state=state))\n\n    cdef int _set_sipfrag_payload(self, int code, str status) except -1:\n        cdef str content\n        if status is None:\n            try:\n                status = sip_status_messages[code]\n            except IndexError:\n                status = \"Unknown\"\n        content = \"SIP/2.0 %d %s\\r\\n\" % (code, status)\n        self._sipfrag_payload = PJSTR(content)\n\n    cdef int _send_notify(self) except -1:\n        cdef pjsip_evsub_state state\n        cdef pj_str_t *reason_p = NULL\n        cdef pjsip_tx_data *tdata\n        cdef int status\n        cdef dict _sipfrag_version = dict(version=\"2.0\")\n        cdef PJSTR _content_type = PJSTR(\"message\")\n        cdef PJSTR _content_subtype = PJSTR(\"sipfrag\")\n        cdef PJSTR noresource = PJSTR(\"noresource\")\n        cdef PJSTR content\n\n        if self.transfer_state == \"ACTIVE\":\n            state = PJSIP_EVSUB_STATE_ACTIVE\n        else:\n            state = PJSIP_EVSUB_STATE_TERMINATED\n            reason_p = &noresource.pj_str\n        with nogil:\n            status = pjsip_evsub_notify(self._transfer_usage, state, NULL, reason_p, &tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not create NOTIFY request\", status)\n        if self.transfer_state in (\"ACTIVE\", \"TERMINATED\"):\n            tdata.msg.body = pjsip_msg_body_create(tdata.pool, &_content_type.pj_str, &_content_subtype.pj_str, &self._sipfrag_payload.pj_str)\n            _dict_to_pjsip_param(_sipfrag_version, &tdata.msg.body.content_type.param, tdata.pool)\n        with nogil:\n            status = pjsip_evsub_send_request(self._transfer_usage, tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not send NOTIFY request\", status)\n        return 0\n\n    cdef int _transfer_cb_timeout_timer(self, timer) except -1:\n        global sip_status_messages\n        cdef int code\n        cdef str reason\n        cdef int status\n        cdef TransferStateCallbackTimer state_timer\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n        if ua is None:\n            return 0\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._transfer_usage != NULL:\n                code = PJSIP_SC_TSX_TIMEOUT\n                reason = sip_status_messages[PJSIP_SC_TSX_TIMEOUT]\n                with nogil:\n                    pjsip_evsub_terminate(self._transfer_usage, 0)\n                # Manually trigger the state callback since we handle the timeout ourselves\n                state_timer = TransferStateCallbackTimer(\"TERMINATED\", code, reason)\n                state_timer.schedule(0, <timer_callback>self._transfer_cb_state, self)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n        return 0\n\n    cdef int _transfer_cb_refresh_timer(self, timer) except -1:\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n        if ua is None:\n            return 0\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            self._terminate_transfer()\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n        return 0\n\n    cdef int _transfer_cb_state(self, TransferStateCallbackTimer timer) except -1:\n        cdef int status\n        cdef str prev_state\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n        if ua is None:\n            return 0\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            prev_state = self.transfer_state\n            self._set_transfer_state(timer.state)\n            if timer.state == \"ACCEPTED\" and prev_state == \"SENT\":\n                _add_event(\"SIPInvitationTransferDidStart\", dict(obj=self))\n            elif timer.state == \"TERMINATED\":\n                # If a NOTIFY is rejected with 408 or 481 PJSIP will erase the subscription\n                if self._transfer_usage != NULL:\n                    pjsip_evsub_set_mod_data(self._transfer_usage, ua._event_module.id, NULL)\n                if self._transfer_timeout_timer is not None:\n                    self._transfer_timeout_timer.cancel()\n                    self._transfer_timeout_timer = None\n                if self._transfer_refresh_timer is not None:\n                    self._transfer_refresh_timer.cancel()\n                    self._transfer_refresh_timer = None\n                self._transfer_usage = NULL\n                if timer.code/100 == 2:\n                    _add_event(\"SIPInvitationTransferDidEnd\", dict(obj=self))\n                else:\n                    _add_event(\"SIPInvitationTransferDidFail\", dict(obj=self, code=timer.code, reason=timer.reason))\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n        return 0\n\n    cdef int _transfer_cb_response(self, TransferResponseCallbackTimer timer) except -1:\n        cdef int expires\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n        if ua is None:\n            return 0\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._transfer_timeout_timer is not None:\n                self._transfer_timeout_timer.cancel()\n                self._transfer_timeout_timer = None\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n        return 0\n\n    cdef int _transfer_cb_notify(self, TransferRequestCallbackTimer timer) except -1:\n        cdef pj_time_val refresh\n        cdef int expires\n        cdef dict notify_dict = dict(obj=self)\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n        if ua is None:\n            return 0\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            sub_state_hdr = timer.rdata[\"headers\"].get(\"Subscription-State\", None)\n            if self.transfer_state != \"TERMINATED\" and sub_state_hdr is not None and sub_state_hdr.expires > 0:\n                if self._transfer_refresh_timer is not None:\n                    self._transfer_refresh_timer.cancel()\n                    self._transfer_refresh_timer = None\n                expires = max(1, sub_state_hdr.expires - self.expire_warning_time, sub_state_hdr.expires/2)\n                self._transfer_refresh_timer = Timer()\n                self._transfer_refresh_timer.schedule(expires, <timer_callback>self._transfer_cb_refresh_timer, self)\n            notify_dict[\"request_uri\"] = timer.rdata[\"request_uri\"]\n            notify_dict[\"from_header\"] = timer.rdata[\"headers\"].get(\"From\", None)\n            notify_dict[\"to_header\"] = timer.rdata[\"headers\"].get(\"To\", None)\n            notify_dict[\"headers\"] = timer.rdata[\"headers\"]\n            notify_dict[\"body\"] = timer.rdata[\"body\"]\n            content_type = notify_dict[\"headers\"].get(\"Content-Type\", None)\n            notify_dict[\"content_type\"] = content_type.content_type if content_type else None\n            event = notify_dict[\"headers\"].get(\"Event\", None)\n            notify_dict[\"event\"] = event.event if event else None\n            _add_event(\"SIPInvitationTransferGotNotify\", notify_dict)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n        return 0\n\n    cdef int _transfer_cb_server_timeout(self, timer) except -1:\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n        if ua is None:\n            return 0\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            self._terminate_transfer()\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n        return 0\n\n\n# Callback functions\n#\n\ncdef void _Invitation_cb_state(pjsip_inv_session *inv, pjsip_event *e) with gil:\n    cdef pjsip_rx_data *rdata = NULL\n    cdef pjsip_tx_data *tdata = NULL\n    cdef object state\n    cdef object rdata_dict = None\n    cdef object tdata_dict = None\n    cdef object originator = None\n    cdef Invitation invitation\n    cdef PJSIPUA ua\n    cdef StateCallbackTimer timer\n\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        if inv.state == PJSIP_INV_STATE_INCOMING:\n            return\n        if inv.mod_data[ua._module.id] != NULL:\n            invitation = (<object> inv.mod_data[ua._module.id])()\n            if invitation is None:\n                return\n            state = pjsip_inv_state_name(inv.state).lower()\n            sub_state = None\n            if state == \"calling\":\n                state = \"outgoing\"\n            elif state == \"confirmed\":\n                state = \"connected\"\n                sub_state = \"normal\"\n            elif state == \"disconnctd\":\n                state = \"disconnected\"\n            if e != NULL:\n                if e.type == PJSIP_EVENT_TSX_STATE and e.body.tsx_state.type == PJSIP_EVENT_TX_MSG:\n                    tdata = e.body.tsx_state.src.tdata\n                    if (tdata.msg.type == PJSIP_RESPONSE_MSG and tdata.msg.line.status.code == 487 and\n                        state == \"disconnected\" and invitation.state in [\"incoming\", \"early\"]):\n                        return\n                elif e.type == PJSIP_EVENT_RX_MSG:\n                    rdata = e.body.rx_msg.rdata\n                elif e.type == PJSIP_EVENT_TSX_STATE and e.body.tsx_state.type == PJSIP_EVENT_RX_MSG:\n                    if (inv.state != PJSIP_INV_STATE_CONFIRMED or\n                        e.body.tsx_state.src.rdata.msg_info.msg.type == PJSIP_REQUEST_MSG):\n                        rdata = e.body.tsx_state.src.rdata\n                elif e.type == PJSIP_EVENT_TSX_STATE and e.body.tsx_state.type == PJSIP_EVENT_TRANSPORT_ERROR and e.body.tsx_state.tsx.role == PJSIP_ROLE_UAC:\n                    # A transport error occurred, fake a local reply\n                    rdata_dict = dict()\n                    rdata_dict[\"code\"] = 408\n                    rdata_dict[\"reason\"] = \"Transport Error\"\n                    rdata_dict[\"headers\"] = dict()\n                    rdata_dict[\"body\"] = None\n                    originator = \"local\"\n            if rdata != NULL:\n                if invitation.peer_address is None:\n                    invitation.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n                else:\n                    invitation.peer_address.ip = rdata.pkt_info.src_name\n                    invitation.peer_address.port = rdata.pkt_info.src_port\n                rdata_dict = dict()\n                _pjsip_msg_to_dict(rdata.msg_info.msg, rdata_dict)\n                originator = \"remote\"\n            if tdata != NULL:\n                tdata_dict = dict()\n                _pjsip_msg_to_dict(tdata.msg, tdata_dict)\n                originator = \"local\"\n            try:\n                timer = StateCallbackTimer(state, sub_state, rdata_dict, tdata_dict, originator)\n                timer.schedule(0, <timer_callback>invitation._cb_state, invitation)\n            except:\n                invitation._fail(ua)\n    except:\n        ua._handle_exception(1)\n\ncdef void _Invitation_cb_sdp_done(pjsip_inv_session *inv, int status) with gil:\n    cdef Invitation invitation\n    cdef PJSIPUA ua\n    cdef SDPCallbackTimer timer\n    cdef pjmedia_sdp_session_ptr_const sdp\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        if inv.mod_data[ua._module.id] != NULL:\n            invitation = (<object> inv.mod_data[ua._module.id])()\n            if invitation is None:\n                return\n            if status == 0:\n                if pjmedia_sdp_neg_get_active_local(invitation._invite_session.neg, &sdp) == 0:\n                    local_sdp = SDPSession_create(sdp)\n                else:\n                    local_sdp = None\n                if pjmedia_sdp_neg_get_active_remote(invitation._invite_session.neg, &sdp) == 0:\n                    remote_sdp = SDPSession_create(sdp)\n                else:\n                    remote_sdp = None\n                if local_sdp is None or remote_sdp is None:\n                    active_local = None\n                    active_remote = None\n                else:\n                    if len(local_sdp.media) > len(remote_sdp.media):\n                        local_sdp.media = local_sdp.media[:len(remote_sdp.media)]\n                    if len(remote_sdp.media) > len(local_sdp.media):\n                        remote_sdp.media = remote_sdp.media[:len(local_sdp.media)]\n                    for index, local_media in enumerate(local_sdp.media):\n                        remote_media = remote_sdp.media[index]\n                        if not local_media.port and remote_media.port:\n                            remote_media.port = 0\n                        if not remote_media.port and local_media.port:\n                            local_media.port = 0\n                    active_local = FrozenSDPSession.new(local_sdp)\n                    active_remote = FrozenSDPSession.new(remote_sdp)\n            else:\n                active_local = None\n                active_remote = None\n            try:\n                timer = SDPCallbackTimer(status, active_local, active_remote)\n                timer.schedule(0, <timer_callback>invitation._cb_sdp_done, invitation)\n            except:\n                invitation._fail(ua)\n    except:\n        ua._handle_exception(1)\n\ncdef int _Invitation_cb_rx_reinvite(pjsip_inv_session *inv, pjmedia_sdp_session_ptr_const offer, pjsip_rx_data *rdata) with gil:\n    cdef int status\n    cdef pjsip_tx_data *answer_tdata\n    cdef object rdata_dict = None\n    cdef Invitation invitation\n    cdef PJSIPUA ua\n    cdef StateCallbackTimer timer\n    try:\n        ua = _get_ua()\n    except:\n        return 1\n    try:\n        if inv.mod_data[ua._module.id] != NULL:\n            invitation = (<object> inv.mod_data[ua._module.id])()\n            if invitation is None:\n                return 1\n            if invitation.peer_address is None:\n                invitation.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n            else:\n                invitation.peer_address.ip = rdata.pkt_info.src_name\n                invitation.peer_address.port = rdata.pkt_info.src_port\n            rdata_dict = dict()\n            _pjsip_msg_to_dict(rdata.msg_info.msg, rdata_dict)\n            with nogil:\n                status = pjsip_inv_initial_answer(inv, rdata, 100, NULL, NULL, &answer_tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not create initial (unused) response to re-INVITE\", status)\n            with nogil:\n                pjsip_tx_data_dec_ref(answer_tdata)\n            if offer != NULL:\n                sub_state = \"received_proposal\"\n            else:\n                sub_state = \"received_proposal_request\"\n            try:\n                timer = StateCallbackTimer(\"connected\", sub_state, rdata_dict, None, \"remote\")\n                timer.schedule(0, <timer_callback>invitation._cb_state, invitation)\n            except:\n                invitation._fail(ua)\n                return 1\n            return 0\n    except:\n        ua._handle_exception(1)\n        return 1\n\ncdef void _Invitation_cb_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e) with gil:\n    cdef pjsip_rx_data *rdata = NULL\n    cdef pjsip_tx_data *tdata = NULL\n    cdef object rdata_dict = None\n    cdef object tdata_dict = None\n    cdef object originator = None\n    cdef Invitation invitation\n    cdef PJSIPUA ua\n    cdef StateCallbackTimer timer\n    cdef TransferRequestCallbackTimer transfer_timer\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        if tsx == NULL or e == NULL:\n            return\n        if e.type == PJSIP_EVENT_TSX_STATE and e.body.tsx_state.type == PJSIP_EVENT_RX_MSG:\n            rdata = e.body.tsx_state.src.rdata\n        if e.type == PJSIP_EVENT_TSX_STATE and e.body.tsx_state.type == PJSIP_EVENT_TX_MSG:\n            tdata = e.body.tsx_state.src.tdata\n        if inv.mod_data[ua._module.id] != NULL:\n            invitation = (<object> inv.mod_data[ua._module.id])()\n            if invitation is None:\n                return\n            if rdata != NULL:\n                if invitation.peer_address is None:\n                    invitation.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n                else:\n                    invitation.peer_address.ip = rdata.pkt_info.src_name\n                    invitation.peer_address.port = rdata.pkt_info.src_port\n            if ((tsx.state == PJSIP_TSX_STATE_TERMINATED or tsx.state == PJSIP_TSX_STATE_COMPLETED) and\n                (inv.neg != NULL and pjmedia_sdp_neg_get_state(inv.neg) in (PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER, PJMEDIA_SDP_NEG_STATE_DONE)) and\n                invitation._reinvite_transaction != NULL and invitation._reinvite_transaction == tsx):\n                if rdata != NULL:\n                    rdata_dict = dict()\n                    _pjsip_msg_to_dict(rdata.msg_info.msg, rdata_dict)\n                    originator = \"remote\"\n                if tdata != NULL:\n                    tdata_dict = dict()\n                    _pjsip_msg_to_dict(tdata.msg, tdata_dict)\n                    originator = \"local\"\n                try:\n                    timer = StateCallbackTimer(\"connected\", \"normal\", rdata_dict, tdata_dict, originator)\n                    timer.schedule(0, <timer_callback>invitation._cb_state, invitation)\n                except:\n                    invitation._fail(ua)\n            elif (invitation.state in (\"incoming\", \"early\") and invitation.direction == \"incoming\" and\n                  rdata != NULL and rdata.msg_info.msg.type == PJSIP_REQUEST_MSG and\n                  rdata.msg_info.msg.line.req.method.id == PJSIP_CANCEL_METHOD):\n                rdata_dict = dict()\n                _pjsip_msg_to_dict(rdata.msg_info.msg, rdata_dict)\n                originator = \"remote\"\n                try:\n                    timer = StateCallbackTimer(\"disconnected\", None, rdata_dict, None, originator)\n                    timer.schedule(0, <timer_callback>invitation._cb_state, invitation)\n                except:\n                    invitation._fail(ua)\n            elif (tsx.role == PJSIP_ROLE_UAS and tsx.state == PJSIP_TSX_STATE_TRYING and\n                  rdata != NULL and rdata.msg_info.msg.type == PJSIP_REQUEST_MSG and\n                  _pj_str_to_str(tsx.method.name) == \"REFER\"):\n                invitation.process_incoming_transfer(ua, rdata)\n            elif (tsx.role == PJSIP_ROLE_UAS and tsx.state == PJSIP_TSX_STATE_TRYING and\n                  rdata != NULL and rdata.msg_info.msg.type == PJSIP_REQUEST_MSG and tsx.method.id == PJSIP_OPTIONS_METHOD):\n                invitation.process_incoming_options(ua, rdata)\n    except:\n        ua._handle_exception(1)\n\ncdef void _Invitation_cb_new(pjsip_inv_session *inv, pjsip_event *e) with gil:\n    # As far as I can tell this is never actually called!\n    pass\n\ncdef void _Invitation_transfer_cb_state(pjsip_evsub *sub, pjsip_event *event) with gil:\n    cdef void *invitation_void\n    cdef Invitation invitation\n    cdef object state\n    cdef int code = 0\n    cdef dict event_dict = dict()\n    cdef str reason = None\n    cdef pjsip_rx_data *rdata = NULL\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        invitation_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if invitation_void == NULL:\n            return\n        invitation = (<object> invitation_void)()\n        if invitation is None:\n            return\n        state = pjsip_evsub_get_state_name(sub)\n        if (event != NULL and event.type == PJSIP_EVENT_TSX_STATE and\n            (event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_COMPLETED or\n             event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_TERMINATED)):\n            if state == \"TERMINATED\":\n                if event.body.tsx_state.tsx.role == PJSIP_ROLE_UAC:\n                    code = event.body.tsx_state.tsx.status_code\n                    reason = _pj_str_to_str(event.body.tsx_state.tsx.status_text)\n                else:\n                    reason = \"Referral has expired\"\n                if event.body.tsx_state.type == PJSIP_EVENT_RX_MSG and _pj_str_to_str(event.body.tsx_state.tsx.method.name) == \"NOTIFY\":\n                    # Extract code and reason from the sipfrag payload\n                    rdata = event.body.tsx_state.src.rdata\n                    if rdata != NULL:\n                        _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n                        if event_dict.get('body', None) is not None:\n                            match = sipfrag_re.match(event_dict['body'])\n                            if match:\n                                code = int(match.group('code'))\n                                reason = match.group('reason')\n        try:\n            timer = TransferStateCallbackTimer(state, code, reason)\n            timer.schedule(0, <timer_callback>invitation._transfer_cb_state, invitation)\n        except:\n            invitation._fail(ua)\n    except:\n        ua._handle_exception(1)\n\ncdef void _Invitation_transfer_cb_tsx(pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event) with gil:\n    cdef void *invitation_void\n    cdef Invitation invitation\n    cdef pjsip_rx_data *rdata\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        invitation_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if invitation_void == NULL:\n            return\n        invitation = (<object> invitation_void)()\n        if invitation is None:\n            return\n        if (event != NULL and event.type == PJSIP_EVENT_TSX_STATE and\n            event.body.tsx_state.type == PJSIP_EVENT_RX_MSG and\n            event.body.tsx_state.tsx.role == PJSIP_ROLE_UAC and\n            event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_COMPLETED and\n            _pj_str_to_str(event.body.tsx_state.tsx.method.name) in (\"REFER\", \"SUBSCRIBE\") and\n            event.body.tsx_state.tsx.status_code/100 == 2):\n            rdata = event.body.tsx_state.src.rdata\n            if rdata != NULL:\n                rdata_dict = dict()\n                _pjsip_msg_to_dict(rdata.msg_info.msg, rdata_dict)\n                try:\n                    timer = TransferResponseCallbackTimer(_pj_str_to_str(event.body.tsx_state.tsx.method.name), rdata_dict)\n                    timer.schedule(0, <timer_callback>invitation._transfer_cb_response, invitation)\n                except:\n                    invitation._fail(ua)\n    except:\n        ua._handle_exception(1)\n\ncdef void _Invitation_transfer_cb_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code,\n                                    pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil:\n    cdef void *invitation_void\n    cdef Invitation invitation\n    cdef TransferRequestCallbackTimer timer\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        invitation_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if invitation_void == NULL:\n            return\n        invitation = (<object> invitation_void)()\n        if invitation is None:\n            return\n        if rdata != NULL:\n            rdata_dict = dict()\n            _pjsip_msg_to_dict(rdata.msg_info.msg, rdata_dict)\n            try:\n                timer = TransferRequestCallbackTimer(rdata_dict)\n                timer.schedule(0, <timer_callback>invitation._transfer_cb_notify, invitation)\n            except:\n                invitation._fail(ua)\n    except:\n        ua._handle_exception(1)\n\ncdef void _Invitation_transfer_cb_refresh(pjsip_evsub *sub) with gil:\n    # We want to handle the refresh timer oursevles, ignore the PJSIP provided timer\n    pass\n\ncdef void _Invitation_transfer_in_cb_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code,\n                                            pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil:\n    cdef void *invitation_void\n    cdef dict rdata_dict\n    cdef pjsip_expires_hdr *expires_header\n    cdef Invitation invitation\n    cdef Timer timer\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        invitation_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if invitation_void == NULL:\n            p_st_code[0] = 481\n            return\n        invitation = (<object> invitation_void)()\n        if invitation is None:\n            p_st_code[0] = 481\n            return\n        expires_header = <pjsip_expires_hdr *> pjsip_msg_find_hdr(rdata.msg_info.msg, PJSIP_H_EXPIRES, NULL)\n        if expires_header != NULL and expires_header.ivalue == 0:\n            try:\n                timer = Timer()\n                timer.schedule(0, <timer_callback>invitation._terminate_transfer, invitation)\n            except:\n                invitation._fail(ua)\n            p_st_code[0] = 200\n            return\n        p_st_code[0] = 501\n    except:\n        ua._handle_exception(1)\n\ncdef void _Invitation_transfer_in_cb_server_timeout(pjsip_evsub *sub) with gil:\n    cdef void *invitation_void\n    cdef Invitation invitation\n    cdef Timer timer\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        invitation_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if invitation_void == NULL:\n            return\n        invitation = (<object> invitation_void)()\n        if invitation is None:\n            return\n        try:\n            timer = Timer()\n            timer.schedule(0, <timer_callback>invitation._transfer_cb_server_timeout, invitation)\n        except:\n            invitation._fail(ua)\n    except:\n        ua._handle_exception(1)\n\ncdef void _Invitation_transfer_in_cb_tsx(pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event) with gil:\n    cdef void *invitation_void\n    cdef Invitation invitation\n    cdef PJSIPUA ua\n    cdef pjsip_rx_data *rdata\n    cdef dict event_dict\n    cdef int code\n    cdef str reason\n    cdef TransferStateCallbackTimer timer\n\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        invitation_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if invitation_void == NULL:\n            return\n        invitation = (<object> invitation_void)()\n        if invitation is None:\n            return\n        if (event != NULL and event.type == PJSIP_EVENT_TSX_STATE and event.body.tsx_state.tsx.role == PJSIP_ROLE_UAC and\n            _pj_str_to_str(event.body.tsx_state.tsx.method.name) == \"NOTIFY\" and\n            event.body.tsx_state.tsx.state in (PJSIP_TSX_STATE_COMPLETED, PJSIP_TSX_STATE_TERMINATED)):\n\n            code = event.body.tsx_state.tsx.status_code\n            reason = _pj_str_to_str(event.body.tsx_state.tsx.status_text)\n\n            if code in (408, 481) or code/100==7:\n                # Be careful! PJSIP will erase the subscription\n                timer = TransferStateCallbackTimer(\"TERMINATED\", code, reason)\n                timer.schedule(0, <timer_callback>invitation._transfer_cb_state, invitation)\n    except:\n        ua._handle_exception(1)\n\n\n# Globals\n#\n\ncdef pjsip_inv_callback _inv_cb\n_inv_cb.on_state_changed = _Invitation_cb_state\n_inv_cb.on_media_update = _Invitation_cb_sdp_done\n_inv_cb.on_rx_reinvite = _Invitation_cb_rx_reinvite\n_inv_cb.on_tsx_state_changed = _Invitation_cb_tsx_state_changed\n_inv_cb.on_new_session = _Invitation_cb_new\n\ncdef pjsip_evsub_user _transfer_cb\n_transfer_cb.on_evsub_state = _Invitation_transfer_cb_state\n_transfer_cb.on_tsx_state = _Invitation_transfer_cb_tsx\n_transfer_cb.on_rx_notify = _Invitation_transfer_cb_notify\n_transfer_cb.on_client_refresh = _Invitation_transfer_cb_refresh\n\ncdef pjsip_evsub_user _incoming_transfer_cb\n_incoming_transfer_cb.on_rx_refresh = _Invitation_transfer_in_cb_rx_refresh\n_incoming_transfer_cb.on_server_timeout = _Invitation_transfer_in_cb_server_timeout\n_incoming_transfer_cb.on_tsx_state = _Invitation_transfer_in_cb_tsx\n\n"
  },
  {
    "path": "sipsimple/core/_core.lib.pxi",
    "content": "\nimport sys\n\n\n# classes\n\ncdef class PJLIB:\n    def __cinit__(self):\n        cdef int status\n        status = pj_init()\n        if status != 0:\n            raise PJSIPError(\"Could not initialize PJLIB\", status)\n        self._init_done = 1\n        status = pjlib_util_init()\n        if status != 0:\n            raise PJSIPError(\"Could not initialize PJLIB-UTIL\", status)\n        status = pjnath_init()\n        if status != 0:\n            raise PJSIPError(\"Could not initialize PJNATH\", status)\n\n    def __dealloc__(self):\n        if self._init_done:\n            with nogil:\n                pj_shutdown()\n\n\ncdef class PJCachingPool:\n    def __cinit__(self):\n        pj_caching_pool_init(&self._obj, &pj_pool_factory_default_policy, 0)\n        self._init_done = 1\n\n    def __dealloc__(self):\n        if self._init_done:\n            pj_caching_pool_destroy(&self._obj)\n\n\ncdef class PJSIPEndpoint:\n    def __cinit__(self, PJCachingPool caching_pool, ip_address, udp_port, tcp_port, tls_port,\n                  tls_verify_server, tls_ca_file, tls_cert_file, tls_privkey_file, int tls_timeout):\n        cdef pj_dns_resolver *resolver\n        cdef pjsip_tpmgr *tpmgr\n        cdef int status\n\n        if ip_address is not None and not _is_valid_ip(pj_AF_INET(), ip_address):\n            raise ValueError(\"Not a valid IPv4 address: %s\" % ip_address)\n        self._local_ip_used = ip_address\n\n        status = pjsip_endpt_create(&caching_pool._obj.factory, \"core\",  &self._obj)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize PJSIP endpoint\", status)\n        self._pool = pjsip_endpt_create_pool(self._obj, \"PJSIPEndpoint\", 4096, 4096)\n        if self._pool == NULL:\n            raise SIPCoreError(\"Could not allocate memory pool\")\n\n        status = pjsip_tsx_layer_init_module(self._obj)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize transaction layer module\", status)\n        status = pjsip_ua_init_module(self._obj, NULL) # TODO: handle forking\n        if status != 0:\n            raise PJSIPError(\"Could not initialize common dialog layer module\", status)\n        status = pjsip_evsub_init_module(self._obj)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize event subscription module\", status)\n        status = pjsip_100rel_init_module(self._obj)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize 100rel module\", status)\n        status = pjsip_replaces_init_module(self._obj)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize replaces module\", status)\n        status = pjsip_inv_usage_init(self._obj, &_inv_cb)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize invitation module\", status)\n        status = pjsip_endpt_create_resolver(self._obj, &resolver)\n        if status != 0:\n            raise PJSIPError(\"Could not create fake DNS resolver for endpoint\", status)\n        status = pjsip_endpt_set_resolver(self._obj, resolver)\n        if status != 0:\n            raise PJSIPError(\"Could not set fake DNS resolver on endpoint\", status)\n\n        tpmgr = pjsip_endpt_get_tpmgr(self._obj)\n        if tpmgr == NULL:\n            raise SIPCoreError(\"Could not get the transport manager\")\n        status = pjsip_tpmgr_set_state_cb(tpmgr, _transport_state_cb)\n        if status != 0:\n            raise PJSIPError(\"Could not set transport state callback\", status)\n        if udp_port is not None:\n            self._start_udp_transport(udp_port)\n        if tcp_port is not None:\n            self._start_tcp_transport(tcp_port)\n        self._tls_verify_server = int(tls_verify_server)\n        if tls_ca_file is not None:\n            self._tls_ca_file = PJSTR(tls_ca_file.encode(sys.getfilesystemencoding()))\n        if tls_cert_file is not None:\n            self._tls_cert_file = PJSTR(tls_cert_file.encode(sys.getfilesystemencoding()))\n        if tls_privkey_file is not None:\n            self._tls_privkey_file = PJSTR(tls_privkey_file.encode(sys.getfilesystemencoding()))\n        if tls_timeout < 0:\n            raise ValueError(\"Invalid TLS timeout value: %d\" % tls_timeout)\n        self._tls_timeout = tls_timeout\n        if tls_port is not None:\n            self._start_tls_transport(tls_port)\n\n    cdef int _make_local_addr(self, pj_sockaddr_in *local_addr, object ip_address, int port) except -1:\n        cdef pj_str_t local_ip_pj\n        cdef pj_str_t *local_ip_p = NULL\n        cdef int status\n        if not (0 <= port <= 65535):\n            raise SIPCoreError(\"Invalid port: %d\" % port)\n        if ip_address is not None and ip_address is not \"0.0.0.0\":\n            local_ip_p = &local_ip_pj\n            _str_to_pj_str(ip_address, local_ip_p)\n        status = pj_sockaddr_in_init(local_addr, local_ip_p, port)\n        if status != 0:\n            raise PJSIPError(\"Could not create local address\", status)\n        return 0\n\n    cdef int _start_udp_transport(self, int port) except -1:\n        cdef pj_sockaddr_in local_addr\n        self._make_local_addr(&local_addr, self._local_ip_used, port)\n        status = pjsip_udp_transport_start(self._obj, &local_addr, NULL, 1, &self._udp_transport)\n        if status != 0:\n            raise PJSIPError(\"Could not create UDP transport\", status)\n        return 0\n\n    cdef int _stop_udp_transport(self) except -1:\n        pjsip_transport_shutdown(self._udp_transport)\n        self._udp_transport = NULL\n        return 0\n\n    cdef int _start_tcp_transport(self, int port) except -1:\n        cdef pj_sockaddr_in local_addr\n        self._make_local_addr(&local_addr, self._local_ip_used, port)\n        status = pjsip_tcp_transport_start2(self._obj, &local_addr, NULL, 1, &self._tcp_transport)\n        if status != 0:\n            raise PJSIPError(\"Could not create TCP transport\", status)\n        return 0\n\n    cdef int _stop_tcp_transport(self) except -1:\n        self._tcp_transport.destroy(self._tcp_transport)\n        self._tcp_transport = NULL\n        return 0\n\n    cdef int _start_tls_transport(self, port) except -1:\n        cdef pj_sockaddr_in local_addr\n        cdef pjsip_tls_setting tls_setting\n        self._make_local_addr(&local_addr, self._local_ip_used, port)\n        pjsip_tls_setting_default(&tls_setting)\n        # The following value needs to be reasonably low, as TLS negotiation hogs the PJSIP polling loop\n        tls_setting.timeout.sec = self._tls_timeout / 1000\n        tls_setting.timeout.msec = self._tls_timeout % 1000\n        if self._tls_ca_file is not None:\n            tls_setting.ca_list_file = self._tls_ca_file.pj_str\n        if self._tls_cert_file is not None:\n            tls_setting.cert_file = self._tls_cert_file.pj_str\n        if self._tls_privkey_file is not None:\n            tls_setting.privkey_file = self._tls_privkey_file.pj_str\n        tls_setting.method = PJSIP_SSLV23_METHOD\n        tls_setting.verify_server = self._tls_verify_server\n        status = pjsip_tls_transport_start(self._obj, &tls_setting, &local_addr, NULL, 1, &self._tls_transport)\n        if status in (PJSIP_TLS_EUNKNOWN, PJSIP_TLS_EINVMETHOD, PJSIP_TLS_ECACERT, PJSIP_TLS_ECERTFILE, PJSIP_TLS_EKEYFILE, PJSIP_TLS_ECIPHER, PJSIP_TLS_ECTX):\n            raise PJSIPTLSError(\"Could not create TLS transport\", status)\n        elif status != 0:\n            raise PJSIPError(\"Could not create TLS transport\", status)\n        return 0\n\n    cdef int _stop_tls_transport(self) except -1:\n        self._tls_transport.destroy(self._tls_transport)\n        self._tls_transport = NULL\n        return 0\n\n    cdef int _set_dns_nameservers(self, list servers) except -1:\n        cdef int num_servers = len(servers)\n        cdef pj_str_t *pj_servers\n        cdef int status\n        cdef pj_dns_resolver *resolver\n\n        if num_servers == 0:\n            return 0\n\n        resolver = pjsip_endpt_get_resolver(self._obj)\n        if resolver == NULL:\n            raise SIPCoreError(\"Could not get DNS resolver on endpoint\")\n\n        pj_servers = <pj_str_t *> malloc(sizeof(pj_str_t)*num_servers)\n        if pj_servers == NULL:\n            raise MemoryError()\n\n        for i, ns in enumerate(servers):\n            _str_to_pj_str(ns, &pj_servers[i])\n        status = pj_dns_resolver_set_ns(resolver, num_servers, pj_servers, NULL)\n        free(pj_servers)\n        if status != 0:\n            raise PJSIPError(\"Could not set nameservers on DNS resolver\", status)\n\n        return 0\n\n    def __dealloc__(self):\n        cdef pjsip_tpmgr *tpmgr\n        tpmgr = pjsip_endpt_get_tpmgr(self._obj)\n        if tpmgr != NULL:\n            pjsip_tpmgr_set_state_cb(tpmgr, NULL)\n        if self._udp_transport != NULL:\n            self._stop_udp_transport()\n        if self._tcp_transport != NULL:\n            self._stop_tcp_transport()\n        if self._tls_transport != NULL:\n            self._stop_tls_transport()\n        if self._pool != NULL:\n            pjsip_endpt_release_pool(self._obj, self._pool)\n        if self._obj != NULL:\n            with nogil:\n                pjsip_endpt_destroy(self._obj)\n\n\ncdef class PJMEDIAEndpoint:\n    def __cinit__(self, PJCachingPool caching_pool):\n        cdef int status\n        status = pjmedia_endpt_create(&caching_pool._obj.factory, NULL, 1, &self._obj)\n        if status != 0:\n            raise PJSIPError(\"Could not create PJMEDIA endpoint\", status)\n        self._pool = pjmedia_endpt_create_pool(self._obj, \"PJMEDIAEndpoint\", 4096, 4096)\n        if self._pool == NULL:\n            raise SIPCoreError(\"Could not allocate memory pool\")\n\n        self._audio_subsystem_init(caching_pool)\n        self._video_subsystem_init(caching_pool)\n\n    def __dealloc__(self):\n        self._audio_subsystem_shutdown()\n        self._video_subsystem_shutdown()\n        if self._pool != NULL:\n            pj_pool_release(self._pool)\n        if self._obj != NULL:\n            with nogil:\n                pjmedia_endpt_destroy(self._obj)\n\n    cdef void _audio_subsystem_init(self, PJCachingPool caching_pool):\n        cdef int status\n        cdef pjmedia_audio_codec_config audio_codec_cfg\n\n        pjmedia_audio_codec_config_default(&audio_codec_cfg)\n        audio_codec_cfg.speex.option = PJMEDIA_SPEEX_NO_NB\n        audio_codec_cfg.ilbc.mode = 30\n\n        status = pjmedia_codec_register_audio_codecs(self._obj, &audio_codec_cfg)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize audio codecs\", status)\n        self._has_audio_codecs = 1\n\n    cdef void _audio_subsystem_shutdown(self):\n        pass\n\n    cdef void _video_subsystem_init(self, PJCachingPool caching_pool):\n        cdef int status\n\n        status = pjmedia_video_format_mgr_create(self._pool, 64, 0, NULL)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize video format manager\", status)\n        status = pjmedia_converter_mgr_create(self._pool, NULL)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize converter manager\", status)\n        status = pjmedia_event_mgr_create(self._pool, 0, NULL)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize event manager\", status)\n        status = pjmedia_vid_codec_mgr_create(self._pool, NULL)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize video codec manager\", status)\n        status = pjmedia_codec_ffmpeg_vid_init(NULL, &caching_pool._obj.factory)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize ffmpeg video codecs\", status)\n        self._has_ffmpeg_video = 1\n        status = pjmedia_codec_vpx_init(NULL, &caching_pool._obj.factory)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize vpx video codecs\", status)\n        self._has_vpx = 1\n        status = pjmedia_vid_dev_subsys_init(&caching_pool._obj.factory)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize video subsystem\", status)\n        self._has_video = 1\n\n    cdef void _video_subsystem_shutdown(self):\n        if self._has_video:\n            pjmedia_vid_dev_subsys_shutdown()\n        if self._has_ffmpeg_video:\n            pjmedia_codec_ffmpeg_vid_deinit()\n        if self._has_vpx:\n            pjmedia_codec_vpx_deinit()\n        if pjmedia_vid_codec_mgr_instance() != NULL:\n            pjmedia_vid_codec_mgr_destroy(NULL)\n        if pjmedia_event_mgr_instance() != NULL:\n            pjmedia_event_mgr_destroy(NULL)\n        if pjmedia_converter_mgr_instance() != NULL:\n            pjmedia_converter_mgr_destroy(NULL)\n        if pjmedia_video_format_mgr_instance() != NULL:\n            pjmedia_video_format_mgr_destroy(NULL)\n\n    cdef list _get_codecs(self):\n        cdef unsigned int count = PJMEDIA_CODEC_MGR_MAX_CODECS\n        cdef pjmedia_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS]\n        cdef unsigned int prio[PJMEDIA_CODEC_MGR_MAX_CODECS]\n        cdef int i\n        cdef list retval\n        cdef int status\n        status = pjmedia_codec_mgr_enum_codecs(pjmedia_endpt_get_codec_mgr(self._obj), &count, info, prio)\n        if status != 0:\n            raise PJSIPError(\"Could not get available codecs\", status)\n        retval = list()\n        for i from 0 <= i < count:\n            retval.append((prio[i], _pj_str_to_str(info[i].encoding_name), info[i].channel_cnt, info[i].clock_rate))\n        return retval\n\n    cdef list _get_all_codecs(self):\n        cdef list codecs\n        cdef tuple codec_data\n        codecs = self._get_codecs()\n        return list(set([codec_data[1] for codec_data in codecs]))\n\n    cdef list _get_current_codecs(self):\n        cdef list codecs\n        cdef tuple codec_data\n        cdef list retval\n        codecs = [codec_data for codec_data in self._get_codecs() if codec_data[0] > 0]\n        codecs.sort(reverse=True)\n        retval = list(set([codec_data[1] for codec_data in codecs]))\n        return retval\n\n    cdef int _set_codecs(self, list req_codecs) except -1:\n        cdef object new_codecs\n        cdef object all_codecs\n        cdef object codec_set\n        cdef list codecs\n        cdef tuple codec_data\n        cdef str codec\n        cdef int sample_rate\n        cdef int channel_count\n        cdef str codec_name\n        cdef int prio\n        cdef list codec_prio\n        cdef pj_str_t codec_pj\n        new_codecs = set(req_codecs)\n        if len(new_codecs) != len(req_codecs):\n            raise ValueError(\"Requested codec list contains doubles\")\n        all_codecs = set(self._get_all_codecs())\n        codec_set = new_codecs.difference(all_codecs)\n        if len(codec_set) > 0:\n            raise SIPCoreError(\"Unknown codec(s): %s\" % \", \".join(codec_set))\n        # reverse the codec data tuples so that we can easily sort on sample rate\n        # to make sure that bigger sample rates get higher priority\n        codecs = [list(reversed(codec_data)) for codec_data in self._get_codecs()]\n        codecs.sort(reverse=True)\n        codec_prio = list()\n        for codec in req_codecs:\n            for sample_rate, channel_count, codec_name, prio in codecs:\n                if codec == codec_name and channel_count == 1:\n                    codec_prio.append(\"%s/%d/%d\" % (codec_name, sample_rate, channel_count))\n        for prio, codec in enumerate(reversed(codec_prio)):\n            _str_to_pj_str(codec, &codec_pj)\n            status = pjmedia_codec_mgr_set_codec_priority(pjmedia_endpt_get_codec_mgr(self._obj), &codec_pj, prio + 1)\n            if status != 0:\n                raise PJSIPError(\"Could not set codec priority\", status)\n        for sample_rate, channel_count, codec_name, prio in codecs:\n            if codec_name not in req_codecs or channel_count > 1:\n                codec = \"%s/%d/%d\" % (codec_name, sample_rate, channel_count)\n                _str_to_pj_str(codec, &codec_pj)\n                status = pjmedia_codec_mgr_set_codec_priority(pjmedia_endpt_get_codec_mgr(self._obj), &codec_pj, 0)\n                if status != 0:\n                    raise PJSIPError(\"Could not set codec priority\", status)\n        return 0\n\n    cdef list _get_video_codecs(self):\n        cdef unsigned int count = PJMEDIA_VID_CODEC_MGR_MAX_CODECS\n        cdef pjmedia_vid_codec_info info[PJMEDIA_VID_CODEC_MGR_MAX_CODECS]\n        cdef unsigned int prio[PJMEDIA_VID_CODEC_MGR_MAX_CODECS]\n        cdef int i\n        cdef list retval\n        cdef int status\n        status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, info, prio)\n        if status != 0:\n            raise PJSIPError(\"Could not get available video codecs\", status)\n        retval = list()\n        for i from 0 <= i < count:\n            if info[i].packings & PJMEDIA_VID_PACKING_PACKETS:\n                retval.append((prio[i], _pj_str_to_str(info[i].encoding_name), info[i].pt))\n        return retval\n\n    cdef list _get_all_video_codecs(self):\n        cdef list codecs\n        cdef tuple codec_data\n        codecs = self._get_video_codecs()\n        return list(set([codec_data[1] for codec_data in codecs]))\n\n    cdef list _get_current_video_codecs(self):\n        cdef list codecs\n        cdef tuple codec_data\n        cdef list retval\n        codecs = [codec_data for codec_data in self._get_video_codecs() if codec_data[0] > 0]\n        codecs.sort(reverse=True)\n        retval = list(set([codec_data[1] for codec_data in codecs]))\n        return retval\n\n    cdef int _set_video_codecs(self, list req_codecs) except -1:\n        cdef object new_codecs\n        cdef object codec_set\n        cdef list codecs\n        cdef tuple codec_data\n        cdef str codec\n        cdef int payload_type\n        cdef str codec_name\n        cdef int prio\n        cdef list codec_prio\n        cdef pj_str_t codec_pj\n        new_codecs = set(req_codecs)\n        if len(new_codecs) != len(req_codecs):\n            raise ValueError(\"Requested video codec list contains doubles\")\n        codec_set = new_codecs.difference(set(self._get_all_video_codecs()))\n        if len(codec_set) > 0:\n            raise SIPCoreError(\"Unknown video codec(s): %s\" % \", \".join(codec_set))\n        codecs = self._get_video_codecs()\n        codec_prio = list()\n        for codec in req_codecs:\n            for prio, codec_name, payload_type in codecs:\n                if codec == codec_name:\n                    codec_prio.append(\"%s/%d\" % (codec_name, payload_type))\n        for prio, codec in enumerate(reversed(codec_prio)):\n            _str_to_pj_str(codec, &codec_pj)\n            status = pjmedia_vid_codec_mgr_set_codec_priority(NULL, &codec_pj, prio + 1)\n            if status != 0:\n                raise PJSIPError(\"Could not set video codec priority\", status)\n        for prio, codec_name, payload_type in codecs:\n            if codec_name not in req_codecs:\n                codec = \"%s/%d\" % (codec_name, payload_type)\n                _str_to_pj_str(codec, &codec_pj)\n                status = pjmedia_vid_codec_mgr_set_codec_priority(NULL, &codec_pj, 0)\n                if status != 0:\n                    raise PJSIPError(\"Could not set video codec priority\", status)\n        return 0\n\n    cdef void _set_h264_options(self, str profile, int level):\n        global h264_profiles_map, h264_profile_level_id, h264_packetization_mode\n\n        cdef unsigned int count = PJMEDIA_VID_CODEC_MGR_MAX_CODECS\n        cdef pjmedia_vid_codec_info info[PJMEDIA_VID_CODEC_MGR_MAX_CODECS]\n        cdef pjmedia_vid_codec_param vparam\n        cdef unsigned int prio[PJMEDIA_VID_CODEC_MGR_MAX_CODECS]\n        cdef int i\n        cdef int status\n        cdef PJSTR h264_profile_level_id_value\n        cdef PJSTR h264_packetization_mode_value = PJSTR(\"1\")    # TODO; make it configurable?\n\n        try:\n            profile_n = h264_profiles_map[profile]\n        except KeyError:\n            raise ValueError(\"invalid profile specified: %s\" % profile)\n        h264_profile_level_id_value = PJSTR(\"%xe0%x\" % (profile_n, level))    # use common subset (e0)\n\n        status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, info, prio)\n        if status != 0:\n            raise PJSIPError(\"Could not get available video codecs\", status)\n        for i from 0 <= i < count:\n            if not (info[i].packings & PJMEDIA_VID_PACKING_PACKETS):\n                continue\n            if _pj_str_to_str(info[i].encoding_name) != 'H264':\n                continue\n            status = pjmedia_vid_codec_mgr_get_default_param(NULL, &info[i], &vparam)\n            if status != 0:\n                continue\n            # 2 format parameters are currently defined for H264: profile-level-id and packetization-mode\n            vparam.dec_fmtp.param[0].name = h264_profile_level_id.pj_str\n            vparam.dec_fmtp.param[0].val = h264_profile_level_id_value.pj_str\n            vparam.dec_fmtp.param[1].name = h264_packetization_mode.pj_str\n            vparam.dec_fmtp.param[1].val = h264_packetization_mode_value.pj_str\n            vparam.dec_fmtp.cnt = 2\n\n            status = pjmedia_vid_codec_mgr_set_default_param(NULL, &info[i], &vparam)\n            if status != 0:\n                raise PJSIPError(\"Could not set H264 options\", status)\n\n\n    cdef void _set_video_options(self, tuple max_resolution, int max_framerate, float max_bitrate):\n        cdef unsigned int count = PJMEDIA_VID_CODEC_MGR_MAX_CODECS\n        cdef pjmedia_vid_codec_info info[PJMEDIA_VID_CODEC_MGR_MAX_CODECS]\n        cdef pjmedia_vid_codec_param vparam\n        cdef unsigned int prio[PJMEDIA_VID_CODEC_MGR_MAX_CODECS]\n        cdef int i\n        cdef int status\n\n        max_width, max_height = max_resolution\n\n        status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, info, prio)\n        if status != 0:\n            raise PJSIPError(\"Could not get available video codecs\", status)\n        for i from 0 <= i < count:\n            if not (info[i].packings & PJMEDIA_VID_PACKING_PACKETS):\n                continue\n            status = pjmedia_vid_codec_mgr_get_default_param(NULL, &info[i], &vparam)\n            if status != 0:\n                continue\n            # Max resolution\n            vparam.enc_fmt.det.vid.size.w = max_width\n            vparam.enc_fmt.det.vid.size.h = max_height\n            vparam.dec_fmt.det.vid.size.w = max_width\n            vparam.dec_fmt.det.vid.size.h = max_height\n            # Max framerate\n            vparam.enc_fmt.det.vid.fps.num = max_framerate\n            vparam.enc_fmt.det.vid.fps.denum = 1\n            vparam.dec_fmt.det.vid.fps.num = 10\n            vparam.dec_fmt.det.vid.fps.denum = 1\n            # Average and max bitrate (set to 0 for 'unlimited')\n            vparam.enc_fmt.det.vid.avg_bps = int(max_bitrate * 1e6)\n            vparam.enc_fmt.det.vid.max_bps = int(max_bitrate * 1e6)\n            vparam.dec_fmt.det.vid.avg_bps = 0\n            vparam.dec_fmt.det.vid.max_bps = 0\n\n            status = pjmedia_vid_codec_mgr_set_default_param(NULL, &info[i], &vparam)\n            if status != 0:\n                raise PJSIPError(\"Could not set video options\", status)\n\n\ncdef void _transport_state_cb(pjsip_transport *tp, pjsip_transport_state state, pjsip_transport_state_info_ptr_const info) with gil:\n    cdef PJSIPUA ua\n    cdef str local_address\n    cdef str remote_address\n    cdef char buf[PJ_INET6_ADDRSTRLEN]\n    cdef dict event_dict\n    try:\n        ua = _get_ua()\n    except:\n        return\n\n    if pj_sockaddr_has_addr(&tp.local_addr):\n        pj_sockaddr_print(&tp.local_addr, buf, 512, 0)\n        local_address = '%s:%d' % (PyString_FromString(buf), pj_sockaddr_get_port(&tp.local_addr))\n    else:\n        local_address = None\n    remote_address = '%s:%d' % (_pj_str_to_str(tp.remote_name.host), tp.remote_name.port)\n    event_dict = dict(transport=tp.type_name.lower(), local_address=local_address, remote_address=remote_address)\n    if state == PJSIP_TP_STATE_CONNECTED:\n        _add_event(\"SIPEngineTransportDidConnect\", event_dict)\n    else:\n        event_dict['reason'] = _pj_status_to_str(info.status)\n        _add_event(\"SIPEngineTransportDidDisconnect\", event_dict)\n\n\n# globals\ncdef PJSTR h264_profile_level_id = PJSTR(\"profile-level-id\")\ncdef PJSTR h264_packetization_mode = PJSTR(\"packetization-mode\")\ncdef dict h264_profiles_map = dict(baseline=66, main=77, high=100)\n"
  },
  {
    "path": "sipsimple/core/_core.mediatransport.pxi",
    "content": "\nimport sys\n\nfrom errno import EADDRINUSE\n\n\n# classes\n\ncdef class RTPTransport:\n    def __cinit__(self, *args, **kwargs):\n        cdef int status\n        cdef pj_pool_t *pool\n        cdef bytes pool_name\n        cdef char* c_pool_name\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n        pool_name = b\"RTPTransport_%d\" % id(self)\n\n        self.weakref = weakref.ref(self)\n        Py_INCREF(self.weakref)\n\n        self._af = pj_AF_INET()\n\n        status = pj_mutex_create_recursive(ua._pjsip_endpoint._pool, \"rtp_transport_lock\", &self._lock)\n        if status != 0:\n            raise PJSIPError(\"failed to create lock\", status)\n\n        pool = ua.create_memory_pool(pool_name, 4096, 4096)\n        self._pool = pool\n        self.state = \"NULL\"\n\n    def __init__(self, encryption=None, use_ice=False, ice_stun_address=None, ice_stun_port=PJ_STUN_PORT):\n        cdef PJSIPUA ua = _get_ua()\n\n        if self.state != \"NULL\":\n            raise SIPCoreError(\"RTPTransport.__init__() was already called\")\n        self._rtp_valid_pair = None\n        self._encryption = encryption\n        self.use_ice = use_ice\n        self.ice_stun_address = ice_stun_address\n        self.ice_stun_port = ice_stun_port\n\n    def __dealloc__(self):\n        cdef PJSIPUA ua\n        cdef pjmedia_transport *transport\n        cdef Timer timer\n\n        try:\n            ua = _get_ua()\n        except:\n            return\n\n        transport = self._obj\n        if transport != NULL:\n            transport.user_data = NULL\n            if self._wrapped_transport != NULL:\n                self._wrapped_transport.user_data = NULL\n            with nogil:\n                pjmedia_transport_media_stop(transport)\n                pjmedia_transport_close(transport)\n            self._obj = NULL\n            self._wrapped_transport = NULL\n        ua.release_memory_pool(self._pool)\n        self._pool = NULL\n        if self._lock != NULL:\n            pj_mutex_destroy(self._lock)\n        timer = Timer()\n        try:\n            timer.schedule(60, deallocate_weakref, self.weakref)\n        except SIPCoreError:\n            pass\n\n    cdef PJSIPUA _check_ua(self):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n            return ua\n        except:\n            self.state = \"INVALID\"\n            self._obj = NULL\n            self._wrapped_transport = NULL\n            self._pool = NULL\n            return None\n\n    cdef void _get_info(self, pjmedia_transport_info *info):\n        cdef int status\n        cdef pjmedia_transport *transport\n\n        transport = self._obj\n\n        with nogil:\n            pjmedia_transport_info_init(info)\n            status = pjmedia_transport_get_info(transport, info)\n        if status != 0:\n            raise PJSIPError(\"Could not get transport info\", status)\n\n    property local_rtp_port:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_transport_info info\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return None\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                    return None\n                self._get_info(&info)\n                if pj_sockaddr_has_addr(&info.sock_info.rtp_addr_name):\n                    return pj_sockaddr_get_port(&info.sock_info.rtp_addr_name)\n                else:\n                    return None\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property local_rtp_address:\n\n        def __get__(self):\n            cdef char buf[PJ_INET6_ADDRSTRLEN]\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_transport_info info\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return None\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                    return None\n                self._get_info(&info)\n                if pj_sockaddr_has_addr(&info.sock_info.rtp_addr_name):\n                    return pj_sockaddr_print(&info.sock_info.rtp_addr_name, buf, PJ_INET6_ADDRSTRLEN, 0)\n                else:\n                    return None\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property local_rtp_candidate:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return None\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self._rtp_valid_pair:\n                    return self._rtp_valid_pair.local_candidate\n                return None\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property remote_rtp_port:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_transport_info info\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return None\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                    return None\n                if self._ice_active() and self._rtp_valid_pair:\n                    return self._rtp_valid_pair.remote_candidate.port\n                self._get_info(&info)\n                if pj_sockaddr_has_addr(&info.src_rtp_name):\n                    return pj_sockaddr_get_port(&info.src_rtp_name)\n                else:\n                    return None\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property remote_rtp_address:\n\n        def __get__(self):\n            cdef char buf[PJ_INET6_ADDRSTRLEN]\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_transport_info info\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return None\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                    return None\n                if self._ice_active() and self._rtp_valid_pair:\n                    return self._rtp_valid_pair.remote_candidate.address\n                self._get_info(&info)\n                if pj_sockaddr_has_addr(&info.src_rtp_name):\n                    return pj_sockaddr_print(&info.src_rtp_name, buf, PJ_INET6_ADDRSTRLEN, 0)\n                else:\n                    return None\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property remote_rtp_candidate:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return None\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self._rtp_valid_pair:\n                    return self._rtp_valid_pair.remote_candidate\n                return None\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property srtp_active:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_srtp_info *srtp_info\n            cdef pjmedia_transport_info info\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return False\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                    return False\n                self._get_info(&info)\n                srtp_info = <pjmedia_srtp_info *> pjmedia_transport_info_get_spc_info(&info, PJMEDIA_TRANSPORT_TYPE_SRTP)\n                if srtp_info != NULL:\n                    return bool(srtp_info.active)\n                return False\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property srtp_cipher:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_srtp_info *srtp_info\n            cdef pjmedia_transport_info info\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return None\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                    return None\n                self._get_info(&info)\n                srtp_info = <pjmedia_srtp_info *> pjmedia_transport_info_get_spc_info(&info, PJMEDIA_TRANSPORT_TYPE_SRTP)\n                if srtp_info == NULL or not bool(srtp_info.active):\n                    return None\n                return _pj_str_to_str(srtp_info.tx_policy.name)\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property zrtp_active:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_zrtp_info *zrtp_info\n            cdef pjmedia_transport_info info\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return False\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                    return False\n                self._get_info(&info)\n                zrtp_info = <pjmedia_zrtp_info *> pjmedia_transport_info_get_spc_info(&info, PJMEDIA_TRANSPORT_TYPE_ZRTP)\n                if zrtp_info != NULL:\n                    return bool(zrtp_info.active)\n                return False\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    cdef int _ice_active(self):\n        # this function needs to be called with the lock held\n        cdef pjmedia_transport_info info\n        cdef pjmedia_ice_transport_info *ice_info\n\n        if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n            return 0\n\n        self._get_info(&info)\n        ice_info = <pjmedia_ice_transport_info *> pjmedia_transport_info_get_spc_info(&info, PJMEDIA_TRANSPORT_TYPE_ICE)\n        if ice_info != NULL and ice_info.sess_state == PJ_ICE_STRANS_STATE_RUNNING:\n            return 1\n        return 0\n\n    property ice_active:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return False\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                return bool(self._ice_active())\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    cdef int _init_local_sdp(self, BaseSDPSession local_sdp, BaseSDPSession remote_sdp, int sdp_index):\n        cdef int status\n        cdef pj_pool_t *pool\n        cdef pjmedia_sdp_session *pj_local_sdp\n        cdef pjmedia_sdp_session *pj_remote_sdp\n        cdef pjmedia_transport *transport\n\n        pool = self._pool\n        transport = self._obj\n        pj_local_sdp = local_sdp.get_sdp_session()\n        if remote_sdp is not None:\n            pj_remote_sdp = remote_sdp.get_sdp_session()\n        else:\n            pj_remote_sdp = NULL\n        if sdp_index < 0:\n            raise ValueError(\"sdp_index argument cannot be negative\")\n        if sdp_index >= pj_local_sdp.media_count:\n            raise ValueError(\"sdp_index argument out of range\")\n        with nogil:\n            status = pjmedia_transport_media_create(transport, pool, 0, pj_remote_sdp, sdp_index)\n        if status != 0:\n            raise PJSIPError(\"Could not create media transport\", status)\n        return 0\n\n    def set_LOCAL(self, SDPSession local_sdp, int sdp_index):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n\n        _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if local_sdp is None:\n                raise SIPCoreError(\"local_sdp argument cannot be None\")\n            if self.state == \"LOCAL\":\n                return\n            if self.state != \"INIT\":\n                raise SIPCoreError('set_LOCAL can only be called in the \"INIT\" state, current state is \"%s\"' % self.state)\n            self._init_local_sdp(local_sdp, None, sdp_index)\n            self.state = \"LOCAL\"\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def set_REMOTE(self, BaseSDPSession local_sdp, BaseSDPSession remote_sdp, int sdp_index):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n\n        _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if None in [local_sdp, remote_sdp]:\n                raise SIPCoreError(\"SDP arguments cannot be None\")\n            if self.state == \"REMOTE\":\n                return\n            if self.state != \"INIT\":\n                raise SIPCoreError('set_REMOTE can only be called in the \"INIT\" state, current state is \"%s\"' % self.state)\n            self._init_local_sdp(local_sdp, remote_sdp, sdp_index)\n            self.state = \"REMOTE\"\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def set_ESTABLISHED(self, BaseSDPSession local_sdp, BaseSDPSession remote_sdp, int sdp_index):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_sdp_session *pj_local_sdp\n        cdef pjmedia_sdp_session *pj_remote_sdp\n        cdef pjmedia_transport *transport = self._obj\n\n        _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            transport = self._obj\n\n            if None in [local_sdp, remote_sdp]:\n                raise SIPCoreError(\"SDP arguments cannot be None\")\n            pj_local_sdp = local_sdp.get_sdp_session()\n            pj_remote_sdp = remote_sdp.get_sdp_session()\n            if self.state == \"ESTABLISHED\":\n                return\n            if self.state not in [\"LOCAL\", \"REMOTE\"]:\n                raise SIPCoreError('set_ESTABLISHED can only be called in the \"INIT\" and \"LOCAL\" states, ' +\n                                   'current state is \"%s\"' % self.state)\n            with nogil:\n                status = pjmedia_transport_media_start(transport, self._pool, pj_local_sdp, pj_remote_sdp, sdp_index)\n            if status != 0:\n                raise PJSIPError(\"Could not start media transport\", status)\n            self.state = \"ESTABLISHED\"\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def set_INIT(self):\n        global _ice_cb\n        cdef int af\n        cdef int i\n        cdef int status\n        cdef int port\n        cdef pj_caching_pool *caching_pool\n        cdef pj_ice_strans_cfg ice_cfg\n        cdef pj_ice_strans *ice_st\n        cdef pj_ice_strans_state ice_state\n        cdef pj_mutex_t *lock = self._lock\n        cdef pj_str_t local_ip\n        cdef pj_str_t *local_ip_address\n        cdef pjmedia_endpt *media_endpoint\n        cdef pjmedia_srtp_setting srtp_setting\n        cdef pjmedia_transport **transport_address\n        cdef pjmedia_transport *wrapped_transport\n        cdef pjsip_endpoint *sip_endpoint\n        cdef bytes zid_file\n        cdef char *c_zid_file\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            af = self._af\n            caching_pool = &ua._caching_pool._obj\n            media_endpoint = ua._pjmedia_endpoint._obj\n            sip_endpoint = ua._pjsip_endpoint._obj\n            transport_address = &self._obj\n\n            if self.state == \"INIT\":\n                return\n            if self.state in [\"LOCAL\", \"ESTABLISHED\"]:\n                with nogil:\n                    status = pjmedia_transport_media_stop(transport_address[0])\n                if status != 0:\n                    raise PJSIPError(\"Could not stop media transport\", status)\n                self.state = \"INIT\"\n            elif self.state == \"NULL\":\n                if ua.ip_address is None:\n                    local_ip_address = NULL\n                else:\n                    _str_to_pj_str(ua.ip_address, &local_ip)\n                    local_ip_address = &local_ip\n                if self.use_ice:\n                    with nogil:\n                        pj_ice_strans_cfg_default(&ice_cfg)\n                    ice_cfg.af = self._af\n                    with nogil:\n                        pj_stun_config_init(&ice_cfg.stun_cfg, &caching_pool.factory, 0,\n                                            pjmedia_endpt_get_ioqueue(media_endpoint),\n                                            pjsip_endpt_get_timer_heap(sip_endpoint))\n                    if self.ice_stun_address is not None:\n                        _str_to_pj_str(self.ice_stun_address, &ice_cfg.stun.server)\n                        ice_cfg.stun.port = self.ice_stun_port\n                    # IIRC we can't choose the port for ICE\n                    with nogil:\n                        status = pj_sockaddr_init(ice_cfg.af, &ice_cfg.stun.cfg.bound_addr, local_ip_address, 0)\n                    if status != 0:\n                        raise PJSIPError(\"Could not init ICE bound address\", status)\n                    with nogil:\n                        status = pjmedia_ice_create2(media_endpoint, NULL, 2, &ice_cfg, &_ice_cb, 0, transport_address)\n                    if status != 0:\n                        raise PJSIPError(\"Could not create ICE media transport\", status)\n                else:\n                    status = PJ_EBUG\n                    for i in xrange(ua._rtp_port_index, ua._rtp_port_index + ua._rtp_port_usable_count, 2):\n                        port = ua._rtp_port_start + i % ua._rtp_port_usable_count\n                        with nogil:\n                            status = pjmedia_transport_udp_create3(media_endpoint, af, NULL, local_ip_address,\n                                                                   port, 0, transport_address)\n                        if status != PJ_ERRNO_START_SYS + EADDRINUSE:\n                            ua._rtp_port_index = (i + 2) % ua._rtp_port_usable_count\n                            break\n                    if status != 0:\n                        raise PJSIPError(\"Could not create UDP/RTP media transport\", status)\n                self._obj.user_data = <void *> self.weakref\n                if self._encryption is not None:\n                    wrapped_transport = self._wrapped_transport = self._obj\n                    self._obj = NULL\n                    if self._encryption.startswith('sdes'):\n                        with nogil:\n                            pjmedia_srtp_setting_default(&srtp_setting)\n                        if self._encryption == 'sdes_mandatory':\n                            srtp_setting.use = PJMEDIA_SRTP_MANDATORY\n                        with nogil:\n                            status = pjmedia_transport_srtp_create(media_endpoint, wrapped_transport, &srtp_setting, transport_address)\n                        if status != 0:\n                            with nogil:\n                                pjmedia_transport_close(wrapped_transport)\n                            self._wrapped_transport = NULL\n                            raise PJSIPError(\"Could not create SRTP media transport\", status)\n                    elif self._encryption == 'zrtp':\n                        with nogil:\n                            status = pjmedia_transport_zrtp_create(media_endpoint, pjsip_endpt_get_timer_heap(sip_endpoint), wrapped_transport, transport_address, 1)\n                        if status == 0:\n                            zid_file = ua.zrtp_cache.encode(sys.getfilesystemencoding())\n                            c_zid_file = zid_file\n                            with nogil:\n                                # Auto-enable is deactivated\n                                status = pjmedia_transport_zrtp_initialize(self._obj, c_zid_file, 0, &_zrtp_cb)\n                        if status != 0:\n                            with nogil:\n                                pjmedia_transport_close(wrapped_transport)\n                            self._wrapped_transport = NULL\n                            raise PJSIPError(\"Could not create ZRTP media transport\", status)\n                    else:\n                        raise RuntimeError('invalid SRTP key negotiation specified: %s' % self._encryption)\n                    self._obj.user_data = <void *> self.weakref\n                if not self.use_ice or self.ice_stun_address is None:\n                    self.state = \"INIT\"\n                    _add_event(\"RTPTransportDidInitialize\", dict(obj=self))\n                else:\n                    self.state = \"WAIT_STUN\"\n                if self.use_ice:\n                    _add_event(\"RTPTransportICENegotiationStateDidChange\", dict(obj=self, prev_state=\"NULL\", state=\"GATHERING\"))\n                    ice_st = pjmedia_ice_get_strans(transport_address[0])\n                    if ice_st != NULL:\n                        ice_state = pj_ice_strans_get_state(ice_st)\n                        if ice_state == PJ_ICE_STRANS_STATE_READY:\n                            _add_event(\"RTPTransportICENegotiationStateDidChange\", dict(obj=self, prev_state=\"GATHERING\", state=\"GATHERING_COMPLETE\"))\n            else:\n                raise SIPCoreError('set_INIT can only be called in the \"NULL\", \"LOCAL\" and \"ESTABLISHED\" states, ' +\n                                   'current state is \"%s\"' % self.state)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def set_zrtp_sas_verified(self, verified):\n        cdef int status\n        cdef int c_verified\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_zrtp_info *zrtp_info\n        cdef pjmedia_transport_info info\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n        if ua is None:\n            return False\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                return False\n            self._get_info(&info)\n            zrtp_info = <pjmedia_zrtp_info *> pjmedia_transport_info_get_spc_info(&info, PJMEDIA_TRANSPORT_TYPE_ZRTP)\n            if zrtp_info == NULL or not bool(zrtp_info.active):\n                return False\n            c_verified = int(verified)\n            with nogil:\n                pjmedia_transport_zrtp_setSASVerified(self._obj, c_verified)\n            return True\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def set_zrtp_enabled(self, enabled, object master_stream):\n        cdef int status\n        cdef int c_enabled\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_zrtp_info *zrtp_info\n        cdef pjmedia_transport_info info\n        cdef PJSIPUA ua\n        cdef bytes multistream_params\n        cdef char *c_multistream_params\n        cdef int length\n        cdef RTPTransport master_transport\n\n        ua = self._check_ua()\n        if ua is None:\n            return\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                return\n            self._get_info(&info)\n            zrtp_info = <pjmedia_zrtp_info *> pjmedia_transport_info_get_spc_info(&info, PJMEDIA_TRANSPORT_TYPE_ZRTP)\n            if zrtp_info == NULL:\n                return\n            if master_stream is not None:\n                master_transport = master_stream._rtp_transport\n                assert master_transport is not None\n                # extract the multistream parameters\n                multistream_params = master_transport.zrtp_multistream_parameters\n                if multistream_params:\n                    # set multistream mode in ourselves\n                    c_multistream_params = multistream_params\n                    length = len(multistream_params)\n                    with nogil:\n                        pjmedia_transport_zrtp_setMultiStreamParameters(self._obj, c_multistream_params, length, master_transport._obj)\n            c_enabled = int(enabled)\n            with nogil:\n                pjmedia_transport_zrtp_setEnableZrtp(self._obj, c_enabled)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    property zrtp_multistream_parameters:\n\n        def __get__(self):\n            cdef int status\n            cdef char* c_name\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_zrtp_info *zrtp_info\n            cdef pjmedia_transport_info info\n            cdef PJSIPUA ua\n            cdef char *multistr_params\n            cdef int length\n\n            ua = self._check_ua()\n            if ua is None:\n                return None\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                    return None\n                self._get_info(&info)\n                zrtp_info = <pjmedia_zrtp_info *> pjmedia_transport_info_get_spc_info(&info, PJMEDIA_TRANSPORT_TYPE_ZRTP)\n                if zrtp_info == NULL or not bool(zrtp_info.active):\n                    return None\n                with nogil:\n                    multistr_params = pjmedia_transport_zrtp_getMultiStreamParameters(self._obj, &length)\n                if length > 0:\n                    ret = PyString_FromStringAndSize(multistr_params, length)\n                    free(multistr_params)\n                    return ret\n                else:\n                    return None\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property zrtp_cipher:\n\n        def __get__(self):\n            cdef int status\n            cdef char* c_name\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_zrtp_info *zrtp_info\n            cdef pjmedia_transport_info info\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return None\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                    return None\n                self._get_info(&info)\n                zrtp_info = <pjmedia_zrtp_info *> pjmedia_transport_info_get_spc_info(&info, PJMEDIA_TRANSPORT_TYPE_ZRTP)\n                if zrtp_info == NULL or not bool(zrtp_info.active):\n                    return None\n                return PyString_FromString(zrtp_info.cipher)\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property zrtp_peer_name:\n\n        def __get__(self):\n            cdef int status\n            cdef char* c_name\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_zrtp_info *zrtp_info\n            cdef pjmedia_transport_info info\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return ''\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                    return ''\n                self._get_info(&info)\n                zrtp_info = <pjmedia_zrtp_info *> pjmedia_transport_info_get_spc_info(&info, PJMEDIA_TRANSPORT_TYPE_ZRTP)\n                if zrtp_info == NULL or not bool(zrtp_info.active):\n                    return ''\n                with nogil:\n                    c_name = pjmedia_transport_zrtp_getPeerName(self._obj)\n                if c_name == NULL:\n                    return ''\n                else:\n                    name = PyUnicode_FromString(c_name) or u''\n                    free(c_name)\n                    return name\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n        def __set__(self, basestring name):\n            cdef int status\n            cdef char* c_name\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_zrtp_info *zrtp_info\n            cdef pjmedia_transport_info info\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                    return\n                self._get_info(&info)\n                zrtp_info = <pjmedia_zrtp_info *> pjmedia_transport_info_get_spc_info(&info, PJMEDIA_TRANSPORT_TYPE_ZRTP)\n                if zrtp_info == NULL or not bool(zrtp_info.active):\n                    return\n                name = name.encode('utf-8')\n                c_name = name\n                with nogil:\n                    pjmedia_transport_zrtp_putPeerName(self._obj, c_name)\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property zrtp_peer_id:\n\n        def __get__(self):\n            cdef int status\n            cdef unsigned char name[12]    # IDENTIFIER_LEN, 96bits\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_zrtp_info *zrtp_info\n            cdef pjmedia_transport_info info\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return None\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self.state in [\"NULL\", \"WAIT_STUN\", \"INVALID\"]:\n                    return None\n                self._get_info(&info)\n                zrtp_info = <pjmedia_zrtp_info *> pjmedia_transport_info_get_spc_info(&info, PJMEDIA_TRANSPORT_TYPE_ZRTP)\n                if zrtp_info == NULL or not bool(zrtp_info.active):\n                    return None\n                with nogil:\n                    status = pjmedia_transport_zrtp_getPeerZid(self._obj, name)\n                if status <= 0:\n                    return None\n                else:\n                    return PyString_FromStringAndSize(<char*>name, 12)\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    def update_local_sdp(self, SDPSession local_sdp, BaseSDPSession remote_sdp=None, int sdp_index=0):\n        cdef int status\n        cdef pj_pool_t *pool\n        cdef pjmedia_sdp_session *pj_local_sdp\n        cdef pjmedia_sdp_session *pj_remote_sdp\n        cdef pjmedia_transport *transport\n        cdef SDPMediaStream local_media\n\n        pool = self._pool\n        transport = self._obj\n        pj_local_sdp = local_sdp.get_sdp_session()\n        if remote_sdp is not None:\n            pj_remote_sdp = remote_sdp.get_sdp_session()\n        else:\n            pj_remote_sdp = NULL\n        if sdp_index < 0:\n            raise ValueError(\"sdp_index argument cannot be negative\")\n        if sdp_index >= pj_local_sdp.media_count:\n            raise ValueError(\"sdp_index argument out of range\")\n        # Remove ICE and SRTP/ZRTP related attributes from SDP, they will be added by pjmedia_transport_encode_sdp\n        local_media = local_sdp.media[sdp_index]\n        local_media.attributes = [<object> attr for attr in local_media.attributes if attr.name not in ('crypto', 'zrtp-hash', 'ice-ufrag', 'ice-pwd', 'ice-mismatch', 'candidate', 'remote-candidates')]\n        pj_local_sdp = local_sdp.get_sdp_session()\n        with nogil:\n            status = pjmedia_transport_encode_sdp(transport, pool, pj_local_sdp, pj_remote_sdp, sdp_index)\n        if status != 0:\n            raise PJSIPError(\"Could not update SDP for media transport\", status)\n        local_sdp._update()\n        return 0\n\n\ncdef class MediaCheckTimer(Timer):\n    def __init__(self, media_check_interval):\n        self.media_check_interval = media_check_interval\n\n\ncdef class SDPInfo:\n    def __init__(self, BaseSDPMediaStream local_media=None, BaseSDPSession local_sdp=None, BaseSDPSession remote_sdp=None, int index=0):\n        self.local_media = local_media\n        self.local_sdp = local_sdp\n        self.remote_sdp = remote_sdp\n        self.index = index\n\n    property local_media:\n\n        def __get__(self):\n            return self._local_media\n\n        def __set__(self, local_media):\n            if local_media is not None:\n                local_media = SDPMediaStream.new(local_media)\n            self._local_media = local_media\n\n    property local_sdp:\n\n        def __get__(self):\n            return self._local_sdp\n\n        def __set__(self, local_sdp):\n            if local_sdp is not None:\n                local_sdp = SDPSession.new(local_sdp)\n            self._local_sdp = local_sdp\n\n    property remote_sdp:\n\n        def __get__(self):\n            return self._remote_sdp\n\n        def __set__(self, remote_sdp):\n            if remote_sdp is not None:\n                remote_sdp = SDPSession.new(remote_sdp)\n            self._remote_sdp = remote_sdp\n\n\ncdef class AudioTransport:\n    def __cinit__(self, *args, **kwargs):\n        cdef int status\n        cdef pj_pool_t *pool\n        cdef bytes pool_name\n        cdef char* c_pool_name\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n        pool_name = b\"AudioTransport_%d\" % id(self)\n\n        self.weakref = weakref.ref(self)\n        Py_INCREF(self.weakref)\n\n        status = pj_mutex_create_recursive(ua._pjsip_endpoint._pool, \"audio_transport_lock\", &self._lock)\n        if status != 0:\n            raise PJSIPError(\"failed to create lock\", status)\n\n        pool = ua.create_memory_pool(pool_name, 4096, 4096)\n        self._pool = pool\n        self._slot = -1\n        self._timer = None\n        self._volume = 100\n\n    def __init__(self, AudioMixer mixer, RTPTransport transport,\n                 BaseSDPSession remote_sdp=None, int sdp_index=0, enable_silence_detection=False, list codecs=None):\n        cdef int status\n        cdef pj_pool_t *pool\n        cdef pjmedia_endpt *media_endpoint\n        cdef pjmedia_sdp_media *local_media_c\n        cdef pjmedia_sdp_session *local_sdp_c\n        cdef pj_sockaddr *addr\n        cdef pjmedia_transport_info info\n        cdef list global_codecs\n        cdef SDPMediaStream local_media\n        cdef SDPSession local_sdp\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n        media_endpoint = ua._pjmedia_endpoint._obj\n        pool = self._pool\n\n        if self.transport is not None:\n            raise SIPCoreError(\"AudioTransport.__init__() was already called\")\n        if mixer is None:\n            raise ValueError(\"mixer argument may not be None\")\n        if transport is None:\n            raise ValueError(\"transport argument cannot be None\")\n        if sdp_index < 0:\n            raise ValueError(\"sdp_index argument cannot be negative\")\n        if transport.state != \"INIT\":\n            raise SIPCoreError('RTPTransport object provided is not in the \"INIT\" state, but in the \"%s\" state' %\n                               transport.state)\n        self._vad = int(bool(enable_silence_detection))\n        self.mixer = mixer\n        self.transport = transport\n        transport._get_info(&info)\n        global_codecs = ua._pjmedia_endpoint._get_current_codecs()\n        if codecs is None:\n            codecs = global_codecs\n        try:\n            ua._pjmedia_endpoint._set_codecs(codecs)\n            addr = &info.sock_info.rtp_addr_name\n            with nogil:\n                status = pjmedia_endpt_create_base_sdp(media_endpoint, pool, NULL, addr, &local_sdp_c)\n            if status != 0:\n                raise PJSIPError(\"Could not generate base SDP\", status)\n            with nogil:\n                status = pjmedia_endpt_create_audio_sdp(media_endpoint, pool, &info.sock_info, 0, &local_media_c)\n            if status != 0:\n                raise PJSIPError(\"Could not generate SDP audio stream\", status)\n            # Create a 'fake' SDP, which only contains the audio stream, then the m line is extracted because the full\n            # SDP is built by the Session\n            local_sdp_c.media_count = 1\n            local_sdp_c.media[0] = local_media_c\n        finally:\n            ua._pjmedia_endpoint._set_codecs(global_codecs)\n        local_sdp = SDPSession_create(local_sdp_c)\n        local_media = local_sdp.media[0]\n        if remote_sdp is None:\n            self._is_offer = 1\n            self.transport.set_LOCAL(local_sdp, 0)\n        else:\n            self._is_offer = 0\n            if sdp_index != 0:\n                local_sdp.media = [None] * (sdp_index+1)\n                local_sdp.media[sdp_index] = local_media\n            self.transport.set_REMOTE(local_sdp, remote_sdp, sdp_index)\n        self._sdp_info = SDPInfo(local_media, local_sdp, remote_sdp, sdp_index)\n\n    def __dealloc__(self):\n        cdef PJSIPUA ua\n        cdef Timer timer\n        try:\n            ua = _get_ua()\n        except:\n            return\n        if self._obj != NULL:\n            self.stop()\n        ua.release_memory_pool(self._pool)\n        self._pool = NULL\n        if self._lock != NULL:\n            pj_mutex_destroy(self._lock)\n        timer = Timer()\n        try:\n            timer.schedule(60, deallocate_weakref, self.weakref)\n        except SIPCoreError:\n            pass\n\n    cdef PJSIPUA _check_ua(self):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n            return ua\n        except:\n            self._obj = NULL\n            self._pool = NULL\n            return None\n\n    property is_active:\n\n        def __get__(self):\n            self._check_ua()\n            return bool(self._obj != NULL)\n\n    property is_started:\n\n        def __get__(self):\n            return bool(self._is_started)\n\n    property codec:\n\n        def __get__(self):\n            self._check_ua()\n            if self._obj == NULL:\n                return None\n            else:\n                return _pj_str_to_str(self._stream_info.fmt.encoding_name)\n\n    property sample_rate:\n\n        def __get__(self):\n            self._check_ua()\n            if self._obj == NULL:\n                return None\n            else:\n                return self._stream_info.fmt.clock_rate\n\n    property enable_silence_detection:\n\n        def __get__(self):\n            return bool(self._vad)\n\n    property statistics:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_rtcp_stat stat\n            cdef pjmedia_stream *stream\n            cdef dict statistics = dict()\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return None\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                stream = self._obj\n\n                if stream == NULL:\n                    return None\n\n                with nogil:\n                    status = pjmedia_stream_get_stat(stream, &stat)\n                if status != 0:\n                    raise PJSIPError(\"Could not get RTP statistics\", status)\n                statistics[\"rtt\"] = _pj_math_stat_to_dict(&stat.rtt)\n                statistics[\"rx\"] = _pjmedia_rtcp_stream_stat_to_dict(&stat.rx)\n                statistics[\"tx\"] = _pjmedia_rtcp_stream_stat_to_dict(&stat.tx)\n                return statistics\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property volume:\n\n        def __get__(self):\n            return self._volume\n\n        def __set__(self, value):\n            cdef int slot\n            cdef int status\n            cdef int volume\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_conf *conf_bridge\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n\n            if ua is not None:\n                with nogil:\n                    status = pj_mutex_lock(lock)\n                if status != 0:\n                    raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                conf_bridge = self.mixer._obj\n                slot = self._slot\n\n                if value < 0:\n                    raise ValueError(\"volume attribute cannot be negative\")\n                if ua is not None and self._obj != NULL:\n                    volume = int(value * 1.28 - 128)\n                    with nogil:\n                        status = pjmedia_conf_adjust_rx_level(conf_bridge, slot, volume)\n                    if status != 0:\n                        raise PJSIPError(\"Could not set volume of audio transport\", status)\n                self._volume = value\n            finally:\n                if ua is not None:\n                    with nogil:\n                        pj_mutex_unlock(lock)\n\n    property slot:\n\n        def __get__(self):\n            self._check_ua()\n            if self._slot == -1:\n                return None\n            else:\n                return self._slot\n\n    def get_local_media(self, BaseSDPSession remote_sdp=None, int index=0, direction=\"sendrecv\"):\n        global valid_sdp_directions\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef object direction_attr\n        cdef SDPAttribute attr\n        cdef SDPSession local_sdp\n        cdef SDPMediaStream local_media\n        cdef pjmedia_sdp_media *c_local_media\n\n        _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            is_offer = remote_sdp is None\n            if is_offer and direction not in valid_sdp_directions:\n                raise SIPCoreError(\"Unknown direction: %s\" % direction)\n            self._sdp_info.index = index\n            local_sdp = self._sdp_info.local_sdp\n            local_media = self._sdp_info.local_media\n            local_sdp.media = [None] * (index+1)\n            local_sdp.media[index] = local_media\n            self.transport.update_local_sdp(local_sdp, remote_sdp, index)\n            # updating the local SDP might have modified the connection line\n            if local_sdp.connection is not None and local_media.connection is None:\n                local_media.connection = SDPConnection.new(local_sdp.connection)\n            local_media.attributes = [<object> attr for attr in local_media.attributes if attr.name not in valid_sdp_directions]\n            if is_offer:\n                direction_attr = direction\n            else:\n                if self.direction is None or \"recv\" in self.direction:\n                    direction_attr = \"sendrecv\"\n                else:\n                    direction_attr = \"sendonly\"\n            local_media.attributes.append(SDPAttribute(direction_attr, \"\"))\n            for attribute in local_media.attributes:\n                if attribute.name == 'rtcp':\n                    attribute.value = attribute.value.split(' ', 1)[0]\n            self._sdp_info.local_media = local_media\n            return local_media\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def start(self, BaseSDPSession local_sdp, BaseSDPSession remote_sdp, int sdp_index, int timeout=30):\n        cdef int status\n        cdef object desired_state\n        cdef pj_mutex_t *lock = self._lock\n        cdef pj_pool_t *pool\n        cdef pjmedia_endpt *media_endpoint\n        cdef pjmedia_port *media_port\n        cdef pjmedia_sdp_media *local_media\n        cdef pjmedia_sdp_session *pj_local_sdp\n        cdef pjmedia_sdp_session *pj_remote_sdp\n        cdef pjmedia_stream **stream_address\n        cdef pjmedia_stream_info *stream_info_address\n        cdef pjmedia_transport *transport\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            pool = self._pool\n            media_endpoint = ua._pjmedia_endpoint._obj\n            stream_address = &self._obj\n            stream_info_address = &self._stream_info\n            transport = self.transport._obj\n\n            if self._is_started:\n                raise SIPCoreError(\"This AudioTransport was already started once\")\n            desired_state = (\"LOCAL\" if self._is_offer else \"REMOTE\")\n            if self.transport.state != desired_state:\n                raise SIPCoreError('RTPTransport object provided is not in the \"%s\" state, but in the \"%s\" state' %\n                                   (desired_state, self.transport.state))\n            if None in [local_sdp, remote_sdp]:\n                raise ValueError(\"SDP arguments cannot be None\")\n            pj_local_sdp = local_sdp.get_sdp_session()\n            pj_remote_sdp = remote_sdp.get_sdp_session()\n            if sdp_index < 0:\n                raise ValueError(\"sdp_index argument cannot be negative\")\n            if local_sdp.media[sdp_index].port == 0 or remote_sdp.media[sdp_index].port == 0:\n                raise SIPCoreError(\"Cannot start a rejected audio stream\")\n            if timeout < 0:\n                raise ValueError(\"timeout value cannot be negative\")\n            self.transport.set_ESTABLISHED(local_sdp, remote_sdp, sdp_index)\n            with nogil:\n                status = pjmedia_stream_info_from_sdp(stream_info_address, pool, media_endpoint,\n                                                      pj_local_sdp, pj_remote_sdp, sdp_index)\n            if status != 0:\n                raise PJSIPError(\"Could not parse SDP for audio session\", status)\n            if self._stream_info.param == NULL:\n                raise SIPCoreError(\"Could not parse SDP for audio session\")\n            self._stream_info.param.setting.vad = self._vad\n            self._stream_info.use_ka = 1\n            with nogil:\n                status = pjmedia_stream_create(media_endpoint, pool, stream_info_address,\n                                               transport, NULL, stream_address)\n            if status != 0:\n                raise PJSIPError(\"Could not initialize RTP for audio session\", status)\n            with nogil:\n                status = pjmedia_stream_set_dtmf_callback(stream_address[0], _AudioTransport_cb_dtmf, <void *> self.weakref)\n            if status != 0:\n                with nogil:\n                    pjmedia_stream_destroy(stream_address[0])\n                self._obj = NULL\n                raise PJSIPError(\"Could not set DTMF callback for audio session\", status)\n            with nogil:\n                status = pjmedia_stream_start(stream_address[0])\n            if status != 0:\n                with nogil:\n                    pjmedia_stream_destroy(stream_address[0])\n                self._obj = NULL\n                raise PJSIPError(\"Could not start RTP for audio session\", status)\n            with nogil:\n                status = pjmedia_stream_get_port(stream_address[0], &media_port)\n            if status != 0:\n                with nogil:\n                    pjmedia_stream_destroy(stream_address[0])\n                self._obj = NULL\n                raise PJSIPError(\"Could not get audio port for audio session\", status)\n            try:\n                self._slot = self.mixer._add_port(ua, pool, media_port)\n                if self._volume != 100:\n                    self.volume = self._volume\n            except:\n                with nogil:\n                    pjmedia_stream_destroy(stream_address[0])\n                self._obj = NULL\n                raise\n            self.update_direction(local_sdp.media[sdp_index].direction)\n            self._sdp_info.local_media = local_sdp.media[sdp_index]\n            self._sdp_info.local_sdp = local_sdp\n            self._sdp_info.remote_sdp = remote_sdp\n            self._sdp_info.index = sdp_index\n            self._is_started = 1\n            if timeout > 0:\n                self._timer = MediaCheckTimer(timeout)\n                self._timer.schedule(timeout, <timer_callback>self._cb_check_rtp, self)\n            self.mixer.reset_ec()\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def stop(self):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_stream *stream\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n\n        if ua is not None:\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            stream = self._obj\n\n            if self._timer is not None:\n                self._timer.cancel()\n                self._timer = None\n            if self._obj == NULL:\n                return\n            self._obj = NULL\n            self.mixer._remove_port(ua, self._slot)\n            with nogil:\n                pjmedia_stream_destroy(stream)\n            self.transport.set_INIT()\n        finally:\n            if ua is not None:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    def update_direction(self, direction):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n\n        _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._obj == NULL:\n                raise SIPCoreError(\"Stream is not active\")\n            if direction not in valid_sdp_directions:\n                raise SIPCoreError(\"Unknown direction: %s\" % direction)\n            if direction != self.direction:\n                self.mixer.reset_ec()\n            self.direction = direction\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def update_sdp(self, local_sdp, remote_sdp, index):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n\n        _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._obj == NULL:\n                raise SIPCoreError(\"Stream is not active\")\n            self._sdp_info.local_media = local_sdp.media[index]\n            self._sdp_info.local_sdp = local_sdp\n            self._sdp_info.remote_sdp = remote_sdp\n            self._sdp_info.index = index\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def send_dtmf(self, digit):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pj_str_t digit_pj\n        cdef pjmedia_stream *stream\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            stream = self._obj\n\n            if self._obj == NULL:\n                raise SIPCoreError(\"Stream is not active\")\n            if len(digit) != 1 or digit not in \"0123456789*#ABCD\":\n                raise SIPCoreError(\"Not a valid DTMF digit: %s\" % digit)\n            _str_to_pj_str(digit, &digit_pj)\n            if not self._stream_info.tx_event_pt < 0:\n                # If the remote doesn't support telephone-event just don't send DTMF\n                with nogil:\n                    status = pjmedia_stream_dial_dtmf(stream, &digit_pj)\n                if status != 0:\n                    raise PJSIPError(\"Could not send DTMF digit on audio stream\", status)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    cdef int _cb_check_rtp(self, MediaCheckTimer timer) except -1:\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_rtcp_stat stat\n        cdef pjmedia_stream *stream\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            stream = self._obj\n            if stream == NULL:\n                return 0\n\n            if self._timer is None:\n                return 0\n            self._timer = None\n            with nogil:\n                status = pjmedia_stream_get_stat(stream, &stat)\n            if status == 0:\n                if self._packets_received == stat.rx.pkt and self.direction == \"sendrecv\":\n                    _add_event(\"RTPAudioTransportDidTimeout\", dict(obj=self))\n                self._packets_received = stat.rx.pkt\n                if timer.media_check_interval > 0:\n                    self._timer = MediaCheckTimer(timer.media_check_interval)\n                    self._timer.schedule(timer.media_check_interval, <timer_callback>self._cb_check_rtp, self)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n\ncdef class VideoTransport:\n\n    def __cinit__(self, *args, **kwargs):\n        cdef int status\n        cdef pj_pool_t *pool\n        cdef bytes pool_name\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n        endpoint = ua._pjsip_endpoint._obj\n        pool_name = b\"VideoTransport_%d\" % id(self)\n\n        self.weakref = weakref.ref(self)\n        Py_INCREF(self.weakref)\n\n        pool = ua.create_memory_pool(pool_name, 4096, 4096)\n        self._pool = pool\n\n        status = pj_mutex_create_recursive(pool, \"video_transport_lock\", &self._lock)\n        if status != 0:\n            raise PJSIPError(\"failed to create lock\", status)\n\n        self._timer = None\n\n    def __init__(self, RTPTransport transport, BaseSDPSession remote_sdp=None, int sdp_index=0, list codecs=None):\n        cdef int status\n        cdef pj_pool_t *pool\n        cdef pjmedia_endpt *media_endpoint\n        cdef pjmedia_sdp_media *local_media_c\n        cdef pjmedia_sdp_session *local_sdp_c\n        cdef pjmedia_transport_info info\n        cdef pj_sockaddr *addr\n        cdef list global_codecs\n        cdef SDPMediaStream local_media\n        cdef SDPSession local_sdp\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n        media_endpoint = ua._pjmedia_endpoint._obj\n        pool = self._pool\n\n        if self.transport is not None:\n            raise SIPCoreError(\"VideoTransport.__init__() was already called\")\n        if transport is None:\n            raise ValueError(\"transport argument cannot be None\")\n        if sdp_index < 0:\n            raise ValueError(\"sdp_index argument cannot be negative\")\n        if transport.state != \"INIT\":\n            raise SIPCoreError('RTPTransport object provided is not in the \"INIT\" state, but in the \"%s\" state' % transport.state)\n        self.transport = transport\n        transport._get_info(&info)\n        global_codecs = ua._pjmedia_endpoint._get_current_video_codecs()\n        if codecs is None:\n            codecs = global_codecs\n        try:\n            ua._pjmedia_endpoint._set_video_codecs(codecs)\n            addr = &(info.sock_info.rtp_addr_name)\n            with nogil:\n                status = pjmedia_endpt_create_base_sdp(media_endpoint, pool, NULL, addr, &local_sdp_c)\n            if status != 0:\n                raise PJSIPError(\"Could not generate base SDP\", status)\n            with nogil:\n                status = pjmedia_endpt_create_video_sdp(media_endpoint, pool, &info.sock_info, 0, &local_media_c)\n            if status != 0:\n                raise PJSIPError(\"Could not generate SDP video stream\", status)\n            # Create a 'fake' SDP, which only contains the video stream, then the m line is extracted because the full\n            # SDP is built by the Session\n            local_sdp_c.media_count = 1\n            local_sdp_c.media[0] = local_media_c\n        finally:\n            ua._pjmedia_endpoint._set_video_codecs(global_codecs)\n        local_sdp = SDPSession_create(local_sdp_c)\n        local_media = local_sdp.media[0]\n        if remote_sdp is None:\n            self._is_offer = 1\n            self.transport.set_LOCAL(local_sdp, 0)\n        else:\n            self._is_offer = 0\n            if sdp_index != 0:\n                local_sdp.media = [None] * (sdp_index+1)\n                local_sdp.media[sdp_index] = local_media\n            self.transport.set_REMOTE(local_sdp, remote_sdp, sdp_index)\n        self._sdp_info = SDPInfo(local_media, local_sdp, remote_sdp, sdp_index)\n\n        self.local_video = None\n        self.remote_video = None\n\n    def __dealloc__(self):\n        cdef PJSIPUA ua\n        cdef Timer timer\n        try:\n            ua = _get_ua()\n        except SIPCoreError:\n            return\n        if self._obj != NULL:\n            self.stop()\n        if self._lock != NULL:\n            pj_mutex_destroy(self._lock)\n        ua.release_memory_pool(self._pool)\n        self._pool = NULL\n        timer = Timer()\n        try:\n            timer.schedule(60, deallocate_weakref, self.weakref)\n        except SIPCoreError:\n            pass\n\n    cdef PJSIPUA _check_ua(self):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n            return ua\n        except:\n            self._obj = NULL\n            self._pool = NULL\n            return None\n\n    property is_active:\n\n        def __get__(self):\n            self._check_ua()\n            return bool(self._obj != NULL)\n\n    property is_started:\n\n        def __get__(self):\n            return bool(self._is_started)\n\n    property codec:\n\n        def __get__(self):\n            self._check_ua()\n            if self._obj == NULL:\n                return None\n            else:\n                return _pj_str_to_str(self._stream_info.codec_info.encoding_name)\n\n    property sample_rate:\n\n        def __get__(self):\n            self._check_ua()\n            if self._obj == NULL:\n                return None\n            else:\n                return self._stream_info.codec_info.clock_rate\n\n    property statistics:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_rtcp_stat stat\n            cdef pjmedia_vid_stream *stream\n            cdef dict statistics = dict()\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n            if ua is None:\n                return None\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                stream = self._obj\n\n                if stream == NULL:\n                    return None\n\n                with nogil:\n                    status = pjmedia_vid_stream_get_stat(stream, &stat)\n                if status != 0:\n                    raise PJSIPError(\"Could not get RTP statistics\", status)\n                statistics[\"rtt\"] = _pj_math_stat_to_dict(&stat.rtt)\n                statistics[\"rx\"] = _pjmedia_rtcp_stream_stat_to_dict(&stat.rx)\n                statistics[\"tx\"] = _pjmedia_rtcp_stream_stat_to_dict(&stat.tx)\n                return statistics\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    def get_local_media(self, BaseSDPSession remote_sdp=None, int index=0, direction=\"sendrecv\"):\n        global valid_sdp_directions\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef object direction_attr\n        cdef SDPAttribute attr\n        cdef SDPSession local_sdp\n        cdef SDPMediaStream local_media\n        cdef pjmedia_sdp_media *c_local_media\n\n        _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            is_offer = remote_sdp is None\n            if is_offer and direction not in valid_sdp_directions:\n                raise SIPCoreError(\"Unknown direction: %s\" % direction)\n            self._sdp_info.index = index\n            local_sdp = self._sdp_info.local_sdp\n            local_media = self._sdp_info.local_media\n            local_sdp.media = [None] * (index+1)\n            local_sdp.media[index] = local_media\n            self.transport.update_local_sdp(local_sdp, remote_sdp, index)\n            # updating the local SDP might have modified the connection line\n            if local_sdp.connection is not None and local_media.connection is None:\n                local_media.connection = SDPConnection.new(local_sdp.connection)\n            local_media.attributes = [<object> attr for attr in local_media.attributes if attr.name not in valid_sdp_directions]\n            if is_offer:\n                direction_attr = direction\n            else:\n                if self.direction is None or \"recv\" in self.direction:\n                    direction_attr = \"sendrecv\"\n                else:\n                    direction_attr = \"sendonly\"\n            local_media.attributes.append(SDPAttribute(direction_attr, \"\"))\n            for attribute in local_media.attributes:\n                if attribute.name == 'rtcp':\n                    attribute.value = attribute.value.split(' ', 1)[0]\n            return local_media\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def start(self, BaseSDPSession local_sdp, BaseSDPSession remote_sdp, int sdp_index, int timeout=30):\n        cdef int status\n        cdef object desired_state\n        cdef pj_mutex_t *lock = self._lock\n        cdef pj_pool_t *pool\n        cdef pjmedia_endpt *media_endpoint\n        cdef pjmedia_sdp_media *local_media\n        cdef pjmedia_sdp_session *pj_local_sdp\n        cdef pjmedia_sdp_session *pj_remote_sdp\n        cdef pjmedia_vid_stream *stream\n        cdef pjmedia_vid_stream_info *stream_info\n        cdef pjmedia_transport *transport\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            pool = self._pool\n            media_endpoint = ua._pjmedia_endpoint._obj\n            stream_info = &self._stream_info\n            transport = self.transport._obj\n\n            if self._is_started:\n                raise SIPCoreError(\"This VideoTransport was already started once\")\n            desired_state = (\"LOCAL\" if self._is_offer else \"REMOTE\")\n            if self.transport.state != desired_state:\n                raise SIPCoreError('RTPTransport object provided is not in the \"%s\" state, but in the \"%s\" state' % (desired_state, self.transport.state))\n            if None in (local_sdp, remote_sdp):\n                raise ValueError(\"SDP arguments cannot be None\")\n            pj_local_sdp = local_sdp.get_sdp_session()\n            pj_remote_sdp = remote_sdp.get_sdp_session()\n            if sdp_index < 0:\n                raise ValueError(\"sdp_index argument cannot be negative\")\n            if local_sdp.media[sdp_index].port == 0 or remote_sdp.media[sdp_index].port == 0:\n                raise SIPCoreError(\"Cannot start a rejected video stream\")\n            if timeout < 0:\n                raise ValueError(\"timeout value cannot be negative\")\n            self.transport.set_ESTABLISHED(local_sdp, remote_sdp, sdp_index)\n            with nogil:\n                status = pjmedia_vid_stream_info_from_sdp(stream_info, pool, media_endpoint, pj_local_sdp, pj_remote_sdp, sdp_index)\n            if status != 0:\n                raise PJSIPError(\"Could not parse SDP for video session\", status)\n            if self._stream_info.codec_param == NULL:\n                raise SIPCoreError(\"Could not parse SDP for video session\")\n            self._stream_info.use_ka = 1\n            with nogil:\n                status = pjmedia_vid_stream_create(media_endpoint, pool, stream_info, transport, NULL, &stream)\n            if status != 0:\n                raise PJSIPError(\"Could not initialize RTP for video session\", status)\n            self._obj = stream\n            with nogil:\n                status = pjmedia_vid_stream_start(stream)\n            if status != 0:\n                with nogil:\n                    pjmedia_vid_stream_destroy(stream)\n                self._obj = NULL\n                raise PJSIPError(\"Could not start RTP for video session\", status)\n            with nogil:\n                pjmedia_vid_stream_send_rtcp_sdes(stream)\n            try:\n                local_video = LocalVideoStream_create(stream)\n                remote_video = RemoteVideoStream_create(stream, self._remote_video_event_handler)\n            except PJSIPError:\n                with nogil:\n                    pjmedia_vid_stream_destroy(stream)\n                self._obj = NULL\n                self.local_video = None\n                self.remote_video = None\n                raise\n            self.local_video = local_video\n            self.remote_video = remote_video\n            self.update_direction(local_sdp.media[sdp_index].direction)\n            self._sdp_info.local_media = local_sdp.media[sdp_index]\n            self._sdp_info.local_sdp = local_sdp\n            self._sdp_info.remote_sdp = remote_sdp\n            self._sdp_info.index = sdp_index\n            self._is_started = 1\n            if timeout > 0:\n                self._timer = MediaCheckTimer(timeout)\n                self._timer.schedule(timeout, <timer_callback>self._cb_check_rtp, self)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def stop(self):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_vid_stream *stream\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n\n        if ua is not None:\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            stream = self._obj\n\n            if self._timer is not None:\n                self._timer.cancel()\n                self._timer = None\n            if self._obj == NULL:\n                return\n            self._obj = NULL\n            if self.local_video is not None:\n                self.local_video.close()\n                self.local_video = None\n            if self.remote_video is not None:\n                self.remote_video.close()\n                self.remote_video = None\n            with nogil:\n                pjmedia_vid_stream_send_rtcp_bye(stream)\n                pjmedia_vid_stream_destroy(stream)\n            self.transport.set_INIT()\n        finally:\n            if ua is not None:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    def update_direction(self, direction):\n        global valid_sdp_directions\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_vid_stream *stream\n\n        _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            stream = self._obj\n\n            if self._obj == NULL:\n                raise SIPCoreError(\"Stream is not active\")\n            if direction not in valid_sdp_directions:\n                raise SIPCoreError(\"Unknown direction: %s\" % direction)\n            self.direction = direction\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def update_sdp(self, local_sdp, remote_sdp, index):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n\n        _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._obj == NULL:\n                raise SIPCoreError(\"Stream is not active\")\n            self._sdp_info.local_media = local_sdp.media[index]\n            self._sdp_info.local_sdp = local_sdp\n            self._sdp_info.remote_sdp = remote_sdp\n            self._sdp_info.index = index\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def pause(self, direction=\"both\"):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_vid_stream *stream\n        cdef pjmedia_dir pj_dir\n\n        _get_ua()\n\n        if direction not in (\"incoming\", \"outgoing\", \"both\"):\n            raise ValueError(\"direction can only be one of 'incoming', 'outgoing' or 'both'\")\n\n        if direction == \"incoming\":\n            pj_dir = PJMEDIA_DIR_RENDER\n        elif direction == \"outgoing\":\n            pj_dir = PJMEDIA_DIR_CAPTURE\n        else:\n            pj_dir = PJMEDIA_DIR_CAPTURE_RENDER\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            stream = self._obj\n            if self._obj == NULL:\n                raise SIPCoreError(\"Stream is not active\")\n            with nogil:\n                status = pjmedia_vid_stream_pause(stream, pj_dir)\n            if status != 0:\n                raise PJSIPError(\"failed to pause video stream\", status)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def resume(self, direction=\"both\"):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_vid_stream *stream\n        cdef pjmedia_dir pj_dir\n\n        _get_ua()\n\n        if direction not in (\"incoming\", \"outgoing\", \"both\"):\n            raise ValueError(\"direction can only be one of 'incoming', 'outgoing' or 'both'\")\n\n        if direction == \"incoming\":\n            pj_dir = PJMEDIA_DIR_RENDER\n        elif direction == \"outgoing\":\n            pj_dir = PJMEDIA_DIR_CAPTURE\n        else:\n            pj_dir = PJMEDIA_DIR_CAPTURE_RENDER\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            stream = self._obj\n            if self._obj == NULL:\n                raise SIPCoreError(\"Stream is not active\")\n            with nogil:\n                status = pjmedia_vid_stream_resume(stream, pj_dir)\n            if status != 0:\n                raise PJSIPError(\"failed to resume video stream\", status)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def send_keyframe(self):\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_vid_stream *stream\n\n        _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            stream = self._obj\n            if stream != NULL:\n                # Do not check for errors, it's OK if we can't send it\n                pjmedia_vid_stream_send_keyframe(stream)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def request_keyframe(self):\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_vid_stream *stream\n\n        _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            stream = self._obj\n            if stream != NULL:\n                # Do not check for errors, it's OK if we can't send it\n                pjmedia_vid_stream_send_rtcp_pli(stream)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    cdef int _cb_check_rtp(self, MediaCheckTimer timer) except -1:\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_rtcp_stat stat\n        cdef pjmedia_vid_stream *stream\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            stream = self._obj\n            if stream == NULL:\n                return 0\n            if self._timer is None:\n                return 0\n            self._timer = None\n            with nogil:\n                status = pjmedia_vid_stream_get_stat(stream, &stat)\n            if status == 0:\n                if self._packets_received == stat.rx.pkt and self.direction == \"sendrecv\":\n                    _add_event(\"RTPVideoTransportDidTimeout\", dict(obj=self))\n                self._packets_received = stat.rx.pkt\n                if timer.media_check_interval > 0:\n                    self._timer = MediaCheckTimer(timer.media_check_interval)\n                    self._timer.schedule(timer.media_check_interval, <timer_callback>self._cb_check_rtp, self)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def _remote_video_event_handler(self, str name, object data):\n        if name == \"FORMAT_CHANGED\":\n            size, framerate = data\n            _add_event(\"RTPVideoTransportRemoteFormatDidChange\", dict(obj=self, size=size, framerate=framerate))\n        elif name == \"RECEIVED_KEYFRAME\":\n            _add_event(\"RTPVideoTransportReceivedKeyFrame\", dict(obj=self))\n        elif name == \"MISSED_KEYFRAME\":\n            _add_event(\"RTPVideoTransportMissedKeyFrame\", dict(obj=self))\n        elif name == \"REQUESTED_KEYFRAME\":\n            _add_event(\"RTPVideoTransportRequestedKeyFrame\", dict(obj=self))\n\n\ncdef class ICECandidate:\n    def __init__(self, component, cand_type, address, port, priority, rel_addr=''):\n        self.component = component\n        self.type = cand_type\n        self.address = address\n        self.port = port\n        self.priority = priority\n        self.rel_address = rel_addr\n\n    def __str__(self):\n        return '(%s) %s:%d%s priority=%d type=%s' % (self.component,\n                                                     self.address,\n                                                     self.port,\n                                                     ' rel_addr=%s' % self.rel_address if self.rel_address else '',\n                                                     self.priority,\n                                                     self.type.lower())\n\ncdef ICECandidate ICECandidate_create(pj_ice_sess_cand *cand):\n    cdef char buf[PJ_INET6_ADDRSTRLEN]\n    cdef str address\n    cdef str cand_type\n    cdef int port\n\n    if cand.type == PJ_ICE_CAND_TYPE_HOST:\n        cand_type = 'HOST'\n    elif cand.type == PJ_ICE_CAND_TYPE_SRFLX:\n        cand_type = 'SRFLX'\n    elif cand.type == PJ_ICE_CAND_TYPE_PRFLX:\n        cand_type = 'PRFLX'\n    elif cand.type == PJ_ICE_CAND_TYPE_RELAYED:\n        cand_type = 'RELAY'\n    else:\n        cand_type = 'UNKNOWN'\n\n    pj_sockaddr_print(&cand.addr, buf, PJ_INET6_ADDRSTRLEN, 0)\n    address = PyString_FromString(buf)\n    port = pj_sockaddr_get_port(&cand.addr)\n    if pj_sockaddr_has_addr(&cand.rel_addr):\n        pj_sockaddr_print(&cand.rel_addr, buf, PJ_INET6_ADDRSTRLEN, 0)\n        rel_addr = PyString_FromString(buf)\n    else:\n        rel_addr = ''\n\n    return ICECandidate('RTP' if cand.comp_id==1 else 'RTCP', cand_type, address, port, cand.prio, rel_addr)\n\n\ncdef class ICECheck:\n    def __init__(self, local_candidate, remote_candidate, state, nominated):\n        self.local_candidate = local_candidate\n        self.remote_candidate = remote_candidate\n        self.state = state\n        self.nominated = nominated\n\n    def __str__(self):\n        return '%s:%d -> %s:%d (%s, %s)' % (self.local_candidate.address, self.local_candidate.port,\n                                            self.remote_candidate.address, self.remote_candidate.port,\n                                            self.state.lower(), 'nominated' if self.nominated else 'not nominated')\n\ncdef ICECheck ICECheck_create(pj_ice_sess_check *check):\n    cdef str state\n    cdef ICECandidate lcand\n    cdef ICECandidate rcand\n\n    if check.state == PJ_ICE_SESS_CHECK_STATE_FROZEN:\n        state = 'FROZEN'\n    elif check.state == PJ_ICE_SESS_CHECK_STATE_WAITING:\n        state = 'WAITING'\n    elif check.state == PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS:\n        state = 'IN_PROGRESS'\n    elif check.state == PJ_ICE_SESS_CHECK_STATE_SUCCEEDED:\n        state = 'SUCCEEDED'\n    elif check.state == PJ_ICE_SESS_CHECK_STATE_FAILED:\n        state = 'FAILED'\n    else:\n        state = 'UNKNOWN'\n\n    lcand = ICECandidate_create(check.lcand)\n    rcand = ICECandidate_create(check.rcand)\n\n    return ICECheck(lcand, rcand, state, bool(check.nominated))\n\ncdef ICECheck _get_rtp_valid_pair(pj_ice_strans *ice_st):\n    cdef pj_ice_sess_check_ptr_const ice_check\n\n    ice_check = pj_ice_strans_get_valid_pair(ice_st, 1)\n    if ice_check == NULL:\n        return None\n    return ICECheck_create(<pj_ice_sess_check*>ice_check)\n\n\n# helper functions\n\ncdef dict _pj_math_stat_to_dict(pj_math_stat *stat):\n    cdef dict retval = dict()\n    retval[\"count\"] = stat.n\n    retval[\"max\"] = stat.max\n    retval[\"min\"] = stat.min\n    retval[\"last\"] = stat.last\n    retval[\"avg\"] = stat.mean\n    return retval\n\ncdef dict _pjmedia_rtcp_stream_stat_to_dict(pjmedia_rtcp_stream_stat *stream_stat):\n    cdef dict retval = dict()\n    retval[\"packets\"] = stream_stat.pkt\n    retval[\"bytes\"] = stream_stat.bytes\n    retval[\"packets_discarded\"] = stream_stat.discard\n    retval[\"packets_lost\"] = stream_stat.loss\n    retval[\"packets_reordered\"] = stream_stat.reorder\n    retval[\"packets_duplicate\"] = stream_stat.dup\n    retval[\"loss_period\"] = _pj_math_stat_to_dict(&stream_stat.loss_period)\n    retval[\"burst_loss\"] = bool(stream_stat.loss_type.burst)\n    retval[\"random_loss\"] = bool(stream_stat.loss_type.random)\n    retval[\"jitter\"] = _pj_math_stat_to_dict(&stream_stat.jitter)\n    return retval\n\ncdef str _ice_state_to_str(int state):\n    if state == PJ_ICE_STRANS_STATE_NULL:\n        return 'NULL'\n    elif state == PJ_ICE_STRANS_STATE_INIT:\n        return 'GATHERING'\n    elif state == PJ_ICE_STRANS_STATE_READY:\n        return 'GATHERING_COMPLETE'\n    elif state == PJ_ICE_STRANS_STATE_SESS_READY:\n        return 'NEGOTIATION_START'\n    elif state == PJ_ICE_STRANS_STATE_NEGO:\n        return 'NEGOTIATING'\n    elif state == PJ_ICE_STRANS_STATE_RUNNING:\n        return 'RUNNING'\n    elif state == PJ_ICE_STRANS_STATE_FAILED:\n        return 'FAILED'\n    else:\n        return 'UNKNOWN'\n\ncdef dict _extract_ice_session_data(pj_ice_sess *ice_sess):\n    cdef dict data = dict()\n    cdef pj_ice_sess_cand *cand\n    cdef pj_ice_sess_check *check\n\n    # Process local candidates\n    local_candidates = []\n    for i in range(ice_sess.lcand_cnt):\n        cand = &ice_sess.lcand[i]\n        local_candidates.append(ICECandidate_create(cand))\n    data['local_candidates'] = local_candidates\n\n    # Process remote candidates\n    remote_candidates = []\n    for i in range(ice_sess.rcand_cnt):\n        cand = &ice_sess.rcand[i]\n        remote_candidates.append(ICECandidate_create(cand))\n    data['remote_candidates'] = remote_candidates\n\n    # Process valid pairs\n    valid_pairs = []\n    for i in range(ice_sess.comp_cnt):\n        check = ice_sess.comp[i].valid_check\n        valid_pairs.append(ICECheck_create(check))\n    data['valid_pairs'] = valid_pairs\n\n    # Process valid list\n    valid_list = []\n    for i in range(ice_sess.valid_list.count):\n        check = &ice_sess.valid_list.checks[i]\n        valid_list.append(ICECheck_create(check))\n    data['valid_list'] = valid_list\n\n    return data\n\ncdef object _extract_rtp_transport(pjmedia_transport *tp):\n    cdef void *rtp_transport_ptr = NULL\n\n    if tp != NULL:\n        rtp_transport_ptr = tp.user_data\n    if rtp_transport_ptr == NULL:\n        return None\n    return (<object> rtp_transport_ptr)()\n\n# callback functions\n\ncdef void _RTPTransport_cb_ice_complete(pjmedia_transport *tp, pj_ice_strans_op op, int status) with gil:\n    # Despite the name this callback is not only called when ICE negotiation ends, it depends on the\n    # op parameter\n    cdef int lock_status\n    cdef double duration\n    cdef pj_ice_strans *ice_st\n    cdef pj_ice_sess *ice_sess\n    cdef pj_time_val tv, start_time\n    cdef pj_mutex_t *lock\n    cdef RTPTransport rtp_transport\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n\n    rtp_transport = _extract_rtp_transport(tp)\n    if rtp_transport is None:\n        return\n\n    lock = rtp_transport._lock\n    with nogil:\n        lock_status = pj_mutex_lock(lock)\n    if lock_status != 0:\n        raise PJSIPError(\"failed to acquire lock\", status)\n\n    try:\n        if op == PJ_ICE_STRANS_OP_NEGOTIATION:\n            if status == 0:\n                ice_st = pjmedia_ice_get_strans(tp)\n                if ice_st == NULL:\n                    return\n                ice_sess = pj_ice_strans_get_session(ice_st)\n                if ice_sess == NULL:\n                    return\n                start_time = pj_ice_strans_get_start_time(ice_st)\n                pj_gettimeofday(&tv)\n                tv.sec -= start_time.sec\n                tv.msec -= start_time.msec\n                pj_time_val_normalize(&tv)\n                duration = (tv.sec*1000 + tv.msec)/1000.0\n                data = _extract_ice_session_data(ice_sess)\n                rtp_transport._rtp_valid_pair = _get_rtp_valid_pair(ice_st)\n                _add_event(\"RTPTransportICENegotiationDidSucceed\", dict(obj=rtp_transport,\n                                                                        duration=duration,\n                                                                        local_candidates=data['local_candidates'],\n                                                                        remote_candidates=data['remote_candidates'],\n                                                                        valid_pairs=data['valid_pairs'],\n                                                                        valid_list=data['valid_list']))\n            else:\n                rtp_transport._rtp_valid_pair = None\n                _add_event(\"RTPTransportICENegotiationDidFail\", dict(obj=rtp_transport, reason=_pj_status_to_str(status)))\n        elif op == PJ_ICE_STRANS_OP_INIT:\n            if status == 0:\n                rtp_transport.state = \"INIT\"\n                _add_event(\"RTPTransportDidInitialize\", dict(obj=rtp_transport))\n            else:\n                rtp_transport.state = \"INVALID\"\n                _add_event(\"RTPTransportDidFail\", dict(obj=rtp_transport, reason=_pj_status_to_str(status)))\n        else:\n            # silence compiler warning\n            pass\n    finally:\n        with nogil:\n            pj_mutex_unlock(lock)\n\n\ncdef void _RTPTransport_cb_ice_state(pjmedia_transport *tp, pj_ice_strans_state prev, pj_ice_strans_state curr) with gil:\n    cdef int status\n    cdef pj_mutex_t *lock\n    cdef RTPTransport rtp_transport\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n\n    rtp_transport = _extract_rtp_transport(tp)\n    if rtp_transport is None:\n        return\n\n    lock = rtp_transport._lock\n    with nogil:\n        status = pj_mutex_lock(lock)\n    if status != 0:\n        raise PJSIPError(\"failed to acquire lock\", status)\n\n    try:\n        _add_event(\"RTPTransportICENegotiationStateDidChange\", dict(obj=rtp_transport,\n                                                                    prev_state=_ice_state_to_str(prev),\n                                                                    state=_ice_state_to_str(curr)))\n    finally:\n        with nogil:\n            pj_mutex_unlock(lock)\n\n\ncdef void _RTPTransport_cb_ice_stop(pjmedia_transport *tp, char *reason, int err) with gil:\n    cdef int status\n    cdef pj_mutex_t *lock\n    cdef RTPTransport rtp_transport\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n\n    rtp_transport = _extract_rtp_transport(tp)\n    if rtp_transport is None:\n        return\n\n    lock = rtp_transport._lock\n    with nogil:\n        status = pj_mutex_lock(lock)\n    if status != 0:\n        raise PJSIPError(\"failed to acquire lock\", status)\n\n    try:\n        rtp_transport._rtp_valid_pair = None\n        _reason = reason\n        if _reason != b\"media stop requested\":\n            _add_event(\"RTPTransportICENegotiationDidFail\", dict(obj=rtp_transport, reason=_reason))\n    finally:\n        with nogil:\n            pj_mutex_unlock(lock)\n\n\ncdef void _RTPTransport_cb_zrtp_secure_on(pjmedia_transport *tp, char* cipher) with gil:\n   cdef RTPTransport rtp_transport\n   cdef PJSIPUA ua\n   try:\n       ua = _get_ua()\n   except:\n       return\n   try:\n       rtp_transport = _extract_rtp_transport(tp)\n       if rtp_transport is None:\n           return\n       _add_event(\"RTPTransportZRTPSecureOn\", dict(obj=rtp_transport, cipher=bytes(cipher)))\n   except:\n       ua._handle_exception(1)\n\ncdef void _RTPTransport_cb_zrtp_secure_off(pjmedia_transport *tp) with gil:\n   cdef RTPTransport rtp_transport\n   cdef PJSIPUA ua\n   try:\n       ua = _get_ua()\n   except:\n       return\n   try:\n       rtp_transport = _extract_rtp_transport(tp)\n       if rtp_transport is None:\n           return\n       _add_event(\"RTPTransportZRTPSecureOff\", dict(obj=rtp_transport))\n   except:\n       ua._handle_exception(1)\n\ncdef void _RTPTransport_cb_zrtp_show_sas(pjmedia_transport *tp, char* sas, int verified) with gil:\n   cdef RTPTransport rtp_transport\n   cdef PJSIPUA ua\n   try:\n       ua = _get_ua()\n   except:\n       return\n   try:\n       rtp_transport = _extract_rtp_transport(tp)\n       if rtp_transport is None:\n           return\n       _add_event(\"RTPTransportZRTPReceivedSAS\", dict(obj=rtp_transport, sas=str(sas), verified=bool(verified)))\n   except:\n       ua._handle_exception(1)\n\ncdef void _RTPTransport_cb_zrtp_confirm_goclear(pjmedia_transport *tp) with gil:\n   cdef RTPTransport rtp_transport\n   cdef PJSIPUA ua\n   try:\n       ua = _get_ua()\n   except:\n       return\n   try:\n       rtp_transport = _extract_rtp_transport(tp)\n       if rtp_transport is None:\n           return\n       # TODO: not yet implemented by PJSIP's ZRTP transport\n   except:\n       ua._handle_exception(1)\n\ncdef void _RTPTransport_cb_zrtp_show_message(pjmedia_transport *tp, int severity, int sub_code) with gil:\n    global zrtp_message_levels, zrtp_error_messages\n    cdef RTPTransport rtp_transport\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        rtp_transport = _extract_rtp_transport(tp)\n        if rtp_transport is None:\n            return\n        level = zrtp_message_levels.get(severity, 1)\n        message = zrtp_error_messages[level].get(sub_code, 'Unknown')\n        _add_event(\"RTPTransportZRTPLog\", dict(obj=rtp_transport, level=level, message=message))\n    except:\n        ua._handle_exception(1)\n\ncdef void _RTPTransport_cb_zrtp_negotiation_failed(pjmedia_transport *tp, int severity, int sub_code) with gil:\n    global zrtp_message_levels, zrtp_error_messages\n    cdef RTPTransport rtp_transport\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        rtp_transport = _extract_rtp_transport(tp)\n        if rtp_transport is None:\n            return\n        level = zrtp_message_levels.get(severity, 1)\n        reason = zrtp_error_messages[level].get(sub_code, 'Unknown')\n        _add_event(\"RTPTransportZRTPNegotiationFailed\", dict(obj=rtp_transport, reason=reason))\n    except:\n        ua._handle_exception(1)\n\ncdef void _RTPTransport_cb_zrtp_not_supported_by_other(pjmedia_transport *tp) with gil:\n    cdef RTPTransport rtp_transport\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        rtp_transport = _extract_rtp_transport(tp)\n        if rtp_transport is None:\n            return\n        _add_event(\"RTPTransportZRTPNotSupportedByRemote\", dict(obj=rtp_transport))\n    except:\n        ua._handle_exception(1)\n\ncdef void _RTPTransport_cb_zrtp_ask_enrollment(pjmedia_transport *tp, int info) with gil:\n    cdef RTPTransport rtp_transport\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        rtp_transport = _extract_rtp_transport(tp)\n        if rtp_transport is None:\n            return\n        # TODO: implement PBX enrollment\n    except:\n        ua._handle_exception(1)\n\ncdef void _RTPTransport_cb_zrtp_inform_enrollment(pjmedia_transport *tp, int info) with gil:\n    cdef RTPTransport rtp_transport\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        rtp_transport = _extract_rtp_transport(tp)\n        if rtp_transport is None:\n            return\n        # TODO: implement PBX enrollment\n    except:\n        ua._handle_exception(1)\n\ncdef void _AudioTransport_cb_dtmf(pjmedia_stream *stream, void *user_data, int digit) with gil:\n    cdef AudioTransport audio_stream = (<object> user_data)()\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    if audio_stream is None:\n        return\n    try:\n        _add_event(\"RTPAudioStreamGotDTMF\", dict(obj=audio_stream, digit=chr(digit)))\n    except:\n        ua._handle_exception(1)\n\n# globals\n\ncdef pjmedia_ice_cb _ice_cb\n_ice_cb.on_ice_complete = _RTPTransport_cb_ice_complete\n_ice_cb.on_ice_state = _RTPTransport_cb_ice_state\n_ice_cb.on_ice_stop = _RTPTransport_cb_ice_stop\n\nvalid_sdp_directions = (\"sendrecv\", \"sendonly\", \"recvonly\", \"inactive\")\n\n# ZRTP\n\ncdef pjmedia_zrtp_cb _zrtp_cb\n_zrtp_cb.secure_on = _RTPTransport_cb_zrtp_secure_on\n_zrtp_cb.secure_off = _RTPTransport_cb_zrtp_secure_off\n_zrtp_cb.show_sas = _RTPTransport_cb_zrtp_show_sas\n_zrtp_cb.confirm_go_clear = _RTPTransport_cb_zrtp_confirm_goclear\n_zrtp_cb.show_message = _RTPTransport_cb_zrtp_show_message\n_zrtp_cb.negotiation_failed = _RTPTransport_cb_zrtp_negotiation_failed\n_zrtp_cb.not_supported_by_other = _RTPTransport_cb_zrtp_not_supported_by_other\n_zrtp_cb.ask_enrollment = _RTPTransport_cb_zrtp_ask_enrollment\n_zrtp_cb.inform_enrollment = _RTPTransport_cb_zrtp_inform_enrollment\n_zrtp_cb.sign_sas = NULL\n_zrtp_cb.check_sas_signature = NULL\n\n# Keep these aligned with ZrtpCodes.h\n\ncdef dict zrtp_message_levels = {1: 'INFO', 2: 'WARNING', 3: 'SEVERE', 4: 'ERROR'}\ncdef dict zrtp_error_messages = {\n    'INFO': {\n        0: \"Unknown\",\n        1: \"Hello received and prepared a Commit, ready to get peer's hello hash\", #InfoHelloReceived\n        2: \"Commit: Generated a public DH key\",                                    #InfoCommitDHGenerated\n        3: \"Responder: Commit received, preparing DHPart1\",                        #InfoRespCommitReceived\n        4: \"DH1Part: Generated a public DH key\",                                   #InfoDH1DHGenerated\n        5: \"Initiator: DHPart1 received, preparing DHPart2\",                       #InfoInitDH1Received\n        6: \"Responder: DHPart2 received, preparing Confirm1\",                      #InfoRespDH2Received\n        7: \"Initiator: Confirm1 received, preparing Confirm2\",                     #InfoInitConf1Received\n        8: \"Responder: Confirm2 received, preparing Conf2Ack\",                     #InfoRespConf2Received\n        9: \"At least one retained secrets matches - security OK\",                  #InfoRSMatchFound\n       10: \"Entered secure state\",                                                 #InfoSecureStateOn\n       11: \"No more security for this session\",                                    #InfoSecureStateOff\n    },\n    'WARNING': {\n        0: \"Unknown\",\n        1: \"WarningDHAESmismatch = 1, //!< Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096 - not used DH4096 was discarded\", #WarningDHAESmismatch\n        2: \"Received a GoClear message\",                                                                                                              #WarningGoClearReceived\n        3: \"Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096- not used DH4096 was discarded\",                                    #WarningDHShort\n        4: \"No retained shared secrets available - must verify SAS\",                                                                                  #WarningNoRSMatch\n        5: \"Internal ZRTP packet checksum mismatch - packet dropped\",                                                                                 #WarningCRCmismatch\n        6: \"Dropping packet because SRTP authentication failed!\",                                                                                     #WarningSRTPauthError\n        7: \"Dropping packet because SRTP replay check failed!\",                                                                                       #WarningSRTPreplayError\n        8: \"Valid retained shared secrets availabe but no matches found - must verify SAS\",                                                           #WarningNoExpectedRSMatch\n    },\n    'SEVERE': {\n        0: \"Unknown\",\n        1: \"Hash HMAC check of Hello failed!\",                                    #SevereHelloHMACFailed\n        2: \"Hash HMAC check of Commit failed!\",                                   #SevereCommitHMACFailed\n        3: \"Hash HMAC check of DHPart1 failed!\",                                  #SevereDH1HMACFailed\n        4: \"Hash HMAC check of DHPart2 failed!\",                                  #SevereDH2HMACFailed\n        5: \"Cannot send data - connection or peer down?\",                         #SevereCannotSend\n        6: \"Internal protocol error occured!\",                                    #SevereProtocolError\n        7: \"Cannot start a timer - internal resources exhausted?\",                #SevereNoTimer\n        8: \"Too much retries during ZRTP negotiation - connection or peer down?\", #SevereTooMuchRetries\n    },\n    'ERROR': {\n              0x00: \"Unknown\",\n              0x10: \"Malformed packet (CRC OK, but wrong structure)\", #MalformedPacket\n              0x20: \"Critical software error\",                        #CriticalSWError\n              0x30: \"Unsupported ZRTP version\",                       #UnsuppZRTPVersion\n              0x40: \"Hello components mismatch\",                      #HelloCompMismatch\n              0x51: \"Hash type not supported\",                        #UnsuppHashType\n              0x52: \"Cipher type not supported\",                      #UnsuppCiphertype\n              0x53: \"Public key exchange not supported\",              #UnsuppPKExchange\n              0x54: \"SRTP auth. tag not supported\",                   #UnsuppSRTPAuthTag\n              0x55: \"SAS scheme not supported\",                       #UnsuppSASScheme\n              0x56: \"No shared secret available, DH mode required\",   #NoSharedSecret\n              0x61: \"DH Error: bad pvi or pvr ( == 1, 0, or p-1)\",    #DHErrorWrongPV\n              0x62: \"DH Error: hvi != hashed data\",                   #DHErrorWrongHVI\n              0x63: \"Received relayed SAS from untrusted MiTM\",       #SASuntrustedMiTM\n              0x70: \"Auth. Error: Bad Confirm pkt HMAC\",              #ConfirmHMACWrong\n              0x80: \"Nonce reuse\",                                    #NonceReused\n              0x90: \"Equal ZIDs in Hello\",                            #EqualZIDHello\n             0x100: \"GoClear packet received, but not allowed\",       #GoCleatNotAllowed\n        0x7fffffff: \"Packet ignored\",                                 #IgnorePacket\n    }\n}\n\n"
  },
  {
    "path": "sipsimple/core/_core.pxd",
    "content": "# cython: language_level=2\n\ncdef extern from *:\n    ctypedef char *char_ptr_const \"const char *\"\n    enum:\n        PJ_SVN_REV \"PJ_SVN_REVISION\"\n\n# system imports\n\nfrom libc.stdlib cimport malloc, free\nfrom libc.string cimport memcpy\n\n\n# Python C imports\n\nfrom cpython.float cimport PyFloat_AsDouble\nfrom cpython.ref cimport Py_INCREF, Py_DECREF\nfrom cpython.string cimport PyString_FromString, PyString_FromStringAndSize, PyString_AsString, PyString_Size\n\ncdef extern from \"Python.h\":\n    object PyUnicode_FromString(const char *u)\n\n\n# PJSIP imports\n\ncdef extern from \"pjlib.h\":\n\n    # constants\n    enum:\n        PJ_ERR_MSG_SIZE\n    enum:\n        PJ_ERRNO_START_SYS\n        PJ_EBUG\n        PJ_ETOOMANY\n    enum:\n        PJ_MAX_OBJ_NAME\n\n    # init / shutdown\n    int pj_init() nogil\n    void pj_shutdown() nogil\n\n    # version\n    char *pj_get_version() nogil\n\n    # string\n    struct pj_str_t:\n        char *ptr\n        int slen\n    ctypedef pj_str_t *pj_str_ptr_const \"const pj_str_t *\"\n\n    # errors\n    pj_str_t pj_strerror(int statcode, char *buf, int bufsize) nogil\n\n    # logging\n    enum:\n        PJ_LOG_MAX_LEVEL\n    enum pj_log_decoration:\n        PJ_LOG_HAS_YEAR\n        PJ_LOG_HAS_MONTH\n        PJ_LOG_HAS_DAY_OF_MON\n        PJ_LOG_HAS_TIME\n        PJ_LOG_HAS_MICRO_SEC\n        PJ_LOG_HAS_SENDER\n        PJ_LOG_HAS_INDENT\n    void pj_log_set_decor(int decor) nogil\n    int pj_log_get_level() nogil\n    void pj_log_set_level(int level) nogil\n    void pj_log_set_log_func(void func(int level, char_ptr_const data, int len)) nogil\n\n    # memory management\n    struct pj_pool_t\n    struct pj_pool_factory_policy:\n        pass\n    pj_pool_factory_policy pj_pool_factory_default_policy\n    struct pj_pool_factory:\n        pass\n    struct pj_caching_pool:\n        pj_pool_factory factory\n    void pj_caching_pool_init(pj_caching_pool *ch_pool, pj_pool_factory_policy *policy, int max_capacity) nogil\n    void pj_caching_pool_destroy(pj_caching_pool *ch_pool) nogil\n    void *pj_pool_alloc(pj_pool_t *pool, int size) nogil\n    void pj_pool_reset(pj_pool_t *pool) nogil\n    pj_pool_t *pj_pool_create_on_buf(char *name, void *buf, int size) nogil\n    pj_str_t *pj_strdup2_with_null(pj_pool_t *pool, pj_str_t *dst, char *src) nogil\n    void pj_pool_release(pj_pool_t *pool) nogil\n\n    # threads\n    enum:\n        PJ_THREAD_DESC_SIZE\n    struct pj_mutex_t\n    struct pj_rwmutex_t\n    struct pj_thread_t\n    int pj_mutex_create_simple(pj_pool_t *pool, char *name, pj_mutex_t **mutex) nogil\n    int pj_mutex_create_recursive(pj_pool_t *pool, char *name, pj_mutex_t **mutex) nogil\n    int pj_mutex_lock(pj_mutex_t *mutex) nogil\n    int pj_mutex_unlock(pj_mutex_t *mutex) nogil\n    int pj_mutex_destroy(pj_mutex_t *mutex) nogil\n    int pj_rwmutex_create(pj_pool_t *pool, char *name, pj_rwmutex_t **mutex) nogil\n    int pj_rwmutex_lock_read(pj_rwmutex_t *mutex) nogil\n    int pj_rwmutex_lock_write(pj_rwmutex_t *mutex) nogil\n    int pj_rwmutex_unlock_read(pj_rwmutex_t *mutex) nogil\n    int pj_rwmutex_unlock_write(pj_rwmutex_t *mutex) nogil\n    int pj_rwmutex_destroy(pj_rwmutex_t *mutex) nogil\n    int pj_thread_is_registered() nogil\n    int pj_thread_register(char *thread_name, long *thread_desc, pj_thread_t **thread) nogil\n\n    # sockets\n    enum:\n        PJ_INET6_ADDRSTRLEN\n    struct pj_ioqueue_t\n    struct pj_addr_hdr:\n        unsigned int sa_family\n    struct pj_sockaddr_in:\n        pass\n    struct pj_sockaddr_in6:\n        pass\n    ctypedef union pj_sockaddr:\n        pj_addr_hdr addr\n        pj_sockaddr_in ipv4\n        pj_sockaddr_in6 ipv6\n    ctypedef pj_sockaddr *pj_sockaddr_ptr_const \"const pj_sockaddr *\"\n    int pj_AF_INET() nogil\n    int pj_AF_INET6() nogil\n    int pj_sockaddr_in_init(pj_sockaddr_in *addr, pj_str_t *cp, int port) nogil\n    int pj_sockaddr_get_port(pj_sockaddr *addr) nogil\n    char *pj_sockaddr_print(pj_sockaddr *addr, char *buf, int size, unsigned int flags) nogil\n    int pj_sockaddr_has_addr(pj_sockaddr *addr) nogil\n    int pj_sockaddr_init(int af, pj_sockaddr *addr, pj_str_t *cp, unsigned int port) nogil\n    int pj_inet_pton(int af, pj_str_t *src, void *dst) nogil\n\n    # dns\n    struct pj_dns_resolver\n    int pj_dns_resolver_set_ns(pj_dns_resolver *resolver, unsigned count, pj_str_t *servers, int *ports) nogil\n\n    # time\n    struct pj_time_val:\n        long sec\n        long msec\n    void pj_gettimeofday(pj_time_val *tv) nogil\n    void pj_time_val_normalize(pj_time_val *tv) nogil\n\n    # timers\n    struct pj_timer_heap_t\n    struct pj_timer_entry:\n        void *user_data\n        int id\n    pj_timer_entry *pj_timer_entry_init(pj_timer_entry *entry, int id, void *user_data,\n                                        void cb(pj_timer_heap_t *timer_heap, pj_timer_entry *entry) with gil) nogil\n\n    # lists\n    struct pj_list:\n        void *prev\n        void *next\n    void pj_list_init(pj_list *node) nogil\n    void pj_list_insert_after(pj_list *pos, pj_list *node) nogil\n\n    # random\n    void pj_srand(unsigned int seed) nogil\n\n    # maths\n    struct pj_math_stat:\n        int n\n        int max\n        int min\n        int last\n        int mean\n\ncdef extern from \"pjlib-util.h\":\n\n    # init\n    int pjlib_util_init() nogil\n\ncdef extern from \"pjnath.h\":\n\n    # init\n    int pjnath_init() nogil\n\n    # STUN\n    enum:\n        PJ_STUN_PORT\n    struct pj_stun_config:\n        pass\n    struct pj_stun_sock_cfg:\n        pj_sockaddr bound_addr\n    void pj_stun_config_init(pj_stun_config *cfg, pj_pool_factory *factory, unsigned int options,\n                             pj_ioqueue_t *ioqueue, pj_timer_heap_t *timer_heap) nogil\n\n    # NAT detection\n    struct pj_stun_nat_detect_result:\n        int status\n        char *status_text\n        char *nat_type_name\n    ctypedef pj_stun_nat_detect_result *pj_stun_nat_detect_result_ptr_const \"const pj_stun_nat_detect_result *\"\n    int pj_stun_detect_nat_type(pj_sockaddr_in *server, pj_stun_config *stun_cfg, void *user_data,\n                                void pj_stun_nat_detect_cb(void *user_data,\n                                                           pj_stun_nat_detect_result_ptr_const res) with gil) nogil\n\n    # ICE\n    struct pj_ice_strans\n    struct pj_ice_sess_cand:\n        int type\n        int comp_id\n        int prio\n        pj_sockaddr addr\n        pj_sockaddr rel_addr\n    struct pj_ice_sess_check:\n        pj_ice_sess_cand *lcand\n        pj_ice_sess_cand *rcand\n        int state\n        int nominated\n    ctypedef pj_ice_sess_check *pj_ice_sess_check_ptr_const \"const pj_ice_sess_check *\"\n    struct pj_ice_sess_comp:\n        pj_ice_sess_check *valid_check\n    struct pj_ice_sess_checklist:\n        int count\n        pj_ice_sess_check *checks\n    struct pj_ice_sess:\n        int comp_cnt\n        pj_ice_sess_comp *comp\n        int lcand_cnt\n        pj_ice_sess_cand *lcand\n        int rcand_cnt\n        pj_ice_sess_cand *rcand\n        pj_ice_sess_checklist valid_list\n    struct pj_ice_strans_cfg_stun:\n        pj_stun_sock_cfg cfg\n        pj_str_t server\n        unsigned int port\n    struct pj_ice_strans_cfg:\n        int af\n        pj_stun_config stun_cfg\n        pj_ice_strans_cfg_stun stun\n    enum pj_ice_strans_op:\n        PJ_ICE_STRANS_OP_INIT\n        PJ_ICE_STRANS_OP_NEGOTIATION\n    enum pj_ice_strans_state:\n        PJ_ICE_STRANS_STATE_NULL\n        PJ_ICE_STRANS_STATE_INIT\n        PJ_ICE_STRANS_STATE_READY\n        PJ_ICE_STRANS_STATE_SESS_READY\n        PJ_ICE_STRANS_STATE_NEGO\n        PJ_ICE_STRANS_STATE_RUNNING\n        PJ_ICE_STRANS_STATE_FAILED\n    enum pj_ice_cand_type:\n        PJ_ICE_CAND_TYPE_HOST\n        PJ_ICE_CAND_TYPE_SRFLX\n        PJ_ICE_CAND_TYPE_PRFLX\n        PJ_ICE_CAND_TYPE_RELAYED\n    enum pj_ice_sess_check_state:\n        PJ_ICE_SESS_CHECK_STATE_FROZEN\n        PJ_ICE_SESS_CHECK_STATE_WAITING\n        PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS\n        PJ_ICE_SESS_CHECK_STATE_SUCCEEDED\n        PJ_ICE_SESS_CHECK_STATE_FAILED\n    struct pjmedia_ice_transport_info:\n        int active\n        pj_ice_strans_state sess_state\n    void pj_ice_strans_cfg_default(pj_ice_strans_cfg *cfg) nogil\n    pj_ice_sess* pj_ice_strans_get_session(pj_ice_strans *ice_st)\n    pj_time_val pj_ice_strans_get_start_time(pj_ice_strans *ice_st)\n    pj_ice_strans_state pj_ice_strans_get_state(pj_ice_strans *ice_st)\n    pj_ice_sess_check_ptr_const pj_ice_strans_get_valid_pair(pj_ice_strans *ice_st, unsigned comp_id)\n\ncdef extern from \"pjmedia.h\":\n\n    enum:\n        PJMEDIA_ENOSNDREC\n        PJMEDIA_ENOSNDPLAY\n\n    enum:\n        PJMEDIA_AUD_DEFAULT_CAPTURE_DEV\n        PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV\n        PJMEDIA_AUD_DEV_CAP_EC\n        PJMEDIA_AUD_DEV_CAP_EC_TAIL\n\n    enum:\n        PJMEDIA_VID_DEFAULT_CAPTURE_DEV\n        PJMEDIA_VID_DEFAULT_RENDER_DEV\n        PJMEDIA_VID_INVALID_DEV\n\n    enum pjmedia_dir:\n        PJMEDIA_DIR_NONE\n        PJMEDIA_DIR_ENCODING\n        PJMEDIA_DIR_DECODING\n        PJMEDIA_DIR_ENCODING_DECODING\n        PJMEDIA_DIR_PLAYBACK = PJMEDIA_DIR_DECODING\n        PJMEDIA_DIR_RENDER = PJMEDIA_DIR_DECODING\n        PJMEDIA_DIR_CAPTURE = PJMEDIA_DIR_ENCODING\n        PJMEDIA_DIR_CAPTURE_PLAYBACK = PJMEDIA_DIR_ENCODING_DECODING\n        PJMEDIA_DIR_CAPTURE_RENDER = PJMEDIA_DIR_ENCODING_DECODING\n\n    enum pjmedia_type:\n        PJMEDIA_TYPE_NONE\n        PJMEDIA_TYPE_NONEYPE_AUDIO\n        PJMEDIA_TYPE_VIDEO\n        PJMEDIA_TYPE_APPLICATION\n        PJMEDIA_TYPE_UNKNOWN\n\n    struct pjmedia_rect_size:\n        unsigned int w\n        unsigned int h\n\n    struct pjmedia_ratio:\n        int num\n        int denum\n\n    # frame\n    struct pjmedia_frame:\n        void *buf\n        int size\n    ctypedef pjmedia_frame *pjmedia_frame_ptr_const \"const pjmedia_frame *\"\n\n    # codec manager\n    struct pjmedia_codec_mgr\n    enum:\n        PJMEDIA_CODEC_MGR_MAX_CODECS\n    struct pjmedia_codec_info:\n        pj_str_t encoding_name\n        unsigned int clock_rate\n        unsigned int channel_cnt\n    int pjmedia_codec_mgr_enum_codecs(pjmedia_codec_mgr *mgr, unsigned int *count, pjmedia_codec_info *info, unsigned int *prio) nogil\n    int pjmedia_codec_mgr_set_codec_priority(pjmedia_codec_mgr *mgr, pj_str_t *codec_id, unsigned int prio) nogil\n\n    # transport manager\n    struct pjsip_tpmgr\n    struct pjsip_transport_state_info:\n        int status\n    enum pjsip_transport_state:\n        PJSIP_TP_STATE_CONNECTED\n        PJSIP_TP_STATE_DISCONNECTED\n    ctypedef pjsip_transport_state_info *pjsip_transport_state_info_ptr_const \"const pjsip_transport_state_info *\"\n    ctypedef void (*pjsip_tp_state_callback)(pjsip_transport *tp, pjsip_transport_state state, pjsip_transport_state_info_ptr_const info) with gil\n    int pjsip_tpmgr_set_state_cb(pjsip_tpmgr *mgr, pjsip_tp_state_callback cb)\n\n    # formats\n    enum pjmedia_format_detail_type:\n        PJMEDIA_FORMAT_DETAIL_NONE\n        PJMEDIA_FORMAT_DETAIL_AUDIO\n        PJMEDIA_FORMAT_DETAIL_VIDEO\n        PJMEDIA_FORMAT_DETAIL_MAX\n    struct pjmedia_audio_format_detail:\n        unsigned int clock_rate\n        unsigned int channel_count\n        unsigned int frame_time_usec\n        unsigned int baseits_per_sample\n        unsigned int avg_bps\n        unsigned int max_bps\n    struct pjmedia_video_format_detail:\n        pjmedia_rect_size size\n        pjmedia_ratio fps\n        unsigned int avg_bps\n        unsigned int max_bps\n    cdef union pjmedia_format_union:\n        pjmedia_audio_format_detail aud\n        pjmedia_video_format_detail vid\n        char user[1]\n    struct pjmedia_format:\n        unsigned int id\n        pjmedia_type type\n        pjmedia_format_detail_type detail_type\n        pjmedia_format_union det\n    ctypedef pjmedia_format *pjmedia_format_ptr_const \"const pjmedia_format *\"\n    enum:\n        PJMEDIA_CODEC_MAX_FMTP_CNT\n    struct _param:\n        pj_str_t name\n        pj_str_t val\n    struct pjmedia_codec_fmtp:\n        int cnt\n        _param param[PJMEDIA_CODEC_MAX_FMTP_CNT]\n\n    # video codec parameters\n    enum pjmedia_vid_packing:\n        PJMEDIA_VID_PACKING_PACKETS\n    struct pjmedia_vid_codec_param:\n        pjmedia_dir dir\n        pjmedia_vid_packing packing\n        pjmedia_format enc_fmt\n        pjmedia_codec_fmtp enc_fmtp\n        pjmedia_format dec_fmt\n        pjmedia_codec_fmtp dec_fmtp\n    ctypedef pjmedia_vid_codec_param *pjmedia_vid_codec_param_ptr_const \"const pjmedia_vid_codec_param *\"\n\n    # video codec manager\n    enum:\n        PJMEDIA_VID_CODEC_MGR_MAX_CODECS\n    struct pjmedia_vid_codec_info:\n        pj_str_t encoding_name\n        unsigned int pt\n        unsigned int clock_rate\n        unsigned int packings\n    ctypedef pjmedia_vid_codec_info *pjmedia_vid_codec_info_ptr_const \"const pjmedia_vid_codec_info *\"\n    struct pjmedia_vid_codec_mgr\n    int pjmedia_vid_codec_mgr_create(pj_pool_t *pool, pjmedia_vid_codec_mgr **mgr) nogil\n    void pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr *mgr) nogil\n    pjmedia_vid_codec_mgr* pjmedia_vid_codec_mgr_instance() nogil\n    int pjmedia_vid_codec_mgr_enum_codecs(pjmedia_vid_codec_mgr *mgr, unsigned int *count, pjmedia_vid_codec_info *info, unsigned int *prio) nogil\n    int pjmedia_vid_codec_mgr_set_codec_priority(pjmedia_vid_codec_mgr *mgr, pj_str_t *codec_id, unsigned int prio) nogil\n    int pjmedia_vid_codec_mgr_get_default_param(pjmedia_vid_codec_mgr *mgr, pjmedia_vid_codec_info_ptr_const info, pjmedia_vid_codec_param *param) nogil\n    int pjmedia_vid_codec_mgr_set_default_param(pjmedia_vid_codec_mgr *mgr, pjmedia_vid_codec_info_ptr_const info, pjmedia_vid_codec_param_ptr_const param) nogil\n\n    # video format manager\n    struct pjmedia_video_format_mgr\n    int pjmedia_video_format_mgr_create(pj_pool_t *pool, unsigned int max_fmt, unsigned int options, pjmedia_video_format_mgr **p_mgr) nogil\n    void pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr *mgr) nogil\n    pjmedia_video_format_mgr* pjmedia_video_format_mgr_instance() nogil\n\n    # converter manager\n    struct pjmedia_converter_mgr\n    int pjmedia_converter_mgr_create(pj_pool_t *pool, pjmedia_converter_mgr **mgr) nogil\n    void pjmedia_converter_mgr_destroy(pjmedia_converter_mgr *mgr) nogil\n    pjmedia_converter_mgr* pjmedia_converter_mgr_instance() nogil\n\n    # event manager\n    struct pjmedia_event_mgr\n    enum pjmedia_event_type:\n        PJMEDIA_EVENT_FMT_CHANGED\n        PJMEDIA_EVENT_KEYFRAME_FOUND\n        PJMEDIA_EVENT_KEYFRAME_MISSING\n        PJMEDIA_EVENT_KEYFRAME_REQUESTED\n    struct pjmedia_event_fmt_changed_data:\n        pjmedia_dir dir\n        pjmedia_format new_fmt\n    cdef union pjmedia_event_data_union:\n        pjmedia_event_fmt_changed_data fmt_changed\n        void* ptr\n    struct pjmedia_event:\n        pjmedia_event_type type\n        pjmedia_event_data_union data\n    int pjmedia_event_mgr_create(pj_pool_t *pool, unsigned int options, pjmedia_event_mgr **mgr) nogil\n    void pjmedia_event_mgr_destroy(pjmedia_event_mgr *mgr) nogil\n    pjmedia_event_mgr* pjmedia_event_mgr_instance() nogil\n    ctypedef int pjmedia_event_cb(pjmedia_event *event, void *user_data)\n    int pjmedia_event_subscribe(pjmedia_event_mgr *mgr, pjmedia_event_cb *cb, void *user_data, void *epub) nogil\n    int pjmedia_event_unsubscribe(pjmedia_event_mgr *mgr, pjmedia_event_cb *cb, void *user_data, void *epub) nogil\n\n    # endpoint\n    struct pjmedia_endpt\n    int pjmedia_endpt_create(pj_pool_factory *pf, pj_ioqueue_t *ioqueue, int worker_cnt, pjmedia_endpt **p_endpt) nogil\n    pj_pool_t *pjmedia_endpt_create_pool(pjmedia_endpt *endpt, char *pool_name, int initial, int increment) nogil\n    int pjmedia_endpt_destroy(pjmedia_endpt *endpt) nogil\n    pj_ioqueue_t *pjmedia_endpt_get_ioqueue(pjmedia_endpt *endpt) nogil\n    pjmedia_codec_mgr *pjmedia_endpt_get_codec_mgr(pjmedia_endpt *endpt) nogil\n    pjsip_tpmgr* pjsip_endpt_get_tpmgr(pjsip_endpoint *endpt)\n\n    # sound devices\n    struct pjmedia_aud_dev_info:\n        char *name\n        int input_count\n        int output_count\n    struct pjmedia_aud_param:\n        pjmedia_dir dir\n        int play_id\n        int rec_id\n        int clock_rate\n        int channel_count\n        int samples_per_frame\n        int bits_per_sample\n        int flags\n        int ec_enabled\n        int ec_tail_ms\n    struct pjmedia_aud_stream\n    int pjmedia_aud_dev_count() nogil\n    int pjmedia_aud_dev_get_info(int index, pjmedia_aud_dev_info *info) nogil\n    int pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm, pjmedia_aud_param *param) nogil\n    enum pjmedia_aud_dev_event:\n        PJMEDIA_AUD_DEV_DEFAULT_INPUT_CHANGED\n        PJMEDIA_AUD_DEV_DEFAULT_OUTPUT_CHANGED\n        PJMEDIA_AUD_DEV_LIST_WILL_REFRESH\n        PJMEDIA_AUD_DEV_LIST_DID_REFRESH\n    ctypedef void (*pjmedia_aud_dev_observer_callback)(pjmedia_aud_dev_event event)\n    int pjmedia_aud_dev_set_observer_cb(pjmedia_aud_dev_observer_callback cb) nogil\n    int pjmedia_aud_dev_default_param(int index, pjmedia_aud_param *param) nogil\n    int pjmedia_aud_dev_refresh() nogil\n\n    # sound port\n    struct pjmedia_port_info:\n        pjmedia_format fmt\n    struct pjmedia_port:\n        pjmedia_port_info info\n    struct pjmedia_snd_port\n    struct pjmedia_snd_port_param:\n        pjmedia_aud_param base\n    ctypedef pjmedia_snd_port_param *pjmedia_snd_port_param_ptr_const \"const pjmedia_snd_port_param *\"\n    int pjmedia_snd_port_create2(pj_pool_t *pool, pjmedia_snd_port_param_ptr_const prm, pjmedia_snd_port **p_port) nogil\n    void pjmedia_snd_port_param_default(pjmedia_snd_port_param *prm)\n    int pjmedia_snd_port_connect(pjmedia_snd_port *snd_port, pjmedia_port *port) nogil\n    int pjmedia_snd_port_disconnect(pjmedia_snd_port *snd_port) nogil\n    int pjmedia_snd_port_set_ec(pjmedia_snd_port *snd_port, pj_pool_t *pool, unsigned int tail_ms, int options) nogil\n    int pjmedia_snd_port_reset_ec_state(pjmedia_snd_port *snd_port) nogil\n    int pjmedia_snd_port_destroy(pjmedia_snd_port *snd_port) nogil\n    pjmedia_aud_stream *pjmedia_snd_port_get_snd_stream(pjmedia_snd_port *snd_port) nogil\n    int pjmedia_null_port_create(pj_pool_t *pool, unsigned int sampling_rate, unsigned int channel_count,\n                                 unsigned int samples_per_frame, unsigned int bits_per_sample, pjmedia_port **p_port) nogil\n    int pjmedia_mixer_port_create(pj_pool_t *pool, unsigned int sampling_rate, unsigned int channel_count,\n                                  unsigned int samples_per_frame, unsigned int bits_per_sample, pjmedia_port **p_port) nogil\n\n    # master port\n    struct pjmedia_master_port\n    int pjmedia_master_port_create(pj_pool_t *pool, pjmedia_port *u_port, pjmedia_port *d_port,\n                                   unsigned int options, pjmedia_master_port **p_m) nogil\n    int pjmedia_master_port_start(pjmedia_master_port *m) nogil\n    int pjmedia_master_port_destroy(pjmedia_master_port *m, int destroy_ports) nogil\n\n    # conference bridge\n    enum pjmedia_conf_option:\n        PJMEDIA_CONF_NO_DEVICE\n    struct pjmedia_conf\n    int pjmedia_conf_create(pj_pool_t *pool, int max_slots, int sampling_rate, int channel_count,\n                            int samples_per_frame, int bits_per_sample, int options, pjmedia_conf **p_conf) nogil\n    int pjmedia_conf_destroy(pjmedia_conf *conf) nogil\n    pjmedia_port *pjmedia_conf_get_master_port(pjmedia_conf *conf) nogil\n    int pjmedia_conf_add_port(pjmedia_conf *conf, pj_pool_t *pool, pjmedia_port *strm_port,\n                              pj_str_t *name, unsigned int *p_slot) nogil\n    int pjmedia_conf_remove_port(pjmedia_conf *conf, unsigned int slot) nogil\n    int pjmedia_conf_connect_port(pjmedia_conf *conf, unsigned int src_slot, unsigned int sink_slot, int level) nogil\n    int pjmedia_conf_disconnect_port(pjmedia_conf *conf, unsigned int src_slot, unsigned int sink_slot) nogil\n    int pjmedia_conf_adjust_rx_level(pjmedia_conf *conf, unsigned slot, int adj_level) nogil\n    int pjmedia_conf_adjust_tx_level(pjmedia_conf *conf, unsigned slot, int adj_level) nogil\n\n    # video devices\n    enum pjmedia_vid_dev_cap:\n        PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE\n        PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE\n        PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS\n    enum pjmedia_vid_dev_wnd_flag:\n        PJMEDIA_VID_DEV_WND_BORDER\n        PJMEDIA_VID_DEV_WND_RESIZABLE\n    struct pjmedia_vid_dev_info:\n        int id\n        char *name\n        char *driver\n        int dir\n    cdef struct pjmedia_hwnd_win:\n        void *hwnd\n    cdef struct pjmedia_hwnd_x11:\n        void *window\n        void *display\n    cdef struct pjmedia_hwnd_cocoa:\n        void *window\n    cdef struct pjmedia_hwnd_ios:\n        void *window\n    cdef union pjmedia_hwnd_union:\n        pjmedia_hwnd_win win\n        pjmedia_hwnd_x11 x11\n        pjmedia_hwnd_cocoa cocoa\n        pjmedia_hwnd_ios ios\n        void *window\n    struct pjmedia_vid_dev_hwnd:\n        pjmedia_hwnd_union info\n    struct pjmedia_vid_dev_param:\n        pjmedia_dir dir\n        int cap_id\n        int rend_id\n        unsigned int flags\n        pjmedia_format fmt\n        pjmedia_vid_dev_hwnd window\n        pjmedia_rect_size disp_size\n        int window_hide\n        unsigned int window_flags\n    struct pjmedia_vid_dev_stream\n    int pjmedia_vid_dev_count() nogil\n    int pjmedia_vid_dev_get_info(int index, pjmedia_vid_dev_info *info) nogil\n    int pjmedia_vid_dev_subsys_init(pj_pool_factory *pf) nogil\n    int pjmedia_vid_dev_subsys_shutdown() nogil\n    int pjmedia_vid_dev_default_param(pj_pool_t *pool, int id, pjmedia_vid_dev_param *param) nogil\n    int pjmedia_vid_dev_stream_get_cap(pjmedia_vid_dev_stream *strm, pjmedia_vid_dev_cap cap, void *value) nogil\n    int pjmedia_vid_dev_stream_set_cap(pjmedia_vid_dev_stream *strm, pjmedia_vid_dev_cap cap, void *value) nogil\n    int pjmedia_vid_dev_stream_get_param(pjmedia_vid_dev_stream *strm, pjmedia_vid_dev_param *param) nogil\n    int pjmedia_vid_dev_refresh() nogil\n    int pjmedia_vid_dev_lookup(char_ptr_const drv_name, char_ptr_const dev_name,  int *id)\n\n    # video stream\n    struct pjmedia_vid_stream_info:\n        pjmedia_vid_codec_param *codec_param\n        pjmedia_vid_codec_info codec_info\n        int use_ka\n\n    struct pjmedia_vid_stream\n    ctypedef pjmedia_vid_stream *pjmedia_vid_stream_ptr_const \"const pjmedia_vid_stream *\"\n    int pjmedia_vid_stream_get_stat(pjmedia_vid_stream_ptr_const stream, pjmedia_rtcp_stat *stat) nogil\n    int pjmedia_vid_stream_get_info(pjmedia_vid_stream_ptr_const stream, pjmedia_vid_stream_info *info) nogil\n    int pjmedia_vid_stream_info_from_sdp(pjmedia_vid_stream_info *si, pj_pool_t *pool, pjmedia_endpt *endpt,\n                                         pjmedia_sdp_session *local, pjmedia_sdp_session *remote, unsigned int stream_idx) nogil\n    int pjmedia_vid_stream_create(pjmedia_endpt *endpt, pj_pool_t *pool, pjmedia_vid_stream_info *info,\n                                  pjmedia_transport *tp, void *user_data, pjmedia_vid_stream **p_stream) nogil\n    int pjmedia_vid_stream_start(pjmedia_vid_stream *stream) nogil\n    int pjmedia_vid_stream_destroy(pjmedia_vid_stream *stream) nogil\n    int pjmedia_vid_stream_get_port(pjmedia_vid_stream *stream, pjmedia_dir dir, pjmedia_port **p_port) nogil\n    int pjmedia_vid_stream_pause(pjmedia_vid_stream *stream, pjmedia_dir dir) nogil\n    int pjmedia_vid_stream_resume(pjmedia_vid_stream *stream, pjmedia_dir dir) nogil\n    int pjmedia_vid_stream_send_keyframe(pjmedia_vid_stream *stream) nogil\n    int pjmedia_vid_stream_send_rtcp_sdes(pjmedia_vid_stream *stream) nogil\n    int pjmedia_vid_stream_send_rtcp_bye(pjmedia_vid_stream *stream) nogil\n    int pjmedia_vid_stream_send_rtcp_pli(pjmedia_vid_stream *stream) nogil\n\n    # video port\n    struct pjmedia_vid_port\n    struct pjmedia_vid_port_param:\n        pjmedia_vid_dev_param vidparam\n        int active\n\n    void pjmedia_vid_port_param_default(pjmedia_vid_port_param *prm) nogil\n    ctypedef pjmedia_vid_port_param *pjmedia_vid_port_param_ptr_const \"const pjmedia_vid_port_param *\"\n    int pjmedia_vid_port_create(pj_pool_t *pool, pjmedia_vid_port_param_ptr_const prm, pjmedia_vid_port **p_vp) nogil\n    int pjmedia_vid_port_start(pjmedia_vid_port *vid_port) nogil\n    int pjmedia_vid_port_is_running(pjmedia_vid_port *vid_port) nogil\n    int pjmedia_vid_port_stop(pjmedia_vid_port *vid_port) nogil\n    int pjmedia_vid_port_connect(pjmedia_vid_port *vid_port, pjmedia_port *port, int destroy) nogil\n    pjmedia_port *pjmedia_vid_port_get_passive_port(pjmedia_vid_port *vid_port) nogil\n    int pjmedia_vid_port_disconnect(pjmedia_vid_port *vid_port) nogil\n    void pjmedia_vid_port_destroy(pjmedia_vid_port *vid_port) nogil\n    pjmedia_vid_dev_stream *pjmedia_vid_port_get_stream(pjmedia_vid_port *vid_port) nogil\n\n    # video tee\n    int pjmedia_vid_tee_create(pj_pool_t *pool, pjmedia_format_ptr_const fmt, unsigned int max_dst_cnt, pjmedia_port **p_vid_tee) nogil\n    int pjmedia_vid_tee_add_dst_port2(pjmedia_port *vid_tee, unsigned int option, pjmedia_port *port) nogil\n    int pjmedia_vid_tee_remove_dst_port(pjmedia_port *vid_tee, pjmedia_port *port) nogil\n\n    # sdp\n    enum:\n        PJMEDIA_MAX_SDP_FMT\n    enum:\n        PJMEDIA_MAX_SDP_ATTR\n    enum:\n        PJMEDIA_MAX_SDP_MEDIA\n    enum:\n        PJMEDIA_MAX_SDP_BANDW\n    struct pjmedia_sdp_attr:\n        pj_str_t name\n        pj_str_t value\n    struct pjmedia_sdp_bandw:\n        pj_str_t modifier\n        unsigned int value\n    struct pjmedia_sdp_conn:\n        pj_str_t net_type\n        pj_str_t addr_type\n        pj_str_t addr\n    struct pjmedia_sdp_media_desc:\n        pj_str_t media\n        unsigned int port\n        unsigned int port_count\n        pj_str_t transport\n        unsigned int fmt_count\n        pj_str_t fmt[PJMEDIA_MAX_SDP_FMT]\n    struct pjmedia_sdp_media:\n        pjmedia_sdp_media_desc desc\n        pjmedia_sdp_conn *conn\n        unsigned int attr_count\n        pjmedia_sdp_attr *attr[PJMEDIA_MAX_SDP_ATTR]\n        unsigned int bandw_count\n        pjmedia_sdp_bandw *bandw[PJMEDIA_MAX_SDP_BANDW]\n    struct pjmedia_sdp_session_origin:\n        pj_str_t user\n        unsigned int id\n        unsigned int version\n        pj_str_t net_type\n        pj_str_t addr_type\n        pj_str_t addr\n    struct pjmedia_sdp_session_time:\n        unsigned int start\n        unsigned int stop\n    struct pjmedia_sdp_session:\n        pjmedia_sdp_session_origin origin\n        pj_str_t name\n        pjmedia_sdp_conn *conn\n        pjmedia_sdp_session_time time\n        unsigned int attr_count\n        pjmedia_sdp_attr *attr[PJMEDIA_MAX_SDP_ATTR]\n        unsigned int bandw_count\n        pjmedia_sdp_bandw *bandw[PJMEDIA_MAX_SDP_BANDW]\n        unsigned int media_count\n        pjmedia_sdp_media *media[PJMEDIA_MAX_SDP_MEDIA]\n    ctypedef pjmedia_sdp_session *pjmedia_sdp_session_ptr_const \"const pjmedia_sdp_session *\"\n    pjmedia_sdp_media *pjmedia_sdp_media_clone(pj_pool_t *pool, pjmedia_sdp_media *rhs) nogil\n    pjmedia_sdp_session *pjmedia_sdp_session_clone(pj_pool_t *pool, pjmedia_sdp_session_ptr_const sdp) nogil\n    int pjmedia_sdp_print(pjmedia_sdp_session_ptr_const sdp, char *buf, int length)\n    int pjmedia_sdp_parse(pj_pool_t *pool, char *buf, int length, pjmedia_sdp_session **p_sdp) nogil\n\n    # sdp negotiation\n\n    enum pjmedia_sdp_neg_state:\n        PJMEDIA_SDP_NEG_STATE_NULL\n        PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER\n        PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER\n        PJMEDIA_SDP_NEG_STATE_WAIT_NEGO\n        PJMEDIA_SDP_NEG_STATE_DONE\n    struct pjmedia_sdp_neg\n    int pjmedia_sdp_neg_create_w_local_offer(pj_pool_t *pool, pjmedia_sdp_session_ptr_const local, pjmedia_sdp_neg **neg) nogil\n    int pjmedia_sdp_neg_create_w_remote_offer(pj_pool_t *pool, pjmedia_sdp_session_ptr_const initial, pjmedia_sdp_session_ptr_const remote, pjmedia_sdp_neg **neg) nogil\n    int pjmedia_sdp_neg_set_local_answer(pj_pool_t *pool, pjmedia_sdp_neg *neg, pjmedia_sdp_session_ptr_const local) nogil\n    int pjmedia_sdp_neg_set_remote_answer(pj_pool_t *pool, pjmedia_sdp_neg *neg, pjmedia_sdp_session_ptr_const remote) nogil\n    int pjmedia_sdp_neg_set_remote_offer(pj_pool_t *pool, pjmedia_sdp_neg *neg, pjmedia_sdp_session_ptr_const remote) nogil\n    int pjmedia_sdp_neg_get_neg_remote(pjmedia_sdp_neg *neg, pjmedia_sdp_session_ptr_const *remote) nogil\n    int pjmedia_sdp_neg_get_neg_local(pjmedia_sdp_neg *neg, pjmedia_sdp_session_ptr_const *local) nogil\n    int pjmedia_sdp_neg_get_active_remote(pjmedia_sdp_neg *neg, pjmedia_sdp_session_ptr_const *remote) nogil\n    int pjmedia_sdp_neg_get_active_local(pjmedia_sdp_neg *neg, pjmedia_sdp_session_ptr_const *local) nogil\n    int pjmedia_sdp_neg_modify_local_offer (pj_pool_t *pool, pjmedia_sdp_neg *neg, pjmedia_sdp_session_ptr_const local) nogil\n    int pjmedia_sdp_neg_cancel_offer(pjmedia_sdp_neg *neg) nogil\n    int pjmedia_sdp_neg_negotiate(pj_pool_t *poll, pjmedia_sdp_neg *neg, int allow_asym) nogil\n    pjmedia_sdp_neg_state pjmedia_sdp_neg_get_state(pjmedia_sdp_neg *neg) nogil\n    char *pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_state state) nogil\n\n    # transport\n    enum pjmedia_transport_type:\n        PJMEDIA_TRANSPORT_TYPE_ICE\n        PJMEDIA_TRANSPORT_TYPE_SRTP\n        PJMEDIA_TRANSPORT_TYPE_ZRTP\n    struct pjmedia_sock_info:\n        pj_sockaddr rtp_addr_name\n    ctypedef pjmedia_sock_info *pjmedia_sock_info_ptr_const \"const pjmedia_sock_info *\"\n    struct pjmedia_transport:\n        char *name\n        pjmedia_transport_type type\n        void *user_data\n    struct pjmedia_transport_specific_info:\n        pjmedia_transport_type type\n        char *buffer\n    struct pjmedia_transport_info:\n        pjmedia_sock_info sock_info\n        pj_sockaddr src_rtp_name\n        int specific_info_cnt\n        pjmedia_transport_specific_info *spc_info\n    void pjmedia_transport_info_init(pjmedia_transport_info *info) nogil\n    int pjmedia_transport_udp_create3(pjmedia_endpt *endpt, int af, char *name, pj_str_t *addr, int port,\n                                      unsigned int options, pjmedia_transport **p_tp) nogil\n    int pjmedia_transport_get_info(pjmedia_transport *tp, pjmedia_transport_info *info) nogil\n    void *pjmedia_transport_info_get_spc_info(pjmedia_transport_info *info, pjmedia_transport_type type)\n    int pjmedia_transport_close(pjmedia_transport *tp) nogil\n    int pjmedia_transport_media_create(pjmedia_transport *tp, pj_pool_t *sdp_pool, unsigned int options,\n                                       pjmedia_sdp_session *rem_sdp, unsigned int media_index) nogil\n    int pjmedia_transport_encode_sdp(pjmedia_transport *tp, pj_pool_t *sdp_pool, pjmedia_sdp_session *sdp,\n                                     pjmedia_sdp_session *rem_sdp, unsigned int media_index) nogil\n    int pjmedia_transport_media_start(pjmedia_transport *tp, pj_pool_t *tmp_pool, pjmedia_sdp_session *sdp_local,\n                                      pjmedia_sdp_session *sdp_remote, unsigned int media_index) nogil\n    int pjmedia_transport_media_stop(pjmedia_transport *tp) nogil\n    int pjmedia_endpt_create_sdp(pjmedia_endpt *endpt, pj_pool_t *pool, unsigned int stream_cnt,\n                                 pjmedia_sock_info *sock_info, pjmedia_sdp_session **p_sdp) nogil\n    int pjmedia_endpt_create_base_sdp(pjmedia_endpt *endpt, pj_pool_t *pool, pj_str_ptr_const sess_name,\n                                      pj_sockaddr_ptr_const origin, pjmedia_sdp_session **p_sdp) nogil\n    int pjmedia_endpt_create_audio_sdp(pjmedia_endpt *endpt, pj_pool_t *pool, pjmedia_sock_info_ptr_const si,\n                                       unsigned int options, pjmedia_sdp_media **p_media) nogil\n    int pjmedia_endpt_create_video_sdp(pjmedia_endpt *endpt, pj_pool_t *pool, pjmedia_sock_info_ptr_const si,\n                                       unsigned int options, pjmedia_sdp_media **p_media) nogil\n\n    # SRTP\n    struct pjmedia_srtp_crypto:\n        pj_str_t key\n        pj_str_t name\n        unsigned int flags\n    struct pjmedia_srtp_info:\n        int active\n        pjmedia_srtp_crypto tx_policy\n    enum pjmedia_srtp_use:\n        PJMEDIA_SRTP_MANDATORY\n    struct pjmedia_srtp_setting:\n        pjmedia_srtp_use use\n    void pjmedia_srtp_setting_default(pjmedia_srtp_setting *opt) nogil\n    int pjmedia_transport_srtp_create(pjmedia_endpt *endpt, pjmedia_transport *tp,\n                                      pjmedia_srtp_setting *opt, pjmedia_transport **p_tp) nogil\n\n    # ZRTP\n    struct pjmedia_zrtp_info:\n        int active\n        char cipher[128]\n    struct pjmedia_zrtp_cb:\n        void secure_on(pjmedia_transport *tp, char* cipher) with gil\n        void secure_off(pjmedia_transport *tp) with gil\n        void show_sas(pjmedia_transport *tp, char* sas, int verified) with gil\n        void confirm_go_clear(pjmedia_transport *tp) with gil\n        void show_message(pjmedia_transport *tp, int severity, int subCode) with gil\n        void negotiation_failed(pjmedia_transport *tp, int severity, int subCode) with gil\n        void not_supported_by_other(pjmedia_transport *tp) with gil\n        void ask_enrollment(pjmedia_transport *tp, int info) with gil\n        void inform_enrollment(pjmedia_transport *tp, int info) with gil\n        void sign_sas(pjmedia_transport *tp, unsigned char* sas) with gil\n        int check_sas_signature(pjmedia_transport *tp, unsigned char* sas) with gil\n\n    int pjmedia_transport_zrtp_create(pjmedia_endpt *endpt, pj_timer_heap_t *timer_heap, pjmedia_transport *tp,\n                                      pjmedia_transport **p_tp, int close_slave) nogil\n    int pjmedia_transport_zrtp_initialize(pjmedia_transport *tp, char_ptr_const zidFilename,\n                                          int autoEnable, pjmedia_zrtp_cb *zrtp_cb) nogil\n    void pjmedia_transport_zrtp_setSASVerified(pjmedia_transport *tp, int verified) nogil\n    char* pjmedia_transport_zrtp_getPeerName(pjmedia_transport *tp) nogil\n    void pjmedia_transport_zrtp_putPeerName(pjmedia_transport *tp, const char *name) nogil\n    int pjmedia_transport_zrtp_getPeerZid(pjmedia_transport *tp, unsigned char* data) nogil\n    void pjmedia_transport_zrtp_setEnableZrtp(pjmedia_transport *tp, int onOff) nogil\n    char* pjmedia_transport_zrtp_getMultiStreamParameters(pjmedia_transport *tp, int *length) nogil\n    void pjmedia_transport_zrtp_setMultiStreamParameters(pjmedia_transport *tp, const char *parameters, int length, pjmedia_transport *master_tp) nogil\n\n    # ICE\n    struct pjmedia_ice_cb:\n        void on_ice_complete(pjmedia_transport *tp, pj_ice_strans_op op, int status) with gil\n        void on_ice_state(pjmedia_transport *tp, pj_ice_strans_state prev, pj_ice_strans_state curr) with gil\n        void on_ice_stop(pjmedia_transport *tp, char *reason, int err) with gil\n    int pjmedia_ice_create2(pjmedia_endpt *endpt, char *name, unsigned int comp_cnt, pj_ice_strans_cfg *cfg,\n                            pjmedia_ice_cb *cb, unsigned int options, pjmedia_transport **p_tp) nogil\n    pj_ice_strans *pjmedia_ice_get_strans(pjmedia_transport *tp) with gil\n\n    # stream\n    struct pjmedia_codec_param_setting:\n        unsigned int vad\n    struct pjmedia_codec_param:\n        pjmedia_codec_param_setting setting\n    struct pjmedia_stream_info:\n        pjmedia_codec_info fmt\n        pjmedia_codec_param *param\n        unsigned int tx_event_pt\n        int use_ka\n\n    struct pjmedia_rtcp_stream_stat_loss_type:\n        unsigned int burst\n        unsigned int random\n    struct pjmedia_rtcp_stream_stat:\n        unsigned int pkt\n        unsigned int bytes\n        unsigned int discard\n        unsigned int loss\n        unsigned int reorder\n        unsigned int dup\n        pj_math_stat loss_period\n        pjmedia_rtcp_stream_stat_loss_type loss_type\n        pj_math_stat jitter\n    struct pjmedia_rtcp_stat:\n        pjmedia_rtcp_stream_stat tx\n        pjmedia_rtcp_stream_stat rx\n        pj_math_stat rtt\n    struct pjmedia_stream\n    int pjmedia_stream_info_from_sdp(pjmedia_stream_info *si, pj_pool_t *pool, pjmedia_endpt *endpt,\n                                     pjmedia_sdp_session *local, pjmedia_sdp_session *remote, unsigned int stream_idx) nogil\n    int pjmedia_stream_create(pjmedia_endpt *endpt, pj_pool_t *pool, pjmedia_stream_info *info,\n                              pjmedia_transport *tp, void *user_data, pjmedia_stream **p_stream) nogil\n    int pjmedia_stream_destroy(pjmedia_stream *stream) nogil\n    int pjmedia_stream_get_port(pjmedia_stream *stream, pjmedia_port **p_port) nogil\n    int pjmedia_stream_start(pjmedia_stream *stream) nogil\n    int pjmedia_stream_dial_dtmf(pjmedia_stream *stream, pj_str_t *ascii_digit) nogil\n    int pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream,\n                                         void cb(pjmedia_stream *stream, void *user_data, int digit) with gil,\n                                         void *user_data) nogil\n    int pjmedia_stream_pause(pjmedia_stream *stream, pjmedia_dir dir) nogil\n    int pjmedia_stream_resume(pjmedia_stream *stream, pjmedia_dir dir) nogil\n    int pjmedia_stream_get_stat(pjmedia_stream *stream, pjmedia_rtcp_stat *stat) nogil\n\n    # wav player\n    enum:\n        PJMEDIA_FILE_NO_LOOP\n    int pjmedia_port_destroy(pjmedia_port *port) nogil\n    int pjmedia_wav_player_port_create(pj_pool_t *pool, char *filename, unsigned int ptime, unsigned int flags,\n                                       unsigned int buff_size, pjmedia_port **p_port) nogil\n    int pjmedia_wav_player_set_eof_cb(pjmedia_port *port, void *user_data,\n                                      int cb(pjmedia_port *port, void *usr_data) with gil) nogil\n    int pjmedia_wav_player_port_set_pos(pjmedia_port *port, unsigned int offset) nogil\n\n    # wav recorder\n    enum pjmedia_file_writer_option:\n        PJMEDIA_FILE_WRITE_PCM\n    int pjmedia_wav_writer_port_create(pj_pool_t *pool, char *filename, unsigned int clock_rate,\n                                       unsigned int channel_count, unsigned int samples_per_frame,\n                                       unsigned int bits_per_sample, unsigned int flags, int buff_size,\n                                       pjmedia_port **p_port) nogil\n\n    # tone generator\n    enum:\n        PJMEDIA_TONEGEN_MAX_DIGITS\n    struct pjmedia_tone_desc:\n        short freq1\n        short freq2\n        short on_msec\n        short off_msec\n        short volume\n        short flags\n    struct pjmedia_tone_digit:\n        char digit\n        short on_msec\n        short off_msec\n        short volume\n    int pjmedia_tonegen_create(pj_pool_t *pool, unsigned int clock_rate, unsigned int channel_count,\n                               unsigned int samples_per_frame, unsigned int bits_per_sample,\n                               unsigned int options, pjmedia_port **p_port) nogil\n    int pjmedia_tonegen_play(pjmedia_port *tonegen, unsigned int count, pjmedia_tone_desc *tones, unsigned int options) nogil\n    int pjmedia_tonegen_play_digits(pjmedia_port *tonegen, unsigned int count,\n                                    pjmedia_tone_digit *digits, unsigned int options) nogil\n    int pjmedia_tonegen_stop(pjmedia_port *tonegen) nogil\n    int pjmedia_tonegen_is_busy(pjmedia_port *tonegen) nogil\n\ncdef extern from \"pjmedia_videodev.h\":\n    ctypedef void (*pjmedia_vid_dev_fb_frame_cb)(pjmedia_frame_ptr_const frame, pjmedia_rect_size size, void *user_data)\n    int pjmedia_vid_dev_fb_set_callback(pjmedia_vid_dev_stream *strm, pjmedia_vid_dev_fb_frame_cb cb, void *user_data)\n\ncdef extern from \"pjmedia-codec.h\":\n\n    # codecs\n    enum:\n        PJMEDIA_SPEEX_NO_NB\n    struct speex_options:\n        unsigned int option\n        int quality\n        int complexity\n    struct ilbc_options:\n        unsigned mode\n    struct pjmedia_audio_codec_config:\n        speex_options speex\n        ilbc_options ilbc\n\n    void pjmedia_audio_codec_config_default(pjmedia_audio_codec_config *cfg)\n    int pjmedia_codec_register_audio_codecs(pjmedia_endpt *endpt, const pjmedia_audio_codec_config *c) nogil\n    int pjmedia_codec_ffmpeg_vid_init(pjmedia_vid_codec_mgr *mgr, pj_pool_factory *pf) nogil\n    int pjmedia_codec_ffmpeg_vid_deinit() nogil\n    int pjmedia_codec_vpx_init(pjmedia_vid_codec_mgr *mgr, pj_pool_factory *pf) nogil\n    int pjmedia_codec_vpx_deinit() nogil\n\ncdef extern from \"pjsip.h\":\n\n    # messages\n    enum pjsip_status_code:\n        PJSIP_SC_TSX_TIMEOUT\n        PJSIP_SC_TSX_TRANSPORT_ERROR\n        PJSIP_TLS_EUNKNOWN\n        PJSIP_TLS_EINVMETHOD\n        PJSIP_TLS_ECACERT\n        PJSIP_TLS_ECERTFILE\n        PJSIP_TLS_EKEYFILE\n        PJSIP_TLS_ECIPHER\n        PJSIP_TLS_ECTX\n    enum pjsip_uri_context_e:\n        PJSIP_URI_IN_CONTACT_HDR\n    struct pjsip_param:\n        pj_str_t name\n        pj_str_t value\n    struct pjsip_uri\n    struct pjsip_sip_uri:\n        pj_str_t user\n        pj_str_t passwd\n        pj_str_t host\n        int port\n        pj_str_t user_param\n        pj_str_t method_param\n        pj_str_t transport_param\n        int ttl_param\n        int lr_param\n        pj_str_t maddr_param\n        pjsip_param other_param\n        pjsip_param header_param\n    struct pjsip_name_addr:\n        pj_str_t display\n        pjsip_uri *uri\n    struct pjsip_media_type:\n        pj_str_t type\n        pj_str_t subtype\n        pjsip_param param\n    enum pjsip_method_e:\n        PJSIP_OPTIONS_METHOD\n        PJSIP_CANCEL_METHOD\n        PJSIP_OTHER_METHOD\n    struct pjsip_method:\n        pjsip_method_e id\n        pj_str_t name\n    struct pjsip_host_port:\n        pj_str_t host\n        int port\n    enum pjsip_hdr_e:\n        PJSIP_H_VIA\n        PJSIP_H_CALL_ID\n        PJSIP_H_CONTACT\n        PJSIP_H_CSEQ\n        PJSIP_H_EXPIRES\n        PJSIP_H_FROM\n    struct pjsip_hdr:\n        pjsip_hdr_e type\n        pj_str_t name\n    ctypedef pjsip_hdr *pjsip_hdr_ptr_const \"const pjsip_hdr*\"\n    struct pjsip_generic_array_hdr:\n        unsigned int count\n        pj_str_t *values\n    struct pjsip_generic_string_hdr:\n        pj_str_t name\n        pj_str_t hvalue\n    struct pjsip_cid_hdr:\n        pj_str_t id\n    struct pjsip_contact_hdr:\n        int star\n        pjsip_uri *uri\n        int q1000\n        int expires\n        pjsip_param other_param\n    struct pjsip_clen_hdr:\n        int len\n    struct pjsip_ctype_hdr:\n        pjsip_media_type media\n    struct pjsip_cseq_hdr:\n        int cseq\n        pjsip_method method\n    struct pjsip_generic_int_hdr:\n        int ivalue\n    ctypedef pjsip_generic_int_hdr pjsip_expires_hdr\n    struct pjsip_fromto_hdr:\n        pjsip_uri *uri\n        pj_str_t tag\n        pjsip_param other_param\n    struct pjsip_routing_hdr:\n        pjsip_name_addr name_addr\n        pjsip_param other_param\n    ctypedef pjsip_routing_hdr pjsip_route_hdr\n    struct pjsip_retry_after_hdr:\n        int ivalue\n        pjsip_param param\n        pj_str_t comment\n    struct pjsip_via_hdr:\n        pj_str_t transport\n        pjsip_host_port sent_by\n        int ttl_param\n        int rport_param\n        pj_str_t maddr_param\n        pj_str_t recvd_param\n        pj_str_t branch_param\n        pjsip_param other_param\n        pj_str_t comment\n    enum:\n        PJSIP_MAX_ACCEPT_COUNT\n    struct pjsip_msg_body:\n        pjsip_media_type content_type\n        void *data\n        unsigned int len\n    struct pjsip_request_line:\n        pjsip_method method\n        pjsip_uri *uri\n    struct pjsip_status_line:\n        int code\n        pj_str_t reason\n    union pjsip_msg_line:\n        pjsip_request_line req\n        pjsip_status_line status\n    enum pjsip_msg_type_e:\n        PJSIP_REQUEST_MSG\n        PJSIP_RESPONSE_MSG\n    struct pjsip_msg:\n        pjsip_msg_type_e type\n        pjsip_msg_line line\n        pjsip_hdr hdr\n        pjsip_msg_body *body\n    struct pjsip_buffer:\n        char *start\n        char *cur\n    struct pjsip_tx_data_tp_info:\n        char *dst_name\n        int dst_port\n        pjsip_transport *transport\n    struct pjsip_tx_data:\n        pjsip_msg *msg\n        pj_pool_t *pool\n        pjsip_buffer buf\n        pjsip_tx_data_tp_info tp_info\n    struct pjsip_rx_data_tp_info:\n        pj_pool_t *pool\n        pjsip_transport *transport\n    struct pjsip_rx_data_pkt_info:\n        pj_time_val timestamp\n        char *packet\n        int len\n        char *src_name\n        int src_port\n    struct pjsip_rx_data_msg_info:\n        pjsip_msg *msg\n        pjsip_fromto_hdr *from_hdr \"from\"\n        pjsip_fromto_hdr *to_hdr \"to\"\n        pjsip_via_hdr *via\n    struct pjsip_rx_data:\n        pjsip_rx_data_pkt_info pkt_info\n        pjsip_rx_data_tp_info tp_info\n        pjsip_rx_data_msg_info msg_info\n    void *pjsip_hdr_clone(pj_pool_t *pool, void *hdr) nogil\n    void pjsip_msg_add_hdr(pjsip_msg *msg, pjsip_hdr *hdr) nogil\n    void *pjsip_msg_find_hdr(pjsip_msg *msg, pjsip_hdr_e type, void *start) nogil\n    void *pjsip_msg_find_hdr_by_name(pjsip_msg *msg, pj_str_t *name, void *start) nogil\n    void *pjsip_msg_find_remove_hdr_by_name(pjsip_msg *msg, pj_str_t *name, void *start) nogil\n    pjsip_generic_string_hdr *pjsip_generic_string_hdr_create(pj_pool_t *pool, pj_str_t *hname, pj_str_t *hvalue) nogil\n    pjsip_contact_hdr *pjsip_contact_hdr_create(pj_pool_t *pool) nogil\n    pjsip_expires_hdr *pjsip_expires_hdr_create(pj_pool_t *pool, int value) nogil\n    pjsip_msg_body *pjsip_msg_body_create(pj_pool_t *pool, pj_str_t *type, pj_str_t *subtype, pj_str_t *text) nogil\n    pjsip_msg_body *pjsip_msg_body_clone(pj_pool_t *pool, const pjsip_msg_body *body) nogil\n    pjsip_route_hdr *pjsip_route_hdr_init(pj_pool_t *pool, void *mem) nogil\n    void pjsip_sip_uri_init(pjsip_sip_uri *url, int secure) nogil\n    int pjsip_tx_data_dec_ref(pjsip_tx_data *tdata) nogil\n    void pjsip_tx_data_add_ref(pjsip_tx_data *tdata) nogil\n    pj_str_t *pjsip_uri_get_scheme(pjsip_uri *uri) nogil\n    void *pjsip_uri_get_uri(pjsip_uri *uri) nogil\n    int pjsip_uri_print(pjsip_uri_context_e context, void *uri, char *buf, unsigned int size) nogil\n    int PJSIP_URI_SCHEME_IS_SIP(pjsip_sip_uri *uri) nogil\n    enum:\n        PJSIP_PARSE_URI_AS_NAMEADDR\n    pjsip_uri *pjsip_parse_uri(pj_pool_t *pool, char *buf, unsigned int size, unsigned int options) nogil\n    void pjsip_method_init_np(pjsip_method *m, pj_str_t *str) nogil\n    pj_str_t *pjsip_get_status_text(int status_code) nogil\n    int pjsip_print_body(pjsip_msg_body *msg_body, char **buf, int *len)\n\n    # module\n    enum pjsip_module_priority:\n        PJSIP_MOD_PRIORITY_APPLICATION\n        PJSIP_MOD_PRIORITY_DIALOG_USAGE\n        PJSIP_MOD_PRIORITY_TRANSPORT_LAYER\n    struct pjsip_event\n    struct pjsip_transaction\n    struct pjsip_module:\n        pj_str_t name\n        int id\n        int priority\n        int on_rx_request(pjsip_rx_data *rdata) with gil\n        int on_rx_response(pjsip_rx_data *rdata) with gil\n        int on_tx_request(pjsip_tx_data *tdata) with gil\n        int on_tx_response(pjsip_tx_data *tdata) with gil\n        void on_tsx_state(pjsip_transaction *tsx, pjsip_event *event) with gil\n\n    # endpoint\n    struct pjsip_endpoint\n    int pjsip_endpt_create(pj_pool_factory *pf, char *name, pjsip_endpoint **endpt) nogil\n    void pjsip_endpt_destroy(pjsip_endpoint *endpt) nogil\n    pj_pool_t *pjsip_endpt_create_pool(pjsip_endpoint *endpt, char *pool_name, int initial, int increment) nogil\n    void pjsip_endpt_release_pool(pjsip_endpoint *endpt, pj_pool_t *pool) nogil\n    int pjsip_endpt_handle_events(pjsip_endpoint *endpt, pj_time_val *max_timeout) nogil\n    int pjsip_endpt_register_module(pjsip_endpoint *endpt, pjsip_module *module) nogil\n    int pjsip_endpt_schedule_timer(pjsip_endpoint *endpt, pj_timer_entry *entry, pj_time_val *delay) nogil\n    void pjsip_endpt_cancel_timer(pjsip_endpoint *endpt, pj_timer_entry *entry) nogil\n    enum:\n        PJSIP_H_ACCEPT\n        PJSIP_H_ALLOW\n        PJSIP_H_SUPPORTED\n    pjsip_hdr_ptr_const pjsip_endpt_get_capability(pjsip_endpoint *endpt, int htype, pj_str_t *hname) nogil\n    int pjsip_endpt_add_capability(pjsip_endpoint *endpt, pjsip_module *mod, int htype,\n                                   pj_str_t *hname, unsigned count, pj_str_t *tags) nogil\n    int pjsip_endpt_create_response(pjsip_endpoint *endpt, pjsip_rx_data *rdata,\n                                    int st_code, pj_str_t *st_text, pjsip_tx_data **p_tdata) nogil\n    int pjsip_endpt_send_response2(pjsip_endpoint *endpt, pjsip_rx_data *rdata,\n                                   pjsip_tx_data *tdata, void *token, void *cb) nogil\n    int pjsip_endpt_respond_stateless(pjsip_endpoint *endpt, pjsip_rx_data *rdata,\n                                      int st_code, pj_str_t *st_text, pjsip_hdr *hdr_list, pjsip_msg_body *body) nogil\n    int pjsip_endpt_create_request(pjsip_endpoint *endpt, pjsip_method *method, pj_str_t *target, pj_str_t *frm,\n                                   pj_str_t *to, pj_str_t *contact, pj_str_t *call_id,\n                                   int cseq,pj_str_t *text, pjsip_tx_data **p_tdata) nogil\n    pj_timer_heap_t *pjsip_endpt_get_timer_heap(pjsip_endpoint *endpt) nogil\n    int pjsip_endpt_create_resolver(pjsip_endpoint *endpt, pj_dns_resolver **p_resv) nogil\n    int pjsip_endpt_set_resolver(pjsip_endpoint *endpt, pj_dns_resolver *resv) nogil\n    pj_dns_resolver* pjsip_endpt_get_resolver(pjsip_endpoint *endpt) nogil\n\n    # transports\n    enum pjsip_ssl_method:\n        PJSIP_TLSV1_METHOD\n        PJSIP_SSLV23_METHOD\n    struct pjsip_transport:\n        char *type_name\n        pj_sockaddr local_addr\n        pjsip_host_port local_name\n        pjsip_host_port remote_name\n    struct pjsip_tpfactory:\n        pjsip_host_port addr_name\n        int destroy(pjsip_tpfactory *factory) nogil\n    struct pjsip_tls_setting:\n        pj_str_t ca_list_file\n        pj_str_t cert_file\n        pj_str_t privkey_file\n        int method\n        int verify_server\n        pj_time_val timeout\n    enum pjsip_tpselector_type:\n        PJSIP_TPSELECTOR_TRANSPORT\n    union pjsip_tpselector_u:\n        pjsip_transport *transport\n    struct pjsip_tpselector:\n        pjsip_tpselector_type type\n        pjsip_tpselector_u u\n    int pjsip_transport_shutdown(pjsip_transport *tp) nogil\n    int pjsip_udp_transport_start(pjsip_endpoint *endpt, pj_sockaddr_in *local, pjsip_host_port *a_name,\n                                  unsigned int async_cnt, pjsip_transport **p_transport) nogil\n    int pjsip_tcp_transport_start2(pjsip_endpoint *endpt, pj_sockaddr_in *local, pjsip_host_port *a_name,\n                                   unsigned int async_cnt, pjsip_tpfactory **p_tpfactory) nogil\n    int pjsip_tls_transport_start(pjsip_endpoint *endpt, pjsip_tls_setting *opt, pj_sockaddr_in *local,\n                                  pjsip_host_port *a_name, unsigned async_cnt, pjsip_tpfactory **p_factory) nogil\n    void pjsip_tls_setting_default(pjsip_tls_setting *tls_opt) nogil\n    int pjsip_transport_shutdown(pjsip_transport *tp) nogil\n\n    # transaction layer\n    enum pjsip_role_e:\n        PJSIP_ROLE_UAC\n        PJSIP_ROLE_UAS\n    enum pjsip_tsx_state_e:\n        PJSIP_TSX_STATE_TRYING\n        PJSIP_TSX_STATE_PROCEEDING\n        PJSIP_TSX_STATE_COMPLETED\n        PJSIP_TSX_STATE_TERMINATED\n    struct pjsip_transaction:\n        int status_code\n        pj_str_t status_text\n        pjsip_role_e role\n        pjsip_tx_data *last_tx\n        pjsip_tsx_state_e state\n        void **mod_data\n        pjsip_method method\n    int pjsip_tsx_layer_init_module(pjsip_endpoint *endpt) nogil\n    int pjsip_tsx_create_key(pj_pool_t *pool, pj_str_t *key, pjsip_role_e role,\n                             pjsip_method *method, pjsip_rx_data *rdata) nogil\n    pjsip_transaction *pjsip_tsx_layer_find_tsx(pj_str_t *key, int lock) nogil\n    int pjsip_tsx_create_uac(pjsip_module *tsx_user, pjsip_tx_data *tdata, pjsip_transaction **p_tsx) nogil\n    int pjsip_tsx_terminate(pjsip_transaction *tsx, int code) nogil\n    int pjsip_tsx_send_msg(pjsip_transaction *tsx, pjsip_tx_data *tdata) nogil\n    pjsip_transaction *pjsip_rdata_get_tsx(pjsip_rx_data *rdata) nogil\n    int pjsip_tsx_create_uas(pjsip_module *tsx_user, pjsip_rx_data *rdata, pjsip_transaction **p_tsx) nogil\n    void pjsip_tsx_recv_msg(pjsip_transaction *tsx, pjsip_rx_data *rdata) nogil\n\n    # event\n    enum pjsip_event_id_e:\n        PJSIP_EVENT_TSX_STATE\n        PJSIP_EVENT_RX_MSG\n        PJSIP_EVENT_TX_MSG\n        PJSIP_EVENT_TRANSPORT_ERROR\n        PJSIP_EVENT_TIMER\n    union pjsip_event_body_tsx_state_src:\n        pjsip_rx_data *rdata\n        pjsip_tx_data *tdata\n    struct pjsip_event_body_tsx_state:\n        pjsip_event_body_tsx_state_src src\n        pjsip_transaction *tsx\n        pjsip_event_id_e type\n    struct pjsip_event_body_rx_msg:\n        pjsip_rx_data *rdata\n    union pjsip_event_body:\n        pjsip_event_body_tsx_state tsx_state\n        pjsip_event_body_rx_msg rx_msg\n    struct pjsip_event:\n        pjsip_event_id_e type\n        pjsip_event_body body\n    int pjsip_endpt_send_request(pjsip_endpoint *endpt, pjsip_tx_data *tdata, int timeout,\n                                 void *token, void cb(void *token, pjsip_event *e) with gil) nogil\n\n    # auth\n    enum:\n        PJSIP_EFAILEDCREDENTIAL\n    enum pjsip_cred_data_type:\n        PJSIP_CRED_DATA_PLAIN_PASSWD\n        PJSIP_CRED_DATA_DIGEST\n    struct pjsip_cred_info:\n        pj_str_t realm\n        pj_str_t scheme\n        pj_str_t username\n        pjsip_cred_data_type data_type\n        pj_str_t data\n    struct pjsip_auth_clt_sess:\n        pass\n    int pjsip_auth_clt_init(pjsip_auth_clt_sess *sess, pjsip_endpoint *endpt, pj_pool_t *pool, unsigned int options) nogil\n    int pjsip_auth_clt_set_credentials(pjsip_auth_clt_sess *sess, int cred_cnt, pjsip_cred_info *c) nogil\n    int pjsip_auth_clt_reinit_req(pjsip_auth_clt_sess *sess, pjsip_rx_data *rdata,\n                                  pjsip_tx_data *old_request, pjsip_tx_data **new_request) nogil\n\n    # dialog layer\n    ctypedef pjsip_module pjsip_user_agent\n    struct pjsip_dlg_party:\n        pjsip_contact_hdr *contact\n        pjsip_fromto_hdr *info\n    struct pjsip_dialog:\n        pjsip_auth_clt_sess auth_sess\n        pjsip_cid_hdr *call_id\n        pj_pool_t *pool\n        pjsip_dlg_party local\n        pjsip_dlg_party remote\n    struct pjsip_ua_init_param:\n        pjsip_dialog *on_dlg_forked(pjsip_dialog *first_set, pjsip_rx_data *res) nogil\n    int pjsip_ua_init_module(pjsip_endpoint *endpt, pjsip_ua_init_param *prm) nogil\n    pjsip_user_agent *pjsip_ua_instance() nogil\n    int pjsip_dlg_create_uac(pjsip_user_agent *ua, pj_str_t *local_uri, pj_str_t *local_contact,\n                             pj_str_t *remote_uri, pj_str_t *target, pjsip_dialog **p_dlg) nogil\n    int pjsip_dlg_set_route_set(pjsip_dialog *dlg, pjsip_route_hdr *route_set) nogil\n    int pjsip_dlg_create_uas_and_inc_lock(pjsip_user_agent *ua, pjsip_rx_data *rdata, pj_str_t *contact, pjsip_dialog **p_dlg) nogil\n    int pjsip_dlg_terminate(pjsip_dialog *dlg) nogil\n    int pjsip_dlg_set_transport(pjsip_dialog *dlg, pjsip_tpselector *sel) nogil\n    int pjsip_dlg_respond(pjsip_dialog *dlg, pjsip_rx_data *rdata, int st_code,\n                          pj_str_t *st_text, pjsip_hdr *hdr_list, pjsip_msg_body *body) nogil\n    int pjsip_dlg_create_response(pjsip_dialog *dlg, pjsip_rx_data *rdata,\n                                  int st_code, pj_str_t *st_text, pjsip_tx_data **tdata) nogil\n    int pjsip_dlg_modify_response(pjsip_dialog *dlg, pjsip_tx_data *tdata, int st_code, pj_str_t *st_text) nogil\n    int pjsip_dlg_send_response(pjsip_dialog *dlg, pjsip_transaction *tsx, pjsip_tx_data *tdata) nogil\n    void pjsip_dlg_inc_lock(pjsip_dialog *dlg) nogil\n    void pjsip_dlg_dec_lock(pjsip_dialog *dlg) nogil\n    int pjsip_dlg_inc_session(pjsip_dialog *dlg, pjsip_module *mod) nogil\n    int pjsip_dlg_dec_session(pjsip_dialog *dlg, pjsip_module *mod) nogil\n\ncdef extern from \"pjsip-simple/evsub_msg.h\":\n    struct pjsip_event_hdr:\n        pj_str_t event_type\n        pj_str_t id_param\n        pjsip_param other_param\n    struct pjsip_sub_state_hdr:\n        pj_str_t sub_state\n        pj_str_t reason_param\n        int expires_param\n        int retry_after\n        pjsip_param other_param\n    pjsip_event_hdr *pjsip_event_hdr_create(pj_pool_t *pool) nogil\n\ncdef extern from \"pjsip_simple.h\":\n\n    # subscribe / notify\n    enum:\n        PJSIP_EVSUB_NO_EVENT_ID\n    enum pjsip_evsub_state:\n        PJSIP_EVSUB_STATE_PENDING\n        PJSIP_EVSUB_STATE_ACTIVE\n        PJSIP_EVSUB_STATE_TERMINATED\n    struct pjsip_evsub\n    struct pjsip_evsub_user:\n        void on_evsub_state(pjsip_evsub *sub, pjsip_event *event) with gil\n        void on_tsx_state(pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event) with gil\n        void on_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code, pj_str_t **p_st_text,\n                           pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil\n        void on_rx_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code,\n                          pj_str_t **p_st_text,pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil\n        void on_client_refresh(pjsip_evsub *sub) with gil\n        void on_server_timeout(pjsip_evsub *sub) with gil\n    int pjsip_evsub_init_module(pjsip_endpoint *endpt) nogil\n    int pjsip_evsub_register_pkg(pjsip_module *pkg_mod, pj_str_t *event_name,\n                                 unsigned int expires, unsigned int accept_cnt, pj_str_t *accept) nogil\n    int pjsip_evsub_create_uac(pjsip_dialog *dlg, pjsip_evsub_user *user_cb,\n                               pj_str_t *event, int option, pjsip_evsub **p_evsub) nogil\n    int pjsip_evsub_create_uas(pjsip_dialog *dlg, pjsip_evsub_user *user_cb,\n                               pjsip_rx_data *rdata, unsigned int option, pjsip_evsub **p_evsub) nogil\n    int pjsip_evsub_initiate(pjsip_evsub *sub, void *method, unsigned int expires, pjsip_tx_data **p_tdata) nogil\n    int pjsip_evsub_send_request(pjsip_evsub *sub, pjsip_tx_data *tdata) nogil\n    int pjsip_evsub_terminate(pjsip_evsub *sub, int notify) nogil\n    char *pjsip_evsub_get_state_name(pjsip_evsub *sub) nogil\n    void pjsip_evsub_set_mod_data(pjsip_evsub *sub, int mod_id, void *data) nogil\n    void *pjsip_evsub_get_mod_data(pjsip_evsub *sub, int mod_id) nogil\n    void pjsip_evsub_update_expires(pjsip_evsub *sub, int interval) nogil\n    void pjsip_evsub_set_timer(pjsip_evsub *sub, int timer_id, int seconds) nogil\n    pjsip_hdr *pjsip_evsub_get_allow_events_hdr(pjsip_module *m) nogil\n    int pjsip_evsub_notify(pjsip_evsub *sub, pjsip_evsub_state state,\n                           pj_str_t *state_str, pj_str_t *reason, pjsip_tx_data **p_tdata) nogil\n\ncdef extern from \"pjsip_ua.h\":\n\n    # 100rel / PRACK\n    int pjsip_100rel_init_module(pjsip_endpoint *endpt) nogil\n\n    # invite sessions\n    enum pjsip_inv_option:\n        PJSIP_INV_SUPPORT_100REL\n    enum pjsip_inv_state:\n        PJSIP_INV_STATE_INCOMING\n        PJSIP_INV_STATE_CONFIRMED\n    enum pjmedia_mod_offer_flag:\n        PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE\n    struct pjsip_inv_session:\n        pjsip_inv_state state\n        void **mod_data\n        pjmedia_sdp_neg *neg\n        unsigned sdp_neg_flags\n        int cause\n        pj_str_t cause_text\n        int cancelling\n        pjsip_transaction *invite_tsx\n    struct pjsip_inv_callback:\n        void on_state_changed(pjsip_inv_session *inv, pjsip_event *e) with gil\n        void on_new_session(pjsip_inv_session *inv, pjsip_event *e) with gil\n        void on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e) with gil\n        void on_media_update(pjsip_inv_session *inv, int status) with gil\n        int on_rx_reinvite(pjsip_inv_session *inv, pjmedia_sdp_session_ptr_const offer, pjsip_rx_data *rdata) with gil\n    int pjsip_inv_usage_init(pjsip_endpoint *endpt, pjsip_inv_callback *cb) nogil\n    int pjsip_inv_terminate(pjsip_inv_session *inv, int st_code, int notify) nogil\n    int pjsip_inv_end_session(pjsip_inv_session *inv, int st_code, pj_str_t *st_text, pjsip_tx_data **p_tdata) nogil\n    int pjsip_inv_cancel_reinvite(pjsip_inv_session *inv, pjsip_tx_data **p_tdata) nogil\n    int pjsip_inv_send_msg(pjsip_inv_session *inv, pjsip_tx_data *tdata) nogil\n    int pjsip_inv_verify_request(pjsip_rx_data *rdata, unsigned int *options, pjmedia_sdp_session *sdp,\n                                 pjsip_dialog *dlg, pjsip_endpoint *endpt, pjsip_tx_data **tdata) nogil\n    int pjsip_inv_create_uas(pjsip_dialog *dlg, pjsip_rx_data *rdata, pjmedia_sdp_session *local_sdp,\n                             unsigned int options, pjsip_inv_session **p_inv) nogil\n    int pjsip_inv_initial_answer(pjsip_inv_session *inv, pjsip_rx_data *rdata, int st_code,\n                                 pj_str_t *st_text, pjmedia_sdp_session *sdp, pjsip_tx_data **p_tdata) nogil\n    int pjsip_inv_answer(pjsip_inv_session *inv, int st_code, pj_str_t *st_text,\n                         pjmedia_sdp_session *local_sdp, pjsip_tx_data **p_tdata) nogil\n    int pjsip_inv_create_uac(pjsip_dialog *dlg, pjmedia_sdp_session *local_sdp,\n                             unsigned int options, pjsip_inv_session **p_inv) nogil\n    int pjsip_inv_invite(pjsip_inv_session *inv, pjsip_tx_data **p_tdata) nogil\n    char *pjsip_inv_state_name(pjsip_inv_state state) nogil\n    int pjsip_inv_reinvite(pjsip_inv_session *inv, pj_str_t *new_contact,\n                           pjmedia_sdp_session *new_offer, pjsip_tx_data **p_tdata) nogil\n    int pjsip_create_sdp_body(pj_pool_t *pool, pjmedia_sdp_session *sdp, pjsip_msg_body **p_body) nogil\n\n    # Replaces\n    struct pjsip_replaces_hdr:\n        pj_str_t call_id\n        pj_str_t to_tag\n        pj_str_t from_tag\n        int early_only\n        pjsip_param other_param\n    pjsip_replaces_hdr *pjsip_replaces_hdr_create(pj_pool_t *pool) nogil\n    int pjsip_replaces_verify_request(pjsip_rx_data *rdata, pjsip_dialog **p_dlg, int lock_dlg, pjsip_tx_data **p_tdata) nogil\n    int pjsip_replaces_init_module(pjsip_endpoint *endpt) nogil\n\n\n# declarations\n\n# core.util\n\ncdef class frozenlist(object):\n    # attributes\n    cdef int initialized\n    cdef list list\n    cdef long hash\n\ncdef class frozendict(object):\n    # attributes\n    cdef int initialized\n    cdef dict dict\n    cdef long hash\n\ncdef class PJSTR(object):\n    # attributes\n    cdef pj_str_t pj_str\n    cdef object str\n\n# core.lib\n\ncdef class PJLIB(object):\n    # attributes\n    cdef int _init_done\n\ncdef class PJCachingPool(object):\n    # attributes\n    cdef pj_caching_pool _obj\n    cdef int _init_done\n\ncdef class PJSIPEndpoint(object):\n    # attributes\n    cdef pjsip_endpoint *_obj\n    cdef pj_pool_t *_pool\n    cdef pjsip_transport *_udp_transport\n    cdef pjsip_tpfactory *_tcp_transport\n    cdef pjsip_tpfactory *_tls_transport\n    cdef int _tls_verify_server\n    cdef PJSTR _tls_ca_file\n    cdef PJSTR _tls_cert_file\n    cdef PJSTR _tls_privkey_file\n    cdef object _local_ip_used\n    cdef int _tls_timeout\n\n    # private methods\n    cdef int _make_local_addr(self, pj_sockaddr_in *local_addr, object ip_address, int port) except -1\n    cdef int _start_udp_transport(self, int port) except -1\n    cdef int _stop_udp_transport(self) except -1\n    cdef int _start_tcp_transport(self, int port) except -1\n    cdef int _stop_tcp_transport(self) except -1\n    cdef int _start_tls_transport(self, port) except -1\n    cdef int _stop_tls_transport(self) except -1\n    cdef int _set_dns_nameservers(self, list servers) except -1\n\ncdef class PJMEDIAEndpoint(object):\n    # attributes\n    cdef pjmedia_endpt *_obj\n    cdef pj_pool_t *_pool\n    cdef int _has_audio_codecs\n    cdef int _has_video\n    cdef int _has_ffmpeg_video\n    cdef int _has_vpx\n\n    # private methods\n    cdef list _get_codecs(self)\n    cdef list _get_all_codecs(self)\n    cdef list _get_current_codecs(self)\n    cdef int _set_codecs(self, list req_codecs) except -1\n    cdef list _get_video_codecs(self)\n    cdef list _get_all_video_codecs(self)\n    cdef list _get_current_video_codecs(self)\n    cdef int _set_video_codecs(self, list req_codecs) except -1\n    cdef void _audio_subsystem_init(self, PJCachingPool caching_pool)\n    cdef void _audio_subsystem_shutdown(self)\n    cdef void _video_subsystem_init(self, PJCachingPool caching_pool)\n    cdef void _video_subsystem_shutdown(self)\n    cdef void _set_h264_options(self, str profile, int level)\n    cdef void _set_video_options(self, tuple max_resolution, int max_framerate, float max_bitrate)\n\n# core.helper\n\ncdef class BaseCredentials(object):\n    # attributes\n    cdef pjsip_cred_info _credentials\n\n    # private methods\n    cdef pjsip_cred_info* get_cred_info(self)\n\ncdef class Credentials(BaseCredentials):\n    # attributes\n    cdef str _username\n    cdef str _realm\n    cdef str _password\n    cdef bint _digest\n\ncdef class FrozenCredentials(BaseCredentials):\n    # attributes\n    cdef int initialized\n    cdef readonly str username\n    cdef readonly str realm\n    cdef readonly str password\n    cdef readonly bint digest\n\ncdef class BaseSIPURI(object):\n    pass\n\ncdef class SIPURI(BaseSIPURI):\n    # attributes\n    cdef public object user\n    cdef public object password\n    cdef public object host\n    cdef public bint secure\n    cdef public dict parameters\n    cdef public dict headers\n    cdef object _port\n\ncdef class FrozenSIPURI(BaseSIPURI):\n    # attributes\n    cdef int initialized\n    cdef readonly object user\n    cdef readonly object password\n    cdef readonly object host\n    cdef readonly object port\n    cdef readonly bint secure\n    cdef readonly frozendict parameters\n    cdef readonly frozendict headers\n\ncdef SIPURI SIPURI_create(pjsip_sip_uri *base_uri)\ncdef FrozenSIPURI FrozenSIPURI_create(pjsip_sip_uri *base_uri)\n\n# core.headers\n\ncdef class BaseHeader(object):\n    pass\n\ncdef class Header(BaseHeader):\n    # attributes\n    cdef str _name\n    cdef str _body\n\ncdef class FrozenHeader(BaseHeader):\n    # attributes\n    cdef readonly str name\n    cdef readonly str body\n\ncdef class BaseContactHeader(object):\n    pass\n\ncdef class ContactHeader(BaseContactHeader):\n    # attributes\n    cdef SIPURI _uri\n    cdef unicode _display_name\n    cdef dict _parameters\n\ncdef class FrozenContactHeader(BaseContactHeader):\n    # attributes\n    cdef int initialized\n    cdef readonly FrozenSIPURI uri\n    cdef readonly unicode display_name\n    cdef readonly frozendict parameters\n\ncdef class BaseContentTypeHeader(object):\n    pass\n\ncdef class ContentTypeHeader(BaseContentTypeHeader):\n    # attributes\n    cdef str _content_type\n    cdef dict _parameters\n\ncdef class FrozenContentTypeHeader(BaseContentTypeHeader):\n    # attributes\n    cdef int initialized\n    cdef readonly str _content_type\n    cdef readonly frozendict parameters\n\ncdef class BaseIdentityHeader(object):\n    pass\n\ncdef class IdentityHeader(BaseIdentityHeader):\n    # attributes\n    cdef SIPURI _uri\n    cdef public unicode display_name\n    cdef dict _parameters\n\ncdef class FrozenIdentityHeader(BaseIdentityHeader):\n    # attributes\n    cdef int initialized\n    cdef readonly FrozenSIPURI uri\n    cdef readonly unicode display_name\n    cdef readonly frozendict parameters\n\ncdef class FromHeader(IdentityHeader):\n    pass\n\ncdef class FrozenFromHeader(FrozenIdentityHeader):\n    pass\n\ncdef class ToHeader(IdentityHeader):\n    pass\n\ncdef class FrozenToHeader(FrozenIdentityHeader):\n    pass\n\ncdef class RouteHeader(IdentityHeader):\n    pass\n\ncdef class FrozenRouteHeader(FrozenIdentityHeader):\n    pass\n\ncdef class RecordRouteHeader(IdentityHeader):\n    pass\n\ncdef class FrozenRecordRouteHeader(FrozenIdentityHeader):\n    pass\n\ncdef class BaseRetryAfterHeader(object):\n    pass\n\ncdef class RetryAfterHeader(BaseRetryAfterHeader):\n    # attributes\n    cdef public int seconds\n    cdef public str comment\n    cdef dict _parameters\n\ncdef class FrozenRetryAfterHeader(BaseRetryAfterHeader):\n    # attributes\n    cdef int initialized\n    cdef readonly int seconds\n    cdef readonly str comment\n    cdef readonly frozendict parameters\n\ncdef class BaseViaHeader(object):\n    pass\n\ncdef class ViaHeader(BaseViaHeader):\n    # attributes\n    cdef str _transport\n    cdef str _host\n    cdef int _port\n    cdef dict _parameters\n\ncdef class FrozenViaHeader(BaseViaHeader):\n    # attributes\n    cdef int initialized\n    cdef readonly str transport\n    cdef readonly str host\n    cdef readonly int port\n    cdef readonly frozendict parameters\n\ncdef class BaseWarningHeader(object):\n    pass\n\ncdef class WarningHeader(BaseWarningHeader):\n    # attributes\n    cdef int _code\n    cdef str _agent\n    cdef str _text\n\ncdef class FrozenWarningHeader(BaseWarningHeader):\n    # attributes\n    cdef int initialized\n    cdef readonly int code\n    cdef readonly str agent\n    cdef readonly str text\n\ncdef class BaseEventHeader(object):\n    pass\n\ncdef class EventHeader(BaseEventHeader):\n    # attributes\n    cdef public event\n    cdef dict _parameters\n\ncdef class FrozenEventHeader(BaseEventHeader):\n    # attributes\n    cdef int initialized\n    cdef readonly str event\n    cdef readonly frozendict parameters\n\ncdef class BaseSubscriptionStateHeader(object):\n    pass\n\ncdef class SubscriptionStateHeader(BaseSubscriptionStateHeader):\n    # attributes\n    cdef public state\n    cdef dict _parameters\n\ncdef class FrozenSubscriptionStateHeader(BaseSubscriptionStateHeader):\n    # attributes\n    cdef int initialized\n    cdef readonly str state\n    cdef readonly frozendict parameters\n\ncdef class BaseReasonHeader(object):\n    pass\n\ncdef class ReasonHeader(BaseReasonHeader):\n    # attributes\n    cdef public str protocol\n    cdef public dict parameters\n\ncdef class FrozenReasonHeader(BaseReasonHeader):\n    # attributes\n    cdef int initialized\n    cdef readonly str protocol\n    cdef readonly frozendict parameters\n\ncdef class BaseReferToHeader(object):\n    pass\n\ncdef class ReferToHeader(BaseReferToHeader):\n    # attributes\n    cdef public str uri\n    cdef dict _parameters\n\ncdef class FrozenReferToHeader(BaseReferToHeader):\n    # attributes\n    cdef int initialized\n    cdef readonly str uri\n    cdef readonly frozendict parameters\n\ncdef class BaseSubjectHeader(object):\n    pass\n\ncdef class SubjectHeader(BaseSubjectHeader):\n    # attributes\n    cdef public unicode subject\n\ncdef class FrozenSubjectHeader(BaseSubjectHeader):\n    # attributes\n    cdef int initialized\n    cdef readonly unicode subject\n\ncdef class BaseReplacesHeader(object):\n    pass\n\ncdef class ReplacesHeader(BaseReplacesHeader):\n    # attributes\n    cdef public str call_id\n    cdef public str from_tag\n    cdef public str to_tag\n    cdef public int early_only\n    cdef dict _parameters\n\ncdef class FrozenReplacesHeader(BaseReplacesHeader):\n    # attributes\n    cdef int initialized\n    cdef readonly str call_id\n    cdef readonly str from_tag\n    cdef readonly str to_tag\n    cdef readonly int early_only\n    cdef readonly frozendict parameters\n\ncdef Header Header_create(pjsip_generic_string_hdr *header)\ncdef FrozenHeader FrozenHeader_create(pjsip_generic_string_hdr *header)\ncdef ContactHeader ContactHeader_create(pjsip_contact_hdr *header)\ncdef FrozenContactHeader FrozenContactHeader_create(pjsip_contact_hdr *header)\ncdef ContentTypeHeader ContentTypeHeader_create(pjsip_ctype_hdr *header)\ncdef FrozenContentTypeHeader FrozenContentTypeHeader_create(pjsip_ctype_hdr *header)\ncdef FromHeader FromHeader_create(pjsip_fromto_hdr *header)\ncdef FrozenFromHeader FrozenFromHeader_create(pjsip_fromto_hdr *header)\ncdef ToHeader ToHeader_create(pjsip_fromto_hdr *header)\ncdef FrozenToHeader FrozenToHeader_create(pjsip_fromto_hdr *header)\ncdef RouteHeader RouteHeader_create(pjsip_routing_hdr *header)\ncdef FrozenRouteHeader FrozenRouteHeader_create(pjsip_routing_hdr *header)\ncdef RecordRouteHeader RecordRouteHeader_create(pjsip_routing_hdr *header)\ncdef FrozenRecordRouteHeader FrozenRecordRouteHeader_create(pjsip_routing_hdr *header)\ncdef RetryAfterHeader RetryAfterHeader_create(pjsip_retry_after_hdr *header)\ncdef FrozenRetryAfterHeader FrozenRetryAfterHeader_create(pjsip_retry_after_hdr *header)\ncdef ViaHeader ViaHeader_create(pjsip_via_hdr *header)\ncdef FrozenViaHeader FrozenViaHeader_create(pjsip_via_hdr *header)\ncdef EventHeader EventHeader_create(pjsip_event_hdr *header)\ncdef FrozenEventHeader FrozenEventHeader_create(pjsip_event_hdr *header)\ncdef SubscriptionStateHeader SubscriptionStateHeader_create(pjsip_sub_state_hdr *header)\ncdef FrozenSubscriptionStateHeader FrozenSubscriptionStateHeader_create(pjsip_sub_state_hdr *header)\ncdef ReferToHeader ReferToHeader_create(pjsip_generic_string_hdr *header)\ncdef FrozenReferToHeader FrozenReferToHeader_create(pjsip_generic_string_hdr *header)\ncdef SubjectHeader SubjectHeader_create(pjsip_generic_string_hdr *header)\ncdef FrozenSubjectHeader FrozenSubjectHeader_create(pjsip_generic_string_hdr *header)\ncdef ReplacesHeader ReplacesHeader_create(pjsip_replaces_hdr *header)\ncdef FrozenReplacesHeader FrozenReplacesHeader_create(pjsip_replaces_hdr *header)\n\n# core.util\n\ncdef int _str_to_pj_str(object string, pj_str_t *pj_str) except -1\ncdef object _pj_str_to_str(pj_str_t pj_str)\ncdef object _pj_status_to_str(int status)\ncdef object _pj_status_to_def(int status)\ncdef dict _pjsip_param_to_dict(pjsip_param *param_list)\ncdef int _dict_to_pjsip_param(object params, pjsip_param *param_list, pj_pool_t *pool)\ncdef int _pjsip_msg_to_dict(pjsip_msg *msg, dict info_dict) except -1\ncdef int _is_valid_ip(int af, object ip) except -1\ncdef int _get_ip_version(object ip) except -1\ncdef int _add_headers_to_tdata(pjsip_tx_data *tdata, object headers) except -1\ncdef int _remove_headers_from_tdata(pjsip_tx_data *tdata, object headers) except -1\ncdef int _BaseSIPURI_to_pjsip_sip_uri(BaseSIPURI uri, pjsip_sip_uri *pj_uri, pj_pool_t *pool) except -1\ncdef int _BaseRouteHeader_to_pjsip_route_hdr(BaseIdentityHeader header, pjsip_route_hdr *pj_header, pj_pool_t *pool) except -1\n\n# core.ua\n\nctypedef int (*timer_callback)(object, object) except -1\ncdef class Timer(object):\n    # attributes\n    cdef int _scheduled\n    cdef double schedule_time\n    cdef timer_callback callback\n    cdef object obj\n\n    # private methods\n    cdef int schedule(self, float delay, timer_callback callback, object obj) except -1\n    cdef int cancel(self) except -1\n    cdef int call(self) except -1\n\ncdef class PJSIPThread(object):\n    # attributes\n    cdef pj_thread_t *_obj\n    cdef long _thread_desc[PJ_THREAD_DESC_SIZE]\n\ncdef class PJSIPUA(object):\n    # attributes\n    cdef object _threads\n    cdef object _event_handler\n    cdef list _timers\n    cdef PJLIB _pjlib\n    cdef PJCachingPool _caching_pool\n    cdef PJSIPEndpoint _pjsip_endpoint\n    cdef PJMEDIAEndpoint _pjmedia_endpoint\n    cdef pjsip_module _module\n    cdef PJSTR _module_name\n    cdef pjsip_module _opus_fix_module\n    cdef PJSTR _opus_fix_module_name\n    cdef pjsip_module _trace_module\n    cdef PJSTR _trace_module_name\n    cdef pjsip_module _ua_tag_module\n    cdef PJSTR _ua_tag_module_name\n    cdef pjsip_module _event_module\n    cdef PJSTR _event_module_name\n    cdef int _trace_sip\n    cdef int _detect_sip_loops\n    cdef int _enable_colorbar_device\n    cdef PJSTR _user_agent\n    cdef object _events\n    cdef object _sent_messages\n    cdef object _ip_address\n    cdef int _rtp_port_start\n    cdef int _rtp_port_count\n    cdef int _rtp_port_usable_count\n    cdef int _rtp_port_index\n    cdef pj_stun_config _stun_cfg\n    cdef int _fatal_error\n    cdef set _incoming_events\n    cdef set _incoming_requests\n    cdef pj_rwmutex_t *audio_change_rwlock\n    cdef pj_mutex_t *video_lock\n    cdef list old_devices\n    cdef list old_video_devices\n    cdef object _zrtp_cache\n\n    # private methods\n    cdef object _get_sound_devices(self, int is_output)\n    cdef object _get_default_sound_device(self, int is_output)\n    cdef object _get_video_devices(self)\n    cdef object _get_default_video_device(self)\n    cdef int _poll_log(self) except -1\n    cdef int _handle_exception(self, int is_fatal) except -1\n    cdef int _check_self(self) except -1\n    cdef int _check_thread(self) except -1\n    cdef int _add_timer(self, Timer timer) except -1\n    cdef int _remove_timer(self, Timer timer) except -1\n    cdef int _cb_rx_request(self, pjsip_rx_data *rdata) except 0\n\n    cdef pj_pool_t* create_memory_pool(self, bytes name, int initial_size, int resize_size)\n    cdef void release_memory_pool(self, pj_pool_t* pool)\n    cdef void reset_memory_pool(self, pj_pool_t* pool)\n\ncdef int _PJSIPUA_cb_rx_request(pjsip_rx_data *rdata) with gil\ncdef void _cb_detect_nat_type(void *user_data, pj_stun_nat_detect_result_ptr_const res) with gil\ncdef int _cb_opus_fix_tx(pjsip_tx_data *tdata) with gil\ncdef int _cb_trace_rx(pjsip_rx_data *rdata) with gil\ncdef int _cb_trace_tx(pjsip_tx_data *tdata) with gil\ncdef int _cb_add_user_agent_hdr(pjsip_tx_data *tdata) with gil\ncdef int _cb_add_server_hdr(pjsip_tx_data *tdata) with gil\ncdef PJSIPUA _get_ua()\ncdef int deallocate_weakref(object weak_ref, object timer) except -1 with gil\n\n# core.sound\n\ncdef class AudioMixer(object):\n    # attributes\n    cdef int _input_volume\n    cdef int _output_volume\n    cdef bint _muted\n    cdef pj_mutex_t *_lock\n    cdef pj_pool_t *_conf_pool\n    cdef pj_pool_t *_snd_pool\n    cdef pjmedia_conf *_obj\n    cdef pjmedia_master_port *_master_port\n    cdef pjmedia_port *_null_port\n    cdef pjmedia_snd_port *_snd\n    cdef list _connected_slots\n    cdef readonly int ec_tail_length\n    cdef readonly int sample_rate\n    cdef readonly int slot_count\n    cdef readonly int used_slot_count\n    cdef readonly unicode input_device\n    cdef readonly unicode output_device\n    cdef readonly unicode real_input_device\n    cdef readonly unicode real_output_device\n\n    # private methods\n    cdef void _start_sound_device(self, PJSIPUA ua, unicode input_device, unicode output_device, int ec_tail_length)\n    cdef void _stop_sound_device(self, PJSIPUA ua)\n    cdef int _add_port(self, PJSIPUA ua, pj_pool_t *pool, pjmedia_port *port) except -1 with gil\n    cdef int _remove_port(self, PJSIPUA ua, unsigned int slot) except -1 with gil\n    cdef int _cb_postpoll_stop_sound(self, timer) except -1\n\ncdef class ToneGenerator(object):\n    # attributes\n    cdef int _slot\n    cdef int _volume\n    cdef pj_mutex_t *_lock\n    cdef pj_pool_t *_pool\n    cdef pjmedia_port *_obj\n    cdef Timer _timer\n    cdef readonly AudioMixer mixer\n\n    # private methods\n    cdef PJSIPUA _get_ua(self, int raise_exception)\n    cdef int _stop(self, PJSIPUA ua) except -1\n    cdef int _cb_check_done(self, timer) except -1\n\ncdef class RecordingWaveFile(object):\n    # attributes\n    cdef int _slot\n    cdef int _was_started\n    cdef pj_mutex_t *_lock\n    cdef pj_pool_t *_pool\n    cdef pjmedia_port *_port\n    cdef readonly str filename\n    cdef readonly AudioMixer mixer\n\n    # private methods\n    cdef PJSIPUA _check_ua(self)\n    cdef int _stop(self, PJSIPUA ua) except -1\n\ncdef class WaveFile(object):\n    # attributes\n    cdef object __weakref__\n    cdef object weakref\n    cdef int _slot\n    cdef int _volume\n    cdef pj_mutex_t *_lock\n    cdef pj_pool_t *_pool\n    cdef pjmedia_port *_port\n    cdef readonly str filename\n    cdef readonly AudioMixer mixer\n\n    # private methods\n    cdef PJSIPUA _check_ua(self)\n    cdef int _stop(self, PJSIPUA ua, int notify) except -1\n    cdef int _cb_eof(self, timer) except -1\n\ncdef class MixerPort(object):\n    cdef int _slot\n    cdef int _was_started\n    cdef pj_mutex_t *_lock\n    cdef pj_pool_t *_pool\n    cdef pjmedia_port *_port\n    cdef readonly AudioMixer mixer\n\n    # private methods\n    cdef PJSIPUA _check_ua(self)\n    cdef int _stop(self, PJSIPUA ua) except -1\n\ncdef int _AudioMixer_dealloc_handler(object obj) except -1\ncdef int cb_play_wav_eof(pjmedia_port *port, void *user_data) with gil\n\n# core.video\n\ncdef class VideoFrame(object):\n    cdef readonly str data\n    cdef readonly int width\n    cdef readonly int height\n\ncdef class VideoConsumer(object):\n    cdef pjmedia_port *consumer_port\n    cdef pjmedia_vid_port *_video_port\n    cdef pj_pool_t *_pool\n    cdef pj_mutex_t *_lock\n    cdef int _running\n    cdef int _closed\n    cdef VideoProducer _producer\n    cdef object __weakref__\n    cdef object weakref\n\n    cdef void _set_producer(self, VideoProducer producer)\n\ncdef class VideoProducer(object):\n    cdef pjmedia_port *producer_port\n    cdef pjmedia_vid_port *_video_port\n    cdef pj_pool_t *_pool\n    cdef pj_mutex_t *_lock\n    cdef int _running\n    cdef int _started\n    cdef int _closed\n    cdef object _consumers\n\n    cdef void _add_consumer(self, VideoConsumer consumer)\n    cdef void _remove_consumer(self, VideoConsumer consumer)\n\ncdef class VideoCamera(VideoProducer):\n    cdef pjmedia_port *_video_tee\n    cdef readonly unicode name\n    cdef readonly unicode real_name\n\n    cdef void _start(self)\n    cdef void _stop(self)\n\ncdef class FrameBufferVideoRenderer(VideoConsumer):\n    cdef pjmedia_vid_dev_stream *_video_stream\n    cdef object _frame_handler\n\n    cdef _initialize(self, VideoProducer producer)\n    cdef void _destroy_video_port(self)\n    cdef void _start(self)\n    cdef void _stop(self)\n\ncdef class LocalVideoStream(VideoConsumer):\n    cdef void _initialize(self, pjmedia_port *media_port)\n\ncdef class RemoteVideoStream(VideoProducer):\n    cdef pjmedia_vid_stream *_video_stream\n    cdef object _event_handler\n\n    cdef void _initialize(self, pjmedia_vid_stream *stream)\n\ncdef LocalVideoStream_create(pjmedia_vid_stream *stream)\ncdef RemoteVideoStream_create(pjmedia_vid_stream *stream, format_change_handler=*)\ncdef int RemoteVideoStream_on_event(pjmedia_event *event, void *user_data) with gil\ncdef void _start_video_port(pjmedia_vid_port *port)\ncdef void _stop_video_port(pjmedia_vid_port *port)\n\n# core.event\n\ncdef struct _core_event\ncdef struct _handler_queue\ncdef int _event_queue_append(_core_event *event)\ncdef void _cb_log(int level, char_ptr_const data, int len)\ncdef int _add_event(object event_name, dict params) except -1\ncdef list _get_clear_event_queue()\ncdef int _add_handler(int func(object obj) except -1, object obj, _handler_queue *queue) except -1\ncdef int _remove_handler(object obj, _handler_queue *queue) except -1\ncdef int _process_handler_queue(PJSIPUA ua, _handler_queue *queue) except -1\n\n# core.request\n\ncdef class EndpointAddress(object):\n    # attributes\n    cdef readonly bytes ip\n    cdef readonly int port\n\ncdef class Request(object):\n    # attributes\n    cdef readonly object state\n    cdef PJSTR _method\n    cdef readonly EndpointAddress peer_address\n    cdef readonly FrozenCredentials credentials\n    cdef readonly FrozenFromHeader from_header\n    cdef readonly FrozenToHeader to_header\n    cdef readonly FrozenSIPURI request_uri\n    cdef readonly FrozenContactHeader contact_header\n    cdef readonly FrozenRouteHeader route_header\n    cdef PJSTR _call_id\n    cdef readonly int cseq\n    cdef readonly frozenlist extra_headers\n    cdef PJSTR _content_type\n    cdef PJSTR _content_subtype\n    cdef PJSTR _body\n    cdef pjsip_tx_data *_tdata\n    cdef pjsip_transaction *_tsx\n    cdef pjsip_auth_clt_sess _auth\n    cdef pjsip_route_hdr _route_header\n    cdef int _need_auth\n    cdef pj_timer_entry _timer\n    cdef int _timer_active\n    cdef int _expire_rest\n    cdef object _expire_time\n    cdef object _timeout\n\n    # private methods\n    cdef PJSIPUA _get_ua(self)\n    cdef int _cb_tsx_state(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1\n    cdef int _cb_timer(self, PJSIPUA ua) except -1\n\ncdef class IncomingRequest(object):\n    # attributes\n    cdef readonly str state\n    cdef pjsip_transaction *_tsx\n    cdef pjsip_tx_data *_tdata\n    cdef readonly EndpointAddress peer_address\n\n    # methods\n    cdef int init(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1\n\ncdef void _Request_cb_tsx_state(pjsip_transaction *tsx, pjsip_event *event) with gil\ncdef void _Request_cb_timer(pj_timer_heap_t *timer_heap, pj_timer_entry *entry) with gil\n\n# core.referral\n\ncdef class Referral(object):\n    # attributes\n    cdef pjsip_evsub *_obj\n    cdef pjsip_dialog *_dlg\n    cdef pjsip_route_hdr _route_header\n    cdef pj_list _route_set\n    cdef int _create_subscription\n    cdef readonly object state\n    cdef pj_timer_entry _timeout_timer\n    cdef int _timeout_timer_active\n    cdef pj_timer_entry _refresh_timer\n    cdef int _refresh_timer_active\n    cdef readonly EndpointAddress peer_address\n    cdef readonly FrozenFromHeader from_header\n    cdef readonly FrozenToHeader to_header\n    cdef readonly FrozenReferToHeader refer_to_header\n    cdef readonly FrozenRouteHeader route_header\n    cdef readonly FrozenCredentials credentials\n    cdef readonly FrozenContactHeader local_contact_header\n    cdef readonly FrozenContactHeader remote_contact_header\n    cdef readonly int refresh\n    cdef readonly frozenlist extra_headers\n    cdef pj_time_val _request_timeout\n    cdef int _want_end\n    cdef int _term_code\n    cdef object _term_reason\n\n    # private methods\n    cdef PJSIPUA _get_ua(self)\n    cdef int _update_contact_header(self, BaseContactHeader contact_header) except -1\n    cdef int _cancel_timers(self, PJSIPUA ua, int cancel_timeout, int cancel_refresh) except -1\n    cdef int _send_refer(self, PJSIPUA ua, pj_time_val *timeout, FrozenReferToHeader refer_to_header, frozenlist extra_headers) except -1\n    cdef int _send_subscribe(self, PJSIPUA ua, int expires, pj_time_val *timeout, frozenlist extra_headers) except -1\n    cdef int _cb_state(self, PJSIPUA ua, object state, int code, str reason) except -1\n    cdef int _cb_got_response(self, PJSIPUA ua, pjsip_rx_data *rdata, str method) except -1\n    cdef int _cb_notify(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1\n    cdef int _cb_timeout_timer(self, PJSIPUA ua)\n    cdef int _cb_refresh_timer(self, PJSIPUA ua)\n\ncdef class IncomingReferral(object):\n    cdef pjsip_evsub *_obj\n    cdef pjsip_dialog *_dlg\n    cdef pjsip_tx_data *_initial_response\n    cdef pjsip_transaction *_initial_tsx\n    cdef pj_time_val _expires_time\n    cdef int _create_subscription\n    cdef readonly str state\n    cdef readonly EndpointAddress peer_address\n    cdef readonly FrozenContactHeader local_contact_header\n    cdef readonly FrozenContactHeader remote_contact_header\n    cdef PJSTR _content\n\n    cdef int init(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1\n    cdef PJSIPUA _get_ua(self, int raise_exception)\n    cdef int _set_content(self, int code, str reason) except -1\n    cdef int _set_state(self, str state) except -1\n    cdef int _send_initial_response(self, int code) except -1\n    cdef int _send_notify(self) except -1\n    cdef int _terminate(self, PJSIPUA ua, int do_cleanup) except -1\n    cdef int _cb_rx_refresh(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1\n    cdef int _cb_server_timeout(self, PJSIPUA ua) except -1\n    cdef int _cb_tsx(self, PJSIPUA ua, pjsip_event *event) except -1\n\ncdef void _Referral_cb_state(pjsip_evsub *sub, pjsip_event *event) with gil\ncdef void _Referral_cb_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code, pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil\ncdef void _Referral_cb_refresh(pjsip_evsub *sub) with gil\ncdef void _IncomingReferral_cb_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code, pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil\ncdef void _IncomingReferral_cb_server_timeout(pjsip_evsub *sub) with gil\ncdef void _IncomingReferral_cb_tsx(pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event) with gil\n\n# core.subscription\n\ncdef class Subscription(object):\n    # attributes\n    cdef pjsip_evsub *_obj\n    cdef pjsip_dialog *_dlg\n    cdef pjsip_route_hdr _route_header\n    cdef pj_list _route_set\n    cdef pj_timer_entry _timeout_timer\n    cdef int _timeout_timer_active\n    cdef pj_timer_entry _refresh_timer\n    cdef int _refresh_timer_active\n    cdef readonly object state\n    cdef readonly EndpointAddress peer_address\n    cdef readonly FrozenFromHeader from_header\n    cdef readonly FrozenToHeader to_header\n    cdef readonly FrozenContactHeader contact_header\n    cdef readonly object event\n    cdef readonly FrozenRouteHeader route_header\n    cdef readonly FrozenCredentials credentials\n    cdef readonly int refresh\n    cdef readonly frozenlist extra_headers\n    cdef readonly object body\n    cdef readonly object content_type\n    cdef readonly str call_id\n    cdef pj_time_val _subscribe_timeout\n    cdef int _want_end\n    cdef int _term_code\n    cdef object _term_reason\n    cdef int _expires\n\n    # private methods\n    cdef PJSIPUA _get_ua(self)\n    cdef int _cancel_timers(self, PJSIPUA ua, int cancel_timeout, int cancel_refresh) except -1\n    cdef int _send_subscribe(self, PJSIPUA ua, int expires, pj_time_val *timeout,\n                             object extra_headers, object content_type, object body) except -1\n    cdef int _cb_state(self, PJSIPUA ua, object state, int code, object reason, dict headers) except -1\n    cdef int _cb_got_response(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1\n    cdef int _cb_notify(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1\n    cdef int _cb_timeout_timer(self, PJSIPUA ua)\n    cdef int _cb_refresh_timer(self, PJSIPUA ua)\n\ncdef class IncomingSubscription(object):\n    # attributes\n    cdef pjsip_evsub *_obj\n    cdef pjsip_dialog *_dlg\n    cdef PJSTR _content_type\n    cdef PJSTR _content_subtype\n    cdef PJSTR _content\n    cdef pjsip_tx_data *_initial_response\n    cdef pjsip_transaction *_initial_tsx\n    cdef int _expires\n    cdef readonly str state\n    cdef readonly str event\n    cdef readonly str call_id\n    cdef readonly EndpointAddress peer_address\n\n    # methods\n    cdef int _set_state(self, str state) except -1\n    cdef PJSIPUA _get_ua(self, int raise_exception)\n    cdef int init(self, PJSIPUA ua, pjsip_rx_data *rdata, str event) except -1\n    cdef int _send_initial_response(self, int code) except -1\n    cdef int _send_notify(self, str reason=*) except -1\n    cdef int _terminate(self, PJSIPUA ua, str reason, int do_cleanup) except -1\n    cdef int _cb_rx_refresh(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1\n    cdef int _cb_server_timeout(self, PJSIPUA ua) except -1\n    cdef int _cb_tsx(self, PJSIPUA ua, pjsip_event *event) except -1\n\ncdef void _Subscription_cb_state(pjsip_evsub *sub, pjsip_event *event) with gil\ncdef void _Subscription_cb_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code,\n                                    pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil\ncdef void _Subscription_cb_refresh(pjsip_evsub *sub) with gil\ncdef void _IncomingSubscription_cb_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata,\n                                              int *p_st_code, pj_str_t **p_st_text,\n                                              pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil\ncdef void _IncomingSubscription_cb_server_timeout(pjsip_evsub *sub) with gil\ncdef void _IncomingSubscription_cb_tsx(pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event) with gil\n\n# core.sdp\n\ncdef class BaseSDPConnection(object):\n    # attributes\n    cdef pjmedia_sdp_conn _sdp_connection\n\n    # private methods\n    cdef pjmedia_sdp_conn* get_sdp_connection(self)\n\ncdef class SDPConnection(BaseSDPConnection):\n    # attributes\n    cdef str _address\n    cdef str _net_type\n    cdef str _address_type\n\ncdef class FrozenSDPConnection(BaseSDPConnection):\n    # attributes\n    cdef int initialized\n    cdef readonly str address\n    cdef readonly str net_type\n    cdef readonly str address_type\n\ncdef class SDPAttributeList(list):\n    pass\n\ncdef class FrozenSDPAttributeList(frozenlist):\n    pass\n\ncdef class SDPBandwidthInfoList(list):\n    pass\n\ncdef class FrozenSDPBandwidthInfoList(frozenlist):\n    pass\n\ncdef class BaseSDPSession(object):\n    # attributes\n    cdef pjmedia_sdp_session _sdp_session\n\n    # private methods\n    cdef pjmedia_sdp_session* get_sdp_session(self)\n\ncdef class SDPSession(BaseSDPSession):\n    # attributes\n    cdef str _address\n    cdef str _user\n    cdef str _net_type\n    cdef str _address_type\n    cdef str _name\n    cdef str _info\n    cdef SDPConnection _connection\n    cdef list _attributes\n    cdef list _bandwidth_info\n    cdef list _media\n\n    # private methods\n    cdef int _update(self) except -1\n\ncdef class FrozenSDPSession(BaseSDPSession):\n    # attributes\n    cdef int initialized\n    cdef readonly str address\n    cdef readonly unsigned int id\n    cdef readonly unsigned int version\n    cdef readonly str user\n    cdef readonly str net_type\n    cdef readonly str address_type\n    cdef readonly str name\n    cdef readonly str info\n    cdef readonly FrozenSDPConnection connection\n    cdef readonly int start_time\n    cdef readonly int stop_time\n    cdef readonly FrozenSDPAttributeList attributes\n    cdef readonly FrozenSDPBandwidthInfoList bandwidth_info\n    cdef readonly frozenlist media\n\ncdef class BaseSDPMediaStream(object):\n    # attributes\n    cdef pjmedia_sdp_media _sdp_media\n\n    # private methods\n    cdef pjmedia_sdp_media* get_sdp_media(self)\n\ncdef class SDPMediaStream(BaseSDPMediaStream):\n    # attributes\n    cdef str _media\n    cdef str _transport\n    cdef list _formats\n    cdef list _codec_list\n    cdef str _info\n    cdef SDPConnection _connection\n    cdef SDPAttributeList _attributes\n    cdef SDPBandwidthInfoList _bandwidth_info\n\n    # private methods\n    cdef int _update(self, SDPMediaStream media) except -1\n\ncdef class FrozenSDPMediaStream(BaseSDPMediaStream):\n    # attributes\n    cdef int initialized\n    cdef readonly str media\n    cdef readonly int port\n    cdef readonly str transport\n    cdef readonly int port_count\n    cdef readonly frozenlist formats\n    cdef readonly frozenlist codec_list\n    cdef readonly str info\n    cdef readonly FrozenSDPConnection connection\n    cdef readonly FrozenSDPAttributeList attributes\n    cdef readonly FrozenSDPBandwidthInfoList bandwidth_info\n\ncdef class BaseSDPAttribute(object):\n    # attributes\n    cdef pjmedia_sdp_attr _sdp_attribute\n\n    # private methods\n    cdef pjmedia_sdp_attr* get_sdp_attribute(self)\n\ncdef class SDPAttribute(BaseSDPAttribute):\n    # attributes\n    cdef str _name\n    cdef str _value\n\ncdef class FrozenSDPAttribute(BaseSDPAttribute):\n    # attributes\n    cdef int initialized\n    cdef readonly str name\n    cdef readonly str value\n\ncdef class BaseSDPBandwidthInfo(object):\n    # attributes\n    cdef pjmedia_sdp_bandw _sdp_bandwidth_info\n\n    # private methods\n    cdef pjmedia_sdp_bandw* get_sdp_bandwidth_info(self)\n\ncdef class SDPBandwidthInfo(BaseSDPBandwidthInfo):\n    # attributes\n    cdef str _modifier\n    cdef int _value\n\ncdef class FrozenSDPBandwidthInfo(BaseSDPBandwidthInfo):\n    # attributes\n    cdef int initialized\n    cdef readonly str modifier\n    cdef readonly int value\n\ncdef SDPSession SDPSession_create(pjmedia_sdp_session_ptr_const pj_session)\ncdef FrozenSDPSession FrozenSDPSession_create(pjmedia_sdp_session_ptr_const pj_session)\ncdef SDPMediaStream SDPMediaStream_create(pjmedia_sdp_media *pj_media)\ncdef FrozenSDPMediaStream FrozenSDPMediaStream_create(pjmedia_sdp_media *pj_media)\ncdef SDPConnection SDPConnection_create(pjmedia_sdp_conn *pj_conn)\ncdef FrozenSDPConnection FrozenSDPConnection_create(pjmedia_sdp_conn *pj_conn)\ncdef SDPAttribute SDPAttribute_create(pjmedia_sdp_attr *pj_attr)\ncdef FrozenSDPAttribute FrozenSDPAttribute_create(pjmedia_sdp_attr *pj_attr)\ncdef SDPBandwidthInfo SDPBandwidthInfo_create(pjmedia_sdp_bandw *pj_bandw)\ncdef FrozenSDPBandwidthInfo FrozenSDPBandwidthInfo_create(pjmedia_sdp_bandw *pj_bandw)\n\ncdef class SDPNegotiator(object):\n    # attributes\n    cdef pjmedia_sdp_neg* _neg\n    cdef pj_pool_t *_pool\n\n# core.invitation\n\ncdef class SDPPayloads:\n    cdef readonly FrozenSDPSession proposed_local\n    cdef readonly FrozenSDPSession proposed_remote\n    cdef readonly FrozenSDPSession active_local\n    cdef readonly FrozenSDPSession active_remote\n\ncdef class StateCallbackTimer(Timer):\n    cdef object state\n    cdef object sub_state\n    cdef object rdata\n    cdef object tdata\n    cdef object originator\n\ncdef class SDPCallbackTimer(Timer):\n    cdef int status\n    cdef object active_local\n    cdef object active_remote\n\ncdef class TransferStateCallbackTimer(Timer):\n    cdef object state\n    cdef object code\n    cdef object reason\n\ncdef class TransferResponseCallbackTimer(Timer):\n    cdef object method\n    cdef object rdata\n\ncdef class TransferRequestCallbackTimer(Timer):\n    cdef object rdata\n\ncdef class Invitation(object):\n    # attributes\n    cdef object __weakref__\n    cdef object weakref\n    cdef int _sdp_neg_status\n    cdef int _failed_response\n    cdef pj_list _route_set\n    cdef pj_mutex_t *_lock\n    cdef pjsip_inv_session *_invite_session\n    cdef pjsip_evsub *_transfer_usage\n    cdef pjsip_role_e _transfer_usage_role\n    cdef pjsip_dialog *_dialog\n    cdef pjsip_route_hdr _route_header\n    cdef pjsip_transaction *_reinvite_transaction\n    cdef PJSTR _sipfrag_payload\n    cdef Timer _timer\n    cdef Timer _transfer_timeout_timer\n    cdef Timer _transfer_refresh_timer\n    cdef readonly str call_id\n    cdef readonly str direction\n    cdef readonly str remote_user_agent\n    cdef readonly str state\n    cdef readonly str sub_state\n    cdef readonly str transport\n    cdef readonly str transfer_state\n    cdef readonly EndpointAddress peer_address\n    cdef readonly FrozenCredentials credentials\n    cdef readonly FrozenContactHeader local_contact_header\n    cdef readonly FrozenContactHeader remote_contact_header\n    cdef readonly FrozenFromHeader from_header\n    cdef readonly FrozenToHeader to_header\n    cdef readonly FrozenSIPURI request_uri\n    cdef readonly FrozenRouteHeader route_header\n    cdef readonly SDPPayloads sdp\n\n    # private methods\n    cdef int init_incoming(self, PJSIPUA ua, pjsip_rx_data *rdata, unsigned int inv_options) except -1\n    cdef int process_incoming_transfer(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1\n    cdef int process_incoming_options(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1\n    cdef PJSIPUA _check_ua(self)\n    cdef int _do_dealloc(self) except -1\n    cdef int _update_contact_header(self, BaseContactHeader contact_header) except -1\n    cdef int _fail(self, PJSIPUA ua) except -1\n    cdef int _cb_state(self, StateCallbackTimer timer) except -1\n    cdef int _cb_sdp_done(self, SDPCallbackTimer timer) except -1\n    cdef int _cb_timer_disconnect(self, timer) except -1\n    cdef int _cb_postpoll_fail(self, timer) except -1\n    cdef int _start_incoming_transfer(self, timer) except -1\n    cdef int _terminate_transfer(self) except -1\n    cdef int _terminate_transfer_uac(self) except -1\n    cdef int _terminate_transfer_uas(self) except -1\n    cdef int _set_transfer_state(self, str state) except -1\n    cdef int _set_sipfrag_payload(self, int code, str reason) except -1\n    cdef int _send_notify(self) except -1\n    cdef int _transfer_cb_timeout_timer(self, timer) except -1\n    cdef int _transfer_cb_refresh_timer(self, timer) except -1\n    cdef int _transfer_cb_state(self, TransferStateCallbackTimer timer) except -1\n    cdef int _transfer_cb_response(self, TransferResponseCallbackTimer timer) except -1\n    cdef int _transfer_cb_notify(self, TransferRequestCallbackTimer timer) except -1\n    cdef int _transfer_cb_server_timeout(self, timer) except -1\n\ncdef void _Invitation_cb_state(pjsip_inv_session *inv, pjsip_event *e) with gil\ncdef void _Invitation_cb_sdp_done(pjsip_inv_session *inv, int status) with gil\ncdef int _Invitation_cb_rx_reinvite(pjsip_inv_session *inv, pjmedia_sdp_session_ptr_const offer, pjsip_rx_data *rdata) with gil\ncdef void _Invitation_cb_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e) with gil\ncdef void _Invitation_cb_new(pjsip_inv_session *inv, pjsip_event *e) with gil\ncdef void _Invitation_transfer_cb_state(pjsip_evsub *sub, pjsip_event *event) with gil\ncdef void _Invitation_transfer_cb_tsx(pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event) with gil\ncdef void _Invitation_transfer_cb_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code,\n                                         pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil\ncdef void _Invitation_transfer_cb_refresh(pjsip_evsub *sub) with gil\ncdef void _Invitation_transfer_in_cb_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code,\n                                                pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil\ncdef void _Invitation_transfer_in_cb_server_timeout(pjsip_evsub *sub) with gil\n\n# core.mediatransport\n\ncdef class ICECandidate(object):\n    # attributes\n    cdef readonly str component\n    cdef readonly str type\n    cdef readonly str address\n    cdef readonly int port\n    cdef readonly int priority\n    cdef readonly str rel_address\n\ncdef class ICECheck(object):\n    cdef readonly ICECandidate local_candidate\n    cdef readonly ICECandidate remote_candidate\n    cdef readonly str state\n    cdef readonly int nominated\n\ncdef class RTPTransport(object):\n    # attributes\n    cdef object __weakref__\n    cdef object weakref\n    cdef int _af\n    cdef pj_mutex_t *_lock\n    cdef pj_pool_t *_pool\n    cdef pjmedia_transport *_obj\n    cdef pjmedia_transport *_wrapped_transport\n    cdef ICECheck _rtp_valid_pair\n    cdef str _encryption\n    cdef readonly object ice_stun_address\n    cdef readonly object ice_stun_port\n    cdef readonly object state\n    cdef readonly object use_ice\n\n    # private methods\n    cdef PJSIPUA _check_ua(self)\n    cdef void _get_info(self, pjmedia_transport_info *info)\n    cdef int _init_local_sdp(self, BaseSDPSession local_sdp, BaseSDPSession remote_sdp, int sdp_index)\n    cdef int _ice_active(self)\n\ncdef class MediaCheckTimer(Timer):\n    # attributes\n    cdef int media_check_interval\n\ncdef class SDPInfo(object):\n    # attributes\n    cdef BaseSDPMediaStream _local_media\n    cdef BaseSDPSession _local_sdp\n    cdef BaseSDPSession _remote_sdp\n    cdef public int index\n\ncdef class AudioTransport(object):\n    # attributes\n    cdef object __weakref__\n    cdef object weakref\n    cdef int _is_offer\n    cdef int _is_started\n    cdef int _slot\n    cdef int _volume\n    cdef unsigned int _packets_received\n    cdef unsigned int _vad\n    cdef pj_mutex_t *_lock\n    cdef pj_pool_t *_pool\n    cdef pjmedia_stream *_obj\n    cdef pjmedia_stream_info _stream_info\n    cdef Timer _timer\n    cdef readonly object direction\n    cdef readonly AudioMixer mixer\n    cdef readonly RTPTransport transport\n    cdef SDPInfo _sdp_info\n\n    # private methods\n    cdef PJSIPUA _check_ua(self)\n    cdef int _cb_check_rtp(self, MediaCheckTimer timer) except -1\n\ncdef class VideoTransport(object):\n    # attributes\n    cdef object __weakref__\n    cdef object weakref\n    cdef int _is_offer\n    cdef int _is_started\n    cdef unsigned int _packets_received\n    cdef pj_mutex_t *_lock\n    cdef pj_pool_t *_pool\n    cdef pjmedia_vid_stream *_obj\n    cdef pjmedia_vid_stream_info _stream_info\n    cdef Timer _timer\n    cdef readonly object direction\n    cdef readonly RTPTransport transport\n    cdef SDPInfo _sdp_info\n    cdef readonly LocalVideoStream local_video\n    cdef readonly RemoteVideoStream remote_video\n\n    # private methods\n    cdef PJSIPUA _check_ua(self)\n    cdef int _cb_check_rtp(self, MediaCheckTimer timer) except -1\n\ncdef void _RTPTransport_cb_ice_complete(pjmedia_transport *tp, pj_ice_strans_op op, int status) with gil\ncdef void _RTPTransport_cb_ice_state(pjmedia_transport *tp, pj_ice_strans_state prev, pj_ice_strans_state curr) with gil\ncdef void _RTPTransport_cb_ice_stop(pjmedia_transport *tp, char *reason, int err) with gil\ncdef void _RTPTransport_cb_zrtp_secure_on(pjmedia_transport *tp, char* cipher) with gil\ncdef void _RTPTransport_cb_zrtp_secure_off(pjmedia_transport *tp) with gil\ncdef void _RTPTransport_cb_zrtp_show_sas(pjmedia_transport *tp, char* sas, int verified) with gil\ncdef void _RTPTransport_cb_zrtp_confirm_goclear(pjmedia_transport *tp) with gil\ncdef void _RTPTransport_cb_zrtp_show_message(pjmedia_transport *tp, int severity, int subCode) with gil\ncdef void _RTPTransport_cb_zrtp_negotiation_failed(pjmedia_transport *tp, int severity, int subCode) with gil\ncdef void _RTPTransport_cb_zrtp_not_supported_by_other(pjmedia_transport *tp) with gil\ncdef void _RTPTransport_cb_zrtp_ask_enrollment(pjmedia_transport *tp, int info) with gil\ncdef void _RTPTransport_cb_zrtp_inform_enrollment(pjmedia_transport *tp, int info) with gil\ncdef void _AudioTransport_cb_dtmf(pjmedia_stream *stream, void *user_data, int digit) with gil\ncdef ICECandidate ICECandidate_create(pj_ice_sess_cand *cand)\ncdef ICECheck ICECheck_create(pj_ice_sess_check *check)\ncdef str _ice_state_to_str(int state)\ncdef dict _extract_ice_session_data(pj_ice_sess *ice_sess)\ncdef object _extract_rtp_transport(pjmedia_transport *tp)\ncdef dict _pj_math_stat_to_dict(pj_math_stat *stat)\ncdef dict _pjmedia_rtcp_stream_stat_to_dict(pjmedia_rtcp_stream_stat *stream_stat)\n"
  },
  {
    "path": "sipsimple/core/_core.pyx",
    "content": "\ninclude \"_core.error.pxi\"\ninclude \"_core.lib.pxi\"\ninclude \"_core.sound.pxi\"\ninclude \"_core.video.pxi\"\ninclude \"_core.util.pxi\"\n\ninclude \"_core.ua.pxi\"\n\ninclude \"_core.event.pxi\"\ninclude \"_core.request.pxi\"\ninclude \"_core.helper.pxi\"\ninclude \"_core.headers.pxi\"\ninclude \"_core.subscription.pxi\"\ninclude \"_core.invitation.pxi\"\ninclude \"_core.referral.pxi\"\ninclude \"_core.sdp.pxi\"\ninclude \"_core.mediatransport.pxi\"\n\n# constants\n\nPJ_VERSION = pj_get_version()\nPJ_SVN_REVISION = int(PJ_SVN_REV)\nCORE_REVISION = 181\n\n# exports\n\n__all__ = [\"PJ_VERSION\", \"PJ_SVN_REVISION\", \"CORE_REVISION\",\n           \"SIPCoreError\", \"PJSIPError\", \"PJSIPTLSError\", \"SIPCoreInvalidStateError\",\n           \"AudioMixer\", \"ToneGenerator\", \"RecordingWaveFile\", \"WaveFile\", \"MixerPort\",\n           \"VideoCamera\", \"FrameBufferVideoRenderer\",\n           \"sip_status_messages\",\n           \"BaseCredentials\", \"Credentials\", \"FrozenCredentials\", \"BaseSIPURI\", \"SIPURI\", \"FrozenSIPURI\",\n           \"BaseHeader\", \"Header\", \"FrozenHeader\",\n           \"BaseContactHeader\", \"ContactHeader\", \"FrozenContactHeader\",\n           \"BaseContentTypeHeader\", \"ContentType\", \"ContentTypeHeader\", \"FrozenContentTypeHeader\",\n           \"BaseIdentityHeader\", \"IdentityHeader\", \"FrozenIdentityHeader\", \"FromHeader\", \"FrozenFromHeader\", \"ToHeader\", \"FrozenToHeader\",\n           \"RouteHeader\", \"FrozenRouteHeader\", \"RecordRouteHeader\", \"FrozenRecordRouteHeader\", \"BaseRetryAfterHeader\", \"RetryAfterHeader\", \"FrozenRetryAfterHeader\",\n           \"BaseViaHeader\", \"ViaHeader\", \"FrozenViaHeader\", \"BaseWarningHeader\", \"WarningHeader\", \"FrozenWarningHeader\",\n           \"BaseEventHeader\", \"EventHeader\", \"FrozenEventHeader\", \"BaseSubscriptionStateHeader\", \"SubscriptionStateHeader\", \"FrozenSubscriptionStateHeader\",\n           \"BaseReasonHeader\", \"ReasonHeader\", \"FrozenReasonHeader\",\n           \"BaseReferToHeader\", \"ReferToHeader\", \"FrozenReferToHeader\",\n           \"BaseSubjectHeader\", \"SubjectHeader\", \"FrozenSubjectHeader\",\n           \"BaseReplacesHeader\", \"ReplacesHeader\", \"FrozenReplacesHeader\",\n           \"Request\",\n           \"Referral\",\n           \"sipfrag_re\",\n           \"Subscription\",\n           \"Invitation\",\n           \"DialogID\",\n           \"SDPSession\", \"FrozenSDPSession\", \"SDPMediaStream\", \"FrozenSDPMediaStream\", \"SDPConnection\", \"FrozenSDPConnection\", \"SDPAttribute\", \"FrozenSDPAttribute\", \"SDPNegotiator\",\n           \"RTPTransport\", \"AudioTransport\", \"VideoTransport\"]\n\n\n"
  },
  {
    "path": "sipsimple/core/_core.referral.pxi",
    "content": "\nimport re\n\ncdef class Referral:\n    expire_warning_time = 30\n\n    def __cinit__(self, *args, **kwargs):\n        self.state = \"NULL\"\n        pj_timer_entry_init(&self._timeout_timer, 0, <void *> self, _Referral_cb_timer)\n        self._timeout_timer_active = 0\n        pj_timer_entry_init(&self._refresh_timer, 1, <void *> self, _Referral_cb_timer)\n        self._refresh_timer_active = 0\n        self.extra_headers = frozenlist()\n        self.peer_address = None\n        self._create_subscription = 1\n        self.local_contact_header = None\n        self.remote_contact_header = None\n\n    def __init__(self, SIPURI request_uri not None, FromHeader from_header not None, ToHeader to_header not None, ReferToHeader refer_to_header not None,\n                 ContactHeader contact_header not None, RouteHeader route_header not None, Credentials credentials=None):\n        global _refer_cb\n        global _refer_event\n        cdef PJSTR from_header_str\n        cdef PJSTR to_header_str\n        cdef PJSTR contact_str\n        cdef PJSTR request_uri_str\n        cdef pjsip_cred_info *cred_info\n        cdef PJSIPUA ua = _get_ua()\n        cdef int status\n        if self._obj != NULL or self.state != \"NULL\":\n            raise SIPCoreError(\"Referral.__init__() was already called\")\n        self.local_contact_header = FrozenContactHeader.new(contact_header)\n        self.route_header = FrozenRouteHeader.new(route_header)\n        self.route_header.uri.parameters.dict[\"lr\"] = None # always send lr parameter in Route header\n        self.route_header.uri.parameters.dict[\"hide\"] = None # always hide Route header\n        if credentials is not None:\n            self.credentials = FrozenCredentials.new(credentials)\n        from_header_parameters = from_header.parameters.copy()\n        from_header_parameters.pop(\"tag\", None)\n        from_header.parameters = {}\n        from_header_str = PJSTR(from_header.body)\n        to_header_parameters = to_header.parameters.copy()\n        to_header_parameters.pop(\"tag\", None)\n        to_header.parameters = {}\n        to_header_str = PJSTR(to_header.body)\n        contact_str = PJSTR(str(contact_header.body))\n        request_uri_str = PJSTR(str(request_uri))\n        with nogil:\n            status = pjsip_dlg_create_uac(pjsip_ua_instance(), &from_header_str.pj_str, &contact_str.pj_str,\n                                          &to_header_str.pj_str, &request_uri_str.pj_str, &self._dlg)\n        if status != 0:\n            raise PJSIPError(\"Could not create dialog for REFER\", status)\n        # Increment dialog session count so that it's never destroyed by PJSIP\n        with nogil:\n            status = pjsip_dlg_inc_session(self._dlg, &ua._module)\n        if contact_header.expires is not None:\n            self._dlg.local.contact.expires = contact_header.expires\n        if contact_header.q is not None:\n            self._dlg.local.contact.q1000 = int(contact_header.q*1000)\n        contact_parameters = contact_header.parameters.copy()\n        contact_parameters.pop(\"q\", None)\n        contact_parameters.pop(\"expires\", None)\n        _dict_to_pjsip_param(contact_parameters, &self._dlg.local.contact.other_param, self._dlg.pool)\n        _dict_to_pjsip_param(from_header_parameters, &self._dlg.local.info.other_param, self._dlg.pool)\n        _dict_to_pjsip_param(to_header_parameters, &self._dlg.remote.info.other_param, self._dlg.pool)\n        self.from_header = FrozenFromHeader_create(self._dlg.local.info)\n        self.to_header = FrozenToHeader.new(to_header)\n        self.refer_to_header = FrozenReferToHeader.new(refer_to_header)\n        with nogil:\n            status = pjsip_evsub_create_uac(self._dlg, &_refer_cb, &_refer_event.pj_str, PJSIP_EVSUB_NO_EVENT_ID, &self._obj)\n        if status != 0:\n            raise PJSIPError(\"Could not create REFER\", status)\n        pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, <void *> self)\n        _BaseRouteHeader_to_pjsip_route_hdr(self.route_header, &self._route_header, self._dlg.pool)\n        pj_list_init(<pj_list *> &self._route_set)\n        pj_list_insert_after(<pj_list *> &self._route_set, <pj_list *> &self._route_header)\n        with nogil:\n            status = pjsip_dlg_set_route_set(self._dlg, <pjsip_route_hdr *> &self._route_set)\n        if status != 0:\n            raise PJSIPError(\"Could not set route on REFER\", status)\n        if self.credentials is not None:\n            cred_info = self.credentials.get_cred_info()\n            with nogil:\n                status = pjsip_auth_clt_set_credentials(&self._dlg.auth_sess, 1, cred_info)\n            if status != 0:\n                raise PJSIPError(\"Could not set credentials for REFER\", status)\n\n    def __dealloc__(self):\n        cdef PJSIPUA ua = self._get_ua()\n        if ua is not None:\n            self._cancel_timers(ua, 1, 1)\n        if self._obj != NULL:\n            pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, NULL)\n            with nogil:\n                pjsip_evsub_terminate(self._obj, 0)\n            self._obj = NULL\n        if self._dlg != NULL:\n            with nogil:\n                pjsip_dlg_dec_session(self._dlg, &ua._module)\n            self._dlg = NULL\n\n    def send_refer(self, int create_subscription=1, list extra_headers not None=list(), object timeout=None):\n        cdef PJSIPUA ua = self._get_ua()\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state != \"NULL\":\n                raise SIPCoreError('This method may only be called in the \"NULL\" state')\n            if timeout is not None:\n                if timeout <= 0:\n                    raise ValueError(\"Timeout value cannot be negative\")\n                self._request_timeout.sec = int(timeout)\n                self._request_timeout.msec = (timeout * 1000) % 1000\n            else:\n                self._request_timeout.sec = 0\n                self._request_timeout.msec = 0\n            if extra_headers is not None:\n                self.extra_headers = frozenlist([header.frozen_type.new(header) for header in extra_headers])\n            self._create_subscription = create_subscription\n            self._send_refer(ua, &self._request_timeout, self.refer_to_header, self.extra_headers)\n            _add_event(\"SIPReferralWillStart\", dict(obj=self))\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    def refresh(self, ContactHeader contact_header=None, list extra_headers not None=list(), object timeout=None):\n        cdef PJSIPUA ua = self._get_ua()\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state not in (\"ACCEPTED\", \"ACTIVE\", \"PENDING\"):\n                raise SIPCoreError('This method may only be called in the \"ACCEPTED\", \"ACTIVE\" or \"PENDING\" states')\n            if timeout is not None:\n                if timeout <= 0:\n                    raise ValueError(\"Timeout value cannot be negative\")\n                self._request_timeout.sec = int(timeout)\n                self._request_timeout.msec = (timeout * 1000) % 1000\n            else:\n                self._request_timeout.sec = 0\n                self._request_timeout.msec = 0\n            if contact_header is not None:\n                self._update_contact_header(contact_header)\n            if extra_headers is not None:\n                self.extra_headers = frozenlist([header.frozen_type.new(header) for header in extra_headers])\n            self._send_subscribe(ua, 600, &self._request_timeout, self.extra_headers)\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    def end(self, object timeout=None):\n        cdef pj_time_val end_timeout\n        cdef PJSIPUA ua = self._get_ua()\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state == \"TERMINATED\":\n                return\n            if self.state == \"NULL\":\n                raise SIPCoreError('This method may not be called in the \"NULL\" state')\n            if timeout is not None:\n                if timeout <= 0:\n                    raise ValueError(\"Timeout value cannot be negative\")\n                end_timeout.sec = int(timeout)\n                end_timeout.msec = (timeout * 1000) % 1000\n            else:\n                end_timeout.sec = 0\n                end_timeout.msec = 0\n            self._want_end = 1\n            self._cancel_timers(ua, 1, 1)\n            _add_event(\"SIPReferralWillEnd\", dict(obj=self))\n            try:\n                self._send_subscribe(ua, 0, &end_timeout, frozenlist([]))\n            except PJSIPError, e:\n                self._term_reason = e.args[0]\n                if self._obj != NULL:\n                    pjsip_evsub_terminate(self._obj, 1)\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    cdef PJSIPUA _get_ua(self):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n        except SIPCoreError:\n            self._obj = NULL\n            self._timeout_timer_active = 0\n            self._refresh_timer_active = 0\n            self.state = \"TERMINATED\"\n            return None\n        else:\n            return ua\n\n    cdef int _update_contact_header(self, BaseContactHeader contact_header) except -1:\n        # The PJSIP functions called here don't do much, so there is no need to call them\n        # without the gil.\n        cdef pj_str_t contact_str_pj\n        cdef pjsip_uri *contact\n\n        contact_str = str(contact_header.uri)\n        if contact_header.display_name:\n            contact_str = \"%s <%s>\" % (contact_header.display_name.encode('utf-8'), contact_str)\n        pj_strdup2_with_null(self._dlg.pool, &contact_str_pj, contact_str)\n        contact = pjsip_parse_uri(self._dlg.pool, contact_str_pj.ptr, contact_str_pj.slen, PJSIP_PARSE_URI_AS_NAMEADDR)\n        if contact == NULL:\n            raise SIPCoreError(\"Not a valid Contact header: %s\" % contact_str)\n        self._dlg.local.contact = pjsip_contact_hdr_create(self._dlg.pool)\n        self._dlg.local.contact.uri = contact\n        if contact_header.expires is not None:\n            self._dlg.local.contact.expires = contact_header.expires\n        if contact_header.q is not None:\n            self._dlg.local.contact.q1000 = int(contact_header.q*1000)\n        parameters = contact_header.parameters.copy()\n        parameters.pop(\"q\", None)\n        parameters.pop(\"expires\", None)\n        _dict_to_pjsip_param(parameters, &self._dlg.local.contact.other_param, self._dlg.pool)\n        self.local_contact_header = FrozenContactHeader.new(contact_header)\n        return 0\n\n    cdef int _cancel_timers(self, PJSIPUA ua, int cancel_timeout, int cancel_refresh) except -1:\n        if cancel_timeout and self._timeout_timer_active:\n            pjsip_endpt_cancel_timer(ua._pjsip_endpoint._obj, &self._timeout_timer)\n            self._timeout_timer_active = 0\n        if cancel_refresh and self._refresh_timer_active:\n            pjsip_endpt_cancel_timer(ua._pjsip_endpoint._obj, &self._refresh_timer)\n            self._refresh_timer_active = 0\n\n    cdef int _send_refer(self, PJSIPUA ua, pj_time_val *timeout, FrozenReferToHeader refer_to_header, frozenlist extra_headers) except -1:\n        global _refer_method\n        cdef pjsip_method refer_method\n        cdef pjsip_tx_data *tdata\n        cdef int status\n        pjsip_method_init_np(&refer_method, &_refer_method.pj_str)\n        with nogil:\n            status = pjsip_evsub_initiate(self._obj, &refer_method, -1, &tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not create REFER message\", status)\n        _add_headers_to_tdata(tdata, [refer_to_header, Header('Referred-By', str(self.from_header.uri))])\n        _add_headers_to_tdata(tdata, extra_headers)\n        if not self._create_subscription:\n            _add_headers_to_tdata(tdata, [Header('Refer-Sub', 'false')])\n        # We can't remove the Event header or PJSIP will fail to match responses to this request\n        _remove_headers_from_tdata(tdata, [\"Expires\"])\n        with nogil:\n            status = pjsip_evsub_send_request(self._obj, tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not send REFER message\", status)\n        if timeout.sec or timeout.msec:\n            status = pjsip_endpt_schedule_timer(ua._pjsip_endpoint._obj, &self._timeout_timer, timeout)\n            if status == 0:\n                self._timeout_timer_active = 1\n\n    cdef int _send_subscribe(self, PJSIPUA ua, int expires, pj_time_val *timeout, frozenlist extra_headers) except -1:\n        cdef pjsip_tx_data *tdata\n        cdef int status\n        with nogil:\n            status = pjsip_evsub_initiate(self._obj, NULL, expires, &tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not create SUBSCRIBE message\", status)\n        _add_headers_to_tdata(tdata, extra_headers)\n        with nogil:\n            status = pjsip_evsub_send_request(self._obj, tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not send SUBSCRIBE message\", status)\n        self._cancel_timers(ua, 1, 0)\n        if timeout.sec or timeout.msec:\n            status = pjsip_endpt_schedule_timer(ua._pjsip_endpoint._obj, &self._timeout_timer, timeout)\n            if status == 0:\n                self._timeout_timer_active = 1\n\n    cdef int _cb_state(self, PJSIPUA ua, object state, int code, str reason) except -1:\n        # PJSIP holds the dialog lock when this callback is entered\n        cdef object prev_state = self.state\n        cdef int status\n        self.state = state\n        if state == \"ACCEPTED\" and prev_state == \"SENT\":\n            _add_event(\"SIPReferralDidStart\", dict(obj=self))\n            if not self._create_subscription:\n                # Terminate the subscription\n                self._want_end = 1\n                _add_event(\"SIPReferralWillEnd\", dict(obj=self))\n                with nogil:\n                    pjsip_evsub_terminate(self._obj, 1)\n        elif state == \"TERMINATED\":\n            pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, NULL)\n            self._cancel_timers(ua, 1, 1)\n            self._obj = NULL\n            if self._want_end:\n                _add_event(\"SIPReferralDidEnd\", dict(obj=self))\n            else:\n                if self._term_reason is not None:\n                    _add_event(\"SIPReferralDidFail\", dict(obj=self, code=self._term_code, reason=self._term_reason))\n                elif code/100 == 2:\n                    _add_event(\"SIPReferralDidEnd\", dict(obj=self))\n                else:\n                    _add_event(\"SIPReferralDidFail\", dict(obj=self, code=code, reason=reason))\n        if prev_state != state:\n            _add_event(\"SIPReferralChangedState\", dict(obj=self, prev_state=prev_state, state=state))\n\n    cdef int _cb_got_response(self, PJSIPUA ua, pjsip_rx_data *rdata, str method) except -1:\n        # PJSIP holds the dialog lock when this callback is entered\n        global _refer_sub_hdr_name\n        cdef int expires\n        cdef int status\n        cdef dict event_dict = dict()\n        cdef pj_time_val refresh\n        cdef pjsip_generic_int_hdr *expires_hdr\n        cdef pjsip_generic_string_hdr *refer_sub_header\n\n        self.to_header = FrozenToHeader_create(rdata.msg_info.to_hdr)\n        if self.state != \"TERMINATED\" and not self._want_end:\n            self._cancel_timers(ua, 1, 0)\n            if method == \"REFER\":\n                refer_sub_header = <pjsip_generic_string_hdr *> pjsip_msg_find_hdr_by_name(rdata.msg_info.msg, &_refer_sub_hdr_name.pj_str, NULL);\n                if not self._create_subscription:\n                    if not (refer_sub_header != NULL and _pj_str_to_str(refer_sub_header.hvalue) == \"false\"):\n                        self._create_subscription = 1\n            elif method == \"SUBSCRIBE\":\n                # For the REFER method the expires value will be taken from the NOTIFY Subscription-State header\n                expires_hdr = <pjsip_generic_int_hdr *> pjsip_msg_find_hdr(rdata.msg_info.msg, PJSIP_H_EXPIRES, NULL)\n                if expires_hdr != NULL and not self._refresh_timer_active:\n                    expires = expires_hdr.ivalue\n                    refresh.sec = max(1, expires - self.expire_warning_time, expires/2)\n                    refresh.msec = 0\n                    status = pjsip_endpt_schedule_timer(ua._pjsip_endpoint._obj, &self._refresh_timer, &refresh)\n                    if status == 0:\n                        self._refresh_timer_active = 1\n        if self.state != \"TERMINATED\":\n            _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n            try:\n                self.remote_contact_header = event_dict['headers']['Contact'][0]\n            except LookupError:\n                pass\n\n    cdef int _cb_notify(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1:\n        # PJSIP holds the dialog lock when this callback is entered\n        global _subscription_state_hdr_name\n        cdef pjsip_sub_state_hdr *sub_state_hdr\n        cdef pj_time_val refresh\n        cdef int expires\n        cdef dict event_dict = dict()\n        cdef dict notify_dict = dict(obj=self)\n        sub_state_hdr = <pjsip_sub_state_hdr *> pjsip_msg_find_hdr_by_name(rdata.msg_info.msg, &_subscription_state_hdr_name.pj_str, NULL)\n        if self.state != \"TERMINATED\" and sub_state_hdr != NULL and sub_state_hdr.expires_param > 0 and not self._refresh_timer_active:\n            expires = sub_state_hdr.expires_param\n            refresh.sec = max(1, expires - self.expire_warning_time, expires/2)\n            refresh.msec = 0\n            status = pjsip_endpt_schedule_timer(ua._pjsip_endpoint._obj, &self._refresh_timer, &refresh)\n            if status == 0:\n                self._refresh_timer_active = 1\n        _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n        if self.state != \"TERMINATED\":\n            try:\n                self.remote_contact_header = event_dict['headers']['Contact'][0]\n            except LookupError:\n                pass\n        notify_dict[\"request_uri\"] = event_dict[\"request_uri\"]\n        notify_dict[\"from_header\"] = event_dict[\"headers\"].get(\"From\", None)\n        notify_dict[\"to_header\"] = event_dict[\"headers\"].get(\"To\", None)\n        notify_dict[\"headers\"] = event_dict[\"headers\"]\n        notify_dict[\"body\"] = event_dict[\"body\"]\n        content_type = notify_dict[\"headers\"].get(\"Content-Type\", None)\n        notify_dict[\"content_type\"] = content_type.content_type if content_type else None\n        event = notify_dict[\"headers\"].get(\"Event\", None)\n        notify_dict[\"event\"] = event.event if event else None\n        _add_event(\"SIPReferralGotNotify\", notify_dict)\n\n    cdef int _cb_timeout_timer(self, PJSIPUA ua):\n        # Timer callback, dialog lock is not held by PJSIP\n        global sip_status_messages\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            self._term_code = PJSIP_SC_TSX_TIMEOUT\n            self._term_reason = sip_status_messages[PJSIP_SC_TSX_TIMEOUT]\n            if self._obj != NULL:\n                with nogil:\n                    pjsip_evsub_terminate(self._obj, 1)\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    cdef int _cb_refresh_timer(self, PJSIPUA ua):\n        # Timer callback, dialog lock is not held by PJSIP\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            self._send_subscribe(ua, 600, &self._request_timeout, self.extra_headers)\n        except PJSIPError, e:\n            self._term_reason = e.args[0]\n            if self._obj != NULL:\n                with nogil:\n                    pjsip_evsub_terminate(self._obj, 1)\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n\ncdef class IncomingReferral:\n\n    def __cinit__(self):\n        self.state = None\n        self.peer_address = None\n        self._create_subscription = 1\n        self.local_contact_header = None\n        self.remote_contact_header = None\n\n    def __dealloc__(self):\n        cdef PJSIPUA ua = self._get_ua(0)\n        self._initial_response = NULL\n        self._initial_tsx = NULL\n        if self._obj != NULL:\n            pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, NULL)\n            with nogil:\n                pjsip_evsub_terminate(self._obj, 0)\n            self._obj = NULL\n        if self._dlg != NULL and ua is not None:\n            with nogil:\n                pjsip_dlg_dec_session(self._dlg, &ua._module)\n            self._dlg = NULL\n\n    cdef int init(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1:\n        global _incoming_refer_subs_cb\n        global _event_hdr_name\n        global _refer_event\n        global _refer_to_hdr_name\n        global _refer_sub_hdr_name\n        cdef int status\n        cdef str transport\n        cdef FrozenSIPURI request_uri\n        cdef FrozenContactHeader contact_header\n        cdef PJSTR contact_str\n        cdef dict event_dict\n        cdef pjsip_generic_string_hdr *refer_to_header\n        cdef pjsip_generic_string_hdr *refer_sub_header\n        cdef pjsip_tpselector tp_sel\n        cdef pjsip_event_hdr *event_header\n\n        refer_to_header = <pjsip_generic_string_hdr *> pjsip_msg_find_hdr_by_name(rdata.msg_info.msg, &_refer_to_hdr_name.pj_str, NULL);\n        if refer_to_header == NULL:\n            with nogil:\n                status = pjsip_endpt_create_response(ua._pjsip_endpoint._obj, rdata, 400, NULL, &self._initial_response)\n            if status != 0:\n                raise PJSIPError(\"Could not create response\", status)\n            with nogil:\n                status = pjsip_endpt_send_response2(ua._pjsip_endpoint._obj, rdata, self._initial_response, NULL, NULL)\n            if status != 0:\n                with nogil:\n                    pjsip_tx_data_dec_ref(self._initial_response)\n                raise PJSIPError(\"Could not send response\", status)\n            return 0\n        # If there is a Ref-Sub header and it contains 'false', don't establish a subscription\n        refer_sub_header = <pjsip_generic_string_hdr *> pjsip_msg_find_hdr_by_name(rdata.msg_info.msg, &_refer_sub_hdr_name.pj_str, NULL);\n        if refer_sub_header != NULL and _pj_str_to_str(refer_sub_header.hvalue) == \"false\":\n            self._create_subscription = 0\n        self._set_state(\"incoming\")\n        self.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n        event_dict = dict(obj=self, prev_state=self.state, state=\"incoming\")\n        _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n        try:\n            self.remote_contact_header = event_dict['headers']['Contact'][0]\n        except LookupError:\n            # Contact header is required\n            with nogil:\n                status = pjsip_endpt_create_response(ua._pjsip_endpoint._obj, rdata, 400, NULL, &self._initial_response)\n            if status != 0:\n                raise PJSIPError(\"Could not create response\", status)\n            with nogil:\n                status = pjsip_endpt_send_response2(ua._pjsip_endpoint._obj, rdata, self._initial_response, NULL, NULL)\n            if status != 0:\n                with nogil:\n                    pjsip_tx_data_dec_ref(self._initial_response)\n                raise PJSIPError(\"Could not send response\", status)\n            return 0\n        event_dict[\"refer_to\"] = event_dict[\"headers\"].get(\"Refer-To\")\n        transport = rdata.tp_info.transport.type_name.lower()\n        request_uri = event_dict[\"request_uri\"]\n        if _is_valid_ip(pj_AF_INET(), request_uri.host):\n            self.local_contact_header = FrozenContactHeader(request_uri)\n        else:\n            self.local_contact_header = FrozenContactHeader(FrozenSIPURI(host=_pj_str_to_str(rdata.tp_info.transport.local_name.host),\n                                                            user=request_uri.user, port=rdata.tp_info.transport.local_name.port,\n                                                            parameters=(frozendict(transport=transport) if transport != \"udp\" else frozendict())))\n        contact_str = PJSTR(self.local_contact_header.body)\n        with nogil:\n            status = pjsip_dlg_create_uas_and_inc_lock(pjsip_ua_instance(), rdata, &contact_str.pj_str, &self._dlg)\n        if status != 0:\n            with nogil:\n                status = pjsip_endpt_create_response(ua._pjsip_endpoint._obj, rdata, 400, NULL, &self._initial_response)\n            if status != 0:\n                raise PJSIPError(\"Could not create response\", status)\n            with nogil:\n                status = pjsip_endpt_send_response2(ua._pjsip_endpoint._obj, rdata, self._initial_response, NULL, NULL)\n            if status != 0:\n                with nogil:\n                    pjsip_tx_data_dec_ref(self._initial_response)\n                raise PJSIPError(\"Could not send response\", status)\n            return 0\n        # Increment dialog session count so that it's never destroyed by PJSIP\n        with nogil:\n            status = pjsip_dlg_inc_session(self._dlg, &ua._module)\n        if status != 0:\n            pjsip_dlg_dec_lock(self._dlg)\n            raise PJSIPError(\"Could not increment dialog session count\", status)\n        # PJSIP event framework needs an Event header, even if it's not needed for REFER, so we insert a fake one\n        event_header = <pjsip_event_hdr *> pjsip_msg_find_hdr_by_name(rdata.msg_info.msg, &_event_hdr_name.pj_str, NULL)\n        if event_header == NULL:\n            event_header = pjsip_event_hdr_create(rdata.tp_info.pool)\n            event_header.event_type = _refer_event.pj_str\n            pjsip_msg_add_hdr(rdata.msg_info.msg, <pjsip_hdr *> event_header)\n        self._initial_tsx = pjsip_rdata_get_tsx(rdata)\n        with nogil:\n            status = pjsip_evsub_create_uas(self._dlg, &_incoming_refer_subs_cb, rdata, 0, &self._obj)\n            pjsip_dlg_dec_lock(self._dlg)\n        if status != 0:\n            with nogil:\n                pjsip_tsx_terminate(self._initial_tsx, 500)\n            self._initial_tsx = NULL\n            self._dlg = NULL\n            raise PJSIPError(\"Could not create incoming REFER session\", status)\n        pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, <void *> self)\n        with nogil:\n            status = pjsip_dlg_create_response(self._dlg, rdata, 500, NULL, &self._initial_response)\n        if status != 0:\n            with nogil:\n                pjsip_tsx_terminate(self._initial_tsx, 500)\n            self._initial_tsx = NULL\n            raise PJSIPError(\"Could not create response for incoming REFER\", status)\n        _add_event(\"SIPIncomingReferralGotRefer\", event_dict)\n        return 0\n\n    def accept(self, int code=202, int duration=180):\n        cdef PJSIPUA ua = self._get_ua(1)\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state != \"incoming\":\n                raise SIPCoreInvalidStateError('Can only accept an incoming REFER in the \"incoming\" state, '+\n                                        'object is currently in the \"%s\" state' % self.state)\n            pjsip_evsub_update_expires(self._obj, duration)\n            self._send_initial_response(code)\n            self._set_state(\"active\")\n            if not self._create_subscription:\n                pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, NULL)\n                with nogil:\n                    pjsip_evsub_terminate(self._obj, 0)\n                self._obj = NULL\n                self._set_state(\"terminated\")\n                _add_event(\"SIPIncomingReferralDidEnd\", dict(obj=self))\n            else:\n                self._set_content(100, \"Trying\")\n                self._send_notify()\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    def reject(self, int code):\n        cdef PJSIPUA ua = self._get_ua(1)\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state != \"incoming\":\n                raise SIPCoreInvalidStateError('Can only reject an incoming REFER in the \"incoming\" state, '+\n                                        'object is currently in the \"%s\" state' % self.state)\n            if not (300 <= code < 700):\n                raise ValueError(\"Invalid negative SIP response code: %d\" % code)\n            self._send_initial_response(code)\n            pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, NULL)\n            with nogil:\n                pjsip_evsub_terminate(self._obj, 0)\n            self._obj = NULL\n            self._set_state(\"terminated\")\n            _add_event(\"SIPIncomingReferralDidEnd\", dict(obj=self))\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    def send_notify(self, int code, str status=None):\n        cdef PJSIPUA ua = self._get_ua(1)\n        cdef str content\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state != \"active\":\n                raise SIPCoreInvalidStateError('Can only send NOTIFY for a REFER session in the \"active\" state, '\n                                            'object is currently in the \"%s\" state' % self.state)\n            self._set_content(code, status)\n            self._send_notify()\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    def end(self, int code, str status=None):\n        cdef PJSIPUA ua = self._get_ua(0)\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state == \"terminated\":\n                return\n            if self.state not in (\"pending\", \"active\"):\n                raise SIPCoreInvalidStateError('Can only end an incoming REFER session in the \"pending\" or '+\n                                        '\"active\" state, object is currently in the \"%s\" state' % self.state)\n            self._set_content(code, status)\n            self._terminate(ua, 1)\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    cdef PJSIPUA _get_ua(self, int raise_exception):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n        except SIPCoreError:\n            self._obj = NULL\n            self._set_state(\"terminated\")\n            if raise_exception:\n                raise\n            else:\n                return None\n        else:\n            return ua\n\n    cdef int _set_content(self, int code, str reason) except -1:\n        cdef str content\n        if reason is None:\n            try:\n                reason = sip_status_messages[code]\n            except IndexError:\n                reason = \"Unknown\"\n        content = \"SIP/2.0 %d %s\\r\\n\" % (code, reason)\n        self._content = PJSTR(content)\n\n    cdef int _set_state(self, str state) except -1:\n        cdef str prev_state\n        prev_state = self.state\n        self.state = state\n        if prev_state != state and prev_state is not None:\n            _add_event(\"SIPIncomingReferralChangedState\", dict(obj=self, prev_state=prev_state, state=state))\n\n    cdef int _send_initial_response(self, int code) except -1:\n        cdef int status\n        with nogil:\n            status = pjsip_dlg_modify_response(self._dlg, self._initial_response, code, NULL)\n        if status != 0:\n            raise PJSIPError(\"Could not modify response\", status)\n        # pjsip_dlg_modify_response() increases ref count unncessarily\n        with nogil:\n            pjsip_tx_data_dec_ref(self._initial_response)\n        if not self._create_subscription:\n            _add_headers_to_tdata(self._initial_response, [Header('Refer-Sub', 'false')])\n        with nogil:\n            status = pjsip_dlg_send_response(self._dlg, self._initial_tsx, self._initial_response)\n        if status != 0:\n            raise PJSIPError(\"Could not send response\", status)\n        self._initial_response = NULL\n        self._initial_tsx = NULL\n\n    cdef int _send_notify(self) except -1:\n        cdef pjsip_evsub_state state\n        cdef pj_str_t *reason_p\n        cdef pjsip_tx_data *tdata\n        cdef int status\n        cdef dict _sipfrag_version = dict(version=\"2.0\")\n        cdef PJSTR _content_type = PJSTR(\"message\")\n        cdef PJSTR _content_subtype = PJSTR(\"sipfrag\")\n        cdef PJSTR reason = PJSTR(\"noresource\")\n\n        reason_p = NULL\n        if self.state == \"pending\":\n            state = PJSIP_EVSUB_STATE_PENDING\n        elif self.state == \"active\":\n            state = PJSIP_EVSUB_STATE_ACTIVE\n        else:\n            state = PJSIP_EVSUB_STATE_TERMINATED\n            reason_p = &reason.pj_str\n        with nogil:\n            status = pjsip_evsub_notify(self._obj, state, NULL, reason_p, &tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not create NOTIFY request\", status)\n        if self.state in (\"active\", \"terminated\"):\n            tdata.msg.body = pjsip_msg_body_create(tdata.pool, &_content_type.pj_str, &_content_subtype.pj_str, &self._content.pj_str)\n            _dict_to_pjsip_param(_sipfrag_version, &tdata.msg.body.content_type.param, tdata.pool)\n        with nogil:\n            status = pjsip_evsub_send_request(self._obj, tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not send NOTIFY request\", status)\n        event_dict = dict(obj=self)\n        _pjsip_msg_to_dict(tdata.msg, event_dict)\n        _add_event(\"SIPIncomingReferralSentNotify\", event_dict)\n        return 0\n\n    cdef int _terminate(self, PJSIPUA ua, int do_cleanup) except -1:\n        cdef int status\n        self._set_state(\"terminated\")\n        self._send_notify()\n        if do_cleanup:\n            pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, NULL)\n            self._obj = NULL\n        _add_event(\"SIPIncomingReferralDidEnd\", dict(obj=self))\n\n    cdef int _cb_rx_refresh(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1:\n        # PJSIP holds the dialog lock when this callback is entered\n        cdef int status\n        cdef pjsip_expires_hdr *expires_header\n        cdef int expires\n        cdef dict event_dict\n\n        event_dict = dict(obj=self)\n        _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n        expires_header = <pjsip_expires_hdr *> pjsip_msg_find_hdr(rdata.msg_info.msg, PJSIP_H_EXPIRES, NULL)\n        if expires_header == NULL:\n            self._expires_time.sec = 600\n            self._expires_time.msec = 0\n        else:\n            if expires_header.ivalue == 0:\n                _add_event(\"SIPIncomingReferralGotUnsubscribe\", event_dict)\n                # cleanup will be done by _cb_tsx\n                self._terminate(ua, 0)\n                return 200\n            else:\n                expires = min(expires_header.ivalue, 600)\n                self._expires_time.sec = expires\n                self._expires_time.msec = 0\n        _add_event(\"SIPIncomingReferralGotRefreshingSubscribe\", event_dict)\n        # Last NOTIFY will be resent\n        self._send_notify()\n        if self.state == \"active\":\n            return 200\n        else:\n            return 202\n\n    cdef int _cb_server_timeout(self, PJSIPUA ua) except -1:\n        # PJSIP holds the dialog lock when this callback is entered\n        self._terminate(ua, 1)\n\n    cdef int _cb_tsx(self, PJSIPUA ua, pjsip_event *event) except -1:\n        # PJSIP holds the dialog lock when this callback is entered\n        cdef pjsip_rx_data *rdata\n        cdef dict event_dict\n        cdef int status_code\n\n        if (event != NULL and event.type == PJSIP_EVENT_TSX_STATE and\n            event.body.tsx_state.tsx.role == PJSIP_ROLE_UAC and\n            _pj_str_to_str(event.body.tsx_state.tsx.method.name) == \"NOTIFY\" and\n            event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_COMPLETED):\n            event_dict = dict(obj=self)\n            rdata = event.body.tsx_state.src.rdata\n            if rdata != NULL:\n                if self.peer_address is None:\n                    self.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n                else:\n                    self.peer_address.ip = rdata.pkt_info.src_name\n                    self.peer_address.port = rdata.pkt_info.src_port\n            status_code = event.body.tsx_state.tsx.status_code\n            if event.body.tsx_state.type==PJSIP_EVENT_RX_MSG and status_code/100==2:\n                _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n                try:\n                    self.remote_contact_header = event_dict['headers']['Contact'][0]\n                except LookupError:\n                    pass\n                _add_event(\"SIPIncomingReferralNotifyDidSucceed\", event_dict)\n            else:\n                if event.body.tsx_state.type == PJSIP_EVENT_RX_MSG:\n                    _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n                else:\n                    event_dict[\"code\"] = status_code\n                    event_dict[\"reason\"] = _pj_str_to_str(event.body.tsx_state.tsx.status_text)\n                _add_event(\"SIPIncomingReferralNotifyDidFail\", event_dict)\n                if status_code in (408, 481) or status_code/100==7:\n                    # PJSIP will terminate the subscription and the dialog will be destroyed\n                    self._terminate(ua, 1)\n        elif (event != NULL and event.type == PJSIP_EVENT_TSX_STATE and\n            event.body.tsx_state.tsx.role == PJSIP_ROLE_UAC and\n            _pj_str_to_str(event.body.tsx_state.tsx.method.name) == \"NOTIFY\" and\n            event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_TERMINATED):\n            event_dict = dict(obj=self)\n            status_code = event.body.tsx_state.tsx.status_code\n            if status_code == 408:\n                # Local timeout, PJSIP will terminate the subscription and the dialog will be destroyed\n                event_dict[\"code\"] = status_code\n                event_dict[\"reason\"] = _pj_str_to_str(event.body.tsx_state.tsx.status_text)\n                _add_event(\"SIPIncomingReferralNotifyDidFail\", event_dict)\n                self._terminate(ua, 1)\n        elif (event != NULL and event.type == PJSIP_EVENT_TSX_STATE and\n            event.body.tsx_state.tsx.role == PJSIP_ROLE_UAS and\n            _pj_str_to_str(event.body.tsx_state.tsx.method.name) == \"REFER\" and\n            event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_COMPLETED and\n            event.body.tsx_state.type == PJSIP_EVENT_TX_MSG):\n            event_dict = dict(obj=self)\n            _pjsip_msg_to_dict(event.body.tsx_state.src.tdata.msg, event_dict)\n            _add_event(\"SIPIncomingReferralAnsweredRefer\", event_dict)\n            if self.state == \"terminated\" and self._obj != NULL:\n                pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, NULL)\n                self._obj = NULL\n\n\ncdef void _Referral_cb_state(pjsip_evsub *sub, pjsip_event *event) with gil:\n    cdef void *referral_void\n    cdef Referral referral\n    cdef object state\n    cdef int code = 0\n    cdef dict event_dict = dict()\n    cdef str reason = None\n    cdef pjsip_rx_data *rdata = NULL\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        referral_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if referral_void == NULL:\n            return\n        referral = <object> referral_void\n        state = pjsip_evsub_get_state_name(sub)\n        if (event != NULL and event.type == PJSIP_EVENT_TSX_STATE and\n            (event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_COMPLETED or\n             event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_TERMINATED)):\n            if state == \"TERMINATED\":\n                if event.body.tsx_state.tsx.role == PJSIP_ROLE_UAC:\n                    code = event.body.tsx_state.tsx.status_code\n                    reason = _pj_str_to_str(event.body.tsx_state.tsx.status_text)\n                else:\n                    reason = \"Referral has expired\"\n                if event.body.tsx_state.type == PJSIP_EVENT_RX_MSG and _pj_str_to_str(event.body.tsx_state.tsx.method.name) == \"NOTIFY\":\n                    # Extract code and reason from the sipfrag payload\n                    rdata = event.body.tsx_state.src.rdata\n                    if rdata != NULL:\n                        _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n                        if event_dict.get('body', None) is not None:\n                            match = sipfrag_re.match(event_dict['body'])\n                            if match:\n                                code = int(match.group('code'))\n                                reason = match.group('reason')\n        referral._cb_state(ua, state, code, reason)\n    except:\n        ua._handle_exception(1)\n\ncdef void _Referral_cb_tsx(pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event) with gil:\n    cdef void *referral_void\n    cdef Referral referral\n    cdef pjsip_rx_data *rdata\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        referral_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if referral_void == NULL:\n            return\n        referral = <object> referral_void\n        if (event != NULL and event.type == PJSIP_EVENT_TSX_STATE and\n            event.body.tsx_state.type == PJSIP_EVENT_RX_MSG and\n            event.body.tsx_state.tsx.role == PJSIP_ROLE_UAC and\n            event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_COMPLETED and\n            _pj_str_to_str(event.body.tsx_state.tsx.method.name) in (\"REFER\", \"SUBSCRIBE\") and\n            event.body.tsx_state.tsx.status_code/100 == 2):\n            rdata = event.body.tsx_state.src.rdata\n            if rdata != NULL:\n                if referral.peer_address is None:\n                    referral.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n                else:\n                    referral.peer_address.ip = rdata.pkt_info.src_name\n                    referral.peer_address.port = rdata.pkt_info.src_port\n            referral._cb_got_response(ua, rdata, _pj_str_to_str(event.body.tsx_state.tsx.method.name))\n    except:\n        ua._handle_exception(1)\n\ncdef void _Referral_cb_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code,\n                                    pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil:\n    cdef void *referral_void\n    cdef Referral referral\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        referral_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if referral_void == NULL:\n            return\n        referral = <object> referral_void\n        if rdata != NULL:\n            if referral.peer_address is None:\n                referral.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n            else:\n                referral.peer_address.ip = rdata.pkt_info.src_name\n                referral.peer_address.port = rdata.pkt_info.src_port\n        referral._cb_notify(ua, rdata)\n    except:\n        ua._handle_exception(1)\n\ncdef void _Referral_cb_refresh(pjsip_evsub *sub) with gil:\n    # We want to handle the refresh timer oursevles, ignore the PJSIP provided timer\n    pass\n\ncdef void _Referral_cb_timer(pj_timer_heap_t *timer_heap, pj_timer_entry *entry) with gil:\n    cdef Referral referral\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        if entry.user_data != NULL:\n            referral = <object> entry.user_data\n            if entry.id == 1:\n                referral._refresh_timer_active = 0\n                referral._cb_refresh_timer(ua)\n            else:\n                referral._timeout_timer_active = 0\n                referral._cb_timeout_timer(ua)\n    except:\n        ua._handle_exception(1)\n\ncdef void _IncomingReferral_cb_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code, pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil:\n    cdef void *referral_void\n    cdef IncomingReferral referral\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        referral_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if referral_void == NULL:\n            p_st_code[0] = 481\n            return\n        referral = <object> referral_void\n        if rdata != NULL:\n            if referral.peer_address is None:\n                referral.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n            else:\n                referral.peer_address.ip = rdata.pkt_info.src_name\n                referral.peer_address.port = rdata.pkt_info.src_port\n        p_st_code[0] = referral._cb_rx_refresh(ua, rdata)\n    except:\n        ua._handle_exception(1)\n\ncdef void _IncomingReferral_cb_server_timeout(pjsip_evsub *sub) with gil:\n    cdef void *referral_void\n    cdef IncomingReferral referral\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        referral_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if referral_void == NULL:\n            return\n        referral = <object> referral_void\n        referral._cb_server_timeout(ua)\n    except:\n        ua._handle_exception(1)\n\ncdef void _IncomingReferral_cb_tsx(pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event) with gil:\n    cdef void *referral_void\n    cdef IncomingReferral referral\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        referral_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if referral_void == NULL:\n            return\n        referral = <object> referral_void\n        referral._cb_tsx(ua, event)\n    except:\n        ua._handle_exception(1)\n\n\n# Globals\n#\n\ncdef pjsip_evsub_user _refer_cb\n_refer_cb.on_evsub_state = _Referral_cb_state\n_refer_cb.on_tsx_state = _Referral_cb_tsx\n_refer_cb.on_rx_notify = _Referral_cb_notify\n_refer_cb.on_client_refresh = _Referral_cb_refresh\ncdef pjsip_evsub_user _incoming_refer_subs_cb\n_incoming_refer_subs_cb.on_rx_refresh = _IncomingReferral_cb_rx_refresh\n_incoming_refer_subs_cb.on_server_timeout = _IncomingReferral_cb_server_timeout\n_incoming_refer_subs_cb.on_tsx_state = _IncomingReferral_cb_tsx\n\nsipfrag_re = re.compile(r'^SIP/2\\.0\\s+(?P<code>\\d{3})\\s+(?P<reason>[ a-zA-Z0-9_-]+)')\ncdef PJSTR _refer_method = PJSTR(\"REFER\")\ncdef PJSTR _refer_event = PJSTR(\"refer\")\ncdef PJSTR _refer_to_hdr_name = PJSTR(\"Refer-To\")\ncdef PJSTR _refer_sub_hdr_name = PJSTR(\"Refer-Sub\")\ncdef PJSTR _subscription_state_hdr_name = PJSTR(\"Subscription-State\")\n\n"
  },
  {
    "path": "sipsimple/core/_core.request.pxi",
    "content": "\nfrom datetime import datetime, timedelta\n\n\ncdef class EndpointAddress:\n\n    def __init__(self, ip, port):\n        self.ip = ip\n        self.port = port\n\n    def __repr__(self):\n        return \"%s(%r, %r)\" % (self.__class__.__name__, self.ip, self.port)\n\n    def __str__(self):\n        return \"%s:%d\" % (self.ip, self.port)\n\n\ncdef class Request:\n    expire_warning_time = 30\n\n    # properties\n\n    property method:\n\n        def __get__(self):\n            return self._method.str\n\n    property call_id:\n\n        def __get__(self):\n            return self._call_id.str\n\n    property content_type:\n\n        def __get__(self):\n            if self._content_type is None:\n                return None\n            else:\n                return \"/\".join([self._content_type.str, self._content_subtype.str])\n\n    property body:\n\n        def __get__(self):\n            if self._body is None:\n                return None\n            else:\n                return self._body.str\n\n    property expires_in:\n\n        def __get__(self):\n            cdef object dt\n            self._get_ua()\n            if self.state != \"EXPIRING\" or self._expire_time is None:\n                return 0\n            else:\n                dt = self._expire_time - datetime.now()\n                return max(0, dt.seconds)\n\n    # public methods\n\n    def __cinit__(self, *args, **kwargs):\n        self.state = \"INIT\"\n        self.peer_address = None\n        pj_timer_entry_init(&self._timer, 0, <void *> self, _Request_cb_timer)\n        self._timer_active = 0\n\n    def __init__(self, method, SIPURI request_uri not None, FromHeader from_header not None, ToHeader to_header not None,\n                 RouteHeader route_header not None, Credentials credentials=None, ContactHeader contact_header=None, call_id=None, cseq=None,\n                 object extra_headers=None, content_type=None, body=None):\n        cdef pjsip_method method_pj\n        cdef PJSTR from_header_str\n        cdef PJSTR to_header_str\n        cdef PJSTR request_uri_str\n        cdef PJSTR contact_header_str\n        cdef pj_str_t *contact_header_pj = NULL\n        cdef pj_str_t *call_id_pj = NULL\n        cdef object content_type_spl\n        cdef pjsip_hdr *hdr\n        cdef pjsip_contact_hdr *contact_hdr\n        cdef pjsip_cid_hdr *cid_hdr\n        cdef pjsip_cseq_hdr *cseq_hdr\n        cdef int status\n        cdef PJSIPUA ua = _get_ua()\n        if self._tsx != NULL or self.state != \"INIT\":\n            raise SIPCoreError(\"Request.__init__() was already called\")\n        if cseq is not None and cseq < 0:\n            raise ValueError(\"cseq argument cannot be negative\")\n        if extra_headers is not None:\n            header_names = set([header.name for header in extra_headers])\n            if \"Route\" in header_names:\n                raise ValueError(\"Route should be specified with route_header argument, not extra_headers\")\n            if \"Content-Type\" in header_names:\n                raise ValueError(\"Content-Type should be specified with content_type argument, not extra_headers\")\n        else:\n            header_names = ()\n        if content_type is not None and body is None:\n            raise ValueError(\"Cannot specify a content_type without a body\")\n        if content_type is None and body is not None:\n            raise ValueError(\"Cannot specify a body without a content_type\")\n        self._method = PJSTR(method)\n        pjsip_method_init_np(&method_pj, &self._method.pj_str)\n        if credentials is not None:\n            self.credentials = FrozenCredentials.new(credentials)\n        from_header_str = PJSTR(from_header.body)\n        self.to_header = FrozenToHeader.new(to_header)\n        to_header_str = PJSTR(to_header.body)\n        self.request_uri = FrozenSIPURI.new(request_uri)\n        request_uri_str = PJSTR(str(request_uri))\n        self.route_header = FrozenRouteHeader.new(route_header)\n        self.route_header.uri.parameters.dict[\"lr\"] = None # always send lr parameter in Route header\n        self.route_header.uri.parameters.dict[\"hide\"] = None # always hide Route header\n        if contact_header is not None:\n            self.contact_header = FrozenContactHeader.new(contact_header)\n            contact_parameters = contact_header.parameters.copy()\n            contact_parameters.pop(\"q\", None)\n            contact_parameters.pop(\"expires\", None)\n            contact_header.parameters = {}\n            contact_header_str = PJSTR(contact_header.body)\n            contact_header_pj = &contact_header_str.pj_str\n        if call_id is not None:\n            self._call_id = PJSTR(call_id)\n            call_id_pj = &self._call_id.pj_str\n        if cseq is None:\n            self.cseq = -1\n        else:\n            self.cseq = cseq\n        if extra_headers is None:\n            self.extra_headers = frozenlist()\n        else:\n            self.extra_headers = frozenlist([header.frozen_type.new(header) for header in extra_headers])\n        if body is not None:\n            content_type_spl = content_type.split(\"/\", 1)\n            self._content_type = PJSTR(content_type_spl[0])\n            self._content_subtype = PJSTR(content_type_spl[1])\n            self._body = PJSTR(body)\n        status = pjsip_endpt_create_request(ua._pjsip_endpoint._obj, &method_pj, &request_uri_str.pj_str,\n                                            &from_header_str.pj_str, &to_header_str.pj_str, contact_header_pj,\n                                            call_id_pj, self.cseq, NULL, &self._tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not create request\", status)\n        if body is not None:\n            self._tdata.msg.body = pjsip_msg_body_create(self._tdata.pool, &self._content_type.pj_str,\n                                                         &self._content_subtype.pj_str, &self._body.pj_str)\n        hdr = <pjsip_hdr *> (<pj_list *> &self._tdata.msg.hdr).next\n        while hdr != &self._tdata.msg.hdr:\n            if _pj_str_to_str(hdr.name) in header_names:\n                raise ValueError(\"Cannot override %s header value in extra_headers\" % _pj_str_to_str(hdr.name))\n            if hdr.type == PJSIP_H_CONTACT:\n                contact_hdr = <pjsip_contact_hdr *> hdr\n                _dict_to_pjsip_param(contact_parameters, &contact_hdr.other_param, self._tdata.pool)\n            elif hdr.type == PJSIP_H_CALL_ID:\n                cid_hdr = <pjsip_cid_hdr *> hdr\n                self._call_id = PJSTR(_pj_str_to_str(cid_hdr.id))\n            elif hdr.type == PJSIP_H_CSEQ:\n                cseq_hdr = <pjsip_cseq_hdr *> hdr\n                self.cseq = cseq_hdr.cseq\n            elif hdr.type == PJSIP_H_FROM:\n                self.from_header = FrozenFromHeader_create(<pjsip_fromto_hdr*> hdr)\n            else:\n                pass\n            hdr = <pjsip_hdr *> (<pj_list *> hdr).next\n        _BaseRouteHeader_to_pjsip_route_hdr(self.route_header, &self._route_header, self._tdata.pool)\n        pjsip_msg_add_hdr(self._tdata.msg, <pjsip_hdr *> &self._route_header)\n        _add_headers_to_tdata(self._tdata, self.extra_headers)\n        if self.credentials is not None:\n            status = pjsip_auth_clt_init(&self._auth, ua._pjsip_endpoint._obj, self._tdata.pool, 0)\n            if status != 0:\n                raise PJSIPError(\"Could not init authentication credentials\", status)\n            status = pjsip_auth_clt_set_credentials(&self._auth, 1, self.credentials.get_cred_info())\n            if status != 0:\n                raise PJSIPError(\"Could not set authentication credentials\", status)\n            self._need_auth = 1\n        else:\n            self._need_auth = 0\n        status = pjsip_tsx_create_uac(&ua._module, self._tdata, &self._tsx)\n        if status != 0:\n            raise PJSIPError(\"Could not create transaction for request\", status)\n        self._tsx.mod_data[ua._module.id] = <void *> self\n\n    def __dealloc__(self):\n        cdef PJSIPUA ua = self._get_ua()\n        if self._tsx != NULL:\n            self._tsx.mod_data[ua._module.id] = NULL\n            if self._tsx.state < PJSIP_TSX_STATE_COMPLETED:\n                pjsip_tsx_terminate(self._tsx, 500)\n            self._tsx = NULL\n        if self._tdata != NULL:\n            pjsip_tx_data_dec_ref(self._tdata)\n            self._tdata = NULL\n        if self._timer_active:\n            pjsip_endpt_cancel_timer(ua._pjsip_endpoint._obj, &self._timer)\n            self._timer_active = 0\n\n    def send(self, timeout=None):\n        cdef pj_time_val timeout_pj\n        cdef int status\n        cdef PJSIPUA ua = self._get_ua()\n        if self.state != \"INIT\":\n            raise SIPCoreError('This method may only be called in the \"INIT\" state, current state is \"%s\"' % self.state)\n        if timeout is not None:\n            if timeout <= 0:\n                raise ValueError(\"Timeout value cannot be negative\")\n            timeout_pj.sec = int(timeout)\n            timeout_pj.msec = (timeout * 1000) % 1000\n        self._timeout = timeout\n        status = pjsip_tsx_send_msg(self._tsx, self._tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not send request\", status)\n        pjsip_tx_data_add_ref(self._tdata)\n        if timeout:\n            status = pjsip_endpt_schedule_timer(ua._pjsip_endpoint._obj, &self._timer, &timeout_pj)\n        if status == 0:\n            self._timer_active = 1\n        self.state = \"IN_PROGRESS\"\n\n    def end(self):\n        cdef PJSIPUA ua = self._get_ua()\n        if self.state == \"IN_PROGRESS\":\n            pjsip_tsx_terminate(self._tsx, 408)\n        elif self.state == \"EXPIRING\":\n            pjsip_endpt_cancel_timer(ua._pjsip_endpoint._obj, &self._timer)\n            self._timer_active = 0\n            self.state = \"TERMINATED\"\n            _add_event(\"SIPRequestDidEnd\", dict(obj=self))\n\n    # private methods\n\n    cdef PJSIPUA _get_ua(self):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n        except SIPCoreError:\n            self._tsx = NULL\n            self._tdata = NULL\n            self._timer_active = 0\n            self.state = \"TERMINATED\"\n            return None\n        else:\n            return ua\n\n    cdef int _cb_tsx_state(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1:\n        cdef pjsip_tx_data *tdata_auth\n        cdef pjsip_transaction *tsx_auth\n        cdef pjsip_cseq_hdr *cseq\n        cdef dict event_dict\n        cdef int expires = -1\n        cdef SIPURI contact_uri\n        cdef dict contact_params\n        cdef pj_time_val timeout_pj\n        cdef int status\n        if rdata != NULL:\n            self.to_header = FrozenToHeader_create(rdata.msg_info.to_hdr)\n            if self.peer_address is None:\n                self.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n            else:\n                self.peer_address.ip = rdata.pkt_info.src_name\n                self.peer_address.port = rdata.pkt_info.src_port\n        if self._tsx.state == PJSIP_TSX_STATE_PROCEEDING:\n            if rdata == NULL:\n                return 0\n            event_dict = dict(obj=self)\n            _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n            _add_event(\"SIPRequestGotProvisionalResponse\", event_dict)\n        elif self._tsx.state == PJSIP_TSX_STATE_COMPLETED:\n            if self._timer_active:\n                pjsip_endpt_cancel_timer(ua._pjsip_endpoint._obj, &self._timer)\n                self._timer_active = 0\n            if self._need_auth and self._tsx.status_code in [401, 407]:\n                self._need_auth = 0\n                status = pjsip_auth_clt_reinit_req(&self._auth, rdata, self._tdata, &tdata_auth)\n                if status != 0:\n                    _add_event(\"SIPRequestDidFail\",\n                               dict(obj=self, code=0,\n                                    reason=\"Could not add auth data to request %s\" % _pj_status_to_str(status)))\n                    self.state = \"TERMINATED\"\n                    _add_event(\"SIPRequestDidEnd\", dict(obj=self))\n                    return 0\n                cseq = <pjsip_cseq_hdr *> pjsip_msg_find_hdr(tdata_auth.msg, PJSIP_H_CSEQ, NULL)\n                if cseq != NULL:\n                    cseq.cseq += 1\n                    self.cseq = cseq.cseq\n                status = pjsip_tsx_create_uac(&ua._module, tdata_auth, &tsx_auth)\n                if status != 0:\n                    pjsip_tx_data_dec_ref(tdata_auth)\n                    _add_event(\"SIPRequestDidFail\",\n                               dict(obj=self, code=0,\n                                    reason=\"Could not create transaction for request with auth %s\" %\n                                            _pj_status_to_str(status)))\n                    self.state = \"TERMINATED\"\n                    _add_event(\"SIPRequestDidEnd\", dict(obj=self))\n                    return 0\n                self._tsx.mod_data[ua._module.id] = NULL\n                self._tsx = tsx_auth\n                self._tsx.mod_data[ua._module.id] = <void *> self\n                status = pjsip_tsx_send_msg(self._tsx, tdata_auth)\n                if status != 0:\n                    pjsip_tx_data_dec_ref(tdata_auth)\n                    _add_event(\"SIPRequestDidFail\",\n                               dict(obj=self, code=0,\n                                    reason=\"Could not send request with auth %s\" % _pj_status_to_str(status)))\n                    self.state = \"TERMINATED\"\n                    _add_event(\"SIPRequestDidEnd\", dict(obj=self))\n                    return 0\n                elif self._timeout is not None:\n                    timeout_pj.sec = int(self._timeout)\n                    timeout_pj.msec = (self._timeout * 1000) % 1000\n                    status = pjsip_endpt_schedule_timer(ua._pjsip_endpoint._obj, &self._timer, &timeout_pj)\n                    if status == 0:\n                        self._timer_active = 1\n            else:\n                event_dict = dict(obj=self)\n                if rdata != NULL:\n                    # This shouldn't happen, but safety fist!\n                    _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n                if self._tsx.status_code / 100 == 2:\n                    if rdata != NULL:\n                        if \"Expires\" in event_dict[\"headers\"]:\n                            expires = event_dict[\"headers\"][\"Expires\"]\n                        elif self.contact_header is not None:\n                            for contact_header in event_dict[\"headers\"].get(\"Contact\", []):\n                                if contact_header.uri == self.contact_header.uri and contact_header.expires is not None:\n                                    expires = contact_header.expires\n                        if expires == -1:\n                            expires = 0\n                            for header in self.extra_headers:\n                                if header.name == \"Expires\":\n                                    try:\n                                        expires = int(header.body)\n                                    except ValueError:\n                                        pass\n                                    break\n                    event_dict[\"expires\"] = expires\n                    self._expire_time = datetime.now() + timedelta(seconds=expires)\n                    _add_event(\"SIPRequestDidSucceed\", event_dict)\n                else:\n                    expires = 0\n                    _add_event(\"SIPRequestDidFail\", event_dict)\n                if expires == 0:\n                    self.state = \"TERMINATED\"\n                    _add_event(\"SIPRequestDidEnd\", dict(obj=self))\n                else:\n                    timeout_pj.sec = max(1, expires - self.expire_warning_time, expires/2)\n                    timeout_pj.msec = 0\n                    status = pjsip_endpt_schedule_timer(ua._pjsip_endpoint._obj, &self._timer, &timeout_pj)\n                    if status == 0:\n                        self._timer_active = 1\n                        self.state = \"EXPIRING\"\n                        self._expire_rest = max(1, expires - timeout_pj.sec)\n                    else:\n                        self.state = \"TERMINATED\"\n                        _add_event(\"SIPRequestDidEnd\", dict(obj=self))\n        elif self._tsx.state == PJSIP_TSX_STATE_TERMINATED:\n            if self.state == \"IN_PROGRESS\":\n                if self._timer_active:\n                    pjsip_endpt_cancel_timer(ua._pjsip_endpoint._obj, &self._timer)\n                    self._timer_active = 0\n                _add_event(\"SIPRequestDidFail\", dict(obj=self, code=self._tsx.status_code,\n                                                     reason=_pj_str_to_str(self._tsx.status_text)))\n                self.state = \"TERMINATED\"\n                _add_event(\"SIPRequestDidEnd\", dict(obj=self))\n            self._tsx.mod_data[ua._module.id] = NULL\n            self._tsx = NULL\n        else:\n            pass\n\n    cdef int _cb_timer(self, PJSIPUA ua) except -1:\n        cdef pj_time_val expires\n        cdef int status\n        if self.state == \"IN_PROGRESS\":\n            pjsip_tsx_terminate(self._tsx, 408)\n        elif self.state == \"EXPIRING\":\n            if self._expire_rest > 0:\n                _add_event(\"SIPRequestWillExpire\", dict(obj=self, expires=self._expire_rest))\n                expires.sec = self._expire_rest\n                expires.msec = 0\n                self._expire_rest = 0\n                status = pjsip_endpt_schedule_timer(ua._pjsip_endpoint._obj, &self._timer, &expires)\n                if status == 0:\n                    self._timer_active = 1\n                else:\n                    self.state = \"TERMINATED\"\n                    _add_event(\"SIPRequestDidEnd\", dict(obj=self))\n            else:\n                self.state = \"TERMINATED\"\n                _add_event(\"SIPRequestDidEnd\", dict(obj=self))\n        return 0\n\n\ncdef class IncomingRequest:\n\n    def __cinit__(self, *args, **kwargs):\n        self.peer_address = None\n\n    def __dealloc__(self):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n        except SIPCoreError:\n            return\n        if self._tsx != NULL:\n            pjsip_tsx_terminate(self._tsx, 500)\n            self._tsx = NULL\n        if self._tdata != NULL:\n            pjsip_tx_data_dec_ref(self._tdata)\n            self._tdata = NULL\n\n    def answer(self, int code, str reason=None, object extra_headers=None):\n        cdef bytes reason_bytes\n        cdef dict event_dict\n        cdef int status\n        cdef PJSIPUA ua = _get_ua()\n        if self.state != \"incoming\":\n            raise SIPCoreInvalidStateError('Can only answer an incoming request in the \"incoming\" state, '\n                                     'object is currently in the \"%s\" state' % self.state)\n        if code < 200 or code >= 700:\n            raise ValueError(\"Invalid SIP final response code: %d\" % code)\n        self._tdata.msg.line.status.code = code\n        if reason is None:\n            self._tdata.msg.line.status.reason = pjsip_get_status_text(code)[0]\n        else:\n            reason_bytes = reason.encode()\n            pj_strdup2_with_null(self._tdata.pool, &self._tdata.msg.line.status.reason, reason_bytes)\n        if extra_headers is not None:\n            _add_headers_to_tdata(self._tdata, extra_headers)\n        event_dict = dict(obj=self)\n        _pjsip_msg_to_dict(self._tdata.msg, event_dict)\n        status = pjsip_tsx_send_msg(self._tsx, self._tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not send response\", status)\n        self.state = \"answered\"\n        self._tdata = NULL\n        self._tsx = NULL\n        _add_event(\"SIPIncomingRequestSentResponse\", event_dict)\n\n    cdef int init(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1:\n        cdef dict event_dict\n        cdef int status\n        status = pjsip_endpt_create_response(ua._pjsip_endpoint._obj, rdata, 500, NULL, &self._tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not create response\", status)\n        status = pjsip_tsx_create_uas(&ua._module, rdata, &self._tsx)\n        if status != 0:\n            pjsip_tx_data_dec_ref(self._tdata)\n            self._tdata = NULL\n            raise PJSIPError(\"Could not create transaction for incoming request\", status)\n        pjsip_tsx_recv_msg(self._tsx, rdata)\n        self.state = \"incoming\"\n        self.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n        event_dict = dict(obj=self)\n        _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n        _add_event(\"SIPIncomingRequestGotRequest\", event_dict)\n\n\n# callback functions\n\ncdef void _Request_cb_tsx_state(pjsip_transaction *tsx, pjsip_event *event) with gil:\n    cdef PJSIPUA ua\n    cdef void *req_ptr\n    cdef Request req\n    cdef pjsip_rx_data *rdata = NULL\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        req_ptr = tsx.mod_data[ua._module.id]\n        if req_ptr != NULL:\n            req = <object> req_ptr\n            if event.type == PJSIP_EVENT_RX_MSG:\n                rdata = event.body.rx_msg.rdata\n            elif event.type == PJSIP_EVENT_TSX_STATE and event.body.tsx_state.type == PJSIP_EVENT_RX_MSG:\n                rdata = event.body.tsx_state.src.rdata\n            req._cb_tsx_state(ua, rdata)\n    except:\n        ua._handle_exception(1)\n\ncdef void _Request_cb_timer(pj_timer_heap_t *timer_heap, pj_timer_entry *entry) with gil:\n    cdef PJSIPUA ua\n    cdef Request req\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        if entry.user_data != NULL:\n            req = <object> entry.user_data\n            req._timer_active = 0\n            req._cb_timer(ua)\n    except:\n        ua._handle_exception(1)\n\n\n"
  },
  {
    "path": "sipsimple/core/_core.sdp.pxi",
    "content": "\nimport re\n\nfrom application.python.descriptor import WriteOnceAttribute\n\n\ncdef object BaseSDPSession_richcmp(object self, object other, int op) with gil:\n    cdef int eq = 1\n    if op not in [2,3]:\n        return NotImplemented\n    if not isinstance(other, BaseSDPSession):\n        return NotImplemented\n    for attr in (\"id\", \"version\", \"user\", \"net_type\", \"address_type\", \"address\", \"address\",\n                 \"name\", \"connection\", \"start_time\", \"stop_time\", \"attributes\", \"bandwidth_info\", \"media\"):\n        if getattr(self, attr) != getattr(other, attr):\n            eq = 0\n            break\n    if op == 2:\n        return bool(eq)\n    else:\n        return not eq\n\ncdef pjmedia_sdp_session* _parse_sdp_session(str sdp):\n    cdef int status\n    cdef pjmedia_sdp_session *sdp_session\n\n    status = pjmedia_sdp_parse(_get_ua()._pjsip_endpoint._pool, PyString_AsString(sdp), PyString_Size(sdp), &sdp_session)\n    if status != 0:\n        raise PJSIPError(\"failed to parse SDP\", status)\n    return sdp_session\n\ncdef class BaseSDPSession:\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"BaseSDPSession cannot be instantiated directly\")\n\n    def __repr__(self):\n        return \"%s(%r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r)\" % (self.__class__.__name__, self.address, self.id, self.version, self.user, self.net_type,\n                    self.address_type, self.name, self.connection, self.start_time, self.stop_time, self.attributes, self.bandwidth_info, self.media)\n\n    def __str__(self):\n        cdef char cbuf[2048]\n        cdef int buf_len\n        buf_len = pjmedia_sdp_print(self.get_sdp_session(), cbuf, sizeof(cbuf))\n        if buf_len > -1:\n            return PyString_FromStringAndSize(cbuf, buf_len)\n        return ''\n\n    def __richcmp__(self, other, op):\n        return BaseSDPSession_richcmp(self, other, op)\n\n    cdef pjmedia_sdp_session* get_sdp_session(self):\n        self._sdp_session.media_count = len(self.media)\n        for index, m in enumerate(self.media):\n            if m is not None:\n                self._sdp_session.media[index] = (<BaseSDPMediaStream>m).get_sdp_media()\n            else:\n                self._sdp_session.media[index] = NULL\n        self._sdp_session.attr_count = len(self.attributes)\n        for index, attr in enumerate(self.attributes):\n            self._sdp_session.attr[index] = (<BaseSDPAttribute>attr).get_sdp_attribute()\n        self._sdp_session.bandw_count = len(self.bandwidth_info)\n        for index, info in enumerate(self.bandwidth_info):\n            self._sdp_session.bandw[index] = (<BaseSDPBandwidthInfo>info).get_sdp_bandwidth_info()\n        return &self._sdp_session\n\n    property has_ice_attributes:\n\n        def __get__(self):\n            return set([attr.name for attr in self.attributes]).issuperset(['ice-pwd', 'ice-ufrag'])\n\ncdef class SDPSession(BaseSDPSession):\n    def __init__(self, str address not None, object id=None, object version=None, str user not None=\"-\", str net_type not None=\"IN\", str address_type not None=\"IP4\",\n                 str name not None=\" \", SDPConnection connection=None, unsigned long start_time=0, unsigned long stop_time=0, list attributes=None, list bandwidth_info=None, list media=None):\n        cdef unsigned int version_id = 2208988800UL\n        cdef pj_time_val tv\n\n        pj_gettimeofday(&tv)\n        version_id += tv.sec\n\n        self.address = address\n        self.id = id if id is not None else version_id\n        self.version = version if version is not None else version_id\n        self.user = user\n        self.net_type = net_type\n        self.address_type = address_type\n        self.name = name\n        self.connection = connection\n        self.start_time = start_time\n        self.stop_time = stop_time\n        self.attributes = attributes if attributes is not None else []\n        self.bandwidth_info = bandwidth_info if bandwidth_info is not None else []\n        self.media = media if media is not None else []\n\n    @classmethod\n    def new(cls, BaseSDPSession sdp_session):\n        connection = SDPConnection.new(sdp_session.connection) if (sdp_session.connection is not None) else None\n        attributes = [SDPAttribute.new(attr) for attr in sdp_session.attributes]\n        bandwidth_info = [SDPBandwidthInfo.new(info) for info in sdp_session.bandwidth_info]\n        media = [SDPMediaStream.new(m) if m is not None else None for m in sdp_session.media]\n        return cls(sdp_session.address, sdp_session.id, sdp_session.version, sdp_session.user, sdp_session.net_type, sdp_session.address_type, sdp_session.name,\n                   connection, sdp_session.start_time, sdp_session.stop_time, attributes, bandwidth_info, media)\n\n    @classmethod\n    def parse(cls, str sdp):\n        cdef pjmedia_sdp_session *sdp_session\n        sdp_session = _parse_sdp_session(sdp)\n        return SDPSession_create(sdp_session)\n\n    property address:\n\n        def __get__(self):\n            return self._address\n\n        def __set__(self, str address not None):\n            _str_to_pj_str(address, &self._sdp_session.origin.addr)\n            self._address = address\n\n    property id:\n\n        def __get__(self):\n            return self._sdp_session.origin.id\n\n        def __set__(self, unsigned int id):\n            self._sdp_session.origin.id = id\n\n    property version:\n\n        def __get__(self):\n            return self._sdp_session.origin.version\n\n        def __set__(self, unsigned int version):\n            self._sdp_session.origin.version = version\n\n    property user:\n\n        def __get__(self):\n            return self._user\n\n        def __set__(self, str user not None):\n            _str_to_pj_str(user, &self._sdp_session.origin.user)\n            self._user = user\n\n    property net_type:\n\n        def __get__(self):\n            return self._net_type\n\n        def __set__(self, str net_type not None):\n            _str_to_pj_str(net_type, &self._sdp_session.origin.net_type)\n            self._net_type = net_type\n\n    property address_type:\n\n        def __get__(self):\n            return self._address_type\n\n        def __set__(self, str address_type not None):\n            _str_to_pj_str(address_type, &self._sdp_session.origin.addr_type)\n            self._address_type = address_type\n\n    property name:\n\n        def __get__(self):\n            return self._name\n\n        def __set__(self, str name not None):\n            _str_to_pj_str(name, &self._sdp_session.name)\n            self._name = name\n\n    property connection:\n\n        def __get__(self):\n            return self._connection\n\n        def __set__(self, SDPConnection connection):\n            if connection is None:\n                self._sdp_session.conn = NULL\n            else:\n                self._sdp_session.conn = connection.get_sdp_connection()\n            self._connection = connection\n\n    property start_time:\n\n        def __get__(self):\n            return self._sdp_session.time.start\n\n        def __set__(self, unsigned long start_time):\n            self._sdp_session.time.start = start_time\n\n    property stop_time:\n\n        def __get__(self):\n            return self._sdp_session.time.stop\n\n        def __set__(self, unsigned long stop_time):\n            self._sdp_session.time.stop = stop_time\n\n    property attributes:\n\n        def __get__(self):\n            return self._attributes\n\n        def __set__(self, list attributes not None):\n            if len(attributes) > PJMEDIA_MAX_SDP_ATTR:\n                raise SIPCoreError(\"Too many attributes\")\n            for attr in attributes:\n                if not isinstance(attr, SDPAttribute):\n                    raise TypeError(\"Items in SDPSession attribute list must be SDPAttribute instancess\")\n            if not isinstance(attributes, SDPAttributeList):\n                attributes = SDPAttributeList(attributes)\n            self._attributes = attributes\n\n    property bandwidth_info:\n\n        def __get__(self):\n            return self._bandwidth_info\n\n        def __set__(self, list infos not None):\n            if len(infos) > PJMEDIA_MAX_SDP_BANDW:\n                raise SIPCoreError(\"Too many bandwidth info attributes\")\n            for info in infos:\n                if not isinstance(info, SDPBandwidthInfo):\n                    raise TypeError(\"Items in SDPSession attribute list must be SDPBandwidthInfo instancess\")\n            if not isinstance(infos, SDPBandwidthInfoList):\n                infos = SDPBandwidthInfoList(infos)\n            self._bandwidth_info = infos\n\n    property media:\n\n        def __get__(self):\n            return self._media\n\n        def __set__(self, list media not None):\n            if len(media) > PJMEDIA_MAX_SDP_MEDIA:\n                raise SIPCoreError(\"Too many media objects\")\n            for m in media:\n                if m is not None and not isinstance(m, SDPMediaStream):\n                    raise TypeError(\"Items in SDPSession media list must be SDPMediaStream instancess\")\n            self._media = media\n\n    cdef int _update(self) except -1:\n        cdef SDPSession session\n        cdef SDPMediaStream media, old_media\n        session = SDPSession_create(&(<BaseSDPSession>self)._sdp_session)\n        if len(self._media) != len(session._media):\n            raise ValueError(\"Number of media streams in SDPSession got changed\")\n        if len(self._attributes) > len(session._attributes):\n            raise ValueError(\"Number of attributes in SDPSession got reduced\")\n        for attr in (\"id\", \"version\", \"user\", \"net_type\", \"address_type\",\n                     \"address\", \"name\", \"start_time\", \"stop_time\"):\n            setattr(self, attr, getattr(session, attr))\n        if session._connection is None:\n            self.connection = None\n        elif self._connection is None or self._connection != session._connection:\n            self.connection = session._connection\n        for index, attribute in enumerate(session._attributes):\n            try:\n                old_attribute = self._attributes[index]\n            except IndexError:\n                self._attributes.append(attribute)\n            else:\n                if old_attribute != attribute:\n                    self._attributes[index] = attribute\n        for index, info in enumerate(session._bandwidth_info):\n            try:\n                old_info = self._bandwidth_info[index]\n            except IndexError:\n                self._bandwidth_info.append(info)\n            else:\n                if old_info != info:\n                    self._bandwidth_info[index] = info\n        for index, media in enumerate(session._media):\n            old_media = self._media[index]\n            if old_media is not None:\n                old_media._update(media)\n\ncdef class FrozenSDPSession(BaseSDPSession):\n    def __init__(self, str address not None, object id=None, object version=None, str user not None=\"-\", str net_type not None=\"IN\", str address_type not None=\"IP4\", str name not None=\" \",\n                 FrozenSDPConnection connection=None, unsigned long start_time=0, unsigned long stop_time=0, frozenlist attributes not None=frozenlist(), frozenlist bandwidth_info not None=frozenlist(),\n                 frozenlist media not None=frozenlist()):\n        cdef unsigned int version_id = 2208988800UL\n        cdef pj_time_val tv\n\n        if not self.initialized:\n            if len(attributes) > PJMEDIA_MAX_SDP_ATTR:\n                raise SIPCoreError(\"Too many attributes\")\n            for attr in attributes:\n                if not isinstance(attr, FrozenSDPAttribute):\n                    raise TypeError(\"Items in FrozenSDPSession attribute list must be FrozenSDPAttribute instances\")\n            if len(bandwidth_info) > PJMEDIA_MAX_SDP_BANDW:\n                raise SIPCoreError(\"Too many bandwidth info attributes\")\n            for info in bandwidth_info:\n                if not isinstance(info, FrozenSDPBandwidthInfo):\n                    raise TypeError(\"Items in FrozenSDPSession bandwidth info attribute list must be FrozenSDPBandwidthInfo instances\")\n            if len(media) > PJMEDIA_MAX_SDP_MEDIA:\n                raise SIPCoreError(\"Too many media objects\")\n            for m in media:\n                if not isinstance(m, FrozenSDPMediaStream):\n                    raise TypeError(\"Items in FrozenSDPSession media list must be FrozenSDPMediaStream instancess\")\n\n            pj_gettimeofday(&tv)\n            version_id += tv.sec\n\n            self.address = address\n            _str_to_pj_str(address, &self._sdp_session.origin.addr)\n            self.id = id if id is not None else version_id\n            self._sdp_session.origin.id = id if id is not None else version_id\n            self.version = version if version is not None else version_id\n            self._sdp_session.origin.version = version if version is not None else version_id\n            self.user = user\n            _str_to_pj_str(user, &self._sdp_session.origin.user)\n            self.net_type = net_type\n            _str_to_pj_str(net_type, &self._sdp_session.origin.net_type)\n            self.address_type = address_type\n            _str_to_pj_str(address_type, &self._sdp_session.origin.addr_type)\n            self.name = name\n            _str_to_pj_str(name, &self._sdp_session.name)\n            self.connection = connection\n            if connection is None:\n                self._sdp_session.conn = NULL\n            else:\n                self._sdp_session.conn = connection.get_sdp_connection()\n            self.start_time = start_time\n            self._sdp_session.time.start = start_time\n            self.stop_time = stop_time\n            self._sdp_session.time.stop = stop_time\n            self.attributes = FrozenSDPAttributeList(attributes) if not isinstance(attributes, FrozenSDPAttributeList) else attributes\n            self.bandwidth_info = FrozenSDPBandwidthInfoList(bandwidth_info) if not isinstance(bandwidth_info, FrozenSDPBandwidthInfo) else bandwidth_info\n            self.media = media\n            self.initialized = 1\n\n    @classmethod\n    def new(cls, BaseSDPSession sdp_session):\n        if isinstance(sdp_session, FrozenSDPSession):\n            return sdp_session\n        connection = FrozenSDPConnection.new(sdp_session.connection) if (sdp_session.connection is not None) else None\n        attributes = frozenlist([FrozenSDPAttribute.new(attr) for attr in sdp_session.attributes])\n        bandwidth_info = frozenlist([FrozenSDPBandwidthInfo.new(info) for info in sdp_session.bandwidth_info])\n        media = frozenlist([FrozenSDPMediaStream.new(m) for m in sdp_session.media])\n        return cls(sdp_session.address, sdp_session.id, sdp_session.version, sdp_session.user, sdp_session.net_type, sdp_session.address_type, sdp_session.name,\n                   connection, sdp_session.start_time, sdp_session.stop_time, attributes, bandwidth_info, media)\n\n    @classmethod\n    def parse(cls, str sdp):\n        cdef pjmedia_sdp_session *sdp_session\n        sdp_session = _parse_sdp_session(sdp)\n        return FrozenSDPSession_create(sdp_session)\n\n    def __hash__(self):\n        return hash((self.address, self.id, self.version, self.user, self.net_type, self.address_type, self.name, self.connection, self.start_time, self.stop_time, self.attributes, self.bandwidth_info, self.media))\n\n    def __richcmp__(self, other, op):\n        return BaseSDPSession_richcmp(self, other, op)\n\n\nclass MediaCodec(object):\n    name = WriteOnceAttribute()\n    rate = WriteOnceAttribute()\n\n    def __init__(self, name, rate):\n        self.name = name\n        self.rate = int(rate)\n\n    def __repr__(self):\n        return \"%s(%r, %r)\" % (self.__class__.__name__, self.name, self.rate)\n\n    def __str__(self):\n        return \"%s/%s\" % (self.name, self.rate)\n\n    def __hash__(self):\n        return hash(self.name)\n\n    def __eq__(self, other):\n        if isinstance(other, MediaCodec):\n            return self.name.lower() == other.name.lower() and self.rate == other.rate\n        elif isinstance(other, basestring):\n            if '/' in other:\n                return self.__str__().lower() == other.lower()\n            else:\n                return self.name.lower() == other.lower()\n        return False\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n\ncdef object BaseSDPMediaStream_richcmp(object self, object other, int op) with gil:\n    cdef int eq = 1\n    if op not in [2,3]:\n        return NotImplemented\n    if not isinstance(other, BaseSDPMediaStream):\n        return NotImplemented\n    for attr in (\"media\", \"port\", \"port_count\", \"transport\", \"formats\", \"connection\", \"attributes\", \"bandwidth_info\"):\n        if getattr(self, attr) != getattr(other, attr):\n            eq = 0\n            break\n    if op == 2:\n        return bool(eq)\n    else:\n        return not eq\n\ncdef class BaseSDPMediaStream:\n    rtpmap_re = re.compile(r\"\"\"^(?P<type>\\d+)\\s+(?P<name>[-\\w]+)/(?P<rate>\\d+)(?:/\\w+)?$\"\"\", re.IGNORECASE | re.MULTILINE)\n    rtp_mappings = { 0: MediaCodec('PCMU',  8000),\n                     3: MediaCodec('GSM',   8000),\n                     4: MediaCodec('G723',  8000),\n                     5: MediaCodec('DVI4',  8000),\n                     6: MediaCodec('DVI4', 16000),\n                     7: MediaCodec('LPC',   8000),\n                     8: MediaCodec('PCMA',  8000),\n                     9: MediaCodec('G722',  8000),\n                    10: MediaCodec('L16',  44100), # 2 channels\n                    11: MediaCodec('L16',  44100), # 1 channel\n                    12: MediaCodec('QCELP', 8000),\n                    13: MediaCodec('CN',    8000),\n                    14: MediaCodec('MPA',  90000),\n                    15: MediaCodec('G728',  8000),\n                    16: MediaCodec('DVI4', 11025),\n                    17: MediaCodec('DVI4', 22050),\n                    18: MediaCodec('G729',  8000)}\n\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"BaseSDPMediaStream cannot be instantiated directly\")\n\n    def __repr__(self):\n        return \"%s(%r, %r, %r, %r, %r, %r, %r, %r)\" % (self.__class__.__name__, self.media, self.port, self.transport,\n                self.port_count, self.formats, self.connection, self.attributes, self.bandwidth_info)\n\n    def __richcmp__(self, other, op):\n        return BaseSDPMediaStream_richcmp(self, other, op)\n\n    property direction:\n\n        def __get__(self):\n            for attribute in self.attributes:\n                if attribute.name in (\"sendrecv\", \"sendonly\", \"recvonly\", \"inactive\"):\n                    return attribute.name\n            return \"sendrecv\"\n\n    property has_ice_attributes:\n\n        def __get__(self):\n            return set([attr.name for attr in self.attributes]).issuperset(['ice-pwd', 'ice-ufrag'])\n\n    property has_ice_candidates:\n\n        def __get__(self):\n            return 'candidate' in self.attributes\n\n    cdef pjmedia_sdp_media* get_sdp_media(self):\n        self._sdp_media.attr_count = len(self.attributes)\n        for index, attr in enumerate(self.attributes):\n            self._sdp_media.attr[index] = (<BaseSDPAttribute>attr).get_sdp_attribute()\n        self._sdp_media.bandw_count = len(self.bandwidth_info)\n        for index, info in enumerate(self.bandwidth_info):\n            self._sdp_media.bandw[index] = (<BaseSDPBandwidthInfo>info).get_sdp_bandwidth_info()\n        return &self._sdp_media\n\ncdef class SDPMediaStream(BaseSDPMediaStream):\n    def __init__(self, str media not None, int port, str transport not None, int port_count=1, list formats=None,\n                 SDPConnection connection=None, list attributes=None, list bandwidth_info=None):\n        self.media = media\n        self.port = port\n        self.transport = transport\n        self.port_count = port_count\n        self.formats = formats if formats is not None else []\n        self.connection = connection\n        self.attributes = attributes if attributes is not None else []\n        self.bandwidth_info = bandwidth_info if bandwidth_info is not None else []\n\n    @classmethod\n    def new(cls, BaseSDPMediaStream sdp_media):\n        connection = SDPConnection.new(sdp_media.connection) if (sdp_media.connection is not None) else None\n        attributes = [SDPAttribute.new(attr) for attr in sdp_media.attributes]\n        bandwidth_info = [SDPBandwidthInfo.new(bi) for bi in sdp_media.bandwidth_info]\n        return cls(sdp_media.media, sdp_media.port, sdp_media.transport, sdp_media.port_count, list(sdp_media.formats),\n                   connection, attributes, bandwidth_info)\n\n    property media:\n\n        def __get__(self):\n            return self._media\n\n        def __set__(self, str media not None):\n            _str_to_pj_str(media, &self._sdp_media.desc.media)\n            self._media = media\n\n    property port:\n\n        def __get__(self):\n            return self._sdp_media.desc.port\n\n        def __set__(self, int port):\n            self._sdp_media.desc.port = port\n\n    property transport:\n\n        def __get__(self):\n            return self._transport\n\n        def __set__(self, str transport not None):\n            _str_to_pj_str(transport, &self._sdp_media.desc.transport)\n            self._transport = transport\n\n    property port_count:\n\n        def __get__(self):\n            return self._sdp_media.desc.port_count\n\n        def __set__(self, int port_count):\n            self._sdp_media.desc.port_count = port_count\n\n    property formats:\n\n        def __get__(self):\n            return self._formats\n\n        def __set__(self, list formats not None):\n            if len(formats) > PJMEDIA_MAX_SDP_FMT:\n                raise SIPCoreError(\"Too many formats\")\n            self._sdp_media.desc.fmt_count = len(formats)\n            for index, format in enumerate(formats):\n                _str_to_pj_str(format, &self._sdp_media.desc.fmt[index])\n            self._formats = formats\n\n    property codec_list:\n\n        def __get__(self):\n            return self._codec_list\n\n    property connection:\n\n        def __get__(self):\n            return self._connection\n\n        def __set__(self, SDPConnection connection):\n            if connection is None:\n                self._sdp_media.conn = NULL\n            else:\n                self._sdp_media.conn = connection.get_sdp_connection()\n            self._connection = connection\n\n    property attributes:\n\n        def __get__(self):\n            return self._attributes\n\n        def __set__(self, list attributes not None):\n            if len(attributes) > PJMEDIA_MAX_SDP_ATTR:\n                raise SIPCoreError(\"Too many attributes\")\n            for attr in attributes:\n                if not isinstance(attr, SDPAttribute):\n                    raise TypeError(\"Items in SDPMediaStream attribute list must be SDPAttribute instances\")\n            if not isinstance(attributes, SDPAttributeList):\n                attributes = SDPAttributeList(attributes)\n            self._attributes = attributes\n            if self._media in (\"audio\", \"video\"):\n                rtp_mappings = self.rtp_mappings.copy()\n                rtpmap_lines = '\\n'.join([attr.value for attr in attributes if attr.name=='rtpmap']) # iterators are not supported -Dan\n                rtpmap_codecs = dict([(int(type), MediaCodec(name, rate)) for type, name, rate in self.rtpmap_re.findall(rtpmap_lines)])\n                rtp_mappings.update(rtpmap_codecs)\n                self._codec_list = [rtp_mappings.get(int(format), MediaCodec('Unknown', 0)) for format in self.formats]\n            else:\n                self._codec_list = list()\n\n    property bandwidth_info:\n\n        def __get__(self):\n            return self._bandwidth_info\n\n        def __set__(self, list infos not None):\n            if len(infos) > PJMEDIA_MAX_SDP_BANDW:\n                raise SIPCoreError(\"Too many bandwidth information attributes\")\n            for info in infos:\n                if not isinstance(info, SDPBandwidthInfo):\n                    raise TypeError(\"Items in SDPMediaStream bandwidth_info list must be SDPBandwidthInfo instances\")\n            if not isinstance(infos, SDPBandwidthInfoList):\n                infos = SDPBandwidthInfoList(infos)\n            self._bandwidth_info = infos\n\n    cdef int _update(self, SDPMediaStream media) except -1:\n        if len(self._attributes) > len(media._attributes):\n            raise ValueError(\"Number of attributes in SDPMediaStream got reduced\")\n        if len(self._bandwidth_info) > len(media._bandwidth_info):\n            raise ValueError(\"Number of bandwidth info attributes in SDPMediaStream got reduced\")\n        for attr in (\"media\", \"port\", \"transport\", \"port_count\", \"formats\"):\n            setattr(self, attr, getattr(media, attr))\n        if media._connection is None:\n            self.connection = None\n        elif self._connection is None or self._connection != media.connection:\n            self.connection = media._connection\n        for index, attribute in enumerate(media._attributes):\n            try:\n                old_attribute = self._attributes[index]\n            except IndexError:\n                self._attributes.append(attribute)\n            else:\n                if old_attribute != attribute:\n                    self._attributes[index] = attribute\n        for index, info in enumerate(media._bandwidth_info):\n            try:\n                old_info = self._bandwidth_info[index]\n            except IndexError:\n                self._bandwidth_info.append(info)\n            else:\n                if old_info != info:\n                    self._bandwidth_info[index] = info\n\ncdef class FrozenSDPMediaStream(BaseSDPMediaStream):\n    def __init__(self, str media not None, int port, str transport not None, int port_count=1, frozenlist formats not None=frozenlist(),\n                 FrozenSDPConnection connection=None, frozenlist attributes not None=frozenlist(), frozenlist bandwidth_info not None=frozenlist()):\n        if not self.initialized:\n            if len(formats) > PJMEDIA_MAX_SDP_FMT:\n                raise SIPCoreError(\"Too many formats\")\n            if len(attributes) > PJMEDIA_MAX_SDP_ATTR:\n                raise SIPCoreError(\"Too many attributes\")\n            for attr in attributes:\n                if not isinstance(attr, FrozenSDPAttribute):\n                    raise TypeError(\"Items in FrozenSDPMediaStream attribute list must be FrozenSDPAttribute instances\")\n            if len(bandwidth_info) > PJMEDIA_MAX_SDP_BANDW:\n                raise SIPCoreError(\"Too many bandwidth info attributes\")\n            for info in bandwidth_info:\n                if not isinstance(info, FrozenSDPBandwidthInfo):\n                    raise TypeError(\"Items in FrozenSDPMediaStream bandwidth info list must be FrozenSDPBandwidthInfo instances\")\n            self.media = media\n            _str_to_pj_str(media, &self._sdp_media.desc.media)\n            self.port = port\n            self._sdp_media.desc.port = port\n            self.transport = transport\n            _str_to_pj_str(transport, &self._sdp_media.desc.transport)\n            self.port_count = port_count\n            self._sdp_media.desc.port_count = port_count\n            self.formats = formats\n            self._sdp_media.desc.fmt_count = len(self.formats)\n            for index, format in enumerate(self.formats):\n                _str_to_pj_str(format, &self._sdp_media.desc.fmt[index])\n            self.connection = connection\n            if connection is None:\n                self._sdp_media.conn = NULL\n            else:\n                self._sdp_media.conn = connection.get_sdp_connection()\n            self.attributes = FrozenSDPAttributeList(attributes) if not isinstance(attributes, FrozenSDPAttributeList) else attributes\n            if self.media in (\"audio\", \"video\"):\n                rtp_mappings = self.rtp_mappings.copy()\n                rtpmap_lines = '\\n'.join([attr.value for attr in attributes if attr.name=='rtpmap']) # iterators are not supported -Dan\n                rtpmap_codecs = dict([(int(type), MediaCodec(name, rate)) for type, name, rate in self.rtpmap_re.findall(rtpmap_lines)])\n                rtp_mappings.update(rtpmap_codecs)\n                self.codec_list = frozenlist([rtp_mappings.get(int(format) if format.isdigit() else None, MediaCodec('Unknown', 0)) for format in self.formats])\n            else:\n                self.codec_list = frozenlist()\n            self.bandwidth_info = FrozenSDPBandwidthInfoList(bandwidth_info) if not isinstance(bandwidth_info, FrozenSDPBandwidthInfoList) else bandwidth_info\n            self.initialized = 1\n\n    @classmethod\n    def new(cls, BaseSDPMediaStream sdp_media):\n        if isinstance(sdp_media, FrozenSDPMediaStream):\n            return sdp_media\n        connection = FrozenSDPConnection.new(sdp_media.connection) if (sdp_media.connection is not None) else None\n        attributes = frozenlist([FrozenSDPAttribute.new(attr) for attr in sdp_media.attributes])\n        bandwidth_info = frozenlist([FrozenSDPBandwidthInfo.new(info) for info in sdp_media.bandwidth_info])\n        return cls(sdp_media.media, sdp_media.port, sdp_media.transport, sdp_media.port_count,\n                   frozenlist(sdp_media.formats), connection, attributes, bandwidth_info)\n\n    def __hash__(self):\n        return hash((self.media, self.port, self.transport, self.port_count, self.formats, self.connection, self.attributes, self.bandwidth_info))\n\n    def __richcmp__(self, other, op):\n        return BaseSDPMediaStream_richcmp(self, other, op)\n\n\ncdef object BaseSDPConnection_richcmp(object self, object other, int op) with gil:\n    cdef int eq = 1\n    if op not in [2,3]:\n        return NotImplemented\n    if not isinstance(other, BaseSDPConnection):\n        return NotImplemented\n    for attr in (\"net_type\", \"address_type\", \"address\"):\n        if getattr(self, attr) != getattr(other, attr):\n            eq = 0\n            break\n    if op == 2:\n        return bool(eq)\n    else:\n        return not eq\n\ncdef class BaseSDPConnection:\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"BaseSDPConnection cannot be instantiated directly\")\n\n    def __repr__(self):\n        return \"%s(%r, %r, %r)\" % (self.__class__.__name__, self.address, self.net_type, self.address_type)\n\n    def __richcmp__(self, other, op):\n        return BaseSDPConnection_richcmp(self, other, op)\n\n    cdef pjmedia_sdp_conn* get_sdp_connection(self):\n        return &self._sdp_connection\n\ncdef class SDPConnection(BaseSDPConnection):\n    def __init__(self, str address not None, str net_type not None=\"IN\", str address_type not None=\"IP4\"):\n        self.address = address\n        self.net_type = net_type\n        self.address_type = address_type\n\n    @classmethod\n    def new(cls, BaseSDPConnection sdp_connection):\n        return cls(sdp_connection.address, sdp_connection.net_type, sdp_connection.address_type)\n\n    property address:\n\n        def __get__(self):\n            return self._address\n\n        def __set__(self, str address not None):\n            _str_to_pj_str(address, &self._sdp_connection.addr)\n            self._address = address\n\n    property net_type:\n\n        def __get__(self):\n            return self._net_type\n\n        def __set__(self, str net_type not None):\n            _str_to_pj_str(net_type, &self._sdp_connection.net_type)\n            self._net_type = net_type\n\n    property address_type:\n\n        def __get__(self):\n            return self._address_type\n\n        def __set__(self, str address_type not None):\n            _str_to_pj_str(address_type, &self._sdp_connection.addr_type)\n            self._address_type = address_type\n\ncdef class FrozenSDPConnection(BaseSDPConnection):\n    def __init__(self, str address not None, str net_type not None=\"IN\", str address_type not None=\"IP4\"):\n        if not self.initialized:\n            _str_to_pj_str(address, &self._sdp_connection.addr)\n            _str_to_pj_str(net_type, &self._sdp_connection.net_type)\n            _str_to_pj_str(address_type, &self._sdp_connection.addr_type)\n            self.address = address\n            self.net_type = net_type\n            self.address_type = address_type\n            self.initialized = 1\n\n    @classmethod\n    def new(cls, BaseSDPConnection sdp_connection):\n        if isinstance(sdp_connection, FrozenSDPConnection):\n            return sdp_connection\n        return cls(sdp_connection.address, sdp_connection.net_type, sdp_connection.address_type)\n\n    def __hash__(self):\n        return hash((self.address, self.net_type, self.address_type))\n\n    def __richcmp__(self, other, op):\n        return BaseSDPConnection_richcmp(self, other, op)\n\n\ncdef class SDPAttributeList(list):\n    def __contains__(self, item):\n        if isinstance(item, BaseSDPAttribute):\n            return list.__contains__(self, item)\n        else:\n            return item in [attr.name for attr in self]\n\n    def getall(self, name):\n        return [attr.value for attr in self if attr.name == name]\n\n    def getfirst(self, name, default=None):\n        for attr in self:\n            if attr.name == name:\n                return attr.value\n        return default\n\ncdef class FrozenSDPAttributeList(frozenlist):\n    def __contains__(self, item):\n        if isinstance(item, BaseSDPAttribute):\n            return list.__contains__(self, item)\n        else:\n            return item in [attr.name for attr in self]\n\n    def getall(self, name):\n        return [attr.value for attr in self if attr.name == name]\n\n    def getfirst(self, name, default=None):\n        for attr in self:\n            if attr.name == name:\n                return attr.value\n        return default\n\n\ncdef object BaseSDPAttribute_richcmp(object self, object other, int op) with gil:\n    cdef int eq = 1\n    if op not in [2,3]:\n        return NotImplemented\n    if not isinstance(other, BaseSDPAttribute):\n        return NotImplemented\n    for attr in (\"name\", \"value\"):\n        if getattr(self, attr) != getattr(other, attr):\n            eq = 0\n            break\n    if op == 2:\n        return bool(eq)\n    else:\n        return not eq\n\ncdef class BaseSDPAttribute:\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"BaseSDPAttribute cannot be instantiated directly\")\n\n    def __repr__(self):\n        return \"%s(%r, %r)\" % (self.__class__.__name__, self.name, self.value)\n\n    def __richcmp__(self, other, op):\n        return BaseSDPAttribute_richcmp(self, other, op)\n\n    cdef pjmedia_sdp_attr* get_sdp_attribute(self):\n        return &self._sdp_attribute\n\ncdef class SDPAttribute(BaseSDPAttribute):\n    def __init__(self, str name not None, str value not None):\n        self.name = name\n        self.value = value\n\n    @classmethod\n    def new(cls, BaseSDPAttribute sdp_attribute):\n        return cls(sdp_attribute.name, sdp_attribute.value)\n\n    property name:\n\n        def __get__(self):\n            return self._name\n\n        def __set__(self, str name not None):\n            _str_to_pj_str(name, &self._sdp_attribute.name)\n            self._name = name\n\n    property value:\n\n        def __get__(self):\n            return self._value\n\n        def __set__(self, str value not None):\n            _str_to_pj_str(value, &self._sdp_attribute.value)\n            self._value = value\n\ncdef class FrozenSDPAttribute(BaseSDPAttribute):\n    def __init__(self, str name not None, str value not None):\n        if not self.initialized:\n            _str_to_pj_str(name, &self._sdp_attribute.name)\n            _str_to_pj_str(value, &self._sdp_attribute.value)\n            self.name = name\n            self.value = value\n            self.initialized = 1\n\n    @classmethod\n    def new(cls, BaseSDPAttribute sdp_attribute):\n        if isinstance(sdp_attribute, FrozenSDPAttribute):\n            return sdp_attribute\n        return cls(sdp_attribute.name, sdp_attribute.value)\n\n    def __hash__(self):\n        return hash((self.name, self.value))\n\n    def __richcmp__(self, other, op):\n        return BaseSDPAttribute_richcmp(self, other, op)\n\n\ncdef class SDPBandwidthInfoList(list):\n    def __contains__(self, item):\n        if isinstance(item, BaseSDPBandwidthInfo):\n            return list.__contains__(self, item)\n        else:\n            return item in [attr.name for attr in self]\n\ncdef class FrozenSDPBandwidthInfoList(frozenlist):\n    def __contains__(self, item):\n        if isinstance(item, BaseSDPBandwidthInfo):\n            return list.__contains__(self, item)\n        else:\n            return item in [info.modifier for info in self]\n\n\ncdef object BaseSDPBandwidthInfo_richcmp(object self, object other, int op) with gil:\n    cdef int eq = 1\n    if op not in [2,3]:\n        return NotImplemented\n    if not isinstance(other, BaseSDPBandwidthInfo):\n        return NotImplemented\n    for attr in (\"modifier\", \"value\"):\n        if getattr(self, attr) != getattr(other, attr):\n            eq = 0\n            break\n    if op == 2:\n        return bool(eq)\n    else:\n        return not eq\n\ncdef class BaseSDPBandwidthInfo:\n    def __init__(self, *args, **kwargs):\n        raise TypeError(\"BaseSDPBandwidthInfo cannot be instantiated directly\")\n\n    def __repr__(self):\n        return \"%s(%r, %r)\" % (self.__class__.__name__, self.modifier, self.value)\n\n    def __richcmp__(self, other, op):\n        return BaseSDPBandwidthInfo_richcmp(self, other, op)\n\n    cdef pjmedia_sdp_bandw* get_sdp_bandwidth_info(self):\n        return &self._sdp_bandwidth_info\n\ncdef class SDPBandwidthInfo(BaseSDPBandwidthInfo):\n    def __init__(self, str modifier not None, object value not None):\n        self.modifier = modifier\n        self.value = value\n\n    @classmethod\n    def new(cls, BaseSDPBandwidthInfo sdp_bandwidth_info):\n        return cls(sdp_bandwidth_info.modifier, sdp_bandwidth_info.value)\n\n    property modifier:\n\n        def __get__(self):\n            return self._modifier\n\n        def __set__(self, str modifier not None):\n            _str_to_pj_str(modifier, &self._sdp_bandwidth_info.modifier)\n            self._modifier = modifier\n\n    property value:\n\n        def __get__(self):\n            return self._value\n\n        def __set__(self, object value not None):\n            self._value = value\n            self._sdp_bandwidth_info.value = self._value\n\ncdef class FrozenSDPBandwidthInfo(BaseSDPBandwidthInfo):\n    def __init__(self, str modifier not None, object value not None):\n        if not self.initialized:\n            _str_to_pj_str(modifier, &self._sdp_bandwidth_info.modifier)\n            self.modifier = modifier\n            self._sdp_bandwidth_info.value = value\n            self.value = value\n            self.initialized = 1\n\n    @classmethod\n    def new(cls, BaseSDPBandwidthInfo sdp_bandwidth_info):\n        if isinstance(sdp_bandwidth_info, FrozenSDPBandwidthInfo):\n            return sdp_bandwidth_info\n        return cls(sdp_bandwidth_info.modifier, sdp_bandwidth_info.value)\n\n    def __hash__(self):\n        return hash((self.modifier, self.value))\n\n    def __richcmp__(self, other, op):\n        return BaseSDPBandwidthInfo_richcmp(self, other, op)\n\n\n# Factory functions\n#\n\ncdef SDPSession SDPSession_create(pjmedia_sdp_session_ptr_const pj_session):\n    cdef SDPConnection connection = None\n    cdef int i\n    if pj_session.conn != NULL:\n        connection = SDPConnection_create(pj_session.conn)\n    return SDPSession(_pj_str_to_str(pj_session.origin.addr),\n                       pj_session.origin.id,\n                       pj_session.origin.version,\n                       _pj_str_to_str(pj_session.origin.user),\n                       _pj_str_to_str(pj_session.origin.net_type),\n                       _pj_str_to_str(pj_session.origin.addr_type),\n                       _pj_str_to_str(pj_session.name),\n                       connection,\n                       pj_session.time.start,\n                       pj_session.time.stop,\n                       [SDPAttribute_create(pj_session.attr[i]) for i in range(pj_session.attr_count)],\n                       [SDPBandwidthInfo_create(pj_session.bandw[i]) for i in range(pj_session.bandw_count)],\n                       [SDPMediaStream_create(pj_session.media[i]) if pj_session.media[i] != NULL else None for i in range(pj_session.media_count)])\n\ncdef FrozenSDPSession FrozenSDPSession_create(pjmedia_sdp_session_ptr_const pj_session):\n    cdef FrozenSDPConnection connection = None\n    cdef int i\n    if pj_session.conn != NULL:\n        connection = FrozenSDPConnection_create(pj_session.conn)\n    return FrozenSDPSession(_pj_str_to_str(pj_session.origin.addr),\n                            pj_session.origin.id,\n                            pj_session.origin.version,\n                            _pj_str_to_str(pj_session.origin.user),\n                            _pj_str_to_str(pj_session.origin.net_type),\n                            _pj_str_to_str(pj_session.origin.addr_type),\n                            _pj_str_to_str(pj_session.name),\n                            connection,\n                            pj_session.time.start,\n                            pj_session.time.stop,\n                            frozenlist([FrozenSDPAttribute_create(pj_session.attr[i]) for i in range(pj_session.attr_count)]),\n                            frozenlist([FrozenSDPBandwidthInfo_create(pj_session.bandw[i]) for i in range(pj_session.bandw_count)]),\n                            frozenlist([FrozenSDPMediaStream_create(pj_session.media[i]) if pj_session.media[i] != NULL else None for i in range(pj_session.media_count)]))\n\ncdef SDPMediaStream SDPMediaStream_create(pjmedia_sdp_media *pj_media):\n    cdef SDPConnection connection = None\n    cdef int i\n    if pj_media.conn != NULL:\n        connection = SDPConnection_create(pj_media.conn)\n    return SDPMediaStream(_pj_str_to_str(pj_media.desc.media),\n                          pj_media.desc.port,\n                          _pj_str_to_str(pj_media.desc.transport),\n                          pj_media.desc.port_count,\n                          [_pj_str_to_str(pj_media.desc.fmt[i]) for i in range(pj_media.desc.fmt_count)],\n                          connection,\n                          [SDPAttribute_create(pj_media.attr[i]) for i in range(pj_media.attr_count)],\n                          [SDPBandwidthInfo_create(pj_media.bandw[i]) for i in range(pj_media.bandw_count)])\n\ncdef FrozenSDPMediaStream FrozenSDPMediaStream_create(pjmedia_sdp_media *pj_media):\n    cdef FrozenSDPConnection connection = None\n    cdef int i\n    if pj_media.conn != NULL:\n        connection = FrozenSDPConnection_create(pj_media.conn)\n    return FrozenSDPMediaStream(_pj_str_to_str(pj_media.desc.media),\n                          pj_media.desc.port,\n                          _pj_str_to_str(pj_media.desc.transport),\n                          pj_media.desc.port_count,\n                          frozenlist([_pj_str_to_str(pj_media.desc.fmt[i]) for i in range(pj_media.desc.fmt_count)]),\n                          connection,\n                          frozenlist([FrozenSDPAttribute_create(pj_media.attr[i]) for i in range(pj_media.attr_count)]),\n                          frozenlist([FrozenSDPBandwidthInfo_create(pj_media.bandw[i]) for i in range(pj_media.bandw_count)]))\n\ncdef SDPConnection SDPConnection_create(pjmedia_sdp_conn *pj_conn):\n    return SDPConnection(_pj_str_to_str(pj_conn.addr), _pj_str_to_str(pj_conn.net_type),\n                          _pj_str_to_str(pj_conn.addr_type))\n\ncdef FrozenSDPConnection FrozenSDPConnection_create(pjmedia_sdp_conn *pj_conn):\n    return FrozenSDPConnection(_pj_str_to_str(pj_conn.addr), _pj_str_to_str(pj_conn.net_type),\n                               _pj_str_to_str(pj_conn.addr_type))\n\ncdef SDPAttribute SDPAttribute_create(pjmedia_sdp_attr *pj_attr):\n    return SDPAttribute(_pj_str_to_str(pj_attr.name), _pj_str_to_str(pj_attr.value))\n\ncdef FrozenSDPAttribute FrozenSDPAttribute_create(pjmedia_sdp_attr *pj_attr):\n    return FrozenSDPAttribute(_pj_str_to_str(pj_attr.name), _pj_str_to_str(pj_attr.value))\n\ncdef SDPBandwidthInfo SDPBandwidthInfo_create(pjmedia_sdp_bandw *pj_bandw):\n    return SDPBandwidthInfo(_pj_str_to_str(pj_bandw.modifier), int(pj_bandw.value))\n\ncdef FrozenSDPBandwidthInfo FrozenSDPBandwidthInfo_create(pjmedia_sdp_bandw *pj_bandw):\n    return FrozenSDPBandwidthInfo(_pj_str_to_str(pj_bandw.modifier), int(pj_bandw.value))\n\n\n# SDP negotiator\n#\n\ncdef class SDPNegotiator:\n    def __cinit__(self, *args, **kwargs):\n        cdef pj_pool_t *pool\n        cdef bytes pool_name\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n        pool_name = b\"SDPNegotiator_%d\" % id(self)\n\n        pool = ua.create_memory_pool(pool_name, 4096, 4096)\n        self._pool = pool\n        self._neg = NULL\n\n    def __dealloc__(self):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n        except:\n            return\n\n        ua.release_memory_pool(self._pool)\n        self._pool = NULL\n\n    @classmethod\n    def create_with_local_offer(cls, BaseSDPSession sdp_session):\n        cdef int status\n        cdef pjmedia_sdp_neg *neg\n        cdef pj_pool_t *pool\n        cdef SDPNegotiator obj\n\n        obj = cls()\n        pool = obj._pool\n\n        status = pjmedia_sdp_neg_create_w_local_offer(pool, sdp_session.get_sdp_session(), &neg)\n        if status != 0:\n            raise PJSIPError(\"failed to create SDPNegotiator with local offer\", status)\n\n        obj._neg = neg\n        return obj\n\n    @classmethod\n    def create_with_remote_offer(cls, BaseSDPSession sdp_session):\n        cdef int status\n        cdef pjmedia_sdp_neg *neg\n        cdef pj_pool_t *pool\n        cdef SDPNegotiator obj\n\n        obj = cls()\n        pool = obj._pool\n\n        status = pjmedia_sdp_neg_create_w_remote_offer(pool, NULL, sdp_session.get_sdp_session(), &neg)\n        if status != 0:\n            raise PJSIPError(\"failed to create SDPNegotiator with remote offer\", status)\n\n        obj._neg = neg\n        return obj\n\n    def __repr__(self):\n        return \"%s, state=%s\" % (self.__class__.__name__, self.state)\n\n    property state:\n\n        def __get__(self):\n            if self._neg == NULL:\n                return None\n            return PyString_FromString(pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_get_state(self._neg)))\n\n    property active_local:\n\n        def __get__(self):\n            cdef int status\n            cdef pjmedia_sdp_session_ptr_const sdp\n            if self._neg == NULL:\n                return None\n            status = pjmedia_sdp_neg_get_active_local(self._neg, &sdp)\n            if status != 0:\n                return None\n            return FrozenSDPSession_create(sdp)\n\n    property active_remote:\n\n        def __get__(self):\n            cdef int status\n            cdef pjmedia_sdp_session_ptr_const sdp\n            if self._neg == NULL:\n                return None\n            status = pjmedia_sdp_neg_get_active_remote(self._neg, &sdp)\n            if status != 0:\n                return None\n            return FrozenSDPSession_create(sdp)\n\n    property current_local:\n\n        def __get__(self):\n            cdef int status\n            cdef pjmedia_sdp_session_ptr_const sdp\n            if self._neg == NULL:\n                return None\n            status = pjmedia_sdp_neg_get_neg_local(self._neg, &sdp)\n            if status != 0:\n                return None\n            return FrozenSDPSession_create(sdp)\n\n    property current_remote:\n\n        def __get__(self):\n            cdef int status\n            cdef pjmedia_sdp_session_ptr_const sdp\n            if self._neg == NULL:\n                return None\n            status = pjmedia_sdp_neg_get_neg_remote(self._neg, &sdp)\n            if status != 0:\n                return None\n            return FrozenSDPSession_create(sdp)\n\n    def _check_self(self):\n        if self._neg == NULL:\n            raise RuntimeError('SDPNegotiator was not properly initialized')\n\n    def set_local_answer(self, BaseSDPSession sdp_session):\n        self._check_self()\n        cdef int status\n        cdef pj_pool_t *pool = self._pool\n\n        status = pjmedia_sdp_neg_set_local_answer(pool, self._neg, sdp_session.get_sdp_session())\n        if status != 0:\n            raise PJSIPError(\"failed to set local answer\", status)\n\n    def set_local_offer(self, BaseSDPSession sdp_session):\n        # PJSIP has an asymmetric API here. This function will modify the local session with the new SDP and treat it as a local offer.\n        self._check_self()\n        cdef int status\n        cdef pj_pool_t *pool = self._pool\n\n        status = pjmedia_sdp_neg_modify_local_offer(pool, self._neg, sdp_session.get_sdp_session())\n        if status != 0:\n            raise PJSIPError(\"failed to set local offer\", status)\n\n    def set_remote_answer(self, BaseSDPSession sdp_session):\n        self._check_self()\n        cdef int status\n        cdef pj_pool_t *pool = self._pool\n\n        status = pjmedia_sdp_neg_set_remote_answer(pool, self._neg, sdp_session.get_sdp_session())\n        if status != 0:\n            raise PJSIPError(\"failed to set remote answer\", status)\n\n    def set_remote_offer(self, BaseSDPSession sdp_session):\n        self._check_self()\n        cdef int status\n        cdef pj_pool_t *pool = self._pool\n\n        status = pjmedia_sdp_neg_set_remote_offer(pool, self._neg, sdp_session.get_sdp_session())\n        if status != 0:\n            raise PJSIPError(\"failed to set remote offer\", status)\n\n    def cancel_offer(self):\n        self._check_self()\n        cdef int status\n\n        status = pjmedia_sdp_neg_cancel_offer(self._neg)\n        if status != 0:\n            raise PJSIPError(\"failed to cancel offer\", status)\n\n    def negotiate(self):\n        self._check_self()\n        cdef int status\n        cdef pj_pool_t *pool = self._pool\n\n        status = pjmedia_sdp_neg_negotiate(pool, self._neg, 0)\n        if status != 0:\n            raise PJSIPError(\"SDP negotiation failed\", status)\n\n"
  },
  {
    "path": "sipsimple/core/_core.sound.pxi",
    "content": "\nimport sys\n\n\ncdef class AudioMixer:\n\n    def __cinit__(self, *args, **kwargs):\n        cdef int status\n\n        self._connected_slots = list()\n        self._input_volume = 100\n        self._output_volume = 100\n\n        status = pj_mutex_create_recursive(_get_ua()._pjsip_endpoint._pool, \"audio_mixer_lock\", &self._lock)\n        if status != 0:\n            raise PJSIPError(\"failed to create lock\", status)\n\n    def __init__(self, unicode input_device, unicode output_device, int sample_rate, int ec_tail_length, int slot_count=254):\n        global _dealloc_handler_queue\n        cdef int status\n        cdef pj_pool_t *conf_pool\n        cdef pj_pool_t *snd_pool\n        cdef pjmedia_conf **conf_bridge_address\n        cdef pjmedia_port **null_port_address\n        cdef bytes conf_pool_name, snd_pool_name\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n        conf_bridge_address = &self._obj\n        null_port_address = &self._null_port\n\n        if self._obj != NULL:\n            raise SIPCoreError(\"AudioMixer.__init__() was already called\")\n        if ec_tail_length < 0:\n            raise ValueError(\"ec_tail_length argument cannot be negative\")\n        if sample_rate <= 0:\n            raise ValueError(\"sample_rate argument should be a non-negative integer\")\n        if sample_rate % 50:\n            raise ValueError(\"sample_rate argument should be dividable by 50\")\n        self.sample_rate = sample_rate\n        self.slot_count = slot_count\n\n        conf_pool_name = b\"AudioMixer_%d\" % id(self)\n        conf_pool = ua.create_memory_pool(conf_pool_name, 4096, 4096)\n        self._conf_pool = conf_pool\n        snd_pool_name = b\"AudioMixer_snd_%d\" % id(self)\n        snd_pool = ua.create_memory_pool(snd_pool_name, 4096, 4096)\n        self._snd_pool = snd_pool\n        with nogil:\n            status = pjmedia_conf_create(conf_pool, slot_count+1, sample_rate, 1,\n                                         sample_rate / 50, 16, PJMEDIA_CONF_NO_DEVICE, conf_bridge_address)\n        if status != 0:\n            raise PJSIPError(\"Could not create audio mixer\", status)\n        with nogil:\n            status = pjmedia_null_port_create(conf_pool, sample_rate, 1,\n                                              sample_rate / 50, 16, null_port_address)\n        if status != 0:\n            raise PJSIPError(\"Could not create null audio port\", status)\n        self._start_sound_device(ua, input_device, output_device, ec_tail_length)\n        if not (input_device is None and output_device is None):\n            self._stop_sound_device(ua)\n        _add_handler(_AudioMixer_dealloc_handler, self, &_dealloc_handler_queue)\n\n    # properties\n\n    property input_volume:\n\n        def __get__(self):\n            return self._input_volume\n\n        def __set__(self, int value):\n            cdef int status\n            cdef int volume\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_conf *conf_bridge\n            cdef PJSIPUA ua\n\n            try:\n                ua = _get_ua()\n            except SIPCoreError:\n                pass\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                conf_bridge = self._obj\n\n                if value < 0:\n                    raise ValueError(\"input_volume attribute cannot be negative\")\n                if ua is not None:\n                    volume = int(value * 1.28 - 128)\n                    with nogil:\n                        status = pjmedia_conf_adjust_rx_level(conf_bridge, 0, volume)\n                    if status != 0:\n                        raise PJSIPError(\"Could not set input volume of sound device\", status)\n                if value > 0 and self._muted:\n                    self._muted = False\n                self._input_volume = value\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property output_volume:\n\n        def __get__(self):\n            return self._output_volume\n\n        def __set__(self, int value):\n            cdef int status\n            cdef int volume\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_conf *conf_bridge\n            cdef PJSIPUA ua\n\n            try:\n                ua = _get_ua()\n            except SIPCoreError:\n                pass\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                conf_bridge = self._obj\n\n                if value < 0:\n                    raise ValueError(\"output_volume attribute cannot be negative\")\n                if ua is not None:\n                    volume = int(value * 1.28 - 128)\n                    with nogil:\n                        status = pjmedia_conf_adjust_tx_level(conf_bridge, 0, volume)\n                    if status != 0:\n                        raise PJSIPError(\"Could not set output volume of sound device\", status)\n                self._output_volume = value\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property muted:\n\n        def __get__(self):\n            return self._muted\n\n        def __set__(self, bint muted):\n            cdef int status\n            cdef int volume\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_conf *conf_bridge\n            cdef PJSIPUA ua\n\n            try:\n                ua = _get_ua()\n            except SIPCoreError:\n                pass\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                conf_bridge = self._obj\n\n                if muted == self._muted:\n                    return\n                if ua is not None:\n                    if muted:\n                        volume = -128\n                    else:\n                        volume = int(self._input_volume * 1.28 - 128)\n                    with nogil:\n                        status = pjmedia_conf_adjust_rx_level(conf_bridge, 0, volume)\n                    if status != 0:\n                        raise PJSIPError(\"Could not set input volume of sound device\", status)\n                self._muted = muted\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property connected_slots:\n\n        def __get__(self):\n            return sorted(self._connected_slots)\n\n    # public methods\n\n    def set_sound_devices(self, unicode input_device, unicode output_device, int ec_tail_length):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if ec_tail_length < 0:\n                raise ValueError(\"ec_tail_length argument cannot be negative\")\n            self._stop_sound_device(ua)\n            self._start_sound_device(ua, input_device, output_device, ec_tail_length)\n            if self.used_slot_count == 0 and not (input_device is None and output_device is None):\n                self._stop_sound_device(ua)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def connect_slots(self, int src_slot, int dst_slot):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_conf *conf_bridge\n        cdef tuple connection\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            conf_bridge = self._obj\n\n            if src_slot < 0:\n                raise ValueError(\"src_slot argument cannot be negative\")\n            if dst_slot < 0:\n                raise ValueError(\"dst_slot argument cannot be negative\")\n            connection = (src_slot, dst_slot)\n            if connection in self._connected_slots:\n                return\n            with nogil:\n                status = pjmedia_conf_connect_port(conf_bridge, src_slot, dst_slot, 0)\n            if status != 0:\n                raise PJSIPError(\"Could not connect slots on audio mixer\", status)\n            self._connected_slots.append(connection)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def disconnect_slots(self, int src_slot, int dst_slot):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_conf *conf_bridge\n        cdef tuple connection\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            conf_bridge = self._obj\n\n            if src_slot < 0:\n                raise ValueError(\"src_slot argument cannot be negative\")\n            if dst_slot < 0:\n                raise ValueError(\"dst_slot argument cannot be negative\")\n            connection = (src_slot, dst_slot)\n            if connection not in self._connected_slots:\n                return\n            with nogil:\n                status = pjmedia_conf_disconnect_port(conf_bridge, src_slot, dst_slot)\n            if status != 0:\n                raise PJSIPError(\"Could not disconnect slots on audio mixer\", status)\n            self._connected_slots.remove(connection)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def reset_ec(self):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._snd == NULL:\n                return\n            with nogil:\n                pjmedia_snd_port_reset_ec_state(self._snd)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    # private methods\n\n    cdef void _start_sound_device(self, PJSIPUA ua, unicode input_device, unicode output_device, int ec_tail_length):\n        cdef int idx\n        cdef int input_device_i = -99\n        cdef int output_device_i = -99\n        cdef int sample_rate = self.sample_rate\n        cdef int status\n        cdef pj_pool_t *conf_pool\n        cdef pj_pool_t *snd_pool\n        cdef pjmedia_conf *conf_bridge\n        cdef pjmedia_master_port **master_port_address\n        cdef pjmedia_port *null_port\n        cdef pjmedia_aud_dev_info dev_info\n        cdef pjmedia_snd_port **snd_port_address\n        cdef pjmedia_aud_param aud_param\n        cdef pjmedia_snd_port_param port_param\n\n        conf_bridge = self._obj\n        conf_pool = self._conf_pool\n        snd_pool = self._snd_pool\n        master_port_address = &self._master_port\n        null_port = self._null_port\n        sample_rate = self.sample_rate\n        snd_port_address = &self._snd\n\n        with nogil:\n            status = pj_rwmutex_lock_read(ua.audio_change_rwlock)\n        if status != 0:\n            raise PJSIPError('Audio change lock could not be acquired for read', status)\n\n        try:\n            dev_count = pjmedia_aud_dev_count()\n            if dev_count == 0:\n                input_device = None\n                output_device = None\n            if input_device == u\"system_default\":\n                input_device_i = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV\n            if output_device == u\"system_default\":\n                output_device_i = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV\n            if ((input_device_i == -99 and input_device is not None) or\n                (output_device_i == -99 and output_device is not None)):\n                for i in range(dev_count):\n                    with nogil:\n                        status = pjmedia_aud_dev_get_info(i, &dev_info)\n                    if status != 0:\n                        raise PJSIPError(\"Could not get audio device info\", status)\n                    if (input_device is not None and input_device_i == -99 and\n                        dev_info.input_count > 0 and decode_device_name(dev_info.name) == input_device):\n                        input_device_i = i\n                    if (output_device is not None and output_device_i == -99 and\n                        dev_info.output_count > 0 and decode_device_name(dev_info.name) == output_device):\n                        output_device_i = i\n                if input_device_i == -99 and input_device is not None:\n                    input_device_i = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV\n                if output_device_i == -99 and output_device is not None:\n                    output_device_i = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV\n            if input_device is None and output_device is None:\n                with nogil:\n                    status = pjmedia_master_port_create(conf_pool, null_port, pjmedia_conf_get_master_port(conf_bridge), 0, master_port_address)\n                if status != 0:\n                    raise PJSIPError(\"Could not create master port for dummy sound device\", status)\n                with nogil:\n                    status = pjmedia_master_port_start(master_port_address[0])\n                if status != 0:\n                    raise PJSIPError(\"Could not start master port for dummy sound device\", status)\n            else:\n                pjmedia_snd_port_param_default(&port_param)\n                idx = input_device_i if input_device is not None else output_device_i\n                with nogil:\n                    status = pjmedia_aud_dev_default_param(idx, &port_param.base)\n                if status != 0:\n                    raise PJSIPError(\"Could not get default parameters for audio device\", status)\n                if input_device is None:\n                    port_param.base.dir = PJMEDIA_DIR_PLAYBACK\n                    port_param.base.play_id = output_device_i\n                elif output_device is None:\n                    port_param.base.dir = PJMEDIA_DIR_CAPTURE\n                    port_param.base.rec_id = input_device_i\n                else:\n                    port_param.base.dir = PJMEDIA_DIR_CAPTURE_PLAYBACK\n                    port_param.base.play_id = output_device_i\n                    port_param.base.rec_id = input_device_i\n                port_param.base.channel_count = 1\n                port_param.base.clock_rate = sample_rate\n                port_param.base.samples_per_frame = sample_rate / 50\n                port_param.base.bits_per_sample = 16\n                port_param.base.flags |= (PJMEDIA_AUD_DEV_CAP_EC | PJMEDIA_AUD_DEV_CAP_EC_TAIL)\n                port_param.base.ec_enabled = 1\n                port_param.base.ec_tail_ms = ec_tail_length\n                with nogil:\n                    status = pjmedia_snd_port_create2(snd_pool, &port_param, snd_port_address)\n                if status == PJMEDIA_ENOSNDPLAY:\n                    ua.reset_memory_pool(snd_pool)\n                    self._start_sound_device(ua, input_device, None, ec_tail_length)\n                    return\n                elif status == PJMEDIA_ENOSNDREC:\n                    ua.reset_memory_pool(snd_pool)\n                    self._start_sound_device(ua, None, output_device, ec_tail_length)\n                    return\n                elif status != 0:\n                    raise PJSIPError(\"Could not create sound device\", status)\n                with nogil:\n                    status = pjmedia_snd_port_connect(snd_port_address[0], pjmedia_conf_get_master_port(conf_bridge))\n                if status != 0:\n                    self._stop_sound_device(ua)\n                    raise PJSIPError(\"Could not connect sound device\", status)\n                if input_device_i == PJMEDIA_AUD_DEFAULT_CAPTURE_DEV or output_device_i == PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV:\n                    with nogil:\n                        status = pjmedia_aud_stream_get_param(pjmedia_snd_port_get_snd_stream(snd_port_address[0]), &aud_param)\n                    if status != 0:\n                        self._stop_sound_device(ua)\n                        raise PJSIPError(\"Could not get sounds device info\", status)\n                    if input_device_i == PJMEDIA_AUD_DEFAULT_CAPTURE_DEV:\n                        with nogil:\n                            status = pjmedia_aud_dev_get_info(aud_param.rec_id, &dev_info)\n                        if status != 0:\n                            raise PJSIPError(\"Could not get audio device info\", status)\n                        self.real_input_device = decode_device_name(dev_info.name)\n                    if output_device_i == PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV:\n                        with nogil:\n                            status = pjmedia_aud_dev_get_info(aud_param.play_id, &dev_info)\n                        if status != 0:\n                            raise PJSIPError(\"Could not get audio device info\", status)\n                        self.real_output_device = decode_device_name(dev_info.name)\n            if input_device_i != PJMEDIA_AUD_DEFAULT_CAPTURE_DEV:\n                self.real_input_device = input_device\n            if output_device_i != PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV:\n                self.real_output_device = output_device\n            self.input_device = input_device\n            self.output_device = output_device\n            self.ec_tail_length = ec_tail_length\n        finally:\n            with nogil:\n                pj_rwmutex_unlock_read(ua.audio_change_rwlock)\n\n    cdef void _stop_sound_device(self, PJSIPUA ua):\n        cdef pjmedia_master_port *master_port\n        cdef pjmedia_snd_port *snd_port\n\n        master_port = self._master_port\n        snd_port = self._snd\n\n        if self._snd != NULL:\n            with nogil:\n                pjmedia_snd_port_destroy(snd_port)\n            self._snd = NULL\n        ua.reset_memory_pool(self._snd_pool)\n        if self._master_port != NULL:\n            with nogil:\n                pjmedia_master_port_destroy(master_port, 0)\n            self._master_port = NULL\n\n    cdef int _add_port(self, PJSIPUA ua, pj_pool_t *pool, pjmedia_port *port) except -1 with gil:\n        cdef int input_device_i\n        cdef int output_device_i\n        cdef unsigned int slot\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_conf* conf_bridge\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            conf_bridge = self._obj\n\n            with nogil:\n                status = pjmedia_conf_add_port(conf_bridge, pool, port, NULL, &slot)\n            if status != 0:\n                raise PJSIPError(\"Could not add audio object to audio mixer\", status)\n            self.used_slot_count += 1\n            if self.used_slot_count == 1 and not (self.input_device is None and self.output_device is None) and self._snd == NULL:\n                self._start_sound_device(ua, self.input_device, self.output_device, self.ec_tail_length)\n            return slot\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    cdef int _remove_port(self, PJSIPUA ua, unsigned int slot) except -1 with gil:\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_conf* conf_bridge\n        cdef tuple connection\n        cdef Timer timer\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            conf_bridge = self._obj\n\n            with nogil:\n                status = pjmedia_conf_remove_port(conf_bridge, slot)\n            if status != 0:\n                raise PJSIPError(\"Could not remove audio object from audio mixer\", status)\n            self._connected_slots = [connection for connection in self._connected_slots if slot not in connection]\n            self.used_slot_count -= 1\n            if self.used_slot_count == 0 and not (self.input_device is None and self.output_device is None):\n                timer = Timer()\n                timer.schedule(0, <timer_callback>self._cb_postpoll_stop_sound, self)\n            return 0\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    cdef int _cb_postpoll_stop_sound(self, timer) except -1:\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self.used_slot_count == 0:\n                self._stop_sound_device(ua)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def __dealloc__(self):\n        global _dealloc_handler_queue\n        cdef PJSIPUA ua\n        cdef pjmedia_conf *conf_bridge = self._obj\n        cdef pjmedia_port *null_port = self._null_port\n\n        _remove_handler(self, &_dealloc_handler_queue)\n\n        try:\n            ua = _get_ua()\n        except:\n            return\n\n        self._stop_sound_device(ua)\n        if self._null_port != NULL:\n            with nogil:\n                pjmedia_port_destroy(null_port)\n            self._null_port = NULL\n        if self._obj != NULL:\n            with nogil:\n                pjmedia_conf_destroy(conf_bridge)\n            self._obj = NULL\n        ua.release_memory_pool(self._conf_pool)\n        self._conf_pool = NULL\n        ua.release_memory_pool(self._snd_pool)\n        self._snd_pool = NULL\n        if self._lock != NULL:\n            pj_mutex_destroy(self._lock)\n\n\ncdef class ToneGenerator:\n    # properties\n\n    property volume:\n\n        def __get__(self):\n            return self._volume\n\n        def __set__(self, value):\n            cdef int slot\n            cdef int volume\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_conf *conf_bridge\n            cdef PJSIPUA ua\n\n            ua = self._get_ua(0)\n\n            if ua is not None:\n                with nogil:\n                    status = pj_mutex_lock(lock)\n                if status != 0:\n                    raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                conf_bridge = self.mixer._obj\n                slot = self._slot\n\n                if value < 0:\n                    raise ValueError(\"volume attribute cannot be negative\")\n                if ua is not None and self._slot != -1:\n                    volume = int(value * 1.28 - 128)\n                    with nogil:\n                        status = pjmedia_conf_adjust_rx_level(conf_bridge, slot, volume)\n                    if status != 0:\n                        raise PJSIPError(\"Could not set volume of tone generator\", status)\n                self._volume = value\n            finally:\n                if ua is not None:\n                    with nogil:\n                        pj_mutex_unlock(lock)\n\n    property slot:\n\n        def __get__(self):\n            self._get_ua(0)\n            if self._slot == -1:\n                return None\n            else:\n                return self._slot\n\n    property is_active:\n\n        def __get__(self):\n            self._get_ua(0)\n            return bool(self._slot != -1)\n\n    property is_busy:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_port *port\n            cdef PJSIPUA ua\n\n            ua = self._get_ua(0)\n            if ua is None:\n                return False\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                port = self._obj\n\n                if self._obj == NULL:\n                    return False\n                with nogil:\n                    status = pjmedia_tonegen_is_busy(port)\n                return bool(status)\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    # public methods\n\n    def __cinit__(self, *args, **kwargs):\n        cdef int status\n        cdef pj_pool_t *pool\n        cdef bytes pool_name\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        status = pj_mutex_create_recursive(ua._pjsip_endpoint._pool, \"tone_generator_lock\", &self._lock)\n        if status != 0:\n            raise PJSIPError(\"failed to create lock\", status)\n\n        pool_name = b\"ToneGenerator_%d\" % id(self)\n        pool = ua.create_memory_pool(pool_name, 4096, 4096)\n        self._pool = pool\n        self._slot = -1\n        self._timer = None\n        self._volume = 100\n\n    def __init__(self, AudioMixer mixer):\n        cdef int sample_rate\n        cdef int status\n        cdef pj_pool_t *pool\n        cdef pjmedia_port **port_address\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n        pool = self._pool\n        port_address = &self._obj\n        sample_rate = mixer.sample_rate\n\n        if self._obj != NULL:\n            raise SIPCoreError(\"ToneGenerator.__init__() was already called\")\n        if mixer is None:\n            raise ValueError(\"mixer argument may not be None\")\n        self.mixer = mixer\n        with nogil:\n            status = pjmedia_tonegen_create(pool, sample_rate, 1,\n                                            sample_rate / 50, 16, 0, port_address)\n        if status != 0:\n            raise PJSIPError(\"Could not create tone generator\", status)\n\n    def start(self):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = self._get_ua(1)\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._slot != -1:\n                return\n            self._slot = self.mixer._add_port(ua, self._pool, self._obj)\n            if self._volume != 100:\n                self.volume = self._volume\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def stop(self):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = self._get_ua(0)\n        if ua is None:\n            return\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._slot == -1:\n                return\n            self._stop(ua)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def __dealloc__(self):\n        cdef pjmedia_port *port = self._obj\n        cdef PJSIPUA ua\n\n        ua = self._get_ua(0)\n        if ua is None:\n            return\n\n        self._stop(ua)\n        if self._obj != NULL:\n            with nogil:\n                pjmedia_tonegen_stop(port)\n            self._obj = NULL\n        ua.release_memory_pool(self._pool)\n        self._pool = NULL\n        if self._lock != NULL:\n            pj_mutex_destroy(self._lock)\n\n    def play_tones(self, object tones):\n        cdef unsigned int count = 0\n        cdef int duration\n        cdef int freq1\n        cdef int freq2\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_port *port\n        cdef pjmedia_tone_desc tones_arr[PJMEDIA_TONEGEN_MAX_DIGITS]\n        cdef PJSIPUA ua\n\n        ua = self._get_ua(1)\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            port = self._obj\n\n            if self._slot == -1:\n                raise SIPCoreError(\"ToneGenerator has not yet been started\")\n            for freq1, freq2, duration in tones:\n                if freq1 == 0 and count > 0:\n                    tones_arr[count-1].off_msec += duration\n                else:\n                    if count >= PJMEDIA_TONEGEN_MAX_DIGITS:\n                        raise SIPCoreError(\"Too many tones\")\n                    tones_arr[count].freq1 = freq1\n                    tones_arr[count].freq2 = freq2\n                    tones_arr[count].on_msec = duration\n                    tones_arr[count].off_msec = 0\n                    tones_arr[count].volume = 0\n                    tones_arr[count].flags = 0\n                    count += 1\n            if count > 0:\n                with nogil:\n                    status = pjmedia_tonegen_play(port, count, tones_arr, 0)\n                if status != 0 and status != PJ_ETOOMANY:\n                    raise PJSIPError(\"Could not playback tones\", status)\n            if self._timer is None:\n                self._timer = Timer()\n                self._timer.schedule(0.250, <timer_callback>self._cb_check_done, self)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def play_dtmf(self, str digit):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_port *port\n        cdef pjmedia_tone_digit tone\n        cdef PJSIPUA ua\n\n        ua = self._get_ua(1)\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            port = self._obj\n\n            if self._slot == -1:\n                raise SIPCoreError(\"ToneGenerator has not yet been started\")\n            tone.digit = ord(digit)\n            tone.on_msec = 200\n            tone.off_msec = 50\n            tone.volume = 0\n            with nogil:\n                status = pjmedia_tonegen_play_digits(port, 1, &tone, 0)\n            if status != 0 and status != PJ_ETOOMANY:\n                raise PJSIPError(\"Could not playback DTMF tone\", status)\n            if self._timer is None:\n                self._timer = Timer()\n                self._timer.schedule(0.250, <timer_callback>self._cb_check_done, self)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    # private methods\n\n    cdef PJSIPUA _get_ua(self, int raise_exception):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n        except SIPCoreError:\n            self._obj = NULL\n            self._pool = NULL\n            self._slot = -1\n            self._timer = None\n            if raise_exception:\n                raise\n            else:\n                return None\n        else:\n            return ua\n\n    cdef int _stop(self, PJSIPUA ua) except -1:\n        if self._timer is not None:\n            self._timer.cancel()\n            self._timer = None\n        if self._slot != -1:\n            self.mixer._remove_port(ua, self._slot)\n            self._slot = -1\n        return 0\n\n    cdef int _cb_check_done(self, timer) except -1:\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_port *port\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            port = self._obj\n\n            with nogil:\n                status = pjmedia_tonegen_is_busy(port)\n            if status:\n                self._timer = Timer()\n                self._timer.schedule(0.250, <timer_callback>self._cb_check_done, self)\n            else:\n                self._timer = None\n                _add_event(\"ToneGeneratorDidFinishPlaying\", dict(obj=self))\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n\ncdef class RecordingWaveFile:\n    def __cinit__(self, *args, **kwargs):\n        cdef int status\n\n        status = pj_mutex_create_recursive(_get_ua()._pjsip_endpoint._pool, \"recording_wave_file_lock\", &self._lock)\n        if status != 0:\n            raise PJSIPError(\"failed to create lock\", status)\n\n        self._slot = -1\n\n    def __init__(self, AudioMixer mixer, filename):\n        if self.filename is not None:\n            raise SIPCoreError(\"RecordingWaveFile.__init__() was already called\")\n        if mixer is None:\n            raise ValueError(\"mixer argument may not be None\")\n        if filename is None:\n            raise ValueError(\"filename argument may not be None\")\n        if not isinstance(filename, basestring):\n            raise TypeError(\"file argument must be str or unicode\")\n        if isinstance(filename, unicode):\n            filename = filename.encode(sys.getfilesystemencoding())\n        self.mixer = mixer\n        self.filename = filename\n\n    cdef PJSIPUA _check_ua(self):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n            return ua\n        except:\n            self._pool = NULL\n            self._port = NULL\n            self._slot = -1\n            return None\n\n    property is_active:\n\n        def __get__(self):\n            self._check_ua()\n            return self._slot != -1\n\n    property slot:\n\n        def __get__(self):\n            self._check_ua()\n            if self._slot == -1:\n                return None\n            else:\n                return self._slot\n\n    def start(self):\n        cdef char *filename\n        cdef int sample_rate\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pj_pool_t *pool\n        cdef pjmedia_port **port_address\n        cdef bytes pool_name\n        cdef char* c_pool_name\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            filename = PyString_AsString(self.filename)\n            pool_name = b\"RecordingWaveFile_%d\" % id(self)\n            port_address = &self._port\n            sample_rate = self.mixer.sample_rate\n\n            if self._was_started:\n                raise SIPCoreError(\"This RecordingWaveFile was already started once\")\n            pool = ua.create_memory_pool(pool_name, 4096, 4096)\n            self._pool = pool\n            try:\n                with nogil:\n                    status = pjmedia_wav_writer_port_create(pool, filename,\n                                                            sample_rate, 1,\n                                                            sample_rate / 50, 16,\n                                                            PJMEDIA_FILE_WRITE_PCM, 0, port_address)\n                if status != 0:\n                    raise PJSIPError(\"Could not create WAV file\", status)\n                self._slot = self.mixer._add_port(ua, self._pool, self._port)\n            except:\n                self.stop()\n                raise\n            self._was_started = 1\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def stop(self):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            self._stop(ua)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    cdef int _stop(self, PJSIPUA ua) except -1:\n        cdef pjmedia_port *port = self._port\n\n        if self._slot != -1:\n            self.mixer._remove_port(ua, self._slot)\n            self._slot = -1\n        if self._port != NULL:\n            with nogil:\n                pjmedia_port_destroy(port)\n            self._port = NULL\n        ua.release_memory_pool(self._pool)\n        self._pool = NULL\n        return 0\n\n    def __dealloc__(self):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n        except:\n            return\n        self._stop(ua)\n\n        if self._lock != NULL:\n            pj_mutex_destroy(self._lock)\n\n\ncdef class WaveFile:\n    def __cinit__(self, *args, **kwargs):\n        cdef int status\n\n        self.weakref = weakref.ref(self)\n        Py_INCREF(self.weakref)\n\n        status = pj_mutex_create_recursive(_get_ua()._pjsip_endpoint._pool, \"wave_file_lock\", &self._lock)\n        if status != 0:\n            raise PJSIPError(\"failed to create lock\", status)\n\n        self._slot = -1\n        self._volume = 100\n\n    def __init__(self, AudioMixer mixer, filename):\n        if self.filename is not None:\n            raise SIPCoreError(\"WaveFile.__init__() was already called\")\n        if mixer is None:\n            raise ValueError(\"mixer argument may not be None\")\n        if filename is None:\n            raise ValueError(\"filename argument may not be None\")\n        if not isinstance(filename, basestring):\n            raise TypeError(\"file argument must be str or unicode\")\n        if isinstance(filename, unicode):\n            filename = filename.encode(sys.getfilesystemencoding())\n        self.mixer = mixer\n        self.filename = filename\n\n    cdef PJSIPUA _check_ua(self):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n            return ua\n        except:\n            self._pool = NULL\n            self._port = NULL\n            self._slot = -1\n            return None\n\n    property is_active:\n\n        def __get__(self):\n            self._check_ua()\n            return self._port != NULL\n\n    property slot:\n\n        def __get__(self):\n            self._check_ua()\n            if self._slot == -1:\n                return None\n            else:\n                return self._slot\n\n    property volume:\n\n        def __get__(self):\n            return self._volume\n\n        def __set__(self, value):\n            cdef int slot\n            cdef int status\n            cdef int volume\n            cdef pj_mutex_t *lock = self._lock\n            cdef pjmedia_conf *conf_bridge\n            cdef PJSIPUA ua\n\n            ua = self._check_ua()\n\n            if ua is not None:\n                with nogil:\n                    status = pj_mutex_lock(lock)\n                if status != 0:\n                    raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                conf_bridge = self.mixer._obj\n                slot = self._slot\n\n                if value < 0:\n                    raise ValueError(\"volume attribute cannot be negative\")\n                if ua is not None and self._slot != -1:\n                    volume = int(value * 1.28 - 128)\n                    with nogil:\n                        status = pjmedia_conf_adjust_rx_level(conf_bridge, slot, volume)\n                    if status != 0:\n                        raise PJSIPError(\"Could not set volume of .wav file\", status)\n                self._volume = value\n            finally:\n                if ua is not None:\n                    with nogil:\n                        pj_mutex_unlock(lock)\n\n    def start(self):\n        cdef char *filename\n        cdef int status\n        cdef void *weakref\n        cdef pj_pool_t *pool\n        cdef pj_mutex_t *lock = self._lock\n        cdef pjmedia_port **port_address\n        cdef bytes pool_name\n        cdef char* c_pool_name\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            filename = PyString_AsString(self.filename)\n            port_address = &self._port\n            weakref = <void *> self.weakref\n\n            if self._port != NULL:\n                raise SIPCoreError(\"WAV file is already playing\")\n            pool_name = b\"WaveFile_%d\" % id(self)\n            pool = ua.create_memory_pool(pool_name, 4096, 4096)\n            self._pool = pool\n            try:\n                with nogil:\n                    status = pjmedia_wav_player_port_create(pool, filename, 0, PJMEDIA_FILE_NO_LOOP, 0, port_address)\n                if status != 0:\n                    raise PJSIPError(\"Could not open WAV file\", status)\n                with nogil:\n                    status = pjmedia_wav_player_set_eof_cb(port_address[0], weakref, cb_play_wav_eof)\n                if status != 0:\n                    raise PJSIPError(\"Could not set WAV EOF callback\", status)\n                self._slot = self.mixer._add_port(ua, self._pool, self._port)\n                if self._volume != 100:\n                    self.volume = self._volume\n            except:\n                self._stop(ua, 0)\n                raise\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    cdef int _stop(self, PJSIPUA ua, int notify) except -1:\n        cdef int status\n        cdef int was_active\n        cdef pj_pool_t *pool\n        cdef pjmedia_port *port\n\n        port = self._port\n        was_active = 0\n\n        if self._slot != -1:\n            was_active = 1\n            self.mixer._remove_port(ua, self._slot)\n            self._slot = -1\n        if self._port != NULL:\n            with nogil:\n                pjmedia_port_destroy(port)\n            self._port = NULL\n            was_active = 1\n        ua.release_memory_pool(self._pool)\n        self._pool = NULL\n        if notify and was_active:\n            _add_event(\"WaveFileDidFinishPlaying\", dict(obj=self))\n\n    def stop(self):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n        if ua is None:\n            return\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            self._stop(ua, 1)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def __dealloc__(self):\n        cdef PJSIPUA ua\n        cdef Timer timer\n        try:\n            ua = _get_ua()\n        except:\n            return\n        self._stop(ua, 0)\n        timer = Timer()\n        try:\n            timer.schedule(60, deallocate_weakref, self.weakref)\n        except SIPCoreError:\n            pass\n        if self._lock != NULL:\n            pj_mutex_destroy(self._lock)\n\n    cdef int _cb_eof(self, timer) except -1:\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n        if ua is None:\n            return 0\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            self._stop(ua, 1)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n\ncdef class MixerPort:\n    def __cinit__(self, *args, **kwargs):\n        cdef int status\n\n        status = pj_mutex_create_recursive(_get_ua()._pjsip_endpoint._pool, \"mixer_port_lock\", &self._lock)\n        if status != 0:\n            raise PJSIPError(\"failed to create lock\", status)\n\n        self._slot = -1\n\n    def __init__(self, AudioMixer mixer):\n        if self.mixer is not None:\n            raise SIPCoreError(\"MixerPort.__init__() was already called\")\n        if mixer is None:\n            raise ValueError(\"mixer argument may not be None\")\n        self.mixer = mixer\n\n    cdef PJSIPUA _check_ua(self):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n            return ua\n        except:\n            self._pool = NULL\n            self._port = NULL\n            self._slot = -1\n            return None\n\n    property is_active:\n\n        def __get__(self):\n            self._check_ua()\n            return self._slot != -1\n\n    property slot:\n\n        def __get__(self):\n            self._check_ua()\n            if self._slot == -1:\n                return None\n            else:\n                return self._slot\n\n    def start(self):\n        cdef int sample_rate\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef pj_pool_t *pool\n        cdef pjmedia_port **port_address\n        cdef bytes pool_name\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            pool_name = b\"MixerPort_%d\" % id(self)\n            port_address = &self._port\n            sample_rate = self.mixer.sample_rate\n\n            if self._was_started:\n                raise SIPCoreError(\"This MixerPort was already started once\")\n            pool = ua.create_memory_pool(pool_name, 4096, 4096)\n            self._pool = pool\n            try:\n                with nogil:\n                    status = pjmedia_mixer_port_create(pool, sample_rate, 1, sample_rate / 50, 16, port_address)\n                if status != 0:\n                    raise PJSIPError(\"Could not create WAV file\", status)\n                self._slot = self.mixer._add_port(ua, self._pool, self._port)\n            except:\n                self.stop()\n                raise\n            self._was_started = 1\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def stop(self):\n        cdef int status\n        cdef pj_mutex_t *lock = self._lock\n        cdef PJSIPUA ua\n\n        ua = self._check_ua()\n        if ua is None:\n            return\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            self._stop(ua)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    cdef int _stop(self, PJSIPUA ua) except -1:\n        cdef pj_pool_t *pool\n        cdef pjmedia_port *port\n\n        pool = self._pool\n        port = self._port\n\n        if self._slot != -1:\n            self.mixer._remove_port(ua, self._slot)\n            self._slot = -1\n        if self._port != NULL:\n            with nogil:\n                pjmedia_port_destroy(port)\n            self._port = NULL\n        ua.release_memory_pool(self._pool)\n        self._pool = NULL\n        return 0\n\n    def __dealloc__(self):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n        except:\n            return\n        self._stop(ua)\n        if self._lock != NULL:\n            pj_mutex_destroy(self._lock)\n\n\n# callback functions\n\ncdef int _AudioMixer_dealloc_handler(object obj) except -1:\n    cdef int status\n    cdef AudioMixer mixer = obj\n    cdef PJSIPUA ua\n\n    ua = _get_ua()\n\n    status = pj_mutex_lock(mixer._lock)\n    if status != 0:\n        raise PJSIPError(\"failed to acquire lock\", status)\n    try:\n        mixer._stop_sound_device(ua)\n        mixer._connected_slots = list()\n        mixer.used_slot_count = 0\n    finally:\n        pj_mutex_unlock(mixer._lock)\n\ncdef int cb_play_wav_eof(pjmedia_port *port, void *user_data) with gil:\n    cdef Timer timer\n    cdef WaveFile wav_file\n\n    wav_file = (<object> user_data)()\n    if wav_file is not None:\n        timer = Timer()\n        timer.schedule(0, <timer_callback>wav_file._cb_eof, wav_file)\n    # do not return PJ_SUCCESS because if you do pjsip will access the just deallocated port\n    return 1\n\n"
  },
  {
    "path": "sipsimple/core/_core.subscription.pxi",
    "content": "\nimport re\n\n\ncdef class Subscription:\n    expire_warning_time = 30\n\n    #public methods\n\n    def __cinit__(self, *args, **kwargs):\n        self.state = \"NULL\"\n        pj_timer_entry_init(&self._timeout_timer, 0, <void *> self, _Subscription_cb_timer)\n        self._timeout_timer_active = 0\n        pj_timer_entry_init(&self._refresh_timer, 1, <void *> self, _Subscription_cb_timer)\n        self._refresh_timer_active = 0\n        self.extra_headers = frozenlist()\n        self.peer_address = None\n        self.call_id = None\n\n    def __init__(self, SIPURI request_uri not None, FromHeader from_header not None, ToHeader to_header not None, ContactHeader contact_header not None,\n                 object event, RouteHeader route_header not None, Credentials credentials=None, int refresh=300):\n        global _subs_cb\n        cdef PJSTR from_header_str\n        cdef PJSTR to_header_str\n        cdef PJSTR contact_str\n        cdef PJSTR request_uri_str\n        cdef pj_str_t event_pj\n        cdef pjsip_cred_info *cred_info\n        cdef PJSIPUA ua = _get_ua()\n        cdef int status\n        if self._obj != NULL or self.state != \"NULL\":\n            raise SIPCoreError(\"Subscription.__init__() was already called\")\n        if refresh <= 0:\n            raise ValueError(\"refresh argument needs to be a non-negative integer\")\n        if event not in ua._events.iterkeys():\n            raise ValueError('Unknown event \"%s\"' % event)\n        self.contact_header = FrozenContactHeader.new(contact_header)\n        self.event = event\n        self.route_header = FrozenRouteHeader.new(route_header)\n        self.route_header.uri.parameters.dict[\"lr\"] = None # always send lr parameter in Route header\n        self.route_header.uri.parameters.dict[\"hide\"] = None # always hide Route header\n        if credentials is not None:\n            self.credentials = FrozenCredentials.new(credentials)\n        self.refresh = refresh\n        from_header_parameters = from_header.parameters.copy()\n        from_header_parameters.pop(\"tag\", None)\n        from_header.parameters = {}\n        from_header_str = PJSTR(from_header.body)\n        to_header_parameters = to_header.parameters.copy()\n        to_header_parameters.pop(\"tag\", None)\n        to_header.parameters = {}\n        to_header_str = PJSTR(to_header.body)\n        contact_str = PJSTR(str(contact_header.body))\n        request_uri_str = PJSTR(str(request_uri))\n        _str_to_pj_str(self.event, &event_pj)\n        with nogil:\n            status = pjsip_dlg_create_uac(pjsip_ua_instance(), &from_header_str.pj_str, &contact_str.pj_str,\n                                          &to_header_str.pj_str, &request_uri_str.pj_str, &self._dlg)\n        if status != 0:\n            raise PJSIPError(\"Could not create dialog for SUBSCRIBE\", status)\n        # Increment dialog session count so that it's never destroyed by PJSIP\n        with nogil:\n            status = pjsip_dlg_inc_session(self._dlg, &ua._module)\n        if status != 0:\n            raise PJSIPError(\"Could not increment dialog session count\", status)\n        self.call_id = _pj_str_to_str(self._dlg.call_id.id)\n        if contact_header.expires is not None:\n            self._dlg.local.contact.expires = contact_header.expires\n        if contact_header.q is not None:\n            self._dlg.local.contact.q1000 = int(contact_header.q*1000)\n        contact_parameters = contact_header.parameters.copy()\n        contact_parameters.pop(\"q\", None)\n        contact_parameters.pop(\"expires\", None)\n        _dict_to_pjsip_param(contact_parameters, &self._dlg.local.contact.other_param, self._dlg.pool)\n        _dict_to_pjsip_param(from_header_parameters, &self._dlg.local.info.other_param, self._dlg.pool)\n        _dict_to_pjsip_param(to_header_parameters, &self._dlg.remote.info.other_param, self._dlg.pool)\n        self.from_header = FrozenFromHeader_create(self._dlg.local.info)\n        self.to_header = FrozenToHeader.new(to_header)\n        with nogil:\n            status = pjsip_evsub_create_uac(self._dlg, &_subs_cb, &event_pj, PJSIP_EVSUB_NO_EVENT_ID, &self._obj)\n        if status != 0:\n            raise PJSIPError(\"Could not create SUBSCRIBE\", status)\n        pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, <void *> self)\n        _BaseRouteHeader_to_pjsip_route_hdr(self.route_header, &self._route_header, self._dlg.pool)\n        pj_list_init(<pj_list *> &self._route_set)\n        pj_list_insert_after(<pj_list *> &self._route_set, <pj_list *> &self._route_header)\n        with nogil:\n            status = pjsip_dlg_set_route_set(self._dlg, <pjsip_route_hdr *> &self._route_set)\n        if status != 0:\n            raise PJSIPError(\"Could not set route on SUBSCRIBE\", status)\n        if self.credentials is not None:\n            cred_info = self.credentials.get_cred_info()\n            with nogil:\n                status = pjsip_auth_clt_set_credentials(&self._dlg.auth_sess, 1, cred_info)\n            if status != 0:\n                raise PJSIPError(\"Could not set credentials for SUBSCRIBE\", status)\n\n    def __dealloc__(self):\n        cdef PJSIPUA ua = self._get_ua()\n        if ua is not None:\n            self._cancel_timers(ua, 1, 1)\n        if self._obj != NULL:\n            pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, NULL)\n            with nogil:\n                pjsip_evsub_terminate(self._obj, 0)\n            self._obj = NULL\n        if self._dlg != NULL and ua is not None:\n            with nogil:\n                pjsip_dlg_dec_session(self._dlg, &ua._module)\n            self._dlg = NULL\n\n    def subscribe(self, list extra_headers not None=list(), object content_type=None, object body=None, object timeout=None):\n        cdef object prev_state = self.state\n        cdef PJSIPUA ua = self._get_ua()\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state == \"TERMINATED\":\n                raise SIPCoreError('This method may not be called in the \"TERMINATED\" state')\n            if (content_type is not None and body is None) or (content_type is None and body is not None):\n                raise ValueError(\"Both or none of content_type and body arguments need to be specified\")\n            if timeout is not None:\n                if timeout <= 0:\n                    raise ValueError(\"Timeout value cannot be negative\")\n                self._subscribe_timeout.sec = int(timeout)\n                self._subscribe_timeout.msec = (timeout * 1000) % 1000\n            else:\n                self._subscribe_timeout.sec = 0\n                self._subscribe_timeout.msec = 0\n            if extra_headers is not None:\n                self.extra_headers = frozenlist([header.frozen_type.new(header) for header in extra_headers])\n            self.content_type = content_type\n            self.body = body\n            self._send_subscribe(ua, self.refresh, &self._subscribe_timeout, self.extra_headers, content_type, body)\n            self._cancel_timers(ua, 0, 1)\n            if prev_state == \"NULL\":\n                _add_event(\"SIPSubscriptionWillStart\", dict(obj=self))\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    def end(self, object timeout=None):\n        cdef pj_time_val end_timeout\n        cdef PJSIPUA ua = self._get_ua()\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state == \"TERMINATED\":\n                return\n            if self.state == \"NULL\":\n                raise SIPCoreError('This method may not be called in the \"NULL\" state')\n            if timeout is not None:\n                if timeout <= 0:\n                    raise ValueError(\"Timeout value cannot be negative\")\n                end_timeout.sec = int(timeout)\n                end_timeout.msec = (timeout * 1000) % 1000\n            else:\n                end_timeout.sec = 0\n                end_timeout.msec = 0\n            self._want_end = 1\n            self._cancel_timers(ua, 1, 1)\n            _add_event(\"SIPSubscriptionWillEnd\", dict(obj=self))\n            try:\n                self._send_subscribe(ua, 0, &end_timeout, self.extra_headers, None, None)\n            except PJSIPError, e:\n                self._term_reason = e.args[0]\n                if self._obj != NULL:\n                    with nogil:\n                        pjsip_evsub_terminate(self._obj, 1)\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n\n    # private methods\n\n    cdef PJSIPUA _get_ua(self):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n        except SIPCoreError:\n            self._obj = NULL\n            self._timeout_timer_active = 0\n            self._refresh_timer_active = 0\n            self.state = \"TERMINATED\"\n            return None\n        else:\n            return ua\n\n    cdef int _cancel_timers(self, PJSIPUA ua, int cancel_timeout, int cancel_refresh) except -1:\n        if cancel_timeout and self._timeout_timer_active:\n            pjsip_endpt_cancel_timer(ua._pjsip_endpoint._obj, &self._timeout_timer)\n            self._timeout_timer_active = 0\n        if cancel_refresh and self._refresh_timer_active:\n            pjsip_endpt_cancel_timer(ua._pjsip_endpoint._obj, &self._refresh_timer)\n            self._refresh_timer_active = 0\n\n    cdef int _send_subscribe(self, PJSIPUA ua, int expires, pj_time_val *timeout,\n                             object extra_headers, object content_type, object body) except -1:\n        cdef pjsip_tx_data *tdata\n        cdef pj_str_t body_pj\n        cdef object content_type_spl\n        cdef PJSTR content_type_str\n        cdef PJSTR content_subtype_str\n        cdef int status\n        if body is not None:\n            content_type_spl = content_type.split(\"/\")\n            if len(content_type_spl) != 2:\n                raise ValueError('Supplied content_type argument does not contain a \"/\" character')\n            content_type_str = PJSTR(content_type_spl[0])\n            content_subtype_str = PJSTR(content_type_spl[1])\n            _str_to_pj_str(body, &body_pj)\n        with nogil:\n            status = pjsip_evsub_initiate(self._obj, NULL, expires, &tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not create SUBSCRIBE message\", status)\n        _add_headers_to_tdata(tdata, extra_headers)\n        if body is not None:\n            tdata.msg.body = pjsip_msg_body_create(tdata.pool, &content_type_str.pj_str, &content_subtype_str.pj_str, &body_pj)\n        with nogil:\n            status = pjsip_evsub_send_request(self._obj, tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not send SUBSCRIBE message\", status)\n        self._cancel_timers(ua, 1, 0)\n        if timeout.sec or timeout.msec:\n            status = pjsip_endpt_schedule_timer(ua._pjsip_endpoint._obj, &self._timeout_timer, timeout)\n            if status == 0:\n                self._timeout_timer_active = 1\n        self._expires = self.refresh\n\n    # callback methods\n\n    cdef int _cb_state(self, PJSIPUA ua, object state, int code, object reason, dict headers) except -1:\n        # PJSIP holds the dialog lock when this callback is entered\n        cdef object prev_state = self.state\n        cdef int expires\n        cdef int status\n        cdef pj_time_val end_timeout\n        self.state = state\n        if state == \"ACCEPTED\" and prev_state == \"SENT\":\n            try:\n                contact_header = headers['Contact'][0]\n            except LookupError:\n                self._term_code = 1400\n                self._term_reason = \"Contact header missing\"\n                with nogil:\n                    pjsip_evsub_terminate(self._obj, 1)\n                return 0\n            _add_event(\"SIPSubscriptionDidStart\", dict(obj=self))\n            try:\n                expires = int(headers[\"Expires\"])\n            except (KeyError, ValueError):\n                return 0\n            if expires == 0:\n                self._want_end = 1\n                self._cancel_timers(ua, 1, 1)\n                end_timeout.sec = 1\n                end_timeout.msec = 0\n                _add_event(\"SIPSubscriptionWillEnd\", dict(obj=self))\n                try:\n                    self._send_subscribe(ua, 0, &end_timeout, self.extra_headers, None, None)\n                except PJSIPError, e:\n                    self._term_reason = e.args[0]\n                    if self._obj != NULL:\n                        with nogil:\n                            pjsip_evsub_terminate(self._obj, 1)\n                return 0\n        elif state == \"TERMINATED\":\n            pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, NULL)\n            self._cancel_timers(ua, 1, 1)\n            self._obj = NULL\n            if self._want_end:\n                _add_event(\"SIPSubscriptionDidEnd\", dict(obj=self))\n            else:\n                min_expires = headers.get('Min-Expires')\n                if self._term_reason is not None:\n                    _add_event(\"SIPSubscriptionDidFail\", dict(obj=self, code=self._term_code, reason=self._term_reason, min_expires=min_expires))\n                else:\n                    subscription_state = headers.get('Subscription-State')\n                    if subscription_state is not None and subscription_state.state == 'terminated':\n                        reason = subscription_state.reason\n                    _add_event(\"SIPSubscriptionDidFail\", dict(obj=self, code=code, reason=reason, min_expires=min_expires))\n        if prev_state != state:\n            _add_event(\"SIPSubscriptionChangedState\", dict(obj=self, prev_state=prev_state, state=state))\n\n    cdef int _cb_got_response(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1:\n        # PJSIP holds the dialog lock when this callback is entered\n        cdef dict event_dict = dict()\n        cdef int expires = self._expires\n        cdef int status\n        cdef pj_time_val refresh\n        _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n        self.to_header = FrozenToHeader_create(rdata.msg_info.to_hdr)\n        if self.state != \"TERMINATED\":\n            try:\n                contact_header = event_dict[\"headers\"][\"Contact\"][0]\n            except LookupError:\n                return 0\n            try:\n                expires = int(event_dict[\"headers\"][\"Expires\"])\n            except (KeyError, ValueError):\n                expires = self._expires\n            if expires == 0:\n                return 0\n        if self.state != \"TERMINATED\" and not self._want_end:\n            self._cancel_timers(ua, 1, 0)\n            refresh.sec = max(1, expires - self.expire_warning_time, expires/2)\n            refresh.msec = 0\n            status = pjsip_endpt_schedule_timer(ua._pjsip_endpoint._obj, &self._refresh_timer, &refresh)\n            if status == 0:\n                self._refresh_timer_active = 1\n\n    cdef int _cb_notify(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1:\n        # PJSIP holds the dialog lock when this callback is entered\n        cdef dict event_dict = dict()\n        cdef dict notify_dict = dict(obj=self)\n        _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n        body = event_dict[\"body\"]\n        content_type = event_dict[\"headers\"].get(\"Content-Type\", None)\n        event = event_dict[\"headers\"].get(\"Event\", None)\n        if event is None or event.event != self.event or (body is not None and content_type is not None and content_type.content_type not in ua.events[event.event]):\n            return 0\n        notify_dict[\"request_uri\"] = event_dict[\"request_uri\"]\n        notify_dict[\"from_header\"] = event_dict[\"headers\"].get(\"From\", None)\n        notify_dict[\"to_header\"] = event_dict[\"headers\"].get(\"To\", None)\n        notify_dict[\"headers\"] = event_dict[\"headers\"]\n        notify_dict[\"body\"] = body\n        notify_dict[\"content_type\"] = content_type.content_type if content_type and body else None\n        notify_dict[\"event\"] = event.event\n        _add_event(\"SIPSubscriptionGotNotify\", notify_dict)\n\n    cdef int _cb_timeout_timer(self, PJSIPUA ua):\n        # Timer callback, dialog lock is not held by PJSIP\n        global sip_status_messages\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            self._term_code = PJSIP_SC_TSX_TIMEOUT\n            self._term_reason = sip_status_messages[PJSIP_SC_TSX_TIMEOUT]\n            if self._obj != NULL:\n                with nogil:\n                    pjsip_evsub_terminate(self._obj, 1)\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    cdef int _cb_refresh_timer(self, PJSIPUA ua):\n        # Timer callback, dialog lock is not held by PJSIP\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            self._send_subscribe(ua, self.refresh, &self._subscribe_timeout,\n                                 self.extra_headers, self.content_type, self.body)\n        except PJSIPError, e:\n            self._term_reason = e.args[0]\n            if self._obj != NULL:\n                with nogil:\n                    pjsip_evsub_terminate(self._obj, 1)\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n\ncdef class IncomingSubscription:\n    # properties\n\n    property content_type:\n\n        def __get__(self):\n            if self._content_type is None:\n                return None\n            return \"%s/%s\" % (self._content_type.str, self._content_subtype.str)\n\n    property content:\n\n        def __get__(self):\n            if self._content is None:\n                return None\n            return self._content.str\n\n    def __cinit__(self):\n        self.state = None\n        self.peer_address = None\n        self.call_id = None\n\n    def __dealloc__(self):\n        cdef PJSIPUA ua = self._get_ua(0)\n        self._initial_response = NULL\n        self._initial_tsx = NULL\n        if self._obj != NULL:\n            pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, NULL)\n            with nogil:\n                pjsip_evsub_terminate(self._obj, 0)\n            self._obj = NULL\n        if self._dlg != NULL and ua is not None:\n            with nogil:\n                pjsip_dlg_dec_session(self._dlg, &ua._module)\n            self._dlg = NULL\n\n    cdef int init(self, PJSIPUA ua, pjsip_rx_data *rdata, str event) except -1:\n        global _incoming_subs_cb\n        cdef int status\n        cdef str transport\n        cdef FrozenSIPURI request_uri\n        cdef FrozenContactHeader contact_header\n        cdef PJSTR contact_str\n        cdef dict event_dict\n        cdef pjsip_expires_hdr *expires_header\n        cdef char *error_message\n\n        expires_header = <pjsip_expires_hdr *> pjsip_msg_find_hdr(rdata.msg_info.msg, PJSIP_H_EXPIRES, NULL)\n        if expires_header == NULL:\n            self._expires = 3600\n        else:\n            self._expires = min(expires_header.ivalue, 3600)\n        self._set_state(\"incoming\")\n        self.event = event\n        self.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n        event_dict = dict(obj=self)\n        _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n        transport = rdata.tp_info.transport.type_name.lower()\n        request_uri = event_dict[\"request_uri\"]\n        if _is_valid_ip(pj_AF_INET(), request_uri.host):\n            contact_header = FrozenContactHeader(request_uri)\n        else:\n            contact_header = FrozenContactHeader(FrozenSIPURI(host=_pj_str_to_str(rdata.tp_info.transport.local_name.host),\n                                                            user=request_uri.user, port=rdata.tp_info.transport.local_name.port,\n                                                            parameters=(frozendict(transport=transport) if transport != \"udp\" else frozendict())))\n        contact_str = PJSTR(str(contact_header.body))\n\n        with nogil:\n            status = pjsip_dlg_create_uas_and_inc_lock(pjsip_ua_instance(), rdata, &contact_str.pj_str, &self._dlg)\n            if status != 0:\n                error_message = \"Could not create dialog for incoming SUBSCRIBE\"\n            else:\n                pjsip_dlg_inc_session(self._dlg, &ua._module)  # Increment dialog session count so it's never destroyed by PJSIP\n                # setting the transport to rdata.tp_info.transport doesn't work as the NOTIFY has to be sent to the Contact URI and the transports can conflict\n        if status != 0:\n            raise PJSIPError(error_message, status)\n        self._initial_tsx = pjsip_rdata_get_tsx(rdata)\n        self.call_id = _pj_str_to_str(self._dlg.call_id.id)\n        with nogil:\n            status = pjsip_evsub_create_uas(self._dlg, &_incoming_subs_cb, rdata, 0, &self._obj)\n            pjsip_dlg_dec_lock(self._dlg)\n            if status != 0:\n                pjsip_tsx_terminate(self._initial_tsx, 500)\n                self._initial_tsx = NULL\n                self._dlg = NULL\n                error_message = \"Could not create incoming SUBSCRIBE session\"\n            else:\n                pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, <void *> self)\n                status = pjsip_dlg_create_response(self._dlg, rdata, 500, NULL, &self._initial_response)\n                if status != 0:\n                    pjsip_tsx_terminate(self._initial_tsx, 500)\n                    self._initial_tsx = NULL\n                    error_message = \"Could not create response for incoming SUBSCRIBE\"\n\n        if status != 0:\n            raise PJSIPError(error_message, status)\n\n        _add_event(\"SIPIncomingSubscriptionGotSubscribe\", event_dict)\n        return 0\n\n    def reject(self, int code):\n        cdef PJSIPUA ua = self._get_ua(1)\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state != \"incoming\":\n                raise SIPCoreInvalidStateError('Can only reject an incoming SUBSCRIBE in the \"incoming\" state, '+\n                                        'object is currently in the \"%s\" state' % self.state)\n            if not (300 <= code < 700):\n                raise ValueError(\"Invalid negative SIP response code: %d\" % code)\n            self._send_initial_response(code)\n            pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, NULL)\n            with nogil:\n                pjsip_evsub_terminate(self._obj, 0)\n            self._obj = NULL\n            self._set_state(\"terminated\")\n            _add_event(\"SIPIncomingSubscriptionDidEnd\", dict(obj=self))\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    def accept_pending(self):\n        cdef PJSIPUA ua = self._get_ua(1)\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state != \"incoming\":\n                raise SIPCoreInvalidStateError('Can only accept an incoming SUBSCRIBE as pending in the \"incoming\" state, '+\n                                        'object is currently in the \"%s\" state' % self.state)\n            self._send_initial_response(202)\n            self._set_state(\"pending\")\n            if self._expires > 0:\n                self._send_notify()\n            else:\n                # cleanup will be done by _cb_tsx\n                self._terminate(ua, \"timeout\", 0)\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    def accept(self, str content_type=None, str content=None):\n        global _re_content_type\n        cdef object content_type_match\n        cdef PJSIPUA ua = self._get_ua(1)\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state not in (\"incoming\", \"pending\"):\n                raise SIPCoreInvalidStateError('Can only accept an incoming SUBSCRIBE in the \"incoming\" or \"pending\" state, object is currently in the \"%s\" state' % self.state)\n            if (content_type is None and content is not None) or (content_type is not None and content is None):\n                raise ValueError('Either both or neither of the \"content_type\" and \"content\" arguments should be specified')\n            if content_type is not None:\n                content_type_match = _re_content_type.match(content_type)\n                if content_type_match is None:\n                    raise ValueError(\"content_type parameter is not properly formatted\")\n                self._content_type = PJSTR(content_type_match.group(1))\n                self._content_subtype = PJSTR(content_type_match.group(2))\n                self._content = PJSTR(content)\n            if self.state == \"incoming\":\n                self._send_initial_response(200)\n            self._set_state(\"active\")\n            if self._expires > 0:\n                self._send_notify()\n            else:\n                # cleanup will be done by _cb_tsx\n                self._terminate(ua, \"timeout\", 0)\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    def push_content(self, str content_type not None, str content not None):\n        global _re_content_type\n        cdef object content_type_match\n        cdef PJSIPUA ua = self._get_ua(1)\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state != \"active\":\n                raise SIPCoreInvalidStateError('Can only push the content for a SUBSCRIBE session in the \"active\" state, '\n                                            'object is currently in the \"%s\" state' % self.state)\n            content_type_match = _re_content_type.match(content_type)\n            if content_type_match is None:\n                raise ValueError(\"content_type parameter is not properly formatted\")\n            self._content_type = PJSTR(content_type_match.group(1))\n            self._content_subtype = PJSTR(content_type_match.group(2))\n            self._content = PJSTR(content)\n            self._send_notify()\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    def end(self, reason=None):\n        cdef PJSIPUA ua = self._get_ua(0)\n\n        with nogil:\n            pjsip_dlg_inc_lock(self._dlg)\n        try:\n            if self.state == \"terminated\":\n                return\n            if self.state not in (\"pending\", \"active\"):\n                raise SIPCoreInvalidStateError('Can only end an incoming SUBSCRIBE session in the \"pending\" or '+\n                                        '\"active\" state, object is currently in the \"%s\" state' % self.state)\n            self._terminate(ua, reason, 1)\n        finally:\n            with nogil:\n                pjsip_dlg_dec_lock(self._dlg)\n\n    cdef int _set_state(self, str state) except -1:\n        cdef str prev_state\n        prev_state = self.state\n        self.state = state\n        if prev_state != state and prev_state is not None:\n            _add_event(\"SIPIncomingSubscriptionChangedState\", dict(obj=self, prev_state=prev_state, state=state))\n\n    cdef PJSIPUA _get_ua(self, int raise_exception):\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n        except SIPCoreError:\n            self._obj = NULL\n            self._initial_response = NULL\n            self._initial_tsx = NULL\n            self._set_state(\"terminated\")\n            if raise_exception:\n                raise\n            else:\n                return None\n        else:\n            return ua\n\n    cdef int _send_initial_response(self, int code) except -1:\n        cdef PJSIPUA ua = self._get_ua(1)\n        cdef int status\n\n        with nogil:\n            status = pjsip_dlg_modify_response(self._dlg, self._initial_response, code, NULL)\n        if status != 0:\n            raise PJSIPError(\"Could not modify response\", status)\n        # pjsip_dlg_modify_response() increases ref count unncessarily\n        with nogil:\n            pjsip_tx_data_dec_ref(self._initial_response)\n        if code / 100 == 2:\n            pjsip_msg_add_hdr(self._initial_response.msg,\n                              <pjsip_hdr *> pjsip_expires_hdr_create(self._initial_response.pool, self._expires))\n        with nogil:\n            status = pjsip_dlg_send_response(self._dlg, self._initial_tsx, self._initial_response)\n        if status != 0:\n            raise PJSIPError(\"Could not send response\", status)\n        self._initial_response = NULL\n        self._initial_tsx = NULL\n        if self._expires > 0:\n            with nogil:\n                # Start TIMER_TYPE_UAS_TIMEOUT, which PJSIP doesn't do for the initial SUBSCRIBE\n                pjsip_evsub_set_timer(self._obj, 2, self._expires)\n\n    cdef int _send_notify(self, str reason=None) except -1:\n        cdef pjsip_evsub_state state\n        cdef pj_str_t reason_pj\n        cdef pj_str_t *reason_p\n        cdef pjsip_tx_data *tdata\n        cdef int status\n\n        reason_p = NULL\n        if self.state == \"pending\":\n            state = PJSIP_EVSUB_STATE_PENDING\n        elif self.state == \"active\":\n            state = PJSIP_EVSUB_STATE_ACTIVE\n        else:\n            state = PJSIP_EVSUB_STATE_TERMINATED\n            if reason is not None:\n                _str_to_pj_str(reason, &reason_pj)\n                reason_p = &reason_pj\n        with nogil:\n            status = pjsip_evsub_notify(self._obj, state, NULL, reason_p, &tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not create NOTIFY request\", status)\n        if self.state == \"active\" and None not in (self._content_type, self._content_subtype, self._content):\n            tdata.msg.body = pjsip_msg_body_create(tdata.pool, &self._content_type.pj_str,\n                                                   &self._content_subtype.pj_str, &self._content.pj_str)\n        with nogil:\n            status = pjsip_evsub_send_request(self._obj, tdata)\n        if status != 0:\n            raise PJSIPError(\"Could not send NOTIFY request\", status)\n        event_dict = dict(obj=self)\n        _pjsip_msg_to_dict(tdata.msg, event_dict)\n        _add_event(\"SIPIncomingSubscriptionSentNotify\", event_dict)\n        return 0\n\n    cdef int _terminate(self, PJSIPUA ua, str reason, int do_cleanup) except -1:\n        cdef int status\n        self._set_state(\"terminated\")\n        try:\n            self._send_notify(reason)\n        except SIPCoreError:\n            pass\n        if do_cleanup:\n            pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, NULL)\n            self._obj = NULL\n        _add_event(\"SIPIncomingSubscriptionDidEnd\", dict(obj=self))\n\n\n    # callback methods\n\n    cdef int _cb_rx_refresh(self, PJSIPUA ua, pjsip_rx_data *rdata) except -1:\n        # PJSIP holds the dialog lock when this callback is entered\n        cdef int status\n        cdef pjsip_expires_hdr *expires_header\n        cdef int expires\n        cdef dict event_dict\n\n        event_dict = dict(obj=self)\n        _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n        expires_header = <pjsip_expires_hdr *> pjsip_msg_find_hdr(rdata.msg_info.msg, PJSIP_H_EXPIRES, NULL)\n        if expires_header == NULL:\n            self._expires = 3600\n        else:\n            if expires_header.ivalue == 0:\n                _add_event(\"SIPIncomingSubscriptionGotUnsubscribe\", event_dict)\n                # cleanup will be done by _cb_tsx\n                self._terminate(ua, None, 0)\n                return 200\n            else:\n                self._expires = min(expires_header.ivalue, 3600)\n        _add_event(\"SIPIncomingSubscriptionGotRefreshingSubscribe\", event_dict)\n        try:\n            self._send_notify()\n        except SIPCoreError, e:\n            _add_event(\"SIPIncomingSubscriptionNotifyDidFail\", dict(obj=self, code=0, reason=e.args[0]))\n        if self.state == \"active\":\n            return 200\n        else:\n            return 202\n\n    cdef int _cb_server_timeout(self, PJSIPUA ua) except -1:\n        # PJSIP holds the dialog lock when this callback is entered\n        _add_event(\"SIPIncomingSubscriptionDidTimeout\", dict(obj=self))\n        self._terminate(ua, \"timeout\", 1)\n\n    cdef int _cb_tsx(self, PJSIPUA ua, pjsip_event *event) except -1:\n        # PJSIP holds the dialog lock when this callback is entered\n        cdef pjsip_rx_data *rdata\n        cdef dict event_dict\n        cdef int status_code\n\n        if (event != NULL and event.type == PJSIP_EVENT_TSX_STATE and\n            event.body.tsx_state.tsx.role == PJSIP_ROLE_UAC and\n            _pj_str_to_str(event.body.tsx_state.tsx.method.name) == \"NOTIFY\" and\n            event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_COMPLETED):\n            event_dict = dict(obj=self)\n            rdata = event.body.tsx_state.src.rdata\n            if rdata != NULL:\n                if self.peer_address is None:\n                    self.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n                else:\n                    self.peer_address.ip = rdata.pkt_info.src_name\n                    self.peer_address.port = rdata.pkt_info.src_port\n            status_code = event.body.tsx_state.tsx.status_code\n            if event.body.tsx_state.type==PJSIP_EVENT_RX_MSG and status_code/100==2:\n                _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n                _add_event(\"SIPIncomingSubscriptionNotifyDidSucceed\", event_dict)\n            else:\n                if event.body.tsx_state.type == PJSIP_EVENT_RX_MSG:\n                    _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n                else:\n                    event_dict[\"code\"] = status_code\n                    event_dict[\"reason\"] = _pj_str_to_str(event.body.tsx_state.tsx.status_text)\n                _add_event(\"SIPIncomingSubscriptionNotifyDidFail\", event_dict)\n                if status_code in (408, 481) or status_code/100==7:\n                    # PJSIP will terminate the subscription and the dialog will be destroyed\n                    self._terminate(ua, None, 1)\n        elif (event != NULL and event.type == PJSIP_EVENT_TSX_STATE and\n            event.body.tsx_state.tsx.role == PJSIP_ROLE_UAC and\n            _pj_str_to_str(event.body.tsx_state.tsx.method.name) == \"NOTIFY\" and\n            event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_TERMINATED):\n            event_dict = dict(obj=self)\n            status_code = event.body.tsx_state.tsx.status_code\n            if status_code == 408:\n                # Local timeout, PJSIP will terminate the subscription and the dialog will be destroyed\n                event_dict[\"code\"] = status_code\n                event_dict[\"reason\"] = _pj_str_to_str(event.body.tsx_state.tsx.status_text)\n                _add_event(\"SIPIncomingSubscriptionNotifyDidFail\", event_dict)\n                self._terminate(ua, None, 1)\n        elif (event != NULL and event.type == PJSIP_EVENT_TSX_STATE and\n            event.body.tsx_state.tsx.role == PJSIP_ROLE_UAS and\n            _pj_str_to_str(event.body.tsx_state.tsx.method.name) == \"SUBSCRIBE\" and\n            event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_COMPLETED and\n            event.body.tsx_state.type == PJSIP_EVENT_TX_MSG):\n            event_dict = dict(obj=self)\n            _pjsip_msg_to_dict(event.body.tsx_state.src.tdata.msg, event_dict)\n            _add_event(\"SIPIncomingSubscriptionAnsweredSubscribe\", event_dict)\n            if self.state == \"terminated\" and self._obj != NULL:\n                pjsip_evsub_set_mod_data(self._obj, ua._event_module.id, NULL)\n                self._obj = NULL\n\n# callback functions\n\ncdef void _Subscription_cb_state(pjsip_evsub *sub, pjsip_event *event) with gil:\n    cdef void *subscription_void\n    cdef Subscription subscription\n    cdef object state\n    cdef int code = 0\n    cdef object reason = None\n    cdef pjsip_rx_data *rdata = NULL\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        subscription_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if subscription_void == NULL:\n            return\n        subscription = <object> subscription_void\n        state = pjsip_evsub_get_state_name(sub)\n        if (event != NULL and event.type == PJSIP_EVENT_TSX_STATE and\n            (event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_COMPLETED or\n             event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_TERMINATED)):\n            if state == \"TERMINATED\":\n                if event.body.tsx_state.tsx.role == PJSIP_ROLE_UAC:\n                    code = event.body.tsx_state.tsx.status_code\n                    reason = _pj_str_to_str(event.body.tsx_state.tsx.status_text)\n                else:\n                    code = 0\n                    reason = None\n\n            if event.body.tsx_state.type == PJSIP_EVENT_RX_MSG and _pj_str_to_str(event.body.tsx_state.tsx.method.name) in (\"SUBSCRIBE\", \"NOTIFY\"):\n                rdata = event.body.tsx_state.src.rdata\n\n        headers_dict = dict()\n        if rdata != NULL:\n            rdata_dict = dict()\n            _pjsip_msg_to_dict(rdata.msg_info.msg, rdata_dict)\n            headers_dict = rdata_dict.get('headers', {})\n        subscription._cb_state(ua, state, code, reason, headers_dict)\n    except:\n        ua._handle_exception(1)\n\ncdef void _Subscription_cb_tsx(pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event) with gil:\n    cdef void *subscription_void\n    cdef Subscription subscription\n    cdef pjsip_rx_data *rdata\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        subscription_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if subscription_void == NULL:\n            return\n        subscription = <object> subscription_void\n        if (event != NULL and event.type == PJSIP_EVENT_TSX_STATE and\n            event.body.tsx_state.type == PJSIP_EVENT_RX_MSG and\n            event.body.tsx_state.tsx.role == PJSIP_ROLE_UAC and\n            event.body.tsx_state.tsx.state == PJSIP_TSX_STATE_COMPLETED and\n            _pj_str_to_str(event.body.tsx_state.tsx.method.name) == \"SUBSCRIBE\" and\n            event.body.tsx_state.tsx.status_code / 100 == 2):\n            rdata = event.body.tsx_state.src.rdata\n            if rdata != NULL:\n                if subscription.peer_address is None:\n                    subscription.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n                else:\n                    subscription.peer_address.ip = rdata.pkt_info.src_name\n                    subscription.peer_address.port = rdata.pkt_info.src_port\n            subscription._cb_got_response(ua, rdata)\n    except:\n        ua._handle_exception(1)\n\ncdef void _Subscription_cb_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code,\n                                    pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil:\n    cdef void *subscription_void\n    cdef Subscription subscription\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        subscription_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if subscription_void == NULL:\n            return\n        subscription = <object> subscription_void\n        if rdata != NULL:\n            if subscription.peer_address is None:\n                subscription.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n            else:\n                subscription.peer_address.ip = rdata.pkt_info.src_name\n                subscription.peer_address.port = rdata.pkt_info.src_port\n        subscription._cb_notify(ua, rdata)\n    except:\n        ua._handle_exception(1)\n\ncdef void _Subscription_cb_refresh(pjsip_evsub *sub) with gil:\n    # We want to handle the refresh timer oursevles, ignore the PJSIP provided timer\n    pass\n\ncdef void _Subscription_cb_timer(pj_timer_heap_t *timer_heap, pj_timer_entry *entry) with gil:\n    cdef Subscription subscription\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        if entry.user_data != NULL:\n            subscription = <object> entry.user_data\n            if subscription._dlg == NULL:\n                return\n            if entry.id == 1:\n                subscription._refresh_timer_active = 0\n                subscription._cb_refresh_timer(ua)\n            else:\n                subscription._timeout_timer_active = 0\n                subscription._cb_timeout_timer(ua)\n    except:\n        ua._handle_exception(1)\n\ncdef void _IncomingSubscription_cb_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata,\n                                              int *p_st_code, pj_str_t **p_st_text,\n                                              pjsip_hdr *res_hdr, pjsip_msg_body **p_body) with gil:\n    cdef void *subscription_void\n    cdef IncomingSubscription subscription\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        subscription_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if subscription_void == NULL:\n            p_st_code[0] = 481\n            return\n        subscription = <object> subscription_void\n        if rdata != NULL:\n            if subscription.peer_address is None:\n                subscription.peer_address = EndpointAddress(rdata.pkt_info.src_name, rdata.pkt_info.src_port)\n            else:\n                subscription.peer_address.ip = rdata.pkt_info.src_name\n                subscription.peer_address.port = rdata.pkt_info.src_port\n        p_st_code[0] = subscription._cb_rx_refresh(ua, rdata)\n    except:\n        ua._handle_exception(1)\n\ncdef void _IncomingSubscription_cb_server_timeout(pjsip_evsub *sub) with gil:\n    cdef void *subscription_void\n    cdef IncomingSubscription subscription\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        subscription_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if subscription_void == NULL:\n            return\n        subscription = <object> subscription_void\n        subscription._cb_server_timeout(ua)\n    except:\n        ua._handle_exception(1)\n\ncdef void _IncomingSubscription_cb_tsx(pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event) with gil:\n    cdef void *subscription_void\n    cdef IncomingSubscription subscription\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        subscription_void = pjsip_evsub_get_mod_data(sub, ua._event_module.id)\n        if subscription_void == NULL:\n            return\n        subscription = <object> subscription_void\n        subscription._cb_tsx(ua, event)\n    except:\n        ua._handle_exception(1)\n\n# globals\n\ncdef pjsip_evsub_user _subs_cb\n_subs_cb.on_evsub_state = _Subscription_cb_state\n_subs_cb.on_tsx_state = _Subscription_cb_tsx\n_subs_cb.on_rx_notify = _Subscription_cb_notify\n_subs_cb.on_client_refresh = _Subscription_cb_refresh\ncdef pjsip_evsub_user _incoming_subs_cb\n_incoming_subs_cb.on_rx_refresh = _IncomingSubscription_cb_rx_refresh\n_incoming_subs_cb.on_server_timeout = _IncomingSubscription_cb_server_timeout\n_incoming_subs_cb.on_tsx_state = _IncomingSubscription_cb_tsx\n_re_content_type = re.compile(\"^([a-zA-Z0-9\\-.!%*_+`'~]+)\\/([a-zA-Z0-9\\-.!%*_+`'~]+)$\")\n"
  },
  {
    "path": "sipsimple/core/_core.ua.pxi",
    "content": "\nimport errno\nimport heapq\nimport re\nimport random\nimport sys\nimport time\nimport traceback\nimport os\nimport tempfile\n\n\ncdef class Timer:\n    cdef int schedule(self, float delay, timer_callback callback, object obj) except -1:\n        cdef PJSIPUA ua = _get_ua()\n        if delay < 0:\n            raise ValueError(\"delay must be a non-negative number\")\n        if callback == NULL:\n            raise ValueError(\"callback must be non-NULL\")\n        if self._scheduled:\n            raise RuntimeError(\"already scheduled\")\n        self.schedule_time = PyFloat_AsDouble(time.time() + delay)\n        self.callback = callback\n        self.obj = obj\n        ua._add_timer(self)\n        self._scheduled = 1\n        return 0\n\n    cdef int cancel(self) except -1:\n        cdef PJSIPUA ua = _get_ua()\n        if not self._scheduled:\n            return 0\n        ua._remove_timer(self)\n        self._scheduled = 0\n        return 0\n\n    cdef int call(self) except -1:\n        self._scheduled = 0\n        self.callback(self.obj, self)\n\n    def __richcmp__(self, other, op):\n        cdef double diff\n        if not isinstance(self, Timer) or not isinstance(other, Timer):\n            return NotImplemented\n        diff = (<Timer>self).schedule_time - (<Timer>other).schedule_time\n        if op == 0: # <\n            return diff < 0.0\n        elif op == 1: # <=\n            return diff <= 0.0\n        elif op == 2: # ==\n            return diff == 0.0\n        elif op == 3: # !=\n            return diff != 0.0\n        elif op == 4: # >\n            return diff > 0.0\n        elif op == 5: # >=\n            return diff >= 0.0\n        return\n\n\ncdef class PJSIPUA:\n    def __cinit__(self, *args, **kwargs):\n        global _ua\n        if _ua != NULL:\n            raise SIPCoreError(\"Can only have one PJSUPUA instance at the same time\")\n        _ua = <void *> self\n        self._threads = []\n        self._timers = list()\n        self._events = {}\n        self._incoming_events = set()\n        self._incoming_requests = set()\n        self._sent_messages = set()\n\n    def __init__(self, event_handler, *args, **kwargs):\n        global _event_queue_lock\n        cdef str event\n        cdef str method\n        cdef list accept_types\n        cdef int status\n        cdef PJSTR message_method = PJSTR(\"MESSAGE\")\n        cdef PJSTR refer_method = PJSTR(\"REFER\")\n        cdef PJSTR str_norefersub = PJSTR(\"norefersub\")\n        cdef PJSTR str_gruu = PJSTR(\"gruu\")\n        self._event_handler = event_handler\n        if kwargs[\"log_level\"] < 0 or kwargs[\"log_level\"] > PJ_LOG_MAX_LEVEL:\n            raise ValueError(\"Log level should be between 0 and %d\" % PJ_LOG_MAX_LEVEL)\n        pj_log_set_level(kwargs[\"log_level\"])\n        pj_log_set_decor(PJ_LOG_HAS_YEAR | PJ_LOG_HAS_MONTH | PJ_LOG_HAS_DAY_OF_MON |\n                         PJ_LOG_HAS_TIME | PJ_LOG_HAS_MICRO_SEC | PJ_LOG_HAS_SENDER | PJ_LOG_HAS_INDENT)\n        pj_log_set_log_func(_cb_log)\n        self._pjlib = PJLIB()\n        pj_srand(random.getrandbits(32)) # rely on python seed for now\n        self._caching_pool = PJCachingPool()\n        self._pjmedia_endpoint = PJMEDIAEndpoint(self._caching_pool)\n        self._pjsip_endpoint = PJSIPEndpoint(self._caching_pool, kwargs[\"ip_address\"], kwargs[\"udp_port\"],\n                                             kwargs[\"tcp_port\"], kwargs[\"tls_port\"],\n                                             kwargs[\"tls_verify_server\"], kwargs[\"tls_ca_file\"],\n                                             kwargs[\"tls_cert_file\"], kwargs[\"tls_privkey_file\"], kwargs[\"tls_timeout\"])\n        status = pj_mutex_create_simple(self._pjsip_endpoint._pool, \"event_queue_lock\", &_event_queue_lock)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize event queue mutex\", status)\n        self._ip_address = kwargs[\"ip_address\"]\n        self.codecs = kwargs[\"codecs\"]\n        self.video_codecs = kwargs[\"video_codecs\"]\n        self._module_name = PJSTR(\"mod-core\")\n        self._module.name = self._module_name.pj_str\n        self._module.id = -1\n        self._module.priority = PJSIP_MOD_PRIORITY_APPLICATION\n        self._module.on_rx_request = _PJSIPUA_cb_rx_request\n        self._module.on_tsx_state = _Request_cb_tsx_state\n        status = pjsip_endpt_register_module(self._pjsip_endpoint._obj, &self._module)\n        if status != 0:\n            raise PJSIPError(\"Could not load application module\", status)\n        status = pjsip_endpt_add_capability(self._pjsip_endpoint._obj, &self._module,\n                                            PJSIP_H_ALLOW, NULL, 1, &message_method.pj_str)\n        if status != 0:\n            raise PJSIPError(\"Could not add MESSAGE method to supported methods\", status)\n        status = pjsip_endpt_add_capability(self._pjsip_endpoint._obj, &self._module,\n                                            PJSIP_H_ALLOW, NULL, 1, &refer_method.pj_str)\n        if status != 0:\n            raise PJSIPError(\"Could not add REFER method to supported methods\", status)\n        status = pjsip_endpt_add_capability(self._pjsip_endpoint._obj, NULL,\n                                            PJSIP_H_SUPPORTED, NULL, 1, &str_norefersub.pj_str)\n        if status != 0:\n            raise PJSIPError(\"Could not add 'norefsub' to Supported header\", status)\n        status = pjsip_endpt_add_capability(self._pjsip_endpoint._obj, NULL,\n                                            PJSIP_H_SUPPORTED, NULL, 1, &str_gruu.pj_str)\n        if status != 0:\n            raise PJSIPError(\"Could not add 'gruu' to Supported header\", status)\n        self._trace_sip = int(bool(kwargs[\"trace_sip\"]))\n        self._detect_sip_loops = int(bool(kwargs[\"detect_sip_loops\"]))\n        self._enable_colorbar_device = int(bool(kwargs[\"enable_colorbar_device\"]))\n        self._opus_fix_module_name = PJSTR(\"mod-core-opus-fix\")\n        self._opus_fix_module.name = self._opus_fix_module_name.pj_str\n        self._opus_fix_module.id = -1\n        self._opus_fix_module.priority = PJSIP_MOD_PRIORITY_TRANSPORT_LAYER+1\n        self._opus_fix_module.on_rx_request = _cb_opus_fix_rx\n        self._opus_fix_module.on_rx_response = _cb_opus_fix_rx\n        self._opus_fix_module.on_tx_request = _cb_opus_fix_tx\n        self._opus_fix_module.on_tx_response = _cb_opus_fix_tx\n        status = pjsip_endpt_register_module(self._pjsip_endpoint._obj, &self._opus_fix_module)\n        if status != 0:\n            raise PJSIPError(\"Could not load opus-fix module\", status)\n        self._trace_module_name = PJSTR(\"mod-core-sip-trace\")\n        self._trace_module.name = self._trace_module_name.pj_str\n        self._trace_module.id = -1\n        self._trace_module.priority = 0\n        self._trace_module.on_rx_request = _cb_trace_rx\n        self._trace_module.on_rx_response = _cb_trace_rx\n        self._trace_module.on_tx_request = _cb_trace_tx\n        self._trace_module.on_tx_response = _cb_trace_tx\n        status = pjsip_endpt_register_module(self._pjsip_endpoint._obj, &self._trace_module)\n        if status != 0:\n            raise PJSIPError(\"Could not load sip trace module\", status)\n        self._ua_tag_module_name = PJSTR(\"mod-core-ua-tag\")\n        self._ua_tag_module.name = self._ua_tag_module_name.pj_str\n        self._ua_tag_module.id = -1\n        self._ua_tag_module.priority = PJSIP_MOD_PRIORITY_TRANSPORT_LAYER+1\n        self._ua_tag_module.on_tx_request = _cb_add_user_agent_hdr\n        self._ua_tag_module.on_tx_response = _cb_add_server_hdr\n        status = pjsip_endpt_register_module(self._pjsip_endpoint._obj, &self._ua_tag_module)\n        if status != 0:\n            raise PJSIPError(\"Could not load User-Agent/Server header tagging module\", status)\n        self._event_module_name = PJSTR(\"mod-core-events\")\n        self._event_module.name = self._event_module_name.pj_str\n        self._event_module.id = -1\n        self._event_module.priority = PJSIP_MOD_PRIORITY_DIALOG_USAGE\n        status = pjsip_endpt_register_module(self._pjsip_endpoint._obj, &self._event_module)\n        if status != 0:\n            raise PJSIPError(\"Could not load events module\", status)\n        status = pjmedia_aud_dev_set_observer_cb(_cb_audio_dev_process_event);\n        if status != 0:\n            raise PJSIPError(\"Could not set audio_change callbacks\", status)\n        status = pj_rwmutex_create(self._pjsip_endpoint._pool, \"ua_audio_change_rwlock\", &self.audio_change_rwlock)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize audio change rwmutex\", status)\n        status = pj_mutex_create_recursive(self._pjsip_endpoint._pool, \"ua_video_lock\", &self.video_lock)\n        if status != 0:\n            raise PJSIPError(\"Could not initialize video mutex\", status)\n        self._user_agent = PJSTR(kwargs[\"user_agent\"])\n        for event, accept_types in kwargs[\"events\"].iteritems():\n            self.add_event(event, accept_types)\n        for event in kwargs[\"incoming_events\"]:\n            if event not in self._events.iterkeys():\n                raise ValueError('Event \"%s\" is not known' % event)\n            self._incoming_events.add(event)\n        for method in kwargs[\"incoming_requests\"]:\n            method = method.upper()\n            if method in (\"ACK\", \"BYE\", \"INVITE\", \"REFER\", \"SUBSCRIBE\"):\n                raise ValueError('Handling incoming \"%s\" requests is not allowed' % method)\n            self._incoming_requests.add(method)\n        self.rtp_port_range = kwargs[\"rtp_port_range\"]\n        self.zrtp_cache = kwargs[\"zrtp_cache\"]\n        pj_stun_config_init(&self._stun_cfg, &self._caching_pool._obj.factory, 0,\n                            pjmedia_endpt_get_ioqueue(self._pjmedia_endpoint._obj),\n                            pjsip_endpt_get_timer_heap(self._pjsip_endpoint._obj))\n\n    property trace_sip:\n\n        def __get__(self):\n            self._check_self()\n            return bool(self._trace_sip)\n\n        def __set__(self, value):\n            self._check_self()\n            self._trace_sip = int(bool(value))\n\n    property detect_sip_loops:\n\n        def __get__(self):\n            self._check_self()\n            return bool(self._detect_sip_loops)\n\n        def __set__(self, value):\n            self._check_self()\n            self._detect_sip_loops = int(bool(value))\n\n    property enable_colorbar_device:\n\n        def __get__(self):\n            self._check_self()\n            return bool(self._enable_colorbar_device)\n\n        def __set__(self, value):\n            self._check_self()\n            self._enable_colorbar_device = int(bool(value))\n            self.refresh_video_devices()\n\n    property events:\n\n        def __get__(self):\n            self._check_self()\n            return self._events.copy()\n\n    property ip_address:\n\n        def __get__(self):\n            self._check_self()\n            return self._ip_address\n\n    def add_event(self, object event, list accept_types):\n        cdef pj_str_t event_pj\n        cdef pj_str_t accept_types_pj[PJSIP_MAX_ACCEPT_COUNT]\n        cdef int index\n        cdef object accept_type\n        cdef int accept_cnt = len(accept_types)\n        cdef int status\n        self._check_self()\n        if accept_cnt == 0:\n            raise SIPCoreError(\"Need at least one of accept_types\")\n        if accept_cnt > PJSIP_MAX_ACCEPT_COUNT:\n            raise SIPCoreError(\"Too many accept_types\")\n        _str_to_pj_str(event, &event_pj)\n        for index, accept_type in enumerate(accept_types):\n            _str_to_pj_str(accept_type, &accept_types_pj[index])\n        status = pjsip_evsub_register_pkg(&self._event_module, &event_pj, 3600, accept_cnt, accept_types_pj)\n        if status != 0:\n            raise PJSIPError(\"Could not register event package\", status)\n        self._events[event] = accept_types[:]\n\n    property incoming_events:\n\n        def __get__(self):\n            self._check_self()\n            return self._incoming_events.copy()\n\n    def add_incoming_event(self, str event):\n        self._check_self()\n        if event not in self._events.iterkeys():\n            raise ValueError('Event \"%s\" is not known' % event)\n        self._incoming_events.add(event)\n\n    def remove_incoming_event(self, str event):\n        self._check_self()\n        if event not in self._events.iterkeys():\n            raise ValueError('Event \"%s\" is not known' % event)\n        self._incoming_events.discard(event)\n\n    property incoming_requests:\n\n        def __get__(self):\n            self._check_self()\n            return self._incoming_requests.copy()\n\n    def add_incoming_request(self, object value):\n        cdef str method\n        self._check_self()\n        method = value.upper()\n        if method in (\"ACK\", \"BYE\", \"INVITE\", \"REFER\", \"SUBSCRIBE\"):\n            raise ValueError('Handling incoming \"%s\" requests is not allowed' % method)\n        self._incoming_requests.add(method)\n\n    def remove_incoming_request(self, object value):\n        cdef str method\n        self._check_self()\n        method = value.upper()\n        if method in (\"ACK\", \"BYE\", \"INVITE\", \"REFER\", \"SUBSCRIBE\"):\n            raise ValueError('Handling incoming \"%s\" requests is not allowed' % method)\n        self._incoming_requests.discard(method)\n\n    cdef pj_pool_t* create_memory_pool(self, bytes name, int initial_size, int resize_size):\n        cdef pj_pool_t *pool\n        cdef char *c_pool_name\n        cdef pjsip_endpoint *endpoint\n\n        c_pool_name = name\n        endpoint = self._pjsip_endpoint._obj\n\n        with nogil:\n            pool = pjsip_endpt_create_pool(endpoint, c_pool_name, initial_size, resize_size)\n        if pool == NULL:\n            raise SIPCoreError(\"Could not allocate memory pool\")\n        return pool\n\n    cdef void release_memory_pool(self, pj_pool_t* pool):\n        cdef pjsip_endpoint *endpoint\n        endpoint = self._pjsip_endpoint._obj\n\n        if pool != NULL:\n            with nogil:\n                pjsip_endpt_release_pool(endpoint, pool)\n\n    cdef void reset_memory_pool(self, pj_pool_t* pool):\n        if pool != NULL:\n            with nogil:\n                pj_pool_reset(pool)\n\n    cdef object _get_sound_devices(self, int is_output):\n        cdef int count\n        cdef pjmedia_aud_dev_info info\n        cdef list retval = list()\n        cdef int status\n\n        with nogil:\n            status = pj_rwmutex_lock_read(self.audio_change_rwlock)\n        if status != 0:\n            raise PJSIPError('Could not acquire audio_change_rwlock', status)\n        try:\n            for i in range(pjmedia_aud_dev_count()):\n                with nogil:\n                    status = pjmedia_aud_dev_get_info(i, &info)\n                if status != 0:\n                    raise PJSIPError(\"Could not get audio device info\", status)\n                if is_output:\n                    count = info.output_count\n                else:\n                    count = info.input_count\n                if count:\n                    retval.append(decode_device_name(info.name))\n            return retval\n        finally:\n            pj_rwmutex_unlock_read(self.audio_change_rwlock)\n\n    cdef object _get_default_sound_device(self, int is_output):\n        cdef pjmedia_aud_dev_info info\n        cdef int dev_id\n        cdef int status\n        with nogil:\n            status = pj_rwmutex_lock_read(self.audio_change_rwlock)\n        if status != 0:\n            raise SIPCoreError('Could not acquire audio_change_rwlock', status)\n        try:\n            if is_output:\n                dev_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV\n            else:\n                dev_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV\n            with nogil:\n                status = pjmedia_aud_dev_get_info(dev_id, &info)\n            if status != 0:\n                raise PJSIPError(\"Could not get audio device info\", status)\n            return decode_device_name(info.name)\n        finally:\n            pj_rwmutex_unlock_read(self.audio_change_rwlock)\n\n\n    property default_output_device:\n\n        def __get__(self):\n            self._check_self()\n            return self._get_default_sound_device(1)\n\n    property default_input_device:\n\n        def __get__(self):\n            self._check_self()\n            return self._get_default_sound_device(0)\n\n    property output_devices:\n\n        def __get__(self):\n            self._check_self()\n            return self._get_sound_devices(1)\n\n    property input_devices:\n\n        def __get__(self):\n            self._check_self()\n            return self._get_sound_devices(0)\n\n    property sound_devices:\n\n        def __get__(self):\n            self._check_self()\n            cdef int count\n            cdef pjmedia_aud_dev_info info\n            cdef list retval = list()\n            cdef int status\n\n            with nogil:\n                status = pj_rwmutex_lock_read(self.audio_change_rwlock)\n            if status != 0:\n                raise SIPCoreError('Could not acquire audio_change_rwlock', status)\n            try:\n                for i in range(pjmedia_aud_dev_count()):\n                    with nogil:\n                        status = pjmedia_aud_dev_get_info(i, &info)\n                    if status == 0:\n                        retval.append(decode_device_name(info.name))\n                return retval\n            finally:\n                pj_rwmutex_unlock_read(self.audio_change_rwlock)\n\n    def refresh_sound_devices(self):\n        self._check_self()\n        cdef int status\n        cdef dict event_dict\n\n        self.old_devices = self.sound_devices\n        with nogil:\n            status = pj_rwmutex_lock_write(self.audio_change_rwlock)\n        if status != 0:\n            raise SIPCoreError('Could not acquire audio_change_rwlock', status)\n        with nogil:\n            pjmedia_aud_dev_refresh()\n            status = pj_rwmutex_unlock_write(self.audio_change_rwlock)\n        if status != 0:\n            raise SIPCoreError('Could not release audio_change_rwlock', status)\n        event_dict = dict()\n        event_dict[\"old_devices\"] = self.old_devices\n        event_dict[\"new_devices\"] = self.sound_devices\n        _add_event(\"AudioDevicesDidChange\", event_dict)\n\n    cdef object _get_video_devices(self):\n        cdef pjmedia_vid_dev_info info\n        cdef list retval = list()\n        cdef int direction\n        cdef int status\n\n        for i in range(pjmedia_vid_dev_count()):\n            with nogil:\n                status = pjmedia_vid_dev_get_info(i, &info)\n            if status != 0:\n                raise PJSIPError(\"Could not get video device info\", status)\n            direction = info.dir\n            if direction in (PJMEDIA_DIR_CAPTURE, PJMEDIA_DIR_CAPTURE_PLAYBACK):\n                if (not self._enable_colorbar_device and bytes(info.driver) == \"Colorbar\") or bytes(info.driver) == \"Null\":\n                    continue\n                retval.append(decode_device_name(info.name))\n        return retval\n\n    cdef object _get_default_video_device(self):\n        cdef pjmedia_vid_dev_info info\n        cdef int status\n\n        with nogil:\n            status = pjmedia_vid_dev_get_info(PJMEDIA_VID_DEFAULT_CAPTURE_DEV, &info)\n        if status != 0:\n            raise PJSIPError(\"Could not get default video device info\", status)\n        if (not self._enable_colorbar_device and bytes(info.driver) == \"Colorbar\") or bytes(info.driver) == \"Null\":\n            raise SIPCoreError(\"Could not get default video device\")\n        return decode_device_name(info.name)\n\n    def refresh_video_devices(self):\n        self._check_self()\n        cdef int status\n        cdef dict event_dict\n\n        self.old_video_devices = self.video_devices\n        with nogil:\n            pjmedia_vid_dev_refresh()\n        event_dict = dict()\n        event_dict[\"old_devices\"] = self.old_video_devices\n        event_dict[\"new_devices\"] = self.video_devices\n        _add_event(\"VideoDevicesDidChange\", event_dict)\n\n    property default_video_device:\n\n        def __get__(self):\n            self._check_self()\n            return self._get_default_video_device()\n\n    property video_devices:\n\n        def __get__(self):\n            self._check_self()\n            return self._get_video_devices()\n\n    property available_codecs:\n\n        def __get__(self):\n            self._check_self()\n            return self._pjmedia_endpoint._get_all_codecs()\n\n    property codecs:\n\n        def __get__(self):\n            self._check_self()\n            return self._pjmedia_endpoint._get_current_codecs()\n\n        def __set__(self, value):\n            self._check_self()\n            self._pjmedia_endpoint._set_codecs(value)\n\n    property available_video_codecs:\n\n        def __get__(self):\n            self._check_self()\n            return self._pjmedia_endpoint._get_all_video_codecs()\n\n    property video_codecs:\n\n        def __get__(self):\n            self._check_self()\n            return self._pjmedia_endpoint._get_current_video_codecs()\n\n        def __set__(self, value):\n            self._check_self()\n            self._pjmedia_endpoint._set_video_codecs(value)\n\n    property udp_port:\n\n        def __get__(self):\n            self._check_self()\n            if self._pjsip_endpoint._udp_transport == NULL:\n                return None\n            return self._pjsip_endpoint._udp_transport.local_name.port\n\n    def set_udp_port(self, value):\n        cdef int port\n        self._check_self()\n        if value is None:\n            if self._pjsip_endpoint._udp_transport == NULL:\n                return\n            self._pjsip_endpoint._stop_udp_transport()\n        else:\n            port = value\n            if not (0 <= port <= 65535):\n                raise ValueError(\"Not a valid UDP port: %d\" % value)\n            if self._pjsip_endpoint._udp_transport != NULL:\n                if port == self._pjsip_endpoint._udp_transport.local_name.port:\n                    return\n                self._pjsip_endpoint._stop_udp_transport()\n            self._pjsip_endpoint._start_udp_transport(port)\n\n    property tcp_port:\n\n        def __get__(self):\n            self._check_self()\n            if self._pjsip_endpoint._tcp_transport == NULL:\n                return None\n            return self._pjsip_endpoint._tcp_transport.addr_name.port\n\n    def set_tcp_port(self, value):\n        cdef int port\n        self._check_self()\n        if value is None:\n            if self._pjsip_endpoint._tcp_transport == NULL:\n                return\n            self._pjsip_endpoint._stop_tcp_transport()\n        else:\n            port = value\n            if not (0 <= port <= 65535):\n                raise ValueError(\"Not a valid TCP port: %d\" % value)\n            if self._pjsip_endpoint._tcp_transport != NULL:\n                if port == self._pjsip_endpoint._tcp_transport.addr_name.port:\n                    return\n                self._pjsip_endpoint._stop_tcp_transport()\n            self._pjsip_endpoint._start_tcp_transport(port)\n\n    property tls_port:\n\n        def __get__(self):\n            self._check_self()\n            if self._pjsip_endpoint._tls_transport == NULL:\n                return None\n            return self._pjsip_endpoint._tls_transport.addr_name.port\n\n    property rtp_port_range:\n\n        def __get__(self):\n            self._check_self()\n            return (self._rtp_port_start, self._rtp_port_start + self._rtp_port_count)\n\n        def __set__(self, value):\n            cdef int _rtp_port_start\n            cdef int _rtp_port_stop\n            cdef int _rtp_port_count\n            cdef int _rtp_port_usable_count\n            cdef int port\n            self._check_self()\n            for port in value:\n                if not (0 <= port <= 65535):\n                    raise SIPCoreError(\"RTP port range values should be between 0 and 65535\")\n            _rtp_port_start, _rtp_port_stop = value\n            _rtp_port_count = _rtp_port_stop - _rtp_port_start\n            _rtp_port_usable_count = _rtp_port_count - _rtp_port_count % 2 # we need an even number of ports, so we won't use the last one if an odd number is provided\n            if _rtp_port_usable_count < 2:\n                raise SIPCoreError(\"RTP port range should contain at least 2 ports\")\n            self._rtp_port_start = _rtp_port_start\n            self._rtp_port_count = _rtp_port_count\n            self._rtp_port_usable_count = _rtp_port_usable_count\n            self._rtp_port_index = 0\n\n    property user_agent:\n\n        def __get__(self):\n            self._check_self()\n            return self._user_agent.str\n\n        def __set__(self, value):\n            self._check_self()\n            self._user_agent = PJSTR(\"value\")\n\n    property log_level:\n\n        def __get__(self):\n            self._check_self()\n            return pj_log_get_level()\n\n        def __set__(self, value):\n            self._check_self()\n            if value < 0 or value > PJ_LOG_MAX_LEVEL:\n                raise ValueError(\"Log level should be between 0 and %d\" % PJ_LOG_MAX_LEVEL)\n            pj_log_set_level(value)\n\n    property tls_verify_server:\n\n        def __get__(self):\n            self._check_self()\n            return bool(self._pjsip_endpoint._tls_verify_server)\n\n    property tls_ca_file:\n\n        def __get__(self):\n            self._check_self()\n            if self._pjsip_endpoint._tls_ca_file is None:\n                return None\n            else:\n                return self._pjsip_endpoint._tls_ca_file.str\n\n    property tls_cert_file:\n\n        def __get__(self):\n            self._check_self()\n            if self._pjsip_endpoint._tls_cert_file is None:\n                return None\n            else:\n                return self._pjsip_endpoint._tls_cert_file.str\n\n    property tls_privkey_file:\n\n        def __get__(self):\n            self._check_self()\n            if self._pjsip_endpoint._tls_privkey_file is None:\n                return None\n            else:\n                return self._pjsip_endpoint._tls_privkey_file.str\n\n    property tls_timeout:\n\n        def __get__(self):\n            self._check_self()\n            return self._pjsip_endpoint._tls_timeout\n\n    def set_tls_options(self, port=None, verify_server=False,\n                        ca_file=None, cert_file=None, privkey_file=None, int timeout=3000):\n        cdef int c_port\n        self._check_self()\n        if port is None:\n            if self._pjsip_endpoint._tls_transport == NULL:\n                return\n            self._pjsip_endpoint._stop_tls_transport()\n        else:\n            c_port = port\n            if not (0 <= c_port <= 65535):\n                raise ValueError(\"Not a valid TCP port: %d\" % port)\n            if ca_file is not None and not os.path.isfile(ca_file):\n                raise ValueError(\"Cannot find the specified CA file: %s\" % ca_file)\n            if cert_file is not None and not os.path.isfile(cert_file):\n                raise ValueError(\"Cannot find the specified certificate file: %s\" % cert_file)\n            if privkey_file is not None and not os.path.isfile(privkey_file):\n                raise ValueError(\"Cannot find the specified private key file: %s\" % privkey_file)\n            if timeout < 0:\n                raise ValueError(\"Invalid TLS timeout value: %d\" % timeout)\n            if self._pjsip_endpoint._tls_transport != NULL:\n                self._pjsip_endpoint._stop_tls_transport()\n            self._pjsip_endpoint._tls_verify_server = int(bool(verify_server))\n            if ca_file is None:\n                self._pjsip_endpoint._tls_ca_file = None\n            else:\n                self._pjsip_endpoint._tls_ca_file = PJSTR(ca_file.encode(sys.getfilesystemencoding()))\n            if cert_file is None:\n                self._pjsip_endpoint._tls_cert_file = None\n            else:\n                self._pjsip_endpoint._tls_cert_file = PJSTR(cert_file.encode(sys.getfilesystemencoding()))\n            if privkey_file is None:\n                self._pjsip_endpoint._tls_privkey_file = None\n            else:\n                self._pjsip_endpoint._tls_privkey_file = PJSTR(privkey_file.encode(sys.getfilesystemencoding()))\n            self._pjsip_endpoint._tls_timeout = timeout\n            self._pjsip_endpoint._start_tls_transport(c_port)\n\n    def detect_nat_type(self, stun_server_address, stun_server_port=PJ_STUN_PORT, object user_data=None):\n        cdef pj_str_t stun_server_address_pj\n        cdef pj_sockaddr_in stun_server\n        cdef int status\n        self._check_self()\n        if not _is_valid_ip(pj_AF_INET(), stun_server_address):\n            raise ValueError(\"Not a valid IPv4 address: %s\" % stun_server_address)\n        _str_to_pj_str(stun_server_address, &stun_server_address_pj)\n        status = pj_sockaddr_in_init(&stun_server, &stun_server_address_pj, stun_server_port)\n        if status != 0:\n            raise PJSIPError(\"Could not init STUN server address\", status)\n        status = pj_stun_detect_nat_type(&stun_server, &self._stun_cfg, <void *> user_data, _cb_detect_nat_type)\n        if status != 0:\n            raise PJSIPError(\"Could not start NAT type detection\", status)\n        Py_INCREF(user_data)\n\n    def set_nameservers(self, list nameservers):\n        self._check_self()\n        return self._pjsip_endpoint._set_dns_nameservers([n for n in nameservers if _re_ipv4.match(n)])\n\n    def set_h264_options(self, profile, level):\n        self._check_self()\n        self._pjmedia_endpoint._set_h264_options(str(profile), int(level.replace('.', '')))\n\n    def set_video_options(self, max_resolution, int max_framerate, object max_bitrate):\n        self._check_self()\n        self._pjmedia_endpoint._set_video_options(tuple(max_resolution),\n                                                  max_framerate,\n                                                  max_bitrate or 0.0)\n\n    property zrtp_cache:\n\n        def __get__(self):\n            self._check_self()\n            return self._zrtp_cache\n\n        def __set__(self, value):\n            self._check_self()\n            if value is None:\n                value = os.path.join(tempfile.gettempdir(), 'zrtp_cache_%d.db' % os.getpid())\n            self._zrtp_cache = value\n\n    def __dealloc__(self):\n        self.dealloc()\n\n    def dealloc(self):\n        global _ua, _dealloc_handler_queue, _event_queue_lock\n        if _ua == NULL:\n            return\n        self._check_thread()\n        pjmedia_aud_dev_set_observer_cb(NULL)\n        if self.audio_change_rwlock != NULL:\n            pj_rwmutex_destroy(self.audio_change_rwlock)\n            self.audio_change_rwlock = NULL\n        if self.video_lock != NULL:\n            pj_mutex_destroy(self.video_lock)\n            self.video_lock = NULL\n        _process_handler_queue(self, &_dealloc_handler_queue)\n        if _event_queue_lock != NULL:\n            pj_mutex_lock(_event_queue_lock)\n            pj_mutex_destroy(_event_queue_lock)\n            _event_queue_lock = NULL\n        self._pjsip_endpoint = None\n        self._pjmedia_endpoint = None\n        self._caching_pool = None\n        self._pjlib = None\n        _ua = NULL\n        self._poll_log()\n\n    cdef int _poll_log(self) except -1:\n        cdef object event_name\n        cdef dict event_params\n        cdef list events\n        events = _get_clear_event_queue()\n        for event_name, event_params in events:\n            self._event_handler(event_name, **event_params)\n\n    def poll(self):\n        global _post_poll_handler_queue\n        cdef int status\n        cdef double now\n        cdef object retval = None\n        cdef float max_timeout\n        cdef pj_time_val pj_max_timeout\n        cdef list timers\n        cdef Timer timer\n\n        self._check_self()\n\n        max_timeout = 0.100\n        while self._timers:\n            if not (<Timer>self._timers[0])._scheduled:\n                # timer was cancelled\n                heapq.heappop(self._timers)\n            else:\n                max_timeout = min(max((<Timer>self._timers[0]).schedule_time - time.time(), 0.0), max_timeout)\n                break\n        pj_max_timeout.sec = int(max_timeout)\n        pj_max_timeout.msec = int(max_timeout * 1000) % 1000\n        with nogil:\n            status = pjsip_endpt_handle_events(self._pjsip_endpoint._obj, &pj_max_timeout)\n        IF UNAME_SYSNAME == \"Darwin\":\n            if status not in [0, PJ_ERRNO_START_SYS + errno.EBADF]:\n                raise PJSIPError(\"Error while handling events\", status)\n        ELSE:\n            if status != 0:\n                raise PJSIPError(\"Error while handling events\", status)\n        _process_handler_queue(self, &_post_poll_handler_queue)\n\n        timers = list()\n        now = time.time()\n        while self._timers:\n            if not (<Timer>self._timers[0])._scheduled:\n                # timer was cancelled\n                heapq.heappop(self._timers)\n            elif (<Timer>self._timers[0]).schedule_time <= now:\n                # timer needs to be processed\n                timer = heapq.heappop(self._timers)\n                timers.append(timer)\n            else:\n                break\n        for timer in timers:\n            timer.call()\n\n        self._poll_log()\n        if self._fatal_error:\n            return True\n        else:\n            return False\n\n    cdef int _handle_exception(self, int is_fatal) except -1:\n        cdef object exc_type\n        cdef object exc_val\n        cdef object exc_tb\n        exc_type, exc_val, exc_tb = sys.exc_info()\n        if is_fatal:\n            self._fatal_error = is_fatal\n        _add_event(\"SIPEngineGotException\",\n                    dict(type=exc_type, value=exc_val,\n                         traceback=\"\".join(traceback.format_exception(exc_type, exc_val, exc_tb))))\n        return 0\n\n    cdef int _check_self(self) except -1:\n        global _ua\n        if _ua == NULL:\n            raise SIPCoreError(\"The PJSIPUA is no longer running\")\n        self._check_thread()\n\n    cdef int _check_thread(self) except -1:\n        if not pj_thread_is_registered():\n            self._threads.append(PJSIPThread())\n        return 0\n\n    cdef int _add_timer(self, Timer timer) except -1:\n        heapq.heappush(self._timers, timer)\n        return 0\n\n    cdef int _remove_timer(self, Timer timer) except -1:\n        # Don't remove it from the heap, just mark it as not scheduled\n        timer._scheduled = 0\n        return 0\n\n    cdef int _cb_rx_request(self, pjsip_rx_data *rdata) except 0:\n        global _event_hdr_name\n        cdef int status\n        cdef int bad_request\n        cdef pjsip_tx_data *tdata = NULL\n        cdef pjsip_hdr_ptr_const hdr_add\n        cdef IncomingRequest request\n        cdef Invitation inv\n        cdef IncomingSubscription sub\n        cdef IncomingReferral ref\n        cdef list extra_headers\n        cdef dict event_dict\n        cdef dict message_params\n        cdef pj_str_t tsx_key\n        cdef pjsip_via_hdr *top_via\n        cdef pjsip_via_hdr *via\n        cdef pjsip_transaction *tsx = NULL\n        cdef unsigned int options = PJSIP_INV_SUPPORT_100REL\n        cdef pjsip_event_hdr *event_hdr\n        cdef object method_name = _pj_str_to_str(rdata.msg_info.msg.line.req.method.name)\n        if method_name != \"ACK\":\n            if self._detect_sip_loops:\n                # Temporarily trick PJSIP into believing the last Via header is actually the first\n                top_via = via = rdata.msg_info.via\n                while True:\n                    rdata.msg_info.via = via\n                    via = <pjsip_via_hdr *> pjsip_msg_find_hdr(rdata.msg_info.msg, PJSIP_H_VIA, (<pj_list *> via).next)\n                    if via == NULL:\n                        break\n                status = pjsip_tsx_create_key(rdata.tp_info.pool, &tsx_key,\n                                              PJSIP_ROLE_UAC, &rdata.msg_info.msg.line.req.method, rdata)\n                rdata.msg_info.via = top_via\n                if status != 0:\n                    raise PJSIPError(\"Could not generate transaction key for incoming request\", status)\n                tsx = pjsip_tsx_layer_find_tsx(&tsx_key, 0)\n        if tsx != NULL:\n            status = pjsip_endpt_create_response(self._pjsip_endpoint._obj, rdata, 482, NULL, &tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not create response\", status)\n        elif method_name in self._incoming_requests:\n            request = IncomingRequest()\n            request.init(self, rdata)\n        elif method_name == \"OPTIONS\":\n            status = pjsip_endpt_create_response(self._pjsip_endpoint._obj, rdata, 200, NULL, &tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not create response\", status)\n            for hdr_type in [PJSIP_H_ALLOW, PJSIP_H_ACCEPT, PJSIP_H_SUPPORTED]:\n                hdr_add = pjsip_endpt_get_capability(self._pjsip_endpoint._obj, hdr_type, NULL)\n                if hdr_add != NULL:\n                    pjsip_msg_add_hdr(tdata.msg, <pjsip_hdr *> pjsip_hdr_clone(tdata.pool, hdr_add))\n        elif method_name == \"INVITE\":\n            status = pjsip_inv_verify_request(rdata, &options, NULL, NULL, self._pjsip_endpoint._obj, &tdata)\n            if status == 0:\n                inv = Invitation()\n                inv.init_incoming(self, rdata, options)\n        elif method_name == \"SUBSCRIBE\":\n            event_hdr = <pjsip_event_hdr *> pjsip_msg_find_hdr_by_name(rdata.msg_info.msg, &_event_hdr_name.pj_str, NULL)\n            if event_hdr == NULL or _pj_str_to_str(event_hdr.event_type) not in self._incoming_events:\n                status = pjsip_endpt_create_response(self._pjsip_endpoint._obj, rdata, 489, NULL, &tdata)\n                if status != 0:\n                    raise PJSIPError(\"Could not create response\", status)\n            else:\n                sub = IncomingSubscription()\n                sub.init(self, rdata, _pj_str_to_str(event_hdr.event_type))\n        elif method_name == \"REFER\":\n            ref = IncomingReferral()\n            ref.init(self, rdata)\n        elif method_name == \"MESSAGE\":\n            bad_request = 0\n            extra_headers = list()\n            message_params = dict()\n            event_dict = dict()\n            _pjsip_msg_to_dict(rdata.msg_info.msg, event_dict)\n            message_params[\"request_uri\"] = event_dict[\"request_uri\"]\n            message_params[\"from_header\"] = event_dict[\"headers\"].get(\"From\", None)\n            message_params[\"to_header\"] = event_dict[\"headers\"].get(\"To\", None)\n            message_params[\"headers\"] = event_dict[\"headers\"]\n            message_params[\"body\"] = event_dict[\"body\"]\n            content_type = message_params[\"headers\"].get(\"Content-Type\", None)\n            if content_type is not None:\n                message_params[\"content_type\"] = content_type.content_type\n                if message_params[\"headers\"].get(\"Content-Length\", 0) > 0 and message_params[\"body\"] is None:\n                    bad_request = 1\n                    extra_headers.append(WarningHeader(399, \"local\", \"Missing body\"))\n            else:\n                message_params[\"content_type\"] = None\n                if message_params[\"headers\"].get(\"Content-Length\", 0) > 0 and message_params[\"body\"] is None:\n                    bad_request = 1\n                    extra_headers.append(WarningHeader(399, \"local\", \"Missing Content-Type header\"))\n            if bad_request:\n                status = pjsip_endpt_create_response(self._pjsip_endpoint._obj, rdata, 400, NULL, &tdata)\n                if status != 0:\n                    raise PJSIPError(\"Could not create response\", status)\n                _add_headers_to_tdata(tdata, extra_headers)\n            else:\n                _add_event(\"SIPEngineGotMessage\", message_params)\n                status = pjsip_endpt_create_response(self._pjsip_endpoint._obj, rdata, 200, NULL, &tdata)\n                if status != 0:\n                    raise PJSIPError(\"Could not create response\", status)\n        elif method_name != \"ACK\":\n            status = pjsip_endpt_create_response(self._pjsip_endpoint._obj, rdata, 405, NULL, &tdata)\n            if status != 0:\n                raise PJSIPError(\"Could not create response\", status)\n        if tdata != NULL:\n            status = pjsip_endpt_send_response2(self._pjsip_endpoint._obj, rdata, tdata, NULL, NULL)\n            if status != 0:\n                pjsip_tx_data_dec_ref(tdata)\n                raise PJSIPError(\"Could not send response\", status)\n        return 1\n\n\ncdef class PJSIPThread:\n    def __cinit__(self):\n        cdef object thread_name = \"python_%d\" % id(self)\n        cdef int status\n        status = pj_thread_register(thread_name, self._thread_desc, &self._obj)\n        if status != 0:\n            raise PJSIPError(\"Error while registering thread\", status)\n\n\n# callback functions\n\ncdef void _cb_audio_dev_process_event(pjmedia_aud_dev_event event) with gil:\n    cdef PJSIPUA ua\n    event_dict = dict()\n    try:\n       ua = _get_ua()\n    except:\n       return\n    try:\n        if event in (PJMEDIA_AUD_DEV_DEFAULT_INPUT_CHANGED, PJMEDIA_AUD_DEV_DEFAULT_OUTPUT_CHANGED):\n            event_dict[\"changed_input\"] = event == PJMEDIA_AUD_DEV_DEFAULT_INPUT_CHANGED\n            event_dict[\"changed_output\"] = event == PJMEDIA_AUD_DEV_DEFAULT_OUTPUT_CHANGED\n            _add_event(\"DefaultAudioDeviceDidChange\", event_dict)\n        elif event == PJMEDIA_AUD_DEV_LIST_WILL_REFRESH:\n            ua.old_devices = ua.sound_devices\n            with nogil:\n                status = pj_rwmutex_lock_write(ua.audio_change_rwlock)\n            if status != 0:\n                raise SIPCoreError('Could not acquire audio_change_rwlock for writing', status)\n        elif event == PJMEDIA_AUD_DEV_LIST_DID_REFRESH:\n            with nogil:\n                status = pj_rwmutex_unlock_write(ua.audio_change_rwlock)\n            if status != 0:\n                raise SIPCoreError('Could not release the audio_change_rwlock', status)\n            event_dict[\"old_devices\"] = ua.old_devices\n            event_dict[\"new_devices\"] = ua.sound_devices\n            _add_event(\"AudioDevicesDidChange\", event_dict)\n    except:\n        ua._handle_exception(1)\n\ncdef void _cb_detect_nat_type(void *user_data, pj_stun_nat_detect_result_ptr_const res) with gil:\n    cdef PJSIPUA ua\n    cdef dict event_dict\n    cdef object user_data_obj = <object> user_data\n    Py_DECREF(user_data_obj)\n    try:\n        ua = _get_ua()\n    except:\n        return\n    try:\n        event_dict = dict()\n        event_dict[\"succeeded\"] = res.status == 0\n        event_dict[\"user_data\"] = user_data_obj\n        if res.status == 0:\n            event_dict[\"nat_type\"] = res.nat_type_name\n        else:\n            event_dict[\"error\"] = res.status_text\n        _add_event(\"SIPEngineDetectedNATType\", event_dict)\n    except:\n        ua._handle_exception(0)\n\ncdef int _PJSIPUA_cb_rx_request(pjsip_rx_data *rdata) with gil:\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return 0\n    try:\n        return ua._cb_rx_request(rdata)\n    except:\n        ua._handle_exception(0)\n\ncdef int _cb_opus_fix_tx(pjsip_tx_data *tdata) with gil:\n    cdef PJSIPUA ua\n    cdef pjsip_msg_body *body\n    cdef pjsip_msg_body *new_body\n    cdef pjmedia_sdp_session *sdp\n    cdef pjmedia_sdp_media *media\n    cdef pjmedia_sdp_attr *attr\n    cdef int i\n    cdef int j\n    cdef pj_str_t new_value\n    try:\n        ua = _get_ua()\n    except:\n        return 0\n    try:\n        if tdata != NULL and tdata.msg != NULL:\n            body = tdata.msg.body\n            if body != NULL and _pj_str_to_str(body.content_type.type).lower() == \"application\" and _pj_str_to_str(body.content_type.subtype).lower() == \"sdp\":\n                new_body = pjsip_msg_body_clone(tdata.pool, body)\n                sdp = <pjmedia_sdp_session *> new_body.data\n                for i in range(sdp.media_count):\n                    media = sdp.media[i]\n                    if _pj_str_to_str(media.desc.media).lower() != \"audio\":\n                        continue\n                    for j in range(media.attr_count):\n                        attr = media.attr[j]\n                        if _pj_str_to_str(attr.name).lower() != \"rtpmap\":\n                            continue\n                        attr_value = _pj_str_to_str(attr.value).lower()\n                        pos = attr_value.find(\"opus\")\n                        if pos == -1:\n                            continue\n                        # this is the opus rtpmap attribute\n                        opus_line = attr_value[:pos] + \"opus/48000/2\"\n                        new_value.slen = len(opus_line)\n                        new_value.ptr = <char *> pj_pool_alloc(tdata.pool, new_value.slen)\n                        memcpy(new_value.ptr, PyString_AsString(opus_line), new_value.slen)\n                        attr.value = new_value\n                        break\n                tdata.msg.body = new_body\n    except:\n        ua._handle_exception(0)\n    return 0\n\ncdef int _cb_opus_fix_rx(pjsip_rx_data *rdata) with gil:\n    cdef PJSIPUA ua\n    cdef pjsip_msg_body *body\n    cdef int pos1\n    cdef int pos2\n    cdef char *body_ptr\n    try:\n        ua = _get_ua()\n    except:\n        return 0\n    try:\n        if rdata != NULL and rdata.msg_info.msg != NULL:\n            body = rdata.msg_info.msg.body\n            if body != NULL and _pj_str_to_str(body.content_type.type).lower() == \"application\" and _pj_str_to_str(body.content_type.subtype).lower() == \"sdp\":\n                body_ptr = <char*>body.data\n                body_str = PyString_FromStringAndSize(body_ptr, body.len).lower()\n                pos1 = body_str.find(\"opus/48000\")\n                if pos1 != -1:\n                    pos2 = body_str.find(\"opus/48000/2\")\n                    if pos2 != -1:\n                        memcpy(body_ptr + pos2 + 11, '1', 1)\n                    else:\n                        # old opus, we must make it fail\n                        memcpy(body_ptr + pos1 + 5, 'XXXXX', 5)\n    except:\n        ua._handle_exception(0)\n    return 0\n\ncdef int _cb_trace_rx(pjsip_rx_data *rdata) with gil:\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return 0\n    try:\n        if ua._trace_sip:\n            _add_event(\"SIPEngineSIPTrace\",\n                        dict(received=True, source_ip=rdata.pkt_info.src_name, source_port=rdata.pkt_info.src_port,\n                             destination_ip=_pj_str_to_str(rdata.tp_info.transport.local_name.host),\n                             destination_port=rdata.tp_info.transport.local_name.port,\n                             data=PyString_FromStringAndSize(rdata.pkt_info.packet, rdata.pkt_info.len),\n                             transport=rdata.tp_info.transport.type_name))\n    except:\n        ua._handle_exception(0)\n    return 0\n\ncdef int _cb_trace_tx(pjsip_tx_data *tdata) with gil:\n    cdef PJSIPUA ua\n    try:\n        ua = _get_ua()\n    except:\n        return 0\n    try:\n        if ua._trace_sip:\n            _add_event(\"SIPEngineSIPTrace\",\n                        dict(received=False,\n                             source_ip=_pj_str_to_str(tdata.tp_info.transport.local_name.host),\n                             source_port=tdata.tp_info.transport.local_name.port, destination_ip=tdata.tp_info.dst_name,\n                             destination_port=tdata.tp_info.dst_port,\n                             data=PyString_FromStringAndSize(tdata.buf.start, tdata.buf.cur - tdata.buf.start),\n                             transport=tdata.tp_info.transport.type_name))\n    except:\n        ua._handle_exception(0)\n    return 0\n\ncdef int _cb_add_user_agent_hdr(pjsip_tx_data *tdata) with gil:\n    cdef PJSIPUA ua\n    cdef pjsip_hdr *hdr\n    cdef void *found_hdr\n    try:\n        ua = _get_ua()\n    except:\n        return 0\n    try:\n        found_hdr = pjsip_msg_find_hdr_by_name(tdata.msg, &_user_agent_hdr_name.pj_str, NULL)\n        if found_hdr == NULL:\n            hdr = <pjsip_hdr *> pjsip_generic_string_hdr_create(tdata.pool, &_user_agent_hdr_name.pj_str,\n                                                                &ua._user_agent.pj_str)\n            if hdr == NULL:\n                raise SIPCoreError('Could not add \"User-Agent\" header to outgoing request')\n            pjsip_msg_add_hdr(tdata.msg, hdr)\n    except:\n        ua._handle_exception(0)\n    return 0\n\ncdef int _cb_add_server_hdr(pjsip_tx_data *tdata) with gil:\n    cdef PJSIPUA ua\n    cdef pjsip_hdr *hdr\n    cdef void *found_hdr\n    try:\n        ua = _get_ua()\n    except:\n        return 0\n    try:\n        found_hdr = pjsip_msg_find_hdr_by_name(tdata.msg, &_server_hdr_name.pj_str, NULL)\n        if found_hdr == NULL:\n            hdr = <pjsip_hdr *> pjsip_generic_string_hdr_create(tdata.pool, &_server_hdr_name.pj_str,\n                                                                &ua._user_agent.pj_str)\n            if hdr == NULL:\n                raise SIPCoreError('Could not add \"Server\" header to outgoing response')\n            pjsip_msg_add_hdr(tdata.msg, hdr)\n    except:\n        ua._handle_exception(0)\n    return 0\n\n# functions\n\ncdef PJSIPUA _get_ua():\n    global _ua\n    cdef PJSIPUA ua\n    if _ua == NULL:\n        raise SIPCoreError(\"PJSIPUA is not instantiated\")\n    ua = <object> _ua\n    ua._check_thread()\n    return ua\n\ncdef int deallocate_weakref(object weak_ref, object timer) except -1 with gil:\n    Py_DECREF(weak_ref)\n\n\n# globals\n\ncdef void *_ua = NULL\ncdef PJSTR _user_agent_hdr_name = PJSTR(\"User-Agent\")\ncdef PJSTR _server_hdr_name = PJSTR(\"Server\")\ncdef PJSTR _event_hdr_name = PJSTR(\"Event\")\ncdef object _re_ipv4 = re.compile(r\"^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$\")\n"
  },
  {
    "path": "sipsimple/core/_core.util.pxi",
    "content": "\nimport platform\nimport re\nimport sys\n\nfrom application.version import Version\n\n\ncdef class PJSTR:\n    def __cinit__(self, str):\n        self.str = str\n        _str_to_pj_str(str, &self.pj_str)\n\n    def __str__(self):\n        return self.str\n\n\ncdef class SIPStatusMessages:\n    cdef object _default_status\n\n    def __cinit__(self, *args, **kwargs):\n        self._default_status = _pj_str_to_str(pjsip_get_status_text(0)[0])\n\n    def __getitem__(self, int val):\n        cdef object _status\n        _status = _pj_str_to_str(pjsip_get_status_text(val)[0])\n        if _status == self._default_status:\n            raise IndexError(\"Unknown SIP response code: %d\" % val)\n        return _status\n\n\ncdef class frozenlist:\n    def __cinit__(self, *args, **kw):\n        self.list = list()\n        self.initialized = 0\n        self.hash = 0\n    def __init__(self, *args, **kw):\n        if not self.initialized:\n            self.list = list(*args, **kw)\n            self.initialized = 1\n            self.hash = hash(tuple(self.list))\n    def __reduce__(self):\n        return (self.__class__, (self.list,), None)\n    def __repr__(self):\n        return \"frozenlist(%r)\" % self.list\n    def __len__(self):\n        return self.list.__len__()\n    def __hash__(self):\n        return self.hash\n    def __iter__(self):\n        return self.list.__iter__()\n    def __cmp__(self, frozenlist other):\n        return self.list.__cmp__(other.list)\n    def __richcmp__(frozenlist self, other, op):\n        if isinstance(other, frozenlist):\n            other = (<frozenlist>other).list\n        if op == 0:\n            return self.list.__cmp__(other) < 0\n        elif op == 1:\n            return self.list.__cmp__(other) <= 0\n        elif op == 2:\n            return self.list.__eq__(other)\n        elif op == 3:\n            return self.list.__ne__(other)\n        elif op == 4:\n            return self.list.__cmp__(other) > 0\n        elif op == 5:\n            return self.list.__cmp__(other) >= 0\n        else:\n            return NotImplemented\n    def __contains__(self, item):\n        return self.list.__contains__(item)\n    def __getitem__(self, key):\n        return self.list.__getitem__(key)\n    def __add__(first, second):\n        if isinstance(first, frozenlist):\n            first = (<frozenlist>first).list\n        if isinstance(second, frozenlist):\n            second = (<frozenlist>second).list\n        return frozenlist(first+second)\n    def __mul__(first, second):\n        if isinstance(first, frozenlist):\n            first = (<frozenlist>first).list\n        if isinstance(second, frozenlist):\n            second = (<frozenlist>second).list\n        return frozenlist(first*second)\n    def __reversed__(self):\n        return self.list.__reversed__()\n    def count(self, elem):\n        return self.list.count(elem)\n    def index(self, elem):\n        return self.list.index(elem)\n\n\ncdef class frozendict:\n    def __cinit__(self, *args, **kw):\n        self.dict = dict()\n        self.initialized = 0\n    def __init__(self, *args, **kw):\n        if not self.initialized:\n            self.dict = dict(*args, **kw)\n            self.initialized = 1\n            self.hash = hash(tuple(self.dict.iteritems()))\n    def __reduce__(self):\n        return (self.__class__, (self.dict,), None)\n    def __repr__(self):\n        return \"frozendict(%r)\" % self.dict\n    def __len__(self):\n        return self.dict.__len__()\n    def __hash__(self):\n        return self.hash\n    def __iter__(self):\n        return self.dict.__iter__()\n    def __cmp__(self, frozendict other):\n        return self.dict.__cmp__(other.dict)\n    def __richcmp__(frozendict self, other, op):\n        if isinstance(other, frozendict):\n            other = (<frozendict>other).dict\n        if op == 0:\n            return self.dict.__cmp__(other) < 0\n        elif op == 1:\n            return self.dict.__cmp__(other) <= 0\n        elif op == 2:\n            return self.dict.__eq__(other)\n        elif op == 3:\n            return self.dict.__ne__(other)\n        elif op == 4:\n            return self.dict.__cmp__(other) > 0\n        elif op == 5:\n            return self.dict.__cmp__(other) >= 0\n        else:\n            return NotImplemented\n    def __contains__(self, item):\n        return self.dict.__contains__(item)\n    def __getitem__(self, key):\n        return self.dict.__getitem__(key)\n    def copy(self):\n        return self\n    def get(self, *args):\n        return self.dict.get(*args)\n    def has_key(self, key):\n        return self.dict.has_key(key)\n    def items(self):\n        return self.dict.items()\n    def iteritems(self):\n        return self.dict.iteritems()\n    def iterkeys(self):\n        return self.dict.iterkeys()\n    def itervalues(self):\n        return self.dict.itervalues()\n    def keys(self):\n        return self.dict.keys()\n    def values(self):\n        return self.dict.values()\n\n\n# functions\n\ncdef int _str_to_pj_str(object string, pj_str_t *pj_str) except -1:\n    pj_str.ptr = PyString_AsString(string)\n    pj_str.slen = len(string)\n\ncdef object _pj_str_to_str(pj_str_t pj_str):\n    return PyString_FromStringAndSize(pj_str.ptr, pj_str.slen)\n\ncdef object _pj_status_to_str(int status):\n    cdef char buf[PJ_ERR_MSG_SIZE]\n    return _pj_str_to_str(pj_strerror(status, buf, PJ_ERR_MSG_SIZE))\n\ncdef object _pj_status_to_def(int status):\n    return _re_pj_status_str_def.match(_pj_status_to_str(status)).group(1)\n\ncdef dict _pjsip_param_to_dict(pjsip_param *param_list):\n    cdef pjsip_param *param\n    cdef dict retval = dict()\n    param = <pjsip_param *> (<pj_list *> param_list).next\n    while param != param_list:\n        if param.value.slen == 0:\n            retval[_pj_str_to_str(param.name)] = None\n        else:\n            retval[_pj_str_to_str(param.name)] = _pj_str_to_str(param.value)\n        param = <pjsip_param *> (<pj_list *> param).next\n    return retval\n\ncdef int _dict_to_pjsip_param(object params, pjsip_param *param_list, pj_pool_t *pool):\n    cdef pjsip_param *param = NULL\n    for name, value in params.iteritems():\n        param = <pjsip_param *> pj_pool_alloc(pool, sizeof(pjsip_param))\n        if param == NULL:\n            return -1\n        _str_to_pj_str(name, &param.name)\n        if value is None:\n            param.value.slen = 0\n        else:\n            _str_to_pj_str(value, &param.value)\n        pj_list_insert_after(<pj_list *> param_list, <pj_list *> param)\n    return 0\n\ncdef int _pjsip_msg_to_dict(pjsip_msg *msg, dict info_dict) except -1:\n    cdef pjsip_msg_body *body\n    cdef pjsip_hdr *header\n    cdef pjsip_generic_array_hdr *array_header\n    cdef pjsip_ctype_hdr *ctype_header\n    cdef pjsip_cseq_hdr *cseq_header\n    cdef char *buf\n    cdef int buf_len, i, status\n    headers = {}\n    header = <pjsip_hdr *> (<pj_list *> &msg.hdr).next\n    while header != &msg.hdr:\n        header_name = _pj_str_to_str(header.name)\n        header_data = None\n        multi_header = False\n        if header_name in (\"Accept\", \"Allow\", \"Require\", \"Supported\", \"Unsupported\", \"Allow-Events\"):\n            array_header = <pjsip_generic_array_hdr *> header\n            header_data = []\n            for i from 0 <= i < array_header.count:\n                header_data.append(_pj_str_to_str(array_header.values[i]))\n        elif header_name == \"Contact\":\n            multi_header = True\n            header_data = FrozenContactHeader_create(<pjsip_contact_hdr *> header)\n        elif header_name == \"Content-Length\":\n            header_data = (<pjsip_clen_hdr *> header).len\n        elif header_name == \"Content-Type\":\n            header_data = FrozenContentTypeHeader_create(<pjsip_ctype_hdr *> header)\n        elif header_name == \"CSeq\":\n            cseq_header = <pjsip_cseq_hdr *> header\n            header_data = (cseq_header.cseq, _pj_str_to_str(cseq_header.method.name))\n        elif header_name in (\"Expires\", \"Max-Forwards\", \"Min-Expires\"):\n            header_data = (<pjsip_generic_int_hdr *> header).ivalue\n        elif header_name == \"From\":\n            header_data = FrozenFromHeader_create(<pjsip_fromto_hdr *> header)\n        elif header_name == \"To\":\n            header_data = FrozenToHeader_create(<pjsip_fromto_hdr *> header)\n        elif header_name == \"Route\":\n            multi_header = True\n            header_data = FrozenRouteHeader_create(<pjsip_routing_hdr *> header)\n        elif header_name == \"Reason\":\n            value = _pj_str_to_str((<pjsip_generic_string_hdr *>header).hvalue)\n            protocol, sep, params_str = value.partition(';')\n            params = frozendict([(name, value or None) for name, sep, value in [param.partition('=') for param in params_str.split(';')]])\n            header_data = FrozenReasonHeader(protocol, params)\n        elif header_name == \"Record-Route\":\n            multi_header = True\n            header_data = FrozenRecordRouteHeader_create(<pjsip_routing_hdr *> header)\n        elif header_name == \"Retry-After\":\n            header_data = FrozenRetryAfterHeader_create(<pjsip_retry_after_hdr *> header)\n        elif header_name == \"Via\":\n            multi_header = True\n            header_data = FrozenViaHeader_create(<pjsip_via_hdr *> header)\n        elif header_name == \"Warning\":\n            match = _re_warning_hdr.match(_pj_str_to_str((<pjsip_generic_string_hdr *>header).hvalue))\n            if match is not None:\n                warning_params = match.groupdict()\n                warning_params['code'] = int(warning_params['code'])\n                header_data = FrozenWarningHeader(**warning_params)\n        elif header_name == \"Event\":\n            header_data = FrozenEventHeader_create(<pjsip_event_hdr *> header)\n        elif header_name == \"Subscription-State\":\n            header_data = FrozenSubscriptionStateHeader_create(<pjsip_sub_state_hdr *> header)\n        elif header_name == \"Refer-To\":\n            header_data = FrozenReferToHeader_create(<pjsip_generic_string_hdr *> header)\n        elif header_name == \"Subject\":\n            header_data = FrozenSubjectHeader_create(<pjsip_generic_string_hdr *> header)\n        elif header_name == \"Replaces\":\n            header_data = FrozenReplacesHeader_create(<pjsip_replaces_hdr *> header)\n        # skip the following headers:\n        elif header_name not in (\"Authorization\", \"Proxy-Authenticate\", \"Proxy-Authorization\", \"WWW-Authenticate\"):\n            header_data = FrozenHeader(header_name, _pj_str_to_str((<pjsip_generic_string_hdr *> header).hvalue))\n        if header_data is not None:\n            if multi_header:\n                headers.setdefault(header_name, []).append(header_data)\n            else:\n                if header_name not in headers:\n                    headers[header_name] = header_data\n        header = <pjsip_hdr *> (<pj_list *> header).next\n    info_dict[\"headers\"] = headers\n    body = msg.body\n    if body == NULL:\n        info_dict[\"body\"] = None\n    else:\n        status = pjsip_print_body(body, &buf, &buf_len)\n        if status != 0:\n            info_dict[\"body\"] = None\n        else:\n            info_dict[\"body\"] = PyString_FromStringAndSize(buf, buf_len)\n    if msg.type == PJSIP_REQUEST_MSG:\n        info_dict[\"method\"] = _pj_str_to_str(msg.line.req.method.name)\n        # You need to call pjsip_uri_get_uri on the request URI if the message is for transmitting,\n        # but it isn't required if message is one received. Otherwise, a seg fault occurs. Don't ask.\n        info_dict[\"request_uri\"] = FrozenSIPURI_create(<pjsip_sip_uri*>pjsip_uri_get_uri(msg.line.req.uri))\n    else:\n        info_dict[\"code\"] = msg.line.status.code\n        info_dict[\"reason\"] = _pj_str_to_str(msg.line.status.reason)\n    return 0\n\ncdef int _is_valid_ip(int af, object ip) except -1:\n    cdef char buf[16]\n    cdef pj_str_t src\n    cdef int status\n    _str_to_pj_str(ip, &src)\n    status = pj_inet_pton(af, &src, buf)\n    if status == 0:\n        return 1\n    else:\n        return 0\n\ncdef int _get_ip_version(object ip) except -1:\n    if _is_valid_ip(pj_AF_INET(), ip):\n        return pj_AF_INET()\n    elif _is_valid_ip(pj_AF_INET6(), ip):\n        return pj_AF_INET()\n    else:\n        return 0\n\ncdef int _add_headers_to_tdata(pjsip_tx_data *tdata, object headers) except -1:\n    cdef pj_str_t name_pj, value_pj\n    cdef pjsip_hdr *hdr\n    for header in headers:\n        _str_to_pj_str(header.name, &name_pj)\n        _str_to_pj_str(header.body, &value_pj)\n        hdr = <pjsip_hdr *> pjsip_generic_string_hdr_create(tdata.pool, &name_pj, &value_pj)\n        pjsip_msg_add_hdr(tdata.msg, hdr)\n\ncdef int _remove_headers_from_tdata(pjsip_tx_data *tdata, object headers) except -1:\n    cdef pj_str_t header_name_pj\n    cdef pjsip_hdr *hdr\n    for header in headers:\n        _str_to_pj_str(header, &header_name_pj)\n        hdr = <pjsip_hdr *> pjsip_msg_find_remove_hdr_by_name(tdata.msg, &header_name_pj, NULL)\n\ncdef int _BaseSIPURI_to_pjsip_sip_uri(BaseSIPURI uri, pjsip_sip_uri *pj_uri, pj_pool_t *pool) except -1:\n    cdef pjsip_param *param\n    pjsip_sip_uri_init(pj_uri, uri.secure)\n    if uri.user:\n        _str_to_pj_str(uri.user, &pj_uri.user)\n    if uri.password:\n        _str_to_pj_str(uri.password, &pj_uri.passwd)\n    if uri.host:\n        _str_to_pj_str(uri.host, &pj_uri.host)\n    if uri.port:\n        pj_uri.port = uri.port\n    for name, value in uri.parameters.iteritems():\n        if name == \"lr\":\n            pj_uri.lr_param = 1\n        elif name == \"maddr\":\n            _str_to_pj_str(value, &pj_uri.maddr_param)\n        elif name == \"method\":\n            _str_to_pj_str(value, &pj_uri.method_param)\n        elif name == \"transport\":\n            _str_to_pj_str(value, &pj_uri.transport_param)\n        elif name == \"ttl\":\n            pj_uri.ttl_param = int(value)\n        elif name == \"user\":\n            _str_to_pj_str(value, &pj_uri.user_param)\n        else:\n            param = <pjsip_param *> pj_pool_alloc(pool, sizeof(pjsip_param))\n            _str_to_pj_str(name, &param.name)\n            if value is None:\n                param.value.slen = 0\n            else:\n                _str_to_pj_str(value, &param.value)\n            pj_list_insert_after(<pj_list *> &pj_uri.other_param, <pj_list *> param)\n    _dict_to_pjsip_param(uri.headers, &pj_uri.header_param, pool)\n    return 0\n\ncdef int _BaseRouteHeader_to_pjsip_route_hdr(BaseIdentityHeader header, pjsip_route_hdr *pj_header, pj_pool_t *pool) except -1:\n    cdef pjsip_param *param\n    cdef pjsip_sip_uri *sip_uri\n    pjsip_route_hdr_init(NULL, <void *> pj_header)\n    sip_uri = <pjsip_sip_uri *> pj_pool_alloc(pool, sizeof(pjsip_sip_uri))\n    _BaseSIPURI_to_pjsip_sip_uri(header.uri, sip_uri, pool)\n    pj_header.name_addr.uri = <pjsip_uri *> sip_uri\n    if header.display_name:\n        _str_to_pj_str(header.display_name.encode('utf-8'), &pj_header.name_addr.display)\n    _dict_to_pjsip_param(header.parameters, &pj_header.other_param, pool)\n    return 0\n\ndef _get_device_name_encoding():\n    if sys.platform == 'win32':\n        encoding = 'mbcs'\n    elif sys.platform.startswith('linux2') and Version.parse(platform.release()) < Version(2,6,31):\n        encoding = 'latin1'\n    else:\n        encoding = 'utf-8'\n    return encoding\n_device_name_encoding = _get_device_name_encoding()\n\ndef decode_device_name(device_name):\n    # ignore decoding errors, some systems (I'm looking at you, OSX), seem to misbehave\n    return device_name.decode(_device_name_encoding, 'ignore')\n\n\n# globals\n\ncdef object _re_pj_status_str_def = re.compile(\"^.*\\((.*)\\)$\")\ncdef object _re_warning_hdr = re.compile('(?P<code>[0-9]{3}) (?P<agent>.*?) \"(?P<text>.*?)\"')\nsip_status_messages = SIPStatusMessages()\n\n"
  },
  {
    "path": "sipsimple/core/_core.video.pxi",
    "content": "\nimport weakref\n\n\ncdef class VideoProducer:\n\n    def __init__(self):\n        self._consumers = set()\n\n    def __cinit__(self, *args, **kwargs):\n        cdef PJSIPUA ua\n        cdef pj_pool_t *pool\n        cdef int status\n        cdef bytes lock_name, pool_name\n\n        ua = _get_ua()\n        lock_name = b\"VideoProducer_lock_%d\" % id(self)\n        pool_name = b\"VideoProducer_pool_%d\" % id(self)\n\n        pool = ua.create_memory_pool(pool_name, 4096, 4096)\n        self._pool = pool\n\n        status = pj_mutex_create_recursive(pool, lock_name, &self._lock)\n        if status != 0:\n            raise PJSIPError(\"Could not create lock\", status)\n        self._running = 0\n        self._started = 0\n        self._closed = 0\n\n    def __dealloc__(self):\n        # cython will always call the __dealloc__ method of the parent class *after* the child's\n        # __dealloc__ was executed\n        cdef PJSIPUA ua\n        try:\n            ua = _get_ua()\n        except:\n            return\n        if self._lock != NULL:\n            pj_mutex_destroy(self._lock)\n        ua.release_memory_pool(self._pool)\n\n    property consumers:\n\n        def __get__(self):\n            cdef pj_mutex_t *lock\n            lock = self._lock\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                return self._consumers.copy()\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property closed:\n\n        def __get__(self):\n            cdef pj_mutex_t *lock\n            lock = self._lock\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                return bool(self._closed)\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    cdef void _add_consumer(self, VideoConsumer consumer):\n        raise NotImplementedError\n\n    cdef void _remove_consumer(self, VideoConsumer consumer):\n        raise NotImplementedError\n\n    def start(self):\n        raise NotImplementedError\n\n    def stop(self):\n        raise NotImplementedError\n\n    def close(self):\n        raise NotImplementedError\n\n\ncdef class VideoConsumer:\n\n    def __init__(self):\n        self._producer = None\n\n    def __cinit__(self, *args, **kwargs):\n        cdef PJSIPUA ua\n        cdef pj_pool_t *pool\n        cdef int status\n        cdef bytes lock_name, pool_name\n\n        self.weakref = weakref.ref(self)\n        Py_INCREF(self.weakref)\n\n        ua = _get_ua()\n        lock_name = b\"VideoConsumer_lock_%d\" % id(self)\n        pool_name = b\"VideoConsumer_pool_%d\" % id(self)\n\n        pool = ua.create_memory_pool(pool_name, 4096, 4096)\n        self._pool = pool\n\n        status = pj_mutex_create_recursive(pool, lock_name, &self._lock)\n        if status != 0:\n            raise PJSIPError(\"Could not create lock\", status)\n        self._running = 0\n        self._closed = 0\n\n    def __dealloc__(self):\n        # cython will always call the __dealloc__ method of the parent class *after* the child's\n        # __dealloc__ was executed\n        cdef PJSIPUA ua\n        cdef Timer timer\n        try:\n            ua = _get_ua()\n        except:\n            return\n        if self._lock != NULL:\n            pj_mutex_destroy(self._lock)\n        ua.release_memory_pool(self._pool)\n        timer = Timer()\n        try:\n            timer.schedule(60, deallocate_weakref, self.weakref)\n        except SIPCoreError:\n            pass\n\n    property producer:\n\n        def __get__(self):\n            cdef pj_mutex_t *lock\n            lock = self._lock\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self._closed:\n                    return None\n                return self._producer\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n        def __set__(self, value):\n            cdef PJSIPUA ua\n            cdef pj_mutex_t *global_lock\n            cdef pj_mutex_t *lock\n\n            try:\n                ua = _get_ua()\n            except:\n                return\n\n            global_lock = ua.video_lock\n            lock = self._lock\n\n            with nogil:\n                status = pj_mutex_lock(global_lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire global video lock\", status)\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                pj_mutex_unlock(global_lock)\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                if self._closed:\n                    return\n                self._set_producer(value)\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n                    pj_mutex_unlock(global_lock)\n\n    property closed:\n\n        def __get__(self):\n            cdef pj_mutex_t *lock\n            lock = self._lock\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            try:\n                return bool(self._closed)\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    cdef void _set_producer(self, VideoProducer producer):\n        # Called to set producer, which can be None. Must set self._producer.\n        # No need to hold the lock or check for closed state.\n        raise NotImplementedError\n\n    def close(self):\n        raise NotImplementedError\n\n\ncdef class VideoCamera(VideoProducer):\n    # NOTE: we use a video tee to be able to send the video to multiple consumers at the same\n    # time. The video tee, however, is not thread-safe, so we need to make sure the source port\n    # is stopped before adding or removing a destination port.\n\n    def __init__(self, unicode device, object resolution, int fps):\n        cdef pjmedia_vid_port_param vp_param\n        cdef pjmedia_vid_dev_info vdi\n        cdef pjmedia_vid_port *video_port\n        cdef pjmedia_port *video_tee\n        cdef pjmedia_format fmt\n        cdef pj_mutex_t *lock\n        cdef pj_pool_t *pool\n        cdef int status\n        cdef int device_id\n        cdef int dev_count\n        cdef int width\n        cdef int height\n        cdef PJSIPUA ua\n\n        super(VideoCamera, self).__init__()\n\n        ua = _get_ua()\n        lock = self._lock\n        pool = self._pool\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._video_port != NULL:\n                raise SIPCoreError(\"VideoCamera.__init__() was already called\")\n\n            dev_count = pjmedia_vid_dev_count()\n            if dev_count == 0:\n                raise SIPCoreError(\"no video devices available\")\n\n            if device is None:\n                status = pjmedia_vid_dev_lookup(\"Null\", \"Null video device\", &device_id)\n                if status != 0:\n                    raise PJSIPError(\"Could not get capture video device index\", status)\n            else:\n                device_id = PJMEDIA_VID_DEFAULT_CAPTURE_DEV\n                # Find the device matching the name\n                if device != u\"system_default\":\n                    for i in range(dev_count):\n                        with nogil:\n                            status = pjmedia_vid_dev_get_info(i, &vdi)\n                        if status != 0:\n                            continue\n                        if vdi.dir in (PJMEDIA_DIR_CAPTURE, PJMEDIA_DIR_CAPTURE_PLAYBACK) and decode_device_name(vdi.name) == device:\n                            device_id = vdi.id\n                            break\n\n            with nogil:\n                status = pjmedia_vid_dev_get_info(device_id, &vdi)\n            if status != 0:\n                raise PJSIPError(\"Could not get video device info\", status)\n\n            if not ua.enable_colorbar_device and bytes(vdi.driver) == \"Colorbar\":\n                raise SIPCoreError(\"no video devices available\")\n\n            if bytes(vdi.driver) in (\"Colorbar\", \"Null\"):\n                # override camera fps\n                fps = 5\n\n            self.name = device\n            self.real_name = decode_device_name(vdi.name) if device is not None else None\n\n            pjmedia_vid_port_param_default(&vp_param)\n            with nogil:\n                status = pjmedia_vid_dev_default_param(pool, device_id, &vp_param.vidparam)\n            if status != 0:\n                raise PJSIPError(\"Could not get video device default parameters\", status)\n\n            # Create capture video port\n            vp_param.active = 1\n            vp_param.vidparam.dir = PJMEDIA_DIR_CAPTURE\n            # Set maximum possible resolution\n            vp_param.vidparam.fmt.det.vid.size.w = resolution.width\n            vp_param.vidparam.fmt.det.vid.size.h = resolution.height\n            # Set maximum fps\n            vp_param.vidparam.fmt.det.vid.fps.num = fps\n            vp_param.vidparam.fmt.det.vid.fps.denum = 1\n            with nogil:\n                status = pjmedia_vid_port_create(pool, &vp_param, &video_port)\n            if status != 0:\n                raise PJSIPError(\"Could not create capture video port\", status)\n            self._video_port = video_port\n\n            # Get format info\n            fmt = vp_param.vidparam.fmt\n\n            # Create video tee\n            with nogil:\n                status = pjmedia_vid_tee_create(pool, &fmt, 255, &video_tee)\n            if status != 0:\n                raise PJSIPError(\"Could not create video tee\", status)\n            self._video_tee = video_tee\n\n            # Connect capture and video tee ports\n            with nogil:\n                status = pjmedia_vid_port_connect(video_port, video_tee, 0)\n            if status != 0:\n                raise PJSIPError(\"Could not connect video capture and tee ports\", status)\n            self.producer_port = self._video_tee\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    property framerate:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock\n            cdef pjmedia_vid_dev_stream *stream\n            cdef pjmedia_vid_dev_param param\n            cdef PJSIPUA ua\n\n            ua = _get_ua()\n            lock = self._lock\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            if self._closed:\n                return None\n            stream = pjmedia_vid_port_get_stream(self._video_port)\n            if stream == NULL:\n                return None\n            try:\n                with nogil:\n                    status = pjmedia_vid_dev_stream_get_param(stream, &param)\n                if status != 0:\n                    return None\n                return float(param.fmt.det.vid.fps.num) / param.fmt.det.vid.fps.denum\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property framesize:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock\n            cdef pjmedia_vid_dev_stream *stream\n            cdef pjmedia_vid_dev_param param\n            cdef PJSIPUA ua\n\n            ua = _get_ua()\n            lock = self._lock\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            if self._closed:\n                return (-1, -1)\n            stream = pjmedia_vid_port_get_stream(self._video_port)\n            if stream == NULL:\n                return (-1, -1)\n            try:\n                with nogil:\n                    status = pjmedia_vid_dev_stream_get_param(stream, &param)\n                if status != 0:\n                    return (-1, -1)\n                return (param.fmt.det.vid.size.w, param.fmt.det.vid.size.h)\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    def start(self):\n        cdef int status\n        cdef pj_mutex_t *lock\n\n        lock = self._lock\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._closed:\n                raise SIPCoreError(\"video device is closed\")\n            if self._started:\n                return\n            if self._consumers:\n                self._start()\n            self._started = 1\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def stop(self):\n        cdef int status\n        cdef pj_mutex_t *lock\n\n        lock = self._lock\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._closed:\n                raise SIPCoreError(\"video device is closed\")\n            if not self._started:\n                return\n            self._stop()\n            self._started = 0\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    def close(self):\n        cdef int status\n        cdef pj_mutex_t *lock\n        cdef pj_mutex_t *global_lock\n        cdef PJSIPUA ua\n\n        try:\n            ua = _get_ua()\n        except:\n            return\n\n        global_lock = ua.video_lock\n        lock = self._lock\n\n        with nogil:\n            status = pj_mutex_lock(global_lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire global video lock\", status)\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            pj_mutex_unlock(global_lock)\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._closed:\n                return\n            self.stop()\n            for c in self._consumers.copy():\n                c.producer = None\n            self._closed = 1\n            if self._video_port != NULL:\n                with nogil:\n                    pjmedia_vid_port_stop(self._video_port)\n                    pjmedia_vid_port_disconnect(self._video_port)\n                    pjmedia_vid_port_destroy(self._video_port)\n                    if self._video_tee != NULL:\n                        pjmedia_port_destroy(self._video_tee)\n                self._video_port = NULL\n                self._video_tee = NULL\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n                pj_mutex_unlock(global_lock)\n\n    cdef void _add_consumer(self, VideoConsumer consumer):\n        cdef int status\n        cdef pj_mutex_t *lock\n        cdef pjmedia_port *consumer_port\n        cdef pjmedia_port *producer_port\n\n        lock = self._lock\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._closed:\n                raise SIPCoreError(\"video device is closed\")\n            if consumer in self._consumers:\n                return\n            consumer_port = consumer.consumer_port\n            producer_port = self.producer_port\n            with nogil:\n                status = pjmedia_vid_tee_add_dst_port2(producer_port, 0, consumer_port)\n            if status != 0:\n                raise PJSIPError(\"Could not connect video consumer with producer\", status)\n            self._consumers.add(consumer)\n            if self._started:\n                self._start()\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    cdef void _remove_consumer(self, VideoConsumer consumer):\n        cdef int status\n        cdef pj_mutex_t *lock\n\n        lock = self._lock\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._closed:\n                raise SIPCoreError(\"video device is closed\")\n            if consumer not in self._consumers:\n                return\n            consumer_port = consumer.consumer_port\n            producer_port = self.producer_port\n            with nogil:\n                status = pjmedia_vid_tee_remove_dst_port(producer_port, consumer_port)\n            if status != 0:\n                raise PJSIPError(\"Could not disconnect video consumer from producer\", status)\n            self._consumers.remove(consumer)\n            if not self._consumers:\n                self._stop()\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    cdef void _start(self):\n        # No need to hold the lock, this function is always called with it held\n        if self._running:\n            return\n        _start_video_port(self._video_port)\n        self._running = 1\n\n    cdef void _stop(self):\n        # No need to hold the lock, this function is always called with it held\n        if not self._running:\n            return\n        _stop_video_port(self._video_port)\n        self._running = 0\n\n    def __dealloc__(self):\n        self.close()\n\n\ncdef class LocalVideoStream(VideoConsumer):\n\n    cdef void _initialize(self, pjmedia_port *media_port):\n        self.consumer_port = media_port\n        self._running = 1\n        self._closed = 0\n\n    cdef void _set_producer(self, VideoProducer producer):\n        old_producer = self._producer\n        if old_producer is producer:\n            return\n        if old_producer is not None and not old_producer.closed:\n            old_producer._remove_consumer(self)\n        self._producer = producer\n        if producer is not None:\n            producer._add_consumer(self)\n\n    def close(self):\n        cdef int status\n        cdef pj_mutex_t *global_lock\n        cdef pj_mutex_t *lock\n        cdef PJSIPUA ua\n\n        try:\n            ua = _get_ua()\n        except:\n            return\n\n        global_lock = ua.video_lock\n        lock = self._lock\n\n        with nogil:\n            status = pj_mutex_lock(global_lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire global video lock\", status)\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            pj_mutex_unlock(global_lock)\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._closed:\n                return\n            self._set_producer(None)\n            self._closed = 1\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n                pj_mutex_unlock(global_lock)\n\n\ncdef LocalVideoStream_create(pjmedia_vid_stream *stream):\n    cdef pjmedia_port *media_port\n    cdef int status\n\n    with nogil:\n        status = pjmedia_vid_stream_get_port(stream, PJMEDIA_DIR_ENCODING, &media_port)\n    if status != 0:\n        raise PJSIPError(\"failed to get video stream port\", status)\n    if media_port == NULL:\n        raise ValueError(\"invalid media port\")\n\n    obj = LocalVideoStream()\n    obj._initialize(media_port)\n    return obj\n\n\ncdef class RemoteVideoStream(VideoProducer):\n\n    def __init__(self, object event_handler=None):\n        super(RemoteVideoStream, self).__init__()\n        if event_handler is not None and not callable(event_handler):\n            raise TypeError(\"event_handler must be a callable or None\")\n        self._event_handler = event_handler\n\n    cdef void _initialize(self, pjmedia_vid_stream *stream):\n        cdef pjmedia_port *media_port\n        cdef int status\n        cdef void* ptr\n\n        with nogil:\n            status = pjmedia_vid_stream_get_port(stream, PJMEDIA_DIR_DECODING, &media_port)\n        if status != 0:\n            raise PJSIPError(\"failed to get video stream port\", status)\n        if media_port == NULL:\n            raise ValueError(\"invalid media port\")\n        self._video_stream = stream\n\n        ptr = <void*>self\n        with nogil:\n            pjmedia_event_subscribe(NULL, &RemoteVideoStream_on_event, ptr, media_port);\n\n        # TODO: we cannot use a tee here, because the remote video is a passive port, we have a pjmedia_port, not a\n        # pjmedia_vid_port, so, for now, only one consumer is allowed\n        self.producer_port = media_port\n        self._running = 1\n        self._closed = 0\n\n    property framerate:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock\n            cdef pjmedia_vid_stream *stream\n            cdef pjmedia_vid_stream_info info\n            cdef PJSIPUA ua\n\n            ua = _get_ua()\n            lock = self._lock\n            stream = self._video_stream\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            if self._closed:\n                return 0\n            try:\n                with nogil:\n                    status = pjmedia_vid_stream_get_info(stream, &info)\n                if status != 0:\n                    return 0\n                return float(info.codec_param.dec_fmt.det.vid.fps.num) / info.codec_param.dec_fmt.det.vid.fps.denum\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    property framesize:\n\n        def __get__(self):\n            cdef int status\n            cdef pj_mutex_t *lock\n            cdef pjmedia_vid_stream *stream\n            cdef pjmedia_vid_stream_info info\n            cdef PJSIPUA ua\n\n            ua = _get_ua()\n            lock = self._lock\n            stream = self._video_stream\n\n            with nogil:\n                status = pj_mutex_lock(lock)\n            if status != 0:\n                raise PJSIPError(\"failed to acquire lock\", status)\n            if self._closed:\n                return (-1, -1)\n            try:\n                with nogil:\n                    status = pjmedia_vid_stream_get_info(stream, &info)\n                if status != 0:\n                    return (-1, -1)\n                return (info.codec_param.dec_fmt.det.vid.size.w, info.codec_param.dec_fmt.det.vid.size.h)\n            finally:\n                with nogil:\n                    pj_mutex_unlock(lock)\n\n    def start(self):\n        pass\n\n    def stop(self):\n        pass\n\n    def close(self):\n        cdef int status\n        cdef pj_mutex_t *global_lock\n        cdef pj_mutex_t *lock\n        cdef PJSIPUA ua\n        cdef VideoConsumer consumer\n        cdef void* ptr\n        cdef pjmedia_port *media_port\n\n        try:\n            ua = _get_ua()\n        except:\n            return\n\n        global_lock = ua.video_lock\n        lock = self._lock\n\n        with nogil:\n            status = pj_mutex_lock(global_lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire global video lock\", status)\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            pj_mutex_unlock(global_lock)\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._closed:\n                return\n            if self._consumers:\n                consumer = self._consumers.pop()\n                consumer.producer = None\n            ptr = <void*>self\n            media_port = self.producer_port\n            with nogil:\n                pjmedia_event_unsubscribe(NULL, &RemoteVideoStream_on_event, ptr, media_port)\n            self._closed = 1\n            self._event_handler = None\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n                pj_mutex_unlock(global_lock)\n\n    cdef void _add_consumer(self, VideoConsumer consumer):\n        cdef int status\n        cdef pj_mutex_t *lock\n        cdef pjmedia_port *producer_port\n        cdef pjmedia_vid_port *consumer_port\n        cdef PJSIPUA ua\n\n        ua = _get_ua()\n        lock = self._lock\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._closed:\n                raise SIPCoreError(\"producer is closed\")\n            if consumer in self._consumers:\n                return\n            if self._consumers:\n                raise SIPCoreError(\"another consumer is already attached to this producer\")\n            consumer_port = consumer._video_port\n            producer_port = self.producer_port\n            with nogil:\n                status = pjmedia_vid_port_connect(consumer_port, producer_port, 0)\n            if status != 0:\n                raise PJSIPError(\"Could not connect video consumer with producer\", status)\n            self._consumers.add(consumer)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    cdef void _remove_consumer(self, VideoConsumer consumer):\n        cdef int status\n        cdef pj_mutex_t *lock\n        cdef PJSIPUA ua\n        cdef pjmedia_vid_port *consumer_port\n\n        ua = _get_ua()\n        lock = self._lock\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._closed:\n                raise SIPCoreError(\"producer is closed\")\n            if consumer not in self._consumers:\n                return\n            consumer_port = consumer._video_port\n            with nogil:\n                status = pjmedia_vid_port_disconnect(consumer_port)\n            if status != 0:\n                raise PJSIPError(\"Could not disconnect video consumer from producer\", status)\n            self._consumers.remove(consumer)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n\ncdef class FrameBufferVideoRenderer(VideoConsumer):\n\n    def __init__(self, frame_handler):\n        super(FrameBufferVideoRenderer, self).__init__()\n        if not callable(frame_handler):\n            raise TypeError('frame_handler must be callable')\n        self._frame_handler = frame_handler\n\n    cdef _initialize(self, VideoProducer producer):\n        cdef pjmedia_vid_port_param vp_param\n        cdef pjmedia_vid_port *video_port\n        cdef pjmedia_vid_dev_stream *video_stream\n        cdef pjmedia_format fmt\n        cdef pjmedia_port *consumer_port\n        cdef pj_pool_t *pool\n        cdef pj_mutex_t *lock\n        cdef int status\n        cdef int index\n        cdef void *ptr\n\n        lock = self._lock\n        pool = self._pool\n\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._video_port != NULL:\n                raise RuntimeError(\"object already initialized\")\n\n            if not isinstance(producer, (VideoCamera, RemoteVideoStream)):\n                raise TypeError(\"unsupported producer type: %s\" % producer.__class__)\n\n            status = pjmedia_vid_dev_lookup(\"FrameBuffer\", \"FrameBuffer renderer\", &index)\n            if status != 0:\n                raise PJSIPError(\"Could not get render video device index\", status)\n            pjmedia_vid_port_param_default(&vp_param)\n            with nogil:\n                status = pjmedia_vid_dev_default_param(pool, index, &vp_param.vidparam)\n            if status != 0:\n                raise PJSIPError(\"Could not get render video device default parameters\", status)\n            fmt = producer.producer_port.info.fmt\n            vp_param.active = 0 if isinstance(producer, VideoCamera) else 1\n            vp_param.vidparam.dir = PJMEDIA_DIR_RENDER;\n            vp_param.vidparam.fmt = fmt\n            vp_param.vidparam.disp_size = fmt.det.vid.size\n            vp_param.vidparam.flags = 0\n\n            with nogil:\n                status = pjmedia_vid_port_create(pool, &vp_param, &video_port)\n            if status != 0:\n                raise PJSIPError(\"Could not create consumer video port\", status)\n            self._video_port = video_port\n\n            if not vp_param.active:\n                with nogil:\n                    consumer_port = pjmedia_vid_port_get_passive_port(video_port)\n                if consumer_port == NULL:\n                    raise SIPCoreError(\"Could not get passive video port\")\n            else:\n                consumer_port = NULL\n            self.consumer_port = consumer_port\n\n            with nogil:\n                video_stream = pjmedia_vid_port_get_stream(video_port)\n            if video_stream == NULL:\n                raise SIPCoreError(\"invalid video device stream\")\n            self._video_stream = video_stream\n\n            ptr = <void*>self.weakref\n            status = pjmedia_vid_dev_fb_set_callback(video_stream, FrameBufferVideoRenderer_frame_handler, ptr)\n            if status != 0:\n                raise PJSIPError(\"Could not set frame handler callback\", status)\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n\n    cdef void _set_producer(self, VideoProducer producer):\n        old_producer = self._producer\n        if old_producer is producer:\n            return\n\n        if old_producer is not None:\n            self._stop()\n            old_producer._remove_consumer(self)\n            self._destroy_video_port()\n\n        self._producer = producer\n\n        if producer is not None:\n            self._initialize(producer)\n            producer._add_consumer(self)\n            self._start()\n\n    def close(self):\n        cdef int status\n        cdef pj_mutex_t *global_lock\n        cdef pj_mutex_t *lock\n        cdef PJSIPUA ua\n        cdef void* ptr\n\n        try:\n            ua = _get_ua()\n        except:\n            return\n\n        global_lock = ua.video_lock\n        lock = self._lock\n\n        with nogil:\n            status = pj_mutex_lock(global_lock)\n        if status != 0:\n            raise PJSIPError(\"failed to acquire global video lock\", status)\n        with nogil:\n            status = pj_mutex_lock(lock)\n        if status != 0:\n            pj_mutex_unlock(global_lock)\n            raise PJSIPError(\"failed to acquire lock\", status)\n        try:\n            if self._closed:\n                return\n            self._set_producer(None)\n            self._stop()\n            self._closed = 1\n            self._destroy_video_port()\n            self._frame_handler = None\n        finally:\n            with nogil:\n                pj_mutex_unlock(lock)\n                pj_mutex_unlock(global_lock)\n\n    cdef void _destroy_video_port(self):\n        # No need to hold the lock, this function is always called with it held\n        cdef pjmedia_vid_port *video_port\n        video_port = self._video_port\n        if video_port != NULL:\n            with nogil:\n                pjmedia_vid_port_stop(video_port)\n                pjmedia_vid_port_disconnect(video_port)\n                pjmedia_vid_port_destroy(video_port)\n        self._video_port = NULL\n\n    cdef void _start(self):\n        # No need to hold the lock, this function is always called with it held\n        if self._running:\n            return\n        _start_video_port(self._video_port)\n        self._running = 1\n\n    cdef void _stop(self):\n        # No need to hold the lock, this function is always called with it held\n        if not self._running:\n            return\n        _stop_video_port(self._video_port)\n        self._running = 0\n\n    def __dealloc__(self):\n        self.close()\n\n\ncdef RemoteVideoStream_create(pjmedia_vid_stream *stream, format_change_handler=None):\n    obj = RemoteVideoStream(format_change_handler)\n    obj._initialize(stream)\n    return obj\n\n\ncdef void _start_video_port(pjmedia_vid_port *port):\n    cdef int status\n    with nogil:\n        status = pjmedia_vid_port_start(port)\n    if status != 0:\n        raise PJSIPError(\"Could not start video port\", status)\n\n\ncdef void _stop_video_port(pjmedia_vid_port *port):\n    cdef int status\n    with nogil:\n        status = pjmedia_vid_port_stop(port)\n    if status != 0:\n        raise PJSIPError(\"Could not stop video port\", status)\n\n\ncdef class VideoFrame:\n\n    def __init__(self, str data, int width, int height):\n        self.data = data\n        self.width = width\n        self.height = height\n\n    property size:\n\n        def __get__(self):\n            return (self.width, self.height)\n\n\ncdef void FrameBufferVideoRenderer_frame_handler(pjmedia_frame_ptr_const frame, pjmedia_rect_size size, void *user_data) with gil:\n    cdef PJSIPUA ua\n    cdef FrameBufferVideoRenderer rend\n    try:\n        ua = _get_ua()\n    except:\n        return\n    if user_data == NULL:\n        return\n    rend = (<object> user_data)()\n    if rend is None:\n        return\n    if rend._frame_handler is not None:\n        data = PyString_FromStringAndSize(<char*>frame.buf, frame.size)\n        rend._frame_handler(VideoFrame(data, size.w, size.h))\n\n\ncdef int RemoteVideoStream_on_event(pjmedia_event *event, void *user_data) with gil:\n    cdef PJSIPUA ua\n    cdef RemoteVideoStream stream\n    cdef pjmedia_format fmt\n\n    try:\n        ua = _get_ua()\n    except:\n        return 0\n    if user_data == NULL:\n        return 0\n    stream = <object>user_data\n    if stream._event_handler is not None:\n        if event.type == PJMEDIA_EVENT_FMT_CHANGED:\n            fmt = event.data.fmt_changed.new_fmt\n            size = (fmt.det.vid.size.w, fmt.det.vid.size.h)\n            fps = 1.0*fmt.det.vid.fps.num/fmt.det.vid.fps.denum\n            stream._event_handler('FORMAT_CHANGED', (size, fps))\n        elif event.type == PJMEDIA_EVENT_KEYFRAME_FOUND:\n            stream._event_handler('RECEIVED_KEYFRAME', None)\n        elif event.type == PJMEDIA_EVENT_KEYFRAME_MISSING:\n            stream._event_handler('MISSED_KEYFRAME', None)\n        elif event.type == PJMEDIA_EVENT_KEYFRAME_REQUESTED:\n            stream._event_handler('REQUESTED_KEYFRAME', None)\n        else:\n            # Pacify compiler\n            pass\n    return 0\n\n"
  },
  {
    "path": "sipsimple/core/_engine.py",
    "content": "\n\"\"\"\nImplements a mechanism for starting the SIP core engine based on PJSIP\n(http://pjsip.org) stack.\n\"\"\"\n\n__all__ = [\"Engine\"]\n\nimport sys\nimport traceback\nimport atexit\n\nfrom application.notification import NotificationCenter, NotificationData\nfrom application.python.types import Singleton\nfrom threading import Thread, RLock\n\nfrom sipsimple import log, __version__\nfrom sipsimple.core._core import PJSIPUA, PJ_VERSION, PJ_SVN_REVISION, SIPCoreError\n\n\nclass Engine(Thread):\n    __metaclass__ = Singleton\n    default_start_options = {\"ip_address\": None,\n                             \"udp_port\": 0,\n                             \"tcp_port\": None,\n                             \"tls_port\": None,\n                             \"tls_verify_server\": False,\n                             \"tls_ca_file\": None,\n                             \"tls_cert_file\": None,\n                             \"tls_privkey_file\": None,\n                             \"tls_timeout\": 3000,\n                             \"user_agent\": \"sipsimple-%s-pjsip-%s-r%s\" % (__version__, PJ_VERSION, PJ_SVN_REVISION),\n                             \"log_level\": 0,\n                             \"trace_sip\": False,\n                             \"detect_sip_loops\": True,\n                             \"rtp_port_range\": (50000, 50500),\n                             \"zrtp_cache\": None,\n                             \"codecs\": [\"G722\", \"speex\", \"PCMU\", \"PCMA\"],\n                             \"video_codecs\": [\"H264\", \"H263-1998\", \"VP8\"],\n                             \"enable_colorbar_device\": False,\n                             \"events\": {\"conference\":      [\"application/conference-info+xml\"],\n                                        \"message-summary\": [\"application/simple-message-summary\"],\n                                        \"presence\":        [\"multipart/related\", \"application/rlmi+xml\", \"application/pidf+xml\"],\n                                        \"presence.winfo\":  [\"application/watcherinfo+xml\"],\n                                        \"dialog\":          [\"multipart/related\", \"application/rlmi+xml\", \"application/dialog-info+xml\"],\n                                        \"dialog.winfo\":    [\"application/watcherinfo+xml\"],\n                                        \"refer\":           [\"message/sipfrag;version=2.0\"],\n                                        \"xcap-diff\":       [\"application/xcap-diff+xml\"]},\n                             \"incoming_events\": set(),\n                             \"incoming_requests\": set()}\n\n    def __init__(self):\n        self.notification_center = NotificationCenter()\n        self._thread_started = False\n        self._thread_stopping = False\n        self._lock = RLock()\n        self._options = None\n        atexit.register(self.stop)\n        super(Engine, self).__init__()\n        self.daemon = True\n\n    @property\n    def is_running(self):\n        return (hasattr(self, \"_ua\") and hasattr(self, \"_thread_started\")\n                and self._thread_started and not self._thread_stopping)\n\n    def __dir__(self):\n        if hasattr(self, '_ua'):\n            ua_attributes = [attr for attr in dir(self._ua) if not attr.startswith('__') and attr != 'poll']\n        else:\n            ua_attributes = []\n        return sorted(set(dir(self.__class__) + self.__dict__.keys() + ua_attributes))\n\n    def __getattr__(self, attr):\n        if attr not in [\"_ua\", \"poll\"] and hasattr(self, \"_ua\") and attr in dir(self._ua):\n            return getattr(self._ua, attr)\n        raise AttributeError(\"'%s' object has no attribute '%s'\" % (self.__class__.__name__, attr))\n\n    def __setattr__(self, attr, value):\n        if attr not in [\"_ua\", \"poll\"] and hasattr(self, \"_ua\") and attr in dir(self._ua):\n            setattr(self._ua, attr, value)\n            return\n        object.__setattr__(self, attr, value)\n\n    def start(self, **kwargs):\n        with self._lock:\n            if self._thread_started:\n                raise SIPCoreError(\"Worker thread was already started once\")\n            self._options = kwargs\n            self._thread_started = True\n            super(Engine, self).start()\n\n    def stop(self):\n        with self._lock:\n            if self._thread_stopping:\n                return\n            if self._thread_started:\n                self._thread_stopping = True\n\n    # worker thread\n    def run(self):\n        self.notification_center.post_notification('SIPEngineWillStart', sender=self)\n        init_options = Engine.default_start_options.copy()\n        init_options.update(self._options)\n        try:\n            self._ua = PJSIPUA(self._handle_event, **init_options)\n        except Exception:\n            log.exception('Exception occurred while starting the Engine')\n            exc_type, exc_val, exc_tb = sys.exc_info()\n            exc_tb = \"\".join(traceback.format_exception(exc_type, exc_val, exc_tb))\n            self.notification_center.post_notification('SIPEngineGotException', sender=self, data=NotificationData(type=exc_type, value=exc_val, traceback=exc_tb))\n            self.notification_center.post_notification('SIPEngineDidFail', sender=self)\n            return\n        else:\n            self.notification_center.post_notification('SIPEngineDidStart', sender=self)\n        failed = False\n        while not self._thread_stopping:\n            try:\n                failed = self._ua.poll()\n            except:\n                log.exception('Exception occurred while running the Engine')\n                exc_type, exc_val, exc_tb = sys.exc_info()\n                self.notification_center.post_notification('SIPEngineGotException', sender=self, data=NotificationData(type=exc_type, value=exc_val, traceback=\"\".join(traceback.format_exception(exc_type, exc_val, exc_tb))))\n                failed = True\n            if failed:\n                self.notification_center.post_notification('SIPEngineDidFail', sender=self)\n                break\n        if not failed:\n            self.notification_center.post_notification('SIPEngineWillEnd', sender=self)\n        self._ua.dealloc()\n        del self._ua\n        self.notification_center.post_notification('SIPEngineDidEnd', sender=self)\n\n    def _handle_event(self, event_name, **kwargs):\n        sender = kwargs.pop(\"obj\", None)\n        if sender is None:\n            sender = self\n        self.notification_center.post_notification(event_name, sender, NotificationData(**kwargs))\n\n"
  },
  {
    "path": "sipsimple/core/_helpers.py",
    "content": "\n\"\"\"Miscellaneous SIP related helpers\"\"\"\n\nimport random\nimport socket\nimport string\n\nfrom application.python.types import MarkerType\nfrom application.system import host\n\nfrom sipsimple.core._core import SIPURI\nfrom sipsimple.core._engine import Engine\n\n\n__all__ = ['Route', 'ContactURIFactory', 'NoGRUU', 'PublicGRUU', 'TemporaryGRUU', 'PublicGRUUIfAvailable', 'TemporaryGRUUIfAvailable']\n\n\nclass Route(object):\n    _default_ports = dict(udp=5060, tcp=5060, tls=5061)\n\n    def __init__(self, address, port=None, transport='udp'):\n        self.address = address\n        self.port = port\n        self.transport = transport\n\n    @property\n    def address(self):\n        return self._address\n\n    @address.setter\n    def address(self, address):\n        try:\n            socket.inet_aton(address)\n        except:\n            raise ValueError('illegal address: %s' % address)\n        self._address = address\n\n    @property\n    def port(self):\n        if self._port is None:\n            return 5061 if self.transport == 'tls' else 5060\n        else:\n            return self._port\n\n    @port.setter\n    def port(self, port):\n        port = int(port) if port is not None else None\n        if port is not None and not (0 < port < 65536):\n            raise ValueError('illegal port value: %d' % port)\n        self._port = port\n\n    @property\n    def transport(self):\n        return self._transport\n\n    @transport.setter\n    def transport(self, transport):\n        if transport not in ('udp', 'tcp', 'tls'):\n            raise ValueError('illegal transport value: %s' % transport)\n        self._transport = transport\n\n    @property\n    def uri(self):\n        port = None if self._default_ports[self.transport] == self.port else self.port\n        parameters = {} if self.transport == 'udp' else {'transport': self.transport}\n        return SIPURI(host=self.address, port=port, parameters=parameters)\n\n    def __repr__(self):\n        return '{0.__class__.__name__}({0.address!r}, port={0.port!r}, transport={0.transport!r})'.format(self)\n\n    def __str__(self):\n        return str(self.uri)\n\n\nclass ContactURIType(MarkerType): pass\n\nclass NoGRUU:                   __metaclass__ = ContactURIType\nclass PublicGRUU:               __metaclass__ = ContactURIType\nclass TemporaryGRUU:            __metaclass__ = ContactURIType\nclass PublicGRUUIfAvailable:    __metaclass__ = ContactURIType\nclass TemporaryGRUUIfAvailable: __metaclass__ = ContactURIType\n\n\nclass ContactURIFactory(object):\n    def __init__(self, username=None):\n        self.username = username or ''.join(random.sample(string.digits, 8))\n        self.public_gruu = None\n        self.temporary_gruu = None\n\n    def __repr__(self):\n        return '{0.__class__.__name__}(username={0.username!r})'.format(self)\n\n    def __getitem__(self, key):\n        if isinstance(key, tuple):\n            contact_type, key = key\n            if not isinstance(contact_type, ContactURIType):\n                raise KeyError(\"unsupported contact type: %r\" % contact_type)\n        else:\n            contact_type = NoGRUU\n        if not isinstance(key, (basestring, Route)):\n            raise KeyError(\"key must be a transport name or Route instance\")\n\n        transport = key if isinstance(key, basestring) else key.transport\n        parameters = {} if transport == 'udp' else {'transport': transport}\n\n        if contact_type is PublicGRUU:\n            if self.public_gruu is None:\n                raise KeyError(\"could not get Public GRUU\")\n            uri = SIPURI.new(self.public_gruu)\n        elif contact_type is TemporaryGRUU:\n            if self.temporary_gruu is None:\n                raise KeyError(\"could not get Temporary GRUU\")\n            uri = SIPURI.new(self.temporary_gruu)\n        elif contact_type is PublicGRUUIfAvailable and self.public_gruu is not None:\n            uri = SIPURI.new(self.public_gruu)\n        elif contact_type is TemporaryGRUUIfAvailable and self.temporary_gruu is not None:\n            uri = SIPURI.new(self.temporary_gruu)\n        else:\n            ip = host.default_ip if isinstance(key, basestring) else host.outgoing_ip_for(key.address)\n            if ip is None:\n                raise KeyError(\"could not get outgoing IP address\")\n            port = getattr(Engine(), '%s_port' % transport, None)\n            if port is None:\n                raise KeyError(\"unsupported transport: %s\" % transport)\n            uri = SIPURI(user=self.username, host=ip, port=port)\n        uri.parameters.update(parameters)\n        return uri\n\n\n"
  },
  {
    "path": "sipsimple/core/_primitives.py",
    "content": "\n\"\"\"\nImplements a high-level mechanism for SIP methods that can be used for\nnon-session based operations like REGISTER, SUBSCRIBE, PUBLISH and\nMESSAGE.\n\"\"\"\n\n__all__ = [\"Message\", \"Registration\", \"Publication\", \"PublicationError\", \"PublicationETagError\"]\n\nfrom threading import RLock\n\nfrom application.notification import IObserver, NotificationCenter, NotificationData\nfrom application.python import Null\nfrom zope.interface import implements\n\nfrom sipsimple.core._core import ContactHeader, Header, Request, RouteHeader, SIPCoreError, SIPURI, ToHeader\n\n\nclass Registration(object):\n    implements(IObserver)\n\n    def __init__(self, from_header, credentials=None, duration=300, extra_headers=None):\n        self.from_header = from_header\n        self.credentials = credentials\n        self.duration = duration\n        self.extra_headers = extra_headers or []\n        self._current_request = None\n        self._last_request = None\n        self._unregistering = False\n        self._lock = RLock()\n\n    is_registered = property(lambda self: self._last_request is not None)\n    contact_uri = property(lambda self: None if self._last_request is None else self._last_request.contact_uri)\n    expires_in = property(lambda self: 0 if self._last_request is None else self._last_request.expires_in)\n    peer_address = property(lambda self: None if self._last_request is None else self._last_request.peer_address)\n\n    def register(self, contact_header, route_header, timeout=None):\n        with self._lock:\n            try:\n                self._make_and_send_request(contact_header, route_header, timeout, True)\n            except SIPCoreError, e:\n                notification_center = NotificationCenter()\n                notification_center.post_notification('SIPRegistrationDidFail', sender=self, data=NotificationData(code=0, reason=e.args[0], route_header=route_header))\n\n    def end(self, timeout=None):\n        with self._lock:\n            if self._last_request is None:\n                return\n            notification_center = NotificationCenter()\n            notification_center.post_notification('SIPRegistrationWillEnd', sender=self)\n            try:\n                self._make_and_send_request(ContactHeader.new(self._last_request.contact_header), RouteHeader.new(self._last_request.route_header), timeout, False)\n            except SIPCoreError, e:\n                notification_center.post_notification('SIPRegistrationDidNotEnd', sender=self, data=NotificationData(code=0, reason=e.args[0]))\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_SIPRequestDidSucceed(self, notification):\n        request = notification.sender\n        with self._lock:\n            if request is not self._current_request:\n                return\n            self._current_request = None\n            if self._unregistering:\n                if self._last_request is not None:\n                    self._last_request.end()\n                    self._last_request = None\n                notification.center.post_notification('SIPRegistrationDidEnd', sender=self, data=NotificationData(expired=False))\n            else:\n                self._last_request = request\n                try:\n                    contact_header_list = notification.data.headers[\"Contact\"]\n                except KeyError:\n                    contact_header_list = []\n                notification.center.post_notification('SIPRegistrationDidSucceed', sender=self, data=NotificationData(code=notification.data.code, reason=notification.data.reason,\n                                                                                                                      contact_header=request.contact_header, contact_header_list=contact_header_list,\n                                                                                                                      expires_in=notification.data.expires, route_header=request.route_header))\n\n    def _NH_SIPRequestDidFail(self, notification):\n        request = notification.sender\n        with self._lock:\n            if request is not self._current_request:\n                return\n            self._current_request = None\n            if self._unregistering:\n                notification.center.post_notification('SIPRegistrationDidNotEnd', sender=self, data=NotificationData(code=notification.data.code, reason=notification.data.reason))\n            else:\n                if hasattr(notification.data, 'headers'):\n                    min_expires = notification.data.headers.get('Min-Expires', None)\n                else:\n                    min_expires = None\n                notification.center.post_notification('SIPRegistrationDidFail', sender=self, data=NotificationData(code=notification.data.code, reason=notification.data.reason,\n                                                                                                                   route_header=request.route_header, min_expires=min_expires))\n\n    def _NH_SIPRequestWillExpire(self, notification):\n        with self._lock:\n            if notification.sender is not self._last_request:\n                return\n            notification.center.post_notification('SIPRegistrationWillExpire', sender=self, data=NotificationData(expires=notification.data.expires))\n\n    def _NH_SIPRequestDidEnd(self, notification):\n        request = notification.sender\n        with self._lock:\n            notification.center.remove_observer(self, sender=request)\n            if request is not self._last_request:\n                return\n            self._last_request = None\n            if self._current_request is not None:\n                self._current_request.end()\n                self._current_request = None\n            notification.center.post_notification('SIPRegistrationDidEnd', sender=self, data=NotificationData(expired=True))\n\n    def _make_and_send_request(self, contact_header, route_header, timeout, do_register):\n        notification_center = NotificationCenter()\n        prev_request = self._current_request or self._last_request\n        if prev_request is not None:\n            call_id = prev_request.call_id\n            cseq = prev_request.cseq + 1\n        else:\n            call_id = None\n            cseq = 1\n        extra_headers = []\n        extra_headers.append(Header(\"Expires\", str(int(self.duration) if do_register else 0)))\n        extra_headers.extend(self.extra_headers)\n        request = Request(\"REGISTER\", SIPURI(self.from_header.uri.host), self.from_header, ToHeader.new(self.from_header), route_header,\n                          credentials=self.credentials, contact_header=contact_header, call_id=call_id,\n                          cseq=cseq, extra_headers=extra_headers)\n        notification_center.add_observer(self, sender=request)\n        if self._current_request is not None:\n            # we are trying to send something already, cancel whatever it is\n            self._current_request.end()\n            self._current_request = None\n        try:\n            request.send(timeout=timeout)\n        except:\n            notification_center.remove_observer(self, sender=request)\n            raise\n        self._unregistering = not do_register\n        self._current_request = request\n\n\nclass Message(object):\n    implements(IObserver)\n\n    def __init__(self, from_header, to_header, route_header, content_type, body, credentials=None, extra_headers=None):\n        self._request = Request(\"MESSAGE\", to_header.uri, from_header, to_header, route_header, credentials=credentials, extra_headers=extra_headers, content_type=content_type, body=body)\n        self._lock = RLock()\n\n    from_header = property(lambda self: self._request.from_header)\n    to_header = property(lambda self: self._request.to_header)\n    route_header = property(lambda self: self._request.route_header)\n    content_type = property(lambda self: self._request.content_type)\n    body = property(lambda self: self._request.body)\n    credentials = property(lambda self: self._request.credentials)\n    is_sent = property(lambda self: self._request.state != \"INIT\")\n    in_progress = property(lambda self: self._request.state == \"IN_PROGRESS\")\n    peer_address = property(lambda self: self._request.peer_address)\n\n    def send(self, timeout=None):\n        notification_center = NotificationCenter()\n        with self._lock:\n            if self.is_sent:\n                raise RuntimeError(\"This MESSAGE was already sent\")\n            notification_center.add_observer(self, sender=self._request)\n            try:\n                self._request.send(timeout)\n            except:\n                notification_center.remove_observer(self, sender=self._request)\n                raise\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_SIPRequestDidSucceed(self, notification):\n        if notification.data.expires:\n            # this shouldn't happen really\n            notification.sender.end()\n        notification.center.post_notification('SIPMessageDidSucceed', sender=self, data=notification.data)\n\n    def _NH_SIPRequestDidFail(self, notification):\n        notification.center.post_notification('SIPMessageDidFail', sender=self, data=notification.data)\n\n    def _NH_SIPRequestDidEnd(self, notification):\n        notification.center.remove_observer(self, sender=notification.sender)\n\n\nclass PublicationError(Exception): pass\nclass PublicationETagError(PublicationError): pass\n\n\nclass Publication(object):\n    implements(IObserver)\n\n    def __init__(self, from_header, event, content_type, credentials=None, duration=300, extra_headers=None):\n        self.from_header = from_header\n        self.event = event\n        self.content_type = content_type\n        self.credentials = credentials\n        self.duration = duration\n        self.extra_headers = extra_headers or []\n        self._last_etag = None\n        self._current_request = None\n        self._last_request = None\n        self._unpublishing = False\n        self._lock = RLock()\n\n    is_published = property(lambda self: self._last_request is not None)\n    expires_in = property(lambda self: 0 if self._last_request is None else self._last_request.expires_in)\n    peer_address = property(lambda self: None if self._last_request is None else self._last_request.peer_address)\n\n    def publish(self, body, route_header, timeout=None):\n        with self._lock:\n            if body is None:\n                if self._last_request is None:\n                    raise ValueError(\"Need body for initial PUBLISH\")\n                elif self._last_etag is None:\n                    raise PublicationETagError(\"Cannot refresh, last ETag was invalid\")\n            self._make_and_send_request(body, route_header, timeout, True)\n\n    def end(self, timeout=None):\n        with self._lock:\n            if self._last_request is None:\n                return\n            notification_center = NotificationCenter()\n            notification_center.post_notification('SIPPublicationWillEnd', sender=self)\n            try:\n                self._make_and_send_request(None, RouteHeader.new(self._last_request.route_header), timeout, False)\n            except SIPCoreError, e:\n                notification_center.post_notification('SIPPublicationDidNotEnd', sender=self, data=NotificationData(code=0, reason=e.args[0]))\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_SIPRequestDidSucceed(self, notification):\n        request = notification.sender\n        with self._lock:\n            if request is not self._current_request:\n                return\n            self._current_request = None\n            if self._unpublishing:\n                if self._last_request is not None:\n                    self._last_request.end()\n                    self._last_request = None\n                self._last_etag = None\n                notification.center.post_notification('SIPPublicationDidEnd', sender=self, data=NotificationData(expired=False))\n            else:\n                self._last_request = request\n                self._last_etag = notification.data.headers[\"SIP-ETag\"].body if \"SIP-ETag\" in notification.data.headers else None\n                # TODO: add more data?\n                notification.center.post_notification('SIPPublicationDidSucceed', sender=self, data=NotificationData(code=notification.data.code, reason=notification.data.reason,\n                                                                                                                     expires_in=notification.data.expires, route_header=request.route_header))\n\n    def _NH_SIPRequestDidFail(self, notification):\n        request = notification.sender\n        with self._lock:\n            if request is not self._current_request:\n                return\n            self._current_request = None\n            if notification.data.code == 412:\n                self._last_etag = None\n            if self._unpublishing:\n                notification.center.post_notification('SIPPublicationDidNotEnd', sender=self, data=NotificationData(code=notification.data.code, reason=notification.data.reason))\n            else:\n                notification.center.post_notification('SIPPublicationDidFail', sender=self, data=NotificationData(code=notification.data.code, reason=notification.data.reason,\n                                                                                                                  route_header=request.route_header))\n\n    def _NH_SIPRequestWillExpire(self, notification):\n        with self._lock:\n            if notification.sender is not self._last_request:\n                return\n            notification.center.post_notification('SIPPublicationWillExpire', sender=self, data=NotificationData(expires=notification.data.expires))\n\n    def _NH_SIPRequestDidEnd(self, notification):\n        with self._lock:\n            notification.center.remove_observer(self, sender=notification.sender)\n            if notification.sender is not self._last_request:\n                return\n            self._last_request = None\n            if self._current_request is not None:\n                self._current_request.end()\n                self._current_request = None\n            self._last_etag = None\n            notification.center.post_notification('SIPPublicationDidEnd', sender=self, data=NotificationData(expired=True))\n\n    def _make_and_send_request(self, body, route_header, timeout, do_publish):\n        notification_center = NotificationCenter()\n        extra_headers = []\n        extra_headers.append(Header(\"Event\", self.event))\n        extra_headers.append(Header(\"Expires\",  str(int(self.duration) if do_publish else 0)))\n        if self._last_etag is not None:\n            extra_headers.append(Header(\"SIP-If-Match\", self._last_etag))\n        extra_headers.extend(self.extra_headers)\n        content_type = (self.content_type if body is not None else None)\n        request = Request(\"PUBLISH\", self.from_header.uri, self.from_header, ToHeader.new(self.from_header), route_header,\n                          credentials=self.credentials, cseq=1, extra_headers=extra_headers,\n                          content_type=content_type, body=body)\n        notification_center.add_observer(self, sender=request)\n        if self._current_request is not None:\n            # we are trying to send something already, cancel whatever it is\n            self._current_request.end()\n            self._current_request = None\n        try:\n            request.send(timeout=timeout)\n        except:\n            notification_center.remove_observer(self, sender=request)\n            raise\n        self._unpublishing = not do_publish\n        self._current_request = request\n\n\n"
  },
  {
    "path": "sipsimple/logging.py",
    "content": "\nfrom __future__ import absolute_import\n\nfrom application import log\n\n# Use a named logger for sipsimple logging\nlog = log.get_logger('sipsimple')\n"
  },
  {
    "path": "sipsimple/lookup.py",
    "content": "\n\"\"\"\nImplements DNS lookups in the context of SIP, STUN and MSRP relay based\non RFC3263 and related standards. This can be used to determine the next\nhop(s) and failover for routing of SIP messages and reservation of network\nresources prior the starting of a SIP session.\n\"\"\"\n\nfrom __future__ import absolute_import\n\nimport re\nfrom itertools import chain\nfrom time import time\nfrom urlparse import urlparse\n\n# patch dns.entropy module which is not thread-safe\nimport dns\nimport sys\nfrom functools import partial\nfrom random import randint, randrange\n\ndns.entropy = dns.__class__('dns.entropy')\ndns.entropy.__file__ = dns.__file__.replace('__init__.py', 'entropy.py')\ndns.entropy.__builtins__ = dns.__builtins__\ndns.entropy.random_16 = partial(randrange, 2**16)\ndns.entropy.between = randint\n\nsys.modules['dns.entropy'] = dns.entropy\n\ndel partial, randint, randrange, sys\n\n# replace standard select and socket modules with versions from eventlib\nfrom eventlib import coros, proc\nfrom eventlib.green import select\nfrom eventlib.green import socket\nimport dns.name\nimport dns.resolver\nimport dns.query\ndns.resolver.socket = socket\ndns.query.socket = socket\ndns.query.select = select\ndns.query._set_polling_backend(dns.query._select_for)\n\nfrom application.notification import IObserver, NotificationCenter, NotificationData\nfrom application.python import Null, limit\nfrom application.python.decorator import decorator, preserve_signature\nfrom application.python.types import Singleton\nfrom dns import exception, rdatatype\nfrom twisted.internet import reactor\nfrom zope.interface import implements\n\nfrom sipsimple.core import Route\nfrom sipsimple.threading import run_in_twisted_thread\nfrom sipsimple.threading.green import Command, InterruptCommand, run_in_waitable_green_thread\n\n\ndef domain_iterator(domain):\n    \"\"\"\n    A generator which returns the domain and its parent domains.\n    \"\"\"\n    while domain not in ('.', ''):\n        yield domain\n        domain = (domain.split('.', 1)+[''])[1]\n\n\n@decorator\ndef post_dns_lookup_notifications(func):\n    @preserve_signature(func)\n    def wrapper(obj, *args, **kwargs):\n        notification_center = NotificationCenter()\n        try:\n            result = func(obj, *args, **kwargs)\n        except DNSLookupError, e:\n            notification_center.post_notification('DNSLookupDidFail', sender=obj, data=NotificationData(error=str(e)))\n            raise\n        else:\n            notification_center.post_notification('DNSLookupDidSucceed', sender=obj, data=NotificationData(result=result))\n            return result\n    return wrapper\n\n\nclass DNSLookupError(Exception):\n    \"\"\"\n    The error raised by DNSLookup when a lookup cannot be performed.\n    \"\"\"\n\n\nclass DNSCache(object):\n    \"\"\"\n    A simple DNS cache which uses twisted's timers to invalidate its expired\n    data.\n    \"\"\"\n    def __init__(self):\n        self.data = {}\n\n    def get(self, key):\n        return self.data.get(key, None)\n\n    def put(self, key, value):\n        expiration = value.expiration-time()\n        if expiration > 0:\n            self.data[key] = value\n            reactor.callLater(limit(expiration, max=3600), self.data.pop, key, None)\n\n    def flush(self, key=None):\n        if key is not None:\n            self.data.pop(key, None)\n        else:\n            self.data = {}\n\n\nclass InternalResolver(dns.resolver.Resolver):\n    def __init__(self, *args, **kw):\n        super(InternalResolver, self).__init__(*args, **kw)\n        if self.domain.to_text().endswith('local.'):\n            self.domain = dns.name.root\n        self.search = [item for item in self.search if not item.to_text().endswith('local.')]\n\n\nclass DNSResolver(dns.resolver.Resolver):\n    \"\"\"\n    The resolver used by DNSLookup.\n\n    The lifetime setting on it applies to all the queries made on this resolver.\n    Each time a query is performed, its duration is subtracted from the lifetime\n    value.\n    \"\"\"\n\n    def __init__(self):\n        dns.resolver.Resolver.__init__(self, configure=False)\n        dns_manager = DNSManager()\n        self.search = dns_manager.search\n        self.domain = dns_manager.domain\n        self.nameservers = dns_manager.nameservers\n\n    def query(self, *args, **kw):\n        start_time = time()\n        try:\n            return dns.resolver.Resolver.query(self, *args, **kw)\n        finally:\n            self.lifetime -= min(self.lifetime, time()-start_time)\n\n\nclass SRVResult(object):\n    \"\"\"\n    Internal object used to save the result of SRV queries.\n    \"\"\"\n    def __init__(self, priority, weight, port, address):\n        self.priority = priority\n        self.weight = weight\n        self.port = port\n        self.address = address\n\n\nclass NAPTRResult(object):\n    \"\"\"\n    Internal object used to save the result of NAPTR queries.\n    \"\"\"\n    def __init__(self, service, order, preference, priority, weight, port, address):\n        self.service = service\n        self.order = order\n        self.preference = preference\n        self.priority = priority\n        self.weight = weight\n        self.port = port\n        self.address = address\n\n\nclass DNSLookup(object):\n\n    cache = DNSCache()\n\n    @run_in_waitable_green_thread\n    @post_dns_lookup_notifications\n    def lookup_service(self, uri, service, timeout=3.0, lifetime=15.0):\n        \"\"\"\n        Performs an SRV query to determine the servers used for the specified\n        service from the domain in uri.host. If this fails and falling back is\n        supported, also performs an A query on uri.host, returning the default\n        port of the service along with the IP addresses in the answer.\n\n        The services supported are `stun' and 'msrprelay'.\n\n        The DNSLookupDidSucceed notification contains a result attribute which\n        is a list of (address, port) tuples. The DNSLookupDidFail notification\n        contains an error attribute describing the error encountered.\n        \"\"\"\n        service_srv_record_map = {\"stun\": (\"_stun._udp\", 3478, False),\n                                  \"msrprelay\": (\"_msrps._tcp\", 2855, True)}\n        log_context = dict(context='lookup_service', service=service, uri=uri)\n\n        try:\n            service_prefix, service_port, service_fallback = service_srv_record_map[service]\n        except KeyError:\n            raise DNSLookupError(\"Unknown service: %s\" % service)\n\n        try:\n            # If the host part of the URI is an IP address, we will not do any lookup\n            if re.match(\"^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$\", uri.host):\n                return [(uri.host, uri.port or service_port)]\n\n            resolver = DNSResolver()\n            resolver.cache = self.cache\n            resolver.timeout = timeout\n            resolver.lifetime = lifetime\n\n            record_name = '%s.%s' % (service_prefix, uri.host)\n            services = self._lookup_srv_records(resolver, [record_name], log_context=log_context)\n            if services[record_name]:\n                return [(result.address, result.port) for result in services[record_name]]\n            elif service_fallback:\n                addresses = self._lookup_a_records(resolver, [uri.host], log_context=log_context)\n                if addresses[uri.host]:\n                    return [(addr, service_port) for addr in addresses[uri.host]]\n        except dns.resolver.Timeout:\n            raise DNSLookupError('Timeout in lookup for %s servers for domain %s' % (service, uri.host))\n        else:\n            raise DNSLookupError('No %s servers found for domain %s' % (service, uri.host))\n\n\n    @run_in_waitable_green_thread\n    @post_dns_lookup_notifications\n    def lookup_sip_proxy(self, uri, supported_transports, timeout=3.0, lifetime=15.0):\n        \"\"\"\n        Performs an RFC 3263 compliant lookup of transport/ip/port combinations\n        for a particular SIP URI. As arguments it takes a SIPURI object\n        and a list of supported transports, in order of preference of the\n        application. It returns a list of Route objects that can be used in\n        order of preference.\n\n        The DNSLookupDidSucceed notification contains a result attribute which\n        is a list of Route objects. The DNSLookupDidFail notification contains\n        an error attribute describing the error encountered.\n        \"\"\"\n\n        naptr_service_transport_map = {\"sips+d2t\": \"tls\",\n                                       \"sip+d2t\": \"tcp\",\n                                       \"sip+d2u\": \"udp\"}\n        transport_service_map = {\"udp\": \"_sip._udp\",\n                                 \"tcp\": \"_sip._tcp\",\n                                 \"tls\": \"_sips._tcp\"}\n\n        log_context = dict(context='lookup_sip_proxy', uri=uri)\n\n        if not supported_transports:\n            raise DNSLookupError(\"No transports are supported\")\n        supported_transports = [transport.lower() for transport in supported_transports]\n        unknown_transports = set(supported_transports).difference(transport_service_map)\n        if unknown_transports:\n            raise DNSLookupError(\"Unknown transports: %s\" % ', '.join(unknown_transports))\n\n        try:\n            # If the host part of the URI is an IP address, we will not do any lookup\n            if re.match(\"^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$\", uri.host):\n                transport = 'tls' if uri.secure else uri.transport.lower()\n                if transport not in supported_transports:\n                    raise DNSLookupError(\"Transport %s dictated by URI is not supported\" % transport)\n                port = uri.port or (5061 if transport=='tls' else 5060)\n                return [Route(address=uri.host, port=port, transport=transport)]\n\n            resolver = DNSResolver()\n            resolver.cache = self.cache\n            resolver.timeout = timeout\n            resolver.lifetime = lifetime\n\n            # If the port is specified in the URI, we will only do an A lookup\n            if uri.port:\n                transport = 'tls' if uri.secure else uri.transport.lower()\n                if transport not in supported_transports:\n                    raise DNSLookupError(\"Transport %s dictated by URI is not supported\" % transport)\n                addresses = self._lookup_a_records(resolver, [uri.host], log_context=log_context)\n                if addresses[uri.host]:\n                    return [Route(address=addr, port=uri.port, transport=transport) for addr in addresses[uri.host]]\n\n            # If the transport was already set as a parameter on the SIP URI, only do SRV lookups\n            elif 'transport' in uri.parameters:\n                transport = uri.parameters['transport'].lower()\n                if transport not in supported_transports:\n                    raise DNSLookupError(\"Requested lookup for URI with %s transport, but it is not supported\" % transport)\n                if uri.secure and transport != 'tls':\n                    raise DNSLookupError(\"Requested lookup for SIPS URI, but with %s transport parameter\" % transport)\n                record_name = '%s.%s' % (transport_service_map[transport], uri.host)\n                services = self._lookup_srv_records(resolver, [record_name], log_context=log_context)\n                if services[record_name]:\n                    return [Route(address=result.address, port=result.port, transport=transport) for result in services[record_name]]\n                else:\n                    # If SRV lookup fails, try A lookup\n                    addresses = self._lookup_a_records(resolver, [uri.host], log_context=log_context)\n                    port = 5061 if transport=='tls' else 5060\n                    if addresses[uri.host]:\n                        return [Route(address=addr, port=port, transport=transport) for addr in addresses[uri.host]]\n\n            # Otherwise, it means we don't have a numeric IP address, a port isn't specified and neither is a transport. So we have to do a full NAPTR lookup\n            else:\n                # If the URI is a SIPS URI, we only support the TLS transport.\n                if uri.secure:\n                    if 'tls' not in supported_transports:\n                        raise DNSLookupError(\"Requested lookup for SIPS URI, but TLS transport is not supported\")\n                    supported_transports = ['tls']\n                # First try NAPTR lookup\n                naptr_services = [service for service, transport in naptr_service_transport_map.iteritems() if transport in supported_transports]\n                try:\n                    pointers = self._lookup_naptr_record(resolver, uri.host, naptr_services, log_context=log_context)\n                except dns.resolver.Timeout:\n                    pointers = []\n                if pointers:\n                    return [Route(address=result.address, port=result.port, transport=naptr_service_transport_map[result.service]) for result in pointers]\n                else:\n                    # If that fails, try SRV lookup\n                    routes = []\n                    for transport in supported_transports:\n                        record_name = '%s.%s' % (transport_service_map[transport], uri.host)\n                        try:\n                            services = self._lookup_srv_records(resolver, [record_name], log_context=log_context)\n                        except dns.resolver.Timeout:\n                            continue\n                        if services[record_name]:\n                            routes.extend(Route(address=result.address, port=result.port, transport=transport) for result in services[record_name])\n                    if routes:\n                        return routes\n                    else:\n                        # If SRV lookup fails, try A lookup\n                        transport = 'tls' if uri.secure else 'udp'\n                        if transport in supported_transports:\n                            addresses = self._lookup_a_records(resolver, [uri.host], log_context=log_context)\n                            port = 5061 if transport=='tls' else 5060\n                            if addresses[uri.host]:\n                                return [Route(address=addr, port=port, transport=transport) for addr in addresses[uri.host]]\n        except dns.resolver.Timeout:\n            raise DNSLookupError(\"Timeout in lookup for routes for SIP URI %s\" % uri)\n        else:\n            raise DNSLookupError(\"No routes found for SIP URI %s\" % uri)\n\n    @run_in_waitable_green_thread\n    @post_dns_lookup_notifications\n    def lookup_xcap_server(self, uri, timeout=3.0, lifetime=15.0):\n        \"\"\"\n        Performs a TXT query against xcap.<uri.host> and returns all results\n        that look like HTTP URIs.\n        \"\"\"\n        log_context = dict(context='lookup_xcap_server', uri=uri)\n        notification_center = NotificationCenter()\n\n        try:\n            # If the host part of the URI is an IP address, we cannot not do any lookup\n            if re.match(\"^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$\", uri.host):\n                raise DNSLookupError(\"Cannot perform DNS query because the host is an IP address\")\n\n            resolver = DNSResolver()\n            resolver.cache = self.cache\n            resolver.timeout = timeout\n            resolver.lifetime = lifetime\n\n            record_name = 'xcap.%s' % uri.host\n            results = []\n            try:\n                answer = resolver.query(record_name, rdatatype.TXT)\n            except dns.resolver.Timeout, e:\n                notification_center.post_notification('DNSLookupTrace', sender=self, data=NotificationData(query_type='TXT', query_name=str(record_name), nameservers=resolver.nameservers, answer=None, error=e, **log_context))\n                raise\n            except exception.DNSException, e:\n                notification_center.post_notification('DNSLookupTrace', sender=self, data=NotificationData(query_type='TXT', query_name=str(record_name), nameservers=resolver.nameservers, answer=None, error=e, **log_context))\n            else:\n                notification_center.post_notification('DNSLookupTrace', sender=self, data=NotificationData(query_type='TXT', query_name=str(record_name), nameservers=resolver.nameservers, answer=answer, error=None, **log_context))\n                for result_uri in list(chain(*(r.strings for r in answer.rrset))):\n                    parsed_uri = urlparse(result_uri)\n                    if parsed_uri.scheme in ('http', 'https') and parsed_uri.netloc:\n                        results.append(result_uri)\n            if not results:\n                raise DNSLookupError('No XCAP servers found for domain %s' % uri.host)\n            return results\n        except dns.resolver.Timeout:\n            raise DNSLookupError('Timeout in lookup for XCAP servers for domain %s' % uri.host)\n\n\n    def _lookup_a_records(self, resolver, hostnames, additional_records=[], log_context={}):\n        notification_center = NotificationCenter()\n        additional_addresses = dict((rset.name.to_text(), rset) for rset in additional_records if rset.rdtype == rdatatype.A)\n        addresses = {}\n        for hostname in hostnames:\n            if hostname in additional_addresses:\n                addresses[hostname] = [r.address for r in additional_addresses[hostname]]\n            else:\n                try:\n                    answer = resolver.query(hostname, rdatatype.A)\n                except dns.resolver.Timeout, e:\n                    notification_center.post_notification('DNSLookupTrace', sender=self, data=NotificationData(query_type='A', query_name=str(hostname), nameservers=resolver.nameservers, answer=None, error=e, **log_context))\n                    raise\n                except exception.DNSException, e:\n                    notification_center.post_notification('DNSLookupTrace', sender=self, data=NotificationData(query_type='A', query_name=str(hostname), nameservers=resolver.nameservers, answer=None, error=e, **log_context))\n                    addresses[hostname] = []\n                else:\n                    notification_center.post_notification('DNSLookupTrace', sender=self, data=NotificationData(query_type='A', query_name=str(hostname), nameservers=resolver.nameservers, answer=answer, error=None, **log_context))\n                    addresses[hostname] = [r.address for r in answer.rrset]\n        return addresses\n\n\n    def _lookup_srv_records(self, resolver, srv_names, additional_records=[], log_context={}):\n        notification_center = NotificationCenter()\n        additional_services = dict((rset.name.to_text(), rset) for rset in additional_records if rset.rdtype == rdatatype.SRV)\n        services = {}\n        for srv_name in srv_names:\n            services[srv_name] = []\n            if srv_name in additional_services:\n                addresses = self._lookup_a_records(resolver, [r.target.to_text() for r in additional_services[srv_name]], additional_records)\n                for record in additional_services[srv_name]:\n                    services[srv_name].extend(SRVResult(record.priority, record.weight, record.port, addr) for addr in addresses.get(record.target.to_text(), ()))\n            else:\n                try:\n                    answer = resolver.query(srv_name, rdatatype.SRV)\n                except dns.resolver.Timeout, e:\n                    notification_center.post_notification('DNSLookupTrace', sender=self, data=NotificationData(query_type='SRV', query_name=str(srv_name), nameservers=resolver.nameservers, answer=None, error=e, **log_context))\n                    raise\n                except exception.DNSException, e:\n                    notification_center.post_notification('DNSLookupTrace', sender=self, data=NotificationData(query_type='SRV', query_name=str(srv_name), nameservers=resolver.nameservers, answer=None, error=e, **log_context))\n                else:\n                    notification_center.post_notification('DNSLookupTrace', sender=self, data=NotificationData(query_type='SRV', query_name=str(srv_name), nameservers=resolver.nameservers, answer=answer, error=None, **log_context))\n                    addresses = self._lookup_a_records(resolver, [r.target.to_text() for r in answer.rrset], answer.response.additional, log_context)\n                    for record in answer.rrset:\n                        services[srv_name].extend(SRVResult(record.priority, record.weight, record.port, addr) for addr in addresses.get(record.target.to_text(), ()))\n            services[srv_name].sort(key=lambda result: (result.priority, -result.weight))\n        return services\n\n\n    def _lookup_naptr_record(self, resolver, domain, services, log_context={}):\n        notification_center = NotificationCenter()\n        pointers = []\n        try:\n            answer = resolver.query(domain, rdatatype.NAPTR)\n        except dns.resolver.Timeout, e:\n            notification_center.post_notification('DNSLookupTrace', sender=self, data=NotificationData(query_type='NAPTR', query_name=str(domain), nameservers=resolver.nameservers, answer=None, error=e, **log_context))\n            raise\n        except exception.DNSException, e:\n            notification_center.post_notification('DNSLookupTrace', sender=self, data=NotificationData(query_type='NAPTR', query_name=str(domain), nameservers=resolver.nameservers, answer=None, error=e, **log_context))\n        else:\n            notification_center.post_notification('DNSLookupTrace', sender=self, data=NotificationData(query_type='NAPTR', query_name=str(domain), nameservers=resolver.nameservers, answer=answer, error=None, **log_context))\n            records = [r for r in answer.rrset if r.service.lower() in services]\n            services = self._lookup_srv_records(resolver, [r.replacement.to_text() for r in records], answer.response.additional, log_context)\n            for record in records:\n                pointers.extend(NAPTRResult(record.service.lower(), record.order, record.preference, r.priority, r.weight, r.port, r.address) for r in services.get(record.replacement.to_text(), ()))\n        pointers.sort(key=lambda result: (result.order, result.preference))\n        return pointers\n\n\nclass DNSManager(object):\n    __metaclass__ = Singleton\n\n    implements(IObserver)\n\n    def __init__(self):\n        default_resolver = InternalResolver()\n        self.search = default_resolver.search\n        self.domain = default_resolver.domain\n        self.nameservers = default_resolver.nameservers\n        self.google_nameservers = ['8.8.8.8', '8.8.4.4']\n        self.probed_domain = 'sip2sip.info.'\n        self._channel = coros.queue()\n        self._proc = None\n        self._timer = None\n        self._wakeup_timer = None\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, name='SystemIPAddressDidChange')\n        notification_center.add_observer(self, name='SystemDidWakeUpFromSleep')\n\n    @property\n    def nameservers(self):\n        return self.__dict__['nameservers']\n\n    @nameservers.setter\n    def nameservers(self, value):\n        old_value = self.__dict__.get('nameservers', Null)\n        self.__dict__['nameservers'] = value\n        if old_value is Null:\n            NotificationCenter().post_notification('DNSResolverDidInitialize', sender=self, data=NotificationData(nameservers=value))\n        elif value != old_value:\n            NotificationCenter().post_notification('DNSNameserversDidChange', sender=self, data=NotificationData(nameservers=value))\n\n    def start(self):\n        self._proc = proc.spawn(self._run)\n        self._channel.send(Command('probe_dns'))\n\n    def stop(self):\n        if self._proc is not None:\n            self._proc.kill()\n            self._proc = None\n        if self._timer is not None and self._timer.active():\n            self._timer.cancel()\n        self._timer = None\n        if self._wakeup_timer is not None and self._wakeup_timer.active():\n            self._wakeup_timer.cancel()\n        self._wakeup_timer = None\n\n    def _run(self):\n        while True:\n            try:\n                command = self._channel.wait()\n                handler = getattr(self, '_CH_%s' % command.name)\n                handler(command)\n            except InterruptCommand:\n                pass\n\n    def _CH_probe_dns(self, command):\n        if self._timer is not None and self._timer.active():\n            self._timer.cancel()\n        self._timer = None\n        resolver = InternalResolver()\n        self.domain = resolver.domain\n        self.search = resolver.search\n        local_nameservers = resolver.nameservers\n        # probe local resolver\n        resolver.timeout = 1\n        resolver.lifetime = 3\n        try:\n            answer = resolver.query(self.probed_domain, rdatatype.NAPTR)\n            if not any(record.rdtype == rdatatype.NAPTR for record in answer.rrset):\n                raise exception.DNSException(\"No NAPTR records found\")\n            answer = resolver.query(\"_sip._udp.%s\" % self.probed_domain, rdatatype.SRV)\n            if not any(record.rdtype == rdatatype.SRV for record in answer.rrset):\n                raise exception.DNSException(\"No SRV records found\")\n        except (dns.resolver.Timeout, exception.DNSException):\n            pass\n        else:\n            self.nameservers = resolver.nameservers\n            return\n        # local resolver failed. probe google resolver\n        resolver.nameservers = self.google_nameservers\n        resolver.timeout = 2\n        resolver.lifetime = 4\n        try:\n            answer = resolver.query(self.probed_domain, rdatatype.NAPTR)\n            if not any(record.rdtype == rdatatype.NAPTR for record in answer.rrset):\n                raise exception.DNSException(\"No NAPTR records found\")\n        except (dns.resolver.Timeout, exception.DNSException):\n            pass\n        else:\n            self.nameservers = resolver.nameservers\n            return\n        # google resolver failed. fallback to local resolver and schedule another probe for later\n        self.nameservers = local_nameservers\n        self._timer = reactor.callLater(15, self._channel.send, Command('probe_dns'))\n\n    @run_in_twisted_thread\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_SystemIPAddressDidChange(self, notification):\n        self._proc.kill(InterruptCommand)\n        self._channel.send(Command('probe_dns'))\n\n    def _NH_SystemDidWakeUpFromSleep(self, notification):\n        if self._wakeup_timer is None:\n            def wakeup_action():\n                self._proc.kill(InterruptCommand)\n                self._channel.send(Command('probe_dns'))\n                self._wakeup_timer = None\n            self._wakeup_timer = reactor.callLater(5, wakeup_action) # wait for system to stabilize\n\n\n"
  },
  {
    "path": "sipsimple/payloads/README.txt",
    "content": "\nSIP SIMPLE client Payloads\n--------------------------\n\nThese applications provide functionality that are required for implementing\na feature-rich SIP SIMPLE client.\n\nThese applications are used for parsing and generating bodies carried using\nPUBLISH, SUBSCRIBE and NOTIFY methods designed for asynchronous event\nnotifications, to convey in near real-time, information between SIP\nend-points.\n\nAn example of such information is presence, which in its basic form it\nprovides user availability information based on end-user choice.  In its\nadvanced form, presence can provide rich state information including but not\nlimited to user mood, geo-location, environment, noise level and the type of\ncommunication desired.  The information can be disseminated based on a\ngranular policy which allows end-users to decide who has access to which\npart of the published information.\n\n\naddressbook.py\n\nHigh-level implementation of an addressbook stored in XCAP documents.  The\ncontacts, groups and their attributes are stored in resource lists and OMA\nextensions described in OMA-TS-Presence_SIMPLE_XDM are used for describing\npolicy and RLS services by references to resource lists.  Multiple client\ninstances can synchronize this addressbook using XCAP-diff event package.\n\n\nwatcherinfo.py (RFC3857 and RFC3858)\n\nParses NOTIFY body for presence.winfo event. Used for keeping track of\nwatchers that subscribed to our presentity.  Based on this information the\nthe user can manage its presence policy.  To retrieve this information the\nSIP client must subscribe to its own address for event presence.winfo.\n\n\nresourcelists.py (RFC4826)\n\nParses and generates XML documents for constructing resource lists\ndocuments.  Used for server side storage of presence related buddy lists\nusing XCAP protocol.  The SIP clients maintain the resource-lists on the\nXCAP server which provides persisten storage and aggregation point for\nmultiple devices.\n\n\nrlsservices.py (RFC4826)\n\nParses and generates XML documents for constructing rls-services documents. \nUsed for delegating presence related works to the server.  The client build\nrls-services lists with buddies and instructs the server to subscribe to the\nsip uris indicated in the lists.  This way the client can save bandwidth as\nthe server performs the signalling for subscription and collection of\nnotifications and provides consolidated answer to the sip user agent.\n\n\nrlmi.py, rlsnotify.py (RFC4482)\n\nDocument handling for NOTIFY body for Resource Lists Contact Information.\n\n\npolicy.py (RFC4745)\n\nGeneric data types to be used in policy applications.\n\n\npresrules.py (RFC5025)\n\nParses and generates authorization rules in XML format for presence or other\napplications.  Authorization rules are stored on the XCAP server.  The\npresence rules are generated either based on user initiative or as a\nresponse to a new subscription signaled by a change in the watcherinfo\napplication.\n\n\nomapolicy.py (OMA-TS-Presence_SIMPLE_XDM-V1_1)\n\nConditions extension handling according to OMA-TS-Presence_SIMPLE_XDM-V1_1. \nThis module provides an extension to common policy defined in RFC4745 to\nsupport condition extensions defined by OMA.\n\n\nprescontent.py (OMA-TS-Presence_SIMPLE_XDM-V1_1)\n\nGenerates presence content application documents according to OMA TS\nPresence SIMPLE Content.\n\n\ndirectory.py (OMA Core Specifications)\n\nParses xcap-directory messages according to OMA TS XDM Core.\n\n\ndialoginfo.py (RFC4235)\n\nParses and produces dialog-info messages according to RFC4235.\n\n\ndialogrules.py\n\nParses and produces Dialog Authorization Rules documents. As there is no RFC\nfor this, common-policy format from RFC 4745 is used.  Subscription Handling\nhas been taken from RFC 5025.\n\n\npidf.py (RFC3863 and RFC3379)\n\nThis module provides classes to parse and generate PIDF documents, and also\nuses the XML Application extensibility API to allow extensions to PIDF. It\nis used to parse NOTIFY body for presence event and generates rich presence\nstate information for use with PUBLISH. Used to generate own presence\ninformation and to parse the state of buddy lists entries we have subscribed\nto. A SIP client typically instantiates a new pidf object for itself and for\neach buddy it SUBSCRIBEs to and update each object when a NOTIFY is\nreceived. The list of buddys is maintained using resourcelists application.\n\n\nrpid.py (RFC4480)\n\nThis module provides an extension to PIDF to support rich presence.\n\n\npresdm.py (RFC4479)\n\nThis module provides an extension to the PIDF to support the data module\ndefined in RFC4479.\n\n\ncipid.py (RFC4482)\n \nThis module provides an extension to PIDF to provide person related information.\n\n\ncaps.py (RFC5196)\n\nThis module provides capabilities application: displays OPTIONS request-like information\nas an extension to the PIDF.\n\n\nxcapcaps.py (RFC4825)\n\nSupport for parsing and building xcap-caps documents, as defined by RFC4825.\n\n\nxcapdiff.py (RFC5874)\n\nParses NOTIFY body for xcap-diff event. Used to detect changes in XCAP\ndocuments changed by other device configured for the same presentity.\n\n\niscomposing.py (RFC3994)\n\nThis module parses and generates isComposing messages according to RFC3994. It's used\nmainly in chat environments to indicate the other party that the user is actually\ntyping a message.\n\n\nconference.py (RFC4575)\n\nThis module implements conference-info payload parsing and generating for\ndescribing information about conference participants and related resources.\n\n\nmessagesummary.py (RFC3842)\n\nThis module implements a parser and generator for message-summary payload,\nwhich is used to indicate missed calls or voice mail recordings.\n\n"
  },
  {
    "path": "sipsimple/payloads/__init__.py",
    "content": "\n__all__ = ['ParserError',\n           'BuilderError',\n           'ValidationError',\n           'IterateTypes',\n           'IterateIDs',\n           'IterateItems',\n           'All',\n           'parse_qname',\n           'XMLDocument',\n           'XMLAttribute',\n           'XMLElementID',\n           'XMLElementChild',\n           'XMLElementChoiceChild',\n           'XMLStringChoiceChild',\n           'XMLElement',\n           'XMLRootElement',\n           'XMLSimpleElement',\n           'XMLStringElement',\n           'XMLLocalizedStringElement',\n           'XMLBooleanElement',\n           'XMLByteElement',\n           'XMLUnsignedByteElement',\n           'XMLShortElement',\n           'XMLUnsignedShortElement',\n           'XMLIntElement',\n           'XMLUnsignedIntElement',\n           'XMLLongElement',\n           'XMLUnsignedLongElement',\n           'XMLIntegerElement',\n           'XMLPositiveIntegerElement',\n           'XMLNegativeIntegerElement',\n           'XMLNonNegativeIntegerElement',\n           'XMLNonPositiveIntegerElement',\n           'XMLDecimalElement',\n           'XMLDateTimeElement',\n           'XMLAnyURIElement',\n           'XMLEmptyElement',\n           'XMLEmptyElementRegistryType',\n           'XMLListElement',\n           'XMLListRootElement',\n           'XMLStringListElement']\n\n\nimport os\nimport sys\nimport urllib\nfrom collections import defaultdict, deque\nfrom copy import deepcopy\nfrom decimal import Decimal\nfrom itertools import chain, izip\nfrom weakref import WeakValueDictionary\n\nfrom application.python import Null\nfrom application.python.descriptor import classproperty\nfrom application.python.types import MarkerType\nfrom application.python.weakref import weakobjectmap\nfrom lxml import etree\n\nfrom sipsimple.payloads.datatypes import Boolean, Byte, UnsignedByte, Short, UnsignedShort, Int, UnsignedInt, Long, UnsignedLong\nfrom sipsimple.payloads.datatypes import PositiveInteger, NegativeInteger, NonNegativeInteger, NonPositiveInteger, DateTime, AnyURI\nfrom sipsimple.util import All\n\n\n## Exceptions\n\nclass ParserError(Exception): pass\nclass BuilderError(Exception): pass\nclass ValidationError(ParserError): pass\n\n\n## Markers\n\nclass IterateTypes: __metaclass__ = MarkerType\nclass IterateIDs:   __metaclass__ = MarkerType\nclass IterateItems: __metaclass__ = MarkerType\n\nclass StoredAttribute: __metaclass__ = MarkerType\n\n\n## Utilities\n\ndef parse_qname(qname):\n    if qname[0] == '{':\n        qname = qname[1:]\n        return qname.split('}')\n    else:\n        return None, qname\n\n\n## XMLDocument\n\nclass XMLDocumentType(type):\n    def __init__(cls, name, bases, dct):\n        cls.nsmap = {}\n        cls.schema_map = {}\n        cls.element_map = {}\n        cls.root_element = None\n        cls.schema = None\n        cls.parser = None\n        for base in reversed(bases):\n            if hasattr(base, 'element_map'):\n                cls.element_map.update(base.element_map)\n            if hasattr(base, 'schema_map'):\n                cls.schema_map.update(base.schema_map)\n            if hasattr(base, 'nsmap'):\n                cls.nsmap.update(base.nsmap)\n        cls._update_schema()\n\n    def __setattr__(cls, name, value):\n        if name == 'schema_path':\n            if cls is not XMLDocument:\n                raise AttributeError(\"%s can only be changed on XMLDocument\" % name)\n            super(XMLDocumentType, cls).__setattr__(name, value)\n            def update_schema(document_class):\n                document_class._update_schema()\n                for document_subclass in document_class.__subclasses__():\n                    update_schema(document_subclass)\n            update_schema(XMLDocument)\n        else:\n            super(XMLDocumentType, cls).__setattr__(name, value)\n\n    def _update_schema(cls):\n        if cls.schema_map:\n            location_map = {ns: urllib.quote(os.path.abspath(os.path.join(cls.schema_path, schema_file)).replace('\\\\', '//')) for ns, schema_file in cls.schema_map.iteritems()}\n            schema = \"\"\"<?xml version=\"1.0\"?>\n                <xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n                    %s\n                </xs:schema>\n            \"\"\" % '\\r\\n'.join('<xs:import namespace=\"%s\" schemaLocation=\"%s\"/>' % (namespace, schema_location) for namespace, schema_location in location_map.iteritems())\n            cls.schema = etree.XMLSchema(etree.XML(schema))\n            cls.parser = etree.XMLParser(schema=cls.schema, remove_blank_text=True)\n        else:\n            cls.schema = None\n            cls.parser = etree.XMLParser(remove_blank_text=True)\n\n\nclass XMLDocument(object):\n    __metaclass__ = XMLDocumentType\n\n    encoding = 'UTF-8'\n    content_type = None\n    schema_path = os.path.join(os.path.dirname(__file__), 'xml-schemas')\n\n    @classmethod\n    def parse(cls, document):\n        try:\n            if isinstance(document, str):\n                xml = etree.XML(document, parser=cls.parser)\n            elif isinstance(document, unicode):\n                xml = etree.XML(document.encode('utf-8'), parser=cls.parser)\n            else:\n                xml = etree.parse(document, parser=cls.parser).getroot()\n            if cls.schema is not None:\n                cls.schema.assertValid(xml)\n            return cls.root_element.from_element(xml, xml_document=cls)\n        except (etree.DocumentInvalid, etree.XMLSyntaxError, ValueError), e:\n            raise ParserError(str(e))\n\n    @classmethod\n    def build(cls, root_element, encoding=None, pretty_print=False, validate=True):\n        if type(root_element) is not cls.root_element:\n            raise TypeError(\"can only build XML documents from root elements of type %s\" % cls.root_element.__name__)\n        element = root_element.to_element()\n        if validate and cls.schema is not None:\n            cls.schema.assertValid(element)\n        # Cleanup namespaces and move element NS mappings to the global scope.\n        normalized_element = etree.Element(element.tag, attrib=element.attrib, nsmap=dict(chain(element.nsmap.iteritems(), cls.nsmap.iteritems())))\n        normalized_element.text = element.text\n        normalized_element.tail = element.tail\n        normalized_element.extend(deepcopy(child) for child in element)\n        etree.cleanup_namespaces(normalized_element)\n        return etree.tostring(normalized_element, encoding=encoding or cls.encoding, method='xml', xml_declaration=True, pretty_print=pretty_print)\n\n    @classmethod\n    def create(cls, build_kw={}, **kw):\n        return cls.build(cls.root_element(**kw), **build_kw)\n\n    @classmethod\n    def register_element(cls, xml_class):\n        cls.element_map[xml_class.qname] = xml_class\n        for child in cls.__subclasses__():\n            child.register_element(xml_class)\n\n    @classmethod\n    def get_element(cls, qname, default=None):\n        return cls.element_map.get(qname, default)\n\n    @classmethod\n    def register_namespace(cls, namespace, prefix=None, schema=None):\n        if prefix in cls.nsmap:\n            raise ValueError(\"prefix %s is already registered in %s\" % (prefix, cls.__name__))\n        if namespace in cls.nsmap.itervalues():\n            raise ValueError(\"namespace %s is already registered in %s\" % (namespace, cls.__name__))\n        cls.nsmap[prefix] = namespace\n        if schema is not None:\n            cls.schema_map[namespace] = schema\n            cls._update_schema()\n        for child in cls.__subclasses__():\n            child.register_namespace(namespace, prefix, schema)\n\n    @classmethod\n    def unregister_namespace(cls, namespace):\n        try:\n            prefix = (prefix for prefix in cls.nsmap if cls.nsmap[prefix]==namespace).next()\n        except StopIteration:\n            raise KeyError(\"namespace %s is not registered in %s\" % (namespace, cls.__name__))\n        del cls.nsmap[prefix]\n        schema = cls.schema_map.pop(namespace, None)\n        if schema is not None:\n            cls._update_schema()\n        for child in cls.__subclasses__():\n            try:\n                child.unregister_namespace(namespace)\n            except KeyError:\n                pass\n\n\n## Children descriptors\n\nclass XMLAttribute(object):\n    def __init__(self, name, xmlname=None, type=unicode, default=None, required=False, test_equal=True, onset=None, ondel=None):\n        self.name = name\n        self.xmlname = xmlname or name\n        self.type = type\n        self.default = default\n        self.__xmlparse__ = getattr(type, '__xmlparse__', lambda value: value)\n        self.__xmlbuild__ = getattr(type, '__xmlbuild__', unicode)\n        self.required = required\n        self.test_equal = test_equal\n        self.onset = onset\n        self.ondel = ondel\n        self.values = weakobjectmap()\n    \n    def __get__(self, obj, objtype):\n        if obj is None:\n            return self\n        try:\n            return self.values[obj]\n        except KeyError:\n            value = self.values.setdefault(obj, self.default)\n            if value is not None:\n                obj.element.set(self.xmlname, self.build(value))\n            return value\n    \n    def __set__(self, obj, value):\n        if value is not None and not isinstance(value, self.type):\n            value = self.type(value)\n        old_value = self.values.get(obj, self.default)\n        if value == old_value:\n            return\n        if value is not None:\n            obj.element.set(self.xmlname, self.build(value))\n        else:\n            obj.element.attrib.pop(self.xmlname, None)\n        self.values[obj] = value\n        obj.__dirty__ = True\n        if self.onset:\n            self.onset(obj, self, value)\n\n    def __delete__(self, obj):\n        obj.element.attrib.pop(self.xmlname, None)\n        try:\n            value = self.values.pop(obj)\n        except KeyError:\n            pass\n        else:\n            if value != self.default:\n                obj.__dirty__ = True\n        if self.ondel:\n            self.ondel(obj, self)\n\n    def parse(self, xmlvalue):\n        return self.__xmlparse__(xmlvalue)\n\n    def build(self, value):\n        return self.__xmlbuild__(value)\n\n\nclass XMLElementID(XMLAttribute):\n    \"\"\"An XMLAttribute that represents the ID of an element (immutable).\"\"\"\n\n    def __set__(self, obj, value):\n        if obj in self.values:\n            raise AttributeError(\"An XML element ID cannot be changed\")\n        super(XMLElementID, self).__set__(obj, value)\n\n    def __delete__(self, obj):\n        raise AttributeError(\"An XML element ID cannot be deleted\")\n\n\nclass XMLElementChild(object):\n    def __init__(self, name, type, required=False, test_equal=True, onset=None, ondel=None):\n        self.name = name\n        self.type = type\n        self.required = required\n        self.test_equal = test_equal\n        self.onset = onset\n        self.ondel = ondel\n        self.values = weakobjectmap()\n\n    def __get__(self, obj, objtype):\n        if obj is None:\n            return self\n        try:\n            return self.values[obj]\n        except KeyError:\n            return None\n\n    def __set__(self, obj, value):\n        if value is not None and not isinstance(value, self.type):\n            value = self.type(value)\n        same_value = False\n        old_value = self.values.get(obj)\n        if value is old_value:\n            return\n        elif value is not None and value == old_value:\n            value.__dirty__ = old_value.__dirty__\n            same_value = True\n        if old_value is not None:\n            obj.element.remove(old_value.element)\n        if value is not None:\n            obj._insert_element(value.element)\n        self.values[obj] = value\n        if not same_value:\n            obj.__dirty__ = True\n        if self.onset:\n            self.onset(obj, self, value)\n\n    def __delete__(self, obj):\n        try:\n            old_value = self.values.pop(obj)\n        except KeyError:\n            pass\n        else:\n            if old_value is not None:\n                obj.element.remove(old_value.element)\n                obj.__dirty__ = True\n        if self.ondel:\n            self.ondel(obj, self)\n\n\nclass XMLElementChoiceChildWrapper(object):\n    __slots__ = ('descriptor', 'type')\n\n    def __init__(self, descriptor, type):\n        self.descriptor = descriptor\n        self.type = type\n\n    def __getattribute__(self, name):\n        if name in ('descriptor', 'type', 'register_extension', 'unregister_extension'):\n            return super(XMLElementChoiceChildWrapper, self).__getattribute__(name)\n        else:\n            return self.descriptor.__getattribute__(name)\n\n    def __setattr__(self, name, value):\n        if name in ('descriptor', 'type'):\n            super(XMLElementChoiceChildWrapper, self).__setattr__(name, value)\n        else:\n            setattr(self.descriptor, name, value)\n\n    def __dir__(self):\n        return dir(self.descriptor) + ['descriptor', 'type', 'register_extension', 'unregister_extension']\n\n    def register_extension(self, type):\n        if self.extension_type is None:\n            raise ValueError(\"The %s XML choice element of %s does not support extensions\" % (self.name, self.type.__name__))\n        if not issubclass(type, XMLElement) or not issubclass(type, self.extension_type):\n            raise TypeError(\"type is not a subclass of XMLElement and/or %s: %s\" % (self.extension_type.__name__, type.__name__))\n        if type in self.types:\n            raise ValueError(\"%s is already registered as a choice extension\" % type.__name__)\n        self.types.add(type)\n        self.type._xml_children_qname_map[type.qname] = (self.descriptor, type)\n        for child_class in self.type.__subclasses__():\n            child_class._xml_children_qname_map[type.qname] = (self.descriptor, type)\n\n    def unregister_extension(self, type):\n        if self.extension_type is None:\n            raise ValueError(\"The %s XML choice element of %s does not support extensions\" % (self.name, self.type.__name__))\n        try:\n            self.types.remove(type)\n        except ValueError:\n            raise ValueError(\"%s is not a registered choice extension on %s\" % (type.__name__, self.type.__name__))\n        del self.type._xml_children_qname_map[type.qname]\n        for child_class in self.type.__subclasses__():\n            del child_class._xml_children_qname_map[type.qname]\n\n\nclass XMLElementChoiceChild(object):\n    def __init__(self, name, types, extension_type=None, required=False, test_equal=True, onset=None, ondel=None):\n        self.name = name\n        self.types = set(types)\n        self.extension_type = extension_type\n        self.required = required\n        self.test_equal = test_equal\n        self.onset = onset\n        self.ondel = ondel\n        self.values = weakobjectmap()\n\n    def __get__(self, obj, objtype):\n        if obj is None:\n            return XMLElementChoiceChildWrapper(self, objtype)\n        try:\n            return self.values[obj]\n        except KeyError:\n            return None\n\n    def __set__(self, obj, value):\n        if value is not None and type(value) not in self.types:\n            raise TypeError(\"%s is not an acceptable type for %s\" % (value.__class__.__name__, obj.__class__.__name__))\n        same_value = False\n        old_value = self.values.get(obj)\n        if value is old_value:\n            return\n        elif value is not None and value == old_value:\n            value.__dirty__ = old_value.__dirty__\n            same_value = True\n        if old_value is not None:\n            obj.element.remove(old_value.element)\n        if value is not None:\n            obj._insert_element(value.element)\n        self.values[obj] = value\n        if not same_value:\n            obj.__dirty__ = True\n        if self.onset:\n            self.onset(obj, self, value)\n\n    def __delete__(self, obj):\n        try:\n            old_value = self.values.pop(obj)\n        except KeyError:\n            pass\n        else:\n            if old_value is not None:\n                obj.element.remove(old_value.element)\n                obj.__dirty__ = True\n        if self.ondel:\n            self.ondel(obj, self)\n\n\nclass XMLStringChoiceChild(XMLElementChoiceChild):\n    \"\"\"\n    A choice between keyword strings from a registry, custom strings from the\n    other type and custom extensions. This descriptor will accept and return\n    strings instead of requiring XMLElement instances for the values in the\n    registry and the other type. Check XMLEmptyElementRegistryType for a\n    metaclass for building registries of XMLEmptyElement classes for keywords.\n    \"\"\"\n\n    def __init__(self, name, registry=None, other_type=None, extension_type=None):\n        self.registry = registry\n        self.other_type = other_type\n        self.extension_type = extension_type\n        types  = registry.classes if registry is not None else ()\n        types += (other_type,) if other_type is not None else ()\n        super(XMLStringChoiceChild, self).__init__(name, types, extension_type=extension_type, required=True, test_equal=True)\n\n    def __get__(self, obj, objtype):\n        value = super(XMLStringChoiceChild, self).__get__(obj, objtype)\n        if obj is None or objtype is StoredAttribute or value is None or isinstance(value, self.extension_type or ()):\n            return value\n        else:\n            return unicode(value)\n\n    def __set__(self, obj, value):\n        if isinstance(value, basestring):\n            if self.registry is not None and value in self.registry.names:\n                value = self.registry.class_map[value]()\n            elif self.other_type is not None:\n                value = self.other_type.from_string(value)\n        super(XMLStringChoiceChild, self).__set__(obj, value)\n\n\n## XMLElement base classes\n\nclass XMLElementBase(object):\n    \"\"\"\n    This class is used as a common ancestor for XML elements and provides\n    the means for super() to find at least dummy implementations for the\n    methods that are supposed to be implemented by subclasses, even when\n    they are not implemented by any other ancestor class. This is necessary\n    in order to simplify access to these methods when multiple inheritance\n    is involved and none or only some of the classes implement them.\n    The methods declared here should to be implemented in subclasses as\n    necessary.\n    \"\"\"\n\n    def __get_dirty__(self):\n        return False\n\n    def __set_dirty__(self, dirty):\n        return\n\n    def _build_element(self):\n        return\n\n    def _parse_element(self, element):\n        return\n\n\nclass XMLElementType(type):\n    def __init__(cls, name, bases, dct):\n        super(XMLElementType, cls).__init__(name, bases, dct)\n\n        # set dictionary of xml attributes and xml child elements\n        cls._xml_attributes = {}\n        cls._xml_element_children = {}\n        cls._xml_children_qname_map = {}\n        for base in reversed(bases):\n            if hasattr(base, '_xml_attributes'):\n                cls._xml_attributes.update(base._xml_attributes)\n            if hasattr(base, '_xml_element_children') and hasattr(base, '_xml_children_qname_map'):\n                cls._xml_element_children.update(base._xml_element_children)\n                cls._xml_children_qname_map.update(base._xml_children_qname_map)\n        for name, value in dct.iteritems():\n            if isinstance(value, XMLElementID):\n                if cls._xml_id is not None:\n                    raise AttributeError(\"Only one XMLElementID attribute can be defined in the %s class\" % cls.__name__)\n                cls._xml_id = value\n                cls._xml_attributes[value.name] = value\n            elif isinstance(value, XMLAttribute):\n                cls._xml_attributes[value.name] = value\n            elif isinstance(value, XMLElementChild):\n                cls._xml_element_children[value.name] = value\n                cls._xml_children_qname_map[value.type.qname] = (value, value.type)\n            elif isinstance(value, XMLElementChoiceChild):\n                cls._xml_element_children[value.name] = value\n                for type in value.types:\n                    cls._xml_children_qname_map[type.qname] = (value, type)\n\n        # register class in its XMLDocument\n        if cls._xml_document is not None:\n            cls._xml_document.register_element(cls)\n\nclass XMLElement(XMLElementBase):\n    __metaclass__ = XMLElementType\n    \n    _xml_tag = None # To be defined in subclass\n    _xml_namespace = None # To be defined in subclass\n    _xml_document = None # To be defined in subclass\n    _xml_extension_type = None # Can be defined in subclass\n    _xml_id = None # Can be defined in subclass, or will be set by the metaclass to the XMLElementID attribute (if present)\n    _xml_children_order = {} # Can be defined in subclass\n\n    # dynamically generated\n    _xml_attributes = {}\n    _xml_element_children = {}\n    _xml_children_qname_map = {}\n\n    qname = classproperty(lambda cls: '{%s}%s' % (cls._xml_namespace, cls._xml_tag))\n\n    def __init__(self):\n        self.element = etree.Element(self.qname, nsmap=self._xml_document.nsmap)\n        self.__dirty__ = True\n\n    def __get_dirty__(self):\n        return (self.__dict__['__dirty__']\n                or any(child.__dirty__ for child in (getattr(self, name) for name in self._xml_element_children) if child is not None)\n                or super(XMLElement, self).__get_dirty__())\n\n    def __set_dirty__(self, dirty):\n        super(XMLElement, self).__set_dirty__(dirty)\n        if not dirty:\n            for child in (child for child in (getattr(self, name) for name in self._xml_element_children) if child is not None):\n                child.__dirty__ = dirty\n        self.__dict__['__dirty__'] = dirty\n\n    __dirty__ = property(__get_dirty__, __set_dirty__)\n\n    def check_validity(self):\n        # check attributes\n        for name, attribute in self._xml_attributes.iteritems():\n            # if attribute has default but it was not set, will also be added with this occasion\n            value = getattr(self, name, None)\n            if attribute.required and value is None:\n                raise ValidationError(\"required attribute %s of %s is not set\" % (name, self.__class__.__name__))\n        # check element children\n        for name, element_child in self._xml_element_children.iteritems():\n            # if child has default but it was not set, will also be added with this occasion\n            child = getattr(self, name, None)\n            if child is None and element_child.required:\n                raise ValidationError(\"element child %s of %s is not set\" % (name, self.__class__.__name__))\n\n    def to_element(self):\n        try:\n            self.check_validity()\n        except ValidationError, e:\n            raise BuilderError(str(e))\n        # build element children\n        for name in self._xml_element_children:\n            descriptor = getattr(self.__class__, name)\n            child = descriptor.__get__(self, StoredAttribute)\n            if child is not None:\n                child.to_element()\n        self._build_element()\n        return self.element\n\n    @classmethod\n    def from_element(cls, element, xml_document=None):\n        obj = cls.__new__(cls)\n        obj._xml_document = xml_document if xml_document is not None else cls._xml_document\n        obj.element = element\n        # set known attributes\n        for name, attribute in cls._xml_attributes.iteritems():\n            xmlvalue = element.get(attribute.xmlname, None)\n            if xmlvalue is not None:\n                try:\n                    setattr(obj, name, attribute.parse(xmlvalue))\n                except (ValueError, TypeError):\n                    raise ValidationError(\"got illegal value for attribute %s of %s: %s\" % (name, cls.__name__, xmlvalue))\n        # set element children\n        for child in element:\n            element_child, type = cls._xml_children_qname_map.get(child.tag, (None, None))\n            if element_child is not None:\n                try:\n                    value = type.from_element(child, xml_document=obj._xml_document)\n                except ValidationError:\n                    pass # we should accept partially valid documents\n                else:\n                    setattr(obj, element_child.name, value)\n        obj._parse_element(element)\n        obj.check_validity()\n        obj.__dirty__ = False\n        return obj\n\n    @classmethod\n    def _register_xml_attribute(cls, attribute, element):\n        cls._xml_element_children[attribute] = element\n        cls._xml_children_qname_map[element.type.qname] = (element, element.type)\n        for subclass in cls.__subclasses__():\n            subclass._register_xml_attribute(attribute, element)\n\n    @classmethod\n    def _unregister_xml_attribute(cls, attribute):\n        element = cls._xml_element_children.pop(attribute)\n        del cls._xml_children_qname_map[element.type.qname]\n        for subclass in cls.__subclasses__():\n            subclass._unregister_xml_attribute(attribute)\n\n    @classmethod\n    def register_extension(cls, attribute, type, test_equal=True):\n        if cls._xml_extension_type is None:\n            raise ValueError(\"XMLElement type %s does not support extensions (requested extension type %s)\" % (cls.__name__, type.__name__))\n        elif not issubclass(type, cls._xml_extension_type):\n            raise TypeError(\"XMLElement type %s only supports extensions of type %s (requested extension type %s)\" % (cls.__name__, cls._xml_extension_type, type.__name__))\n        elif hasattr(cls, attribute):\n            raise ValueError(\"XMLElement type %s already has an attribute named %s (requested extension type %s)\" % (cls.__name__, attribute, type.__name__))\n        extension = XMLElementChild(attribute, type=type, required=False, test_equal=test_equal)\n        setattr(cls, attribute, extension)\n        cls._register_xml_attribute(attribute, extension)\n\n    @classmethod\n    def unregister_extension(cls, attribute):\n        if cls._xml_extension_type is None:\n            raise ValueError(\"XMLElement type %s does not support extensions\" % cls.__name__)\n        cls._unregister_xml_attribute(attribute)\n        delattr(cls, attribute)\n\n    def _insert_element(self, element):\n        if element in self.element:\n            return\n        order = self._xml_children_order.get(element.tag, self._xml_children_order.get(None, sys.maxint))\n        for i in xrange(len(self.element)):\n            child_order = self._xml_children_order.get(self.element[i].tag, self._xml_children_order.get(None, sys.maxint))\n            if child_order > order:\n                position = i\n                break\n        else:\n            position = len(self.element)\n        self.element.insert(position, element)\n\n    def __eq__(self, other):\n        if isinstance(other, XMLElement):\n            if self is other:\n                return True\n            for name, attribute in self._xml_attributes.iteritems():\n                if attribute.test_equal:\n                    if not hasattr(other, name) or getattr(self, name) != getattr(other, name):\n                        return False\n            for name, element_child in self._xml_element_children.iteritems():\n                if element_child.test_equal:\n                    if not hasattr(other, name) or getattr(self, name) != getattr(other, name):\n                        return False\n            try:\n                __eq__ = super(XMLElement, self).__eq__\n            except AttributeError:\n                return True\n            else:\n                return __eq__(other)\n        elif self._xml_id is not None:\n            return self._xml_id == other\n        else:\n            return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    def __hash__(self):\n        if self._xml_id is not None:\n            return hash(self._xml_id)\n        else:\n            return object.__hash__(self)\n\n\nclass XMLRootElementType(XMLElementType):\n    def __init__(cls, name, bases, dct):\n        super(XMLRootElementType, cls).__init__(name, bases, dct)\n        if cls._xml_document is not None:\n            if cls._xml_document.root_element is not None:\n                raise TypeError('there is already a root element registered for %s' % cls.__name__)\n            cls._xml_document.root_element = cls\n\nclass XMLRootElement(XMLElement):\n    __metaclass__ = XMLRootElementType\n\n    def __init__(self):\n        XMLElement.__init__(self)\n        self.__cache__ = WeakValueDictionary({self.element: self})\n\n    @classmethod\n    def from_element(cls, element, xml_document=None):\n        obj = super(XMLRootElement, cls).from_element(element, xml_document)\n        obj.__cache__ = WeakValueDictionary({obj.element: obj})\n        return obj\n\n    @classmethod\n    def parse(cls, document):\n        return cls._xml_document.parse(document)\n\n    def toxml(self, encoding=None, pretty_print=False, validate=True):\n        return self._xml_document.build(self, encoding=encoding, pretty_print=pretty_print, validate=validate)\n\n    def xpath(self, xpath, namespaces=None):\n        result = []\n        try:\n            nodes = self.element.xpath(xpath, namespaces=namespaces)\n        except etree.XPathError:\n            raise ValueError(\"illegal XPath expression\")\n        for element in (node for node in nodes if isinstance(node, etree._Element)):\n            if element in self.__cache__:\n                result.append(self.__cache__[element])\n                continue\n            if element is self.element:\n                self.__cache__[element] = self\n                result.append(self)\n                continue\n            for ancestor in element.iterancestors():\n                if ancestor in self.__cache__:\n                    container = self.__cache__[ancestor]\n                    break\n            else:\n                container = self\n            notvisited = deque([container])\n            visited = set()\n            while notvisited:\n                container = notvisited.popleft()\n                self.__cache__[container.element] = container\n                if isinstance(container, XMLListMixin):\n                    children = set(child for child in container if isinstance(child, XMLElement) and child not in visited)\n                    visited.update(children)\n                    notvisited.extend(children)\n                for child in container._xml_element_children:\n                    value = getattr(container, child)\n                    if value is not None and value not in visited:\n                        visited.add(value)\n                        notvisited.append(value)\n            if element in self.__cache__:\n                result.append(self.__cache__[element])\n        return result\n\n    def get_xpath(self, element):\n        raise NotImplementedError\n\n    def find_parent(self, element):\n        raise NotImplementedError\n\n\n## Mixin classes\n\nclass ThisClass(object):\n    \"\"\"\n    Special marker class that is used to indicate that an XMLListElement\n    subclass can be an item of itself. This is necessary because a class\n    cannot reference itself when defining _xml_item_type\n    \"\"\"\n\n\nclass XMLListMixinType(type):\n    def __init__(cls, name, bases, dct):\n        super(XMLListMixinType, cls).__init__(name, bases, dct)\n        if '_xml_item_type' in dct:\n            cls._xml_item_type = cls._xml_item_type # trigger __setattr__\n\n    def __setattr__(cls, name, value):\n        if name == '_xml_item_type':\n            if value is ThisClass:\n                value = cls\n            elif isinstance(value, tuple) and ThisClass in value:\n                value = tuple(cls if type is ThisClass else type for type in value)\n            if value is None:\n                cls._xml_item_element_types = ()\n                cls._xml_item_extension_types = ()\n            else:\n                item_types = value if isinstance(value, tuple) else (value,)\n                cls._xml_item_element_types = tuple(type for type in item_types if issubclass(type, XMLElement))\n                cls._xml_item_extension_types = tuple(type for type in item_types if not issubclass(type, XMLElement))\n        super(XMLListMixinType, cls).__setattr__(name, value)\n\n\nclass XMLListMixin(XMLElementBase):\n    \"\"\"A mixin representing a list of other XML elements\"\"\"\n\n    __metaclass__ = XMLListMixinType\n\n    _xml_item_type = None\n\n    def __new__(cls, *args, **kw):\n        if cls._xml_item_type is None:\n            raise TypeError(\"The %s class cannot be instantiated because it doesn't define the _xml_item_type attribute\" % cls.__name__)\n        instance = super(XMLListMixin, cls).__new__(cls)\n        instance._element_map = {}\n        instance._xmlid_map = defaultdict(dict)\n        return instance\n\n    def __contains__(self, item):\n        return item in self._element_map.itervalues()\n\n    def __iter__(self):\n        return (self._element_map[element] for element in self.element if element in self._element_map)\n\n    def __len__(self):\n        return len(self._element_map)\n\n    def __repr__(self):\n        return '%s(%r)' % (self.__class__.__name__, list(self))\n\n    def __eq__(self, other):\n        if isinstance(other, XMLListMixin):\n            return self is other or (len(self) == len(other) and all(self_item == other_item for self_item, other_item in izip(self, other)))\n        else:\n            return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    def __getitem__(self, key):\n        if key is IterateTypes:\n            return (cls for cls, mapping in self._xmlid_map.iteritems() if mapping)\n        if not isinstance(key, tuple):\n            raise KeyError(key)\n        try:\n            cls, id = key\n        except ValueError:\n            raise KeyError(key)\n        if id is IterateIDs:\n            return self._xmlid_map[cls].iterkeys()\n        elif id is IterateItems:\n            return self._xmlid_map[cls].itervalues()\n        else:\n            return self._xmlid_map[cls][id]\n\n    def __delitem__(self, key):\n        if not isinstance(key, tuple):\n            raise KeyError(key)\n        try:\n            cls, id = key\n        except ValueError:\n            raise KeyError(key)\n        if id is All:\n            for item in self._xmlid_map[cls].values():\n                self.remove(item)\n        else:\n            self.remove(self._xmlid_map[cls][id])\n\n    def __get_dirty__(self):\n        return any(item.__dirty__ for item in self._element_map.itervalues()) or super(XMLListMixin, self).__get_dirty__()\n\n    def __set_dirty__(self, dirty):\n        super(XMLListMixin, self).__set_dirty__(dirty)\n        if not dirty:\n            for item in self._element_map.itervalues():\n                item.__dirty__ = dirty\n\n    def _parse_element(self, element):\n        super(XMLListMixin, self)._parse_element(element)\n        self._element_map.clear()\n        self._xmlid_map.clear()\n        for child in element[:]:\n            child_class = self._xml_document.get_element(child.tag, type(None))\n            if child_class in self._xml_item_element_types or issubclass(child_class, self._xml_item_extension_types):\n                try:\n                    value = child_class.from_element(child, xml_document=self._xml_document)\n                except ValidationError:\n                    pass\n                else:\n                    if value._xml_id is not None and value._xml_id in self._xmlid_map[child_class]:\n                        element.remove(child)\n                    else:\n                        if value._xml_id is not None:\n                            self._xmlid_map[child_class][value._xml_id] = value\n                        self._element_map[value.element] = value\n\n    def _build_element(self):\n        super(XMLListMixin, self)._build_element()\n        for child in self._element_map.itervalues():\n            child.to_element()\n\n    def add(self, item):\n        if not (item.__class__ in self._xml_item_element_types or isinstance(item, self._xml_item_extension_types)):\n            raise TypeError(\"%s cannot add items of type %s\" % (self.__class__.__name__, item.__class__.__name__))\n        same_value = False\n        if item._xml_id is not None and item._xml_id in self._xmlid_map[item.__class__]:\n            old_item = self._xmlid_map[item.__class__][item._xml_id]\n            if item is old_item:\n                return\n            elif item == old_item:\n                item.__dirty__ = old_item.__dirty__\n                same_value = True\n            self.element.remove(old_item.element)\n            del self._xmlid_map[item.__class__][item._xml_id]\n            del self._element_map[old_item.element]\n        self._insert_element(item.element)\n        if item._xml_id is not None:\n            self._xmlid_map[item.__class__][item._xml_id] = item\n        self._element_map[item.element] = item\n        if not same_value:\n            self.__dirty__ = True\n\n    def remove(self, item):\n        self.element.remove(item.element)\n        if item._xml_id is not None:\n            del self._xmlid_map[item.__class__][item._xml_id]\n        del self._element_map[item.element]\n        self.__dirty__ = True\n\n    def update(self, sequence):\n        for item in sequence:\n            self.add(item)\n\n    def clear(self):\n        for item in self._element_map.values():\n            self.remove(item)\n\n\n## Element types\n\nclass XMLSimpleElement(XMLElement):\n    _xml_value_type = None # To be defined in subclass\n\n    def __new__(cls, *args, **kw):\n        if cls._xml_value_type is None:\n            raise TypeError(\"The %s class cannot be instantiated because it doesn't define the _xml_value_type attribute\" % cls.__name__)\n        return super(XMLSimpleElement, cls).__new__(cls)\n\n    def __init__(self, value):\n        XMLElement.__init__(self)\n        self.value = value\n\n    def __eq__(self, other):\n        if isinstance(other, XMLSimpleElement):\n            return self is other or self.value == other.value\n        else:\n            return self.value == other\n\n    def __nonzero__(self):\n        return bool(self.value)\n\n    def __repr__(self):\n        return '%s(%r)' % (self.__class__.__name__, self.value)\n\n    def __str__(self):\n        return str(self.value)\n\n    def __unicode__(self):\n        return unicode(self.value)\n\n    @property\n    def value(self):\n        return self.__dict__['value']\n\n    @value.setter\n    def value(self, value):\n        if not isinstance(value, self._xml_value_type):\n            value = self._xml_value_type(value)\n        if self.__dict__.get('value', Null) == value:\n            return\n        self.__dict__['value'] = value\n        self.__dirty__ = True\n\n    def _parse_element(self, element):\n        super(XMLSimpleElement, self)._parse_element(element)\n        value = element.text or u''\n        if hasattr(self._xml_value_type, '__xmlparse__'):\n            self.value = self._xml_value_type.__xmlparse__(value)\n        else:\n            self.value = self._xml_value_type(value)\n\n    def _build_element(self):\n        super(XMLSimpleElement, self)._build_element()\n        if hasattr(self.value, '__xmlbuild__'):\n            self.element.text = self.value.__xmlbuild__()\n        else:\n            self.element.text = unicode(self.value)\n\n\nclass XMLStringElement(XMLSimpleElement):\n    _xml_value_type = unicode  # Can be overwritten in subclasses\n\n    def __len__(self):\n        return len(self.value)\n\n\nclass XMLLocalizedStringElement(XMLStringElement):\n    lang = XMLAttribute('lang', xmlname='{http://www.w3.org/XML/1998/namespace}lang', type=str, required=False, test_equal=True)\n\n    def __init__(self, value, lang=None):\n        XMLStringElement.__init__(self, value)\n        self.lang = lang\n\n    def __eq__(self, other):\n        if isinstance(other, XMLLocalizedStringElement):\n            return self is other or (self.lang == other.lang and self.value == other.value)\n        elif self.lang is None:\n            return XMLStringElement.__eq__(self, other)\n        else:\n            return NotImplemented\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.value, self.lang)\n\n    def _parse_element(self, element):\n        super(XMLLocalizedStringElement, self)._parse_element(element)\n        self.lang = element.get('{http://www.w3.org/XML/1998/namespace}lang', None)\n\n\nclass XMLBooleanElement(XMLSimpleElement):\n    _xml_value_type = Boolean\n\n\nclass XMLByteElement(XMLSimpleElement):\n    _xml_value_type = Byte\n\n\nclass XMLUnsignedByteElement(XMLSimpleElement):\n    _xml_value_type = UnsignedByte\n\n\nclass XMLShortElement(XMLSimpleElement):\n    _xml_value_type = Short\n\n\nclass XMLUnsignedShortElement(XMLSimpleElement):\n    _xml_value_type = UnsignedShort\n\n\nclass XMLIntElement(XMLSimpleElement):\n    _xml_value_type = Int\n\n\nclass XMLUnsignedIntElement(XMLSimpleElement):\n    _xml_value_type = UnsignedInt\n\n\nclass XMLLongElement(XMLSimpleElement):\n    _xml_value_type = Long\n\n\nclass XMLUnsignedLongElement(XMLSimpleElement):\n    _xml_value_type = UnsignedLong\n\n\nclass XMLIntegerElement(XMLSimpleElement):\n    _xml_value_type = int\n\n\nclass XMLPositiveIntegerElement(XMLSimpleElement):\n    _xml_value_type = PositiveInteger\n\n\nclass XMLNegativeIntegerElement(XMLSimpleElement):\n    _xml_value_type = NegativeInteger\n\n\nclass XMLNonNegativeIntegerElement(XMLSimpleElement):\n    _xml_value_type = NonNegativeInteger\n\n\nclass XMLNonPositiveIntegerElement(XMLSimpleElement):\n    _xml_value_type = NonPositiveInteger\n\n\nclass XMLDecimalElement(XMLSimpleElement):\n    _xml_value_type = Decimal\n\n\nclass XMLDateTimeElement(XMLSimpleElement):\n    _xml_value_type = DateTime\n\n\nclass XMLAnyURIElement(XMLStringElement):\n    _xml_value_type = AnyURI\n\n\nclass XMLEmptyElement(XMLElement):\n    def __repr__(self):\n        return '%s()' % self.__class__.__name__\n    def __eq__(self, other):\n        return type(self) is type(other) or NotImplemented\n    def __hash__(self):\n        return hash(self.__class__)\n\n\nclass XMLEmptyElementRegistryType(type):\n    \"\"\"A metaclass for building registries of XMLEmptyElement subclasses from names\"\"\"\n\n    def __init__(cls, name, bases, dct):\n        super(XMLEmptyElementRegistryType, cls).__init__(name, bases, dct)\n        typename = getattr(cls, '__typename__', name.partition('Registry')[0]).capitalize()\n        class BaseElementType(XMLEmptyElement):\n            def __str__(self): return self._xml_tag\n            def __unicode__(self): return unicode(self._xml_tag)\n        cls.__basetype__ = BaseElementType\n        cls.__basetype__.__name__ = 'Base%sType' % typename\n        cls.class_map = {}\n        for name in cls.names:\n            class ElementType(BaseElementType):\n                _xml_tag = name\n                _xml_namespace = cls._xml_namespace\n                _xml_document = cls._xml_document\n                _xml_id = name\n            ElementType.__name__ = typename + name.title().translate(None, '-_')\n            cls.class_map[name] = ElementType\n        cls.classes = tuple(cls.class_map[name] for name in cls.names)\n\n\n## Created using mixins\n\nclass XMLListElementType(XMLElementType, XMLListMixinType): pass\n\nclass XMLListRootElementType(XMLRootElementType, XMLListMixinType): pass\n\nclass XMLListElement(XMLElement, XMLListMixin):\n    __metaclass__ = XMLListElementType\n\n    def __nonzero__(self):\n        if self._xml_attributes or self._xml_element_children:\n            return True\n        else:\n            return len(self._element_map) != 0\n\nclass XMLListRootElement(XMLRootElement, XMLListMixin):\n    __metaclass__ = XMLListRootElementType\n\n    def __nonzero__(self):\n        if self._xml_attributes or self._xml_element_children:\n            return True\n        else:\n            return len(self._element_map) != 0\n\n\nclass XMLStringListElementType(XMLListElementType):\n    def __init__(cls, name, bases, dct):\n        if cls._xml_item_type is not None:\n            raise TypeError(\"The %s class should not define _xml_item_type, but define _xml_item_registry, _xml_item_other_type and _xml_item_extension_type instead\" % cls.__name__)\n        types = cls._xml_item_registry.classes if cls._xml_item_registry is not None else ()\n        types += tuple(type for type in (cls._xml_item_other_type, cls._xml_item_extension_type) if type is not None)\n        cls._xml_item_type = types or None\n        super(XMLStringListElementType, cls).__init__(name, bases, dct)\n\n\nclass XMLStringListElement(XMLListElement):\n    __metaclass__ = XMLStringListElementType\n\n    _xml_item_registry = None\n    _xml_item_other_type = None\n    _xml_item_extension_type = None\n\n    def __contains__(self, item):\n        if isinstance(item, basestring):\n            if self._xml_item_registry is not None and item in self._xml_item_registry.names:\n                item = self._xml_item_registry.class_map[item]()\n            elif self._xml_item_other_type is not None:\n                item = self._xml_item_other_type.from_string(item)\n        return item in self._element_map.itervalues()\n\n    def __iter__(self):\n        return (item if isinstance(item, self._xml_item_extension_types) else unicode(item) for item in super(XMLStringListElement, self).__iter__())\n\n    def add(self, item):\n        if isinstance(item, basestring):\n            if self._xml_item_registry is not None and item in self._xml_item_registry.names:\n                item = self._xml_item_registry.class_map[item]()\n            elif self._xml_item_other_type is not None:\n                item = self._xml_item_other_type.from_string(item)\n        super(XMLStringListElement, self).add(item)\n\n    def remove(self, item):\n        if isinstance(item, basestring):\n            if self._xml_item_registry is not None and item in self._xml_item_registry.names:\n                xmlitem = self._xml_item_registry.class_map[item]()\n                try:\n                    item = (entry for entry in super(XMLStringListElement, self).__iter__() if entry == xmlitem).next()\n                except StopIteration:\n                    raise KeyError(item)\n            elif self._xml_item_other_type is not None:\n                xmlitem = self._xml_item_other_type.from_string(item)\n                try:\n                    item = (entry for entry in super(XMLStringListElement, self).__iter__() if entry == xmlitem).next()\n                except StopIteration:\n                    raise KeyError(item)\n        super(XMLStringListElement, self).remove(item)\n\n\n"
  },
  {
    "path": "sipsimple/payloads/addressbook.py",
    "content": "\n\"\"\"Addressbook related payload elements\"\"\"\n\n\n__all__ = ['namespace', 'Group', 'Contact', 'ContactURI', 'Policy', 'ElementExtension', 'ElementAttributes']\n\n\nfrom application.python import Null\nfrom lxml import etree\n\nfrom sipsimple.payloads import XMLElement, XMLListElement, XMLStringElement, XMLBooleanElement, XMLElementID, XMLAttribute, XMLElementChild\nfrom sipsimple.payloads import IterateIDs, IterateItems, All\nfrom sipsimple.payloads.datatypes import AnyURI, ID\nfrom sipsimple.payloads.resourcelists import ResourceListsDocument, ListElement\n\n\nnamespace = 'urn:ag-projects:xml:ns:addressbook'\n\nResourceListsDocument.register_namespace(namespace, prefix='addressbook', schema='addressbook.xsd')\n\n\nclass ElementExtension(object): pass\n\n\nclass Name(XMLStringElement):\n    _xml_tag = 'name'\n    _xml_namespace = namespace\n    _xml_document = ResourceListsDocument\n\n\nclass ContactID(XMLStringElement):\n    _xml_tag = 'contact_id'\n    _xml_namespace = namespace\n    _xml_document = ResourceListsDocument\n    _xml_value_type = ID\n\n\nclass ContactList(XMLListElement):\n    _xml_tag = 'contacts'\n    _xml_namespace = namespace\n    _xml_document = ResourceListsDocument\n    _xml_item_type = ContactID\n\n    def __init__(self, contacts=[]):\n        XMLListElement.__init__(self)\n        self.update(contacts)\n\n    def __contains__(self, item):\n        if isinstance(item, basestring):\n            item = ContactID(item)\n        return super(ContactList, self).__contains__(item)\n\n    def __iter__(self):\n        return (item.value for item in super(ContactList, self).__iter__())\n\n    def add(self, item):\n        if isinstance(item, basestring):\n            item = ContactID(item)\n        super(ContactList, self).add(item)\n\n    def remove(self, item):\n        if isinstance(item, basestring):\n            try:\n                item = (entry for entry in super(ContactList, self).__iter__() if entry.value == item).next()\n            except StopIteration:\n                raise KeyError(item)\n        super(ContactList, self).remove(item)\n\n\nclass Group(XMLElement, ListElement):\n    _xml_tag = 'group'\n    _xml_namespace = namespace\n    _xml_extension_type = ElementExtension\n    _xml_document = ResourceListsDocument\n\n    id = XMLElementID('id', type=ID, required=True, test_equal=True)\n    name = XMLElementChild('name', type=Name, required=True, test_equal=True)\n    contacts = XMLElementChild('contacts', type=ContactList, required=True, test_equal=True)\n\n    def __init__(self, id, name, contacts=[]):\n        XMLElement.__init__(self)\n        self.id = id\n        self.name = name\n        self.contacts = ContactList(contacts)\n\n    def __unicode__(self):\n        return unicode(self.name)\n\n    def __repr__(self):\n        return '%s(%r, %r, contacts=%r)' % (self.__class__.__name__, self.id, self.name, list(self.contacts))\n\n\nclass ContactURI(XMLElement):\n    _xml_tag = 'uri'\n    _xml_namespace = namespace\n    _xml_extension_type = ElementExtension\n    _xml_document = ResourceListsDocument\n\n    id = XMLElementID('id', type=ID, required=True, test_equal=True)\n    uri = XMLAttribute('uri', type=AnyURI, required=True, test_equal=True)\n    type = XMLAttribute('type', type=unicode, required=False, test_equal=True)\n\n    def __init__(self, id, uri, type=None):\n        XMLElement.__init__(self)\n        self.id = id\n        self.uri = uri\n        self.type = type\n\n    def __unicode__(self):\n        return unicode(self.uri)\n\n    def __repr__(self):\n        return '%s(%r, %r, %r)' % (self.__class__.__name__, self.id, self.uri, self.type)\n\n\nclass ContactURIList(XMLListElement):\n    _xml_tag = 'uris'\n    _xml_namespace = namespace\n    _xml_document = ResourceListsDocument\n    _xml_item_type = ContactURI\n\n    default = XMLAttribute('default', type=str, required=False, test_equal=True)\n\n    def __init__(self, uris=[], default=None):\n        XMLListElement.__init__(self)\n        self.update(uris)\n        self.default = default\n\n    def __getitem__(self, key):\n        if key is IterateIDs:\n            return self._xmlid_map[ContactURI].iterkeys()\n        elif key is IterateItems:\n            return self._xmlid_map[ContactURI].itervalues()\n        else:\n            return self._xmlid_map[ContactURI][key]\n\n    def __delitem__(self, key):\n        if key is All:\n            for item in self._xmlid_map[ContactURI].values():\n                self.remove(item)\n        else:\n            self.remove(self._xmlid_map[ContactURI][key])\n\n    def get(self, key, default=None):\n        return self._xmlid_map[ContactURI].get(key, default)\n\n\nclass PolicyValue(str):\n    def __new__(cls, value):\n        if value not in ('allow', 'block', 'default'):\n            raise ValueError(\"Invalid policy value: %s\" % value)\n        return super(PolicyValue, cls).__new__(cls, value)\n\n\nclass PolicyString(XMLStringElement):\n    _xml_tag = 'policy'\n    _xml_namespace = namespace\n    _xml_document = ResourceListsDocument\n    _xml_value_type = PolicyValue\n\n\nclass Subscribe(XMLBooleanElement):\n    _xml_tag = 'subscribe'\n    _xml_namespace = namespace\n    _xml_document = ResourceListsDocument\n\n\nclass DialogHandling(XMLElement):\n    _xml_tag = 'dialog'\n    _xml_namespace = namespace\n    _xml_document = ResourceListsDocument\n\n    policy    = XMLElementChild('policy', type=PolicyString, required=True, test_equal=True)\n    subscribe = XMLElementChild('subscribe', type=Subscribe, required=True, test_equal=True)\n\n    def __init__(self, policy, subscribe):\n        XMLElement.__init__(self)\n        self.policy = policy\n        self.subscribe = subscribe\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.policy, self.subscribe)\n\n\nclass PresenceHandling(XMLElement):\n    _xml_tag = 'presence'\n    _xml_namespace = namespace\n    _xml_document = ResourceListsDocument\n\n    policy    = XMLElementChild('policy', type=PolicyString, required=True, test_equal=True)\n    subscribe = XMLElementChild('subscribe', type=Subscribe, required=True, test_equal=True)\n\n    def __init__(self, policy, subscribe):\n        XMLElement.__init__(self)\n        self.policy = policy\n        self.subscribe = subscribe\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.policy, self.subscribe)\n\n\nclass Contact(XMLElement, ListElement):\n    _xml_tag = 'contact'\n    _xml_namespace = namespace\n    _xml_extension_type = ElementExtension\n    _xml_document = ResourceListsDocument\n\n    id = XMLElementID('id', type=ID, required=True, test_equal=True)\n\n    name = XMLElementChild('name', type=Name, required=True, test_equal=True)\n    uris = XMLElementChild('uris', type=ContactURIList, required=True, test_equal=True)\n    dialog = XMLElementChild('dialog', type=DialogHandling, required=True, test_equal=True)\n    presence = XMLElementChild('presence', type=PresenceHandling, required=True, test_equal=True)\n\n    def __init__(self, id, name, uris=[], presence_handling=None, dialog_handling=None):\n        XMLElement.__init__(self)\n        self.id = id\n        self.name = name\n        self.uris = uris\n        self.dialog = dialog_handling or DialogHandling('default', False)\n        self.presence = presence_handling or PresenceHandling('default', False)\n\n    def __repr__(self):\n        return '%s(%r, %r, %r, %r, %r)' % (self.__class__.__name__, self.id, self.name, list(self.uris), self.presence, self.dialog)\n\n\nclass Policy(XMLElement, ListElement):\n    _xml_tag = 'policy-element'\n    _xml_namespace = namespace\n    _xml_extension_type = ElementExtension\n    _xml_document = ResourceListsDocument\n\n    id = XMLElementID('id', type=ID, required=True, test_equal=True)\n    uri = XMLAttribute('uri', type=AnyURI, required=True, test_equal=True)\n\n    name = XMLElementChild('name', type=Name, required=True, test_equal=True)\n    dialog = XMLElementChild('dialog', type=DialogHandling, required=True, test_equal=True)\n    presence = XMLElementChild('presence', type=PresenceHandling, required=True, test_equal=True)\n\n    def __init__(self, id, uri, name='', presence_handling=None, dialog_handling=None):\n        XMLElement.__init__(self)\n        self.id = id\n        self.uri = uri\n        self.name = name\n        self.dialog = dialog_handling or DialogHandling('default', False)\n        self.presence = presence_handling or PresenceHandling('default', False)\n\n    def __unicode__(self):\n        return unicode(self.uri)\n\n    def __repr__(self):\n        return '%s(%r, %r, %r, %r, %r)' % (self.__class__.__name__, self.id, self.uri, self.name, self.presence, self.dialog)\n\n\n#\n# Extensions\n#\n\nclass ElementAttributes(XMLElement, ElementExtension):\n    _xml_tag = 'attributes'\n    _xml_namespace = 'urn:ag-projects:sipsimple:xml:ns:addressbook'\n    _xml_document = ResourceListsDocument\n\n    def __init__(self, iterable=(), **attributes):\n        XMLElement.__init__(self)\n        self._attributes = dict()\n        self.update(iterable, **attributes)\n\n    def _parse_element(self, element):\n        self._attributes = dict()\n        attribute_tag = '{%s}attribute' % self._xml_namespace\n        for child in (child for child in element if child.tag == attribute_tag):\n            if 'nil' in child.attrib:\n                self[child.attrib['name']] = None\n            else:\n                self[child.attrib['name']] = unicode(child.text or u'')\n\n    def _build_element(self):\n        self.element.clear()\n        attribute_tag = '{%s}attribute' % self._xml_namespace\n        for key, value in self.iteritems():\n            child = etree.SubElement(self.element, attribute_tag, nsmap=self._xml_document.nsmap)\n            child.attrib['name'] = key\n            if value is None:\n                child.attrib['nil'] = 'true'\n            else:\n                child.text = value\n\n    def __contains__(self, key):\n        return key in self._attributes\n\n    def __iter__(self):\n        return iter(self._attributes)\n\n    def __len__(self):\n        return len(self._attributes)\n\n    def __getitem__(self, key):\n        return self._attributes[key]\n\n    def __setitem__(self, key, value):\n        if self._attributes.get(key, Null) == value:\n            return\n        self._attributes[key] = value\n        self.__dirty__ = True\n\n    def __delitem__(self, key):\n        del self._attributes[key]\n        self.__dirty__ = True\n\n    def __repr__(self):\n        return \"%s(%r)\" % (self.__class__.__name__, dict(self))\n\n    def clear(self):\n        if self._attributes:\n            self._attributes.clear()\n            self.__dirty__ = True\n\n    def get(self, key, default=None):\n        return self._attributes.get(key, default)\n\n    def has_key(self, key):\n        return key in self._attributes\n\n    def items(self):\n        return self._attributes.items()\n\n    def iteritems(self):\n        return self._attributes.iteritems()\n\n    def iterkeys(self):\n        return self._attributes.iterkeys()\n\n    def itervalues(self):\n        return self._attributes.itervalues()\n\n    def keys(self):\n        return self._attributes.keys()\n\n    def pop(self, key, *args):\n        value = self._attributes.pop(key, *args)\n        if not args or value is not args[0]:\n            self.__dirty__ = True\n        return value\n\n    def popitem(self):\n        value = self._attributes.popitem()\n        self.__dirty__ = True\n        return value\n\n    def setdefault(self, key, default=None):\n        value = self._attributes.setdefault(key, default)\n        if value is default:\n            self.__dirty__ = True\n        return value\n\n    def update(self, iterable=(), **attributes):\n        self._attributes.update(iterable, **attributes)\n        if iterable or attributes:\n            self.__dirty__ = True\n\nResourceListsDocument.register_namespace(ElementAttributes._xml_namespace, prefix='sipsimple')\nGroup.register_extension('attributes', ElementAttributes)\nContact.register_extension('attributes', ElementAttributes)\nContactURI.register_extension('attributes', ElementAttributes)\nPolicy.register_extension('attributes', ElementAttributes)\n\n\n"
  },
  {
    "path": "sipsimple/payloads/caps.py",
    "content": "\n# This module is partially broken. It breaks the core assumption of the\n# payloads infrastructure, that an element qname is unique inside a given\n# application. Fortunately, the elements with duplicate qnames are used\n# as child elements for other elements, which are not affected by the\n# problem as each element keeps it's own qname mapping for its children\n# qnames. The problem only affects different elements with the same qname\n# that are used in list elements, as currently the list element uses the\n# application's qname mapping to find the classes and that mapping is\n# broken when multiple elements with the same qname are defined.\n# In other words, this module works, but the application qname mapping\n# that is generated by it is broken.\n#\n# -Dan\n\n\"\"\"\nUser Agent Capability Extension handling according to RFC5196\n\nThis module provides an extension to PIDF to describe a user-agent\ncapabilities in the PIDF documents.\n\"\"\"\n\n\n__all__ = ['namespace',\n           'Audio',\n           'Application',\n           'Data',\n           'Control',\n           'Video',\n           'Video',\n           'Text',\n           'Message',\n           'Type',\n           'Automata',\n           'Class',\n           'Duplex',\n           'Description',\n           'EventPackages',\n           'Priority',\n           'Methods',\n           'Extensions',\n           'Scheme',\n           'Schemes',\n           'Actor',\n           'IsFocus',\n           'Languages',\n           'Language',\n           'ServiceCapabilities',\n           'Mobility',\n           'DeviceCapabilities',\n           'ServiceCapabilitiesExtension',\n           'EventPackagesExtension',\n           'PriorityExtension',\n           'MethodsExtension',\n           'ExtensionsExtension',\n           'DeviceCapabilitiesExtension',\n           'MobilityExtension',\n           # Extensions\n           'FileTransfer',\n           'ScreenSharingServer',\n           'ScreenSharingClient']\n\n\nfrom sipsimple.payloads import XMLStringElement, XMLLocalizedStringElement, XMLBooleanElement, XMLElement, XMLEmptyElement\nfrom sipsimple.payloads import XMLElementChild, XMLListElement, XMLStringListElement, XMLAttribute, XMLEmptyElementRegistryType\nfrom sipsimple.payloads.pidf import PIDFDocument, ServiceExtension, Service, DeviceExtension, Device\n\n\nnamespace = \"urn:ietf:params:xml:ns:pidf:caps\"\nPIDFDocument.register_namespace(namespace, prefix='caps', schema='caps.xsd')\n\n\n\n# Marker mixins\nclass EventPackagesExtension(object): pass\nclass PriorityExtension(object): pass\nclass MethodsExtension(object): pass\nclass ExtensionsExtension(object): pass\nclass MobilityExtension(object): pass\nclass DeviceCapabilitiesExtension(object): pass\nclass ServiceCapabilitiesExtension(object): pass\n\n\nclass ContentTypeValue(str):\n    def __new__(cls, value):\n        if len(value.split('/')) != 2:\n            raise ValueError(\"illegal value for Content-Type: %s\" % value)\n        return str.__new__(cls, value)\n\n\nclass Audio(XMLBooleanElement):\n    _xml_tag = 'audio'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n\nclass Application(XMLBooleanElement):\n    _xml_tag = 'application'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n\nclass Data(XMLBooleanElement):\n    _xml_tag = 'data'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n\nclass Control(XMLBooleanElement):\n    _xml_tag = 'control'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n\nclass Video(XMLBooleanElement):\n    _xml_tag = 'video'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n\nclass Text(XMLBooleanElement):\n    _xml_tag = 'text'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n\nclass Message(XMLBooleanElement):\n    _xml_tag = 'message'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n\nclass Automata(XMLBooleanElement):\n    _xml_tag = 'automata'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n\nclass Type(XMLStringElement):\n    _xml_tag = 'type'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_value_type = ContentTypeValue\n\n\nclass ClassRegistry(object):\n    __metaclass__ = XMLEmptyElementRegistryType\n\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    names = ('business', 'personal')\n\n\nclass ClassSupported(XMLStringListElement):\n    _xml_tag = 'supported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = ClassRegistry\n\n    def __init__(self, supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(supported)\n\n\nclass ClassNotSupported(XMLStringListElement):\n    _xml_tag = 'notsupported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = ClassRegistry\n\n    def __init__(self, not_supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(not_supported)\n\n\nclass Class(XMLElement):\n    _xml_tag = 'class'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    supported = XMLElementChild('supported', type=ClassSupported, required=False, test_equal=True)\n    not_supported = XMLElementChild('not_supported', type=ClassNotSupported, required=False, test_equal=True)\n\n    def __init__(self, supported=None, not_supported=None):\n        XMLElement.__init__(self)\n        self.supported = supported\n        self.not_supported = not_supported\n\n\nclass DuplexRegistry(object):\n    __metaclass__ = XMLEmptyElementRegistryType\n\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    names = ('full', 'half', 'receive-only', 'send-only')\n\n\nclass DuplexSupported(XMLStringListElement):\n    _xml_tag = 'supported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = DuplexRegistry\n\n    def __init__(self, supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(supported)\n\n\nclass DuplexNotSupported(XMLStringListElement):\n    _xml_tag = 'notsupported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = DuplexRegistry\n\n    def __init__(self, not_supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(not_supported)\n\n\nclass Duplex(XMLElement):\n    _xml_tag = 'duplex'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    supported = XMLElementChild('supported', type=DuplexSupported, required=False, test_equal=True)\n    not_supported = XMLElementChild('not_supported', type=DuplexNotSupported, required=False, test_equal=True)\n\n    def __init__(self, supported=None, not_supported=None):\n        XMLElement.__init__(self)\n        self.supported = supported\n        self.not_supported = not_supported\n\n\nclass EventRegistry(object):\n    __metaclass__ = XMLEmptyElementRegistryType\n\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    names = ('conference', 'dialog', 'kpml', 'message-summary', 'poc-settings',\n             'presence', 'reg', 'refer', 'Siemens-RTP-Stats', 'spirits-INDPs',\n             'spirits-user-prof', 'winfo')\n\n\nclass EventSupported(XMLStringListElement):\n    _xml_tag = 'supported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = EventRegistry\n\n    def __init__(self, supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(supported)\n\n\nclass EventNotSupported(XMLStringListElement):\n    _xml_tag = 'notsupported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = EventRegistry\n\n    def __init__(self, not_supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(not_supported)\n\n\nclass EventPackages(XMLElement):\n    _xml_tag = 'event-packages'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_extension_type = EventPackagesExtension\n\n    supported = XMLElementChild('supported', type=EventSupported, required=False, test_equal=True)\n    not_supported = XMLElementChild('not_supported', type=EventNotSupported, required=False, test_equal=True)\n\n    def __init__(self, supported=None, not_supported=None):\n        XMLElement.__init__(self)\n        self.supported = supported\n        self.not_supported = not_supported\n\n\nclass PriorityLowerthan(XMLEmptyElement):\n    _xml_tag = 'lowerthan'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    maxvalue = XMLAttribute('maxvalue', type=int, required=True, test_equal=True)\n\n    def __init__(self, maxvalue):\n        XMLEmptyElement.__init__(self)\n        self.maxvalue = maxvalue\n\n\nclass PriorityHigherthan(XMLEmptyElement):\n    _xml_tag = 'higherthan'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    minvalue = XMLAttribute('minvalue', type=int, required=True, test_equal=True)\n\n    def __init__(self, minvalue):\n        XMLEmptyElement.__init__(self)\n        self.minvalue = minvalue\n\n\nclass PriorityEquals(XMLEmptyElement):\n    _xml_tag = 'equals'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    value = XMLAttribute('value', type=int, required=True, test_equal=True)\n\n    def __init__(self, value):\n        XMLEmptyElement.__init__(self)\n        self.value = value\n\n\nclass PriorityRange(XMLEmptyElement):\n    _xml_tag = 'range'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    maxvalue = XMLAttribute('maxvalue', type=int, required=True, test_equal=True)\n    minvalue = XMLAttribute('minvalue', type=int, required=True, test_equal=True)\n\n    def __init__(self, maxvalue, minvalue):\n        XMLEmptyElement.__init__(self)\n        self.maxvalue = maxvalue\n        self.minvalue = minvalue\n\n\nclass PrioritySupported(XMLListElement):\n    _xml_tag = 'supported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_type = (PriorityLowerthan, PriorityHigherthan, PriorityEquals, PriorityRange)\n\n    def __init__(self, supported=[]):\n        XMLListElement.__init__(self)\n        self.update(supported)\n\n\nclass PriorityNotSupported(XMLListElement):\n    _xml_tag = 'notsupported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_type = (PriorityLowerthan, PriorityHigherthan, PriorityEquals, PriorityRange)\n\n    def __init__(self, not_supported=[]):\n        XMLListElement.__init__(self)\n        self.update(not_supported)\n\n\nclass Priority(XMLElement):\n    _xml_tag = 'priority'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_extension_type = PriorityExtension\n\n    supported = XMLElementChild('supported', type=PrioritySupported, required=False, test_equal=True)\n    not_supported = XMLElementChild('not_supported', type=PriorityNotSupported, required=False, test_equal=True)\n\n    def __init__(self, supported=None, not_supported=None):\n        XMLElement.__init__(self)\n        self.supported = supported\n        self.not_supported = not_supported\n\n\nclass MethodRegistry(object):\n    __metaclass__ = XMLEmptyElementRegistryType\n\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    names = ('ACK', 'BYE', 'CANCEL', 'INFO', 'INVITE', 'MESSAGE',\n             'NOTIFY', 'OPTIONS', 'PRACK', 'PUBLISH', 'REFER',\n             'REGISTER', 'SUBSCRIBE', 'UPDATE')\n\n\nclass MethodSupported(XMLStringListElement):\n    _xml_tag = 'supported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = MethodRegistry\n\n    def __init__(self, supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(supported)\n\n\nclass MethodNotSupported(XMLStringListElement):\n    _xml_tag = 'notsupported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = MethodRegistry\n\n    def __init__(self, not_supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(not_supported)\n\n\nclass Methods(XMLElement):\n    _xml_tag = 'methods'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_extension_type = MethodsExtension\n\n    supported = XMLElementChild('supported', type=MethodSupported, required=False, test_equal=True)\n    not_supported = XMLElementChild('not_supported', type=MethodNotSupported, required=False, test_equal=True)\n\n    def __init__(self, supported=None, not_supported=None):\n        XMLElement.__init__(self)\n        self.supported = supported\n        self.not_supported = not_supported\n\n\nclass ExtensionRegistry(object):\n    __metaclass__ = XMLEmptyElementRegistryType\n\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    names = ('rel100', 'early-session', 'eventlist', 'from-change', 'gruu',\n             'histinfo', 'join', 'norefsub', 'path', 'precondition', 'pref',\n             'privacy', 'recipient-list-invite', 'recipient-list-subscribe',\n             'replaces', 'resource-priority', 'sdp-anat', 'sec-agree',\n             'tdialog', 'timer')\n\n\nclass ExtensionSupported(XMLStringListElement):\n    _xml_tag = 'supported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = ExtensionRegistry\n\n    def __init__(self, supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(supported)\n\n\nclass ExtensionNotSupported(XMLStringListElement):\n    _xml_tag = 'notsupported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = ExtensionRegistry\n\n    def __init__(self, not_supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(not_supported)\n\n\nclass Extensions(XMLElement):\n    _xml_tag = 'extensions'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_extension_type = ExtensionsExtension\n\n    supported = XMLElementChild('supported', type=ExtensionSupported, required=False, test_equal=True)\n    not_supported = XMLElementChild('not_supported', type=ExtensionNotSupported, required=False, test_equal=True)\n\n    def __init__(self, supported=None, not_supported=None):\n        XMLElement.__init__(self)\n        self.supported = supported\n        self.not_supported = not_supported\n\n\nclass Scheme(XMLStringElement):\n    _xml_tag = 's'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n\nclass SchemeSupported(XMLListElement):\n    _xml_tag = 'supported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_type = Scheme\n\n    def __init__(self, supported=[]):\n        XMLListElement.__init__(self)\n        self.update(supported)\n\n\nclass SchemeNotSupported(XMLListElement):\n    _xml_tag = 'notsupported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_type = Scheme\n\n    def __init__(self, not_supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(not_supported)\n\n\nclass Schemes(XMLElement):\n    _xml_tag = 'schemes'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    supported = XMLElementChild('supported', type=SchemeSupported, required=False, test_equal=True)\n    not_supported = XMLElementChild('not_supported', type=SchemeNotSupported, required=False, test_equal=True)\n\n    def __init__(self, supported=None, not_supported=None):\n        XMLElement.__init__(self)\n        self.supported = supported\n        self.not_supported = not_supported\n\n\nclass ActorRegistry(object):\n    __metaclass__ = XMLEmptyElementRegistryType\n\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    names = ('principal', 'attendant', 'msg-taker', 'information')\n\n\nclass ActorSupported(XMLStringListElement):\n    _xml_tag = 'supported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = ActorRegistry\n\n    def __init__(self, supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(supported)\n\n\nclass ActorNotSupported(XMLStringListElement):\n    _xml_tag = 'notsupported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = ActorRegistry\n\n    def __init__(self, not_supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(not_supported)\n\n\nclass Actor(XMLElement):\n    _xml_tag = 'actor'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    supported = XMLElementChild('supported', type=ActorSupported, required=False, test_equal=True)\n    not_supported = XMLElementChild('not_supported', type=ActorNotSupported, required=False, test_equal=True)\n\n    def __init__(self, supported=None, not_supported=None):\n        XMLElement.__init__(self)\n        self.supported = supported\n        self.not_supported = not_supported\n\n\nclass Language(XMLStringElement):\n    _xml_tag = 'l'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n\nclass LanguageSupported(XMLListElement):\n    _xml_tag = 'supported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_type = Language\n\n    def __init__(self, supported=[]):\n        XMLListElement.__init__(self)\n        self.update(supported)\n\n    def __iter__(self):\n        return (unicode(item) for item in super(LanguageSupported, self).__iter__())\n\n    def add(self, item):\n        if isinstance(item, basestring):\n            item = Language(item)\n        super(LanguageSupported, self).add(item)\n\n    def remove(self, item):\n        if isinstance(item, basestring):\n            try:\n                item = (entry for entry in super(LanguageSupported, self).__iter__() if entry == item).next()\n            except StopIteration:\n                raise KeyError(item)\n        super(LanguageSupported, self).remove(item)\n\n\nclass LanguageNotSupported(XMLListElement):\n    _xml_tag = 'notsupported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_type = Language\n\n    def __init__(self, not_supported=[]):\n        XMLListElement.__init__(self)\n        self.update(not_supported)\n\n    def __iter__(self):\n        return (unicode(item) for item in super(LanguageNotSupported, self).__iter__())\n\n    def add(self, item):\n        if isinstance(item, basestring):\n            item = Language(item)\n        super(LanguageNotSupported, self).add(item)\n\n    def remove(self, item):\n        if isinstance(item, basestring):\n            try:\n                item = (entry for entry in super(LanguageNotSupported, self).__iter__() if entry == item).next()\n            except StopIteration:\n                raise KeyError(item)\n        super(LanguageNotSupported, self).remove(item)\n\n\nclass Languages(XMLElement):\n    _xml_tag = 'languages'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    supported = XMLElementChild('supported', type=LanguageSupported, required=False, test_equal=True)\n    not_supported = XMLElementChild('not_supported', type=LanguageNotSupported, required=False, test_equal=True)\n\n    def __init__(self, supported=None, not_supported=None):\n        XMLElement.__init__(self)\n        self.supported = supported\n        self.not_supported = not_supported\n\n\nclass Description(XMLLocalizedStringElement):\n    _xml_tag = 'description'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n\nclass IsFocus(XMLBooleanElement):\n    _xml_tag = 'isfocus'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n\nclass ServiceCapabilities(XMLListElement, ServiceExtension):\n    _xml_tag = 'servcaps'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_extension_type = ServiceCapabilitiesExtension\n    _xml_item_type = Description\n    _xml_children_order = {Actor.qname: 0,\n                           Application.qname: 1,\n                           Audio.qname: 2,\n                           Automata.qname: 3,\n                           Class.qname: 4,\n                           Control.qname: 5,\n                           Data.qname: 6,\n                           Description.qname: 7,\n                           Duplex.qname: 8,\n                           EventPackages.qname: 9,\n                           Extensions.qname: 10,\n                           IsFocus.qname: 11,\n                           Message.qname: 12,\n                           Methods.qname: 13,\n                           Languages.qname: 14,\n                           Priority.qname: 15,\n                           Schemes.qname: 16,\n                           Text.qname: 17,\n                           Type.qname: 18,\n                           Video.qname: 19,\n                           None: 20}\n\n    audio = XMLElementChild('audio', type=Audio, required=False, test_equal=True)\n    application = XMLElementChild('application', type=Application, required=False, test_equal=True)\n    data = XMLElementChild('data', type=Data, required=False, test_equal=True)\n    control = XMLElementChild('control', type=Control, required=False, test_equal=True)\n    video = XMLElementChild('video', type=Video, required=False, test_equal=True)\n    text = XMLElementChild('text', type=Text, required=False, test_equal=True)\n    message = XMLElementChild('message', type=Message, required=False, test_equal=True)\n    mime_type = XMLElementChild('mime_type', type=Type, required=False, test_equal=True)\n    automata = XMLElementChild('automata', type=Automata, required=False, test_equal=True)\n    communication_class = XMLElementChild('communication_class', type=Class, required=False, test_equal=True)\n    duplex = XMLElementChild('duplex', type=Duplex, required=False, test_equal=True)\n    event_packages = XMLElementChild('event_packages', type=EventPackages, required=False, test_equal=True)\n    priority = XMLElementChild('priority', type=Priority, required=False, test_equal=True)\n    methods = XMLElementChild('methods', type=Methods, required=False, test_equal=True)\n    extensions = XMLElementChild('extensions', type=Extensions, required=False, test_equal=True)\n    schemes = XMLElementChild('schemes', type=Schemes, required=False, test_equal=True)\n    actor = XMLElementChild('actor', type=Actor, required=False, test_equal=True)\n    is_focus = XMLElementChild('is_focus', type=IsFocus, required=False, test_equal=True)\n    languages = XMLElementChild('languages', type=Languages, required=False, test_equal=True)\n\n    def __init__(self, audio=None, application=None, data=None, control=None, video=None, text=None, message=None, mime_type=None, automata=None, communication_class=None, duplex=None, event_packages=None, priority=None, methods=None, extensions=None, schemes=None, actor=None, is_focus=None, languages=None, descriptions=[]):\n        XMLListElement.__init__(self)\n        self.audio = audio\n        self.application = application\n        self.data = data\n        self.control = control\n        self.video = video\n        self.text = text\n        self.message = message\n        self.mime_type = mime_type\n        self.automata = automata\n        self.communication_class = communication_class\n        self.duplex = duplex\n        self.event_packages = event_packages\n        self.priority = priority\n        self.methods = methods\n        self.extensions = extensions\n        self.schemes = schemes\n        self.actor = actor\n        self.is_focus = is_focus\n        self.languages = languages\n        self.update(descriptions)\n\nService.register_extension('capabilities', type=ServiceCapabilities)\n\n\nclass MobilityRegistry(object):\n    __metaclass__ = XMLEmptyElementRegistryType\n\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    names = ('fixed', 'mobile')\n\n\nclass MobilitySupported(XMLStringListElement):\n    _xml_tag = 'supported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = MobilityRegistry\n\n    def __init__(self, supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(supported)\n\n\nclass MobilityNotSupported(XMLStringListElement):\n    _xml_tag = 'notsupported'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_item_registry = MobilityRegistry\n\n    def __init__(self, not_supported=[]):\n        XMLStringListElement.__init__(self)\n        self.update(not_supported)\n\n\nclass Mobility(XMLElement):\n    _xml_tag = 'mobility'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_extension_type = MobilityExtension\n\n    supported = XMLElementChild('supported', type=MobilitySupported, required=False, test_equal=True)\n    not_supported = XMLElementChild('not_supported', type=MobilityNotSupported, required=False, test_equal=True)\n\n    def __init__(self, supported=None, not_supported=None):\n        XMLElement.__init__(self)\n        self.supported = supported()\n        self.not_supported = not_supported\n\n\nclass DeviceCapabilities(XMLListElement, DeviceExtension):\n    _xml_tag = 'devcaps'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_extension_type = DeviceCapabilitiesExtension\n    _xml_item_type = Description\n\n    mobility = XMLElementChild('mobility', type=Mobility, required=False, test_equal=True)\n\n    def __init__(self, mobility=None, descriptions=[]):\n        XMLListElement.__init__(self)\n        self.mobility = mobility\n        self.update(descriptions)\n\n    def __repr__(self):\n        return \"%s(%r, %r)\" % (self.__class__.__name__, self.mobility, list(self))\n\nDevice.register_extension('capabilities', type=DeviceCapabilities)\n\n\n#\n# Extensions\n#\n\nagp_caps_namespace = 'urn:ag-projects:xml:ns:pidf:caps'\nPIDFDocument.register_namespace(agp_caps_namespace, prefix='agp-caps')\n\nclass FileTransfer(XMLBooleanElement, ServiceCapabilitiesExtension):\n    _xml_tag = 'file-transfer'\n    _xml_namespace = agp_caps_namespace\n    _xml_document = PIDFDocument\n\nclass ScreenSharingServer(XMLBooleanElement, ServiceCapabilitiesExtension):\n    _xml_tag = 'screen-sharing-server'\n    _xml_namespace = agp_caps_namespace\n    _xml_document = PIDFDocument\n\nclass ScreenSharingClient(XMLBooleanElement, ServiceCapabilitiesExtension):\n    _xml_tag = 'screen-sharing-client'\n    _xml_namespace = agp_caps_namespace\n    _xml_document = PIDFDocument\n\nServiceCapabilities.register_extension('file_transfer', type=FileTransfer)\nServiceCapabilities.register_extension('screen_sharing_server', type=ScreenSharingServer)\nServiceCapabilities.register_extension('screen_sharing_client', type=ScreenSharingClient)\n\n\n"
  },
  {
    "path": "sipsimple/payloads/cipid.py",
    "content": "\n\"\"\"\nCIPID handling according to RFC4482\n\nThis module provides an extension to PIDF to provide additional contact\ninformation about a presentity.\n\"\"\"\n\nfrom sipsimple.payloads import XMLAnyURIElement, XMLLocalizedStringElement\nfrom sipsimple.payloads.pidf import PIDFDocument, ServiceExtension, PersonExtension, Service, Person\n\n__all__ = ['namespace', 'Card', 'DisplayName', 'Homepage', 'Icon', 'Map', 'Sound']\n\nnamespace = \"urn:ietf:params:xml:ns:pidf:cipid\"\nPIDFDocument.register_namespace(namespace, prefix='c', schema='cipid.xsd')\n\n\nclass Card(XMLAnyURIElement, PersonExtension, ServiceExtension):\n    _xml_tag = 'card'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\nPerson.register_extension('card', type=Card)\nService.register_extension('card', type=Card)\n\nclass DisplayName(XMLLocalizedStringElement, PersonExtension, ServiceExtension):\n    _xml_tag = 'display-name'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\nPerson.register_extension('display_name', type=DisplayName)\nService.register_extension('display_name', type=DisplayName)\n\nclass Homepage(XMLAnyURIElement, PersonExtension, ServiceExtension):\n    _xml_tag = 'homepage'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\nPerson.register_extension('homepage', type=Homepage)\nService.register_extension('homepage', type=Homepage)\n\nclass Icon(XMLAnyURIElement, PersonExtension, ServiceExtension):\n    _xml_tag = 'icon'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\nPerson.register_extension('icon', type=Icon)\nService.register_extension('icon', type=Icon)\n\nclass Map(XMLAnyURIElement, PersonExtension, ServiceExtension):\n    _xml_tag = 'map'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\nPerson.register_extension('map', type=Map)\nService.register_extension('map', type=Map)\n\nclass Sound(XMLAnyURIElement, PersonExtension, ServiceExtension):\n    _xml_tag = 'sound'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\nPerson.register_extension('sound', type=Sound)\nService.register_extension('sound', type=Sound)\n\n"
  },
  {
    "path": "sipsimple/payloads/commonpolicy.py",
    "content": "\n\"\"\"\nGeneric data types to be used in policy applications, according to\nRFC4745.\n\"\"\"\n\n\n__all__ = ['namespace',\n           'CommonPolicyDocument',\n           'ConditionElement',\n           'ActionElement',\n           'TransformationElement',\n           'RuleExtension',\n           'IdentityOne',\n           'IdentityExcept',\n           'IdentityMany',\n           'Identity',\n           'Validity',\n           'Conditions',\n           'Actions',\n           'Transformations',\n           'Rule',\n           'RuleSet',\n           # Extensions\n           'FalseCondition',\n           'RuleDisplayName']\n\n\nfrom sipsimple.payloads import ValidationError, XMLDocument, XMLElement, XMLListElement, XMLListRootElement, XMLAttribute, XMLElementID, XMLElementChild, XMLLocalizedStringElement, XMLDateTimeElement\nfrom sipsimple.payloads import IterateIDs, IterateItems, All\nfrom sipsimple.payloads.datatypes import AnyURI, ID\n\n\nnamespace = 'urn:ietf:params:xml:ns:common-policy'\n\n\nclass CommonPolicyDocument(XMLDocument):\n    content_type = 'application/auth-policy+xml'\n\nCommonPolicyDocument.register_namespace(namespace, prefix='cp', schema='common-policy.xsd')\n\n\n## Mixin types for extensibility\n\nclass ConditionElement(object): pass\nclass ActionElement(object): pass\nclass TransformationElement(object): pass\nclass RuleExtension(object): pass\n\n\n## Elements\n\nclass IdentityOne(XMLElement):\n    _xml_tag = 'one'\n    _xml_namespace = namespace\n    _xml_document = CommonPolicyDocument\n\n    id = XMLElementID('id', type=AnyURI, required=True, test_equal=True)\n\n    def __init__(self, id):\n        XMLElement.__init__(self)\n        self.id = id\n\n    def __repr__(self):\n        return '%s(%r)' % (self.__class__.__name__, self.id)\n\n    def __str__(self):\n        return self.id\n\n    def matches(self, uri):\n        return self.id == uri\n\n\nclass IdentityExcept(XMLElement):\n    _xml_tag = 'except'\n    _xml_namespace = namespace\n    _xml_document = CommonPolicyDocument\n\n    def _onset_id(self, attribute, value):\n        if value is not None:\n            self.domain = None\n    id = XMLAttribute('id', type=str, required=False, test_equal=True, onset=_onset_id)\n    del _onset_id\n\n    def _onset_domain(self, attribute, value):\n        if value is not None:\n            self.id = None\n    domain = XMLAttribute('domain', type=str, required=False, test_equal=True, onset=_onset_domain)\n    del _onset_domain\n\n    def __init__(self, id=None, domain=None):\n        XMLElement.__init__(self)\n        self.id = id\n        self.domain = domain\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.id, self.domain)\n\n    def __str__(self):\n        if self.id is not None:\n            return self.id\n        else:\n            return self.domain\n\n    def matches(self, uri):\n        if self.id is not None:\n            return self.id != uri\n        else:\n            return [self.domain] != uri.split('@', 1)[1:]\n\n\nclass IdentityMany(XMLListElement):\n    _xml_tag = 'many'\n    _xml_namespace = namespace\n    _xml_document = CommonPolicyDocument\n    _xml_children_order = {IdentityExcept.qname: 0}\n    _xml_item_type = IdentityExcept\n\n    domain = XMLAttribute('domain', type=str, required=False, test_equal=True)\n\n    def __init__(self, domain=None, exceptions=[]):\n        XMLListElement.__init__(self)\n        self.domain = domain\n        self.update(exceptions)\n\n    def __repr__(self):\n        return '%s(%r, %s)' % (self.__class__.__name__, self.domain, list(self))\n\n    def matches(self, uri):\n        if self.domain is not None:\n            if self.domain != uri.partition('@')[2]:\n                return False\n        for child in self:\n            if not child.matches(uri):\n                return False\n        return True\n\n\nclass Identity(XMLListElement):\n    _xml_tag = 'identity'\n    _xml_namespace = namespace\n    _xml_document = CommonPolicyDocument\n    _xml_item_type = (IdentityOne, IdentityMany)\n\n    def __init__(self, identities=[]):\n        XMLListElement.__init__(self)\n        self.update(identities)\n\n    def matches(self, uri):\n        for child in self:\n            if child.matches(uri):\n                return True\n        return False\n\n\nclass Sphere(XMLElement):\n    _xml_tag = 'sphere'\n    _xml_namespace = namespace\n    _xml_document = CommonPolicyDocument\n\n    value = XMLAttribute('value', type=str, required=True, test_equal=True)\n\n    def __init__(self, value):\n        XMLElement.__init__(self)\n        self.value = value\n\n    def __repr__(self):\n        return '%s(%r)' % (self.__class__.__name__, self.value)\n\n\nclass ValidFrom(XMLDateTimeElement):\n    _xml_tag = 'from'\n    _xml_namespace = namespace\n    _xml_document = CommonPolicyDocument\n\n\nclass ValidUntil(XMLDateTimeElement):\n    _xml_tag = 'until'\n    _xml_namespace = namespace\n    _xml_document = CommonPolicyDocument\n\n\nclass ValidityInterval(object):\n    def __init__(self, from_timestamp, until_timestamp):\n        self.valid_from = ValidFrom(from_timestamp)\n        self.valid_until = ValidUntil(until_timestamp)\n\n    def __eq__(self, other):\n        if isinstance(other, ValidityInterval):\n            return self is other or (self.valid_from == other.valid_from and self.valid_until == other.valid_until)\n        return NotImplemented\n\n    def __ne__(self, other):\n        if isinstance(other, ValidityInterval):\n            return self is not other and (self.valid_from != other.valid_from or self.valid_until != other.valid_until)\n        return NotImplemented\n\n    @classmethod\n    def from_elements(cls, from_element, until_element, xml_document=None):\n        instance = object.__new__(cls)\n        instance.valid_from = ValidFrom.from_element(from_element, xml_document)\n        instance.valid_until = ValidUntil.from_element(until_element, xml_document)\n        return instance\n\n\nclass Validity(XMLListElement):\n    _xml_tag = 'validity'\n    _xml_namespace = namespace\n    _xml_document = CommonPolicyDocument\n    _xml_item_type = ValidityInterval\n\n    def __init__(self, children=[]):\n        XMLListElement.__init__(self)\n        self.update(children)\n\n    def _parse_element(self, element):\n        iterator = iter(element)\n        for first_child in iterator:\n            second_child = iterator.next()\n            if first_child.tag == '{%s}from' % self._xml_namespace and second_child.tag == '{%s}until' % self._xml_namespace:\n                try:\n                    item = ValidityInterval.from_elements(first_child, second_child, xml_document=self._xml_document)\n                except:\n                    pass\n                else:\n                    self._element_map[item.valid_from.element] = item\n\n    def _build_element(self):\n        for child in self:\n            child.valid_from.to_element()\n            child.valid_until.to_element()\n\n    def add(self, item):\n        if not isinstance(item, ValidityInterval):\n            raise TypeError(\"Validity element must be a ValidityInterval instance\")\n        self._insert_element(item.valid_from.element)\n        self._insert_element(item.valid_until.element)\n        self._element_map[item.valid_from.element] = item\n        self.__dirty__ = True\n\n    def remove(self, item):\n        self.element.remove(item.valid_from.element)\n        self.element.remove(item.valid_until.element)\n        del self._element_map[item.valid_from.element]\n        self.__dirty__ = True\n\n    def check_validity(self):\n        if not self:\n            raise ValidationError(\"cannot have Validity element without any children\")\n        super(Validity, self).check_validity(self)\n\n\nclass Conditions(XMLListElement):\n    _xml_tag = 'conditions'\n    _xml_namespace = namespace\n    _xml_document = CommonPolicyDocument\n    _xml_children_order = {Identity.qname: 0,\n                           Sphere.qname: 1,\n                           Validity.qname: 2}\n    _xml_item_type = (Identity, Sphere, Validity, ConditionElement)\n\n    def __init__(self, conditions=[]):\n        XMLListElement.__init__(self)\n        self.update(conditions)\n\n\nclass Actions(XMLListElement):\n    _xml_tag = 'actions'\n    _xml_namespace = namespace\n    _xml_document = CommonPolicyDocument\n    _xml_item_type = ActionElement\n\n    def __init__(self, actions=[]):\n        XMLListElement.__init__(self)\n        self.update(actions)\n\n\nclass Transformations(XMLListElement):\n    _xml_tag = 'transformations'\n    _xml_namespace = namespace\n    _xml_document = CommonPolicyDocument\n    _xml_item_type = TransformationElement\n\n    def __init__(self, transformations=[]):\n        XMLListElement.__init__(self)\n        self.update(transformations)\n\n\nclass Rule(XMLElement):\n    _xml_tag = 'rule'\n    _xml_namespace = namespace\n    _xml_extension_type = RuleExtension\n    _xml_document = CommonPolicyDocument\n    _xml_children_order = {Conditions.qname: 0,\n                           Actions.qname: 1,\n                           Transformations.qname: 2}\n\n    id = XMLElementID('id', type=ID, required=True, test_equal=True)\n\n    conditions = XMLElementChild('conditions', type=Conditions, required=False, test_equal=True)\n    actions = XMLElementChild('actions', type=Actions, required=False, test_equal=True)\n    transformations = XMLElementChild('transformations', type=Transformations, required=False, test_equal=True)\n\n    def __init__(self, id, conditions=None, actions=None, transformations=None):\n        XMLElement.__init__(self)\n        self.id = id\n        self.conditions = conditions\n        self.actions = actions\n        self.transformations = transformations\n\n    def __repr__(self):\n        return '%s(%r, %r, %r, %r)' % (self.__class__.__name__, self.id, self.conditions, self.actions, self.transformations)\n\n\nclass RuleSet(XMLListRootElement):\n    _xml_tag = 'ruleset'\n    _xml_namespace = namespace\n    _xml_document = CommonPolicyDocument\n    _xml_item_type = Rule\n\n    def __init__(self, rules=[]):\n        XMLListRootElement.__init__(self)\n        self.update(rules)\n\n    def __getitem__(self, key):\n        if key is IterateIDs:\n            return self._xmlid_map[Rule].iterkeys()\n        elif key is IterateItems:\n            return self._xmlid_map[Rule].itervalues()\n        else:\n            return self._xmlid_map[Rule][key]\n\n    def __delitem__(self, key):\n        if key is All:\n            for item in self._xmlid_map[Rule].values():\n                self.remove(item)\n        else:\n            self.remove(self._xmlid_map[Rule][key])\n\n    def get(self, key, default=None):\n        return self._xmlid_map[Rule].get(key, default)\n\n\n#\n# Extensions\n#\n\nagp_cp_namespace = 'urn:ag-projects:xml:ns:common-policy'\nCommonPolicyDocument.register_namespace(agp_cp_namespace, prefix='agp-cp')\n\n# A condition element in the AG Projects namespace, it will always be evaluated to false\n# because it's not understood by servers\nclass FalseCondition(XMLElement, ConditionElement):\n    _xml_tag = 'false-condition'\n    _xml_namespace = agp_cp_namespace\n    _xml_document = CommonPolicyDocument\n\n\nclass RuleDisplayName(XMLLocalizedStringElement, RuleExtension):\n    _xml_tag = 'display-name'\n    _xml_namespace = agp_cp_namespace\n    _xml_document = CommonPolicyDocument\n\nRule.register_extension('display_name', RuleDisplayName)\n\n"
  },
  {
    "path": "sipsimple/payloads/conference.py",
    "content": "\n# This module is currently broken. It breaks the core assumption of the\n# payloads infrastructure, that there is only one element with a given qname\n# for every given application.\n# Currently this module defines at least 2 different elements with the same\n# qname (tag=entry) which are used inside list elements. As a result, when\n# the list element tries to lookup the class to use for a given qname, only\n# one list element will get the class right, the other will get a wrong class\n# because the list element uses the application qname map to determine the\n# class and that mapping can only contain 1 mapping from a given qname to a\n# class. Since the class it obtains is not the right one, it will be ignored\n# as it doesn't match the known item types for that list element and the\n# corresponding xml data will also be ignored.\n#\n# To make matters even worse, this module subclasses XMLElement classes\n# without changing their qname, which in turn generates even more overlapping\n# classes for a given qname. At least according to the xml schema, all these\n# subclasses (which seem to be defined in order to impose some restrictions\n# in different cases), seem to be unnecessary. The schema only defines one\n# type with a string element that has no resctrictions and is to be used\n# in all the places. The code however tries to use a variation of the type\n# with restrictions in different places and fails as the correct class cannot\n# be identified anymore (see for example all the UrisType subclasses or the\n# multiple classes to define purpose elements).\n#\n# -Dan\n#\n\n\"\"\"Parses and produces conference-info messages according to RFC4575.\"\"\"\n\n\n__all__ = ['namespace', \n        'ConferenceDocument',\n        'ConferenceDescription',\n        'ConfUris',\n        'ConfUrisEntry',\n        'ServiceUris',\n        'ServiceUrisEntry',\n        'UrisTypeModified',\n        'UrisTypeEntry',\n        'AvailableMedia',\n        'AvailableMediaEntry',\n        'Users',\n        'User',\n        'UserExtension',\n        'AssociatedAors',\n        'Roles',\n        'Role',\n        'Endpoint',\n        'CallInfo',\n        'Sip',\n        'Referred',\n        'JoiningInfo',\n        'DisconnectionInfo',\n        'HostInfo',\n        'HostInfoUris',\n        'ConferenceState',\n        'SidebarsByRef',\n        'SidebarsByVal',\n        'Conference',\n        'ConferenceDescriptionExtension',\n        # Extensions\n        'FileResource',\n        'FileResources',\n        'Resources']\n\n\nfrom sipsimple.payloads import ValidationError, XMLDocument, XMLRootElement, XMLStringElement, XMLBooleanElement, XMLDateTimeElement, XMLUnsignedIntElement, XMLAnyURIElement\nfrom sipsimple.payloads import XMLElementChild, XMLElement, XMLListElement, XMLAttribute\n\n\nnamespace = 'urn:ietf:params:xml:ns:conference-info'\n\n\nclass ConferenceDocument(XMLDocument):\n    content_type = \"application/conference-info+xml\"\n\nConferenceDocument.register_namespace(namespace, prefix=None, schema='conference.xsd')\n\n\n# Marker mixins\nclass UserExtension(object): pass\n\nclass ConferenceDescriptionExtension(object): pass\n\n\nclass State(str):\n    def __new__(cls, value):\n        if value not in ('full', 'partial', 'deleted'):\n            raise ValueError(\"illegal value for state\")\n        return str.__new__(cls, value)\n\n\nclass Version(str):\n    def __new__(cls, value):\n        return str.__new__(cls, int(value))\n\n\nclass When(XMLDateTimeElement):\n    _xml_tag = 'when'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass Reason(XMLStringElement):\n    _xml_tag = 'reason'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass By(XMLStringElement):\n    _xml_tag = 'by'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass ExecutionType(XMLElement):\n    _xml_tag = None     # To be set by the subclass\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n    when = XMLElementChild('when', type=When, required=False, test_equal=True)\n    reason = XMLElementChild('reason', type=Reason, required=False, test_equal=True)\n    by = XMLElementChild('by', type=By, required=False, test_equal=True)\n\n    def __init__(self, when=None, reason=None, by=None):\n        XMLElement.__init__(self)\n        self.when = when\n        self.reason = reason\n        self.by = by\n\n\nclass URI(XMLAnyURIElement):\n    _xml_tag = 'uri'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass DisplayText(XMLStringElement):\n    _xml_tag = 'display-text'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass UrisTypePurpose(XMLStringElement):\n    _xml_tag = 'purpose'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass UrisTypeModified(ExecutionType):\n    _xml_tag = 'modified'\n\n\nclass UrisTypeEntry(XMLElement):\n    _xml_tag = 'entry'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n    state = XMLAttribute('state', type=State, required=False, test_equal=False)\n\n    uri = XMLElementChild('uri', type=URI, required=True, test_equal=True)\n    display_text = XMLElementChild('display_text', type=DisplayText, required=False, test_equal=True)\n    purpose = XMLElementChild('purpose', type=UrisTypePurpose, required=False, test_equal=True)\n    modified = XMLElementChild('modified', type=UrisTypeModified, required=False, test_equal=True)\n\n    def __init__(self, uri, state=None, display_text=None, purpose=None, modified=None):\n        XMLElement.__init__(self)\n        self.uri = uri\n        self.state = state\n        self.display_text = display_text\n        self.purpose = purpose\n        self.modified = modified\n\n\nclass Subject(XMLStringElement):\n    _xml_tag = 'subject'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass FreeText(XMLStringElement):\n    _xml_tag = 'free-text'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass Keywords(XMLStringElement):\n    _xml_tag = 'keywords'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass ConfUrisPurposeValue(str):\n    def __new__(cls, value):\n        if value not in ('participation', 'streaming'):\n            raise ValueError(\"illegal value for purpose element\")\n        return str.__new__(cls, value)\n\n\nclass ConfUrisPurpose(UrisTypePurpose):\n    _xml_value_type = ConfUrisPurposeValue\n\n\nclass ConfUrisEntry(UrisTypeEntry):\n    purpose = XMLElementChild('purpose', type=ConfUrisPurpose, required=False, test_equal=True)\n\n\nclass ConfUris(XMLListElement):\n    _xml_tag = 'conf-uris'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_item_type = ConfUrisEntry\n\n    def __init__(self, entries=[]):\n        XMLListElement.__init__(self)\n        self.update(entries)\n\n\nclass ServiceUrisPurposeValue(str):\n    def __new__(cls, value):\n        if value not in ('web-page', 'recording', 'event'):\n            raise ValueError(\"illegal value for purpose element\")\n        return str.__new__(cls, value)\n\n\nclass ServiceUrisPurpose(UrisTypePurpose):\n    _xml_value_type = ServiceUrisPurposeValue\n\n\nclass ServiceUrisEntry(UrisTypeEntry):\n    purpose = XMLElementChild('purpose', type=ServiceUrisPurpose, required=False, test_equal=True)\n\n\nclass ServiceUris(XMLListElement):\n    _xml_tag = 'service-uris'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_item_type = ServiceUrisEntry\n\n    def __init__(self, entries=[]):\n        XMLListElement.__init__(self)\n        self.update(entries)\n\n\nclass MaximumUserCount(XMLUnsignedIntElement):\n    _xml_tag = 'maximum-user-count'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass MediaTypeValue(str):\n    def __new__(cls, value):\n        if value not in ('audio', 'video', 'text', 'message'):\n            raise ValueError(\"illegal value for type element\")\n        return str.__new__(cls, value)\n\n\nclass MediaType(XMLStringElement):\n    _xml_tag = 'type'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_value_type = MediaTypeValue\n\n\nclass MediaTypeStatusValue(str):\n    def __new__(cls, value):\n        if value not in ('sendrecv', 'sendonly', 'recvonly', 'inactive'):\n            raise ValueError(\"illegal value for status element\")\n        return str.__new__(cls, value)\n\n\nclass MediaTypeStatus(XMLStringElement):\n    _xml_tag = 'status'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_value_type = MediaTypeStatusValue\n\n\nclass AvailableMediaEntry(XMLElement):\n    _xml_tag = 'entry'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_children_order = {DisplayText.qname: 0,\n                           MediaType.qname: 1,\n                           MediaTypeStatus.qname: 2,\n                           None: 3}\n\n    label = XMLAttribute('label', type=str, required=True, test_equal=False)\n\n    media_type = XMLElementChild('media_type', type=MediaType, required=True, test_equal=True)\n    display_text = XMLElementChild('display_text', type=DisplayText, required=False, test_equal=True)\n    status = XMLElementChild('status', type=MediaTypeStatus, required=False, test_equal=True)\n\n    def __init__(self, label, media_type, display_text=None, status=None):\n        XMLElement.__init__(self)\n        self.label = label\n        self.media_type = media_type\n        self.display_text = display_text\n        self.status = status\n\n\nclass AvailableMedia(XMLListElement):\n    _xml_tag = 'available-media'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_item_type = AvailableMediaEntry\n\n    def __init__(self, entries=[]):\n        XMLListElement.__init__(self)\n        self.update(entries)\n\n\nclass ConferenceDescription(XMLElement):\n    _xml_tag = 'conference-description'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_extension_type = ConferenceDescriptionExtension\n\n    display_text = XMLElementChild('display_text', type=DisplayText, required=False, test_equal=True)\n    subject = XMLElementChild('subject', type=Subject, required=False, test_equal=True)\n    free_text = XMLElementChild('free_text', type=FreeText, required=False, test_equal=True)\n    keywords = XMLElementChild('keywords', type=Keywords, required=False, test_equal=True)\n    conf_uris = XMLElementChild('conf_uris', type=ConfUris, required=False, test_equal=True)\n    service_uris = XMLElementChild('service_uris', type=ServiceUris, required=False, test_equal=True)\n    maximum_user_count = XMLElementChild('maximum_user_count', type=MaximumUserCount, required=False, test_equal=True)\n    available_media = XMLElementChild('available_media', type=AvailableMedia, required=False, test_equal=True)\n\n    def __init__(self, display_text=None, subject=None, free_text=None, keywords=None, conf_uris=None, service_uris=None, maximum_user_count=None, available_media=None):\n        XMLElement.__init__(self)\n        self.display_text = display_text\n        self.subject = subject\n        self.free_text = free_text\n        self.keywords = keywords\n        self.conf_uris = conf_uris\n        self.service_uris = service_uris\n        self.maximum_user_count = maximum_user_count\n        self.available_media = available_media\n\n\nclass WebPage(XMLStringElement):\n    _xml_tag = 'web-page'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass HostInfoUris(XMLListElement):\n    _xml_tag = 'uris'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_item_type = UrisTypeEntry\n\n    def __init__(self, entries=[]):\n        XMLListElement.__init__(self)\n        self.update(entries)\n\n\nclass HostInfo(XMLElement):\n    _xml_tag = 'host-info'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n    display_text = XMLElementChild('display_text', type=DisplayText, required=False, test_equal=True)\n    web_page = XMLElementChild('web_page', type=WebPage, required=False, test_equal=True)\n    uris = XMLElementChild('uris', type=HostInfoUris, required=False, test_equal=True)\n\n    def __init__(self, display_text=None, web_page=None, uris=None):\n        XMLElement.__init__(self)\n        self.display_text = display_text\n        self.web_page = web_page\n        self.uris = uris\n\n\nclass UserCount(XMLUnsignedIntElement):\n    _xml_tag = 'user-count'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass Active(XMLBooleanElement):\n    _xml_tag = 'active'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass Locked(XMLBooleanElement):\n    _xml_tag = 'locked'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass ConferenceState(XMLElement):\n    _xml_tag = 'conference-state'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n    user_count = XMLElementChild('user_count', type=UserCount, required=False, test_equal=True)\n    active = XMLElementChild('active', type=Active, required=False, test_equal=True)\n    locked = XMLElementChild('locked', type=Locked, required=False, test_equal=True)\n\n    def __init__(self, user_count=None, active=None, locked=None):\n        XMLElement.__init__(self)\n        self.user_count = user_count\n        self.active = active\n        self.locked = locked\n\n\nclass AssociatedAors(XMLListElement):\n    _xml_tag = 'associated-aors'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_item_type = UrisTypeEntry\n\n    def __init__(self, entries=[]):\n        XMLListElement.__init__(self)\n        self.update(entries)\n\n\nclass Role(XMLStringElement):\n    _xml_tag = 'entry'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass Roles(XMLListElement):\n    _xml_tag = 'roles'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_item_type = Role\n\n    def __init__(self, roles=[]):\n        XMLListElement.__init__(self)\n        self.update(roles)\n\n\nclass Languages(XMLStringElement):\n    _xml_tag = 'languages'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass CascadedFocus(XMLStringElement):\n    _xml_tag = 'cascaded-focus'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass Referred(ExecutionType):\n    _xml_tag = 'referred'\n\n\nclass EndpointStatusValue(str):\n    def __new__(cls, value):\n        if value not in ('connected', 'disconnected', 'on-hold', 'muted-via-focus', 'pending', 'alerting', 'dialing-in', 'dialing-out', 'disconnecting'):\n            raise ValueError(\"illegal value for status element\")\n        return str.__new__(cls, value)\n\n\nclass EndpointStatus(XMLStringElement):\n    _xml_tag = 'status'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_value_type = EndpointStatusValue\n\n\nclass JoiningMethodValue(str):\n    def __new__(cls, value):\n        if value not in ('dialed-in', 'dialed-out', 'focus-owner'):\n            raise ValueError(\"illegal value for joining method element\")\n        return str.__new__(cls, value)\n\n\nclass JoiningMethod(XMLStringElement):\n    _xml_tag = 'joining-method'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_value_type = JoiningMethodValue\n\n\nclass JoiningInfo(ExecutionType):\n    _xml_tag = 'joining-info'\n\n\nclass DisconnectionMethodValue(str):\n    def __new__(cls, value):\n        if value not in ('departed', 'booted', 'failed', 'busy'):\n            raise ValueError(\"illegal value for disconnection method element\")\n        return str.__new__(cls, value)\n\n\nclass DisconnectionMethod(XMLStringElement):\n    _xml_tag = 'disconnection-method'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_value_type = DisconnectionMethodValue\n\n\nclass DisconnectionInfo(ExecutionType):\n    _xml_tag = 'disconnection-info'\n\n\nclass Label(XMLStringElement):\n    _xml_tag = 'label'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass SrcId(XMLStringElement):\n    _xml_tag = 'src-id'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass Media(XMLElement):\n    _xml_tag = 'media'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n    id = XMLAttribute('id', type=str, required=True, test_equal=False)\n\n    display_text = XMLElementChild('display_text', type=DisplayText, required=False, test_equal=True)\n    media_type = XMLElementChild('media_type', type=MediaType, required=False, test_equal=True)\n    label = XMLElementChild('label', type=Label, required=False, test_equal=True)\n    src_id = XMLElementChild('src_id', type=SrcId, required=False, test_equal=True)\n    status = XMLElementChild('status', type=MediaTypeStatus, required=False, test_equal=True)\n\n    def __init__(self, id, display_text=None, media_type=None, label=None, src_id=None, status=None):\n        XMLElement.__init__(self)\n        self.id = id\n        self.display_text = display_text\n        self.media_type = media_type\n        self.label = label\n        self.src_id = src_id\n        self.status = status\n\n\nclass CallId(XMLStringElement):\n    _xml_tag = 'call-id'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass FromTag(XMLStringElement):\n    _xml_tag = 'from-tag'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass ToTag(XMLStringElement):\n    _xml_tag = 'to-tag'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n\nclass Sip(XMLElement):\n    _xml_tag = 'sip'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n    display_text = XMLElementChild('display_text', type=DisplayText, required=False, test_equal=True)\n    call_id = XMLElementChild('call_id', type=CallId, required=False, test_equal=True)\n    from_tag = XMLElementChild('from_tag', type=FromTag, required=False, test_equal=True)\n    to_tag = XMLElementChild('to_tag', type=ToTag, required=False, test_equal=True)\n\n    def __init__(self, display_text=None, call_id=None, from_tag=None, to_tag=None):\n        XMLElement.__init__(self)\n        self.display_text = display_text\n        self.call_id = call_id\n        self.from_tag = from_tag\n        self.to_tag = to_tag\n\n\nclass CallInfo(XMLElement):\n    _xml_tag = 'call-info'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n    sip = XMLElementChild('sip', type=Sip, required=False, test_equal=True)\n\n    def __init__(self, sip=None):\n        XMLElement.__init__(self)\n        self.sip = sip\n\n\nclass Endpoint(XMLListElement):\n    _xml_tag = 'endpoint'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_item_type = Media\n\n    entity = XMLAttribute('entity', type=str, required=True, test_equal=False)\n    state = XMLAttribute('state', type=State, required=False, test_equal=False)\n\n    display_text = XMLElementChild('display_text', type=DisplayText, required=False, test_equal=True)\n    referred = XMLElementChild('referred', type=Referred, required=False, test_equal=True)\n    status = XMLElementChild('status', type=EndpointStatus, required=False, test_equal=True)\n    joining_method = XMLElementChild('joining_method', type=JoiningMethod, required=False, test_equal=True)\n    joining_info = XMLElementChild('joining_info', type=JoiningInfo, required=False, test_equal=True)\n    disconnection_method = XMLElementChild('disconnection_method', type=DisconnectionMethod, required=False, test_equal=True)\n    disconnection_info = XMLElementChild('disconnection_info', type=DisconnectionInfo, required=False, test_equal=True)\n    call_info = XMLElementChild('call_info', type=CallInfo, required=False, test_equal=True)\n\n    def __init__(self, entity, state='full', display_text=None, referred=None, status=None, joining_method=None, joining_info=None, disconnection_method=None, disconnection_info=None, call_info=None, media=[]):\n        XMLListElement.__init__(self)\n        self.entity = entity\n        self.state = state\n        self.display_text = display_text\n        self.referred = referred\n        self.status = status\n        self.joining_method = joining_method\n        self.joining_info = joining_info\n        self.disconnection_method = disconnection_method\n        self.disconnection_info = disconnection_info\n        self.call_info = call_info\n        self.update(media)\n\n    def __repr__(self):\n        args = ('entity', 'state', 'display_text', 'referred', 'status', 'joining_method', 'joining_info', 'disconnection_method', 'disconnection_info', 'call_info')\n        return \"%s(%s, media=%r)\" % (self.__class__.__name__, ', '.join(\"%s=%r\" % (name, getattr(self, name)) for name in args), list(self))\n\n\nclass User(XMLListElement):\n    _xml_tag = 'user'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_item_type = Endpoint\n    _xml_extension_type = UserExtension\n\n    entity = XMLAttribute('entity', type=str, required=True, test_equal=False)\n    state = XMLAttribute('state', type=State, required=False, test_equal=False)\n\n    display_text = XMLElementChild('display_text', type=DisplayText, required=False, test_equal=True)\n    associated_aors = XMLElementChild('associated_aors', type=AssociatedAors, required=False, test_equal=True)\n    roles = XMLElementChild('roles', type=Roles, required=False, test_equal=True)\n    languages = XMLElementChild('languages', type=Languages, required=False, test_equal=True)\n    cascaded_focus = XMLElementChild('cascaded_focus', type=CascadedFocus, required=False, test_equal=True)\n\n    def __init__(self, entity, state='full', display_text=None, associated_aors=None, roles=None, languages=None, cascaded_focus=None, endpoints=[]):\n        XMLListElement.__init__(self)\n        self.entity = entity\n        self.state = state\n        self.display_text = display_text\n        self.associated_aors = associated_aors\n        self.roles = roles\n        self.languages = languages\n        self.cascaded_focus = cascaded_focus\n        self.update(endpoints)\n\n    def __repr__(self):\n        args = ('entity', 'state', 'display_text', 'associated_aors', 'roles', 'languages', 'cascaded_focus')\n        return \"%s(%s, endpoints=%r)\" % (self.__class__.__name__, ', '.join(\"%s=%r\" % (name, getattr(self, name)) for name in args), list(self))\n\n\nclass Users(XMLListElement):\n    _xml_tag = 'users'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_item_type = User\n\n    state = XMLAttribute('state', type=State, required=False, test_equal=False)\n\n    def __init__(self, state='full', users=[]):\n        XMLListElement.__init__(self)\n        self.state = state\n        self.update(users)\n\n    def __repr__(self):\n        return \"%s(state=%r, users=%r)\" % (self.__class__.__name__, self.state, list(self))\n\n\nclass SidebarsByRef(XMLListElement):\n    _xml_tag = 'sidebars-by-ref'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_item_type = UrisTypeEntry\n\n    def __init__(self, entries=[]):\n        XMLListElement.__init__(self)\n        self.update(entries)\n\n\nclass SidebarsByVal(XMLListElement):\n    _xml_tag = 'sidebars-by-val'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_item_type = None # will be set later, after the item type is defined below\n\n    state = XMLAttribute('state', type=State, required=False, test_equal=False)\n\n    def __init__(self, state='full', entries=[]):\n        XMLListElement.__init__(self)\n        self.state = state\n        self.update(entries)\n\n    def __repr__(self):\n        return \"%s(state=%r, entries=%r)\" % (self.__class__.__name__, self.state, list(self))\n\n\nclass SidebarsByValEntry(XMLElement):\n    _xml_tag = 'entry'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n\n    entity = XMLAttribute('entity', type=str, required=True, test_equal=False)\n    state = XMLAttribute('state', type=State, required=False, test_equal=False)\n\n    conference_description = XMLElementChild('conference_description', type=ConferenceDescription, required=False, test_equal=True)\n    host_info = XMLElementChild('host_info', type=HostInfo, required=False, test_equal=True)\n    conference_state = XMLElementChild('conference_state', type=ConferenceState, required=False, test_equal=True)\n    users = XMLElementChild('users', type=Users, required=False, test_equal=True)\n    sidebars_by_ref = XMLElementChild('sidebars_by_ref', type=SidebarsByRef, required=False, test_equal=True)\n    sidebars_by_val = XMLElementChild('sidebars_by_val', type=SidebarsByVal, required=False, test_equal=True)\n    \n    def __init__(self, entity, state='full', version=None, conference_description=None, host_info=None, conference_state=None, users=None, sidebars_by_ref=None, sidebars_by_val=None):\n        XMLElement.__init__(self)\n        self.entity = entity\n        self.state = state\n        self.version = version\n        self.conference_description = conference_description\n        self.host_info = host_info\n        self.conference_state = conference_state\n        self.users = users\n        self.sidebars_by_ref = sidebars_by_ref\n        self.sidebars_by_val = sidebars_by_val\n        if self.state == \"full\" and (self.conference_description is None or self.users is None):\n            raise ValidationError(\"A full conference document must at least include the <conference-description> and <users> child elements.\")\n\nSidebarsByVal._xml_item_type = SidebarsByValEntry\n\n\nclass Conference(XMLRootElement):\n    _xml_tag = 'conference-info'\n    _xml_namespace = namespace\n    _xml_document = ConferenceDocument\n    _xml_children_order = {ConferenceDescription.qname: 0,\n                           HostInfo.qname: 1,\n                           ConferenceState.qname: 2,\n                           Users.qname: 3,\n                           SidebarsByRef.qname: 4,\n                           SidebarsByVal.qname: 5,\n                           None: 6}\n\n    entity = XMLAttribute('entity', type=str, required=True, test_equal=False)\n    state = XMLAttribute('state', type=State, required=False, test_equal=False)\n    version = XMLAttribute('version', type=Version, required=False, test_equal=False)\n\n    conference_description = XMLElementChild('conference_description', type=ConferenceDescription, required=False, test_equal=True)\n    host_info = XMLElementChild('host_info', type=HostInfo, required=False, test_equal=True)\n    conference_state = XMLElementChild('conference_state', type=ConferenceState, required=False, test_equal=True)\n    users = XMLElementChild('users', type=Users, required=False, test_equal=True)\n    sidebars_by_ref = XMLElementChild('sidebars_by_ref', type=SidebarsByRef, required=False, test_equal=True)\n    sidebars_by_val = XMLElementChild('sidebars_by_val', type=SidebarsByVal, required=False, test_equal=True)\n    \n    def __init__(self, entity, state='full', version=None, conference_description=None, host_info=None, conference_state=None, users=None, sidebars_by_ref=None, sidebars_by_val=None):\n        XMLRootElement.__init__(self)\n        self.entity = entity\n        self.state = state\n        self.version = version\n        self.conference_description = conference_description\n        self.host_info = host_info\n        self.conference_state = conference_state\n        self.users = users\n        self.sidebars_by_ref = sidebars_by_ref\n        self.sidebars_by_val = sidebars_by_val\n        if self.state == \"full\" and (self.conference_description is None or self.users is None):\n            raise ValidationError(\"A full conference document must at least include the <conference-description> and <users> child elements.\")\n\n\n#\n# Extensions\n#\n\nagp_conf_namespace = 'urn:ag-projects:xml:ns:conference-info'\nConferenceDocument.register_namespace(agp_conf_namespace, prefix='agp-conf')\n\n\nclass FileResource(XMLElement):\n    _xml_tag = 'file'\n    _xml_namespace = agp_conf_namespace\n    _xml_document = ConferenceDocument\n\n    name = XMLAttribute('name', type=unicode, required=True, test_equal=False)\n    hash = XMLAttribute('hash', type=str, required=True, test_equal=False)\n    size = XMLAttribute('size', type=int, required=True, test_equal=False)\n    sender = XMLAttribute('sender', type=unicode, required=True, test_equal=False)\n    status = XMLAttribute('status', type=str, required=True, test_equal=False)\n\n    def __init__(self, name, hash, size, sender, status):\n        XMLElement.__init__(self)\n        self.name = name\n        self.hash = hash\n        self.size = size\n        self.sender = sender\n        self.status = status\n\n\nclass FileResources(XMLListElement):\n    _xml_tag = 'files'\n    _xml_namespace = agp_conf_namespace\n    _xml_document = ConferenceDocument\n    _xml_item_type = FileResource\n\n    def __init__(self, files=[]):\n        XMLListElement.__init__(self)\n        self.update(files)\n\n\nclass Resources(XMLElement, ConferenceDescriptionExtension):\n    _xml_tag = 'resources'\n    _xml_namespace = agp_conf_namespace\n    _xml_document = ConferenceDocument\n\n    files = XMLElementChild('files', type=FileResources, required=False, test_equal=True)\n\n    def __init__(self, files=None):\n        XMLElement.__init__(self)\n        self.files = files\n\nConferenceDescription.register_extension('resources', Resources)\n\n\nclass ScreenImageURL(XMLStringElement, UserExtension):\n    _xml_tag = 'screen_image_url'\n    _xml_namespace = agp_conf_namespace\n    _xml_document = ConferenceDocument\n\nUser.register_extension('screen_image_url', ScreenImageURL)\n\n\n"
  },
  {
    "path": "sipsimple/payloads/datatypes.py",
    "content": "\n\"\"\"Data types used for simple XML elements and for XML attributes\"\"\"\n\n\n__all__ = ['Boolean', 'DateTime', 'Byte', 'UnsignedByte', 'Short', 'UnsignedShort', 'Int', 'UnsignedInt', 'Long', 'UnsignedLong',\n           'PositiveInteger', 'NegativeInteger', 'NonNegativeInteger', 'NonPositiveInteger', 'ID', 'AnyURI', 'SIPURI', 'XCAPURI']\n\n\nimport re\nimport urllib\nimport urlparse\n\nfrom sipsimple.util import ISOTimestamp\n\n\nclass Boolean(int):\n    def __new__(cls, value):\n        return int.__new__(cls, bool(value))\n\n    def __repr__(self):\n        return 'True' if self else 'False'\n\n    __str__ = __repr__\n\n    @classmethod\n    def __xmlparse__(cls, value):\n        if value in ('True', 'true'):\n            return int.__new__(cls, 1)\n        elif value in ('False', 'false'):\n            return int.__new__(cls, 0)\n        else:\n            raise ValueError(\"Invalid boolean string representation: %s\" % value)\n\n    def __xmlbuild__(self):\n        return u'true' if self else u'false'\n\n\nclass DateTime(ISOTimestamp):\n    pass\n\n\nclass Byte(int):\n    def __new__(cls, value):\n        instance = int.__new__(cls, value)\n        if not (-128 <= instance <= 127):\n            raise ValueError(\"integer number must be a signed 8bit value\")\n        return instance\n\n\nclass UnsignedByte(int):\n    def __new__(cls, value):\n        instance = int.__new__(cls, value)\n        if not (0 <= instance <= 255):\n            raise ValueError(\"integer number must be an unsigned 8bit value\")\n        return instance\n\n\nclass Short(int):\n    def __new__(cls, value):\n        instance = int.__new__(cls, value)\n        if not (-32768 <= instance <= 32767):\n            raise ValueError(\"integer number must be a signed 16bit value\")\n        return instance\n\n\nclass UnsignedShort(int):\n    def __new__(cls, value):\n        instance = int.__new__(cls, value)\n        if not (0 <= instance <= 65535):\n            raise ValueError(\"integer number must be an unsigned 16bit value\")\n        return instance\n\n\nclass Int(long):\n    def __new__(cls, value):\n        instance = long.__new__(cls, value)\n        if not (-2147483648 <= instance <= 2147483647):\n            raise ValueError(\"integer number must be a signed 32bit value\")\n        return instance\n\n\nclass UnsignedInt(long):\n    def __new__(cls, value):\n        instance = long.__new__(cls, value)\n        if not (0 <= instance <= 4294967295):\n            raise ValueError(\"integer number must be an unsigned 32bit value\")\n        return instance\n\n\nclass Long(long):\n    def __new__(cls, value):\n        instance = long.__new__(cls, value)\n        if not (-9223372036854775808 <= instance <= 9223372036854775807):\n            raise ValueError(\"integer number must be a signed 64bit value\")\n        return instance\n\n\nclass UnsignedLong(long):\n    def __new__(cls, value):\n        instance = long.__new__(cls, value)\n        if not (0 <= instance <= 18446744073709551615):\n            raise ValueError(\"integer number must be an unsigned 64bit value\")\n        return instance\n\n\nclass PositiveInteger(long):\n    def __new__(cls, value):\n        instance = long.__new__(cls, value)\n        if instance <= 0:\n            raise ValueError(\"integer number must be a positive value\")\n        return instance\n\n\nclass NegativeInteger(long):\n    def __new__(cls, value):\n        instance = long.__new__(cls, value)\n        if instance >= 0:\n            raise ValueError(\"integer number must be a negative value\")\n        return instance\n\n\nclass NonNegativeInteger(long):\n    def __new__(cls, value):\n        instance = long.__new__(cls, value)\n        if instance < 0:\n            raise ValueError(\"integer number must be a non-negative value\")\n        return instance\n\n\nclass NonPositiveInteger(long):\n    def __new__(cls, value):\n        instance = long.__new__(cls, value)\n        if instance > 0:\n            raise ValueError(\"integer number must be a non-positive value\")\n        return instance\n\n\nclass ID(str):\n    _id_regex = re.compile(r'^[a-z_][a-z0-9_.-]*$', re.I)\n\n    def __new__(cls, value):\n        if not cls._id_regex.match(value):\n            raise ValueError(\"illegal ID value: %s\" % value)\n        return str.__new__(cls, value)\n\n\nclass AnyURI(unicode):\n    @classmethod\n    def __xmlparse__(cls, value):\n        return cls.__new__(cls, urllib.unquote(value).decode('utf-8'))\n\n    def __xmlbuild__(self):\n        return urllib.quote(self.encode('utf-8'))\n\n\nclass SIPURI(AnyURI):\n    _path_regex = re.compile(r'^((?P<username>[^:@]+)(:(?P<password>[^@]+))?@)?(?P<domain>.*)$')\n\n    def __new__(cls, value):\n        instance = AnyURI.__new__(cls, value)\n        uri = urlparse.urlparse(instance)\n\n        if uri.scheme not in ('sip', 'sips'):\n            raise ValueError(\"illegal scheme for SIP URI: %s\" % uri.scheme)\n\n        instance.scheme = uri.scheme\n        instance.__dict__.update(cls._path_regex.match(uri.path).groupdict())\n        instance.params = {}\n\n        if uri.params:\n            params = (param.split('=', 1) for param in uri.params.split(';'))\n            for param in params:\n                if not param[0]:\n                    raise ValueError(\"illegal SIP URI parameter name: %s\" % param[0])\n                if len(param) == 1:\n                    param.append(None)\n                elif '=' in param[1]:\n                    raise ValueError(\"illegal SIP URI parameter value: %s\" % param[1])\n                instance.params[param[0]] = param[1]\n\n        if uri.query:\n            try:\n                instance.headers = dict(header.split('=') for header in uri.query.split('&'))\n            except ValueError:\n                raise ValueError(\"illegal SIP URI headers: %s\" % uri.query)\n            else:\n                for name, value in instance.headers.iteritems():\n                    if not name or not value:\n                        raise ValueError(\"illegal URI header: %s=%s\" % (name, value))\n        else:\n            instance.headers = {}\n\n        return instance\n\n\nclass XCAPURI(AnyURI):\n    _path_regex = re.compile(r'^(?P<root>/(([^/]+)/)*)?(?P<auid>[^/]+)/((?P<globaltree>global)|(users/(?P<userstree>[^/]+)))/(?P<document>~?(([^~]+~)|([^~]+))*)(/~~(?P<node>.*))?$')\n\n    def __new__(cls, value):\n        instance = AnyURI.__new__(cls, value)\n        uri = urlparse.urlparse(instance)\n\n        if uri.scheme not in ('http', 'https', ''):\n            raise ValueError(\"illegal scheme for XCAP URI: %s\" % uri.scheme)\n\n        instance.scheme = uri.scheme\n        instance.username = uri.username\n        instance.password = uri.password\n        instance.hostname = uri.hostname\n        instance.port = uri.port\n        instance.__dict__.update(cls._path_regex.match(uri.path).groupdict())\n        instance.globaltree = instance.globaltree is not None\n\n        if uri.query:\n            try:\n                instance.query = dict(header.split('=') for header in uri.query.split('&'))\n            except ValueError:\n                raise ValueError(\"illegal XCAP URI query string: %s\" % uri.query)\n            else:\n                for name, value in instance.query.iteritems():\n                    if not name or not value:\n                        raise ValueError(\"illegal XCAP URI query parameter: %s=%s\" % (name, value))\n        else:\n            instance.query = {}\n\n        return instance\n\n    relative = property(lambda self: self.scheme == '')\n\n\n"
  },
  {
    "path": "sipsimple/payloads/dialoginfo.py",
    "content": "\n\"\"\"Parses and produces dialog-info messages according to RFC4235.\"\"\"\n\n\n__all__ = ['namespace',\n           'DialogInfoDocument',\n           'DialogState',\n           'Replaces',\n           'ReferredBy',\n           'Identity',\n           'Param',\n           'Target',\n           'Local',\n           'Remote',\n           'Dialog',\n           'DialogInfo']\n\n\nfrom sipsimple.payloads import XMLDocument, XMLListRootElement, XMLListElement, XMLStringElement, XMLNonNegativeIntegerElement, XMLElementChild, XMLEmptyElement, XMLElement, XMLElementID, XMLAttribute\nfrom sipsimple.payloads import IterateIDs, IterateItems, All\n\n\nnamespace = 'urn:ietf:params:xml:ns:dialog-info'\n\n\nclass DialogInfoDocument(XMLDocument):\n    content_type = \"application/dialog-info+xml\"\n\nDialogInfoDocument.register_namespace(namespace, prefix=None, schema='dialog-info.xsd')\n\n\n# Attribute value types\nclass StateValue(str):\n    def __new__(cls, value):\n        if value not in ('full', 'partial'):\n            raise ValueError(\"illegal value for state\")\n        return str.__new__(cls, value)\n\n\nclass VersionValue(int):\n    def __new__(cls, value):\n        value = int.__new__(cls, value)\n        if value < 0:\n            raise ValueError(\"illegal value for version\")\n        return value\n\n\nclass DirectionValue(str):\n    def __new__(cls, value):\n        if value not in ('initiator', 'recipient'):\n            raise ValueError(\"illegal value for direction\")\n        return str.__new__(cls, value)\n\n\nclass DialogEventValue(str):\n    def __new__(cls, value):\n        if value not in ('rejected', 'cancelled', 'replaced', 'local-bye', 'remote-bye', 'error', 'timeout'):\n            raise ValueError(\"illegal value for dialog state event\")\n        return str.__new__(cls, value)\n\n\nclass DialogStateValue(str):\n    def __new__(cls, value):\n        if value not in ('trying', 'proceeding', 'early', 'confirmed', 'terminated'):\n            raise ValueError(\"illegal value for dialog state\")\n        return str.__new__(cls, value)\n\n\nclass CodeValue(int):\n    def __new__(cls, value):\n        value = int.__new__(cls, value)\n        if value < 100 or value > 699:\n            raise ValueError(\"illegal value for code\")\n        return value\n\n\n# Elements\n\nclass CallId(XMLStringElement):\n    _xml_tag = 'call-id'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n\n\nclass LocalTag(XMLStringElement):\n    _xml_tag = 'local-tag'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n\n\nclass RemoteTag(XMLStringElement):\n    _xml_tag = 'remote-tag'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n\n\nclass DialogState(XMLStringElement):\n    _xml_tag = 'state'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n    _xml_value_type = DialogStateValue\n\n    code = XMLAttribute('code', type=int, required=False, test_equal=True)\n    event = XMLAttribute('event', type=DialogEventValue, required=False, test_equal=True)\n\n\nclass Duration(XMLNonNegativeIntegerElement):\n    _xml_tag = 'duration'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n\n\nclass Replaces(XMLEmptyElement):\n    _xml_tag = 'replaces'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n\n    call_id = XMLAttribute('call_id', xmlname='call-id', type=str, required=True, test_equal=True)\n    local_tag = XMLAttribute('local_tag', xmlname='local-tag', type=str, required=True, test_equal=True)\n    remote_tag = XMLAttribute('remote_tag', xmlname='remote-tag', type=str, required=True, test_equal=True)\n\n    def __init__(self, call_id, local_tag, remote_tag):\n        XMLEmptyElement.__init__(self)\n        self.call_id = call_id\n        self.local_tag = local_tag\n        self.remote_tag = remote_tag\n\n\nclass ReferredBy(XMLStringElement):\n    _xml_tag = 'referred-by'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n\n    display = XMLAttribute('display', type=str, required=False, test_equal=True)\n\n\nclass Identity(XMLStringElement):\n    _xml_tag = 'identity'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n\n    display = XMLAttribute('display', type=str, required=False, test_equal=True)\n\n\nclass Param(XMLEmptyElement):\n    _xml_tag = 'param'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n\n    pname = XMLAttribute('pname', type=str, required=True, test_equal=True)\n    pval = XMLAttribute('pval', type=str, required=True, test_equal=True)\n\n    def __init__(self, pname, pval):\n        XMLEmptyElement.__init__(self)\n        self.pname = pname\n        self.pval = pval\n\n\nclass Target(XMLListElement):\n    _xml_tag = 'target'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n    _xml_item_type = Param\n\n    uri = XMLAttribute('uri', type=str, required=True, test_equal=True)\n\n    def __init__(self, uri, params=[]):\n        self.uri = uri\n        self.update(params)\n\n\nclass Participant(XMLElement):\n    identity = XMLElementChild('identity', type=Identity, required=False, test_equal=True)\n    target = XMLElementChild('target', type=Target, required=False, test_equal=True)\n\n    def __init__(self, identity=None, target=None):\n        XMLElement.__init__(self)\n        self.identity = identity\n        self.target = target\n\n\nclass Local(Participant):\n    _xml_tag = 'local'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n\n\nclass Remote(Participant):\n    _xml_tag = 'remote'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n\n\nclass Dialog(XMLElement):\n    _xml_tag = 'dialog'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n\n    id = XMLElementID('id', type=str, required=True, test_equal=True)\n\n    call_id = XMLAttribute('call_id', xmlname='call-id', type=str, required=False, test_equal=True)\n    local_tag = XMLAttribute('local_tag', xmlname='local-tag', type=str, required=False, test_equal=True)\n    remote_tag = XMLAttribute('remote_tag', xmlname='remote-tag', type=str, required=False, test_equal=True)\n    direction = XMLAttribute('direction', type=DirectionValue, required=False, test_equal=True)\n\n    state = XMLElementChild('state', type=DialogState, required=True, test_equal=True)\n    duration = XMLElementChild('duration', type=Duration, required=False, test_equal=True)\n    replaces = XMLElementChild('replaces', type=Replaces, required=False, test_equal=True)\n    referred_by = XMLElementChild('referred_by', type=ReferredBy, required=False, test_equal=True)\n    local = XMLElementChild('local', type=Local, required=False, test_equal=True)\n    remote = XMLElementChild('remote', type=Remote, required=False, test_equal=True)\n\n    def __init__(self, id, state, call_id=None, local_tag=None, remote_tag=None, direction=None, duration=None, replaces=None, referred_by=None, local=None, remote=None):\n        XMLElement.__init__(self)\n        self.id = id\n        self.state = state\n        self.call_id = call_id\n        self.local_tag = local_tag\n        self.remote_tag = remote_tag\n        self.direction = direction\n        self.duration = duration\n        self.replaces = replaces\n        self.referred_by = referred_by\n        self.local = local\n        self.remote = remote\n\n\nclass DialogInfo(XMLListRootElement):\n    _xml_tag = 'dialog-info'\n    _xml_namespace = namespace\n    _xml_document = DialogInfoDocument\n    _xml_children_order = {Dialog.qname: 0,\n                           None: 1}\n    _xml_item_type = Dialog\n\n    version = XMLAttribute('version', type=VersionValue, required=True, test_equal=True)\n    state = XMLAttribute('state', type=StateValue, required=True, test_equal=True)\n    entity = XMLAttribute('entity', type=str, required=True, test_equal=True)\n\n    def __init__(self, version, state, entity, dialogs=[]):\n        XMLListRootElement.__init__(self)\n        self.version = version\n        self.state = state\n        self.entity = entity\n        self.update(dialogs)\n\n    def __getitem__(self, key):\n        if key is IterateIDs:\n            return self._xmlid_map[Dialog].iterkeys()\n        elif key is IterateItems:\n            return self._xmlid_map[Dialog].itervalues()\n        else:\n            return self._xmlid_map[Dialog][key]\n\n    def __delitem__(self, key):\n        if key is All:\n            for item in self._xmlid_map[Dialog].values():\n                self.remove(item)\n        else:\n            self.remove(self._xmlid_map[Dialog][key])\n\n    def get(self, key, default=None):\n        return self._xmlid_map[Dialog].get(key, default)\n\n\n"
  },
  {
    "path": "sipsimple/payloads/dialogrules.py",
    "content": "\n\"\"\"\nParses and produces Dialog Authorization Rules documents. As there is no\nRFC for this we'll use common-policy format (RFC 4745).\n\nNOTE: Subscription Handling has been taken from RFC 5025.\n\"\"\"\n\n\n__all__ = ['namespace', 'DialogRulesDocument', 'SubHandling', 'DialogRules']\n\n\nfrom sipsimple.payloads import commonpolicy, omapolicy\nfrom sipsimple.payloads import XMLStringElement\n\n\nnamespace = 'urn:ag-projects:xml:ns:dialog-rules'\n\n\nclass DialogRulesDocument(commonpolicy.CommonPolicyDocument): pass\nDialogRulesDocument.register_namespace(namespace, prefix='dr', schema='dialog-rules.xsd')\nDialogRulesDocument.register_namespace(omapolicy.namespace, prefix='ocp', schema='oma-common-policy.xsd')\nDialogRulesDocument.register_element(omapolicy.AnonymousRequest)\nDialogRulesDocument.register_element(omapolicy.OtherIdentity)\nDialogRulesDocument.register_element(omapolicy.Entry)\nDialogRulesDocument.register_element(omapolicy.ExternalList)\n\n\nclass SubHandlingValue(str):\n    __prioritymap__ = {'block': 0, 'confirm': 10, 'polite-block': 20, 'allow': 30}\n\n    def __new__(cls, value):\n        if value not in cls.__prioritymap__:\n            raise ValueError(\"illegal value for SubHandling element\")\n        return str.__new__(cls, value)\n\n    @property\n    def priority(self):\n        return self.__prioritymap__[self]\n\n\nclass SubHandling(XMLStringElement, commonpolicy.ActionElement):\n    _xml_tag = 'sub-handling'\n    _xml_namespace = namespace\n    _xml_document = DialogRulesDocument\n    _xml_value_type = SubHandlingValue\n\n\nclass DialogRules(commonpolicy.RuleSet):\n    _xml_document = DialogRulesDocument\n\n"
  },
  {
    "path": "sipsimple/payloads/directory.py",
    "content": "\n\"\"\"Parses xcap-directory messages according to OMA TS XDM Core 1.1\"\"\"\n\n\n__all__ = ['namespace', 'XCAPDirectoryDocument', 'Folder', 'Entry', 'ErrorCode']\n\n\nfrom sipsimple.payloads import XMLDocument, XMLListRootElement, XMLStringElement, XMLListElement, XMLAttribute, XMLElementChild\nfrom sipsimple.payloads.datatypes import DateTime, AnyURI\n\n\nnamespace = 'urn:oma:xml:xdm:xcap-directory'\n\n\nclass XCAPDirectoryDocument(XMLDocument):\n    content_type = \"application/vnd.oma.xcap-directory+xml\"\n\nXCAPDirectoryDocument.register_namespace(namespace, prefix=None, schema='xcap-directory.xsd')\n\n\n# Attribute value types\nclass SizeValue(int):\n    def __new__(cls, value):\n        value = int.__new__(cls, value)\n        if value <= 0:\n            raise ValueError(\"illegal value for size\")\n        return value\n\n\n# Elements\nclass Entry(XMLStringElement):\n    _xml_tag = 'entry'\n    _xml_namespace = namespace\n    _xml_document = XCAPDirectoryDocument\n\n    uri = XMLAttribute('uri', type=AnyURI, required=True, test_equal=True)\n    etag = XMLAttribute('etag', type=str, required=True, test_equal=True)\n    last_modified = XMLAttribute('last_modified', xmlname='last-modified', type=DateTime, required=False, test_equal=True)\n    size = XMLAttribute('size', type=SizeValue, required=False, test_equal=True)\n\nclass ErrorCode(XMLStringElement):\n    _xml_tag = 'error-code'\n    _xml_namespace = namespace\n    _xml_document = XCAPDirectoryDocument\n\nclass Folder(XMLListElement):\n    _xml_tag = 'folder'\n    _xml_namespace = namespace\n    _xml_document = XCAPDirectoryDocument\n    _xml_item_type = Entry\n\n    auid = XMLAttribute('auid', type=str, required=True, test_equal=True)\n    error_code = XMLElementChild('error_code', type=ErrorCode, required=False, test_equal=True, onset=lambda self, descriptor, value: self.clear() if value is not None else None)\n\n    def __init__(self, auid, entries=[], error_code=None):\n        if error_code is not None and entries:\n            raise ValueError(\"Cannot set both an error code and add entries at the same time\")\n        XMLListElement.__init__(self)\n        self.auid = auid\n        self.error_code = error_code\n        self.update(entries)\n\n    def add(self, entry):\n        if self.error_code is not None:\n            raise ValueError(\"Cannot add an entry when error_code is set\")\n        super(Folder, self).add(entry)\n\n\nclass XCAPDirectory(XMLListRootElement):\n    _xml_tag = 'xcap-directory'\n    _xml_namespace = namespace\n    _xml_document = XCAPDirectoryDocument\n    _xml_item_type = Folder\n\n    def __init__(self, folders=[]):\n        XMLListRootElement.__init__(self)\n        self.update(folders)\n\n\n"
  },
  {
    "path": "sipsimple/payloads/imdn.py",
    "content": "\n\"\"\"Parses and produces IMDN messages according to RFC5438.\"\"\"\n\n\n__all__ = ['namespace',\n           'IMDNDocument',\n           'MessageId',\n           'DateTime',\n           'RecipientUri',\n           'OriginalRecipientUri',\n           'Subject',\n           'Delivered',\n           'Failed',\n           'Displayed',\n           'Processed',\n           'Stored',\n           'Error',\n           'Forbidden',\n           'DeliveryStatus',\n           'DisplayStatus',\n           'ProcessingStatus',\n           'DeliveryNotification',\n           'DisplayNotification',\n           'ProcessingNotification',\n           'IMDNMessage']\n\n\nfrom sipsimple.payloads import XMLDocument, XMLRootElement, XMLAnyURIElement, XMLStringElement, XMLElementChild, XMLElementChoiceChild, XMLEmptyElement, XMLElement\n\n\nnamespace = 'urn:ietf:params:xml:ns:imdn'\n\n\nclass IMDNDocument(XMLDocument):\n    content_type = \"message/imdn+xml\"\n\n\nIMDNDocument.register_namespace(namespace, prefix=None, schema='imdn.xsd')\n\n\n# Elements\n\nclass MessageId(XMLStringElement):\n    _xml_tag = 'message-id'\n    _xml_namespace = namespace\n    _xml_document = IMDNDocument\n\n\nclass DateTime(XMLStringElement):\n    _xml_tag = 'datetime'\n    _xml_namespace = namespace\n    _xml_document = IMDNDocument\n\n\nclass RecipientUri(XMLAnyURIElement):\n    _xml_tag = 'recipient-uri'\n    _xml_namespace = namespace\n    _xml_document = IMDNDocument\n\n\nclass OriginalRecipientUri(XMLAnyURIElement):\n    _xml_tag = 'original-recipient-uri'\n    _xml_namespace = namespace\n    _xml_document = IMDNDocument\n\n\nclass Subject(XMLStringElement):\n    _xml_tag = 'subject'\n    _xml_namespace = namespace\n    _xml_document = IMDNDocument\n\n\nclass StatusElement(XMLEmptyElement):\n    _xml_namespace = namespace\n    _xml_document = IMDNDocument\n\n    def __init__(self):\n        XMLEmptyElement.__init__(self)\n\n    def __str__(self):\n        return \"%s\" % (self._xml_tag)\n\n\nclass Delivered(StatusElement):\n    _xml_tag = 'delivered'\n\n\nclass Failed(StatusElement):\n    _xml_tag = 'failed'\n\n\nclass Displayed(StatusElement):\n    _xml_tag = 'displayed'\n\n\nclass Processed(StatusElement):\n    _xml_tag = 'processed'\n\n\nclass Stored(StatusElement):\n    _xml_tag = 'stored'\n\n\nclass Error(StatusElement):\n    _xml_tag = 'error'\n\n\nclass Forbidden(StatusElement):\n    _xml_tag = 'forbidden'\n\n\nclass Status(XMLElement):\n    _xml_tag = 'status'\n    _xml_namespace = namespace\n    _xml_document = IMDNDocument\n\n    def __init__(self, status):\n        XMLElement.__init__(self)\n        if isinstance(status, basestring) and status not in ('delivered', 'failed', 'displayed', 'processed', 'stored', 'forbidden', 'error'):\n            raise ValueError(\"illegal value for status\")\n        self.status = status if not isinstance(status, basestring) else eval(status.title())()\n\n    def __repr__(self):\n        return \"%s(%r)\" % (self.__class__.__name__, self.status)\n\n    def __str__(self):\n        return \"%s\" % (self.status)\n\n\nclass DeliveryStatus(Status):\n    status = XMLElementChoiceChild('status', types=(Delivered, Failed, Forbidden, Error), required=True, test_equal=True)\n\n\nclass DisplayStatus(Status):\n    status = XMLElementChoiceChild('status', types=(Displayed, Forbidden, Error), required=True, test_equal=True)\n\n\nclass ProcessingStatus(Status):\n    status = XMLElementChoiceChild('status', types=(Processed, Stored, Forbidden, Error), required=True, test_equal=True)\n\n\nclass NotificationType(XMLElement):\n    _xml_namespace = namespace\n    _xml_document = IMDNDocument\n\n    def __init__(self, status):\n        XMLElement.__init__(self)\n        self.status = status\n\n\nclass DeliveryNotification(NotificationType):\n    _xml_tag = 'delivery-notification'\n\n    status = XMLElementChild('status', type=DeliveryStatus, required=True, test_equal=True)\n\n\nclass DisplayNotification(NotificationType):\n    _xml_tag = 'display-notification'\n\n    status = XMLElementChild('status', type=DisplayStatus, required=True, test_equal=True)\n\n\nclass ProcessingNotification(NotificationType):\n    _xml_tag = 'processing-notification'\n\n    status = XMLElementChild('status', type=ProcessingStatus, required=True, test_equal=True)\n\n\n# document\n\nclass IMDNMessage(XMLRootElement):\n    _xml_tag = 'imdn'\n    _xml_namespace = namespace\n    _xml_document = IMDNDocument\n    _xml_children_order = {MessageId.qname: 0,\n                           DateTime.qname: 1,\n                           RecipientUri.qname: 2,\n                           OriginalRecipientUri.qname: 3,\n                           Subject.qname: 4,\n                           DeliveryNotification.qname: 5,\n                           DisplayNotification.qname: 6,\n                           ProcessingNotification.qname: 7,\n                           None: 8}\n\n    message_id = XMLElementChild('message_id', type=MessageId, required=True, test_equal=True)\n    datetime = XMLElementChild('datetime', type=DateTime, required=True, test_equal=True)\n    recipient_uri = XMLElementChild('recipient_uri', type=RecipientUri, required=False, test_equal=True)\n    original_recipient_uri = XMLElementChild('original_recipient_uri', type=OriginalRecipientUri, required=False, test_equal=True)\n    subject = XMLElementChild('subject', type=Subject, required=False, test_equal=True)\n    notification = XMLElementChoiceChild('notification', types=(DisplayNotification, DeliveryNotification, ProcessingNotification), required=True, test_equal=True)\n\n    def __init__(self, message_id=None, datetime=None, recipient_uri=None, original_recipient_uri=None, subject=None, notification=None):\n        XMLRootElement.__init__(self)\n        self.message_id = message_id\n        self.datetime = datetime\n        self.recipient_uri = recipient_uri\n        self.original_recipient_uri = original_recipient_uri if original_recipient_uri is not None else recipient_uri\n        self.subject = subject\n        self.notification = notification\n"
  },
  {
    "path": "sipsimple/payloads/iscomposing.py",
    "content": "\n\"\"\"Parses and produces isComposing messages according to RFC3994.\"\"\"\n\n\n__all__ = ['namespace', 'IsComposingDocument', 'State', 'LastActive', 'ContentType', 'Refresh', 'IsComposingMessage']\n\n\nfrom sipsimple.payloads import XMLDocument, XMLRootElement, XMLStringElement, XMLPositiveIntegerElement, XMLDateTimeElement, XMLElementChild\n\n\nnamespace = 'urn:ietf:params:xml:ns:im-iscomposing'\n\n\nclass IsComposingDocument(XMLDocument):\n    content_type = \"application/im-iscomposing+xml\"\n\nIsComposingDocument.register_namespace(namespace, prefix=None, schema='im-iscomposing.xsd')\n\n\n# Attribute value types\nclass StateValue(str):\n    def __new__(cls, value):\n        if value not in ('active', 'idle'):\n            value = 'idle'\n        return str.__new__(cls, value)\n\n\n# Elements\nclass State(XMLStringElement):\n    _xml_tag = 'state'\n    _xml_namespace = namespace\n    _xml_document = IsComposingDocument\n    _xml_value_type = StateValue\n\n\nclass LastActive(XMLDateTimeElement):\n    _xml_tag = 'lastactive'\n    _xml_namespace = namespace\n    _xml_document = IsComposingDocument\n\n\nclass ContentType(XMLStringElement):\n    _xml_tag = 'contenttype'\n    _xml_namespace = namespace\n    _xml_document = IsComposingDocument\n\n\nclass Refresh(XMLPositiveIntegerElement):\n    _xml_tag = 'refresh'\n    _xml_namespace = namespace\n    _xml_document = IsComposingDocument\n\n\nclass IsComposingMessage(XMLRootElement):\n    _xml_tag = 'isComposing'\n    _xml_namespace = namespace\n    _xml_document = IsComposingDocument\n    _xml_children_order = {State.qname: 0,\n                           LastActive.qname: 1,\n                           ContentType.qname: 2,\n                           Refresh.qname: 3,\n                           None: 4}\n\n    state = XMLElementChild('state', type=State, required=True, test_equal=True)\n    last_active = XMLElementChild('last_active', type=LastActive, required=False, test_equal=True)\n    content_type = XMLElementChild('content_type', type=ContentType, required=False, test_equal=True)\n    refresh = XMLElementChild('refresh', type=Refresh, required=False, test_equal=True)\n\n    def __init__(self, state=None, last_active=None, content_type=None, refresh=None):\n        XMLRootElement.__init__(self)\n        self.state = state\n        self.last_active = last_active\n        self.content_type = content_type\n        self.refresh = refresh\n\n"
  },
  {
    "path": "sipsimple/payloads/messagesummary.py",
    "content": "\n\"\"\"\nMessage summary and Message Waiting Indication handling according to RFC3842\n\"\"\"\n\nimport re\n\nfrom cStringIO import StringIO\nfrom application.configuration.datatypes import Boolean\n\nfrom sipsimple.payloads import ValidationError\n\n\nclass MessageSummary(object):\n    content_type = \"application/simple-message-summary\"\n\n    def __init__(self, messages_waiting=False, message_account=None, summaries=None, optional_headers=None):\n        self.messages_waiting = messages_waiting\n        self.message_account = message_account\n        self.summaries = summaries if summaries is not None else {}\n        self.optional_headers = optional_headers if optional_headers is not None else []\n\n    @classmethod\n    def parse(cls, content):\n        message = StringIO(content)\n        summary = cls()\n        tmp_headers = []\n        for line in message:\n            if line == '\\r\\n':\n                if tmp_headers:\n                    summary.optional_headers.append(tmp_headers)\n                    tmp_headers = []\n            else:\n                field, sep, rest = line.partition(':')\n                if not field and not rest:\n                    raise ValidationError(\"incorrect line format\")\n                field = field.strip()\n                rest = rest.strip()\n\n                if field.lower() == \"messages-waiting\":\n                    summary.messages_waiting = Boolean(rest)\n                elif field.lower() == \"message-account\":\n                    summary.message_account = rest\n                elif field.lower() in {\"voice-message\", \"fax-message\", \"pager-message\", \"multimedia-message\", \"text-message\", \"none\"}:\n                    m = re.match(\"((\\d+)/(\\d+))( \\((\\d+)/(\\d+)\\))?\", rest)\n                    if m:\n                        summary.summaries[field.lower()] = dict(new_messages=m.groups()[1], old_messages=m.groups()[2], new_urgent_messages=m.groups()[4] or 0, old_urgent_messages=m.groups()[5] or 0)\n                    else:\n                        raise ValidationError(\"invalid message context class\")\n                else:\n                    tmp_headers.append(line.strip())\n        if tmp_headers:\n            summary.optional_headers.append(tmp_headers)\n            tmp_headers = []\n        return summary\n\n    def to_string(self):\n        data = \"Messages-Waiting: %s\\r\\n\" % 'yes' if self.messages_waiting else 'no'\n        if self.message_account:\n            data += \"Message-Account: %s\\r\\n\" % self.message_account\n        if self.summaries:\n            for k, v in self.summaries.iteritems():\n                data += \"%s: %s/%s (%s/%s)\\r\\n\" % (k.title(), v['new_messages'], v['old_messages'], v['new_urgent_messages'], v['old_urgent_messages'])\n        if self.optional_headers:\n            data += \"\\r\\n\"\n            for headers in self.optional_headers:\n                for h in headers:\n                    data += \"%s\\r\\n\" % h\n                data += \"\\r\\n\"\n        return data\n\n"
  },
  {
    "path": "sipsimple/payloads/omapolicy.py",
    "content": "\n\"\"\"\nConditions extension handling according to OMA-TS-Presence_SIMPLE_XDM-V1_1\n\nThis module provides an extension to RFC4745 (Common Policy) to\nsupport condition extensions defined by OMA.\n\"\"\"\n\n\n__all__ = ['namespace', 'OtherIdentity', 'ExternalList', 'AnonymousRequest']\n\n\nfrom sipsimple.payloads import XMLElement, XMLEmptyElement, XMLListElement, XMLElementID\nfrom sipsimple.payloads.datatypes import AnyURI\nfrom sipsimple.payloads.commonpolicy import ConditionElement\nfrom sipsimple.payloads.presrules import PresRulesDocument\n\n\nnamespace = 'urn:oma:xml:xdm:common-policy'\nPresRulesDocument.register_namespace(namespace, prefix='ocp', schema='oma-common-policy.xsd')\n\n\nclass OtherIdentity(XMLEmptyElement, ConditionElement):\n    _xml_tag = 'other-identity'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass Entry(XMLElement):\n    _xml_tag = 'entry'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n    uri = XMLElementID('uri', xmlname='anc', type=AnyURI, required=True, test_equal=True)\n\n    def __init__(self, uri):\n        XMLElement.__init__(self)\n        self.uri = uri\n\n    def __unicode__(self):\n        return self.uri\n\n    def __str__(self):\n        return str(self.uri)\n\n\nclass ExternalList(XMLListElement, ConditionElement):\n    _xml_tag = 'external-list'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n    _xml_item_type = Entry\n\n    def __init__(self, entries=[]):\n        XMLListElement.__init__(self)\n        self.update(entries)\n\n    def __iter__(self):\n        return (unicode(item) for item in super(ExternalList, self).__iter__())\n\n    def __repr__(self):\n        return '%s(%r)' % (self.__class__.__name__, list(self))\n\n    def add(self, item):\n        if isinstance(item, basestring):\n            item = Entry(item)\n        super(ExternalList, self).add(item)\n\n    def remove(self, item):\n        if isinstance(item, basestring):\n            try:\n                item = (entry for entry in super(ExternalList, self).__iter__() if entry == item).next()\n            except StopIteration:\n                raise KeyError(item)\n        super(ExternalList, self).remove(item)\n\n\nclass AnonymousRequest(XMLEmptyElement, ConditionElement):\n    _xml_tag = 'anonymous-request'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n"
  },
  {
    "path": "sipsimple/payloads/pidf.py",
    "content": "\n\"\"\"PIDF handling according to RFC3863 and RFC4479\"\"\"\n\n\n__all__ = ['pidf_namespace',\n           'dm_namespace',\n           'PIDFDocument',\n           'ServiceExtension',\n           'DeviceExtension',\n           'PersonExtension',\n           'StatusExtension',\n           'Note',\n           'DeviceID',\n           'Status',\n           'Basic',\n           'Contact',\n           'ServiceTimestamp',\n           'Service',\n           'DeviceTimestamp',\n           'Device',\n           'PersonTimestamp',\n           'Person',\n           'PIDF',\n           # Extensions\n           'ExtendedStatus',\n           'StatusType',\n           'DeviceInfo']\n\n\nfrom itertools import izip\n\nfrom application.python.weakref import weakobjectmap\n\nfrom sipsimple.payloads import ValidationError, XMLDocument, XMLListRootElement, XMLListElement, XMLElement, XMLAttribute, XMLElementID, XMLElementChild\nfrom sipsimple.payloads import XMLStringElement, XMLLocalizedStringElement, XMLDateTimeElement, XMLAnyURIElement\nfrom sipsimple.payloads.datatypes import AnyURI, ID, DateTime\n\n\npidf_namespace = 'urn:ietf:params:xml:ns:pidf'\ndm_namespace = 'urn:ietf:params:xml:ns:pidf:data-model'\n\n\nclass PIDFDocument(XMLDocument):\n    content_type = 'application/pidf+xml'\n\nPIDFDocument.register_namespace(pidf_namespace, prefix=None, schema='pidf.xsd')\nPIDFDocument.register_namespace(dm_namespace, prefix='dm', schema='data-model.xsd')\n\n\n## Marker mixin\n\nclass ServiceExtension(object): pass\nclass ServiceItemExtension(object): pass\nclass DeviceExtension(object): pass\nclass PersonExtension(object): pass\nclass StatusExtension(object): pass\n\n\n## Attribute value types\n\nclass BasicStatusValue(str):\n    def __new__(cls, value):\n        if value not in ('closed', 'open'):\n            raise ValueError('illegal BasicStatusValue')\n        return str.__new__(cls, value)\n\n\n## General elements\n\nclass Note(unicode):\n    def __new__(cls, value, lang=None):\n        instance = unicode.__new__(cls, value)\n        instance.lang = lang\n        return instance\n\n    def __repr__(self):\n        return \"%s(%s, lang=%r)\" % (self.__class__.__name__, unicode.__repr__(self), self.lang)\n\n    def __eq__(self, other):\n        if isinstance(other, Note):\n            return unicode.__eq__(self, other) and self.lang == other.lang\n        elif isinstance(other, basestring):\n            return self.lang is None and unicode.__eq__(self, other)\n        else:\n            return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n\nclass PIDFNote(XMLLocalizedStringElement):\n    _xml_tag = 'note'\n    _xml_namespace = pidf_namespace\n    _xml_document = PIDFDocument\n\n    def __unicode__(self):\n        return Note(self.value, self.lang)\n\n\nclass DMNote(XMLLocalizedStringElement):\n    _xml_tag = 'note'\n    _xml_namespace = dm_namespace\n    _xml_document = PIDFDocument\n\n    def __unicode__(self):\n        return Note(self.value, self.lang)\n\n\nclass NoteMap(object):\n    \"\"\"Descriptor to be used for _note_map attributes on XML elements with notes\"\"\"\n\n    def __init__(self):\n        self.object_map = weakobjectmap()\n\n    def __get__(self, obj, type):\n        if obj is None:\n            return self\n        try:\n            return self.object_map[obj]\n        except KeyError:\n            return self.object_map.setdefault(obj, {})\n\n    def __set__(self, obj, value):\n        raise AttributeError(\"cannot set attribute\")\n\n    def __delete__(self, obj):\n        raise AttributeError(\"cannot delete attribute\")\n\n\nclass NoteList(object):\n    def __init__(self, xml_element, note_type):\n        self.xml_element = xml_element\n        self.note_type = note_type\n\n    def __contains__(self, item):\n        if isinstance(item, Note):\n            item = self.note_type(item, item.lang)\n        elif isinstance(item, basestring):\n            item = self.note_type(item)\n        return item in self.xml_element._note_map.itervalues()\n\n    def __iter__(self):\n        return (unicode(self.xml_element._note_map[element]) for element in self.xml_element.element if element in self.xml_element._note_map)\n\n    def __len__(self):\n        return len(self.xml_element._note_map)\n\n    def __eq__(self, other):\n        if isinstance(other, NoteList):\n            return self is other or (len(self) == len(other) and all(self_item == other_item for self_item, other_item in izip(self, other)))\n        else:\n            return NotImplemented\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n    def _parse_element(self, element):\n        self.xml_element._note_map.clear()\n        for child in element:\n            if child.tag == self.note_type.qname:\n                try:\n                    note = self.note_type.from_element(child, xml_document=self.xml_element._xml_document)\n                except ValidationError:\n                    pass\n                else:\n                    self.xml_element._note_map[note.element] = note\n\n    def _build_element(self):\n        for note in self.xml_element._note_map.itervalues():\n            note.to_element()\n\n    def add(self, item):\n        if isinstance(item, Note):\n            item = self.note_type(item, item.lang)\n        elif isinstance(item, basestring):\n            item = self.note_type(item)\n        if type(item) is not self.note_type:\n            raise TypeError(\"%s cannot add notes of type %s\" % (self.xml_element.__class__.__name__, item.__class__.__name__))\n        self.xml_element._insert_element(item.element)\n        self.xml_element._note_map[item.element] = item\n        self.xml_element.__dirty__ = True\n\n    def remove(self, item):\n        if isinstance(item, Note):\n            try:\n                item = (entry for entry in self.xml_element._note_map.itervalues() if unicode(entry) == item).next()\n            except StopIteration:\n                raise KeyError(item)\n        elif isinstance(item, basestring):\n            try:\n                item = (entry for entry in self.xml_element._note_map.itervalues() if entry == item).next()\n            except StopIteration:\n                raise KeyError(item)\n        if type(item) is not self.note_type:\n            raise KeyError(item)\n        self.xml_element.element.remove(item.element)\n        del self.xml_element._note_map[item.element]\n        self.xml_element.__dirty__ = True\n\n    def update(self, sequence):\n        for item in sequence:\n            self.add(item)\n\n    def clear(self):\n        for item in self.xml_element._note_map.values():\n            self.remove(item)\n\n\nclass DeviceID(XMLStringElement):\n    _xml_tag = 'deviceID'\n    _xml_namespace = dm_namespace\n    _xml_document = PIDFDocument\n\n\n## Service elements\n\nclass Basic(XMLStringElement):\n    _xml_tag = 'basic'\n    _xml_namespace = pidf_namespace\n    _xml_document = PIDFDocument\n    _xml_value_type = BasicStatusValue\n\n\nclass Status(XMLElement):\n    _xml_tag = 'status'\n    _xml_namespace = pidf_namespace\n    _xml_document = PIDFDocument\n    _xml_extension_type = StatusExtension\n    _xml_children_order = {Basic.qname: 0}\n\n    basic = XMLElementChild('basic', type=Basic, required=False, test_equal=True)\n\n    def __init__(self, basic=None):\n        XMLElement.__init__(self)\n        self.basic = basic\n\n    def check_validity(self):\n        if len(self.element) == 0:\n            raise ValidationError(\"Status objects must have at least one child\")\n        super(Status, self).check_validity()\n\n    def __repr__(self):\n        return '%s(%r)' % (self.__class__.__name__, self.basic)\n\n\nclass Contact(XMLAnyURIElement):\n    _xml_tag = 'contact'\n    _xml_namespace = pidf_namespace\n    _xml_document = PIDFDocument\n\n    priority = XMLAttribute('priority', type=float, required=False, test_equal=False)\n\n\nclass ServiceTimestamp(XMLDateTimeElement):\n    _xml_tag = 'timestamp'\n    _xml_namespace = pidf_namespace\n    _xml_document = PIDFDocument\n\n\nclass Service(XMLListElement):\n    _xml_tag = 'tuple'\n    _xml_namespace = pidf_namespace\n    _xml_document = PIDFDocument\n    _xml_extension_type = ServiceExtension\n    _xml_item_type = (DeviceID, ServiceItemExtension)\n    _xml_children_order = {Status.qname: 0,\n                           None: 1,\n                           Contact.qname: 2,\n                           PIDFNote.qname: 3,\n                           ServiceTimestamp.qname: 4}\n\n    id = XMLElementID('id', type=ID, required=True, test_equal=True)\n\n    status = XMLElementChild('status', type=Status, required=True, test_equal=True)\n    contact = XMLElementChild('contact', type=Contact, required=False, test_equal=True)\n    timestamp = XMLElementChild('timestamp', type=ServiceTimestamp, required=False, test_equal=True)\n\n    _note_map = NoteMap()\n\n    def __init__(self, id, notes=[], status=None, contact=None, timestamp=None):\n        XMLListElement.__init__(self)\n        self.id = id\n        self.status = status\n        self.contact = contact\n        self.timestamp = timestamp\n        self.notes.update(notes)\n\n    @property\n    def notes(self):\n        return NoteList(self, PIDFNote)\n\n    def __eq__(self, other):\n        if isinstance(other, Service):\n            return super(Service, self).__eq__(other) and self.notes == other.notes\n        else:\n            return self.id == other\n\n    def __repr__(self):\n        return '%s(%r, %r, %r, %r, %r)' % (self.__class__.__name__, self.id, list(self.notes), self.status, self.contact, self.timestamp)\n\n    def _parse_element(self, element):\n        super(Service, self)._parse_element(element)\n        self.notes._parse_element(element)\n\n    def _build_element(self):\n        super(Service, self)._build_element()\n        self.notes._build_element()\n\n\nclass DeviceTimestamp(XMLDateTimeElement):\n    _xml_tag = 'timestamp'\n    _xml_namespace = dm_namespace\n    _xml_document = PIDFDocument\n\n\nclass Device(XMLElement):\n    _xml_tag = 'device'\n    _xml_namespace = dm_namespace\n    _xml_document = PIDFDocument\n    _xml_extension_type = DeviceExtension\n    _xml_children_order = {None: 0,\n                           DeviceID.qname: 1,\n                           DMNote.qname: 2,\n                           DeviceTimestamp.qname: 3}\n\n    id = XMLElementID('id', type=ID, required=True, test_equal=True)\n    device_id = XMLElementChild('device_id', type=DeviceID, required=False, test_equal=True)\n    timestamp = XMLElementChild('timestamp', type=DeviceTimestamp, required=False, test_equal=True)\n\n    _note_map = NoteMap()\n\n    def __init__(self, id, device_id=None, notes=[], timestamp=None):\n        XMLElement.__init__(self)\n        self.id = id\n        self.device_id = device_id\n        self.timestamp = timestamp\n        self.notes.update(notes)\n\n    @property\n    def notes(self):\n        return NoteList(self, DMNote)\n\n    def __eq__(self, other):\n        if isinstance(other, Device):\n            return super(Device, self).__eq__(other) and self.notes == other.notes\n        else:\n            return self.id == other\n\n    def __repr__(self):\n        return '%s(%r, %r, %r, %r)' % (self.__class__.__name__, self.id, self.device_id, list(self.notes), self.timestamp)\n\n    def _parse_element(self, element):\n        super(Device, self)._parse_element(element)\n        self.notes._parse_element(element)\n\n    def _build_element(self):\n        super(Device, self)._build_element()\n        self.notes._build_element()\n\n\nclass PersonTimestamp(XMLDateTimeElement):\n    _xml_tag = 'timestamp'\n    _xml_namespace = dm_namespace\n    _xml_document = PIDFDocument\n\n\nclass Person(XMLElement):\n    _xml_tag = 'person'\n    _xml_namespace = dm_namespace\n    _xml_document = PIDFDocument\n    _xml_extension_type = PersonExtension\n    _xml_children_order = {None: 0,\n                           DMNote.qname: 1,\n                           PersonTimestamp.qname: 2}\n\n    id = XMLElementID('id', type=ID, required=True, test_equal=True)\n    timestamp = XMLElementChild('timestamp', type=PersonTimestamp, required=False, test_equal=True)\n\n    _note_map = NoteMap()\n\n    def __init__(self, id, notes=[], timestamp=None):\n        XMLElement.__init__(self)\n        self.id = id\n        self.timestamp = timestamp\n        self.notes.update(notes)\n\n    @property\n    def notes(self):\n        return NoteList(self, DMNote)\n\n    def __eq__(self, other):\n        if isinstance(other, Person):\n            return super(Person, self).__eq__(other) and self.notes == other.notes\n        else:\n            return self.id == other\n\n    def __repr__(self):\n        return '%s(%r, %r, %r)' % (self.__class__.__name__, self.id, list(self.notes), self.timestamp)\n\n    def _parse_element(self, element):\n        super(Person, self)._parse_element(element)\n        self.notes._parse_element(element)\n\n    def _build_element(self):\n        super(Person, self)._build_element()\n        self.notes._build_element()\n\n\nclass PIDF(XMLListRootElement):\n    _xml_tag = 'presence'\n    _xml_namespace = pidf_namespace\n    _xml_document = PIDFDocument\n    _xml_children_order = {Service.qname: 0,\n                           PIDFNote.qname: 1,\n                           Person.qname: 2,\n                           Device.qname: 3}\n    _xml_item_type = (Service, PIDFNote, Person, Device)\n\n    entity = XMLAttribute('entity', type=AnyURI, required=True, test_equal=True)\n\n    services = property(lambda self: (item for item in self if type(item) is Service))\n    notes    = property(lambda self: (item for item in self if type(item) is Note))\n    persons  = property(lambda self: (item for item in self if type(item) is Person))\n    devices  = property(lambda self: (item for item in self if type(item) is Device))\n\n    def __init__(self, entity, elements=[]):\n        XMLListRootElement.__init__(self)\n        self.entity = entity\n        self.update(elements)\n\n    def __contains__(self, item):\n        if isinstance(item, Note):\n            item = PIDFNote(item, item.lang)\n        return super(PIDF, self).__contains__(item)\n\n    def __iter__(self):\n        return (unicode(item) if type(item) is PIDFNote else item for item in super(PIDF, self).__iter__())\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.entity, list(self))\n\n    def add(self, item):\n        if isinstance(item, Note):\n            item = PIDFNote(item, item.lang)\n        super(PIDF, self).add(item)\n\n    def remove(self, item):\n        if isinstance(item, Note):\n            try:\n                item = (entry for entry in super(PIDF, self).__iter__() if type(entry) is PIDFNote and unicode(entry) == item).next()\n            except StopIteration:\n                raise KeyError(item)\n        super(PIDF, self).remove(item)\n\n\n#\n# Extensions\n#\n\nagp_pidf_namespace = 'urn:ag-projects:xml:ns:pidf'\nPIDFDocument.register_namespace(agp_pidf_namespace, prefix='agp-pidf')\n\nclass ExtendedStatusValue(str):\n    def __new__(cls, value):\n        if value not in ('available', 'offline', 'away', 'busy'):\n            raise ValueError(\"illegal value for extended status\")\n        return str.__new__(cls, value)\n\nclass ExtendedStatus(XMLStringElement, StatusExtension):\n    _xml_tag = 'extended'\n    _xml_namespace = agp_pidf_namespace\n    _xml_document = PIDFDocument\n    _xml_value_type = ExtendedStatusValue\n\nclass StatusType(XMLStringElement, StatusExtension):\n    _xml_tag = 'type'\n    _xml_namespace = agp_pidf_namespace\n    _xml_document = PIDFDocument\n\nStatus.register_extension('extended', type=ExtendedStatus)\nStatus.register_extension('type', type=StatusType)\n\n\nclass Description(XMLStringElement):\n    _xml_tag = 'description'\n    _xml_namespace = agp_pidf_namespace\n    _xml_document = PIDFDocument\n\nclass UserAgent(XMLStringElement):\n    _xml_tag = 'user-agent'\n    _xml_namespace = agp_pidf_namespace\n    _xml_document = PIDFDocument\n\nclass TimeOffset(XMLStringElement):\n    _xml_tag = 'time-offset'\n    _xml_namespace = agp_pidf_namespace\n    _xml_document = PIDFDocument\n\n    description = XMLAttribute('description', type=unicode, required=False, test_equal=True)\n\n    def __init__(self, value=None, description=None):\n        if value is None:\n            value = DateTime.now().utcoffset().seconds / 60\n        XMLStringElement.__init__(self, str(value))\n        self.description = description\n\n    def __int__(self):\n        return int(self.value)\n\nclass DeviceInfo(XMLElement, ServiceExtension):\n    _xml_tag = 'device-info'\n    _xml_namespace = agp_pidf_namespace\n    _xml_document = PIDFDocument\n    _xml_children_order = {Description.qname: 0,\n                           UserAgent.qname: 1}\n\n    id = XMLElementID('id', type=str, required=True, test_equal=True)\n    description = XMLElementChild('description', type=Description, required=False, test_equal=True)\n    user_agent = XMLElementChild('user_agent', type=UserAgent, required=False, test_equal=True)\n    time_offset = XMLElementChild('time_offset', type=TimeOffset, required=False, test_equal=True)\n\n    def __init__(self, id, description=None, user_agent=None, time_offset=None):\n        XMLElement.__init__(self)\n        self.id = id\n        self.description = description\n        self.user_agent = user_agent\n        self.time_offset = time_offset\n\n    def __repr__(self):\n        return '%s(%r, %r, %r, %r)' % (self.__class__.__name__, self.id, self.description, self.user_agent, self.time_offset)\n\nService.register_extension('device_info', type=DeviceInfo)\n\n"
  },
  {
    "path": "sipsimple/payloads/prescontent.py",
    "content": "\n\"\"\"Generates presence content application documents according to OMA TS Presence SIMPLE Content\"\"\"\n\n\n__all__ = ['namespace', 'PresenceContentDocument', 'MIMEType', 'Encoding', 'Description', 'Data', 'PresenceContent']\n\n\nfrom sipsimple.payloads import XMLDocument, XMLRootElement, XMLStringElement, XMLLocalizedStringElement, XMLElementChild\n\n\nnamespace = 'urn:oma:xml:prs:pres-content'\n\n\nclass PresenceContentDocument(XMLDocument):\n    content_type = \"application/vnd.oma.pres-content+xml\"\n\nPresenceContentDocument.register_namespace(namespace, prefix=None, schema='oma-pres-content.xsd')\n\n# Elements\nclass MIMEType(XMLStringElement):\n    _xml_tag = 'mime-type'\n    _xml_namespace = namespace\n    _xml_document = PresenceContentDocument\n\n\nclass Encoding(XMLStringElement):\n    _xml_tag = 'encoding'\n    _xml_namespace = namespace\n    _xml_document = PresenceContentDocument\n\n\nclass Description(XMLLocalizedStringElement):\n    _xml_tag = 'description'\n    _xml_namespace = namespace\n    _xml_document = PresenceContentDocument\n\n\nclass Data(XMLStringElement):\n    _xml_tag = 'data'\n    _xml_namespace = namespace\n    _xml_document = PresenceContentDocument\n\n\nclass PresenceContent(XMLRootElement):\n    _xml_tag = 'content'\n    _xml_namespace = namespace\n    _xml_document = PresenceContentDocument\n    _xml_children_order = {MIMEType.qname: 0,\n                           Encoding.qname: 1,\n                           Description.qname: 2,\n                           Data.qname: 3,\n                           None: 4}\n\n    mime_type = XMLElementChild('mime_type', type=MIMEType, required=False, test_equal=True)\n    encoding = XMLElementChild('encoding', type=Encoding, required=False, test_equal=True)\n    description = XMLElementChild('description', type=Description, required=False, test_equal=True)\n    data = XMLElementChild('data', type=Data, required=True, test_equal=True)\n\n    def __init__(self, data, mime_type=None, encoding=None, description=None):\n        XMLRootElement.__init__(self)\n        self.data = data\n        self.mime_type = mime_type\n        self.encoding = encoding\n        self.description = description\n\n"
  },
  {
    "path": "sipsimple/payloads/presrules.py",
    "content": "\n\"\"\"Parses and produces Presence Authorization Rules documents according to RFC5025.\"\"\"\n\n\n__all__ = ['namespace',\n           'PresRulesDocument',\n           'SubHandling',\n           'DeviceID',\n           'Class',\n           'All',\n           'ProvideDevices',\n           'OccurenceID',\n           'ProvidePersons',\n           'ServiceURI',\n           'ServiceURIScheme',\n           'ProvideServices',\n           'ProvideActivities',\n           'ProvideClass',\n           'ProvideDeviceID',\n           'ProvideMood',\n           'ProvidePlaceIs',\n           'ProvidePlaceType',\n           'ProvidePrivacy',\n           'ProvideRelationship',\n           'ProvideStatusIcon',\n           'ProvideSphere',\n           'ProvideTimeOffset',\n           'ProvideUserInput',\n           'ProvideUnknownAttribute',\n           'ProvideAllAttributes',\n           'PresRules']\n\n\nfrom sipsimple.payloads import XMLListElement, XMLStringElement, XMLBooleanElement, XMLEmptyElement, XMLAttribute\nfrom sipsimple.payloads import commonpolicy\nfrom sipsimple.util import All\n\n\nnamespace = 'urn:ietf:params:xml:ns:pres-rules'\n\nclass PresRulesDocument(commonpolicy.CommonPolicyDocument): pass\nPresRulesDocument.register_namespace(namespace, prefix='pr', schema='pres-rules.xsd')\n\n\n## Marker mixins\n\nclass ProvideDeviceElement(object): pass\nclass ProvidePersonElement(object): pass\nclass ProvideServiceElement(object): pass\n\n\n## Attribute value types\n\nclass SubHandlingValue(str):\n    __prioritymap__ = {'block': 0, 'confirm': 10, 'polite-block': 20, 'allow': 30}\n\n    def __new__(cls, value):\n        if value not in cls.__prioritymap__:\n            raise ValueError(\"illegal value for SubHandling element\")\n        return str.__new__(cls, value)\n\n    @property\n    def priority(self):\n        return self.__prioritymap__[self]\n\n\nclass ProvideUserInputValue(str):\n    def __new__(cls, value):\n        if value not in ('false', 'bare', 'thresholds', 'full'):\n            raise ValueError(\"illegal value for ProvideUserInput element\")\n        return str.__new__(cls, value)\n\n\n## Action Elements\n\nclass SubHandling(XMLStringElement, commonpolicy.ActionElement):\n    _xml_tag = 'sub-handling'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n    _xml_value_type = SubHandlingValue\n\n\n## Transformation Elements\n\nclass Class(XMLStringElement):\n    _xml_tag = 'class'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass OccurenceID(XMLStringElement):\n    _xml_tag = 'occurence-id'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\n## Devices element\n\n\nclass DeviceID(XMLStringElement):\n    _xml_tag = 'deviceID'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass AllDevices(XMLEmptyElement):\n    _xml_tag = 'all-devices'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvideDevices(XMLListElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-devices'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n    _xml_item_type = (DeviceID, OccurenceID, Class, AllDevices, ProvideDeviceElement)\n\n    def __init__(self, provides=[]):\n        XMLListElement.__init__(self)\n        self.update(provides)\n\n    def __contains__(self, item):\n        if item == All:\n            item = AllDevices()\n        return super(ProvideDevices, self).__contains__(item)\n\n    def __iter__(self):\n        return (All if type(item) is AllDevices else item for item in super(ProvideDevices, self).__iter__())\n\n    def add(self, item):\n        if item == All:\n            item = AllDevices()\n        if type(item) is AllDevices:\n            self.clear()\n        else:\n            try:\n                self.remove(All)\n            except KeyError:\n                pass\n        super(ProvideDevices, self).add(item)\n\n    def remove(self, item):\n        if item == All:\n            try:\n                item = (item for item in super(ProvideDevices, self).__iter__() if type(item) is AllDevices).next()\n            except StopIteration:\n                raise KeyError(item)\n        super(ProvideDevices, self).remove(item)\n\n\n## Persons elmeent\n\nclass AllPersons(XMLEmptyElement):\n    _xml_tag = 'all-persons'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvidePersons(XMLListElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-persons'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n    _xml_item_type = (OccurenceID, Class, AllPersons, ProvidePersonElement)\n\n    def __init__(self, provides=[]):\n        XMLListElement.__init__(self)\n        self.update(provides)\n\n    def __contains__(self, item):\n        if item == All:\n            item = AllPersons()\n        return super(ProvidePersons, self).__contains__(item)\n\n    def __iter__(self):\n        return (All if type(item) is AllPersons else item for item in super(ProvidePersons, self).__iter__())\n\n    def add(self, item):\n        if item == All:\n            item = AllPersons()\n        if type(item) is AllPersons:\n            self.clear()\n        else:\n            try:\n                self.remove(All)\n            except KeyError:\n                pass\n        super(ProvidePersons, self).add(item)\n\n    def remove(self, item):\n        if item == All:\n            try:\n                item = (item for item in super(ProvidePersons, self).__iter__() if type(item) is AllPersons).next()\n            except StopIteration:\n                raise KeyError(item)\n        super(ProvidePersons, self).remove(item)\n\n\n## Service elements\n\nclass ServiceURI(XMLStringElement):\n    _xml_tag = 'service-uri'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ServiceURIScheme(XMLStringElement):\n    _xml_tag = 'service-uri-scheme'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass AllServices(XMLEmptyElement):\n    _xml_tag = 'all-services'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvideServices(XMLListElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-services'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n    _xml_item_type = (ServiceURI, ServiceURIScheme, OccurenceID, Class, AllServices, ProvideServiceElement)\n\n    def __init__(self, provides=[]):\n        XMLListElement.__init__(self)\n        self.update(provides)\n\n    def __contains__(self, item):\n        if item == All:\n            item = AllServices()\n        return super(ProvideServices, self).__contains__(item)\n\n    def __iter__(self):\n        return (All if type(item) is AllServices else item for item in super(ProvideServices, self).__iter__())\n\n    def add(self, item):\n        if item == All:\n            item = AllServices()\n        if type(item) is AllServices:\n            self.clear()\n        else:\n            try:\n                self.remove(All)\n            except KeyError:\n                pass\n        super(ProvideServices, self).add(item)\n\n    def remove(self, item):\n        if item == All:\n            try:\n                item = (item for item in super(ProvideServices, self).__iter__() if type(item) is AllServices).next()\n            except StopIteration:\n                raise KeyError(item)\n        super(ProvideServices, self).remove(item)\n\n\n## Transformation elements\n\nclass ProvideActivities(XMLBooleanElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-activities'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvideClass(XMLBooleanElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-class'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvideDeviceID(XMLBooleanElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-deviceID'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvideMood(XMLBooleanElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-mood'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvidePlaceIs(XMLBooleanElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-place-is'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvidePlaceType(XMLBooleanElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-place-type'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvidePrivacy(XMLBooleanElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-privacy'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvideRelationship(XMLBooleanElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-relationship'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvideStatusIcon(XMLBooleanElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-status-icon'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvideSphere(XMLBooleanElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-sphere'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvideTimeOffset(XMLBooleanElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-time-offset'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass ProvideUserInput(XMLStringElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-user-input'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n    _xml_value_type = ProvideUserInputValue\n\n\nclass ProvideUnknownAttribute(XMLBooleanElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-unknown-attribute'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n    name = XMLAttribute('name', type=str, required=True, test_equal=True)\n    ns = XMLAttribute('ns', type=str, required=True, test_equal=True)\n\n    def __init__(self, ns, name, value):\n        XMLBooleanElement.__init__(self, value)\n        self.ns = ns\n        self.name = name\n\n    def __repr__(self):\n        return '%s(%r, %r, %r)' % (self.__class__.__name__, self.ns, self.name, self.value)\n\n\nclass ProvideAllAttributes(XMLEmptyElement, commonpolicy.TransformationElement):\n    _xml_tag = 'provide-all-attributes'\n    _xml_namespace = namespace\n    _xml_document = PresRulesDocument\n\n\nclass PresRules(commonpolicy.RuleSet):\n    _xml_document = PresRulesDocument\n\n\n"
  },
  {
    "path": "sipsimple/payloads/resourcelists.py",
    "content": "\n\"\"\"Resource lists (rfc4826) handling\"\"\"\n\n\n__all__ = ['namespace',\n           'ResourceListsDocument',\n           'DisplayName',\n           'Entry',\n           'EntryRef',\n           'External',\n           'List',\n           'ResourceLists',\n           # Extensions\n           'EntryAttributes']\n\n\nfrom collections import deque\nfrom lxml import etree\nfrom xml.sax.saxutils import quoteattr\n\nfrom application.python import Null\n\nfrom sipsimple.payloads import XMLDocument, XMLListRootElement, XMLElement, XMLListElement, XMLLocalizedStringElement, XMLElementID, XMLElementChild, ThisClass\nfrom sipsimple.payloads import IterateIDs, IterateItems, All\nfrom sipsimple.payloads.datatypes import AnyURI\n\n\nnamespace = 'urn:ietf:params:xml:ns:resource-lists'\n\n# excerpt from the RFC:\n\n# <list>\n# attribute \"name\" - optional, unique among the same level \n# body: optional <display-name>, the sequence of entry/list/entry-ref/external\n\n# <display-name>\n# attribute xml:lang - optional\n# body: utf8 string\n\n# <entry>\n# attribute \"uri\" - mandatory, unique among all other <uri> within the same parent\n# body: optional <display-name>\n\n# <entry-ref>\n# attribute \"ref\" - mandatory, unique among all other <entry-ref> within the same parent\n# body: optional <display-name>\n# ref is a relative URI that resolves into <entry>\n\n# <external>\n# attribute \"anchor\" - mandatory, unique among all other anchor in <external> within the same parent\n# anchor must be an absolute http uri that resolves into <list>\n\n\nclass ResourceListsDocument(XMLDocument):\n    content_type = 'application/resource-lists+xml'\n\nResourceListsDocument.register_namespace(namespace, prefix='rl', schema='resourcelists.xsd')\n\n\n## Marker mixins\n\nclass ListElement(object): pass\nclass EntryExtension(object): pass\n\n\n## Elements\n\nclass DisplayName(XMLLocalizedStringElement):\n    _xml_tag = 'display-name'\n    _xml_namespace = namespace\n    _xml_document = ResourceListsDocument\n\n\nclass Entry(XMLElement):\n    _xml_tag = 'entry'\n    _xml_namespace = namespace\n    _xml_extension_type = EntryExtension\n    _xml_document = ResourceListsDocument\n    _xml_children_order = {DisplayName.qname: 0}\n\n    uri = XMLElementID('uri', type=AnyURI, required=True, test_equal=True)\n    display_name = XMLElementChild('display_name', type=DisplayName, required=False, test_equal=False)\n\n    def __init__(self, uri, display_name=None):\n        XMLElement.__init__(self)\n        self.uri = uri\n        self.display_name = display_name\n\n    def __unicode__(self):\n        return self.display_name and u'\"%s\" <%s>' % (self.display_name, self.uri) or self.uri\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.uri, self.display_name)\n\n\nclass EntryRef(XMLElement):\n    _xml_tag = 'entry-ref'\n    _xml_namespace = namespace\n    _xml_document = ResourceListsDocument\n    _xml_children_order = {DisplayName.qname: 0}\n\n    ref = XMLElementID('ref', type=AnyURI, required=True, test_equal=True)\n    display_name = XMLElementChild('display_name', type=DisplayName, required=False, test_equal=False)\n\n    def __init__(self, ref, display_name=None):\n        XMLElement.__init__(self)\n        self.ref = ref\n        self.display_name = display_name\n\n    def __unicode__(self):\n        return self.display_name and '\"%s\" <%s>' % (self.display_name, self.ref) or self.ref\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.ref, self.display_name)\n\n\nclass External(XMLElement):\n    _xml_tag = 'external'\n    _xml_namespace = namespace\n    _xml_document = ResourceListsDocument\n    _xml_children_order = {DisplayName.qname: 0}\n\n    anchor = XMLElementID('anchor', type=AnyURI, required=True, test_equal=True)\n    display_name = XMLElementChild('display_name', type=DisplayName, required=False, test_equal=False)\n\n    def __init__(self, anchor, display_name=None):\n        XMLElement.__init__(self)\n        self.anchor = anchor\n        self.display_name = display_name\n\n    def __unicode__(self):\n        return self.display_name and '\"%s\" <%s>' % (self.display_name, self.anchor) or self.anchor\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.anchor, self.display_name)\n\n\nList = ThisClass # a List can contain items of its own kind\n\nclass List(XMLListElement):\n    _xml_tag = 'list'\n    _xml_namespace = namespace\n    _xml_document = ResourceListsDocument\n    _xml_children_order = {DisplayName.qname: 0,\n                           Entry.qname: 1,\n                           EntryRef.qname: 1,\n                           External.qname: 1}\n    _xml_item_type = (Entry, EntryRef, External, List, ListElement)\n\n    name = XMLElementID('name', type=unicode, required=False, test_equal=True)\n    display_name = XMLElementChild('display_name', type=DisplayName, required=False, test_equal=False)\n\n    def __init__(self, entries=[], name=None, display_name=None):\n        XMLListElement.__init__(self)\n        self.name = name\n        self.display_name = display_name\n        self.update(entries)\n\n    def __repr__(self):\n        return '%s(%s, %r, %r)' % (self.__class__.__name__, list(self), self.name, self.display_name)\n\n    def __unicode__(self):\n        name = u'List element'\n        if self.name is not None:\n            name += u' %s' % self.name\n        if self.display_name is not None:\n            name += u' (%s)' % self.display_name\n        return name\n\nList._xml_children_order[List.qname] = 1 # cannot self reference in declaration\n\n\nclass ResourceLists(XMLListRootElement):\n    _xml_tag = 'resource-lists'\n    _xml_namespace = namespace\n    _xml_document = ResourceListsDocument\n    _xml_children_order = {List.qname: 0}\n    _xml_item_type = List\n\n    def __init__(self, lists=[]):\n        XMLListRootElement.__init__(self)\n        self.update(lists)\n\n    def __getitem__(self, key):\n        if key is IterateIDs:\n            return self._xmlid_map[List].iterkeys()\n        elif key is IterateItems:\n            return self._xmlid_map[List].itervalues()\n        else:\n            return self._xmlid_map[List][key]\n\n    def __delitem__(self, key):\n        if key is All:\n            for item in self._xmlid_map[List].values():\n                self.remove(item)\n        else:\n            self.remove(self._xmlid_map[List][key])\n\n    def get(self, key, default=None):\n        return self._xmlid_map[List].get(key, default)\n\n    def get_xpath(self, element):\n        if not isinstance(element, (List, Entry, EntryRef, External, ResourceLists)):\n            raise ValueError('can only find xpath for List, Entry, EntryRef or External elements')\n        nsmap = dict((namespace, prefix) for prefix, namespace in self._xml_document.nsmap.iteritems())\n        nsmap[self._xml_namespace] = None\n        xpath_nsmap = {}\n        root_xpath = '/' + self._xml_tag\n        if element is self:\n            return root_xpath\n        notexpanded = deque([self])\n        visited = set(notexpanded)\n        parents = {self: None}\n        obj = None\n        while notexpanded:\n            list = notexpanded.popleft()\n            for child in list:\n                if child is element:\n                    parents[child] = list\n                    obj = child\n                    notexpanded.clear()\n                    break\n                elif isinstance(child, List) and child not in visited:\n                    parents[child] = list\n                    notexpanded.append(child)\n                    visited.add(child)\n        if obj is None:\n            return None\n        components = []\n        while obj is not self:\n            prefix = nsmap[obj._xml_namespace]\n            if prefix:\n                name = '%s:%s' % (prefix, obj._xml_tag)\n                xpath_nsmap[obj._xml_namespace] = prefix\n            else:\n                name = obj._xml_tag\n            if isinstance(obj, List):\n                if obj.name is not None:\n                    components.append('/%s[@%s=%s]' % (name, List.name.xmlname, quoteattr(obj.name)))\n                else:\n                    siblings = [l for l in parents[obj] if isinstance(l, List)]\n                    components.append('/%s[%d]' % (name, siblings.index(obj)+1))\n            elif isinstance(obj, Entry):\n                components.append('/%s[@%s=%s]' % (name, Entry.uri.xmlname, quoteattr(obj.uri)))\n            elif isinstance(obj, EntryRef):\n                components.append('/%s[@%s=%s]' % (name, EntryRef.ref.xmlname, quoteattr(obj.ref)))\n            elif isinstance(obj, External):\n                components.append('/%s[@%s=%s]' % (name, External.anchor.xmlname, quoteattr(obj.anchor)))\n            obj = parents[obj]\n        components.reverse()\n        return root_xpath + ''.join(components) + ('?' + ''.join('xmlns(%s=%s)' % (prefix, namespace) for namespace, prefix in xpath_nsmap.iteritems()) if xpath_nsmap else '')\n\n    def find_parent(self, element):\n        if not isinstance(element, (List, Entry, EntryRef, External)):\n            raise ValueError('can only find parent for List, Entry, EntryRef or External elements')\n        if element is self:\n            return None\n        notexpanded = deque([self])\n        visited = set(notexpanded)\n        while notexpanded:\n            list = notexpanded.popleft()\n            for child in list:\n                if child is element:\n                    return list\n                elif isinstance(child, List) and child not in visited:\n                    notexpanded.append(child)\n                    visited.add(child)\n        return None\n\n\n#\n# Extensions\n#\n\nclass EntryAttributes(XMLElement, EntryExtension):\n    _xml_tag = 'attributes'\n    _xml_namespace = 'urn:ag-projects:xml:ns:resource-lists'\n    _xml_document = ResourceListsDocument\n\n    def __init__(self, iterable=(), **attributes):\n        XMLElement.__init__(self)\n        self._attributes = dict()\n        self.update(iterable, **attributes)\n\n    def _parse_element(self, element):\n        self._attributes = dict()\n        attribute_tag = '{%s}attribute' % self._xml_namespace\n        for child in (child for child in element if child.tag == attribute_tag):\n            if 'nil' in child.attrib:\n                self[child.attrib['name']] = None\n            else:\n                self[child.attrib['name']] = unicode(child.text or u'')\n\n    def _build_element(self):\n        self.element.clear()\n        attribute_tag = '{%s}attribute' % self._xml_namespace\n        for key, value in self.iteritems():\n            child = etree.SubElement(self.element, attribute_tag, nsmap=self._xml_document.nsmap)\n            child.attrib['name'] = key\n            if value is None:\n                child.attrib['nil'] = 'true'\n            else:\n                child.text = value\n\n    def __contains__(self, key):\n        return key in self._attributes\n\n    def __iter__(self):\n        return iter(self._attributes)\n\n    def __len__(self):\n        return len(self._attributes)\n\n    def __getitem__(self, key):\n        return self._attributes[key]\n\n    def __setitem__(self, key, value):\n        if self._attributes.get(key, Null) == value:\n            return\n        self._attributes[key] = value\n        self.__dirty__ = True\n\n    def __delitem__(self, key):\n        del self._attributes[key]\n        self.__dirty__ = True\n\n    def clear(self):\n        if self._attributes:\n            self._attributes.clear()\n            self.__dirty__ = True\n\n    def get(self, key, default=None):\n        return self._attributes.get(key, default)\n\n    def has_key(self, key):\n        return key in self._attributes\n\n    def items(self):\n        return self._attributes.items()\n\n    def iteritems(self):\n        return self._attributes.iteritems()\n\n    def iterkeys(self):\n        return self._attributes.iterkeys()\n\n    def itervalues(self):\n        return self._attributes.itervalues()\n\n    def keys(self):\n        return self._attributes.keys()\n\n    def pop(self, key, *args):\n        value = self._attributes.pop(key, *args)\n        if not args or value is not args[0]:\n            self.__dirty__ = True\n        return value\n\n    def popitem(self):\n        value = self._attributes.popitem()\n        self.__dirty__ = True\n        return value\n\n    def setdefault(self, key, default=None):\n        value = self._attributes.setdefault(key, default)\n        if value is default:\n            self.__dirty__ = True\n        return value\n\n    def update(self, iterable=(), **attributes):\n        self._attributes.update(iterable, **attributes)\n        if iterable or attributes:\n            self.__dirty__ = True\n\nResourceListsDocument.register_namespace(EntryAttributes._xml_namespace, prefix='agp-rl')\nEntry.register_extension('attributes', EntryAttributes)\n\n\n"
  },
  {
    "path": "sipsimple/payloads/rlmi.py",
    "content": "\n\"\"\"RLMI document handling as described in RFC 4662\"\"\"\n\n\n__all__ = ['namespace', 'RLMIDocument', 'Name', 'Instance', 'Resource', 'List']\n\n\nfrom sipsimple.payloads import XMLDocument, XMLElement, XMLListElement, XMLListRootElement, XMLLocalizedStringElement, XMLElementID, XMLAttribute\nfrom sipsimple.payloads.datatypes import AnyURI, Boolean, UnsignedInt\n\n\nnamespace = 'urn:ietf:params:xml:ns:rlmi'\n\n\nclass RLMIDocument(XMLDocument):\n    content_type = 'application/rlmi+xml'\n\nRLMIDocument.register_namespace(namespace, prefix=None, schema='rlmi.xsd')\n\n\nclass StateValue(str):\n    def __new__(cls, value):\n        if value not in ('active', 'pending', 'terminated'):\n            raise ValueError(\"Invalid state value: %s\" % value)\n        return str.__new__(cls, value)\n\n\nclass Name(XMLLocalizedStringElement):\n    _xml_tag = 'name'\n    _xml_namespace = namespace\n    _xml_document = RLMIDocument\n\n\nclass Instance(XMLElement):\n    _xml_tag = 'instance'\n    _xml_namespace = namespace\n    _xml_document = RLMIDocument\n\n    id = XMLElementID('id', type=str, required=True, test_equal=True)\n    state = XMLAttribute('state', type=StateValue, required=True, test_equal=True)\n    reason = XMLAttribute('reason', type=str, required=False, test_equal=True)\n    cid = XMLAttribute('cid', type=str, required=False, test_equal=True)\n\n    def __init__(self, id, state, reason=None, cid=None):\n        XMLElement.__init__(self)\n        self.id = id\n        self.state = state\n        self.reason = reason\n        self.cid = cid\n\n    def __repr__(self):\n        return '%s(%r, state=%r, reason=%r, cid=%r)' % (self.__class__.__name__, self.id, self.state, self.reason, self.cid)\n\n\nclass Resource(XMLListElement):\n    _xml_tag = 'resource'\n    _xml_namespace = namespace\n    _xml_document = RLMIDocument\n    _xml_item_type = (Name, Instance)\n\n    uri = XMLElementID('uri', type=AnyURI, required=True, test_equal=True)\n\n    def __init__(self, uri, items=[]):\n        XMLElement.__init__(self)\n        self.uri = uri\n        self.update(items)\n\n    def __repr__(self):\n        return '%s(%r, items=%r)' % (self.__class__.__name__, self.uri, list(self))\n\n\nclass List(XMLListRootElement):\n    _xml_tag = 'list'\n    _xml_namespace = namespace\n    _xml_document = RLMIDocument\n    _xml_item_type = (Name, Resource)\n\n    uri = XMLElementID('uri', type=AnyURI, required=True, test_equal=True)\n    version = XMLAttribute('version', type=UnsignedInt, required=True, test_equal=True)\n    full_state = XMLAttribute('full_state', xmlname='fullState', type=Boolean, required=True, test_equal=True)\n    cid = XMLAttribute('cid', type=str, required=False, test_equal=True)\n\n    def __init__(self, uri, version, full_state, cid=None, items=[]):\n        XMLListElement.__init__(self)\n        self.uri = uri\n        self.version = version\n        self.full_state = full_state\n        self.cid = cid\n        self.update(items)\n\n    def __repr__(self):\n        return '%s(%r, version=%r, full_state=%r, cid=%r, items=%r)' % (self.__class__.__name__, self.uri, self.version, self.full_state, self.cid, list(self))\n\n\n"
  },
  {
    "path": "sipsimple/payloads/rlsnotify.py",
    "content": "\n\"\"\"Payload of the RLS notify messages.\"\"\"\n\n__all__ = ['RLSNotify']\n\nimport email\n\nfrom sipsimple.payloads import IterateItems, ParserError\nfrom sipsimple.payloads import rlmi, pidf\nfrom sipsimple.payloads import rpid; rpid # needs to be imported to register its namespace\n\n\nclass ResourceURI(unicode):\n    def __eq__(self, other):\n        return super(ResourceURI, self).__eq__(other) or self.rpartition('sip:')[2] == other\n\n    def __ne__(self, other):\n        equal = self.__eq__(other)\n        return NotImplemented if equal is NotImplemented else not equal\n\n\nclass Resource(object):\n    __prioritymap__ = dict(active=10, pending=20, terminated=30)\n\n    def __init__(self, uri, name=None, state=None, reason=None, pidf_list=None):\n        self.uri = ResourceURI(uri)\n        self.name = name\n        self.state = state\n        self.reason = reason\n        self.pidf_list = pidf_list or []\n\n    @classmethod\n    def from_payload(cls, xml_element, payload_map):\n        try:\n            name = next(element for element in xml_element if isinstance(element, rlmi.Name))\n        except StopIteration:\n            name = None\n        instances = list(xml_element[rlmi.Instance, IterateItems])\n        if len(instances) == 0:\n            state = None\n            reason = None\n        elif len(instances) == 1:\n            instance = instances[0]\n            state = instance.state\n            reason = instance.reason\n        else:\n            instance = sorted(instances, key=lambda item: cls.__prioritymap__[item.state])[0]\n            state = instance.state\n            reason = instance.reason\n        pidf_list = []\n        for instance in (instance for instance in instances if instance.cid is not None):\n            try:\n                payload = payload_map['<%s>' % instance.cid].get_payload()\n            except KeyError:\n                continue\n            try:\n                pidf_list.append(pidf.PIDFDocument.parse(payload))\n            except ParserError:\n                pass\n        return cls(xml_element.uri, name, state, reason, pidf_list)\n\n\nclass RLSNotify(object):\n    \"\"\"The payload from RLS notify messages\"\"\"\n\n    content_type = 'multipart/related'\n\n    def __init__(self, uri, version, full_state, resources):\n        self.uri = ResourceURI(uri)\n        self.version = version\n        self.full_state = full_state\n        self.resources = resources\n\n    def __iter__(self):\n        return iter(self.resources)\n\n    def __len__(self):\n        return len(self.resources)\n\n    @classmethod\n    def parse(cls, payload):\n        message = email.message_from_string(payload)\n        if message.get_content_type() != cls.content_type:\n            raise ParserError(\"expected multipart/related content, got %s\" % message.get_content_type())\n        payloads = message.get_payload()\n        if len(payloads) == 0:\n            raise ParserError(\"multipart/related body contains no parts\")\n        payload_map = dict((payload['Content-ID'], payload) for payload in payloads if payload['Content-ID'] is not None)\n        root_id = message.get_param('start')\n        root_type = message.get_param('type', '').lower()\n        if root_id is not None:\n            try:\n                root = payload_map[root_id]\n            except KeyError:\n                raise ParserError('cannot find root element')\n        else:\n            root = payloads[0]\n        if root_type != rlmi.RLMIDocument.content_type != root.get_content_type():\n            raise ParserError(\"the multipart/related root element must be of type %s\" % rlmi.RLMIDocument.content_type)\n        rlmi_document = rlmi.RLMIDocument.parse(root.get_payload())\n        resources = [Resource.from_payload(xml_element, payload_map) for xml_element in rlmi_document[rlmi.Resource, IterateItems]]\n        return cls(rlmi_document.uri, rlmi_document.version, rlmi_document.full_state, resources)\n\n\n"
  },
  {
    "path": "sipsimple/payloads/rlsservices.py",
    "content": "\n\"\"\"RFC4826 compliant parser/builder for application/rls-services+xml documents.\"\"\"\n\n\n__all__ = ['namespace',\n           'RLSServicesDocument',\n           'Packages',\n           'ResourceList',\n           'List',\n           'Service',\n           'RLSServices']\n\n\nfrom sipsimple.payloads import XMLListRootElement, XMLElement, XMLListElement, XMLStringElement, XMLAnyURIElement, XMLElementID, XMLElementChild, XMLElementChoiceChild\nfrom sipsimple.payloads import IterateIDs, IterateItems, All\nfrom sipsimple.payloads import resourcelists\nfrom sipsimple.payloads.datatypes import AnyURI\n\n\nnamespace = 'urn:ietf:params:xml:ns:rls-services'\n\n\nclass RLSServicesDocument(resourcelists.ResourceListsDocument):\n    content_type = 'application/rls-services+xml'\n\nRLSServicesDocument.register_namespace(namespace, prefix=None, schema='rlsservices.xsd')\n\n## Marker mixins\n\nclass PackagesElement(object): pass\n\n\n## Elements\n\nclass Package(XMLStringElement):\n    _xml_tag = 'package'\n    _xml_namespace = namespace\n    _xml_document = RLSServicesDocument\n\n\nclass Packages(XMLListElement):\n    _xml_tag = 'packages'\n    _xml_namespace = namespace\n    _xml_document = RLSServicesDocument\n    _xml_children_order = {Package.qname: 0}\n    _xml_item_type = (Package, PackagesElement)\n\n    def __init__(self, packages=[]):\n        XMLListElement.__init__(self)\n        self.update(packages)\n\n    def __iter__(self):\n        return (unicode(item) if type(item) is Package else item for item in super(Packages, self).__iter__())\n\n    def add(self, item):\n        if isinstance(item, basestring):\n            item = Package(item)\n        super(Packages, self).add(item)\n\n    def remove(self, item):\n        if isinstance(item, basestring):\n            package = Package(item)\n            try:\n                item = (entry for entry in super(Packages, self).__iter__() if entry == package).next()\n            except StopIteration:\n                raise KeyError(item)\n        super(Packages, self).remove(item)\n\n\nclass ResourceList(XMLAnyURIElement):\n    _xml_tag = 'resource-list'\n    _xml_namespace = namespace\n    _xml_document = RLSServicesDocument\n\n\n# This is identical to the list element in resourcelists, except for the\n# namespace. We'll redefine the xml tag just for readability purposes.\nclass List(resourcelists.List):\n    _xml_tag = 'list'\n    _xml_namespace = namespace\n    _xml_document = RLSServicesDocument\n\n\nclass Service(XMLElement):\n    _xml_tag = 'service'\n    _xml_namespace = namespace\n    _xml_document = RLSServicesDocument\n    _xml_children_order = {List.qname: 0,\n                           ResourceList.qname: 0,\n                           Packages.qname: 1}\n\n    uri = XMLElementID('uri', type=AnyURI, required=True, test_equal=True)\n    list = XMLElementChoiceChild('list', types=(ResourceList, List), required=True, test_equal=True)\n    packages = XMLElementChild('packages', type=Packages, required=False, test_equal=True)\n\n    def __init__(self, uri, list=None, packages=None):\n        XMLElement.__init__(self)\n        self.uri = uri\n        self.list = list if list is not None else List()\n        self.packages = packages if packages is not None else Packages()\n\n    def __repr__(self):\n        return '%s(%r, %r, %r)' % (self.__class__.__name__, self.uri, self.list, self.packages)\n\n\nclass RLSServices(XMLListRootElement):\n    _xml_tag = 'rls-services'\n    _xml_namespace = namespace\n    _xml_document = RLSServicesDocument\n    _xml_children_order = {Service.qname: 0}\n    _xml_item_type = Service\n\n    def __init__(self, services=[]):\n        XMLListRootElement.__init__(self)\n        self.update(services)\n\n    def __getitem__(self, key):\n        if key is IterateIDs:\n            return self._xmlid_map[Service].iterkeys()\n        elif key is IterateItems:\n            return self._xmlid_map[Service].itervalues()\n        else:\n            return self._xmlid_map[Service][key]\n\n    def __delitem__(self, key):\n        if key is All:\n            for item in self._xmlid_map[Service].values():\n                self.remove(item)\n        else:\n            self.remove(self._xmlid_map[Service][key])\n\n    def get(self, key, default=None):\n        return self._xmlid_map[Service].get(key, default)\n\n\n"
  },
  {
    "path": "sipsimple/payloads/rpid.py",
    "content": "\n\"\"\"\nRPID handling according to RFC4480\n\nThis module provides an extension to PIDF to support rich presence.\n\"\"\"\n\n\n__all__ = ['namespace',\n           'ActivityElement',\n           'MoodElement',\n           'PlaceTypeElement',\n           'PrivacyElement',\n           'RelationshipElement',\n           'ServiceClassElement',\n           'SphereElement',\n           'Note',\n           'Other',\n           'Activities',\n           'Mood',\n           'PlaceIs',\n           'AudioPlaceInformation',\n           'VideoPlaceInformation',\n           'TextPlaceInformation',\n           'PlaceType',\n           'AudioPrivacy',\n           'TextPrivacy',\n           'VideoPrivacy',\n           'Privacy',\n           'Relationship',\n           'ServiceClass',\n           'Sphere',\n           'StatusIcon',\n           'TimeOffset',\n           'UserInput',\n           'Class']\n\n\nfrom lxml import etree\n\nfrom sipsimple.payloads import ValidationError, XMLElementType, XMLEmptyElementRegistryType, XMLAttribute, XMLElementChild, XMLStringChoiceChild\nfrom sipsimple.payloads import XMLElement, XMLEmptyElement, XMLStringElement, XMLLocalizedStringElement, XMLStringListElement\nfrom sipsimple.payloads.pidf import PIDFDocument, ServiceExtension, PersonExtension, DeviceExtension, Note, NoteMap, NoteList, Service, Person, Device\nfrom sipsimple.payloads.datatypes import UnsignedLong, DateTime, ID\n\n\nnamespace = 'urn:ietf:params:xml:ns:pidf:rpid'\nPIDFDocument.register_namespace(namespace, prefix='rpid', schema='rpid.xsd')\n\n\n## Marker mixins\n\nclass ActivityElement(object): pass\nclass MoodElement(object): pass\nclass PlaceTypeElement(object): pass\nclass PrivacyElement(object): pass\nclass RelationshipElement(object): pass\nclass ServiceClassElement(object): pass\nclass SphereElement(object): pass\n\n\n## Attribute value types\n\nclass AudioPlaceValue(str):\n    def __new__(cls, value):\n        if value not in ('noisy', 'ok', 'quiet', 'unknown'):\n            raise ValueError(\"illegal value for audio place-is\")\n        return str.__new__(cls, value)\n\n\nclass VideoPlaceValue(str):\n    def __new__(cls, value):\n        if value not in ('toobright', 'ok', 'dark', 'unknown'):\n            raise ValueError(\"illegal value for video place-is\")\n        return str.__new__(cls, value)\n\n\nclass TextPlaceValue(str):\n    def __new__(cls, value):\n        if value not in ('uncomfortable', 'inappropriate', 'ok', 'unknown'):\n            raise ValueError(\"illegal value for text place-is\")\n        return str.__new__(cls, value)\n\n\nclass UserInputValue(str):\n    def __new__(cls, value):\n        if value not in ('active', 'idle'):\n            raise ValueError(\"illegal value for user-input\")\n        return str.__new__(cls, value)\n\n\n## Elements\n\nclass RPIDNote(XMLLocalizedStringElement):\n    _xml_tag = 'note'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    def __unicode__(self):\n        return Note(self.value, self.lang)\n\n    @classmethod\n    def from_string(cls, value):\n        if isinstance(value, Note):\n            return cls(value, value.lang)\n        elif isinstance(value, basestring):\n            return cls(value)\n        else:\n            raise ValueError(\"expected str/unicode instance, got %s instead\" % value.__class__.__name__)\n\n\nclass RPIDOther(XMLLocalizedStringElement):\n    _xml_tag = 'other'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    def __unicode__(self):\n        return Other(self.value, self.lang)\n\n    @classmethod\n    def from_string(cls, value):\n        if isinstance(value, Other):\n            return cls(value, value.lang)\n        elif isinstance(value, basestring):\n            return cls(value)\n        else:\n            raise ValueError(\"expected str/unicode instance, got %s instead\" % value.__class__.__name__)\n\n\nclass Other(Note): pass\n\n\nclass ActivityRegistry(object):\n    __metaclass__ = XMLEmptyElementRegistryType\n\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    names = ('appointment', 'away', 'breakfast', 'busy', 'dinner',\n             'holiday', 'in-transit', 'looking-for-work', 'meal', 'meeting',\n             'on-the-phone', 'performance', 'permanent-absence', 'playing',\n             'presentation', 'shopping', 'sleeping', 'spectator', 'steering',\n             'travel', 'tv', 'vacation', 'working', 'worship', 'unknown')\n\n\nclass Activities(XMLStringListElement, PersonExtension):\n    _xml_tag = 'activities'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_children_order = {RPIDNote.qname: 0}\n    _xml_item_registry = ActivityRegistry\n    _xml_item_other_type = RPIDOther\n    _xml_item_extension_type = ActivityElement\n\n    id = XMLAttribute('id', type=str, required=False, test_equal=True)\n    since = XMLAttribute('since', xmlname='from', type=DateTime, required=False, test_equal=True)\n    until = XMLAttribute('until', type=DateTime, required=False, test_equal=True)\n\n    _note_map = NoteMap()\n\n    def __init__(self, id=None, since=None, until=None, activities=[], notes=[]):\n        XMLElement.__init__(self)\n        self.id = id\n        self.since = since\n        self.until = until\n        self.update(activities)\n        self.notes.update(notes)\n\n    @property\n    def notes(self):\n        return NoteList(self, RPIDNote)\n\n    def __eq__(self, other):\n        if isinstance(other, Activities):\n            return super(Activities, self).__eq__(other) and self.notes == other.notes\n        else:\n            return NotImplemented\n\n    def __repr__(self):\n        return '%s(%r, %r, %r, %r, %r)' % (self.__class__.__name__, self.id, self.since, self.until, list(self), list(self.notes))\n\n    def _parse_element(self, element):\n        super(Activities, self)._parse_element(element)\n        self.notes._parse_element(element)\n\n    def _build_element(self):\n        super(Activities, self)._build_element()\n        self.notes._build_element()\n\n    def add(self, activity):\n        if isinstance(activity, basestring):\n            if activity in self._xml_item_registry.names:\n                activity = self._xml_item_registry.class_map[activity]()\n            else:\n                activity = self._xml_item_other_type.from_string(activity)\n        unknown_activity = self._xml_item_registry.class_map['unknown']()\n        if activity == unknown_activity or unknown_activity in self._element_map.itervalues():\n            self.clear()\n        super(Activities, self).add(activity)\n\n    def check_validity(self):\n        if not self:\n            raise ValidationError(\"Activity element must have at least one value\")\n        super(Activities, self).check_validity()\n\nPerson.register_extension('activities', type=Activities)\n\n\nclass MoodRegistry(object):\n    __metaclass__ = XMLEmptyElementRegistryType\n\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    names = ('afraid', 'amazed', 'angry', 'annoyed', 'anxious', 'ashamed',\n             'bored', 'brave', 'calm', 'cold', 'confused', 'contended',\n             'cranky', 'curious', 'depressed', 'disappointed', 'disgusted',\n             'distracted', 'embarrassed', 'excited', 'flirtatious',\n             'frustrated', 'grumpy', 'guilty', 'happy', 'hot', 'humbled',\n             'humiliated', 'hungry', 'hurt', 'impressed', 'in_awe', 'in_love',\n             'indignant', 'interested', 'invisible', 'jealous', 'lonely',\n             'mean', 'moody', 'nervous', 'neutral', 'offended', 'playful',\n             'proud', 'relieved', 'remorseful', 'restless', 'sad',\n             'sarcastic', 'serious', 'shocked', 'shy', 'sick', 'sleepy',\n             'stressed', 'surprised', 'thirsty', 'worried', 'unknown')\n\n\nclass Mood(XMLStringListElement, PersonExtension):\n    _xml_tag = 'mood'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_extension_type = MoodElement\n    _xml_children_order = {RPIDNote.qname: 0}\n    _xml_item_registry = MoodRegistry\n    _xml_item_other_type = RPIDOther\n    _xml_item_extension_type = MoodElement\n\n    id = XMLAttribute('id', type=str, required=False, test_equal=True)\n    since = XMLAttribute('since', xmlname='from', type=DateTime, required=False, test_equal=True)\n    until = XMLAttribute('until', type=DateTime, required=False, test_equal=True)\n\n    _note_map = NoteMap()\n\n    def __init__(self, id=None, since=None, until=None, moods=[], notes=[]):\n        XMLElement.__init__(self)\n        self.id = id\n        self.since = since\n        self.until = until\n        self.update(moods)\n        self.notes.update(notes)\n\n    @property\n    def notes(self):\n        return NoteList(self, RPIDNote)\n\n    def __eq__(self, other):\n        if isinstance(other, Mood):\n            return super(Mood, self).__eq__(other) and self.notes == other.notes\n        else:\n            return NotImplemented\n\n    def __repr__(self):\n        return '%s(%r, %r, %r, %r, %r)' % (self.__class__.__name__, self.id, self.since, self.until, list(self), list(self.notes))\n\n    def _parse_element(self, element):\n        super(Mood, self)._parse_element(element)\n        self.notes._parse_element(element)\n\n    def _build_element(self):\n        super(Mood, self)._build_element()\n        self.notes._build_element()\n\n    def add(self, mood):\n        if isinstance(mood, basestring):\n            if mood in self._xml_item_registry.names:\n                mood = self._xml_item_registry.class_map[mood]()\n            else:\n                mood = self._xml_item_other_type.from_string(mood)\n        unknown_mood = self._xml_item_registry.class_map['unknown']()\n        if mood == unknown_mood or unknown_mood in self._element_map.itervalues():\n            self.clear()\n        super(Mood, self).add(mood)\n\n    def check_validity(self):\n        if not self:\n            raise ValidationError(\"Mood element must have at least one value\")\n        super(Mood, self).check_validity()\n\nPerson.register_extension('mood', type=Mood)\n\n\nclass AudioPlaceInformation(XMLStringElement):\n    _xml_tag = 'audio'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_value_type = AudioPlaceValue\n\n\nclass VideoPlaceInformation(XMLStringElement):\n    _xml_tag = 'video'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_value_type = VideoPlaceValue\n\n\nclass TextPlaceInformation(XMLStringElement):\n    _xml_tag = 'text'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_value_type = TextPlaceValue\n\n\nclass PlaceIs(XMLElement, PersonExtension):\n    _xml_tag = 'place-is'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_children_order = {RPIDNote.qname: 0,\n                           AudioPlaceInformation.qname: 1,\n                           VideoPlaceInformation.qname: 2,\n                           TextPlaceInformation.qname: 3}\n\n    id = XMLAttribute('id', type=str, required=False, test_equal=True)\n    since = XMLAttribute('since', xmlname='from', type=DateTime, required=False, test_equal=True)\n    until = XMLAttribute('until', type=DateTime, required=False, test_equal=True)\n    audio = XMLElementChild('audio', type=AudioPlaceInformation, required=False, test_equal=True)\n    video = XMLElementChild('video', type=VideoPlaceInformation, required=False, test_equal=True)\n    text = XMLElementChild('text', type=TextPlaceInformation, required=False, test_equal=True)\n\n    _note_map = NoteMap()\n\n    def __init__(self, id=None, since=None, until=None, audio=None, video=None, text=None, notes=[]):\n        XMLElement.__init__(self)\n        self.id = id\n        self.since = since\n        self.until = until\n        self.audio = audio\n        self.video = video\n        self.text = text\n        self.notes.update(notes)\n\n    @property\n    def notes(self):\n        return NoteList(self, RPIDNote)\n\n    def __eq__(self, other):\n        if isinstance(other, PlaceIs):\n            return super(PlaceIs, self).__eq__(other) and self.notes == other.notes\n        else:\n            return NotImplemented\n\n    def __repr__(self):\n        return '%s(%r, %r, %r, %r, %r, %r, %r)' % (self.__class__.__name__, self.id, self.since, self.until, self.audio, self.video, self.text, list(self.notes))\n\n    def _parse_element(self, element):\n        self.notes._parse_element(element)\n\n    def _build_element(self):\n        self.notes._build_element()\n\nPerson.register_extension('place_is', type=PlaceIs)\n\n\nclass PlaceType(XMLElement, PersonExtension):\n    _xml_tag = 'place-type'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_children_order = {RPIDNote.qname: 0}\n\n    id = XMLAttribute('id', type=str, required=False, test_equal=True)\n    since = XMLAttribute('since', xmlname='from', type=DateTime, required=False, test_equal=True)\n    until = XMLAttribute('until', type=DateTime, required=False, test_equal=True)\n    value = XMLStringChoiceChild('value', other_type=RPIDOther, extension_type=PlaceTypeElement)\n\n    _note_map = NoteMap()\n\n    def __init__(self, id=None, since=None, until=None, placetype=None, notes=[]):\n        super(PlaceType, self).__init__()\n        self.id = id\n        self.since = since\n        self.until = until\n        self.value = placetype\n        self.notes.update(notes)\n\n    @property\n    def notes(self):\n        return NoteList(self, RPIDNote)\n\n    def __eq__(self, other):\n        if isinstance(other, PlaceType):\n            return super(PlaceType, self).__eq__(other) and self.notes == other.notes\n        else:\n            return NotImplemented\n\n    def __repr__(self):\n        return '%s(%r, %r, %r, %r, %r)' % (self.__class__.__name__, self.id, self.since, self.until, self.value, list(self.notes))\n\n    def _parse_element(self, element):\n        self.notes._parse_element(element)\n\n    def _build_element(self):\n        self.notes._build_element()\n\nPerson.register_extension('place_type', type=PlaceType)\n\n\nclass AudioPrivacy(XMLEmptyElement):\n    _xml_tag = 'audio'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    def __init__(self, private=True):\n        XMLEmptyElement.__init__(self)\n\n    def __new__(cls, private=True):\n        if not private:\n            return None\n        return XMLEmptyElement.__new__(cls)\n\n\nclass TextPrivacy(XMLEmptyElement):\n    _xml_tag = 'text'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    def __init__(self, private=True):\n        XMLEmptyElement.__init__(self)\n\n    def __new__(cls, private=True):\n        if not private:\n            return None\n        return XMLEmptyElement.__new__(cls)\n\n\nclass VideoPrivacy(XMLEmptyElement):\n    _xml_tag = 'video'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    def __init__(self, private=True):\n        XMLEmptyElement.__init__(self)\n\n    def __new__(cls, private=True):\n        if not private:\n            return None\n        return XMLEmptyElement.__new__(cls)\n\n\nclass PrivacyType(XMLElementType):\n    def __init__(cls, name, bases, dct):\n        super(PrivacyType, cls).__init__(name, bases, dct)\n        child_attributes = (getattr(cls, name) for name in dir(cls) if type(getattr(cls, name)) is XMLElementChild)\n        cls._privacy_attributes = tuple(attr.name for attr in child_attributes if attr.name in ('audio', 'text', 'video') or issubclass(attr.type, PrivacyElement))\n\nclass Privacy(XMLElement, PersonExtension):\n    __metaclass__ = PrivacyType\n\n    _xml_tag = 'privacy'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_children_order = {RPIDNote.qname: 0,\n                           AudioPrivacy.qname: 1,\n                           TextPrivacy.qname: 2,\n                           VideoPrivacy.qname: 3}\n\n    id = XMLAttribute('id', type=str, required=False, test_equal=True)\n    since = XMLAttribute('since', xmlname='from', type=DateTime, required=False, test_equal=True)\n    until = XMLAttribute('until', type=DateTime, required=False, test_equal=True)\n\n    audio = XMLElementChild('audio', type=AudioPrivacy, required=False, test_equal=True)\n    text = XMLElementChild('text', type=TextPrivacy, required=False, test_equal=True)\n    video = XMLElementChild('video', type=VideoPrivacy, required=False, test_equal=True)\n    unknown = property(lambda self: all(getattr(self, name) is None for name in self._privacy_attributes))\n\n    _note_map = NoteMap()\n\n    def __init__(self, id=None, since=None, until=None, notes=[], audio=False, text=False, video=False):\n        super(Privacy, self).__init__()\n        self.id = id\n        self.since = since\n        self.until = until\n        self.audio = audio\n        self.text = text\n        self.video = video\n        self.notes.update(notes)\n\n    @property\n    def notes(self):\n        return NoteList(self, RPIDNote)\n\n    def __eq__(self, other):\n        if isinstance(other, Privacy):\n            return super(Privacy, self).__eq__(other) and self.notes == other.notes\n        else:\n            return NotImplemented\n\n    def __repr__(self):\n        return '%s(%r, %r, %r, %r, %r, %r, %r)' % (self.__class__.__name__, self.id, self.since, self.until, list(self.notes), self.audio, self.text, self.video)\n\n    def _parse_element(self, element):\n        self.notes._parse_element(element)\n\n    def _build_element(self):\n        if self.unknown:\n            if self.element.find('{%s}unknown' % self._xml_namespace) is None:\n                etree.SubElement(self.element, '{%s}unknown' % self._xml_namespace, nsmap=self._xml_document.nsmap)\n        else:\n            unknown_element = self.element.find('{%s}unknown' % self._xml_namespace)\n            if unknown_element is not None:\n                self.element.remove(unknown_element)\n        self.notes._build_element()\n\nPerson.register_extension('privacy', type=Privacy)\n\n\nclass RelationshipRegistry(object):\n    __metaclass__ = XMLEmptyElementRegistryType\n\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    names = ('assistant', 'associate', 'family', 'friend', 'self', 'supervisor', 'unknown')\n\n\nclass Relationship(XMLElement, ServiceExtension):\n    _xml_tag = 'relationship'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_children_order = {RPIDNote: 0}\n\n    value = XMLStringChoiceChild('value', registry=RelationshipRegistry, other_type=RPIDOther, extension_type=RelationshipElement)\n\n    _note_map = NoteMap()\n\n    def __init__(self, relationship='self', notes=[]):\n        XMLElement.__init__(self)\n        self.value = relationship\n        self.notes.update(notes)\n\n    @property\n    def notes(self):\n        return NoteList(self, RPIDNote)\n\n    def __eq__(self, other):\n        if isinstance(other, Relationship):\n            return super(Relationship, self).__eq__(other) and self.notes == other.notes\n        else:\n            return NotImplemented\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.value, list(self.notes))\n\n    def _parse_element(self, element):\n        self.notes._parse_element(element)\n\n    def _build_element(self):\n        self.notes._build_element()\n\nService.register_extension('relationship', type=Relationship)\n\n\nclass ServiceClassRegistry(object):\n    __metaclass__ = XMLEmptyElementRegistryType\n\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    names = ('courier', 'electronic', 'freight', 'in-person', 'postal', 'unknown')\n\n\nclass ServiceClass(XMLElement, ServiceExtension):\n    _xml_tag = 'service-class'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    value = XMLStringChoiceChild('value', registry=ServiceClassRegistry, extension_type=ServiceClassElement)\n\n    _note_map = NoteMap()\n\n    def __init__(self, service_class=None, notes=[]):\n        XMLElement.__init__(self)\n        self.value = service_class\n        self.notes.update(notes)\n\n    @property\n    def notes(self):\n        return NoteList(self, RPIDNote)\n\n    def __eq__(self, other):\n        if isinstance(other, ServiceClass):\n            return super(ServiceClass, self).__eq__(other) and self.notes == other.notes\n        else:\n            return NotImplemented\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.value, list(self.notes))\n\n    def _parse_element(self, element):\n        self.notes._parse_element(element)\n\n    def _build_element(self):\n        self.notes._build_element()\n\nService.register_extension('service_class', type=ServiceClass)\n\n\nclass SphereRegistry(object):\n    __metaclass__ = XMLEmptyElementRegistryType\n\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    names = ('home', 'work', 'unknown')\n\n\nclass Sphere(XMLElement, PersonExtension):\n    _xml_tag = 'sphere'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    id = XMLAttribute('id', type=ID, required=False, test_equal=True)\n    since = XMLAttribute('since', xmlname='from', type=DateTime, required=False, test_equal=True)\n    until = XMLAttribute('until', type=DateTime, required=False, test_equal=True)\n    value = XMLStringChoiceChild('value', registry=SphereRegistry, extension_type=SphereElement)\n\n    def __init__(self, value=None, id=None, since=None, until=None):\n        XMLElement.__init__(self)\n        self.id = id\n        self.since = since\n        self.until = until\n        self.value = value\n\n    def __repr__(self):\n        return '%s(%r, %r, %r, %r)' % (self.__class__.__name__, self.value, self.id, self.since, self.until)\n\nPerson.register_extension('sphere', type=Sphere)\n\n\nclass StatusIcon(XMLStringElement, ServiceExtension, PersonExtension):\n    _xml_tag = 'status-icon'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    id = XMLAttribute('id', type=str, required=False, test_equal=True)\n    since = XMLAttribute('since', xmlname='from', type=DateTime, required=False, test_equal=True)\n    until = XMLAttribute('until', type=DateTime, required=False, test_equal=True)\n\n    def __init__(self, value=None, id=None, since=None, until=None):\n        XMLStringElement.__init__(self, value)\n        self.id = id\n        self.since = since\n        self.until = until\n\nPerson.register_extension('status_icon', type=StatusIcon)\nService.register_extension('status_icon', type=StatusIcon)\n\n\nclass TimeOffset(XMLStringElement, PersonExtension):\n    _xml_tag = 'time-offset'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\n    id = XMLAttribute('id', type=str, required=False, test_equal=True)\n    since = XMLAttribute('since', xmlname='from', type=DateTime, required=False, test_equal=True)\n    until = XMLAttribute('until', type=DateTime, required=False, test_equal=True)\n    description = XMLAttribute('description', type=str, required=False, test_equal=True)\n\n    def __init__(self, value=None, id=None, since=None, until=None, description=None):\n        if value is None:\n            value = DateTime.now().utcoffset().seconds / 60\n        XMLStringElement.__init__(self, str(value))\n        self.id = id\n        self.since = since\n        self.until = until\n        self.description = description\n\n    def __int__(self):\n        return int(self.value)\n\nPerson.register_extension('time_offset', type=TimeOffset)\n\n\nclass UserInput(XMLStringElement, ServiceExtension, PersonExtension, DeviceExtension):\n    _xml_tag = 'user-input'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n    _xml_value_type = UserInputValue\n\n    id = XMLAttribute('id', type=str, required=False, test_equal=True)\n    last_input = XMLAttribute('last_input', xmlname='last-input', type=DateTime, required=False, test_equal=True)\n    idle_threshold = XMLAttribute('idle_threshold', xmlname='idle-threshold', type=UnsignedLong, required=False, test_equal=True)\n\n    def __init__(self, value='active', id=None, last_input=None, idle_threshold=None):\n        XMLStringElement.__init__(self, value)\n        self.id = id\n        self.last_input = last_input\n        self.idle_threshold = idle_threshold\n\nService.register_extension('user_input', type=UserInput)\nPerson.register_extension('user_input', type=UserInput)\nDevice.register_extension('user_input', type=UserInput)\n\n\nclass Class(XMLStringElement, ServiceExtension, PersonExtension, DeviceExtension):\n    _xml_tag = 'class'\n    _xml_namespace = namespace\n    _xml_document = PIDFDocument\n\nService.register_extension('rpid_class', type=Class)\nPerson.register_extension('rpid_class', type=Class)\nDevice.register_extension('rpid_class', type=Class)\n\n\n"
  },
  {
    "path": "sipsimple/payloads/watcherinfo.py",
    "content": "\n\"\"\"Parses application/watcherinfo+xml documents according to RFC3857 and RFC3858.\"\"\"\n\n\n__all__ = ['namespace',\n           'NeedFullUpdateError',\n           'WatcherInfoDocument',\n           'Watcher',\n           'WatcherList',\n           'WatcherInfo']\n\n\nfrom sipsimple.payloads import XMLDocument, XMLAnyURIElement, XMLListElement, XMLListRootElement, XMLElementID, XMLAttribute\nfrom sipsimple.payloads import IterateIDs, IterateItems, All\nfrom sipsimple.payloads.datatypes import NonNegativeInteger, UnsignedLong, SIPURI\n\n\nnamespace = 'urn:ietf:params:xml:ns:watcherinfo'\n\n\nclass NeedFullUpdateError(Exception): pass\n\n\nclass WatcherInfoDocument(XMLDocument):\n    content_type = 'application/watcherinfo+xml'\n\nWatcherInfoDocument.register_namespace(namespace, prefix=None, schema='watcherinfo.xsd')\n\n\n## Attribute value types\n\nclass WatcherStatus(str):\n    def __new__(cls, value):\n        if value not in ('pending', 'active', 'waiting', 'terminated'):\n            raise ValueError('illegal status value for watcher')\n        return str.__new__(cls, value)\n\n\nclass WatcherEvent(str):\n    def __new__(cls, value):\n        if value not in ('subscribe', 'approved', 'deactivated', 'probation', 'rejected', 'timeout', 'giveup', 'noresource'):\n            raise ValueError('illegal event value for watcher')\n        return str.__new__(cls, value)\n\n\nclass WatcherInfoState(str):\n    def __new__(cls, value):\n        if value not in ('full', 'partial'):\n            raise ValueError('illegal state value for watcherinfo')\n        return str.__new__(cls, value)\n\n\n## XMLElements\n\nclass Watcher(XMLAnyURIElement):\n    \"\"\"\n    Definition for a watcher in a watcherinfo document\n\n    Provides the attributes:\n     * id\n     * status\n     * event\n     * display_name\n     * expiration\n     * duration\n     * sipuri\n\n    Can be transformed to a string with the format DISPLAY_NAME <SIP_URI>.\n    \"\"\"\n\n    _xml_tag = 'watcher'\n    _xml_namespace = namespace\n    _xml_document = WatcherInfoDocument\n    _xml_value_type = SIPURI\n\n    id           = XMLElementID('id', type=str, required=True, test_equal=True)\n    status       = XMLAttribute('status', type=WatcherStatus, required=True, test_equal=True)\n    event        = XMLAttribute('event', type=WatcherEvent, required=True, test_equal=True)\n    display_name = XMLAttribute('display_name', xmlname='display-name', type=str, required=False, test_equal=True)\n    expiration   = XMLAttribute('expiration', type=UnsignedLong, required=False, test_equal=False)\n    duration     = XMLAttribute('duration', xmlname='duration-subscribed', type=UnsignedLong, required=False, test_equal=False)\n\n    sipuri = XMLAnyURIElement.value\n\n    def __init__(self, sipuri, id, status, event, display_name=None, expiration=None, duration=None):\n        XMLAnyURIElement.__init__(self)\n        self.sipuri = sipuri\n        self.id = id\n        self.status = status\n        self.event = event\n        self.display_name = display_name\n        self.expiration = expiration\n        self.duration = duration\n\n    def __repr__(self):\n        return '%s(%r, %r, %r, %r, %r, %r, %r)' % (self.__class__.__name__, self.sipuri, self.id, self.status, self.event, self.display_name, self.expiration, self.duration)\n\n    def __str__(self):\n        return '\"%s\" <%s>' % (self.display_name, self.sipuri) if self.display_name else self.sipuri\n\n\nclass WatcherList(XMLListElement):\n    \"\"\"\n    Definition for a list of watchers in a watcherinfo document\n    \n    It behaves like a list in that it can be indexed by a number, can be\n    iterated and counted.\n\n    It also provides the properties pending, active and terminated which are\n    generators returning Watcher objects with the corresponding status.\n    \"\"\"\n\n    _xml_tag = 'watcher-list'\n    _xml_namespace = namespace\n    _xml_document = WatcherInfoDocument\n    _xml_children_order = {Watcher.qname: 0}\n    _xml_item_type = Watcher\n\n    resource = XMLElementID('resource', type=SIPURI, required=True, test_equal=True)\n    package  = XMLAttribute('package', type=str, required=True, test_equal=True)\n\n    def __init__(self, resource, package, watchers=[]):\n        XMLListElement.__init__(self)\n        self.resource = resource\n        self.package = package\n        self.update(watchers)\n\n    def __repr__(self):\n        return '%s(%r, %r, %r)' % (self.__class__.__name__, self.resource, self.package, list(self))\n\n    def __getitem__(self, key):\n        if key is IterateIDs:\n            return self._xmlid_map[Watcher].iterkeys()\n        elif key is IterateItems:\n            return self._xmlid_map[Watcher].itervalues()\n        else:\n            return self._xmlid_map[Watcher][key]\n\n    def __delitem__(self, key):\n        if key is All:\n            for item in self._xmlid_map[Watcher].values():\n                self.remove(item)\n        else:\n            self.remove(self._xmlid_map[Watcher][key])\n\n    def get(self, key, default=None):\n        return self._xmlid_map[Watcher].get(key, default)\n\n    pending = property(lambda self: (watcher for watcher in self if watcher.status == 'pending'))\n    waiting = property(lambda self: (watcher for watcher in self if watcher.status == 'waiting'))\n    active = property(lambda self: (watcher for watcher in self if watcher.status == 'active'))\n    terminated = property(lambda self: (watcher for watcher in self if watcher.status == 'terminated'))\n\n\nclass WatcherInfo(XMLListRootElement):\n    \"\"\"\n    Definition for watcher info: a list of WatcherList elements\n    \n    The user agent instantiates this class once it subscribes to a *.winfo event\n    and calls its update() method with the application/watcherinfo+xml documents\n    it receives via NOTIFY.\n\n    The watchers can be accessed in two ways:\n     1. via the wlists property, which returns a list of WatcherList elements;\n     2. via the pending, active and terminated properties, which return\n     dictionaries, mapping WatcherList objects to lists of Watcher objects.\n     Since WatcherList objects can be compared for equality to SIP URI strings,\n     representing the presentity to which the watchers have subscribed, the\n     dictionaries can also be indexed by such strings.\n    \"\"\"\n\n    _xml_tag = 'watcherinfo'\n    _xml_namespace = namespace\n    _xml_document = WatcherInfoDocument\n    _xml_children_order = {WatcherList.qname: 0}\n    _xml_item_type = WatcherList\n\n    version = XMLAttribute('version', type=NonNegativeInteger, required=True, test_equal=True)\n    state   = XMLAttribute('state', type=WatcherInfoState, required=True, test_equal=True)\n\n    def __init__(self, version=0, state='full', wlists=[]):\n        XMLListRootElement.__init__(self)\n        self.version = version\n        self.state = state\n        self.update(wlists)\n\n    def __repr__(self):\n        return '%s(%r, %r, %r)' % (self.__class__.__name__, self.version, self.state, list(self))\n\n    def __getitem__(self, key):\n        if key is IterateIDs:\n            return self._xmlid_map[WatcherList].iterkeys()\n        elif key is IterateItems:\n            return self._xmlid_map[WatcherList].itervalues()\n        else:\n            return self._xmlid_map[WatcherList][key]\n\n    def __delitem__(self, key):\n        if key is All:\n            for item in self._xmlid_map[WatcherList].values():\n                self.remove(item)\n        else:\n            self.remove(self._xmlid_map[WatcherList][key])\n\n    def get(self, key, default=None):\n        return self._xmlid_map[WatcherList].get(key, default)\n\n    wlists = property(lambda self: self._element_map.values())\n    pending = property(lambda self: dict((wlist, list(wlist.pending)) for wlist in self._element_map.itervalues()))\n    waiting = property(lambda self: dict((wlist, list(wlist.waiting)) for wlist in self._element_map.itervalues()))\n    active = property(lambda self: dict((wlist, list(wlist.active)) for wlist in self._element_map.itervalues()))\n    terminated = property(lambda self: dict((wlist, list(wlist.terminated)) for wlist in self._element_map.itervalues()))\n\n\n"
  },
  {
    "path": "sipsimple/payloads/xcapcaps.py",
    "content": "\n\"\"\"Support for parsing and building xcap-caps documents, as defined by RFC4825.\"\"\"\n\n\n__all__ = ['XCAPCapabilitiesDocument', 'AUIDS', 'Extensions', 'Namespaces', 'XCAPCapabilities']\n\n\nfrom sipsimple.payloads import XMLDocument, XMLElementChild, XMLListElement, XMLRootElement, XMLStringElement\n\n\nnamespace = 'urn:ietf:params:xml:ns:xcap-caps'\n\n\nclass XCAPCapabilitiesDocument(XMLDocument):\n    content_type = 'application/xcap-caps+xml'\n\nXCAPCapabilitiesDocument.register_namespace(namespace, prefix=None, schema='xcap-caps.xsd')\n\n\n## Elements\n\nclass AUID(XMLStringElement):\n    _xml_tag = 'auid'\n    _xml_namespace = namespace\n    _xml_document = XCAPCapabilitiesDocument\n\n\nclass AUIDS(XMLListElement):\n    _xml_tag = 'auids'\n    _xml_namespace = namespace\n    _xml_document = XCAPCapabilitiesDocument\n    _xml_item_type = AUID\n\n    def __init__(self, children=[]):\n        XMLListElement.__init__(self)\n        self.update(children)\n\n    def __iter__(self):\n        return (unicode(item) for item in super(AUIDS, self).__iter__())\n\n    def add(self, item):\n        if isinstance(item, basestring):\n            item = AUID(item)\n        super(AUIDS, self).add(item)\n\n    def remove(self, item):\n        if isinstance(item, basestring):\n            try:\n                item = (entry for entry in super(AUIDS, self).__iter__() if entry == item).next()\n            except StopIteration:\n                raise KeyError(item)\n        super(AUIDS, self).remove(item)\n\n\nclass Extension(XMLStringElement):\n    _xml_tag = 'extension'\n    _xml_namespace = namespace\n    _xml_document = XCAPCapabilitiesDocument\n\n\nclass Extensions(XMLListElement):\n    _xml_tag = 'extensions'\n    _xml_namespace = namespace\n    _xml_document = XCAPCapabilitiesDocument\n    _xml_item_type = Extension\n\n    def __init__(self, children=[]):\n        XMLListElement.__init__(self)\n        self.update(children)\n\n    def __iter__(self):\n        return (unicode(item) for item in super(Extensions, self).__iter__())\n\n    def add(self, item):\n        if isinstance(item, basestring):\n            item = Extension(item)\n        super(Extensions, self).add(item)\n\n    def remove(self, item):\n        if isinstance(item, basestring):\n            try:\n                item = (entry for entry in super(Extensions, self).__iter__() if entry == item).next()\n            except StopIteration:\n                raise KeyError(item)\n        super(Extensions, self).remove(item)\n\n\nclass Namespace(XMLStringElement):\n    _xml_tag = 'extension'\n    _xml_namespace = namespace\n    _xml_document = XCAPCapabilitiesDocument\n\n\nclass Namespaces(XMLListElement):\n    _xml_tag = 'namespaces'\n    _xml_namespace = namespace\n    _xml_document = XCAPCapabilitiesDocument\n    _xml_item_type = Namespace\n\n    def __init__(self, children=[]):\n        XMLListElement.__init__(self)\n        self.update(children)\n\n    def __iter__(self):\n        return (unicode(item) for item in super(Namespaces, self).__iter__())\n\n    def add(self, item):\n        if isinstance(item, basestring):\n            item = Namespace(item)\n        super(Namespaces, self).add(item)\n\n    def remove(self, item):\n        if isinstance(item, basestring):\n            try:\n                item = (entry for entry in super(Namespaces, self).__iter__() if entry == item).next()\n            except StopIteration:\n                raise KeyError(item)\n        super(Namespaces, self).remove(item)\n\n\nclass XCAPCapabilities(XMLRootElement):\n    _xml_tag = 'xcap-caps'\n    _xml_namespace = namespace\n    _xml_document = XCAPCapabilitiesDocument\n    _xml_children_order = {AUIDS.qname: 0,\n                           Extensions.qname: 1,\n                           Namespaces.qname: 2}\n\n    auids = XMLElementChild('auids', type=AUIDS, required=True, test_equal=True)\n    extensions = XMLElementChild('extensions', type=Extensions, required=False, test_equal=True)\n    namespaces = XMLElementChild('namespaces', type=Namespaces, required=True, test_equal=True)\n\n    def __init__(self, auids=[], extensions=[], namespaces=[]):\n        XMLRootElement.__init__(self)\n        self.auids = AUIDS(auids)\n        self.extensions = Extensions(extensions)\n        self.namespaces = Namespaces(namespaces)\n\n    def __repr__(self):\n        return '%s(%r, %r, %r)' % (self.__class__.__name__, self.auids, self.extensions, self.namespaces)\n\n\n\n"
  },
  {
    "path": "sipsimple/payloads/xcapdiff.py",
    "content": "\n\"\"\"\nThis module allows parsing and building xcap-diff documents according to\nRFC 5874.\n\"\"\"\n\n\n__all__ = ['namespace', 'XCAPDiffDocument', 'BodyNotChanged', 'Document', 'Element', 'Attribute', 'XCAPDiff']\n\n\nfrom sipsimple.payloads import XMLDocument, XMLElement, XMLListRootElement, XMLStringElement, XMLEmptyElement, XMLAttribute, XMLElementID, XMLElementChild\nfrom sipsimple.payloads.datatypes import Boolean, XCAPURI\n\n\nnamespace = 'urn:ietf:params:xml:ns:xcap-diff'\n\n\nclass XCAPDiffDocument(XMLDocument):\n    content_type = 'application/xcap-diff+xml'\n\nXCAPDiffDocument.register_namespace(namespace, prefix=None, schema='xcapdiff.xsd')\n\n\nclass BodyNotChanged(XMLEmptyElement):\n    _xml_tag = 'body-not-changed'\n    _xml_namespace = namespace\n    _xml_document = XCAPDiffDocument\n\n\nclass Document(XMLElement):\n    _xml_tag = 'document'\n    _xml_namespace = namespace\n    _xml_document = XCAPDiffDocument\n\n    selector = XMLElementID('selector', xmlname='sel', type=XCAPURI, required=True, test_equal=True)\n    new_etag = XMLAttribute('new_etag', xmlname='new-etag', type=str, required=False, test_equal=True)\n    previous_etag = XMLAttribute('previous_etag', xmlname='previous-etag', type=str, required=False, test_equal=True)\n    body_not_changed = XMLElementChild('body_not_changed', type=BodyNotChanged, required=False, test_equal=True)\n\n    def __init__(self, selector, new_etag=None, previous_etag=None):\n        XMLElement.__init__(self)\n        self.selector = selector\n        self.new_etag = new_etag\n        self.previous_etag = previous_etag\n\n    def __repr__(self):\n        return '%s(%r, %r, %r)' % (self.__class__.__name__, self.selector, self.new_etag, self.previous_etag)\n\n    @property\n    def empty_body(self):\n        return self.body_not_changed is not None\n\n    @empty_body.setter\n    def empty_body(self, body_not_changed):\n        if body_not_changed:\n            self.body_not_changed = BodyNotChanged()\n        else:\n            self.body_not_changed = None\n\n\nclass Element(XMLElement):\n    _xml_tag = 'element'\n    _xml_namespace = namespace\n    _xml_document = XCAPDiffDocument\n\n    selector = XMLElementID('selector', xmlname='sel', type=XCAPURI, required=True, test_equal=True)\n    exists = XMLAttribute('exists', type=Boolean, required=False, test_equal=True)\n\n    def __init__(self, selector, exists=None):\n        XMLElement.__init__(self)\n        self.selector = selector\n        self.exists = exists\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.selector, self.exists)\n\n\nclass Attribute(XMLStringElement):\n    _xml_tag = 'attribute'\n    _xml_namespace = namespace\n    _xml_document = XCAPDiffDocument\n\n    selector = XMLElementID('selector', xmlname='sel', type=XCAPURI, required=True, test_equal=True)\n    exists = XMLAttribute('exists', type=Boolean, required=False, test_equal=True)\n\n    def __init__(self, selector, exists=None):\n        XMLStringElement.__init__(self)\n        self.selector = selector\n        self.exists = exists\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.selector, self.exists)\n\n\nclass XCAPDiff(XMLListRootElement):\n    _xml_tag = 'xcap-diff'\n    _xml_namespace = namespace\n    _xml_document = XCAPDiffDocument\n    _xml_item_type = (Document, Element, Attribute)\n\n    xcap_root = XMLElementID('xcap_root', xmlname='xcap-root', type=str, required=True, test_equal=True)\n\n    def __init__(self, xcap_root, children=[]):\n        XMLListRootElement.__init__(self)\n        self.xcap_root = xcap_root\n        self.update(children)\n\n    def __repr__(self):\n        return '%s(%r, %r)' % (self.__class__.__name__, self.xcap_root, list(self))\n\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/addressbook.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:ag-projects:xml:ns:addressbook\"\n    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns=\"urn:ag-projects:xml:ns:addressbook\"\n    elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n\n   <xs:complexType name=\"Group\">\n    <xs:sequence>\n     <xs:element name=\"name\" type=\"xs:string\"/>\n     <xs:element name=\"contacts\" type=\"ContactList\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"id\" type=\"xs:ID\" use=\"required\"/>\n   </xs:complexType>\n\n   <xs:complexType name=\"ContactList\">\n    <xs:sequence>\n     <xs:element name=\"contact_id\" type=\"xs:string\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n   </xs:complexType>\n\n   <xs:complexType name=\"Contact\">\n    <xs:sequence>\n     <xs:element name=\"name\" type=\"xs:string\"/>\n     <xs:element name=\"uris\" type=\"ContactURIList\"/>\n     <xs:element name=\"dialog\" type=\"DialogHandling\"/>\n     <xs:element name=\"presence\" type=\"PresenceHandling\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"id\" type=\"xs:ID\" use=\"required\"/>\n   </xs:complexType>\n\n   <xs:complexType name=\"ContactURIList\">\n    <xs:sequence>\n     <xs:element name=\"uri\" type=\"ContactURI\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"default\" type=\"xs:string\"/>\n   </xs:complexType>\n\n   <xs:complexType name=\"ContactURI\">\n    <xs:sequence>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"id\"   type=\"xs:ID\"     use=\"required\"/>\n    <xs:attribute name=\"uri\"  type=\"xs:anyURI\" use=\"required\"/>\n    <xs:attribute name=\"type\" type=\"xs:string\"/>\n   </xs:complexType>\n\n   <xs:complexType name=\"DialogHandling\">\n    <xs:sequence>\n     <xs:element name=\"policy\" type=\"PolicyString\"/>\n     <xs:element name=\"subscribe\" type=\"xs:boolean\"/>\n    </xs:sequence>\n   </xs:complexType>\n\n   <xs:complexType name=\"PresenceHandling\">\n    <xs:sequence>\n     <xs:element name=\"policy\" type=\"PolicyString\"/>\n     <xs:element name=\"subscribe\" type=\"xs:boolean\"/>\n    </xs:sequence>\n   </xs:complexType>\n\n   <xs:simpleType name=\"PolicyString\">\n    <xs:restriction base=\"xs:string\">\n     <xs:enumeration value=\"allow\"/>\n     <xs:enumeration value=\"block\"/>\n     <xs:enumeration value=\"default\"/>\n    </xs:restriction>\n   </xs:simpleType>\n\n   <xs:complexType name=\"Policy\">\n    <xs:sequence>\n     <xs:element name=\"name\" type=\"xs:string\"/>\n     <xs:element name=\"dialog\" type=\"DialogHandling\"/>\n     <xs:element name=\"presence\" type=\"PresenceHandling\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"id\"  type=\"xs:ID\"     use=\"required\"/>\n    <xs:attribute name=\"uri\" type=\"xs:anyURI\" use=\"required\"/>\n   </xs:complexType>\n\n</xs:schema>\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/caps.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema xmlns:tns=\"urn:ietf:params:xml:ns:pidf:caps\"\n  xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"urn:ietf:params:xml:ns:pidf:caps\"\n  elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n\n  <!-- This import brings in the XML language attribute xml:lang-->\n\n  <xs:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n\n  <!-- ROOT -->\n  <xs:element name=\"servcaps\" type=\"tns:servcapstype\"/>\n  <xs:complexType name=\"servcapstype\">\n   <xs:sequence>\n    <xs:element name=\"actor\" type=\"tns:actortype\" minOccurs=\"0\"/>\n    <xs:element name=\"application\" type=\"tns:applicationtype\" minOccurs=\"0\"/>\n    <xs:element name=\"audio\" type=\"tns:audiotype\" minOccurs=\"0\"/>\n    <xs:element name=\"automata\" type=\"tns:automatatype\" minOccurs=\"0\"/>\n    <xs:element name=\"class\" type=\"tns:classtype\" minOccurs=\"0\"/>\n    <xs:element name=\"control\" type=\"tns:controltype\" minOccurs=\"0\"/>\n    <xs:element name=\"data\" type=\"tns:datatype\" minOccurs=\"0\"/>\n    <xs:element name=\"description\" type=\"tns:descriptiontype\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xs:element name=\"duplex\" type=\"tns:duplextype\" minOccurs=\"0\"/>\n    <xs:element name=\"event-packages\" type=\"tns:event-packagestype\" minOccurs=\"0\"/>\n    <xs:element name=\"extensions\" type=\"tns:extensionstype\" minOccurs=\"0\"/>\n    <xs:element name=\"isfocus\" type=\"tns:isfocustype\" minOccurs=\"0\"/>\n    <xs:element name=\"message\" type=\"tns:messagetype\" minOccurs=\"0\"/>\n    <xs:element name=\"methods\" type=\"tns:methodstype\" minOccurs=\"0\"/>\n    <xs:element name=\"languages\" type=\"tns:languagestype\" minOccurs=\"0\"/>\n    <xs:element name=\"priority\" type=\"tns:prioritytype\" minOccurs=\"0\"/>\n    <xs:element name=\"schemes\" type=\"tns:schemestype\" minOccurs=\"0\"/>\n    <xs:element name=\"text\" type=\"tns:texttype\" minOccurs=\"0\"/>\n    <xs:element name=\"type\" type=\"tns:typetype\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xs:element name=\"video\" type=\"tns:videotype\" minOccurs=\"0\"/>\n    <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n   </xs:sequence>\n   <xs:anyAttribute namespace=\"##any\" processContents=\"lax\"/>\n  </xs:complexType>\n\n  <xs:element name=\"devcaps\" type=\"tns:devcaps\"/>\n  <xs:complexType name=\"devcaps\">\n   <xs:sequence>\n    <xs:element name=\"description\" type=\"tns:descriptiontype\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xs:element name=\"mobility\" type=\"tns:mobilitytype\" minOccurs=\"0\"/>\n    <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n   </xs:sequence>\n   <xs:anyAttribute namespace=\"##any\" processContents=\"lax\"/>\n  </xs:complexType>\n\n  <!-- AUDIO -->\n  <xs:simpleType name=\"audiotype\">\n   <xs:restriction base=\"xs:boolean\"/>\n  </xs:simpleType>\n\n  <!-- APPLICATION -->\n  <xs:simpleType name=\"applicationtype\">\n   <xs:restriction base=\"xs:boolean\"/>\n  </xs:simpleType>\n\n  <!-- DATA -->\n  <xs:simpleType name=\"datatype\">\n   <xs:restriction base=\"xs:boolean\"/>\n  </xs:simpleType>\n\n  <!-- CONTROL -->\n  <xs:simpleType name=\"controltype\">\n   <xs:restriction base=\"xs:boolean\"/>\n  </xs:simpleType>\n\n  <!-- VIDEO -->\n  <xs:simpleType name=\"videotype\">\n   <xs:restriction base=\"xs:boolean\"/>\n  </xs:simpleType>\n\n  <!-- TEXT -->\n  <xs:simpleType name=\"texttype\">\n   <xs:restriction base=\"xs:boolean\"/>\n  </xs:simpleType>\n\n  <!-- MESSAGE -->\n  <xs:simpleType name=\"messagetype\">\n   <xs:restriction base=\"xs:boolean\"/>\n  </xs:simpleType>\n\n  <!-- TYPE -->\n  <xs:simpleType name=\"typetype\">\n   <xs:restriction base=\"xs:string\"/>\n  </xs:simpleType>\n\n  <!-- AUTOMATA -->\n  <xs:simpleType name=\"automatatype\">\n   <xs:restriction base=\"xs:boolean\"/>\n  </xs:simpleType>\n\n  <!-- CLASS -->\n  <xs:complexType name=\"classtype\">\n   <xs:sequence>\n    <xs:element name=\"supported\" type=\"tns:classtypes\" minOccurs=\"0\"/>\n    <xs:element name=\"notsupported\" type=\"tns:classtypes\" minOccurs=\"0\"/>\n   </xs:sequence>\n  </xs:complexType>\n  <xs:complexType name=\"classtypes\">\n   <xs:sequence>\n    <xs:element name=\"business\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"personal\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n   </xs:sequence>\n  </xs:complexType>\n\n  <!-- DUPLEX -->\n  <xs:complexType name=\"duplextype\">\n   <xs:sequence>\n    <xs:element name=\"supported\" type=\"tns:duplextypes\" minOccurs=\"0\"/>\n    <xs:element name=\"notsupported\" type=\"tns:duplextypes\" minOccurs=\"0\"/>\n   </xs:sequence>\n  </xs:complexType>\n  <xs:complexType name=\"duplextypes\">\n   <xs:sequence>\n    <xs:element name=\"full\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"half\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"receive-only\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"send-only\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n   </xs:sequence>\n  </xs:complexType>\n\n  <!-- DESCRIPTION -->\n  <xs:complexType name=\"descriptiontype\">\n   <xs:simpleContent>\n    <xs:extension base=\"xs:string\">\n     <xs:attribute ref=\"xml:lang\"/>\n    </xs:extension>\n   </xs:simpleContent>\n  </xs:complexType>\n\n  <!-- EVENT-PACKAGES -->\n  <xs:complexType name=\"event-packagestype\">\n   <xs:sequence>\n    <xs:element name=\"supported\" type=\"tns:eventtypes\" minOccurs=\"0\"/>\n    <xs:element name=\"notsupported\" type=\"tns:eventtypes\" minOccurs=\"0\"/>\n   </xs:sequence>\n  </xs:complexType>\n  <xs:complexType name=\"eventtypes\">\n   <xs:sequence>\n    <xs:element name=\"conference\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"dialog\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"kpml\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"message-summary\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"poc-settings\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"presence\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"reg\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"refer\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"Siemens-RTP-Stats\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"spirits-INDPs\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"spirits-user-prof\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"winfo\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n   </xs:sequence>\n  </xs:complexType>\n\n  <!-- PRIORITY -->\n  <xs:complexType name=\"prioritytype\">\n   <xs:sequence>\n    <xs:element name=\"supported\" type=\"tns:prioritytypes\" minOccurs=\"0\"/>\n    <xs:element name=\"notsupported\" type=\"tns:prioritytypes\" minOccurs=\"0\"/>\n   </xs:sequence>\n  </xs:complexType>\n  <xs:complexType name=\"prioritytypes\">\n   <xs:sequence>\n    <xs:element name=\"equals\" type=\"tns:equalstype\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xs:element name=\"higherhan\" type=\"tns:higherthantype\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xs:element name=\"lowerthan\" type=\"tns:lowerthantype\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xs:element name=\"range\" type=\"tns:rangetype\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n   </xs:sequence>\n  </xs:complexType>\n  <xs:complexType name=\"lowerthantype\">\n   <xs:attribute name=\"maxvalue\" type=\"xs:integer\" use=\"required\"/>\n  </xs:complexType>\n  <xs:complexType name=\"higherthantype\">\n   <xs:attribute name=\"minvalue\" type=\"xs:integer\" use=\"required\"/>\n  </xs:complexType>\n  <xs:complexType name=\"equalstype\">\n   <xs:attribute name=\"value\" type=\"xs:integer\" use=\"required\"/>\n  </xs:complexType>\n  <xs:complexType name=\"rangetype\">\n   <xs:attribute name=\"minvalue\" type=\"xs:integer\" use=\"required\"/>\n   <xs:attribute name=\"maxvalue\" type=\"xs:integer\" use=\"required\"/>\n  </xs:complexType>\n\n  <!-- METHODS -->\n  <xs:complexType name=\"methodstype\">\n   <xs:sequence>\n    <xs:element name=\"supported\" type=\"tns:methodtypes\" minOccurs=\"0\"/>\n    <xs:element name=\"notsupported\" type=\"tns:methodtypes\" minOccurs=\"0\"/>\n   </xs:sequence>\n  </xs:complexType>\n  <xs:complexType name=\"methodtypes\">\n   <xs:sequence>\n    <xs:element name=\"ACK\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"BYE\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"CANCEL\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"INFO\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"INVITE\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"MESSAGE\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"NOTIFY\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"OPTIONS\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"PRACK\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"PUBLISH\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"REFER\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"REGISTER\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"SUBSCRIBE\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"UPDATE\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n   </xs:sequence>\n  </xs:complexType>\n\n  <!-- EXTENSIONS -->\n  <xs:complexType name=\"extensionstype\">\n   <xs:sequence>\n    <xs:element name=\"supported\" type=\"tns:extensiontypes\" minOccurs=\"0\"/>\n    <xs:element name=\"notsupported\" type=\"tns:extensiontypes\" minOccurs=\"0\"/>\n   </xs:sequence>\n  </xs:complexType>\n  <xs:complexType name=\"extensiontypes\">\n   <xs:sequence>\n    <xs:element name=\"rel100\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"early-session\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"eventlist\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"from-change\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"gruu\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"hist-info\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"join\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"norefersub\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"path\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"precondition\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"pref\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"privacy\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"recipient-list-invite\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"recipient-list-subscribe\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"replaces\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"resource-priority\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"sdp-anat\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"sec-agree\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"tdialog\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"timer\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n   </xs:sequence>\n  </xs:complexType>\n\n  <!-- SCHEMES -->\n  <xs:complexType name=\"schemestype\">\n   <xs:sequence>\n    <xs:element name=\"supported\" minOccurs=\"0\">\n     <xs:complexType>\n      <xs:sequence>\n       <xs:element name=\"s\" type=\"xs:string\" maxOccurs=\"unbounded\"/>\n      </xs:sequence>\n     </xs:complexType>\n    </xs:element>\n    <xs:element name=\"notsupported\" minOccurs=\"0\">\n     <xs:complexType>\n      <xs:sequence>\n       <xs:element name=\"s\" type=\"xs:string\" maxOccurs=\"unbounded\"/>\n      </xs:sequence>\n     </xs:complexType>\n    </xs:element>\n   </xs:sequence>\n  </xs:complexType>\n\n  <!-- ACTOR -->\n  <xs:complexType name=\"actortype\">\n   <xs:sequence>\n    <xs:element name=\"supported\" type=\"tns:actortypes\" minOccurs=\"0\"/>\n    <xs:element name=\"notsupported\" type=\"tns:actortypes\" minOccurs=\"0\"/>\n   </xs:sequence>\n  </xs:complexType>\n  <xs:complexType name=\"actortypes\">\n   <xs:sequence>\n    <xs:element name=\"attendant\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"information\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"msg-taker\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"principal\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n   </xs:sequence>\n  </xs:complexType>\n\n  <!-- ISFOCUS -->\n  <xs:simpleType name=\"isfocustype\">\n   <xs:restriction base=\"xs:boolean\"/>\n  </xs:simpleType>\n\n  <!-- LANGUAGES -->\n  <xs:complexType name=\"languagestype\">\n   <xs:sequence>\n    <xs:element name=\"supported\" minOccurs=\"0\">\n     <xs:complexType>\n      <xs:sequence>\n       <xs:element name=\"l\" type=\"xs:string\" maxOccurs=\"unbounded\"/>\n      </xs:sequence>\n     </xs:complexType>\n    </xs:element>\n    <xs:element name=\"notsupported\" minOccurs=\"0\">\n     <xs:complexType>\n      <xs:sequence>\n       <xs:element name=\"l\" type=\"xs:string\" maxOccurs=\"unbounded\"/>\n      </xs:sequence>\n     </xs:complexType>\n    </xs:element>\n   </xs:sequence>\n  </xs:complexType>\n\n  <!-- MOBILITY -->\n  <xs:complexType name=\"mobilitytype\">\n   <xs:sequence>\n    <xs:element name=\"supported\" type=\"tns:mobilitytypes\" minOccurs=\"0\"/>\n    <xs:element name=\"notsupported\" type=\"tns:mobilitytypes\" minOccurs=\"0\"/>\n   </xs:sequence>\n  </xs:complexType>\n  <xs:complexType name=\"mobilitytypes\">\n   <xs:sequence>\n    <xs:element name=\"fixed\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:element name=\"mobile\" type=\"xs:string\" minOccurs=\"0\"/>\n    <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n   </xs:sequence>\n  </xs:complexType>\n </xs:schema>\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/cipid.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n   <xs:schema targetNamespace=\"urn:ietf:params:xml:ns:pidf:cipid\"\n       xmlns:cipid=\"urn:ietf:params:xml:ns:pidf:cipid\"\n       xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n       elementFormDefault=\"qualified\"\n       attributeFormDefault=\"unqualified\">\n\n     <xs:annotation>\n       <xs:documentation>\n         Describes CIPID tuple extensions for PIDF.\n       </xs:documentation>\n     </xs:annotation>\n\n     <xs:element name=\"card\" type=\"xs:anyURI\"/>\n     <xs:element name=\"display-name\" type=\"xs:string\"/>\n     <xs:element name=\"homepage\" type=\"xs:anyURI\"/>\n     <xs:element name=\"icon\" type=\"xs:anyURI\"/>\n     <xs:element name=\"map\" type=\"xs:anyURI\"/>\n     <xs:element name=\"sound\" type=\"xs:anyURI\"/>\n   </xs:schema>\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/common-policy.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:ietf:params:xml:ns:common-policy\"\n    xmlns:cp=\"urn:ietf:params:xml:ns:common-policy\"\n    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n    elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n\n    <!-- /ruleset -->\n    <xs:element name=\"ruleset\">\n        <xs:complexType>\n            <xs:complexContent>\n                <xs:restriction base=\"xs:anyType\">\n                    <xs:sequence>\n                        <xs:element name=\"rule\" type=\"cp:ruleType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n                    </xs:sequence>\n                </xs:restriction>\n            </xs:complexContent>\n        </xs:complexType>\n    </xs:element>\n\n    <!-- /ruleset/rule -->\n    <xs:complexType name=\"ruleType\">\n        <xs:complexContent>\n            <xs:restriction base=\"xs:anyType\">\n                <xs:sequence>\n                    <xs:element name=\"conditions\" type=\"cp:conditionsType\" minOccurs=\"0\"/>\n                    <xs:element name=\"actions\" type=\"cp:extensibleType\" minOccurs=\"0\"/>\n                    <xs:element name=\"transformations\" type=\"cp:extensibleType\" minOccurs=\"0\"/>\n                </xs:sequence>\n                <xs:attribute name=\"id\" type=\"xs:ID\" use=\"required\"/>\n            </xs:restriction>\n        </xs:complexContent>\n    </xs:complexType>\n\n    <!-- //rule/conditions -->\n    <xs:complexType name=\"conditionsType\">\n        <xs:complexContent>\n            <xs:restriction base=\"xs:anyType\">\n                <xs:choice maxOccurs=\"unbounded\">\n                    <xs:element name=\"identity\" type=\"cp:identityType\" minOccurs=\"0\"/>\n                    <xs:element name=\"sphere\"  type=\"cp:sphereType\" minOccurs=\"0\"/>\n                    <xs:element name=\"validity\" type=\"cp:validityType\" minOccurs=\"0\"/>\n                    <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n                </xs:choice>\n            </xs:restriction>\n        </xs:complexContent>\n    </xs:complexType>\n\n    <!-- //conditions/identity -->\n    <xs:complexType name=\"identityType\">\n        <xs:complexContent>\n            <xs:restriction base=\"xs:anyType\">\n                <xs:choice  minOccurs=\"1\" maxOccurs=\"unbounded\">\n                    <xs:element name=\"one\" type=\"cp:oneType\"/>\n                    <xs:element name=\"many\" type=\"cp:manyType\"/>\n                    <xs:any namespace=\"##other\" processContents=\"lax\"/>\n                </xs:choice>\n            </xs:restriction>\n        </xs:complexContent>\n    </xs:complexType>\n\n    <!-- //identity/one -->\n    <xs:complexType name=\"oneType\">\n        <xs:complexContent>\n            <xs:restriction base=\"xs:anyType\">\n                <xs:sequence>\n                    <xs:any namespace=\"##other\" minOccurs=\"0\" processContents=\"lax\"/>\n                </xs:sequence>\n                <xs:attribute name=\"id\" type=\"xs:anyURI\" use=\"required\"/>\n            </xs:restriction>\n        </xs:complexContent>\n    </xs:complexType>\n\n    <!-- //identity/many -->\n    <xs:complexType name=\"manyType\">\n        <xs:complexContent>\n            <xs:restriction base=\"xs:anyType\">\n                <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n                    <xs:element name=\"except\" type=\"cp:exceptType\"/>\n                    <xs:any namespace=\"##other\" minOccurs=\"0\" processContents=\"lax\"/>\n                </xs:choice>\n                <xs:attribute name=\"domain\" use=\"optional\" type=\"xs:string\"/>\n            </xs:restriction>\n        </xs:complexContent>\n    </xs:complexType>\n\n    <!-- //many/except -->\n    <xs:complexType name=\"exceptType\">\n        <xs:attribute name=\"domain\" type=\"xs:string\" use=\"optional\"/>\n        <xs:attribute name=\"id\" type=\"xs:anyURI\" use=\"optional\"/>\n    </xs:complexType>\n\n    <!-- //conditions/sphere -->\n    <xs:complexType name=\"sphereType\">\n        <xs:complexContent>\n            <xs:restriction base=\"xs:anyType\">\n                <xs:attribute name=\"value\" type=\"xs:string\" use=\"required\"/>\n            </xs:restriction>\n        </xs:complexContent>\n    </xs:complexType>\n\n    <!-- //conditions/validity -->\n    <xs:complexType name=\"validityType\">\n        <xs:complexContent>\n            <xs:restriction base=\"xs:anyType\">\n                <xs:sequence maxOccurs=\"unbounded\">\n                    <xs:element name=\"from\" type=\"xs:dateTime\"/>\n                    <xs:element name=\"until\" type=\"xs:dateTime\"/>\n                </xs:sequence>\n            </xs:restriction>\n        </xs:complexContent>\n    </xs:complexType>\n\n    <!-- //rule/actions or //rule/transformations -->\n    <xs:complexType name=\"extensibleType\">\n        <xs:complexContent>\n            <xs:restriction base=\"xs:anyType\">\n                <xs:sequence>\n                    <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n                </xs:sequence>\n            </xs:restriction>\n        </xs:complexContent>\n    </xs:complexType>\n</xs:schema>\n\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/common-schema.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n    elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n\n    <xs:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n\n    <xs:simpleType name=\"Timestamp_t\">\n     <xs:annotation>\n      <xs:documentation>Timestamp type</xs:documentation>\n     </xs:annotation>\n     <xs:restriction base=\"xs:dateTime\"/>\n    </xs:simpleType>\n\n    <xs:simpleType name=\"deviceID_t\">\n     <xs:annotation>\n      <xs:documentation>Device ID, a URN</xs:documentation>\n     </xs:annotation>\n     <xs:restriction base=\"xs:anyURI\"/>\n    </xs:simpleType>\n\n    <xs:complexType name=\"Note_t\">\n     <xs:annotation>\n      <xs:documentation>Note type</xs:documentation>\n     </xs:annotation>\n     <xs:simpleContent>\n      <xs:extension base=\"xs:string\">\n       <xs:attribute ref=\"xml:lang\"/>\n      </xs:extension>\n     </xs:simpleContent>\n    </xs:complexType>\n\n    <xs:attributeGroup name=\"fromUntil\">\n     <xs:attribute name=\"from\" type=\"xs:dateTime\"/>\n     <xs:attribute name=\"until\" type=\"xs:dateTime\"/>\n    </xs:attributeGroup>\n    <xs:complexType name=\"empty\"/>\n   </xs:schema>\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/conference.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<xs:schema targetNamespace=\"urn:ietf:params:xml:ns:conference-info\"\n   xmlns:tns=\"urn:ietf:params:xml:ns:conference-info\"\n   xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n   xmlns=\"urn:ietf:params:xml:ns:conference-info\"\n   elementFormDefault=\"qualified\"\n   attributeFormDefault=\"unqualified\">\n\n  <!-- This imports the xml:language definition -->\n   <xs:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n\n   <!-- CONFERENCE ELEMENT -->\n   <xs:element name=\"conference-info\" type=\"conference-type\"/>\n\n   <!-- CONFERENCE TYPE -->\n   <xs:complexType name=\"conference-type\">\n    <xs:sequence>\n     <xs:element name=\"conference-description\" type=\"conference-description-type\" minOccurs=\"0\"/>\n     <xs:element name=\"host-info\" type=\"host-type\" minOccurs=\"0\"/>\n     <xs:element name=\"conference-state\" type=\"conference-state-type\" minOccurs=\"0\"/>\n     <xs:element name=\"users\" type=\"users-type\" minOccurs=\"0\"/>\n     <xs:element name=\"sidebars-by-ref\" type=\"uris-type\" minOccurs=\"0\"/>\n     <xs:element name=\"sidebars-by-val\" type=\"sidebars-by-val-type\" minOccurs=\"0\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"entity\" type=\"xs:anyURI\" use=\"required\"/>\n    <xs:attribute name=\"state\" type=\"state-type\" use=\"optional\" default=\"full\"/>\n    <xs:attribute name=\"version\" type=\"xs:unsignedInt\" use=\"optional\"/>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- STATE TYPE -->\n   <xs:simpleType name=\"state-type\">\n    <xs:restriction base=\"xs:string\">\n     <xs:enumeration value=\"full\"/>\n     <xs:enumeration value=\"partial\"/>\n     <xs:enumeration value=\"deleted\"/>\n    </xs:restriction>\n   </xs:simpleType>\n\n   <!-- CONFERENCE DESCRIPTION TYPE -->\n   <xs:complexType name=\"conference-description-type\">\n    <xs:sequence>\n     <xs:element name=\"display-text\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"subject\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"free-text\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"keywords\" type=\"keywords-type\" minOccurs=\"0\"/>\n     <xs:element name=\"conf-uris\" type=\"uris-type\" minOccurs=\"0\"/>\n     <xs:element name=\"service-uris\" type=\"uris-type\" minOccurs=\"0\"/>\n     <xs:element name=\"maximum-user-count\" type=\"xs:unsignedInt\" minOccurs=\"0\"/>\n     <xs:element name=\"available-media\" type=\"conference-media-type\" minOccurs=\"0\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- HOST TYPE -->\n   <xs:complexType name=\"host-type\">\n    <xs:sequence>\n     <xs:element name=\"display-text\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"web-page\" type=\"xs:anyURI\" minOccurs=\"0\"/>\n     <xs:element name=\"uris\" type=\"uris-type\" minOccurs=\"0\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- CONFERENCE STATE TYPE -->\n   <xs:complexType name=\"conference-state-type\">\n    <xs:sequence>\n     <xs:element name=\"user-count\" type=\"xs:unsignedInt\" minOccurs=\"0\"/>\n     <xs:element name=\"active\" type=\"xs:boolean\" minOccurs=\"0\"/>\n     <xs:element name=\"locked\" type=\"xs:boolean\" minOccurs=\"0\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- CONFERENCE MEDIA TYPE -->\n   <xs:complexType name=\"conference-media-type\">\n    <xs:sequence>\n     <xs:element name=\"entry\" type=\"conference-medium-type\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- CONFERENCE MEDIUM TYPE -->\n   <xs:complexType name=\"conference-medium-type\">\n    <xs:sequence>\n     <xs:element name=\"display-text\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"type\" type=\"xs:string\"/>\n     <xs:element name=\"status\" type=\"media-status-type\" minOccurs=\"0\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"label\" type=\"xs:string\" use=\"required\"/>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- URIs TYPE -->\n   <xs:complexType name=\"uris-type\">\n    <xs:sequence>\n     <xs:element name=\"entry\" type=\"uri-type\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"state\" type=\"state-type\" use=\"optional\" default=\"full\"/>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- URI TYPE -->\n   <xs:complexType name=\"uri-type\">\n    <xs:sequence>\n     <xs:element name=\"uri\" type=\"xs:anyURI\"/>\n     <xs:element name=\"display-text\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"purpose\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"modified\" type=\"execution-type\" minOccurs=\"0\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- KEYWORDS TYPE -->\n   <xs:simpleType name=\"keywords-type\">\n    <xs:list itemType=\"xs:string\"/>\n   </xs:simpleType>\n\n   <!-- USERS TYPE -->\n   <xs:complexType name=\"users-type\">\n    <xs:sequence>\n     <xs:element name=\"user\" type=\"user-type\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"state\" type=\"state-type\" use=\"optional\" default=\"full\"/>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- USER TYPE -->\n   <xs:complexType name=\"user-type\">\n    <xs:sequence>\n     <xs:element name=\"display-text\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"associated-aors\" type=\"uris-type\" minOccurs=\"0\"/>\n     <xs:element name=\"roles\" type=\"user-roles-type\" minOccurs=\"0\"/>\n     <xs:element name=\"languages\" type=\"user-languages-type\" minOccurs=\"0\"/>\n     <xs:element name=\"cascaded-focus\" type=\"xs:anyURI\" minOccurs=\"0\"/>\n     <xs:element name=\"endpoint\" type=\"endpoint-type\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"entity\" type=\"xs:anyURI\"/>\n    <xs:attribute name=\"state\" type=\"state-type\" use=\"optional\" default=\"full\"/>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- USER ROLES TYPE -->\n   <xs:complexType name=\"user-roles-type\">\n    <xs:sequence>\n     <xs:element name=\"entry\" type=\"xs:string\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- USER LANGUAGES TYPE -->\n   <xs:simpleType name=\"user-languages-type\">\n    <xs:list itemType=\"xs:language\"/>\n   </xs:simpleType>\n\n   <!-- ENDPOINT TYPE -->\n   <xs:complexType name=\"endpoint-type\">\n    <xs:sequence>\n     <xs:element name=\"display-text\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"referred\" type=\"execution-type\" minOccurs=\"0\"/>\n     <xs:element name=\"status\" type=\"endpoint-status-type\" minOccurs=\"0\"/>\n     <xs:element name=\"joining-method\" type=\"joining-type\" minOccurs=\"0\"/>\n     <xs:element name=\"joining-info\" type=\"execution-type\" minOccurs=\"0\"/>\n     <xs:element name=\"disconnection-method\" type=\"disconnection-type\" minOccurs=\"0\"/>\n     <xs:element name=\"disconnection-info\" type=\"execution-type\" minOccurs=\"0\"/>\n     <xs:element name=\"media\" type=\"media-type\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     <xs:element name=\"call-info\" type=\"call-type\" minOccurs=\"0\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"entity\" type=\"xs:string\"/>\n    <xs:attribute name=\"state\" type=\"state-type\" use=\"optional\" default=\"full\"/>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- ENDPOINT STATUS TYPE -->\n   <xs:simpleType name=\"endpoint-status-type\">\n    <xs:restriction base=\"xs:string\">\n     <xs:enumeration value=\"pending\"/>\n     <xs:enumeration value=\"dialing-out\"/>\n     <xs:enumeration value=\"dialing-in\"/>\n     <xs:enumeration value=\"alerting\"/>\n     <xs:enumeration value=\"on-hold\"/>\n     <xs:enumeration value=\"connected\"/>\n     <xs:enumeration value=\"muted-via-focus\"/>\n     <xs:enumeration value=\"disconnecting\"/>\n     <xs:enumeration value=\"disconnected\"/>\n    </xs:restriction>\n   </xs:simpleType>\n\n   <!-- JOINING TYPE -->\n   <xs:simpleType name=\"joining-type\">\n    <xs:restriction base=\"xs:string\">\n     <xs:enumeration value=\"dialed-in\"/>\n     <xs:enumeration value=\"dialed-out\"/>\n     <xs:enumeration value=\"focus-owner\"/>\n    </xs:restriction>\n   </xs:simpleType>\n\n   <!-- DISCONNECTION TYPE -->\n   <xs:simpleType name=\"disconnection-type\">\n    <xs:restriction base=\"xs:string\">\n     <xs:enumeration value=\"departed\"/>\n     <xs:enumeration value=\"booted\"/>\n     <xs:enumeration value=\"failed\"/>\n     <xs:enumeration value=\"busy\"/>\n    </xs:restriction>\n   </xs:simpleType>\n\n   <!-- EXECUTION TYPE -->\n   <xs:complexType name=\"execution-type\">\n    <xs:sequence>\n     <xs:element name=\"when\" type=\"xs:dateTime\" minOccurs=\"0\"/>\n     <xs:element name=\"reason\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"by\" type=\"xs:anyURI\" minOccurs=\"0\"/>\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n  <!-- CALL TYPE -->\n   <xs:complexType name=\"call-type\">\n    <xs:choice>\n     <xs:element name=\"sip\" type=\"sip-dialog-id-type\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:choice>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- SIP DIALOG ID TYPE -->\n   <xs:complexType name=\"sip-dialog-id-type\">\n    <xs:sequence>\n     <xs:element name=\"display-text\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"call-id\" type=\"xs:string\"/>\n     <xs:element name=\"from-tag\" type=\"xs:string\"/>\n     <xs:element name=\"to-tag\" type=\"xs:string\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- MEDIA TYPE -->\n   <xs:complexType name=\"media-type\">\n    <xs:sequence>\n     <xs:element name=\"display-text\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"type\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"label\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"src-id\" type=\"xs:string\" minOccurs=\"0\"/>\n     <xs:element name=\"status\" type=\"media-status-type\" minOccurs=\"0\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"id\" type=\"xs:string\" use=\"required\"/>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <!-- MEDIA STATUS TYPE -->\n   <xs:simpleType name=\"media-status-type\">\n    <xs:restriction base=\"xs:string\">\n     <xs:enumeration value=\"recvonly\"/>\n     <xs:enumeration value=\"sendonly\"/>\n     <xs:enumeration value=\"sendrecv\"/>\n     <xs:enumeration value=\"inactive\"/>\n    </xs:restriction>\n   </xs:simpleType>\n\n   <!-- SIDEBARS BY VAL TYPE -->\n   <xs:complexType name=\"sidebars-by-val-type\">\n    <xs:sequence>\n     <xs:element name=\"entry\" type=\"conference-type\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"state\" type=\"state-type\" use=\"optional\" default=\"full\"/>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n</xs:schema>\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/data-model.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:ietf:params:xml:ns:pidf:data-model\"\n    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns=\"urn:ietf:params:xml:ns:pidf:data-model\"\n    elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n\n    <xs:include schemaLocation=\"common-schema.xsd\"/>\n\n    <xs:element name=\"deviceID\" type=\"deviceID_t\">\n     <xs:annotation>\n      <xs:documentation>Device ID, a URN</xs:documentation>\n     </xs:annotation>\n    </xs:element>\n\n    <xs:element name=\"device\">\n     <xs:annotation>\n      <xs:documentation>\n        Contains information about the device\n      </xs:documentation>\n     </xs:annotation>\n     <xs:complexType>\n      <xs:sequence>\n       <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       <xs:element ref=\"deviceID\"/>\n       <xs:element name=\"note\" type=\"Note_t\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       <xs:element name=\"timestamp\" type=\"Timestamp_t\" minOccurs=\"0\"/>\n      </xs:sequence>\n      <xs:attribute name=\"id\" type=\"xs:ID\" use=\"required\"/>\n     </xs:complexType>\n    </xs:element>\n\n    <xs:element name=\"person\">\n     <xs:annotation>\n      <xs:documentation>\n        Contains information about the human user\n      </xs:documentation>\n     </xs:annotation>\n     <xs:complexType>\n      <xs:sequence>\n       <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xs:annotation>\n         <xs:documentation>\n           Characteristic and status information\n         </xs:documentation>\n        </xs:annotation>\n       </xs:any>\n       <xs:element name=\"note\" type=\"Note_t\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       <xs:element name=\"timestamp\" type=\"Timestamp_t\" minOccurs=\"0\"/>\n      </xs:sequence>\n      <xs:attribute name=\"id\" type=\"xs:ID\" use=\"required\"/>\n     </xs:complexType>\n    </xs:element>\n\n</xs:schema>\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/dialog-info.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:ietf:params:xml:ns:dialog-info\"\n   xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n   xmlns:tns=\"urn:ietf:params:xml:ns:dialog-info\"\n   elementFormDefault=\"qualified\"\n   attributeFormDefault=\"unqualified\">\n\n   <!-- This import brings in the XML language attribute xml:lang-->\n   <xs:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n\n   <xs:element name=\"dialog-info\">\n     <xs:complexType>\n       <xs:sequence>\n         <xs:element ref=\"tns:dialog\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n         <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       </xs:sequence>\n       <xs:attribute name=\"version\" type=\"xs:nonNegativeInteger\" use=\"required\"/>\n       <xs:attribute name=\"state\" use=\"required\">\n         <xs:simpleType>\n           <xs:restriction base=\"xs:string\">\n             <xs:enumeration value=\"full\"/>\n             <xs:enumeration value=\"partial\"/>\n           </xs:restriction>\n         </xs:simpleType>\n       </xs:attribute>\n       <xs:attribute name=\"entity\" type=\"xs:anyURI\" use=\"required\"/>\n     </xs:complexType>\n   </xs:element>\n\n   <xs:element name=\"dialog\">\n     <xs:complexType>\n       <xs:sequence>\n         <xs:element ref=\"tns:state\" minOccurs=\"1\" maxOccurs=\"1\"/>\n         <xs:element name=\"duration\" type=\"xs:nonNegativeInteger\" minOccurs=\"0\" maxOccurs=\"1\"/>\n         <xs:element name=\"replaces\" minOccurs=\"0\" maxOccurs=\"1\">\n           <xs:complexType>\n             <xs:attribute name=\"call-id\" type=\"xs:string\" use=\"required\"/>\n             <xs:attribute name=\"local-tag\" type=\"xs:string\" use=\"required\"/>\n             <xs:attribute name=\"remote-tag\" type=\"xs:string\" use=\"required\"/>\n           </xs:complexType>\n         </xs:element>\n         <xs:element name=\"referred-by\" type=\"tns:nameaddr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n         <xs:element name=\"route-set\" minOccurs=\"0\" maxOccurs=\"1\">\n           <xs:complexType>\n             <xs:sequence>\n               <xs:element name=\"hop\" type=\"xs:string\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n             </xs:sequence>\n           </xs:complexType>\n         </xs:element>\n         <xs:element name=\"local\" type=\"tns:participant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n         <xs:element name=\"remote\" type=\"tns:participant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n         <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       </xs:sequence>\n       <xs:attribute name=\"id\" type=\"xs:string\" use=\"required\"/>\n       <xs:attribute name=\"call-id\" type=\"xs:string\" use=\"optional\"/>\n       <xs:attribute name=\"local-tag\" type=\"xs:string\" use=\"optional\"/>\n       <xs:attribute name=\"remote-tag\" type=\"xs:string\" use=\"optional\"/>\n       <xs:attribute name=\"direction\" use=\"optional\">\n         <xs:simpleType>\n           <xs:restriction base=\"xs:string\">\n             <xs:enumeration value=\"initiator\"/>\n             <xs:enumeration value=\"recipient\"/>\n           </xs:restriction>\n         </xs:simpleType>\n       </xs:attribute>\n     </xs:complexType>\n   </xs:element>\n\n   <xs:complexType name=\"participant\">\n     <xs:sequence>\n       <xs:element name=\"identity\" type=\"tns:nameaddr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n       <xs:element name=\"target\" minOccurs=\"0\" maxOccurs=\"1\">\n         <xs:complexType>\n           <xs:sequence>\n             <xs:element name=\"param\" minOccurs=\"0\" maxOccurs=\"unbounded\">\n               <xs:complexType>\n                 <xs:attribute name=\"pname\" type=\"xs:string\" use=\"required\"/>\n                 <xs:attribute name=\"pval\" type=\"xs:string\" use=\"required\"/>\n               </xs:complexType>\n             </xs:element>\n           </xs:sequence>\n           <xs:attribute name=\"uri\" type=\"xs:string\" use=\"required\"/>\n         </xs:complexType>\n       </xs:element>\n       <xs:element name=\"session-description\" type=\"tns:sessd\" minOccurs=\"0\" maxOccurs=\"1\"/>\n       <xs:element name=\"cseq\" type=\"xs:nonNegativeInteger\" minOccurs=\"0\" maxOccurs=\"1\"/>\n       <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xs:sequence>\n   </xs:complexType>\n\n   <xs:complexType name=\"nameaddr\">\n     <xs:simpleContent>\n       <xs:extension base=\"xs:anyURI\">\n         <xs:attribute name=\"display\" type=\"xs:string\" use=\"optional\"/>\n       </xs:extension>\n     </xs:simpleContent>\n   </xs:complexType>\n\n   <xs:complexType name=\"sessd\">\n     <xs:simpleContent>\n       <xs:extension base=\"xs:string\">\n         <xs:attribute name=\"type\" type=\"xs:string\" use=\"required\"/>\n       </xs:extension>\n     </xs:simpleContent>\n   </xs:complexType>\n\n   <xs:element name=\"state\">\n     <xs:complexType>\n       <xs:simpleContent>\n         <xs:extension base=\"xs:string\">\n           <xs:attribute name=\"event\" use=\"optional\">\n             <xs:simpleType>\n               <xs:restriction base=\"xs:string\">\n                 <xs:enumeration value=\"cancelled\"/>\n                 <xs:enumeration value=\"rejected\"/>\n                 <xs:enumeration value=\"replaced\"/>\n                 <xs:enumeration value=\"local-bye\"/>\n                 <xs:enumeration value=\"remote-bye\"/>\n                 <xs:enumeration value=\"error\"/>\n                 <xs:enumeration value=\"timeout\"/>\n               </xs:restriction>\n             </xs:simpleType>\n           </xs:attribute>\n           <xs:attribute name=\"code\" use=\"optional\">\n             <xs:simpleType>\n               <xs:restriction base=\"xs:positiveInteger\">\n                 <xs:minInclusive value=\"100\"/>\n                 <xs:maxInclusive value=\"699\"/>\n               </xs:restriction>\n             </xs:simpleType>\n           </xs:attribute>\n         </xs:extension>\n       </xs:simpleContent>\n     </xs:complexType>\n   </xs:element>\n\n</xs:schema>\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/dialog-rules.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:ag-projects:xml:ns:dialog-rules\"\n    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:cr=\"urn:ietf:params:xml:ns:common-policy\"\n    xmlns:dr=\"urn:ag-projects:xml:ns:dialog-rules\"\n    elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n\n   <xs:import namespace=\"urn:ietf:params:xml:ns:common-policy\" schemaLocation=\"common-policy.xsd\"/>\n\n   <xs:element name=\"sub-handling\">\n    <xs:simpleType>\n     <xs:restriction base=\"xs:token\">\n      <xs:enumeration value=\"block\"/>\n      <xs:enumeration value=\"confirm\"/>\n      <xs:enumeration value=\"polite-block\"/>\n      <xs:enumeration value=\"allow\"/>\n     </xs:restriction>\n    </xs:simpleType>\n   </xs:element>\n\n</xs:schema>\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/im-iscomposing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:ietf:params:xml:ns:im-iscomposing\"\n   elementFormDefault=\"qualified\"\n   attributeFormDefault=\"unqualified\"\n   xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n   xmlns:tns=\"urn:ietf:params:xml:ns:im-iscomposing\">\n\n   <xs:element name=\"isComposing\">\n     <xs:complexType>\n       <xs:sequence>\n         <xs:element name=\"state\" type=\"xs:string\"/>\n         <xs:element name=\"lastactive\" type=\"xs:dateTime\" minOccurs=\"0\"/>\n         <xs:element name=\"contenttype\" type=\"xs:string\" minOccurs=\"0\"/>\n         <xs:element name=\"refresh\" type=\"xs:positiveInteger\" minOccurs=\"0\"/>\n         <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       </xs:sequence>\n     </xs:complexType>\n   </xs:element>\n\n</xs:schema>\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/imdn.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" targetNamespace=\"urn:ietf:params:xml:ns:imdn\" xmlns:ns1=\"urn:ietf:params:xml:ns:imdn\">\n  <xs:element name=\"imdn\">\n    <xs:complexType>\n      <xs:sequence>\n        <xs:element ref=\"ns1:message-id\"/>\n        <xs:element ref=\"ns1:datetime\"/>\n        <xs:sequence minOccurs=\"0\">\n          <xs:element ref=\"ns1:recipient-uri\"/>\n          <xs:element ref=\"ns1:original-recipient-uri\"/>\n          <xs:element minOccurs=\"0\" ref=\"ns1:subject\"/>\n        </xs:sequence>\n        <xs:choice minOccurs=\"0\">\n          <xs:element ref=\"ns1:delivery-notification\"/>\n          <xs:element ref=\"ns1:display-notification\"/>\n          <xs:element ref=\"ns1:processing-notification\"/>\n        </xs:choice>\n        <xs:group ref=\"ns1:imdnExtension\"/>\n      </xs:sequence>\n    </xs:complexType>\n  </xs:element>\n  <xs:element name=\"message-id\" type=\"xs:token\"/>\n  <xs:element name=\"datetime\" type=\"xs:string\"/>\n  <xs:element name=\"recipient-uri\" type=\"xs:anyURI\"/>\n  <xs:element name=\"original-recipient-uri\" type=\"xs:anyURI\"/>\n  <xs:element name=\"subject\" type=\"xs:string\"/>\n  <xs:element name=\"delivery-notification\">\n    <xs:complexType>\n      <xs:sequence>\n        <xs:element name=\"status\">\n          <xs:complexType>\n            <xs:sequence>\n              <xs:choice>\n                <xs:element ref=\"ns1:delivered\"/>\n                <xs:element ref=\"ns1:failed\"/>\n                <xs:element ref=\"ns1:commonDispositionStatus\"/>\n              </xs:choice>\n              <xs:group ref=\"ns1:deliveryExtension\"/>\n            </xs:sequence>\n          </xs:complexType>\n        </xs:element>\n      </xs:sequence>\n    </xs:complexType>\n  </xs:element>\n  <xs:element name=\"delivered\">\n    <xs:complexType/>\n  </xs:element>\n  <xs:element name=\"failed\">\n    <xs:complexType/>\n  </xs:element>\n  <xs:element name=\"display-notification\">\n    <xs:complexType>\n      <xs:sequence>\n        <xs:element name=\"status\">\n          <xs:complexType>\n            <xs:sequence>\n              <xs:choice>\n                <xs:element ref=\"ns1:displayed\"/>\n                <xs:element ref=\"ns1:commonDispositionStatus\"/>\n              </xs:choice>\n              <xs:group ref=\"ns1:displayExtension\"/>\n            </xs:sequence>\n          </xs:complexType>\n        </xs:element>\n      </xs:sequence>\n    </xs:complexType>\n  </xs:element>\n  <xs:element name=\"displayed\">\n    <xs:complexType/>\n  </xs:element>\n  <xs:element name=\"processing-notification\">\n    <xs:complexType>\n      <xs:sequence>\n        <xs:element name=\"status\">\n          <xs:complexType>\n            <xs:sequence>\n              <xs:choice>\n                <xs:element ref=\"ns1:processed\"/>\n                <xs:element ref=\"ns1:stored\"/>\n                <xs:element ref=\"ns1:commonDispositionStatus\"/>\n              </xs:choice>\n              <xs:group ref=\"ns1:processingExtension\"/>\n            </xs:sequence>\n          </xs:complexType>\n        </xs:element>\n      </xs:sequence>\n    </xs:complexType>\n  </xs:element>\n  <xs:element name=\"processed\">\n    <xs:complexType/>\n  </xs:element>\n  <xs:element name=\"stored\">\n    <xs:complexType/>\n  </xs:element>\n  <xs:element name=\"commonDispositionStatus\" abstract=\"true\">\n    <xs:complexType/>\n  </xs:element>\n  <xs:element name=\"forbidden\" substitutionGroup=\"ns1:commonDispositionStatus\"/>\n  <xs:element name=\"error\" substitutionGroup=\"ns1:commonDispositionStatus\"/>\n  <!--\n    <imdn> extension point for the extension schemas to add\n    new definitions with the combine=\"interleave\" pattern.\n    Extension schemas should add proper cardinalities.  For\n    example, the <zeroOrMore> cardinality should be used if\n    the extension is to allow multiple elements, and the\n    <optional> cardinality should be used if the extension\n    is to allow a single optional element.\n  -->\n  <xs:group name=\"imdnExtension\">\n    <xs:sequence>\n      <xs:group minOccurs=\"0\" maxOccurs=\"unbounded\" ref=\"ns1:anyIMDN\"/>\n    </xs:sequence>\n  </xs:group>\n  <!-- delivery-notification <status> extension point -->\n  <xs:group name=\"deliveryExtension\">\n    <xs:sequence>\n      <xs:group minOccurs=\"0\" maxOccurs=\"unbounded\" ref=\"ns1:anyIMDN\"/>\n    </xs:sequence>\n  </xs:group>\n  <!-- display-notification <status> extension point -->\n  <xs:group name=\"displayExtension\">\n    <xs:sequence>\n      <xs:group minOccurs=\"0\" maxOccurs=\"unbounded\" ref=\"ns1:anyIMDN\"/>\n    </xs:sequence>\n  </xs:group>\n  <!-- processing-notification <status> extension point -->\n  <xs:group name=\"processingExtension\">\n    <xs:sequence>\n      <xs:group minOccurs=\"0\" maxOccurs=\"unbounded\" ref=\"ns1:anyIMDN\"/>\n    </xs:sequence>\n  </xs:group>\n  <!--\n    wildcard definition for complex elements (of mixed type)\n    unqualified or qualified in the imdn namespace.\n    Extension schemas MUST redefine this or the\n    individual, previous definitions that use this definition.\n    In other words, the extension schema MUST reduce the\n    allowable content in order to maintain deterministic\n    and unambiguous schemas with the interleave pattern.\n  -->\n  <xs:group name=\"anyIMDN\">\n    <xs:sequence>\n      <xs:any namespace=\"##other\" processContents=\"skip\"/>\n    </xs:sequence>\n  </xs:group>\n  <!-- the rest of the \"anyIMDN\" wildcard definition -->\n  <xs:group name=\"anyExtension\">\n    <xs:sequence>\n      <xs:group minOccurs=\"0\" maxOccurs=\"unbounded\" ref=\"ns1:any\"/>\n    </xs:sequence>\n  </xs:group>\n  <xs:attributeGroup name=\"anyExtension\">\n    <xs:anyAttribute processContents=\"skip\"/>\n  </xs:attributeGroup>\n  <!--\n    wildcard type for complex elements (of mixed type)\n    without any namespace or content restrictions\n  -->\n  <xs:group name=\"any\">\n    <xs:sequence>\n      <xs:any processContents=\"skip\"/>\n    </xs:sequence>\n  </xs:group>\n</xs:schema>\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/oma-common-policy.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--\n\tXDM - Common Policy\n\t    version - 1.0\n\t    date    - 27 Jun 2008\n\n    FILE INFORMATION\n\n\tOMA Permanent Document\n\t   File: OMA-SUP-XSD_xdm_commonPolicy-V1_0_2-20080627-A\n\t   Type: Text - Schema Description\n\n\tPublic Reachable Information\n\t   Path: http://www.openmobilealliance.org/tech/profiles\n\t   Name: xdm_commonPolicy-v1_0.xsd\n\n    NORMATIVE INFORMATION\n\n\tInformation about this file can be found in the specification\n\t    OMA-TS-XDM_Core-V1_1\n\tavailable at http://www.openmobilealliance.org/\n\n\tSend comments to technical-comments@mail.openmobilealliance.org\n\n    LEGAL DISCLAIMER\n\n\tUse of this document is subject to all of the terms and conditions\n\tof the Use Agreement located at\n\t\thttp://www.openmobilealliance.org/UseAgreement.html\n\n\tYou may use this document or any part of the document for internal\n\tor educational purposes only, provided you do not modify, edit or\n\ttake out of context the information in this document in any manner.\n\tInformation contained in this document may be used, at your sole\n\trisk, for any purposes.\n\n\tYou may not use this document in any other manner without the prior\n\twritten permission of the Open Mobile Alliance.  The Open Mobile\n\tAlliance authorizes you to copy this document, provided that you\n\tretain all copyright and other proprietary notices contained in the\n\toriginal materials on any copies of the materials and that you\n\tcomply strictly with these terms.  This copyright permission does\n\tnot constitute an endorsement of the products or services.  The\n\tOpen Mobile Alliance assumes no responsibility for errors or\n\tomissions in this document.\n\n\tEach Open Mobile Alliance member has agreed to use reasonable\n\tendeavors to inform the Open Mobile Alliance in a timely manner of\n\tEssential IPR as it becomes aware that the Essential IPR is related\n\tto the prepared or published specification.  However, the members\n\tdo not have an obligation to conduct IPR searches.  The declared\n\tEssential IPR is publicly available to members and non-members of\n\tthe Open Mobile Alliance and may be found on the \"OMA IPR\n\tDeclarations\" list at http://www.openmobilealliance.org/ipr.html.\n\tThe Open Mobile Alliance has not conducted an independent IPR review\n\tof this document and the information contained herein, and makes no\n\trepresentations or warranties regarding third party IPR, including\n\twithout limitation patents, copyrights or trade secret rights.  This\n\tdocument may contain inventions for which you must obtain licenses\n\tfrom third parties before making, using or selling the inventions.\n\tDefined terms above are set forth in the schedule to the Open Mobile\n\tAlliance Application Form.\n\n\tNO REPRESENTATIONS OR WARRANTIES (WHETHER EXPRESS OR IMPLIED) ARE\n\tMADE BY THE OPEN MOBILE ALLIANCE OR ANY OPEN MOBILE ALLIANCE MEMBER\n\tOR ITS AFFILIATES REGARDING ANY OF THE IPR'S REPRESENTED ON THE \"OMA\n\tIPR DECLARATIONS\" LIST, INCLUDING, BUT NOT LIMITED TO THE ACCURACY,\n\tCOMPLETENESS, VALIDITY OR RELEVANCE OF THE INFORMATION OR WHETHER OR\n\tNOT SUCH RIGHTS ARE ESSENTIAL OR NON-ESSENTIAL.\n\n\tTHE OPEN MOBILE ALLIANCE IS NOT LIABLE FOR AND HEREBY DISCLAIMS ANY\n\tDIRECT, INDIRECT, PUNITIVE, SPECIAL, INCIDENTAL, CONSEQUENTIAL, OR\n\tEXEMPLARY DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE USE OF\n\tDOCUMENTS AND THE INFORMATION CONTAINED IN THE DOCUMENTS.\n\n\tCopyright 2008 Open Mobile Alliance Ltd.  All Rights Reserved.\n\tUsed with the permission of the Open Mobile Alliance Ltd. under the\n\tterms set forth above.\n-->\n\n<xs:schema targetNamespace=\"urn:oma:xml:xdm:common-policy\"\n   xmlns=\"urn:oma:xml:xdm:common-policy\"\n   xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n   elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n\n   <!-- OMA specific \"conditions\" child elements -->\n   <xs:element name=\"other-identity\" type=\"emptyType\"/>\n\n   <xs:element name=\"external-list\">\n     <xs:complexType>\n       <xs:sequence>\n         <xs:element name=\"entry\" type=\"anchorType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       </xs:sequence>\n     </xs:complexType>\n   </xs:element>\n\n  <xs:element name=\"anonymous-request\" type=\"emptyType\"/>\n\n  <xs:complexType name=\"anchorType\">\n    <xs:attribute name=\"anc\" type=\"xs:anyURI\"/>\n    <xs:anyAttribute processContents=\"lax\"/>\n  </xs:complexType>\n\n  <xs:complexType name=\"emptyType\"/>\n\n</xs:schema>\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/oma-pres-content.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:oma:xml:prs:pres-content\"\n   xmlns=\"urn:oma:xml:prs:pres-content\"\n   xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" \n   elementFormDefault=\"qualified\" \n   attributeFormDefault=\"unqualified\">\n\n   <xs:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n\n   <xs:element name=\"content\">\n      <xs:complexType>\n         <xs:sequence>\n            <xs:element name=\"mime-type\" minOccurs=\"0\">\n               <xs:complexType>\n                  <xs:simpleContent>\n                     <xs:extension base=\"xs:string\">\n                        <xs:anyAttribute processContents=\"lax\"/>\n                     </xs:extension>\n                  </xs:simpleContent>\n               </xs:complexType>\n            </xs:element>\n\n            <xs:element name=\"encoding\" minOccurs=\"0\">\n               <xs:complexType>\n                  <xs:simpleContent>\n                     <xs:extension base=\"xs:string\">\n                        <xs:anyAttribute processContents=\"lax\"/>\n                     </xs:extension>\n                  </xs:simpleContent>\n               </xs:complexType>\n            </xs:element>\n\n            <xs:element name=\"description\" minOccurs=\"0\" maxOccurs=\"unbounded\">\n               <xs:complexType>\n                  <xs:simpleContent>\n                    <xs:extension base=\"xs:string\">\n                      <xs:attribute ref=\"xml:lang\"/>\n                       <xs:anyAttribute processContents=\"lax\"/>\n                    </xs:extension>\n                  </xs:simpleContent>\n               </xs:complexType>\n            </xs:element>\n\n            <xs:element name=\"data\">\n               <xs:complexType>\n                  <xs:simpleContent>\n                     <xs:extension base=\"xs:string\">\n                        <xs:anyAttribute processContents=\"lax\"/>\n                     </xs:extension>\n                  </xs:simpleContent>\n               </xs:complexType>\n            </xs:element>\n\n            <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n         </xs:sequence>\n         <xs:anyAttribute processContents=\"lax\"/>\n      </xs:complexType>\n   </xs:element>\n\n</xs:schema>\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/patchops.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE schema [\n<!ENTITY ncname \"\\i\\c*\">\n    <!ENTITY qname  \"(&ncname;:)?&ncname;\">\n    <!ENTITY aname  \"@&qname;\">\n    <!ENTITY pos    \"\\[\\d+\\]\">\n\n    <!ENTITY attr   \"\\[&aname;='(.)*'\\]|\\[&aname;=&quot;(.)*&quot;\\]\">\n    <!ENTITY valueq \"\\[(&qname;|\\.)=&quot;(.)*&quot;\\]\">\n    <!ENTITY value  \"\\[(&qname;|\\.)='(.)*'\\]|&valueq;\">\n    <!ENTITY cond   \"&attr;|&value;|&pos;\">\n    <!ENTITY step   \"(&qname;|\\*)(&cond;)*\">\n    <!ENTITY piq    \"processing-instruction\\((&quot;&ncname;&quot;)\\)\">\n    <!ENTITY pi     \"processing-instruction\\(('&ncname;')?\\)|&piq;\">\n    <!ENTITY id     \"id\\(('&ncname;')?\\)|id\\((&quot;&ncname;&quot;)?\\)\">\n    <!ENTITY com    \"comment\\(\\)\">\n    <!ENTITY text   \"text\\(\\)\">\n    <!ENTITY nspa   \"namespace::&ncname;\">\n    <!ENTITY cnodes \"(&text;(&pos;)?)|(&com;(&pos;)?)|((&pi;)(&pos;)?)\">\n    <!ENTITY child  \"&cnodes;|&step;\">\n    <!ENTITY last   \"(&child;|&aname;|&nspa;)\">\n    ]>\n    <xsd:schema\n        xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n        elementFormDefault=\"qualified\">\n\n        <xsd:simpleType name=\"xpath\">\n            <xsd:restriction base=\"xsd:string\">\n                <xsd:pattern\n                    value=\"(/)?((&id;)((/&step;)*(/&last;))?|(&step;/)*(&last;))\"/>\n            </xsd:restriction>\n        </xsd:simpleType>\n\n        <xsd:simpleType name=\"xpath-add\">\n            <xsd:restriction base=\"xsd:string\">\n                <xsd:pattern\n                    value=\"(/)?((&id;)((/&step;)*(/&child;))?|(&step;/)*(&child;))\"/>\n            </xsd:restriction>\n        </xsd:simpleType>\n\n        <xsd:simpleType name=\"pos\">\n            <xsd:restriction base=\"xsd:string\">\n                <xsd:enumeration value=\"before\"/>\n                <xsd:enumeration value=\"after\"/>\n                <xsd:enumeration value=\"prepend\"/>\n            </xsd:restriction>\n        </xsd:simpleType>\n\n        <xsd:simpleType name=\"type\">\n            <xsd:restriction base=\"xsd:string\">\n                <xsd:pattern value=\"&aname;|&nspa;\"/>\n            </xsd:restriction>\n        </xsd:simpleType>\n\n        <xsd:complexType name=\"add\">\n            <xsd:complexContent mixed=\"true\">\n                <xsd:restriction base=\"xsd:anyType\">\n                    <xsd:sequence>\n                        <xsd:any processContents=\"lax\" namespace=\"##any\"\n                            minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n                    </xsd:sequence>\n                    <xsd:attribute name=\"sel\" type=\"xpath-add\"\n                        use=\"required\"/>\n                    <xsd:attribute name=\"pos\" type=\"pos\"/>\n                    <xsd:attribute name=\"type\" type=\"type\"/>\n                </xsd:restriction>\n            </xsd:complexContent>\n        </xsd:complexType>\n\n        <xsd:complexType name=\"replace\">\n            <xsd:complexContent mixed=\"true\">\n                <xsd:restriction base=\"xsd:anyType\">\n                    <xsd:sequence>\n                        <xsd:any processContents=\"lax\" namespace=\"##any\"\n                            minOccurs=\"0\" maxOccurs=\"1\"/>\n                    </xsd:sequence>\n                    <xsd:attribute name=\"sel\" type=\"xpath\" use=\"required\"/>\n                </xsd:restriction>\n            </xsd:complexContent>\n        </xsd:complexType>\n\n        <xsd:simpleType name=\"ws\">\n            <xsd:restriction base=\"xsd:string\">\n                <xsd:enumeration value=\"before\"/>\n                <xsd:enumeration value=\"after\"/>\n                <xsd:enumeration value=\"both\"/>\n            </xsd:restriction>\n        </xsd:simpleType>\n\n        <xsd:complexType name=\"remove\">\n            <xsd:attribute name=\"sel\" type=\"xpath\" use=\"required\"/>\n            <xsd:attribute name=\"ws\" type=\"ws\"/>\n        </xsd:complexType>\n\n    </xsd:schema>\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/pidf.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:ietf:params:xml:ns:pidf\"\n    xmlns:tns=\"urn:ietf:params:xml:ns:pidf\"\n    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n    elementFormDefault=\"qualified\"\n    attributeFormDefault=\"unqualified\">\n\n  <!-- This import brings in the XML language attribute xml:lang-->\n  <xs:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n\n  <xs:element name=\"presence\" type=\"tns:presence\"/>\n\n  <xs:complexType name=\"presence\">\n    <xs:sequence>\n      <xs:element name=\"tuple\" type=\"tns:tuple\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xs:element name=\"note\" type=\"tns:note\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"entity\" type=\"xs:anyURI\" use=\"required\"/>\n  </xs:complexType>\n\n  <xs:complexType name=\"tuple\">\n    <xs:sequence>\n      <xs:element name=\"status\" type=\"tns:status\"/>\n      <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xs:element name=\"contact\" type=\"tns:contact\" minOccurs=\"0\"/>\n      <xs:element name=\"note\" type=\"tns:note\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xs:element name=\"timestamp\" type=\"xs:dateTime\" minOccurs=\"0\"/>\n    </xs:sequence>\n    <xs:attribute name=\"id\" type=\"xs:ID\" use=\"required\"/>\n  </xs:complexType>\n\n  <xs:complexType name=\"status\">\n    <xs:sequence>\n      <xs:element name=\"basic\" type=\"tns:basic\" minOccurs=\"0\"/>\n      <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n  </xs:complexType>\n\n  <xs:simpleType name=\"basic\">\n    <xs:restriction base=\"xs:string\">\n      <xs:enumeration value=\"open\"/>\n      <xs:enumeration value=\"closed\"/>\n    </xs:restriction>\n  </xs:simpleType>\n\n  <xs:complexType name=\"contact\">\n    <xs:simpleContent>\n      <xs:extension base=\"xs:anyURI\">\n        <xs:attribute name=\"priority\" type=\"tns:qvalue\"/>\n      </xs:extension>\n    </xs:simpleContent>\n  </xs:complexType>\n\n  <xs:complexType name=\"note\">\n    <xs:simpleContent>\n      <xs:extension base=\"xs:string\">\n        <xs:attribute ref=\"xml:lang\"/>\n      </xs:extension>\n    </xs:simpleContent>\n  </xs:complexType>\n\n  <xs:simpleType name=\"qvalue\">\n    <xs:restriction base=\"xs:decimal\">\n      <xs:pattern value=\"0(.[0-9]{0,3})?\"/>\n      <xs:pattern value=\"1(.0{0,3})?\"/>\n    </xs:restriction>\n  </xs:simpleType>\n\n  <!-- Global Attributes -->\n  <xs:attribute name=\"mustUnderstand\" type=\"xs:boolean\" default=\"0\">\n    <xs:annotation>\n      <xs:documentation>\n        This attribute may be used on any element within an optional\n        PIDF extension to indicate that the corresponding element must\n        be understood by the PIDF processor if the enclosing optional\n        element is to be handled.\n      </xs:documentation>\n    </xs:annotation>\n  </xs:attribute>\n\n</xs:schema>\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/pres-rules.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:ietf:params:xml:ns:pres-rules\"\n    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:cr=\"urn:ietf:params:xml:ns:common-policy\"\n    xmlns:pr=\"urn:ietf:params:xml:ns:pres-rules\"\n    elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n\n   <xs:import namespace=\"urn:ietf:params:xml:ns:common-policy\" schemaLocation=\"common-policy.xsd\"/>\n\n   <xs:simpleType name=\"booleanPermission\">\n    <xs:restriction base=\"xs:boolean\"/>\n   </xs:simpleType>\n\n   <xs:element name=\"service-uri-scheme\" type=\"xs:token\"/>\n   <xs:element name=\"class\" type=\"xs:token\"/>\n   <xs:element name=\"occurrence-id\" type=\"xs:token\"/>\n   <xs:element name=\"service-uri\" type=\"xs:anyURI\"/>\n\n   <xs:complexType name=\"provideServicePermission\">\n    <xs:choice>\n     <xs:element name=\"all-services\">\n      <xs:complexType/>\n     </xs:element>\n     <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xs:choice>\n       <xs:element ref=\"pr:service-uri\"/>\n       <xs:element ref=\"pr:service-uri-scheme\"/>\n       <xs:element ref=\"pr:occurrence-id\"/>\n       <xs:element ref=\"pr:class\"/>\n       <xs:any namespace=\"##other\" processContents=\"lax\"/>\n      </xs:choice>\n     </xs:sequence>\n    </xs:choice>\n   </xs:complexType>\n\n   <xs:element name=\"provide-services\" type=\"pr:provideServicePermission\"/>\n   <xs:element name=\"deviceID\" type=\"xs:anyURI\"/>\n\n   <xs:complexType name=\"provideDevicePermission\">\n    <xs:choice>\n     <xs:element name=\"all-devices\">\n      <xs:complexType/>\n     </xs:element>\n     <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xs:choice>\n       <xs:element ref=\"pr:deviceID\"/>\n       <xs:element ref=\"pr:occurrence-id\"/>\n       <xs:element ref=\"pr:class\"/>\n       <xs:any namespace=\"##other\" processContents=\"lax\"/>\n      </xs:choice>\n     </xs:sequence>\n    </xs:choice>\n   </xs:complexType>\n\n   <xs:element name=\"provide-devices\" type=\"pr:provideDevicePermission\"/>\n\n   <xs:complexType name=\"providePersonPermission\">\n    <xs:choice>\n     <xs:element name=\"all-persons\">\n      <xs:complexType/>\n     </xs:element>\n     <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xs:choice>\n       <xs:element ref=\"pr:occurrence-id\"/>\n       <xs:element ref=\"pr:class\"/>\n       <xs:any namespace=\"##other\" processContents=\"lax\"/>\n      </xs:choice>\n     </xs:sequence>\n    </xs:choice>\n   </xs:complexType>\n\n   <xs:element name=\"provide-persons\" type=\"pr:providePersonPermission\"/>\n   <xs:element name=\"provide-activities\" type=\"pr:booleanPermission\"/>\n   <xs:element name=\"provide-class\" type=\"pr:booleanPermission\"/>\n   <xs:element name=\"provide-deviceID\" type=\"pr:booleanPermission\"/>\n   <xs:element name=\"provide-mood\" type=\"pr:booleanPermission\"/>\n   <xs:element name=\"provide-place-is\" type=\"pr:booleanPermission\"/>\n   <xs:element name=\"provide-place-type\" type=\"pr:booleanPermission\"/>\n   <xs:element name=\"provide-privacy\" type=\"pr:booleanPermission\"/>\n   <xs:element name=\"provide-relationship\" type=\"pr:booleanPermission\"/>\n   <xs:element name=\"provide-status-icon\" type=\"pr:booleanPermission\"/>\n   <xs:element name=\"provide-sphere\" type=\"pr:booleanPermission\"/>\n   <xs:element name=\"provide-time-offset\" type=\"pr:booleanPermission\"/>\n\n   <xs:element name=\"provide-user-input\">\n    <xs:simpleType>\n     <xs:restriction base=\"xs:string\">\n      <xs:enumeration value=\"false\"/>\n      <xs:enumeration value=\"bare\"/>\n      <xs:enumeration value=\"thresholds\"/>\n      <xs:enumeration value=\"full\"/>\n     </xs:restriction>\n    </xs:simpleType>\n   </xs:element>\n\n   <xs:element name=\"provide-note\" type=\"pr:booleanPermission\"/>\n\n   <xs:element name=\"sub-handling\">\n    <xs:simpleType>\n     <xs:restriction base=\"xs:token\">\n      <xs:enumeration value=\"block\"/>\n      <xs:enumeration value=\"confirm\"/>\n      <xs:enumeration value=\"polite-block\"/>\n      <xs:enumeration value=\"allow\"/>\n     </xs:restriction>\n    </xs:simpleType>\n   </xs:element>\n\n   <xs:complexType name=\"unknownBooleanPermission\">\n    <xs:simpleContent>\n     <xs:extension base=\"pr:booleanPermission\">\n      <xs:attribute name=\"name\" type=\"xs:string\" use=\"required\"/>\n      <xs:attribute name=\"ns\" type=\"xs:string\" use=\"required\"/>\n     </xs:extension>\n    </xs:simpleContent>\n   </xs:complexType>\n\n   <xs:element name=\"provide-unknown-attribute\" type=\"pr:unknownBooleanPermission\"/>\n\n   <xs:element name=\"provide-all-attributes\">\n    <xs:complexType/>\n   </xs:element>\n\n</xs:schema>\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/resourcelists.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:ietf:params:xml:ns:resource-lists\"\n    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns=\"urn:ietf:params:xml:ns:resource-lists\"\n    elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n\n   <xs:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n\n   <xs:complexType name=\"listType\">\n    <xs:sequence>\n     <xs:element name=\"display-name\" type=\"display-nameType\" minOccurs=\"0\"/>\n     <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xs:choice>\n       <xs:element name=\"list\">\n        <xs:complexType>\n         <xs:complexContent>\n          <xs:extension base=\"listType\"/>\n         </xs:complexContent>\n        </xs:complexType>\n       </xs:element>\n       <xs:element name=\"external\" type=\"externalType\"/>\n       <xs:element name=\"entry\" type=\"entryType\"/>\n       <xs:element name=\"entry-ref\" type=\"entry-refType\"/>\n      </xs:choice>\n     </xs:sequence>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"name\" type=\"xs:string\" use=\"optional\"/>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <xs:complexType name=\"entryType\">\n    <xs:sequence>\n     <xs:element name=\"display-name\" minOccurs=\"0\">\n      <xs:complexType>\n       <xs:simpleContent>\n        <xs:extension base=\"display-nameType\"/>\n       </xs:simpleContent>\n      </xs:complexType>\n     </xs:element>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"uri\" type=\"xs:anyURI\" use=\"required\"/>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <xs:complexType name=\"entry-refType\">\n    <xs:sequence>\n     <xs:element name=\"display-name\" type=\"display-nameType\" minOccurs=\"0\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"ref\" type=\"xs:anyURI\" use=\"required\"/>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <xs:complexType name=\"externalType\">\n    <xs:sequence>\n     <xs:element name=\"display-name\" type=\"display-nameType\" minOccurs=\"0\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"anchor\" type=\"xs:anyURI\"/>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <xs:element name=\"resource-lists\">\n    <xs:complexType>\n     <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xs:element name=\"list\" type=\"listType\"/>\n     </xs:sequence>\n    </xs:complexType>\n   </xs:element>\n\n   <xs:complexType name=\"display-nameType\">\n    <xs:simpleContent>\n     <xs:extension base=\"xs:string\">\n      <xs:attribute ref=\"xml:lang\"/>\n     </xs:extension>\n    </xs:simpleContent>\n   </xs:complexType>\n\n</xs:schema>\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/rlmi.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:ietf:params:xml:ns:rlmi\"\n    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns=\"urn:ietf:params:xml:ns:rlmi\"\n    elementFormDefault=\"qualified\">\n\n  <xs:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n\n  <xs:element name=\"list\">\n    <xs:complexType>\n      <xs:sequence>\n        <xs:element ref=\"name\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        <xs:element ref=\"resource\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xs:sequence>\n      <xs:attribute name=\"uri\" type=\"xs:anyURI\" use=\"required\"/>\n      <xs:attribute name=\"version\" type=\"xs:unsignedInt\" use=\"required\"/>\n      <xs:attribute name=\"fullState\" type=\"xs:boolean\" use=\"required\"/>\n      <xs:attribute name=\"cid\" type=\"xs:string\" use=\"optional\"/>\n      <xs:anyAttribute processContents=\"lax\"/>\n    </xs:complexType>\n  </xs:element>\n\n  <xs:element name=\"resource\">\n    <xs:complexType>\n      <xs:sequence>\n        <xs:element ref=\"name\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        <xs:element ref=\"instance\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xs:sequence>\n      <xs:attribute name=\"uri\" type=\"xs:anyURI\" use=\"required\"/>\n      <xs:anyAttribute processContents=\"lax\"/>\n    </xs:complexType>\n  </xs:element>\n\n  <xs:element name=\"instance\">\n    <xs:complexType>\n      <xs:sequence>\n        <xs:any minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\"/>\n      </xs:sequence>\n      <xs:attribute name=\"id\" type=\"xs:string\" use=\"required\"/>\n      <xs:attribute name=\"state\" use=\"required\">\n        <xs:simpleType>\n          <xs:restriction base=\"xs:string\">\n            <xs:enumeration value=\"active\"/>\n            <xs:enumeration value=\"pending\"/>\n            <xs:enumeration value=\"terminated\"/>\n          </xs:restriction>\n        </xs:simpleType>\n      </xs:attribute>\n      <xs:attribute name=\"reason\" type=\"xs:string\" use=\"optional\"/>\n      <xs:attribute name=\"cid\" type=\"xs:string\" use=\"optional\"/>\n      <xs:anyAttribute processContents=\"lax\"/>\n    </xs:complexType>\n  </xs:element>\n\n  <xs:element name=\"name\">\n    <xs:complexType>\n      <xs:simpleContent>\n        <xs:extension base=\"xs:string\">\n          <xs:attribute ref=\"xml:lang\" use=\"optional\"/>\n        </xs:extension>\n      </xs:simpleContent>\n    </xs:complexType>\n  </xs:element>\n\n</xs:schema>\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/rlsservices.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:ietf:params:xml:ns:rls-services\"\n    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns=\"urn:ietf:params:xml:ns:rls-services\"\n    xmlns:rl=\"urn:ietf:params:xml:ns:resource-lists\"\n    elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n\n   <xs:import namespace=\"urn:ietf:params:xml:ns:resource-lists\" schemaLocation=\"resourcelists.xsd\"/>\n\n   <xs:element name=\"rls-services\">\n    <xs:complexType>\n     <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xs:element name=\"service\" type=\"serviceType\"/>\n     </xs:sequence>\n    </xs:complexType>\n   </xs:element>\n\n   <xs:complexType name=\"serviceType\">\n    <xs:sequence>\n     <xs:choice>\n      <xs:element name=\"resource-list\" type=\"xs:anyURI\"/>\n      <xs:element name=\"list\" type=\"rl:listType\"/>\n     </xs:choice>\n     <xs:element name=\"packages\" type=\"packagesType\" minOccurs=\"0\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n    <xs:attribute name=\"uri\" type=\"xs:anyURI\" use=\"required\"/>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\"/>\n   </xs:complexType>\n\n   <xs:complexType name=\"packagesType\">\n    <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n     <xs:element name=\"package\" type=\"packageType\"/>\n     <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xs:sequence>\n   </xs:complexType>\n\n   <xs:simpleType name=\"packageType\">\n    <xs:restriction base=\"xs:string\"/>\n   </xs:simpleType>\n\n</xs:schema>\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/rpid.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n  <xs:schema targetNamespace=\"urn:ietf:params:xml:ns:pidf:rpid\"\n      xmlns=\"urn:ietf:params:xml:ns:pidf:rpid\"\n      xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\"\n      xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n      elementFormDefault=\"qualified\"\n      attributeFormDefault=\"unqualified\">\n\n    <xs:include schemaLocation=\"common-schema.xsd\"/>\n\n    <xs:simpleType name=\"activeIdle\">\n      <xs:restriction base=\"xs:string\">\n        <xs:enumeration value=\"active\"/>\n        <xs:enumeration value=\"idle\"/>\n      </xs:restriction>\n    </xs:simpleType>\n\n    <xs:element name=\"activities\">\n      <xs:annotation>\n        <xs:documentation>\n          Describes what the person is currently doing, expressed as\n          an enumeration of activity-describing elements.  A person\n          can be engaged in multiple activities at the same time,\n          e.g., traveling and having a meal.\n        </xs:documentation>\n      </xs:annotation>\n      <xs:complexType>\n        <xs:sequence>\n          <xs:element name=\"note\" type=\"Note_t\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n          <xs:choice>\n            <xs:element name=\"unknown\" type=\"empty\" minOccurs=\"0\"/>\n            <xs:sequence maxOccurs=\"unbounded\">\n              <xs:choice>\n                <xs:element name=\"appointment\"       type=\"empty\" />\n                <xs:element name=\"away\"              type=\"empty\" />\n                <xs:element name=\"breakfast\"         type=\"empty\" />\n                <xs:element name=\"busy\"              type=\"empty\" />\n                <xs:element name=\"dinner\"            type=\"empty\" />\n                <xs:element name=\"holiday\"           type=\"empty\" />\n                <xs:element name=\"in-transit\"        type=\"empty\" />\n                <xs:element name=\"looking-for-work\"  type=\"empty\" />\n                <xs:element name=\"meal\"              type=\"empty\" />\n                <xs:element name=\"meeting\"           type=\"empty\" />\n                <xs:element name=\"on-the-phone\"      type=\"empty\" />\n                <xs:element name=\"performance\"       type=\"empty\" />\n                <xs:element name=\"permanent-absence\" type=\"empty\" />\n                <xs:element name=\"playing\"           type=\"empty\" />\n                <xs:element name=\"presentation\"      type=\"empty\" />\n                <xs:element name=\"shopping\"          type=\"empty\" />\n                <xs:element name=\"sleeping\"          type=\"empty\" />\n                <xs:element name=\"spectator\"         type=\"empty\" />\n                <xs:element name=\"steering\"          type=\"empty\" />\n                <xs:element name=\"travel\"            type=\"empty\" />\n                <xs:element name=\"tv\"                type=\"empty\" />\n                <xs:element name=\"vacation\"          type=\"empty\" />\n                <xs:element name=\"working\"           type=\"empty\" />\n                <xs:element name=\"worship\"           type=\"empty\" />\n                <xs:element name=\"other\"             type=\"Note_t\" />\n                <xs:any namespace=\"##other\" maxOccurs=\"unbounded\" processContents=\"lax\"/>\n              </xs:choice>\n            </xs:sequence>\n          </xs:choice>\n        </xs:sequence>\n        <xs:attributeGroup ref=\"fromUntil\"/>\n        <xs:attribute name=\"id\" type=\"xs:ID\"/>\n        <xs:anyAttribute namespace=\"##any\" processContents=\"lax\"/>\n      </xs:complexType>\n    </xs:element>\n\n    <xs:element name=\"class\" type=\"xs:token\">\n      <xs:annotation>\n        <xs:documentation>\n          Describes the class of the service, device or person.\n        </xs:documentation>\n      </xs:annotation>\n    </xs:element>\n\n    <xs:element name=\"mood\">\n      <xs:annotation>\n        <xs:documentation>\n          Describes the mood of the presentity.\n        </xs:documentation>\n      </xs:annotation>\n      <xs:complexType>\n        <xs:sequence>\n          <xs:element name=\"note\" type=\"Note_t\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n          <xs:choice>\n            <xs:element name=\"unknown\" type=\"empty\"/>\n            <xs:sequence maxOccurs=\"unbounded\">\n              <xs:choice>\n                <xs:element name=\"afraid\"       type=\"empty\"/>\n                <xs:element name=\"amazed\"       type=\"empty\"/>\n                <xs:element name=\"angry\"        type=\"empty\"/>\n                <xs:element name=\"annoyed\"      type=\"empty\"/>\n                <xs:element name=\"anxious\"      type=\"empty\"/>\n                <xs:element name=\"ashamed\"      type=\"empty\"/>\n                <xs:element name=\"bored\"        type=\"empty\"/>\n                <xs:element name=\"brave\"        type=\"empty\"/>\n                <xs:element name=\"calm\"         type=\"empty\"/>\n                <xs:element name=\"cold\"         type=\"empty\"/>\n                <xs:element name=\"confused\"     type=\"empty\"/>\n                <xs:element name=\"contented\"    type=\"empty\"/>\n                <xs:element name=\"cranky\"       type=\"empty\"/>\n                <xs:element name=\"curious\"      type=\"empty\"/>\n                <xs:element name=\"depressed\"    type=\"empty\"/>\n                <xs:element name=\"disappointed\" type=\"empty\"/>\n                <xs:element name=\"disgusted\"    type=\"empty\"/>\n                <xs:element name=\"distracted\"   type=\"empty\"/>\n                <xs:element name=\"embarrassed\"  type=\"empty\"/>\n                <xs:element name=\"excited\"      type=\"empty\"/>\n                <xs:element name=\"flirtatious\"  type=\"empty\"/>\n                <xs:element name=\"frustrated\"   type=\"empty\"/>\n                <xs:element name=\"grumpy\"       type=\"empty\"/>\n                <xs:element name=\"guilty\"       type=\"empty\"/>\n                <xs:element name=\"happy\"        type=\"empty\"/>\n                <xs:element name=\"hot\"          type=\"empty\"/>\n                <xs:element name=\"humbled\"      type=\"empty\"/>\n                <xs:element name=\"humiliated\"   type=\"empty\"/>\n                <xs:element name=\"hungry\"       type=\"empty\"/>\n                <xs:element name=\"hurt\"         type=\"empty\"/>\n                <xs:element name=\"impressed\"    type=\"empty\"/>\n                <xs:element name=\"in_awe\"       type=\"empty\"/>\n                <xs:element name=\"in_love\"      type=\"empty\"/>\n                <xs:element name=\"indignant\"    type=\"empty\"/>\n                <xs:element name=\"interested\"   type=\"empty\"/>\n                <xs:element name=\"invincible\"   type=\"empty\"/>\n                <xs:element name=\"jealous\"      type=\"empty\"/>\n                <xs:element name=\"lonely\"       type=\"empty\"/>\n                <xs:element name=\"mean\"         type=\"empty\"/>\n                <xs:element name=\"moody\"        type=\"empty\"/>\n                <xs:element name=\"nervous\"      type=\"empty\"/>\n                <xs:element name=\"neutral\"      type=\"empty\"/>\n                <xs:element name=\"offended\"     type=\"empty\"/>\n                <xs:element name=\"playful\"      type=\"empty\"/>\n                <xs:element name=\"proud\"        type=\"empty\"/>\n                <xs:element name=\"relieved\"     type=\"empty\"/>\n                <xs:element name=\"remorseful\"   type=\"empty\"/>\n                <xs:element name=\"restless\"     type=\"empty\"/>\n                <xs:element name=\"sad\"          type=\"empty\"/>\n                <xs:element name=\"sarcastic\"    type=\"empty\"/>\n                <xs:element name=\"serious\"      type=\"empty\"/>\n                <xs:element name=\"shocked\"      type=\"empty\"/>\n                <xs:element name=\"shy\"          type=\"empty\"/>\n                <xs:element name=\"sick\"         type=\"empty\"/>\n                <xs:element name=\"sleepy\"       type=\"empty\"/>\n                <xs:element name=\"stressed\"     type=\"empty\"/>\n                <xs:element name=\"surprised\"    type=\"empty\"/>\n                <xs:element name=\"thirsty\"      type=\"empty\"/>\n                <xs:element name=\"worried\"      type=\"empty\"/>\n                <xs:element name=\"other\"        type=\"Note_t\" />\n                <xs:any namespace=\"##other\" maxOccurs=\"unbounded\" processContents=\"lax\"/>\n              </xs:choice>\n            </xs:sequence>\n          </xs:choice>\n        </xs:sequence>\n        <xs:attributeGroup ref=\"fromUntil\"/>\n        <xs:attribute name=\"id\" type=\"xs:ID\"/>\n        <xs:anyAttribute namespace=\"##any\" processContents=\"lax\"/>\n      </xs:complexType>\n    </xs:element>\n\n    <xs:element name=\"place-is\">\n      <xs:complexType>\n        <xs:sequence>\n          <xs:element name=\"note\" type=\"Note_t\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n          <xs:element name=\"audio\" minOccurs=\"0\">\n            <xs:complexType>\n              <xs:choice>\n                <xs:element name=\"noisy\"   type=\"empty\"/>\n                <xs:element name=\"ok\"      type=\"empty\"/>\n                <xs:element name=\"quiet\"   type=\"empty\"/>\n                <xs:element name=\"unknown\" type=\"empty\"/>\n              </xs:choice>\n            </xs:complexType>\n          </xs:element>\n          <xs:element name=\"video\" minOccurs=\"0\">\n            <xs:complexType>\n              <xs:choice>\n                <xs:element name=\"toobright\" type=\"empty\"/>\n                <xs:element name=\"ok\"        type=\"empty\"/>\n                <xs:element name=\"dark\"      type=\"empty\"/>\n                <xs:element name=\"unknown\"   type=\"empty\"/>\n              </xs:choice>\n            </xs:complexType>\n          </xs:element>\n          <xs:element name=\"text\" minOccurs=\"0\">\n            <xs:complexType>\n              <xs:choice>\n                <xs:element name=\"uncomfortable\" type=\"empty\"/>\n                <xs:element name=\"inappropriate\" type=\"empty\"/>\n                <xs:element name=\"ok\"            type=\"empty\"/>\n                <xs:element name=\"unknown\"       type=\"empty\"/>\n              </xs:choice>\n            </xs:complexType>\n          </xs:element>\n        </xs:sequence>\n        <xs:attributeGroup ref=\"fromUntil\"/>\n        <xs:attribute name=\"id\" type=\"xs:ID\"/>\n        <xs:anyAttribute namespace=\"##any\" processContents=\"lax\"/>\n      </xs:complexType>\n    </xs:element>\n\n    <xs:element name=\"place-type\">\n       <xs:annotation>\n         <xs:documentation>\n           Describes the type of place the person is currently at.\n         </xs:documentation>\n       </xs:annotation>\n       <xs:complexType>\n         <xs:sequence>\n           <xs:element name=\"note\" type=\"Note_t\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n           <xs:choice>\n             <xs:element name=\"other\" type=\"Note_t\"/>\n             <xs:any namespace=\"##other\" maxOccurs=\"unbounded\" processContents=\"lax\"/>\n           </xs:choice>\n         </xs:sequence>\n         <xs:attributeGroup ref=\"fromUntil\"/>\n         <xs:attribute name=\"id\" type=\"xs:ID\"/>\n         <xs:anyAttribute namespace=\"##any\" processContents=\"lax\"/>\n       </xs:complexType>\n    </xs:element>\n\n    <xs:element name=\"privacy\">\n      <xs:annotation>\n         <xs:documentation>\n           Indicates which type of communication third parties in the\n           vicinity of the presentity are unlikely to be able to\n           intercept accidentally or intentionally.\n         </xs:documentation>\n      </xs:annotation>\n      <xs:complexType>\n        <xs:sequence>\n          <xs:element name=\"note\" type=\"Note_t\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n          <xs:choice>\n            <xs:element name=\"unknown\" type=\"empty\"/>\n            <xs:sequence>\n              <xs:element name=\"audio\" type=\"empty\" minOccurs=\"0\"/>\n              <xs:element name=\"text\"  type=\"empty\" minOccurs=\"0\"/>\n              <xs:element name=\"video\" type=\"empty\" minOccurs=\"0\"/>\n              <xs:any namespace=\"##other\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\"/>\n            </xs:sequence>\n          </xs:choice>\n        </xs:sequence>\n        <xs:attributeGroup ref=\"fromUntil\"/>\n        <xs:attribute name=\"id\" type=\"xs:ID\"/>\n        <xs:anyAttribute namespace=\"##any\" processContents=\"lax\"/>\n      </xs:complexType>\n    </xs:element>\n\n    <xs:element name=\"relationship\">\n        <xs:annotation>\n           <xs:documentation>\n             Designates the type of relationship an alternate contact\n             has with the presentity.\n           </xs:documentation>\n        </xs:annotation>\n        <xs:complexType>\n          <xs:sequence>\n            <xs:element name=\"note\" type=\"Note_t\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n            <xs:choice>\n               <xs:element name=\"assistant\"  type=\"empty\"/>\n               <xs:element name=\"associate\"  type=\"empty\"/>\n               <xs:element name=\"family\"     type=\"empty\"/>\n               <xs:element name=\"friend\"     type=\"empty\"/>\n               <xs:element name=\"other\"      type=\"Note_t\" minOccurs=\"0\"/>\n               <xs:element name=\"self\"       type=\"empty\"/>\n               <xs:element name=\"supervisor\" type=\"empty\"/>\n               <xs:element name=\"unknown\"    type=\"empty\"/>\n               <xs:any namespace=\"##other\" maxOccurs=\"unbounded\" processContents=\"lax\"/>\n            </xs:choice>\n          </xs:sequence>\n        </xs:complexType>\n    </xs:element>\n\n    <xs:element name=\"service-class\">\n      <xs:annotation>\n        <xs:documentation>\n          Designates the type of service offered.\n        </xs:documentation>\n      </xs:annotation>\n      <xs:complexType>\n        <xs:sequence>\n          <xs:element name=\"note\" type=\"Note_t\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n          <xs:choice>\n            <xs:element name=\"courier\"    type=\"empty\"/>\n            <xs:element name=\"electronic\" type=\"empty\"/>\n            <xs:element name=\"freight\"    type=\"empty\"/>\n            <xs:element name=\"in-person\"  type=\"empty\"/>\n            <xs:element name=\"postal\"     type=\"empty\"/>\n            <xs:element name=\"unknown\"    type=\"empty\"/>\n            <xs:any namespace=\"##other\" maxOccurs=\"unbounded\" processContents=\"lax\"/>\n          </xs:choice>\n        </xs:sequence>\n      </xs:complexType>\n    </xs:element>\n\n    <xs:element name=\"sphere\">\n      <xs:annotation>\n        <xs:documentation>\n          Designates the current state and role that the person plays.\n        </xs:documentation>\n      </xs:annotation>\n      <xs:complexType>\n        <xs:choice minOccurs=\"0\">\n          <xs:element name=\"home\"    type=\"empty\"/>\n          <xs:element name=\"work\"    type=\"empty\"/>\n          <xs:element name=\"unknown\" type=\"empty\"/>\n          <xs:any namespace=\"##other\" maxOccurs=\"unbounded\" processContents=\"lax\"/>\n        </xs:choice>\n        <xs:attributeGroup ref=\"fromUntil\"/>\n        <xs:attribute name=\"id\" type=\"xs:ID\"/>\n        <xs:anyAttribute namespace=\"##any\" processContents=\"lax\"/>\n      </xs:complexType>\n    </xs:element>\n\n    <xs:element name=\"status-icon\">\n      <xs:annotation>\n        <xs:documentation>\n          A URI pointing to an image (icon) representing the current\n          status of the person or service.\n        </xs:documentation>\n      </xs:annotation>\n      <xs:complexType>\n        <xs:simpleContent>\n          <xs:extension base=\"xs:anyURI\">\n            <xs:attributeGroup ref=\"fromUntil\"/>\n            <xs:attribute name=\"id\" type=\"xs:ID\"/>\n            <xs:anyAttribute namespace=\"##any\" processContents=\"lax\"/>\n          </xs:extension>\n        </xs:simpleContent>\n      </xs:complexType>\n    </xs:element>\n\n    <xs:element name=\"time-offset\">\n      <xs:annotation>\n        <xs:documentation>\n          Describes the number of minutes of offset from UTC at the\n          user's current location.\n        </xs:documentation>\n      </xs:annotation>\n      <xs:complexType>\n        <xs:simpleContent>\n          <xs:extension base=\"xs:integer\">\n            <xs:attributeGroup ref=\"fromUntil\"/>\n            <xs:attribute name=\"description\" type=\"xs:string\"/>\n            <xs:attribute name=\"id\" type=\"xs:ID\"/>\n            <xs:anyAttribute namespace=\"##any\" processContents=\"lax\"/>\n          </xs:extension>\n        </xs:simpleContent>\n      </xs:complexType>\n    </xs:element>\n\n    <xs:element name=\"user-input\">\n      <xs:annotation>\n        <xs:documentation>\n          Records the user-input or usage state of the service or device.\n        </xs:documentation>\n      </xs:annotation>\n      <xs:complexType>\n          <xs:simpleContent>\n            <xs:extension base=\"activeIdle\">\n              <xs:attribute name=\"idle-threshold\" type=\"xs:positiveInteger\"/>\n              <xs:attribute name=\"last-input\" type=\"xs:dateTime\"/>\n              <xs:attribute name=\"id\" type=\"xs:ID\"/>\n              <xs:anyAttribute namespace=\"##any\" processContents=\"lax\"/>\n            </xs:extension>\n          </xs:simpleContent>\n      </xs:complexType>\n    </xs:element>\n\n</xs:schema>\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/watcherinfo.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:ietf:params:xml:ns:watcherinfo\"\n    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:tns=\"urn:ietf:params:xml:ns:watcherinfo\">\n\n   <!-- This import brings in the XML language attribute xml:lang-->\n   <xs:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\" />\n\n   <xs:element name=\"watcherinfo\">\n     <xs:complexType>\n       <xs:sequence>\n         <xs:element ref=\"tns:watcher-list\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n         <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       </xs:sequence>\n       <xs:attribute name=\"version\" type=\"xs:nonNegativeInteger\" use=\"required\"/>\n       <xs:attribute name=\"state\" use=\"required\">\n         <xs:simpleType>\n           <xs:restriction base=\"xs:string\">\n             <xs:enumeration value=\"full\"/>\n             <xs:enumeration value=\"partial\"/>\n           </xs:restriction>\n         </xs:simpleType>\n       </xs:attribute>\n     </xs:complexType>\n   </xs:element>\n\n   <xs:element name=\"watcher-list\">\n     <xs:complexType>\n       <xs:sequence>\n         <xs:element ref=\"tns:watcher\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n           <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       </xs:sequence>\n       <xs:attribute name=\"resource\" type=\"xs:anyURI\" use=\"required\"/>\n       <xs:attribute name=\"package\" type=\"xs:string\" use=\"required\"/>\n     </xs:complexType>\n   </xs:element>\n\n   <xs:element name=\"watcher\">\n     <xs:complexType>\n       <xs:simpleContent>\n         <xs:extension base=\"xs:anyURI\">\n           <xs:attribute name=\"display-name\" type=\"xs:string\"/>\n           <xs:attribute name=\"status\" use=\"required\">\n             <xs:simpleType>\n               <xs:restriction base=\"xs:string\">\n                 <xs:enumeration value=\"pending\"/>\n                 <xs:enumeration value=\"active\"/>\n                 <xs:enumeration value=\"waiting\"/>\n                 <xs:enumeration value=\"terminated\"/>\n               </xs:restriction>\n             </xs:simpleType>\n           </xs:attribute>\n           <xs:attribute name=\"event\" use=\"required\">\n             <xs:simpleType>\n               <xs:restriction base=\"xs:string\">\n                 <xs:enumeration value=\"subscribe\"/>\n                 <xs:enumeration value=\"approved\"/>\n                 <xs:enumeration value=\"deactivated\"/>\n                 <xs:enumeration value=\"probation\"/>\n                 <xs:enumeration value=\"rejected\"/>\n                 <xs:enumeration value=\"timeout\"/>\n                 <xs:enumeration value=\"giveup\"/>\n                 <xs:enumeration value=\"noresource\"/>\n               </xs:restriction>\n             </xs:simpleType>\n           </xs:attribute>\n           <xs:attribute name=\"expiration\" type=\"xs:unsignedLong\"/>\n           <xs:attribute name=\"id\" type=\"xs:string\" use=\"required\"/>\n           <xs:attribute name=\"duration-subscribed\" type=\"xs:unsignedLong\"/>\n           <xs:attribute ref=\"xml:lang\"/>\n         </xs:extension>\n       </xs:simpleContent>\n     </xs:complexType>\n   </xs:element>\n\n</xs:schema>\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/xcap-caps.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:ietf:params:xml:ns:xcap-caps\" \n    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" \n    xmlns=\"urn:ietf:params:xml:ns:xcap-caps\" \n    elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n\n   <xs:element name=\"xcap-caps\">\n     <xs:annotation>\n       <xs:documentation>Root element for xcap-caps</xs:documentation>\n     </xs:annotation>\n     <xs:complexType>\n       <xs:sequence>\n         <xs:element name=\"auids\">\n           <xs:annotation>\n             <xs:documentation>List of supported AUID.</xs:documentation>\n           </xs:annotation>\n           <xs:complexType>\n             <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n               <xs:element name=\"auid\" type=\"auidType\"/>\n             </xs:sequence>\n           </xs:complexType>\n         </xs:element>\n         <xs:element name=\"extensions\">\n           <xs:annotation>\n             <xs:documentation>List of supported extensions.</xs:documentation>\n           </xs:annotation>\n           <xs:complexType>\n             <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n               <xs:element name=\"extension\" type=\"extensionType\"/>\n             </xs:sequence>\n           </xs:complexType>\n         </xs:element>\n         <xs:element name=\"namespaces\">\n           <xs:annotation>\n             <xs:documentation>List of supported namespaces.</xs:documentation>\n           </xs:annotation>\n           <xs:complexType>\n             <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n               <xs:element name=\"namespace\" type=\"namespaceType\"/>\n             </xs:sequence>\n           </xs:complexType>\n         </xs:element>\n         <xs:any namespace=\"##other\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       </xs:sequence>\n     </xs:complexType>\n   </xs:element>\n\n   <xs:simpleType name=\"auidType\">\n     <xs:annotation>\n       <xs:documentation>AUID Type</xs:documentation>\n     </xs:annotation>\n     <xs:restriction base=\"xs:string\"/>\n   </xs:simpleType>\n\n   <xs:simpleType name=\"extensionType\">\n     <xs:annotation>\n       <xs:documentation>Extension Type</xs:documentation>\n     </xs:annotation>\n     <xs:restriction base=\"xs:string\"/>\n   </xs:simpleType>\n\n   <xs:simpleType name=\"namespaceType\">\n     <xs:annotation>\n       <xs:documentation>Namespace type</xs:documentation>\n     </xs:annotation>\n     <xs:restriction base=\"xs:anyURI\"/>\n   </xs:simpleType>\n\n</xs:schema>\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/xcap-directory.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"urn:oma:xml:xdm:xcap-directory\"\n    xmlns=\"urn:oma:xml:xdm:xcap-directory\"\n    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n    elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n\n    <xs:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n\n    <xs:element name=\"xcap-directory\">\n      <xs:complexType>\n        <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n          <xs:element name=\"folder\">\n            <xs:complexType>\n              <xs:choice>\n                <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n                  <xs:element name=\"entry\">\n                    <xs:complexType>\n                      <xs:attribute name=\"uri\" type=\"xs:anyURI\" use=\"required\"/>\n                      <xs:attribute name=\"etag\" type=\"xs:string\" use=\"required\"/>\n                      <xs:attribute name=\"last-modified\" type=\"xs:dateTime\"/>\n                      <xs:attribute name=\"size\" type=\"xs:nonNegativeInteger\"/>\n                      <xs:anyAttribute processContents=\"lax\"/>\n                    </xs:complexType>\n                  </xs:element>\n                </xs:sequence>\n                <xs:element name=\"error-code\" type=\"xs:string\"/>\n              </xs:choice>\n              <xs:attribute name=\"auid\" type=\"xs:string\" use=\"required\"/>\n            </xs:complexType>\n          </xs:element>\n        </xs:sequence>\n      </xs:complexType>\n    </xs:element>\n\n</xs:schema>\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/xcapdiff.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns=\"urn:ietf:params:xml:ns:xcap-diff\"\n    targetNamespace=\"urn:ietf:params:xml:ns:xcap-diff\"\n    elementFormDefault=\"qualified\"\n    attributeFormDefault=\"unqualified\">\n\n    <!-- include patch-ops -->\n    <!--<xs:include-->\n        <!--schemaLocation=\"urn:ietf:params:xml:schema:patch-ops\"/>-->\n    <xs:include schemaLocation=\"patchops.xsd\"/>\n\n    <!-- document root -->\n    <xs:element name=\"xcap-diff\">\n        <xs:complexType>\n            <xs:sequence minOccurs=\"0\">\n                <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n                    <xs:choice>\n                        <xs:element name=\"document\" type=\"documentType\"/>\n                        <xs:element name=\"element\" type=\"elementType\"/>\n                        <xs:element name=\"attribute\" type=\"attributeType\"/>\n                    </xs:choice>\n                </xs:sequence>\n                <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n            </xs:sequence>\n            <xs:attribute name=\"xcap-root\" type=\"xs:anyURI\" use=\"required\"/>\n            <xs:anyAttribute processContents=\"lax\"/>\n        </xs:complexType>\n    </xs:element>\n\n    <!-- xcap document type -->\n    <xs:complexType name=\"documentType\">\n        <xs:choice minOccurs=\"0\">\n            <xs:element name=\"body-not-changed\" type=\"emptyType\"/>\n            <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n                <xs:choice>\n                    <xs:element name=\"add\">\n                        <xs:complexType mixed=\"true\">\n                            <xs:complexContent>\n                                <xs:extension base=\"add\">\n                                    <xs:anyAttribute processContents=\"lax\"/>\n                                </xs:extension>\n                            </xs:complexContent>\n                        </xs:complexType>\n                    </xs:element>\n                    <xs:element name=\"remove\">\n                        <xs:complexType>\n                            <xs:complexContent>\n                                <xs:extension base=\"remove\">\n                                    <xs:anyAttribute processContents=\"lax\"/>\n                                </xs:extension>\n                            </xs:complexContent>\n                        </xs:complexType>\n                    </xs:element>\n                    <xs:element name=\"replace\">\n                        <xs:complexType mixed=\"true\">\n                            <xs:complexContent>\n                                <xs:extension base=\"replace\">\n                                    <xs:anyAttribute processContents=\"lax\"/>\n                                </xs:extension>\n                            </xs:complexContent>\n                        </xs:complexType>\n                    </xs:element>\n                    <xs:any namespace=\"##other\" processContents=\"lax\"/>\n                </xs:choice>\n            </xs:sequence>\n        </xs:choice>\n        <xs:attribute name=\"sel\" type=\"xs:anyURI\" use=\"required\"/>\n        <xs:attribute name=\"new-etag\" type=\"xs:string\"/>\n        <xs:attribute name=\"previous-etag\" type=\"xs:string\"/>\n        <xs:anyAttribute processContents=\"lax\"/>\n    </xs:complexType>\n\n    <!-- xcap element type -->\n    <xs:complexType name=\"elementType\">\n        <xs:complexContent mixed=\"true\">\n            <xs:restriction base=\"xs:anyType\">\n                <xs:sequence>\n                    <xs:any processContents=\"lax\" namespace=\"##any\" minOccurs=\"0\" maxOccurs=\"1\"/>\n                </xs:sequence>\n                <xs:attribute name=\"sel\" type=\"xs:string\" use=\"required\"/>\n                <xs:attribute name=\"exists\" type=\"xs:boolean\"/>\n                <xs:anyAttribute processContents=\"lax\"/>\n            </xs:restriction>\n        </xs:complexContent>\n    </xs:complexType>\n\n    <!-- xcap attribute type -->\n    <xs:complexType name=\"attributeType\">\n        <xs:simpleContent>\n            <xs:extension base=\"xs:string\">\n                <xs:attribute name=\"sel\" type=\"xs:string\" use=\"required\"/>\n                <xs:attribute name=\"exists\" type=\"xs:boolean\"/>\n                <xs:anyAttribute processContents=\"lax\"/>\n            </xs:extension>\n        </xs:simpleContent>\n    </xs:complexType>\n\n    <!-- empty type -->\n    <xs:complexType name=\"emptyType\"/>\n</xs:schema>\n\n"
  },
  {
    "path": "sipsimple/payloads/xml-schemas/xml.xsd",
    "content": "<?xml version='1.0'?>\n<!DOCTYPE xs:schema PUBLIC \"-//W3C//DTD XMLSCHEMA 200102//EN\" \"XMLSchema.dtd\" >\n<xs:schema targetNamespace=\"http://www.w3.org/XML/1998/namespace\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xml:lang=\"en\">\n\n <xs:annotation>\n  <xs:documentation>\n   See http://www.w3.org/XML/1998/namespace.html and\n   http://www.w3.org/TR/REC-xml for information about this namespace.\n\n    This schema document describes the XML namespace, in a form\n    suitable for import by other schema documents.  \n\n    Note that local names in this namespace are intended to be defined\n    only by the World Wide Web Consortium or its subgroups.  The\n    following names are currently defined in this namespace and should\n    not be used with conflicting semantics by any Working Group,\n    specification, or document instance:\n\n    base (as an attribute name): denotes an attribute whose value\n         provides a URI to be used as the base for interpreting any\n         relative URIs in the scope of the element on which it\n         appears; its value is inherited.  This name is reserved\n         by virtue of its definition in the XML Base specification.\n\n    lang (as an attribute name): denotes an attribute whose value\n         is a language code for the natural language of the content of\n         any element; its value is inherited.  This name is reserved\n         by virtue of its definition in the XML specification.\n  \n    space (as an attribute name): denotes an attribute whose\n         value is a keyword indicating what whitespace processing\n         discipline is intended for the content of the element; its\n         value is inherited.  This name is reserved by virtue of its\n         definition in the XML specification.\n\n    Father (in any context at all): denotes Jon Bosak, the chair of \n         the original XML Working Group.  This name is reserved by \n         the following decision of the W3C XML Plenary and \n         XML Coordination groups:\n\n             In appreciation for his vision, leadership and dedication\n             the W3C XML Plenary on this 10th day of February, 2000\n             reserves for Jon Bosak in perpetuity the XML name\n             xml:Father\n  </xs:documentation>\n </xs:annotation>\n\n <xs:annotation>\n  <xs:documentation>This schema defines attributes and an attribute group\n        suitable for use by\n        schemas wishing to allow xml:base, xml:lang or xml:space attributes\n        on elements they define.\n\n        To enable this, such a schema must import this schema\n        for the XML namespace, e.g. as follows:\n        &lt;schema . . .>\n         . . .\n         &lt;import namespace=\"http://www.w3.org/XML/1998/namespace\"\n                    schemaLocation=\"http://www.w3.org/2001/03/xml.xsd\"/>\n\n        Subsequently, qualified reference to any of the attributes\n        or the group defined below will have the desired effect, e.g.\n\n        &lt;type . . .>\n         . . .\n         &lt;attributeGroup ref=\"xml:specialAttrs\"/>\n \n         will define a type which will schema-validate an instance\n         element with any of those attributes</xs:documentation>\n </xs:annotation>\n\n <xs:annotation>\n  <xs:documentation>In keeping with the XML Schema WG's standard versioning\n   policy, this schema document will persist at\n   http://www.w3.org/2001/03/xml.xsd.\n   At the date of issue it can also be found at\n   http://www.w3.org/2001/xml.xsd.\n   The schema document at that URI may however change in the future,\n   in order to remain compatible with the latest version of XML Schema\n   itself.  In other words, if the XML Schema namespace changes, the version\n   of this document at\n   http://www.w3.org/2001/xml.xsd will change\n   accordingly; the version at\n   http://www.w3.org/2001/03/xml.xsd will not change.\n  </xs:documentation>\n </xs:annotation>\n\n <xs:attribute name=\"lang\" type=\"xs:language\">\n  <xs:annotation>\n   <xs:documentation>In due course, we should install the relevant ISO 2- and 3-letter\n         codes as the enumerated possible values . . .</xs:documentation>\n  </xs:annotation>\n </xs:attribute>\n\n <xs:attribute name=\"space\" default=\"preserve\">\n  <xs:simpleType>\n   <xs:restriction base=\"xs:NCName\">\n    <xs:enumeration value=\"default\"/>\n    <xs:enumeration value=\"preserve\"/>\n   </xs:restriction>\n  </xs:simpleType>\n </xs:attribute>\n\n <xs:attribute name=\"base\" type=\"xs:anyURI\">\n  <xs:annotation>\n   <xs:documentation>See http://www.w3.org/TR/xmlbase/ for\n                     information about this attribute.</xs:documentation>\n  </xs:annotation>\n </xs:attribute>\n\n <xs:attributeGroup name=\"specialAttrs\">\n  <xs:attribute ref=\"xml:base\"/>\n  <xs:attribute ref=\"xml:lang\"/>\n  <xs:attribute ref=\"xml:space\"/>\n </xs:attributeGroup>\n\n</xs:schema>\n"
  },
  {
    "path": "sipsimple/session.py",
    "content": "\n\"\"\"\nImplements an asynchronous notification based mechanism for\nestablishment, modification and termination of sessions using Session\nInitiation Protocol (SIP) standardized in RFC3261.\n\"\"\"\n\nfrom __future__ import absolute_import\n\n__all__ = ['Session', 'SessionManager']\n\nimport random\n\nfrom threading import RLock\nfrom time import time\n\nfrom application.notification import IObserver, Notification, NotificationCenter, NotificationData\nfrom application.python import Null, limit\nfrom application.python.decorator import decorator, preserve_signature\nfrom application.python.types import Singleton\nfrom application.system import host\nfrom eventlib import api, coros, proc\nfrom twisted.internet import reactor\nfrom zope.interface import implements\n\nfrom sipsimple import log\nfrom sipsimple.account import AccountManager, BonjourAccount\nfrom sipsimple.configuration.settings import SIPSimpleSettings\nfrom sipsimple.core import DialogID, Engine, Invitation, Referral, Subscription, PJSIPError, SIPCoreError, SIPCoreInvalidStateError, SIPURI, sip_status_messages, sipfrag_re\nfrom sipsimple.core import ContactHeader, FromHeader, Header, ReasonHeader, ReferToHeader, ReplacesHeader, RouteHeader, ToHeader, WarningHeader\nfrom sipsimple.core import SDPConnection, SDPMediaStream, SDPSession\nfrom sipsimple.core import PublicGRUU, PublicGRUUIfAvailable, NoGRUU\nfrom sipsimple.lookup import DNSLookup, DNSLookupError\nfrom sipsimple.payloads import ParserError\nfrom sipsimple.payloads.conference import ConferenceDocument\nfrom sipsimple.streams import MediaStreamRegistry, InvalidStreamError, UnknownStreamError\nfrom sipsimple.threading import run_in_twisted_thread\nfrom sipsimple.threading.green import Command, run_in_green_thread\nfrom sipsimple.util import ISOTimestamp\n\n\nclass InvitationDisconnectedError(Exception):\n    def __init__(self, invitation, data):\n        self.invitation = invitation\n        self.data = data\n\n\nclass MediaStreamDidNotInitializeError(Exception):\n    def __init__(self, stream, data):\n        self.stream = stream\n        self.data = data\n\n\nclass MediaStreamDidFailError(Exception):\n    def __init__(self, stream, data):\n        self.stream = stream\n        self.data = data\n\n\nclass SubscriptionError(Exception):\n    def __init__(self, error, timeout, **attributes):\n        self.error = error\n        self.timeout = timeout\n        self.attributes = attributes\n\n\nclass SIPSubscriptionDidFail(Exception):\n    def __init__(self, data):\n        self.data = data\n\n\nclass InterruptSubscription(Exception):\n    pass\n\n\nclass TerminateSubscription(Exception):\n    pass\n\n\nclass ReferralError(Exception):\n    def __init__(self, error, code=0):\n        self.error = error\n        self.code = code\n\n\nclass TerminateReferral(Exception):\n    pass\n\n\nclass SIPReferralDidFail(Exception):\n    def __init__(self, data):\n        self.data = data\n\n\nclass IllegalStateError(RuntimeError):\n    pass\n\n\nclass IllegalDirectionError(RuntimeError):\n    pass\n\n\nclass SIPInvitationTransferDidFail(Exception):\n    def __init__(self, data):\n        self.data = data\n\n\n@decorator\ndef transition_state(required_state, new_state):\n    def state_transitioner(func):\n        @preserve_signature(func)\n        def wrapper(obj, *args, **kwargs):\n            with obj._lock:\n                if obj.state != required_state:\n                    raise IllegalStateError('cannot call %s in %s state' % (func.__name__, obj.state))\n                obj.state = new_state\n            return func(obj, *args, **kwargs)\n        return wrapper\n    return state_transitioner\n\n\n@decorator\ndef check_state(required_states):\n    def state_checker(func):\n        @preserve_signature(func)\n        def wrapper(obj, *args, **kwargs):\n            if obj.state not in required_states:\n                raise IllegalStateError('cannot call %s in %s state' % (func.__name__, obj.state))\n            return func(obj, *args, **kwargs)\n        return wrapper\n    return state_checker\n\n\n@decorator\ndef check_transfer_state(direction, state):\n    def state_checker(func):\n        @preserve_signature(func)\n        def wrapper(obj, *args, **kwargs):\n            if obj.transfer_handler.direction != direction:\n                raise IllegalDirectionError('cannot transfer in %s direction' % obj.transfer_handler.direction)\n            if obj.transfer_handler.state != state:\n                raise IllegalStateError('cannot transfer in %s state' % obj.transfer_handler.state)\n            return func(obj, *args, **kwargs)\n        return wrapper\n    return state_checker\n\n\nclass AddParticipantOperation(object):\n    pass\n\nclass RemoveParticipantOperation(object):\n    pass\n\nclass ReferralHandler(object):\n    implements(IObserver)\n\n    def __init__(self, session, participant_uri, operation):\n        self.participant_uri = participant_uri\n        if not isinstance(self.participant_uri, SIPURI):\n            if not self.participant_uri.startswith(('sip:', 'sips:')):\n                self.participant_uri = 'sip:%s' % self.participant_uri\n            try:\n                self.participant_uri = SIPURI.parse(self.participant_uri)\n            except SIPCoreError:\n                notification_center = NotificationCenter()\n                if operation is AddParticipantOperation:\n                    notification_center.post_notification('SIPConferenceDidNotAddParticipant', sender=session, data=NotificationData(participant=self.participant_uri, code=0, reason='invalid participant URI'))\n                else:\n                    notification_center.post_notification('SIPConferenceDidNotRemoveParticipant', sender=session, data=NotificationData(participant=self.participant_uri, code=0, reason='invalid participant URI'))\n                return\n        self.session = session\n        self.operation = operation\n        self.active = False\n        self.route = None\n        self._channel = coros.queue()\n        self._referral = None\n\n    def start(self):\n        notification_center = NotificationCenter()\n        if not self.session.remote_focus:\n            if self.operation is AddParticipantOperation:\n                notification_center.post_notification('SIPConferenceDidNotAddParticipant', sender=self.session, data=NotificationData(participant=self.participant_uri, code=0, reason='remote endpoint is not a focus'))\n            else:\n                notification_center.post_notification('SIPConferenceDidNotRemoveParticipant', sender=self.session, data=NotificationData(participant=self.participant_uri, code=0, reason='remote endpoint is not a focus'))\n            self.session = None\n            return\n        notification_center.add_observer(self, sender=self.session)\n        notification_center.add_observer(self, name='NetworkConditionsDidChange')\n        proc.spawn(self._run)\n\n    def _run(self):\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n\n        try:\n            # Lookup routes\n            account = self.session.account\n            if account is BonjourAccount():\n                uri = SIPURI.new(self.session._invitation.remote_contact_header.uri)\n            elif account.sip.outbound_proxy is not None and account.sip.outbound_proxy.transport in settings.sip.transport_list:\n                uri = SIPURI(host=account.sip.outbound_proxy.host, port=account.sip.outbound_proxy.port, parameters={'transport': account.sip.outbound_proxy.transport})\n            elif account.sip.always_use_my_proxy:\n                uri = SIPURI(host=account.id.domain)\n            else:\n                uri = SIPURI.new(self.session.remote_identity.uri)\n            lookup = DNSLookup()\n            try:\n                routes = lookup.lookup_sip_proxy(uri, settings.sip.transport_list).wait()\n            except DNSLookupError, e:\n                timeout = random.uniform(15, 30)\n                raise ReferralError(error='DNS lookup failed: %s' % e)\n\n            target_uri = SIPURI.new(self.session.remote_identity.uri)\n\n            timeout = time() + 30\n            for route in routes:\n                self.route = route\n                remaining_time = timeout - time()\n                if remaining_time > 0:\n                    try:\n                        contact_uri = account.contact[NoGRUU, route]\n                    except KeyError:\n                        continue\n                    refer_to_header = ReferToHeader(str(self.participant_uri))\n                    refer_to_header.parameters['method'] = 'INVITE' if self.operation is AddParticipantOperation else 'BYE'\n                    referral = Referral(target_uri, FromHeader(account.uri, account.display_name),\n                                        ToHeader(target_uri),\n                                        refer_to_header,\n                                        ContactHeader(contact_uri),\n                                        RouteHeader(route.uri),\n                                        account.credentials)\n                    notification_center.add_observer(self, sender=referral)\n                    try:\n                        referral.send_refer(timeout=limit(remaining_time, min=1, max=5))\n                    except SIPCoreError:\n                        notification_center.remove_observer(self, sender=referral)\n                        timeout = 5\n                        raise ReferralError(error='Internal error')\n                    self._referral = referral\n                    try:\n                        while True:\n                            notification = self._channel.wait()\n                            if notification.name == 'SIPReferralDidStart':\n                                break\n                    except SIPReferralDidFail, e:\n                        notification_center.remove_observer(self, sender=referral)\n                        self._referral = None\n                        if e.data.code in (403, 405):\n                            raise ReferralError(error=sip_status_messages[e.data.code], code=e.data.code)\n                        else:\n                            # Otherwise just try the next route\n                            continue\n                    else:\n                        break\n            else:\n                self.route = None\n                raise ReferralError(error='No more routes to try')\n            # At this point it is subscribed. Handle notifications and ending/failures.\n            try:\n                self.active = True\n                while True:\n                    notification = self._channel.wait()\n                    if notification.name == 'SIPReferralGotNotify':\n                        if notification.data.event == 'refer' and notification.data.body:\n                            match = sipfrag_re.match(notification.data.body)\n                            if match:\n                                code = int(match.group('code'))\n                                reason = match.group('reason')\n                                if code/100 > 2:\n                                    continue\n                                if self.operation is AddParticipantOperation:\n                                    notification_center.post_notification('SIPConferenceGotAddParticipantProgress', sender=self.session, data=NotificationData(participant=self.participant_uri, code=code, reason=reason))\n                                else:\n                                    notification_center.post_notification('SIPConferenceGotRemoveParticipantProgress', sender=self.session, data=NotificationData(participant=self.participant_uri, code=code, reason=reason))\n                    elif notification.name == 'SIPReferralDidEnd':\n                        break\n            except SIPReferralDidFail, e:\n                notification_center.remove_observer(self, sender=self._referral)\n                raise ReferralError(error=e.data.reason, code=e.data.code)\n            else:\n                notification_center.remove_observer(self, sender=self._referral)\n                if self.operation is AddParticipantOperation:\n                    notification_center.post_notification('SIPConferenceDidAddParticipant', sender=self.session, data=NotificationData(participant=self.participant_uri))\n                else:\n                    notification_center.post_notification('SIPConferenceDidRemoveParticipant', sender=self.session, data=NotificationData(participant=self.participant_uri))\n            finally:\n                self.active = False\n        except TerminateReferral:\n            if self._referral is not None:\n                try:\n                    self._referral.end(timeout=2)\n                except SIPCoreError:\n                    pass\n                else:\n                    try:\n                        while True:\n                            notification = self._channel.wait()\n                            if notification.name == 'SIPReferralDidEnd':\n                                break\n                    except SIPReferralDidFail:\n                        pass\n                finally:\n                    notification_center.remove_observer(self, sender=self._referral)\n            if self.operation is AddParticipantOperation:\n                notification_center.post_notification('SIPConferenceDidNotAddParticipant', sender=self.session, data=NotificationData(participant=self.participant_uri, code=0, reason='error'))\n            else:\n                notification_center.post_notification('SIPConferenceDidNotRemoveParticipant', sender=self.session, data=NotificationData(participant=self.participant_uri, code=0, reason='error'))\n        except ReferralError, e:\n            if self.operation is AddParticipantOperation:\n                notification_center.post_notification('SIPConferenceDidNotAddParticipant', sender=self.session, data=NotificationData(participant=self.participant_uri, code=e.code, reason=e.error))\n            else:\n                notification_center.post_notification('SIPConferenceDidNotRemoveParticipant', sender=self.session, data=NotificationData(participant=self.participant_uri, code=e.code, reason=e.error))\n        finally:\n            notification_center.remove_observer(self, sender=self.session)\n            notification_center.remove_observer(self, name='NetworkConditionsDidChange')\n            self.session = None\n            self._referral = None\n\n    def _refresh(self):\n        try:\n            contact_header = ContactHeader(self.session.account.contact[NoGRUU, self.route])\n        except KeyError:\n            pass\n        else:\n            try:\n                self._referral.refresh(contact_header=contact_header, timeout=2)\n            except (SIPCoreError, SIPCoreInvalidStateError):\n                pass\n\n    @run_in_twisted_thread\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_SIPReferralDidStart(self, notification):\n        self._channel.send(notification)\n\n    def _NH_SIPReferralDidEnd(self, notification):\n        self._channel.send(notification)\n\n    def _NH_SIPReferralDidFail(self, notification):\n        self._channel.send_exception(SIPReferralDidFail(notification.data))\n\n    def _NH_SIPReferralGotNotify(self, notification):\n        self._channel.send(notification)\n\n    def _NH_SIPSessionDidFail(self, notification):\n        self._channel.send_exception(TerminateReferral())\n\n    def _NH_SIPSessionWillEnd(self, notification):\n        self._channel.send_exception(TerminateReferral())\n\n    def _NH_NetworkConditionsDidChange(self, notification):\n        if self.active:\n            self._refresh()\n\n\nclass ConferenceHandler(object):\n    implements(IObserver)\n\n    def __init__(self, session):\n        self.session = session\n        self.active = False\n        self.subscribed = False\n        self._command_proc = None\n        self._command_channel = coros.queue()\n        self._data_channel = coros.queue()\n        self._subscription = None\n        self._subscription_proc = None\n        self._subscription_timer = None\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, sender=self.session)\n        notification_center.add_observer(self, name='NetworkConditionsDidChange')\n        self._command_proc = proc.spawn(self._run)\n\n    @run_in_green_thread\n    def add_participant(self, participant_uri):\n        referral_handler = ReferralHandler(self.session, participant_uri, AddParticipantOperation)\n        referral_handler.start()\n\n    @run_in_green_thread\n    def remove_participant(self, participant_uri):\n        referral_handler = ReferralHandler(self.session, participant_uri, RemoveParticipantOperation)\n        referral_handler.start()\n\n    def _run(self):\n        while True:\n            command = self._command_channel.wait()\n            handler = getattr(self, '_CH_%s' % command.name)\n            handler(command)\n\n    def _activate(self):\n        self.active = True\n        command = Command('subscribe')\n        self._command_channel.send(command)\n        return command\n\n    def _deactivate(self):\n        self.active = False\n        command = Command('unsubscribe')\n        self._command_channel.send(command)\n        return command\n\n    def _resubscribe(self):\n        command = Command('subscribe')\n        self._command_channel.send(command)\n        return command\n\n    def _terminate(self):\n        notification_center = NotificationCenter()\n        notification_center.remove_observer(self, sender=self.session)\n        notification_center.remove_observer(self, name='NetworkConditionsDidChange')\n        self._deactivate()\n        command = Command('terminate')\n        self._command_channel.send(command)\n        command.wait()\n        self.session = None\n\n    def _CH_subscribe(self, command):\n        if self._subscription_timer is not None and self._subscription_timer.active():\n            self._subscription_timer.cancel()\n        self._subscription_timer = None\n        if self._subscription_proc is not None:\n            subscription_proc = self._subscription_proc\n            subscription_proc.kill(InterruptSubscription)\n            subscription_proc.wait()\n        self._subscription_proc = proc.spawn(self._subscription_handler, command)\n\n    def _CH_unsubscribe(self, command):\n        # Cancel any timer which would restart the subscription process\n        if self._subscription_timer is not None and self._subscription_timer.active():\n            self._subscription_timer.cancel()\n        self._subscription_timer = None\n        if self._subscription_proc is not None:\n            subscription_proc = self._subscription_proc\n            subscription_proc.kill(TerminateSubscription)\n            subscription_proc.wait()\n            self._subscription_proc = None\n        command.signal()\n\n    def _CH_terminate(self, command):\n        command.signal()\n        raise proc.ProcExit()\n\n    def _subscription_handler(self, command):\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n\n        try:\n            # Lookup routes\n            account = self.session.account\n            if account is BonjourAccount():\n                uri = SIPURI.new(self.session._invitation.remote_contact_header.uri)\n            elif account.sip.outbound_proxy is not None and account.sip.outbound_proxy.transport in settings.sip.transport_list:\n                uri = SIPURI(host=account.sip.outbound_proxy.host, port=account.sip.outbound_proxy.port, parameters={'transport': account.sip.outbound_proxy.transport})\n            elif account.sip.always_use_my_proxy:\n                uri = SIPURI(host=account.id.domain)\n            else:\n                uri = SIPURI.new(self.session.remote_identity.uri)\n            lookup = DNSLookup()\n            try:\n                routes = lookup.lookup_sip_proxy(uri, settings.sip.transport_list).wait()\n            except DNSLookupError, e:\n                timeout = random.uniform(15, 30)\n                raise SubscriptionError(error='DNS lookup failed: %s' % e, timeout=timeout)\n\n            target_uri = SIPURI.new(self.session.remote_identity.uri)\n            default_interval = 600 if account is BonjourAccount() else account.sip.subscribe_interval\n            refresh_interval = getattr(command, 'refresh_interval', default_interval)\n\n            timeout = time() + 30\n            for route in routes:\n                remaining_time = timeout - time()\n                if remaining_time > 0:\n                    try:\n                        contact_uri = account.contact[NoGRUU, route]\n                    except KeyError:\n                        continue\n                    subscription = Subscription(target_uri, FromHeader(account.uri, account.display_name),\n                                                ToHeader(target_uri),\n                                                ContactHeader(contact_uri),\n                                                'conference',\n                                                RouteHeader(route.uri),\n                                                credentials=account.credentials,\n                                                refresh=refresh_interval)\n                    notification_center.add_observer(self, sender=subscription)\n                    try:\n                        subscription.subscribe(timeout=limit(remaining_time, min=1, max=5))\n                    except SIPCoreError:\n                        notification_center.remove_observer(self, sender=subscription)\n                        timeout = 5\n                        raise SubscriptionError(error='Internal error', timeout=timeout)\n                    self._subscription = subscription\n                    try:\n                        while True:\n                            notification = self._data_channel.wait()\n                            if notification.sender is subscription and notification.name == 'SIPSubscriptionDidStart':\n                                break\n                    except SIPSubscriptionDidFail, e:\n                        notification_center.remove_observer(self, sender=subscription)\n                        self._subscription = None\n                        if e.data.code == 407:\n                            # Authentication failed, so retry the subscription in some time\n                            timeout = random.uniform(60, 120)\n                            raise SubscriptionError(error='Authentication failed', timeout=timeout)\n                        elif e.data.code == 423:\n                            # Get the value of the Min-Expires header\n                            timeout = random.uniform(60, 120)\n                            if e.data.min_expires is not None and e.data.min_expires > refresh_interval:\n                                raise SubscriptionError(error='Interval too short', timeout=timeout, min_expires=e.data.min_expires)\n                            else:\n                                raise SubscriptionError(error='Interval too short', timeout=timeout)\n                        elif e.data.code in (405, 406, 489, 1400):\n                            command.signal(e)\n                            return\n                        else:\n                            # Otherwise just try the next route\n                            continue\n                    else:\n                        self.subscribed = True\n                        command.signal()\n                        break\n            else:\n                # There are no more routes to try, reschedule the subscription\n                timeout = random.uniform(60, 180)\n                raise SubscriptionError(error='No more routes to try', timeout=timeout)\n            # At this point it is subscribed. Handle notifications and ending/failures.\n            try:\n                while True:\n                    notification = self._data_channel.wait()\n                    if notification.sender is not self._subscription:\n                        continue\n                    if notification.name == 'SIPSubscriptionGotNotify':\n                        if notification.data.event == 'conference' and notification.data.body:\n                            try:\n                                conference_info = ConferenceDocument.parse(notification.data.body)\n                            except ParserError:\n                                pass\n                            else:\n                                notification_center.post_notification('SIPSessionGotConferenceInfo', sender=self.session, data=NotificationData(conference_info=conference_info))\n                    elif notification.name == 'SIPSubscriptionDidEnd':\n                        break\n            except SIPSubscriptionDidFail:\n                self._command_channel.send(Command('subscribe'))\n            notification_center.remove_observer(self, sender=self._subscription)\n        except InterruptSubscription, e:\n            if not self.subscribed:\n                command.signal(e)\n            if self._subscription is not None:\n                notification_center.remove_observer(self, sender=self._subscription)\n                try:\n                    self._subscription.end(timeout=2)\n                except SIPCoreError:\n                    pass\n        except TerminateSubscription, e:\n            if not self.subscribed:\n                command.signal(e)\n            if self._subscription is not None:\n                try:\n                    self._subscription.end(timeout=2)\n                except SIPCoreError:\n                    pass\n                else:\n                    try:\n                        while True:\n                            notification = self._data_channel.wait()\n                            if notification.sender is self._subscription and notification.name == 'SIPSubscriptionDidEnd':\n                                break\n                    except SIPSubscriptionDidFail:\n                        pass\n                finally:\n                    notification_center.remove_observer(self, sender=self._subscription)\n        except SubscriptionError, e:\n            if 'min_expires' in e.attributes:\n                command = Command('subscribe', command.event, refresh_interval=e.attributes['min_expires'])\n            else:\n                command = Command('subscribe', command.event)\n            self._subscription_timer = reactor.callLater(e.timeout, self._command_channel.send, command)\n        finally:\n            self.subscribed = False\n            self._subscription = None\n            self._subscription_proc = None\n\n    @run_in_twisted_thread\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_SIPSubscriptionDidStart(self, notification):\n        self._data_channel.send(notification)\n\n    def _NH_SIPSubscriptionDidEnd(self, notification):\n        self._data_channel.send(notification)\n\n    def _NH_SIPSubscriptionDidFail(self, notification):\n        self._data_channel.send_exception(SIPSubscriptionDidFail(notification.data))\n\n    def _NH_SIPSubscriptionGotNotify(self, notification):\n        self._data_channel.send(notification)\n\n    def _NH_SIPSessionDidStart(self, notification):\n        if self.session.remote_focus:\n            self._activate()\n\n    @run_in_green_thread\n    def _NH_SIPSessionDidFail(self, notification):\n        self._terminate()\n\n    @run_in_green_thread\n    def _NH_SIPSessionDidEnd(self, notification):\n        self._terminate()\n\n    def _NH_SIPSessionDidRenegotiateStreams(self, notification):\n        if self.session.remote_focus and not self.active:\n            self._activate()\n        elif not self.session.remote_focus and self.active:\n            self._deactivate()\n\n    def _NH_NetworkConditionsDidChange(self, notification):\n        if self.active:\n            self._resubscribe()\n\n\nclass TransferInfo(object):\n    def __init__(self, referred_by=None, replaced_dialog_id=None):\n        self.referred_by = referred_by\n        self.replaced_dialog_id = replaced_dialog_id\n\n\nclass TransferHandler(object):\n    implements(IObserver)\n\n    def __init__(self, session):\n        self.state = None\n        self.direction = None\n        self.new_session = None\n        self.session = session\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, sender=self.session)\n        notification_center.add_observer(self, sender=self.session._invitation)\n        self._command_channel = coros.queue()\n        self._data_channel = coros.queue()\n        self._proc = proc.spawn(self._run)\n\n    def _run(self):\n        while True:\n            command = self._command_channel.wait()\n            handler = getattr(self, '_CH_%s' % command.name)\n            handler(command)\n            self.direction = None\n            self.state = None\n\n    def _CH_incoming_transfer(self, command):\n        self.direction = 'incoming'\n        notification_center = NotificationCenter()\n        refer_to_hdr = command.data.headers.get('Refer-To')\n        target = SIPURI.parse(refer_to_hdr.uri)\n        referred_by_hdr = command.data.headers.get('Referred-By', None)\n        if referred_by_hdr is not None:\n            origin = referred_by_hdr.body\n        else:\n            origin = str(self.session.remote_identity.uri)\n        try:\n            while True:\n                try:\n                    notification = self._data_channel.wait()\n                except SIPInvitationTransferDidFail:\n                    self.state = 'failed'\n                    return\n                else:\n                    if notification.name == 'SIPInvitationTransferDidStart':\n                        self.state = 'starting'\n                        refer_to_uri = SIPURI.new(target)\n                        refer_to_uri.headers = {}\n                        refer_to_uri.parameters = {}\n                        notification_center.post_notification('SIPSessionTransferNewIncoming', self.session, NotificationData(transfer_destination=refer_to_uri))\n                    elif notification.name == 'SIPSessionTransferDidStart':\n                        break\n                    elif notification.name == 'SIPSessionTransferDidFail':\n                        self.state = 'failed'\n                        try:\n                            self.session._invitation.notify_transfer_progress(notification.data.code, notification.data.reason)\n                        except SIPCoreError:\n                            return\n                        while True:\n                            try:\n                                notification = self._data_channel.wait()\n                            except SIPInvitationTransferDidFail:\n                                return\n            self.state = 'started'\n            transfer_info = TransferInfo(referred_by=origin)\n            try:\n                replaces_hdr = target.headers.pop('Replaces')\n                call_id, rest = replaces_hdr.split(';', 1)\n                params = dict((item.split('=') for item in rest.split(';')))\n                to_tag = params.get('to-tag')\n                from_tag = params.get('from-tag')\n            except (KeyError, ValueError):\n                pass\n            else:\n                transfer_info.replaced_dialog_id = DialogID(call_id, local_tag=from_tag, remote_tag=to_tag)\n            settings = SIPSimpleSettings()\n            account = self.session.account\n            if account is BonjourAccount():\n                uri = target\n            elif account.sip.outbound_proxy is not None and account.sip.outbound_proxy.transport in settings.sip.transport_list:\n                uri = SIPURI(host=account.sip.outbound_proxy.host, port=account.sip.outbound_proxy.port, parameters={'transport': account.sip.outbound_proxy.transport})\n            elif account.sip.always_use_my_proxy:\n                uri = SIPURI(host=account.id.domain)\n            else:\n                uri = target\n            lookup = DNSLookup()\n            try:\n                routes = lookup.lookup_sip_proxy(uri, settings.sip.transport_list).wait()\n            except DNSLookupError, e:\n                self.state = 'failed'\n                notification_center.post_notification('SIPSessionTransferDidFail', sender=self.session, data=NotificationData(code=0, reason=\"DNS lookup failed: {}\".format(e)))\n                try:\n                    self.session._invitation.notify_transfer_progress(480)\n                except SIPCoreError:\n                    return\n                while True:\n                    try:\n                        self._data_channel.wait()\n                    except SIPInvitationTransferDidFail:\n                        return\n                return\n            self.new_session = Session(account)\n            notification_center = NotificationCenter()\n            notification_center.add_observer(self, sender=self.new_session)\n            self.new_session.connect(ToHeader(target), routes=routes, streams=[MediaStreamRegistry.AudioStream()], transfer_info=transfer_info)\n            while True:\n                try:\n                    notification = self._data_channel.wait()\n                except SIPInvitationTransferDidFail:\n                    return\n                if notification.name == 'SIPInvitationTransferDidEnd':\n                    return\n        except proc.ProcExit:\n            if self.new_session is not None:\n                notification_center.remove_observer(self, sender=self.new_session)\n                self.new_session = None\n            raise\n\n    def _CH_outgoing_transfer(self, command):\n        self.direction = 'outgoing'\n        notification_center = NotificationCenter()\n        self.state = 'starting'\n        while True:\n            try:\n                notification = self._data_channel.wait()\n            except SIPInvitationTransferDidFail, e:\n                self.state = 'failed'\n                notification_center.post_notification('SIPSessionTransferDidFail', sender=self.session, data=NotificationData(code=e.data.code, reason=e.data.reason))\n                return\n            if notification.name == 'SIPInvitationTransferDidStart':\n                self.state = 'started'\n                notification_center.post_notification('SIPSessionTransferDidStart', sender=self.session)\n            elif notification.name == 'SIPInvitationTransferDidEnd':\n                self.state = 'ended'\n                self.session.end()\n                notification_center.post_notification('SIPSessionTransferDidEnd', sender=self.session)\n                return\n\n    def _terminate(self):\n        notification_center = NotificationCenter()\n        notification_center.remove_observer(self, sender=self.session._invitation)\n        notification_center.remove_observer(self, sender=self.session)\n        self._proc.kill()\n        self._proc = None\n        self._command_channel = None\n        self._data_channel = None\n        self.session = None\n\n    @run_in_twisted_thread\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_SIPInvitationTransferNewIncoming(self, notification):\n        self._command_channel.send(Command('incoming_transfer', data=notification.data))\n\n    def _NH_SIPInvitationTransferNewOutgoing(self, notification):\n        self._command_channel.send(Command('outgoing_transfer', data=notification.data))\n\n    def _NH_SIPInvitationTransferDidStart(self, notification):\n        self._data_channel.send(notification)\n\n    def _NH_SIPInvitationTransferDidFail(self, notification):\n        self._data_channel.send_exception(SIPInvitationTransferDidFail(notification.data))\n\n    def _NH_SIPInvitationTransferDidEnd(self, notification):\n        self._data_channel.send(notification)\n\n    def _NH_SIPInvitationTransferGotNotify(self, notification):\n        if notification.data.event == 'refer' and notification.data.body:\n            match = sipfrag_re.match(notification.data.body)\n            if match:\n                code = int(match.group('code'))\n                reason = match.group('reason')\n                notification.center.post_notification('SIPSessionTransferGotProgress', sender=self.session, data=NotificationData(code=code, reason=reason))\n\n    def _NH_SIPSessionTransferDidStart(self, notification):\n        if notification.sender is self.session and self.state == 'starting':\n            self._data_channel.send(notification)\n\n    def _NH_SIPSessionTransferDidFail(self, notification):\n        if notification.sender is self.session and self.state == 'starting':\n            self._data_channel.send(notification)\n\n    def _NH_SIPSessionGotRingIndication(self, notification):\n        if notification.sender is self.new_session and self.session is not None:\n            try:\n                self.session._invitation.notify_transfer_progress(180)\n            except SIPCoreError:\n                pass\n\n    def _NH_SIPSessionGotProvisionalResponse(self, notification):\n        if notification.sender is self.new_session and self.session is not None:\n            try:\n                self.session._invitation.notify_transfer_progress(notification.data.code, notification.data.reason)\n            except SIPCoreError:\n                pass\n\n    def _NH_SIPSessionDidStart(self, notification):\n        if notification.sender is self.new_session:\n            notification.center.remove_observer(self, sender=notification.sender)\n            self.new_session = None\n            if self.session is not None:\n                notification.center.post_notification('SIPSessionTransferDidEnd', sender=self.session)\n                if self.state == 'started':\n                    try:\n                        self.session._invitation.notify_transfer_progress(200)\n                    except SIPCoreError:\n                        pass\n                self.state = 'ended'\n                self.session.end()\n\n    def _NH_SIPSessionDidEnd(self, notification):\n        if notification.sender is self.new_session:\n            # If any stream fails to start we won't get SIPSessionDidFail, we'll get here instead\n            notification.center.remove_observer(self, sender=notification.sender)\n            self.new_session = None\n            if self.session is not None:\n                notification.center.post_notification('SIPSessionTransferDidFail', sender=self.session, data=NotificationData(code=500, reason='internal error'))\n                if self.state == 'started':\n                    try:\n                        self.session._invitation.notify_transfer_progress(500)\n                    except SIPCoreError:\n                        pass\n                self.state = 'failed'\n        else:\n            self._terminate()\n\n    def _NH_SIPSessionDidFail(self, notification):\n        if notification.sender is self.new_session:\n            notification.center.remove_observer(self, sender=notification.sender)\n            self.new_session = None\n            if self.session is not None:\n                notification.center.post_notification('SIPSessionTransferDidFail', sender=self.session, data=NotificationData(code=notification.data.code or 500, reason=notification.data.reason))\n                if self.state == 'started':\n                    try:\n                        self.session._invitation.notify_transfer_progress(notification.data.code or 500, notification.data.reason)\n                    except SIPCoreError:\n                        pass\n                self.state = 'failed'\n        else:\n            self._terminate()\n\n\nclass OptionalTag(str):\n    def __eq__(self, other):\n        return other is None or super(OptionalTag, self).__eq__(other)\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __repr__(self):\n        return '{}({})'.format(self.__class__.__name__, super(OptionalTag, self).__repr__())\n\n\nclass SessionReplaceHandler(object):\n    implements(IObserver)\n\n    def __init__(self, session):\n        self.session = session\n\n    def start(self):\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, sender=self.session)\n        notification_center.add_observer(self, sender=self.session.replaced_session)\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_SIPSessionDidStart(self, notification):\n        notification.center.remove_observer(self, sender=self.session)\n        notification.center.remove_observer(self, sender=self.session.replaced_session)\n        self.session.replaced_session.end()\n        self.session.replaced_session = None\n        self.session = None\n\n    def _NH_SIPSessionDidFail(self, notification):\n        if notification.sender is self.session:\n            notification.center.remove_observer(self, sender=self.session)\n            notification.center.remove_observer(self, sender=self.session.replaced_session)\n            self.session.replaced_session = None\n            self.session = None\n\n    _NH_SIPSessionDidEnd = _NH_SIPSessionDidFail\n\n\nclass Session(object):\n    implements(IObserver)\n\n    media_stream_timeout = 15\n    short_reinvite_timeout = 5\n\n    def __init__(self, account):\n        self.account = account\n        self.direction = None\n        self.end_time = None\n        self.on_hold = False\n        self.proposed_streams = None\n        self.route = None\n        self.state = None\n        self.start_time = None\n        self.streams = None\n        self.transport = None\n        self.local_focus = False\n        self.remote_focus = False\n        self.greenlet = None\n        self.conference = None\n        self.replaced_session = None\n        self.transfer_handler = None\n        self.transfer_info = None\n        self._channel = coros.queue()\n        self._hold_in_progress = False\n        self._invitation = None\n        self._local_identity = None\n        self._remote_identity = None\n        self._lock = RLock()\n\n    def init_incoming(self, invitation, data):\n        notification_center = NotificationCenter()\n        remote_sdp = invitation.sdp.proposed_remote\n        self.proposed_streams = []\n        if remote_sdp:\n            for index, media_stream in enumerate(remote_sdp.media):\n                if media_stream.port != 0:\n                    for stream_type in MediaStreamRegistry:\n                        try:\n                            stream = stream_type.new_from_sdp(self, remote_sdp, index)\n                        except UnknownStreamError:\n                            continue\n                        except InvalidStreamError as e:\n                            log.error(\"Invalid stream: {}\".format(e))\n                            break\n                        except Exception as e:\n                            log.exception(\"Exception occurred while setting up stream from SDP: {}\".format(e))\n                            break\n                        else:\n                            stream.index = index\n                            self.proposed_streams.append(stream)\n                            break\n        self.direction = 'incoming'\n        self.state = 'incoming'\n        self.transport = invitation.transport\n        self._invitation = invitation\n        self.conference = ConferenceHandler(self)\n        self.transfer_handler = TransferHandler(self)\n        if 'isfocus' in invitation.remote_contact_header.parameters:\n            self.remote_focus = True\n        if 'Referred-By' in data.headers or 'Replaces' in data.headers:\n            self.transfer_info = TransferInfo()\n            if 'Referred-By' in data.headers:\n                self.transfer_info.referred_by = data.headers['Referred-By'].body\n            if 'Replaces' in data.headers:\n                replaces_header = data.headers.get('Replaces')\n                # Because we only allow the remote tag to be optional, it can only match established dialogs and early outgoing dialogs, but not early incoming dialogs,\n                # which according to RFC3891 should be rejected with 481 (which will happen automatically by never matching them).\n                if replaces_header.early_only or replaces_header.from_tag == '0':\n                    replaced_dialog_id = DialogID(replaces_header.call_id, local_tag=replaces_header.to_tag, remote_tag=OptionalTag(replaces_header.from_tag))\n                else:\n                    replaced_dialog_id = DialogID(replaces_header.call_id, local_tag=replaces_header.to_tag, remote_tag=replaces_header.from_tag)\n                session_manager = SessionManager()\n                try:\n                    replaced_session = next(session for session in session_manager.sessions if session.dialog_id == replaced_dialog_id)\n                except StopIteration:\n                    invitation.send_response(481)\n                    return\n                else:\n                    # Any matched dialog at this point is either established, terminated or early outgoing.\n                    if replaced_session.state in ('terminating', 'terminated'):\n                        invitation.send_response(603)\n                        return\n                    elif replaced_session.dialog_id.remote_tag is not None and replaces_header.early_only:  # The replaced dialog is established, but the early-only flag is set\n                        invitation.send_response(486)\n                        return\n                    self.replaced_session = replaced_session\n                    self.transfer_info.replaced_dialog_id = replaced_dialog_id\n                    replace_handler = SessionReplaceHandler(self)\n                    replace_handler.start()\n        notification_center.add_observer(self, sender=invitation)\n        notification_center.post_notification('SIPSessionNewIncoming', sender=self, data=NotificationData(streams=self.proposed_streams[:], headers=data.headers))\n\n    @transition_state(None, 'connecting')\n    @run_in_green_thread\n    def connect(self, to_header, routes, streams, is_focus=False, transfer_info=None, extra_headers=None):\n        self.greenlet = api.getcurrent()\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n\n        connected = False\n        received_code = 0\n        received_reason = None\n        unhandled_notifications = []\n        extra_headers = extra_headers or []\n\n        if {'to', 'from', 'via', 'contact', 'route', 'record-route'}.intersection(header.name.lower() for header in extra_headers):\n            raise RuntimeError('invalid header in extra_headers: To, From, Via, Contact, Route and Record-Route headers are not allowed')\n\n        self.direction = 'outgoing'\n        self.proposed_streams = streams\n        self.route = routes[0]\n        self.transport = self.route.transport\n        self.local_focus = is_focus\n        self._invitation = Invitation()\n        self._local_identity = FromHeader(self.account.uri, self.account.display_name)\n        self._remote_identity = to_header\n        self.conference = ConferenceHandler(self)\n        self.transfer_handler = TransferHandler(self)\n        self.transfer_info = transfer_info\n        notification_center.add_observer(self, sender=self._invitation)\n        notification_center.post_notification('SIPSessionNewOutgoing', sender=self, data=NotificationData(streams=streams[:]))\n        for stream in self.proposed_streams:\n            notification_center.add_observer(self, sender=stream)\n            stream.initialize(self, direction='outgoing')\n\n        try:\n            wait_count = len(self.proposed_streams)\n            while wait_count > 0:\n                notification = self._channel.wait()\n                if notification.name == 'MediaStreamDidInitialize':\n                    wait_count -= 1\n            try:\n                contact_uri = self.account.contact[PublicGRUUIfAvailable, self.route]\n                local_ip = host.outgoing_ip_for(self.route.address)\n                if local_ip is None:\n                    raise ValueError(\"could not get outgoing IP address\")\n            except (KeyError, ValueError), e:\n                for stream in self.proposed_streams:\n                    notification_center.remove_observer(self, sender=stream)\n                    stream.deactivate()\n                    stream.end()\n                self._fail(originator='local', code=480, reason=sip_status_messages[480], error=str(e))\n                return\n            connection = SDPConnection(local_ip)\n            local_sdp = SDPSession(local_ip, name=settings.user_agent)\n            for index, stream in enumerate(self.proposed_streams):\n                stream.index = index\n                media = stream.get_local_media(remote_sdp=None, index=index)\n                if media.connection is None or (media.connection is not None and not media.has_ice_attributes and not media.has_ice_candidates):\n                    media.connection = connection\n                local_sdp.media.append(media)\n            from_header = FromHeader(self.account.uri, self.account.display_name)\n            route_header = RouteHeader(self.route.uri)\n            contact_header = ContactHeader(contact_uri)\n            if is_focus:\n                contact_header.parameters['isfocus'] = None\n            if self.transfer_info is not None:\n                if self.transfer_info.referred_by is not None:\n                    extra_headers.append(Header('Referred-By', self.transfer_info.referred_by))\n                if self.transfer_info.replaced_dialog_id is not None:\n                    dialog_id = self.transfer_info.replaced_dialog_id\n                    extra_headers.append(ReplacesHeader(dialog_id.call_id, dialog_id.local_tag, dialog_id.remote_tag))\n            self._invitation.send_invite(to_header.uri, from_header, to_header, route_header, contact_header, local_sdp, self.account.credentials, extra_headers)\n            try:\n                with api.timeout(settings.sip.invite_timeout):\n                    while True:\n                        notification = self._channel.wait()\n                        if notification.name == 'SIPInvitationGotSDPUpdate':\n                            if notification.data.succeeded:\n                                local_sdp = notification.data.local_sdp\n                                remote_sdp = notification.data.remote_sdp\n                                break\n                            else:\n                                for stream in self.proposed_streams:\n                                    notification_center.remove_observer(self, sender=stream)\n                                    stream.deactivate()\n                                    stream.end()\n                                self._fail(originator='remote', code=0, reason=None, error='SDP negotiation failed: %s' % notification.data.error)\n                                return\n                        elif notification.name == 'SIPInvitationChangedState':\n                            if notification.data.state == 'early':\n                                if notification.data.code == 180:\n                                    notification_center.post_notification('SIPSessionGotRingIndication', self)\n                                notification_center.post_notification('SIPSessionGotProvisionalResponse', self, NotificationData(code=notification.data.code, reason=notification.data.reason))\n                            elif notification.data.state == 'connecting':\n                                received_code = notification.data.code\n                                received_reason = notification.data.reason\n                            elif notification.data.state == 'connected':\n                                if not connected:\n                                    connected = True\n                                    notification_center.post_notification('SIPSessionDidProcessTransaction', self,\n                                                                          NotificationData(originator='local', method='INVITE', code=received_code, reason=received_reason))\n                                else:\n                                    unhandled_notifications.append(notification)\n                            elif notification.data.state == 'disconnected':\n                                raise InvitationDisconnectedError(notification.sender, notification.data)\n            except api.TimeoutError:\n                self.end()\n                return\n\n            notification_center.post_notification('SIPSessionWillStart', sender=self)\n            stream_map = dict((stream.index, stream) for stream in self.proposed_streams)\n            for index, local_media in enumerate(local_sdp.media):\n                remote_media = remote_sdp.media[index]\n                stream = stream_map[index]\n                if remote_media.port:\n                    # TODO: check if port is also 0 in local_sdp. In that case PJSIP disabled the stream because\n                    # negotiation failed. If there are more streams, however, the negotiation is considered successful as a\n                    # whole, so while we built a normal SDP, PJSIP modified it and sent it to the other side. That's kind io\n                    # OK, but we cannot really start the stream. -Saul\n                    stream.start(local_sdp, remote_sdp, index)\n                else:\n                    notification_center.remove_observer(self, sender=stream)\n                    self.proposed_streams.remove(stream)\n                    del stream_map[stream.index]\n                    stream.deactivate()\n                    stream.end()\n            removed_streams = [stream for stream in self.proposed_streams if stream.index >= len(local_sdp.media)]\n            for stream in removed_streams:\n                notification_center.remove_observer(self, sender=stream)\n                self.proposed_streams.remove(stream)\n                del stream_map[stream.index]\n                stream.deactivate()\n                stream.end()\n            invitation_notifications = []\n            with api.timeout(self.media_stream_timeout):\n                wait_count = len(self.proposed_streams)\n                while wait_count > 0:\n                    notification = self._channel.wait()\n                    if notification.name == 'MediaStreamDidStart':\n                        wait_count -= 1\n                    elif notification.name == 'SIPInvitationChangedState':\n                        invitation_notifications.append(notification)\n            for notification in invitation_notifications:\n                self._channel.send(notification)\n            while not connected or self._channel:\n                notification = self._channel.wait()\n                if notification.name == 'SIPInvitationChangedState':\n                    if notification.data.state == 'early':\n                        if notification.data.code == 180:\n                            notification_center.post_notification('SIPSessionGotRingIndication', self)\n                        notification_center.post_notification('SIPSessionGotProvisionalResponse', self, NotificationData(code=notification.data.code, reason=notification.data.reason))\n                    elif notification.data.state == 'connecting':\n                        received_code = notification.data.code\n                        received_reason = notification.data.reason\n                    elif notification.data.state == 'connected':\n                        if not connected:\n                            connected = True\n                            notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='local', method='INVITE', code=received_code, reason=received_reason))\n                        else:\n                            unhandled_notifications.append(notification)\n                    elif notification.data.state == 'disconnected':\n                        raise InvitationDisconnectedError(notification.sender, notification.data)\n        except (MediaStreamDidNotInitializeError, MediaStreamDidFailError, api.TimeoutError), e:\n            for stream in self.proposed_streams:\n                notification_center.remove_observer(self, sender=stream)\n                stream.deactivate()\n                stream.end()\n            if isinstance(e, api.TimeoutError):\n                error = 'media stream timed-out while starting'\n            elif isinstance(e, MediaStreamDidNotInitializeError):\n                error = 'media stream did not initialize: %s' % e.data.reason\n            else:\n                error = 'media stream failed: %s' % e.data.reason\n            self._fail(originator='local', code=0, reason=None, error=error)\n        except InvitationDisconnectedError, e:\n            notification_center.remove_observer(self, sender=self._invitation)\n            for stream in self.proposed_streams:\n                notification_center.remove_observer(self, sender=stream)\n                stream.deactivate()\n                stream.end()\n            self.state = 'terminated'\n            # As weird as it may sound, PJSIP accepts a BYE even without receiving a final response to the INVITE\n            if e.data.prev_state in ('connecting', 'connected') or getattr(e.data, 'method', None) == 'BYE':\n                notification_center.post_notification('SIPSessionWillEnd', self, NotificationData(originator=e.data.originator))\n                if e.data.originator == 'remote':\n                    notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method=e.data.method, code=200, reason=sip_status_messages[200]))\n                self.end_time = ISOTimestamp.now()\n                notification_center.post_notification('SIPSessionDidEnd', self, NotificationData(originator=e.data.originator, end_reason=e.data.disconnect_reason))\n            else:\n                if e.data.originator == 'remote':\n                    notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='local', method='INVITE', code=e.data.code, reason=e.data.reason))\n                    code = e.data.code\n                    reason = e.data.reason\n                elif e.data.disconnect_reason == 'timeout':\n                    code = 408\n                    reason = 'timeout'\n                else:\n                    # TODO: we should know *exactly* when there are set -Saul\n                    code = getattr(e.data, 'code', 0)\n                    reason = getattr(e.data, 'reason', 'Session disconnected')\n                if e.data.originator == 'remote' and code // 100 == 3:\n                    redirect_identities = e.data.headers.get('Contact', [])\n                else:\n                    redirect_identities = None\n                notification_center.post_notification('SIPSessionDidFail', self, NotificationData(originator=e.data.originator, code=code, reason=reason, failure_reason=e.data.disconnect_reason, redirect_identities=redirect_identities))\n            self.greenlet = None\n        except SIPCoreError, e:\n            for stream in self.proposed_streams:\n                notification_center.remove_observer(self, sender=stream)\n                stream.deactivate()\n                stream.end()\n            self._fail(originator='local', code=0, reason=None, error='SIP core error: %s' % str(e))\n        else:\n            self.greenlet = None\n            self.state = 'connected'\n            self.streams = self.proposed_streams\n            self.proposed_streams = None\n            self.start_time = ISOTimestamp.now()\n            any_stream_ice = any(getattr(stream, 'ice_active', False) for stream in self.streams)\n            if any_stream_ice:\n                self._reinvite_after_ice()\n            notification_center.post_notification('SIPSessionDidStart', self, NotificationData(streams=self.streams[:]))\n            for notification in unhandled_notifications:\n                self.handle_notification(notification)\n            if self._hold_in_progress:\n                self._send_hold()\n\n    def _reinvite_after_ice(self):\n        # This function does not do any error checking, it's designed to be called at the end of connect and add_stream\n        self.state = 'sending_proposal'\n        self.greenlet = api.getcurrent()\n        notification_center = NotificationCenter()\n\n        local_sdp = SDPSession.new(self._invitation.sdp.active_local)\n        local_sdp.version += 1\n        for index, stream in enumerate(self.streams):\n            local_sdp.media[index] = stream.get_local_media(remote_sdp=None, index=index)\n        self._invitation.send_reinvite(sdp=local_sdp)\n\n        received_invitation_state = False\n        received_sdp_update = False\n        try:\n            with api.timeout(self.short_reinvite_timeout):\n                while not received_invitation_state or not received_sdp_update:\n                    notification = self._channel.wait()\n                    if notification.name == 'SIPInvitationGotSDPUpdate':\n                        received_sdp_update = True\n                        if notification.data.succeeded:\n                            local_sdp = notification.data.local_sdp\n                            remote_sdp = notification.data.remote_sdp\n                            for index, stream in enumerate(self.streams):\n                                stream.update(local_sdp, remote_sdp, index)\n                        else:\n                            return\n                    elif notification.name == 'SIPInvitationChangedState':\n                        if notification.data.state == 'connected' and notification.data.sub_state == 'normal':\n                            received_invitation_state = True\n                            notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='local', method='INVITE', code=notification.data.code, reason=notification.data.reason))\n                        elif notification.data.state == 'disconnected':\n                            self.end()\n                            return\n        except Exception:\n            pass\n        finally:\n            self.state = 'connected'\n            self.greenlet = None\n\n    @check_state(['incoming', 'received_proposal'])\n    @run_in_green_thread\n    def send_ring_indication(self):\n        try:\n            self._invitation.send_response(180)\n        except SIPCoreInvalidStateError:\n            pass # The INVITE session might have already been cancelled; ignore the error\n\n    @transition_state('incoming', 'accepting')\n    @run_in_green_thread\n    def accept(self, streams, is_focus=False, extra_headers=None):\n        self.greenlet = api.getcurrent()\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n\n        self.local_focus = is_focus\n        connected = False\n        unhandled_notifications = []\n        extra_headers = extra_headers or []\n\n        if {'to', 'from', 'via', 'contact', 'route', 'record-route'}.intersection(header.name.lower() for header in extra_headers):\n            raise RuntimeError('invalid header in extra_headers: To, From, Via, Contact, Route and Record-Route headers are not allowed')\n\n        if self.proposed_streams:\n            for stream in self.proposed_streams:\n                if stream in streams:\n                    notification_center.add_observer(self, sender=stream)\n                    stream.initialize(self, direction='incoming')\n        else:\n            for index, stream in enumerate(streams):\n                notification_center.add_observer(self, sender=stream)\n                stream.index = index\n                stream.initialize(self, direction='outgoing')\n        self.proposed_streams = streams\n\n        wait_count = len(self.proposed_streams)\n\n        try:\n            while wait_count > 0:\n                notification = self._channel.wait()\n                if notification.name == 'MediaStreamDidInitialize':\n                    wait_count -= 1\n\n            remote_sdp = self._invitation.sdp.proposed_remote\n            sdp_connection = remote_sdp.connection or (media.connection for media in remote_sdp.media if media.connection is not None).next()\n            local_ip = host.outgoing_ip_for(sdp_connection.address) if sdp_connection.address != '0.0.0.0' else sdp_connection.address\n            if local_ip is None:\n                for stream in self.proposed_streams:\n                    notification_center.remove_observer(self, sender=stream)\n                    stream.deactivate()\n                    stream.end()\n                self._fail(originator='local', code=500, reason=sip_status_messages[500], error='could not get local IP address')\n                return\n            connection = SDPConnection(local_ip)\n            local_sdp = SDPSession(local_ip, name=settings.user_agent)\n            if remote_sdp:\n                stream_map = dict((stream.index, stream) for stream in self.proposed_streams)\n                for index, media in enumerate(remote_sdp.media):\n                    stream = stream_map.get(index, None)\n                    if stream is not None:\n                        media = stream.get_local_media(remote_sdp=remote_sdp, index=index)\n                        if not media.has_ice_attributes and not media.has_ice_candidates:\n                            media.connection = connection\n                    else:\n                        media = SDPMediaStream.new(media)\n                        media.connection = connection\n                        media.port = 0\n                        media.attributes = []\n                        media.bandwidth_info = []\n                    local_sdp.media.append(media)\n            else:\n                for index, stream in enumerate(self.proposed_streams):\n                    stream.index = index\n                    media = stream.get_local_media(remote_sdp=None, index=index)\n                    if media.connection is None or (media.connection is not None and not media.has_ice_attributes and not media.has_ice_candidates):\n                        media.connection = connection\n                    local_sdp.media.append(media)\n            contact_header = ContactHeader.new(self._invitation.local_contact_header)\n            try:\n                local_contact_uri = self.account.contact[PublicGRUU, self._invitation.transport]\n            except KeyError:\n                pass\n            else:\n                contact_header.uri = local_contact_uri\n            if is_focus:\n                contact_header.parameters['isfocus'] = None\n            self._invitation.send_response(200, contact_header=contact_header, sdp=local_sdp, extra_headers=extra_headers)\n            notification_center.post_notification('SIPSessionWillStart', sender=self)\n            # Local and remote SDPs will be set after the 200 OK is sent\n            while True:\n                notification = self._channel.wait()\n                if notification.name == 'SIPInvitationGotSDPUpdate':\n                    if notification.data.succeeded:\n                        local_sdp = notification.data.local_sdp\n                        remote_sdp = notification.data.remote_sdp\n                        break\n                    else:\n                        if not connected:\n                            # we could not have got a SIPInvitationGotSDPUpdate if we did not get an ACK\n                            connected = True\n                            notification_center.post_notification('SIPSessionDidProcessTransaction', self,\n                                                                  NotificationData(originator='remote', method='INVITE', code=200, reason=sip_status_messages[200], ack_received=True))\n                        for stream in self.proposed_streams:\n                            notification_center.remove_observer(self, sender=stream)\n                            stream.deactivate()\n                            stream.end()\n                        self._fail(originator='remote', code=0, reason=None, error='SDP negotiation failed: %s' % notification.data.error)\n                        return\n                elif notification.name == 'SIPInvitationChangedState':\n                    if notification.data.state == 'connected':\n                        if not connected:\n                            connected = True\n                            notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=200, reason=sip_status_messages[200], ack_received=True))\n                        elif notification.data.prev_state == 'connected':\n                            unhandled_notifications.append(notification)\n                    elif notification.data.state == 'disconnected':\n                        raise InvitationDisconnectedError(notification.sender, notification.data)\n            wait_count = 0\n            stream_map = dict((stream.index, stream) for stream in self.proposed_streams)\n            for index, local_media in enumerate(local_sdp.media):\n                remote_media = remote_sdp.media[index]\n                stream = stream_map.get(index, None)\n                if stream is not None:\n                    if remote_media.port:\n                        wait_count += 1\n                        stream.start(local_sdp, remote_sdp, index)\n                    else:\n                        notification_center.remove_observer(self, sender=stream)\n                        self.proposed_streams.remove(stream)\n                        del stream_map[stream.index]\n                        stream.deactivate()\n                        stream.end()\n            removed_streams = [stream for stream in self.proposed_streams if stream.index >= len(local_sdp.media)]\n            for stream in removed_streams:\n                notification_center.remove_observer(self, sender=stream)\n                self.proposed_streams.remove(stream)\n                del stream_map[stream.index]\n                stream.deactivate()\n                stream.end()\n            with api.timeout(self.media_stream_timeout):\n                while wait_count > 0 or not connected or self._channel:\n                    notification = self._channel.wait()\n                    if notification.name == 'MediaStreamDidStart':\n                        wait_count -= 1\n                    elif notification.name == 'SIPInvitationChangedState':\n                        if notification.data.state == 'connected':\n                            if not connected:\n                                connected = True\n                                notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=200, reason='OK', ack_received=True))\n                            elif notification.data.prev_state == 'connected':\n                                unhandled_notifications.append(notification)\n                        elif notification.data.state == 'disconnected':\n                            raise InvitationDisconnectedError(notification.sender, notification.data)\n                    else:\n                        unhandled_notifications.append(notification)\n        except (MediaStreamDidNotInitializeError, MediaStreamDidFailError, api.TimeoutError), e:\n            if self._invitation.state == 'connecting':\n                ack_received = False if isinstance(e, api.TimeoutError) and wait_count == 0 else 'unknown'\n                # pjsip's invite session object does not inform us whether the ACK was received or not\n                notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=200, reason='OK', ack_received=ack_received))\n            elif self._invitation.state == 'connected' and not connected:\n                # we didn't yet get to process the SIPInvitationChangedState (state -> connected) notification\n                notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=200, reason='OK', ack_received=True))\n            for stream in self.proposed_streams:\n                notification_center.remove_observer(self, sender=stream)\n                stream.deactivate()\n                stream.end()\n            reason_header = None\n            if isinstance(e, api.TimeoutError):\n                if wait_count > 0:\n                    error = 'media stream timed-out while starting'\n                else:\n                    error = 'No ACK received'\n                    reason_header = ReasonHeader('SIP')\n                    reason_header.cause = 500\n                    reason_header.text = 'Missing ACK'\n            elif isinstance(e, MediaStreamDidNotInitializeError):\n                error = 'media stream did not initialize: %s' % e.data.reason\n                reason_header = ReasonHeader('SIP')\n                reason_header.cause = 500\n                reason_header.text = 'media stream did not initialize'\n            else:\n                error = 'media stream failed: %s' % e.data.reason\n                reason_header = ReasonHeader('SIP')\n                reason_header.cause = 500\n                reason_header.text = 'media stream failed to start'\n            self.start_time = ISOTimestamp.now()\n            if self._invitation.state in ('incoming', 'early'):\n                self._fail(originator='local', code=500, reason=sip_status_messages[500], error=error, reason_header=reason_header)\n            else:\n                self._fail(originator='local', code=0, reason=None, error=error, reason_header=reason_header)\n        except InvitationDisconnectedError, e:\n            notification_center.remove_observer(self, sender=self._invitation)\n            for stream in self.proposed_streams:\n                notification_center.remove_observer(self, sender=stream)\n                stream.deactivate()\n                stream.end()\n            self.state = 'terminated'\n            if e.data.prev_state in ('incoming', 'early'):\n                notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=487, reason='Session Cancelled', ack_received='unknown'))\n                notification_center.post_notification('SIPSessionDidFail', self, NotificationData(originator='remote', code=487, reason='Session Cancelled', failure_reason=e.data.disconnect_reason, redirect_identities=None))\n            elif e.data.prev_state == 'connecting' and e.data.disconnect_reason == 'missing ACK':\n                notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=200, reason='OK', ack_received=False))\n                notification_center.post_notification('SIPSessionDidFail', self, NotificationData(originator='local', code=200, reason=sip_status_messages[200], failure_reason=e.data.disconnect_reason, redirect_identities=None))\n            else:\n                notification_center.post_notification('SIPSessionWillEnd', self, NotificationData(originator='remote'))\n                notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method=getattr(e.data, 'method', 'INVITE'), code=200, reason='OK'))\n                self.end_time = ISOTimestamp.now()\n                notification_center.post_notification('SIPSessionDidEnd', self, NotificationData(originator='remote', end_reason=e.data.disconnect_reason))\n            self.greenlet = None\n        except SIPCoreInvalidStateError:\n            # the only reason for which this error can be thrown is if invitation.send_response was called after the INVITE session was cancelled by the remote party\n            notification_center.remove_observer(self, sender=self._invitation)\n            for stream in self.proposed_streams:\n                notification_center.remove_observer(self, sender=stream)\n                stream.deactivate()\n                stream.end()\n            self.greenlet = None\n            self.state = 'terminated'\n            notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=487, reason='Session Cancelled', ack_received='unknown'))\n            notification_center.post_notification('SIPSessionDidFail', self, NotificationData(originator='remote', code=487, reason='Session Cancelled', failure_reason='user request', redirect_identities=None))\n        except SIPCoreError, e:\n            for stream in self.proposed_streams:\n                notification_center.remove_observer(self, sender=stream)\n                stream.deactivate()\n                stream.end()\n            self._fail(originator='local', code=500, reason=sip_status_messages[500], error='SIP core error: %s' % str(e))\n        else:\n            self.greenlet = None\n            self.state = 'connected'\n            self.streams = self.proposed_streams\n            self.proposed_streams = None\n            self.start_time = ISOTimestamp.now()\n            notification_center.post_notification('SIPSessionDidStart', self, NotificationData(streams=self.streams[:]))\n            for notification in unhandled_notifications:\n                self.handle_notification(notification)\n            if self._hold_in_progress:\n                self._send_hold()\n        finally:\n            self.greenlet = None\n\n    @transition_state('incoming', 'terminating')\n    @run_in_green_thread\n    def reject(self, code=603, reason=None):\n        self.greenlet = api.getcurrent()\n        notification_center = NotificationCenter()\n\n        try:\n            self._invitation.send_response(code, reason)\n            with api.timeout(1):\n                while True:\n                    notification = self._channel.wait()\n                    if notification.name == 'SIPInvitationChangedState':\n                        if notification.data.state == 'disconnected':\n                            ack_received = notification.data.disconnect_reason != 'missing ACK'\n                            notification_center.post_notification('SIPSessionDidProcessTransaction', self,\n                                                                  NotificationData(originator='remote', method='INVITE', code=code, reason=sip_status_messages[code], ack_received=ack_received))\n                            break\n        except SIPCoreInvalidStateError:\n            # the only reason for which this error can be thrown is if invitation.send_response was called after the INVITE session was cancelled by the remote party\n            self.greenlet = None\n        except SIPCoreError, e:\n            self._fail(originator='local', code=500, reason=sip_status_messages[500], error='SIP core error: %s' % str(e))\n        except api.TimeoutError:\n            notification_center.remove_observer(self, sender=self._invitation)\n            self.greenlet = None\n            self.state = 'terminated'\n            notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=code, reason=sip_status_messages[code], ack_received=False))\n            notification_center.post_notification('SIPSessionDidFail', self, NotificationData(originator='local', code=code, reason=sip_status_messages[code], failure_reason='timeout', redirect_identities=None))\n        else:\n            notification_center.remove_observer(self, sender=self._invitation)\n            self.greenlet = None\n            self.state = 'terminated'\n            notification_center.post_notification('SIPSessionDidFail', self, NotificationData(originator='local', code=code, reason=sip_status_messages[code], failure_reason='user request', redirect_identities=None))\n        finally:\n            self.greenlet = None\n\n    @transition_state('received_proposal', 'accepting_proposal')\n    @run_in_green_thread\n    def accept_proposal(self, streams):\n        self.greenlet = api.getcurrent()\n        notification_center = NotificationCenter()\n\n        unhandled_notifications = []\n\n        streams = [stream for stream in streams if stream in self.proposed_streams]\n        for stream in streams:\n            notification_center.add_observer(self, sender=stream)\n            stream.initialize(self, direction='incoming')\n\n        try:\n            wait_count = len(streams)\n            while wait_count > 0:\n                notification = self._channel.wait()\n                if notification.name == 'MediaStreamDidInitialize':\n                    wait_count -= 1\n\n            local_sdp = SDPSession.new(self._invitation.sdp.active_local)\n            local_sdp.version += 1\n            remote_sdp = self._invitation.sdp.proposed_remote\n            connection = SDPConnection(local_sdp.address)\n            stream_map = dict((stream.index, stream) for stream in streams)\n            for index, media in enumerate(remote_sdp.media):\n                stream = stream_map.get(index, None)\n                if stream is not None:\n                    media = stream.get_local_media(remote_sdp=remote_sdp, index=index)\n                    if not media.has_ice_attributes and not media.has_ice_candidates:\n                        media.connection = connection\n                    if index < len(local_sdp.media):\n                        local_sdp.media[index] = media\n                    else:\n                        local_sdp.media.append(media)\n                elif index >= len(local_sdp.media):  # actually == is sufficient\n                    media = SDPMediaStream.new(media)\n                    media.connection = connection\n                    media.port = 0\n                    media.attributes = []\n                    media.bandwidth_info = []\n                    local_sdp.media.append(media)\n            self._invitation.send_response(200, sdp=local_sdp)\n\n            prev_on_hold_streams = set(stream for stream in self.streams if stream.hold_supported and stream.on_hold_by_remote)\n\n            received_invitation_state = False\n            received_sdp_update = False\n            while not received_invitation_state or not received_sdp_update:\n                notification = self._channel.wait()\n                if notification.name == 'SIPInvitationGotSDPUpdate':\n                    received_sdp_update = True\n                    if notification.data.succeeded:\n                        local_sdp = notification.data.local_sdp\n                        remote_sdp = notification.data.remote_sdp\n                        for stream in self.streams:\n                            stream.update(local_sdp, remote_sdp, stream.index)\n                    else:\n                        self._fail_proposal(originator='remote', error='SDP negotiation failed: %s' % notification.data.error)\n                        return\n                elif notification.name == 'SIPInvitationChangedState':\n                    if notification.data.state == 'connected' and notification.data.sub_state == 'normal':\n                        notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=200, reason=sip_status_messages[200], ack_received='unknown'))\n                        received_invitation_state = True\n                    elif notification.data.state == 'disconnected':\n                        raise InvitationDisconnectedError(notification.sender, notification.data)\n\n            on_hold_streams = set(stream for stream in self.streams if stream.hold_supported and stream.on_hold_by_remote)\n            if on_hold_streams != prev_on_hold_streams:\n                hold_supported_streams = (stream for stream in self.streams if stream.hold_supported)\n                notification_center.post_notification('SIPSessionDidChangeHoldState', self, NotificationData(originator='remote', on_hold=bool(on_hold_streams),\n                                                      partial=bool(on_hold_streams) and any(not stream.on_hold_by_remote for stream in hold_supported_streams)))\n\n            for stream in streams:\n                # TODO: check if port is 0 in local_sdp. In that case PJSIP disabled the stream because\n                # negotiation failed. If there are more streams, however, the negotiation is considered successful as a\n                # whole, so while we built a normal SDP, PJSIP modified it and sent it to the other side. That's kind of\n                # OK, but we cannot really start the stream. -Saul\n                stream.start(local_sdp, remote_sdp, stream.index)\n            with api.timeout(self.media_stream_timeout):\n                wait_count = len(streams)\n                while wait_count > 0 or self._channel:\n                    notification = self._channel.wait()\n                    if notification.name == 'MediaStreamDidStart':\n                        wait_count -= 1\n                    else:\n                        unhandled_notifications.append(notification)\n        except api.TimeoutError:\n            self._fail_proposal(originator='remote', error='media stream timed-out while starting')\n        except MediaStreamDidNotInitializeError as e:\n            self._fail_proposal(originator='remote', error='media stream did not initialize: {.data.reason}'.format(e))\n        except MediaStreamDidFailError as e:\n            self._fail_proposal(originator='remote', error='media stream failed: {.data.reason}'.format(e))\n        except InvitationDisconnectedError, e:\n            self._fail_proposal(originator='remote', error='session ended')\n            notification = Notification('SIPInvitationChangedState', e.invitation, e.data)\n            notification.center = notification_center\n            self.handle_notification(notification)\n        except SIPCoreError, e:\n            self._fail_proposal(originator='remote', error='SIP core error: %s' % str(e))\n        else:\n            proposed_streams = self.proposed_streams\n            self.proposed_streams = None\n            self.streams = self.streams + streams\n            self.greenlet = None\n            self.state = 'connected'\n            notification_center.post_notification('SIPSessionProposalAccepted', self, NotificationData(originator='remote', accepted_streams=streams, proposed_streams=proposed_streams))\n            notification_center.post_notification('SIPSessionDidRenegotiateStreams', self, NotificationData(originator='remote', added_streams=streams, removed_streams=[]))\n            for notification in unhandled_notifications:\n                self.handle_notification(notification)\n            if self._hold_in_progress:\n                self._send_hold()\n        finally:\n            self.greenlet = None\n\n    @transition_state('received_proposal', 'rejecting_proposal')\n    @run_in_green_thread\n    def reject_proposal(self, code=488, reason=None):\n        self.greenlet = api.getcurrent()\n        notification_center = NotificationCenter()\n\n        try:\n            self._invitation.send_response(code, reason)\n            with api.timeout(1, None):\n                while True:\n                    notification = self._channel.wait()\n                    if notification.name == 'SIPInvitationChangedState':\n                        if notification.data.state == 'connected' and notification.data.sub_state == 'normal':\n                            notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=code, reason=sip_status_messages[code], ack_received='unknown'))\n                            break\n        except SIPCoreError, e:\n            self._fail_proposal(originator='remote', error='SIP core error: %s' % str(e))\n        else:\n            proposed_streams = self.proposed_streams\n            self.proposed_streams = None\n            self.greenlet = None\n            self.state = 'connected'\n            notification_center.post_notification('SIPSessionProposalRejected', self, NotificationData(originator='remote', code=code, reason=sip_status_messages[code], proposed_streams=proposed_streams))\n            if self._hold_in_progress:\n                self._send_hold()\n        finally:\n            self.greenlet = None\n\n    def add_stream(self, stream):\n        self.add_streams([stream])\n\n    @transition_state('connected', 'sending_proposal')\n    @run_in_green_thread\n    def add_streams(self, streams):\n        streams = list(set(streams).difference(self.streams))\n        if not streams:\n            self.state = 'connected'\n            return\n\n        self.greenlet = api.getcurrent()\n        notification_center = NotificationCenter()\n        settings = SIPSimpleSettings()\n        unhandled_notifications = []\n\n        self.proposed_streams = streams\n        for stream in self.proposed_streams:\n            notification_center.add_observer(self, sender=stream)\n            stream.initialize(self, direction='outgoing')\n\n        try:\n            wait_count = len(self.proposed_streams)\n            while wait_count > 0:\n                notification = self._channel.wait()\n                if notification.name == 'MediaStreamDidInitialize':\n                    wait_count -= 1\n                elif notification.name == 'SIPInvitationChangedState':\n                    # This is actually the only reason for which this notification could be received\n                    if notification.data.state == 'connected' and notification.data.sub_state == 'received_proposal':\n                        self._fail_proposal(originator='local', error='received stream proposal')\n                        self.handle_notification(notification)\n                        return\n\n            local_sdp = SDPSession.new(self._invitation.sdp.active_local)\n            local_sdp.version += 1\n            for stream in self.proposed_streams:\n                # Try to reuse a disabled media stream to avoid an ever-growing SDP\n                try:\n                    index = next(index for index, media in enumerate(local_sdp.media) if media.port == 0)\n                    reuse_media = True\n                except StopIteration:\n                    index = len(local_sdp.media)\n                    reuse_media = False\n                stream.index = index\n                media = stream.get_local_media(remote_sdp=None, index=index)\n                if reuse_media:\n                    local_sdp.media[index] = media\n                else:\n                    local_sdp.media.append(media)\n            self._invitation.send_reinvite(sdp=local_sdp)\n            notification_center.post_notification('SIPSessionNewProposal', sender=self, data=NotificationData(originator='local', proposed_streams=self.proposed_streams[:]))\n\n            received_invitation_state = False\n            received_sdp_update = False\n            try:\n                with api.timeout(settings.sip.invite_timeout):\n                    while not received_invitation_state or not received_sdp_update:\n                        notification = self._channel.wait()\n                        if notification.name == 'SIPInvitationGotSDPUpdate':\n                            received_sdp_update = True\n                            if notification.data.succeeded:\n                                local_sdp = notification.data.local_sdp\n                                remote_sdp = notification.data.remote_sdp\n                                for s in self.streams:\n                                    s.update(local_sdp, remote_sdp, s.index)\n                            else:\n                                self._fail_proposal(originator='local', error='SDP negotiation failed: %s' % notification.data.error)\n                                return\n                        elif notification.name == 'SIPInvitationChangedState':\n                            if notification.data.state == 'connected' and notification.data.sub_state == 'normal':\n                                received_invitation_state = True\n                                notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='local', method='INVITE', code=notification.data.code, reason=notification.data.reason))\n                                if notification.data.code >= 300:\n                                    proposed_streams = self.proposed_streams\n                                    for stream in proposed_streams:\n                                        notification_center.remove_observer(self, sender=stream)\n                                        stream.deactivate()\n                                        stream.end()\n                                    self.proposed_streams = None\n                                    self.greenlet = None\n                                    self.state = 'connected'\n                                    notification_center.post_notification('SIPSessionProposalRejected', self, NotificationData(originator='local', code=notification.data.code, reason=notification.data.reason, proposed_streams=proposed_streams))\n                                    return\n                            elif notification.data.state == 'disconnected':\n                                raise InvitationDisconnectedError(notification.sender, notification.data)\n            except api.TimeoutError:\n                self.cancel_proposal()\n                return\n\n            accepted_streams = []\n            for stream in self.proposed_streams:\n                try:\n                    remote_media = remote_sdp.media[stream.index]\n                except IndexError:\n                    self._fail_proposal(originator='local', error='SDP media missing in answer')\n                    return\n                else:\n                    if remote_media.port:\n                        stream.start(local_sdp, remote_sdp, stream.index)\n                        accepted_streams.append(stream)\n                    else:\n                        notification_center.remove_observer(self, sender=stream)\n                        stream.deactivate()\n                        stream.end()\n\n            with api.timeout(self.media_stream_timeout):\n                wait_count = len(accepted_streams)\n                while wait_count > 0:\n                    notification = self._channel.wait()\n                    if notification.name == 'MediaStreamDidStart':\n                        wait_count -= 1\n        except api.TimeoutError:\n            self._fail_proposal(originator='local', error='media stream timed-out while starting')\n        except MediaStreamDidNotInitializeError as e:\n            self._fail_proposal(originator='local', error='media stream did not initialize: {.data.reason}'.format(e))\n        except MediaStreamDidFailError as e:\n            self._fail_proposal(originator='local', error='media stream failed: {.data.reason}'.format(e))\n        except InvitationDisconnectedError, e:\n            self._fail_proposal(originator='local', error='session ended')\n            notification = Notification('SIPInvitationChangedState', e.invitation, e.data)\n            notification.center = notification_center\n            self.handle_notification(notification)\n        except SIPCoreError, e:\n            self._fail_proposal(originator='local', error='SIP core error: %s' % str(e))\n        else:\n            self.greenlet = None\n            self.state = 'connected'\n            self.streams += accepted_streams\n            proposed_streams = self.proposed_streams\n            self.proposed_streams = None\n            any_stream_ice = any(getattr(stream, 'ice_active', False) for stream in accepted_streams)\n            if any_stream_ice:\n                self._reinvite_after_ice()\n            notification_center.post_notification('SIPSessionProposalAccepted', self, NotificationData(originator='local', accepted_streams=accepted_streams, proposed_streams=proposed_streams))\n            notification_center.post_notification('SIPSessionDidRenegotiateStreams', self, NotificationData(originator='local', added_streams=accepted_streams, removed_streams=[]))\n            for notification in unhandled_notifications:\n                self.handle_notification(notification)\n            if self._hold_in_progress:\n                self._send_hold()\n        finally:\n            self.greenlet = None\n\n    def remove_stream(self, stream):\n        self.remove_streams([stream])\n\n    @transition_state('connected', 'sending_proposal')\n    @run_in_green_thread\n    def remove_streams(self, streams):\n        streams = list(set(streams).intersection(self.streams))\n        if not streams:\n            self.state = 'connected'\n            return\n\n        self.greenlet = api.getcurrent()\n        notification_center = NotificationCenter()\n        unhandled_notifications = []\n\n        try:\n            local_sdp = SDPSession.new(self._invitation.sdp.active_local)\n            local_sdp.version += 1\n            for stream in streams:\n                notification_center.remove_observer(self, sender=stream)\n                stream.deactivate()\n                self.streams.remove(stream)\n                media = local_sdp.media[stream.index]\n                media.port = 0\n                media.attributes = []\n                media.bandwidth_info = []\n\n            self._invitation.send_reinvite(sdp=local_sdp)\n\n            received_invitation_state = False\n            received_sdp_update = False\n\n            with api.timeout(self.short_reinvite_timeout):\n                while not received_invitation_state or not received_sdp_update:\n                    notification = self._channel.wait()\n                    if notification.name == 'SIPInvitationGotSDPUpdate':\n                        received_sdp_update = True\n                        if notification.data.succeeded:\n                            local_sdp = notification.data.local_sdp\n                            remote_sdp = notification.data.remote_sdp\n                            for s in self.streams:\n                                s.update(local_sdp, remote_sdp, s.index)\n                    elif notification.name == 'SIPInvitationChangedState':\n                        if notification.data.state == 'connected' and notification.data.sub_state == 'normal':\n                            received_invitation_state = True\n                            notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='local', method='INVITE', code=notification.data.code, reason=notification.data.reason))\n                            if not (200 <= notification.data.code < 300):\n                                break\n                        elif notification.data.state == 'disconnected':\n                            raise InvitationDisconnectedError(notification.sender, notification.data)\n        except InvitationDisconnectedError, e:\n            for stream in streams:\n                stream.end()\n            self.greenlet = None\n            notification = Notification('SIPInvitationChangedState', e.invitation, e.data)\n            notification.center = notification_center\n            self.handle_notification(notification)\n        except (api.TimeoutError, MediaStreamDidFailError, SIPCoreError):\n            for stream in streams:\n                stream.end()\n            self.end()\n        else:\n            for stream in streams:\n                stream.end()\n            self.greenlet = None\n            self.state = 'connected'\n            notification_center.post_notification('SIPSessionDidRenegotiateStreams', self, NotificationData(originator='local', added_streams=[], removed_streams=streams))\n            for notification in unhandled_notifications:\n                self.handle_notification(notification)\n            if self._hold_in_progress:\n                self._send_hold()\n        finally:\n            self.greenlet = None\n\n    @transition_state('sending_proposal', 'cancelling_proposal')\n    @run_in_green_thread\n    def cancel_proposal(self):\n        if self.greenlet is not None:\n            api.kill(self.greenlet, api.GreenletExit())\n        self.greenlet = api.getcurrent()\n        notification_center = NotificationCenter()\n        try:\n            self._invitation.cancel_reinvite()\n            while True:\n                try:\n                    notification = self._channel.wait()\n                except MediaStreamDidFailError:\n                    continue\n                if notification.name == 'SIPInvitationChangedState':\n                    if notification.data.state == 'connected' and notification.data.sub_state == 'normal':\n                        notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=notification.data.code, reason=notification.data.reason))\n                        if notification.data.code == 487:\n                            proposed_streams = self.proposed_streams or []\n                            for stream in proposed_streams:\n                                notification_center.remove_observer(self, sender=stream)\n                                stream.deactivate()\n                                stream.end()\n                            self.proposed_streams = None\n                            self.state = 'connected'\n                            notification_center.post_notification('SIPSessionProposalRejected', self, NotificationData(originator='local', code=notification.data.code, reason=notification.data.reason, proposed_streams=proposed_streams))\n                        elif notification.data.code == 200:\n                            self.end()\n                    elif notification.data.state == 'disconnected':\n                        raise InvitationDisconnectedError(notification.sender, notification.data)\n                    break\n        except SIPCoreError, e:\n            notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='local', code=0, reason=None, failure_reason='SIP core error: %s' % str(e), redirect_identities=None))\n            proposed_streams = self.proposed_streams or []\n            for stream in proposed_streams:\n                notification_center.remove_observer(self, sender=stream)\n                stream.deactivate()\n                stream.end()\n            self.proposed_streams = None\n            self.greenlet = None\n            self.state = 'connected'\n            notification_center.post_notification('SIPSessionProposalRejected', self, NotificationData(originator='local', code=0, reason='SIP core error: %s' % str(e), proposed_streams=proposed_streams))\n        except InvitationDisconnectedError, e:\n            for stream in self.proposed_streams or []:\n                notification_center.remove_observer(self, sender=stream)\n                stream.deactivate()\n                stream.end()\n            self.proposed_streams = None\n            self.greenlet = None\n            notification = Notification('SIPInvitationChangedState', e.invitation, e.data)\n            notification.center = notification_center\n            self.handle_notification(notification)\n        else:\n            for stream in self.proposed_streams or []:\n                notification_center.remove_observer(self, sender=stream)\n                stream.deactivate()\n                stream.end()\n            self.proposed_streams = None\n            self.greenlet = None\n            self.state = 'connected'\n        finally:\n            self.greenlet = None\n            if self._hold_in_progress:\n                self._send_hold()\n\n    @run_in_green_thread\n    def hold(self):\n        if self.on_hold or self._hold_in_progress:\n            return\n        self._hold_in_progress = True\n        streams = (self.streams or []) + (self.proposed_streams or [])\n        if not streams:\n            return\n        for stream in streams:\n            stream.hold()\n        if self.state == 'connected':\n            self._send_hold()\n\n    @run_in_green_thread\n    def unhold(self):\n        if not self.on_hold and not self._hold_in_progress:\n            return\n        self._hold_in_progress = False\n        streams = (self.streams or []) + (self.proposed_streams or [])\n        if not streams:\n            return\n        for stream in streams:\n            stream.unhold()\n        if self.state == 'connected':\n            self._send_unhold()\n\n    @run_in_green_thread\n    def end(self):\n        if self.state in (None, 'terminating', 'terminated'):\n            return\n        if self.greenlet is not None:\n            api.kill(self.greenlet, api.GreenletExit())\n        self.greenlet = None\n        notification_center = NotificationCenter()\n        if self._invitation is None:\n            # The invitation was not yet constructed\n            self.state = 'terminated'\n            notification_center.post_notification('SIPSessionDidFail', self, NotificationData(originator='local', code=487, reason='Session Cancelled', failure_reason='user request', redirect_identities=None))\n            return\n        elif self._invitation.state is None:\n            # The invitation was built but never sent\n            streams = (self.streams or []) + (self.proposed_streams or [])\n            for stream in streams[:]:\n                try:\n                    notification_center.remove_observer(self, sender=stream)\n                except KeyError:\n                    streams.remove(stream)\n                else:\n                    stream.deactivate()\n                    stream.end()\n            self.state = 'terminated'\n            notification_center.post_notification('SIPSessionDidFail', self, NotificationData(originator='local', code=487, reason='Session Cancelled', failure_reason='user request', redirect_identities=None))\n            return\n        invitation_state = self._invitation.state\n        if invitation_state in ('disconnecting', 'disconnected'):\n            return\n        self.greenlet = api.getcurrent()\n        self.state = 'terminating'\n        if invitation_state == 'connected':\n            notification_center.post_notification('SIPSessionWillEnd', self, NotificationData(originator='local'))\n        streams = (self.streams or []) + (self.proposed_streams or [])\n        for stream in streams[:]:\n            try:\n                notification_center.remove_observer(self, sender=stream)\n            except KeyError:\n                streams.remove(stream)\n            else:\n                stream.deactivate()\n        cancelling = invitation_state != 'connected' and self.direction == 'outgoing'\n        try:\n            self._invitation.end(timeout=1)\n            while True:\n                try:\n                    notification = self._channel.wait()\n                except MediaStreamDidFailError:\n                    continue\n                if notification.name == 'SIPInvitationChangedState' and notification.data.state == 'disconnected':\n                    if notification.data.disconnect_reason in ('internal error', 'missing ACK'):\n                        pass\n                    elif notification.data.disconnect_reason == 'timeout':\n                        notification_center.post_notification('SIPSessionDidProcessTransaction', self,\n                                                              NotificationData(originator='local' if self.direction=='outgoing' else 'remote', method='INVITE', code=408, reason='Timeout'))\n                    elif cancelling:\n                        notification_center.post_notification('SIPSessionDidProcessTransaction', self,\n                                                              NotificationData(originator='local', method='INVITE', code=notification.data.code, reason=notification.data.reason))\n                    elif hasattr(notification.data, 'method'):\n                        notification_center.post_notification('SIPSessionDidProcessTransaction', self,\n                                                              NotificationData(originator='remote', method=notification.data.method, code=200, reason=sip_status_messages[200]))\n                    elif notification.data.disconnect_reason == 'user request':\n                        notification_center.post_notification('SIPSessionDidProcessTransaction', self,\n                                                              NotificationData(originator='local', method='BYE', code=notification.data.code, reason=notification.data.reason))\n                    break\n        except SIPCoreError, e:\n            if cancelling:\n                notification_center.post_notification('SIPSessionDidFail', self, NotificationData(originator='local', code=0, reason=None, failure_reason='SIP core error: %s' % str(e), redirect_identities=None))\n            else:\n                self.end_time = ISOTimestamp.now()\n                notification_center.post_notification('SIPSessionDidEnd', self, NotificationData(originator='local', end_reason='SIP core error: %s' % str(e)))\n        except InvitationDisconnectedError, e:\n            # As it weird as it may sound, PJSIP accepts a BYE even without receiving a final response to the INVITE\n            if e.data.prev_state == 'connected':\n                if e.data.originator == 'remote':\n                    notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator=e.data.originator, method=e.data.method, code=200, reason=sip_status_messages[200]))\n                self.end_time = ISOTimestamp.now()\n                notification_center.post_notification('SIPSessionDidEnd', self, NotificationData(originator=e.data.originator, end_reason=e.data.disconnect_reason))\n            elif getattr(e.data, 'method', None) == 'BYE' and e.data.originator == 'remote':\n                notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator=e.data.originator, method=e.data.method, code=200, reason=sip_status_messages[200]))\n                notification_center.post_notification('SIPSessionDidFail', self, NotificationData(originator=e.data.originator, code=0, reason=None, failure_reason=e.data.disconnect_reason, redirect_identities=None))\n            else:\n                if e.data.originator == 'remote':\n                    code = e.data.code\n                    reason = e.data.reason\n                elif e.data.disconnect_reason == 'timeout':\n                    code = 408\n                    reason = 'timeout'\n                else:\n                    code = 0\n                    reason = None\n                if e.data.originator == 'remote' and code // 100 == 3:\n                    redirect_identities = e.data.headers.get('Contact', [])\n                else:\n                    redirect_identities = None\n                notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='local', method='INVITE', code=code, reason=reason))\n                notification_center.post_notification('SIPSessionDidFail', self, NotificationData(originator=e.data.originator, code=code, reason=reason, failure_reason=e.data.disconnect_reason, redirect_identities=redirect_identities))\n        else:\n            if cancelling:\n                notification_center.post_notification('SIPSessionDidFail', self, NotificationData(originator='local', code=487, reason='Session Cancelled', failure_reason='user request', redirect_identities=None))\n            else:\n                self.end_time = ISOTimestamp.now()\n                notification_center.post_notification('SIPSessionDidEnd', self, NotificationData(originator='local', end_reason='user request'))\n        finally:\n            for stream in streams:\n                stream.end()\n            notification_center.remove_observer(self, sender=self._invitation)\n            self.greenlet = None\n            self.state = 'terminated'\n\n    @check_state(['connected'])\n    @check_transfer_state(None, None)\n    @run_in_twisted_thread\n    def transfer(self, target_uri, replaced_session=None):\n        notification_center = NotificationCenter()\n        notification_center.post_notification('SIPSessionTransferNewOutgoing', self, NotificationData(transfer_destination=target_uri))\n        try:\n            self._invitation.transfer(target_uri, replaced_session.dialog_id if replaced_session is not None else None)\n        except SIPCoreError, e:\n            notification_center.post_notification('SIPSessionTransferDidFail', sender=self, data=NotificationData(code=500, reason=str(e)))\n\n    @check_state(['connected', 'received_proposal', 'sending_proposal', 'accepting_proposal', 'rejecting_proposal', 'cancelling_proposal'])\n    @check_transfer_state('incoming', 'starting')\n    def accept_transfer(self):\n        notification_center = NotificationCenter()\n        notification_center.post_notification('SIPSessionTransferDidStart', sender=self)\n\n    @check_state(['connected', 'received_proposal', 'sending_proposal', 'accepting_proposal', 'rejecting_proposal', 'cancelling_proposal'])\n    @check_transfer_state('incoming', 'starting')\n    def reject_transfer(self, code=603, reason=None):\n        notification_center = NotificationCenter()\n        notification_center.post_notification('SIPSessionTransferDidFail', self, NotificationData(code=code, reason=reason or sip_status_messages[code]))\n\n    @property\n    def dialog_id(self):\n        return self._invitation.dialog_id if self._invitation is not None else None\n\n    @property\n    def local_identity(self):\n        if self._invitation is not None and self._invitation.local_identity is not None:\n            return self._invitation.local_identity\n        else:\n            return self._local_identity\n\n    @property\n    def peer_address(self):\n        return self._invitation.peer_address if self._invitation is not None else None\n\n    @property\n    def remote_identity(self):\n        if self._invitation is not None and self._invitation.remote_identity is not None:\n            return self._invitation.remote_identity\n        else:\n            return self._remote_identity\n\n    @property\n    def remote_user_agent(self):\n        return self._invitation.remote_user_agent if self._invitation is not None else None\n\n    def _cancel_hold(self):\n        notification_center = NotificationCenter()\n        try:\n            self._invitation.cancel_reinvite()\n            while True:\n                try:\n                    notification = self._channel.wait()\n                except MediaStreamDidFailError:\n                    continue\n                if notification.name == 'SIPInvitationChangedState':\n                    if notification.data.state == 'connected' and notification.data.sub_state == 'normal':\n                        notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=notification.data.code, reason=notification.data.reason))\n                        if notification.data.code == 200:\n                            self.end()\n                            return False\n                    elif notification.data.state == 'disconnected':\n                        raise InvitationDisconnectedError(notification.sender, notification.data)\n                    break\n        except SIPCoreError, e:\n            notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='local', code=0, reason=None, failure_reason='SIP core error: %s' % str(e), redirect_identities=None))\n        except InvitationDisconnectedError, e:\n            self.greenlet = None\n            notification = Notification('SIPInvitationChangedState', e.invitation, e.data)\n            notification.center = notification_center\n            self.handle_notification(notification)\n            return False\n        return True\n\n    def _send_hold(self):\n        self.state = 'sending_proposal'\n        self.greenlet = api.getcurrent()\n        notification_center = NotificationCenter()\n\n        unhandled_notifications = []\n\n        try:\n            local_sdp = SDPSession.new(self._invitation.sdp.active_local)\n            local_sdp.version += 1\n            for stream in self.streams:\n                local_sdp.media[stream.index] = stream.get_local_media(remote_sdp=None, index=stream.index)\n            self._invitation.send_reinvite(sdp=local_sdp)\n\n            received_invitation_state = False\n            received_sdp_update = False\n\n            with api.timeout(self.short_reinvite_timeout):\n                while not received_invitation_state or not received_sdp_update:\n                    notification = self._channel.wait()\n                    if notification.name == 'SIPInvitationGotSDPUpdate':\n                        received_sdp_update = True\n                        if notification.data.succeeded:\n                            local_sdp = notification.data.local_sdp\n                            remote_sdp = notification.data.remote_sdp\n                            for stream in self.streams:\n                                stream.update(local_sdp, remote_sdp, stream.index)\n                    elif notification.name == 'SIPInvitationChangedState':\n                        if notification.data.state == 'connected' and notification.data.sub_state == 'normal':\n                            received_invitation_state = True\n                            notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='local', method='INVITE', code=notification.data.code, reason=notification.data.reason))\n                        elif notification.data.state == 'disconnected':\n                            raise InvitationDisconnectedError(notification.sender, notification.data)\n        except InvitationDisconnectedError, e:\n            self.greenlet = None\n            notification = Notification('SIPInvitationChangedState', e.invitation, e.data)\n            notification.center = notification_center\n            self.handle_notification(notification)\n            return\n        except api.TimeoutError:\n            if not self._cancel_hold():\n                return\n        except SIPCoreError:\n            pass\n\n        self.greenlet = None\n        self.on_hold = True\n        self.state = 'connected'\n        hold_supported_streams = (stream for stream in self.streams if stream.hold_supported)\n        notification_center.post_notification('SIPSessionDidChangeHoldState', self, NotificationData(originator='local', on_hold=True, partial=any(not stream.on_hold_by_local for stream in hold_supported_streams)))\n        for notification in unhandled_notifications:\n            self.handle_notification(notification)\n        if self._hold_in_progress:\n            self._hold_in_progress = False\n        else:\n            for stream in self.streams:\n                stream.unhold()\n            self._send_unhold()\n\n    def _send_unhold(self):\n        self.state = 'sending_proposal'\n        self.greenlet = api.getcurrent()\n        notification_center = NotificationCenter()\n\n        unhandled_notifications = []\n\n        try:\n            local_sdp = SDPSession.new(self._invitation.sdp.active_local)\n            local_sdp.version += 1\n            for stream in self.streams:\n                local_sdp.media[stream.index] = stream.get_local_media(remote_sdp=None, index=stream.index)\n            self._invitation.send_reinvite(sdp=local_sdp)\n\n            received_invitation_state = False\n            received_sdp_update = False\n\n            with api.timeout(self.short_reinvite_timeout):\n                while not received_invitation_state or not received_sdp_update:\n                    notification = self._channel.wait()\n                    if notification.name == 'SIPInvitationGotSDPUpdate':\n                        received_sdp_update = True\n                        if notification.data.succeeded:\n                            local_sdp = notification.data.local_sdp\n                            remote_sdp = notification.data.remote_sdp\n                            for stream in self.streams:\n                                stream.update(local_sdp, remote_sdp, stream.index)\n                    elif notification.name == 'SIPInvitationChangedState':\n                        if notification.data.state == 'connected' and notification.data.sub_state == 'normal':\n                            received_invitation_state = True\n                            notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='local', method='INVITE', code=notification.data.code, reason=notification.data.reason))\n                        elif notification.data.state == 'disconnected':\n                            raise InvitationDisconnectedError(notification.sender, notification.data)\n        except InvitationDisconnectedError, e:\n            self.greenlet = None\n            notification = Notification('SIPInvitationChangedState', e.invitation, e.data)\n            notification.center = notification_center\n            self.handle_notification(notification)\n            return\n        except api.TimeoutError:\n            if not self._cancel_hold():\n                return\n        except SIPCoreError:\n            pass\n\n        self.greenlet = None\n        self.on_hold = False\n        self.state = 'connected'\n        notification_center.post_notification('SIPSessionDidChangeHoldState', self, NotificationData(originator='local', on_hold=False, partial=False))\n        for notification in unhandled_notifications:\n            self.handle_notification(notification)\n        if self._hold_in_progress:\n            for stream in self.streams:\n                stream.hold()\n            self._send_hold()\n\n    def _fail(self, originator, code, reason, error, reason_header=None):\n        notification_center = NotificationCenter()\n        prev_inv_state = self._invitation.state\n        self.state = 'terminating'\n        if prev_inv_state not in (None, 'incoming', 'outgoing', 'early', 'connecting'):\n            notification_center.post_notification('SIPSessionWillEnd', self, NotificationData(originator=originator))\n        if self._invitation.state not in (None, 'disconnecting', 'disconnected'):\n            try:\n                if self._invitation.direction == 'incoming' and self._invitation.state in ('incoming', 'early'):\n                    if 400<=code<=699 and reason is not None:\n                        self._invitation.send_response(code, extra_headers=[reason_header] if reason_header is not None else [])\n                else:\n                    self._invitation.end(extra_headers=[reason_header] if reason_header is not None else [])\n                with api.timeout(1):\n                    while True:\n                        notification = self._channel.wait()\n                        if notification.name == 'SIPInvitationChangedState' and notification.data.state == 'disconnected':\n                            if prev_inv_state in ('connecting', 'connected'):\n                                if notification.data.disconnect_reason in ('timeout', 'missing ACK'):\n                                    sip_code = 200\n                                    sip_reason = 'OK'\n                                    originator = 'local'\n                                elif hasattr(notification.data, 'method'):\n                                    sip_code = 200\n                                    sip_reason = 'OK'\n                                    originator = 'remote'\n                                else:\n                                    sip_code = notification.data.code\n                                    sip_reason = notification.data.reason\n                                    originator = 'local'\n                                notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator=originator, method='BYE', code=sip_code, reason=sip_reason))\n                            elif self._invitation.direction == 'incoming' and prev_inv_state in ('incoming', 'early'):\n                                ack_received = notification.data.disconnect_reason != 'missing ACK'\n                                notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=code, reason=reason, ack_received=ack_received))\n                            elif self._invitation.direction == 'outgoing' and prev_inv_state in ('outgoing', 'early'):\n                                notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='local', method='INVITE', code=487, reason='Session Cancelled'))\n                            break\n            except SIPCoreError:\n                pass\n            except api.TimeoutError:\n                if prev_inv_state in ('connecting', 'connected'):\n                    notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='local', method='BYE', code=408, reason=sip_status_messages[408]))\n        notification_center.remove_observer(self, sender=self._invitation)\n        self.state = 'terminated'\n        notification_center.post_notification('SIPSessionDidFail', self, NotificationData(originator=originator, code=code, reason=reason, failure_reason=error, redirect_identities=None))\n        self.greenlet = None\n\n    def _fail_proposal(self, originator, error):\n        notification_center = NotificationCenter()\n        for stream in self.proposed_streams:\n            try:\n                notification_center.remove_observer(self, sender=stream)\n            except KeyError:\n                # _fail_proposal can be called from reject_proposal, which means the stream will\n                # not have been initialized or the session registered as an observer for it.\n                pass\n            else:\n                stream.deactivate()\n                stream.end()\n        if originator == 'remote' and self._invitation.sub_state == 'received_proposal':\n            try:\n                self._invitation.send_response(488 if self.proposed_streams else 500)\n            except SIPCoreError:\n                pass\n            else:\n                notification_center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=500, reason=sip_status_messages[500], ack_received='unknown'))\n        notification_center.post_notification('SIPSessionHadProposalFailure', self, NotificationData(originator=originator, failure_reason=error, proposed_streams=self.proposed_streams[:]))\n        self.state = 'connected'\n        self.proposed_streams = None\n        self.greenlet = None\n\n    @run_in_green_thread\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_SIPInvitationChangedState(self, notification):\n        if self.state == 'terminated':\n            return\n        if notification.data.originator == 'remote' and notification.data.state not in ('disconnecting', 'disconnected'):\n            contact_header = notification.data.headers.get('Contact', None)\n            if contact_header and 'isfocus' in contact_header[0].parameters:\n                self.remote_focus = True\n        if self.greenlet is not None:\n            if notification.data.state == 'disconnected' and notification.data.prev_state != 'disconnecting':\n                self._channel.send_exception(InvitationDisconnectedError(notification.sender, notification.data))\n            else:\n                self._channel.send(notification)\n        else:\n            self.greenlet = api.getcurrent()\n            unhandled_notifications = []\n            try:\n                if notification.data.state == 'connected' and notification.data.sub_state == 'received_proposal':\n                    self.state = 'received_proposal'\n                    try:\n                        proposed_remote_sdp = self._invitation.sdp.proposed_remote\n                        active_remote_sdp = self._invitation.sdp.active_remote\n                        if len(proposed_remote_sdp.media) < len(active_remote_sdp.media):\n                            engine = Engine()\n                            self._invitation.send_response(488, extra_headers=[WarningHeader(399, engine.user_agent, 'Streams cannot be deleted from the SDP')])\n                            self.state = 'connected'\n                            notification.center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=488, reason=sip_status_messages[488], ack_received='unknown'))\n                            return\n                        for stream in self.streams:\n                            if not stream.validate_update(proposed_remote_sdp, stream.index):\n                                engine = Engine()\n                                self._invitation.send_response(488, extra_headers=[WarningHeader(399, engine.user_agent, 'Failed to update media stream index %d' % stream.index)])\n                                self.state = 'connected'\n                                notification.center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=488, reason=sip_status_messages[488], ack_received='unknown'))\n                                return\n                        added_media_indexes = set()\n                        removed_media_indexes = set()\n                        reused_media_indexes = set()\n                        for index, media_stream in enumerate(proposed_remote_sdp.media):\n                            if index >= len(active_remote_sdp.media):\n                                added_media_indexes.add(index)\n                            elif media_stream.port == 0 and active_remote_sdp.media[index].port > 0:\n                                removed_media_indexes.add(index)\n                            elif media_stream.port > 0 and active_remote_sdp.media[index].port == 0:\n                                reused_media_indexes.add(index)\n                            elif media_stream.media != active_remote_sdp.media[index].media:\n                                added_media_indexes.add(index)\n                                removed_media_indexes.add(index)\n                        if added_media_indexes | reused_media_indexes and removed_media_indexes:\n                            engine = Engine()\n                            self._invitation.send_response(488, extra_headers=[WarningHeader(399, engine.user_agent, 'Both removing AND adding a media stream is currently not supported')])\n                            self.state = 'connected'\n                            notification.center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=488, reason=sip_status_messages[488], ack_received='unknown'))\n                            return\n                        elif added_media_indexes | reused_media_indexes:\n                            self.proposed_streams = []\n                            for index in added_media_indexes | reused_media_indexes:\n                                media_stream = proposed_remote_sdp.media[index]\n                                if media_stream.port != 0:\n                                    for stream_type in MediaStreamRegistry:\n                                        try:\n                                            stream = stream_type.new_from_sdp(self, proposed_remote_sdp, index)\n                                        except UnknownStreamError:\n                                            continue\n                                        except InvalidStreamError as e:\n                                            log.error(\"Invalid stream: {}\".format(e))\n                                            break\n                                        except Exception as e:\n                                            log.exception(\"Exception occurred while setting up stream from SDP: {}\".format(e))\n                                            break\n                                        else:\n                                            stream.index = index\n                                            self.proposed_streams.append(stream)\n                                            break\n                            if self.proposed_streams:\n                                self._invitation.send_response(100)\n                                notification.center.post_notification('SIPSessionNewProposal', sender=self, data=NotificationData(originator='remote', proposed_streams=self.proposed_streams[:]))\n                            else:\n                                self._invitation.send_response(488)\n                                self.state = 'connected'\n                                notification.center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=488, reason=sip_status_messages[488], ack_received='unknown'))\n                            return\n                        else:\n                            local_sdp = SDPSession.new(self._invitation.sdp.active_local)\n                            local_sdp.version += 1\n                            removed_streams = [stream for stream in self.streams if stream.index in removed_media_indexes]\n                            prev_on_hold_streams = set(stream for stream in self.streams if stream.hold_supported and stream.on_hold_by_remote)\n                            for stream in removed_streams:\n                                notification.center.remove_observer(self, sender=stream)\n                                stream.deactivate()\n                                media = local_sdp.media[stream.index]\n                                media.port = 0\n                                media.attributes = []\n                                media.bandwidth_info = []\n                            for stream in self.streams:\n                                local_sdp.media[stream.index] = stream.get_local_media(remote_sdp=proposed_remote_sdp, index=stream.index)\n                            try:\n                                self._invitation.send_response(200, sdp=local_sdp)\n                            except PJSIPError:\n                                for stream in removed_streams:\n                                    self.streams.remove(stream)\n                                    stream.end()\n                                if removed_streams:\n                                    self.end()\n                                    return\n                                else:\n                                    try:\n                                        self._invitation.send_response(488)\n                                    except PJSIPError:\n                                        self.end()\n                                        return\n                            else:\n                                for stream in removed_streams:\n                                    self.streams.remove(stream)\n                                    stream.end()\n                                notification.center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=200, reason=sip_status_messages[200], ack_received='unknown'))\n\n                                received_invitation_state = False\n                                received_sdp_update = False\n                                while not received_sdp_update or not received_invitation_state or self._channel:\n                                    notification = self._channel.wait()\n                                    if notification.name == 'SIPInvitationGotSDPUpdate':\n                                        received_sdp_update = True\n                                        if notification.data.succeeded:\n                                            local_sdp = notification.data.local_sdp\n                                            remote_sdp = notification.data.remote_sdp\n                                            for stream in self.streams:\n                                                stream.update(local_sdp, remote_sdp, stream.index)\n                                    elif notification.name == 'SIPInvitationChangedState':\n                                        if notification.data.state == 'connected' and notification.data.sub_state == 'normal':\n                                            received_invitation_state = True\n                                        elif notification.data.state == 'disconnected':\n                                            raise InvitationDisconnectedError(notification.sender, notification.data)\n                                        else:\n                                            unhandled_notifications.append(notification)\n                                    else:\n                                        unhandled_notifications.append(notification)\n                                on_hold_streams = set(stream for stream in self.streams if stream.hold_supported and stream.on_hold_by_remote)\n                                if on_hold_streams != prev_on_hold_streams:\n                                    hold_supported_streams = (stream for stream in self.streams if stream.hold_supported)\n                                    notification.center.post_notification('SIPSessionDidChangeHoldState', self, NotificationData(originator='remote', on_hold=bool(on_hold_streams),\n                                                                          partial=bool(on_hold_streams) and any(not stream.on_hold_by_remote for stream in hold_supported_streams)))\n                                if removed_media_indexes:\n                                    notification.center.post_notification('SIPSessionDidRenegotiateStreams', self, NotificationData(originator='remote', added_streams=[], removed_streams=removed_streams))\n                    except InvitationDisconnectedError, e:\n                        self.greenlet = None\n                        self.state = 'connected'\n                        notification = Notification('SIPInvitationChangedState', e.invitation, e.data)\n                        notification.center = NotificationCenter()\n                        self.handle_notification(notification)\n                    except SIPCoreError:\n                        self.end()\n                    else:\n                        self.state = 'connected'\n                elif notification.data.state == 'connected' and notification.data.sub_state == 'received_proposal_request':\n                    self.state = 'received_proposal_request'\n                    try:\n                        # An empty proposal was received, generate an offer\n                        self._invitation.send_response(100)\n                        local_sdp = SDPSession.new(self._invitation.sdp.active_local)\n                        local_sdp.version += 1\n                        connection_address = host.outgoing_ip_for(self._invitation.peer_address.ip)\n                        if local_sdp.connection is not None:\n                            local_sdp.connection.address = connection_address\n                        for index, stream in enumerate(self.streams):\n                            stream.reset(index)\n                            media = stream.get_local_media(remote_sdp=None, index=index)\n                            if media.connection is not None:\n                                media.connection.address = connection_address\n                            local_sdp.media[stream.index] = media\n                        self._invitation.send_response(200, sdp=local_sdp)\n                        notification.center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=200, reason=sip_status_messages[200], ack_received='unknown'))\n                        received_invitation_state = False\n                        received_sdp_update = False\n                        while not received_sdp_update or not received_invitation_state or self._channel:\n                            notification = self._channel.wait()\n                            if notification.name == 'SIPInvitationGotSDPUpdate':\n                                received_sdp_update = True\n                                if notification.data.succeeded:\n                                    local_sdp = notification.data.local_sdp\n                                    remote_sdp = notification.data.remote_sdp\n                                    for stream in self.streams:\n                                        stream.update(local_sdp, remote_sdp, stream.index)\n                            elif notification.name == 'SIPInvitationChangedState':\n                                if notification.data.state == 'connected' and notification.data.sub_state == 'normal':\n                                    received_invitation_state = True\n                                elif notification.data.state == 'disconnected':\n                                    raise InvitationDisconnectedError(notification.sender, notification.data)\n                                else:\n                                    unhandled_notifications.append(notification)\n                            else:\n                                unhandled_notifications.append(notification)\n                    except InvitationDisconnectedError, e:\n                        self.greenlet = None\n                        self.state = 'connected'\n                        notification = Notification('SIPInvitationChangedState', e.invitation, e.data)\n                        notification.center = NotificationCenter()\n                        self.handle_notification(notification)\n                    except SIPCoreError:\n                        raise  # FIXME\n                    else:\n                        self.state = 'connected'\n                elif notification.data.prev_state == notification.data.state == 'connected' and notification.data.prev_sub_state == 'received_proposal' and notification.data.sub_state == 'normal':\n                    if notification.data.originator == 'local' and notification.data.code == 487:\n                        proposed_streams = self.proposed_streams\n                        self.proposed_streams = None\n                        self.state = 'connected'\n                        notification.center.post_notification('SIPSessionProposalRejected', self, NotificationData(originator='remote', code=notification.data.code, reason=notification.data.reason, proposed_streams=proposed_streams))\n                        if self._hold_in_progress:\n                            self._send_hold()\n                elif notification.data.state == 'disconnected':\n                    if self.state == 'incoming':\n                        self.state = 'terminated'\n                        if notification.data.originator == 'remote':\n                            notification.center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator='remote', method='INVITE', code=487, reason='Session Cancelled', ack_received='unknown'))\n                            notification.center.post_notification('SIPSessionDidFail', self, NotificationData(originator='remote', code=487, reason='Session Cancelled', failure_reason=notification.data.disconnect_reason, redirect_identities=None))\n                        else:\n                            # There must have been an error involved\n                            notification.center.post_notification('SIPSessionDidFail', self, NotificationData(originator='local', code=0, reason=None, failure_reason=notification.data.disconnect_reason, redirect_identities=None))\n                    else:\n                        self.state = 'terminated'\n                        notification.center.post_notification('SIPSessionWillEnd', self, NotificationData(originator=notification.data.originator))\n                        for stream in self.streams:\n                            notification.center.remove_observer(self, sender=stream)\n                            stream.deactivate()\n                            stream.end()\n                        if notification.data.originator == 'remote':\n                            if hasattr(notification.data, 'method'):\n                                notification.center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator=notification.data.originator, method=notification.data.method, code=200, reason=sip_status_messages[200]))\n                            else:\n                                notification.center.post_notification('SIPSessionDidProcessTransaction', self, NotificationData(originator=notification.data.originator, method='INVITE', code=notification.data.code, reason=notification.data.reason))\n                        self.end_time = ISOTimestamp.now()\n                        notification.center.post_notification('SIPSessionDidEnd', self, NotificationData(originator=notification.data.originator, end_reason=notification.data.disconnect_reason))\n                    notification.center.remove_observer(self, sender=self._invitation)\n            finally:\n                self.greenlet = None\n                for notification in unhandled_notifications:\n                    self.handle_notification(notification)\n\n    def _NH_SIPInvitationGotSDPUpdate(self, notification):\n        if self.greenlet is not None:\n            self._channel.send(notification)\n\n    def _NH_MediaStreamDidInitialize(self, notification):\n        if self.greenlet is not None:\n            self._channel.send(notification)\n\n    def _NH_RTPStreamDidEnableEncryption(self, notification):\n        if notification.sender.type != 'audio':\n            return\n        audio_stream = notification.sender\n        if audio_stream.encryption.type == 'ZRTP':\n            # start ZRTP on the video stream, if applicable\n            try:\n                video_stream = next(stream for stream in self.streams or [] if stream.type=='video')\n            except StopIteration:\n                return\n            if video_stream.encryption.type == 'ZRTP' and not video_stream.encryption.active:\n                video_stream.encryption.zrtp._enable(audio_stream)\n\n    def _NH_MediaStreamDidStart(self, notification):\n        stream = notification.sender\n        if stream.type == 'audio' and stream.encryption.type == 'ZRTP':\n            stream.encryption.zrtp._enable()\n        elif stream.type == 'video' and stream.encryption.type == 'ZRTP':\n            # start ZRTP on the video stream, if applicable\n            try:\n                audio_stream = next(stream for stream in self.streams or [] if stream.type=='audio')\n            except StopIteration:\n                pass\n            else:\n                if audio_stream.encryption.type == 'ZRTP' and audio_stream.encryption.active:\n                    stream.encryption.zrtp._enable(audio_stream)\n        if self.greenlet is not None:\n            self._channel.send(notification)\n\n    def _NH_MediaStreamDidNotInitialize(self, notification):\n        if self.greenlet is not None and self.state not in ('terminating', 'terminated'):\n            self._channel.send_exception(MediaStreamDidNotInitializeError(notification.sender, notification.data))\n\n    def _NH_MediaStreamDidFail(self, notification):\n        if self.greenlet is not None:\n            if self.state not in ('terminating', 'terminated'):\n                self._channel.send_exception(MediaStreamDidFailError(notification.sender, notification.data))\n        else:\n            stream = notification.sender\n            if self.streams == [stream]:\n                self.end()\n            else:\n                try:\n                    self.remove_stream(stream)\n                except IllegalStateError:\n                    self.end()\n\n\nclass SessionManager(object):\n    __metaclass__ = Singleton\n    implements(IObserver)\n\n    def __init__(self):\n        self.sessions = []\n        self.state = None\n        self._channel = coros.queue()\n\n    def start(self):\n        self.state = 'starting'\n        notification_center = NotificationCenter()\n        notification_center.post_notification('SIPSessionManagerWillStart', sender=self)\n        notification_center.add_observer(self, 'SIPInvitationChangedState')\n        notification_center.add_observer(self, 'SIPSessionNewIncoming')\n        notification_center.add_observer(self, 'SIPSessionNewOutgoing')\n        notification_center.add_observer(self, 'SIPSessionDidFail')\n        notification_center.add_observer(self, 'SIPSessionDidEnd')\n        self.state = 'started'\n        notification_center.post_notification('SIPSessionManagerDidStart', sender=self)\n\n    def stop(self):\n        self.state = 'stopping'\n        notification_center = NotificationCenter()\n        notification_center.post_notification('SIPSessionManagerWillEnd', sender=self)\n        for session in self.sessions:\n            session.end()\n        while self.sessions:\n            self._channel.wait()\n        notification_center.remove_observer(self, 'SIPInvitationChangedState')\n        notification_center.remove_observer(self, 'SIPSessionNewIncoming')\n        notification_center.remove_observer(self, 'SIPSessionNewOutgoing')\n        notification_center.remove_observer(self, 'SIPSessionDidFail')\n        notification_center.remove_observer(self, 'SIPSessionDidEnd')\n        self.state = 'stopped'\n        notification_center.post_notification('SIPSessionManagerDidEnd', sender=self)\n\n    @run_in_twisted_thread\n    def handle_notification(self, notification):\n        if notification.name == 'SIPInvitationChangedState' and notification.data.state == 'incoming':\n            account_manager = AccountManager()\n            account = account_manager.find_account(notification.data.request_uri)\n            if account is None:\n                notification.sender.send_response(404)\n                return\n            notification.sender.send_response(100)\n            session = Session(account)\n            session.init_incoming(notification.sender, notification.data)\n        elif notification.name in ('SIPSessionNewIncoming', 'SIPSessionNewOutgoing'):\n            self.sessions.append(notification.sender)\n        elif notification.name in ('SIPSessionDidFail', 'SIPSessionDidEnd'):\n            self.sessions.remove(notification.sender)\n            if self.state == 'stopping':\n                self._channel.send(notification)\n\n\n"
  },
  {
    "path": "sipsimple/storage.py",
    "content": "\n\"\"\"Definitions and implementations of storage backends\"\"\"\n\n__all__ = ['ISIPSimpleStorage', 'ISIPSimpleApplicationDataStorage', 'FileStorage', 'MemoryStorage']\n\nimport os\n\nfrom functools import partial\nfrom zope.interface import Attribute, Interface, implements\n\nfrom sipsimple.account.xcap.storage.file import FileStorage as XCAPFileStorage\nfrom sipsimple.account.xcap.storage.memory import MemoryStorage as XCAPMemoryStorage\nfrom sipsimple.configuration.backend.file import FileBackend as ConfigurationFileBackend\nfrom sipsimple.configuration.backend.memory import MemoryBackend as ConfigurationMemoryBackend\n\n\nclass ISIPSimpleStorage(Interface):\n    \"\"\"Interface describing the backends used for storage throughout SIP Simple\"\"\"\n\n    configuration_backend = Attribute(\"The backend used for the configuration\")\n    xcap_storage_factory  = Attribute(\"The factory used to create XCAP storage backends for each account\")\n\n\nclass ISIPSimpleApplicationDataStorage(Interface):\n    \"\"\"Interface describing the directory used for application data storage \"\"\"\n\n    directory = Attribute(\"The directory used for application data\")\n\n\nclass FileStorage(object):\n    \"\"\"Store/read SIP Simple data to/from files\"\"\"\n\n    implements(ISIPSimpleStorage, ISIPSimpleApplicationDataStorage)\n\n    def __init__(self, directory):\n        self.configuration_backend = ConfigurationFileBackend(os.path.join(directory, 'config'))\n        self.xcap_storage_factory  = partial(XCAPFileStorage, os.path.join(directory, 'xcap'))\n        self.directory = directory\n\n\nclass MemoryStorage(object):\n    \"\"\"Store/read SIP Simple data to/from memory\"\"\"\n\n    implements(ISIPSimpleStorage)\n\n    def __init__(self):\n        self.configuration_backend = ConfigurationMemoryBackend()\n        self.xcap_storage_factory  = XCAPMemoryStorage\n\n\n"
  },
  {
    "path": "sipsimple/streams/__init__.py",
    "content": "\n\"\"\"\nThis module automatically registers media streams to a stream registry\nallowing for a plug and play mechanism of various types of media\nnegotiated in a SIP session that can be added to this library by using\na generic API.\n\nFor actual implementations see rtp/* and msrp/* that have media stream\nimplementations based on their respective RTP and MSRP protocols.\n\"\"\"\n\n__all__ = ['StreamError', 'InvalidStreamError', 'UnknownStreamError', 'IMediaStream', 'MediaStreamRegistry', 'MediaStreamType']\n\nfrom operator import attrgetter\nfrom zope.interface import Interface, Attribute\n\n\nclass StreamError(Exception): pass\nclass InvalidStreamError(StreamError): pass\nclass UnknownStreamError(StreamError): pass\n\n\n# The MediaStream interface\n#\nclass IMediaStream(Interface):\n    type = Attribute(\"A string identifying the stream type (ex: audio, video, ...)\")\n    priority = Attribute(\"An integer value indicating the stream priority relative to the other streams types (higher numbers have higher priority).\")\n\n    session = Attribute(\"Session object to which this stream is attached\")\n\n    hold_supported = Attribute(\"True if the stream supports hold\")\n    on_hold_by_local = Attribute(\"True if the stream is on hold by the local party\")\n    on_hold_by_remote = Attribute(\"True if the stream is on hold by the remote\")\n    on_hold = Attribute(\"True if either on_hold_by_local or on_hold_by_remote is true\")\n\n    # this should be a classmethod, but zopeinterface complains if we decorate it with @classmethod -Dan\n    def new_from_sdp(cls, session, remote_sdp, stream_index):\n        pass\n\n    def get_local_media(self, for_offer):\n        pass\n\n    def initialize(self, session, direction):\n        pass\n\n    def start(self, local_sdp, remote_sdp, stream_index):\n        pass\n\n    def deactivate(self):\n        pass\n\n    def end(self):\n        pass\n\n    def validate_update(self, remote_sdp, stream_index):\n        pass\n\n    def update(self, local_sdp, remote_sdp, stream_index):\n        pass\n\n    def hold(self):\n        pass\n\n    def unhold(self):\n        pass\n\n    def reset(self, stream_index):\n        pass\n\n\n# The MediaStream registry\n#\nclass StreamDescriptor(object):\n    def __init__(self, type):\n        self.type = type\n    def __get__(self, obj, owner):\n        return self if obj is None else obj.get(self.type)\n    def __set__(self, obj, value):\n        raise AttributeError('cannot set attribute')\n    def __delete__(self, obj):\n        raise AttributeError('cannot delete attribute')\n\n\nclass MediaStreamRegistry(object):\n    def __init__(self):\n        self.__types__ = []\n\n    def __iter__(self):\n        return iter(self.__types__)\n\n    def add(self, cls):\n        if cls.type is not None and cls.priority is not None and cls not in self.__types__:\n            self.__types__.append(cls)\n            self.__types__.sort(key=attrgetter('priority'), reverse=True)\n            setattr(self.__class__, cls.type.title().translate(None, ' -_') + 'Stream', StreamDescriptor(cls.type))\n\n    def get(self, type):\n        try:\n            return next(cls for cls in self.__types__ if cls.type == type)\n        except StopIteration:\n            raise UnknownStreamError(\"unknown stream type: %s\" % type)\n\nMediaStreamRegistry = MediaStreamRegistry()\n\n\nclass MediaStreamType(type):\n    \"\"\"Metaclass for MediaStream classes that automatically adds them to the media stream registry\"\"\"\n\n    type = None\n    priority = None\n\n    def __init__(cls, name, bases, dictionary):\n        super(MediaStreamType, cls).__init__(name, bases, dictionary)\n        MediaStreamRegistry.add(cls)\n\n\n# Import the submodules in order for them to register the streams they define in MediaStreamRegistry\nfrom sipsimple.streams import msrp, rtp\n\n"
  },
  {
    "path": "sipsimple/streams/msrp/__init__.py",
    "content": "\n\"\"\"\nHandling of MSRP media streams according to RFC4975, RFC4976, RFC5547 and RFC3994.\n\"\"\"\n\n__all__ = ['MSRPStreamError', 'MSRPStreamBase']\n\nimport traceback\n\nfrom application.notification import NotificationCenter, NotificationData, IObserver\nfrom application.python import Null\nfrom application.system import host\nfrom twisted.internet.error import ConnectionDone\nfrom zope.interface import implements\n\nfrom eventlib import api\nfrom msrplib.connect import DirectConnector, DirectAcceptor, RelayConnection, MSRPRelaySettings\nfrom msrplib.protocol import URI\nfrom msrplib.session import contains_mime_type\n\nfrom sipsimple.account import Account, BonjourAccount\nfrom sipsimple.configuration.settings import SIPSimpleSettings\nfrom sipsimple.core import SDPAttribute, SDPConnection, SDPMediaStream\nfrom sipsimple.streams import IMediaStream, MediaStreamType, StreamError\nfrom sipsimple.threading.green import run_in_green_thread\n\n\nclass MSRPStreamError(StreamError):\n    pass\n\n\nclass MSRPStreamBase(object):\n    __metaclass__ = MediaStreamType\n\n    implements(IMediaStream, IObserver)\n\n    # Attributes that need to be defined by each MSRP stream type\n    type = None\n    priority = None\n    msrp_session_class = None\n\n    media_type = None\n    accept_types = None\n    accept_wrapped_types = None\n\n    # These attributes are always False for any MSRP stream\n    hold_supported = False\n    on_hold = False\n    on_hold_by_local = False\n    on_hold_by_remote = False\n\n    def __new__(cls, *args, **kw):\n        if cls is MSRPStreamBase:\n            raise TypeError(\"MSRPStreamBase cannot be instantiated directly\")\n        return object.__new__(cls)\n\n    def __init__(self, direction='sendrecv'):\n        self.direction = direction\n        self.greenlet = None\n        self.local_media = None\n        self.remote_media = None\n        self.msrp = None  # Placeholder for the MSRPTransport that will be set when started\n        self.msrp_connector = None\n        self.cpim_enabled = None  # Boolean value. None means it was not negotiated yet\n        self.session = None\n        self.msrp_session = None\n        self.shutting_down = False\n        self.local_role = None\n        self.remote_role = None\n        self.transport = None\n        self.remote_accept_types = None\n        self.remote_accept_wrapped_types = None\n\n        self._initialize_done = False\n        self._done = False\n        self._failure_reason = None\n\n    @property\n    def local_uri(self):\n        msrp = self.msrp or self.msrp_connector\n        return msrp.local_uri if msrp is not None else None\n\n    def _create_local_media(self, uri_path):\n        transport = \"TCP/TLS/MSRP\" if uri_path[-1].use_tls else \"TCP/MSRP\"\n        attributes = [SDPAttribute(\"path\", \" \".join(str(uri) for uri in uri_path))]\n        if self.direction not in [None, 'sendrecv']:\n            attributes.append(SDPAttribute(self.direction, ''))\n        if self.accept_types is not None:\n            attributes.append(SDPAttribute(\"accept-types\", \" \".join(self.accept_types)))\n        if self.accept_wrapped_types is not None:\n            attributes.append(SDPAttribute(\"accept-wrapped-types\", \" \".join(self.accept_wrapped_types)))\n        attributes.append(SDPAttribute(\"setup\", self.local_role))\n        local_ip = uri_path[-1].host\n        connection = SDPConnection(local_ip)\n        return SDPMediaStream(self.media_type, uri_path[-1].port or 2855, transport, connection=connection, formats=[\"*\"], attributes=attributes)\n\n    # The public API (the IMediaStream interface)\n\n    # noinspection PyUnusedLocal\n    def get_local_media(self, remote_sdp=None, index=0):\n        return self.local_media\n\n    def new_from_sdp(self, session, remote_sdp, stream_index):\n        raise NotImplementedError\n\n    @run_in_green_thread\n    def initialize(self, session, direction):\n        self.greenlet = api.getcurrent()\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, sender=self)\n        try:\n            self.session = session\n            self.transport = self.session.account.msrp.transport\n            outgoing = direction == 'outgoing'\n            logger = NotificationProxyLogger()\n            if self.session.account is BonjourAccount():\n                if outgoing:\n                    self.msrp_connector = DirectConnector(logger=logger)\n                    self.local_role = 'active'\n                else:\n                    if self.transport == 'tls' and None in (self.session.account.tls_credentials.cert, self.session.account.tls_credentials.key):\n                        raise MSRPStreamError(\"Cannot accept MSRP connection without a TLS certificate\")\n                    self.msrp_connector = DirectAcceptor(logger=logger)\n                    self.local_role = 'passive'\n            else:\n                if self.session.account.msrp.connection_model == 'relay':\n                    if not outgoing and self.remote_role in ('actpass', 'passive'):\n                        # 'passive' not allowed by the RFC but play nice for interoperability. -Saul\n                        self.msrp_connector = DirectConnector(logger=logger, use_sessmatch=True)\n                        self.local_role = 'active'\n                    elif outgoing and not self.session.account.nat_traversal.use_msrp_relay_for_outbound:\n                        self.msrp_connector = DirectConnector(logger=logger, use_sessmatch=True)\n                        self.local_role = 'active'\n                    else:\n                        if self.session.account.nat_traversal.msrp_relay is None:\n                            relay_host = relay_port = None\n                        else:\n                            if self.transport != self.session.account.nat_traversal.msrp_relay.transport:\n                                raise MSRPStreamError(\"MSRP relay transport conflicts with MSRP transport setting\")\n                            relay_host = self.session.account.nat_traversal.msrp_relay.host\n                            relay_port = self.session.account.nat_traversal.msrp_relay.port\n                        relay = MSRPRelaySettings(domain=self.session.account.uri.host,\n                                                  username=self.session.account.uri.user,\n                                                  password=self.session.account.credentials.password,\n                                                  host=relay_host,\n                                                  port=relay_port,\n                                                  use_tls=self.transport=='tls')\n                        self.msrp_connector = RelayConnection(relay, 'passive', logger=logger, use_sessmatch=True)\n                        self.local_role = 'actpass' if outgoing else 'passive'\n                else:\n                    if not outgoing and self.remote_role in ('actpass', 'passive'):\n                        # 'passive' not allowed by the RFC but play nice for interoperability. -Saul\n                        self.msrp_connector = DirectConnector(logger=logger, use_sessmatch=True)\n                        self.local_role = 'active'\n                    else:\n                        if not outgoing and self.transport == 'tls' and None in (self.session.account.tls_credentials.cert, self.session.account.tls_credentials.key):\n                            raise MSRPStreamError(\"Cannot accept MSRP connection without a TLS certificate\")\n                        self.msrp_connector = DirectAcceptor(logger=logger, use_sessmatch=True)\n                        self.local_role = 'actpass' if outgoing else 'passive'\n            full_local_path = self.msrp_connector.prepare(local_uri=URI(host=host.default_ip, port=0, use_tls=self.transport=='tls', credentials=self.session.account.tls_credentials))\n            self.local_media = self._create_local_media(full_local_path)\n        except Exception, e:\n            notification_center.post_notification('MediaStreamDidNotInitialize', sender=self, data=NotificationData(reason=str(e)))\n        else:\n            notification_center.post_notification('MediaStreamDidInitialize', sender=self)\n        finally:\n            self._initialize_done = True\n            self.greenlet = None\n\n    # noinspection PyUnusedLocal\n    @run_in_green_thread\n    def start(self, local_sdp, remote_sdp, stream_index):\n        self.greenlet = api.getcurrent()\n        notification_center = NotificationCenter()\n        context = 'sdp_negotiation'\n        try:\n            remote_media = remote_sdp.media[stream_index]\n            self.remote_media = remote_media\n            self.remote_accept_types = remote_media.attributes.getfirst('accept-types', '').split()\n            self.remote_accept_wrapped_types = remote_media.attributes.getfirst('accept-wrapped-types', '').split()\n            self.cpim_enabled = contains_mime_type(self.accept_types, 'message/cpim') and contains_mime_type(self.remote_accept_types, 'message/cpim')\n            remote_uri_path = remote_media.attributes.getfirst('path')\n            if remote_uri_path is None:\n                raise AttributeError(\"remote SDP media does not have 'path' attribute\")\n            full_remote_path = [URI.parse(uri) for uri in remote_uri_path.split()]\n            remote_transport = 'tls' if full_remote_path[0].use_tls else 'tcp'\n            if self.transport != remote_transport:\n                raise MSRPStreamError(\"remote transport ('%s') different from local transport ('%s')\" % (remote_transport, self.transport))\n            if isinstance(self.session.account, Account) and self.local_role == 'actpass':\n                remote_setup = remote_media.attributes.getfirst('setup', 'passive')\n                if remote_setup == 'passive':\n                    # If actpass is offered connectors are always started as passive\n                    # We need to switch to active if the remote answers with passive\n                    if self.session.account.msrp.connection_model == 'relay':\n                        self.msrp_connector.mode = 'active'\n                    else:\n                        local_uri = self.msrp_connector.local_uri\n                        logger = self.msrp_connector.logger\n                        self.msrp_connector = DirectConnector(logger=logger, use_sessmatch=True)\n                        self.msrp_connector.prepare(local_uri)\n            context = 'start'\n            self.msrp = self.msrp_connector.complete(full_remote_path)\n            if self.msrp_session_class is not None:\n                self.msrp_session = self.msrp_session_class(self.msrp, accept_types=self.accept_types, on_incoming_cb=self._handle_incoming, automatic_reports=False)\n            self.msrp_connector = None\n        except Exception, e:\n            self._failure_reason = str(e)\n            notification_center.post_notification('MediaStreamDidFail', sender=self, data=NotificationData(context=context, reason=self._failure_reason))\n        else:\n            notification_center.post_notification('MediaStreamDidStart', sender=self)\n        finally:\n            self.greenlet = None\n\n    def deactivate(self):\n        self.shutting_down = True\n\n    @run_in_green_thread\n    def end(self):\n        if self._done:\n            return\n        self._done = True\n        notification_center = NotificationCenter()\n        if not self._initialize_done:\n            # we are in the middle of initialize()\n            try:\n                msrp_connector = self.msrp_connector\n                if self.greenlet is not None:\n                    api.kill(self.greenlet)\n                if msrp_connector is not None:\n                    msrp_connector.cleanup()\n            finally:\n                notification_center.post_notification('MediaStreamDidNotInitialize', sender=self, data=NotificationData(reason='Interrupted'))\n                notification_center.remove_observer(self, sender=self)\n                self.msrp_connector = None\n                self.greenlet = None\n        else:\n            notification_center.post_notification('MediaStreamWillEnd', sender=self)\n            msrp = self.msrp\n            msrp_session = self.msrp_session\n            msrp_connector = self.msrp_connector\n            try:\n                if self.greenlet is not None:\n                    api.kill(self.greenlet)\n                if msrp_session is not None:\n                    msrp_session.shutdown()\n                elif msrp is not None:\n                    msrp.loseConnection(wait=False)\n                if msrp_connector is not None:\n                    msrp_connector.cleanup()\n            finally:\n                notification_center.post_notification('MediaStreamDidEnd', sender=self, data=NotificationData(error=self._failure_reason))\n                notification_center.remove_observer(self, sender=self)\n                self.msrp = None\n                self.msrp_session = None\n                self.msrp_connector = None\n                self.session = None\n                self.greenlet = None\n\n    # noinspection PyMethodMayBeStatic,PyUnusedLocal\n    def validate_update(self, remote_sdp, stream_index):\n        return True  # TODO\n\n    def update(self, local_sdp, remote_sdp, stream_index):\n        pass  # TODO\n\n    def hold(self):\n        pass\n\n    def unhold(self):\n        pass\n\n    def reset(self, stream_index):\n        pass\n\n    # Internal IObserver interface\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    # Internal message handlers\n\n    def _handle_incoming(self, chunk=None, error=None):\n        notification_center = NotificationCenter()\n        if error is not None:\n            if self.shutting_down and isinstance(error.value, ConnectionDone):\n                return\n            self._failure_reason = error.getErrorMessage()\n            notification_center.post_notification('MediaStreamDidFail', sender=self, data=NotificationData(context='reading', reason=self._failure_reason))\n        elif chunk is not None:\n            method_handler = getattr(self, '_handle_%s' % chunk.method, None)\n            if method_handler is not None:\n                method_handler(chunk)\n\n    def _handle_REPORT(self, chunk):\n        pass\n\n    def _handle_SEND(self, chunk):\n        pass\n\n\n# temporary solution. to be replaced later by a better logging system in msrplib -Dan\n#\n\nclass ChunkInfo(object):\n    __slots__ = 'content_type', 'header', 'footer', 'data'\n\n    def __init__(self, content_type, header='', footer='', data=''):\n        self.content_type = content_type\n        self.header = header\n        self.footer = footer\n        self.data = data\n\n    def __repr__(self):\n        return \"{0.__class__.__name__}(content_type={0.content_type!r}, header={0.header!r}, footer={0.footer!r}, data={0.data!r})\".format(self)\n\n    @property\n    def content(self):\n        return self.header + self.data + self.footer\n\n    @property\n    def normalized_content(self):\n        if not self.data:\n            return self.header + self.footer\n        elif self.content_type == 'message/cpim':\n            headers, sep, body = self.data.partition('\\r\\n\\r\\n')\n            if not sep:\n                return self.header + self.data + self.footer\n            mime_headers, mime_sep, mime_body = body.partition('\\n\\n')\n            if not mime_sep:\n                return self.header + self.data + self.footer\n            for mime_header in mime_headers.lower().splitlines():\n                if mime_header.startswith('content-type:'):\n                    wrapped_content_type = mime_header[13:].partition(';')[0].strip()\n                    break\n            else:\n                wrapped_content_type = None\n            if wrapped_content_type is None or wrapped_content_type == 'application/im-iscomposing+xml' or wrapped_content_type.startswith(('text/', 'message/')):\n                data = self.data\n            else:\n                data = headers + sep + mime_headers + mime_sep + '<<<stripped data>>>'\n            return self.header + data + self.footer\n        elif self.content_type is None or self.content_type == 'application/im-iscomposing+xml' or self.content_type.startswith(('text/', 'message/')):\n            return self.header + self.data + self.footer\n        else:\n            return self.header + '<<<stripped data>>>' + self.footer\n\n\nclass NotificationProxyLogger(object):\n    def __init__(self):\n        from application import log\n        self.level = log.level\n        self.notification_center = NotificationCenter()\n        self.log_settings = SIPSimpleSettings().logs\n\n    def received_chunk(self, data, transport):\n        if self.log_settings.trace_msrp:\n            chunk_info = ChunkInfo(data.content_type, header=data.chunk_header, footer=data.chunk_footer, data=data.data)\n            notification_data = NotificationData(direction='incoming', local_address=transport.getHost(), remote_address=transport.getPeer(), data=chunk_info.normalized_content, illegal=False)\n            self.notification_center.post_notification('MSRPTransportTrace', sender=transport, data=notification_data)\n\n    def sent_chunk(self, data, transport):\n        if self.log_settings.trace_msrp:\n            chunk_info = ChunkInfo(data.content_type, header=data.encoded_header, footer=data.encoded_footer, data=data.data)\n            notification_data = NotificationData(direction='outgoing', local_address=transport.getHost(), remote_address=transport.getPeer(), data=chunk_info.normalized_content, illegal=False)\n            self.notification_center.post_notification('MSRPTransportTrace', sender=transport, data=notification_data)\n\n    def received_illegal_data(self, data, transport):\n        if self.log_settings.trace_msrp:\n            notification_data = NotificationData(direction='incoming', local_address=transport.getHost(), remote_address=transport.getPeer(), data=data, illegal=True)\n            self.notification_center.post_notification('MSRPTransportTrace', sender=transport, data=notification_data)\n\n    def debug(self, message, *args, **kw):\n        pass\n\n    def info(self, message, *args, **kw):\n        if self.log_settings.trace_msrp:\n            self.notification_center.post_notification('MSRPLibraryLog', data=NotificationData(message=message % args if args else message, level=self.level.INFO))\n\n    def warning(self, message, *args, **kw):\n        if self.log_settings.trace_msrp:\n            self.notification_center.post_notification('MSRPLibraryLog', data=NotificationData(message=message % args if args else message, level=self.level.WARNING))\n\n    warn = warning\n\n    def error(self, message, *args, **kw):\n        if self.log_settings.trace_msrp:\n            self.notification_center.post_notification('MSRPLibraryLog', data=NotificationData(message=message % args if args else message, level=self.level.ERROR))\n\n    def exception(self, message='', *args, **kw):\n        if self.log_settings.trace_msrp:\n            message = message % args if args else message\n            exception = traceback.format_exc()\n            self.notification_center.post_notification('MSRPLibraryLog', data=NotificationData(message=message + '\\n' + exception if message else exception, level=self.level.ERROR))\n\n    def critical(self, message, *args, **kw):\n        if self.log_settings.trace_msrp:\n            self.notification_center.post_notification('MSRPLibraryLog', data=NotificationData(message=message % args if args else message, level=self.level.CRITICAL))\n\n    fatal = critical\n\n\nfrom sipsimple.streams.msrp import chat, filetransfer, screensharing\n"
  },
  {
    "path": "sipsimple/streams/msrp/chat.py",
    "content": "\n\"\"\"\nThis module provides classes to parse and generate SDP related to SIP sessions that negotiate Instant Messaging, including CPIM as defined in RFC3862\n\"\"\"\n\nimport cPickle as pickle\nimport codecs\nimport os\nimport random\nimport re\n\nfrom application.python.descriptor import WriteOnceAttribute\nfrom application.notification import IObserver, NotificationCenter, NotificationData\nfrom application.python import Null\nfrom application.python.types import Singleton\nfrom application.system import openfile\nfrom collections import defaultdict\nfrom email.message import Message as EmailMessage\nfrom email.parser import Parser as EmailParser\nfrom eventlib.coros import queue\nfrom eventlib.proc import spawn, ProcExit\nfrom functools import partial\nfrom msrplib.protocol import FailureReportHeader, SuccessReportHeader, UseNicknameHeader\nfrom msrplib.session import MSRPSession, contains_mime_type\nfrom otr import OTRSession, OTRTransport, OTRState, SMPStatus\nfrom otr.cryptography import DSAPrivateKey\nfrom otr.exceptions import IgnoreMessage, UnencryptedMessage, EncryptedMessageError, OTRError\nfrom zope.interface import implements\n\nfrom sipsimple.core import SIPURI, BaseSIPURI\nfrom sipsimple.payloads import ParserError\nfrom sipsimple.payloads.iscomposing import IsComposingDocument, State, LastActive, Refresh, ContentType\nfrom sipsimple.storage import ISIPSimpleApplicationDataStorage\nfrom sipsimple.streams import InvalidStreamError, UnknownStreamError\nfrom sipsimple.streams.msrp import MSRPStreamError, MSRPStreamBase\nfrom sipsimple.threading import run_in_thread, run_in_twisted_thread\nfrom sipsimple.threading.green import run_in_green_thread\nfrom sipsimple.util import MultilingualText, ISOTimestamp\n\n\n__all__ = ['ChatStream', 'ChatStreamError', 'ChatIdentity', 'CPIMPayload', 'CPIMHeader', 'CPIMNamespace', 'CPIMParserError', 'OTRState', 'SMPStatus']\n\n\nclass OTRTrustedPeer(object):\n    fingerprint = WriteOnceAttribute()  # in order to be hashable this needs to be immutable\n\n    def __init__(self, fingerprint, description=u'', **kw):\n        if not isinstance(fingerprint, basestring):\n            raise TypeError(\"fingerprint must be a string\")\n        self.fingerprint = fingerprint\n        self.description = description\n        self.__dict__.update(kw)\n\n    def __hash__(self):\n        return hash(self.fingerprint)\n\n    def __eq__(self, other):\n        if isinstance(other, OTRTrustedPeer):\n            return self.fingerprint == other.fingerprint\n        elif isinstance(other, basestring):\n            return self.fingerprint == other\n        else:\n            return NotImplemented\n\n    def __ne__(self, other):\n        return not (self == other)\n\n    def __repr__(self):\n        return \"{0.__class__.__name__}({0.fingerprint!r}, description={0.description!r})\".format(self)\n\n    def __reduce__(self):\n        return self.__class__, (self.fingerprint,), self.__dict__\n\n\nclass OTRTrustedPeerSet(object):\n    def __init__(self, iterable=()):\n        self.__data__ = {}\n        self.update(iterable)\n\n    def __repr__(self):\n        return \"{}({})\".format(self.__class__.__name__, self.__data__.values())\n\n    def __contains__(self, item):\n        return item in self.__data__\n\n    def __getitem__(self, item):\n        return self.__data__[item]\n\n    def __iter__(self):\n        return self.__data__.itervalues()\n\n    def __len__(self):\n        return len(self.__data__)\n\n    def get(self, item, default=None):\n        return self.__data__.get(item, default)\n\n    def add(self, item):\n        if not isinstance(item, OTRTrustedPeer):\n            raise TypeError(\"item should be and instance of OTRTrustedPeer\")\n        self.__data__[item.fingerprint] = item\n\n    def remove(self, item):\n        del self.__data__[item]\n\n    def discard(self, item):\n        self.__data__.pop(item, None)\n\n    def update(self, iterable=()):\n        for item in iterable:\n            self.add(item)\n\n\nclass OTRCache(object):\n    __metaclass__ = Singleton\n\n    def __init__(self):\n        from sipsimple.application import SIPApplication\n        if SIPApplication.storage is None:\n            raise RuntimeError(\"Cannot access the OTR cache before SIPApplication.storage is defined\")\n        if ISIPSimpleApplicationDataStorage.providedBy(SIPApplication.storage):\n            self.key_file = os.path.join(SIPApplication.storage.directory, 'otr.key')\n            self.trusted_file = os.path.join(SIPApplication.storage.directory, 'otr.trusted')\n            try:\n                self.private_key = DSAPrivateKey.load(self.key_file)\n                if self.private_key.key_size != 1024:\n                    raise ValueError\n            except (EnvironmentError, ValueError):\n                self.private_key = DSAPrivateKey.generate()\n                self.private_key.save(self.key_file)\n            try:\n                self.trusted_peers = pickle.load(open(self.trusted_file, 'rb'))\n                if not isinstance(self.trusted_peers, OTRTrustedPeerSet) or not all(isinstance(item, OTRTrustedPeer) for item in self.trusted_peers):\n                    raise ValueError(\"invalid OTR trusted peers file\")\n            except Exception:\n                self.trusted_peers = OTRTrustedPeerSet()\n                self.save()\n        else:\n            self.key_file = self.trusted_file = None\n            self.private_key = DSAPrivateKey.generate()\n            self.trusted_peers = OTRTrustedPeerSet()\n\n    # def generate_private_key(self):\n    #     self.private_key = DSAPrivateKey.generate()\n    #     if self.key_file:\n    #         self.private_key.save(self.key_file)\n\n    @run_in_thread('file-io')\n    def save(self):\n        if self.trusted_file is not None:\n            with openfile(self.trusted_file, 'wb', permissions=0600) as trusted_file:\n                pickle.dump(self.trusted_peers, trusted_file)\n\n\nclass OTREncryption(object):\n    implements(IObserver)\n\n    def __init__(self, stream):\n        self.stream = stream\n        self.otr_cache = OTRCache()\n        self.otr_session = OTRSession(self.otr_cache.private_key, self.stream, supported_versions={3})  # we need at least OTR-v3 for question based SMP\n\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, sender=stream)\n        notification_center.add_observer(self, sender=self.otr_session)\n\n    @property\n    def active(self):\n        try:\n            return self.otr_session.encrypted\n        except AttributeError:\n            return False\n\n    @property\n    def cipher(self):\n        return 'AES-128-CTR' if self.active else None\n\n    @property\n    def key_fingerprint(self):\n        try:\n            return self.otr_session.local_private_key.public_key.fingerprint\n        except AttributeError:\n            return None\n\n    @property\n    def peer_fingerprint(self):\n        try:\n            return self.otr_session.remote_public_key.fingerprint\n        except AttributeError:\n            return None\n\n    @property\n    def peer_name(self):\n        try:\n            return self.__dict__['peer_name']\n        except KeyError:\n            trusted_peer = self.otr_cache.trusted_peers.get(self.peer_fingerprint, None)\n            if trusted_peer is None:\n                return u''\n            else:\n                return self.__dict__.setdefault('peer_name', trusted_peer.description)\n\n    @peer_name.setter\n    def peer_name(self, name):\n        old_name = self.peer_name\n        new_name = self.__dict__['peer_name'] = name\n        if old_name != new_name:\n            trusted_peer = self.otr_cache.trusted_peers.get(self.peer_fingerprint, None)\n            if trusted_peer is not None:\n                trusted_peer.description = new_name\n                self.otr_cache.save()\n            notification_center = NotificationCenter()\n            notification_center.post_notification(\"ChatStreamOTRPeerNameChanged\", sender=self.stream, data=NotificationData(name=name))\n\n    @property\n    def verified(self):\n        return self.peer_fingerprint in self.otr_cache.trusted_peers\n\n    @verified.setter\n    def verified(self, value):\n        peer_fingerprint = self.peer_fingerprint\n        old_verified = peer_fingerprint in self.otr_cache.trusted_peers\n        new_verified = bool(value)\n        if peer_fingerprint is None or new_verified == old_verified:\n            return\n        if new_verified:\n            self.otr_cache.trusted_peers.add(OTRTrustedPeer(peer_fingerprint, description=self.peer_name))\n        else:\n            self.otr_cache.trusted_peers.remove(peer_fingerprint)\n        self.otr_cache.save()\n        notification_center = NotificationCenter()\n        notification_center.post_notification(\"ChatStreamOTRVerifiedStateChanged\", sender=self.stream, data=NotificationData(verified=new_verified))\n\n    @run_in_twisted_thread\n    def start(self):\n        if self.otr_session is not None:\n            self.otr_session.start()\n\n    @run_in_twisted_thread\n    def stop(self):\n        if self.otr_session is not None:\n            self.otr_session.stop()\n\n    @run_in_twisted_thread\n    def smp_verify(self, secret, question=None):\n        self.otr_session.smp_verify(secret, question)\n\n    @run_in_twisted_thread\n    def smp_answer(self, secret):\n        self.otr_session.smp_answer(secret)\n\n    @run_in_twisted_thread\n    def smp_abort(self):\n        self.otr_session.smp_abort()\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_MediaStreamDidStart(self, notification):\n        if self.stream.start_otr:\n            self.otr_session.start()\n\n    def _NH_MediaStreamDidEnd(self, notification):\n        notification.center.remove_observer(self, sender=self.stream)\n        notification.center.remove_observer(self, sender=self.otr_session)\n        self.otr_session.stop()\n        self.otr_session = None\n        self.stream = None\n\n    _NH_MediaStreamDidNotInitialize = _NH_MediaStreamDidEnd\n\n    def _NH_OTRSessionStateChanged(self, notification):\n        notification.center.post_notification('ChatStreamOTREncryptionStateChanged', sender=self.stream, data=notification.data)\n\n    def _NH_OTRSessionSMPVerificationDidStart(self, notification):\n        notification.center.post_notification('ChatStreamSMPVerificationDidStart', sender=self.stream, data=notification.data)\n\n    def _NH_OTRSessionSMPVerificationDidNotStart(self, notification):\n        notification.center.post_notification('ChatStreamSMPVerificationDidNotStart', sender=self.stream, data=notification.data)\n\n    def _NH_OTRSessionSMPVerificationDidEnd(self, notification):\n        notification.center.post_notification('ChatStreamSMPVerificationDidEnd', sender=self.stream, data=notification.data)\n\n\nclass ChatStreamError(MSRPStreamError): pass\n\n\nclass ChatStream(MSRPStreamBase):\n    type = 'chat'\n    priority = 1\n    msrp_session_class = MSRPSession\n\n    media_type = 'message'\n    accept_types = ['message/cpim', 'text/*', 'image/*', 'application/im-iscomposing+xml']\n    accept_wrapped_types = ['text/*', 'image/*', 'application/im-iscomposing+xml']\n\n    prefer_cpim = True\n    start_otr = True\n\n    def __init__(self):\n        super(ChatStream, self).__init__(direction='sendrecv')\n        self.message_queue = queue()\n        self.sent_messages = set()\n        self.incoming_queue = defaultdict(list)\n        self.message_queue_thread = None\n        self.encryption = OTREncryption(self)\n\n    @classmethod\n    def new_from_sdp(cls, session, remote_sdp, stream_index):\n        remote_stream = remote_sdp.media[stream_index]\n        if remote_stream.media != 'message':\n            raise UnknownStreamError\n        expected_transport = 'TCP/TLS/MSRP' if session.account.msrp.transport=='tls' else 'TCP/MSRP'\n        if remote_stream.transport != expected_transport:\n            raise InvalidStreamError(\"expected %s transport in chat stream, got %s\" % (expected_transport, remote_stream.transport))\n        if remote_stream.formats != ['*']:\n            raise InvalidStreamError(\"wrong format list specified\")\n        stream = cls()\n        stream.remote_role = remote_stream.attributes.getfirst('setup', 'active')\n        if remote_stream.direction != 'sendrecv':\n            raise InvalidStreamError(\"Unsupported direction for chat stream: %s\" % remote_stream.direction)\n        remote_accept_types = remote_stream.attributes.getfirst('accept-types')\n        if remote_accept_types is None:\n            raise InvalidStreamError(\"remote SDP media does not have 'accept-types' attribute\")\n        if not any(contains_mime_type(cls.accept_types, mime_type) for mime_type in remote_accept_types.split()):\n            raise InvalidStreamError(\"no compatible media types found\")\n        return stream\n\n    @property\n    def local_identity(self):\n        try:\n            return ChatIdentity(self.session.local_identity.uri, self.session.local_identity.display_name)\n        except AttributeError:\n            return None\n\n    @property\n    def remote_identity(self):\n        try:\n            return ChatIdentity(self.session.remote_identity.uri, self.session.remote_identity.display_name)\n        except AttributeError:\n            return None\n\n    @property\n    def private_messages_allowed(self):\n        return 'private-messages' in self.chatroom_capabilities\n\n    @property\n    def nickname_allowed(self):\n        return 'nickname' in self.chatroom_capabilities\n\n    @property\n    def chatroom_capabilities(self):\n        try:\n            if self.cpim_enabled and self.session.remote_focus:\n                return ' '.join(self.remote_media.attributes.getall('chatroom')).split()\n        except AttributeError:\n            pass\n        return []\n\n    def _NH_MediaStreamDidStart(self, notification):\n        self.message_queue_thread = spawn(self._message_queue_handler)\n\n    def _NH_MediaStreamDidNotInitialize(self, notification):\n        message_queue, self.message_queue = self.message_queue, queue()\n        while message_queue:\n            message = message_queue.wait()\n            if message.notify_progress:\n                data = NotificationData(message_id=message.id, message=None, code=0, reason='Stream was closed')\n                notification.center.post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)\n\n    def _NH_MediaStreamDidEnd(self, notification):\n        if self.message_queue_thread is not None:\n            self.message_queue_thread.kill()\n        else:\n            message_queue, self.message_queue = self.message_queue, queue()\n            while message_queue:\n                message = message_queue.wait()\n                if message.notify_progress:\n                    data = NotificationData(message_id=message.id, message=None, code=0, reason='Stream ended')\n                    notification.center.post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)\n\n    def _handle_REPORT(self, chunk):\n        # in theory, REPORT can come with Byte-Range which would limit the scope of the REPORT to the part of the message.\n        if chunk.message_id in self.sent_messages:\n            self.sent_messages.remove(chunk.message_id)\n            notification_center = NotificationCenter()\n            data = NotificationData(message_id=chunk.message_id, message=chunk, code=chunk.status.code, reason=chunk.status.comment)\n            if chunk.status.code == 200:\n                notification_center.post_notification('ChatStreamDidDeliverMessage', sender=self, data=data)\n            else:\n                notification_center.post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)\n\n    def _handle_SEND(self, chunk):\n        if chunk.size == 0:  # keep-alive\n            self.msrp_session.send_report(chunk, 200, 'OK')\n            return\n        content_type = chunk.content_type.lower()\n        if not contains_mime_type(self.accept_types, content_type):\n            self.msrp_session.send_report(chunk, 413, 'Unwanted Message')\n            return\n        if chunk.contflag == '#':\n            self.incoming_queue.pop(chunk.message_id, None)\n            self.msrp_session.send_report(chunk, 200, 'OK')\n            return\n        elif chunk.contflag == '+':\n            self.incoming_queue[chunk.message_id].append(chunk.data)\n            self.msrp_session.send_report(chunk, 200, 'OK')\n            return\n        else:\n            data = ''.join(self.incoming_queue.pop(chunk.message_id, [])) + chunk.data\n\n        if content_type == 'message/cpim':\n            try:\n                payload = CPIMPayload.decode(data)\n            except CPIMParserError:\n                self.msrp_session.send_report(chunk, 400, 'CPIM Parser Error')\n                return\n            else:\n                message = Message(**{name: getattr(payload, name) for name in Message.__slots__})\n                if not contains_mime_type(self.accept_wrapped_types, message.content_type):\n                    self.msrp_session.send_report(chunk, 413, 'Unwanted Message')\n                    return\n                if message.timestamp is None:\n                    message.timestamp = ISOTimestamp.now()\n                if message.sender is None:\n                    message.sender = self.remote_identity\n                private = self.session.remote_focus and len(message.recipients) == 1 and message.recipients[0] != self.remote_identity\n        else:\n            payload = SimplePayload.decode(data, content_type)\n            message = Message(payload.content, payload.content_type, sender=self.remote_identity, recipients=[self.local_identity], timestamp=ISOTimestamp.now())\n            private = False\n\n        try:\n            message.content = self.encryption.otr_session.handle_input(message.content, message.content_type)\n        except IgnoreMessage:\n            self.msrp_session.send_report(chunk, 200, 'OK')\n            return\n        except UnencryptedMessage:\n            encrypted = False\n            encryption_active = True\n        except EncryptedMessageError, e:\n            self.msrp_session.send_report(chunk, 400, str(e))\n            notification_center = NotificationCenter()\n            notification_center.post_notification('ChatStreamOTRError', sender=self, data=NotificationData(error=str(e)))\n            return\n        except OTRError, e:\n            self.msrp_session.send_report(chunk, 200, 'OK')\n            notification_center = NotificationCenter()\n            notification_center.post_notification('ChatStreamOTRError', sender=self, data=NotificationData(error=str(e)))\n            return\n        else:\n            encrypted = encryption_active = self.encryption.active\n\n        if payload.charset is not None:\n            message.content = message.content.decode(payload.charset)\n        elif payload.content_type.startswith('text/'):\n            message.content.decode('utf8')\n\n        notification_center = NotificationCenter()\n        if message.content_type.lower() == IsComposingDocument.content_type:\n            try:\n                document = IsComposingDocument.parse(message.content)\n            except ParserError as e:\n                self.msrp_session.send_report(chunk, 400, str(e))\n                return\n            self.msrp_session.send_report(chunk, 200, 'OK')\n            data = NotificationData(state=document.state.value,\n                                    refresh=document.refresh.value if document.refresh is not None else 120,\n                                    content_type=document.content_type.value if document.content_type is not None else None,\n                                    last_active=document.last_active.value if document.last_active is not None else None,\n                                    sender=message.sender, recipients=message.recipients, private=private,\n                                    encrypted=encrypted, encryption_active=encryption_active)\n            notification_center.post_notification('ChatStreamGotComposingIndication', sender=self, data=data)\n        else:\n            self.msrp_session.send_report(chunk, 200, 'OK')\n            data = NotificationData(message=message, private=private, encrypted=encrypted, encryption_active=encryption_active)\n            notification_center.post_notification('ChatStreamGotMessage', sender=self, data=data)\n\n    def _on_transaction_response(self, message_id, response):\n        if message_id in self.sent_messages and response.code != 200:\n            self.sent_messages.remove(message_id)\n            data = NotificationData(message_id=message_id, message=response, code=response.code, reason=response.comment)\n            NotificationCenter().post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)\n\n    def _on_nickname_transaction_response(self, message_id, response):\n        notification_center = NotificationCenter()\n        if response.code == 200:\n            notification_center.post_notification('ChatStreamDidSetNickname', sender=self, data=NotificationData(message_id=message_id, response=response))\n        else:\n            notification_center.post_notification('ChatStreamDidNotSetNickname', sender=self, data=NotificationData(message_id=message_id, message=response, code=response.code, reason=response.comment))\n\n    def _message_queue_handler(self):\n        notification_center = NotificationCenter()\n        try:\n            while True:\n                message = self.message_queue.wait()\n                if self.msrp_session is None:\n                    if message.notify_progress:\n                        data = NotificationData(message_id=message.id, message=None, code=0, reason='Stream ended')\n                        notification_center.post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)\n                    break\n\n                try:\n                    if isinstance(message.content, unicode):\n                        message.content = message.content.encode('utf8')\n                        charset = 'utf8'\n                    else:\n                        charset = None\n\n                    if not isinstance(message, QueuedOTRInternalMessage):\n                        try:\n                            message.content = self.encryption.otr_session.handle_output(message.content, message.content_type)\n                        except OTRError, e:\n                            raise ChatStreamError(str(e))\n\n                    message.sender = message.sender or self.local_identity\n                    message.recipients = message.recipients or [self.remote_identity]\n\n                    # check if we MUST use CPIM\n                    need_cpim = (message.sender != self.local_identity or message.recipients != [self.remote_identity] or\n                                 message.courtesy_recipients or message.subject or message.timestamp or message.required or message.additional_headers)\n\n                    if need_cpim or not contains_mime_type(self.remote_accept_types, message.content_type):\n                        if not contains_mime_type(self.remote_accept_wrapped_types, message.content_type):\n                            raise ChatStreamError('Unsupported content_type for outgoing message: %r' % message.content_type)\n                        if not self.cpim_enabled:\n                            raise ChatStreamError('Additional message meta-data cannot be sent, because the CPIM wrapper is not used')\n                        if not self.private_messages_allowed and message.recipients != [self.remote_identity]:\n                            raise ChatStreamError('The remote end does not support private messages')\n                        if message.timestamp is None:\n                            message.timestamp = ISOTimestamp.now()\n                        payload = CPIMPayload(charset=charset, **{name: getattr(message, name) for name in Message.__slots__})\n                    elif self.prefer_cpim and self.cpim_enabled and contains_mime_type(self.remote_accept_wrapped_types, message.content_type):\n                        if message.timestamp is None:\n                            message.timestamp = ISOTimestamp.now()\n                        payload = CPIMPayload(charset=charset, **{name: getattr(message, name) for name in Message.__slots__})\n                    else:\n                        payload = SimplePayload(message.content, message.content_type, charset)\n                except ChatStreamError, e:\n                    if message.notify_progress:\n                        data = NotificationData(message_id=message.id, message=None, code=0, reason=e.args[0])\n                        notification_center.post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)\n                    continue\n                else:\n                    content, content_type = payload.encode()\n\n                message_id = message.id\n                notify_progress = message.notify_progress\n                report = 'yes' if notify_progress else 'no'\n\n                chunk = self.msrp_session.make_message(content, content_type=content_type, message_id=message_id)\n                chunk.add_header(FailureReportHeader(report))\n                chunk.add_header(SuccessReportHeader(report))\n\n                try:\n                    self.msrp_session.send_chunk(chunk, response_cb=partial(self._on_transaction_response, message_id))\n                except Exception, e:\n                    if notify_progress:\n                        data = NotificationData(message_id=message_id, message=None, code=0, reason=str(e))\n                        notification_center.post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)\n                except ProcExit:\n                    if notify_progress:\n                        data = NotificationData(message_id=message_id, message=None, code=0, reason='Stream ended')\n                        notification_center.post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)\n                    raise\n                else:\n                    if notify_progress:\n                        self.sent_messages.add(message_id)\n                        notification_center.post_notification('ChatStreamDidSendMessage', sender=self, data=NotificationData(message=chunk))\n        finally:\n            self.message_queue_thread = None\n            while self.sent_messages:\n                message_id = self.sent_messages.pop()\n                data = NotificationData(message_id=message_id, message=None, code=0, reason='Stream ended')\n                notification_center.post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)\n            message_queue, self.message_queue = self.message_queue, queue()\n            while message_queue:\n                message = message_queue.wait()\n                if message.notify_progress:\n                    data = NotificationData(message_id=message.id, message=None, code=0, reason='Stream ended')\n                    notification_center.post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)\n\n    @run_in_twisted_thread\n    def _enqueue_message(self, message):\n        if self._done:\n            if message.notify_progress:\n                data = NotificationData(message_id=message.id, message=None, code=0, reason='Stream ended')\n                NotificationCenter().post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)\n        else:\n            self.message_queue.send(message)\n\n    @run_in_green_thread\n    def _set_local_nickname(self, nickname, message_id):\n        if self.msrp_session is None:\n            # should we generate ChatStreamDidNotSetNickname here?\n            return\n        chunk = self.msrp.make_request('NICKNAME')\n        chunk.add_header(UseNicknameHeader(nickname or u''))\n        try:\n            self.msrp_session.send_chunk(chunk, response_cb=partial(self._on_nickname_transaction_response, message_id))\n        except Exception, e:\n            self._failure_reason = str(e)\n            NotificationCenter().post_notification('MediaStreamDidFail', sender=self, data=NotificationData(context='sending', reason=self._failure_reason))\n\n    def inject_otr_message(self, data):\n        message = QueuedOTRInternalMessage(data)\n        self._enqueue_message(message)\n\n    def send_message(self, content, content_type='text/plain', recipients=None, courtesy_recipients=None, subject=None, timestamp=None, required=None, additional_headers=None):\n        message = QueuedMessage(content, content_type, recipients=recipients, courtesy_recipients=courtesy_recipients, subject=subject, timestamp=timestamp, required=required, additional_headers=additional_headers, notify_progress=True)\n        self._enqueue_message(message)\n        return message.id\n\n    def send_composing_indication(self, state, refresh=None, last_active=None, recipients=None):\n        content = IsComposingDocument.create(state=State(state), refresh=Refresh(refresh) if refresh is not None else None, last_active=LastActive(last_active) if last_active is not None else None, content_type=ContentType('text'))\n        message = QueuedMessage(content, IsComposingDocument.content_type, recipients=recipients, notify_progress=False)\n        self._enqueue_message(message)\n        return message.id\n\n    def set_local_nickname(self, nickname):\n        if not self.nickname_allowed:\n            raise ChatStreamError('Setting nickname is not supported')\n        message_id = '%x' % random.getrandbits(64)\n        self._set_local_nickname(nickname, message_id)\n        return message_id\n\n\nOTRTransport.register(ChatStream)\n\n\n# Chat related objects, including CPIM support as defined in RFC3862\n#\n\nclass ChatIdentity(object):\n    _format_re = re.compile(r'^(?:\"?(?P<display_name>[^<]*[^\"\\s])\"?)?\\s*<(?P<uri>sips?:.+)>$')\n\n    def __init__(self, uri, display_name=None):\n        self.uri = uri\n        self.display_name = display_name\n\n    def __eq__(self, other):\n        if isinstance(other, ChatIdentity):\n            return self.uri.user == other.uri.user and self.uri.host == other.uri.host\n        elif isinstance(other, BaseSIPURI):\n            return self.uri.user == other.user and self.uri.host == other.host\n        elif isinstance(other, basestring):\n            try:\n                other_uri = SIPURI.parse(other)\n            except Exception:\n                return False\n            else:\n                return self.uri.user == other_uri.user and self.uri.host == other_uri.host\n        else:\n            return NotImplemented\n\n    def __ne__(self, other):\n        return not (self == other)\n\n    def __repr__(self):\n        return '{0.__class__.__name__}(uri={0.uri!r}, display_name={0.display_name!r})'.format(self)\n\n    def __str__(self):\n        return self.__unicode__().encode('utf-8')\n\n    def __unicode__(self):\n        if self.display_name:\n            return u'{0.display_name} <{0.uri}>'.format(self)\n        else:\n            return u'<{0.uri}>'.format(self)\n\n    @classmethod\n    def parse(cls, value):\n        match = cls._format_re.match(value)\n        if match is None:\n            raise ValueError('Cannot parse identity value: %r' % value)\n        return cls(SIPURI.parse(match.group('uri')), match.group('display_name'))\n\n\nclass Message(object):\n    __slots__ = 'content', 'content_type', 'sender', 'recipients', 'courtesy_recipients', 'subject', 'timestamp', 'required', 'additional_headers'\n\n    def __init__(self, content, content_type, sender=None, recipients=None, courtesy_recipients=None, subject=None, timestamp=None, required=None, additional_headers=None):\n        self.content = content\n        self.content_type = content_type\n        self.sender = sender\n        self.recipients = recipients or []\n        self.courtesy_recipients = courtesy_recipients or []\n        self.subject = subject\n        self.timestamp = ISOTimestamp(timestamp) if timestamp is not None else None\n        self.required = required or []\n        self.additional_headers = additional_headers or []\n\n\nclass QueuedMessage(Message):\n    __slots__ = 'id', 'notify_progress'\n\n    def __init__(self, content, content_type, sender=None, recipients=None, courtesy_recipients=None, subject=None, timestamp=None, required=None, additional_headers=None, id=None, notify_progress=True):\n        super(QueuedMessage, self).__init__(content, content_type, sender, recipients, courtesy_recipients, subject, timestamp, required, additional_headers)\n        self.id = id or '%x' % random.getrandbits(64)\n        self.notify_progress = notify_progress\n\n\nclass QueuedOTRInternalMessage(QueuedMessage):\n    def __init__(self, content):\n        super(QueuedOTRInternalMessage, self).__init__(content, 'text/plain', notify_progress=False)\n\n\nclass SimplePayload(object):\n    def __init__(self, content, content_type, charset=None):\n        if not isinstance(content, bytes):\n            raise TypeError(\"content should be an instance of bytes\")\n        self.content = content\n        self.content_type = content_type\n        self.charset = charset\n\n    def encode(self):\n        if self.charset is not None:\n            return self.content, '{0.content_type}; charset=\"{0.charset}\"'.format(self)\n        else:\n            return self.content, str(self.content_type)\n\n    @classmethod\n    def decode(cls, content, content_type):\n        if not isinstance(content, bytes):\n            raise TypeError(\"content should be an instance of bytes\")\n        type_helper = EmailParser().parsestr('Content-Type: {}'.format(content_type))\n        content_type = type_helper.get_content_type()\n        charset = type_helper.get_content_charset()\n        return cls(content, content_type, charset)\n\n\nclass CPIMPayload(object):\n    standard_namespace = u'urn:ietf:params:cpim-headers:'\n\n    headers_re = re.compile(r'(?:([^:]+?)\\.)?(.+?):\\s*(.+?)(?:\\r\\n|$)')\n    subject_re = re.compile(r'^(?:;lang=([a-z]{1,8}(?:-[a-z0-9]{1,8})*)\\s+)?(.*)$')\n    namespace_re = re.compile(r'^(?:(\\S+) ?)?<(.*)>$')\n\n    def __init__(self, content, content_type, charset=None, sender=None, recipients=None, courtesy_recipients=None, subject=None, timestamp=None, required=None, additional_headers=None):\n        if not isinstance(content, bytes):\n            raise TypeError(\"content should be an instance of bytes\")\n        self.content = content\n        self.content_type = content_type\n        self.charset = charset\n        self.sender = sender\n        self.recipients = recipients or []\n        self.courtesy_recipients = courtesy_recipients or []\n        self.subject = subject if isinstance(subject, (MultilingualText, type(None))) else MultilingualText(subject)\n        self.timestamp = ISOTimestamp(timestamp) if timestamp is not None else None\n        self.required = required or []\n        self.additional_headers = additional_headers or []\n\n    def encode(self):\n        namespaces = {u'': CPIMNamespace(self.standard_namespace)}\n        header_list = []\n\n        if self.sender is not None:\n            header_list.append(u'From: {}'.format(self.sender))\n        header_list.extend(u'To: {}'.format(recipient) for recipient in self.recipients)\n        header_list.extend(u'cc: {}'.format(recipient) for recipient in self.courtesy_recipients)\n        if self.subject is not None:\n            header_list.append(u'Subject: {}'.format(self.subject))\n            header_list.extend(u'Subject:;lang={} {}'.format(language, translation) for language, translation in self.subject.translations.iteritems())\n        if self.timestamp is not None:\n            header_list.append(u'DateTime: {}'.format(self.timestamp))\n        if self.required:\n            header_list.append(u'Required: {}'.format(','.join(self.required)))\n\n        for header in self.additional_headers:\n            if namespaces.get(header.namespace.prefix) != header.namespace:\n                if header.namespace.prefix:\n                    header_list.append(u'NS: {0.namespace.prefix} <{0.namespace}>'.format(header))\n                else:\n                    header_list.append(u'NS: <{0.namespace}>'.format(header))\n                namespaces[header.namespace.prefix] = header.namespace\n            if header.namespace.prefix:\n                header_list.append(u'{0.namespace.prefix}.{0.name}: {0.value}'.format(header))\n            else:\n                header_list.append(u'{0.name}: {0.value}'.format(header))\n\n        headers = '\\r\\n'.join(header.encode('cpim-header') for header in header_list)\n\n        mime_message = EmailMessage()\n        mime_message.set_payload(self.content)\n        mime_message.set_type(self.content_type)\n        if self.charset is not None:\n            mime_message.set_param('charset', self.charset)\n\n        return headers + '\\r\\n\\r\\n' + mime_message.as_string(), 'message/cpim'\n\n    @classmethod\n    def decode(cls, message):\n        if not isinstance(message, bytes):\n            raise TypeError(\"message should be an instance of bytes\")\n\n        headers, separator, body = message.partition('\\r\\n\\r\\n')\n        if not separator:\n            raise CPIMParserError('Invalid CPIM message')\n\n        sender = None\n        recipients = []\n        courtesy_recipients = []\n        subject = None\n        timestamp = None\n        required = []\n        additional_headers = []\n\n        namespaces = {u'': CPIMNamespace(cls.standard_namespace)}\n        subjects = {}\n\n        for prefix, name, value in cls.headers_re.findall(headers):\n            namespace = namespaces.get(prefix)\n\n            if namespace is None or '.' in name:\n                continue\n\n            try:\n                value = value.decode('cpim-header')\n                if namespace == cls.standard_namespace:\n                    if name == 'From':\n                        sender = ChatIdentity.parse(value)\n                    elif name == 'To':\n                        recipients.append(ChatIdentity.parse(value))\n                    elif name == 'cc':\n                        courtesy_recipients.append(ChatIdentity.parse(value))\n                    elif name == 'Subject':\n                        match = cls.subject_re.match(value)\n                        if match is None:\n                            raise ValueError('Illegal Subject header: %r' % value)\n                        lang, subject = match.groups()\n                        # language tags must be ASCII\n                        subjects[str(lang) if lang is not None else None] = subject\n                    elif name == 'DateTime':\n                        timestamp = ISOTimestamp(value)\n                    elif name == 'Required':\n                        required.extend(re.split(r'\\s*,\\s*', value))\n                    elif name == 'NS':\n                        match = cls.namespace_re.match(value)\n                        if match is None:\n                            raise ValueError('Illegal NS header: %r' % value)\n                        prefix, uri = match.groups()\n                        namespaces[prefix] = CPIMNamespace(uri, prefix)\n                    else:\n                        additional_headers.append(CPIMHeader(name, namespace, value))\n                else:\n                    additional_headers.append(CPIMHeader(name, namespace, value))\n            except ValueError:\n                pass\n\n        if None in subjects:\n            subject = MultilingualText(subjects.pop(None), **subjects)\n        elif subjects:\n            subject = MultilingualText(**subjects)\n\n        mime_message = EmailParser().parsestr(body)\n        content_type = mime_message.get_content_type()\n        if content_type is None:\n            raise CPIMParserError(\"CPIM message missing Content-Type MIME header\")\n        content = mime_message.get_payload()\n        # If the content_type is 'message/imdn+xml' the parser thinks it is a multipart message, hence the result of get_payload\n        # will be a list. Since it is not actually a list we take first item in the list and get the payload again\n        # --Tijmen\n        if content_type == 'message/imdn+xml':\n            content = content[0].get_payload()\n        charset = mime_message.get_content_charset()\n\n        return cls(content, content_type, charset, sender, recipients, courtesy_recipients, subject, timestamp, required, additional_headers)\n\n\nclass CPIMParserError(StandardError): pass\n\n\nclass CPIMNamespace(unicode):\n    def __new__(cls, value, prefix=u''):\n        obj = unicode.__new__(cls, value)\n        obj.prefix = prefix\n        return obj\n\n\nclass CPIMHeader(object):\n    def __init__(self, name, namespace, value):\n        self.name = name\n        self.namespace = namespace\n        self.value = value\n\n\nclass CPIMCodec(codecs.Codec):\n    character_map = {c: u'\\\\u{:04x}'.format(c) for c in range(32) + [127]}\n    character_map[ord(u'\\\\')] = u'\\\\\\\\'\n\n    @classmethod\n    def encode(cls, input, errors='strict'):\n        return input.translate(cls.character_map).encode('utf-8', errors), len(input)\n\n    @classmethod\n    def decode(cls, input, errors='strict'):\n        return input.decode('utf-8', errors).encode('raw-unicode-escape', errors).decode('unicode-escape', errors), len(input)\n\n\ndef cpim_codec_search(name):\n    if name.lower() in ('cpim-header', 'cpim_header'):\n        return codecs.CodecInfo(name='CPIM-header',\n                                encode=CPIMCodec.encode,\n                                decode=CPIMCodec.decode,\n                                incrementalencoder=codecs.IncrementalEncoder,\n                                incrementaldecoder=codecs.IncrementalDecoder,\n                                streamwriter=codecs.StreamWriter,\n                                streamreader=codecs.StreamReader)\ncodecs.register(cpim_codec_search)\ndel cpim_codec_search\n\n\n"
  },
  {
    "path": "sipsimple/streams/msrp/filetransfer.py",
    "content": "\n\"\"\"\nThis module provides classes to parse and generate SDP related to SIP sessions that negotiate File Transfer.\n\"\"\"\n\n__all__ = ['FileTransferStream', 'FileSelector']\n\nimport cPickle as pickle\nimport hashlib\nimport mimetypes\nimport os\nimport random\nimport re\nimport time\nimport uuid\n\nfrom abc import ABCMeta, abstractmethod\nfrom application.notification import NotificationCenter, NotificationData, IObserver\nfrom application.python.threadpool import ThreadPool, run_in_threadpool\nfrom application.python.types import MarkerType\nfrom application.system import FileExistsError, makedirs, openfile, unlink\nfrom itertools import count\nfrom msrplib.protocol import FailureReportHeader, SuccessReportHeader, ContentTypeHeader, IntegerHeaderType, MSRPNamedHeader, HeaderParsingError\nfrom msrplib.session import MSRPSession\nfrom msrplib.transport import make_response\nfrom Queue import Queue\nfrom threading import Event, Lock\nfrom zope.interface import implements\n\nfrom sipsimple.configuration.settings import SIPSimpleSettings\nfrom sipsimple.core import SDPAttribute\nfrom sipsimple.storage import ISIPSimpleApplicationDataStorage\nfrom sipsimple.streams import InvalidStreamError, UnknownStreamError\nfrom sipsimple.streams.msrp import MSRPStreamBase\nfrom sipsimple.threading import run_in_twisted_thread, run_in_thread\nfrom sipsimple.util import sha1\n\n\nHASH = type(hashlib.sha1())\n\n\nclass RandomID: __metaclass__ = MarkerType\n\n\nclass FileSelectorHash(str):\n    _hash_re = re.compile(r'^sha-1(:[0-9A-F]{2}){20}$')\n    _byte_re = re.compile(r'..')\n\n    def __new__(cls, value):\n        if isinstance(value, str):\n            if value.startswith('sha1:'):  # backward compatibility hack (sort of).\n                value = 'sha-1' + value[len('sha1'):]\n            if not cls._hash_re.match(value):\n                raise ValueError(\"Invalid hash value: {!r}\".format(value))\n            return super(FileSelectorHash, cls).__new__(cls, value)\n        elif isinstance(value, (HASH, sha1)):\n            return super(FileSelectorHash, cls).__new__(cls, cls.encode_hash(value))\n        else:\n            raise ValueError(\"Invalid hash value: {!r}\".format(value))\n\n    def __eq__(self, other):\n        if isinstance(other, str):\n            return super(FileSelectorHash, self).__eq__(other)\n        elif isinstance(other, (HASH, sha1)) and other.name.lower() == 'sha1':\n            return super(FileSelectorHash, self).__eq__(self.encode_hash(other))\n        else:\n            return NotImplemented\n\n    def __ne__(self, other):\n        return not self == other\n\n    @classmethod\n    def encode_hash(cls, hash_instance):\n        if hash_instance.name.lower() != 'sha1':\n            raise TypeError(\"Invalid hash type: {.name} (only sha1 hashes are supported).\".format(hash_instance))\n        # unexpected as it may be, using a regular expression is the fastest method to do this\n        return 'sha-1:' + ':'.join(cls._byte_re.findall(hash_instance.hexdigest().upper()))\n\n\nclass FileSelector(object):\n    _name_re = re.compile(r'name:\"([^\"]+)\"')\n    _size_re = re.compile(r'size:(\\d+)')\n    _type_re = re.compile(r'type:([^ ]+)')\n    _hash_re = re.compile(r'hash:([^ ]+)')\n\n    def __init__(self, name=None, type=None, size=None, hash=None, fd=None):\n        # If present, hash should be a sha1 object or a string in the form: sha-1:72:24:5F:E8:65:3D:DA:F3:71:36:2F:86:D4:71:91:3E:E4:A2:CE:2E\n        # According to the specification, only sha1 is supported ATM.\n        self.name = name\n        self.type = type\n        self.size = size\n        self.hash = hash\n        self.fd = fd\n\n    @property\n    def hash(self):\n        return self.__dict__['hash']\n\n    @hash.setter\n    def hash(self, value):\n        self.__dict__['hash'] = None if value is None else FileSelectorHash(value)\n\n    @classmethod\n    def parse(cls, string):\n        name_match = cls._name_re.search(string)\n        size_match = cls._size_re.search(string)\n        type_match = cls._type_re.search(string)\n        hash_match = cls._hash_re.search(string)\n        name = name_match and name_match.group(1).decode('utf-8')\n        size = size_match and int(size_match.group(1))\n        type = type_match and type_match.group(1)\n        hash = hash_match and hash_match.group(1)\n        return cls(name, type, size, hash)\n\n    @classmethod\n    def for_file(cls, path, type=None, hash=None):\n        name = unicode(path)\n        fd = open(name, 'rb')\n        size = os.fstat(fd.fileno()).st_size\n        if type is None:\n            mime_type, encoding = mimetypes.guess_type(name)\n            if encoding is not None:\n                type = 'application/x-%s' % encoding\n            elif mime_type is not None:\n                type = mime_type\n            else:\n                type = 'application/octet-stream'\n        return cls(name, type, size, hash, fd)\n\n    @property\n    def sdp_repr(self):\n        items = [('name', self.name and '\"%s\"' % os.path.basename(self.name).encode('utf-8')), ('type', self.type), ('size', self.size), ('hash', self.hash)]\n        return ' '.join('%s:%s' % (name, value) for name, value in items if value is not None)\n\n\nclass UniqueFilenameGenerator(object):\n    @classmethod\n    def generate(cls, name):\n        yield name\n        prefix, extension = os.path.splitext(name)\n        for x in count(1):\n            yield \"%s-%d%s\" % (prefix, x, extension)\n\n\nclass FileMetadataEntry(object):\n    def __init__(self, hash, filename, partial_hash=None):\n        self.hash = hash\n        self.filename = filename\n        self.mtime = os.path.getmtime(self.filename)\n        self.partial_hash = partial_hash\n\n    @classmethod\n    def from_selector(cls, file_selector):\n        return cls(file_selector.hash.lower(), file_selector.name)\n\n\nclass FileTransfersMetadata(object):\n    __filename__ = 'transfer_metadata'\n    __lifetime__ = 60*60*24*7\n\n    def __init__(self):\n        self.data = {}\n        self.lock = Lock()\n        self.loaded = False\n        self.directory = None\n\n    def _load(self):\n        if self.loaded:\n            return\n        from sipsimple.application import SIPApplication\n        if ISIPSimpleApplicationDataStorage.providedBy(SIPApplication.storage):\n            self.directory = SIPApplication.storage.directory\n        if self.directory is not None:\n            try:\n                with open(os.path.join(self.directory, self.__filename__), 'rb') as f:\n                    data = pickle.loads(f.read())\n            except Exception:\n                data = {}\n            now = time.time()\n            for hash, entry in data.items():\n                try:\n                    mtime = os.path.getmtime(entry.filename)\n                except OSError:\n                    data.pop(hash)\n                else:\n                    if mtime != entry.mtime or now - mtime > self.__lifetime__:\n                        data.pop(hash)\n            self.data.update(data)\n        self.loaded = True\n\n    @run_in_thread('file-io')\n    def _save(self, data):\n        if self.directory is not None:\n            with open(os.path.join(self.directory, self.__filename__), 'wb') as f:\n                f.write(data)\n\n    def __enter__(self):\n        self.lock.acquire()\n        self._load()\n        return self.data\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        if None is exc_type is exc_val is exc_tb:\n            self._save(pickle.dumps(self.data))\n        self.lock.release()\n\n\nclass FileTransferHandler(object):\n    __metaclass__ = ABCMeta\n\n    implements(IObserver)\n\n    threadpool = ThreadPool(name='FileTransfers', min_threads=0, max_threads=100)\n    threadpool.start()\n\n    def __init__(self):\n        self.stream = None\n        self.session = None\n        self._started = False\n        self._session_started = False\n        self._initialize_done = False\n        self._initialize_successful = False\n\n    def initialize(self, stream, session):\n        self.stream = stream\n        self.session = session\n        notification_center = NotificationCenter()\n        notification_center.add_observer(self, sender=stream)\n        notification_center.add_observer(self, sender=session)\n        notification_center.add_observer(self, sender=self)\n\n    @property\n    def filename(self):\n        return self.stream.file_selector.name if self.stream is not None else None\n\n    @abstractmethod\n    def start(self):\n        raise NotImplementedError\n\n    @abstractmethod\n    def end(self):\n        raise NotImplementedError\n\n    @abstractmethod\n    def process_chunk(self, chunk):\n        raise NotImplementedError\n\n    def __terminate(self):\n        notification_center = NotificationCenter()\n        notification_center.remove_observer(self, sender=self.stream)\n        notification_center.remove_observer(self, sender=self.session)\n        notification_center.remove_observer(self, sender=self)\n        try:\n            self.stream.file_selector.fd.close()\n        except AttributeError:  # when self.stream.file_selector.fd is None\n            pass\n        except IOError:         # we can get this if we try to close while another thread is reading from it\n            pass\n        self.stream = None\n        self.session = None\n\n    @run_in_twisted_thread\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, None)\n        if handler is not None:\n            handler(notification)\n\n    def _NH_MediaStreamDidNotInitialize(self, notification):\n        if not self._initialize_done:\n            self.end()\n        self.__terminate()\n\n    def _NH_MediaStreamDidStart(self, notification):\n        self._started = True\n        self.start()\n\n    def _NH_MediaStreamWillEnd(self, notification):\n        if self._started:\n            self.end()\n        elif self._session_started:\n            notification.center.post_notification('FileTransferHandlerDidEnd', sender=self, data=NotificationData(error=True, reason='Refused'))\n\n    def _NH_SIPSessionWillStart(self, notification):\n        self._session_started = True\n\n    def _NH_SIPSessionDidFail(self, notification):\n        if not self._session_started and self._initialize_successful:\n            if notification.data.code == 487:\n                reason = 'Cancelled'\n            else:\n                reason = notification.data.reason or 'Failed'\n            notification.center.post_notification('FileTransferHandlerDidEnd', sender=self, data=NotificationData(error=True, reason=reason))\n\n    def _NH_FileTransferHandlerDidInitialize(self, notification):\n        self._initialize_done = True\n        self._initialize_successful = True\n\n    def _NH_FileTransferHandlerDidNotInitialize(self, notification):\n        self._initialize_done = True\n        self._initialize_successful = False\n\n    def _NH_FileTransferHandlerDidEnd(self, notification):\n        self.__terminate()\n\n\nclass OffsetHeader(MSRPNamedHeader):\n    name = 'Offset'\n    type = IntegerHeaderType\n\n\nclass EndTransfer: __metaclass__ = MarkerType\n\n\nclass IncomingFileTransferHandler(FileTransferHandler):\n    metadata = FileTransfersMetadata()\n\n    def __init__(self):\n        super(IncomingFileTransferHandler, self).__init__()\n        self.hash = sha1()\n        self.queue = Queue()\n        self.offset = 0\n        self.received_chunks = 0\n\n    @property\n    def save_directory(self):\n        return self.__dict__.get('save_directory')\n\n    @save_directory.setter\n    def save_directory(self, value):\n        if self.stream is not None:\n            raise AttributeError('cannot set save_directory, transfer is in progress')\n        self.__dict__['save_directory'] = value\n\n    def initialize(self, stream, session):\n        super(IncomingFileTransferHandler, self).initialize(stream, session)\n        try:\n            directory = self.save_directory or SIPSimpleSettings().file_transfer.directory.normalized\n            makedirs(directory)\n            with self.metadata as metadata:\n                try:\n                    prev_file = metadata.pop(stream.file_selector.hash.lower())\n                    mtime = os.path.getmtime(prev_file.filename)\n                    if mtime != prev_file.mtime:\n                        raise ValueError('file was modified')\n                    filename = os.path.join(directory, os.path.basename(stream.file_selector.name))\n                    try:\n                        os.link(prev_file.filename, filename)\n                    except (AttributeError, OSError):\n                        stream.file_selector.name = prev_file.filename\n                    else:\n                        stream.file_selector.name = filename\n                        unlink(prev_file.filename)\n                    stream.file_selector.fd = openfile(stream.file_selector.name, 'ab')  # open doesn't seek to END in append mode on win32 until first write, but openfile does\n                    self.offset = stream.file_selector.fd.tell()\n                    self.hash = prev_file.partial_hash\n                except (KeyError, EnvironmentError, ValueError):\n                    for name in UniqueFilenameGenerator.generate(os.path.join(directory, os.path.basename(stream.file_selector.name))):\n                        try:\n                            stream.file_selector.fd = openfile(name, 'xb')\n                        except FileExistsError:\n                            continue\n                        else:\n                            stream.file_selector.name = name\n                            break\n        except Exception, e:\n            NotificationCenter().post_notification('FileTransferHandlerDidNotInitialize', sender=self, data=NotificationData(reason=str(e)))\n        else:\n            NotificationCenter().post_notification('FileTransferHandlerDidInitialize', sender=self)\n\n    def end(self):\n        self.queue.put(EndTransfer)\n\n    def process_chunk(self, chunk):\n        if chunk.method == 'SEND':\n            if not self.received_chunks and chunk.byte_range.start == 1:\n                self.stream.file_selector.fd.truncate(0)\n                self.stream.file_selector.fd.seek(0)\n                self.hash = sha1()\n                self.offset = 0\n            self.received_chunks += 1\n            self.queue.put(chunk)\n        elif chunk.method == 'FILE_OFFSET':\n            if self.received_chunks > 0:\n                response = make_response(chunk, 413, 'Unwanted message')\n            else:\n                offset = self.stream.file_selector.fd.tell()\n                response = make_response(chunk, 200, 'OK')\n                response.add_header(OffsetHeader(offset))\n            self.stream.msrp_session.send_chunk(response)\n\n    @run_in_threadpool(FileTransferHandler.threadpool)\n    def start(self):\n        notification_center = NotificationCenter()\n        notification_center.post_notification('FileTransferHandlerDidStart', sender=self)\n        file_selector = self.stream.file_selector\n        fd = file_selector.fd\n\n        while True:\n            chunk = self.queue.get()\n            if chunk is EndTransfer:\n                break\n            try:\n                fd.write(chunk.data)\n            except EnvironmentError, e:\n                fd.close()\n                notification_center.post_notification('FileTransferHandlerError', sender=self, data=NotificationData(error=str(e)))\n                notification_center.post_notification('FileTransferHandlerDidEnd', sender=self, data=NotificationData(error=True, reason=str(e)))\n                return\n            self.hash.update(chunk.data)\n            self.offset += chunk.size\n            transferred_bytes = chunk.byte_range.start + chunk.size - 1\n            total_bytes = file_selector.size = chunk.byte_range.total\n            notification_center.post_notification('FileTransferHandlerProgress', sender=self, data=NotificationData(transferred_bytes=transferred_bytes, total_bytes=total_bytes))\n            if transferred_bytes == total_bytes:\n                break\n\n        fd.close()\n\n        # Transfer is finished\n\n        if self.offset != self.stream.file_selector.size:\n            notification_center.post_notification('FileTransferHandlerDidEnd', sender=self, data=NotificationData(error=True, reason='Incomplete file'))\n            return\n        if self.hash != self.stream.file_selector.hash:\n            unlink(self.filename)  # something got corrupted, better delete the file\n            notification_center.post_notification('FileTransferHandlerDidEnd', sender=self, data=NotificationData(error=True, reason='File hash mismatch'))\n            return\n\n        notification_center.post_notification('FileTransferHandlerDidEnd', sender=self, data=NotificationData(error=False, reason=None))\n\n    def _NH_MediaStreamDidNotInitialize(self, notification):\n        if self.stream.file_selector.fd is not None:\n            position = self.stream.file_selector.fd.tell()\n            self.stream.file_selector.fd.close()\n            if position == 0:\n                unlink(self.stream.file_selector.name)\n        super(IncomingFileTransferHandler, self)._NH_MediaStreamDidNotInitialize(notification)\n\n    def _NH_FileTransferHandlerDidEnd(self, notification):\n        if notification.data.error and self.stream.file_selector.hash is not None:\n            if os.path.getsize(self.stream.file_selector.name) == 0:\n                unlink(self.stream.file_selector.name)\n            else:\n                with self.metadata as metadata:\n                    entry = FileMetadataEntry.from_selector(self.stream.file_selector)\n                    entry.partial_hash = self.hash\n                    metadata[entry.hash] = entry\n        super(IncomingFileTransferHandler, self)._NH_FileTransferHandlerDidEnd(notification)\n\n\nclass OutgoingFileTransferHandler(FileTransferHandler):\n    file_part_size = 64*1024\n\n    def __init__(self):\n        super(OutgoingFileTransferHandler, self).__init__()\n        self.stop_event = Event()\n        self.finished_event = Event()\n        self.file_offset_event = Event()\n        self.message_id = '%x' % random.getrandbits(64)\n        self.offset = 0\n\n    def initialize(self, stream, session):\n        super(OutgoingFileTransferHandler, self).initialize(stream, session)\n        if stream.file_selector.fd is None:\n            NotificationCenter().post_notification('FileTransferHandlerDidNotInitialize', sender=self, data=NotificationData(reason='file descriptor not specified'))\n            return\n        if stream.file_selector.size == 0:\n            NotificationCenter().post_notification('FileTransferHandlerDidNotInitialize', sender=self, data=NotificationData(reason='file is empty'))\n            return\n\n        if stream.file_selector.hash is None:\n            self._calculate_file_hash()\n        else:\n            NotificationCenter().post_notification('FileTransferHandlerDidInitialize', sender=self)\n\n    @run_in_threadpool(FileTransferHandler.threadpool)\n    def _calculate_file_hash(self):\n        file_hash = hashlib.sha1()\n        processed = 0\n\n        notification_center = NotificationCenter()\n        notification_center.post_notification('FileTransferHandlerHashProgress', sender=self, data=NotificationData(processed=0, total=self.stream.file_selector.size))\n\n        file_selector = self.stream.file_selector\n        fd = file_selector.fd\n        while not self.stop_event.is_set():\n            try:\n                content = fd.read(self.file_part_size)\n            except EnvironmentError, e:\n                fd.close()\n                notification_center.post_notification('FileTransferHandlerDidNotInitialize', sender=self, data=NotificationData(reason=str(e)))\n                return\n            if not content:\n                file_selector.hash = file_hash\n                notification_center.post_notification('FileTransferHandlerDidInitialize', sender=self)\n                break\n            file_hash.update(content)\n            processed += len(content)\n            notification_center.post_notification('FileTransferHandlerHashProgress', sender=self, data=NotificationData(processed=processed, total=file_selector.size))\n        else:\n            fd.close()\n            notification_center.post_notification('FileTransferHandlerDidNotInitialize', sender=self, data=NotificationData(reason='Interrupted transfer'))\n\n    def end(self):\n        self.stop_event.set()\n        self.file_offset_event.set()    # in case we are busy waiting on it\n\n    @run_in_threadpool(FileTransferHandler.threadpool)\n    def start(self):\n        notification_center = NotificationCenter()\n        notification_center.post_notification('FileTransferHandlerDidStart', sender=self)\n\n        if self.stream.file_offset_supported:\n            self._send_file_offset_chunk()\n            self.file_offset_event.wait()\n\n        finished = False\n        failure_reason = None\n        fd = self.stream.file_selector.fd\n        fd.seek(self.offset)\n\n        try:\n            while not self.stop_event.is_set():\n                try:\n                    data = fd.read(self.file_part_size)\n                except EnvironmentError, e:\n                    failure_reason = str(e)\n                    break\n                if not data:\n                    finished = True\n                    break\n                self._send_chunk(data)\n        finally:\n            fd.close()\n\n        if not finished:\n            notification_center.post_notification('FileTransferHandlerDidEnd', sender=self, data=NotificationData(error=True, reason=failure_reason or 'Interrupted transfer'))\n            return\n\n        # Wait until the stream ends or we get all reports\n        self.stop_event.wait()\n        if self.finished_event.is_set():\n            notification_center.post_notification('FileTransferHandlerDidEnd', sender=self, data=NotificationData(error=False, reason=None))\n        else:\n            notification_center.post_notification('FileTransferHandlerDidEnd', sender=self, data=NotificationData(error=True, reason='Incomplete transfer'))\n\n    def _on_transaction_response(self, response):\n        if self.stop_event.is_set():\n            return\n        if response.code != 200:\n            NotificationCenter().post_notification('FileTransferHandlerError', sender=self, data=NotificationData(error=response.comment))\n            self.end()\n\n    @run_in_twisted_thread\n    def _send_chunk(self, data):\n        if self.stop_event.is_set():\n            return\n        data_len = len(data)\n        chunk = self.stream.msrp.make_send_request(message_id=self.message_id,\n                                                   data=data,\n                                                   start=self.offset+1,\n                                                   end=self.offset+data_len,\n                                                   length=self.stream.file_selector.size)\n        chunk.add_header(ContentTypeHeader(self.stream.file_selector.type))\n        chunk.add_header(SuccessReportHeader('yes'))\n        chunk.add_header(FailureReportHeader('yes'))\n\n        try:\n            self.stream.msrp_session.send_chunk(chunk, response_cb=self._on_transaction_response)\n        except Exception, e:\n            NotificationCenter().post_notification('FileTransferHandlerError', sender=self, data=NotificationData(error=str(e)))\n        else:\n            self.offset += data_len\n\n    @run_in_twisted_thread\n    def _send_file_offset_chunk(self):\n        def response_cb(response):\n            if not self.stop_event.is_set() and response.code == 200:\n                try:\n                    offset = response.headers['Offset'].decoded\n                except (KeyError, HeaderParsingError):\n                    offset = 0\n                self.offset = offset\n            self.file_offset_event.set()\n\n        if self.stop_event.is_set():\n            self.file_offset_event.set()\n            return\n\n        chunk = self.stream.msrp.make_request('FILE_OFFSET')  # TODO: _ is illegal in MSRP method names according to RFC 4975\n        try:\n            self.stream.msrp_session.send_chunk(chunk, response_cb=response_cb)\n        except Exception, e:\n            NotificationCenter().post_notification('FileTransferHandlerError', sender=self, data=NotificationData(error=str(e)))\n\n    def process_chunk(self, chunk):\n        # here we process the REPORT chunks\n        notification_center = NotificationCenter()\n        if chunk.status.code == 200:\n            transferred_bytes = chunk.byte_range.end\n            total_bytes = chunk.byte_range.total\n            notification_center.post_notification('FileTransferHandlerProgress', sender=self, data=NotificationData(transferred_bytes=transferred_bytes, total_bytes=total_bytes))\n            if transferred_bytes == total_bytes:\n                self.finished_event.set()\n                self.end()\n        else:\n            notification_center.post_notification('FileTransferHandlerError', sender=self, data=NotificationData(error=chunk.status.comment))\n            self.end()\n\n\nclass FileTransferMSRPSession(MSRPSession):\n    def _handle_incoming_FILE_OFFSET(self, chunk):\n        self._on_incoming_cb(chunk)\n\n\nclass FileTransferStream(MSRPStreamBase):\n    type = 'file-transfer'\n    priority = 10\n    msrp_session_class = FileTransferMSRPSession\n\n    media_type = 'message'\n    accept_types = ['*']\n    accept_wrapped_types = None\n\n    IncomingTransferHandler = IncomingFileTransferHandler\n    OutgoingTransferHandler = OutgoingFileTransferHandler\n\n    def __init__(self, file_selector, direction, transfer_id=RandomID):\n        if direction not in ('sendonly', 'recvonly'):\n            raise ValueError(\"direction must be one of 'sendonly' or 'recvonly'\")\n        super(FileTransferStream, self).__init__(direction=direction)\n        self.file_selector = file_selector\n        self.transfer_id = transfer_id if transfer_id is not RandomID else str(uuid.uuid4())\n        if direction == 'sendonly':\n            self.handler = self.OutgoingTransferHandler()\n        else:\n            self.handler = self.IncomingTransferHandler()\n\n    @classmethod\n    def new_from_sdp(cls, session, remote_sdp, stream_index):\n        remote_stream = remote_sdp.media[stream_index]\n        if remote_stream.media != 'message' or 'file-selector' not in remote_stream.attributes:\n            raise UnknownStreamError\n        expected_transport = 'TCP/TLS/MSRP' if session.account.msrp.transport == 'tls' else 'TCP/MSRP'\n        if remote_stream.transport != expected_transport:\n            raise InvalidStreamError(\"expected %s transport in file transfer stream, got %s\" % (expected_transport, remote_stream.transport))\n        if remote_stream.formats != ['*']:\n            raise InvalidStreamError(\"wrong format list specified\")\n        try:\n            file_selector = FileSelector.parse(remote_stream.attributes.getfirst('file-selector'))\n        except Exception as e:\n            raise InvalidStreamError(\"error parsing file-selector: {}\".format(e))\n        transfer_id = remote_stream.attributes.getfirst('file-transfer-id', None)\n        if remote_stream.direction == 'sendonly':\n            stream = cls(file_selector, 'recvonly', transfer_id)\n        elif remote_stream.direction == 'recvonly':\n            stream = cls(file_selector, 'sendonly', transfer_id)\n        else:\n            raise InvalidStreamError(\"wrong stream direction specified\")\n        stream.remote_role = remote_stream.attributes.getfirst('setup', 'active')\n        return stream\n\n    def initialize(self, session, direction):\n        self._initialize_args = session, direction\n        NotificationCenter().add_observer(self, sender=self.handler)\n        self.handler.initialize(self, session)\n\n    def _create_local_media(self, uri_path):\n        local_media = super(FileTransferStream, self)._create_local_media(uri_path)\n        local_media.attributes.append(SDPAttribute('file-selector', self.file_selector.sdp_repr))\n        local_media.attributes.append(SDPAttribute('x-file-offset', ''))\n        if self.transfer_id is not None:\n            local_media.attributes.append(SDPAttribute('file-transfer-id', self.transfer_id))\n        return local_media\n\n    @property\n    def file_offset_supported(self):\n        try:\n            return 'x-file-offset' in self.remote_media.attributes\n        except AttributeError:\n            return False\n\n    @run_in_twisted_thread\n    def _NH_FileTransferHandlerDidInitialize(self, notification):\n        session, direction = self._initialize_args\n        del self._initialize_args\n        if not self._done:\n            super(FileTransferStream, self).initialize(session, direction)\n\n    @run_in_twisted_thread\n    def _NH_FileTransferHandlerDidNotInitialize(self, notification):\n        del self._initialize_args\n        if not self._done:\n            notification.center.post_notification('MediaStreamDidNotInitialize', sender=self, data=notification.data)\n\n    @run_in_twisted_thread\n    def _NH_FileTransferHandlerError(self, notification):\n        self._failure_reason = notification.data.error\n        notification.center.post_notification('MediaStreamDidFail', sender=self, data=NotificationData(context='transferring', reason=self._failure_reason))\n\n    def _NH_MediaStreamDidNotInitialize(self, notification):\n        notification.center.remove_observer(self, sender=self.handler)\n\n    def _NH_MediaStreamWillEnd(self, notification):\n        notification.center.remove_observer(self, sender=self.handler)\n\n    def _handle_REPORT(self, chunk):\n        # in theory, REPORT can come with Byte-Range which would limit the scope of the REPORT to the part of the message.\n        self.handler.process_chunk(chunk)\n\n    def _handle_SEND(self, chunk):\n        notification_center = NotificationCenter()\n        if chunk.size == 0:\n            # keep-alive\n            self.msrp_session.send_report(chunk, 200, 'OK')\n            return\n        if self.direction=='sendonly':\n            self.msrp_session.send_report(chunk, 413, 'Unwanted Message')\n            return\n        if chunk.content_type.lower() == 'message/cpim':\n            # In order to properly support the CPIM wrapper, msrplib needs to be refactored. -Luci\n            self.msrp_session.send_report(chunk, 415, 'Invalid Content-Type')\n            self._failure_reason = \"CPIM wrapper is not supported\"\n            notification_center.post_notification('MediaStreamDidFail', sender=self, data=NotificationData(context='reading', reason=self._failure_reason))\n            return\n        try:\n            self.msrp_session.send_report(chunk, 200, 'OK')\n        except Exception:\n            pass    # Best effort approach: even if we couldn't send the REPORT keep writing the chunks, we might have them all -Saul\n        self.handler.process_chunk(chunk)\n\n    def _handle_FILE_OFFSET(self, chunk):\n        if self.direction != 'recvonly':\n            response = make_response(chunk, 413, 'Unwanted message')\n            self.msrp_session.send_chunk(response)\n            return\n        self.handler.process_chunk(chunk)\n"
  },
  {
    "path": "sipsimple/streams/msrp/screensharing.py",
    "content": "\n\"\"\"\nThis module provides classes to parse and generate SDP related to SIP sessions that negotiate Screen Sharing.\n\"\"\"\n\n__all__ = ['ScreenSharingStream', 'VNCConnectionError', 'ScreenSharingHandler', 'ScreenSharingServerHandler', 'ScreenSharingViewerHandler',\n           'InternalVNCViewerHandler', 'InternalVNCServerHandler', 'ExternalVNCViewerHandler', 'ExternalVNCServerHandler']\n\nfrom abc import ABCMeta, abstractmethod, abstractproperty\nfrom application.notification import NotificationCenter, NotificationData, IObserver\nfrom application.python.descriptor import WriteOnceAttribute\nfrom eventlib.coros import queue\nfrom eventlib.greenio import GreenSocket\nfrom eventlib.proc import spawn\nfrom eventlib.util import tcp_socket, set_reuse_addr\nfrom msrplib.protocol import FailureReportHeader, SuccessReportHeader, ContentTypeHeader\nfrom msrplib.transport import make_response, make_report\nfrom twisted.internet.error import ConnectionDone\nfrom zope.interface import implements\n\nfrom sipsimple.core import SDPAttribute\nfrom sipsimple.streams import InvalidStreamError, UnknownStreamError\nfrom sipsimple.streams.msrp import MSRPStreamBase\nfrom sipsimple.threading import run_in_twisted_thread\n\n\nclass VNCConnectionError(Exception): pass\n\n\nclass ScreenSharingHandler(object):\n    __metaclass__ = ABCMeta\n\n    implements(IObserver)\n\n    def __init__(self):\n        self.incoming_msrp_queue = None\n        self.outgoing_msrp_queue = None\n        self.msrp_reader_thread = None\n        self.msrp_writer_thread = None\n\n    def initialize(self, stream):\n        self.incoming_msrp_queue = stream.incoming_queue\n        self.outgoing_msrp_queue = stream.outgoing_queue\n        NotificationCenter().add_observer(self, sender=stream)\n\n    @abstractproperty\n    def type(self):\n        raise NotImplementedError\n\n    @abstractmethod\n    def _msrp_reader(self):\n        raise NotImplementedError\n\n    @abstractmethod\n    def _msrp_writer(self):\n        raise NotImplementedError\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, None)\n        if handler is not None:\n            handler(notification)\n\n    def _NH_MediaStreamDidStart(self, notification):\n        self.msrp_reader_thread = spawn(self._msrp_reader)\n        self.msrp_writer_thread = spawn(self._msrp_writer)\n\n    def _NH_MediaStreamWillEnd(self, notification):\n        notification.center.remove_observer(self, sender=notification.sender)\n        if self.msrp_reader_thread is not None:\n            self.msrp_reader_thread.kill()\n            self.msrp_reader_thread = None\n        if self.msrp_writer_thread is not None:\n            self.msrp_writer_thread.kill()\n            self.msrp_writer_thread = None\n\n\nclass ScreenSharingServerHandler(ScreenSharingHandler):\n    type = property(lambda self: 'passive')\n\n\nclass ScreenSharingViewerHandler(ScreenSharingHandler):\n    type = property(lambda self: 'active')\n\n\n\nclass InternalVNCViewerHandler(ScreenSharingViewerHandler):\n    @run_in_twisted_thread\n    def send(self, data):\n        self.outgoing_msrp_queue.send(data)\n\n    def _msrp_reader(self):\n        notification_center = NotificationCenter()\n        while True:\n            data = self.incoming_msrp_queue.wait()\n            notification_center.post_notification('ScreenSharingStreamGotData', sender=self, data=NotificationData(data=data))\n\n    def _msrp_writer(self):\n        pass\n\n\nclass InternalVNCServerHandler(ScreenSharingServerHandler):\n    @run_in_twisted_thread\n    def send(self, data):\n        self.outgoing_msrp_queue.send(data)\n\n    def _msrp_reader(self):\n        notification_center = NotificationCenter()\n        while True:\n            data = self.incoming_msrp_queue.wait()\n            notification_center.post_notification('ScreenSharingStreamGotData', sender=self, data=NotificationData(data=data))\n\n    def _msrp_writer(self):\n        pass\n\n\nclass ExternalVNCViewerHandler(ScreenSharingViewerHandler):\n    address = ('localhost', 0)\n    connect_timeout = 5\n\n    def __init__(self):\n        super(ExternalVNCViewerHandler, self).__init__()\n        self.vnc_starter_thread = None\n        self.vnc_socket = GreenSocket(tcp_socket())\n        set_reuse_addr(self.vnc_socket)\n        self.vnc_socket.settimeout(self.connect_timeout)\n        self.vnc_socket.bind(self.address)\n        self.vnc_socket.listen(1)\n        self.address = self.vnc_socket.getsockname()\n\n    def _msrp_reader(self):\n        while True:\n            try:\n                data = self.incoming_msrp_queue.wait()\n                self.vnc_socket.sendall(data)\n            except Exception, e:\n                self.msrp_reader_thread = None # avoid issues caused by the notification handler killing this greenlet during post_notification\n                NotificationCenter().post_notification('ScreenSharingHandlerDidFail', sender=self, data=NotificationData(context='sending', reason=str(e)))\n                break\n\n    def _msrp_writer(self):\n        while True:\n            try:\n                data = self.vnc_socket.recv(2048)\n                if not data:\n                    raise VNCConnectionError(\"connection with the VNC viewer was closed\")\n                self.outgoing_msrp_queue.send(data)\n            except Exception, e:\n                self.msrp_writer_thread = None # avoid issues caused by the notification handler killing this greenlet during post_notification\n                NotificationCenter().post_notification('ScreenSharingHandlerDidFail', sender=self, data=NotificationData(context='reading', reason=str(e)))\n                break\n\n    def _start_vnc_connection(self):\n        try:\n            sock, addr = self.vnc_socket.accept()\n            self.vnc_socket.close()\n            self.vnc_socket = sock\n            self.vnc_socket.settimeout(None)\n        except Exception, e:\n            self.vnc_starter_thread = None # avoid issues caused by the notification handler killing this greenlet during post_notification\n            NotificationCenter().post_notification('ScreenSharingHandlerDidFail', sender=self, data=NotificationData(context='connecting', reason=str(e)))\n        else:\n            self.msrp_reader_thread = spawn(self._msrp_reader)\n            self.msrp_writer_thread = spawn(self._msrp_writer)\n        finally:\n            self.vnc_starter_thread = None\n\n    def _NH_MediaStreamDidStart(self, notification):\n        self.vnc_starter_thread = spawn(self._start_vnc_connection)\n\n    def _NH_MediaStreamWillEnd(self, notification):\n        if self.vnc_starter_thread is not None:\n            self.vnc_starter_thread.kill()\n            self.vnc_starter_thread = None\n        super(ExternalVNCViewerHandler, self)._NH_MediaStreamWillEnd(notification)\n        self.vnc_socket.close()\n\n\nclass ExternalVNCServerHandler(ScreenSharingServerHandler):\n    address = ('localhost', 5900)\n    connect_timeout = 5\n\n    def __init__(self):\n        super(ExternalVNCServerHandler, self).__init__()\n        self.vnc_starter_thread = None\n        self.vnc_socket = None\n\n    def _msrp_reader(self):\n        while True:\n            try:\n                data = self.incoming_msrp_queue.wait()\n                self.vnc_socket.sendall(data)\n            except Exception, e:\n                self.msrp_reader_thread = None # avoid issues caused by the notification handler killing this greenlet during post_notification\n                NotificationCenter().post_notification('ScreenSharingHandlerDidFail', sender=self, data=NotificationData(context='sending', reason=str(e)))\n                break\n\n    def _msrp_writer(self):\n        while True:\n            try:\n                data = self.vnc_socket.recv(2048)\n                if not data:\n                    raise VNCConnectionError(\"connection to the VNC server was closed\")\n                self.outgoing_msrp_queue.send(data)\n            except Exception, e:\n                self.msrp_writer_thread = None # avoid issues caused by the notification handler killing this greenlet during post_notification\n                NotificationCenter().post_notification('ScreenSharingHandlerDidFail', sender=self, data=NotificationData(context='reading', reason=str(e)))\n                break\n\n    def _start_vnc_connection(self):\n        try:\n            self.vnc_socket = GreenSocket(tcp_socket())\n            self.vnc_socket.settimeout(self.connect_timeout)\n            self.vnc_socket.connect(self.address)\n            self.vnc_socket.settimeout(None)\n        except Exception, e:\n            self.vnc_starter_thread = None # avoid issues caused by the notification handler killing this greenlet during post_notification\n            NotificationCenter().post_notification('ScreenSharingHandlerDidFail', sender=self, data=NotificationData(context='connecting', reason=str(e)))\n        else:\n            self.msrp_reader_thread = spawn(self._msrp_reader)\n            self.msrp_writer_thread = spawn(self._msrp_writer)\n        finally:\n            self.vnc_starter_thread = None\n\n    def _NH_MediaStreamDidStart(self, notification):\n        self.vnc_starter_thread = spawn(self._start_vnc_connection)\n\n    def _NH_MediaStreamWillEnd(self, notification):\n        if self.vnc_starter_thread is not None:\n            self.vnc_starter_thread.kill()\n            self.vnc_starter_thread = None\n        super(ExternalVNCServerHandler, self)._NH_MediaStreamWillEnd(notification)\n        if self.vnc_socket is not None:\n            self.vnc_socket.close()\n\n\nclass ScreenSharingStream(MSRPStreamBase):\n    type = 'screen-sharing'\n    priority = 1\n\n    media_type = 'application'\n    accept_types = ['application/x-rfb']\n    accept_wrapped_types = None\n\n    ServerHandler = InternalVNCServerHandler\n    ViewerHandler = InternalVNCViewerHandler\n\n    handler = WriteOnceAttribute()\n\n    def __init__(self, mode):\n        if mode not in ('viewer', 'server'):\n            raise ValueError(\"mode should be 'viewer' or 'server' not '%s'\" % mode)\n        super(ScreenSharingStream, self).__init__(direction='sendrecv')\n        self.handler = self.ViewerHandler() if mode=='viewer' else self.ServerHandler()\n        self.incoming_queue = queue()\n        self.outgoing_queue = queue()\n        self.msrp_reader_thread = None\n        self.msrp_writer_thread = None\n\n    @classmethod\n    def new_from_sdp(cls, session, remote_sdp, stream_index):\n        remote_stream = remote_sdp.media[stream_index]\n        if remote_stream.media != 'application':\n            raise UnknownStreamError\n        accept_types = remote_stream.attributes.getfirst('accept-types', None)\n        if accept_types is None or 'application/x-rfb' not in accept_types.split():\n            raise UnknownStreamError\n        expected_transport = 'TCP/TLS/MSRP' if session.account.msrp.transport=='tls' else 'TCP/MSRP'\n        if remote_stream.transport != expected_transport:\n            raise InvalidStreamError(\"expected %s transport in chat stream, got %s\" % (expected_transport, remote_stream.transport))\n        if remote_stream.formats != ['*']:\n            raise InvalidStreamError(\"wrong format list specified\")\n        remote_rfbsetup = remote_stream.attributes.getfirst('rfbsetup', 'active')\n        if remote_rfbsetup == 'active':\n            stream = cls(mode='server')\n        elif remote_rfbsetup == 'passive':\n            stream = cls(mode='viewer')\n        else:\n            raise InvalidStreamError(\"unknown rfbsetup attribute in the remote screen sharing stream\")\n        stream.remote_role = remote_stream.attributes.getfirst('setup', 'active')\n        return stream\n\n    def _create_local_media(self, uri_path):\n        local_media = super(ScreenSharingStream, self)._create_local_media(uri_path)\n        local_media.attributes.append(SDPAttribute('rfbsetup', self.handler.type))\n        return local_media\n\n    def _msrp_reader(self):\n        while True:\n            try:\n                chunk = self.msrp.read_chunk()\n                if chunk.method in (None, 'REPORT'):\n                    continue\n                elif chunk.method == 'SEND':\n                    if chunk.content_type in self.accept_types:\n                        self.incoming_queue.send(chunk.data)\n                        response = make_response(chunk, 200, 'OK')\n                        report = make_report(chunk, 200, 'OK')\n                    else:\n                        response = make_response(chunk, 415, 'Invalid Content-Type')\n                        report = None\n                else:\n                    response = make_response(chunk, 501, 'Unknown method')\n                    report = None\n                if response is not None:\n                    self.msrp.write_chunk(response)\n                if report is not None:\n                    self.msrp.write_chunk(report)\n            except Exception, e:\n                self.msrp_reader_thread = None # avoid issues caused by the notification handler killing this greenlet during post_notification\n                if self.shutting_down and isinstance(e, ConnectionDone):\n                    break\n                self._failure_reason = str(e)\n                NotificationCenter().post_notification('MediaStreamDidFail', sender=self, data=NotificationData(context='reading', reason=self._failure_reason))\n                break\n\n    def _msrp_writer(self):\n        while True:\n            try:\n                data = self.outgoing_queue.wait()\n                chunk = self.msrp.make_send_request(data=data)\n                chunk.add_header(SuccessReportHeader('no'))\n                chunk.add_header(FailureReportHeader('partial'))\n                chunk.add_header(ContentTypeHeader('application/x-rfb'))\n                self.msrp.write_chunk(chunk)\n            except Exception, e:\n                self.msrp_writer_thread = None # avoid issues caused by the notification handler killing this greenlet during post_notification\n                if self.shutting_down and isinstance(e, ConnectionDone):\n                    break\n                self._failure_reason = str(e)\n                NotificationCenter().post_notification('MediaStreamDidFail', sender=self, data=NotificationData(context='sending', reason=self._failure_reason))\n                break\n\n    def _NH_MediaStreamDidInitialize(self, notification):\n        notification.center.add_observer(self, sender=self.handler)\n        self.handler.initialize(self)\n\n    def _NH_MediaStreamDidStart(self, notification):\n        self.msrp_reader_thread = spawn(self._msrp_reader)\n        self.msrp_writer_thread = spawn(self._msrp_writer)\n\n    def _NH_MediaStreamWillEnd(self, notification):\n        notification.center.remove_observer(self, sender=self.handler)\n        if self.msrp_reader_thread is not None:\n            self.msrp_reader_thread.kill()\n            self.msrp_reader_thread = None\n        if self.msrp_writer_thread is not None:\n            self.msrp_writer_thread.kill()\n            self.msrp_writer_thread = None\n\n    def _NH_ScreenSharingHandlerDidFail(self, notification):\n        self._failure_reason = notification.data.reason\n        notification.center.post_notification('MediaStreamDidFail', sender=self, data=notification.data)\n\n"
  },
  {
    "path": "sipsimple/streams/rtp/__init__.py",
    "content": "\n\"\"\"\nHandling of RTP media streams according to RFC3550, RFC3605, RFC3581,\nRFC2833 and RFC3711, RFC3489 and RFC5245.\n\"\"\"\n\n__all__ = ['RTPStream']\n\nimport weakref\n\nfrom abc import ABCMeta, abstractmethod\nfrom application.notification import IObserver, NotificationCenter, NotificationData, ObserverWeakrefProxy\nfrom application.python import Null\nfrom threading import RLock\nfrom zope.interface import implements\n\nfrom sipsimple.account import BonjourAccount\nfrom sipsimple.configuration.settings import SIPSimpleSettings\nfrom sipsimple.core import RTPTransport, SIPCoreError, SIPURI\nfrom sipsimple.lookup import DNSLookup\nfrom sipsimple.streams import IMediaStream, InvalidStreamError, MediaStreamType, UnknownStreamError\nfrom sipsimple.threading import run_in_thread\n\n\nclass ZRTPStreamOptions(object):\n    implements(IObserver)\n\n    def __init__(self, stream):\n        self._stream = stream\n        self.__dict__['master'] = None\n        self.__dict__['sas'] = None\n        self.__dict__['verified'] = False\n        self.__dict__['peer_name'] = ''\n\n    @property\n    def sas(self):\n        if self.master is not None:\n            return self.master.encryption.zrtp.sas\n        return self.__dict__['sas']\n\n    @property\n    def verified(self):\n        if self.master is not None:\n            return self.master.encryption.zrtp.verified\n        return self.__dict__['verified']\n\n    @verified.setter\n    def verified(self, verified):\n        if self.__dict__['verified'] == verified:\n            return\n        if self.sas is None:\n            raise AttributeError('Cannot verify peer before SAS is received')\n        if self.master is not None:\n            self.master.encryption.zrtp.verified = verified\n        else:\n            rtp_transport = self._stream._rtp_transport\n            if rtp_transport is not None:\n                @run_in_thread('file-io')\n                def update_verified(rtp_transport, verified):\n                    rtp_transport.set_zrtp_sas_verified(verified)\n                    notification_center = NotificationCenter()\n                    notification_center.post_notification('RTPStreamZRTPVerifiedStateChanged', sender=self._stream, data=NotificationData(verified=verified))\n                self.__dict__['verified'] = verified\n                update_verified(rtp_transport, verified)\n\n    @property\n    def peer_id(self):\n        if self.master is not None:\n            return self.master.encryption.zrtp.peer_id\n        rtp_transport = self._stream._rtp_transport\n        if rtp_transport is None:\n            return None\n        return rtp_transport.zrtp_peer_id\n\n    @property\n    def peer_name(self):\n        if self.master is not None:\n            return self.master.encryption.zrtp.peer_name\n        return self.__dict__['peer_name']\n\n    @peer_name.setter\n    def peer_name(self, name):\n        if self.__dict__['peer_name'] == name:\n            return\n        if self.master is not None:\n            self.master.encryption.zrtp.peer_name = name\n        else:\n            rtp_transport = self._stream._rtp_transport\n            if rtp_transport is not None:\n                @run_in_thread('file-io')\n                def update_name(rtp_transport, name):\n                    rtp_transport.zrtp_peer_name = name\n                    notification_center = NotificationCenter()\n                    notification_center.post_notification('RTPStreamZRTPPeerNameChanged', sender=self._stream, data=NotificationData(name=name))\n                self.__dict__['peer_name'] = name\n                update_name(rtp_transport, name)\n\n    @property\n    def master(self):\n        return self.__dict__['master']\n\n    @master.setter\n    def master(self, master):\n        old_master = self.__dict__['master']\n        if old_master is master:\n            return\n        notification_center = NotificationCenter()\n        if old_master is not None:\n            notification_center.remove_observer(self, sender=old_master)\n        if master is not None:\n            notification_center.add_observer(self, sender=master)\n        self.__dict__['master'] = master\n\n    def _enable(self, master_stream=None):\n        rtp_transport = self._stream._rtp_transport\n        if rtp_transport is None:\n            return\n        if master_stream is not None and not (master_stream.encryption.active and master_stream.encryption.type == 'ZRTP'):\n            raise RuntimeError('Master stream must have ZRTP encryption activated')\n        rtp_transport.set_zrtp_enabled(True, master_stream)\n        self.master = master_stream\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_RTPStreamZRTPReceivedSAS(self, notification):\n        # ZRTP begins on the audio stream, so this notification will only be processed\n        # by the other streams\n        self.__dict__['sas'] = notification.data.sas\n        self.__dict__['verified'] = notification.data.verified\n        self.__dict__['peer_name'] = notification.data.peer_name\n        notification.center.post_notification(notification.name, sender=self._stream, data=notification.data)\n\n    def _NH_RTPStreamZRTPVerifiedStateChanged(self, notification):\n        self.__dict__['verified'] = notification.data.verified\n        notification.center.post_notification(notification.name, sender=self._stream, data=notification.data)\n\n    def _NH_RTPStreamZRTPPeerNameChanged(self, notification):\n        self.__dict__['peer_name'] = notification.data.name\n        notification.center.post_notification(notification.name, sender=self._stream, data=notification.data)\n\n    def _NH_MediaStreamDidEnd(self, notification):\n        self.master = None\n\n\nclass RTPStreamEncryption(object):\n    implements(IObserver)\n\n    def __init__(self, stream):\n        self._stream_ref = weakref.ref(stream)  # Keep a weak reference before the stream is initialized to avoid a memory cycle that would delay releasing audio resources\n        self._stream = None                     # We will store the actual reference once it's initialized and we're guaranteed to get MediaStreamDidEnd and do the cleanup\n        self._rtp_transport = None\n\n        self.__dict__['type'] = None\n        self.__dict__['zrtp'] = None\n\n        notification_center = NotificationCenter()\n        notification_center.add_observer(ObserverWeakrefProxy(self), name='MediaStreamDidInitialize')\n        notification_center.add_observer(ObserverWeakrefProxy(self), name='MediaStreamDidNotInitialize')\n\n    @property\n    def active(self):\n        rtp_transport = self._rtp_transport\n        if rtp_transport is None:\n            return False\n        if self.type == 'SRTP/SDES':\n            return rtp_transport.srtp_active\n        elif self.type == 'ZRTP':\n            return rtp_transport.zrtp_active\n        return False\n\n    @property\n    def cipher(self):\n        rtp_transport = self._rtp_transport\n        if rtp_transport is None:\n            return None\n        if self.type == 'SRTP/SDES':\n            return rtp_transport.srtp_cipher\n        elif self.type == 'ZRTP':\n            return rtp_transport.zrtp_cipher\n        return None\n\n    @property\n    def type(self):\n        return self.__dict__['type']\n\n    @property\n    def zrtp(self):\n        zrtp = self.__dict__['zrtp']\n        if zrtp is None:\n            raise RuntimeError('ZRTP options have not been initialized')\n        return zrtp\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_MediaStreamDidInitialize(self, notification):\n        stream = notification.sender\n        if stream is self._stream_ref():\n            self._stream = stream\n            self._rtp_transport = stream._rtp_transport\n            notification.center.remove_observer(ObserverWeakrefProxy(self), name='MediaStreamDidInitialize')\n            notification.center.remove_observer(ObserverWeakrefProxy(self), name='MediaStreamDidNotInitialize')\n            notification.center.add_observer(self, sender=self._stream)\n            notification.center.add_observer(self, sender=self._rtp_transport)\n            encryption = stream._srtp_encryption or ''\n            if encryption.startswith('sdes'):\n                self.__dict__['type'] = 'SRTP/SDES'\n            elif encryption == 'zrtp':\n                self.__dict__['type'] = 'ZRTP'\n                self.__dict__['zrtp'] = ZRTPStreamOptions(stream)\n\n    def _NH_MediaStreamDidNotInitialize(self, notification):\n        if notification.sender is self._stream_ref():\n            notification.center.remove_observer(ObserverWeakrefProxy(self), name='MediaStreamDidInitialize')\n            notification.center.remove_observer(ObserverWeakrefProxy(self), name='MediaStreamDidNotInitialize')\n            self._stream_ref = None\n            self._stream = None\n\n    def _NH_MediaStreamDidStart(self, notification):\n        if self.type == 'SRTP/SDES':\n            stream = notification.sender\n            if self.active:\n                notification.center.post_notification('RTPStreamDidEnableEncryption', sender=stream)\n            else:\n                reason = 'Not supported by remote'\n                notification.center.post_notification('RTPStreamDidNotEnableEncryption', sender=stream, data=NotificationData(reason=reason))\n\n    def _NH_MediaStreamDidEnd(self, notification):\n        notification.center.remove_observer(self, sender=self._stream)\n        notification.center.remove_observer(self, sender=self._rtp_transport)\n        self._stream = None\n        self._stream_ref = None\n        self._rtp_transport = None\n        self.__dict__['type'] = None\n        self.__dict__['zrtp'] = None\n\n    def _NH_RTPTransportZRTPSecureOn(self, notification):\n        stream = self._stream\n        with stream._lock:\n            if stream.state == \"ENDED\":\n                return\n        notification.center.post_notification('RTPStreamDidEnableEncryption', sender=stream)\n\n    def _NH_RTPTransportZRTPSecureOff(self, notification):\n        # We should never get here because we don't allow disabling encryption -Saul\n        pass\n\n    def _NH_RTPTransportZRTPReceivedSAS(self, notification):\n        stream = self._stream\n        with stream._lock:\n            if stream.state == \"ENDED\":\n                return\n        self.zrtp.__dict__['sas'] = sas = notification.data.sas\n        self.zrtp.__dict__['verified'] = verified = notification.data.verified\n        self.zrtp.__dict__['peer_name'] = peer_name = notification.sender.zrtp_peer_name\n        notification.center.post_notification('RTPStreamZRTPReceivedSAS', sender=stream, data=NotificationData(sas=sas, verified=verified, peer_name=peer_name))\n\n    def _NH_RTPTransportZRTPLog(self, notification):\n        stream = self._stream\n        with stream._lock:\n            if stream.state == \"ENDED\":\n                return\n        notification.center.post_notification('RTPStreamZRTPLog', sender=stream, data=notification.data)\n\n    def _NH_RTPTransportZRTPNegotiationFailed(self, notification):\n        stream = self._stream\n        with stream._lock:\n            if stream.state == \"ENDED\":\n                return\n        reason = 'Negotiation failed: %s' % notification.data.reason\n        notification.center.post_notification('RTPStreamDidNotEnableEncryption', sender=stream, data=NotificationData(reason=reason))\n\n    def _NH_RTPTransportZRTPNotSupportedByRemote(self, notification):\n        stream = self._stream\n        with stream._lock:\n            if stream.state == \"ENDED\":\n                return\n        reason = 'ZRTP not supported by remote'\n        notification.center.post_notification('RTPStreamDidNotEnableEncryption', sender=stream, data=NotificationData(reason=reason))\n\n\nclass RTPStreamType(ABCMeta, MediaStreamType):\n    pass\n\n\nclass RTPStream(object):\n    __metaclass__ = RTPStreamType\n    implements(IMediaStream, IObserver)\n\n    type = None\n    priority = None\n\n    hold_supported = True\n\n    def __init__(self):\n        self.notification_center = NotificationCenter()\n        self.on_hold_by_local = False\n        self.on_hold_by_remote = False\n        self.direction = None\n        self.state = \"NULL\"\n        self.session = None\n        self.encryption = RTPStreamEncryption(self)\n\n        self._transport = None\n        self._hold_request = None\n        self._ice_state = \"NULL\"\n        self._lock = RLock()\n        self._rtp_transport = None\n\n        self._try_ice = False\n        self._srtp_encryption = None\n        self._remote_rtp_address_sdp = None\n        self._remote_rtp_port_sdp = None\n\n        self._initialized = False\n        self._done = False\n        self._failure_reason = None\n\n    @property\n    def codec(self):\n        return self._transport.codec if self._transport else None\n\n    @property\n    def sample_rate(self):\n        return self._transport.sample_rate if self._transport else None\n\n    @property\n    def statistics(self):\n        return self._transport.statistics if self._transport else None\n\n    @property\n    def local_rtp_address(self):\n        return self._rtp_transport.local_rtp_address if self._rtp_transport else None\n\n    @property\n    def local_rtp_port(self):\n        return self._rtp_transport.local_rtp_port if self._rtp_transport else None\n\n    @property\n    def local_rtp_candidate(self):\n        return self._rtp_transport.local_rtp_candidate if self._rtp_transport else None\n\n    @property\n    def remote_rtp_address(self):\n        if self._ice_state == \"IN_USE\":\n            return self._rtp_transport.remote_rtp_address if self._rtp_transport else None\n        return self._remote_rtp_address_sdp if self._rtp_transport else None\n\n    @property\n    def remote_rtp_port(self):\n        if self._ice_state == \"IN_USE\":\n            return self._rtp_transport.remote_rtp_port if self._rtp_transport else None\n        return self._remote_rtp_port_sdp if self._rtp_transport else None\n\n    @property\n    def remote_rtp_candidate(self):\n        return self._rtp_transport.remote_rtp_candidate if self._rtp_transport else None\n\n    @property\n    def ice_active(self):\n        return self._ice_state == \"IN_USE\"\n\n    @property\n    def on_hold(self):\n        return self.on_hold_by_local or self.on_hold_by_remote\n\n    @abstractmethod\n    def start(self, local_sdp, remote_sdp, stream_index):\n        raise NotImplementedError\n\n    @abstractmethod\n    def update(self, local_sdp, remote_sdp, stream_index):\n        raise NotImplementedError\n\n    @abstractmethod\n    def validate_update(self, remote_sdp, stream_index):\n        raise NotImplementedError\n\n    @abstractmethod\n    def deactivate(self):\n        raise NotImplementedError\n\n    @abstractmethod\n    def end(self):\n        raise NotImplementedError\n\n    @abstractmethod\n    def reset(self, stream_index):\n        raise NotImplementedError\n\n    def hold(self):\n        with self._lock:\n            if self.on_hold_by_local or self._hold_request == 'hold':\n                return\n            if self.state == \"ESTABLISHED\" and self.direction != \"inactive\":\n                self._pause()\n            self._hold_request = 'hold'\n\n    def unhold(self):\n        with self._lock:\n            if (not self.on_hold_by_local and self._hold_request != 'hold') or self._hold_request == 'unhold':\n                return\n            if self.state == \"ESTABLISHED\" and self._hold_request == 'hold':\n                self._resume()\n            self._hold_request = None if self._hold_request == 'hold' else 'unhold'\n\n    @classmethod\n    def new_from_sdp(cls, session, remote_sdp, stream_index):\n        # TODO: actually validate the SDP\n        settings = SIPSimpleSettings()\n        remote_stream = remote_sdp.media[stream_index]\n        if remote_stream.media != cls.type:\n            raise UnknownStreamError\n        if remote_stream.transport not in ('RTP/AVP', 'RTP/SAVP'):\n            raise InvalidStreamError(\"expected RTP/AVP or RTP/SAVP transport in %s stream, got %s\" % (cls.type, remote_stream.transport))\n        local_encryption_policy = session.account.rtp.encryption.key_negotiation if session.account.rtp.encryption.enabled else None\n        if local_encryption_policy == \"sdes_mandatory\" and not \"crypto\" in remote_stream.attributes:\n            raise InvalidStreamError(\"SRTP/SDES is locally mandatory but it's not remotely enabled\")\n        if remote_stream.transport == 'RTP/SAVP' and \"crypto\" in remote_stream.attributes and local_encryption_policy not in (\"opportunistic\", \"sdes_optional\", \"sdes_mandatory\"):\n            raise InvalidStreamError(\"SRTP/SDES is remotely mandatory but it's not locally enabled\")\n        account_preferred_codecs = getattr(session.account.rtp, '%s_codec_list' % cls.type)\n        general_codecs = getattr(settings.rtp, '%s_codec_list' % cls.type)\n        supported_codecs = account_preferred_codecs or general_codecs\n        if not any(codec for codec in remote_stream.codec_list if codec in supported_codecs):\n            raise InvalidStreamError(\"no compatible codecs found\")\n        stream = cls()\n        stream._incoming_remote_sdp = remote_sdp\n        stream._incoming_stream_index = stream_index\n        return stream\n\n    def initialize(self, session, direction):\n        with self._lock:\n            if self.state != \"NULL\":\n                raise RuntimeError(\"%sStream.initialize() may only be called in the NULL state\" % self.type.capitalize())\n            self.state = \"INITIALIZING\"\n            self.session = session\n            local_encryption_policy = session.account.rtp.encryption.key_negotiation if session.account.rtp.encryption.enabled else None\n            if hasattr(self, \"_incoming_remote_sdp\") and hasattr(self, '_incoming_stream_index'):\n                # ICE attributes could come at the session level or at the media level\n                remote_stream = self._incoming_remote_sdp.media[self._incoming_stream_index]\n                self._try_ice = self.session.account.nat_traversal.use_ice and ((remote_stream.has_ice_attributes or self._incoming_remote_sdp.has_ice_attributes) and remote_stream.has_ice_candidates)\n                if \"zrtp-hash\" in remote_stream.attributes:\n                    incoming_stream_encryption = 'zrtp'\n                elif \"crypto\" in remote_stream.attributes:\n                    incoming_stream_encryption = 'sdes_mandatory' if remote_stream.transport == 'RTP/SAVP' else 'sdes_optional'\n                else:\n                    incoming_stream_encryption = None\n                if incoming_stream_encryption is not None and local_encryption_policy == 'opportunistic':\n                    self._srtp_encryption = incoming_stream_encryption\n                else:\n                    self._srtp_encryption = 'zrtp' if local_encryption_policy == 'opportunistic' else local_encryption_policy\n            else:\n                self._try_ice = self.session.account.nat_traversal.use_ice\n                self._srtp_encryption = 'zrtp' if local_encryption_policy == 'opportunistic' else local_encryption_policy\n\n            if self._try_ice:\n                if self.session.account.nat_traversal.stun_server_list:\n                    stun_servers = list((server.host, server.port) for server in self.session.account.nat_traversal.stun_server_list)\n                    self._init_rtp_transport(stun_servers)\n                elif not isinstance(self.session.account, BonjourAccount):\n                    dns_lookup = DNSLookup()\n                    self.notification_center.add_observer(self, sender=dns_lookup)\n                    dns_lookup.lookup_service(SIPURI(self.session.account.id.domain), \"stun\")\n            else:\n                self._init_rtp_transport()\n\n    def get_local_media(self, remote_sdp=None, index=0):\n        with self._lock:\n            if self.state not in (\"INITIALIZED\", \"WAIT_ICE\", \"ESTABLISHED\"):\n                raise RuntimeError(\"%sStream.get_local_media() may only be called in the INITIALIZED, WAIT_ICE  or ESTABLISHED states\" % self.type.capitalize())\n            if remote_sdp is None:\n                # offer\n                old_direction = self._transport.direction\n                if old_direction is None:\n                    new_direction = \"sendrecv\"\n                elif \"send\" in old_direction:\n                    new_direction = (\"sendonly\" if (self._hold_request == 'hold' or (self._hold_request is None and self.on_hold_by_local)) else \"sendrecv\")\n                else:\n                    new_direction = (\"inactive\" if (self._hold_request == 'hold' or (self._hold_request is None and self.on_hold_by_local)) else \"recvonly\")\n            else:\n                new_direction = None\n            return self._transport.get_local_media(remote_sdp, index, new_direction)\n\n    # Notifications\n\n    def handle_notification(self, notification):\n        handler = getattr(self, '_NH_%s' % notification.name, Null)\n        handler(notification)\n\n    def _NH_DNSLookupDidFail(self, notification):\n        self.notification_center.remove_observer(self, sender=notification.sender)\n        with self._lock:\n            if self.state == \"ENDED\":\n                return\n        self._init_rtp_transport()\n\n    def _NH_DNSLookupDidSucceed(self, notification):\n        self.notification_center.remove_observer(self, sender=notification.sender)\n        with self._lock:\n            if self.state == \"ENDED\":\n                return\n        self._init_rtp_transport(notification.data.result)\n\n    def _NH_RTPTransportDidInitialize(self, notification):\n        rtp_transport = notification.sender\n        with self._lock:\n            if self.state == \"ENDED\":\n                self.notification_center.remove_observer(self, sender=rtp_transport)\n                return\n            del self._rtp_args\n            del self._stun_servers\n            remote_sdp = self.__dict__.pop('_incoming_remote_sdp', None)\n            stream_index = self.__dict__.pop('_incoming_stream_index', None)\n            try:\n                if remote_sdp is not None:\n                    transport = self._create_transport(rtp_transport, remote_sdp=remote_sdp, stream_index=stream_index)\n                    self._save_remote_sdp_rtp_info(remote_sdp, stream_index)\n                else:\n                    transport = self._create_transport(rtp_transport)\n            except SIPCoreError, e:\n                self.state = \"ENDED\"\n                self.notification_center.remove_observer(self, sender=rtp_transport)\n                self.notification_center.post_notification('MediaStreamDidNotInitialize', sender=self, data=NotificationData(reason=e.args[0]))\n                return\n            self._rtp_transport = rtp_transport\n            self._transport = transport\n            self.notification_center.add_observer(self, sender=transport)\n            self._initialized = True\n            self.state = \"INITIALIZED\"\n            self.notification_center.post_notification('MediaStreamDidInitialize', sender=self)\n\n    def _NH_RTPTransportDidFail(self, notification):\n        self.notification_center.remove_observer(self, sender=notification.sender)\n        with self._lock:\n            if self.state == \"ENDED\":\n                return\n        self._try_next_rtp_transport(notification.data.reason)\n\n    def _NH_RTPTransportICENegotiationStateDidChange(self, notification):\n        with self._lock:\n            if self._ice_state != \"NULL\" or self.state not in (\"INITIALIZING\", \"INITIALIZED\", \"WAIT_ICE\"):\n                return\n        self.notification_center.post_notification('RTPStreamICENegotiationStateDidChange', sender=self, data=notification.data)\n\n    def _NH_RTPTransportICENegotiationDidSucceed(self, notification):\n        with self._lock:\n            if self.state != \"WAIT_ICE\":\n                return\n            self._ice_state = \"IN_USE\"\n            self.state = 'ESTABLISHED'\n        self.notification_center.post_notification('RTPStreamICENegotiationDidSucceed', sender=self, data=notification.data)\n        self.notification_center.post_notification('MediaStreamDidStart', sender=self)\n\n    def _NH_RTPTransportICENegotiationDidFail(self, notification):\n        with self._lock:\n            if self.state != \"WAIT_ICE\":\n                return\n            self._ice_state = \"FAILED\"\n            self.state = 'ESTABLISHED'\n        self.notification_center.post_notification('RTPStreamICENegotiationDidFail', sender=self, data=notification.data)\n        self.notification_center.post_notification('MediaStreamDidStart', sender=self)\n\n    # Private methods\n\n    def _init_rtp_transport(self, stun_servers=None):\n        self._rtp_args = dict()\n        self._rtp_args[\"encryption\"] = self._srtp_encryption\n        self._rtp_args[\"use_ice\"] = self._try_ice\n        self._stun_servers = [(None, None)]\n        if stun_servers:\n            self._stun_servers.extend(reversed(stun_servers))\n        self._try_next_rtp_transport()\n\n    def _try_next_rtp_transport(self, failure_reason=None):\n        if self._stun_servers:\n            stun_address, stun_port = self._stun_servers.pop()\n            try:\n                rtp_transport = RTPTransport(ice_stun_address=stun_address, ice_stun_port=stun_port, **self._rtp_args)\n            except SIPCoreError, e:\n                self._try_next_rtp_transport(e.args[0])\n            else:\n                self.notification_center.add_observer(self, sender=rtp_transport)\n                try:\n                    rtp_transport.set_INIT()\n                except SIPCoreError, e:\n                    self.notification_center.remove_observer(self, sender=rtp_transport)\n                    self._try_next_rtp_transport(e.args[0])\n        else:\n            self.state = \"ENDED\"\n            self.notification_center.post_notification('MediaStreamDidNotInitialize', sender=self, data=NotificationData(reason=failure_reason))\n\n    def _save_remote_sdp_rtp_info(self, remote_sdp, index):\n        connection = remote_sdp.media[index].connection or remote_sdp.connection\n        self._remote_rtp_address_sdp = connection.address\n        self._remote_rtp_port_sdp = remote_sdp.media[index].port\n\n    @abstractmethod\n    def _create_transport(self, rtp_transport, remote_sdp=None, stream_index=None):\n        raise NotImplementedError\n\n    @abstractmethod\n    def _check_hold(self, direction, is_initial):\n        raise NotImplementedError\n\n    @abstractmethod\n    def _pause(self):\n        raise NotImplementedError\n\n    @abstractmethod\n    def _resume(self):\n        raise NotImplementedError\n\n\nfrom sipsimple.streams.rtp import audio, video\n\n"
  },
  {
    "path": "sipsimple/streams/rtp/audio.py",
    "content": "\n__all__ = ['AudioStream']\n\nfrom application.notification import NotificationCenter, NotificationData\nfrom zope.interface import implements\n\nfrom sipsimple.audio import AudioBridge, AudioDevice, IAudioPort, WaveRecorder\nfrom sipsimple.configuration.settings import SIPSimpleSettings\nfrom sipsimple.core import AudioTransport, PJSIPError, SIPCoreError\nfrom sipsimple.streams.rtp import RTPStream\n\n\nclass AudioStream(RTPStream):\n    implements(IAudioPort)\n\n    type = 'audio'\n    priority = 1\n\n    def __init__(self):\n        super(AudioStream, self).__init__()\n\n        from sipsimple.application import SIPApplication\n        self.mixer = SIPApplication.voice_audio_mixer\n        self.bridge = AudioBridge(self.mixer)\n        self.device = AudioDevice(self.mixer)\n        self._audio_rec = None\n\n        self.bridge.add(self.device)\n\n    @property\n    def muted(self):\n        return self.__dict__.get('muted', False)\n\n    @muted.setter\n    def muted(self, value):\n        if not isinstance(value, bool):\n            raise ValueError(\"illegal value for muted property: %r\" % (value,))\n        if value == self.muted:\n            return\n        old_producer_slot = self.producer_slot\n        self.__dict__['muted'] = value\n        notification_center = NotificationCenter()\n        data = NotificationData(consumer_slot_changed=False, producer_slot_changed=True, old_producer_slot=old_producer_slot, new_producer_slot=self.producer_slot)\n        notification_center.post_notification('AudioPortDidChangeSlots', sender=self, data=data)\n\n    @property\n    def consumer_slot(self):\n        return self._transport.slot if self._transport else None\n\n    @property\n    def producer_slot(self):\n        return self._transport.slot if self._transport and not self.muted else None\n\n    @property\n    def recorder(self):\n        return self._audio_rec\n\n    def start(self, local_sdp, remote_sdp, stream_index):\n        with self._lock:\n            if self.state != \"INITIALIZED\":\n                raise RuntimeError(\"AudioStream.start() may only be called in the INITIALIZED state\")\n            settings = SIPSimpleSettings()\n            self._transport.start(local_sdp, remote_sdp, stream_index, timeout=settings.rtp.timeout)\n            self._save_remote_sdp_rtp_info(remote_sdp, stream_index)\n            self._check_hold(self._transport.direction, True)\n            if self._try_ice and self._ice_state == \"NULL\":\n                self.state = 'WAIT_ICE'\n            else:\n                self.state = 'ESTABLISHED'\n                self.notification_center.post_notification('MediaStreamDidStart', sender=self)\n\n    def validate_update(self, remote_sdp, stream_index):\n        with self._lock:\n            # TODO: implement\n            return True\n\n    def update(self, local_sdp, remote_sdp, stream_index):\n        with self._lock:\n            connection = remote_sdp.media[stream_index].connection or remote_sdp.connection\n            if not self._rtp_transport.ice_active and (connection.address != self._remote_rtp_address_sdp or self._remote_rtp_port_sdp != remote_sdp.media[stream_index].port):\n                settings = SIPSimpleSettings()\n                if self._audio_rec is not None:\n                    self.bridge.remove(self._audio_rec)\n                old_consumer_slot = self.consumer_slot\n                old_producer_slot = self.producer_slot\n                self.notification_center.remove_observer(self, sender=self._transport)\n                self._transport.stop()\n                try:\n                    self._transport = AudioTransport(self.mixer, self._rtp_transport, remote_sdp, stream_index, codecs=list(self.session.account.rtp.audio_codec_list or settings.rtp.audio_codec_list))\n                except SIPCoreError, e:\n                    self.state = \"ENDED\"\n                    self._failure_reason = e.args[0]\n                    self.notification_center.post_notification('MediaStreamDidFail', sender=self, data=NotificationData(context='update', reason=self._failure_reason))\n                    return\n                self.notification_center.add_observer(self, sender=self._transport)\n                self._transport.start(local_sdp, remote_sdp, stream_index, timeout=settings.rtp.timeout)\n                self.notification_center.post_notification('AudioPortDidChangeSlots', sender=self, data=NotificationData(consumer_slot_changed=True, producer_slot_changed=True,\n                                                                                                                         old_consumer_slot=old_consumer_slot, new_consumer_slot=self.consumer_slot,\n                                                                                                                         old_producer_slot=old_producer_slot, new_producer_slot=self.producer_slot))\n                if connection.address == '0.0.0.0' and remote_sdp.media[stream_index].direction == 'sendrecv':\n                    self._transport.update_direction('recvonly')\n                self._check_hold(self._transport.direction, False)\n                self.notification_center.post_notification('RTPStreamDidChangeRTPParameters', sender=self)\n            else:\n                new_direction = local_sdp.media[stream_index].direction\n                self._transport.update_direction(new_direction)\n                self._check_hold(new_direction, False)\n            self._save_remote_sdp_rtp_info(remote_sdp, stream_index)\n            self._transport.update_sdp(local_sdp, remote_sdp, stream_index)\n            self._hold_request = None\n\n    def deactivate(self):\n        with self._lock:\n            self.bridge.stop()\n\n    def end(self):\n        with self._lock:\n            if self.state == \"ENDED\" or self._done:\n                return\n            self._done = True\n            if not self._initialized:\n                self.state = \"ENDED\"\n                self.notification_center.post_notification('MediaStreamDidNotInitialize', sender=self, data=NotificationData(reason='Interrupted'))\n                return\n            self.notification_center.post_notification('MediaStreamWillEnd', sender=self)\n            if self._transport is not None:\n                if self._audio_rec is not None:\n                    self._stop_recording()\n                self.notification_center.remove_observer(self, sender=self._transport)\n                self.notification_center.remove_observer(self, sender=self._rtp_transport)\n                self._transport.stop()\n                self._transport = None\n                self._rtp_transport = None\n            self.state = \"ENDED\"\n            self.notification_center.post_notification('MediaStreamDidEnd', sender=self, data=NotificationData(error=self._failure_reason))\n            self.session = None\n\n    def reset(self, stream_index):\n        with self._lock:\n            if self.direction == \"inactive\" and not self.on_hold_by_local:\n                new_direction = \"sendrecv\"\n                self._transport.update_direction(new_direction)\n                self._check_hold(new_direction, False)\n                # TODO: do a full reset, re-creating the AudioTransport, so that a new offer\n                # would contain all codecs and ICE would be renegotiated -Saul\n\n    def send_dtmf(self, digit):\n        with self._lock:\n            if self.state != \"ESTABLISHED\":\n                raise RuntimeError(\"AudioStream.send_dtmf() cannot be used in %s state\" % self.state)\n            try:\n                self._transport.send_dtmf(digit)\n            except PJSIPError, e:\n                if not e.args[0].endswith(\"(PJ_ETOOMANY)\"):\n                    raise\n\n    def start_recording(self, filename):\n        with self._lock:\n            if self.state == \"ENDED\":\n                raise RuntimeError(\"AudioStream.start_recording() may not be called in the ENDED state\")\n            if self._audio_rec is not None:\n                raise RuntimeError(\"Already recording audio to a file\")\n            self._audio_rec = WaveRecorder(self.mixer, filename)\n            if self.state == \"ESTABLISHED\":\n                self._check_recording()\n\n    def stop_recording(self):\n        with self._lock:\n            if self._audio_rec is None:\n                raise RuntimeError(\"Not recording any audio\")\n            self._stop_recording()\n\n    def _NH_RTPAudioStreamGotDTMF(self, notification):\n        notification.center.post_notification('AudioStreamGotDTMF', sender=self, data=NotificationData(digit=notification.data.digit))\n\n    def _NH_RTPAudioTransportDidTimeout(self, notification):\n        notification.center.post_notification('RTPStreamDidTimeout', sender=self)\n\n    # Private methods\n    #\n\n    def _create_transport(self, rtp_transport, remote_sdp=None, stream_index=None):\n        settings = SIPSimpleSettings()\n        codecs = list(self.session.account.rtp.audio_codec_list or settings.rtp.audio_codec_list)\n        return AudioTransport(self.mixer, rtp_transport, remote_sdp=remote_sdp, sdp_index=stream_index or 0, codecs=codecs)\n\n    def _check_hold(self, direction, is_initial):\n        was_on_hold_by_local = self.on_hold_by_local\n        was_on_hold_by_remote = self.on_hold_by_remote\n        was_inactive = self.direction == \"inactive\"\n        self.direction = direction\n        inactive = self.direction == \"inactive\"\n        self.on_hold_by_local = was_on_hold_by_local if inactive else direction == \"sendonly\"\n        self.on_hold_by_remote = \"send\" not in direction\n        if (is_initial or was_on_hold_by_local or was_inactive) and not inactive and not self.on_hold_by_local and self._hold_request != 'hold':\n            self._resume()\n        if not was_on_hold_by_local and self.on_hold_by_local:\n            self.notification_center.post_notification('RTPStreamDidChangeHoldState', sender=self, data=NotificationData(originator=\"local\", on_hold=True))\n        if was_on_hold_by_local and not self.on_hold_by_local:\n            self.notification_center.post_notification('RTPStreamDidChangeHoldState', sender=self, data=NotificationData(originator=\"local\", on_hold=False))\n        if not was_on_hold_by_remote and self.on_hold_by_remote:\n            self.notification_center.post_notification('RTPStreamDidChangeHoldState', sender=self, data=NotificationData(originator=\"remote\", on_hold=True))\n        if was_on_hold_by_remote and not self.on_hold_by_remote:\n            self.notification_center.post_notification('RTPStreamDidChangeHoldState', sender=self, data=NotificationData(originator=\"remote\", on_hold=False))\n        if self._audio_rec is not None:\n            self._check_recording()\n\n    def _check_recording(self):\n        if not self._audio_rec.is_active:\n            self.notification_center.post_notification('AudioStreamWillStartRecording', sender=self, data=NotificationData(filename=self._audio_rec.filename))\n            try:\n                self._audio_rec.start()\n            except SIPCoreError, e:\n                self._audio_rec = None\n                self.notification_center.post_notification('AudioStreamDidStopRecording', sender=self, data=NotificationData(filename=self._audio_rec.filename, reason=e.args[0]))\n                return\n            self.notification_center.post_notification('AudioStreamDidStartRecording', sender=self, data=NotificationData(filename=self._audio_rec.filename))\n        if not self.on_hold:\n            self.bridge.add(self._audio_rec)\n        elif self._audio_rec in self.bridge:\n            self.bridge.remove(self._audio_rec)\n\n    def _stop_recording(self):\n        self.notification_center.post_notification('AudioStreamWillStopRecording', sender=self, data=NotificationData(filename=self._audio_rec.filename))\n        try:\n            if self._audio_rec.is_active:\n                self._audio_rec.stop()\n        finally:\n            self.notification_center.post_notification('AudioStreamDidStopRecording', sender=self, data=NotificationData(filename=self._audio_rec.filename))\n            self._audio_rec = None\n\n    def _pause(self):\n        self.bridge.remove(self)\n\n    def _resume(self):\n        self.bridge.add(self)\n"
  },
  {
    "path": "sipsimple/streams/rtp/video.py",
    "content": "\n__all__ = ['VideoStream']\n\nfrom application.notification import NotificationData\nfrom zope.interface import implements\n\nfrom sipsimple.configuration.settings import SIPSimpleSettings\nfrom sipsimple.core import VideoTransport\nfrom sipsimple.streams import InvalidStreamError\nfrom sipsimple.streams.rtp import RTPStream\nfrom sipsimple.threading import call_in_thread, run_in_twisted_thread\nfrom sipsimple.util import ExponentialTimer\nfrom sipsimple.video import IVideoProducer\n\n\nclass VideoStream(RTPStream):\n    implements(IVideoProducer)\n\n    type = 'video'\n    priority = 1\n\n    def __init__(self):\n        super(VideoStream, self).__init__()\n\n        from sipsimple.application import SIPApplication\n        self.device = SIPApplication.video_device\n        self._keyframe_timer = None\n\n    @property\n    def producer(self):\n        return self._transport.remote_video if self._transport else None\n\n    @classmethod\n    def new_from_sdp(cls, session, remote_sdp, stream_index):\n        stream = super(VideoStream, cls).new_from_sdp(session, remote_sdp, stream_index)\n        if stream.device.producer is None:\n            raise InvalidStreamError(\"no video support available\")\n        if not stream.validate_update(remote_sdp, stream_index):\n            raise InvalidStreamError(\"no valid SDP\")\n        return stream\n\n    def initialize(self, session, direction):\n        super(VideoStream, self).initialize(session, direction)\n        self.notification_center.add_observer(self, name='VideoDeviceDidChangeCamera')\n\n    def start(self, local_sdp, remote_sdp, stream_index):\n        with self._lock:\n            if self.state != \"INITIALIZED\":\n                raise RuntimeError(\"VideoStream.start() may only be called in the INITIALIZED state\")\n            settings = SIPSimpleSettings()\n            self._transport.start(local_sdp, remote_sdp, stream_index, timeout=settings.rtp.timeout)\n            self._transport.local_video.producer = self.device.producer\n            self._save_remote_sdp_rtp_info(remote_sdp, stream_index)\n            self._check_hold(self._transport.direction, True)\n            if self._try_ice and self._ice_state == \"NULL\":\n                self.state = 'WAIT_ICE'\n            else:\n                self._send_keyframes()\n                self.state = 'ESTABLISHED'\n                self.notification_center.post_notification('MediaStreamDidStart', sender=self)\n\n    def validate_update(self, remote_sdp, stream_index):\n        with self._lock:\n            remote_media = remote_sdp.media[stream_index]\n            if 'H264' in remote_media.codec_list:\n                rtpmap = next(attr for attr in remote_media.attributes if attr.name=='rtpmap' and 'h264' in attr.value.lower())\n                payload_type = rtpmap.value.partition(' ')[0]\n                has_profile_level_id = any('profile-level-id' in attr.value.lower() for attr in remote_media.attributes if attr.name=='fmtp' and attr.value.startswith(payload_type + ' '))\n                if not has_profile_level_id:\n                    return False\n            return True\n\n    def update(self, local_sdp, remote_sdp, stream_index):\n        with self._lock:\n            new_direction = local_sdp.media[stream_index].direction\n            self._check_hold(new_direction, False)\n            self._transport.update_direction(new_direction)\n            self._save_remote_sdp_rtp_info(remote_sdp, stream_index)\n            self._transport.update_sdp(local_sdp, remote_sdp, stream_index)\n            self._hold_request = None\n\n    def deactivate(self):\n        with self._lock:\n            self.notification_center.discard_observer(self, name='VideoDeviceDidChangeCamera')\n\n    def end(self):\n        with self._lock:\n            if self.state == \"ENDED\" or self._done:\n                return\n            self._done = True\n            if not self._initialized:\n                self.state = \"ENDED\"\n                self.notification_center.post_notification('MediaStreamDidNotInitialize', sender=self, data=NotificationData(reason='Interrupted'))\n                return\n            if self._keyframe_timer is not None:\n                self._keyframe_timer.stop()\n                self.notification_center.remove_observer(self, sender=self._keyframe_timer)\n            self._keyframe_timer = None\n            self.notification_center.post_notification('MediaStreamWillEnd', sender=self)\n            if self._transport is not None:\n                self.notification_center.remove_observer(self, sender=self._transport)\n                self.notification_center.remove_observer(self, sender=self._rtp_transport)\n                call_in_thread('device-io', self._transport.stop)\n                self._transport = None\n                self._rtp_transport = None\n            self.state = \"ENDED\"\n            self.notification_center.post_notification('MediaStreamDidEnd', sender=self, data=NotificationData(error=self._failure_reason))\n            self.session = None\n\n    def reset(self, stream_index):\n        pass\n\n    def _NH_RTPTransportICENegotiationDidSucceed(self, notification):\n        with self._lock:\n            if self.state == \"WAIT_ICE\":\n                self._send_keyframes()\n        super(VideoStream, self)._NH_RTPTransportICENegotiationDidSucceed(notification)\n\n    def _NH_RTPTransportICENegotiationDidFail(self, notification):\n        with self._lock:\n            if self.state == \"WAIT_ICE\":\n                self._send_keyframes()\n        super(VideoStream, self)._NH_RTPTransportICENegotiationDidFail(notification)\n\n    def _NH_RTPVideoTransportDidTimeout(self, notification):\n        self.notification_center.post_notification('RTPStreamDidTimeout', sender=self)\n\n    def _NH_RTPVideoTransportRemoteFormatDidChange(self, notification):\n        self.notification_center.post_notification('VideoStreamRemoteFormatDidChange', sender=self, data=notification.data)\n\n    def _NH_RTPVideoTransportReceivedKeyFrame(self, notification):\n        self.notification_center.post_notification('VideoStreamReceivedKeyFrame', sender=self, data=notification.data)\n\n    def _NH_RTPVideoTransportMissedKeyFrame(self, notification):\n        self._transport.request_keyframe()\n        self.notification_center.post_notification('VideoStreamMissedKeyFrame', sender=self, data=notification.data)\n\n    def _NH_RTPVideoTransportRequestedKeyFrame(self, notification):\n        self._transport.send_keyframe()\n        self.notification_center.post_notification('VideoStreamRequestedKeyFrame', sender=self, data=notification.data)\n\n    def _NH_VideoDeviceDidChangeCamera(self, notification):\n        new_camera = notification.data.new_camera\n        if self._transport is not None and self._transport.local_video is not None:\n            self._transport.local_video.producer = new_camera\n\n    def _NH_ExponentialTimerDidTimeout(self, notification):\n        if self._transport is not None:\n            self._transport.send_keyframe()\n\n    def _create_transport(self, rtp_transport, remote_sdp=None, stream_index=None):\n        settings = SIPSimpleSettings()\n        codecs = list(self.session.account.rtp.video_codec_list or settings.rtp.video_codec_list)\n        return VideoTransport(rtp_transport, remote_sdp=remote_sdp, sdp_index=stream_index or 0, codecs=codecs)\n\n    def _check_hold(self, direction, is_initial):\n        was_on_hold_by_local = self.on_hold_by_local\n        was_on_hold_by_remote = self.on_hold_by_remote\n        self.direction = direction\n        inactive = self.direction == \"inactive\"\n        self.on_hold_by_local = was_on_hold_by_local if inactive else direction == \"sendonly\"\n        self.on_hold_by_remote = \"send\" not in direction\n        if self.on_hold_by_local or self.on_hold_by_remote:\n            self._pause()\n        elif not self.on_hold_by_local and not self.on_hold_by_remote and (was_on_hold_by_local or was_on_hold_by_remote):\n            self._resume()\n        if not was_on_hold_by_local and self.on_hold_by_local:\n            self.notification_center.post_notification('RTPStreamDidChangeHoldState', sender=self, data=NotificationData(originator=\"local\", on_hold=True))\n        if was_on_hold_by_local and not self.on_hold_by_local:\n            self.notification_center.post_notification('RTPStreamDidChangeHoldState', sender=self, data=NotificationData(originator=\"local\", on_hold=False))\n        if not was_on_hold_by_remote and self.on_hold_by_remote:\n            self.notification_center.post_notification('RTPStreamDidChangeHoldState', sender=self, data=NotificationData(originator=\"remote\", on_hold=True))\n        if was_on_hold_by_remote and not self.on_hold_by_remote:\n            self.notification_center.post_notification('RTPStreamDidChangeHoldState', sender=self, data=NotificationData(originator=\"remote\", on_hold=False))\n\n    @run_in_twisted_thread\n    def _send_keyframes(self):\n        if self._keyframe_timer is None:\n            self._keyframe_timer = ExponentialTimer()\n            self.notification_center.add_observer(self, sender=self._keyframe_timer)\n        self._keyframe_timer.start(0.5, immediate=True, iterations=5)\n\n    def _pause(self):\n        self._transport.pause()\n\n    def _resume(self):\n        self._transport.resume()\n        self._send_keyframes()\n        self._transport.request_keyframe()\n\n"
  },
  {
    "path": "sipsimple/threading/__init__.py",
    "content": "\n\"\"\"Thread management\"\"\"\n\n__all__ = [\"ThreadManager\", \"run_in_thread\", \"call_in_thread\", \"run_in_twisted_thread\", \"call_in_twisted_thread\"]\n\nfrom application.python import Null\nfrom application.python.decorator import decorator, preserve_signature\nfrom application.python.queue import EventQueue\nfrom application.python.types import Singleton\nfrom threading import Lock, current_thread\nfrom twisted.python import threadable\n\nfrom sipsimple import log\n\n\nclass CallFunctionEvent(object):\n    __slots__ = ('function', 'args', 'kw')\n\n    def __init__(self, function, args, kw):\n        self.function = function\n        self.args = args\n        self.kw = kw\n\n\nclass ThreadManager(object):\n    __metaclass__ = Singleton\n\n    def __init__(self):\n        self.threads = {}\n        self.lock = Lock()\n\n    def _event_handler(self, event):\n        handler = getattr(self, '_EH_%s' % event.__class__.__name__, Null)\n        handler(event)\n\n    def _EH_CallFunctionEvent(self, event):\n        try:\n            event.function(*event.args, **event.kw)\n        except:\n            log.exception('Exception occurred while calling %r in the %r thread' % (event.function, current_thread().name))\n\n    def start(self):\n        pass\n\n    def stop(self):\n        with self.lock:\n            threads = self.threads.values()\n            self.threads = {}\n        for thread in threads:\n            thread.stop()\n        for thread in threads:\n            thread.join()\n\n    def get_thread(self, thread_id):\n        with self.lock:\n            try:\n                thread = self.threads[thread_id]\n            except KeyError:\n                self.threads[thread_id] = thread = EventQueue(handler=self._event_handler, name=thread_id)\n                thread.start()\n            return thread\n\n    def stop_thread(self, thread_id):\n        if thread_id == 'thread-ops':\n            raise RuntimeError(\"Won't stop internal 'thread-ops' thread\")\n        thread = self.threads.pop(thread_id)\n        thread.stop()\n        call_in_thread('thread-ops', thread.join)\n\n\n@decorator\ndef run_in_thread(thread_id, scheduled=False):\n    def thread_decorator(function):\n        @preserve_signature(function)\n        def wrapper(*args, **kw):\n            thread_manager = ThreadManager()\n            thread = thread_manager.get_thread(thread_id)\n            if thread is current_thread() and not scheduled:\n                function(*args, **kw)\n            else:\n                thread.put(CallFunctionEvent(function, args, kw))\n        return wrapper\n    return thread_decorator\n\n\ndef call_in_thread(thread_id, function, *args, **kw):\n    thread_manager = ThreadManager()\n    thread = thread_manager.get_thread(thread_id)\n    if thread is current_thread():\n        function(*args, **kw)\n    else:\n        thread.put(CallFunctionEvent(function, args, kw))\n\n\ndef schedule_in_thread(thread_id, function, *args, **kw):\n    thread_manager = ThreadManager()\n    thread = thread_manager.get_thread(thread_id)\n    thread.put(CallFunctionEvent(function, args, kw))\n\n\n@decorator\ndef run_in_twisted_thread(func):\n    @preserve_signature(func)\n    def wrapper(*args, **kwargs):\n        if threadable.isInIOThread():\n            func(*args, **kwargs)\n        else:\n            from twisted.internet import reactor\n            reactor.callFromThread(func, *args, **kwargs)\n    return wrapper\n\n\ndef call_in_twisted_thread(func, *args, **kwargs):\n    if threadable.isInIOThread():\n        func(*args, **kwargs)\n    else:\n        from twisted.internet import reactor\n        reactor.callFromThread(func, *args, **kwargs)\n\n\n"
  },
  {
    "path": "sipsimple/threading/green.py",
    "content": "\n\"\"\"Green thread utilities\"\"\"\n\n__all__ = [\"Command\", \"InterruptCommand\", \"run_in_green_thread\", \"run_in_waitable_green_thread\", \"call_in_green_thread\", \"Worker\"]\n\nimport sys\n\nfrom application.python.decorator import decorator, preserve_signature\nfrom datetime import datetime\nfrom eventlib import coros\nfrom eventlib.twistedutil import callInGreenThread\nfrom twisted.python import threadable\n\n\nclass modulelocal(object):\n    __locals__ = {}\n    def __get__(self, obj, objtype):\n        frame = sys._getframe().f_back\n        while frame.f_globals['__name__'] == __name__:\n            frame = frame.f_back\n        module_name = frame.f_globals['__name__']\n        return self.__locals__.setdefault(module_name, {})\n    def __set__(self, obj, value):\n        raise AttributeError('cannot set attribute')\n    def __delete__(self, obj):\n        raise AttributeError('cannot delete attribute')\n\n\nclass Command(object):\n    __defaults__ = modulelocal()\n\n    def __init__(self, name, event=None, timestamp=None, **kw):\n        self.name = name\n        self.event = event or coros.event()\n        self.timestamp = timestamp or datetime.utcnow()\n        self.__dict__.update(self.__defaults__.get(name, {}))\n        self.__dict__.update(kw)\n\n    @classmethod\n    def register_defaults(cls, name, **kw):\n        cls.__defaults__[name] = kw\n\n    def signal(self, result=None):\n        if isinstance(result, BaseException):\n            self.event.send_exception(result)\n        else:\n            self.event.send(result)\n\n    def wait(self):\n        return self.event.wait()\n\n\nclass InterruptCommand(Exception): pass\n\n\n@decorator\ndef run_in_green_thread(func):\n    @preserve_signature(func)\n    def wrapper(*args, **kw):\n        if threadable.isInIOThread():\n            callInGreenThread(func, *args, **kw)\n        else:\n            from twisted.internet import reactor\n            reactor.callFromThread(callInGreenThread, func, *args, **kw)\n    return wrapper\n\n\ndef call_in_green_thread(func, *args, **kw):\n    if threadable.isInIOThread():\n        callInGreenThread(func, *args, **kw)\n    else:\n        from twisted.internet import reactor\n        reactor.callFromThread(callInGreenThread, func, *args, **kw)\n\n\n@decorator\ndef run_in_waitable_green_thread(func):\n    @preserve_signature(func)\n    def wrapper(*args, **kw):\n        event = coros.event()\n        def wrapped_func():\n            try:\n                result = func(*args, **kw)\n            except:\n                event.send_exception(*sys.exc_info())\n            else:\n                event.send(result)\n        if threadable.isInIOThread():\n            callInGreenThread(wrapped_func)\n        else:\n            from twisted.internet import reactor\n            reactor.callFromThread(callInGreenThread, wrapped_func)\n        return event\n    return wrapper\n\n\nclass Worker(object):\n    def __init__(self, func, *args, **kw):\n        self.func = func\n        self.args = args\n        self.kw = kw\n        self.event = coros.event()\n        self._started = False\n\n    def __run__(self):\n        try:\n            result = self.func(*self.args, **self.kw)\n        except:\n            self.event.send_exception(*sys.exc_info())\n        else:\n            self.event.send(result)\n\n    def start(self):\n        if self._started:\n            raise RuntimeError(\"worker has already been started\")\n        if not threadable.isInIOThread():\n            raise RuntimeError(\"worker can only be started in the IO thread\")\n        self._started = True\n        callInGreenThread(self.__run__)\n\n    def wait(self):\n        if not self._started:\n            raise RuntimeError(\"worker has not been started\")\n        return self.event.wait()\n\n    def wait_ex(self):\n        if not self._started:\n            raise RuntimeError(\"worker has not been started\")\n        try:\n            return self.event.wait()\n        except Exception as e:\n            return e\n\n    @classmethod\n    def spawn(cls, func, *args, **kw):\n        worker = cls(func, *args, **kw)\n        worker.start()\n        return worker\n\n\n"
  },
  {
    "path": "sipsimple/util/__init__.py",
    "content": "\n\"\"\"Implements utilities commonly used in various parts of the library\"\"\"\n\nfrom __future__ import absolute_import\n\n__all__ = [\"All\", \"Any\", \"ExponentialTimer\", \"ISOTimestamp\", \"MultilingualText\", \"user_info\", \"sha1\"]\n\nimport os\nimport platform\nimport sys\nimport dateutil.parser\n\nfrom application.notification import NotificationCenter\nfrom application.python.types import Singleton, MarkerType\nfrom datetime import datetime\nfrom dateutil.tz import tzlocal, tzutc\nfrom twisted.internet import reactor\n\nfrom sipsimple.util._sha1 import sha1\n\n\n# Utility classes\n#\n\nclass All(object):\n    __metaclass__ = MarkerType\n\n\nclass Any(object):\n    __metaclass__ = MarkerType\n\n\nclass ISOTimestamp(datetime):\n    def __new__(cls, *args, **kw):\n        if len(args) == 1:\n            value = args[0]\n            if isinstance(value, cls):\n                return value\n            elif isinstance(value, basestring):\n                value = dateutil.parser.parse(value)\n                return cls(value.year, value.month, value.day, value.hour, value.minute, value.second, value.microsecond, value.tzinfo)\n            elif isinstance(value, datetime):\n                return cls(value.year, value.month, value.day, value.hour, value.minute, value.second, value.microsecond, value.tzinfo or tzlocal())\n            else:\n                return datetime.__new__(cls, *args, **kw)\n        else:\n            if len(args) < 8 and 'tzinfo' not in kw:\n                kw['tzinfo'] = tzlocal()\n            return datetime.__new__(cls, *args, **kw)\n\n    def __str__(self):\n        return self.isoformat()\n\n    @classmethod\n    def now(cls):\n        return cls(datetime.now(tzlocal()))\n\n    @classmethod\n    def utcnow(cls):\n        return cls(datetime.now(tzutc()))\n\n\nclass MultilingualText(unicode):\n    def __new__(cls, *args, **translations):\n        if len(args) > 1:\n            raise TypeError(\"%s.__new__ takes at most 1 positional argument (%d given)\" % (cls.__name__, len(args)))\n        default = args[0] if args else translations.get('en', u'')\n        obj = unicode.__new__(cls, default)\n        obj.translations = translations\n        return obj\n\n    def get_translation(self, language):\n        return self.translations.get(language, self)\n\n\nclass ExponentialTimer(object):\n    def __init__(self):\n        self._timer = None\n        self._limit_timer = None\n        self._interval = 0\n        self._iterations = None\n\n    def _step(self):\n        if self._iterations is not None:\n            self._iterations -= 1\n        if self._iterations == 0:\n            self.stop()\n        else:\n            self._interval *= 2\n            self._timer = reactor.callLater(self._interval, self._step)\n        NotificationCenter().post_notification('ExponentialTimerDidTimeout', sender=self)\n\n    @property\n    def active(self):\n        return self._timer is not None\n\n    def start(self, base_interval, immediate=False, iterations=None, time_limit=None):\n        assert base_interval > 0\n        assert iterations is None or iterations > 0\n        assert time_limit is None or time_limit > 0\n        if self._timer is not None:\n            self.stop()\n        self._interval = base_interval / 2.0 if immediate else base_interval\n        self._iterations = iterations\n        if time_limit is not None:\n            self._limit_timer = reactor.callLater(time_limit, self.stop)\n        self._timer = reactor.callLater(0 if immediate else base_interval, self._step)\n\n    def stop(self):\n        if self._timer is not None and self._timer.active():\n            self._timer.cancel()\n        if self._limit_timer is not None and self._limit_timer.active():\n            self._limit_timer.cancel()\n        self._timer = None\n        self._limit_timer = None\n\n\n# Utility objects\n#\n\nclass UserInfo(object):\n    __metaclass__ = Singleton\n\n    def __repr__(self):\n        return '<username={0.username!r}, fullname={0.fullname!r}>'.format(self)\n\n    @property\n    def username(self):\n        if platform.system() == 'Windows':\n            name = os.getenv('USERNAME')\n        else:\n            import pwd\n            name = pwd.getpwuid(os.getuid()).pw_name\n        return name.decode(sys.getfilesystemencoding())\n\n    @property\n    def fullname(self):\n        if platform.system() == 'Windows':\n            name = os.getenv('USERNAME')\n        else:\n            import pwd\n            name = pwd.getpwuid(os.getuid()).pw_gecos.split(',', 1)[0] or pwd.getpwuid(os.getuid()).pw_name\n        return name.decode(sys.getfilesystemencoding())\n\nuser_info = UserInfo()\ndel UserInfo\n\n\n"
  },
  {
    "path": "sipsimple/util/_sha1.h",
    "content": "\n#ifndef __SHA1_H\n#define __SHA1_H\n\n\n#include <stdint.h>\n#include <string.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define SHA1_BLOCK_SIZE  64\n#define SHA1_DIGEST_SIZE 20\n\n\ntypedef struct {\n    uint32_t state[SHA1_DIGEST_SIZE/4];  // state variables\n    uint64_t count;                      // 64-bit block count\n    uint8_t  block[SHA1_BLOCK_SIZE];     // data block buffer\n    uint32_t index;                      // index into buffer\n} sha1_context;\n\n\nvoid sha1_init(sha1_context *context);\nvoid sha1_update(sha1_context *context, const uint8_t *data, const size_t len);\nvoid sha1_digest(sha1_context *context, uint8_t *digest);\n\n#ifdef __cplusplus\n}\n#endif\n\n\n/* Reads a 32-bit integer, in network, big-endian, byte order */\n#define READ_UINT32(p)                          \\\n(  (((uint32_t) (p)[0]) << 24)                  \\\n | (((uint32_t) (p)[1]) << 16)                  \\\n | (((uint32_t) (p)[2]) << 8)                   \\\n |  ((uint32_t) (p)[3]))\n\n#define ROTL32(n,x) (((x)<<(n)) | ((x)>>((-(n)&31))))\n\n/* A block, treated as a sequence of 32-bit words. */\n#define SHA1_DATA_LENGTH 16\n\n/* The SHA f()-functions.  The f1 and f3 functions can be optimized to\n   save one boolean operation each - thanks to Rich Schroeppel,\n   rcs@cs.arizona.edu for discovering this */\n\n/* FIXME: Can save a temporary in f3 by using ( (x & y) + (z & (x ^\n   y)) ), and then, in the round, compute one of the terms and add it\n   into the destination word before computing the second term. Credits\n   to George Spelvin for pointing this out. Unfortunately, gcc\n   doesn't seem to be smart enough to take advantage of this. */\n\n/* #define f1(x,y,z) ( ( x & y ) | ( ~x & z ) )            Rounds  0-19 */\n#define f1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )           /* Rounds  0-19 */\n#define f2(x,y,z)   ( x ^ y ^ z )                       /* Rounds 20-39 */\n/* #define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) Rounds 40-59 */\n#define f3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )   /* Rounds 40-59 */\n#define f4 f2\n\n/* The SHA Mysterious Constants */\n\n#define K1  0x5A827999L                                 /* Rounds  0-19 */\n#define K2  0x6ED9EBA1L                                 /* Rounds 20-39 */\n#define K3  0x8F1BBCDCL                                 /* Rounds 40-59 */\n#define K4  0xCA62C1D6L                                 /* Rounds 60-79 */\n\n/* The initial expanding function.  The hash function is defined over an\n   80-word expanded input array W, where the first 16 are copies of the input\n   data, and the remaining 64 are defined by\n\n        W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]\n\n   This implementation generates these values on the fly in a circular\n   buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this\n   optimization.\n\n   The updated SHA changes the expanding function by adding a rotate of 1\n   bit.  Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor\n   for this information */\n\n#define expand(W,i) ( W[ i & 15 ] = \\\n\t\t      ROTL32( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \\\n\t\t\t\t   W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )\n\n\n/* The prototype SHA sub-round.  The fundamental sub-round is:\n\n        a' = e + ROTL32( 5, a ) + f( b, c, d ) + k + data;\n        b' = a;\n        c' = ROTL32( 30, b );\n        d' = c;\n        e' = d;\n\n   but this is implemented by unrolling the loop 5 times and renaming the\n   variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.\n   This code is then replicated 20 times for each of the 4 functions, using\n   the next 20 values from the W[] array each time */\n\n#define subRound(a, b, c, d, e, f, k, data) \\\n    ( e += ROTL32( 5, a ) + f( b, c, d ) + k + data, b = ROTL32( 30, b ) )\n\n/* Perform the SHA transformation.  Note that this code, like MD5, seems to\n   break some optimizing compilers due to the complexity of the expressions\n   and the size of the basic block.  It may be necessary to split it into\n   sections, e.g. based on the four subrounds. */\n\nstatic void sha1_compress(uint32_t *state, const uint8_t *input)\n{\n  uint32_t data[SHA1_DATA_LENGTH];\n  uint32_t A, B, C, D, E;     /* Local vars */\n  int i;\n\n  for (i = 0; i < SHA1_DATA_LENGTH; i++, input+= 4)\n    {\n      data[i] = READ_UINT32(input);\n    }\n\n  /* Set up first buffer and local data buffer */\n  A = state[0];\n  B = state[1];\n  C = state[2];\n  D = state[3];\n  E = state[4];\n\n  /* Heavy mangling, in 4 sub-rounds of 20 interations each. */\n  subRound(A, B, C, D, E, f1, K1, data[ 0]);\n  subRound(E, A, B, C, D, f1, K1, data[ 1]);\n  subRound(D, E, A, B, C, f1, K1, data[ 2]);\n  subRound(C, D, E, A, B, f1, K1, data[ 3]);\n  subRound(B, C, D, E, A, f1, K1, data[ 4]);\n  subRound(A, B, C, D, E, f1, K1, data[ 5]);\n  subRound(E, A, B, C, D, f1, K1, data[ 6]);\n  subRound(D, E, A, B, C, f1, K1, data[ 7]);\n  subRound(C, D, E, A, B, f1, K1, data[ 8]);\n  subRound(B, C, D, E, A, f1, K1, data[ 9]);\n  subRound(A, B, C, D, E, f1, K1, data[10]);\n  subRound(E, A, B, C, D, f1, K1, data[11]);\n  subRound(D, E, A, B, C, f1, K1, data[12]);\n  subRound(C, D, E, A, B, f1, K1, data[13]);\n  subRound(B, C, D, E, A, f1, K1, data[14]);\n  subRound(A, B, C, D, E, f1, K1, data[15]);\n  subRound(E, A, B, C, D, f1, K1, expand(data, 16));\n  subRound(D, E, A, B, C, f1, K1, expand(data, 17));\n  subRound(C, D, E, A, B, f1, K1, expand(data, 18));\n  subRound(B, C, D, E, A, f1, K1, expand(data, 19));\n\n  subRound(A, B, C, D, E, f2, K2, expand(data, 20));\n  subRound(E, A, B, C, D, f2, K2, expand(data, 21));\n  subRound(D, E, A, B, C, f2, K2, expand(data, 22));\n  subRound(C, D, E, A, B, f2, K2, expand(data, 23));\n  subRound(B, C, D, E, A, f2, K2, expand(data, 24));\n  subRound(A, B, C, D, E, f2, K2, expand(data, 25));\n  subRound(E, A, B, C, D, f2, K2, expand(data, 26));\n  subRound(D, E, A, B, C, f2, K2, expand(data, 27));\n  subRound(C, D, E, A, B, f2, K2, expand(data, 28));\n  subRound(B, C, D, E, A, f2, K2, expand(data, 29));\n  subRound(A, B, C, D, E, f2, K2, expand(data, 30));\n  subRound(E, A, B, C, D, f2, K2, expand(data, 31));\n  subRound(D, E, A, B, C, f2, K2, expand(data, 32));\n  subRound(C, D, E, A, B, f2, K2, expand(data, 33));\n  subRound(B, C, D, E, A, f2, K2, expand(data, 34));\n  subRound(A, B, C, D, E, f2, K2, expand(data, 35));\n  subRound(E, A, B, C, D, f2, K2, expand(data, 36));\n  subRound(D, E, A, B, C, f2, K2, expand(data, 37));\n  subRound(C, D, E, A, B, f2, K2, expand(data, 38));\n  subRound(B, C, D, E, A, f2, K2, expand(data, 39));\n\n  subRound(A, B, C, D, E, f3, K3, expand(data, 40));\n  subRound(E, A, B, C, D, f3, K3, expand(data, 41));\n  subRound(D, E, A, B, C, f3, K3, expand(data, 42));\n  subRound(C, D, E, A, B, f3, K3, expand(data, 43));\n  subRound(B, C, D, E, A, f3, K3, expand(data, 44));\n  subRound(A, B, C, D, E, f3, K3, expand(data, 45));\n  subRound(E, A, B, C, D, f3, K3, expand(data, 46));\n  subRound(D, E, A, B, C, f3, K3, expand(data, 47));\n  subRound(C, D, E, A, B, f3, K3, expand(data, 48));\n  subRound(B, C, D, E, A, f3, K3, expand(data, 49));\n  subRound(A, B, C, D, E, f3, K3, expand(data, 50));\n  subRound(E, A, B, C, D, f3, K3, expand(data, 51));\n  subRound(D, E, A, B, C, f3, K3, expand(data, 52));\n  subRound(C, D, E, A, B, f3, K3, expand(data, 53));\n  subRound(B, C, D, E, A, f3, K3, expand(data, 54));\n  subRound(A, B, C, D, E, f3, K3, expand(data, 55));\n  subRound(E, A, B, C, D, f3, K3, expand(data, 56));\n  subRound(D, E, A, B, C, f3, K3, expand(data, 57));\n  subRound(C, D, E, A, B, f3, K3, expand(data, 58));\n  subRound(B, C, D, E, A, f3, K3, expand(data, 59));\n\n  subRound(A, B, C, D, E, f4, K4, expand(data, 60));\n  subRound(E, A, B, C, D, f4, K4, expand(data, 61));\n  subRound(D, E, A, B, C, f4, K4, expand(data, 62));\n  subRound(C, D, E, A, B, f4, K4, expand(data, 63));\n  subRound(B, C, D, E, A, f4, K4, expand(data, 64));\n  subRound(A, B, C, D, E, f4, K4, expand(data, 65));\n  subRound(E, A, B, C, D, f4, K4, expand(data, 66));\n  subRound(D, E, A, B, C, f4, K4, expand(data, 67));\n  subRound(C, D, E, A, B, f4, K4, expand(data, 68));\n  subRound(B, C, D, E, A, f4, K4, expand(data, 69));\n  subRound(A, B, C, D, E, f4, K4, expand(data, 70));\n  subRound(E, A, B, C, D, f4, K4, expand(data, 71));\n  subRound(D, E, A, B, C, f4, K4, expand(data, 72));\n  subRound(C, D, E, A, B, f4, K4, expand(data, 73));\n  subRound(B, C, D, E, A, f4, K4, expand(data, 74));\n  subRound(A, B, C, D, E, f4, K4, expand(data, 75));\n  subRound(E, A, B, C, D, f4, K4, expand(data, 76));\n  subRound(D, E, A, B, C, f4, K4, expand(data, 77));\n  subRound(C, D, E, A, B, f4, K4, expand(data, 78));\n  subRound(B, C, D, E, A, f4, K4, expand(data, 79));\n\n  /* Build message digest */\n  state[0] += A;\n  state[1] += B;\n  state[2] += C;\n  state[3] += D;\n  state[4] += E;\n}\n\n\nvoid sha1_init(sha1_context *context)\n{\n    /* SHA1 initialization constants */\n    context->state[0] = 0x67452301;\n    context->state[1] = 0xEFCDAB89;\n    context->state[2] = 0x98BADCFE;\n    context->state[3] = 0x10325476;\n    context->state[4] = 0xC3D2E1F0;\n    context->count = 0;\n    context->index = 0;\n}\n\n\nvoid sha1_update(sha1_context *context, const uint8_t *data, size_t length)\n{\n    if (context->index) {\n        unsigned int left  = SHA1_BLOCK_SIZE - context->index;\n        if (length < left) {\n            memcpy(context->block + context->index, data, length);\n            context->index += length;\n            return;\n        } else {\n            memcpy(context->block + context->index, data, left);\n            sha1_compress(context->state, context->block);\n            context->count++;\n            data += left;\n            length -= left;\n        }\n    }\n\n    while (length >= SHA1_BLOCK_SIZE) {\n        sha1_compress(context->state, data);\n        context->count++;\n        data += SHA1_BLOCK_SIZE;\n        length -= SHA1_BLOCK_SIZE;\n    }\n    memcpy(context->block, data, length);\n    context->index = length;\n}\n\n\nvoid sha1_digest(sha1_context *context, uint8_t *digest)\n{\n    uint64_t bit_count;\n    unsigned int i;\n\n    i = context->index;\n\n    context->block[i++] = 0x80;\n    if (i > SHA1_BLOCK_SIZE - 8) {\n        // no room for length in this block. process it, then pad another one\n        memset(context->block + i, 0, SHA1_BLOCK_SIZE - i);\n        sha1_compress(context->state, context->block);\n        memset(context->block, 0, SHA1_BLOCK_SIZE - 8);\n    } else {\n        memset(context->block + i, 0, SHA1_BLOCK_SIZE - 8 - i);\n    }\n\n    bit_count = (context->count << 9) | (context->index << 3);\n\n    context->block[56] = (bit_count >> 56) & 0xff;\n    context->block[57] = (bit_count >> 48) & 0xff;\n    context->block[58] = (bit_count >> 40) & 0xff;\n    context->block[59] = (bit_count >> 32) & 0xff;\n    context->block[60] = (bit_count >> 24) & 0xff;\n    context->block[61] = (bit_count >> 16) & 0xff;\n    context->block[62] = (bit_count >>  8) & 0xff;\n    context->block[63] = (bit_count      ) & 0xff;\n\n    sha1_compress(context->state, context->block);\n\n    digest[ 0] = (context->state[0] >> 24) & 0xff;\n    digest[ 1] = (context->state[0] >> 16) & 0xff;\n    digest[ 2] = (context->state[0] >>  8) & 0xff;\n    digest[ 3] = (context->state[0]      ) & 0xff;\n    digest[ 4] = (context->state[1] >> 24) & 0xff;\n    digest[ 5] = (context->state[1] >> 16) & 0xff;\n    digest[ 6] = (context->state[1] >>  8) & 0xff;\n    digest[ 7] = (context->state[1]      ) & 0xff;\n    digest[ 8] = (context->state[2] >> 24) & 0xff;\n    digest[ 9] = (context->state[2] >> 16) & 0xff;\n    digest[10] = (context->state[2] >>  8) & 0xff;\n    digest[11] = (context->state[2]      ) & 0xff;\n    digest[12] = (context->state[3] >> 24) & 0xff;\n    digest[13] = (context->state[3] >> 16) & 0xff;\n    digest[14] = (context->state[3] >>  8) & 0xff;\n    digest[15] = (context->state[3]      ) & 0xff;\n    digest[16] = (context->state[4] >> 24) & 0xff;\n    digest[17] = (context->state[4] >> 16) & 0xff;\n    digest[18] = (context->state[4] >>  8) & 0xff;\n    digest[19] = (context->state[4]      ) & 0xff;\n}\n\n#endif /* __SHA1_H */\n\n"
  },
  {
    "path": "sipsimple/util/_sha1.pyx",
    "content": "# cython: language_level=2\n\n__all__ = ['sha1']\n\n\nfrom libc.stddef cimport size_t\nfrom libc.stdint cimport uint8_t, uint32_t, uint64_t\nfrom libc.string cimport memcpy\nfrom cpython.buffer cimport PyObject_CheckBuffer, PyObject_GetBuffer, PyBuffer_Release\nfrom cpython.string cimport PyString_FromStringAndSize, PyString_AS_STRING\nfrom cpython.unicode cimport PyUnicode_Check\n\n\ncdef extern from \"_sha1.h\":\n    enum:\n        SHA1_BLOCK_SIZE  = 64\n        SHA1_DIGEST_SIZE = 20\n\n    ctypedef struct sha1_context:\n        uint32_t state[SHA1_DIGEST_SIZE/4]  # state variables\n        uint64_t count                      # 64-bit block count\n        uint8_t  block[SHA1_BLOCK_SIZE]     # data block buffer\n        uint32_t index                      # index into buffer\n\n    cdef void sha1_init(sha1_context *context)\n    cdef void sha1_update(sha1_context *context, const uint8_t *data, size_t length)\n    cdef void sha1_digest(sha1_context *context, uint8_t *digest)\n\n\ncdef class sha1(object):\n    cdef sha1_context context\n\n    def __cinit__(self, *args, **kw):\n        sha1_init(&self.context)\n\n    def __init__(self, data=''):\n        self.update(data)\n\n    property name:\n        def __get__(self):\n            return 'sha1'\n\n    property block_size:\n        def __get__(self):\n            return SHA1_BLOCK_SIZE\n\n    property digest_size:\n        def __get__(self):\n            return SHA1_DIGEST_SIZE\n\n    def __reduce__(self):\n        state_variables = [self.context.state[i] for i in range(sizeof(self.context.state)/4)]\n        block = PyString_FromStringAndSize(<char*>self.context.block, self.context.index)\n        return self.__class__, (), (state_variables, self.context.count, block)\n\n    def __setstate__(self, state):\n        state_variables, count, block = state\n        for i, number in enumerate(state_variables):\n            self.context.state[i] = number\n        self.context.count = count\n        self.context.index = len(block)\n        memcpy(self.context.block, PyString_AS_STRING(block), self.context.index)\n\n    def copy(self):\n        cdef sha1 instance = self.__class__()\n        instance.context = self.context\n        return instance\n\n    def update(self, data):\n        cdef Py_buffer view\n\n        if PyObject_CheckBuffer(data):\n            PyObject_GetBuffer(data, &view, 0)\n            if view.ndim > 1:\n                raise BufferError('Buffer must be single dimension')\n            sha1_update(&self.context, <uint8_t*>view.buf, view.len)\n            PyBuffer_Release(&view)\n        elif PyUnicode_Check(data):\n            raise TypeError('Unicode-objects must be encoded before hashing')\n        else:\n            raise TypeError('object supporting the buffer API required')\n\n    def digest(self):\n        cdef sha1_context context_copy\n        cdef uint8_t digest[SHA1_DIGEST_SIZE]\n\n        context_copy = self.context\n        sha1_digest(&context_copy, digest)\n        return PyString_FromStringAndSize(<char*>digest, SHA1_DIGEST_SIZE)\n\n    def hexdigest(self):\n        return self.digest().encode('hex')\n\n"
  },
  {
    "path": "sipsimple/video.py",
    "content": "\n\"\"\"Video support\"\"\"\n\nfrom __future__ import absolute_import\n\n__all__ = ['IVideoProducer', 'VideoDevice', 'VideoError']\n\nfrom application.notification import NotificationCenter, NotificationData\nfrom zope.interface import Attribute, Interface, implements\n\nfrom sipsimple.core import SIPCoreError, VideoCamera\n\n\nclass IVideoProducer(Interface):\n    \"\"\"\n    Interface describing an object which can produce video data.\n    All attributes of this interface are read-only.\n    \"\"\"\n\n    producer = Attribute(\"The core producer object which can be connected to a consumer\")\n\n\nclass VideoError(Exception):\n    pass\n\n\nclass VideoDevice(object):\n    implements(IVideoProducer)\n\n    def __init__(self, device_name, resolution, framerate):\n        self._camera = self._open_camera(device_name, resolution, framerate)\n        self._camera.start()\n\n    def _open_camera(self, device_name, resolution, framerate):\n        try:\n            return VideoCamera(device_name, resolution, framerate)\n        except SIPCoreError:\n            try:\n                return VideoCamera(u'system_default', resolution, framerate)\n            except SIPCoreError:\n                return VideoCamera(None, resolution, framerate)\n\n    def set_camera(self, device_name, resolution, framerate):\n        old_camera = self._camera\n        old_camera.close()\n        new_camera = self._open_camera(device_name, resolution, framerate)\n        if not self.muted:\n            new_camera.start()\n        self._camera = new_camera\n        notification_center = NotificationCenter()\n        notification_center.post_notification('VideoDeviceDidChangeCamera', sender=self, data=NotificationData(old_camera=old_camera, new_camera=new_camera))\n\n    @property\n    def producer(self):\n        return self._camera\n\n    @property\n    def name(self):\n        return self._camera.name\n\n    @property\n    def real_name(self):\n        return self._camera.real_name\n\n    @property\n    def muted(self):\n        return self.__dict__.get('muted', False)\n\n    @muted.setter\n    def muted(self, value):\n        if not isinstance(value, bool):\n            raise ValueError('illegal value for muted property: %r' % (value,))\n        if value == self.muted:\n            return\n        if value:\n            self._camera.stop()\n        else:\n            self._camera.start()\n        self.__dict__['muted'] = value\n"
  }
]